From 01836494f965afd7fa8de88cf32be6db756da39a Mon Sep 17 00:00:00 2001 From: pibo Date: Thu, 1 Jun 2023 15:00:23 -0600 Subject: [PATCH] Squashed 'OpenFAST/' changes from 08fffef24..6b8706b75 6b8706b75 Merge pull request #1568 from OpenFAST/rc-3.5.0 021594911 docs: address documentation changes requested by @jjonkman for v3.5.0 bdb6d4cb3 Store changelog as markdown (this is GH markdown which is not entirely standard) d114cac01 Update r-test to point to r-test v3.5.0 tag 794d0dbdf Update conf.py for v3.5.0 e3a22e277 Add changelog notes for v3.5.0 8fe902e67 CMake: add awaelib and wdlib to FAST.Farm dependencies 2d94241b8 CMake: remove extra dependencies on wdlib awaelib from OpenFAST and FAST_SFunc 20d628e22 Add missing FAST_SFunc (Simulink deps) ddce16935 Merge pull request #1567 from bjonkman/b/AD_divideByZero 54770bb8b Merge pull request #1566 from deslaughter/b/cmake-matlab c283aa3a3 more divide-by-zero checks f593904cb AD: Fix divide-by-zero errors e79b13b2b Fix FAST_SFunc build using wrong libraries 951825d7b Simulink getting incorrect Sys file during compile with CMake 4bf2cf876 Minor updates to documentation -- typos mostly 2bfd58523 Update api_change.rst for 3.5.0 d5bdbbf78 VS-Build: remove windows 10.0 windows target platform d63e82d42 Roll back to VS toolset v140 instead of v143 700e8a731 Merge pull request #1561 from bjonkman/b/AD_vsbuild e29dca6ec AD vs-build: fix file list ac31048e1 Don't set LINKER_LANGUAGE on CMake INTERFACE Library f93616b15 Fix module_name in unit_tests/version/CMakeLists.txt c7fc73a9f Merge pull request #1560 from deslaughter/b/def_dp 716fde2b2 vs-build: define `OPENFAST_DOUBLE_PRECISION` in AeroDyn_Inflow_c_binding cb8b454c5 vs-build: define `OPENFAST_DOUBLE_PRECISION` instead of `DOUBLE_PRECISION` 214109650 Merge pull request #1559 from andrew-platt/b/RTD d72db2c34 [BugFix] Limit urllib3 version for readthedocs building 69e71212e Merge pull request #1493 from mchurchf/v3.4.1-branch 8ef2c01cf Removing more (:) from whole-array operations. 821641c88 Small changes to remove comments and replace print statements with WrScr calls. bb72d2622 Merge pull request #1555 from deslaughter/bug/cmake-undef 1549da9e1 Document that Simulink mex can be built by CMake a4740d72a Restore openfast_prelib and _postlib, fix simulink c120fcecd Update Github actions to Ubuntu 22.04 and GCC-12 fb4164cab Move OpenMP to main CMakeLists.txt 1836193b9 Use reg libs in CMake, build FAST_SFunc in CMake c050f05d7 Merge pull request #1550 from bjonkman/b/TurbSim_textGrids 52a725931 TurbSim bug fix: fix index into Z array for text grid files 2aef0cc0e Merge pull request #1549 from deslaughter/bug/ifw_read 86ad8a6ca IfW: ifort didn't read derived types properly f7d968bc9 NWTC_IO: incorrect format specifier in ReadLVarWDefault 11c57be73 Merge pull request #1541 from andrew-platt/f/ADIupdates fe198323b ADI: MHK wasn't getting passed to IfW b471f7986 IfW: indentation adjust. Change INOUT to IN (InflowWind_SetParameters) 390c0ecdb ADI: update arguments to ADI_ADIW_Solve after rebase dffd8e5ff ADI: bugfix for segfault if IfW fails to init 312306255 ADI: fix bug in ADI initialization dc4ef40a0 ADI: modify CMakeLists to compile in 1 shot after incorporating dvr_subs 45ba20f45 ADI_C: call to ADI_ADIW_Solve for IfW setting values, update regression tests db4a29896 ADI_c: add output file writing to interface 8bd71da87 ADI: remove t_initial, change data structures fc12d84fa AD driver_subs: optional directory for setVTKparameters routine bf7933f6a ADI c_binding: move x,xd,z,OtherState into ADI_data 3b7c8dcc2 ADI: make x,xd,z,OtherState allocatable (needed for correction steps in aerodyn_inflow_c) driver_types.f90 354d050b8 ADI: allocatable inputs (u inputTimes) for quadratic interpolation 4c8927532 ADI: use the dvr_Outputs data structure for internal vtk info 3988df19d ADI: set ifw rootname for summary file/echo d125157dc Merge pull request #1477 from hkross/feature/FloatingMHK fdb6f2dc9 Update AeroDyn theory documentation to include caveat about modeling MHK turbine support structures and include equation for blade and tower buoyancy volume 6f4bf854c Update r-tests 167884abf Use YAML output for buoyancy parameters in AeroDyn summary file bc94f0dca Merge remote-tracking branch 'OpenFAST/dev' into feature/FloatingMHK d6e1bc53a Update r-test pointer c6b976093 Merge pull request #1543 from deslaughter/bug/ifw-mean-vel 5d4572a6e Update r-tests f05e7ff70 Merge remote tracking branch upstream/dev into feature/FloatingMHK 70d8b43f3 Merge remote-tracking branch 'upstream/dev' into bug/ifw-mean-vel bc03780ff IfW: perf changes to IfW_FlowField_GetVelAcc 3bded79bd IfW: SigmaF and PLExp was not set for Bladed files 3c05a6166 IfW: fix incorrect use of p%RefPosition 133836507 r-test: update pointer and add IfW tests 87e27ef01 Update r-tests accfaee51 Fix typo in CTestList 2fa7bf551 Add floating MHK r-tests 907d23eba Merge pull request #1542 from andrew-platt/b/FLANG_nwtclibs d518bce9c [BugFix] segfault with gfortran 10.4.0 -- NWTC_Base.f90 e083682dc Merge pull request #1538 from deslaughter/f/flang e50dcbaa3 Update r-test pointer to include ifw_nativeBladed e1ad195ef ifw: use correct function to calc mean velocity 55eb00c50 This commit addresses PR comments (#1538) 8774ec43e Add support for Flang (classic) compiler 004a1fae4 AWAE: fix error handling in Init da48da882 Merge pull request #1535 from deslaughter/bug/cmake-ninja 4e29ef9e2 SD: removing static improvement method (SIM) from SubDyn elastic output mesh (y3 mesh) (#1526) 740d19296 Merge remote-tracking branch 'upstream/dev' into bug/cmake-ninja 1d17dcdbb Merge pull request #1534 from bjonkman/b/IfW_below_ground 1513e2d78 Remove trailing slash in SubDyn warning 06fb934ae SD Bug Fix: diameter not set properly for rectangular beams (#1531) 6575c81e1 Fix local LAPACK to work with ninja 7a3502351 SD: fix continuation statement that doesn't build on my compiler 8a3e6a0ab Fixed CMake on Windows (and Ninja build) 3e1c6a43e IfW: add comment/question 9ed8c74cf IfW: Ensure velocity is zero when Z <= 0 334cb1bb8 Use find_package(LAPACK) to find MKL 9c6d8f376 Fix unit_tests so ninja can build project e2f56e36c [BugFix] AWAE attempting to get size of possibly unallocated array (from PR #1464) 9d6a009dc Update r-test after merging #1516 84158f3fd Merge pull request #1516 from deslaughter/ifw-mod fec5f76a1 Merge pull request #1530 from andrew-platt/f/cmake_bugfix_PR1010 168e2941a Resolved inflowwind/CMakeLists.txt issue 179dea0e9 Merge remote-tracking branch 'upstream/dev' into ifw-mod 9c64eedfd Docs: indent issue in SD/input_files.rst e5df74b83 SD: Implementing directional cosine matrices and section properties for rectangular members (#1413) c9aa5554a Update buoyancy theory documentation to account for floating MHK turbines 86861b6e7 Merge remote tracking branch upstream/dev into feature/FloatingMHK f2a3bc2a3 cmake: fix cmakelists.txt for map 8a03232dc cmake: fix for nwtclib_obj compile 86b63a995 Update CMake min version after PR #1010 cb01490ba Merge pull request #1010 from Reoptimize-Systems/static-openfast-cmake-obj-libs 68e5dc1be Merge pull request #1427 from gbarter/mkl_cmake c6cbb54aa Merge pull request #1506 from pablo-benito/fix/CompileWithLinuxIntel 931305511 IfW: initialized ErrStat/ErrMsg in IfW_Points_Init 47255466e Fix Visual Studio project files 442144966 Updated Visual Studio Files 953139951 IfW: added BoxExceed to driver input, moved accel 4860bc433 IfW put FlowField back in ParameterType, cleanup d3dfeeefe IfW: final iteration of tower interpolation c0fd51886 Updated InflowWind docs for acceleration 05e999e03 IfW: Moved Y bounds checking to reduce calls e323e90bb Merge remote-tracking branch 'refs/remotes/origin/ifw-mod' into ifw-mod 3059a246f Fix Grid3DField_GetCell returning NaN when Y=0 465d5a914 IfW: fix comment on Point_WindNumber a8a4de697 Updated api_change.rst for InflowWind changes bdf7f1827 InflowWind cleanup and better tower grid interp fbf44875f InflowWind: minor cleanup aca292eba Missing check for OutputAccel in IfW 10b5f51c3 Added InflowWind acceleration outputs d48ce4248 Removed inflowwind_driver change 7ac862bf5 Moved IfW_FlowField into MiscVars 5075f9ab6 Removed new InflowwindRegressionCase.py code c82222d37 Regenerated IfW types and updated r-test db5ae99d8 Merge remote-tracking branch 'upstream/dev' into ifw-mod ce12a866f Integrated IfW BoxExceed a20932781 Merge pull request #1509 from ebranlard/f/ad-cone 68373b978 Merge pull request #1464 from Russell9798/main d2ab54196 Merge pull request #4 from andrew-platt/f/lidar 900ec4902 Merge remote-tracking branch 'OpenFAST/dev' into f/lidar 0ed1c1ada Merge pull request #3 from andrew-platt/f/lidar 36d255dd2 Update r-test pointer 88157b022 Merge pull request #2 from andrew-platt/f/lidar 4d214b098 AD: new BEM for coning and prebend temporary accessible using WakeMod=11 or 12 cf07578d2 OLAF:fix WrVTK=2 555e5a3ef Code cleanup 0af90e28e Compile Fix 0b7f41ebf Merge remote-tracking branch 'andy/f/IfW_BoxExceed' into ifw-mod cf5c40647 Update regression test pointer 2621d3151 Check IfW acceleration data in test cb31cdee5 Updated FASTWrapper for FlowField structure 4240273d8 Fixed bug Grid3DField_GetBoundsT for periodic wind 97bf5084e Fixed code to writes files from inflowwind_driver da679373f IfW lidar: add input file change to the api_change.rst 5005a3076 Merge pull request #1504 from andrew-platt/f/FF_morePlanes 1642941da Merge remote-tracking branch 'upstream/dev' into ifw-mod e3df8c03b Changed InflowWind to use new FlowField type 06763abf6 FF: updated FF docs for 99 planes in input file section e2369d385 FF: allow up to 99 output VTK planes 029c5d80e Lidar IfW: update IfW unit tests babdb747d Final changes to allow for non-uniform body force node spacing on blades. 5d46b2964 Lidar IfW: more unallocated arrays c742b9105 Lidar IfW: fix some unallocated variables for lidar in glue code 74d126595 Lidar IfW: cleanup SrvD -- add lidar info to the summary file c286236a4 Changed the option for blade force point distribution from bool to int (we likely will have more than 2 options in the future) 2e4ac0c7a Various updates to fix incorrect logic in the chord-clustered spacing code. 20b3e2c68 Lidar IfW: format registry files and Lidar file 92f4705fa lidar: get hub info directly from mesh (for later mesh mappings to a lidar mesh) 687722a03 Lidar: revert _Types.f90 for ED to unix line endings 5f7e540cf docs: mispell on figure option `width` 17530fd9e Ifw grid exceed: fix logic error at grid boundary 6966ab97c IfW grid exceed: add warning on first occurance 37cef069e IfW grid exceed: add rough test case placeholder 7f7596d73 IfW grid exceed: fix logic error for points outside box e351cb7b0 Revert formatting changes 1698843bb IfW grid exceed: add some rudimentary documentation 3a63e7c3c IfW grid exceed: algorithm for extrapolating from tower below grid d4de50703 IfW: logic for extrapolation of points outside grid 23f8a1cc9 IfW: rearrange FFWind_Interp routine b370ab7c1 IfW: add flags for handling wind grid exceedence points (only for OLAF) 64a571b46 Merge branch 'dev' into v3.4.1-branch 5014e0164 Small punctuation fix. 9c66ebba2 Removing modifications to UserSubs.f90 515ea0bdc Small formatting clean up. b23a8436e Cleaned up the OpenFOAM.f90 OpFM_CreateActForceBladeTowerNodes function. a87e0bb15 Merged dev into f/lidar 4b89b711b Attempting to merge my chord-clustered Aerodyn point distribution option into the newest OpenFAST. 8d701d664 Update r-test 2a7727eb7 Update Lidar.f90 3b114ad60 Merge pull request #1 from Russell9798/Lidar-IfW-Updates 3876a20c5 Add counter for lidar inputs 9e7846a17 Fixed column alignment 02a9fafd2 Fixed column alignment 921a4c31b Update FAST_Solver.f90 97d88b653 Updated Lidar.F90 7699393f9 Moved Lidar Input Section c4a7375b2 Fixed column alignment 100bcb347 Fixed column alignment d0a7624a8 Update Lidar.txt 6ecd5a0ca Update Lidar.txt 7daaa1317 Update Lidar.txt 863ad9ba7 Fixed column alignment d23f3728a Update Lidar.txt 79de88b8c Fixed column alignment eec4e49f3 hd: add NBodyMod regression tests f6bdf20ef Update r-test submodule pointer 24c6bd813 Merge pull request #1482 from deslaughter/bug/BD_conv 994936391 Merge pull request #1480 from andrew-platt/b/HD_nbodymod bb7709df4 Add 5MW_Land_BD_Init test, updated r-test pointer 1f07d1634 BeamDyn missing velocity init in BD_InitAcc bfd9342ea hd: fix NBody>1 & NBodyMod=1 WAMIT2 bug f8636c8f7 Update ServoDyn_Registry.txt e34b0718b Update ServoDyn_Registry.txt 530c7d97d Merge remote tracking branch upstream/dev in feature/FloatingMHK 4acefd77a Update types files 7af0174af Update documentation for floating MHK turbines b35ab10d8 Merge pull request #1474 from andrew-platt/f/BDdriverVTK c54940085 AWAE: bugfix -- IfW needs HubPosition and rotor rad (#1476) 9fa2a5458 BD: modify bd_5MW_dynamic_gravity_Az90 to test the TranslationDisp bug in BD driver f342ad574 BD: fix initial translational displacement in driver 4da3f820c BD: add VTK at T=0 (right after Init) 7e9ca64ff BD: add VTK outputs to driver 59c11c134 Merge pull request #1453 from deslaughter/f/del-quki 76fab2f28 Update to r-test pointer to delete QuKi fd5cb5b5a [BugFix] FF: uninitialized flag for WAT (#1470) 072389f6b Merge pull request #1419 from andrew-platt/b/RegTestWin_docs 18432374b Merge remote tracking branch upstream/dev into feature/FloatingMHK 75583f17c Flow field supports Bladed wind files a8942cf57 OLAF: fix documentation issues in circulation solving theory af3fcb27a FlowField integration and testing with driver eaab8980c Update ServoDyn_Types.f90 b61a4d6cc Update InflowWind_Types.f90 9c4c22e81 Update Lidar_Types.f90 0c58ee713 Update FAST_Subs.f90 882e4e73e Update Lidar.f90 7de58f3d7 Update FASTWrapper.f90 dde14876d Update AWAE.f90 16b2c4c9d Update FAST_Solver.f90 ccd16565a Update FAST_Subs.f90 b6263367b Update ElastoDyn_Types.f90 a4b9d89bb Update ElastoDyn_Registry.txt 544b84bc0 Update ElastoDyn.f90 44ea7dd8d Update BladedInterface_EX.f90 460b31413 Update ServoDyn.f90 3bc0c851a Update ServoDyn_Types.f90 560274a26 Update ServoDyn_Registry.txt a91c06f35 Update Lidar.f90 6c919040a Update Lidar_Types.f90 b45a8bf78 Update Lidar.txt 181b9622b Update InflowWind_Subs.f90 24ed5682f Update InflowWind.f90 a8f04db74 Update InflowWind_Types.f90 3ea38c4c0 Update InflowWind.txt e172534af Update InflowWind.txt 1baa7f579 Updating to ifw-mod branch of r-test 26e690cad Reorg FlowField module, finish VelInterpCubic flag e0e592690 Added VelInterpOrder to IfW input file 351909526 Moved FlowField module to InflowWind ed24fc111 flowfield: set end derivatives of cubic spline = 0 385dd41b7 inflowwind: added ExtGrid & ExtPoint to FlowField fee05ac3e nwtc-library: FlowField smooth Grid and ExtGrid d58ffc395 inflowwind: add acceleration calc to IfW_FlowField 8d3bf7045 nwtc-library: add acceleration calc for FlowField 67d83e91f inflowwind: add FlowField init to InflowWind_Init 64509d81a inflowwind: adding IfW_FlowField module f80d45c3a nwtc-library: adding FlowField module ca3e99812 Merge pull request #1 from bjonkman/f/del-quki c3aae1cfb Add blade and tower buoyancy volumes to AeroDyn summary file e0471b069 More updates for new `DbKi=R8Ki` behavior 410d922cd Remove QuKi from OpenFAST 60c02f362 Merge remote-tracking branch 'OpenFAST/main' (v3.4.1) into dev 18704086d Fix api_change.rst c7ca9784e Merge pull request #1445 from OpenFAST/rc-3.4.1 9ea405347 Update version info and release notes for 3.4.1 861c88461 [BugFix] Doxygen builds failing on rtd, and locally (#1442) 50fa7f7c2 Merge remote tracking branch upstream/dev into feature/FloatingMHK 221c09025 Specify StC Force from External DLL (#1434) 34cc1034f AD15: revert to `Aero` names for output channels (`Fld` is now an alias) (#1428) c8df56b23 Merge branch 'dev' of https://github.com/openfast/openfast into mkl_cmake 39a1384c6 [BugFix] incorrect routine call in WakeDynamics.f90 caused FF to not compile 61bb4bdc2 prioritize mkl_rt library to avoid runtime errors and eschew preloading libraries a8cc65a3a Update input files 5MW_Land_ModeShapes 7967f397a Merge pull request #1426 from hkross/f/ADAMSremove ece8a2481 FAST.Farm: Preliminary implementation of wake-added turbulence (WAT) (#1329) 5265b13db Update types files 19dc800d0 Remove references to ADAMS coupling 6f626a313 SD: SumPrint line in input file had name of SSSum (#1418) 0abd13f9f Update minimum Bokeh version in docs to 2.4+ f1e5b0cc9 Update manualRegressionTest syntax description 9c8d63722 Docs: update manual regression testing syntax for Windows b428af5c6 Added some comments to CMakeFiles.txt de00a9ee2 Restore openfastlib to always be shared 1da89dfdf Merge branch 'static-openfast-cmake-obj-libs' of github.com:REOptimize-Systems/openfast into static-openfast-cmake-obj-libs 4c73cdc66 openfast-cpp CMakeLists.txt: ensure fortran implicit libs are linked 515ba3c7d Merge remote tracking branch upstream/dev into feature/FloatingMHK 9e9db8625 SubDyn: documentation fix (missing R_b2g) ab0d1724c Merge branch 'dev' into static-openfast-cmake-obj-libs 6823d98b8 create_FAST_SFunc.m: need linux-specific mex call COMPFLAGS windows only -MT option differrent in gcc 8b1bec3e0 Use object libraries to avoid missing symbol and linking errors in cpp interface 57dfd99cb openfast-library/CMakeLists.txt: correct target_link_libraries for openfastlib_common_obj and export openfastlib_common_obj 89d8a8366 Solved circular nwtclibs versioninfo dependency and 5a784895f Adjust OLAF warning for fixed and floating MHK turbines ae106c52e Merge branch 'dev' into static-openfast-cmake-obj-libs 32237760b Take absolute value of some parameters in AeroDyn for floating MHK turbines e8ec53f9c Merge pull request #1386 from OpenFAST/dev 8ad9e9754 Update r-test pointer for 3.4.0 27314ad89 update conf.py for 3.4.0 f89e37812 Merge remote-tracking branch 'OpenFAST/main' into dev c85d456f3 Docs: update example InflowWind and FAST.Farm input files (#1406) c51790cc8 GetNewUnit: increase allowed number of open files to 16384 (#1392) dc47c50e4 Take absolute value of additional ElastoDyn variables for floating MHK turbines 608205c6d Merge remote tracking branch upstream/dev into feature/FloatingMHK 415440c4c Correct additional ElastoDyn values for floating MHK turbines efc80896d change np.float to float in regression test scripts 9946fb0fc Update api_change.rst for v3.4.0 release 650b60520 Add `regression_tests` to the ALL target. (#1376) 3271b8123 MoorDyn v2 C-bindings interface (#848) 60e3cc0d3 MoorDyn bending bugfix and message updates for v2 (#1371) aef318c7e OpFM: fix mesh access in DEBUG_OPENFOAM option 4eba321a4 OLAF: fix documentation 4d331e7a2 UA: adding UA_Driver outputs, fix separation function for UAMod=6, and adding r-tests (#1369) 8a446ceca OLAF: Adding free near wake panels (#1355) 695c57195 Merge remote tracking branch upstream/dev into feature/FloatingMHK d2f2df6d9 Take absolute value of some ElastoDyn calcs to prevent negative mass and stiffness for floating MHK 220adf42a OpFM: [bugfix] test for warning condition was broken 524c6c274 TurbSim: User-defined time series updates 785bd1d61 CI: exclude bokeh 3.0.[0-3] -- broken plots ae73af430 BeamDyn: output summary file in yaml format (#1335) 381660f91 NWTC_Lib: Adding Yaml and VTK to library (moved from SD and AD) (#1333) 0ffa0c059 AeroDyn/UnsteadyAero_Driver: Fix for bug #1346 (#1356) 28f2647ad Merge pull request #1324 from andrew-platt/b/openfoam_mesh afc5cabba AD15: line endings in AeroDyn_Driver_Types.f90 6beae107c OpFM: add docs on intermediate meshes, updates from PR feedback 87173deb5 OpFM: add error if number of blade points from CFD is significantly larger than AD15 mesh points 09f374eac OpFM: remove unnecessary meshs 57c1a4d34 OpFM: remove ED, and AD14 from OpFM 1defb56d8 add version info to c-binding libraries (#1327) dfca46063 FF: update of guidelines for Curled wake dr and DT_low (#1328) 4e85fa628 Documentation fixes (#1332) ca595c443 VTKLin: being more forgiving with number of modes (#1330) a7b390aa4 Adjust external wind positions for MHK turbines ec31ce673 Undo TwrInfl index adjustment for floating MHK turbines b6e3e7b4f Merge remote tracking branch upstream/dev into feature/FloatingMHK 3fff3f475 VTK output: add safety checks (#1321) 6feb60940 Glue VTK: cleanup HD meshes written to VTK files (#1319) 88386bf97 Registry: tweaks to allow extrap/interp of types without module name (#1318) 11dac9e88 Fix for Visual Studio builds with ADI (#1317) 4fbac48cf FF: additional OpenMP parallelizations in FAST.Farm (#1310) 39d37e6be NWTC_IO: nullifying DLL (on restart) if not present when packing (#1311) d2c9fef49 Cleanup of OutlistParameters.xlsx 96006c5ff Implementation of the curled-wake model in FAST.Farm (#931) 71d19e5d8 FF: Cartesian grid for AWAE and WD outputs (#1305) - change of FF r-test b1ed3386c Merge remote-tracking branch 'openfast/main' into dev 5f3fb6ef7 Merge pull request #1291 from OpenFAST/rc-v3.3 b85e3e09e Include NAWEA 2022 slides 3210dac8e API docs bug fix 777a2c48c FF: API changes for future curl wake implementation, WD restructuring (Cq, OMP, skew filt) (#1304) d1ed5a81a FF: Small reorganization and clean up of FAST.Farm r-test input files, upload of artifact(#1303) 13cd8bcf8 Update version to v3.3 8b8177f01 Add a super-controller library target to CMake (#889) 2e7c97b83 Update of r-test to point to dev branch after #1240 c719778a7 Improvements to the InflowWind disk averaged velocity calculations (#1240) fb9aec734 AA: using new BL r-test input files for IEA_LB 1ca61657c New AeroDynInflow (ADI) module with c-bindings interface (#1110) 8d2b79947 Update of r-test to point to dev branch abdb47ebc ED/AD: reactivating rotor furling and tailfin aerodynamics (#1277) a449a52ce Minor error handling and code cleanup (#1293) 70635c51f AD: add new projection method and BEM methods (#1283) ce24848b3 Merge pull request #957 from hkross/feature/Buoyancy ffdd6809f Adjust syntax in api_change.rst 76d2a72a4 Remove redundant paragraph in AD docs 7b2015c15 GH Actions: Update artifact upload action version ccf25ad4b AD/MHK: update of r-test 6ccb32c36 AD/MHK: placing hub and nacelle prop before tower dd3c56c40 AD: allowing blade input file without cuoyancy columns 98338fe49 Merge remote tracking branch feature/Buoyancy into feature/FloatingMHK 9007f776d Update regression tests 5a50b5397 Merge remote tracking branch upstream/dev into feature/Buoyancy 839bb62da Update regression tests fd4fab06c Use mesh mapping routines for tower buoyant loads 4051210a2 Add back in blade root hub buoyancy correction b4886e733 Use mesh mapping routines for blade buoyant loads 35a28725a Bug Fix: OLAF: particles are NaN when vortex segments have zero length (#1276) dcdc7c33c Linear Trim Solution Improvements (#1275) 0ae44fad9 Remove platform and tower base geometry checks for floating MHK turbines a9927602e Merge pull request #1263 from bjonkman/b/Farm_OMP 22b997517 Merge pull request #1267 from ebranlard/f/olaf-doc 8e9a44ec2 OLAF: documentationr: updated guidelines, using nFWPanels 16b2d82ec Merge pull request #1266 from ebranlard/f/ifw-omp e387ff7ca IfW: removing OMP in inflowwind until pointer implemented (see #1265) 95ce92217 Remove blade root corrections and use element length based on aerodynamic centers for defining per unit length loads aa9c459b5 GitHub Workflow: adding build-all-debug-single to check types on compile (#1264) 6906dfcbb Simplify code in Farm_SetOutParam 99113d0a3 FAST.Farm: Update types files + remove OutStrLenM1 parameter 624dfab19 Merge remote-tracking branch 'bjonkman/test/OMP_FF' into b/Farm_OMP bfa9eb148 VS build of FAST.Farm OMP: remove dependency on MKL libraries 284152d08 FAST.Farm OutListParameters: fix issue with Windows/Intel/OMP 1b4a1ac38 Merge pull request #1248 from bjonkman/f/Registry ba6e89b37 Merge pull request #1000 from ebranlard/f/ua-dbemt 2e9ea7cf2 VS FAST.Farm OMP build: use static libraries 6661940d6 UA/DBEMT: update of r-test 9fea6a62a Merge branch 'dev' into f/ua-dbemt 42774c9d0 Merge branch 'dev' into f/ua-dbemt e3f401f86 Merge pull request #1037 from bjonkman/b/BEM_TSR_turnoff f558a6391 Merge branch 'dev' into f/Registry c6dc52e47 update r-test 620c60b16 Remove unnecessary artifact upload step 27e418bc3 Compile and run Registry in GH Actions 5773f704f Merge remote-tracking branch 'NREL/dev' into b/BEM_TSR_turnoff 782d4aea7 Merge pull request #1254 from bjonkman/f/WriteOutput 3a6e5c68f update r-test 172b020c3 Merge remote-tracking branch 'NREL/dev' into f/WriteOutput ef6d6baa1 Merge pull request #1061 from bjonkman/f/Aero_Sync 77ad92e07 Merge branch 'dev' into f/Aero_Sync 8bb1bc229 Merge pull request #1042 from bjonkman/f/AD_TwrShadow 98d86ee14 Merge pull request #20 from rafmudaf/f/AD_TwrShadow 673b437d8 Update r-test baselines for AOC cases 936f18e75 Merge branch 'dev' into f/AD_TwrShadow a0d4f7e76 Also adding in UserSub to do yaw control based on Eric Simley's paper. 49ca7ad91 Remove redundant parameter from Waves 23ce9743c MAP: fix compiler warning about parameter being different than declaration 9162ee89e NWTC_IO: update GetWords to return the number actually read 4e034aa47 NWTC Lib: add `OutStrLenM1` and `FindValidChannelIndx` 6e5c3e88c Registry: fix typo in error message text 56aaad362 NWTC Lib: fix uninitialized ErrStat in FreeDynamicLib 35d8bb356 Update Types files e1969eb6b Update Registry to use pointers when requested 8ad56a7cc Merge pull request #1086 from mattEhall/MDv2-farm 637b93fc0 MDv2: update api_change.rst 15e2480e1 MDv2: add MD documenation (linked to another readthedocs for now) 679d85054 Merge pull request #28 from andrew-platt/MDv2-farm 4791e9a31 MDv2: update regression tests using MD f067eb998 Merge remote-tracking branch 'OpenFAST/dev' into MDv2-farm 066807917 Merge pull request #999 from ebranlard/f/hd-am-end 66582caf7 HD: regression test update after added mass fix 23fb58fd5 Merge remote-tracking branch 'OpenFAST/dev' into f/hd-am-end 59fa0db66 Merge pull request #1199 from ebranlard/f/linviz 1a1091f79 Lin: close default vtk circle shape b5c449160 Lin: minor update to error handling in SetVTKDefaultBladeParams 1dc43e6b6 Merge remote-tracking branch 'OpenFAST/dev' into MDv2-farm 0f8237e78 Merge pull request #1244 from andrew-platt/f/DisableRegTests de6e54466 testing: cpp testing failing from last commit due to missing .yaml file 8b776ce08 FF: add warning if a turbine using shared moorings is using SD 6ce04ff58 Merge remote-tracking branch 'origin/f/DisableRegTests' into MDv2-farm 83b5f9a41 Merge pull request #1211 from deslaughter/bug/pythonlib 4fff8f218 testing: update test execution scripts to use rtl.copyTree e1e61744e RegTest: remove a python test and a hd test that were equivalents to OpenFAST tests that were removed. c5c38fa01 Merge remote-tracking branch 'OpenFAST/dev' into MDv2-farm 1d16cd419 Merge remote-tracking branch 'NREL/dev' into f/Aero_Sync 4506efe2d Merge remote-tracking branch 'NREL/dev' into f/AD_TwrShadow 7228d7f11 Merge remote-tracking branch 'NREL/dev' into b/BEM_TSR_turnoff a249ec9ac Merge remote tracking branch feature/Buoyancy into feature/FloatingMHK b496e46b8 Merge pull request #1230 from andrew-platt/b/HD_KinematicLongInputLine 3770ba9c8 Merge pull request #1239 from ebranlard/f/aa-delta0 f67cfb1c9 AA: fix BL-thickness for heavily-tripped airfoil, and adding equation references (see #1079) e4392d7ea Merge remote tracking branch upstream/dev into feature/Buoyancy cc9b71fd4 Add bent blade corrections to buoyancy calculation 28d535ca7 MDv2: use small angle perturbation for angles in Perturb_u 8f93c02fb MDv2: true up FAST_Lin.f90 to match dev (bad merge may have occured at some point) 471c7a646 Merge remote-tracking branch 'OpenFAST/dev' into MDv2-farm 51740e683 MDv2: update r-test cases 179298421 HD: increase max length of line read from kinematics files b888e4a83 [bugfix] Seg Fault due to hub model and external inflow (#1227) 32a5f3406 Merge remote-tracking branch 'OpenFAST/dev' into MDv2-farm 19b4ca7f3 Merge pull request #1222 from bjonkman/f/Python_RegTests 0a6d2f005 Merge pull request #1228 from andrew-platt/b/CMake_FlagUpdate-rtest a8b7c89c1 r-test: Remove -m64 in CMAKE_Fortran_FLAG from r-test 458b2b36f Add hub buoyant forces and moments to rotor fluid force and moment outputs 273e9c191 Merge remote-tracking branch 'NREL/dev' into f/Python_RegTests fccee33a2 r-test: missing test case after merge of #1217 93b5288b9 Merge remote-tracking branch 'NREL/dev' into f/Python_RegTests 4923e05d4 Missing r-test commit from previous PR cd14fab5f fix broken spacing from previous merge conflict b22fc02d1 python scripts: avoid plotting errors with different numbers of output channels 6adf4ac61 Fix broken manual regression test python script cec8dfa90 Merge remote-tracking branch 'NREL/dev' into f/Python_RegTests 7f4e9057e Add some outputs to fixed MHK_RM1 AeroDyn driver r-test and update baseline 7f1bc2f58 Adjust AeroDyn driver inputs and geometry checks for floating MHK turbines 1c4866124 Merge remote-tracking branch 'mhall/MDv2-farm' into MDv2-farm ddcb39270 Merge remote-tracking branch 'OpenFAST/dev' into MDv2-farm 2ea9bcb24 Merge pull request #1217 from rafmudaf/q3/one_baseline 783925f82 Revert path changes (see #1021) 134959cd1 Add legend to error plots c0453417c Improvements to regression-test python scripts 92ddaf336 Bug fix in finding the channel order of magnitude 705bf08f0 Disable consistently inconsistent test cases e46cbaa65 Connect tolerance parameters through CMake 5ba94cef1 FastLibAPI: change output_channel_names to vector. Renaming the class member channel_names to output_channel_names created a conflict with a class function prototype which was designed to return a string of channel names. To make FastLibAPI consistent with openfast_library.py, this commit changes output_channel_names to be a vector of strings which is populated by the fast_init method. 8faa2538a Merge remote-tracking branch 'OpenFAST/dev' into MDv2-farm 31cd646bf FastLibAPI: channel_names -> output_channel_names Class member was renamed for consistency with openfast_library.py. b427ef7eb openfast_library.py channel_names -> output_channel_names This change was requested to so WEIS, which uses this library, doesn't have to change. c6b19d963 simulink: updates FAST_SFunc.c from FAST_Library.h Updates FAST_SFunc.c for the new FAST_Sizes function signature which exposes DT_Out. c4e837bc2 FastLibAPI: update for FAST_Sizes, fix memory leak The C++ interface to openfast-library was updated to match the changes to openfast_library.py - basing output on DT_Out instead of DT. Also, the output_array variable was removed and output_values changed to a vector of vectors so the memory will be freed when FastLibAPI is destroyed. This change also removes the copying of data between arrays. 859f4f44d openfast_library.py: save output based on DT_Out For long simulations openfast_library.py would allocate a large array to hold output values for every step based on DT. This array could consume a significant amount of memory and was inconsistent with the data stored in output files which is based on DT_Out. This commit bases the output array size on DT_Out and changes the data collection to match, which can significantly reduce memory usage. In addition, the output_values array is passed directory to FAST_Update to reduce copying data. Lastly, the channel name processing is moved to fast_init to avoid a memory leak 789eadbf5 Fast_Library: expose DT_Out through FAST_Sizes DT_Out is needed to determine the frequency at which results should be captured from FAST_Update in the programs that use openfast-library. This change exposes the DT_out by adding it the arguments of FAST_Sizes. The corresponding function prototype was updated in FAST_Library.h. bbe030704 Fix typo in cavitation calculation 97ce00c23 Merge remote tracking branch feature/Buoyancy into feature/FloatingMHK 0d8762b24 Add HD module test for OC4 jacket 35875cc76 Update regression tests c15991270 Merge remote tracking branch upstream/dev into feature/Buoyancy cbf93de4d Adjust inputs, geometry checks, and buoyancy and cavitation calculations for floating MHK turbines 5dc727265 Host a large file in the docs outside of GitHub 0ffbe85f4 Add a ctest label for fastlib cases ff1cf541f Set ctest driver paths based on system type 35387f79b Rename openfast library ctest function d1daab1b0 Make atol a function of the magnitude of the data 8a59edd56 Update a few HD cases to use RANLUX pRNG ccaabe435 Add more precision to SubDyn tests abcdb12e8 Test ascii output silently 761ef68fb HD: add precision and update Python driver scripts 7c2215bb8 IfW Driver: Fix output headers and column fmt 0b76b44e2 Add fpic compiler flag for C targets df1cc9e4b Add a no-run flag to CTest options c70fb2be8 Mark channels with nan or inf as failing 2d75a7273 Expand precision for BeamDyn and SubDyn module tests acf2c89a0 Update reg test plotting - bug fixes, Bokeh 2.4 68ed80ae9 Update reg test driver scripts 22e8395ae Unify baselines b2b3d5c7d Plot pass/fail boundary in error plot fa66d5b64 Determine passing channels instead of norms 84addf3ad Clean up in rtestlib 6aae04a23 Merge pull request #1203 from rafmudaf/q3/parallel_actions 7763deaba Merge branch 'main' into dev 5099377d2 Build HydroDyn C-interface for interface tests 6d9d1c978 Update ideal beam linearization test baselines 3aa7f39ba Disable variable tracking on all FF modules 78fc18774 Consolidate tests and improve naming 7693fa1fe Add a branch for linearization tests c4d2ca8f4 Add fPIC flag for MAP++ 5a8ec2669 Configure OpenFAST Library as shared library 7ed465503 Add parallel jobs to improve Actions reg test time 1b744a29f Option to disable variable tracking with GNU compiler (#1198) 71940d87a Lin: default rectangular cross section for BD and ED. Using FPS for VTKLinTim=2 2ee8b4ae3 Lin: surface mesh outputs without AD using basic geometries, adding circle/rectangle as options 157cfac8d Lin: unifying some code for VTKLinTim=1,2 and adding screen output 23d2330e1 Lin: create VTK directory on restart (user might have deleted it) 3d415d3ef Add overview presentation from NAWEA 2019 d66bd88df Update types files 232439f02 Adjust inputs, geometry checks, and buoyancy and cavitation calculations for fixed MHK turbines 3a381817b Merge branch 'main' into dev 09a57eb43 Merge branch 'main' into dev 8539e4e90 MoorDyn Rod bugfixes to solve power cable issues: da6fb64e1 Merge pull request #1188 from andrew-platt/f/ad_driver_lineVTK b4c9facb0 AD15: add checks on driver inputs for WrVTK and WrVTK_Type 9e1f8f976 AD15: update documentation for WrVTK_Type in the driver 3a12ac60d AD15: add WrVTK_Type to driver for outputting line mesh info 81c879830 Merge pull request #1183 from rafmudaf/dev 4eb9938f5 Merge pull request #1186 from andrew-platt/f/MAP_keyword_Fixed 924241a59 MAP: allow keyword `fixed` and `fix` 092f4cac4 Merge pull request #1078 from hkross/feature/Cavitation 75879ae50 Simulink: add documentation of channels in FAST_Library.h (#1176) a21da3b90 Fix name of InflowWind_Driver in syntax help docs 70628ac7d Move IfW API changes to the correct section da66f9a09 Make test documentation more visible in TOC eab09f07d UA/DBEMT: linearization with UA_OYE, using 4th state only ffae12952 Merge remote tracking branch feature/Buoyancy into feature/FloatingMHK cab687b7f Merge remote tracking branch upstream/dev into feature/Buoyancy eb347694f UA/DBEMT: update of documentation. UAMod=4,5,6 support linearization fdb59b326 Update regression tests f049ce3a7 Merge remote tracking branch upstream/dev into feature/Cavitation de7f525f6 Rename AeroDyn images so they get past ad blockers 461ad532c Link to repo-hosted NWTC Programmer's Handbook fc9114101 UA/DBEMT: update of r-tests a2c744950 Merge remote-tracking branch 'origin/dev' into f/ua-dbemt db3423322 Merge remote-tracking branch 'OpenFAST/dev' into mh-MDv2-farm eb54ace83 Adjust inputs for fixed MHK turbines f1de6223c Merge remote tracking branch upstream/dev into feature/Buoyancy d27b0adf1 UA/DBEMT: update of r-test 729a2afd3 UA/DBEMT: update of documentation and static equation references in code 36c4dec66 openfast-library/CMakeLists.txt: change order of object files af56d527f nwtc-library/CMakeLists.txt: put all nwtcsyslib_matlab_obj link libs on one line 54488a2d6 openfast-cpp/CMakeLists.txt: add OpenMP target link libs if necessary c76948830 Add missing map library objects to openfast-library 221b250c1 odifications to cmake files to ensure each object file is built only once, and also to reduce pollution when building Simulink interface and linking against mex libraries 680361f14 Merge branch 'dev' into f/ua-dbemt 8788b6a43 Merge branch 'dev' of https://github.com/openfast/openfast into dev c70906c70 Merge branch 'dev' of https://github.com/openfast/openfast into dev eca838702 SD lin: [BugFix] indexing to SD_y%Y3Mesh start in Indx_y_SD_Y3Mesh_Start 670375e15 MD: fix issue with compiling double with Intel ea33943d2 All updates to be able to specify chord-based actuator force point clustering. 7844b9350 MoorDyn: add slack-segment 0.5 safety factor for linearization perturbation size 4ac90265c MDv2: update input file format in r-test e96a0861b MDv2: [BugFix] segfault in logging option. update input files in r-test 6f8dc6fb5 MDv2: merge issue in MoorDyn registry -- registry.exe could not build it 43e22cc24 Merge branch 'dev' of https://github.com/openfast/openfast into dev 4ed7952af Add option to pass in node clustering type for actuator sims 9c7ee2e06 Added Ganesh's implementation of tip clustered force point spacing. 461fd87ea MoorDyn updates: linearization, wave stretching, buoyancy, print: ea6bc8fe6 MDv2: Fix compile issue with the UnLog 3b4f10d23 MDv2: remove tab characters 017910190 Merge branch 'dev' of https://github.com/openfast/openfast into dev a8b1d091e Enabling and fixing cable bending stiffness capability: 52d1468d4 Merge pull request #20 from andrew-platt/MDv2-farm 490bd8e85 MoorDyn: restoring backward-compatible output names e908c4b4f MDv2: Check for correct number of columns in each row of each input table -> throw fatal error if wrong number of columns to prevent program crashes and incorrect processing of data f7b799e5e MDv2: More strict parsing of Type/BodyID for pinned Rods f2629d685 MDv2: Make parsing of OutList from input file more robust de041bb30 MoorDyn cylinder hydrodynamics capability 250f7761d Update regression tests 458438987 Enable cavitation calculation using FVW model 82397643c Update regression test metadata 1d89546ee Merge branch 'dev' of https://github.com/openfast/openfast into dev 605de108f MDv2-farm: update regression test cases from @erickaloz 8c12ac0e7 MDv2: update MoorDyn_Types.f90 after regenerating 1230c155b Merge remote-tracking branch 'OpenFAST/dev' into mh-MDv2-farm 693a56b49 Add description of reference location for MHK turbine inputs 76e74bf08 Merge remote tracking branch upstream/dev into feature/Buoyancy 8448b51e8 Update regression tests 7dc0524ec Update regression tests for AeroDyn module fixed MHK test 47830e425 Move cavitation check call a42aaf4e2 Merge remote tracking branch upstream/dev into feature/Buoyancy 0a63305c2 Merge remote tracking branch upstream/dev into feature/Buoyancy f9b5439dd Merge branch 'f/AD_TwrShadow' into f/Aero_Sync 273584958 Merge remote-tracking branch 'NREL/dev' into f/AD_TwrShadow 8156e6c2c AD: fix some typos + convert `pi/180` to `D2R` 5e46952b7 Merge branch 'dev' into f/Aero_Sync_full 48084bcbf FAST lin: update `Indx_y_ED_Nacelle_Start` with suggestion from bjonkman a612d2a6c MDv2: Fix error message for unidentified Type/BodyID of Connections to show the correct, related wrong user input c51e7c0ea MDv2: BugFix to ensure correct output of solver options warning and matching line type error b820815ef Bugfixes for cable bending stiffness 9a28d15c8 Merge pull request #18 from andrew-platt/MDv2-farm 27de1d433 Merge remote-tracking branch 'OpenFAST/dev' into mh-MDv2-farm d34239ae3 Merge branch 'dev' of https://github.com/openfast/openfast into dev 4f4b5a8fb HD: allways allocating A,B,C (Closes #1046) c0c1c29e2 GitHub template: update list of binaries for Windows executable b2e900a21 Merge remote-tracking branch 'NREL/dev' into f/AD_TwrShadow 78efc1bd2 Improve and correct some error messages and warnings to be more precise and helpful 0b3bc95d0 Merge pull request #16 from ebranlard/f/hd-am-end 81df6721b HD: Fix HD added mass on member end (scaling factor) (Close #992) 4cc8f6d41 Bug fixes for nonlinear tension-strain capability ebc5c85be Merge pull request #14 from andrew-platt/MDv2-farm 5c39dbe08 AD: merge more of `TwrInfl` and `TwrInflArray` routines 19fe467b0 Merge remote-tracking branch 'origin/f/SrvD_linearization' into mh-MDv2-farm 4f5baa82c Merge remote-tracking branch 'OpenFAST/dev' into f/SrvD_linearization 17795d7c0 AD sync: sort BEMT/FVW outputs in AeroDyn_IO.f90 f4f5f994a Merge remote-tracking branch 'NREL/dev' into f/Aero_Sync 73614b03d Merge branch 'dev' into static-openfast-cmake-obj-libs cf58377c8 AD/AA: remove unused variables 92effbf2f Merge branch 'b/minor_updates' into f/Aero_Sync 5d2c84832 AD: do not turn off BEM for all negative TSRs 232279486 MDv2: fix non-standard fortran 'if' statement c69c1780a MDv2: double precision compiling working 383ba9091 MDv2: convert tabs to spaces 643e51332 MDv2: update CMakeLists.txt ff59f0f27 Merge pull request #11 from andrew-platt/MDv2-farm into mattehall/MDv2-farm c825ba244 Fixed some duplication and initialization issues for Rods: dbe0239df Reset a few VS project file entries to match what is in dev 7fcc6bcc7 Merge branch 'f/SrvD_linearization' into mh-MDv2-farm fcc732f2f [BugFix] Reset WindowsTargetPlatformVersion to 8.1 c5e26157c [BugFix] reset platformtoolset to v140 74b917dd9 Fix typo in buoyancy calculation bc5c19bbd Merge remote-tracking branch 'NREL/dev' into b/minor_updates 642e4b27d Merge branch 'NREL/dev' into b/minor_updates 2043993f2 Clean up cavitation calculation 91e9a5789 Increase allowed line length in the FileInfoType parsing 44ef89240 MoorDyn: Improved error handling for Rods and WaterKin b759ca2d6 Update regression tests 1acb3d466 Merge remote tracking branch upstream/dev into feature/Buoyancy 94fd3a7b6 top level CMakeLists.txt: install downloaded lapack in src dir, not system, and do so when openfast is installed, also use correct built lapack library locations for linking before make install is invoked 2a793b4fe openfast-library/CMakeLists.txt: remove object libraries from target_link_libraries, also remove STATIC arg from add_library a1649712e supercontroller/CMakeLists.txt: add onject libs to install targets b35ce05cd Add external lapack as dependency when USE_LOCAL_STATIC_LAPACK option is used 2848f6cf2 top level CMakeLists.txt: add option to use locally built lapack and blas libraries 6a14d061c Updating CMakeLists to add object libs to install directives to fix export error, also ensure object lib deps all correct 4f4baff73 servodyn/CMakeLists.txt: correct servodyn_obj target_link_libraries 0d907d3f7 Adding more missing target_include_libraries for object libraries e5cb26d24 Adjust merged FAST_Lin additions for MDv2-farm compatibility 345669f34 Merge remote tracking branch upstream/dev into feature/Buoyancy ccdf44d65 MD Lin: add du{MD}/du{MD} term (accel + vel terms) e8f1a7bc4 MD lin: missing argument to MD_JacobianPInput 56604b116 Adding MoorDyn driver visual studio files 9cb0b1bb9 Cherry picking some overlooked linearization updates from MDv2 04e9cba86 UA/DBEMT: Allowing linearization c1024dfbe DBEMT: fixing equations for continuous DBEMT 46de657be Update regression tests to include fixed RM1 model 911ef64ba Add fixed MHK regression test to CTestList 0ab29c9f1 More modifying build system to create static libopenfast from object libraries to ensure correct linking abcd0a522 Modify build system to create static libopenfast from object libraries to ensure correct linking b009fb7fe Merge branch 'main' into dev a9512546d create_FAST_SFunc.m: need linux-specific mex call COMPFLAGS windows only -MT option differrent in gcc e2e2d2b38 openfast-cpp/CMakeLists.txt: fixed wrong case on SC.h causes install failure on linux 5184e3b8d MoorDyn waterkin and i/o updates 104f8fc69 Fix HD added mass on member end (Close #992) 6d469b2ac Clarify hub, nacelle, and water depth reference positions in AeroDyn buoyancy documentation 204fd8c44 Merge remote tracking branch upstream/dev into feature/Buoyancy 3fbfe8e94 Merge remote tracking branch upstream/dev into feature/Buoyancy 5476f0c1e Merge remote tracking branch upstream/dev into feature/Buoyancy 360fcc5d6 DBEMT: temporarily turning off Wdot, and changing tau1 e2942a5b0 UA: update driver to switch between oscillation at mid/chord or AC, and velocity at 3/4 or AC 66955bf46 UA: update of drag to better match HAWC2's implementation b4f650a19 Merge remote tracking branch upstream/dev into feature/Buoyancy 327a7af7e Merge pull request #2 from andrew-platt/feature/Buoyancy ff5b24ca1 AD buoyancy: partially resetting meshcopy u_ED_HubPtLoad to how it was 5bb6a5006 AD buoyancy: previous commit missed case of MHK without Solve Option 1 d0254604b AD buoyancy: minor modification of SolveOption1 algorithm 670926d61 Update documentation to include buoyancy db495114f Correct hub buoyancy calculation and AeroDyn to ElastoDyn mesh mapping 86517c9c4 Fix bug in error handling in buoyant loads calculation 5737fdad2 Merge remote tracking branch upstream/dev into feature/Buoyancy 8294c93e0 Adjust the allocation of a buoyancy parameter a47a0bae1 Merge remote tracking branch upstream/dev into feature/Buoyancy f21290e66 Bug fix of transverse/axial friction coefficients d4f24d01b Merge friction updates from shousner/MDv2-farm-bath into MDv2-farm 3990bce9c Update MoorDyn to new input file Body/Line format/capabilities: e3eec4abf FASTLib.vfproj update for new MD source files 72fbba80d Merge branch 'f/SrvD_linearization' into MDv2-farm: 8f9853371 MD Driver updates and line output fix: 9406880a7 Move cavitation check inside BEMT call in AeroDyn 26c65a88a Merge remote tracking branch upstream/dev into feature/Buoyancy 070dc2f88 Update regression tests 199d604e5 Update regression tests bb83995cc Remove added mass inputs and validation checks d8e620a39 Bug fix in getDepthFromBathymetry: fy, not fx in interpolation 98dab1efb Update regression tests bfca44637 Merge remote tracking branch upstream/dev into feature/AddedMass_Buoyancy 475ac1d03 Remove if statement for variable initialization in FAST_Solver 616c70e25 Update regression tests 24c06af96 Fixed the wrong index for the unit normal vector d6225f48e Fix uninitialized variables in FAST_Solver 48c9e3e25 Changes in my vs-build FAST sln file 33382c19c A couple bug fixes to the friction code 0d7c83c3a vs-build/FASTlib/FASTlib.vfproj commit 7ffb95e94 Seabed Friction Implementation d092f6ada Merge remote tracking branch upstream/dev into feature/AddedMass_Buoyancy 3e40ac156 MoorDyn: Implementation of Line bending stiffness a9ce6e907 Adding unit normal vector to seabed bathymetry interpolation: f1e6f3ed8 Adding the new MoorDyn sources files I forgot to add in commit 3a1173b2469cde453b938ab8b5977ee189ccc2ee fcb63e77d Add MD_InitInp Tmax in FAST_Subs 3a1173b24 Restructuring of MoorDyn source and wave/current addition: e90f8e706 Merge branch 'MDv2-farm-synth' into MDv2-farm 1fd6bf6a1 Remove double-counted weight in fairten outputs d22feca8f Some water depth variables changed in MoorDyn_Types I'm assuming because I recompiled/rebuilt with Matt's new changes without the water depth variable 75dfc12c9 Added temporary depth variable to make negative and store in tempArray 5a9792a35 Merge remote-tracking branch 'upstream/MDv2-farm' into MDv2-farm-bath 91373f056 First pass at setting anchor depth based on bathymetry 340610b21 Reorder input parsing in prep for auto anchor depth: e17a19c0d Merge remote-tracking branch 'stein/MDv2-farm-bath' into MDv2-farm 83c570c05 Merge remote-tracking branch 'upstream/MDv2-farm' into MDv2-farm-bath e1cf18eda Getting MD driver to give t=0 output 3770d3e49 Fixed MD driver to support nonzero initial positions: 7c241b45e MD viscoelastic adjustment to input overall static and dynamic stiffnesses 45d4d9e6b Added .fstf input validation and MD driver improvements: 4654dc125 Adding .vs folders to git ignore c50568335 Fixed inputString/OptValue character length issue that was causing long-named bathymetry files not to work. Also added an error statement call bafba40b8 Merge remote-tracking branch 'upstream/MDv2-farm' into MDv2-farm-bath 45463920b Created MDv2 driver and tweaked Rod/Body farm positions: 4d6c96c32 Correct factor of 2 error in buoyancy calculation 41f16628f Implemented simple viscoelastic capability: d5620011a Corrections in Rod end hydrodynamic added mass and inertia: 9c45c6f3e Some touchups to MoorDyn to get it to compile and run d4a9e6ff2 Third iteration of fixes for compilation: depth and BathGrid names 5801d166f Debugging error fixes: allocatable issue, syntax errors, etc. 191070f3b Replacing MoorDyn depth parameter with option for bathymetry a300ec073 Enabling MoorDyn dtOut and FAST.Farm thread/timer output: 12f3a50c5 Update regression test files after correcting merge errors d3a76f137 Update regression test files after merge with remote branch f/driver 83117efb7 Merge remote branch ebranlard:f/driver into feature/AddedMass_Buoyancy dc92d7c15 New approach succeeds in applying shared mooring forces: 64373ba9b Finishing up merging of MDv2 and fast-farm branches. Compiles and runs. 82d54d03b MoorDyn_IO fixing bug when specifying output channel node number 73d47e03b MoorDyn further edits to merge MDv2 and shared-mooring farm capablities. Now compiles. 0f1b87079 Adjusted some indenting in MoorDyn 12728ccf6 First batch of changes to make shared mooring ability work with MDv2: 43e06efdf Remaining MD I/O mesh fixes in FAST_Solver and _Lin aa2fd46db Merge Matt's f/fast-farm (shared moorings) branch into MDv2-farm 926c9aa1f Merge remote-tracking branch 'andy/f/StrucCtrl_controls' into MDv2 356bc6184 Merge branch 'dev' into f/fast-farm 044cc8dbc Fixed/improved error handling edits in FARM_UpdateStates: c52803218 MoorDyn linearization fixes and default parameters: 0a37d1206 MDv2 lin: missing initialization and unsafe size() of potentially unallocated arrays dc295314e MDv2: missed wave kin stuff in FAST_Subs for commit ca9380ce 8a4489e0c Revert commit 2ed8c232 changes to cmake setup ff925dd90 StC ctrl: controller input nominally 0 2ed8c232c SrvD array bugfix from Andy, and proper MD groundBody initialization 93225decd Update user-selectable output names in regression test input files 91a6bbb33 Add user-selectable buoyancy outputs bbed9fb2c Add buoyancy outputs to OutListParameters.xlsx ca9380ce9 Removing hard-coded wave grid for general use pending future wave capabilities ddfdff6c5 Removing 'MD can't linearize' error message 8cd93eeb0 Adding linearization subroutines to MoorDyn v2: 46dbf4f0a Update regression test files to fix typo in speed of sound label 9fdc6f59b Fix typo in speed of sound label 1cbac0c4b Fix hub load point mesh mapping conflict bewteen option 1 and 2 solves 6809ce5d0 Fix typo in nacelle buoyancy calculation 444784635 Adjust nacelle buoyancy calculation 702e736c0 Add buoyancy and added mass inputs to regression test input files b02033630 Update example input files efc61b578 Make minor changes to buoyancy and added mass inputs and update types files 7c35bd120 Merge remote tracking branch toan/features/AddMass into feature/AddedMass_Buoyancy 3fa32145d Add hub loads to output mesh 5f9e089af Add AeroDyn hub load point mesh and map to ElastoDyn 824bb9f1e Merge branch 'f/StrucCtrl_controls' of https://github.com/andrew-platt/openfast into MDv2 076cca643 Merge pull request #4 from andrew-platt/MDv2_InputFileParsing 6cf549636 Merge pull request #3 from andrew-platt/b/MDv2_minorBugs 137bb775a copyright update ced03edc2 Add added mass inputs and validation checks 13bb935f9 Add added mass inputs and validation checks de1c92fbc Merge remote-tracking branch 'hannah/feature/AddedMass_Buoyancy' into features/AddMass 15631e378 MDv2: turn off the verbose input file info ef18dc22d MDv2: changed index for line number counting to current line instead of next line 45aee88bf MDv2: potential segfault on closing files that were never opened. 8e1a2e4e0 MDv2: added FileInfo_Type parsing of input file 0e6b7dc4b MDv2: add passing of input FileInfo_Type, remove unused var from MDIO_OpenOutput 04e8ab978 Add blade, tower, and nacelle buoyant loads to output meshes 596516291 Merge remote-tracking branch 'origin/b/HD_unitializedVars' into MDv2_InputFileParsing 6d1a1a6f3 MDv2: set some uninitialized variables b5c6150ff MDv2: remove a few unnecessary REAL conversions 15e59244d Calculate nacelle buoyant loads 556ad48db MDv2: fix some array bounds issues in interpolation routines 1f285c122 MDv2: change InitInp to intent in only 39419ace2 Calculate hub buoyant loads b104356b2 Replace 1.0/0.0 with NaN -- gcc wouldn't compile 2f77648e3 Replace non-standard tabs with spaces 743b10454 Add some _Types.f90 files back in. Deleted in prior commit???? 00139e466 Remove print statements f4c688e7f Merge branch 'f/StrucCtrl_controls' of https://github.com/andrew-platt/openfast into MDv2 1e22dcee1 Updating MD version number 0d4c01298 Trap buoyant load NaN case and set to zero 5f316c129 Calculate tower buoyant loads, rename some buoyancy variables 2d7f58956 Calculate blade buoyant loads, edit buoyancy parameters 2fd0973f5 Fixed up MD input prep in FAST.Farm 7d126cdd2 Handling uncoupled turbines with a dummy node in the MD meshes e4f93cfbf Fix routineName of Farm_InitMD ee8f77222 Drafting shared moorings capability in FAST.Farm: 0106cfe38 Calculate buoyancy parameters 4cf50aa50 Merge branch 'f/StrucCtrl_controls' of https://github.com/andrew-platt/openfast into MDv2 99a982bd3 Add environmental variables to driver input files 29f5dec11 Merge branch 'f/fast-farm' of https://github.com/jjonkman/OpenFAST into f/fast-farm 47f37c54e Fix-ups from merging StrucCtrl with MDv2 work. e2a0d9416 Merge branch 'f/StrucCtrl_controls' of https://github.com/andrew-platt/openfast into MDv2 e06154815 Merge branch 'f/StrucCtrl_controls' of https://github.com/andrew-platt/openfast into MDv2 5d17d6d73 The first version shared for USFLOWT. 6ad0dd0bd Merge remote branch ebranlard:f/driver into feature/AddedMass_Buoyancy 9c7c4bb9a Add MHK turbine type switch and validation checks 95f644e19 Add buoyancy inputs and validation checks 96120686e Merge remote branch ebranlard:f/AD_multi into feature/AddedMass_Buoyancy 1c01e71df Merge remote tracking branch upstream/dev into feature/AddedMass_Buoyancy 82829f7d2 Merge remote tracking branch upstream/dev into feature/AddedMass_Buoyancy 42052413a Merge branch 'dev' of https://github.com/OpenFAST/openfast into MDv2 983d4a7c3 Ensuring no side forces in node weights d31776675 Merge remote tracking branch upstream/dev into feature/AddedMass_Buoyancy fe65caae7 Add input flags for added mass and buoyancy back into AeroDyn_IO (deleted during a merge conflict) a92ca670e Merge remote tracking branch upstream/dev into feature/AddedMass_Buoyancy and resolve merge conflict in AeroDyn_IO 82a1d2240 Bug fixes in wave grid implementation and MD Rod Froude-Krylov force. - Solved memory bug in WameMod=0 case by reordering htings. - Removing unnecessary USE WAVES and specifying "only..." in MD. - In MD, now using WaveTimes array rather than (J-1)*dtWave. - Fixed error in MD Rod Froude Krylov force calculation (was 50% too small) 3ac0590ce Merge branch 'TCF-mods2' of https://github.com/HaymanConsulting/OpenFAST into MDv2 24cc24193 Merge remote tracking branch upstream/dev into feature/AddedMass_Buoyancy 130547e45 Correction of my earlier edits in FAST_Subs - no if statements for allocating all mooring models' inputs. f9cd66224 Merge branch 'TCF-mods2' of https://github.com/HaymanConsulting/OpenFAST into MDv2 734e2468f Small adjustment/bugfix to wave grid, MoorDyn coupled Rod bugfix, MoorDyn tidying. 938fa0a65 Merge branch 'TCF-mods2' of https://github.com/HaymanConsulting/OpenFAST into MDv2 f16b590cd Adjusting hard-coded wave kinematics grid functionality to use public parameters of the Waves module. This makes it quicker to adjust the grid settings and recompile. Also fixed the allocation oversight that prevented WaveMod=0 cases from running (given this wave grid functionality). 2b4a27a78 Tiny registry fix in MD 8813a1667 Properly hooking up CaEnd and CdEnd to Rods in MoorDyn. 2e07a669c Merge branch 'TCF-mods2' of https://github.com/HaymanConsulting/OpenFAST into MDv2 701c94723 Major MoorDyn v2 changes. Introducing all the v2 objects and structure. Still some things to work out for buoyancy can applications. d8ae282c6 Merge remote tracking branch upstream/dev into feature/AddedMass_Buoyancy de02d56ad Added Mod_WaveField input to FAST.Farm for wave load phasing based on turbine positions: - New variable WaveFieldMod is passed through FAST.Farm into each OpenFAST instance to each HydroDyn module where it can adjust phases in the complex wave elevation amplitudes in Waves and Waves2. - This adds a new line for Mod_WaveField below the line for Mod_AmbWind in the FAST.Farm primary input file: - Mod_WaveField Wave field handling (-) (switch) {1: use individual HydroDyn inputs without adjustment, 2: adjust wave phases based on turbine offsets from farm origin} 8aea9125f Combine added mass coefficient input checks into a single loop a1f01297d Merge remote tracking branch upstream/dev into feature/AddedMass_Buoyancy 21cdf5765 Add input flags and coefficients for added mass and buoyancy 7f604a1c6 Edits to Waves, HydroDyn, and glue code changes to support MoorDyn v2 changes and to hard-code a simple wave kinematics grid to pass this info to MoorDyn for buoyancy cans. a0254a25f Merge branch 'MDmods' of https://github.com/mattEhall/openfast into TCF-mods2 - This brings in the initial active tension capability and the MoorDyn driver. - Much of this will be overwritten shortly by MoorDyn v2 code. 426243624 MoorDyn bug fix for tensions changing part-way through simulation. - Tension amplitudes were sometimes changing, typically at 512 s. - This was likely caused by use of single-precision time variable with MD_Input_ExtrapInterp. - All time variables are now double precision, solving the problem. git-subtree-dir: OpenFAST git-subtree-split: 6b8706b75698cb1c97c6a8e3e9f42538a63fa71b --- .gitattributes | 2 - .github/PULL_REQUEST_TEMPLATE.md | 1 - .../actions/tests-module-aerodyn/action.yml | 2 +- .../actions/tests-module-moordyn/action.yml | 21 + .github/workflows/automated-dev-tests.yml | 954 +- .gitignore | 1 + .readthedocs.yml | 2 +- CMakeLists.txt | 152 +- cmake/FindMKL.cmake | 68 - cmake/FindMatlab.cmake | 1720 -- cmake/OpenfastCmakeUtils.cmake | 4 +- cmake/OpenfastFortranOptions.cmake | 81 +- docs/CMakeLists.txt | 6 +- .../Buoyancy_Implementation_Plan_Rev11.docx | Bin 0 -> 168111 bytes .../Buoyancy_Implementation_Plan_Rev3.docx | Bin 170667 -> 0 bytes .../ElastoDyn/FASTLogicFlow.doc | Bin 25088 -> 27648 bytes .../OpenFAST_Algorithms.pdf | Bin 243381 -> 288913 bytes .../OpenFAST_Algorithms.tex | 1 + docs/OtherSupporting/OutListParameters.xlsx | Bin 570186 -> 600181 bytes docs/_static/assets_download.jpg | Bin 139599 -> 469850 bytes docs/changelogs/v3.5.0.md | 117 + docs/conf.py | 28 +- docs/requirements.txt | 1 + docs/source/dev/code_style.rst | 2 +- docs/source/install/index.rst | 4 +- docs/source/testing/index.rst | 2 - docs/source/testing/regression_test.rst | 44 +- .../testing/regression_test_windows.rst | 2 +- docs/source/testing/unit_test.rst | 4 +- docs/source/this_doc.rst | 2 +- .../user/aerodyn-aeroacoustics/App-usage.rst | 5 +- .../aerodyn-aeroacoustics/example/AD15.ipt | 5 +- .../examples/UA-driver.dvr | 5 +- .../ExampleFiles/ExampleFile--OLAF.dat | 63 +- docs/source/user/aerodyn-olaf/InputFiles.rst | 119 +- .../source/user/aerodyn-olaf/Introduction.rst | 6 +- docs/source/user/aerodyn-olaf/OLAFTheory.rst | 51 +- docs/source/user/aerodyn-olaf/RunningOLAF.rst | 280 +- docs/source/user/aerodyn/ADNodalOutputs.rst | 2 +- docs/source/user/aerodyn/Makefile | 145 + docs/source/user/aerodyn/appendix.rst | 14 +- docs/source/user/aerodyn/bibliography.bib | 22 + docs/source/user/aerodyn/conf.py | 218 + docs/source/user/aerodyn/driver.rst | 80 +- .../user/aerodyn/examples/NodalOutputs.txt | 6 + .../aerodyn/examples/ad_blade_example.dat | 50 +- .../aerodyn/examples/ad_driver_example.dvr | 9 +- .../aerodyn/examples/ad_driver_multiple.dvr | 13 +- .../aerodyn/examples/ad_primary_example.dat | 41 +- .../user/aerodyn/figs/TailFinAirfoilCoord.png | Bin 0 -> 71778 bytes .../user/aerodyn/figs/TailFinAirfoilCoord.svg | 533 + .../source/user/aerodyn/figs/TailFinCoord.png | Bin 0 -> 150637 bytes .../source/user/aerodyn/figs/TailFinCoord.svg | 635 + ..._blade_geom.png => aerodyn_blade_geom.png} | Bin ...ocal_cs.png => aerodyn_blade_local_cs.png} | Bin ...river_geom.png => aerodyn_driver_geom.png} | Bin .../aerodyn/figs/aerodyn_not_ad.README.txt | 5 + ...channel.pdf => aerodyn_output_channel.pdf} | Bin ..._tower_geom.png => aerodyn_tower_geom.png} | Bin docs/source/user/aerodyn/index.rst | 3 +- docs/source/user/aerodyn/input.rst | 300 +- docs/source/user/aerodyn/introduction.rst | 33 +- docs/source/user/aerodyn/modeling.rst | 20 +- docs/source/user/aerodyn/theory.rst | 175 + docs/source/user/aerodyn/theory_tailfin.rst | 171 + docs/source/user/aerodyn/theory_ua.rst | 24 +- docs/source/user/api_change.rst | 194 +- docs/source/user/elastodyn/Makefile | 145 + docs/source/user/elastodyn/conf.py | 218 + docs/source/user/elastodyn/coordsys.rst | 153 + .../user/elastodyn/figs/TailFinAxes.png | Bin 0 -> 165015 bytes .../user/elastodyn/figs/TailFinFurl.png | Bin 0 -> 281408 bytes .../user/elastodyn/figs/TailFinGeom.png | Bin 0 -> 256870 bytes docs/source/user/elastodyn/index.rst | 5 + docs/source/user/elastodyn/input.rst | 448 +- docs/source/user/elastodyn/theory.rst | 191 + docs/source/user/fast.farm/AppendixC.rst | 22 + docs/source/user/fast.farm/FFarmTheory.rst | 38 +- docs/source/user/fast.farm/InputFiles.rst | 158 +- docs/source/user/fast.farm/ModelGuidance.rst | 15 + docs/source/user/fast.farm/OutputFiles.rst | 24 + .../fast.farm/examples/FAST.Farm--input.dat | 162 +- docs/source/user/index.rst | 6 +- docs/source/user/inflowwind/driver.rst | 157 +- .../examples/inflowwind_driver_example.inp | 3 + .../examples/inflowwind_example.dat | 24 +- .../inflowwind/figs/FFWindExtrap--NoTower.png | Bin 0 -> 136589 bytes .../inflowwind/figs/FFWindExtrap--Tower.png | Bin 0 -> 135967 bytes docs/source/user/inflowwind/input.rst | 4 + docs/source/user/moordyn/index.rst | 12 + .../ExampleFiles/NRELOffshrBsline5MW_StC.dat | 2 +- docs/source/user/servodyn-stc/StC_input.rst | 8 +- .../subdyn/examples/OC4_Jacket_SD_Input.dat | 278 +- docs/source/user/subdyn/input_files.rst | 21 +- docs/source/user/subdyn/output_files.rst | 2 +- docs/source/user/subdyn/theory.rst | 20 +- glue-codes/CMakeLists.txt | 4 + glue-codes/fast-farm/CMakeLists.txt | 37 +- glue-codes/fast-farm/src/FASTWrapper.f90 | 118 +- .../fast-farm/src/FASTWrapper_Registry.txt | 5 + .../fast-farm/src/FASTWrapper_Types.f90 | 288 +- glue-codes/fast-farm/src/FAST_Farm_IO.f90 | 14580 +------------- .../fast-farm/src/FAST_Farm_IO_Params.f90 | 15907 ++++++++++++++++ .../fast-farm/src/FAST_Farm_Registry.txt | 27 +- glue-codes/fast-farm/src/FAST_Farm_Subs.f90 | 749 +- glue-codes/fast-farm/src/FAST_Farm_Types.f90 | 2057 +- glue-codes/openfast-cpp/CMakeLists.txt | 52 +- glue-codes/openfast-cpp/src/OpenFAST.H | 2 + glue-codes/openfast-cpp/src/OpenFAST.cpp | 16 +- glue-codes/openfast/CMakeLists.txt | 15 +- glue-codes/openfast/src/FastLibAPI.cpp | 40 +- glue-codes/openfast/src/FastLibAPI.h | 9 +- glue-codes/python/openfast_library.py | 52 +- glue-codes/simulink/CMakeLists.txt | 77 + glue-codes/simulink/README.md | 5 + glue-codes/simulink/src/FAST_SFunc.c | 3 +- glue-codes/simulink/src/create_FAST_SFunc.m | 55 +- modules/aerodyn/CMakeLists.txt | 97 +- .../python-lib/aerodyn_inflow_library.py | 970 + modules/aerodyn/src/AeroAcoustics.f90 | 279 +- modules/aerodyn/src/AeroAcoustics_IO.f90 | 199 +- modules/aerodyn/src/AeroAcoustics_TNO.f90 | 3 +- modules/aerodyn/src/AeroAcoustics_Types.f90 | 859 +- modules/aerodyn/src/AeroDyn.f90 | 2790 ++- .../aerodyn/src/AeroDyn_AllBldNdOuts_IO.f90 | 177 +- modules/aerodyn/src/AeroDyn_Driver.f90 | 212 +- .../aerodyn/src/AeroDyn_Driver_Registry.txt | 80 +- modules/aerodyn/src/AeroDyn_Driver_Subs.f90 | 1940 +- modules/aerodyn/src/AeroDyn_Driver_Types.f90 | 6178 ++---- modules/aerodyn/src/AeroDyn_IO.f90 | 3209 +--- modules/aerodyn/src/AeroDyn_IO_Params.f90 | 2479 +++ modules/aerodyn/src/AeroDyn_Inflow.f90 | 720 + .../aerodyn/src/AeroDyn_Inflow_C_Binding.f90 | 1860 ++ .../aerodyn/src/AeroDyn_Inflow_Registry.txt | 139 + modules/aerodyn/src/AeroDyn_Inflow_Types.f90 | 7325 +++++++ modules/aerodyn/src/AeroDyn_Registry.txt | 131 +- modules/aerodyn/src/AeroDyn_Types.f90 | 15255 +++++++++------ modules/aerodyn/src/AirfoilInfo_Types.f90 | 153 +- modules/aerodyn/src/BEMT.f90 | 275 +- modules/aerodyn/src/BEMTUncoupled.f90 | 840 +- modules/aerodyn/src/BEMT_Registry.txt | 46 +- modules/aerodyn/src/BEMT_Types.f90 | 1696 +- modules/aerodyn/src/DBEMT.f90 | 95 +- modules/aerodyn/src/DBEMT_Registry.txt | 4 +- modules/aerodyn/src/DBEMT_Types.f90 | 282 +- modules/aerodyn/src/FVW.f90 | 401 +- modules/aerodyn/src/FVW_BiotSavart.f90 | 22 +- modules/aerodyn/src/FVW_IO.f90 | 133 +- modules/aerodyn/src/FVW_Registry.txt | 54 +- modules/aerodyn/src/FVW_Subs.f90 | 471 +- modules/aerodyn/src/FVW_Tests.f90 | 141 +- modules/aerodyn/src/FVW_Types.f90 | 1172 +- modules/aerodyn/src/FVW_VTK.f90 | 592 - modules/aerodyn/src/FVW_VortexTools.f90 | 1078 +- modules/aerodyn/src/FVW_Wings.f90 | 33 +- modules/aerodyn/src/UA_Dvr_Subs.f90 | 176 +- modules/aerodyn/src/UnsteadyAero.f90 | 114 +- modules/aerodyn/src/UnsteadyAero_Driver.f90 | 123 +- modules/aerodyn/src/UnsteadyAero_Registry.txt | 108 +- modules/aerodyn/src/UnsteadyAero_Types.f90 | 331 +- modules/aerodyn14/CMakeLists.txt | 28 +- modules/aerodyn14/src/AeroDyn14.f90 | 9 + modules/aerodyn14/src/AeroDyn14_Types.f90 | 684 +- modules/aerodyn14/src/AeroSubs.f90 | 4 +- modules/aerodyn14/src/DWM_Types.f90 | 504 +- modules/awae/CMakeLists.txt | 6 +- modules/awae/src/AWAE.f90 | 679 +- modules/awae/src/AWAE_IO.f90 | 3 +- modules/awae/src/AWAE_Registry.txt | 21 +- modules/awae/src/AWAE_Types.f90 | 1006 +- modules/beamdyn/CMakeLists.txt | 27 +- modules/beamdyn/src/BeamDyn.f90 | 34 +- modules/beamdyn/src/BeamDyn_BldNdOuts_IO.f90 | 2 +- modules/beamdyn/src/BeamDyn_IO.f90 | 212 +- modules/beamdyn/src/BeamDyn_Types.f90 | 306 +- modules/beamdyn/src/Driver_Beam.f90 | 67 +- modules/beamdyn/src/Driver_Beam_Subs.f90 | 229 +- modules/elastodyn/CMakeLists.txt | 8 +- modules/elastodyn/src/ED_UserSubs.f90 | 9 - modules/elastodyn/src/ElastoDyn.f90 | 771 +- .../src/ElastoDyn_AllBldNdOuts_IO.f90 | 2 +- modules/elastodyn/src/ElastoDyn_IO.f90 | 1482 +- modules/elastodyn/src/ElastoDyn_Registry.txt | 120 +- modules/elastodyn/src/ElastoDyn_Types.f90 | 3234 +--- modules/extptfm/CMakeLists.txt | 6 +- modules/extptfm/src/ExtPtfm_MCKF_IO.f90 | 3 +- modules/extptfm/src/ExtPtfm_MCKF_Registry.txt | 2 +- modules/extptfm/src/ExtPtfm_MCKF_Types.f90 | 215 +- modules/feamooring/CMakeLists.txt | 21 +- modules/feamooring/src/FEAM.f90 | 5 - modules/feamooring/src/FEAMooring_Types.f90 | 216 +- modules/hydrodyn/CMakeLists.txt | 26 +- .../hydrodyn/python-lib/hydrodyn_library.py | 3 +- modules/hydrodyn/src/Conv_Radiation_Types.f90 | 180 +- modules/hydrodyn/src/Current_Types.f90 | 180 +- modules/hydrodyn/src/HydroDyn.f90 | 10 +- modules/hydrodyn/src/HydroDyn.txt | 7 + modules/hydrodyn/src/HydroDyn_C_Binding.f90 | 17 +- modules/hydrodyn/src/HydroDyn_DriverCode.f90 | 2 +- modules/hydrodyn/src/HydroDyn_Input.f90 | 7 +- modules/hydrodyn/src/HydroDyn_Output.f90 | 20 +- modules/hydrodyn/src/HydroDyn_Types.f90 | 729 +- modules/hydrodyn/src/Morison.f90 | 12 +- modules/hydrodyn/src/Morison_Output.f90 | 39 +- modules/hydrodyn/src/Morison_Types.f90 | 468 +- modules/hydrodyn/src/SS_Excitation_Types.f90 | 183 +- modules/hydrodyn/src/SS_Radiation_Types.f90 | 183 +- modules/hydrodyn/src/UserWaves.f90 | 2 +- modules/hydrodyn/src/WAMIT2.f90 | 76 +- modules/hydrodyn/src/WAMIT2.txt | 2 +- modules/hydrodyn/src/WAMIT2_Types.f90 | 252 +- modules/hydrodyn/src/WAMIT_Types.f90 | 264 +- modules/hydrodyn/src/Waves.f90 | 73 +- modules/hydrodyn/src/Waves.txt | 5 + modules/hydrodyn/src/Waves2_Output.f90 | 1 - modules/hydrodyn/src/Waves2_Types.f90 | 183 +- modules/hydrodyn/src/Waves_Types.f90 | 270 +- modules/icedyn/CMakeLists.txt | 3 +- modules/icedyn/src/IceDyn.f90 | 2 +- modules/icedyn/src/IceDyn_Types.f90 | 210 +- modules/icefloe/CMakeLists.txt | 11 +- modules/icefloe/src/icefloe/IceFloe_Types.f90 | 189 +- .../src/interfaces/ADAMS/IceADAMS_VFOSUB.f90 | 264 - .../src/interfaces/Console/SysIVF_reduced.f90 | 4 +- modules/inflowwind/CMakeLists.txt | 59 +- .../python-lib/inflowwind_library.py | 14 +- modules/inflowwind/src/CTWind.f90 | 1345 -- modules/inflowwind/src/FDWind.f90 | 1300 -- modules/inflowwind/src/IfW_4Dext.f90 | 369 - modules/inflowwind/src/IfW_4Dext.txt | 39 - modules/inflowwind/src/IfW_4Dext_Types.f90 | 830 - modules/inflowwind/src/IfW_BladedFFWind.f90 | 1896 -- modules/inflowwind/src/IfW_BladedFFWind.txt | 41 - .../inflowwind/src/IfW_BladedFFWind_Types.f90 | 797 - modules/inflowwind/src/IfW_C_Binding.f90 | 40 +- modules/inflowwind/src/IfW_FFWind_Base.f90 | 1172 -- modules/inflowwind/src/IfW_FFWind_Base.txt | 53 - .../inflowwind/src/IfW_FFWind_Base_Types.f90 | 711 - modules/inflowwind/src/IfW_FlowField.f90 | 2050 ++ modules/inflowwind/src/IfW_FlowField.txt | 124 + .../inflowwind/src/IfW_FlowField_Types.f90 | 3583 ++++ modules/inflowwind/src/IfW_HAWCWind.f90 | 387 - modules/inflowwind/src/IfW_HAWCWind.txt | 52 - modules/inflowwind/src/IfW_HAWCWind_Types.f90 | 1609 -- modules/inflowwind/src/IfW_TSFFWind.f90 | 659 - modules/inflowwind/src/IfW_TSFFWind.txt | 33 - modules/inflowwind/src/IfW_TSFFWind_Types.f90 | 738 - modules/inflowwind/src/IfW_UniformWind.f90 | 1121 -- modules/inflowwind/src/IfW_UniformWind.txt | 67 - .../inflowwind/src/IfW_UniformWind_Types.f90 | 1484 -- modules/inflowwind/src/IfW_UserWind.f90 | 286 - modules/inflowwind/src/IfW_UserWind.txt | 36 - modules/inflowwind/src/IfW_UserWind_Types.f90 | 646 - modules/inflowwind/src/InflowWind.f90 | 1600 +- modules/inflowwind/src/InflowWind.txt | 133 +- modules/inflowwind/src/InflowWind_Driver.f90 | 356 +- .../inflowwind/src/InflowWind_Driver_Subs.f90 | 398 +- .../src/InflowWind_Driver_Types.f90 | 64 +- modules/inflowwind/src/InflowWind_IO.f90 | 2937 +++ modules/inflowwind/src/InflowWind_IO.txt | 92 + .../inflowwind/src/InflowWind_IO_Types.f90 | 2209 +++ modules/inflowwind/src/InflowWind_Subs.f90 | 977 +- modules/inflowwind/src/InflowWind_Types.f90 | 4256 ++--- modules/inflowwind/src/Lidar.f90 | 191 +- modules/inflowwind/src/Lidar.txt | 90 +- modules/inflowwind/src/Lidar_Types.f90 | 780 +- modules/inflowwind/tests/ifw_test_tools.F90 | 32 +- modules/inflowwind/tests/test_outputs.F90 | 2 +- modules/inflowwind/tests/test_steady_wind.F90 | 2 +- .../inflowwind/tests/test_uniform_wind.F90 | 12 +- modules/map/CMakeLists.txt | 38 +- modules/map/src/MAP_Fortran_Types.f90 | 54 +- modules/map/src/MAP_Types.f90 | 376 +- modules/map/src/lineroutines.h | 2 +- modules/map/src/mapinit.c | 4 +- modules/moordyn/CMakeLists.txt | 39 +- modules/moordyn/README.md | 3 - modules/moordyn/python-lib/moordyn_library.py | 412 + modules/moordyn/src/MoorDyn.f90 | 5088 +++-- modules/moordyn/src/MoorDyn_Body.f90 | 545 + modules/moordyn/src/MoorDyn_C_Binding.f90 | 745 + modules/moordyn/src/MoorDyn_Driver.f90 | 910 +- modules/moordyn/src/MoorDyn_IO.f90 | 1795 +- modules/moordyn/src/MoorDyn_Line.f90 | 1635 ++ modules/moordyn/src/MoorDyn_Misc.f90 | 2110 ++ modules/moordyn/src/MoorDyn_Point.f90 | 419 + modules/moordyn/src/MoorDyn_Registry.txt | 376 +- modules/moordyn/src/MoorDyn_Rod.f90 | 1194 ++ modules/moordyn/src/MoorDyn_Types.f90 | 13637 ++++++++++--- modules/moordyn/src/MoorDyn_bathymetry.txt | 8 + modules/nwtc-library/CMakeLists.txt | 150 +- modules/nwtc-library/src/JSON.f90 | 170 + modules/nwtc-library/src/ModMesh.f90 | 116 +- modules/nwtc-library/src/ModMesh_Mapping.f90 | 110 +- modules/nwtc-library/src/NWTC_Base.f90 | 15 +- modules/nwtc-library/src/NWTC_IO.f90 | 1435 +- modules/nwtc-library/src/NWTC_Library.f90 | 1 + .../nwtc-library/src/NWTC_Library_Types.f90 | 108 +- modules/nwtc-library/src/NWTC_Num.f90 | 1375 +- .../nwtc-library/src/NWTC_RandomNumber.f90 | 28 - .../src/NetLib/scalapack/NWTC_ScaLAPACK.f90 | 4 +- .../src/NetLib/slatec/NWTC_SLATEC.f90 | 16 +- .../nwtc-library/src/Polynomial/quartic.f90 | 591 + .../nwtc-library/src/Polynomial/readme.txt | 63 + .../Registry_NWTC_Library_typedef_nomesh.txt | 4 +- modules/nwtc-library/src/SingPrec.f90 | 33 +- modules/nwtc-library/src/SysFlangLinux.f90 | 461 + modules/nwtc-library/src/SysGnuLinux.f90 | 31 +- modules/nwtc-library/src/SysGnuWin.f90 | 31 +- modules/nwtc-library/src/SysIFL.f90 | 31 +- modules/nwtc-library/src/SysIVF.f90 | 34 +- modules/nwtc-library/src/SysIVF_Labview.f90 | 30 +- .../nwtc-library/src/SysMatlabLinuxGnu.f90 | 31 +- .../nwtc-library/src/SysMatlabLinuxIntel.f90 | 31 +- modules/nwtc-library/src/SysMatlabWindows.f90 | 32 +- modules/nwtc-library/src/VTK.f90 | 972 + .../Yaml.f90 => nwtc-library/src/YAML.f90} | 686 +- modules/openfast-library/CMakeLists.txt | 94 +- modules/openfast-library/src/FAST_Library.f90 | 9 +- modules/openfast-library/src/FAST_Library.h | 18 +- modules/openfast-library/src/FAST_Lin.f90 | 419 +- modules/openfast-library/src/FAST_Mods.f90 | 2 - .../openfast-library/src/FAST_Registry.txt | 21 +- modules/openfast-library/src/FAST_Solver.f90 | 325 +- modules/openfast-library/src/FAST_Subs.f90 | 517 +- modules/openfast-library/src/FAST_Types.f90 | 2609 ++- modules/openfast-registry/src/data.h | 2 + .../openfast-registry/src/gen_module_files.c | 187 +- modules/openfast-registry/src/reg_parse.c | 52 +- modules/openfast-registry/src/type.c | 4 +- modules/openfoam/CMakeLists.txt | 25 +- modules/openfoam/src/OpenFOAM.f90 | 1532 +- modules/openfoam/src/OpenFOAM_Registry.txt | 33 +- modules/openfoam/src/OpenFOAM_Types.f90 | 903 +- modules/openfoam/src/OpenFOAM_Types.h | 6 +- modules/orcaflex-interface/CMakeLists.txt | 18 +- .../src/OrcaFlexInterface.f90 | 5 - .../src/OrcaFlexInterface_Types.f90 | 213 +- modules/servodyn/CMakeLists.txt | 37 +- modules/servodyn/src/BladedInterface_EX.f90 | 96 +- modules/servodyn/src/PitchCntrl_ACH.f90 | 12 +- modules/servodyn/src/ServoDyn.f90 | 22 + modules/servodyn/src/ServoDyn_IO.f90 | 8 +- modules/servodyn/src/ServoDyn_Registry.txt | 30 +- modules/servodyn/src/ServoDyn_Types.f90 | 1211 +- modules/servodyn/src/StrucCtrl.f90 | 47 +- modules/servodyn/src/StrucCtrl_Types.f90 | 228 +- modules/servodyn/src/UserSubs.f90 | 16 +- modules/subdyn/CMakeLists.txt | 14 +- modules/subdyn/src/FEM.f90 | 32 +- modules/subdyn/src/SD_FEM.f90 | 201 +- modules/subdyn/src/SubDyn.f90 | 444 +- modules/subdyn/src/SubDyn_Output.f90 | 1 + modules/subdyn/src/SubDyn_Registry.txt | 24 +- modules/subdyn/src/SubDyn_Types.f90 | 786 +- modules/supercontroller/CMakeLists.txt | 45 +- .../supercontroller/src/SCDataEx_Types.f90 | 114 +- modules/supercontroller/src/SC_DLL.F90 | 80 +- .../src/SuperController_Types.f90 | 242 +- modules/turbsim/CMakeLists.txt | 12 +- modules/turbsim/src/TS_FileIO.f90 | 2 +- modules/turbsim/src/TSsubs.f90 | 19 +- modules/version/CMakeLists.txt | 3 +- modules/wakedynamics/CMakeLists.txt | 6 +- modules/wakedynamics/src/WakeDynamics.f90 | 1109 +- .../src/WakeDynamics_Registry.txt | 76 +- .../wakedynamics/src/WakeDynamics_Types.f90 | 2257 ++- reg_tests/CMakeLists.txt | 61 +- reg_tests/CTestList.cmake | 150 +- reg_tests/README.md | 2 +- reg_tests/executeAerodynPyRegressionCase.py | 137 + reg_tests/executeAerodynRegressionCase.py | 66 +- reg_tests/executeBeamdynRegressionCase.py | 57 +- reg_tests/executeFASTFarmRegressionCase.py | 96 +- reg_tests/executeHydrodynPyRegressionCase.py | 63 +- reg_tests/executeHydrodynRegressionCase.py | 78 +- .../executeInflowwindPyRegressionCase.py | 57 +- reg_tests/executeInflowwindRegressionCase.py | 63 +- reg_tests/executeMoordynPyRegressionCase.py | 136 + reg_tests/executeMoordynRegressionCase.py | 143 + ...ecuteOpenfastAeroAcousticRegressionCase.py | 95 +- reg_tests/executeOpenfastCppRegressionCase.py | 93 +- .../executeOpenfastLinearRegressionCase.py | 84 +- reg_tests/executeOpenfastRegressionCase.py | 94 +- reg_tests/executePythonRegressionCase.py | 94 +- reg_tests/executeSubdynRegressionCase.py | 58 +- .../executeUnsteadyAeroRegressionCase.py | 164 + reg_tests/lib/errorPlotting.py | 133 +- reg_tests/lib/fast_io.py | 4 +- reg_tests/lib/openfastDrivers.py | 33 +- reg_tests/lib/pass_fail.py | 90 +- reg_tests/lib/rtestlib.py | 27 +- reg_tests/manualRegressionTest.py | 54 +- reg_tests/r-test | 2 +- unit_tests/CMakeLists.txt | 48 +- unit_tests/aerodyn/CMakeLists.txt | 12 +- unit_tests/beamdyn/CMakeLists.txt | 10 +- unit_tests/inflowwind/CMakeLists.txt | 10 +- unit_tests/nwtc-library/CMakeLists.txt | 10 +- unit_tests/version/CMakeLists.txt | 10 +- vs-build/AeroDyn/AeroDyn_Driver.vfproj | 350 +- .../AeroDyn_Inflow_c_binding.sln | 84 + .../AeroDyn_Inflow_c_binding.vfproj | 1054 + vs-build/BeamDyn/BeamDyn.vfproj | 12 +- vs-build/FAST-farm/FAST-Farm.vfproj | 5 +- vs-build/FAST/FAST.vfproj | 8 +- vs-build/FASTlib/FASTlib.vfproj | 1403 +- vs-build/HydroDyn/HydroDynDriver.vfproj | 27 +- .../HydroDyn_c_binding.sln} | 2 +- .../HydroDyn_c_binding.vfproj} | 22 +- vs-build/InflowWind/InflowWind_driver.vfproj | 190 +- .../InflowWind_c_binding.vfproj | 202 +- vs-build/MAPlib/MAP_dll.vcxproj | 3 +- vs-build/MoorDyn/MoorDynDriver.sln | 37 + vs-build/MoorDyn/MoorDynDriver.vfproj | 244 + .../MoorDyn_c_binding/MoorDyn_c_binding.sln | 64 + .../MoorDyn_c_binding.vfproj | 264 + vs-build/Registry/FAST_Registry.vcxproj | 2 +- vs-build/RunRegistry.bat | 21 +- vs-build/SubDyn/SubDyn.sln | 15 +- vs-build/SubDyn/SubDyn.vfproj | 14 +- vs-build/TurbSim/TurbSim.vfproj | 3 +- vs-build/UnsteadyAero/UnsteadyAero.vfproj | 11 +- 423 files changed, 125378 insertions(+), 76408 deletions(-) create mode 100644 .github/actions/tests-module-moordyn/action.yml delete mode 100644 cmake/FindMKL.cmake delete mode 100644 cmake/FindMatlab.cmake create mode 100644 docs/OtherSupporting/AeroDyn/Buoyancy_Implementation_Plan_Rev11.docx delete mode 100644 docs/OtherSupporting/AeroDyn/Buoyancy_Implementation_Plan_Rev3.docx create mode 100644 docs/changelogs/v3.5.0.md create mode 100644 docs/source/user/aerodyn/Makefile create mode 100644 docs/source/user/aerodyn/conf.py create mode 100644 docs/source/user/aerodyn/figs/TailFinAirfoilCoord.png create mode 100644 docs/source/user/aerodyn/figs/TailFinAirfoilCoord.svg create mode 100644 docs/source/user/aerodyn/figs/TailFinCoord.png create mode 100644 docs/source/user/aerodyn/figs/TailFinCoord.svg rename docs/source/user/aerodyn/figs/{ad_blade_geom.png => aerodyn_blade_geom.png} (100%) rename docs/source/user/aerodyn/figs/{ad_blade_local_cs.png => aerodyn_blade_local_cs.png} (100%) rename docs/source/user/aerodyn/figs/{ad_driver_geom.png => aerodyn_driver_geom.png} (100%) create mode 100644 docs/source/user/aerodyn/figs/aerodyn_not_ad.README.txt rename docs/source/user/aerodyn/figs/{ad_output_channel.pdf => aerodyn_output_channel.pdf} (100%) rename docs/source/user/aerodyn/figs/{ad_tower_geom.png => aerodyn_tower_geom.png} (100%) create mode 100644 docs/source/user/aerodyn/theory_tailfin.rst create mode 100644 docs/source/user/elastodyn/Makefile create mode 100644 docs/source/user/elastodyn/conf.py create mode 100644 docs/source/user/elastodyn/coordsys.rst create mode 100644 docs/source/user/elastodyn/figs/TailFinAxes.png create mode 100644 docs/source/user/elastodyn/figs/TailFinFurl.png create mode 100644 docs/source/user/elastodyn/figs/TailFinGeom.png create mode 100644 docs/source/user/elastodyn/theory.rst create mode 100644 docs/source/user/inflowwind/figs/FFWindExtrap--NoTower.png create mode 100644 docs/source/user/inflowwind/figs/FFWindExtrap--Tower.png create mode 100644 docs/source/user/moordyn/index.rst create mode 100644 glue-codes/fast-farm/src/FAST_Farm_IO_Params.f90 create mode 100644 glue-codes/simulink/CMakeLists.txt create mode 100644 glue-codes/simulink/README.md create mode 100644 modules/aerodyn/python-lib/aerodyn_inflow_library.py create mode 100644 modules/aerodyn/src/AeroDyn_IO_Params.f90 create mode 100644 modules/aerodyn/src/AeroDyn_Inflow.f90 create mode 100644 modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 create mode 100644 modules/aerodyn/src/AeroDyn_Inflow_Registry.txt create mode 100644 modules/aerodyn/src/AeroDyn_Inflow_Types.f90 delete mode 100644 modules/aerodyn/src/FVW_VTK.f90 delete mode 100644 modules/icefloe/src/interfaces/ADAMS/IceADAMS_VFOSUB.f90 delete mode 100644 modules/inflowwind/src/CTWind.f90 delete mode 100644 modules/inflowwind/src/FDWind.f90 delete mode 100644 modules/inflowwind/src/IfW_4Dext.f90 delete mode 100644 modules/inflowwind/src/IfW_4Dext.txt delete mode 100644 modules/inflowwind/src/IfW_4Dext_Types.f90 delete mode 100644 modules/inflowwind/src/IfW_BladedFFWind.f90 delete mode 100644 modules/inflowwind/src/IfW_BladedFFWind.txt delete mode 100644 modules/inflowwind/src/IfW_BladedFFWind_Types.f90 delete mode 100644 modules/inflowwind/src/IfW_FFWind_Base.f90 delete mode 100644 modules/inflowwind/src/IfW_FFWind_Base.txt delete mode 100644 modules/inflowwind/src/IfW_FFWind_Base_Types.f90 create mode 100644 modules/inflowwind/src/IfW_FlowField.f90 create mode 100644 modules/inflowwind/src/IfW_FlowField.txt create mode 100644 modules/inflowwind/src/IfW_FlowField_Types.f90 delete mode 100644 modules/inflowwind/src/IfW_HAWCWind.f90 delete mode 100644 modules/inflowwind/src/IfW_HAWCWind.txt delete mode 100644 modules/inflowwind/src/IfW_HAWCWind_Types.f90 delete mode 100644 modules/inflowwind/src/IfW_TSFFWind.f90 delete mode 100644 modules/inflowwind/src/IfW_TSFFWind.txt delete mode 100644 modules/inflowwind/src/IfW_TSFFWind_Types.f90 delete mode 100644 modules/inflowwind/src/IfW_UniformWind.f90 delete mode 100644 modules/inflowwind/src/IfW_UniformWind.txt delete mode 100644 modules/inflowwind/src/IfW_UniformWind_Types.f90 delete mode 100644 modules/inflowwind/src/IfW_UserWind.f90 delete mode 100644 modules/inflowwind/src/IfW_UserWind.txt delete mode 100644 modules/inflowwind/src/IfW_UserWind_Types.f90 create mode 100644 modules/inflowwind/src/InflowWind_IO.f90 create mode 100644 modules/inflowwind/src/InflowWind_IO.txt create mode 100644 modules/inflowwind/src/InflowWind_IO_Types.f90 create mode 100644 modules/moordyn/python-lib/moordyn_library.py create mode 100644 modules/moordyn/src/MoorDyn_Body.f90 create mode 100644 modules/moordyn/src/MoorDyn_C_Binding.f90 create mode 100644 modules/moordyn/src/MoorDyn_Line.f90 create mode 100644 modules/moordyn/src/MoorDyn_Misc.f90 create mode 100644 modules/moordyn/src/MoorDyn_Point.f90 create mode 100644 modules/moordyn/src/MoorDyn_Rod.f90 create mode 100644 modules/moordyn/src/MoorDyn_bathymetry.txt create mode 100644 modules/nwtc-library/src/JSON.f90 create mode 100644 modules/nwtc-library/src/Polynomial/quartic.f90 create mode 100644 modules/nwtc-library/src/Polynomial/readme.txt create mode 100644 modules/nwtc-library/src/SysFlangLinux.f90 create mode 100644 modules/nwtc-library/src/VTK.f90 rename modules/{subdyn/src/Yaml.f90 => nwtc-library/src/YAML.f90} (56%) create mode 100644 reg_tests/executeAerodynPyRegressionCase.py create mode 100644 reg_tests/executeMoordynPyRegressionCase.py create mode 100644 reg_tests/executeMoordynRegressionCase.py create mode 100644 reg_tests/executeUnsteadyAeroRegressionCase.py create mode 100644 vs-build/AeroDyn_Inflow_c_binding/AeroDyn_Inflow_c_binding.sln create mode 100644 vs-build/AeroDyn_Inflow_c_binding/AeroDyn_Inflow_c_binding.vfproj rename vs-build/{HydroDyn_c_lib/HydroDynDriver_c_lib.sln => HydroDyn_c_binding/HydroDyn_c_binding.sln} (96%) rename vs-build/{HydroDyn_c_lib/HydroDynDriver_c_lib.vfproj => HydroDyn_c_binding/HydroDyn_c_binding.vfproj} (91%) create mode 100644 vs-build/MoorDyn/MoorDynDriver.sln create mode 100644 vs-build/MoorDyn/MoorDynDriver.vfproj create mode 100644 vs-build/MoorDyn_c_binding/MoorDyn_c_binding.sln create mode 100644 vs-build/MoorDyn_c_binding/MoorDyn_c_binding.vfproj diff --git a/.gitattributes b/.gitattributes index 096b1c29a..3cabefadc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,4 @@ # add (semi-useful) version info to git archive CreateGitVersion.bat ident export-subst - # Declare files that will always have CRLF line endings on checkout. *.bat text eol=crlf - diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 2a941bef2..48085ccba 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -25,7 +25,6 @@ - [ ] Create a merge commit in r-test and add a corresponding tag - [ ] Compile executables for Windows builds - [ ] FAST_SFunc.mexw64 - - [ ] MAP_X64.dll - [ ] OpenFAST-Simulink_x64.dll - [ ] openfast_x64.exe - [ ] DISCON.dll diff --git a/.github/actions/tests-module-aerodyn/action.yml b/.github/actions/tests-module-aerodyn/action.yml index 7dd9fb557..950663ab8 100644 --- a/.github/actions/tests-module-aerodyn/action.yml +++ b/.github/actions/tests-module-aerodyn/action.yml @@ -18,7 +18,7 @@ runs: fi if [[ ${{ inputs.test-target }} == "regression" ]] || [[ ${{ inputs.test-target }} == "all" ]]; then - ctest -VV -R ad_ # -j7 do not run these tests in parallel due to a bug in accessing shared files + ctest -VV -R ad_ -LE python # -j7 do not run these tests in parallel due to a bug in accessing shared files fi working-directory: ${{runner.workspace}}/openfast/build diff --git a/.github/actions/tests-module-moordyn/action.yml b/.github/actions/tests-module-moordyn/action.yml new file mode 100644 index 000000000..b071285f0 --- /dev/null +++ b/.github/actions/tests-module-moordyn/action.yml @@ -0,0 +1,21 @@ +name: 'MoorDyn module tests' +description: 'Run tests specific to the MoorDyn module' +author: 'Andy Platt https://github.com/andrew-platt' + + +inputs: + test-target: + description: 'Which tests to run: unit | regression | all' + default: 'all' + +runs: + using: "composite" + steps: + - run: | + + if [[ ${{ inputs.test-target }} == "regression" ]] || [[ ${{ inputs.test-target }} == "all" ]]; then + ctest -VV -j7 -R md_ -LE python + fi + + working-directory: ${{runner.workspace}}/openfast/build + shell: bash diff --git a/.github/workflows/automated-dev-tests.yml b/.github/workflows/automated-dev-tests.yml index a04fc80a2..7da144a29 100644 --- a/.github/workflows/automated-dev-tests.yml +++ b/.github/workflows/automated-dev-tests.yml @@ -1,4 +1,4 @@ - + name: 'Development Pipeline' on: @@ -16,35 +16,40 @@ on: # paths-ignore: env: - FORTRAN_COMPILER: gfortran-10 - CXX_COMPILER: g++-10 - C_COMPILER: gcc-10 - GCOV_EXE: gcov-10 - NUM_PROCS: 8 + FORTRAN_COMPILER: gfortran-12 + CXX_COMPILER: g++-12 + C_COMPILER: gcc-12 + GCOV_EXE: gcov-12 + CMAKE_BUILD_PARALLEL_LEVEL: 8 jobs: - regression-tests-aerodyn-driver: - runs-on: ubuntu-20.04 + ### BUILD JOBS + + + build-all-debug: + # Tests compiling in debug mode. + # Also compiles the Registry and generates new types files. + # Debug more speeds up the build. + runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@main with: submodules: recursive - - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: - python-version: '3.7' + python-version: '3.9' + cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip - pip install numpy Bokeh==1.4 - - - name: Setup Workspace + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + - name: Setup workspace run: cmake -E make_directory ${{runner.workspace}}/openfast/build - - name: Configure Build + - name: Configure build working-directory: ${{runner.workspace}}/openfast/build run: | cmake \ @@ -52,47 +57,75 @@ jobs: -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ -DCMAKE_CXX_COMPILER:STRING=${{env.CXX_COMPILER}} \ -DCMAKE_C_COMPILER:STRING=${{env.C_COMPILER}} \ - -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo \ + -DCMAKE_BUILD_TYPE:STRING=DEBUG \ + -DBUILD_SHARED_LIBS:BOOL=OFF \ + -DGENERATE_TYPES=ON \ + -DVARIABLE_TRACKING=OFF \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ ${GITHUB_WORKSPACE} - - name: Build AeroDyn Driver + # -DDOUBLE_PRECISION=OFF \ + - name: Build all working-directory: ${{runner.workspace}}/openfast/build - run: cmake --build . --target aerodyn_driver -- -j ${{env.NUM_PROCS}} - - - name: Run AeroDyn tests - uses: ./.github/actions/tests-module-aerodyn + run: | + cmake --build . --target all + - name: Cache the workspace + uses: actions/cache@v3.0.4 with: - test-target: regression - - - name: Failing test artifacts - uses: actions/upload-artifact@v2 - if: failure() + path: ${{runner.workspace}} + key: build-all-debug-${{ github.sha }} + + build-all-debug-single: + # Tests compiling in debug mode with single precision. + # This workspace is not used by any other subtests, it checks type errors of the type ReKi/R8Ki + # Debug speeds up the build. + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@main with: - name: regression-tests-aerodyn-module - path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules + submodules: recursive + - name: Setup workspace + run: cmake -E make_directory ${{runner.workspace}}/openfast/build + - name: Configure build + working-directory: ${{runner.workspace}}/openfast/build + run: | + cmake \ + -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/openfast/install \ + -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ + -DCMAKE_CXX_COMPILER:STRING=${{env.CXX_COMPILER}} \ + -DCMAKE_C_COMPILER:STRING=${{env.C_COMPILER}} \ + -DCMAKE_BUILD_TYPE:STRING=DEBUG \ + -DBUILD_SHARED_LIBS:BOOL=OFF \ + -DVARIABLE_TRACKING=OFF \ + -DDOUBLE_PRECISION:BOOL=OFF \ + ${GITHUB_WORKSPACE} + - name: Build all + working-directory: ${{runner.workspace}}/openfast/build + run: | + cmake --build . --target all - regression-tests-release: - runs-on: ubuntu-20.04 + + + build-drivers-release: + runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@main with: submodules: recursive - - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: - python-version: '3.7' + python-version: '3.9' + cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip - pip install numpy Bokeh==1.4 - - - name: Setup Workspace + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + - name: Setup workspace run: cmake -E make_directory ${{runner.workspace}}/openfast/build - - name: Configure Build + - name: Configure build working-directory: ${{runner.workspace}}/openfast/build run: | cmake \ @@ -101,400 +134,711 @@ jobs: -DCMAKE_CXX_COMPILER:STRING=${{env.CXX_COMPILER}} \ -DCMAKE_C_COMPILER:STRING=${{env.C_COMPILER}} \ -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo \ + -DVARIABLE_TRACKING=OFF \ -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') + - name: Build module drivers working-directory: ${{runner.workspace}}/openfast/build - run: cmake --build . --target install -- -j ${{env.NUM_PROCS}} - - # SubDyn has only regression tests - - name: Run SubDyn tests - uses: ./.github/actions/tests-module-subdyn - # - name: Run AeroDyn tests - # uses: ./.github/actions/tests-module-aerodyn - # with: - # test-target: regression - # HydroDyn has only regression tests - - name: Run HydroDyn tests - uses: ./.github/actions/tests-module-hydrodyn - - name: Run InflowWind tests - uses: ./.github/actions/tests-module-inflowwind - with: - test-target: regression - - name: Run BeamDyn tests - uses: ./.github/actions/tests-module-beamdyn + run: | + cmake --build . --target regression_test_module_drivers + - name: Cache the workspace + uses: actions/cache@v3.0.4 with: - test-target: regression - - 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 + path: ${{runner.workspace}} + key: build-drivers-release-${{ github.sha }} - - name: Failing test artifacts - uses: actions/upload-artifact@v2 - if: failure() - with: - name: regression-tests-release - path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline - regression-tests-debug: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - os: macOS-11 - FORTRAN_COMPILER: gfortran-11 - install_deps: brew install gcovr - - os: ubuntu-20.04 - FORTRAN_COMPILER: gfortran-10 - install_deps: sudo apt-get update && sudo apt-get install -y gcovr - - name: regression-test-debug-${{ matrix.os }}-${{ matrix.FORTRAN_COMPILER }} + build-postlib-release: + runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@main with: submodules: recursive - - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: - python-version: '3.7' - - name: Install Dependencies + python-version: '3.9' + cache: 'pip' + - name: Install dependencies run: | python -m pip install --upgrade pip - pip install numpy Bokeh==1.4 - ${{matrix.install_deps}} - - - name: Setup Workspace + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + sudo apt-get update -y + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev # gcovr + - name: Setup workspace run: cmake -E make_directory ${{runner.workspace}}/openfast/build - - name: Configure Build + - name: Configure build working-directory: ${{runner.workspace}}/openfast/build run: | cmake \ -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/openfast/install \ - -DCMAKE_Fortran_COMPILER:STRING=${{matrix.FORTRAN_COMPILER}} \ + -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ -DCMAKE_CXX_COMPILER:STRING=${{env.CXX_COMPILER}} \ -DCMAKE_C_COMPILER:STRING=${{env.C_COMPILER}} \ - -DCMAKE_BUILD_TYPE:STRING=Debug \ + -DCMAKE_BUILD_TYPE:STRING=RELWITHDEBINFO \ + -DOPENMP:BOOL=ON \ + -DDOUBLE_PRECISION=ON \ + -DVARIABLE_TRACKING=OFF \ + -DBUILD_FASTFARM:BOOL=ON \ + -DBUILD_OPENFAST_CPP_API:BOOL=ON \ + -DBUILD_SHARED_LIBS:BOOL=OFF \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ ${GITHUB_WORKSPACE} + - name: Build openfast-postlib + working-directory: ${{runner.workspace}}/openfast/build + run: cmake --build . --target openfast_postlib + - name: Cache the workspace + uses: actions/cache@v3.0.4 + with: + path: ${{runner.workspace}} + key: build-postlib-release-${{ github.sha }} + - - name: Build Drivers + build-interfaces-release: + runs-on: ubuntu-22.04 + needs: build-postlib-release + steps: + - name: Cache the workspace + uses: actions/cache@v3.0.4 + with: + path: ${{runner.workspace}} + key: build-postlib-release-${{ github.sha }} + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: '3.9' + cache: 'pip' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + sudo apt-get update -y + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Build OpenFAST C-Interfaces working-directory: ${{runner.workspace}}/openfast/build run: | - cmake --build . --target aerodyn_driver -- -j ${{env.NUM_PROCS}} - cmake --build . --target beamdyn_driver -- -j ${{env.NUM_PROCS}} - cmake --build . --target hydrodyn_driver -- -j ${{env.NUM_PROCS}} - cmake --build . --target inflowwind_driver -- -j ${{env.NUM_PROCS}} - cmake --build . --target subdyn_driver -- -j ${{env.NUM_PROCS}} + cmake --build . --target openfastlib openfast_cpp openfastcpp aerodyn_inflow_c_binding moordyn_c_binding ifw_c_binding hydrodyn_c_binding regression_test_controllers + - name: Cache the workspace + uses: actions/cache@v3.0.4 + with: + path: ${{runner.workspace}} + key: build-interfaces-release-${{ github.sha }} - - name: Run SubDyn tests - uses: ./.github/actions/tests-module-subdyn - # - name: Run AeroDyn tests - # uses: ./.github/actions/tests-module-aerodyn - # with: - # test-target: regression - - name: Run HydroDyn tests - uses: ./.github/actions/tests-module-hydrodyn - - name: Run InflowWind tests - uses: ./.github/actions/tests-module-inflowwind + + build-openfast-release: + runs-on: ubuntu-22.04 + needs: build-postlib-release + steps: + - name: Cache the workspace + uses: actions/cache@v3.0.4 with: - test-target: regression - - name: Run BeamDyn tests - uses: ./.github/actions/tests-module-beamdyn + path: ${{runner.workspace}} + key: build-postlib-release-${{ github.sha }} + - name: Setup Python + uses: actions/setup-python@v3 with: - test-target: regression + python-version: '3.9' + cache: 'pip' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + sudo apt-get update -y + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Build OpenFAST glue-code + working-directory: ${{runner.workspace}}/openfast/build + run: | + cmake --build . --target openfast + - name: Cache the workspace + uses: actions/cache@v3.0.4 + with: + path: ${{runner.workspace}} + key: build-openfast-release-${{ github.sha }} - # Disabled Codecov since the dashboard and GitHub comments were buggy, - # but it may be useful to post the gcov coverage reports to GitHub Actions - # artifacts. - # Note: if reenabling Codecov, the reports must be in xml format not html. - # - name: Generate coverage report - # working-directory: ${{runner.workspace}}/openfast/build - # run: | - # find . -type f -name '*.gcno' -not -path "**tests**" -exec ${{env.GCOV_EXE}} -pb {} + - # cd .. - # gcovr -g -k -r . --html --html-details -o regressioncov.html # -v - # # cp `find . -name *.gcno` . - # # cp `find . -name *.gcda` . - # # ${{env.GCOV_EXE}} -b -l -p -c *.gcno - # - name: Success artifacts - # uses: actions/upload-artifact@v2 - # if: success() - # with: - # name: regression-tests-debug - # path: | - # ${{runner.workspace}}/openfast/regressioncov.html - - name: Failing test artifacts - uses: actions/upload-artifact@v2 - if: failure() + + build-fastfarm-release: + runs-on: ubuntu-22.04 + needs: build-postlib-release + steps: + - name: Cache the workspace + uses: actions/cache@v3.0.4 with: - name: regression-tests-debug - path: | - ${{runner.workspace}}/openfast/build/reg_tests/modules + path: ${{runner.workspace}} + key: build-postlib-release-${{ github.sha }} + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: '3.9' + cache: 'pip' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + sudo apt-get update -y + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Build FAST.Farm + working-directory: ${{runner.workspace}}/openfast/build + run: | + cmake --build . --target FAST.Farm + - name: Cache the workspace + uses: actions/cache@v3.0.4 + with: + path: ${{runner.workspace}} + key: build-fastfarm-release-${{ github.sha }} + + + + ### BUILD AND TEST JOBS - fastfarm-regression-test: - runs-on: ubuntu-20.04 + build-test-uadriver-debug: + # UA driver requires -DUA_OUTS, cannot be compiled with other + runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@main with: submodules: recursive - - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: - python-version: '3.7' + python-version: '3.9' + cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip - pip install numpy Bokeh==1.4 - - - name: Setup Workspace + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + - name: Setup workspace run: cmake -E make_directory ${{runner.workspace}}/openfast/build - - name: Configure Build + - name: Configure build working-directory: ${{runner.workspace}}/openfast/build run: | cmake \ -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/openfast/install \ -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ - -DOPENMP:BOOL=ON \ - -DBUILD_FASTFARM:BOOL=ON \ - -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo \ + -DCMAKE_CXX_COMPILER:STRING=${{env.CXX_COMPILER}} \ + -DCMAKE_C_COMPILER:STRING=${{env.C_COMPILER}} \ + -DCMAKE_BUILD_TYPE:STRING=DEBUG \ + -DBUILD_SHARED_LIBS:BOOL=OFF \ + -DGENERATE_TYPES=ON \ + -DVARIABLE_TRACKING=OFF \ -DBUILD_TESTING:BOOL=ON \ -DCTEST_PLOT_ERRORS:BOOL=ON \ + -DCMAKE_Fortran_FLAGS="-DUA_OUTS=ON" \ ${GITHUB_WORKSPACE} - - name: Build FAST.Farm - # if: contains(github.event.head_commit.message, 'Action - Test All') || contains(github.event.pull_request.labels.*.name, 'Action - Test All') + - name: Build all working-directory: ${{runner.workspace}}/openfast/build run: | - cmake --build . --target FAST.Farm -- -j ${{env.NUM_PROCS}} - cmake --build . --target regression_tests -- -j ${{env.NUM_PROCS}} + cmake --build . --target unsteadyaero_driver - - name: Run FAST.Farm tests - run: | - ctest -VV -L fastfarm -j ${{env.NUM_PROCS}} + - name: Run UnsteadyAero tests working-directory: ${{runner.workspace}}/openfast/build shell: bash + run: | + ctest -VV -R "^ua_" - name: Failing test artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: failure() with: - name: test-results + name: rtest-uadriver path: | - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/fastfarm + ${{runner.workspace}}/openfast/build/reg_tests/modules/unsteadyaero + - unit-test: - runs-on: ubuntu-20.04 + + ### TEST JOBS + + rtest-module-drivers: + runs-on: ubuntu-22.04 + needs: build-drivers-release steps: - - name: Checkout - uses: actions/checkout@main + - name: Cache the workspace + uses: actions/cache@v3.0.4 with: - submodules: recursive - + path: ${{runner.workspace}} + key: build-drivers-release-${{ github.sha }} - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: - python-version: '3.7' + python-version: '3.9' + cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip - pip install numpy Bokeh==1.4 - + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y gcovr + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Run AeroDyn tests + uses: ./.github/actions/tests-module-aerodyn + with: + test-target: regression + - name: Run BeamDyn tests + uses: ./.github/actions/tests-module-beamdyn + with: + test-target: regression + - name: Run HydroDyn tests + uses: ./.github/actions/tests-module-hydrodyn + - name: Run InflowWind tests + uses: ./.github/actions/tests-module-inflowwind + with: + test-target: regression + - name: Run MoorDyn tests + uses: ./.github/actions/tests-module-moordyn + - name: Run SubDyn tests + uses: ./.github/actions/tests-module-subdyn + - name: Failing test artifacts + uses: actions/upload-artifact@v3 + if: failure() + with: + name: rtest-module-drivers + path: | + ${{runner.workspace}}/openfast/build/reg_tests/modules - - name: Setup Workspace - run: cmake -E make_directory ${{runner.workspace}}/openfast/build - - name: Configure Build + + rtest-modules-debug: + runs-on: ubuntu-22.04 + needs: build-all-debug + steps: + - name: Cache the workspace + uses: actions/cache@v3.0.4 + with: + path: ${{runner.workspace}} + key: build-all-debug-${{ github.sha }} + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: '3.9' + cache: 'pip' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + sudo apt-get update -y + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Configure Tests working-directory: ${{runner.workspace}}/openfast/build run: | cmake \ - -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/openfast/install \ - -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ - -DCMAKE_CXX_COMPILER:STRING=${{env.CXX_COMPILER}} \ - -DCMAKE_C_COMPILER:STRING=${{env.C_COMPILER}} \ - -DCMAKE_BUILD_TYPE:STRING=Debug \ -DBUILD_TESTING:BOOL=ON \ + -DCTEST_PLOT_ERRORS:BOOL=ON \ ${GITHUB_WORKSPACE} - - - name: Build unit tests - working-directory: ${{runner.workspace}}/openfast/build - run: cmake --build . --target unit_tests -- -j ${{env.NUM_PROCS}} - - # NWTC Library has only unit tests - - name: Run NWTC Library tests - uses: ./.github/actions/tests-module-nwtclibrary - # VersionInfo has only unit tests - - name: Run VersionInfo tests - uses: ./.github/actions/tests-module-version + cmake --build . --target regression_test_controllers - name: Run AeroDyn tests uses: ./.github/actions/tests-module-aerodyn with: + # Don't run regression tests here since they currently fail inconsistently test-target: unit - name: Run BeamDyn tests uses: ./.github/actions/tests-module-beamdyn - with: - test-target: unit + - name: Run HydroDyn tests + uses: ./.github/actions/tests-module-hydrodyn - name: Run InflowWind tests uses: ./.github/actions/tests-module-inflowwind + - name: Run MoorDyn tests + uses: ./.github/actions/tests-module-moordyn + - name: Run NWTC Library tests + uses: ./.github/actions/tests-module-nwtclibrary + - name: Run SubDyn tests + uses: ./.github/actions/tests-module-subdyn + - name: Run VersionInfo tests + uses: ./.github/actions/tests-module-version + - name: Failing test artifacts + uses: actions/upload-artifact@v3 + if: failure() with: - test-target: unit + name: rtest-modules-debug + path: | + ${{runner.workspace}}/openfast/build/reg_tests/modules + ${{runner.workspace}}/openfast/build/unit_tests - # Disabled Codecov since the dashboard and GitHub comments were buggy, - # but it may be useful to post the gcov coverage reports to GitHub Actions - # artifacts. - # Note: if reenabling Codecov, the reports must be in xml format not html. - # - name: Generate coverage report - # working-directory: ${{runner.workspace}}/openfast/build - # run: | - # find . -type f -name '*.gcno' -not -path "**tests**" -exec ${{env.GCOV_EXE}} -pb {} + - # cd .. - # gcovr -g -k -r . --html --html-details unitcov.html - # - name: Success artifacts - # uses: actions/upload-artifact@v2 - # if: success() - # with: - # name: unit-tests - # path: | - # ${{runner.workspace}}/openfast/unitcov.html + rtest-interfaces: + runs-on: ubuntu-22.04 + needs: build-interfaces-release + steps: + - name: Cache the workspace + uses: actions/cache@v3.0.4 + with: + path: ${{runner.workspace}} + key: build-interfaces-release-${{ github.sha }} + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: '3.9' + cache: 'pip' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" vtk + sudo apt-get update -y + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Run Interface / API tests + working-directory: ${{runner.workspace}}/openfast/build + run: | + ctest -VV -L "cpp|python|fastlib" - name: Failing test artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: failure() with: - name: unit-tests + name: rtest-interfaces path: | - ${{runner.workspace}}/openfast/build/unit_tests + ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast-cpp + ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/python + ${{runner.workspace}}/openfast/build/reg_tests/modules/aerodyn + ${{runner.workspace}}/openfast/build/reg_tests/modules/moordyn + ${{runner.workspace}}/openfast/build/reg_tests/modules/inflowwind + ${{runner.workspace}}/openfast/build/reg_tests/modules/hydrodyn + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast-cpp/5MW_Baseline - compile-all-single-precision: - # Test if single precision compile completes. - # Compiles all targets excluding tests. - # Run with the OpenFAST registry generating the types files. - # Do not run the test suite. - runs-on: ubuntu-20.04 + rtest-OF: + runs-on: ubuntu-22.04 + needs: build-openfast-release steps: - - name: Checkout - uses: actions/checkout@main + - name: Cache the workspace + uses: actions/cache@v3.0.4 with: - submodules: recursive - - name: Setup - run: cmake -E make_directory ${{runner.workspace}}/openfast/build - - name: Configure - working-directory: ${{runner.workspace}}/openfast/build + path: ${{runner.workspace}} + key: build-openfast-release-${{ github.sha }} + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: '3.9' + cache: 'pip' + - name: Install dependencies run: | - cmake \ - -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/openfast/install \ - -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ - -DCMAKE_BUILD_TYPE:STRING=Debug \ - -DDOUBLE_PRECISION:BOOL=OFF \ - -DGENERATE_TYPES:BOOL=ON \ - ${GITHUB_WORKSPACE} - - name: Build all + python -m pip install --upgrade pip + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + sudo apt-get update -y + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Configure Tests working-directory: ${{runner.workspace}}/openfast/build - run: cmake --build . --target all -- -j ${{env.NUM_PROCS}} - - name: Test + run: | + cmake --build . --target regression_test_controllers + - name: Run 5MW tests working-directory: ${{runner.workspace}}/openfast/build - run: ./glue-codes/openfast/openfast -v + run: | + ctest -VV -j8 \ + -L openfast \ + -LE "cpp|linear|python|fastlib" \ + -E "5MW_OC4Semi_WSt_WavesWN|5MW_OC3Mnpl_DLL_WTurb_WavesIrr|5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth|5MW_OC3Trpd_DLL_WSt_WavesReg|5MW_Land_BD_DLL_WTurb" + - name: Failing test artifacts + uses: actions/upload-artifact@v3 + if: failure() + with: + name: rtest-OF + path: | + ${{runner.workspace}}/openfast/build/reg_tests/modules + ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline + - interface-tests: - runs-on: ubuntu-20.04 + rtest-OF-5MW_OC4Semi_WSt_WavesWN: + runs-on: ubuntu-22.04 + needs: build-openfast-release steps: - - name: Checkout - uses: actions/checkout@main + - name: Cache the workspace + uses: actions/cache@v3.0.4 with: - submodules: recursive - + path: ${{runner.workspace}} + key: build-openfast-release-${{ github.sha }} - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: - python-version: '3.7' + python-version: '3.9' + cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip - pip install numpy Bokeh==1.4 + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + sudo apt-get update -y + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Configure Tests + working-directory: ${{runner.workspace}}/openfast/build + run: | + cmake --build . --target regression_test_controllers + - name: Run 5MW tests + working-directory: ${{runner.workspace}}/openfast/build + run: | + ctest -VV -L openfast -LE "cpp|linear|python" -R 5MW_OC4Semi_WSt_WavesWN + - name: Failing test artifacts + uses: actions/upload-artifact@v3 + if: failure() + with: + name: rtest-OF-5MW_OC4Semi_WSt_WavesWN + path: | + ${{runner.workspace}}/openfast/build/reg_tests/modules + ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline + + rtest-OF-5MW_OC3Mnpl_DLL_WTurb_WavesIrr: + runs-on: ubuntu-22.04 + needs: build-openfast-release + steps: + - name: Cache the workspace + uses: actions/cache@v3.0.4 + with: + path: ${{runner.workspace}} + key: build-openfast-release-${{ github.sha }} + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: '3.9' + cache: 'pip' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" sudo apt-get update -y - sudo apt-get install -y gcovr sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Configure Tests + working-directory: ${{runner.workspace}}/openfast/build + run: | + cmake --build . --target regression_test_controllers + - name: Run 5MW tests + working-directory: ${{runner.workspace}}/openfast/build + run: | + ctest -VV -L openfast -LE "cpp|linear|python" -R 5MW_OC3Mnpl_DLL_WTurb_WavesIrr + - name: Failing test artifacts + uses: actions/upload-artifact@v3 + if: failure() + with: + name: rtest-OF-5MW_OC3Mnpl_DLL_WTurb_WavesIrr + path: | + ${{runner.workspace}}/openfast/build/reg_tests/modules + ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline - - name: Setup Workspace - run: cmake -E make_directory ${{runner.workspace}}/openfast/build - - name: Configure Build + + rtest-OF-5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth: + runs-on: ubuntu-22.04 + needs: build-openfast-release + steps: + - name: Cache the workspace + uses: actions/cache@v3.0.4 + with: + path: ${{runner.workspace}} + key: build-openfast-release-${{ github.sha }} + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: '3.9' + cache: 'pip' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + sudo apt-get update -y + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Configure Tests working-directory: ${{runner.workspace}}/openfast/build run: | - cmake \ - -DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/openfast/install \ - -DCMAKE_Fortran_COMPILER:STRING=${{env.FORTRAN_COMPILER}} \ - -DCMAKE_CXX_COMPILER:STRING=${{env.CXX_COMPILER}} \ - -DCMAKE_C_COMPILER:STRING=${{env.C_COMPILER}} \ - -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo \ - -DBUILD_OPENFAST_CPP_API:BOOL=ON \ - -DBUILD_SHARED_LIBS:BOOL=ON \ - -DBUILD_TESTING:BOOL=ON \ - -DCTEST_PLOT_ERRORS:BOOL=ON \ - ${GITHUB_WORKSPACE} + cmake --build . --target regression_test_controllers + - name: Run 5MW tests + working-directory: ${{runner.workspace}}/openfast/build + run: | + ctest -VV -L openfast -LE "cpp|linear|python" -R 5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth + - name: Failing test artifacts + uses: actions/upload-artifact@v3 + if: failure() + with: + name: rtest-OF-5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth + path: | + ${{runner.workspace}}/openfast/build/reg_tests/modules + ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline - - name: Build OpenFAST C-Interfaces + + rtest-OF-5MW_OC3Trpd_DLL_WSt_WavesReg: + runs-on: ubuntu-22.04 + needs: build-openfast-release + steps: + - name: Cache the workspace + uses: actions/cache@v3.0.4 + with: + path: ${{runner.workspace}} + key: build-openfast-release-${{ github.sha }} + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: '3.9' + cache: 'pip' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + sudo apt-get update -y + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Configure Tests + working-directory: ${{runner.workspace}}/openfast/build + run: | + cmake --build . --target regression_test_controllers + - name: Run 5MW tests working-directory: ${{runner.workspace}}/openfast/build run: | - cmake --build . --target openfastlib -- -j ${{env.NUM_PROCS}} - cmake --build . --target openfast_cpp -- -j ${{env.NUM_PROCS}} - cmake --build . --target openfastcpp -- -j ${{env.NUM_PROCS}} - cmake --build . --target hydrodyn_c_binding -- -j ${{env.NUM_PROCS}} - cmake --build . --target ifw_c_binding -- -j ${{env.NUM_PROCS}} - cmake --build . --target regression_tests -- -j ${{env.NUM_PROCS}} + ctest -VV -L openfast -LE "cpp|linear|python" -R 5MW_OC3Trpd_DLL_WSt_WavesReg + - name: Failing test artifacts + uses: actions/upload-artifact@v3 + if: failure() + with: + name: rtest-OF-5MW_OC3Trpd_DLL_WSt_WavesReg + path: | + ${{runner.workspace}}/openfast/build/reg_tests/modules + ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline + - - name: Run C++ API tests + rtest-OF-5MW_Land_BD_DLL_WTurb: + runs-on: ubuntu-22.04 + needs: build-openfast-release + steps: + - name: Cache the workspace + uses: actions/cache@v3.0.4 + with: + path: ${{runner.workspace}} + key: build-openfast-release-${{ github.sha }} + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: '3.9' + cache: 'pip' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + sudo apt-get update -y + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Configure Tests + working-directory: ${{runner.workspace}}/openfast/build + run: | + cmake --build . --target regression_test_controllers + - name: Run 5MW tests working-directory: ${{runner.workspace}}/openfast/build run: | - ctest -VV -L cpp + ctest -VV -L openfast -LE "cpp|linear|python" -R 5MW_Land_BD_DLL_WTurb + - name: Failing test artifacts + uses: actions/upload-artifact@v3 + if: failure() + with: + name: rtest-OF-5MW_Land_BD_DLL_WTurb + path: | + ${{runner.workspace}}/openfast/build/reg_tests/modules + ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline - - name: Run Python API tests + + rtest-OF-linearization: + runs-on: ubuntu-22.04 + needs: build-openfast-release + steps: + - name: Cache the workspace + uses: actions/cache@v3.0.4 + with: + path: ${{runner.workspace}} + key: build-openfast-release-${{ github.sha }} + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: '3.9' + cache: 'pip' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + sudo apt-get update -y + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Configure Tests + working-directory: ${{runner.workspace}}/openfast/build + run: | + cmake --build . --target regression_test_controllers + - name: Run OpenFAST linearization tests working-directory: ${{runner.workspace}}/openfast/build run: | - ctest -VV -L python + ctest -VV -j8 -L linear + - name: Failing test artifacts + uses: actions/upload-artifact@v3 + if: failure() + with: + name: rtest-OF-linearization + path: | + ${{runner.workspace}}/openfast/build/reg_tests/modules + ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/5MW_Baseline + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AOC + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/AWT27 + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/SWRT + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI + !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline - # Disabled Codecov since the dashboard and GitHub comments were buggy, - # but it may be useful to post the gcov coverage reports to GitHub Actions - # artifacts. - # Note: if reenabling Codecov, the reports must be in xml format not html. - # - name: Generate coverage report - # working-directory: ${{runner.workspace}}/openfast/build - # run: | - # find . -type f -name '*.gcno' -not -path "**tests**" -exec ${{env.GCOV_EXE}} -pb {} + - # cd .. - # gcovr -g -k -r . --html --html-details regressioncov.html - # - name: Success artifacts - # uses: actions/upload-artifact@v2 - # if: success() - # with: - # name: c-interface-reg-tests - # path: | - # ${{runner.workspace}}/openfast/regressioncov.html + rtest-FF: + runs-on: ubuntu-22.04 + needs: build-fastfarm-release + steps: + - name: Cache the workspace + uses: actions/cache@v3.0.4 + with: + path: ${{runner.workspace}} + key: build-fastfarm-release-${{ github.sha }} + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: '3.9' + cache: 'pip' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3" + sudo apt-get update -y + sudo apt-get install -y libhdf5-dev libopenmpi-dev libyaml-cpp-dev + - name: Configure Tests + working-directory: ${{runner.workspace}}/openfast/build + run: | + cmake --build . --target regression_test_controllers + - name: Run FAST.Farm tests + working-directory: ${{runner.workspace}}/openfast/build + shell: bash + run: | + set OMP_NUM_THREADS=2 + ctest -VV -L fastfarm --verbose - name: Failing test artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: failure() with: - name: interface-reg-tests + name: rtest-FF path: | - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast-cpp - ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/python - ${{runner.workspace}}/openfast/build/reg_tests/modules/hydrodyn - ${{runner.workspace}}/openfast/build/reg_tests/modules/inflowwind - !${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast-cpp/5MW_Baseline + ${{runner.workspace}}/openfast/build/reg_tests/glue-codes/fast-farm diff --git a/.gitignore b/.gitignore index 1634702f8..0b6dd4368 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ vs-build/ .vscode .atom .fortls +.devcontainer # backup files *.asv ~$*.xlsx diff --git a/.readthedocs.yml b/.readthedocs.yml index 2a5338b5c..5b54f8b4a 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -7,7 +7,7 @@ version: 2 formats: - htmlzip - - pdf + # - pdf # - epub python: diff --git a/CMakeLists.txt b/CMakeLists.txt index 36f0a0ecc..2a8792b19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,29 +14,39 @@ # limitations under the License. # -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.15) project(OpenFAST CXX C Fortran) include(${CMAKE_SOURCE_DIR}/cmake/OpenfastCmakeUtils.cmake) include(${CMAKE_SOURCE_DIR}/cmake/OpenfastFortranOptions.cmake) +include (FindPackageHandleStandardArgs) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/ftnmods) + # CMake Configuration variables if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the build type: Debug Release" FORCE) endif (NOT CMAKE_BUILD_TYPE) +#------------------------------------------------------------------------------- +# Options +#------------------------------------------------------------------------------- + +option(VARIABLE_TRACKING "Enables variable tracking for better runtime debugging output. May increase compile time. Valid only for GNU." on) option(GENERATE_TYPES "Use the openfast-regsitry to autogenerate types modules" off) option(BUILD_SHARED_LIBS "Enable building shared libraries" off) option(DOUBLE_PRECISION "Treat REAL as double precision" on) option(USE_DLL_INTERFACE "Enable runtime loading of dynamic libraries" on) option(FPE_TRAP_ENABLED "Enable FPE trap in compiler options" off) option(ORCA_DLL_LOAD "Enable OrcaFlex Library Load" on) -option(BUILD_OPENFAST_CPP_API "Enable building OpenFAST - C++ API" off) option(BUILD_FASTFARM "Enable building FAST.Farm" off) +option(BUILD_OPENFAST_CPP_API "Enable building OpenFAST - C++ API" off) +option(BUILD_OPENFAST_SIMULINK_API "Enable building OpenFAST for use with Simulink" off) option(OPENMP "Enable OpenMP support" off) +option(USE_LOCAL_STATIC_LAPACK "Enable downloading and building static LAPACK and BLAS libs" off) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) # Configure the default install path to openfast/install set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install" CACHE PATH "OpenFAST install directory" FORCE) @@ -45,6 +55,12 @@ if(APPLE) option(CMAKE_MACOSX_RPATH "Use RPATH runtime linking" on) endif() +# Warn if atypical configuration for variable tracking and build type +string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type) +if(NOT ${VARIABLE_TRACKING} AND (${_build_type} STREQUAL "DEBUG" OR ${_build_type} STREQUAL "RELWITHDEBINFO") ) + message(WARNING "Variable tracking is disabled and build type includes debug symbols. This may reduce the ability to debug.") +endif() + # Precompiler/preprocessor flag configuration # Do this before configuring modules so that the flags are included option(BUILD_TESTING "Build the testing tree." OFF) @@ -52,10 +68,6 @@ if(BUILD_TESTING) option(CODECOVERAGE "Enable infrastructure for measuring code coverage." OFF) set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -DUNIT_TEST") endif() -option(BUILD_OPENFAST_SIMULINK_API "Enable building OpenFAST for use with Simulink" off) -if(BUILD_OPENFAST_SIMULINK_API) - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -DCOMPILE_SIMULINK") -endif() # Setup Fortran Compiler options based on architecture/compiler set_fast_fortran() @@ -83,43 +95,83 @@ if(CODECOVERAGE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage") endif() -if (USE_DLL_INTERFACE) - add_definitions(-DUSE_DLL_INTERFACE) -endif (USE_DLL_INTERFACE) - if (FPE_TRAP_ENABLED) add_definitions(-DFPE_TRAP_ENABLED) endif (FPE_TRAP_ENABLED) -# Setup dependencies -if (${CMAKE_Fortran_COMPILER_ID} MATCHES "^Intel") - find_package(MKL) +# Set the RPATH after configuring the install prefix +include(${CMAKE_SOURCE_DIR}/cmake/set_rpath.cmake) + +#------------------------------------------------------------------------------- +# OpenMP +#------------------------------------------------------------------------------- + +if (OPENMP OR BUILD_FASTFARM OR BUILD_OPENFAST_CPP_API) + FIND_PACKAGE(OpenMP REQUIRED) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + set(CMAKE_FORTRAN_FLAGS "${CMAKE_FORTRAN_FLAGS} ${OpenMP_FORTRAN_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") endif() -if (MKL_FOUND) - include_directories(${MKL_INCLUDE_DIRS}) - set(BLAS_LIBRARIES ${MKL_LIBRARIES}) - set(LAPACK_LIBRARIES ${MKL_LIBRARIES}) - set(CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES "ifport;ifcore;imf;svml;m;ipgo;intlc;c;irc_s;dl;c") + +#------------------------------------------------------------------------------- +# BLAS and LAPACK +#------------------------------------------------------------------------------- + +# Find BLAS and LAPACK - set BLA_VENDOR to use a specific version of BLAS and LAPACK +# For example -DBLA_VENDOR=Intel10_64lp for Intel MKL v10+ 64 bit, threaded code, lp64 model +# (see https://cmake.org/cmake/help/latest/module/FindBLAS.html#blas-lapack-vendors) +# If USE_LOCAL_STATIC_LAPACK then LAPACK will be downloaded, built, and statically linked. + +if (USE_LOCAL_STATIC_LAPACK) + message(STATUS "Downloading and building LAPACK as static libraries for linking with OpenFAST") + set(BLAS_LIB_PATH ${CMAKE_BINARY_DIR}/dependencies/src/lapack-build/lib/${CMAKE_STATIC_LIBRARY_PREFIX}blas${CMAKE_STATIC_LIBRARY_SUFFIX} ) + set(LAPACK_LIB_PATH ${CMAKE_BINARY_DIR}/dependencies/src/lapack-build/lib/${CMAKE_STATIC_LIBRARY_PREFIX}lapack${CMAKE_STATIC_LIBRARY_SUFFIX}) + include(ExternalProject) + ExternalProject_Add(lapack + URL http://www.netlib.org/lapack/lapack.tgz + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_SOURCE_DIR}/install + PREFIX ${CMAKE_BINARY_DIR}/dependencies + BUILD_BYPRODUCTS ${BLAS_LIB_PATH} ${LAPACK_LIB_PATH} + ) + set(LAPACK_LIBRARIES ${BLAS_LIB_PATH} ${LAPACK_LIB_PATH} CACHE STRING "LAPACK library" FORCE) + install(FILES ${LAPACK_LIBRARIES} DESTINATION ${CMAKE_SOURCE_DIR}/install/lib) + message(STATUS "Using LAPACK libraries: ${LAPACK_LIBRARIES}") else() - find_package(BLAS REQUIRED) - find_package(LAPACK REQUIRED) + find_package(LAPACK) + if (LAPACK_FOUND) + add_link_options(${LAPACK_LINKER_FLAGS}) + else() + message(FATAL_ERROR "Unable to find BLAS and LAPACK") + endif() endif() -# Set the RPATH after configuring the install prefix -include(${CMAKE_SOURCE_DIR}/cmake/set_rpath.cmake) +#------------------------------------------------------------------------------- +# Simulink +#------------------------------------------------------------------------------- + +if (BUILD_OPENFAST_SIMULINK_API) + if (BUILD_SHARED_LIBS) + message(FATAL_ERROR "OpenFAST's Simulink API is not compatible with BUILD_SHARED_LIBS=ON") + endif () + find_package(Matlab REQUIRED SIMULINK) +endif () + +#------------------------------------------------------------------------------- +# OpenFAST Registry +#------------------------------------------------------------------------------- -######################################################################## -# Build rules for OpenFAST Registry -# if(GENERATE_TYPES) add_subdirectory(modules/openfast-registry) endif() -######################################################################## -# OpenFAST modules -# +#------------------------------------------------------------------------------- +# Modules +#------------------------------------------------------------------------------- + set(OPENFAST_MODULES nwtc-library + version inflowwind aerodyn aerodyn14 @@ -130,18 +182,17 @@ set(OPENFAST_MODULES hydrodyn orcaflex-interface extptfm - openfoam - supercontroller - turbsim - openfast-library - version feamooring moordyn icedyn icefloe - map wakedynamics awae + map + turbsim + supercontroller + openfoam + openfast-library ) set(OPENFAST_REGISTRY_INCLUDES "" CACHE INTERNAL "Registry includes paths") @@ -155,11 +206,17 @@ foreach(IDIR IN ITEMS ${OPENFAST_MODULES}) add_subdirectory("${CMAKE_SOURCE_DIR}/modules/${IDIR}") endforeach(IDIR IN ITEMS ${OPENFAST_MODULES}) +#------------------------------------------------------------------------------- +# Glue Code +#------------------------------------------------------------------------------- + add_subdirectory(glue-codes) # Install fortran .mod files also to installation directory -install(CODE - "EXECUTE_PROCESS (COMMAND \"${CMAKE_COMMAND}\" -E copy_directory \"${CMAKE_Fortran_MODULE_DIRECTORY}\" \"${CMAKE_INSTALL_PREFIX}/include/openfast/\")") +install(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/include/openfast/ + FILES_MATCHING PATTERN "*.mod" +) # Install the library dependency information install(EXPORT OpenFASTLibraries @@ -186,20 +243,39 @@ configure_package_config_file( install(FILES ${CMAKE_CURRENT_BINARY_DIR}/OpenFASTConfig.cmake DESTINATION lib/cmake/OpenFAST) -######################################################################## +#------------------------------------------------------------------------------- +# Testing +#------------------------------------------------------------------------------- # Option configuration if(BUILD_TESTING) include(CTest) + # Find Python interpreter - used for running tests. + # If the wrong version is found, set Python_ROOT_DIR when running CMake. + if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.15.0") + cmake_policy(SET CMP0094 NEW) # Search for Python by LOCATION + endif() + find_package (Python COMPONENTS Interpreter) + if(NOT ${Python_Interpreter_FOUND}) + message(FATAL_ERROR "CMake cannot find a Python interpreter. Python is required for regression and unit tests." ) + endif() + # regression tests add_subdirectory(reg_tests) # unit tests - add_subdirectory(unit_tests) + if(NOT (${CMAKE_Fortran_COMPILER_ID} STREQUAL "Flang")) + add_subdirectory(unit_tests) + endif() endif() +#------------------------------------------------------------------------------- +# Documentation +#------------------------------------------------------------------------------- + option(BUILD_DOCUMENTATION "Build documentation." OFF) if(BUILD_DOCUMENTATION) add_subdirectory(docs) endif() + diff --git a/cmake/FindMKL.cmake b/cmake/FindMKL.cmake deleted file mode 100644 index d2dfb9ebb..000000000 --- a/cmake/FindMKL.cmake +++ /dev/null @@ -1,68 +0,0 @@ -# -# Copyright 2016 National Renewable Energy Laboratory -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# find_path(MKL_INCLUDE_DIRS -# mkl.h -# HINTS $ENV{MKLROOT} -# PATH_SUFFIXES include) - -# infer the architecture build type -# https://cmake.org/cmake/help/v3.0/variable/CMAKE_SIZEOF_VOID_P.html -if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") - set(ARCHDIR "ia32") - set(WINDOWS_INTERFACE "_c_") - set(UNIX_INTERFACE "") -elseif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8") - set(ARCHDIR "intel64") - set(WINDOWS_INTERFACE "_lp64_") - set(UNIX_INTERFACE "_lp64") -endif() - -set(MKLSEARCHPATHS - $ENV{MKLROOT}/lib/${ARCHDIR}_win - $ENV{MKLROOT}/lib/${ARCHDIR} - $ENV{MKLROOT}/lib -) - -# using mkl_intel_c on windows since that is the default for intel compilers -# https://software.intel.com/en-us/mkl-windows-developer-guide-using-the-cdecl-and-stdcall-interfaces -find_library(MKL_IFACE_LIB - NAMES mkl_intel${UNIX_INTERFACE} libmkl_intel${UNIX_INTERFACE} mkl_intel${WINDOWS_INTERFACE}dll - PATHS ${MKLSEARCHPATHS} - NO_DEFAULT_PATH) - -find_library(MKL_SEQ_LIB - NAMES mkl_sequential libmkl_sequential mkl_sequential_dll - PATHS ${MKLSEARCHPATHS} - NO_DEFAULT_PATH) - -find_library(MKL_CORE_LIB - NAMES mkl_core libmkl_core mkl_core_dll - PATHS ${MKLSEARCHPATHS} - NO_DEFAULT_PATH) - -if (MKL_IFACE_LIB AND MKL_SEQ_LIB AND MKL_CORE_LIB) - set(MKL_LIBRARIES ${MKL_IFACE_LIB} ${MKL_SEQ_LIB} ${MKL_CORE_LIB}) -else() - set(MKL_LIBRARIES "") - set(MKL_INCLUDE_DIRS "") -endif() - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(MKL DEFAULT_MSG - MKL_LIBRARIES MKL_IFACE_LIB MKL_SEQ_LIB MKL_CORE_LIB) # MKL_INCLUDE_DIRS) -mark_as_advanced( - MKL_INCLUDE_DIRS MKL_LIBRARIES MKL_IFACE_LIB MKL_SEQ_LIB MKL_CORE_LIB) diff --git a/cmake/FindMatlab.cmake b/cmake/FindMatlab.cmake deleted file mode 100644 index c50878ef5..000000000 --- a/cmake/FindMatlab.cmake +++ /dev/null @@ -1,1720 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# FindMatlab -# ---------- -# -# Finds Matlab or Matlab Compiler Runtime (MCR) and provides Matlab tools, -# libraries and compilers to CMake. -# -# This package primary purpose is to find the libraries associated with Matlab -# or the MCR in order to be able to build Matlab extensions (mex files). It -# can also be used: -# -# * to run specific commands in Matlab in case Matlab is available -# * for declaring Matlab unit test -# * to retrieve various information from Matlab (mex extensions, versions and -# release queries, ...) -# -# The module supports the following components: -# -# * ``MX_LIBRARY``, ``ENG_LIBRARY`` and ``MAT_LIBRARY``: respectively the ``MX``, -# ``ENG`` and ``MAT`` libraries of Matlab -# * ``MAIN_PROGRAM`` the Matlab binary program. Note that this component is not -# available on the MCR version, and will yield an error if the MCR is found -# instead of the regular Matlab installation. -# * ``MEX_COMPILER`` the MEX compiler. -# * ``MCC_COMPILER`` the MCC compiler, included with the Matlab Compiler add-on. -# * ``SIMULINK`` the Simulink environment. -# -# .. note:: -# -# The version given to the :command:`find_package` directive is the Matlab -# **version**, which should not be confused with the Matlab *release* name -# (eg. `R2014`). -# The :command:`matlab_get_version_from_release_name` and -# :command:`matlab_get_release_name_from_version` provide a mapping -# between the release name and the version. -# -# The variable :variable:`Matlab_ROOT_DIR` may be specified in order to give -# the path of the desired Matlab version. Otherwise, the behaviour is platform -# specific: -# -# * Windows: The installed versions of Matlab/MCR are retrieved from the -# Windows registry -# * OS X: The installed versions of Matlab/MCR are given by the MATLAB -# default installation paths in ``/Application``. If no such application is -# found, it falls back to the one that might be accessible from the ``PATH``. -# * Unix: The desired Matlab should be accessible from the ``PATH``. This does -# not work for MCR installation and :variable:`Matlab_ROOT_DIR` should be -# specified on this platform. -# -# Additional information is provided when :variable:`MATLAB_FIND_DEBUG` is set. -# When a Matlab/MCR installation is found automatically and the ``MATLAB_VERSION`` -# is not given, the version is queried from Matlab directly (on Windows this -# may pop up a Matlab window) or from the MCR installation. -# -# The mapping of the release names and the version of Matlab is performed by -# defining pairs (name, version). The variable -# :variable:`MATLAB_ADDITIONAL_VERSIONS` may be provided before the call to -# the :command:`find_package` in order to handle additional versions. -# -# A Matlab scripts can be added to the set of tests using the -# :command:`matlab_add_unit_test`. By default, the Matlab unit test framework -# will be used (>= 2013a) to run this script, but regular ``.m`` files -# returning an exit code can be used as well (0 indicating a success). -# -# Module Input Variables -# ^^^^^^^^^^^^^^^^^^^^^^ -# -# Users or projects may set the following variables to configure the module -# behaviour: -# -# :variable:`Matlab_ROOT_DIR` -# the root of the Matlab installation. -# :variable:`MATLAB_FIND_DEBUG` -# outputs debug information -# :variable:`MATLAB_ADDITIONAL_VERSIONS` -# additional versions of Matlab for the automatic retrieval of the installed -# versions. -# -# Variables defined by the module -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -# -# Result variables -# """""""""""""""" -# -# ``Matlab_FOUND`` -# ``TRUE`` if the Matlab installation is found, ``FALSE`` -# otherwise. All variable below are defined if Matlab is found. -# ``Matlab_ROOT_DIR`` -# the final root of the Matlab installation determined by the FindMatlab -# module. -# ``Matlab_MAIN_PROGRAM`` -# the Matlab binary program. Available only if the component ``MAIN_PROGRAM`` -# is given in the :command:`find_package` directive. -# ``Matlab_INCLUDE_DIRS`` -# the path of the Matlab libraries headers -# ``Matlab_MEX_LIBRARY`` -# library for mex, always available. -# ``Matlab_MX_LIBRARY`` -# mx library of Matlab (arrays). Available only if the component -# ``MX_LIBRARY`` has been requested. -# ``Matlab_ENG_LIBRARY`` -# Matlab engine library. Available only if the component ``ENG_LIBRARY`` -# is requested. -# ``Matlab_MAT_LIBRARY`` -# Matlab matrix library. Available only if the component ``MAT_LIBRARY`` -# is requested. -# ``Matlab_LIBRARIES`` -# the whole set of libraries of Matlab -# ``Matlab_MEX_COMPILER`` -# the mex compiler of Matlab. Currently not used. -# Available only if the component ``MEX_COMPILER`` is requested. -# ``Matlab_MCC_COMPILER`` -# the mcc compiler of Matlab. Included with the Matlab Compiler add-on. -# Available only if the component ``MCC_COMPILER`` is requested. -# -# Cached variables -# """""""""""""""" -# -# ``Matlab_MEX_EXTENSION`` -# the extension of the mex files for the current platform (given by Matlab). -# ``Matlab_ROOT_DIR`` -# the location of the root of the Matlab installation found. If this value -# is changed by the user, the result variables are recomputed. -# -# Provided macros -# ^^^^^^^^^^^^^^^ -# -# :command:`matlab_get_version_from_release_name` -# returns the version from the release name -# :command:`matlab_get_release_name_from_version` -# returns the release name from the Matlab version -# -# Provided functions -# ^^^^^^^^^^^^^^^^^^ -# -# :command:`matlab_add_mex` -# adds a target compiling a MEX file. -# :command:`matlab_add_unit_test` -# adds a Matlab unit test file as a test to the project. -# :command:`matlab_extract_all_installed_versions_from_registry` -# parses the registry for all Matlab versions. Available on Windows only. -# The part of the registry parsed is dependent on the host processor -# :command:`matlab_get_all_valid_matlab_roots_from_registry` -# returns all the possible Matlab or MCR paths, according to a previously -# given list. Only the existing/accessible paths are kept. This is mainly -# useful for the searching all possible Matlab installation. -# :command:`matlab_get_mex_suffix` -# returns the suffix to be used for the mex files -# (platform/architecture dependent) -# :command:`matlab_get_version_from_matlab_run` -# returns the version of Matlab/MCR, given the full directory of the Matlab/MCR -# installation path. -# -# -# Known issues -# ^^^^^^^^^^^^ -# -# **Symbol clash in a MEX target** -# By default, every symbols inside a MEX -# file defined with the command :command:`matlab_add_mex` have hidden -# visibility, except for the entry point. This is the default behaviour of -# the MEX compiler, which lowers the risk of symbol collision between the -# libraries shipped with Matlab, and the libraries to which the MEX file is -# linking to. This is also the default on Windows platforms. -# -# However, this is not sufficient in certain case, where for instance your -# MEX file is linking against libraries that are already loaded by Matlab, -# even if those libraries have different SONAMES. -# A possible solution is to hide the symbols of the libraries to which the -# MEX target is linking to. This can be achieved in GNU GCC compilers with -# the linker option ``-Wl,--exclude-libs,ALL``. -# -# **Tests using GPU resources** -# in case your MEX file is using the GPU and -# in order to be able to run unit tests on this MEX file, the GPU resources -# should be properly released by Matlab. A possible solution is to make -# Matlab aware of the use of the GPU resources in the session, which can be -# performed by a command such as ``D = gpuDevice()`` at the beginning of -# the test script (or via a fixture). -# -# -# Reference -# ^^^^^^^^^ -# -# .. variable:: Matlab_ROOT_DIR -# -# The root folder of the Matlab installation. If set before the call to -# :command:`find_package`, the module will look for the components in that -# path. If not set, then an automatic search of Matlab -# will be performed. If set, it should point to a valid version of Matlab. -# -# .. variable:: MATLAB_FIND_DEBUG -# -# If set, the lookup of Matlab and the intermediate configuration steps are -# outputted to the console. -# -# .. variable:: MATLAB_ADDITIONAL_VERSIONS -# -# If set, specifies additional versions of Matlab that may be looked for. -# The variable should be a list of strings, organised by pairs of release -# name and versions, such as follows:: -# -# set(MATLAB_ADDITIONAL_VERSIONS -# "release_name1=corresponding_version1" -# "release_name2=corresponding_version2" -# ... -# ) -# -# Example:: -# -# set(MATLAB_ADDITIONAL_VERSIONS -# "R2013b=8.2" -# "R2013a=8.1" -# "R2012b=8.0") -# -# The order of entries in this list matters when several versions of -# Matlab are installed. The priority is set according to the ordering in -# this list. - -set(_FindMatlab_SELF_DIR "${CMAKE_CURRENT_LIST_DIR}") - -include(CheckCXXCompilerFlag) -include(CheckCCompilerFlag) - - -# The currently supported versions. Other version can be added by the user by -# providing MATLAB_ADDITIONAL_VERSIONS -if(NOT MATLAB_ADDITIONAL_VERSIONS) - set(MATLAB_ADDITIONAL_VERSIONS) -endif() - -set(MATLAB_VERSIONS_MAPPING - "R2020b=9.9" - "R2020a=9.8" - "R2019b=9.7" - "R2019a=9.6" - "R2018b=9.5" - "R2018a=9.4" - "R2017b=9.3" - "R2017a=9.2" - "R2016b=9.1" - "R2016a=9.0" - "R2015b=8.6" - "R2015a=8.5" - "R2014b=8.4" - "R2014a=8.3" - "R2013b=8.2" - "R2013a=8.1" - "R2012b=8.0" - "R2012a=7.14" - "R2011b=7.13" - "R2011a=7.12" - "R2010b=7.11" - - ${MATLAB_ADDITIONAL_VERSIONS} - ) - - -# temporary folder for all Matlab runs -set(_matlab_temporary_folder ${CMAKE_BINARY_DIR}/Matlab) - -if(NOT EXISTS "${_matlab_temporary_folder}") - file(MAKE_DIRECTORY "${_matlab_temporary_folder}") -endif() - -#.rst: -# .. command:: matlab_get_version_from_release_name -# -# Returns the version of Matlab (17.58) from a release name (R2017k) -macro(matlab_get_version_from_release_name release_name version_name) - - string(REGEX MATCHALL "${release_name}=([0-9]+\\.?[0-9]*)" _matched ${MATLAB_VERSIONS_MAPPING}) - - set(${version_name} "") - if(NOT _matched STREQUAL "") - set(${version_name} ${CMAKE_MATCH_1}) - else() - message(WARNING "[MATLAB] The release name ${release_name} is not registered") - endif() - unset(_matched) - -endmacro() - - - - - -#.rst: -# .. command:: matlab_get_release_name_from_version -# -# Returns the release name (R2017k) from the version of Matlab (17.58) -macro(matlab_get_release_name_from_version version release_name) - - set(${release_name} "") - foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING) - string(REGEX MATCHALL "(.+)=${version}" _matched ${_var}) - if(NOT _matched STREQUAL "") - set(${release_name} ${CMAKE_MATCH_1}) - break() - endif() - endforeach(_var) - - unset(_var) - unset(_matched) - if(${release_name} STREQUAL "") - message(WARNING "[MATLAB] The version ${version} is not registered") - endif() - -endmacro() - - - - - -# extracts all the supported release names (R2017k...) of Matlab -# internal use -macro(matlab_get_supported_releases list_releases) - set(${list_releases}) - foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING) - string(REGEX MATCHALL "(.+)=([0-9]+\\.?[0-9]*)" _matched ${_var}) - if(NOT _matched STREQUAL "") - list(APPEND ${list_releases} ${CMAKE_MATCH_1}) - endif() - unset(_matched) - unset(CMAKE_MATCH_1) - endforeach(_var) - unset(_var) -endmacro() - - - -# extracts all the supported versions of Matlab -# internal use -macro(matlab_get_supported_versions list_versions) - set(${list_versions}) - foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING) - string(REGEX MATCHALL "(.+)=([0-9]+\\.?[0-9]*)" _matched ${_var}) - if(NOT _matched STREQUAL "") - list(APPEND ${list_versions} ${CMAKE_MATCH_2}) - endif() - unset(_matched) - unset(CMAKE_MATCH_1) - endforeach(_var) - unset(_var) -endmacro() - - -#.rst: -# .. command:: matlab_extract_all_installed_versions_from_registry -# -# This function parses the registry and founds the Matlab versions that are -# installed. The found versions are returned in `matlab_versions`. -# Set `win64` to `TRUE` if the 64 bit version of Matlab should be looked for -# The returned list contains all versions under -# ``HKLM\\SOFTWARE\\Mathworks\\MATLAB`` and -# ``HKLM\\SOFTWARE\\Mathworks\\MATLAB Runtime`` or an empty list in case an -# error occurred (or nothing found). -# -# .. note:: -# -# Only the versions are provided. No check is made over the existence of the -# installation referenced in the registry, -# -function(matlab_extract_all_installed_versions_from_registry win64 matlab_versions) - - if(NOT CMAKE_HOST_WIN32) - message(FATAL_ERROR "[MATLAB] This macro can only be called by a windows host (call to reg.exe)") - endif() - - if(${win64} AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "64") - set(APPEND_REG "/reg:64") - else() - set(APPEND_REG "/reg:32") - endif() - - set(matlabs_from_registry) - - foreach(_installation_type IN ITEMS "MATLAB" "MATLAB Runtime") - - # /reg:64 should be added on 64 bits capable OSs in order to enable the - # redirection of 64 bits applications - execute_process( - COMMAND reg query HKEY_LOCAL_MACHINE\\SOFTWARE\\Mathworks\\${_installation_type} /f * /k ${APPEND_REG} - RESULT_VARIABLE resultMatlab - OUTPUT_VARIABLE varMatlab - ERROR_VARIABLE errMatlab - INPUT_FILE NUL - ) - - - if(${resultMatlab} EQUAL 0) - - string( - REGEX MATCHALL "MATLAB\\\\([0-9]+(\\.[0-9]+)?)" - matlab_versions_regex ${varMatlab}) - - foreach(match IN LISTS matlab_versions_regex) - string( - REGEX MATCH "MATLAB\\\\(([0-9]+)(\\.([0-9]+))?)" - current_match ${match}) - - set(_matlab_current_version ${CMAKE_MATCH_1}) - set(current_matlab_version_major ${CMAKE_MATCH_2}) - set(current_matlab_version_minor ${CMAKE_MATCH_4}) - if(NOT current_matlab_version_minor) - set(current_matlab_version_minor "0") - endif() - - list(APPEND matlabs_from_registry ${_matlab_current_version}) - unset(_matlab_current_version) - endforeach() - - endif() - endforeach() - - if(matlabs_from_registry) - list(REMOVE_DUPLICATES matlabs_from_registry) - list(SORT matlabs_from_registry) - list(REVERSE matlabs_from_registry) - endif() - - set(${matlab_versions} ${matlabs_from_registry} PARENT_SCOPE) - -endfunction() - - - -# (internal) -macro(extract_matlab_versions_from_registry_brute_force matlab_versions) - # get the supported versions - set(matlab_supported_versions) - matlab_get_supported_versions(matlab_supported_versions) - - - # this is a manual population of the versions we want to look for - # this can be done as is, but preferably with the call to - # matlab_get_supported_versions and variable - - # populating the versions we want to look for - # set(matlab_supported_versions) - - # # Matlab 7 - # set(matlab_major 7) - # foreach(current_matlab_minor RANGE 4 20) - # list(APPEND matlab_supported_versions "${matlab_major}.${current_matlab_minor}") - # endforeach(current_matlab_minor) - - # # Matlab 8 - # set(matlab_major 8) - # foreach(current_matlab_minor RANGE 0 5) - # list(APPEND matlab_supported_versions "${matlab_major}.${current_matlab_minor}") - # endforeach(current_matlab_minor) - - # # taking into account the possible additional versions provided by the user - # if(DEFINED MATLAB_ADDITIONAL_VERSIONS) - # list(APPEND matlab_supported_versions MATLAB_ADDITIONAL_VERSIONS) - # endif() - - # we order from more recent to older - if(matlab_supported_versions) - list(REMOVE_DUPLICATES matlab_supported_versions) - list(SORT matlab_supported_versions) - list(REVERSE matlab_supported_versions) - endif() - - set(${matlab_versions} ${matlab_supported_versions}) -endmacro() - - - - -#.rst: -# .. command:: matlab_get_all_valid_matlab_roots_from_registry -# -# Populates the Matlab root with valid versions of Matlab or -# Matlab Runtime (MCR). -# The returned matlab_roots is organized in triplets -# ``(type,version_number,matlab_root_path)``, where ``type`` -# indicates either ``MATLAB`` or ``MCR``. -# -# :: -# -# matlab_get_all_valid_matlab_roots_from_registry( -# matlab_versions -# matlab_roots) -# -# ``matlab_versions`` -# the versions of each of the Matlab or MCR installations -# ``matlab_roots`` -# the location of each of the Matlab or MCR installations -function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_roots) - - # The matlab_versions comes either from - # extract_matlab_versions_from_registry_brute_force or - # matlab_extract_all_installed_versions_from_registry. - - set(_matlab_roots_list ) - # check for Matlab installations - foreach(_matlab_current_version ${matlab_versions}) - get_filename_component( - current_MATLAB_ROOT - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\${_matlab_current_version};MATLABROOT]" - ABSOLUTE) - - if(EXISTS ${current_MATLAB_ROOT}) - list(APPEND _matlab_roots_list "MATLAB" ${_matlab_current_version} ${current_MATLAB_ROOT}) - endif() - - endforeach() - - # Check for MCR installations - foreach(_matlab_current_version ${matlab_versions}) - get_filename_component( - current_MATLAB_ROOT - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB Runtime\\${_matlab_current_version};MATLABROOT]" - ABSOLUTE) - - # remove the dot - string(REPLACE "." "" _matlab_current_version_without_dot "${_matlab_current_version}") - - if(EXISTS ${current_MATLAB_ROOT}) - list(APPEND _matlab_roots_list "MCR" ${_matlab_current_version} "${current_MATLAB_ROOT}/v${_matlab_current_version_without_dot}") - endif() - - endforeach() - set(${matlab_roots} ${_matlab_roots_list} PARENT_SCOPE) -endfunction() - -#.rst: -# .. command:: matlab_get_mex_suffix -# -# Returns the extension of the mex files (the suffixes). -# This function should not be called before the appropriate Matlab root has -# been found. -# -# :: -# -# matlab_get_mex_suffix( -# matlab_root -# mex_suffix) -# -# ``matlab_root`` -# the root of the Matlab/MCR installation -# ``mex_suffix`` -# the variable name in which the suffix will be returned. -function(matlab_get_mex_suffix matlab_root mex_suffix) - - # todo setup the extension properly. Currently I do not know if this is - # sufficient for all win32 distributions. - # there is also CMAKE_EXECUTABLE_SUFFIX that could be tweaked - set(mexext_suffix "") - if(WIN32) - list(APPEND mexext_suffix ".bat") - endif() - - # we first try without suffix, since cmake does not understand a list with - # one empty string element - find_program( - Matlab_MEXEXTENSIONS_PROG - NAMES mexext - PATHS ${matlab_root}/bin - DOC "Matlab MEX extension provider" - NO_DEFAULT_PATH - ) - - foreach(current_mexext_suffix IN LISTS mexext_suffix) - if(NOT DEFINED Matlab_MEXEXTENSIONS_PROG OR NOT Matlab_MEXEXTENSIONS_PROG) - # this call should populate the cache automatically - find_program( - Matlab_MEXEXTENSIONS_PROG - "mexext${current_mexext_suffix}" - PATHS ${matlab_root}/bin - DOC "Matlab MEX extension provider" - NO_DEFAULT_PATH - ) - endif() - endforeach(current_mexext_suffix) - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Determining mex files extensions from '${matlab_root}/bin' with program '${Matlab_MEXEXTENSIONS_PROG}'") - endif() - - # the program has been found? - if((NOT Matlab_MEXEXTENSIONS_PROG) OR (NOT EXISTS ${Matlab_MEXEXTENSIONS_PROG})) - if(MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] Cannot found mexext program. Matlab root is ${matlab_root}") - endif() - unset(Matlab_MEXEXTENSIONS_PROG CACHE) - return() - endif() - - set(_matlab_mex_extension) - - set(devnull) - if(UNIX) - set(devnull INPUT_FILE /dev/null) - elseif(WIN32) - set(devnull INPUT_FILE NUL) - endif() - - # this is the preferred way. If this does not work properly (eg. MCR on Windows), then we use our own knowledge - execute_process( - COMMAND ${Matlab_MEXEXTENSIONS_PROG} - OUTPUT_VARIABLE _matlab_mex_extension - #RESULT_VARIABLE _matlab_mex_extension_call - ERROR_VARIABLE _matlab_mex_extension_error - ${devnull}) - - if(NOT "${_matlab_mex_extension_error}" STREQUAL "") - if(WIN32) - # this is only for intel architecture - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_matlab_mex_extension "mexw64") - else() - set(_matlab_mex_extension "mexw32") - endif() - endif() - endif() - - string(STRIP "${_matlab_mex_extension}" _matlab_mex_extension) - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] '${Matlab_MEXEXTENSIONS_PROG}' : returned '${_matlab_mex_extension_call}', determined extension '${_matlab_mex_extension}' and error string is '${_matlab_mex_extension_error}'") - endif() - - unset(Matlab_MEXEXTENSIONS_PROG CACHE) - set(${mex_suffix} ${_matlab_mex_extension} PARENT_SCOPE) -endfunction() - - - - -#.rst: -# .. command:: matlab_get_version_from_matlab_run -# -# This function runs Matlab program specified on arguments and extracts its -# version. If the path provided for the Matlab installation points to an MCR -# installation, the version is extracted from the installed files. -# -# :: -# -# matlab_get_version_from_matlab_run( -# matlab_binary_path -# matlab_list_versions) -# -# ``matlab_binary_path`` -# the location of the `matlab` binary executable -# ``matlab_list_versions`` -# the version extracted from Matlab -function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_versions) - - set(${matlab_list_versions} "" PARENT_SCOPE) - - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Determining the version of Matlab from ${matlab_binary_program}") - endif() - - if(EXISTS "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Removing previous ${_matlab_temporary_folder}/matlabVersionLog.cmaketmp file") - endif() - file(REMOVE "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") - endif() - - - # the log file is needed since on windows the command executes in a new - # window and it is not possible to get back the answer of Matlab - # the -wait command is needed on windows, otherwise the call returns - # immediately after the program launches itself. - if(WIN32) - set(_matlab_additional_commands "-wait") - endif() - - set(devnull) - if(UNIX) - set(devnull INPUT_FILE /dev/null) - elseif(WIN32) - set(devnull INPUT_FILE NUL) - endif() - - # timeout set to 120 seconds, in case it does not start - # note as said before OUTPUT_VARIABLE cannot be used in a platform - # independent manner however, not setting it would flush the output of Matlab - # in the current console (unix variant) - execute_process( - COMMAND "${matlab_binary_program}" -nosplash -nojvm ${_matlab_additional_commands} -logfile "matlabVersionLog.cmaketmp" -nodesktop -nodisplay -r "version, exit" - OUTPUT_VARIABLE _matlab_version_from_cmd_dummy - RESULT_VARIABLE _matlab_result_version_call - ERROR_VARIABLE _matlab_result_version_call_error - TIMEOUT 120 - WORKING_DIRECTORY "${_matlab_temporary_folder}" - ${devnull} - ) - - if("${_matlab_result_version_call}" MATCHES "timeout") - if(MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] Unable to determine the version of Matlab." - " Matlab call timed out after 120 seconds.") - endif() - return() - endif() - - if(${_matlab_result_version_call}) - if(MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] Unable to determine the version of Matlab. Matlab call returned with error ${_matlab_result_version_call}.") - endif() - return() - elseif(NOT EXISTS "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") - if(MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] Unable to determine the version of Matlab. The log file does not exist.") - endif() - return() - endif() - - # if successful, read back the log - file(READ "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp" _matlab_version_from_cmd) - file(REMOVE "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") - - set(index -1) - string(FIND ${_matlab_version_from_cmd} "ans" index) - if(index EQUAL -1) - - if(MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] Cannot find the version of Matlab returned by the run.") - endif() - - else() - set(matlab_list_of_all_versions_tmp) - - string(SUBSTRING ${_matlab_version_from_cmd} ${index} -1 substring_ans) - string( - REGEX MATCHALL "ans[\r\n\t ]*=[\r\n\t ]*'?([0-9]+(\\.[0-9]+)?)" - matlab_versions_regex - ${substring_ans}) - foreach(match IN LISTS matlab_versions_regex) - string( - REGEX MATCH "ans[\r\n\t ]*=[\r\n\t ]*'?(([0-9]+)(\\.([0-9]+))?)" - current_match ${match}) - - list(APPEND matlab_list_of_all_versions_tmp ${CMAKE_MATCH_1}) - endforeach() - if(matlab_list_of_all_versions_tmp) - list(REMOVE_DUPLICATES matlab_list_of_all_versions_tmp) - endif() - set(${matlab_list_versions} ${matlab_list_of_all_versions_tmp} PARENT_SCOPE) - - endif() - -endfunction() - -#.rst: -# .. command:: matlab_add_unit_test -# -# Adds a Matlab unit test to the test set of cmake/ctest. -# This command requires the component ``MAIN_PROGRAM`` and hence is not -# available for an MCR installation. -# -# The unit test uses the Matlab unittest framework (default, available -# starting Matlab 2013b+) except if the option ``NO_UNITTEST_FRAMEWORK`` -# is given. -# -# The function expects one Matlab test script file to be given. -# In the case ``NO_UNITTEST_FRAMEWORK`` is given, the unittest script file -# should contain the script to be run, plus an exit command with the exit -# value. This exit value will be passed to the ctest framework (0 success, -# non 0 failure). Additional arguments accepted by :command:`add_test` can be -# passed through ``TEST_ARGS`` (eg. ``CONFIGURATION ...``). -# -# :: -# -# matlab_add_unit_test( -# NAME -# UNITTEST_FILE matlab_file_containing_unittest.m -# [CUSTOM_TEST_COMMAND matlab_command_to_run_as_test] -# [UNITTEST_PRECOMMAND matlab_command_to_run] -# [TIMEOUT timeout] -# [ADDITIONAL_PATH path1 [path2 ...]] -# [MATLAB_ADDITIONAL_STARTUP_OPTIONS option1 [option2 ...]] -# [TEST_ARGS arg1 [arg2 ...]] -# [NO_UNITTEST_FRAMEWORK] -# ) -# -# The function arguments are: -# -# ``NAME`` -# name of the unittest in ctest. -# ``UNITTEST_FILE`` -# the matlab unittest file. Its path will be automatically -# added to the Matlab path. -# ``CUSTOM_TEST_COMMAND`` -# Matlab script command to run as the test. -# If this is not set, then the following is run: -# ``runtests('matlab_file_name'), exit(max([ans(1,:).Failed]))`` -# where ``matlab_file_name`` is the ``UNITTEST_FILE`` without the extension. -# ``UNITTEST_PRECOMMAND`` -# Matlab script command to be ran before the file -# containing the test (eg. GPU device initialisation based on CMake -# variables). -# ``TIMEOUT`` -# the test timeout in seconds. Defaults to 180 seconds as the -# Matlab unit test may hang. -# ``ADDITIONAL_PATH`` -# a list of paths to add to the Matlab path prior to -# running the unit test. -# ``MATLAB_ADDITIONAL_STARTUP_OPTIONS`` -# a list of additional option in order -# to run Matlab from the command line. -# ``-nosplash -nodesktop -nodisplay`` are always added. -# ``TEST_ARGS`` -# Additional options provided to the add_test command. These -# options are added to the default options (eg. "CONFIGURATIONS Release") -# ``NO_UNITTEST_FRAMEWORK`` -# when set, indicates that the test should not -# use the unittest framework of Matlab (available for versions >= R2013a). -# ``WORKING_DIRECTORY`` -# This will be the working directory for the test. If specified it will -# also be the output directory used for the log file of the test run. -# If not specified the temporary directory ``${CMAKE_BINARY_DIR}/Matlab`` will -# be used as the working directory and the log location. -# -function(matlab_add_unit_test) - - if(NOT Matlab_MAIN_PROGRAM) - message(FATAL_ERROR "[MATLAB] This functionality needs the MAIN_PROGRAM component (not default)") - endif() - - set(options NO_UNITTEST_FRAMEWORK) - set(oneValueArgs NAME UNITTEST_FILE TIMEOUT WORKING_DIRECTORY - UNITTEST_PRECOMMAND CUSTOM_TEST_COMMAND) - set(multiValueArgs ADDITIONAL_PATH MATLAB_ADDITIONAL_STARTUP_OPTIONS TEST_ARGS) - - set(prefix _matlab_unittest_prefix) - cmake_parse_arguments(PARSE_ARGV 0 ${prefix} "${options}" "${oneValueArgs}" "${multiValueArgs}" ) - - if(NOT ${prefix}_NAME) - message(FATAL_ERROR "[MATLAB] The Matlab test name cannot be empty") - endif() - - add_test(NAME ${${prefix}_NAME} - COMMAND ${CMAKE_COMMAND} - "-Dtest_name=${${prefix}_NAME}" - "-Dadditional_paths=${${prefix}_ADDITIONAL_PATH}" - "-Dtest_timeout=${${prefix}_TIMEOUT}" - "-Doutput_directory=${_matlab_temporary_folder}" - "-Dworking_directory=${${prefix}_WORKING_DIRECTORY}" - "-DMatlab_PROGRAM=${Matlab_MAIN_PROGRAM}" - "-Dno_unittest_framework=${${prefix}_NO_UNITTEST_FRAMEWORK}" - "-DMatlab_ADDITIONAL_STARTUP_OPTIONS=${${prefix}_MATLAB_ADDITIONAL_STARTUP_OPTIONS}" - "-Dunittest_file_to_run=${${prefix}_UNITTEST_FILE}" - "-Dcustom_Matlab_test_command=${${prefix}_CUSTOM_TEST_COMMAND}" - "-Dcmd_to_run_before_test=${${prefix}_UNITTEST_PRECOMMAND}" - -P ${_FindMatlab_SELF_DIR}/MatlabTestsRedirect.cmake - ${${prefix}_TEST_ARGS} - ${${prefix}_UNPARSED_ARGUMENTS} - ) -endfunction() - - -#.rst: -# .. command:: matlab_add_mex -# -# Adds a Matlab MEX target. -# This commands compiles the given sources with the current tool-chain in -# order to produce a MEX file. The final name of the produced output may be -# specified, as well as additional link libraries, and a documentation entry -# for the MEX file. Remaining arguments of the call are passed to the -# :command:`add_library` or :command:`add_executable` command. -# -# :: -# -# matlab_add_mex( -# NAME -# [EXECUTABLE | MODULE | SHARED] -# SRC src1 [src2 ...] -# [OUTPUT_NAME output_name] -# [DOCUMENTATION file.txt] -# [LINK_TO target1 target2 ...] -# [...] -# ) -# -# ``NAME`` -# name of the target. -# ``SRC`` -# list of source files. -# ``LINK_TO`` -# a list of additional link dependencies. The target links to ``libmex`` -# by default. If ``Matlab_MX_LIBRARY`` is defined, it also -# links to ``libmx``. -# ``OUTPUT_NAME`` -# if given, overrides the default name. The default name is -# the name of the target without any prefix and -# with ``Matlab_MEX_EXTENSION`` suffix. -# ``DOCUMENTATION`` -# if given, the file ``file.txt`` will be considered as -# being the documentation file for the MEX file. This file is copied into -# the same folder without any processing, with the same name as the final -# mex file, and with extension `.m`. In that case, typing ``help `` -# in Matlab prints the documentation contained in this file. -# ``MODULE`` or ``SHARED`` may be given to specify the type of library to be -# created. ``EXECUTABLE`` may be given to create an executable instead of -# a library. If no type is given explicitly, the type is ``SHARED``. -# -# The documentation file is not processed and should be in the following -# format: -# -# :: -# -# % This is the documentation -# function ret = mex_target_output_name(input1) -# -function(matlab_add_mex) - - if(NOT WIN32) - # we do not need all this on Windows - # pthread options - if(CMAKE_CXX_COMPILER_LOADED) - check_cxx_compiler_flag(-pthread HAS_MINUS_PTHREAD) - elseif(CMAKE_C_COMPILER_LOADED) - check_c_compiler_flag(-pthread HAS_MINUS_PTHREAD) - endif() - # we should use try_compile instead, the link flags are discarded from - # this compiler_flag function. - #check_cxx_compiler_flag(-Wl,--exclude-libs,ALL HAS_SYMBOL_HIDING_CAPABILITY) - - endif() - - set(options EXECUTABLE MODULE SHARED) - set(oneValueArgs NAME DOCUMENTATION OUTPUT_NAME) - set(multiValueArgs LINK_TO SRC) - - set(prefix _matlab_addmex_prefix) - cmake_parse_arguments(${prefix} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) - - if(NOT ${prefix}_NAME) - message(FATAL_ERROR "[MATLAB] The MEX target name cannot be empty") - endif() - - if(NOT ${prefix}_OUTPUT_NAME) - set(${prefix}_OUTPUT_NAME ${${prefix}_NAME}) - endif() - - if(${prefix}_EXECUTABLE) - add_executable(${${prefix}_NAME} - ${${prefix}_SRC} - ${${prefix}_DOCUMENTATION} - ${${prefix}_UNPARSED_ARGUMENTS}) - else() - if(${prefix}_MODULE) - set(type MODULE) - else() - set(type SHARED) - endif() - - add_library(${${prefix}_NAME} - ${type} - ${${prefix}_SRC} - ${${prefix}_DOCUMENTATION} - ${${prefix}_UNPARSED_ARGUMENTS}) - endif() - - target_include_directories(${${prefix}_NAME} PRIVATE ${Matlab_INCLUDE_DIRS}) - - if(DEFINED Matlab_MX_LIBRARY) - target_link_libraries(${${prefix}_NAME} ${Matlab_MX_LIBRARY}) - endif() - - target_link_libraries(${${prefix}_NAME} ${Matlab_MEX_LIBRARY} ${${prefix}_LINK_TO}) - set_target_properties(${${prefix}_NAME} - PROPERTIES - PREFIX "" - OUTPUT_NAME ${${prefix}_OUTPUT_NAME} - SUFFIX ".${Matlab_MEX_EXTENSION}") - - - # documentation - if(NOT ${${prefix}_DOCUMENTATION} STREQUAL "") - get_target_property(output_name ${${prefix}_NAME} OUTPUT_NAME) - add_custom_command( - TARGET ${${prefix}_NAME} - PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${${prefix}_DOCUMENTATION} $/${output_name}.m - COMMENT "[MATLAB] Copy ${${prefix}_NAME} documentation file into the output folder" - ) - endif() # documentation - - # entry point in the mex file + taking care of visibility and symbol clashes. - if(WIN32) - set_target_properties(${${prefix}_NAME} - PROPERTIES - DEFINE_SYMBOL "DLL_EXPORT_SYM=__declspec(dllexport)") - else() - - if(HAS_MINUS_PTHREAD AND NOT APPLE) - # Apparently, compiling with -pthread generated the proper link flags - # and some defines at compilation - target_compile_options(${${prefix}_NAME} PRIVATE "-pthread") - endif() - - - # if we do not do that, the symbols linked from eg. boost remain weak and - # then clash with the ones defined in the matlab process. So by default - # the symbols are hidden. - # This also means that for shared libraries (like MEX), the entry point - # should be explicitly declared with default visibility, otherwise Matlab - # cannot find the entry point. - # Note that this is particularly meaningful if the MEX wrapper itself - # contains symbols that are clashing with Matlab (that are compiled in the - # MEX file). In order to propagate the visibility options to the libraries - # to which the MEX file is linked against, the -Wl,--exclude-libs,ALL - # option should also be specified. - - set_target_properties(${${prefix}_NAME} - PROPERTIES - CXX_VISIBILITY_PRESET "hidden" - C_VISIBILITY_PRESET "hidden" - VISIBILITY_INLINES_HIDDEN ON - ) - - # get_target_property( - # _previous_link_flags - # ${${prefix}_NAME} - # LINK_FLAGS) - # if(NOT _previous_link_flags) - # set(_previous_link_flags) - # endif() - - # if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - # set_target_properties(${${prefix}_NAME} - # PROPERTIES - # LINK_FLAGS "${_previous_link_flags} -Wl,--exclude-libs,ALL" - # # -Wl,--version-script=${_FindMatlab_SELF_DIR}/MatlabLinuxVisibility.map" - # ) - # elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - # # in this case, all other symbols become hidden. - # set_target_properties(${${prefix}_NAME} - # PROPERTIES - # LINK_FLAGS "${_previous_link_flags} -Wl,-exported_symbol,_mexFunction" - # #-Wl,-exported_symbols_list,${_FindMatlab_SELF_DIR}/MatlabOSXVisilibity.map" - # ) - # endif() - - - - set_target_properties(${${prefix}_NAME} - PROPERTIES - DEFINE_SYMBOL "DLL_EXPORT_SYM=__attribute__ ((visibility (\"default\")))" - ) - - - endif() - -endfunction() - - -# (internal) -# Used to get the version of matlab, using caching. This basically transforms the -# output of the root list, with possible unknown version, to a version -# This can possibly run Matlab for extracting the version. -function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_version matlab_final_version) - - # if the version is not trivial, we query matlab (if not MCR) for that - # we keep track of the location of matlab that induced this version - #if(NOT DEFINED Matlab_PROG_VERSION_STRING_AUTO_DETECT) - # set(Matlab_PROG_VERSION_STRING_AUTO_DETECT "" CACHE INTERNAL "internal matlab location for the discovered version") - #endif() - - if(NOT ${matlab_known_version} STREQUAL "NOTFOUND") - # the version is known, we just return it - set(${matlab_final_version} ${matlab_known_version} PARENT_SCOPE) - set(Matlab_VERSION_STRING_INTERNAL ${matlab_known_version} CACHE INTERNAL "Matlab version (automatically determined)" FORCE) - return() - endif() - - if("${matlab_or_mcr}" STREQUAL "UNKNOWN") - if(MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] Determining Matlab or MCR") - endif() - - if(EXISTS "${matlab_root}/appdata/version.xml") - # we inspect the application version.xml file that contains the product information - file(STRINGS "${matlab_root}/appdata/version.xml" productinfo_string NEWLINE_CONSUME) - string(REGEX MATCH "" - product_reg_match - ${productinfo_string} - ) - - # default fallback to Matlab - set(matlab_or_mcr "MATLAB") - if(NOT "${CMAKE_MATCH_1}" STREQUAL "") - string(TOLOWER "${CMAKE_MATCH_1}" product_reg_match) - - if("${product_reg_match}" STREQUAL "matlab runtime") - set(matlab_or_mcr "MCR") - endif() - endif() - endif() - - if(MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] '${matlab_root}' contains the '${matlab_or_mcr}'") - endif() - endif() - - # UNKNOWN is the default behaviour in case we - # - have an erroneous matlab_root - # - have an initial 'UNKNOWN' - if("${matlab_or_mcr}" STREQUAL "MATLAB" OR "${matlab_or_mcr}" STREQUAL "UNKNOWN") - # MATLAB versions - set(_matlab_current_program ${Matlab_MAIN_PROGRAM}) - - # do we already have a matlab program? - if(NOT _matlab_current_program) - - set(_find_matlab_options) - if(matlab_root AND EXISTS ${matlab_root}) - set(_find_matlab_options PATHS ${matlab_root} ${matlab_root}/bin NO_DEFAULT_PATH) - endif() - - find_program( - _matlab_current_program - matlab - ${_find_matlab_options} - DOC "Matlab main program" - ) - endif() - - if(NOT _matlab_current_program OR NOT EXISTS ${_matlab_current_program}) - # if not found, clear the dependent variables - if(MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] Cannot find the main matlab program under ${matlab_root}") - endif() - set(Matlab_PROG_VERSION_STRING_AUTO_DETECT "" CACHE INTERNAL "internal matlab location for the discovered version" FORCE) - set(Matlab_VERSION_STRING_INTERNAL "" CACHE INTERNAL "internal matlab location for the discovered version" FORCE) - unset(_matlab_current_program) - unset(_matlab_current_program CACHE) - return() - endif() - - # full real path for path comparison - get_filename_component(_matlab_main_real_path_tmp "${_matlab_current_program}" REALPATH) - unset(_matlab_current_program) - unset(_matlab_current_program CACHE) - - # is it the same as the previous one? - if(_matlab_main_real_path_tmp STREQUAL Matlab_PROG_VERSION_STRING_AUTO_DETECT) - set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE) - return() - endif() - - # update the location of the program - set(Matlab_PROG_VERSION_STRING_AUTO_DETECT - ${_matlab_main_real_path_tmp} - CACHE INTERNAL "internal matlab location for the discovered version" FORCE) - - set(matlab_list_of_all_versions) - matlab_get_version_from_matlab_run("${Matlab_PROG_VERSION_STRING_AUTO_DETECT}" matlab_list_of_all_versions) - - list(LENGTH matlab_list_of_all_versions list_of_all_versions_length) - if(${list_of_all_versions_length} GREATER 0) - list(GET matlab_list_of_all_versions 0 _matlab_version_tmp) - else() - set(_matlab_version_tmp "unknown") - endif() - - # set the version into the cache - set(Matlab_VERSION_STRING_INTERNAL ${_matlab_version_tmp} CACHE INTERNAL "Matlab version (automatically determined)" FORCE) - - # warning, just in case several versions found (should not happen) - if((${list_of_all_versions_length} GREATER 1) AND MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] Found several versions, taking the first one (versions found ${matlab_list_of_all_versions})") - endif() - - # return the updated value - set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE) - else() - # MCR - # we cannot run anything in order to extract the version. We assume that the file - # VersionInfo.xml exists under the MatlabRoot, we look for it and extract the version from there - set(_matlab_version_tmp "unknown") - file(STRINGS "${matlab_root}/VersionInfo.xml" versioninfo_string NEWLINE_CONSUME) - # parses "9.2.0.538062" - string(REGEX MATCH "(.*)" - version_reg_match - ${versioninfo_string} - ) - - if(NOT "${version_reg_match}" STREQUAL "") - if("${CMAKE_MATCH_1}" MATCHES "(([0-9])\\.([0-9]))[\\.0-9]*") - set(_matlab_version_tmp "${CMAKE_MATCH_1}") - endif() - endif() - set(${matlab_final_version} "${_matlab_version_tmp}" PARENT_SCOPE) - set(Matlab_VERSION_STRING_INTERNAL - "${_matlab_version_tmp}" - CACHE INTERNAL "Matlab (MCR) version (automatically determined)" - FORCE) - - endif() # Matlab or MCR - -endfunction() - - -# Utility function for finding Matlab or MCR on Win32 -function(_Matlab_find_instances_win32 matlab_roots) - # On WIN32, we look for Matlab installation in the registry - # if unsuccessful, we look for all known revision and filter the existing - # ones. - - # testing if we are able to extract the needed information from the registry - set(_matlab_versions_from_registry) - - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_matlab_win64 ON) - else() - set(_matlab_win64 OFF) - endif() - - matlab_extract_all_installed_versions_from_registry(_matlab_win64 _matlab_versions_from_registry) - - # the returned list is empty, doing the search on all known versions - if(NOT _matlab_versions_from_registry) - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Search for Matlab from the registry unsuccessful, testing all supported versions") - endif() - extract_matlab_versions_from_registry_brute_force(_matlab_versions_from_registry) - endif() - - # filtering the results with the registry keys - matlab_get_all_valid_matlab_roots_from_registry("${_matlab_versions_from_registry}" _matlab_possible_roots) - unset(_matlab_versions_from_registry) - - set(_matlab_versions_from_registry) - matlab_extract_all_installed_versions_from_registry(CMAKE_CL_64 _matlab_versions_from_registry) - - # the returned list is empty, doing the search on all known versions - if(NOT _matlab_versions_from_registry) - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Search for Matlab from the registry unsuccessful, testing all supported versions") - endif() - extract_matlab_versions_from_registry_brute_force(_matlab_versions_from_registry) - endif() - - # filtering the results with the registry keys - matlab_get_all_valid_matlab_roots_from_registry("${_matlab_versions_from_registry}" _matlab_possible_roots) - set(${matlab_roots} ${_matlab_possible_roots} PARENT_SCOPE) - -endfunction() - -# Utility function for finding Matlab or MCR on OSX -function(_Matlab_find_instances_osx matlab_roots) - - set(_matlab_possible_roots) - # on mac, we look for the /Application paths - # this corresponds to the behaviour on Windows. On Linux, we do not have - # any other guess. - matlab_get_supported_releases(_matlab_releases) - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Matlab supported versions ${_matlab_releases}. If more version should be supported " - "the variable MATLAB_ADDITIONAL_VERSIONS can be set according to the documentation") - endif() - - foreach(_matlab_current_release IN LISTS _matlab_releases) - matlab_get_version_from_release_name("${_matlab_current_release}" _matlab_current_version) - string(REPLACE "." "" _matlab_current_version_without_dot "${_matlab_current_version}") - set(_matlab_base_path "/Applications/MATLAB_${_matlab_current_release}.app") - - # Check Matlab, has precedence over MCR - if(EXISTS ${_matlab_base_path}) - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Found version ${_matlab_current_release} (${_matlab_current_version}) in ${_matlab_base_path}") - endif() - list(APPEND _matlab_possible_roots "MATLAB" ${_matlab_current_version} ${_matlab_base_path}) - endif() - - # Checks MCR - set(_mcr_path "/Applications/MATLAB/MATLAB_Runtime/v${_matlab_current_version_without_dot}") - if(EXISTS "${_mcr_path}") - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Found MCR version ${_matlab_current_release} (${_matlab_current_version}) in ${_mcr_path}") - endif() - list(APPEND _matlab_possible_roots "MCR" ${_matlab_current_version} ${_mcr_path}) - endif() - - endforeach() - set(${matlab_roots} ${_matlab_possible_roots} PARENT_SCOPE) - -endfunction() - -# Utility function for finding Matlab or MCR from the PATH -function(_Matlab_find_instances_from_path matlab_roots) - - set(_matlab_possible_roots) - - # At this point, we have no other choice than trying to find it from PATH. - # If set by the user, this wont change - find_program( - _matlab_main_tmp - NAMES matlab) - - if(_matlab_main_tmp) - # we then populate the list of roots, with empty version - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] matlab found from PATH: ${_matlab_main_tmp}") - endif() - - # resolve symlinks - get_filename_component(_matlab_current_location "${_matlab_main_tmp}" REALPATH) - - # get the directory (the command below has to be run twice) - # this will be the matlab root - get_filename_component(_matlab_current_location "${_matlab_current_location}" DIRECTORY) - get_filename_component(_matlab_current_location "${_matlab_current_location}" DIRECTORY) # Matlab should be in bin - - # We found the Matlab program - list(APPEND _matlab_possible_roots "MATLAB" "NOTFOUND" ${_matlab_current_location}) - - # we remove this from the CACHE - unset(_matlab_main_tmp CACHE) - else() - find_program( - _matlab_mex_tmp - NAMES mex) - if(_matlab_mex_tmp) - # we then populate the list of roots, with empty version - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] mex compiler found from PATH: ${_matlab_mex_tmp}") - endif() - - # resolve symlinks - get_filename_component(_mex_current_location "${_matlab_mex_tmp}" REALPATH) - - # get the directory (the command below has to be run twice) - # this will be the matlab root - get_filename_component(_mex_current_location "${_mex_current_location}" DIRECTORY) - get_filename_component(_mex_current_location "${_mex_current_location}" DIRECTORY) # Matlab Runtime mex compiler should be in bin - - # We found the Matlab program - list(APPEND _matlab_possible_roots "MCR" "NOTFOUND" ${_mex_current_location}) - - unset(_matlab_mex_tmp CACHE) - else() - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] mex compiler not found") - endif() - endif() - - - endif() - - set(${matlab_roots} ${_matlab_possible_roots} PARENT_SCOPE) -endfunction() - - -# ################################### -# Exploring the possible Matlab_ROOTS - -# this variable will get all Matlab installations found in the current system. -set(_matlab_possible_roots) - -if(Matlab_ROOT_DIR) - # if the user specifies a possible root, we keep this one - - if(NOT EXISTS "${Matlab_ROOT_DIR}") - # if Matlab_ROOT_DIR specified but erroneous - if(MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] the specified path for Matlab_ROOT_DIR does not exist (${Matlab_ROOT_DIR})") - endif() - else() - # NOTFOUND indicates the code below to search for the version automatically - if("${Matlab_VERSION_STRING_INTERNAL}" STREQUAL "") - list(APPEND _matlab_possible_roots "UNKNOWN" "NOTFOUND" ${Matlab_ROOT_DIR}) # empty version, empty MCR/Matlab indication - else() - list(APPEND _matlab_possible_roots "UNKNOWN" ${Matlab_VERSION_STRING_INTERNAL} ${Matlab_ROOT_DIR}) # cached version - endif() - endif() -else() - - # if the user does not specify the possible installation root, we look for - # one installation using the appropriate heuristics. - # There is apparently no standard way on Linux. - if(CMAKE_HOST_WIN32) - _Matlab_find_instances_win32(_matlab_possible_roots_win32) - list(APPEND _matlab_possible_roots ${_matlab_possible_roots_win32}) - elseif(APPLE) - _Matlab_find_instances_osx(_matlab_possible_roots_osx) - list(APPEND _matlab_possible_roots ${_matlab_possible_roots_osx}) - endif() -endif() - - -list(LENGTH _matlab_possible_roots _numbers_of_matlab_roots) -if(_numbers_of_matlab_roots EQUAL 0) - # if we have not found anything, we fall back on the PATH - _Matlab_find_instances_from_path(_matlab_possible_roots) -endif() - - -if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Matlab root folders are ${_matlab_possible_roots}") -endif() - - - - - -# take the first possible Matlab root -list(LENGTH _matlab_possible_roots _numbers_of_matlab_roots) -set(Matlab_VERSION_STRING "NOTFOUND") -set(Matlab_Or_MCR "UNKNOWN") -if(_numbers_of_matlab_roots GREATER 0) - list(GET _matlab_possible_roots 0 Matlab_Or_MCR) - list(GET _matlab_possible_roots 1 Matlab_VERSION_STRING) - list(GET _matlab_possible_roots 2 Matlab_ROOT_DIR) - - # adding a warning in case of ambiguity - if(_numbers_of_matlab_roots GREATER 3 AND MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] Found several distributions of Matlab. Setting the current version to ${Matlab_VERSION_STRING} (located ${Matlab_ROOT_DIR})." - " If this is not the desired behaviour, provide the -DMatlab_ROOT_DIR=... on the command line") - endif() -endif() - - -# check if the root changed wrt. the previous defined one, if so -# clear all the cached variables for being able to reconfigure properly -if(DEFINED Matlab_ROOT_DIR_LAST_CACHED) - - if(NOT Matlab_ROOT_DIR_LAST_CACHED STREQUAL Matlab_ROOT_DIR) - set(_Matlab_cached_vars - Matlab_INCLUDE_DIRS - Matlab_MEX_LIBRARY - Matlab_MEX_COMPILER - Matlab_MCC_COMPILER - Matlab_MAIN_PROGRAM - Matlab_MX_LIBRARY - Matlab_ENG_LIBRARY - Matlab_MAT_LIBRARY - Matlab_MEX_EXTENSION - Matlab_SIMULINK_INCLUDE_DIR - - # internal - Matlab_MEXEXTENSIONS_PROG - Matlab_ROOT_DIR_LAST_CACHED - #Matlab_PROG_VERSION_STRING_AUTO_DETECT - Matlab_VERSION_STRING_INTERNAL - ) - foreach(_var IN LISTS _Matlab_cached_vars) - if(DEFINED ${_var}) - unset(${_var} CACHE) - endif() - endforeach() - endif() -endif() - -set(Matlab_ROOT_DIR_LAST_CACHED ${Matlab_ROOT_DIR} CACHE INTERNAL "last Matlab root dir location") -set(Matlab_ROOT_DIR ${Matlab_ROOT_DIR} CACHE PATH "Matlab installation root path" FORCE) - -# Fix the version, in case this one is NOTFOUND -_Matlab_get_version_from_root( - "${Matlab_ROOT_DIR}" - "${Matlab_Or_MCR}" - ${Matlab_VERSION_STRING} - Matlab_VERSION_STRING -) - -if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Current version is ${Matlab_VERSION_STRING} located ${Matlab_ROOT_DIR}") -endif() - - - -if(Matlab_ROOT_DIR) - file(TO_CMAKE_PATH ${Matlab_ROOT_DIR} Matlab_ROOT_DIR) -endif() - -if(CMAKE_SIZEOF_VOID_P EQUAL 4) - set(_matlab_64Build FALSE) -else() - set(_matlab_64Build TRUE) -endif() - -if(APPLE) - set(_matlab_bin_prefix "mac") # i should be for intel - set(_matlab_bin_suffix_32bits "i") - set(_matlab_bin_suffix_64bits "i64") -elseif(UNIX) - set(_matlab_bin_prefix "gln") - set(_matlab_bin_suffix_32bits "x86") - set(_matlab_bin_suffix_64bits "xa64") -else() - set(_matlab_bin_prefix "win") - set(_matlab_bin_suffix_32bits "32") - set(_matlab_bin_suffix_64bits "64") -endif() - - - -set(MATLAB_INCLUDE_DIR_TO_LOOK ${Matlab_ROOT_DIR}/extern/include) -if(_matlab_64Build) - set(_matlab_current_suffix ${_matlab_bin_suffix_64bits}) -else() - set(_matlab_current_suffix ${_matlab_bin_suffix_32bits}) -endif() - -set(Matlab_BINARIES_DIR - ${Matlab_ROOT_DIR}/bin/${_matlab_bin_prefix}${_matlab_current_suffix}) -set(Matlab_EXTERN_LIBRARY_DIR - ${Matlab_ROOT_DIR}/extern/lib/${_matlab_bin_prefix}${_matlab_current_suffix}) - -if(WIN32) - if(MINGW) - set(_matlab_lib_dir_for_search ${Matlab_EXTERN_LIBRARY_DIR}/mingw64) - else() - set(_matlab_lib_dir_for_search ${Matlab_EXTERN_LIBRARY_DIR}/microsoft) - endif() - set(_matlab_lib_prefix_for_search "lib") -else() - set(_matlab_lib_dir_for_search ${Matlab_BINARIES_DIR}) - set(_matlab_lib_prefix_for_search "lib") -endif() - -unset(_matlab_64Build) - - -if(NOT DEFINED Matlab_MEX_EXTENSION) - set(_matlab_mex_extension "") - matlab_get_mex_suffix("${Matlab_ROOT_DIR}" _matlab_mex_extension) - - # This variable goes to the cache. - set(Matlab_MEX_EXTENSION ${_matlab_mex_extension} CACHE STRING "Extensions for the mex targets (automatically given by Matlab)") - unset(_matlab_mex_extension) -endif() - - -if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] [DEBUG]_matlab_lib_prefix_for_search = ${_matlab_lib_prefix_for_search} | _matlab_lib_dir_for_search = ${_matlab_lib_dir_for_search}") -endif() - - - -# internal -# This small stub around find_library is to prevent any pollution of CMAKE_FIND_LIBRARY_PREFIXES in the global scope. -# This is the function to be used below instead of the find_library directives. -function(_Matlab_find_library _matlab_library_prefix) - set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES} ${_matlab_library_prefix}) - find_library(${ARGN}) -endfunction() - - -set(_matlab_required_variables) - - -# the MEX library/header are required -find_path( - Matlab_INCLUDE_DIRS - mex.h - PATHS ${MATLAB_INCLUDE_DIR_TO_LOOK} - NO_DEFAULT_PATH - ) -list(APPEND _matlab_required_variables Matlab_INCLUDE_DIRS) - -_Matlab_find_library( - ${_matlab_lib_prefix_for_search} - Matlab_MEX_LIBRARY - mex - PATHS ${_matlab_lib_dir_for_search} - NO_DEFAULT_PATH -) - -list(APPEND _matlab_required_variables Matlab_MEX_LIBRARY) - -# the MEX extension is required -list(APPEND _matlab_required_variables Matlab_MEX_EXTENSION) - -# the matlab root is required -list(APPEND _matlab_required_variables Matlab_ROOT_DIR) - -# component Mex Compiler -list(FIND Matlab_FIND_COMPONENTS MEX_COMPILER _matlab_find_mex_compiler) -if(_matlab_find_mex_compiler GREATER -1) - find_program( - Matlab_MEX_COMPILER - "mex" - PATHS ${Matlab_BINARIES_DIR} - DOC "Matlab MEX compiler" - NO_DEFAULT_PATH - ) - if(Matlab_MEX_COMPILER) - set(Matlab_MEX_COMPILER_FOUND TRUE) - endif() -endif() -unset(_matlab_find_mex_compiler) - -# component Matlab program -list(FIND Matlab_FIND_COMPONENTS MAIN_PROGRAM _matlab_find_matlab_program) -if(_matlab_find_matlab_program GREATER -1) - find_program( - Matlab_MAIN_PROGRAM - matlab - PATHS ${Matlab_ROOT_DIR} ${Matlab_ROOT_DIR}/bin - DOC "Matlab main program" - NO_DEFAULT_PATH - ) - if(Matlab_MAIN_PROGRAM) - set(Matlab_MAIN_PROGRAM_FOUND TRUE) - endif() -endif() -unset(_matlab_find_matlab_program) - -# Component MX library -list(FIND Matlab_FIND_COMPONENTS MX_LIBRARY _matlab_find_mx) -if(_matlab_find_mx GREATER -1) - _Matlab_find_library( - ${_matlab_lib_prefix_for_search} - Matlab_MX_LIBRARY - mx - PATHS ${_matlab_lib_dir_for_search} - NO_DEFAULT_PATH - ) - if(Matlab_MX_LIBRARY) - set(Matlab_MX_LIBRARY_FOUND TRUE) - endif() -endif() -unset(_matlab_find_mx) - -# Component ENG library -list(FIND Matlab_FIND_COMPONENTS ENG_LIBRARY _matlab_find_eng) -if(_matlab_find_eng GREATER -1) - _Matlab_find_library( - ${_matlab_lib_prefix_for_search} - Matlab_ENG_LIBRARY - eng - PATHS ${_matlab_lib_dir_for_search} - NO_DEFAULT_PATH - ) - if(Matlab_ENG_LIBRARY) - set(Matlab_ENG_LIBRARY_FOUND TRUE) - endif() -endif() -unset(_matlab_find_eng) - -# Component MAT library -list(FIND Matlab_FIND_COMPONENTS MAT_LIBRARY _matlab_find_mat) -if(_matlab_find_mat GREATER -1) - _Matlab_find_library( - ${_matlab_lib_prefix_for_search} - Matlab_MAT_LIBRARY - mat - PATHS ${_matlab_lib_dir_for_search} - NO_DEFAULT_PATH - ) - if(Matlab_MAT_LIBRARY) - set(Matlab_MAT_LIBRARY_FOUND TRUE) - endif() -endif() -unset(_matlab_find_mat) - -# Component Simulink -list(FIND Matlab_FIND_COMPONENTS SIMULINK _matlab_find_simulink) -if(_matlab_find_simulink GREATER -1) - find_path( - Matlab_SIMULINK_INCLUDE_DIR - simstruc.h - PATHS "${Matlab_ROOT_DIR}/simulink/include" - NO_DEFAULT_PATH - ) - if(Matlab_SIMULINK_INCLUDE_DIR) - set(Matlab_SIMULINK_FOUND TRUE) - list(APPEND Matlab_INCLUDE_DIRS "${Matlab_SIMULINK_INCLUDE_DIR}") - endif() -endif() -unset(_matlab_find_simulink) - -# component MCC Compiler -list(FIND Matlab_FIND_COMPONENTS MCC_COMPILER _matlab_find_mcc_compiler) -if(_matlab_find_mcc_compiler GREATER -1) - find_program( - Matlab_MCC_COMPILER - "mcc" - PATHS ${Matlab_BINARIES_DIR} - DOC "Matlab MCC compiler" - NO_DEFAULT_PATH - ) - if(Matlab_MCC_COMPILER) - set(Matlab_MCC_COMPILER_FOUND TRUE) - endif() -endif() -unset(_matlab_find_mcc_compiler) - -unset(_matlab_lib_dir_for_search) - -set(Matlab_LIBRARIES ${Matlab_MEX_LIBRARY} ${Matlab_MX_LIBRARY} ${Matlab_ENG_LIBRARY} ${Matlab_MAT_LIBRARY}) - -find_package_handle_standard_args( - Matlab - FOUND_VAR Matlab_FOUND - REQUIRED_VARS ${_matlab_required_variables} - VERSION_VAR Matlab_VERSION_STRING - HANDLE_COMPONENTS) - -unset(_matlab_required_variables) -unset(_matlab_bin_prefix) -unset(_matlab_bin_suffix_32bits) -unset(_matlab_bin_suffix_64bits) -unset(_matlab_current_suffix) -unset(_matlab_lib_dir_for_search) -unset(_matlab_lib_prefix_for_search) - -if(Matlab_INCLUDE_DIRS AND Matlab_LIBRARIES) - mark_as_advanced( - Matlab_MEX_LIBRARY - Matlab_MX_LIBRARY - Matlab_ENG_LIBRARY - Matlab_MAT_LIBRARY - Matlab_INCLUDE_DIRS - Matlab_FOUND - Matlab_MAIN_PROGRAM - Matlab_MEXEXTENSIONS_PROG - Matlab_MEX_EXTENSION - ) -endif() diff --git a/cmake/OpenfastCmakeUtils.cmake b/cmake/OpenfastCmakeUtils.cmake index 483758241..1a490e745 100644 --- a/cmake/OpenfastCmakeUtils.cmake +++ b/cmake/OpenfastCmakeUtils.cmake @@ -42,13 +42,11 @@ function(generate_f90_types regfile outfile) get_filename_component(input ${regfile} ABSOLUTE) get_filename_component(outdir ${outfile} DIRECTORY) - add_custom_command( OUTPUT ${outfile} DEPENDS openfast_registry ${input} - COMMAND ${CMAKE_BINARY_DIR}/modules/openfast-registry/openfast_registry ${input} "-O" "${outdir}" ${OPENFAST_REGISTRY_INCLUDES} ${ARGN} + COMMAND ${CMAKE_BINARY_DIR}/modules/openfast-registry/openfast_registry ${input} "-O" ${outdir} ${OPENFAST_REGISTRY_INCLUDES} ${ARGN} ) - set_source_files_properties(${output} PROPERTIES GENERATED TRUE) endfunction(generate_f90_types) # diff --git a/cmake/OpenfastFortranOptions.cmake b/cmake/OpenfastFortranOptions.cmake index b936aed4b..0efa0aed5 100644 --- a/cmake/OpenfastFortranOptions.cmake +++ b/cmake/OpenfastFortranOptions.cmake @@ -42,8 +42,9 @@ macro(set_fast_fortran) # Abort if we do not have gfortran or Intel Fortran Compiler. if (NOT (${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU" OR - ${CMAKE_Fortran_COMPILER_ID} MATCHES "^Intel")) - message(FATAL_ERROR "OpenFAST requires either GFortran or Intel Fortran Compiler. Compiler detected by CMake: ${FCNAME}.") + ${CMAKE_Fortran_COMPILER_ID} MATCHES "^Intel" OR + ${CMAKE_Fortran_COMPILER_ID} STREQUAL "Flang")) + message(FATAL_ERROR "OpenFAST requires GFortran, Intel, or Flang Compiler. Compiler detected by CMake: ${FCNAME}.") endif() # Verify proper compiler versions are available @@ -70,7 +71,16 @@ macro(set_fast_fortran) set_fast_gfortran() elseif(${CMAKE_Fortran_COMPILER_ID} MATCHES "^Intel") set_fast_intel_fortran() + elseif(${CMAKE_Fortran_COMPILER_ID} STREQUAL "Flang") + set_fast_flang() endif() + + # If double precision option enabled, set preprocessor define to use + # real64 for ReKi reals + if (DOUBLE_PRECISION) + add_definitions(-DOPENFAST_DOUBLE_PRECISION) + endif() + endmacro(set_fast_fortran) # @@ -101,6 +111,7 @@ macro(set_fast_gfortran) if(NOT WIN32) set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fpic ") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpic") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fpic") endif(NOT WIN32) # Fix free-form compilation for OpenFAST @@ -112,11 +123,10 @@ macro(set_fast_gfortran) # and https://github.com/OpenFAST/openfast/pull/595 set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fstack-reuse=none") - # Deal with Double/Single precision + # If double precision, make constants double precision if (DOUBLE_PRECISION) - add_definitions(-DOPENFAST_DOUBLE_PRECISION) - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fdefault-real-8") - endif (DOUBLE_PRECISION) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fdefault-real-8 -fdefault-double-8") + endif() # debug flags if(CMAKE_BUILD_TYPE MATCHES Debug) @@ -129,12 +139,6 @@ macro(set_fast_gfortran) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS},--stack,${stack_size}") endif() - # OPENMP - if (OPENMP) - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fopenmp") - set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fopenmp" ) - endif() - check_f2008_features() endmacro(set_fast_gfortran) @@ -155,25 +159,19 @@ endmacro(set_fast_intel_fortran) # macro(set_fast_intel_fortran_posix) set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fpic -fpp") - # Deal with Double/Single precision - if (DOUBLE_PRECISION) - add_definitions(-DOPENFAST_DOUBLE_PRECISION) - 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,noarg_temp_created -traceback -init=huge,infinity" ) endif() - # OPENMP - if (OPENMP) - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -qopenmp") - set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -qopenmp" ) + # If double precision, make real and double constants 64 bits + if (DOUBLE_PRECISION) + if("${CMAKE_Fortran_COMPILER_VERSION}" VERSION_GREATER "19") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -real-size 64 -double-size 64") + else() + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -real_size 64 -double_size 64") + endif() endif() check_f2008_features() @@ -205,15 +203,14 @@ macro(set_fast_intel_fortran_windows) # - 5268: 132 column limit set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} /Qdiag-disable:5199,5268 /fpp") - # Deal with Double/Single precision + # If double precision, make constants double precision if (DOUBLE_PRECISION) - add_definitions(-DOPENFAST_DOUBLE_PRECISION) if("${CMAKE_Fortran_COMPILER_VERSION}" VERSION_GREATER "19") - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} /real-size:64 /double-size:128") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} /real-size:64 /double-size:64") else() - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} /real_size:64 /double_size:128") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} /real_size:64 /double_size:64") endif() - endif (DOUBLE_PRECISION) + endif() # increase the default 2MB stack size to 16 MB MATH(EXPR stack_size "16 * 1024 * 1024") @@ -224,11 +221,23 @@ macro(set_fast_intel_fortran_windows) set( CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} /check:all,noarg_temp_created /traceback /Qinit=huge,infinity" ) endif() - # OPENMP - if (OPENMP) - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} /qopenmp") - set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} /qopenmp" ) - endif() - check_f2008_features() endmacro(set_fast_intel_fortran_windows) + +# +# set_fast_flang - Customizations for GNU Fortran compiler +# +macro(set_fast_flang) + + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fno-backslash -cpp -fPIC") + + # Deal with Double/Single precision + if (DOUBLE_PRECISION) + add_definitions(-DOPENFAST_DOUBLE_PRECISION) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fdefault-real-8") + endif (DOUBLE_PRECISION) + + add_definitions(-DFLANG_COMPILER) + + check_f2008_features() +endmacro(set_fast_flang) diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 7e67f2f05..176286d01 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -29,15 +29,13 @@ else() # Add a sphinx-only HTML target to avoid building doxygen while developing documentation add_custom_target(sphinx-html COMMAND ${SPHINX_EXECUTABLE} -M html - "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" - -c ${CMAKE_CURRENT_SOURCE_DIR}) + "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}") # PDF documentation generation using sphinx -> latex -> pdflatex find_package(LATEX COMPONENTS PDFLATEX BIBTEX) if (LATEX_FOUND) add_custom_target(sphinx-pdf COMMAND ${SPHINX_EXECUTABLE} -M latexpdf - "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" - -c ${CMAKE_CURRENT_BINARY_DIR}) + "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}") endif() endif() diff --git a/docs/OtherSupporting/AeroDyn/Buoyancy_Implementation_Plan_Rev11.docx b/docs/OtherSupporting/AeroDyn/Buoyancy_Implementation_Plan_Rev11.docx new file mode 100644 index 0000000000000000000000000000000000000000..201a4116de593da0a48ab06409d92405e41a340e GIT binary patch literal 168111 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

3+RQ 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 Nz!%Le640{&{U7E0jfDUJ literal 0 HcmV?d00001 diff --git a/docs/OtherSupporting/AeroDyn/Buoyancy_Implementation_Plan_Rev3.docx b/docs/OtherSupporting/AeroDyn/Buoyancy_Implementation_Plan_Rev3.docx deleted file mode 100644 index b690d9c7e72c55bc27c52ce58609e83337b0b821..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 170667 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 z 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

%WY8$?Y#o)d<(82A|7>$rg=XfzvY!rHZ# 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%0A;Bb+1SO(_suSu_1;&URGW?_F?gp4<* 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 Mr?yMQG0kk@1^el0=Kufz diff --git a/docs/OtherSupporting/ElastoDyn/FASTLogicFlow.doc b/docs/OtherSupporting/ElastoDyn/FASTLogicFlow.doc index 8a7131579bf728a68bec0aa72d0e1fd9d673d838..360e13d3cb46edae106a632abc269a148f3462b6 100644 GIT binary patch literal 27648 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 NkBw(_>VHlH{{tW1J<$LF literal 25088 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

;40*7S~Ee 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�y+)kAQOzT-i%%Ah*ue|r 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 diff --git a/docs/_static/assets_download.jpg b/docs/_static/assets_download.jpg index ed5e874ae02862fa78a5fdbc54f18f57a7a97029..7451d68bee02fdbcd1bd2ed104d1d5c9dd9cb1f9 100644 GIT binary patch literal 469850 zcmeFZcU)6j*Dku~O+=+B2q;x*Ec6x;0RaK&0zyP;i1Zd}6ct3;mZ~726p=0^AT?6m zihy(pLMYN(q7WjaoTdBS`~B|u>pSJ1-#zzp<+n1QH8a~7Ypyw;G3LyoeWuLc~2mlPJu>cDg z9s|#7&*}gEl|kk?!{3-O=x0J5OI<@lFtl_DaC7qs^z;p)&9R;K3<~m7hd_J+6`Wmt zZ@DSB_*fi+ z5+2}Y8E$Ij5{__Da}|YZpVCCCBfb5+-GZD?A-!+=1gayoM1K{o4&tBD5Ybb=k^~{N zM6a7%JEiLz;C4z`;jF@0Q80IatGl|zW&MBU1+TP3|JBIQ&`^cY3ktpg9*}ctYHE

-;B>?Uh1o!nh^|M6hTfV_TTB4#5um;G#s`v^2 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ⓈOE>K|zzO~+TA|X~ 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⩔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∋jh3LBMW!G0T zUmuD;&LzlEqw1UmnT28mi8>^?GcSS6eL2X->NSKWLZYKVp zi68x*bl+dil_t26j2<`pB8nO>q8at~Y%^QiD9%>>$(9e0Qc)^FgS!$TIps>_=Fti?4w< zApjd}Et9AY+YWGAkn+S#p*z&LsiG8pgQZ_LTr3N&n4<5vk>i&E}=EWHiJ=9-^eniU(Zp>$DiG~{K@Th!+fXLomunXJUXqw`dTIKhrpk%8bG_p= z&TsBCRUjCH=0Pjt95Y%}SgjCL)$5vr(7|?N6X=1AJX!h-Y*VoQ<4|HJG(7Y=6-?ZB ziX+f}OxK)&^f@O%_G+QjvU861VTN|-1mQeiv+sh)t{11(?q5{=9RE7Bs@ z2t0D(ugcv@^E|?5T^)uLiXwrc3M3!GO5$4c3cSi{hQ@``4NQp=ww zDNktL1=~uI?V+G~A)09ZnSiM)2zGiDF*$J;z@3sn2vxp=G~B@P>4FkhI}UUp#Z6X3vQMj0Igg{fU7A}!_Q?GySjw0ZBpSR za#9Dyc%oBh=LK_qY7}g{3V71I*cA|j5$s!Xy*Bkr=5S?iWjn{L(e4`ITOa)0o_3A%$ZPHt1QX<7JuQIRB~GWQ7tAg_&oL#wh%G3>6r^Hu4=_PmDqRT-s| zvWu`+WMtEZ-U=L{4C$#Ptvca00rZTZC9?wrXGfuHn;fJ*jJ8?RaPFIdU*x!VD)KO{Br!mnb5?kJu_xyrS#yOVUMcmu+ZxQfp1WL%&nCg zZnu>aIMy5Qs~ZWYl)DK>)qk;$s7%z)j^8AOgUrUw&{5@S$hS>TXlQ@o)eWKvkAM~@ z?&_fI(wNT(4ni51hwb&TFY*2gpFzSmQq2T_(ql90^u%AqahzAkt8V?5$c3UfRDQ0v zs#4_3%B?R__yl$_^6nKp^*vSR)3Oj-MK5!x{5nFZKuX;*#_T|l^BocLkq>$=(Fnv{ z7!vkEe-v#ccWMkEk}N?q0Iv8)EW_bCGwlQiz`VC-Y**plEk_#9dex)wE0gRY;ztG}{ zIX;K){+R_5y%QqMHN5667W)^tjg83uiRcl?v5(TF3)V+eZ(1bWlLlHws!P$^i ziOLh;&U~W0pcw#A)#ry}9Z6#JJfBLqGRWFzL8&q+OEDOjvP`LyY=b%=vXk{41nmSj zsyA{zb?4W2R{~dSPY$quOT#(-?o+oK*QBJ?M+jKLnCIexVvE-;tOQMvMoBpco^q)Fu+G@o+V!A$>n#+eVd=r$J`g{^$IQr`ZxOrSku{sg{o?&n)FOxA6#i+p|Ftg zm6$v9nMc`13MJhqZ9|5QBClf;kUJoWD5v-(2yByi0!-4qR<^Z6W1G^+4c9leXpvD; zSCpwMXR#i#4Qtfp2L8s$Uj)B0Jp8(LA9>c;-J2gqZS5l1OVqr{V5c8A%f<+5PRy%6~UG6DBinQK3ViLl?d;clGTt1j780aSg_b7s_G0@~3QR#zo?4kLG^6g=DVamOgf%I5G*nEWyCQj*~+|AP>6AuSM z`9Dh?1~_ybClPxmgPT#PeicLV5CB)g3s)sAELa8%qG}d>h{zhGT!c@xtnnM$m zzo;$(ybVPrZ6|_$5ros;1)KK9Bi(B26&*^|76Vi#GWiw*s%Q;v5tYtnP(qXg|7^PRz;ts{0_!&G|wFkVGhx(<~V-1`Hr7jJ!g9Yl_rP)s-a2GV&+J|V(eFgvfbhpMI0@bM2=A{ ztSQdYeo+yVVP0YNZ1vLNee=AzxTw4b9VcFfSF*xmT~6E|F2HacY$o_4 zV<0@(w>f0=5cT>8s=hI%n~}A|nDFI?v75@22T85Q>@dpz^n}|9SErQhRG2=?1PYMj zVc!C92XRQ{Cj;p%_tDyQk^1=a?d?K+VAkQ)#ya$POtZssGk!4l^6Q+pmFu5RnBVu| z-72~Cwk+6_>FjW4Y5Y)$0LST#5`a3%n8S9YAL-;rxH;weM$ud7^=jf&F+i<$NaVjt zNe`N1CrxCZ7wp8O6paOBCfg+^N(cT&z{r+3#y|qlN>7IES|+Ej=NQzLZl^u<4F8JZ zboRSSZcNPOJULI3W{D&3 z-L(Hk?8`eh1XEt%gq-8z`tz$R8eHwBOuAqHiOltU)qMvial0I!SR#4JbzNq$e2#L- zwfu2%+H$xsvBmr|DK><|mZApk5>KjA?N5Pj`QLTJ^{|I>$~yZWCn+iD?IJfb&g(1C zn2$80-E4gOzw0gx!P&dg52G08%3VbZ*2wQyt@YRf-b?X_>Q9SMM_s>TkE;v#kxVzq zNUUb1dH&CY(_fFpf31wKtFM(n=$=JWXPKRRpPIrts`^D;1cZ%6#w;m66(G0wWu=8u z4RS-^6@2V3!_B6$t!)g}Rv8I=++|LsftIQEJF4(8J%Tpec4zaSZ#?>;G4*hv$w8l6 zp1y22Ju%vShJKb*x&L?at%Td-W|-o^vg!XcZ1vIs&E`?%QPq#o1L;7gUht1V>Isg= zz2LL?;@DQyC=eECb)j}bwQ>^VHkHv36dv!>ILS`o$4K-2>`#>kwMZUJ4o4?C3Z0nR zR=0YV+(R3Ji^*<|Uwxhq1r7z}k6`)ioR6 zkrVlltO2wfX%sC2Hc=`8duU(-A_!xXr&oqdZuTo{zb%(DdF1jSOgyhJ78855!q55R zhqrIFOOCk|&S$y#b^3GG=%!)N@|JThd?scbUL2f3{dXNLqtHpU6D7YmJkQ!UgZv)F zp*#}k0}Tw}H|b*TbJYzfyF%qWv?BSQfL8`0cW92{TL>4hw_@q4OT$rPU4zT?9evT- zl;q|2H11D>%VU3fexi@{p|c&$-^}S=e;SjPc(AldSiR7h_%y01t6mYywq6j%zO0w8 z7JOoZSCgR5Unw*b_0hn_hM=jHXd=~W?bR7w@_?R9>SV+V?;{QpE<Y8pCiBlJV~U}NzsL1?Lq^M z9{!u_DIgC98VuWo9*5S3I(t4z-19FDN516I=Pe_jvxdu*IBrjI@GYM@bo0l8m-*y` zH>_OlHQEr*kgCsfb+vQh2T?kN!VyVASDyMgX_Cx-tytJKg-&Ii076@t@~s|nuWH9+ zCzg-CyCaxRE!6xb`M^G~XVK8f4J zi`XV|%07o*N;1jQxUxe9*((?XICW#JmW{`L%wGJM9d&inZpdt*3<8l!UUgQ~@Aqcg=rbFQo5HZJB3)vu?+*Q^*! zzW2}o3Rsm|qoqF!M^9tex>e0?vi0&85V>3xsxJH$4EPvvWGd27(i|%GlIC@F=Aj>3 z71~??#zERI-$h0xIyrLZtwycpuGD>rD*xmc)m?AcJMJiEy++0i-kYY_I{O9lB=t>W z^}^BMPTTSB3H!%iS^2A2Dm^mm{g-AiyKKO!|4?a1$~^T(SZDE{NU7{vNh&)u9q9=b z%JMtV-@{?|(cd%&Ts>S^rLu#}Zi$ancl~eK`RWY=!J!OKYg{Nsx6$=-=7gvBtZS|) zu*R$Ix6Iq<@F1|3r|p@>s=-wUG+Ga%e-TDDeTLP)m_kB_VDl~FCiXTV#`s5dF-z|Q zhO`B-7f5X?RYs6Vj7nGDjO+ACEzYm1u-4>~Y{OyFd_cPqC_yU#wd zc^&Y})t@W-(7(7Wbl-76_$a2EVwz%Wht!J9sFy3vSvBN3S`?!thiyh^uwk76?aNW* z^$dX)r$Hcj)a;@BX(m`lW|Y!SvlMH!BDWB3%G@)gC~;_RTVqt0^jfgB6h0vT;|+Fm z9qyQ5F>$Nsy9oG|D)W!S)JCTE?T=IxF4`9x+ggRpA2btwBP_1;JgS5Um)}|e{2aoRb*GaAi z5FbWA5B;!Cxpk~}bCnfkXZW`xQDDFF!@1izwHKo9=~(!c`CR^x=aGA|*3;MRYz#Lc zcGd22)bNm7ea~V6+6>L_UCy z@j`%10R>$%QZGC9W&3kHm!q-B`=q=yc$Hhf^~*u-uda4KMfm%qmZojl(Np(Pyqsay zd|Ce(is|FOI@j=z2X%7=2!1Rn$j`#otA(vjBWh3=%)$EkjtGPInIF62qtxzJ&j?iQ|u$2~@7g-K~6;N^OdsUpuvcOcmBB+AYcG zePFRhpu@q5J-|FTnyeHXzmWDt(L#?$>AispMQG@P$`!zdhjVzb+Ex39HbsrNR$9Iu zr`SJhegAszn@&)t<|&Cr%PT~76^?V}Xf$9Cjo0i}{pioc@xH2Eu5!mA)*<41*v?&| zsbE)S6yEooGv}9NjbW z+|_O+j!MUQ4v&CXj4|>Y-Khomt9G`@e{U|N_tQ)UH9ql*<@yXu2=Gc99;yFits{6y zwK#Ztw9_tK0 zfINE&{ek?~fvwx@+%6Op9MnGZ+gQ+|QlVt2w|cm^$B&m#u;#R}ST5SkAo!#@4`B$+ z$x|V7B?_A^{y}zX(&j$mDE{Ev%Fs%%@HXZEu~>R&y}~3no6W>r6N?I~7UO@{m61ASs|g)2sVfLb4}`|6RhSx? zO_y-f7`{vF{zOI=>$idu9xn4u(tM+Ggs8<^y>uSihf1fMZiEcO^JnVRwsU^2XFc29 zcyueJE6u&_(~VJ~gMYX^gFMJ_?p*Rn+{IrL@Lz9#8d%UW9h0Ay%M{FxG$cqA0Ta-e zycrA<`+WEG=jyNQ*hJJt}Od@&snWVhCXZXnH`4+21Nw znScl>r(f!2{D*`y)Nr5p#D5qKdOyyd@_*=ylSFaF|xR8oqA^E*YEwdSm4R95{ zo)BETwJR;n1u=_p?gV;zMPzho!=QTF_5`k>uksT%-#wJaQwOd2cQxEVOD_(L*0!^E z*HOp<0((aWISM_tUYxPOzHVWU-o`|!EZAiBcC9v{o)bJne$uLFoAI7?Gr>l?N^)#- z*FwU5ze5ao&URM^I8O9=&9DBp*fd9E#$)@w`>KpJuHyBI_xDYE1W zW&+m8=GGe-$d%`~Rdu~h&z|2m-$6UVaU9I1_k7H{#m3T+c0r?+sYB!l-^`Zkm-B_p zdU~0wYV52+UaEe=+Ck*AHyTbladc(D*&;h!LTm6b>0*Oa+0hXEy^MWN1vn`GzhqiT z1ZQvq>>hKv6Z>+`- zJjY*#Gp*^?k4?DEuI2dnZ(_yTzfHq8jYM}}AO7dWDs7`LBYScIHqH>!u2oBLa@4iP z#OUU*(Jmn`c+JIM9%Nmc7`0UUUThx=iqI4FpDLU<0REhEUF8?@tW|CY=@3Ks?Fw4cCOp(Dxu$CTG7| za_MvQZ!o@5)-%nvjC9K_8Zs_{RxaJV{$FKlpAHCVAsz+HU=Oh=Jqr0yY*oeRzg zfzT)&Q9Nqal4+qKEuGHDoiMON%sL6-j9%e=14dZ;Ca7~xCe1lMxxPGqL@gB)Py4tf zw*1NfVs-DaA(w7PImWqb!X=<`K|y!D0gf-7?%JuD!_qBSC{m`CC3`X#R!i&Z3i6st zekL9etZ!pX`~X#!s&2{9Kux9v=3l2|Fr4eD0=S6o1NgZP^fs$@?Uu!gMAFr;O03@N za32BU^{X*XT=`7H_NFWHp=po0pxk3wzL^=JU%6%dd@UD?Kz?RZlZy|Tm@~&m2PD$V zi2F5tFl~*ADhkq7Ucf(Tc0}wa4tx)3bW(cD!e=ngPZFF5e~^L=axl3sGisl$IO=_G zD!=90gsMR?Jx%*L*=HP2rqxriGh?+g3cJ+^ue6AhJXuRqIE_wXOAtXk&cHyZ+4Y(f3cPY&E_g%tmBJb zZ>+8erOvKV>wKAyDR++a@EMe2=`ZICF6X&BBU0xYgaY0#lu&(Bv+khMp{(gh?hO!{-i`vLImK=v+F8Nfr{K4ZZK#c^o3ib9rI!fTYKMCs1eDl8G6`P?nK1Xpz)9Sxo|Fn(NL6!TVgUjKBlO4n#xgiV97Q?^!RQ$AzYfR zXoaP(DHe1^mSoV3RaRn<1}i$`B8$2fE&&TJ3B20;P~(WOlj*RWXPH`+)5Giecb#+E z1m}l)dt|7wfjmzFJ@1%3E!aBX5PfjA9=%`gG41lzhtOS-@L?ckyq^8?>+3Hzzz+mD z%36}gtEr^xepHAI%K4a_26cf>=rMZtI3ehJ*#Sr>Mv<-Pd!a}8kSm(M$6kJE_ZzGN zp<~ORYgky<3-HFqKmR`Dy-?P-7lU_jz)&+8%of6O!&T+!H$Aojw+6b;;{3vzUEF(F zMmkdJXgPXns;ol@PHD3TI5JM{Ou#IhwGj=Z5RcE0wrkGdQ{Dp0+s{dey^u>+D-(H_ z005MoJhQVQZSmFl)ER!fhElGs7E3PIy5<{>TOW;}ExtOP$~i*alzYlIEz8|q;U*Xe zxIx3syB2Ginn%p%p&T>oX*k;F>b0AuT^Y~;{(PiN(qU{qLYJ^?RhI8mB;Yhj`W9Sr zbCZ-#^H|Y9J9;13oRE`kK$_|W@xbQyg7MM02F*sUF;Cc@QSNF@`EG{sqi{y>=)fnl zm*6dP{iVCp9q5hvY}me7APRaP@zhA+n_=dGJDfvi^oDU66HubZN`IM?JYo;AW7aXKr9Mat_FT!ngDfd|xUl@9Sai*-f`d$=ouH`?> zL{3iQCQ3!;&&=yZIbSQ?9J*Z3EX~$?O7v+giCN`eQ7;7%Yfew9AD=CH_3t{K;5794 z9&$2`T|>I}0BDtriCh*u1~gNq#J`!Ygr6Z{1-{k(sMJ)PQ&@trr6j3f*oqsUy4r8y zV^M=Q7YL>n`M8}kvSfq%{uQoa_lgb_&*(}jW(*U0)>w)r7FnvuEY{_@eSI@$_GJwl zUFO7%@Qv!$7?4_ZfuJPWEAT9uO%tCvUxC-u1A2?L6Y^(}Lf!@&oSR5|F4f zHyR%}npIJlV!HW(JVt66&W@dBE8GL_fP>%;$k_P>z1fPg9W+;up$iqN{c1|{UZr{a z6!IR$pq`$rv4Ya2r{3CnS3ePv))Rbqbpb|2mUZ0y_h!Ysm7B{gj{Qqlc&6M%8sfv> z6~1}5hb;5lV=|eKiWZTi*aSZTKP#%3T9AAEa^k4JEXbIzWX%=N3_K#e9%!Y2{=c>h zcnXAqN$H$8ANGK_rv>s(C?5NQFlkEaIKgfm*agLMinc$V>hQ0N=V+dnc}rQ()U{`o zffKX5PxFC6WODACE9uUT5#b*O@)KL8!%D}_>g6oer#(G*q`Ya=YWb`3-*o}2=scta z!5egsNKH3v51nwU9M6zU8PPsxurUEJLAy_rw5y|cU>kZys9(q4YI%PdSP>Oae;;rKOQ3sL-+eyD~klljkwCFKulmMn1~Qt7~T5PI1&`NU9nY zN;Ka!ZYeR7f1fn@gi=GfuQI}lQsJm{;t4()EXBquy@5p{y+bF>KjRVLiOxfGDP2L- z%Izw$;Z>P3d8#unM>leRefJyV^@E$|(oNGaCeONpaT9~C*{u#{4yG;jL-H?_;+mhz zTLGIl{hy&4E|$JB=Hm?t)Z`zenuY~enb{OrCD?~2Pe~qFl5SXTgIwFuhRvqZrm5|< zlNsw&9*A#V*K+N5(eVRq3`VREv%g7{pl##I82b1oS9#*_vug_fpy9!~%s=R-k8qB# zd_DxE3s^IDm8K-~wec4{Pp^$d1g|t^W;u^xsVyzUxl>;(za_S@*K3Ss(RDc$q8a;} z5$tfvX1pobt0C3dI~fhTzJ%6`a#hE08=$M3p6ScYXQa>jR@&>O%n>B_{;h9+^@}#K za2@-A>l~l92uloF`RZ`nGJzC#NWGI$Shx6*FhvJ%t}!x{=5!u%D~5bK(RHLYJIMp& zI(t*4C7X=UR^8-*mFp&P>|4o(vGz!jWIe%uqz=17pG-U65xc$N-RO+}pIGH^+M;1> zvRQ)nXGzexi9q>NFOS?Mrvb@AY$XVSay{cX2wWcKsLHXy2!-ALW^SM&NmSid@5dEk6LP*%Uf44)}uV%JoAJ=31X1uc~J_XS)pV$xA( zQBVJqJ+y);FO-y?r%)X-J|#mh?A@k007XkBqLj{Fo$Z9*Wu_^0Bmt?NwC&~(T*4Wf zg&#_1q$S8*@Luw1f1?Dye5LhLpewmtQYbE*0w;vycjU%c2D62?LTG7Njrx${axyj| z;E?*W#H7I{u}Q568%EZn=6$7h@^w0V zun2_`tZXRSn^I&46!UBS$!zWD)4RN-=urgDT3wncqW@Ne4<3)tB?rF#$Uc_lVk^PV zOZd|F*)DpS3X1jD+Yv!L=FJs<3_nk!01MDHiut%nDBy~Yl#5QKGL`}C$b z!ASLU)^R9F-1VrsN@WuYPrm!|y>J%P=D&ul5|2%M`sje8&ctK|JKN;H3PLyQmGVqI z`uQGd0Y^9vaV<8H{2_j*<1w2N##%Q+Z3*%lB(?TrQI~3$z8nJu$Sg$^4r!aSY#)gI zMs~3UcjS+y<-^TabwA}04-k2I+ky?DDkk-hK@nD>Q(Cx_)Mi$aI+?h0>XdVA;veoqoIdut9 ze>OulC+=Fx31o`F4dD*S z&$KBciy55xieW&~d6juwQ;j5gV9qH7`tHHOw(I zKDqjnFz6s`J{P$0MYge1iN-S2g02;5J>mqGZNSnd*zj1VW(8es=wyV6%wE9hXO}=1 z-sZ;N`it9q>QxZ-BfYXLx2BdX@JfZcflWMBwdwfWH(J9$Q z|4->+*f$y;@mRAgveW2bmtIAQpAjKkpRb7Vw|~--A`i~C^LyGzKzYu&EuGz!b-%g} z)9P?dw1h3S8ob&3-cdx54WmXEENG>j(Cj!2z3qXXm7b-um@7E={rs^4H)rJ5)nM z4L92C^nv&N-k;6v9L-(xWP!Bq=*ZxP7*uRx)JB(Mirbjds_E#k(FBH&RcPM)hLQw2 zVfJX)WJ-p;Aqe{{La57C&SG{7ayw!_;Rh%-L8b+o@H9dQ?0*2|K0kQyU8KF?>qb^HzWMu^;{8-}hOd`uSSsnfK=%3-ULIM_(Iq=Xo2svAC;WngQCa{|i0LD7fMG zkHVL$H#GmQbBIi6Q-Nk{Lzp^S6*kGrTlib7U2gej04-=Y$oFe4%+L; zVny_O5f+~Y>qu#=y%}z~F8qj(X=`(+k?0`3vG%;jm8CuM*oIw>|LlFWUXY> z-HUh~k0=ak9hI>*uRPD>)>V%A zX^-6Z9P%#PQ(lQdL@m5Z07C)p()f|aJ9cx%KJ?;%@H#e4iNhA%5=o##rt>XVr3!Ib zJInyzE6;)kMWi&+*5jJ*nvn(wd#ItyOND?irQz0j{ZB;nWHX!hRn5nkjUBE%?Qyv2B}w9bF^!`Y`dxt}oALD$A}L6kHj z0qve_nZllYgs#!O4>LF*V>QSWQ@AdG8Q$}^e2YwFmURw1^6z@Qk{Hlxyhmn2NozK{ zb+x=VB;?jhENjn*RSQh{ox}y}y7fpD`8X!hE_fhn;y_tb=;p7zg||5-F;&Vhi<0QX zSf6wA#k3C;tGJ-?W#P0!&9g7-gh`zWPl;0QA>a@fxFLv?=WQ0EWtNi;W%Hk3sIbtI z(gFXOW6%Xmx?`s@w8O!20*Q>PBMW!oNdZ!jy|dt=voR2l_jkg?4E{W`O_3YVtPfs1 zb}OxvI?%gkEFiveToR@6`I%{r%JKY!aeCI*WG1XxP3$&D4WrUXwYly8zq_ZWBCo^9 zm*$L5LpUI}$`NX-uB@@>(KZiP7Az*(h6a@Wis0S^9Qg@}P;PcY6 z!hj=vo#D4?Fyk@4Gc)f-I4%~Jmq#coAEcBdv=oKBC)`Nzo*dYR3ATW^QzU%|Cdczg z*NskffcNL1+Y}Ca2|`yv{ZpN+;FgMsnLj3GnVPIPds}OAWv}g49qpO5m`rmMy~^K5 zj@1;+9=&r%aID*krXY>cgCe>g?Z#EcWLQ+M1uHeiMJZ_$q*f!)8vUs;Cajm5-ctd> zKxHxvR*g{i1u1Xo8wg&IlPv$TRG*U`BHC10(MLlQ5V9_^RpF1n%A8V4MiwKYPvbrh zUCnF1)R?D0(`2b6S6I(%R^1T3IH2=^>AN^S#_R>3{0{62i) zYc|XDibVt4<`5QOQAnKb8Z=_zSh3F_l-3&{q@8a#9)31%7E|Mqkyn@H&UZGqV-%)l zTZFk`y0xQm-Rz$6#YI&Wv6=`rs=m>{G+a0Eo_3TY6@OGRnFNNBc z{$#h|Kg@!@2%aTRDQ$devJW(I>AWq$Lti(CT^ar3yUv}zKMgYybA89$H9>tQx<}r$ z39#CyW)|Rz7HSqzt3n;$tF|`=$ zwUo3f_kwgf#2V^R`lso9ZzZQwc3^4nDq8s|DwBJwAi$@fky1G^o>enL&nbCz%iTP3 z^H;iSKoC4;uB@2d)QdOOY_U_GBG^O!n>Zn*r?GDY*|o~!6^~WEBJ}@`%9=Px=>Xze z(4pOcpH{hvk(*SOK@8i(`K&ox#)~pPbnvXdac+6I&7Jo%-&Zy1GKa$Z&aVagDDnbK z&56pOMM?QF5BHfKeq?U`I6u*RNjMNt9o+x_QRb5qn!nN8Nx$`yNe>T-NNw67E;6S! zq3$StLg5TGOzIfiFg`fk?C~5DwrP+GR)Xp`(`1JIiU~+%a^%s132|FWGH>TrWdhCW^q@9+CvD0 zGOFS8ct*uA7_tbZ z*#~EMN9~!$Izd`ZjfW3f8lC90=j%#@`Wm>~>2oiZ>(8D0Kj}t!|2N$zNoFJGL9Wsy z`E#k(e7kJpCuw!@l<+QTC-H1qhhzs9p(h0-r8X2MDkH13C;MDoWX84C*c|7UaoPb zR#*BG2O{z)zxWf*OSRRKwg)g;67TAN*L@&u%dqN` zTb9kXwivd@7v61B5mMr@Q)?{JmwcLa` zq9AVk>k@hsSSF$ZXrj|nU$qUoik<33YpKu>2q|wz)>$TL_Tp>i-0FD?1QT)N@?4PV zPb1N0c5^}Ulj71x*=X>@hvE!u3(w?P4}bJ;O#B>us8XApdWjH0= ztI!iOZfBfCeVwH*EjP-2s4{(#JiP+Tw0=Fs-ZW#&exQN_#+Z^?M|161GkHuE3AI+U z9Ke@?n?j-!wRzw&wibM{To^xZmuUG8ICX$$E#Wv)j2rTr0Z4jWy$n3b*I86_L>&T{n(i&J=Iq)MYv5 z3rw~+MJ>c+VM^u~%Er~IcI<_BGlGfMfkDoO zKaq3bM)?d-Mod-m_0cb$FqS?BPNt_2~_ zlPA}G-Pe7U&sYC2IE^w&3(R|i0q0W1o^yY^=PA~WpRXbwW5@LE&K4y^gR6(f5`t(b_2W!V!B-)40W z;wka?HEDMS`&N|f(6GI8yK)~Z=Cj53^^j4=*|g2_o1q4w_H0y^Xr;qSWrGkp?J5l9 zt<-=it|9$>3{osxw#Xj1)a(K_t~U^q82PP4IYt0PXsVQ<9$P^=Jnzs8%0DrW7X;}i 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Ξ^~^ao1xidib=6E39imf09uX&Q|*5`eFSe zQpG(+4;tBWAKs*?@ZkK$EWKbb$2K!5-X!ox`J+w7t(Hk<8Y9rJl;8Dz(-|8Ac=OO# z)2HeSb=tXcdO@$&0uQ?~Iwrrzsy9 zIGIkmkq|B|R?(?;fO@NywafEL)MXTH`c0k4ntQ|MsN+|9pXuKN)@VieI@kgcmFPUW zy%y4tQoIrJ4G*?y2<<3fdS0VDNr3q*gxx%VY5tK>$c^$50~KU3YP&pB55R11{kA1& zjVz`G*s+tj%d^XqPUfDHXWao)#1}ak7)I7t=vH(N_eX&U*!qnpB(BUBSS(N$05ZDq z5Do+(yvxJX>E7kpDuPm9VB7?@FR2e#fmO-z{kuHBr9){a0GnN&n_7IJCLA;kv-)B0 zivOoSRSV$flHs2)oxhMmA$}m*;}Ue=xlJ zps@w7gA-RdOEer;9xQtA@@Qh&=V6QB&kSKZS{Uk8>I(OP2UwW6LAB$Y7z4}TQC#O; zp3h{i+}fPcE|1Y@3zTi{56)`A1%RJP!$#aV5(}JPZwe(-*v&m4Ck5M7vi)N<3~WSU z*X{D8VA*Cfy$Rfesu&EAIRn-+1|f__Olbl~9J4qM;`KJMq`%wH!Nxks_C>HP55Doy z6#>kekP-VjgqJiMNyV^@R#&*T5T+K+1iGz1p$J;OKiIFib`L{7$o&jmcLNy(L0q8; zX^?>?mjHz8i(q>An?TNN!W4yF1f?PLlQHYh>aD>=Is*k?11_0JK29=bwgZGBudwCo zukP}EF@rFVppA!bg z|902lX7QgHV9-AqAd{B%w+wKX=YMK}E&pb`D}UQ~|C7J{Ppud64_YtfAGKc6KW4p{ zzhJ!|F;tLRv$tCQdBffFd;eGay}cdm|CSwW@0Nea*hAch{Ke<4lH*>ukNJz-)bj8wa?eZjx&1_1L=K|NW{Sw%S5)lV)Os6+)K4X{X12_ZN){0}8 zawJU{Gfjw*QS!)foM)~_h``be)6}r1JWKz`(qoNIWm6_BOeJ7RzjZ|97GX)HXfkqS zU+9s2>ixJvU7-Fc^mLh??IrP; z63fr{$A)9iV@u|Ebx3-qgUO!~sf8c)v?d#*mmWnr!h;|6>lwYfcGeU> zEB5M-1ZUw{of{+liFkv`AGOS0148QY>l^Yi(+fq6mj~Kei^F}t&YR;@CHG> zFICai{<^F}`R-Mx;jek~Loe;qfA(F?F+*78p08LiIWansXzCV(3H1jhH4z6;jtmPd zQHHI>l*56Xe4w~b}VOZ;(>43t%xGA&GrLHF*PB6VE%iJ zoOiQ*{OKH-4yI0?dsKc*;f;gg`Aflnbz5KNq$On>Z{jzUyta0G zRJHxQjlasM_zm?>mf6x-PPTHWWY2DqD111%)hbl?Tl%^OxxwU>v-$Nl`b=Y%X>-Bk zfa+ zed+^|yP}UC?0f$_(O8@32k@W$NijUD&n)OOpBlu-+tAoRTs-t>IgS^IT(j(3{}T;; zvR(@Ow!nFjTiK4z4sAw*#TCf%CG$1YnyPGyWo2n~He8XKDw!N}Gms#nL?|!l_x9=y ztF?d=v`983ua4t2k^;{pJvD2$uc$SjUvkXZsg(3(g8s!I`!zMoYk_Xp9QIAvTZ#PCyyA5=AK2qlMys7+JB-XFxM6oV{x>?{B=6juKucjHout#-ixq<+@-K*-eQWVhPm}SKs zY?_#{8c>rd?+e%oE}n|iDXEaG0o6*&s;c{-RAK?T3I$N<@|8_pr0XRN-i zciyisGymq99$A(@JWiRj4I&z}=D5NA1Kowc-cTke1S)U2`2v`T)XU4T-v^fc{hkj{#>ip#J}emFR%F|si* zy6h+=N1{myG}W37*3quob{O;&r4RdTs2T=TmQ}$!s#Uyimg(?D(pIM@MpSU=o;lYN zoAC1T4>J%CNmSg_CVzR##2?@O$Ne9f;%PY}bEb7N?CXo%6X>_;;~~F;WvQdPJb%2Q zmh6bGBRH2GZS1(R2xk8-Pw#KF4uy#x8A#r=G8@oA%ZMc$wosaC(|1_2T9|<2&knmyq3Y@TEg1hYK zmnpUhhFSm;3jXW2@hr1P9%u<}kF+!ZW9;(KVM{oANwh9VFF3;X93lji#6U{Z+W6%{ zDTg{}!R(Vex=3rI28Q`7`g$aS4@fj(V#9q172V-3YFe1lrvg$N*;w5#X&*w8vyA)5 zt)hh{%1I~9Mx0`7+*Ya^T$ejcUimIgU=P}y>Mv2$GWYiHdDk$c=3r^g8ww54ZJgko zEgq|%AUEOo^a6tz-L04-xlHv|Ow5ENAja$lS-KS#ZDuBB)~%p=FQpkW3~$j@3!5Z3 z($0M?!P5H0nz`p<+6(}@$;y`k$30oSX8v!!Rpgd+tk*+ytZB=qSX~;P7=rlW(lD<~ zSKi<*QR{cKiC31feg#@<^GH3jQ~lI>j+IrR-Ohd;R-#>I=Dgc)zqO`&+P8NZD?Krx z$l;sNUxHwKXxVuR!%P`A9QH{J#GH4(a5?mHfrSTNQCA{rH-9N7KpIb=1p4ctB}nBq zv=XUDPs^R2p`7&ruiEdj<2OhR07E@%cvj zE4fHAxX|eHIur6DnHF(RfJJHF#Hn)Mnuy1^qc7SOU2~$EyR!FP%87b;vT@A?@&zSi zeYQ&((6o5rmtL-ojV#6MYj>RwmR44J6WMW}9QdTVs7&LF67_>{nTolxMnOc1#Chc4 z``+vy9maaMSTl6HHi`iI6eqskxd`P6(BI7qvXAtZEE7+9pwEHgAu}|w*m`IA7S7WV z#7V%YMK>r6WjP6pnNY9k6YMr5G7dMVz3j8-p=l{g6cwt#d@aJYWu#h&DsD&@!O3~y zA6tJ*7Y1^~(-_5=S8l;hNXLU#I%v;S+9jtt9cpHA_KyQCce=GP*#y+xWT~-W*;Ntk zv=~OF4t4N;6wO?oV9%)FEu*q8Yeo4z9zEYiJkxUh-WW;hhFY6jFw0e!H(R>cI$rZ0577=7cy%1^W5U9rDf%pu>FLExha^0|m7^tWu2BQoL)IHwL}a?qAeZ zCHd$?7ZRIrzWzxy=>pjeC4=^#(X=HR^^J1poe_?tNg&^deuEo`R6iNj^+7-}>$dr&lbLs7@$m_zwGqi&A$6LI8j^S8 ziJn2*DXt6-jINcN<477W-7Joh?TG@1U4oC5hFCRO;Zx|MuBYxa^>ipz=qb}ry2O! zHD}Mun;|z}nfg;z1ZCAAG6BLX(-;7{-JSQw%$-s&+aj z?a7i}&~fs)m+oQql`=xHcbPVdwB(#)eUede!K&9Y%$>?OS`n9=5c`?>O7@$AzAgyz z09&pd*{xZSHPAZa-{g+aL>{wXc}tuMzDsV(leYBlV3cQAp-0}rClbIaepOmRAVms} zDd)Zdi6haZa<{7ZT%dDDPwNxpg@jrPT^9I}MjCFVH)D>X3=YR_nDMF~>!i*hgqr2= z^=m>-&WB{Z#QLz=z>*(c}=tq)3Z z8*R$;*`Kv>>e-f&tri#Z6XF$rMi&}J!fx<8syDl(Fts-nZQ_)T)&xW@Ihn(w>5nhN zvwXuZX*D~Y1*{{V^j{JoYjclhYn^E&Uu?c_dypz?^MKRfQ2lx19o^IQT~8yvUGcih z6r;*;fX=B57)|ThxLXNf*p`ee+|g3cn;=wwsOF^TT{s}|JnQ#+5%JCQKfhS}vZK*= zC{jn-;2|uY=Hw#ka>5RO+C{3dQ-d>wpj_ogrI&Rbj{k_VOdYA9FVcgBBu?Tdp2pRw=3?vw@Ryn%;u58 z1QsU$Rv7ZX3ef^m_8(udhzp@KaiEQqBYI*q=qdGhlw%GOLxY0~kotm*wAgh_grMvI zCGH`kIG-*RO0InvvP?q24~H)mTWu8w6nclO*;Pd>tNhI0gAM2(n>RK}RJ&sphZnQ< zSW_stoP&mYc6PuEt41W5aW6ZtsUjVy=} za3EWp*-w(V;4VmbzIj<+vt8;{VQ*fd#oP`8J>=LS!Xd0eq7Z^)&a zUo;s?9?woIeF@S%I^eIp>^OP#0u1*__eNU|4iv920z&Dd&|k`CZL=>kaZMJ$Z8u;6 z51W8*63;RO!t2c*si_s|1=BDRFt6I>64xBhzWKpgY^;jrvn!_cFBQ@UzNR>&TrG3z z3G|^$WM;R|f%x;uoVUc(mz4uCMV?L4oen~*r_)cSS!oTusi{dx2!qg$H!GxaZW2Aq zouvzi=K>d-Fp(2_walu;j6<*8isv@<6{`W?0^BL2teWe58TG|+cl%Hlv#XW=jW}Q+J%lG z_=eYzz6^6?DgPHVFIyY1rq5}BVn5=<5rR()l#?>|cu=D{`KcNo2JQ!n|vD6L7Ke@F8^|Z#j zj3PUlYDsOOI8hIn*gEF03re3+)m(==0jM{%IUMh&h|dCKZWp|Nh7wQ-AC zb>WDv>?1;6!ZV-Y?W<1ixBkYE|24m_vK8d9>X`ALQ;N@B)VQuKdii2aioL`6SIe$v zOG{m!{QQ&B4_ih%GN|joL1ru~5+jJxsAXWEmkUI=>|44B!Z$ra$1 zhA9aGqJ~dQQ{ zZpA>#1)@P+%?lpTlZ$9Ilt>@?AX}a>FcTw21%(>@=q!+WtDjd)Q-O<;$k+(9Qb^Q50dW9C~PJQs5{6wvPpcX{ z#gGfv>VO<3pDh#iyqqK1h?WVXu0$Dy(HIl)j1{V8kpl~xzW}yht(5ca;7)issL;$z zU6{uF*TjU_XrRihri{mx?fJ6(2p!_)daH#;<#i@h z4OUG)tDUd2i^%Zy`JVDJoNW$tFkzF31mbyQ6>TU=pI_}cjS{xY!=t8J!B-NMF8^Y~ z;sjfI0HH#>ItCvB#o=c2hR~-yVS?y$&TwhbBwA;5#WMl&1f)mQ%tqDcp`BCmTz`c2 zwY&9RHa*wcm0~w-t$i-}zA)>nv+|xL_|@cF2`0bSwr@%rG*Kl3X-{IG%q02F47SS$ z=DKeLg>hBkl_Z7*M38ObEKe7iE_jQ)M7t>}Z5MxzY1iz1z3(>ja>LtuKw1;*WT3@S zgMtNVY0)F;GvO##0#bj$1#FtS%*Sub?X&N{5AVEj)Y?MyO^Bz-6U6w`3qRxP&%EZn zq&kIG+vy&Ajhx&^T!Nyk^{uXv3G>dvR@*vbxF{X%^0K{SvIGkiBFcF&K(Q}}?&j`T z2ht+-EeZ{|f~Uv)IQ75dK$ zQ3iv0#&iT9%J{`X(?~@`RU_^Yu+v=YoKg~lQpXd2<(^5uszkdgj;OzpHd%q*WZ*6ihY_Geg&zAid z3O7D8R6*KDrgqxdu6cXUq_S2$m(N57Ka5BE@+y`0t3Dizy^DAIk~E)OT)U-JGjy%J zH#TdfxD-gAMiG_@<1_k}^Izo(B`47*1Y?7l=1% zCUA9e+twod@3yTu0-s@kTsJ#uW%Lram!FB<<*|kx8JeURt!yF$cX<{Ud`qUV(0U>c zv#PbNwaYW2gak7K@4l^VY?Gcs!(MQTe~;6z`XP8Pw?pSxsQttqF1hB}?s= zMB3f`DIJTgx5>E&uf6)sY0rJBE4 zh{im9o9rsvaV{5Um;_7M00aSOBl-joN*&i~(%;V@KA)uUc`&vlU|7_J+Bk!qA19HAdzR-c-cp(4?(h1To>oPY|`TE^8k3x0ul5OJfxP5uwfU`!QdFK-5I)%J~MIQs~sc^_4 z1=8Ym4rVs1Rl^Z|SZawex(bhRFo6s=oJwF=s%;#x}jJW(ZSYh%dtqYm? zG~7A88NSQ&{SKp>6C0w%%}{+`xXUA01Pt_}PtE%pZyor>+!yxMsW)E1 z@3ZCR`^O`s#?fuI#iZK3&qZ4~;-Tf6#-sEV4*C#Y+%ku^Uf(jd*!QA7icdQg> zHU>By%K{5_i4fp`p)r-jcSEv6E#mhU;ak1N=hD4j7)hK_Szi8n@TSed*S}5j7`O6E z_vWvG^Bntr4b{c83$PEJ&5x{CRXX=-R#*7dAMcreql zaw(W;6b?1Pbwk<5uPuTV$8%7|5$u2XJUJtGxxrx8-%r5ZV(Z6Uo?mW4sbY*F4&Sys zmv@l_wEWAR@Bf!O-v_?t2q}^@3+sV0?A$;OoWj36k+9)D?k&vZNdds%PXX@h+-MMZ zSEtUsU{qefUfbpQ^j*3Ow|WDNZK5zu>eP~Lv2_c!$S{T(a}{qfgX11P^RJKe2KOX} zAM=&;7BgAgvC9)@xuk^A1KZAZ4wvP#e+A#^EM)IV>^+G+o7h_&dw$}dHlaO_xwm)h z?V@|}#9n0ezb?kSXu$`-J1{{0x`j=@zlGGV08_4kz_DGP zZ&f*%x#E!&3=Pybl(OI`rrhw-Pu}IZv6{v`S_a17JFG9eJmq1i`@1~-Lrt21R?iM+ zw3)P{I|kpn-@T%qPhrP%!DI^9CwLq)e_4-%E*Vdl{IduH{R@=&fBfk5_qHYeQ$K?W z`m3}C5KmVhxkPViYoYKVNi_FG%N;E*m*b2-GrAINCFX$<{W8zcB9saP+dPh-L0bfl zIJD%?<4)=E<42K^tGz2tPo)(^x7|{(tT>{;(CE@}Vv0hOu&0vGh2|l1lR%j-gl+`| z>maYptd!hALW6CLo~9GtDqlBw*2>rX#M6*Q<1V;4a>PuVV(QX0BR{Dg1D?_Jc~M4; z?ihVxz@nMR!}%3`0T7~_e`It}jap%XPRJz3gnOVwuzw3iR0ApjsFSZe8YBv`^@lQU zRFz>rRdFvhgpO-ja(gSk>Z!H%Dm0)HRLSo4gJvlY=8a9IGN*K&DiOsEMP!U1zujpZ zc#`~f?sK`~fR9iBUPK$O=6$#R%cvAg`E%Lr4uJ!MLMmT;%M~9;X3E+feL;xM%XF1h zuu3kFRZuL@ZXbPx?*J3ahe?kqBZ)&?aY!?y9E#OHIDyjQlm(a~^-j{D;g=`0di9JL z3vCi5m?&Wz z923~*3VcpDfi#QDT#F;ccs&G)Nc!!J`fH|G=5IxXQpuByln?jbYscA2kUq42EflBX z^^Hw(PrGg%J`TjUfhnXrz9{D~s@H3+sOo!dDy>i0{wn%f3SSn!Z(NE~gPd=Aq+MjD z=geEKV259NQbD6ST$nM>Or~2?)!8CqjXl7AR!EPYaSq!apfaH}ELjo}?J!7~q+rqf zjQB+tiGIDnLf~?TLp4K@$!V;v-*L%a(8B8N528z%D@*EV>iitxhO~B(-`0NA+pWDK zo<^&74MX~4wPW%HCKh0Tz)s$w0)B*=*z@iT_25%B8G z9A>1pEmG4PJ#;6{zE7r?&hPmS`Ev6oY|~)KFOJ3=xxx3+3*ee?OT)mPv! z)&KS*qe$9g`GXHGRrk=w>;&i+pteoZ+D`l?=bIk5MWwv|+A&Mde{J(7Ub%^JF1yZXjDO&O^DcFs?8>@=%uB z;#9O%vi)?e09)kJB)ZCz02hM@a5a&Lre2gTSp6`fy2t5ROmd*Nz^+~dFZ)bcO+U(0 zoy=DgIGsw{9x|^;vaa~ZJSQ!kzF^k5El^sJNW@C6`_NBIImro%&m5tzDY%d6kTXqF z+=dA#7iiceHKjuHNNee{_+x@`3jNJCFQxI1iTA!)H*={IIa3L-5zOw$3+J0@^2tm& zzWpjVz3z*8WT`Yu@+6S+1G#_7@nWj6)jgu;K)&Jeaz)o4!!l>N8)^n!Az=QPy5obC zVZ}2iDj3t<)Dm!fJR)21Bj8U>h}}MjZ7JdVhV-(KWS?g`FU*A?;`J_wWLFeg$R%oe zjGAS7S$b}o`oB6YXjr_kTK{a4<@-rTO#n)0)>CeN?TrHI3REX=AF(fmk50A&u_`&I z&1Dq6xY-?z4EMF*la0a-%(!IaE>Gw7TfCWE5xUrQq4R>yRh5h=Kb1fg+`(pT6CLiM z)T7hEa{7gDZd`0sx>s~FOQ6W0C#^DGynuZn`ED+P`;8=BZ?~hzhB5?V^?uCrkRX6= z6RnFn3%FtqNBvH!F2~+rZbs93DndI9`YQM@-yKjTI1zCwWv1}c6wMa=X93mfdWFf% zvX^UPE6Sa|r^YmoRfTEiN4>N7LH9&~o{w>wsaOQwX6TKJI=|K13S`rT0tHXrS0Pz0 zXMJs<;TJOt&v(q;zaZi}W=Y9S5IPzxj=d{Uh$f#y>+_z z#jQe9U}z`Mi91q7DU+SX?|`6$Ce2*b}l-QqNauC zH*5Qx&dJ1h*u?o6*xKtcHFGTHnS^7Ak8x=g)?V(dcW5wScbbh0Z-L`;H2#Jh+1JeJ z_QkQS2X2W&-AYq9%kXTkxuVWHc*UJytL>7CM0971Hbfm6#^nuS{^1Gx!9C$FD1t5q ziP2Z!6lxGcK@7KG{RQSF2gX23{-*>He#xdv3ES6HbrJrj&hTc@(3d%B)z7DlmkDnx zUJ93DdOkpnT==(#B(LA|(We=ZgAtL)B2j1Z@c+l&dqp+5zu&&P)P;1B-fi>}>BW$& zB?1Bh(mPQR5RgtFKuDJK7Fbf17Li^fCDcHKP?RcNia-(p>4^$N2w5k;G4?p)jD7aS zKKuN~-Z$$egNx*baIJA4~ z&yOa7X*Y$Y^CpYMn0i_P;VohW|2spEZbj1~>jgZdCBK1<^fNU|x?EL@pG9vzSK?Z< z$;L2q8#Cp@(4c}72hjppkKcTC!7&y18C-}Mw?^8@)A`)sM4A|KauGJcLu-zK1*EDL zigP52X0HW;cb-xm;H#o(!ydQ=hzP;+tn1iHR@sH!AS6u=&`Thr^a;8~FM5<|iG2tOnh_C_zM@I%D5F8lvWRVeG5BGG_nr8D zPSF97!i+z3DcY^qYf3$0FQI@76;xx4ym3n)cxfmoh-F;=+t~o}^NgC99klN=$Asj7 zaNh48Vt|yF81ApZjmFAh6pemxvD^c}TSP;NGD{j%v&UK;Ms zS*7!(#1ZXS!M}RH3Q5S0(qg$^y!rmT_Qq&1&d@J$$bH9xU(7&C5hU^ONTqMQrKY8X zMQA+eYYR6`KCd^beBK`jrL>Xpy=PiRG~Rl~)XJnM9d;nQGDYcUWTdtDPhZj^#45q8zff?%Aq^t(i1vGfWMcDk zbL9$1|Em=36k4IQyZkSNM6pP*D~E=C8fHx1&&k2tJ|>&INd$%xhtZD3-Y=>4T$2P! zk4&2P+<4P6NJ3~d9p$86_2jnOh^QNM+r8Y4o!#KB24H_4#i}73#k{FDpL)SH&T2iW zD_KM{-T?$B6-h{>d@Yuz1fT>7s5&Qa1mInPHD$ax07|sD0xP)J)i|rkA3yl;9zch0NZwCwyvbR`oIc zeK0XMElyoqBI_5!u3E#OBWQJ>-_3PE3WQ=M8~~Ds%h19pUhgG&SP~BLOM<VquZ9CTB2Rns>WhB(r$ zpXz&qIpJK3&ttqfQ7s4&+-vB4K^VSUAr$_$OVol7cZ(>&GYq#F^tdv5(>acY?t@p# zoeZklzI|8d{{B_*^>Mo!%B*%(KSUnFyj#0bqSG$(9UuuBsvmBOTGQ3Zrud_;d_`Q_ z5KbwHM=6lBLsB1Sc{HSM_-DJv_}Qg&)>?LEY z>(nrD+9VJvT^gn2Qg)PPZ6-pD)5Hk>*#$F`H_zuw>23b;F;q+Xo8k1zx=UdKo1$N(Y3|z--caJ^Rlza zUaI`P927QF7~w9bFgSk3J9m~jH~D=+7%>aMa{mSPLY}AlQE9Xbl<&t*6s7r8Y06PI zkvsYL1dXB_SNrIqHe(qQTe|!iX|_EguB$LGgXgp;pkG3oDwyg%g)^-isRU)VMw-p` zAG7hvIE9k;JhQVSvfpG26ix@^ge=-OnFyMkeBqJDx|^%zHKWL5o@L7gGeS zdlKkQRzR^6jZ#7}yk<;8NJhpUPLiz0w+tI{?wIro_<3;o+0^F@w#D(q-|^6D-?88m zyGernqIuR)W|6#g_Ai$wg(UL+P`;9E*<$cKjf0@-FW$l4PID#jW2K6J&iOjHPE>4brgc1#GfaC^I-0#!IdVtG zaIe8$YJbG{i_?6wam9MQNM=>}*vS6aAa&AYZa$~OM7PVywV@&3@?^VX>_5hc|8A*% zK2uH6|3iYkjpzN@oCj%qIe(1bl?(nY;Rzpa?lq1{CW(y!fgvGttLSC;V@en4V5l0Q zw@AN1tM#MQ+WNT@!>XwYu2T%51sDpz_JU%Pe=G6Z=Cu~Y~7X9Mp zC+XBO3Fna-IEaIurs}bg??*-WoyeGHmQQen&dl%@)!V8sm-9a*4^Npz&25?%)V+(_ zjxsm?erI6pJLEXBT(7IYZ|3E@Lqh4gz0+>ru$W%?zMz6&yqb6PW8w zSS867omi&ln&A)!)jkHNe$Pbz}Ig@Bq~`&tER?a%COv(sLOr=5vuP`OcuE zZ#c+lFiqh-v(OA@M49iGLG((LqS`Yvb1dJy2J{Em zju$oR_vYiVX2^S!EfC)FLQJ`jRp}q!U-k_@w6=~%%V-Vk%V*>&o6k+s?fi!7T>oBA zN_$EoYIsN&7a!l~YU-ZLYxd1`73mBrUK0!%3FJ zdi7{i`?EIvJ(mS|EYnH%J z5+JGJ62H+BOWFNcoaXl7=aFv=wEB6Z6OJ3r$`_uU_#GbR)`nMgzs$PZF|A=*4{&Vi zY@B(H`T7o*PHGC>v$Wof?J_n4hq$$c`Fyc%Hs4wtOhIgd65arwm7Wgt%8fTT$(%=zhy( zaK4*4?Dn$lq`Klnu5RV!>eei7U(TJ{rDU0DY0C!dbY{FZkR8dh9T{E9GL{mI`r`WR zX(LZ~i}XfW>4&-{e`S*~Ez#hLrJmeo?3k<85s89H0^TWiqd|y*g8^4yWCv#Mtsjy& zhiCO`;pSd||IyY%vsAZZ=*?-E`dRlM=}KpnJPWrM$n}Fp*Bj}rAD+eMO6R@o>;r6M54tlAqSo+=8}-lw+f5 z2pdS6=0%nv9B|N$DN&Gr&OM?PPmz41qMe3awd|(@LQhY-Z#qt5QJ{bohwT#yY~{8H zsQTFeJ@r%}Y0j9(c1h&#&`nuWSWkialy`lL&lsYs;I2=Q6>9giR>R9Pe{M{}6Lb9e zCo6dNBZG|mCSC5|ZE5ts#k2K4&l>yRqg2AVPwygz(N_<5GEg9uvm%7F15CdkFHRR{ z68KW^T#Repm z>qooV)b>Vc&nBvtOUZ|%wvZ1()DQNDm3BO{TqRobG@R5BQ#O?&@-JJ+QZUmm>lQc< zUxj-0IaTZ^I1$~L*DoGGC>Ft;m4X!YNnn239ijx5f+6DLn928@GN$j`I)IdsXa(1x zawqu-J`AS{X5b!I!4MH^1R%??doV zWa1E#%VtFPwQ{QBVtD)$ErbG9935YQn^I&ZE_}2SrdAkxr52iAVQ1(xTzCnZsEy$! zfF!@d`IE`Z!@`Lo8=qY!)W<^}e7`b^$F4xweq|RaHlMdwMJd|)2(hW>I8K%oSjM?a zj?f@|y1z7K5^KG1UIjshl5v4*y@9RH&gcIcZrZJ|?q%Be>s-FAb<~iV=Q)?3a(09E zRa=8)Uoo2N;G0Zr;Z?9HGfr#~i@a2M_6C|uf%Ks-F2R(Tay)_ut~CeL2QSbe(WEvi z_%FJ16gOQ8$ws$@wT+dz`RHvjDH)4=tia@o zF?9-Tw?!Yg#lC-!cMY73xUqxh#~GXg7aX45-qPJn1Dd^+eu-K1=>esyQ(ZS>G$KCv z%&&0#&8|>zh+6LqSY=9|oCUB+eISu8A*rzj5+4j|fc(8i^Ey8S^(B|5^m;gksXEkg zx@a1H{XXnCF2KD#6B0W6%re-r48vl&qk6#Zv#v8P-3l2Lo)e7^>KIf24F;lgh3Cy=)0$8s8HRY&h-V(gVNnP}%Ms8h%$^@{?7)wZm+q%9V1bb1f2Per}}3Q|hR z;6CuekG@5G0#JdC&OeFJ@)qooq)JyU*2mc`CT3t$#eX~e>8Ba(?<_Rcd(TX$-x-AA z{h2dhA=3Pu<+rDfcF+Q<)@7=Z7*j7DQY#?QAuOaS@;f1qgnBvR_XkRFs1RA@N^i|n z4l+W+OBjC0{ack0+xJ~BAOmqP&Y4-~x3$i;HDsVmu;_fMWfE_*KP6+DKuB~(w7 zILH@zBkX^h`WQs3i7>p{!_M*=7wt0V7*m>B1iZTutlA(_tDLS?Z9zKmb}dc zKNqP7cyVNb*GA>O~mNrxoAAlH@**9aB9pph}I6zxMBx$!*OQe0i&l zch9k0mYq3}HjHd>#*9MviL@*Nb7?b7!(4h#dtmO;o~1q9Q*Zr(!hI>G-+EyE=hhQ> zAVjU!ExTOk&(oKi$1>bwc`={st`bic1VzZIX@tZ^7yG1=bOvE0gxk*|RpsRXscNQ= zEN>Ers2|zgvN5qj56M>U7fPn!*V0!w=Ya}qc` z?pgzXPSrS013o4z2@)39>mpeQ7y-^GYn-lUGtpNaH~q6Tpu%b7N~?3iQPXO_+-+ttgC_4TE8GPgtXU@MSD30k0l3D9IHKPha5~>xCGe!eH1I@IFs_@7G z+o~$kZS@={7{W=VFd}08r^R3RM@UY%CIvYN;YRbgz|ERz)u#YD;H*%Cn;n+E00fl# z=tBB35>7S=r@jTYH?^XTNqu;1G`f!PGvj5|LVGJvoQNkrr zOK`gxBq{l6^c}y1drC<%$^TlfSB{)jAE`941ac~0!EeM-X~i?>=e$s{jOdc5R9?#R zpc}=VeEm@qad7b|T-^RbT1@Z5TK(%E8y#(Ata%f2oM!MX?n%KI*}DPk-5OROE!I|J z&=lqo7sXsz!Hq~~T1S;x11A82%~|Flcp;pS%eX~Dui=vsvdyMw-e)JpiO{tUAQLRk z?rkR_K#9&xy_jpyP-??dA;|$NT669(UmjdROb;-?f#FGMryL58`43$xx zM_KVBEckg_k1!Qr58#SUMbPUfzMhWt@Tapr!mcL5o{+nok7eX~A{fpDH?ANM6g4VK z9T~m7AipNR%oCfg1{?_~gh~NDMS4Ucp1%|J|2V&eyt~wbQz~~YG7IhBlPzu(LAcRixnvW?;$ZO=VOqU;JU>|os?TEl9Z!Z@oo}r zY9%Tac?FiqI61IxQ~i~%DDo8Hfy1X!z0wx!1>J9}j<&OD*VO_>v{ShgN7Vc^NxRY0oBIKB2{sYx&d8%n5$Hql_^n z0h(rT(bSIKBp$t^480GdWW?>ah-;BFR=SWR3tne@Dt?k~5&qWKsi(PNWx>G=u<+9q z^@QZ`s0-#d>Q-~|=Uq7X)gvnKe5O4Kw?wFhdA*{(9aGbFST@u*Wzj#MXX9wQ?J?8% z>VY!vB||LCU}jLC{qk@*zkK0J6vZ=WoVmpXdKF9)ciT`ULof+}+zaQe+4Z$@r5gak zW*gjj;@0d*n4|&o9AVQeR>gaTe9MnYzAzS)Oy{_xGEdB;rwcr z@hF#@M1R4!9SSzmaqy<7vd{<&qf}Ny^tL)#)~*FP?m6X%$&WF)yQ$kh$wDJbf68ZO z-zwzB*HV5QKK!o^sRHvzo9|Z>z~br?+*^{oKiR)TPV^PuNE|2@_X7`rlqoq!FG&hf z>}SfHP7}5i&u-$LrSg+^vw*!Ut@S@|52+nyM#LMJf774T4kWW@WXguqS(G`!)1B7v(2L^EVBH_85hk>&f7gB zucox+k0N+!2Mu&x3MLKC2_P`R+BY_PPh>LSTF6rK;~ixT(U&vw`_xh|LpguQrfb?C zn%z35=)d=58nuE_UxeaNd^LUfE;HHd!g7Nq{#@JRQ%&&6PV+_Q(%JNK9rL3qvanI6 z<@yGyt8B5QzI^wea~DH~$K1nrBV(dXtgi#&h1rw9>`AWct+sgk@nYm?R*^;ERwI?%e+rKQ56K% z2>(NI!xQ3qM-TpW+OyZQwR?Ow-juKft*7~aJ@hy0&~x_d`KaKigp!;78j_WjU2!1e z!T+|&ScyNcAfPrAc}afjtivGDwj38N4uzGnISj8$*5(cHl4%v>-cb1jL<4Cel4f7{2YSl4%V+ zuR&(;v!^|iKoDVur5?kg2y^*n6&V%J{$6zWytGiqbu6w?+gJCb)R^#6c5qg#RH%L` zHD%7i?jY>A^L}5B+_e9p&P+izhTWK{nU7)Qn@n>xjinZ~k-SKEPUk_!by^BTh(;!X znWrLdgfeWp7tPaioepZGBqkpA*3hPVn_*82#sK}D@%_5#sim;D^LS6N}{NoMX z3m#TKG+u~WZ19^`=uqGsv9#IPXsOhYxL>h+0F^r(J9zf3ezO*Ze1UJQOr@)wYWS{l zV*xx1vZP2X9MS^#P*+1xK=$o4#NBXtAqvPh|ZDOC6W#zW}wy1S|_B9Upw(!lbicMA- z2`3layTD1OAfNGZKCr8;5^CEJx!>NdN0Qd2 z=q65^t*<|7CQ1q)U@67PBr`Wy%NUDe*PJ?gG~3VvDt}3;Y0Rc^@|*VjSNZ-{DKSMd zY(cFphZQZ^2Js3r}Je@6`MD>-JPu8(+ey zEGsOR zJz=eK#@IMcz%2eB9>}J}8a!12nO@1r9{4Y`K>pA3i{~h7sL2? z@AW_Dynm-LeQ?#7IA2OY>G5e>GV%!8KL4G7UV&KPe~F%nGOd~XKxQOh=6S@)8Kg_H zx0k8wA^*Q%fB$Rw1vdYUU%))Q(yoI0s~IB5(}h2lEsMj7W zihp*8^N#r(++c0T?1>~h%#_&rqIQ5|F+8b92DZVN`aXXT+m*1fxIxgLY&k;?=;q)i z$9~V?uWS5*zbC83?PujSp6Vy3F(!wd;_2K7?+gzzncGk)@-?2W6tsG4+>&pJItq!t za~L)^cIOIR>kQK(ZZsr_zSN^j^MU*Y`H!^k!%zZUrT&ifuA_kmR<3-y-rhL}^rq~P z__5u^Ihb!EP*ltONqs}L?;Bd8L91!rjC#cS~$cQL-L4}-$9fo^@-va_i6v2(k`^ryws?UC-4 zhJ4tw+4RI3h%3QUtLoGymn7h6>nNP$bRu^87i=@W;oEV)-6Ch+iaOPv*)(>o^?@xI2?Z7-<==g1&$}`1^RQyat~_U>T`bzk#_rI^ zieO)BrG98yG+@xphi&{!*I_om<5LlrDaZZD#K>Kc6vaMecl9BK(G}o_^x`V@79Twd zP<7f4Yt^Fcb+i^=&9nR4xKlOEPuBP2#CML>_#bJAKhcjW^EQ5Y*y@YNR9m4OiQB`4 z3bMMdBC+4he{SEkue1wl$!#-}NH8n(!2Ox~SgjDvFXr!@QL#-_c^K~$RBvV;x}2>r zU2dmYq+`hZs$qM+YONTtpM6YE>;~PH47kipQ|(uhnE6{+DS^R3sYqp8_F+g-&6_K~ ziE!mz`0#gGXF`3=grEDf4E2`;Q47_?-20>lU2oe;a@KV!A~Fc;5t^>)W6eO9FF<8T zE>VFT)c(4vL;DlqafubyQFhSU=SoS(}>~gnV=}GjMGwAEE)sdA%7)D_pan>o9H-o@ol83F-?Pxl+Ru z>5t#|AS6DSq1wB;T|;cK_}mG@%<nmME&$7AC9PGzG^YWdyxi-313&8o-jaX!@?C7>Akk2x7N);6D({$Zz>u*8?V<5DK*W< z>So33W|MUce~&N{ptK^5gp)pMr%H`gc^tz|K68w)Bv-~}D3(WsTDIYcJM8=Rz} zt)bO2<%cP=QdB;88nZ~_oXdO=3x#@0h*24~uhw51di26AUyOw`Aa~Qc_+M_Q2fZ$= z9?Gw~tsOzkaWOMdpv`>igUasNsXQmJ4ARA4Jqr3&%#s2_3g&sh@rw?-Aio#2@$coj z?mBc*F}vUHmNNKFn&RXG%&m-@r~PpOYfF+>VaVQjX0YZElL~jN^vP#Bpwxou9P}}; zM3YH@$-^R3gQ>Ej0PG!cxq!NYhn>xBxuPoJ&%I#uZ^!UGAX>9NkKF9z=&xJhm}^gX z93s|NEP$gph?%R*Iy?XYu9oZu9yTh+d)zH@G=#d!7bbt#ko1YDaJCSR8>w-p1P*QR z`I2sH%aP=a_|r-fY*ucxio|Bty5(H5E2z~C%$EB>C~A0CWDrpqq;EH?sICXFn!`Hh zG*A7EVjr`%>Vm$Unj=`WW$u4ppSzW5=b%JnzD$0-e*d25bziu$NRJwCVlT0}v%SzY z(&4$DYTyFh?>ybKWpskEh}bqZ60mg z6j+*@8S(^sOaGj_^O-==N(U-X6?z$B)Z-Wp81~>Yt<3~GN7t((1Vs1>l$Wo($z0rG zR%ZI%*+Ht9KhO$mJ?8n_&f#UR?e2K+^O3}67ld))V~?0IRh-!a2{5Z}cFhQP^4niN z)=*iST0=O-d#YC3*jM-y0eK?a1&+bI#7BOClD&Vs zI*-)BM|q^IS=v2ALp>}`@bBjpaZY)57>@89@tgqE zl#@F*Q8cjJB(t33$0hlf#ZdEyRz)+kuq(ykg8R-4-p5u~`+Yq|vvo4;DS0V$9WtKd znS?qe0ppFKIS=R>BrrGU{=G$YSXW8ww)Fiz#%$UB`RD7zQ-$i zp30DiaDzYtyXr`g?K_8E@uxY@H5ItE%)8lARI_ciW>VAYE&o7OBd<$G-!Crpak zvwlEXO$GGaq=DuMh-)*UrmuGo3pfRx3mjavtZ`HRdksoZ1z&~Q|*KuevRnR?us2zhoEA7C4t3&N@H+`Quv0Sq0upK~JG? zac^}96PtS?lP=vE+q>A0zX})2_e$|-!bR);d?vW*aH?FVcqp`F(G?{pZR)#zDmI>X z>n8ZI(|3~`Ln2j*HLA^i{!7@js}+8@@2DjQ-NGz0MgyTy-WaHV=N1&BRlCi&L1Db` z_C_}BB*!V*OXjqW9d(I~GwPiVv5J z6dRHj%GTeSwG>Rcee_v<>(sPl8kX7V)a7&Jsu5stvK#0oM?0Vxy&q`+qd>ReDwIr^ zm%}7ZkEBVJNyn+YRgT5bQU*6|KB?9IceD z`oSDy=iI{e(ZW2%Tl-nfK1*f01s0||zFG3wWQ2F0rZ>o2%5!!qJW>g?&*N^I&E7vIL-OM$oL3{qfX!sRE&9h_sTr1Oy%;2uE4y^Dw z)b66<@YUG$LJwi(OmhH426On;>c7LhR96fA4_co2&Tp)6(MBj)BndnT%tqrT1^mTa zt3xi|e?m2kB_jF1MQ+r;xvzYyC8*}JcUzmF=94=gJezYWP<9F*%3EIMlC)6DHrs#7 znOsftpmZ3NodMPxP7cansubQ@c9(6FOqMQi>-y)MYpd?+Ran6v6hvw`3Bczw7b%hW zXf8FX#^>rUf!wj^h=58bR*!3YT7vUobB)v=X6n9!+ph*bF3Pnvq<(Z|Fq^J-HK**O zZU+DTe_ut+M#&EFa=_WeY35Rp<$p`s;QtV=ZG@(dAF}^mf&9&gmIEeO{BtfqH~+&Y zy3Sb{a{}!m;s-EGS|pZ%Q^_lESsIGO9<4w^?v|h4-P)_6nJkj~C9X0(F90H%rXPBc zqHCOLBGSL2O39vdg)32WMjT)jANMxeCb5=*91=x>x_=V}3#?<#zC@Z&g+ZM+0wb4l zA^j=G&yQx-YD$IevkzGBn4@f=HD!77`AuEf2v+9L@$-+d3rt@;2jW&nJTv^t`39Cp z!lZ|SW58l?-_r+lL?&m{Ab6=*je5M>OMM%TlV(;q_Dvh6j3|${Cyk5b%GWak&}iPLO7hL|BB9SF$8Tfh?W)RU2aB|))5>*c zJ@`Gs_WU92$#SRuViWF(@g|3re|xdE8$xBQ>K`=onDdqRd0AQKTUMIsh1&V9Y#_aA z#YIVO)l5UsWDPBANGtMIYrbo&@7Bdmmqn5VN8<)$Xa7!pDv=JJ;^i3xx@LOfbcP~u)qyM= zlce3YWEG*pVT=&dzWI7zQ2D((_24Gqk*bfwhnaqR2N~@rH{${eolt;{6`s=g{~%uy zi4CG-!OK75f@eW06Fz}+cce=6FIgmPKT>ftgChX!FPJt-PY-LZt?4(^YLhrBo2B14 z+d<};=Xz%1qrig3Q#JynK#lfpt^tI6B{Tw3Bfk~6Q7{>FapIX* z-^wjoGU#u`=TI;U+_x#qxS6thV_WJ}eTj7XVZBGvUAuNbvF*|erXxvlWQSTIuTHD) zIXC{jQ2AlI`=woqPOect`Q1Y9h3g4`B|E~#@^w4yn)Y9(I&Oh23=nKZqmTK?bM8S7 z4Qit*E!u9e)r66=py3}JhEIRct#TDE6s)&DH@qNPFu_r6Ri786B=>l0jZ|Zld$r?e zp5Piqk~-d#A+v&{c2-;cvrZpoEGi6!As2%Zv$C`X!00DdhJ@45e7BX)w{k zh_X&G$CJKjIxubml1h{PlvQ+Z;WMaQEZ0kk3|k3_UYKbLW%KOru&-A{E0{OWnq0+X zu@sgR&J1tr^C-(l(8J!Z!;&Vhoy3*xSoE*wfVHBkY`G zOHgQ5(|AM)tH<9%gIMlE=+g4A+wDU}+drGOlq6bZBVjApnUz_x>Id?ONMyocIE~p>%GSqeY932C0i=S7w*^{z#F}XLsRrT1 z?yLwa7vUnL$>{h09Nn>U1hqbxy-}PuESVTBd3on6EL|)YEJ-;0!J$e*AEv|L_o$z7 z&8Kp+wHfsTY{BKP+|axOI@`L?H3d)b8_{rmGjX@&pXPUBtV&OQtHi}DN2LG1=g-_ar|8ZwQtke6N^2{)62Xv=N_XnqTgTrS+RCqW0F zAF1%)PFJpQyc@blxBqhm*o~(1S(zyeihy^&ke2k6dNi2#P5o0NX8F9}5F}CJLTe(4 zi^-aBb{2Pj&_Xp^jcG9k90GX1F|N#G**WzePCj~vKXrPLeiU5B_3Q_S2pg?d4; zmRUk;qg{{!yP)}@T`ftiChNnymgamcr9HpHPjOXHgim$X%{QjRDW2o$j@6M>tjXID z6Su^)tAq`01jne{r+>~l21`hg72C8(X$A6eAOiX?E&hu!9nRdkl+BP|>mAtee;Aof{2o;WxjLqc~n9lTtvz8! zC~}&-EHQpkwwP8qF#%}*2~L7Ec?~Ezla5nCLJVf#4nO>H2`&7{dj@xhdei0;h}##< z@q}6#zmFA-_~#t)&#j)zRD1e06&O<){O6oIb_M{N5U*wawYaqW?BVtkR~v^B+KSo@ z>YW4%PANA?Fcq$mK~!(~lrIMCRDoW;6j^Pjwj6xS}$FmHDU7~h^#Aohu3Dn zfqgWO!FGnoT47tF?|Sh~SjcO#>Vx^@8tOgmO3oKUUi>>lr*||f3g3lp$!9kP5k6rI z9}fO$w~p0BBxkHKH2Q-!+17sS%MWdaQt8}-pT(4Y^PZ~H5H5NU{>58M`08f9Rs>NwNethz*ccO@QLb zquH1WoyRo*k^-Axa+jzWgdi<3%*tA=^ zpLE|yzXTsH=6LVjwx2{-g@wwr+v+^#6)if4YQg3q^t_g!=w>_6qaC!#9i)6y@Gm0n zIb~Tisej!@HX0%f3fN6!Pmsnw=khWM?arobJ1CmTMnBPj(={)o{ZLE<4Us}5fCP71 zR9`XIxT>xYJS;pm-e0=X^meuL67lTwhEP?fdNqk+TWV<&AAZ;=w(@Zhv*!vJfQZu) z$>wOP9+H_{CmjwA9xUub;@ns%_=KKYtMJP>+Jy}oi+#^5K)qYk2>qTL8qlD0wwZir zW}Gz;X_54%wY4=@L35_W6|R=S`Ltbv2SdP9IVj5tTvy0dLFNIkHpIaCD7hfKa(G-x zLV5B4iCioXz3q=u?BZm)m*a4Dzd_|~(smSqb^g{kYT?Zn}v!mHm1M=A_ zC;dDHxhIN&gU)I+GU8Tvn1@)5n4&HuX4R5Xn6Ft*^pgMxZ$r40>BbR$0*xg61<_RD zigb2^o^ZPq{CSFR{I{=E65Q|x`n;!DP(DR~MUOJi-v6tTb3+&mlF>?+R7(eNza|x1 z>VwPkrV8J^_6)gf7bm6Lkdl@?u>gEHvAtpSLG}|`XpLsAOy;n&9&$*F1x(zI$VYLs zEv-pNwEh+sBC??Oz~jCV&nplAP!Flg@~B$V9~o5q-v3T%cej% zTlS``iS9rP(gx;X*eXdFXDdl6wdZ!r;P^VT^AKYm>T6Za!6~H+^|rCBHZKz=%bKfX zJ2e~EN?O@(3@!f`(u`S#C0nImQnLmm*?%7V4!=%8l#?&RA!JToBU-uN8ybO7%t}>+ zum*)hkl7_UeL>PQp|$MM&I3Ho&M>q6Qk?0Smg(G~p5ce+rnxV9aB#DAaJ7_#LmT_R zuyV!ZhGkk2li}uU&sSitQddDLy|^ABbw|7M<56aCkbNHE+d+9|-r(vv=s}9xxw90U z!JB8ubIgP<+@y!LO0{Q7HoXwm?Ku&{?#eBvybNZ=SiZPg|FM9`J^N4I5?nOs@1@bz zkQE=E-pUnhf1USOU%5(MqP4!5SokX>n3D+<%H{j1kaL-?PSYZBg8R{240$^5SqnpGdzBxdvV~_q zL?+vTuhwJtw1y&4_&p`Q$n*@%A`C@`usToh8^ED_6hQLc<|pO)pJ(zDhRujqSo!9v z4llNL?<(t~6fS|Fvk`3mIyMK57bs3QyxLhQ;%A~(>81?jbNPiCJ!@z@by_)IN9_0o zm+k>*G8;uT-hU&eeq&O1dB5py4zc2#OW{xE7?P`Sg?1V?0s~Vcus3XLGA^_;xzlHw zBYkb1a5vu8S)5+kRwN+F+Ke%2s*ecRZ|G?B1G~4lcvp4$!0E|48V3PkXf-Q;%WmxH z9pY?v!=7&5W>DZJ&URHP(~jof66XIA{g(ej=>On)yQn42;}_`9dgZc*+TSibT!TOE ztC0S<>))Gpz}OICJCA-P+0>Q_5`{a^j)1Pjz27#8=tL%!lzRYu8SI6R52k~t;j!3w z%Juo5Q5j;epDkHXjvKNgQKgT*+W}ffyq_-t-2MM873elT4HR?)VM{mc3oQ zQ&?(M_lqdSMDV$b`s|kd`dS}eX*!abnzkJx^`S)2JX^;@a2VY!2eF78$pNLDv^}F) z>=_GGH^7F-j3V;sL`E?EK`iN@w*c^0F+atxvfmeK1W2rxrbste zBA;W@JZP!4uoueEZZ>C_ri=H{yRFm1QV$Vjwmg~U>OBvcOB$AP`%4>U4Q}^ZGTR1f z(rmkO3}md)#pq_s&GkT>|8DmjW^4lb1C^&K)`=dNNJeAd!o2jeNEpHwK@ubt?<1Lj zgT=O456> zAN_}tl({y->!XZ0pBHynPPwwjcpe>BU~2s1Y|{8%!MJT*2dPs2T`?BGKm1G7Y1()} z`#Y2V-R-RY9A{01vx zsQPfl%+-OOE0jED)nszk&Z2oGRf{kvu78iRky_&4lmC9gb9iQJ2Bkfyit}O~r@J;% zsxW2%@BQJxM1_a`_I@X*j`6~BITOunIX{qN@Ex0goN7b0oay}a7O2^`j0T((^}@g+ za`!w5BBW0_C5;wepM=X$c`c@JasgzBfG_%rhOa0$uW!C|K|Rf42y~sY47uX@DIl~& zG6^SDy946S8w_*1D!>$-%&b;e4!b_b+-dEC8@GzY!bWmcvDnn04a@!AbqXK`{wMX%rT$_8Dpxr*)#~guGvxOSoDkdp zlCCt%0QtIIn*mJVD6%HA!i=LDgxSl5EB+3k-TGwDTM?r)VV z{fmMhx-_L!?zswo|50O?in7TAx}RdfUSq@Szslu8DwV9EdU@FRU*d+lYfJ0FDOFSd z7klp+)#TQ%{o-;d0%8QDx3xq>y7U&3r6?>wKx*hLLAvx7AS5c%+mfoZEQJtSi1c1V zQHpdBP#}qbG)bfd3E{oh-e3h7DVAjXb% z_&Dp`z$&D}bTi&t%g(zXIJ`YG93O?0-5x&jTO0C5>%C)CnH&PTpj#^GpCXFP3n}RT ztT%G4xBQ>U!dD7&UwS>?DN3h+6KQ+8qyuCKjB1gN1& zuK<-uOC89&?2F?slUpHC689Vbyi8g2Jfwb{|EPNlD)Z(I^YiGGk)Xas@VK{IRqjy* zbl@wOfqvPw$?=k^++7pYX0t?Gojg0-@a|-r2GK|CE@dfhFDbZgV$X=Rf5>1Wc+;A( z(w>cWZa8Qdmp2tskoue+e(lZC=dVY3k&U5CBcB*h__cKXYw2^coO|`1@=bHQ&ZkU; z)u&8LzyutSv~@s#y!l@~x>45(Z8|%W#E1awK~eZqCZX38Ta0Cps{GNW=*dARJuu0z z_W1GcXrd@9gAd_FDHwPHk*4Vo7PTo+)7!B{0mLPa1@W&hWe;+o^TEg1$8XQ%PWX$* z00)$#wdan9mjcu{{A1lOZpH>Z3f0e@EOG*wh(0d;LK4&C0=YZp<{FPzu=RVF@08~} zFMPfw6^yT~(}}m5=3UOEzgmj%8OziAENO@AR0=nICx4KzJuw z(efJ5nK*;cq+Tk+G$fUJG599Ms@q#93Rl_s-{hM9D*I^GYRuS$tav9S|L|(msP!q+ zPCbCo%KUr$&-|DFX6hM=^5>6O%_;&KfYX2mVL)l_MA*jx|teTPV~*Lc}G zGes=K;Lqe{cmCT}b+1YD*?g5MLT-W_&w2^-52zMi#LdaoOpPxy(O4^?v4H&WSJ#_g z-FW9n^(=mGPK+an#x9))^A^*=06)$L)Gfj`#uy9!bXF(+mgkk(98QNNhv9FA;v*|3 zCm$yrmNs~6KQ1nQ91`!F?yc3*ia_Y~0);!CRa)h7f)dy*Adjq#o>BPlE@(Pa^0sp6 z#8U(1FJrF^6fn1AZkQM8=DQddsP{_>XvWYRK3m2%glTRg96=A|7A2`almi}Y{cd9()ZIC$4(55yO_C?E|Eu0yED+^ zZ4_;V2UxjG|4)7s<{#hjAKTr(&Cws@@jti!ALH>4_OKuGoKL%YYRsICqciW9+v)q}xI5lO-T;dZ$fm2MS($^GNowk!{6HF5zvG&pG#5FQy6 z6d4}k|Lx)Vze+rs#P3Mk$a`>{Ng)h#SdQJQ7;c*D1o_>%E{TzkB$`H zCtx;8Yfp>&Qy@MXrAx_)Q4Rl$Abo^u#6%}~&=TJ~2Dk>l#3KbP{?J%b? zVIC8ADSGyA0dM$!fdr?f4kWxamsWxE*7F_(jb z$D&9>Lu1NnA&G1}`QYgV7qf4M$~AYY`-HsMz^Q|Ye`TvPd;U%3++j%m8~o>Vkphx?16x7fL!`5is`5Fz?K3_7%1Qf|?5xYlwU$b~h!ev+^3 zG$cxc<}B(E<&Um_l>is>A`mxQ(&}XiG^_0BA<(@N2lmqM<|m**C))K|4@~ zaEQCqoo%jTolO)kLa>zXbCS~O`bn=l*SDTx(!F@q1hkP2%R#ZwMX82>4}>(zVxJ;m zOq<1cP~p+0Puc`4;Vtu%#x>Q36(F`v*zgu3OZ$0Ial6RSkm1#>O_^(&I;hH{k zk%MY}Mrvv7FiDH@HD0qA3Bk#v#t+FKb6XA)oQOUibscRVo6irUxgvc29R#4Hro*Lm3 zXh5@|U=dw96b5umB2B+7*Bt~3wX)@}y_B;|F3_(8Vmn=FBX*=@R#)HZjU`U+2itAe9qN|?N?nN4kvU#Cd+tkSNth50lI#mT9 z3&@$dl(n2LdqS>JK&hlG;drTo82}3Gz z=t6I1JM=<0oi}EN-+VNB;i^$+-m9U?6<8h9`FP z%T7M?;`ayoS$w~*AjF>aF7Lj-{ywNJmH!jso`*lfFuo$DB9|2SJrI*)G2&s`M;4Qk zGw)gfahoYi9@~g(sEgkJBHEZ12R5hb*Z_k44pxNU3{rp=MsjPUg!PJw?%~-zZF2|? zY$Qzo*Tyc7zxA zW<~qx!p}%TD9|4?{MjyAB~k*^tNt3uLg<0oRdDXg24?dK`6N9T&lmyfTM0;>A zr@AY-HD|C=)$Qb!2!JxHLkz`WMo2#9fMBv8#X?i+gA<9&fn!VzkJe^8r<1=*>s- z9-BhHCnPyuVyevGH@dE?Ial{l8qX{?W)So8eU+VVtUTL(d36s-dL^s6JX`G0zBU&v z9}`QR6vN%No~LW~h9m8g-l<1Jh{FUyy)&#rhEIttDhm9`{tDO>oE>}o_jWa)ixmad zD$||Tp1u(j>9j>Ye&m6wZ5C)&gfx}VbAaO9Mkw&oucO!y4yEsk zJQShkDY26^;E9q zrD*14grz4*lx8nprF2x6>j9s|3#3KUzRfG!E0Fp+D+LcrR`=4Gcd@1$jOAz^u-SE*@9v5MZW0JYEL8C7H8(n{yN`WKg*>Jc^BAl?^~L;lu@RBX~n zg)5C;hd%}L1iSM-hBfo^QI@`u8P?R0n0Aq|1m#!Rd1iYK{TTTR5>W69Go%r)lhC{2|x-eG1!FFWB$pn zk0!J-QFFDRpW!Cw`qVd?7xhS@=P08WDI%`@bn|pK>*Nfj5ru$mmp601TsRn0U;s5*y$=2s6)<-$u}wK~Qn#ROfA!`#Y338@u6v2=7UW zGtHEwrG4W|7#h@ZgD%}TP1o`x4QbzIdxcvUxkiy|F5Og%xKvBr9D;+}Zx30b@6E{I zi5@t>mWs8a%cr^!vmQZAUeLnju6J4Wo&;t`0{CBZwzNVUt7q#cCfqq|>Y988)*r8H zX6f(VuZYFQ_sqOfk(`dPR%bN!n33l#Yr!Ca$~b=G=$@&;pteN5WFdvUO*oB%e$wZg?pR#8mC?@upnPB=31pil1=DWP`zff+MYsgnj~d_B%2dse(;VKb*utN zd8^w0f?FLDQ#;EBNHk?sf+NScv)^SCQj%d-otl*`EK!0&7x3NydbD;97{=Sp1IT3x z^BEz$(r{B}{5RIQ3^4H{foqU# zTo)=H;2s_lil2VtSi2>j`m%CKuky3X|i_(56BE6 z`1^P^%?TLH01&J_ZFD1?^UY#Y!wOph9|iSnVxg{z#6C$b4QJiv{z zn0Ly=X4vz+KBL=}NDR=P{#sV1idTTTPS)*$LpR$Ef*&}|^>e%POZl=D=)&@yw@%(+ zTj!*GaQVqDnl(kkE5@8jXsv+2l)vW39qfGZU)zgTMW82`POnp@SadC(u$0_+xgHhm z$ULKhK5Ihqq-)Ffm?SWMX`{L))jI&mLH8*+PgK6D1C7jzM_MP@o4{yzRnvle^KOy5YCF~OG3VrypWShU)b>|FGzl5{YOl3U2FBe=r-@Mo)h8%?F4FWaBxivP=?hC?0^tanI!kil~d-0-O@@?!1H)EUEO)b3!)7!VrbGAP9 z$X5CK#dwB0xgy^#V)R(Od>06L+t-RGLhG9gTWn`1qr~K2fWwa;(jU~(*eMGK&&Kxw z?LcX#!!S}3;C#I(q% z=bB<}l-^8SI8^sIeNQH{h4qV;QEmiEWu=HWlfk)Jd@<<OCqyFiG@$_o^i`o6_8HgD8x!ZHj*4%dNs@8AK?oIO|!ni zC$}Bgy62zg^w?%&M3P&K_RH^1nq6tnse4)`8g*OF2kKRMRGhA_mo>k+NXsrC;k#|A zjlK5KsdaeD+;P+?RIPP&74}Ku>%Nf?ew+E&)w}RwG%55srIrX#26UG$wz*JtyF_GZ z7-4LjZySi{#|Iy^rbG`F+pmY^Ze!y^BBSJQQSUyV-S>eSW{=)(ox)k6rzjf!%L(Hx84zWrI_)%h%P)9T7cc4ppvv`lW*knR_cqJ`P@!p+*iB^BY4XHH7PN z5IhLDpQv=k3M}=UG6`1IbEowlwebo!G*Z6pz^Ercpga1aJ+0NcW)dvnN!m=i;?cnP zWxNuPrG#Qhvhv3DGmQ6OB9>))sFdh>L$dsNWAkY7_Bk{AvIf%Yt?iK^S^1d}{UHv% zcYQr}#`6PwpFOSYTYhlRr92=)2V zZ4Q;aj-SR<{4Ud?ttW%=my`v>ark(IPNlaRPm6I*$)GD7r@kES>O5R5$1<>`!A$)*Bk4+hLnXW|@eqT}P-ND>Jd(KngM>gW^%PC|_`fZ|3 z6yr6^xY~}kOkKO%K3Ot(y(W9r4h0Q+mOef8G)}B^b&CA3UG>eK-f~#`m?wEIY*aTiu4jBXH1e3-HL~6d|4*#P`-`LF z`G?O=nLgjAjGiP#s4?U<7ugJCiHpY@*RHUgr|j4^bLQ!3a}qTi1XIf}l*OWa9esM9oe zdYrhxzmo0v!G@HKf$`30lP8brTR%aD?PzH|j*63X4dKFiZrSTWF^>dIjES+LCy;xi!sbOgYlC<2^uK%O8>)si9A@#9=j7 z<_bYdF`8eEU=>gMbhr%)+?n}xGs=vmOfllpKGGPmB;l+9#i8nEYja1Xdf{Q|pScLz7+Xa=Fr94ipTGipU;pDB~YWvxuyd4&zb&(azP z5Pp}Jo3PB8{xBB*C`XOqvQ>N6mk+B)s2U|Gsqnai^6r^Fx4A-%2RFHfEfhlhUkJcG zEGrB$GAEunBYg;k9K=9-N1cRWctwJGdJgL!UVo^&%MY*Q+#jlePxZ(!&qzL~q4RKB z=R1Ho;SrY9`T))t4ddBNjMDJ_4(-|+VH*XMW33uICXpK? zIYmr2T^q<;gpO>ui`u?=5unPGB9NsxZ{yYF;%|*u%?5!7*LxCs&AQ#{6og(RsBUO_ zr#oJk@3JrA|MOv+f_Xv^HskZrBgN^sis-l1+)}ssHkwYEa6|>mZ-Xz|u%c#`!U9c| zE$zITEOK|DNXQ%!`awyDqSmVobEIGgL{kJLdVC^Ds?}5%hZFRciqB6=U7E8gAt&6* zKHkSLSkmpZ{;(?7`-p_bS8XU4zQUrQxf`~nW7$GVdpl{DVI`5-eI4L9WPrOCvx z5!B_>@iF~V?{g@fxXstP+w!AXlos%9&^eR zA5yAp_f9!V>bOr$07&LWR!RXN8KH0q|TKSD?TW-+qU*02UBA=X!;*biWr6Ig`H)U()N< zU}j%d2pV!VjHMt9Zf9!NGUSbDLqYALswtU$&qTZMJA(SIuyq{ zz{t_D_0G#3vT*lMdZvT9b)j0;+GsTVzud>&yr*m9G0^4{V zQuh`11Jvz##JGf_mZXwh_QUn=8eICO;EP~Cc0rD{xGqH_)o%TT9B$B5Sxq6!|4cVN z$%QCy&ab85+PwerQmD_)!+8{51$<+~ld$gDmZ<)}RB&weNoErvx^~u8dq)O(*BpX( z(^%oW9EPgP-(M_oNIS1Pf6HHrL)<0`@qi@CGF{$mTlGFrfL|naXffxR;#on=Dcz%> z1cHQ>#b(d9XGi6($g2S%tS`g3bXdAADEl{$Qf&$-FivM`cma5b#YWR2K>d*~EUw2n z@OvHB#@WB=1?dK?PRuN+CSL=XAx}NvqW38~z0Gt>Y8t7kotj5-?*lQ>om*)8&V?XK zXL6f7c`4=~M*#Iy1$d2Fl|o$9CA`X9rgnrV^=9+P zMM7Lrwm+8rk0!%7c#sy+z@FRIrph&Q)kcB?sLGN7zbo~{`f5nIv-daw_6i0(&xt`5 zPx6~;%pfU1{@l00Ch&$esj8PXX184>?r?q;w8>ZtGT{zv8{j1b zm%&}T)kS!Tx#5!p3hu@l7s1VXcn2hwH-$~uB}p)EuPA^^Abw{SHG z`BmQU3~}|rQ-XWFRKN~5sh0jd+!oi%En*|^;i9UggC!<t9rwRxvrZxm4%Y=~}Yk`B#eOH}b)As%ji5jk7z{N4ZJvnTSZs7;ZcG?77}Rm9|M? z{T=ZO`@3z1WJpLaT`SLjRa#=u|HGrDb6wT~ACke86+_<3JTYnGin)&V!~x=%RHQ}g#USW9ciRK48-&NZ=2 zDzP%tej4h|la(2@=;-PlIn&;_;=B1Uc}9fwQf}Z%&|21~g&8_tuVknwYA0xnag#CH zveU<|=g>5cRHfghg#k#ot{T9nf_=6Z>BkO_CfHUzk>0p%cOq&?HO?yQ2J+YpJu4hN zCpW)4i`H95WlOj6f3B&^mc&}!)YrV9m)uO27%oN^rYq@I zp14pG_X?ODUI*1DTDue7rcWUdJA3Z5P6v;&(&cA5xV#ocE*#{>Y*iyfrj;E`2)4)~ zRg6z?j>1RPXjkr&u~e;wqqTALwh-Kj!q9h1vENo}*Qe(XrosmInOT7~@D0%GWd?!P16u__X8N zml@3!eEce9CJ*m1n*><74|Z)BAF0=4qzyfJ8rk~}l7mOL4Zp07J3Hin#Z=1-k}_6} z@B65XxV3-5c(f}o9$)?<8}5DsNww6!QO_^E_zqY6Y5r?n{l_#9nk+>Q^eiH+H;rop zqE6N8O%p-bP;=cl2+Ja{0y6vj);mqnpTo*)g2L zzxiz)9xH4DzNL^fjtzNgXWtUXcAG1X7TxD~(}@>u(v|)FFtH7WcaRz1%-u;+)&?2R zRK1V$NO=84zeBbt!Z{qZ{CHEHjk|p0jwt1a%_B+)XJPfli-QZ%7 zQL?ln)SQ>G3K0FiH;W5rrCZe)%zKWEB6LrZfvTUdcjska<<6v2CJqGq@@V3s62-mO zBpwQ)Yx@v2_EP-%k*qlcAHUKCuZWIlROPxRDqfZ@`Pz<#|GmD|+sAr7oTB|~Vsy31 zS;Io!SSeHNMvu?nhGIvGgxjprijTviy+*05OYYLfrskQhH;QuuQ*dryr?;wbho6M1 zqK}#3h5(wFTX{5j-Xvjvhhqc6O2zk^By{jneEMU6U@@bn8H64+$#|ATy`Dxw$FmXN z(j7?B9IDMKjd2pQDhYzOYwRK=KeyL3q;M8WnMIdO82Dq2jdw#+v;vz39_}6DeEqI} zOt6OcdxiOBo9Cvys>ls9w#Ri09yVf{JrL(kQo*;D@pDTsT2uwRWT#6+i8|1WLy_d; zohNt+q8z~~TDO{Kd>>G9dSspDdEs7Bg8dK{%IssGJyB-+1=XyQmk%bZv5s~FSCpDz zmoYYmIfV*OpZSe2N6L96Wt9}KgiG(*eqXZE47T@dY9OtsN%&f&cl<0%}?Q zNtg(S$$1)=4K2VQ&5qjxF>Mqw*9qjrhJLftqOUDz>-1>@ z!ouix)S#?AZquj)mIY^<9%YxDil!=&O?m+vdP128lvCbE8I>Y1yAXnBrd60zC1NU- z(fkfWJ`Y}PL=@J#{`KWg0x3xps+SP_VTOOT>gpvUT~>=`$$>1aV2iiDIKKpUi)mnX zn$?0!%=y=O8Oc){2AfNs77=|7S@e0k4SZ-+1tpB=_=Ex@0%0uzaNixPsk+fieWk4% z^ZUcFh{eVV?}&EbE`hjJ<#nh^v9lX0-LyTZDD%p3Tby6~biEb6y`0E>$I&YztaL~HYbj-a^X^&={+)NHx`0xecnIXMNgM;hn7?wfTK4a1ql+|lSWcPVz9OQJ zdG`EHRP8Kb3~@i|)G5=%i~I9w80Z-N?=$M7Q>J&2lUnHZFH3x=eHBUyl6?<($`neK zXS{C|U|0to53L`bGKryzP$#dk(dh3fX;7z%Ll>GlppyZej{OTNENRjkn?R%d@+p(s zt&;cH-zl>N2gj`yR#u#w3qRjp?BCM-Q{TDo0{9%b7Io{muph0Iez;+mB{6{x*ZX!{ zx61hGu)Xrg0x1yL(1~u`Kdf~hp*qoNw8&GY^YcI@NwQql@TeTM%yG)J62sW7gB&sE zkvfm4ltTu4y*$I*)XQlE(Ec!`0eOa?#n8B=Uv?3&Qzi&R1Sn870E0N_^?!cBljHYe z$Dc*~5>J`d1_(OdSN#x3!Ir48eO^29aKV#CaERKIXATg1o(x! zhI21F7k+~y}48P+B`{@o5#)lS7#BWVBj$@rKJe_A5;Pnpf8L*eKXULG#W#De! z7~Q7f9#ra$RHUKE-oerDC+bdAC)UiT_MqJBi^5b$nkW0v2o@m3*n6?p%XDu`snPpJ#p!e_Liz;?vsw?tJlXPrUi$?n@564CKs;n-Knq^e6K z5z!t}wfC7=eC|q9vbZK~mSyCDXG^vH{zu982DxoGo{7kTwHgR`c~QLAs^_7QQHDET zzN#>3bF9mylq6+JkSsN5|9vvE*;8^*A;{<2=ZyMU`Ma-?W6-m7eM-#^85u)$=>lTq zjxU60CG8}H76SLp?$AFyX4BWdSLQ%|IsSd}m7U<1hjnPgh8Yo2;Jen^kb-?| z$hw0MY&2ovI(5XG*mN``pvFwW843@6m?HW!89>bHEgRp12=u~i6> zFmk@3(dW%=#lG+|D1sj(;Gc8l#P7tOBvYhieZjmeIoww@Rq{dE%t3kPrlvXinwO?Z z_`@x9Z2{h`D4Ie(=sL-P+=MrP&d_CPN0i0^hGI*!SxX~jHU{i~@z!iRnAhZ2(I?f_ z7TSnt{cJXC{MUuw#5Wt`0VI@IOknexy?!@X|M`mYS{w#UP#UDF-;so{rPDr zefds1yLJ0-IMCT%h!kU@lL>NuqflfVa+Cgm7DZWtQLPRrjJ&_i1?w#;tJsS{ecrO4 z?>pQ}*TeP&fq5o2%qy)p?2WE)+E-3oRr^4hjcW_&w|*3=6azQcCS8=X@xwbSwsmqO zVd64hNj=9%P9`N+4CYIisYf8DS1uR?L?^qdBi={$BP0milo!6gl7z6=dtIt1nL!tQ zgj5X1lQYH56!J4HELQjo>W(~h1CxcOFx+xUB<6nfGc+p>ArVQHAn84&b9jd8au*qr46zL%~qE=o6u@upg=H^#oYTT*UZ{xr!*OT8}CtxfOG&;DH&BfH71 zve;bbvOj9($O^$81Hwso5ie_mSU#y@x=b`eq2%+&5dD&u>-D?Xy8kWe;WIHIw8f7Rm?kG%wcpn;-!d$VmFetu?iQg0eG3jZ1iM^tDx~dglz*v4pG!e|2!I`@<&*RzT|`|FBSF?APdC2uFKI>!d8gsCam`!*Vq`pw!xN?rwSS z_QP4#+Fl8H!E@seHe2Vj^oHd0Z51cHw>rc0!%?4GFKn5F;AyRX7r68w`o5 zZL6D-mG#?_!|hc1`4C%c+Us()^6Xme;%B@g^StA2UKcLH3&dkRUKXXR!gQs&8m^Zu zS(ZnXv}AkyBYN03zn|!EngUg;7kQPEMi@<4WTm1L+O9h>IEA?gE&H)pRLQllKx;$g zHw*Vx?cnmH?0(Y5hY`PX8!E*U;$7c1Rt$!#9kHO{Ez2bqMKYTe#zhMza3VRSF;o$(w7V28BG97~JP4aaio(%Expu0w@i-k?<^U)6+g>|F{%R-B3bgO6 z25hLJNqe7o7Ide!xA)uKytQy&I;Yi>cY40ceE*Fcz?a|2Mwk<2rlPM<8#w}u)O3~W-Q$>`e`_+^0 zyt15!*!_jL0!$9kXaEGXw1uMX9E8&_ygf-nqEDTKApCZWLDJ#C0HONJ_qb?;Hfd;y z*&9Gt?fFPMQbl7B50+23NNEWOkao%dAoD(7L2{c2c5wd4iz*%nKpOViTN3>e^En0( zYI4_$?2^^B;=SOR>kpHJs1{0(kT!a%UCRnD+Kk!chifVq_zB_20M@BD>ioo-{e(Uu zwip4HV0U{daS4E+?r{5OhhI#@$qAAkr^C)aUygM8897#{dXn2oECi4h z_olX$jZC%+d8wk&A?)%-8GY4oZui7dW2)!GRnC!+Al6ZEqvFB`q(0eEFs|kibKKGg zTIYTcq)=YHET1B0LgFG1C&j&)4tU|``qK5N{-V`Y4g1<07E65AiI=eghNa0oMSU9o z9U2o-n?K3l@2v!w_kABy2`ic3I%J2Nluk@XcFXrDKo~bOe~x95uFccIDY8NK9~8=J z<{GzIU`C8AuzxWFSI8Kx<4cTpXm-G-u|SfGqn;(1#I!{bvGqyBxCFDc-=^wtdi{&P z=+ZL$l}jZkKDg;8zwagCxp1$&c*Cp?W+E5=kd7X>2>m`w7EPe*WCfhpNqI{{DZbsk zFqOlx^1e_Dlt}nYyWWHpwaHiV%G_MEE)Nf@50*49FeuYyAE@n#IAz*civ^!eU)4|z zh#9F(zU2MXKUE*Fd|DA^hN+%wO4e{gIjp9UjP^ahYhLe*JttQKSJMVjwQD`-`Dh}D z&Xs0E{q!C~hVq}Fmq$~!=o-g2X)ep#=pMi1d2I%c)VkoeXOegT^`vEJpQPq#f5lyc zQj$w>W$RTl**DyeucUnU6An;|6EY`%34_WHFz#cwp=Q&Y?0YM z+_|xa_&r$K`B%e>m=lbQswfAyS?&Fh%ns1AKshzy4s$io175XBlen}ROhIrwAniWPC0R90@2*mpHZiQ!i!zaD@sV~LgS32iLu;Eo)@KU@qY`&Rfd zLI>>^-GJ6@!y6jR>SijG%PRQI-sZ7Xb;_lPdxy|@y#r6`G`<%EoK;LIKReaEe}QI3 z=p6qPO0=K^cD5D#KLF}2Uqx|t|GYE@S@75MTHwPoq)bF4|XKBuc;|3pJBV!UYc1Ac}QsO=X4h5 zZ{ActUau+gdwxn%qT{sxEV6BadF_iBJB z;oIC4TEvS)XlJrJe-OGH?q?t*iiW5C=~De+_|mPI(Qktv6-0g=4p89+fXCN*NJ<*6 zw2$*`<>VVO{UO{i<9h3fvf~DF2-iE*GIkbdaJPkldZO$Ov;eaSX*4;)7fm%D>do!! zZmq3=>xw=Nq(Ol7{+bqNo&1re0J-{!0Lfiq2`*dn<7te?X8VYIxTRdvI29#)<6*c= zQyx31{$jKY5quXZSdl}7*W~uBW{_yB)%MV&E~4w!uKS-8`3h_aR0~o~-{YsTa`v5iAyg4qz}q&Bu6<~S+G_)vM4XbXqo zQ8Ov1ZIj!>44YDB%mHkO(Y;&2Z;oa>yXtnub4-^ncE)+Ggja#)K2H)>n;}r`e8oiN z@)?Ys;_wZfvv&M^8)AOd-YxJ7$M)mok&eF9J%bV#T;Kcoo4l_u(U zY&bs$hmq{FVZgh{v>3Rb>5;sl=YZcGM4ALr8lXK9;K@19Mb&1SQRw`B+Z#c{(1z!} zw~^Y*Zg+bST78+jsp2E*VWN5vB18clS1+}SfC@}CMa%U?>B!^qmV*Z3hu}dA^ZhNw%;!felS+_zq*d?U@Yzd-GH+|>J1pjsBsu;x{z=S}_u>XshN(sSZ9d>u z?#yE$WXKbOeowZmOzi7^y_{^cMCZ^^D=?_YsRs1VNP#{|#O6UFRV{5h#BcuB!b1Y& zBCVCk#s>OO{(bNksq=!J9<^~>M68V#!&7tkoH6BFs7 zRmwb;FW~2<@|-iSbK>{p&y{&ql?k_XAv z3M?*Uzm{tdn7Mx2qJYJ)gc|k?FzDEg&Zp^hP()r)bGnfNHGqo8_24934o^RGe9yba z4#8JXX^00~5>FhIy^{bks!(%VJ7c<@hV!Gg8arLa9D8x5)yxlhZLh6_qko#9Eb;1T z5h&R{FRTdgBtWZoJL}>uVfczyfRFtU?@3--Pn&~O^T7k-6yDe}g3>Zwr%RLLuiOeV z?gt_t3G$?k{D9c9tZ5Rs@ti^D&rr~Y)nL=)6*3{1qV9x$5FpL2{_ullmQ<8;VdSOj zMf-234{GfH%+f$lj-U!84#xfwSeWVm!-t|j0ZN=(bO|zu1J1RaT@Tb(`dakjIz*A< z3??eJkKL{-La5^!H9Ll~D9hFl5uOF>6Wc{5@6DnzsqRDwZ+ZeAyAe2Ak^U+m z9Yi`rcrAc{fb>oTL4#26U^NUmJ>yyi9MfBt_ShGV%_4X={qJk=EeRo1sWB_-u~=Q%&e zt&$bE-Ose9_TeL>NKRR~PQ&Rw;}*ZY43E;_5WvY4<=Z8kj?`#grkOUcUQ_ES4Z5F08373OCoA$z*6~ip3@VJ&Dm~o;AyEq1NSZ?kRfX3)h?Uom~ACo~hzm-NKYWM66mB$TscYK1R<{;N= zF^!N)v=ZM*+r@kXshqj;51~s#)#Ftb| zp5BWKd|uDzFe4v4h5z{~B=yuE~{-`SENHY}=utv2I z?xs|HZ@$>nKJNTaI(z*D$Sa(PV-aGcsxMik{?H}&<~I4`Z&p;SUzrJ>PAt%tbsriw zDYx|~77Lv%>k*mr0F8am%nGyp{H;iQ7^^JF!B7!W3Y14}QmUiF;d92F8z=-J)?7!X8c1{?xoUyRLQl`vfW3hq+S=kolGc zL1Auw6v@8s=h>@YDlT`;89!H?HZ0Tsiu$~!gRC#B2+#*Dj*T~_9#&6F#mMH#Voc*J z7R!gW_>YL2^X7zaSf8fW)R6B+hjl)IMT58)O%dATQ?#t2r|~74HZ>eYdq@e{(j(8U zaIVm~4~i;nsJDN0I*N>U@Ox%2B?Zle3q`iVmsztq z>MznjSpSatK+U0`m$kZu613Q8+AE05V0XGC)qwn`gN8A=DTNjaKqBYh!^cx76wRuI zk`kkNZOINg3Kyc8QcL|vs(j9k=1HpJiYum=qk@ZK z7Gj1vX5Ujl*9TptN_L)B&&Q0Y`{(AS8F3O;(+f{?8s;}^%p1py-R<`etWyr6s4nH6 z^vmR{ND3a$PDSE*(Vv#s`XfA-FRPH+r!pvRJ&Qbz)OuIq0=Tb3X!H-FWn7vIG`7fp}&pb&z#h*{~Jzpb3~&OThXSZ`cO6 zyEu`<4JZ?ie>P9i`~r&I8|A5)UDqrst1#+W9w_pTu_aiZ z{*Y5DsAw8EFq-0jPHLId)w8Iq%v}}PaTn{~QOuacG&FgMj7-YS{<+k5fUD2KYarqh zNKYw`EY(T9`HF8*ltefuFzj3EpvAgEv3oe;3(^&OkrF*_W6U6G;Gz*-p`r6pM5w@nzF}^WFAh@8rw&TpZ=#ly5GCqq-ge7 z;s1p|6!qU`C^-HvC>dwijGWb!rHE&{7s{ZZPtZ9xbek_K(cZRXsowD$@3^gk_-Dg{ zWUw)*d<;-~pCa%=pW;xafN(hz30M{YL)9#SNbfp8a6Aa6U5NRMMidM%O}L?l;Lxlp z8>mZnn8S7qiO-PHaWqI=aN1;azam1*d~Bb|MrT$A9eA?Z+|c?;`!m!n`r*9qz}=D- z(soOlgT?sC^gcBXz}BroevXG2hL+;?=izCd#32U5y3s(X2oCMhy*cQX;+B|RG~RIh zxy*HkT00wSn^-R|FOo^4>XSHOZKC-ZaoAAfQI7Xk!<_ZAMhXDtIdzP$ax*B%6!3T{y>fPoKzdo=N zwd|;mZr(_Os^`mQUGmcm$4^jpQK09y6Y(4`lO+Q=S9B~UFTJr4)iW>q@GU1kHx)Dc z>;29}Uo^+aWz8F(ZzrxpA5KJH4b5a?P0SQj%5|_F4Jw@H(!HQo)_;>!otK1;`pb5O z1;#PzLsKCqbP6(3y*_wkS7v`NDx#_wjO_`iA6jP)j~J(!wP0$jowN5h15fyLnu8#` zOa{=nIrekkNScx)xLnWIFRG=Wq2@@wXuR&Zn4V`dtUEJ7n`GdcK6Y*N(A8oLrJs|7 z&6Vi%x>j~a%CZcc(5UNM8g2$_Sk?M%Kc#P>{-LHY>n7Z-G>#3pMC0Fiph%fmCfex({G}o%VOS8X+q(bs$`-lDg zvlNRDy#PNwt&PU66cN+J=c%(|O+SuKe;EHSr!8)eXEIV7K9_W-m9g z|LUJW*f12*T?j?Iy>0%zfU5I8gWY65ZO0@O@9{$WEq z!#`gQ8jed(g|4=?K&z@~4GIejhIbZL2cw&@ZP}g`??s!lZFuy650sW(eCXfi^L^(u zc*gHrd_$Z5z&rqd-RDFd@aIEy#2w;Bn7WS6@@N`sST^$j*m%!I`{lR5k|*wp6yPsXnUq-jQ`lUL;(2!<`B#emJUQ^Mc3nqq+A$5MQ{cgfh!5+vXn8 z3NPIU>V1#MndPpY<&bPdOpt))@rCM2^rn~MV4KvS%~!p1LsgSl)4P6WN9+1IM>TYB z+;VlkpqQthpsQBW02#1l6w%65-i!03vu!cZUxaDVnWS<56EVqO_el8gffiBltJY7( zBEYk-Zt#EMC5a$XwF2+|{mcLH?Y{YY!T#PPXUJ-de?J(1N0PsT!QUsw@4th=-)Y5P zdEei`;Qtg1bPR}FXSA>L3Z}eC)}!F%3?d?gSB{_>0 zF9>*x*7^Xx<>L+*$^S8oDDdA_|NmF8SpQ3saYr*7W;K{eD(#8vb%&CGrAHh+@~R#f`=)g&%;KVO||$+>Vp~Na+;3JtZSuB`s5! zqutOtG2FLTzI!j@+IUtS+ClFl7CU`7FKno|DhZjh=@DC;K7@Lx>7#7)HODfzIoFo5 zpb{+&JG_}~_H}-G&x`#Q*(p}NS}y_h8;y%1MhtnqrO5yvS`q>=P^Q6TpUsU*Xd;z# zA;|a~jhzDS6=H%tj=9(HmZnC2NxL6XG{f}!OpGAov`<4^!^ufpka4XiPxAOIk#?R# zb;SQsg@9y+Q^N2r?7S@IX1V!shl)I&DAmQqn-gHZZk$?4l(i9=zHN*g9F~8VST8;l zz%T7&Wc|G2cCXW#x#O7N9Mj9HIFwqao+!7vpJ^%22H!%->2S)y6F@W-MU8Q!a#6Tf z0Bt^kAV-Yp9-;md@FlkHkb=e#RbImxpc_Q5!`C#ca4#3p=s39)tX{Q;x=>tE%e1!( zIS3o3-8ffqvf-t#@zVW+)*dc)@!S(%d&nEI7PBumoA2SllAuAfFTY8)U$tR(dH|>~ zNq-cbn5>sY6nDA(!}y$$4MvZI3NsfsFOc*uYCv3EMsmwTtFH}1>or%H)6{INE=V78 zzj>l+r|@}wm3sWPWX;JfXT^`Jrg*r7v~CrN?1b#Z+Ux$?bhP_WtFaKd2>i zFXOx8L9erHD2$Q&NwSOUJSrc5`LRZ7@~!5}`dWgml!u^*uKe4b&#WuYyC8uvtlA~} z&+E@Zp9xF%JbPEEB&`YNpHm-nzt0M^CenSI`Nx^!^3-(3l8@x#Xnx7$xp=>Z-A$Yt zg*93p3er?yNOxLyu0dK36};#(=_8V_!3_1OeOa#W*6YwwMGgjR@q@LTE~;(4cMdl< zC_5`ZwgkvKq>>zR-$4zPl{9h<%4bJz-$y2*HUEIlbuG%1=^1{gbyI3qCs1wxK6q9) z;oMYOxNMQv74k@;ViNp^VS8f}?!~PA(4~2mggz|55k80Xof3|P$*C5LN5lP4L90m2J?bfDIn7aDINcF&_qb*NVmeZkL)ixO>| zKiaQ)7*%@|Z57vPQTlFz_-K&fy_2|66vX8=Z6k`(JTLOoBEwy-{Fy53>CcJRl09R& zg(x{wU>iozY)*?cmFYuaT3Z~Hwmt+a>^^rl;)4A~2RpemQj^~is)oHDQs^ltKDN&_ zsbq(|291R#%RGd%27Z;aS-aWY=Nnc1U|7sBKLx-B|75E{#n5mDm`+0 zsQFdq^LktBFE{PtK9FZTLLC`TG|e?@9Xb4~5)S6SW^K3d8wYgR0~dK{PNeTVxO=w5 zBq2H=YlJIn`SxahiR142yXQvgQLbP%5T1Mg^OU*!z}3Gx{EA0MS#qCowM{fm22x5- z3X3s?gT&Y;bcXg|GEgXH5d=&k;hrI508M!UNND9+@mE>z&4v>@)&#gD#h-d9z@0*H za8yOy2oH~w7ja%RMV3Qrmk}(!!Dp3jiAe$7aMp=HqyROY9}fP&M-%NI^ZbJ^VjYz0}S4TPw4ZG76dulKCTlu0@d^wTbqv z(#6ON5`I?48=4&WmAb@3=3kX6XI&)6zWCLbm02d+M3uiPk`8oKyU!-*PIS3fu zP@^<d%^X~%8iGfGt>%v zc2qu&Sdo)=gDzlqcS2^zQ7Xjc>2OWIG`bo69e~pNHnSj^o~a6o3^v!tQ2WHuIZxkD zIlS&&7PeKD4tm}sbg!D}RussBhgjPnrl$`Hx8N4NR@~BY_)2xr-a+#poi4XQJ}f^# z3hzw^>+R8eaa}GBYR)z3wKM7y6sUv&tEFn9jP-a${Gq1l@ur4X( ztN~wOO#O8Tbs*l<>T%5>`b+2eFze$>WcCH94*Nb-n9n2TQ%l0Vw3Unw5W{7NBN z>=wRXa)ecUI7Q>f;}zggW51OzfNf&SSyiPOS-ih5pp)^QV^2?!--c!C#hLl z1jJl?+&P^PSY#`!WF9e$7#Sf5(J#qUmL5=xs;N?4t@g;XX+)JyxfldDU3`s@)hTzC zKFYpk8Cn;Iyr30vneWee*~)20whQyX_Hu*d1h zOVHWnN;j4#^{_z>!CP6Je(>-vtcqg{_bQB$--0<4C9NcFdH2;2xg}aSRsp-jVTyXh zVqvlT(-i->xK^paO29a6*ISN)h_7jx5|jPpw2C+R4D}QzF>hyh^L|ln|5}wjo`0iS zNVRA6T_P8Aj?|#I4kzW^u_uRZ(E8BV;x%H)k2Nqxj>gGE0!L$vW3uHocjWL9&j#^k z@Zo%s(?VKMStp{J>fEP$`T+|ef-h1vKEcn%8w_3DHfDoHKAPTV6{xN%yY9f(73P|l z6@2f+^p^H7K=&trpN;0z?4iu7MqaeKl_I#T%5<|pQdPRQTIyw8;-JD%J$9`(|90x9 zCw|u?d8F`RW z9Xcbl?|?iS1dg1-)%Qh$B1jr0GH3P~jYk7<~;SPvJ4(;45FH97;P zCK!wglb;h@TNTy$Df0{c2b1*nQlfEGpz5Fm*^Vcg)S4TT^Yq;%+(x_f93yki#qOiV zd-Y$g{s~eh%UbN(%C<9~7v_;BT+2>1?ZwZII)0{ml#|3_m7p&26ywXW#Gk&=b~!Hp zXf`deiwi9gyFOTt*sOGv`QgdqVN+$H(3|? zY>3=Ypu>TG0@iWUt}NJ!p#u#CU~bb)mrKpo;-rz~a&dYS^AUPN zvigLWjj^TnP$Ca1$%t+QH%*`HHb=X@>>#(ipPW?=75is%(*!7h_?bB6E!F`Du)OKt zy`EjfT(%`m=z1})Po>c_QpimB+%`>$*yU7!^vFw1cuh3oB9AM5zFjRibQ%rGC8<^e z%j%b0s?MYABteuIFW5g;Bu3@BJC#p(qpX!oh1jAf2}yplx(rrde&t_XPSj;{qXlHS zsYQomojgBpWf0>_^_YcU^{aaS#N3Zdax#;>DD#Fwxh;St>IGaw2{l7? zL`sGNf^@4~0_gs7p0dw5!n`}LSkL=S5LoUtAn-+Bn1gm~GZ2TEdT)!jLoi!q>@Bd(z|=rMdWF%77nGzzs;G!AAy&8?1a}b* z^0XC70*O+%b*K*(MZP}AATL0Pm=T7d3W%m6`B{@@foFlkI`3tIgM0Qj^4ejrzp-rh z&z=aL`c%6!pFqmUTJdyJuz&xg{+*MbjgC)bv|zPz z2D6viSnm^}`rbyD{9!Gg`YR1v*cg)B?`Qo8Cqd%nVdNzF&L)F%h`WqQUE|%Wv&bp` ze&<_9nRfAc)=pwpOcv&NXB4kOse}qgE)|fDoeLuycb#aR72<($P#ojXo;W5zNS)N7 zOfIQi*#Q*!(=-M$uG>+#WfXQjR3Ii!Nk;HTFI;uHVIz>jjAWsyFt;vdxCHrJouD04@qf@0yuDi!7cDiZrdk~Co8 zKe<)Te^U~pHk_y0X}vN;e`E7Z&sds1O3a1xamRmN^HX+v(fzDNhm||yDHQAaNEvKm z+B=0Gy#0k@?zG>R{)9wPlo-B}i&6>Lug4R%-;?qf?o*WG{0`drx@~oGs@J%kc;$mi zJPsbOU*-OTU#c|E(~q-Fz#=R7+MgHD-&G_MIzXff^1Bt|QSaF9gwGB$SK*-v3#r!!IHxq*Hw@Iaky5ER;F33^p_e*SfKm}?tivyde_YZ_@Ba6=l2Kc4QwMYWccQy7SS_z2cs91mQIraFy) zAlRw5A1Vql{e=IC!C}eI>55c`a%#yUYqX;>H6g$~Fob-VgtdAG(@^viU3fFOZzpqO zscHRd;<~KfP;dIpvT~1kx~xsv$@-;jN^)Bjhnq?xQiLzv8KtH@nI5Pwff-^H{k)3F z&2coG+4s3bpUKytSZx|ogjTj+7W|}(Qu^>{cIZeaqj}9J>@I5*NE<>F;@2jI!sQ51 z>(Ip;F?e>U4iPRoPj%L4*brfs zaaCU4roE@$*Ng{g>2^tD!5OH*k-;MU#ouRSXldbj#+z9u1|A4b`c0ZW^?n)PBDF|CN<(U*}-)DZi6N_YN^x(Td;OjKhVDMFBR*may0L#r)c3!5+W3)g&K zW^23ND!PlEE-bhd#3^c!Hz1q4q+s7z-=1dQze#Fr^*53Z^!PRG`y)x4i%0UUrE&J5 zm$~+M3}Rq97Z*~r{93_P~%qGxryha3h&>^KzA>(dLTJq zcI2XEOrq~lNT|X_HZlb!??*IdGdx?U`ujVXc#QdBXMS96@@!;d_C6!3-6?8iI!Pqq(;{15V1oOT4$3(~r>k(> zkIBa2INM4YF^QA9bW71OBZ~rqOi-<#Pqxf}RoE`Nd2oYEhWkt5X$%HpntO!$GTGpz zqb?dEquvybtVW)Pc_DzRlMr4gR=rYPprc|1{0G#yhqtOJIw%%&m$+eQX7_b7=(5hZ z_Oy(nL4=iILwj@n;uxJrK-MYlDRT(>V#LETBR@k7k7}vtv(2sGR&djiKuucuburHY zd7q3$6^M%4B-mwa{nEdq3jXuQAF14IElFon&${p`9C>V?x8ONw{513e?CHe_Pyjy( zU7-QUN6MC#d)v}$+!dMw`4>sFjOrG$f)kpdGIfOz&Y?dct}JG^l1&vj~GZTDyH3_I-osU zt-5x2V0Qr6saC=d03dcC7DaO-ZMk)hEv#kIuT0!bv8J%RFZ$^yUYF9Hy-wT3nsPGlST<*pbFZ_At3f49f2RP1quO#Ha|bQrbf@OA#qW&{OLYR>F^Tdf%vp zteF*2?zwomhN79_3a7J82G#rmU%Nq{7z+%+zLd~q8oDrKZV3Y*WMi*#Tg<)(o7Oj} z$R@PanTp1)<|M@Y+C8CQbGemk?S~{}@{rj{r)xBy6F5}}pRI`^v9dsQA5)%1LWm)NUV>y+4`q;YsX#|~%Nqw<0%;9pHCtZNlKNvcb#&hkqNg;e6gXMA1@R~i zgO6t{4(%?ep!SRoriFu(AgZIkt=RA=^;L1W(s+*Yl)r4 zMv7pt?wG<}jG)M!1i{7EjKyMP0%f>62|DN?lHTR?LxN+4(`lMO#)ds%!Jw_nzhTuZ z6DeFS(X6M6QeyJ=o=em7#_XF6sAfp@+->iD#2?K~joQV>3emK61>3OG?%sJ#J++n55wvsO-tdvpcA)H24WJBbU*ixh0X))glE4`$H4c*z1vb4P@`uoi6)Czcz1rZvd2_W};_I!Sy zX)q@T06qYGqeOD-14 zjlCWLT)yJejcOrs@o<2JQ`1b&q28YQ(UZ>+N^BjanU(zfbJ}nW8$h(HkZ~R!7$A(% zN9^j7o=<p@_U<)W95>nefR(IMfJUvMZJA0U{*2VcZ8Voz_ymiHcIBH+}s#P zhYV4UvZ7~|Jv&2%{&c3aQzA3KXQ}P{X^ojf&kyShROLyPGsD$I%Pt)VgTYEL* zNJ(=yZFgT@9E~Gn`5rWe1aBt~T2c--f1eTR0W(lFy0RA&$lTVz;k%~(tPMbUbT5(9 zpt_`+(b%Pj_K*~}@5xe}&*%anBYsm>L5e^EIp zw&fp8m5w3t{eC>?OS*RkZ`00;UGAER=TR1nmXhq1e#W5ERjJHnUi!`iMhych{EH7FW2K1ou*TZk)c^1Um5K^vACsy(`M_mac|Bm>h+)dpvXTCBdg3W*~M z&vk-wDS{E*iZ#v8`_zU#oCHOQw-g=tZ(fa(zRJxMjnYql`faH$Pd}|bPfzF8YYt+} z=F0-ubt;6+Kva1J2dW*w7#;ZvwB*9x%s!G8FVuai)pNzugW%RZ;{{Ul^sKP{d6+#< z$WOVN=2dvaJvB8p?0v6Q-%lw1-J&E(Pz4}+M?=AEIh6WAH|Ym8@74xmJXh;GF|ouo zi!Z?4(vHi3kzW(o}to#5AwxkI5DbdC`m$2*kH1VnZ=z0;f`rqKp9L9OU~PQEi(OW zGH?*gSCz5YE*2-;mhyOf&r{~Qca@T^ZnD-UxMswMdlv2G?VKHy<+j4guG4a)(Cd5D~`Mm0L?MHc2rLSyY<@!-Di$`WCE9UI()0g2M6< z3bEqOw(OUDBI&wwb>nNa+vd9SqLR5qxl=iD@}U(3weRC5uA7QdD>oFBSZ1Y)j&y1L z>3M7wpVGaQAb5jv9!Wt0ju|{VO4rFtk1#ljRi_sR_$x@Mq$7=ph#|0KxezzDG{Bj6 z90v_C80_24D$%+L>AdQp>1j9QL%R5|uWD|s?+)`S^%70A$DZ$!YDo9BkLkA;WqY6a zwM1Wcu9rUKi>pX30H5P=@*qi0p{`9<@HTjg>fQfdhi2GiuIGyB18r#bkbY9cSp7ij zmh|2tqehKr@(fn?QbNJ2fm`ViC&|$sOl+ynm9hm%?>rB$i68s8IH4LeUM`N%x5ZfH z=_p0nPwLy^1I)pI=Qm$ALBEas&DXsNSzj@$M-&Gs%7N5EM6MD>>k^?EK{iUEZmePl z=B<`yK7+smpGecjHyfSna=QH`6{GpbC%;~B#vq4*ki-g*_I<2Z`z|;rbWfrD^}$#u zV$xFZR^9OzKTEf-ZkpUrTNZ^AYE^ULp87DCM546!lQQ$pGN+He;l;bu<%~xHdOFvT zu0quxci1Exjaemm#eWIjpo&pWmiu~A5|Eq-S1(~AGRX($zQp#^@fNiTLK*C}J&f6; zsZ>%GI$K#^f>a>Oe28;U_2W>*!7U+!%wM+jB^$b%~<- zbXQujxpG1o|415Weuh53s>&Z^59d%G@@pA(veGEe`QGrPmeUU!JJuDU6UA%Hityq# zmGmd|l9#Ufeh){w!I)zD6(q6Xgs$&A`-B!#JVq>x652xB0|-bZtb~( zjHfC2iVb0^}S`tZ?b=t5&3PJvE;EmjjG6tp4^lOX?Cwn_@p*oisJaug;{ zMrRe!jHbP5#>6`c-G&t5PhqcHhx%SUQ1N$H7wKIx59b>kd_N{TU(v&l>`Dy231>O= z5jd?dmdJNQQc6ssi}FoTFTO}Q`{k-dqOzVrbN~FT@bOmHeHDKcv$rfi)zvmb{GREz zFEFhyv}Q{r%zT?n@k`Dg|)B5b(bzNDDaENOmgc2TlKMXn$*blA$$I?feapUHh$ z?9z7nx)H3J3LI}|N#xRQn-4fd3Qhm!%JJl6$fXoU-e#DL2T+?YQBRVbd35LD8qYmrHF7vZuBtiA zrU%NeBNbDFmFs?oy(%VG8cX_8%5-tOlzDYfHbW^sLmjhb(X$L8N}8h_D@7?fCO{%V zzvy$q12ZS@g~^O`<*9UK$1l=A`9FF(xGs8;BJ}aZp{c0Tyu$U6>~!_Ks{LqmAr(G{ zSKkDHbf|#B`Go|}6NkHnxCBAojUp?ofNxdXQV(@>9Ws-}PmipvM0Chq zHei*$qpw76#yZVm7#dUFuQj6Z&_DaXUtT#Yf73+WzAvg+Lr$+TF zT$*3gJWHPkZm;+7w!mdg!}$FcNL|U3Pl(ac#%3Kn%Vx_oXlGE7VC}8a!#t+*ala?3 zX!)52Q%s*9BRds!ic2Um=E{pO_y@6-s274 ztn7VsuP5_X+q}xt8|%YX0FCSPfoqaBk)I~e_Yy;|1J2TAp+b~%b(Pw7&H>vZ_;1&+ z!^sivePvm1qv#(kh8Du0H1q2`%a%`e2}g;p@fEME%S@|Gehtf;rn5|w+-Mvz%ep=2 zE7YQH!P^rsNbsT*^^m-=vRzPOx9ENg(*KbLB4_3-XOKY>zt3DanQwXlviq=>d9Wxm zCR^?8gWk0qH?NIzP6ELND2GX^V1}$G{<)fFhOW6BNMCJcZGG#tY3TDq#cnsDx!WCT zW;WlglDdaWtm08d8N64Gss$TXC4jMOEI;x22~Tp*cdmNg6rr9_Ev~5o-ggg2Ep`(- zlCA4Lqd%$v^x&wX3ohhex$Bd^&twJtEbF~BJC0aJ0uUxI5QMzb80&_Is5eeW1 zm0lSIe1}+MmwI1xkPjPtl(I#!h{lx6Q>}B7#PI&FTgYLAA-6JX2W`&dq=S!?0>?+X z$^3R!;v;prcbIWIEe-!x3Ue+b*lP@3?dOa`$(gqEMgN!s~&3}O*mzu*S zP~wk^qD^57idZq?=VvxLuC~=Gyu0v!khX6WMfUc|bw8;EN_>`mCf%d?7k?4S{+LI& z)W=o&eu)(pm1Axel#v4!vep(OcR~YL0J=m1IsQqJdqI;S3P=(2V?O>QAYRfgl7!Av zON_bPwKzfCD9tF}W4DxLq9$?43OcH_S+jpj-Hc67EL zi_`d0|H$~tif?o4QE$-8p}NV;6=;A;ccqsq>9!i4;9Q`eEAAq(;xWQu%v(~h+16Zy zudGjSdFNFBXhb#HB58oE7Qvju6kDJxJt!XHLT?JiAlWo;(k!Vt%cr`eARLgjY6?=A7tf9<8pi`^Objq5gu6t= zKP3CS0x3CzxQS~8DUMB}iVqvo%Bj(+K?43erYB03CJ~^HH~iYs!(#d0KzH!=8rhGD z{p3a6%qy|bcE_38M38sSOImvAC;DRBL6adDT|dmxABwLDn3xdLAb}%{q0?r(n=4N$J)Ui`P^%w-KvluY%rnDAb;9O ztR%&eTije>Q`RocPf&`%fbrckwIF7}@R;24XG-Fg!D2GK#vGZ_PfMjWIau`rP_q2G zFI!}wuBrA0J&KfO=4^hA*e`j{i`bHf{6U(sB~lD8`z*Rwxe7~PBw4-2uhe|Sub`q6 zg&o^NdlgdFlG93T-Loy<7g-DUxfDYVY+X||8j>?Jua4Tz34fl22slMCXb60{>ym1S z0Fi3B{NCm2$hMhQ#iQ-mZ1u!TE!%;K@d=9wv)mj#4VjD)!mT|CV%cN7si7%;wDexK z_m&yzoYBRm3J-ZJpNOGLpJo8i+y5|X`OoU*fB8j*FPhRY#WcWNY;Qqwq|Z@>>Qm+J zcmr?|BmO?a4P`WIsGU;WvU`-gy&#OOn|vPRz|d_gvz2$cnqN-bVO!%ZNr~WGlg@m# zO&I>ZxHgh%wVF6?B&%R$sAZtIxN6`htrhj zd${w4h0u@{2+0Y?P4lX51p`!^U(S$ph z?>$lOFdR)OWsWo0^oyCx@$1GX9vSm6ek#5dtkCigL5M+T@YQ9T@8em?gCjFc?8b25qsLXBko~ zqB85tpg+17rCTT^O_ahFyQa~iiIncSE${6B8Nxg|#wZ{ENK@eCk~AmizQ1YUT4Ql` zYwKf!OvSOex1t+MP9K#M;&aD*{enHV4HqVGZ97dRQ;pfhEv-ARkY_42S(l*r?vO<# zid8pSfcn$@YW_bcr3qCu`BH}@)~+|;J|gb2J3%ZmP>7l8cJFJ$V3Lc&WJiC=PjY`m z)y8peMVY;WgQIu6 zYe2tzMCb5{4$!Nj8t733(In4^dvpXFOnq8b8moJ-=qkE$ zLC+{j?UzMR#CC)Tsc>wyEK4@4-t36bed;*%t=#nLtI|?oZ_v<2n5SJwF7ExlN*69V z|0)$APxTro1$P$A7-fG+6E^rK0AwJ19wWk(~o@?7r~2H=qLQCW>OsgK+lm8 zy1@RFt-k9^v2_N%TQDT~Tmj5!mRPV_D*|Biap$DK1pyz} zUD0G@QI99;zPof~B{8zF3gMA@U`~9R9vXT&gQ_#K|9FB6-r7KIyXYsB%pIg56}-yD zJ;f%Qi{}iqLkjDx>g4Gn@E*r&)EE+&cfAoHx5A~Vd|iP02xj(|zydHP3|c-l#$Tng zQ*@JH9Lg__!LhO|Rm3Da`x^Ch!E2*lFhkT@7$!fBB)%#0ZQ}W2P^bf*L%gi?f?n6{ zL@|-0A|9}zKwkCcVg;&$P5)JT@x+gFH&Nn!nZqWS{92zv!{;Y5JVQUVYEoWenE=Pl z73G(t6y6O&>1&WHC4l4>2^U&t_;i(*35q7s^QwDD3tCnbZQLstN@JT7BB*Luu^ekm za&QE*K5%Yqc(XQ&Ni*v)dK^fIH%(I2_sq%3%&~+7_?M)f$VVNw&GuRfN_s&0cLxFz zg=El*+c~S>Ax%?83xI`LJ)IHWo1OIvs7B?P5qm3EF8dHil0a@0g>EFL(#g&lk1*pn zuR!-8hp=rh3+#3dodeA5Vau3=y+}+sTb;E0KJX5rYp2K&LhyaXbghbr36vz6fBdyu z-h1nDe5xPd6>l6=QnDKApntfI_Uno?KMKtiSsgxd*s6XrrJQc=#iuxKfJ(jNW_

kg4_Zb%;3Z)6Tyw$GHID%wVU!uQ+vWlZ9W*BoX`Lr^9a5&R zY!bxrJsa6kDuoL-A2(F29DCkt9h~OtZ5EKY{q4iFw0%S$XX@yBcDXu;lbzOf>6LF?{$u8)&ue+W=uD{aXq*d+`0-(g{twljSIXM98aSf3$r{8BLrn{7=Dx)W-bKSTT^?A=Dr;#1G(j{6F9e~pw z#OJdh)|El0aP&gT@-mQDX#Jl47qlJT^qrReK64Qfi>s&OQ#O&8Lvhbl&TRh*+Ufwm z?Um2nR{OkiW_pjiZL?r#h+;k~Mgw{c=oX<*9`v!`CcH6#ibXUXMI7fKDJIA6$h=eC z?URx1IQZcqV)x1KGw~_o4`@3-PnSYZM_I#9a7VWgJ-Ta!@Q^+D4wn8iru}q@_D+jb zv^T1yajX@xhzPvDNZ+A968iVQCe*g0)p~sg5%T-YO;&2zsiN^PJ!Rn#xp3tW*Y^8N z8Y9gdo-OtR@o)b%HhgITuyKl{OKKT%{K6F-M*KK@aA#*5Xzg?Y@l&WI?r3TBq~q5~ zq2S+d@9)+7d++`IX#5>m{tnCk|C}06apbp0{!iWC%^U$~L&^Bs$f{wuMwMIZ+P@!N zSN^vYA_GCP1oC?0Q;FpNJ}%F{f&9sXqIL&q2&f9sOXJqvcbYev0|0fc{_-pa1+G}kL0DQ;0ZxfwG~u!m*({(rzyqQ zsz5ubc8^26pvq_i>y??cgF~yU{gpFwnuT*FgSFQNn#0s0)Zewf!)o*26imGCu`jP0 z|F%dc(di>l+0Aug(bH4Yli_pktyWIHnitkQi@(gQbg4Oe-&JlN&#J>-VOgJ%_Bcv) zz~9uwLvpR(J#42dg)j$jF@Hpqt>G?e%0pH9vcimB)5Rvt?ql;GR)OyD*WNq+(xfnF zM@YK!H2;eC)!;|!xQoB0rzk2>^ndueGHVLQtC}hIL!4_Xfa0dBxQ>P2utI8=POhYR z#nwDz@X#BnG>Hi|Ihs#MX;z7=uqt>%VR6W|z&klAV|^!YPD+coUK?an8)hphm(UZF z4a_{TpBY6!QvPaEf-lIywcK&sG)4s3&dA}x63ie4T%Xcq8KXbJr;kgHundV8$-is} z@BAiEKNw88d)BmH@geOUj#YK#j~+#+Fn8DNq@ZlK`lS?BgL4+&Gc0e$Ou6e{bJsCV z7mM+3(tML7Dlu%5cyl;Wi`O?_E@qwLC=`3UHCIL3A}9bAU&?<@%gJhH!W4b85XHOH zYC=V+>D)@3FGS(3>GN83&x)2K+(>sy`+OMmmUmcyo^cdS`y*y`!k>x&PkXtwj|L9; z=w}YxanVOw)nQuN#%)iGqxm-6MY9PurpiGFo>Vnbu#j5UQ!c22TC!(Kr*i=Rc^;Ee z@s%1?^*2Qc-A^d;mE`7kP8H@+(z>;1Q}d5T^0{UZL035r=%o&u*kK8Zk>&2DplmcF zx5H$v>+2p;f%-d-YuW52wVYzHsEZQ?TM%uF*RGQO5anQ?;E#ZyUmzN^4*IFW6yq)& z`#ApVjQz%Ks^hlZjP#R9(e@bQOg+Mdg154$adcr)LFoAt8;iz_9w^O@_=C?^Y*K5Q zh4%|JbfwfWpIt3Ud@KV(EYb-gUXy6iF<*%-l913*H;=SxS@ZqDOGa}?xSiUL+)^9s z>`kZ0F_>Bi>np8VDi(iRxrQ+{_vn>XnaZ8YbVsfTZCxiT9KciVBN74KtNbz#=+R+0 z@kHj?_Wh5Z5+%BvgsNd=@$CJO@&)U)TZWv+RW!@!5yPl4yMCgs>1bE(AHDVg(#}Lp zfiD5gtE0t~$(r<3yp!M!(`4Q}n4ygse!MC^SJe3OJqs@T2jfZN{iTC2?Ou?4mnT4% zQSWp$=3SQ-1!?PSkhspG90Ps#h^7r|j}y~3CX-Z*5^Xc|?rIFi1IEs^Ct^_c>CTWv zN$LrC<^N*u&7;}g-@f1Wx7*q^wy2rx);zan8uDxHQWQl|W45Xx=2;N3TSLrRV~yEr zh!|VM7*Y}xMJt9DMUtYZN@z8R^!fhIbFcfH`#ksa$FtUR?sL{zdo6!htnXU+=KJ|x zpX+m7@9X`#(*_87s%W5pd{pZK)QC#-)}{ET-#?1EX~Ii33Xj*V67UMjU;d#@JF*GO5rVQ;Ufh~bb;a2mGpFVRT* zrkjGWsDzIY7u3^P*RYHJ?vf0lVxPv(C4I%-xS968n`gRP`#RO?*2Pn0%sf@n7hRt4 z`cpKy3F7&*moeU+C~VTm>a|ND&)%rI#N9EHOIovP65Z?Q-kem^X!F~S?*9H>B}n+% zpvOz5(pzAG=EJC0XE#@JahxwVFt);Gdy}eWZpxU}S@DA5$bXl>$DoFCvLKwmY;O=q z7?6_AqgWi2<0kVJlNbH-K_s4fe_fbLVUJ0kkJxxz{Z`Sn0nGsn5CMg4Wo!+GaH0*L znVw1TqRjpCYY6pRS{ptRfFHTV>M6Ny^CVT%#JU>oot(49d93V`eBArYBc87bu9x0s zXnvJ>-32`>K}^-WBWIt4bry-W54G2qMBKV1&ut`CV%w0~qAjZTu1a*qPs2}bK8r_} z_G7@(lcG8@lBG#SJ>E6q`LG$Af{SBFsfJClFS@Aenw7W&+QxmfESGMNH`qGgq#oFO z#?fK^DX#IY>Z@xG@3ViUvg8HrRvS%uy}xy}Hp`{(XWvk{1l=)spLtK(j)zk(qO89D z+t$q{vHU~qOpUCqX2fDySk(|hJMFdnke23~4h%0quobY=&sIXuz-)+PcUzPS7T0P& zPx51I1#GaKPb1dOUNH}8+>*=g(NEWxbW3Qh;2-LwHK%?TCko>*K}~8(Ai4Q@^`-+R zdQ@BV*21y*k?XfGJXvjWkEQ0HPg9`neF=mFCJlRROqui<`AEfvO>dW|T@NaWdO1Iz zADw*aex#279rZqJHy@Ac2$}>uXafH@$Up4XpVyvVo9*q(BX^dpj4yxVaU5n} zc#FSL1$T5}NIk6qD#-@WRP8?D+x>kh3;VXyV5LHSc%E%Xw!_`ISee*bv|LTd?d(}K z3hYMXtQ3LBYve6I`c zoo)hvHg#pNqh0Ma)05_#*H;{HoooK0Ju?NRWsVwQ*}c`@{mtCu{>4AtF8YXoPc;f!hifp@Z|#vzd(Bj3wH!kHxd$97SQP? z9|GEHx<$&gha9M$T^wEid4E(es{gm?Kb=iV%af=$~Y< zQFWZ?oN4+;oaD`U^ETcW)wv)e_QBl8s7j*w`Gv}o+H3irsxC$CdM%H!-Gq@{wbPD4 zqmcmez`*(GzrS;)x<^>#cInSkpXEwE#{Q)b)ZBiadR<9D9}9g8KGAWpcVx>3GiH9C zntoOnXgZDloB+t22Xv61&X7E(q3WbNDW&r?qc z?+EO7b^}uSR!@WL7ViVHRi8wH4}ejED_a7}HkOL@`K2MMb&9)Y-q13?u-H9=@y&jK z&6!0KGGTx9F1=Gk{%ga=qd*Ze`qkn20{*Y9ece%ou1RofTc=h*OU=^(ClmhWEfe=6 zyBZt!cR;nfdQH+p&37|iY^Bs*O5l|dAKh`Ng^MLONAPY*X3H>m(W~l-5OIVHW1N=1 z;Ls2Q8iHg%_<{dkfQvBWOc+naR6K+5USPV zH040?0VAY=EFIH;;m{mV=!Zg0f@%0E?%7ZG<-Nq|n7Rck%bGx7wg{ zaL-{I76jOOw4^axQbzRJZVC?kVfqAky$nmy=pv8L z23U&T7&bCA5}0b0$RP3lgUZW0(WV9(vY}MSjAH5Pb2Z%H7X@Koc)cVrqFICW+Tj6! z;Em{m3+oQ2hI6QR)|iKun!f*e>V@poFhKy0I>mn+F=FAc&2X*bx@&E@Hs893%1 zM=3f^g>~!Zt-ULHIqdaf*u!nZDil$m9g=&jDm9XHiSDXM$vL-%w}5gHV;aN0ICi}9 zDezqr`5rJODYNDAl1zMXsY(wRcdVxFdUpdo?9CalDvd84a*nNmP@Oe0BvSc)g*%S) z3jon(NBLNuX$*8(+ecFH+E~A7K&Xu#Y)K=WS8ZgO^rXYHr@jCvEUc?`d6}cYN$yws zm>rpnFJRHiVlS}%5JHjkEa-d%hxVIR*C|QLkF@S)Ps&%1XCCyIL(@ctIxpjv`FoBV ztIBbHdOa7ioLiF&n-qY|yl4Vm>G;dDjk4>c7|8_XY<0C)>s{O+QMwTHG0jzqv*XJB z*n&Oq_HP(#k@`kAh^Hfub5Ob7q@O@ucp~agmJajsF_d+eNjw(z|1swb^l@m0ng>^z zeHiBA5L@5`jaP2~CbW8L0J(pY#_=tBR1F1m!Pylq0LZEsEvS-_;nr-EH60VdW3-iYvGkMPVWG1RYA1?s-55$qAx z!eFBH4O*hXOY2%;1uyQr2gVj(BPP(WSFFnoPpk;#K#BCcXnGY>0OHj=aw_!rlcK^a ztupvPi6N`hh3M~xW?<};$3qVbFHXPlqg*nFr$-jR2lF4)4_+epH9!^w28@0?={6Er zMChMX^~-Iqh_|EP14aZ8QclVW55f!!SN|6sHqz^_P2{CWiwpwCh+4+#^#P=RWE_&R zWB4F9vLLyyxb1?qQH9v-sw?f6)p>!LDJBOh1T2}(c#tFTN#X`cGy$YTL=XqJ1FohHXz^IB0>c}8elEOp-Tiw}* zFWyBQcULpfa)~ei1zWLq-CB72A`?6TXcONved?XZ*Zqw&#LURk%J)0AFBpqUn@DGO zc?uA7SL+YaXU9=WC!)$UWpX;@Jl3$e@=xKZC!(Nj?#) ze{1+NJsW9k=xT4FPJOl!!q_Vm%Q6G+P+)WugXbw8sZP<58Ny5d8!H!|9rHcNmkzk| zprpw2SkpIl{?7zWS2%%cI$*sRwtrAaCuIIS1ydIQc!*gwx*6U~Lt4(M8(3zB9o^`u z=eh3CI=D1dsJH>1pvq;zkquqtAcROI-`0;?dv=(CL)PQ2UxhjH%x1mm;naFAJDCI+GjF(=Hs*R=EdHlH#Q} z2dQBd(uE#nA@gYkaPrw=V4q6ePv^T@#Je7IPuWx1>sf5*kX5r&sSU|PNT|@XXw9Z7 zvnH+6@OPT70YHTn9?TJAPcN%8X$=26%TyECX&XguE@&i0QaQ>j9s-|z|<@g`N@M<@(GBu!zxYUve3~`|8 zJh27f@JS7$Ys2>%h}|8+0s{@I<5%@E167FEFiOu7MBn(CUQ}|zX`_f#dxfs~A6_CG zR4LH(_oEY}^d*w0oI9!4Mvl;$cXYQm=2jexAFw*=f6(#xeJ>ERZr6`HUG;5}Kg< zc%yhtekZPq_qA`O5bRy z`Rr&dij~gT3s?Ul`kX*|Wzo96V@gc34`&N_Wd4ovEY=y}N4IN8ugN6Qwrzu)hM`5& z&(tk)zgTXi?L9%nu@e(=?39yaa2EAtzlQy8h2Hjn`I6CQ&(yA8Mi?*)=tV%_<}*6` zk#$W6(8+*>BVi0<(z5=1U?ak-VHC5#5+UQgur6C0Bkob%e>vaq;{MUme;|;KxQejL zZW)1BoCa7(UPK8{3iXYu$}x(GzBUCPLtiwBITvWv!t3?Hh_?oT;cS?pE}7V*G$gZ! zJ`K?7C-If$2`17g=3xk%AN}h)pjuXg4%LxHDbI}Vm!Zz)(Q$Y3iuA|*jKRa}T_q9W zN?$Vpg{PN;2ztjVz=}WLL)4*WnPtzs$oS#VM~6H@dPC1466l~oC{RuXCi_6CJvA%o z-yjms{zy)vD+!}Lj@fuK&sA&TW{hWGXccpuib{JRnS1@pPrsJPn^ixKV zq{IrP=Mb$q{d!hLauTHk7?>oS`YG0RDRKH_)pNg|xu-%!94P@iUvX~AMD&8QP8v;l z@w2Tidct`i6!H(R?)g+HG5VYbg&lg5N9jBlGSA^%W?W36y9y6|sIVyk1hE^>ytS@% z-H}tfU%akeZ%2F(x<`D#D88knv3}PkpBl!iHsXbl9EthLk-0Zg96BZFgSYr|^s4qt zuniF|G5(9A;#dOaaZ@tsfx^u!6~W5}?-7Fj9xpxsj)QG^Vc&N&R|z{9hU0+`6GRzD zC+isLF=5YH51F$J>0uz{VQX){V+k`W8O8%g*6Fwm!iUWSMVNv7W8D29oJC>9;&6rj zbZ|tkr3J~kzx26jJy*=KKk6{RR2Xhbbid5V_OMQCc*ru&pcq}Guu2Un+=5-bD7|3q zA+IiH*9c~?K;{I!4UULgE*zQSaC5V2< zQka?pXa&)UMk35kI(viClEyNu^)qnmL}`m^i+mq`Ct%mp4S;-aRQvT<<-}7a+_zjx zyVl;;K1Q}J-tZ6Wv{hZr<{M-`z27hK2H{S9Gm^YNhPYAW$pCx_?<7d+MJL`LNvW~w zG>MZuwxTN37Q zAKjqzUEaJ|Ek&9S)sRTCoD3}#x?3c3*$T0{;0%eMr^;^){PW+-od0Qw;eY9m9Fu5V z&f`Et_^~0&jZ7X4VG>9V1YU3)Br!nP*e&jUB56K>Z|+-zK0@EOqchsS+4WYPE9@W# zbL(JJXwSvhZ2yCD0Jz)V4zcudBS({<)S8>{qp&=Pptt4>p22+GwmUV0*x{gnR0oi04MBFKJA5X4I!Ls-^~_GRsMdd`8{d@`F8 zX0Y)XFWQ*;-K?dN)PHqOTe$#G_`495Ze^_#)Z^Bnw5W{;iS zbs5G`209B7O;;Y?V}>8ppOgd?0bM&BeQ~HncmVx@c9)qEM}dmGXHE?`hcg8xf|J== zWEK4Nu##IRfKMgZwCYCndw9`J+{>AWKEJW|<^s1(u4dg=yxVxvE-P%?iqeXK_65Vl z2{DTD%7FPpZ=oFkK{lVo%3FoxCdD`F(0&4km)Q3oex?1cFy*-?`%cyVZmxbBpti{T2A0PPr zCvVY(rDw_b^$3lBUe2Eo8~ni|b3^>ijWcF4ZAEwLQnaFHZd}n4IMXV5+1{irOcW1tS_rdKnNtv4~gEST#ORc!FPNT>Z44`g30?LhiIa~lu6)A-e zXZYU(LZJ7LRgQE#A5h&$HJJMI8{zSR?h3EW?6*&|VDQxHgt+B&qyL`Jh||T*WlkrnIZY>BGDvTHNUh#-hC$*S7D7LT5|mclqzi6$DwVy(Ds~e; zm@5S-m4pWRmIa_Sb7T9bj7y3rKS+c$0O{aoY9R>-%^$By z{bLp{N_CT`Om;W1+!#W2M&f=8Qn)zG=L8wLP{C@T?y=?ozhQF*EE3}`&9z{cqyQ}` zTavyRQLu^dGn-U8uUOmnd1CbVpuZ<=(6)&_sbt$AdW@5NPPRepbhUphvvtT`(7OMw z9htf!!TyE0LdB3Wc2heR%5$>Vg6yg7UYwkGVi1}uYD91}iu=jPtU z=jHacIkwXx>oXiJEL9TX;LyPe&1q?dP!1J(ie);B^dg;9843FV1zRpHbxzhD=1rr^ z%xGJtB-J9`1cXXB&+Mhfsf)u)P02=zi@v}(GbZtm*~|S5i3Q7p_Ju2lju+g%kJ&_p z=3fFxrju)&6_e(Tfm2HUxvGO(8f|Nq$_;hnB}x{hC7Ka^jlq{hjVp{Morn2@Y|{&B z6h697>~)5}WI9!S@b5oM{{(nR8%ZGo7^Yv|)v~95p2F2s^wNKr0K3C36`B#jVl)S{gq);z9mTlIy0q7oAvAw-kB9u zZQ1eIGW^m@D`&&!OHo#=m!WgY722|9_Dyg#7|zExJZx*a&EZGm52Wvj{mGMvDG)&G z0obOhy3~hKGVKg|TnesZWY{qp-XwspzRZ^Njqn7ZLGU2$|0=xoeQop%EtEIUzkW`Lz!Kf=0m&Kk98j) zmVt4g+m`>X-)$`1o)s$t?irAU-lb2SWW?&SOI7O|fD=O}a|^k7=bld0ru8?7B6779 zvS&>Qm^!|#I}AFpL`Xvu<3WUvcnjdeHw_aCCD?mM@jw-S9On+D8C^jbzko$8xM59bpF1#Txl&ONRCNNnvW;nU7Zf;?R;*WS;q<}3MQ4GY+XTKdFS=udnh-^8aObT2Oe47z1l zZv6?(K7Hko#$p^(ZD(5WmmBZ9Z94aDqbd!-Xm#zr z34ERTDEB*Xn4;1aG1;&D_pg;U+HE$uf2?s-RP>g ztn4Dr#Z|5`JvKRa<{~lB-#=L9uFC+ohpobcEa|LM_IFQJlIuP$De3$O(g+aztKBx; z;`hAl)J~v@axU@bsT+OLfONtE%1S6|!?N-K=B11TgAG4n@G$`kwIiNQ5L2TSAVYnN zGeD0*SpT>&1=`42xd1GI#2Y|Ccp0!9OjK59LrnkU)!-tk?x6JtGWFzZDHfPR<`}e2 z?Mcb;SIsVnqgiqdF3a?g8#jukO6JDmot3ewO>3n;T5kzl(L(E=&5Ad{XwOzfT>gDG3UEes9j~7_3dNHo%!WjI z;B1+ReZ&uOQ$7h<75Bi5Ay0-N{RP&c@hZJ3t!&FA({H}XR*U?}uEEw!UQs{NOH{}7 zi3cX}_1;pi!r*L+isc<0w-n;)=c$W&b~Q@mnwuAr>c`5(?uPpp50(i8-ctBM_>b#q zn{*Hf$we~H+j>71boy75kS`rD4WRmZ+e!E;=DXQ5sdzokmsn}O&FaO;#Zc)Itc zf_+|CzMszbz+p>*1F6PJ(M0XMD!-ME#dz@eR|C-hE${C8?`gm?9&PzDO|6)Lt9-mL_Y3q}ghar(B#?h; zVbcgiKb+QTlDAH-j;VI>SJp}Sbpf_kNTvR>!fWVF>(b;dxb?cCNqcF2m91@Dw+V1h zyN8GV9vCY{g|YLhxuF(E?4ELYmW&wR$+>SiEKw&U)jIOv-_9dSObhlcKJK5V-gj0ZH=7s!9~t=|{}-G( z^A}ter>ML9#j7a~dK^>!arjcE^hO@^wcFVH(c#efe)!_aKNjy{KM>L}E=c+BKqCbC z51DfFBDQn9It#GxWL=w%e@tW}njmyB5L?%2*==Rnt?EPku=mSoN)GR4bk9nvT7)Fm zEwbvT-kHew2Z4|~)8CHor)&lV2k+hyD(qmiXjp>Z4JQ_QScdE5t_OZ8Y&w!9e1C6w zOKwHU!eOD+Vxo`GO#Fsr={Ik7I1i(A(i%6#3h>dfQ4KX_o^_j@2YG6rn*&;!xDVzX z_OKr%-df58;TtZdi{}O!J)FzZ^+uP(A>C5)oqO7>>m8wwDi65$4)@xD)1@zx`B8bi z_jvH#m;Tk`vnbY~Gjdf6!V1dx`;UKrA%8E1zh8vEBg5ZO@$Vhs-*!W)et-%B3whfF znI*7#jZetzS8QZ~)>>r4$4D;I*5k~U|0spGYhjtM(6B#G)m*K_fy|MWhd{yo3@~t* z8-MJLT)5GH_2;QAe~K7O{PPKWhYCF@57K76*!WRI-em)6G4OMI%bEl7U0f=G;P`cf z9s)2zKtE^x3(}(hl}XqH1y%q^0PJyWo-mCTF!~K{efy*e;!XH)-HC3GJt@Z-df~MY zx_~1&r{@6r62h3_d29OXR}Z@U5R`v2*FUyPil6yZIA7&T3WR4%CpP8v27nti$r206 zt8&IaJZW`YPnf=&rSm=i$`@Rs^A_2Xw2GZl!uiP5Pgji}*B%DOhL)C)3oYG_0gX|o zt9vdLf1ReDMrg|+O`T#P07I^CEkGvQ1{vNx!wON4H=Z#l#Vt4_x-b3ku zr(o_6S(^cqx48V$Xr||9BT?qbF<`VmjeMw{0~G_5L||qfedC~k@$(dM>NGqL5F4Tr z#NRW$tyB0}KGR<#tBsU9+9EOJeFg^_71bo~>X8NzdgDLYv zak~;smm#qr!0;#K1v6#WX*!stTkGPqeRM0O3Px$V?dv@8?HZu|b03mzk5UfgT5+5T z^?A3T&kIVwdZ-KX0$Y+;lBn0=+{Y=tp8#4>Dsc^A4CYahQ_J>9D-YmR>f`KA29QQJ z<@6aZ(XlqH-rb@$Vug-{UK8>Az7_AAFp0#pZ66UZ+Nh!AkI)%^+TMNYMjCN;;BGS5 zT`J2DuC!uLx|e=1dxeUv4=u18N9Y0qS2Qz*s?G_xjSq#eew*Q+H)d*5A=wG1UbHgH zS9hZA80aLhIu*p{>zsn7_Db^3v3DuZ^jZ|DCkp3T$$YGOt2u&vRaiOZ%)z^OIgf8< zQz4>-riB*ib>_9Y8DVVh$!!P9oB6Y-v2fS%)7issTM8Y9?Q1O3!d_bgPLynhl8=DbJ?utIlw7~ZpRZ_FyPVs@IrV%Uuuo`f z5?(5|RMgb8yFc%{hhjzTvQ2kD!2QTF`<}A|n3R(OI_=)cvjk0q`V7(=ebH%xTFg>r zWQ!A$&>(QQ)FUq{Zo2(?jMmz`bUPVu>=REhJj!C1BmKo{KDAl!w>X}P2X(m!4@*dX z2YQk`RNeE8OMDkzT=FO!(V*ztQnSyGVzL?v!45h$&Geuq1dpG7d7Vv*NkbS$#Kd)p zXBfo1=wDb@9t~lzI>G=|`f|mk=5B9kyJi?CP26hK8Ll0&zb4JEY zyj;G#p(k|;n>EH<Dzm5Hz7eMG_b z=0Ro6nCr-Y2k*utdb89U{#b58;zMcXC$X?H57=MLg}{r&sGkQ{Jnd4?&8%}3Sq zxc2@_MYgag1 zcN;_i-lDb2dx{#64sVnb&}>K@WUM3eK3%1{df$MmRjOz^=WE>W6iylOZm)N5t#P7+ zv{e~|U=;@irkI__7764GUOPE7*BkYj$`tczyDi4$hJ+tFt&BUN3KPO1i zkC;WoejN){7YZ~Bp61J{~%&$H6Shk@5y^*ye?EV zpnEl>8zo|I&kXvYrU}Z9iSo#g3sC1@6HU32FJI_=$$uC#D=j`|FR|1{<<+9uQ&im{ zl&?mkp|fFP_jj8e2k0|~g)zWJ^~_aHVEfsfNiBw`kXKTrt~FD zI?ddqKp+1w;$|uzTPDmB_z*D04=QgJW|?UMJU3(dE>Shk?FGYaqPd7t&Sy?fcp4dg z_DfcSX{48bLZ14|U*>bwK*U-#uHKTj>(fcPt`qd?;QS7FF= zk(NHR`EIT@BM2X|Espz)EG zxYDrZwHz`74=Ut2+?zSG{Mr=ntyt6?@x1yTVI?g*o<;H&=``hXXxugltx|%=S}QVIt__3?+dCKWY`D6l zx+cM?(IiWs3!K+*MokhS(4en*qR_6Ae27BMP zAxtIpr(Qs0_BhsO_6|69I6HpXrUn19*^`q4R<0kXStqZwqewi`uiS+gk+Z{zfprT^ zsN=NHT%fk3-JmZ2R`hl7IArIxyouMLGr<%Db5TvPAL(`vHt&$n(LiimG?slse>?3`UYFB8uLk?zj`3$^^}nvh#GsLca%3sZnFL*ty1NVvg7#r_T)U~d#a_bFe2&%hkuA}H%g|P zz7qOT!2^uD1Rg(3m_(jqU*6`osM)@N_?=!f3{C36kj6_bu3zs{v7oGxXH_FMtFyPL zU#a&K$Y>W@OpJSwaT1KBU&HY0eaClpT!DhjqOm^)&7AFPqQQoZZuieClBRDQTywrvz zW31rODp#uW6~=7Jwk$^~G?TnWL09P@mLO^*0Yrx+w_Ec8;)Q}^Qzp@YuDc`3NCybU z^ZmcEbmm_oihoedMO=k|1=fYI3LJ8kEnM$%?uw1nR0&ekR;DU< z=D;&=fwgs2tklZQ1!3gDapD-uYvO9LHwRY|1;3FQE_MhN3FUESHm=BxH+bxQm7;>9 z+)|Tch^Lc@=7PR97U#eCPWJu&f*E5{<7CxsVGO)G<RVDRJ=7U=K>rx^g}F??0cl10+z)X)wH;NG{t`L|8+;JNy$HB zc&~FfUeectr8ng5RDe)3PF*#+#^6u^UU1iI#aU+)DM#;^VBZ*mypxM8y9ZzVSf?*G<*+A{j~01TI6mO2etC)K2eR?gBF5Woonj|`~frOFnBy( zzdJZECKi166uI$LKG&~%;&`wZg4J5hL?zClyi z!j^W{@2Y~uOc{FZ30H9VX-J!$8GT9DZb`WOZs)fX^{NPuj8(tyU5lqPU$cIvN{Ni? zK?I6cU9WY2bt<70szcsXi1n*kC?KxG{!p?VI`N=}?$>aJ-VIx4abmJHDnJ>EHk3Qw z;ySC1MUWAODtC~Y`uTj%JwWp5F#5u1p-}2DKfJf`p_0e!S=4|@SZTO_(bUgVo`l8H zksr>43~lR$INGJ93gMgspTvXQ3@gUQ7vS16Umb}KojQ<3DK(~9v-4JTRKj(p%NemG zv4+qrAbFBt&*ESx?Jg058r}~8r3ajB0K3qy2b5dzr z9$fE*ut~%w*Eq^j%_fr=0@-e06MOTdP`%g!NxzHvcz_FPJyHMQ+IQw+YCV{9wJS6q z=8czO`dOSkKYcXm@#F!Ps$@5zp*Ps>JAD81-8VkY_mppP7C0#!5x!hLzMJq4ByMya z5lmkhQ6_Nu9*Hx5q2vsqlUI1Y#YxH;2EURLW)?(J{hO4D6|(cHGP?c0F(g|6K)u*5 z$td>AG|pl%pvH{3or!xh0#NW zn=%gWSLSw93x|J8yqobE@f%$|MU$JD7+Mxiit$1~h3G9pp;k_>K=&qS86yw7xQmQ1 zMe7<TKh+m*O zWf?82--umqt8&zX`sc_$gqO+XYBapg~UDMnEeLi?cZ3;$;xWm5FKGwLAqnV+MH z^_8z%{t>@7Y3_1&DW9cu$Quzqjfpmb&(dj`p6N%+*A`Rvmvu(G^lLr70M0gY3_VV* zx;WljD9qTFU5!|_Eif&zpZ*dYX{^vxqQAD!KxHxA?;{&L3ij?`lCKsQLK8Rc6<9BM zDou8FtRIjGDjN#2zZ`TBp5$!a{omt_{%LnnU<7#yah|?CXomph3=!!0@KS0^B0@ec zdKGzklW>t`fr0zqwRApq#gh@bP3_JCR&z(rA581Ei*#bG%2hu_3wMV6UNc|C_p4Rd zK^gufMlo(bBx^PoU)UGy6?JTw>2DsI{)wPj<_RAuum16FvlaKT^Uz{_$Cx@#vRL_m zabpg699y$)&?jr?88(1BPXCq9>?_RE^nN0hw}o~bXnp4;kczq)585uQY&z?vl5P9Q zT0G}0&&7?aUj$mU*0o!f(b2ywTDvHP*w5^;)EFSD(PFY@j50D+(#e@;P=#D4b+!<$#Q7d?+1)FiV(zv^Yc% zMOfCuEnAWnaMfb*Ya1xMC?!L*iDfAM(S6DFb5Y4$O~}EVgH8&Yc)J_lXZ_-q0ziS1 zi1GQdCNCChyV=|t)t}}j8|YRF)7VgY`&SJdJFGZ?i;u0Vo?fx&U5vmP{&KLy9B0_A z77gTZGq)*{$rUfD9n4Dl`iSk@=Eev8$O~{Ci$fe#@^i_wGq*=eu)smZVax=lWl_cQ2wlUBoY~53#5nzTQ>Q*Ss zB8nb6wf`XRU>rJom3qj;kq`F@em{9$CVe)}Nh$r3_`*Stg>}!U=wy4jc_@ZH#-Cr_ zOU}nu@AhZ)Nfq|9chL!erru{*Jq^Nd#0~cxfn3Dph;KqK8U5oU;`jLx66jGD{o1!F zv4!_=JDZ%_0Ht=+vnnUu8JbtWowv2Oa38v`xgb~W)pV=zO;Lt`gIu!S&FZSN!kqP7 zxh*&=-CX?lgo%!VmWF5thi)xptMJERVYZkzhuC9CoT)D)y4b1rgZbFx*B=n~?Wybk z30eREqyD-s>+nQcWcK}Y%|D}*d#W?jT~0rfF5tKz71t5F-A!L z8oGCFZDV>w(m)wH?h^E%BFe-stEjBVz;H_-eT-k-<=J+CNxf`#hF9GvB9U=LnQ}9T zTbFWD8nq9-U!t5XbhjGB+()gh7F?eyL~E5sKFHh1vpQHq^bC(LcXa4elq$%%c9}a; zu)XR6eci7^TD$eVKbpVw6--(jpiY|mWqb<>LhUPwE8LNWrZ<>&G&Bm$3-)9rF*ArS zyB~fmz8Qzi3dT| zvs)(NS=S9cFDbj5&jk)|89FXFzNmKqc%6x%NmZg&+otm33u-&n<)w$!J2CEzqMdDE ziaL5&6}kFlg-aze5dMMXXpNc^(;b@P@LN`6r1a7o1|5yAb&+u^XJJCIS-XFJ0Xx;+ zhw^blw+vD+*z^1!B2PGO=I-hFW($;*V0Tmq(NnQu=GU-lF0~7GYe;^Fy|5P+0^_>8 zw~)v}vgPQ28%7YVI=6VZw@hMd0QupcaL3=@;;aRjj<4nul<2c4RR1X`T5ttkxJWb- zA|q}b-#BToc^lCpyd4G;YjhWUi&v$1R55dg*h&@Rl-dz0kJ_N2n17l@efGtUe2mY8 zeOTST*>GXjkh_{?Z{6_GUdNKD%1w*nTR6Xj?_cs7>er*9%yq&LJ#N0co}0nEEDyq* z(V0<3?*2gNg5L$WryJumJ)xLJIJ@1UJMG(&@Z?rC!Wd=OPWM`V+SHWqSQ4D79^Ag@ zA8&M^h%0qd`zrp?XhqZ(2lbi2Xt+-DXvgnz?aOue?YcFWXl0oyC6J3;bjNB$1LJGH z)|NL{lms`u+w(~xtXA^S9(L19MED~+qHal6GtNh-*uw{F91~n;v^TitY>V|vn3xzP`YlFB#f z=r2D{)i1Li%&?_d?sP!{cVuwtviQ3ltvJYI$BtN^EQDnPoTBy7)WXFW>*wr^u5yC) zL}AowBI_1)(PvBC+!iq@nJ!_CeI?2I`*od2e|oc_+_m-IxL#clwx1K>Fx{`i()brC6=X51B?7)7g$<7T%m3!evEx7I@rF%) z?xGB}_)C@y_G!ExU;I)rF`w%K)-jZO2FL&5qs@ zatZdVR!QHtxZ3iPgejw5@QYJ@ zGWt1LR&z#N2rFh2g=^&;%Q)&0-Uc{)Bs_&AZ_u;a6To!UFW57&>!p>WyyaE!6{4^h zB<)+T1w62})Zs;1fO37dtZ}Y3to{W?R>2=OfDMn!?U>l29_Aftc{pSgX(lbn>UE7b z%70y4&hA+lHFK(A&Dn_3EePXAUIWf3lR3 zlvMELCSW9nk1h4V{2(fCyI%@*tV}XeVw@drqh^IITO|4K7>#Xyn^~yvgmR@;rM()v zZ{CHlRB_{+`Pe`dxY_7$)3l@Qcdvd}6EoH%Eco4b3@)bqd8RVMLcj{g`7E}*-t>oU zr9)|rL(vsK2KF3HUb$OtXRN$xoTUlGryv%H=|gQn^=trsOWFMpddooR_=NRp&Y*P~ zWO8LT-siv;{id?`@NJT)`7tDP;@d-!rSZ#Rq18~#pRb2z(f^h&1F@+ z`A3EFMK=%FXq}0zO&Ox$;1+N{4}HT1``S)^%>t{Mu7v>uypCc zg&!nKJ5t9HI+dkJiEH}Ba&~pL1+U&%gBx4k>J*Et#TZq_VBX)*95Oi3O^4pj^bw@N z(dP&C)hu$oz^1%Xm6=n>m$Vexo$<3zD6NN-J=XZOn(UV3LZNKWq)5dcz59+0s4PzV zZL5pfVUwy-v#&IB z@K-|o-6LRg1 zgID_;ou|K#egh7nH^G9LKXmp#ALtka0&qy^P^UrAQ_lC!;QRZFBvQPz9^qp7nuK{* z++ziw!=QK+P>1$6mKz~nLa#Fe-;RRyNXDbknZog2NX`5bZ{ zgLN&G-?ZxcAe>y}M;?A}RZ)YwXboEP<$2*4TG#Aq3Tp~YtU@cKvXr#Lg`Z6pN^$0^ zc5i|NexCXxClMkPxhn$CAeF3;Tr2z9dDfyCZ)7ySkbHc5#M_0 zP2XO8gl>!B-bl&k!oGSE$kQSb?<3-pN#983PWE zbk1!WIW!TMoh*p9)~q^Du1p#vSGb6nOV zBwOx$%khucKbNu51hzRITs+SeH2!$?uEdL7WW zO39*h;klYw#_zOt_=fw%={hOFq5A3s_PO!p|%W1|HrYW4@`nIzofAV?8U&R^6{eDAHbt zlnE+((5&+D$R2k$I?3~%GrF?GRHjzcG{O_9!dXFh zQ;ZwSis6`!H>Uc7gaDgqz^NeauO%SbE*dm9c?8Mt;dQ0TFO{4CBT^sirPP(#(mulK z{2JB*mC3JR>nvT=;A)skMFrG7hj*|sxsC*%In`<`cJ9_%*vK85|T zRho&`ysW|9R-gG5dbaPKIRRIgLFC$UDNnml^p8TFB4N7fU(m}{J#fVPkD|Y)Kkz;H zZ|uEiR8woa_lwKrLTM4{eJRqLG--i6ihzKC(tAXtMx;xCNS4z3k}5S)BQ?^C5F~*h zARvSyMIb>$dIACwLOgTtefE2v_uc2idB=Ii9_NhVHwI&7jxq09?yLN-|Iax09~{3i z91iHdHUJ7Tq0E$1JG16yw(pw~4Z9V~^2)NS#8qDtyR`JGW6&g}twP4_+ho8n{a^To{~J?d7* zILE|4s4PI(1N5MUo^(}<==~^_;XT=xu2LU@Sl|e~OK{(Vk~GGMeWAG!yJ4J?kdb^@ z0>+#ZF<#wW-gB*j^oKFqJabxIG1XH;emEH5b~@qt0bsKD<#%gbb#|PB-@S(~9IP3} zMjZH(C@sqSWhTMdE7GQaBVz%}oJVt4>us%&<*|QIqs3}KDwRS&AJ0|9#y-EL!Zw7Oby?b~ z{5}G}KlUhA<=pLG%fL^Ogm<5>YPWZB*C0K-Xmn5a)Y=N+){FKuJHm9DXboESVufH} zRb1hU%;;D$a2-XE-w=M~Fm1zzTKb(-b^m8bmZ;zKpQ34*Mu1a*+1X`m3yiFE2LAR| zXEa`R8Ve?dz7^6n^s{seE;Cc_asxwH9@~z|Qa4joQf#?+VsQcAi}_M$1*vF5EHnwD zFOWuFkZ}GZEPF*}Ou5B5mopmU7;|m>OaDzC2}DRyUU+&mT_KMI_;eUbX(#msVD)hg zRYpSb6;A9xrQ8hcY4g&pTL1S73-z+Z3iH~U;R2A%&Fj7WK!1Z~1mJHdNW7k8CSfkO zuP0qkmzupsK*m8t)sbAZ6GE}jjQUgm0VoUjaur+(pIqf)uw20Vlx4+mN>VT_?@Zg@ z#{TXcnc?N@hcypAJ76ZxCN;@pwSbxFcDbuVuPN!A0k&L2E1M~l2-*-TYy&`fHq4_;-k2OP2r?rYD^aDVN{HWwe%L<3yGU}0W4 z&cqQFVJy}u+NQE`PJ!eVkCAXp(YjhFV+68H<&RXYpeWI~HkVQO`2tuSmkTWuoYTXi zr%D$|4OIxn&zwgnQHcX>OPmO|C*&pElbFpX5noHdqGE5Ex1K~i==VpWeZypD(%07X zw5W06<`rO1)_9U&p&8EEPAb0F{nfNbZ=M2Myli>LzDd>n&HEHeRT|pIwk|QK%7`;Q z+PZ8$n`VsHx1OJfB#+LKxN?u9mPa9pg)Ar$%YFG$!|nF`tEo4Be{#G{3;)oT_W7i%aE0ez#P zCP(`P9`KlK`h}4(dBU>twPA9Vd-c8v|C*)^j_fm>?N+r%xVN(kNOY{h(XcwqT361*@=1zqTuVg(a|LyWrmQ$}AHsAXj_-IBJZ+HcdAs+e}7@ z)8d_IFP2e>*xzZNLjhFldgtG??Fxj|bj3_)BqmAJDE^Vyy{RsZ;6Po}^H3#@w%D&9 z)vEM*8+X*r^4G*}b7+oG!lR%Ei0CuXB>GBxa6Jf}yZR{!6s-(ak4XcuTEvG_52l0_ z-OMl66uMD2mE&|Sb+@b=kC+E7{Xw%(>|0UB&TA1K1Q#}G54Go4YKR!N9TW9+`-XWE zs)~c|zwZ2$BD^LW?)OOejSB8#)bNrqFm}t?V_~$9#DwLm0^4*Pv*Mi;=1F#j<-{!$rhRW6U`?N-^NL!ohtfV z^{BQ?^nY}xFL)ErbFUd{C@-dB?6ap8hU$aZkJ$AVL3C}mOdlpIBvX|s@!eemkk$nJ>oh-MRoN6g@lmBw6g2F$ZewABiCM){oP!=uvK6Qck zRtt5C?8ZbvNiy!Ljsk~Qs!h^_5_~K~SRCS5&w9z9SgCE%tenhbf^%< zg;VoXvq{BEj$F3pnVu$4YzPS z@k%^k^=I>Wa{LA5W2X3HMLR3ProM@%xB~VqU~NJ*MH6-|+bv*0=Uw}jt-)WTjgNA* zJ~Xl!JX(=^AH0MC+ZsJ5xHW;L8irq6e+X2+=3|v3`8;=OHL)fp+gaBYyxXfNI2ITl zcLf{T|LKmNf9g=v9irU3HEy5Pyg2`?E~z&o4feh?Hj8G$bR0{JvQn{{ui7RdCQz2A zDgqVXD&F#tvB*#Ag8z%P%(1dJ0f{iQSZ}ECc6y6#izz_Tel_M?p?!3#b&dQ?NZ`v)X z{Y9q?RMofQE92^^e3lJe#c~C_f8S8!GmjcI+avg(1q^-H(cg#`rj_|V2Tm_EgUdTA zc=I!|T=HSNW?^OyKfZ1T|d_nS)J?Sgfqgr_*`F0pOwDh~w>zJ}d7rGg( zNVltDb`uLpo53I2YS_;4%p7{6N!vpBoMNGg=7L=i4bksAJr~fLYvk%TSi!%DYBYu} zJYN@!3~PG4{rT@0@5t>)txZVQWRTi@=>Q z8UNpLH8EAA%CYO)Wk+q(5gP}sg`HR5HddIKs3r&bM!`PsrFU*MW2+rED<*V6!U)Ze z2qY-_{`A@;DgE7|CS@tT`5Ai54}_|vLAN2ZhsWu23W_nu4|{yGT%B+V=qx`@mmB;3 zFGuZ=B|m?Qw{C%eOJvv*=rLIL>sV>mCduLtn&Cl+{}~_7q4*oEO-*T$MaBm2 zJLl{>fl{GUJ5I^yP-0|ccF1zt-}HN1pNAm#N()0~5Jn$gh52PfZNMya!<(bH7z73< z%>{$FHnSTggYcnMDD^^F7HAOC^*pLlpX()*K1DG%{M8MTX+e>yDaGhn7wC_&8e`H+ z$QwcxS-keMK6(Tkpk@gvFsZy^WtD_BM>S_;EnL}^EMgF|vrjh-hmJSjkZxWJMC_xk zG;7TrS=kbEWOwFVz7wrBH`cEI-++zJuNr2^h&w!dR-QWUnPBJ2nO8;|Saw%iXV3eYX4-yUD7cqWaPZWxqHN>^mG4l20_uZaqV+iC z4ghH7F7Z;tO{zvT-EU=y39i(4ESk3rXr0F1?R#64&~h!CCJ}Nqo4hj_cv3en(WPM` zv`)v6Dl8aUGTl7iQM&&b&!uT7ms42iE{zLH4odNetk@;!v=V*Iu5bH=C*DmdKoFBM zEwdg>6=v5-!3P%y<)l2D!%nocrM3)~LFW+qL_IlpaNp9!13#=kg$Z=&*)?61*PJ`n-2&E6%ZwuzH{GE-JxtWw+reXO0zTQXNy12e<2$-7}s6(^HI z!hQDkH3vsV+I0&ej24s4Wg=UBjpr)|svV;SQLG9*UKX5DA2Q6yFw7ZRy%IOJr+To; z-jP;)Voyy^R6@Ab(Vi(bf0i7$(J*cw{ zNTi#t>?R!_^&y!M|LCDY`yirdeELNnJJ)lRw3=m@Q%}6BB<;qsE-$`UyNTuxu&MJ$ zq31V>1t!0*ALy`dt3cWW$a9)C&1fDL-%HO^#7Dc=W#;ZxX?!TK`$nAI@sQWe3=Aq< zSdkk-q*2Xf2zO&kCy+zLDYg2A7Ayw?f8;7a^C6u;xDhv~$Y**AKFCW^^7Pv+)HWQF zPp_%w8z;hfYW3|*mw-|tRtoOkr?gU}ytUX#sPG^6L1+2=ngJ3!0=EXu!fGuo9 zD+s4jxpF>e^t#0hA4U82y|;^lj|%MUnhUQTKJTiyP-UH~CNj4cQ8S{m4r|3cwW&>S zV(=nVDQ&&L%ivGyiN1_Y#$)-Li&>4;f$pxEBV*(Ec++O;AQfua4(M>PZMD#)jpMp` z`3I3F^LgS){Igfg!$)ndt|`o~m)eeBZD}-ifHgW5;5gAd=eOQ&d_M4NgSF24n=R>g z6`Wf49E|*A`p#w9=K8t}MM2S%LTUrUm*H4fyE*_0}BbY;w;J2IYvsa-hU;9*=+y zTLFIh=|7p|Sbv@A*E;=r3VyvUzrF>(zL~#vgkL-7uejh>{PZh2{1rw2|0YKmd_c9! zmGnpGrlzB4*&9!z6^BWpzZ zUj^Tr`ESTI|9AWb5OP$=Vb9xk8mT&J5E$#PPbDD*qds;@7F5DSuVs=!33fPFCR$)A zOz>%1jZf9a4SpJWVD2?h-Au<)kB1_PiVWt-{-Wx8+?vQ$n?1z_*_nzMy;r)_St9B) zI#QWat!!tpn3*;g?7UVKwk;xf&+>Kll3JEK_tef&Rx|82#ba5 zSBeL7o)`|7Z)h*ZGe7GxVom{{rJlVtQM(f=SLAf7SVQkB#pcI^pVyQS4tg= z8wWj4zemCMiYiZq8c^d2x&WLR4+!)S8n0;neR@(;EyHzJ7Uy=Ix?p~1%_afKpto&U z&QbnoQ&meP3hmI*Q5?u-)dh9JcY*qxt#Si-1G7kPmS&x0qRZ08g4v$9JsW=0t_=tH zveBj0?!ZVUR!PV<>l^9X%TUYihz9HR-qC;*hQAK^LuNd6R?^|+Onno_m3|wX2fw@| zh%c@00XjZL_JMDZoA=bACPG2`@0x_Z>5y;Zl?$s<{3H0;J-IKnW95t<%;vrpNPu?I ziv+2i>ex~T5<^g|>z%DVWi%(V?x~%eY1XBSwCCH8Ld--z&!2i6qT#s33C_%`Xm3KW zYrWNruRjj2VELqmsSau4?9cnZY9?tqnwNiD4p8fERpPs+6qhEN5h^>f&c87RQ66br zC`}bM^hzyxUIOKde>Yx}P<%vdhK7BMy(V4Xbf2yNeczoFM9BFw)=8d$m8GzEEH9 znY1{!C?nP0UVJO*{GYLGnPzH@JZYMxsSaOW%--X4cp3Zq6t2i5GgdaB$Rt~W|7PKp zRjpA!!;2{o3JWVF%eXWBnlr*0R10NrHd4~Kiz#TCArs}42OSkM#N)sXFd z`kau9X3G!gf?Nhin$1P7DE8O0s^PJqGbJJ3(`ecjV^s|VY;|MdV z28oIIlZo_@W_QQzrW5Ky>uU#v%RSgg>F;^@ z`(jb{Z!Z^ejAVd1I7LFQF?#Ar|AKBB(|_s7iH1=jP&0NgIAN1|g#~zw2^4(bC$^3Vu+@hX)HDd6nW;Y;+NeN9>I7>J_tRtaV zE<}kS%(WS9b>6mi5jhx`59xOb4Bl?w=H?a_uKRsXI089aqEbN=7uT)TwUfDFput_( zO>>ak!YH`cOw8%!L^O&-n8-ShPWUN3vGbFAYdG>P6IuP~dtQ_hLc4|L`ICviMeLG6 z8A3DJ&@T$fNsBh027?v8xBUICabaD1u?W4{I-~0B*V;-%6U8U%cRZfY%}qPhD~yw@ z3Q$cZ``vZC6`1PAh)|0irDAZ`QL|rUx7v@2A5V{NiLpkh($#5Wz`~&L>6b);6wX?? zh`Ba)jkf?2fz3|Q3W-9&*zVRQ5{75pQ7WOiwd+l1TX#doiD_FLW5T+lDFYt#-MnzU zxw0-a)U!N)FDoSC^s~VQLg{10!zaEYYILG;o%&RG%>ptOFv?J*w#CssfD$Pye8zB! zu1Y!Tb5*9GQd?e@=d(iCXvrk{-aKvCWXf@eUv%;5Z?~NnJM=Fkd-Poz_P=ubOVy~N za+YJ(qz6xr3JNz93Hb4ypNz@OdYGS__3%WKZhVaR$s}Y%2(_3;9omg=(Uo2=A#7rN zu*wvUM5^h{$vW`ml~Yr5|M+6@j>$*gp?n)N$NsU3+hC2-C1)SOe2JMv$q7VuV|xzi zK`dKpDQ@PmvA+EX(Pv0zzmA;gGq`~jIaV*>=$7yrqZ;Mu7}wh!7MKirADKSR(R)oi zU=^_?3|kYG6k6Cd?zOaGiMw0qw2jfjp&g0h>79wMyx#Q+^?$yQeD0lBmZM>3DEqEe zL2WKVZEMDh76k=-aLT8vHc+871~UBd-~YAue2M95;h90HSE6XN1!nahqI{I4!)%&3 zHMnmsJw{KIwlmWw$UwP=Radkf8YMK>nE4yMnM5`!wTzwjJ)VAn_GV~&tPNGk(a4{P z-aY7+oetl&g*Ef#U>`S?+2&goI@+0rY|V9An(QdlXZWnQ#s$=v`w>*$I&MpZE-I`` ztcmFDPaynO{MivYl<5-kE}yTs$wxKx8`I5|bNyo(bHx>2qk8Rba~lzwY9Xcco4z{Qe*1`EFY~d(%28_9SHxl%*Zg^DCUPUpjvZ+OxVeM6DJ&|u z{sMjbI?^OM+aS)m5(5fqkvzx}v6Gy1yjK|RQ5%}^Sv9UP#U;#=gVrH)UU5e{Dk5z(~^&^`l+dKkGeU>gVbm^w2 zD0R$Phss2950^6%=S79|U&m@w&-IVKUAfS=DD*KkCC9e&dwtGyz*8xf2aS)IdB5-% z%f?R!v1l=@>@<1}^~Q&#OVTUs_%2u`1%3&+EFpU@Is0~NcVS^VYr<msi z(d2SZYisx_yQfkk1N>La7>_MSN_=7;svV&}>I{pN#3!g%t-}_v3oC{bfc%q%W`qk{)K2dcz0x#&1%=N5 ztUu)XZ3F41(H7Wflg=x)u~>ikm9#T>&qX1~MOx2a?M-Rd?8Ppw=qCkTSe;Y>7w723 zT>^vRMpU)6)F_%PpN#dzguBU&Lm8y?nKH1MBxy`6SPbXv<|Mxo+v}`B5Z1!I?1G-_ zT!0kn3pr_g*tlO!hVsn3yYK6n&Xa;puwa&dP?A<5yrEW&i!~1J^r}Q?oM!3$NgD%V z@Fuap5dO=^)H%$%&GdN~c_~R9*pf4Q^;Bu5{>%O`fZfztgqaW8C&T+5{G{Jig%XDA zHYJoU&YQlWS|o%F*Nj-*#l~;RxYsx-42%UbCwA~!rBb9W@(rUK6T__k76) zh|I&+z&83RK^reqZUr_Dsw|+dlb!V}wta!Xu3gwb+dhKZvw8^2TT`*~u#36CQ&W$1 zC>UIm7$~f2)mIB_Lr|pwkGvdx;hOkr%BYIk>r-2;R-J3ZjoP#MvD(}Xv`(uk+ivej z>50A@=9pgp*|P*H@RIy}01}{|r$txKBlxIm+q0z4f+zjgXt?(@R;1y9jrN z+xTO=!i!`9E~%UwH}S`_xvZWC>y$+p zIR^x?6A{Ltrc?^g8I$3X*^iv7r2utoxACxipLN@`a8ZS=a?E8?&+kzeqKJHsOZ|!U zQ5P5!DCTCRL{uZFPeF)m5RXTlf$!oLrE|$dS|ia)Fe;l2O+sC2IZ;Xyy&i2*w7ms( zT7%z&@O&Gq^(huh3M=eqo(+uWhew(+w0LsQtUlq` zw);c|K4bq;PatX%`FmF=DV58J_LOQwI!e{M3g^{(^@Kxgg*|$7dWY6SBAl6gH%l=E|nBTorEsU6}AFp0(pN?XiTLr zT08sB6Y<#BE3_He!Nx5`RhF6|8%nZJY&N1Z>)U7<;yN*(E2d84zQ==8-o7#dm zJ3Xr^H-2CIv^Y2B_v8*$3qwu`i(^Q-H?)6v)UKbn@AH6apK_FElihL^2p3xN`h1ebOpbAc}G!*r9JoZa9J#V{8b~}6ZRbM zeoZ!2`o?{#eZ(h>pFUUYy+fXFQ(vo0Y9-9kJ-q1z3+5<5KOoR$OvS8>WI(bGHRCFDnq1dq#@m{&@eY#^rA9fe&m#k4NAvobW~Qh!v|#cU?id+;6!Cr7ujE^g z-*{ckl z^l67rLty z9Y;beso<j_7F5*3<6D7~U9 zP>ukp5<5H@C)Q|}2Ii!4_|Fjyn~70eG^@kES^-;gAyP&9yU2F6;o)QpR{M?CTs!S? z$|J}0cy%S#fr^FC24PP_ukOYt0YR9|Ai_>`*E>p8(Iu-I<6L~I!IxP;$|EeeR zRc!X9sAR84I4=|jn48Ix=%q2L+Wg=#)tan;O4D4@weNfMr?NJSiY@Z}Gi3r3MGnWs zq5(gdgef3iFU?wFjQ7m&8&}a~Y){JjK!-U0R5BZp_2rsFw$FXo0}8)jcrK^s%MWJZ zE7wA$j5fYk-*-2xEzu;57a>I{7C5_uU=ti$>@xuJ2e@g-ROQIt#403O`C zS_sirIh+h$P}E^}+LW6cD%|Y2!E=?yd18#jeLH=1kRA_AL1@5Xq?r^o$Q+h<_-E@R z(f&;fO^I6LM45i!1EhGOusMT~?35*rW~G$e>vJEFza5}1F3$Nd`1T)P=5!pcnIF+> zSb>6mGEFJ|fm`b`>z$2zn(Yo&saj#bql2@p>hBVd{t#%R(v^EI3GLVwO!sH8s*1@K za0}p;wfoQ^Gcr_ut>yChTvlrC@j!ojO4(&Hg4gOLsr^t-;AV3mcNJyn68Vk2Z+M(f z65hN>;NhpoSE|@7NhyXZ<=)HI=yUugU0#q%AQ{O5Oak(x|UpRQ!WX06{!=Ln}&s)ftkx zytlxvC95*r*ky*W)nOiVRJ<0mVUF}!HUfF&>A4l!^^-KC<=)x7-*e=z?NNW<5H89R zetJ%+-aVk^+GsG?Tt~oCv2?)w+g&_K89eD&SaJR)q*a~%9BKMrlgR&4LHXZ2g!%na zt6j_%-G*}VZf_%BieLu2MZxs%{z1byA^$qE9H4@35o_fSHo3^GI_x^;lXSDX^?Z*- zwC`MN-tv2KYLKJJTz&Gj+&l2qZ+K%uP*Y`Li8KaAxxNtM|8UMx%T-r&eL!$fv!<#U z&3lUKtDCtsZ(40~T8p?2<|2^%AOV0y`S+G^2g62hS; zj(}2nwsuKHXUWLkrIaOZJ@NI$KMDwT>!Gi_gJE{qOUdNW=}c0Qj@?u_ES32#jrt0q z#ptJ2RxN*NF#YW0NK|~)mZ4x9k{VbjGt^utYl&vov#DuB+=&bw zKwSU^d{(5=FbZ8)I=vDeg`WPlX+rrh4!7%#Bi^0>^MqhIC@o#nM}oE2W?fIS51ghF z0|QHQn=J2TWXTwt6h7Uo%nv%Mc=DyA0%KGA;I8?BlaI~PATZ$U;A*0EX}grP$mC_bMrnxTcb3(S7`x?K^U zH$J&RzuZMxdk)qK;Vhf%Ix)NX+eciw3rC&Cu!i(LscOPHo46KK@q4b*iOiyfjh~ev zOV*5aKW?3XY>EErB&#U!_z{89w=_%ir;)*Z4p&G?Da|(XL3eP;EYoVPs93@}AaB;=u zIC@M5&GrgwwEa!^J0@x4tGY32q?%ZDk6?Z;IMXt+`7<%fziP?M*y?$PiHWkM>BH@6 z$L`k8KQuZvZSvgyOGQ;bz@2wLugs_9;*dw88!RX1T08>wIB8c$d-axd+C*l9O)_AJ z4U`3qlKdHRh{#FoW%wrGmrM|g<kMH#n%d@mbEdYE-qsN z_>h42a^<;v26uK_6IRO?HndC%NgmQx$(1YoxJ}!`paSDr$3cnCE^NqY1%qod>ffwq zNnLgnofSwQDv9wYt%Kt4Kx3zh_0I7nwji0|{>z6iA}Ol}W;~&%Dm%Jo@wO2hWtFs{ z{Q+0b$&96Y)Uf#nJEAed+j;NH7upS=u57XWz{!PXOdgBJ3R1^XdVEpm5RYfn zc9{^jn;W`mFtWuT@JvG*vIZW#5(YT@AxY_iJ`oFt5qt><^-8#vQS=Rp$kA*_vYg)~ zxVY(b^-XTIDgl#gC9=jt1&9sPB3WPXN0{|O(U+F4`X3&|!cCptUgK%2+^co($v>3t zjZRn?W~7#WAFoUn6`-W2MQPK2qoVtviGR}#rVeVLLUaWhS0(x{`emv9&l)Zi^cG+i zWA_g#Ut*UNW#4#O{s1M0kf-HRmFZSw3jy!NOBuT^li!WT`>{nKosX(aEK{``&>Xi4 zeQgl?hql=d^HV%`$~13C_rH}}^7|q^RH0?!JW_Qt_pN9oA=9VBKyB4LxT`!@wWWIs zhH`@&&XD6?0G|;^KM_Xdv+cl`nq#u>$>ag^N!k-UH?nQ>2k>HhHA=>a)cYTSV2{x6;N{ zK4UOQBDy+-*cWXReYH2mD>kexpHfM+E4VhEHbC&6Eqihe}25wxc^l^3O-)NAnMR6n(SmfkWdT`tCp4a}AL{Ys=$w3} zZF7ExubJ%Msa{4LE0(s;eP{B``lUNu6({a?I<@}rxSJGcZoMjNQU~jGeM}#I(ToWd zQZH+E?fi_Y5o-j+cZHLnv%{p~XzG=Dz-m`FHLb15glb-PT1WQd!t=RG&nST}yn-j+ z)3B=xuJ_hsZl~;|SBK}?aT$br$a9UzkKf+L17L8UcD3pJ3hxf-3MrB1AhSB&6C?Nf zq>Kt4oqf5Toyl;N?Bktn!@*7LVaN9nz^`8t@T0Lre*2>VaM>}u54ZRy4pQS>{eQOK zasN84_xOK9&GzqsYM=bDWcn?2c0)qnNIA`?lrJ~uu+qRdba{lo_?9B~o8Mpm$rT+9 z{pg&LEgeL#SgdOF|Dl6~CeqK1@K2%C%EX=&Z_CjEiZJHg0+4zZ;8EYj#vv3xw|^$^ zo>oBC;u*}B>UJ8IPfaG)EPxpqcIYQpeTkOU?CrzcP@hnLm8~4s0-x0k0a7-9`3sYj zw7Qn8=LRfA2Guddy_D!VD+b(&eow@wj%I?JUK|>*rK}cZmn+XZIyyqva}HalDX-G_ z6}Cy)590XCY;KcNZ8*7QU!P^s4i&BE^4pkCX#x3I{2=*LZw*lIK-dw1ua;;|1pVG( z8On6E!i?2N#0|yN8Xv*ub1uC|UnR8@VjwI)Vb{;Eo^%OE)=9XM7w|2md-gFzeXyZf zRUXZkHXO{R`kF#pV0ZlFY{LvRzimQl#iTNQ*jJ>^Yus6z?(PUi2Ouvc+Isva3iRmXS zp8!x7=|6z6Y-v6Jb^$+`p7lXUl9aVm=I<7CA$#Be-T%Oo{doxF0L5Z7VSUCWe-7kF zB+#SiZ2?B;#L8wT8OA`4aOvNd;9qkFN}bU%-&QIxLgCxl);l)4Vl{bS`nKTI^xh<3 z&-iukSBvlalS-5W9+G9#F^ex3&&mWbA$OjaA*>ju&U>j~ql zS*01Kw=!&vB}$E-PKy9>w?;hV8>AGuJO|Ws(u>&bU!gcvpbT8qSAd+M+F;L>ac~W-BDN2bBe4n zeO)Y6;6wHq8f2rq?Z5iydZ(()d&zwCJ+(=xkR2f0e>Pe9eJ!>aC46U>LoD7E^zr)= z8_kR^Lc(x-n za>+0WBjx~SB}9qk!xhWN5$5?E9hC(&wo86b6x79<|B-9^!PIG?RG!kLoMtdsodUbD ze^dR+jE#U4=2eBPs%=));FF+a=*+>#Zc^62SuL`fQ+i?`BvwjK+;_O%NQJka=u)K`5&Sv7xvf3R;QpLC{1#Vp1C`(%9voM0!fY) z^!&{7lF{yw|D~TyTbqHH)p$r37KPl?I0h6IbFy$?sb7EEKRE7r0*QY97YozRiT{QS zJLl6CjpQz~4xWYzxVz9_nx|iTh_auN=&0*Inf_r)vj!wi!2I$f$TM-e35o;^Iky!- zviazH=?oea;0ovS17HbIEM25@L-Z>3aZ?G+9Y1#m6k4^J&nR&(_tAdZ?5?E#wIu5B zu$B53XiUCZhpmt$Fr|F*L1DqHL>TQt3s1N@cbng=Qo&UUql47L^KA~9(4|!UZBhKA zI_zQB#6dU5;jr~Yi;%+~?(K~|4Ux%CFP)nI{;*k?@qKUT#~DLwSZfBpLV*E;-q27WyQ;`!2DRmf1W z<2J@Q#`;gD%8=>JsS8`D0`Vls4{osPPo@WpsldO7eXD^IaUDY&b!^2VbniR*SS+iD zVut!5wbbf$S}wE#VpL)|F}>LIrJY4!o0y$mfev#Z!=LK?WcuR&-Tx<3vo$67C)2%# zwatU5EhID03O@7mzXKxwzcalQB}I2{rWKGa=DZGH(EtlA4tUsMGELw_dLxRJxN=(9 zXp%RK-IXfc$q=Nd= zFCZRJ4WnN#AaQj>#^sUM4nA#dqQVqNykB#CLq2(+PkXxKsro|A{9k>`*FJUWBF31S zJ}5$y@Y96lYO>sYTetXFZ$c~c=1U`C7nab{1>J6~NPEQHRhs!754OkR?5;Uy1x_;) z2yUB}_y_ABE0W>b6BSaXd(?Z3Z%GPRiXY<2rk$dEWd`HvM=O0w&7jDH?dq&kqFp46p7I!U!N?;iK0-kI?) znZ+GyKcAPs5kAX@^-&8!ml7`!X518%8= zWmz_jiYMfOJNqE&mokC0#6B7K? zmKc9sQoYJDW?k)dt*+;f)x!lN@&O`Kqvg;UgF7_lpml6hwe9PCCC*a>kmT}qluok_s#s9Wab%&8Y1=DUmx%-1?P z!GN0e&9dd(cxOAD9{2q{#q0Q0VT1m5)TJPX*azi8)%;-US8*va!ca^SlYg`LdWE7u ziN%?l{EvN``fXyJ4YZ>O)u|?cOcg5^h~c0rCA8Ph$JTsxkm9(z{Kzx-Io|6fv*^XL zyf56auUU;hEI{VIwv8dX?N)t%EB-YvvbL!b%}o!0Zp#SU!&D?y_YChRiinO;T9)$ z(ZL@w`QP{kkF>`#v&_cX$aUkt<_nHa@8B}t21hQu&b zPfNg|)U$`trHH&)az&TRxtK8E2tDKY$$@5cqGOq_z;!1_!N_KU zUfz20r0p>4dY2aFIYKwjt*m&>*({54-RuQLBlhK1=$+hHRr%hP8fsbpGRd`-b1hVE zYQ$C?B(M_5nIp!Y_%&2F4K!%mQ;n6=^@7KS0+3i}$zU!5D%ZwWR z*c>4qZR-X(S+q$pbPJ|Q@-|VIySsY#u)RKHWk;+LP3P8kI4z5kKxj~)2~kYGODx|( zsbc320Q-0p3&I9y9fez2{CV<-V}FS9XG!Gp5WTf4NN_bgcbbaUg_rgYI| zc3p!{?jcHu41LCLeuhN<$)xd)O5jTj>=N()q{u~n)S6?II(#`AQ?T5im1C3G>mI0? z-!MRcn_NuO&hoajcQ&&#$wt^{o7ZAd&%myI)U@DCk9I5<=7pPPX1ubq!QU&@o}V5e zsMbMSHo_ckMqIHaH$mrD5^FSKs$_}qq>DCErXZPWuNh!(>mjg5F7x%G_z?F$GQ<|> zrt$9r?KiPflu=ZjLCHqdasg};NxP%IE$OhOem+!0AFqAZb@Su5Mpoq-iI`TO*ADO3 zC8F#|y8v5lDLDwsL-5L?ML0~>+;7|>U^(C)R7Yj+Rh?!(?<4ShGmm8(5PZE{k(^v} zVCSmt!qSkOc+4jl$RQW28GMZ_tY~GWon|8luYJstCaLMWDIaT(^d`UA34s~5JmTe< z>NjGWg4D{I=hvCFi0=)ofau&#=BUvo#90b58Npn_m_+ddrg82hWC}v51db$! z^;-x6{e3Ia4@`U#LTOoy+n^L~hns6lZwXYWi-}U2+Tp{^aTGiyE4Z3od!2YHg)9Dz z(t4vHa7%MueQ3YdD~>LMcSz@4b;!{W!FQ==1u9)yDKS{>NDIvw7RdVwf0WL$V*7UJ z&1A7h8ph~MY^u|c5ecEc!hF$7AdGo9HfRekhocT~dVLa3SAItd$eWJLdl=4f$tJ4% z*-%4|?Yrebf%+?y3SnFqqb#P(jxQl(t4tJ!Kir_!A{&97hpttDFdpwRII%%k(aMh+$VW+81Uio_24gT zeCtr@j#{0-fPaSt9I_MYRWuzN->pzpa74Vi1$T#D+G)m5Cg0@KFvf*l((YX5N?6i1 z0$K~VAdU3__sVhxp^Nt6%~$|2`MSzbLxM>zipZGx}Vdy-?yJWA}DA`RxrL7+ly9rnUg!IQA?>{J`&!~E1uIV;3b-gx! zx0MS!>V1^h?BaB)MsI`}Zc~*G$rmc{^J4d@gcm)x2j=$_UC+b2 z5$FVXhGj7*zH!4;4QDk{3_4$u^kH9f21j~LD2)@$QS|lYNCHv}=)N-Abgj7#WNah)A>8 zoY%4!9+3YCjvpXFK4KTYU#{sdfsNNj)V~O1|2$oUbPIaVs}uYDcxc&iv9F5fG_S2Y zP0e_U@5fP}A}fIwPH+I~WMBDf6?J%CxJT8f*=(~5`z+N`pTFtjAij@GhGSw5Sk5M|u$wArJ%vq)R73KtLb?g(Zaet$n`z?Rod! zGvAqa&OYz?=Im#N8HSmVthI8ld)@c{e_hwF(;j51hF77i#@kNQRwl{Z{S;SY#}Sl! zArjwlFd6O7;C;QYrc21h;Cy}Y-ht9Ma-!5{mwKMIeX$+We1zdhQs%c;I4!}C>4`}h zE%~FZZLN&t^bowDNb~CCO*#^Ak{IiX`WT8LfE89LWTw>+{(ZbJ5>FRY9PJr(Vo!*hVVoxYyA6i(fum zIZ7J0P1bNbm!#v@EAreb*kyakq;WobdEwiFS&dalC{72K`*P4`xi9_8p_ZkI>rC!& z`HVNiAmT6*<)6BDx`8gHC2|q{nPQZVb~YTv-i*C9iV_thA6Ziqz?kBr7oic=e~`tk zWECY#JgD$Wwi1!Lk(hjGNp#FsWzJC{ z+dA)VY3E-0uyp9pf*hBSN=s9J6}!|rgq-XNoKT-d@OV*r#5MK#-u}I(eH4{%n<`6L ztc9(OPbo5u7}e=}IhUS$HvPFnyD0>Mh!!3d{=mc(NCEG>=vb3a z1aX%Qq9_lkgCItmj7D=Z%qAYXUR(kdG*8=DOV>mmW;K*JZ@3AkcZE3>#4mBcy7kVF zexH-QF&WSxt_wdW-Oyuub97H3sCcbO&k4O7oX3OO$?+>M4K7;h%k{f7vLC+IS}@!_ zU}LJ4pJtkeB?(OrIm|Vvgw>&%Zc>Tf*l8lQJu{muuD`fS^1^l!Sy7R+Z3;dKt1f}Z^YqMzlgtm3Wf7KeBPL@n4ZrMTb&0rRqkt#t3Tg+>63ZJ zEw}WV&yA2|J-bm8i^(+K%qCGB0$x!VWK($w-_P}kC&^RqUXCAmFIA~3?eXT9CUTyT&WzmErr{G8F z_Dw3Q!v(^?hGxs5&H$adah>)t#2GN_a=WCf0;W=Qv@S#iz^~_8J(UFcdI|TJV6+#* z4?Wz)yB-ggA7veww@;>5txZ3|dq&`|CzU!i)mp%Ll4ma!RnH5wkMFtke$UJwur(Xm z%Yw6IW>80)5ML_}zptma!P476f5=IWG3JG$c`jOPCx#1&UAi{eEzV16ifz-PEF{q3 z4E1s9gr2AmhQA65HU)UM82rVv&Inz>=uq>!%61c6r{M6RiW%o=?_r;;?C0=_old!k zk&-3z>w{K-`;){Eg}ooEW*$dO)P`mFc?eNm+Q(0dC7hc!J2UGw!)IgDfd z?X7Ixs`8?>1C^J>-q|B_10_A`lbREOt}fSANuA0~_WP!M%O78dyH(Y=WPi)`1CbY6 z4@GR3m8C3x=-?&n^=vZ4b61zs=8Dp+e)>c@)2>q6W69gm^B|nrz0gNOOm}fYsX?F9 zCvCCe$`H;>sxq&2O~S!AVF+{LirWnyopHsp^>gygS`m)L zjfkSrLu|i)O#MpPb#q0xeORHzh?DoXQG4gD$3=ff5{w2(g4eKxU>}I}7t4p&6zrkE z_kbf!XIp!wbO3$q7t6?t+taBy{Z9-WI7NV9s9wFJI{nS_3qqJ58nk3I$9MEEmPd35 zbFfK-=@4?*zqStoo-u`(qc`|x*n{L$eR%o42cRv-@`~%%*gv7U^p6xEQLw|`(LLuF zcIiFyihwm3y^i^fDa$aS3WIOxr_61e$??QrMqS#Yq+@3pB`3cE6$I-DoA@~wbCZ*i;Hw|r5@lO4n#YN zF-D^1bo!vRz7D<4+4G6R@4R!yoqGi_UPDu7Cn>g*&lm_$ovsy+)@C@;U{RZGq7;4J zjbU)YLxP6XSn9AJNCb3<>C_tu@viv*k&;#3yw=yt7%a%~e<6Dz(a74Kfd ztGk~W!OMr37(1HJ@8|7jwc@tO*91Pw-~O_kv9fNVm}#;mRPHqVwB9ba-Fd4DtQ+z$ z!Oqq3HpfM->C+T)EeatMeRvaP*#dMgMU)3{R~9t90k-ac@@yK1@|MmZh6ztw{d!`) z_gCu5zZpxiW@Stk=r{^~XAsH$s(rhJQ$sZD6gQc6n$wzct041M`*^2^s>9JEjmuMH z31qxdNSA?R9Nz7AmSllgTTRrPWyljU04E7C@QJD@vyULvD5RGz;AJJ$4daa&xJ0Ys zukEAZ1fy*{pB3s}Nh@1Y@%NIJ333wz2WBven>L$1KL?r#;YmMcwo~-kiQeYU-4a)U zCxY=PlSH~$zAdn6f%LP?A<&g9{ttQiyGwG+VRqcvpacN)1 z`PV{BWl)i-$^4Ds4PfaIYHVT~j9xslv;-oOSAfdJYIcTM8;GGM#);UITm^3pL$6YZ zyue)&48Ez%x;XM+tD2H_xH;lhQR@VsGEmRjc7c5VW66!1GA}{-Sgk@4sRt|y9yfbw zeMCM^(bxMxhZ-by-KGDGaeXmSH7_ZGPpC9aS~C7jPE7I{F4w*hlm{LUfuDM7TX%4m zJ%Gm=%RM9?zUTaOu*_XGX*$L{rZA>svF5XgOPIQm(fvn@prx z=szjYrKb?9*3t67u=`?w5HJdsZMmTVG+9F+8-r(X(_@oR8X-mVi0Q_fMT)1!n2E-G ze6gF46FR+Otu=CUGdX`@>P-R1rjBuHn`hdxwwQpVGDYO)plyantr#|mo_EcND75To z0Y)sD5(HUuBfLk`la=nvWS#{oWG=RgXsnOyrA2+S^IY6#zyC4?BIqpHl@a{0N44|* zPb`~zNKQS{>&nMK>(^E(QoPv_IyNrjm&X+Ba0c8rlASV2Z32_tv^-uoi|*7vff8R@ z;9?k#sGtH-*D2M)jBxryzW8LE(()*0!=WK!LKmL8)LfTp6i2|GtjY&_FK3o3Lb^gr zwdzL}O3xO!c`d<&?oX*)z0hslODKHdDaM~R8A{VAj61*{qblAF*0QLmu{Ld6x5rMd zoAMltJ$O@6zYH-rMhW2XY^mbaCXEe9Ku*4(+aU~Xx<@hvHj2A2Dx^v_l?mDU9d&eI%dvB@Ye z98lO@izHdlma|gJeGdAKy+Sw>Bitj4NeIPG73HeCT<^w8mjq-Jf?Uj=(vP1h4_pwT z%djOhXJxbB#ytT|+6}=;c;0N!puQTRgU=P3f@g4cJY>sC@I*SyrpEEIyhE`u4rocz z7l$g2E?vh}wtL7bi4S=@SliNNUROEx zF3$NobGuV3b*I^!kIYQ7oUcY4S}LWCM=fDEn`MP#sWA4P6ve`BK+sM25hTg?%T$5= z9|!XS1fF7jj_CJRo#T#;oEq%}$GB46jKI$?j2cY&^W237Wuvuc65fv2>RtWV{J5Iq z?zp^1AVbYey}yp#gG80Td*NAST=#glbvRnaraenH>B8BD5>p$BouFqT5s;OAZ%fON zI7b_7pu^tV&5Hqb)eKL-z6_8e2Yz*0egBJv4=5A%W0>Gj(qp_vnGCJPN`KMBxB!Oa z<5u#YcbW@Ck(*1w3i8N9@{oD~;>8^x;A-iMK=SD*Ae$p^S&h61^eFdx3NHf%a-@EK z{uf?CI-Pl6@7Lp_yF*5!)=jNa)vNH&z?c)P*t?VQL#icrcE7>7?>QvZU2%9|&+bt( zoN*;X^=vs8O2RolX;q{p(l(CNJZQ@O)Hl0piGE0b;37=%Yixr?KLyPu+igRywUWk+Xn zfu8%4S3L6Lz9{yNHuf?lp?Ox*_Kz%hCo&Jl<;fR3n~+5Nsp)8N?2j(1*sN^0QOLdR1z| zM#0F6hfbk*x6s$7JbUUHh>}k37~?-Mi`ZW*ENBtn^n2o2h8#ijE#SAfDN9XBtw2g} z@q#HUNH1zbQ}>*VIajwe!+oUQRsU84eg1U-4*JN6|A^{5yLN8+b6gRoW@d9^kP*0q zzA(63ApNlb<{YQ?z@GCi?Pb@_w%?1u0Skeyiu=x-{9RPKP|i!`voA6gK2P)Il~O^D zy}Eq^R!h&CqR;xJ#lrsi9RV*hnf?;57bpuy_OO}`uTRvoTpTIc=RT2czh)n)kkf#% z+7-D&q3&i`R(pZQ8in8lt)s`ahCW5NC*@YhW9ngX3~A6t4miKh)`iETm1fufM8MhG z6w95~pEFcHZT@1Zc~w_S%WC2;5|ITfQohx^K6;Xl>Lm;lKlV|+Fu zB_unxBwlAO?L2-tDYz8OKyw|>9O6nIT6N=7b>TqTrM5MXhDy{t`4uF4;Zau6<)3zHQ=Jtwes{M_-Qm3#7!O%3NF7*9g??i4 zA=yZhoD8k7>V>ZazENxQS|Z)9y%bs46}D)iw7cNz#H>_5h$$^`ogGl$7vyceJ+$oH zeX{;`hv1hygMuaPT-}c$-#W8S#X!`$poTue{%l;?cjO2ToqT~Wl$7Mb;efZ`j=FGW zu4LE3IuECVPEA`Da*0)VzbvHtqP6+KNq(bD7qm*_Rbkr@)8NwhZm@DZzF`Btaxfs= zi93q#PMGbI#H;_OKJoty&q4-lveI}-nEF`KcOZbe&5K+j=}GEc9EKV{W}X=TJ|MH} zkp8zE=Xc_w&aNK6(>Zg?k-_HID<6t(3hbL_O)xji-wNI^^ImDfI@x*}xzLmDeOua= z*+iEODw|H4%sFjMe;&kXSV1d$6^nm5**6(Kyfpr!p*>&^IRM*psvG~##p*D}2mk<- z`(mW8%Xpg_-A-QsaFUD@&@8z0Hq~qbrKOYjer<6RM#|Q-d_(dm1N8PHL^GZqkhj=2 zd?Q|z&%EnBRB)*^F%_%MoSM_vZjpzVWv90veOYsr-c*>=Lb!(bR7`e`y4sG`O?BNx zf538X62#UqtYF=MA7wKNJyyZcg~c4;V=EXTffG%QT4>pEs67~pb!)#-FkMm%^|vvN zfx9#0d0Eb;$5pu{0|=iSbU)&bUX7lomWaO(YTZJ2?$Vp4CM7GEvQ3#r^WB?!S1i9+ z_^3b|R~DRmH!F%~R{UHSaFdWvlM({M_i1@d)~0$_EmAG;2+n5UQLNx39g}c?81bkd z9k+bb=iZYX>^q?JLR}s z-}LnJRNOfO=Odr8CX%P)q*LU(Ca-pCuAdCSXT_}(yWfEOR*k9i4Ud@E2yphkz9jiM zjIxldu`TJNwZNmNh0qfLD*Y&lV4@HQLubhkVoZZ1e?uu#l%?KJ?CE~IjC25Uu9`cO zM3f6&RvX}eTnkrIfqau_Px;@2tW71BwG_g>NE-BP}! z)X;P|En#`mtITxo@g{!iP-bvsx^rZLJjmBnSKIV-WMckG++t&6y!%t39_^cN3=M@T zHV>=rZ&%xww%i59kl>#6x4--Kn@*u>x00FCpY_k%?s`88f17Rf#-Xh%O}ZQ@=Xu6JF$WUZDg*=I0Ot%@F57&x8oV| zRbO+O;-QWuU~kD+LVkSf0fVaunQc#J&yHZ^8(Y&)j&}P~KNZeg_u?S@2;!_YwOKPP zzeEw1NgFnF^ON>ZP^7mc>ndc8mR_38FB&!PoooE=ckq4G+2u7|a!(oXpeuH}$*e z4F%1FE9X8>1NSz}i#H~xmp8|-)6>N*D$kX+LR0Hz)F-T);`3guHSpntZUmbxWVrjg zZdIkN^`omxGS84*hJ)KY!4G#^4X2%LB*NB=Z_>;ZTgzLdq*D7nsmGweWJ8^4lm!*+p)7g z2M+v)%1T@HYqXxRN{lBw+77I_ZxIhQ%_QRjP$#J`P^R-2##9=>;^unmP$KGjICUVP zYt(1r(W9)ujcf_&_FTurZ;xFYGkpVVoUh|#@_DAzBOa&JR=&yeyI0+p=2GfESGkJ0 zktr0RW#;DSw!Nt(Gm|;q@UHc1qY2JqbwP~T`6z4pbex9%F(kH&pb4J1WSrh{;7KWX z#j8^_Do=Mk_t85+Bj6Y3G&efj)Bx8az<-0XS4)r_!@>@Y@?ZJrO3yu87xCMRp{-~0 z6c2Z6T`C5bQ-fml)SUX|k3S2wq%|TR%tSb@dFZ&0gLh(jhG%#$9@*XPblW~9KeO_o z?^O}~vqbkqNp^505(;_`x4Y+gK`S}qCh(fB(%&P=3bihs-p~_Gr#9j>hT@>22&%rg z6M(->_m9;pX!RphmH@5fUCW7vNL|Rei)&3A{+|?H;N=?&g|Bz!i76OrK<-x*jVxP+ zwYRvY`T2T%q{Lc2P0T2i*6GjT90+N*U5)@@Sh-+5Hnmny7}P@GJ0Zt_0LswQ2U|*Q z8k7imWhI`yy;Z9*73r4N=COy$Fzd1EOIaJY#~UK;cJ^(@1MtE7kE1s~eu2E;X<5~= z$-~Qro6OA^PF>3CRTfOsOtQIH$bYYqF|$$rn80)vZ~MCnTjsx1*h06D!qJ$ZA>iM8 zq|5%7N4nd*+rE1C z{9B{*D)6Cc%cdU(r0L2{aX%#E=ArbkD6o|DW$Zf`t1d-)^w_pKdc+qY zcx&SR*bh;l^4_7?1-wO{O-XBD{>}09e3K4^;Dp*JDa9!~Cb3O@z4Bv-ZKoy?86lf?2ClpB9H<7dC7+YpqFzma)X zt!u1Wvvef-ETXT{G{wBkC&ONSCOsjwZF>6JLWlm0^Pb<)>o#kxXL|fd=8_X#_>&CX zKhwP&X+S1$!}*X#Y~{YfZMKVtL;)b|_jQ{ zPMcRbC7`QC8Y**q<5M49<84coWe&7SJzuw>Flzs8S1cdPCmH8pINsU! z#--0(PJ0k;QCx^`g9K+!1O$i`*rek=aqenoDpxg(qinNb*XaT#~=XWeNj?d~?+TlU|xIB?tuYityk z{*k17u|M3G_xBHJ71`$sjYgzQL_P?27^P_-&RstF+%a2$6$ci1(~}iyt<1a0c{yoG zEzah~HbrC3_VxMs)d(%SJZG!YGtKoydDJ|Y^dNKpT$6^#5x+A{dyq@#aGQnZA?FIF zrCXwln*Vs(=`F=Ua7ZY<_&a-)yw2jMulAOC`66ZN%e__>c^U5N-zb_(-o4k9Wd+eW z@wP>?cgseD^K4%8Yd6WYO&OWHRNR#uOdWjy;#Shbh`n^Lz4DMpydO0Qp>PEEkNG=u zE8lvqCLG&7TAH%mLr+eP?b$Ey<)!VR=2|xUF^UT#^Yl&m-9tT)cMzhB>c?gimA3<~ zLVD(RQiV{#K=>jiUjGajkJ_65o{lBYIg_1apFF7W6WN>gGk#yd*Fwj}xsO-94$gt4 zzjlIYw6s|6z0Ce_y={e%t*|(|uR~$VQ6ET1NKQd7ME3=~9B>-HmVEQmV4Xs^#VMpy zhzT{Ep6MZykbjhSZSPy^=_^!Jq0(S5dn~^bX4=IJeud;2x@P^*U7^M8RCtPtcEa;V zq#cU8yg@#C$8Ei??%G|^a_88bs}V0`BfNI1c!Ucx7t^tGA4|Hr7?RIBn@)o1^-2dOg5 zXi;wZEr9n!B>)ejB}r(FFR~^o^O7c8D{@paL(11V`~BSY>Pnp9Jw?-|^O4^l-!D}6 zzR(a>eHVHy$4m;}rO5T5k$`|=*|Z=F9#_5x4tG-#6mPlK%-2z`t)gmdJ+>^7NzhAU z>)jF$>M962^*i>?N3AJv_91Rj^ae*%xtoIzZ54aZF_ceLi=W+1wcu=C@T_>)*`Lu4wq;wRkjG-p9G#5MU~DOZa2rw2ZkcHZ|fEA1~!Mgziqe@l695W&@_uPuXHpB zr@Is7W1E5K)>0(vOMurgm4rEo#8OYkYn;{-qIv!~#(;$vy+7!h*2_riYMRE)<;Ug* zH|m;Kq^;)^l_gEI+TxZeMmL2t?&V#}@%l+{e!l!&a4#jmd41}k(ya*rp|)Fv5RVv~ zU6ZnwGq2qhl6&ER4>*69%HY($)VXXxdUt01{gNt}h1u4&H4Wa^sh+WWqc}e&%)V8+MD9Oy?f!ia@BfXzj(1mMysMw;hII`XEdE&S zO69yx7d4_)RWA93kcxd{L{7)3%lTC`M8djsyB-a_`YL&+uC1O}(C;wzt>GBn#h^sF z&{21AT0z5w-|+N@FK-HRdcUSQx7*f_wn$9mU}bez>e5})=C^I?C!Irwx2yr%LsOI( zFk0s3P2_4bFM+RTwHh|XZC3mkIt>hU1aHg>w&i}CASlsZ(6O=g$Ee$E=D{bM>0B|n zHX~W~O*}4d=BC<7`63zPtD=fKbEc|w^CQa{EuPEDkq>^_D2$eD3O>sGVP&5(+qc(B z$cCq^VwSe!KsW`0(husDkngOWITXzgkG1R+`j(HhW|eyuI<;wDURe*-+TR=gKsVap zsWXuoGtxL0RXldLA?*9G>-zTS_RegJiJ|5};`<|4Y7!=rSqrWVyS zyc^?;f4F?~VrKp-KJrXi{hBpw-qv@ZTUtlG^m@^&%`g?a!m2~39&yLkhYEdzgZV=E zurqUmCg4IYBRu_4Slv|Keuv3Dpn=L2)w=bJR<_^ebP5!S|x@_l`;fh;K(?emE3wP8is(GO! z#TK*{CLDg~mL<9IV`n_3q-a;@PQH_MH&n3!Ufw!(R1K-Kez)KDaU_xK>2Sc^zw|N! zg%veB)Wl&*N63edA34b19oKzMs<_dv?_Ua=+6`&-HI&R?aMMV8I#VXU?b4r4&(Dxs8*|In1aelAAC|eT zpEgOES3Yi&wj%pf2-K`>CN0G=H8D zgKtAGLm$GFtv=K}PGyCiOs8dGEY5u_AMSFe#F6^iP3a_ZUf}plR3X2?^V~frV6>8P z{-`weJ$x#CiK_z=3no*6UWEG;1Pw;sPxhn2<0VB2g5ZPh7fUkuWX5)ih%dxF44!O~ z5FLSphD}BfM+Uxj}l@6kdjL(Jm5$Od%{m^V8aQyPQBX)BG?FYd##o9Wvf0g0e6)|fn$;HE~m z|29nT>C|V_Q)W(L-&Vbgq@;?jr2`?(&4BYFHfg%3^>}RTkKUqD^{dW5zg3`a zWF2JK+wC0;G~m9*P!Upz&Oqp#d>7ANRrQDdAwX) zpWlCZN|f!#H$IOzvQ6RHaT-tgjnH)%t5v0-+zn2*Vqa38L63_`!HV`48x=*A8e&|h z5&5l8zWkKM#jBL6NU2zW3@Y9g5agA=O|mXmu%V+eGbm!_x(~x;b%GC4k`Gm}vBZXe z_|Q4uJtKg))b2mC6ibRU-n#>=ErPI3H$ebFb6(_%Wyn&FR6wd;f$X!cV7+HWNZH$? z8sK0Xiq#U4cm)m3Nf1q~uPPGY%IgMVkKR!V;BlSE!p;^IPW)-F?@*(~j~fc46&Hi< z*`Sn<^v^j{$x5x^j~!<10t~pH928(+;s%HOpM1_jILD6K^iN{$15^1AkEdtjkH2X9Xy{_HnRlM$|RznxaSzxcK z)L3q(yH%FwD;zPbajpi1Etj+8>3Ju+fm@Jh)V1uu?Rb|9?=SaDkwGJVY+P^|2)#>G zSSr<77E02ybUyAH#G&v))=a6BVkeW6@m`2$Y!i9B^fwRnL(m(4D&J*Uw=98S!l#^pzamnqQ@xxX1)$AR#FF>$X z{kR{d;pufbTknL3FP#s6NYEKWtgLjw z&G3^wky6c|3K+;;x{FEh?1;h2-Sj=gMpfH(if!fMG^ym`*KvHuEgY`~~282`ape4(WhR zjdn{M2aJ7-j4NhQH%HV@(dVBWJ@fDgYVm)d4wvZlD@8t8ObHwD3rM%p+_^RJb{1{_ zXZ0p0FYVeLWLfNqk$!-fsye%o;Byxj6>~kIM=4kQ$MpECY6}A7Qt~amlNOc^Wf^Yb z=GSfVA)i8Gf9PGLdu*VtIw$xnA$_B+OxayO%f_v=$`!>N?Toa`)S0u$64eN-OboI@ zB5iG3T=Jy!pI-#d7q9``6lMDkI4k-hpt@w5xYtA9-#lIh#8QfzX#Iw0-vG#mCwFZ|HvRnh8(@vIW(Roy>Cibj1gh!REzIc$S3;;sPb;Gea?_%d5fLs(aOu2wj#p=;xu_MMVPYhNnFEvu zCs9r32UVv&rN*^X3)qwIHRok>i1n+|b~WGB2)PJIWe)erPn5>=?aVt&DezIQPJo1W zy_0~w5zVV()1IpNgr?TBa2zf26-$E=1-#+)0)HSJ%nx^EX zJjJ`(2C=m8EEVBOB|i~|Te=_KZVoA1_4)LTx!ERk_i-mlJ5>Y{j&o!O9-&rQNjgnz zUp@!0)&OqGl{uZEC3MY@`1cfC)>x-aX?*2TwX1YW+Q(O~Hw$05(}wf#(x%y)`rp>x z_!5MVu;`P>kZx|5>(l@)h8W=a2AROtc2va?VoI}%_b4|AcF5A=hIc?i1f-J^y5sMf zW2Ays)IhV(knoD|gV#`^csI&0>Agi}dj<`ew;<@uru%3#%|@2>#uYcNdR_k_fsey$JnSd$;p6y-J$kUM-E7N~|Fayqa2XZR#?IQ0`~rzqVG#@q3tG zb)rWWWR^O7_Sr|@d(I~8FX5WyZeN^f;bgtPDQ(Xs2X~g!t*mdVcQ(h(b{6U2MUB=v z>plJSq(xjvx=Q9Sc=zTni4s!-DAmv4b^Gy59tQ*Z=zDOr5)_7? z1rugy(&O0ZP%{kM+Fl^TulA=}LtZo2a04$TkkKF5#R;4BofHB8G2 zLviwMeNONCT(Vb21c{*)NhM_e3Qq{aCv;XHStuB;K4x1v(3e$L3&U*u5b29 zU}DyFr2Ne7eII$#%dggCH9q25WiOSMR2k*}@M}?i+-QK;v3vLIX-2t`pMixPRxxD7 z-{k9Fy<4BAOD$mkUQZREAL@WY)TS;oNE}*Wk}H|X&k&@6x;~OVr#FV*V*+~e5Q2=g zrfm)-KMY`5SbwyK<p7y)rm`z43~(#tSy!*WtR*#IV>nbw$<$}L~^u<%T?Venv4 z#+Nmm!kSs8xoofY^%AnVvvJuwgWC_~O@mj`SE6_mtXGm{EAj&PwfkHKEuAZQ?2M<} zxQF!=)+A{#7%%X+fAJC4cj+@joGxol+wa);oeqyt{!z(u*mb~oY?DaoWw?e>tIxP1 z6G>VIU5d1=QF46Ho7s8UsL*yZ(`e;aZ&%atKN=uDvmo)v{L<*MeOrs4qS@T)^31%C zQysFj;;JdOEn|}_JVa)}SjBr+7Hx5FlJxK%I`k`+qs?H^%>3~oRf}ZqO1$53c#|PZ zKL%(~iEQ5Ry5e-Y)yVc@Ks@RivVa@(TM&f}-$19ix^8}l^DZDIUFjTo^Ou`Hd5&#U z+r~ytwr_-3E#J=BBlHzT7Kv7@F@LBpYm*N;GzR#7>eLS(w)LrK1t*5iIS}tJeFObC zVajio{iG4v1UG+YhLiYY2k`{L?K}`f(dY9e{?-PktL^!XVi5Y%)4tWu2xq0J^*QFu z8mf@`FP0eedCgXpmPo|X!12x+#Jmix-l-tD1c)^qZg4f?FdB4J{x)gV0Md^96l$Wq zjJXbbncKftYiui$t^8GeOf)kyt2((Y&RXQ=OWQSVEp2Z@g1%0wnrpOe5?X_qZ_yw0 z_~<=PF<$yHXkj20QHB5mVIFAIw#u}CJwiWUH&NQ$euBn;L5H5e_z!sfyyzUPlgZxt z3927?p|#~+%jmu6Dp~KO?T)w%PbYuQwT7~3^Gmo(^|cvQdmEoNUke*$@KxmylIM!P z%vwL5E1A0X_+iWUDB}8;Uo2o`%6DEz<;k*tp&f@T_px^4@y$q>^D zJml}Neo1-R(IZNH)grAB`t$BWyLG@}?6UM^lN-?s;4o2WP#M`rY>hC%7=X$7%jhTezuwEro6gqcvvGi3OS9JeF>d&(cre)K-uvU=CbMogAWr%Afb%DqGA(nH-P`sUhFYGuWS7X4g zl@(;j=dD>31U~qZx&LPSyQmF2`!TaATc!yHzPH3+(pFPh0Bl-!;zCJjD$MB)Td$51p7`@cVD zp2Ru8$lO%ieG3XbXlN)ph$Iw`B35t5bgnyiwbUliu=U2i(7nA~bN{M~X%2Uv|5>Z3 z(pRji9Zuofs8BY2TW!r*W_~;Wv1Ok8M5bb}?%QamKa-75%aMZ<9;Gk$j*@hTyRONDOEUN+n>TC1CRpF|>RoFj8(| z8oF+s=OKKfNG9X8T%T$Z*bPWmsPLY^TP1s%Rw}&B*R3y;vjE!)iAigNJZ+w=-OYW< zP9{_H%c9XV<@x7=v0K@lle&DY?tHrHOJ>=o3Cb$I5y`4@-+yXNUwXtl?bPojLgtw^ z^L9I*%;Ps*AghW?$kNS{5`>9rxmlBMv^(7ORJx^Lz%6f|y6sZlS$Weoy=3m@ppW^k zi7<@oX=!W<4~|`(R%25rroJ`;8djoS>&japIuxw&tkxz@JW(!weZId~{{48dhy3ez zEql@L%8aU*Ge;tc(8txWxEtZ2zA#wxxXsU?h=b+<5d6Gd|oS zB0vMTj2j=%*qgL#;;z>MB^stHI5f?^oUWvJ|@>&yf*IF z#M=17Z|f+s=jYLT+=&VtUskX7=i&dj3&k}<=G-`bL)!yCE@OUC;iSV4CZ!yUTLqB1;-#ivg#Q5w~iGLxrJQZ@wNpVD-f#oUGSc(fJ;JlH4=Xj!xlr6Eyr)j|BDWy=PUu zL)RN;qGtRz+ZUKOf3fH{``mVtH&p5E8u`CFY>|V#7|ZwL-)l|ZvcPA8Z!R&NxK@8! z+myLRq|IUAzcH8;9rDn8%20(Vn&x!#M6PvlC}fKhf}kSdI*du!5a>UwFf&vNloGId9|Qh5vSKxuA?ac~by zlQo^-^BJ?pTZGs*jQLl$w?FXGtzX>KAwwcv^WXhqv19nD>{7Nt{p^AOR7Wt8AcE{C z5wvMzP4;$*6@agGK_?hXa|(rNa&IC9_|Rt-cyfMbBxE_!%h+G8^)nJ z6d2$1Pw*ND=|Nn2FSY6?Kdk0N22-y-jGL`n7g>HfEoAtkriIYhP>*fR^@(QFBu*=A z${RCXM>kF^@5_GuVXQRr(AO2dZ__G|7_u(Pfk(J*)!&yTvAG6xz$GdndOSVsVAxsR zAs@k*X2L^Hi*J3x5_?0>vMe@873bSoWQNE-b%H3l&8F&k} z{1BhQFppRXdVL^rZTU|ewC7Mu5Gt;)8$=rGu}(cysFn|IIBjLhn_0NE-}G)50~VZT zVyQzN&ecNeph_XTt2!kOAa%l7pw4ti&qCck8TJQ(gLWckA(5elp&TL_^ruKv`==M1 zXp`|!QNI$OXV-}}Gw<4S z`VcF<$}hi%HFN2!M;VE$XZBj&V0a8X*XDKX!KTP(A9bdf&Y+X06W*_kUj}ozJe(CfsBfFSS9I*`YHTu{egp|Y z-7YAkaz*8uW%m>BZvzU&$%i)>55b74tB@EEa~dcH4WRlzS=8r29Beg|1K3;d08dSv z*gl2_T!)C`k-nr>OoGQqfF!B<6)@T@cy|8QV_bV;+fzv4(l3@mJH;nRh#FO)?FL=A ziR%s!CZ6y4gXVBc#W@bwb(_@3*NhPro8f-pv9Vm+ZIzf3D zqV7Iu`1HXGs$RbOnW1vwZZP1ndp4xQUFzxk`x<;1zV^`ys=={iE2zjWSp05MdNgn? zNPsIw;okS=M4sI|J=YZ5kT`N1;vN7slypxn;5w;It>F?(em|Pwj5o4XxP)JM1QuQ` zBSV+xF+vr- zJBG^}eNQd*@G^1?y&N39*27m;W!)8<1S$`-slI`;-ZWba2$^OGJv_8f1JgYkFT2g> z(QQ>dW0q6wtp#ICqoW;`mgB7&Ox!c|6IXNfXBL)Xy8@E2Z@0UYVI90Ev7;P<;ySzm z5?>)TiV8zelYOZHPr!bdDE(0-zK4FglkWXUo{|rTjn~VeObQ*=rU^|51#_WX%Y+pj z4oQ9VN~lyKvBBAr zvfzo8ah;3nWXo)6*3rOnNE)76&Fdv*MoIB=R?g<6xkWms1l8NJPZV6`&0lteaIOd? zC~9>Wvze_sBxumylHE%!LB~&n_O6|E(yNHoZwS!cbfxB~94(7LAH!1W(E_#fA<~=y zHI_8sWjLuZ#G_I5%)JCxjtrsR9D|BdDiuitwJh@gXz#njnohH}aUDldnxaxf7)5#$ z0YMEgiogH@(j}CLh!7&ZOCU1}gd#A46lodhML@bhAVLU?ARt|ukRTvEKM)9zgzs@? zci-7}cW1}%`mTNV{VxB_mE>2R^W5h?=Q-!xPF3PdFePvxc~$Bp>G|Nb*00gCR5Ytp&Zevc{cZ}A37#6wz@NW7qX;q(hhUKpwOF{;pC zTFXAHMpeC7LR?~w3Fh%uYPZI+I^(Km2-LbwZ7oJp@K-%ry1aKwvj^cfdQB9;R@|&|P3fAZgx4MaXN`@LNtFd*PsLjg z1}{(_Y$QO0Xgn*F1V&uNHVS+QK18#m_LNU3iAF0>qRkhs zxN**z-xF!*rRm`Gs+fZWd*cfLzIImx-afF`;P^y2`DGe_)GiTOGXr4&kG9~MBL-rCc)$K=Owfh2QGBC z)A#Jypo5^;NZ2W|ss&IA!Lg3hEg3kx#m={Mss7U7v$pg6dQKy%E8l1J;xA3j-KBF> z&;m_@)LY+7EF^7TySSWSKTYCD_bNR1PKnSvn{k|~Ws-EK7R**&qxUAUL0y(F$8@k+ z&6V!7oG4OH*K|bN`$t7-y1ev@#qsT72g4-&1@v8!rlp2#>EdQoP?xAuA>ZckmQ9=O z_S=Ktu$Xn~Ma}7AlW^xjBL2K!t{FcsY|wPIN?OEEPa)dc41SnoH@Dh))Y-gBM1o*TStVoSw^ z`5eMF;t%f{ zJb~k-%lE?eDL;^fnN6LT8?|ZdS6af5l+7)CFY0$=KVCYiHuzn3mxPIX_MJYn+t-E(cx6ripeN;lb7#!!$w~+51=~F zJHc#%j_2fB>rI`??94)zH&KeR3di`oOSKN?NaQzj9JA;3G@Uh*cxBKV{IP1&yj{7m zz>=@0NX+=GXMvKWtFaeW>`b3Uaw5*M-L2ttt{@JEz&L(wEG_q&{(@g1UJURF7DD4U687*$JRh<mNU*xk-{aMDE54 z_XK}~DxzYID+e1t#ly#Ep{q=#LG=D?T8fnFr&xAivETHN3h zK+S!M0oN{^-?mA_=8X9JM5Pivg1nII&zdrC-1ESv>jbLldg^Pub1lT1rN#A#1=$W( z7iyTzN{JlUF>rn~?X~HmKir72-K>sO-KcOJ*k$>XnzR+&m1aT4L|k`D%HU6hyLcH4 z;4cMvxCMATrA0Mo2oKPODK1h=)!CyHmmMhVhm7xcF-4-?o(&!%i0+jSJzHcrY;fHz zWv~KnqnMpuXQSw15ZrsvylOe6VUaQhZ%nE%v#SfNLa@TXfbVT3Ha6q=o2JzkC$2q0?Kz0p7e7N=K>%pI;3d6*PJqxr`$K`IVL+hk=F?=yK)VEM{KUl-Pcj-RoxZr`jo9CEzfp$>MzEyN)j zw*l29F9z>Wf;KWd$b9Y2?C8vN9yI573t7es^L~Rrpa-C)htsb@Zbz z=a)p=-$_idC(h^zuiGi0U2S5TXDnST!Tf*eAc2nkk=eT}L0A$wx6p3Bsb1@2Zf(Ml zbafm`19v!)?D0aECg7q%c@7lntU1Iujo|5bRsC1ZL*h1zjW4RY36)cZ6wB$SK%o?w zkph$5oHDJX#X_R(Qy`(y$bsayAjL)oD?!X8GG|zZl-1E8y42)?zL#mT)A3CRnc^*% zKY9rzuVH5|a4}LQr;fB;jRJj&mT^zloon}Vnq#>pRVt1}kYi4?pMx2oS}xcZQY{lv z7W>1ZTDwBZj?LujOP|TJt<1yXs?u_{W)PDr`zCG7Y%{#ldNcH*$RkG;7B|mz<~wYi zS09!(-!GdJQ7jS?eWNFf2hP*ds#qXy9vNb4p#xCHjoDG>cRyH+cH;UQya#1LE-HhM z+IF9ASwfqjSVY6jC^Wp-WZ>flsv(xHN(r(sPc@+~r;}x_h%2!lQI)(Qcw*Gw)m5a< z|Hpzz2xvc}wLFNmoosjX6U@ozHu=u-*T)Ts!&+7edJ0|0x(ltBPA1tse@>i&_|jPo z!p_}D5bt_83#LQg?tiHMAdOQ)rfaqRg?0DYJly2-3%=^dp3GiIR6iTDS1P3_(e7;W znAYhW&_mSt%-)JE-}A-5LosDp(+IjSSc*kP8d|7`5dKpX#UdQ0?Exv1{YX1NzrnwQ zlJpR5S>l{=iKhC~!n+ext%Ce{_+XZgmyer6HZ9hqroNAF$Pmx&EI53mYxs1xA~Y3S zVJ+>>oy0lmew5}HPBRbNFG0o^NjH&KZ6#YLz1XJMvBb#_y?F*X*5-(?bm=Qm#kvE= z1!C~*=>SZKz{#Xrg0hFZJp5ld1_*HtkY+B-*vGaEb*cm&ifo!rC^ByuEV$5|z~-Micu6@0x9_4*+&E58#N8{d5BsE%E%gADH zSbN#laYXX1a)Bal+;o7bqj?V6*DTR7;dx&h`K%AnlvUI937EUMo^bGS|4i0+6qOh% zpQfR9ra)UEOt#VPK_`?ft>*FM`m3_7l0T&(?G)I2P4o^62#OukO223{lP-2JqdmUp zUHcmii(OVJ&O1s#3`$k zL|w|ROXvhdNMNJJe2{zGx;yu>gJQ2P)DkQQVUNA9I(K*JHg8fmaXR^$ub<$FSNV{r zedw#XzMRB2ZH|@HM{WIK{OOX{XF|xvcnOoR(>dQ=k(Uyt_J#TTDTN^uV6&Y3$I56A z1x=(k6$>8S^x#X&gZWsC8o@N0`Vs>A3oaR?k#&6}bsr*ijUSU~Svwr)uW0qq=}k&( z=rE(GsYiLtO4y?NZ_ zezSR=_KEd?Va-l0;}ClT&oto<{_}|EhKo~n&|S3MgUgW7fC+`80CMKs*E!XF+>n|( zL`kg5Gt70yamh6D>lM_5+Ceho#RIJikIQxxya^7;6Wt+$* zt3LW{q!A-fZdsyc$)@mHpYKg+s>v${%Srp_0)y-oCA~)m2F@v|GZ!#>Fipzp4l7te zHL7Ea5c`~htge!1ZgIykAzhl#jsRVVfm8ZWMZnfzj^Lve zF2A6bhQj11ZjrVskOfeyBS)q7ptpJM(?y;w@Bq0odx40f$BQ?tqB<_|f}siZVV%bh zZZYK{MC6NwebRz~hS*w&cO)RgF?o7SIexmf(I>etYtdX;x$|tYu0P%esoCzsQ<?O5E~{d@>{>AWc;f;82FWhPGVIen>ZTrap1q%N>z%f?Y?6 zw=cNeN1`{xsW}@-x|-So#`CCQDJ!6JRjK%%RgfOJZHb%era`lV44c_SmJ*-(1(C6k zATE31o_U^ww4u|GEidF-lw*tcyd2=-k>|9TXpGg-)Uu%nDog#WqQUwD5XRVL*#q5C z2&cIz8fC#lFJ6dzX+gRPsW{g}BfvBH-_<`R-X5*%19_va=o(3#X!5rX_G)>NW}0Os zMqvsxzkf1gJ+ABHZ1xiGBCRGFde7io?(F^7Qg8D6vy8d3utf%b#zvH7^_z$vEK;gU zN(1xJ7WE#_=n9ZlOY%ed7@Go$@U~XdB>-ln0p1YNj zXOJM(-`w7yi7h^$>kb?CH)&p%=V~!6#+hO)UwOPuQRtRm;Y^+pP+#{+nBhwhF_z+c z_*6hvkUL%Lsg3c2(t{O|X+d}THr%Nkk20Mua{S;$Nte1tosCqJq_ubJAdaF;KJa(d zL-#jHDWy^NP|5d0MS1>1#94DFu`D0iC;)xsmtvl({C1>^H>GPlb1M>$NvD)0kGWpV zu!?NC!{^8DpyVMZ+pKXSw8_0#pn^T2L%dDW@NoQ8B9BD#_0r^uMbB&)-_haZ=wSF}L)0f;Z=bd|tyStW6! zqzdnT8xC0(Q)xU@LY4n=h7(Bz{cW~nauFAu$_ehMwp2R*fnjpl; z!A@CM#1v6zS$mpaL@KUb%iAAABqO`R^x~$=y33A9O=XDjrOkR2JZ$M;4UNhire|yK7|+=` zNo$Gh=&W6l-;QrVl*4$`_EMFbgZ8#D&(_ksvgn31`zg+&bG9l&u4qFqZHW|_ zy)SK#k{WUvvAMQ1oCY<^`JfraM%Vy<|ENMYH)*SSFNw9Ut0F_J?e-H>g+&VvkK<;E zlym4~(sgNGuA({8UthZTdc`;!N{+nXtDvyK`9z;mb~I07^@=XS>milN-Cq70%bI#e z;T3gjMmyO)|BipbRE~80sUm?pJW?;EuJAf5dAzmW`>YB(FlQQKoR*~$^aK$vl=b^v zPXF&u`2`&)6Cr9}Lv2xb^(n-Wxgm?~p)kDg)WqJoCMBr_z2nr`mKPw$Z{_HNL@G*o z$SkS}^ao+w6E|ohfRYfj(i*FY5Z%JN}khN&f;jPt@ zHF~)6Iv)99c|s4NC1Dhj>bmfR^h&fhKDK#exXPib)WxmLP@fUgc${X^dJofrW8GzG zwh)WJp8~W{?E(#q{_tzF6~>VXp>#(`cL**hUta;_FkxIb{DDk>RYQIMH%_H$M46V} z50GV|eEoLIn6;3cbie)i%-U&QAm>*-KjJssm}z>7PeN-m>TzZ*PV#ZzOkd9O3gLZL zH~Kgu#@h```04~Xx0WJfuLr4BK$lu3_&@@Y8}#?^MBur+cUkypv80RGaF<22vbz%B z3U~?FyRP8qBlm;tHy0BV{IZcf+CjOzPh>KEH5zt!8`_Do~v99=keGOS@oO)tyYg1~{l4$}aw zy7(cb3+T(woSBkC%Xo_tTFhFDl!sup&&~w5t$s;Rqr|OMIeck_CVQp)Xo+i;wvkyw z-U)ce)wpsUR8D1$%Ti#{;!g#2zUcCXbw5{wr3vl8g}|V;Zp;yaT{Qn1@!nE5u^2vU zNsFhbhuiL>g_io)ObIhXSe&}`8<^ST$y@CEucM@b5Y1hQ zOHMWLAm*b0#{yd^7dE{*6Y~%|aq+(EIuc4^K2oj7sz6=Y5z8VGfmy7+ns&eiE&a~U z8V8p%>6G4ko*PwFcN?g&8+_EE5H&Cdt{Iru@hZ@vBm^{oaS`X=DbUO)h~u;?E5wvo z(n+lu3>VGu+d&^ydrL^PfLx&1R@NtHMM{Y&#T1XvL8zfvj{I)|%}kC-7#PS~$8ce# zr}z+$q;!hT=UzoQ_i*+@+xM6tCtL$)1=946%CoU0nk@ru{Fum+Ttb{H%XZInZY) zdnOa8WLmpbBItR_`Dx^BT-U9c1 z!j_}VmH0+4K&Cj$rrYhSBzZp5p|y$FC?PE@*0SV~Sm)Y{+qS3P54S3_#!X7isE{7K zB$o}K3>2MO%^MO_+Kck^`_oR(Yd`VA{Dk>7>Cu!2?z@s>T`GhSe_4V6LrA42KBxky6WpSl274`OJz?mvhC!g4hBd9wmlfv01!r9BEf@UZ0@x;Cmw6z2!4t*AN zs0TA?ZjH3+^u>DkkcA5FjSy^RCbn1mLnZ*);IlVJ;;dW}KY)zg$@Hyo40$05^U*=Q z+L6iIeFU669$o>xOj#((Eb|nYDKPVVmnDL=dzWSIOmGC?3oqPp^d(N(z3B-CpW)II z(3GdpQi*8^>;PR(BQ$Vi6MmPl^-P^|#R~)%IzpKkrmTS2F3TkireLif=tMIC{c7Zg zkc>B_yR$ENdKL8(B z0TvX$!}KHs4`XPz=-_0wO&nm&CTNZ9se%C3a1CSDZV>(oJAMFmlz)Ytng9ShW;+hM zEaWH%Tu~s4Df|urJ{ux+(>1`yoj?ZX2seP8-tQRP1jwCC*cuU{uGe>OpDP^&KVU;d zU})3-9I!xbWfYeE&w%x>ZxYiIG7EZr$=8#ShN8!jmSemfNsox z4s;j_nfNQt`Qbh~AgU2eUIM80hT7FBs?*?aUC`Dbzk41*9~6R4UD#z|oQdtZw9CT7 zablMx9khIMTHyh@OELhoQ%N-N`eKZJ7xE_n;!pg7_~Ww-K8q#ri!iws0%%61#Rgy) zClEa95Igu#2}}RZ0JF=YBmB_-oLCUUc3EbfFvP(X^$+cYy9By?u*jzd*WX#{FH1J4 z{(DpQ8XzX)L5g74*`OeQV#a$L)i-wuW-Pb#1>`WhldQVquw^ zDOdyi9bgu>0kepN0IvPQEUdt1eWVGx2Jpsz!z_La3?T9WR|QcExGDg(U&zJ8_W2B1 z0I5R%JQ^yV0CWdXAa(F=z^(jBffB)Im5?8xKwJNm0)5tv{)Phm@%#KM3F-j>rQgIS zYGT3UEd|uXQsQr%zBdRDF@L2d;H?2~u-*Z}!i->l&8@-*DvILCi!W&g#~ zesPY7J{e{s^%D*Km%seSH1u;G@6Ssh2bkd|Vev2I6)@fr+${8W{MG)yhv7B7bN2 zzYW}eg9sgj?Q^(M1%R%O5l(*}CH}+Z{p<(IHo-KRO!uFT>z&%T$f#EA2clSY zvXt7s3r}-Na7mom=sMuwEn@7qhR#*H8PQHjf!5^U;Dstcu7;WDlZvI|qen+SZXp9B z7=KcjNx|sIW!^W`Yinf_2BVLwnGGCaoHR+lP!|`wifYC~j4N%jx+Z4iK-=PG{!$FD z{o$(*E;hP{7iNipdYOu(*km0qOluW%XBo^NDi~14Y+l%=Z>JDHaHngwF)wO-$Z@L5 zgs}U{=XP06FTca6<$=}t>UBA!O_y*R(QaXiQN?0{1u@Odj0&_5bm+<(Fb~<@go+C% zkWWI6;b@*hq#qBzZ2{XkOwp6#oRr~Z7quZbFE-_KThg7SJu`{wJ3`SOZx{2FUJ9r&WyQQ4DBz4qLz(2k6+MJ3inVfd&u&Br zl@9Eb(FMRU+5XSaragI?Wu1lbt$H_|d8MK}5OhbbGklfwi&Jf*OFOoA-lp>GL~Y4P zX_xO{yX9t+Ccb$~7(={rstlBSabcRiy7T_TFJCww>#(^WM#w;*AKU^Xyf7k}J&TQ# zvq@_mD?i>vEX%#GgsUcv39K>$f>zn17$kaP6!^;r8HjGV#>-`x7lgPTrwxR=SI5@$ z=FjKlHhEUzGJ+k;903?uO)(I^F#JL6+S= zt_F7!6m{Qr-Y!RaTs^5fq;Y26 z(NE1c>Wv>(r}++{h80T#MRA1|_@MK(o%g|e{C77${qgHf(?Rt04Umn0UIS9z>t}jV zaCIR@t;H^j{Np|;(yFulUJh2IhsTlKZC^-VdMu*)7hckXGu_?dw-8|mJ8 zbIZlS`i+STK^Fp~&Zlctd1Q}S_^kvNjs)lZjN1>xP{lUxfToRZPE>{(?GpKCG=ln| z8HD9{RSJ%W7EOjqTMduW2)ecXFyxfs3521Odd>6z8UedL0!sh83+JJ^wG*f8*?hNM zDn6Pt+U0GR#7R44R#xK!6I$yAo#NAceR=!*zRKCBIJ%i9+AycS6EJ*f zBCE`8(g92VW}*@duvZV`XU_=Dq$#&zSb~M<{!rcnyr`qwS2U?9p75%14I;d1BE)6p zerIJM=gAM%hf1t(yh0*X*O#%3>Otz5^%#$&nzOf~pM+LrL8~FfU3Vj)G}t0{m&JMH z?Wyc}%`=&Eh0#*01r3TlXg$P^?}mlrTw)Y#2(A|I<*xIhwoh6t?a}=^DT5LsXM8UW zmtV3-ReU^?*lw)XqikQt{({snW)fVz6^!u6GrkUHsQ$Z4xBlq$_RCEPZS7HJgyNM! zC?FaS@1X&ijCR7d^BtdH&YgQg+tvn|<%(cq?fr}?u%9f_vr)L$p>8-3<#KW%`^fMF za`iy9GaOVFEu1>-HV%7qq*K6Tk3bKeTEQugf}7|<@#QW`A{)1>gJVnToYu<{zEfV2 zft#c1)_Vt;rDa=F>Wc|Q{%|L6Oo)&mNTgZO)t(Q!R&^huE6}2;USyEH-;oR5j%E;T z5Sr8|6R3B1A(*Xf$4kdA*QwKsBE$V%qIRraUuGGX)#Zt$fVjtVfm%ro7kxxHeELSj zZS+v*x2)#ZYhNvHd50Qk2Awiab9`0O<28-4Nm#5qAH+@7n^XhJ6^27gl}lEn3`IyT zW<7a*mn9O%gZ6Vz0yU{Kd2Xna33xvqdH7qa(YcL__ezp}a;lTXIgnR4kkPPvK6TyF zr5@4nQRVhpvjXF=ve50uBtsj7f-n3`r$p}r1>LnSsYgku6RBs~WM)=>2(m8BFARTb z_N|#2i)7)$eJnRwSYEQ+Om)qvn=L}Z5-aTbt5JNK; zfBd6n|39=LKWDf7d9qQUWo122ig|_oo_d_#&h2x z>eUg}F>;7{ZQ)(~%|H(8B`?bYH>B1EA->+ww?=0;^Gy1bNU2O8+&Kp|!Z3@kP8yk? z`vE$5|8fsn<55#;WCvAcOmcrv*V1PyJ=a@Gc7hYFZ}A?&L{WiGWBp=Io0VLPx9e# zrKRZcrRAqb-~sY;LqATmv2nqoVQbcgE^IfSp^kdsV|rZ=MjPp-dV1;)=jYc?Jn@`g z?A1}8?MoQHAUb|ENjh%EzyNNQu;x_bQkitMX2#E1HRzV}FDF#Lj*IbX010H~+{>;M2@0?0^2015&jAwEDP7(o4v0e}UO0su;K1b~4^i4alkJ@VhV zsCn;E{@`DEz*9{b5D1ZKTDn_XJA2rZ_v0_*J|Tsrt}6VC`FBV($jp(+o0Cih!>yl3XFu8zp}0Km!F(_KSB znn6$BfB|D0Av-331<(Ub=9V6=Pu0|({o?s|`kVispYz#YIs(8H*Dqdw$p1Y+WM%DP ziRdOHL~#o%4@)Nm?m|SUrK`IqqN6?_=!`y|uD|d!0+YBS1VrH7U)c69eEkbs{KlvV zO%P?YG-Ln(l?ibnaLvu#Z2ECp7cLe%JT`vdi zKXf~5&>#N(c3QfBm+=PcJpUVeIB5Qn$KOuo58d5M*^`}r!7~<-}B^m z|5!UJ{GoezYyPS0i5Q%J^Ktc5`_qT^=1RZDgK+?))2kN9{2;Me^9RR#dQYy6&3lspQKow96Gy&~E zH!uK<0AGO_UM}CPMkNg%nAGs2_5xE3Uvb&ih7HNhem_Of%X^;grzEEy3-=UBLa0hlj_4_XN)X&l4{muMDpjZxs)YPmIrv55l*?55dpEZ^WO( zKPJE;U?zA~ zh;Ww(gNTJlj>wAWB~bxUFA;Bc zfaVL$87&>H0<9};25m3xAsrdr6FPgkH*_6zd-TNglJsEuH}swK`wXNEPZ=B;-ZJzt zK=0GsSG@0aKkxq7{i_G8540bIJ*auG!idc%!f3X z$DGbQ$b7-V%A(5>$O$Y)VBQEAZ-(RR_FkA)t4KCXRyBE}`= zAXYB6E6yrzEnX-Nk$50sE|Dj(F3BKiCiz}+UFyD+xm3Q?<`c#zR!@qb>^yz=)c$GZ z(_`sJ((cj?(ibw1WrAe7WKm=lWTR!rn&q13TGCnxT1(n&+Fsf{Is`gKI%PT+y0W^- zy6bv8dO><4`c(R0{bmCU10926gEK=p!&Jj z?9%KG!7|`XFw9=jKG*)jLDiwe;m%RlvBnA0$;_$6naJ6}xzB~p#n)xRmBTf{b=~c; zTdEt>UD>_Z1IfeKquG-LVJLm^V)J_Cwc#!4o#hSp(ebJCCG>Un{o=>&7v;C(FYjLz zfEr*K&=Yt+Ff?!@=xI=1FjBBZa8C$h$jgxJ7YZ**L$O00LPx_Mg(Zjm2-gj7eM$TB z#Y@O5g;y03_z~_AbCF_^xvx=QgI|wD@keDu-9}qQ563);NsGCTwTvB(=$ts4B$ZT}OqlGS3`tQ*X?(-*Ci=~fRMXU!li{ePzOBW#u&G2^Gi{UKM+lMwMTyWUHF1xvKMO$ZBFf z03WMsw@)R`a_Hjtj6w@5QU77t3hN(JS{>(pG6!^Vc4()vODxf7+1U__C?F zxdgF<9Bg@PU2nhqhW9OPhkmDQmv6UyPk!&~zTy7%f$PE5VZ;&P(Ys@|}b2WE2|7{EW@@$Z85dO|-3Bo?s2LR%)0Dx`ymwo-a#Baan9|&QN{ziYL|APOr z!GGro0YJeV0B8jOz_U>R$jC&vN(lZ02){s$06`Z6koo!l#DB2!u;J(Xs|{Q!glV#J zclVtQ05FmO;3nzr?yBJK?xp}?>ns64m)~D@{jbvZDiNN{J82OW-Nk;<7r*QO%gFg9Z`)ZUYG! z1r-e)0}~4y2T`Em9>P^bK|w}EK|}lH#32PC@&QyrG@|>wPtl3h%`qOhk?@5kg40AW)2YjKJB+^NFAG@&_`8A-V7VZ<+WK04Z%&=do z{nqTir&!qkFU|fa_D{W*02u)JcR)c#TqP6~#Faut1T+k^UjYLXVU8gJ=05`V?|?9$ zaBvWo(Lcf+f(a6W2cj}M;){ocf%SLRe?PrjK`a9(-z@^TC`gFGghB{N0XNtA(QLqf z5mAWyLQXN7?|>H}yAFn4QJYdfQIAlvPDhWHW1N|%}2e5!e_zlt7lOOYIj28FsD3Gk1I zboce&uV@V~?4s{Ts>^3lKJoH-RrS9Ae5->PEgj~!?1DPNj6zAr5AU_UYr<WUr6Zo_EZ5ezI8)dT&Y2bd!pCW8Gyu=H zDN3Aiorf&&QJml>d&4T0S)L<9DZ(M&;{AzqeuV(M`7WK;^r?~5=u=6F9>Em$9o+B~ zsDH@ORoM|wO@7D653}oWhqi5vy$TLxh57_2!_A32G;zJyPf(QKvz*(u4l%h7Ob&Oe zBiY!9U}G>P`y&|*MznjZcT!R(ZEyvs%*JJ*HB$vG>#{uXh`Tiu;tvn=71``?hO$Om z!z(XX2QIkqLpKs|gi7U|x5? zfNk=)>{l)U`H3Hjw2&~6KM^bAHqg2cVgXLlz@1jdL&AnIv0 zHVo{cLrm+~KO??fbx&N&!7Dr5??V%okf9Sosuh;2okr;`*p7RG_ZiTd#>h<$3PMD7l=@j>L;DWsE0T@d#d=Tyw<*?Hd}FvwL{^Q^WI^`rQf^B8;9@TRF@!f4xdz?Oo@}0 z+nYRSm@fKIH^o`>eeuYglS<*0m39Ef@jCG)U@_;%qjPkf*oeQyG-uf-kE)xpr} zl$LfeX3U&Y8Wq!zGKjcxfE{%3#nNkxu|8KxAL%z0+Pw`F6`!<^RybB_1Tw`+VZoX@ zg<#Fftd!b`#hV%j)6Z9`odTXGlO4A3lPeWp&Go=pDw;Im$9F)Kpc>V*INgow%Zfs8AM(Q^LNNX`AJ+RuPkAQ1 z4gII0P8G?b(00bG%}1R^MRLsoi!;VWZR#!=MJp^$uQy|BBUtwv?29-Ge|W1LW;LXo z*{-apFbB54de7fOFS5Y@k*IdC))S@#gVqkKXV{hBCU{zIB6vak8dQNE4Mq~j3Nd#03a zFTvff!?o{(G?i)J$``!b7Fpzr)!1&_>u=llYp63CC(O|9F|$U)l;=KGX&Mb4Wh{j| zz)ZVx$?F5MLpII}y~L=Mi|aCFTm)P6XNaWRY~zKbILba#>{LIk>?FVTfE%t$QG$a3 zm`-Dw!ExPIQ2cziK9xO9I9!9JqD7w`TC0A z{LH7S^6R4t*-6?smEJeb03Rv4P#S_ceeZxLb0Kz4%9}fbH{5=&(qC3{X@Ur$EDcRT zuio4N1gTE+IrEI)0>A6_EDNW9n;#yl+*T!^W?EAD4l3;ycCcUSh>`n_e}5d-;!KwO zQtM#&s4&y$qi%}Q#e`GYRn|P=s2_RX9T1<3(?P&Q56wAnn;-WqIyzFP+x#YnLH$yl zKkrDSziK9y5H5yQt3sBz` zPBo;SgZ5Xl(`6hFUhgOnMCK5uUyL$8416dU&^cv1{z)9^N*^IYN>%ShC&9t(^Ah(Z zuA>vD?FRlP>$nwJ$HCg;^!A&V@DQlNVDN1o3rvT^}Vts3NJyX=FK|+!#9?RlZApNk5^PO3NS#2V~K%DFM z5w5*4>d;F^{{dc7xJSn|Tc7=Sbu38wc7UURX^5(_I>O3EoiVJ>E!kg3Z=XhrT$NCH z(Y|bD;7ZWT_OzWV@YKGD^3;PvWNbXOq}BeS^-R1lc*e_t=&%6D|$+0?Mr zw`A#n<%F9&-K|6;yke`=by6jjJlwoB+G?NgH6FFBxIR{s;OOa)y0*(&*9|v=W!do^ zG>!+*7WK%vGCac49{$`n$f8yIa#z&cB(KP~PJZT^)d6A%p7E?`!#rcoh$nR_eEp2_ z)1ye14k3MKX7i0`w+og(w6`PTs0zQ$!e|HEH6ySJt=V ztAw-PzVft7&-v)oQdHx`Rn9%?+js36j#mHRf5??k<+do?w?-a3D}{RP-~`=yeh0kN z*w@zteeCFLvx!$5rC#3Z#qu3rSaLz?u-$*8g0O7RI;|5TL-2#?7wt^gzX}Ao7-jM; zR{c01@@7dLe@LxLxBW_b}B4^LLLSF&78sg70m+0lA^U_kG1SZ9>VTt_jLz%J(LDRfV{QhaQ}P z7+q_qW5XM!Y3}*ob7;7z8My-%s0IcVZc2h#ch?A*eV}rceDAeve91PrE$^XOJYO$3 z!lAZ0e)3$^;O2?wfP%RZje3g4h}#K)v`T;JkSU0nDN}{J{4#r4EKBRlBl}NwMNEs{ z3-ybwr?#1aAb2PAWP>i7tPFBv!^I~SrnCBh&M;~i;**YRUTD@r{o1%9DVg60qqk#zqPsZfSy3{#-F)_7scD#9d6*N-ch#a*^6w%sbhwT~oL@>J-1)G#biJ+|0|}wtSzd5BeK&jujaQB%c$in1!pCjjL2?WAC)RbfQgZuMGozmhiB?vW5__=)l0l4Uvf7k3 z7QO&JNF2$;1*$usOMfqz#Mf{@xR3gi=Ch{ctrvhWcAE_Y{)^9*PYyY@Yv63;@eQi@ z*Bn#rj0K-zDx05V4lmH~DUZ130tPU5b`tvt%C}X~I}|uJF6Y0jiYj|&rNjhP1>5de zWl82f8rw6k9n4_%8qPF6ap1|a`=O$6zIc-@uwq=F4r3hOZc%7ytZT_!CLAQAYwWhP`0Ml8}F7O_iZ^t?faBSZJ^ZO7r!~?ErQ|j<~ zj>rh?O{7u^zID+)Wsc`s%_@$ti&?jPIM~@1HB{?pLqKTw&_grN=4Yn8TPH_ytq!>U z@FZ_@qt0;(FFFr*RBoVZa=X>dyY>0eT6HUZv8TFRAmw?U9Elpz|MaNmjqp)_mWIsr z+yT39E8IUE-2ssAh&yr3t21)!BtF?$6 z4wy=%(BrDgIo*k;q;DFNqvGnrCQnJc#SBE%#b-nl!zzAA^}0l@5ne06M*4G*r+-wK zZv>G`LvL=XHrjRC6s9$HPm;(`zvFek3=?LH8Tq{O&D`z&O}seaxv0R6YJU#*j8l5g zWqNoe4(;@@ByuplE)-@5x8Z0`m(vR0INbp^fi<^L(Z!{n<7abs zz}czPk7wEh7Ml+0a-?Ygx`;x5H}UU|d@)}|nGO*4=;_uy@DDYNu{!`dmP2(reZ_j7 zeQ|w1*Xec|aX**Yx*fUl_OUHSJWXA0b{0Ig{c?qPPv^dtmq(L60dN5k06U0e$q}Tt z6S6@H?bWw8aM(RZpVCVMol$!@kf-`_c5x=SW_b^fk)Ye6en64n$eju%3FMlH>jl%{ zf8|u!Zcj@`UwYQ?a@0i#H3?M9+bZ0(9LXLK{ezvYjW%9N4@wYvE$t}P)GkqEFSTHX z!_%POE4&c)0*LXaePL$Cje+u2r*f6i&Pxh3P~Eo8-vNJaTBDC9kgUTP?c05{RLtnphtGs%JRpM6I}@S84zL3Li1T95$-!d+=m*I+MSBRdlsB z6pM*O@)+X5`<#ehq?I#s>6QsUIDd7MY5}jRUc8or3Vm3mfK|Onu-+ zN?=pNlnz+(eEy1DgmN$XdH`xu-~yw*#YU=v$Mk+-ooW|07w21+caQyQ$eeX5BGs9i z>c7RUKw1_6%{@PZ(T4l#8o@&gm-dnwA_B5}2*+S__{nU^8wAvZbK zf>4ZJaw_KxetUzCd<_+4jU-ejF?swxS+w@%6ju9V%VZEMBV7lX2u%z|RAygKmHh|L z%{=cnR&xS{i#pyq%DR_+dKnP@cXF6FCR%%%>EiDyv+U179Bal4r}T#pi*`M(wc#}t zMuXJ*jp;FXb$ns4Zi&%}Ec1i!0&Wq5@6Reao6f4zayLyQB$+0)EnrmpM1@51K&Ik) zG8W?qzGA%2PYImH$C=RFP*dz%R^QHnU`beK_Zo5k#yHU~)$;6c6G!Xp{^F^A#-z;l z7ZKht(tIygjBN(0%g8R%+QEJol0c2A4vyf7Tb717Zcm+fWol}vOnxR@69#w$CL~@I z|K@dMKoBH0{6ciphzupl_ML9O{MWGOxu3o)l~|KhIf$)ZG$oztTZ`-PGwEB?@V6H) z=DaI=xYBqMP$B3*N4a^B5OrbN#QOR;m~O9Cr)rby@glLMOI6Cb-Fq^f^>*Ln2Ta)8 z5!CRvkWXHw)E(5fbEeb+)U?!tlGM<+cm6?hi&e*!)z644NUZFxhn%hH48w5PXx?b% zaO@@|tkns1LTV_%on*Jf4rLoP)Zo`iKkJ;yE^z3i$*gqQH$d{kk3YZFp`iKc*;z+$ zgaeDzpNu@Bg(y>x6M!}SAgYsZIKK3TC#KE9%G{E^(H@p7s_{8Q;`P0y?8S;N(RstH zlo|6ac13nGwo zZBbZD#ADHTGkFRkT(mA1V)z$+eaKjTyQp z{VV^3!L`W6!G8Le!30rt^#RjV%tI z98P&|TyQnJwqX;*-}}&BDiP!Bc-W^utiB9|a0v zpRaJ-Vj-4T9Y%#FkFL!(t@(OsUg`KEhwbBI9Q)(K4A+P|ZRqKJ$Io4$3O%&!SD*v~ z=*(#SoQIJL-{Rw5w7zE#yh68FJuBiSYJeZ>^evukwzX4ET+H`#C>Wz&?<%oj&@Jl* zg9o%9%`>aA*9@=N*MbcGnSk9VVr1>VEIf| znPygodqZI`S;NY??&EUTV@A@9=j!juG>b?v4aW8kxTdD8f~|wQf>~z+xypUp)=gv9 z(^aSIFN}3oC*2wqhpFnBt>^`+x%=0IKEQDbZS)K-AQ zfm44^#Rr^k-0ESGx@u1cI2Z@$>n>soZ;F2q#IK^ZO*vH&vAv&jI^NC{-FZ@lT18d( zJYMCaTHb>E4-APx9LV^B@FspZjOzPl`r-Cwb31>TeGTW_x$vu3b;=wrL2sk2>{g;& z*!42BTQty-&n>>=w$Wy^k413opOs7VsTj)(3cazKbRL^i9oJ023m;sE;vkt49F<9H zs0d`au5uYK?w>a;`}z!oEJW(xWL%57!2;IT;u@6Meza8GPC2+eDEyM5l*CPUpT+|? z&dX2ck1nq)~s;>3LX9DnIi*LPz@j4;^b}1v3Sfjt4V$ zfX&)s2}EVII0ZH`DD(*KzG$7M>?Eqy{wm;gep8r`%W-?<64qzU&ovYDIB*XTG$gWq z4aZLHCRcT`%A&3@L6n1pozy)b866~^lI#!}%l}xr_EIEJ#dof6K&7SMF3*9jMc+g0 zVEf}z&q9!a-hRWbdMb@rv=X0xi>XfPN@~57)V1dLHHm2t{W)6t9iZrP@FURYK?i6y z7!}^8c2g<96YpvaK6npq4Okp?o>by7kZ){xN%|BkwtDZ))-XO2FpZDV!xSYA=)rO0=fez;`61$b<<@y7#W#-?Ub~npI-aol#EZx% z=D4jUecm0Q-LEWH`iN>4n=mdFXaDW#!nRUklkMU5dbo1-KL@N0=vI$<_&YgL<}!6u<$}m{8fsVh&*Jjr({#g%c&x38 z*cR&3(sb=dmvk3$y{^&WtQ%{gIT+!+R8p66hok3lN;l~aE6Yh?^E;0Al6q58>}Mln ztV;w8S93$T810N#2D_`g%4@N~0ux@H_%VK|Rh$-aEc}h)jl+BAgE(U$esHS2U^+Mo zL_QLh(!a_Li;PLphDMau;<1ACnJgU*wCp;)KQqP*zZS3>82v`v(o&N(>N?iQ-Vi9y zPMqCR-IB}iJgXZ$h|yt44=_9~Yr_;XzXZt$cOWgu}W zA??b_k0!N>+#JQK8kSye{|Mz&m%Pz{lcT!o#of-j+$i%LS^Wmqy4oh)TT!}i!e$bR zQM8@wqSYRd@x#GQ7gFETaR^U$wzm`>e0Ki9m#JgJfEupA2KW7B(h!~t$IAF*79xSm2W%2&~4n}aW9a9ylgCMtd)l5yg} z;E~5FV^LRSOdkxN(-7u3Avra%RM+f(ev#?teugTzJ zDkYdUYzPvDec!m~HzkM5D1E)ffk*RT8!wpjeHYH+s{K@GH_WJiU%`yzNKEL+?2#%! zH?m3JGs?4B(`%Rzxhn8>nYzL^e6=r>DgKxNds+SyNhIac*D`irmX3gjV|E+-nfgci zC8MG(awag1R;N9u!Xw+S7yLBUjjS9ws?YI6I%Q)pJTRaz7mv-C%bD3Gev{h!uyVF`gn*Vzl!7H#p4MSMcVT=T zJqb$CpR z(Q(K5TUqX{I^G~dAG{^Uplb&d{_sIX# z<411CV@R{Z2wvQ`7tGPpPb}KearwjJ2`~`O6ku*^a0lcnN ze8zb~`%Ayof03=gkHeVDYUqsC&`NwQZ_yP@jUK{lKt>iZ_8@lEDt-V&U%cbu+=Yv< zBJ9*bZLh+j*$N;1%dP^HyUBmLv*p5*t1{MZf-iAAyl9?(l|J=T<_rbN@-#G}J0dSV zf4u&qVpX2sXV z+nn9^&Z#CGe+qyV`%vT!E{&={zKm9Vl*UzoEpJnDv_qolLx=f2~-qh&Q zJN%NpBW0y2!7NMLiiM>$!(@tn528^z1(}9!N_wRh67{E4{n(st@3G6@qp3YcoUFiZ zVs_BW(G6JsX$v{7t6ui)?WIGSI1!}Q7aSGSP8$+9C_6L=dd}Jqjh-3c4I*2e6fJH| z^+7YI!?b)Q9$dsy0#OYQMxQI3Z5VN(gttoY%hxwgHN+fHJgWxf{8%znrNPx$6t%Um z6z#%@#lB1#peMNIfqXt9?@OBkF~=y*em68W(pRO(7H?5gabnVNOqJ9p_MWAE+Ew8O zXYGL*+X*M`?GeK*Rt=4r)w3DvqwQwNv|=B{-X0+%4=YtmCsNiK4Kd+~<#NGm`ZN2} z`w56m4#*Zi%|!%av4j(3fU8wYs#=W)Y2w5Tr4`P@(-Wg)k4fa4)xLarn8QCO?zEBn z`oliCWuNppWMEMxHKv~lv4lpjadlF+)c!21W7vlKBzt5hN*)^cad47qr)LcXp3;Z4 z>13+v=Q3>=C1kWLhc>uCGla3o5HA-28S-cmpAIT1(rbZxY$&gh4no9sovRxtnDy5| zC)GuDVV*HV#Bw&1S$f;21HzT&Z97cKZxUPdH|cOxNqzY@1q>A88K+r3!34)z7lray zAAIWkn8-A_B8S>)^~$V~chL!R;)Ft)uW+;dpa-#f6d55n!a?hO(&uk|GalYhfp{l= zFyMEXKjV28+P@O(UMFu68Gv$b_Q1++I&2-XpG~k~8{RIlNdQ;kWN6P)SKN-q;%Pv< zA#RL!r;=@o{|43|bw>|uFcI17my(B@u7AQmzXQ~o>T`~FG#UdQZcn>7dy$hlD+{*U z?CS@XVu|t=&xl*m;L>~+)!(46JFeNR+q9j$R==qz$?C+}YfaX-zkHKfnLd?4>nwz=x=twj|5L$HN!4*awQo%>1VR zOf8S865N1M$sb*JLKlDViXKx?nRKf$J*(3-(=E3P}0STAq)7Bi#%tgzZA5D!IiKF+* zEt$@qQSFYi!d;*q-SpVb4NILEhU2I?4_e972f&$TlV$Eg5mIbl;<{?I`&s?PELz<} z%I7oV8~j8;i%0uEbPO&TX(XvqvF%eSO8Xtt7WYANBs%Eb|I?RD|2N5paX0n%tLHtg%E=i(enEUUvAjPxXik}VX)m4Y1>w_&)|p&` zZhX=e^`w&eKXte9a(Q^Y$XQwD=6*=T7H5l!dYlw>YI^jUBDSkUbmFkWI>W^sD(pK1 zr#QFfxSSO-T)+ZkwqC>e4_suiYr;%@8AWSmrRLip5pA%V4NGI+ii^d87y<9(RW@pu z`^n77lu@V&kIL@DfkbL}1%%*rhw!X9+r5ya;Z^s&65PE=o;RFMYa zyg4Z({fP9~6spo0Nyh+f>c!I>FkuWc1Yd*BsqKIB z{AN8LJyl(OQqft|`Q<_+94Dec;UXyYlS|Edkl@DJqC)pA+vJ&qkMe}L(xP)JNwHz) zVPo<`?g!aUw!v$#>f@ZJRAES;T3W7D>MsbF zlyT=y+|9rRvdwW;QH^2`w%pOR-u*1SNe>KSeR<0Q#$KhHvV}Di$KbtcD4IE(ovkT( zX7xsy6DB^|;)jny)OTIZYpPF*vmYqt{&Bw(Iw3@d{o%vccI#r_bUhfw*N~GaG&!xP=cri-}(v;3Ht?}`lW1Ll~3&-h0a^w zkbyhg?2nhS3xFN>a#%M*>=KNi=O#oOURLG1xfme#VY(fUHR3_s>eI)of?rZF%oy44 zFRokhI__)_3J&b$B8w{{U$ZrJwtqMcBz|vyDOo-NdI)Bkc7!y_H{#vHFaNCU!u!q= z_<^&`p*eXdDF~NQ`v_IJRyQd$k>JDQ546J#)>7f8PFTGcZlBv~nmg8RX?jyy~;X3~rTGC}2t8+n5P_IgE z3inne@WpocT;M?7O5T(<_XvbthY>TP`(#)s3`4Uyk)JLJN(_-e*gZUGru#WGS-p|~ zOfaX$NjwCsB7Hi$s854MGBCmPI+^d4hW60*z;c~>6i-GDBmj2M(`p;T0R42ET4UJj zQNbNa_E9KjsHh`<2MhVj7uuK)i`9&5s$w5gj1s!;fS6!zco9UEQmD+*uV}Yb@Nm&9 z_1&dQ%62=t_)Y%qmz^U$j}9aXEhE~2_9o4n%v-koRiUQ21{E2(X^rs#vReifjpOfX zLGmh+)S+y3_edP{P{BPfDVUH_DFuI&^n?HhbZF@Vwf5f)pNT7Mt|*w)U-64MHnu5h zlNs;6eM2#}-uA{VLLx;?`DwMy8BS;HDpeiKxn)EDQ1D3yMZ(yumug+jxl=657gNsU zXI8i}^4_mxZC6Frnk{?b1&}Q%=u3G1mE4q|1cA|1yQoJE*v%o$g0!vaHNXm!wiqtTe9<28|Zezt4HPl)sm_K$fH^x6B;-L9LH;K#?hQ zOFekJgS`d1_PV|;j!W!NlW)#&7)QQPp{(X+FGz4fMOqyk3G8P5n3VnlaD(G}N( zh08)Cs<_h13LR9<9hfV1Tl<9cr<@F+rLpam`(vGtkL{A5Wc1$it)WNkCc6VF?IpSA z&WwdspxacvAe-2q&hD)oVZw0i#>k2@dBe^&W zdj_NXdTaeftM=ZrVTL#k3rS3Rg=V*QJ)g7Q$y=(d@#EX4<_@f3uR5Gx%6c1=>#f>r z*qyg7Eru2u*%R^?Jf&H>Ncko|QSr9ValQPbV4rWwhE(iXNR&Ff=2@i7q|$zxu7c^* zu?v?Vh?6UtlJmHV&|vYXP}{D3$a;~H@xo7yKy1Th;Y0(v6Xlq=7fjPO>3QU=VnA!M z=`c4VULdyIf3JbsY1S?~Eb4kvsFa0oA%Eh-@mTnPR6Slhj+4s0nvA7R&18U9cl>-8nxmZwL^x#x8o60-Ae0NeQf>W85FwCDZ0MkKkv!xsh~>mM{px3< z?@KPC&lzUSM2~{Xi*!96ol8aM5W@(f4h58Ru?2I_i$kjx9q#p)f|!J+UXv-VvL>@_ zdoCv@Q!tu^CPkYZhfRM^g24m`2;l?0{f|vbB(vThq@9Pj)Yj=VOjRB`anYI_>m+$x z?OCmCN3u6_0^JfScR+s(J)VOkd$?ZOiN+QB$D%zlDzEJ5s$OGzvZQB;a`$r`w=dFp zSd)oUw}9uuuO*3nQ*@yr{l>_YhZ+Ziy6(&1!%5I~57UQ+24rtSXAP#%gwHjniT=qb z;wsRJKL6~&xa0eE(A$qLn@)yGpAuAO#qR)iWd|_|t|Iwlkr6}HZ*mp@|w}_y>IcJ z?UnJ-^z3<(@v=#O$-*;IjY*EI#Jb^+>xo~=pIRVJn0#Nuxqb+bvhTo#rbluA@P^L4 zaE7$jw$_2i@=Al^v78QP?Mwut@uIl*l!jQ&)zH7Hs1%eM?|Mm6!EZKPNbC(Hva3_7 z7WEJ2bjir5injCR%mueUyg?W<975l>K9d~I_bcKmKBy1A4=)*542ivFUOz!oDKZ$U z87xA&fJD&1~@w z0RfFmguG!^eFwd0G<5#9dGMqS7utQvN6_5ZKpeUxH_1@CGLrMlhUxRt&07(5B>}Pv z)YQ`%rT0}8SG6g2Ry1IA=^pc&EhXpZPr*SE*Y5GL09YQ6o^)om5 zv104+wq5(^1TEle8;U>Te6;2`&y4XQz4;3@o-5MRTzllBwO{*^#LIXVnb1YfMSphd zEXw)awn6#(=>)#EYllGal%J>f(=ntd1$Z{an;y1_c!D}6oScS;Ta_6>JD}dcpW4(< z1ga!a9a7){#_A<-pI(E}zDw=ZG|vSd9*F*rm{1@3#hqqCfute!qxmGBw8D37bnIVA zw*u0`Iv5tg~vkr;5U}Q-c65gL%WzZ6kDErB`%{E7X<*sY4o%x@c^B8+hU_ zKft4Ee2si_d;QUJ(kqwtbYS)dDrd`+Khw@n$n@*ZYXbB7;d(JW*)pv^Hyw+lGI{ey6VVYKMK&9s}_IKbRJ?= zKPBkrxr8ouJ@S?d5)=5vu-b-?Z4i~)Z`6;hZv763oeLo;f_2wH$Er&9hRvWy4aY@( zF6WqA6q(-9Vp!_c#qaQIxD ze4>@MI4d?%6m7RH+qgheo|G2vG>OuN+}OYqCCQsG7>x7r3|iZrbHK zt&riFZ-Mm3p4SsUty;W2-m%B>oB7slr1$x8w>#v)g$_Uoy=(XMKp_%aDa_w8IL{{* zR>cXKo~Qi$&{rf3q8s9SF6U3zxvpF>>auY*77y(&flFS3i$NJL<50kJWNww_YGK_) z8a|}dPesR&s?f?HKO6GU(sfxx$|MN{%D=u!eB2%1(tECPT_W z9bd^uP`2s4JGzU+JTccw|KoOzf8DzAe*&hzoBqqmtW=T3I^n8f`t~6C%dkIh?0dB! zh4FX(p@v=wK6k)q-GCHnpl#u@Z;kfX zb`=^j6ATqB&L1%&dL|GPWw?22VfL0*hKa|+Xel;@NX=$j22dq@YIA$=wHMZpT+%^H zv)p@(&_E%T;-xQ)4XsU42v_vciz7}I7E9El&p&&^UmSK_N&RXldTmpfn}Rf=96AWBqsM6b0Ufy2|Gr($Bi16VZG4PgA0I&JyBR#hamAMXMP#ih^x; z{Dz&)DJoNycnybC)`yLWYs!K*!}4jTKgIi<gq%dxBAH%Tw7$yZI@hrY$PwEK#sI*j~oZhm&eJ#B&uQrLt< zq6E7iN7+RkooCBlcuG=tPh{vo5&JO4rPN>q6Wf_K{|!D05WAl1svEwm;xbD+cpVHz zY)^u&U9uP~mnFIVm!~)i&na}X;o}=Vq1Qp2@{+ zl7=9eKa`$rCQfJ0!;FR3Ln64GshpIq)Mp?epU@5rU(Z`oSh}F%L#D+Zxoo29ew4vg zlTCaQL*rH|D~qJ9Ee`;$046 z$6Pj?B-g5Ejr+RHcEQx=_7gb-d$HU{Cvmm!K{_Lbd+j^E54%rk@dTSQXx;tiUbGWz zN<3dOgb_s6e^OPeTRIP@7!k3};VR+yxT1_poD|-@-d9 z?FO|3vFzlEc!SVdZN;r)xle}=jjyR(^o`M;5I9)T>7}>sXl{r$d@GdQJCgdQ)$Cm? zVfd(?Bqemg#-m6tEns_k{w7mAYa2;!=%?R1Gyrtb1=vP^z5UX52fRn@=D#?mzZF*a z_m)Hx-Rs5!WuTE=!7Q@^E1Ei!RW^~TLDIS(9qg#aj-8$<>?pet%gZL)Fq-Pe(3G(zfG*Hyhq_qzk0KD+}?mZh$p z6As(PFR>6O^MVoQ_#mDh4BOVqv^cU;%xOWwstxtYzUED->!FOc5erJa)TF?hD7}}O zJz-B!1Z8?}@t_GWJErac%<8BTyF0+q^@854A$n=d{2lpest;jG?2l1L#H)T|#LZMG ze;k9ozJXh=OA+5rUJ5n9BKuA6U7O~2S2!3nG`*@voLAeg1?yy* zWEZa}TjR#znsW8`#Ua+!9$EiC?7df5lYjT-i&#);g7g+?qS8c~w4fqgKva5(NGD=M zT97~#q?ZT?CST^RUs~R2AImfliR2tsW4O@_9%vR7R7OOl` z2e;KZuTK9Fl)0+%{0d3vRhEs*pyXATvf-i4d-*~m1ivmO4~j9VOf$QQ4)D>#c}C5 z)qGpX-hOIb<8LOh)V(aP-f*{Enw33%vY0Cdas+?TQ&>;#d7BUV>^f7I-uvPJL1!*^ zYCyF{Yj6+_Ki;*+uB~(5Y32!%P56W(xZI8HrQ=F}SdxESmM~!3Xj-r^?__F?deJeR zL&sg$^LfWm`tJ))e+LbP;iwqS?!k3OLj?_hC5)%{;<9YQZSHS5I6%t@bhQWGP=26JuP5o_DLuLh700s)ZgSJ=v8Fj z9!>GbxBh@aE82{aiCk-9hzCA>{7o@(#>SwhtMcMGI(&@a#_;Y9X=}hA$o-AP20}oA zHrx7NJ5t_*4%q-tJ!bu}bgKxd<$g}jP`y{j6Vs2}KPfykR#3l3!tkQb0sK@Ja<-oD#B>* zHbYD>Gzzjg^+)ED(<_V5RWAot1TRPRJxj|8wd2o=V~#K-T_6kRF_7+=@a|b5zzn5( zO9T^pz7+>P^e>**IA0yB3HrS=Y&&h_W(#%Q9C)f8q>UiiGRivC$Ju(gd4a53T~1|DvG=CHR5L>EVn=P33hRIS)C1sUgZNxLBu z=e`9yY$+~{W?H_lvmTRX=$%yImm%)aZ5~B)&bdHkD1K*nLy1_{#j8f3gV=xKJU9B5g@1Cz`lZ z7gM-4e^)%zrDd!t9sVlSJ6$wvCQEbrvd|O0v~M}TbmmfXY-4EX1kg%o5$)?s-#5fD zgqnP#Q_RisPnCo%SbVtKmosbP@MP{Xo4y8{1>LGc8%sjGfO64Kv?vn(#>EAhi)*Yo z8F}Nws*CKWd%mVM-7r3$X{r6(RcrrdiYkkW{<1a4*V4C% z!;+tJHv~1$#hiEWw-F5xee3qsocA%>S3hP>H1eV!QGA#nrmGw}uXDm_#``8&8T&95 z8^)e-O!LIV$h_XGn=-MAeKL_^{MH3l!$rV;09%|SgTE|Vp>RKVAX2LFW6s}IuIwK? zj}%-@{2BVW%vw*2=g?KTM7J^ENzXFPHjWM_CbVdb{EMakV%~k8%G7%*QiSYVhi@a*xKH_@>vwBE`0ySmd<#y3*H*}6b7Ear zwIi0N9{yVOA7Gsn_b?eTow)mY%q>)4sPf9B8jvPL=3eN+;56l^fCDt07=bw9Qq6>mL+M2CN@}Y z_BW}s_p_2!CtaqJDw51)ZZUeL;^e#@>nyMT{X?Q!k+AV;sGAJI9#~SHuL?5Ge)M63 zJg4f-ET<$r9rL;{If{4w1&=J>n)9K7A1^&)8A24Vng_fqO1xzBe|n9K{ulXwHI-k$ zl4iVV#Dw<%cekq~IvENbjl4JoR65~?gSI!}d&9SC{Q`|WkFAEJyf=RM;51|))8<~d zzoHTCQSTN%|Idk12Dvw@jjxKxjYPB;(9_qxyz_P3Evqp8K=Lf3bcCyYv<#H7{Ayh^ z!~1^Wg51_|nV&q&@26x3pmJc;gu2mb5s!T?(lDFmhz4QD?G5>$pn)*jU=8uQWW>JZ zwld$7k4?L!{6D?BAQaDL@})1etP`a(%@AH8c74 z*}BjqQ_eK1=Yh<@*Ak5pp|@2^5&nj#@FM025egGVp6$%n2b{vFK47jf705ubG{}t+t`KE(OIxiyCdMOl>=1R6?fSPehFv1TDO@otsklSiQK5%& zKA+}W0RZ$fl6uLJXX%fME0GXadRzQ2L?RS2x}|2n z>>xdEdoL3d-7|hn%{UD;S-;-A_t^GY3;a7lYyUd3`KOgA5DMM|7^Uu+Z zV-^`fPa_)ZPn06ceHm};Shs{;8C>}y(QA~_xW&QF;SKAAH59}vAGlKw*=dkxTe`v} z0Lip_g749zYDP%EV>0n6dIz+ zXlRPQ3l7M@qVxdtyf4a`$%p&cGEPx+r1bq>7?axhwmR{oQhmifUSW#nGI`CMLn3Ln zh*6e;;@;N>+CYgs_d9*c#M65_rKDSpBlbp8Uhqr@>6a#S`pui1y~&BTZh0kfOSoc*8A7tEQn4}wDI;g5%J6SZK^z=9X zANayh;+)9uwm5XdU|d4bXz6!k;82nk0Y9E@8uaCOW=1dkboVjKb*ayzZ}3scJ-T9E z!~%NgCL2u)^&*r6;iBwx<&a|XHcjHlJ|+G;*&qU&$9L;?f-LF2#ubwt3)S6kjMzf(i?SohOn!m) zvto>_5(*b4^h7OOw(D=dTJ7~y_@Lxof3xc4p0K@`<4KBe~*DB(QT{dZKo+y3rAcuUr(O&fIwGruOAM7%>F(LqWN$A9y`{Mv#B^4FFhZ^$MEfw`mo@prW_RX)2}>k58mIR2QZz?tBq@B7jV7 z=ex*d&VLsSHjO@2hdS1E;|)`w1n-r(Z`iTW%VyB^?n`k-!W;LZVFeIYq5^W;4%nK# z%uvDx2hUq2*TEknwfh`gsyD1+N_m`K7kgdg-i;|5dOXFlBYa)wlUh1^LD4U}MTyGr zVn1^Rse4uhn4%$$!(9a#u}$zo3W-*sSp5LsfWv1^sEx{oqQd zL>Vw3z4~WRs{0O3zWJ>5#i69F8lsqPMG5E-KA-C;dcJbU*+Q*wn2ROFtY^#o$g`IC z?H~+=y(>}ya4$xZJD^91W4{NDZ?}$Me>q_18{&*xMm@4b3&T-s*3za@lEUs@5&bWI zJZrLd{u`V4N3auyyXCkKJP~*A99jA42ffltKi^<+U}x>?IHu9&i@TRDGZoDF{Zhg? zl})dsCkklFl%grKv4iWyD@5U3`<6O}GnC`ou<`@Ei<6D{^-wg?^tNo3fP7}U?G?{g z&s4jiwt`T65kYl+yGIKOvK}!c%4|GJlZHO!JazrUYGs%}F^l@3k zGld=OuSCf&Z7S37-4ISx5U@}J$hH5C!$^&)TZsJh)UL8UGdb0m;&W4@$W1O+x2jJ6 zRbop!xuHkU&4=9NA3?C?3PNicR!A*Tb)G8-=pitZmDB;w4>$y{%0#59Ft67LH$#MHSNms|7@(^H=Xfo#>O^qM-h2) zdvmhm37Tw4iC@qH7=(AR%SZDt*&L6Iy;10*$&KX;q5MbHf1v9Ty`q0=HiHylx7v1? zk|=Y=G|&6OfTR?0wI5l4(-#RDj@xn>wc{A2D^Tu;^F(Cxl?OU?cqiG z;S95wY7u&aKAY|Bd!>OgTZW}v4@B^}jq`E{C)Vp+J{@x?@L_1*7>Mqe6=rxfF*2x2 z)l_*5$CRVXwJh?fO8d1o#A_#~4tRuEfZ=Y&<1eC}REMLLKMG|8-2NT^L2(*$^!=1A zSxrAFUkFTJN;@X>nYko)jlU%#2*|{mVX79Vrcf{ z>~(08b&ppdrHvVo)S#A4?frdQQEa1wdgkQ5-ml9q;JzLXyoNE!i8nOtuRQqY$t(`C zhP`@Py_Hg-+{-P9>|H=45csQ+upW`cnm9OjVo4(|adu>4*2#YKRwhL&Z7I}B@vidT zUCwAz`REXRy9?N_ST>Z`L=aXK>^2b<1_Rys+uD=Ryzr3ts>=tTDh;x(_0Y4qv zkoL~jQ*=>SH1I98;N-tpd=AmH@x#=LQh*nU68No{Y^UK-`6{z;}I2|m1%v$#4 ztKJw1j~H_nYG95tm=#?NQBH-CWRiXBx8PL*L>)`o=7U@NJhe*Ts(83}#UfDEY066D zHJ`=tsvVX}X|4N0s!~y^8)z}&W#BoZEap_RcFuW+E_TSobs^%FPv^Vaa0 zpHZ*p&fNV}egrST^5l=b^X^~yAO7CE$&9UnDn~%t5(p3n-(JOEnG?aA3P9`xWyl<# zA12k9fGB;TI5^nZ^|iLj?*rSwe4r~2Scm1y0E-Onc@N^5Z_3KL!Zf(Qw@vs_?3ZG_ z#o4!#sXkbN8BKIojmyB97MU#*p`%M$_Rfcwi--!K-46bH^ii-rPxt(44OHBxdCJFb z_B?Z}(L5$gKC?b&N%1l^PqD=ASh0zi%4vt&&jMB?*a0eS8_eYl!RHNDtY&JEQ|qB3 zO4T$|oJl$#a`O&N^*H{OXO5A#O;BHzU*G{YZ~kCoZQ`ezS2ye_%N+3v|DTW_BNJ%2xVZ(Mtc!4`gL>WD zfIGF-)?fZE;|{DdNT<3&U*{9#q#{HK~N zf_NZXY6-)oH)`kwNIN+vsUB|699G)Ap6Mn~0Z&NYS7~_0_rtE@Kpg0m>srV10O3x< z+_48%RQX&Vbr*Gn)Y$z~;evVox`K~mOp7uNj{Gc^mp^gaQ2zK(U{Tuz=tW?sT|-|y zQk8pp|2hC7 zDULCDr`9J_kl-{pwc*bXe5|6`#McQQ1v?Zz)UMt1n41*xX717YTl+Sqga72?)gq$9 zFxsazv|HkI>$tAUy!@s?caCM7T%5Yg5yWOXJ9~NY*@hiIxyy&ioh$uUiUpMT&R_4n zD7P7`UiN(Z_ohLIra@PZX0qBgo1X-vVeEdhzTen@(JB8&-qy4R z4`vkbV73!EHYbpAhhZF33@8UHC!j?VuK z$1C0}J5N)#57exBm5+CqA?v%DBJ{=i2`WV2wrPYFg}IgdR|2z;`e&6xh0 z_V7*BfYlWhLvQCOW6_9gn)fE83^;pd90Xzr0a1!)+p}kNTALC#u8TNcn^Kg#yJ(tC z@O)VrfOA)jT{Q+HtOZ!;A_aHj7|^zbAr7Q@50j;do`OjYTCX-HiM(ijD~JuXILd~5Czr*BRS|$T*az3^J7l+ zryQA)8pn$@{{A8=vS7_|tPVB2@#QwmT?7RN%P)pVOdM3rmwBE{l=S%<@f?n3?RY<3 z`n^ED+_=KGzg*JhJI8gKs3%T($W@pYD8Pm=6_Mlx?#?iRI`vgjCsCd5(fnigjvqt$ zi_Uj7JZG*;_r|e-@@LorLO})}ScvYgB?9=}F|ux$J5`wt2<+HBJ3R>$bpM5Bd@%K` zf?@(>?#|rg?eT&xGb6-uK3|yQ{oUdsO48?5b78j}JJ723d0Nof;$py* z%hrBzN$yjvP1IcEoPr^bPigSd@^+gX-`FET{aY*8G+p%m?KKHu1|&%heAj?W2tHrv zk$Yf9&bD^3rF2kVwkws!_EGM;{zHoxf-6k^!CZMtEKmwR{89fvsxHv8YVGP{(!5N5%*l3`^Y35dajv> z%h-36U)kEUGi^D~-WB71*|KyYfIZIj6lc>(aps$Shc&^892lksbu8ACObm z>4uEa;6by#T_GilA13M3*UP>)tKsXMN|KrkjGLJErUMEL>DxUzU|Tktc0NuZL;Vw- zPdli`bh=me`&iK87;A&F2(HCQwBOUeS6YVa71&B@OayAkyB`?ngc@D>5|lOo*NhLw z@F69Jdf6XR1~hIvPR*DNtMOVX922lT&6D|LV=nlf>PeLNzAIef5_pA0yYMhBb#b|N zrtY}gH-+GqJfoSK2jgBlXN+Z|E(RR=6l;>@eopSu=CdnNU<%#$13yrI>WEBJTo*`# zi5q~5S=DeJ*R?*Z@ZXJ=cR7rCl==pv>wqJFmQil=omr$6Gwe297Q_V*kU1X+d(H2` zqtyHgy{xtm=dlR?Bsfy)Q##y7CY~^2EEe-4=@S2qG-&}zOE4^cFCwapG8GT3$MyYs z>8aTzynWwz_lJNw&Ok(mg z+DN%r_DP^KJXeo*Y1tN+zcE8Pmd(>0;mMoTu(OcRcsbo!?8MP@F7U%}MQy4IAo6vu zOaB;DX$>uMpcAN(R)p-?>QvsCJ0t4!X~41TOicmbZX?4aZ8FQ*B4fGy(zRn`0{E`H zVQ}SEAc^Z8Xs+!88!9Z0%u7LLIL2Ay8`8BlA2@6+)Hh_B&*b_{3qz4VpH#Lqfq|HO z&+g09y-it~Q=2IEIq?i|8YVVvMRn2ap4ckK%lB_s zVL^yoE?YMuMg-P1$G-ZLZM@1eUtD9!`fTa6EG>P)G~{KeTuQMrKG|Em!XakJrl{>Q z^CZfJ;T?6LLc=7us?%$VtB}P#u37~8QqpPU^X=T*ZGwAgy=8`c9sV1NRnj1P3B_V( zsQA2-jEA@3vWn+19LR|U8sxcB1B@Seo@_q${#)VLgVxl4u~?4ROpM4UnSZ9;-uIlX zO5uIkk0*ldxB*Okc?}zNJ6_k9=5icoB?dS#dDwS91;<%xzi>=0@S>E;q?=f~n+j!d z3Muhn=d`dAppL;;KKx%SQTd#}XEipH16bv%quDB0I~}i1Eh}d~BAMMs`s1-ZRT~;H zo!U^P1CDiIXJL`!Ox2l%yt|~f)7akyTqvyxoSr;vTzb5k8j<5RP&YYcDioe=A0Xe` z#2Urg(s*qXWw3v9jZBoQr5ALdPgpQmw_HvPb&*F>jKt4VMlHtzcXds*_1^?ME+0s9 zi?q(VuNv3a9k^yDzq2>5+&u^Brr+pwp_8L=`T~AW_Yw)VOxt3#KrYuCghc6+H9R@+ z4|wXfl}X{XynZz1L%|t+-+}}QNjl{Dfd!pRLb#QiGDJo@iIN|4@8MyWeo`3cBJ{k@ z^oxCS-ICtCAlQFf)OY3?*a6o!@WH+$xPb`M>>K1@3>SzbRK(5#`WAIW#(j}-T+Vl^ zQ2$+Q?c|%{!Gl!+p-rBO<3{rX0>$HKzb17Tw9z*xFVd9Y4y~j*=?nRP8u$Md2D5Ba zl1v@BIAPS>bU1}bet7e$ZAL&lSgG!xNbDQ_eM;S5s^2DkB3yugPYi?ywJ4ptQtmER zna)3|WA8B^?TC{G@!QY-qd)!s8U_7d*m3`}vg5y}Y5?j1>HXWjXfA>SJYS=9P)8{Nk{?hSKx{J& zMhY)-0N6C0&2^0I->&j$nsdBc-o z&@Jey++Yr4^;2D+mGOTe0yOF{#p zXu2;oi8=?M^ykHT7x4lkF8QDuAp?$cco!J?|v0Z#HT(zWMGG^4OjouPQ?EO3xde>o!NPf-LklZx{r1iy@a1 zJj4Ol5P29WNpFlUb~4t*pIWvkSqq$Vz8?DHoJT`*tTnrurN?63Yav9#O7WW*%wUS< zt`YD8O?8_gl_1$WDi*lovLnybj-ak6N#UY)eT7G8Ywo_HRs_uPD5}3U|1A3nb7ur%#ri$W(`or(>ou*px6&fbUa$2UgD zer9bm$P&6^n`eD9mBpLo#C>hnr*A_l`KI?z_jVRYpuN%YFg|sc8zj>a-BST>vZc7j zXqsqu^C-cPnw7xXGWErqJ)%S!qj7xaoed(5bV24&nxRY`T*gG62I8o2zlVrmEcdkU z(L0}P5#)*rtGNYe(i{ktcfxS1;(1shV0b(qw=(z6gf!)5ojjft*!otFn zueIZcoxbbp@9QARW`I5&L;bZ!aq@$*G9obX>KE@gq!1b#$(n)MPPNZ;%xr^Mw55KC zeVi|7xOj3|E%34lkU`ttSY@#H6fbZvMO%i`(Gvah6%E0}e41JcK|Mf>%(~Hwki35G zmhobO>VXry@Dt#|n4)15byY$cEw|}Cnbd;QYZHGD95rKdwzgahtZQ{PImgF;-1d*U zs2{di0#jj8(dGZUmFV2zzViho{~l#<*ocs$=YeR}wzvl$8Qe+dQZ+Of$QHBIb&HSj z{hfb0XWiuAedVkZ&}zqez@j8B!B`GL=@l)bOftj3nq2cMZb$a#JIuWi{|!k&7H<7d`0*WEKA_lB)rD^}W{%VwvoOk2uC%q?aPs?9U|!_lDTOM~x%5 zWK8m5X`#C4mM{04Sk7WjkkJniM*)z8EJg(6+~6h1-Q;|QA7YeXqVCbO+{uJx5& zXvl=%<*5>Dwb6D7EuMw6#NsQQlN_d3Hx>azjsB)EoDuBZ!0e6gu!D;Fu(weLrzy#T zepJvP+sD&$9qP6DT{PhH?%IVGb_s<@@pUx)TQQAX06%=GD}>Vdfk5L9tJYYzBWLnq znTw19)sQWXg`7X|uDLpFSNNc^xk+y<%Jf9u0$Ko>zD{zS>8AKl@@m>1|D>psj2|s; zYPi+$fK#S{IhA&~U)qUUuk8Uy$G=$Wu*pG)C^V1m@i5KUhE{YJ^b$f4c(`)8A71LK zIl-|1@*oNFN+KM(4RZtL>;=j?Cg}@Ko$7&@{1( z|M_d~xP3(atZ2B${V3XMVU&3VyUAt-uR@q)U^@IO7Ah1u;>rt@GL(BE?1%%&fHHu& zY?VF>l0SB}8kTEE-!%woMX@;uH52daU$ja7^DN7HH|C$z@Mkb=pWhjI56}kr3y%8H zx}i#ORC|y#W{;$e69?7OoK1u9yWqG#WZ29z|Mtr5*yQq=PhNO}^}eiMPFyThVve!` zg zH~(t?JbYDc`xp?iaD&kg6j+ZQD0=*jNDh&tAeJ(Fd?yrXvuW3#7M0`lJyrqD0 zW3carGO$VN+X*7?^TJDe1(Vh1j{1d2g?ZVgLOA-5&Qx{Wzh6U>{t=@jl=i6%Vay2a zICKY5L))l_dm-O^@Zh)}r_5$j_;yxy@NoL>DI1M2FWD4PnJ+CNC#F3xMHh;w?hE>? zC|;n}ovlNN;Hw#z$>bdj_tja&Yu;g>(b*TUxH59j!M}Lwu?xxU#S5Ebm9;ts2iNJ@ z3;0-&0>gq5X`>JA3U-A@mrpl-A_usvP+m<`_y+1VJ9W#1noHeCE#DNFyed-@xC_Q* z@X`E0o@eVSc=2>OR@ZS-FrMqZYy5E%FFQZN1w|lwd5!qa2v&kE(yQ-k9pLHs>68bVn|0_D)^a zZ2?1ro~3nIA)oa?XK%art{>2g#RwzYy8h0^`J;R*fEE%{?VC)k)0>7V_~7Yb#VpFA zXR4OtSs|ZW30c8VuW`A4aZECi3xxov^V~v!`ND~6YPFKy9rh!IzE9Pz_z7s>b0Rut zl5(52sIk6XKaJ7|lB^0k#2pRzM)QRwH+QPlDQ16jRw;s(r`eN#2JoM65f3G4&Po{3 zp|34=`Xk?KJ<4B$hkK=}yWW|x`T1Q@u0QHC6P&oX%C-S6ZVNM39sNZIYUGFN!ZM>C zt(s4pC#TFG);IUFq@J>o`4`JQcKQ0++2{8(XU6{dmHhK*jAQm|5PGeX3A}Anhvasc zEXTvCjQ)EecjymswEpnXT!wxK!HSCASfJ(|?aJ3?z%VF1YAeEqA()K)eW-M}QPk4X z_^~N=Mk?WbJ`3YBMl9Jz_~oO|4@`T<)b4-7z;?tj zU*Cl?*q;67WFtv;&arO?=^ef2lt!zpJ~xfbU+cV>V_$^KnZA*I-`^l`H@5vqlmNDp zsdAt*!IZR^Hy-xJ;Uxqa`Pnr2A)HRx8()u%ssw>9RNt*)AO8_iq1~0xzgJ zBV+gBIKhJPV1b5>MXAoigf*}wPQIakVX6Lk#f|x2raMA?bwkLvG-XQ9#}{p%EP*1$ zyL z%|CUR{?($xRNSDTNY$>kBf2_O$VZS^;`wpqW#(w^rh&`ouR+I^nOTSKhqa=< zFjQU1orXS*Mu)(}eOjW~Erl>dHzE$sV54#;Fok?G&KDfw3uk;aMm{QvaVng@3a*f~ zw$wcGRW%jff1pS2r={$rLIsiAy%z7LW|5jV$iMO&#g%AFK1&(5HGKVL@p%a0OLxW^ z3U^<59SKc^uYoXSb_gplw`<1WPCU;z(Y#Krw!4FfuLt@~Mt^_yAb^FU5~%8c!u76m z$nLTbp+(&19p*o*Nl%%u|cZ>N4 z>wPIf8Wu!RxTZ13$^gr2&w$S|&lh)?-OY_}<}ql@xcXl#>O!jUYzv@(dRu7rgN^Y__jXung-2kBaXbhxciV=>}N}mrrQ@*_&tUuo6I$cJBi(@PbAD z-ZTM>X6%7h_y?J+cgS$Fh6qigFtU5UNMFmA&ckjAbi2vZdg-~m(#ca$Q+0W*s-R>UkS=8r0Gw7S4!#nY zg^cRn^?Z_TC1vsx9>NZPj3o=+?^{3dVZj(>JUdPn`ZLg^-ba+?CR;)l1>KbH^t{Umq2= ze-Vg9#1mB*Rxb_|=~LYTM2)7zf3a*r)jx(OZ3^stvG=;X(fHcs8q+@Wfv;p&GU=)e zd306{Fno_B&qo&0@6hZY`Xhpl6qQWaRv?bI7@zLtdpRX}N-UtcQo-!nY1Zge_~eCu zvKx&Lu-Z2TMtdQg>O+ayL~aZDcFobjP=O4^jf}M(T4%UXlbd?8j3s-Ga5$v<0o!- zpF8~X&)F1((Ci$dK-zQmQXUf7*JcIct}}XYP@-~hX_IzpLPTU*^@0I{&+0fW%SuBw zjdtV7-k9n?8!UYRj62ohvHcNJ6Ls zFW*_u|K#aAu?eG?f9{((phd5wE_Ux`Q83R5p5U`)bT7*tp;(IhJ=kBuai44C)thTv z@h#8$k3>Zd{im#kQr;I^cRe%af1vD1wThu+$NA$bl-(H`l_jEB-V_biarLVMZ<8cIo`5erXJ#-(pOe!1d$4sH{&1x{N{&bO;bOv(sGml$ZS=bfHA!+^uu~|dF~ViySs=UI zbuCozX;X`fmC>hhsy$+W$3WB|NYpp|4ETb7kDb;&#Qpo;EzsxYGnYx&1T1!SPhgwc z53Z~V?-bw>KsT}t%QngWfGHU96lY$x`Jy0t>BOm3eeb!rr*oZ{7;U@fx`ukygNG>- zm1^k@I)vj09DDAk&V~e0Ug4vu3WalfjG)k5He05Wa>5m0q^a7wQDjE3*77n z*T!`bMT5$DN_m%NXI)JcAH}Df2ixtN=>{U{sYmX#d(0zycLRYA#$8LsP@-;d7`0zt z5Sd}|twHfpzh%zquYOKdv$4@T*@I2#N7U-ABm=vS*qv@Vm);g`ZS^Mcv;0n(<>6bj zPcGyHxcF>tx8Q|S2a%oORZ#8dC*i*`j`+1M4*Izf3efAZ!q%t$WKQcyDcuuDZ!;_} z$$MT|@CJI4j^5;?nJcFdd4Y&fY9$QZ&DT47sV;xpVc*eD#G4}Qmha?Km_lo^i;orx zO?vn&-N8zN0zG+f2e?aHhw-3TKhY1z^M+!A(ClkZ(Fq<+_@nzrB;-Xumo_Bc*{C(^ zm$_Ab@+g;T@1)w@C3Z-T`Mwm&zMftdRi*BWl3i#b=u{%}_wNm>uPV(CtILs<2D@9S z_M3|!Bl_9d*CmN2J-a6-MRUu)p*;%{T*Uw_{g{SzEc+CYPomv~LPr!g7V<~0v(7FF zj|>)@+-hVTH#W2%-+k7m@&ohD@xt|j_=L!$L*w`31j_$|63Ix!{(0-iCRM4Nv3?vd}>!Lpkoi95euSN}NsVk&tWn zwi#R$DxwZxKA+UaXG{x+ zC&dZk={~zT-jhy!S@QiAHw!(_o=C7&dpwZ*MDQ5UmZV<=;+T~7k7N~LNgt87gW04*C))NV8zaBh8hE~t z$2v!{n-z~X!+%rXPm(vcX&&AzdsSVrqxi-5Ntc=juj#pT3n##zvEL)XUI#mhvWC#p z=6qmh$kfffc8J)v}dym?CIJn~C>%aIjVy~B#$Xq+;?(`r6X zGkKGsLIc5p_pE$F5@dJFsy`4uwqqm)cas#Z#lB<<(^$N05du0UpjVI?JrbG>HWDJ< z^$g-TkbSeRe%!55S=!gopO@dp+m)+CO<4-x?{bZRqL>x0caklim& z{p(fcUk%!l9G$Kvnmowj;gzL)W>h2)VFiz$yu;lAliH>nO_G+h&4#*3mj>+qQ4oSb zrz_`Sz`DTSoEd|%hdZ0gmy2?pGI!1{N*VS%?qxX(8kVYkuu%)Z!UvQE9dt*FBFWUP zVk!tghbn?q?H=j(5EPh`V3s)o9#s>!3)$k(o>BfKIZHJ3aAD>s^9`9 zjZ%8wgcrlLW>+MT0;Frzo;H$ zp<-}N&E{=V%V*SCw@Rl~JMCY8OB*yFg1EP7m#NhfwR*<{kE7_CuPEQtZBbc=APQ=b1if6zej+j2^B>O?00G7F$%#Iw2w{1q+9;l+t>3iC@XGD+)TS|v?=vQFvNlHlIH7^ z|L7mH4UyX&h{W^*M|$g4HM-c8I_Q0Ke7iy1+a!ysG?-O*f8JCmU;SR@={oJ^XTtV8 z+Z#6jO4 z7b`JKvG<=5?7wVO^ZiNpm)l(4&%w=C+!8BHH9X^94jXBkjY6U-29mIz)PNw*rsgr} zm

GO<5CKa>vu^uvrO41|}mKbHj-jmfbv1#d7U)0-Bu#QLe`Y!5$=2WGzylb-V=Z zLCRrnHuxwVuMgA7%S(0N5x8tTdkI++-dVui=F52&w1>qrW#KvKDD{fq{;t}_)@=JR z_ok5pO^#>X-f+a>>*30LuiU+N7FvH^U#fxrr-qNRZt%V^>NdlWoV3YHZqG^nyO$v9 zjANvJR9a$)g~T$H+&?-`nTnSu@O8?>-gvM4%BbZFtcYMhhtclMY5*O8te;Pglz6Hmb>IYXQf`$Z87nmB|s&RSn5(+ zV5NhfH;Lk%*oNPFOdkxbMCSaQ{XIK-E}3YiZBn39dHhs|%)*A>Kf}XrujObVtFW2*%d#D$20DvmrTT`_XK;>s=-_zoss2ohl1w;Bf7{^u~b3&?-g;ga@P= z5@6=yIB*9S@zQ`QB%yG@rP<24CE=&`St~7rZ=x)zT8Pfb>u>le2S{_H*}?4%SWV5% zOy~VtENd6)kO(I~!1^euH$&L5`Zp`{lx=H$ZEJ#ZI{DE!skVX%tDSpA-SLu5=a-ss z(U4#!MOGLUPOW-7m>QB0)q#RAx=ODA;ix?OT+^qT_TjoI6x^m~Vb3Fj_@FY+0k3zB+D$^G@)mOJmVU_dHo4Dq&}9=A9f9uHeb*yMk6dGE4C*j4 zSE>Eu4lCtckTfnyf8tjg;VffAf+_h6^JFkZ#*&&Q?-o2R}PrBj3iQdqNCLJrB zv$9Q|l4}6=?&y@qyhb;pQCh>FHdSbmDQ;$Ffq&r%kA&xwMW?7K>iH*4xBY^FYj#-~ zF#VgY`P(uoC)-RC7X=3W8sj&7cA1fsTk&gme|HvlqC-P)k0B2qMmF;7sG1v-&Ra$)=KxU>de2 zUQ#FehI-}-f;O=v=T)gszc@0UDDe)X6Z*vwHu8k!E)Tr@EVE8qXU#9xI~}Xt6|T5^ zr{mkK+eQkh(~IVZe6jvE0@!}9zwlTOekhZ&4@&*nMU&(AIHDK^K~XZDqzykCt4MqA z;gTy)SX{Ir2sf;TH(O^T8MT)D=V);?j<9XIG1ReMyqol1P=~37TA(xeek+gQ`^nc_ zZ_?ZuJr=_acaOXVZ$Li}VGzt9Dk-v|i|n@*z!1`20eI1-V_iN)+Zk=}jAw4eG-kj? zI{Uq?`wk7JP{SjvF%#kg4p>XVgK=Ozw^#2Kcg$SrOGlGJJAbeCPVBscy)Rt3e3de- z{bk5@i_uz{CSC;XE(T(2O`3B#wva$eMU`VUEOEx^01`I5c&DwQ`Ni;tCTj_IpHuAJ zk^AJWT)DE0HN#2-yJD_@b`H+Gro`+@wRk1bg6pc@X3C!bT|W*4-#RXuje3*;{+nkU z>Dr1~a1Qy8E1{1oT7KS8K}q|qsFa+PA^_ACCin|&#`u-?NJx^lILn)E$tUQQX3gb-bW6IJ9 ztPG*lXaYGl1M$|?oM%Ot(Wok{{wu6v!FA}m>tp<0kH*!AM(rT*UHwU#(Oi|U&YpZ? z{`DesIlbSU(o{np5O2&PIx`e8!7NZ;B|y|ZQ5w9za}wh-9X$+=8o0mS+j=L)|HIUDnA2d)hKJ52CsfZkm&9&v7wiIA_YK8p} ztM1#2HMB(f;)&0Tel${Y5;?H0YsflVOQwTE1V4yB&F8|dh61qMFt}C0)e}s5@_I1& z^Wz=4jn782p5GH_;52-8+>C^J%G>^Qn7r;);E7MEV2=`w2@=ODrd(_`et`lgY!^*G zg`@Xxr}Xl`jc~Iw^#l$G`)hhnP2P~l0cQYHilO*sRFSj=12e4cEGk7VyNrT)jxO?2 zlE>`-WWOzXLk72H;g_;ASU4S}`@@gU13@9ruakm=pa3qxys3FEAG^{~b{%Exr_Lhc)*b3T3>8}JWcZ3LyLg(2WRq^6-Pm6j z3e|=y{(5CjC|G;<)_2G6L#-ESYEa(2o@!`CUvT{v;@WHAP_k|2AktZQWbXcP>78Id zp@{r~I#f&K}crT_k|_y@-ak-<1|k+8P1#4Cn; zT-ce^e6w774#exx6ETL7WYT^7{IR>1jlXGM-Tky?+cIiv**l z8Vjz=8Kb0^X&v`1t?lDNS@-q~UWwuLXIn+AlI%&ku2L97BWFU!cJ&zl}P`<8=! z$Xjj6yi{u=k~xL?@o&?n#@o#mPQ2Wsl%MRRfeHQezD(d%#rTF=JNi3FUd9E0#gTkv z^%O_`)B*$e{hb=%c#;F(N5c=AHE|l4GUcD53W9}D8N?ZrNCAhIf0>!H?}VxO5Y1in zbh>!1`1t(tH_tyj{ApCAtJXa>ebOOg2H=Gf941LGnOl&|ab{oAop=(W?sFyd80yJ| z5lM|e9Z}7Qt~<_t?-;_bM2no>xfQhU`)2t>(0?;`(<>WI)bFN}4%jB)Cw-)Nv||~nCjaeG6wU*43Rm(+Nn<(_ zuA{&FaD-1O)$iX7dI*AthY81pm-fu-`IY##LQP&>Nn*|;8{~IIBQ7kX*GBaMxa%4_ z8z$KwcGuR!l~ECknYIbP{HQW%-F#*5BnFDdigX_Zhg*>}{Dl|3LKxjE?Uz(;q3PpS z?(*(qt&q6YZ<(WpIR)X;Jqh>Zpa_{C>`+~xQiK-fhuCyt`6y#ZJe7xxP=5|X=%v%}Xm3tGC`xMNV8Su6w?S|M1-qsIyoQsXqRKE8-5%KK1mD=w^tA{^w zsuONS)Y##9*oRyN-p&`7bL<}@qd8N9$~lQryhW}WDnCYm4uQej6O3*E$aN2vaO3@e zprAUr7*}US{re2r*kIa}0r9%dIy*Bwv$ytFjX1n~Z$I_JwsKeIHrgv zbg%L781X1VNK#_?$^I3)`v15W3Mk^Nepr1V(ENrHrZjuQjcXZ^%pqLTkz367FBaN; z;4x7AMU*S?OM9k~koc1!R*6fon^{G|>n|tEp6k8Hz_T=e)Sow6!&>_hpAO*TJkOSi z4aqkiS@-D4GP336D>$wJceDzoscbEeaelDesja`=%+mC`iE45aC0U7y$uqLbV)1VT z_nt^?b`dB!T16_=&t{f8=aG3g*WJuz$<|c!W*+cS~8~;L2~$N{0jR5@5DT! zRb+!fQ!Q{1tSCZ>L4h(DwQtrlnm_JeytBf_ez4bQHa|OwUes$$>Tyl}k{mVoPRho#FotW-Wz8~K_7T8PsM#&GxOjY4f+-ZJ>R^YZ+~nd8lvRf zq0`qXglP(02N4XT%s{Lv3Z2Xya#c8KpqhH$}eAC~Uo>eqDQ z6jZQ+Xd(3ai(mqn0j8rfx+;?^QwprO`2%^dav#h|B}rXG`oU}@nIt*+^Bc@6p_0Qm z9ged3H?Wo$pC9`B+L z`>$0{2NkHiyErX`KD51mMI?RCIm^_dB!XjAC&8|*rKK&|!aA01TX9`NA|yWx*Cra{ z_pW1Zpu-FOGPKGWJv9(?`y2R{R7O+!z@}Pl6AyERjX@RCb}J!N75m|t-m2)F5+k6* zxirOQga-*+3A9XR^yN}nJRjYYYRVF1QF%F|_fQfn)utt+r;bs_im97#x%Wd|Z$`WB zUn!SdskdX(t58Eyt1Qs6Uek-fSgqoQrtl|O6D7^uYa-9pARB%2iq5w_tF=UOy5hHX zZ|4f(MwJq7l&(~>dna`&p$@X%%c3LL7g2MXiSnefFQm^pbry!4mTQYDEcq=)88B<27ih0C-+e>{KqSyb|0SUl))H7mb?*&^l%-MNM738LG2p z{MMQx$(jg7?pmD$Evf#v;NF3b+^y$}T+u_ClAna|T1Ql@k8Nyx{ll&A%Kk`V#yaj* z0Ecf7PWOv)34k$rcaHcAkE92cpre6R6;(|5qS|!!d$LDnVIu{Qaoo1?y0w(p6SkGA zY?AYMYu_DkbiaoN8~=n;1%8Fb8DS#_L#yEm8MD|?`${uq$^M|Js4!!l^n}eQ11inU zVB)83Tl*^O780*!ydTS>n$LhQk(tzWmBFm+y|A^moa-0uA4roSq31rt{hbR$1~Klx z+neu|5SI?<$aEtc)>!{b0cXEuNGt^&HI2R4*7(W_BGB*v35DmhuctMJBc=21!

dJPlLq$2Y|Auky%F0(*w78YYp`aLAczW=Hdi;T+w|*Zz zkD>809fC6R<@0lm@)Z}QhNk*L=<~7Qd$7kdCtb`gmh2F+d7R4u;DkHa=a3=ypeX*` zbYv_9V#WJstC&Dx?k!tJr$Gm4C`AdE)5g4Y)q<+Or`WFBaxv`Wx*a|akD8&nlF z=Awz#VvVaOW*L7`eYfrVOl>54Oc`rc*VPA5H`lG^%B%>X%L>Z*I~N9>W$Q#d0eO^5 z$VEmGHz6ULC^P-DOiH9X6Gz==&#$+H!u6*_f?Xa5SYaKq0R~z`Fl9B|!m9$v%*K{9 zO#OCue#MjbRWe`bkjwM^hQ${;qo6ada|2S=?3dU1r!{m}vXj6KLV4RoZlK=(%Zf8o zRDzEmVQ!Yx!RJX0-{$j_yU!+NIgyp`_bxL?rztaGbZfzhs}!A*J3-7i=*okx83j>H zc&{9N6{KR=k0Qs1yJ61bKKP&@bc38Wnffax0oyt@(C>Y5xR;G3(IJMav92R>AI=C} zsntO9`mPw(y_Gv0{^(r_oG@$Kh zODpXvfSIx~&cI~t18FxmZ-m9MDa#@gMNzK)ux+bR_b)|48bhgzFf|+wa>E4E#gz50 z61cEFm{SnWSE*duK9gI$ijb_xyw90CuHTe!|Dn)}6nsVj_0>-_<{}A~+%Q|9-LGQ9 z0Ftn9Z?MZCx&RmMdMAQGZ2PAvIiIO;yzdT4Thb$cM}nYVnKJ%)?bX8rp!((krPwx^ zzSVosqjQ9>r3f}S@(m_2#=dmahbP0@mf+BP{P9TBu4Ia~WJJn0YlA0$+Qp_fVGy({ z3n$+}n9ciZb_n^$D&mO*A|ax1>)SDB}RhjK9{^6UWn`Cq56 z|0n9~jDA?MUso!KmhN`410t%mLk8UBVy_IfsVlN9x?#Io=&c*ut0|REv-hU{*58k* z={$>+o=$f5zP)IQ-Be&lk5fXA5loKpFn(xOR6?cMpr4~>$d`0}LSmV234N0ZFMDm!&0jba^c2embww{CA1>f`f`wFjElYTOXZ!&Zc+HGEuv( zJA2+8&(EGIp3t~07VjpcrM2bf`-en_W!aI}u8&M&cjCt7wpiU6?AWQM;}?f>;$CY z{rW&K?Y768valUp3LzvjY^A4c~WMnoh97O+zyuW7ajo?b9W!Krb7;` z6HPq)g0T1Vb3zKISNH(SfMtSJ*JNcsr}YmF#spXWT6nUe7qV*dJJx1qkudp70YHqP zcn4>V2HnN2n|_;6&_q#ELlfXHvf_7~rT?4~9~8muKb8YbP~b5`Rzz{@QB6z5sDeHw z040+s1@!?+KUCt$oR1)k=unD98u{CYv^PoIc;P)u=pz<2l4W%uvmu}>!iomS{)k4r ztEAfQBD_*Y?fV%`N@h|uXv^!(OhOet<`NvKuhtJs^*wt=Vcay83yYe2HVHS8i4I~m zaWQJkKvXCt%DhvI7O)ywaroHA(l;ml&_eJ}ib)AVo5-5eo|Na{(X}pCBMi>64rX&= zefYCs-|vN?k=f(tlY;F&b_9Y%8-}lb5aWe@prlRjB*IwaDHBBV1&j zJ|_S>gK2Z$yyeb(0y4S{ohH8ZyQEo$ow zQt*12p3kKH8>%3BitzU(HAflYb$Z z)aw&`X@>L3Q_ON@2Iwts<6&etEj<LOL16HCl&ePWM1#CMw9L7b$Vh@(<~zOcV6p`$ z0w%Lo!vHe@T>k!83gpVMDV7(ZHeE6;T5O+kZdw7=jbt3S^8jfq6l4v3ENMma_iun0`}DLB zL)eT4#fZDy8}~k&eV177TwxvFj zGda8-9CcDfZ|3^vvl{tq23J-|WFxZmgYtueZRw$pD?QIRc~3bmQC)}*Erj;ks7CLF z)L6)|raSU=TVVTqW~pDgrb1ZM<3rB&dhn2g&`V7zo2hQgJKrWxMo9({S=yc1g-ay| znT~Yv#1MNQR&=V_z!z$MqX6rlgv^PQJc;hL$Dr<2A}1@7E+?g!JhChDTT^hc3z=x2 zZSNkT6a+ZX_xz{10*AUynDuRm#K@2V!4Pa|D5e>$v40;+qkLT`x~?sO$fAhzK$*#3 z0~ypvLHYNk0hhSjL-(8~H=as%NvPAQtGg>6N2^YNPvi3LneCiS{BHix5B7q6C|nvP zxRb^A>m&I=a)xKDCW*;6LT#@b5gZsWobJ1<$YBN&(9*Rwvx5fT!cKZ$5+7at3T*8j zdzfX8T=G?tfrHVc*CgjgScabcU<2%fCae0>5hPDL%%oBNz5eSzZVT~ZKpL(6%*b=& zFK(Jcjy+X;P<%9HINSoY*hS>j_V_Sb%C*B~3b7(EEp@Hmm;P%04|ch+s{f;t+nY?f z_>#25vlqGaT{>vYR&>FPzIn7(owlY>R8~eDgt5hpZL$B`M-eQMNBi*D=+e5>IL-FP?)Laot z_2a#eq<3%HSmlxiOjWfjH2vHU&WzenwdvmrQitgWme2lJKl#3Vo*8qkFwseI#fdp6 zx~|QK0w))s)*~Y^Z4HxE)}Jf{+K9u8ts_G1l2yV#%adIVKE4eF^>{cLb}}R(E=-+f zB{aNT%Y;92j1d=Pj3+)rEo>AOufh!t?pSR;IMy67RFZ^Qt&fuf$u36w5(U36mK$@w zDUS{}08O#Fq%DA|>8QT&ueLKD-t znPVSVK4c9cY5Ew3KI1mAC6_d_z5VjV6Kuj}=k+Y0rQybkw0fW+RKQ0-R@eC9o0(f# z?ie;RNIV_d`1C9N*~0RRV0MD!=8c_x_b$ws62++~2--YwBRT0^L(3cEIO*6_JLCOb z#CFO`tARehcQQuyBc3M7rvX`7FSgpyOR=FZSIXBJ3c?U9*=VImZSnH_(&L*$>B|?+ zWzEh0G047gJ5C3;s&-kfUsnKIoCK%QyIL=bNM-_2LIVa?sY)iVyuO$&X}UO0Ry7J+ z$~(F78WJ-5rLjl;GJL_0)ERL-y&+<6ijsGQ&hiz$N*)LiDE!iGfFFXlc5AYA17j7Q zib#RVO0qokCWcM$d=x^_i*7x$Pxa{>=Q~W!TogQhDC93&G9nN97|d{TNRCs{!cAe; z*P8M%I3{xZUWR5d=kpp5*J9UmQ>5yU%f_!GOEc9(4YfD7@YbhJIZ=lQojX^8KbaAh zguqO$zLKjYp!M~z(2=$m$5;5ImIOSBGs0rTj4M|15Lg0929uAjb@29@vgC$(aEwZ4 z5avKw;_He8E8wJz37^FU2?d@BP_eg+kflwF;0JANU@;E9BMn5 zYH1Q!Xj}+CYLtHyqm=%8QoT}TpZ89h*N2BD_h6zxI!Y(8D~Q&6L5c>QckAjE6K`~* z>?w1m!?#JWf)-&8OMF1F;2EU8J?g1ge~j!J<*cwo_YKJe=w-GV<|gCKg{lnwMS$so z3UPhZeqZX~EmcCU%xTHkPZZts1hJs*8`4zG)}K~SCKq48;c}6q$#oHn+V310c+k(9 z-ufr>#=MB2KgNR{-2b}8!2c(lH}Zx6TGp4>;9G((LQFUGHf%$$_!gAoDR0ev@YSl@(VT=lUPR%$Rt*nUQ`-T&8=B^o)q zgdqLF^%nmv$bB&-=yj9w5qrlbt z^a9i?t=Ko%U8ugQBKLy?yPa8}qTI*7f2otPx%I%&*Q4KU2-QWYgC>F*NoUvrC82%+ zQ7#2{IFff}lp8^Ke7K>lPRJ4DeZBbgN(ARzjmugcc()pH@>s>H zo)3I#RwcLMIv)?6*Yk`2ULq#_VO8|)>lIEM1Ov#3tD;)b<77_A*`ks(SLTkVy`&X! zHdQVDde7sBqU56{#ge{NlWNohqBvQNL@Mn~VY<*= zA*X|_xL%(sQk}+3A6dI;kuo4;%QZp7%$Ad~t|Zx=^XTmTj1?{hvLHxF;nXG_(aD54 zO{h*S?I-QIQ}vPf4xHrA_e8$l!uS+-yiIsCiUH8QuA|gLQNvD>7Myxm-spyT?+LWw zjn0pPxmK2IH{f?zIuh525YXH+v&7d&OJuo9Q}J1@d*- zdG^?{&vu|U74D$MAKDQ0C%~r7Rhv?E>XiA~0in~_G%cl1+|?dMn;1~@C-m{J37c+D#G+**Md*cl8wHhNwAts|hFnf&cXm{J%o&Y}?KdERrO5q`ofd{=LL(YrlR94RkYd3v00+~*nG{c#Go;Td6?I8w~| z6Kq!xDC(U-&a|9#2U^?n&=g>ew#vvA?-ab4d_2?hahUz{lM1orX!B~ZXEk{+O^j9d zg-)*(62Fhh^Y^_~m@t-QPm$!Ki;Tt%6|M?gd3r~S&A#u+xEId>v3)o120;*fdHWqt zNpRWkwx~Q;pMYXbuC~CDpIoV?nv!7J1pIHpGzxFO_Y-kz>i2NeJ7A2$-70+&1h$l? zxa+WFHHtNF&)gg2;_EmD4!t9#$41`Anm+0K`bFWE)@NARM)1B=CDe8xtE*pF*E@h% zDj0veDMq9fElOv;H71A^-2(vu}=;VC2Oz_ z@;NR_xF@h%UcVZrG5u$wPsgw;yLNhP5(O$7twY+QiKU&#bBaJ-99Fs>^!`d?Z5iKS z#ySK!7#L7$W^P`2=efU)Ca1$fL)zl!H$ZCO_DKyX&QZB7{aj^I2vC>A1(?Y?G&IE$ zb2Zf(nmL&yD?6yRye%)ol4!c&Fg6Rchebh>*~<)+|p zb5rB2)Uw<&;i`4`2RZ*5maI=YxpWN+Z6^sf1 z(Yl@+%CXM~p_^R;`CRTHhq#)W(3-hO9_JLJrBd~I+Mp~K5LpnjOD98kH!?3$Qmcl- z^d9&mreW9bTSUVA!^KY{&(t@23<&HlrVbSWM(;FC5ELp3NL9?CZg>Q83PAI}gI(u( z+swZqLP{-GM34pB7J^+~vh7?9B%pNYw*5?-V!k*VvhuVgJ+J@S=$hcRs1aEhxiQr_ z=S4u)dtXbgX7rn8LoQxT^)4ymh8c4n(eOzUM6%;+DxLY3C~R1#IdOJ{ZIIVaSD^6M z=g$<4?XQ-Xe<=SKNVUcP=h(geGfYZR*W;$Mp%KMNGM8E5+RW|R6 z`~^HkSxY1hlMB0(ZkK($_eL6T4INQUK7Z|1*!dD$v#)YD6mC!hlb?Y<^x%!>XrC&; zl%|sZRKle8ls9KQI6L|j68XmGgGIFAJpuZq?%1)JE@#pAkaZ;xmxo5#B0fVDAVuTOvJMcrR`#q|$$nTp8Dxx4sX3G9ZBJ_ELz5;d4VvYb`)< zUV*`%HwgkW@L4Otgjx2EWR1Re7NI+AdLP-~ySsJ&jOtrF{^z+&AYW>r22~RWB)LPd zuBy`tqJXrE9ktayLBH?A7e6Y6Rj*5VoIHG%%=N6MNuq1RyvoWlN&`t;kcC#iF-rl87GER09ZhCWg!H!{DUd*166~Hci;X1*o>^%u$*4h*=g2SU6AT{Om~N38H9j=9b^e0nR{;2l}q){@La%9}gDoj`Z= zdnx3Wg11$ZVwE3iH((bOh5X#MF_=^x1QLn3h@e`kE`r#e0Zbh}>(|r{((*sP;`2E$ z>irE&PmldWYJOb|^RlhfTDxXI{rJ7Y`}3s2LZ|Ocum-uPTq?DloZr~on#Fwy9v-~! zUh%-`mU#;=o#ED5eUfD-COr+v2ChO^9Ma+JVMeqvZB?CdO+zJO{`WG|tr{$esb&ga z(fNki-3t9X=&yFW<|EwbQUeId?fTx%$CqG*==&eXD9PZx~2 z7JZR-&9CBgXX@{4S;ojmn?miKhJ5WG|2FJ30|_<3t~wx~SqNOyW_XQ*IMgp$Kr>Y9 z+w%647sWL^f+39I)M|Y8?Mv1Uj1LJ{#~vEMbT8F$UC*%uD`c2)1hxhm2RsKGb!d>m zZe}LRr9-fI?84%>WbjV&9b1Q6dXj<->3Z{bfmjJsT`RWVphj?0^~#-koIa`sr+G@r zvh9hB8e`GW4_Ap1LP6J|5%pY!W<8wyN1XcSTJ%IRMl$H}_%0@^b&Z~D!6%rAGbW>$ zlPZTT-AO4Hb!M&TT!NnqD9Lq z8gw=||L`U6JIGgzD@a*iss;CMs2#%_P39fh0^eWNgf|>xREVZR3BR% zmXRQDJYM!Yoyz%mVMQFsYS!d5k}ouQ`k}+qcf$o#FWRpYOLJue$MuwN)2G1HFlR|6 z3(AFog};Rb0y+G*B9xFear;y;WS$bRl7$>!fk@uNtiQcwYgS}8KiWF0SR0FRi#>p4 z0|v7Gg7eb-IXV~CQ0K#cAjPQNzU+T&w#e)>asPd!Lhp$Cc!QUxQg~OxTnyxf!5Dh3 zkMZ2@B9~euSJ#wW5Y=9(Zt|U66gsHu<_t5?RGPW{V{gwd-+=tw=Wm)EdX-L*Wj9C` z&=LmPYUa)|!a(Tcs#Re`8$2C7aIpB6oeH7ZiF(OcxKD5}b_)ZF1J#Q(R>6$t04tLj zP&_HGY+(A&Y-QWyXtZ!_ z&{z;3;O+zS_T5lpN;?%qeNYwOPXk5PUtn@hh~+F>!nDNnen6{PR`@bw((Xr_r^a2% zT|L6q^jQF@SJ6Bru7Qxd0~WReka8`8*@rG|uq;<&|Fe5($?&ok+g~yFgS}gY+ruyH zCB???$9kJkwN-@t@EBL=*ESfTpT^mu2ls}nT&?J(R%2P|FYKKDdTiB3qQaglZUPvVw$62%#HwiI#*z#VV_~o)5IlR z!pXJFrF!qkVyDg+;g0FvXbpvx-BBUdv`uRLQUdTldvb-YKi}|K;h1|Z38t$Q=&*8A zYM7IE_I)>E48B>Bou!$CXR{Yb=FF?Q$XA1(e*MAsFHVgyI@82T*Oujxz?V~w`*Up6J@j|8?FGe0-?Y? z-<+H>Z=7zZvU(Y)0*fqK&W7&nk<< zUl-QsS)s!iWJCegt66>Wq^z-H(kG7C+tn4UZn!j;WtZ-5-Uzp=CyX>;W>j=QJ52`R zT^VB%qI+Dg8O$fIRI0CJq7A;yFq>p;^0`$u7BGG=`%yd2@2ZwSO(_Q3F7hYrocjmf zixilFIf}*rIM145+`!FvkKBt3otT1|@dQa-AA7X?vIsG3{F^zlSP&vO%y>_WtC^Zz z=aah5u+=+VHQ>AsY~`O>|3f}N``={*|8@V~{ihhf@6i3{Sv(zmE?scq1B0)y_t}g_gUPlqMhOb?7#T#~{l+^k(JApHy@%zjOx<*HU|%EsZ{1)FaT zs)_u?j?V0H%pBkmGM8d%*%}ED+11^A-1u4T+({rSsfC8tMD+Xtr)Vc=Uz8%SaM#W3 z#`H)3;u1DiQ*d4+C~@0p?p<|E*>Ary8fQNv-*4tRw(j4jOos&sp>|Hg?9ll%o8ofL zFtxXH>luBcS~pZ?l=w+RyK;#+w(Fqin+I{|_MHhp#8wYeP#gqPRJ23ImK8j;-5Q4%&YB6PJYg0@uev&^l2NumYdA&RwTA?yiVME3CmmSQgI*q)XeXa}3y3((~r3 zH6W}%?SuNuRrsGfUZ-cVR~6Xvs75OW4WOSl#U@svbYiliQZWa!U>(G}r1v7;kOl^u z!9FJYVfExpx7%RxQKmaclDfH7rQ2}LB3#$nRya%(Fc|Jrm99FSrI;pI>PTOy-V=xc zM1JYj55sxoZ_ZwN>L)~H?t1I0J?o9-`*$*-f8E!V{~S;F-)JL$fvdZ?2U+dV&>&Xm zE0-jB^G3{sP~`B-J(FVbKk~!%)LM>Q$62Re`S7E$RtQLRu3Sqk9NQIn0=cJC`Y?ds zM~g_5bs>h}QhX)E!b`YAr_Y@5$}AHrAF$UOrxW#e87Y_ z^OV8SdLF_=)ej9ZTzdRVhj8fw#i+t8U%DhJ947{L#XceRUbHcIf7!9mv@)x+43-{K zwwP(kSA~v3&Pw})tuV5yCdjlh@+yQpehBABIfIPTwOM=e`uJ*h$-p+ex~g&C4cg>` zg9<^*p*(9ez>?GZwXVl!pRy1bsWn9j#1=KmgA{g{WoCK)=hKbJxtG|*SC#} zBK|x}N;AHBbsKAp9PBxa=wy$6-aH4RL+z^zQ#0r1!uTG#!NDE*Zf4!l0)_!l1WV5FqZJ>Vg?wU>v?3hdZg=owHA@`ikSKo%O}VNucn zr~jbg?8>A<#`ibHhmMNY+TisYJiKoF5P{KueX7B~_jdggESxoTSf#<>TR5HdyOEtl zE{C29YUo{)gUU=Q@=7g|@89dc+Zk%)4Sjq{$Lz&UkSHDk(7OLltg6X`TLBAeATa!_ z9doRW;Z1-W1fp7m+@$1_D0XJ&nlL;?%$j!z4`k=l)KNCP0v@^hf}tm)z`&ENlNYCi z-ioxrMu)i}H-|RUXPq_^@>?6*n!$C8OHbDn^wooo#O@MMrLpCy7XM#b$N#!b%Kz^B zzxy9|yj^)=D_7}*xcjjZ>vN$nGM@@3xQ1;xPQOnH*@TI61>G9upyV0t$$H)90~ex; z`U_7U@4=g!zPid--EIK{0jn}$?Fod^35XWT#~emCEIt<1Y*eA8r#HkdBKw)CpBF#; zT3F7Nf`^~_Ql!^qYeOT+#~Zhgjqa0+ssN)p%n;5fN=ks}5ZBMj2gm$2nRhXq)bR** zXlkkl@^SuXI@mDLFo~*!&OkL#%QgLn?^lUoqS$P`=z$Mvm?B+xdv5R9ubm5oO1TMw zpsrK+S8GC1vYnz0s`yso-tC}^=^L^uw%LYJ3DsEza#Z`iyqaDXxMU#JS-2x5HKhsL zpk|}z&yGhhXA6pkDN&R|s#QuBcuJfdklp~Vnz1EzXo00_@>TmR^+XY456ScLfhS+R z_C)lL^7_+36jG4eSMInREIv?m(an*-FM~AjwpY0pB)B-6a3B(FefxX(P>vzB^nmK+ ze2Na|c5wKL)RZ?UNr}D@5+hfdm%qA%3+R?uA-()mMdip8xM+@NZ^x+d7W7gg_G0`s z&K9$3h81p3kjf)*%2;9h$96ae*bZ<1-?qap<5eLX;Hk_6mO)w++zJ3tvg&OZmN(9IQ4|j5fu^ADthp38ne=(!E#Xfx^RKN-brLL5a}gUZ%6wHM1@vD86wMCgS{Fobe&y=ZxA#GqFXEe#qw2 z&{*nwDF&4CW+f^p(TJP7fS5DkE(+Y43Hjor2x@MKS|P>RwonRZ3neefwSAQE|G~3@ z$Dxzy?xFR`P|*YDwFUrwS*|M%6=*QOXHF9E`xNoO4u9e4(2OeRxfsfQ_TBNi+~MNT zi1IaJyP7AsTHxLPIw;2z>(hwkpW1&}nO2iK zr26syeGIz&e@NH!Z=aL$pQyY4*MvC!56Sxf1YY@1;M@LJ2U9O_hRhadG;CqJ+ zNmR}?m>c7Qxf9Y$+NRkm%XP;Tg^W+Cy#^n|#j;)bxL7lB!M#Bbu<7AtH^Ziqom@&3 zKDvd_Gqn8hr7>@SpjJ7Ux48)lAsK8j8+s5d&1hTdia)?GC!I$Y>>^5Pg#$`CMR8Lu zX!;Niv5BDqbWqQ1YFhwqLu10;NHRROlH`~5JRMtjxTQ8~UcnYZ(FRk&X6s=0>$fw0XBjkQmYIC#Iy&Mx z7Pj{%dO{=^&$96N4vZNy)fdE$W5Hy+0IK3?vPh6DP6ja-M8Q|d*^HI?W!Pr;RT<=6 zEUp}6ymq@rEA4S~04UH2)Ch@$yP^VhfL$sDj1#@exZrHb-GS*FE?hur3u@cbdNxiH zi*gW7s-?l2g&w4ixXv~Pk>5;8gP83b@(?!!*xa;Y%Rx`fu4zZwXE`sa$^@FSO!B?M zt`YTD3UGTJjuz4RuAVj}#3%zgI8>5gq09+%&+X*WU7fL{Gqr@xVbBofX1g3CHF*Q< zosZt$(ENp0lK=t4C+7`WPpSir)M#JF|NDOSU;XtzM>Ft`)2Bsq4`tYy=@c#n2%2LE zH%f7A3BaAWO13!{gGbpvscbSh$O?Z>9jbX<81g8X5eRYh!BXz!VZQwhImy0M8oA^> z8_0nKp9RZ9GB*MXWfr<@4i*y@)!&iWHzSmy&MX;QF^>V&$Rh<=e<1gqNx{^o&iOcS z^)$WrA`e_gMvrUC~}AMaO$ zikSu5NWqoiV&}6a%JOBY(_OQtAF{K{4AgUNLi|(eIQV^s@8vt%_iR)O%{3dIo`73MT|2b&)zZ&@RfA#$;{WX1k_5T9L z{9hyK{#S-({O3aC@1OEUD)O4|f~ZbGkrxSJ+&2lR4v=|kSCl(Oo2T@gO46gWCsMtc zOYyixY|S>0`P+4cloG8ID=Dxy#P6PRT@l27-DP;?RHm0WxiW@OYY)&osD{`@L>hiz zQ=_6DxeTzI&Q-Vf*{^3598t@l0aJsr_b1HR%PyqjICUR+VfB;WJp45_38rH{ z5Rqr$AuQov4@gtEA{G^Y;@Gjd$Ln}l`_3{{Tn&i}>%G~oZ-+wF2b`^``}`2HNinAo z?a&f|_{v_@TRqH8Nhu8G*u-XR_Bvp4RbE=ZBeEX}cwF_OEok`6#tS#y-6 zj=ZkQW&>{ZZQrewR>h)AI_>J+CJ+tGuVS^o0)Y-@0ti1}k&Bwn_Q4MfeZRreHTfM~ zRnwRl?YJ_Gk6!Mr{}c@(#g%To!eRYbWFHPPo z%MJvYN@^#0yFa{{2EvT&QOlw#b8y*Ur)EWpiAJkCPa$TnTCmJZY6PH#i67W#nF$>s zzRURd?Hm8@CBj1>(#N@m)+uYO3K*zTUMa~P6rjkZf1LM!Y1?QlbUtTDUv;@;$<}6+ zIW9J~ZM1nxlF;+s6b&dO9>VmnIT_JG%V>FWj$>3_)X66WqPIL*&ocVblY8ADHHaS8 z?FZdWLyXi(?7ut<=J`gkWqV!gV57ft(9Cp*t{!3)i`KP-<+NXd=*_f!vqY+#U799` ztYzkZ1!Qa97G(T&@1e)%>X$5q!a6#0N-jE0yFmAK-Wv?uQN0!c=o(T4`qCRd!#1Hj z%1+W!Nu;D5rvzXq}Fi0+Ij#ZmTKvIoa2DozFQFXAf98YjFD_g&8? zUevmHY1k9&_$HKUytN?#jied84gd?QqumA%=;+pSX>mDTl`xHIAZksTDC0sV>Lk!} z^X5LHM=~pWNp)f%n~;ua>BHsN8X`0?2wN*blI5S)tA2~u*@4Z=;(RX<9jG&4NsP^SFJ*jKRnmqF zNBf#RRz6=^PC#D1ke(o7guriZpP94Pob%?)n&*F>IrGdb z@*-;`tlar#-+O=db6|54=0I^zn#>B#);Q&h;^`K@`g zaKrdS3Ar5F((F>Y>7X3>EqTe!)9m<5)44_-G#y-KoTqfv_3A>_ z?|tST(t=G>8?n!$$ILP|Seu=$`n?yp@;8NdaiyT+-b|KMy8o?8%g+GjN+OXRxuPV%sP zIby(%#nNiY@}$tMLoxQ!(SJzpJVm9An}HzmJ^OS9<$ptJ@63~6EQAX2{u-KHu9Ct6 zBTT#fy?IY0t-V3EU+cNd#oH@F#eFZ#Tt@2an@z9rk=@o{JvtC|cgEf82XoQAIpUA< z57E_kS3h{Jv~4__^udAYkA=~7W)Ij7e!;Ut;2a2hIw9GQ6$}M1aSYSxoXEy#mSA%h(itUO2Xt_ zPiAdrnSHAVDryFbI*zT)>7vwvS;XQ*)B3-uPB|b?SSe96c@);k4uh>R1IBS9_3rF} zwyIU4$(-NGm&2MDC@wui^_w?VR);28RKBP+uX1?x1B}8X3E0z%QjqX&C@ImjnsBo> zx_3<$R~mcLPHi3Gmhqd?etTt6&CuPe79D6}GpN@4F{Pf8Gv*K3W_q+D_`XEVJDAb= zUBaZ^LKT`apKwJP!M+UeC9O_#{r4d1nu=1fe76J*7Yj(Yuy&FoLIZE9GaSj4W7Zqd zAYnw;X(u)8#+tw!+Ox=JPkwPX_yd=a7Hh;F#M?tGOO)AGwA+DUpj6N>pHx42xUJ>PK}c<>zZ zhH3$^KgxODp-#q+-eY)8Ht?ayvz1pK7Yd%Rg_~JYZEdJl5xa*&GfFL&)(SvXV?*5~pBID2N z`JgfFl1Z#BvhvVe2e};N;f{UxP@VwIdp;t|pTYXo)vh74PwwqcD6=g=7>H&D=S9Ip zVEh$U(AZLB)2vJa7Wb@QrqUO!SUjB4^v+-6yAQ?id3fCI@WHL|$^CrbHm&z2@RO<^ zim_waWw&EgmgCyBqWzYcu|!toS!U5o+70^ZkZv{a;1p>on((H0Sfp$T*p7CXY+)cu)np&!=1k$P+JN>!}G<`h&O@7sN!D+%W?p<t?2AXMnjoSeU}IdRv02qe#uv(+W8*?Wem)6|(^paAnb zF-M8#y$V+k)g-p;>op2DGQ<4WqwJ`NsvE}45ZW5IV9op}?4S5rpNR=Zn#dxBo=TyF zmKBpL8e8qQ|1a9V|K022(0~7+`0p^{|GJ6zKlm^Izhpr6zjMFLw-tYljh|ctf_K~A z42(s3^8Z*9z{{QLq=?6^Vdu9XymztcQvCbz(J2l|j`#1xeWW{Tr2yBZAOAzrO}{wW z3#L~ZtvF(bzU~cUtLMc1T(0Bz<+%^IwWq7Io(l(_ed=P!^JDyA22VWagqbwV z!4xj?AsdD{d34ZaW4!WFLNU89wD4JDfCRLbmX7lq42+kJ}djlAAKmYOrASo7+HxP`9sRE50 zp3BJf2`Oa;i;41C0-l>B`GK@X9X;g(TcAQugzwWBu)dR&_5z`B<^%4+gSj9yE+G2Vq&<6-k{yfHF5G$4 z*S)H-EB3zV6{8A@R~ffg6KH&Ye#pB9bO=Mpz;S$BIFAa<)qL0kJXu{ib^P!4a}NaB z=Xh$gD-Xz~FG}>9&R9IpTlH0ouxZt9`uI>97^DdLcEe~g+T-L0k+q1Rc)HM6Z*ymg zma*tu=9|vEq{dABV?N>U;kxuc9d(_kwp9V`W9EHAPT)o-n{0fUYj$-zMvl+WVajd# zB6nOVwy-hT&?6>gMWaY+V4tNwfp+j3umr3|=rjTV138%OFqo+C<`MfEQFDr@UH<3n zL+~q=COH-_=^2}e)IVv)ip_dmA_vlabgt|4p^iWY*Oq1KlHbDZtRyAS8v~|=F6(q= zONx`e&SSC>Ii0>=a^?6&`A?MljX???Uo)aIj(^jxr(pxZ3{!5!4dhq5=8{gMnXxip zi|j*g%4I`!Oj~1fIQhGJjZ{fXA)BeqLzM0(w*YY6@7P~pPN?{Rt-zdpM^nZgmOggz z)i3gOUq{Zik)_VDkrJBy8%1RTVf`<50j25L4oWRA28;7s;HN{{xFe;Gm_yyHMSDhB zM;6C@+1{H^WK2tin-tM;L`s+4xpndn$>Jy`IuXQ506&{Xhm>2mElo6HL+tIcj~-ew zae|RsKO5?`$y8SKC8#5R@U||DO~D7Pw&JVYviZ^gOZZtwSoz)pSCOp{o-El@`CMIU z8G$r%b6;A`Z-I`Yz4U%lklIUiu^`);A@)-+({pp^pmxsS?{O_1n1Ajjy1cn z70b&nm)0n%MY5MDh2)e{1_gtJMj{^->Gj9h{=|9?A~>Kroc@UGL~vd|h`(X_<-CV~ zY@>CE*qVi?PUdL6Wrl9+$CozW<>QBJmXmJ8!RYZ;(5suMNcdc7NCg&NSYz|!P$Y9C zT=R)Osy4!gU&=>ul$o8e@{Qm%CZED?nCrPPQGfo|=w4I<4jlIhK$#Y~m}T1Du&yZA zP|%FbT=d{KYC0B)GR@Z7u26_1_WpFBVgIC_bA}r5WZC6M>P9vmMZ$SI@DaAMgeRUA zJ7*6v@jDrH+P?6H_=<9opTaRQi}oW$Nj7u3oWjO^p&Z+U3^=1(MnL8o=j^LXY1L@h zy~1&MMQhtd*QMC(C4C{#Gd%z5P^DsJu{8;fS%*N2-@{zC;m-RzNIP(itJ@JBoUUu+ zv&f5wulrCP%}stmwvq)X=Oks9xx$p>2A?Xfs1;Qu`o+${fJabs^Z8#kH}?9Z@G6@C zDQk^hP3pnQ*A>f)>@KBOheA4G=HrXaQVIeaj9*y?2hX32WXcorE*btr_s0I}{!|(V zZj|Zx;t1)it(uxq*p63e{c|ny_klVZZ7z-*0^ct?(oz|n$5SFX{=uIQRPq-a-Kf&9}@eIkRGnY&d7bVB(Ci-?x3kr zbRRA@=l9khYf>`ov%v4{i<2uL|^L7SWvB7_E)fIz?4W$C{xaG3i zk;Cq^&DUVs=dAF`nyTmimWTU&@;$g==8?m?QM8iF_qf}pk6)u`jlJezy4Z2@)91!4 zP^b&AKD^CH9W?eyt8R-!Tz*B_qRv~bsh%yO`u{iAu*@NtmBydQVP zL8w{VbER{cheG~yEx3~?sfy@D8hPo|;cbJ2YC$Rs4*{z4lF{xbojozY8}luAu*Pe| zgoP>&@hnjX`mL}e(;0jt)qNzj-FXcd4mUtbiOfj+hc!NZIP>a?^~9O`_-y>^l9EKR z9Egx~({K~!W3M5nAgk7mZy)o;qGoQaU(TO(yv2NU^JIo;wl(6TqhY3ngqP>NDy<(> zebgc0stwIet&BxJmBZpgm373f3dLX5g^vh-@QUkZ)99-uLr zMz+h_Xf~o#cV)+#p(|VI|WY{}HF|f~7R?kg`>X|_xP63w$?(W#qHpRP#k=*fn7o=di-81tThnA+M z3@J!-b5l#yYl{+ZX?LZ#-67ND1O^?KF946q{6MZ4y8H|$_SQMyX3>VwNYr-?y}t4} z?Z*-#3Rc|On9geHD5g&pWp46@n`h%5mVU{j_f9STT^=rJ)y@sXgAd6IM^>rL``v`7 zeI&BY+$ozVOTKy<&QbTgg7ejf$Qp&Fi<}M_s3LH~zuleP^tOWV`~CvVuzIh~E!3r9 z+Mg3<`8GHiEvYm`!70p;aj#j{n%@uKp-3>?lp}>H;PVidQiL>v>0iGI(Io)y&uC65 zM{4|@(M+{Frm-nWy;-9%Z@;`ruPDVgCMG>bJ(=xpn`(zR{7dfbIhZ)!5Ce`U()(|O zGJS=~FAz<5SGbUYIF3TQhCcVw@LTVj{%~Xna;YG=^#m)XK&-IW_*Z8OZ!{=3CrMWc z0fPfpH^I^VS-)<{e(%WcneyOMuW(uLuS~Umdm}1kxcf;I4f$y6HMsgkafbv<4+0>% zAbqrenfeLtU2t@?+1@4NIOrder!8hE6lB;;Uo0yeJ;Q38qEhx)YjXJv0GTnmfrJUl z72UoLwM6yoT_Y2lZ}jqcdO5~+4Ocj6?$?v4kA;dEi+>lc|H3-)1R&&~ZK?^&n3`^S zioM?*Y<4`hyMe(S6(#cVj}Qi54yIjSG`)NKZCE39Aon@?UgxQRn!6^*#Pw4O7>z%B+y#xCLa9EF7b6Awu9cx)M?~34zrUNnd>lh`JeMclorm#O zxSX1+u@x-XG5-Q{gW}63{rS=>b^1Z`@489d zF4u46)be5@QPl`<9!C_cGR$}Jp7bo%D*537T6PgWS3C-`pWyf$`!OqTg#2m+o_s%Z zlN$hXgDEQ;dD%^H0g*Kp(44M}rQOlsS4F4*S7gXtwwTH@S4)v3aVAa^epfRp_<;v?wkO-r6Gm=$TqR?L?wAwes>;a6|$+%Wqf^BibLHoG4;N~85R6+`}?iP8P9{SWh8ASsoYPkfBK7>q@OudlXOb(EIvJjjfR70i3k zk~(ijs+#=DIpN*y;b%-&Hb{bb|8MOQ^BkBgA@K!Xw>J|cGE*g1AGdBcrlbyDfdj*@vc(VBp;$HikNTJZc&klB|D_rk<8mR3HG3Is7}NP52G z=?JPZ05-FJLOf%ZLKgZHbul-V9-y)V!kn?>ZKAM@xYI4{qW#q)PcxLX@dHNNwEs$8 z2Bwa;3H2JHo1Ij!Tho5rM+}f$pu|fzv=j)ZmZD~l^ziTy$-R%!__Y+n`QaN0-OWZ^ z1y(t_-rG$u0?uF@fH*`?+o~dno}ku>LBL zYZ!{uW|$LIP`^JiaGT0K#W(8iQ=AdJ)m+qd!}Gf9@uJZS%)yN%BbD9VvtdkqluA=u z2c4{Q#OJF#4Y521dr`?ZJ;cRjWxM7khijN%>^M*wF7xyap6o+wgz7pqO!qZ?crjNZ z&{2+nOIbrSwH^;~dNbTy8Ey-=^rHNu#aApI1*e4FyC}X?T!i_~2~xf&fxf)#8TtJr z&A2H-zqn?}^QCEq^3D7ApX(3D@F}1depIee;oRqv>WZKJP;+Rq6-?irJII}2i#Ex) zZ?SrqT(Y>B!f2?+k#0)1{H8mjppxj?2e=qI;PQ@^}9IH>GV%~1ykj$>d4 z_U92Fl=lcIqO@>iHJ+GqrA`tTE4GiASeOa6VwKE@+t5e>jD7JuSgWI zN-;UQ@T>GOfT;CP)HRxG43QlFrvHIsCE6zm`PL8iwtR z0@D)x|0>=>sa$deT5JCyL0C2#f!2=o$n^W%6%|aPTouEo1Ip9O6`p4&*y(Fyv=BR(d;Vzxqx)9twIo^+Jk z{{@lFd970Haw&-Cwq9FN2&#UmRy?c^2xB$kqX3iR!gPn!U&P{|t22KhOrekvrnI&0 z)LIcgVX^-LPbOpn zkVa$9HdH)-Xxwubkza0eQ}b`1QBoN@pm7-GW=c`2HVKvt5av$u0D3(1=<8T|n*NP; zpqKox5JR{RVN3V72M8N6QNoK?1rr14+akGNzs!`kAoddyH#OC5@ZoRD%(V zzJVn_PJOxskW?vyzAi&`E8X8dMHI3MfzvI$q#_Bo&p~!D4SexYAD9`!Wpi0BmaHVj z%}@WM?uVLDWNh>KgEpB|*U@pMk;>znNi4GRWc-S?)=wrc1&Q)Fw$5`GD7pFEiS_G> zVYEW!?qh@V-^y#5zNIonr8Hze?lH8teB=5v`fv`W9*7GCz`G&N_xS`{@w$nyK+)X1 zGKlA=ACG~q?{4O#;B0B4NRX-7qnB@lgAi$mj84U*Pcq#cd&>J<&~D(Jnt9aF+BslSx=5>=M0@3&^H z>5ExdDTbQ|@n&_cjE(67?FGTF#4MasjbrFWJGcw3Iw!LaXVu0RKK=5`yTt9cs+DGY zoU6&I<<4H2o?!CMWLeAgoR`P92Wb7lUpr}q@u~+`fW*m~S|e^Uin$lgQr|S2XOitM z{Gd7e*jMI5pro*p8H#T0X@@mdC0F|yBN847J=z$ruG(nPki?DHNOhB06XXts5%(I} zXO!v1lp{ZN)V<&u=k80%cl1lS?|lH1of#vFTzsrTGkRka%?H_o?PBFL%puMtD;A4C zzU*Z4R%g8wJ>EaqSDomv);QLPTt%hc;@N8H9|=P2SING`)bIf;-m1%t(<+sS3k7}zNMV`{IS+CC(MkZ2 zaRr>Cq-OL^#bjvn%|vYh+4Ec1zJ>J%m@)+ha{cdGkpK79;s5jTm48Vj{rZ0hH&I5V zHFHe@{}2H%98mF>>_qEOhIL@Tt}1%5I+qujF`^!>^a~jgG2>As68XqL6y%Wb&?hKg z>TLkn%B4mG7u}Zy)55b4@YBlfo2hq_eRVNcWuF>;U%hS-hZ)j~+fv{}Y1*L3coilm zgLMxAvGi=Z8&cq_u-nb^jd}b8r_H{AjL@YiYb~cH6g746cwh1h`z6Dmd`h{-YYt5t z7P29o+Aznm%LVY_+BGDerh{TOukY=^6oLFPuE*xCN0on&y{j;z5kd@moBW+UtUz%% zwb!-k{zW+=vJfAcH;_lM3YD|O$twR8krCfqy9{2Xw$h`4##{EFZ zCWp~lK$a!d#Q@`bau!EeH@~PX#Q{6g)>VX@uHW;vQaGKOLRTwP)Jt?6R)_1`mqCbT z@w9lRnn7yD9aBmNiDk8gFKbMA-MAVUzg*0v5WyQJ{+cA$75S|b@kC*{k6H>jB_tSN zk{U=m>dKS3sNHr{4 zhlE{;f~rvTUAi^sDXJa&5N&`uqq7&Ww2nEkRhWB_eeII!3$l~la`D-iUreKo+u7y3 zrjCRIMI30EMuF3kbzYnbI>9gT>_VcTQ?o-Fs7*==&tDQ%fVhRSdK;LE5NMLr+vmOf zOrOSlDYv0?%~s1@O_Ex1dD%+3`BkKA*nk&gu2F93Uf(4jJ~zGu+J>3iip3xppiy$P zU)_Fl71wpDnmy+hjauGZ{&vID74Z7ZmupcC8yATnEUM=`{}4PLJ4 z%>j_o+@&}nTobIruA^K({Yj%o>RsVP&e%bFY|YXE8XSVPaq8_( z+l7;`=%?3Y&Vv#lIY#Gu;F(xc~$}N$;#o` zPxe}0t{Y4hSSx=M3UKwZH{lHFYkq;W7Z>J*d`ED==hj50WYFH&8Y-A_2VOiJebpDB z7H4DKysQj--(|NRqbQPKtH1wyXy6@}g1@4fsSF zc~yJNnFz~$R%@l0SzP4;PV3ajP}^0T(9-FD{FsAHbM3jAG%snsNLXeWd|`nrG+K3d z!+Mzb!hMsPpUe*Gv221$PyP9%30N5Tgr@#Ber<>yB99=cb8id!3!Suz`%~B#$_`if z5$yC%rh`R!t+JMp|WTYS1G)BIPA^>%I+!P1KY;b5I#ue>v63Nc6^w zZ{$`0{Ko^i2%>l4o_WLK>h7bZVQ;37kiz^j+`s&QMPtG~LAV!xtk!sfoVeVmoR#^?t>mSklR#h2wW}#sTidc5E7-GpJ zd2>a)3vCF5V;jt-h_1NpK|b2dZm!k!Fy#wh-E7*Iv=3S>tq(G8C$ z2xutS3tkUDn89wxpYSKJEtu64P`x0PRmjv7#SHMB`fb+Eq09C*N@0IeX2KTQ0{)e4N*Y2 z?%6#Bh;n3^03B%%&W%f|bAb<6@9+uCi_fB0WZv=dCoNg}GUzCJT8H~^2JHV>#Q4-b zJ2jB{X$MSi_%4N^hwB)zD)5^|V+w+OKOp^-QbAOPy4_RC4DeZrwm5QsL3P@*MQZaD z`MJyeCEb;iRrXDI^oBdQ4+qulRjY2m%0RGD4VZDTPKaqW_oF#s(+sSC?zdNU4SFd> z3U7ufI35K8RO7J_lr}W52NAy%jqtBwB*^t&a_95_Agug`kb4haHy>@hw$b7}sCKU| zd}>)3Dyt0^s#i?z;xVVk{#(Q)uq`tf;Y)^J z;WMmNtq+qHRCQ>p?YUV4ugf%t*(y|AezAHL%6QnJ3iUk*u8G1D#8u;DP6ppEQ)X)# z2P{0(OBo|kXmEe^JW1Dlq`Ton7PvIniO&iucT3xtVp=tG6Vhv|ioTy ze>I-Ax~e&*@ZMf8E4-g;NXy5N=ZcL}15V0jA=Cllxp<7doL;w%?mi2M@D!FkeR~F6`5q+eGKifqqP7dKFw4S@7RMq5PBJw`}f0Q$T-E5 zB&pK71(O-{dBW0;>E52-B0j)*_S!{+;u74{xS_u>cFR+b4-UC?XJs0-Q>Dtd9Acj7 zzLOXhh&k~4PH~&xcS>KKZm{PpZ~r?U+}|pf0BG69b?+K;K^OXLnP)u&>R*QyTkPbr zw?(;BVY4tdN2PQc6ao@ii@fA3#zXo=Tosibm-%^_rblU!hf|y=E3>GGAfh!?aj4Tm zf+>cxgB~U~2ZWt4E?n64I}5*pWEae*_QeAnlMF3BxyWvz=PCv~gtUcS9#Njt#lgm; zVcHvrMbzMuY##3XDPE_hWEUBZd^NHpzpW2EH3 z7$^K#ugmP`)->r*YOafKolt-;??%OE&>Wj8fyK3Z86;&q< z#ZZY^bw2u0_%S}6|Jw59NXJcFXS{|MVCgeIdzgo(+ZEYi{Y&S-E|^0tU?aOQqA)>@7k`rgHsm0(xp+99#v;omqHb$Z?cSC7J3o z*h9BkY1vQR@UPSYqqfy_!(dWDrNlcx8#1sIYBs)KSvcc2%-u`>{=`$3EXg$hz`MfEDyFiWdSPN9q?DzqQPS5*JtC9A{*&xy@mPtse4MQ zv_iMc^)*oHER>{qne5%64TyfvXgCi+#7}CSejO4@6NR!b@AZ`#V>1s>+k7j$Jj~ms zHqKPQs+0KWL$!A}9RF|s;;n*DUm;hYEL1D&p|!EJ0&9@d0CN<- zOZMz?W7|C+d?s`w<&fdpfcYD#S^xD2Ft3I()-#3yCNv9E%;hGed-+pmDW~~mF3IL= zRt5y#v>v?X$vQohB3v+pcTanpJ^>&5w+)QKjp(pno>6(^L|&kHv&mQs(d}JQ&i&{w zQ>ea-Zo)^{bF1lmr{rPNzO^qkpyavOYcUh*x_1Sk88F=hj?f+s{02^z*_OUqwv zR_osrJ7o@@i}1^%vZP?2eBd1g>4Wy)j663`eU4~CdAW;tPirb+yN~N(F zNaUY!k+=Ze~}$x4{;Md78y zd(I@4`p(GD`Za_Dp>^j;ikr zqy`m3^#WLwaC@u zt)G$(^MA(=wK13_hGec1tEH z=VF91EFCifgE$60%jfGz4Trjb7tgWA{q3(!4SA)y7BWy?T71!1b$p;b)|ghWB32~a zTJOWEdzxZTi3^Lu5++mRVo;lB0%O0K(-{HWkPxqL(z5_L;I%5uxB)-6)y|+vD6{e` z^P*c58^pmgpRLXyEp{`J7aNj?=24l3q%~e79VuN18IxH;RQ@6Pioj*;0oU6yuib(3 zx0;9z_1x6iK2o$7KaBf(q+x7)H{=EljkpIpsWhl7piV%> z?C$I@>%~Uedk6O{re%Je%9Jg4d$KsKZDxrca~2~!j&g3X?tw^wu@XTTfCe$u$dn>4 zhw)~4`L1V5FIL8Bf^{-aubzf|k9<~pJ%D}W*b7=yw^nY~R9762S}nMP zIH2?cq3pn%Dlg9JRW3`ztg`imHRgA`j1VLg_2-y-S;}XCd-=9lrdJ%9nYr^dM++`* zbF#^)D*nE+qzYhtU6)IAjLWFFIDIaodAjE`JGPC^M)0YxfPAD)|GTTr_6f|33*WW} zc^@BH*AxDPkhD%^pZBa&izP9vJ)1Z34ZVFsp$8q*J?L#ygMiWHkpPXAro1aM9)N0x zktm5bC1#X+dk6eh8%UlXn7~oyn!T>umR}wA@$z}-@|`-bcy4Q*ssm7*o8rQOs68@! zfNWM-6FmH(0(7Bx3{ibm!x0cs|GS%Wt5Z?>ByaJj_B_~G^9hDOhV5rxhX7tB9n@6o zR=+w~R{FKXwc208%9+}ix0|YX&N6W5&2xsE)gH>rlaau;i1+)>Z$1t@If59(Rs*SY z1EQlg2V-1G`J#zctKX3~_3DN$?WL^)Mn&ABYv|uS8{AK11=?Tn#cr4UZwGDpLUixs z+^wI-UXD&{fGeNvWt?#jzlz$LJWy4^F?2YIT4Z`5#-s*AGmCJYT?iIJ+G)~khZH1y z-5R$YQ&WwsQz@4z%6{Np+GXEf7wf3CJ*>te%^Dx1_mPg%XIK3PywSw&eJBNy(Gy>| zNgwT>m#DI!R#N-|m)RYR&d6jQXOa0l><#TXgxb5zZ9gu0vk~F!aWes`8zGH$#mdM| zV$)ZTB9x3{@^IN`bCBSihGm&{wdl9tiu+6Vvmbv&-{lnGcTSqK$WP38;9m+@R!=8d zc**VN8f_qUGs?VVKMk6uWedV5&ais9G7oPHT5?&isXCkLyo|U-E}XOh_g-=dy{2IU ztWg*Oy&!(HssAS^Am&w_-N(!c&51V7`B8HlM%c(GebvE#A12Yg+jJ-{+ZQDq4_BYz z?_22PL6YIMlfoBrLAZC15(BUh8L+9aer@tjrcZah#mjaoQ(`S0bnsU3hoE?kv+mL*Q4@NF5EoeyO3|6Dk5`hetG}0&*43I#YV8zt_qSm-{zCr- z=}C`@@Fc3^Jux^yUjVjLn~3DLUF|VJ?lk4cit7DTZZSPx=DZrHjJ9*c0jo5+gK}|p z48Mk@JERHbeQ<&3yUp$otwZh^K*;_fiDhk!pawXv7=Tnd7&}@gl6&tPyTaMFrP^9K zUu>b>-c4bB-pI;@2l2g%J&{A4n<7-i#TlSs9k}V-Czq(&$^Pn4_LmebeNSrdE7{U; z8TH3`cP*WAC9r-bY9sNDS^AHfIcT~r?%`_e=3u7hLWICRwQmRhWp+>|P7h}v!%@lF zUUlYF%b`)eZ`scZADr4ngOrd2#0Ebd>`pBzb$Yok*fh6-7Tw1wlyoebZW4#Hy!U)F zVZq%l0jQ#oh{#+Xf;dhNtJ|yTT1qGlsUkQV1|pthK$d4S98j}L%kjR#*BelcYx%I+ zIuVzygzs%f?1Z1aR{Z;O=MR1acc9#zE5#FtHlC~>7N{~EYqoV783!zGTe5cFExdO1 zVkT*AKrgj!czP z{I-^LPmSC^#S9cp{sX*7ZQOu2-haCh!r!NG(J^E8#ksLP?xk@aZC{%1joTAmBYk|n z@yu`D&u3H&*#emA^`Jy|LPw6_{4k8b1?|`^jGJx8-ln*p(2TcAP09 zQ_ryu>@&KiD??{l2(*9`ZX@P_zSyTv|4EoW{{~h27m&IC+e&T_JRfJhaax5f#!r-Q zAn0ufu@06|<)AEg(e3Q_%Yx~JvJN(dkhB)>Zq{9vN95w=Q0{K4vFwD_fw1CrP;Ew? zn~bj`%{Vke)}hHd{KtcetEp4uLpmbWloed4D8G+Z-*$8Fo1KkVKKp95i@(R%*$}no z`CcGvDlU8|$^4y@wsa|JtAWH->=7k=6eLuS&x=OuZq~5wa8>0+`7>7DqeB4q9CSxd zXA7b%1X|~0Uu0_m?p?jRMcx$(tAjV-A6o&hnAAG$=*IaZtt;~n=24O39UqH3^K#PD zO4I6ho{Y*KH>fK-%M?Y3WFJVB28bm2_S&-G2Hz^ZN79q;uyOHaQ930}K5R;wUZv)# zW9<9+TJYO~ub6n;6eXv`w&(&f2jH}<0gQr9abWQ&?2vo>S5uD;eu*dK{V zf7}b#?xF=U#X^&4UvZLP+X)COEPlIcs{c^r) z+`*4l^n2T1D=*V$lJ;(#u4hyi68fB_%J7+FgKA&m6CJey;RSB_?vy+6b^*coe(iLX zoY3s^x~7>bY*XAR89nRB{kjOtO-D0JlC>gII&Jm;VYKw&k5VrMA>83x_t)ia0ZWb_ z%(I6Q+{`IGxkiHpjb#%C{s%+!pwPZJ|QTi&g;vONj{OKkmZM0;ZyIvoKL;3FjvNm6`%H%DeGyOqPi^hs{$dOQTEGQ?wx$(g<8K z)I>Rgt9ZQm;3P(q7X6^qXHWbgO6|=n_o0?!;>u>i;l!;Sqcn_NFDJ~Z0|eMvmAW7LZ4)X;cgwdj6t6-39S%GJ5k_r;In zjlHiLEB2YL-7+1i@crrN`qdniTY&ED*icO_5u-erkmF|mc5V%p2H%UlK(PfCJ>$~)!UIz`N%}d$NA$ii6(uBnV7k#S@V{c# z^}pgZ!T)|}#Gfa9p~pd&l>d;_hhq6Jfnle%5aDm!X7 zk?1CzQ0r4K6&|TWL4ID!H;6Hgf-?~!&&>#cs5J!H8jGur+<;ujE*^?nTX_2OA3s}Sj%3J8VZ#KTD+}Iv`EfL zT5*`!5`RZD#U-WSPzD$8WG-(&?X5fs&#ZLXq`A}w%MJV~8n0HSqh?+-{4}`8g>u~N z6TY!0tf!+txL_-aoT)?y;rR!_q##)dWUMXYOj9A~kS3dZ(i2=^7g6R$t;w?mfXv6n- zEjSKH;?IAA*>Ss>zXpU{^{yEUweeG1mw5YT^*OS+0cLIzlQT#V@EK6LnUn3AOeyV^ z=RC~OQ#5vEN%GrEEP>n|E4s+NThSrcysV?uRnFdX$zgdCUv?6IJ?BpB#w_gprgERXmz5ex*jqtX{RZSB;jb68} zMGR%A`?*r9W^x-WYl&u+_i*wMpSnh7uPKLN79i(c2)8Zfs~Jo7o9 zLp2Loz$gz*?se}pA|JuXw_v`SuY#pz_ zo2h+=xAP56kgytDFP0Y(30H*~b`q*SFa1!9JPJqCSB&!#hdoO7PcwV|Y?|MoNOD?Q z)+N8n`jfvWKJ+TIO`pJx;YXnGgB$uF?$uo`$ByFQQ!DrX!rprZHQB%Ix+ow>k>0Bm zL8^46BhrjWlipNnhyjrnAb`?)6%Y^*=~5yRKp@mmM5H$fH38`*QA&isv+iflytDU* zJ+o)c{P&u9*Q^iuNM?ZKzJK?1o#%0!#tU~{mo2QX2_URXbZACw07uBmp^o4(`MKC7dN5gF?82DZ5Vb&b4^;S!dRx}z*6@x$~rC1)1SlG?fACK6Z zDsOx6p0*UQp$a^Qr5MY6KN@hlV?NzGI;cl6tqz|XyO?y0E4J>#?_atj=$cJYAxV2S zr;d_0Z5N(PY-kU9y&0$BZQ?^}DQkfx+ZljAP_g!SQ^AE=&!v3B#9;qM!~Jov@+*fy zA2)w@X4!eSX~vGGfpL@h!S_$nuVaBYPWWkmF_WgOJw%RZK1AZ3ZFb`8m;;1DAI7kS z5*nIfU)rajb#=GWhUFCuT^Vv;x(IvnbXk|-wIbb;>|!0sK`@e`Ty3dsueJGAElG~2 z6=D}Z=g&u0WQV5``)0%c9pSMJ6aWF+Yp@85V!gz>irX?r?cn86&WM@8E3lsf2_%WH zG$AxzfgHF0VhMiQZG>wjr9||AH9)3H3HV4-o%}V6(g?uOrqCP=1RCUoc^JGM$Z%iZ zWCrnit0Q^d@|7N0U>|n@(+O-^GzwH&upnyg zm7mogLEFgdr8j84r0djqky40$Sde5P&#G8&L|UYyY)=rd!n{>; zEv?GI$PF6wN$L0SGmqdu`nGk*-N=c7{bBO#HC9lKz3wWc`0B#$T+}KK4gu^()k%K? z#o~&77>mYtECIJm3n2!r5v-9haqF*9>)9{8a3_-a#3dC;5ibTTQ-G+o{}j@Pg~(z) zhqMnJY@0YzR7DDO#Uy@?IbdXwzy6ak@u667gy#yEr{+y!0zqGZ4#IvG|CvZtha4Ed zx~JZD>$s8U`LpU(w6a2BEyI2JRs+8yKrPuV(Aa|J)VxEIz@srM#sHC`SGDOh5h^-e zkC6^MGzM|BMl?(U7&NULQH3n3G zr+UhURZbok2Su=2vjp4zq4Q0*vQA+nBx{;ET)eBd9_YL?p(#KFSrfVv++d1@H%9Gu zhg|ftC#jz_rYF+Mk@@rHlge{@RrX835e%|TDS|MkwKdte7yHO!8pvt>N6!g|pNnDb zCLEJGP$|gGzq5BopEG~vF{C(vTNABUSE#lHkU?k$dT_XNtQ4H79ELWT{E-EsPp!2u zOSO+DZ)aWnEctaib&TG4*Y7j-$^g zFS|Uz)x=C=mfjj#_4~mUuuLpM=D`;Qk*9L;9O2gt@nh7mpzcmpylnTrHBQ}1wIUBn z;OW!kw4Xn8Z$on5zg2M(m=G+N^6Rx>m7oXBk58p!@RF*48!pGYI&;TRYrDCl5d$66 zWF0c8>O*7a*G#b_i&R4^{T#}a`5Ci!B{!~oTl>lv5N-v3JR|d>=^wHrZs=^OZ#mJ~ zoLIeDDB0JN^QWV09!Xm#G32eFnm*ny{MYvzHkW#{$WT3Kpirw?3X5QC${Z9m|8umKD(6?!l@V`}LGdHv({OpB!s@LWjkMQw zM*=hs5Cfz3%nd%8L$ev<=8sSw|00W_@(o~|vv5l6M*q7Nd4>~+pXC=IW&lU+*gqI! z>A7U-rlf+|&QFha&zPpEbh#2l4*CZ!NUQ}uFwe-^VDYIWP5u9qO ze}b(Ks|~oNk@RfSUX$M``zM8CpZdwZjo#$aG+4dofBjN~!~?+L{GqbCO~kmcU?|Ka z$va?$aW};HIA-{vQas&lGSgqzFLo8>_qDH3RDa{pvR7wWE51R}ne>=bS5O!O`&2oD zGZizC4;;3qI*_}uWa(c9y7{AD-K`((;=DO=WOC(lG=HfJO_cJlsWZU!b@CFT`0hj1 zhQ@KT2;o@Tg{mCe+Wq-QFHxV~M4QWPc9nT*vUK5>(+E+$Z4pVNoA?EE%Q9=DEEv1O zw7h%A)9&pbb)%3&rMj-4Yp8_iR}|1ek9Sn}=)3Qw&4fs<%FaX1X?q1&l~!V_u}K1S zyB_G~d?Xspy_Y{0+eGX3)iY)Q7Z(qguJ+{i zt_i>j(Ah69I}s86D%||pm3o058MmhPp{s?PZ9MXSVt5P<|BQ3}nnic!YJsW{LtRmw zbQ7Ig#9?fIOaD{=PEv&^TCuda;NUo#vFu3y(8daqCi4JXXxczI^mp_hGSn5WP7Y(? zzWfNFNxQ;!e6JY0&V876l$(0;+YoxpQ%H0CVNzPwW4S!%E?tqi0?z!6p;|D!#P6uF zw~GnL=&=%a2bL+Ck@>V~6b^vqQlb5J>gtY_@AA#$8`^s5x5s=3*;+sBo;BChLC)Mu zKP-c-FnZIbwkr-sEdAAkB9g+Os{?yGRXx8e>HRO$O?rWw5ixHb7~ zP&th#76Z1CqW5XP45JmHu_E&6I_rL*TzkqREz2#$aK%M|CW{l?lsL9}U2<KNm+* zDTCPQXST)sY@9kaeoQ-|vB&iHD+k4VpYHqgAeUI7uL$a%Re?k;=1V4U7r&Bw`h55y?_V0*u>jCg|yz&VC$%acL_*Y%^X~b|cFQWh7m2O*6Tx{ochybhqyb=qp_zKCCTP&{W-Z4*}`{zlhI_O#1;L8DT5^E8I$l%nmSX<2jN7j;BCFz?s01BnyCZ(SfGA zwA+pIwmKeC;h=Tnugczhg*)%ZIZ^!uy3 zN_pjQZld0YpNn8Sfk^dx!135ax!8}gIUB<2H@}!Zr6W|Ut#1A$a%lxJn& zH4c(+k$`GSY^{I0a9FvHXkETz)WXreWF!c;gfTyx^6 zP)%nN;6K=c+w?Fy++l?s(M$^%r(1!GI@}*@Hh2n{#c#+5ug{{15cI1Z4$S*D%cSL< zoNAY_SF;m&^>r>QU#`Ee-xhL~J1J!@^?UjX5|T*vd$%hxf=c#CL#y|6nG(M=kWw}* za>5PIH!iia11b1qV59rLC}*_3`rxhMXP4VW7tXyC&JXN!(xQ*l>TZNqcH}-PFm4VN zYs>hNrlvjd?nmvO?fZIMU*;=F$H&6%4W6E5CeJ2M9^ENBjZpB6DMq&$;C4f3F3O;N z3(xhEg9|< z?%NJ@p@p=1sF@c5!y}rrVFr(k)*4Wm6roA3tu(i6+yqh2O%r)%01OCaet6}|%q?r0pCYbws~O{S&U$1pvE&Gkm8--Ok~H*L zB{*L{8+*v8+!0V=5B?mMWf3gp@fo(6a$jtO7wsqCD)Gi}KyI6#j~KctOSR=kbm=YP zne>P9@Ba9+CnZ(V+*B~)h}h8Mme4%LwvcD^;M!GhFTL3e=OG&78++#DoL~k$m}?2X z-hYPZFyVPnhzQi5&0Ty#zqZ0s&$@>v@-^&g&DIK4I1^BLz5F?@&VpS6ic$ObiH>$) ztIt1VvK=XUChzoWe=#iS8Rd%&cPW1KG3oQ&GGY+^QmxSYK#Oi`S1Td1zD4l!Yt0Il zz=^;>_f`6lG=(6GT{B`Rwh~=@-Ls{L2j3Fo?&~&&3_J*2^IFn~Z*CerM0L zKWF@i+5TA~t$u}3@AmKqON{r~P5zyF=X(f~ZMY0EV$~#G`SVZWAv)hAe!s5x zM=YP+cb@5lQTcC;!ZBjxA^~jkX4A*O%r7kr|Wc z38bMj)5*A{b9=;If31D!pun9*22^?el| z%r>>)86uif7mBdmKKbkwlKfIHG?-UBmqTvB=eL!uHiJ zxn)OMG+Z}ejp3RTI9vrds>bi3B;aC@P`0C%{Gv}8pr?ZEw5(7Gvrk_9;`o*%_1hx7wxx-G(9KL3#UMhox$yf0meWV; z!m&Hb)14|r$8!UK^B0N(7HqK7C-~+6G=m_CKO<~Ax4c}GA@R^%YMh!MC%T6nQ^~Jf$ z@?01{J_PwcmpI8f*W2xs!plRJsqyqDH8^pl_7#R5jC#w->@3Fkps2hOQup96?i6oJcZ)qlVyKO{b^?kq0uK1%H>I;Ak5$l;O5Z8w7#PwO-cTcoMLj{arHv%oLk+Go z%s+w%tACMTW%}$kdgXT-#pOsBE1U`6-e1Jh(m)Ij(~2j7#p28HN3+an^q_JRFogD} zRJabrI@Qo9(K7K_jFsEsy4c;WhRTG)aDK;al?>wZ*@Kke~VQ4luo z=0L^?YPN?F=8hIO(`!GJ+R?Wr`;&G9(4WEsCR~A&l57knHkivlGw8rc=3_sA=Znab0l6a*yAIjo02$r zEYd)qn;U&YHY`MYzuMMQH2n3g4GycdeR~VCpviYRnJ?Ry64VnSlU?d)SIoY3wp^lx zS!WunSlUuConNvYX0&MSoBX`YrOzVBi01cshF4kh=tThIUvZ*r05)lfl?Xz2vPC^2 zP|Uqlt54vaC?6h%QoP~5Gu%Y>Ogv~P`P0GhCcX>xD;;%4d((4t;$SUA^)p)T-3(te+pB!(^>#HlYKMr2cnw-^+ii7CeHgZr;xJYrkU}R%&hmpy^?tEj&8spxQh}@Bt}laqk^)he68QRpfD+G; zigH|vWZ$L0xU`I{3|ymBGh3q;H}9S=_tN~=szI*?kJ+mae>V)YdS^VQ%rvgoGovr0W z5t0mk7*=dgsCWb9CnRhfy-dM(z-J-y4>mRqEHmIeYVRzC4Wzyg#&Ff2W4q8R+*>QG zBsYS>fEXx&WdD))d>pggIC3}gk5MY#F=evn#xvPhouIG{vYaP(seXa9evb94ip6R2 zt{9cUcn0!Mqe=ICv31r)1alMJ?n_3 z{^;c!`1%^`Aw9?!XTrMMa>?z;V?OF`*MHjKw=rmj}1RMk8-$7Ek9(?H@;ee9wE6ZjR3$N1?Y ziHh(mw>L$gXO^Fv=u*9D*4{Nol9S2AM8q9Xb_?C~5P4}LVzEH>;W1tTG^BQyJmcSw zA|m0EpZM(AYOo@}Ed!b@P{@;MZ zQke;QlP~IAIA~BmKU0$93`s2ryX25C3FSWndcH+eu4KmiTg&&9V~sc>lYza3Kyfj3 zrwpvIXCJ^nR`zMp?r^8JRugwldqXsk{DPsU`NZYAj`{=$RA>%ZS(GzZ!vK>!b2elZ{*Jc@eRQ3cYfY?%Mb45l^PQLXpmH&=YGSH|* zlYCYWSv=2VTHP_V90Jc0f8)N}h(-D|zHLoBxi`!7TUanKVzuW;fa-GeQW3Z*CBb}Um8IIUI=p1RXAGt?n`?;E^%jQ;lw_~rBp012dB(-3xQ#@~ut zrI=NB_9;czK`_B{b+vm(-|9tRt1+_f@w5dA@JjI{ZaNv;x4d(Ai<|08aRpu1w!5fF zVFlPm;Tk?JB}8Eh{Kc>OICuYH->Mze?54jEdqrJl`!pGCn{RyYV1Zay+?#6|+9^Mt zISB^caVMXV4ksf4oZ(ucOP}*q?<0--z*anmpJsXwZg|R`zJ#v0mx=j%3z-^diyjht z7en)<`3eQOQ5pBUbkbAj1V9i(1&ex^WI8cxkKoxpn@v(nxR z{QHJ39m^Zcb_6mmDQi$u0FOwy!B@{o}yH2&7*Qgd@^AE2Ii z{H#HS;hoX>{m46I>!EW=5#VBA>5!Xrfa1U({6p3cKpDb(r7IJZsseaIjf9J4MT-v9 z)Qp~V%r~d>WNoI2Nwl{U&MNl~30AxJ38!zM-YCs8j(AiscnvCX07`m`O75(KR4v;( z^fixhVm^P3$yo4};PD*d24+Y-CaG;w#Y}L~f9)f^L=&7-Noe(=0b`f+H5q3#g-+;g6nJ7^0JtBXo?i)t9c8sE~(5a&nSJeSp(AnCV6S;akygz!1t z7ENYQ<#?tb!60#m=f~d`#ZdjjFk&b{SeuxHpVK3jRw&p5H|bpd>V)_u@8p6qBkFHU zOmub0$<_VAh+c-spkf+SC{E+?EN@znq9*LxI*(XkgbeBKXrFas;}Tz%~bvhld14=P8q*50dI!ca-&xOC!a4 z_Jk%G{MA?dX=FG(ao8F^y~2Q^{{+qjSIuA4oO@V)882u4X*cqMkOaGzdQ+`zEWJyd zBL9pBn~NUt=>b;Mz&hL8K$OG-K zRc7sKF^9|8Ue28eFeqMds})~2!isgIYgV#KxSR*n`g!RqkZa|6yTaJ%fo-Qn*Q=vX zb{_j4RnB(caLrac{V}3<1Y(u+@CyOr+&x*0T)fC!K5$eN%#k#z#MInO|4PUCfx=?~ z^$fowQX<&*LdzDnhf5rZ&H$46eWR}U)It4f+n>E3W)Bha@8adYnQ=1xp<9PJ zrU59IS|W$uMNvSQGx``JG){idvicm2p$KB;$?pWUXscHcuV z|5~M6==syFe1ljNSMAOvf6?-3-?D5wzNq|Zi_U1G|M}eKw)T7zai7%N@J#*bzwS;t zoT`_?7uC{7Nh3j^Np&S%HYqa_>rVJ>~Y(=Sv6 zw;ks%CJ6yPQJ3_SO)dD9c=cfH7~=}D@`(nL(dx(9{3Gd;NTKk?gB$dL< zSCj^198?{3Pr8cr@ym5Gb*m5r5rhqHULYXLX7Y2tPFi2yRP^-Sn`+5ULB-v)5go(&h8lTv2_rWCAjr7rwoBs|owavKx= z_3SN&IXbMG{`2*{Nu^9Ru*b!sMb6(h)~?#!mW3)OpQqiX)S+uoNOzE(#~T!VaP4+W z8+Q6x4y1iw;#Xa1;^;U1FGeS^Kiiiw%=PDUXzWl~tB1Xa)D?Zuix&2s7lP7l^w^e)iltE*NiZO2kZNmXB~wLhDUx{dP0NGN`U#O`Z7f<-XnMb{ z9&U-)Z5t`v&-t4{d8fp2`Jj}>|Pr-j+RZqDGZ(e`m7bbcTy87oD0Cmoq z@nGzSwC-hI!qsi7aBfH|=G=68kAK#_8nYvgDz^!u#%ixCyl*7~oD+OROTq$9tY<7L zoQ+U^8YhTnPoauM=}#?$)tr0(rltPa-Z=HEB~#9aF;zQbSmJyC%oUol483%(ke0-M z$RN%5wJO5 z1R%(8i&%+Ei*ve0497I3Ma$IfAJYdypYwn$PKG%T1%H=%IvI($XSs;~HGBDMbTu0r z(y|wYz*|?POP5U%Q!sEAd`Ll1^qCY|k0$$rAtvyqn_s$Q5FgJJv zY0e6;5oitT?r>#d8p6@Y{e`-H%};0WXH3oteMdzB#MS(X+(%)bH;JFv9pA0({F2W?oHaGEmZpAVKk8EA2l z^Ok|GSRh20f@kQ9paFa|TmgmldfYFp&$1MKjqXy@HF9R^JN^PGPkWm@wDaWN3Fb)D z0s~V}yRI~3#5K5FI{_eIp}#@hNxP;P_lZ5B4(Y2PmLc_R9?h-xXsTfF)wyxZSTZ6& zHb$O!iaq|gGv(|#^a=dZ=w)-H=Yf!|i;JYl8*2Tf@9#5G{~{EpG;hF)`Y#ocEmmTe z?CNih>b`)^(-mRBQ|QtAKIQN;`4zFe-%pRfr#&JDtk#Utl7#Ss=nik2_4Y})O669| zD@=oDzCGkYOU6eJ%je~9v!y;{B)^%=iL%~-QvoZ|Alykg-sB{NFcyE5)V>sCMu^Sk zHT}6G$A!}6J=54uHTq^K)M8t454Q4ZfF)RrjG-j!q&DmRILZh3X|bLbO#y;++1lI&)`pwE}6Yh@`(6vW2Le>(J|am4J{gyB@~vc ztgs}|;yD`z@x>kUe!%+eSdba3NB4t`ve;vz{H`Qd05v=g%7bRWT$9BX@8~k82 zTpC*t=4Z!EIR!pF%RZ^}Ra8FN_b=`M!EkR1qg~mhqkh((b|a#=HvwESa5{AScd1GB zw=HCQwt1Om>f6^W|0I#gMW-Pj$gM%Sil6NArC0KjuGkebUvj}gEyNNRLgQ-xa%MnJ z=|5yoA*!0FN%XU7FyY53qr8a^Z>FvvT|L&OR8sQk>J6*haixYeM&eq(R--_wrXWlW z@ca4j!90xdte0BjALnH0&azvl+>}pqZvCApTzfTvf(kWg`$p=r9|5zT@JT1pX}AHF zR*Mg=(TUG_L!fv^QmGlK>VZuzD$)ngapX)0HI-%cCQn5Eex=+zm9CzJivSE>!}#Gf z>j9Ibxe&Lp#A9bNFV$-W&^^tn}P`VgH&{`#H@Lp8`Lu5rRlJbPk_tAMQ7w>w+Lyw@rz| zeSrdWKC(be@4U}CpCewWd}cKP2fA%3`n4J9nVfrtY1W8EoRydAIgbzJf9Y0z{-<=S zXBUUv0-Q^5F5(D&TUN2BiljG7GO7l@%5y(gzq88&k7@N03sGG=eZ#D+#$LL_UOBeH zNP^-qCKwPP#UMlg88sk`YYV>Q&PAW(TPMgOYiz@3pbATEgWe0A>ko{&e>ILmrUKp_ znlvE%Ctx+IAf9AbU*>UzVm*a_ww(EFWZFXvibMIuYZ4A+wkq_!B{Va z^T1^YR8ip)u+u@+!v6Qo{I{o2a$pZ$24NH4eCeh>g*?krOPUdhcPEX^R~A`Ud5aUf zXfFj9;d&FAig3QpNi0D>ufn9ni`%<>qrUJHSiw++T{(v$)5bkEfPv@J=k-|5Z_jt1 z{ai&|Q`ZBo6|W1^$N!|1&k3 z)gZAkE%y}w$r0e3l)3A4cShzwU5-#OXg-JHatjiEJLNKd$j{mo!KcO{d+xH@O_nNRXD5OEQp@(fhwF!suP}z4DUpK=*8pg-Utd zmmi2PzrRkNjhWMO0cNqbBmtby8#`!y6b?bPYZtJmqSDe5%TuVSjt+y|{DIY+cyS<~ z5r!}QWp1drBmG$A1Wv48dvH+^ew(C4sHhAID}jWZ)B&QJQpZIjd3y&>cY)@4ZQcy- zzZ@^WH`KFIyt-yox+>6b!cBU3QHzSGTHFcpSxriz9E+9GoDjBE>MW>ME)d<(EtXR1 z??W(QVb)DA7+u7d>L=v(;VCSO1W`fF!96$#8o(7CFr` z{T|t1muJZy6bYor0|7p`LvCO?ZB-5Q@qr6wE6J^TJDk6Xz&n{@#ix1&sy@evbRA}m z8@+br*QeM&D!hBtM!!%D=QdtNfQp!^+8M6VH34TM2(A9~v^yRs^%2<*TL;MxY9xEv ziU0a7!eq43@U$ecN~j}n4%^&9HE6;DHxAyvky}eNc{Khs8qgDZzo_@Ql~D-qh?H-k zW{s0Fd{ITlvVO^XQAF}60~BE#t4Re*a)?gO-Dd6zgb+wB5(a&72wj5O^l~kBd}m{p za`AkTu1ztCo{luZ%$b7jY2IWYb5`kn*W^;xmDGh4{PVIU;u)l;V((ANyRYB#)JM+s z0RwX}!Q&*J;5M5^P%-`&x^NMME~0Om_Am75OZU2i0YTw8MXrF26dCYGCj6TSFkj0^ z*ZIl$rYOW@zH#jyF-&C-%U^><5G}L3OvFy|&aF?*wthSFY*ED!uh4H$&h1~KsRy&3g24hWI-iOY23x7O27i?TlgblE z!f1*Qeq(B&tthJs5sQEaD7TB2K8iiiV#`C7dZ*nWzaryi{gmY+^4*Z)qLQk>_3+tD z$QdFgfZn<%m)jtc6i{tYP7HMndyEOq^JrT+QEr<`4{mN)+PhfrfwP-pUrFwLC;cW` zp5G$oc83hc_$M9GkYuw!`0_oAh+a$fbT@)b31tC$^AgWOt<`Dp6ZyrY1fG|RrM_!N z%5Uq&y)N!2idX;tZRfl4pP`QZUrIddL}Kw;*K3j(5GY@vPzq}07a|1Io?1PMkDV2b zadov_mzNYCTmOEOCZ#n!(twNXX~Ip*{>d#gv|iCb*@D&{L6_5nIbP6Y`4 zkk*B8F=Ctx!2>%OcPRpH&isiXMh?k7Z+>3`Vr~_Nu>Cb!YYLJ6uQ!JhXn~SGdKYos zZpF?x5blUmbEfZpE|ChWhwz+*-cB|CKgsRObWW=leRsFzCcf;7A}DtzO7@WLeNC{-6pcCmReRDcsR8WUv9uX{gi zAg5NZa`^T2+n|N5CNp3+#2s?M7J8bSvvjl~W%p`j+%w*mqnGD(L+UtrU)S8RC|W(K ze5!FPQM~Mm-hY_@*)}?P089eTIo?U080rI7RB@u?Hv9VZRmD9(=KT~rHB6rIS%ydB z%#^D9|Bn3x*OwEx(ZX!Upxxq@14@)Tn%66n%F!jz2Px8sC zkBMaB|BYV%5kk=aQnBDY;;c`S7Bh~RN7(J|yrw#XbP{fuCf&vf?Aycin$lixWKd z{pTqOqUM}4W=}GW$gT`kay<3g+%)VUDiAi;R1!%#gksAF<1a{}*g8m$>GIAi@Pz#~ zCI#8T5falm^!(a}TC)D{WTZXWw=MNhEMQY3IHLvT2fMqN18xgom)m7iy=5tvhA|6X znDXWlxzDjD+C!%~M&&m11gR(r-sfFrh)#Nv(DWV<4mJan8!~l@OeqrAku}zd-5!C` z>3vpA?e7K2)sO4=bg>9@oi&=g$1XPpX^&v2MckdNnA%_Ncgt8dNVk707Y7yzlHw4} zOMPWj`GZ|c^cd8k)w9fUQ6i;D@3k)*%Q8^JFzL~CIrYu}QU+o}aePiXW*K2aiZoSc z1ikw}<4S|IT4-F$_%TX-roKU*NCa7PDPVeU9tC+V0|a)N$$$> z4&JUWN57>dN3I=1jDQra^tIm8hvOurGVrY3Te*eh1-qX*6e@T61u`>!#J_QUkaX%* zOMU%!>fI{1Bz^(A`KGr1=#UcTtUnG_x@vboFW*aRcyOH}{P?*ZLyz#r7!}{`KZ%2z zz(A$z^)l5(wI;b8oO${~x|b;|^WY3KW)XH@GJYUKJo4=62q%S$1Vb^&FPxU5T za2{O=19Fwt@%zyAKP6FCUt&-0t`Deu{E^DmFrYoe>tDSwyVe{x-1WH=;a3H}HCM~M zv%E2=M<{Bq04I5b%9MLhCd=3K)7MS!WR5}kf8Pu=wNvM{9txR5N6;^j$ccr7ZORG4 zSPY;NI&I_s`isbBz6pht({$boDmyxi3TcA#rBbKCw4F$hYmn)wKvrqk) zlSe=E;Y0c;yyn)o$<_&^x$<0Io0ssU46hQoF@6YFkc~TPnN+%6-r6yR`OX6NQ~Vt~ zIix76-U`^#gWSz+FI}=mcrlC8C4V)}&3B!62%?AmD;(S0dT&*`-c*1n2<#oW_5%9H zgXYc630Q9SJPO$+P}{ycY!-LFulb7bypMlZY!`dD0<3NDBx_ojJwzoMr4oj%vESD_ z+O^q7NSEcBO-uJ0F(Y^Vl@&|<^x3opc^SS2bVWzdz)k9naX!p21@u`xLZcmH45afG z92|yxggEoXat!C^>0C?94KWXoL@W_30L=)x=DGKb0L0pj12yhkam~*u^a*V4c8QN} z_^i{7eR-GlZ{*-cT*|W+!dPD#1yKU?8;zrSBS;MJsfGob@WUei=%zh+w+!N)8mgf~~hidAyo7a4~~0)_lB0FS^6K4}A_cnW2ZS>*>j5a{Dx+OJOqubd;Zxh!5& z0itF;Nqq)tqWNr?^2UPx)W-t7=A1F(3~3?jFU>#$f#(&+odKL8T|&&$nvCwsQ5g%u zVDD!LKkzN>jv#|5bMqsx!J51#)wbK=w`LEJ(lURnKs~&*uFWmQ`yA{izqs$de`dKf zK)rcnabgr_k0d^53q;g|^DjDz8a~-?2XQ|x)kHvV6y?&dW5SwooUUJ$EB)0@(k-bp z;t)H=hcs?-DJ1#IbKak8*FEY?qq8Rs!v@Bk&cfS`c=F7x%_W8 z*+U=h(7rpW1NG&GKu6w-ie43Wee*6`TMO3TmiwD4^T=t>6ClQ8rOqF^5E#sAl{i-pq0jbd2Sgd@ojmhnJ~YySO5gU+dW(2v4tlG zIf{P-yyPTQl&Qpo(_a}_1n5Y%pLW@~9ZC5qZ6+=hCS_if zc1DAkvch#spAHrH>8}VZ6Y)BBA9Mnp)8yO*1>>|BiKRyE)8D-^os2&retIY@FZWG; zJ%3>FRlDCZYXmkxMSe`%>wM!jIegnv2?A1j_fHfTbsd40Yv4cn*bq zdoSa{M{R+&4tgy$Vyo2TAF_%<`HuWQz=YjVx8E0bXbQ;O0&t*Lb?gnwh2E!I-^k2c z=(*mqkx}0KLUpwbs-`=km~dF{U#K}d;Ap}&+3d2nhi%C4Z;PbP0@#un6U@Ac;W z72WKCjK5(xS^BLA26c~fOIQK6KbkutRWVHB`{{#Bs%N2e)@S#PLw&uYGY3chh%B<= z^t$^4!&%0|nc-T*7QB_o{Grvk<5-f*G)JEiwAv^{$?>M*T){pj5}6s3uT~yk7JXA@ zKz;3(K!nli7_~9Zl~9|{pTB%FbrEx`b~c0OxW&7HHl@=OV1Nb%YSbw70;={)UYOA3 z;S;<7;R z%4UQ3C9(`rttdZUeT<{(nayg@;wN$kiR^XeUeuU1QF!&=DI6mZ#x%C*KWSVxDIKW* zN;YrXidd%(gz?9$oOv{)JW`qvE{pA2Lo92uo`c-(18`psXTVU{fF_O$6uoLq%HauN?^mrqfT)m5?|{ zb~cma&zk!s4=-@mhhwi*_!Xm0z~dXJ*;=?gVgamD4X(CX914YotsAM%Gx|GGHYEhA;>$kwbbXY zza`wHoU!Mk>DLkD<)u3+Ein5@^gHR9zPxJ>Gcj^x0O9Ay7o6~Up$P$!Ul9?=(Hdy; zO>R4+`+UXEIDTI3v%f>xHe2u0DJ-t^R_GhmLx&_KL+cQ--ydPx))oBVvXRKI;kb zIsr2H4;fRyMiX)BMhoJnp@2mWpZRAJC-fB*VOSNTBsbzA~BQslgu`X6(Ke^9TaI$+fxUqQ5auER1Z>}1>sT|*Wrr2 zdthYl@gV-KW!6g?LtYlkACdwzaBpJv2_l7~rTF@B64c&t;*uWLWs2l}u^sSh5!LMD zxvKAIJCuy{G8h?jXZzLFxDqGpUo1enMX-)JMDdgf!IQf^PE6xSE}T)Rk^hJ?W>OCnnIaLFsPyy; zXQ_-r?9bNoQU?4faHWXtWSsRT>0wQPnu~G`oVu-Z>S#CAJ}-*VM!iA5zB~Oo#qZ!< zy_s6xw#C0SCpl3%1cv^!=*z3byg+Ct|1K0^RHY+2Y-j7mU02J7d!+YNhiDJc*~e}fLkNBz2dvBMo~GGZ>e2=lVVWf%eqHYa^i<#z~j`ycGRcUV(hzAqj`MWqSSTTrUflqxj}(nYLvh=@pu5S11n5C!Q?ks_e&Y79_o#)*7&Hc?e_sn_j`$r7Vv$t!ltiARs-|we1nW>Xt z&P^G#r%ryXa3}jD*}aQ60?Es7FBP28uqT%jyQku3ZjjJG7;Dz5#KoGBJ$|1cR9B*w z;w|{a{?1AToS}sG!@-BvD90k%6?AY#GP}Fjr=+H7hB{74|E8&LkBo-ULQZ4KImffh zM(k*m14Fvi1om6#=1pev=&)Mt=~Lm?CE^Y*^w&_&z!?xPpfn^@Q77r< z?y-2+Uv&!mfakDiEZXxX(B2q+G(uq@9b6kig0md4WTJctiao51Uf+Uv;~cgcdfmfX z;!XI3w#bH#RQcH4cMdwHgA*1E5d_REItZ!Zg47gJQLb+27C>r+o|_~q)(n%i zv!#NzGjgnSjJ!`jaO;QMsYRt|+S|u%YcRt11Qd^5?z&E|H8UACZYBmmgy?~UtQru| zBQ9=f_m@d=SdNk6n?|bK-#RI^vg4Ih+-T&J z!|b0dq`cWAG?hjMg0|VKV6u3{;q&s=xJ1jl(<3IVtXZ$MFI35TzY}nm zc2%WNk{vFm4H9t{d7KDH&Ob#mBjxg!xgg_D-INU+$L|g%j@U0qc);A>oQQ+neOW`# zwLT$V#50 z^`>X$=G&2g8R~gWB(*iM2C;;TYD9;`U+GOHS#1C(A5$*Y)U0V_u>w48?8yICtH{6nDnZ;$-5FeiZ$0ASYtoNh;c@mcOHR6 zGw*fv+<6!w)S#|Ecd|yK8B?kjfHOz?L0PtyLy+K14IK0wmK2CxUq)7&x)w;?4n<@| z3oP`6$(m>I^X}bcxl#}Gr0?r~s34G!_iDiey3(6T9ka|v&qdtAjW#Mt;K@b`3L|X& zoLI`J{1?n3B1rHu9~mxUPz{ zhRdnbvND?dkDWey`DO3`ex9)OI#$AH8z$HaOiClRuHu|y%Ii)M_)Ds#HFLFHgg+iz z{-h*$S)8d9kA!$#f8%+JVs%T#Dr}|~OWTqd6h^)>3k^wOlu|hdjyzxauBih4>3VMd z=J@rU?DA@zxAa*JFJ(SoaZ}b?pE$)B8_@g79v!FxIj}~AnUYX6&7Dz!3L{nWB`yqa zXPYgJPQ&F2oN*g#Z?P?madr2F;Vatu#02~r43F6?S-##CQwDZi3mUS=*5?>JCm$)*tVA7(kM={A|Y(K z;5_LSU&e(A&soj*9iKNfik3lLQw%+yB5Qu48Tv4=*?g-XNaKY&zL(a0rB4*PPE zEH&dw=6F4BRF}pZhce<%%f8ATKTMd!o3uvlSicaY_DfgcSw~wP7LzpqTHYA&iqU6S zHmSy;XTMrL<*e&#KP<6b)aJaK6;^nUld8nOA*VCfV!t?)L|NU5CH4lbZyV6ILFk-I zCA=w2liJP6d_`O}>_w}Wm-WzYu%+uvY`bqWK5g!N%TZCBQ;V=6j_Qsg4G81c2rd4O z4n#(+Dk3|U?V-QHK*3C)X7YnmEnOuRnr8})7X_CVF2ugK*!?WlLb(V4pGN%)^Yc|` z0eqaPT(k6qg~f#9Gy8qF^cxSaoD249X>5#VP@E*AG974rS zl8az5!pYTCMfVecEKrwl{W)B4cOg#bvS<9==9{6pp~qh-uo-leea!J4P`eV~!=&MBYoDKj-y4_J&g#k?OX@#6?o zS{sL%i3+3$4Z3ndjYvUg;g_;TUuoq(s#f2U6Nx1kTRvsO-aP_c*l3K3ck|KJ&7%W0 zgxCI>j{I|4@?Yy4_0J1n13T3}3}*kIGnl0@C?yt_5cU9FHSU&dGeq2GD{cxe`!zeo z&@_`F)F#?KBPQ)`=6cj6U21nK2qSt8f1pQ7nsE*~P(U=!)hF5oJjJ_?)8fr|8c|kLCs*k+^O}MvdWN$_ST3-x{e5bpU`Tp zMYjVN+>QZ&hs-@S2#U&Qaxlz zq6Mc=xDI1#%mJj>Xo~^g3YdY!)!9bjQIg9EQjt;}9*J`DDSqh2sn$dHmW&_XB80b0pwviZx4veNganNn3Y7> z^jw}0FTZCVeC3$TqkF<_PyM;BxG{7v)%Z7KN>W;Ypc_rIk9X_t6kjw%V*&enDmR|9=xyR2itnNCh_#tsdhDA7LDqguU?OX{e3Dei08tp2c7?uljd z(hvAc6zw)7aQ{}3a9JwwIO3~XR=Q+2PJH)??x01yd#WplXOXtlk6wFh-$y_G;2J07 z+8u2fS}+fyX~&ZY4?|iLVTM)JgEW415)N$7CU056@lFbNz7(5ZO%_F>FWBE|ezP9S zaaQZHixC+@z{~-X8!j{Ovq)GSp<@}t$hEjWEK5_J=mfo&IGjJQIAhVmJf8WyQy_Rw z`rP@0@#j#hKh?)#O6i`GFFE``J_lgEj0W&Euo>Pb)6GhjV_P``QU3pQ@fY1PZdX%2*y~q| zv6(N{(#{@#aNAG>Bo`0`u7$3 z#e4Xr#qzZo*yO25$0K2D`xk%BGSjKcz$C*(b|!5=8unD=CER%7H_P5pn1!nY^4E>E zO2<8&op3R?E|U-`4?85majXOOm=bi0p}!f%Z#&A*xawp+R?6>PLt+6Ygm1A&u_iCW zE55HR-=%y`rFcE$i#(6BNbEszD6+w3ra)ll1*vH^D$wd!>A*IG(a}nQ0Euvevs|f) zUYyn&IzKFk**aTwU9j()O%2`U$lRGi6YIPwjQvKS8XyTt2)aW62T0*%KR(*r)u{^H zT=l+A^<_w+aPmuV*BTq!_e!cHQ0(z9yH&sZO6Na{)MHrT6d?x;N1YlJVPiOmJdwWg z#$jZiE?)Y^My@#2sjez|{c26734ddA_0B@bo82ww_oVv%79a*0>|P<|Gh4YKiIkX8 zoDWGq0)<))>@O0{RKH8`yqkDGOi&Q2Ityw=T@%en(mxRuPEkXiB<3_5hU|+({`{!W z=qokw)Ya5A8wln`(6tV6lvGoK>AXCxpsRie!f;{;AUIF+x`{3sn#6;OZtu;owhILxKK6dX_|IOxky zHY1ul-X0q#?Mn!&N_uO#R~LKJt6)`%#V(}Uz6pwgm0w$Oz}4L(IUVqmbqJWyI&Q~b zp%D73B<}kMR-XzSP_QIR;+Z7VS%8X?fRBwGo3u=omX;~G?8cN{u^hni^}Pvs^Du=h zmW`;`c}Ls@SpCxx_W(R@kkp1PVJ(E4_Boma(DFvGQyQ->G>Pil!d>7ydB*=SbAE;!;Z0B8Xzm;1epA8A$$Wm=ycu@`7x;O^kUb#w&sO zqV64*;v2jIKAlD1;h?hKV06}!#yH>%&`LMP#Mu@u=ACL z-91u~R`aD{*ZnWl(d$?X3&@WdzQZGRLRD3Uv}8$AK)wlf#luVA(cQ~EdB;FC zw#ocv2R=71#+2!+C*U{bqUF{0whx4-yG&X9W^9D>V$ZpZx^7@y^hU@s&kF%P?_}BGZC(YVc+C+N zh(pdeJyf?k^orE}{d<-z>@hz&?&@T{HM!h|G$AP*=zK>y#SNesN#|OfF56RwEZbf1rbW#gTG^ zl$I#$U=tq;ak8c=FoeAcZ?$i!Vxdo8JM?zN{Z9IX_^srpu*Hp2W0otKktdL5`>1dg zT?ZUGI9?(7Y+nsvc8}e}f|+4f;zJU05tm>FH#A{6g-N{OMLx0k-+&WB6;7`CVgUnK zVCq$zL5KK?9A?*O%$;(E!%Jy{Gy8e044IcbZj*dRp1U}|{T5upd5pQ`mincXm@g_K z5oG<@jWDk#VeFx$mdfTMuBbpO@W{54ev7YYWnXEv@DSc?X2Qg5yh*v&t&(}`)h6%T zrBo5ouTi6kVw*5PoX`(Qh0?Z6GZd&vC83$j^aJA|)OapfMR9TE?pSxmGHteo+{clRTNq0wDk6=SFff-SZcX2t~_>j8RK7->J9Vi`izyp-P_kXCiWT^Z{YZZr@=k*GcV0E}ydDnuIa& zyXLvJSNUh6G@vKQa{WLk836J#5Vj|X_EYDGs8GRDlD}Np__*h;QQuUOvhp%(lLpV| z6|KmucUM8%>FtqAYafwEAfmv|Yd{PNY3)Q<)$4QH;6juyHm^8kkY0=^ClusY?7>t4 z<$k)$8EWe5$amwhy|KPMMgYsQw-p|WVx+KJdIE3y&oHNBxTz7bxT@kox3JuG-%+^z zT5o`TMxd?$!wu(aR348q2_C_&U~0-p3LD@>IyJs*TqpU3Fp@UAhyGyR=AHB1Otq}} zvaT>wB5icn5ANs8b{xk8I@nbQXQf)9r;#>;+lpjWwzTXOCDz%&Z6C04xx80g%8QdT z@0z~8oXEM<(G}6daGiP-w#h!X6fC=O&H+=}+YF_4q*GC3`#2N9=k%y)DR9+zaHHwg z&X!cC09Hf%dHH~r4rk%2aS=ck1182P&iI}CLnkO1I7S*o@qt-I@zCR8=0hi0qFMsV zm3Q&v?8eT8j%yAI#hWKZzgQezOUHogsO%H-%|;uh!S-BH{yz)Mp~=D{a2(M+?Gr3n z)X&=(_Cs<_sF*1!c>Zwt#Ll>iH#L9Nb+$kok2^GB~c!il5ZP7AZqLc5TqIo!43PE$k`!r)U5Q7lk7MQdP(5!7-!j9$J zt>f7{;}5awYgjKkm6_)$T&@6;4+$p$zDM*V?}m&vB`JUMd5Ax7Vi0qZ7Blc@X3}~z1uz_>pALLMOD`5{2Xm1Ys(ZIU2!>`lgU|bF&QG? z-SoW!KXQE!OQqgpmQHv@rQ1M*#n?p!`^t^@@*{vGepFN>g&}2T4H>h`(y{sq!D$Ju5GE@_>nwn7;P=RNFS}x| zL6JHA&9`0-x`^)!Ly|sDn!X0@I5>k9QmDU%A+CaQh7b;6n<0!w6bOuR-yU4UCx4&d zHn+T`8mKDo?e845rS(Yin|feAW7usHw4M#c0m!bnucZX-8wJfw!fuxpS9w=Uh?!C* zqk2sk_EgZ)twM1o!$tL1mx6woj5CCiXGwc=D0)DwqqPJ!>*G9lPabs~>ExpDUGlDL zxCQq;TDFLU>kq??>lA-zKHpDiLQ#=KW>Xp@q$&Czr5dN1ws|=KSpcK>+m)tny2g5m zxDMLRxOXqidlBkij5MjwT)un^SY3uz#5Swv=+RBnK_~{~bzoV0$tM_XaAvM`ier%c zAWIFc!o?S4>r-h!XZHGbr^E;L@FIz^NK<5L8!ew+MIoiLj(e!)JkhXapDzLO`X`!E zH)DBM8e!g~#$P>Z^JR#x_|oJNDATOIywi=5E_Cckuo}Y)21`kHwV(e}ZKY8EIR;0+ zcuO|+`)nbzeXjJh zONvq<-9il`5`>UqL1;k(N8pq8 z>|Q6rqa?BuB$J+wxDV)c^$?mC)!rU`oTmTv&=>~J_o)bEe*ckZ zTX)mQ%dOPCoEWG0sOV27$owxnY72)6T0o zbF2T{hJr*R7BDy5z!NQn)wDf=C%9MAeMqAE!z{H(Sucao zkBIeQo$_$*t%XxEE}In6o}R$r;>Md3KdxA`W)PxgjnHau-SQC1*J_fQ`dZ+b?SPN9 zfQbgpel9*t3;BMo{`;o@3p%RMpI)NWG5s~HGt-QQPA;=}nwx{dC0{HhvHHqaou;^t zyIjDw+Gt)p_Er1>$F;Vr-GXW~ga>sAIrh&GDE+Wo1Cr4Pw@UOyji!3m6&#om0;h{F zKA3#31ZsHy=7oV<%xxNKPXIeqn1-vY@yJCOYE%)0z8Zy@B;Bg;{`nYm(L6A`#xEbR{`HEE)x{U{uJ>TfJuMqB*`VpD8H- zo14HoULt*OSPf)WmGR~%T;VX|Uddp=OifakqR&#|LhBy)uxjXxJp#4Q7)`QJ)jMKn0fm;tTWP7QYUlcaeXr5pw(_d(&s9(Uub3Fn z?%lNTyb1Y}wht|4ki$8%U}};=J(o^j4P%=!DP#qp3#*L=9C7~JstwQVMsg<7lr2_@lrV?oPu=gf{8m=zEeL6vxX769V%CUkbi_H2M z191aF@Jgb5if0;!O$DW^vMkhG>VmlE^F6w3)sRvr%SsN8WlLTbs+MIi1DPrn;RrwR z!>|6_|87*GS;C^^ZnmTz;dxQH`?lt+cJm$=Ln!!c9l_mdf;Ti0Hazs}D z4kO7K`U<+WhXQ`*T>w=FD3St3A1MG1n0zey9l)oZF(&U#AAx3`#$X6d&|{b-z##HZ zwP;gh!22$wWE!%=^nTb8sGXX^9S_`1fdY54#GrmxQWVJ=4OFuPRP(C%4iJr(BZyIu z8^8uuUJo*ND9RDV$vI5TmP zSdTzz9!DS&w-ESuP0IMU76tv$pg(%(k1_PeTlRl%9ugs69t9?;tzVPW7%)kNw^2S& z&I3m~4@&wGX!9DRLZm(&QG;na^wg!WP9m=!=J>KB?-HdEhK&{MFQDyo?*bCXa0W#) z6ogxP)!v)!#j6X1#bcjn0b`ltN!qL4@zj0tJ^0mHD zaY;qfugyC5314q?=2xGgje!G<%xG3aGM}9yn{CwWZtzZ}8IV@2d9GhjervzL9byaU z03FIwo&fNXm;aMKkbgvai?$iHN%QaPww30=EnsOnMT|Q1PuUCI-e5WcedC*>P#uBN z3Ow2I%10nUfmX;418PyM8(7)qEumy)a#Z#VW>54PWP2xt5*L*KnMsChijvTj#@k1r zA8F9^*uBvs&@VpHTkRIq4s*~ENb}5o%3N=d+7*OX>4FW+#@+ZT@#;Cs4HK01UI|_WNH<2W0?Q!t5oq9ow-YN4N`+J; zhBZwcD+lwc+*i4W>ui*i3^$64D<4sQ*-{Fz^#d!|5q0(^#>N9$eah=f$uXM;z2Q)L z*Nsqj@QDq%ZyChooJZK$!uW-oX8MnrnWyYE&Xj-uST6gjqYz)&pq2&=0@R@?Vu(Pg zvlOfqm{6NF6=XY?gkoOCj_!m+-9|AWknNdaH;OlPHiZMSJk5J7=F6{k!YO@LqJ)T) zwg^Lekh$&;s!^v0qw|Y%XiS!Fp^vx$34X8k~KHLaS)V(%hoQOJU%&mU4qX>c^ z6f-hSk)MrZ62ZZ1vQnX!$$HPTLvW)aqw|ACv%Z~h82wk6{6KcuoUm$=v_&L6kN+aX z@n;G<$$rZo4{CwIR?6tCA z6Sv82elHO0vp=UAfZ&0avNw&@JW^o<2TL-1#)c=VzjN>sH@_1?Tbn-3;oCfVCUx<= zJmI>9GY8sosDFU+>`?z5iBEeON{zq*<}qN-8X>lbSwNAz$p!eABhS*lBGCa#TNauy zV&Eo~9(XlzHvLWeS?>_;Ze_ajo5Oc>;(Gfd1dO9`*I}+N+SVaA=ZXrGYnEYrK+fkM{AMzs6ksMH9T+|UO>DTQ)P3&|Z*v6F<~n?x zbZCyMn*Pg`+CN_*?}kI>9RS(h2ujdTMt@+!G75gc$NBS-0_kY6Q z|A=lGpd$Uhou{V%f6PhQvOO%~&kl;{&$cW7xY(Mmph{;k&n>=hjfih9JxaNim9^7%KK z+}>HO;R&8sm2}jR&%B>x0;@*^lK}S}^+*IYb+V(LD7C4ZLRmksp1o)9RKueyuYR0>_5Yubv0r2H-^Lky0UCuW&LMxa z`b60&Is#=x_%{A&0R9ITd|JVqvYn__;E=XY({KdZ6GptFG>lRve4G0K|dh|JM(*)WxmE$AK3`M4z?DzhuldjbT>CVbp+C^LK+WwaOYiw$oO9BiyGG zq)XQQk4K?E-7ti_*Lwu=(L4gRi5>t^%dI8I;Wj$}X~~mTx)C85&dS2}#O5X7%iv9Q zU$)jpZ)9!sPCwjfo7Py!$lLU;eaJmO>a}A8gO)< zzJnrmsQtG3OWQ1#ue9;^fUy3DBhc;;l>8#YPMak-I>skWU;M#xL$ns9E#Nw zYuxk$GRr%dB(@W+F{QM>w4O5yy_oVm*)%4HM^nFd&n9ngXYc!=@k=rnE>b)?`B;z; zFzTd4)|(bapgSwR?hwo0jgG&4l*Yr8DY5_b(@v5YqL`!7derWb?|7j`^~nB*alC^& zxx>6RcFJW@Z}rw8b!z!EV6(%JzrUWwqyB9<-Jo146a?6~z!tLtj7B-8P>@SUpgQ1O zG8g0X8MU{SLirWGiF~jk_EW56kCd?kq!N~TPzNhg6h&=p4iF7eJOXXxVn_>Cfa$mB z;cx!Wo!{PToSVLO2J&~x7p*=P^}F)Gzr8uuD^#-nkIMh(_CE&PAFtX!HOaiJit$<1 z9b(AYwfku-vdQXr(I)YVxb}+*4M4au=bUBk50M!k8+FuO1Af`RJxu%~EbagL9aS2a z9ogRrvicgee+u1;B8kM4L;1vkNjwI!FKYZlE8z&lKW?}`3#RyqHP0CCFp08cElNkYU~rV0q~X-^_!{%)4)RCKjx{nABAa9U0RxVW(s1ydqL{ zo+qUw%xDwB?=W#t@k4BG<1A$aYaD1~Uj}E?=N--oUm}zZ(Yl@v#ZIzm54kM3u*YAx ztWE>1y8^Y|U4>pmx^;6WQzgrIJyqX9%O!%*Z4R+3>Y z5XS=swc!OzLzf-6RIi#95?}XZv2|i?iF)#ranLaPEwO}xbGsw)DK%x22a!Do*zxhE z9DTK=rCM~J)p}w7V83_A$~d0_ad787v1|!I8*y186$v|O)|vKI`DW6HDzQpqTYT-j z*j2V>&t(0G{*deZaksCvw-o?vw&W_pP65ssph|leBH#_iXR#!I)4+8O-)^x0=~GT0 z;FX&i^d#H1!Nf%s^8-PWzvTegVCIk=M~5|hjnw^IUW(Olcs{{VIG-T=d}*)0TBBA$ z{GsHjySfdN{iN!hN5gXXdo5?})#NJsRj$l=zb`C1N!OC#eo|C1Ccu}j?o9)g#bmT(}TNW!=#G{ z!M{pJnBN@UK+AI4#_JOWm82W!dlnNLy`kmV=@6IL@bNswC>o9f^1MB%WGC+nVV>)- zyWD^0n=FRK9C5d2MW2Lsl9aOb?@d@r*4Z&@0`2La6V{~x*|C>l#>|_PdYhdzTH9{h zm*O>=qSEBwe6c;={d7d%V{z|8F;+2HBtH4z;GQgW3}Zx?ZWMzC?n{N8U7`JC_{q^M zVm+31q5SjUw=UwOX|KS#dKUYI+hfuTKjmN;80o(fPy@ou@xM6kqQv)1(U zDML!tq#)CNB-M;LhSmH>l|f*&#F_%pENyV3pr!RNI(tL*BKHMLyfF9r+;PAq9G;53 zKATAhjIOHP2rf0m6X_{APMMlcc9>4=)&z6Zl^AJp*oRn=tBaNX1X`S63abj-X(qyJ zuE7eNqTct@+&sHDbYE;-$I0yU9qO8=@2;Ia@rF-e(zeE?I}Xb=&Q1CvH%i{ z;fGCAxA3Q|>-pE+?9q!s_K)p{g_+}@t)Rl3<>$e-viP`jF6kM-I4TOX^8%)op;Kis z^20Jc0apBG z6?`7i{EDj?G5=Mu7czqy%cGnfCOyUw-W--tSiAPgZHKfS2Oc|1Np1VPo5&Oy^oGJ* z`ck<4+>0~kVwUe26vCh%r-+|mYo)$DJ)Q1{vU&c!FirJLtU=y*tXU6x`No4@lwln= z8f)bvfKyAFNjXcpYaridG>j=Kkb>STizDwY)g*7&q+{X|CE?H)nV?@zi5CY@xo5BEK1 zgtHtU^%tyd>rx%phP$9>{Z+2`hjYBLZfIf6XmZfKp1mjQ{)q^4Qm&Qq=%{Javrxyn z7)Uyy8H4m!$6!v9PQE=*R<#RAgL2}Hx~u)?2j>Rds>f+PXDcIGS3Tv+N-ogFy?n^& zQht+glHMK=3h*1Op~peE5vXP^b9JQH?2j64TPZ9J*+Am^`!Uv=HXXK=w5Jr2aWs*! z@6r)6Z5Zkeq=v`LxH6h|*-B)ju+08vut9Q)WW3xsr?8ES+p{_^#m3J8C!Qz2FmRzr zljJ^A`l=%RaZy|j9=_B`H>wU)*FVa}RfUYWV&tcm+C3$l&uAsPsyI(vZ^t4EAvUqY zZTd{+aaTQsoQ>9#qh{cV>pjX>SAFt(Fir{g8d?LyI%?qF1zf{OqlMxsnECP}aA@5{ z(kFKRw&nvgYXf2KS_Og3USy(iTq!V3zT{c;$drxC$yQAvoBLsOYbNC&j%{x!n1sH5 zn9|#v!nwT67%YyI-7i~sds0r}_IQH3^mddB)mN`HLH9x#+;qJm7gCoN=+XLqk;bbkA8dO8a9i6(JfyD5bmcA70|4#jZkGdwC*!ub?}tN-!?yB}uC72*i$5E+k(XM#6CRWQ}a(omZ6Mhfh<> zxon%u^W5M&b^#hypc~GD;#Vbx=DieviJ29#WkG66C36zwtB{x9{irb8$@5(I}6TV)p;4?Q9i&f>T8XGH#j^maw(Y+UAoByst z+PPgjL8RNw!@X?0sGrgcKC7ZVw?REs5tb|#0dLyxruh4~9DgLbp7rG&{KHvfUaej< z`$Et2SM^&vBp_7LMjS^vnyzD-;sZ=bzt{K@VJ&`y-5>K9REyY z?R3+$Ki6mz3`)Q3#U3W?q}J%9x6ypI+m0t1R#7o`!7iqJ6@JO^{Uzs#%lU?aL_V6s z}S$v&zzB)iD$BgM@U%FIrfvpuIK99yY_iyTGy!MI&YcEG~+IH zx3sJtAJ(*UFI_M)gW0)#HiJ1WmcXsmV_0J1qCNbpD$J{EU8_o_JIGK!h&_gR+&-Cx z;1NI;`Aq6H9aWKbd!JQ1oT~44;bVri+jGGyX^o%Mo=BT~b`p$3=lC*{Zw^w#Ns`ko zBl0fG1DrW!)kR#0yvA>24U258OG!yB z-Hx`joYZ+7cQ;hW;@wN>XP|bGcNUsFN#7M`5|>_7RmiO^C~rY0^(M;oE!V~UJkb^N zEjiy}KkhlXX28siHoT{Ab#0&im>w{HLt6Uc!?59CUYf7yj%h4-r-0O+<7lkLGVoJB z<;3{HyWUEJ(R)&#b$3CKwWY|ieY6E8l*~R0<#9k~BG5O>hwv6m#jbQ(s4A~d`&{Id zkQe#RkTXAKo-@SMRP8BL?aAz-=&zy$zsYEZ^=y)GX<3EaQHf!@Ld!xw`pGy)rMR@b zDcxMhcnzMtpr8K#_r;#DekY`32OjD-Fe-kZd2P$Mep zz1}UWNeryJcE$)gC7d#9bAwkk{ebO7sm^}r6-(O3E5H}ca<+~@$})#nXQ1a0cA=tD zYi6qn5)K&m=Rk1HTas9{rM3+0*@H<H>JU^qO+FrU1PaceoSg0P+)Ia85FdFo?75ZLXG3 zq8(3q=WdW+*v@fqZ~dz6(gGe@BZE+AE9G6r>rxo*nb z<2sTOv1LdNaYtfA@ds-YrZ#7>c|?$K&$7*zXU#TW7cQDfy_Gc1uCrSO{H#-s2Q1cxi$qxtel|N4WxQJz?eeHJ*0 z)wGQ~CB&c)dU3Pa23w2z+qZt?%b@J!rE~Bs>~*_yS6;*s^Yu(#(wt=vc;i(DfXFjU|gpCF$2%&92)QX?2J~5a^w2sFIVy~v#&qXtx z3gvzKvZz%-N$g}(HJ?jpY2U|gAEk|!#EmA)O9wZq%Yv+iTsu$uj(VPsW{Gx<$c|~@ zH0Wae_?GH{)Jq+UIqF%DVDj|>GG7squi6Xl_N27d!8!a+^W*5#Pc-3@awcu3uF{6$ zOATo?({$~2RJ9KAPhInTE{R=ytl?Dtom>*jl;^otY4or`?^OV=Loye^IbjxlT6?Bj z%{)XrEfNu@n_%|TLb>|!=S%bKSNFVZ6xS`>hxVX)q=h+8j9m&|EFl9G94)Sdlv-$| z?)H8vHCwyscWNg)d2u$dF)72Xftppj8Fh|~s9^7<30BdB3&s2YlrS5iXIHNnN=@9~ zSI$mAbBuM)XUOVCO*N*%`3cWAjHao`j4)3d-zelDU_)z2+iG?nJJR3$P(SDn$36EV znO4DiZp*+4o6`yn=5n>LZuSDgfYedplJ?@Shs8Uj3F5+?UMRVEc=KMwB_DRl1?jJUmuYg^gR3D_C{{TwTq~~ z5~VUJ1Aigq8RurDvY`Ijvje|nROOZ4`&FvhUr2wyFE#ad&H3Fmp#OhcVB<=lbpjQ`&cA<;g%F*k{;t@W1bz5v=mf_-om`UX|p z{H5jKzGJb@N?5gtP{K>-b{kK!*p4uK+ljJ@xfSmgOJu?32VSupv zYZm=`FW(=d=}%PW|M8~4LR?$GsIko~A-z$&j$5WgV z*VhFEG@pLk6?v+|CNc5$m7j}6oBuYP9Vwr5V>q(b6K6neJSt9>`eeF-eK$RAJ~b(= zO^-{s9^IoMfLm-dvN_wzQ3gXkAhP(0$S3#DbxJvgIo)P+d$ogU%HOg?^N3%T47 zZ{tgxh-h0Ir~;D3-YNQIJ5nBu;L!lbjfc?;Wk#=0wPL^DEblLC>2xxb_c&o4{4nnA zE9$|-E`lKtR6XZN{Q$y@RA3Llmv+hxoip;kt$%m{H{@p-xAa(<@3M49=inj@YZ|fQ zCea8zGa#w5Qa*@^8v71HBYn?nEAiVwjyGxmN$8mLveGoeo-wIZ{ zIYOj~0#2G84MOUt3uULITCRj4(VxZrG+YiU5*|jx-n{YngZ#Bt(0+anbsSE5X*)1Y z&2~ef0L_}dXkaQ&IW1E7xvgWda;-5?Rb1&sK)JsDSS?h{tXe9>e9;G<>e~-Ki8Qp$ zcT@t0q<;0kUi$71=CF&{&idh6{70K;IZqpogZ?~*YwI!t(@0a2Pj-a(lw&8yNNIJ% zleS$Muu|j5d6kl9LH0V|?t9jFB5rCMQz)b>Q#w^T)GI^qR zyl}(j`}+g6S>DXYwi@L6WU3{OKBO{f8~2qg!B#tCo!&HyI=-sLvjr&=U+2QD<64~N zo_*pUo-Vm!h%+MsmlgNt6#K zzK-42EiWs3H?U!Dv7g<$6GsB)+M7j%6sSCSy8k5F>F(l8i&Cz4UpJjS*Jazce)2Zq zGKGVcbPs+27FQ7eVv-7J6LM~xm&MZOb$9U{DeV5<|7!2LqncXQJ*bEU38GZRpnx<1 zrAm#82#APC2~t(01O!AxA_Sr$MOvOHa106x(uF7_fV9w2QBXsXASI#Kgc1m8yzTLv zd(nH(UFWU!?tAyH>mMwVH9Ir2zxihN>~DU*-v{=PA6qFO^GK=mJKUl{LYLKp!1f4n zy6MKK42QlcAVz~xuRghaG;vhacG6_;rN@E@tijdSBb}{2Z9|DyKuSZD2q0=7CV4aq z2uyPXT9N!-XpiVL_M(%BKco3+?v(sw^5MoihCBsn>ZksY=A?m<0s!mhrSSKx@97fX>D#h5}P6WSnp*>G9G%;o*lK%uZMvyvIXA!5#kiBidKS1{) z_L@=sVpCjFnlc!?BG*4SzQ0oA1SDO4rqq~Wey4cQM{IEJZUHdm7IF7%YkJOv(lU>A=_86HY-Wgli6ceI2?bUPA-sgN-%yje{+ZTmnmbb2{Q9T&^k( zwo8Py4{V>Uf(?ai!YWxb>VV@lO#Ft>-Hit)(7{q0`cppW=oOuJd*`l>0ASJps9%Dm zoi_zp&oavJe5v0@t4X_G2U3!zoS(QNwc8DCp$G&=yz86Yw0#tQu{nuRO?6~6^%ywJ zJP-6aH3CC)AcG&=MoWGWfR^P zLT|u)9l-}fGj`pOBE~&eeaFAigexXLOp^{ZtLdgxndQTlbT*++%#HF^s>svh)#cTu9*rN zunAF8%3Bo9n(J;5so|LuiL2sPn8J`QnH8R_w;L^aWp;@@+-R)l|5~E3>%^U;9w}w+ zW|O6O9R|VXMQP`OOM<;ljrSY&&5LXARDH1|8SWwmFNKII0dn~<{fg8n`sK+mp)zXo z{b#2BJe{4iq3Zg^`Ot^YP}lDFNgtAPzo=@mdkdqbmT`cyo9Y`uVrGLhA7&HJy{;Wr zs}sx=2pKNCaju9zLLByy!g}lCu2fJck=mzRk(LIHYlP-^Iu-U570P<#S1gPNVl9o} z#uY!Z2>#x8BP~YhDpw#rDNLX9Hhn%YIEP7W;Us7sG3b_fD87O;NXN=WQM&Jc$!8 z$nX>wiBun7L~WbsLfhOiLhCw+3KBOcn;o(n+VUjP^zd%=ghu&cd^tLa#>+XH6=gmJpDEbj~VQ>nc~%M|L{z^62kZd-D8R3?4}RKPq0+)4$jD znquzD`*OLDa9vv;gYozFyC&p&(KJcolI6b0E#roYe2Z>Uk~H2dHKqZW(hi70jQ|VU zIHx_Fxquv4LDDN=J^f^uhP#8p^Mkd!cP~uJ(~Ox0Aj=astu{U8*r-(l17%R%p#Em&nK1UBOfm2zi14moadS=}Y|hrJ*IAe_-aYh^H);b4Kne*Bb8z_fS{4 z!jMdWDgtZ^Pu%=j{?k4`{o}8z|IhjHZ?-AyY;110Ww?@aN}ySQP9a>$jF zZ!m4DUi%4o0vpL&a6WNXRG#Ps?4_g-4@~a2$hJ%OCU~l zt6Ri~tK6zOmM#E2O?|8Rm^`JVHmxnmqIf;ZSi;c^9Msz<2j||#-;cn!Jx?tOolQpTs?j#6E=k2W#?dfu z^mRbnCZ!t1{if#w&H5C^NTmgUi2nhHqG$0q*X=;CN)t)wSzedd;o-^bygEeoi$Vly z-7M5oL2A6KP-$=xAWlLmlQk0N)ElAECHVz!#Ev<@&a37eK5t=NzArP?GPT&evbjyu zyvQxcyVpF>93pkk|B-blBe+in=A?^#{1{gpJTV;h!dFyQ3T%I>NbOz>tE7TzaEk=$ z0bpC0yO*3y)m3&ndy4GQuZkI+h3$V~Cw=I7r36~nr2ojB6C&%+kGwp$M?0n7u+H8Q zvc*rskXp@h*yn|Mj+^*s#om3{#9pEd+0*QTPwp8VO2g(}3DlwOgxUH8XoQ)oS9h+Y zSIx|}=^$G0Fe&fsV3M*a*l0s`KU)hAYkH6$uw3jMeoJ_2; zuZd-sUAvZDmN2K}GpLaI1Q+sg)YLc8!}WG+VuQcr&?r7Ck)?+eBjQoMEK`x@3q!gQ ziTe7pdJDXd`p@c^@PT_yY^%AzCGoIst8*}^ptI4+%CE=4v#&Cz0P2|M&>!5hteexQ zte)F(#f<23!?Vz5M`_`JQC540#i7l_O|O@WR9eCesLKtHc{zd*LA|>kOR3(c8pQ6g zTJwbEIF`Kud};M~6@*9tcc&!zuU@4Y-iZ-?P+18!I%A4?V-f3mu7X}NbZO22=a&IbP_k|3Y!A6h zuuic|AZ+q!OA&f{@O9BunO&l@2Q2iu2VAhXo$=FbG7`IPwgRE*9DR$cHnF+ePU8B? z(RqEH?x=XuFQl=ExcojFn7)$td}U5hAjO{Hl@?VJPL{tYPnOQ>Ay^brycfq8d!584 zE5PwpkfPGZJh-};1uFs+T2@?cCDi@-^OFT}skfwOHj?w3>qaYTjZej~y@x2Gu(XYz z@GulVyuj{d84L&6+P_T|v8_8e3%fKbN4gxL#(wnTXqt8R8)u2R{f|R2c9RC;!s3XE z_9#6|HU{Q)BQ!L3FLT3vWBx+_0G#uP^r>8;*vV1@N84YVMG_QJ3r?OjHBPlFaOwAP zN%aeSHdBKZB_B?P!}0_7rB-8omzD!@WnD`(EmN<~8@s%XAL@X#7rZ?1EO+*4?sg=lSz+PyTTIYPhFP9VQx0rdC-&KWrROSY#_Iq*YNG=-0$1Pp-_%W0 zNRPs?6`OQqqM{cSBPs|qMfhxCwj+t0WGG)ZynD~lI^OX22rH%*qz<_qajdf{U~pnF zUUPPo=%BRY$jgUD?{qGo)@!ZI4HsUR6gUMuA(t2T|DYh< zKZ+HvIxvU-z_~?5a!k{tf2WzhRJSw=yN!gbh2{Lqef}=YgIN;+8ed2ILF@+nXLP6j z(Wa(-`&!*8@E_?;Wv$hn`sHu*T%J_8^FM|qd}s!B$O)~`{#M$BTQf-DmACe7DZyqf z^U2LqWjrPf4_xW4^fcw(q)YX@?y3cNgmr_ZRQuqE+K&w<8`ZDp z+m4QuyAZMAO!Ld!@qDiJR3Y9q*XdQ8aY6vZa+m|4OYo@@SEOtclAL_FTi2TJ(W793 ztz7qPeq174beN{`hd(1!&MKQMDGQxFc%;dA#JI%0sW;B2MRc(VI!{wsq42U-{5ZPC zYZ`@yw!EzrPO|2ctCh&pD_`~{YPpJ0VhTqlT^9O5%=rPtW@4oZ2J9Nfm+`nA|3M5~lneB>Kv%IUU zq)dj(Mjm}79b=?0UQ4q*dvwnO(w@v!E`0zDj0a+>EuKBVJN55Y+~L*6ItZ%D=&K$)^QPb-{d~}CK zO=sy)Gy5)IZ0`QjPu);_Ncr@>a_&n4dFw~r&P05voDuDdpzcEDvV6uaJ}@yiG%kH1tW~se~??3 zGfxBmHniHtDQisDinblDN$q{tV-=I4YCkitE|;&X0bZg1)~`%=z}OIhZ{v#NNy+`= zQta0_TnPaDPLKX}f0|y9g}HCubVTIe=ZC`XK$4w-*|K>|3%*aP(A7s9%8Zwm?c9he)&I$m6-PW=RB{pxBcU$Fh45&Siv}Z8^;VzHgg+`{< z3XQz%uu=JLw%iC#`HLT5K3I&AXN1gJJMh0R6MLMq*82OppQUSN|4(cD^o^f0<=d0+ zpE(yihyor}QuoGCpX8dP4D$}R5M7Ucc_s^q9J|1Ri_X-XVNtf&{+3`l2f#xdt zVK>eDXH@@q8;va(%wUpYJ!q z9d}X(jHLV1qFICNyBtN99zBSJ*-nHL9B`l9D{Ep*&XP(~Y~tjl!fW-Qy?81C$<3s< z0z#=Z?R4lnJe8ud3Ftw09&#WTU;hAEr&qNv0N|Z|U82JP-KZ_BUfC!ix6e9o1-R$o zmV)HUvVnJ;*dg&6VSj#q2kl08n@oj5%_M!HM0;ngi7yOqj(ETzgw1d7$7VrDW~*G= zw5ecD6ae?;fT@^=NK(H6us?o^0d`k-%dfO63V2Nisx4-el>uuD~H^9QWNz7Rj*4P$3r=A(Vp(#WPh<*%CyE1fa|5K4vKbJPk6z`fL$aSP zcC*ySYLSfH*a0RTS&#am9RzSh`dv)`sSr*#=0pM;W3~~%9E14>vDY;K1Vf;w;K}7X z_(hFIH>hN zLN&f0w#@Iw)I}8_&;3}}kHboIbOLyZF94DwelUtrO;TZR^9R#`Q!}gqfbolbLk!xBG??+a2f$15}vjK%sG4%OYXDcz#`@3!pDXAy&L*StX zNh>`}87GH7j3n6;z5UY`X8o}a(q>#MB>2d2O3 zGl$ox$2Oy{SKi1qm#8Y`oSJLSJ^p0f)l6+sj84(k=m5Tktqu~$4n@cZIGJUqOftbo z!`rI#Nvv@7y5Vvn&if*4UgofR5yr>b1{0R^*%}D3JwvMe%Z1f`2%Y`dKk%Q?tlhCj c8rdQ6?wa<^b@W&GEVwf-l52e0=0Hy?3m;s5{u diff --git a/docs/changelogs/v3.5.0.md b/docs/changelogs/v3.5.0.md new file mode 100644 index 000000000..03185c77f --- /dev/null +++ b/docs/changelogs/v3.5.0.md @@ -0,0 +1,117 @@ +**Feature or improvement description** +Pull request to merge `rc-3.5.0` into `main` and create a tagged release for v3.5.0. + +See the milestone and project pages for additional information + + https://github.com/OpenFAST/openfast/milestone/9 + https://github.com/orgs/OpenFAST/projects/1 + +Test results, if applicable +See GitHub Actions + +### Release checklist: +- [ ] Update the documentation version in docs/conf.py +- [ ] Update the versions in docs/source/user/api_change.rst +- [ ] Verify readthedocs builds correctly +- [ ] Create a tag in OpenFAST +- [ ] Create a merge commit in r-test and add a corresponding tag +- [ ] Compile executables for Windows builds + - [ ] FAST_SFunc.mexw64 + - [ ] OpenFAST-Simulink_x64.dll + - [ ] openfast_x64.exe + - [ ] DISCON.dll (x64) + - [ ] AeroDyn_Driver + - [ ] AeroDyn_Inflow_C_Binding + - [ ] BeamDyn_Driver + - [ ] HydroDyn_Driver + - [ ] HydroDyn_C_Binding (x64) + - [ ] InflowWind_Driver + - [ ] IfW_C_Binding (x64) + - [ ] MoorDyn_Driver + - [ ] FAST.Farm (x64) + +# Changelog + +## General + +### Build systems + +#1010 Use Cmake OBJECT libraries to create openfastlib and add option to use downloaded reference lapack and blas sources (`USE_LOCAL_STATIC_LAPACK` option in CMake) @reos-rcozier +#1427 Improve CMake's `FindMKL` to avoid rutime issues and preloading libraries @gbarter +#1506 Fix compilation issue, using Intel OneAPI on Linux (missing `-fPIC` flag) @pablo-benito +#1530 Add missing objects from #1010 +#1535 [BugFix] CMake build on Windows and Ninja build on all platforms +#1538, #1542 Add support for Flang (Classic) compiler +#1555, #1566 Modernize CMake, remove object libraries, build Simulink MEX +#1561 [BugFix] typo in souce file list for Visual Studio build of AeroDyn driver @bjonkman + +### Documentation + +#1419 update manual regression testing syntax for Windows +#1559 [BugFix] Limit urllib3 version so that readthedocs builds + + +## Solvers + +### OpenFAST + +#1453, #1560 Remove QuKi (quad-precision) from OpenFAST + +### FAST.Farm + +#1504 Increase number of VTK output planes from 9 to 99 + +### TurbSim + +#1550 [BugFix] fix index into Z array for text grid files @bjonkman + + +## Module changes + +### AeroDyn + +#1477 Allow tower, hub, nacelle, and rotor below platform for MHK turbines +#1509 Improved coning and prebend modeling in future BEM +#1541 AeroDyn_Inflow minor updates +#1567 fix some divide by zero issues + +### BeamDyn + +#1474 BeamDyn driver visualization, and driver bugfix +#1482 Fix convergence issue at initialization + +### ElastoDyn + +#1477 Allow tower, hub, nacelle, and rotor below platform for MHK turbines. + +### HydroDyn + +#1480 [BugFix] NBody>1 && NBodyMod==1 bug in WAMIT2 + +### InflowWind + +#1464 Add LIDAR simulation within InflowWind with control channels passed to controller @Russell9798 +#1534 [BugFix] potential error when requesting wind below the ground (also fix build issue with SD syntax) @bjonkman +#1516, #1543, #1549 InflowWind restructure + +### OpenFOAM + +#1493 Allow Non-Uniform Force Point Distribution on Blades @mchurchf + + +## API changes + +#1493 C++ interface for OpenFOAM module includes `NodeClusterType_c` argument + + +## Input file changes + +#1464 New section in InflowWind input file for LIDAR inputs + +Full list of changes: https://openfast.readthedocs.io/en/main/source/user/api_change.html + +Full input file sets: https://github.com/OpenFAST/r-test/tree/v3.5.0 (example input files from the regression testing) + + + + diff --git a/docs/conf.py b/docs/conf.py index 7bd700a91..04d08e201 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -28,7 +28,7 @@ sourcedir = sys.argv[-2] # Use this to turn Doxygen on or off -useDoxygen = True +useDoxygen = False # This function was adapted from https://gitlab.kitware.com/cmb/smtk # Only run when on readthedocs @@ -120,7 +120,7 @@ def runDoxygen(sourcfile, doxyfileIn, doxyfileOut): # General information about the project. project = u'OpenFAST' -copyright = u'2021, National Renewable Energy Laboratory' +copyright = u'2023, National Renewable Energy Laboratory' author = u'OpenFAST Team' # The version info for the project you're documenting, acts as replacement for @@ -128,9 +128,9 @@ def runDoxygen(sourcfile, doxyfileIn, doxyfileOut): # built documents. # # The short X.Y version. -version = u'3.2' +version = u'3.5' # The full version, including alpha/beta/rc tags. -release = u'v3.2.0' +release = u'v3.5.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -274,4 +274,24 @@ def setup(app): objname="CMake configuration value", indextemplate="pair: %s; CMake configuration" ) +# --- Prolog that will be included at the top of every rst file +# Here: defining the role :red: for html and latex +rst_prolog = r""" + +.. raw:: html + + + +.. raw:: latex + + + \makeatletter + \@ifundefined{DUrolered}{% + \newcommand{\DUrolered}[1]{{\color{red}{#1}}} + }{} + \makeatother + +.. role:: red + +""" diff --git a/docs/requirements.txt b/docs/requirements.txt index 23c91beee..0754df792 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -8,3 +8,4 @@ sphinxcontrib-doxylink>=1.3 sphinxcontrib-mermaid>=0.6 sphinx_rtd_theme>=0.3 requests[security] +urllib3<2.0.0 diff --git a/docs/source/dev/code_style.rst b/docs/source/dev/code_style.rst index eac515713..9e383738b 100644 --- a/docs/source/dev/code_style.rst +++ b/docs/source/dev/code_style.rst @@ -4,7 +4,7 @@ Code Style ~~~~~~~~~~ OpenFAST and its underlying modules are mostly written in Fortran adhering to the 2003 standard, but modules can be written in C or C++. The -`NWTC Programmer's Handbook `__ +:download:`NWTC Programmer's Handbook <../../OtherSupporting/NWTC_Programmers_Handbook.pdf>` is the definitive reference for all questions related to working with the FAST Framework and adding code to OpenFAST. diff --git a/docs/source/install/index.rst b/docs/source/install/index.rst index ec6ffcbc7..9da66481d 100644 --- a/docs/source/install/index.rst +++ b/docs/source/install/index.rst @@ -243,7 +243,7 @@ combination of the packages listed in the table below. ============================================== ==================== ================= ======= Package Applicable systems Minimum version Link ============================================== ==================== ================= ======= - CMake All 3.0 https://cmake.org + CMake All 3.12 https://cmake.org GNU Make macOS, Linux 1.8 https://www.gnu.org/software/make/ Visual Studio Windows 2015 https://visualstudio.microsoft.com> ============================================== ==================== ================= ======= @@ -600,7 +600,7 @@ on Windows systems is given below. # and build architecture. For a list of available CMake generators, run # ``cmake .. -G``. # This step creates the Visual Studio solution. - cmake .. -G "Visual Studio 14 2015 Win64" + cmake .. -G "Visual Studio 16 2019" # Open the generated Visual Studio solution start OpenFAST.sln diff --git a/docs/source/testing/index.rst b/docs/source/testing/index.rst index a8dad20a2..77fea3c21 100644 --- a/docs/source/testing/index.rst +++ b/docs/source/testing/index.rst @@ -29,8 +29,6 @@ GitHub users and is highly recommended as part of the development workflow. After enabling GitHub Actions in an OpenFAST repository, simply pushing new commits will trigger the tests. -Test specific documentation ---------------------------- .. toctree:: :maxdepth: 1 diff --git a/docs/source/testing/regression_test.rst b/docs/source/testing/regression_test.rst index 212e7dd4c..491fd0565 100644 --- a/docs/source/testing/regression_test.rst +++ b/docs/source/testing/regression_test.rst @@ -1,7 +1,7 @@ .. _regression_test: -Regression test -=============== +Regression tests +================ The regression test executes a series of test cases which intend to fully describe OpenFAST and its module's capabilities. Jump to one of the following sections for instructions on running the regression @@ -68,7 +68,7 @@ The following packages are required for regression testing: - Python 3.7+ - Numpy - CMake and CTest (Optional) -- Bokeh 1.4 (Optional) +- Bokeh 2.4+ (Optional) .. _python_driver: @@ -85,17 +85,15 @@ executing with the help option: >>>$ python manualRegressionTest.py -h usage: manualRegressionTest.py [-h] [-p [Plotting-Flag]] [-n [No-Execution]] - [-v [Verbose-Flag]] [-case [Case-Name]] - OpenFAST System-Name Compiler-Id Test-Tolerance + [-v [Verbose-Flag]] [-case [Case-Name]] [-module [Module-Name]] + Executable-Name Relative-Tolerance Absolute-Tolerance - Executes OpenFAST and a regression test for a single test case. + Executes OpenFAST or driver and a regression test for a single test case. positional arguments: - OpenFAST path to the OpenFAST executable - System-Name current system's name: [Darwin,Linux,Windows] - Compiler-Id compiler's id: [Intel,GNU] - Test-Tolerance tolerance defining pass or failure in the regression - test + Executable-Name path to the executable + Relative-Tolerance Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline. + Absolute-Tolerance Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline. optional arguments: -h, --help show this help message and exit @@ -106,6 +104,8 @@ executing with the help option: -v [Verbose-Flag], -verbose [Verbose-Flag] bool to include verbose system output -case [Case-Name] single case name to execute + -module [Module-Name], -mod [Module-Name] + name of module to execute .. note:: @@ -351,17 +351,15 @@ included Python driver. cd reg_tests python manualRegressionTest.py -h # usage: manualRegressionTest.py [-h] [-p [Plotting-Flag]] [-n [No-Execution]] - # [-v [Verbose-Flag]] [-case [Case-Name]] - # OpenFAST System-Name Compiler-Id Test-Tolerance + # [-v [Verbose-Flag]] [-case [Case-Name]] [-module [Module-Name]] + # Executable-Name Relative-Tolerance Absolute-Tolerance # - # Executes OpenFAST and a regression test for a single test case. + # Executes OpenFAST or driver and a regression test for a single test case. # # positional arguments: - # OpenFAST path to the OpenFAST executable - # System-Name current system's name: [Darwin,Linux,Windows] - # Compiler-Id compiler's id: [Intel,GNU] - # Test-Tolerance tolerance defining pass or failure in the regression - # test + # Executable-Name path to the executable + # Relative-Tolerance Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline. + # Absolute-Tolerance Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline. # # optional arguments: # -h, --help show this help message and exit @@ -372,12 +370,10 @@ included Python driver. # -v [Verbose-Flag], -verbose [Verbose-Flag] # bool to include verbose system output # -case [Case-Name] single case name to execute + # -module [Module-Name], -mod [Module-Name] + # name of module to execute - python manualRegressionTest.py \ - ..\build\bin\openfast_x64_Double.exe \ - Windows \ - Intel \ - 1e-5 + python manualRegressionTest.py ..\build\bin\openfast_x64_Double.exe 2.0 1.9 .. _reg_test_windows: diff --git a/docs/source/testing/regression_test_windows.rst b/docs/source/testing/regression_test_windows.rst index 4894e7b51..6c04bee6a 100644 --- a/docs/source/testing/regression_test_windows.rst +++ b/docs/source/testing/regression_test_windows.rst @@ -84,7 +84,7 @@ Windows with Visual Studio regression test b) Change your working directory to ``openfast\reg_tests`` - c) Type: ``python manualRegressionTest.py ..\build\bin\openfast_x64_Double.exe Windows Intel 1e-5`` + c) Type: ``python manualRegressionTest.py ..\build\bin\openfast_x64_Double.exe 2.0 1.9`` You should see this: ``executing AWT_YFix_WSt`` d) The tests will continue to execute one-by-one until you finally see something like this: diff --git a/docs/source/testing/unit_test.rst b/docs/source/testing/unit_test.rst index e8bfd3f9e..31c9cca58 100644 --- a/docs/source/testing/unit_test.rst +++ b/docs/source/testing/unit_test.rst @@ -1,7 +1,7 @@ .. _unit_test: -Unit test -========= +Unit tests +========== In a software package as dynamic and collaborative as OpenFAST, confidence in multiple layers of code is best accomplished with a strong system of unit tests. Through robust testing practices, the entire OpenFAST community can diff --git a/docs/source/this_doc.rst b/docs/source/this_doc.rst index 78b3ffa5d..2991b53fa 100644 --- a/docs/source/this_doc.rst +++ b/docs/source/this_doc.rst @@ -19,7 +19,7 @@ and link to other relevant websites. While OpenFAST developer documentation is being enhanced here, developers are encouraged to consult the legacy FAST v8 -`Programmer's Handbook `_. +:download:`NWTC Programmer's Handbook <../OtherSupporting/NWTC_Programmers_Handbook.pdf>`. Instructions on obtaining and installing OpenFAST are available in :ref:`installation`, and documentation for verifying an installation with the automated tests is at :ref:`testing`. diff --git a/docs/source/user/aerodyn-aeroacoustics/App-usage.rst b/docs/source/user/aerodyn-aeroacoustics/App-usage.rst index 303023e49..d442d1300 100644 --- a/docs/source/user/aerodyn-aeroacoustics/App-usage.rst +++ b/docs/source/user/aerodyn-aeroacoustics/App-usage.rst @@ -5,11 +5,12 @@ Using the Aeroacoustics Model in AeroDyn A live version of this documentation is available at https://openfast.readthedocs.io/. To run the aeroacoustics model, the -flag **CompAA** needs to be set to **True** at line 13 of the AeroDyn15 main +flag **CompAA** needs to be set to **True** at line 14 of the AeroDyn15 main input file in the inputs block **General Options**. When the flag is set to **True**, the following line must include the name of the file containing the inputs to the aeroacoustics model, which is discussed in -:numref:`aa-sec-BLinputs`. +:numref:`aa-sec-MainInput`. Currently, this module cannot be used with an MHK +turbine. .. container:: diff --git a/docs/source/user/aerodyn-aeroacoustics/example/AD15.ipt b/docs/source/user/aerodyn-aeroacoustics/example/AD15.ipt index 0b2e89b20..57c3752e0 100644 --- a/docs/source/user/aerodyn-aeroacoustics/example/AD15.ipt +++ b/docs/source/user/aerodyn-aeroacoustics/example/AD15.ipt @@ -2,7 +2,7 @@ IEA Wind Task 37 land-based reference wind turbine ====== General Options =================================================== False Echo - Echo the input to ".AD.ech"? (flag) -"default" DT_AA - Time interval for aerodynamic calculations {or "default"} (s) +"default" DTAero - Time interval for aerodynamic calculations {or "default"} (s) 1 WakeMod - Type of wake/induction model (switch) {0=none, 1=BEMT} 2 AFAeroMod - Type of blade airfoil aerodynamics model (switch 0 TwrPotent - Type of tower influence on wind around the tower (switch) @@ -10,9 +10,10 @@ False Echo - Echo the input to ".AD.ech"? (flag) False TwrAero - Calculate tower aerodynamic loads? (flag) False FrozenWake - Assume frozen wake during linearization? (flag False CavitCheck - Perform cavitation check? (flag) +False Buoyancy - Include buoyancy effects? (flag) True CompAA - Flag to compute AeroAcoustics calculation "AeroAcousticsInput.dat" AA_InputFile ====== Environmental Conditions ========================================== -1.225. AirDens - Air density (kg/m^3) +"default" AirDens - Air density (kg/m^3) File continues... diff --git a/docs/source/user/aerodyn-dynamicStall/examples/UA-driver.dvr b/docs/source/user/aerodyn-dynamicStall/examples/UA-driver.dvr index 1bef7307a..290e7e224 100644 --- a/docs/source/user/aerodyn-dynamicStall/examples/UA-driver.dvr +++ b/docs/source/user/aerodyn-dynamicStall/examples/UA-driver.dvr @@ -22,4 +22,7 @@ TRUE UseCm - Use Cm data in airfoil table 15.195 Mean - Cycle mean (deg) -180 Phase - Initial phase (num steps) "UA-driver-timeseries.dat" InputsFile - Time series data in an ASCII input file (whitespace-separated data). 8 header lines, followed by column data. First column is time (sec), second column is angle-of-attack (deg), third column is InflowVel (m/s) -"END" of driver input file +------------------- OUTPUT CONTROL -------------------------------------------- +True SumPrint - Write unsteady aerodynamics summary file (flag) +True WrAFITables - Write the tables of aerodynamic coefficients used internally, with extension ".Coeff.out" (flag) +END of driver input file diff --git a/docs/source/user/aerodyn-olaf/ExampleFiles/ExampleFile--OLAF.dat b/docs/source/user/aerodyn-olaf/ExampleFiles/ExampleFile--OLAF.dat index 6cc17e192..bd9d6a46d 100644 --- a/docs/source/user/aerodyn-olaf/ExampleFiles/ExampleFile--OLAF.dat +++ b/docs/source/user/aerodyn-olaf/ExampleFiles/ExampleFile--OLAF.dat @@ -1,45 +1,46 @@ --------------------------- OLAF (cOnvecting LAgrangian Filaments) INPUT FILE ----------------- Free wake input file for the Helix test case --------------------------- GENERAL OPTIONS --------------------------------------------------- -5 IntMethod Integration method {1: Runge-Kutta 4th order, 5: Forward Euler 1st order, default: 5} (switch) -0.2 DTfvw Time interval for wake propagation. {default: dtaero} (s) -default FreeWakeStart Time when wake is free. (-) value = always free. {default: 0.0} (s) -default FullCircStart Time at which full circulation is reached. {default: 0.0} (s) +default IntMethod - Integration method {1: Runge-Kutta 4th order, 5: Forward Euler 1st order, default: 5} (switch) +0.2 DTfvw - Time interval for wake propagation. {default: dtaero} (s) +default FreeWakeStart - Time when wake is free. (-) value = always free. {default: 0.0} (s) +default FullCircStart - Time at which full circulation is reached. {default: 0.0} (s) --------------------------- CIRCULATION SPECIFICATIONS ---------------------------------------- -1 CircSolvingMethod Circulation solving method {1: Cl-Based, 2: No-Flow Through, 3: Prescribed, default: 1 }(switch) -default CircSolvConvCrit Convergence criteria {default: 0.001} [only if CircSolvingMethod=1] (-) -default CircSolvRelaxation Relaxation factor {default: 0.1} [only if CircSolvingMethod=1] (-) -default CircSolvMaxIter Maximum number of iterations for circulation solving {default: 30} (-) - "NA" PrescribedCircFile File containing prescribed circulation [only if CircSolvingMethod=3] (quoted string) +default CircSolvMethod - Circulation solving method {1: Cl-Based, 2: No-Flow Through, 3: Prescribed, default: 1 }(switch) +default CircSolvConvCrit - Convergence criteria {default: 0.001} [only if CircSolvMethod=1] (-) +default CircSolvRelaxation - Relaxation factor {default: 0.1} [only if CircSolvMethod=1] (-) +default CircSolvMaxIter - Maximum number of iterations for circulation solving {default: 30} (-) +"NA" PrescribedCircFile - File containing prescribed circulation [only if CircSolvMethod=3] (quoted string) =============================================================================================== --------------------------- WAKE OPTIONS ------------------------------------------------------ ------------------- WAKE EXTENT AND DISCRETIZATION -------------------------------------------- -150 nNWPanel Number of near-wake panels [integer] (-) -400 WakeLength Total wake distance [integer] (number of time steps) -default FreeWakeLength Wake length that is free [integer] (number of time steps) {default: WakeLength} -False FWShedVorticity Include shed vorticity in the far wake {default: false} +150 nNWPanels - Number of near-wake panels (-) +default nNWPanelsFree - Number of free near-wake panels (-) {default: nNWPanels} +default nFWPanels - Number of far-wake panels (-) {default: 0} +default nFWPanelsFree - Number of free far-wake panels (-) {default: nNWPanels} +default FWShedVorticity - Include shed vorticity in the far wake {default: false} ------------------- WAKE REGULARIZATIONS AND DIFFUSION ----------------------------------------- -0 DiffusionMethod Diffusion method to account for viscous effects {0: None, 1: Core Spreading, "default": 0} -2 RegDeterMethod Method to determine the regularization parameters {0: Constant, 1: Optimized, 2: Chord-scaled, 3: dr-scaled, default: 0 } -2 RegFunction Viscous diffusion function {0: None, 1: Rankine, 2: LambOseen, 3: Vatistas, 4: Denominator, "default": 3} (switch) -3 WakeRegMethod Wake regularization method {1: Constant, 2: Stretching, 3: Age, default: 1} (switch) -0.25 WakeRegFactor Wake regularization factor (m or -) -0.25 BladeRegFactor Blade regularization factor (m or -) -1000 CoreSpreadEddyVisc Eddy viscosity in core spreading methods, typical values 1-1000 +default DiffusionMethod - Diffusion method to account for viscous effects {0: None, 1: Core Spreading, "default": 0} +2 RegDeterMethod - Method to determine the regularization parameters {0: Constant, 1: Optimized, 2: Chord-scaled, 3: dr-scaled, default: 0 } +default RegFunction - Viscous diffusion function {0: None, 1: Rankine, 2: LambOseen, 3: Vatistas, 4: Denominator, "default": 3} (switch) +default WakeRegMethod - Wake regularization method {1: Constant, 2: Stretching, 3: Age, default: 1} (switch) +0.25 WakeRegFactor - Wake regularization factor (m or -) +0.25 WingRegFactor - Wing regularization factor (m or -) +1000 CoreSpreadEddyVisc - Eddy viscosity in core spreading methods, typical values 1-1000 ------------------- WAKE TREATMENT OPTIONS --------------------------------------------------- -False TwrShadowOnWake Include tower flow disturbance effects on wake convection {default:false} [only if TwrPotent or TwrShadow] -0 ShearModel Shear Model {0: No treatment, 1: Mirrored vorticity, default: 0} +default TwrShadowOnWake - Include tower flow disturbance effects on wake convection {default:false} [only if TwrPotent or TwrShadow] +default ShearModel - Shear Model {0: No treatment, 1: Mirrored vorticity, default: 0} ------------------- SPEEDUP OPTIONS ----------------------------------------------------------- -2 VelocityMethod Method to determine the velocity {1:Biot-Savart Segment, 2:Particle tree, 3: Segment tree, default: 1} -1.5 TreeBranchFactor Branch radius fraction above which a multipole calculation is used {default: 2.0} [only if VelocityMethod=2] -1 PartPerSegment Number of particles per segment [only if VelocityMethod=2] +default VelocityMethod - Method to determine the velocity {1:Segment N^2, 2:Particle tree, 3: Particle N^2, 4: Segment Tree, default: 2} +default TreeBranchFactor - Branch radius fraction above which a multipole calculation is used {default: 1.5} [only if VelocityMethod=2,4] +default PartPerSegment - Number of particles per segment [only if VelocityMethod=2,3] =============================================================================================== --------------------------- OUTPUT OPTIONS --------------------------------------------------- -1 WrVTk Outputs Visualization Toolkit (VTK) (independent of .fst option) {0: NoVTK, 1: Write VTK at each time step} (flag) -1 nVTKBlades Number of blades for which VTK files are exported {0: No VTK per blade, n: VTK for blade 1 to n} (-) -2 VTKCoord Coordinate system used for VTK export. {1: Global, 2: Hub, "default": 1} -1 VTK_fps Frame rate for VTK output (frames per second) {"all" for all glue code timesteps, "default" for all OLAF timesteps} [used only if WrVTK=1] -0 nGridOut Number of grid outputs -GridName GridType TStart TEnd DTOut XStart XEnd nX YStart YEnd nY ZStart ZEnd nZ +default WrVTk - Outputs Visualization Toolkit (VTK) (independent of .fst option) {0: NoVTK, 1: Write VTK at each time step, default: 0} (flag) +default nVTKBlades - Number of blades for which VTK files are exported {0: No VTK per blade, n: VTK for blade 1 to n, default: 0} (-) +default VTKCoord - Coordinate system used for VTK export. {1: Global, 2: Hub, 3: Both, default: 1} +default VTK_fps - Frame rate for VTK output (frames per second) {"all" for all glue code timesteps, "default" for all OLAF timesteps} [only if WrVTK=1] +0 nGridOut - Number of grid outputs +GridName GridType TStart TEnd DTGrid XStart XEnd nX YStart YEnd nY ZStart ZEnd nZ (-) (-) (s) (s) (s) (m) (m) (-) (m) (m) (-) (m) (m) (-) ------------------------------------------------------------------------------------------------ diff --git a/docs/source/user/aerodyn-olaf/InputFiles.rst b/docs/source/user/aerodyn-olaf/InputFiles.rst index 4a05165cb..bd561525e 100644 --- a/docs/source/user/aerodyn-olaf/InputFiles.rst +++ b/docs/source/user/aerodyn-olaf/InputFiles.rst @@ -87,18 +87,48 @@ circulation file is given in :numref:`Prescribed-Circulation-Input-File`. Wake Extent and Discretization Options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -**nNWPanel** [-] specifies the number of FVW time steps (**DTfvw**) for which -the near-wake lattice is computed. In the future, this value will be defined as -an azimuthal span in degrees or a downstream distance in rotor diameter. -**WakeLength** [D] specifies the length, in rotor diameters, of the far wake. -The default value is :math:`8`. [1]_ -**FreeWakeLength** [D] specifies the length, in rotor diameters, for which the -turbine wake is convected as “free." If *FreeWakeLength* is greater than -*WakeLength*, then the entire wake is free. Otherwise, the Lagrangian markers -located within the buffer zone delimited by *FreeWakeLength* and *WakeLength* -are convected with the average velocity. The default value is :math:`6`. [2]_ +**nNWPanels** [-] specifies the number of near-wake (NW) panels (i.e. FVW time steps, **DTfvw**) used for the extent of the near-wake lattice. +See :numref:`Guidelines-OLAF` for recommendations on setting this parameter. + +**nNWPanelsFree** [-] specifies the number of near-wake panels (in FVW time steps), for which the +wake is convected as "free." +If *nNWPanelsFree* is equal to +*nNWPanels*, then the entire near wake is free. +Otherwise, the Lagrangian markers +located within the buffer zone ("frozen near wake") delimited by *nNWPanelsFree* and *nNWsPanel* +are all convected with a common and decaying induced velocity but with a varying free-stream. +(see :numref:`sec:vortconvfrozen`). +This option can be used to speed up the simulation and stabilize the end of the "near-wake" region. +It can potentially remove the need for the far wake region. +Currently, the induced velocity of the frozen near wake is arbitrarily determined as the average over +the last 20 panels of the free near wake. +The decay of the convection velocity is such that the induced velocity is about 50% at the end of the frozen near wake. +The convection velocity of the frozen wake requires additional verification and validation, and +might change in future releases. +If a "frozen" near-wake region is used then the "free" far-wake region needs to be of zero length (**nFWPanelsFree=0**) +By default, this variable is set to **nNWPanels** (no frozen wake). +See :numref:`Guidelines-OLAF` for recommendations on setting up this parameter. + +**nFWPanels** [-] specifies the number of panels (FVW time steps) used for the far wake (where the tip and root vortex are rolled-up to speed up computational time). +See :numref:`Guidelines-OLAF` for recommendations on setting this parameter. +Default value: 0. + + +**nFWPanelsFree** [-] specifies the number of far-wake panels (in FVW time steps), for which the +wake is convected as "free." +If *nFWPanelsFree* is equal to +*nFWPanels*, then the entire far-wake is free. Otherwise, the Lagrangian markers +located within the buffer zone ("frozen far wake") delimited by *nNWPanelsFree* and *nNWPanels* +are all convected with a common induced velocity but with a varying free-stream. +Currently, the induced velocity for the frozen far wake is determined as +the average over the free far-wake when **nNWPanelsFree=nNWPanels** (i.e. no frozen near wake), +or, using the same convection as the end of the frozen near wake otherwise. +By default, this variable is set to **nFWPanels**. +See :numref:`Guidelines-OLAF` for recommendations on setting up this parameter. + + **FWShedVorticity** [flag] specifies whether shed vorticity is included in the far wake. The default value is *[False]*, specifying that the far wake consists @@ -111,39 +141,39 @@ Wake Regularization and Diffusion Options for viscous diffusion. There are two options: 1) no diffusion *[0]* and 2) the core-spreading method *[1]*. The default option is *[0]*. -**RegDetMethod** [switch] specifies which method is used to determine the +**RegDeterMethod** [switch] specifies which method is used to determine the regularization parameters. There are four options: 1) constant *[0]* and 2) optimized *[1]*, 3) chord *[2]*, and 4) span *[3]*. The optimized option determines all the parameters in this section for the user. The optimized option is still work in progress and not recommended. The constant option requires the user to specify all the parameters present in this section. -The default option is *[0]*. -When **RegDetMethod==0**, the regularization parameters is set constant: +The default and recomment option is *[3]*. + .. math:: r_{c,\text{wake}}(r) = \text{WakeRegParam} ,\quad - r_{c,\text{blade}}(r) = \text{BladeRegParam} + r_{c,\text{blade}}(r) = \text{WingRegParam} -When **RegDetMethod==2**, the regularization parameters is set according to the local chord: +When **RegDeterMethod==2**, the regularization parameters is set according to the local chord: .. math:: r_{c,\text{wake}}(r) = \text{WakeRegParam} \cdot c(r) ,\quad - r_{c,,\text{blade}}(r) = \text{BladeRegParam} \cdot c(r) + r_{c,,\text{blade}}(r) = \text{WingRegParam} \cdot c(r) -When **RegDetMethod==3**, the regularization parameters is set according to the spanwise discretization: +When **RegDeterMethod==3**, the regularization parameters is set according to the spanwise discretization: .. math:: r_{c,\text{wake}}(r) = \text{WakeRegParam} \cdot \Delta r(r) ,\quad - r_{c,,\text{blade}}(r) = \text{BladeRegParam} \cdot \Delta r(r) + r_{c,,\text{blade}}(r) = \text{WingRegParam} \cdot \Delta r(r) where :math:`Delta r` is the length of the spanwise station. - +See :numref:`Guidelines-OLAF` for recommendations on setting up this parameter. @@ -151,27 +181,32 @@ where :math:`Delta r` is the length of the spanwise station. the singularity of the vortex elements, as specified in :numref:`sec:vortconv`. There are five options: 1) no correction *[0]*, 2) the Rankine method *[1]*, 3) the Lamb-Oseen method *[2]*, 4) the Vatistas -method *[3]*, and 5) the denominator offset method *[4]*. The functions are -given in . The default option is *[3]*. +method *[3]*, and 5) the denominator offset method *[4]*. +The functions are given in :numref:`sec:RegularizationFunction`. +The default option is *[3]*. **WakeRegMethod** [switch] specifies the method of determining viscous core radius (i.e., the regularization parameter). There are three options: 1) constant *[1]*, 2) stretching *[2]*, and 3) age *[3]*. The methods are -described in :numref:`sec:corerad`. The default option is *[1]*. +described in :numref:`sec:corerad`. +The default option is *[3]*. -**WakeRegParam** [m, or -] specifies the wake regularization parameter, which is the +**WakeRegFactor** [m, or -] specifies the wake regularization parameter, which is the regularization value used at the initialization of a vortex element. If the regularization method is “constant”, this value is used throughout the wake. +See :numref:`Guidelines-OLAF` for recommendations on setting up this parameter. -**BladeRegParam** [m, or -] specifies the bound vorticity regularization parameter, +**WingRegFactor** [m, or -] specifies the bound vorticity regularization parameter, which is the regularization value used for the vorticity elements bound to the blades. +See :numref:`Guidelines-OLAF` for recommendations on setting up this parameter. **CoreSpreadEddyVisc** [-] specifies the eddy viscosity parameter :math:`\delta`. The parameter is used for the core-spreading method (*DiffusionMethod* = *[1]*) and the regularization method with age (*WakeRegMethod* = *[3]*). The variable :math:`\delta` is described in -:numref:`sec:corerad`. The default value is :math:`100`. +:numref:`sec:corerad`. +The default value is :math:`100`. Wake Treatment Options ~~~~~~~~~~~~~~~~~~~~~~ @@ -200,20 +235,21 @@ There are four options: 2) Particle-Tree formulation *[2]*, 3) :math:`N^2` Biot-Savart computation using a particle representation, 4) Segment-Tree formulation. -The default option is *[1]*. Option *[2]* and *[3]* requires the specification of *PartPerSegment* (see below). Option *[4]* is expected to give results close to option *[1]* while offering significant speedup, and this option does not require the specification of *PartPerSegment*. +The default option is *[2]*. **TreeBranchFactor** [-] specifies the dimensionless distance, in branch radius, -above which a multipole calculation is used instead of a direct evaluation. This -option is only used in conjunction with the tree code -(*VelocityMethod* = *[2]*). +above which a multipole calculation is used instead of a direct evaluation. +Only used when *VelocityMethod* = *[2,4]*. +Default value: 1.5. **PartPerSegment** [-] specifies the number of particles that are used when a -vortex segment is represented by vortex particles. The default value is -:math:`1`. +vortex segment is represented by vortex particles. +Only used when *VelocityMethod* = *[2,3]*). +The default value is :math:`1`. Output Options ~~~~~~~~~~~~~~ @@ -227,19 +263,23 @@ used with `VTK_fps=0` to output only at the end of the simulation). The outputs are written in the folder, ``vtk_fvw.`` The parameters *WrVTK*, *VTKCoord*, and *VTK_fps* are independent of the glue code VTK output options. +Default value: 0. -**VTKBlades** [-] specifies how many blade VTK files are to be written out. -*VTKBlades* :math:`= n` outputs VTK files for :math:`n` blades, with :math:`0` -being an acceptable value. The default value is :math:`1`. +**nVTKBlades** [-] specifies how many blade VTK files are to be written out. +*nVTKBlades* :math:`= n` outputs VTK files for :math:`n` blades, with :math:`0` +being an acceptable value. +The default value is :math:`0`. **VTKCoord** [switch] specifies in which coordinate system the VTK files are written. There are two options: 1) global coordinate system *[1]* and 2) hub -coordinate system *[2]*. The default option is *[1]*. +coordinate system *[2]*. +The default option is *[1]*. **VTK_fps** [:math:`1`/sec] specifies the output frequency of the VTK files. The provided value is rounded to the nearest allowable multiple of the time step. -The default value is :math:`1/dt_\text{fvw}`. Specifying *VTK_fps* = *[all]*, +The default value is :math:`1/dt_\text{fvw}`. +Specifying *VTK_fps* = *[all]*, is equivalent to using the value :math:`1/dt_\text{aero}`. If *VTK_fps<0*, then no outputs are created, except if *WrVTK=2*. @@ -302,10 +342,3 @@ are used by the vortex code: - tower aerodynamics; and - outputs. -.. [1] - At present, this variable is called nFWPanel and specified as the number of far - wake panels. This will be changed soon. - -.. [2] - At present, this variable is called nFWPanelFree and specified as the number of - free far wake panels. This will be changed soon. diff --git a/docs/source/user/aerodyn-olaf/Introduction.rst b/docs/source/user/aerodyn-olaf/Introduction.rst index 00fc2b101..3a242306f 100644 --- a/docs/source/user/aerodyn-olaf/Introduction.rst +++ b/docs/source/user/aerodyn-olaf/Introduction.rst @@ -116,10 +116,12 @@ which may be different from the time step of AeroDyn. After an optional initialization period, the wake is allowed to move and distort, thus changing the wake structure as the markers are convected downstream. To limit computational expense, the root and tip vortices are truncated after a specified -distance (**WakeLength**) downstream from the turbine. The wake truncation +distance (taken as a number of panels **nNWPanels**) downstream from the turbine. +The wake truncation violates Helmholtz's first law and hence introduces an erroneous boundary condition. To alleviate this, the wake is "frozen" in a buffer zone between a -specified buffer distance, **FreeWakeLength**, and **WakeLength**. In this +specified buffer distance, **nFWPanelsFree**, and **nFWPanels**. +In this buffer zone, the markers convect at the average ambient velocity. In this way, truncation error is minimized~(:cite:`olaf-Leishman02_1`). The buffer zone is typically chosen as the convected distance over one rotor revolution. diff --git a/docs/source/user/aerodyn-olaf/OLAFTheory.rst b/docs/source/user/aerodyn-olaf/OLAFTheory.rst index 02d8f8617..7bde8f658 100644 --- a/docs/source/user/aerodyn-olaf/OLAFTheory.rst +++ b/docs/source/user/aerodyn-olaf/OLAFTheory.rst @@ -241,7 +241,7 @@ approach using the following steps: .. math:: \begin{aligned} - \Gamma_{ll,j} =\frac{1}{2} C_{l,j}(\alpha_j) \frac{\left[ (\vec{v}_j \cdot \vec{N})^2 + (\vec{v}_j \cdot \vec{T})^2\right]^2\,dA}{ + \Gamma_{ll,j} =\frac{1}{2} C_{l,j}(\alpha_j) \frac{\left[ (\vec{v}_j \cdot \vec{N})^2 + (\vec{v}_j \cdot \vec{T})^2\right]\,dA}{ \sqrt{\left[(\vec{v}_j\times \vec{dl})\cdot\vec{N}\right]^2 + \left[(\vec{v}_j\times \vec{dl})\cdot\vec{T}\right]^2} } %\label{eq:} ,\quad\text{with} @@ -278,11 +278,13 @@ approach using the following steps: No-flow-through Method ^^^^^^^^^^^^^^^^^^^^^^ -A Weissinger-L-based representation (:cite:`olaf-Weissinger47_1`) -of the lifting surface is also -available (:cite:`olaf-Bagai94_1,olaf-Gupta06_1,olaf-Ribera07_1`). In this -method, the circulation is solved by satisfying a no-flow through -condition at the 1/4-chord points. It is selected with **CircSolvMethod=[2]**. +A no-flow-through circulation solving method +(sometimes called Weissinger-L-based method) +might be implemented in the future +(:cite:`olaf-Weissinger47_1,olaf-Bagai94_1,olaf-Gupta06_1,olaf-Ribera07_1`). +In this method, the circulation is solved by satisfying a no-flow through +condition at the 1/4-chord points. +It would be selected with **CircSolvMethod=[2]** but is currently no implemented. Prescribed Circulation ^^^^^^^^^^^^^^^^^^^^^^ @@ -343,6 +345,39 @@ where :math:`d\psi/dt=\Omega` and marker, and :math:`\vec{V}[\vec{r}(\psi,\zeta)]` is the velocity. +.. _sec:vortconvfrozen: + +Frozen Vorticity Convection +--------------------------- + +For computational efficiency, the user can define "frozen" near wake and far wake zones. +In these zones, the Lagrangian markers are convected using an common induced velocity +which is independent of the radial location of the marker, and potentially a function of the wake age. +The convection equation of the Lagrangian markers in the frozen zone is: + +.. math:: + \frac{d\vec{r}_\zeta}{dt}=\vec{V}_0(\vec{r}_\zeta,t) + \vec{V}_\text{avg}(t)*k(\zeta) + +where :math:`\vec{V}_\text{avg}(t)` is an average induced velocity computed based on the convection velocity of a subset of the "free" markers. +:math:`k(\zeta)` is a decay factor between 1 and 0 based on the wake age :math:`\zeta`. +A constant decay factor of 1 would result in a uniform convection velocity across the frozen wake. +This is what is used for the far-wake. +For the near-wake, typical values are such that the decay factor is 1 at the beginning of the frozen wake, and +0.5 at the end of the frozen wake. +In fact, current verification indicated that starting at :math:`k(0)=0.75` was better, as otherwise the +average convection velocity (computed over a subset of the free markers) ended up too low, and the +frozen wake would be more condensed, leading to higher inductions at the rotor. +Clearly, the choice of the average velocity and its decay are tuning parameters that might change in future releases. +These parameters are currently not directly exposed in the input file. + +In general, convecting the whole "frozen" wake with a unique induced velocity introduces some error, but greatly reduces the computational time. +The advantage of having a "frozen" far-wake region, is that it mitigates the impact of wake truncation which is an erroneous boundary condition (vortex lines cannot end in the fluid). If the wake is truncated while still being "free", then the vorticity will rollup on itself in this region. +Another advantage is that in the absence of diffusion, the wake tends to become excessively distorted downstream, reaching limit on the validity of the vortex filament representation. + + + + + Induced Velocity and Velocity Field ----------------------------------- @@ -446,10 +481,10 @@ The regularization parameter is both a function of the physics being modeled (blade boundary layer and wake) and the choice of discretization. Contributing factors are the chord length, the boundary layer height, and the volume that each vortex filament is approximating. Currently the choice is left to the user -(**RegDetMethod=[0]**). Empirical results for a rotating blade are found in the +(**RegDeterMethod=[0]**). Empirical results for a rotating blade are found in the work of Gupta (:cite:`olaf-Gupta06_1`). As a guideline, the regularization parameter may be chosen as twice the average spanwise discretization of the blade. This -guideline is implemented when the user chooses **RegDetMethod=[1]**. Further +guideline is implemented when the user chooses **RegDeterMethod=[1]**. Further refinement of this option will be considered in the future. .. _sec:RegularizationFunction: diff --git a/docs/source/user/aerodyn-olaf/RunningOLAF.rst b/docs/source/user/aerodyn-olaf/RunningOLAF.rst index 4b49ade13..373e461a6 100644 --- a/docs/source/user/aerodyn-olaf/RunningOLAF.rst +++ b/docs/source/user/aerodyn-olaf/RunningOLAF.rst @@ -1,4 +1,3 @@ - Working with OLAF ================= @@ -17,81 +16,274 @@ available in the :ref:`installation` documentation. `OpenMP`. To do so, add the `-DOPENMP=ON` option with CMake. +.. _Guidelines-OLAF: + Guidelines ~~~~~~~~~~ -Most options of OLAF can be left to default. The results will depend on the time discretization, wake length, and regularization parameters. We provide guidelines for these parameters in this section, together with a simple python code to compute these parameters. +Most options of OLAF can be left to default. The results will depend on the time discretization, wake length, and regularization parameters. +We provide guidelines for these parameters in this section, together with a simple python code to compute these parameters. Please check this section again as we might further refine our guidelines with time. +We provide a python script at the end of the this section to programmatically set the main parameters. -**Time step and wake length** + +**Time step** We recommend to set OLAF's time step (**DTfvw**) such that it corresponds to :math:`\Delta \psi = 6` degrees of one rotor revolution: .. math:: - \Delta t + \Delta t_\text{FVW} = \frac{\Delta \psi_\text{rad}}{\Omega_\text{rad/s}} = \frac{\Delta \psi_\text{deg}}{6 \times \Omega_\text{RPM}} If the structural solver requires a smaller time step, the time step for the glue code can be set to a different value than **DTfvw** as long as **DTfvw** is a multiple of the glue code time step. -We recommend to set the near wake length to the number of time steps needed to reach two rotor revolutions. For the far wake, we recommend 10 rotor revolutions. -For the free far-wake, we recommend to set the distance to a value somewhere between 25% and 50% of the far wake length, (e.g. 3 revolutions). -The following python script computes the parameters according to these guidelines. +**Wake length and number of panels** -.. code:: +Each vortex element in the wake contributes to the induced velocity on the lifting line of the rotor. +The longer the wake, the more contributions will be present. +There is yet a trade-off to reach, as an increased wake length leads to more vortex elements, and therefore a higher computational time. - def OLAFParams(omega_rpm, deltaPsiDeg=6, nNWrot=2, nFWrot=10, nFWrotFree=3, nPerAzimuth=None): - """ - Computes recommended time step and wake length based on the rotational speed in RPM - INPUTS: - - omega_rpm: rotational speed in RPM - - deltaPsiDeg : azimuthal discretization in deg - - nNWrot : number of near wake rotations - - nFWrot : total number of far wake rotations - - nFWrotFree : number of far wake rotations that are free - - deltaPsiDeg - nPerAzimuth - 5 72 - 6 60 - 7 51.5 - 8 45 - """ - omega = omega_rpm*2*np.pi/60 - T = 2*np.pi/omega - if nPerAzimuth is not None: - dt_wanted = np.around(T/nPerAzimuth,3) - else: - dt_wanted = np.around(deltaPsiDeg/(6*omega_rpm),3) - nPerAzimuth = int(2*np.pi /(deltaPsiDeg*np.pi/180)) +If the wake consisted of a vortex cylinder of constant vorticity distribution, it can be shown that a wake length of 4D, 5D and 6D provide 99.2%, 99.5% and 99.7% of the induced velocity respectively. +We therefore recommend to have a total wake length equal to at least 4D. +As an approximation, the distance convected by the wake length is a function of the mean wind speed :math:`U_0` and the induced velocity within the wake. +The induced velocity vary with downstream distance from :math:`-aU_0` at the rotor, where :math:`a` is the average axial induction factor at the rotor, to :math:`-2aU_0` once the wake has reached equilibrium (according to momentum theory). +As an approximation, it can be assumed that the convection velocity is :math:`U_c = U_0(1-k_a a)`, with :math:`k_a\approx1.2`. +We note that viscous diffusion is not accounted for, so for a simulation without turbulence, the wake convection velocity is not expected to recover to the freestream, +and a "large" value of :math:`k_a` should be used (e.g. :math:`k_a\approx1.5`) +For a simulation with turbulence, meandering will diffuse the wake and a small value of :math:`k_a` should be used (e.g. :math:`k_a\approx1.0`). +The axial induction factor is a function of the operating condition and design of the rotor. For estimates below, we will use :math:`a\approx1/3`. +The approximate time needed for the wake to reach a desired downstream distance :math:`d_\text{target}` is therefore: + + +.. math:: + + T_\text{target} = \frac{d_\text{target}}{U_0(1-k_a a)} + +This time corresponds to a number of time steps (i.e. the total number of wake panels) equal to: + +.. math:: :label: ntargetDist + + + n_\text{target,distance} + = \frac{T_\text{target}}{\Delta t_\text{FVW}} + = \frac{d_\text{target}}{U_0(1-k_a a) \Delta t_\text{FVW}} + \approx \frac{d_\text{target}}{0.5 U_0 \Delta t_\text{FVW}} + \approx \frac{12 D}{U_0 \Delta t_\text{FVW}} + \qquad \text{(integer)} + +where the first approximation uses :math:`k_a a\approx 0.5` and the second approximation assumes a target distance of 6D. +It is also possible to define the number of near-wake panels based on a total number of revolution, :math:`n_\text{rot}`, leading to: + +.. math:: :label: ntargetRot + + n_\text{target, rotations} + = \frac{n_\text{rot} T_\text{rot}}{dt_\text{FVW}} + = \frac{n_\text{rot} 2 \pi }{\Omega dt_\text{FVW}} + = \frac{n_\text{rot} 60 }{\Omega_\text{RPM} dt_\text{FVW}} + \qquad \text{(integer)} + + +The wake of OLAF consists of two regions defined as "near wake" (NW) and "far wake" (FW), where the far consists of rolled-up tip and root vortices. +The far wake has reduced accuracy, therefore velocity profiles crossing the far wake will likely be inaccurate. +The role of the far wake is to reduce the computational time. For increased accuracy, it is recommended to use a longer near wake and a shorter far wake. +The far wake may be removed altogether. + +The near wake and far wake are further decomposed into two regions, a region where the vortex filaments are free to convect, and another one where the filaments convect with a frozen, averaged induced velocity. +The advantage of having a "frozen" wake region, is that it mitigates the impact of wake truncation which is an erroneous boundary condition (vortex lines cannot end in the fluid). If the wake is truncated while still being "free", then the vorticity will rollup in this region. +Another advantage is that in the absence of diffusion, the wake tends to become excessively distorted downstream, reaching limit on the validity of the vortex filament representation. +It is therefore useful to have a frozen far-wake region. +The total number of wake panels is equal to the number of free near-wake panels, frozen near-wake panels, free far-wake panels and frozen far-wake panels: + +.. math:: + + n_\text{target} = n_\text{NW} + n_\text{FW} = n_\text{NW,Free} + n_\text{NW,Frozen} + n_\text{FW,Free} + n_\text{FW,Frozen} - nNWPanel = nNWrot*nPerAzimuth - nFWPanel = nFWrot*nPerAzimuth - nFWPanelFree = nFWrotFree*nPerAzimuth +OLAF input file defines +:math:`n_\text{NW}` (**nNWPanels**), +:math:`n_\text{NW,Free}` (**nNWPanelsFree**), +:math:`n_\text{FW}` (**nFWPanels**), and +:math:`n_\text{FW,Free}` (**nFWPanelsFree**). - print(dt_wanted , ' DTfvw') - print(int (nNWPanel ), ' nNWPanel ') - print(int (nFWPanel ), ' WakeLength ') - print(int (nFWPanelFree), ' FreeWakeLength') +If a "frozen" near-wake region is used (:math:`n_\text{NW,Free}`_) -The factor with which the regularization parameter will increase with downstream distance can be set as -**CoreSpreadEddyVisc=1000** for modern multi-MW turbines. Further guidelines will follow for this parameter in the future. +.. code:: + + def OLAFParams(omega_rpm, U0, R, a=0.3, aScale=1.2, + deltaPsiDeg=6, nPerRot=None, + targetFreeWakeLengthD=1, + targetWakeLengthD=4., + nNWrot=8, nFWrot=0, nFWrotFree=0, + verbose=True, dt_glue_code=None): + """ + Computes recommended time step and wake length for OLAF based on: + + INPUTS: + - omega_rpm: rotational speed [RPM] + - U0: mean wind speed [m/s] + - R: rotor radius [m] + + OPTIONS FOR TIME STEP: + - either: + - deltaPsiDeg : target azimuthal discretization [deg] + or + - nPerRot : number of time step per rotations. + deltaPsiDeg - nPerRot + 5 72 + 6 60 + 7 51.5 + 8 45 + - dt_glue_code: glue code time step. If provided, the time step of OLAF will be approximated + such that it is a multiple of the glue-code time step. + + OPTIONS FOR WAKE LENGTH: + - a: average axial induction factor at the rotor [-] + - aScale: scaling factor to estimate induction, such that the wake convection velocity is: + Uc=U0(1-aScale*a) + - targetWakeLengthD: target wake length in diameter [D] + - nNWrot : minimum number of near wake rotations + - nFWrot : minimum number of far wake rotations + - nFWrotFree : minimum number of far wake rotations (free panels) + + """ + def myprint(*args, **kwargs): + if verbose: + print(*args, **kwargs) + # Rotational period + omega = omega_rpm*2*np.pi/60 + T = 2*np.pi/omega + # Convection velocity + Uc = U0 * (1-aScale*a) + + # Desired time step + if nPerRot is not None: + dt_wanted = np.around(T/nPerRot,5) + deltaPsiDeg = np.around(omega*dt_wanted*180/np.pi ,2) + else: + dt_wanted = np.around(deltaPsiDeg/(6*omega_rpm),5) + nPerRot = int(2*np.pi /(deltaPsiDeg*np.pi/180)) + + # Adapting desired time step based on glue code time step + if dt_glue_code is not None: + dt_rounded = round(dt_wanted/dt_glue_code)*dt_glue_code + deltaPsiDeg2 = np.around(omega*dt_rounded *180/np.pi ,2) + myprint('>>> To satisfy glue-code dt:') + myprint(' Rounding dt from {} to {}'.format(dt_wanted, dt_rounded )) + myprint(' Changing dpsi from {} to {}'.format(deltaPsiDeg, deltaPsiDeg2)) + dt_fvw = dt_rounded + deltaPsiDeg = deltaPsiDeg2 + nPerRot = int(2*np.pi /(deltaPsiDeg*np.pi/180)) + else: + dt_fvw = dt_wanted + + # Useful functions + n2L = lambda n: (n * dt_fvw * Uc)/(2*R) # convert number of panels to distance + n2R = lambda n: n * dt_fvw / T # convert number of panels to number of rotations + + # All Wake (AW) panels - Wake length from mean wind speed + targetWakeLength = targetWakeLengthD * 2 * R + nAWPanels_FromU0 = int(targetWakeLength / (Uc*dt_fvw)) + # Free near wake panels (based on distance) + targetFreeWakeLength = targetFreeWakeLengthD * 2 * R + nNWPanelsFree_FromU0 = int(targetFreeWakeLength / (Uc*dt_fvw)) + # Far wake (FW) panels, always from number of rotations + nFWPanels = int(nFWrot*nPerRot) + nFWPanelsFree = int(nFWrotFree*nPerRot) + # Wake length from rotational speed and number of rotations + nAWPanels_FromRot = int(nNWrot*nPerRot) # Total number of panels NW+FW + + # Below we chose between criteria on number of rotation or donwstream distance + # This can be adapted/improved + myprint('Number of panels (NW free) from wind speed and distance:{:15d}'.format(nNWPanelsFree_FromU0)) + myprint('Number of panels (NW+FW) from wind speed and distance:{:15d}'.format(nAWPanels_FromU0)) + myprint('Number of panels (NW+FW) from number of rotations :{:15d}'.format(nAWPanels_FromRot)) + myprint('Number of panels (NW+FW) from average between two :{:15d}'.format(int((nAWPanels_FromRot+nAWPanels_FromU0)/2))) + if nAWPanels_FromRot>nAWPanels_FromU0: + # Criteria based on rotation wins: + myprint('[INFO] Using number of rotations to setup number of panels') + nAWPanels = nAWPanels_FromRot # Total number of panels NW+FW + else: + myprint('[INFO] Using wind speed and distance to setup number of panels') + # Wake distance wins, we keep the nFW from rot but increase nNW + nAWPanels = nAWPanels_FromU0 # Total number of panels NW+FW + nNWPanels = nAWPanels - nFWPanels # nNW = All-Far Wake + + # See "free" near wake + nNWPanelsFree = nNWPanelsFree_FromU0 + if nNWPanelsFree>nNWPanels: + nNWPanelsFree=nNWPanels + myprint('[INFO] Capping number of free NW panels to max.') + if nNWPanelsFree0: + nFWPanelsFree=0 + myprint('[INFO] Setting number of Free FW panels to zero because a frozen near wake is used') + + # Transient time (twice the time to develop the full wake extent) + # This is the minimum recommended time before convergence of the wake is expected + # (might be quite long) + tMin = 2 * dt_fvw*nAWPanels + if verbose: + myprint('') + myprint('{:15.2f} Transient time ({:5.1f} rot)'.format(tMin, tMin/T)) + myprint('{:15d} nAWPanels ({:5.1f} rot, {:5.1f}D)'.format(nAWPanels, n2R(nAWPanels), n2L(nAWPanels))) + myprint('') + myprint('OLAF INPUT FILE:') + myprint('----------------------- GENERAL OPTIONS ---------------------') + myprint('{:15.6f} DTFVW (delta psi = {:5.1f}deg)'.format(dt_fvw, deltaPsiDeg)) + myprint('--------------- WAKE EXTENT AND DISCRETIZATION --------------') + myprint('{:15d} nNWPanels ({:5.1f} rot, {:5.1f}D)'.format(nNWPanels , n2R(nNWPanels ), n2L(nNWPanels ))) + myprint('{:15d} nNWPanelsFree ({:5.1f} rot, {:5.1f}D)'.format(nNWPanelsFree, n2R(nNWPanelsFree), n2L(nNWPanelsFree))) + myprint('{:15d} nFWPanels ({:5.1f} rot, {:5.1f}D)'.format(nFWPanels , n2R(nFWPanels ), n2L(nFWPanels ))) + myprint('{:15d} nFWPanelsFree ({:5.1f} rot, {:5.1f}D)'.format(nFWPanelsFree, n2R(nFWPanelsFree), n2L(nFWPanelsFree))) + + return dt_fvw, tMin, nNWPanels, nNWPanelsFree, nFWPanels, nFWPanelsFree diff --git a/docs/source/user/aerodyn/ADNodalOutputs.rst b/docs/source/user/aerodyn/ADNodalOutputs.rst index 075561c13..72f7686d9 100644 --- a/docs/source/user/aerodyn/ADNodalOutputs.rst +++ b/docs/source/user/aerodyn/ADNodalOutputs.rst @@ -10,7 +10,7 @@ for a complete list of possible output parameters. This section follows the `END` statement from normal Outputs section described above, and includes a separator description line followed by the following -optinos. +options. **BldNd_BladesOut** specifies the number of blades to output. Possible values are 0 through the number of blades AeroDyn is modeling. If the value is set to diff --git a/docs/source/user/aerodyn/Makefile b/docs/source/user/aerodyn/Makefile new file mode 100644 index 000000000..aed4e1476 --- /dev/null +++ b/docs/source/user/aerodyn/Makefile @@ -0,0 +1,145 @@ +# Makefile for Sphinx documentation +# +MAIN=AeroDyn +INKSCAPE=inkscape + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +CP = cp -r +CP = copy /Y + +# 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/* + +builddir: _build + +pdf: builddir latex pdf-compile +# diff +# cd _build/latex && make all-pdf + +pdf-compile: + cd _build\latex && pdflatex $(MAIN).tex +# cd _build\latex && bibtex $(MAIN).aux +# 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) -D -o "$@" "$<" + +$(SVGOUTDIR)/%.png:$(SVGDIR)/%.svg + $(INKSCAPE) -D -d 300 -o "$@" "$<" + + +html: builddir + $(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) + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex + $(CP) figs _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." + +_build: + mkdir _build + diff --git a/docs/source/user/aerodyn/appendix.rst b/docs/source/user/aerodyn/appendix.rst index 0a92e1bb0..6fd5b7f22 100644 --- a/docs/source/user/aerodyn/appendix.rst +++ b/docs/source/user/aerodyn/appendix.rst @@ -27,7 +27,7 @@ outside of OpenFAST. 3) AeroDyn Primary Input File :download:`(primary input file example) `: -The primary AeroDyn input file defines modeling options, environmental conditions (except freestream flow), airfoils, tower nodal discretization and properties, as well as output file specifications. +The primary AeroDyn input file defines modeling options, environmental conditions (except freestream flow), airfoils, tower nodal discretization and properties, tower, hub, and nacelle buoyancy properties, as well as output file specifications. The file is organized into several functional sections. Each section corresponds to an aspect of the aerodynamics model. @@ -44,23 +44,23 @@ The airfoil data input files themselves (one for each airfoil) include tables co 5) Blade Data Input File :download:`(blade data input file example) `: -The blade data input file contains the nodal discretization, geometry, twist, chord, and airfoil identifier for a blade. Separate files are used for each blade, which permits modeling of aerodynamic imbalances. +The blade data input file contains the nodal discretization, geometry, twist, chord, airfoil identifier, and buoyancy properties for a blade. Separate files are used for each blade, which permits modeling of aerodynamic imbalances. .. _ad_output_channels: AeroDyn List of Output Channels ------------------------------- -This is a list of all possible output parameters for the AeroDyn module. The names are grouped by meaning, but can be ordered in the OUTPUTS section of the AeroDyn input file as you see fit. :math:`B \alpha N \beta`, refers to output node :math:`\beta` of blade :math:`\alpha`, where :math:`\alpha` is a number in the range [1,3] and :math:`\beta` is a number in the range [1,9], corresponding to entry :math:`\beta` in the :math:`\textit{BlOutNd}` list. :math:`\textit{TwN}\beta` refers to output node :math:`\beta` of the tower and is in the range [1,9], corresponding to entry :math:`\beta` in the :math:`\textit{TwOutNd}` list. +This is a list of output parameters for the AeroDyn module. The names are grouped by meaning, but can be ordered in the OUTPUTS section of the AeroDyn input file as you see fit. :math:`B \alpha N \beta`, refers to output node :math:`\beta` of blade :math:`\alpha`, where :math:`\alpha` is a number in the range [1,3] and :math:`\beta` is a number in the range [1,9], corresponding to entry :math:`\beta` in the :math:`\textit{BlOutNd}` list. :math:`\textit{TwN}\beta` refers to output node :math:`\beta` of the tower and is in the range [1,9], corresponding to entry :math:`\beta` in the :math:`\textit{TwOutNd}` list. A comprehensive, up-to-date list of all possible output parameters is given in the Excel file :download:`OutListParameters.xlsx <../../../OtherSupporting/OutListParameters.xlsx>`. The local tower coordinate system is shown in :numref:`ad_tower_geom` and the local blade coordinate system is shown in :numref:`ad_blade_local_cs` below. Figure :numref:`ad_blade_local_cs` also shows the direction of the local angles and force components. .. _ad_blade_local_cs: -.. figure:: figs/ad_blade_local_cs.png +.. figure:: figs/aerodyn_blade_local_cs.png :width: 80% :align: center - :alt: ad_blade_local_cs.png + :alt: aerodyn_blade_local_cs.png AeroDyn Local Blade Coordinate System (Looking Toward the Tip, from the Root) – l: Lift, d: Drag, m: Pitching, x: Normal (to Plane), @@ -69,9 +69,9 @@ The local tower coordinate system is shown in :numref:`ad_tower_geom` and the lo .. _ad-output-channel: -.. figure:: figs/ad_output_channel.pdf +.. figure:: figs/aerodyn_output_channel.pdf :width: 500px :align: center - :alt: ad_output_channel.pdf + :alt: aerodyn_output_channel.pdf AeroDyn Output Channel List diff --git a/docs/source/user/aerodyn/bibliography.bib b/docs/source/user/aerodyn/bibliography.bib index 248a77a52..dc79859eb 100644 --- a/docs/source/user/aerodyn/bibliography.bib +++ b/docs/source/user/aerodyn/bibliography.bib @@ -26,6 +26,18 @@ @book{ad-Branlard:book } +@article{ad-Branlard:2022, + author = {E Branlard and B Jonkman and G R Pirrung and K Dixon and J Jonkman}, + title = {Dynamic inflow and unsteady aerodynamics models for modal and stability analyses in {OpenFAST}}, + doi = {10.1088/1742-6596/2265/3/032044}, + year = 2022, + publisher = {{IOP} Publishing}, + volume = {2265}, + number = {3}, + pages = {032044}, + journal = {Journal of Physics: Conference Series} +} + @article{ad-Hansen:book, author = {Hansen, M. O. L. and S{\o}rensen, J. N. and Voutsinas, S. and S{\o}rensen, N. and Madsen, H. Aa.}, doi = {10.1016/j.paerosci.2006.10.002}, @@ -86,3 +98,13 @@ @techreport{ad-Murray:2011 year={2011}, institution={49th AIAA Aerospace Sciences Meeting, Orlando, Florida} } + + +@article{ad-hammam2022, + author = {Mohamed M. Hammam and David H. Wood}, + title = {Aeroelastic modelling of tail fins for small wind turbines}, + year = {2022}, + journal= {Journal of Physics: Conference Series}, + volume= 1, + number=1 +} diff --git a/docs/source/user/aerodyn/conf.py b/docs/source/user/aerodyn/conf.py new file mode 100644 index 000000000..330c0dfce --- /dev/null +++ b/docs/source/user/aerodyn/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 + + +from sphinx.highlighting import PygmentsBridge +from pygments.formatters.latex import LatexFormatter + +class CustomLatexFormatter(LatexFormatter): + def __init__(self, **options): + super(CustomLatexFormatter, self).__init__(**options) + self.verboptions = r"formatcom=\footnotesize" + +PygmentsBridge.latex_formatter = CustomLatexFormatter + +#sys.path.append(os.path.abspath('_extensions/')) + +readTheDocs = os.environ.get('READTHEDOCS', None) == 'True' +sourcedir = sys.argv[-2] +builddir = sys.argv[-1] + +# -- 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'AeroDyn' +filename = project.replace(' ','_') +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'] + +# 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 = '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 = [''] + + +# -- 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, '{}.tex'.format(filename), u'{} Documentation'.format(project), + 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, project, u'{} Documentation'.format(project), + [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, filename, u'{} Documentation'.format(project), + author, project, '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") + +# --- Prolog that will be included at the top of every rst file +# Here: defining the role :red: for html and latex +rst_prolog = r""" + +.. raw:: html + + + +.. raw:: latex + + + \makeatletter + \@ifundefined{DUrolered}{% + \newcommand{\DUrolered}[1]{{\color{red}{#1}}} + }{} + \makeatother + +.. role:: red + +""" diff --git a/docs/source/user/aerodyn/driver.rst b/docs/source/user/aerodyn/driver.rst index 0c214249e..86469839f 100644 --- a/docs/source/user/aerodyn/driver.rst +++ b/docs/source/user/aerodyn/driver.rst @@ -63,7 +63,7 @@ More details are provided below, where the different sections of the input file The input file starts with a header, the user can place a relevant description of the model on the second line. The input configuration section follows. The user can toggle the flag `Echo` to write back the input file, as parsed by the driver, to disk. -The `MHK` switch allows the user to specify whether or not the turbine is an MHK turbine. `MHK=0` denotes not an MHK turbine, `MHK=1` denotes a fixed MHK turbine, and `MHK=2` denotes a floating MHK turbine. Currently, only `MHK=0` can be specified, although users can still select a cavitation check. +The `MHK` switch allows the user to specify whether or not the turbine is an MHK turbine. `MHK=0` denotes not an MHK turbine, `MHK=1` denotes a fixed MHK turbine, and `MHK=2` denotes a floating MHK turbine. The driver supports three kinds of analyses, but not all turbine formats and inflow types are available for each analysis type: - `AnalysisType=1`: Simulation of one or multiple rotors with basic (HAWT) or arbitrary geometries (HAWT/VAWT, quad-rotor, etc.), with basic or advanced wind inputs, and optional time-varying motion of the tower base, nacelle and individual pitch angles. Arbitrary motion or sinusoidal motion of the tower base are possible. @@ -91,13 +91,13 @@ An example of header and input configuration is given below: **Environmental conditions** -Environmental conditions are specified here and passed to AeroDyn. `FldDens` (equivalent to `AirDens` in the AeroDyn primary input file) specifies the fluid density and must be a value greater than zero; a typical value is around 1.225 kg/m\ :sup:`3` for air (wind turbines) and 1025 kg/m\ :sup:`3` for seawater (MHK turbines). `KinVisc` specifies the kinematic viscosity of the fluid (used in the Reynolds number calculation); a typical value is around 1.460E-5 m\ :sup:`2`/s for air (wind turbines) and 1.004E-6 m\ :sup:`2`/s for seawater (MHK turbines). `SpdSound` is the speed of sound in the fluid (used to calculate the Mach number within the unsteady airfoil aerodynamics calculations); a typical value is around 340.3 m/s for air. The next two parameters in this section are only used when `CavitCheck = TRUE` for MHK turbines. `Patm` is the atmospheric pressure above the free surface; typically around 101,325 Pa. `Pvap` is the vapor pressure of the fluid; for seawater this is typically around 2,000 Pa. `WtrDpth` is the water depth from the seabed to the mean sea level (MSL). +Environmental conditions are specified here and passed to AeroDyn. `FldDens` (equivalent to `AirDens` in the AeroDyn primary input file) specifies the fluid density and must be a value greater than zero; a typical value is around 1.225 kg/m\ :sup:`3` for air (wind turbines) and 1025 kg/m\ :sup:`3` for seawater (MHK turbines). `KinVisc` specifies the kinematic viscosity of the fluid (used in the Reynolds number calculation); a typical value is around 1.460E-5 m\ :sup:`2`/s for air (wind turbines) and 1.004E-6 m\ :sup:`2`/s for seawater (MHK turbines). `SpdSound` is the speed of sound in the fluid (used to calculate the Mach number within the unsteady airfoil aerodynamics calculations); a typical value is around 340.3 m/s for air (wind turbines) and 1500 m/s for seawater (MHK turbines). The next two parameters in this section are only used when `CavitCheck = TRUE` for MHK turbines. `Patm` is the atmospheric pressure above the free surface; typically around 101,325 Pa. `Pvap` is the vapor pressure of the fluid; for seawater this is typically around 2,000 Pa. `WtrDpth` is the water depth from the seabed to the mean sea level (MSL). **Inflow data** The inflow can be provided in two ways: -- basic (`CompInflow=0`): uniform wind with a power law shear. The wind is defined using a reference height (`RefHt`), a power law exponent (`PLExp`), and the wind speed at reference height (`HWindSpeed`). With `AnalysisType=2`, the reference wind speed and power law are defined separately as time series (see "time-dependent analysis"). With `AnalysisType=3`, these parameters are provided in a separate table (see "Combined-Case analyses"). The reference height is used for all analyses types, since this height may be different than the hub height. The wind at a given node is determined using the following equation, where :math:`Z` is the instantaneous elevation of the node above the ground for land-based wind turbines, above the mean sea level (MSL) for offshore wind turbines, or above the seabed for MHK turbines. +- basic (`CompInflow=0`): uniform wind with a power law shear. The wind is defined using a reference height (`RefHt`), a power law exponent (`PLExp`), and the wind speed at reference height (`HWindSpeed`). With `AnalysisType=2`, the reference wind speed and power law are defined separately as time series (see "time-dependent analysis"). With `AnalysisType=3`, these parameters are provided in a separate table (see "Combined-Case analyses"). The reference height is used for all analyses types, since this height may be different than the hub height. The wind at a given node is determined using the following equation, where :math:`Z` is the instantaneous elevation of the node above the ground for land-based wind turbines, above the mean sea level (MSL) for offshore wind turbines, or above the seabed for fixed and floating MHK turbines. .. math:: @@ -150,15 +150,15 @@ Two turbine input formats are supported: - basic (`BasicHAWTFormat=True`): Basic horizontal axis wind turbine (HAWT) format. In this format, the turbine geometry is entirely determined by the number of blades (`NumBlades`), the hub radius (`HubRad`), the hub height (`HubHt`), the overhang (`Overhang`), the shaft tilt (`ShftTilt`), the precone (`Precone`), and the vertical distance from the tower-top to the rotor shaft (`Twr2Shft`), as shown in :numref:`fig:BasicGeometry`. - The definition of each parameter follows the ElastoDyn convention. For example, `HubRad` specifies the radius from the center-of-rotation to the blade root along the (possibly preconed) blade-pitch axis and must be greater than zero. `HubHt` specifies the elevation of the hub center above the ground for land-based wind turbines, above the mean sea level (MSL) for offshore wind turbines, or above the seabed for MHK turbines. `Overhang` specifies the distance along the (possibly tilted) rotor shaft between the tower centerline and hub center and is positive downwind (use a negative number for upwind rotors). `ShftTilt` is the angle (in degrees) between the rotor shaft and the horizontal plane, and positive `ShftTilt` means that the downwind end of the shaft is the highest (upwind turbines have negative `ShftTilt` for improved tower clearance). `Precone` is the angle (in degrees) between a flat rotor disk and the cone swept by the blades, positive downwind (upwind turbines have negative `Precone` for improved tower clearance). + The definition of each parameter follows the ElastoDyn convention. For example, `HubRad` specifies the radius from the center-of-rotation to the blade root along the (possibly preconed) blade-pitch axis and must be greater than zero. `HubHt` specifies the elevation of the hub center above the ground for land-based wind turbines, relative to the mean sea level (MSL) for offshore wind and floating MHK turbines, or relative to the seabed for fixed MHK turbines. For floating MHK turbines with the hub positioned below the MSL, `HubHt` should be negative. `Overhang` specifies the distance along the (possibly tilted) rotor shaft between the tower centerline and hub center and is positive downwind (use a negative number for upwind rotors). `ShftTilt` is the angle (in degrees) between the rotor shaft and the horizontal plane, and positive `ShftTilt` means that the downwind end of the shaft is the highest (upwind turbines have negative `ShftTilt` for improved tower clearance). For floating MHK turbines, the sign of `ShftTilt` should be flipped to achieve an equivalent shaft tilt. For example, floating, upwind MHK turbines have positive `ShftTilt` for improved tower clearance. `Precone` is the angle (in degrees) between a flat rotor disk and the cone swept by the blades, positive downwind (upwind turbines have negative `Precone` for improved tower clearance). `Twr2Shft` is the vertical distance from the tower-top to the rotor shaft. For floating MHK turbines with the rotor below the tower-top, this value should be negative. - .. figure:: figs/ad_driver_geom.png + .. figure:: figs/aerodyn_driver_geom.png :width: 60% :name: fig:BasicGeometry Definition of basic turbine geometry. - Additionally, the user needs to provide the origin of the turbine base at `t=0` (`BaseOriginInit`). An example of basic input is given below: + Additionally, the user needs to provide the origin of the turbine base at `t=0` (`BaseOriginInit`). For fixed MHK turbines, `BaseOriginInit` is input relative to the seabed. For floating MHK turbines, `BaseOriginInit` is input relative to the MSL, and the vertical component is negative if the turbine base is below the MSL. An example of basic input is given below: .. code:: @@ -176,7 +176,7 @@ Two turbine input formats are supported: - advanced (`BasicHAWTFormat=False`): The position and orientation of the tower base, nacelle, hub, and individual blades can be arbitrarily defined. This can be used for HAWT and any other turbine concepts. The definition of the different frames are given in :numref:`fig:MultiRotor`. - The position (`BaseOriginInit`) and orientation (`BaseOrientationInit`) of the turbine base frame are defined with respect to the global frame. Orientations are given using the values of three successive rotations (x-y-z Euler angle sequence). If the base undergoes a motion, the orientation of the base frame will consist of the time-varying rotations followed by these initial rotations. + The position (`BaseOriginInit`) and orientation (`BaseOrientationInit`) of the turbine base frame are defined with respect to the global frame. The vertical component of `BaseOriginInit` is defined relative to the seabed for fixed MHK turbines and relative to the MSL for floating MHK turbines. Orientations are given using the values of three successive rotations (x-y-z Euler angle sequence). If the base undergoes a motion, the orientation of the base frame will consist of the time-varying rotations followed by these initial rotations. A flag indicating whether the turbine has a tower is given on the next line (`HasTower`). This flag currently affects the VTK outputs and does not have an impact on AeroDyn yet. The user still has to provide tower input data in AeroDyn for each turbine (see :numref:`ad_inputs_multirot`). The next line indicates which projection AeroDyn is to use in its calculation. It is recommended to use `HAWTprojection=True` for HAWT, which is the default projection used in AeroDyn (projects on the coned-pitched axis). For other rotor concepts, set `HAWTprojection=False`. @@ -185,7 +185,8 @@ Two turbine input formats are supported: The tower and the nacelle are defined with respect to the turbine base (t) origin and frame. The tower top is assumed to coincide with the nacelle origin. The tower stations defined in the AeroDyn input file are assumed to be given with respect to the tower origin, unlike OpenFAST which uses ground/MSL as a reference (see :numref:`ad_inputs_multirot`). - The hub is defined with respect to the nacelle origin and frame (n). + For floating MHK turbines, the vertical components of `TwrOrigin_t` and `NacOrigin_t` are negative if the tower origin and nacelle origin are below the turbine base. + The hub is defined with respect to the nacelle origin and frame (n). The vertical component of `HubOrigin_n` is negative for floating MHK turbines if the hub origin is below the nacelle origin (i.e., tower top). The definitions of the blades follow, starting with the number of blades `NumBlades`. A rotor with zero blades is supported and can be used to model an isolated tower. If tower shadow/potential is used in AeroDyn, then the isolated tower will disturb the flow of the vortex wake when OLAF is used. @@ -250,7 +251,7 @@ An example of inputs for a sinusoidal surge motion is given below: The different inputs for the basic and advanced geometries are given below: -- basic: The motion of a basic turbine consists of a constant nacelle yaw (`NacYaw`, positive rotation of the nacelle about the vertical tower axis, counterclockwise when looking downward), rotor speed (`RotSpeed`, positive clockwise looking downwind), and blade pitch (`BldPitch`, negative around :math:`z_b`). +- basic: The motion of a basic turbine consists of a constant nacelle yaw (`NacYaw`, positive rotation of the nacelle about the vertical tower axis, counterclockwise when looking downward), rotor speed (`RotSpeed`, positive clockwise looking downwind), and blade pitch (`BldPitch`, negative around :math:`z_b`). For floating MHK turbines, `NacYaw` should be flipped to achieve the same global yaw direction (i.e., positive rotation of the nacelle about the vertical tower axis, clockwise when looking downward). Examples are given below: .. code:: @@ -349,7 +350,7 @@ No changes are required to the AeroDyn input files when one turbine is used. To minimize the impact of the multiple-turbines implementation, the driver currently uses only one AeroDyn input file for all turbines. This means that the AeroDyn options are currently the same for all rotors. -The definition of the blade files and tower inputs needs to be adapted when more than three blades are used and more than one turbine is used. +The definition of the blade files and the tower, hub, and nacelle inputs needs to be adapted when more than three blades are used and more than one turbine is used. **Blade files** @@ -371,6 +372,29 @@ An example is given below for two turbines, the first one having 3 blades, the s "AD_Turbine2_blade2.dat" ADBlFile(5) - Name of file containing distributed aerodynamic properties for Blade #5 (-) + +**Hub and nacelle inputs** + +The sections defining the hub and nacelle buoyancy parameters must also be reproduced for each turbine. + +An example is given below for two turbines: + +.. code:: + + ====== Hub Properties ============================================================================== [used only when Buoyancy=True] + 7.0 VolHub - Hub volume (m^3) + 0.0 HubCenBx - Hub center of buoyancy x direction offset (m) + ====== Hub Properties ============================================================================== [used only when Buoyancy=True] + 5.0 VolHub - Hub volume (m^3) + 0.2 HubCenBx - Hub center of buoyancy x direction offset (m) + ====== Nacelle Properties ========================================================================== [used only when Buoyancy=True] + 32.0 VolNac - Nacelle volume (m^3) + 0.3, 0.0, 0.05 NacCenB - Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m) + ====== Nacelle Properties ========================================================================== [used only when Buoyancy=True] + 30.0 VolNac - Nacelle volume (m^3) + 0.5, 0.1, 0.05 NacCenB - Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m) + + **Aerodynamic tower inputs** The entire tower input section of AeroDyn has to be reproduced for each turbine, including turbines that are set not to have a tower (`hasTower=False`). @@ -382,21 +406,19 @@ An example is given below for two turbines: .. code:: - ====== Turbine(1) Tower Influence and Aerodynamics ================================================ [used only when TwrPotent/=0, TwrShadow=True, or TwrAero=True] - 2 NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow=True, or TwrAero=True] - TwrElev TwrDiam TwrCd TwrTI - (m) (m) (-) (-) - 0.0 2.0 1.0 0.1 - 10.0 1.0 1.0 0.1 - ====== Turbine(2) Tower Influence and Aerodynamics ================================================ [used only when TwrPotent/=0, TwrShadow=True, or TwrAero=True] - 3 NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow=True, or TwrAero=True] - TwrElev TwrDiam TwrCd TwrTI - (m) (m) (-) (-) - 0.0 4.0 1.0 0.1 - 15.0 3.0 1.0 0.1 - 30.0 2.0 1.0 0.1 - - + ====== Turbine(1) Tower Influence and Aerodynamics ================================================ [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True] + 2 NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True] + TwrElev TwrDiam TwrCd TwrTI TwrCb + (m) (m) (-) (-) (-) + 0.0 2.0 1.0 0.1 0.0 + 10.0 1.0 1.0 0.1 0.0 + ====== Turbine(2) Tower Influence and Aerodynamics ================================================ [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True] + 3 NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True] + TwrElev TwrDiam TwrCd TwrTI TwrCb + (m) (m) (-) (-) (-) + 0.0 4.0 1.0 0.1 0.0 + 15.0 3.0 1.0 0.1 0.0 + 30.0 2.0 1.0 0.1 0.0 .. _ad_inputfiles_examples: @@ -425,10 +447,18 @@ An example of an AeroDyn driver for a basic inflow, basic HAWT, and combined cas Three bladed wind turbine, using basic geometry input ----- Input Configuration --------------------------------------------------------------- False Echo - Echo input parameters to ".ech"? + 0 MHK - MHK turbine type (switch) {0: not an MHK turbine, 1: fixed MHK turbine, 2: floating MHK turbine} 3 AnalysisType - {1: multiple turbines, one simulation, 2: one turbine, one time-dependent simulation, 3: one turbine, combined cases} 11.0 TMax - Total run time [used only when AnalysisType/=3] (s) 0.5 DT - Simulation time step [used only when AnalysisType/=3] (s) "./AD.dat" AeroFile - Name of the primary AeroDyn input file + ----- Environmental Conditions ---------------------------------------------------------- + 1.225000000000000e+00 FldDens - Density of working fluid (kg/m^3) + 1.477551020408163e-05 KinVisc - Kinematic viscosity of working fluid (m^2/s) + 3.350000000000000e+02 SpdSound - Speed of sound in working fluid (m/s) + 1.035000000000000e+05 Patm - Atmospheric pressure (Pa) [used only for an MHK turbine cavitation check] + 1.700000000000000e+03 Pvap - Vapour pressure of working fluid (Pa) [used only for an MHK turbine cavitation check] + 0 WtrDpth - Water depth (m) ----- Inflow Data ----------------------------------------------------------------------- 0 CompInflow - Compute inflow wind velocities (switch) {0=Steady Wind; 1=InflowWind} "unused" InflowFile - Name of the InflowWind input file [used only when CompInflow=1] diff --git a/docs/source/user/aerodyn/examples/NodalOutputs.txt b/docs/source/user/aerodyn/examples/NodalOutputs.txt index 2e1f3ec9b..7929a50ca 100644 --- a/docs/source/user/aerodyn/examples/NodalOutputs.txt +++ b/docs/source/user/aerodyn/examples/NodalOutputs.txt @@ -54,5 +54,11 @@ END of input file (the word "END" must appear in the first 3 columns of this las "Uin" - Axial induced velocity in rotating hub coordinates. Axial aligned with hub axis. rotor plane polar hub rotating coordinates "Uit" - Tangential induced velocity in rotating hub coordinates. Tangential to the rotation plane. Perpendicular to blade aziumth. rotor plane polar hub rotating coordinates "Uir" - Radial induced velocity in rotating hub coordinates. Radial outwards in rotation plane. Aligned with blade azimuth. rotor plane polar hub rotating coordinates +"Fbn" - Buoyant force normal to chord per unit length at each node +"Fbt" - Buoyant force tangential to chord per unit length at each node +"Fbs" - Buoyant spanwise force per unit length at each node +"Mbn" - Buoyant moment normal to chord per unit length at each node +"Mbt" - Buoyant moment tangential to chord per unit length at each node +"Mbs" - Buoyant spanwise moment per unit length at each node END of input file (the word "END" must appear in the first 3 columns of this last OutList line) --------------------------------------------------------------------------------------- diff --git a/docs/source/user/aerodyn/examples/ad_blade_example.dat b/docs/source/user/aerodyn/examples/ad_blade_example.dat index 69b1ca77c..80522dec0 100644 --- a/docs/source/user/aerodyn/examples/ad_blade_example.dat +++ b/docs/source/user/aerodyn/examples/ad_blade_example.dat @@ -2,29 +2,29 @@ Description line for this file -- file corresponds to inputs in Test01_UAE_AeroDyn.dat ====== Blade Properties ================================================================= 23 NumBlNds - Number of blade nodes used in the analysis (-) - BlSpn BlCrvAC BlSwpAC BlCrvAng BlTwist BlChord BlAFID - (m) (m) (m) (deg) (deg) (m) (-) - 0.0 0.0 0.0 0.0 0.000 0.219 1 - 0.1360 0.0 0.0 0.0 0.000 0.219 1 - 0.4481 0.0 0.0 0.0 -0.098 0.181 1 - 0.8001 0.0 0.0 0.0 19.423 0.714 3 - 1.0767 0.0 0.0 0.0 14.318 0.711 4 - 1.2779 0.0 0.0 0.0 10.971 0.691 5 - 1.4958 0.0 0.0 0.0 8.244 0.668 6 - 1.7137 0.0 0.0 0.0 6.164 0.647 7 - 1.9149 0.0 0.0 0.0 4.689 0.627 7 - 2.1160 0.0 0.0 0.0 3.499 0.606 8 - 2.3340 0.0 0.0 0.0 2.478 0.584 8 - 2.5520 0.0 0.0 0.0 1.686 0.561 8 - 2.7530 0.0 0.0 0.0 1.115 0.542 8 - 2.9542 0.0 0.0 0.0 0.666 0.522 8 - 3.1721 0.0 0.0 0.0 0.267 0.499 8 - 3.3900 0.0 0.0 0.0 -0.079 0.478 8 - 3.5912 0.0 0.0 0.0 -0.381 0.457 9 - 3.7924 0.0 0.0 0.0 -0.679 0.437 9 - 3.9684 0.0 0.0 0.0 -0.933 0.419 9 - 4.1444 0.0 0.0 0.0 -1.184 0.401 10 - 4.3456 0.0 0.0 0.0 -1.466 0.381 10 - 4.5216 0.0 0.0 0.0 -1.711 0.363 10 - 4.5970 0.0 0.0 0.0 -1.711 0.363 10 + BlSpn BlCrvAC BlSwpAC BlCrvAng BlTwist BlChord BlAFID BlCb BlCenBn BlCenBt + (m) (m) (m) (deg) (deg) (m) (-) (-) (m) (m) + 0.0 0.0 0.0 0.0 0.000 0.219 1 0.0 0.0 0.0 + 0.1360 0.0 0.0 0.0 0.000 0.219 1 0.0 0.0 0.0 + 0.4481 0.0 0.0 0.0 -0.098 0.181 1 0.0 0.0 0.0 + 0.8001 0.0 0.0 0.0 19.423 0.714 3 0.0 0.0 0.0 + 1.0767 0.0 0.0 0.0 14.318 0.711 4 0.0 0.0 0.0 + 1.2779 0.0 0.0 0.0 10.971 0.691 5 0.0 0.0 0.0 + 1.4958 0.0 0.0 0.0 8.244 0.668 6 0.0 0.0 0.0 + 1.7137 0.0 0.0 0.0 6.164 0.647 7 0.0 0.0 0.0 + 1.9149 0.0 0.0 0.0 4.689 0.627 7 0.0 0.0 0.0 + 2.1160 0.0 0.0 0.0 3.499 0.606 8 0.0 0.0 0.0 + 2.3340 0.0 0.0 0.0 2.478 0.584 8 0.0 0.0 0.0 + 2.5520 0.0 0.0 0.0 1.686 0.561 8 0.0 0.0 0.0 + 2.7530 0.0 0.0 0.0 1.115 0.542 8 0.0 0.0 0.0 + 2.9542 0.0 0.0 0.0 0.666 0.522 8 0.0 0.0 0.0 + 3.1721 0.0 0.0 0.0 0.267 0.499 8 0.0 0.0 0.0 + 3.3900 0.0 0.0 0.0 -0.079 0.478 8 0.0 0.0 0.0 + 3.5912 0.0 0.0 0.0 -0.381 0.457 9 0.0 0.0 0.0 + 3.7924 0.0 0.0 0.0 -0.679 0.437 9 0.0 0.0 0.0 + 3.9684 0.0 0.0 0.0 -0.933 0.419 9 0.0 0.0 0.0 + 4.1444 0.0 0.0 0.0 -1.184 0.401 10 0.0 0.0 0.0 + 4.3456 0.0 0.0 0.0 -1.466 0.381 10 0.0 0.0 0.0 + 4.5216 0.0 0.0 0.0 -1.711 0.363 10 0.0 0.0 0.0 + 4.5970 0.0 0.0 0.0 -1.711 0.363 10 0.0 0.0 0.0 diff --git a/docs/source/user/aerodyn/examples/ad_driver_example.dvr b/docs/source/user/aerodyn/examples/ad_driver_example.dvr index d390e3856..ea92c3edd 100644 --- a/docs/source/user/aerodyn/examples/ad_driver_example.dvr +++ b/docs/source/user/aerodyn/examples/ad_driver_example.dvr @@ -34,9 +34,9 @@ False Echo - Echo input parameters to ".ech"? 3.09343 Twr2Shft(1) - Vertical distance from the tower-top to the rotor shaft (m) ----- Turbine(1) Motion [used only when AnalysisType=1] --------------------------------- 1 BaseMotionType(1) - Type of motion prescribed for this base {0: fixed, 1: Sinusoidal motion, 2: arbitrary motion} (flag) -1 DegreeOfFreedom(1) - {1:xg, 2:yg, 3:zg, 4:theta_xg, 5:theta_yg, 6:theta_zg} [used only when BaseMotionType=1] (flag) -5.0 Amplitude(1) - Amplitude of sinusoidal motion [used only when BaseMotionType=1] -0.1 Frequency(1) - Frequency of sinusoidal motion [used only when BaseMotionType=1] +1 DegreeOfFreedom(1) - {1:xt, 2:yt, 3:zt, 4:theta_xt, 5:theta_yt, 6:theta_zt} [used only when BaseMotionType=1] (flag) +5.0 Amplitude(1) - Amplitude of sinusoidal motion [used only when BaseMotionType=1] (m or rad) +0.1 Frequency(1) - Frequency of sinusoidal motion [used only when BaseMotionType=1] (Hz) "" BaseMotionFileName(1) - Filename containing arbitrary base motion (19 columns: Time, x, y, z, theta_x, ..., alpha_z) [used only when BaseMotionType=2] 0 NacYaw(1) - Yaw angle (about z_t) of the nacelle (deg) 7 RotSpeed(1) - Rotational speed of rotor in rotor coordinates (rpm) @@ -54,6 +54,7 @@ HWndSpeed PLExp RotSpd Pitch Yaw dT Tmax DOF Amplitude Frequency ----- Output Settings ------------------------------------------------------------------- "ES15.8E2" OutFmt - Format used for text tabular output, excluding the time channel. Resulting field should be 10 characters. (quoted string) 2 OutFileFmt - Format for tabular (time-marching) output file (switch) {1: text file [.out], 2: binary file [.outb], 3: both} -0 WrVTK - VTK visualization data output: (switch) {0=none; 1=animation} +0 WrVTK - VTK visualization data output: (switch) {0=none; 1=init; 2=animation} +1 WrVTK_Type - VTK visualization data type: (switch) {1=surfaces; 2=lines; 3=both} 2 VTKHubRad - HubRadius for VTK visualization (m) -1,-1,-1,2,2,2 VTKNacDim - Nacelle Dimension for VTK visualization x0,y0,z0,Lx,Ly,Lz (m) diff --git a/docs/source/user/aerodyn/examples/ad_driver_multiple.dvr b/docs/source/user/aerodyn/examples/ad_driver_multiple.dvr index 43e601ae8..00cf19887 100644 --- a/docs/source/user/aerodyn/examples/ad_driver_multiple.dvr +++ b/docs/source/user/aerodyn/examples/ad_driver_multiple.dvr @@ -46,8 +46,8 @@ True HAWTprojection(1) - True if turbine is a horizontal axis tu ----- Turbine(1) Motion [used only when AnalysisType=1] --------------------------------- 0 BaseMotionType(1) - Type of motion prescribed for this base {0: fixed, 1: Sinusoidal motion, 2: arbitrary motion} (flag) 1 DegreeOfFreedom(1) - {1:xt, 2:yt, 3:zt, 4:theta_xt, 5:theta_yt, 6:theta_zt} [used only when BaseMotionType=1] (flag) -0 Amplitude(1) - Amplitude of sinusoidal motion [used only when BaseMotionType=1] -0 Frequency(1) - Frequency of sinusoidal motion [used only when BaseMotionType=1] +0 Amplitude(1) - Amplitude of sinusoidal motion [used only when BaseMotionType=1] (m or rad) +0 Frequency(1) - Frequency of sinusoidal motion [used only when BaseMotionType=1] (Hz) "unused" BaseMotionFileName(1) - Filename containing arbitrary base motion (19 columns: Time, x, y, z, theta_x, ..., alpha_z) [used only when BaseMotionType=2] 0 NacMotionType(1) - Type of motion prescribed for the nacelle {0: fixed yaw, 1: time varying yaw angle} (flag) 0 NacYaw(1) - Yaw angle (about z_t) of the nacelle [user only when NacMotionType=0] (deg) @@ -75,8 +75,8 @@ True HAWTprojection(1) - True if turbine is a horizontal axis tu ----- Turbine(2) Motion [used only when AnalysisType=1] --------------------------------- 0 BaseMotionType(2) - Type of motion prescribed for this base {0: fixed, 1: Sinusoidal motion, 2: arbitrary motion} (flag) 0 DegreeOfFreedom(2) - {1:xt, 2:yt, 3:zt, 4:theta_xt, 5:theta_yt, 6:theta_zt} [used only when BaseMotionType=1] (flag) -0.0 Amplitude(2) - Amplitude of sinusoidal motion [used only when BaseMotionType=1] -0.0 Frequency(2) - Frequency of sinusoidal motion [used only when BaseMotionType=1] +0.0 Amplitude(2) - Amplitude of sinusoidal motion [used only when BaseMotionType=1] (m or deg) +0.0 Frequency(2) - Frequency of sinusoidal motion [used only when BaseMotionType=1] (Hz) "unused" BaseMotionFileName(2) - Filename containing arbitrary base motion (29 columns: Time, x, y, z, theta_x, ..., alpha_z) [used only when BaseMotionType=2] 0 NacYaw(2) - Yaw angle (about z_t) of the nacelle [user only when NacMotionType=0] (deg) 6 RotSpeed(2) - Rotational speed of rotor in rotor coordinates [used only when RotorMotionType=0] (rpm) @@ -86,10 +86,11 @@ True HAWTprojection(1) - True if turbine is a horizontal axis tu ----- Combined-Case Analysis [used only when AnalysisType=3, numTurbines=1] ------------- 0 NumCases - Number of cases to run HWndSpeed PLExp RotSpd Pitch Yaw dT Tmax DOF Amplitude Frequency -(m/s) (-) (rpm) (deg) (deg) (s) (s) (-) (-) (Hz) +(m/s) (-) (rpm) (deg) (deg) (s) (s) (-) (m or rad) (Hz) ----- Output Settings ------------------------------------------------------------------- "ES15.8E2" OutFmt - Format used for text tabular output, excluding the time channel. Resulting field should be 10 characters. (quoted string) 2 OutFileFmt - Format for tabular (time-marching) output file (switch) {1: text file [.out], 2: binary file [.outb], 3: both} -0 WrVTK - VTK visualization data output: (switch) {0=none; 1=animation} +0 WrVTK - VTK visualization data output: (switch) {0=none; 1=init; 2=animation} +1 WrVTK_Type - VTK visualization data type: (switch) {1=surfaces; 2=lines; 3=both} 2 VTKHubRad - HubRadius for VTK visualization (m) -7,-4,0,21,8,8 VTKNacDim - Nacelle Dimension for VTK visualization x0,y0,z0,Lx,Ly,Lz (m) diff --git a/docs/source/user/aerodyn/examples/ad_primary_example.dat b/docs/source/user/aerodyn/examples/ad_primary_example.dat index f1ebaa5d6..67a6035a3 100644 --- a/docs/source/user/aerodyn/examples/ad_primary_example.dat +++ b/docs/source/user/aerodyn/examples/ad_primary_example.dat @@ -6,12 +6,13 @@ True Echo - Echo the input to ".AD.ech"? (flag 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 of tower influence on wind based on potential flow around the tower (switch) {0=none, 1=baseline potential flow, 2=potential flow with Bak correction} - 0 TwrShadow - Type of tower influence on wind based on downstream tower shadow (switch) {0=none, 1=Powles model, 2=Eames model} + 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] -False CompAA - Flag to compute AeroAcoustics calculation [only used when WakeMod=1 or 2] -"unused" AA_InputFile - Aeroacoustics input file +False Buoyancy - Include buoyancy effects? (flag) +False CompAA - Flag to compute AeroAcoustics calculation [used only when WakeMod = 1 or 2] +"unused" AA_InputFile - AeroAcoustics input file [used only when CompAA=true] ====== Environmental Conditions =================================================================== "default" AirDens - Air density (kg/m^3) "default" KinVisc - Kinematic viscosity of working fluid (m^2/s) @@ -29,15 +30,13 @@ True TIDrag - Include the drag term in the tangential-induc 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] - 4 tau1_const - Time constant for DBEMT (s) [used only when WakeMod=2 and DBEMT_Mod=1] + 2 DBEMT_Mod - Type of dynamic BEMT (DBEMT) model {1=constant tau1, 2=time-dependent tau1, 3=constant tau1 with continuous formulation} (-) [used only when WakeMod=2] + 4 tau1_const - Time constant for DBEMT (s) [used only when WakeMod=2 and DBEMT_Mod=1 or 3] ====== OLAF -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options ================== [used only when WakeMod=3] "unused" OLAFInputFileName - Input file for OLAF [used only when WakeMod=3] ====== Beddoes-Leishman Unsteady Airfoil Aerodynamics Options ===================================== [used only when AFAeroMod=2] - 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)}, 4=HGM, 5=HGM+vortex, 6=Oye, 7=Boeing-Vertol [used only when AFAeroMod=2] + 1 UAMod - Unsteady Aero Model Switch (switch) {2=B-L Gonzalez, 3=B-L Minnema/Pierce, 4=B-L HGM 4-states, 5=B-L 5 states, 6=Oye, 7=Boeing-Vertol} [used only when AFAeroMod=2] FALSE 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] - 0.25 UAStartRad - Starting radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2; if line is missing UAStartRad=0] - 0.95 UAEndRad - Ending radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2; if line is missing UAEndRad=1] ====== Airfoil Information ========================================================================= 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} (-) 1 InCol_Alfa - The column in the airfoil tables that contains the angle of attack (-) @@ -61,15 +60,21 @@ 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/=0, or TwrAero=True] - 5 NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow/=0, or TwrAero=True] -TwrElev TwrDiam TwrCd TwrTI ! [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 +====== Hub Properties ============================================================================== [used only when Buoyancy=True] + 0.0 VolHub - Hub volume (m^3) + 0.0 HubCenBx - Hub center of buoyancy x direction offset (m) +====== Nacelle Properties ========================================================================== [used only when Buoyancy=True] + 0.0 VolNac - Nacelle volume (m^3) +0.0, 0.0, 0.0 NacCenB - Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m) +====== Tower Influence and Aerodynamics ============================================================ [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True] + 5 NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True] +TwrElev TwrDiam TwrCd TwrTI (used only with TwrShadow=2) TwrCb (used only with Buoyancy=True) +(m) (m) (-) (-) (-) +0.0000000E+00 6.0000000E+00 0.0000000E+00 1.0000000E-01 0.0 +2.0000000E+01 5.5000000E+00 0.0000000E+00 1.0000000E-01 0.0 +4.0000000E+01 5.0000000E+00 0.0000000E+00 1.0000000E-01 0.0 +6.0000000E+01 4.5000000E+00 0.0000000E+00 1.0000000E-01 0.0 +8.0000000E+01 4.0000000E+00 0.0000000E+00 1.0000000E-01 0.0 ====== 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] (-) @@ -88,7 +93,7 @@ True SumPrint - Generate a summary file listing input option "B1N1Alpha, B1N2Alpha, B1N3Alpha" "B1N1Theta, B1N2Theta, B1N3Theta" END of OutList section (the word "END" must appear in the first 3 columns of the last OutList line) -====== Outputs for all blade stations (same ending as above for B1N1.... =========================== [optional section] +====== Outputs for all blade stations (same ending as above for B1N1.... ============================ [optional section] 1 BldNd_BladesOut - Number of blades to output all node information at. Up to number of blades on turbine. (-) "All" BldNd_BlOutNd - Future feature will allow selecting a portion of the nodes to output. Not implemented yet. (-) OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) diff --git a/docs/source/user/aerodyn/figs/TailFinAirfoilCoord.png b/docs/source/user/aerodyn/figs/TailFinAirfoilCoord.png new file mode 100644 index 0000000000000000000000000000000000000000..27cb021e1503d98dd337c456e158665c11ef3409 GIT binary patch literal 71778 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 literal 0 HcmV?d00001 diff --git a/docs/source/user/aerodyn/figs/TailFinAirfoilCoord.svg b/docs/source/user/aerodyn/figs/TailFinAirfoilCoord.svg new file mode 100644 index 000000000..82e44169d --- /dev/null +++ b/docs/source/user/aerodyn/figs/TailFinAirfoilCoord.svg @@ -0,0 +1,533 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + xtf + ytf + + + + Vrel,x + Vrel,y + + L + D + + Vrel, + + + + + α + + + + + M + + + + + + + A + + xtf + ztf + + c + + diff --git a/docs/source/user/aerodyn/figs/TailFinCoord.png b/docs/source/user/aerodyn/figs/TailFinCoord.png new file mode 100644 index 0000000000000000000000000000000000000000..ddbead5aa8916f44340e6bc004cf7f21b1af2af7 GIT binary patch literal 150637 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 literal 0 HcmV?d00001 diff --git a/docs/source/user/aerodyn/figs/TailFinCoord.svg b/docs/source/user/aerodyn/figs/TailFinCoord.svg new file mode 100644 index 000000000..5fe4079ce --- /dev/null +++ b/docs/source/user/aerodyn/figs/TailFinCoord.svg @@ -0,0 +1,635 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ω + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inertial frame + tail fin frame + (t=0) + xi + yi + zi + xtf + ytf + ztf + + + + Vwind + Velast + Vind + + Vrel + Reference point + + + + + + θskew + θbank + θtilt + + diff --git a/docs/source/user/aerodyn/figs/ad_blade_geom.png b/docs/source/user/aerodyn/figs/aerodyn_blade_geom.png similarity index 100% rename from docs/source/user/aerodyn/figs/ad_blade_geom.png rename to docs/source/user/aerodyn/figs/aerodyn_blade_geom.png diff --git a/docs/source/user/aerodyn/figs/ad_blade_local_cs.png b/docs/source/user/aerodyn/figs/aerodyn_blade_local_cs.png similarity index 100% rename from docs/source/user/aerodyn/figs/ad_blade_local_cs.png rename to docs/source/user/aerodyn/figs/aerodyn_blade_local_cs.png diff --git a/docs/source/user/aerodyn/figs/ad_driver_geom.png b/docs/source/user/aerodyn/figs/aerodyn_driver_geom.png similarity index 100% rename from docs/source/user/aerodyn/figs/ad_driver_geom.png rename to docs/source/user/aerodyn/figs/aerodyn_driver_geom.png diff --git a/docs/source/user/aerodyn/figs/aerodyn_not_ad.README.txt b/docs/source/user/aerodyn/figs/aerodyn_not_ad.README.txt new file mode 100644 index 000000000..4e929b42d --- /dev/null +++ b/docs/source/user/aerodyn/figs/aerodyn_not_ad.README.txt @@ -0,0 +1,5 @@ + +The AeroDyn documentation should not reference images that are prefixed with "ad_". +This can lead to ad-blockers in browsers blocking these images. Instead, simply +use the prefix "aerodyn_". +See https://github.com/OpenFAST/openfast/issues/912 for details. diff --git a/docs/source/user/aerodyn/figs/ad_output_channel.pdf b/docs/source/user/aerodyn/figs/aerodyn_output_channel.pdf similarity index 100% rename from docs/source/user/aerodyn/figs/ad_output_channel.pdf rename to docs/source/user/aerodyn/figs/aerodyn_output_channel.pdf diff --git a/docs/source/user/aerodyn/figs/ad_tower_geom.png b/docs/source/user/aerodyn/figs/aerodyn_tower_geom.png similarity index 100% rename from docs/source/user/aerodyn/figs/ad_tower_geom.png rename to docs/source/user/aerodyn/figs/aerodyn_tower_geom.png diff --git a/docs/source/user/aerodyn/index.rst b/docs/source/user/aerodyn/index.rst index c7a08118c..9fafc5a5e 100644 --- a/docs/source/user/aerodyn/index.rst +++ b/docs/source/user/aerodyn/index.rst @@ -15,7 +15,7 @@ can be downladed from the list below. - :download:`Predicting Cavitation on Marine and Hydrokinetic Turbine Blades with AeroDyn V15.04 ` - :download:`Development Plan for the Aerodynamic Linearization of OpenFAST <../../../OtherSupporting/AeroDyn/AeroLin_2019-12.pdf>` - :download:`AeroDyn Meshes and Related Calculations <../../../OtherSupporting/AeroDyn/AeroDynMesh_Rev4.docx>` -- :download:`Calculation of Buoyancy on a Marine Hydrokinetic Turbine in AeroDyn <../../../OtherSupporting/AeroDyn/Buoyancy_Implementation_Plan_Rev3.docx>` +- :download:`Calculation of Buoyancy on a Marine Hydrokinetic Turbine in AeroDyn <../../../OtherSupporting/AeroDyn/Buoyancy_Implementation_Plan_Rev11.docx>` .. - :download:` ` @@ -32,6 +32,7 @@ The documentation here was derived from AeroDyn Manual for AeroDyn version 15.04 driver.rst theory.rst theory_ua.rst + theory_tailfin.rst zrefs.rst appendix.rst diff --git a/docs/source/user/aerodyn/input.rst b/docs/source/user/aerodyn/input.rst index a49686c45..3fe7ff7a3 100644 --- a/docs/source/user/aerodyn/input.rst +++ b/docs/source/user/aerodyn/input.rst @@ -32,7 +32,8 @@ AeroDyn Primary Input File The primary AeroDyn input file defines modeling options, environmental conditions (except freestream flow), airfoils, tower nodal -discretization and properties, as well as output file specifications. +discretization and properties, tower, hub, and nacelle buoyancy properties, +as well as output file specifications. The file is organized into several functional sections. Each section corresponds to an aspect of the aerodynamics model. A sample AeroDyn @@ -67,7 +68,7 @@ program). Set ``WakeMod`` to 0 if you want to disable rotor wake/induction effects or 1 to include these effects using the (quasi-steady) BEM theory model. When ``WakeMod`` is set to 2, a dynamic BEM theory model (DBEMT) is used (also -referred to as dynamic inflow or dynamic wake model). When ``WakeMod`` is set +referred to as dynamic inflow or dynamic wake model, see :numref:`AD_DBEMT`). When ``WakeMod`` is set to 3, the free vortex wake model is used, also referred to as OLAF (see :numref:`OLAF`). ``WakeMod`` cannot be set to 2 or 3 during linearization analyses. @@ -101,11 +102,19 @@ recalculate the induction during linearization using BEM theory. Set the ``CavitCheck`` flag to TRUE to perform a cavitation check for MHK turbines or FALSE to disable this calculation. If ``CavitCheck`` is TRUE, ``AFAeroMod`` must be set to 1 because the cavitation check does -not function with unsteady airfoil aerodynamics. +not function with unsteady airfoil aerodynamics. If ``CavitCheck`` is +TRUE, the ``MHK`` flag in the AeroDyn or OpenFAST driver input file must be set +to 1 or 2 to indicate an MHK turbine is being modeled. + +Set the ``Buoyancy`` flag to TRUE to calculate buoyant loads on the blades, +tower, nacelle, and hub of an MHK turbine or FALSE to disable this calculation. +If ``Buoyancy`` is TRUE, the ``MHK`` flag in the AeroDyn or OpenFAST driver +input file must be set to 1 or 2 to indicate an MHK turbine is being modeled. Set the ``CompAA`` flag to TRUE to run aero-acoustic calculations. This -option is only available for ``WakeMod = 1`` or ``2``. See section -:numref:`AeroAcoustics` for information on how to use this feature. +option is only available for ``WakeMod = 1`` or ``2`` and is not available for +an MHK turbine. See section :numref:`AeroAcoustics` for information on how to +use this feature. The ``AA_InputFile`` is used to specify the input file for the aeroacoustics sub-module. See :numref:`AeroAcoustics` for information on how to use this @@ -127,7 +136,8 @@ Reynolds number calculation); a typical value is around 1.460E-5 m\ :sup:`2`/s for air (wind turbines) and 1.004E-6 m\ :sup:`2`/s for seawater (MHK turbines). ``SpdSound`` is the speed of sound in the fluid (used to calculate the Mach number within the unsteady airfoil -aerodynamics calculations); a typical value is around 340.3 m/s for air. The +aerodynamics calculations); a typical value is around 340.3 m/s for air (wind +turbines) and 1500 m/s for seawater (MHK turbines). The last two parameters in this section are only used when ``CavitCheck = TRUE`` for MHK turbines. ``Patm`` is the atmospheric pressure above the free surface; typically around 101,325 Pa. ``Pvap`` @@ -179,13 +189,20 @@ Dynamic Blade-Element/Momentum Theory Options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The input parameters in this section are used only when ``WakeMod = 2``. +The theory is described in :numref:`AD_DBEMT`. + +There are three options available for ``DBEMT_Mod``: + +- ``1``: discrete-time Oye's model, with constant :math:`\tau_1` +- ``2``: discrete-time Oye's model, with varying :math:`\tau_1`, automatically adjusted based on inflow. (recommended for time-domain simulations) +- ``3``: continuous-time Oye's model, with constant :math:`\tau_1` (recommended for linearization) + +For ``DBEMT_Mod=1`` or ``DBEMT_Mod=3`` it is the user responsability to set the value of :math:`\tau_1` (i.e. ``tau1_const``) according to the expression given in :numref:`AD_DBEMT`, using an estimate of what the mean axial induction (:math:`\overline{a}`) and the mean relative wind velocity across the rotor (:math:`\overline{U_0}`) are for a given simulation. + +The option ``DBEMT_Mod=3`` is the only one that can be used for linearization. + -Set ``DBEMT_Mod`` to 1 for the constant-tau1 model, set ``DBEMT_Mod`` to 2 -to use a model where tau1 varies with time, or set ``DBEMT_Mod`` to 3 -to use a continuous-state model with constant tau1. -If ``DBEMT_Mod=1`` (constant-tau1 model) or ``DBEMT_Mod=3`` (continuous-state constant-tau1 model), -set ``tau1_const`` to the time constant to use for DBEMT. OLAF -- cOnvecting LAgrangian Filaments (Free Vortex Wake) Theory Options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -207,15 +224,15 @@ The input parameters in this section are used only when ``AFAeroMod ``UAMod`` determines the UA model. It has the following options: -- ``1``: the original theoretical developments of B-L (**not currently functional**), -- ``2``: the extensions to B-L developed by González -- ``3``: the extensions to B-L developed by Minnema/Pierce -- ``4``: a continuous-state model developed by Hansen, Gaunna, and Madsen (HGM) -- ``5``: a model similar to HGM with an additional state for vortex generation -- ``6``: Oye's dynamic stall model -- ``7``: Boeing-Vertol model +- ``1``: the discrete-time model of Beddoes-Leishman (B-L) (**not currently functional**), +- ``2``: the extensions to B-L developed by González (changes in Cn, Cc, Cm) +- ``3``: the extensions to B-L developed by Minnema/Pierce (changes in Cc and Cm) +- ``4``: 4-states continuous-time B-L model developed by Hansen, Gaunna, and Madsen (HGM). NOTE: might require smaller time steps until a stiff integrator is implemented. +- ``5``: 5-states continuous-time B-L model similar to HGM with an additional state for vortex generation +- ``6``: 1-state continuous-time developed by Oye +- ``7``: discrete-time Boeing-Vertol (BV) model -The models are described in :numref:`AD_UA`. +Linearization is supported with ``UAMod=4,5,6`` (which use continuous-time states) but not with the other models. The different models are described in :numref:`AD_UA`. **While all of the UA models are documented in this @@ -297,22 +314,65 @@ airfoil aerodynamics or FALSE to neglect them; if ``UseBlCm = TRUE``, pitching-moment coefficient data must be included in the airfoil data tables with ``InCol_Cm`` not equal to zero. -The blade nodal discretization, geometry, twist, chord, and airfoil -identifier are set in separate input files for each blade, described in -:numref:`blade_data_input_file`. ``ADBlFile(1)`` is the filename for blade 1, -``ADBlFile(2)`` is the filename for blade 2, and ``ADBlFile(3)`` is -the filename for blade 3, respectively; the latter is not used for -two-bladed rotors and the latter two are not used for one-bladed rotors. -The file names should be in quotations and can contain an absolute path +The blade nodal discretization, geometry, twist, chord, airfoil +identifier, and buoyancy properties are set in separate input files for each +blade, described in :numref:`blade_data_input_file`. ``ADBlFile(1)`` is the +filename for blade 1, ``ADBlFile(2)`` is the filename for blade 2, and +``ADBlFile(3)`` is the filename for blade 3, respectively; the latter is not +used for two-bladed rotors and the latter two are not used for one-bladed +rotors. The file names should be in quotations and can contain an absolute path or a relative path. The data in each file need not be identical, which permits modeling of aerodynamic imbalances. +Hub Properties +~~~~~~~~~~~~~~ +The input parameters in this section pertain to the calculation of buoyant loads +on the hub and are only used when ``Buoyancy = TRUE``. + +``VolHub`` is the volume of the hub and ``HubCenBx`` is the x offset of the hub +center of buoyancy from the hub center in local hub coordinates; +offsets in the y and z directions are assumed to be zero. To neglect buoyant +loads on the hub, set ``VolHub`` to 0. + +Since the hub and blades are joined elements, hub buoyancy should be turned on if blade buoyancy is on, and vice versa. + +Nacelle Properties +~~~~~~~~~~~~~~~~~~ +The input parameters in this section pertain to the calculation of buoyant loads +on the nacelle and are only used when ``Buoyancy = TRUE``. + +``VolNac`` is the volume of the nacelle and ``NacCenB``` is the +position (x,y,z vector) of the nacelle center of buoyancy from +the yaw bearing in local nacelle coordinates. To neglect buoyant +loads on the nacelle, set ``VolNac`` to 0. + +Tail fin AeroDynamics +~~~~~~~~~~~~~~~~~~~~~ + +The tail fin aerodynamics section contains two lines: + +.. code:: + + ====== Tail fin AeroDynamics ======================================================================== + true TFinAero - Calculate tail fin aerodynamics model (flag) + "" TFinFile - Input file for tail fin aerodynamics [used only when TFinAero=True] + ====== Tower Influence and Aerodynamics ============================================================= + +**TFinAero** Flag to activate the tail fin aerodynamics calculation. + +**TFinFile** Path (absolute or relative to the AeroDyn input file) where the +tail fin input file is located. + +The content of the tail fin input file is described in :numref:`TF_tf_input-file`. + + + 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`` > 0, or ``TwrAero = TRUE``. +The input parameters in this section pertain to the tower influence, tower drag, +and/or tower buoyancy calculations and are only used when ``TwrPotent`` > +0, ``TwrShadow`` > 0, ``TwrAero = TRUE``, or ``Buoyancy = TRUE``. ``NumTwrNds`` is the user-specified number of tower analysis nodes and determines the number of rows in the subsequent table (after two table @@ -320,20 +380,25 @@ header lines). ``NumTwrNds`` must be greater than or equal to two; the higher the number, the finer the resolution and longer the computational 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), +specifies the local elevation of the tower node above ground (or relative +to MSL for offshore wind and floating MHK turbines or relative to the seabed for fixed MHK turbines), ``TwrDiam`` specifies the local tower diameter, ``TwrCd`` specifies the -local tower drag-force coefficient, and ``TwrTI`` specifies the +local tower drag-force coefficient, ``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 interpreted carefully, but the code -will allow such values for scientific investigation purposes. -See :numref:`ad_tower_geom`. - +wind fluctuation, and ``TwrCb`` specifies the tower buoyancy coefficient. +``TwrElev`` must be entered in monotonically increasing order—from the lowest +(tower-base) to the highest (tower-top) elevation. For floating MHK turbines with +the tower below MSL, tower nodes should be entered as increasingly negative values, +from the tower-base (closest to the platform) to the tower-top (closest to the nacelle). +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 interpreted carefully, but the code +will allow such values for scientific investigation purposes. ``TwrCb`` is +defined at each node as the cross-sectional area of the tower divided by the +area of a circle with diameter equal to the characteristic length of the tower +cross section (i.e., ``TwrDiam``). For towers with circular cross-sections, +``TwrCb`` will likely be 1.0 at each node. To neglect buoyant loads on the +tower, set ``TwrCb`` to 0. See :numref:`ad_tower_geom`. .. _AD-Outputs: @@ -371,10 +436,10 @@ quantities are actually output at these nodes. .. _ad_tower_geom: -.. figure:: figs/ad_tower_geom.png +.. figure:: figs/aerodyn_tower_geom.png :width: 60% :align: center - :alt: ad_tower_geom.png + :alt: aerodyn_tower_geom.png AeroDyn Tower Geometry @@ -404,6 +469,39 @@ complete list of possible output parameters. .. include:: ADNodalOutputs.rst +Tail fin outputs +~~~~~~~~~~~~~~~~ + +The tail fin outputs are: + + - TFinAlpha (deg): Angle of attack at the reference point of the fin + - TFinDynP (Pa): Dynamic pressure at the reference point of the fin + - TFinM (-): Mach number at the reference point of the fin + - TFinRe (-): Reynolds number at the reference point of the fin + - TFinVrel (m/s): Orthogonal relative velocity norm (:math:`V_{\text{rel},\perp}`) at the reference point of the fin + - TFinVdisxi (m/s): Disturbed velocity (x) at the reference point of the fin in the inertial coordinate system + - TFinVdisyi (m/s): Disturbed velocity (y) at the reference point of the fin in the inertial coordinate system + - TFinVdiszi (m/s): Disturbed velocity (z) at the reference point of the fin in the inertial coordinate system + - TFinVrelxi (m/s): Relative velocity (x) at the reference point of the fin in the inertial coordinate system + - TFinVrelyi (m/s): Relative velocity (y) at the reference point of the fin in the inertial coordinate system + - TFinVrelzi (m/s): Relative velocity (z) at the reference point of the fin in the inertial coordinate system + - TFinVundxi (m/s): Undisturbed velocity (x) at the reference point of the fin in the inertial coordinate system + - TFinVundyi (m/s): Undisturbed velocity (y) at the reference point of the fin in the inertial coordinate system + - TFinVundzi (m/s): Undisturbed velocity (z) at the reference point of the fin in the inertial coordinate system + - TFinSTVxi (m/s): Structural velocity (x) at the reference point of the fin in the inertial coordinate system + - TFinSTVyi (m/s): Structural velocity (y) at the reference point of the fin in the inertial coordinate system + - TFinSTVzi (m/s): Structural velocity (z) at the reference point of the fin in the inertial coordinate system + - TFinFxi (N) : Aerodynamic force (x) at the reference point of the fin in the inertial coordinate system + - TFinFyi (N) : Aerodynamic force (y) at the reference point of the fin in the inertial coordinate system + - TFinFzi (N) : Aerodynamic force (z) at the reference point of the fin in the inertial coordinate system + - TFinMxi (Nm): Aerodynamic moment (x) at the reference point of the fin in the inertial coordinate system + - TFinMyi (Nm): Aerodynamic moment (y) at the reference point of the fin in the inertial coordinate system + - TFinMzi (Nm): Aerodynamic moment (z) at the reference point of the fin in the inertial coordinate system + + + + + .. _airfoil_data_input_file: Airfoil Data Input File @@ -501,6 +599,9 @@ or calculating it based on the polar coefficient data in the airfoil table: - ``C_nalpha`` is the slope of the 2D normal force coefficient curve in the linear region; +- ``C_lalpha`` is the slope of the 2D normal lift coefficient curve + in the linear region; Used for ``UAMod=4,6``. + - ``T_f0`` is the initial value of the time constant associated with *Df* in the expressions of *Df* and *f’*; if the keyword ``DEFAULT`` is entered in place of a numerical value, ``T_f0`` is set to 3.0; @@ -681,9 +782,9 @@ Blade Data Input File --------------------- The blade data input file contains the nodal discretization, geometry, -twist, chord, and airfoil identifier for a blade. Separate files are -used for each blade, which permits modeling of aerodynamic imbalances. A -sample blade data input file is given in :numref:`ad_appendix`. +twist, chord, airfoil identifier, and buoyancy properties for a blade. Separate +files are used for each blade, which permits modeling of aerodynamic imbalances. +A sample blade data input file is given in :numref:`ad_appendix`. The input file begins with two lines of header information which is for your use, but is not used by the software. @@ -728,22 +829,123 @@ nodes. For each node: feather, leading edge upwind; the blade-pitch angle will be added to the local twist; -- ``BlChord`` specifies the local chord length; and +- ``BlChord`` specifies the local chord length; - ``BlAFID`` specifies which airfoil data the local blade node is associated with; valid values are numbers between 1 and ``NumAFfiles`` (corresponding to a row number in the airfoil file table in the AeroDyn primary input file); multiple blade nodes can - use the same airfoil data. + use the same airfoil data; + +- ``BlCb`` specifies the blade buoyancy coefficient, defined as the local + cross-sectional area of the blade divided by the area of a circle with + diameter equal to ``BlChord``; to neglect buoyant loads on the blade, + set ``BlCb`` to 0; since the blades and hub are joined elements, blade buoyancy should be turned on if hub buoyancy is on, and vice versa; + +- ``BlCenBn`` specifies the offset of the blade center of buoyancy from the + aerodynamic center in the direction normal to the chord (positive pointing + toward the suction side of the blade); and + +- ``BlCenBt`` specifies the offset of the blade center of buoyancy from the + aerodynamic center in the direction tangential to the chord + (positive pointing toward the trailing edge of the blade). See :numref:`ad_blade_geom`. Twist is shown in :numref:`ad_blade_local_cs` of :numref:`ad_appendix`. .. _ad_blade_geom: -.. figure:: figs/ad_blade_geom.png +.. figure:: figs/aerodyn_blade_geom.png :width: 90% :align: center - :alt: ad_blade_geom.png + :alt: aerodyn_blade_geom.png AeroDyn Blade Geometry – Left: Side View; Right: Front View (Looking Downwind) + + +.. _TF_tf_input-file: + +Tail fin input file +------------------- + +An example of tail fin input file is given below: + +.. code:: + + ------- TAIL FIN AERODYNAMICS INPUT FILE-------------------------------------------- + Comment + ====== General inputs ============================================================= + 1 TFinMod - Tail fin aerodynamics model {0: none, 1: polar-based, 2: USB-based} (switch) + 0.5 TFinChord - Tail fin chord (m) [used only when TFinMod=1] + 0.3 TFinArea - Tail fin planform area (m^2) [used only when TFinMod=1] + 10.,0.,0. TFinRefP_n - Undeflected position of the tail fin reference point wrt the tower top (m) + 0.,0.,0. TFinAngles - Tail fin chordline skew, tilt, and bank angles about the reference point (degrees) + 0 TFinIndMod - Model for induced velocity calculation {0: none, 1:rotor-average} (switch) + ====== Polar-based model ================================ [used only when TFinMod=1] + 1 TFinAFID - Index of Tail fin airfoil number [1 to NumAFfiles] + ====== Unsteady slender body model ===================== [used only when TFinMod=2] + [TODO inputs for model 2] + +General inputs +~~~~~~~~~~~~~~ + +**TFinMod** Switch to select a model for the tail fin aerodynamics: +0) none (the aerodynamic forces are zero), 1) polar-based, 2) USB-based (see :numref:`TF-aerotheory`). +(switch) + +**TFinArea** Area of the tail fin. (m^2) +This is the plan form area of the tail fin plate used to relate the local dynamic pressure and airfoil +coefficients to aerodynamic loads. This value must not be negative and is only used when +TFinMod is set to 1. (m^2) + +**TFinRefP_n** Undeflected position (:math:`x_{\text{ref},x_n},x_{\text{ref},y_n}, x_{\text{ref},z_n}`) of the tail fin from the tower top in nacelle coordinates. +(formerly defined using ``TFinCPxn``, ``TFinCPyn``, ``TFinCPzn``). +The distances defines the configuration for a furl angle of zero. +For a typical upwind wind turbine, +:math:`x_n`, is positive downwind, +:math:`y_n`, is positive to the left when looking downwind, and +:math:`z_n`, is positive upward when looking downwind. +See :numref:`figTFGeom` and :numref:`figTFcoord1`. +(m) + +**TFinAngles** Angles (:math:`\theta_\text{skew},\theta_\text{tilt}, \theta_\text{bank}`) of the tail fin +(formerly defined as ``TFinSkew``, ``TFinTilt``, ``TFinBank``). +See :numref:`figTFGeom` and :numref:`figTFcoord1`. +These angles define the chordline at a furl angle of zero, where the chordline is assumed to be passing through the reference point. +:math:`\theta_\text{skew}` is the skew angle of the tail fin chordline in the nominally horizontal plane. +Positive skew orients the nominal horizontal projection of the tail fin chordline about the :math:`z_n`-axis. +The aforementioned chordline is the chordline passing through the tail fin reference point. +This value must be greater than -180 and less than or equal to 180 degrees. +:math:`\theta_\text{tilt}` is the tilt angle of the tail fin chordline from the nominally horizontal plane. +This value must be between -90 and 90 degrees (inclusive). +Positive tilt means that the trailing edge of the tail fin is higher than the leading edge. +:math:`\theta_\text{bank}` is the bank angle of the tail fin plane about the tail fin chordline. +This value must be greater than -180 and less than or equal to 180 degrees. +(deg) + + + +**TFinIndMod** +Switch to select a model for the calculation of the velocity induced by the rotor and its wake on the tailfin (not the induced velocity from the tailfin wing). +The options available are: +0) none (the induced velocity is zero) +1) rotor-average (using the average induced velocity across all blades and blade nodes) +(see :numref:`TF-aerotheory`). (switch) + + +Polar-based model inputs +~~~~~~~~~~~~~~~~~~~~~~~~ + +**TFinAFID** +This integer tells AeroDyn which of the input airfoil files (``AFNames``) is assigned to the tail fin. For +instance, a value of 2 means that the tail fin will use ``AFNames(2)`` for the local tail fin airfoil. +This value must be +between 1 and ``NumAFfiles`` and is only used when TFinMod is set to 1. (-) + + +Unsteady slender body (USB) model inputs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This option is currently not available and will be documented in a future release. + + diff --git a/docs/source/user/aerodyn/introduction.rst b/docs/source/user/aerodyn/introduction.rst index 62674e3fa..6a1a380e8 100644 --- a/docs/source/user/aerodyn/introduction.rst +++ b/docs/source/user/aerodyn/introduction.rst @@ -14,7 +14,8 @@ 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 +wind turbines, computed by AeroDyn include a cavitation check and buoyant forces +and moments on the blades, tower, hub, and nacelle. 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 @@ -66,12 +67,14 @@ and returns them back to OpenFAST as part of the aero-elastic calculation. In standalone mode, the inputs to AeroDyn are prescribed by a simple driver code, without aero-elastic coupling. -AeroDyn consists of four submodels: (1) rotor wake/induction, (2) blade +AeroDyn consists of six submodels: (1) rotor wake/induction, (2) blade airfoil aerodynamics, (3) tower influence on the fluid local to the -blade nodes, and (4) tower drag. Nacelle, hub, and tail-vane fluid -influence and loading, aeroacoustics, and wake and array effects between -multiple turbines in a wind plant, are not yet available in AeroDyn v15 -and newer. +blade nodes, (4) tower drag, (5) aeroacoustics, +and (6) buoyancy on the blades, hub, nacelle, and tower (for MHK turbines). +Nacelle, hub, and tail-vane fluid influence and loading (with the exception +of nacelle and hub buoyant loads) and wake and array effects between +multiple turbines in a wind plant are not yet available in AeroDyn. +Aeroacoustics are not available for MHK turbines. For operating wind and MHK turbine rotors, AeroDyn calculates the influence of the wake via induction factors based on the quasi-steady @@ -178,15 +181,15 @@ flow models. The primary AeroDyn input file defines modeling options, environmental conditions (except freestream flow), airfoils, tower nodal -discretization and properties, as well as output file specifications. -Airfoil data properties are read from dedicated inputs files (one for -each airfoil) and include coefficients of lift force, drag force, and -optional pitching moment and minimum pressure versus AoA, as well as UA -model parameters. (Minimum pressure coefficients versus AoA are also -included in the airfoil input files in case that a cavitation check is -requested.) Blade nodal discretization, geometry, twist, chord, and -airfoil identifier are likewise read from separate input files (one for -each blade). +discretization and properties, tower, hub, and nacelle buoyancy properties, +as well as output file specifications. Airfoil data properties are read from +dedicated inputs files (one for each airfoil) and include coefficients of +lift force, drag force, and optional pitching moment and minimum pressure +versus AoA, as well as UA model parameters. (Minimum pressure coefficients +versus AoA are also included in the airfoil input files in case that a +cavitation check is requested.) Blade nodal discretization, geometry, twist, +chord, airfoil identifier, and buoyancy properties are likewise read from +separate input files (one for each blade). :numref:`ad_input` describes the AeroDyn input files. :numref:`ad_output` discusses the diff --git a/docs/source/user/aerodyn/modeling.rst b/docs/source/user/aerodyn/modeling.rst index b75ecd263..fa245af95 100644 --- a/docs/source/user/aerodyn/modeling.rst +++ b/docs/source/user/aerodyn/modeling.rst @@ -19,8 +19,8 @@ Environmental Conditions For air, typical values for ``AirDens``, ``KinVisc``, ``SpdSound``, and ``Patm`` are around 1.225 kg/m\ :sup:`3`, 1.460E-5 m\ :sup:`2`/s, 340.3 m/s, and 101,325 Pa, respectively. For seawater, -typical values for ``AirDens``, ``KinVisc``, and ``Pvap`` are -around 1025 kg/m\ :sup:`3`, 1.004E-6 m\ :sup:`2`/s, and 2000 Pa, +typical values for ``FldDens``, ``KinVisc``, ``SpdSound``, and ``Pvap`` are +around 1025 kg/m\ :sup:`3`, 1.004E-6 m\ :sup:`2`/s, 1500 m/s, and 2000 Pa, respectively. Temporal and Spatial Discretization @@ -51,15 +51,15 @@ When the tower potential-flow (``TwrPotent > 0``), tower shadow (``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 -above ground (or above MSL for offshore wind turbines or above the -seabed for MHK turbines) (``TwrElev``), must be entered in -monotonically increasing order from the lowest (tower-base) to the -highest (tower-top) elevation. However, when AeroDyn is coupled to FAST, -the tower-base node in AeroDyn cannot be set lower than the lowest point +above ground (or relative to MSL for offshore wind and floating +MHK turbines or relative to the seabed for fixed MHK turbines) (``TwrElev``), +must be entered in monotonically increasing order from the lowest (tower-base) to the +highest (tower-top) elevation (or monotonically decreasing order for floating MHK turbines). +However, when AeroDyn is coupled to FAST, the tower-base node in AeroDyn cannot be set lower than the lowest point where wind is specified in the InflowWind module. To avoid truncating the lower section of the tower in AeroDyn, we recommend that the wind be specified in InflowWind as low to the ground (or MSL for offshore wind -turbines or above the seabed for MHK turbines) as possible (this is a +turbines or seabed for fixed and floating MHK turbines) as possible (this is a particular issue for full-field wind file formats). Model Options Under Operational and Parked/Idling Conditions @@ -114,4 +114,6 @@ linearization of the full coupled solution. When induction is enabled (``WakeMod = 1``), we recommend to base the linearized solution on the frozen-wake assumption, by setting ``FrozenWake = TRUE``. The UA models are not set up to support linearization, so, UA must be disabled -during linearization by setting ``AFAeroMod = 1``. +during linearization by setting ``AFAeroMod = 1``. Linearization is not +currently possible when modeling an MHK turbine, but we will attempt to +enable it in an upcoming release. diff --git a/docs/source/user/aerodyn/theory.rst b/docs/source/user/aerodyn/theory.rst index dfa632f1c..8043c51cf 100644 --- a/docs/source/user/aerodyn/theory.rst +++ b/docs/source/user/aerodyn/theory.rst @@ -14,6 +14,94 @@ Steady BEM The steady blade element momentum (BEM) equations are solved as a constrained equation, and the formulation follows the description from Ning :cite:`ad-Ning:2014`. + +.. _AD_DBEMT: + +Dynamic BEM Theory (DBEMT) +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + + +Two equivalent versions of Oye's dynamic inflow model are implemented in AeroDyn. +The first one uses discrete time, it can be used with the constant-tau1 model +(``DBEMT_Mod=1``) or the varying-tau1 model (``DBEMT_Mod=2``), but it cannot be used for linearization. +The second version uses a continuous-time state-space formulation (``DBEMT_Mod=1``), it assumes a constant-tau1, and can be used for linearization. +For a same value of :math:`\tau_1`, the discrete-time and continuous-time formulations returns exactly the same results. + + + + + +Oye's dynamic inflow model consists of two first-order differential equations (see :cite:`ad-Branlard:book`): + +.. math:: + \begin{aligned} + \boldsymbol{W}_\text{int}+\tau_1 \boldsymbol{\dot{W}}_\text{int} &= \boldsymbol{W}_\text{qs} + k \tau_1 \boldsymbol{\dot{W}}_\text{qs} \\ + \boldsymbol{W}+\tau_2 \boldsymbol{\dot{W}} &= \boldsymbol{W}_\text{int} + \end{aligned} + +where +:math:`\boldsymbol{W}` is the dynamic induction vector at the rotor (at a given blade position and radial position), +:math:`\boldsymbol{W}_\text{qs}` is the quasi-steady induction, +:math:`\boldsymbol{W}_\text{int}` is an intermediate value coupling the quasi-steady and the actual inductions (may be discontinuous if the quasi-steady indution is discontinuous). +and +:math:`(\dot{\ })` represents the time derivative. +The coupling constant :math:`k`, with values between 0 and 1, is usually chosen as :math:`k=0.6`. +Oye's dynamic inflow model relies on two time constants, :math:`\tau_1` and :math:`\tau_2` : + +.. math:: + \tau_1=\frac{1.1}{1-1.3 \min(\overline{a},0.5)} \frac{R}{\overline{U}_0} + , \qquad + \tau_2 =\left[ 0.39-0.26\left(\frac{r}{R}\right)^2\right] \tau_1 + +where :math:`R` is the rotor radius, :math:`\overline{U}_0` is the average wind speed over the rotor, :math:`\overline{a}` is the average axial induction over the rotor, and :math:`r` is the radial position along the blade. +For ``DBEMT_Mod=1`` or ``DBEMT_Mod=3``, the user needs to provide the value of :math:`\tau_1`. + + + + +The continuous-time state-space formulation of the dynamic inflow model (``DBEMT_Mod=3``) was derived in :cite:`ad-Branlard:2022`. + +.. math:: + \begin{align} + \begin{bmatrix} + \boldsymbol{\dot{W}}_\text{red}\\ + \boldsymbol{\dot{W}}\\ + \end{bmatrix} + = + \begin{bmatrix} + -\frac{1}{\tau_1}\boldsymbol{I}_2 & \boldsymbol{0} \\ + \frac{1}{\tau_2}\boldsymbol{I}_2 & + -\frac{1}{\tau_2}\boldsymbol{I}_2 \\ + \end{bmatrix} + \begin{bmatrix} + \boldsymbol{W}_\text{red}\\ + \boldsymbol{W}\\ + \end{bmatrix} + + + \begin{bmatrix} + \frac{1-k}{\tau_1} \\ + \frac{k}{\tau_2}\\ + \end{bmatrix} + \boldsymbol{W}_\text{qs} + \end{align} + +where +:math:`\boldsymbol{I}_2` is the 2x2 identity matrix, +:math:`\boldsymbol{W}_\text{red}` is the reduced induction which is a continuous, scaled, and lagged version of the quasi-steady induction, defined as: + +.. math:: + \boldsymbol{W}_\text{int} = \boldsymbol{W}_\text{red} + k \boldsymbol{W}_\text{qs} + + +The discrete-time version of the model is documented in the unpublished manual of DBEMT. +The current discrete-time formulation is complex and in the future it can be simplified by using :math:`\boldsymbol{W}_\text{red}`. + + + + + + .. _AD_twr_shadow: Tower shadow models @@ -37,5 +125,92 @@ Eames tower shadow model (**TwrShadow=2**) is given by: where :math:`TI` is the turbulence intensity at the tower node. +.. _AD_buoyancy: + +Buoyancy +~~~~~~~~ + +When a solid object is submerged in a fluid, it experiences a net force, buoyancy, +from the hydrostatic fluid pressure acting on its surface. This force can often +be neglected in less dense fluids, such as air, but can be significant in denser +fluids, such as water. To capture the effects of this force on MHK turbines, +buoyant loads are calculated for the turbine blades, tower, hub, and nacelle. +Marine growth is neglected for all components. :numref:`AD_buoy_coords` - +:numref:`AD_buoy_hubnacelle` detail the coordinate systems and blade, tower, hub, +and nacelle buoyancy calculations. + +.. _AD_buoy_coords: + +Coordinate Systems +------------------ +The buoyant force acting on an element depends on its instantaneous orientation +and depth. The orientation is defined by heading and inclination angles, which +are calculated for each element at every time step. Total water depth is defined +by the user, relative to the still water level (or relative to the mean sea +level when running AeroDyn in standalone mode with the AeroDyn driver). The +instantaneous depth of each element is based on its position in global coordinates +at each time step. + +.. _AD_buoy_bladestower: + +Blades and Tower +---------------- +To allow for an efficient analytical solution, the blades and tower are modeled +as tapered cylinders. The cross-sectional area of the tapered cylinders is set +equal to the blade or tower cross-sectional area. Loads are estimated by breaking +the blade or tower into elements of a given length and integrating the hydrostatic +pressure over the wetted area of each element. For the blades, loads are applied +at a user-specified center of buoyancy. For the tower, loads are applied at the +centerline. When applicable, end effects are accounted for by calculating the +fluid pressure on the exposed axial face of the element. The tower is assumed to +be either embedded into the seabed or attached to another support structure member, +such that no end effects at the tower base are needed. For MHK turbines with a support +structure (i.e., any structure other than a simple tower embedded in the seabed), it +is currently recommended to model the entire support structure, including the tower, in HydroDyn. +Future releases will include the ability to neglect fluid loads at the interface between a tower +modeled in AeroDyn and a platform modeled in HydroDyn. + + +The buoyancy calculation for the blades and tower is completed according to the following steps: + +1. Calculate parameters related to element geometry that do not change with time +2. Check that no elements cross the free surface or go beneath the seabed +3. Calculate the instantaneous orientation and depth of each element +4. Integrate hydrostatic fluid pressure over the wetted surface of each element and express as a force acting at the center of buoyancy +5. For blades, calculate the buoyant force on the axial face of the blade root and tip; add the tip force to the adjacent element and store the root force +6. For the tower, calculate and store the buoyant force on the axial face of the tower top +7. Move buoyant loads from the center of buoyancy to the aerodynamic center +8. Express buoyant loads in the form expected by OpenFAST +9. Add buoyant loads to aerodynamic loads + +Although the blade and tower buoyant loads are not based on volume, the volumes of these components are +written to the AeroDyn summary file for reference. The blade and tower volumes are calculated by summing +the volume of each element, assumed to be a tapered cylinder. The volume of a single element :math:`(V_{elem})` +is given by: + +.. math:: + V_{elem} = \frac{\pi}{3} (r_i^2 + r_i r_{i+1} + r_{i+1}^2) dl + +where :math:`r_i` is the element radius at node :math:`i`, :math:`r_{i+1}` is the element radius at node +:math:`i+1`, and :math:`dl` is the element length. + + +.. _AD_buoy_hubnacelle: + +Hub and Nacelle +--------------- +The hub and nacelle are treated as separate components. The buoyant force is +determined by the volume of either the hub or nacelle and applied at its +user-specified center of buoyancy. Corrections are made to account for the joints +between the hub and blades and the nacelle and tower, as the joint locations are +not exposed to fluid pressure. No correction is made for the joint between the +hub and nacelle. +The buoyancy calculation for the hub and nacelle is completed according to the following steps: +1. Check that the component does not cross the free surface or go beneath the seabed +2. Calculate the instantaneous depth of the component +3. Calculate the buoyant force from the volume of the component +4. Move buoyant loads from the center of buoyancy to the aerodynamic center +5. For the hub, correct loads to account for the joints with each blade +6. For the nacelle, correct loads to account for the joint with the tower diff --git a/docs/source/user/aerodyn/theory_tailfin.rst b/docs/source/user/aerodyn/theory_tailfin.rst new file mode 100644 index 000000000..5c5a356a7 --- /dev/null +++ b/docs/source/user/aerodyn/theory_tailfin.rst @@ -0,0 +1,171 @@ +.. _TF-aerotheory: + +Tail fin Aerodynamics Theory +============================ + +Notations +--------- + +**Tail fin aerodynamic reference point** + +The tail fin aerodynamic reference point, :math:`\boldsymbol{x}_\text{ref}`, is the point where the aerodynamic loads are calculated on the tail fin. +The structural solver computes the instantenous position, velocity, acceleration, of the reference point at each time step. +The initial position of the reference point with respect to the tower top is a user input. +Typical choices are the +leading edge/apex of the fin or a point close to the center of pressure at zero angle of attack. +The other aerodynamic inputs (e.g. aerodynamic moment coefficient) need to be consistent with the choice of the reference point. + +**Tail fin coordinate system** + +The inertial and tail fin coordinate systems are illustrated in :numref:`figTFcoord1`. +The transformation matrix from the inertial coordinate system to the tail fin coordinate system is given by :math:`\boldsymbol{R}_\text{tf,i}`. + +.. _figTFcoord1: +.. figure:: figs/TailFinCoord.png + :width: 70% + + Coordinate systems and velocity vectors used for the tail fin aerodynamics + + +The reference orientation (when the structure is un-deflected), the transformation matrix is: + +.. math:: :label: tfRrfiinit + + \boldsymbol{R}_\text{tf,i} = \operatorname{EulerConstruct}(\theta_\text{bank}, \theta_\text{tilt}, \theta_\text{skew}) + +For a common application with a vertical fin, the three angles are zero. +:red:`TODO: The order of the angles might be different in the current implementation (3-2-1) instead of (1-2-3) above)` + + +**Velocities** + +The following velocity vectors (3D vectors in global coordinates) are defined (see :numref:`figTFcoord1`): + +- :math:`\boldsymbol{V}_\text{wind}`: + Undisturbed Wind speed vector at the reference point +- :math:`\boldsymbol{V}_\text{dist}`: + Disturbed wind speed vector at the reference point (the disturbed wind contains the influence of the tower on the flow). AeroDyn has internal methods to compute :math:`\boldsymbol{V}_\text{dist}` from :math:`\boldsymbol{V}_\text{wind}`. + :red:`For now, we use "wind" but in the future we might use "dist". In the theory below we would simply replace all the "wind" by "dist"`. +- :math:`\boldsymbol{V}_\text{elast}`: + Structural translational velocity vector at the reference point +- :math:`\boldsymbol{V}_\text{ind}`: + Induced velocity from the wake at the reference point (assumed to be zero for now) +- :math:`\boldsymbol{\omega}`: + Structural rotational velocity of the fin + +All velocities (except for :math:`\boldsymbol{V}_\text{ind}` and :math:`\boldsymbol{V}_\text{dist}` which are computed internally by AeroDyn) are provided as input to the aerodynamic solver. +The relative wind experienced by the airfoil is given by: + +.. math:: :label: tfVrel + + \boldsymbol{V}_\text{rel} = + \boldsymbol{V}_\text{wind} + -\boldsymbol{V}_\text{elast} + +\boldsymbol{V}_\text{ind} + + + + +**Angle of attack** + +The angle of attack is defined in the :math:`x_\text{tf}-y_\text{tf}` plane of the tail fin coordinate systems as illustrated in :numref:`figTFcoord2`. + +.. _figTFcoord2: +.. figure:: figs/TailFinAirfoilCoord.png + :width: 70% + + Tail fin airfoil coordinate system and definition of angle of attack in the x-y plane + +We write :math:`V_{\text{rel},\perp}` the projection of :math:`\boldsymbol{V}_\text{rel}` in this plane. The angle of attack is given by the components of this vector: + +.. math:: :label: tfalpha + + \alpha = \arctan\frac{V_{\text{rel},y_\text{tf}}}{V_{\text{rel},x_\text{tf}}} + +In this implementation, the function `atan2` is used to compute the angle of attack. + + + +**Loads** + +If the dimensionless coefficients are known, they can be projected in the :math:`x_\text{tf}-y_\text{tf}` plane as follows: + +.. math:: :label: tfCxCy + + C_{x_\text{tf}}(\alpha) = -C_l(\alpha) \sin\alpha + C_d(\alpha)\cos\alpha + ,\quad + C_{y_\text{tf}}(\alpha) = C_l(\alpha) \cos\alpha + C_d(\alpha)\sin\alpha + +and the loads are therefore given by: + +.. math:: :label: tffxfymz + + f_{x_\text{tf}} = \frac{1}{2}\rho V_{\text{rel},\perp}^2 A \,C_{x_\text{tf}}(\alpha) + ,\quad + f_{y_\text{tf}} = \frac{1}{2}\rho V_{\text{rel},\perp}^2 A \,C_{y_\text{tf}}(\alpha) + ,\quad + m_{z_\text{tf}} = \frac{1}{2}\rho V_{\text{rel},\perp}^2 Ac \, C_m(\alpha) + + +Once the loads are known in the tail fin coordinate systems, they are transferred to the inertial system as follows: + +.. math:: :label: tfforcesi + + \left.\boldsymbol{f}\right|_{i} = \boldsymbol{R}_\text{tf,i}^t \left.\boldsymbol{f}\right|_\text{tf} + = \boldsymbol{R}_\text{tf,i}^t + \begin{bmatrix} + f_{x_\text{tf}}\\ + f_{y_\text{tf}}\\ + 0\\ + \end{bmatrix} + ,\qquad + \left.\boldsymbol{m}\right|_{i} = \boldsymbol{R}_\text{tf,i}^t \left.\boldsymbol{m}\right|_\text{tf} + = \boldsymbol{R}_\text{tf,i}^t + \begin{bmatrix} + 0\\ + 0\\ + m_{z_\text{tf}}\\ + \end{bmatrix} + + +**Induced velocity** + +The induced velocity from the wake at the reference point will affect the relative wind and therefore the angle of attack of the tail fin. +Different models are implemented to compute this induced velocity. +As a first approximation, this velocity may be set to zero (corresponding to the input `TFinIndMod=0`): + +.. math:: :label: TFVindZero + + \boldsymbol{V}_\text{ind}=0 + +The rotor-averaged induced velocity can also be used as an estimate (`TFinIndMod=1`). It is computed as the mean induced velocity over all the blade and aerodynamic nodes + +.. math:: :label: TFVindRtAvg + + \boldsymbol{V}_\text{ind}=\frac{1}{n_B n_r}\sum_{i_b=1..n_B} \sum_{i_r=1..n_r} \boldsymbol{V}_{\text{ind},\text{blade}}[i_b, i_r] + +Where :math:`\boldsymbol{V}_{\text{ind},\text{blade}}[i_b, i_r]` is the induced velocity vector for blade :math:`i_b` and at the radial node :math:`i_r`. +:red:`NOTE: This averaging corresponds to what is done for the disk-average of the inflow in AeroDyn. In the future, we can use something weighted by the radius, or using precomputed coefficients, as done by Envision`. + +More advanced models could set the induced velocity to zero when outside of the wake boundary, or include a tower-shadow-like wake model. Such option is not yet available. + + + + +Polar-based model +----------------- + +In the polar-based model, the user provides the aerodynamic coefficients :math:`C_l, C_d, C_m`, as tabulated data, functions of the angle of attack. The aerodynamic moment is assumed to be provided at the reference point. A common practice is to use the center of pressure at zero angle of attack for polar data, so the user might want to chose such a point as the reference point of the fin. +The tabulated data are provided as part of the list of airfoils given with `AFNames` in the AeroDyn input file. +The user only needs to indicate the index `TFinAFIndex` within the list `AFNames` to indicate which polar to use for the tail fin. + + +Unsteady slender body model +--------------------------- + +The unsteady slender body (USB) model is documented in :cite:`ad-hammam2022`. + +The theory will be implemented and documented in a future release. + + + diff --git a/docs/source/user/aerodyn/theory_ua.rst b/docs/source/user/aerodyn/theory_ua.rst index 7c66917bb..d55699d5b 100644 --- a/docs/source/user/aerodyn/theory_ua.rst +++ b/docs/source/user/aerodyn/theory_ua.rst @@ -3,7 +3,7 @@ .. _AD_UA: -Unsteady aerodynamics +Unsteady Aerodynamics ===================== @@ -197,8 +197,11 @@ Two variants are implemented in the Unsteady Aerodynamic module. These two (comp Beddoes-Leishman 4-states model (UAMod=4) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The 4-states (incompressible) dynamic stall model from Hansen-Gaunaa-Madsen (HGM) is described in :cite:`ad-Hansen:2004` and enabled using ``UAMod=4``. The model uses :math:`C_l` as main physical quantity. -Linearization of the model will be available in the future. +The 4-states (incompressible) dynamic stall model as implemented in OpenFAST is described in :cite:`ad-Branlard:2022` (the model differs slithgly from the original formulation from Hansen-Gaunaa-Madsen (HGM) :cite:`ad-Hansen:2004`). +The model is enabled using ``UAMod=4``. The model uses :math:`C_l` as main physical quantity. +Linearization of the model is available. + +NOTE: this model might require smaller time steps until a stiff integrator is implemented in AeroDyn-UA. **State equation:** @@ -225,6 +228,9 @@ with \end{aligned} + + + **Output equation:** The unsteady airfoil coefficients :math:`C_{l,\text{dyn}}`, :math:`C_{d,\text{dyn}}`, @@ -233,8 +239,9 @@ The unsteady airfoil coefficients .. math:: \begin{aligned} - C_{l,\text{dyn}}(t) &= x_4 (\alpha_E-\alpha_0) C_{l,\alpha} + (1-x_4) C_{l,{fs}}(\alpha_E)+ \pi T_u \omega \\ - C_{d,\text{dyn}}(t) &= C_d(\alpha_E) + (\alpha_{ac}-\alpha_E) C_{l,\text{dyn}} + \left[ C_d(\alpha_E)-C_d(\alpha_0)\right ] \Delta C_{d,f}'' \\ + C_{l,\text{dyn}}(t) &= C_{l,\text{circ}} + \pi T_u \omega \\ + % C_{d,\text{dyn}}(t) &= C_d(\alpha_E) + (\alpha_{ac}-\alpha_E) C_{l,\text{dyn}} + \left[ C_d(\alpha_E)-C_d(\alpha_0)\right ] \Delta C_{d,f}'' \\ + C_{d,\text{dyn}}(t) &= C_d(\alpha_E) + \left[(\alpha_{ac}-\alpha_E) +T_u \omega \right]C_{l,\text{circ}} + \left[ C_d(\alpha_E)-C_d(\alpha_0)\right ] \Delta C_{d,f}'' \\ % C_{m,\text{dyn}}(t) &= C_m(\alpha_E) + C_{l,\text{dyn}} \Delta C_{m,f}'' - \frac{\pi}{2} T_u \omega\\ C_{m,\text{dyn}}(t) &= C_m(\alpha_E) - \frac{\pi}{2} T_u \omega\\ \end{aligned} @@ -245,7 +252,8 @@ with: \begin{aligned} \Delta C_{d,f}'' &= \frac{\sqrt{f_s^{st}(\alpha_E)}-\sqrt{x_4}}{2} - \frac{f_s^{st}(\alpha_E)-x_4}{4} ,\qquad - x_4\ge 0 + x_4\ge 0 \\ + C_{l,\text{circ}}&= x_4 (\alpha_E-\alpha_0) C_{l,\alpha} + (1-x_4) C_{l,{\text{fs}}}(\alpha_E) \end{aligned} @@ -258,7 +266,7 @@ Beddoes-Leishman 5-states model (UAMod=5) The 5-states (incompressible) dynamic stall model is similar to the Beddoes-Leishman 4-states model (UAMod=4), but adds a 5th state to represent vortex generation. It is enabled using ``UAMod=5``. The model uses :math:`C_n` and :math:`C_c` as main physical quantities. -Linearization of the model will be available in the future. +Linearization of the model is available. @@ -272,7 +280,7 @@ Oye model (UAMod=6) Oye's dynamic stall model is a one-state (continuous) model, formulated in :cite:`ad-Oye:1991` and described e.g. in :cite:`ad-Branlard:book`. The model attempts to capture trailing edge stall. -Linearization of the model will be available in the future. +Linearization of the model is available. **State equation:** diff --git a/docs/source/user/api_change.rst b/docs/source/user/api_change.rst index 2e39de856..6ca2caf00 100644 --- a/docs/source/user/api_change.rst +++ b/docs/source/user/api_change.rst @@ -9,11 +9,155 @@ The changes are tabulated according to the module input file, line number, and f The line number corresponds to the resulting line number after all changes are implemented. Thus, be sure to implement each in order so that subsequent line numbers are correct. +OpenFAST v3.4.0 to OpenFAST v3.5.0 +---------------------------------- + +Updated the CMake build system. Now requires CMake v3.12 or higher. + +============================================= ==== ==================== ======================================================================================================================================================================================================== +Modified in OpenFAST `3.5.0` +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Module Line Flag Name Example Value +============================================= ==== ==================== ======================================================================================================================================================================================================== +ServoDyn-StructCtrl 6 StC_DOF_MODE 2 StC_DOF_MODE - DOF mode (switch) {0: No StC or TLCD DOF; 1: StC_X_DOF, StC_Y_DOF, and/or StC_Z_DOF (three independent StC DOFs); 2: StC_XY_DOF (Omni-Directional StC); 3: TLCD; 4: Prescribed force/moment time series; 5: Force determined by external DLL} +InflowWind 8 VelInterpCubic true VelInterpCubic - Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7] +InflowWind 51 ================== LIDAR Parameters =========================================================================== +InflowWind 52 SensorType 0 SensorType - Switch for lidar configuration (0 = None, 1 = Single Point Beam(s), 2 = Continuous, 3 = Pulsed) +InflowWind 53 NumPulseGate 0 NumPulseGate - Number of lidar measurement gates (used when SensorType = 3) +InflowWind 54 PulseSpacing 30 PulseSpacing - Distance between range gates (m) (used when SensorType = 3) +InflowWind 55 NumBeam 0 NumBeam - Number of lidar measurement beams (0-5)(used when SensorType = 1) +InflowWind 56 FocalDistanceX -200 FocalDistanceX - Focal distance co-ordinates of the lidar beam in the x direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) +InflowWind 57 FocalDistanceY 0 FocalDistanceY - Focal distance co-ordinates of the lidar beam in the y direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) +InflowWind 58 FocalDistanceZ 0 FocalDistanceZ - Focal distance co-ordinates of the lidar beam in the z direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) +InflowWind 59 RotorApexOffsetPos 0.0 0.0 0.0 RotorApexOffsetPos - Offset of the lidar from hub height (m) +InflowWind 60 URefLid 17 URefLid - Reference average wind speed for the lidar[m/s] +InflowWind 61 MeasurementInterval 0.25 MeasurementInterval - Time between each measurement [s] +InflowWind 62 LidRadialVel False LidRadialVel - TRUE => return radial component, FALSE => return 'x' direction estimate +InflowWind 63 ConsiderHubMotion 1 ConsiderHubMotion - Flag whether to consider the hub motion's impact on Lidar measurements +============================================= ==== ==================== ======================================================================================================================================================================================================== + + + +OpenFAST v3.4.0 to OpenFAST v3.4.1 +---------------------------------- + +Restored the AeroDyn channel names with `Aero` in the name. These had be +changed to `Fld` in v3.4.0 which caused headaches for users. The `Fld` names +are now aliases to the `Aero` names. + -OpenFAST v3.2.0 to OpenFAST `dev` +OpenFAST v3.3.0 to OpenFAST v3.4.0 ---------------------------------- -None +============================================= ==== ================= ======================================================================================================================================================================================================== +Added in OpenFAST `3.4.0` +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Module Line Flag Name Example Value +============================================= ==== ================= ======================================================================================================================================================================================================== +FAST.Farm 17 ModWake 1 Mod_Wake - Switch between wake formulations {1:Polar, 2:Curl, 3:Cartesian} (-) (switch) +FAST.Farm 67 CurlSection --- CURLED-WAKE PARAMETERS [only used if Mod_Wake=2 or 3] --- +FAST.Farm 68 Swirl DEFAULT Swirl - Switch to include swirl velocities in wake (-) (switch) [DEFAULT=True] +FAST.Farm 69 k_VortexDecay DEFAULT k_VortexDecay - Vortex decay constant for curl (-) [DEFAULT=0.01] [only used if Mod_Wake=2] +FAST.Farm 70 NumVortices DEFAULT NumVortices - The number of vortices in the curled wake model (-) [DEFAULT=100] [only used if Mod_Wake=2] +FAST.Farm 71 sigma_D DEFAULT sigma_D - The width of the vortices in the curled wake model non-dimensionalized by rotor diameter (-) [DEFAULT=0.2] [only used if Mod_Wake=2] +FAST.Farm 72 FilterInit DEFAULT FilterInit - Switch to filter the initial wake plane deficit and select the number of grid points for the filter {0: no filter, 1: filter of size 1} or DEFAULT [DEFAULT=1] (switch) +FAST.Farm 73 k_vCurl DEFAULT k_vCurl - Calibrated parameter for scaling the eddy viscosity in the curled-wake model (-) [>=0] or DEFAULT [DEFAULT=2.0 ] +FAST.Farm 74 Mod_Projection DEFAULT Mod_Projection - Switch to select how the wake plane velocity is projected in AWAE {1: keep all components, 2: project against plane normal} or DEFAULT [DEFAULT=1: if Mod_Wake is 1 or 3, or DEFAULT=2: if Mod_Wake is 2] (switch) +FAST.Farm 91 OutAllPlanes DEFAULT OutAllPlanes - Output all wake planes at all time steps. [DEFAULT=False] +AeroDyn 15 13 Buoyancy True Buoyancy - Include buoyancy effects? (flag) +AeroDyn 15 65 HubPropsSection ====== Hub Properties ============================================================================== [used only when Buoyancy=True] +AeroDyn 15 66 VolHub 7.0 VolHub - Hub volume (m^3) +AeroDyn 15 67 HubCenBx 0.5 HubCenBx - Hub center of buoyancy x direction offset (m) +AeroDyn 15 68 NacPropsSection ====== Nacelle Properties ========================================================================== [used only when Buoyancy=True] +AeroDyn 15 69 VolNac 32.0 VolNac - Nacelle volume (m^3) +AeroDyn 15 70 NacCenB 0.4,0,0 NacCenB - Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates (m) +AeroDyn 15 71 TFinPropsSection ====== Tail fin Aerodynamics ======================================================================== +AeroDyn 15 72 TFinAero True TFinAero - Calculate tail fin aerodynamics model (flag) +AeroDyn 15 73 TFinFile\$ "AD_Fin.dat" TFinFile - Input file for tail fin aerodynamics [used only when TFinAero=True] +AeroDyn 15 TwrCb 1.0 [additional column in *Tower Influence and Aerodynamics* table] +AeroDyn blade BlCb 0.187 [additional column in *Blade Properties* table] +AeroDyn blade BlCenBn 0.3 [additional column in *Blade Properties* table] +AeroDyn blade BlCenBt 0.1 [additional column in *Blade Properties* table] +OLAF 18 nNWPanelFree 180 nNWPanelFree - Number of free near-wake panels (-) {default: nNWPanels} +OLAF 19 nFWPanels 900 nFWPanels - Number of far-wake panels (-) {default: 0} +OLAF 20 nFWPanelsFree 0 nFWPanelsFree - Number of free far-wake panels (-) {default: nFWPanels} +============================================= ==== ================= ======================================================================================================================================================================================================== + +\*Exact line number depends on number of entries in various preceeding tables. + +\$ The content of the tail fin input file is described in :numref:`TF_tf_input-file`. + +**New Default Values**: +The following default value were changed + +- OLAF *VelocityMethod* is now 2 (particle tree), previous value 1 (n^2 BiotSavart law on segments). +- OLAF *WakeRegMethod* is now 3 (increasing with wake age), previous value was 1 (constant). +- OLAF *nVTKBlades* is now 0 (no wake panels output), previous value was 1 (wake panels output for blade 1) + + +============================================= ==== =============== ======================================================================================================================================================================================================== +Removed in OpenFAST v3.4.0 +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Module Line Flag Name Example Value +============================================= ==== =============== ======================================================================================================================================================================================================== +OLAF 18 WakeLength 900 WakeLength Total wake distance [integer] (number of time steps) +OLAF 19 FreeWakeLength 0 FreeWakeLength Wake length that is free [integer] (number of time steps) {default: WakeLength} +============================================= ==== =============== ======================================================================================================================================================================================================== + + + +OpenFAST v3.2.0 to OpenFAST v3.3.0 +---------------------------------- + + +============================================= ==== ================= ======================================================================================================================================================================================================== +Added in OpenFAST `3.3.0` +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Module Line Flag Name Example Value +============================================= ==== ================= ======================================================================================================================================================================================================== +FAST.Farm 9 ModWaveField 2 Mod_WaveField - Wave field handling (-) (switch) {1: use individual HydroDyn inputs without adjustment, 2: adjust wave phases based on turbine offsets from farm origin} +FAST.Farm 10 Mod_SharedMooring 0 Mod_SharedMooring - Shared mooring system model (switch) {0: None, 3=MoorDyn}} +FAST.Farm 13 na ------ SHARED MOORING SYSTEM ------ [used only for Mod_SharedMoor>0] +FAST.Farm 14 SharedMoorFile "" SharedMoorFile - Name of file containing shared mooring system input parameters (quoted string) [used only when Mod_SharedMooring > 0] +FAST.Farm 15 DT_Mooring 0.04 DT_Mooring - Time step for farm-level mooring coupling with each turbine (s) [used only when Mod_SharedMooring > 0] +AeroDyn driver 54\* WrVTK_Type 1 WrVTK_Type - VTK visualization data type: (switch) {1=surfaces; 2=lines; 3=both} +============================================= ==== ================= ======================================================================================================================================================================================================== + + +============================================= ==== =============== ======================================================================================================================================================================================================== +Modified in OpenFAST v3.3.0 +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Module Line Flag Name Example Value +============================================= ==== =============== ======================================================================================================================================================================================================== +MoorDyn\& 5 na Name Diam MassDen EA BA/-zeta EI Cd Ca CdAx CaAx +MoorDyn\& 6 na (-) (m) (kg/m) (N) (N-s/-) (-) (-) (-) (-) (-) +MoorDyn\& 7 na main 0.0766 113.35 7.536E8 -1.0 0 2.0 0.8 0.4 0.25 +MoorDyn\& 8\* na ---------------------- POINTS -------------------------------- +MoorDyn\& 9\* na ID Attachment X Y Z M V CdA CA +MoorDyn\& 10\* na (-) (-) (m) (m) (m) (kg) (m^3) (m^2) (-) +MoorDyn\& 11\* na 1 Fixed 418.8 725.383 -200.0 0 0 0 0 +MoorDyn\& 17\* na ---------------------- LINES -------------------------------------- +MoorDyn\& 18\* na ID LineType AttachA AttachB UnstrLen NumSegs Outputs +MoorDyn\& 19\* na (-) (-) (-) (-) (m) (-) (-) +MoorDyn\& 20\* na 1 main 1 4 835.35 20 - +============================================= ==== =============== ======================================================================================================================================================================================================== + +\&MoorDyn has undergone an extensive revision that leaves few lines unchanged. We recommend looking at a sample input file for the 5MW_OC4Semi_WSt_WavesWN regression test for reference rather than line by line changes in the above tables. + + +============================================= ==== =============== ======================================================================================================================================================================================================== +Removed in OpenFAST v3.3.0 +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Module Line Flag Name Example Value +============================================= ==== =============== ======================================================================================================================================================================================================== +MoorDyn\& 5 NTypes 1 NTypes - number of LineTypes +MoorDyn\& 10\* NConnects 6 NConnects - number of connections including anchors and fairleads +MoorDyn\& 20\* NLines 3 NLines - number of line objects +============================================= ==== =============== ======================================================================================================================================================================================================== + +\*Exact line number depends on number of entries in various preceeding tables. + +\&MoorDyn has undergone an extensive revision that leaves few lines unchanged. We recommend looking at a sample input file for the 5MW_OC4Semi_WSt_WavesWN regression test for reference rather than line by line changes in the above tables. @@ -52,12 +196,12 @@ ServoDyn 62 AfC_Mean 0 ServoDyn 63 AfC_Amp 0 AfC_Amp - Amplitude for cosine cycling of flap signal (-) [used only with AfCmode==1] ServoDyn 64 AfC_Phase 0 AfC_Phase - Phase relative to the blade azimuth (0 is vertical) for cosine cycling of flap signal (deg) [used only with AfCmode==1] ServoDyn 74 CablesSection ---------------------- CABLE CONTROL ------------------------------------------- -ServoDyn 75 CCmode 0 CCmode - Cable control mode {0: none, 4: user-defined from Simulink/Labview, 5: user-defined from Bladed-style DLL} (switch) +ServoDyn 75 CCmode 0 CCmode - Cable control mode {0: none, 4: user-defined from Simulink/Labview, 5: user-defined from Bladed-style DLL} (switch) HydroDyn driver 6 WtrDens 1025 WtrDens - Water density (kg/m^3) HydroDyn driver 7 WtrDpth 200 WtrDpth - Water depth (m) HydroDyn driver 8 MSL2SWL 0 MSL2SWL - Offset between still-water level and mean sea level (m) [positive upward] OpenFAST 21 MHK 0 MHK - MHK turbine type (switch) {0=Not an MHK turbine; 1=Fixed MHK turbine; 2=Floating MHK turbine} -OpenFAST 22 N/A ---------------------- ENVIRONMENTAL CONDITIONS -------------------------------- +OpenFAST 22 EnvCondSection ---------------------- ENVIRONMENTAL CONDITIONS -------------------------------- OpenFAST 23 Gravity 9.80665 Gravity - Gravitational acceleration (m/s^2) OpenFAST 24 AirDens 1.225 AirDens - Air density (kg/m^3) OpenFAST 25 WtrDens 1025 WtrDens - Water density (kg/m^3) @@ -67,14 +211,25 @@ OpenFAST 28 Patm 103500 Pa OpenFAST 29 Pvap 1700 Pvap - Vapour pressure of working fluid (Pa) [used only for an MHK turbine cavitation check] OpenFAST 30 WtrDpth 50 WtrDpth - Water depth (m) OpenFAST 31 MSL2SWL 0 MSL2SWL - Offset between still-water level and mean sea level (m) [positive upward] -AeroDyn 15 40 UAStartRad 0.25 UAStartRad - Starting radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2; if line is missing UAStartRad=0] -AeroDyn 15 41 UAEndRad 0.95 UAEndRad - Ending radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2; if line is missing UAEndRad=1] +AeroDyn 15 39 UAStartRad 0.25 UAStartRad - Starting radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2; if line is missing UAStartRad=0] +AeroDyn 15 40 UAEndRad 0.95 UAEndRad - Ending radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2; if line is missing UAEndRad=1] AeroDyn driver 34 Twr2Shft 3.09343 Twr2Shft - Vertical distance from the tower-top to the rotor shaft (m) AirFoilTables 12\* alphaUpper 5.0 alphaUpper ! Angle of attack at upper boundary of fully-attached region. (deg) [used only when UAMod=5] ! THIS IS AN OPTIONAL LINE; if omitted, it will be calculated from the polar data AirFoilTables 13\* alphaLower \-3.0 alphaLower ! Angle of attack at lower boundary of fully-attached region. (deg) [used only when UAMod=5] ! THIS IS AN OPTIONAL LINE; if omitted, it will be calculated from the polar data AirFoilTables 42\* UACutout_delta "DEFAULT" UACutout_delta ! Delta angle of attack below UACutout where unsteady aerodynamics begin to turn off (blend with steady solution) (deg) [Specifying the string "Default" sets UACutout_delta to 5 degrees] ! THIS IS AN OPTIONAL LINE; if omitted, it will be set to its default value +FASTFarm 28 Mod_Wake 1 Mod_Wake - Switch between wake formulations {1:Polar, 2:Curl, 3:Cartesian} (-) (switch) +FASTFarm 62 Swirl False Swirl - Switch to include swirl velocities in wake [only used if Mod_Wake=2 or Mod_Wake=3] (-) (switch) +FASTFarm 63 k_VortexDecay 0. k_VortexDecay - Vortex decay constant for curl (-) +FASTFarm 64 NumVortices DEFAULT NumVortices - The number of vortices in the curled wake model (-) [DEFAULT=100] +FASTFarm 65 sigma_D DEFAULT sigma_D - The width of the vortices in the curled wake model non-dimesionalized by rotor diameter (-) [DEFAULT=0.2] +FASTFarm 66 FilterInit DEFAULT FilterInit - Switch to filter the initial wake plane deficit and select the number of grid points for the filter {0: no filter, 1: filter of size 1} or DEFAULT [DEFAULT=1] [unused for Mod_Wake=1] (switch) +FASTFarm 67 k_vCurl 20 k_vCurl - Calibrated parameter for scaling the eddy viscosity in the curled-wake model (-) [only used if Mod_Wake=2 or Mod_Wake=3] [>=0] or DEFAULT [DEFAULT=2.0 ] +FASTFarm 68 Mod_Projection DEFAULT Mod_Projection - Switch to select how the wake plane velocity is project +FASTFarm 85 OutAllPlanes True OutAllPlanes - Output all wake planes at all time steps. [DEFAULT=False] ============================================= ==== =============== ======================================================================================================================================================================================================== + + \*non-comment line count, excluding lines contained if NumCoords is not 0, and including all OPTIONAL lines in the UA coefficients table. ============================================= ==== =============== ======================================================================================================================================================================================================== @@ -98,7 +253,7 @@ Removed in OpenFAST v3.1.0 Module Line Flag Name Example Value ============================================= ==== =============== ======================================================================================================================================================================================================== AeroDyn 21 FluidDepth 0.5 FluidDepth - Water depth above mid-hub height (m) [used only when CavitCheck=True] -ElastoDyn 7 N/A ---------------------- ENVIRONMENTAL CONDITION --------------------------------- +ElastoDyn 7 EnvCondSection ---------------------- ENVIRONMENTAL CONDITION --------------------------------- ElastoDyn 8 Gravity 9.80665 Gravity - Gravitational acceleration (m/s^2) ============================================= ==== =============== ======================================================================================================================================================================================================== @@ -303,13 +458,23 @@ Modified in OpenFAST v2.5.0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Module Line Flag Name / section Example Value ============================ ====== ================================================ ==================================================================================== -MoorDyn na added CtrlChan column in LINE PROPERTIES table .. code-block:: none - - Line LineType UnstrLen NumSegs NodeAnch NodeFair Outputs CtrlChan - (-) (-) (m) (-) (-) (-) (-) (-) - 1 main 835.35 20 1 4 - 0 +MoorDyn na added CtrlChan column in LINE PROPERTIES table ============================ ====== ================================================ ==================================================================================== +============== ====== =============== ============== ============================================================================================================================================================================= +Renamed in OpenFAST v2.5.0 +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Module Line Previous Name New Name Example Value +============== ====== =============== ============== ============================================================================================================================================================================= +InflowWind 17 Filename FileName_Uni "Shr11_30.wnd" FileName_Uni - Filename of time series data for uniform wind field. (-) +InflowWind 18 RefHt RefHt_Uni 90 RefHt_Uni - Reference height for horizontal wind speed (m) +InflowWind 21 Filename FileName_BTS "unused" FileName_BTS - Name of the Full field wind file to use (.bts) (-) +InflowWind 23 Filename FileNameRoot "unused" FileNameRoot - WindType=4: Rootname of the full-field wind file to use (.wnd, .sum); WindType=7: name of the intermediate file with wind scaling values +InflowWind 35 RefHt RefHt_Hawc 90 RefHt_Hawc - reference height; the height (in meters) of the vertical center of the grid (m) +InflowWind 47 PLExp PLExp_Hawc 0.2 PLExp_Hawc - Power law exponent (-) (used for PL wind profile type only) +InflowWind 49 InitPosition(x) XOffset 0 XOffset - Initial offset in +x direction (shift of wind box) +============== ====== =============== ============== ============================================================================================================================================================================= + OpenFAST v2.3.0 to OpenFAST v2.4.0 @@ -343,11 +508,6 @@ Modified in OpenFAST v2.4.0 Module Line New Flag Name Example Value Previous Flag Name/Value ============== ==== ================== ======================================================================================================================================================= ========================= AirFoilTables 40\* filtCutOff "DEFAULT" filtCutOff - Reduced frequency cut-off for low-pass filtering the AoA input to UA, as well as the 1st and 2nd deriv (-) [default = 0.5] [default = 20] -InflowWind 17 Filename_Uni "unused" Filename_Uni - Filename of time series data for uniform wind field. (-) Filename -InflowWind 18 RefHt_Uni 90 RefHt_Uni - Reference height for horizontal wind speed (m) RefHt -InflowWind 35 RefHt_Hawc 90 RefHt_Hawc - reference height; the height (in meters) of the vertical center of the grid (m) RefHt -InflowWind 47 PLExp_Hawc 0.2 PLExp_Hawc - Power law exponent (-) (used for PL wind profile type only) PLExp -InflowWind 49 XOffset 0 XOffset - Initial offset in +x direction (shift of wind box) InitPosition(x) ============== ==== ================== ======================================================================================================================================================= ========================= \*non-comment line count, excluding lines contained if NumCoords is not 0. diff --git a/docs/source/user/elastodyn/Makefile b/docs/source/user/elastodyn/Makefile new file mode 100644 index 000000000..684a7cb29 --- /dev/null +++ b/docs/source/user/elastodyn/Makefile @@ -0,0 +1,145 @@ +# Makefile for Sphinx documentation +# +MAIN=ElastoDyn +INKSCAPE=inkscape + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +CP = cp -r +CP = copy /Y + +# 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/* + +builddir: _build + +pdf: builddir latex pdf-compile +# diff +# cd _build/latex && make all-pdf + +pdf-compile: + cd _build\latex && pdflatex $(MAIN).tex +# cd _build\latex && bibtex $(MAIN).aux +# 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) -D -o "$@" "$<" + +$(SVGOUTDIR)/%.png:$(SVGDIR)/%.svg + $(INKSCAPE) -D -d 300 -o "$@" "$<" + + +html: builddir + $(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) + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex + $(CP) figs _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." + +_build: + mkdir _build + diff --git a/docs/source/user/elastodyn/conf.py b/docs/source/user/elastodyn/conf.py new file mode 100644 index 000000000..bdd636a01 --- /dev/null +++ b/docs/source/user/elastodyn/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 + + +from sphinx.highlighting import PygmentsBridge +from pygments.formatters.latex import LatexFormatter + +class CustomLatexFormatter(LatexFormatter): + def __init__(self, **options): + super(CustomLatexFormatter, self).__init__(**options) + self.verboptions = r"formatcom=\footnotesize" + +PygmentsBridge.latex_formatter = CustomLatexFormatter + +#sys.path.append(os.path.abspath('_extensions/')) + +readTheDocs = os.environ.get('READTHEDOCS', None) == 'True' +sourcedir = sys.argv[-2] +builddir = sys.argv[-1] + +# -- 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'ElastoDyn' +filename = project.replace(' ','_') +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'] + +# 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 = '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 = [''] + + +# -- 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, '{}.tex'.format(filename), u'{} Documentation'.format(project), + 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, project, u'{} Documentation'.format(project), + [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, filename, u'{} Documentation'.format(project), + author, project, '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") + +# --- Prolog that will be included at the top of every rst file +# Here: defining the role :red: for html and latex +rst_prolog = r""" + +.. raw:: html + + + +.. raw:: latex + + + \makeatletter + \@ifundefined{DUrolered}{% + \newcommand{\DUrolered}[1]{{\color{red}{#1}}} + }{} + \makeatother + +.. role:: red + +""" diff --git a/docs/source/user/elastodyn/coordsys.rst b/docs/source/user/elastodyn/coordsys.rst new file mode 100644 index 000000000..b0f6abe85 --- /dev/null +++ b/docs/source/user/elastodyn/coordsys.rst @@ -0,0 +1,153 @@ +.. _ed_coordsys: + + +Coordinate systems +================== + +For the coordinates system not detailed in subsections below, please refer to the following references: + +- `FAST 7 Manual `_ + +- `Technical report `_ on FAST_AD and modeling of the UAE wind turbine (in section 3) + +- :download:`FASTCoordinateSystems.doc <../../../OtherSupporting/ElastoDyn/FASTCoordinateSystems.doc>`: + Documents the transformation matrices relating each coordinate system in OpenFAST. Unfortunately, there are no pictures in this document that diagram these coordinate systems. They can hopefully be visualized by means of the transformation matrices. + +.. _ed_rfrl_coordsys: + +Rotor-Furl coordinate system +---------------------------- +The rotor-furl DOF allows the user to model the +unusual configuration of a bearing that permits the +rotor and drivetrain to rotate about the yawing-portion +of the structure atop the tower. The rotor-furl DOF can +alternatively be used to model torsional flexibility in +the gearbox mounting if the rotor-furl axis is aligned +with the rotor shaft axis. In order to include rotor- +furling in the model, the user must designate the turbine +as a furling machine by setting input ``Furling`` from the +primary input file to True. Then, the user must assemble +the furling input file, ``FurlFile``, and use the rotor-furl +flag, RFrlDOF, to enable this feature. +The angular rotor-furl motion takes place about the +rotor-furl axis defined by inputs: +``RFrlPnt_n``, +``RFrlSkew``, and ``RFrlTilt``. +available in FurlFile. +The input ``RFrlPnt_n`` locate an arbitrary point on the rotor- +furl axis relative to the tower-top. Inputs ``RFrlSkew`` +and ``RFrlTilt`` then define the angular orientation of the +rotor-furl axis passing through this point. +See :numref:`figTFAxes` for a schematic. + +The geometries of the hub and rotor-furl structure +mass center, which are both components of the furling- +rotor assembly, are defined relative to the tower-top as +shown in :numref:`figTFFurl`. +This definition was chosen in +order to avoid having to define a coordinate system in +the furling-rotor assembly since such a coordinate +system would most likely have an obscure orientation, +making it difficult for users to input configuration +information relative to it. This definition also avoids +the complications involved in having to define +geometries differently, depending on whether or not a +rotor-furl assembly exists separately from the nacelle, +which depends on whether rotor-furl is present or +absent in the turbine. + +Since the component geometry of the furling-rotor +assembly is defined relative to the tower-top, this +geometry naturally changes with the rotor-furl angle. +In order to avoid having to define different geometries +for different rotor-furl positions (for example, +variations in the initial rotor-furl angle), ElastoDyn expects +the component geometry of the furling-rotor assembly +to be defined/input at a rotor-furl angle of zero. As +such, the initial rotor-furl angle does not affect the +specification of any other rotor-furl geometry. Stated +another way, the input geometries for the rotor-furl +assembly components define the rotor configuration +when the rotor-furl angle is zero regardless of initial +rotor-furl position. Users should be clear of this +convention when assembling their furling input file. + +.. _ed_tfrl_coordsys: + +Tail-Furl coordinate system +--------------------------- +The tail-furl DOF allows the user to model the unusual +configuration of a bearing that permits the tail to rotate +about the yawing-portion of the structure atop the +tower. In order to include tail-furling in a model, +the user must designate the turbine as a furling machine by +setting the input ``Furling`` from the ElastoDyn input file to +True. Then you must assemble the furling input file, +``FurlFile``, and use the tail-furl flag, ``TFrlDOF``, to enable +this feature. +The angular tail-furl motion takes place about the +tail-furl axis defined by inputs ``TFrlPnt_n``, ``TFrlSkew``, and ``TFrlTilt`` available in +``FurlFile``. +The input ``TFrlPnt_n`` locate an arbitrary point on the tail-furl axis +relative to the tower-top. +See :numref:`figTFAxes` for a schematic. + + +The geometries of the tail boom mass center, tail +fin mass center, and tail fin aerodynamic surface, +which are all components of the furling-tail assembly, +are defined relative to the tower-top as shown in :numref:`figTFGeom`. +This definition was chosen in order to avoid +having to define a coordinate system in the furling-tail +assembly since such a coordinate system would most +likely have an obscure orientation, making it difficult +for users to input configuration information relative to +it. This definition also avoids the complications +involved in having to define geometries differently, +depending on whether or not a tail-furl assembly exists +separately from the nacelle, which depends on whether +tail-furl is present or absent in the turbine. + +Since the component geometry of the furling-tail +assembly is defined relative to the tower-top, this +geometry naturally changes with the tail-furl angle. In +order to avoid having to define different geometries for +different tail-furl positions (for example, variations in +the initial tail-furl angle), ElastoDyn expects the component +geometry of the furling-tail assembly to be +defined/input at a tail-furl angle of zero. As such, the +initial tail-furl angle does not affect the specification of +any other tail-furl geometry. Stated another way, the +input geometries for the tail-furl assembly components +define the tail configuration when the tail-furl angle is +zero regardless of initial tail-furl position. Users +should be clear of this convention when assembling +their furling input file. Further clarification on this +furling geometry convention is provided in the Rotor- +Furl section above. + + + +.. _figTFAxes: +.. figure:: figs/TailFinAxes.png + :width: 70% + + Layout of a three-bladed, upwind, furling turbine: furl axes + + +.. _figTFFurl: +.. figure:: figs/TailFinFurl.png + :width: 70% + + Layout of a three-bladed, upwind, furling turbine: rotor-furl structure + + +.. _figTFGeom: +.. figure:: figs/TailFinGeom.png + :width: 70% + + Layout of a three-bladed, upwind, furling turbine: tail-furl structure. + NOTE: The tail fin "CP" (center of pressure) parameters are now replaced by the location of the reference point. + + + diff --git a/docs/source/user/elastodyn/figs/TailFinAxes.png b/docs/source/user/elastodyn/figs/TailFinAxes.png new file mode 100644 index 0000000000000000000000000000000000000000..5d4eee49934bf74a2cfff311659a7374dbdadd32 GIT binary patch literal 165015 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

5|Gr}ZKcnAfU-?XY41E&XuLjwxG)z&NsezF<0{ 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%0Ai%>mwJuKRU;64Qmr`%_4v5N8XY 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%0DcmcBIA5+83sU)@8c=9_ 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≧̸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

d4N{$K*Yu;wVZp>ww0*yF&>hp8`6?GkU8PuB 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°cbW4&?ssevATUV9&v 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 z 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%0AMD5ZGc3jxMVrz3;0|&tm1Ezn!idX~%w33LEQO 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 ZnDNW9g_TSV&w>Bs?<&a@Nf|%;e*hfB#E1X@ literal 0 HcmV?d00001 diff --git a/docs/source/user/elastodyn/index.rst b/docs/source/user/elastodyn/index.rst index 1cec77ef7..c95aecd40 100644 --- a/docs/source/user/elastodyn/index.rst +++ b/docs/source/user/elastodyn/index.rst @@ -1,3 +1,6 @@ + +.. _ed_intro: + ElastoDyn Users Guide and Theory Manual ======================================= @@ -52,4 +55,6 @@ equations of FAST v7 and the ElastoDyn module of FAST v8 and OpenFAST. .. toctree:: + coordsys.rst input.rst + theory.rst diff --git a/docs/source/user/elastodyn/input.rst b/docs/source/user/elastodyn/input.rst index 1a96273ee..97d165184 100644 --- a/docs/source/user/elastodyn/input.rst +++ b/docs/source/user/elastodyn/input.rst @@ -134,7 +134,7 @@ Turbine Configuration **Delta3** - Delta-3 angle for teetering rotors (degrees) [unused for 3 blades] -**AzimB1Up** - Azimuth value to use for I/O when blade 1 points up (degrees) +**AzimB1Up** - Azimuth value to use for I/O when blade 1 points up (degrees); for floating MHK turbines, blade 1 will be pointed up (opposite gravity) when `AzimB1Up` = 0; the user can set `AzimB1Up` to 180 degrees to give the same azimuth convention relative to the tower for floating MHK turbines as for fixed MHK turbines **OverHang** - Distance from yaw axis to rotor apex [3 blades] or teeter pin [2 blades] (meters) @@ -146,27 +146,27 @@ Turbine Configuration **NacCMyn** - Lateral distance from the tower-top to the nacelle CM (meters) -**NacCMzn** - Vertical distance from the tower-top to the nacelle CM (meters) +**NacCMzn** - Vertical distance from the tower-top to the nacelle CM, typically negative for floating MHK turbines (meters) **NcIMUxn** - Downwind distance from the tower-top to the nacelle IMU (meters) **NcIMUyn** - Lateral distance from the tower-top to the nacelle IMU (meters) -**NcIMUzn** - Vertical distance from the tower-top to the nacelle IMU (meters) +**NcIMUzn** - Vertical distance from the tower-top to the nacelle IMU, typically negative for floating MHK turbines (meters) -**Twr2Shft** - Vertical distance from the tower-top to the rotor shaft (meters) +**Twr2Shft** - Vertical distance from the tower-top to the rotor shaft, typically negative for floating MHK turbines (meters) -**TowerHt** - Height of tower above ground level [onshore] or MSL [offshore] (meters) +**TowerHt** - Height of tower relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] (meters) -**TowerBsHt** - Height of tower base above ground level [onshore] or MSL [offshore] (meters) +**TowerBsHt** - Height of tower base relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] (meters) -**PtfmCMxt** - Downwind distance from the ground level [onshore] or MSL [offshore] to the platform CM (meters) +**PtfmCMxt** - Downwind distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM (meters) -**PtfmCMyt** - Lateral distance from the ground level [onshore] or MSL [offshore] to the platform CM (meters) +**PtfmCMyt** - Lateral distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM (meters) -**PtfmCMzt** - Vertical distance from the ground level [onshore] or MSL [offshore] to the platform CM (meters) +**PtfmCMzt** - Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM (meters) -**PtfmRefzt** - Vertical distance from the ground level [onshore] or MSL [offshore] to the platform reference point (meters) +**PtfmRefzt** - Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform reference point (meters) @@ -222,8 +222,6 @@ Rotor-Teeter **TeetDmp** - Rotor-teeter damping constant (N-m/(rad/s)) [used only for 2 blades and when TeetMod=1] -**TeetCDmp** - Rotor-teeter rate-independent Coulomb-damping moment (N-m) [used only for 2 blades and when TeetMod=1] - **TeetSStP** - Rotor-teeter soft-stop position (degrees) [used only for 2 blades and when TeetMod=1] **TeetHStP** - Rotor-teeter hard-stop position (degrees) [used only for 2 blades and when TeetMod=1] @@ -253,6 +251,8 @@ Furling **Furling** - Read in additional model properties for furling turbine (flag) [must currently be FALSE) **FurlFile** - Name of file containing furling properties (quoted string) [unused when Furling=False] +An example of furling input file is given in :numref:`TF_ed_input-file`. + Tower @@ -297,7 +297,7 @@ format specifiers. **DecFact** [-] This parameter sets the decimation factor for output. ElastoDyn will output data to **OutFile** only once each DecFact integration time steps. -For instance, a value of 5 will cause FAST to generate output only every fifth +For instance, a value of 5 will cause ElastoDyn to generate output only every fifth time step. This value must be an integer greater than zero. **NTwGages** [-] The number of strain-gage locations along the tower indicates @@ -359,3 +359,425 @@ for a complete list of possible output parameters. .. _ED-Nodal-Outputs: .. include:: EDNodalOutputs.rst + + + + + + +.. _TF_ed_input-file: + +ElastoDyn furl input file +------------------------- + +This section describes the furl input file indicated by the input ``FurlFile`` from the ElastoDyn input file. +OpenFAST will only read this file if the model is designated as a furling machine (when Furling from the primary input +file is set to True). +The input file defines the geometry and stuctural properties of the rotor-furl and tail-furl. + +The rotor-furl and tail-turl coordinate systems and the geometrical inputs are described in +:numref:`ed_rfrl_coordsys` and +:numref:`ed_tfrl_coordsys`, respectively. + +An example of ElastoDyn furl input file is provided below: + +.. code:: + + ---------------------- FAST FURLING FILE --------------------------------------- + Comment + ---------------------- FEATURE FLAGS (CONT) ------------------------------------ + False RFrlDOF - Rotor-furl DOF (flag) + True TFrlDOF - Tail-furl DOF (flag) + ---------------------- INITIAL CONDITIONS (CONT) ------------------------------- + 0.0 RotFurl - Initial or fixed rotor-furl angle (deg) + 0.0 TailFurl - Initial or fixed tail-furl angle (deg) + ---------------------- TURBINE CONFIGURATION (CONT) ---------------------------- + 0.1 Yaw2Shft - Lateral distance from the yaw axis to the rotor shaft (m) + 0.0 ShftSkew - Rotor shaft skew angle (deg) + 0., 0., 0. RFrlCM_n - Position of the CM of the structure that furls with the rotor [not including rotor] from the tower-top, in nacelle coordinates (m) + 1.7,0.1,0. BoomCM_n - Postion of the tail boom CM from the tower top, in nacelle coordinates (m) + 0., 0., 0. TFinCM_n - Position of tail fin CM from the tower top, in nacelle coordinates (m) + 0., 0., 0. RFrlPnt_n - Position of an arbitrary point on the rotor-furl axis from the tower top, in nacelle coordinates (m) + 0.0 RFrlSkew - Rotor-furl axis skew angle (deg) + 0.0 RFrlTilt - Rotor-furl axis tilt angle (deg) + 0.3, 0., 0. TFrlPnt_n - Position of an arbitrary point on the tail-furl axis from the tower top, in nacelle coordinates (m) + -45.2 TFrlSkew - Tail-furl axis skew angle (deg) + 78.7 TFrlTilt - Tail-furl axis tilt angle (deg) + ---------------------- MASS AND INERTIA (CONT) --------------------------------- + 0.0 RFrlMass - Mass of structure that furls with the rotor [not including rotor] (kg) + 86.8 BoomMass - Tail boom mass (kg) + 0.0 TFinMass - Tail fin mass (kg) + 0.0 RFrlIner - Inertia of the structure that furls with the rotor about the rotor-furl axis (kg m^2) [not including rotor] + 264.7 TFrlIner - Tail boom inertia about tail-furl axis (kg m^2) + ---------------------- ROTOR-FURL ---------------------------------------------- + 0 RFrlMod - Rotor-furl spring/damper model {0: none, 1: standard, 2:user-defined routine} (switch) + 0.0 RFrlSpr - Rotor-furl spring constant (N-m/rad) [used only when RFrlMod=1] + 0.0 RFrlDmp - Rotor-furl damping constant (N-m/(rad/s)) [used only when RFrlMod=1] + 0.0 RFrlUSSP - Rotor-furl up-stop spring position (deg) [used only when RFrlMod=1] + 0.0 RFrlDSSP - Rotor-furl down-stop spring position (deg) [used only when RFrlMod=1] + 0.0 RFrlUSSpr - Rotor-furl up-stop spring constant (N-m/rad) [used only when RFrlMod=1] + 0.0 RFrlDSSpr - Rotor-furl down-stop spring constant (N-m/rad) [used only when RFrlMod=1] + 0.0 RFrlUSDP - Rotor-furl up-stop damper position (deg) [used only when RFrlMod=1] + 0.0 RFrlDSDP - Rotor-furl down-stop damper position (deg) [used only when RFrlMod=1] + 0.0 RFrlUSDmp - Rotor-furl up-stop damping constant (N-m/(rad/s)) [used only when RFrlMod=1] + 0.0 RFrlDSDmp - Rotor-furl down-stop damping constant (N-m/(rad/s)) [used only when RFrlMod=1] + ---------------------- TAIL-FURL ----------------------------------------------- + 1 TFrlMod - Tail-furl spring/damper model {0: none, 1: standard, 2:user-defined routine} (switch) + 0.0 TFrlSpr - Tail-furl spring constant (N-m/rad) [used only when TFrlMod=1] + 10.0 TFrlDmp - Tail-furl damping constant (N-m/(rad/s)) [used only when TFrlMod=1] + 85.0 TFrlUSSP - Tail-furl up-stop spring position (deg) [used only when TFrlMod=1] + 3.0 TFrlDSSP - Tail-furl down-stop spring position (deg) [used only when TFrlMod=1] + 1.0E3 TFrlUSSpr - Tail-furl up-stop spring constant (N-m/rad) [used only when TFrlMod=1] + 1.7E4 TFrlDSSpr - Tail-furl down-stop spring constant (N-m/rad) [used only when TFrlMod=1] + 85.0 TFrlUSDP - Tail-furl up-stop damper position (deg) [used only when TFrlMod=1] + 0.0 TFrlDSDP - Tail-furl down-stop damper position (deg) [used only when TFrlMod=1] + 1.0E3 TFrlUSDmp - Tail-furl up-stop damping constant (N-m/(rad/s)) [used only when TFrlMod=1] + 137.0 TFrlDSDmp - Tail-furl down-stop damping constant (N-m/(rad/s)) [used only when TFrlMod=1] + + + + + + +*Feature Flags* + +**RFrlDOF** +The rotor-furl DOF will be enabled when this is True. The initial rotor-furl angle is specified with +RotFurl. If RFrlDOF is disabled, the rotor-furl angle will be fixed at RotFurl. (flag) + +**TFrlDOF** +The tail-furl DOF will be enabled when this is True. The initial tail-furl angle is specified with +TailFurl. If TFrlDOF is disabled, the tail-furl angle will be fixed at TailFurl. (flag) + + +*Initial Conditions* + +**RotFurl** +This is the fixed or initial rotor-furl angle. It is positive about the rotor-furl axis as shown in +:numref:`figTFAxes`. The rotor-furl axis is defined through input ``RFrlPnt_n`` +RFrlSkew, and RFrlTilt below. This value must be greater than -180 and less than or equal to +180 degrees. (deg) + +**TailFurl** +This is the fixed or initial tail-furl angle. It is positive about the tail-furl axis as shown in :numref:`figTFAxes`. +The tail-furl axis is defined through inputs ``TFrlPnt_n``, ``TFrlSkew``, +and ``TFrlTilt`` below. This value must be greater than -180 and less than or equal to 180 degrees. +(deg) + + + + +*Turbine Configuration* + +Inputs ``RFrlPnt_n``, ``RFrlSkew``, and ``RFrlTilt`` define the orientation of the rotor-furl axis and associated DOF, ``RFrlDOF``. +Inputs ``TFrlPnt_n``, ``TFrlSkew``, and ``TFrlTilt`` define the orientation of the tail-furl axis and associated DOF, ``TFrlDOF``. +See :numref:`figTFAxes`. + + +**Yaw2Shft** +This is the lateral offset distance from the yaw axis to the intersection of the rotor shaft axis with +the yn-/zn-plane. The distance is measured parallel to the yn-axis. It is positive to the left when +looking downwind as shown in :numref:`figTFFurl`. +For turbines with rotor-furl, this distance defines the configuration at a furl angle of zero. (m) + +**ShftSkew** +This is the skew angle of the rotor shaft in the nominally horizontal plane. Positive skew acts like +positive nacelle yaw as shown in :numref:`figTFFurl`; however, ``ShftSkew`` should only be used to skew the +shaft a few degrees away from the zero-yaw position and must not be used as a replacement for +the yaw angle. This value must be between -15 and 15 degrees (inclusive). +For turbines with rotor-furl, this angle defines the configuration at a furl angle of zero. (deg) + +**RFrlCM_n** +Position of the center of mass of the structure that furls with the rotor +(not including the rotor-reference input ``RFrlMass``) measured from the tower top +and expressed in the nacelle coordinate system. +See :numref:`figTFFurl`. +For turbines with rotor-furl, this position defines the configuration at a furl angle of zero. (m) + +**BoomCM_n** +Position of the tail boom mass center (reference input ``BoomMass``) with respect to the tower top, +expressed in the nacelle coordinate system. +See :numref:`figTFGeom`. +For turbines with tail-furl, this distance defines the configuration at a furl angle of zero. (m) + +**TFinCM_n** +Position of the tail fin mass center (reference input ``TFinMass``) with respect to the top, +expressed in the nacelle coordinate system. +See :numref:`figTFGeom`. +For turbines with tail-furl, this distance defines the configuration at a furl angle of zero. (m) + +**RFrlPnt_n** +Position of an arbitrary point on the rotor-furl axis expressed from the tower top and +in the nacelle coordinate system. +See :numref:`figTFAxes`. (m) + +**RFrlSkew** +This is the skew angle of the rotor-furl axis in the nominally horizontal plane. Positive skew +orients the nominal horizontal projection of the rotor-furl axis about the zn-axis. +See :numref:`figTFAxes`. +This value must be greater than -180 +and less than or equal to 180 degrees. (deg) + +**RFrlTilt** +This is the tilt angle of the rotor-furl axis from the nominally horizontal plane. +This value must be between -90 and 90 degrees (inclusive). +See :numref:`figTFAxes`. (deg) + +**TFrlPnt_n** +Position from the tower top to an arbitrary point on the tail-furl axis, in nacelle coordinates. +See :numref:`figTFAxes`. (m) + +**TFrlSkew** +This is the skew angle of the tail-furl axis in the nominally horizontal plane. +Positive skew orients the nominal horizontal projection of the tail-furl axis about the zn-axis. +See :numref:`figTFAxes`. +This value must be greater than -180 and less than or equal to 180 degrees. +(deg) + +**TFrlTilt** +This is the tilt angle of the tail-furl axis from the nominally horizontal plane. +See :numref:`figTFAxes`. +This value must be between -90 and 90 degrees (inclusive). +(deg) + + +*Mass and Inertia* + +**RFrlMass** +This is the mass of the structure that furls with the rotor (not including the rotor). The center of +this mass is located at the point specified by input ``RFrlCM_n`` +relative to the tower-top at a rotor-furl angle of zero. It includes everything that furls with the +rotor excluding the rotor (blades, hub, and tip brakes). This value must not be negative. (kg) + +**BoomMass** +This is the mass of the tail boom. The center of the tail boom mass is located at the point specified +by input ``BoomCM_n`` relative to the tower-top at a tail-furl angle +of zero. It includes everything that furls with the tail except the tail fin (see next input). This +value must not be negative. (kg) + +**TFinMass** +This is the mass of the tail fin. The center of the tail fin mass is located at the point specified by +input ``TFinCM_n`` relative to the tower-top at a tail-furl angle of +zero. TFinMass and BoomMass combined should include everything that furls with the tail. +This value must not be negative. (kg) + +**RFrlIner** +This is the moment of inertia of the structure that furls with the rotor (not including the rotor) +about the rotor-furl axis. It includes all mass contained in ``RFrlMass``. This value must be greater +than: ``RFrlMass*d^2`` where d is the perpendicular distance between rotor-furl axis and C.M. of the structure +that furls with the rotor [not including the rotor]. (kg·m2) + +**TFrlIner** +This is the tail boom moment of inertia about the tail-furl axis. It includes all mass contained in +BoomMass. This value must be greater than: ``BoomMass*d^2`` where d is the perpendicular distance between +tail-furl axis and tail boom C.M. (kg·m2) + + + +*Rotor-Furl* + + +The rotor-furl bearing can be an ideal bearing with +no friction by setting ``RFrlMod`` to 0; by setting +``RFrlMod`` to 1, it also has a standard model that +includes a linear spring and linear damper, +as well as up- and down-stop springs, and up- +and down-stop dampers. +The formulae are provided in :numref:`ed_rtfrl_theory`. +ElastoDyn models the stop +springs with a linear function of rotor-furl deflection. +The rotor-furl stops start at a specified angle and work +as a linear spring based on the deflection past the stop +angles. The rotor-furl dampers are linear functions of +the furl rate and start at the specified up-stop and +down-stop angles. These dampers are bidirectional, +resisting motion equally in both directions once past +the stop angle. + +A user-defined rotor-furl spring and damper model +is also available. To use it, set `RFrlMod` to 2 and +create a subroutine entitled `UserRFrl()` with the +parameters ``RFrlDef``, ``RFrlRate``, ``DirRoot``, ``ZTime``, and +``RFrlMom``: + +- ``RFrlDef``: Current rotor-furl angular deflection in radians (input) +- ``RFrlRate``: Current rotor-furl angular rate in rad/sec (input) +- ``ZTime``: Current simulation time in sec (input) +- ``DirRoot``: Simulation root name including the full path to the current working director (input) +- ``RFrlMom``: Rotor-furl moment in N·m (output) + +The source file ``ED_UserSubs.f90`` contains a dummy +``UserRFrl()`` routine; replace it with your own and +rebuild ElastoDyn. + + +**RFrlMod** +The rotor-furl springs and dampers can be modeled three ways. For a value of 0 for ``RFrlMod``, +there will be no rotor-furl spring nor damper and the moment normally produced will be set to +zero. A ``RFrlMod`` of 1 will invoke simple spring and damper models using the inputs provided +below as appropriate coefficients. If ``RFrlMod`` is set to 2, ElastoDyn will call the routine ``UserRFrl()`` +to compute the rotor-furl spring and damper moments. You should replace the dummy routine +supplied with the code with your own, which will need to be linked with the rest of ElastoDyn. Using +values other than 0, 1, or 2 will cause ElastoDyn to abort. (switch) + +**RFrlSpr** +The linear rotor-furl spring restoring moment is proportional to the rotor-furl deflection through +this constant. This value must not be negative and is only used when ``RFrlMod`` is set to 1. +(N·m/rad) + +**RFrlDmp** +The linear rotor-furl damping moment is proportional to the rotor-furl rate through this constant. +This value must not be negative and is only used when ``RFrlMod`` is set to 1. (N·m/(rad/s)) + +**RFrlCDmp** +This Coulomb-friction damping moment resists rotor-furl motion, but it is a constant that is not +proportional to the rotor-furl rate. However, if the rotor-furl rate is zero, the damping is zero. +This value must not be negative and is only used when ``RFrlMod`` is set to 1. (N·m) + +**RFrlUSSP** +The rotor-furl up-stop spring is effective when the rotor-furl deflection exceeds this value. This +value must be greater than -180 and less than or equal to 180 degrees and is only used when +``RFrlMod`` is set to 1. (deg) + +**RFrlDSSP** +The rotor-furl down-stop spring is effective when the rotor-furl deflection exceeds this value. This +value must be greater than -180 and less than or equal to ``RFrlUSSP`` degrees and is only used +when ``RFrlMod`` is set to 1. (deg) + +**RFrlUSSpr** +The linear rotor-furl up-stop spring restoring moment is proportional to the rotor-furl up-stop +deflection by this constant and is effective when the rotor-furl deflection exceeds ``RFrlUSSP``. +This value must not be negative and is only used when ``RFrlMod`` is set to 1. (N·m/rad) + +**RFrlDSSpr** +The linear rotor-furl down-stop spring restoring moment is proportional to the rotor-furl down- +stop deflection by this constant and is effective when the rotor-furl deflection exceeds ``RFrlDSSP``. +This value must not be negative and is only used when ``RFrlMod`` is set to 1. (N·m/rad) + +**RFrlUSDP** +The rotor-furl up-stop damper is effective when the rotor-furl deflection exceeds this value. This +value must be greater than -180 and less than or equal to 180 degrees and is only used when +``RFrlMod`` is set to 1. (deg) + +**RFrlDSDP** +The rotor-furl down-stop damper is effective when the rotor-furl deflection exceeds this value. +This value must be greater than -180 and less than or equal to ``RFrlUSDP`` degrees and is only +used when ``RFrlMod`` is set to 1. (deg) + +**RFrlUSDmp** +The linear rotor-furl up-stop damping moment is proportional to the rotor-furl rate by this constant +and is effective when the rotor-furl deflection exceeds ``RFrlUSDP``. This value must not be +negative and is only used when ``RFrlMod`` is set to 1. (N·m/(rad/s)) + +**RFrlDSDmp** +The linear rotor-furl down-stop damping restoring moment is proportional to the rotor-furl rate by +this constant and is effective when the rotor-furl deflection exceeds ``RFrlDSDP``. This value must +not be negative and is only used when ``RFrlMod`` is set to 1. (N·m/(rad/s)) + + + + + +*Tail-Furl* + + +The tail-furl bearing can be an ideal bearing with +no friction by setting ``TFrlMod`` to 0; by setting +``TFrlMod`` to 1, it also has a standard model that +includes a linear spring and damper , +as well as up- and down-stop springs, and up- +and down-stop dampers. +The formulae are provided in :numref:`ed_rtfrl_theory`. +ElastoDyn models the stop +springs with a linear function of tail-furl deflection. +The tail-furl stops start at a specified angle and work as +a linear spring based on the deflection past the stop +angles. The tail-furl dampers are linear functions of +the furl rate and start at the specified up-stop and +down-stop angles. These dampers are bidirectional, +resisting motion equally in both directions once past +the stop angle. + +A user-defined tail-furl spring and damper model +is also available. To use it, set ``TFrlMod`` to 2 and +create a subroutine entitled ``UserTFrl()`` with the +arguments ``TFrlDef``, ``TFrlRate``, ``ZTime``, ``DirRoot``, and +``TFrlMom``: + +- ``TFrlDef``: Current tail-furl angular deflection in radians (input) +- ``TFrlRate``: Current tail-furl angular rate in rad/sec (input) +- ``ZTime``: Current simulation time in sec (input) +- ``DirRoot``: Simulation root name including the full path to the current working directory (input) +- ``TFrlMom``: Tail-furl moment in N.m (output) + +The source file ``ED_UserSubs.f90`` contains a dummy +``UserTFrl()`` routine; replace it with your own and +rebuild ElastoDyn. + + +**TFrlMod** +The tail-furl springs and dampers can be modeled three ways. For a value of 0 for ``TFrlMod``, there +will be no tail-furl spring nor damper and the moment normally produced will be set to zero. A +``TFrlMod`` of 1 will invoke simple spring and damper models using the inputs provided below as +appropriate coefficients. If you set ``TFrlMod`` to 2, ElastoDyn will call the routine ``UserTFrl()`` to +compute the tail-furl spring and damper moments. You should replace the dummy routine +supplied with the code with your own, which will need to be linked with the rest of ElastoDyn. Using +values other than 0, 1, or 2 will cause ElastoDyn to abort. (switch) + +**TFrlSpr** +The linear tail-furl spring restoring moment is proportional to the tail-furl deflection through this +constant. This value must not be negative and is only used when ``TFrlMod`` is set to 1. (N·m/rad) + +**TFrlDmp** +The linear tail-furl damping moment is proportional to the tail-furl rate through this constant. This +value must not be negative and is only used when ``TFrlMod`` is set to 1. (N·m/(rad/s)) + +**TFrlCDmp** +This Coulomb-friction damping moment resists tail-furl motion, but it is a constant that is not +proportional to the tail-furl rate. However, if the tail-furl rate is zero, the damping is zero. This +value must not be negative and is only used when ``TFrlMod`` is set to 1. (N·m) + +**TFrlUSSP** +The tail-furl up-stop spring is effective when the tail-furl deflection exceeds this value. This value +must be greater than -180 and less than or equal to 180 degrees and is only used when ``TFrlMod`` is +set to 1. (deg) + +**TFrlDSSP** +The tail-furl down-stop spring is effective when the tail-furl deflection exceeds this value. This +value must be greater than -180 and less than or equal to ``TFrlUSSP`` degrees and is only used +when ``TFrlMod`` is set to 1. (deg) + +**TFrlUSSpr** +The linear tail-furl up-stop spring restoring moment is proportional to the tail-furl up-stop +deflection by this constant and is effective when the tail-furl deflection exceeds ``TFrlUSSP``. This +value must not be negative and is only used when ``TFrlMod`` is set to 1. (N·m/rad) + +**TFrlDSSpr** +The linear tail-furl down-stop spring restoring moment is proportional to the tail-furl down-stop +deflection by this constant and is effective when the tail-furl deflection exceeds ``TFrlDSSP``. This +value must not be negative and is only used when ``TFrlMod`` is set to 1. (N·m/rad) + +**TFrlUSDP** +The tail-furl up-stop damper is effective when the tail-furl deflection exceeds this value. This +value must be greater than -180 and less than or equal to 180 degrees and is only used when +``TFrlMod`` is set to 1. (deg) + +**TFrlDSDP** +The tail-furl down-stop damper is effective when the tail-furl deflection exceeds this value. This +value must be greater than -180 and less than or equal to ``TFrlUSDP`` degrees and is only used +when ``TFrlMod`` is set to 1. (deg) + +**TFrlUSDmp** +The linear tail-furl up-stop damping moment is proportional to the tail-furl rate by this constant +and is effective when the tail-furl deflection exceeds ``TFrlUSDP``. This value must not be negative +and is only used when ``TFrlMod`` is set to 1. (N·m/(rad/s)) + +**TFrlDSDmp** +The linear tail-furl down-stop damping restoring moment is proportional to the tail-furl rate by this +constant and is effective when the tail-furl deflection exceeds ``TFrlDSDP``. This value must not be +negative and is only used when ``TFrlMod`` is set to 1. (N·m/(rad/s)) + + + + + diff --git a/docs/source/user/elastodyn/theory.rst b/docs/source/user/elastodyn/theory.rst new file mode 100644 index 000000000..f68727733 --- /dev/null +++ b/docs/source/user/elastodyn/theory.rst @@ -0,0 +1,191 @@ +.. _ed_theory: + + +ElastoDyn Theory +================ + +Note this document is work in progress and is greatly incomplete. +This documentation was started to document some code changes to the the tail furl and rotor furl part of ElastoDyn. +Please refer to the different ressources provided in :numref:`ed_intro` for additional documents. + + + +Notations +--------- + +**Points** + +The following (partial) list of points are defined by ElastoDyn: + +- ``Z``: the platform reference point +- ``O``: the tower-top/base plate point +- ``W``: the specified point on the tail-furl axis +- ``I``: the tail boom center of mass +- ``J``: the tail fin center of mass + +**Bodies** + +The following (partial) list of bodies are defined by ElastoDyn: + +- ``E``: the earth/inertial frame +- ``X``: the platform body +- ``N``: the nacelle body +- ``A``: the tail-furl body + + + + + +Kinematics +---------- + + +ElastoDyn computes the position, velocity and accelerations of key points of the structure, starting from the platform reference point `Z` and going up in the structure. + +The different position vectors are available in the data stucture ``RtHSdat``. +For instance, the global position of point J is given by: + +.. math:: :label: TFPointJPos + + \boldsymbol{r}_J = \boldsymbol{r}_Z + \boldsymbol{r}_{ZO} + \boldsymbol{r}_{OW} + \boldsymbol{r}_{WJ} + +The translational displacement vector (how much a point has moved compared to its reference position) is calculated as follows: :math:`\boldsymbol{r}_J-\boldsymbol{r}_{J,\text{ref}}`. + + +The coordinate systems of ElastoDyn are stored in the variable ``CoordSys``. +The orientation matrix of a given coordinate system can be formed using the unit vectors (assumed to be column vectors) of a given coordinate system expressed in the inertial frame. +For instance for the tailfin coordinate system: + +.. math:: :label: TFPointJOrientation + + \boldsymbol{R}_{Ai} = \begin{bmatrix} + \left.\boldsymbol{\hat{x}_\text{tf}^t}\right|_i \\ + \left.\boldsymbol{\hat{y}_\text{tf}^t}\right|_i \\ + \left.\boldsymbol{\hat{z}_\text{tf}^t}\right|_i \\ + \end{bmatrix} + + +Angular velocities are stored in variables ``RtHSdat%AngVelE*`` with respect to the initial frame ("Earth", `E`). +For instance, the angular velocity of the tail-furl body (body `A`) is: + +.. math:: :label: TFPointJAngVel + + \boldsymbol{\omega}_{A/E} = \boldsymbol{\omega}_{X/E} + \boldsymbol{\omega}_{N/X} + \boldsymbol{\omega}_{A/N} + +where :math:`\boldsymbol{\omega}_{N/X}=\boldsymbol{\omega}_{B/X}+\boldsymbol{\omega}_{N/B}` + + + +Linear (translational) velocities of the different points are found in the variables ``RtHSdat%LinVelE*``, and are computed based on Kane's partial velocities (which are Jacobians of the velocity with respect to the time derivatives of the degrees of freedom). +For instance, the linear velocity of point J is computed as: + +.. math:: :label: TFPointJVel + + \boldsymbol{v}_J = \sum_{j} \frac{\partial v_J}{\partial \dot{q}_j} \dot{q}_j + +where the Jacobians :math:`\frac{\partial v_J}{\partial \dot{q}_j}` are stored in ``RtHSdat%PLinVelEJ(:,0)`` + + + + +Translational accelerations are computed as the sum of contribution from the first and second time derivatives of the degrees of freedom. +For instance, the acceleration of point `J` is computed as: + +.. math:: :label: TFPointJAng + + \boldsymbol{\tilde{a}}_J &= \sum_{j\in PA} \frac{\partial a_J}{\partial \dot{q}_j} \dot{q}_j + + \boldsymbol{a}_J &= \boldsymbol{\tilde{a}}_J + \sum_{j\in PA} \frac{\partial v_J}{\partial \dot{q}_j} \ddot{q}_j + + +where :math:`\frac{\partial a_J}{\partial \dot{q}_j}` are stored in ``RtHSdat%PLinVelEJ(:,1)`` + +Angular accelerations requires similar computations currently not documented. + + + +.. _ed_rtfrl_theory: + +Rotor and tail furl +------------------- + +The user can select linear spring and damper models, together with +up- and down-stop springs, and up- and down-stop dampers. + +The torque applied from the linear spring and damper is: + +.. math:: :label: TFLinTorque + + Q_\text{lin} = - k \theta - d \dot{\theta} + +where :math:`\theta` is the degree of freedom (rotor or tail furl), +:math:`k` is the linear spring constant (``RFrlSpr`` or ``TFrlSpr``) +:math:`d` is the linear damping constant (``RFrlDmp`` or ``TFrlDmp``). + +The up-/down- stop spring torque is defined as: + +.. math:: :label: TFStopTorqueSpring + + Q_\text{stop, spr} = \begin{cases} + - k_{US} (\theta-\theta_{k_{US}}),&\text{if } \theta>\theta_{k_{US}} \\ + - k_{DS} (\theta-\theta_{k_{DS}}),&\text{if } \theta<\theta_{k_{DS}} \\ + 0 ,&\text{otherwise} + \end{cases} + +where +:math:`k_{US}` is the up-stop spring constant (``RFrlUSSpr`` or ``TFrlUSSpr``), +:math:`\theta_{k_{US}}` is the up-stop spring angle (``RFrlUSSP`` or ``TFrlUSSP``), +and similar notations are used for the down-stop spring. + +The up-/down- stop damping torque is defined as: + +.. math:: :label: TFStopTorqueDamp + + Q_\text{stop, dmp} = \begin{cases} + - d_{US} \dot{\theta},&\text{if } \theta>\theta_{d_{US}} \\ + - d_{DS} \dot{\theta},&\text{if } \theta<\theta_{d_{DS}} \\ + 0 ,&\text{otherwise} + \end{cases} + +where similar nnotations are used. +The total moment on the given degree of freedom is: + +.. math:: :label: TFTotTorque + + Q = Q_\text{lin} + Q_\text{stop,spr} + Q_\text{stop,dmp} + + + + + + + + + +.. _ed_dev_notes: + + +Developer notes +=============== + + +**Internal coordinate systems** + +The different coordinate systems of ElastoDyn are stored in the variable ``CoordSys``. +The coordinate systems used internally by ElastoDyn are using a different convention than the OpenFAST input/output coordinate system. + +For instance, for the coordinate system of the nacelle, with unit axes noted :math:`x_n,y_n,z_n` in OpenFAST, and :math:`d_1,d_2,d_3` in ElastoDyn, the following conversions apply: +:math:`d_1 = x_n`, +:math:`d_2 =z_n` and +:math:`d_3 =-y_n`. + +The following (partial) list of coordinate systems are defined internally by ElastoDyn: + +- `z` : inertial coordinate system +- `a` : tower base coordinate system +- `t` : tower-node coordinate system (one per node) +- `d` : nacelle coordinate system +- `c` : shaft-tilted coordinate system +- `rf` : rotor furl coordinate system +- `tf` : tail furl coordinate system +- `g` : hub coordinate system diff --git a/docs/source/user/fast.farm/AppendixC.rst b/docs/source/user/fast.farm/AppendixC.rst index 18879e0c6..458fe8430 100644 --- a/docs/source/user/fast.farm/AppendixC.rst +++ b/docs/source/user/fast.farm/AppendixC.rst @@ -47,6 +47,7 @@ to entry :math:`\gamma` in the **OutDist** list. Setting :math:`\gamma` calculated or for any distance where the wake from the turbine has overlapped itself. + .. container:: :name: Tab:FF:Outputs @@ -92,11 +93,32 @@ overlapped itself. | | | induction or wakes from upstream turbines) for | | | | turbine :math:`\alpha` | +--------------------------------------------------------------+-------------------+-------------------------------------------------+ + | RtVAmbFiltT\ :math:`\alpha` | (m/s) | Time-filtered value of RtVAmbT:math:`\alpha` | + | | | for turbine :math:`\alpha` | + +--------------------------------------------------------------+-------------------+-------------------------------------------------+ + | AxiSkewT\ :math:`\alpha` | (deg) | Skew azimuth angle (used in curled-wake model) | + | | | for turbine :math:`\alpha` | + +--------------------------------------------------------------+-------------------+-------------------------------------------------+ + | AxiSkewFiltT\ :math:`\alpha` | (deg) | Time-filtered value of AxiSkewT:math:`\alpha` | + | | | for turbine :math:`\alpha` | + +--------------------------------------------------------------+-------------------+-------------------------------------------------+ + | RtSkewT\ :math:`\alpha` | (deg) | Skew angle (used in curled-wake model) | + | | | for turbine :math:`\alpha` | + +--------------------------------------------------------------+-------------------+-------------------------------------------------+ + | RtSkewFiltT\ :math:`\alpha` | (deg) | Time-filtered value of RtSkewT:math:`\alpha` | + | | | for turbine :math:`\alpha` | + +--------------------------------------------------------------+-------------------+-------------------------------------------------+ + | RtGamCurlT\ :math:`\alpha` | (m^2/s) | Rotor circulation (used in curled-wake model) | + | | | for turbine :math:`\alpha` | + +--------------------------------------------------------------+-------------------+-------------------------------------------------+ | RtVRelT\ :math:`\alpha` | (m/s) | Rotor-disk-averaged relative wind speed (normal | | | | to disk, including structural motion and wakes | | | | from upstream turbines, but not including local | | | | induction) for turbine :math:`\alpha` | +--------------------------------------------------------------+-------------------+-------------------------------------------------+ + | RtCtAvgT\ :math:`\alpha` | (-) | Rotor-disk-averaged thrust coefficient | + | | | for turbine :math:`\alpha` | + +--------------------------------------------------------------+-------------------+-------------------------------------------------+ | CtT\ :math:`\alpha`\ N\ :math:`\beta` | (-) | Azimuthally averaged thrust force coefficient | | | | (normal to disk) for radial output node | | | | :math:`\beta` of turbine :math:`\alpha` | diff --git a/docs/source/user/fast.farm/FFarmTheory.rst b/docs/source/user/fast.farm/FFarmTheory.rst index 57e1a5b16..893ffe03c 100644 --- a/docs/source/user/fast.farm/FFarmTheory.rst +++ b/docs/source/user/fast.farm/FFarmTheory.rst @@ -552,12 +552,44 @@ overwritten by the user of FAST.Farm. The wake-deficit evolution is solved in discrete time on an axisymmetric finite-difference grid consisting of a fixed number of wake planes, :math:`N_p` (with :math:`n_p` the wake-plane counter such that -:math:`0\le n_p\le N_p-1`), each with a fixed radial grid of nodes. -Because the wake deficit is assumed to be axisymmetric, the radial -finite-difference grid can be considered a plane. A wake plane can be +:math:`0\le n_p\le N_p-1`). +A wake plane can be thought of as a cross section of the wake wherein the wake deficit is calculated. + +Three wake formulations are available forthe evolution of the wake planes. +The parameter **Mod_Wake** is used to switch between wake formulations. +There are three options available: + +1) Polar [**Mod_Wake=1**] (default). +The wake is axi-symmetric, defined on a polar grid, +solved using an implicit Crank-Nicolson scheme, +satisfying both the momentum and mass conservation laws under a shear layer approximation. +Each plane has a fixed radial grid of nodes. +Because the wake deficit is assumed to be axisymmetric, the radial +finite-difference grid can be considered a plane. + +2) Curled-wake model [**Mod_Wake=2**]. +The wake is defined on a Cartesian grid, +the effect of curled wake vorticies in skewed inflow is accounted for by introducing cross-flow velocities, the momentum conservation is solved using a first-order forward Euler scheme, +mass conservation is not enforced, the effect of wake swirl may be accounted for. +Each plane has a fixed number of nodes in the y and z direction (of the meandering frame). +The wake will adopt a "curled" shape in skewed inflow. + +3) Cartesian [**Mod_Wake=3**] +This corresponds to model 2 with curled-wake vortices of zero intensities, leading to an axi-symmetric wake. +Swirl effects can be included in this formulation. + +Because the Curl and Cartesian implementations rely on a first-order forward sheme, the implementation is less robust that the Polar implementation. +An approximate stability criterion for the curled-wake model is given in Equation 20 of the following `paper `__). This criterion was adapted to provide the guidelines on **dr** and **DT_Low** given in :numref:`FF:ModGuidance`. + + +The curled-wake model implementation is described in the following `reference `__. + +**The rest of this documentation concerns the Polar fomulation**. + + Inputs to the *WD* module include :math:`\hat{x}^\text{Disk}`, :math:`\vec{p}^\text{Hub}`, :math:`D^\text{Rotor}`, :math:`\gamma^\text{YawErr}`, :math:`^\text{DiskAvg}V_x^\text{Rel}`, and diff --git a/docs/source/user/fast.farm/InputFiles.rst b/docs/source/user/fast.farm/InputFiles.rst index 8b353e282..6bae9fefa 100644 --- a/docs/source/user/fast.farm/InputFiles.rst +++ b/docs/source/user/fast.farm/InputFiles.rst @@ -34,6 +34,8 @@ sections: - Super Controller +- Shared Moorings + - Ambient Wind - Wind Turbines @@ -95,6 +97,15 @@ ambient wind data as defined by the FAST.Farm interface to the **[Mod_AmbWind=3]**. The distinct Ambient Wind subsections below pertain to each option. +**Mod_WaveField** [switch] indicates how the wave field should be treated. The +two options are: 1) use individual HydroDyn inputs at each turbine without +adjustment, 2) adjust wave phases based on turbine offsets from wind farm +origin. + +**Mod_SharedMooring** [switch] indicates if a farm level mooring line system +interconnects turbines. There are presently two options: 0) No shared moorings, +3) MoorDyn. + Super Controller ~~~~~~~~~~~~~~~~ @@ -108,6 +119,25 @@ turbine controllers defined in the style of the DISCON dynamic library of the DNV GL’s Bladed wind turbine software package, with minor modification. See :numref:`FF:sec:SupCon` for more information. +Shared Moorings +~~~~~~~~~~~~~~~ + +Shared mooring lines running between platforms introduce a coupling between the +platforms that operates on the same time scales as a platform's interaction with +a regular mooring system (typically resolved at a time step of 10--30 ms in +OpenFAST simulations). See :numref:`MoorDyn` for more information. + +**SharedMoorFile** [quoted string] sets the name and location of the MoorDyn +input file for the mooring lines in the wind farm. It is only used if +**Mod_SharedMooring** = 3. **The file name must be in quotations** and can +contain an absolute or a relative path. The mooring lines then connect to each +of the wind turbines in the farm. See `MoorDyn with FAST.Farm +`_ +documentation for details on the input file at the farm level. + +**DT_Mooring** (sec) sets the timestep for the shared mooring connections with +MoorDyn. + .. _FF:Input:VTK: Ambient Wind: Precursor in Visualization Toolkit Format @@ -213,6 +243,11 @@ low-resolution ambient wind calculation, as well as the global called every **DT_Low** seconds, although OpenFAST and its modules may choose to use a time step that is an integer multiple smaller than or equal to **DT_Low**. +When **Wake_Mod=2,3**, the stability of the algorithm will depend on the choice +of **dr** and **DT_Low**. +(typically :math:`\textbf{DT_Low} \lessapprox \textbf{dr}/(2V_\text{Hub})`, +see :numref:`FF:ModGuidance`) + **DT_High** [sec] sets the time step of the high-resolution ambient wind data calculation and must be an integer multiple smaller than or equal @@ -354,16 +389,43 @@ grid, as shown in :numref:`FF:RadialFD`. number and size of the wake planes are shown smaller than they should be. -These planes are defined by the following parameters: + +Three wake formulations are available (see :numref:`FF:Theory` for more details): + +**Mod_Wake** [switch] is used to switch between wake formulations. +There are three options available: +1) Polar [**Mod_Wake=1**] (default); +the wake is axi-symmetric, defined on a polar grid, +solved using an implicit Crank-Nicolson scheme, +satisfying both the momentum and mass conservation laws under a shear layer approximation. +2) Curled-wake model [**Mod_Wake=2**]; +the wake is defined on a Cartesian grid, +the effect of curled wake vorticies in skewed inflow is accounted for by introducing cross-flow velocities, the momentum conservation is solved using a first-order forward Euler scheme, +mass conservation is not enforced, the effect of wake swirl may be accounted for. +The wake will adopt a "curled" shape in skewed inflow. +3) Cartesian [**Mod_Wake=3**]; corresponds to model 2 with curled-wake vortices of zero intensities, leading to an axi-symmetric wake. + +When Wake_Mod=2,3, the stability of the algorithm will depend on the choice of **dr** and **DT_Low** (see the guidelines (see the guidelines given in :numref:`FF:ModGuidance`). + + + + +The wake planes are defined by the following parameters: - **dr** [m] sets the radial increment. To ensure the wake deficits are accurately computed by FAST.Farm, **dr** should be set so that FAST.Farm sufficiently resolves the wake deficit within each plane. + When a cartesian grid is used (**Mod_Wake=2 or 2**), **dr** represents the + spacing in the y and z direction of the plane. + When **Wake_Mod=2,3**, the stability of the algorithm will depend on the choice + of **dr** and **DT_Low** (see the guidelines given in :numref:`FF:ModGuidance`). - **NumRadii** [integer] (:math:`N_r`) sets the number of radii. To ensure the wake deficits are accurately computed by FAST.Farm, **NumRadii** should be set so that the diameter of each wake plane, 2(**NumRadii**-1)\ **dr**, is large relative to the rotor diameter. + When a Cartesian grid is used, the y and z coordinates extend from + (-NumRaddi+1)*dr to (NumRadii-1)*dr. - **NumPlanes** [integer] (:math:`N_p`) sets the number of wake planes. To ensure the wake deficits are accurately captured by FAST.Farm, @@ -382,8 +444,23 @@ user. **f_c** [Hz] (:math:`f_c`) is the cutoff (corner) frequency of the low-pass time filter for the wake advection, deflection, and meandering -model and must be greater than zero. If the DEFAULT keyword is specified -in place of a numerical value, **f_c** is set to :math:`0.0007`. +model and must be greater than zero. +Preferably the filter constant should be set as follows: + +.. math:: :label: fffc + + \tau_1=\frac{1.1}{1-1.3 \operatorname{min}(a_\text{avg}, 0.5)} \frac{R}{U_\infty} , \qquad f_c = \frac{2.4}{\tau_1} + +where +:math:`\tau_1` is a time scale similar to the one used in the Oye dynamic inflow model and +:math:`a_\text{avg}` is the average axial induction factor across the rotor disk. +If the DEFAULT keyword is specified in place of a numerical value, **f_c** is set to :math:`12.5/R_\text{est}` Hz +which corresponds to :math:`U=10` m/s, :math:`a=1/3` in the equation above, and +where the estimated rotor radius is obtained as: :math:`R_\text{est} = (dr * NumRadii) / 3`. +Changing the grid resolution will change the estimated radius, therefore it is recommended to set a numerical +value for **f_c** directly instead of using DEFAULT. +If numerical issues occur, you may attempt to lower the value of **f_c** to introduce more filtering of high frequencies. +In previous release, the default value was excessively small, set to :math:`0.0007` Hz. **C_HWkDfl_O** [m] (:math:`C_{HWkDfl}^{O}`) is the calibrated parameter for the wake deflection correction defining the horizontal offset at the @@ -393,8 +470,9 @@ value, **C_HWkDfl_O** is set to :math:`0.0`. **C_HWkDfl_OY** [m/deg] (:math:`C_{HWkDfl}^{OY}`) is the calibrated parameter for the wake deflection correction defining the horizontal offset at the rotor scaled with yaw error. If the DEFAULT keyword is -specified in place of a numerical value, **C_HWkDfl_OY** is set to -:math:`0.3`. +specified in place of a numerical value, +**C_HWkDfl_OY** is set to :math:`0` when **Mod_Wake=2** +**C_HWkDfl_OY** is set to :math:`0.3` otherwise. **C_HWkDfl_x** [-] (:math:`C_{HWkDfl}^{x}`) is the calibrated parameter for the wake deflection correction defining the horizontal offset scaled @@ -404,8 +482,9 @@ of a numerical value, **C_HWkDfl_x** is set to :math:`0.0`. **C_HWkDfl_xY** [1/deg] (:math:`C_{HWkDfl}^{xY}`) is the calibrated parameter for the wake deflection correction defining the horizontal offset scaled with downstream distance and yaw error. If the DEFAULT -keyword is specified in place of a numerical value, **C_HWkDfl_xY** is -set to :math:`-0.004`. +keyword is specified in place of a numerical value, +**C_HWkDfl_xY** is set to :math:`0.0` when **Mod_Wake=2**. +**C_HWkDfl_xY** is set to :math:`-0.004` otherwise. **C_NearWake** (:math:`C_{NearWake}`) [-] is the calibrated parameter for the near-wake correction and must be greater than one. If the @@ -500,6 +579,56 @@ the wake meandering and must be greater than or equal to one. If the DEFAULT keyword is specified in place of a numerical value, **C_Meander** is set to :math:`1.9`. +*----------------Curled wake parameters------------------* + + + +**Swirl** [switch] +Include swirl velocities in wake [only used if [**Mod_Wake=2**] +or [**Mod_Wake=3**]. + +**k_VortexDecay** [-] This constant specifies the decay rate of the +spanwise velocity components from the curled wake model. +DEFAULT is 0.01. + +**NumVortices** [-] The number of vortices in the curled wake model. +DEFAULT is 100. + +**sigma_D** [-] The width of the vortex core in the curled wake model +non-dimesionalized by rotor diameter. If the DEFAULT keyword is +specified in place of a numerical value, **sigma_D** is set to +:math:`0.2`. + +**FilterInit** [switch] The number of grid points (in the `y` and `z` directions) +used to filter the initial wake plane deficit in the curled wake model. +A value of zero corresponds to no filter. The filter is used to remove strong gradients +in the wake, and stabilize the solution. +DEFAULT is 1. + +**k_vCurl** [-] Calibrated parameter for scaling the eddy viscosity in the +curled-wake model. +This value is a tuning parameters to increase or decrease the diffusion in the curled wake model. +We have found that this value may be a function of the thrust coefficient, with higher values recommended for higher thrust coefficients. +The following guidelines are suggested: +:math:`k_v=0.9` for :math:`C_T=0.4`, +:math:`k_v=2.0` for :math:`C_T=0.7`, +:math:`k_v=3.0` for :math:`C_T=0.9`. +These guidelines may change in the future. +The DEFAULT value is 2.0. + +**Mod_Projection** [switch] Select how the wake plane velocity is +projected in AWAE. There are two options: +1) keep all components +2) project against plane normal. +If DEFAULT is used, then **Mod_Projection=2** when **Mod_Wake=2**, +and **Mod_Projection=1** otherwise. + + + +**OutAllPlanes** [-] Output all wake planes in VTK at all time steps. +Note: this option requires intensive writing to disk and will drastically slow down the simulation. +DEFAULT is False. + Visualize ~~~~~~~~~ @@ -520,15 +649,14 @@ excluding its file extension, where ** and ** are as specified in :numref:`FF:Input:VTK`, but include leading zeros. -For visualization, FAST.Farm can also output low-resolution disturbed -(including wakes) wind data output files that are two-dimensional (2D) -slices of the full low-resolution domain, specified by the following 7 -inputs. Up to nine 2D slices parallel to the *X-Y*, *Y-Z*, and/or *X-Z* -planes can be output. +For visualization, FAST.Farm can also output low-resolution disturbed (including +wakes) wind data output files that are two-dimensional (2D) slices of the full +low-resolution domain, specified by the following 7 inputs. Up to ninety-nine 2D +slices parallel to the *X-Y*, *Y-Z*, and/or *X-Z* planes can be output. - **NOutDisWindXY** [integer] specifies the number of 2D slices parallel to the *X-Y* plane where low-resolution disturbed wind data - output files are output (:math:`0` to :math:`9`). + output files are output (:math:`0` to :math:`99`). - **OutDisWindZ** [m] is a list **NOutDisWindXY** values long of the *Z* coordinates of each plane that will be output. These values are @@ -537,7 +665,7 @@ planes can be output. - **NOutDisWindYZ** [integer] specifies the number of 2D slices parallel to the *Y-Z* plane where low-resolution disturbed wind data - output files are output (:math:`0` to :math:`9`). + output files are output (:math:`0` to :math:`99`). - **OutDisWindX** [m] is a list **NOutDisWindYZ** values long of the *X* coordinates of each plane that will be output. These values are @@ -546,7 +674,7 @@ planes can be output. - **NOutDisWindXZ** [integer] specifies the number of 2D slices parallel to the *X-Z* plane where low-resolution disturbed wind data - output files are output (:math:`0` to :math:`9`). + output files are output (:math:`0` to :math:`99`). - **OutDisWindY** [m] is a list **NOutDisWindXZ** values long of the *Y* coordinates of each plane that will be output. These values are diff --git a/docs/source/user/fast.farm/ModelGuidance.rst b/docs/source/user/fast.farm/ModelGuidance.rst index 24e0fd36c..ad99882f9 100644 --- a/docs/source/user/fast.farm/ModelGuidance.rst +++ b/docs/source/user/fast.farm/ModelGuidance.rst @@ -513,6 +513,12 @@ frequency of wake meandering should be resolved by at least :math:`10` time steps. Note that :math:`D^\text{Wake}` can be approximated as :math:`D^\text{Rotor}` in this calculation. +When **Wake_Mod=2,3**, for numerical stability, it is recommended to set the time step with a value that (approximately) satisfies the following guideline (see Equation 20 of the following `paper `__): + + .. math:: + \textbf{DT_Low} \lessapprox \frac{\textbf{dr}}{2 V_\text{Hub}} + + Spatial discretization convergence was assessed in the same manner as temporal discretization. Minimal sensitivity to spatial discretization was found for the low-resolution domain in the range of spatial @@ -812,6 +818,13 @@ parameters: .. math:: \textbf{dr} \le c_\text{max} +When **Wake_Mod=2,3**, for numerical stability, it is recommended to set the spacing with a value that (approximately) satisfies the following guideline (see Equation 20 of the following `paper `__): + + .. math:: + \textbf{dr} \ltrapprox \frac{D}{10} + + + - **NumRadii** -- To ensure the wake deficits are accurately computed by FAST.Farm, **NumRadii** should be set so that the diameter of each wake plane, 2(**NumRadii**\ -1)\ **dr**, is large relative to the rotor @@ -820,6 +833,8 @@ parameters: .. math:: \textbf{NumRadii} \ge \frac{3D^{Rotor}}{2\ \textbf{dr}}+1 + + - **NumPlanes** -- To ensure the wake deficits are accurately captured by FAST.Farm, **NumPlanes** should be set so that the wake planes propagate a sufficient distance downstream, preferably until the wake diff --git a/docs/source/user/fast.farm/OutputFiles.rst b/docs/source/user/fast.farm/OutputFiles.rst index 0673bf2fd..683820605 100644 --- a/docs/source/user/fast.farm/OutputFiles.rst +++ b/docs/source/user/fast.farm/OutputFiles.rst @@ -90,6 +90,30 @@ take up a lot of disk space, especially when generating full low- and high-resolution disturbed wind data files. Therefore, disabling visualization is recommended when running many FAST.Farm simulations. + +.. _FF:Output:Planes: + +Wake dynamics Plane Files +------------------------- + +Setting the option **OutAllPlanes** to true in the main FAST.Farm input file +will result in the wake planes of the Wake Dynamics module to be written. +This option requires intensive writing to disk and will drastically slow down the simulation. +The wake planes are written in VTK format, in the folder `vtk_ff_planes` at the root +of the simulation directory. +A VTK file is written for each plane, time step and turbine. +The number of planes written will increase with each **DT_Low** time step, until +the full number of planes **Num_Planes** is reached. +The coordinates of the planes are in the meandering frame of reference (not global coordinates) +and using Cartesian coordinates. +The following field are always written: +x,y,z components of the wake deficit velocity (in the meandering frame), +ambient, shear, and total eddy viscosity. +When **Mod_Wake=1`** (polar wake), the fields are converted from polar to Cartesian. +Additional velocity gradients are provided in the VTK file when **Mod_Wake/=1`**. + + + .. _FF:Output:Time: Time-Series Results File diff --git a/docs/source/user/fast.farm/examples/FAST.Farm--input.dat b/docs/source/user/fast.farm/examples/FAST.Farm--input.dat index 35a546243..1164ae82e 100644 --- a/docs/source/user/fast.farm/examples/FAST.Farm--input.dat +++ b/docs/source/user/fast.farm/examples/FAST.Farm--input.dat @@ -1,87 +1,103 @@ -FAST.Farm v1.00.* INPUT FILE -Sample FAST.Farm input file +------- FAST.Farm for OpenFAST INPUT FILE ------------------------------------------------- +Comment --- SIMULATION CONTROL --- -False Echo Echo input data to .ech? (flag) -FATAL AbortLevel Error level when simulation should abort (string) {"WARNING", "SEVERE", "FATAL"} -2000.0 TMax Total run time (s) [>=0.0] -False UseSC Use a super controller? (flag) -1 Mod_AmbWind Ambient wind model (-) (switch) {1: high-fidelity precursor in VTK format, 2: one InflowWind module, 3: multiple instances of InflowWind module} +False Echo - Echo input data to .ech? (flag) +FATAL AbortLevel - Error level when simulation should abort (string) {"WARNING", "SEVERE", "FATAL"} +2000.0 TMax - Total run time (s) [>=0.0] +False UseSC - Use a super controller? (flag) +1 Mod_AmbWind - Ambient wind model (-) (switch) {1: high-fidelity precursor in VTK format, 2: one InflowWind module, 3: multiple instances of InflowWind module} +2 Mod_WaveField - Wave field handling (-) (switch) {1: use individual HydroDyn inputs without adjustment, 2: adjust wave phases based on turbine offsets from farm origin} +0 Mod_SharedMooring - Shared mooring system model (switch) {0: None, 3=MoorDyn}} --- SUPER CONTROLLER --- [used only for UseSC=True] -"SC_DLL.dll" SC_FileName Name/location of the dynamic library {.dll [Windows] or .so [Linux]} containing the Super Controller algorithms (quoted string) +"SC_DLL.dll" SC_FileName Name/location of the dynamic library {.dll [Windows] or .so [Linux]} containing the Super Controller algorithms (quoted string) +--- SHARED MOORING SYSTEM --- [used only for Mod_SharedMoor>0] +"" SharedMoorFile - Name of file containing shared mooring system input parameters (quoted string) [used only when Mod_SharedMooring > 0] +0.04 DT_Mooring - Time step for farm-level mooring coupling with each turbine (s) [used only when Mod_SharedMooring > 0] --- AMBIENT WIND: PRECURSOR IN VTK FORMAT --- [used only for Mod_AmbWind=1] -2.0 DT_Low-VTK Time step for low-resolution wind data input files; will be used as the global FAST.Farm time step (s) [>0.0] -0.5 DT_High-VTK Time step for high-resolution wind data input files (s) [>0.0] "/AmbWind/steady" WindFilePath Path name to wind data files from precursor (string) -False ChkWndFiles Check all the ambient wind files for data consistency (flag) +2.0 DT_Low-VTK - Time step for low-resolution wind data input files; will be used as the global FAST.Farm time step (s) [>0.0] +0.5 DT_High-VTK - Time step for high-resolution wind data input files (s) [>0.0] +"unused" WindFilePath - Path name to VTK wind data files from precursor (string) +False ChkWndFiles - Check all the ambient wind files for data consistency? (flag) --- AMBIENT WIND: INFLOWWIND MODULE --- [used only for Mod_AmbWind=2 or 3] -2.0 DT_Low Time step for low-resolution wind data interpolation; will be used as the global FAST.Farm time step (s) [>0.0] -0.5 DT_High Time step for high-resolution wind data interpolation (s) [>0.0] -300 NX_Low Number of low-resolution spatial nodes in X direction for wind data interpolation (-) [>=2] -300 NY_Low Number of low-resolution spatial nodes in Y direction for wind data interpolation (-) [>=2] -35 NZ_Low Number of low-resolution spatial nodes in Z direction for wind data interpolation (-) [>=2] -5.0 X0_Low Origin of low-resolution spatial nodes in X direction for wind data interpolation (m) -5.0 Y0_Low Origin of low-resolution spatial nodes in Y direction for wind data interpolation (m) -5.0 Z0_Low Origin of low-resolution spatial nodes in Z direction for wind data interpolation (m) -10.0 dX_Low Spacing of low-resolution spatial nodes in X direction for wind data interpolation (m) [>0.0] -10.0 dY_Low Spacing of low-resolution spatial nodes in Y direction for wind data interpolation (m) [>0.0] -10.0 dZ_Low Spacing of low-resolution spatial nodes in Z direction for wind data interpolation (m) [>0.0] -16 NX_High Number of high-resolution spatial nodes in X direction for wind data interpolation (-) [>=2] -16 NY_High Number of high-resolution spatial nodes in Y direction for wind data interpolation (-) [>=2] -17 NZ_High Number of high-resolution spatial nodes in Z direction for wind data interpolation (-) [>=2] -"InflowWind.dat" InflowFile Name of file containing InflowWind module input parameters (quoted string) +2.0 DT_Low - Time step for low-resolution wind data interpolation; will be used as the global FAST.Farm time step (s) [>0.0] +0.5 DT_High - Time step for high-resolution wind data interpolation (s) [>0.0] +300 NX_Low - Number of low-resolution spatial nodes in X direction for wind data interpolation (-) [>=2] +300 NY_Low - Number of low-resolution spatial nodes in Y direction for wind data interpolation (-) [>=2] +35 NZ_Low - Number of low-resolution spatial nodes in Z direction for wind data interpolation (-) [>=2] +5.0 X0_Low - Origin of low-resolution spatial nodes in X direction for wind data interpolation (m) +5.0 Y0_Low - Origin of low-resolution spatial nodes in Y direction for wind data interpolation (m) +5.0 Z0_Low - Origin of low-resolution spatial nodes in Z direction for wind data interpolation (m) +10.0 dX_Low - Spacing of low-resolution spatial nodes in X direction for wind data interpolation (m) [>0.0] +10.0 dY_Low - Spacing of low-resolution spatial nodes in Y direction for wind data interpolation (m) [>0.0] +10.0 dZ_Low - Spacing of low-resolution spatial nodes in Z direction for wind data interpolation (m) [>0.0] +16 NX_High - Number of high-resolution spatial nodes in X direction for wind data interpolation (-) [>=2] +16 NY_High - Number of high-resolution spatial nodes in Y direction for wind data interpolation (-) [>=2] +17 NZ_High - Number of high-resolution spatial nodes in Z direction for wind data interpolation (-) [>=2] +"InflowWind.dat" InflowFile - Name of file containing InflowWind module input parameters (quoted string) --- WIND TURBINES --- -1 NumTurbines Number of wind turbines (-) [>=1] [last 6 columns below used only for Mod_AmbWind=2 or 3] +1 NumTurbines - Number of wind turbines (-) [>=1] [last 6 columns below used only for Mod_AmbWind=2 or 3] WT_X WT_Y WT_Z WT_FASTInFile X0_High Y0_High Z0_High dX_High dY_High dZ_High (m) (m) (m) (string) (m) (m) (m) (m) (m) (m) 605.0 1500.0 0.0 "/FAST/Test18.fst" 525.0 1425.0 5.0 10.0 10.0 10.0 --- WAKE DYNAMICS --- -5.0 dr Radial increment of radial finite-difference grid (m) [>0.0] -40 NumRadii Number of radii in the radial finite-difference grid (-) [>=2] -140 NumPlanes Number of wake planes (-) [>=2] -DEFAULT f_c Cutoff (corner) frequency of the low-pass time-filter for the wake advection, deflection, and meandering model (Hz) [>0.0] or DEFAULT [=0.0007] -DEFAULT C_HWkDfl_O Calibrated parameter in the correction for wake deflection defining the horizontal offset at the rotor (m) or DEFAULT [=0.0] -DEFAULT C_HWkDfl_OY Calibrated parameter in the correction for wake deflection defining the horizontal offset at the rotor scaled with yaw error (m/deg) or DEFAULT [=0.3] -DEFAULT C_HWkDfl_x Calibrated parameter in the correction for wake deflection defining the horizontal offset scaled with downstream distance (-) or DEFAULT [=0.0] -DEFAULT C_HWkDfl_xY Calibrated parameter in the correction for wake deflection defining the horizontal offset scaled with downstream distance and yaw error (1/deg) or DEFAULT [=-0.004] -DEFAULT C_NearWake Calibrated parameter for the near-wake correction (-) [>1. and <2.5] or DEFAULT [=1.8] -DEFAULT k_vAmb Calibrated parameter for the influence of ambient turbulence in the eddy viscosity (-) [>=0.0] or DEFAULT [=0.05] -DEFAULT k_vShr Calibrated parameter for the influence of the shear layer in the eddy viscosity (-) [>=0.0] or DEFAULT [=0.016] -DEFAULT C_vAmb_DMin Calibrated parameter in the eddy viscosity filter function for ambient turbulence defining the transitional diameter fraction between the minimum and exponential regions (-) [>=0.0] or DEFAULT [=0.0] -DEFAULT C_vAmb_DMax Calibrated parameter in the eddy viscosity filter function for ambient turbulence defining the transitional diameter fraction between the exponential and maximum regions (-) [> C_vAmb_DMin] or DEFAULT [=1.0] -DEFAULT C_vAmb_FMin Calibrated parameter in the eddy viscosity filter function for ambient turbulence defining the value in the minimum region (-) [>=0.0 and <=1.0] or DEFAULT [=1.0] -DEFAULT C_vAmb_Exp Calibrated parameter in the eddy viscosity filter function for ambient turbulence defining the exponent in the exponential region (-) [> 0.0] or DEFAULT [=0.01] -DEFAULT C_vShr_DMin Calibrated parameter in the eddy viscosity filter function for the shear layer defining the transitional diameter fraction between the minimum and exponential regions (-) [>=0.0] or DEFAULT [=3.0] -DEFAULT C_vShr_DMax Calibrated parameter in the eddy viscosity filter function for the shear layer defining the transitional diameter fraction between the exponential and maximum regions (-) [> C_vShr_DMin] or DEFAULT [=25.0] -DEFAULT C_vShr_FMin Calibrated parameter in the eddy viscosity filter function for the shear layer defining the value in the minimum region (-) [>=0.0 and <=1.0] or DEFAULT [=0.2] -DEFAULT C_vShr_Exp Calibrated parameter in the eddy viscosity filter function for the shear layer defining the exponent in the exponential region (-) [> 0.0] or DEFAULT [=0.1] -DEFAULT Mod_WakeDiam Wake diameter calculation model (-) (switch) {1: rotor diameter, 2: velocity based, 3: mass-flux based, 4: momentum-flux based} or DEFAULT [=1] -DEFAULT C_WakeDiam Calibrated parameter for wake diameter calculation (-) [>0.0 and <0.99] or DEFAULT [=0.95] [unused for Mod_WakeDiam=1] -DEFAULT Mod_Meander Spatial filter model for wake meandering (-) (switch) {1: uniform, 2: truncated jinc, 3: windowed jinc} or DEFAULT [=3] -DEFAULT C_Meander Calibrated parameter for wake meandering (-) [>=1.0] or DEFAULT [=1.9] +1 Mod_Wake - Switch between wake formulations {1:Polar, 2:Curl, 3:Cartesian} (-) (switch) +5.0 dr - Radial increment of radial finite-difference grid (m) [>0.0] +40 NumRadii - Number of radii in the radial finite-difference grid (-) [>=2] +140 NumPlanes - Number of wake planes (-) [>=2] +DEFAULT f_c - Cutoff (corner) frequency of the low-pass time-filter for the wake advection, deflection, and meandering model [recommended=1.28*U0/R] (Hz) [>0.0] +DEFAULT C_HWkDfl_O - Calibrated parameter in the correction for wake deflection defining the horizontal offset at the rotor (m) or DEFAULT [=0.0] +DEFAULT C_HWkDfl_OY - Calibrated parameter in the correction for wake deflection defining the horizontal offset at the rotor scaled with yaw error (m/deg) or DEFAULT [=0.3] +DEFAULT C_HWkDfl_x - Calibrated parameter in the correction for wake deflection defining the horizontal offset scaled with downstream distance (-) or DEFAULT [=0.0] +DEFAULT C_HWkDfl_xY - Calibrated parameter in the correction for wake deflection defining the horizontal offset scaled with downstream distance and yaw error (1/deg) or DEFAULT [=-0.004] +DEFAULT C_NearWake - Calibrated parameter for the near-wake correction (-) [>1. and <2.5] or DEFAULT [=1.8] +DEFAULT k_vAmb - Calibrated parameter for the influence of ambient turbulence in the eddy viscosity (-) [>=0.0] or DEFAULT [=0.05] +DEFAULT k_vShr - Calibrated parameter for the influence of the shear layer in the eddy viscosity (-) [>=0.0] or DEFAULT [=0.016] +DEFAULT C_vAmb_DMin - Calibrated parameter in the eddy viscosity filter function for ambient turbulence defining the transitional diameter fraction between the minimum and exponential regions (-) [>=0.0] or DEFAULT [=0.0] +DEFAULT C_vAmb_DMax - Calibrated parameter in the eddy viscosity filter function for ambient turbulence defining the transitional diameter fraction between the exponential and maximum regions (-) [> C_vAmb_DMin] or DEFAULT [=1.0] +DEFAULT C_vAmb_FMin - Calibrated parameter in the eddy viscosity filter function for ambient turbulence defining the value in the minimum region (-) [>=0.0 and <=1.0] or DEFAULT [=1.0] +DEFAULT C_vAmb_Exp - Calibrated parameter in the eddy viscosity filter function for ambient turbulence defining the exponent in the exponential region (-) [> 0.0] or DEFAULT [=0.01] +DEFAULT C_vShr_DMin - Calibrated parameter in the eddy viscosity filter function for the shear layer defining the transitional diameter fraction between the minimum and exponential regions (-) [>=0.0] or DEFAULT [=3.0] +DEFAULT C_vShr_DMax - Calibrated parameter in the eddy viscosity filter function for the shear layer defining the transitional diameter fraction between the exponential and maximum regions (-) [> C_vShr_DMin] or DEFAULT [=25.0] +DEFAULT C_vShr_FMin - Calibrated parameter in the eddy viscosity filter function for the shear layer defining the value in the minimum region (-) [>=0.0 and <=1.0] or DEFAULT [=0.2] +DEFAULT C_vShr_Exp - Calibrated parameter in the eddy viscosity filter function for the shear layer defining the exponent in the exponential region (-) [> 0.0] or DEFAULT [=0.1] +DEFAULT Mod_WakeDiam - Wake diameter calculation model (-) (switch) {1: rotor diameter, 2: velocity based, 3: mass-flux based, 4: momentum-flux based} or DEFAULT [=1] +DEFAULT C_WakeDiam - Calibrated parameter for wake diameter calculation (-) [>0.0 and <0.99] or DEFAULT [=0.95] [unused for Mod_WakeDiam=1] +DEFAULT Mod_Meander - Spatial filter model for wake meandering (-) (switch) {1: uniform, 2: truncated jinc, 3: windowed jinc} or DEFAULT [=3] +DEFAULT C_Meander - Calibrated parameter for wake meandering (-) [>=1.0] or DEFAULT [=1.9] +--- CURLED-WAKE PARAMETERS [only used if Mod_Wake=2 or 3] --- +True Swirl - Switch to include swirl velocities in wake [only used if Mod_Wake=2 or Mod_Wake=3] (-) (switch) [DEFAULT=TRUE] +0 k_VortexDecay - Vortex decay constant for curl (-) [DEFAULT=0] +DEFAULT NumVortices - The number of vortices in the curled wake model (-) [DEFAULT=100] +DEFAULT sigma_D - The width of the vortices in the curled wake model non-dimesionalized by rotor diameter (-) [DEFAULT=0.2] +DEFAULT FilterInit - Switch to filter the initial wake plane deficit and select the number of grid points for the filter {0: no filter, 1: filter of size 1} or DEFAULT [DEFAULT=1] [unused for Mod_Wake=1] (switch) +DEFAULT k_vCurl - Calibrated parameter for scaling the eddy viscosity in the curled-wake model (-) [only used if Mod_Wake=2 or Mod_Wake=3] [>=0] or DEFAULT [DEFAULT=2.0 ] +DEFAULT Mod_Projection - Switch to select how the wake plane velocity is projected in AWAE {1: keep all components, 2: project against plane normal} or DEFAULT [DEFAULT=1: if Mod_Wake is 1 or 3, or DEFAULT=2: if Mod_Wake is 2] (switch) --- VISUALIZATION --- -False WrDisWind Write low- and high-resolution disturbed wind data to .Low.Dis.t.vtk etc. (flag) -1 NOutDisWindXY Number of XY planes for output of disturbed wind data across the low-resolution domain to .Low.DisXY.t.vtk (-) [0 to 9] -90.0 OutDisWindZ Z coordinates of XY planes for output of disturbed wind data across the low-resolution domain (m) [1 to NOutDisWindXY] [unused for NOutDisWindXY=0] -2 NOutDisWindYZ Number of YZ planes for output of disturbed wind data across the low-resolution domain to /Low.DisYZ.t.vtk (-) [0 to 9] -600.0,978.0 OutDisWindX X coordinates of YZ planes for output of disturbed wind data across the low-resolution domain (m) [1 to NOutDisWindYZ] [unused for NOutDisWindYZ=0] -1 NOutDisWindXZ Number of XZ planes for output of disturbed wind data across the low-resolution domain to /Low.DisXZ.t.vtk (-) [0 to 9] -1500.0 OutDisWindY Y coordinates of XZ planes for output of disturbed wind data across the low-resolution domain (m) [1 to NOutDisWindXZ] [unused for NOutDisWindXZ=0] -4.0 WrDisDT Time step for disturbed wind visualization output (s) [>0.0] or DEFAULT [=DT_Low or DT_Low-VTK] [unused for WrDisWind=False and NOutDisWindXY=NOutDisWindYZ=NOutDisWindXZ=0] +False WrDisWind - Write low- and high-resolution disturbed wind data to .Low.Dis.t.vtk etc. (flag) +1 NOutDisWindXY - Number of XY planes for output of disturbed wind data across the low-resolution domain to .Low.DisXY.t.vtk (-) [0 to 9] +90.0 OutDisWindZ - Z coordinates of XY planes for output of disturbed wind data across the low-resolution domain (m) [1 to NOutDisWindXY] [unused for NOutDisWindXY=0] +2 NOutDisWindYZ - Number of YZ planes for output of disturbed wind data across the low-resolution domain to /Low.DisYZ.t.vtk (-) [0 to 9] +600.0,978.0 OutDisWindX X - coordinates of YZ planes for output of disturbed wind data across the low-resolution domain (m) [1 to NOutDisWindYZ] [unused for NOutDisWindYZ=0] +1 NOutDisWindXZ - Number of XZ planes for output of disturbed wind data across the low-resolution domain to /Low.DisXZ.t.vtk (-) [0 to 9] +1500.0 OutDisWindY - Y coordinates of XZ planes for output of disturbed wind data across the low-resolution domain (m) [1 to NOutDisWindXZ] [unused for NOutDisWindXZ=0] +4.0 WrDisDT - Time step for disturbed wind visualization output (s) [>0.0] or DEFAULT [=DT_Low or DT_Low-VTK] [unused for WrDisWind=False and NOutDisWindXY=NOutDisWindYZ=NOutDisWindXZ=0] --- OUTPUT --- -True SumPrint Print summary data to .sum? (flag) -99999.9 ChkptTime Amount of time between creating checkpoint files for potential restart (s) [>0.0] -200.0 TStart Time to begin tabular output (s) [>=0.0] -1 OutFileFmt Format for tabular (time-marching) output file (-) (switch) {1: text file [.out], 2: binary file [.outb], 3: both} -True TabDelim Use tab delimiters in text tabular output file? (flag) {uses spaces if False} -"ES10.3E2" OutFmt Format used for text tabular output, excluding the time channel. Resulting field should be 10 characters. (quoted string) -3 NOutRadii Number of radial nodes for wake output for an individual rotor (-) [0 to 20] -0, 15, 39 OutRadii List of radial nodes for wake output for an individual rotor (-) -2 NOutDist Number of downstream distances for wake output for an individual rotor (-) [1 to NOutRadii] [unused for NOutRadii=0] rotor (-) [0 to 9] -0.0, 378.0 OutDist List of downstream distances for wake output for an individual rotor (m) [1 to NOutDist] [unused for NOutDist =0] -1 NWindVel Number of points for wind output (-) [0 to 9] -600.0 WindVelX List of coordinates in the X direction for wind output (m) [1 to NWindVel] [unused for NWindVel=0] -1500.0 WindVelY List of coordinates in the Y direction for wind output (m) [1 to NWindVel] [unused for NWindVel=0] -90.0 WindVelZ List of coordinates in the Z direction for wind output (m) [1 to NWindVel] [unused for NWindVel=0] -OutList The next line(s) contains a list of output parameters. (quoted string) +True SumPrint - Print summary data to .sum? (flag) +99999.9 ChkptTime - Amount of time between creating checkpoint files for potential restart (s) [>0.0] +0.0 TStart - Time to begin tabular output (s) [>=0.0] +1 OutFileFmt - Format for tabular (time-marching) output file (switch) {1: text file [.out], 2: binary file [.outb], 3: both} +True TabDelim - Use tab delimiters in text tabular output file? (flag) {uses spaces if False} +"ES10.3E2" OutFmt - Format used for text tabular output, excluding the time channel. Resulting field should be 10 characters. (quoted string) +DEFAULT OutAllPlanes - Output all wake planes at all time steps. [DEFAULT=False] +3 NOutRadii - Number of radial nodes for wake output for an individual rotor (-) [0 to 20] +0, 15, 39 OutRadii - List of radial nodes for wake output for an individual rotor (-) +2 NOutDist - Number of downstream distances for wake output for an individual rotor (-) [1 to NOutRadii] [unused for NOutRadii=0] rotor (-) [0 to 9] +0.0, 378.0 OutDist - List of downstream distances for wake output for an individual rotor (m) [1 to NOutDist] [unused for NOutDist =0] +1 NWindVel - Number of points for wind output (-) [0 to 9] +600.0 WindVelX - List of coordinates in the X direction for wind output (m) [1 to NWindVel] [unused for NWindVel=0] +1500.0 WindVelY - List of coordinates in the Y direction for wind output (m) [1 to NWindVel] [unused for NWindVel=0] +90.0 WindVelZ - List of coordinates in the Z direction for wind output (m) [1 to NWindVel] [unused for NWindVel=0] + OutList - The next line(s) contains a list of output parameters. (quoted string) "RtAxsXT1, RtAxsYT1, RtAxsZT1" "RtPosXT1, RtPosYT1, RtPosZT1" "YawErrT1" diff --git a/docs/source/user/index.rst b/docs/source/user/index.rst index 59736b2fe..65a9a4bad 100644 --- a/docs/source/user/index.rst +++ b/docs/source/user/index.rst @@ -24,7 +24,10 @@ General Workshop material, legacy documentation, and other resources are listed below. -- `Workshop Presentations `_ +- `Overview of OpenFAST at NAWEA WindTech 2022 `_ +- `Practical Guide to OpenFAST at NAWEA WindTech 2022 `_ +- `Overview of OpenFAST at NAWEA WindTech 2019 `_ +- `Workshop Presentations `_ - :download:`Old FAST v6 User's Guide <../../OtherSupporting/Old_FAST6_UsersGuide.pdf>` - :download:`FAST v8 README <../../OtherSupporting/FAST8_README.pdf>` - `Implementation of Substructure Flexibility and Member-Level Load Capabilities for Floating Offshore Wind Turbines in OpenFAST `_ @@ -51,6 +54,7 @@ Documentation covers usage of models, underlying theory, and in some cases modul ElastoDyn HydroDyn InflowWind + MoorDyn ServoDyn Structural Control TurbSim diff --git a/docs/source/user/inflowwind/driver.rst b/docs/source/user/inflowwind/driver.rst index b0ef7a017..c4a92c487 100644 --- a/docs/source/user/inflowwind/driver.rst +++ b/docs/source/user/inflowwind/driver.rst @@ -7,28 +7,30 @@ Command-line syntax for InflowWind driver: :: - InlowWind_Driver [options] + InflowWind_Driver [options] where: -- Name of driver input file to use options: /ifw -- treat as name of InflowWind input file (no driver input file) The following options will override values in the driver input file: - /DT[#] -- timestep - /TStart[#] -- start time - /TSteps[#] -- number of timesteps - /xrange[#:#] -- range of x (#'s are reals) - /yrange[#:#] -- range of y - /zrange[#:#] -- range in z (ground = 0.0) - /Dx[#] -- spacing in x - /Dy[#] -- spacing in y - /Dz[#] -- spacing in z - /points[FILE] -- calculates at x,y,z coordinates specified in a white space delimited FILE - /v -- verbose output - /vv -- very verbose output - /hawc -- convert wind file specified in InflowWind to HAWC format - /bladed -- convert wind file specified in InflowWind to Bladed format - /vtk -- convert wind file specified in InflowWind to VTK format - /help -- print this help menu and exit + /DT[#] -- timestep + /TStart[#] -- start time + /TSteps[#] -- number of timesteps + /xrange[#:#] -- range of x (#'s are reals) + /yrange[#:#] -- range of y + /zrange[#:#] -- range in z (ground = 0.0) + /Dx[#] -- spacing in x + /Dy[#] -- spacing in y + /Dz[#] -- spacing in z + /points[FILE] -- calculates at x,y,z coordinates specified in a white space delimited FILE + /v -- verbose output + /vv -- very verbose output + /hawc -- convert wind file specified in InflowWind to HAWC format + /bladed -- convert wind file specified in InflowWind to Bladed format + /vtk -- convert wind file specified in InflowWind to VTK format + /accel -- output acceleration when processing a points file + /BoxExceedAllow -- set flag to extrapolate values of points outside FF wind box + /help -- print this help menu and exit :: @@ -89,6 +91,15 @@ vtk file for each time in the full-field data structure, and the entire Y-Z grid is printed in each file. This format can be used to visualize the wind field using a viewer such as ParaView. +Uniform Wind +~~~~~~~~~~~~ + +This format generates a text file in the uniform wind format. Converting to this format will +generally lose information in the file because it specifies the wind speed and direction +at only one point and approximates the shear as a power-law exponent. + + + Converting uniform wind to full-field wind format ------------------------------------------------- @@ -113,3 +124,115 @@ full-field wind files, equal to the time it takes to travel the distance of half the grid width. When using the resulting full-field files, care must be taken that the aeroelastic code does not treat it as periodic. + +Converting from a full-field wind format to uniform wind format +--------------------------------------------------------------- + +When converting from a full-field wind format to a uniform wind file, the following assumptions are used: + +- The gust speed, horizontal shear, and vertical linear shear are all 0. +- The Uniform Wind reference height is on a full-field grid point. +- The upflow is calculated using the mean upflow value at the reference point. +- The mean wind direction and upflow are removed from the reference grid point before writing the velocities to the Uniform Wind file. +- The wind direction in the file is the sum of the mean wind direction and the instantaneous direction calculated between instantaneous U and V wind components. +- The power law exponent is either + + 1. The power-law exponent specified in InflowWind (if a power law wind profile is used to add to the turbulence with native-Bladed or HAWC2 files), or + 2. Calculated by using the mean wind speeds at two points: the reference (hub) height and the uppermost height on the grid. + +accel flag +------------------- + +The ability to calculate the acceleration of the flow field was added to +InflowWind to support the analysis of MHK, underwater, turbines. The +acceleration is needed to calculate the fluid-inertia effects of the fluid +interacting with the rotor. Calculation of the acceleration is supported for +Uniform/Steady Wind and grid based wind profiles (Turbsim, HAWC, and Bladed +files). Enabling this flag causes the driver to output the flow field +acceleration for points defined in the Points file in addition to the velocities +at those same points. + + +BoxExceedAllow flag +------------------- + +A feature was added to InflowWind to allow some requested points to lie +outside the full field wind grid. This allows for a continuous exptrapolation of +values beyond the grid that approaches an average level. + +Purpose +~~~~~~~ + +When InflowWind is coupled to OpenFAST, wind points corresponding to the free +vortex wake module (OLAF) in AeroDyn 15 and LidarSim module may be outside the +full-field wind data. No other wind data points may be outside the grid +(AeroDyn15 blades must be within the wind box). The wake from OLAF may over +time stray outside the full-field wind box, in which case it should be +sufficiently far from the turbine that any inacuracies in the reported wind +value should have little to no effect on the turbine. The method employed here +should allow the wake to continue evolving without flow reversals or other +oddities due to a discontinuity at the wind grid boundary. However, to limit +the impact of the approximation used, the wake should not be allowed to exit the +box until far from the turbine. + +The other use case is when the LidarSim requests data far from the turbine that +may lie outside the wind box, such as a yawed, or floating turbine where the +sensing beam periodically exits the wind box. + +Method +~~~~~~ + +During initialization, a flag and corresponding index are passed to tell IfW to +allow points in the requested position array to lie outside the full-field wind +and tower grids starting at this index. The values for these points are then +extrapolated using the data from the full-field wind as follows: + + 1. The average wind value at each Z height at each timestep is calculated and + stored during initialization (averaged across the Y dimension). + 2. Wind above the full field wind grid is linearly interpolated between the + value at the top of the grid the average of the top of the grid. This + linear interpolation zone extends from the top of grid to the top of the + grid + one half grid height (``FFZHWid``). Values beyond that are held + constant. + 3. Values beyond the +/-Y grid edges are linearly interpolated between the + value at the edge of the grid and the average for that Z elevation in the + grid. The interpolation zone is between the edge of the grid and one half + grid width further along Y at ``+/-2*FFYHWid``. + 4. When no tower data is present, the values below the grid are linearly + interpolated between the bottom of the grid and 0 at the ground. + 5. When tower data is present, points below the grid are interpolated between + the tower and grid and the ground (0 value at ``+/-2*FFYHWid``). Linear + interpolation is then used beyond the edge of the grid. + + +Testing with driver +~~~~~~~~~~~~~~~~~~~ + +To test this feature, the driver accepts the flag ``BoxExceedAllow`` and will +signal to InflowWind that all windgrid points may be beyond the edge of the +grid. To use this, setup a driver input file with an output wind grid that is +larger than the full-field grid from the wind file referenced in the +corresponding InflowWind input file. Then the following command can be used +(Linux syntax, Windows is slightly different): + +.. code-block:: bash + + > inflowwind_driver -BoxExceedAllow MyDriverFile.inp + +For a single YZ plane from the resulting wind grid output file at time T, the +results for extrapolated data points can be plotted and should show +characteristics similar to the following plots. + + +.. figure:: figs/FFWindExtrap--NoTower.png + :width: 90% + + Extrapolation of wind values beyond the full field wind grid when no tower data is present. The semi-transparent red planes indicate the edges of the full-field wind grid, and the red points are the locations of wind grid data in this example case. All other points shown on the surface are interpolated/extrapolated. + + +.. figure:: figs/FFWindExtrap--Tower.png + :width: 90% + + Extrapolation of wind values beyond the full field wind grid when tower data is present. The semi-transparent red planes indicate the edges of th e full-field wind grid, blue semi-transparent plane indicates the tower grid, and the red points indcate the data points from the wind grid and tower. All other points shown on the surface are interpolated/extrapolated. + + diff --git a/docs/source/user/inflowwind/examples/inflowwind_driver_example.inp b/docs/source/user/inflowwind/examples/inflowwind_driver_example.inp index 6e84d1667..ada6a1542 100644 --- a/docs/source/user/inflowwind/examples/inflowwind_driver_example.inp +++ b/docs/source/user/inflowwind/examples/inflowwind_driver_example.inp @@ -7,15 +7,18 @@ InflowWind driver input file. false WrHAWC -- Convert all data to HAWC2 format? (flag) false WrBladed -- Convert all data to Bladed format? (flag) false WrVTK -- Convert all data to VTK format? (flag) + false WrUniform -- Convert data to Uniform wind format? (flag) ===================== Tests of Interpolation Options ========================= DEFAULT NumTSteps -- number of timesteps to run (DEFAULT for all) (-) 0.0 TStart -- Start time (s) DEFAULT DT -- timestep size for driver to take (s, or DEFAULT for what the file contains) t Summary -- Summarize the data extents in the windfile (flag) t SummaryFile -- Write summary to file (.dvr.sum) (flag) + f BoxExceedAllow -- Allow point sampling outside grid ---- Points file input (output given as POINTSFILENAME.Velocity.dat) -------- f PointsFile -- read in a list of output points from a file (flag) "Test005.txt" PointsFileName -- name of points file (-) (comma separated x,y,z coordinates, # symbol for comments) + f CalcAccel -- calculate and output acceleration at points in addition to velocity ---- Output grid (Points below ground will simply be ignored) --------------- t WindGrid -- report wind data at set of X,Y,Z coordinat (flag) 6,0,15 GridCtrCoord -- coordinate of center of grid (m) diff --git a/docs/source/user/inflowwind/examples/inflowwind_example.dat b/docs/source/user/inflowwind/examples/inflowwind_example.dat index a2159a4aa..f17434dc7 100644 --- a/docs/source/user/inflowwind/examples/inflowwind_example.dat +++ b/docs/source/user/inflowwind/examples/inflowwind_example.dat @@ -5,6 +5,7 @@ False Echo - Echo input data to .ech (flag) 3 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 (meteorological rotation from aligned with X (positive rotates towards -Y) -- degrees) (not used for native Bladed format WindType=7) 0 VFlowAng - Upflow angle (degrees) (not used for native Bladed format WindType=7) + False VelInterpCubic - Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7] 1 NWindVel - Number of points to output the wind velocity (0 to 9) 0 WindVxiList - List of coordinates in the inertial X direction (m) 0 WindVyiList - List of coordinates in the inertial Y direction (m) @@ -14,8 +15,8 @@ False Echo - Echo input data to .ech (flag) 90 RefHt - Reference height for horizontal wind speed (m) 0.2 PLexp - Power law exponent (-) ================== Parameters for Uniform wind file [used only for WindType = 2] ============================ -"Wind/90m_12mps_twr.hh" Filename - Filename of time series data for uniform wind field. (-) - 90 RefHt - Reference height for horizontal wind speed (m) +"Wind/90m_12mps_twr.hh" FileName_Uni - Filename of time series data for uniform wind field. (-) + 90 RefHt_Uni - Reference height for horizontal wind speed (m) 125.88 RefLength - Reference length for linear horizontal and vertical sheer (-) ================== Parameters for Binary TurbSim Full-Field files [used only for WindType = 3] ============== "Wind/90m_12mps_twr.bts" Filename - Name of the Full field wind file to use (.bts) @@ -32,7 +33,7 @@ False TowerFile - Have tower file (.twr) (flag) ignored when WindTy 16 dx - distance (in meters) between points in the x direction (m) 3 dy - distance (in meters) between points in the y direction (m) 3 dz - distance (in meters) between points in the z direction (m) - 90 RefHt - reference height; the height (in meters) of the vertical center of the grid (m) + 90 RefHt_HAWC - reference height; the height (in meters) of the vertical center of the grid (m) ------------- Scaling parameters for turbulence --------------------------------------------------------- 2 ScaleMethod - Turbulence scaling method [0 = none, 1 = direct scaling, 2 = calculate scaling factor based on a desired standard deviation] 1 SFx - Turbulence scaling factor for the x direction (-) [ScaleMethod=1] @@ -44,9 +45,22 @@ False TowerFile - Have tower file (.twr) (flag) ignored when WindTy ------------- Mean wind profile parameters (added to HAWC-format files) --------------------------------- 12 URef - Mean u-component wind speed at the reference height (m/s) 2 WindProfile - Wind profile type (0=constant;1=logarithmic,2=power law) - 0.2 PLExp - Power law exponent (-) (used for PL wind profile type only) + 0.2 PLExp_HAWC - Power law exponent (-) (used for PL wind profile type only) 0.03 Z0 - Surface roughness length (m) (used for LG wind profile type only) - 0 InitPosition(x) - Initial offset in +x direction (shift of wind box) + 0 XOffset - Initial offset in +x direction (shift of wind box) +================== LIDAR Parameters =========================================================================== + 0 SensorType - Switch for lidar configuration (0 = None, 1 = Single Point Beam(s), 2 = Continuous, 3 = Pulsed) + 0 NumPulseGate - Number of lidar measurement gates (used when SensorType = 3) + 30 PulseSpacing - Distance between range gates (m) (used when SensorType = 3) + 0 NumBeam - Number of lidar measurement beams (0-5)(used when SensorType = 1) + -200 FocalDistanceX - Focal distance co-ordinates of the lidar beam in the x direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) + 0 FocalDistanceY - Focal distance co-ordinates of the lidar beam in the y direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) + 0 FocalDistanceZ - Focal distance co-ordinates of the lidar beam in the z direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m) +0.0 0.0 0.0 RotorApexOffsetPos - Offset of the lidar from hub height (m) + 17 URefLid - Reference average wind speed for the lidar[m/s] + 0.25 MeasurementInterval - Time between each measurement [s] + False LidRadialVel - TRUE => return radial component, FALSE => return 'x' direction estimate + 1 ConsiderHubMotion - Flag whether to consider the hub motion's impact on Lidar measurements ====================== OUTPUT ================================================== False SumPrint - Print summary data to .IfW.sum (flag) OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) diff --git a/docs/source/user/inflowwind/figs/FFWindExtrap--NoTower.png b/docs/source/user/inflowwind/figs/FFWindExtrap--NoTower.png new file mode 100644 index 0000000000000000000000000000000000000000..8d1746de8eb7a30d4940e49cf283ebaee55c934c GIT binary patch literal 136589 zcmZU51z1#Hw>KprEj4ugk?tJ21QZGB4hI5xWRy6Zc` z``&xs`(2)Ao;h>QS!bWU^0(GroA;XP%J`3|9;2Y3;6GPU)Ivc)r$<3Sqr%1n&dAXn zd_h4$RkBr3(0s0-z@X{sY-8(Sje^4V0b*hC=mB?pMaGG$~&;)=?3*ug%#;B)n`v;kL4%sXt%a7X+{@1MPgVeth**wqC^-c~f$3-VQ{U*F%miJ_x6 zKSl3e+_}HMU%0!!U$mAzcIM}!xxhqGwy@YMXQk%{7^`P(@Z3gC4TS?Z#zsMnutmWD zj!=OQ74QLM@G%?(3;2Eld=x*U{nu4=`p@Y9b&U3Kr<}IJ^XI@#+7MT3YbUoi&hF)h z&6dEUCT(>L+zr%TibI?oc`U7*Ut9BdJHmiFQBWkk#eqXdYj;ZqZ$}3wH*s$%riVMk zfn(%pUM7ZzTiorXm<-f385Epdtr>)Qgn0Ovq#rXdFi5&u*@$Z?D*c-r_$9^k#@!tz z&dclN<;CMA$m8q^<>d#1!MuC|yaEE;z#ZIfK2GkI-rP=Z%>R1Ge?3Rh+704r3v;)1 zc49z2*YdTqhr1LL6LO&c{`=Q^T6^36&qz*g|DF~wL0;q)UVa`v-v53!Kq`qmE3Rql zZS7#7XzK{D2N*+I6bzPpxc~oL`JWO0MXBp%?W*AH2oSnU{||rvP5hr1|9`@VAr1d$ zNMS*-{~Yo^uKb%)k{3Di|KP;G*!*x7;Is5&N#6gKne<~W60jc%iY&@=ML8XB)ZJE` z@u$kV_ltu3Bu^NqpR2r-?{a;@@Rk}=CqeWxs;HvLm$#hWiqFUyoj%_gNHP&8JbOfl zK^Qqu!thp+v71R=HlgC)@NGgzSlB;&4vAtu_qSUA+iia*cku$Wx$6fK~W|%j`g1>|82mJrN5pY&jjv+HXzk??E zf4%Ahu^7Dz!T&kip+$tf0b%D;X8Auai<|=b|2g}=rm#jdJwMOoKgpKBxydF;PKv_^j@lr3VmK0A1x$ud z5KY2!m+h~|cR#WzQ!mrQ(fGicFZ353SRAeQmpS)_qh2kmw7rZGG+L5tjD+mjcPE7u z&}^SSKTp;3mcpr>*s@Q{pk$!70Gwl|L>k%AwiCgrxaNh^^4{;av)|R?64k|vpPb%E z%r6sw$zuI8m!D;O>9x~q#D>0sK&UZV0y)i6q3cX^NRf1K0b=LJ^?fA*2=dR{4meyX zeW4AqPN#8 zV9JZE{kpl`c>b)ep4%ztdXD0|cQ0p&>-G6QFWvn`pS~c+;?=iBqaW{!1%4A=B{U8> zI%(hh;=R>6%;ya#zPMeyzkP9Tym&QfmlEoGcf@;Nr73ZLYJOjPk!*gM{G9r3P2=wC zr$$SqwGZ+BR%9}F7pu|xcYpVJHWO#BcG~ZDbfr$#C%y-seq~wf?uJR9&$~t6-|gRL zuMs!iUF{_L_8&XGP2JX}csX)76?8lG2=khD-@8w~8k4=XW)GMT^l%AFChc{ve*4u# z$zr^B4|9ooiE|fZvNG@O{&m|v=iTn`or5ck=j%mGC4MGE!@G;5#0^V%T|eklzmz`+ z;g+raDt2qf{Qhd?c0VZS-BzK@?bhT*^7d6O{Z;PU(1ZB-r$$tkpBgh@7r-7G9s{y2Ds97jlYGebQ%@y))1p(_Xi${+H|dC-qw-S6Umm z{;}=7pujLdtw30S1;#)!^HM`(zY`~n9+!KymUb-3oQx<$)8BN`bKL=aDHZ5(kwt(v zGVS!%R_X7(4^O`bwO*`Hv>OlsQd%^V+_fYujaj%qzrQn|7*1`!Sx>Hp#rw_Yd5`DO z2^+Sp%X#nFn;YLO?BAN@Q={V-qFoucpBnd4v>m)#5e-}wEfI3gauK0BZ|KwI`0JY5 ztP>YCd+-w~U3~#?|85|%r{b#D{HAvW_^}@yAFvDQ70f=2d2XCO<1?V0t+hMfSnaDF z)JvvMDrO+YRhZ>zbU0opU3)RVA+4Y3wcyi>e5dDbi#LBn^)WN1qJy2a%QYPNU*(JW z2AwDe>FmzdmR<}k-VBx8kpffvYVma}C+Pk>h*$dPLp-Th`}ObYfV}wXxUAXt-RHqr zlAp!j6w1drALm@pZ;*>C^E7RKDN)lm5Ab*rs3W)(<=)<1A3aP&bi%%a^7)4^x4^hc3r=UxFn#rwj)FDE-_^S8xWG&f^1^6?Ob`}U2V%O; zlex<4UA+ChNJe4q?_yn%1M9*`)(&@5x>%;aTVCm=zk`u&^u-q?ozwGzKkoj z1SWcD{ti083evRpyA{(3Ym(;IR#3^})m6HL@RRet0oYz9gT{Ycc?Y49!o$D}K?(nh zbP;;t)8~Qv=j1dPDXhy0^LtKSs%PlkA3ET#@o3+&Ij`eH(0Up?yB!v7JB*Eb7nn(! zV#+^vh}5x1&K)?Q8i5o}rIn4cYD7tc1I^w0oQwAZ@2?R1H;4i3`V~8@Q{p1}hlNHMINK`JBJVWz97} z+t`LuqV~8i=%x=hlP<3PsrQg(oI2bmx4kKws*_j!2Agz>J8jElR zzx8B&^7dnicJ1An>O${jTyp~&x1anIPlSz?d9u4oaLiAiZ@8*^#pR3*Yqbo**9yf`hIe0AC`w?FqsGQu^l4ouT^@c93I)v?7J6A&{~Zg ztuvhkSGY%Xm^}d-?iw@fJKz0r<|uq8#qgMGk?HG6iBm266zf?I(I>v*umSoM+EF?h zj%|xS@0KdNA~!CIbFPZ*oDmDHex>O|R&D`_jIl9DbB@;<|kh$bZ=h|N6BXe=A@1dgM?4nz32wE@}x>M93ObJDhmX2ml(Gb0isPQ zG%ZpZ&L`~>;3E*9tO~azVjk)%R!gj46YJ=XDXzaR5jc{=@=q& z2Il|cuL1l*?_0lI54H(BKYcHOy+hhd9|Yq>sral zqtsZ}Px&9O30-}%^Y;5&&b;hfl9o$rpC?sfDr=QyIlj&TJH{Hbs`u%{&$mt;U!1-l z9~$Yr&H23wRrzys_m?Hd&oU2^C+S3`L84D!`#hIqF(IOSN&XQer(e*Lw_7-aJZpb zhAG08#8WBSX6oOE&K(C%i@Bd}!ci>?y2WwXTmAnD7QN@*7+q27Sax~UnEGt_v zoh=qHWrK9y_f<6J@Wxnjt%g;+k`OM}^D1$)=nZ_FDU{+rM0Mjmxuv>1_)9_LQ+0aA zu+Ft+;o?UAiC;jY`?i07Kc)&>#m#L-va4+`8cg4}^L0fabo!_i{&~Js@ZJjEg2lwM%G8kCmj+d(?>{ zvb^d5J5c`UZxtMR@=BR@B0nktA93>i%Lp0$+h1Mr42yp^4#MpY4_2jlHwh@y||4$G71T zDs|D!CC58iY2hPz%baIzct&_;RD|>40Xt7V0TPf&SA#t5e`f-8sF`TZVUG)!06cHK z4*R*{aN+AS(LrN~->0zvWJY8Zdy zzo-|HBRexc*~57-k3wvVrK{LwPaIuPb1AhL_h1+0s7$fB$As=-|H1_R^KlwLf|P)5 z{y-tweNZxZ3`!g(mTF;5%;Sx>)>8bXql<#*tYPV_1ViEeTdL+9BBG+K*N#_nS8ogf zDaD{7Rg`aFwC{nMil{?#0uFP0^QXGJGOPr(fevaf5*EAt3IDy?wiI2(8zTn3C%|x^ zepzMFhs3x7d&vQq-)xyb;M3#I+J(84c1Wij$l@YJiUpa!%#?X-+n=xile>xqeAg{q z&KuJQd~5R}A6oRFv3d!bpWaJy6;}>TC@5 z8$C#09PLBk>Ng6)8-|I%y_LRRmsuM+XhB87hEL&7Plfb4k?!IWs6F)ERN$#SC=VAc zDh+o@j|ooE+*@pK zzj{p!H@~Tezm+3Aoxs96={FN8KE?|7$B$LpJ^*7eKNvV4(rjOb8YMjl+yWJQnnlM| zq=r9J^cN@qD7jcOf1V-ABtneZmp4AWdmbuB;9&pZ?s|*l4&+nlawzt*4lS9uf-J+N#CNw-0_ymKzPEN8_m%TEC!7>!G8|b7!1K z-nL+4XCj=3nk=W5ry+BDVm0@zGnU!)ay?ZaUPm)*l`9Oj6A5c&1pJ*LIRdQy!vOkz z(tkS7FGQ9T(DOHsw6Pxnubf8Q!Dg)>c3<52gyU`2#B?=O!)4aCFqZO*+*y{(L>VTg zfUQjFXg(y#dJ?@5J-|~0gYFW7H;evS6tIHVv}gP)PXY)q;87i7`(Y5;y-hDbacbmI zn3Dk0DGmAXwRT6~s}cL-+y#b?v?nkT7@imm6ZRO}NM4u4=H`Q$`(S6MT z71W9h5h>UfNp_Hig}^x$9f&Zdao3bFKb)-FjC3`nGU;$J!X+P{#x-WQiYqgb9~0g; z{2!*ppG`WtQL79@f?E2OO$!D-CyX_RuXo0)ll5(E+BFUu@mT6e6<4!j?K+2ztl zJGJxI5;mqsa1}BJ2s(P(XxsrCG7y8EG43MoEjNONRW-$`C&WVp!UhZn&+7A+bYRjW zF~Kof+__A&)l@?br>63l;(I-stZ!@}>8eE~Q5!dT>6A3Ycuo@3Xz@3dk9IPbV-ETk zfLcxI1k|tdAL$v1IzgtZW+&{J{qi~|X3#AThEfcQQgMo=Wzvz2P-d)U4v{N^aGoVp zcyp%dj-*AnVclUS2(NFG4uV2KLqq^;{PW4aWF}$yt2Dft@v4Of$vqxs%3DANxDF{xqm!N3WCC{Xv9`Nq##1=xrY1Dup9bXEK0Dw)&Kdi5&Q$Dvy$v1UQVeWii0r zvpTzKh;Mymsr{!UofR#nSR@Prf`DGr48r0>e;vzFOS(+2&4&oPWD;dI@niDk-g6C# zuP13g%@}X&+k6HGxxAOgLJLp?_#hqkqK2KwKoEm32Jo0-j47JvROw-cH?z|IK5`~1UQsnIZzUw!GSw0m8L>^2c{z;4q8O(+>m6g#$))_m{>7kJO zyW3=!fig_{8l0AQF``R@)X_c@|E!V+eEQvSVa>Joq{L@}!ncXB!+?)Kj7jY6zf2wX z#BihN-imi)4?wNLA}U|nLu7f0K#RYNC@Peh(Lzq;Q1VXT)XrRIdvp3=>aP$z$n@$U z=t)g|$FN=5&W2NjlpU5)d}VC4B~;;TcSbNh`K=5bh371>6^OkWXK{xPk<#C(06FPN zp}h)X;N!#KdwB~#fQev=M3y(kuoHymM_LrY%fiv^WuN0Y!Q(>@d(#12IhSf3f}69u zUTR5Dg)qv2R+(a&U^JNBM%TrW~p^7~g_@V<~(jbh{|$!8bPgBZ?# zNifecgC{8v6qu&Ga}$7fTslGDpJ;6VT%!Y!-l4`eM3Vi>@PCxsfzZ(1b6<}+_{3Xw z(3?_8<4dx9Fn@Aqzp)tsrD=?<{~tY-*igIO#sV-eOdgVW)mhDW^WM@yi@r~oxYa}& zuxKv&<05{dO?)&E{ZBiKgo+ash|VIM5Sl02JzmTxz{cJ)=Lk;;J&a+|$@*;KXNkZ? z;Ls3fYW>@^uU;;K0p0eVr$>g@4hO)Z5dzd^uf&N!Txg(tnk#4gmDy6cLOyAAiM^W6 zGv^rmsWdyKZiHR1vj1Pt80fQeY2(lgx2PGS>-c5RZy@#nF5KL0NSKTVU|2w2A3Ti1NDoh!B{%*bslgS7}oeO#si9B@WXT?`zt`=6M5tu}7xH z&v2MifARW4F#5+PXS`zP>KZbW3v`7{;uI@>?G~^71-nFF|0*wXtGrzh5Z53vd2|70 zs(`oLY!}{zAMjJ-E6_QBsRhvZgHOoC0af?0x?c3mvd?rDC#>aCRjs{RjJ~WVGPxLL zB7lvu`Yrbbc;0zOz)z8ua!NC`Iq`|PLm{5GssfxTru@4M{;9i?9GIYR#&T9HOlb0T zB-R`bo;^YiZG&AM8w*}%qlh`zNJ&M&^D}HI5;n9F*~97wMG=aM!vxe&NpO60l##gu z-TeMrXOaw|R3^TS=!)YUpK=PnwWAcOg1WQ1^(KEg0Abn~J1+YveywrYi(s%S61-TP zZP`2v#<`v1`XD_scqd-II{me6lNkFJSZ@XrhFF6duRY?WT=kJ4`-I6d%$wDCnZP9T z+}wQy{FvMrVVP378~~5OlthG61SI>`_;!eQla49V}Qy8`@QZv23i zZ@<~9Lh^DZQaKEU)b^qQ5gcjOIEY9ah3O)Kr~K3c$S`3~3|ge^Jd<7t>3B@kkyd&CEjM4=SF<;x zk_>MEPgfutnOx$PkC(yUvu2CEShdGg(br3=TpJOSZ{*=8$7!VGI0CcTLs1%1bUm%J zj9&M44ZN;|4rk+pL%O=U2zbO8Xfl}(`^}=&d-@^)oCl#f-8}w9v?P}}2U2I|d&!K4 zi%MCTa-??*#88i)c6jz|ta0JAs;wAlHsMiKo|v-LD4^doYw;}DxCba$Lj?Vd)H|x= zNS)|>mrmrU6%Y86_3g;OxD9m>gch3%6*UHwqDia>fm}QZHn$*)VGkz>N5g`nhbP8x zuKcjDdIo4Tm8wxO3&5m}QFH`8n5HC=66I}XqR+S>DXm4>PMG}9+grv;E_*hpSB)Fe%cf!0vXNjrFa}%Z#x9Fd12y4`9zLl*X^;}{U||{zkOl#m z%2kB#AO4SgpPBH`Lz*hTVl}ep9RJPA)IreChAj_uHum@k7q|^j&wIX~ovx_Zplo=P zD1J`U_U4Do&p{kU8F_{Zb?hF>R`oo}07Eu35CK3BB7z7okv~3pk}OyNlErAn*^nDH z2(PZ}2}x7X_2lATQaN|zveob}IP0(oeKZA9$6B?9DlC1Fsgupwl86u~uI7r?IO~d@ zNvO;s-kDoGH2u9Jkuq8hW)43561!}EyRBbZui5OmS3-xf?C_Ivm!$|I3FdQm-?Y>? z9rPt>3oDQN@)-V$H=m?$?RFV`Su) zKmaW(Mg~yZW$XjkSU7A{fdFiELfH5Yz5VlJkVcp0Vi+%WN@t0+WM3VPIwC0xpK=FJ z_AxH^;Kw|X=|sQq@X)~z%5;XbCd^mp3KtMhgiWweR5>;>Mq&8tG@D>Fyt2n3bB^5& zvhRT(tjG0A+Cd}%92#YYSD)LClY=F#@T=3nb&aNvpC_U_ZB2602LX11qJ#^zRoCen ze8!UO2vJb2`ur~+yc)Tg*ebdB14y$^$U?*fn>$UX|Vpq)0%j?O_ArajaSHS}w>kL7@Vt9s3jtf>N$p5t4;Ea@!$pJzLT4 zyx2w-JF;E+h(dz;wam<*AivqKvcQ-xkFWs1#Eb~*WDMrdyPsqz&)^U>OVP>l`I8>H zGnPi}5UWjD9K%95;7uZ3CKy_|mN52)R@qko&Y}|yk}Ho-Llq0=GJxfD5HI_$4#~t} z+Y%i0k#AOCeb+b>pzb;*4g`XW161+;N}{c_DhQZZi5!YT_!fk%np!j9-Q(5q_Worx zi?BPUjtiHy810mv*inPc{m6;>n98K?A88+LZn|8``W(#~Cx46^yun0a9$Tc}&~>Ii z#f}C%beoaUpih5zz+1dS={mnrM>LA-{sm;2IJp{*rFT-;5bdO}Nr)i{gm`a7rdBNs z?_fKKn6n*BsKLiIF(!7IllD_F2UOBJDM}#QGE@E0#sF@ANAfXSXnc4t*Mwa}L}i5_ zN=u|=iF&>P?z1MPLa zra|<%9@2R@&flEoP&uY(#!{7`x@RBuFp%M|x}${ZjVV$>Bj2zmZeDWF2@_QLY5&~SvwHZFE$~MD4L(sDu=DxU1^bD0&&!bnFu=3LX00k zg3-`<&7vcD(vaT!qy*<>==;qOwNQQwka8>(R2WJLFUgHzL4}a!jf=+}K=$$3YH!{wGR`Ww@THF2kW29 zto!n`agjC9cOBvm`SS*@08)zmvzDkq=ZU2}=}TFVf)--#svu1`g?+2k5yuSRMM{)I zrq8$2wkcl%-f#W$jaeWGkcYDPFkBM7!z161$$KdbX5nD3WYtvtdOE+O*I8?d)z9!& z7Fdq|Ob{ZbusuTgoK931s4*WU<2unHOG1*UAdLl+D1j77u3XDZ0_T^)aiEY-6Oo6z z(s9u+5dfbG7=IDL^ANE@s)Wp{`Fg#%m&IF>0!l#}g^M5_GqY`b!#Pz&4kEE&0E{q8 zlGKDf&I@M-^r3+@1g;rg9HZTuylP2lDTX~B3l)po>wBft#yvXms>0gsFmrWOXG#;Q z&=KP14m^Kh>Cdxa1JT{N9W)c5lyW+x%MFGc9c6o99xnpL!Jt(LWaFbD0 zuU^90oi&;9uu$QN5wxi2!PL@Nt04Fm4E~C{cD2|g_K;M3&vszuAm1(SZED8Ty{uRh zQ?s}xhq;I0j0X0n)+&U^V}AFU`0Dtrb1pf~ncNbBN@{wl0W%-`$y8Y<Bi78)Dc)*aE+!mM0xo~E@ z5KrimEB~s4?5#}r7-~#9cDI}?A>9K4hZ7)z7sBppX$z*@++~I^*^=#&29jL z{lxIbKGInNaEl;DUKmG=(8=2>>psm@^=2C`e1YM1_^4)-B92x#Fc7wLL#gg)z zb9tvv@hN7zy^S_L)W88Czvm=IGsMigI`hIeZ{g37L|bH&UU6d6b(?5UTy8n@-`F0X z^5x8*f_UrFb$DD_4QI6UuudGHz9<+lZw^WHwfiSx2zLYWY_;!E0TAfb6ZqYbOXkQ9 zt0*IpT|0dji1m#apSp)Zgv$cq)U((TjtXNPbDN1l?*ZAj+q0yn2#7_hlH|I>R~EuQ zJY7XH4JqiEJRY^lj-09XV?sA=yn|H%zl7nZy{AIoXA&6AqUms#Ee}8G`>R|W0PCYO z&0fw9S~*iVBP3G%g|%NpEc8Ng*=zYTsbht0ytV0a+p#z0dQXq9Do`=ho_u=Dpqi)BZI3tfr7G z)x`C=$C2b&WjuG=?Oc1Sk*j;>BMMSypk1hxy{=E{uS@Umzn=BWj7D{7)J3N9y`i%3 zpZt9^)kC8oD=g*lP4RA0(8_U9w*)0f8yx$^Bu8?y%f~?`Tfp5B$GPl#7fStJf3Mq~ z-CQ8AvXrC8pIITow%Pnj#^2}GhQ1=N-|Wn;xs^3NU5;n@T4C{=RW5GUprYayBb7N` zvPxV`xkglRBQn6pe(+gKJ2uzvOYh%1X8I;By=1+mKsvCZ=IpC|m{cg4?+x_j>9znZ zG3*Q13+Lp>PM0XJw&Sec#GIS872)qbYC#_axyRtJHdEUBZra! z@|Q{aqLZ+ks1fKrh-Q`Adj8PH#4#i^OZyiVfn&s_@j4*KNis2pMS0BuHuh9~>FWk2 z5u*1a76iTxlA$aV1JN{v^co^;Dud}p8hf&@f{99RSwU63i zCZfRA@hG6#)x!tuUY|VFUu$cg__D-Q%{nQ^eo9T8Fve>UD!)lMC3p@+o06CUV+}7= z4xw!NJZtyZrv?y`K5Ne;VZ$_XmB$S4_@i;qD~omJHeX;4{v+$iwuD|)v!jn_%8Cdq z>c})T%?`e`p6BnXhozfm1wRgCB&Qn5_o}I5;vZsn%gTyEji|%7_~2#b$uX=EG|D@Y zT5Pn1pRj({vNcmoaT+@eQZ=%avw{drt&@`HzHdXj|>4NIN<`4(8o z)fEO-CGRqcRb?cACd4TUXYX$6C|ur_3S?gxSnjQ1{6k}@&qkL10oIG3zM1|<{fYk6 zmet|}*dZ4+AsKp35HWFmsT~2wcDO-Y<=T=>UcPn{afmXgpj(0yK!+tM0tNg#(~ewo zV$=(4-%1%-InnFN9j02IjSG`znO1Hy?f1P%TZ%~#?NQtQgu0X`0(tC!4FyBom)8ZRva2d%<5t4sD+{a9J7`XzWzcyG;|D{WlfNU*I z{%}~NELHN*4ft)2`3~8@M~n|<#1;WF0c%Z(9~dB*p#{9vR0>xFUXNBD2f8Qb+ff$9 ztUvT8#t0%dhYZS5J{6amoca{8yi-;U zA32?se)~ur+Z*VzbjzT9Wy~kA@wUSVOfL_l8Z%@Cmf!lm-?WYCQVIlgK2s{rulY7) z5J%f=2#0-`=1-AC!4aeW%Kvyx?94|m55FL~2Qm3w_$r09d*n##u+BAUk13<16xW&9 zV@P3R0r#)L&E_RNx2LGP4V{Ou&Z~^yb$4~HI(n>gURXWm(eut${%$#=ZePjAg@@MK z{I>E_$&o899{aR{apV1VP7{ z^>=MsiIyB3c{(-Gmf|A2f50inJ?fAxsPLQbG;uz40TWGs-e+BX{4}9yMr{O@tz*ym zXc&gjkuvpZ^jyDiJaKlwxm8tV{Thp~9;n&#GX~E(S-(GbG1U8Ol=R^}vph|=pF_qt zrNV)wjf(nAS|ti0b;pVV{gvh^G+b;(vJ{y^y$L*oN&kshpBGwp%62QYco)^s0Jch! z7v|;>S3RDjY&L}1YI_>(Zo}PaX=6!K#$H1`@-y-6cMWHBTE00LH|o$vuMOpyf@#5R z`|-(h2kB2+=X#ozibFrEEqJUu`faZ@t#Qkci}8A(Fqq&qQnoU zRjQbZc45th%@DOEk!6f)s|>-7uX6AZlk;p+LKqE|hd8nXDV>Kb94i54>G<+6zk6f- z0t`M8T>XGcZH=kS;hkj`URNX~JzVJKs^(!JW#&mI{w;9Dh=6VT_&Vj!Gm2sQwm1D! zFNRs!&g=Q#budZIW>Roz09F365?-51ue2a7XuL|;3~^+7{0x6)Ghljd`Yjgk=4-%O z)l@pMZk@4CA1sText}D~HEB-^$8LdAxxXH~w1ln$*G1ad<51HDsWJxs98u&7>Q6~t zG@cDKs4pjSuFfTXoI8-m-}=q7xN~C5YL?+(T=$J8+2g}EN0X-{x1|Ot6YktLpNyrN zYed5~l57-Rj}+GHJ0q^!Y{EO)(ehxu zm*@OjWD*yifA-d-_ZgUUS6sf8)TLs~Xh}MDOG{h^!Xm!!eO$`IX12~0)0(?^Vo>vZ z<4UhjdA}tyA@-A!on9FJR&m7~Ux1&sZI5GfYs{;9?pZx2fTyb*Xo@H8og4N#DOiPMs2j9Z&gbWao?H!6^7G^B0Y?Dp8DUR(T2J+IYm6 zR{m_}jjH2_p0x?A3CBg@V;-k;us-`J#{wVr3*2_p;!m5?GHmLex{@(`i!utY7-f4!`n_ezGkIJi`@Z;n zjYv`VwA3<>=*MoK6uqCS8((NY_(-F>2d()iXQnUY4x_w`CcI4r%!g*u zmrU{TIY9)S?;8g#XO}#jjl4%HgXCMjN4#GGnnoiBW=4$TrNyX<1J6;Lb(*g_AY6Oi zv;6r1WnR*)^PwcUbRpK_)Ti8y>|SQ!%W6~<)PuG4aT?KD2qi@BkHb;zRAp()JV_W& z83eUmO$E%-JV%jcn{)k35;sdvO|&-ZBkqds*XWlIm18Z_;=%t@u+drDG01M#~W|KDxLM z-S(4BU(#XO9H=eMxdM+=`&q3Ixg8;%MNEUO!a%T+{-V43T)Pf;y^8WA&nb)Nic&f%#E9kVG? z#0?Qzb!Q)~mx*iQ716BBu*lm-!!gqpK_n#>U4w>>S~4q<%q21nHi_cZOvH6SOG%%n zq|%3v5pj7TavV^Ftkk^D*c9rQV$|{li#iA;yO)&8naXtJ`~{aTJwzX0g^?cW{GfC( z#pC0ZAk1p}2F@~b%C@~q-ZqZY`0YxgxGq*?y29yLe59jf`)at}x?e%PN@N(`%Dg>1jC0@fXrWaqQ26poS6r?GM0>hASIvHjba?&j$LFzl(=eW{k&+Z?l=-zWD_- zD8Y)L;7f2P&OC<4;UL?)#VKkg#|-7PN6kLt?QFC$r8LSmWgu-}HD$!GyXiF+Pm7^x z!DwA%)79rh5hAU)m|0dMoKN&aJO;|ayENuLW^L~^0y6{_eiYKk-NbU}-mhlG6}Y$7 zp*J?qVdHB)^)eIkc;{*=J=45>o%VM^G6=_2@zYgf*^TuIq>=$qCgFVo=0c~h=)hT) zQSkgb5B7;Wr%d&!=gy4xVHU>R&@+&O2)iDj-Avua?dZ-lPvt!AH1IGGD zeZkZvZUJ>k_t5L!1~OD5^s@51XPY_!j_w;)Rz0ezZ{oiD7p1;3(y5YmyzGIx$d{}8 z_rJK3a{bkr)H@5QO5wWuHO$DwwZl=o)5TylHPbn3H6HDf?yybJxtNI(nk@S5&2 zI=RAhMf*$t4vcGj24RYsjvTyi>otT47^rs9CUynVuv3D=cKQ0O3d1HsX~ z!mt;Z^k-kgDHdH7c=Ie^hGubK-D>+H=^TN1#4g=Z-o)|jFKZ#ByFZ@>o%N%d)}%OZ zvCun~)t#!X-^R5Up4aYE$Cj#&oK@Jr$F@(@RTlRlP4~xmOKsm%Uw#YD3DwLwFcc+qj^EI# zSm~dh4b~^RFIH4L0*m|Pv0E!@a9TKLC-wb-)pS%>wdJR(Uo3W~?0=7w$cOq3r4O5= z4GlT#E0agp*oyqAKmB5f2t6`A@~ST$`EhZ0Zp$q0;hrpBoYBe{&=zlK;UjV&39KOa zR=!#PL%Yu`UE0O;&N1fzm4dtfwc%vBX>*jv%vU;u^7gJV+IIw7?`6Y|>3&m~UYR*r zX`2gQ`KO7cPI+H8g0+&$v6*RQWd%ojg=Ub2qxIat%$aa<1T`+|jZ+)aVEP>8uIvgFz|XZTdj;DBc0F=1wv^}DtebRID#|MIC> z(!nn4g;Ss(!C6u8%3bcmZ>yxU)3ssuZ~D8|kU|&hm#0f3u^+L1B-oUu#L}`Ns!}z% zSF9Wb-s(V&!E4PwUIdXO6LV~@FOz5?A_pStxFuo{&&G4lJVyg+jX79o*_A^i!MN38 zj3p5ACcn~({ZfrX6SX&+3lJ+u#MtXv&t?=+w{WZhQ?P= zP)M2i(HT=^^(np&q+w54+usOMtiCVl;R_j`QkCwMU{2ZhU~{zA@@-YOa-ngOgWF=Y^2U&^*ZMSGct(Irt-d znt!^t&Y5yyRM=Z?w3WDrEG!iwyThnS^tPeJz+D+=;cry}#LLukkJDIQPM5ocv zQGgE;``0bA4O}G~0>f+1eum=_)6Zm^U(ZefO;?06HwR|J;Xt9QVY{R>3M#c@*!%Z) zbM*D%{ar6f_CeToCa~{g(MaSn8?c{f077sW>hWz~$7-@6OHWx6{geMn6q zz|M^&d0UoztRA6}=S5X0Pw=c<(!c*g+$(WL;DX;ly#CXXW38!`V`I6CUt6)vNMhj9 zuksRKMqcK`4bnqf8x)(?;d8XeDq?o7KZlug;?he%u`LEgMqby^(tx!SuX7{i@>#gu5963%xiISl#4#z3sfo z8nn^*2@+B_ZTpftpK`us(h_GvD50)by{Xv&&pf44ZjSub6qEboKEqAPIhNI*^?gT< z^8-Ns7~{V+!^NDl%NL#NIxeRIru|4fRI7ZMa+OZFZ=y1JtZi$xo|fP|wjjsgOsxK% z=3~jx5wxBuZnp9t^#eiugV}69$MvR7MG>-b&$+*(@l^_$sFeYKX5Nwf^1%GO6RadUnef2&m6%kb!A5|anGcP z!h!Q9|Jeaz4KQO{jD|5SNBb**);xwrQZ+EGt60K$)2Cla>GdRU5jxX*X^oX$uXTUr z*h^<|j3uXz6(0|4xvz2wpN8DzB7zNWyz4C8=VlU`D1)1>TP7rWfO$u+*qS{pXO`}I zM@jq?y4hHC}a5v}sD-9meyPw;TqIiKAN7986dOi;MA)yxhRn_{LEo0W>k%^?49i>(<6nsT4@PWO|#`Yh0&)C=hDO$RxMYvaE+( zxpmsiNg_Dqw+T6QpL+deZ+~Ba7$xP+XJx^1rp+XrGvB4m1o(mCms4*&#qCtdu;AH! z*R+aGZj@3BH1s5YJK2mqK0GOuX>GEANjG@Y0o#blkX7So5)DayKeZpk&%uoB8|WjA zY}}@2WlD8|Pa(fG0>>sA75BUYZ&vAf)q%dx{9(PJd}dCasz?@~35z=VZJuNE>;QL3 z*3M^r^@zfgp(7RhGX)p6P6^Bx(R2wfhD)X;!9q#QY}}MZ6OFG5TA7za|r|99Fcdl;ZzVP=N*w@$E>gAkQ?z(wf;U_9VnYghh~GnZNEy|sR}EJ zMjd_TsrQ)zX~>A#VaC+^S=PTgG%gYGI_lw9A)y~|Ki#Sf`PX=WMjUCejrCtBtEae9 z7gTuBywrn?r<@XCypwXC6cV39_9CGu+|po_mY1O z^Zbi=AwG3Qa5~@X>%bnHZ@Tl+yzl=XP46Ag=KFt-*C=hRwnnL4)!0fE(O6ZZ)ZQ~~ zQIr@VY6P{tY$Z~}7O|-jwX14H?LCSjViqxjw!ifK{eAvV?&NV_<9V)g&huP#w@BoM zP^)q!>~1{0d&{%I>InA2-&ZB%`3Ei?_Hd{qEI`K`xE<5Fsq1lfjb=qE=d#IbyohJjT;z%Mz8W^=DP?ekJFZI>*$pr?N&=EnX8E;X_)9qs;o6hv$L9F^FmgDI4-`J3Ou5}kb<`Z_ni z1y}z@xgzzRfZ=%>+c6xiZVX*($R>?^r*^CmP;Hj5n0*jUsi-S$dpNq8P3K2F?4ivo z1lxabjCv*MZ&>v>EZuPy`px?hmx#xvm?QAcwfMFnx($UVylhW$&`7%g7q73^0b*;9 z8n9LEy`7YR2sO@$e0wavgX=8W4?_l3Z9}dE_(p`jc#DzU(&mhQusaR4;S=LYpIh-9 zPqL@&t)8Nlp%k>OWl=bGDD3KQht&1>7y-Ng@}mCM54P-{R~uHv&x5VQZ3_A~_emn{ z)+yp|xhav4Eh(=qksr+nHgkjy{Ws|}Fz0=x{hjQ$I>)F#$D;GdX8B>Q6Lq3=l9Lz> zV4(JrUL`vbhD+@f7dum!_}6G^_gAw=dLQZCLvBy0UH{X+2<2W_SKx6%d1?4da=iJx zQ#%kfyDw}N)Wsm@W*4~Ikd^!Qk|4Kv>ZE)zE5eY}TJ`G1OsK9u^PCvNcI@ryCv!O1 zsHORm$l=_{V?pG~ge7H>g`0Y;%8;YiYpWR@dc7 zwqFKc4uNb;-dS)T(_E3&_0LV$J5$f7F7%;!;B}CxjtflzhoZL?26a@4u26CplhB; z#}a+-aXE#DW#^K7y6GNh%Ozlc_EI*gYHc2eMWik|j$(Ifp|bAtKn7(~8oSu)<~56C ztQS5`gz4?-T41!AqfveT=sroFXOZNbl`gfMY5vgyL$L^%pnn@svYaIHjbvo)V3!jFy*W<_6I$g8&@XrZh)dLtvlX-gX z%A}KjrA=%I(O%g;&OHuE6NGTDld`!gEa2}K8%G{;+4|>z=Iecf7j%{&CT&cy?jxrU z87Ca2PHnPps<$5;%bpe0SWM;`4f{y@h|$aTa(Tb#HR3q%*UdlD)&CCve)=OG6xa$GTXnt^aeyr%Q5#F+iWjMVwPHr>By}S#VfhWB@o|8XKP>=El2{g^&kN;rhebrejwo?dOEMk;BtUb0L*8D|p!{4#pue?_bmBObR9RL1m_1O0= z-Ni$f*lCVZT}N+{+GtbEN%@{IChS~nNr7V}Fb7vsx#3Z!Mlv%4ZGM_~!dIj?j1$fA zmKOtibsTBCY~n_-jA5{cYw|@nqolKf_6l6NE|6B0BrhY+T~sONm6hI#G@ip*X}&I; z$a<2=bpz*b3mJnrOg!*dxR8NPNok>5Ha=98OhUG?Ue*}=9mo00p9yfHF$i2GkuBok zUs}6H*m_W{qqSMR>eXTK>?7gPZEK3GFTbMS%dI^WSNcjx`z%mxs$batMdt%l(#)Y$ z<91eDR1gQ3jSSbq3oWMIm5h@fDbbHGrWBXMt$5SwI;b0WL=Gs}9PFlVZV zZsnnnI-9uueu`P4;~4=wy#>!fvrMzwADPW!>2`*xK6CK0FypaHmeZ=8x$WGx$s95z z_)LA4EwG3_Bx{L9AJGT`=YX<2R{KPD2hb-n0UT)9t|-Jsg6R*as~{((Rv=1=>LC+c zjBUm^D8yy{KDwuMr71dTddVyi zYU>cBXgmJD(^BPl@^&HDb;C6`;DC7!#x4qe+-tm|6-`yIp z=%x6fRC#Wk80j-B9UF*ICwBrHZhQ9K`UHjE7fbs5P7i*U19)QuYVd%j<&4uB#omvrIQs);n`6Bd6D!CN$oR4r`Hnadz{Eu6*a@-M`5;lHWGcKwz2q_FXfa z>h@4?sIi6|B^TYImM5`qmYt~nQt}#S?r8$mkARo;`AxK%S+&57{EhDoA-695U%t+! z;xrHZ`JbeA4&egSA2SE{tGC_NHykdES0vL|Tudbi#(FO0;h(uEN)j$WS?Ov9nh+i@ zw0A(7hZD#RxFUFkl}7sLz9>O0F&g%=WSDo#`Tj7bJN)$*<2?<370BHjx&0t3X#?&) zp+)i=z$VNqz_Z|18Xc%BTQ%hQ?9g2YRjR5lk)#6q7kv0sFEpR3V5Ap@$K$>^tyFzmRvGPWh~8?CKzxuA!K&+MIuISjr2irLNI$f|$d;(384q{#!tV}I?y+c| z19WP=WMe86EoK7#B*GnECZ-Hm9H7Db{|RZw>vf+lUI;K7j!_TSZ6;_J2uUm!Bzxml zBN@PD_rTx=X?1J$Aj@2Lw1ZAxx}csx3p}$GnOW_WVzv*@#X`RwU#()vtrh0zpBnvP zozYCA*x=YNurXj>kYj#5BX{gmNqgRU>8*@sumnAJ@q0~VJ&O)8|4h3OX03qu*!xHt z-S}TLButl>-~liE!uWIBAgEq5Jv3=Y#;rlg{%0?X+xl@sxu+7SSy8J|kpv6{e*Op} zv*m`&iAv`iJV$Sube-d}tzbXYof>^_m=rTW$a|-#X11-ve7zTsbp3w@r@(m|#lwwZ zF@-huwK>`)ToL`ujOq4^kLy<~*bi+MCnXL~nU4%ll{Gs@+>;Av$^h9|M zO8z3wR5zb%#Kpi^Zti7Pm4DsR26D^tDnccoaIpDMehqx{$kE$H(gU`u$D(bUC7eS( zNzk9cv6djwX_o27Tlk%06fSE$XY*L7QdT8N>Gbxe)cWm5(xnbG#ct{C!L{!)$OUzS z%+Qlz;*chMw=DY5y2(XZcYfC8d%in8m}LjJV*>Uct|*?JA0cWiT458E9R2~tT$_uZ z^PsFnp^HiZ%$;^|Fkt#YbzIfht&$#&vd@)WhdPB1nn)A4+0Qb;PaEWI}Q=K5O z(*BO20!J3t%Is&q0^Gb148CuPfw)Hd{ac%Mn#vg#P{fKQx9uTh)@EV*86z3qwWd{x zF7&{x7YQU{6MO(rRi99(b6F6-z1)0XLL~T3nQLj)3%z2|j;h3B(7%6!7(bLy&&o+D zl_v8)mTWq;=e4}AP0y~;xhW(nxf_vJr+CW^g1w>nBz*vkxb3i35P_j%A=q=Dx_-Yh zTU1iRtR}bWZ}elQH}BE(w8Uk?7~j4o=Z;CVbC&dBa*DkHMu#S`1ku14nV{1{G%=3_ z_#g9>e_(Uqpk)JFyOFA=U&-Z_Rqd3A`NOe!Xr3|^ zXWGI`xhV3r>>z(>=G|P;A|Q~-jm+8CF%T4f%8yErlfZOoEIGR_HYloBibqT^?yVw`!HZMB7S?Q(RdI{}AoNESvV}=3 zOtb=c2aEOuooJX)Cb5$FslT<^`NW-)gj6u{#D5GR;`EhV&xSB~AB(M3r34j}4ZTv;pP$IKY1L4Uzz1VM2`XAgmmA52C-BxwyyOy`Oulwh3P=Ww#>wuHBMBi&%M?sAaI$f^ zQM}qU+I$o4d9UUTQ*T&YB*pmcGTFe#=fT9`Lx-WwvB9ZDXJb&7vMz|sgya@8A~p;D z2elhsEy^6{6*3Mi361~xLP2JJ<@tmG&vuJDw(3fVc~cahymFleidKYwOpR(GZb{-D zk}T-zaVEa~xLWHb&0a)|{#!_R0 zE>3i}{%mL}TiN*ijO_N#IYg~UCHcQN*l|)0{4jlbZTywsm&wlhiGO_(^1JKajsG%Y z|7Vy!Pzs)IW;&~l!10upuCXLxk#bw5Ey?3#0;aUDQ4}*iV5n(5i?Tub4&5vNTPef~ zou7#5NN~BW?EeRIBhlQ>vt?_9C@R$3kw)&uki|)(r3?*Y$H9zo87l_q;9GgV!e%bt z^~Mk?B&wuk;Z~L^vGUq{ANCuGCN(-WeFWwlZ0j(R@yK##hY%Tv*gpAfOYaMX ztrBr6ESnSVQ$_6X(ytjSJ3(7CbN+^GnWM%0M~45#W}TCT%7#fqVK8Il*rtIGXZP0q zn%1pA-0IR|@XPDSbZg;+7o^_E$xf&!Bf4K;M}jHc$P3hHW7VB6Ln^wyef-Vw^lxA2+-IVs z2=b}dO)*n0rGW|-H?EwuXU5QGq)^gD3$tpNv7xpg`M)nSN=3`im{IAce zB4T83I*S-t<@;Yk=8)p)!U`aS2x!a}XnD6M!9$MAW&0Q58A}$5Kl!ac%54(wki4$v zPV;&E!hi)K?n40s%{=HI~0YzdwSnK`zBBT`czh%-*Y)nxj@AA!a4gEJ`nQ^ zKAQHZ0Hou^*UB7vxSUPT#T4m+x>HJxvN9(nnyz`Ltp8oltQ_wyjvgo=tuh!$gza-Ri zPEb!w7$fLI5Ju-KA39%c0}{q58bXhN*7QI|++Tyu3N0S(yBv&LMqK`r;v(ERQ$QA6 zon8bPbGd9HjQMUX^>{s4GqBLMfflrjxmZWlbI}?4DNO(cIMEM#>s6;C6g@_-=BlZZ z3>dQ{fkM+&Rp4%z$7GO-0zyCY^I)SFUQPM$9xa#hiW<|o{v$VW#;=p+U|a4v%_m1n zSV#xicyx0|01Ban*CGA0%5iu_f%0r7P6{a zi<9IuZqWQpW_w}bnBEDTHm?cv+pdx5%Dzcrvksups)`!yvT~vlr3PB_DM1mR4P+$h zCYofTEmqV<8(s-{aU($lMueEOLK>zXgNr_I{kmU)T9H$_7|P-*0@Qawg|<>9bUZ3X z^FgAyv0!j;N^Cet-7#Y#+_P`b zt$zhBUAVWCEj5`%rg!urS71I?1U1(UcA@t@vwZDZPF+jaqJoLr51dQgd(x4yjR+mY z;K6!+U1cH`THg@oHs5ZU{S7j=wSjANZ0V81wVw;%Us_~H=*7feo0m8qHsWlom6a%z zQ|~^EY8W%q7g_AS-g)I&G)#j9>CVA7RZ|06b0Zh>Q@^4yVIF+9`4jd2RQtSu2u>N+ z#7@ul{o@S^iK`V&Wd(svuk6hNq_0B>>wb?YOz~7)-pn z4LOUl>J=X@;^7A1UwQF} z28FfwvsyD6+Aal-QW>IIRJ{*wb4JL2KPc-bDZF;&*3v`T^E7}BEYY&bWi7?Rl+xP?g{=?EmgSTY z;Ljo_drRQ|1waq~UKnO&3f>O~xK5jB)L$~Uhpm!LJ~>>t@g$x zkLN%g=Hak1{GcBvk5yN5g5`r&E)vAi8`_@O?4zeyW(x~&v$M|rP$&V;C05w2kUKws zM|hvFjgVv%q1?T4IQnfh^)Vua7=7 zaislvsN{8uAnNm7sUNn)B{$g!0nIt$PCI>fzHG3UWnvf2@Zp8HR$z{JZmdoYi1RP9 zlIg`4fP}V9plqJ31hD@pq#du*LF^ZZ(O)2R8qWv`a8cU=n!#V{yvA-c%X$Ys{A?%h z){e_lBaH#9%%d(MJDdy{b52TAuz}-R)!r}lBTm$6m>S{zinAZvhJNcE>t;>Na;|)` z*oyisF@8TNebO!F&9gk>{w2X3*%a~i?r^U0(1>Lz-On-TilV~8&P?mPMc zBPmamm&+N298L7dR3$8iHt}n%iOD9B#d0v%dA*YuW2}KMvaTbC+^K;i)#h-*9f{|E z`3?Ptr*DgH)&`j^i6>>mC)6s!Xr(`ppB;If#kT*qK(O-jdk|!VX@FIIb=7XrcTsKl z&d*_6qK}<**=O-`d4C*P|L9jG8=Ny^@zI*Xm}-!73_@)`K{H|20TA6)+NiH$B)#0+(GsR@sM7b$VSO2Uko8CoU7hL zk`e@#(%OX%Gwg65kcCS6j~>7#2&T9n!x|Y=s_8?vD>oDx#U~qL=n1VtUj3cMTxIgp zg3**-zpfW#4!##zH0h~+n(_;VY2tV<8A2N9HgdWWaHYORE2tJ(-6C;s$0lOTbo(0x z|F;m=iKK7INCSMp11c#bxL02hlzgf%kDHuCgEq(1v@Tf?6-2nzW$}qoqJSWQ)Hf4g zL@JxUn=Z|cATV4(Bb3Dv%&!M9ertgMYNrU5TsL0PHza{VlOVQZQV~9)PlyfS#wo%r zUE;_-5L2UIQRT?Zi0>@?A*-Kwm4;ryaiT1wNV&t2`gu~xV;>{-=ZT;|M&@afisCm| zyXtR$K}Cp=JgH__zGZ5bPr`{>+X{5NwDncBhEY{w*U`60&;lx5K}D(Wf@0mPnei1$ zRO`-HQZwHC;YbnxE|D9}Owo`S$whzQ^ZP%e#puBfrLMXMEzK=e)1fxHTx!{f+-F|8%bauCpzyJK%{V+;_WK#j^MBYJ5;8xF)^I{ z#L940o9VYz^msVO4}ipvpj5T+g^!d`asxZNfWQW^j>gBJ2S?}{5{$+5X^ z!o{3zXiCjI9$!{OowXYSsnnvv$(l3&lDgSB27Oo}I&D6D3i&>{i#Kvn^gK$|?ytv} zazo}tfkM$ZV_vU==b~U~0}ibJAlAuRXJdg{Jjha1?~1;x1SVAE=Pw<|k5 zxp~MJ3Fmrrbud_n0g=l8_7H9(J?}h=ZGM?ef1IzE(<-4Cg=iSkC}Z4s; z;6z_JW%)6lFRSOD^}xMalK9+v<_=TrK}D)%Je7CGyyPnaqWYB{wK^$?ZRq&h394wZFgO^l*1##Yud`Qg^+ zqp;A@fcdQ#2*^qU1c_9up2HtP;gZu6*k-t5TCvwt_>&1cFj$Y#pOIJ@kH-+DZa9j? z;$rGy+k=8Kg!n$K+YNZ91bZ&eGrmHK@K=T3(+p#|XdY#iPI~xJpDm7nD!x(VoJ)u} zQQ}@@-$IL`*EKmmGnB`!M7$I_;{#A*)OHJase#OeXMErXTF6SiA+v-VNSAZ-d4|<;+^M)N7DDY7uLIJk>{|#*R z0q^z+d+K>zyCcMp=pnWFmGd2u1IrC1!x!zsV}6NLt6v?YPpMkz`16<5L&8b9S)%Pj zyF!`oe`P_s6WFDm(sGI2Lr;}!!kH^*2bkoiQ`Uj;-$iA8mm71TB6_l3wjlUE zn`4X$E6b?~Y23*5z7{PgUN+v4-jVx=mB++m&x^5DO7||6LC_rp^F5J5i+VBapzy8r z{mRZ4R{VsBktiJ<`*4*k<4}$(b1U;6j+LGEBweo|>#c@B9g_#sJVapt{5}(FR61c; zF$*Kjrsi4fUh)vLhy6RHszRF>3IlmQ(DI%DGRSj6K_lMwrP0k0+x^i_WTOcah*t7@(&ozjgj%)wy-2tB{h83EkhyH{ zrxoF$@hHX>*&oHf+qt&@y97S*vd>4cl4Z4P_VTwq#pEB}d)B5JilV>80T6bg27bMV zx@4XTh3ds^J{# z8g%&Q8o{dfmqV2q5BwHK-n33=cs>WR?Ykwfrg+~S0RXN79K5IhlrdTlZ5c02iCg;g z=f7WxdH4oft(^+cR44poz#nTYTdgjbE#F!$(F5CHOp1tLtQmz_z!UkG9i|7^YQggI7=1G(2Gft;Cx zDtda+D^r~{Uc{gpM@SBe4Rv$TH_4xr(%mhgPORg%&k?L;Z%Bwf9AztI#kpvNKX_3W zfs^~8R1dNH(e(p|UV*@halZJ$LW#}3B@L@0*j>DdRl$f1Nyd}?YM zLeR9-L>u6NR9I%%km4DgcoYB6^jg9_(FFR?qNUEp%L)p9? z+Qq1Zn+RqVt09UyR@pB|HH;-AQMhIGTsHFj85xBZ-2 zae|#Fe@}Z);;=$M!)8dMVFC9GDK(unmr`(&Sw9WY#+KK;+G7k zs~dxGR)2H`I2b9(i-%dzqws~zC&9gH#jzDt{CyQXd)@#|Rmcx2u@3UW+(cHKY1eVl zX@28e!0~eG4n{p>{wlR@Ss+1BmFKk`u?iEbyZi6r<&{Bv1p0Tvk)2~o($M=1_rO4;C+*tX@h>(UdE}OIEVRwVd zti7L+A@#jxcTc1J$p+v#yT4_QpUZOPy^(}h=~ukXqc(XJ}a?M`<4qK%b;@h%Q=0N?B*tD5N&U=29% zX4$~q<5CdE-@XB%RFqGw5g=OESP#CU2Z$FfCHx$Ij%S?uPSpozAGy;83*vlFdi-&|=pLy$Tpzc@s zm}i^WDMUQ+pGz%FxQItE2@_PM<*!o%>9j?cklmpv^o(>~{V^g-Tc%tb_;N7_o3Ft< zZI9BOjYp&wZA|#~2FfV8i>AG-*iz~&^LNP;x#ZM3{u}x~U#nwc#W5xcUoS<-n|QH9sVnNpUZ_#B zdYBTQo@?H)#QmuBFMqS3=T%l6~YbsN!TuPo?7YKEWHQGkM04!4adApyGahG z%8Q`|dzHL-_N@O@Rqq;0p;nf?MdK6+COuos zNf}H%<-78(G!aC33i;b&;YP{fdG(mJK#t8c=9Pi9vG&28!do;3fmPR-@H&8LR$4;& zkt+E-Nr)O^#(Cuk*#ZT{)9t)$v(>l-1y!CiuZb0v_?;-Ja5PvSuyjk+Bu1nw^Sg#~ zT{FzWd?r5Yj*g`r1m5nmq^0VOxMFI<7==psXR<_$QyfzWfHgXX2hiR`AlVK)B8(9b zWYUKl;`)}cS)c4lqq=qcUjVOm(m1ljunLssOQI-8E)^YmMf9Wc-o#5OH+yr(-grl~`mwadIc;ysW*8Im*Vk45^gjH19lo zm9tTr(=nr&s;#N8%0@*0^gYWl=!ZF(>O3ObGLUaI6W?`@d(`!-2FFevD3QJ!yLyRf zXP0)_nU`K-TPGSaS1f~0>|U-uFT^-3dUi2n1)l!;(Ms-*lO-GKhu!~YvHzEW$8Y@`vmyVzrgJr#Tl)cp}Ly@eStCf|c^8=Y>k8 zcKA|yxOMefnxwxZAUO8Cw%t}Kfl>UGpCjoc`OEj{>|3QDtuI4n1FY$iK8G!S5MhXX zX9&FDF9Z2elh>2X_NT)X-kjE}N|$WrEL;&|oh2(P=&{zve>8+?yS4c?81_OZbUQd5 z>t&$W!I<~i`>v0uyi&1Quj7G^z#U+ox9U;x?Ol7ZB@u@B@EbAHzCg20HA`hO zr-(7-5(krdJV#Ik7W2Dr8EybM_haH>nGnn?+>BeS`X-Q+Pywpjya0yCw^J2bHDPB4%MUCWJD%f}XGoy_C4 z_gN~``0Wynl!>KyOA$3rXei!XK|eXaV+)X0|M2yKcfLfDbbYFKqCL`!_&4NaQE>)a zQ8vDiQUBWMHO-CRv^Qc}3siKvd+O&@p-~EhV zJr12X;)i+La8C16JWV?Fi4P5S=n9^@uT|pD{PJa?WKBu?+C!!VZ>z+PD}_B!TdkW$ zyAArCgIzOh3xq~q?qB%}lE-(xxu@msDAMvCyKx*byPZ|^d}%0Orwq0shNF9?Q34%z zHAB{{y-!}ho7`0}^I%*r!P*`-?OGPC$tE0a8apcQxbC2MIRCVLoXDbbf8kDh!FNhm z8)PqjBu#7Y{Em@$zHl1TFDVLc z7rF2G4iaXUC!;6a%ZH^2D`22Ffen z>Vg#S>CbU12Z{gEL^X{|r+=M;P=api6vn)Zd`Zb#>5Qz|G^fzsWu_8>>a81i@Gf_P zX7rM%ZxxMprokqdtI1l_>h4QrZ7*y5X zF#M6Dt2%%Jo)=d+$;y6YBiZVEzc+miCghJhn+mRqeK{PAo77k$s3gA=q|itx&$FkN z33#bC!v94paghD@;$;Y^jZt~W*t6xX5#6s>BQW=k%BX!zqTE;BCpqCsP|udMYs0eV zd7?kNehCF{s^@&0JSAJ%uY(g&iBg$=wUiqN3qPjhFySv>K4|P7GHRQb>U}r(pK|4p zN71{*&7|)a8r~Pi8s;6PRisTo23Rr3;rM*2{cxNSb0zw0M5F2|P!<+kW6U?g7Z+Jt z7is6ZcTC54{1)P_9N`nz{`BQL05+5eR0{RZv3 z3!}zqg*|Y%MBMWoHe{ax+t|@8fd~R0D&}(0NPaVZIVN(AJ;KesjeRyS;Kn;TqtE3$ zXH%=UxMe8$c><&DknJZs*STWymWRS}m5TI!m0ddsPG#b)40!PzNB8pEWq18%Gvz&b zuZ09PP0x^Kh+AXADJxKzphCarF9;7f-$DjaTxtG21?4*BkQMIiktpXowkei8IPAP* z4G7U-=Ts>QW3Uh40uK-K>~)u{26W@18*NOhz{I12eD58~TSF8jy~cnN6%4&Turutv z>JU5by7Y)z+l<=4&+<<#S8m=5yn31dzeu^5m`wh6{p|SL(c^Y)A4a9QC%NT!xvo*( zWV+E5nf-fpKT{ws`n&n>8u4S>E#xXBRTHS`<$YK!>us*s)G+BaG5s-Rk;$28(V8*N zw1W;8GI{qRG)df1 zX-1U&mcvKQoA;*OQz-X68>krf``T61YSUNwWEe>w~ z97NP?_^o2-T==64iMZ7aW1L`59@B;= z==H|7nsRAl_J(xMOb)NVh2tw_X^Cf{yEnS?i~rtWzY@b9eaEYAn40 zR>1m*_0>)QL1W34h9Gwl?tfimhW2?wb;9q|X7LB#u_Ty6 zmYPezJ!egrV6i1BgJx)nNZh8VkJ#=4Uf=zCoJ~2P6BbV`)V=#bf{^yUfVhQv8GbnA zt)Hk|yByXoZ9}^M=~Q{=XOSYCrKh*GnJq(;p}X?duKY>&zrj%pOQPny!XR1G7S0Dd z$6r<0)p77PS<3V-<@HZLPrTf+SwDy6oSXe#un?Hn+GAH#iZ$GehV~@JvK~KvQ#6bc z@SnE0bYc6wzPowwyse#MAUKcoM`&KI2gKqlbAG!Ps2LEHG(ftExi0&?P){*3teeuN zCO>5BB+KYasO>UE<8_6o-yJq5?*Ui!Z#ROkKV83(cDHf*gT=$8i8UMkzJe#cTm9|B zo-toPoO*IvCOaHR-=Vts$>J{Qw;|QFChoIO;-<)h>srK*I=MOVk{3+N5B$ozeR(ci z>O8CbnSBgQRyFHB_bSuv-R&4C`+CjIK`)U`s4;xE7=N+*8RRh3k*mgI-3JUg&qxYR z61&7-C}N7e!IWlsYr>d8@21{Bh1a8Cw*~9U8M&jwIJ#oC zn%++;8^Kjb(}L~0@GD{>BQsas;u&v9?oYO_t=QV{NDcytkMxNtdoJJW);%l8el0PC zzCiETr+{F#Ck+;yn}NVG_y7OJ>$EAr%N8wy{6d_6&8JQN)KS%Hxy|>DDS&WoiRS4( z|ByvzO!xJZB#%6Y4zKr-)StD=uyehq9(4O9qC97L^BxOMiX*C&Ob)U9H&|6;P^L_7 z&rg^#q16qi_408(O@CT@+x2ropzyS9FE=>T_sf;6zoQOV=lpA%x2{HC)f&!;O!Vz7 zpU-dWWsW%7QOq7rw?k!)4*^@q{4t>QW_djKY&(G)-Z2|+5em_1D;I=9-35l6I<(#o-})jD zgt})-3n0vpVqusIR@fjYTP!2cYv$#32!nfM+lgnxd&b5eh2`ZpZ=Z4xLqDL9l?Q$Rs!z#K(@{2nze^f&c&Pe-_OvW+G0IgUg0%a^L1 zI}D!BIdV?MDftq;1r~zWuoC#T$z<1qB<||FXP-|O1I^zp1)U0BT>ML{*dpI}-oM54 zXE~qh_iapM>hTT@nga;DkPLep3E+*PB!Zprw z1|bzvTfbE*?8mER>5yf6-DcUJ1b#naI6t8KvJqdXvTGx6H1qt_{N&)3rmlZZILHccq?5Sl#qZpSHB8$6-qn%ATfxd!ape|_ zWsucj2EaS`x`l1gF6*eXdZ^Q8NSN0Fy_~h9xQ0?%!+OG1 z*7)_Fo-C|u-b|z5anEhvU&I!313RM{-A#Ef!s2iZfF+OYW~;R6#3S{osnxA3tRq~x zb+@+t>GhlDYKMU;;cGb|h}Ev9b<#Qs!xI8)v!I~)(-#(-_Nnxa^F~sx!*>^|o5a%_ zzqauw0;fw}pUe3{yp#rq{KqGn?^EF@l)1=yYM;shni;rHO}Kr zWqaD;MZ-+GLHN0yfyoQiGCQR)*S!M>Fi>g>+ilkJk}pnPm7@JSIA=agPthLpA~)#8 z>hBMQ(Ica^BZ55A)rY0tozYC*DpZ3^zDLhlO^O(1|ekQ_!%Ic&~^9CMtFIiDHh-sgK?-|M=s>;41w%U-~H_j^`vLvtd4@Cr&xN z%^*X#M(y#QrSR)>5GmSX*0`@C7JcSKQPh9peta!Bk>@V^WK^+y;ewTq6;q>bM<)j zY|Gw)+Nb-axqki)_JoEJ*&=1J-e8O{4HMg>)9(O=cU){f5h={W=U#l?sH)9W#G^v} z=}zMh^cS{Z5H*zD7GeO5d48}zT9Wxr+2Xi+yF{Px$a9aCmR zS)eIyk7$T$*t9=xdx`E+*6$PHHkzLoJC3z7@p>P+YcA?aUUhbx3dxSWW zR)YaVmdn@B7<6Bb%&qEoAF0STUpQ(X=Go)idiYU}3+91aNFT1qrL7DP=J@Rh>-u%S zu-kq={0dEeWtWUfEt04Q)_Yk_7~~4rJEc>v?MkkjO(*9fmp5xU^F<_43Wc@rk7@$v zj=fZ)gFlZ<&F@B7gLh>*0w9j^#aFo&2UnC&uO2UPsQJJahq^XjZ)|Ht4F;}*Ylrqp zI59^->Q>QmFe2vpTc<7>}|=Y^by{9tKF~f5SKg`I<0@b>DbJege_>; z&1?lC$-$uoykBj&`EH!qW@Qr*kZ{15c`_(Lp9CH(OBhFRNbZVzgZ= z+3{z5aOq8B@;$r`{C$RE+P=@s;9#OpQK=$jIdg~RRid_wzHE79U{CweDDOhGI8<>A zY6Hw$sXSjle=>n!J!*lZoQ3S0cK!mZOvykLWe1}Jk+Tt)^w*JXOp2AEUs1t%G+*5u z>sf;vThDkx^I0^Xdsrg;*Cc^#03yeDCv%Zl$J@sK_u`Qaa*~8U^Z?LvmO3+9*MFm@ zUTCj-GKq-zqyceQl?}AC17TnERNA>Ytn_t?cbvO-M31NYESm;KKogxK&@b^YZ$kYq zOcBSqxb08UcnwfIPv~bk!>Xy#zP$TpRII$zl{6BKUeoV8t05=sW>P=Qkr!5Ch9$&V z+@b`3I6Dtf3rI%xULaStZZ1{K&8q4&HBSOBsO)`^6Kx;pb9aeLoZgBx2b?Ws35dV$ z;)CT}I$GR&5*2C$&-t+F5{rDI8|0(Stl1~y-#N<2(Q#kwka!rwP0QiRCYG-RM2JCf zKg4y)u0u-f`@fC!X*5ScX-Q|@GAmfr{ydG-JXj1F{6qffY^i&-rX%RDCtS0{J-2Hf z-C_Qzh}PYm1q9R6{E?RbwOkaE5eLXD7BPPZ)xfp+hNCrWAi|hkM=<)yWiDg%eX8yH zbMDVD+HTQ*vRCB#yz~6Usr+A=`zzmy8VZw@w< z6cz_3;Q+(GrKbn?WxPJYr{Azc`wNVw=WcrpIP>l&_|>t-gG5tIK5Us;>c<2O7HD*U zm>2-9pl9=|%@Y{KKJ#2>wW})F&D@=A$(_gi#-URcSZ8Vq78H$bOrp^VA|bsj zO-Me+36W^X;NsxVf_ilekD?K-s(sUt)6KyQRsh#Nz3^&JQcdVbydve~mgSOEk+|5% z*894>{p{b!Px#^T=Rj%tu(Q|)WCKQ_ryeb^vrwgIKrt~g2t;FK_gU3SNF?WDp!HVT z3^o_+oqJ!fVvX$KPJggq8@MA@3Mb^)jI!{A*QOjrmisi)aS^#ge1aus@B@`&3>oUO zyI_B^aR0yH!Rk+^Z*vdcw(K(jQpBCvcpl?HD)hyi%Xu+5F_=hUGx7i3Ii2pO>Z}n~ z8OGsjX4ie+{(tck`LyLFi}I(Azvm0eq5_uoOno{Fg5 z(>ES@SB_|U0SuTVd{vuki1xHZG-{y4@`AF=jY~-FFK@KiaFi7CGqHIhX(AXOcGRsS zHh2(VBx(7*VR-Fe*QUAeJU=-Ui$<=q>w8Kwo=TB^tC0?iJ_NY7^dYToU{-f*e6#h7 zgbo<=c98IX{ao%ZE{>sVWRYTPc-cgFH?1q zMCD9_8B*iL{EmgL|8ZFD!5!#l^l%dk_lNBwOD*cuI&ErLIj4LDtjr|AcC%Y{)XSXV z8c+=&l;`NoMG#}tA==zb{dMq#>#zphnxi5EN&oYwoU|41v+~^~&eRBkLVY$+1biJS_GfAd>bC-bPTFZjJ2;& zlBqVq@qM}$P|p;5B5HqnYILnQbmvW4q79A5jqoC_I_hiTX@Z5@fE0)5(MH|h=|^VJ zjbHj^t466H@fEP{)ivZr0!l?$GXnStKFsDi)$2WM}qrLcBuV^pf`bNC><@9-&~kH3vIf8$*?rH*7AffU{Bh%2`@Cl zu1GRmB91Z%$}$Lw<9t9Y&bLF8(c?;bb(os&{4?ve%H074{-rYwZ|=Fm_+cJ^ z&~91L&0t8#n3$Po2RF8QZ>SKq8@jhfcVy)K)A8M)zj~h^M-LY4>22NW>n%Z*t%_8* zW4e-&6Pb0R`rE=wuR7{uJ&*3Kt{o+#Z?CzRPplxFe(HR>F^$W7UIbZbNqcK*jKx6y ziTQUfMPSxf?UtuQ_TiaAJ`-Obw-{Te{YA6^ODId0D5_eX7otT0_oLkBSZFcxc(#+; za$l{qww^zCb={u6P|$u#yeOsbMIn?+#<;uBE2gLRbaR!)^nU?kJJ8dKA_>#WMNVSG zhpNUeZXM}8HF{a%mH8+wKCBw#IyhAA=p3^?ro@Z`CVrD`xd11p!bq(O*(Y1j1g)nK zn3moGQE;ip6AJ0cCWACdaq!8f9@}yLa*N!q;}y9-{A#udkdNyH6!j39mUl zIpY4Wf5%vL9(*zj7R##}c#A^NR?v^Z_1hoTp{l>UhAm*@Vg6%p%y|gbU-gQFWU>%9 zu1}=JEw?}`Ip%p;8iAUh+&)k&SCKT+UR-8D)xa-3s@>GU@z8oo*YPTY@g^&H$@}{> zpU_wIHH+!a>Nbyxk>Ih?BEe_YSF&|aSL)^lV$ypUR;bN`*s0ZziI}6SPo}NsXC^(G zuMncG>yn}_othu%o&9%GtEy(oz?AKB-RCuZ6bLS;{r<5bEYi?I{!L468W-E)Z0=sa z!mW?%ZQqOJBuL41F`LWqkl@rpEVqe_)=SdZf-j4S~&yUCC58D~Ot9Bap zEML~J10GtWdfHSc!%DoCYJUU{#FX~vF8dD8^RAxe`n-+^=5#i~5idQx0j-+7C)P;q zz;Ss`2Cn?p`m#Xn-F#K-8TS3C_g8Bb2%V~vwOKFC;k388M63OKspHWM<_Wxi)S~)E z-$LNjUy;465RV8NMzUc|eV({dG3iMtetPG`BoS33C$#lb_ClxxRIq>Q~Up81mrA)$wcjA$;UIoWZx2<j4ys0RmPl>esY# z4(O114#bR9v-3Xnb%o|izEcKt6l$U&16h04ZK{O^D0BExZ=c(+%edcOxTlQm<-9j{ z$mYUT$Ft3kAcX{E>IzQ)$6l>Pk4M`Lqz=-;UqkW@YezM~uJB9EtCofy`Sd^3zccG> z*2GBgI-~Dm{awzia!52I|Hiw`kGbNX=|2!Rbq5`bm1?%9YX~r2^y>R4W+~$pibQK~ zyxVP#!q9efjkA?7%b_EnCt=J1Ou_^nn4RvTq(R=xw@a!_iv!`4&qYwEz^YWrRX1aX$V@r1Gp{as)#vz+F`VNJm5)xR@-i{g zOSl=J@Ak8&=9s|-8(yO~s2mSQ89Bpwj&OmGiw_yuzv=g8PQ|d)n!1H^5ox|YIscN9 zM{DM@Pu4j{>|tXgeIY!3l#b@Wg`2sZDE`RbvK-lVjqT(35l6RD+4aM67b6G8 zIwt1z5%uYl#(bfa*Ku6u4EV27NE&@1fXjhWf=gow`E&#U{Gp}(;&^%Btw#LI9FBt< z{M^1SVQyHl(jv}-r0T*x|K5jv6GLRRA7%_+9U3SdcXi3ZSw#~!ukGab@vlt0N#oAh z48M{`Xpj@>NE3~~T@CPPKV(2K3T(XV$U;4_Pz)>*J?I-NLtgvwLqb2JNE92G7p-B* zc+RV@fGB%573GWwhlVjUj0Y-?E9-@Zm9R+hxh*bNhG)L(0m5SekpbG1ipY~B>TE-e zNGW+{-e+YvUD@)c9}bZiOao~2EUhX1CA|6!?}h5)^r+HKL)<6QiqtsAZH7nFwuhJZ zQ=p)5IiLoaXO4KCPg>nmUjk+&EDAgizgzhP_56nj@S_9E$bGp(L}@fG3>k&nR^k+kUj5|G^acAESI2z<|YNz5e9RyOQb=RrV10j9Qg zJS>;|fayZO)U3X}D2i|%p>ek?X%hJrUzC6W#M38g2i;y6`RfpaFz8J1yZUQQ&q)0q zu$l$}AgSV|FhBAR~3N#mv=XnBE)<^ew{IXDYGgicx7qUX+i(3k9**w&Y;^{x)8DuyJXO2-C3NCNk4}Q)mT!sGM>esm z(D%>MFGn$oEgb}`j&bL%0=zaF!5}{1o2HhUpZWQ&+ci;0+wI^8vaj*ji!*oySb)e4 zu1R-G@@dMwQDy!T>dXstNGHE-AGcN{{1zOUmCcP_%V;6wm##$*Z8elrv{N^nvdaeo zTdmdYh#9a@UGW{FtYw}8Fb4A$WnX*zrJbDaI&eYFPC9j}>y>>2Se#`1%_ zLH#kSZSx!DNqa3*vvLhC7eX~gg1J7OIIpK2C!QfA<+qU=-mj^?)VGv4!U-=AR8 zAFy5Ht+r?q=G_8CIa-OE9)XJcos5t`^$-3@M29D^^FN2u+~xQWhM?go(&epWdCQ%G zsS?X^A~xpbVI#HC;(RENOY(M5Ng1xp_@?(RWSPZE)(vpJvgsSmcait0$Gc)QKu54; zZZ)q18)fB|XMN`(&jnpx8tHF01J6eV!Q1c!$XYc)3yhTw_(f7}M^@lvbC7MJXz7=3 z43o=whXV__n?SuX?~=SF8P7G{J0b1#QWM0(ds3|T`XF6?*TIjZ$sefn>8*r&TSCAI zl2b)Y$Pj1X(TN~Vfmlr-NLgh+v#G!Bl<3e_a?j5BNCGm=0_^X3i&2!Eg3t-+D<#U# zyMQ0ga61_EhsqxjKuOS$cd3O&V$_Gnk{n`Xl9qL_Q3(`RP_%lfub@@~%euVBGzJGY&G5*`*Mn;AKXA~y-$TTeXQ0o4P$OF3s10HG1xCVP)7oztBtd)?X;t)?oe%3rnuLA zZT$X^Mb8NGhC0KJdhmLOG3ID0<)+(@z1^YPMlL! z5fWUZb=-%qyt#TXc5DaP^0uyPx)x(gsqXsa*RixGD$_p7>j@5z-P2Y$kt(kb#t&D5 zW=1DwGV6#|a}zPIdqS>##>{8wV@vSXvyF#f&Q(q?qX~KaM7R80Z*%M(GtZacjU1!k z_>U$>N7J;@!YEAn9{FXEeAHh)QE2Ar*e31N>(2`~TS(c$r{wvDJuonCICWsPk-8*o zy?VBYtC3P9Y8*5{h3mcX?yjPGBl11-8=s>d9X%<2Tm9SlAXlQqYWzUmtGr|IopAl( z%r`vv!>OR&`h``t=-h5|Wq1-cFO zopv=5)~p7Ol_%l!fjQW)oYpH(QuY#dLq?i99(Nsn?80f-L;Q$G z^C8hm`|lgJ_Nz~&wBd8>4^QE2Fl5iRORxUK_k|zcFn{A6|KSVjbC{q}qIs_d3Ti)? zzJ>WGvXlt@W7)W3-|;Bn^oNG*?uq35XGovU@!@Ik&-|^xd_RY~jp=QEmFfqh*>qKt zl4%`6&N%oRxYrP+kJe|t_F=yD-MNgH+Y>#8ad!t`m_W+yYI#3F|IVo6sEwL$Jp(Z@ zC9>%U)E*BxkuSl9mO6nE)t^EF+rx*MoP}DS-{K3jygpMh(?}ePqnH?5%9rsf2VRnN zihq_TIh;YL52lDjTbKH`&+EiK-JN&rnCon-e-+a1ytJ9a<+A(g=R}!nzcTnhL8h0Z zNVGT*f$MA*Irj5YN*8Dhkf(e*>LlRR>!+tYnlFMUSX_1^m_J4=uB#d!Wh~pbcY5k( zQ&~4lu+;|Te`eLU8pm_~X}IQ$6VYAMF%-#wm72L`$SQKskMSWcnS_Hx|Tp6hZe3he1)n+~Atd$py| z=<)zg#8VF~pYy<`#?2Fb1j>0fBZ8>Pz4}-=| z?#$_vF-3`KsrkUz9tsO>>W%^Bk#^#QbhS|d_SM=)WeaKE>YrNq1Tb16fG@V(?I zEA;QWlQ{Jvari-y{r9dcGB%1B;*5cRM(?=S9lGxSdR4g(5N8aRyHUt4KBO?4f3cAy za;Vr&C(Wvz(UQ5T#4QFKNeoqH(TF>_{Hon;d+ceSjZCuqmGoe%Ck><$oBn|l(}1l70qm~@isPV- zt9xzRb58z1HsJYJ=n3%M84ye#!~+qJR1^=34xNQ8Pe8azxc{l$8qj^LQptQNuyyhy z1m2FiANwlUsbBl_7!UW{ja{x9q4I-AudoRML~iet1EEB~x!9#&yD@TK1C&^PG;X{L z3}sN{A+zGKd9(L|tm4Rrl)k~|>p;Oibx1>@_i6`J6^wjoUvu}MB6rk&obSx%xYF&O z)myo(zPN-Bdv;gn56}e)njZNe=M8d5c&wOZ#wH=y1G4^8+Da!Rr7yL+%iU`7BB{i& zV{?MpV1swXGC@9!2@%O`eob%#LkE)LG_?^v&a~avhE$5vwN=BKa*~oBib*KgRNGKX zsrChDWLXIyc{_Jy*EZx$ZbV}AUR%~XzR0-H=4%2&lsd!Sf(FUP`IQ-W9A%Fvhy*7b z?83yA(R5QK60-9Rvic&o>*M+}FQE3iE>+`D_L6IO!lTw93|*IVMhizrTmezMt^~y$ z^J7-A)=B zTlWs_X2q~x11Q3{F9O2q_{_G~RNG8WTW8fPCt@yyXv-m;P46n&=Ca^qKV)|ww&ChjGgm-w$MA9&`tcKjIrm<& z+^vIq8zbApHod}dQhyzDVQ+b=T&gagzlPd;krNn%_#FEJh?wh)4z@2m>vQVz6(6uM zX-{6>w2k&#OH=4z;JJNWCyo|)Vl~rp|5Cdn9O6Tjo#$S%-i`j-lE%M4)CxgLe-&>x zH{JDWj)E{rQc4TVd8$9|CsE^n3Hflrph~?OCOmW<=&?AV=PP>jKmKt-+NIas5?3vc zbW-S;J_;@NHVl5=jYZ)F&&yI;Y_W-p2ZsZ2o`@uci_E3VSzMVhw9wFlvEAHBR_4kJ zyU3L^JGve^fy_%pfP0fO$pfHZ&&5Tt=dIexOPXslTONNA-~IscLy~x9f$|me&b03K*bM-AZ-H8ZyG=O{u$yw z*m$R0Nny`fofnwVpiF zl0PdnyQ=+Vn6ejSxlYdsx)z}J8SNSeV9c%^diBlTb3eYl6cSW!uHIQN?d>D9%<`3H zThlZv1@XI3YT3OrCl3l#qqlgIC2!GQ8~->x+V1qI^v3b)BDm)*C))6*=wB8^rR+)JV&WAe8tw^~zXC-;iP?{G zneS~1MloEP8P!nG(zm9YZ!*dT_HB}!$o_=|36OsA?S6c;1#J`QF+QLTDb>AudcLus z!P$YUTb>*}1^ZELFM&MaV^Gw`RvKbmY>*kv;C;A zp{I|Tx~5Rwf!Wx(i%OFdELUJn4#FgQG@JDuGu_kbMLq!W06+ceUHyy#GT7iUDnOjU zJEdy7AhvCJCO$T^Zi#;J5!N`H*y_hP&l$Q(s_|sG(QW{{|33ou04a=O7QAHEW#XVi zjjR2?a-*{@@ADR9ptEfHIh+@4t+pLkFI}T6a9yUPgWn-Vp) zKis<^N7r!aR1by=zOYb$kT_7sSST!s;&LXCJwzM9#8ZDh#_kMyHy{B*ckw-ver0D^ z6QZ^lLCVkMUF30XViF4HYA8V6gd$#W1=F7HGrWR(D@(op_uBWUVDG9P*3p3u2!KNg zY8UlBmCZHKAk-yQgJv10rFHc(`jN=TN&=YMlvgwU?l*!}E_8Qc4J^$N?eM>Xpw1Xy`uoUPk|_PoRv$yfhO?xFBNfX&ZT2wyZdmzm+FM*1kxQw zIgR|o>ardYq=y}Tth(1WCp78+;^^VKOGy+agkC1dch2Tc#k_3qp@rG6<`>aRTKb)# zO}ac`y~8n`XWz`YfDfgJo0s9Yv9^v(=gzw(>1HFEe}R~HeRdDnq<%IJEJ>Qwc|*AT zoJtqy7gopr)j=2iPmWpc%0i>=SB6q`O%|}rq9~IaKn1q*k=s3#8TBTDw`?}-@Qprn zj?mrL>Hbjvl5e*$_f>bp1(sPtsb%nkX?NJf3UPu|(PNxoS{^Rn!96%+K4w#Q@V>?I zCKfHgbq@ew1--dt%oiz@X>hu8tG$$kpRU*m>+}ZbGKmtiJ-)>Z$0u{u_xann{ou|e ze~Ba!?MA*LiPo}so~DR2 zZh~iQp>cqBTI*pFi=!La&t!05?^2hp!mG-l8PDgov1s{oBWk{4`*cWj-M`AJH+)iL zI9E{+9DZce_W6xKuNJ%Bd$Pn+{2x_!%1n1!xm48?;Y9~5b;y3;Q(y3yUUlkmH+Q{v z9Qi~iDiGO?%HD>?)$9ygmkLfqfBnEx^bo{D+IqH}1~}E7|Ko-qIe2JV+Qz2DC|n14 z!>-48m*lm338ILNsVP}GJC(}o(q(%$1svk(mS~hGA%6Wki&Pn#II&*Cy)bRwzHy-u z`Dg@6?pj!;N$k>>{4}mXoH^$gss5S5ae$aeoFOaE7U9PFjUN{sZR9EStS@rsCFy(r zHN4q`YjMG*RwMOsph)guw<-J}aC_`ag?Jfj=5}d=q2pCOqH3eV$8feI{*zXDpoD58 zD$Ia1$P5PZ9-n(fH)>j)(UyB4|FH#&|K-Wz>Ch~pGGk}jkEE+vQ z{XG%6nnaGCCJM`>peLsy^8_D=b>lh&8fMV$xJ^%S*CQO))1kwoy!s89+-l$zP*Tg{ z;Yj^c<~IoSyQSRcH$`&K{adun+88N>uCZ-qf<^n5f1b@h7&O8D+gw$C%1RfF}VzaF9%a-rX+La%CL4Cvkl-17CI< z#7zaH)+P>EV z0v7AY$g2B3EB|0pPxaAo&1%(zvAY`XqS6(L2}t~!zOnj=)V31-;eugk_aB@!BQg4U zXO_Nwz_?$UJdufsO*5&&bB$f+@(GjTfp~Tz><0=ZDiD;oQJObT`te8`YnQ{W8F)CX zsMk{@50Mi;w>aT}>lAd3`NS^H_i~Z0$OSZkE71lPK|T%t>if?@<9gY3*B@{E;*@hr z28xb%3?99;wS>j>oKNyR7!P`2G8vGXdY=CcF5b2Dg4+S>nJeUjD!^+bEUzduR3snS zc6{!oO1qbc+ezR9N`K;4>cFdnR)1s7{fIC5tQqt7-yU>l`|K8Yny%LzOib#JZ;&<9 zP%qOqIs%kJeBwz;SK@%OQ)YOV$%#%l>Eo~vW#j9Y**_KgU5g3rBg3O;Hjso)HJy;reEO+vZiF|FcuPbsin3i z_MfM}eBkAiXU8)7(w6X@=7g&(2>QK*N#kx{!&YPSj>@aHK2A%C%(sQFy02actv7}; z$;8iDPI=eeRK1d3Bnc@H%aq`L{g^*tM}q7eOd)i!v*7R6r*%1X)YRHS_NO2{yG;Qc zXLeGvg%j3O=6*Ph~LY$IHT_|)TlMULTJ&~C`}%`6 z1-ts)l4!7paJ2GOfQtX1?J$9*Ww}DAZc@h=q6YEo`hF{TH8JMYmZaKgir0+C)DZ;_ zuN^jtwu$Ml``3l?z@drCcJUG!;NKhXiq^k!v+~@#3X~vz3;hIQ+bS@rB-`la<+Jeh z&nmmn5YVTaTVO?eqV%#p@H#Xu1?B;h(ZYbe7Yw_l}BMf+%zsu=p9}+t*Bolly%&03|fG364p=ftG#nZmD zzo#VX7U5^fF70le(!|W9MwDw3X8ue{kVuzSgPcs12sTD)w8>9M%Kxhk&qVzZxBH=Pp0LzTgd>g`@%9R8X2wPVBIE~3Ng`F#R(ZGXAVJl+~)19 z6Op@2!3^R6Ms3y;!aZ!{3{pf~QTkD%pu!uC-sjQf;gQ{maVL-MH>~xC&Ue>bOv%d^ z2nGOco5rI|0O@*__zFfItcT)!r*W8cC%-?cU98;y-7%l>p$=A z9C_b_x9}cJXHM!n6P9H}4VvTwt#Q!7mQD&%-Q+mOV1B;TgqovH!S>G(d!JhFe-^>| zZSvH~KK_n`zVcd6@;e9;^(Wol#mOLXo+x`mJ^>$S6j33Yd{ zv;+*6?tO3f-cPP}ZVplbv1?7+`kqI`wSPy)Rm84iw>9sc4l?tjN0s$qP&tziOr6AY z3I{uGTDFnyH?7L$a3QAL%O(%w`54_%#%8gfVUc)GPwyauP7NRrSZs z&|X^YJ?;ezTM|g3&EeN-S29 zSk_fOe96!^q-fgmGL&p)R5-p+1JZb4$Fh0Qg=EiNk>t?1(x<@47dPykzBiT&I_Jp9 z=kpSamco00!Gz)XPVN$Y`?GEi5RlMT)wg#Hi0(F{D%Hzb7Mh^EwTJ|rOG6MQJ&I}dZ zhl50^`x=U^o?XdJw{X~;BrwlhCkrZOk>!1_Ij07qWlksuwW6}x0|jyc?qL1=<=%>m$F=A*uPEc1tnw7 zHHfWO0@|krQ3s@!#MVcwa8g*J5%~?7Z8J^qMZ)FF72?&`Ux^XFjLFcE%v-sNlb3># z-El3Je{vfXy^dOkM>P{W0ygG$-@JIx>oU_|>cSiMgT+9t_by@5w_)dle*5JY5y~cX zB{_f+c(nlawtMqRjfuxqKZCVIdDs1evyl(h8u)B>YH)g!H2VM$_ks-$5ZVt0CX0=F zRbI4IRZ|jot_LX{mT2ErXm{sz=off-nL*RFKb{@&CEim3z-y^X(WOvrrR$TAI{*5PYUA9^8HW4|z-Oi(Q#1ZmPNk~~c|BNJ z2i^I;{)g_u9eJ!$Vr7qobAfWz6PX+LoidaS%>=dETZ3XWcz+}qhiRbb#kfeQP1M3 z=VHc8*eRI+gFVDpX8Y}8<5;f)BqrIVuM^I*uUqf$$;C)+1sl)bE{-HVf1~6ezWwA( zo{n$;nRNyc!KkVgLMBzQTP<#f@Z3Yky7hMS2Y9Q3xJ+x<8Hu?&P1D7$=fcjR!}*RM zE?rNDMfM`)IBv~z*Iz>|n4A)xJYKcgxOqv2GvMZMjyFk~zj0-MYqmlTqK>_P!G1sa z^~z=Vt+HDxbZBrnwDvRf+KE%QQX%n8FqFxa=m_79~@W1YX_tv{L>kUU1Rkqr!4wCevs`}n6 z>}R~%Fz8JBqT)E3%Me>pyB;W^1>ll;DEZsF0 zw9gZG+^j5lRBLSbHIWbscm`tp;G)ql9PQaIz1aU0b_8Oko_~4oxUgOz)$h1Kx=DMQ zk*8Jutu%8Uu%kz2e;U8qCHs{o-~*Q0-@6j5*XZ~}B7wV2L*5eJFT-}mEZRuS0;U93 zDguXd9e-xLKuJk#=M}X2$tLuMDHP!gB|UEGRnu9_te6(-QkEfWi|tp6=kRgbZ7_xM zB)W3^74bY&P*Gbkm5ZF|MjJt1zGpha#y=p{aju_TtMGUfp2i zr7%hIw@~CitxgX`3KhAxBB%IQsnnd|<-$G4nzvl;c8OX-pAAz-L*r#jCp{YD*#p*_ zdXuR4N0^#%eRchCoCR`$J#VNTI_!1Lh3i-4Rv**fZp4!cqaXWN4}2-^_8T!CmG74@mI#7XSBS+(hv8 zV?DcJ0_|t)Rn{;C`MIL$YXHY@>x9y3cf(*Z;8x|Zi)LAV#1YVvERlyuOhjwh`JUtA zhe-BDEA)K&4GP^f`@+q}Pvqa|NUr42nK_HFDt+UOmGur#On|Cv3siq>pgzg93FizL z&mb5AA`z{_@o^oB0CDguvZu#`^Zo}(8hI_@LNiVB=5&1F`mHMNFC0c25kvz2Vln#b zt2BlnzP41gM(={_W|stzARYh$V^6ww^115wk9a|Dx)gcwe(0Fbnf4x7!%mg}@i-GH zzer$t=xqGK|H6`YdFa{)$z;dO?2Dp~yDgstjHkDGkM5QL5qS}R|9m-9C>kBOEt9c5 zq3ZI11=YUjjdVGqG+|VJWMW+*KCBL5QfX5`ZAo#r-yQqAuaQ(okq~ITWRi7U znd@|^W=2qp%X_6v;mWkCz|jMTi(ZS~%>-9p$=z0yJPD61N4thfLDah4H9PiDJ!BJZ(uWudpV;(JnX=}5EFBqm`2Q-2{}kEND8r?+@zRp1jVN`a zRTnhLMa6xAj;COw%Fcc~X8Qi(uz928#vJ<%%%1y0Lqu4%##RYJ|CEpI1^j0Cp7eee^bb^4G@7e4|`|5uZ$`sCVLg zCzGT|gjlp8t_X}ZBV^D+IC@c|^M>0}mrackkHx~?AU@G`JO2sBn0CWiYksI5R%LeE zI~{1}(-An{v#hiHQj1q%aawm**c)nu98oK}lni>+)_(?6n>{{wue zfb!#1`X)9++?RQ|w7u%x6EEf{!l4v%BS-aP7WiJ+ls|_il@RjF?p9VxiG6oQ?Unm^ zX2lHW0-b@`YRA&^tBEzQVbyNKpp@W;_p&2G4EJsBB0h?G*wOw(bsxJTZx%P{!X3Lm zDES>tY`rh?+5YY_0p#UjDw+NXetr!lEfz8-zIPv#q`P`>9`Q#qF@jjVUZXjCn1U%^ zO!Tij1gme!mesTVhN9^c1&c`*v>p}!E*#00%bGz0CJ{I&ZEU{wi($t%6 zo=Czn%!*wtothj%j4i=F&5O7)$^(_M>=j`XBIv?>u}>Wgf3svm-8&`ABsLZ|a}t6n zvVwuP7??CT!>wBf_4#@FE&u8#i2Vtn6x%^`u&|Ridi-;*tU^uH|5V6FPIuJRCD|i`l``)F8u0{E-7Wm*z^&A+$*>aBdWI7eU?=T`FVku^i#3M;}9e${^ z`|mfusk@R4eX=#w5ZY=UTks3(;0!L)wqH9==*_-Gos3-l8dId6dca# zqgRzfTp1Ak`yTK)Y?hoa{bV#^-_4u}ZGTRnb3;@2vnh}RjY`{qoUdzPysY2Ql7Qsb z!itjcZQwa^Uf%t#i?~f6RF6a`eGI49+_c^CGJ`m1H{F8-$O8g@6?WmoIaJ}*7{KGQ+CatU_BAkusYtDd#C&EoeMnT=4GMiXT^{i60cR0sD92# zzF^`*2%1puM7Q19Q2}olc>!!kJK@h1#M+axi)7$0&0 zJ_?I|{k+{g_h+)g1rsNbu%VDTmu-b>EEkgrZ-jFNDt$g)g4%iY5wR}J;Ep~ zc7H-igvG6l(j4-yhT8m#iEW~t!G_4*&UeagVDoMCbz$lHlLZh!LmtSyeeUIAv~j>~ zBPt&U@LHe)gK%ENmlbxxXRF40UekUP?%8!uf6*47pImv+yZ*dmMZiLruI0sJ#?SRO zse?OCDrcu+=NdPl35jLr`emS$|jLLQ4bYViJ@GdPME^Zq}Bk z3@5TbSS5-b4t*L4a1J{on3tTGj$(iQGVM?G_*lIAD^>#~AmrRY(%A?vy4M`W2st zPI!GQ7RMN&Y|-$ z7jDFq!giR>oNFN5ei*rIxXCqR(EqV#)aJ>I-!&netBs)>(d^RSWmZi$t>4V$>s71p z>S%Az=ZeIYF!}9`E{l8ZcVqm&9Z4C*w$-{5UmB&7F_Q5~R<0Jg&ky&-qw6(W` zrv!c2kHO=KflhLB^52-B-?&XKz>n(MTR7>n^U*mIf zYd<(?N}I@I2`cHB-egG3rmhDJ&vUzulAKpJOqC0r2%8}j+^EhWrM(7lz*ZQi*2#s4 zHQImdtk@6QJ7qQG<*v<%kln$;r)MV9k=p7b_@|TK562&Q2RZ0kE+k_q*4qBJdo`I+ zG#`ZqNXRzs zU+bU#WfS-+sTX=cg#Pdpn~S?UJ;^^8$O#^wGIy;%v|+QgUdr5KvcUnvZ>!_UZrwLl zWnbJMnP_J|$K^VDrS#;P2_1Sr#d{w1%E~~W#HLH{X6zRY`5@w@G;naZAuX0(0lbKM8b-EqkrRS7L;}7^z`f?wevel2zQ8J;(?!3x5jJkDKzj}96 zqBn28;NHd^To!j-`OUtx_{IKHsn*aA>t`-hc2C+}H7xydOBK) z_}4ugvDvHap#h}%^onJJn5bMtk9JF<@dz@*?|3|CriTF!4=~{yYho!yIl8n zVd1~7=gLO0MO^2bf4CuMd!%dG&fsX=KSFmcsnoC)pqi(ZOQrohH}aOFJXe-we%*m5 zxRX}CAyG3)+B;^SixG4z_}t&}&1{CH|19@Yi~SDDW2IqQQ<1*FZcPu{7p)Qdrl4mg z6$#>9!NFaHNIxvx;--fsZ|R{l+)e!~-W z&4Ca@3#1cfR%;n&X`^Na-p?E}S=Z)%ffoMD398$Afv08`*cg6OYMDoBPM2LHg~=)12RbG--dhR=)Ix6O7x;-Pg0CZlR`gA z2S>)xv0|gbB%dCB#D!C_8v9ZIL&F$OcXOlENJb}8WS!G$*qp+1KoN#2vpRq@Z}#c$ z6F6&AIEtaHO}4{ce|$w}C@$_qVnv2$;Io*t*I~S*w;-pxmw8vSAnT1*Vs??H*_vGb zn@7FT>^Y$h*OZy=ug*~OLG47(<+)(jgk#bZ`d|x=ongYF_}yEUPLp3|0bCnoW(qSf zhG#pPl{(t)9~ia*oPe`B(%)4Z1}UxmOmw(Q{tD2Y28dGGmjU*LBW1f#U<#ayH?8}7 zV6b38@en3m3rB-0w==4WM3?gQJY27dtcM)pNbf(Z;-6*F2>SeTqk}3`=4maZ`qEtY zKf{2eaG5BY{4o&)E&~U_3Mb)7_>hr6_Am1vZM7V_=I_UUCOff!S6sMy{4QD%T~kv6 zO04dOGxbzKW!a`Vh&sgQ8ewWf$lGdb^)-9H)6EvMtC-q9GWzmH=>iIb{$d(=T<;mR zfLDBWaQIP8vbB2C=M2~yyelcj@NZS;$#3tu-EAd9udM$*8@qD2PNnSzm=F8xt#UA)tm zMI0>*_`y}To^)bzLXLP411+WK;|({JKKV$;A9=+)-|sPeh$L2ToP|?X^G4r7ae31u z++Uz#c%WBtzag(OJ5SW{Aa!^v+3>$*_A-3O*$bDh5}tNsVt%@As+*tlS~c+9?wDn) zxjLANK{MuuofzKCwkv8F5wQwgC#6(ga1qD7guE_Hu7G|nCwnZO=~K~l^Zb_RLKd_PniLVnW;C3djFVEAkdENS z#`T)ND|N~;JLxqBDYMw)t&9+PZa)}DsBnkcZ16n$qR`5{bv;A~y}&V!D2<{hsNtej z%QDuzk}i3Rqo7ZA6t0WP%J3+aSh_po4JMvdW}f{&VDJMy5VTMx?^b))jWHVv3=vtjY;#m>6+r-c|;4mSqo1Bkt1ttTt256VpYxC=u zi)2(z)#0{kDdp$6LSbFhi5Kv&eamw|5arBOyJ3_aijCQBS#1sZK3bHNEGV>de4t>K zg_{JPjf52lIX-=EeW)g* z2BBO!XWbo-jy9{3`JfhmXG*%hFm~|kWgZS3q|IQlvsAwyzz;vZt+mBJ(2)K8E6k7V zU2_s{8n4#p`ywE@)`F6hc+pt-G1=8VV|1}<#Ev3Zq6tei;H?^V%Gg;PAbian zzSgd9Oa2=pL;fP8LhK(p>yPm!fAdxeo}FC?9M|YcWC1I;QFA?r>Y@aqQ3`Cp&9`aX z^zXeWou)#s8>Z)ONeTSDAj7VrmIo7=sh3Y+QYlhPZ;htIZ}NQ4Fb~5T8wz2Tij64f z`-)Z?2u4?qHv`-=d$@(9%Im|9m@nYBHjd(p)CthK1XpB(sV_~0<>|lo8t5VCtpP%? znPGR+iEjAXjeofQ72OxfOcCeQsy7${@R+0NnAhj;IKkFHw)J0~M~#rr{wTVU+oWEs zakW10{2;zV{%(X&Q6}wdY1{G#ex?uddx<&P@om$l=Zs9C6G(U-(2BzU$sRPf^uzXM zXNm*(RdC4ju}167^-}0!Gjcpl^880-aqLxLpTJTUPJO3Eh-aT(*pQx=}eJ3 zWY+v5b>vr4g$mK7eiIOWz#VbWo_w*MEco+lVGKw367BUKA|7&yk9p56BX~Bjcs9^J zbg?}os75hkK!X2RF8Dp8>Pe&mD@TG{!bef7FAIf@IGnDo`D zZp}QZH6AwNKQ9@5b>L~6`&vom{pGzanM(SI9p|$itc9z&ZusB;>BN7qnA_2cut6%( zw_UxzT{?%~`JLcj5KKsLE^Ar^A;;?TiZf#@vnl`by>i$RGt(Fb5t34~&+TDhb=A3I zwTFhW`|1@bYN4)7pmHc!p`@NKdbjMaYjm=sI=+2z=yHxS zxN-A;nr^u_Y-^Jhz0YbcL>`VelcCIiHD5fGTKqw7syuCaMk`p#pkan27b9nqlA$Vz z>TNZAX9@fqG5D6QxtL`&0979;F)q zIFsjU92`+wpJ(?Ub%$UIYPy z*kRj>4C*JvVU;Qo$3a)uKHJRa<}}!eD-VUX1fKt~m^yd%vnDbgEY#dM`!Q5sj{_$V zvaW(0CvoZkR`tZG!c;+_aHwGAeMsVa4o6h@Ii3=mmo$6jE@RJoqb;&%rb5jtUJ+ADktCx3#c zf?vgaL#p_F$2ThCONxfH7db(Gi*m>&YZ8@`T%%0Y$Qx6m2ro#Dw}Loo+Bw0xH@M-) zp2(0Bku!L$)fcrXzH4!QG-*wi4I@h**f)Q32EKxmfw1tqYTYJ`M!Z6&J#6>elJ>_) z{l8a#9{+KcPZ;N@n2T(~hOj#6dmg!@#(gqcy^5haYXi z_2!+m_1ry!<}aQ0e38YnyYv)&t9|J5Y)GhOnax|7_*drquj@@GZ|}V&qst?s%D#8; z_$G?-XZ6|f`R*PCKYsGN92dZgJD9;9fs+*VhZDh^HbJNEN@zw?_Ybqk1oSOzcO z2Ok1-XR2S?h9Kb5;-CcYrR5&Chg}4Zu2^J7ZeX`F+w$D_va0rUjOF7U%jo%Ez~-nSOl zFze(9DDdl!96g>KLLLPh>4FJm@Uj=^o3;G8eltAp;hQfG8b@kxdE*Tfz%yeV? zP|6T55mh0M>99;{LgkqI@R?BBGbA;bExMTwe zW@P;Q?cn+6(}{EMT+eFqnwsDJ?o`!Jk^uDzub=Ny$sbQ0wDdI;tV7tr=GwTfx)liaWU&TQ3Wg~#mhwIDKm2)eBwp-U_uEgG zHDK|1v(#2eW%y4e2ko+8H4N{NMeS^<8S;{}W9~0_Ts1CLKj(LG+J#X6`MBqD!i8}@ z)i%G$>ax7rqCj}gY8xGt@b&PWR)8$&H`qQe3hdTv; zEbpu5cT5)EZTEI_qsoh(sRyD*D(gH$p-s^uL64O|*3`u$oJUqcg+C{5j#4;Fbr++^ zS0`BxiyQsyq#a8t16SM1LLZz<8t;NwaZFN6ErF9Yq!@8C`x20o1 zn{9b?4OuhB;IPc6UcKSRc<$Q2SPOFd2tiL>4Z3tX^W%ks z8nhoG5Dt5v4mJw1Ck^jN$)SRk{sQtP)SwP)>th zrO-O>7E0x%%y+sH;fenHwAa?ZB=mF@+xoCX4#lm$n9xz#^-Un_S&HZ7_`$QSXPhAv z)eq4^4)(Zh?v-cf7hja{my%z*YO2w)6mKB-?P343g#Hm0Vs9>B`sNk)X6{aZjqTait#8F`r? zpM5fXVi7^KN(gLd+-%r9c&KITnP5vGO!Wf#ZmiEqj~9SA4?E4aZ7mqvTj}+wsKjlI zqf3_<@~G~L=-$SRi+}&GOKM}=a6nv6>&yf>dqgKbOq#9S?hx_fzn&Mob@TPN!Yf5> zu}ghqYxY5&B%{=vO9g7q_D^^RcCH;L{s5vy#T!Wnl8a^mHPt<;ZuIP%EgIII7SEWh z(B9Inj82VzpxdrJ-ds+_S~tJr7tvNdk{2;huH&A<$mB944&Y;`yy;(v2zjFPAtc%G zx_?5K$C^?QOQGd$1^OG4hxevQ4;TJ0YlYUow3eahXb$@ao{PtxrL5f2Whh)2 z%6Z%?;6<(FYct4M2c*TJC}&hVOrwgrXX<#7k20OTLx@E!V+O{|XlY4d+()wn(=Y~! zgL%`)CXea)nPtza>V|onZyCRkexPR4$M}fYM`~94!hNz~Vl$HcT#*N0#mx4H9hzpHWFU1ectTQay{3ONh zms;ez#%Jv3_r#s)1vW&7QxuNplp|U7BB^zYay=Y9 z6OX!1h|(00pt(lsIrqgX{!TrmTYI9MCyJcZ6KaoZan@#R(@V)mzD5IJ6iS;)RAdX* zRA%UmSYqB)k!&TTY|x6D8A#R8Y7`THDjw(jv+vLd%nm){}+i zrqkVKB{&C|xU_kS+B^NmIF4SCL^(7ix;wUX#kNpJ1t*e|myd>`W_lNwZgYHBc=x-I zUV@_O%cGv(eQF;cup}%u5ZcNUzu~HN0)Se>KmxDG{|8QHWb=P~d2&FxPg=egl)bEhoYus6pLKbw zxzxKG_$K|K-8u{3vppZT6?kB*a31ug4zn*wYHQ?(!$r97>&hP`<4*_F#-N7Hdr^VW zf~WR}X8WFkOuBc>H`hmB*n@pf53LE%#{LkiL96WKIjiGQaoiI^dC#K9$z2NHp)X0I z^4L1OH}wGP@%l3LBpY1UHwxLIP$P3mG~VbdXJ+$Mctskm(^H-f59%k>iy3xoDGO6ABXa zd3p4+)dfOM8$ytw;e$HT+oD2U&@gNR@XXzvo?N(f@U`i48a%NaJVhu5p6YKy!E96> zlwS?#eR%W`)(5R76T;=|0~>vt&85YY^B7twBr_$BVxjuuIbfQ?K^rLzdA9oOG_8GH z=JHUc5`0<%32PdEhg>*+ZA*OpY?gTkwmw>3ztGf#A5=A`K$Iu1GQxkHG*TF#M^zL~ z%$%Hh)nG~c^8!k03A;(T@c8qU^4(9)8BL$2-RT6$8%we$heLOi#+7S-`5e9;wd&R5 zoyT0FXOmWs_|MGV>=i;*T6Qx_ooD~WSuH&{{A^jl5i;sr=>7WQ6-y6R)AeE#bB_)z zfzj2sCg&+-0K#scQ6Sb^r|)h1j$oC`WHWV`M{zwwVwUxQ;#Ah@P6Z#TRgCr4Pv<_( zO%&cuU!(Rnm$HhI4LaNi{CYeW>%{K3?QTA_$y_JqMPGX13Q2lwXzrFN*;%4n5o_h4 za=M7Jx!I00Fz8|!A5Yfa88JsOd%xZ=dAU{l3;K60{T~P_-}~Ri+j94S@GWPqVVu%# zPvfEeoF~V{j+jGGcyQOsk{hjj>CN&f-8ti9=mmfLomJYEV)MZ94lp3cvBMf>uT~dd z9US<3jxE^3>!zs9re|}VpwPTS;okcB60B$Z#u>~zVaNBR@pS%#{JJ`H=sj)xS<89c!I5^SC3$`|NF>k)y6gmi7gd9kcR@~lj6e|Rt{)JP*9~3h> zV5_clu2>DZ--1*3CYVA9rlU}y9sbLWOYjVfZj+}IoOx?{2!6cjYD7u0va_AJO%w5&zrn+y^o{JG z5O*?(l0W|_9$(AeTD`eUW>wkVN+bUaQQJ^jA@Jykq__Z&zedBKA>x@F&VKh{ZD6`sHrPv!@o30@MrOBZf1duSxg z-G%V%vN?)lI>6f0%XM$`3M-iSy%$zOKF&gv7Bc_5`jkxVi8w8ro!+OtO`JQ}r=97q zPG-1Zck2H`phLc3RaLy_G}bWMPkocUJ%(>P+{Jk?Pog5`)rXF6H#9O46Kop$S+x9t zg-A_doo2->OU79%=e|l&k$;AJc&Nn?foEOVB!+5cs^^S6RBmcUVv}vbXREl-#!^kd zUOfu{#Rx4gdz%xW9L`o&Zs<5g-HRygfAcVwMlf!qY!Ooe;}*6nk}Lin=j}^B0Kf)^6MwM==JS zgX!OISF%(;u1>aw%}>JSH@7J9a2y6S6f*ek&P7VQqm_4X2S4`XM&pl=$%50S1xBH8 zANt5_#@PGnTE7zyuio=oIJjD(y^GyRTti(D#8IxS{Ml@YIRgTCy2Kf^YtFRUY>FZ5 zXAi1?7dU4AG7&u{#;Hxd3eWIF!d&WR=NB33n96wzOqRltsBZ0K>XrpROe{VTB{xxM z)3sR%V!qm$>1d6^N>*ZFKcPSp5Kj~N*Md5V zbj@yEd_gmOFlf5me(r;RP+`pHuPvL+^1Ky>x^P;`WK7|+R=V)c)lB|bX2DMk1CoiQ zl-Gj}5LxN*KykBRC#00LqvkuU$13<>Zr7uYWG znq7ItH@VekQzP|sH^?8cOk5JkqrcAmyZ1b?1J9D$Xd(#DwO!f19&2kxpIJ9{j&*@O zwP=6=i1S$Ls5WJXrlyG=D`-m6k>#w_*J|c#0v=D%Aw99zFn=Rd{e}MYp$p-&=pQE! zgs_9zL#Hi6&0y+w8zJCO%SMfeIM@daLt)7O*-l_&?bnl#3k>9f{9iA7x2!k5PyGil z^dt&@W~VH~gsareU5i<624_QGTprNk;;lgtkKgfS!7`z?MG>oKmo7w+rQ(n|a$?Ts zjcII4UvWrlJJQ(_lYzaimQA!%#+#f`)~%{Mq2d*JT)~k4Nh`TF*`dX(XRL-j6lY}F zmApMsTn#c88t*yL-dtT%BUpncAA=Nq@i4=lEfBkb;Jdg^Ne5WH z?U-D1)Q70-DI{l`=YVu8N_S@-t&HKb%cG87NQ&Q8J}_^5+y1J|cd$6w<|`c2ik`C8 zZteP95PtA0zH{`XusASC?egnT!(dcp+Ke(s5;IGkJRx;%7bt_h}@_8#o-Lq6D z6dTQxby%8(1$X0Clinm7k5@K-{cq)tJZmK$@1n>qfQY;iUCg(Lf5hRc>WYbYZ$$b9 z_Ia=5Nj=##X2ymI^*5s_#K~@EoKR!h-mWo`!-CxyYLO0fBjY%4U-!3(siZ9yD)#bp ztd(qjG1VXqm=Is!+t799L^LxOTS|InneGs)d^6t<*sFnca-0F+1;#61Ls1k&!vM#k zlB?;YbA_K9)+;!+4N{g4_+pcJ>1FSO^sdom*_2gilBsEu>!(K1Xqg~2Y+gG@knR+z2mfo3n0&dCQ*-t` z=n`3zZD;@KOfM${2AMdy3yrHC&#D0?!+mALTTx~ny9~uO9c{JzI}bR!?TVs#l8T?( z@E0L>!(B2bKX1M?@ZbG+fddot&<|Zln$z8N_zo$a9%u{PnT9M#*Q{a`oBpKq&ZGcB zq~t4V5D4G(8TX_>hi`W-IvpQP@l0(EYR>F`6+(va#t%$Mf18k{h;$a>?q3w{1Y1b* z!;re)AAhfIcFQ`chZE4|t+GF6*_JU3M}O)m`9){=_GUeNtKN*FjaZsj2LG1CqP+%f zm2tr*&5JO7nID|dH#E-b?rU`DejiRwHlF`$3H|o_lVIYX)6D{30>=Y*f7*o5<8Qn_ zMV?~cPFK0r_}&!$Najdg4Xms7$4oTp?lTV4f zKY*Uk2|vMZ!)>FPwmB4umX$qPr=plWcvZM)rUV%>!Nr*{8lR(WT;dyGIG0|`R7u~v zZ}oBP)!nx@RbJ_msNbySP0x={&1BCsT%&Y!39b$W`T(d-VtGg>r@LC?6;F*gMxZ~M z+MPWcF80x7tIz-qZr92qmJQT9QL~W8-Y)aB1|6h2N=@idQGZlcHW$8oSrK2Ep3O@G zOtyN)vou2rl6doyN?<~Qocu)rTc{oRel8F7>t01d;Bn1ud+ZE4=$7OIp) zzyn@dzdmq3A&Uf@-i2rVaeO{%`j65M<@v@XE46MI;FYYY z0Wx9Jf9kp^h5q;1z*K5Z1~fG!y34bft?0#+HQT~b3yE6KU*}hs$cbV*bt^ycd)K|@ zsnMy6b2NU5OZFO&j*Tj2nLXavhe;z7Lt^Iaf6aDO)~m+o`(OvSOB}A5)}8b&o2=~G z3}QPU957vR9&0?vc~D2LV&&^$zomi*D3P)6;Neq@d!o+&6J&?S+#l9tMuhsKKXJ9j zB$g@z9phpQu2&{v7vcmhbCOr8%-7}WY8>^~ms&C-eqrt4FI7?i;qVx!$>0I?<4%>i z1D}On51*R+x$*B$-eX4r?X;?m8nNi#myuf$p|{MMKX6oBA8J5xL7_)NOVtXzMA`C-SNI zx2~7gn3S6=na)y&3DYl?q@l4iVvKU*6cGiCk*_0Xsa^yA{WN^wi$3q2tw}|A5WW)b=(-*Of&$Y%w(IqfC;j+DXi!Gbw7|*DXIJmKLwtSFmN^TA2~J z@P-yVZ%rj2iZKu|Siyzbjllv(vGR;+PyRa1eiX&K!(5l9!*F zyA^TJz7Y0x@;D6nLwn_veSJxIV)=76M+d%A^+DrlyQn8NRWx&eG#X$a1k{LTsH1r; ztMORrP>>~QO4+SkT8RHdZc;PiVrfLeeVgX}?uewPUcgpP(W;7kY_!SFZM)%&B|8Cx z{}z7%8tWk5{cW+qW1qmEHh=Kyj(1CupnxN1smZ6;w!Gq0#;Hg@BP zA_0NgL{mPT;@}mbZJ+-Xd|TLb25fq>6t!7erwjMo4awQA9$Z7wMCx1&+(7qbnm-Ft z%*12SqYPBHt_Y9Aa+qng=)jJ(A_@~Kl$pa_U%fD38hZYSO`g&uBgkLA4Wrhs700o; zT7r(U9Au~?TtjQhc*TlOXLVX-ixgo>IUvM9}g-IHICuI~$*F z{scVT7R$!ju}vV7U3UQ4`s@yy!bs@LeHE&EL4nHV;TPxZh1H#xOGk{;HW%YtuW~>g z)+uhbVUuiMeewo$ZmKqEH{(<3q+NV?d&cOmLHA6i_4uHl1BDtt+rPvsUlY;i{P6X= zJ0|xpA(jD$b<_3R2h*tls2B+e`pvagMz-{#J9>V~Ez;4vz)fNN#n?<*m|%ebb=$2y zk@n}_Ijt8Dtr%~0iu*ea>OtsK=&r1N$GUC@eZikKy!ee6}Q;uqWId_?b zuAPt4XpkjBVg^2UHV3S{uHm#R4z%5Mcp`@Y{+5a$JbSh?yz{xAIzoeN_*r zdTfYL7B!Z;)ljE;W5SXWUsK@j6?*1491EhO#Yq@#73k2!HAO}}9U?qo)S^rEII1+% z1SCkh%k9Nh@jqc?1G6<7M>{!3(OOiYLMYp*|3#fnQY>cx##wfz?J8*M^%pt`e_L&s zKtI}t90|hV@F$I^;e*u-xaMc0^#`8-wFf_4%h}2}Z#~Vv%XR(iK?Q(UA2k46CI*MI zZd7P~oGxjU9M*iJD!iR*wfHLM>Cd2K{j1M+S~%#b&(w0$lf46)g*sV{qHi=7E8rBN zU>oO`HvB`}Stq)x0qneUtP{&Uq1J3?0{(XV?StT95vRM&wMOpxZR<7IhwpQWniA2LAw zP|j{m{NOrYgu6s>_jmmC)R}NnfhxzgzPo8f^uN}(f)uX-W0MjfQWj%s?YF)fAmue_ zTit>9IhQkfhMnEe;bEw3g&`x=N>pNtw2-Ypg?$oy^T+k}s6nbbO{sPdy6GeP@e-9? zJ}9+!YtApMIv`>elfK=K%qnh%IeTt~^sET%=OMNH0n~NAtW-6sD01J7uyZ5Uo^K!VLwDvx z`FG0}+nva!mBRATN&Uqt!v`(ctM{oen>P~FjHdP#&3i*~816T!iH$`LIc zV6d?zxQiPK51Tm>+$%w=a`MuSlM4ipnJS1qFH*#R)%gKMx#mJP_LafvH;bY<;O^&N zxLaKaSS54_;lEB#>Bb(kKf-GNzpnAS%7yd)JZ0lswwGj5sXxcLJ}zi0vB9IV8LU-% z)b6t&)9s77$*FNqgNf(nqfBv^@21l_i(T_^5cAr`$-0k@C=IPw=%nY>xa3GkN6b|n+_ySqSzgB)fCS_n_hIB zZPMN82AuHtCS%Rf!Jc^zY(TTZcx>At9i>!b+j=A@Ly5R-H*%guvVOS zF_Wc`iCbSuP()3%5YT9O%0hOjiRj~h8-~JJS0>IgWb7sEH=`nF0 zi<(D6l*7ct%Q?u?UARmt`#KUtjVS@pgd#m--(BpE$?fh^3}S}Bo8Jw#0V6S-A62*b)&NB?~Z#00&^HYwlFb9DgHl$+0mRKWiyiL4&ku}0y^!1gO zT{2O>KP2-}>1Z(k`4st;ZwJOFWVDS?yk*VbF6mg>9v>WyC2VmM-5r}qrxA%62{SS7of+eNlmh?l zCDEEQ;msl1ji*uzK5}y%3p01*h)QDD`x%h;tI=j2kX?gIG|1E_F~agQpcaXnX%UWv z3_0{F-*3A(L2V{wr4fOSKeD*R;F#-Zogm5HhswRe+Y>)?@qFELFS6q2$+dA+`C=2k zX6u~tAF1L}^8Ka6fO!~YLz^gtj_zK+?&+5;G`ns@*q}b;(o2~YoN;j5h6v>XDx0)v zO4#+s5l!0dC3M@qgMg=c{Gl&_$68wVA>Fu^%~gv6awhKcMiA^P*!`t-TYd~1^i$gx z^4wJu8UWBmA|ubf7YEw8uHbf5rkMtziKdH8$WL`H90=85GEk4Vi#E!cXFuE=WKx9P z=xfr0u=>3$Xw zzKUS`*akYz?Rio&?FY6>cl`QI#%2yM{5C*%{y-zBVv$cP9)Is3EzQn>O$@h&GnpdU z=@#uCws_!OEL$gN*xU~hp+VrY@>bk0#f2bF3TZGd(&T(DXi?M}H7WFVF;fzubsG7v zwE`|)BYu)Gt16YCqjKIJF~&TzV!p?;qxF-ab{*jb(co zP5U|vqd(=-Zo&>nzyhEihc%6p8Bfqa+$!!n6gHCzz!pI~H}$ARU%qDC63z%GQeP3# zX1?Jg`w{PicVy=K6h1K}-t}s*yGrM9=INLK)fOw0R@|}5BzR`64RYwJYm>7=$L^P@ z>eAwYvOsDFXHq-SFt1z(#-@a#urIn5>F!`jyd39xh?$wAna9^eBgb^OR7vB8>>V?T z-v%c~I4JLQtO#$H0%q)pWIWY}z1u4S%p5a;4;PCRr6=2P1?JhN zG&hGw*p^?bw7pZk^I#NMl9h2Hx3fuXOa@i0IX_ZaUm`p0wAhT5Kqomrpj>Bq8&rPp z%nVTKCpVVsWm(!t_*aU$fe59)5s=w(kxhPO1CIp-4 z@S4qu@oLV%i*a$gyKnWUWWAa1A0Ln=JIaHU`b;|*Bc{*(6K>vO{u{<>Mlo4Mgeuu| zvz~sYPHaB+cDI^BjAmQBX4AUo!6WLy8S~#4)F2ZfiR$sys{$&qbogvb)3=aGpbdi3 zVZMU-sBdQii~jdfJ581fnr*l1+JpO~GR1ek>bKc41`x@A3ZI@RP>%%_{i;o&p?)Gf zViP1S&oLjj(9}iCe={(+@IAx(s2jjcRu;X%7;Szy!vPgz!Jm_We(JD`{Sis~*e>~H zksu)t9(Py1(W95wUpPVsRcId0=!WL9$_3;`eo(v@E6c6+27`b2;IsvI9u%8%!Vy6| z&tMzrV|YdTG&JzA2)tM%0kb88|NWMmu8iK|r=9Fq-WCQRSW6{=bBBFJw$0y@-mpYyuSXRSf!GrjLg&ohr zUk1{OgeOfvG*du9O>j3NF=>yOM54uoug_s5Q7e*WM)1QloOe^xsLb5IFxaje;Igjk z-&XBExZmu0yKZ83DH3*K9>Z<3tEHozL5Z!$YOMSb?uFikLDd!3P&JO7iuk8RCVj7Z zEnd>IZo3vtKkAW9ewC2_j}Wyc`S`5}+?5#2DyJ294PjuOPChHIMQe6}`KV~BgngLU z0}R2!OPtEtMgB$F2xGqhd16C4*aJYr7?@9+(>|wMi0LbInfzA9`2lD6c;c!G@!r#T z^jd|_5{}7b)ul5*!3csfi3wx!usCTc^!Z>LXJ^{aH+6o}mVLsRtVu0=g&#)k00csg zM91mb3PZmg!Us>v_ApzfDU1gpsCW&=ll%Oa?6M2((`+N1tN|K_c$(Z$O_iYF$qjOdF3(w_Nv(aNEIgw-8x&GXNP>x{!P_a6dBlA-ia7n&EugR9%XoZu2CT$kyGRVc$tv>(J6zBbv zVnjh_#sE5S^_mBdxntRQFUyVo(gBKyhxr5!;6uqIqj#l(m&~~Vn^rveZ_#e;x9G3g z7wm>wWvxVf33udD6`2xX7GxId5)sH|Bq+zSx#5!W|IY$|D%%cC2aAESi!kV1luZVM zbbR9NIu`B+AErObD>0}-Ki6A#EH=sf9=W?mbMsu!&2P*)sVQzRV5k4wkIqx?^W|3B zQOrgQ5F6c7=oO?!ccswIO2e`75ZD~6Ts3JufDC?<)1__SeaS<-= zFfL)GuTg++({fz}mriJvT&9;oR8La?5k6}Y_-r&_5a$xb$c|!qcgxk8Ww+ zl&!Wam)0`LgE+dd(G{p@g=je{K*Spf6ieGJ=>|Qm8b;csR@vtoWL!J_elW9EswxD@Y(*BjYaF@An z$P@b$!8^$#n%y(_{h?Uqa^|byR5^H&!CI?D;;0@X!aj2A9s6S%VH@Y&#K?@T;Gv%+ zaBtY35ZYp*)e!MskY;>a)Y*4#Nd32=L{Q=hDn`eqp(p$2NT%wrJIt+6iqK!n@K=Rb z(vHVmq+sx^Lbr-ue#f1K&@zdqE~QV@*WU;~GV-%fAVzkoK2FU(UE+ouz&= zTz}xqnsVkqGKAmXvRaNQ)zc>6A}(-vv%kkBg6XE#)QC~c;)L?}TC?%Pn}BmmiEOdU z{DZCcBcL;?rh(SKaSK?mX5`=Dzk&n#;Y$G}Ia$;|8(@m+6Uy zQd{;~mtQi#A)nSk{UcpgvOTpwui`-VrKIR9zE~#Xso`4aU@ipgKHVP>0s9<>h)FfT z78x}23lb9=o&Q#kHXIEwwl{_Dx~HUFoJYR=ALfx3~ea8{O#d$8>*Us2P*H8~Hxk=IQA3@5+B#^y7u zl7sh57R2|O;e{uNU`^Vb&@BCJaL0-Bude)I&6wQDFP7$08Z1{Htu%MFP7EmOG)`3a z)&u{ZvG5jzVDnh70FS2v6GOofI~fsvzfIhq2KO}SgIB)4RR7w{`y5xMlI#H6XN=fy z;eR6ZN5y^T{fCH({e$CrG>kwC*{3Z{Cca6wfGsh?m;Mb&%ve!#F@(i#3hV`UA9Ij= z5C7XLCA^m3rriJxk*E0)p@p(3tQ$uBq1>uJoIMZe-j@{*5I%NNUGHPznz?@e8W7vL zp-ZE~c!O8Tt;sFd_u1c+#K`D?qsCW#?`Z_GP3h?o0iVxGeg6W_$pO~WcROFTz*nJ^ zJTkAw-%p`hv;=5_v^=A4nX}rD-Eb$h&TXcJ3KS;-KWd&p+Y`1=dIT(bm@>;G188q`U^LNtn z33x0y-Y4AylqpO=2-EwcvEs5k?$F(qv@u!phgKQ0n(;trv9p0kK_gBJkAAS<9Os*h z2+YTnBacaO+aE>OIb~CJ9iBFpDjzgrswKha^N!Dh`n-B5=M)r-gPIwIuUx0J(!yp& z%^)XGNIki)QjN6jY13bTLeWfTAHM3-{VsUEu8SlZ5DzGo-gb~dwBrd=dNbeIofvC2 zJHN$ccBX^r{k=Y=IxVI^>KMKaZrL(Vwn7!3k#?QeNpx2NK8vyIJVJ=BfS=<$?)N-*D-4)zQPbsBsc4nyG1sY_ zg4s67x6SguM|(sCG}w|Is<+yM$LWNxY~2EtWkE6fFT)2%o}2z3P3IlYcK81O*n5<= zM#QLHt(vh3dZX1^t)exnMQtKft=QZZt6F>Ac4@4t5t|0BSs}5C(nM_yMXcYupYP-M zSN=cmoO7=8dOfe#wd8w97jn3k85p|83McBoT8^i0Y=*ww(Fvb0{0|*|O;GK>ssMuL zH@V+)PVD^fAijh~bCq~rejEDW>2Zz#M#0v1;XlGwnV;l?Gf7C)7>`*B+5D*k|G9=- zTm%ECne@-i@6POtRz{oMOcrjtXD;pI#dbDbf`p@t=}ph0qv>1h9$X}q$cYw8E_`#I zfqm!oVM6e1;&WVxfdKy6PVOP35HY;v{zFt&oHWQO5tF=lJiC*>b--|*W?EONHtI#p zo{X7G*jNyHcJnNDEo$D2KNHjcz_8q?{2FS0p2TOOiN>B7R7Q|M;fdE)&*kfCs+p z4>cXJkzb-h$Ag&P{C4knwmSB~*SQ2*BYNr82ZEDgQfcGtnluQUVlixGf#OXvo{U_^ zb<1j0tO7~wg6dC*-)_$sA=1nLO;b47PUHR&OSeCvTAO7joQ4u2^|sF%kSfn+OG77c z8Srt<86051%1k=-X;(er)g3UoN2#A&y%-DtK~^;qxTQWK(pzX_)m`t8O@w+1Bn{g= z@jm?({Bw~*ejR*K-CQ}Een^Y|tjn#&AI`Qh=u=X)7>A=6CG)$UcBT)!LYww%hZZTO zI;b8!b~{Jyb|Q{^uxjb>lDHkk?}Y-aTWd#lZ-Uu-U<8=|k0xdtt>0J#X*_0fOggtqJAruc8@OshQ(J z!?wDO>LLY6EQfC2tA+XetJ6eBkjA>l*CR>g<8k#qorl)q+TS_0!{uD}FP=_!QpoZ< zWS>uL-Un0IH!k}H7CK-Yzr%*w*ccZ`4>#PiF@ZgqiID6Uds%9KVV8OHHbG$ek zZT?tYzgn#!s27ilK&QyEmUc8QSNJvmGV~{e<~qPNkh`|D%p`PVKQT`=&SUHiL`PF) zj3c|w=@kQn^8Vx1KQU}8CM;J=G^uEgGb4Uw5}&^h*wQbK* zOCg7wcTuXl+9+F#=UZ1WlK;zZ{+oh18j_g%=vD;xHbY|TaS}6F1*6vS;?{3j>ERB| zRq$tT9#v++!5B85H^^mMK!>Gaydsb=AYm(KWf)kOrlyQ1GG?o*vBJc}*{;wGnS(24 zTK87wB(ZrW%-}1+ZNami+ZlFS?%cQEpFJ9Tf!0KusHa%V)3Q57w~B@-UFgx(tEmWP zACID3*g?*$M_JW=vK$4nmcbM!hXw33J%rp8B(k-vz3jA zAK*MhbG!bjxa3j*9eXbJ!Z*xT(z)_;vxPh;#Ty?TVbz&J>ONZDATHjC${Kg7gn#E@ z2R{A7HR~s)=QYAVOpFYe6!SL&)fAd1Td~lyUaE9+5)nL>7fKa_AD!1+(fD;zL>Z*J z+>&`q?X&YEoTvlAjF}0#i+&=a8zMQhFm<#traT_YydOra$sb?N>5TI{PyDRi@Pa{B zeN8w*>3XVJbu=5C=^bU<#X9TMp1B3nAm$Fj&j=?nD@L%ER=0 zPA7e7N2%6(SD-P>k-AkKQS|5PZ30gRKREWZ&o&5lUNU3k`!Z~7XRTXql0=SS3;=(; z-snBmNUsg|nExl|WX^l^PJY~L;-ZM0aIJ}fqi(LevBC-_)SU?eis9^0d*0%C@5;9K;NKBL64 z64yo>1F7lH1%}}x-XBI?P%-RY`87!0B&blA9y7!arQiJ@k%pfMd=$wX1a)r@FIsV7 z3({ZHRhwsPb&I%j*4sVcEObIRRv85%Y#&%HQa&uU0h#M(^SKBg_V*!cKD`{*!-2ZU z%8^L`9>1<6#M)JMtJLP+pc&V-8^Wh`6`@+J{&Xx2C{ z*WrWp7{ZQQ*j!0X3n2=OCnEvdXBCKpB;qVL4Qg*%&q8jB3E7>?^#@_ zq%o^ZT}qCZyLL~w-j7%GC9VxaMBGPf;qe~B$NpzzieJ}t%~f?KR@;zbG3W8g0yX92 zgUr(_a>JxP;sV2HW)57Wo8QPQ3Un-h2tYJV?B_b?GxMp{Hf598V-c7ZcW%{G8~v=o zBk|mE5nm}qp|ih^f{0`3Z6QFbuPvAh9-+Dvq<{3Y3L~PO4Y%LOD<6%GOtEVJai#h% zrfJ{tr>QnysDn~0L@A!qSUev6qpWqlm*TTUa@to}{#$tqT9N-u@7n+7*fNO_NFJy~ z(#BcX!5q=Ds=U?10-jj>JTq9^LfnjVZ2bGsr~&)^x8ulrkO)^rj-fjF2j~wRJ7(iq zGkMoh=F<{hmt8f##c6{F_7_fYGZ%0_A@IV@dlMr+H z%+7>5VaZ7obgjk>Jmi@-amd$xHJPIBA-nTrk>y}9dfXhIwWtU=iv3qs!fR8^@1a>` zx2~3mf!UDy$(qu!txs(${)UL&E~j8#V@Qtc>5 z@Ke*~NLTUJWt`mBObb41Vje5hMd6CUsn@jbv|TZ>P06vLu}iJom{Rk@N_Yk!CuVA_ z!i?*j*!`Jqm}~$@%~aTpuM3>(3){7u9df%p@E3>QLv})UGrt`#QT~Ru{mIceT8fqd zt=4ch?C1JQO&C_nuK4uMu>>)IJ2H1(;W5P8n^&QsL*Kt@9Q(DHQgDmkw*d*Rm&O9P zMnb|;?brkTBbnpIMO25eC`fK#ncCfrO={*`v1jYJs!ug#vQkn*&V)*l2V*Tbyv;@- z)&u-`xp_wMkLL5JXheOhgaRV>;nNXImF?H%V^#qr+XhF+ESm_!nA7T9Q4gjop>ff= z_t=U3Yb2Vzbz-^LcL?Y6Y2$qSlO1q4j7Dw=RttAdW#UxI6+jM#9iB%#$yXI(`tOAU zf6a5zq-O=F0Adhnrz^gVerI62$tCZw&^kaTL^r8ud3(TfZZjOjdF8slt0=zm)pqzp zA^19FCfED>Pv3=>@0$Uk^F;j-+vfS>%HZ#X?zQmk+O7q>r0>hckD{$Xc*!A((Wqf} z@DMF8doj(pbrfngFL&`yB#jOD&~tqVGPU(10dFrtTNtgZVbtx?S&ul|2VPT)Lv8Q6 zbv>smIVYyxel4Em7qM8R-pb3#WH6k@zmkYK^qcy-*WxyLkWTZ;PiqT)62>3+@c3>T6BcgaZO_ zZ&aIEq#dNnJMWunnIF_l`T@_i)T#$~HFZ%k&Z{?7>2Xw)fBx~V=}LW8Nl>AHbM?oW z>OWy5qUhAnKRg0l(0yq|_Bp9|EO~ZyCs3W1^Y={Rpy7XY@^yZvO98evxh{#aMxMix z=e_E}PQZxBW+x|CU=F=hgg2$T6(hLmA3(b2ZGUUK3N9|66!W_2r&!*260SYv%}#NIAtyleJJN%^e+W#CDio!ZBh%4`adWH&CLD zm3YW_Rd3L(xnw&>wH9G3G<5KVig6qWBr;g9|8GKry$X!+4yXJCy|T`|nw^HwECRVBSNza#F=R-{t-TVsd9EDF33WZy`g`%0 z(z2@Z>glb|(#FT2ay)Jv^To?5-Jpuq76A+kM1F~449)Y|@fROG`!fi9MB%A=*SuGh z#2Ht@(i8!xDa-BhLjy{iaEk9J*?se>h@5-ac~9W*Q~7hNFi?qC>7uF1bQc(=Q_3u- zd$=bh)(WCacY=sPyVf&#>7nc*bcw(mDAn>`o02BG-Pk-bEIAHeMJ8uQGBYxXhL>`IXZPHvfO_hP5{Oi`hE9E${uJ(i@cP=4Ai{8FI;2~(bIPw zFpwQ!)N{92;gQ;}pA)_z3{hss9I_O4O{sLgnXc28C-Am9D}&30<_+0BBp()aZ3&%< z>IZ#cW`}Motq4@`P0QiQHGyZ+V-4j8vFy1K8_uSc-P%#?%iXrm=~y?X-fdV^B#XaP zMVXFgmDLqL^V=T_*3&{gQ4dn-uLwO&RZpooq0=OV>G9BOkFLZrUE7WVL6T18y@SEtf(KNLY@Rq4?U_6@hP=$Jx1R{Z<4Jf89;0e<*GI zgcwlS$lG+@fU`l|p2o1QOY(UJ_OVRZnrH~h*<{6t+fCF>@rAxkkH`w{!`#oMMye}N zH(6ImYjB=~xH@WAIlY3)8domZ@^UnQ5!^5D>bBw&m_%<@yf`}>a~Y|>=1YoxMK}eE z*c84J=ryK{cWBRMlhtF{i>{Ff*&4f&rDA!!jkO(_{DwQ5mx_0Y80>(;~a;59jIc-`K?d+2wo3N=UJ%XNJ{OB2^a+4&=!Q(-LMY)M#B z{PQ z5CGVACF06AR(v^|g;;}5c3SiiZBM#atU%GoA~X*D>-vEU@&c|-L`g)m9R85 zzPX>wRCk}^(v)m_k-)}S$-+C;$lqOg?{K1>PM>1_oQ}ccQfB=cv^e{X@(TfysMEDT z#fIXKdrI-@#;r=G0<8RDxgmj2+Ekf0`O#FWj2xC|(P^DMCh_SWdZg;EBuo{bGJND+ zP)|OX3k|ywNL0dxqHd)3cp!LU)arVAcGWp$q!@(;zt=E_+ z5#Ts>yaJVbvxf^krb@9%%N?(;j&z`=))gMBSU*tSVSzLyd-!!Os0AU-z4Y|-4DBjL zBWcLr;@QR>86o(K(TZn-|Jeh7XjKt9)}K#5`*KC(3N`-QIActAdu?dD>*BoQ$03t? z?|`<|FJAb%%n}-_?GO}lntD-n3!Zyq6LI3;O?BJXEZxjWG;B?+79^r%W(ct3ShPv>0gHqtbNf;$EWGRGrPcFbN2vh?yLd$r|@nt0ut93oP9BWX>biT;zmkdvsSAp_&lq)Bu> zoV;MkJK{Aw(v03)&retMh`4Tq*qk}7 zDDcB>Sf!82eVPS;#IeWvg@HLxdW(guS=x1#M;G&ESWy_|!|P#d62X(}?a{cGEGd`< z46$}2&zw_=pLY6Bjls<_bsNWeIQ23b>yMq<8<=K#u@+u8AMGR35;G)yR{CuVx34QR*PH!qVO-UF?Iw| zzk>BuqL**zq~djg(V|?;r1DCf@?9 z{wwH6qEp+kBwQ{J!ftRVa*_M;`oOnn8Q?f+rO~t2V<0orZJR7TFyz92ep+qzG<4dk zww~}}JCeEwmYCv1t}Qsn9aIP$C;A1*V~UXUXzI9wROrh={wFI6j~3?{P1!{IBoG^O zAnfMc8gzo-X*A`fo~^ihYi8GP+>DyXH2fEjr;eG)`5?U}fZqNvj0QrqY@be!&OauY zYWzMRjv89kQd-%Sa7a3?R9Iji@lD?Rfn%rAdQShV(fM0cJ^Y=nc`~HK`|Ua(WvYG} z3HJ~^e%KZ&Z-wHhgy)0CE-=c9B;hgJ{NdP3RIvnh$6?(D@Kd`05?{$E|8dJ3WRZ}x z?IsO1aB->UH@RWe+GeMS$?+NjqHAl@-(1K$wv4`=DK+CFv{_H^#*|9(W;Pl3ROO1#6+b82iI@Xd?TNX#(0Mg7%0)r}-dQE+8z<@JPz>O(5 z&uu9+Du~?=5y!M+BHgnkdbt?Z=jBc(L4_yv)rTiD7dJ_7tFxxD@B>!C(O7PxUi3HKXINlT%me)vm}FP7H^iPMzE-G%y|%G|f>C2r z))3P6{^<(yG}4eiga?oXCAl5-7! zZuaxBz;3Wni8_B|f{;z(-JK2Mj ze@6o=zD!b1cCZV@vV^frk_#Gu&_a%gsrI(r@g4&PPJ+U8=J@CJuf#Je5n+0%&ZC-b9i@hCTCzo0>ul<85BFn2UrKB^_Qm{vP^ z2DFoECw?d>Z(4rsT zp0MvklEr~)|Af_^ha{uwl3Xjg@sxb-dZP`)zt$a{@`OqFXd<76^%QkktUga&49m+$Zy zahuE%A_D5c$3iQYL3s-S`X~5du&7=Ov^F65GeIb+#>h0kHIN|-W3PjB``&>R zgkI~{Vk{kw5`D59-hzNGgCbqlKI`1@GBdN>h*NB8VK{tWrU_h|-`XaBcdI|Zndfq< zC@kxilANJw#5(2e6@@w$uu=>)c3Sr35(`A9&qc9}qW<)3(!io>EKcG1I(8!GDe>pkIp5cfO>`KxbX03K8p|4_nFnU@^j+Oe zIV@w#4S{JO#_LpF;P!fA&bJqV$;@Z5!E^*r4==G&|MwM+NB#{3V$IS|DfFGPBT=&se~pe z4Q0C#&|UvgTYG~UQZi7izQ#LM5J}_cC^bcwFw?r*r@CrjI&MuJ(@3FxcM|dYCX3`t z*B0QcaGf96sxFcSSg1uLIdXS}p|3e}*`I={7#w-{C>BwPt9Hcc#aLN`#dU2pbKYqYJ62 zeoe0h>LA&IRBThmx*4wmcj*9PWv7G9j6ui@G9lNg!DDLt4EIyMU zWu?y)CUDyr^VMl{W`3iCuHWk_8=WgZFKNpj-z=B@;1I+TAoq7cGq0ztJave)1O0OL zb3JpZZ=+FgKYy|7^}E&Im~-iE(>roaWPx%Lg3Y-J&!1gwiZqj@icu@cdfcZf77y~L zz7~^+WShPuWl=CbLZdgBU&xui#%myPT*O6>+|=T4fqR|_xMG9ks1+zi(z zp@paWeJ@GaY1OlSaLI?eqnXhLxqZQS$2Yn4(?4E;Qwr1Y{Gj5!f0#x4L1N*SH^T$9 z2g%`FeZB>UEE@2z(KKUG2a<(A6CJZi%*)yd3v}mvFz7a5D7J|Hr&J!z9%i{sBdQ#4 zU@OeYj=Ce&?NSp+!rrw-KAr?CXeVmr2EO67=nNOsWFFG1#1Qm`L^s(z?;q-z7`;-K1{QgHrQ#-r5U zV@VOOI#$uR!Oc2s{s=iIIy0YMNX9j) zDYJv+pbcY)BWk&UklQ(0wdY+DhZ-@Vig#vvTJ_k#t z#4>x`<%iq*baWoYQlsnfvmsFq3yb~E&bWLIvLUH%^l={(>BreMdo5?&gTVS<6==>V zEugWoL+`ep5tfRT`VKaAr^JfDeS@I(1%jH;g!_+N0{PworN);pBBQp$xDae$iYu>MEZ`ZrYv)x#it-nQIlF|9+_@gbEMNeSh#ZFef@=vyTX5Ox zIy!U9HV8tuo~&h2yJ&%)j`HC~d`i9;zHcb-D7c~?!zzvh`v2@$5^ol-m_+QaGYSPC z-pVq0piXgAO_@Fd|2+|I5m0k}>eSD)^$;3Vzhw$`+m4gGe!uNZqNVdZLg|(}NEvm> z+l;BtrYc)44kqh}bRT6b!N>$=!`t7lA*2<^aly6}Skb3c7s!(z2IYc{0;u zO`lm#8GjU}b78*X_E84J$cpQXh@t_-sPcP);bj|EYEf6Ge-MH=zm{0}P+BfR<52Uz zS`@Baf`K@YiEz!4rGulKnB*8H_eb4Ex%EsCpoW886B|}=>eGV=tjT=V2@U z72Dv-1rxDGQ7A~et{qK?0asE zq38G4Xm;pRceu{KcK?12vDtYtEjr2(=RDS)q+h{a|K0UW)U2Ds7w2={3+1O|l&Ef9 zQTTZ4PRbOM#)o>F(fR4}V=3v8w1 zx&joTi-mzt()smh008*=NXtgl{X}EGcm7grJN++Po0GF%X!!K&d!gkO=t65)?zcv5 zd_=DOcRNfCXedJLXp=4eqGwGz8a^TWP&>|2w--J&DgdztwmF~v{9y9VNBufE9Vb1= zoxFPKsUa2Z1KOmpAQ9W0P~T_NFr7{2sOXv-Jp+_9y2{#VLe)T%>qP;|^*>!* z+m2s2-d-!xt)NZG4iOVsam-Bi^kM;qAw?F$LojKi#X5#acm%T+m$>NCow4E#zun z1kp<-eBz$aU{A|~K>g%h`Nh%Pi~ z%Q0S^Ibz`=;@bE;k`y9!=Ze!0sSxT}b=oB17`Hjs{7V5K-tHborNO>T3j%Dq>-9wb z>%IIG1I^`YR8(3FetbKc&V*x5YFb)<)%Edr=O39EYgQf~P0aipL}aDJb;GngTxwvc z&}li2ko8vmiJva{I3L2Vap`-ihO#rzB4NPWhjc_ogFSN}gA5rU3&{-7;%oSOxfs5? zKTJAu<&o@E^i}6OXP^5VIQui{CLVx9{`!@x4JbhRDb)y+gqErNvari(n4g?*^=-35 zg?0Y^^Izx7K$t3TR7^vZ0d|;auP;w-WPQ+EU^f*MspS-ToUY^C_)hKax?D`09ZY_f zsu*Bu32;W9L0sZ5;_U9^a6w?6c+jG`fQiVfL@*6U1=T&@q52-6x&a2Wgtmm}^AOfQmM&l{N-IpR+pWwBP7@(@)d zx>6H)Ss?=*uXzg~WHWH*bynv)2_Nz#e==}d0N8{rBg10oD;sQVRLb9&|HuC$?_9OX z+0_omZyj21;C;_A{KtsqaF#2#mP|bE-Ws{D7SDY}IPAOsuS@U0vho{eUKi?9F!2St z@v_3oIE$1xUh-1i#unvP<7$T=Pd_9kGwi9E+AVVBZ32^Wm`lEV9HAOXnaz?gEB#*T z4gP88XXicZcGv4(wbHiq1J>xce-~2hXh4?)+pHt0D}5zz=aOZ8guuQQwKBmg%ll-K&cMo9s64*W;S+SDy!`Zb-}jph^$QxhvC)*8 zU%`UZkZH5W&h*K&^fWo}%_3)vOq%kzim+2_aZ-!d2k9fuH6tU?b>4W`Kpv+KEoaex z(QNu-%n+b;2=L_DLc1=yBZ$901gON^g8av@oLLeMUHvb@=r1g^bH2TU4nK;IczN)@ zw(@zBcF@7u;>Fq4=T1hf=UqBBpMY4DMw4_00ePg3oju0ViY-CMuw0d!k`%Bw(|3IiwA5#7JI$+(65r0WOI+lz|C zB;wg*p!??YQj%Mi%}yqX+U|D`q(2Ox865Y_Z-sBKH+K>ll*bz84!Wm%jAE0-t<~y{ zvVG4x%YV#d!2CTew+Jm$iB7!+0P3L-_AipR+kcObI&u)wW04$;r=f68ZG%HL(x>zSdr^pX^@z@;b=y&ccAHV~%DxBVN2R57L)q z4YkDtdL4YM(DFL?AD|D6djD zHm6EgyJ*?@BOjF-v~ZHibBm2F!iz#j$9>>o=Sx?$lDsjlkcGjT2fBeW_&QtwuqaT@OPIhhZWk8V5do9uxgKzQd zfT6Q?{bi_ zVF{j!yQ0@Jwhjz2b3V_VBq^$Tw#PDsCW*^k(u+yY!JzAA^W#$kc-b*UUb=PbU-{xMlgMXzhohf$*SuKHG)uYhqz!jc}1xpa_vL!ZG%b z5zPM?Stnk0s_BoxV;Q{e&ibP#=-hF0kDs>PMqu^sv~lw@wg1JKh$Fb5HBWlDKJisO5VI%LIaeAoFwwN=NuWi<(iW2^ql0herqOm3e4dE##S z3Kv(tuPQrmW$k;Hab>;lfoN-T41p4O@CvP4L*JviJ*S4(bLvdIY{RW7YiS0$M zP=0S06;qHZF>7RTa~wLL1YM34ILKH(;+DcyU*^hKof5H?LRn6~B=$1{W=xQBwekIp z^f9t95d*~t&Zfc`G(;*Opg1!N58T4#v(rE=DrT+R;1vVT{~U&7 z@q+&Z#Mp1_&XVP&_3D3aGkglZ*W|UHUD3(D77+-zd($~TlkwxV3N|XKFcfVpGxh3N z`0_QDr*ni@S}{ZF7-a+K7O=@J)(CV=VN>NoO!wq6)|psE!GUqGr^#HEYmUzOP4sD( ztmp3uQ{A3tTb33$dAzzM2+#=IKpy$j|4j~926s9gUcpGbX&OYeRokuRFtrj<~M8j+u0Ar3;ayH zk^zxUG<-Gk)QKN%A^&-4l-;%qL%+IdK{u?CXA79 z2&$i&-U{G+Kt&B6IZc#T-tB);A!11CF3=F(`P_WRfZAn&f4X)gEFWwbo#OMt^XzZ+ zLAWmV@X1k-?!d0?fAk|=B~hS1>@G<>&={KE82%GN479*FdNfx)tj1| zZzStNR{=k&WODB7HZT??E;RrHaTh=-r&3#5OJ<8@5j4Y0d3e>&! zCTYs0<_|kGDL+UJS{M0Y`>|NY@Hvx0#xF&mK<{wIOM^HRmBe+kRRJxsMKirc9qhd` zj~tHf-wb0|vFV+B_1)(*x#78vWq$elDx@#wB^&5?xgREjZ(l6e=4z9BdO$Exia?$KPv8qxg9DHo4z14WiZ(}Y<* z=EzP(%EGc5P3_==JAn9X(?y|WJ7of6cW5}UA9i2Xy& zBwA>Ka_HlqTR{wOp~X8m@a)`S*{Jv6;f)r zbv%2f-6fe+N2W@^iM(_RGNj#I3)F0*&mk`>2X9aF-$C!J@#6(*Et@og7Pi}yEY&t`kTGm$a$dOiZxZjiO$fNIOAqxxKmKdWxdF3a+glY7cC``; z(Iio)(t3+OSRv<##AEM&FuN({$^=i~^*3iImZOPZWP2|(-$ zGoPge_uP}N(>}8?L;yx4R5m93_)+NpiXc%S2ze?f;xMSz{`iX(+Mb+)A9iTQ?7Y3I zm)Z*c7KY3sEfRjJhOaV-K+o7-^&!($Odc<|1x&CK7XD;T+5 zznnKa{CQ-2;QgQJW^WHad~>xzcpFs6rmSkmJ|_G-cKI^7nkeI2)G zPI@6UCGLtJROXUeN7zMiI~$VH5L!YT&yx#Da`depJkR#sE(do1uM=?2r}C~_51&+#ob^aMJ~Tsycs26GvMZuTpAMW~w4)g`vD z`x)2g6>8{h2Qu=^H_qpe7ksjXmr6R`_`GC1K4|SE=CwwMZ;78 zUe~pVOYm?u(Km&6E`$;2#NigFSwFm%`qZllUhDF>V3d!D6D{O{znA(h z61t#B*iBf2bIr4eQ#Xm~NPHgR)(2ZBiukm2!z1yujXy%eHUT6LLIV$(V z|GHjgsDj3%abWpyqd>Z@C5Y4+#V%6wO zE}_Jx3gtP{5|#$jppN2^Wz>wMr=s`S#uPUY>VDhor4d4omBIG<8@Sp2kdY+5A%5cz zpYkwcR`$tbhByN-fus>PZ4%rY`KKY+7Y$dj2pdgpRrKRu z6PENSVgZ1T+Q~$2iEkW#`oS1Le5@M>-J3_y z%}+VbnT+oq_b`J83@ZceMqaP%Y|9*GneTWMAm~u@Gjb+oGo#LurM*$|Ost@&RAh}B z#U1@814*r4XU4? zI#6pq{=jwdjnKs1>uhaRPJQ5a!wbfsyk1ma19D_dp{#oRek{zvhigs_Mxf7beDipf z!w;zpK=`8o4te99GcC{N-BsaH!`k{j?>xtYm&treZbTJ~ zV9a<{MOd!l=YSDyHMPMe`C2)1Qnt!B)4Z>jZ?m!Epy6?Knz$$br;eSgBlY9sGrMosXE2RG8Y+nZ*b{yUUiD#8+En-YnH0;ox-lMrMC{+ zWWd*2)WW2?YErhEB|}c<`0W$FiXV2=dX7*FLT+pCENWxU9A9>D9Y^lARf{-EjnG}C zr4NO82B@v(dYHtrA$#(f@ed^Kl_nP+1D+Mj)irjnyIaz9OwTE}YE$1|rO@2f4Cn?% zY@~|q{WtiX#GS(Pvz@z>?KDxv+X1`}w~%xgflcIU_p~lUS4U8VXvCYs*7brA`)FJT zJ77Ig#R()&%;JLV))DoD1jWFQG|L&oub5uJLR zf&_e`NhXpm8I6?%hdb%p;H%+3K&Dhs&HnqkV*s?6*4Joo5HSJp zy>l?F~!2l8SHT2MXrFAlcDEiP?h_ymmEBUJ*o%eLu71;dQl6xf! zzaBC@OWe2H)e~FAA};O0?jctvdAl@OhlG%%jfiFQ+O`*l11)X)RTUg&oLApHJD6ZR zd2)LFg(r~iX%``uST^&Ii}UQ~TgpAkf&|C*;Hb+7{ED*&a_H^wXK)|Zbn>S(lMs6b z!LNHce9;b46OVolcA0vA_}SjcP86+_H?(mkBPwdAzpA>+^QhOLXf@YGA5a@M`C8$$~2TCq4coO9{7!i-CfLV|DV2lt3v()qayZY>O54Ui%n+YUXrjt7K(cA!#vT z8Ai^g1%p&T?Wts`K8%q^;UuM-Jc`&!!8zB`F;(2M|Dxo z7NI+yNr74frc3Jn3}RzF65v*)ma9N)RzHLRh))ed1BI06VdCCnJfd;5m|}5LHyWW) zwAzMPN+W^XaCV9N6|xzOB6pn)FoHm+_U7%)MsS+)i)>KDX(uR>)rLf~YNj06Zx5Pr-a4X=&@Brw?gls?L#ZwtHWk(0Z>)**| zSFh1Y2MvtGumj|>tQ#Xlw61b|5AX1Yp(N9~OS_m(jA7-dzX`t9-p-Ga>aK?bEhFy{ZZAl!f30t9%|F3Om|M=G zkfvOSfMhM}p19*BT2v$f>or1hioFxl4phv5r~RfO6ct-uJxr{UA2e5VU#ZqKFS_UX zsBz+!$egr1P|AIPTL2?|Irlx@oc+955*kT&{jDW|5VR^U1Zr{(i3Ri!V}e_yR**eQ zG)EPUuyM2ieFG+06r%?JO*G{3xF0G2;Y>BjTj~y#e%CUwP1l-aYef*QK?*BPtN=S~RY$Bw?~N#TRh zcQ)n(^%&8yPFF*nsDxm3W5Tjz3m)~#Xj$0igG^o^bosZ;JuglU( zct?gactQ|m%*%PT1S`uAA)&=q7o9N+Xk2`ZlhmV<zfn`OJo5G)4ChrER#<2WEzoL#_irUOM_gwR6)X8~*p{P|{3gG-| z&hUwued-;Fk#kegoejXMihxc*VAZUI<>OD8FJabkFN>qw*`ey)Yo4v%+b)cdZI@@Z z>j;$<%}|>ag}+P18uTk~Y@+<*wtL+$u(|WdpF3lJ{y(O^GOWq=|9dcEbg9IcfS_QJ zQlr6pASxva3WE`XvPlg_cNwIT(l-V@LJ&rWqf0s_ATYYSpNso<{Ey>#%d1@{*L9xX z^ONywx6`ZSdw|z*tHkU;*jzFQEKLQOzP4=nP@y=Bcczn#D|Qwz#HSZOUE<_7_=^>? zzVmBVC$vZ)c119P?MD3U$EfW+SyJmj9=;o$-s6xh{J>1h4w&EuXntp8g={YdKQ*G(gKbIn2_}< zJ=ehxKp1G}x{ISg6bhrlanklzjEgk>inb~3ADHJTmUesvNKR)GKBy-?)MW?q^z?-x z`N9~walQ5~UD%&tz$>?uFZKe&b|pIjBoK=-YKbz#vR@f!)98UQ{^!eidFN2xi1rp& z>Iz1Bh>L=f&R^X9lAZZ;t2bi`qoc-}3SGj2FP8>eCJ;PHo=3ghGC#EIo67P`ZCB0! zYix4kh{SWAv~h!Q*NIqKYLpM{@+jbkMb1Bz?D?7Z(w=D1VY~*L=Lb*^ z{FitI=pQL(1%Eb~iFbNKWw|6I+g1P#IrR(k-VxK>&|mkdx81nQoKs+&xGZvb?*w z(xu6r*xDE~G=xXXM=KI@mNPtR+G4B*9u25(wNc(3_}?O$LZ2@K!W=+(s7L@cr1TB` z0tiRtzxS2Hrc`;eN(+=&jyo4oO~$hx8etg$C&`oh-5xo&u%{j0fK@CZ6~pG29qK$V z?JS{DS2GE(m=+@wa7I<@&BwPej#ku+yE{NeX1!`JD|_@<&dpcZ%eMB+@G2m~OR(}b zB17vx-&qvG7ZHSHoX>J!xwmt#x*b`3FIOhN{VT8KEA7_?fYwAaS&~A7G@`@)1nNGs zbXfCdOrovl{Q!w&8`GWhkYk~8x~J?dSnfB=g51Wsf}GJBSf2N}6uRiFkWjm(IGi7I zRG8=~nspG&=}g5w^xG)&T2I!JY6Bztpi{fY>6JWYc!|rJ*%u{OzM9-FK%184^m={g z1S!p=z*G?dAll?+I@r>=ikAZ?dKEXgf7i}iXT?A;d}2ubEhPMINb{AOaQn-`kOY+Z z09)*b7k_7Nv>JGFWbHiM`8W6R!-6Z)1^+(Nza+ZwIF&)TQIt+k+tg6MvX$nu)|-Ra z`eM@-ptA5U?~`#-o$dOh@3~jCRrmaJv|mBZr1aOamc$vf^78Zb;(3Rt!+az*|LIpJ zts$HtE09|s&Uq)Us8!{p1FzE`G@!e&$*)qr{UPmiFB!ten10F>N_(=$xB7Lvk{(Lx zt7zG(9HQ+#Ri$RJUe)93Z$KQuN9xmi8>$;aQ|Y{yfG>co*B^<{KFOkZD`biZV6=)p zt|tx|;|C+~235(6x2PGfZ!Y93KuZ$|d)Ycyt8$Yu&P9EL*`Pp@yU>iQt!5lAW#D=o z7Z5!7P=0J68J)j8H{tr@=ID+a404)(lMAJx`%0X-jRz(yWU#1sjN8pozH! z!nhZ}iC^AYcYRe6eHroocx&WR%Xd%=Goom4+6LCEHKGN{md}z0{dQF`ZK{S3*ZwmU z85XU&#^Vyc#6YJdbIxcDJJ}vXEa6lbgeI;w_n)QtJP>^2ALLi zpgVvRd&G{v~4BBk$Pd5 zkvLYF4LVlJ&|;tlW~A^*0MpwA)qmCL$_PBKHEoT>qMli#ckLD^WyPEgQQPUs z%h=^ZUFWUSZw}u+J<0r+$f0rCH`dH>D+`@HtW(pMjlS;w1#hN1bbsC7Vki3G#di%6 z37s~t4UwTa^Gkd+#SysrOlYIl{CLX^@rqG5Gjw%1Z;Q5yBg%IST|m#({LF+5=%+}z z!xw9p(wmumdGKWJq1Wr(VGi%M{qQI+drD;%~?dzWv#0;7}KXWt3UO!<4l!(!k zpXcS%e~VMN6-0S%=kpx{;@q>Z86dF;Dm&(0hW6xqkLnEP{bwduv1GX@A`#-y2xq zIVudt_6HX|ivs3z6gwq&fvPN4OdSe3ysiahXladfj$64E2IWetb>qRa<#A z5DDy^*8M%kL6OYNKj>%!LrctbX=z6~h0S2E!!+L21u?In1qFhP=lz=)Wo%Fq+XcuT ziDTUjC!us^AY+X2eBisX>tQubLJQ46mdwvxS+2-g8AU=zYmX}~cxk6n*<+7#L<_Jf z@P!oxh{k3}l}H7M-kEx0#PcC40Lix<9K-XWj@jy#@$AGJBCae*B6%5nZKAqIX!u=v zgH6q+55*_qn(wL#pBTjFNTlkH-?5qHxNngAWOywMEwYSAek`BLQV&jtp5405Wvu%^ zRHCf*Oou=m;{7X$qq#)KL>e0jrnB^Lg)w3a63~_%JjBQ^{(Z`K%s|)Brs}OiHt#qQ zl834!hmy}<=R>`(82Jc7vYq57g*8W5*;@<5)mD?b_P>3J-`yhILQUn#WP;Os1C*hZ zhzJU1s*vCaHdMtZ-ZjO9p+akQ^x)tFG!;81t*nWia!0mrBM6!tW-<$~=;U$zf1L+CCuCo-_mu`fu+ zdt3E!H#Qxv+zJo3vyR-oWjs*18-tT5*OnmzB@G`WN~)gYKknAhpv4%FKz?t-5Z88G zQdrt>GF%xS7oi{)ipnqzw^dp2J(($W`0ZTeBz!}*_h1P;M|6mxY!(@k*7RN3{hTOl zZC%J3ErSksCKzW}7~anOmrM^eof&J*GD-jy$Gd=itFE?|%_}cqp`t4Ak6+E(5aV67 zGD0!|6iM6RdGKT(JHq0y`TSU%8Tg~OrcquH^WW!9uK5A8aUivoE6MWy_i14;;ATAp zW)Eh%zNe7^7GY%#j`WOuKbEB*(EI|1v5wGau#BCLxjmbHf;a2@di9HMV3fkq$V4oz z?$qYVXTPB7!};{OtUUN#EJ>lLXa498Zzf^wR7fStE&u)DP zI+!g_{?^$|i<`&nty*H@DkV7C5t4W{WW83>utkb96~j?XDVL82X?8$frs3aDXsGWN zMU?(NxGt#cN3tKrekzW5^PTMzC-a1M-U-b-%kF0*vc<#0c>=>ue+3IGb6Hsq7uwJU+-(E z>}XU0b zX{hh)Bj3@~K%c3z!mat=$6uBB8X??C2P%kCiuHVgE1I+ggb~ z|M4Ut^VgsIFId{h*d0%VNH2Mgm3C8d?Y72hekl^xv;G_4xzF@8mWM)%ngK)w#jl9C z%VUQ211Puc)k{Q^_cai!?!Y%mLhD4SHWvOXUOox!EsQ3a3IY%Ahk zQ7x~o8K^-vtgknELmnfwdhgstGGVEhgv1*v9sq(a0{|W$dQ^l;%Q`w+ne-lwv_*`X zY&~??yS1Wn%AVY*bmKI8Y9_(&Fd-p%4=ArVOkC@WLni^Fohl!r%ITYk+do$qguM%^ z52DI(c@^%;J&HVTfvw}`S`^VMfkl>q!My?^B4u77BfEn<+(GuH1ptj$lqLTmW2!?8rhF8&oeTBZ z9$hKTDTF%7Oi9&q4JOZ3+(7Hs1%{r*nsII>^#@S-Y7*_9908Xf>mgM>iXd|f@2}kp z*#jX+RM9udD6=;nA}P|EsjS|Z=H;UCOp@T!tQo^fHrcSp?nWl(nUb4W0&FED%D+CG90kkf%&u3w~Mvv>|d=&gRdHll|G25rJz7V;#qA(1>!=1t%* zI__C8vwEoH^0T6mrQ;?1+0xu7ia)r9KB$I~-#MQYofW|H0^v8~a1ucR5(f{>IlGg6 z)8WwH{gXo#J-So4p*3Zrj3E6gp3cLl<9loK%t8>u=&AQRx2YlcD^~hTv^M~I3bUW z^V@V#TY{rg5(g3pu?>=VYNovH6tjZmyNt-zfAf$Y{j2C$z&aS6d-i7(G0{L%6~u&5 z^%tCfJzNL0R8d9iWd@C1rb3j{iw^OqHO3Rv!yNS{^TcEJx+b^F82f9p0H83tXluztr((r16xPyaaI^+kDSe4q54Tv)9wwKP#4 zwq0~UPmD&?1%#Yjxud-bW*4oY5v*6ErlL@_)ClD=TJ>zL+EhHbp$|XkGI{GK>leZhQeh>vMQvj#Q8H;O7(jt>{ID!o2`8c z{ahyARnT*kj@bKPo@bF~`s1CRFXv5c-0n$XFa(P5I+_uj2%cd}N;w-+B)wQ!q`1Lq zXX)`~OHal%3Mv&x0alS>sq*^JWN#tpI@}HHXSVr(v!Qac6MK5sFu_0RA* zg4!Q0ZWt9u1riJ;GTP}bEM0gpz+ZOq+`JGSLnz8oe0+5V@$ zP)oJh9`ap!C6s^N3s}?Y(^ZGb(|0PH!Z=08Zp7w=?PF|SS$Qia>JG@6gS8RvPtAAV zZGb3f_`R;daq|4pzRCGc<(gaFRrQ^O+MTbYd6k0(()qF5S@&F@NMThYq?}o%NC6Pf z*9Z7#Jl5;A568{yDB#P=1m8XO8_HEx^B#j2)elkpGq$yGNgCEX^~6s1rj|&*5wMFM z`v(^*i|KzQQNP@u2+PpN$9dpb-&!@PK!J_ml`vK3-;j^b8Ha&g8$0|*)2tstlOJ*~ z&DbnKGevSiy~mSMlVh)02m>JX!ff+nt!6X!7WOUI8UkM~1RJ8nuc$y>2=L0b7GKUF zCZ*&(``KMXR{q*j3r_al(miFzXxDt%K;{)Xj@hA1zMEV?&EYk>Kb;qVP$R|W#V9oV zJE3UvJD^r5uP80tl%a@_pPi19;JY*{)zJL%U zBY!X_kk3=W>`cRc6q^LBD3EgWn+K;GOUIPMp_07JL7(d~qmxSY&ggvjoci0#jg^39jcs?ld=u{`fh6@q?L;f^LwzBAPj$-4t1a9JD;`_SakpTc}6ipv8P zrZb(m9B7K3)3={38KRb@R%&j*a3r`m{P$?pup7{r=RZvCYnoL>1cpdQOPLerzVTHh zJ6QQ&wp_U-H;ivyBlA6t_d7B-F z(+dUC7>MW@a3cL3VGWHQ+CF3uuev5N$DH&3bJDEJo_$*NOB0BCIS6bQIaNHGV7|l9 zi$qt;{fp#Dzyly)O?3?jb{&+1W!gC`28rX+^E77;z!BfGoLK%^Raa}F!0xlZ{PO&1 z;6W-yZ4T%QWyzhR+h&{Z=LB3LEhX&c1!a#P){nBt9v*OMuL7~uQnn~5#ON>9JXn&a zkw!9qU)v8lf&5Pz(R%i~Y_^(Tv@_Hk6Wd~+=O?xwz>D+r4xtP+aol136pvOOQ7+AGehlba9&qWYb zA9-DdZ6niIW8i1J2LQF9+>oW6kr}Ab{p9S|01BLi>2JQWjnX;;(shp^S+A^G%Vw=90rmf7ez;= zStU!z5IISj)UL|p%K^fln4R#YF5&>&t=T+rvXOLULT$@*zr-Iifa;dVnPsq2)I+ctTQDyZX{ zEzVNPjBnYsi7+S|#BPNI%FU!V%fS3{UV|y&FtQnyzF&Mg5b33?*3^x#-|0$vFthm9 z+US0j^Rt;7KJ`tQ0a5i-+d@rzG~+z?6WPP8N_oM=DR^+E{-YtsRJ(rBS0WKlp4Hcz zy=kO?`k1*Ig6bzni%b~Wh-m@&$tS-g4%MnN)Dq$RKqJ6AX82Bo(1nMNnsN5x;vP}> zG7ko^FrNeJtt&aJ7VTSsx3fU@=#tyHo9YNi@&qS=e?J+R9;xRcdo?sa-PTOnv0*dk zE;6Fiq<_)>ME88B$261={2WJ>>_j#2SWJD{OKScTYgfWcso-U zF#XM&icwJE;fx8icCzm{o8Rg1&s{}|%XlBdarRLPHC=J7Q^_;+22IYu1mt_gk8wDI zU{(cA?PVTwKHg#TbKkJNTdV5)0g;7h3r2v*LBrPQewdsU zhs>=4t1g9)pHMd&N62%4dD#=Gl}&J@Jxf=$G4= zS+-j)W+yW$5i>Pl6J_1Ps|&^o>aHB?zpac1mQ*#e9q(HGxV;&L0;luGIK}`T@V^|0 z@YDxB9;WX-(O6683tFvHYm!zbznBHX`cM!we!`)6Q1#oi4P#MIx#NA#-QO}y64g! zJMC7+(rSr)_HG(E$RyZ%{qW+Oq)Q^lZTKh!!nX9Av}yX`m3na& z;Ok`xU=Fx1qI!{8Qrb@)z67SH0#`u=7qTnm@x1~mAX*qEQ6Z4_g+d4&<&}- z5_~a@Z;Nq!w=jm$y}C@U(*jog_%vsiSUYQ45iae9=0aLYSIc2C?p}1xrz)9w5ql zX3~0Nuq%~qJ=M9;un9^*!TMIh(1U0v*xz32x1Gx_GtvHFD=HYWwwxXYYG(Y8R~+D! z>kVOcZ3ys)yr9gIvM#}c1M`DwS&Xd^?yGg^tj17^?(wl;t zuDt=NGkUwXu}YzFuFJ=ZWL28v{l3J2b_g?~jJb?~?l@mK8UmYrA&dtni^t%0mOA7z zv&aLL{xP^WI5>d$|AB~?d@BNqm}0qy7by|D6cL-iKmFRyyo49O>KK`{^Atl6ZK+Dw^e5N-9VELQ7xjO zHUR+9IpI|Q08vPO8x`A91o^Tm!NaWQGjk${7AG8w_BdG8F=TbJ7ykFtppCG_W6>VI z5hlGt(>u`DvVU%8HgyMjFsL>Y%^i)GSPH|qw)3Up2HIXMFj46Rxelu~igsMrd&F6{ zL`4(tgku_A6we(JGTYGd@3r~!MqA*kNs#FMtN0~LoAQ;btVZ)?9s2W^Urh{*KX6ng z&%%hnsMCTZf+7Hs8FZJL z*#*^PVbti+?&A#%)o?oKP-?(GyQEnxU!flqKx2P88Sz;>mif+`{?{v`3b>5WHt}_b zDKFb?98!LWTHK~mhx<=)bm&lFErfRIS?JG*}cT#Rccnw zGFFB}xk(VaU~kd=_M@|Sj~Y#h7IT5WlJk_}1TOsRcM%NPWea8_gKvw5;(fQc+IKSD zRHu!|LpoaIvC9vV2}l;9=pvaVn>r!`%~;i8ylbmlzZjKqX?Gd+jhQ(u9Z`TfyxYbH zEh2TL1{`k3aW5JK*2oc6z0=L4@>W)JK?~K&4nr9xS84&N`2{}p*M?57&;r_uiZ_&N<`FPPm=;Q%$ZXLtA?B@OHn2Q*8 zKALX!2SG_0N)KH$0{TwPQ2kL%HI0-wOe4iM?@?}N;$66^e#4impSF00(#BhNS3JY5 ziG_URJ3_C!7! z%t*!l=2%O1&BWOmwuMOcMn_n>vygAK-Rb&-Zc%dimGK)WXq#lipMW?qk+ z&{VzN=O-_Lo!eH_1w=;&MPkb6t_+Hz_y;-e*=#sMYdwATl~fv9eEcXiip;Z(XEUSpX{j7hB7Gd%iBda) z9SQ<{#cQB_$ezUnSHVaw$Se}&QUzK z0dDq0oss~W_Cz9mwElKkZ1+5LY^{g^f=K@=j9i56%z1(|Lzo2wW_lIsvt_Vxv)3`= zwiEY^4^n6iP8BA7u;!IszJs#o+f;nAe!5Y$mOtfp{{>i&CWTFLq4c>0weu5%#JTh0 zki+F|h1xd3FaSw_NV3c@BWv2nDB21UOO!ODm+u8f=Ee2c;w1KV2i=#yTw=6a8S@^f z>^0k_pdo6}3$%N4Dek^-ySKj(=X^=FtSU+6li#_@$-{>t$&0+MwTf>1LieY(OuSZX z#jvrV#f!D!O>%+ZAA%o>6sv0EYbvia#+T)-U$Y&s;MWw-Ktx!j`C9TO>=C|EaFz@W zr1oI5$BXrNypq|Aa(WC`O3kP#`M+LG&D~uh)^=AN*o{km7i~IH)u069WY4oa0}*7K z2zpQ!d<4mGlb7EX)H^tQBU@y2VLR9ASsjs{r&Z;YFWqe?PI}0LnsN1J2-AgW)5?J! z*vqf)o==!7pXVaKqOX=JHnd3i!DSuaV05-yBYMz!aM|w*)j9xYL}Pz+H=dPu8)#JG z-rb&{=PB)&n*@`hs}4Q@ff*H%>krM3es4{J&S4vzL+9yryFW$KDKgg{U(JNi!j;(P zO1ZoD3*wM$^(ZRN zg7i=I_lG7zm6v(O6f;oNjGZ%tfM9*$zzV{Rdj5MtU&7ZYiid=KsklZoNpuSQX8T&d zPcuHLrRr-o>9pn}=Chh895LpfC zZfd3U&hrnz&C)@r>S&Bzrj-*uF=c|KfgP1M(tr$>@oKc2WC)B7Y$m)#=(Rxpmw$n+ z3HvvFY9`a$0E#aiPdQ3n8Xrlqug-rmLg9uQ8q7%P`O{nQx3q?CBoXQ(dtUiO?ML(Hd7K9IF4*ew2?mGS2E=_5E@QzE}B; zhauZ^zamz86$KGd-cb5@`F_griiUP(Q`yk0^Fan?VDx@frCG=1iWvG1s{v-fZuN0W zaTb#w4#v*9v}?nwOb%3!fED~>`bTWb*0p2}azA`?;c|Vns(|W((dPtbDuJxR7M=wc z#|BRvz4K}ksUnyi)5)QeJ6Ww$GHRQZmhAht=w=>^g3M|&VbuJi%!%V;G=B)w%Xl_W z?&AtA;P0a(W3YdI004S~A(>uAw4C*wW5)R;uiT3+T|*Q)L0lkQK*^^@650jsbiVAj zEw&PQx-dwmOwe5q7%8{c*;jJjR{e99Rn);=8%bM+MmECBoL+eVHi^yj2_hoeUS}*RiRhe!-}i*AaD|)JeKa- zNUGNz?bkZEf3j13Ez2W=8T}g$hrDOlwFeTy^5`lSUWjnqcT`x1Q~0;=0YM%^*NV9@ zwWR#pQsGQ;61u-q8^D{@X=C-~2PNHKYn@$|Bz0asTfRmVB|aIph(Pdk9M4FDX$0>3 zw;c!TRym2%D#`)5BxrtA_vaKJWT7(uuX(wWt7o3g^eU{9%fZ$K+^Q88J<_&>4UIHC zi4QIFWRl!)Cl9&|&fjO_qo%RwsZCKYUow^-0t{WvJsIG1N40!#@?P-8jFIfRGzOF# zWHuSUQ4ien$!IdYKE-b>Qt;u@o!{S-x4E&8fGMM8=XJg*!^H&V+L_!R_tV)qokU>~ z)FTnqTh{C6~Zd?|Ef@ZiFQJvw;sm$R;7B9b0T#}hVz=Qa-a z25_rrJ!htcMzxw7KCM*2JVx`450tZF;G3O*fGPY-%NOSepj^kTdF?*&P2Z|%_^cfh z#b5Q3Q8NOa?Yq&Z8%`a5zBCL=p!d+#GS`Xw_+JHwSnQeM%IL1#3&%=F=Po1+leKKU zoi08FzlkgjR40bJSOo4W80VC02sBmSsuA`77bh1SUWPBG4&(xyP`K;)QI}|f+A`|EA6EToXv0MQ@1-yAx=aIUjd=JHQRQ^d z_U;#;=@$RTP%YcH#ieuMH|nV_`3uR z{i*9UjAqbvd+78fyOpYE#Hji}E+0DX5zV52C;{V?p2D+~!$O3zQYkjz5+mGS{E5h> zmSOuqLBOL_c(*Ocl9TFzoBGHGocSYXYT#FfM&c>vPeb!{Ov>G@r<`IGA+F0d$q_C_ zVa7DIpRsF|#GVJ7LFku{@j2iqLJ7Zx&b+Rk8c?-sD_X4wO+=YxszV;6%h-MCR-^@n zBDFfroDJwFgSt%cZ_@(TmaqN z@~s>|Eo|FS764XLTW}0YcM_~o538)F#KUd;^{rB|JMA+@I9Z^S#I{%82N-~XyTXv- zr8@`@-bzdU^OLBR^YbdR;Wr%|-V=MUKgQ`@H&G46aTm2A2}NpfsJ!fVVBUi|EGUK1 zMS7|kV&*40n!m+UZ&5ap=*U+;6O8+_AQo7)t* z5hRdtXIE^>QeNk}3*%PqXx1|=RiTC~VmBEUYY54K9t4A2PRDGQpYowM0rO^l-s9Ig zAylU~IT%~VKWZo!`-2a0LY;&2@S`LSbJ>#-4l3_8FjTCHy?HP|CCrsw@;5%RE^nDQ zxz@yEZD=f@q87M2L^gX8H>AU#Eg?@!`S!76{iK>EIkSpJ+I_H?hKpP56+ZNhRCfI^kcMV-6+T@Iu#^StSvv zXn{X{0nOQ77CPG7%SYUw;7*5W{olKHUDu!Z#btS3MPE}+-v+7Pk~1z1;_wO6R&AP> zCGcdS*+7Jp^{SIpF`f zRj$lWwLswhA;C=jA&`0W?}K0_=Zmm}p`4BAv%AX6w9;9!4{22_5A9NZq z`G-coHMp5Y+qUfyH%nOr0*%5|0>WfLRk+1#F0jG!m0brUuELdYczeT)dV7 zLgyh2Lu}VlfMDQk3z&aHG4<8($MWqQK=3nVXz!-VdDj`VY9q?Ka?fWGAS=Xbc7Ctb ztoy95U9>x{0hN%nZa_6q%i409sTXM!C^GB1*a2urc(bG-9I&5157l z6F^Jl5#-J-7v5zoAF!r;N4;S%yB~f`&IZzRuiSzQxWMJiLQ>)Wkge#j0VLM^CcleE z*ue#c)9XKbo!13zDfLZzW?71xR6W-E5;~wW5FU^=4`A~LxS=Wg_^PBYFVWd9n%>6 z<|P;9H_ZcmbFMO5ph$Yyhyoz~Zh|{tr>;i=t6>=Sqld=`cUrBDs0DxUDFkF6#1iC=r}t7#$z+6sC9< z4(MzQRL0arUZ-d}RbJ<&9N9LBC3N1YqTklzjN7xvX0nm!Gd|zS%?iAbst_@n)abIX zfgbz<&UX!bL7?8IE6JsVjP_;Ib?9eH%{+R>C!KvWallrJ;6d4b zc_f?jhXu2BZ(Fvr#uEEqa@spopqcFKh)vMr!&>NBF=U&(@h z`6-E~dHXXguCa$zvLf`kV(}40^dvlpns#c6Xl@eM*ro+!dK^Bj=%nVTGvI_al||s8 zen469u}7S+3YzyShK|DZ&o5)P5vOhZz;|n_^q>m6rb)p0Q;8UAeW8B8aCr1Li=*KJ z>lI1n3+P6QlTI9n)}U zYtMbetE+NKy=cPe#$`QvRzeRh6O_OB8nu*^tA+t*8!vohBaQw__mggK?gY3z9XG(3 z<}cC#E9-vCVI!QlwL+{n3a~z!pkXlct{QaZ7sQ)P=`CTidK@PG&R1mj8D)Cyza<&f z*UuAqRkDbN=Nk&| zl3&wOQh{86EMkBCwkOF+l`KxtFv-IqA^-@g5xA>1-YlGfQ-0ln)p`5Y2S*(j(6zMA;vt__Kz#G(r01lwXXVdsq1)=8 zqoJQ`e@@rjSk_w@#Hz)2ki*4uKMCIpiLUEgq}k)=TYR5kx6ZR3j>x%Yr+HsJo+usn z73YOai(Fy-4eRi99vmJ%YdGJ>GuPDs)}vhESDjPSdgeZwL;BCo<2{sQ%C67na78`1 znNBY!+xr#eQZgo5#Wpv+c{G8L{eA`NE}-Gzds)}ltkB6u-EVcu{SvqRm)o(5IeS7k z-q79j56YM!r;X5GN>cev0k(5T5?y7Mqfpsoz0#qw+K>DHFjfYJD8Ez>E{|2GDi41D z!?qgkC=RBYG2k&zZxKfv^CWVmN5}9-6Nw6tR{=UK{EB~cL@Jos!a{-=#VnrNWjbqe{`+vULC+vp{eEmZ z;2UqHU}l#riS$*QhAX21odxW9!g-y|diw__px-wuAS(TIG@W!xsylXbQ`vo@Qf9L3 z={+mRH%h@j91?weP+)&%CATQ+MtgF{9Dudw^&iB|U#tH_Liu1=k zwUG6C&MhN5-wn+b)XRk4oLCg-*o_;s1ILqzb3|L=TjaZrwGg%2?BXNeKMC-Ed6YVr zQrcz%5whRWbf&94P-9HSMxKwHYMnn`!i-c2=q(5qQU-17Ghv^628&yBUbD*8NwInu zDRDCdGEJ3UPW1`U`OuS!z`qX*(NLxDF~gLM5Go*5ad=q^<)~q9mDuBb5W?ny2#Lck zd%$GYNLmoBI<#QdKan7Q>=RD7DJ?)DN!8{}j<&MF|35keSVL7o3&G{^9kys8M+lF4 zn4TW`uS&BfY^xJ+T*5E|uBmQ*j3f4t<7_~*K+Okeo9fDrr}@sNN&7yN`*)pj9H8jn z=)3$M>jvk-Rq%ZdjSj~@38nkEt%AvbQQLPcts9j=K50tE=7-aW&b8;ORIqKOZR2Od zOqJalOTc6W#51R#xDr?f#LYAGC>g4`o*war7Hg+B0iKz%C0-L?-@lraE74SmjE+`s z5dSXcPoI&|&b~Kb2zihMr|S%1_qjr;3LwozK$*IFj{p_WL(Z+|7=e7e-L^`&T*_N0 zhVA8`%1`~sYjJH=P-!_S>@h?@YlAjc#^Al! zqtd3B-k9R2c>hek|AzaP^R3BrKT=h(_DN%Kx%2|R&VsnD5WwV7fN!D<<!z=Ytpia#wQiJdfx0m)I5XX72q7dc0=HEsez zYR&g$O%BD2m1T^+hrO$Tw%k4B{plO;;5`FPpiK>EKh8L`%1$=1{J$)K%1_4=QfDUa zZ&~`?NUUiL)6&Nem$G`^;wLUMA|%jz`n5&=hQO4<$!>!N(FL}C<~>znng(*e^3CUs z2v;e%jaEt-#A;XGLujsByDr_RY1g;JaXN3CHv}+Y?FTe>;RNRWY^{mRgx(3bX%gTMz2T`Jm8DLiAca5S}t}TMGuAVG%8b9ew#Z;NQWP__CjkH08T&v z)Xp{J#w2qf1>nahL-Sq~tO{z90qnU07Le-zAK`J;>8uo(f#c;D=(y!+d4Wo>Cexyk zVWXMV(1Vp5!q+BL4yhHT=Ly@u2C-brwnfcW#ji@6bzHEfF@d@3K;}MZAbRW!7MLh^ zc$Tw$o_FQE=V#8>Vbh0Nc%E6+F28g2e6%q z6%(%;Ij@2KDZml5oB=i|%!zz7l3hlS-;`RIB2>$O05o~oo`TUTj*gcS(GG~}4J-7Y1DzE{li4^9~Grr2OFW30*q0l6xAjLY|8IKVm#iSG++AYv+%m;tFywjjW?vy zD#F?Lix&I0EIFmj=UHvr0%0y1t$0*GSLOv>#8}Oxjr|b;hc!oeKNoau5SqJw$$ILM z3YcBhf{FE3EC^i9g_cwccAv+oz;hxF%Ji%FyQRbez{jsRkgJ%CkSohi^|IxOH__F& zC7V@ge||ieW%*{ojO!pT`3O)iJ)svI>Eyg8S-3RY_j-W_C9$LffgFXfuC^E2hp^hA zX5xBYqtewFSjC~}v(F5A0~FyP3TB0CINqWxTSgg~oqB($7lxF5(V>cs8(0STippoZ zbhN-=3jFfim5eN+@o*txSK%VLiB0TnzN>70L<-;s?m`KoyQijE`G7Eu)}Maod}M_~Eo)SlQ|9r{lMG(9|e)WtrOjCnHJ|6f#{WfiQM^3>v2^}1Ta z&J#^^b#{v9lge)G9mPUN>D2gK@0R>|q?^HC7!=cKzHOTi7Y9O=E+0jY{IJD@Kr9u2 zm^bB2)pz*+v8{)ZEB7HV${>k$Hq?S{k~Cor5dv{mNS5Bcj+p}U0{#R6lm)W>ngCc~ z`{(KSe2=||CK^9Fs!{Ccxr#QgxO&`0L%Opyv)BF#oJW$^ zk8jT}`6!ipJ;SdHbW^ZZ384KR0C1Oo=Ip63#$AP(`h&h1PUUT7ah8$U22E0Q@z>kG z(lgjh8=QU2_@UDF z$_ohd5r{rO)kHf0Y(nmKmNX~1TL8dVF7$&bI6Qo}m4iJIB_bud3v4YMGQbT}5>3bU z+N7U?Ia8yT6&@V)Vn%NvLkD=C07E<))_?LJY^=Be=;K4ve%crXUHK!SID4lHtK?#= zI4;6V`qi@8yEclP_%v?XWc3`UVVtM@Mbuhk^kCakB%$pW3x?l9;2Q&5!PQJW- zkDH0X&3UFTPxNU;cF70WD7(zci*U<4SOzM{?5or0b4S7Sa(W1+ahXi&DwB>urks7o zBimeO3F<+mxs1-%B1X-Rh;C_L|iOA6BgXhVn4QlDX1)rJ;%8&jM7oB6g)7f>9 zq*GAnCDFlV5dJ`-Hp70lLTlA-8{Kw+c`IuN}ycOpg1+GD_ATZT`XraWOj4U8j&AKtP?BZXY29jE` z1Hn}G1Mp6Vx1GsV?CzSM035R~!Z*BQ)?qzLTxztWht%R`>c` zvAR)u`>%esXA}YpqOOpml4(s+BffgPO2=#eySUNr63X- z_ZYi%6hdQFuH}sIx2OeXLTZ8L5k=*Yu8I{o!_-7+R&mWm&sMhJjeJ_tyBI%fPDy`; zjLgWG)Cy7M?SPnI3h%&w$p4~c)4QrzGYW=&Uvwo+^JooOUlc+7@|eb#FZHviZt(o4 zbT|wozHk#9&PDYd0y)oMI^bd!HPyf?a1HzWyUJG*<4baP{l7eQpcXXO5qkRv~080bJH2uhJR~y0oA52wTL%! z)(xO8ul(D(#9tBNDmoE{jeK2%9uzC=E_$c8p+8uWz zm~l>dIL?)zXooBMl*+KhPE!(zdwB$8wc8NHv6Q*^TPEbZE)eP z=%_gU4d@)q-OgHvU-ozYr0Q$SF6wiYw*T9(VMVx(lx<$?UI4ZqC8@Oi-8&PdR!1ky zHCL(xkY~!O*H9t}o?o8;y3cJr&dWf8kV=v;2155~XM7tg1rkYaxE#m^9g>qR}CU#2D%>@AYI=2 zS=f;uc3JPYZ8$p@E7$LDktu3nmD-sa#zozX@Z26#fOGj`1}sZg+3rO-dQs-REAqfL z^{^(0`9!L|)q9sm4E5!bci=g0;8&`$2F_t>oRF&yu~L}M4!lZ zM={+SQU=z-*R|Aql)=<{>r=YvS*Vs<&s*8~=T)}o{T+eBpBL}}CQ5HEIgR31XM(hW zN(Y5xaHLDYB9LT%SNT+SFm8kEa+xN|@;lJ=Dxc*+%^{%i`l>XSiR=(ymh~k__*pKN zl^vNT3?ryz&d~DB8=oUy2sfbO6KcnbHxnfb1FM>zVk>9qdf=5FM{Q}(f&{6z*>C<$1?TfHR2DWa%9rn90 zQrC}`hbVACn&4#rr%k@Z2AQw|W;>Ms#9G+MO|%l(#5I(+|}MfS{n+`r(R z&Fqg)Md@FK*RI9i-fq}PJ|T=B`?L(3le~yNPxjU3bp4L{6I!};_E(PfkGO7~^p`rc z@Tgtv`IFwkb~IO{%xi8EZ{_((a_U82_4^zwCfXqM7527lg6fihhKO-TDlGX$$1mLk z{{+wWU+$YtT;E&;ftwB!s3hK#{PJhuk^RW+OXB!t6TEieJL&wdD$D36k$+n9b%tm! zEf}-*XcdWf14)^;x?Br8AJ@qMa#!&T4%$l)ni2PIbx@8ZI_G$T2D@BDg9~#_#XqQG zN25N%m_fnvVzP(!XUm>MOI=4bH!MECa=7|L+{mIz(A#oT%)K91#wMQW=#!PDpV`oRx95KGrEx*`dffgb*F-P{t+WkSMbE zp7neCe7?Vb_~RZAkB9fY$LsZcJ;%w#Ob*oJ(hXs*Bbps9b+{#mOw6gYis*)6j6y1vT(#1~^Ut&i|l&t0^wWcGGvnck18 z!Nw(ggUb7#h=wDR-UiRzr=FG%Jm*C>rFnf{eBTw~l;`QVlWkH^^Yz%9Q}=pA2Iibx z)TNh?6{mn3V6aSF)KNOeLdgOAe3nkCIAPpb5T`we0%z+QJBDb>=E*g<3+`w zjwx;n?Mb%nq_||`FnjetA!d&LHbIL*`NzgDuM2IKu`93mAwvhh>X+!o-p_h42~(Bw zAs)@{0AGz6xmO9xy%u{vaRIjnP9vF7cV?$<`$G%$k}!)9Perj8k}3)aM+|HQgI*;^ z#L4VsnW=#*xA|40jeRK4eKOm2MdsRBBq^_M;&a`D=ww>D8r5c% zR`_-m#-+#Hdhh4i!2Ayf`1)(q=owQV*n zksZ-lxfgj)QiU>0_afPWoIbkOBA+w4CRy$-sy~YT0ae;3-qoQTbK4yDoTN~k>zREW z6n^v|sjdK@Obc1kJyeOGYXDY@XLj0+7NB!D4{-Xb%NUWrU4rlT5R{sfd;{Di#NWHj)j#U^qzIMzUe>nQoo5lffc00+FHzfzCALW$$4eXVWqFA z8V%I73Ik3I$!f3j9LycbfjBd<(oH8N`1WZJU1hPSnqi@IS2vwQJa)LRD&Bc@1gw9o+BKq) z7|~Fjkr(1WGT6^4ihO_o&M1pG{~4Ubqik)sW^TAeG&R@up83Rux!HfUa4#f}2=4hS z#@^3F=H^{TYZd_uGC0QbT@%s;-6;(J3~x2EO(<5$*zX@z%JZ0)4hQ`<8)*GtVj*^R zt(S#Yh4`9bY44NHVu2%oVt2njRg{QYyhyBa1|~rS{g*Y9d~wIQY9{eHboBBy?E)~A z{F~!CcTBU5O@5p1EWnWmf`APe?a_&z$;$wVB!ga0u4~o^o^SIkQLs&HDn*&N-3eLr zXHqDMOA1IO>xS!=Y6q*ceq=_L6$=h=8^@1INjv!j3?VK9;`~rBrmd{JIOZB3RM;O% zU-dOCO1b0=pM`!qUw@hJM3=tV(KrYH#3;z6wL7QjezVPyred|BL*LH_9b6`hlYqv8 zImKX3-h4O&Ovn4UfcxUSbS)&h0vJ1!9KPpb6+R>JdN#{7znL{X_Sx<8G}G^(-~5TT zqvbe-z*3Rlzo|$q@=yyiQJB&nN=qW;BTX(CCbt!Sd|TyHR`o-F3qLHY4?S*W3QViw z_o5l%Tvhz&#ceOtl-eeDg742d`OkCq`w)rGmL-}fm};Tv->YVvMcxiCpWNftvoXwG z4|X2?I2cgc#u$Q*d}4WZGr0@-2gH-g`We}Br`~M+X`d%W=Jep8fqO+7dHqH;9?FFa_FvgX$|4>ZQKB}+SBre#YE>! zVN=r$Ir@TNJq&D{vsKdjfdsTmfs>z5CqPpNJQKSN68#J_>h+=OLFzg~Ec9!mGQj={H zSePug>orAncQwW~SB1_-D-Jfefl}Kqxb5sfI$oJ+_eJ^ci!WnOv#}Eguez2jTZVLJ z=mTVm=c89NjV5B3Fj0vFL<9e=2b=$@CzfJ*^UMu4hin@j<(cpMpyMwE9^CT{-f`uP z3|PD#@5*$#y}GMWS;`;RVI4ttke6`YSWMi>riFdbY_Kq-Tx8Zt`HW+q?YE3FX@>;^ z7Pcvt<5$)!UehIPwwE`(h4O?)p1<;I1;!8#tq?M%dCB{Um*#0TzkP1s# z4Da6eF7p)UmIMAH<{ImT9aHuYgE0e@roD=hTcBvZ4n`P7YX~23p@Z9 zM5k4nRujIM2;JW8QeCtBPMp$MZy$1;r^o+`eBuKQ4io=O*jS&&Mi`G{XfvkzE7&q{ zkGW-e86;j*7|7@Bz3eVrGKwe8@?GP{)D7*R2F#|*nvuPDRfWHlXN;Pz^K<=lm^ z4^Cg5Yx#$m`!-!WgX)l2Q%YT}c^J4fad&*;X!5)iy!>$NKVC%Ua?tdWdFZD3x}9)! zH|4y@gRR;P8y{h~&UAH;Zg&!1S1O~Tf{}VB6SXu{bq;{1M78D2{foQ{eTcg3P-Z26 z)sJVesHmuv8DAm2Wg6da3AsfwrHLatJ#*WJ3ZQGr5`T;y)gz?yF*G|cKTOFtkTN?3=n59f^^79>LZBMfVT^l6dv1)U%DcU2nt$o6d7qe62dpG zrIvqh+${C9O?*x=XkX`dhcVtx5EEmh+kRZpQ7BmZ7Fh)bf6n z#P0XSXh^lMF7f;Nw|D94@)7K1kRy`=MtK1G@EdmqRcBQgWY-lcDnzZ1twRi^=a7*2|<+Q!(F|}Cl2rcV~ z?<~xe2A&YOGL+74Kt;q_CBD@q-ZUMw2j_uWY3H|DCA)O@AXQ)~- zY}ruW>izN$o_NG29$ zPTw;Y+)N4-xBDKTIZ^ZK?i!M^G&1h!Za?BQvyqtD_LAvzK{iJY))xC}*tP7Bs~@|J zI4<9oKz(&wJ_8AYV--%E)I-nr`{%+e3~2A-J;}G@&N={T+464RlDkX!SI(1af7{`A z#c@PwA8|IPE*6gcy^`XCEG6prC*wO^4FiBull5?^Zj`s_e#ll*I(cgI_u0_h8`~36 zymqwRz|VEB9ZHLvP1362t=l$h11$}RS@#3Pqamq=-PP`Ft;0pAr z@p*raED{9bMiYXfh%8W#Nw?Y@02*8v%s+kB?G~}n?GA20d%Kt=b`#mz$p;^Eev*DI~ z`8ET?x=q^Na3v!ez4o4--W5Cedh|UD&v0^oT3t!A@f%k5IPc$Zun&)PgA8B#x}$t2 z+g%b08oZza5O{g^{_ddDBg0^No-b;@XHs**=uh%p!RKPVC`r0GtyV{@cz#2{sK9e8 ztM!A89^29%)}+5&+Z`P{94(k%MU1U%Y;%PkF%Wi#d39*2gA*7ZRlYhez3ESsB~f;j zeDXJZ(zMf=b}^T{hrTy@YA<|z7&0~}6BH;DH(&A44^%RDG&AWDo4V5Gq(VI55zBEO z34etYpOZ(PowhP<33cI@BJK7-MWXB~ zv=$j#lB>CP%7-?}ryWzRW|`|qj|AgL_b|Y7T?1WIf>l-e@)7mwU+H-rV@>wov8MCa z(&{x6?JC9^ioL*M^8RVDw@?!SX(ves?MVwE8~UL>+Xw5@_H`=t{3mn>$$}mkE^T47 z9GF0o*Th0}UrcJ9ie~6ncY`{6>nzWJ&TW~$hZk;Y{Cv{$PtOLr9?P-$2iLfCHh9+X z%US6i&)-VfyPZoaO&b;0ij+uvyIkk!iw$jVP9sNPs8f=i#JZ|nGto^FwM{90d*k* zy5$x9V_mjs+vH-8KSh!kpOwolPMzfUl}n*K2EKCEO5RlULI}^>kyXg?8a8d+x>IKy z>A7&$gXgrGG04hrgqO#p61xx|7>p`Y-o3Rp0s`9PM#}j!KLmmIsrE&es_UCW{g}!Q z7bc;(@K(V0Iw7z4L$JU$!QjJ7U!kN=z5{hL(ZI~=KiY@4%MsBVfZ2d5FL{A4`+>cP zy;G}j#fZqA(R3=f7H9{5H$VIt^biliTm&lrdPu*O8_8DtW|Gf9`Vp$fMc0`rEUaKWJ`+K_VC#LCklay_{&3N z&#DOMaDWX?bT0bjLSl2$9oobe=O$g+A_DfF z`9(Y%{$wDpaK@di!$3c!)PSc?IJLE4$--Ed$Z~8iig_Z1GH+h_h*vG%)^&0BAR6_U zRMBUtent8Goz%gI|DdM>B@(Ue48Zt@yQ&2C!x`{=c^A~gmXZ#mPVH-NjPL=zhsx#@ z{jopS+rb-EzWn20N@e-S#w(T4o4au9GYtX<5sz`Ra;sRa5Ruymha~T3J-+tmT7p$vfbGaG9&+2KvG1y}fh`fm+vsbkr<|Za0N^0{c$*}fg}f!; z+1QTnOuQLz@R^nZdGzP2GN0C*|4qWoFM62UEoK{WzL~+P3)ZgGkqm6p6w&@!Gu3(zil%1vVY?ep#Pp58Wo)$8LH_W4vfHCN zqWM}k&P~5i(GJXJl~X=89(IXXUx)6p8scj4LHl2u;VN;>BCOT^~)WS0P45axU7LV%xdv+Cnp4Wb7P0r9P6 zjDN2&3D_U}+C4wdf>fgJd@SzCP8t_Z$N^(lU`4hD#)Ou_c>WkN#a5(I?L+Twk1jSM zLpC$PW=M{y_nO9^NFqJm?K!|bp0Px#SKxK+rza4Pb1tLz&ru)P!r zCJGYlW=b;V^7P9qGmIBvb|fI&-P~qXLc|k_<)IeX31^p+j-BAqV%PJPgK$hl5x?*B z3=}n$JiMD=sQN7UNgw}39RGmMY2330h~D|`z9G2@Ltb%hU7GP@?;HQZyN#zObE(>L zImuuTHV_gcp$myD9K*@hK?Aq`q=)W_soSyrR;=4e-ltFU4E@DD-LvidJ$ElJD(Sr_ zfl25XYH~1SaZpZ_9u*)HaV;;W*-Hv-QS)WSsU+CV{EzNKGjx8^?<%d0V4qP=?f!0B zZuPPf2NfbyU&c82=`XRje`mP-aJaurZ(9=tB(wd}BRM4SUs#x^n$PX@d~qccU)!0m zYS7PP=@_)-c-lp?Oj+d5^~OCtZ|@*G$G8#&9Re4V*E*oUDEBFZBY-uN{_qflUX3VU zqZ6|QsIyqd9yhd9?EO+^#FQ`EI~k(OtE=gogLy~3lLpI77GhIp1BNUSS+-0EEzw@# z^s6(HX&u5^g>{VLzRGK~Cxl!h`F1`zT_){X$1w4%H1q-6S~W68V}c&Cz!t>HWHd3&9OOR0~J>?izG=NyQuoq zS^wj+7!(vie%Zn}7&1C-U5}Wx)r{QWT>9(yUhk(;HglkaEos3uXzoU~RaQS|maBQh zEoOt}!z99MB`&4%GDh3EV~xeeqQCztu#vx+OX7sT9Tu%J7C zo@5gSred1WoWCf-v!08|xWaNJ`gE(-&9_w*JwKzh+~)=+ht)Wr{RT!#`%UkkKDUV= z(#M+!IRYjVGi%=ax7K3rDn%|XC+F$T%^XUwl9#Yv~e;%In9xwbQkZF{&L4XX@K|bK`T+=H48U0o>l0KextK(r{uSlCv z&ie1?J;MwQ%YN?$`u#VH?HhfRiEcfvf_rvNYla_uo=c%@1a!{#=`#bWBP^ZjFbEyN zaT>|=mbFR<(@=Wn|1netCN&Yie36xA|2^f;Tw!Ry_Sl@x;6u;h^E}ynV~~NoO6<9dICg(D=QS`@_z7w^kp zkdw>$WHCPeazY`TU7KLVEL1g5gR4byi<8O5Z_dceKzX&Ku=z%#HYkuIBoI-;Suv%g z>EKx8?G-7t4jN>c`U_z4sS;t4E4F?IYZ5$mSbiw-JkV`ViB;ssSI7D2&UyhGrJj2w zLb+>=qbc+{i2=HSHU+jE0uYK=bFeViS01DV} z*SIVbS5>WJ`~#k1PZ1hwi<3rsAqD^w%5#v*t8yY8U!!Bdz^pRScO^4`Vg?~Ex2xi+ zEU;K~WR%=1JNqLdO|vlzw+>TfM4DC4g@qG3t_w};^l)!(`L_ihvoo24`#$HH4j0oy z9vHLII8{rM-3tB4#Og>mj*h)9JPbsx3t9MNvUn%!zyX!mJsjpu;hB*KU$QtZ!(0u{ z*{q%ZfL@3q)*nW%-F%P|vjbtzg+0Tf%2{~=Y=M^tIGh+W|MmmjV9SY`4Hsd}H45NT zSv=LR^jIGvF1V5^=7rg|CD<|(_J!L>qK(TBS7gdOc^7I#Ot+bCg^apu@^x1U)DHE( z>vpkjKIt}V*iPnll!Pc5tIDFtRa+`#;u&}_tk#8c&k+nv~Ew^!E(=Fq#Dvg=|5b77rjNo-6q_>zPxv~d2tUFB&iF7f0|{eGM!dN>7woD8 z2b9%2igjwPJrWV*<|u+XCQoGMFZpS6NEEv%hN^h_U{S+%5HPHoh3GFv5`zqaIh#7( z5A=;e%bLu*&M+XwSV>>F`{IV=9CpRlcAtL%n zk6997qaNtI6D}pZ=%m%jgTB)%#pp+E%$W8x27U9$WoylGqTVs)sa17YHW@#4gYKbgiqSf(Bf| zcea0Ma66etgmNF$%B$-r@7Is)-WpBV-v0Z0?BSfWH<0U@x4hCS*qftq@w$LCp>wiRKNw1PlsUD{lnPOJvLhAA1T|3k+3vy3fnky< zS+?QxO6;lUPYOO)lACR1*V7rD^!>e^kILTE?JvNem-FMxK^wPDaU!{}E?lon^ePQl zftwB{a0+&M*%b`x`Q;VIj9w3~XkUoV4~}C8uPvdH5%FBT*P7{3`5W7L|9CPGH0}*x zTiwbybA!bbfa{b_4AFS~2*ZD_FFOx~v*qUyE9R846+Y7=fa1gw+I(RW1QtT$BN4dp zXs!|4MDCykuUh>hU4200KMAQE(GAQK?R~mHZtG=T7C9B2GJVniuizP^yFs~l_Gyka z_Lb+;O4{$4$?LVD`?YC**_-AXn%vsvi$Cl)oE^)y_j_2PUnqCh=OxerqYvKmeZI=e z)LWC}(F9!aT<4p@-c)%B^>=?g&8UcX7qfJny(kZGih(N6TD z{T1|r^-s}tQ}{_xlDrC!*phuff7$v$SQve{?0Jf~F@&Kr3MzWhLSDZpd)KNh;squD zYA~2EvG6fV?C{?!Ue);+FuA94?NlW3#yaoFXV}lOg5x?o^6%Qa@@`Tj8Q{}bfQ?}4 z6#<0k%k`wA2b8fc2BTkl8m$f6ownbJF?{y8gH2{@^%OvIWLUEfRga{&%mOW! zQcDsR(?TX1-p8w_p4m|y_Z{?zwIAAdAKP*_tUh3r3YG4hTCf!G)jb#x|Dg_{i_NGP zOuJSwUvZ$$6`H2HZ8gPihu!cA_HQ z3F5OfH%%ICp3oL7r z^t-1F*qVgRwM?nTRv$hev*0uj4rkE3QMdK|fPaFmHY>Y}wj zRKR^(|Kt0Z)1mX}A?s_8^;aGRFkDsaNjSs7Ph$ zn-JmZeUh(xAE&^=Z3x5rw@I#?o@}dmqBlDad?gftya&Ob*F@I!LBBnFpKc{Xy9I~a zbg_XWPn@)B#{*`qVH_X$;fp&o++v%P=J6B;Z=!G;cRf{6*rfs;&aP&~MuDO?4WT{i4%r zQPD`gHa2v;$sHNu_;-AUIicOctzU3~9D#BWtP@N3UGwk1{;~azFi4iL8MJ>w2oqBm z7%mf&erIe*EW}5#9abxahXP-cu-FAXnZ4(uUJQyam0oHU5WnItD6-pPMF#>}T5n(2 z4=aT+9~ycH7R=p_ihUt=Gv8JyJLG@pOn3X4yPRj7B&u(bL171+T9mob&y?<9E0X>d zi;|+fH`5~%O=Jh^9|5`?!tdC4VUB`fF?dY^41&$J6?W?pl9|MBx^vrqB}e+ltN1h; zCI_|5sTK`^4Ooaoolmpy4VB34vle|1k4QgN#T9@RHp90&r@R30svp~5i|HQ+71}&I z>I?R7Zv!fiZT$AP1kK(q^y98N*!^c+3F((Hxe-w>TCKua+{}nWFD1Z7l-DyELE_MjV zrt8^E*5;G*%%=%tIvDSH3X8CzO_6>kJ=1!JgZEkS$w1}Tdvo6f3|tkD!oLm4lfViH z6nN2!UpfJapzl$SM>Gkl>O*q)p^0^1?|mPMSnyS%HYm(nEKC3@bm-RR--*h;?1!!U z4W~Rm`hr!fJ+`9iQ=*X{a(A>XWzgLKP*4uYj)5QAHtZmXr3zbwLxdYW`$67QmBWR{ zV8Rr?ITH;z39MZ14k#oIeU*mlcI+F_R)R-Q`vAJx;DQr{s=d0)nZ0|oYSjxN;+XtW z;IkN=NDlz*(m00W{t7kiaumcLQzxKE##0ieK8{cPri?y*UXC~qJ2uy;2dX(^l!&b{ zNf?ZA7bjP*6q3qNx#!yUo|{8;$egAjVIKsAsSXJ#fS#D^u=FjFlVB{V( zAkQ2ax&SY!o%ltJjx~i@fR0IXf<7+3Jg`N3kLzY{V%ahaZYRNnmzsS3#L0mm${8FH zCJt7tk>4ji$VYD>QT#3w)4=tB*t6O|4jv7rxsz5i`-Dqf1+Va_kQl1Tgr_4g$QXH7 ze60)A!=jttszi-E%xXn7H1hvU{`npW2;}=xcXO2Hj!FF)pxCng{C30{2ieE8Y(&L3 zV0sz$4?Ft(YcP5C)kx9NrMoz6@gdzUZ{(;Q6?-an{g!Wyz(mk-X$u+P9*oV?&An>h zpP-$H-k5?QKT1@acSMg`eHLg9LNL|~x_NdvAI1x5>qH?3C<8+c^Ka1O+5}Ds*G`;A zBF4lq3Z9=HB$^)%_jLrO(@d$f5yqKSeFB$USOhz| z%&EGb7T8IwwHc*ZKY-%B_zB9#sZo(-$l>|V6eW= zv#&n3+wD9tHdN-VwB4nF*R2_?@X(#BC~-fLl~B0gx?{XkSPaDpu8%8imuJBA*-(>w z4Whm(?_DRcPAhx{F68CTlHzENhNl)rncZ zK70srizvvvzMhP(hPG7FnMl5v&V;?EyKE9RNql+?X<$-0sVwdzb7^bGK?tjjrHKVI zpW=|85r_Jssf#u_)2ON9ZZ?Pk-6MseQc`;ExjWZ}p+#N;Ca*$g{cSKTr?E0VOXMH^kRt-@~i6Dlw6Hc>`XK@ znWQa9MEN*ntq{?h&y)BFx<`aGrC5^h=W2g|Y(&`P>Z-N}?s2Rp8)ns2r<)9VX~N>> z8cL@%g@uBGW^_e{gAXP|#)8LTA{OHlZJ`HkY5RviIYRy0%zrlhJzO4ZoVQ)Jf)rHk z{`_A37Wu38h*}l8$3272?|Gndk@hTjbWs7Xob~5ot>w=5uv0(2DER9B`8xln92vn5 z?n$8|oxEpM;;De&fXI~*h0M$N1nf%F{{guaRrSi0JX6rA{I=48_9E02)miXayO}@2 zBE9;4|F#-->7~7Y72js3&R*tFMm5RB5ZeRi1}+U;a8#>f(3$%xJqHmcG;4}!>uCIR zFmrpft-Z=RPOEGp{7jZq*}}^nBnl|OID+XCKt9Z9SJP&4IA%B=hPsoPAnKD5e25bo zxcG)upj|n(a8qwJoKexC^??6kXV8>11Hx&rpVnJJGW%?j_3sX@ZHe%m%xx<1y0MoR z!OTnCHk+_WG#=e>p*EixCGHXTu9ZK$+bCkFJ;Q-@w3vlqDVGpK-?ha_Wii*m_nglGWmCE7f=Y+^+>?jHRf)#8 zFDUC_L}QtRs?&d3#bDrd!2Cx*J94$#K?Jnr2P8Waw-UCj#)(T9E^ze)IkIDnls_pmF8Vw)?VcB+RAnt6_yZwLX^6J}1 zbNMgpu>P$&Fq~JMYDx{1neRgc>~YVc^M%g`wufFG1-?prODdtaXgSE062#9ZH^a$S0>~<+-;w@Hfuc|4(~9$3KyM9uJTds#$5DoPmJ-(wE5MY zcv*o1o(-R>rl*_)>3VQox9R|MTCOxJBCcTgxooA zbtz_IbU9@ELHYlt_$&FRzTEi@Vva&T>$OetwH5yN7QIdd2*gYfh2y6MPfl|+oxtcZ zDG|00v*iuJ52l4{DAQSBMN=F7cGLPA^2~vlwV`tgKo7%5ocIY2H~iXP&*cM0_u{fZ zElCbeiGoNSw{nB@?;G$JgHp9vM~28Nk0i|>(HoR#0aD)0vLXe(l6-NNB(|2!) zUwMy07lbohk#uJWI{EhPW8+8W|GXMM!MqYleH8#GR2tdAZTx=SbpyjL%iaS&Tsoby z6{ZCp6RQU-rZY6O9(LB%EU!ZxMrz7*zYQp!ZoIkIE{A00cvCegDU!3Amn1t*z`aX{ zTo$pOhx3`(GmBrK-$6I^ai~(KM>f)MUx#o}3kQ=Q`d(L5whru(J?$THDDoOSwX;jlE-lpLF zt&Q;rjw!x{p{g^Itrd=KiLkvIcWKXfDF#oay&$x>@Q`&A>t{w9bJ6K7nJ-dFw0Cyt z{nYc!syukd9m=KBeS-oSnx2O#T#-nZz=iX%?+A%AdqtNCXK|Ln_HhC>kHY}WyHq7_I^FoJXK@1syN7Q|Ovon?3a%LpxtZEaU8Q{8 z^}Qz;Qc&DX_eUIm{Tp3`h6qL*SoHTxmTKm->_JY>z)-|^?FWMSl;82KbBdCb%b^&G z_hz#owOK*MO72w9h26;~vo4`qF5d#C zGt&yf>%FJDGk#NVkmQ$(&)CuXrrWC+ORfAuy-lVYVLNe0NoAyl z%k2NX01lNU{UInTbg$)DJQPydL|nz3y`Mu<3-mE#VR2<3lJE4|MG@JgJakndCYyDx z9N6|UH?}4x_*H7m#Ta2`9|)XQ>%^*d?t0S-9BXi$m8aT^=Um~Fe$3wdGaj`SM^W8i zNOWqT(aoXu0AtOZ{R*Fz)zzfX3!~mW8naKb51c|qeZF1WeY|;j2chzv=+U%0Scauv(CM z2b9bDUKw%wo{%mo{=mrGTlzYM(6R>;e4jZ?hHNR%aH3Ljbc27yY)fm934NRrEbsd${vtK9Ozo)gE!%dA4%13bNWVM! z5ya@O zZ9Ms-XUkm_h!BpRJNk$IcU25pubjFks=H}A6dPbX`>x4zcD&U-$5RB~XVPJ`b0s+B z`^&e7l_l-bg8tK2xJ`otaxo4wr}53vW5v0LNU6_G7tJQfJDz47e|_*qH13a;C6?}{ zB6K`x_IQ{g(MidP)raOKJ43vlUcXPcD1uB>ccT%tu-d%?_)gP?J{R{}=IED(zC%v% zVyy%5CVEj!n9%D-4U4Z!HT&Hd8XnuJHC_-;!Oczx64q!r~SUs-qbed<`Q*2Voc~4-^q{ECo=lA@t;Y+sa(bQ@?P>q) zIhUJDa_1^!MBuJ`(hbLz*jKwzMQzP1sL%^Eg#yhDOv2>36-XrNw>dv!wfig4?dQ&B zWazYmvv6@RpY#@PMbC4DKv)0tZ4D%5(NTu;WDevUHB}tVgSp~6$L;R}z2sifWn3t? zGPCB~=Klf1XliT{j-XtF34yc8D%E~}eB{dPQs_ZMjhm^bc1%3I01vwF%>5Y{N9AUL z^7R@z1hzFoPqyl3(%07-PQra{_9E$oBux{m`^ap>qib{UAI68PL(D}oDTsiB)wXXp zj5Jbr>=K44_Y)E-{f|im@9Cm18nuau^=^N*GAsw1H^_=M&L`{t%q+$e^K$Fii0KF5 z@FrfpaJj&c19a^u@36N`RU+%MznsopkbrQ6;KtBo)c(=2bNZrsnN{E$A?je) z3&LoMCNNS>U~%_yU{vC9i9%En3~qTZGp~;vX-<7B+N0Ba#WM1XV|Z?ebIX+pSQj0g zxi1yhFRXr4=I*uhG_^k%d-c1X?$0cXj=y5;Q|HCehT6f?cvj>;Y*Z-Q&fNfi(w?T; z!AXW=gp1dP9owUE(TlZsXyle9sU%7lb@ORHhf=$j_HKBVR=cuN85-R=i>rP zxm$Dy_3QX%C;`F=PIx>pPq%W?D&AL<@i$KUDE#PbabC}rS%%X**Gug1tfF*GwkA)Y;e3emwEU7eXM z{6**z6k4OZ(*lk?jQX&=-*on<5&z8Lwb#PiM4bOq|H>U6bQM{5N z=bu7)ewo}~JpU{-prg}H=YJ;7D9`(dPoH?OE`~v0uJg>Z@fo_ z)tC)XpnQ+}WU(7iW*l+rUDFRZitk$+4*{cCBOWu%B$AI!Uw@@hbt`;FVsgZ@}6gaP+*r^gjR2TOPk?p4=C@dFfbUsWHicYGH)z#zJ zW;$f{^PDlmgA{V}$eRRv4k5Dkz4&FAOpul)D5V8&z6xVs&PL}rCk876jZ!4gvlDGJwwBb2!d4s29%!EYs zsq1Ft^$d)=Z{3T{Ll>X%@VSyu_VKmPSvI#N1@jn%z=~|nT7)w~UeXH%ck83MMWTX* zY&Fk4WsAYxI;*XpCQ@F@sr|HNWC#76S!k?<0l&~c@X_w9;;|XXG3nuJ;Eh^-^RUtfYm@^cU5hfL&H>41~*=1G(~4E&F|s>Ym7pSz$K_Lf^WXH*pXNXhw%k3wDv+=G&Y&dr`Y=)D~qMgh$M91P|KuK{DK~nI}s#lVl z3pgw!F3U!kN?zW(0%;DgB%)wp-G;c}5AHCeL2=%X-hdfwd>SD_95e3j>YgA8)$ZWs zY*nCV<~i=#c6ZZy=I+quS15;>YX$?8;z@oPLEL?|SsY{dpQqvtVJWhBOiL2{BGIlK zJ^tAJs$O17HTD8YdqkHR5|$!_M}<{X5!WQg@1Ee`t1RGX$2{&LBB;4)4E{Op&evSD zBkCCta|45%B#8v167KHx{K3$}!O&|>LBn^H-$t^~p6Q#lQi{zub_y?@-aB)w&{-D^ zySM=_=n#IWOh8d*Gd^o;W@cI9(B6TvR^6- z7=<8uvc+HN!k=~vHxw@&5;dSaS1S8nPZWw6-0gT#=2KSb{QTzS@+M7G7@~5@@K81f zn^Bu9ThyV!9SoW!HeC)fInmMbkrt$7?&jIBSdniGg1uD-%zuA)^7=T5NF(1{f6|HW zvgo5gL=7n8F*R@w)XT}*0+`@AIheL{glb3_C#F>=uFIbmk^>bn3&gB)-gYl?Ybocw zgeOEgT1uiIT*Ua)Zk?F9g#s7BGtM z5c}c^YGq!}t*Lu9PF=EEY>xRzhiLo(Fx=Cu0#3?kSG&IYB|?&!k527rI!$Edv8085 zk<`;ZPRCu5t(H2~Q;{k~CNGGUGHy?VbvzZx-#ZLM~n2(_E}FPJWBud;gI!huCBW+Go%yorTa@R_1!fCg3b7AN?=yfkWu# z*oN;{a=LkXPr&-K9Ym-%097dDsYqFvmT1;4>e;8ia_;BZR5rR3Gvv^x(nF6nc{oI0 zY``G4O(1FPzJZm&%-UeDwbq+Kl#Ve|(GwqvZam1Bw5E>G{v;O?>!!zQ)G(>I}F>nB-}fdc(U zruGnAJoMagU3)sspo=d@rRnIB&FzDgUoQyxJmN zXWSm_ISH6djcW%jsmmaj|RM4>nvv3D_j;xu$k}tf1sU3LX zkRLLhjE7&1sCMfQOMKcD=tGxiYN90{COiW!=H{>{28t!~II(M`cX+rS10_)v2oT&| z>GT|4_YJcv<>3fN0;IagQJ*KG;%#G!M(~?77Jkk|Q38q7{7e%YR+>hKU`6(_a$S(1 zd3~E{ztf%sitE%ZzBlVycHUfyKZ3}G0i80e>nAa~k5Ap)9`ze@+U==O5{kq@x|wA(9JFToV1LEL5r?<($yE|1R6nQgW9`T#z*%W3}-`3-bnY&`n97iw)9r_yvt||WSHggiM>^ z-8k6b>wbNgzgx+aLg2N1XdXC(vrrtEa*TdyX+6 zclhXd;**^OiD5PzIE%kc-SGGqZFedAFfo@KUQ2e3)f~71vtOk}mMvKd2JuC~CX65l`kMt;jVzH4b=K zZH)67%j7)gIWx0o&z?Cb9G*@V z;G+t6)+71VOVdFm$+4*#A|-LPJ|&Bhix3WRY>CcoXL|fKX$VUKFH%@RrY%cy;pADK z!VNbjNEqveZ^~l#VmEOXo0HpVYAA2N4TgOd)H*;qETQ2>CNMUG*1^2Py;_98yK(@x zj##l1=&WK=St)onRW3$NDb;LE-$%Pnj~mj+DR~Z1hlKGV>K03w(59V}4Qt20Ko?tRlZ#b?h-K&z}ku!C<1eRqw*z)U_W>Czi`kT()1u zX5RfG^Kdv$KviI(+jAbqTR8ZoFl3qQtxqYA9PI z!s7yMu2SiWUoqHyny){-tB&Lty_eGm&O~`JLO8)HYDqbHt)*9t}&CYtP(N}VT z440`YLEMt;X|`j6b5?BO9jVHK=A_GEapr!x15y(Yj-+&Y&0tGG9MXQwz!A%!mEcDi zv;|H&+yZxZ;*0rPk$i-}x|Jo*&nwliBgY}H=;ZM+-|QH{Wz=tTYZ7bMOTq-q9HA|n zQ`(T;lMs3|NPOYEiE{otuiy&BFR$MUcjG&`k?FNdDJZDyQjy(XWr43W)A1OAXC|9C zzzrZbhE@@3vk#PzGcM|ePgd_2>0sW%q0zmtF zLwXl3W1kFbwBCcE7aJwIDmRqSbrDBN33+j>vcpILL1C8#p3%TwiE=1v6|(h@PWCx9 zq-2wTpHf0!i2P!#i4X>@b0{;idIp30JlE--a>U7SjH9VOl5K|Dz$_!I>}(rI?>7w` zt|y)FvB=RzKiIiKr(!h1ysK=-?X&&sTK-xh^Q2kd)*ra?USiRZKdS&fDg_e02jP*+ zIxBF3c_IE{OlvlS^uX+tW^n&8hdeYFak-*XkW9?h{1Hbdh!fgKy@ZCbWVf`?tE077 z?Lcs|+UaTgaoQ86C0=86WSe~Qen8%^4BOPx2J6(%LU*0CHzyP{W4fbUR*SCV%qN5j ztcJJ6A4^=lAgI7j;thVEm<&(?M8d@BfU=WWY zw{s~hx6z>!=E~&_C(c1(Njb#eRd6R;#^k+=vd$CEm934-;zdElgNwSEry|7f%#mlU`=WJUY!jW=o75-RJ*PF^_I7=mihDey01yEdmc={ zn2;y>kf*L9U|bw`3#e0?pTZ)}$e~L@omJcY+usAb^6lvJ*Nn7FZcGpf#GR0xTn6ma z5mBSy?LrEKxucvEHIDrKL6M*FDMBZvzv2r%-npR?>2Lea*$U||b5GT|LPR_Bjbcrb z)# zEs9&+qC;8QUT;7MJYiQhGh(|uUo;Yb9KEhiiq0u%`_UDERTkE&PrXJTgj&e3om^P$ ztk`B?8%cO~?%k#i^Co}sySUU?NS0Gd1#d z8(AR8^@YP5d<%5LSWhlZKkGbdqtvM$T4Z{&l;dJ)aHgljv+XhKMDwj19lVvff~1 zS?3^53MF7}$~KW7ke*)JJo`R7i;4bEVjio_j>QVbk=i4&hEEaVx-kS7Se5GG;lq)) zV83}cy=z!6ER$w(&f9onm75qUQ=vkYadWWkI_lrL{&&N6b-yplgOZ0&uP*nm;gsuk z&k>N}8~0390D`@jm8#>eSLh71J)0A;eHF#zyhaW6w-jbQ;{iN#lOjLa;mF`<@7kSr z6~Zd7@bEcec5hgedTlE6^-*Uy%3!p%m0G=Ped1_Q5i}B)r~RcsevX#J2^08l!rPOb z3QZg7pccPdU7Ii@E|b+W{O=`91;sD8_zSrPP7JjU?<*2=czqHgi6KV8bCrjJ_RCU% z(C|l++b0Eef>ilF2vtU~G)F`uFfgK5v^=_8_ve)Zx}y?v+1+6X2jRlLL^7AD%e($l zIk409$Gm(r_5bk5^^l9dP1SQ-_VjQnZ-`%NQoKRDY;(z`?)TghHvu0X;%$Ajs3CCc zwQT8o(ctx5p>I^wdug@6-Ct?;m(Gp*V?%61c79O~s7t2t7gh~M8v^gw&LkT5UAt}@ zx%1lKAAkC5j8suv(r9SwsQ_c%_ee`MbN|h49RR9U#RD_;bcPviBe(K*dg+j@RhI9j zeVO9IQP9Xuhd0T2OR@r0bVtbDUtZJksiXqM;y3BdQD%*ks**ERC3rZ9R=$ zZnSY1fMZCPLJ)$Gh+QZGw`&x%jkU~@n46n!LI^YhuVt2;_XjR)-Ilt~Q^~7xdmM?v zG5z2fuifl1p=}Q3XLUku+=bP4pUsim1#8_Jq2G2iXmzyr({aYTdf%c21Ed9lmYXTP z`a&kNFYjGa`57bD_xyI|^K&+o{-27+2#o0ibOw7@9^%>$>aKi=auF>Zu5dRWPJg_4 zD`60VKE^C(B36{Mboufv?C3r(HCMI%R+^nvdxDh79)T%OEsPF6Hc`{%k9j3dS?kI6 zE9@4sL64>r)&s^ekDINpAuXGOBq#*)<$9sNbhBi5v+Gc}y6p3M zY>i&c3yG&5F3s{BbHa5!ZCMN)tzV>wgk%i|_{b~|3~I9bG=xb3=44q|n>7h%ACDh> zhi#AEy29&8g(RgWH;^Db33;Ul7EtN>Dr`^h?VNCR!%65J-vKw3Y%EiH%L94hJy@z4 z@EhqXc9;tVDIvd%?xYwMdX7$ibGt!ms~1((YJxrNzoaVHu$HlOV%p-7quqL z_o}1jV8rzmfOId4D{}&vW=FR80f?Km-}L|&EoJ8vM8xJp1R(Tx)n*wi2Z9(+8aXH; zq+J^a!Ntc;XC6yjA<-vFSj*j+(wr^wD>PNHak>)DyjT%yBO1waB;nYvFNlV#_$Q+k zQmy{Mg0n%XyGrUU&8~jA$-gFf5(O2C<5YS?-Vlj|keGpOE*#U!;4s&mgW>T$7{kcX z9fWjo=thT~7aU_5d|iNy`7++3T~gM0pWCOZwI;g-rr+6C?^DkW;VX%qdd$d+_IQ^f zn}6+OzWRb2(*{0X@q46+dNl2N1X>}H5{5iw0J3P`08p2>*Q%|c)hoV{pv{tVUWJn8 zywWXQAwu;$KEeiUk5_UT+ZDA;pZhiao9o=3%|waF{xhQ^XzOJK9R>$W3RJs%4vDsRRqxBT&1$uHi>g-StKC+BR_4l^XhZe0c_p15V#Y|7 zz04<|js*Fb%4^n6FOcYsYDz??^teY1Q1QP-HXAaEqb%H)lchVHzw_AHd@#4pUnOJX zWBq;|ZIXow>D)wiE|k`t`f;~Y?mVnpor)XBh4dLpm~n^2Rxc#qfp?ATf(lpu_d~^Ccyr@v1d2zjLm7Euo|`Gz zL0ct-3zeO@!g`v+gJ_v!rVMe-K1`}BpP{Sz>I;H<|D~=413FlAdgl z;zHXGk53!SYI^Q8V|p~+*4B6z(3x|dBo4BWPtSp2!YTbgj7P)9(0UGQu(WLeCEt** zYvS-=Yu4E^U^FE&;vKE1Pj-x!8yM6_=S}?SLuBG&%=?|R#W&~`xmVu)->=|%%T>@lx_KbaV)xLEEaWt*CU(&I+8 zPq6W&+7CKy*3`~wonRQPzGQDvx(6|Lu{n~U(5$bo;f}#qi=SZ4*5(Xsh)Pbhj~(9e zx)cUEiow(w!}!`$)f%75jhzxO6D~Atl7|qMmR#Z7VTj{~HrKPF5v{_`S5CrMkOC6v z*7iqKg6xl=P)_84KgyN!vkjz=QJI+h;;0{G$3O$#&E%yXOkLDBiJ4Y_jo@Q<+JwfTtVI6TG>C}KX9%^ zCcncOpgKoGRjpEW(K;`zJZN6}K=G)Ok?|XHQTcPemMwkkw5y;BfW2KhoI$dM!>RgK z!tL;H@u@6lJX^et5*s-zx7GJ-jsUE0zvSHC9yZyntNkI&Eeq~-*Op-aRmhp}+8aPG!GN-SbuG#7{4uMzQ-$}$`w0jY1b4rdKJ!Hc zD?T#LBvos}!jXxCv}~?U%wbXRKdeY%xwFw|>Njz)S+i!>U62)`a+o!%Eu`vU=i9(7 z-NNi*P!aJZthM4)&I{)oHJ%e8q?0KEs($=E=c-eHomKA1S$f&;>NMZhjZ>L_6KOr# z=ZpMLa1+PVSus>;m~oEB0n0Q|a=CFdc0o?A0d_j!#r8seSk>*hW(R8lzzj8-2A;W! zfC@^xjIGVlA&ab-RJ(?4LMlAyI4+n?!u^3R!MQ+4V-Z#)l2Q3vRKZ_kg zY@X!CyCb1@l-bO9bJa7#)!H~9GmR2G3aJ0!< zmw#FX@5+0dd*Sp~_xVkPm}EO0uNS`bZau-U9t#YN)P_$NeBF5*N?-(xZhysMfkLNm ze!o5Q2wSRiN0Nh<>GRd}fd}E2tMjTNT+cMwV0Rh6-p<3ce2j{N`6#Sx>D$TsOmfR) zLr&5N%jb!U@AzGvt*#bAINCQxy-tCx=?q1p$ozH};*SgW_PxPPX9`EE32WAgmusft z=CFOHeC=jUl7HWcs$rem#KFxj)IZ*NaHWKCyL~6&`qCjTFaJ4WwUZ3azQhg=Tg<<% z*|+4}X=-vkoP_|fLWc4?Yb#M0xau1RPsPe?bVSoJP0%Zg2Tz68fAe1m7j4)(^w+2! z7^31Uq&N4Ii(4(oJa&&dP}IFI#|gRi`R4QKzs`UCc%9USdc~v8r4FMdKcS9i>LFCa z=MFk-ucUG*8^Dxi&dCZ~I^3?F=Xk3=C7Dhbc(xH1sc{M~V)z3_kC|#4@e@ktGMIGZ zO+R8;9QMThiaa55X_{Z0z??UD*^?rPR;v)Mc=w#~G>6?!PEz~i{KPyZ;c!PbMXJ0W8Ehu2cA$yjxl}`_=Sg1pE zQm@wi;toXeah)>qZS^rcXaf)X=L4tCT=?suaD(lhBV_VCUrXK13-ZDLAc?TO7V98f3FD!H!+5$yo9Q~7KX1xR zUSsXv(K)t@{@K}bhi}~y<7b{3;OH2uE!(A=!3AHcrPpenGa~t(tgvY|IT=T1M91+e zeMPD$$EU74z+7CI@Pxeh#jq`45Fr~Q`PT=YZdddT{VE!)COO8dcB>e_snVEU?>Fsc z&F$qrz94h;Sfjl*F^4tpl@4N8NBAFSe#=;&bXz;sJxRq=VOOcMB`Wm0`$FAWgAvb9 z^sUZ&k;TrMG?5FJl66l{AA3tGvx+#@2qTiQ+iOC)NvDJp5V9*};3_Ul74m5ZNA;G8 zOXmcFv+e|zW^i@*qOk*^H2xUQ((Ku_hVJrVx0dKj=%UMGJS;vh0T*dlCe2O| zVQ1Xt;V2>gSY>C6LG4QVjyo9SB9*URUm@oBP%wX?M)RVnv4S z;K&^egMq&cA1g=o4?gLW_Au$glX4n(#NCOQcN)D9va?I1E>iM;<_l-DGCEXlwo|R= z66E+Q#O-z!!|0&|I|u?j=aPoYOUjU3Po~LTTsJY%lOI3QZ_Z=GOob}wxa=6-CyNL3 z>r+o&MZgVg3c5RaFE~lX3IR=@GC~l0DrgRYt3pSauBk&J4D`@WUz?6hE7#!Ty}w5* zKctb+@M%V;>Ut@VYTF}u4{9XQL$exrF* zj+X0cS=e}Z)K&=^YoxOAV6JCI(CbZX`99WaS zKhs1{zxhlqT|`B|^s`p9T9@T~(45o6<91ivr)dx9)ACPZUDzPnNt;l6c*c5?5$A)B zFsAexxs-OnA8mA(Dnh!py{)en#2Hit78fHui-yfeGCe^zNKEG=eJjY znhDEYB-gg~zP1Zzrd)HfuY{r#sCvcw4?SQ^Me(2V<=iGe8vDQy6s2+o$@&|C1N&xB zCdd);gSqS`@qNpYp6JjDKHHw&FaF7KCF%sdBS6*WMAS@Im#2~yZZTRa(94jdn_GF( zELPMZxT*@?Q651FQQ`<#I(bo*tQq5%Q6yhbWuD!nu z@YK?$F) zPLUJvljFm~Y{W5+623^T>Ml!p=l+xt2qa-OCjf~;Ais!iYu#$zv}vlgSHIw6Fadjf zO2A7*V?e@q1Ud3%9r{QeO`^Y>we?OTpZd|2zQxr#Tk*BTwE!W&lKl@dWsk3WcVBrP z`v^m7d-hlFWv96w>6SLF6xy-YTbJs*LJ!APrJBj@-gir`5c%>OMV0iO%vpbI-%nGr zK$$wYcrF%A@3~IPnYCNE?<(zFe_FNi-DKhF75MZLW3jBn!=dk@@%%L|3 zZJM$fptPc`hrO7cv(`t&r}m8&(;L4*xwsTwAw`LDIkSthEtfOim+A7B5fx_a<$E|T zE*P>sH6t{F#JPNQujH-ucRs!C5v$wbdNHuSJu0D@vL;v8FX;AU`U2ob4KgZ)Nk;P* zw=4Vh-e_tMD^phP5I$}?3(*mKX0rO|VB2rx9?ws=3Bm0pCN`oiAFRAFju-)55 z`kUtKdMyQ3VaQao!p23SCR6>f2=J0N`ub#r;WA!8Y_jr#3$>@rdaTNq-yN~lx2f3N zt@k^c0hasXD(wv=X%-!ilfAQG?)IvT+gJA9?0h^ITekM7_kfMc2%`a>L!OS~q}}hX zFRZMrTxL94LinF;4$(MGeG~muZFR)aU?cl%p4ufiM8ls&xP_9 z2>-q8lnciraP4VLd%xC8?>ERcosb(E{I-QN?yN|?lT=H?wy%!(STYhXZ!RlbjkeEo z_z2TgkG?i%IbGLX^SI1O4G&cv8gj!tjbCV;?lc~8U0rhKW^-U=a$@-1mawudZK#O{ zp#86JbxExpKH`t;pmTIdWE_W1^6oOlmlP#VBse{B5+V^d2kKg(;)&IzE9#HEF@b}U zLdNl*)MEDZ|BeuaK%RFnL2cj-&`@4&7dy9DkDkYvs_!_d0NQAELw&tRn*v$~x}rnY zd-eOz&%R8GQ~nv_^ZWVjTf+TE@zR}qfXDmQP~+_^7K331%?g2!zC;Br*i5`Ybyj3W zS=E);fhtc0&YW9^rii2iipYy_f$hXR4^3^~Oa*6_cdth~TQ$RdAvocZOEhnBDgzxQ zCbe;GuKm%Vkal)+T<-YUaTvYtpD~(@BS^GEugAmC&Dd69l0e#pC=W=f8o4o{EpB=` zY6moH9zpYrg++^~uyVN~CG8&kN~yXJMxg<)bGs0o(0u-C{viv?L@CQlyWTJVTzP@U z+D>fHd|^Q!pdYiAehJ+F{`6GcVnq<~f7!AmxX`_?iWJbo|Ewyvg68ur8v}W-E4^Zb zoJiDugwerPZC)EmfINlgUjGs$T~apuDkN!F$swnG+Z&KIkxy`L6(<_-ujHQN! zXXO(_xwtJNfF#L9+y76;)d$~?#z5c){E(x0!)f3}8?ka#owf5#z4YLa6uxwwFC%Se zNGtLWx43^sB#Ya^0wijQ+Y2HvDwYHDfzX9~{U;ENwikwH6V0bv8xfVMgWKO{)oXqq zxw_lbcunYj;8Y~{>vWG=8C$PrI?8-e*`;`m1OI@(A7=YGhhqxGYp}N^JSWa9-rJDLh9*2uZcg^yly?GgF_dt# zx6iPwuR^npqXa&46z88!1ea-lSc-8At@g3Jm7Ws&J^$w!enHd#y|hsUQrh(dORI?S z>}&OAm|361ienBzg*4d=SHl`7mL~#2YP5*efw=#67}7FU7|WXe%`CVfl2zb$1L8`y zqtJb~b5U*69@L4?;23KB2v{hgXbbI{)vos$C!t>=zxw_C{``y(jdqIqU)pKoK7T5b z#-c~oIeUL(2XwO{j3!l#`F6lae)v#Q%1OHl<@R-ija2{~L&?LFc6|&?PPqgP2r_D_ z(`f$1UXi6?#)`!)OUr#duQAUB8k_>cRU{8EK?jWd{0DOo4WsV(U>?yi5oq+lU*D1U ztJ+D2jUbXk1i~J1;Jl2-3s)g`TbR$~rF%A>|KU4qdqQt_m#Oaa6A;jEj@KwJ zoY$NDTeoy+*e>wT4C5E&?b``yyOMA;@zq+4$@~xK@Js}tA?Mno3|wE8kLVhgT}ANF zWa-in^g!loey(N;Za#kz&c)lQEZp*i z*UampA)d6kQ~NH51>R0tFz*POZ};RZaa`QrUua=W zH~d{bYXf?t68ufEMQZX4$1|1v1}^JM{AiNy6r#DrrZ(?LHL+}|!W-V7k5g##K3*(M zN~?v}4-Bs<+&jZbV^syltwOa%)khWN@Kerd-2Wi%{|arx)Y19(UX`IkU|f-&!ov~v zx``?W#Rw*xkgt!yZppd|lB?oMx;khJDv_Tj!2y-nD^kLOXLCw$BnH^0se$@~2~we+ zb+NbM^6_XpIbLn;D|;0^fhj$@kmT6er{+?9q3UGHBg zt>J~b2dPpQE0c!uN6iE1cd+ql=+W6kee|dChJfHXsXSlPwSE9__4$E7LR`+Noz;E* z;=y2bK0PwnohN=q+3ri0f?kY4+9P9~UcBj|aU+-Tt7Ya^`klXE%L`RLq=%|S* zOfVvXzMgBG3MPnV%PXt=sp{{eb$Xw@Z5u%UVTe=y$2o616c5le@(8CC|TKhD$%DZNV`XoYiG z%*$Lo$)#ZJK(rGe^+|lV#L5dAN?34Fa9bqGS|xV4k+tDg!{wLv(%&7!kz=Qv&LRXu zu97MBRGujZ6N326gh6 z$(rY6D&|HlK6vW^4Obaq0+b2Rr*(5t==hz)jV2xcxHr%X;7)Im9NXdwOAqf@8-0#G z8OH3+)U-7o$cm30n)XnOVAKP7zbI_&F|fS7n|zsR;;{VN2}|U1tYen(DYl3Dn|_CP zkLp;;|2WINTIi&jGhmB!{{@|Nub+{ol-B#iS3jl zzxjNE@#zzsft*pV5W8h4fK)?5Ez3kF_GQy4U_N_K&U9HmnoS&YwpwW)UzI=ISO`5nruIwE`*K~5}7vAiivW+GOJkQItD`tm&EO|2{<@PI85d5 z)sSB0!_f&ZW&6NtNm_|2n--~fn3{_Ce&YJzX#t5jhrL(LQQfWsAcuwXe#(=CK7FCS zD+XgHP{i1l6@wRV&Lrw#(z`YWWFL)__s+B%2b1Mr9gFxR7Ff6R(l#}J0%{V65KY{5 z@>A2DhEBxVX*q*Hb_&w(a64`No~k-D?6iiL&;bN~vo)`t|aXI^8@mi<#A z*h#YD=??V5vr@x%`AJW0Z{_DekybC>1b)HsM(jO3u|A`7?!C|oCzZBMJ@`*qDgE;^+Qwy;A#^y#qecmi@r40M!QDAX z>WcwI1i!@Gaxf)Ip@mf^*;Lt1;~=3On-{-yQWya^tQ` zM^sSvR*-4H{(`;zo}{m&%?mFm@7p4muQubWsh|7AD>|^>mPUA3e`b_!SF|_v-lA`-&LSS5aX$(3kXMYQP-Tj9^>cC<|57csBV^ zD)Si=y;4=Qjvp_!(>5z`tu|9@@Lj|g!N&pIO6{f2)4r${t)ohiqw>GT!U?<5a<=w- z>E9q|ps6hsUeOmabD&1gFFWRg2Y{oKOO_QJAZc8V|9WYd4w z-v8U#;XKgQc+M6mB`8zTLe=wc^nn?wfo!l>%)pU@J%({H9^-B`6!N&_8nyzMNva*? z%J-UvKkgK@r3a>?)$TT#2^|*kOBt`XQ9zv+#Q+anOl7Hi!R$cOS^`apCcXMoIpSRI z8X6y&0{*^*!(SrrHh@+bD01iek2Eeb2OFS*uFS~=oYJ(1@dVFb&GZEu@dtz7Eokyu(g|5jIJUwJr&Bn_6Q_-Kqxik;oEo)PFnQH7S94I&q-7wwqwTF;r} zvMQ{YQ=JPvUzp5eqNABL33eyjtq!;z%q`<{un$OPV{lE%OKY^Y57%iQenNO8Q|Ka~ zxVJzzs5ygzI256A>5qEti&#ANOg7vfTyBTT89m9@0(vrfeY(!iiU-S-G|Je9Qg`jy zBt+TR=V-C^p!{fO3`QrLgW&uvN?}B_s5yi=QZu`m<7BXq!JQ*1%-8QE?S>xAhH{-N zbfcsgxgSZ{uqg`kC;G`{EWYlzRh3P^*5E*kEkHh5TuQf?xwdP7ND^FFbG1It)XVJT z*=*_9mgp2zN#e`<&?*8mLGO=ujg2#Q8w?WZWjs%o<7ShaoB({rkY zF`vKi@;ERYn;}FBX}3-zW$tsGc7gM?e{@_^#y2mxO%v1dfVZ#RD%b={(`h=Mv+ZQY zNn*CUe zcFeM!h`lNVV-CT&UHEs@#H4#32b4Y&I_sh!8BQbfzpw%dnpK(D#`_lRTfnE)ep8K% z&A&g=rKn4W^m-kyME;+#n%QUrX|BM{#SSahKa@wb!@nMn**ixO zDk44s>wNtLFS!$zFkJup>;n!so?L)2q10|EsE@oe4?kNzZ+&`@D!iZ|&L_&P()J^C zEwum3qqrM*219#ml@S>KTR0~qTJm5ZzrbI0SAsfU?8(Zr+ENoG24&HN_>Nr0$0e3_ z(i1UXGF9**Jkrjm=33&ghMT>PthfP^R#WuuG27)rYS|`AYJXLR%yxtPDs~D({1YE= z9;SN#@5KNeVy555YNvdGZJl3!3yW$oj=zBx`4xc&{7lrjts^X|5YI?>$JT% z8>29i=xH+d%t5ikzPmzZ=jH7wejA4=UrbaA*D(lWY_`l17^ycZ52CGWKgxh}kTnDa zTI(K1UoLA1GB3_i6WU|eR8nM8zPT>qrUHRm!I}3g3jzAMhK&b)k-TK~(q6~GPz(r-temu; z;V4O1yNkb%se`kc3iI(&BSn!kbvZ+XVSI+WM4K`euvbECj`_O;mO=LwKa1PVA2*BQ z;z9s(qihC6;h~Fe%fkC?0wGVqxa)f|hLcyChWFHw*>u7$_5%D9Y@N;;J$-3EaamvB ztj6rrc~RmFEv;VV<4@ye=Ltl-?f_=o_wLT!*XS&^c*i4y#WzES)5c%0sJJwp!)U7s zO5)@8hp4XOUGvmABExBMIVA{JVznh7=-oADurwHjSqkS@WwV z*{KKywLISZ^VA-;~kuV!WTkQi;AcSw-^zkLZ<@9&3ketf*Vbziz~anOnQ&G z*O;)lXK9_KJTU@ihK-%)4!}Qp0ob2aqA;8Du&{*tP1GMrY~R6%fd{#Zl!C0xG_xaU zgg|HVuV*)k3tc|CIl>14^-vzd4`jN`zzDl=6SQn#@F}bE(q>um<6R4br6b9hT%{0jp)#*E+8;E03VF5DZc#9tkm)TTHyx+e zI8mwFN78|37ZxS5(^8Wd={7~$E4hhyCcTj%UXF6(N*{PErS!3@`(Qe-k7|0LkrX>~ zaLf$@a}YjTihxTHm;DZ&N!SlXt*k@&NC*cglf(6JdWuc$sQ;eWxzivGw2~n|+iLZq z)+ntnb!NH^&^%-esh$?*%G#qQXmRBX%XZNSQ&r1GxM#zt7Tl46?S}Cxj2zJZgxEKHwny=%dJcJbRi?#V=!(DSwIdOQx zK#zoy4Fc-!_-^aR(J6sX^Z#Db(0@7p-&KuyG7`ds^22dq;K$RC+!*Ci4-DJ`hc7;gifbpeomXEcZyp^ zh)WbWvo`O9g~2KPHeR^PToCw9>Qa*iP1M(LF6y59zkn1&vWNpt$fA+z{fC|4tB0}o z-=uj{KF@l^z@LFKN-}|e5-Nm*X4NiT^AJ~LF{AK=YQG-z_bs* zZ!_|YLH+6D11$?d7rBD1hGrY@w$6-o5kTB=1zx$(8#pSKrT#IiU?G7`Ow`OXOz!6U zF$O_@;THPYrs9fqk&n;RF_uH`+kABq)vk!2#`HDw8Sx8oj9-Oe|F0T8=Q6;v-&ENo zW2N+!e?PwL_Vx+w9Qm=_=w!T6kz`GSy>`{ek2OB$cJ%Ign3qRW}4&2m2C zx690{+uFz4c|nN+hUd`fiOy({p;g1~qE0Z|#$&Y0`ldZRO(C1(@0#Ictg0qi~ z`$j@$@a9N;?+w1MXYceT9w&5Uss-L1!j4tDrw3LD=u7dP{@oygY7hmYiu?x-5S2aW zK-Hq9+!jId_V05|&!x7@g8#VnFW4Uj45W+F@#f2~T(QtzuDf>ngl%&ZjkIdm8c+YW zUSqS%rr9aUJq3>_bz=^u8A~I`yq+v&embFx;F5%afk`1Di7Aq2tSx+Zex*qTC(=g2 zT=;Mv2%y)Z*8c}0;6zH@E?0*B4xRS)t+o9Ji=z1bXpYa z?wOf+7*ZdRfPB}s-cAkbW_48f^lN7;ZPLea zhSpvw@*I-)iHxBpJxLP`fG{_2!e6azj9dXsfW+0X?+}JlMCJ(CXSVpn3rA{4u zIt$WDIa*rjr#~G)iv%C^94gbCgQp%M`|o&89NO|9+=L%(9$Jv~XaE4pNlmxk*_Va6vw_K{y-;(eL+8G3pSXDUT748wIJ z#O4RWHde7?9(8gWudJ$f?P7s2;lDt($FA(+jGa8RIp};MOM|weFg_t@@cdyo7+{zL z*I4<)nY0^l61UjaR-b0({ZieWsQ7K#!}R>G0Nbeh2M^9wR&X$+T9QIBXF>tj#A~HrNtf{#4TE_W~B8@y)Nx33AYdkQQ*R# zkx?8mj7sQL?;1=@7?}9Jlk)Jt$YMDMb_KQm=W!A(LU5ghJx*Z0<9zlfUkmrfIr%Qt ze<2O$0W1=I?!bHf-}5Cjk-RD^ML<`tQGDJ0-mFFztzPv0%Ktn*8@nZ~5I7|8(Tk0p zyv?|`&~)Gy07kp@U0AMZ+$f<{YpQ_k^tG*Y8z&+5Ym|-!&_AekiU0Rq`Cvh~{5pYQ zl~Km;L2KVASRpDII=clvWg$ub>8k-j0!`GqKP7Y^Vyj!&@k^K6Hu+$Z^*~r4bZ=SbR$o>&*^-xq*wm7pE3yHe9CK%}+lU08R2=~C!! zLFfyQTFUG7)^m;C-`?%7${*fU0VA*b?-XQIzit}n*#?uG(+$};oxQ~rj_Cjy!w1En zi%%P99TBu)YwK=Jn{I{^O?Usi8-7j0IFxp=_>15|!|1hJht`MBO2xWp$t-YhZnPMX zw$at>wvhtYHrMh&nTW#yc z?(T3?Cha~erG_bHPXk&{dPd_yU8Afmje(X5`6<=cm7&^SYFkIE`_y_VKI9zdCX{-b zgJQpoyy9L1CiFqji(8ix89VVGo5un$?9X>Be70O&V=b@ZDpn-qf_Pz49X~0_g#D!i;hYlF9J&`pwI_y3E zU^bt2?vQ_iQ!d{)ZOGvkoP-iC_K44T!?-(Wut%T6}S0uolr})uuI7L#jHM z1R0X6V%F)_2sHc`*AJ&di}yK)?#sU+Mm!EcefZ*N)h;B6t`>Dk_W1s%W+L-1h)2b> zlVQj{tJ@jA_~#)@bYjP#j}P=*_sNm}ITm)pj;_O>ug)QDM`&ISBL=fhI-tD(O83EH z_v(y6r`uHoJC}G>z3be}6`*e39jZac3BE1Y!%Ql!hs1AK-wL*au{2ogTCvKRT$Q|R zrR}V?K1Z<*?Yut6@&t2XmHIz`u}6R~?2{g$OACifj4qtTl6qkHoW}F2#YbuAp3%Gi zJI^I)F*-AB;NVEqKX$Bkzaydf=dJ`KOf6?vD)=uBi;5} z;;S!+CHwA2+HXg$KaCG^`lh?TlXdtY#EZ`OyV?BH30lZBsXV!%F@HVe*Y!Ryo;38T zyB0ezCtL~Rr(D09q5Zfb+b~9#GqssFHx9O%n$}!B>Q`Es&IYW-bFh=&vipOZp!xs> zm$`TPv-P1xY=6^UXH#C*&hxB}39&p@Ox1aNt6XqwR2sG#mTWmw{b#mbc-&Bq_N+xk#R5=e;_RY7%Y=9v;P8&?qvMo zc6@(<#y({|Ep#W1axQf3+}c*|4N$Ol3(M6HvA^3Pv2%H1mnEfCKP1bi&+z=153uo1 zVok$3r+L{4B_{}*FJenhB)y-HA-xgHF0k1j^4zzWJ@5J$XC+zkoF0(#l*W|bJs<{a=M zHe2IuDKtw>XM-MozW?Io9rxhm7?P#vG8mVtmi1+9e6#we%xAHt$BqxXX!+P}V9f#a zC%^u)Z4wI9fZq2@eLB{-9p~2`Ln4c1>xV3`k82xUSPe9&`iK@K(twfWUn<{qZg41` zpkOO>_r>Z&yj8-**y8sD`73y6zV{j9r~cB53a@y<&pL?T0t6e64-%m(Kibqc%lAJ2 zySMI{`r7ku@!&%pu)J3~!h$;u()UkxouMH>o!{7?E%7cukFs0-Wc@k9|on}nWH6{avX&AAly?vfwU8}Rmsv;HC-#@jcyUkUZTzg ztd8FYo`4n*{a44Ams?|ENPQqh!`|_9zhU`5UiiOPLc@MH*khcp|NHO%C({0hQP>Ij zH0HZ+eDpo>UxfY-3;eft?`bftl*)da^WQ`N=Pdtyw&f@-_Wvn~Mbc8$|Jy(OTPjrO l|NkmlU?Kf~zk#Gfh6hJ$$JW73SrG8YQ1_Bfsg^_7{{`N!N*VwF literal 0 HcmV?d00001 diff --git a/docs/source/user/inflowwind/figs/FFWindExtrap--Tower.png b/docs/source/user/inflowwind/figs/FFWindExtrap--Tower.png new file mode 100644 index 0000000000000000000000000000000000000000..1e871c3d1f468c9f550c016cf72af39938bf2d95 GIT binary patch literal 135967 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⪼fy_FB{IQ2H5lFVVAm6sZu%795+8doF$GXhY?^ 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 literal 0 HcmV?d00001 diff --git a/docs/source/user/inflowwind/input.rst b/docs/source/user/inflowwind/input.rst index cbf70c62b..b2d9e9733 100644 --- a/docs/source/user/inflowwind/input.rst +++ b/docs/source/user/inflowwind/input.rst @@ -4,6 +4,10 @@ InflowWind Input Files ====================== +For fixed and floating MHK turbines, all InflowWind parameters should be defined relative to the seabed. +To maintain consistency between the turbine and inflow coordinate systems for MHK turbines, the query points +passed to InflowWind are adjusted at the glue code/driver level to place the origin at the seabed. + .. _ifw_native_bladed: Native Bladed wind file support in InflowWind diff --git a/docs/source/user/moordyn/index.rst b/docs/source/user/moordyn/index.rst new file mode 100644 index 000000000..52730e521 --- /dev/null +++ b/docs/source/user/moordyn/index.rst @@ -0,0 +1,12 @@ +.. _MoorDyn: + +MoorDyn Users Guide +==================== + +A standalone C++ version of MoorDyn is also available outside the OpenFAST +repository. The documentation for the C++ version covers the input file format +(`MoorDyn usage `_, specifically the section for V2) +usage of MoorDyn at the FAST.Farm level +(`MoorDyn with FAST.Farm `_), +and links to publications with the relevant theory. + diff --git a/docs/source/user/servodyn-stc/ExampleFiles/NRELOffshrBsline5MW_StC.dat b/docs/source/user/servodyn-stc/ExampleFiles/NRELOffshrBsline5MW_StC.dat index f504cb8d8..9471cd7c1 100644 --- a/docs/source/user/servodyn-stc/ExampleFiles/NRELOffshrBsline5MW_StC.dat +++ b/docs/source/user/servodyn-stc/ExampleFiles/NRELOffshrBsline5MW_StC.dat @@ -3,7 +3,7 @@ Input file for tuned mass damper, module by Matt Lackner, Meghan Glade, and Semy ---------------------- SIMULATION CONTROL -------------------------------------- True Echo - Echo input data to .ech (flag) ---------------------- StC DEGREES OF FREEDOM ---------------------------------- - 2 StC_DOF_MODE - DOF mode (switch) {0: No StC or TLCD DOF; 1: StC_X_DOF, StC_Y_DOF, and/or StC_Z_DOF (three independent StC DOFs); 2: StC_XY_DOF (Omni-Directional StC); 3: TLCD; 4: Prescribed force/moment time series} + 2 StC_DOF_MODE - DOF mode (switch) {0: No StC or TLCD DOF; 1: StC_X_DOF, StC_Y_DOF, and/or StC_Z_DOF (three independent StC DOFs); 2: StC_XY_DOF (Omni-Directional StC); 3: TLCD; 4: Prescribed force/moment time series; 5: Force determined by external DLL} true StC_X_DOF - DOF on or off for StC X (flag) [Used only when StC_DOF_MODE=1] true StC_Y_DOF - DOF on or off for StC Y (flag) [Used only when StC_DOF_MODE=1] FALSE StC_Z_DOF - DOF on or off for StC Z (flag) [Used only when StC_DOF_MODE=1] diff --git a/docs/source/user/servodyn-stc/StC_input.rst b/docs/source/user/servodyn-stc/StC_input.rst index e62ed9107..c132873d0 100644 --- a/docs/source/user/servodyn-stc/StC_input.rst +++ b/docs/source/user/servodyn-stc/StC_input.rst @@ -107,7 +107,7 @@ StC Degrees of Freedom DOF mode {0: No StC or TLCD DOF; 1: StC_X_DOF, StC_Y_DOF, and/or StC_Z_DOF (three independent StC DOFs); 2: StC_XY_DOF (Omni-Directional StC); 3: TLCD; - 4: Prescribed force/moment time series} + 4: Prescribed force/moment time series; 5: Force determined by external DLL} **StC_X_DOF** [flag] @@ -310,7 +310,8 @@ StructCtrl Control **StC_CMODE** [switch] - Control mode {0:none; 1: Semi-Active Control Mode; 2: Active Control Mode} + Control mode {0:none; 1: Semi-Active Control Mode; 2: Active Control Mode}. + When using StC_DOF_MODE==5, StC_CMODE must be 2. **StC_SA_MODE** [-] @@ -425,7 +426,8 @@ when* **StC_DOF_MODE==4**. **PrescribedForcesCoord** [switch] - Prescribed forces are in global or local coordinates {1: global; 2: local} + Prescribed forces are in global or local coordinates {1: global; 2: local}. + When using StC_DOF_MODE==5, PrescribedForcesCoord must be 1. **PrescribedForcesFile** [-] diff --git a/docs/source/user/subdyn/examples/OC4_Jacket_SD_Input.dat b/docs/source/user/subdyn/examples/OC4_Jacket_SD_Input.dat index 67f6f15ce..43111b830 100644 --- a/docs/source/user/subdyn/examples/OC4_Jacket_SD_Input.dat +++ b/docs/source/user/subdyn/examples/OC4_Jacket_SD_Input.dat @@ -1,19 +1,19 @@ ------------ SubDyn MultiMember Support Structure Input File ------------ +----------- 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 --------------------------------- +-------------------------- 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--------------------------- +-------------------- 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] + 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 @@ -21,9 +21,9 @@ True CBMod - [T/F] If True perform C-B reduction, else full FE 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)--- +---- STRUCTURE JOINTS: joints connect structure members (~Hydrodyn Input File) -------- 64 NJoints - Number of joints (-) -JointID JointXss JointYss JointZss JointType JointDirX JointDirY JointDirZ JointStiff +JointID JointXss JointYss JointZss JointType JointDirX JointDirY JointDirZ JointStiff ![Coordinates of Member joints in SS-Coordinate System][JointType={1:cantilever, 2:universal joint, 3:revolute joint, 4:spherical joint}] (-) (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 @@ -91,15 +91,15 @@ JointID JointXss JointYss JointZss Join 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) +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] +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 @@ -109,124 +109,124 @@ IJointID ItfTDXss ItfTDYss ItfTDZss ItfRDXss ItfRDYss ItfRDZss 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 +----------------------------------- MEMBERS ------------------------------------------- + 112 NMembers - Number of members (-) +MemberID MJointID1 MJointID2 MPropSetID1 MPropSetID2 MType COSMID ![MType={1:beam circ., 2:cable, 3:rigid, 4:beam arb.}. COMSID={-1:none}] (-) (-) (-) (-) (-) (-) (-) - 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) + 1 1 2 2 2 1 -1 + 2 2 3 2 2 1 -1 + 3 3 4 2 2 1 -1 + 4 4 5 2 2 1 -1 + 5 6 7 2 2 1 -1 + 6 7 8 2 2 1 -1 + 7 8 9 2 2 1 -1 + 8 9 10 2 2 1 -1 + 9 11 12 2 2 1 -1 + 10 12 13 2 2 1 -1 + 11 13 14 2 2 1 -1 + 12 14 15 2 2 1 -1 + 13 16 17 2 2 1 -1 + 14 17 18 2 2 1 -1 + 15 18 19 2 2 1 -1 + 16 19 20 2 2 1 -1 + 17 5 21 3 3 1 -1 + 18 21 22 3 3 1 -1 + 19 22 23 3 3 1 -1 + 20 23 24 3 3 1 -1 + 21 10 25 3 3 1 -1 + 22 25 26 3 3 1 -1 + 23 26 27 3 3 1 -1 + 24 27 28 3 3 1 -1 + 25 15 29 3 3 1 -1 + 26 29 30 3 3 1 -1 + 27 30 31 3 3 1 -1 + 28 31 32 3 3 1 -1 + 29 20 33 3 3 1 -1 + 30 33 34 3 3 1 -1 + 31 34 35 3 3 1 -1 + 32 35 36 3 3 1 -1 + 33 8 3 1 1 1 -1 + 34 13 8 1 1 1 -1 + 35 13 18 1 1 1 -1 + 36 18 3 1 1 1 -1 + 37 4 37 1 1 1 -1 + 38 37 20 1 1 1 -1 + 39 19 37 1 1 1 -1 + 40 37 5 1 1 1 -1 + 41 9 38 1 1 1 -1 + 42 38 15 1 1 1 -1 + 43 14 38 1 1 1 -1 + 44 38 10 1 1 1 -1 + 45 4 39 1 1 1 -1 + 46 39 10 1 1 1 -1 + 47 9 39 1 1 1 -1 + 48 39 5 1 1 1 -1 + 49 19 40 1 1 1 -1 + 50 40 15 1 1 1 -1 + 51 14 40 1 1 1 -1 + 52 40 20 1 1 1 -1 + 53 5 41 1 1 1 -1 + 54 41 33 1 1 1 -1 + 55 20 41 1 1 1 -1 + 56 41 21 1 1 1 -1 + 57 10 42 1 1 1 -1 + 58 42 29 1 1 1 -1 + 59 15 42 1 1 1 -1 + 60 42 25 1 1 1 -1 + 61 5 43 1 1 1 -1 + 62 43 25 1 1 1 -1 + 63 10 43 1 1 1 -1 + 64 43 21 1 1 1 -1 + 65 20 44 1 1 1 -1 + 66 44 29 1 1 1 -1 + 67 15 44 1 1 1 -1 + 68 44 33 1 1 1 -1 + 69 21 45 1 1 1 -1 + 70 45 34 1 1 1 -1 + 71 33 45 1 1 1 -1 + 72 45 22 1 1 1 -1 + 73 25 46 1 1 1 -1 + 74 46 30 1 1 1 -1 + 75 29 46 1 1 1 -1 + 76 46 26 1 1 1 -1 + 77 21 47 1 1 1 -1 + 78 47 26 1 1 1 -1 + 79 25 47 1 1 1 -1 + 80 47 22 1 1 1 -1 + 81 33 48 1 1 1 -1 + 82 48 30 1 1 1 -1 + 83 29 48 1 1 1 -1 + 84 48 34 1 1 1 -1 + 85 22 49 1 1 1 -1 + 86 49 35 1 1 1 -1 + 87 34 49 1 1 1 -1 + 88 49 23 1 1 1 -1 + 89 26 50 1 1 1 -1 + 90 50 31 1 1 1 -1 + 91 30 50 1 1 1 -1 + 92 50 27 1 1 1 -1 + 93 22 51 1 1 1 -1 + 94 51 27 1 1 1 -1 + 95 26 51 1 1 1 -1 + 96 51 23 1 1 1 -1 + 97 34 52 1 1 1 -1 + 98 52 31 1 1 1 -1 + 99 30 52 1 1 1 -1 + 100 52 35 1 1 1 -1 + 101 24 53 4 4 1 -1 + 102 28 54 4 4 1 -1 + 103 32 56 4 4 1 -1 + 104 36 55 4 4 1 -1 + 105 58 1 5 5 1 -1 + 106 57 16 5 5 1 -1 + 107 60 6 5 5 1 -1 + 108 59 11 5 5 1 -1 + 109 62 58 6 6 1 -1 + 110 61 57 6 6 1 -1 + 111 64 60 6 6 1 -1 + 112 63 59 6 6 1 -1 +------------------ CIRCULAR BEAM CROSS-SECTION PROPERTIES ----------------------------- + 6 NPropSets - Number of structurally unique circular cross-sections 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 @@ -235,32 +235,32 @@ PropSetID YoungE ShearG MatDens XsecD X 4 2.10000e+11 8.07690e+10 7850.00 1.200000 0.040000 5 2.10000e+11 8.07690e+10 3339.12 2.082000 0.491000 6 2.10000e+11 8.07690e+10 7850.00 2.082000 0.060000 ------------------- 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) +----------------- ARBITRARY BEAM CROSS-SECTION PROPERTIES ----------------------------- + 0 NXPropSets - Number of structurally unique non-circular cross-sections (if 0 the following table is ignored) PropSetID YoungE ShearG MatDens XsecA XsecAsx XsecAsy XsecJxx XsecJyy XsecJ0 (-) (N/m2) (N/m2) (kg/m3) (m2) (m2) (m2) (m4) (m4) (m4) --------------------------- CABLE PROPERTIES ------------------------------------- +-------------------------- CABLE PROPERTIES ------------------------------------------- 0 NCablePropSets - Number of cable cable properties -PropSetID EA MatDens T0 - (-) (N) (kg/m) (N) ------------------------ RIGID LINK PROPERTIES ------------------------------------ +PropSetID EA MatDens T0 CtrlChannel + (-) (N) (kg/m) (N) (-) +----------------------- RIGID LINK PROPERTIES ----------------------------------------- 0 NRigidPropSets - Number of rigid link properties PropSetID MatDens - (-) (kg/m) ----------------------- MEMBER COSINE MATRICES COSM(i,j) ------------------------ + (-) (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 +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. +---------------------------- OUTPUT: SUMMARY & OUTFILE -------------------------------- +True SumPrint - Output a Summary File (flag) 0 OutCBModes - Output Guyan and Craig-Bampton modes {0: No output, 1: JSON output}, (flag) 0 OutFEMModes - Output first 30 FEM modes {0: No output, 1: JSON output} (flag) False OutCOSM - Output cosine matrices with the selected output member forces (flag) -False OutAll - [T/F] Output all members' end forces +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 @@ -268,7 +268,7 @@ True TabDelim - Generate a tab-delimited output in the "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. +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 diff --git a/docs/source/user/subdyn/input_files.rst b/docs/source/user/subdyn/input_files.rst index 00df19977..157ad04f3 100644 --- a/docs/source/user/subdyn/input_files.rst +++ b/docs/source/user/subdyn/input_files.rst @@ -427,8 +427,9 @@ A member is one of the three following types (see :numref:`SD_FEM`): - Rigid link (*MType=3*) -**COSMID** refers to the IDs of the members’ cosine matrices for -noncircular members; the current release ignores this column. +**COSMID** refers to the IDs of the members' cosine matrices for noncircular +members; the current release uses SubDyn's default direction cosine convention +if it's not present or when COSMID values are -1. An example of member table is given below @@ -543,17 +544,13 @@ An example of rigid link properties table is given below 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). +direction cosine matrices (COSM11, COSM12,…COSM33) for matrix elements. +Each row is a vector in the global coordinate system for principal axes +in the x, y and z directions respectively. These vectors need to be +specified with an extremely high level of precision for results to be +equivalent to an internal calculation. Joint Additional Concentrated Masses ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -602,7 +599,7 @@ 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 +Specifying **SumPrint** = 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 diff --git a/docs/source/user/subdyn/output_files.rst b/docs/source/user/subdyn/output_files.rst index f016ecfa1..ca5988e00 100644 --- a/docs/source/user/subdyn/output_files.rst +++ b/docs/source/user/subdyn/output_files.rst @@ -27,7 +27,7 @@ Summary File ------------ SubDyn generates a summary file with the naming convention, -**OutRootName.SD.sum** if the **SDSum** parameter is set to TRUE. +**OutRootName.SD.sum** if the **SumPrint** parameter is set to TRUE. This file summarizes key information about the substructure model, including: diff --git a/docs/source/user/subdyn/theory.rst b/docs/source/user/subdyn/theory.rst index 5ca5917d4..ad56023b4 100644 --- a/docs/source/user/subdyn/theory.rst +++ b/docs/source/user/subdyn/theory.rst @@ -1842,7 +1842,7 @@ 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. +In the "free boundary condition" (floating) 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:: @@ -1935,9 +1935,9 @@ 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 +consists in an additional term :math:`U_{L,\text{SIM}}` obtained +as the static deflection of all the internal DOFs (:math:`U_{L0}`) +minus the static deflection associated with C-B modes (:math:`U_{L0m}`), as cast in :eq:`SIM` : .. math:: :label: SIM @@ -2572,7 +2572,7 @@ Output: nodal motions **Fixed-bottom case** -.. math:: :label: +.. math:: :label: nodalMotionFixed \bar{U}_R &= T_I U_{TP} ,\qquad @@ -2597,7 +2597,7 @@ The meshes :math:`y_2` and :math:`y_3` are identical (Guyan displacements comput **Floating case** -.. math:: :label: +.. math:: :label: nodalMotionFloating \bar{U}_R &= U_{R,\text{rigid}} ,\qquad @@ -2646,7 +2646,13 @@ 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) +**Motions**: nodal motions written to file are in global coordinates. +For the fixed-bottom case, they are :math:`\bar{U}_L = \bar{\Phi}_R \bar{U}_R + \Phi_m q_m + U_{L,\text{SIM}}` +(see Eq. :eq:`nodalMotionFixed`). +For the floating case, they are :math:`\bar{U}_L = U_{L,\text{rigid}} + R_{b2g}(\Phi_m q_m + U_{L,\text{SIM}})`. +Note that the outputs for the floating case contains the elastic motions (similar to what is returned to MoorDyn), whereas these motions are not returned to the glue code for HydroDyn (see the "0" present in Eq. :eq:`nodalMotionFloating`). + + **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/glue-codes/CMakeLists.txt b/glue-codes/CMakeLists.txt index 79a1a66df..84f808077 100644 --- a/glue-codes/CMakeLists.txt +++ b/glue-codes/CMakeLists.txt @@ -8,3 +8,7 @@ endif() if(BUILD_FASTFARM) add_subdirectory(fast-farm) endif() + +if(BUILD_OPENFAST_SIMULINK_API) + add_subdirectory(simulink) +endif() \ No newline at end of file diff --git a/glue-codes/fast-farm/CMakeLists.txt b/glue-codes/fast-farm/CMakeLists.txt index 40507fc30..7a55fe38f 100644 --- a/glue-codes/fast-farm/CMakeLists.txt +++ b/glue-codes/fast-farm/CMakeLists.txt @@ -19,42 +19,35 @@ if (GENERATE_TYPES) generate_f90_types(src/FAST_Farm_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/FAST_Farm_Types.f90 -noextrap) endif() -FIND_PACKAGE( OpenMP ) -if (NOT ${OPENMP_Fortran_FOUND} ) - message(FATAL_ERROR "CMake could not find the OpenMP Fortran libraries.") -endif() - -if(OPENMP_FOUND) - set(CMAKE_FORTRAN_FLAGS "${CMAKE_FORTRAN_FLAGS} ${OpenMP_FORTRAN_FLAGS}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") -endif() - add_executable(FAST.Farm src/FAST_Farm_IO.f90 + src/FAST_Farm_IO_Params.f90 src/FAST_Farm_Subs.f90 src/FASTWrapper.f90 src/FAST_Farm.f90 src/FAST_Farm_Types.f90 - src/FASTWrapper_Types.f90) - -target_link_libraries(FAST.Farm openfast_postlib openfast_prelib nwtclibs scfastlib sctypeslib awaelib wdlib) + src/FASTWrapper_Types.f90 +) +target_link_libraries(FAST.Farm openfastlib_static wdlib awaelib) set_property(TARGET FAST.Farm PROPERTY LINKER_LANGUAGE Fortran) 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") +if (${_compiler_id} STREQUAL "GNU" AND NOT ${VARIABLE_TRACKING}) # 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. + # restarts with this option off. Disabling avoids this problem when compiling with + # full optimizations. However, variable tracking should be enabled when actively debugging + # for better runtime debugging output. # https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html - set_source_files_properties(src/FAST_Farm_Types.f90 src/FASTWrapper_Types.f90 PROPERTIES COMPILE_FLAGS "-fno-var-tracking -fno-var-tracking-assignments") -endif() -if (${_compiler_id} MATCHES "^INTEL" AND ${_build_type} STREQUAL "RELEASE" AND NOT WIN32) + set_source_files_properties(src/FAST_Farm_Types.f90 src/FASTWrapper_Types.f90 src/FASTWrapper.f90 PROPERTIES COMPILE_FLAGS "-fno-var-tracking -fno-var-tracking-assignments") + set_source_files_properties(src/FAST_Farm_IO.f90 PROPERTIES COMPILE_FLAGS "-fno-var-tracking -fno-var-tracking-assignments") + set_source_files_properties(src/FAST_Farm_Subs.f90 PROPERTIES COMPILE_FLAGS "-fno-var-tracking -fno-var-tracking-assignments") + set_source_files_properties(src/FAST_Farm.f90 PROPERTIES COMPILE_FLAGS "-fno-var-tracking -fno-var-tracking-assignments") +elseif (${_compiler_id} MATCHES "^INTEL" AND ${_build_type} STREQUAL "RELEASE" AND NOT WIN32) # Compilation hangs on FAST_Farm_Types.f90 with -O3 on linux (on some hardware) set_source_files_properties(src/FAST_Farm_Types.f90 PROPERTIES COMPILE_FLAGS "-O2") endif() install(TARGETS FAST.Farm - RUNTIME DESTINATION bin) + RUNTIME DESTINATION bin +) diff --git a/glue-codes/fast-farm/src/FASTWrapper.f90 b/glue-codes/fast-farm/src/FASTWrapper.f90 index 2a922ed67..903666cb4 100644 --- a/glue-codes/fast-farm/src/FASTWrapper.f90 +++ b/glue-codes/fast-farm/src/FASTWrapper.f90 @@ -44,6 +44,8 @@ MODULE FASTWrapper PUBLIC :: FWrap_t0 ! call to compute outputs at t0 [and initialize some more variables] PUBLIC :: FWrap_Increment ! call to update states to n+1 and compute outputs at n+1 + PUBLIC :: FWrap_SetInputs + PUBLIC :: FWrap_CalcOutput CONTAINS @@ -116,8 +118,7 @@ SUBROUTINE FWrap_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init !.... Lidar data (unused) .... ExternInitData%Tmax = InitInp%TMax - ExternInitData%SensorType = SensorType_None - ExternInitData%LidRadialVel = .false. + !.... supercontroller .... if ( InitInp%UseSC ) then @@ -140,6 +141,7 @@ SUBROUTINE FWrap_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init !.... multi-turbine options .... ExternInitData%TurbineID = InitInp%TurbNum ExternInitData%TurbinePos = InitInp%p_ref_Turbine + ExternInitData%WaveFieldMod = InitInp%WaveFieldMod ExternInitData%FarmIntegration = .true. ExternInitData%RootName = InitInp%RootName @@ -182,7 +184,7 @@ SUBROUTINE FWrap_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init return end if - call move_alloc(m%Turbine%IfW%m%FDext%V, u%Vdist_High) + call move_alloc(m%Turbine%IfW%p%FlowField%Grid4D%Vel, u%Vdist_High) !................. @@ -201,6 +203,7 @@ SUBROUTINE FWrap_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init !................. call AllocAry(y%AzimAvg_Ct, p%nr, 'y%AzimAvg_Ct (azimuth-averaged ct)', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call AllocAry(y%AzimAvg_Cq, p%nr, 'y%AzimAvg_Cq (azimuth-averaged cq)', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if ( InitInp%UseSC ) then call AllocAry(y%toSC, InitInp%NumCtrl2SC, 'y%toSC (turbine controller outputs to Super Controller)', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -286,11 +289,11 @@ end subroutine cleanup END SUBROUTINE FWrap_Init !---------------------------------------------------------------------------------------------------------------------------------- ! this routine sets the parameters for the FAST Wrapper module. It does not set p%n_FAST_low because we need to initialize FAST first. -subroutine FWrap_SetParameters(InitInp, p, dt_FAST, InitInp_dt_low, ErrStat, ErrMsg) +subroutine FWrap_SetParameters(InitInp, p, dt_FAST, dt_caller, ErrStat, ErrMsg) TYPE(FWrap_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization routine TYPE(FWrap_ParameterType), INTENT(INOUT) :: p !< Parameters REAL(DbKi), INTENT(IN ) :: dt_FAST !< time step for FAST - REAL(DbKi), INTENT(IN ) :: InitInp_dt_low !< time step for FAST.Farm + REAL(DbKi), INTENT(IN ) :: dt_caller !< time step that FWrap will be called at by FAST.Farm (if MooringMod>0, this will be smaller than DT_low) INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None @@ -317,22 +320,22 @@ subroutine FWrap_SetParameters(InitInp, p, dt_FAST, InitInp_dt_low, ErrStat, Err ! p%n_FAST_low has to be set AFTER we initialize FAST, because we need to know what the FAST time step is going to be. - IF ( EqualRealNos( dt_FAST, InitInp_dt_low ) ) THEN + IF ( EqualRealNos( dt_FAST, dt_caller ) ) THEN p%n_FAST_low = 1 ELSE - IF ( dt_FAST > InitInp_dt_low ) THEN + IF ( dt_FAST > dt_caller ) THEN ErrStat = ErrID_Fatal ErrMsg = "The FAST time step ("//TRIM(Num2LStr(dt_FAST))// & - " s) cannot be larger than FAST.Farm time step ("//TRIM(Num2LStr(InitInp_dt_low))//" s)." + " s) cannot be larger than FAST.Farm time step ("//TRIM(Num2LStr(dt_caller))//" s)." ELSE ! calculate the number of subcycles: - p%n_FAST_low = NINT( InitInp_dt_low / dt_FAST ) + p%n_FAST_low = NINT( dt_caller / dt_FAST ) ! let's make sure the FAST DT is an exact integer divisor of the global (FAST.Farm) time step: - IF ( .NOT. EqualRealNos( InitInp_dt_low, dt_FAST * p%n_FAST_low ) ) THEN + IF ( .NOT. EqualRealNos( dt_caller, dt_FAST * p%n_FAST_low ) ) THEN ErrStat = ErrID_Fatal ErrMsg = "The FASTWrapper module time step ("//TRIM(Num2LStr(dt_FAST))// & - " s) must be an integer divisor of the FAST.Farm time step ("//TRIM(Num2LStr(InitInp_dt_low))//" s)." + " s) must be an integer divisor of the FAST.Farm or farm-level mooring time step ("//TRIM(Num2LStr(dt_caller))//" s)." END IF END IF @@ -411,7 +414,7 @@ END SUBROUTINE FWrap_End SUBROUTINE FWrap_Increment( t, n, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) !.................................................................................................................................. - REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds + REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds (no longer used, since inputs are set elsewhere) INTEGER(IntKi), INTENT(IN ) :: n !< Current step of the simulation: t = n*Interval TYPE(FWrap_InputType), INTENT(INOUT) :: u !< Inputs at t (not changed, but possibly copied) TYPE(FWrap_ParameterType), INTENT(IN ) :: p !< Parameters @@ -451,11 +454,11 @@ SUBROUTINE FWrap_Increment( t, n, u, p, x, xd, z, OtherState, y, m, ErrStat, Err !ELSE ! ! set the inputs needed for FAST - call FWrap_SetInputs(u, m, t) + !call FWrap_SetInputs(u, m, t) <<< moved up into FAST.Farm FARM_UpdateStates - ! call FAST p%n_FAST_low times: - do n_ss = 1, p%n_FAST_low - n_FAST = n*p%n_FAST_low + n_ss - 1 + ! call FAST p%n_FAST_low times (p%n_FAST_low is simply the number of steps to make per wrapper call. It is affected by MooringMod) + do n_ss = 1, p%n_FAST_low + n_FAST = n*p%n_FAST_low + n_ss - 1 CALL FAST_Solution_T( t_initial, n_FAST, m%Turbine, ErrStat2, ErrMsg2 ) call setErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -463,8 +466,8 @@ SUBROUTINE FWrap_Increment( t, n, u, p, x, xd, z, OtherState, y, m, ErrStat, Err end do ! n_ss - call FWrap_CalcOutput(p, u, y, m, ErrStat2, ErrMsg2) - call setErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + !call FWrap_CalcOutput(p, u, y, m, ErrStat2, ErrMsg2) <<< moved up into FAST.Farm FARM_UpdateStates + ! call setErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) !END IF @@ -513,6 +516,7 @@ END SUBROUTINE FWrap_t0 !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine sets the FASTWrapper outputs based on what this instance of FAST computed. SUBROUTINE FWrap_CalcOutput(p, u, y, m, ErrStat, ErrMsg) + use AeroDyn_IO, only: Calc_Chi0 TYPE(FWrap_ParameterType), INTENT(IN ) :: p !< Parameters TYPE(FWrap_InputType), INTENT(INOUT) :: u !< Inputs at t @@ -527,8 +531,16 @@ SUBROUTINE FWrap_CalcOutput(p, u, y, m, ErrStat, ErrMsg) REAL(ReKi) :: num ! numerator REAL(ReKi) :: denom ! denominator REAL(ReKi) :: p0(3) ! hub location (in FAST with 0,0,0 as turbine reference) + REAL(ReKi) :: yHat_plane(3) ! horizontal unit vector normal to xhat + REAL(ReKi) :: zHat_plane(3) ! nominally vertical + REAL(ReKi) :: zHat_Disk(3) REAL(R8Ki) :: theta(3) REAL(R8Ki) :: orientation(3,3) + REAL(ReKi) :: tmp_sz_z, tmp_sz_y + + REAL(ReKi) :: xSkew(3) + REAL(ReKi) :: ySkew(3) + REAL(ReKi) :: zSkew(3) INTEGER(IntKi) :: j, k ! loop counters @@ -544,7 +556,7 @@ SUBROUTINE FWrap_CalcOutput(p, u, y, m, ErrStat, ErrMsg) ErrMsg = '' ! put this back! - call move_alloc(m%Turbine%IfW%m%FDext%V, u%Vdist_High) + call move_alloc(m%Turbine%IfW%p%FlowField%Grid4D%Vel, u%Vdist_High) ! Turbine-dependent commands to the super controller: @@ -593,10 +605,10 @@ SUBROUTINE FWrap_CalcOutput(p, u, y, m, ErrStat, ErrMsg) ! Rotor-disk-averaged relative wind speed (ambient + deficits + motion), normal to disk, m/s y%DiskAvg_Vx_Rel = m%Turbine%AD%m%rotors(1)%V_dot_x - + ! Azimuthally averaged thrust force coefficient (normal to disk), distributed radially theta = 0.0_ReKi - do k=1,size(m%ADRotorDisk) + do k=1,size(m%ADRotorDisk) ! loop on blades m%TempDisp(k)%RefOrientation = m%Turbine%AD%Input(1)%rotors(1)%BladeMotion(k)%Orientation m%TempDisp(k)%Position = m%Turbine%AD%Input(1)%rotors(1)%BladeMotion(k)%Position + m%Turbine%AD%Input(1)%rotors(1)%BladeMotion(k)%TranslationDisp @@ -619,25 +631,77 @@ SUBROUTINE FWrap_CalcOutput(p, u, y, m, ErrStat, ErrMsg) if (ErrStat >= AbortErrLev) return end do + ! --- Ct and Cq on polar grid (goes beyond rotor radius) if (EqualRealNos(y%DiskAvg_Vx_Rel,0.0_ReKi)) then y%AzimAvg_Ct = 0.0_ReKi + y%AzimAvg_Cq = 0.0_ReKi else y%AzimAvg_Ct(1) = 0.0_ReKi + y%AzimAvg_Cq(1) = 0.0_ReKi do j=2,p%nr + denom = m%Turbine%AD%p%rotors(1)%AirDens * pi * p%r(j) * y%DiskAvg_Vx_Rel**2 + + ! Thrust coefficient + ! Ct(r) = dT/dr / (1/2 rho pi r U_rel^2 ), with dT/dr = sum_iB dFn/dr num = 0.0_ReKi - do k=1,size(m%ADRotorDisk) + do k=1,size(m%ADRotorDisk) ! loop on blades force contribution num = num + dot_product( y%xHat_Disk, m%ADRotorDisk(k)%Force(:,j) ) end do - - denom = m%Turbine%AD%p%rotors(1)%AirDens * pi * p%r(j) * y%DiskAvg_Vx_Rel**2 - y%AzimAvg_Ct(j) = num / denom + + ! Torque coefficient + ! Cq = dQ/dr / (1/2 rho pi r^2 U_rel^2) dQ/dr = sum_iB r dFt/dr + num = 0.0_ReKi + do k=1,size(m%ADRotorDisk) ! loop on blades force contribution + num = num - p%r(j)*dot_product(m%ADRotorDisk(k)%RefOrientation(2,:,1), m%ADRotorDisk(k)%Force(:,j) ) + dot_product(y%xHat_Disk, m%ADRotorDisk(k)%Moment(:,j) ) + end do + y%AzimAvg_Cq(j) = num / (denom * p%r(j) ) end do end if + ! --- Variables needed to orient wake planes in "skew" coordinate system + ! chi_skew and psi_skew + y%chi_skew = Calc_Chi0(m%Turbine%AD%m%rotors(1)%V_diskAvg, m%turbine%AD%m%rotors(1)%V_dot_x) ! AeroDyn_IO + + ! TODO place me in an AeroDyn Function like Calc_Chi0 + ! Construct y_hat, orthogonal to x_hat when its z component is neglected (in a projected horizontal plane) + yHat_plane(1:3) = (/ -y%xHat_Disk(2), y%xHat_Disk(1), 0.0_ReKi /) + yHat_plane(1:3) = yHat_plane/TwoNorm(yHat_plane) + ! Construct z_hat + zHat_plane(1) = -y%xHat_Disk(1)*y%xHat_Disk(3) + zHat_plane(2) = -y%xHat_Disk(2)*y%xHat_Disk(3) + zHat_plane(3) = y%xHat_Disk(1)*y%xHat_Disk(1) + y%xHat_Disk(2)*y%xHat_Disk(2) + zHat_plane(1:3) = zHat_plane/TwoNorm(zHat_plane) + +!~ zHat_Disk = m%Turbine%AD%Input(1)%rotors(1)%HubMotion%Orientation(3,:,1) ! TODO TODO, shoudn't rotate + + ! Skew system (y and z are in disk plane, x is normal to disk, y is in the cross-flow direction formed by the diskavg velocity) + xSkew = y%xHat_Disk + ySkew = y%xHat_Disk - m%Turbine%AD%m%rotors(1)%V_diskAvg + denom = TwoNorm(ySkew) + if (EqualRealNos(denom, 0.0_ReKi)) then + ! There is no skew + ySkew = yHat_plane + zSkew = zHat_plane + else + ySkew = ySkew / denom + zSkew(1) = xSkew(2) * ySkew(3) - xSkew(3) * ySkew(2) + zSkew(2) = xSkew(3) * ySkew(1) - xSkew(1) * ySkew(3) + zSkew(3) = xSkew(1) * ySkew(2) - xSkew(2) * ySkew(1) + endif + zHat_Disk = zSkew + + tmp_sz_y = -1.0_ReKi * dot_product(zHat_Disk,yHat_plane) + tmp_sz_z = dot_product(zHat_Disk,zHat_plane) + if ( EqualRealNos(tmp_sz_y,0.0_ReKi) .and. EqualRealNos(tmp_sz_z,0.0_ReKi) ) then + y%psi_skew = 0.0_ReKi + else + y%psi_skew = atan2( tmp_sz_y, tmp_sz_z ) + end if + END SUBROUTINE FWrap_CalcOutput !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine sets the inputs needed before calling an instance of FAST @@ -648,8 +712,8 @@ SUBROUTINE FWrap_SetInputs(u, m, t) REAL(DbKi), INTENT(IN ) :: t !< current simulation time ! set the 4d-wind-inflow input array (a bit of a hack [simplification] so that we don't have large amounts of data copied in multiple data structures): - call move_alloc(u%Vdist_High, m%Turbine%IfW%m%FDext%V) - m%Turbine%IfW%m%FDext%TgridStart = t + call move_alloc(u%Vdist_High, m%Turbine%IfW%p%FlowField%Grid4D%Vel) + m%Turbine%IfW%p%FlowField%Grid4D%TimeStart = t ! do something with the inputs from the super-controller: if ( m%Turbine%p_FAST%UseSC ) then diff --git a/glue-codes/fast-farm/src/FASTWrapper_Registry.txt b/glue-codes/fast-farm/src/FASTWrapper_Registry.txt index 7cf5303c5..5dedfed49 100644 --- a/glue-codes/fast-farm/src/FASTWrapper_Registry.txt +++ b/glue-codes/fast-farm/src/FASTWrapper_Registry.txt @@ -22,6 +22,7 @@ typedef ^ InitInputType CHARACTER(1024) FASTInFile typedef ^ InitInputType ReKi dr - - - "Radial increment of radial finite-difference grid" m typedef ^ InitInputType DbKi tmax - - - "Simulation length" s typedef ^ InitInputType ReKi p_ref_Turbine {3} - - "Undisplaced global coordinates of this turbine" m +typedef ^ InitInputType IntKi WaveFieldMod - - - "Wave field handling (-) (switch) 0: use individual HydroDyn inputs without adjustment, 1: adjust wave phases based on turbine offsets from farm origin" - typedef ^ InitInputType IntKi n_high_low - - - "Number of high-resolution time steps per low-resolution time step" - typedef ^ InitInputType DbKi dt_high - - - "High-resolution time step" s typedef ^ InitInputType ReKi p_ref_high {3} - - "Position of the origin of the high-resolution spatial domain for this turbine" m @@ -43,6 +44,7 @@ typedef ^ InitInputType SiKi fromSC # Define outputs from the initialization routine here: #typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "Names of the output-to-file channels" - #typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {:} - - "Units of the output-to-file channels" - +typedef ^ InitOutputType DbKi PtfmInit {6} - - "Initial platform position/rotation vector - surge,sway,heave,roll,pitch,yaw - needed for mooring module initInp" - typedef ^ InitOutputType ProgDesc Ver - - - "This module's name, version, and date" - @@ -90,8 +92,11 @@ typedef ^ InputType SiKi Vdist_High {:}{:}{: typedef ^ OutputType SiKi toSC {:} - - "Turbine-dependent commands to the super controller" "(various units)" typedef ^ OutputType ReKi xHat_Disk {3} - - "Orientation of rotor centerline, normal to disk" "-" typedef ^ OutputType ReKi YawErr - - - "Nacelle-yaw error i.e. the angle about positive Z^ from the rotor centerline to the rotor-disk-averaged relative wind velocity (ambients + deficits + motion), both projected onto the horizontal plane" "rad" +typedef ^ OutputType ReKi psi_skew - - - "Azimuth angle from the nominally vertical axis in the disk plane to the vector about which the inflow skew angle is defined" rad +typedef ^ OutputType ReKi chi_skew - - - "Inflow skew angle" rad typedef ^ OutputType ReKi p_hub {3} - - "Center position of hub" "m" typedef ^ OutputType ReKi D_rotor - - - "Rotor diameter" "m" typedef ^ OutputType ReKi DiskAvg_Vx_Rel - - - "Rotor-disk-averaged relative wind speed (ambient + deficits + motion), normal to disk" "m/s" typedef ^ OutputType ReKi AzimAvg_Ct {:} - - "Azimuthally averaged thrust force coefficient (normal to disk), distributed radially" "-" +typedef ^ OutputType ReKi AzimAvg_Cq {:} - - "Azimuthally averaged torque coefficient (normal to disk), distributed radially" "-" diff --git a/glue-codes/fast-farm/src/FASTWrapper_Types.f90 b/glue-codes/fast-farm/src/FASTWrapper_Types.f90 index 3e0fc25cc..8c003fc95 100644 --- a/glue-codes/fast-farm/src/FASTWrapper_Types.f90 +++ b/glue-codes/fast-farm/src/FASTWrapper_Types.f90 @@ -41,6 +41,7 @@ MODULE FASTWrapper_Types REAL(ReKi) :: dr !< Radial increment of radial finite-difference grid [m] REAL(DbKi) :: tmax !< Simulation length [s] REAL(ReKi) , DIMENSION(1:3) :: p_ref_Turbine !< Undisplaced global coordinates of this turbine [m] + INTEGER(IntKi) :: WaveFieldMod !< Wave field handling (-) (switch) 0: use individual HydroDyn inputs without adjustment, 1: adjust wave phases based on turbine offsets from farm origin [-] INTEGER(IntKi) :: n_high_low !< Number of high-resolution time steps per low-resolution time step [-] REAL(DbKi) :: dt_high !< High-resolution time step [s] REAL(ReKi) , DIMENSION(1:3) :: p_ref_high !< Position of the origin of the high-resolution spatial domain for this turbine [m] @@ -62,6 +63,7 @@ MODULE FASTWrapper_Types ! ======================= ! ========= FWrap_InitOutputType ======= TYPE, PUBLIC :: FWrap_InitOutputType + REAL(DbKi) , DIMENSION(1:6) :: PtfmInit !< Initial platform position/rotation vector - surge,sway,heave,roll,pitch,yaw - needed for mooring module initInp [-] TYPE(ProgDesc) :: Ver !< This module's name, version, and date [-] END TYPE FWrap_InitOutputType ! ======================= @@ -114,10 +116,13 @@ MODULE FASTWrapper_Types REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: toSC !< Turbine-dependent commands to the super controller [(various units)] REAL(ReKi) , DIMENSION(1:3) :: xHat_Disk !< Orientation of rotor centerline, normal to disk [-] REAL(ReKi) :: YawErr !< Nacelle-yaw error i.e. the angle about positive Z^ from the rotor centerline to the rotor-disk-averaged relative wind velocity (ambients + deficits + motion), both projected onto the horizontal plane [rad] + REAL(ReKi) :: psi_skew !< Azimuth angle from the nominally vertical axis in the disk plane to the vector about which the inflow skew angle is defined [rad] + REAL(ReKi) :: chi_skew !< Inflow skew angle [rad] REAL(ReKi) , DIMENSION(1:3) :: p_hub !< Center position of hub [m] REAL(ReKi) :: D_rotor !< Rotor diameter [m] REAL(ReKi) :: DiskAvg_Vx_Rel !< Rotor-disk-averaged relative wind speed (ambient + deficits + motion), normal to disk [m/s] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AzimAvg_Ct !< Azimuthally averaged thrust force coefficient (normal to disk), distributed radially [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AzimAvg_Cq !< Azimuthally averaged torque coefficient (normal to disk), distributed radially [-] END TYPE FWrap_OutputType ! ======================= CONTAINS @@ -145,6 +150,7 @@ SUBROUTINE FWrap_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Er DstInitInputData%dr = SrcInitInputData%dr DstInitInputData%tmax = SrcInitInputData%tmax DstInitInputData%p_ref_Turbine = SrcInitInputData%p_ref_Turbine + DstInitInputData%WaveFieldMod = SrcInitInputData%WaveFieldMod DstInitInputData%n_high_low = SrcInitInputData%n_high_low DstInitInputData%dt_high = SrcInitInputData%dt_high DstInitInputData%p_ref_high = SrcInitInputData%p_ref_high @@ -186,15 +192,27 @@ SUBROUTINE FWrap_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Er ENDIF END SUBROUTINE FWrap_CopyInitInput - SUBROUTINE FWrap_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE FWrap_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FWrap_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%fromSCGlob)) THEN DEALLOCATE(InitInputData%fromSCGlob) ENDIF @@ -243,6 +261,7 @@ SUBROUTINE FWrap_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Re_BufSz = Re_BufSz + 1 ! dr Db_BufSz = Db_BufSz + 1 ! tmax Re_BufSz = Re_BufSz + SIZE(InData%p_ref_Turbine) ! p_ref_Turbine + Int_BufSz = Int_BufSz + 1 ! WaveFieldMod Int_BufSz = Int_BufSz + 1 ! n_high_low Db_BufSz = Db_BufSz + 1 ! dt_high Re_BufSz = Re_BufSz + SIZE(InData%p_ref_high) ! p_ref_high @@ -309,6 +328,8 @@ SUBROUTINE FWrap_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err ReKiBuf(Re_Xferred) = InData%p_ref_Turbine(i1) Re_Xferred = Re_Xferred + 1 END DO + IntKiBuf(Int_Xferred) = InData%WaveFieldMod + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%n_high_low Int_Xferred = Int_Xferred + 1 DbKiBuf(Db_Xferred) = InData%dt_high @@ -422,6 +443,8 @@ SUBROUTINE FWrap_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, OutData%p_ref_Turbine(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO + OutData%WaveFieldMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%n_high_low = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%dt_high = DbKiBuf(Db_Xferred) @@ -504,27 +527,42 @@ SUBROUTINE FWrap_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 = 'FWrap_CopyInitOutput' ! ErrStat = ErrID_None ErrMsg = "" + DstInitOutputData%PtfmInit = SrcInitOutputData%PtfmInit CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE FWrap_CopyInitOutput - SUBROUTINE FWrap_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE FWrap_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FWrap_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE FWrap_DestroyInitOutput SUBROUTINE FWrap_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -562,6 +600,7 @@ SUBROUTINE FWrap_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Db_BufSz = Db_BufSz + SIZE(InData%PtfmInit) ! PtfmInit ! 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 @@ -607,6 +646,10 @@ SUBROUTINE FWrap_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Db_Xferred = 1 Int_Xferred = 1 + DO i1 = LBOUND(InData%PtfmInit,1), UBOUND(InData%PtfmInit,1) + DbKiBuf(Db_Xferred) = InData%PtfmInit(i1) + Db_Xferred = Db_Xferred + 1 + END DO 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 @@ -650,6 +693,7 @@ SUBROUTINE FWrap_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 = 'FWrap_UnPackInitOutput' @@ -663,6 +707,12 @@ SUBROUTINE FWrap_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 + i1_l = LBOUND(OutData%PtfmInit,1) + i1_u = UBOUND(OutData%PtfmInit,1) + DO i1 = LBOUND(OutData%PtfmInit,1), UBOUND(OutData%PtfmInit,1) + OutData%PtfmInit(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -722,15 +772,27 @@ SUBROUTINE FWrap_CopyContState( SrcContStateData, DstContStateData, CtrlCode, Er DstContStateData%dummy = SrcContStateData%dummy END SUBROUTINE FWrap_CopyContState - SUBROUTINE FWrap_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE FWrap_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FWrap_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE FWrap_DestroyContState SUBROUTINE FWrap_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -847,15 +909,27 @@ SUBROUTINE FWrap_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, Er DstDiscStateData%dummy = SrcDiscStateData%dummy END SUBROUTINE FWrap_CopyDiscState - SUBROUTINE FWrap_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE FWrap_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FWrap_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE FWrap_DestroyDiscState SUBROUTINE FWrap_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -972,15 +1046,27 @@ SUBROUTINE FWrap_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCo DstConstrStateData%dummy = SrcConstrStateData%dummy END SUBROUTINE FWrap_CopyConstrState - SUBROUTINE FWrap_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE FWrap_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FWrap_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE FWrap_DestroyConstrState SUBROUTINE FWrap_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1097,15 +1183,27 @@ SUBROUTINE FWrap_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, DstOtherStateData%dummy = SrcOtherStateData%dummy END SUBROUTINE FWrap_CopyOtherState - SUBROUTINE FWrap_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE FWrap_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FWrap_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE FWrap_DestroyOtherState SUBROUTINE FWrap_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1289,37 +1387,54 @@ SUBROUTINE FWrap_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) ENDIF END SUBROUTINE FWrap_CopyMisc - SUBROUTINE FWrap_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE FWrap_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FWrap_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" - CALL FAST_Destroyturbinetype( MiscData%Turbine, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL FAST_Destroyturbinetype( MiscData%Turbine, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MiscData%TempDisp)) THEN DO i1 = LBOUND(MiscData%TempDisp,1), UBOUND(MiscData%TempDisp,1) - CALL MeshDestroy( MiscData%TempDisp(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( MiscData%TempDisp(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%TempDisp) ENDIF IF (ALLOCATED(MiscData%TempLoads)) THEN DO i1 = LBOUND(MiscData%TempLoads,1), UBOUND(MiscData%TempLoads,1) - CALL MeshDestroy( MiscData%TempLoads(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( MiscData%TempLoads(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%TempLoads) ENDIF IF (ALLOCATED(MiscData%ADRotorDisk)) THEN DO i1 = LBOUND(MiscData%ADRotorDisk,1), UBOUND(MiscData%ADRotorDisk,1) - CALL MeshDestroy( MiscData%ADRotorDisk(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( MiscData%ADRotorDisk(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%ADRotorDisk) ENDIF IF (ALLOCATED(MiscData%AD_L2L)) THEN DO i1 = LBOUND(MiscData%AD_L2L,1), UBOUND(MiscData%AD_L2L,1) - CALL NWTC_Library_Destroymeshmaptype( MiscData%AD_L2L(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( MiscData%AD_L2L(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%AD_L2L) ENDIF @@ -2016,15 +2131,27 @@ SUBROUTINE FWrap_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMs DstParamData%p_ref_Turbine = SrcParamData%p_ref_Turbine END SUBROUTINE FWrap_CopyParam - SUBROUTINE FWrap_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE FWrap_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FWrap_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%r)) THEN DEALLOCATE(ParamData%r) ENDIF @@ -2247,15 +2374,27 @@ SUBROUTINE FWrap_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMs ENDIF END SUBROUTINE FWrap_CopyInput - SUBROUTINE FWrap_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE FWrap_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FWrap_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%fromSCglob)) THEN DEALLOCATE(InputData%fromSCglob) ENDIF @@ -2547,6 +2686,8 @@ SUBROUTINE FWrap_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Er ENDIF DstOutputData%xHat_Disk = SrcOutputData%xHat_Disk DstOutputData%YawErr = SrcOutputData%YawErr + DstOutputData%psi_skew = SrcOutputData%psi_skew + DstOutputData%chi_skew = SrcOutputData%chi_skew DstOutputData%p_hub = SrcOutputData%p_hub DstOutputData%D_rotor = SrcOutputData%D_rotor DstOutputData%DiskAvg_Vx_Rel = SrcOutputData%DiskAvg_Vx_Rel @@ -2561,23 +2702,50 @@ SUBROUTINE FWrap_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Er END IF END IF DstOutputData%AzimAvg_Ct = SrcOutputData%AzimAvg_Ct +ENDIF +IF (ALLOCATED(SrcOutputData%AzimAvg_Cq)) THEN + i1_l = LBOUND(SrcOutputData%AzimAvg_Cq,1) + i1_u = UBOUND(SrcOutputData%AzimAvg_Cq,1) + IF (.NOT. ALLOCATED(DstOutputData%AzimAvg_Cq)) THEN + ALLOCATE(DstOutputData%AzimAvg_Cq(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%AzimAvg_Cq.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%AzimAvg_Cq = SrcOutputData%AzimAvg_Cq ENDIF END SUBROUTINE FWrap_CopyOutput - SUBROUTINE FWrap_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE FWrap_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FWrap_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FWrap_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%toSC)) THEN DEALLOCATE(OutputData%toSC) ENDIF IF (ALLOCATED(OutputData%AzimAvg_Ct)) THEN DEALLOCATE(OutputData%AzimAvg_Ct) +ENDIF +IF (ALLOCATED(OutputData%AzimAvg_Cq)) THEN + DEALLOCATE(OutputData%AzimAvg_Cq) ENDIF END SUBROUTINE FWrap_DestroyOutput @@ -2623,6 +2791,8 @@ SUBROUTINE FWrap_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg END IF Re_BufSz = Re_BufSz + SIZE(InData%xHat_Disk) ! xHat_Disk Re_BufSz = Re_BufSz + 1 ! YawErr + Re_BufSz = Re_BufSz + 1 ! psi_skew + Re_BufSz = Re_BufSz + 1 ! chi_skew Re_BufSz = Re_BufSz + SIZE(InData%p_hub) ! p_hub Re_BufSz = Re_BufSz + 1 ! D_rotor Re_BufSz = Re_BufSz + 1 ! DiskAvg_Vx_Rel @@ -2631,6 +2801,11 @@ SUBROUTINE FWrap_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 2*1 ! AzimAvg_Ct upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%AzimAvg_Ct) ! AzimAvg_Ct END IF + Int_BufSz = Int_BufSz + 1 ! AzimAvg_Cq allocated yes/no + IF ( ALLOCATED(InData%AzimAvg_Cq) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AzimAvg_Cq upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AzimAvg_Cq) ! AzimAvg_Cq + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -2679,6 +2854,10 @@ SUBROUTINE FWrap_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg END DO ReKiBuf(Re_Xferred) = InData%YawErr Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%psi_skew + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%chi_skew + Re_Xferred = Re_Xferred + 1 DO i1 = LBOUND(InData%p_hub,1), UBOUND(InData%p_hub,1) ReKiBuf(Re_Xferred) = InData%p_hub(i1) Re_Xferred = Re_Xferred + 1 @@ -2702,6 +2881,21 @@ SUBROUTINE FWrap_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%AzimAvg_Cq) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AzimAvg_Cq,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AzimAvg_Cq,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AzimAvg_Cq,1), UBOUND(InData%AzimAvg_Cq,1) + ReKiBuf(Re_Xferred) = InData%AzimAvg_Cq(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE FWrap_PackOutput SUBROUTINE FWrap_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -2757,6 +2951,10 @@ SUBROUTINE FWrap_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END DO OutData%YawErr = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%psi_skew = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%chi_skew = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 i1_l = LBOUND(OutData%p_hub,1) i1_u = UBOUND(OutData%p_hub,1) DO i1 = LBOUND(OutData%p_hub,1), UBOUND(OutData%p_hub,1) @@ -2785,6 +2983,24 @@ SUBROUTINE FWrap_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AzimAvg_Cq not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AzimAvg_Cq)) DEALLOCATE(OutData%AzimAvg_Cq) + ALLOCATE(OutData%AzimAvg_Cq(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AzimAvg_Cq.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AzimAvg_Cq,1), UBOUND(OutData%AzimAvg_Cq,1) + OutData%AzimAvg_Cq(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE FWrap_UnPackOutput END MODULE FASTWrapper_Types diff --git a/glue-codes/fast-farm/src/FAST_Farm_IO.f90 b/glue-codes/fast-farm/src/FAST_Farm_IO.f90 index 27a30607e..1f05d256f 100644 --- a/glue-codes/fast-farm/src/FAST_Farm_IO.f90 +++ b/glue-codes/fast-farm/src/FAST_Farm_IO.f90 @@ -1,9729 +1,12 @@ module FAST_Farm_IO -USE NWTC_Library -USE FAST_Farm_Types - -IMPLICIT NONE - ! The maximum number of output channels which can be output by the code. -INTEGER(IntKi), PARAMETER :: Farm_MaxOutPts = 9423 -TYPE(ProgDesc), PARAMETER :: Farm_Ver = ProgDesc( 'FAST.Farm', '', '' ) !< module date/version information -! =================================================================================================== -! NOTE: The following lines of code were generated by a Matlab script called "Write_ChckOutLst.m" -! using the parameters listed in the "OutListParameters3.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 13-Mar-2017 10:34:09. - - - ! Parameters related to output length (number of characters allowed in the output data headers): - - INTEGER(IntKi), PARAMETER :: Farm_OutStrLenM1 = ChanLen - 1 - - - ! 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 :: Farm_Time_Indx = 0 - - - ! Global Super Controller Input: - - INTEGER(IntKi), PARAMETER :: SCGblIn1 = 1 - INTEGER(IntKi), PARAMETER :: SCGblIn2 = 2 - INTEGER(IntKi), PARAMETER :: SCGblIn3 = 3 - INTEGER(IntKi), PARAMETER :: SCGblIn4 = 4 - INTEGER(IntKi), PARAMETER :: SCGblIn5 = 5 - INTEGER(IntKi), PARAMETER :: SCGblIn6 = 6 - INTEGER(IntKi), PARAMETER :: SCGblIn7 = 7 - INTEGER(IntKi), PARAMETER :: SCGblIn8 = 8 - INTEGER(IntKi), PARAMETER :: SCGblIn9 = 9 - - - ! Turbine-dependent Super Controller Input: - - INTEGER(IntKi), PARAMETER :: SCT1In1 = 10 - INTEGER(IntKi), PARAMETER :: SCT1In2 = 11 - INTEGER(IntKi), PARAMETER :: SCT1In3 = 12 - INTEGER(IntKi), PARAMETER :: SCT1In4 = 13 - INTEGER(IntKi), PARAMETER :: SCT1In5 = 14 - INTEGER(IntKi), PARAMETER :: SCT1In6 = 15 - INTEGER(IntKi), PARAMETER :: SCT1In7 = 16 - INTEGER(IntKi), PARAMETER :: SCT1In8 = 17 - INTEGER(IntKi), PARAMETER :: SCT1In9 = 18 - INTEGER(IntKi), PARAMETER :: SCT2In1 = 19 - INTEGER(IntKi), PARAMETER :: SCT2In2 = 20 - INTEGER(IntKi), PARAMETER :: SCT2In3 = 21 - INTEGER(IntKi), PARAMETER :: SCT2In4 = 22 - INTEGER(IntKi), PARAMETER :: SCT2In5 = 23 - INTEGER(IntKi), PARAMETER :: SCT2In6 = 24 - INTEGER(IntKi), PARAMETER :: SCT2In7 = 25 - INTEGER(IntKi), PARAMETER :: SCT2In8 = 26 - INTEGER(IntKi), PARAMETER :: SCT2In9 = 27 - INTEGER(IntKi), PARAMETER :: SCT3In1 = 28 - INTEGER(IntKi), PARAMETER :: SCT3In2 = 29 - INTEGER(IntKi), PARAMETER :: SCT3In3 = 30 - INTEGER(IntKi), PARAMETER :: SCT3In4 = 31 - INTEGER(IntKi), PARAMETER :: SCT3In5 = 32 - INTEGER(IntKi), PARAMETER :: SCT3In6 = 33 - INTEGER(IntKi), PARAMETER :: SCT3In7 = 34 - INTEGER(IntKi), PARAMETER :: SCT3In8 = 35 - INTEGER(IntKi), PARAMETER :: SCT3In9 = 36 - INTEGER(IntKi), PARAMETER :: SCT4In1 = 37 - INTEGER(IntKi), PARAMETER :: SCT4In2 = 38 - INTEGER(IntKi), PARAMETER :: SCT4In3 = 39 - INTEGER(IntKi), PARAMETER :: SCT4In4 = 40 - INTEGER(IntKi), PARAMETER :: SCT4In5 = 41 - INTEGER(IntKi), PARAMETER :: SCT4In6 = 42 - INTEGER(IntKi), PARAMETER :: SCT4In7 = 43 - INTEGER(IntKi), PARAMETER :: SCT4In8 = 44 - INTEGER(IntKi), PARAMETER :: SCT4In9 = 45 - INTEGER(IntKi), PARAMETER :: SCT5In1 = 46 - INTEGER(IntKi), PARAMETER :: SCT5In2 = 47 - INTEGER(IntKi), PARAMETER :: SCT5In3 = 48 - INTEGER(IntKi), PARAMETER :: SCT5In4 = 49 - INTEGER(IntKi), PARAMETER :: SCT5In5 = 50 - INTEGER(IntKi), PARAMETER :: SCT5In6 = 51 - INTEGER(IntKi), PARAMETER :: SCT5In7 = 52 - INTEGER(IntKi), PARAMETER :: SCT5In8 = 53 - INTEGER(IntKi), PARAMETER :: SCT5In9 = 54 - INTEGER(IntKi), PARAMETER :: SCT6In1 = 55 - INTEGER(IntKi), PARAMETER :: SCT6In2 = 56 - INTEGER(IntKi), PARAMETER :: SCT6In3 = 57 - INTEGER(IntKi), PARAMETER :: SCT6In4 = 58 - INTEGER(IntKi), PARAMETER :: SCT6In5 = 59 - INTEGER(IntKi), PARAMETER :: SCT6In6 = 60 - INTEGER(IntKi), PARAMETER :: SCT6In7 = 61 - INTEGER(IntKi), PARAMETER :: SCT6In8 = 62 - INTEGER(IntKi), PARAMETER :: SCT6In9 = 63 - INTEGER(IntKi), PARAMETER :: SCT7In1 = 64 - INTEGER(IntKi), PARAMETER :: SCT7In2 = 65 - INTEGER(IntKi), PARAMETER :: SCT7In3 = 66 - INTEGER(IntKi), PARAMETER :: SCT7In4 = 67 - INTEGER(IntKi), PARAMETER :: SCT7In5 = 68 - INTEGER(IntKi), PARAMETER :: SCT7In6 = 69 - INTEGER(IntKi), PARAMETER :: SCT7In7 = 70 - INTEGER(IntKi), PARAMETER :: SCT7In8 = 71 - INTEGER(IntKi), PARAMETER :: SCT7In9 = 72 - INTEGER(IntKi), PARAMETER :: SCT8In1 = 73 - INTEGER(IntKi), PARAMETER :: SCT8In2 = 74 - INTEGER(IntKi), PARAMETER :: SCT8In3 = 75 - INTEGER(IntKi), PARAMETER :: SCT8In4 = 76 - INTEGER(IntKi), PARAMETER :: SCT8In5 = 77 - INTEGER(IntKi), PARAMETER :: SCT8In6 = 78 - INTEGER(IntKi), PARAMETER :: SCT8In7 = 79 - INTEGER(IntKi), PARAMETER :: SCT8In8 = 80 - INTEGER(IntKi), PARAMETER :: SCT8In9 = 81 - INTEGER(IntKi), PARAMETER :: SCT9In1 = 82 - INTEGER(IntKi), PARAMETER :: SCT9In2 = 83 - INTEGER(IntKi), PARAMETER :: SCT9In3 = 84 - INTEGER(IntKi), PARAMETER :: SCT9In4 = 85 - INTEGER(IntKi), PARAMETER :: SCT9In5 = 86 - INTEGER(IntKi), PARAMETER :: SCT9In6 = 87 - INTEGER(IntKi), PARAMETER :: SCT9In7 = 88 - INTEGER(IntKi), PARAMETER :: SCT9In8 = 89 - INTEGER(IntKi), PARAMETER :: SCT9In9 = 90 - - - ! Global Super Controller Output: - - INTEGER(IntKi), PARAMETER :: SCGblOt1 = 91 - INTEGER(IntKi), PARAMETER :: SCGblOt2 = 92 - INTEGER(IntKi), PARAMETER :: SCGblOt3 = 93 - INTEGER(IntKi), PARAMETER :: SCGblOt4 = 94 - INTEGER(IntKi), PARAMETER :: SCGblOt5 = 95 - INTEGER(IntKi), PARAMETER :: SCGblOt6 = 96 - INTEGER(IntKi), PARAMETER :: SCGblOt7 = 97 - INTEGER(IntKi), PARAMETER :: SCGblOt8 = 98 - INTEGER(IntKi), PARAMETER :: SCGblOt9 = 99 - - - ! Turbine-dependent Super Controller Output: - - INTEGER(IntKi), PARAMETER :: SCT1Ot1 = 100 - INTEGER(IntKi), PARAMETER :: SCT1Ot2 = 101 - INTEGER(IntKi), PARAMETER :: SCT1Ot3 = 102 - INTEGER(IntKi), PARAMETER :: SCT1Ot4 = 103 - INTEGER(IntKi), PARAMETER :: SCT1Ot5 = 104 - INTEGER(IntKi), PARAMETER :: SCT1Ot6 = 105 - INTEGER(IntKi), PARAMETER :: SCT1Ot7 = 106 - INTEGER(IntKi), PARAMETER :: SCT1Ot8 = 107 - INTEGER(IntKi), PARAMETER :: SCT1Ot9 = 108 - INTEGER(IntKi), PARAMETER :: SCT2Ot1 = 109 - INTEGER(IntKi), PARAMETER :: SCT2Ot2 = 110 - INTEGER(IntKi), PARAMETER :: SCT2Ot3 = 111 - INTEGER(IntKi), PARAMETER :: SCT2Ot4 = 112 - INTEGER(IntKi), PARAMETER :: SCT2Ot5 = 113 - INTEGER(IntKi), PARAMETER :: SCT2Ot6 = 114 - INTEGER(IntKi), PARAMETER :: SCT2Ot7 = 115 - INTEGER(IntKi), PARAMETER :: SCT2Ot8 = 116 - INTEGER(IntKi), PARAMETER :: SCT2Ot9 = 117 - INTEGER(IntKi), PARAMETER :: SCT3Ot1 = 118 - INTEGER(IntKi), PARAMETER :: SCT3Ot2 = 119 - INTEGER(IntKi), PARAMETER :: SCT3Ot3 = 120 - INTEGER(IntKi), PARAMETER :: SCT3Ot4 = 121 - INTEGER(IntKi), PARAMETER :: SCT3Ot5 = 122 - INTEGER(IntKi), PARAMETER :: SCT3Ot6 = 123 - INTEGER(IntKi), PARAMETER :: SCT3Ot7 = 124 - INTEGER(IntKi), PARAMETER :: SCT3Ot8 = 125 - INTEGER(IntKi), PARAMETER :: SCT3Ot9 = 126 - INTEGER(IntKi), PARAMETER :: SCT4Ot1 = 127 - INTEGER(IntKi), PARAMETER :: SCT4Ot2 = 128 - INTEGER(IntKi), PARAMETER :: SCT4Ot3 = 129 - INTEGER(IntKi), PARAMETER :: SCT4Ot4 = 130 - INTEGER(IntKi), PARAMETER :: SCT4Ot5 = 131 - INTEGER(IntKi), PARAMETER :: SCT4Ot6 = 132 - INTEGER(IntKi), PARAMETER :: SCT4Ot7 = 133 - INTEGER(IntKi), PARAMETER :: SCT4Ot8 = 134 - INTEGER(IntKi), PARAMETER :: SCT4Ot9 = 135 - INTEGER(IntKi), PARAMETER :: SCT5Ot1 = 136 - INTEGER(IntKi), PARAMETER :: SCT5Ot2 = 137 - INTEGER(IntKi), PARAMETER :: SCT5Ot3 = 138 - INTEGER(IntKi), PARAMETER :: SCT5Ot4 = 139 - INTEGER(IntKi), PARAMETER :: SCT5Ot5 = 140 - INTEGER(IntKi), PARAMETER :: SCT5Ot6 = 141 - INTEGER(IntKi), PARAMETER :: SCT5Ot7 = 142 - INTEGER(IntKi), PARAMETER :: SCT5Ot8 = 143 - INTEGER(IntKi), PARAMETER :: SCT5Ot9 = 144 - INTEGER(IntKi), PARAMETER :: SCT6Ot1 = 145 - INTEGER(IntKi), PARAMETER :: SCT6Ot2 = 146 - INTEGER(IntKi), PARAMETER :: SCT6Ot3 = 147 - INTEGER(IntKi), PARAMETER :: SCT6Ot4 = 148 - INTEGER(IntKi), PARAMETER :: SCT6Ot5 = 149 - INTEGER(IntKi), PARAMETER :: SCT6Ot6 = 150 - INTEGER(IntKi), PARAMETER :: SCT6Ot7 = 151 - INTEGER(IntKi), PARAMETER :: SCT6Ot8 = 152 - INTEGER(IntKi), PARAMETER :: SCT6Ot9 = 153 - INTEGER(IntKi), PARAMETER :: SCT7Ot1 = 154 - INTEGER(IntKi), PARAMETER :: SCT7Ot2 = 155 - INTEGER(IntKi), PARAMETER :: SCT7Ot3 = 156 - INTEGER(IntKi), PARAMETER :: SCT7Ot4 = 157 - INTEGER(IntKi), PARAMETER :: SCT7Ot5 = 158 - INTEGER(IntKi), PARAMETER :: SCT7Ot6 = 159 - INTEGER(IntKi), PARAMETER :: SCT7Ot7 = 160 - INTEGER(IntKi), PARAMETER :: SCT7Ot8 = 161 - INTEGER(IntKi), PARAMETER :: SCT7Ot9 = 162 - INTEGER(IntKi), PARAMETER :: SCT8Ot1 = 163 - INTEGER(IntKi), PARAMETER :: SCT8Ot2 = 164 - INTEGER(IntKi), PARAMETER :: SCT8Ot3 = 165 - INTEGER(IntKi), PARAMETER :: SCT8Ot4 = 166 - INTEGER(IntKi), PARAMETER :: SCT8Ot5 = 167 - INTEGER(IntKi), PARAMETER :: SCT8Ot6 = 168 - INTEGER(IntKi), PARAMETER :: SCT8Ot7 = 169 - INTEGER(IntKi), PARAMETER :: SCT8Ot8 = 170 - INTEGER(IntKi), PARAMETER :: SCT8Ot9 = 171 - INTEGER(IntKi), PARAMETER :: SCT9Ot1 = 172 - INTEGER(IntKi), PARAMETER :: SCT9Ot2 = 173 - INTEGER(IntKi), PARAMETER :: SCT9Ot3 = 174 - INTEGER(IntKi), PARAMETER :: SCT9Ot4 = 175 - INTEGER(IntKi), PARAMETER :: SCT9Ot5 = 176 - INTEGER(IntKi), PARAMETER :: SCT9Ot6 = 177 - INTEGER(IntKi), PARAMETER :: SCT9Ot7 = 178 - INTEGER(IntKi), PARAMETER :: SCT9Ot8 = 179 - INTEGER(IntKi), PARAMETER :: SCT9Ot9 = 180 - - - ! Rotor Centerline Orientation: - - INTEGER(IntKi), PARAMETER :: RtAxsXT1 = 181 - INTEGER(IntKi), PARAMETER :: RtAxsXT2 = 182 - INTEGER(IntKi), PARAMETER :: RtAxsXT3 = 183 - INTEGER(IntKi), PARAMETER :: RtAxsXT4 = 184 - INTEGER(IntKi), PARAMETER :: RtAxsXT5 = 185 - INTEGER(IntKi), PARAMETER :: RtAxsXT6 = 186 - INTEGER(IntKi), PARAMETER :: RtAxsXT7 = 187 - INTEGER(IntKi), PARAMETER :: RtAxsXT8 = 188 - INTEGER(IntKi), PARAMETER :: RtAxsXT9 = 189 - INTEGER(IntKi), PARAMETER :: RtAxsYT1 = 190 - INTEGER(IntKi), PARAMETER :: RtAxsYT2 = 191 - INTEGER(IntKi), PARAMETER :: RtAxsYT3 = 192 - INTEGER(IntKi), PARAMETER :: RtAxsYT4 = 193 - INTEGER(IntKi), PARAMETER :: RtAxsYT5 = 194 - INTEGER(IntKi), PARAMETER :: RtAxsYT6 = 195 - INTEGER(IntKi), PARAMETER :: RtAxsYT7 = 196 - INTEGER(IntKi), PARAMETER :: RtAxsYT8 = 197 - INTEGER(IntKi), PARAMETER :: RtAxsYT9 = 198 - INTEGER(IntKi), PARAMETER :: RtAxsZT1 = 199 - INTEGER(IntKi), PARAMETER :: RtAxsZT2 = 200 - INTEGER(IntKi), PARAMETER :: RtAxsZT3 = 201 - INTEGER(IntKi), PARAMETER :: RtAxsZT4 = 202 - INTEGER(IntKi), PARAMETER :: RtAxsZT5 = 203 - INTEGER(IntKi), PARAMETER :: RtAxsZT6 = 204 - INTEGER(IntKi), PARAMETER :: RtAxsZT7 = 205 - INTEGER(IntKi), PARAMETER :: RtAxsZT8 = 206 - INTEGER(IntKi), PARAMETER :: RtAxsZT9 = 207 - - - ! Position of the Rotor (Hub) Center: - - INTEGER(IntKi), PARAMETER :: RtPosXT1 = 208 - INTEGER(IntKi), PARAMETER :: RtPosXT2 = 209 - INTEGER(IntKi), PARAMETER :: RtPosXT3 = 210 - INTEGER(IntKi), PARAMETER :: RtPosXT4 = 211 - INTEGER(IntKi), PARAMETER :: RtPosXT5 = 212 - INTEGER(IntKi), PARAMETER :: RtPosXT6 = 213 - INTEGER(IntKi), PARAMETER :: RtPosXT7 = 214 - INTEGER(IntKi), PARAMETER :: RtPosXT8 = 215 - INTEGER(IntKi), PARAMETER :: RtPosXT9 = 216 - INTEGER(IntKi), PARAMETER :: RtPosYT1 = 217 - INTEGER(IntKi), PARAMETER :: RtPosYT2 = 218 - INTEGER(IntKi), PARAMETER :: RtPosYT3 = 219 - INTEGER(IntKi), PARAMETER :: RtPosYT4 = 220 - INTEGER(IntKi), PARAMETER :: RtPosYT5 = 221 - INTEGER(IntKi), PARAMETER :: RtPosYT6 = 222 - INTEGER(IntKi), PARAMETER :: RtPosYT7 = 223 - INTEGER(IntKi), PARAMETER :: RtPosYT8 = 224 - INTEGER(IntKi), PARAMETER :: RtPosYT9 = 225 - INTEGER(IntKi), PARAMETER :: RtPosZT1 = 226 - INTEGER(IntKi), PARAMETER :: RtPosZT2 = 227 - INTEGER(IntKi), PARAMETER :: RtPosZT3 = 228 - INTEGER(IntKi), PARAMETER :: RtPosZT4 = 229 - INTEGER(IntKi), PARAMETER :: RtPosZT5 = 230 - INTEGER(IntKi), PARAMETER :: RtPosZT6 = 231 - INTEGER(IntKi), PARAMETER :: RtPosZT7 = 232 - INTEGER(IntKi), PARAMETER :: RtPosZT8 = 233 - INTEGER(IntKi), PARAMETER :: RtPosZT9 = 234 - - - ! Rotor Diamete: - - INTEGER(IntKi), PARAMETER :: RtDiamT1 = 235 - INTEGER(IntKi), PARAMETER :: RtDiamT2 = 236 - INTEGER(IntKi), PARAMETER :: RtDiamT3 = 237 - INTEGER(IntKi), PARAMETER :: RtDiamT4 = 238 - INTEGER(IntKi), PARAMETER :: RtDiamT5 = 239 - INTEGER(IntKi), PARAMETER :: RtDiamT6 = 240 - INTEGER(IntKi), PARAMETER :: RtDiamT7 = 241 - INTEGER(IntKi), PARAMETER :: RtDiamT8 = 242 - INTEGER(IntKi), PARAMETER :: RtDiamT9 = 243 - - - ! Nacelle-Yaw Error: - - INTEGER(IntKi), PARAMETER :: YawErrT1 = 244 - INTEGER(IntKi), PARAMETER :: YawErrT2 = 245 - INTEGER(IntKi), PARAMETER :: YawErrT3 = 246 - INTEGER(IntKi), PARAMETER :: YawErrT4 = 247 - INTEGER(IntKi), PARAMETER :: YawErrT5 = 248 - INTEGER(IntKi), PARAMETER :: YawErrT6 = 249 - INTEGER(IntKi), PARAMETER :: YawErrT7 = 250 - INTEGER(IntKi), PARAMETER :: YawErrT8 = 251 - INTEGER(IntKi), PARAMETER :: YawErrT9 = 252 - - - ! Ambient Turbulence Intensity of the Wind at the Rotor Disk: - - INTEGER(IntKi), PARAMETER :: TIAmbT1 = 253 - INTEGER(IntKi), PARAMETER :: TIAmbT2 = 254 - INTEGER(IntKi), PARAMETER :: TIAmbT3 = 255 - INTEGER(IntKi), PARAMETER :: TIAmbT4 = 256 - INTEGER(IntKi), PARAMETER :: TIAmbT5 = 257 - INTEGER(IntKi), PARAMETER :: TIAmbT6 = 258 - INTEGER(IntKi), PARAMETER :: TIAmbT7 = 259 - INTEGER(IntKi), PARAMETER :: TIAmbT8 = 260 - INTEGER(IntKi), PARAMETER :: TIAmbT9 = 261 - - - ! Rotor-Disk-Averaged Ambient Wind Speed: - - INTEGER(IntKi), PARAMETER :: RtVAmbT1 = 262 - INTEGER(IntKi), PARAMETER :: RtVAmbT2 = 263 - INTEGER(IntKi), PARAMETER :: RtVAmbT3 = 264 - INTEGER(IntKi), PARAMETER :: RtVAmbT4 = 265 - INTEGER(IntKi), PARAMETER :: RtVAmbT5 = 266 - INTEGER(IntKi), PARAMETER :: RtVAmbT6 = 267 - INTEGER(IntKi), PARAMETER :: RtVAmbT7 = 268 - INTEGER(IntKi), PARAMETER :: RtVAmbT8 = 269 - INTEGER(IntKi), PARAMETER :: RtVAmbT9 = 270 - - - ! Rotor-Disk-Averaged Relative Wind Speed: - - INTEGER(IntKi), PARAMETER :: RtVRelT1 = 271 - INTEGER(IntKi), PARAMETER :: RtVRelT2 = 272 - INTEGER(IntKi), PARAMETER :: RtVRelT3 = 273 - INTEGER(IntKi), PARAMETER :: RtVRelT4 = 274 - INTEGER(IntKi), PARAMETER :: RtVRelT5 = 275 - INTEGER(IntKi), PARAMETER :: RtVRelT6 = 276 - INTEGER(IntKi), PARAMETER :: RtVRelT7 = 277 - INTEGER(IntKi), PARAMETER :: RtVRelT8 = 278 - INTEGER(IntKi), PARAMETER :: RtVRelT9 = 279 - - - ! Azimuthally Averaged Thrust Force Coefficient: - - INTEGER(IntKi), PARAMETER :: CtT1N01 = 280 - INTEGER(IntKi), PARAMETER :: CtT1N02 = 281 - INTEGER(IntKi), PARAMETER :: CtT1N03 = 282 - INTEGER(IntKi), PARAMETER :: CtT1N04 = 283 - INTEGER(IntKi), PARAMETER :: CtT1N05 = 284 - INTEGER(IntKi), PARAMETER :: CtT1N06 = 285 - INTEGER(IntKi), PARAMETER :: CtT1N07 = 286 - INTEGER(IntKi), PARAMETER :: CtT1N08 = 287 - INTEGER(IntKi), PARAMETER :: CtT1N09 = 288 - INTEGER(IntKi), PARAMETER :: CtT1N10 = 289 - INTEGER(IntKi), PARAMETER :: CtT1N11 = 290 - INTEGER(IntKi), PARAMETER :: CtT1N12 = 291 - INTEGER(IntKi), PARAMETER :: CtT1N13 = 292 - INTEGER(IntKi), PARAMETER :: CtT1N14 = 293 - INTEGER(IntKi), PARAMETER :: CtT1N15 = 294 - INTEGER(IntKi), PARAMETER :: CtT1N16 = 295 - INTEGER(IntKi), PARAMETER :: CtT1N17 = 296 - INTEGER(IntKi), PARAMETER :: CtT1N18 = 297 - INTEGER(IntKi), PARAMETER :: CtT1N19 = 298 - INTEGER(IntKi), PARAMETER :: CtT1N20 = 299 - INTEGER(IntKi), PARAMETER :: CtT2N01 = 300 - INTEGER(IntKi), PARAMETER :: CtT2N02 = 301 - INTEGER(IntKi), PARAMETER :: CtT2N03 = 302 - INTEGER(IntKi), PARAMETER :: CtT2N04 = 303 - INTEGER(IntKi), PARAMETER :: CtT2N05 = 304 - INTEGER(IntKi), PARAMETER :: CtT2N06 = 305 - INTEGER(IntKi), PARAMETER :: CtT2N07 = 306 - INTEGER(IntKi), PARAMETER :: CtT2N08 = 307 - INTEGER(IntKi), PARAMETER :: CtT2N09 = 308 - INTEGER(IntKi), PARAMETER :: CtT2N10 = 309 - INTEGER(IntKi), PARAMETER :: CtT2N11 = 310 - INTEGER(IntKi), PARAMETER :: CtT2N12 = 311 - INTEGER(IntKi), PARAMETER :: CtT2N13 = 312 - INTEGER(IntKi), PARAMETER :: CtT2N14 = 313 - INTEGER(IntKi), PARAMETER :: CtT2N15 = 314 - INTEGER(IntKi), PARAMETER :: CtT2N16 = 315 - INTEGER(IntKi), PARAMETER :: CtT2N17 = 316 - INTEGER(IntKi), PARAMETER :: CtT2N18 = 317 - INTEGER(IntKi), PARAMETER :: CtT2N19 = 318 - INTEGER(IntKi), PARAMETER :: CtT2N20 = 319 - INTEGER(IntKi), PARAMETER :: CtT3N01 = 320 - INTEGER(IntKi), PARAMETER :: CtT3N02 = 321 - INTEGER(IntKi), PARAMETER :: CtT3N03 = 322 - INTEGER(IntKi), PARAMETER :: CtT3N04 = 323 - INTEGER(IntKi), PARAMETER :: CtT3N05 = 324 - INTEGER(IntKi), PARAMETER :: CtT3N06 = 325 - INTEGER(IntKi), PARAMETER :: CtT3N07 = 326 - INTEGER(IntKi), PARAMETER :: CtT3N08 = 327 - INTEGER(IntKi), PARAMETER :: CtT3N09 = 328 - INTEGER(IntKi), PARAMETER :: CtT3N10 = 329 - INTEGER(IntKi), PARAMETER :: CtT3N11 = 330 - INTEGER(IntKi), PARAMETER :: CtT3N12 = 331 - INTEGER(IntKi), PARAMETER :: CtT3N13 = 332 - INTEGER(IntKi), PARAMETER :: CtT3N14 = 333 - INTEGER(IntKi), PARAMETER :: CtT3N15 = 334 - INTEGER(IntKi), PARAMETER :: CtT3N16 = 335 - INTEGER(IntKi), PARAMETER :: CtT3N17 = 336 - INTEGER(IntKi), PARAMETER :: CtT3N18 = 337 - INTEGER(IntKi), PARAMETER :: CtT3N19 = 338 - INTEGER(IntKi), PARAMETER :: CtT3N20 = 339 - INTEGER(IntKi), PARAMETER :: CtT4N01 = 340 - INTEGER(IntKi), PARAMETER :: CtT4N02 = 341 - INTEGER(IntKi), PARAMETER :: CtT4N03 = 342 - INTEGER(IntKi), PARAMETER :: CtT4N04 = 343 - INTEGER(IntKi), PARAMETER :: CtT4N05 = 344 - INTEGER(IntKi), PARAMETER :: CtT4N06 = 345 - INTEGER(IntKi), PARAMETER :: CtT4N07 = 346 - INTEGER(IntKi), PARAMETER :: CtT4N08 = 347 - INTEGER(IntKi), PARAMETER :: CtT4N09 = 348 - INTEGER(IntKi), PARAMETER :: CtT4N10 = 349 - INTEGER(IntKi), PARAMETER :: CtT4N11 = 350 - INTEGER(IntKi), PARAMETER :: CtT4N12 = 351 - INTEGER(IntKi), PARAMETER :: CtT4N13 = 352 - INTEGER(IntKi), PARAMETER :: CtT4N14 = 353 - INTEGER(IntKi), PARAMETER :: CtT4N15 = 354 - INTEGER(IntKi), PARAMETER :: CtT4N16 = 355 - INTEGER(IntKi), PARAMETER :: CtT4N17 = 356 - INTEGER(IntKi), PARAMETER :: CtT4N18 = 357 - INTEGER(IntKi), PARAMETER :: CtT4N19 = 358 - INTEGER(IntKi), PARAMETER :: CtT4N20 = 359 - INTEGER(IntKi), PARAMETER :: CtT5N01 = 360 - INTEGER(IntKi), PARAMETER :: CtT5N02 = 361 - INTEGER(IntKi), PARAMETER :: CtT5N03 = 362 - INTEGER(IntKi), PARAMETER :: CtT5N04 = 363 - INTEGER(IntKi), PARAMETER :: CtT5N05 = 364 - INTEGER(IntKi), PARAMETER :: CtT5N06 = 365 - INTEGER(IntKi), PARAMETER :: CtT5N07 = 366 - INTEGER(IntKi), PARAMETER :: CtT5N08 = 367 - INTEGER(IntKi), PARAMETER :: CtT5N09 = 368 - INTEGER(IntKi), PARAMETER :: CtT5N10 = 369 - INTEGER(IntKi), PARAMETER :: CtT5N11 = 370 - INTEGER(IntKi), PARAMETER :: CtT5N12 = 371 - INTEGER(IntKi), PARAMETER :: CtT5N13 = 372 - INTEGER(IntKi), PARAMETER :: CtT5N14 = 373 - INTEGER(IntKi), PARAMETER :: CtT5N15 = 374 - INTEGER(IntKi), PARAMETER :: CtT5N16 = 375 - INTEGER(IntKi), PARAMETER :: CtT5N17 = 376 - INTEGER(IntKi), PARAMETER :: CtT5N18 = 377 - INTEGER(IntKi), PARAMETER :: CtT5N19 = 378 - INTEGER(IntKi), PARAMETER :: CtT5N20 = 379 - INTEGER(IntKi), PARAMETER :: CtT6N01 = 380 - INTEGER(IntKi), PARAMETER :: CtT6N02 = 381 - INTEGER(IntKi), PARAMETER :: CtT6N03 = 382 - INTEGER(IntKi), PARAMETER :: CtT6N04 = 383 - INTEGER(IntKi), PARAMETER :: CtT6N05 = 384 - INTEGER(IntKi), PARAMETER :: CtT6N06 = 385 - INTEGER(IntKi), PARAMETER :: CtT6N07 = 386 - INTEGER(IntKi), PARAMETER :: CtT6N08 = 387 - INTEGER(IntKi), PARAMETER :: CtT6N09 = 388 - INTEGER(IntKi), PARAMETER :: CtT6N10 = 389 - INTEGER(IntKi), PARAMETER :: CtT6N11 = 390 - INTEGER(IntKi), PARAMETER :: CtT6N12 = 391 - INTEGER(IntKi), PARAMETER :: CtT6N13 = 392 - INTEGER(IntKi), PARAMETER :: CtT6N14 = 393 - INTEGER(IntKi), PARAMETER :: CtT6N15 = 394 - INTEGER(IntKi), PARAMETER :: CtT6N16 = 395 - INTEGER(IntKi), PARAMETER :: CtT6N17 = 396 - INTEGER(IntKi), PARAMETER :: CtT6N18 = 397 - INTEGER(IntKi), PARAMETER :: CtT6N19 = 398 - INTEGER(IntKi), PARAMETER :: CtT6N20 = 399 - INTEGER(IntKi), PARAMETER :: CtT7N01 = 400 - INTEGER(IntKi), PARAMETER :: CtT7N02 = 401 - INTEGER(IntKi), PARAMETER :: CtT7N03 = 402 - INTEGER(IntKi), PARAMETER :: CtT7N04 = 403 - INTEGER(IntKi), PARAMETER :: CtT7N05 = 404 - INTEGER(IntKi), PARAMETER :: CtT7N06 = 405 - INTEGER(IntKi), PARAMETER :: CtT7N07 = 406 - INTEGER(IntKi), PARAMETER :: CtT7N08 = 407 - INTEGER(IntKi), PARAMETER :: CtT7N09 = 408 - INTEGER(IntKi), PARAMETER :: CtT7N10 = 409 - INTEGER(IntKi), PARAMETER :: CtT7N11 = 410 - INTEGER(IntKi), PARAMETER :: CtT7N12 = 411 - INTEGER(IntKi), PARAMETER :: CtT7N13 = 412 - INTEGER(IntKi), PARAMETER :: CtT7N14 = 413 - INTEGER(IntKi), PARAMETER :: CtT7N15 = 414 - INTEGER(IntKi), PARAMETER :: CtT7N16 = 415 - INTEGER(IntKi), PARAMETER :: CtT7N17 = 416 - INTEGER(IntKi), PARAMETER :: CtT7N18 = 417 - INTEGER(IntKi), PARAMETER :: CtT7N19 = 418 - INTEGER(IntKi), PARAMETER :: CtT7N20 = 419 - INTEGER(IntKi), PARAMETER :: CtT8N01 = 420 - INTEGER(IntKi), PARAMETER :: CtT8N02 = 421 - INTEGER(IntKi), PARAMETER :: CtT8N03 = 422 - INTEGER(IntKi), PARAMETER :: CtT8N04 = 423 - INTEGER(IntKi), PARAMETER :: CtT8N05 = 424 - INTEGER(IntKi), PARAMETER :: CtT8N06 = 425 - INTEGER(IntKi), PARAMETER :: CtT8N07 = 426 - INTEGER(IntKi), PARAMETER :: CtT8N08 = 427 - INTEGER(IntKi), PARAMETER :: CtT8N09 = 428 - INTEGER(IntKi), PARAMETER :: CtT8N10 = 429 - INTEGER(IntKi), PARAMETER :: CtT8N11 = 430 - INTEGER(IntKi), PARAMETER :: CtT8N12 = 431 - INTEGER(IntKi), PARAMETER :: CtT8N13 = 432 - INTEGER(IntKi), PARAMETER :: CtT8N14 = 433 - INTEGER(IntKi), PARAMETER :: CtT8N15 = 434 - INTEGER(IntKi), PARAMETER :: CtT8N16 = 435 - INTEGER(IntKi), PARAMETER :: CtT8N17 = 436 - INTEGER(IntKi), PARAMETER :: CtT8N18 = 437 - INTEGER(IntKi), PARAMETER :: CtT8N19 = 438 - INTEGER(IntKi), PARAMETER :: CtT8N20 = 439 - INTEGER(IntKi), PARAMETER :: CtT9N01 = 440 - INTEGER(IntKi), PARAMETER :: CtT9N02 = 441 - INTEGER(IntKi), PARAMETER :: CtT9N03 = 442 - INTEGER(IntKi), PARAMETER :: CtT9N04 = 443 - INTEGER(IntKi), PARAMETER :: CtT9N05 = 444 - INTEGER(IntKi), PARAMETER :: CtT9N06 = 445 - INTEGER(IntKi), PARAMETER :: CtT9N07 = 446 - INTEGER(IntKi), PARAMETER :: CtT9N08 = 447 - INTEGER(IntKi), PARAMETER :: CtT9N09 = 448 - INTEGER(IntKi), PARAMETER :: CtT9N10 = 449 - INTEGER(IntKi), PARAMETER :: CtT9N11 = 450 - INTEGER(IntKi), PARAMETER :: CtT9N12 = 451 - INTEGER(IntKi), PARAMETER :: CtT9N13 = 452 - INTEGER(IntKi), PARAMETER :: CtT9N14 = 453 - INTEGER(IntKi), PARAMETER :: CtT9N15 = 454 - INTEGER(IntKi), PARAMETER :: CtT9N16 = 455 - INTEGER(IntKi), PARAMETER :: CtT9N17 = 456 - INTEGER(IntKi), PARAMETER :: CtT9N18 = 457 - INTEGER(IntKi), PARAMETER :: CtT9N19 = 458 - INTEGER(IntKi), PARAMETER :: CtT9N20 = 459 - - - ! Wake Centerline Orientation: - - INTEGER(IntKi), PARAMETER :: WkAxsXT1D1 = 460 - INTEGER(IntKi), PARAMETER :: WkAxsXT1D2 = 461 - INTEGER(IntKi), PARAMETER :: WkAxsXT1D3 = 462 - INTEGER(IntKi), PARAMETER :: WkAxsXT1D4 = 463 - INTEGER(IntKi), PARAMETER :: WkAxsXT1D5 = 464 - INTEGER(IntKi), PARAMETER :: WkAxsXT1D6 = 465 - INTEGER(IntKi), PARAMETER :: WkAxsXT1D7 = 466 - INTEGER(IntKi), PARAMETER :: WkAxsXT1D8 = 467 - INTEGER(IntKi), PARAMETER :: WkAxsXT1D9 = 468 - INTEGER(IntKi), PARAMETER :: WkAxsXT2D1 = 469 - INTEGER(IntKi), PARAMETER :: WkAxsXT2D2 = 470 - INTEGER(IntKi), PARAMETER :: WkAxsXT2D3 = 471 - INTEGER(IntKi), PARAMETER :: WkAxsXT2D4 = 472 - INTEGER(IntKi), PARAMETER :: WkAxsXT2D5 = 473 - INTEGER(IntKi), PARAMETER :: WkAxsXT2D6 = 474 - INTEGER(IntKi), PARAMETER :: WkAxsXT2D7 = 475 - INTEGER(IntKi), PARAMETER :: WkAxsXT2D8 = 476 - INTEGER(IntKi), PARAMETER :: WkAxsXT2D9 = 477 - INTEGER(IntKi), PARAMETER :: WkAxsXT3D1 = 478 - INTEGER(IntKi), PARAMETER :: WkAxsXT3D2 = 479 - INTEGER(IntKi), PARAMETER :: WkAxsXT3D3 = 480 - INTEGER(IntKi), PARAMETER :: WkAxsXT3D4 = 481 - INTEGER(IntKi), PARAMETER :: WkAxsXT3D5 = 482 - INTEGER(IntKi), PARAMETER :: WkAxsXT3D6 = 483 - INTEGER(IntKi), PARAMETER :: WkAxsXT3D7 = 484 - INTEGER(IntKi), PARAMETER :: WkAxsXT3D8 = 485 - INTEGER(IntKi), PARAMETER :: WkAxsXT3D9 = 486 - INTEGER(IntKi), PARAMETER :: WkAxsXT4D1 = 487 - INTEGER(IntKi), PARAMETER :: WkAxsXT4D2 = 488 - INTEGER(IntKi), PARAMETER :: WkAxsXT4D3 = 489 - INTEGER(IntKi), PARAMETER :: WkAxsXT4D4 = 490 - INTEGER(IntKi), PARAMETER :: WkAxsXT4D5 = 491 - INTEGER(IntKi), PARAMETER :: WkAxsXT4D6 = 492 - INTEGER(IntKi), PARAMETER :: WkAxsXT4D7 = 493 - INTEGER(IntKi), PARAMETER :: WkAxsXT4D8 = 494 - INTEGER(IntKi), PARAMETER :: WkAxsXT4D9 = 495 - INTEGER(IntKi), PARAMETER :: WkAxsXT5D1 = 496 - INTEGER(IntKi), PARAMETER :: WkAxsXT5D2 = 497 - INTEGER(IntKi), PARAMETER :: WkAxsXT5D3 = 498 - INTEGER(IntKi), PARAMETER :: WkAxsXT5D4 = 499 - INTEGER(IntKi), PARAMETER :: WkAxsXT5D5 = 500 - INTEGER(IntKi), PARAMETER :: WkAxsXT5D6 = 501 - INTEGER(IntKi), PARAMETER :: WkAxsXT5D7 = 502 - INTEGER(IntKi), PARAMETER :: WkAxsXT5D8 = 503 - INTEGER(IntKi), PARAMETER :: WkAxsXT5D9 = 504 - INTEGER(IntKi), PARAMETER :: WkAxsXT6D1 = 505 - INTEGER(IntKi), PARAMETER :: WkAxsXT6D2 = 506 - INTEGER(IntKi), PARAMETER :: WkAxsXT6D3 = 507 - INTEGER(IntKi), PARAMETER :: WkAxsXT6D4 = 508 - INTEGER(IntKi), PARAMETER :: WkAxsXT6D5 = 509 - INTEGER(IntKi), PARAMETER :: WkAxsXT6D6 = 510 - INTEGER(IntKi), PARAMETER :: WkAxsXT6D7 = 511 - INTEGER(IntKi), PARAMETER :: WkAxsXT6D8 = 512 - INTEGER(IntKi), PARAMETER :: WkAxsXT6D9 = 513 - INTEGER(IntKi), PARAMETER :: WkAxsXT7D1 = 514 - INTEGER(IntKi), PARAMETER :: WkAxsXT7D2 = 515 - INTEGER(IntKi), PARAMETER :: WkAxsXT7D3 = 516 - INTEGER(IntKi), PARAMETER :: WkAxsXT7D4 = 517 - INTEGER(IntKi), PARAMETER :: WkAxsXT7D5 = 518 - INTEGER(IntKi), PARAMETER :: WkAxsXT7D6 = 519 - INTEGER(IntKi), PARAMETER :: WkAxsXT7D7 = 520 - INTEGER(IntKi), PARAMETER :: WkAxsXT7D8 = 521 - INTEGER(IntKi), PARAMETER :: WkAxsXT7D9 = 522 - INTEGER(IntKi), PARAMETER :: WkAxsXT8D1 = 523 - INTEGER(IntKi), PARAMETER :: WkAxsXT8D2 = 524 - INTEGER(IntKi), PARAMETER :: WkAxsXT8D3 = 525 - INTEGER(IntKi), PARAMETER :: WkAxsXT8D4 = 526 - INTEGER(IntKi), PARAMETER :: WkAxsXT8D5 = 527 - INTEGER(IntKi), PARAMETER :: WkAxsXT8D6 = 528 - INTEGER(IntKi), PARAMETER :: WkAxsXT8D7 = 529 - INTEGER(IntKi), PARAMETER :: WkAxsXT8D8 = 530 - INTEGER(IntKi), PARAMETER :: WkAxsXT8D9 = 531 - INTEGER(IntKi), PARAMETER :: WkAxsXT9D1 = 532 - INTEGER(IntKi), PARAMETER :: WkAxsXT9D2 = 533 - INTEGER(IntKi), PARAMETER :: WkAxsXT9D3 = 534 - INTEGER(IntKi), PARAMETER :: WkAxsXT9D4 = 535 - INTEGER(IntKi), PARAMETER :: WkAxsXT9D5 = 536 - INTEGER(IntKi), PARAMETER :: WkAxsXT9D6 = 537 - INTEGER(IntKi), PARAMETER :: WkAxsXT9D7 = 538 - INTEGER(IntKi), PARAMETER :: WkAxsXT9D8 = 539 - INTEGER(IntKi), PARAMETER :: WkAxsXT9D9 = 540 - INTEGER(IntKi), PARAMETER :: WkAxsYT1D1 = 541 - INTEGER(IntKi), PARAMETER :: WkAxsYT1D2 = 542 - INTEGER(IntKi), PARAMETER :: WkAxsYT1D3 = 543 - INTEGER(IntKi), PARAMETER :: WkAxsYT1D4 = 544 - INTEGER(IntKi), PARAMETER :: WkAxsYT1D5 = 545 - INTEGER(IntKi), PARAMETER :: WkAxsYT1D6 = 546 - INTEGER(IntKi), PARAMETER :: WkAxsYT1D7 = 547 - INTEGER(IntKi), PARAMETER :: WkAxsYT1D8 = 548 - INTEGER(IntKi), PARAMETER :: WkAxsYT1D9 = 549 - INTEGER(IntKi), PARAMETER :: WkAxsYT2D1 = 550 - INTEGER(IntKi), PARAMETER :: WkAxsYT2D2 = 551 - INTEGER(IntKi), PARAMETER :: WkAxsYT2D3 = 552 - INTEGER(IntKi), PARAMETER :: WkAxsYT2D4 = 553 - INTEGER(IntKi), PARAMETER :: WkAxsYT2D5 = 554 - INTEGER(IntKi), PARAMETER :: WkAxsYT2D6 = 555 - INTEGER(IntKi), PARAMETER :: WkAxsYT2D7 = 556 - INTEGER(IntKi), PARAMETER :: WkAxsYT2D8 = 557 - INTEGER(IntKi), PARAMETER :: WkAxsYT2D9 = 558 - INTEGER(IntKi), PARAMETER :: WkAxsYT3D1 = 559 - INTEGER(IntKi), PARAMETER :: WkAxsYT3D2 = 560 - INTEGER(IntKi), PARAMETER :: WkAxsYT3D3 = 561 - INTEGER(IntKi), PARAMETER :: WkAxsYT3D4 = 562 - INTEGER(IntKi), PARAMETER :: WkAxsYT3D5 = 563 - INTEGER(IntKi), PARAMETER :: WkAxsYT3D6 = 564 - INTEGER(IntKi), PARAMETER :: WkAxsYT3D7 = 565 - INTEGER(IntKi), PARAMETER :: WkAxsYT3D8 = 566 - INTEGER(IntKi), PARAMETER :: WkAxsYT3D9 = 567 - INTEGER(IntKi), PARAMETER :: WkAxsYT4D1 = 568 - INTEGER(IntKi), PARAMETER :: WkAxsYT4D2 = 569 - INTEGER(IntKi), PARAMETER :: WkAxsYT4D3 = 570 - INTEGER(IntKi), PARAMETER :: WkAxsYT4D4 = 571 - INTEGER(IntKi), PARAMETER :: WkAxsYT4D5 = 572 - INTEGER(IntKi), PARAMETER :: WkAxsYT4D6 = 573 - INTEGER(IntKi), PARAMETER :: WkAxsYT4D7 = 574 - INTEGER(IntKi), PARAMETER :: WkAxsYT4D8 = 575 - INTEGER(IntKi), PARAMETER :: WkAxsYT4D9 = 576 - INTEGER(IntKi), PARAMETER :: WkAxsYT5D1 = 577 - INTEGER(IntKi), PARAMETER :: WkAxsYT5D2 = 578 - INTEGER(IntKi), PARAMETER :: WkAxsYT5D3 = 579 - INTEGER(IntKi), PARAMETER :: WkAxsYT5D4 = 580 - INTEGER(IntKi), PARAMETER :: WkAxsYT5D5 = 581 - INTEGER(IntKi), PARAMETER :: WkAxsYT5D6 = 582 - INTEGER(IntKi), PARAMETER :: WkAxsYT5D7 = 583 - INTEGER(IntKi), PARAMETER :: WkAxsYT5D8 = 584 - INTEGER(IntKi), PARAMETER :: WkAxsYT5D9 = 585 - INTEGER(IntKi), PARAMETER :: WkAxsYT6D1 = 586 - INTEGER(IntKi), PARAMETER :: WkAxsYT6D2 = 587 - INTEGER(IntKi), PARAMETER :: WkAxsYT6D3 = 588 - INTEGER(IntKi), PARAMETER :: WkAxsYT6D4 = 589 - INTEGER(IntKi), PARAMETER :: WkAxsYT6D5 = 590 - INTEGER(IntKi), PARAMETER :: WkAxsYT6D6 = 591 - INTEGER(IntKi), PARAMETER :: WkAxsYT6D7 = 592 - INTEGER(IntKi), PARAMETER :: WkAxsYT6D8 = 593 - INTEGER(IntKi), PARAMETER :: WkAxsYT6D9 = 594 - INTEGER(IntKi), PARAMETER :: WkAxsYT7D1 = 595 - INTEGER(IntKi), PARAMETER :: WkAxsYT7D2 = 596 - INTEGER(IntKi), PARAMETER :: WkAxsYT7D3 = 597 - INTEGER(IntKi), PARAMETER :: WkAxsYT7D4 = 598 - INTEGER(IntKi), PARAMETER :: WkAxsYT7D5 = 599 - INTEGER(IntKi), PARAMETER :: WkAxsYT7D6 = 600 - INTEGER(IntKi), PARAMETER :: WkAxsYT7D7 = 601 - INTEGER(IntKi), PARAMETER :: WkAxsYT7D8 = 602 - INTEGER(IntKi), PARAMETER :: WkAxsYT7D9 = 603 - INTEGER(IntKi), PARAMETER :: WkAxsYT8D1 = 604 - INTEGER(IntKi), PARAMETER :: WkAxsYT8D2 = 605 - INTEGER(IntKi), PARAMETER :: WkAxsYT8D3 = 606 - INTEGER(IntKi), PARAMETER :: WkAxsYT8D4 = 607 - INTEGER(IntKi), PARAMETER :: WkAxsYT8D5 = 608 - INTEGER(IntKi), PARAMETER :: WkAxsYT8D6 = 609 - INTEGER(IntKi), PARAMETER :: WkAxsYT8D7 = 610 - INTEGER(IntKi), PARAMETER :: WkAxsYT8D8 = 611 - INTEGER(IntKi), PARAMETER :: WkAxsYT8D9 = 612 - INTEGER(IntKi), PARAMETER :: WkAxsYT9D1 = 613 - INTEGER(IntKi), PARAMETER :: WkAxsYT9D2 = 614 - INTEGER(IntKi), PARAMETER :: WkAxsYT9D3 = 615 - INTEGER(IntKi), PARAMETER :: WkAxsYT9D4 = 616 - INTEGER(IntKi), PARAMETER :: WkAxsYT9D5 = 617 - INTEGER(IntKi), PARAMETER :: WkAxsYT9D6 = 618 - INTEGER(IntKi), PARAMETER :: WkAxsYT9D7 = 619 - INTEGER(IntKi), PARAMETER :: WkAxsYT9D8 = 620 - INTEGER(IntKi), PARAMETER :: WkAxsYT9D9 = 621 - INTEGER(IntKi), PARAMETER :: WkAxsZT1D1 = 622 - INTEGER(IntKi), PARAMETER :: WkAxsZT1D2 = 623 - INTEGER(IntKi), PARAMETER :: WkAxsZT1D3 = 624 - INTEGER(IntKi), PARAMETER :: WkAxsZT1D4 = 625 - INTEGER(IntKi), PARAMETER :: WkAxsZT1D5 = 626 - INTEGER(IntKi), PARAMETER :: WkAxsZT1D6 = 627 - INTEGER(IntKi), PARAMETER :: WkAxsZT1D7 = 628 - INTEGER(IntKi), PARAMETER :: WkAxsZT1D8 = 629 - INTEGER(IntKi), PARAMETER :: WkAxsZT1D9 = 630 - INTEGER(IntKi), PARAMETER :: WkAxsZT2D1 = 631 - INTEGER(IntKi), PARAMETER :: WkAxsZT2D2 = 632 - INTEGER(IntKi), PARAMETER :: WkAxsZT2D3 = 633 - INTEGER(IntKi), PARAMETER :: WkAxsZT2D4 = 634 - INTEGER(IntKi), PARAMETER :: WkAxsZT2D5 = 635 - INTEGER(IntKi), PARAMETER :: WkAxsZT2D6 = 636 - INTEGER(IntKi), PARAMETER :: WkAxsZT2D7 = 637 - INTEGER(IntKi), PARAMETER :: WkAxsZT2D8 = 638 - INTEGER(IntKi), PARAMETER :: WkAxsZT2D9 = 639 - INTEGER(IntKi), PARAMETER :: WkAxsZT3D1 = 640 - INTEGER(IntKi), PARAMETER :: WkAxsZT3D2 = 641 - INTEGER(IntKi), PARAMETER :: WkAxsZT3D3 = 642 - INTEGER(IntKi), PARAMETER :: WkAxsZT3D4 = 643 - INTEGER(IntKi), PARAMETER :: WkAxsZT3D5 = 644 - INTEGER(IntKi), PARAMETER :: WkAxsZT3D6 = 645 - INTEGER(IntKi), PARAMETER :: WkAxsZT3D7 = 646 - INTEGER(IntKi), PARAMETER :: WkAxsZT3D8 = 647 - INTEGER(IntKi), PARAMETER :: WkAxsZT3D9 = 648 - INTEGER(IntKi), PARAMETER :: WkAxsZT4D1 = 649 - INTEGER(IntKi), PARAMETER :: WkAxsZT4D2 = 650 - INTEGER(IntKi), PARAMETER :: WkAxsZT4D3 = 651 - INTEGER(IntKi), PARAMETER :: WkAxsZT4D4 = 652 - INTEGER(IntKi), PARAMETER :: WkAxsZT4D5 = 653 - INTEGER(IntKi), PARAMETER :: WkAxsZT4D6 = 654 - INTEGER(IntKi), PARAMETER :: WkAxsZT4D7 = 655 - INTEGER(IntKi), PARAMETER :: WkAxsZT4D8 = 656 - INTEGER(IntKi), PARAMETER :: WkAxsZT4D9 = 657 - INTEGER(IntKi), PARAMETER :: WkAxsZT5D1 = 658 - INTEGER(IntKi), PARAMETER :: WkAxsZT5D2 = 659 - INTEGER(IntKi), PARAMETER :: WkAxsZT5D3 = 660 - INTEGER(IntKi), PARAMETER :: WkAxsZT5D4 = 661 - INTEGER(IntKi), PARAMETER :: WkAxsZT5D5 = 662 - INTEGER(IntKi), PARAMETER :: WkAxsZT5D6 = 663 - INTEGER(IntKi), PARAMETER :: WkAxsZT5D7 = 664 - INTEGER(IntKi), PARAMETER :: WkAxsZT5D8 = 665 - INTEGER(IntKi), PARAMETER :: WkAxsZT5D9 = 666 - INTEGER(IntKi), PARAMETER :: WkAxsZT6D1 = 667 - INTEGER(IntKi), PARAMETER :: WkAxsZT6D2 = 668 - INTEGER(IntKi), PARAMETER :: WkAxsZT6D3 = 669 - INTEGER(IntKi), PARAMETER :: WkAxsZT6D4 = 670 - INTEGER(IntKi), PARAMETER :: WkAxsZT6D5 = 671 - INTEGER(IntKi), PARAMETER :: WkAxsZT6D6 = 672 - INTEGER(IntKi), PARAMETER :: WkAxsZT6D7 = 673 - INTEGER(IntKi), PARAMETER :: WkAxsZT6D8 = 674 - INTEGER(IntKi), PARAMETER :: WkAxsZT6D9 = 675 - INTEGER(IntKi), PARAMETER :: WkAxsZT7D1 = 676 - INTEGER(IntKi), PARAMETER :: WkAxsZT7D2 = 677 - INTEGER(IntKi), PARAMETER :: WkAxsZT7D3 = 678 - INTEGER(IntKi), PARAMETER :: WkAxsZT7D4 = 679 - INTEGER(IntKi), PARAMETER :: WkAxsZT7D5 = 680 - INTEGER(IntKi), PARAMETER :: WkAxsZT7D6 = 681 - INTEGER(IntKi), PARAMETER :: WkAxsZT7D7 = 682 - INTEGER(IntKi), PARAMETER :: WkAxsZT7D8 = 683 - INTEGER(IntKi), PARAMETER :: WkAxsZT7D9 = 684 - INTEGER(IntKi), PARAMETER :: WkAxsZT8D1 = 685 - INTEGER(IntKi), PARAMETER :: WkAxsZT8D2 = 686 - INTEGER(IntKi), PARAMETER :: WkAxsZT8D3 = 687 - INTEGER(IntKi), PARAMETER :: WkAxsZT8D4 = 688 - INTEGER(IntKi), PARAMETER :: WkAxsZT8D5 = 689 - INTEGER(IntKi), PARAMETER :: WkAxsZT8D6 = 690 - INTEGER(IntKi), PARAMETER :: WkAxsZT8D7 = 691 - INTEGER(IntKi), PARAMETER :: WkAxsZT8D8 = 692 - INTEGER(IntKi), PARAMETER :: WkAxsZT8D9 = 693 - INTEGER(IntKi), PARAMETER :: WkAxsZT9D1 = 694 - INTEGER(IntKi), PARAMETER :: WkAxsZT9D2 = 695 - INTEGER(IntKi), PARAMETER :: WkAxsZT9D3 = 696 - INTEGER(IntKi), PARAMETER :: WkAxsZT9D4 = 697 - INTEGER(IntKi), PARAMETER :: WkAxsZT9D5 = 698 - INTEGER(IntKi), PARAMETER :: WkAxsZT9D6 = 699 - INTEGER(IntKi), PARAMETER :: WkAxsZT9D7 = 700 - INTEGER(IntKi), PARAMETER :: WkAxsZT9D8 = 701 - INTEGER(IntKi), PARAMETER :: WkAxsZT9D9 = 702 - - - ! Center Position of Wake Centerline: - - INTEGER(IntKi), PARAMETER :: WkPosXT1D1 = 703 - INTEGER(IntKi), PARAMETER :: WkPosXT1D2 = 704 - INTEGER(IntKi), PARAMETER :: WkPosXT1D3 = 705 - INTEGER(IntKi), PARAMETER :: WkPosXT1D4 = 706 - INTEGER(IntKi), PARAMETER :: WkPosXT1D5 = 707 - INTEGER(IntKi), PARAMETER :: WkPosXT1D6 = 708 - INTEGER(IntKi), PARAMETER :: WkPosXT1D7 = 709 - INTEGER(IntKi), PARAMETER :: WkPosXT1D8 = 710 - INTEGER(IntKi), PARAMETER :: WkPosXT1D9 = 711 - INTEGER(IntKi), PARAMETER :: WkPosXT2D1 = 712 - INTEGER(IntKi), PARAMETER :: WkPosXT2D2 = 713 - INTEGER(IntKi), PARAMETER :: WkPosXT2D3 = 714 - INTEGER(IntKi), PARAMETER :: WkPosXT2D4 = 715 - INTEGER(IntKi), PARAMETER :: WkPosXT2D5 = 716 - INTEGER(IntKi), PARAMETER :: WkPosXT2D6 = 717 - INTEGER(IntKi), PARAMETER :: WkPosXT2D7 = 718 - INTEGER(IntKi), PARAMETER :: WkPosXT2D8 = 719 - INTEGER(IntKi), PARAMETER :: WkPosXT2D9 = 720 - INTEGER(IntKi), PARAMETER :: WkPosXT3D1 = 721 - INTEGER(IntKi), PARAMETER :: WkPosXT3D2 = 722 - INTEGER(IntKi), PARAMETER :: WkPosXT3D3 = 723 - INTEGER(IntKi), PARAMETER :: WkPosXT3D4 = 724 - INTEGER(IntKi), PARAMETER :: WkPosXT3D5 = 725 - INTEGER(IntKi), PARAMETER :: WkPosXT3D6 = 726 - INTEGER(IntKi), PARAMETER :: WkPosXT3D7 = 727 - INTEGER(IntKi), PARAMETER :: WkPosXT3D8 = 728 - INTEGER(IntKi), PARAMETER :: WkPosXT3D9 = 729 - INTEGER(IntKi), PARAMETER :: WkPosXT4D1 = 730 - INTEGER(IntKi), PARAMETER :: WkPosXT4D2 = 731 - INTEGER(IntKi), PARAMETER :: WkPosXT4D3 = 732 - INTEGER(IntKi), PARAMETER :: WkPosXT4D4 = 733 - INTEGER(IntKi), PARAMETER :: WkPosXT4D5 = 734 - INTEGER(IntKi), PARAMETER :: WkPosXT4D6 = 735 - INTEGER(IntKi), PARAMETER :: WkPosXT4D7 = 736 - INTEGER(IntKi), PARAMETER :: WkPosXT4D8 = 737 - INTEGER(IntKi), PARAMETER :: WkPosXT4D9 = 738 - INTEGER(IntKi), PARAMETER :: WkPosXT5D1 = 739 - INTEGER(IntKi), PARAMETER :: WkPosXT5D2 = 740 - INTEGER(IntKi), PARAMETER :: WkPosXT5D3 = 741 - INTEGER(IntKi), PARAMETER :: WkPosXT5D4 = 742 - INTEGER(IntKi), PARAMETER :: WkPosXT5D5 = 743 - INTEGER(IntKi), PARAMETER :: WkPosXT5D6 = 744 - INTEGER(IntKi), PARAMETER :: WkPosXT5D7 = 745 - INTEGER(IntKi), PARAMETER :: WkPosXT5D8 = 746 - INTEGER(IntKi), PARAMETER :: WkPosXT5D9 = 747 - INTEGER(IntKi), PARAMETER :: WkPosXT6D1 = 748 - INTEGER(IntKi), PARAMETER :: WkPosXT6D2 = 749 - INTEGER(IntKi), PARAMETER :: WkPosXT6D3 = 750 - INTEGER(IntKi), PARAMETER :: WkPosXT6D4 = 751 - INTEGER(IntKi), PARAMETER :: WkPosXT6D5 = 752 - INTEGER(IntKi), PARAMETER :: WkPosXT6D6 = 753 - INTEGER(IntKi), PARAMETER :: WkPosXT6D7 = 754 - INTEGER(IntKi), PARAMETER :: WkPosXT6D8 = 755 - INTEGER(IntKi), PARAMETER :: WkPosXT6D9 = 756 - INTEGER(IntKi), PARAMETER :: WkPosXT7D1 = 757 - INTEGER(IntKi), PARAMETER :: WkPosXT7D2 = 758 - INTEGER(IntKi), PARAMETER :: WkPosXT7D3 = 759 - INTEGER(IntKi), PARAMETER :: WkPosXT7D4 = 760 - INTEGER(IntKi), PARAMETER :: WkPosXT7D5 = 761 - INTEGER(IntKi), PARAMETER :: WkPosXT7D6 = 762 - INTEGER(IntKi), PARAMETER :: WkPosXT7D7 = 763 - INTEGER(IntKi), PARAMETER :: WkPosXT7D8 = 764 - INTEGER(IntKi), PARAMETER :: WkPosXT7D9 = 765 - INTEGER(IntKi), PARAMETER :: WkPosXT8D1 = 766 - INTEGER(IntKi), PARAMETER :: WkPosXT8D2 = 767 - INTEGER(IntKi), PARAMETER :: WkPosXT8D3 = 768 - INTEGER(IntKi), PARAMETER :: WkPosXT8D4 = 769 - INTEGER(IntKi), PARAMETER :: WkPosXT8D5 = 770 - INTEGER(IntKi), PARAMETER :: WkPosXT8D6 = 771 - INTEGER(IntKi), PARAMETER :: WkPosXT8D7 = 772 - INTEGER(IntKi), PARAMETER :: WkPosXT8D8 = 773 - INTEGER(IntKi), PARAMETER :: WkPosXT8D9 = 774 - INTEGER(IntKi), PARAMETER :: WkPosXT9D1 = 775 - INTEGER(IntKi), PARAMETER :: WkPosXT9D2 = 776 - INTEGER(IntKi), PARAMETER :: WkPosXT9D3 = 777 - INTEGER(IntKi), PARAMETER :: WkPosXT9D4 = 778 - INTEGER(IntKi), PARAMETER :: WkPosXT9D5 = 779 - INTEGER(IntKi), PARAMETER :: WkPosXT9D6 = 780 - INTEGER(IntKi), PARAMETER :: WkPosXT9D7 = 781 - INTEGER(IntKi), PARAMETER :: WkPosXT9D8 = 782 - INTEGER(IntKi), PARAMETER :: WkPosXT9D9 = 783 - INTEGER(IntKi), PARAMETER :: WkPosYT1D1 = 784 - INTEGER(IntKi), PARAMETER :: WkPosYT1D2 = 785 - INTEGER(IntKi), PARAMETER :: WkPosYT1D3 = 786 - INTEGER(IntKi), PARAMETER :: WkPosYT1D4 = 787 - INTEGER(IntKi), PARAMETER :: WkPosYT1D5 = 788 - INTEGER(IntKi), PARAMETER :: WkPosYT1D6 = 789 - INTEGER(IntKi), PARAMETER :: WkPosYT1D7 = 790 - INTEGER(IntKi), PARAMETER :: WkPosYT1D8 = 791 - INTEGER(IntKi), PARAMETER :: WkPosYT1D9 = 792 - INTEGER(IntKi), PARAMETER :: WkPosYT2D1 = 793 - INTEGER(IntKi), PARAMETER :: WkPosYT2D2 = 794 - INTEGER(IntKi), PARAMETER :: WkPosYT2D3 = 795 - INTEGER(IntKi), PARAMETER :: WkPosYT2D4 = 796 - INTEGER(IntKi), PARAMETER :: WkPosYT2D5 = 797 - INTEGER(IntKi), PARAMETER :: WkPosYT2D6 = 798 - INTEGER(IntKi), PARAMETER :: WkPosYT2D7 = 799 - INTEGER(IntKi), PARAMETER :: WkPosYT2D8 = 800 - INTEGER(IntKi), PARAMETER :: WkPosYT2D9 = 801 - INTEGER(IntKi), PARAMETER :: WkPosYT3D1 = 802 - INTEGER(IntKi), PARAMETER :: WkPosYT3D2 = 803 - INTEGER(IntKi), PARAMETER :: WkPosYT3D3 = 804 - INTEGER(IntKi), PARAMETER :: WkPosYT3D4 = 805 - INTEGER(IntKi), PARAMETER :: WkPosYT3D5 = 806 - INTEGER(IntKi), PARAMETER :: WkPosYT3D6 = 807 - INTEGER(IntKi), PARAMETER :: WkPosYT3D7 = 808 - INTEGER(IntKi), PARAMETER :: WkPosYT3D8 = 809 - INTEGER(IntKi), PARAMETER :: WkPosYT3D9 = 810 - INTEGER(IntKi), PARAMETER :: WkPosYT4D1 = 811 - INTEGER(IntKi), PARAMETER :: WkPosYT4D2 = 812 - INTEGER(IntKi), PARAMETER :: WkPosYT4D3 = 813 - INTEGER(IntKi), PARAMETER :: WkPosYT4D4 = 814 - INTEGER(IntKi), PARAMETER :: WkPosYT4D5 = 815 - INTEGER(IntKi), PARAMETER :: WkPosYT4D6 = 816 - INTEGER(IntKi), PARAMETER :: WkPosYT4D7 = 817 - INTEGER(IntKi), PARAMETER :: WkPosYT4D8 = 818 - INTEGER(IntKi), PARAMETER :: WkPosYT4D9 = 819 - INTEGER(IntKi), PARAMETER :: WkPosYT5D1 = 820 - INTEGER(IntKi), PARAMETER :: WkPosYT5D2 = 821 - INTEGER(IntKi), PARAMETER :: WkPosYT5D3 = 822 - INTEGER(IntKi), PARAMETER :: WkPosYT5D4 = 823 - INTEGER(IntKi), PARAMETER :: WkPosYT5D5 = 824 - INTEGER(IntKi), PARAMETER :: WkPosYT5D6 = 825 - INTEGER(IntKi), PARAMETER :: WkPosYT5D7 = 826 - INTEGER(IntKi), PARAMETER :: WkPosYT5D8 = 827 - INTEGER(IntKi), PARAMETER :: WkPosYT5D9 = 828 - INTEGER(IntKi), PARAMETER :: WkPosYT6D1 = 829 - INTEGER(IntKi), PARAMETER :: WkPosYT6D2 = 830 - INTEGER(IntKi), PARAMETER :: WkPosYT6D3 = 831 - INTEGER(IntKi), PARAMETER :: WkPosYT6D4 = 832 - INTEGER(IntKi), PARAMETER :: WkPosYT6D5 = 833 - INTEGER(IntKi), PARAMETER :: WkPosYT6D6 = 834 - INTEGER(IntKi), PARAMETER :: WkPosYT6D7 = 835 - INTEGER(IntKi), PARAMETER :: WkPosYT6D8 = 836 - INTEGER(IntKi), PARAMETER :: WkPosYT6D9 = 837 - INTEGER(IntKi), PARAMETER :: WkPosYT7D1 = 838 - INTEGER(IntKi), PARAMETER :: WkPosYT7D2 = 839 - INTEGER(IntKi), PARAMETER :: WkPosYT7D3 = 840 - INTEGER(IntKi), PARAMETER :: WkPosYT7D4 = 841 - INTEGER(IntKi), PARAMETER :: WkPosYT7D5 = 842 - INTEGER(IntKi), PARAMETER :: WkPosYT7D6 = 843 - INTEGER(IntKi), PARAMETER :: WkPosYT7D7 = 844 - INTEGER(IntKi), PARAMETER :: WkPosYT7D8 = 845 - INTEGER(IntKi), PARAMETER :: WkPosYT7D9 = 846 - INTEGER(IntKi), PARAMETER :: WkPosYT8D1 = 847 - INTEGER(IntKi), PARAMETER :: WkPosYT8D2 = 848 - INTEGER(IntKi), PARAMETER :: WkPosYT8D3 = 849 - INTEGER(IntKi), PARAMETER :: WkPosYT8D4 = 850 - INTEGER(IntKi), PARAMETER :: WkPosYT8D5 = 851 - INTEGER(IntKi), PARAMETER :: WkPosYT8D6 = 852 - INTEGER(IntKi), PARAMETER :: WkPosYT8D7 = 853 - INTEGER(IntKi), PARAMETER :: WkPosYT8D8 = 854 - INTEGER(IntKi), PARAMETER :: WkPosYT8D9 = 855 - INTEGER(IntKi), PARAMETER :: WkPosYT9D1 = 856 - INTEGER(IntKi), PARAMETER :: WkPosYT9D2 = 857 - INTEGER(IntKi), PARAMETER :: WkPosYT9D3 = 858 - INTEGER(IntKi), PARAMETER :: WkPosYT9D4 = 859 - INTEGER(IntKi), PARAMETER :: WkPosYT9D5 = 860 - INTEGER(IntKi), PARAMETER :: WkPosYT9D6 = 861 - INTEGER(IntKi), PARAMETER :: WkPosYT9D7 = 862 - INTEGER(IntKi), PARAMETER :: WkPosYT9D8 = 863 - INTEGER(IntKi), PARAMETER :: WkPosYT9D9 = 864 - INTEGER(IntKi), PARAMETER :: WkPosZT1D1 = 865 - INTEGER(IntKi), PARAMETER :: WkPosZT1D2 = 866 - INTEGER(IntKi), PARAMETER :: WkPosZT1D3 = 867 - INTEGER(IntKi), PARAMETER :: WkPosZT1D4 = 868 - INTEGER(IntKi), PARAMETER :: WkPosZT1D5 = 869 - INTEGER(IntKi), PARAMETER :: WkPosZT1D6 = 870 - INTEGER(IntKi), PARAMETER :: WkPosZT1D7 = 871 - INTEGER(IntKi), PARAMETER :: WkPosZT1D8 = 872 - INTEGER(IntKi), PARAMETER :: WkPosZT1D9 = 873 - INTEGER(IntKi), PARAMETER :: WkPosZT2D1 = 874 - INTEGER(IntKi), PARAMETER :: WkPosZT2D2 = 875 - INTEGER(IntKi), PARAMETER :: WkPosZT2D3 = 876 - INTEGER(IntKi), PARAMETER :: WkPosZT2D4 = 877 - INTEGER(IntKi), PARAMETER :: WkPosZT2D5 = 878 - INTEGER(IntKi), PARAMETER :: WkPosZT2D6 = 879 - INTEGER(IntKi), PARAMETER :: WkPosZT2D7 = 880 - INTEGER(IntKi), PARAMETER :: WkPosZT2D8 = 881 - INTEGER(IntKi), PARAMETER :: WkPosZT2D9 = 882 - INTEGER(IntKi), PARAMETER :: WkPosZT3D1 = 883 - INTEGER(IntKi), PARAMETER :: WkPosZT3D2 = 884 - INTEGER(IntKi), PARAMETER :: WkPosZT3D3 = 885 - INTEGER(IntKi), PARAMETER :: WkPosZT3D4 = 886 - INTEGER(IntKi), PARAMETER :: WkPosZT3D5 = 887 - INTEGER(IntKi), PARAMETER :: WkPosZT3D6 = 888 - INTEGER(IntKi), PARAMETER :: WkPosZT3D7 = 889 - INTEGER(IntKi), PARAMETER :: WkPosZT3D8 = 890 - INTEGER(IntKi), PARAMETER :: WkPosZT3D9 = 891 - INTEGER(IntKi), PARAMETER :: WkPosZT4D1 = 892 - INTEGER(IntKi), PARAMETER :: WkPosZT4D2 = 893 - INTEGER(IntKi), PARAMETER :: WkPosZT4D3 = 894 - INTEGER(IntKi), PARAMETER :: WkPosZT4D4 = 895 - INTEGER(IntKi), PARAMETER :: WkPosZT4D5 = 896 - INTEGER(IntKi), PARAMETER :: WkPosZT4D6 = 897 - INTEGER(IntKi), PARAMETER :: WkPosZT4D7 = 898 - INTEGER(IntKi), PARAMETER :: WkPosZT4D8 = 899 - INTEGER(IntKi), PARAMETER :: WkPosZT4D9 = 900 - INTEGER(IntKi), PARAMETER :: WkPosZT5D1 = 901 - INTEGER(IntKi), PARAMETER :: WkPosZT5D2 = 902 - INTEGER(IntKi), PARAMETER :: WkPosZT5D3 = 903 - INTEGER(IntKi), PARAMETER :: WkPosZT5D4 = 904 - INTEGER(IntKi), PARAMETER :: WkPosZT5D5 = 905 - INTEGER(IntKi), PARAMETER :: WkPosZT5D6 = 906 - INTEGER(IntKi), PARAMETER :: WkPosZT5D7 = 907 - INTEGER(IntKi), PARAMETER :: WkPosZT5D8 = 908 - INTEGER(IntKi), PARAMETER :: WkPosZT5D9 = 909 - INTEGER(IntKi), PARAMETER :: WkPosZT6D1 = 910 - INTEGER(IntKi), PARAMETER :: WkPosZT6D2 = 911 - INTEGER(IntKi), PARAMETER :: WkPosZT6D3 = 912 - INTEGER(IntKi), PARAMETER :: WkPosZT6D4 = 913 - INTEGER(IntKi), PARAMETER :: WkPosZT6D5 = 914 - INTEGER(IntKi), PARAMETER :: WkPosZT6D6 = 915 - INTEGER(IntKi), PARAMETER :: WkPosZT6D7 = 916 - INTEGER(IntKi), PARAMETER :: WkPosZT6D8 = 917 - INTEGER(IntKi), PARAMETER :: WkPosZT6D9 = 918 - INTEGER(IntKi), PARAMETER :: WkPosZT7D1 = 919 - INTEGER(IntKi), PARAMETER :: WkPosZT7D2 = 920 - INTEGER(IntKi), PARAMETER :: WkPosZT7D3 = 921 - INTEGER(IntKi), PARAMETER :: WkPosZT7D4 = 922 - INTEGER(IntKi), PARAMETER :: WkPosZT7D5 = 923 - INTEGER(IntKi), PARAMETER :: WkPosZT7D6 = 924 - INTEGER(IntKi), PARAMETER :: WkPosZT7D7 = 925 - INTEGER(IntKi), PARAMETER :: WkPosZT7D8 = 926 - INTEGER(IntKi), PARAMETER :: WkPosZT7D9 = 927 - INTEGER(IntKi), PARAMETER :: WkPosZT8D1 = 928 - INTEGER(IntKi), PARAMETER :: WkPosZT8D2 = 929 - INTEGER(IntKi), PARAMETER :: WkPosZT8D3 = 930 - INTEGER(IntKi), PARAMETER :: WkPosZT8D4 = 931 - INTEGER(IntKi), PARAMETER :: WkPosZT8D5 = 932 - INTEGER(IntKi), PARAMETER :: WkPosZT8D6 = 933 - INTEGER(IntKi), PARAMETER :: WkPosZT8D7 = 934 - INTEGER(IntKi), PARAMETER :: WkPosZT8D8 = 935 - INTEGER(IntKi), PARAMETER :: WkPosZT8D9 = 936 - INTEGER(IntKi), PARAMETER :: WkPosZT9D1 = 937 - INTEGER(IntKi), PARAMETER :: WkPosZT9D2 = 938 - INTEGER(IntKi), PARAMETER :: WkPosZT9D3 = 939 - INTEGER(IntKi), PARAMETER :: WkPosZT9D4 = 940 - INTEGER(IntKi), PARAMETER :: WkPosZT9D5 = 941 - INTEGER(IntKi), PARAMETER :: WkPosZT9D6 = 942 - INTEGER(IntKi), PARAMETER :: WkPosZT9D7 = 943 - INTEGER(IntKi), PARAMETER :: WkPosZT9D8 = 944 - INTEGER(IntKi), PARAMETER :: WkPosZT9D9 = 945 - - - ! Advection: Deflection: and Meandering Velocity: - - INTEGER(IntKi), PARAMETER :: WkVelXT1D1 = 946 - INTEGER(IntKi), PARAMETER :: WkVelXT1D2 = 947 - INTEGER(IntKi), PARAMETER :: WkVelXT1D3 = 948 - INTEGER(IntKi), PARAMETER :: WkVelXT1D4 = 949 - INTEGER(IntKi), PARAMETER :: WkVelXT1D5 = 950 - INTEGER(IntKi), PARAMETER :: WkVelXT1D6 = 951 - INTEGER(IntKi), PARAMETER :: WkVelXT1D7 = 952 - INTEGER(IntKi), PARAMETER :: WkVelXT1D8 = 953 - INTEGER(IntKi), PARAMETER :: WkVelXT1D9 = 954 - INTEGER(IntKi), PARAMETER :: WkVelXT2D1 = 955 - INTEGER(IntKi), PARAMETER :: WkVelXT2D2 = 956 - INTEGER(IntKi), PARAMETER :: WkVelXT2D3 = 957 - INTEGER(IntKi), PARAMETER :: WkVelXT2D4 = 958 - INTEGER(IntKi), PARAMETER :: WkVelXT2D5 = 959 - INTEGER(IntKi), PARAMETER :: WkVelXT2D6 = 960 - INTEGER(IntKi), PARAMETER :: WkVelXT2D7 = 961 - INTEGER(IntKi), PARAMETER :: WkVelXT2D8 = 962 - INTEGER(IntKi), PARAMETER :: WkVelXT2D9 = 963 - INTEGER(IntKi), PARAMETER :: WkVelXT3D1 = 964 - INTEGER(IntKi), PARAMETER :: WkVelXT3D2 = 965 - INTEGER(IntKi), PARAMETER :: WkVelXT3D3 = 966 - INTEGER(IntKi), PARAMETER :: WkVelXT3D4 = 967 - INTEGER(IntKi), PARAMETER :: WkVelXT3D5 = 968 - INTEGER(IntKi), PARAMETER :: WkVelXT3D6 = 969 - INTEGER(IntKi), PARAMETER :: WkVelXT3D7 = 970 - INTEGER(IntKi), PARAMETER :: WkVelXT3D8 = 971 - INTEGER(IntKi), PARAMETER :: WkVelXT3D9 = 972 - INTEGER(IntKi), PARAMETER :: WkVelXT4D1 = 973 - INTEGER(IntKi), PARAMETER :: WkVelXT4D2 = 974 - INTEGER(IntKi), PARAMETER :: WkVelXT4D3 = 975 - INTEGER(IntKi), PARAMETER :: WkVelXT4D4 = 976 - INTEGER(IntKi), PARAMETER :: WkVelXT4D5 = 977 - INTEGER(IntKi), PARAMETER :: WkVelXT4D6 = 978 - INTEGER(IntKi), PARAMETER :: WkVelXT4D7 = 979 - INTEGER(IntKi), PARAMETER :: WkVelXT4D8 = 980 - INTEGER(IntKi), PARAMETER :: WkVelXT4D9 = 981 - INTEGER(IntKi), PARAMETER :: WkVelXT5D1 = 982 - INTEGER(IntKi), PARAMETER :: WkVelXT5D2 = 983 - INTEGER(IntKi), PARAMETER :: WkVelXT5D3 = 984 - INTEGER(IntKi), PARAMETER :: WkVelXT5D4 = 985 - INTEGER(IntKi), PARAMETER :: WkVelXT5D5 = 986 - INTEGER(IntKi), PARAMETER :: WkVelXT5D6 = 987 - INTEGER(IntKi), PARAMETER :: WkVelXT5D7 = 988 - INTEGER(IntKi), PARAMETER :: WkVelXT5D8 = 989 - INTEGER(IntKi), PARAMETER :: WkVelXT5D9 = 990 - INTEGER(IntKi), PARAMETER :: WkVelXT6D1 = 991 - INTEGER(IntKi), PARAMETER :: WkVelXT6D2 = 992 - INTEGER(IntKi), PARAMETER :: WkVelXT6D3 = 993 - INTEGER(IntKi), PARAMETER :: WkVelXT6D4 = 994 - INTEGER(IntKi), PARAMETER :: WkVelXT6D5 = 995 - INTEGER(IntKi), PARAMETER :: WkVelXT6D6 = 996 - INTEGER(IntKi), PARAMETER :: WkVelXT6D7 = 997 - INTEGER(IntKi), PARAMETER :: WkVelXT6D8 = 998 - INTEGER(IntKi), PARAMETER :: WkVelXT6D9 = 999 - INTEGER(IntKi), PARAMETER :: WkVelXT7D1 = 1000 - INTEGER(IntKi), PARAMETER :: WkVelXT7D2 = 1001 - INTEGER(IntKi), PARAMETER :: WkVelXT7D3 = 1002 - INTEGER(IntKi), PARAMETER :: WkVelXT7D4 = 1003 - INTEGER(IntKi), PARAMETER :: WkVelXT7D5 = 1004 - INTEGER(IntKi), PARAMETER :: WkVelXT7D6 = 1005 - INTEGER(IntKi), PARAMETER :: WkVelXT7D7 = 1006 - INTEGER(IntKi), PARAMETER :: WkVelXT7D8 = 1007 - INTEGER(IntKi), PARAMETER :: WkVelXT7D9 = 1008 - INTEGER(IntKi), PARAMETER :: WkVelXT8D1 = 1009 - INTEGER(IntKi), PARAMETER :: WkVelXT8D2 = 1010 - INTEGER(IntKi), PARAMETER :: WkVelXT8D3 = 1011 - INTEGER(IntKi), PARAMETER :: WkVelXT8D4 = 1012 - INTEGER(IntKi), PARAMETER :: WkVelXT8D5 = 1013 - INTEGER(IntKi), PARAMETER :: WkVelXT8D6 = 1014 - INTEGER(IntKi), PARAMETER :: WkVelXT8D7 = 1015 - INTEGER(IntKi), PARAMETER :: WkVelXT8D8 = 1016 - INTEGER(IntKi), PARAMETER :: WkVelXT8D9 = 1017 - INTEGER(IntKi), PARAMETER :: WkVelXT9D1 = 1018 - INTEGER(IntKi), PARAMETER :: WkVelXT9D2 = 1019 - INTEGER(IntKi), PARAMETER :: WkVelXT9D3 = 1020 - INTEGER(IntKi), PARAMETER :: WkVelXT9D4 = 1021 - INTEGER(IntKi), PARAMETER :: WkVelXT9D5 = 1022 - INTEGER(IntKi), PARAMETER :: WkVelXT9D6 = 1023 - INTEGER(IntKi), PARAMETER :: WkVelXT9D7 = 1024 - INTEGER(IntKi), PARAMETER :: WkVelXT9D8 = 1025 - INTEGER(IntKi), PARAMETER :: WkVelXT9D9 = 1026 - INTEGER(IntKi), PARAMETER :: WkVelYT1D1 = 1027 - INTEGER(IntKi), PARAMETER :: WkVelYT1D2 = 1028 - INTEGER(IntKi), PARAMETER :: WkVelYT1D3 = 1029 - INTEGER(IntKi), PARAMETER :: WkVelYT1D4 = 1030 - INTEGER(IntKi), PARAMETER :: WkVelYT1D5 = 1031 - INTEGER(IntKi), PARAMETER :: WkVelYT1D6 = 1032 - INTEGER(IntKi), PARAMETER :: WkVelYT1D7 = 1033 - INTEGER(IntKi), PARAMETER :: WkVelYT1D8 = 1034 - INTEGER(IntKi), PARAMETER :: WkVelYT1D9 = 1035 - INTEGER(IntKi), PARAMETER :: WkVelYT2D1 = 1036 - INTEGER(IntKi), PARAMETER :: WkVelYT2D2 = 1037 - INTEGER(IntKi), PARAMETER :: WkVelYT2D3 = 1038 - INTEGER(IntKi), PARAMETER :: WkVelYT2D4 = 1039 - INTEGER(IntKi), PARAMETER :: WkVelYT2D5 = 1040 - INTEGER(IntKi), PARAMETER :: WkVelYT2D6 = 1041 - INTEGER(IntKi), PARAMETER :: WkVelYT2D7 = 1042 - INTEGER(IntKi), PARAMETER :: WkVelYT2D8 = 1043 - INTEGER(IntKi), PARAMETER :: WkVelYT2D9 = 1044 - INTEGER(IntKi), PARAMETER :: WkVelYT3D1 = 1045 - INTEGER(IntKi), PARAMETER :: WkVelYT3D2 = 1046 - INTEGER(IntKi), PARAMETER :: WkVelYT3D3 = 1047 - INTEGER(IntKi), PARAMETER :: WkVelYT3D4 = 1048 - INTEGER(IntKi), PARAMETER :: WkVelYT3D5 = 1049 - INTEGER(IntKi), PARAMETER :: WkVelYT3D6 = 1050 - INTEGER(IntKi), PARAMETER :: WkVelYT3D7 = 1051 - INTEGER(IntKi), PARAMETER :: WkVelYT3D8 = 1052 - INTEGER(IntKi), PARAMETER :: WkVelYT3D9 = 1053 - INTEGER(IntKi), PARAMETER :: WkVelYT4D1 = 1054 - INTEGER(IntKi), PARAMETER :: WkVelYT4D2 = 1055 - INTEGER(IntKi), PARAMETER :: WkVelYT4D3 = 1056 - INTEGER(IntKi), PARAMETER :: WkVelYT4D4 = 1057 - INTEGER(IntKi), PARAMETER :: WkVelYT4D5 = 1058 - INTEGER(IntKi), PARAMETER :: WkVelYT4D6 = 1059 - INTEGER(IntKi), PARAMETER :: WkVelYT4D7 = 1060 - INTEGER(IntKi), PARAMETER :: WkVelYT4D8 = 1061 - INTEGER(IntKi), PARAMETER :: WkVelYT4D9 = 1062 - INTEGER(IntKi), PARAMETER :: WkVelYT5D1 = 1063 - INTEGER(IntKi), PARAMETER :: WkVelYT5D2 = 1064 - INTEGER(IntKi), PARAMETER :: WkVelYT5D3 = 1065 - INTEGER(IntKi), PARAMETER :: WkVelYT5D4 = 1066 - INTEGER(IntKi), PARAMETER :: WkVelYT5D5 = 1067 - INTEGER(IntKi), PARAMETER :: WkVelYT5D6 = 1068 - INTEGER(IntKi), PARAMETER :: WkVelYT5D7 = 1069 - INTEGER(IntKi), PARAMETER :: WkVelYT5D8 = 1070 - INTEGER(IntKi), PARAMETER :: WkVelYT5D9 = 1071 - INTEGER(IntKi), PARAMETER :: WkVelYT6D1 = 1072 - INTEGER(IntKi), PARAMETER :: WkVelYT6D2 = 1073 - INTEGER(IntKi), PARAMETER :: WkVelYT6D3 = 1074 - INTEGER(IntKi), PARAMETER :: WkVelYT6D4 = 1075 - INTEGER(IntKi), PARAMETER :: WkVelYT6D5 = 1076 - INTEGER(IntKi), PARAMETER :: WkVelYT6D6 = 1077 - INTEGER(IntKi), PARAMETER :: WkVelYT6D7 = 1078 - INTEGER(IntKi), PARAMETER :: WkVelYT6D8 = 1079 - INTEGER(IntKi), PARAMETER :: WkVelYT6D9 = 1080 - INTEGER(IntKi), PARAMETER :: WkVelYT7D1 = 1081 - INTEGER(IntKi), PARAMETER :: WkVelYT7D2 = 1082 - INTEGER(IntKi), PARAMETER :: WkVelYT7D3 = 1083 - INTEGER(IntKi), PARAMETER :: WkVelYT7D4 = 1084 - INTEGER(IntKi), PARAMETER :: WkVelYT7D5 = 1085 - INTEGER(IntKi), PARAMETER :: WkVelYT7D6 = 1086 - INTEGER(IntKi), PARAMETER :: WkVelYT7D7 = 1087 - INTEGER(IntKi), PARAMETER :: WkVelYT7D8 = 1088 - INTEGER(IntKi), PARAMETER :: WkVelYT7D9 = 1089 - INTEGER(IntKi), PARAMETER :: WkVelYT8D1 = 1090 - INTEGER(IntKi), PARAMETER :: WkVelYT8D2 = 1091 - INTEGER(IntKi), PARAMETER :: WkVelYT8D3 = 1092 - INTEGER(IntKi), PARAMETER :: WkVelYT8D4 = 1093 - INTEGER(IntKi), PARAMETER :: WkVelYT8D5 = 1094 - INTEGER(IntKi), PARAMETER :: WkVelYT8D6 = 1095 - INTEGER(IntKi), PARAMETER :: WkVelYT8D7 = 1096 - INTEGER(IntKi), PARAMETER :: WkVelYT8D8 = 1097 - INTEGER(IntKi), PARAMETER :: WkVelYT8D9 = 1098 - INTEGER(IntKi), PARAMETER :: WkVelYT9D1 = 1099 - INTEGER(IntKi), PARAMETER :: WkVelYT9D2 = 1100 - INTEGER(IntKi), PARAMETER :: WkVelYT9D3 = 1101 - INTEGER(IntKi), PARAMETER :: WkVelYT9D4 = 1102 - INTEGER(IntKi), PARAMETER :: WkVelYT9D5 = 1103 - INTEGER(IntKi), PARAMETER :: WkVelYT9D6 = 1104 - INTEGER(IntKi), PARAMETER :: WkVelYT9D7 = 1105 - INTEGER(IntKi), PARAMETER :: WkVelYT9D8 = 1106 - INTEGER(IntKi), PARAMETER :: WkVelYT9D9 = 1107 - INTEGER(IntKi), PARAMETER :: WkVelZT1D1 = 1108 - INTEGER(IntKi), PARAMETER :: WkVelZT1D2 = 1109 - INTEGER(IntKi), PARAMETER :: WkVelZT1D3 = 1110 - INTEGER(IntKi), PARAMETER :: WkVelZT1D4 = 1111 - INTEGER(IntKi), PARAMETER :: WkVelZT1D5 = 1112 - INTEGER(IntKi), PARAMETER :: WkVelZT1D6 = 1113 - INTEGER(IntKi), PARAMETER :: WkVelZT1D7 = 1114 - INTEGER(IntKi), PARAMETER :: WkVelZT1D8 = 1115 - INTEGER(IntKi), PARAMETER :: WkVelZT1D9 = 1116 - INTEGER(IntKi), PARAMETER :: WkVelZT2D1 = 1117 - INTEGER(IntKi), PARAMETER :: WkVelZT2D2 = 1118 - INTEGER(IntKi), PARAMETER :: WkVelZT2D3 = 1119 - INTEGER(IntKi), PARAMETER :: WkVelZT2D4 = 1120 - INTEGER(IntKi), PARAMETER :: WkVelZT2D5 = 1121 - INTEGER(IntKi), PARAMETER :: WkVelZT2D6 = 1122 - INTEGER(IntKi), PARAMETER :: WkVelZT2D7 = 1123 - INTEGER(IntKi), PARAMETER :: WkVelZT2D8 = 1124 - INTEGER(IntKi), PARAMETER :: WkVelZT2D9 = 1125 - INTEGER(IntKi), PARAMETER :: WkVelZT3D1 = 1126 - INTEGER(IntKi), PARAMETER :: WkVelZT3D2 = 1127 - INTEGER(IntKi), PARAMETER :: WkVelZT3D3 = 1128 - INTEGER(IntKi), PARAMETER :: WkVelZT3D4 = 1129 - INTEGER(IntKi), PARAMETER :: WkVelZT3D5 = 1130 - INTEGER(IntKi), PARAMETER :: WkVelZT3D6 = 1131 - INTEGER(IntKi), PARAMETER :: WkVelZT3D7 = 1132 - INTEGER(IntKi), PARAMETER :: WkVelZT3D8 = 1133 - INTEGER(IntKi), PARAMETER :: WkVelZT3D9 = 1134 - INTEGER(IntKi), PARAMETER :: WkVelZT4D1 = 1135 - INTEGER(IntKi), PARAMETER :: WkVelZT4D2 = 1136 - INTEGER(IntKi), PARAMETER :: WkVelZT4D3 = 1137 - INTEGER(IntKi), PARAMETER :: WkVelZT4D4 = 1138 - INTEGER(IntKi), PARAMETER :: WkVelZT4D5 = 1139 - INTEGER(IntKi), PARAMETER :: WkVelZT4D6 = 1140 - INTEGER(IntKi), PARAMETER :: WkVelZT4D7 = 1141 - INTEGER(IntKi), PARAMETER :: WkVelZT4D8 = 1142 - INTEGER(IntKi), PARAMETER :: WkVelZT4D9 = 1143 - INTEGER(IntKi), PARAMETER :: WkVelZT5D1 = 1144 - INTEGER(IntKi), PARAMETER :: WkVelZT5D2 = 1145 - INTEGER(IntKi), PARAMETER :: WkVelZT5D3 = 1146 - INTEGER(IntKi), PARAMETER :: WkVelZT5D4 = 1147 - INTEGER(IntKi), PARAMETER :: WkVelZT5D5 = 1148 - INTEGER(IntKi), PARAMETER :: WkVelZT5D6 = 1149 - INTEGER(IntKi), PARAMETER :: WkVelZT5D7 = 1150 - INTEGER(IntKi), PARAMETER :: WkVelZT5D8 = 1151 - INTEGER(IntKi), PARAMETER :: WkVelZT5D9 = 1152 - INTEGER(IntKi), PARAMETER :: WkVelZT6D1 = 1153 - INTEGER(IntKi), PARAMETER :: WkVelZT6D2 = 1154 - INTEGER(IntKi), PARAMETER :: WkVelZT6D3 = 1155 - INTEGER(IntKi), PARAMETER :: WkVelZT6D4 = 1156 - INTEGER(IntKi), PARAMETER :: WkVelZT6D5 = 1157 - INTEGER(IntKi), PARAMETER :: WkVelZT6D6 = 1158 - INTEGER(IntKi), PARAMETER :: WkVelZT6D7 = 1159 - INTEGER(IntKi), PARAMETER :: WkVelZT6D8 = 1160 - INTEGER(IntKi), PARAMETER :: WkVelZT6D9 = 1161 - INTEGER(IntKi), PARAMETER :: WkVelZT7D1 = 1162 - INTEGER(IntKi), PARAMETER :: WkVelZT7D2 = 1163 - INTEGER(IntKi), PARAMETER :: WkVelZT7D3 = 1164 - INTEGER(IntKi), PARAMETER :: WkVelZT7D4 = 1165 - INTEGER(IntKi), PARAMETER :: WkVelZT7D5 = 1166 - INTEGER(IntKi), PARAMETER :: WkVelZT7D6 = 1167 - INTEGER(IntKi), PARAMETER :: WkVelZT7D7 = 1168 - INTEGER(IntKi), PARAMETER :: WkVelZT7D8 = 1169 - INTEGER(IntKi), PARAMETER :: WkVelZT7D9 = 1170 - INTEGER(IntKi), PARAMETER :: WkVelZT8D1 = 1171 - INTEGER(IntKi), PARAMETER :: WkVelZT8D2 = 1172 - INTEGER(IntKi), PARAMETER :: WkVelZT8D3 = 1173 - INTEGER(IntKi), PARAMETER :: WkVelZT8D4 = 1174 - INTEGER(IntKi), PARAMETER :: WkVelZT8D5 = 1175 - INTEGER(IntKi), PARAMETER :: WkVelZT8D6 = 1176 - INTEGER(IntKi), PARAMETER :: WkVelZT8D7 = 1177 - INTEGER(IntKi), PARAMETER :: WkVelZT8D8 = 1178 - INTEGER(IntKi), PARAMETER :: WkVelZT8D9 = 1179 - INTEGER(IntKi), PARAMETER :: WkVelZT9D1 = 1180 - INTEGER(IntKi), PARAMETER :: WkVelZT9D2 = 1181 - INTEGER(IntKi), PARAMETER :: WkVelZT9D3 = 1182 - INTEGER(IntKi), PARAMETER :: WkVelZT9D4 = 1183 - INTEGER(IntKi), PARAMETER :: WkVelZT9D5 = 1184 - INTEGER(IntKi), PARAMETER :: WkVelZT9D6 = 1185 - INTEGER(IntKi), PARAMETER :: WkVelZT9D7 = 1186 - INTEGER(IntKi), PARAMETER :: WkVelZT9D8 = 1187 - INTEGER(IntKi), PARAMETER :: WkVelZT9D9 = 1188 - - - ! Wake Diameter: - - INTEGER(IntKi), PARAMETER :: WkDiamT1D1 = 1189 - INTEGER(IntKi), PARAMETER :: WkDiamT1D2 = 1190 - INTEGER(IntKi), PARAMETER :: WkDiamT1D3 = 1191 - INTEGER(IntKi), PARAMETER :: WkDiamT1D4 = 1192 - INTEGER(IntKi), PARAMETER :: WkDiamT1D5 = 1193 - INTEGER(IntKi), PARAMETER :: WkDiamT1D6 = 1194 - INTEGER(IntKi), PARAMETER :: WkDiamT1D7 = 1195 - INTEGER(IntKi), PARAMETER :: WkDiamT1D8 = 1196 - INTEGER(IntKi), PARAMETER :: WkDiamT1D9 = 1197 - INTEGER(IntKi), PARAMETER :: WkDiamT2D1 = 1198 - INTEGER(IntKi), PARAMETER :: WkDiamT2D2 = 1199 - INTEGER(IntKi), PARAMETER :: WkDiamT2D3 = 1200 - INTEGER(IntKi), PARAMETER :: WkDiamT2D4 = 1201 - INTEGER(IntKi), PARAMETER :: WkDiamT2D5 = 1202 - INTEGER(IntKi), PARAMETER :: WkDiamT2D6 = 1203 - INTEGER(IntKi), PARAMETER :: WkDiamT2D7 = 1204 - INTEGER(IntKi), PARAMETER :: WkDiamT2D8 = 1205 - INTEGER(IntKi), PARAMETER :: WkDiamT2D9 = 1206 - INTEGER(IntKi), PARAMETER :: WkDiamT3D1 = 1207 - INTEGER(IntKi), PARAMETER :: WkDiamT3D2 = 1208 - INTEGER(IntKi), PARAMETER :: WkDiamT3D3 = 1209 - INTEGER(IntKi), PARAMETER :: WkDiamT3D4 = 1210 - INTEGER(IntKi), PARAMETER :: WkDiamT3D5 = 1211 - INTEGER(IntKi), PARAMETER :: WkDiamT3D6 = 1212 - INTEGER(IntKi), PARAMETER :: WkDiamT3D7 = 1213 - INTEGER(IntKi), PARAMETER :: WkDiamT3D8 = 1214 - INTEGER(IntKi), PARAMETER :: WkDiamT3D9 = 1215 - INTEGER(IntKi), PARAMETER :: WkDiamT4D1 = 1216 - INTEGER(IntKi), PARAMETER :: WkDiamT4D2 = 1217 - INTEGER(IntKi), PARAMETER :: WkDiamT4D3 = 1218 - INTEGER(IntKi), PARAMETER :: WkDiamT4D4 = 1219 - INTEGER(IntKi), PARAMETER :: WkDiamT4D5 = 1220 - INTEGER(IntKi), PARAMETER :: WkDiamT4D6 = 1221 - INTEGER(IntKi), PARAMETER :: WkDiamT4D7 = 1222 - INTEGER(IntKi), PARAMETER :: WkDiamT4D8 = 1223 - INTEGER(IntKi), PARAMETER :: WkDiamT4D9 = 1224 - INTEGER(IntKi), PARAMETER :: WkDiamT5D1 = 1225 - INTEGER(IntKi), PARAMETER :: WkDiamT5D2 = 1226 - INTEGER(IntKi), PARAMETER :: WkDiamT5D3 = 1227 - INTEGER(IntKi), PARAMETER :: WkDiamT5D4 = 1228 - INTEGER(IntKi), PARAMETER :: WkDiamT5D5 = 1229 - INTEGER(IntKi), PARAMETER :: WkDiamT5D6 = 1230 - INTEGER(IntKi), PARAMETER :: WkDiamT5D7 = 1231 - INTEGER(IntKi), PARAMETER :: WkDiamT5D8 = 1232 - INTEGER(IntKi), PARAMETER :: WkDiamT5D9 = 1233 - INTEGER(IntKi), PARAMETER :: WkDiamT6D1 = 1234 - INTEGER(IntKi), PARAMETER :: WkDiamT6D2 = 1235 - INTEGER(IntKi), PARAMETER :: WkDiamT6D3 = 1236 - INTEGER(IntKi), PARAMETER :: WkDiamT6D4 = 1237 - INTEGER(IntKi), PARAMETER :: WkDiamT6D5 = 1238 - INTEGER(IntKi), PARAMETER :: WkDiamT6D6 = 1239 - INTEGER(IntKi), PARAMETER :: WkDiamT6D7 = 1240 - INTEGER(IntKi), PARAMETER :: WkDiamT6D8 = 1241 - INTEGER(IntKi), PARAMETER :: WkDiamT6D9 = 1242 - INTEGER(IntKi), PARAMETER :: WkDiamT7D1 = 1243 - INTEGER(IntKi), PARAMETER :: WkDiamT7D2 = 1244 - INTEGER(IntKi), PARAMETER :: WkDiamT7D3 = 1245 - INTEGER(IntKi), PARAMETER :: WkDiamT7D4 = 1246 - INTEGER(IntKi), PARAMETER :: WkDiamT7D5 = 1247 - INTEGER(IntKi), PARAMETER :: WkDiamT7D6 = 1248 - INTEGER(IntKi), PARAMETER :: WkDiamT7D7 = 1249 - INTEGER(IntKi), PARAMETER :: WkDiamT7D8 = 1250 - INTEGER(IntKi), PARAMETER :: WkDiamT7D9 = 1251 - INTEGER(IntKi), PARAMETER :: WkDiamT8D1 = 1252 - INTEGER(IntKi), PARAMETER :: WkDiamT8D2 = 1253 - INTEGER(IntKi), PARAMETER :: WkDiamT8D3 = 1254 - INTEGER(IntKi), PARAMETER :: WkDiamT8D4 = 1255 - INTEGER(IntKi), PARAMETER :: WkDiamT8D5 = 1256 - INTEGER(IntKi), PARAMETER :: WkDiamT8D6 = 1257 - INTEGER(IntKi), PARAMETER :: WkDiamT8D7 = 1258 - INTEGER(IntKi), PARAMETER :: WkDiamT8D8 = 1259 - INTEGER(IntKi), PARAMETER :: WkDiamT8D9 = 1260 - INTEGER(IntKi), PARAMETER :: WkDiamT9D1 = 1261 - INTEGER(IntKi), PARAMETER :: WkDiamT9D2 = 1262 - INTEGER(IntKi), PARAMETER :: WkDiamT9D3 = 1263 - INTEGER(IntKi), PARAMETER :: WkDiamT9D4 = 1264 - INTEGER(IntKi), PARAMETER :: WkDiamT9D5 = 1265 - INTEGER(IntKi), PARAMETER :: WkDiamT9D6 = 1266 - INTEGER(IntKi), PARAMETER :: WkDiamT9D7 = 1267 - INTEGER(IntKi), PARAMETER :: WkDiamT9D8 = 1268 - INTEGER(IntKi), PARAMETER :: WkDiamT9D9 = 1269 - - - ! Axial and Radial Wake Velocity Deficits: - - INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D1 = 1270 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D2 = 1271 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D3 = 1272 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D4 = 1273 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D5 = 1274 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D6 = 1275 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D7 = 1276 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D8 = 1277 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D9 = 1278 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D1 = 1279 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D2 = 1280 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D3 = 1281 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D4 = 1282 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D5 = 1283 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D6 = 1284 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D7 = 1285 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D8 = 1286 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D9 = 1287 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D1 = 1288 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D2 = 1289 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D3 = 1290 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D4 = 1291 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D5 = 1292 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D6 = 1293 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D7 = 1294 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D8 = 1295 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D9 = 1296 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D1 = 1297 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D2 = 1298 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D3 = 1299 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D4 = 1300 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D5 = 1301 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D6 = 1302 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D7 = 1303 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D8 = 1304 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D9 = 1305 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D1 = 1306 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D2 = 1307 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D3 = 1308 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D4 = 1309 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D5 = 1310 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D6 = 1311 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D7 = 1312 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D8 = 1313 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D9 = 1314 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D1 = 1315 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D2 = 1316 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D3 = 1317 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D4 = 1318 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D5 = 1319 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D6 = 1320 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D7 = 1321 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D8 = 1322 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D9 = 1323 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D1 = 1324 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D2 = 1325 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D3 = 1326 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D4 = 1327 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D5 = 1328 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D6 = 1329 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D7 = 1330 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D8 = 1331 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D9 = 1332 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D1 = 1333 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D2 = 1334 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D3 = 1335 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D4 = 1336 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D5 = 1337 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D6 = 1338 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D7 = 1339 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D8 = 1340 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D9 = 1341 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D1 = 1342 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D2 = 1343 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D3 = 1344 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D4 = 1345 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D5 = 1346 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D6 = 1347 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D7 = 1348 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D8 = 1349 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D9 = 1350 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D1 = 1351 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D2 = 1352 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D3 = 1353 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D4 = 1354 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D5 = 1355 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D6 = 1356 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D7 = 1357 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D8 = 1358 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D9 = 1359 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D1 = 1360 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D2 = 1361 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D3 = 1362 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D4 = 1363 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D5 = 1364 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D6 = 1365 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D7 = 1366 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D8 = 1367 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D9 = 1368 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D1 = 1369 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D2 = 1370 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D3 = 1371 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D4 = 1372 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D5 = 1373 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D6 = 1374 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D7 = 1375 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D8 = 1376 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D9 = 1377 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D1 = 1378 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D2 = 1379 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D3 = 1380 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D4 = 1381 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D5 = 1382 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D6 = 1383 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D7 = 1384 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D8 = 1385 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D9 = 1386 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D1 = 1387 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D2 = 1388 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D3 = 1389 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D4 = 1390 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D5 = 1391 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D6 = 1392 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D7 = 1393 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D8 = 1394 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D9 = 1395 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D1 = 1396 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D2 = 1397 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D3 = 1398 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D4 = 1399 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D5 = 1400 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D6 = 1401 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D7 = 1402 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D8 = 1403 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D9 = 1404 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D1 = 1405 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D2 = 1406 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D3 = 1407 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D4 = 1408 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D5 = 1409 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D6 = 1410 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D7 = 1411 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D8 = 1412 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D9 = 1413 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D1 = 1414 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D2 = 1415 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D3 = 1416 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D4 = 1417 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D5 = 1418 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D6 = 1419 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D7 = 1420 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D8 = 1421 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D9 = 1422 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D1 = 1423 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D2 = 1424 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D3 = 1425 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D4 = 1426 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D5 = 1427 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D6 = 1428 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D7 = 1429 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D8 = 1430 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D9 = 1431 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D1 = 1432 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D2 = 1433 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D3 = 1434 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D4 = 1435 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D5 = 1436 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D6 = 1437 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D7 = 1438 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D8 = 1439 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D9 = 1440 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D1 = 1441 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D2 = 1442 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D3 = 1443 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D4 = 1444 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D5 = 1445 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D6 = 1446 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D7 = 1447 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D8 = 1448 - INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D9 = 1449 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D1 = 1450 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D2 = 1451 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D3 = 1452 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D4 = 1453 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D5 = 1454 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D6 = 1455 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D7 = 1456 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D8 = 1457 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D9 = 1458 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D1 = 1459 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D2 = 1460 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D3 = 1461 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D4 = 1462 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D5 = 1463 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D6 = 1464 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D7 = 1465 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D8 = 1466 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D9 = 1467 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D1 = 1468 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D2 = 1469 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D3 = 1470 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D4 = 1471 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D5 = 1472 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D6 = 1473 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D7 = 1474 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D8 = 1475 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D9 = 1476 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D1 = 1477 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D2 = 1478 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D3 = 1479 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D4 = 1480 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D5 = 1481 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D6 = 1482 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D7 = 1483 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D8 = 1484 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D9 = 1485 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D1 = 1486 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D2 = 1487 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D3 = 1488 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D4 = 1489 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D5 = 1490 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D6 = 1491 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D7 = 1492 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D8 = 1493 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D9 = 1494 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D1 = 1495 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D2 = 1496 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D3 = 1497 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D4 = 1498 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D5 = 1499 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D6 = 1500 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D7 = 1501 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D8 = 1502 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D9 = 1503 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D1 = 1504 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D2 = 1505 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D3 = 1506 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D4 = 1507 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D5 = 1508 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D6 = 1509 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D7 = 1510 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D8 = 1511 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D9 = 1512 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D1 = 1513 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D2 = 1514 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D3 = 1515 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D4 = 1516 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D5 = 1517 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D6 = 1518 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D7 = 1519 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D8 = 1520 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D9 = 1521 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D1 = 1522 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D2 = 1523 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D3 = 1524 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D4 = 1525 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D5 = 1526 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D6 = 1527 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D7 = 1528 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D8 = 1529 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D9 = 1530 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D1 = 1531 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D2 = 1532 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D3 = 1533 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D4 = 1534 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D5 = 1535 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D6 = 1536 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D7 = 1537 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D8 = 1538 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D9 = 1539 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D1 = 1540 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D2 = 1541 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D3 = 1542 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D4 = 1543 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D5 = 1544 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D6 = 1545 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D7 = 1546 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D8 = 1547 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D9 = 1548 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D1 = 1549 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D2 = 1550 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D3 = 1551 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D4 = 1552 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D5 = 1553 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D6 = 1554 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D7 = 1555 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D8 = 1556 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D9 = 1557 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D1 = 1558 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D2 = 1559 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D3 = 1560 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D4 = 1561 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D5 = 1562 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D6 = 1563 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D7 = 1564 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D8 = 1565 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D9 = 1566 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D1 = 1567 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D2 = 1568 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D3 = 1569 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D4 = 1570 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D5 = 1571 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D6 = 1572 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D7 = 1573 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D8 = 1574 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D9 = 1575 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D1 = 1576 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D2 = 1577 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D3 = 1578 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D4 = 1579 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D5 = 1580 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D6 = 1581 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D7 = 1582 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D8 = 1583 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D9 = 1584 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D1 = 1585 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D2 = 1586 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D3 = 1587 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D4 = 1588 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D5 = 1589 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D6 = 1590 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D7 = 1591 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D8 = 1592 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D9 = 1593 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D1 = 1594 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D2 = 1595 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D3 = 1596 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D4 = 1597 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D5 = 1598 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D6 = 1599 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D7 = 1600 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D8 = 1601 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D9 = 1602 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D1 = 1603 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D2 = 1604 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D3 = 1605 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D4 = 1606 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D5 = 1607 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D6 = 1608 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D7 = 1609 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D8 = 1610 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D9 = 1611 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D1 = 1612 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D2 = 1613 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D3 = 1614 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D4 = 1615 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D5 = 1616 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D6 = 1617 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D7 = 1618 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D8 = 1619 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D9 = 1620 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D1 = 1621 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D2 = 1622 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D3 = 1623 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D4 = 1624 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D5 = 1625 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D6 = 1626 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D7 = 1627 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D8 = 1628 - INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D9 = 1629 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D1 = 1630 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D2 = 1631 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D3 = 1632 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D4 = 1633 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D5 = 1634 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D6 = 1635 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D7 = 1636 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D8 = 1637 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D9 = 1638 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D1 = 1639 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D2 = 1640 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D3 = 1641 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D4 = 1642 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D5 = 1643 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D6 = 1644 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D7 = 1645 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D8 = 1646 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D9 = 1647 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D1 = 1648 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D2 = 1649 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D3 = 1650 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D4 = 1651 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D5 = 1652 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D6 = 1653 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D7 = 1654 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D8 = 1655 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D9 = 1656 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D1 = 1657 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D2 = 1658 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D3 = 1659 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D4 = 1660 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D5 = 1661 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D6 = 1662 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D7 = 1663 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D8 = 1664 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D9 = 1665 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D1 = 1666 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D2 = 1667 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D3 = 1668 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D4 = 1669 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D5 = 1670 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D6 = 1671 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D7 = 1672 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D8 = 1673 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D9 = 1674 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D1 = 1675 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D2 = 1676 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D3 = 1677 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D4 = 1678 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D5 = 1679 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D6 = 1680 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D7 = 1681 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D8 = 1682 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D9 = 1683 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D1 = 1684 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D2 = 1685 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D3 = 1686 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D4 = 1687 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D5 = 1688 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D6 = 1689 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D7 = 1690 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D8 = 1691 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D9 = 1692 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D1 = 1693 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D2 = 1694 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D3 = 1695 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D4 = 1696 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D5 = 1697 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D6 = 1698 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D7 = 1699 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D8 = 1700 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D9 = 1701 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D1 = 1702 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D2 = 1703 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D3 = 1704 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D4 = 1705 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D5 = 1706 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D6 = 1707 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D7 = 1708 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D8 = 1709 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D9 = 1710 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D1 = 1711 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D2 = 1712 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D3 = 1713 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D4 = 1714 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D5 = 1715 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D6 = 1716 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D7 = 1717 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D8 = 1718 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D9 = 1719 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D1 = 1720 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D2 = 1721 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D3 = 1722 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D4 = 1723 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D5 = 1724 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D6 = 1725 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D7 = 1726 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D8 = 1727 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D9 = 1728 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D1 = 1729 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D2 = 1730 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D3 = 1731 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D4 = 1732 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D5 = 1733 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D6 = 1734 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D7 = 1735 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D8 = 1736 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D9 = 1737 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D1 = 1738 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D2 = 1739 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D3 = 1740 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D4 = 1741 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D5 = 1742 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D6 = 1743 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D7 = 1744 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D8 = 1745 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D9 = 1746 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D1 = 1747 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D2 = 1748 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D3 = 1749 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D4 = 1750 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D5 = 1751 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D6 = 1752 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D7 = 1753 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D8 = 1754 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D9 = 1755 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D1 = 1756 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D2 = 1757 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D3 = 1758 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D4 = 1759 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D5 = 1760 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D6 = 1761 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D7 = 1762 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D8 = 1763 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D9 = 1764 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D1 = 1765 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D2 = 1766 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D3 = 1767 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D4 = 1768 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D5 = 1769 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D6 = 1770 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D7 = 1771 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D8 = 1772 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D9 = 1773 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D1 = 1774 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D2 = 1775 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D3 = 1776 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D4 = 1777 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D5 = 1778 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D6 = 1779 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D7 = 1780 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D8 = 1781 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D9 = 1782 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D1 = 1783 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D2 = 1784 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D3 = 1785 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D4 = 1786 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D5 = 1787 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D6 = 1788 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D7 = 1789 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D8 = 1790 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D9 = 1791 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D1 = 1792 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D2 = 1793 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D3 = 1794 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D4 = 1795 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D5 = 1796 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D6 = 1797 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D7 = 1798 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D8 = 1799 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D9 = 1800 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D1 = 1801 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D2 = 1802 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D3 = 1803 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D4 = 1804 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D5 = 1805 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D6 = 1806 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D7 = 1807 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D8 = 1808 - INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D9 = 1809 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D1 = 1810 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D2 = 1811 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D3 = 1812 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D4 = 1813 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D5 = 1814 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D6 = 1815 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D7 = 1816 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D8 = 1817 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D9 = 1818 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D1 = 1819 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D2 = 1820 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D3 = 1821 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D4 = 1822 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D5 = 1823 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D6 = 1824 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D7 = 1825 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D8 = 1826 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D9 = 1827 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D1 = 1828 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D2 = 1829 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D3 = 1830 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D4 = 1831 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D5 = 1832 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D6 = 1833 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D7 = 1834 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D8 = 1835 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D9 = 1836 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D1 = 1837 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D2 = 1838 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D3 = 1839 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D4 = 1840 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D5 = 1841 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D6 = 1842 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D7 = 1843 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D8 = 1844 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D9 = 1845 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D1 = 1846 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D2 = 1847 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D3 = 1848 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D4 = 1849 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D5 = 1850 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D6 = 1851 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D7 = 1852 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D8 = 1853 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D9 = 1854 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D1 = 1855 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D2 = 1856 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D3 = 1857 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D4 = 1858 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D5 = 1859 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D6 = 1860 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D7 = 1861 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D8 = 1862 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D9 = 1863 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D1 = 1864 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D2 = 1865 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D3 = 1866 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D4 = 1867 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D5 = 1868 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D6 = 1869 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D7 = 1870 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D8 = 1871 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D9 = 1872 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D1 = 1873 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D2 = 1874 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D3 = 1875 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D4 = 1876 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D5 = 1877 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D6 = 1878 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D7 = 1879 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D8 = 1880 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D9 = 1881 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D1 = 1882 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D2 = 1883 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D3 = 1884 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D4 = 1885 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D5 = 1886 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D6 = 1887 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D7 = 1888 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D8 = 1889 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D9 = 1890 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D1 = 1891 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D2 = 1892 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D3 = 1893 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D4 = 1894 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D5 = 1895 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D6 = 1896 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D7 = 1897 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D8 = 1898 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D9 = 1899 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D1 = 1900 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D2 = 1901 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D3 = 1902 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D4 = 1903 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D5 = 1904 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D6 = 1905 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D7 = 1906 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D8 = 1907 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D9 = 1908 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D1 = 1909 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D2 = 1910 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D3 = 1911 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D4 = 1912 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D5 = 1913 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D6 = 1914 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D7 = 1915 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D8 = 1916 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D9 = 1917 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D1 = 1918 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D2 = 1919 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D3 = 1920 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D4 = 1921 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D5 = 1922 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D6 = 1923 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D7 = 1924 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D8 = 1925 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D9 = 1926 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D1 = 1927 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D2 = 1928 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D3 = 1929 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D4 = 1930 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D5 = 1931 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D6 = 1932 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D7 = 1933 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D8 = 1934 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D9 = 1935 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D1 = 1936 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D2 = 1937 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D3 = 1938 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D4 = 1939 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D5 = 1940 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D6 = 1941 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D7 = 1942 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D8 = 1943 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D9 = 1944 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D1 = 1945 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D2 = 1946 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D3 = 1947 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D4 = 1948 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D5 = 1949 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D6 = 1950 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D7 = 1951 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D8 = 1952 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D9 = 1953 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D1 = 1954 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D2 = 1955 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D3 = 1956 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D4 = 1957 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D5 = 1958 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D6 = 1959 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D7 = 1960 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D8 = 1961 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D9 = 1962 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D1 = 1963 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D2 = 1964 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D3 = 1965 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D4 = 1966 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D5 = 1967 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D6 = 1968 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D7 = 1969 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D8 = 1970 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D9 = 1971 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D1 = 1972 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D2 = 1973 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D3 = 1974 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D4 = 1975 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D5 = 1976 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D6 = 1977 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D7 = 1978 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D8 = 1979 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D9 = 1980 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D1 = 1981 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D2 = 1982 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D3 = 1983 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D4 = 1984 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D5 = 1985 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D6 = 1986 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D7 = 1987 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D8 = 1988 - INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D9 = 1989 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D1 = 1990 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D2 = 1991 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D3 = 1992 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D4 = 1993 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D5 = 1994 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D6 = 1995 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D7 = 1996 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D8 = 1997 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D9 = 1998 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D1 = 1999 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D2 = 2000 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D3 = 2001 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D4 = 2002 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D5 = 2003 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D6 = 2004 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D7 = 2005 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D8 = 2006 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D9 = 2007 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D1 = 2008 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D2 = 2009 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D3 = 2010 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D4 = 2011 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D5 = 2012 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D6 = 2013 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D7 = 2014 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D8 = 2015 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D9 = 2016 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D1 = 2017 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D2 = 2018 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D3 = 2019 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D4 = 2020 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D5 = 2021 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D6 = 2022 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D7 = 2023 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D8 = 2024 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D9 = 2025 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D1 = 2026 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D2 = 2027 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D3 = 2028 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D4 = 2029 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D5 = 2030 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D6 = 2031 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D7 = 2032 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D8 = 2033 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D9 = 2034 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D1 = 2035 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D2 = 2036 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D3 = 2037 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D4 = 2038 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D5 = 2039 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D6 = 2040 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D7 = 2041 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D8 = 2042 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D9 = 2043 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D1 = 2044 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D2 = 2045 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D3 = 2046 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D4 = 2047 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D5 = 2048 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D6 = 2049 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D7 = 2050 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D8 = 2051 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D9 = 2052 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D1 = 2053 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D2 = 2054 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D3 = 2055 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D4 = 2056 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D5 = 2057 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D6 = 2058 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D7 = 2059 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D8 = 2060 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D9 = 2061 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D1 = 2062 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D2 = 2063 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D3 = 2064 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D4 = 2065 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D5 = 2066 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D6 = 2067 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D7 = 2068 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D8 = 2069 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D9 = 2070 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D1 = 2071 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D2 = 2072 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D3 = 2073 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D4 = 2074 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D5 = 2075 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D6 = 2076 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D7 = 2077 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D8 = 2078 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D9 = 2079 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D1 = 2080 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D2 = 2081 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D3 = 2082 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D4 = 2083 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D5 = 2084 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D6 = 2085 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D7 = 2086 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D8 = 2087 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D9 = 2088 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D1 = 2089 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D2 = 2090 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D3 = 2091 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D4 = 2092 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D5 = 2093 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D6 = 2094 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D7 = 2095 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D8 = 2096 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D9 = 2097 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D1 = 2098 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D2 = 2099 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D3 = 2100 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D4 = 2101 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D5 = 2102 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D6 = 2103 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D7 = 2104 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D8 = 2105 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D9 = 2106 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D1 = 2107 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D2 = 2108 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D3 = 2109 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D4 = 2110 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D5 = 2111 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D6 = 2112 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D7 = 2113 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D8 = 2114 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D9 = 2115 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D1 = 2116 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D2 = 2117 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D3 = 2118 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D4 = 2119 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D5 = 2120 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D6 = 2121 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D7 = 2122 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D8 = 2123 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D9 = 2124 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D1 = 2125 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D2 = 2126 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D3 = 2127 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D4 = 2128 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D5 = 2129 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D6 = 2130 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D7 = 2131 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D8 = 2132 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D9 = 2133 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D1 = 2134 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D2 = 2135 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D3 = 2136 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D4 = 2137 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D5 = 2138 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D6 = 2139 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D7 = 2140 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D8 = 2141 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D9 = 2142 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D1 = 2143 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D2 = 2144 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D3 = 2145 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D4 = 2146 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D5 = 2147 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D6 = 2148 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D7 = 2149 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D8 = 2150 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D9 = 2151 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D1 = 2152 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D2 = 2153 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D3 = 2154 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D4 = 2155 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D5 = 2156 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D6 = 2157 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D7 = 2158 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D8 = 2159 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D9 = 2160 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D1 = 2161 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D2 = 2162 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D3 = 2163 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D4 = 2164 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D5 = 2165 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D6 = 2166 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D7 = 2167 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D8 = 2168 - INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D9 = 2169 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D1 = 2170 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D2 = 2171 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D3 = 2172 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D4 = 2173 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D5 = 2174 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D6 = 2175 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D7 = 2176 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D8 = 2177 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D9 = 2178 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D1 = 2179 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D2 = 2180 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D3 = 2181 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D4 = 2182 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D5 = 2183 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D6 = 2184 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D7 = 2185 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D8 = 2186 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D9 = 2187 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D1 = 2188 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D2 = 2189 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D3 = 2190 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D4 = 2191 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D5 = 2192 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D6 = 2193 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D7 = 2194 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D8 = 2195 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D9 = 2196 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D1 = 2197 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D2 = 2198 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D3 = 2199 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D4 = 2200 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D5 = 2201 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D6 = 2202 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D7 = 2203 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D8 = 2204 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D9 = 2205 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D1 = 2206 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D2 = 2207 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D3 = 2208 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D4 = 2209 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D5 = 2210 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D6 = 2211 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D7 = 2212 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D8 = 2213 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D9 = 2214 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D1 = 2215 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D2 = 2216 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D3 = 2217 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D4 = 2218 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D5 = 2219 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D6 = 2220 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D7 = 2221 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D8 = 2222 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D9 = 2223 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D1 = 2224 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D2 = 2225 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D3 = 2226 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D4 = 2227 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D5 = 2228 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D6 = 2229 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D7 = 2230 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D8 = 2231 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D9 = 2232 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D1 = 2233 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D2 = 2234 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D3 = 2235 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D4 = 2236 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D5 = 2237 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D6 = 2238 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D7 = 2239 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D8 = 2240 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D9 = 2241 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D1 = 2242 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D2 = 2243 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D3 = 2244 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D4 = 2245 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D5 = 2246 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D6 = 2247 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D7 = 2248 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D8 = 2249 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D9 = 2250 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D1 = 2251 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D2 = 2252 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D3 = 2253 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D4 = 2254 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D5 = 2255 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D6 = 2256 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D7 = 2257 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D8 = 2258 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D9 = 2259 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D1 = 2260 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D2 = 2261 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D3 = 2262 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D4 = 2263 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D5 = 2264 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D6 = 2265 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D7 = 2266 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D8 = 2267 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D9 = 2268 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D1 = 2269 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D2 = 2270 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D3 = 2271 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D4 = 2272 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D5 = 2273 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D6 = 2274 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D7 = 2275 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D8 = 2276 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D9 = 2277 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D1 = 2278 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D2 = 2279 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D3 = 2280 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D4 = 2281 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D5 = 2282 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D6 = 2283 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D7 = 2284 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D8 = 2285 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D9 = 2286 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D1 = 2287 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D2 = 2288 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D3 = 2289 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D4 = 2290 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D5 = 2291 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D6 = 2292 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D7 = 2293 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D8 = 2294 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D9 = 2295 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D1 = 2296 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D2 = 2297 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D3 = 2298 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D4 = 2299 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D5 = 2300 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D6 = 2301 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D7 = 2302 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D8 = 2303 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D9 = 2304 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D1 = 2305 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D2 = 2306 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D3 = 2307 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D4 = 2308 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D5 = 2309 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D6 = 2310 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D7 = 2311 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D8 = 2312 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D9 = 2313 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D1 = 2314 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D2 = 2315 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D3 = 2316 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D4 = 2317 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D5 = 2318 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D6 = 2319 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D7 = 2320 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D8 = 2321 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D9 = 2322 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D1 = 2323 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D2 = 2324 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D3 = 2325 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D4 = 2326 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D5 = 2327 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D6 = 2328 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D7 = 2329 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D8 = 2330 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D9 = 2331 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D1 = 2332 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D2 = 2333 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D3 = 2334 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D4 = 2335 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D5 = 2336 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D6 = 2337 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D7 = 2338 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D8 = 2339 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D9 = 2340 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D1 = 2341 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D2 = 2342 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D3 = 2343 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D4 = 2344 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D5 = 2345 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D6 = 2346 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D7 = 2347 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D8 = 2348 - INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D9 = 2349 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D1 = 2350 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D2 = 2351 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D3 = 2352 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D4 = 2353 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D5 = 2354 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D6 = 2355 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D7 = 2356 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D8 = 2357 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D9 = 2358 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D1 = 2359 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D2 = 2360 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D3 = 2361 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D4 = 2362 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D5 = 2363 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D6 = 2364 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D7 = 2365 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D8 = 2366 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D9 = 2367 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D1 = 2368 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D2 = 2369 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D3 = 2370 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D4 = 2371 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D5 = 2372 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D6 = 2373 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D7 = 2374 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D8 = 2375 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D9 = 2376 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D1 = 2377 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D2 = 2378 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D3 = 2379 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D4 = 2380 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D5 = 2381 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D6 = 2382 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D7 = 2383 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D8 = 2384 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D9 = 2385 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D1 = 2386 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D2 = 2387 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D3 = 2388 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D4 = 2389 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D5 = 2390 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D6 = 2391 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D7 = 2392 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D8 = 2393 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D9 = 2394 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D1 = 2395 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D2 = 2396 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D3 = 2397 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D4 = 2398 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D5 = 2399 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D6 = 2400 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D7 = 2401 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D8 = 2402 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D9 = 2403 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D1 = 2404 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D2 = 2405 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D3 = 2406 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D4 = 2407 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D5 = 2408 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D6 = 2409 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D7 = 2410 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D8 = 2411 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D9 = 2412 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D1 = 2413 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D2 = 2414 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D3 = 2415 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D4 = 2416 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D5 = 2417 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D6 = 2418 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D7 = 2419 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D8 = 2420 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D9 = 2421 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D1 = 2422 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D2 = 2423 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D3 = 2424 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D4 = 2425 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D5 = 2426 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D6 = 2427 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D7 = 2428 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D8 = 2429 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D9 = 2430 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D1 = 2431 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D2 = 2432 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D3 = 2433 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D4 = 2434 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D5 = 2435 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D6 = 2436 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D7 = 2437 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D8 = 2438 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D9 = 2439 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D1 = 2440 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D2 = 2441 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D3 = 2442 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D4 = 2443 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D5 = 2444 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D6 = 2445 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D7 = 2446 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D8 = 2447 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D9 = 2448 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D1 = 2449 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D2 = 2450 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D3 = 2451 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D4 = 2452 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D5 = 2453 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D6 = 2454 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D7 = 2455 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D8 = 2456 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D9 = 2457 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D1 = 2458 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D2 = 2459 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D3 = 2460 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D4 = 2461 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D5 = 2462 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D6 = 2463 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D7 = 2464 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D8 = 2465 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D9 = 2466 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D1 = 2467 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D2 = 2468 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D3 = 2469 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D4 = 2470 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D5 = 2471 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D6 = 2472 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D7 = 2473 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D8 = 2474 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D9 = 2475 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D1 = 2476 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D2 = 2477 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D3 = 2478 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D4 = 2479 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D5 = 2480 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D6 = 2481 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D7 = 2482 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D8 = 2483 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D9 = 2484 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D1 = 2485 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D2 = 2486 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D3 = 2487 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D4 = 2488 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D5 = 2489 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D6 = 2490 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D7 = 2491 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D8 = 2492 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D9 = 2493 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D1 = 2494 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D2 = 2495 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D3 = 2496 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D4 = 2497 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D5 = 2498 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D6 = 2499 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D7 = 2500 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D8 = 2501 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D9 = 2502 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D1 = 2503 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D2 = 2504 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D3 = 2505 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D4 = 2506 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D5 = 2507 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D6 = 2508 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D7 = 2509 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D8 = 2510 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D9 = 2511 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D1 = 2512 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D2 = 2513 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D3 = 2514 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D4 = 2515 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D5 = 2516 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D6 = 2517 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D7 = 2518 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D8 = 2519 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D9 = 2520 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D1 = 2521 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D2 = 2522 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D3 = 2523 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D4 = 2524 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D5 = 2525 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D6 = 2526 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D7 = 2527 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D8 = 2528 - INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D9 = 2529 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D1 = 2530 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D2 = 2531 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D3 = 2532 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D4 = 2533 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D5 = 2534 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D6 = 2535 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D7 = 2536 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D8 = 2537 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D9 = 2538 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D1 = 2539 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D2 = 2540 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D3 = 2541 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D4 = 2542 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D5 = 2543 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D6 = 2544 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D7 = 2545 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D8 = 2546 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D9 = 2547 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D1 = 2548 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D2 = 2549 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D3 = 2550 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D4 = 2551 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D5 = 2552 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D6 = 2553 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D7 = 2554 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D8 = 2555 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D9 = 2556 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D1 = 2557 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D2 = 2558 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D3 = 2559 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D4 = 2560 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D5 = 2561 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D6 = 2562 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D7 = 2563 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D8 = 2564 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D9 = 2565 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D1 = 2566 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D2 = 2567 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D3 = 2568 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D4 = 2569 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D5 = 2570 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D6 = 2571 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D7 = 2572 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D8 = 2573 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D9 = 2574 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D1 = 2575 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D2 = 2576 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D3 = 2577 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D4 = 2578 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D5 = 2579 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D6 = 2580 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D7 = 2581 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D8 = 2582 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D9 = 2583 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D1 = 2584 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D2 = 2585 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D3 = 2586 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D4 = 2587 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D5 = 2588 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D6 = 2589 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D7 = 2590 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D8 = 2591 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D9 = 2592 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D1 = 2593 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D2 = 2594 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D3 = 2595 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D4 = 2596 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D5 = 2597 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D6 = 2598 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D7 = 2599 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D8 = 2600 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D9 = 2601 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D1 = 2602 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D2 = 2603 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D3 = 2604 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D4 = 2605 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D5 = 2606 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D6 = 2607 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D7 = 2608 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D8 = 2609 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D9 = 2610 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D1 = 2611 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D2 = 2612 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D3 = 2613 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D4 = 2614 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D5 = 2615 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D6 = 2616 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D7 = 2617 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D8 = 2618 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D9 = 2619 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D1 = 2620 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D2 = 2621 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D3 = 2622 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D4 = 2623 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D5 = 2624 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D6 = 2625 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D7 = 2626 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D8 = 2627 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D9 = 2628 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D1 = 2629 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D2 = 2630 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D3 = 2631 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D4 = 2632 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D5 = 2633 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D6 = 2634 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D7 = 2635 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D8 = 2636 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D9 = 2637 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D1 = 2638 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D2 = 2639 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D3 = 2640 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D4 = 2641 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D5 = 2642 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D6 = 2643 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D7 = 2644 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D8 = 2645 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D9 = 2646 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D1 = 2647 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D2 = 2648 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D3 = 2649 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D4 = 2650 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D5 = 2651 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D6 = 2652 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D7 = 2653 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D8 = 2654 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D9 = 2655 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D1 = 2656 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D2 = 2657 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D3 = 2658 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D4 = 2659 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D5 = 2660 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D6 = 2661 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D7 = 2662 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D8 = 2663 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D9 = 2664 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D1 = 2665 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D2 = 2666 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D3 = 2667 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D4 = 2668 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D5 = 2669 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D6 = 2670 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D7 = 2671 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D8 = 2672 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D9 = 2673 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D1 = 2674 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D2 = 2675 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D3 = 2676 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D4 = 2677 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D5 = 2678 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D6 = 2679 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D7 = 2680 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D8 = 2681 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D9 = 2682 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D1 = 2683 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D2 = 2684 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D3 = 2685 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D4 = 2686 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D5 = 2687 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D6 = 2688 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D7 = 2689 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D8 = 2690 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D9 = 2691 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D1 = 2692 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D2 = 2693 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D3 = 2694 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D4 = 2695 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D5 = 2696 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D6 = 2697 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D7 = 2698 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D8 = 2699 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D9 = 2700 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D1 = 2701 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D2 = 2702 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D3 = 2703 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D4 = 2704 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D5 = 2705 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D6 = 2706 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D7 = 2707 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D8 = 2708 - INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D9 = 2709 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D1 = 2710 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D2 = 2711 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D3 = 2712 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D4 = 2713 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D5 = 2714 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D6 = 2715 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D7 = 2716 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D8 = 2717 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D9 = 2718 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D1 = 2719 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D2 = 2720 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D3 = 2721 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D4 = 2722 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D5 = 2723 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D6 = 2724 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D7 = 2725 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D8 = 2726 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D9 = 2727 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D1 = 2728 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D2 = 2729 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D3 = 2730 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D4 = 2731 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D5 = 2732 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D6 = 2733 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D7 = 2734 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D8 = 2735 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D9 = 2736 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D1 = 2737 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D2 = 2738 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D3 = 2739 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D4 = 2740 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D5 = 2741 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D6 = 2742 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D7 = 2743 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D8 = 2744 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D9 = 2745 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D1 = 2746 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D2 = 2747 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D3 = 2748 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D4 = 2749 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D5 = 2750 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D6 = 2751 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D7 = 2752 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D8 = 2753 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D9 = 2754 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D1 = 2755 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D2 = 2756 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D3 = 2757 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D4 = 2758 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D5 = 2759 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D6 = 2760 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D7 = 2761 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D8 = 2762 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D9 = 2763 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D1 = 2764 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D2 = 2765 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D3 = 2766 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D4 = 2767 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D5 = 2768 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D6 = 2769 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D7 = 2770 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D8 = 2771 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D9 = 2772 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D1 = 2773 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D2 = 2774 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D3 = 2775 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D4 = 2776 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D5 = 2777 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D6 = 2778 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D7 = 2779 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D8 = 2780 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D9 = 2781 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D1 = 2782 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D2 = 2783 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D3 = 2784 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D4 = 2785 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D5 = 2786 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D6 = 2787 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D7 = 2788 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D8 = 2789 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D9 = 2790 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D1 = 2791 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D2 = 2792 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D3 = 2793 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D4 = 2794 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D5 = 2795 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D6 = 2796 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D7 = 2797 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D8 = 2798 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D9 = 2799 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D1 = 2800 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D2 = 2801 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D3 = 2802 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D4 = 2803 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D5 = 2804 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D6 = 2805 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D7 = 2806 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D8 = 2807 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D9 = 2808 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D1 = 2809 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D2 = 2810 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D3 = 2811 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D4 = 2812 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D5 = 2813 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D6 = 2814 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D7 = 2815 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D8 = 2816 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D9 = 2817 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D1 = 2818 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D2 = 2819 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D3 = 2820 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D4 = 2821 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D5 = 2822 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D6 = 2823 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D7 = 2824 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D8 = 2825 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D9 = 2826 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D1 = 2827 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D2 = 2828 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D3 = 2829 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D4 = 2830 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D5 = 2831 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D6 = 2832 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D7 = 2833 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D8 = 2834 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D9 = 2835 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D1 = 2836 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D2 = 2837 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D3 = 2838 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D4 = 2839 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D5 = 2840 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D6 = 2841 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D7 = 2842 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D8 = 2843 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D9 = 2844 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D1 = 2845 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D2 = 2846 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D3 = 2847 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D4 = 2848 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D5 = 2849 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D6 = 2850 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D7 = 2851 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D8 = 2852 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D9 = 2853 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D1 = 2854 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D2 = 2855 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D3 = 2856 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D4 = 2857 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D5 = 2858 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D6 = 2859 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D7 = 2860 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D8 = 2861 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D9 = 2862 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D1 = 2863 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D2 = 2864 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D3 = 2865 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D4 = 2866 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D5 = 2867 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D6 = 2868 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D7 = 2869 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D8 = 2870 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D9 = 2871 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D1 = 2872 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D2 = 2873 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D3 = 2874 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D4 = 2875 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D5 = 2876 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D6 = 2877 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D7 = 2878 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D8 = 2879 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D9 = 2880 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D1 = 2881 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D2 = 2882 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D3 = 2883 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D4 = 2884 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D5 = 2885 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D6 = 2886 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D7 = 2887 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D8 = 2888 - INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D9 = 2889 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D1 = 2890 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D2 = 2891 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D3 = 2892 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D4 = 2893 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D5 = 2894 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D6 = 2895 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D7 = 2896 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D8 = 2897 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D9 = 2898 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D1 = 2899 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D2 = 2900 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D3 = 2901 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D4 = 2902 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D5 = 2903 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D6 = 2904 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D7 = 2905 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D8 = 2906 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D9 = 2907 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D1 = 2908 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D2 = 2909 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D3 = 2910 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D4 = 2911 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D5 = 2912 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D6 = 2913 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D7 = 2914 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D8 = 2915 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D9 = 2916 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D1 = 2917 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D2 = 2918 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D3 = 2919 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D4 = 2920 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D5 = 2921 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D6 = 2922 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D7 = 2923 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D8 = 2924 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D9 = 2925 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D1 = 2926 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D2 = 2927 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D3 = 2928 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D4 = 2929 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D5 = 2930 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D6 = 2931 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D7 = 2932 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D8 = 2933 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D9 = 2934 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D1 = 2935 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D2 = 2936 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D3 = 2937 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D4 = 2938 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D5 = 2939 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D6 = 2940 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D7 = 2941 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D8 = 2942 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D9 = 2943 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D1 = 2944 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D2 = 2945 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D3 = 2946 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D4 = 2947 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D5 = 2948 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D6 = 2949 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D7 = 2950 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D8 = 2951 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D9 = 2952 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D1 = 2953 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D2 = 2954 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D3 = 2955 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D4 = 2956 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D5 = 2957 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D6 = 2958 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D7 = 2959 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D8 = 2960 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D9 = 2961 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D1 = 2962 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D2 = 2963 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D3 = 2964 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D4 = 2965 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D5 = 2966 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D6 = 2967 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D7 = 2968 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D8 = 2969 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D9 = 2970 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D1 = 2971 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D2 = 2972 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D3 = 2973 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D4 = 2974 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D5 = 2975 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D6 = 2976 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D7 = 2977 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D8 = 2978 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D9 = 2979 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D1 = 2980 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D2 = 2981 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D3 = 2982 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D4 = 2983 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D5 = 2984 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D6 = 2985 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D7 = 2986 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D8 = 2987 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D9 = 2988 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D1 = 2989 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D2 = 2990 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D3 = 2991 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D4 = 2992 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D5 = 2993 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D6 = 2994 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D7 = 2995 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D8 = 2996 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D9 = 2997 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D1 = 2998 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D2 = 2999 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D3 = 3000 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D4 = 3001 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D5 = 3002 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D6 = 3003 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D7 = 3004 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D8 = 3005 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D9 = 3006 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D1 = 3007 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D2 = 3008 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D3 = 3009 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D4 = 3010 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D5 = 3011 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D6 = 3012 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D7 = 3013 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D8 = 3014 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D9 = 3015 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D1 = 3016 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D2 = 3017 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D3 = 3018 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D4 = 3019 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D5 = 3020 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D6 = 3021 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D7 = 3022 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D8 = 3023 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D9 = 3024 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D1 = 3025 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D2 = 3026 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D3 = 3027 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D4 = 3028 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D5 = 3029 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D6 = 3030 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D7 = 3031 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D8 = 3032 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D9 = 3033 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D1 = 3034 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D2 = 3035 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D3 = 3036 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D4 = 3037 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D5 = 3038 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D6 = 3039 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D7 = 3040 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D8 = 3041 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D9 = 3042 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D1 = 3043 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D2 = 3044 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D3 = 3045 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D4 = 3046 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D5 = 3047 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D6 = 3048 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D7 = 3049 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D8 = 3050 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D9 = 3051 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D1 = 3052 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D2 = 3053 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D3 = 3054 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D4 = 3055 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D5 = 3056 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D6 = 3057 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D7 = 3058 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D8 = 3059 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D9 = 3060 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D1 = 3061 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D2 = 3062 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D3 = 3063 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D4 = 3064 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D5 = 3065 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D6 = 3066 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D7 = 3067 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D8 = 3068 - INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D9 = 3069 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D1 = 3070 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D2 = 3071 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D3 = 3072 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D4 = 3073 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D5 = 3074 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D6 = 3075 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D7 = 3076 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D8 = 3077 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D9 = 3078 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D1 = 3079 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D2 = 3080 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D3 = 3081 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D4 = 3082 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D5 = 3083 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D6 = 3084 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D7 = 3085 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D8 = 3086 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D9 = 3087 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D1 = 3088 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D2 = 3089 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D3 = 3090 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D4 = 3091 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D5 = 3092 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D6 = 3093 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D7 = 3094 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D8 = 3095 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D9 = 3096 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D1 = 3097 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D2 = 3098 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D3 = 3099 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D4 = 3100 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D5 = 3101 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D6 = 3102 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D7 = 3103 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D8 = 3104 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D9 = 3105 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D1 = 3106 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D2 = 3107 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D3 = 3108 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D4 = 3109 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D5 = 3110 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D6 = 3111 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D7 = 3112 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D8 = 3113 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D9 = 3114 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D1 = 3115 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D2 = 3116 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D3 = 3117 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D4 = 3118 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D5 = 3119 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D6 = 3120 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D7 = 3121 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D8 = 3122 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D9 = 3123 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D1 = 3124 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D2 = 3125 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D3 = 3126 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D4 = 3127 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D5 = 3128 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D6 = 3129 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D7 = 3130 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D8 = 3131 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D9 = 3132 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D1 = 3133 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D2 = 3134 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D3 = 3135 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D4 = 3136 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D5 = 3137 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D6 = 3138 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D7 = 3139 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D8 = 3140 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D9 = 3141 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D1 = 3142 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D2 = 3143 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D3 = 3144 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D4 = 3145 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D5 = 3146 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D6 = 3147 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D7 = 3148 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D8 = 3149 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D9 = 3150 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D1 = 3151 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D2 = 3152 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D3 = 3153 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D4 = 3154 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D5 = 3155 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D6 = 3156 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D7 = 3157 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D8 = 3158 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D9 = 3159 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D1 = 3160 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D2 = 3161 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D3 = 3162 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D4 = 3163 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D5 = 3164 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D6 = 3165 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D7 = 3166 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D8 = 3167 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D9 = 3168 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D1 = 3169 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D2 = 3170 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D3 = 3171 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D4 = 3172 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D5 = 3173 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D6 = 3174 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D7 = 3175 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D8 = 3176 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D9 = 3177 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D1 = 3178 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D2 = 3179 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D3 = 3180 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D4 = 3181 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D5 = 3182 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D6 = 3183 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D7 = 3184 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D8 = 3185 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D9 = 3186 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D1 = 3187 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D2 = 3188 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D3 = 3189 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D4 = 3190 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D5 = 3191 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D6 = 3192 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D7 = 3193 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D8 = 3194 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D9 = 3195 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D1 = 3196 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D2 = 3197 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D3 = 3198 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D4 = 3199 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D5 = 3200 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D6 = 3201 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D7 = 3202 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D8 = 3203 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D9 = 3204 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D1 = 3205 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D2 = 3206 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D3 = 3207 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D4 = 3208 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D5 = 3209 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D6 = 3210 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D7 = 3211 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D8 = 3212 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D9 = 3213 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D1 = 3214 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D2 = 3215 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D3 = 3216 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D4 = 3217 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D5 = 3218 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D6 = 3219 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D7 = 3220 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D8 = 3221 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D9 = 3222 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D1 = 3223 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D2 = 3224 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D3 = 3225 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D4 = 3226 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D5 = 3227 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D6 = 3228 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D7 = 3229 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D8 = 3230 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D9 = 3231 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D1 = 3232 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D2 = 3233 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D3 = 3234 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D4 = 3235 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D5 = 3236 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D6 = 3237 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D7 = 3238 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D8 = 3239 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D9 = 3240 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D1 = 3241 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D2 = 3242 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D3 = 3243 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D4 = 3244 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D5 = 3245 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D6 = 3246 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D7 = 3247 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D8 = 3248 - INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D9 = 3249 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D1 = 3250 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D2 = 3251 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D3 = 3252 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D4 = 3253 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D5 = 3254 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D6 = 3255 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D7 = 3256 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D8 = 3257 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D9 = 3258 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D1 = 3259 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D2 = 3260 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D3 = 3261 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D4 = 3262 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D5 = 3263 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D6 = 3264 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D7 = 3265 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D8 = 3266 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D9 = 3267 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D1 = 3268 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D2 = 3269 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D3 = 3270 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D4 = 3271 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D5 = 3272 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D6 = 3273 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D7 = 3274 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D8 = 3275 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D9 = 3276 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D1 = 3277 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D2 = 3278 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D3 = 3279 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D4 = 3280 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D5 = 3281 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D6 = 3282 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D7 = 3283 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D8 = 3284 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D9 = 3285 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D1 = 3286 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D2 = 3287 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D3 = 3288 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D4 = 3289 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D5 = 3290 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D6 = 3291 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D7 = 3292 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D8 = 3293 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D9 = 3294 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D1 = 3295 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D2 = 3296 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D3 = 3297 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D4 = 3298 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D5 = 3299 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D6 = 3300 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D7 = 3301 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D8 = 3302 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D9 = 3303 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D1 = 3304 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D2 = 3305 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D3 = 3306 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D4 = 3307 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D5 = 3308 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D6 = 3309 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D7 = 3310 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D8 = 3311 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D9 = 3312 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D1 = 3313 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D2 = 3314 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D3 = 3315 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D4 = 3316 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D5 = 3317 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D6 = 3318 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D7 = 3319 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D8 = 3320 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D9 = 3321 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D1 = 3322 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D2 = 3323 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D3 = 3324 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D4 = 3325 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D5 = 3326 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D6 = 3327 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D7 = 3328 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D8 = 3329 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D9 = 3330 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D1 = 3331 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D2 = 3332 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D3 = 3333 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D4 = 3334 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D5 = 3335 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D6 = 3336 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D7 = 3337 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D8 = 3338 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D9 = 3339 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D1 = 3340 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D2 = 3341 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D3 = 3342 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D4 = 3343 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D5 = 3344 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D6 = 3345 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D7 = 3346 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D8 = 3347 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D9 = 3348 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D1 = 3349 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D2 = 3350 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D3 = 3351 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D4 = 3352 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D5 = 3353 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D6 = 3354 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D7 = 3355 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D8 = 3356 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D9 = 3357 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D1 = 3358 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D2 = 3359 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D3 = 3360 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D4 = 3361 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D5 = 3362 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D6 = 3363 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D7 = 3364 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D8 = 3365 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D9 = 3366 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D1 = 3367 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D2 = 3368 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D3 = 3369 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D4 = 3370 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D5 = 3371 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D6 = 3372 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D7 = 3373 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D8 = 3374 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D9 = 3375 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D1 = 3376 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D2 = 3377 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D3 = 3378 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D4 = 3379 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D5 = 3380 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D6 = 3381 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D7 = 3382 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D8 = 3383 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D9 = 3384 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D1 = 3385 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D2 = 3386 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D3 = 3387 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D4 = 3388 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D5 = 3389 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D6 = 3390 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D7 = 3391 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D8 = 3392 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D9 = 3393 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D1 = 3394 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D2 = 3395 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D3 = 3396 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D4 = 3397 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D5 = 3398 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D6 = 3399 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D7 = 3400 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D8 = 3401 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D9 = 3402 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D1 = 3403 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D2 = 3404 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D3 = 3405 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D4 = 3406 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D5 = 3407 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D6 = 3408 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D7 = 3409 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D8 = 3410 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D9 = 3411 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D1 = 3412 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D2 = 3413 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D3 = 3414 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D4 = 3415 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D5 = 3416 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D6 = 3417 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D7 = 3418 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D8 = 3419 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D9 = 3420 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D1 = 3421 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D2 = 3422 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D3 = 3423 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D4 = 3424 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D5 = 3425 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D6 = 3426 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D7 = 3427 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D8 = 3428 - INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D9 = 3429 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D1 = 3430 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D2 = 3431 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D3 = 3432 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D4 = 3433 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D5 = 3434 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D6 = 3435 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D7 = 3436 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D8 = 3437 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D9 = 3438 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D1 = 3439 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D2 = 3440 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D3 = 3441 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D4 = 3442 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D5 = 3443 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D6 = 3444 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D7 = 3445 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D8 = 3446 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D9 = 3447 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D1 = 3448 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D2 = 3449 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D3 = 3450 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D4 = 3451 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D5 = 3452 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D6 = 3453 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D7 = 3454 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D8 = 3455 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D9 = 3456 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D1 = 3457 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D2 = 3458 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D3 = 3459 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D4 = 3460 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D5 = 3461 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D6 = 3462 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D7 = 3463 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D8 = 3464 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D9 = 3465 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D1 = 3466 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D2 = 3467 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D3 = 3468 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D4 = 3469 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D5 = 3470 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D6 = 3471 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D7 = 3472 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D8 = 3473 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D9 = 3474 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D1 = 3475 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D2 = 3476 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D3 = 3477 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D4 = 3478 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D5 = 3479 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D6 = 3480 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D7 = 3481 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D8 = 3482 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D9 = 3483 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D1 = 3484 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D2 = 3485 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D3 = 3486 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D4 = 3487 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D5 = 3488 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D6 = 3489 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D7 = 3490 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D8 = 3491 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D9 = 3492 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D1 = 3493 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D2 = 3494 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D3 = 3495 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D4 = 3496 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D5 = 3497 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D6 = 3498 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D7 = 3499 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D8 = 3500 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D9 = 3501 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D1 = 3502 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D2 = 3503 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D3 = 3504 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D4 = 3505 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D5 = 3506 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D6 = 3507 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D7 = 3508 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D8 = 3509 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D9 = 3510 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D1 = 3511 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D2 = 3512 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D3 = 3513 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D4 = 3514 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D5 = 3515 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D6 = 3516 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D7 = 3517 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D8 = 3518 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D9 = 3519 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D1 = 3520 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D2 = 3521 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D3 = 3522 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D4 = 3523 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D5 = 3524 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D6 = 3525 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D7 = 3526 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D8 = 3527 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D9 = 3528 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D1 = 3529 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D2 = 3530 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D3 = 3531 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D4 = 3532 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D5 = 3533 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D6 = 3534 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D7 = 3535 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D8 = 3536 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D9 = 3537 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D1 = 3538 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D2 = 3539 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D3 = 3540 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D4 = 3541 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D5 = 3542 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D6 = 3543 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D7 = 3544 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D8 = 3545 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D9 = 3546 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D1 = 3547 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D2 = 3548 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D3 = 3549 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D4 = 3550 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D5 = 3551 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D6 = 3552 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D7 = 3553 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D8 = 3554 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D9 = 3555 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D1 = 3556 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D2 = 3557 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D3 = 3558 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D4 = 3559 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D5 = 3560 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D6 = 3561 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D7 = 3562 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D8 = 3563 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D9 = 3564 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D1 = 3565 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D2 = 3566 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D3 = 3567 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D4 = 3568 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D5 = 3569 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D6 = 3570 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D7 = 3571 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D8 = 3572 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D9 = 3573 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D1 = 3574 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D2 = 3575 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D3 = 3576 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D4 = 3577 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D5 = 3578 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D6 = 3579 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D7 = 3580 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D8 = 3581 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D9 = 3582 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D1 = 3583 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D2 = 3584 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D3 = 3585 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D4 = 3586 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D5 = 3587 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D6 = 3588 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D7 = 3589 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D8 = 3590 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D9 = 3591 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D1 = 3592 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D2 = 3593 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D3 = 3594 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D4 = 3595 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D5 = 3596 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D6 = 3597 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D7 = 3598 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D8 = 3599 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D9 = 3600 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D1 = 3601 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D2 = 3602 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D3 = 3603 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D4 = 3604 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D5 = 3605 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D6 = 3606 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D7 = 3607 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D8 = 3608 - INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D9 = 3609 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D1 = 3610 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D2 = 3611 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D3 = 3612 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D4 = 3613 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D5 = 3614 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D6 = 3615 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D7 = 3616 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D8 = 3617 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D9 = 3618 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D1 = 3619 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D2 = 3620 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D3 = 3621 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D4 = 3622 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D5 = 3623 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D6 = 3624 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D7 = 3625 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D8 = 3626 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D9 = 3627 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D1 = 3628 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D2 = 3629 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D3 = 3630 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D4 = 3631 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D5 = 3632 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D6 = 3633 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D7 = 3634 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D8 = 3635 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D9 = 3636 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D1 = 3637 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D2 = 3638 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D3 = 3639 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D4 = 3640 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D5 = 3641 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D6 = 3642 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D7 = 3643 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D8 = 3644 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D9 = 3645 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D1 = 3646 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D2 = 3647 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D3 = 3648 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D4 = 3649 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D5 = 3650 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D6 = 3651 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D7 = 3652 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D8 = 3653 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D9 = 3654 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D1 = 3655 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D2 = 3656 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D3 = 3657 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D4 = 3658 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D5 = 3659 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D6 = 3660 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D7 = 3661 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D8 = 3662 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D9 = 3663 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D1 = 3664 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D2 = 3665 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D3 = 3666 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D4 = 3667 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D5 = 3668 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D6 = 3669 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D7 = 3670 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D8 = 3671 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D9 = 3672 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D1 = 3673 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D2 = 3674 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D3 = 3675 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D4 = 3676 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D5 = 3677 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D6 = 3678 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D7 = 3679 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D8 = 3680 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D9 = 3681 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D1 = 3682 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D2 = 3683 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D3 = 3684 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D4 = 3685 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D5 = 3686 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D6 = 3687 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D7 = 3688 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D8 = 3689 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D9 = 3690 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D1 = 3691 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D2 = 3692 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D3 = 3693 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D4 = 3694 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D5 = 3695 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D6 = 3696 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D7 = 3697 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D8 = 3698 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D9 = 3699 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D1 = 3700 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D2 = 3701 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D3 = 3702 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D4 = 3703 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D5 = 3704 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D6 = 3705 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D7 = 3706 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D8 = 3707 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D9 = 3708 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D1 = 3709 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D2 = 3710 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D3 = 3711 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D4 = 3712 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D5 = 3713 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D6 = 3714 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D7 = 3715 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D8 = 3716 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D9 = 3717 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D1 = 3718 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D2 = 3719 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D3 = 3720 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D4 = 3721 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D5 = 3722 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D6 = 3723 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D7 = 3724 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D8 = 3725 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D9 = 3726 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D1 = 3727 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D2 = 3728 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D3 = 3729 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D4 = 3730 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D5 = 3731 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D6 = 3732 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D7 = 3733 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D8 = 3734 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D9 = 3735 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D1 = 3736 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D2 = 3737 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D3 = 3738 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D4 = 3739 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D5 = 3740 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D6 = 3741 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D7 = 3742 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D8 = 3743 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D9 = 3744 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D1 = 3745 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D2 = 3746 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D3 = 3747 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D4 = 3748 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D5 = 3749 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D6 = 3750 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D7 = 3751 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D8 = 3752 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D9 = 3753 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D1 = 3754 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D2 = 3755 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D3 = 3756 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D4 = 3757 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D5 = 3758 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D6 = 3759 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D7 = 3760 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D8 = 3761 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D9 = 3762 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D1 = 3763 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D2 = 3764 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D3 = 3765 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D4 = 3766 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D5 = 3767 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D6 = 3768 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D7 = 3769 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D8 = 3770 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D9 = 3771 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D1 = 3772 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D2 = 3773 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D3 = 3774 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D4 = 3775 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D5 = 3776 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D6 = 3777 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D7 = 3778 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D8 = 3779 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D9 = 3780 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D1 = 3781 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D2 = 3782 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D3 = 3783 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D4 = 3784 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D5 = 3785 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D6 = 3786 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D7 = 3787 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D8 = 3788 - INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D9 = 3789 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D1 = 3790 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D2 = 3791 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D3 = 3792 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D4 = 3793 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D5 = 3794 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D6 = 3795 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D7 = 3796 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D8 = 3797 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D9 = 3798 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D1 = 3799 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D2 = 3800 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D3 = 3801 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D4 = 3802 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D5 = 3803 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D6 = 3804 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D7 = 3805 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D8 = 3806 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D9 = 3807 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D1 = 3808 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D2 = 3809 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D3 = 3810 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D4 = 3811 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D5 = 3812 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D6 = 3813 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D7 = 3814 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D8 = 3815 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D9 = 3816 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D1 = 3817 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D2 = 3818 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D3 = 3819 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D4 = 3820 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D5 = 3821 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D6 = 3822 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D7 = 3823 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D8 = 3824 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D9 = 3825 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D1 = 3826 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D2 = 3827 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D3 = 3828 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D4 = 3829 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D5 = 3830 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D6 = 3831 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D7 = 3832 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D8 = 3833 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D9 = 3834 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D1 = 3835 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D2 = 3836 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D3 = 3837 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D4 = 3838 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D5 = 3839 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D6 = 3840 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D7 = 3841 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D8 = 3842 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D9 = 3843 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D1 = 3844 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D2 = 3845 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D3 = 3846 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D4 = 3847 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D5 = 3848 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D6 = 3849 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D7 = 3850 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D8 = 3851 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D9 = 3852 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D1 = 3853 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D2 = 3854 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D3 = 3855 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D4 = 3856 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D5 = 3857 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D6 = 3858 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D7 = 3859 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D8 = 3860 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D9 = 3861 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D1 = 3862 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D2 = 3863 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D3 = 3864 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D4 = 3865 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D5 = 3866 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D6 = 3867 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D7 = 3868 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D8 = 3869 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D9 = 3870 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D1 = 3871 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D2 = 3872 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D3 = 3873 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D4 = 3874 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D5 = 3875 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D6 = 3876 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D7 = 3877 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D8 = 3878 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D9 = 3879 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D1 = 3880 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D2 = 3881 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D3 = 3882 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D4 = 3883 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D5 = 3884 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D6 = 3885 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D7 = 3886 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D8 = 3887 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D9 = 3888 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D1 = 3889 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D2 = 3890 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D3 = 3891 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D4 = 3892 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D5 = 3893 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D6 = 3894 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D7 = 3895 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D8 = 3896 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D9 = 3897 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D1 = 3898 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D2 = 3899 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D3 = 3900 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D4 = 3901 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D5 = 3902 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D6 = 3903 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D7 = 3904 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D8 = 3905 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D9 = 3906 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D1 = 3907 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D2 = 3908 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D3 = 3909 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D4 = 3910 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D5 = 3911 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D6 = 3912 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D7 = 3913 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D8 = 3914 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D9 = 3915 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D1 = 3916 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D2 = 3917 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D3 = 3918 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D4 = 3919 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D5 = 3920 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D6 = 3921 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D7 = 3922 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D8 = 3923 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D9 = 3924 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D1 = 3925 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D2 = 3926 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D3 = 3927 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D4 = 3928 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D5 = 3929 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D6 = 3930 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D7 = 3931 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D8 = 3932 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D9 = 3933 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D1 = 3934 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D2 = 3935 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D3 = 3936 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D4 = 3937 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D5 = 3938 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D6 = 3939 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D7 = 3940 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D8 = 3941 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D9 = 3942 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D1 = 3943 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D2 = 3944 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D3 = 3945 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D4 = 3946 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D5 = 3947 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D6 = 3948 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D7 = 3949 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D8 = 3950 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D9 = 3951 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D1 = 3952 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D2 = 3953 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D3 = 3954 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D4 = 3955 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D5 = 3956 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D6 = 3957 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D7 = 3958 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D8 = 3959 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D9 = 3960 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D1 = 3961 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D2 = 3962 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D3 = 3963 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D4 = 3964 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D5 = 3965 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D6 = 3966 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D7 = 3967 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D8 = 3968 - INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D9 = 3969 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D1 = 3970 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D2 = 3971 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D3 = 3972 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D4 = 3973 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D5 = 3974 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D6 = 3975 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D7 = 3976 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D8 = 3977 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D9 = 3978 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D1 = 3979 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D2 = 3980 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D3 = 3981 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D4 = 3982 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D5 = 3983 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D6 = 3984 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D7 = 3985 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D8 = 3986 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D9 = 3987 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D1 = 3988 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D2 = 3989 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D3 = 3990 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D4 = 3991 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D5 = 3992 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D6 = 3993 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D7 = 3994 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D8 = 3995 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D9 = 3996 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D1 = 3997 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D2 = 3998 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D3 = 3999 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D4 = 4000 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D5 = 4001 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D6 = 4002 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D7 = 4003 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D8 = 4004 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D9 = 4005 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D1 = 4006 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D2 = 4007 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D3 = 4008 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D4 = 4009 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D5 = 4010 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D6 = 4011 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D7 = 4012 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D8 = 4013 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D9 = 4014 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D1 = 4015 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D2 = 4016 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D3 = 4017 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D4 = 4018 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D5 = 4019 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D6 = 4020 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D7 = 4021 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D8 = 4022 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D9 = 4023 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D1 = 4024 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D2 = 4025 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D3 = 4026 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D4 = 4027 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D5 = 4028 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D6 = 4029 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D7 = 4030 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D8 = 4031 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D9 = 4032 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D1 = 4033 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D2 = 4034 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D3 = 4035 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D4 = 4036 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D5 = 4037 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D6 = 4038 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D7 = 4039 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D8 = 4040 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D9 = 4041 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D1 = 4042 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D2 = 4043 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D3 = 4044 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D4 = 4045 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D5 = 4046 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D6 = 4047 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D7 = 4048 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D8 = 4049 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D9 = 4050 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D1 = 4051 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D2 = 4052 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D3 = 4053 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D4 = 4054 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D5 = 4055 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D6 = 4056 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D7 = 4057 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D8 = 4058 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D9 = 4059 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D1 = 4060 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D2 = 4061 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D3 = 4062 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D4 = 4063 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D5 = 4064 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D6 = 4065 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D7 = 4066 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D8 = 4067 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D9 = 4068 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D1 = 4069 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D2 = 4070 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D3 = 4071 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D4 = 4072 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D5 = 4073 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D6 = 4074 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D7 = 4075 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D8 = 4076 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D9 = 4077 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D1 = 4078 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D2 = 4079 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D3 = 4080 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D4 = 4081 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D5 = 4082 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D6 = 4083 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D7 = 4084 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D8 = 4085 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D9 = 4086 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D1 = 4087 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D2 = 4088 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D3 = 4089 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D4 = 4090 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D5 = 4091 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D6 = 4092 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D7 = 4093 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D8 = 4094 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D9 = 4095 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D1 = 4096 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D2 = 4097 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D3 = 4098 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D4 = 4099 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D5 = 4100 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D6 = 4101 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D7 = 4102 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D8 = 4103 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D9 = 4104 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D1 = 4105 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D2 = 4106 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D3 = 4107 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D4 = 4108 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D5 = 4109 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D6 = 4110 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D7 = 4111 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D8 = 4112 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D9 = 4113 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D1 = 4114 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D2 = 4115 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D3 = 4116 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D4 = 4117 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D5 = 4118 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D6 = 4119 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D7 = 4120 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D8 = 4121 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D9 = 4122 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D1 = 4123 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D2 = 4124 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D3 = 4125 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D4 = 4126 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D5 = 4127 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D6 = 4128 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D7 = 4129 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D8 = 4130 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D9 = 4131 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D1 = 4132 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D2 = 4133 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D3 = 4134 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D4 = 4135 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D5 = 4136 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D6 = 4137 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D7 = 4138 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D8 = 4139 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D9 = 4140 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D1 = 4141 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D2 = 4142 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D3 = 4143 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D4 = 4144 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D5 = 4145 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D6 = 4146 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D7 = 4147 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D8 = 4148 - INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D9 = 4149 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D1 = 4150 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D2 = 4151 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D3 = 4152 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D4 = 4153 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D5 = 4154 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D6 = 4155 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D7 = 4156 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D8 = 4157 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D9 = 4158 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D1 = 4159 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D2 = 4160 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D3 = 4161 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D4 = 4162 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D5 = 4163 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D6 = 4164 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D7 = 4165 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D8 = 4166 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D9 = 4167 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D1 = 4168 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D2 = 4169 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D3 = 4170 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D4 = 4171 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D5 = 4172 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D6 = 4173 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D7 = 4174 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D8 = 4175 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D9 = 4176 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D1 = 4177 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D2 = 4178 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D3 = 4179 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D4 = 4180 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D5 = 4181 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D6 = 4182 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D7 = 4183 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D8 = 4184 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D9 = 4185 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D1 = 4186 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D2 = 4187 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D3 = 4188 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D4 = 4189 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D5 = 4190 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D6 = 4191 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D7 = 4192 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D8 = 4193 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D9 = 4194 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D1 = 4195 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D2 = 4196 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D3 = 4197 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D4 = 4198 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D5 = 4199 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D6 = 4200 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D7 = 4201 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D8 = 4202 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D9 = 4203 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D1 = 4204 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D2 = 4205 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D3 = 4206 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D4 = 4207 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D5 = 4208 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D6 = 4209 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D7 = 4210 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D8 = 4211 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D9 = 4212 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D1 = 4213 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D2 = 4214 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D3 = 4215 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D4 = 4216 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D5 = 4217 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D6 = 4218 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D7 = 4219 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D8 = 4220 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D9 = 4221 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D1 = 4222 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D2 = 4223 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D3 = 4224 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D4 = 4225 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D5 = 4226 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D6 = 4227 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D7 = 4228 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D8 = 4229 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D9 = 4230 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D1 = 4231 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D2 = 4232 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D3 = 4233 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D4 = 4234 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D5 = 4235 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D6 = 4236 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D7 = 4237 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D8 = 4238 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D9 = 4239 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D1 = 4240 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D2 = 4241 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D3 = 4242 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D4 = 4243 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D5 = 4244 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D6 = 4245 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D7 = 4246 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D8 = 4247 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D9 = 4248 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D1 = 4249 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D2 = 4250 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D3 = 4251 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D4 = 4252 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D5 = 4253 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D6 = 4254 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D7 = 4255 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D8 = 4256 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D9 = 4257 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D1 = 4258 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D2 = 4259 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D3 = 4260 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D4 = 4261 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D5 = 4262 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D6 = 4263 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D7 = 4264 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D8 = 4265 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D9 = 4266 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D1 = 4267 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D2 = 4268 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D3 = 4269 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D4 = 4270 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D5 = 4271 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D6 = 4272 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D7 = 4273 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D8 = 4274 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D9 = 4275 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D1 = 4276 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D2 = 4277 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D3 = 4278 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D4 = 4279 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D5 = 4280 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D6 = 4281 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D7 = 4282 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D8 = 4283 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D9 = 4284 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D1 = 4285 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D2 = 4286 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D3 = 4287 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D4 = 4288 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D5 = 4289 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D6 = 4290 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D7 = 4291 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D8 = 4292 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D9 = 4293 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D1 = 4294 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D2 = 4295 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D3 = 4296 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D4 = 4297 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D5 = 4298 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D6 = 4299 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D7 = 4300 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D8 = 4301 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D9 = 4302 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D1 = 4303 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D2 = 4304 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D3 = 4305 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D4 = 4306 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D5 = 4307 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D6 = 4308 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D7 = 4309 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D8 = 4310 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D9 = 4311 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D1 = 4312 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D2 = 4313 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D3 = 4314 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D4 = 4315 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D5 = 4316 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D6 = 4317 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D7 = 4318 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D8 = 4319 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D9 = 4320 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D1 = 4321 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D2 = 4322 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D3 = 4323 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D4 = 4324 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D5 = 4325 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D6 = 4326 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D7 = 4327 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D8 = 4328 - INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D9 = 4329 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D1 = 4330 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D2 = 4331 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D3 = 4332 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D4 = 4333 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D5 = 4334 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D6 = 4335 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D7 = 4336 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D8 = 4337 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D9 = 4338 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D1 = 4339 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D2 = 4340 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D3 = 4341 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D4 = 4342 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D5 = 4343 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D6 = 4344 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D7 = 4345 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D8 = 4346 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D9 = 4347 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D1 = 4348 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D2 = 4349 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D3 = 4350 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D4 = 4351 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D5 = 4352 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D6 = 4353 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D7 = 4354 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D8 = 4355 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D9 = 4356 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D1 = 4357 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D2 = 4358 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D3 = 4359 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D4 = 4360 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D5 = 4361 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D6 = 4362 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D7 = 4363 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D8 = 4364 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D9 = 4365 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D1 = 4366 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D2 = 4367 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D3 = 4368 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D4 = 4369 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D5 = 4370 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D6 = 4371 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D7 = 4372 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D8 = 4373 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D9 = 4374 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D1 = 4375 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D2 = 4376 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D3 = 4377 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D4 = 4378 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D5 = 4379 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D6 = 4380 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D7 = 4381 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D8 = 4382 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D9 = 4383 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D1 = 4384 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D2 = 4385 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D3 = 4386 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D4 = 4387 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D5 = 4388 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D6 = 4389 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D7 = 4390 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D8 = 4391 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D9 = 4392 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D1 = 4393 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D2 = 4394 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D3 = 4395 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D4 = 4396 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D5 = 4397 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D6 = 4398 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D7 = 4399 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D8 = 4400 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D9 = 4401 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D1 = 4402 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D2 = 4403 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D3 = 4404 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D4 = 4405 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D5 = 4406 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D6 = 4407 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D7 = 4408 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D8 = 4409 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D9 = 4410 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D1 = 4411 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D2 = 4412 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D3 = 4413 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D4 = 4414 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D5 = 4415 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D6 = 4416 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D7 = 4417 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D8 = 4418 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D9 = 4419 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D1 = 4420 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D2 = 4421 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D3 = 4422 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D4 = 4423 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D5 = 4424 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D6 = 4425 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D7 = 4426 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D8 = 4427 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D9 = 4428 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D1 = 4429 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D2 = 4430 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D3 = 4431 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D4 = 4432 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D5 = 4433 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D6 = 4434 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D7 = 4435 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D8 = 4436 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D9 = 4437 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D1 = 4438 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D2 = 4439 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D3 = 4440 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D4 = 4441 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D5 = 4442 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D6 = 4443 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D7 = 4444 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D8 = 4445 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D9 = 4446 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D1 = 4447 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D2 = 4448 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D3 = 4449 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D4 = 4450 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D5 = 4451 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D6 = 4452 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D7 = 4453 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D8 = 4454 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D9 = 4455 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D1 = 4456 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D2 = 4457 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D3 = 4458 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D4 = 4459 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D5 = 4460 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D6 = 4461 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D7 = 4462 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D8 = 4463 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D9 = 4464 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D1 = 4465 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D2 = 4466 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D3 = 4467 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D4 = 4468 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D5 = 4469 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D6 = 4470 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D7 = 4471 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D8 = 4472 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D9 = 4473 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D1 = 4474 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D2 = 4475 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D3 = 4476 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D4 = 4477 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D5 = 4478 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D6 = 4479 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D7 = 4480 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D8 = 4481 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D9 = 4482 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D1 = 4483 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D2 = 4484 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D3 = 4485 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D4 = 4486 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D5 = 4487 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D6 = 4488 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D7 = 4489 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D8 = 4490 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D9 = 4491 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D1 = 4492 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D2 = 4493 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D3 = 4494 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D4 = 4495 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D5 = 4496 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D6 = 4497 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D7 = 4498 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D8 = 4499 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D9 = 4500 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D1 = 4501 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D2 = 4502 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D3 = 4503 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D4 = 4504 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D5 = 4505 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D6 = 4506 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D7 = 4507 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D8 = 4508 - INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D9 = 4509 - - - ! Total Eddy Viscosity and Individual Contributions: - - INTEGER(IntKi), PARAMETER :: EddVisT1N01D1 = 4510 - INTEGER(IntKi), PARAMETER :: EddVisT1N01D2 = 4511 - INTEGER(IntKi), PARAMETER :: EddVisT1N01D3 = 4512 - INTEGER(IntKi), PARAMETER :: EddVisT1N01D4 = 4513 - INTEGER(IntKi), PARAMETER :: EddVisT1N01D5 = 4514 - INTEGER(IntKi), PARAMETER :: EddVisT1N01D6 = 4515 - INTEGER(IntKi), PARAMETER :: EddVisT1N01D7 = 4516 - INTEGER(IntKi), PARAMETER :: EddVisT1N01D8 = 4517 - INTEGER(IntKi), PARAMETER :: EddVisT1N01D9 = 4518 - INTEGER(IntKi), PARAMETER :: EddVisT1N02D1 = 4519 - INTEGER(IntKi), PARAMETER :: EddVisT1N02D2 = 4520 - INTEGER(IntKi), PARAMETER :: EddVisT1N02D3 = 4521 - INTEGER(IntKi), PARAMETER :: EddVisT1N02D4 = 4522 - INTEGER(IntKi), PARAMETER :: EddVisT1N02D5 = 4523 - INTEGER(IntKi), PARAMETER :: EddVisT1N02D6 = 4524 - INTEGER(IntKi), PARAMETER :: EddVisT1N02D7 = 4525 - INTEGER(IntKi), PARAMETER :: EddVisT1N02D8 = 4526 - INTEGER(IntKi), PARAMETER :: EddVisT1N02D9 = 4527 - INTEGER(IntKi), PARAMETER :: EddVisT1N03D1 = 4528 - INTEGER(IntKi), PARAMETER :: EddVisT1N03D2 = 4529 - INTEGER(IntKi), PARAMETER :: EddVisT1N03D3 = 4530 - INTEGER(IntKi), PARAMETER :: EddVisT1N03D4 = 4531 - INTEGER(IntKi), PARAMETER :: EddVisT1N03D5 = 4532 - INTEGER(IntKi), PARAMETER :: EddVisT1N03D6 = 4533 - INTEGER(IntKi), PARAMETER :: EddVisT1N03D7 = 4534 - INTEGER(IntKi), PARAMETER :: EddVisT1N03D8 = 4535 - INTEGER(IntKi), PARAMETER :: EddVisT1N03D9 = 4536 - INTEGER(IntKi), PARAMETER :: EddVisT1N04D1 = 4537 - INTEGER(IntKi), PARAMETER :: EddVisT1N04D2 = 4538 - INTEGER(IntKi), PARAMETER :: EddVisT1N04D3 = 4539 - INTEGER(IntKi), PARAMETER :: EddVisT1N04D4 = 4540 - INTEGER(IntKi), PARAMETER :: EddVisT1N04D5 = 4541 - INTEGER(IntKi), PARAMETER :: EddVisT1N04D6 = 4542 - INTEGER(IntKi), PARAMETER :: EddVisT1N04D7 = 4543 - INTEGER(IntKi), PARAMETER :: EddVisT1N04D8 = 4544 - INTEGER(IntKi), PARAMETER :: EddVisT1N04D9 = 4545 - INTEGER(IntKi), PARAMETER :: EddVisT1N05D1 = 4546 - INTEGER(IntKi), PARAMETER :: EddVisT1N05D2 = 4547 - INTEGER(IntKi), PARAMETER :: EddVisT1N05D3 = 4548 - INTEGER(IntKi), PARAMETER :: EddVisT1N05D4 = 4549 - INTEGER(IntKi), PARAMETER :: EddVisT1N05D5 = 4550 - INTEGER(IntKi), PARAMETER :: EddVisT1N05D6 = 4551 - INTEGER(IntKi), PARAMETER :: EddVisT1N05D7 = 4552 - INTEGER(IntKi), PARAMETER :: EddVisT1N05D8 = 4553 - INTEGER(IntKi), PARAMETER :: EddVisT1N05D9 = 4554 - INTEGER(IntKi), PARAMETER :: EddVisT1N06D1 = 4555 - INTEGER(IntKi), PARAMETER :: EddVisT1N06D2 = 4556 - INTEGER(IntKi), PARAMETER :: EddVisT1N06D3 = 4557 - INTEGER(IntKi), PARAMETER :: EddVisT1N06D4 = 4558 - INTEGER(IntKi), PARAMETER :: EddVisT1N06D5 = 4559 - INTEGER(IntKi), PARAMETER :: EddVisT1N06D6 = 4560 - INTEGER(IntKi), PARAMETER :: EddVisT1N06D7 = 4561 - INTEGER(IntKi), PARAMETER :: EddVisT1N06D8 = 4562 - INTEGER(IntKi), PARAMETER :: EddVisT1N06D9 = 4563 - INTEGER(IntKi), PARAMETER :: EddVisT1N07D1 = 4564 - INTEGER(IntKi), PARAMETER :: EddVisT1N07D2 = 4565 - INTEGER(IntKi), PARAMETER :: EddVisT1N07D3 = 4566 - INTEGER(IntKi), PARAMETER :: EddVisT1N07D4 = 4567 - INTEGER(IntKi), PARAMETER :: EddVisT1N07D5 = 4568 - INTEGER(IntKi), PARAMETER :: EddVisT1N07D6 = 4569 - INTEGER(IntKi), PARAMETER :: EddVisT1N07D7 = 4570 - INTEGER(IntKi), PARAMETER :: EddVisT1N07D8 = 4571 - INTEGER(IntKi), PARAMETER :: EddVisT1N07D9 = 4572 - INTEGER(IntKi), PARAMETER :: EddVisT1N08D1 = 4573 - INTEGER(IntKi), PARAMETER :: EddVisT1N08D2 = 4574 - INTEGER(IntKi), PARAMETER :: EddVisT1N08D3 = 4575 - INTEGER(IntKi), PARAMETER :: EddVisT1N08D4 = 4576 - INTEGER(IntKi), PARAMETER :: EddVisT1N08D5 = 4577 - INTEGER(IntKi), PARAMETER :: EddVisT1N08D6 = 4578 - INTEGER(IntKi), PARAMETER :: EddVisT1N08D7 = 4579 - INTEGER(IntKi), PARAMETER :: EddVisT1N08D8 = 4580 - INTEGER(IntKi), PARAMETER :: EddVisT1N08D9 = 4581 - INTEGER(IntKi), PARAMETER :: EddVisT1N09D1 = 4582 - INTEGER(IntKi), PARAMETER :: EddVisT1N09D2 = 4583 - INTEGER(IntKi), PARAMETER :: EddVisT1N09D3 = 4584 - INTEGER(IntKi), PARAMETER :: EddVisT1N09D4 = 4585 - INTEGER(IntKi), PARAMETER :: EddVisT1N09D5 = 4586 - INTEGER(IntKi), PARAMETER :: EddVisT1N09D6 = 4587 - INTEGER(IntKi), PARAMETER :: EddVisT1N09D7 = 4588 - INTEGER(IntKi), PARAMETER :: EddVisT1N09D8 = 4589 - INTEGER(IntKi), PARAMETER :: EddVisT1N09D9 = 4590 - INTEGER(IntKi), PARAMETER :: EddVisT1N10D1 = 4591 - INTEGER(IntKi), PARAMETER :: EddVisT1N10D2 = 4592 - INTEGER(IntKi), PARAMETER :: EddVisT1N10D3 = 4593 - INTEGER(IntKi), PARAMETER :: EddVisT1N10D4 = 4594 - INTEGER(IntKi), PARAMETER :: EddVisT1N10D5 = 4595 - INTEGER(IntKi), PARAMETER :: EddVisT1N10D6 = 4596 - INTEGER(IntKi), PARAMETER :: EddVisT1N10D7 = 4597 - INTEGER(IntKi), PARAMETER :: EddVisT1N10D8 = 4598 - INTEGER(IntKi), PARAMETER :: EddVisT1N10D9 = 4599 - INTEGER(IntKi), PARAMETER :: EddVisT1N11D1 = 4600 - INTEGER(IntKi), PARAMETER :: EddVisT1N11D2 = 4601 - INTEGER(IntKi), PARAMETER :: EddVisT1N11D3 = 4602 - INTEGER(IntKi), PARAMETER :: EddVisT1N11D4 = 4603 - INTEGER(IntKi), PARAMETER :: EddVisT1N11D5 = 4604 - INTEGER(IntKi), PARAMETER :: EddVisT1N11D6 = 4605 - INTEGER(IntKi), PARAMETER :: EddVisT1N11D7 = 4606 - INTEGER(IntKi), PARAMETER :: EddVisT1N11D8 = 4607 - INTEGER(IntKi), PARAMETER :: EddVisT1N11D9 = 4608 - INTEGER(IntKi), PARAMETER :: EddVisT1N12D1 = 4609 - INTEGER(IntKi), PARAMETER :: EddVisT1N12D2 = 4610 - INTEGER(IntKi), PARAMETER :: EddVisT1N12D3 = 4611 - INTEGER(IntKi), PARAMETER :: EddVisT1N12D4 = 4612 - INTEGER(IntKi), PARAMETER :: EddVisT1N12D5 = 4613 - INTEGER(IntKi), PARAMETER :: EddVisT1N12D6 = 4614 - INTEGER(IntKi), PARAMETER :: EddVisT1N12D7 = 4615 - INTEGER(IntKi), PARAMETER :: EddVisT1N12D8 = 4616 - INTEGER(IntKi), PARAMETER :: EddVisT1N12D9 = 4617 - INTEGER(IntKi), PARAMETER :: EddVisT1N13D1 = 4618 - INTEGER(IntKi), PARAMETER :: EddVisT1N13D2 = 4619 - INTEGER(IntKi), PARAMETER :: EddVisT1N13D3 = 4620 - INTEGER(IntKi), PARAMETER :: EddVisT1N13D4 = 4621 - INTEGER(IntKi), PARAMETER :: EddVisT1N13D5 = 4622 - INTEGER(IntKi), PARAMETER :: EddVisT1N13D6 = 4623 - INTEGER(IntKi), PARAMETER :: EddVisT1N13D7 = 4624 - INTEGER(IntKi), PARAMETER :: EddVisT1N13D8 = 4625 - INTEGER(IntKi), PARAMETER :: EddVisT1N13D9 = 4626 - INTEGER(IntKi), PARAMETER :: EddVisT1N14D1 = 4627 - INTEGER(IntKi), PARAMETER :: EddVisT1N14D2 = 4628 - INTEGER(IntKi), PARAMETER :: EddVisT1N14D3 = 4629 - INTEGER(IntKi), PARAMETER :: EddVisT1N14D4 = 4630 - INTEGER(IntKi), PARAMETER :: EddVisT1N14D5 = 4631 - INTEGER(IntKi), PARAMETER :: EddVisT1N14D6 = 4632 - INTEGER(IntKi), PARAMETER :: EddVisT1N14D7 = 4633 - INTEGER(IntKi), PARAMETER :: EddVisT1N14D8 = 4634 - INTEGER(IntKi), PARAMETER :: EddVisT1N14D9 = 4635 - INTEGER(IntKi), PARAMETER :: EddVisT1N15D1 = 4636 - INTEGER(IntKi), PARAMETER :: EddVisT1N15D2 = 4637 - INTEGER(IntKi), PARAMETER :: EddVisT1N15D3 = 4638 - INTEGER(IntKi), PARAMETER :: EddVisT1N15D4 = 4639 - INTEGER(IntKi), PARAMETER :: EddVisT1N15D5 = 4640 - INTEGER(IntKi), PARAMETER :: EddVisT1N15D6 = 4641 - INTEGER(IntKi), PARAMETER :: EddVisT1N15D7 = 4642 - INTEGER(IntKi), PARAMETER :: EddVisT1N15D8 = 4643 - INTEGER(IntKi), PARAMETER :: EddVisT1N15D9 = 4644 - INTEGER(IntKi), PARAMETER :: EddVisT1N16D1 = 4645 - INTEGER(IntKi), PARAMETER :: EddVisT1N16D2 = 4646 - INTEGER(IntKi), PARAMETER :: EddVisT1N16D3 = 4647 - INTEGER(IntKi), PARAMETER :: EddVisT1N16D4 = 4648 - INTEGER(IntKi), PARAMETER :: EddVisT1N16D5 = 4649 - INTEGER(IntKi), PARAMETER :: EddVisT1N16D6 = 4650 - INTEGER(IntKi), PARAMETER :: EddVisT1N16D7 = 4651 - INTEGER(IntKi), PARAMETER :: EddVisT1N16D8 = 4652 - INTEGER(IntKi), PARAMETER :: EddVisT1N16D9 = 4653 - INTEGER(IntKi), PARAMETER :: EddVisT1N17D1 = 4654 - INTEGER(IntKi), PARAMETER :: EddVisT1N17D2 = 4655 - INTEGER(IntKi), PARAMETER :: EddVisT1N17D3 = 4656 - INTEGER(IntKi), PARAMETER :: EddVisT1N17D4 = 4657 - INTEGER(IntKi), PARAMETER :: EddVisT1N17D5 = 4658 - INTEGER(IntKi), PARAMETER :: EddVisT1N17D6 = 4659 - INTEGER(IntKi), PARAMETER :: EddVisT1N17D7 = 4660 - INTEGER(IntKi), PARAMETER :: EddVisT1N17D8 = 4661 - INTEGER(IntKi), PARAMETER :: EddVisT1N17D9 = 4662 - INTEGER(IntKi), PARAMETER :: EddVisT1N18D1 = 4663 - INTEGER(IntKi), PARAMETER :: EddVisT1N18D2 = 4664 - INTEGER(IntKi), PARAMETER :: EddVisT1N18D3 = 4665 - INTEGER(IntKi), PARAMETER :: EddVisT1N18D4 = 4666 - INTEGER(IntKi), PARAMETER :: EddVisT1N18D5 = 4667 - INTEGER(IntKi), PARAMETER :: EddVisT1N18D6 = 4668 - INTEGER(IntKi), PARAMETER :: EddVisT1N18D7 = 4669 - INTEGER(IntKi), PARAMETER :: EddVisT1N18D8 = 4670 - INTEGER(IntKi), PARAMETER :: EddVisT1N18D9 = 4671 - INTEGER(IntKi), PARAMETER :: EddVisT1N19D1 = 4672 - INTEGER(IntKi), PARAMETER :: EddVisT1N19D2 = 4673 - INTEGER(IntKi), PARAMETER :: EddVisT1N19D3 = 4674 - INTEGER(IntKi), PARAMETER :: EddVisT1N19D4 = 4675 - INTEGER(IntKi), PARAMETER :: EddVisT1N19D5 = 4676 - INTEGER(IntKi), PARAMETER :: EddVisT1N19D6 = 4677 - INTEGER(IntKi), PARAMETER :: EddVisT1N19D7 = 4678 - INTEGER(IntKi), PARAMETER :: EddVisT1N19D8 = 4679 - INTEGER(IntKi), PARAMETER :: EddVisT1N19D9 = 4680 - INTEGER(IntKi), PARAMETER :: EddVisT1N20D1 = 4681 - INTEGER(IntKi), PARAMETER :: EddVisT1N20D2 = 4682 - INTEGER(IntKi), PARAMETER :: EddVisT1N20D3 = 4683 - INTEGER(IntKi), PARAMETER :: EddVisT1N20D4 = 4684 - INTEGER(IntKi), PARAMETER :: EddVisT1N20D5 = 4685 - INTEGER(IntKi), PARAMETER :: EddVisT1N20D6 = 4686 - INTEGER(IntKi), PARAMETER :: EddVisT1N20D7 = 4687 - INTEGER(IntKi), PARAMETER :: EddVisT1N20D8 = 4688 - INTEGER(IntKi), PARAMETER :: EddVisT1N20D9 = 4689 - INTEGER(IntKi), PARAMETER :: EddVisT2N01D1 = 4690 - INTEGER(IntKi), PARAMETER :: EddVisT2N01D2 = 4691 - INTEGER(IntKi), PARAMETER :: EddVisT2N01D3 = 4692 - INTEGER(IntKi), PARAMETER :: EddVisT2N01D4 = 4693 - INTEGER(IntKi), PARAMETER :: EddVisT2N01D5 = 4694 - INTEGER(IntKi), PARAMETER :: EddVisT2N01D6 = 4695 - INTEGER(IntKi), PARAMETER :: EddVisT2N01D7 = 4696 - INTEGER(IntKi), PARAMETER :: EddVisT2N01D8 = 4697 - INTEGER(IntKi), PARAMETER :: EddVisT2N01D9 = 4698 - INTEGER(IntKi), PARAMETER :: EddVisT2N02D1 = 4699 - INTEGER(IntKi), PARAMETER :: EddVisT2N02D2 = 4700 - INTEGER(IntKi), PARAMETER :: EddVisT2N02D3 = 4701 - INTEGER(IntKi), PARAMETER :: EddVisT2N02D4 = 4702 - INTEGER(IntKi), PARAMETER :: EddVisT2N02D5 = 4703 - INTEGER(IntKi), PARAMETER :: EddVisT2N02D6 = 4704 - INTEGER(IntKi), PARAMETER :: EddVisT2N02D7 = 4705 - INTEGER(IntKi), PARAMETER :: EddVisT2N02D8 = 4706 - INTEGER(IntKi), PARAMETER :: EddVisT2N02D9 = 4707 - INTEGER(IntKi), PARAMETER :: EddVisT2N03D1 = 4708 - INTEGER(IntKi), PARAMETER :: EddVisT2N03D2 = 4709 - INTEGER(IntKi), PARAMETER :: EddVisT2N03D3 = 4710 - INTEGER(IntKi), PARAMETER :: EddVisT2N03D4 = 4711 - INTEGER(IntKi), PARAMETER :: EddVisT2N03D5 = 4712 - INTEGER(IntKi), PARAMETER :: EddVisT2N03D6 = 4713 - INTEGER(IntKi), PARAMETER :: EddVisT2N03D7 = 4714 - INTEGER(IntKi), PARAMETER :: EddVisT2N03D8 = 4715 - INTEGER(IntKi), PARAMETER :: EddVisT2N03D9 = 4716 - INTEGER(IntKi), PARAMETER :: EddVisT2N04D1 = 4717 - INTEGER(IntKi), PARAMETER :: EddVisT2N04D2 = 4718 - INTEGER(IntKi), PARAMETER :: EddVisT2N04D3 = 4719 - INTEGER(IntKi), PARAMETER :: EddVisT2N04D4 = 4720 - INTEGER(IntKi), PARAMETER :: EddVisT2N04D5 = 4721 - INTEGER(IntKi), PARAMETER :: EddVisT2N04D6 = 4722 - INTEGER(IntKi), PARAMETER :: EddVisT2N04D7 = 4723 - INTEGER(IntKi), PARAMETER :: EddVisT2N04D8 = 4724 - INTEGER(IntKi), PARAMETER :: EddVisT2N04D9 = 4725 - INTEGER(IntKi), PARAMETER :: EddVisT2N05D1 = 4726 - INTEGER(IntKi), PARAMETER :: EddVisT2N05D2 = 4727 - INTEGER(IntKi), PARAMETER :: EddVisT2N05D3 = 4728 - INTEGER(IntKi), PARAMETER :: EddVisT2N05D4 = 4729 - INTEGER(IntKi), PARAMETER :: EddVisT2N05D5 = 4730 - INTEGER(IntKi), PARAMETER :: EddVisT2N05D6 = 4731 - INTEGER(IntKi), PARAMETER :: EddVisT2N05D7 = 4732 - INTEGER(IntKi), PARAMETER :: EddVisT2N05D8 = 4733 - INTEGER(IntKi), PARAMETER :: EddVisT2N05D9 = 4734 - INTEGER(IntKi), PARAMETER :: EddVisT2N06D1 = 4735 - INTEGER(IntKi), PARAMETER :: EddVisT2N06D2 = 4736 - INTEGER(IntKi), PARAMETER :: EddVisT2N06D3 = 4737 - INTEGER(IntKi), PARAMETER :: EddVisT2N06D4 = 4738 - INTEGER(IntKi), PARAMETER :: EddVisT2N06D5 = 4739 - INTEGER(IntKi), PARAMETER :: EddVisT2N06D6 = 4740 - INTEGER(IntKi), PARAMETER :: EddVisT2N06D7 = 4741 - INTEGER(IntKi), PARAMETER :: EddVisT2N06D8 = 4742 - INTEGER(IntKi), PARAMETER :: EddVisT2N06D9 = 4743 - INTEGER(IntKi), PARAMETER :: EddVisT2N07D1 = 4744 - INTEGER(IntKi), PARAMETER :: EddVisT2N07D2 = 4745 - INTEGER(IntKi), PARAMETER :: EddVisT2N07D3 = 4746 - INTEGER(IntKi), PARAMETER :: EddVisT2N07D4 = 4747 - INTEGER(IntKi), PARAMETER :: EddVisT2N07D5 = 4748 - INTEGER(IntKi), PARAMETER :: EddVisT2N07D6 = 4749 - INTEGER(IntKi), PARAMETER :: EddVisT2N07D7 = 4750 - INTEGER(IntKi), PARAMETER :: EddVisT2N07D8 = 4751 - INTEGER(IntKi), PARAMETER :: EddVisT2N07D9 = 4752 - INTEGER(IntKi), PARAMETER :: EddVisT2N08D1 = 4753 - INTEGER(IntKi), PARAMETER :: EddVisT2N08D2 = 4754 - INTEGER(IntKi), PARAMETER :: EddVisT2N08D3 = 4755 - INTEGER(IntKi), PARAMETER :: EddVisT2N08D4 = 4756 - INTEGER(IntKi), PARAMETER :: EddVisT2N08D5 = 4757 - INTEGER(IntKi), PARAMETER :: EddVisT2N08D6 = 4758 - INTEGER(IntKi), PARAMETER :: EddVisT2N08D7 = 4759 - INTEGER(IntKi), PARAMETER :: EddVisT2N08D8 = 4760 - INTEGER(IntKi), PARAMETER :: EddVisT2N08D9 = 4761 - INTEGER(IntKi), PARAMETER :: EddVisT2N09D1 = 4762 - INTEGER(IntKi), PARAMETER :: EddVisT2N09D2 = 4763 - INTEGER(IntKi), PARAMETER :: EddVisT2N09D3 = 4764 - INTEGER(IntKi), PARAMETER :: EddVisT2N09D4 = 4765 - INTEGER(IntKi), PARAMETER :: EddVisT2N09D5 = 4766 - INTEGER(IntKi), PARAMETER :: EddVisT2N09D6 = 4767 - INTEGER(IntKi), PARAMETER :: EddVisT2N09D7 = 4768 - INTEGER(IntKi), PARAMETER :: EddVisT2N09D8 = 4769 - INTEGER(IntKi), PARAMETER :: EddVisT2N09D9 = 4770 - INTEGER(IntKi), PARAMETER :: EddVisT2N10D1 = 4771 - INTEGER(IntKi), PARAMETER :: EddVisT2N10D2 = 4772 - INTEGER(IntKi), PARAMETER :: EddVisT2N10D3 = 4773 - INTEGER(IntKi), PARAMETER :: EddVisT2N10D4 = 4774 - INTEGER(IntKi), PARAMETER :: EddVisT2N10D5 = 4775 - INTEGER(IntKi), PARAMETER :: EddVisT2N10D6 = 4776 - INTEGER(IntKi), PARAMETER :: EddVisT2N10D7 = 4777 - INTEGER(IntKi), PARAMETER :: EddVisT2N10D8 = 4778 - INTEGER(IntKi), PARAMETER :: EddVisT2N10D9 = 4779 - INTEGER(IntKi), PARAMETER :: EddVisT2N11D1 = 4780 - INTEGER(IntKi), PARAMETER :: EddVisT2N11D2 = 4781 - INTEGER(IntKi), PARAMETER :: EddVisT2N11D3 = 4782 - INTEGER(IntKi), PARAMETER :: EddVisT2N11D4 = 4783 - INTEGER(IntKi), PARAMETER :: EddVisT2N11D5 = 4784 - INTEGER(IntKi), PARAMETER :: EddVisT2N11D6 = 4785 - INTEGER(IntKi), PARAMETER :: EddVisT2N11D7 = 4786 - INTEGER(IntKi), PARAMETER :: EddVisT2N11D8 = 4787 - INTEGER(IntKi), PARAMETER :: EddVisT2N11D9 = 4788 - INTEGER(IntKi), PARAMETER :: EddVisT2N12D1 = 4789 - INTEGER(IntKi), PARAMETER :: EddVisT2N12D2 = 4790 - INTEGER(IntKi), PARAMETER :: EddVisT2N12D3 = 4791 - INTEGER(IntKi), PARAMETER :: EddVisT2N12D4 = 4792 - INTEGER(IntKi), PARAMETER :: EddVisT2N12D5 = 4793 - INTEGER(IntKi), PARAMETER :: EddVisT2N12D6 = 4794 - INTEGER(IntKi), PARAMETER :: EddVisT2N12D7 = 4795 - INTEGER(IntKi), PARAMETER :: EddVisT2N12D8 = 4796 - INTEGER(IntKi), PARAMETER :: EddVisT2N12D9 = 4797 - INTEGER(IntKi), PARAMETER :: EddVisT2N13D1 = 4798 - INTEGER(IntKi), PARAMETER :: EddVisT2N13D2 = 4799 - INTEGER(IntKi), PARAMETER :: EddVisT2N13D3 = 4800 - INTEGER(IntKi), PARAMETER :: EddVisT2N13D4 = 4801 - INTEGER(IntKi), PARAMETER :: EddVisT2N13D5 = 4802 - INTEGER(IntKi), PARAMETER :: EddVisT2N13D6 = 4803 - INTEGER(IntKi), PARAMETER :: EddVisT2N13D7 = 4804 - INTEGER(IntKi), PARAMETER :: EddVisT2N13D8 = 4805 - INTEGER(IntKi), PARAMETER :: EddVisT2N13D9 = 4806 - INTEGER(IntKi), PARAMETER :: EddVisT2N14D1 = 4807 - INTEGER(IntKi), PARAMETER :: EddVisT2N14D2 = 4808 - INTEGER(IntKi), PARAMETER :: EddVisT2N14D3 = 4809 - INTEGER(IntKi), PARAMETER :: EddVisT2N14D4 = 4810 - INTEGER(IntKi), PARAMETER :: EddVisT2N14D5 = 4811 - INTEGER(IntKi), PARAMETER :: EddVisT2N14D6 = 4812 - INTEGER(IntKi), PARAMETER :: EddVisT2N14D7 = 4813 - INTEGER(IntKi), PARAMETER :: EddVisT2N14D8 = 4814 - INTEGER(IntKi), PARAMETER :: EddVisT2N14D9 = 4815 - INTEGER(IntKi), PARAMETER :: EddVisT2N15D1 = 4816 - INTEGER(IntKi), PARAMETER :: EddVisT2N15D2 = 4817 - INTEGER(IntKi), PARAMETER :: EddVisT2N15D3 = 4818 - INTEGER(IntKi), PARAMETER :: EddVisT2N15D4 = 4819 - INTEGER(IntKi), PARAMETER :: EddVisT2N15D5 = 4820 - INTEGER(IntKi), PARAMETER :: EddVisT2N15D6 = 4821 - INTEGER(IntKi), PARAMETER :: EddVisT2N15D7 = 4822 - INTEGER(IntKi), PARAMETER :: EddVisT2N15D8 = 4823 - INTEGER(IntKi), PARAMETER :: EddVisT2N15D9 = 4824 - INTEGER(IntKi), PARAMETER :: EddVisT2N16D1 = 4825 - INTEGER(IntKi), PARAMETER :: EddVisT2N16D2 = 4826 - INTEGER(IntKi), PARAMETER :: EddVisT2N16D3 = 4827 - INTEGER(IntKi), PARAMETER :: EddVisT2N16D4 = 4828 - INTEGER(IntKi), PARAMETER :: EddVisT2N16D5 = 4829 - INTEGER(IntKi), PARAMETER :: EddVisT2N16D6 = 4830 - INTEGER(IntKi), PARAMETER :: EddVisT2N16D7 = 4831 - INTEGER(IntKi), PARAMETER :: EddVisT2N16D8 = 4832 - INTEGER(IntKi), PARAMETER :: EddVisT2N16D9 = 4833 - INTEGER(IntKi), PARAMETER :: EddVisT2N17D1 = 4834 - INTEGER(IntKi), PARAMETER :: EddVisT2N17D2 = 4835 - INTEGER(IntKi), PARAMETER :: EddVisT2N17D3 = 4836 - INTEGER(IntKi), PARAMETER :: EddVisT2N17D4 = 4837 - INTEGER(IntKi), PARAMETER :: EddVisT2N17D5 = 4838 - INTEGER(IntKi), PARAMETER :: EddVisT2N17D6 = 4839 - INTEGER(IntKi), PARAMETER :: EddVisT2N17D7 = 4840 - INTEGER(IntKi), PARAMETER :: EddVisT2N17D8 = 4841 - INTEGER(IntKi), PARAMETER :: EddVisT2N17D9 = 4842 - INTEGER(IntKi), PARAMETER :: EddVisT2N18D1 = 4843 - INTEGER(IntKi), PARAMETER :: EddVisT2N18D2 = 4844 - INTEGER(IntKi), PARAMETER :: EddVisT2N18D3 = 4845 - INTEGER(IntKi), PARAMETER :: EddVisT2N18D4 = 4846 - INTEGER(IntKi), PARAMETER :: EddVisT2N18D5 = 4847 - INTEGER(IntKi), PARAMETER :: EddVisT2N18D6 = 4848 - INTEGER(IntKi), PARAMETER :: EddVisT2N18D7 = 4849 - INTEGER(IntKi), PARAMETER :: EddVisT2N18D8 = 4850 - INTEGER(IntKi), PARAMETER :: EddVisT2N18D9 = 4851 - INTEGER(IntKi), PARAMETER :: EddVisT2N19D1 = 4852 - INTEGER(IntKi), PARAMETER :: EddVisT2N19D2 = 4853 - INTEGER(IntKi), PARAMETER :: EddVisT2N19D3 = 4854 - INTEGER(IntKi), PARAMETER :: EddVisT2N19D4 = 4855 - INTEGER(IntKi), PARAMETER :: EddVisT2N19D5 = 4856 - INTEGER(IntKi), PARAMETER :: EddVisT2N19D6 = 4857 - INTEGER(IntKi), PARAMETER :: EddVisT2N19D7 = 4858 - INTEGER(IntKi), PARAMETER :: EddVisT2N19D8 = 4859 - INTEGER(IntKi), PARAMETER :: EddVisT2N19D9 = 4860 - INTEGER(IntKi), PARAMETER :: EddVisT2N20D1 = 4861 - INTEGER(IntKi), PARAMETER :: EddVisT2N20D2 = 4862 - INTEGER(IntKi), PARAMETER :: EddVisT2N20D3 = 4863 - INTEGER(IntKi), PARAMETER :: EddVisT2N20D4 = 4864 - INTEGER(IntKi), PARAMETER :: EddVisT2N20D5 = 4865 - INTEGER(IntKi), PARAMETER :: EddVisT2N20D6 = 4866 - INTEGER(IntKi), PARAMETER :: EddVisT2N20D7 = 4867 - INTEGER(IntKi), PARAMETER :: EddVisT2N20D8 = 4868 - INTEGER(IntKi), PARAMETER :: EddVisT2N20D9 = 4869 - INTEGER(IntKi), PARAMETER :: EddVisT3N01D1 = 4870 - INTEGER(IntKi), PARAMETER :: EddVisT3N01D2 = 4871 - INTEGER(IntKi), PARAMETER :: EddVisT3N01D3 = 4872 - INTEGER(IntKi), PARAMETER :: EddVisT3N01D4 = 4873 - INTEGER(IntKi), PARAMETER :: EddVisT3N01D5 = 4874 - INTEGER(IntKi), PARAMETER :: EddVisT3N01D6 = 4875 - INTEGER(IntKi), PARAMETER :: EddVisT3N01D7 = 4876 - INTEGER(IntKi), PARAMETER :: EddVisT3N01D8 = 4877 - INTEGER(IntKi), PARAMETER :: EddVisT3N01D9 = 4878 - INTEGER(IntKi), PARAMETER :: EddVisT3N02D1 = 4879 - INTEGER(IntKi), PARAMETER :: EddVisT3N02D2 = 4880 - INTEGER(IntKi), PARAMETER :: EddVisT3N02D3 = 4881 - INTEGER(IntKi), PARAMETER :: EddVisT3N02D4 = 4882 - INTEGER(IntKi), PARAMETER :: EddVisT3N02D5 = 4883 - INTEGER(IntKi), PARAMETER :: EddVisT3N02D6 = 4884 - INTEGER(IntKi), PARAMETER :: EddVisT3N02D7 = 4885 - INTEGER(IntKi), PARAMETER :: EddVisT3N02D8 = 4886 - INTEGER(IntKi), PARAMETER :: EddVisT3N02D9 = 4887 - INTEGER(IntKi), PARAMETER :: EddVisT3N03D1 = 4888 - INTEGER(IntKi), PARAMETER :: EddVisT3N03D2 = 4889 - INTEGER(IntKi), PARAMETER :: EddVisT3N03D3 = 4890 - INTEGER(IntKi), PARAMETER :: EddVisT3N03D4 = 4891 - INTEGER(IntKi), PARAMETER :: EddVisT3N03D5 = 4892 - INTEGER(IntKi), PARAMETER :: EddVisT3N03D6 = 4893 - INTEGER(IntKi), PARAMETER :: EddVisT3N03D7 = 4894 - INTEGER(IntKi), PARAMETER :: EddVisT3N03D8 = 4895 - INTEGER(IntKi), PARAMETER :: EddVisT3N03D9 = 4896 - INTEGER(IntKi), PARAMETER :: EddVisT3N04D1 = 4897 - INTEGER(IntKi), PARAMETER :: EddVisT3N04D2 = 4898 - INTEGER(IntKi), PARAMETER :: EddVisT3N04D3 = 4899 - INTEGER(IntKi), PARAMETER :: EddVisT3N04D4 = 4900 - INTEGER(IntKi), PARAMETER :: EddVisT3N04D5 = 4901 - INTEGER(IntKi), PARAMETER :: EddVisT3N04D6 = 4902 - INTEGER(IntKi), PARAMETER :: EddVisT3N04D7 = 4903 - INTEGER(IntKi), PARAMETER :: EddVisT3N04D8 = 4904 - INTEGER(IntKi), PARAMETER :: EddVisT3N04D9 = 4905 - INTEGER(IntKi), PARAMETER :: EddVisT3N05D1 = 4906 - INTEGER(IntKi), PARAMETER :: EddVisT3N05D2 = 4907 - INTEGER(IntKi), PARAMETER :: EddVisT3N05D3 = 4908 - INTEGER(IntKi), PARAMETER :: EddVisT3N05D4 = 4909 - INTEGER(IntKi), PARAMETER :: EddVisT3N05D5 = 4910 - INTEGER(IntKi), PARAMETER :: EddVisT3N05D6 = 4911 - INTEGER(IntKi), PARAMETER :: EddVisT3N05D7 = 4912 - INTEGER(IntKi), PARAMETER :: EddVisT3N05D8 = 4913 - INTEGER(IntKi), PARAMETER :: EddVisT3N05D9 = 4914 - INTEGER(IntKi), PARAMETER :: EddVisT3N06D1 = 4915 - INTEGER(IntKi), PARAMETER :: EddVisT3N06D2 = 4916 - INTEGER(IntKi), PARAMETER :: EddVisT3N06D3 = 4917 - INTEGER(IntKi), PARAMETER :: EddVisT3N06D4 = 4918 - INTEGER(IntKi), PARAMETER :: EddVisT3N06D5 = 4919 - INTEGER(IntKi), PARAMETER :: EddVisT3N06D6 = 4920 - INTEGER(IntKi), PARAMETER :: EddVisT3N06D7 = 4921 - INTEGER(IntKi), PARAMETER :: EddVisT3N06D8 = 4922 - INTEGER(IntKi), PARAMETER :: EddVisT3N06D9 = 4923 - INTEGER(IntKi), PARAMETER :: EddVisT3N07D1 = 4924 - INTEGER(IntKi), PARAMETER :: EddVisT3N07D2 = 4925 - INTEGER(IntKi), PARAMETER :: EddVisT3N07D3 = 4926 - INTEGER(IntKi), PARAMETER :: EddVisT3N07D4 = 4927 - INTEGER(IntKi), PARAMETER :: EddVisT3N07D5 = 4928 - INTEGER(IntKi), PARAMETER :: EddVisT3N07D6 = 4929 - INTEGER(IntKi), PARAMETER :: EddVisT3N07D7 = 4930 - INTEGER(IntKi), PARAMETER :: EddVisT3N07D8 = 4931 - INTEGER(IntKi), PARAMETER :: EddVisT3N07D9 = 4932 - INTEGER(IntKi), PARAMETER :: EddVisT3N08D1 = 4933 - INTEGER(IntKi), PARAMETER :: EddVisT3N08D2 = 4934 - INTEGER(IntKi), PARAMETER :: EddVisT3N08D3 = 4935 - INTEGER(IntKi), PARAMETER :: EddVisT3N08D4 = 4936 - INTEGER(IntKi), PARAMETER :: EddVisT3N08D5 = 4937 - INTEGER(IntKi), PARAMETER :: EddVisT3N08D6 = 4938 - INTEGER(IntKi), PARAMETER :: EddVisT3N08D7 = 4939 - INTEGER(IntKi), PARAMETER :: EddVisT3N08D8 = 4940 - INTEGER(IntKi), PARAMETER :: EddVisT3N08D9 = 4941 - INTEGER(IntKi), PARAMETER :: EddVisT3N09D1 = 4942 - INTEGER(IntKi), PARAMETER :: EddVisT3N09D2 = 4943 - INTEGER(IntKi), PARAMETER :: EddVisT3N09D3 = 4944 - INTEGER(IntKi), PARAMETER :: EddVisT3N09D4 = 4945 - INTEGER(IntKi), PARAMETER :: EddVisT3N09D5 = 4946 - INTEGER(IntKi), PARAMETER :: EddVisT3N09D6 = 4947 - INTEGER(IntKi), PARAMETER :: EddVisT3N09D7 = 4948 - INTEGER(IntKi), PARAMETER :: EddVisT3N09D8 = 4949 - INTEGER(IntKi), PARAMETER :: EddVisT3N09D9 = 4950 - INTEGER(IntKi), PARAMETER :: EddVisT3N10D1 = 4951 - INTEGER(IntKi), PARAMETER :: EddVisT3N10D2 = 4952 - INTEGER(IntKi), PARAMETER :: EddVisT3N10D3 = 4953 - INTEGER(IntKi), PARAMETER :: EddVisT3N10D4 = 4954 - INTEGER(IntKi), PARAMETER :: EddVisT3N10D5 = 4955 - INTEGER(IntKi), PARAMETER :: EddVisT3N10D6 = 4956 - INTEGER(IntKi), PARAMETER :: EddVisT3N10D7 = 4957 - INTEGER(IntKi), PARAMETER :: EddVisT3N10D8 = 4958 - INTEGER(IntKi), PARAMETER :: EddVisT3N10D9 = 4959 - INTEGER(IntKi), PARAMETER :: EddVisT3N11D1 = 4960 - INTEGER(IntKi), PARAMETER :: EddVisT3N11D2 = 4961 - INTEGER(IntKi), PARAMETER :: EddVisT3N11D3 = 4962 - INTEGER(IntKi), PARAMETER :: EddVisT3N11D4 = 4963 - INTEGER(IntKi), PARAMETER :: EddVisT3N11D5 = 4964 - INTEGER(IntKi), PARAMETER :: EddVisT3N11D6 = 4965 - INTEGER(IntKi), PARAMETER :: EddVisT3N11D7 = 4966 - INTEGER(IntKi), PARAMETER :: EddVisT3N11D8 = 4967 - INTEGER(IntKi), PARAMETER :: EddVisT3N11D9 = 4968 - INTEGER(IntKi), PARAMETER :: EddVisT3N12D1 = 4969 - INTEGER(IntKi), PARAMETER :: EddVisT3N12D2 = 4970 - INTEGER(IntKi), PARAMETER :: EddVisT3N12D3 = 4971 - INTEGER(IntKi), PARAMETER :: EddVisT3N12D4 = 4972 - INTEGER(IntKi), PARAMETER :: EddVisT3N12D5 = 4973 - INTEGER(IntKi), PARAMETER :: EddVisT3N12D6 = 4974 - INTEGER(IntKi), PARAMETER :: EddVisT3N12D7 = 4975 - INTEGER(IntKi), PARAMETER :: EddVisT3N12D8 = 4976 - INTEGER(IntKi), PARAMETER :: EddVisT3N12D9 = 4977 - INTEGER(IntKi), PARAMETER :: EddVisT3N13D1 = 4978 - INTEGER(IntKi), PARAMETER :: EddVisT3N13D2 = 4979 - INTEGER(IntKi), PARAMETER :: EddVisT3N13D3 = 4980 - INTEGER(IntKi), PARAMETER :: EddVisT3N13D4 = 4981 - INTEGER(IntKi), PARAMETER :: EddVisT3N13D5 = 4982 - INTEGER(IntKi), PARAMETER :: EddVisT3N13D6 = 4983 - INTEGER(IntKi), PARAMETER :: EddVisT3N13D7 = 4984 - INTEGER(IntKi), PARAMETER :: EddVisT3N13D8 = 4985 - INTEGER(IntKi), PARAMETER :: EddVisT3N13D9 = 4986 - INTEGER(IntKi), PARAMETER :: EddVisT3N14D1 = 4987 - INTEGER(IntKi), PARAMETER :: EddVisT3N14D2 = 4988 - INTEGER(IntKi), PARAMETER :: EddVisT3N14D3 = 4989 - INTEGER(IntKi), PARAMETER :: EddVisT3N14D4 = 4990 - INTEGER(IntKi), PARAMETER :: EddVisT3N14D5 = 4991 - INTEGER(IntKi), PARAMETER :: EddVisT3N14D6 = 4992 - INTEGER(IntKi), PARAMETER :: EddVisT3N14D7 = 4993 - INTEGER(IntKi), PARAMETER :: EddVisT3N14D8 = 4994 - INTEGER(IntKi), PARAMETER :: EddVisT3N14D9 = 4995 - INTEGER(IntKi), PARAMETER :: EddVisT3N15D1 = 4996 - INTEGER(IntKi), PARAMETER :: EddVisT3N15D2 = 4997 - INTEGER(IntKi), PARAMETER :: EddVisT3N15D3 = 4998 - INTEGER(IntKi), PARAMETER :: EddVisT3N15D4 = 4999 - INTEGER(IntKi), PARAMETER :: EddVisT3N15D5 = 5000 - INTEGER(IntKi), PARAMETER :: EddVisT3N15D6 = 5001 - INTEGER(IntKi), PARAMETER :: EddVisT3N15D7 = 5002 - INTEGER(IntKi), PARAMETER :: EddVisT3N15D8 = 5003 - INTEGER(IntKi), PARAMETER :: EddVisT3N15D9 = 5004 - INTEGER(IntKi), PARAMETER :: EddVisT3N16D1 = 5005 - INTEGER(IntKi), PARAMETER :: EddVisT3N16D2 = 5006 - INTEGER(IntKi), PARAMETER :: EddVisT3N16D3 = 5007 - INTEGER(IntKi), PARAMETER :: EddVisT3N16D4 = 5008 - INTEGER(IntKi), PARAMETER :: EddVisT3N16D5 = 5009 - INTEGER(IntKi), PARAMETER :: EddVisT3N16D6 = 5010 - INTEGER(IntKi), PARAMETER :: EddVisT3N16D7 = 5011 - INTEGER(IntKi), PARAMETER :: EddVisT3N16D8 = 5012 - INTEGER(IntKi), PARAMETER :: EddVisT3N16D9 = 5013 - INTEGER(IntKi), PARAMETER :: EddVisT3N17D1 = 5014 - INTEGER(IntKi), PARAMETER :: EddVisT3N17D2 = 5015 - INTEGER(IntKi), PARAMETER :: EddVisT3N17D3 = 5016 - INTEGER(IntKi), PARAMETER :: EddVisT3N17D4 = 5017 - INTEGER(IntKi), PARAMETER :: EddVisT3N17D5 = 5018 - INTEGER(IntKi), PARAMETER :: EddVisT3N17D6 = 5019 - INTEGER(IntKi), PARAMETER :: EddVisT3N17D7 = 5020 - INTEGER(IntKi), PARAMETER :: EddVisT3N17D8 = 5021 - INTEGER(IntKi), PARAMETER :: EddVisT3N17D9 = 5022 - INTEGER(IntKi), PARAMETER :: EddVisT3N18D1 = 5023 - INTEGER(IntKi), PARAMETER :: EddVisT3N18D2 = 5024 - INTEGER(IntKi), PARAMETER :: EddVisT3N18D3 = 5025 - INTEGER(IntKi), PARAMETER :: EddVisT3N18D4 = 5026 - INTEGER(IntKi), PARAMETER :: EddVisT3N18D5 = 5027 - INTEGER(IntKi), PARAMETER :: EddVisT3N18D6 = 5028 - INTEGER(IntKi), PARAMETER :: EddVisT3N18D7 = 5029 - INTEGER(IntKi), PARAMETER :: EddVisT3N18D8 = 5030 - INTEGER(IntKi), PARAMETER :: EddVisT3N18D9 = 5031 - INTEGER(IntKi), PARAMETER :: EddVisT3N19D1 = 5032 - INTEGER(IntKi), PARAMETER :: EddVisT3N19D2 = 5033 - INTEGER(IntKi), PARAMETER :: EddVisT3N19D3 = 5034 - INTEGER(IntKi), PARAMETER :: EddVisT3N19D4 = 5035 - INTEGER(IntKi), PARAMETER :: EddVisT3N19D5 = 5036 - INTEGER(IntKi), PARAMETER :: EddVisT3N19D6 = 5037 - INTEGER(IntKi), PARAMETER :: EddVisT3N19D7 = 5038 - INTEGER(IntKi), PARAMETER :: EddVisT3N19D8 = 5039 - INTEGER(IntKi), PARAMETER :: EddVisT3N19D9 = 5040 - INTEGER(IntKi), PARAMETER :: EddVisT3N20D1 = 5041 - INTEGER(IntKi), PARAMETER :: EddVisT3N20D2 = 5042 - INTEGER(IntKi), PARAMETER :: EddVisT3N20D3 = 5043 - INTEGER(IntKi), PARAMETER :: EddVisT3N20D4 = 5044 - INTEGER(IntKi), PARAMETER :: EddVisT3N20D5 = 5045 - INTEGER(IntKi), PARAMETER :: EddVisT3N20D6 = 5046 - INTEGER(IntKi), PARAMETER :: EddVisT3N20D7 = 5047 - INTEGER(IntKi), PARAMETER :: EddVisT3N20D8 = 5048 - INTEGER(IntKi), PARAMETER :: EddVisT3N20D9 = 5049 - INTEGER(IntKi), PARAMETER :: EddVisT4N01D1 = 5050 - INTEGER(IntKi), PARAMETER :: EddVisT4N01D2 = 5051 - INTEGER(IntKi), PARAMETER :: EddVisT4N01D3 = 5052 - INTEGER(IntKi), PARAMETER :: EddVisT4N01D4 = 5053 - INTEGER(IntKi), PARAMETER :: EddVisT4N01D5 = 5054 - INTEGER(IntKi), PARAMETER :: EddVisT4N01D6 = 5055 - INTEGER(IntKi), PARAMETER :: EddVisT4N01D7 = 5056 - INTEGER(IntKi), PARAMETER :: EddVisT4N01D8 = 5057 - INTEGER(IntKi), PARAMETER :: EddVisT4N01D9 = 5058 - INTEGER(IntKi), PARAMETER :: EddVisT4N02D1 = 5059 - INTEGER(IntKi), PARAMETER :: EddVisT4N02D2 = 5060 - INTEGER(IntKi), PARAMETER :: EddVisT4N02D3 = 5061 - INTEGER(IntKi), PARAMETER :: EddVisT4N02D4 = 5062 - INTEGER(IntKi), PARAMETER :: EddVisT4N02D5 = 5063 - INTEGER(IntKi), PARAMETER :: EddVisT4N02D6 = 5064 - INTEGER(IntKi), PARAMETER :: EddVisT4N02D7 = 5065 - INTEGER(IntKi), PARAMETER :: EddVisT4N02D8 = 5066 - INTEGER(IntKi), PARAMETER :: EddVisT4N02D9 = 5067 - INTEGER(IntKi), PARAMETER :: EddVisT4N03D1 = 5068 - INTEGER(IntKi), PARAMETER :: EddVisT4N03D2 = 5069 - INTEGER(IntKi), PARAMETER :: EddVisT4N03D3 = 5070 - INTEGER(IntKi), PARAMETER :: EddVisT4N03D4 = 5071 - INTEGER(IntKi), PARAMETER :: EddVisT4N03D5 = 5072 - INTEGER(IntKi), PARAMETER :: EddVisT4N03D6 = 5073 - INTEGER(IntKi), PARAMETER :: EddVisT4N03D7 = 5074 - INTEGER(IntKi), PARAMETER :: EddVisT4N03D8 = 5075 - INTEGER(IntKi), PARAMETER :: EddVisT4N03D9 = 5076 - INTEGER(IntKi), PARAMETER :: EddVisT4N04D1 = 5077 - INTEGER(IntKi), PARAMETER :: EddVisT4N04D2 = 5078 - INTEGER(IntKi), PARAMETER :: EddVisT4N04D3 = 5079 - INTEGER(IntKi), PARAMETER :: EddVisT4N04D4 = 5080 - INTEGER(IntKi), PARAMETER :: EddVisT4N04D5 = 5081 - INTEGER(IntKi), PARAMETER :: EddVisT4N04D6 = 5082 - INTEGER(IntKi), PARAMETER :: EddVisT4N04D7 = 5083 - INTEGER(IntKi), PARAMETER :: EddVisT4N04D8 = 5084 - INTEGER(IntKi), PARAMETER :: EddVisT4N04D9 = 5085 - INTEGER(IntKi), PARAMETER :: EddVisT4N05D1 = 5086 - INTEGER(IntKi), PARAMETER :: EddVisT4N05D2 = 5087 - INTEGER(IntKi), PARAMETER :: EddVisT4N05D3 = 5088 - INTEGER(IntKi), PARAMETER :: EddVisT4N05D4 = 5089 - INTEGER(IntKi), PARAMETER :: EddVisT4N05D5 = 5090 - INTEGER(IntKi), PARAMETER :: EddVisT4N05D6 = 5091 - INTEGER(IntKi), PARAMETER :: EddVisT4N05D7 = 5092 - INTEGER(IntKi), PARAMETER :: EddVisT4N05D8 = 5093 - INTEGER(IntKi), PARAMETER :: EddVisT4N05D9 = 5094 - INTEGER(IntKi), PARAMETER :: EddVisT4N06D1 = 5095 - INTEGER(IntKi), PARAMETER :: EddVisT4N06D2 = 5096 - INTEGER(IntKi), PARAMETER :: EddVisT4N06D3 = 5097 - INTEGER(IntKi), PARAMETER :: EddVisT4N06D4 = 5098 - INTEGER(IntKi), PARAMETER :: EddVisT4N06D5 = 5099 - INTEGER(IntKi), PARAMETER :: EddVisT4N06D6 = 5100 - INTEGER(IntKi), PARAMETER :: EddVisT4N06D7 = 5101 - INTEGER(IntKi), PARAMETER :: EddVisT4N06D8 = 5102 - INTEGER(IntKi), PARAMETER :: EddVisT4N06D9 = 5103 - INTEGER(IntKi), PARAMETER :: EddVisT4N07D1 = 5104 - INTEGER(IntKi), PARAMETER :: EddVisT4N07D2 = 5105 - INTEGER(IntKi), PARAMETER :: EddVisT4N07D3 = 5106 - INTEGER(IntKi), PARAMETER :: EddVisT4N07D4 = 5107 - INTEGER(IntKi), PARAMETER :: EddVisT4N07D5 = 5108 - INTEGER(IntKi), PARAMETER :: EddVisT4N07D6 = 5109 - INTEGER(IntKi), PARAMETER :: EddVisT4N07D7 = 5110 - INTEGER(IntKi), PARAMETER :: EddVisT4N07D8 = 5111 - INTEGER(IntKi), PARAMETER :: EddVisT4N07D9 = 5112 - INTEGER(IntKi), PARAMETER :: EddVisT4N08D1 = 5113 - INTEGER(IntKi), PARAMETER :: EddVisT4N08D2 = 5114 - INTEGER(IntKi), PARAMETER :: EddVisT4N08D3 = 5115 - INTEGER(IntKi), PARAMETER :: EddVisT4N08D4 = 5116 - INTEGER(IntKi), PARAMETER :: EddVisT4N08D5 = 5117 - INTEGER(IntKi), PARAMETER :: EddVisT4N08D6 = 5118 - INTEGER(IntKi), PARAMETER :: EddVisT4N08D7 = 5119 - INTEGER(IntKi), PARAMETER :: EddVisT4N08D8 = 5120 - INTEGER(IntKi), PARAMETER :: EddVisT4N08D9 = 5121 - INTEGER(IntKi), PARAMETER :: EddVisT4N09D1 = 5122 - INTEGER(IntKi), PARAMETER :: EddVisT4N09D2 = 5123 - INTEGER(IntKi), PARAMETER :: EddVisT4N09D3 = 5124 - INTEGER(IntKi), PARAMETER :: EddVisT4N09D4 = 5125 - INTEGER(IntKi), PARAMETER :: EddVisT4N09D5 = 5126 - INTEGER(IntKi), PARAMETER :: EddVisT4N09D6 = 5127 - INTEGER(IntKi), PARAMETER :: EddVisT4N09D7 = 5128 - INTEGER(IntKi), PARAMETER :: EddVisT4N09D8 = 5129 - INTEGER(IntKi), PARAMETER :: EddVisT4N09D9 = 5130 - INTEGER(IntKi), PARAMETER :: EddVisT4N10D1 = 5131 - INTEGER(IntKi), PARAMETER :: EddVisT4N10D2 = 5132 - INTEGER(IntKi), PARAMETER :: EddVisT4N10D3 = 5133 - INTEGER(IntKi), PARAMETER :: EddVisT4N10D4 = 5134 - INTEGER(IntKi), PARAMETER :: EddVisT4N10D5 = 5135 - INTEGER(IntKi), PARAMETER :: EddVisT4N10D6 = 5136 - INTEGER(IntKi), PARAMETER :: EddVisT4N10D7 = 5137 - INTEGER(IntKi), PARAMETER :: EddVisT4N10D8 = 5138 - INTEGER(IntKi), PARAMETER :: EddVisT4N10D9 = 5139 - INTEGER(IntKi), PARAMETER :: EddVisT4N11D1 = 5140 - INTEGER(IntKi), PARAMETER :: EddVisT4N11D2 = 5141 - INTEGER(IntKi), PARAMETER :: EddVisT4N11D3 = 5142 - INTEGER(IntKi), PARAMETER :: EddVisT4N11D4 = 5143 - INTEGER(IntKi), PARAMETER :: EddVisT4N11D5 = 5144 - INTEGER(IntKi), PARAMETER :: EddVisT4N11D6 = 5145 - INTEGER(IntKi), PARAMETER :: EddVisT4N11D7 = 5146 - INTEGER(IntKi), PARAMETER :: EddVisT4N11D8 = 5147 - INTEGER(IntKi), PARAMETER :: EddVisT4N11D9 = 5148 - INTEGER(IntKi), PARAMETER :: EddVisT4N12D1 = 5149 - INTEGER(IntKi), PARAMETER :: EddVisT4N12D2 = 5150 - INTEGER(IntKi), PARAMETER :: EddVisT4N12D3 = 5151 - INTEGER(IntKi), PARAMETER :: EddVisT4N12D4 = 5152 - INTEGER(IntKi), PARAMETER :: EddVisT4N12D5 = 5153 - INTEGER(IntKi), PARAMETER :: EddVisT4N12D6 = 5154 - INTEGER(IntKi), PARAMETER :: EddVisT4N12D7 = 5155 - INTEGER(IntKi), PARAMETER :: EddVisT4N12D8 = 5156 - INTEGER(IntKi), PARAMETER :: EddVisT4N12D9 = 5157 - INTEGER(IntKi), PARAMETER :: EddVisT4N13D1 = 5158 - INTEGER(IntKi), PARAMETER :: EddVisT4N13D2 = 5159 - INTEGER(IntKi), PARAMETER :: EddVisT4N13D3 = 5160 - INTEGER(IntKi), PARAMETER :: EddVisT4N13D4 = 5161 - INTEGER(IntKi), PARAMETER :: EddVisT4N13D5 = 5162 - INTEGER(IntKi), PARAMETER :: EddVisT4N13D6 = 5163 - INTEGER(IntKi), PARAMETER :: EddVisT4N13D7 = 5164 - INTEGER(IntKi), PARAMETER :: EddVisT4N13D8 = 5165 - INTEGER(IntKi), PARAMETER :: EddVisT4N13D9 = 5166 - INTEGER(IntKi), PARAMETER :: EddVisT4N14D1 = 5167 - INTEGER(IntKi), PARAMETER :: EddVisT4N14D2 = 5168 - INTEGER(IntKi), PARAMETER :: EddVisT4N14D3 = 5169 - INTEGER(IntKi), PARAMETER :: EddVisT4N14D4 = 5170 - INTEGER(IntKi), PARAMETER :: EddVisT4N14D5 = 5171 - INTEGER(IntKi), PARAMETER :: EddVisT4N14D6 = 5172 - INTEGER(IntKi), PARAMETER :: EddVisT4N14D7 = 5173 - INTEGER(IntKi), PARAMETER :: EddVisT4N14D8 = 5174 - INTEGER(IntKi), PARAMETER :: EddVisT4N14D9 = 5175 - INTEGER(IntKi), PARAMETER :: EddVisT4N15D1 = 5176 - INTEGER(IntKi), PARAMETER :: EddVisT4N15D2 = 5177 - INTEGER(IntKi), PARAMETER :: EddVisT4N15D3 = 5178 - INTEGER(IntKi), PARAMETER :: EddVisT4N15D4 = 5179 - INTEGER(IntKi), PARAMETER :: EddVisT4N15D5 = 5180 - INTEGER(IntKi), PARAMETER :: EddVisT4N15D6 = 5181 - INTEGER(IntKi), PARAMETER :: EddVisT4N15D7 = 5182 - INTEGER(IntKi), PARAMETER :: EddVisT4N15D8 = 5183 - INTEGER(IntKi), PARAMETER :: EddVisT4N15D9 = 5184 - INTEGER(IntKi), PARAMETER :: EddVisT4N16D1 = 5185 - INTEGER(IntKi), PARAMETER :: EddVisT4N16D2 = 5186 - INTEGER(IntKi), PARAMETER :: EddVisT4N16D3 = 5187 - INTEGER(IntKi), PARAMETER :: EddVisT4N16D4 = 5188 - INTEGER(IntKi), PARAMETER :: EddVisT4N16D5 = 5189 - INTEGER(IntKi), PARAMETER :: EddVisT4N16D6 = 5190 - INTEGER(IntKi), PARAMETER :: EddVisT4N16D7 = 5191 - INTEGER(IntKi), PARAMETER :: EddVisT4N16D8 = 5192 - INTEGER(IntKi), PARAMETER :: EddVisT4N16D9 = 5193 - INTEGER(IntKi), PARAMETER :: EddVisT4N17D1 = 5194 - INTEGER(IntKi), PARAMETER :: EddVisT4N17D2 = 5195 - INTEGER(IntKi), PARAMETER :: EddVisT4N17D3 = 5196 - INTEGER(IntKi), PARAMETER :: EddVisT4N17D4 = 5197 - INTEGER(IntKi), PARAMETER :: EddVisT4N17D5 = 5198 - INTEGER(IntKi), PARAMETER :: EddVisT4N17D6 = 5199 - INTEGER(IntKi), PARAMETER :: EddVisT4N17D7 = 5200 - INTEGER(IntKi), PARAMETER :: EddVisT4N17D8 = 5201 - INTEGER(IntKi), PARAMETER :: EddVisT4N17D9 = 5202 - INTEGER(IntKi), PARAMETER :: EddVisT4N18D1 = 5203 - INTEGER(IntKi), PARAMETER :: EddVisT4N18D2 = 5204 - INTEGER(IntKi), PARAMETER :: EddVisT4N18D3 = 5205 - INTEGER(IntKi), PARAMETER :: EddVisT4N18D4 = 5206 - INTEGER(IntKi), PARAMETER :: EddVisT4N18D5 = 5207 - INTEGER(IntKi), PARAMETER :: EddVisT4N18D6 = 5208 - INTEGER(IntKi), PARAMETER :: EddVisT4N18D7 = 5209 - INTEGER(IntKi), PARAMETER :: EddVisT4N18D8 = 5210 - INTEGER(IntKi), PARAMETER :: EddVisT4N18D9 = 5211 - INTEGER(IntKi), PARAMETER :: EddVisT4N19D1 = 5212 - INTEGER(IntKi), PARAMETER :: EddVisT4N19D2 = 5213 - INTEGER(IntKi), PARAMETER :: EddVisT4N19D3 = 5214 - INTEGER(IntKi), PARAMETER :: EddVisT4N19D4 = 5215 - INTEGER(IntKi), PARAMETER :: EddVisT4N19D5 = 5216 - INTEGER(IntKi), PARAMETER :: EddVisT4N19D6 = 5217 - INTEGER(IntKi), PARAMETER :: EddVisT4N19D7 = 5218 - INTEGER(IntKi), PARAMETER :: EddVisT4N19D8 = 5219 - INTEGER(IntKi), PARAMETER :: EddVisT4N19D9 = 5220 - INTEGER(IntKi), PARAMETER :: EddVisT4N20D1 = 5221 - INTEGER(IntKi), PARAMETER :: EddVisT4N20D2 = 5222 - INTEGER(IntKi), PARAMETER :: EddVisT4N20D3 = 5223 - INTEGER(IntKi), PARAMETER :: EddVisT4N20D4 = 5224 - INTEGER(IntKi), PARAMETER :: EddVisT4N20D5 = 5225 - INTEGER(IntKi), PARAMETER :: EddVisT4N20D6 = 5226 - INTEGER(IntKi), PARAMETER :: EddVisT4N20D7 = 5227 - INTEGER(IntKi), PARAMETER :: EddVisT4N20D8 = 5228 - INTEGER(IntKi), PARAMETER :: EddVisT4N20D9 = 5229 - INTEGER(IntKi), PARAMETER :: EddVisT5N01D1 = 5230 - INTEGER(IntKi), PARAMETER :: EddVisT5N01D2 = 5231 - INTEGER(IntKi), PARAMETER :: EddVisT5N01D3 = 5232 - INTEGER(IntKi), PARAMETER :: EddVisT5N01D4 = 5233 - INTEGER(IntKi), PARAMETER :: EddVisT5N01D5 = 5234 - INTEGER(IntKi), PARAMETER :: EddVisT5N01D6 = 5235 - INTEGER(IntKi), PARAMETER :: EddVisT5N01D7 = 5236 - INTEGER(IntKi), PARAMETER :: EddVisT5N01D8 = 5237 - INTEGER(IntKi), PARAMETER :: EddVisT5N01D9 = 5238 - INTEGER(IntKi), PARAMETER :: EddVisT5N02D1 = 5239 - INTEGER(IntKi), PARAMETER :: EddVisT5N02D2 = 5240 - INTEGER(IntKi), PARAMETER :: EddVisT5N02D3 = 5241 - INTEGER(IntKi), PARAMETER :: EddVisT5N02D4 = 5242 - INTEGER(IntKi), PARAMETER :: EddVisT5N02D5 = 5243 - INTEGER(IntKi), PARAMETER :: EddVisT5N02D6 = 5244 - INTEGER(IntKi), PARAMETER :: EddVisT5N02D7 = 5245 - INTEGER(IntKi), PARAMETER :: EddVisT5N02D8 = 5246 - INTEGER(IntKi), PARAMETER :: EddVisT5N02D9 = 5247 - INTEGER(IntKi), PARAMETER :: EddVisT5N03D1 = 5248 - INTEGER(IntKi), PARAMETER :: EddVisT5N03D2 = 5249 - INTEGER(IntKi), PARAMETER :: EddVisT5N03D3 = 5250 - INTEGER(IntKi), PARAMETER :: EddVisT5N03D4 = 5251 - INTEGER(IntKi), PARAMETER :: EddVisT5N03D5 = 5252 - INTEGER(IntKi), PARAMETER :: EddVisT5N03D6 = 5253 - INTEGER(IntKi), PARAMETER :: EddVisT5N03D7 = 5254 - INTEGER(IntKi), PARAMETER :: EddVisT5N03D8 = 5255 - INTEGER(IntKi), PARAMETER :: EddVisT5N03D9 = 5256 - INTEGER(IntKi), PARAMETER :: EddVisT5N04D1 = 5257 - INTEGER(IntKi), PARAMETER :: EddVisT5N04D2 = 5258 - INTEGER(IntKi), PARAMETER :: EddVisT5N04D3 = 5259 - INTEGER(IntKi), PARAMETER :: EddVisT5N04D4 = 5260 - INTEGER(IntKi), PARAMETER :: EddVisT5N04D5 = 5261 - INTEGER(IntKi), PARAMETER :: EddVisT5N04D6 = 5262 - INTEGER(IntKi), PARAMETER :: EddVisT5N04D7 = 5263 - INTEGER(IntKi), PARAMETER :: EddVisT5N04D8 = 5264 - INTEGER(IntKi), PARAMETER :: EddVisT5N04D9 = 5265 - INTEGER(IntKi), PARAMETER :: EddVisT5N05D1 = 5266 - INTEGER(IntKi), PARAMETER :: EddVisT5N05D2 = 5267 - INTEGER(IntKi), PARAMETER :: EddVisT5N05D3 = 5268 - INTEGER(IntKi), PARAMETER :: EddVisT5N05D4 = 5269 - INTEGER(IntKi), PARAMETER :: EddVisT5N05D5 = 5270 - INTEGER(IntKi), PARAMETER :: EddVisT5N05D6 = 5271 - INTEGER(IntKi), PARAMETER :: EddVisT5N05D7 = 5272 - INTEGER(IntKi), PARAMETER :: EddVisT5N05D8 = 5273 - INTEGER(IntKi), PARAMETER :: EddVisT5N05D9 = 5274 - INTEGER(IntKi), PARAMETER :: EddVisT5N06D1 = 5275 - INTEGER(IntKi), PARAMETER :: EddVisT5N06D2 = 5276 - INTEGER(IntKi), PARAMETER :: EddVisT5N06D3 = 5277 - INTEGER(IntKi), PARAMETER :: EddVisT5N06D4 = 5278 - INTEGER(IntKi), PARAMETER :: EddVisT5N06D5 = 5279 - INTEGER(IntKi), PARAMETER :: EddVisT5N06D6 = 5280 - INTEGER(IntKi), PARAMETER :: EddVisT5N06D7 = 5281 - INTEGER(IntKi), PARAMETER :: EddVisT5N06D8 = 5282 - INTEGER(IntKi), PARAMETER :: EddVisT5N06D9 = 5283 - INTEGER(IntKi), PARAMETER :: EddVisT5N07D1 = 5284 - INTEGER(IntKi), PARAMETER :: EddVisT5N07D2 = 5285 - INTEGER(IntKi), PARAMETER :: EddVisT5N07D3 = 5286 - INTEGER(IntKi), PARAMETER :: EddVisT5N07D4 = 5287 - INTEGER(IntKi), PARAMETER :: EddVisT5N07D5 = 5288 - INTEGER(IntKi), PARAMETER :: EddVisT5N07D6 = 5289 - INTEGER(IntKi), PARAMETER :: EddVisT5N07D7 = 5290 - INTEGER(IntKi), PARAMETER :: EddVisT5N07D8 = 5291 - INTEGER(IntKi), PARAMETER :: EddVisT5N07D9 = 5292 - INTEGER(IntKi), PARAMETER :: EddVisT5N08D1 = 5293 - INTEGER(IntKi), PARAMETER :: EddVisT5N08D2 = 5294 - INTEGER(IntKi), PARAMETER :: EddVisT5N08D3 = 5295 - INTEGER(IntKi), PARAMETER :: EddVisT5N08D4 = 5296 - INTEGER(IntKi), PARAMETER :: EddVisT5N08D5 = 5297 - INTEGER(IntKi), PARAMETER :: EddVisT5N08D6 = 5298 - INTEGER(IntKi), PARAMETER :: EddVisT5N08D7 = 5299 - INTEGER(IntKi), PARAMETER :: EddVisT5N08D8 = 5300 - INTEGER(IntKi), PARAMETER :: EddVisT5N08D9 = 5301 - INTEGER(IntKi), PARAMETER :: EddVisT5N09D1 = 5302 - INTEGER(IntKi), PARAMETER :: EddVisT5N09D2 = 5303 - INTEGER(IntKi), PARAMETER :: EddVisT5N09D3 = 5304 - INTEGER(IntKi), PARAMETER :: EddVisT5N09D4 = 5305 - INTEGER(IntKi), PARAMETER :: EddVisT5N09D5 = 5306 - INTEGER(IntKi), PARAMETER :: EddVisT5N09D6 = 5307 - INTEGER(IntKi), PARAMETER :: EddVisT5N09D7 = 5308 - INTEGER(IntKi), PARAMETER :: EddVisT5N09D8 = 5309 - INTEGER(IntKi), PARAMETER :: EddVisT5N09D9 = 5310 - INTEGER(IntKi), PARAMETER :: EddVisT5N10D1 = 5311 - INTEGER(IntKi), PARAMETER :: EddVisT5N10D2 = 5312 - INTEGER(IntKi), PARAMETER :: EddVisT5N10D3 = 5313 - INTEGER(IntKi), PARAMETER :: EddVisT5N10D4 = 5314 - INTEGER(IntKi), PARAMETER :: EddVisT5N10D5 = 5315 - INTEGER(IntKi), PARAMETER :: EddVisT5N10D6 = 5316 - INTEGER(IntKi), PARAMETER :: EddVisT5N10D7 = 5317 - INTEGER(IntKi), PARAMETER :: EddVisT5N10D8 = 5318 - INTEGER(IntKi), PARAMETER :: EddVisT5N10D9 = 5319 - INTEGER(IntKi), PARAMETER :: EddVisT5N11D1 = 5320 - INTEGER(IntKi), PARAMETER :: EddVisT5N11D2 = 5321 - INTEGER(IntKi), PARAMETER :: EddVisT5N11D3 = 5322 - INTEGER(IntKi), PARAMETER :: EddVisT5N11D4 = 5323 - INTEGER(IntKi), PARAMETER :: EddVisT5N11D5 = 5324 - INTEGER(IntKi), PARAMETER :: EddVisT5N11D6 = 5325 - INTEGER(IntKi), PARAMETER :: EddVisT5N11D7 = 5326 - INTEGER(IntKi), PARAMETER :: EddVisT5N11D8 = 5327 - INTEGER(IntKi), PARAMETER :: EddVisT5N11D9 = 5328 - INTEGER(IntKi), PARAMETER :: EddVisT5N12D1 = 5329 - INTEGER(IntKi), PARAMETER :: EddVisT5N12D2 = 5330 - INTEGER(IntKi), PARAMETER :: EddVisT5N12D3 = 5331 - INTEGER(IntKi), PARAMETER :: EddVisT5N12D4 = 5332 - INTEGER(IntKi), PARAMETER :: EddVisT5N12D5 = 5333 - INTEGER(IntKi), PARAMETER :: EddVisT5N12D6 = 5334 - INTEGER(IntKi), PARAMETER :: EddVisT5N12D7 = 5335 - INTEGER(IntKi), PARAMETER :: EddVisT5N12D8 = 5336 - INTEGER(IntKi), PARAMETER :: EddVisT5N12D9 = 5337 - INTEGER(IntKi), PARAMETER :: EddVisT5N13D1 = 5338 - INTEGER(IntKi), PARAMETER :: EddVisT5N13D2 = 5339 - INTEGER(IntKi), PARAMETER :: EddVisT5N13D3 = 5340 - INTEGER(IntKi), PARAMETER :: EddVisT5N13D4 = 5341 - INTEGER(IntKi), PARAMETER :: EddVisT5N13D5 = 5342 - INTEGER(IntKi), PARAMETER :: EddVisT5N13D6 = 5343 - INTEGER(IntKi), PARAMETER :: EddVisT5N13D7 = 5344 - INTEGER(IntKi), PARAMETER :: EddVisT5N13D8 = 5345 - INTEGER(IntKi), PARAMETER :: EddVisT5N13D9 = 5346 - INTEGER(IntKi), PARAMETER :: EddVisT5N14D1 = 5347 - INTEGER(IntKi), PARAMETER :: EddVisT5N14D2 = 5348 - INTEGER(IntKi), PARAMETER :: EddVisT5N14D3 = 5349 - INTEGER(IntKi), PARAMETER :: EddVisT5N14D4 = 5350 - INTEGER(IntKi), PARAMETER :: EddVisT5N14D5 = 5351 - INTEGER(IntKi), PARAMETER :: EddVisT5N14D6 = 5352 - INTEGER(IntKi), PARAMETER :: EddVisT5N14D7 = 5353 - INTEGER(IntKi), PARAMETER :: EddVisT5N14D8 = 5354 - INTEGER(IntKi), PARAMETER :: EddVisT5N14D9 = 5355 - INTEGER(IntKi), PARAMETER :: EddVisT5N15D1 = 5356 - INTEGER(IntKi), PARAMETER :: EddVisT5N15D2 = 5357 - INTEGER(IntKi), PARAMETER :: EddVisT5N15D3 = 5358 - INTEGER(IntKi), PARAMETER :: EddVisT5N15D4 = 5359 - INTEGER(IntKi), PARAMETER :: EddVisT5N15D5 = 5360 - INTEGER(IntKi), PARAMETER :: EddVisT5N15D6 = 5361 - INTEGER(IntKi), PARAMETER :: EddVisT5N15D7 = 5362 - INTEGER(IntKi), PARAMETER :: EddVisT5N15D8 = 5363 - INTEGER(IntKi), PARAMETER :: EddVisT5N15D9 = 5364 - INTEGER(IntKi), PARAMETER :: EddVisT5N16D1 = 5365 - INTEGER(IntKi), PARAMETER :: EddVisT5N16D2 = 5366 - INTEGER(IntKi), PARAMETER :: EddVisT5N16D3 = 5367 - INTEGER(IntKi), PARAMETER :: EddVisT5N16D4 = 5368 - INTEGER(IntKi), PARAMETER :: EddVisT5N16D5 = 5369 - INTEGER(IntKi), PARAMETER :: EddVisT5N16D6 = 5370 - INTEGER(IntKi), PARAMETER :: EddVisT5N16D7 = 5371 - INTEGER(IntKi), PARAMETER :: EddVisT5N16D8 = 5372 - INTEGER(IntKi), PARAMETER :: EddVisT5N16D9 = 5373 - INTEGER(IntKi), PARAMETER :: EddVisT5N17D1 = 5374 - INTEGER(IntKi), PARAMETER :: EddVisT5N17D2 = 5375 - INTEGER(IntKi), PARAMETER :: EddVisT5N17D3 = 5376 - INTEGER(IntKi), PARAMETER :: EddVisT5N17D4 = 5377 - INTEGER(IntKi), PARAMETER :: EddVisT5N17D5 = 5378 - INTEGER(IntKi), PARAMETER :: EddVisT5N17D6 = 5379 - INTEGER(IntKi), PARAMETER :: EddVisT5N17D7 = 5380 - INTEGER(IntKi), PARAMETER :: EddVisT5N17D8 = 5381 - INTEGER(IntKi), PARAMETER :: EddVisT5N17D9 = 5382 - INTEGER(IntKi), PARAMETER :: EddVisT5N18D1 = 5383 - INTEGER(IntKi), PARAMETER :: EddVisT5N18D2 = 5384 - INTEGER(IntKi), PARAMETER :: EddVisT5N18D3 = 5385 - INTEGER(IntKi), PARAMETER :: EddVisT5N18D4 = 5386 - INTEGER(IntKi), PARAMETER :: EddVisT5N18D5 = 5387 - INTEGER(IntKi), PARAMETER :: EddVisT5N18D6 = 5388 - INTEGER(IntKi), PARAMETER :: EddVisT5N18D7 = 5389 - INTEGER(IntKi), PARAMETER :: EddVisT5N18D8 = 5390 - INTEGER(IntKi), PARAMETER :: EddVisT5N18D9 = 5391 - INTEGER(IntKi), PARAMETER :: EddVisT5N19D1 = 5392 - INTEGER(IntKi), PARAMETER :: EddVisT5N19D2 = 5393 - INTEGER(IntKi), PARAMETER :: EddVisT5N19D3 = 5394 - INTEGER(IntKi), PARAMETER :: EddVisT5N19D4 = 5395 - INTEGER(IntKi), PARAMETER :: EddVisT5N19D5 = 5396 - INTEGER(IntKi), PARAMETER :: EddVisT5N19D6 = 5397 - INTEGER(IntKi), PARAMETER :: EddVisT5N19D7 = 5398 - INTEGER(IntKi), PARAMETER :: EddVisT5N19D8 = 5399 - INTEGER(IntKi), PARAMETER :: EddVisT5N19D9 = 5400 - INTEGER(IntKi), PARAMETER :: EddVisT5N20D1 = 5401 - INTEGER(IntKi), PARAMETER :: EddVisT5N20D2 = 5402 - INTEGER(IntKi), PARAMETER :: EddVisT5N20D3 = 5403 - INTEGER(IntKi), PARAMETER :: EddVisT5N20D4 = 5404 - INTEGER(IntKi), PARAMETER :: EddVisT5N20D5 = 5405 - INTEGER(IntKi), PARAMETER :: EddVisT5N20D6 = 5406 - INTEGER(IntKi), PARAMETER :: EddVisT5N20D7 = 5407 - INTEGER(IntKi), PARAMETER :: EddVisT5N20D8 = 5408 - INTEGER(IntKi), PARAMETER :: EddVisT5N20D9 = 5409 - INTEGER(IntKi), PARAMETER :: EddVisT6N01D1 = 5410 - INTEGER(IntKi), PARAMETER :: EddVisT6N01D2 = 5411 - INTEGER(IntKi), PARAMETER :: EddVisT6N01D3 = 5412 - INTEGER(IntKi), PARAMETER :: EddVisT6N01D4 = 5413 - INTEGER(IntKi), PARAMETER :: EddVisT6N01D5 = 5414 - INTEGER(IntKi), PARAMETER :: EddVisT6N01D6 = 5415 - INTEGER(IntKi), PARAMETER :: EddVisT6N01D7 = 5416 - INTEGER(IntKi), PARAMETER :: EddVisT6N01D8 = 5417 - INTEGER(IntKi), PARAMETER :: EddVisT6N01D9 = 5418 - INTEGER(IntKi), PARAMETER :: EddVisT6N02D1 = 5419 - INTEGER(IntKi), PARAMETER :: EddVisT6N02D2 = 5420 - INTEGER(IntKi), PARAMETER :: EddVisT6N02D3 = 5421 - INTEGER(IntKi), PARAMETER :: EddVisT6N02D4 = 5422 - INTEGER(IntKi), PARAMETER :: EddVisT6N02D5 = 5423 - INTEGER(IntKi), PARAMETER :: EddVisT6N02D6 = 5424 - INTEGER(IntKi), PARAMETER :: EddVisT6N02D7 = 5425 - INTEGER(IntKi), PARAMETER :: EddVisT6N02D8 = 5426 - INTEGER(IntKi), PARAMETER :: EddVisT6N02D9 = 5427 - INTEGER(IntKi), PARAMETER :: EddVisT6N03D1 = 5428 - INTEGER(IntKi), PARAMETER :: EddVisT6N03D2 = 5429 - INTEGER(IntKi), PARAMETER :: EddVisT6N03D3 = 5430 - INTEGER(IntKi), PARAMETER :: EddVisT6N03D4 = 5431 - INTEGER(IntKi), PARAMETER :: EddVisT6N03D5 = 5432 - INTEGER(IntKi), PARAMETER :: EddVisT6N03D6 = 5433 - INTEGER(IntKi), PARAMETER :: EddVisT6N03D7 = 5434 - INTEGER(IntKi), PARAMETER :: EddVisT6N03D8 = 5435 - INTEGER(IntKi), PARAMETER :: EddVisT6N03D9 = 5436 - INTEGER(IntKi), PARAMETER :: EddVisT6N04D1 = 5437 - INTEGER(IntKi), PARAMETER :: EddVisT6N04D2 = 5438 - INTEGER(IntKi), PARAMETER :: EddVisT6N04D3 = 5439 - INTEGER(IntKi), PARAMETER :: EddVisT6N04D4 = 5440 - INTEGER(IntKi), PARAMETER :: EddVisT6N04D5 = 5441 - INTEGER(IntKi), PARAMETER :: EddVisT6N04D6 = 5442 - INTEGER(IntKi), PARAMETER :: EddVisT6N04D7 = 5443 - INTEGER(IntKi), PARAMETER :: EddVisT6N04D8 = 5444 - INTEGER(IntKi), PARAMETER :: EddVisT6N04D9 = 5445 - INTEGER(IntKi), PARAMETER :: EddVisT6N05D1 = 5446 - INTEGER(IntKi), PARAMETER :: EddVisT6N05D2 = 5447 - INTEGER(IntKi), PARAMETER :: EddVisT6N05D3 = 5448 - INTEGER(IntKi), PARAMETER :: EddVisT6N05D4 = 5449 - INTEGER(IntKi), PARAMETER :: EddVisT6N05D5 = 5450 - INTEGER(IntKi), PARAMETER :: EddVisT6N05D6 = 5451 - INTEGER(IntKi), PARAMETER :: EddVisT6N05D7 = 5452 - INTEGER(IntKi), PARAMETER :: EddVisT6N05D8 = 5453 - INTEGER(IntKi), PARAMETER :: EddVisT6N05D9 = 5454 - INTEGER(IntKi), PARAMETER :: EddVisT6N06D1 = 5455 - INTEGER(IntKi), PARAMETER :: EddVisT6N06D2 = 5456 - INTEGER(IntKi), PARAMETER :: EddVisT6N06D3 = 5457 - INTEGER(IntKi), PARAMETER :: EddVisT6N06D4 = 5458 - INTEGER(IntKi), PARAMETER :: EddVisT6N06D5 = 5459 - INTEGER(IntKi), PARAMETER :: EddVisT6N06D6 = 5460 - INTEGER(IntKi), PARAMETER :: EddVisT6N06D7 = 5461 - INTEGER(IntKi), PARAMETER :: EddVisT6N06D8 = 5462 - INTEGER(IntKi), PARAMETER :: EddVisT6N06D9 = 5463 - INTEGER(IntKi), PARAMETER :: EddVisT6N07D1 = 5464 - INTEGER(IntKi), PARAMETER :: EddVisT6N07D2 = 5465 - INTEGER(IntKi), PARAMETER :: EddVisT6N07D3 = 5466 - INTEGER(IntKi), PARAMETER :: EddVisT6N07D4 = 5467 - INTEGER(IntKi), PARAMETER :: EddVisT6N07D5 = 5468 - INTEGER(IntKi), PARAMETER :: EddVisT6N07D6 = 5469 - INTEGER(IntKi), PARAMETER :: EddVisT6N07D7 = 5470 - INTEGER(IntKi), PARAMETER :: EddVisT6N07D8 = 5471 - INTEGER(IntKi), PARAMETER :: EddVisT6N07D9 = 5472 - INTEGER(IntKi), PARAMETER :: EddVisT6N08D1 = 5473 - INTEGER(IntKi), PARAMETER :: EddVisT6N08D2 = 5474 - INTEGER(IntKi), PARAMETER :: EddVisT6N08D3 = 5475 - INTEGER(IntKi), PARAMETER :: EddVisT6N08D4 = 5476 - INTEGER(IntKi), PARAMETER :: EddVisT6N08D5 = 5477 - INTEGER(IntKi), PARAMETER :: EddVisT6N08D6 = 5478 - INTEGER(IntKi), PARAMETER :: EddVisT6N08D7 = 5479 - INTEGER(IntKi), PARAMETER :: EddVisT6N08D8 = 5480 - INTEGER(IntKi), PARAMETER :: EddVisT6N08D9 = 5481 - INTEGER(IntKi), PARAMETER :: EddVisT6N09D1 = 5482 - INTEGER(IntKi), PARAMETER :: EddVisT6N09D2 = 5483 - INTEGER(IntKi), PARAMETER :: EddVisT6N09D3 = 5484 - INTEGER(IntKi), PARAMETER :: EddVisT6N09D4 = 5485 - INTEGER(IntKi), PARAMETER :: EddVisT6N09D5 = 5486 - INTEGER(IntKi), PARAMETER :: EddVisT6N09D6 = 5487 - INTEGER(IntKi), PARAMETER :: EddVisT6N09D7 = 5488 - INTEGER(IntKi), PARAMETER :: EddVisT6N09D8 = 5489 - INTEGER(IntKi), PARAMETER :: EddVisT6N09D9 = 5490 - INTEGER(IntKi), PARAMETER :: EddVisT6N10D1 = 5491 - INTEGER(IntKi), PARAMETER :: EddVisT6N10D2 = 5492 - INTEGER(IntKi), PARAMETER :: EddVisT6N10D3 = 5493 - INTEGER(IntKi), PARAMETER :: EddVisT6N10D4 = 5494 - INTEGER(IntKi), PARAMETER :: EddVisT6N10D5 = 5495 - INTEGER(IntKi), PARAMETER :: EddVisT6N10D6 = 5496 - INTEGER(IntKi), PARAMETER :: EddVisT6N10D7 = 5497 - INTEGER(IntKi), PARAMETER :: EddVisT6N10D8 = 5498 - INTEGER(IntKi), PARAMETER :: EddVisT6N10D9 = 5499 - INTEGER(IntKi), PARAMETER :: EddVisT6N11D1 = 5500 - INTEGER(IntKi), PARAMETER :: EddVisT6N11D2 = 5501 - INTEGER(IntKi), PARAMETER :: EddVisT6N11D3 = 5502 - INTEGER(IntKi), PARAMETER :: EddVisT6N11D4 = 5503 - INTEGER(IntKi), PARAMETER :: EddVisT6N11D5 = 5504 - INTEGER(IntKi), PARAMETER :: EddVisT6N11D6 = 5505 - INTEGER(IntKi), PARAMETER :: EddVisT6N11D7 = 5506 - INTEGER(IntKi), PARAMETER :: EddVisT6N11D8 = 5507 - INTEGER(IntKi), PARAMETER :: EddVisT6N11D9 = 5508 - INTEGER(IntKi), PARAMETER :: EddVisT6N12D1 = 5509 - INTEGER(IntKi), PARAMETER :: EddVisT6N12D2 = 5510 - INTEGER(IntKi), PARAMETER :: EddVisT6N12D3 = 5511 - INTEGER(IntKi), PARAMETER :: EddVisT6N12D4 = 5512 - INTEGER(IntKi), PARAMETER :: EddVisT6N12D5 = 5513 - INTEGER(IntKi), PARAMETER :: EddVisT6N12D6 = 5514 - INTEGER(IntKi), PARAMETER :: EddVisT6N12D7 = 5515 - INTEGER(IntKi), PARAMETER :: EddVisT6N12D8 = 5516 - INTEGER(IntKi), PARAMETER :: EddVisT6N12D9 = 5517 - INTEGER(IntKi), PARAMETER :: EddVisT6N13D1 = 5518 - INTEGER(IntKi), PARAMETER :: EddVisT6N13D2 = 5519 - INTEGER(IntKi), PARAMETER :: EddVisT6N13D3 = 5520 - INTEGER(IntKi), PARAMETER :: EddVisT6N13D4 = 5521 - INTEGER(IntKi), PARAMETER :: EddVisT6N13D5 = 5522 - INTEGER(IntKi), PARAMETER :: EddVisT6N13D6 = 5523 - INTEGER(IntKi), PARAMETER :: EddVisT6N13D7 = 5524 - INTEGER(IntKi), PARAMETER :: EddVisT6N13D8 = 5525 - INTEGER(IntKi), PARAMETER :: EddVisT6N13D9 = 5526 - INTEGER(IntKi), PARAMETER :: EddVisT6N14D1 = 5527 - INTEGER(IntKi), PARAMETER :: EddVisT6N14D2 = 5528 - INTEGER(IntKi), PARAMETER :: EddVisT6N14D3 = 5529 - INTEGER(IntKi), PARAMETER :: EddVisT6N14D4 = 5530 - INTEGER(IntKi), PARAMETER :: EddVisT6N14D5 = 5531 - INTEGER(IntKi), PARAMETER :: EddVisT6N14D6 = 5532 - INTEGER(IntKi), PARAMETER :: EddVisT6N14D7 = 5533 - INTEGER(IntKi), PARAMETER :: EddVisT6N14D8 = 5534 - INTEGER(IntKi), PARAMETER :: EddVisT6N14D9 = 5535 - INTEGER(IntKi), PARAMETER :: EddVisT6N15D1 = 5536 - INTEGER(IntKi), PARAMETER :: EddVisT6N15D2 = 5537 - INTEGER(IntKi), PARAMETER :: EddVisT6N15D3 = 5538 - INTEGER(IntKi), PARAMETER :: EddVisT6N15D4 = 5539 - INTEGER(IntKi), PARAMETER :: EddVisT6N15D5 = 5540 - INTEGER(IntKi), PARAMETER :: EddVisT6N15D6 = 5541 - INTEGER(IntKi), PARAMETER :: EddVisT6N15D7 = 5542 - INTEGER(IntKi), PARAMETER :: EddVisT6N15D8 = 5543 - INTEGER(IntKi), PARAMETER :: EddVisT6N15D9 = 5544 - INTEGER(IntKi), PARAMETER :: EddVisT6N16D1 = 5545 - INTEGER(IntKi), PARAMETER :: EddVisT6N16D2 = 5546 - INTEGER(IntKi), PARAMETER :: EddVisT6N16D3 = 5547 - INTEGER(IntKi), PARAMETER :: EddVisT6N16D4 = 5548 - INTEGER(IntKi), PARAMETER :: EddVisT6N16D5 = 5549 - INTEGER(IntKi), PARAMETER :: EddVisT6N16D6 = 5550 - INTEGER(IntKi), PARAMETER :: EddVisT6N16D7 = 5551 - INTEGER(IntKi), PARAMETER :: EddVisT6N16D8 = 5552 - INTEGER(IntKi), PARAMETER :: EddVisT6N16D9 = 5553 - INTEGER(IntKi), PARAMETER :: EddVisT6N17D1 = 5554 - INTEGER(IntKi), PARAMETER :: EddVisT6N17D2 = 5555 - INTEGER(IntKi), PARAMETER :: EddVisT6N17D3 = 5556 - INTEGER(IntKi), PARAMETER :: EddVisT6N17D4 = 5557 - INTEGER(IntKi), PARAMETER :: EddVisT6N17D5 = 5558 - INTEGER(IntKi), PARAMETER :: EddVisT6N17D6 = 5559 - INTEGER(IntKi), PARAMETER :: EddVisT6N17D7 = 5560 - INTEGER(IntKi), PARAMETER :: EddVisT6N17D8 = 5561 - INTEGER(IntKi), PARAMETER :: EddVisT6N17D9 = 5562 - INTEGER(IntKi), PARAMETER :: EddVisT6N18D1 = 5563 - INTEGER(IntKi), PARAMETER :: EddVisT6N18D2 = 5564 - INTEGER(IntKi), PARAMETER :: EddVisT6N18D3 = 5565 - INTEGER(IntKi), PARAMETER :: EddVisT6N18D4 = 5566 - INTEGER(IntKi), PARAMETER :: EddVisT6N18D5 = 5567 - INTEGER(IntKi), PARAMETER :: EddVisT6N18D6 = 5568 - INTEGER(IntKi), PARAMETER :: EddVisT6N18D7 = 5569 - INTEGER(IntKi), PARAMETER :: EddVisT6N18D8 = 5570 - INTEGER(IntKi), PARAMETER :: EddVisT6N18D9 = 5571 - INTEGER(IntKi), PARAMETER :: EddVisT6N19D1 = 5572 - INTEGER(IntKi), PARAMETER :: EddVisT6N19D2 = 5573 - INTEGER(IntKi), PARAMETER :: EddVisT6N19D3 = 5574 - INTEGER(IntKi), PARAMETER :: EddVisT6N19D4 = 5575 - INTEGER(IntKi), PARAMETER :: EddVisT6N19D5 = 5576 - INTEGER(IntKi), PARAMETER :: EddVisT6N19D6 = 5577 - INTEGER(IntKi), PARAMETER :: EddVisT6N19D7 = 5578 - INTEGER(IntKi), PARAMETER :: EddVisT6N19D8 = 5579 - INTEGER(IntKi), PARAMETER :: EddVisT6N19D9 = 5580 - INTEGER(IntKi), PARAMETER :: EddVisT6N20D1 = 5581 - INTEGER(IntKi), PARAMETER :: EddVisT6N20D2 = 5582 - INTEGER(IntKi), PARAMETER :: EddVisT6N20D3 = 5583 - INTEGER(IntKi), PARAMETER :: EddVisT6N20D4 = 5584 - INTEGER(IntKi), PARAMETER :: EddVisT6N20D5 = 5585 - INTEGER(IntKi), PARAMETER :: EddVisT6N20D6 = 5586 - INTEGER(IntKi), PARAMETER :: EddVisT6N20D7 = 5587 - INTEGER(IntKi), PARAMETER :: EddVisT6N20D8 = 5588 - INTEGER(IntKi), PARAMETER :: EddVisT6N20D9 = 5589 - INTEGER(IntKi), PARAMETER :: EddVisT7N01D1 = 5590 - INTEGER(IntKi), PARAMETER :: EddVisT7N01D2 = 5591 - INTEGER(IntKi), PARAMETER :: EddVisT7N01D3 = 5592 - INTEGER(IntKi), PARAMETER :: EddVisT7N01D4 = 5593 - INTEGER(IntKi), PARAMETER :: EddVisT7N01D5 = 5594 - INTEGER(IntKi), PARAMETER :: EddVisT7N01D6 = 5595 - INTEGER(IntKi), PARAMETER :: EddVisT7N01D7 = 5596 - INTEGER(IntKi), PARAMETER :: EddVisT7N01D8 = 5597 - INTEGER(IntKi), PARAMETER :: EddVisT7N01D9 = 5598 - INTEGER(IntKi), PARAMETER :: EddVisT7N02D1 = 5599 - INTEGER(IntKi), PARAMETER :: EddVisT7N02D2 = 5600 - INTEGER(IntKi), PARAMETER :: EddVisT7N02D3 = 5601 - INTEGER(IntKi), PARAMETER :: EddVisT7N02D4 = 5602 - INTEGER(IntKi), PARAMETER :: EddVisT7N02D5 = 5603 - INTEGER(IntKi), PARAMETER :: EddVisT7N02D6 = 5604 - INTEGER(IntKi), PARAMETER :: EddVisT7N02D7 = 5605 - INTEGER(IntKi), PARAMETER :: EddVisT7N02D8 = 5606 - INTEGER(IntKi), PARAMETER :: EddVisT7N02D9 = 5607 - INTEGER(IntKi), PARAMETER :: EddVisT7N03D1 = 5608 - INTEGER(IntKi), PARAMETER :: EddVisT7N03D2 = 5609 - INTEGER(IntKi), PARAMETER :: EddVisT7N03D3 = 5610 - INTEGER(IntKi), PARAMETER :: EddVisT7N03D4 = 5611 - INTEGER(IntKi), PARAMETER :: EddVisT7N03D5 = 5612 - INTEGER(IntKi), PARAMETER :: EddVisT7N03D6 = 5613 - INTEGER(IntKi), PARAMETER :: EddVisT7N03D7 = 5614 - INTEGER(IntKi), PARAMETER :: EddVisT7N03D8 = 5615 - INTEGER(IntKi), PARAMETER :: EddVisT7N03D9 = 5616 - INTEGER(IntKi), PARAMETER :: EddVisT7N04D1 = 5617 - INTEGER(IntKi), PARAMETER :: EddVisT7N04D2 = 5618 - INTEGER(IntKi), PARAMETER :: EddVisT7N04D3 = 5619 - INTEGER(IntKi), PARAMETER :: EddVisT7N04D4 = 5620 - INTEGER(IntKi), PARAMETER :: EddVisT7N04D5 = 5621 - INTEGER(IntKi), PARAMETER :: EddVisT7N04D6 = 5622 - INTEGER(IntKi), PARAMETER :: EddVisT7N04D7 = 5623 - INTEGER(IntKi), PARAMETER :: EddVisT7N04D8 = 5624 - INTEGER(IntKi), PARAMETER :: EddVisT7N04D9 = 5625 - INTEGER(IntKi), PARAMETER :: EddVisT7N05D1 = 5626 - INTEGER(IntKi), PARAMETER :: EddVisT7N05D2 = 5627 - INTEGER(IntKi), PARAMETER :: EddVisT7N05D3 = 5628 - INTEGER(IntKi), PARAMETER :: EddVisT7N05D4 = 5629 - INTEGER(IntKi), PARAMETER :: EddVisT7N05D5 = 5630 - INTEGER(IntKi), PARAMETER :: EddVisT7N05D6 = 5631 - INTEGER(IntKi), PARAMETER :: EddVisT7N05D7 = 5632 - INTEGER(IntKi), PARAMETER :: EddVisT7N05D8 = 5633 - INTEGER(IntKi), PARAMETER :: EddVisT7N05D9 = 5634 - INTEGER(IntKi), PARAMETER :: EddVisT7N06D1 = 5635 - INTEGER(IntKi), PARAMETER :: EddVisT7N06D2 = 5636 - INTEGER(IntKi), PARAMETER :: EddVisT7N06D3 = 5637 - INTEGER(IntKi), PARAMETER :: EddVisT7N06D4 = 5638 - INTEGER(IntKi), PARAMETER :: EddVisT7N06D5 = 5639 - INTEGER(IntKi), PARAMETER :: EddVisT7N06D6 = 5640 - INTEGER(IntKi), PARAMETER :: EddVisT7N06D7 = 5641 - INTEGER(IntKi), PARAMETER :: EddVisT7N06D8 = 5642 - INTEGER(IntKi), PARAMETER :: EddVisT7N06D9 = 5643 - INTEGER(IntKi), PARAMETER :: EddVisT7N07D1 = 5644 - INTEGER(IntKi), PARAMETER :: EddVisT7N07D2 = 5645 - INTEGER(IntKi), PARAMETER :: EddVisT7N07D3 = 5646 - INTEGER(IntKi), PARAMETER :: EddVisT7N07D4 = 5647 - INTEGER(IntKi), PARAMETER :: EddVisT7N07D5 = 5648 - INTEGER(IntKi), PARAMETER :: EddVisT7N07D6 = 5649 - INTEGER(IntKi), PARAMETER :: EddVisT7N07D7 = 5650 - INTEGER(IntKi), PARAMETER :: EddVisT7N07D8 = 5651 - INTEGER(IntKi), PARAMETER :: EddVisT7N07D9 = 5652 - INTEGER(IntKi), PARAMETER :: EddVisT7N08D1 = 5653 - INTEGER(IntKi), PARAMETER :: EddVisT7N08D2 = 5654 - INTEGER(IntKi), PARAMETER :: EddVisT7N08D3 = 5655 - INTEGER(IntKi), PARAMETER :: EddVisT7N08D4 = 5656 - INTEGER(IntKi), PARAMETER :: EddVisT7N08D5 = 5657 - INTEGER(IntKi), PARAMETER :: EddVisT7N08D6 = 5658 - INTEGER(IntKi), PARAMETER :: EddVisT7N08D7 = 5659 - INTEGER(IntKi), PARAMETER :: EddVisT7N08D8 = 5660 - INTEGER(IntKi), PARAMETER :: EddVisT7N08D9 = 5661 - INTEGER(IntKi), PARAMETER :: EddVisT7N09D1 = 5662 - INTEGER(IntKi), PARAMETER :: EddVisT7N09D2 = 5663 - INTEGER(IntKi), PARAMETER :: EddVisT7N09D3 = 5664 - INTEGER(IntKi), PARAMETER :: EddVisT7N09D4 = 5665 - INTEGER(IntKi), PARAMETER :: EddVisT7N09D5 = 5666 - INTEGER(IntKi), PARAMETER :: EddVisT7N09D6 = 5667 - INTEGER(IntKi), PARAMETER :: EddVisT7N09D7 = 5668 - INTEGER(IntKi), PARAMETER :: EddVisT7N09D8 = 5669 - INTEGER(IntKi), PARAMETER :: EddVisT7N09D9 = 5670 - INTEGER(IntKi), PARAMETER :: EddVisT7N10D1 = 5671 - INTEGER(IntKi), PARAMETER :: EddVisT7N10D2 = 5672 - INTEGER(IntKi), PARAMETER :: EddVisT7N10D3 = 5673 - INTEGER(IntKi), PARAMETER :: EddVisT7N10D4 = 5674 - INTEGER(IntKi), PARAMETER :: EddVisT7N10D5 = 5675 - INTEGER(IntKi), PARAMETER :: EddVisT7N10D6 = 5676 - INTEGER(IntKi), PARAMETER :: EddVisT7N10D7 = 5677 - INTEGER(IntKi), PARAMETER :: EddVisT7N10D8 = 5678 - INTEGER(IntKi), PARAMETER :: EddVisT7N10D9 = 5679 - INTEGER(IntKi), PARAMETER :: EddVisT7N11D1 = 5680 - INTEGER(IntKi), PARAMETER :: EddVisT7N11D2 = 5681 - INTEGER(IntKi), PARAMETER :: EddVisT7N11D3 = 5682 - INTEGER(IntKi), PARAMETER :: EddVisT7N11D4 = 5683 - INTEGER(IntKi), PARAMETER :: EddVisT7N11D5 = 5684 - INTEGER(IntKi), PARAMETER :: EddVisT7N11D6 = 5685 - INTEGER(IntKi), PARAMETER :: EddVisT7N11D7 = 5686 - INTEGER(IntKi), PARAMETER :: EddVisT7N11D8 = 5687 - INTEGER(IntKi), PARAMETER :: EddVisT7N11D9 = 5688 - INTEGER(IntKi), PARAMETER :: EddVisT7N12D1 = 5689 - INTEGER(IntKi), PARAMETER :: EddVisT7N12D2 = 5690 - INTEGER(IntKi), PARAMETER :: EddVisT7N12D3 = 5691 - INTEGER(IntKi), PARAMETER :: EddVisT7N12D4 = 5692 - INTEGER(IntKi), PARAMETER :: EddVisT7N12D5 = 5693 - INTEGER(IntKi), PARAMETER :: EddVisT7N12D6 = 5694 - INTEGER(IntKi), PARAMETER :: EddVisT7N12D7 = 5695 - INTEGER(IntKi), PARAMETER :: EddVisT7N12D8 = 5696 - INTEGER(IntKi), PARAMETER :: EddVisT7N12D9 = 5697 - INTEGER(IntKi), PARAMETER :: EddVisT7N13D1 = 5698 - INTEGER(IntKi), PARAMETER :: EddVisT7N13D2 = 5699 - INTEGER(IntKi), PARAMETER :: EddVisT7N13D3 = 5700 - INTEGER(IntKi), PARAMETER :: EddVisT7N13D4 = 5701 - INTEGER(IntKi), PARAMETER :: EddVisT7N13D5 = 5702 - INTEGER(IntKi), PARAMETER :: EddVisT7N13D6 = 5703 - INTEGER(IntKi), PARAMETER :: EddVisT7N13D7 = 5704 - INTEGER(IntKi), PARAMETER :: EddVisT7N13D8 = 5705 - INTEGER(IntKi), PARAMETER :: EddVisT7N13D9 = 5706 - INTEGER(IntKi), PARAMETER :: EddVisT7N14D1 = 5707 - INTEGER(IntKi), PARAMETER :: EddVisT7N14D2 = 5708 - INTEGER(IntKi), PARAMETER :: EddVisT7N14D3 = 5709 - INTEGER(IntKi), PARAMETER :: EddVisT7N14D4 = 5710 - INTEGER(IntKi), PARAMETER :: EddVisT7N14D5 = 5711 - INTEGER(IntKi), PARAMETER :: EddVisT7N14D6 = 5712 - INTEGER(IntKi), PARAMETER :: EddVisT7N14D7 = 5713 - INTEGER(IntKi), PARAMETER :: EddVisT7N14D8 = 5714 - INTEGER(IntKi), PARAMETER :: EddVisT7N14D9 = 5715 - INTEGER(IntKi), PARAMETER :: EddVisT7N15D1 = 5716 - INTEGER(IntKi), PARAMETER :: EddVisT7N15D2 = 5717 - INTEGER(IntKi), PARAMETER :: EddVisT7N15D3 = 5718 - INTEGER(IntKi), PARAMETER :: EddVisT7N15D4 = 5719 - INTEGER(IntKi), PARAMETER :: EddVisT7N15D5 = 5720 - INTEGER(IntKi), PARAMETER :: EddVisT7N15D6 = 5721 - INTEGER(IntKi), PARAMETER :: EddVisT7N15D7 = 5722 - INTEGER(IntKi), PARAMETER :: EddVisT7N15D8 = 5723 - INTEGER(IntKi), PARAMETER :: EddVisT7N15D9 = 5724 - INTEGER(IntKi), PARAMETER :: EddVisT7N16D1 = 5725 - INTEGER(IntKi), PARAMETER :: EddVisT7N16D2 = 5726 - INTEGER(IntKi), PARAMETER :: EddVisT7N16D3 = 5727 - INTEGER(IntKi), PARAMETER :: EddVisT7N16D4 = 5728 - INTEGER(IntKi), PARAMETER :: EddVisT7N16D5 = 5729 - INTEGER(IntKi), PARAMETER :: EddVisT7N16D6 = 5730 - INTEGER(IntKi), PARAMETER :: EddVisT7N16D7 = 5731 - INTEGER(IntKi), PARAMETER :: EddVisT7N16D8 = 5732 - INTEGER(IntKi), PARAMETER :: EddVisT7N16D9 = 5733 - INTEGER(IntKi), PARAMETER :: EddVisT7N17D1 = 5734 - INTEGER(IntKi), PARAMETER :: EddVisT7N17D2 = 5735 - INTEGER(IntKi), PARAMETER :: EddVisT7N17D3 = 5736 - INTEGER(IntKi), PARAMETER :: EddVisT7N17D4 = 5737 - INTEGER(IntKi), PARAMETER :: EddVisT7N17D5 = 5738 - INTEGER(IntKi), PARAMETER :: EddVisT7N17D6 = 5739 - INTEGER(IntKi), PARAMETER :: EddVisT7N17D7 = 5740 - INTEGER(IntKi), PARAMETER :: EddVisT7N17D8 = 5741 - INTEGER(IntKi), PARAMETER :: EddVisT7N17D9 = 5742 - INTEGER(IntKi), PARAMETER :: EddVisT7N18D1 = 5743 - INTEGER(IntKi), PARAMETER :: EddVisT7N18D2 = 5744 - INTEGER(IntKi), PARAMETER :: EddVisT7N18D3 = 5745 - INTEGER(IntKi), PARAMETER :: EddVisT7N18D4 = 5746 - INTEGER(IntKi), PARAMETER :: EddVisT7N18D5 = 5747 - INTEGER(IntKi), PARAMETER :: EddVisT7N18D6 = 5748 - INTEGER(IntKi), PARAMETER :: EddVisT7N18D7 = 5749 - INTEGER(IntKi), PARAMETER :: EddVisT7N18D8 = 5750 - INTEGER(IntKi), PARAMETER :: EddVisT7N18D9 = 5751 - INTEGER(IntKi), PARAMETER :: EddVisT7N19D1 = 5752 - INTEGER(IntKi), PARAMETER :: EddVisT7N19D2 = 5753 - INTEGER(IntKi), PARAMETER :: EddVisT7N19D3 = 5754 - INTEGER(IntKi), PARAMETER :: EddVisT7N19D4 = 5755 - INTEGER(IntKi), PARAMETER :: EddVisT7N19D5 = 5756 - INTEGER(IntKi), PARAMETER :: EddVisT7N19D6 = 5757 - INTEGER(IntKi), PARAMETER :: EddVisT7N19D7 = 5758 - INTEGER(IntKi), PARAMETER :: EddVisT7N19D8 = 5759 - INTEGER(IntKi), PARAMETER :: EddVisT7N19D9 = 5760 - INTEGER(IntKi), PARAMETER :: EddVisT7N20D1 = 5761 - INTEGER(IntKi), PARAMETER :: EddVisT7N20D2 = 5762 - INTEGER(IntKi), PARAMETER :: EddVisT7N20D3 = 5763 - INTEGER(IntKi), PARAMETER :: EddVisT7N20D4 = 5764 - INTEGER(IntKi), PARAMETER :: EddVisT7N20D5 = 5765 - INTEGER(IntKi), PARAMETER :: EddVisT7N20D6 = 5766 - INTEGER(IntKi), PARAMETER :: EddVisT7N20D7 = 5767 - INTEGER(IntKi), PARAMETER :: EddVisT7N20D8 = 5768 - INTEGER(IntKi), PARAMETER :: EddVisT7N20D9 = 5769 - INTEGER(IntKi), PARAMETER :: EddVisT8N01D1 = 5770 - INTEGER(IntKi), PARAMETER :: EddVisT8N01D2 = 5771 - INTEGER(IntKi), PARAMETER :: EddVisT8N01D3 = 5772 - INTEGER(IntKi), PARAMETER :: EddVisT8N01D4 = 5773 - INTEGER(IntKi), PARAMETER :: EddVisT8N01D5 = 5774 - INTEGER(IntKi), PARAMETER :: EddVisT8N01D6 = 5775 - INTEGER(IntKi), PARAMETER :: EddVisT8N01D7 = 5776 - INTEGER(IntKi), PARAMETER :: EddVisT8N01D8 = 5777 - INTEGER(IntKi), PARAMETER :: EddVisT8N01D9 = 5778 - INTEGER(IntKi), PARAMETER :: EddVisT8N02D1 = 5779 - INTEGER(IntKi), PARAMETER :: EddVisT8N02D2 = 5780 - INTEGER(IntKi), PARAMETER :: EddVisT8N02D3 = 5781 - INTEGER(IntKi), PARAMETER :: EddVisT8N02D4 = 5782 - INTEGER(IntKi), PARAMETER :: EddVisT8N02D5 = 5783 - INTEGER(IntKi), PARAMETER :: EddVisT8N02D6 = 5784 - INTEGER(IntKi), PARAMETER :: EddVisT8N02D7 = 5785 - INTEGER(IntKi), PARAMETER :: EddVisT8N02D8 = 5786 - INTEGER(IntKi), PARAMETER :: EddVisT8N02D9 = 5787 - INTEGER(IntKi), PARAMETER :: EddVisT8N03D1 = 5788 - INTEGER(IntKi), PARAMETER :: EddVisT8N03D2 = 5789 - INTEGER(IntKi), PARAMETER :: EddVisT8N03D3 = 5790 - INTEGER(IntKi), PARAMETER :: EddVisT8N03D4 = 5791 - INTEGER(IntKi), PARAMETER :: EddVisT8N03D5 = 5792 - INTEGER(IntKi), PARAMETER :: EddVisT8N03D6 = 5793 - INTEGER(IntKi), PARAMETER :: EddVisT8N03D7 = 5794 - INTEGER(IntKi), PARAMETER :: EddVisT8N03D8 = 5795 - INTEGER(IntKi), PARAMETER :: EddVisT8N03D9 = 5796 - INTEGER(IntKi), PARAMETER :: EddVisT8N04D1 = 5797 - INTEGER(IntKi), PARAMETER :: EddVisT8N04D2 = 5798 - INTEGER(IntKi), PARAMETER :: EddVisT8N04D3 = 5799 - INTEGER(IntKi), PARAMETER :: EddVisT8N04D4 = 5800 - INTEGER(IntKi), PARAMETER :: EddVisT8N04D5 = 5801 - INTEGER(IntKi), PARAMETER :: EddVisT8N04D6 = 5802 - INTEGER(IntKi), PARAMETER :: EddVisT8N04D7 = 5803 - INTEGER(IntKi), PARAMETER :: EddVisT8N04D8 = 5804 - INTEGER(IntKi), PARAMETER :: EddVisT8N04D9 = 5805 - INTEGER(IntKi), PARAMETER :: EddVisT8N05D1 = 5806 - INTEGER(IntKi), PARAMETER :: EddVisT8N05D2 = 5807 - INTEGER(IntKi), PARAMETER :: EddVisT8N05D3 = 5808 - INTEGER(IntKi), PARAMETER :: EddVisT8N05D4 = 5809 - INTEGER(IntKi), PARAMETER :: EddVisT8N05D5 = 5810 - INTEGER(IntKi), PARAMETER :: EddVisT8N05D6 = 5811 - INTEGER(IntKi), PARAMETER :: EddVisT8N05D7 = 5812 - INTEGER(IntKi), PARAMETER :: EddVisT8N05D8 = 5813 - INTEGER(IntKi), PARAMETER :: EddVisT8N05D9 = 5814 - INTEGER(IntKi), PARAMETER :: EddVisT8N06D1 = 5815 - INTEGER(IntKi), PARAMETER :: EddVisT8N06D2 = 5816 - INTEGER(IntKi), PARAMETER :: EddVisT8N06D3 = 5817 - INTEGER(IntKi), PARAMETER :: EddVisT8N06D4 = 5818 - INTEGER(IntKi), PARAMETER :: EddVisT8N06D5 = 5819 - INTEGER(IntKi), PARAMETER :: EddVisT8N06D6 = 5820 - INTEGER(IntKi), PARAMETER :: EddVisT8N06D7 = 5821 - INTEGER(IntKi), PARAMETER :: EddVisT8N06D8 = 5822 - INTEGER(IntKi), PARAMETER :: EddVisT8N06D9 = 5823 - INTEGER(IntKi), PARAMETER :: EddVisT8N07D1 = 5824 - INTEGER(IntKi), PARAMETER :: EddVisT8N07D2 = 5825 - INTEGER(IntKi), PARAMETER :: EddVisT8N07D3 = 5826 - INTEGER(IntKi), PARAMETER :: EddVisT8N07D4 = 5827 - INTEGER(IntKi), PARAMETER :: EddVisT8N07D5 = 5828 - INTEGER(IntKi), PARAMETER :: EddVisT8N07D6 = 5829 - INTEGER(IntKi), PARAMETER :: EddVisT8N07D7 = 5830 - INTEGER(IntKi), PARAMETER :: EddVisT8N07D8 = 5831 - INTEGER(IntKi), PARAMETER :: EddVisT8N07D9 = 5832 - INTEGER(IntKi), PARAMETER :: EddVisT8N08D1 = 5833 - INTEGER(IntKi), PARAMETER :: EddVisT8N08D2 = 5834 - INTEGER(IntKi), PARAMETER :: EddVisT8N08D3 = 5835 - INTEGER(IntKi), PARAMETER :: EddVisT8N08D4 = 5836 - INTEGER(IntKi), PARAMETER :: EddVisT8N08D5 = 5837 - INTEGER(IntKi), PARAMETER :: EddVisT8N08D6 = 5838 - INTEGER(IntKi), PARAMETER :: EddVisT8N08D7 = 5839 - INTEGER(IntKi), PARAMETER :: EddVisT8N08D8 = 5840 - INTEGER(IntKi), PARAMETER :: EddVisT8N08D9 = 5841 - INTEGER(IntKi), PARAMETER :: EddVisT8N09D1 = 5842 - INTEGER(IntKi), PARAMETER :: EddVisT8N09D2 = 5843 - INTEGER(IntKi), PARAMETER :: EddVisT8N09D3 = 5844 - INTEGER(IntKi), PARAMETER :: EddVisT8N09D4 = 5845 - INTEGER(IntKi), PARAMETER :: EddVisT8N09D5 = 5846 - INTEGER(IntKi), PARAMETER :: EddVisT8N09D6 = 5847 - INTEGER(IntKi), PARAMETER :: EddVisT8N09D7 = 5848 - INTEGER(IntKi), PARAMETER :: EddVisT8N09D8 = 5849 - INTEGER(IntKi), PARAMETER :: EddVisT8N09D9 = 5850 - INTEGER(IntKi), PARAMETER :: EddVisT8N10D1 = 5851 - INTEGER(IntKi), PARAMETER :: EddVisT8N10D2 = 5852 - INTEGER(IntKi), PARAMETER :: EddVisT8N10D3 = 5853 - INTEGER(IntKi), PARAMETER :: EddVisT8N10D4 = 5854 - INTEGER(IntKi), PARAMETER :: EddVisT8N10D5 = 5855 - INTEGER(IntKi), PARAMETER :: EddVisT8N10D6 = 5856 - INTEGER(IntKi), PARAMETER :: EddVisT8N10D7 = 5857 - INTEGER(IntKi), PARAMETER :: EddVisT8N10D8 = 5858 - INTEGER(IntKi), PARAMETER :: EddVisT8N10D9 = 5859 - INTEGER(IntKi), PARAMETER :: EddVisT8N11D1 = 5860 - INTEGER(IntKi), PARAMETER :: EddVisT8N11D2 = 5861 - INTEGER(IntKi), PARAMETER :: EddVisT8N11D3 = 5862 - INTEGER(IntKi), PARAMETER :: EddVisT8N11D4 = 5863 - INTEGER(IntKi), PARAMETER :: EddVisT8N11D5 = 5864 - INTEGER(IntKi), PARAMETER :: EddVisT8N11D6 = 5865 - INTEGER(IntKi), PARAMETER :: EddVisT8N11D7 = 5866 - INTEGER(IntKi), PARAMETER :: EddVisT8N11D8 = 5867 - INTEGER(IntKi), PARAMETER :: EddVisT8N11D9 = 5868 - INTEGER(IntKi), PARAMETER :: EddVisT8N12D1 = 5869 - INTEGER(IntKi), PARAMETER :: EddVisT8N12D2 = 5870 - INTEGER(IntKi), PARAMETER :: EddVisT8N12D3 = 5871 - INTEGER(IntKi), PARAMETER :: EddVisT8N12D4 = 5872 - INTEGER(IntKi), PARAMETER :: EddVisT8N12D5 = 5873 - INTEGER(IntKi), PARAMETER :: EddVisT8N12D6 = 5874 - INTEGER(IntKi), PARAMETER :: EddVisT8N12D7 = 5875 - INTEGER(IntKi), PARAMETER :: EddVisT8N12D8 = 5876 - INTEGER(IntKi), PARAMETER :: EddVisT8N12D9 = 5877 - INTEGER(IntKi), PARAMETER :: EddVisT8N13D1 = 5878 - INTEGER(IntKi), PARAMETER :: EddVisT8N13D2 = 5879 - INTEGER(IntKi), PARAMETER :: EddVisT8N13D3 = 5880 - INTEGER(IntKi), PARAMETER :: EddVisT8N13D4 = 5881 - INTEGER(IntKi), PARAMETER :: EddVisT8N13D5 = 5882 - INTEGER(IntKi), PARAMETER :: EddVisT8N13D6 = 5883 - INTEGER(IntKi), PARAMETER :: EddVisT8N13D7 = 5884 - INTEGER(IntKi), PARAMETER :: EddVisT8N13D8 = 5885 - INTEGER(IntKi), PARAMETER :: EddVisT8N13D9 = 5886 - INTEGER(IntKi), PARAMETER :: EddVisT8N14D1 = 5887 - INTEGER(IntKi), PARAMETER :: EddVisT8N14D2 = 5888 - INTEGER(IntKi), PARAMETER :: EddVisT8N14D3 = 5889 - INTEGER(IntKi), PARAMETER :: EddVisT8N14D4 = 5890 - INTEGER(IntKi), PARAMETER :: EddVisT8N14D5 = 5891 - INTEGER(IntKi), PARAMETER :: EddVisT8N14D6 = 5892 - INTEGER(IntKi), PARAMETER :: EddVisT8N14D7 = 5893 - INTEGER(IntKi), PARAMETER :: EddVisT8N14D8 = 5894 - INTEGER(IntKi), PARAMETER :: EddVisT8N14D9 = 5895 - INTEGER(IntKi), PARAMETER :: EddVisT8N15D1 = 5896 - INTEGER(IntKi), PARAMETER :: EddVisT8N15D2 = 5897 - INTEGER(IntKi), PARAMETER :: EddVisT8N15D3 = 5898 - INTEGER(IntKi), PARAMETER :: EddVisT8N15D4 = 5899 - INTEGER(IntKi), PARAMETER :: EddVisT8N15D5 = 5900 - INTEGER(IntKi), PARAMETER :: EddVisT8N15D6 = 5901 - INTEGER(IntKi), PARAMETER :: EddVisT8N15D7 = 5902 - INTEGER(IntKi), PARAMETER :: EddVisT8N15D8 = 5903 - INTEGER(IntKi), PARAMETER :: EddVisT8N15D9 = 5904 - INTEGER(IntKi), PARAMETER :: EddVisT8N16D1 = 5905 - INTEGER(IntKi), PARAMETER :: EddVisT8N16D2 = 5906 - INTEGER(IntKi), PARAMETER :: EddVisT8N16D3 = 5907 - INTEGER(IntKi), PARAMETER :: EddVisT8N16D4 = 5908 - INTEGER(IntKi), PARAMETER :: EddVisT8N16D5 = 5909 - INTEGER(IntKi), PARAMETER :: EddVisT8N16D6 = 5910 - INTEGER(IntKi), PARAMETER :: EddVisT8N16D7 = 5911 - INTEGER(IntKi), PARAMETER :: EddVisT8N16D8 = 5912 - INTEGER(IntKi), PARAMETER :: EddVisT8N16D9 = 5913 - INTEGER(IntKi), PARAMETER :: EddVisT8N17D1 = 5914 - INTEGER(IntKi), PARAMETER :: EddVisT8N17D2 = 5915 - INTEGER(IntKi), PARAMETER :: EddVisT8N17D3 = 5916 - INTEGER(IntKi), PARAMETER :: EddVisT8N17D4 = 5917 - INTEGER(IntKi), PARAMETER :: EddVisT8N17D5 = 5918 - INTEGER(IntKi), PARAMETER :: EddVisT8N17D6 = 5919 - INTEGER(IntKi), PARAMETER :: EddVisT8N17D7 = 5920 - INTEGER(IntKi), PARAMETER :: EddVisT8N17D8 = 5921 - INTEGER(IntKi), PARAMETER :: EddVisT8N17D9 = 5922 - INTEGER(IntKi), PARAMETER :: EddVisT8N18D1 = 5923 - INTEGER(IntKi), PARAMETER :: EddVisT8N18D2 = 5924 - INTEGER(IntKi), PARAMETER :: EddVisT8N18D3 = 5925 - INTEGER(IntKi), PARAMETER :: EddVisT8N18D4 = 5926 - INTEGER(IntKi), PARAMETER :: EddVisT8N18D5 = 5927 - INTEGER(IntKi), PARAMETER :: EddVisT8N18D6 = 5928 - INTEGER(IntKi), PARAMETER :: EddVisT8N18D7 = 5929 - INTEGER(IntKi), PARAMETER :: EddVisT8N18D8 = 5930 - INTEGER(IntKi), PARAMETER :: EddVisT8N18D9 = 5931 - INTEGER(IntKi), PARAMETER :: EddVisT8N19D1 = 5932 - INTEGER(IntKi), PARAMETER :: EddVisT8N19D2 = 5933 - INTEGER(IntKi), PARAMETER :: EddVisT8N19D3 = 5934 - INTEGER(IntKi), PARAMETER :: EddVisT8N19D4 = 5935 - INTEGER(IntKi), PARAMETER :: EddVisT8N19D5 = 5936 - INTEGER(IntKi), PARAMETER :: EddVisT8N19D6 = 5937 - INTEGER(IntKi), PARAMETER :: EddVisT8N19D7 = 5938 - INTEGER(IntKi), PARAMETER :: EddVisT8N19D8 = 5939 - INTEGER(IntKi), PARAMETER :: EddVisT8N19D9 = 5940 - INTEGER(IntKi), PARAMETER :: EddVisT8N20D1 = 5941 - INTEGER(IntKi), PARAMETER :: EddVisT8N20D2 = 5942 - INTEGER(IntKi), PARAMETER :: EddVisT8N20D3 = 5943 - INTEGER(IntKi), PARAMETER :: EddVisT8N20D4 = 5944 - INTEGER(IntKi), PARAMETER :: EddVisT8N20D5 = 5945 - INTEGER(IntKi), PARAMETER :: EddVisT8N20D6 = 5946 - INTEGER(IntKi), PARAMETER :: EddVisT8N20D7 = 5947 - INTEGER(IntKi), PARAMETER :: EddVisT8N20D8 = 5948 - INTEGER(IntKi), PARAMETER :: EddVisT8N20D9 = 5949 - INTEGER(IntKi), PARAMETER :: EddVisT9N01D1 = 5950 - INTEGER(IntKi), PARAMETER :: EddVisT9N01D2 = 5951 - INTEGER(IntKi), PARAMETER :: EddVisT9N01D3 = 5952 - INTEGER(IntKi), PARAMETER :: EddVisT9N01D4 = 5953 - INTEGER(IntKi), PARAMETER :: EddVisT9N01D5 = 5954 - INTEGER(IntKi), PARAMETER :: EddVisT9N01D6 = 5955 - INTEGER(IntKi), PARAMETER :: EddVisT9N01D7 = 5956 - INTEGER(IntKi), PARAMETER :: EddVisT9N01D8 = 5957 - INTEGER(IntKi), PARAMETER :: EddVisT9N01D9 = 5958 - INTEGER(IntKi), PARAMETER :: EddVisT9N02D1 = 5959 - INTEGER(IntKi), PARAMETER :: EddVisT9N02D2 = 5960 - INTEGER(IntKi), PARAMETER :: EddVisT9N02D3 = 5961 - INTEGER(IntKi), PARAMETER :: EddVisT9N02D4 = 5962 - INTEGER(IntKi), PARAMETER :: EddVisT9N02D5 = 5963 - INTEGER(IntKi), PARAMETER :: EddVisT9N02D6 = 5964 - INTEGER(IntKi), PARAMETER :: EddVisT9N02D7 = 5965 - INTEGER(IntKi), PARAMETER :: EddVisT9N02D8 = 5966 - INTEGER(IntKi), PARAMETER :: EddVisT9N02D9 = 5967 - INTEGER(IntKi), PARAMETER :: EddVisT9N03D1 = 5968 - INTEGER(IntKi), PARAMETER :: EddVisT9N03D2 = 5969 - INTEGER(IntKi), PARAMETER :: EddVisT9N03D3 = 5970 - INTEGER(IntKi), PARAMETER :: EddVisT9N03D4 = 5971 - INTEGER(IntKi), PARAMETER :: EddVisT9N03D5 = 5972 - INTEGER(IntKi), PARAMETER :: EddVisT9N03D6 = 5973 - INTEGER(IntKi), PARAMETER :: EddVisT9N03D7 = 5974 - INTEGER(IntKi), PARAMETER :: EddVisT9N03D8 = 5975 - INTEGER(IntKi), PARAMETER :: EddVisT9N03D9 = 5976 - INTEGER(IntKi), PARAMETER :: EddVisT9N04D1 = 5977 - INTEGER(IntKi), PARAMETER :: EddVisT9N04D2 = 5978 - INTEGER(IntKi), PARAMETER :: EddVisT9N04D3 = 5979 - INTEGER(IntKi), PARAMETER :: EddVisT9N04D4 = 5980 - INTEGER(IntKi), PARAMETER :: EddVisT9N04D5 = 5981 - INTEGER(IntKi), PARAMETER :: EddVisT9N04D6 = 5982 - INTEGER(IntKi), PARAMETER :: EddVisT9N04D7 = 5983 - INTEGER(IntKi), PARAMETER :: EddVisT9N04D8 = 5984 - INTEGER(IntKi), PARAMETER :: EddVisT9N04D9 = 5985 - INTEGER(IntKi), PARAMETER :: EddVisT9N05D1 = 5986 - INTEGER(IntKi), PARAMETER :: EddVisT9N05D2 = 5987 - INTEGER(IntKi), PARAMETER :: EddVisT9N05D3 = 5988 - INTEGER(IntKi), PARAMETER :: EddVisT9N05D4 = 5989 - INTEGER(IntKi), PARAMETER :: EddVisT9N05D5 = 5990 - INTEGER(IntKi), PARAMETER :: EddVisT9N05D6 = 5991 - INTEGER(IntKi), PARAMETER :: EddVisT9N05D7 = 5992 - INTEGER(IntKi), PARAMETER :: EddVisT9N05D8 = 5993 - INTEGER(IntKi), PARAMETER :: EddVisT9N05D9 = 5994 - INTEGER(IntKi), PARAMETER :: EddVisT9N06D1 = 5995 - INTEGER(IntKi), PARAMETER :: EddVisT9N06D2 = 5996 - INTEGER(IntKi), PARAMETER :: EddVisT9N06D3 = 5997 - INTEGER(IntKi), PARAMETER :: EddVisT9N06D4 = 5998 - INTEGER(IntKi), PARAMETER :: EddVisT9N06D5 = 5999 - INTEGER(IntKi), PARAMETER :: EddVisT9N06D6 = 6000 - INTEGER(IntKi), PARAMETER :: EddVisT9N06D7 = 6001 - INTEGER(IntKi), PARAMETER :: EddVisT9N06D8 = 6002 - INTEGER(IntKi), PARAMETER :: EddVisT9N06D9 = 6003 - INTEGER(IntKi), PARAMETER :: EddVisT9N07D1 = 6004 - INTEGER(IntKi), PARAMETER :: EddVisT9N07D2 = 6005 - INTEGER(IntKi), PARAMETER :: EddVisT9N07D3 = 6006 - INTEGER(IntKi), PARAMETER :: EddVisT9N07D4 = 6007 - INTEGER(IntKi), PARAMETER :: EddVisT9N07D5 = 6008 - INTEGER(IntKi), PARAMETER :: EddVisT9N07D6 = 6009 - INTEGER(IntKi), PARAMETER :: EddVisT9N07D7 = 6010 - INTEGER(IntKi), PARAMETER :: EddVisT9N07D8 = 6011 - INTEGER(IntKi), PARAMETER :: EddVisT9N07D9 = 6012 - INTEGER(IntKi), PARAMETER :: EddVisT9N08D1 = 6013 - INTEGER(IntKi), PARAMETER :: EddVisT9N08D2 = 6014 - INTEGER(IntKi), PARAMETER :: EddVisT9N08D3 = 6015 - INTEGER(IntKi), PARAMETER :: EddVisT9N08D4 = 6016 - INTEGER(IntKi), PARAMETER :: EddVisT9N08D5 = 6017 - INTEGER(IntKi), PARAMETER :: EddVisT9N08D6 = 6018 - INTEGER(IntKi), PARAMETER :: EddVisT9N08D7 = 6019 - INTEGER(IntKi), PARAMETER :: EddVisT9N08D8 = 6020 - INTEGER(IntKi), PARAMETER :: EddVisT9N08D9 = 6021 - INTEGER(IntKi), PARAMETER :: EddVisT9N09D1 = 6022 - INTEGER(IntKi), PARAMETER :: EddVisT9N09D2 = 6023 - INTEGER(IntKi), PARAMETER :: EddVisT9N09D3 = 6024 - INTEGER(IntKi), PARAMETER :: EddVisT9N09D4 = 6025 - INTEGER(IntKi), PARAMETER :: EddVisT9N09D5 = 6026 - INTEGER(IntKi), PARAMETER :: EddVisT9N09D6 = 6027 - INTEGER(IntKi), PARAMETER :: EddVisT9N09D7 = 6028 - INTEGER(IntKi), PARAMETER :: EddVisT9N09D8 = 6029 - INTEGER(IntKi), PARAMETER :: EddVisT9N09D9 = 6030 - INTEGER(IntKi), PARAMETER :: EddVisT9N10D1 = 6031 - INTEGER(IntKi), PARAMETER :: EddVisT9N10D2 = 6032 - INTEGER(IntKi), PARAMETER :: EddVisT9N10D3 = 6033 - INTEGER(IntKi), PARAMETER :: EddVisT9N10D4 = 6034 - INTEGER(IntKi), PARAMETER :: EddVisT9N10D5 = 6035 - INTEGER(IntKi), PARAMETER :: EddVisT9N10D6 = 6036 - INTEGER(IntKi), PARAMETER :: EddVisT9N10D7 = 6037 - INTEGER(IntKi), PARAMETER :: EddVisT9N10D8 = 6038 - INTEGER(IntKi), PARAMETER :: EddVisT9N10D9 = 6039 - INTEGER(IntKi), PARAMETER :: EddVisT9N11D1 = 6040 - INTEGER(IntKi), PARAMETER :: EddVisT9N11D2 = 6041 - INTEGER(IntKi), PARAMETER :: EddVisT9N11D3 = 6042 - INTEGER(IntKi), PARAMETER :: EddVisT9N11D4 = 6043 - INTEGER(IntKi), PARAMETER :: EddVisT9N11D5 = 6044 - INTEGER(IntKi), PARAMETER :: EddVisT9N11D6 = 6045 - INTEGER(IntKi), PARAMETER :: EddVisT9N11D7 = 6046 - INTEGER(IntKi), PARAMETER :: EddVisT9N11D8 = 6047 - INTEGER(IntKi), PARAMETER :: EddVisT9N11D9 = 6048 - INTEGER(IntKi), PARAMETER :: EddVisT9N12D1 = 6049 - INTEGER(IntKi), PARAMETER :: EddVisT9N12D2 = 6050 - INTEGER(IntKi), PARAMETER :: EddVisT9N12D3 = 6051 - INTEGER(IntKi), PARAMETER :: EddVisT9N12D4 = 6052 - INTEGER(IntKi), PARAMETER :: EddVisT9N12D5 = 6053 - INTEGER(IntKi), PARAMETER :: EddVisT9N12D6 = 6054 - INTEGER(IntKi), PARAMETER :: EddVisT9N12D7 = 6055 - INTEGER(IntKi), PARAMETER :: EddVisT9N12D8 = 6056 - INTEGER(IntKi), PARAMETER :: EddVisT9N12D9 = 6057 - INTEGER(IntKi), PARAMETER :: EddVisT9N13D1 = 6058 - INTEGER(IntKi), PARAMETER :: EddVisT9N13D2 = 6059 - INTEGER(IntKi), PARAMETER :: EddVisT9N13D3 = 6060 - INTEGER(IntKi), PARAMETER :: EddVisT9N13D4 = 6061 - INTEGER(IntKi), PARAMETER :: EddVisT9N13D5 = 6062 - INTEGER(IntKi), PARAMETER :: EddVisT9N13D6 = 6063 - INTEGER(IntKi), PARAMETER :: EddVisT9N13D7 = 6064 - INTEGER(IntKi), PARAMETER :: EddVisT9N13D8 = 6065 - INTEGER(IntKi), PARAMETER :: EddVisT9N13D9 = 6066 - INTEGER(IntKi), PARAMETER :: EddVisT9N14D1 = 6067 - INTEGER(IntKi), PARAMETER :: EddVisT9N14D2 = 6068 - INTEGER(IntKi), PARAMETER :: EddVisT9N14D3 = 6069 - INTEGER(IntKi), PARAMETER :: EddVisT9N14D4 = 6070 - INTEGER(IntKi), PARAMETER :: EddVisT9N14D5 = 6071 - INTEGER(IntKi), PARAMETER :: EddVisT9N14D6 = 6072 - INTEGER(IntKi), PARAMETER :: EddVisT9N14D7 = 6073 - INTEGER(IntKi), PARAMETER :: EddVisT9N14D8 = 6074 - INTEGER(IntKi), PARAMETER :: EddVisT9N14D9 = 6075 - INTEGER(IntKi), PARAMETER :: EddVisT9N15D1 = 6076 - INTEGER(IntKi), PARAMETER :: EddVisT9N15D2 = 6077 - INTEGER(IntKi), PARAMETER :: EddVisT9N15D3 = 6078 - INTEGER(IntKi), PARAMETER :: EddVisT9N15D4 = 6079 - INTEGER(IntKi), PARAMETER :: EddVisT9N15D5 = 6080 - INTEGER(IntKi), PARAMETER :: EddVisT9N15D6 = 6081 - INTEGER(IntKi), PARAMETER :: EddVisT9N15D7 = 6082 - INTEGER(IntKi), PARAMETER :: EddVisT9N15D8 = 6083 - INTEGER(IntKi), PARAMETER :: EddVisT9N15D9 = 6084 - INTEGER(IntKi), PARAMETER :: EddVisT9N16D1 = 6085 - INTEGER(IntKi), PARAMETER :: EddVisT9N16D2 = 6086 - INTEGER(IntKi), PARAMETER :: EddVisT9N16D3 = 6087 - INTEGER(IntKi), PARAMETER :: EddVisT9N16D4 = 6088 - INTEGER(IntKi), PARAMETER :: EddVisT9N16D5 = 6089 - INTEGER(IntKi), PARAMETER :: EddVisT9N16D6 = 6090 - INTEGER(IntKi), PARAMETER :: EddVisT9N16D7 = 6091 - INTEGER(IntKi), PARAMETER :: EddVisT9N16D8 = 6092 - INTEGER(IntKi), PARAMETER :: EddVisT9N16D9 = 6093 - INTEGER(IntKi), PARAMETER :: EddVisT9N17D1 = 6094 - INTEGER(IntKi), PARAMETER :: EddVisT9N17D2 = 6095 - INTEGER(IntKi), PARAMETER :: EddVisT9N17D3 = 6096 - INTEGER(IntKi), PARAMETER :: EddVisT9N17D4 = 6097 - INTEGER(IntKi), PARAMETER :: EddVisT9N17D5 = 6098 - INTEGER(IntKi), PARAMETER :: EddVisT9N17D6 = 6099 - INTEGER(IntKi), PARAMETER :: EddVisT9N17D7 = 6100 - INTEGER(IntKi), PARAMETER :: EddVisT9N17D8 = 6101 - INTEGER(IntKi), PARAMETER :: EddVisT9N17D9 = 6102 - INTEGER(IntKi), PARAMETER :: EddVisT9N18D1 = 6103 - INTEGER(IntKi), PARAMETER :: EddVisT9N18D2 = 6104 - INTEGER(IntKi), PARAMETER :: EddVisT9N18D3 = 6105 - INTEGER(IntKi), PARAMETER :: EddVisT9N18D4 = 6106 - INTEGER(IntKi), PARAMETER :: EddVisT9N18D5 = 6107 - INTEGER(IntKi), PARAMETER :: EddVisT9N18D6 = 6108 - INTEGER(IntKi), PARAMETER :: EddVisT9N18D7 = 6109 - INTEGER(IntKi), PARAMETER :: EddVisT9N18D8 = 6110 - INTEGER(IntKi), PARAMETER :: EddVisT9N18D9 = 6111 - INTEGER(IntKi), PARAMETER :: EddVisT9N19D1 = 6112 - INTEGER(IntKi), PARAMETER :: EddVisT9N19D2 = 6113 - INTEGER(IntKi), PARAMETER :: EddVisT9N19D3 = 6114 - INTEGER(IntKi), PARAMETER :: EddVisT9N19D4 = 6115 - INTEGER(IntKi), PARAMETER :: EddVisT9N19D5 = 6116 - INTEGER(IntKi), PARAMETER :: EddVisT9N19D6 = 6117 - INTEGER(IntKi), PARAMETER :: EddVisT9N19D7 = 6118 - INTEGER(IntKi), PARAMETER :: EddVisT9N19D8 = 6119 - INTEGER(IntKi), PARAMETER :: EddVisT9N19D9 = 6120 - INTEGER(IntKi), PARAMETER :: EddVisT9N20D1 = 6121 - INTEGER(IntKi), PARAMETER :: EddVisT9N20D2 = 6122 - INTEGER(IntKi), PARAMETER :: EddVisT9N20D3 = 6123 - INTEGER(IntKi), PARAMETER :: EddVisT9N20D4 = 6124 - INTEGER(IntKi), PARAMETER :: EddVisT9N20D5 = 6125 - INTEGER(IntKi), PARAMETER :: EddVisT9N20D6 = 6126 - INTEGER(IntKi), PARAMETER :: EddVisT9N20D7 = 6127 - INTEGER(IntKi), PARAMETER :: EddVisT9N20D8 = 6128 - INTEGER(IntKi), PARAMETER :: EddVisT9N20D9 = 6129 - INTEGER(IntKi), PARAMETER :: EddAmbT1N01D1 = 6130 - INTEGER(IntKi), PARAMETER :: EddAmbT1N01D2 = 6131 - INTEGER(IntKi), PARAMETER :: EddAmbT1N01D3 = 6132 - INTEGER(IntKi), PARAMETER :: EddAmbT1N01D4 = 6133 - INTEGER(IntKi), PARAMETER :: EddAmbT1N01D5 = 6134 - INTEGER(IntKi), PARAMETER :: EddAmbT1N01D6 = 6135 - INTEGER(IntKi), PARAMETER :: EddAmbT1N01D7 = 6136 - INTEGER(IntKi), PARAMETER :: EddAmbT1N01D8 = 6137 - INTEGER(IntKi), PARAMETER :: EddAmbT1N01D9 = 6138 - INTEGER(IntKi), PARAMETER :: EddAmbT1N02D1 = 6139 - INTEGER(IntKi), PARAMETER :: EddAmbT1N02D2 = 6140 - INTEGER(IntKi), PARAMETER :: EddAmbT1N02D3 = 6141 - INTEGER(IntKi), PARAMETER :: EddAmbT1N02D4 = 6142 - INTEGER(IntKi), PARAMETER :: EddAmbT1N02D5 = 6143 - INTEGER(IntKi), PARAMETER :: EddAmbT1N02D6 = 6144 - INTEGER(IntKi), PARAMETER :: EddAmbT1N02D7 = 6145 - INTEGER(IntKi), PARAMETER :: EddAmbT1N02D8 = 6146 - INTEGER(IntKi), PARAMETER :: EddAmbT1N02D9 = 6147 - INTEGER(IntKi), PARAMETER :: EddAmbT1N03D1 = 6148 - INTEGER(IntKi), PARAMETER :: EddAmbT1N03D2 = 6149 - INTEGER(IntKi), PARAMETER :: EddAmbT1N03D3 = 6150 - INTEGER(IntKi), PARAMETER :: EddAmbT1N03D4 = 6151 - INTEGER(IntKi), PARAMETER :: EddAmbT1N03D5 = 6152 - INTEGER(IntKi), PARAMETER :: EddAmbT1N03D6 = 6153 - INTEGER(IntKi), PARAMETER :: EddAmbT1N03D7 = 6154 - INTEGER(IntKi), PARAMETER :: EddAmbT1N03D8 = 6155 - INTEGER(IntKi), PARAMETER :: EddAmbT1N03D9 = 6156 - INTEGER(IntKi), PARAMETER :: EddAmbT1N04D1 = 6157 - INTEGER(IntKi), PARAMETER :: EddAmbT1N04D2 = 6158 - INTEGER(IntKi), PARAMETER :: EddAmbT1N04D3 = 6159 - INTEGER(IntKi), PARAMETER :: EddAmbT1N04D4 = 6160 - INTEGER(IntKi), PARAMETER :: EddAmbT1N04D5 = 6161 - INTEGER(IntKi), PARAMETER :: EddAmbT1N04D6 = 6162 - INTEGER(IntKi), PARAMETER :: EddAmbT1N04D7 = 6163 - INTEGER(IntKi), PARAMETER :: EddAmbT1N04D8 = 6164 - INTEGER(IntKi), PARAMETER :: EddAmbT1N04D9 = 6165 - INTEGER(IntKi), PARAMETER :: EddAmbT1N05D1 = 6166 - INTEGER(IntKi), PARAMETER :: EddAmbT1N05D2 = 6167 - INTEGER(IntKi), PARAMETER :: EddAmbT1N05D3 = 6168 - INTEGER(IntKi), PARAMETER :: EddAmbT1N05D4 = 6169 - INTEGER(IntKi), PARAMETER :: EddAmbT1N05D5 = 6170 - INTEGER(IntKi), PARAMETER :: EddAmbT1N05D6 = 6171 - INTEGER(IntKi), PARAMETER :: EddAmbT1N05D7 = 6172 - INTEGER(IntKi), PARAMETER :: EddAmbT1N05D8 = 6173 - INTEGER(IntKi), PARAMETER :: EddAmbT1N05D9 = 6174 - INTEGER(IntKi), PARAMETER :: EddAmbT1N06D1 = 6175 - INTEGER(IntKi), PARAMETER :: EddAmbT1N06D2 = 6176 - INTEGER(IntKi), PARAMETER :: EddAmbT1N06D3 = 6177 - INTEGER(IntKi), PARAMETER :: EddAmbT1N06D4 = 6178 - INTEGER(IntKi), PARAMETER :: EddAmbT1N06D5 = 6179 - INTEGER(IntKi), PARAMETER :: EddAmbT1N06D6 = 6180 - INTEGER(IntKi), PARAMETER :: EddAmbT1N06D7 = 6181 - INTEGER(IntKi), PARAMETER :: EddAmbT1N06D8 = 6182 - INTEGER(IntKi), PARAMETER :: EddAmbT1N06D9 = 6183 - INTEGER(IntKi), PARAMETER :: EddAmbT1N07D1 = 6184 - INTEGER(IntKi), PARAMETER :: EddAmbT1N07D2 = 6185 - INTEGER(IntKi), PARAMETER :: EddAmbT1N07D3 = 6186 - INTEGER(IntKi), PARAMETER :: EddAmbT1N07D4 = 6187 - INTEGER(IntKi), PARAMETER :: EddAmbT1N07D5 = 6188 - INTEGER(IntKi), PARAMETER :: EddAmbT1N07D6 = 6189 - INTEGER(IntKi), PARAMETER :: EddAmbT1N07D7 = 6190 - INTEGER(IntKi), PARAMETER :: EddAmbT1N07D8 = 6191 - INTEGER(IntKi), PARAMETER :: EddAmbT1N07D9 = 6192 - INTEGER(IntKi), PARAMETER :: EddAmbT1N08D1 = 6193 - INTEGER(IntKi), PARAMETER :: EddAmbT1N08D2 = 6194 - INTEGER(IntKi), PARAMETER :: EddAmbT1N08D3 = 6195 - INTEGER(IntKi), PARAMETER :: EddAmbT1N08D4 = 6196 - INTEGER(IntKi), PARAMETER :: EddAmbT1N08D5 = 6197 - INTEGER(IntKi), PARAMETER :: EddAmbT1N08D6 = 6198 - INTEGER(IntKi), PARAMETER :: EddAmbT1N08D7 = 6199 - INTEGER(IntKi), PARAMETER :: EddAmbT1N08D8 = 6200 - INTEGER(IntKi), PARAMETER :: EddAmbT1N08D9 = 6201 - INTEGER(IntKi), PARAMETER :: EddAmbT1N09D1 = 6202 - INTEGER(IntKi), PARAMETER :: EddAmbT1N09D2 = 6203 - INTEGER(IntKi), PARAMETER :: EddAmbT1N09D3 = 6204 - INTEGER(IntKi), PARAMETER :: EddAmbT1N09D4 = 6205 - INTEGER(IntKi), PARAMETER :: EddAmbT1N09D5 = 6206 - INTEGER(IntKi), PARAMETER :: EddAmbT1N09D6 = 6207 - INTEGER(IntKi), PARAMETER :: EddAmbT1N09D7 = 6208 - INTEGER(IntKi), PARAMETER :: EddAmbT1N09D8 = 6209 - INTEGER(IntKi), PARAMETER :: EddAmbT1N09D9 = 6210 - INTEGER(IntKi), PARAMETER :: EddAmbT1N10D1 = 6211 - INTEGER(IntKi), PARAMETER :: EddAmbT1N10D2 = 6212 - INTEGER(IntKi), PARAMETER :: EddAmbT1N10D3 = 6213 - INTEGER(IntKi), PARAMETER :: EddAmbT1N10D4 = 6214 - INTEGER(IntKi), PARAMETER :: EddAmbT1N10D5 = 6215 - INTEGER(IntKi), PARAMETER :: EddAmbT1N10D6 = 6216 - INTEGER(IntKi), PARAMETER :: EddAmbT1N10D7 = 6217 - INTEGER(IntKi), PARAMETER :: EddAmbT1N10D8 = 6218 - INTEGER(IntKi), PARAMETER :: EddAmbT1N10D9 = 6219 - INTEGER(IntKi), PARAMETER :: EddAmbT1N11D1 = 6220 - INTEGER(IntKi), PARAMETER :: EddAmbT1N11D2 = 6221 - INTEGER(IntKi), PARAMETER :: EddAmbT1N11D3 = 6222 - INTEGER(IntKi), PARAMETER :: EddAmbT1N11D4 = 6223 - INTEGER(IntKi), PARAMETER :: EddAmbT1N11D5 = 6224 - INTEGER(IntKi), PARAMETER :: EddAmbT1N11D6 = 6225 - INTEGER(IntKi), PARAMETER :: EddAmbT1N11D7 = 6226 - INTEGER(IntKi), PARAMETER :: EddAmbT1N11D8 = 6227 - INTEGER(IntKi), PARAMETER :: EddAmbT1N11D9 = 6228 - INTEGER(IntKi), PARAMETER :: EddAmbT1N12D1 = 6229 - INTEGER(IntKi), PARAMETER :: EddAmbT1N12D2 = 6230 - INTEGER(IntKi), PARAMETER :: EddAmbT1N12D3 = 6231 - INTEGER(IntKi), PARAMETER :: EddAmbT1N12D4 = 6232 - INTEGER(IntKi), PARAMETER :: EddAmbT1N12D5 = 6233 - INTEGER(IntKi), PARAMETER :: EddAmbT1N12D6 = 6234 - INTEGER(IntKi), PARAMETER :: EddAmbT1N12D7 = 6235 - INTEGER(IntKi), PARAMETER :: EddAmbT1N12D8 = 6236 - INTEGER(IntKi), PARAMETER :: EddAmbT1N12D9 = 6237 - INTEGER(IntKi), PARAMETER :: EddAmbT1N13D1 = 6238 - INTEGER(IntKi), PARAMETER :: EddAmbT1N13D2 = 6239 - INTEGER(IntKi), PARAMETER :: EddAmbT1N13D3 = 6240 - INTEGER(IntKi), PARAMETER :: EddAmbT1N13D4 = 6241 - INTEGER(IntKi), PARAMETER :: EddAmbT1N13D5 = 6242 - INTEGER(IntKi), PARAMETER :: EddAmbT1N13D6 = 6243 - INTEGER(IntKi), PARAMETER :: EddAmbT1N13D7 = 6244 - INTEGER(IntKi), PARAMETER :: EddAmbT1N13D8 = 6245 - INTEGER(IntKi), PARAMETER :: EddAmbT1N13D9 = 6246 - INTEGER(IntKi), PARAMETER :: EddAmbT1N14D1 = 6247 - INTEGER(IntKi), PARAMETER :: EddAmbT1N14D2 = 6248 - INTEGER(IntKi), PARAMETER :: EddAmbT1N14D3 = 6249 - INTEGER(IntKi), PARAMETER :: EddAmbT1N14D4 = 6250 - INTEGER(IntKi), PARAMETER :: EddAmbT1N14D5 = 6251 - INTEGER(IntKi), PARAMETER :: EddAmbT1N14D6 = 6252 - INTEGER(IntKi), PARAMETER :: EddAmbT1N14D7 = 6253 - INTEGER(IntKi), PARAMETER :: EddAmbT1N14D8 = 6254 - INTEGER(IntKi), PARAMETER :: EddAmbT1N14D9 = 6255 - INTEGER(IntKi), PARAMETER :: EddAmbT1N15D1 = 6256 - INTEGER(IntKi), PARAMETER :: EddAmbT1N15D2 = 6257 - INTEGER(IntKi), PARAMETER :: EddAmbT1N15D3 = 6258 - INTEGER(IntKi), PARAMETER :: EddAmbT1N15D4 = 6259 - INTEGER(IntKi), PARAMETER :: EddAmbT1N15D5 = 6260 - INTEGER(IntKi), PARAMETER :: EddAmbT1N15D6 = 6261 - INTEGER(IntKi), PARAMETER :: EddAmbT1N15D7 = 6262 - INTEGER(IntKi), PARAMETER :: EddAmbT1N15D8 = 6263 - INTEGER(IntKi), PARAMETER :: EddAmbT1N15D9 = 6264 - INTEGER(IntKi), PARAMETER :: EddAmbT1N16D1 = 6265 - INTEGER(IntKi), PARAMETER :: EddAmbT1N16D2 = 6266 - INTEGER(IntKi), PARAMETER :: EddAmbT1N16D3 = 6267 - INTEGER(IntKi), PARAMETER :: EddAmbT1N16D4 = 6268 - INTEGER(IntKi), PARAMETER :: EddAmbT1N16D5 = 6269 - INTEGER(IntKi), PARAMETER :: EddAmbT1N16D6 = 6270 - INTEGER(IntKi), PARAMETER :: EddAmbT1N16D7 = 6271 - INTEGER(IntKi), PARAMETER :: EddAmbT1N16D8 = 6272 - INTEGER(IntKi), PARAMETER :: EddAmbT1N16D9 = 6273 - INTEGER(IntKi), PARAMETER :: EddAmbT1N17D1 = 6274 - INTEGER(IntKi), PARAMETER :: EddAmbT1N17D2 = 6275 - INTEGER(IntKi), PARAMETER :: EddAmbT1N17D3 = 6276 - INTEGER(IntKi), PARAMETER :: EddAmbT1N17D4 = 6277 - INTEGER(IntKi), PARAMETER :: EddAmbT1N17D5 = 6278 - INTEGER(IntKi), PARAMETER :: EddAmbT1N17D6 = 6279 - INTEGER(IntKi), PARAMETER :: EddAmbT1N17D7 = 6280 - INTEGER(IntKi), PARAMETER :: EddAmbT1N17D8 = 6281 - INTEGER(IntKi), PARAMETER :: EddAmbT1N17D9 = 6282 - INTEGER(IntKi), PARAMETER :: EddAmbT1N18D1 = 6283 - INTEGER(IntKi), PARAMETER :: EddAmbT1N18D2 = 6284 - INTEGER(IntKi), PARAMETER :: EddAmbT1N18D3 = 6285 - INTEGER(IntKi), PARAMETER :: EddAmbT1N18D4 = 6286 - INTEGER(IntKi), PARAMETER :: EddAmbT1N18D5 = 6287 - INTEGER(IntKi), PARAMETER :: EddAmbT1N18D6 = 6288 - INTEGER(IntKi), PARAMETER :: EddAmbT1N18D7 = 6289 - INTEGER(IntKi), PARAMETER :: EddAmbT1N18D8 = 6290 - INTEGER(IntKi), PARAMETER :: EddAmbT1N18D9 = 6291 - INTEGER(IntKi), PARAMETER :: EddAmbT1N19D1 = 6292 - INTEGER(IntKi), PARAMETER :: EddAmbT1N19D2 = 6293 - INTEGER(IntKi), PARAMETER :: EddAmbT1N19D3 = 6294 - INTEGER(IntKi), PARAMETER :: EddAmbT1N19D4 = 6295 - INTEGER(IntKi), PARAMETER :: EddAmbT1N19D5 = 6296 - INTEGER(IntKi), PARAMETER :: EddAmbT1N19D6 = 6297 - INTEGER(IntKi), PARAMETER :: EddAmbT1N19D7 = 6298 - INTEGER(IntKi), PARAMETER :: EddAmbT1N19D8 = 6299 - INTEGER(IntKi), PARAMETER :: EddAmbT1N19D9 = 6300 - INTEGER(IntKi), PARAMETER :: EddAmbT1N20D1 = 6301 - INTEGER(IntKi), PARAMETER :: EddAmbT1N20D2 = 6302 - INTEGER(IntKi), PARAMETER :: EddAmbT1N20D3 = 6303 - INTEGER(IntKi), PARAMETER :: EddAmbT1N20D4 = 6304 - INTEGER(IntKi), PARAMETER :: EddAmbT1N20D5 = 6305 - INTEGER(IntKi), PARAMETER :: EddAmbT1N20D6 = 6306 - INTEGER(IntKi), PARAMETER :: EddAmbT1N20D7 = 6307 - INTEGER(IntKi), PARAMETER :: EddAmbT1N20D8 = 6308 - INTEGER(IntKi), PARAMETER :: EddAmbT1N20D9 = 6309 - INTEGER(IntKi), PARAMETER :: EddAmbT2N01D1 = 6310 - INTEGER(IntKi), PARAMETER :: EddAmbT2N01D2 = 6311 - INTEGER(IntKi), PARAMETER :: EddAmbT2N01D3 = 6312 - INTEGER(IntKi), PARAMETER :: EddAmbT2N01D4 = 6313 - INTEGER(IntKi), PARAMETER :: EddAmbT2N01D5 = 6314 - INTEGER(IntKi), PARAMETER :: EddAmbT2N01D6 = 6315 - INTEGER(IntKi), PARAMETER :: EddAmbT2N01D7 = 6316 - INTEGER(IntKi), PARAMETER :: EddAmbT2N01D8 = 6317 - INTEGER(IntKi), PARAMETER :: EddAmbT2N01D9 = 6318 - INTEGER(IntKi), PARAMETER :: EddAmbT2N02D1 = 6319 - INTEGER(IntKi), PARAMETER :: EddAmbT2N02D2 = 6320 - INTEGER(IntKi), PARAMETER :: EddAmbT2N02D3 = 6321 - INTEGER(IntKi), PARAMETER :: EddAmbT2N02D4 = 6322 - INTEGER(IntKi), PARAMETER :: EddAmbT2N02D5 = 6323 - INTEGER(IntKi), PARAMETER :: EddAmbT2N02D6 = 6324 - INTEGER(IntKi), PARAMETER :: EddAmbT2N02D7 = 6325 - INTEGER(IntKi), PARAMETER :: EddAmbT2N02D8 = 6326 - INTEGER(IntKi), PARAMETER :: EddAmbT2N02D9 = 6327 - INTEGER(IntKi), PARAMETER :: EddAmbT2N03D1 = 6328 - INTEGER(IntKi), PARAMETER :: EddAmbT2N03D2 = 6329 - INTEGER(IntKi), PARAMETER :: EddAmbT2N03D3 = 6330 - INTEGER(IntKi), PARAMETER :: EddAmbT2N03D4 = 6331 - INTEGER(IntKi), PARAMETER :: EddAmbT2N03D5 = 6332 - INTEGER(IntKi), PARAMETER :: EddAmbT2N03D6 = 6333 - INTEGER(IntKi), PARAMETER :: EddAmbT2N03D7 = 6334 - INTEGER(IntKi), PARAMETER :: EddAmbT2N03D8 = 6335 - INTEGER(IntKi), PARAMETER :: EddAmbT2N03D9 = 6336 - INTEGER(IntKi), PARAMETER :: EddAmbT2N04D1 = 6337 - INTEGER(IntKi), PARAMETER :: EddAmbT2N04D2 = 6338 - INTEGER(IntKi), PARAMETER :: EddAmbT2N04D3 = 6339 - INTEGER(IntKi), PARAMETER :: EddAmbT2N04D4 = 6340 - INTEGER(IntKi), PARAMETER :: EddAmbT2N04D5 = 6341 - INTEGER(IntKi), PARAMETER :: EddAmbT2N04D6 = 6342 - INTEGER(IntKi), PARAMETER :: EddAmbT2N04D7 = 6343 - INTEGER(IntKi), PARAMETER :: EddAmbT2N04D8 = 6344 - INTEGER(IntKi), PARAMETER :: EddAmbT2N04D9 = 6345 - INTEGER(IntKi), PARAMETER :: EddAmbT2N05D1 = 6346 - INTEGER(IntKi), PARAMETER :: EddAmbT2N05D2 = 6347 - INTEGER(IntKi), PARAMETER :: EddAmbT2N05D3 = 6348 - INTEGER(IntKi), PARAMETER :: EddAmbT2N05D4 = 6349 - INTEGER(IntKi), PARAMETER :: EddAmbT2N05D5 = 6350 - INTEGER(IntKi), PARAMETER :: EddAmbT2N05D6 = 6351 - INTEGER(IntKi), PARAMETER :: EddAmbT2N05D7 = 6352 - INTEGER(IntKi), PARAMETER :: EddAmbT2N05D8 = 6353 - INTEGER(IntKi), PARAMETER :: EddAmbT2N05D9 = 6354 - INTEGER(IntKi), PARAMETER :: EddAmbT2N06D1 = 6355 - INTEGER(IntKi), PARAMETER :: EddAmbT2N06D2 = 6356 - INTEGER(IntKi), PARAMETER :: EddAmbT2N06D3 = 6357 - INTEGER(IntKi), PARAMETER :: EddAmbT2N06D4 = 6358 - INTEGER(IntKi), PARAMETER :: EddAmbT2N06D5 = 6359 - INTEGER(IntKi), PARAMETER :: EddAmbT2N06D6 = 6360 - INTEGER(IntKi), PARAMETER :: EddAmbT2N06D7 = 6361 - INTEGER(IntKi), PARAMETER :: EddAmbT2N06D8 = 6362 - INTEGER(IntKi), PARAMETER :: EddAmbT2N06D9 = 6363 - INTEGER(IntKi), PARAMETER :: EddAmbT2N07D1 = 6364 - INTEGER(IntKi), PARAMETER :: EddAmbT2N07D2 = 6365 - INTEGER(IntKi), PARAMETER :: EddAmbT2N07D3 = 6366 - INTEGER(IntKi), PARAMETER :: EddAmbT2N07D4 = 6367 - INTEGER(IntKi), PARAMETER :: EddAmbT2N07D5 = 6368 - INTEGER(IntKi), PARAMETER :: EddAmbT2N07D6 = 6369 - INTEGER(IntKi), PARAMETER :: EddAmbT2N07D7 = 6370 - INTEGER(IntKi), PARAMETER :: EddAmbT2N07D8 = 6371 - INTEGER(IntKi), PARAMETER :: EddAmbT2N07D9 = 6372 - INTEGER(IntKi), PARAMETER :: EddAmbT2N08D1 = 6373 - INTEGER(IntKi), PARAMETER :: EddAmbT2N08D2 = 6374 - INTEGER(IntKi), PARAMETER :: EddAmbT2N08D3 = 6375 - INTEGER(IntKi), PARAMETER :: EddAmbT2N08D4 = 6376 - INTEGER(IntKi), PARAMETER :: EddAmbT2N08D5 = 6377 - INTEGER(IntKi), PARAMETER :: EddAmbT2N08D6 = 6378 - INTEGER(IntKi), PARAMETER :: EddAmbT2N08D7 = 6379 - INTEGER(IntKi), PARAMETER :: EddAmbT2N08D8 = 6380 - INTEGER(IntKi), PARAMETER :: EddAmbT2N08D9 = 6381 - INTEGER(IntKi), PARAMETER :: EddAmbT2N09D1 = 6382 - INTEGER(IntKi), PARAMETER :: EddAmbT2N09D2 = 6383 - INTEGER(IntKi), PARAMETER :: EddAmbT2N09D3 = 6384 - INTEGER(IntKi), PARAMETER :: EddAmbT2N09D4 = 6385 - INTEGER(IntKi), PARAMETER :: EddAmbT2N09D5 = 6386 - INTEGER(IntKi), PARAMETER :: EddAmbT2N09D6 = 6387 - INTEGER(IntKi), PARAMETER :: EddAmbT2N09D7 = 6388 - INTEGER(IntKi), PARAMETER :: EddAmbT2N09D8 = 6389 - INTEGER(IntKi), PARAMETER :: EddAmbT2N09D9 = 6390 - INTEGER(IntKi), PARAMETER :: EddAmbT2N10D1 = 6391 - INTEGER(IntKi), PARAMETER :: EddAmbT2N10D2 = 6392 - INTEGER(IntKi), PARAMETER :: EddAmbT2N10D3 = 6393 - INTEGER(IntKi), PARAMETER :: EddAmbT2N10D4 = 6394 - INTEGER(IntKi), PARAMETER :: EddAmbT2N10D5 = 6395 - INTEGER(IntKi), PARAMETER :: EddAmbT2N10D6 = 6396 - INTEGER(IntKi), PARAMETER :: EddAmbT2N10D7 = 6397 - INTEGER(IntKi), PARAMETER :: EddAmbT2N10D8 = 6398 - INTEGER(IntKi), PARAMETER :: EddAmbT2N10D9 = 6399 - INTEGER(IntKi), PARAMETER :: EddAmbT2N11D1 = 6400 - INTEGER(IntKi), PARAMETER :: EddAmbT2N11D2 = 6401 - INTEGER(IntKi), PARAMETER :: EddAmbT2N11D3 = 6402 - INTEGER(IntKi), PARAMETER :: EddAmbT2N11D4 = 6403 - INTEGER(IntKi), PARAMETER :: EddAmbT2N11D5 = 6404 - INTEGER(IntKi), PARAMETER :: EddAmbT2N11D6 = 6405 - INTEGER(IntKi), PARAMETER :: EddAmbT2N11D7 = 6406 - INTEGER(IntKi), PARAMETER :: EddAmbT2N11D8 = 6407 - INTEGER(IntKi), PARAMETER :: EddAmbT2N11D9 = 6408 - INTEGER(IntKi), PARAMETER :: EddAmbT2N12D1 = 6409 - INTEGER(IntKi), PARAMETER :: EddAmbT2N12D2 = 6410 - INTEGER(IntKi), PARAMETER :: EddAmbT2N12D3 = 6411 - INTEGER(IntKi), PARAMETER :: EddAmbT2N12D4 = 6412 - INTEGER(IntKi), PARAMETER :: EddAmbT2N12D5 = 6413 - INTEGER(IntKi), PARAMETER :: EddAmbT2N12D6 = 6414 - INTEGER(IntKi), PARAMETER :: EddAmbT2N12D7 = 6415 - INTEGER(IntKi), PARAMETER :: EddAmbT2N12D8 = 6416 - INTEGER(IntKi), PARAMETER :: EddAmbT2N12D9 = 6417 - INTEGER(IntKi), PARAMETER :: EddAmbT2N13D1 = 6418 - INTEGER(IntKi), PARAMETER :: EddAmbT2N13D2 = 6419 - INTEGER(IntKi), PARAMETER :: EddAmbT2N13D3 = 6420 - INTEGER(IntKi), PARAMETER :: EddAmbT2N13D4 = 6421 - INTEGER(IntKi), PARAMETER :: EddAmbT2N13D5 = 6422 - INTEGER(IntKi), PARAMETER :: EddAmbT2N13D6 = 6423 - INTEGER(IntKi), PARAMETER :: EddAmbT2N13D7 = 6424 - INTEGER(IntKi), PARAMETER :: EddAmbT2N13D8 = 6425 - INTEGER(IntKi), PARAMETER :: EddAmbT2N13D9 = 6426 - INTEGER(IntKi), PARAMETER :: EddAmbT2N14D1 = 6427 - INTEGER(IntKi), PARAMETER :: EddAmbT2N14D2 = 6428 - INTEGER(IntKi), PARAMETER :: EddAmbT2N14D3 = 6429 - INTEGER(IntKi), PARAMETER :: EddAmbT2N14D4 = 6430 - INTEGER(IntKi), PARAMETER :: EddAmbT2N14D5 = 6431 - INTEGER(IntKi), PARAMETER :: EddAmbT2N14D6 = 6432 - INTEGER(IntKi), PARAMETER :: EddAmbT2N14D7 = 6433 - INTEGER(IntKi), PARAMETER :: EddAmbT2N14D8 = 6434 - INTEGER(IntKi), PARAMETER :: EddAmbT2N14D9 = 6435 - INTEGER(IntKi), PARAMETER :: EddAmbT2N15D1 = 6436 - INTEGER(IntKi), PARAMETER :: EddAmbT2N15D2 = 6437 - INTEGER(IntKi), PARAMETER :: EddAmbT2N15D3 = 6438 - INTEGER(IntKi), PARAMETER :: EddAmbT2N15D4 = 6439 - INTEGER(IntKi), PARAMETER :: EddAmbT2N15D5 = 6440 - INTEGER(IntKi), PARAMETER :: EddAmbT2N15D6 = 6441 - INTEGER(IntKi), PARAMETER :: EddAmbT2N15D7 = 6442 - INTEGER(IntKi), PARAMETER :: EddAmbT2N15D8 = 6443 - INTEGER(IntKi), PARAMETER :: EddAmbT2N15D9 = 6444 - INTEGER(IntKi), PARAMETER :: EddAmbT2N16D1 = 6445 - INTEGER(IntKi), PARAMETER :: EddAmbT2N16D2 = 6446 - INTEGER(IntKi), PARAMETER :: EddAmbT2N16D3 = 6447 - INTEGER(IntKi), PARAMETER :: EddAmbT2N16D4 = 6448 - INTEGER(IntKi), PARAMETER :: EddAmbT2N16D5 = 6449 - INTEGER(IntKi), PARAMETER :: EddAmbT2N16D6 = 6450 - INTEGER(IntKi), PARAMETER :: EddAmbT2N16D7 = 6451 - INTEGER(IntKi), PARAMETER :: EddAmbT2N16D8 = 6452 - INTEGER(IntKi), PARAMETER :: EddAmbT2N16D9 = 6453 - INTEGER(IntKi), PARAMETER :: EddAmbT2N17D1 = 6454 - INTEGER(IntKi), PARAMETER :: EddAmbT2N17D2 = 6455 - INTEGER(IntKi), PARAMETER :: EddAmbT2N17D3 = 6456 - INTEGER(IntKi), PARAMETER :: EddAmbT2N17D4 = 6457 - INTEGER(IntKi), PARAMETER :: EddAmbT2N17D5 = 6458 - INTEGER(IntKi), PARAMETER :: EddAmbT2N17D6 = 6459 - INTEGER(IntKi), PARAMETER :: EddAmbT2N17D7 = 6460 - INTEGER(IntKi), PARAMETER :: EddAmbT2N17D8 = 6461 - INTEGER(IntKi), PARAMETER :: EddAmbT2N17D9 = 6462 - INTEGER(IntKi), PARAMETER :: EddAmbT2N18D1 = 6463 - INTEGER(IntKi), PARAMETER :: EddAmbT2N18D2 = 6464 - INTEGER(IntKi), PARAMETER :: EddAmbT2N18D3 = 6465 - INTEGER(IntKi), PARAMETER :: EddAmbT2N18D4 = 6466 - INTEGER(IntKi), PARAMETER :: EddAmbT2N18D5 = 6467 - INTEGER(IntKi), PARAMETER :: EddAmbT2N18D6 = 6468 - INTEGER(IntKi), PARAMETER :: EddAmbT2N18D7 = 6469 - INTEGER(IntKi), PARAMETER :: EddAmbT2N18D8 = 6470 - INTEGER(IntKi), PARAMETER :: EddAmbT2N18D9 = 6471 - INTEGER(IntKi), PARAMETER :: EddAmbT2N19D1 = 6472 - INTEGER(IntKi), PARAMETER :: EddAmbT2N19D2 = 6473 - INTEGER(IntKi), PARAMETER :: EddAmbT2N19D3 = 6474 - INTEGER(IntKi), PARAMETER :: EddAmbT2N19D4 = 6475 - INTEGER(IntKi), PARAMETER :: EddAmbT2N19D5 = 6476 - INTEGER(IntKi), PARAMETER :: EddAmbT2N19D6 = 6477 - INTEGER(IntKi), PARAMETER :: EddAmbT2N19D7 = 6478 - INTEGER(IntKi), PARAMETER :: EddAmbT2N19D8 = 6479 - INTEGER(IntKi), PARAMETER :: EddAmbT2N19D9 = 6480 - INTEGER(IntKi), PARAMETER :: EddAmbT2N20D1 = 6481 - INTEGER(IntKi), PARAMETER :: EddAmbT2N20D2 = 6482 - INTEGER(IntKi), PARAMETER :: EddAmbT2N20D3 = 6483 - INTEGER(IntKi), PARAMETER :: EddAmbT2N20D4 = 6484 - INTEGER(IntKi), PARAMETER :: EddAmbT2N20D5 = 6485 - INTEGER(IntKi), PARAMETER :: EddAmbT2N20D6 = 6486 - INTEGER(IntKi), PARAMETER :: EddAmbT2N20D7 = 6487 - INTEGER(IntKi), PARAMETER :: EddAmbT2N20D8 = 6488 - INTEGER(IntKi), PARAMETER :: EddAmbT2N20D9 = 6489 - INTEGER(IntKi), PARAMETER :: EddAmbT3N01D1 = 6490 - INTEGER(IntKi), PARAMETER :: EddAmbT3N01D2 = 6491 - INTEGER(IntKi), PARAMETER :: EddAmbT3N01D3 = 6492 - INTEGER(IntKi), PARAMETER :: EddAmbT3N01D4 = 6493 - INTEGER(IntKi), PARAMETER :: EddAmbT3N01D5 = 6494 - INTEGER(IntKi), PARAMETER :: EddAmbT3N01D6 = 6495 - INTEGER(IntKi), PARAMETER :: EddAmbT3N01D7 = 6496 - INTEGER(IntKi), PARAMETER :: EddAmbT3N01D8 = 6497 - INTEGER(IntKi), PARAMETER :: EddAmbT3N01D9 = 6498 - INTEGER(IntKi), PARAMETER :: EddAmbT3N02D1 = 6499 - INTEGER(IntKi), PARAMETER :: EddAmbT3N02D2 = 6500 - INTEGER(IntKi), PARAMETER :: EddAmbT3N02D3 = 6501 - INTEGER(IntKi), PARAMETER :: EddAmbT3N02D4 = 6502 - INTEGER(IntKi), PARAMETER :: EddAmbT3N02D5 = 6503 - INTEGER(IntKi), PARAMETER :: EddAmbT3N02D6 = 6504 - INTEGER(IntKi), PARAMETER :: EddAmbT3N02D7 = 6505 - INTEGER(IntKi), PARAMETER :: EddAmbT3N02D8 = 6506 - INTEGER(IntKi), PARAMETER :: EddAmbT3N02D9 = 6507 - INTEGER(IntKi), PARAMETER :: EddAmbT3N03D1 = 6508 - INTEGER(IntKi), PARAMETER :: EddAmbT3N03D2 = 6509 - INTEGER(IntKi), PARAMETER :: EddAmbT3N03D3 = 6510 - INTEGER(IntKi), PARAMETER :: EddAmbT3N03D4 = 6511 - INTEGER(IntKi), PARAMETER :: EddAmbT3N03D5 = 6512 - INTEGER(IntKi), PARAMETER :: EddAmbT3N03D6 = 6513 - INTEGER(IntKi), PARAMETER :: EddAmbT3N03D7 = 6514 - INTEGER(IntKi), PARAMETER :: EddAmbT3N03D8 = 6515 - INTEGER(IntKi), PARAMETER :: EddAmbT3N03D9 = 6516 - INTEGER(IntKi), PARAMETER :: EddAmbT3N04D1 = 6517 - INTEGER(IntKi), PARAMETER :: EddAmbT3N04D2 = 6518 - INTEGER(IntKi), PARAMETER :: EddAmbT3N04D3 = 6519 - INTEGER(IntKi), PARAMETER :: EddAmbT3N04D4 = 6520 - INTEGER(IntKi), PARAMETER :: EddAmbT3N04D5 = 6521 - INTEGER(IntKi), PARAMETER :: EddAmbT3N04D6 = 6522 - INTEGER(IntKi), PARAMETER :: EddAmbT3N04D7 = 6523 - INTEGER(IntKi), PARAMETER :: EddAmbT3N04D8 = 6524 - INTEGER(IntKi), PARAMETER :: EddAmbT3N04D9 = 6525 - INTEGER(IntKi), PARAMETER :: EddAmbT3N05D1 = 6526 - INTEGER(IntKi), PARAMETER :: EddAmbT3N05D2 = 6527 - INTEGER(IntKi), PARAMETER :: EddAmbT3N05D3 = 6528 - INTEGER(IntKi), PARAMETER :: EddAmbT3N05D4 = 6529 - INTEGER(IntKi), PARAMETER :: EddAmbT3N05D5 = 6530 - INTEGER(IntKi), PARAMETER :: EddAmbT3N05D6 = 6531 - INTEGER(IntKi), PARAMETER :: EddAmbT3N05D7 = 6532 - INTEGER(IntKi), PARAMETER :: EddAmbT3N05D8 = 6533 - INTEGER(IntKi), PARAMETER :: EddAmbT3N05D9 = 6534 - INTEGER(IntKi), PARAMETER :: EddAmbT3N06D1 = 6535 - INTEGER(IntKi), PARAMETER :: EddAmbT3N06D2 = 6536 - INTEGER(IntKi), PARAMETER :: EddAmbT3N06D3 = 6537 - INTEGER(IntKi), PARAMETER :: EddAmbT3N06D4 = 6538 - INTEGER(IntKi), PARAMETER :: EddAmbT3N06D5 = 6539 - INTEGER(IntKi), PARAMETER :: EddAmbT3N06D6 = 6540 - INTEGER(IntKi), PARAMETER :: EddAmbT3N06D7 = 6541 - INTEGER(IntKi), PARAMETER :: EddAmbT3N06D8 = 6542 - INTEGER(IntKi), PARAMETER :: EddAmbT3N06D9 = 6543 - INTEGER(IntKi), PARAMETER :: EddAmbT3N07D1 = 6544 - INTEGER(IntKi), PARAMETER :: EddAmbT3N07D2 = 6545 - INTEGER(IntKi), PARAMETER :: EddAmbT3N07D3 = 6546 - INTEGER(IntKi), PARAMETER :: EddAmbT3N07D4 = 6547 - INTEGER(IntKi), PARAMETER :: EddAmbT3N07D5 = 6548 - INTEGER(IntKi), PARAMETER :: EddAmbT3N07D6 = 6549 - INTEGER(IntKi), PARAMETER :: EddAmbT3N07D7 = 6550 - INTEGER(IntKi), PARAMETER :: EddAmbT3N07D8 = 6551 - INTEGER(IntKi), PARAMETER :: EddAmbT3N07D9 = 6552 - INTEGER(IntKi), PARAMETER :: EddAmbT3N08D1 = 6553 - INTEGER(IntKi), PARAMETER :: EddAmbT3N08D2 = 6554 - INTEGER(IntKi), PARAMETER :: EddAmbT3N08D3 = 6555 - INTEGER(IntKi), PARAMETER :: EddAmbT3N08D4 = 6556 - INTEGER(IntKi), PARAMETER :: EddAmbT3N08D5 = 6557 - INTEGER(IntKi), PARAMETER :: EddAmbT3N08D6 = 6558 - INTEGER(IntKi), PARAMETER :: EddAmbT3N08D7 = 6559 - INTEGER(IntKi), PARAMETER :: EddAmbT3N08D8 = 6560 - INTEGER(IntKi), PARAMETER :: EddAmbT3N08D9 = 6561 - INTEGER(IntKi), PARAMETER :: EddAmbT3N09D1 = 6562 - INTEGER(IntKi), PARAMETER :: EddAmbT3N09D2 = 6563 - INTEGER(IntKi), PARAMETER :: EddAmbT3N09D3 = 6564 - INTEGER(IntKi), PARAMETER :: EddAmbT3N09D4 = 6565 - INTEGER(IntKi), PARAMETER :: EddAmbT3N09D5 = 6566 - INTEGER(IntKi), PARAMETER :: EddAmbT3N09D6 = 6567 - INTEGER(IntKi), PARAMETER :: EddAmbT3N09D7 = 6568 - INTEGER(IntKi), PARAMETER :: EddAmbT3N09D8 = 6569 - INTEGER(IntKi), PARAMETER :: EddAmbT3N09D9 = 6570 - INTEGER(IntKi), PARAMETER :: EddAmbT3N10D1 = 6571 - INTEGER(IntKi), PARAMETER :: EddAmbT3N10D2 = 6572 - INTEGER(IntKi), PARAMETER :: EddAmbT3N10D3 = 6573 - INTEGER(IntKi), PARAMETER :: EddAmbT3N10D4 = 6574 - INTEGER(IntKi), PARAMETER :: EddAmbT3N10D5 = 6575 - INTEGER(IntKi), PARAMETER :: EddAmbT3N10D6 = 6576 - INTEGER(IntKi), PARAMETER :: EddAmbT3N10D7 = 6577 - INTEGER(IntKi), PARAMETER :: EddAmbT3N10D8 = 6578 - INTEGER(IntKi), PARAMETER :: EddAmbT3N10D9 = 6579 - INTEGER(IntKi), PARAMETER :: EddAmbT3N11D1 = 6580 - INTEGER(IntKi), PARAMETER :: EddAmbT3N11D2 = 6581 - INTEGER(IntKi), PARAMETER :: EddAmbT3N11D3 = 6582 - INTEGER(IntKi), PARAMETER :: EddAmbT3N11D4 = 6583 - INTEGER(IntKi), PARAMETER :: EddAmbT3N11D5 = 6584 - INTEGER(IntKi), PARAMETER :: EddAmbT3N11D6 = 6585 - INTEGER(IntKi), PARAMETER :: EddAmbT3N11D7 = 6586 - INTEGER(IntKi), PARAMETER :: EddAmbT3N11D8 = 6587 - INTEGER(IntKi), PARAMETER :: EddAmbT3N11D9 = 6588 - INTEGER(IntKi), PARAMETER :: EddAmbT3N12D1 = 6589 - INTEGER(IntKi), PARAMETER :: EddAmbT3N12D2 = 6590 - INTEGER(IntKi), PARAMETER :: EddAmbT3N12D3 = 6591 - INTEGER(IntKi), PARAMETER :: EddAmbT3N12D4 = 6592 - INTEGER(IntKi), PARAMETER :: EddAmbT3N12D5 = 6593 - INTEGER(IntKi), PARAMETER :: EddAmbT3N12D6 = 6594 - INTEGER(IntKi), PARAMETER :: EddAmbT3N12D7 = 6595 - INTEGER(IntKi), PARAMETER :: EddAmbT3N12D8 = 6596 - INTEGER(IntKi), PARAMETER :: EddAmbT3N12D9 = 6597 - INTEGER(IntKi), PARAMETER :: EddAmbT3N13D1 = 6598 - INTEGER(IntKi), PARAMETER :: EddAmbT3N13D2 = 6599 - INTEGER(IntKi), PARAMETER :: EddAmbT3N13D3 = 6600 - INTEGER(IntKi), PARAMETER :: EddAmbT3N13D4 = 6601 - INTEGER(IntKi), PARAMETER :: EddAmbT3N13D5 = 6602 - INTEGER(IntKi), PARAMETER :: EddAmbT3N13D6 = 6603 - INTEGER(IntKi), PARAMETER :: EddAmbT3N13D7 = 6604 - INTEGER(IntKi), PARAMETER :: EddAmbT3N13D8 = 6605 - INTEGER(IntKi), PARAMETER :: EddAmbT3N13D9 = 6606 - INTEGER(IntKi), PARAMETER :: EddAmbT3N14D1 = 6607 - INTEGER(IntKi), PARAMETER :: EddAmbT3N14D2 = 6608 - INTEGER(IntKi), PARAMETER :: EddAmbT3N14D3 = 6609 - INTEGER(IntKi), PARAMETER :: EddAmbT3N14D4 = 6610 - INTEGER(IntKi), PARAMETER :: EddAmbT3N14D5 = 6611 - INTEGER(IntKi), PARAMETER :: EddAmbT3N14D6 = 6612 - INTEGER(IntKi), PARAMETER :: EddAmbT3N14D7 = 6613 - INTEGER(IntKi), PARAMETER :: EddAmbT3N14D8 = 6614 - INTEGER(IntKi), PARAMETER :: EddAmbT3N14D9 = 6615 - INTEGER(IntKi), PARAMETER :: EddAmbT3N15D1 = 6616 - INTEGER(IntKi), PARAMETER :: EddAmbT3N15D2 = 6617 - INTEGER(IntKi), PARAMETER :: EddAmbT3N15D3 = 6618 - INTEGER(IntKi), PARAMETER :: EddAmbT3N15D4 = 6619 - INTEGER(IntKi), PARAMETER :: EddAmbT3N15D5 = 6620 - INTEGER(IntKi), PARAMETER :: EddAmbT3N15D6 = 6621 - INTEGER(IntKi), PARAMETER :: EddAmbT3N15D7 = 6622 - INTEGER(IntKi), PARAMETER :: EddAmbT3N15D8 = 6623 - INTEGER(IntKi), PARAMETER :: EddAmbT3N15D9 = 6624 - INTEGER(IntKi), PARAMETER :: EddAmbT3N16D1 = 6625 - INTEGER(IntKi), PARAMETER :: EddAmbT3N16D2 = 6626 - INTEGER(IntKi), PARAMETER :: EddAmbT3N16D3 = 6627 - INTEGER(IntKi), PARAMETER :: EddAmbT3N16D4 = 6628 - INTEGER(IntKi), PARAMETER :: EddAmbT3N16D5 = 6629 - INTEGER(IntKi), PARAMETER :: EddAmbT3N16D6 = 6630 - INTEGER(IntKi), PARAMETER :: EddAmbT3N16D7 = 6631 - INTEGER(IntKi), PARAMETER :: EddAmbT3N16D8 = 6632 - INTEGER(IntKi), PARAMETER :: EddAmbT3N16D9 = 6633 - INTEGER(IntKi), PARAMETER :: EddAmbT3N17D1 = 6634 - INTEGER(IntKi), PARAMETER :: EddAmbT3N17D2 = 6635 - INTEGER(IntKi), PARAMETER :: EddAmbT3N17D3 = 6636 - INTEGER(IntKi), PARAMETER :: EddAmbT3N17D4 = 6637 - INTEGER(IntKi), PARAMETER :: EddAmbT3N17D5 = 6638 - INTEGER(IntKi), PARAMETER :: EddAmbT3N17D6 = 6639 - INTEGER(IntKi), PARAMETER :: EddAmbT3N17D7 = 6640 - INTEGER(IntKi), PARAMETER :: EddAmbT3N17D8 = 6641 - INTEGER(IntKi), PARAMETER :: EddAmbT3N17D9 = 6642 - INTEGER(IntKi), PARAMETER :: EddAmbT3N18D1 = 6643 - INTEGER(IntKi), PARAMETER :: EddAmbT3N18D2 = 6644 - INTEGER(IntKi), PARAMETER :: EddAmbT3N18D3 = 6645 - INTEGER(IntKi), PARAMETER :: EddAmbT3N18D4 = 6646 - INTEGER(IntKi), PARAMETER :: EddAmbT3N18D5 = 6647 - INTEGER(IntKi), PARAMETER :: EddAmbT3N18D6 = 6648 - INTEGER(IntKi), PARAMETER :: EddAmbT3N18D7 = 6649 - INTEGER(IntKi), PARAMETER :: EddAmbT3N18D8 = 6650 - INTEGER(IntKi), PARAMETER :: EddAmbT3N18D9 = 6651 - INTEGER(IntKi), PARAMETER :: EddAmbT3N19D1 = 6652 - INTEGER(IntKi), PARAMETER :: EddAmbT3N19D2 = 6653 - INTEGER(IntKi), PARAMETER :: EddAmbT3N19D3 = 6654 - INTEGER(IntKi), PARAMETER :: EddAmbT3N19D4 = 6655 - INTEGER(IntKi), PARAMETER :: EddAmbT3N19D5 = 6656 - INTEGER(IntKi), PARAMETER :: EddAmbT3N19D6 = 6657 - INTEGER(IntKi), PARAMETER :: EddAmbT3N19D7 = 6658 - INTEGER(IntKi), PARAMETER :: EddAmbT3N19D8 = 6659 - INTEGER(IntKi), PARAMETER :: EddAmbT3N19D9 = 6660 - INTEGER(IntKi), PARAMETER :: EddAmbT3N20D1 = 6661 - INTEGER(IntKi), PARAMETER :: EddAmbT3N20D2 = 6662 - INTEGER(IntKi), PARAMETER :: EddAmbT3N20D3 = 6663 - INTEGER(IntKi), PARAMETER :: EddAmbT3N20D4 = 6664 - INTEGER(IntKi), PARAMETER :: EddAmbT3N20D5 = 6665 - INTEGER(IntKi), PARAMETER :: EddAmbT3N20D6 = 6666 - INTEGER(IntKi), PARAMETER :: EddAmbT3N20D7 = 6667 - INTEGER(IntKi), PARAMETER :: EddAmbT3N20D8 = 6668 - INTEGER(IntKi), PARAMETER :: EddAmbT3N20D9 = 6669 - INTEGER(IntKi), PARAMETER :: EddAmbT4N01D1 = 6670 - INTEGER(IntKi), PARAMETER :: EddAmbT4N01D2 = 6671 - INTEGER(IntKi), PARAMETER :: EddAmbT4N01D3 = 6672 - INTEGER(IntKi), PARAMETER :: EddAmbT4N01D4 = 6673 - INTEGER(IntKi), PARAMETER :: EddAmbT4N01D5 = 6674 - INTEGER(IntKi), PARAMETER :: EddAmbT4N01D6 = 6675 - INTEGER(IntKi), PARAMETER :: EddAmbT4N01D7 = 6676 - INTEGER(IntKi), PARAMETER :: EddAmbT4N01D8 = 6677 - INTEGER(IntKi), PARAMETER :: EddAmbT4N01D9 = 6678 - INTEGER(IntKi), PARAMETER :: EddAmbT4N02D1 = 6679 - INTEGER(IntKi), PARAMETER :: EddAmbT4N02D2 = 6680 - INTEGER(IntKi), PARAMETER :: EddAmbT4N02D3 = 6681 - INTEGER(IntKi), PARAMETER :: EddAmbT4N02D4 = 6682 - INTEGER(IntKi), PARAMETER :: EddAmbT4N02D5 = 6683 - INTEGER(IntKi), PARAMETER :: EddAmbT4N02D6 = 6684 - INTEGER(IntKi), PARAMETER :: EddAmbT4N02D7 = 6685 - INTEGER(IntKi), PARAMETER :: EddAmbT4N02D8 = 6686 - INTEGER(IntKi), PARAMETER :: EddAmbT4N02D9 = 6687 - INTEGER(IntKi), PARAMETER :: EddAmbT4N03D1 = 6688 - INTEGER(IntKi), PARAMETER :: EddAmbT4N03D2 = 6689 - INTEGER(IntKi), PARAMETER :: EddAmbT4N03D3 = 6690 - INTEGER(IntKi), PARAMETER :: EddAmbT4N03D4 = 6691 - INTEGER(IntKi), PARAMETER :: EddAmbT4N03D5 = 6692 - INTEGER(IntKi), PARAMETER :: EddAmbT4N03D6 = 6693 - INTEGER(IntKi), PARAMETER :: EddAmbT4N03D7 = 6694 - INTEGER(IntKi), PARAMETER :: EddAmbT4N03D8 = 6695 - INTEGER(IntKi), PARAMETER :: EddAmbT4N03D9 = 6696 - INTEGER(IntKi), PARAMETER :: EddAmbT4N04D1 = 6697 - INTEGER(IntKi), PARAMETER :: EddAmbT4N04D2 = 6698 - INTEGER(IntKi), PARAMETER :: EddAmbT4N04D3 = 6699 - INTEGER(IntKi), PARAMETER :: EddAmbT4N04D4 = 6700 - INTEGER(IntKi), PARAMETER :: EddAmbT4N04D5 = 6701 - INTEGER(IntKi), PARAMETER :: EddAmbT4N04D6 = 6702 - INTEGER(IntKi), PARAMETER :: EddAmbT4N04D7 = 6703 - INTEGER(IntKi), PARAMETER :: EddAmbT4N04D8 = 6704 - INTEGER(IntKi), PARAMETER :: EddAmbT4N04D9 = 6705 - INTEGER(IntKi), PARAMETER :: EddAmbT4N05D1 = 6706 - INTEGER(IntKi), PARAMETER :: EddAmbT4N05D2 = 6707 - INTEGER(IntKi), PARAMETER :: EddAmbT4N05D3 = 6708 - INTEGER(IntKi), PARAMETER :: EddAmbT4N05D4 = 6709 - INTEGER(IntKi), PARAMETER :: EddAmbT4N05D5 = 6710 - INTEGER(IntKi), PARAMETER :: EddAmbT4N05D6 = 6711 - INTEGER(IntKi), PARAMETER :: EddAmbT4N05D7 = 6712 - INTEGER(IntKi), PARAMETER :: EddAmbT4N05D8 = 6713 - INTEGER(IntKi), PARAMETER :: EddAmbT4N05D9 = 6714 - INTEGER(IntKi), PARAMETER :: EddAmbT4N06D1 = 6715 - INTEGER(IntKi), PARAMETER :: EddAmbT4N06D2 = 6716 - INTEGER(IntKi), PARAMETER :: EddAmbT4N06D3 = 6717 - INTEGER(IntKi), PARAMETER :: EddAmbT4N06D4 = 6718 - INTEGER(IntKi), PARAMETER :: EddAmbT4N06D5 = 6719 - INTEGER(IntKi), PARAMETER :: EddAmbT4N06D6 = 6720 - INTEGER(IntKi), PARAMETER :: EddAmbT4N06D7 = 6721 - INTEGER(IntKi), PARAMETER :: EddAmbT4N06D8 = 6722 - INTEGER(IntKi), PARAMETER :: EddAmbT4N06D9 = 6723 - INTEGER(IntKi), PARAMETER :: EddAmbT4N07D1 = 6724 - INTEGER(IntKi), PARAMETER :: EddAmbT4N07D2 = 6725 - INTEGER(IntKi), PARAMETER :: EddAmbT4N07D3 = 6726 - INTEGER(IntKi), PARAMETER :: EddAmbT4N07D4 = 6727 - INTEGER(IntKi), PARAMETER :: EddAmbT4N07D5 = 6728 - INTEGER(IntKi), PARAMETER :: EddAmbT4N07D6 = 6729 - INTEGER(IntKi), PARAMETER :: EddAmbT4N07D7 = 6730 - INTEGER(IntKi), PARAMETER :: EddAmbT4N07D8 = 6731 - INTEGER(IntKi), PARAMETER :: EddAmbT4N07D9 = 6732 - INTEGER(IntKi), PARAMETER :: EddAmbT4N08D1 = 6733 - INTEGER(IntKi), PARAMETER :: EddAmbT4N08D2 = 6734 - INTEGER(IntKi), PARAMETER :: EddAmbT4N08D3 = 6735 - INTEGER(IntKi), PARAMETER :: EddAmbT4N08D4 = 6736 - INTEGER(IntKi), PARAMETER :: EddAmbT4N08D5 = 6737 - INTEGER(IntKi), PARAMETER :: EddAmbT4N08D6 = 6738 - INTEGER(IntKi), PARAMETER :: EddAmbT4N08D7 = 6739 - INTEGER(IntKi), PARAMETER :: EddAmbT4N08D8 = 6740 - INTEGER(IntKi), PARAMETER :: EddAmbT4N08D9 = 6741 - INTEGER(IntKi), PARAMETER :: EddAmbT4N09D1 = 6742 - INTEGER(IntKi), PARAMETER :: EddAmbT4N09D2 = 6743 - INTEGER(IntKi), PARAMETER :: EddAmbT4N09D3 = 6744 - INTEGER(IntKi), PARAMETER :: EddAmbT4N09D4 = 6745 - INTEGER(IntKi), PARAMETER :: EddAmbT4N09D5 = 6746 - INTEGER(IntKi), PARAMETER :: EddAmbT4N09D6 = 6747 - INTEGER(IntKi), PARAMETER :: EddAmbT4N09D7 = 6748 - INTEGER(IntKi), PARAMETER :: EddAmbT4N09D8 = 6749 - INTEGER(IntKi), PARAMETER :: EddAmbT4N09D9 = 6750 - INTEGER(IntKi), PARAMETER :: EddAmbT4N10D1 = 6751 - INTEGER(IntKi), PARAMETER :: EddAmbT4N10D2 = 6752 - INTEGER(IntKi), PARAMETER :: EddAmbT4N10D3 = 6753 - INTEGER(IntKi), PARAMETER :: EddAmbT4N10D4 = 6754 - INTEGER(IntKi), PARAMETER :: EddAmbT4N10D5 = 6755 - INTEGER(IntKi), PARAMETER :: EddAmbT4N10D6 = 6756 - INTEGER(IntKi), PARAMETER :: EddAmbT4N10D7 = 6757 - INTEGER(IntKi), PARAMETER :: EddAmbT4N10D8 = 6758 - INTEGER(IntKi), PARAMETER :: EddAmbT4N10D9 = 6759 - INTEGER(IntKi), PARAMETER :: EddAmbT4N11D1 = 6760 - INTEGER(IntKi), PARAMETER :: EddAmbT4N11D2 = 6761 - INTEGER(IntKi), PARAMETER :: EddAmbT4N11D3 = 6762 - INTEGER(IntKi), PARAMETER :: EddAmbT4N11D4 = 6763 - INTEGER(IntKi), PARAMETER :: EddAmbT4N11D5 = 6764 - INTEGER(IntKi), PARAMETER :: EddAmbT4N11D6 = 6765 - INTEGER(IntKi), PARAMETER :: EddAmbT4N11D7 = 6766 - INTEGER(IntKi), PARAMETER :: EddAmbT4N11D8 = 6767 - INTEGER(IntKi), PARAMETER :: EddAmbT4N11D9 = 6768 - INTEGER(IntKi), PARAMETER :: EddAmbT4N12D1 = 6769 - INTEGER(IntKi), PARAMETER :: EddAmbT4N12D2 = 6770 - INTEGER(IntKi), PARAMETER :: EddAmbT4N12D3 = 6771 - INTEGER(IntKi), PARAMETER :: EddAmbT4N12D4 = 6772 - INTEGER(IntKi), PARAMETER :: EddAmbT4N12D5 = 6773 - INTEGER(IntKi), PARAMETER :: EddAmbT4N12D6 = 6774 - INTEGER(IntKi), PARAMETER :: EddAmbT4N12D7 = 6775 - INTEGER(IntKi), PARAMETER :: EddAmbT4N12D8 = 6776 - INTEGER(IntKi), PARAMETER :: EddAmbT4N12D9 = 6777 - INTEGER(IntKi), PARAMETER :: EddAmbT4N13D1 = 6778 - INTEGER(IntKi), PARAMETER :: EddAmbT4N13D2 = 6779 - INTEGER(IntKi), PARAMETER :: EddAmbT4N13D3 = 6780 - INTEGER(IntKi), PARAMETER :: EddAmbT4N13D4 = 6781 - INTEGER(IntKi), PARAMETER :: EddAmbT4N13D5 = 6782 - INTEGER(IntKi), PARAMETER :: EddAmbT4N13D6 = 6783 - INTEGER(IntKi), PARAMETER :: EddAmbT4N13D7 = 6784 - INTEGER(IntKi), PARAMETER :: EddAmbT4N13D8 = 6785 - INTEGER(IntKi), PARAMETER :: EddAmbT4N13D9 = 6786 - INTEGER(IntKi), PARAMETER :: EddAmbT4N14D1 = 6787 - INTEGER(IntKi), PARAMETER :: EddAmbT4N14D2 = 6788 - INTEGER(IntKi), PARAMETER :: EddAmbT4N14D3 = 6789 - INTEGER(IntKi), PARAMETER :: EddAmbT4N14D4 = 6790 - INTEGER(IntKi), PARAMETER :: EddAmbT4N14D5 = 6791 - INTEGER(IntKi), PARAMETER :: EddAmbT4N14D6 = 6792 - INTEGER(IntKi), PARAMETER :: EddAmbT4N14D7 = 6793 - INTEGER(IntKi), PARAMETER :: EddAmbT4N14D8 = 6794 - INTEGER(IntKi), PARAMETER :: EddAmbT4N14D9 = 6795 - INTEGER(IntKi), PARAMETER :: EddAmbT4N15D1 = 6796 - INTEGER(IntKi), PARAMETER :: EddAmbT4N15D2 = 6797 - INTEGER(IntKi), PARAMETER :: EddAmbT4N15D3 = 6798 - INTEGER(IntKi), PARAMETER :: EddAmbT4N15D4 = 6799 - INTEGER(IntKi), PARAMETER :: EddAmbT4N15D5 = 6800 - INTEGER(IntKi), PARAMETER :: EddAmbT4N15D6 = 6801 - INTEGER(IntKi), PARAMETER :: EddAmbT4N15D7 = 6802 - INTEGER(IntKi), PARAMETER :: EddAmbT4N15D8 = 6803 - INTEGER(IntKi), PARAMETER :: EddAmbT4N15D9 = 6804 - INTEGER(IntKi), PARAMETER :: EddAmbT4N16D1 = 6805 - INTEGER(IntKi), PARAMETER :: EddAmbT4N16D2 = 6806 - INTEGER(IntKi), PARAMETER :: EddAmbT4N16D3 = 6807 - INTEGER(IntKi), PARAMETER :: EddAmbT4N16D4 = 6808 - INTEGER(IntKi), PARAMETER :: EddAmbT4N16D5 = 6809 - INTEGER(IntKi), PARAMETER :: EddAmbT4N16D6 = 6810 - INTEGER(IntKi), PARAMETER :: EddAmbT4N16D7 = 6811 - INTEGER(IntKi), PARAMETER :: EddAmbT4N16D8 = 6812 - INTEGER(IntKi), PARAMETER :: EddAmbT4N16D9 = 6813 - INTEGER(IntKi), PARAMETER :: EddAmbT4N17D1 = 6814 - INTEGER(IntKi), PARAMETER :: EddAmbT4N17D2 = 6815 - INTEGER(IntKi), PARAMETER :: EddAmbT4N17D3 = 6816 - INTEGER(IntKi), PARAMETER :: EddAmbT4N17D4 = 6817 - INTEGER(IntKi), PARAMETER :: EddAmbT4N17D5 = 6818 - INTEGER(IntKi), PARAMETER :: EddAmbT4N17D6 = 6819 - INTEGER(IntKi), PARAMETER :: EddAmbT4N17D7 = 6820 - INTEGER(IntKi), PARAMETER :: EddAmbT4N17D8 = 6821 - INTEGER(IntKi), PARAMETER :: EddAmbT4N17D9 = 6822 - INTEGER(IntKi), PARAMETER :: EddAmbT4N18D1 = 6823 - INTEGER(IntKi), PARAMETER :: EddAmbT4N18D2 = 6824 - INTEGER(IntKi), PARAMETER :: EddAmbT4N18D3 = 6825 - INTEGER(IntKi), PARAMETER :: EddAmbT4N18D4 = 6826 - INTEGER(IntKi), PARAMETER :: EddAmbT4N18D5 = 6827 - INTEGER(IntKi), PARAMETER :: EddAmbT4N18D6 = 6828 - INTEGER(IntKi), PARAMETER :: EddAmbT4N18D7 = 6829 - INTEGER(IntKi), PARAMETER :: EddAmbT4N18D8 = 6830 - INTEGER(IntKi), PARAMETER :: EddAmbT4N18D9 = 6831 - INTEGER(IntKi), PARAMETER :: EddAmbT4N19D1 = 6832 - INTEGER(IntKi), PARAMETER :: EddAmbT4N19D2 = 6833 - INTEGER(IntKi), PARAMETER :: EddAmbT4N19D3 = 6834 - INTEGER(IntKi), PARAMETER :: EddAmbT4N19D4 = 6835 - INTEGER(IntKi), PARAMETER :: EddAmbT4N19D5 = 6836 - INTEGER(IntKi), PARAMETER :: EddAmbT4N19D6 = 6837 - INTEGER(IntKi), PARAMETER :: EddAmbT4N19D7 = 6838 - INTEGER(IntKi), PARAMETER :: EddAmbT4N19D8 = 6839 - INTEGER(IntKi), PARAMETER :: EddAmbT4N19D9 = 6840 - INTEGER(IntKi), PARAMETER :: EddAmbT4N20D1 = 6841 - INTEGER(IntKi), PARAMETER :: EddAmbT4N20D2 = 6842 - INTEGER(IntKi), PARAMETER :: EddAmbT4N20D3 = 6843 - INTEGER(IntKi), PARAMETER :: EddAmbT4N20D4 = 6844 - INTEGER(IntKi), PARAMETER :: EddAmbT4N20D5 = 6845 - INTEGER(IntKi), PARAMETER :: EddAmbT4N20D6 = 6846 - INTEGER(IntKi), PARAMETER :: EddAmbT4N20D7 = 6847 - INTEGER(IntKi), PARAMETER :: EddAmbT4N20D8 = 6848 - INTEGER(IntKi), PARAMETER :: EddAmbT4N20D9 = 6849 - INTEGER(IntKi), PARAMETER :: EddAmbT5N01D1 = 6850 - INTEGER(IntKi), PARAMETER :: EddAmbT5N01D2 = 6851 - INTEGER(IntKi), PARAMETER :: EddAmbT5N01D3 = 6852 - INTEGER(IntKi), PARAMETER :: EddAmbT5N01D4 = 6853 - INTEGER(IntKi), PARAMETER :: EddAmbT5N01D5 = 6854 - INTEGER(IntKi), PARAMETER :: EddAmbT5N01D6 = 6855 - INTEGER(IntKi), PARAMETER :: EddAmbT5N01D7 = 6856 - INTEGER(IntKi), PARAMETER :: EddAmbT5N01D8 = 6857 - INTEGER(IntKi), PARAMETER :: EddAmbT5N01D9 = 6858 - INTEGER(IntKi), PARAMETER :: EddAmbT5N02D1 = 6859 - INTEGER(IntKi), PARAMETER :: EddAmbT5N02D2 = 6860 - INTEGER(IntKi), PARAMETER :: EddAmbT5N02D3 = 6861 - INTEGER(IntKi), PARAMETER :: EddAmbT5N02D4 = 6862 - INTEGER(IntKi), PARAMETER :: EddAmbT5N02D5 = 6863 - INTEGER(IntKi), PARAMETER :: EddAmbT5N02D6 = 6864 - INTEGER(IntKi), PARAMETER :: EddAmbT5N02D7 = 6865 - INTEGER(IntKi), PARAMETER :: EddAmbT5N02D8 = 6866 - INTEGER(IntKi), PARAMETER :: EddAmbT5N02D9 = 6867 - INTEGER(IntKi), PARAMETER :: EddAmbT5N03D1 = 6868 - INTEGER(IntKi), PARAMETER :: EddAmbT5N03D2 = 6869 - INTEGER(IntKi), PARAMETER :: EddAmbT5N03D3 = 6870 - INTEGER(IntKi), PARAMETER :: EddAmbT5N03D4 = 6871 - INTEGER(IntKi), PARAMETER :: EddAmbT5N03D5 = 6872 - INTEGER(IntKi), PARAMETER :: EddAmbT5N03D6 = 6873 - INTEGER(IntKi), PARAMETER :: EddAmbT5N03D7 = 6874 - INTEGER(IntKi), PARAMETER :: EddAmbT5N03D8 = 6875 - INTEGER(IntKi), PARAMETER :: EddAmbT5N03D9 = 6876 - INTEGER(IntKi), PARAMETER :: EddAmbT5N04D1 = 6877 - INTEGER(IntKi), PARAMETER :: EddAmbT5N04D2 = 6878 - INTEGER(IntKi), PARAMETER :: EddAmbT5N04D3 = 6879 - INTEGER(IntKi), PARAMETER :: EddAmbT5N04D4 = 6880 - INTEGER(IntKi), PARAMETER :: EddAmbT5N04D5 = 6881 - INTEGER(IntKi), PARAMETER :: EddAmbT5N04D6 = 6882 - INTEGER(IntKi), PARAMETER :: EddAmbT5N04D7 = 6883 - INTEGER(IntKi), PARAMETER :: EddAmbT5N04D8 = 6884 - INTEGER(IntKi), PARAMETER :: EddAmbT5N04D9 = 6885 - INTEGER(IntKi), PARAMETER :: EddAmbT5N05D1 = 6886 - INTEGER(IntKi), PARAMETER :: EddAmbT5N05D2 = 6887 - INTEGER(IntKi), PARAMETER :: EddAmbT5N05D3 = 6888 - INTEGER(IntKi), PARAMETER :: EddAmbT5N05D4 = 6889 - INTEGER(IntKi), PARAMETER :: EddAmbT5N05D5 = 6890 - INTEGER(IntKi), PARAMETER :: EddAmbT5N05D6 = 6891 - INTEGER(IntKi), PARAMETER :: EddAmbT5N05D7 = 6892 - INTEGER(IntKi), PARAMETER :: EddAmbT5N05D8 = 6893 - INTEGER(IntKi), PARAMETER :: EddAmbT5N05D9 = 6894 - INTEGER(IntKi), PARAMETER :: EddAmbT5N06D1 = 6895 - INTEGER(IntKi), PARAMETER :: EddAmbT5N06D2 = 6896 - INTEGER(IntKi), PARAMETER :: EddAmbT5N06D3 = 6897 - INTEGER(IntKi), PARAMETER :: EddAmbT5N06D4 = 6898 - INTEGER(IntKi), PARAMETER :: EddAmbT5N06D5 = 6899 - INTEGER(IntKi), PARAMETER :: EddAmbT5N06D6 = 6900 - INTEGER(IntKi), PARAMETER :: EddAmbT5N06D7 = 6901 - INTEGER(IntKi), PARAMETER :: EddAmbT5N06D8 = 6902 - INTEGER(IntKi), PARAMETER :: EddAmbT5N06D9 = 6903 - INTEGER(IntKi), PARAMETER :: EddAmbT5N07D1 = 6904 - INTEGER(IntKi), PARAMETER :: EddAmbT5N07D2 = 6905 - INTEGER(IntKi), PARAMETER :: EddAmbT5N07D3 = 6906 - INTEGER(IntKi), PARAMETER :: EddAmbT5N07D4 = 6907 - INTEGER(IntKi), PARAMETER :: EddAmbT5N07D5 = 6908 - INTEGER(IntKi), PARAMETER :: EddAmbT5N07D6 = 6909 - INTEGER(IntKi), PARAMETER :: EddAmbT5N07D7 = 6910 - INTEGER(IntKi), PARAMETER :: EddAmbT5N07D8 = 6911 - INTEGER(IntKi), PARAMETER :: EddAmbT5N07D9 = 6912 - INTEGER(IntKi), PARAMETER :: EddAmbT5N08D1 = 6913 - INTEGER(IntKi), PARAMETER :: EddAmbT5N08D2 = 6914 - INTEGER(IntKi), PARAMETER :: EddAmbT5N08D3 = 6915 - INTEGER(IntKi), PARAMETER :: EddAmbT5N08D4 = 6916 - INTEGER(IntKi), PARAMETER :: EddAmbT5N08D5 = 6917 - INTEGER(IntKi), PARAMETER :: EddAmbT5N08D6 = 6918 - INTEGER(IntKi), PARAMETER :: EddAmbT5N08D7 = 6919 - INTEGER(IntKi), PARAMETER :: EddAmbT5N08D8 = 6920 - INTEGER(IntKi), PARAMETER :: EddAmbT5N08D9 = 6921 - INTEGER(IntKi), PARAMETER :: EddAmbT5N09D1 = 6922 - INTEGER(IntKi), PARAMETER :: EddAmbT5N09D2 = 6923 - INTEGER(IntKi), PARAMETER :: EddAmbT5N09D3 = 6924 - INTEGER(IntKi), PARAMETER :: EddAmbT5N09D4 = 6925 - INTEGER(IntKi), PARAMETER :: EddAmbT5N09D5 = 6926 - INTEGER(IntKi), PARAMETER :: EddAmbT5N09D6 = 6927 - INTEGER(IntKi), PARAMETER :: EddAmbT5N09D7 = 6928 - INTEGER(IntKi), PARAMETER :: EddAmbT5N09D8 = 6929 - INTEGER(IntKi), PARAMETER :: EddAmbT5N09D9 = 6930 - INTEGER(IntKi), PARAMETER :: EddAmbT5N10D1 = 6931 - INTEGER(IntKi), PARAMETER :: EddAmbT5N10D2 = 6932 - INTEGER(IntKi), PARAMETER :: EddAmbT5N10D3 = 6933 - INTEGER(IntKi), PARAMETER :: EddAmbT5N10D4 = 6934 - INTEGER(IntKi), PARAMETER :: EddAmbT5N10D5 = 6935 - INTEGER(IntKi), PARAMETER :: EddAmbT5N10D6 = 6936 - INTEGER(IntKi), PARAMETER :: EddAmbT5N10D7 = 6937 - INTEGER(IntKi), PARAMETER :: EddAmbT5N10D8 = 6938 - INTEGER(IntKi), PARAMETER :: EddAmbT5N10D9 = 6939 - INTEGER(IntKi), PARAMETER :: EddAmbT5N11D1 = 6940 - INTEGER(IntKi), PARAMETER :: EddAmbT5N11D2 = 6941 - INTEGER(IntKi), PARAMETER :: EddAmbT5N11D3 = 6942 - INTEGER(IntKi), PARAMETER :: EddAmbT5N11D4 = 6943 - INTEGER(IntKi), PARAMETER :: EddAmbT5N11D5 = 6944 - INTEGER(IntKi), PARAMETER :: EddAmbT5N11D6 = 6945 - INTEGER(IntKi), PARAMETER :: EddAmbT5N11D7 = 6946 - INTEGER(IntKi), PARAMETER :: EddAmbT5N11D8 = 6947 - INTEGER(IntKi), PARAMETER :: EddAmbT5N11D9 = 6948 - INTEGER(IntKi), PARAMETER :: EddAmbT5N12D1 = 6949 - INTEGER(IntKi), PARAMETER :: EddAmbT5N12D2 = 6950 - INTEGER(IntKi), PARAMETER :: EddAmbT5N12D3 = 6951 - INTEGER(IntKi), PARAMETER :: EddAmbT5N12D4 = 6952 - INTEGER(IntKi), PARAMETER :: EddAmbT5N12D5 = 6953 - INTEGER(IntKi), PARAMETER :: EddAmbT5N12D6 = 6954 - INTEGER(IntKi), PARAMETER :: EddAmbT5N12D7 = 6955 - INTEGER(IntKi), PARAMETER :: EddAmbT5N12D8 = 6956 - INTEGER(IntKi), PARAMETER :: EddAmbT5N12D9 = 6957 - INTEGER(IntKi), PARAMETER :: EddAmbT5N13D1 = 6958 - INTEGER(IntKi), PARAMETER :: EddAmbT5N13D2 = 6959 - INTEGER(IntKi), PARAMETER :: EddAmbT5N13D3 = 6960 - INTEGER(IntKi), PARAMETER :: EddAmbT5N13D4 = 6961 - INTEGER(IntKi), PARAMETER :: EddAmbT5N13D5 = 6962 - INTEGER(IntKi), PARAMETER :: EddAmbT5N13D6 = 6963 - INTEGER(IntKi), PARAMETER :: EddAmbT5N13D7 = 6964 - INTEGER(IntKi), PARAMETER :: EddAmbT5N13D8 = 6965 - INTEGER(IntKi), PARAMETER :: EddAmbT5N13D9 = 6966 - INTEGER(IntKi), PARAMETER :: EddAmbT5N14D1 = 6967 - INTEGER(IntKi), PARAMETER :: EddAmbT5N14D2 = 6968 - INTEGER(IntKi), PARAMETER :: EddAmbT5N14D3 = 6969 - INTEGER(IntKi), PARAMETER :: EddAmbT5N14D4 = 6970 - INTEGER(IntKi), PARAMETER :: EddAmbT5N14D5 = 6971 - INTEGER(IntKi), PARAMETER :: EddAmbT5N14D6 = 6972 - INTEGER(IntKi), PARAMETER :: EddAmbT5N14D7 = 6973 - INTEGER(IntKi), PARAMETER :: EddAmbT5N14D8 = 6974 - INTEGER(IntKi), PARAMETER :: EddAmbT5N14D9 = 6975 - INTEGER(IntKi), PARAMETER :: EddAmbT5N15D1 = 6976 - INTEGER(IntKi), PARAMETER :: EddAmbT5N15D2 = 6977 - INTEGER(IntKi), PARAMETER :: EddAmbT5N15D3 = 6978 - INTEGER(IntKi), PARAMETER :: EddAmbT5N15D4 = 6979 - INTEGER(IntKi), PARAMETER :: EddAmbT5N15D5 = 6980 - INTEGER(IntKi), PARAMETER :: EddAmbT5N15D6 = 6981 - INTEGER(IntKi), PARAMETER :: EddAmbT5N15D7 = 6982 - INTEGER(IntKi), PARAMETER :: EddAmbT5N15D8 = 6983 - INTEGER(IntKi), PARAMETER :: EddAmbT5N15D9 = 6984 - INTEGER(IntKi), PARAMETER :: EddAmbT5N16D1 = 6985 - INTEGER(IntKi), PARAMETER :: EddAmbT5N16D2 = 6986 - INTEGER(IntKi), PARAMETER :: EddAmbT5N16D3 = 6987 - INTEGER(IntKi), PARAMETER :: EddAmbT5N16D4 = 6988 - INTEGER(IntKi), PARAMETER :: EddAmbT5N16D5 = 6989 - INTEGER(IntKi), PARAMETER :: EddAmbT5N16D6 = 6990 - INTEGER(IntKi), PARAMETER :: EddAmbT5N16D7 = 6991 - INTEGER(IntKi), PARAMETER :: EddAmbT5N16D8 = 6992 - INTEGER(IntKi), PARAMETER :: EddAmbT5N16D9 = 6993 - INTEGER(IntKi), PARAMETER :: EddAmbT5N17D1 = 6994 - INTEGER(IntKi), PARAMETER :: EddAmbT5N17D2 = 6995 - INTEGER(IntKi), PARAMETER :: EddAmbT5N17D3 = 6996 - INTEGER(IntKi), PARAMETER :: EddAmbT5N17D4 = 6997 - INTEGER(IntKi), PARAMETER :: EddAmbT5N17D5 = 6998 - INTEGER(IntKi), PARAMETER :: EddAmbT5N17D6 = 6999 - INTEGER(IntKi), PARAMETER :: EddAmbT5N17D7 = 7000 - INTEGER(IntKi), PARAMETER :: EddAmbT5N17D8 = 7001 - INTEGER(IntKi), PARAMETER :: EddAmbT5N17D9 = 7002 - INTEGER(IntKi), PARAMETER :: EddAmbT5N18D1 = 7003 - INTEGER(IntKi), PARAMETER :: EddAmbT5N18D2 = 7004 - INTEGER(IntKi), PARAMETER :: EddAmbT5N18D3 = 7005 - INTEGER(IntKi), PARAMETER :: EddAmbT5N18D4 = 7006 - INTEGER(IntKi), PARAMETER :: EddAmbT5N18D5 = 7007 - INTEGER(IntKi), PARAMETER :: EddAmbT5N18D6 = 7008 - INTEGER(IntKi), PARAMETER :: EddAmbT5N18D7 = 7009 - INTEGER(IntKi), PARAMETER :: EddAmbT5N18D8 = 7010 - INTEGER(IntKi), PARAMETER :: EddAmbT5N18D9 = 7011 - INTEGER(IntKi), PARAMETER :: EddAmbT5N19D1 = 7012 - INTEGER(IntKi), PARAMETER :: EddAmbT5N19D2 = 7013 - INTEGER(IntKi), PARAMETER :: EddAmbT5N19D3 = 7014 - INTEGER(IntKi), PARAMETER :: EddAmbT5N19D4 = 7015 - INTEGER(IntKi), PARAMETER :: EddAmbT5N19D5 = 7016 - INTEGER(IntKi), PARAMETER :: EddAmbT5N19D6 = 7017 - INTEGER(IntKi), PARAMETER :: EddAmbT5N19D7 = 7018 - INTEGER(IntKi), PARAMETER :: EddAmbT5N19D8 = 7019 - INTEGER(IntKi), PARAMETER :: EddAmbT5N19D9 = 7020 - INTEGER(IntKi), PARAMETER :: EddAmbT5N20D1 = 7021 - INTEGER(IntKi), PARAMETER :: EddAmbT5N20D2 = 7022 - INTEGER(IntKi), PARAMETER :: EddAmbT5N20D3 = 7023 - INTEGER(IntKi), PARAMETER :: EddAmbT5N20D4 = 7024 - INTEGER(IntKi), PARAMETER :: EddAmbT5N20D5 = 7025 - INTEGER(IntKi), PARAMETER :: EddAmbT5N20D6 = 7026 - INTEGER(IntKi), PARAMETER :: EddAmbT5N20D7 = 7027 - INTEGER(IntKi), PARAMETER :: EddAmbT5N20D8 = 7028 - INTEGER(IntKi), PARAMETER :: EddAmbT5N20D9 = 7029 - INTEGER(IntKi), PARAMETER :: EddAmbT6N01D1 = 7030 - INTEGER(IntKi), PARAMETER :: EddAmbT6N01D2 = 7031 - INTEGER(IntKi), PARAMETER :: EddAmbT6N01D3 = 7032 - INTEGER(IntKi), PARAMETER :: EddAmbT6N01D4 = 7033 - INTEGER(IntKi), PARAMETER :: EddAmbT6N01D5 = 7034 - INTEGER(IntKi), PARAMETER :: EddAmbT6N01D6 = 7035 - INTEGER(IntKi), PARAMETER :: EddAmbT6N01D7 = 7036 - INTEGER(IntKi), PARAMETER :: EddAmbT6N01D8 = 7037 - INTEGER(IntKi), PARAMETER :: EddAmbT6N01D9 = 7038 - INTEGER(IntKi), PARAMETER :: EddAmbT6N02D1 = 7039 - INTEGER(IntKi), PARAMETER :: EddAmbT6N02D2 = 7040 - INTEGER(IntKi), PARAMETER :: EddAmbT6N02D3 = 7041 - INTEGER(IntKi), PARAMETER :: EddAmbT6N02D4 = 7042 - INTEGER(IntKi), PARAMETER :: EddAmbT6N02D5 = 7043 - INTEGER(IntKi), PARAMETER :: EddAmbT6N02D6 = 7044 - INTEGER(IntKi), PARAMETER :: EddAmbT6N02D7 = 7045 - INTEGER(IntKi), PARAMETER :: EddAmbT6N02D8 = 7046 - INTEGER(IntKi), PARAMETER :: EddAmbT6N02D9 = 7047 - INTEGER(IntKi), PARAMETER :: EddAmbT6N03D1 = 7048 - INTEGER(IntKi), PARAMETER :: EddAmbT6N03D2 = 7049 - INTEGER(IntKi), PARAMETER :: EddAmbT6N03D3 = 7050 - INTEGER(IntKi), PARAMETER :: EddAmbT6N03D4 = 7051 - INTEGER(IntKi), PARAMETER :: EddAmbT6N03D5 = 7052 - INTEGER(IntKi), PARAMETER :: EddAmbT6N03D6 = 7053 - INTEGER(IntKi), PARAMETER :: EddAmbT6N03D7 = 7054 - INTEGER(IntKi), PARAMETER :: EddAmbT6N03D8 = 7055 - INTEGER(IntKi), PARAMETER :: EddAmbT6N03D9 = 7056 - INTEGER(IntKi), PARAMETER :: EddAmbT6N04D1 = 7057 - INTEGER(IntKi), PARAMETER :: EddAmbT6N04D2 = 7058 - INTEGER(IntKi), PARAMETER :: EddAmbT6N04D3 = 7059 - INTEGER(IntKi), PARAMETER :: EddAmbT6N04D4 = 7060 - INTEGER(IntKi), PARAMETER :: EddAmbT6N04D5 = 7061 - INTEGER(IntKi), PARAMETER :: EddAmbT6N04D6 = 7062 - INTEGER(IntKi), PARAMETER :: EddAmbT6N04D7 = 7063 - INTEGER(IntKi), PARAMETER :: EddAmbT6N04D8 = 7064 - INTEGER(IntKi), PARAMETER :: EddAmbT6N04D9 = 7065 - INTEGER(IntKi), PARAMETER :: EddAmbT6N05D1 = 7066 - INTEGER(IntKi), PARAMETER :: EddAmbT6N05D2 = 7067 - INTEGER(IntKi), PARAMETER :: EddAmbT6N05D3 = 7068 - INTEGER(IntKi), PARAMETER :: EddAmbT6N05D4 = 7069 - INTEGER(IntKi), PARAMETER :: EddAmbT6N05D5 = 7070 - INTEGER(IntKi), PARAMETER :: EddAmbT6N05D6 = 7071 - INTEGER(IntKi), PARAMETER :: EddAmbT6N05D7 = 7072 - INTEGER(IntKi), PARAMETER :: EddAmbT6N05D8 = 7073 - INTEGER(IntKi), PARAMETER :: EddAmbT6N05D9 = 7074 - INTEGER(IntKi), PARAMETER :: EddAmbT6N06D1 = 7075 - INTEGER(IntKi), PARAMETER :: EddAmbT6N06D2 = 7076 - INTEGER(IntKi), PARAMETER :: EddAmbT6N06D3 = 7077 - INTEGER(IntKi), PARAMETER :: EddAmbT6N06D4 = 7078 - INTEGER(IntKi), PARAMETER :: EddAmbT6N06D5 = 7079 - INTEGER(IntKi), PARAMETER :: EddAmbT6N06D6 = 7080 - INTEGER(IntKi), PARAMETER :: EddAmbT6N06D7 = 7081 - INTEGER(IntKi), PARAMETER :: EddAmbT6N06D8 = 7082 - INTEGER(IntKi), PARAMETER :: EddAmbT6N06D9 = 7083 - INTEGER(IntKi), PARAMETER :: EddAmbT6N07D1 = 7084 - INTEGER(IntKi), PARAMETER :: EddAmbT6N07D2 = 7085 - INTEGER(IntKi), PARAMETER :: EddAmbT6N07D3 = 7086 - INTEGER(IntKi), PARAMETER :: EddAmbT6N07D4 = 7087 - INTEGER(IntKi), PARAMETER :: EddAmbT6N07D5 = 7088 - INTEGER(IntKi), PARAMETER :: EddAmbT6N07D6 = 7089 - INTEGER(IntKi), PARAMETER :: EddAmbT6N07D7 = 7090 - INTEGER(IntKi), PARAMETER :: EddAmbT6N07D8 = 7091 - INTEGER(IntKi), PARAMETER :: EddAmbT6N07D9 = 7092 - INTEGER(IntKi), PARAMETER :: EddAmbT6N08D1 = 7093 - INTEGER(IntKi), PARAMETER :: EddAmbT6N08D2 = 7094 - INTEGER(IntKi), PARAMETER :: EddAmbT6N08D3 = 7095 - INTEGER(IntKi), PARAMETER :: EddAmbT6N08D4 = 7096 - INTEGER(IntKi), PARAMETER :: EddAmbT6N08D5 = 7097 - INTEGER(IntKi), PARAMETER :: EddAmbT6N08D6 = 7098 - INTEGER(IntKi), PARAMETER :: EddAmbT6N08D7 = 7099 - INTEGER(IntKi), PARAMETER :: EddAmbT6N08D8 = 7100 - INTEGER(IntKi), PARAMETER :: EddAmbT6N08D9 = 7101 - INTEGER(IntKi), PARAMETER :: EddAmbT6N09D1 = 7102 - INTEGER(IntKi), PARAMETER :: EddAmbT6N09D2 = 7103 - INTEGER(IntKi), PARAMETER :: EddAmbT6N09D3 = 7104 - INTEGER(IntKi), PARAMETER :: EddAmbT6N09D4 = 7105 - INTEGER(IntKi), PARAMETER :: EddAmbT6N09D5 = 7106 - INTEGER(IntKi), PARAMETER :: EddAmbT6N09D6 = 7107 - INTEGER(IntKi), PARAMETER :: EddAmbT6N09D7 = 7108 - INTEGER(IntKi), PARAMETER :: EddAmbT6N09D8 = 7109 - INTEGER(IntKi), PARAMETER :: EddAmbT6N09D9 = 7110 - INTEGER(IntKi), PARAMETER :: EddAmbT6N10D1 = 7111 - INTEGER(IntKi), PARAMETER :: EddAmbT6N10D2 = 7112 - INTEGER(IntKi), PARAMETER :: EddAmbT6N10D3 = 7113 - INTEGER(IntKi), PARAMETER :: EddAmbT6N10D4 = 7114 - INTEGER(IntKi), PARAMETER :: EddAmbT6N10D5 = 7115 - INTEGER(IntKi), PARAMETER :: EddAmbT6N10D6 = 7116 - INTEGER(IntKi), PARAMETER :: EddAmbT6N10D7 = 7117 - INTEGER(IntKi), PARAMETER :: EddAmbT6N10D8 = 7118 - INTEGER(IntKi), PARAMETER :: EddAmbT6N10D9 = 7119 - INTEGER(IntKi), PARAMETER :: EddAmbT6N11D1 = 7120 - INTEGER(IntKi), PARAMETER :: EddAmbT6N11D2 = 7121 - INTEGER(IntKi), PARAMETER :: EddAmbT6N11D3 = 7122 - INTEGER(IntKi), PARAMETER :: EddAmbT6N11D4 = 7123 - INTEGER(IntKi), PARAMETER :: EddAmbT6N11D5 = 7124 - INTEGER(IntKi), PARAMETER :: EddAmbT6N11D6 = 7125 - INTEGER(IntKi), PARAMETER :: EddAmbT6N11D7 = 7126 - INTEGER(IntKi), PARAMETER :: EddAmbT6N11D8 = 7127 - INTEGER(IntKi), PARAMETER :: EddAmbT6N11D9 = 7128 - INTEGER(IntKi), PARAMETER :: EddAmbT6N12D1 = 7129 - INTEGER(IntKi), PARAMETER :: EddAmbT6N12D2 = 7130 - INTEGER(IntKi), PARAMETER :: EddAmbT6N12D3 = 7131 - INTEGER(IntKi), PARAMETER :: EddAmbT6N12D4 = 7132 - INTEGER(IntKi), PARAMETER :: EddAmbT6N12D5 = 7133 - INTEGER(IntKi), PARAMETER :: EddAmbT6N12D6 = 7134 - INTEGER(IntKi), PARAMETER :: EddAmbT6N12D7 = 7135 - INTEGER(IntKi), PARAMETER :: EddAmbT6N12D8 = 7136 - INTEGER(IntKi), PARAMETER :: EddAmbT6N12D9 = 7137 - INTEGER(IntKi), PARAMETER :: EddAmbT6N13D1 = 7138 - INTEGER(IntKi), PARAMETER :: EddAmbT6N13D2 = 7139 - INTEGER(IntKi), PARAMETER :: EddAmbT6N13D3 = 7140 - INTEGER(IntKi), PARAMETER :: EddAmbT6N13D4 = 7141 - INTEGER(IntKi), PARAMETER :: EddAmbT6N13D5 = 7142 - INTEGER(IntKi), PARAMETER :: EddAmbT6N13D6 = 7143 - INTEGER(IntKi), PARAMETER :: EddAmbT6N13D7 = 7144 - INTEGER(IntKi), PARAMETER :: EddAmbT6N13D8 = 7145 - INTEGER(IntKi), PARAMETER :: EddAmbT6N13D9 = 7146 - INTEGER(IntKi), PARAMETER :: EddAmbT6N14D1 = 7147 - INTEGER(IntKi), PARAMETER :: EddAmbT6N14D2 = 7148 - INTEGER(IntKi), PARAMETER :: EddAmbT6N14D3 = 7149 - INTEGER(IntKi), PARAMETER :: EddAmbT6N14D4 = 7150 - INTEGER(IntKi), PARAMETER :: EddAmbT6N14D5 = 7151 - INTEGER(IntKi), PARAMETER :: EddAmbT6N14D6 = 7152 - INTEGER(IntKi), PARAMETER :: EddAmbT6N14D7 = 7153 - INTEGER(IntKi), PARAMETER :: EddAmbT6N14D8 = 7154 - INTEGER(IntKi), PARAMETER :: EddAmbT6N14D9 = 7155 - INTEGER(IntKi), PARAMETER :: EddAmbT6N15D1 = 7156 - INTEGER(IntKi), PARAMETER :: EddAmbT6N15D2 = 7157 - INTEGER(IntKi), PARAMETER :: EddAmbT6N15D3 = 7158 - INTEGER(IntKi), PARAMETER :: EddAmbT6N15D4 = 7159 - INTEGER(IntKi), PARAMETER :: EddAmbT6N15D5 = 7160 - INTEGER(IntKi), PARAMETER :: EddAmbT6N15D6 = 7161 - INTEGER(IntKi), PARAMETER :: EddAmbT6N15D7 = 7162 - INTEGER(IntKi), PARAMETER :: EddAmbT6N15D8 = 7163 - INTEGER(IntKi), PARAMETER :: EddAmbT6N15D9 = 7164 - INTEGER(IntKi), PARAMETER :: EddAmbT6N16D1 = 7165 - INTEGER(IntKi), PARAMETER :: EddAmbT6N16D2 = 7166 - INTEGER(IntKi), PARAMETER :: EddAmbT6N16D3 = 7167 - INTEGER(IntKi), PARAMETER :: EddAmbT6N16D4 = 7168 - INTEGER(IntKi), PARAMETER :: EddAmbT6N16D5 = 7169 - INTEGER(IntKi), PARAMETER :: EddAmbT6N16D6 = 7170 - INTEGER(IntKi), PARAMETER :: EddAmbT6N16D7 = 7171 - INTEGER(IntKi), PARAMETER :: EddAmbT6N16D8 = 7172 - INTEGER(IntKi), PARAMETER :: EddAmbT6N16D9 = 7173 - INTEGER(IntKi), PARAMETER :: EddAmbT6N17D1 = 7174 - INTEGER(IntKi), PARAMETER :: EddAmbT6N17D2 = 7175 - INTEGER(IntKi), PARAMETER :: EddAmbT6N17D3 = 7176 - INTEGER(IntKi), PARAMETER :: EddAmbT6N17D4 = 7177 - INTEGER(IntKi), PARAMETER :: EddAmbT6N17D5 = 7178 - INTEGER(IntKi), PARAMETER :: EddAmbT6N17D6 = 7179 - INTEGER(IntKi), PARAMETER :: EddAmbT6N17D7 = 7180 - INTEGER(IntKi), PARAMETER :: EddAmbT6N17D8 = 7181 - INTEGER(IntKi), PARAMETER :: EddAmbT6N17D9 = 7182 - INTEGER(IntKi), PARAMETER :: EddAmbT6N18D1 = 7183 - INTEGER(IntKi), PARAMETER :: EddAmbT6N18D2 = 7184 - INTEGER(IntKi), PARAMETER :: EddAmbT6N18D3 = 7185 - INTEGER(IntKi), PARAMETER :: EddAmbT6N18D4 = 7186 - INTEGER(IntKi), PARAMETER :: EddAmbT6N18D5 = 7187 - INTEGER(IntKi), PARAMETER :: EddAmbT6N18D6 = 7188 - INTEGER(IntKi), PARAMETER :: EddAmbT6N18D7 = 7189 - INTEGER(IntKi), PARAMETER :: EddAmbT6N18D8 = 7190 - INTEGER(IntKi), PARAMETER :: EddAmbT6N18D9 = 7191 - INTEGER(IntKi), PARAMETER :: EddAmbT6N19D1 = 7192 - INTEGER(IntKi), PARAMETER :: EddAmbT6N19D2 = 7193 - INTEGER(IntKi), PARAMETER :: EddAmbT6N19D3 = 7194 - INTEGER(IntKi), PARAMETER :: EddAmbT6N19D4 = 7195 - INTEGER(IntKi), PARAMETER :: EddAmbT6N19D5 = 7196 - INTEGER(IntKi), PARAMETER :: EddAmbT6N19D6 = 7197 - INTEGER(IntKi), PARAMETER :: EddAmbT6N19D7 = 7198 - INTEGER(IntKi), PARAMETER :: EddAmbT6N19D8 = 7199 - INTEGER(IntKi), PARAMETER :: EddAmbT6N19D9 = 7200 - INTEGER(IntKi), PARAMETER :: EddAmbT6N20D1 = 7201 - INTEGER(IntKi), PARAMETER :: EddAmbT6N20D2 = 7202 - INTEGER(IntKi), PARAMETER :: EddAmbT6N20D3 = 7203 - INTEGER(IntKi), PARAMETER :: EddAmbT6N20D4 = 7204 - INTEGER(IntKi), PARAMETER :: EddAmbT6N20D5 = 7205 - INTEGER(IntKi), PARAMETER :: EddAmbT6N20D6 = 7206 - INTEGER(IntKi), PARAMETER :: EddAmbT6N20D7 = 7207 - INTEGER(IntKi), PARAMETER :: EddAmbT6N20D8 = 7208 - INTEGER(IntKi), PARAMETER :: EddAmbT6N20D9 = 7209 - INTEGER(IntKi), PARAMETER :: EddAmbT7N01D1 = 7210 - INTEGER(IntKi), PARAMETER :: EddAmbT7N01D2 = 7211 - INTEGER(IntKi), PARAMETER :: EddAmbT7N01D3 = 7212 - INTEGER(IntKi), PARAMETER :: EddAmbT7N01D4 = 7213 - INTEGER(IntKi), PARAMETER :: EddAmbT7N01D5 = 7214 - INTEGER(IntKi), PARAMETER :: EddAmbT7N01D6 = 7215 - INTEGER(IntKi), PARAMETER :: EddAmbT7N01D7 = 7216 - INTEGER(IntKi), PARAMETER :: EddAmbT7N01D8 = 7217 - INTEGER(IntKi), PARAMETER :: EddAmbT7N01D9 = 7218 - INTEGER(IntKi), PARAMETER :: EddAmbT7N02D1 = 7219 - INTEGER(IntKi), PARAMETER :: EddAmbT7N02D2 = 7220 - INTEGER(IntKi), PARAMETER :: EddAmbT7N02D3 = 7221 - INTEGER(IntKi), PARAMETER :: EddAmbT7N02D4 = 7222 - INTEGER(IntKi), PARAMETER :: EddAmbT7N02D5 = 7223 - INTEGER(IntKi), PARAMETER :: EddAmbT7N02D6 = 7224 - INTEGER(IntKi), PARAMETER :: EddAmbT7N02D7 = 7225 - INTEGER(IntKi), PARAMETER :: EddAmbT7N02D8 = 7226 - INTEGER(IntKi), PARAMETER :: EddAmbT7N02D9 = 7227 - INTEGER(IntKi), PARAMETER :: EddAmbT7N03D1 = 7228 - INTEGER(IntKi), PARAMETER :: EddAmbT7N03D2 = 7229 - INTEGER(IntKi), PARAMETER :: EddAmbT7N03D3 = 7230 - INTEGER(IntKi), PARAMETER :: EddAmbT7N03D4 = 7231 - INTEGER(IntKi), PARAMETER :: EddAmbT7N03D5 = 7232 - INTEGER(IntKi), PARAMETER :: EddAmbT7N03D6 = 7233 - INTEGER(IntKi), PARAMETER :: EddAmbT7N03D7 = 7234 - INTEGER(IntKi), PARAMETER :: EddAmbT7N03D8 = 7235 - INTEGER(IntKi), PARAMETER :: EddAmbT7N03D9 = 7236 - INTEGER(IntKi), PARAMETER :: EddAmbT7N04D1 = 7237 - INTEGER(IntKi), PARAMETER :: EddAmbT7N04D2 = 7238 - INTEGER(IntKi), PARAMETER :: EddAmbT7N04D3 = 7239 - INTEGER(IntKi), PARAMETER :: EddAmbT7N04D4 = 7240 - INTEGER(IntKi), PARAMETER :: EddAmbT7N04D5 = 7241 - INTEGER(IntKi), PARAMETER :: EddAmbT7N04D6 = 7242 - INTEGER(IntKi), PARAMETER :: EddAmbT7N04D7 = 7243 - INTEGER(IntKi), PARAMETER :: EddAmbT7N04D8 = 7244 - INTEGER(IntKi), PARAMETER :: EddAmbT7N04D9 = 7245 - INTEGER(IntKi), PARAMETER :: EddAmbT7N05D1 = 7246 - INTEGER(IntKi), PARAMETER :: EddAmbT7N05D2 = 7247 - INTEGER(IntKi), PARAMETER :: EddAmbT7N05D3 = 7248 - INTEGER(IntKi), PARAMETER :: EddAmbT7N05D4 = 7249 - INTEGER(IntKi), PARAMETER :: EddAmbT7N05D5 = 7250 - INTEGER(IntKi), PARAMETER :: EddAmbT7N05D6 = 7251 - INTEGER(IntKi), PARAMETER :: EddAmbT7N05D7 = 7252 - INTEGER(IntKi), PARAMETER :: EddAmbT7N05D8 = 7253 - INTEGER(IntKi), PARAMETER :: EddAmbT7N05D9 = 7254 - INTEGER(IntKi), PARAMETER :: EddAmbT7N06D1 = 7255 - INTEGER(IntKi), PARAMETER :: EddAmbT7N06D2 = 7256 - INTEGER(IntKi), PARAMETER :: EddAmbT7N06D3 = 7257 - INTEGER(IntKi), PARAMETER :: EddAmbT7N06D4 = 7258 - INTEGER(IntKi), PARAMETER :: EddAmbT7N06D5 = 7259 - INTEGER(IntKi), PARAMETER :: EddAmbT7N06D6 = 7260 - INTEGER(IntKi), PARAMETER :: EddAmbT7N06D7 = 7261 - INTEGER(IntKi), PARAMETER :: EddAmbT7N06D8 = 7262 - INTEGER(IntKi), PARAMETER :: EddAmbT7N06D9 = 7263 - INTEGER(IntKi), PARAMETER :: EddAmbT7N07D1 = 7264 - INTEGER(IntKi), PARAMETER :: EddAmbT7N07D2 = 7265 - INTEGER(IntKi), PARAMETER :: EddAmbT7N07D3 = 7266 - INTEGER(IntKi), PARAMETER :: EddAmbT7N07D4 = 7267 - INTEGER(IntKi), PARAMETER :: EddAmbT7N07D5 = 7268 - INTEGER(IntKi), PARAMETER :: EddAmbT7N07D6 = 7269 - INTEGER(IntKi), PARAMETER :: EddAmbT7N07D7 = 7270 - INTEGER(IntKi), PARAMETER :: EddAmbT7N07D8 = 7271 - INTEGER(IntKi), PARAMETER :: EddAmbT7N07D9 = 7272 - INTEGER(IntKi), PARAMETER :: EddAmbT7N08D1 = 7273 - INTEGER(IntKi), PARAMETER :: EddAmbT7N08D2 = 7274 - INTEGER(IntKi), PARAMETER :: EddAmbT7N08D3 = 7275 - INTEGER(IntKi), PARAMETER :: EddAmbT7N08D4 = 7276 - INTEGER(IntKi), PARAMETER :: EddAmbT7N08D5 = 7277 - INTEGER(IntKi), PARAMETER :: EddAmbT7N08D6 = 7278 - INTEGER(IntKi), PARAMETER :: EddAmbT7N08D7 = 7279 - INTEGER(IntKi), PARAMETER :: EddAmbT7N08D8 = 7280 - INTEGER(IntKi), PARAMETER :: EddAmbT7N08D9 = 7281 - INTEGER(IntKi), PARAMETER :: EddAmbT7N09D1 = 7282 - INTEGER(IntKi), PARAMETER :: EddAmbT7N09D2 = 7283 - INTEGER(IntKi), PARAMETER :: EddAmbT7N09D3 = 7284 - INTEGER(IntKi), PARAMETER :: EddAmbT7N09D4 = 7285 - INTEGER(IntKi), PARAMETER :: EddAmbT7N09D5 = 7286 - INTEGER(IntKi), PARAMETER :: EddAmbT7N09D6 = 7287 - INTEGER(IntKi), PARAMETER :: EddAmbT7N09D7 = 7288 - INTEGER(IntKi), PARAMETER :: EddAmbT7N09D8 = 7289 - INTEGER(IntKi), PARAMETER :: EddAmbT7N09D9 = 7290 - INTEGER(IntKi), PARAMETER :: EddAmbT7N10D1 = 7291 - INTEGER(IntKi), PARAMETER :: EddAmbT7N10D2 = 7292 - INTEGER(IntKi), PARAMETER :: EddAmbT7N10D3 = 7293 - INTEGER(IntKi), PARAMETER :: EddAmbT7N10D4 = 7294 - INTEGER(IntKi), PARAMETER :: EddAmbT7N10D5 = 7295 - INTEGER(IntKi), PARAMETER :: EddAmbT7N10D6 = 7296 - INTEGER(IntKi), PARAMETER :: EddAmbT7N10D7 = 7297 - INTEGER(IntKi), PARAMETER :: EddAmbT7N10D8 = 7298 - INTEGER(IntKi), PARAMETER :: EddAmbT7N10D9 = 7299 - INTEGER(IntKi), PARAMETER :: EddAmbT7N11D1 = 7300 - INTEGER(IntKi), PARAMETER :: EddAmbT7N11D2 = 7301 - INTEGER(IntKi), PARAMETER :: EddAmbT7N11D3 = 7302 - INTEGER(IntKi), PARAMETER :: EddAmbT7N11D4 = 7303 - INTEGER(IntKi), PARAMETER :: EddAmbT7N11D5 = 7304 - INTEGER(IntKi), PARAMETER :: EddAmbT7N11D6 = 7305 - INTEGER(IntKi), PARAMETER :: EddAmbT7N11D7 = 7306 - INTEGER(IntKi), PARAMETER :: EddAmbT7N11D8 = 7307 - INTEGER(IntKi), PARAMETER :: EddAmbT7N11D9 = 7308 - INTEGER(IntKi), PARAMETER :: EddAmbT7N12D1 = 7309 - INTEGER(IntKi), PARAMETER :: EddAmbT7N12D2 = 7310 - INTEGER(IntKi), PARAMETER :: EddAmbT7N12D3 = 7311 - INTEGER(IntKi), PARAMETER :: EddAmbT7N12D4 = 7312 - INTEGER(IntKi), PARAMETER :: EddAmbT7N12D5 = 7313 - INTEGER(IntKi), PARAMETER :: EddAmbT7N12D6 = 7314 - INTEGER(IntKi), PARAMETER :: EddAmbT7N12D7 = 7315 - INTEGER(IntKi), PARAMETER :: EddAmbT7N12D8 = 7316 - INTEGER(IntKi), PARAMETER :: EddAmbT7N12D9 = 7317 - INTEGER(IntKi), PARAMETER :: EddAmbT7N13D1 = 7318 - INTEGER(IntKi), PARAMETER :: EddAmbT7N13D2 = 7319 - INTEGER(IntKi), PARAMETER :: EddAmbT7N13D3 = 7320 - INTEGER(IntKi), PARAMETER :: EddAmbT7N13D4 = 7321 - INTEGER(IntKi), PARAMETER :: EddAmbT7N13D5 = 7322 - INTEGER(IntKi), PARAMETER :: EddAmbT7N13D6 = 7323 - INTEGER(IntKi), PARAMETER :: EddAmbT7N13D7 = 7324 - INTEGER(IntKi), PARAMETER :: EddAmbT7N13D8 = 7325 - INTEGER(IntKi), PARAMETER :: EddAmbT7N13D9 = 7326 - INTEGER(IntKi), PARAMETER :: EddAmbT7N14D1 = 7327 - INTEGER(IntKi), PARAMETER :: EddAmbT7N14D2 = 7328 - INTEGER(IntKi), PARAMETER :: EddAmbT7N14D3 = 7329 - INTEGER(IntKi), PARAMETER :: EddAmbT7N14D4 = 7330 - INTEGER(IntKi), PARAMETER :: EddAmbT7N14D5 = 7331 - INTEGER(IntKi), PARAMETER :: EddAmbT7N14D6 = 7332 - INTEGER(IntKi), PARAMETER :: EddAmbT7N14D7 = 7333 - INTEGER(IntKi), PARAMETER :: EddAmbT7N14D8 = 7334 - INTEGER(IntKi), PARAMETER :: EddAmbT7N14D9 = 7335 - INTEGER(IntKi), PARAMETER :: EddAmbT7N15D1 = 7336 - INTEGER(IntKi), PARAMETER :: EddAmbT7N15D2 = 7337 - INTEGER(IntKi), PARAMETER :: EddAmbT7N15D3 = 7338 - INTEGER(IntKi), PARAMETER :: EddAmbT7N15D4 = 7339 - INTEGER(IntKi), PARAMETER :: EddAmbT7N15D5 = 7340 - INTEGER(IntKi), PARAMETER :: EddAmbT7N15D6 = 7341 - INTEGER(IntKi), PARAMETER :: EddAmbT7N15D7 = 7342 - INTEGER(IntKi), PARAMETER :: EddAmbT7N15D8 = 7343 - INTEGER(IntKi), PARAMETER :: EddAmbT7N15D9 = 7344 - INTEGER(IntKi), PARAMETER :: EddAmbT7N16D1 = 7345 - INTEGER(IntKi), PARAMETER :: EddAmbT7N16D2 = 7346 - INTEGER(IntKi), PARAMETER :: EddAmbT7N16D3 = 7347 - INTEGER(IntKi), PARAMETER :: EddAmbT7N16D4 = 7348 - INTEGER(IntKi), PARAMETER :: EddAmbT7N16D5 = 7349 - INTEGER(IntKi), PARAMETER :: EddAmbT7N16D6 = 7350 - INTEGER(IntKi), PARAMETER :: EddAmbT7N16D7 = 7351 - INTEGER(IntKi), PARAMETER :: EddAmbT7N16D8 = 7352 - INTEGER(IntKi), PARAMETER :: EddAmbT7N16D9 = 7353 - INTEGER(IntKi), PARAMETER :: EddAmbT7N17D1 = 7354 - INTEGER(IntKi), PARAMETER :: EddAmbT7N17D2 = 7355 - INTEGER(IntKi), PARAMETER :: EddAmbT7N17D3 = 7356 - INTEGER(IntKi), PARAMETER :: EddAmbT7N17D4 = 7357 - INTEGER(IntKi), PARAMETER :: EddAmbT7N17D5 = 7358 - INTEGER(IntKi), PARAMETER :: EddAmbT7N17D6 = 7359 - INTEGER(IntKi), PARAMETER :: EddAmbT7N17D7 = 7360 - INTEGER(IntKi), PARAMETER :: EddAmbT7N17D8 = 7361 - INTEGER(IntKi), PARAMETER :: EddAmbT7N17D9 = 7362 - INTEGER(IntKi), PARAMETER :: EddAmbT7N18D1 = 7363 - INTEGER(IntKi), PARAMETER :: EddAmbT7N18D2 = 7364 - INTEGER(IntKi), PARAMETER :: EddAmbT7N18D3 = 7365 - INTEGER(IntKi), PARAMETER :: EddAmbT7N18D4 = 7366 - INTEGER(IntKi), PARAMETER :: EddAmbT7N18D5 = 7367 - INTEGER(IntKi), PARAMETER :: EddAmbT7N18D6 = 7368 - INTEGER(IntKi), PARAMETER :: EddAmbT7N18D7 = 7369 - INTEGER(IntKi), PARAMETER :: EddAmbT7N18D8 = 7370 - INTEGER(IntKi), PARAMETER :: EddAmbT7N18D9 = 7371 - INTEGER(IntKi), PARAMETER :: EddAmbT7N19D1 = 7372 - INTEGER(IntKi), PARAMETER :: EddAmbT7N19D2 = 7373 - INTEGER(IntKi), PARAMETER :: EddAmbT7N19D3 = 7374 - INTEGER(IntKi), PARAMETER :: EddAmbT7N19D4 = 7375 - INTEGER(IntKi), PARAMETER :: EddAmbT7N19D5 = 7376 - INTEGER(IntKi), PARAMETER :: EddAmbT7N19D6 = 7377 - INTEGER(IntKi), PARAMETER :: EddAmbT7N19D7 = 7378 - INTEGER(IntKi), PARAMETER :: EddAmbT7N19D8 = 7379 - INTEGER(IntKi), PARAMETER :: EddAmbT7N19D9 = 7380 - INTEGER(IntKi), PARAMETER :: EddAmbT7N20D1 = 7381 - INTEGER(IntKi), PARAMETER :: EddAmbT7N20D2 = 7382 - INTEGER(IntKi), PARAMETER :: EddAmbT7N20D3 = 7383 - INTEGER(IntKi), PARAMETER :: EddAmbT7N20D4 = 7384 - INTEGER(IntKi), PARAMETER :: EddAmbT7N20D5 = 7385 - INTEGER(IntKi), PARAMETER :: EddAmbT7N20D6 = 7386 - INTEGER(IntKi), PARAMETER :: EddAmbT7N20D7 = 7387 - INTEGER(IntKi), PARAMETER :: EddAmbT7N20D8 = 7388 - INTEGER(IntKi), PARAMETER :: EddAmbT7N20D9 = 7389 - INTEGER(IntKi), PARAMETER :: EddAmbT8N01D1 = 7390 - INTEGER(IntKi), PARAMETER :: EddAmbT8N01D2 = 7391 - INTEGER(IntKi), PARAMETER :: EddAmbT8N01D3 = 7392 - INTEGER(IntKi), PARAMETER :: EddAmbT8N01D4 = 7393 - INTEGER(IntKi), PARAMETER :: EddAmbT8N01D5 = 7394 - INTEGER(IntKi), PARAMETER :: EddAmbT8N01D6 = 7395 - INTEGER(IntKi), PARAMETER :: EddAmbT8N01D7 = 7396 - INTEGER(IntKi), PARAMETER :: EddAmbT8N01D8 = 7397 - INTEGER(IntKi), PARAMETER :: EddAmbT8N01D9 = 7398 - INTEGER(IntKi), PARAMETER :: EddAmbT8N02D1 = 7399 - INTEGER(IntKi), PARAMETER :: EddAmbT8N02D2 = 7400 - INTEGER(IntKi), PARAMETER :: EddAmbT8N02D3 = 7401 - INTEGER(IntKi), PARAMETER :: EddAmbT8N02D4 = 7402 - INTEGER(IntKi), PARAMETER :: EddAmbT8N02D5 = 7403 - INTEGER(IntKi), PARAMETER :: EddAmbT8N02D6 = 7404 - INTEGER(IntKi), PARAMETER :: EddAmbT8N02D7 = 7405 - INTEGER(IntKi), PARAMETER :: EddAmbT8N02D8 = 7406 - INTEGER(IntKi), PARAMETER :: EddAmbT8N02D9 = 7407 - INTEGER(IntKi), PARAMETER :: EddAmbT8N03D1 = 7408 - INTEGER(IntKi), PARAMETER :: EddAmbT8N03D2 = 7409 - INTEGER(IntKi), PARAMETER :: EddAmbT8N03D3 = 7410 - INTEGER(IntKi), PARAMETER :: EddAmbT8N03D4 = 7411 - INTEGER(IntKi), PARAMETER :: EddAmbT8N03D5 = 7412 - INTEGER(IntKi), PARAMETER :: EddAmbT8N03D6 = 7413 - INTEGER(IntKi), PARAMETER :: EddAmbT8N03D7 = 7414 - INTEGER(IntKi), PARAMETER :: EddAmbT8N03D8 = 7415 - INTEGER(IntKi), PARAMETER :: EddAmbT8N03D9 = 7416 - INTEGER(IntKi), PARAMETER :: EddAmbT8N04D1 = 7417 - INTEGER(IntKi), PARAMETER :: EddAmbT8N04D2 = 7418 - INTEGER(IntKi), PARAMETER :: EddAmbT8N04D3 = 7419 - INTEGER(IntKi), PARAMETER :: EddAmbT8N04D4 = 7420 - INTEGER(IntKi), PARAMETER :: EddAmbT8N04D5 = 7421 - INTEGER(IntKi), PARAMETER :: EddAmbT8N04D6 = 7422 - INTEGER(IntKi), PARAMETER :: EddAmbT8N04D7 = 7423 - INTEGER(IntKi), PARAMETER :: EddAmbT8N04D8 = 7424 - INTEGER(IntKi), PARAMETER :: EddAmbT8N04D9 = 7425 - INTEGER(IntKi), PARAMETER :: EddAmbT8N05D1 = 7426 - INTEGER(IntKi), PARAMETER :: EddAmbT8N05D2 = 7427 - INTEGER(IntKi), PARAMETER :: EddAmbT8N05D3 = 7428 - INTEGER(IntKi), PARAMETER :: EddAmbT8N05D4 = 7429 - INTEGER(IntKi), PARAMETER :: EddAmbT8N05D5 = 7430 - INTEGER(IntKi), PARAMETER :: EddAmbT8N05D6 = 7431 - INTEGER(IntKi), PARAMETER :: EddAmbT8N05D7 = 7432 - INTEGER(IntKi), PARAMETER :: EddAmbT8N05D8 = 7433 - INTEGER(IntKi), PARAMETER :: EddAmbT8N05D9 = 7434 - INTEGER(IntKi), PARAMETER :: EddAmbT8N06D1 = 7435 - INTEGER(IntKi), PARAMETER :: EddAmbT8N06D2 = 7436 - INTEGER(IntKi), PARAMETER :: EddAmbT8N06D3 = 7437 - INTEGER(IntKi), PARAMETER :: EddAmbT8N06D4 = 7438 - INTEGER(IntKi), PARAMETER :: EddAmbT8N06D5 = 7439 - INTEGER(IntKi), PARAMETER :: EddAmbT8N06D6 = 7440 - INTEGER(IntKi), PARAMETER :: EddAmbT8N06D7 = 7441 - INTEGER(IntKi), PARAMETER :: EddAmbT8N06D8 = 7442 - INTEGER(IntKi), PARAMETER :: EddAmbT8N06D9 = 7443 - INTEGER(IntKi), PARAMETER :: EddAmbT8N07D1 = 7444 - INTEGER(IntKi), PARAMETER :: EddAmbT8N07D2 = 7445 - INTEGER(IntKi), PARAMETER :: EddAmbT8N07D3 = 7446 - INTEGER(IntKi), PARAMETER :: EddAmbT8N07D4 = 7447 - INTEGER(IntKi), PARAMETER :: EddAmbT8N07D5 = 7448 - INTEGER(IntKi), PARAMETER :: EddAmbT8N07D6 = 7449 - INTEGER(IntKi), PARAMETER :: EddAmbT8N07D7 = 7450 - INTEGER(IntKi), PARAMETER :: EddAmbT8N07D8 = 7451 - INTEGER(IntKi), PARAMETER :: EddAmbT8N07D9 = 7452 - INTEGER(IntKi), PARAMETER :: EddAmbT8N08D1 = 7453 - INTEGER(IntKi), PARAMETER :: EddAmbT8N08D2 = 7454 - INTEGER(IntKi), PARAMETER :: EddAmbT8N08D3 = 7455 - INTEGER(IntKi), PARAMETER :: EddAmbT8N08D4 = 7456 - INTEGER(IntKi), PARAMETER :: EddAmbT8N08D5 = 7457 - INTEGER(IntKi), PARAMETER :: EddAmbT8N08D6 = 7458 - INTEGER(IntKi), PARAMETER :: EddAmbT8N08D7 = 7459 - INTEGER(IntKi), PARAMETER :: EddAmbT8N08D8 = 7460 - INTEGER(IntKi), PARAMETER :: EddAmbT8N08D9 = 7461 - INTEGER(IntKi), PARAMETER :: EddAmbT8N09D1 = 7462 - INTEGER(IntKi), PARAMETER :: EddAmbT8N09D2 = 7463 - INTEGER(IntKi), PARAMETER :: EddAmbT8N09D3 = 7464 - INTEGER(IntKi), PARAMETER :: EddAmbT8N09D4 = 7465 - INTEGER(IntKi), PARAMETER :: EddAmbT8N09D5 = 7466 - INTEGER(IntKi), PARAMETER :: EddAmbT8N09D6 = 7467 - INTEGER(IntKi), PARAMETER :: EddAmbT8N09D7 = 7468 - INTEGER(IntKi), PARAMETER :: EddAmbT8N09D8 = 7469 - INTEGER(IntKi), PARAMETER :: EddAmbT8N09D9 = 7470 - INTEGER(IntKi), PARAMETER :: EddAmbT8N10D1 = 7471 - INTEGER(IntKi), PARAMETER :: EddAmbT8N10D2 = 7472 - INTEGER(IntKi), PARAMETER :: EddAmbT8N10D3 = 7473 - INTEGER(IntKi), PARAMETER :: EddAmbT8N10D4 = 7474 - INTEGER(IntKi), PARAMETER :: EddAmbT8N10D5 = 7475 - INTEGER(IntKi), PARAMETER :: EddAmbT8N10D6 = 7476 - INTEGER(IntKi), PARAMETER :: EddAmbT8N10D7 = 7477 - INTEGER(IntKi), PARAMETER :: EddAmbT8N10D8 = 7478 - INTEGER(IntKi), PARAMETER :: EddAmbT8N10D9 = 7479 - INTEGER(IntKi), PARAMETER :: EddAmbT8N11D1 = 7480 - INTEGER(IntKi), PARAMETER :: EddAmbT8N11D2 = 7481 - INTEGER(IntKi), PARAMETER :: EddAmbT8N11D3 = 7482 - INTEGER(IntKi), PARAMETER :: EddAmbT8N11D4 = 7483 - INTEGER(IntKi), PARAMETER :: EddAmbT8N11D5 = 7484 - INTEGER(IntKi), PARAMETER :: EddAmbT8N11D6 = 7485 - INTEGER(IntKi), PARAMETER :: EddAmbT8N11D7 = 7486 - INTEGER(IntKi), PARAMETER :: EddAmbT8N11D8 = 7487 - INTEGER(IntKi), PARAMETER :: EddAmbT8N11D9 = 7488 - INTEGER(IntKi), PARAMETER :: EddAmbT8N12D1 = 7489 - INTEGER(IntKi), PARAMETER :: EddAmbT8N12D2 = 7490 - INTEGER(IntKi), PARAMETER :: EddAmbT8N12D3 = 7491 - INTEGER(IntKi), PARAMETER :: EddAmbT8N12D4 = 7492 - INTEGER(IntKi), PARAMETER :: EddAmbT8N12D5 = 7493 - INTEGER(IntKi), PARAMETER :: EddAmbT8N12D6 = 7494 - INTEGER(IntKi), PARAMETER :: EddAmbT8N12D7 = 7495 - INTEGER(IntKi), PARAMETER :: EddAmbT8N12D8 = 7496 - INTEGER(IntKi), PARAMETER :: EddAmbT8N12D9 = 7497 - INTEGER(IntKi), PARAMETER :: EddAmbT8N13D1 = 7498 - INTEGER(IntKi), PARAMETER :: EddAmbT8N13D2 = 7499 - INTEGER(IntKi), PARAMETER :: EddAmbT8N13D3 = 7500 - INTEGER(IntKi), PARAMETER :: EddAmbT8N13D4 = 7501 - INTEGER(IntKi), PARAMETER :: EddAmbT8N13D5 = 7502 - INTEGER(IntKi), PARAMETER :: EddAmbT8N13D6 = 7503 - INTEGER(IntKi), PARAMETER :: EddAmbT8N13D7 = 7504 - INTEGER(IntKi), PARAMETER :: EddAmbT8N13D8 = 7505 - INTEGER(IntKi), PARAMETER :: EddAmbT8N13D9 = 7506 - INTEGER(IntKi), PARAMETER :: EddAmbT8N14D1 = 7507 - INTEGER(IntKi), PARAMETER :: EddAmbT8N14D2 = 7508 - INTEGER(IntKi), PARAMETER :: EddAmbT8N14D3 = 7509 - INTEGER(IntKi), PARAMETER :: EddAmbT8N14D4 = 7510 - INTEGER(IntKi), PARAMETER :: EddAmbT8N14D5 = 7511 - INTEGER(IntKi), PARAMETER :: EddAmbT8N14D6 = 7512 - INTEGER(IntKi), PARAMETER :: EddAmbT8N14D7 = 7513 - INTEGER(IntKi), PARAMETER :: EddAmbT8N14D8 = 7514 - INTEGER(IntKi), PARAMETER :: EddAmbT8N14D9 = 7515 - INTEGER(IntKi), PARAMETER :: EddAmbT8N15D1 = 7516 - INTEGER(IntKi), PARAMETER :: EddAmbT8N15D2 = 7517 - INTEGER(IntKi), PARAMETER :: EddAmbT8N15D3 = 7518 - INTEGER(IntKi), PARAMETER :: EddAmbT8N15D4 = 7519 - INTEGER(IntKi), PARAMETER :: EddAmbT8N15D5 = 7520 - INTEGER(IntKi), PARAMETER :: EddAmbT8N15D6 = 7521 - INTEGER(IntKi), PARAMETER :: EddAmbT8N15D7 = 7522 - INTEGER(IntKi), PARAMETER :: EddAmbT8N15D8 = 7523 - INTEGER(IntKi), PARAMETER :: EddAmbT8N15D9 = 7524 - INTEGER(IntKi), PARAMETER :: EddAmbT8N16D1 = 7525 - INTEGER(IntKi), PARAMETER :: EddAmbT8N16D2 = 7526 - INTEGER(IntKi), PARAMETER :: EddAmbT8N16D3 = 7527 - INTEGER(IntKi), PARAMETER :: EddAmbT8N16D4 = 7528 - INTEGER(IntKi), PARAMETER :: EddAmbT8N16D5 = 7529 - INTEGER(IntKi), PARAMETER :: EddAmbT8N16D6 = 7530 - INTEGER(IntKi), PARAMETER :: EddAmbT8N16D7 = 7531 - INTEGER(IntKi), PARAMETER :: EddAmbT8N16D8 = 7532 - INTEGER(IntKi), PARAMETER :: EddAmbT8N16D9 = 7533 - INTEGER(IntKi), PARAMETER :: EddAmbT8N17D1 = 7534 - INTEGER(IntKi), PARAMETER :: EddAmbT8N17D2 = 7535 - INTEGER(IntKi), PARAMETER :: EddAmbT8N17D3 = 7536 - INTEGER(IntKi), PARAMETER :: EddAmbT8N17D4 = 7537 - INTEGER(IntKi), PARAMETER :: EddAmbT8N17D5 = 7538 - INTEGER(IntKi), PARAMETER :: EddAmbT8N17D6 = 7539 - INTEGER(IntKi), PARAMETER :: EddAmbT8N17D7 = 7540 - INTEGER(IntKi), PARAMETER :: EddAmbT8N17D8 = 7541 - INTEGER(IntKi), PARAMETER :: EddAmbT8N17D9 = 7542 - INTEGER(IntKi), PARAMETER :: EddAmbT8N18D1 = 7543 - INTEGER(IntKi), PARAMETER :: EddAmbT8N18D2 = 7544 - INTEGER(IntKi), PARAMETER :: EddAmbT8N18D3 = 7545 - INTEGER(IntKi), PARAMETER :: EddAmbT8N18D4 = 7546 - INTEGER(IntKi), PARAMETER :: EddAmbT8N18D5 = 7547 - INTEGER(IntKi), PARAMETER :: EddAmbT8N18D6 = 7548 - INTEGER(IntKi), PARAMETER :: EddAmbT8N18D7 = 7549 - INTEGER(IntKi), PARAMETER :: EddAmbT8N18D8 = 7550 - INTEGER(IntKi), PARAMETER :: EddAmbT8N18D9 = 7551 - INTEGER(IntKi), PARAMETER :: EddAmbT8N19D1 = 7552 - INTEGER(IntKi), PARAMETER :: EddAmbT8N19D2 = 7553 - INTEGER(IntKi), PARAMETER :: EddAmbT8N19D3 = 7554 - INTEGER(IntKi), PARAMETER :: EddAmbT8N19D4 = 7555 - INTEGER(IntKi), PARAMETER :: EddAmbT8N19D5 = 7556 - INTEGER(IntKi), PARAMETER :: EddAmbT8N19D6 = 7557 - INTEGER(IntKi), PARAMETER :: EddAmbT8N19D7 = 7558 - INTEGER(IntKi), PARAMETER :: EddAmbT8N19D8 = 7559 - INTEGER(IntKi), PARAMETER :: EddAmbT8N19D9 = 7560 - INTEGER(IntKi), PARAMETER :: EddAmbT8N20D1 = 7561 - INTEGER(IntKi), PARAMETER :: EddAmbT8N20D2 = 7562 - INTEGER(IntKi), PARAMETER :: EddAmbT8N20D3 = 7563 - INTEGER(IntKi), PARAMETER :: EddAmbT8N20D4 = 7564 - INTEGER(IntKi), PARAMETER :: EddAmbT8N20D5 = 7565 - INTEGER(IntKi), PARAMETER :: EddAmbT8N20D6 = 7566 - INTEGER(IntKi), PARAMETER :: EddAmbT8N20D7 = 7567 - INTEGER(IntKi), PARAMETER :: EddAmbT8N20D8 = 7568 - INTEGER(IntKi), PARAMETER :: EddAmbT8N20D9 = 7569 - INTEGER(IntKi), PARAMETER :: EddAmbT9N01D1 = 7570 - INTEGER(IntKi), PARAMETER :: EddAmbT9N01D2 = 7571 - INTEGER(IntKi), PARAMETER :: EddAmbT9N01D3 = 7572 - INTEGER(IntKi), PARAMETER :: EddAmbT9N01D4 = 7573 - INTEGER(IntKi), PARAMETER :: EddAmbT9N01D5 = 7574 - INTEGER(IntKi), PARAMETER :: EddAmbT9N01D6 = 7575 - INTEGER(IntKi), PARAMETER :: EddAmbT9N01D7 = 7576 - INTEGER(IntKi), PARAMETER :: EddAmbT9N01D8 = 7577 - INTEGER(IntKi), PARAMETER :: EddAmbT9N01D9 = 7578 - INTEGER(IntKi), PARAMETER :: EddAmbT9N02D1 = 7579 - INTEGER(IntKi), PARAMETER :: EddAmbT9N02D2 = 7580 - INTEGER(IntKi), PARAMETER :: EddAmbT9N02D3 = 7581 - INTEGER(IntKi), PARAMETER :: EddAmbT9N02D4 = 7582 - INTEGER(IntKi), PARAMETER :: EddAmbT9N02D5 = 7583 - INTEGER(IntKi), PARAMETER :: EddAmbT9N02D6 = 7584 - INTEGER(IntKi), PARAMETER :: EddAmbT9N02D7 = 7585 - INTEGER(IntKi), PARAMETER :: EddAmbT9N02D8 = 7586 - INTEGER(IntKi), PARAMETER :: EddAmbT9N02D9 = 7587 - INTEGER(IntKi), PARAMETER :: EddAmbT9N03D1 = 7588 - INTEGER(IntKi), PARAMETER :: EddAmbT9N03D2 = 7589 - INTEGER(IntKi), PARAMETER :: EddAmbT9N03D3 = 7590 - INTEGER(IntKi), PARAMETER :: EddAmbT9N03D4 = 7591 - INTEGER(IntKi), PARAMETER :: EddAmbT9N03D5 = 7592 - INTEGER(IntKi), PARAMETER :: EddAmbT9N03D6 = 7593 - INTEGER(IntKi), PARAMETER :: EddAmbT9N03D7 = 7594 - INTEGER(IntKi), PARAMETER :: EddAmbT9N03D8 = 7595 - INTEGER(IntKi), PARAMETER :: EddAmbT9N03D9 = 7596 - INTEGER(IntKi), PARAMETER :: EddAmbT9N04D1 = 7597 - INTEGER(IntKi), PARAMETER :: EddAmbT9N04D2 = 7598 - INTEGER(IntKi), PARAMETER :: EddAmbT9N04D3 = 7599 - INTEGER(IntKi), PARAMETER :: EddAmbT9N04D4 = 7600 - INTEGER(IntKi), PARAMETER :: EddAmbT9N04D5 = 7601 - INTEGER(IntKi), PARAMETER :: EddAmbT9N04D6 = 7602 - INTEGER(IntKi), PARAMETER :: EddAmbT9N04D7 = 7603 - INTEGER(IntKi), PARAMETER :: EddAmbT9N04D8 = 7604 - INTEGER(IntKi), PARAMETER :: EddAmbT9N04D9 = 7605 - INTEGER(IntKi), PARAMETER :: EddAmbT9N05D1 = 7606 - INTEGER(IntKi), PARAMETER :: EddAmbT9N05D2 = 7607 - INTEGER(IntKi), PARAMETER :: EddAmbT9N05D3 = 7608 - INTEGER(IntKi), PARAMETER :: EddAmbT9N05D4 = 7609 - INTEGER(IntKi), PARAMETER :: EddAmbT9N05D5 = 7610 - INTEGER(IntKi), PARAMETER :: EddAmbT9N05D6 = 7611 - INTEGER(IntKi), PARAMETER :: EddAmbT9N05D7 = 7612 - INTEGER(IntKi), PARAMETER :: EddAmbT9N05D8 = 7613 - INTEGER(IntKi), PARAMETER :: EddAmbT9N05D9 = 7614 - INTEGER(IntKi), PARAMETER :: EddAmbT9N06D1 = 7615 - INTEGER(IntKi), PARAMETER :: EddAmbT9N06D2 = 7616 - INTEGER(IntKi), PARAMETER :: EddAmbT9N06D3 = 7617 - INTEGER(IntKi), PARAMETER :: EddAmbT9N06D4 = 7618 - INTEGER(IntKi), PARAMETER :: EddAmbT9N06D5 = 7619 - INTEGER(IntKi), PARAMETER :: EddAmbT9N06D6 = 7620 - INTEGER(IntKi), PARAMETER :: EddAmbT9N06D7 = 7621 - INTEGER(IntKi), PARAMETER :: EddAmbT9N06D8 = 7622 - INTEGER(IntKi), PARAMETER :: EddAmbT9N06D9 = 7623 - INTEGER(IntKi), PARAMETER :: EddAmbT9N07D1 = 7624 - INTEGER(IntKi), PARAMETER :: EddAmbT9N07D2 = 7625 - INTEGER(IntKi), PARAMETER :: EddAmbT9N07D3 = 7626 - INTEGER(IntKi), PARAMETER :: EddAmbT9N07D4 = 7627 - INTEGER(IntKi), PARAMETER :: EddAmbT9N07D5 = 7628 - INTEGER(IntKi), PARAMETER :: EddAmbT9N07D6 = 7629 - INTEGER(IntKi), PARAMETER :: EddAmbT9N07D7 = 7630 - INTEGER(IntKi), PARAMETER :: EddAmbT9N07D8 = 7631 - INTEGER(IntKi), PARAMETER :: EddAmbT9N07D9 = 7632 - INTEGER(IntKi), PARAMETER :: EddAmbT9N08D1 = 7633 - INTEGER(IntKi), PARAMETER :: EddAmbT9N08D2 = 7634 - INTEGER(IntKi), PARAMETER :: EddAmbT9N08D3 = 7635 - INTEGER(IntKi), PARAMETER :: EddAmbT9N08D4 = 7636 - INTEGER(IntKi), PARAMETER :: EddAmbT9N08D5 = 7637 - INTEGER(IntKi), PARAMETER :: EddAmbT9N08D6 = 7638 - INTEGER(IntKi), PARAMETER :: EddAmbT9N08D7 = 7639 - INTEGER(IntKi), PARAMETER :: EddAmbT9N08D8 = 7640 - INTEGER(IntKi), PARAMETER :: EddAmbT9N08D9 = 7641 - INTEGER(IntKi), PARAMETER :: EddAmbT9N09D1 = 7642 - INTEGER(IntKi), PARAMETER :: EddAmbT9N09D2 = 7643 - INTEGER(IntKi), PARAMETER :: EddAmbT9N09D3 = 7644 - INTEGER(IntKi), PARAMETER :: EddAmbT9N09D4 = 7645 - INTEGER(IntKi), PARAMETER :: EddAmbT9N09D5 = 7646 - INTEGER(IntKi), PARAMETER :: EddAmbT9N09D6 = 7647 - INTEGER(IntKi), PARAMETER :: EddAmbT9N09D7 = 7648 - INTEGER(IntKi), PARAMETER :: EddAmbT9N09D8 = 7649 - INTEGER(IntKi), PARAMETER :: EddAmbT9N09D9 = 7650 - INTEGER(IntKi), PARAMETER :: EddAmbT9N10D1 = 7651 - INTEGER(IntKi), PARAMETER :: EddAmbT9N10D2 = 7652 - INTEGER(IntKi), PARAMETER :: EddAmbT9N10D3 = 7653 - INTEGER(IntKi), PARAMETER :: EddAmbT9N10D4 = 7654 - INTEGER(IntKi), PARAMETER :: EddAmbT9N10D5 = 7655 - INTEGER(IntKi), PARAMETER :: EddAmbT9N10D6 = 7656 - INTEGER(IntKi), PARAMETER :: EddAmbT9N10D7 = 7657 - INTEGER(IntKi), PARAMETER :: EddAmbT9N10D8 = 7658 - INTEGER(IntKi), PARAMETER :: EddAmbT9N10D9 = 7659 - INTEGER(IntKi), PARAMETER :: EddAmbT9N11D1 = 7660 - INTEGER(IntKi), PARAMETER :: EddAmbT9N11D2 = 7661 - INTEGER(IntKi), PARAMETER :: EddAmbT9N11D3 = 7662 - INTEGER(IntKi), PARAMETER :: EddAmbT9N11D4 = 7663 - INTEGER(IntKi), PARAMETER :: EddAmbT9N11D5 = 7664 - INTEGER(IntKi), PARAMETER :: EddAmbT9N11D6 = 7665 - INTEGER(IntKi), PARAMETER :: EddAmbT9N11D7 = 7666 - INTEGER(IntKi), PARAMETER :: EddAmbT9N11D8 = 7667 - INTEGER(IntKi), PARAMETER :: EddAmbT9N11D9 = 7668 - INTEGER(IntKi), PARAMETER :: EddAmbT9N12D1 = 7669 - INTEGER(IntKi), PARAMETER :: EddAmbT9N12D2 = 7670 - INTEGER(IntKi), PARAMETER :: EddAmbT9N12D3 = 7671 - INTEGER(IntKi), PARAMETER :: EddAmbT9N12D4 = 7672 - INTEGER(IntKi), PARAMETER :: EddAmbT9N12D5 = 7673 - INTEGER(IntKi), PARAMETER :: EddAmbT9N12D6 = 7674 - INTEGER(IntKi), PARAMETER :: EddAmbT9N12D7 = 7675 - INTEGER(IntKi), PARAMETER :: EddAmbT9N12D8 = 7676 - INTEGER(IntKi), PARAMETER :: EddAmbT9N12D9 = 7677 - INTEGER(IntKi), PARAMETER :: EddAmbT9N13D1 = 7678 - INTEGER(IntKi), PARAMETER :: EddAmbT9N13D2 = 7679 - INTEGER(IntKi), PARAMETER :: EddAmbT9N13D3 = 7680 - INTEGER(IntKi), PARAMETER :: EddAmbT9N13D4 = 7681 - INTEGER(IntKi), PARAMETER :: EddAmbT9N13D5 = 7682 - INTEGER(IntKi), PARAMETER :: EddAmbT9N13D6 = 7683 - INTEGER(IntKi), PARAMETER :: EddAmbT9N13D7 = 7684 - INTEGER(IntKi), PARAMETER :: EddAmbT9N13D8 = 7685 - INTEGER(IntKi), PARAMETER :: EddAmbT9N13D9 = 7686 - INTEGER(IntKi), PARAMETER :: EddAmbT9N14D1 = 7687 - INTEGER(IntKi), PARAMETER :: EddAmbT9N14D2 = 7688 - INTEGER(IntKi), PARAMETER :: EddAmbT9N14D3 = 7689 - INTEGER(IntKi), PARAMETER :: EddAmbT9N14D4 = 7690 - INTEGER(IntKi), PARAMETER :: EddAmbT9N14D5 = 7691 - INTEGER(IntKi), PARAMETER :: EddAmbT9N14D6 = 7692 - INTEGER(IntKi), PARAMETER :: EddAmbT9N14D7 = 7693 - INTEGER(IntKi), PARAMETER :: EddAmbT9N14D8 = 7694 - INTEGER(IntKi), PARAMETER :: EddAmbT9N14D9 = 7695 - INTEGER(IntKi), PARAMETER :: EddAmbT9N15D1 = 7696 - INTEGER(IntKi), PARAMETER :: EddAmbT9N15D2 = 7697 - INTEGER(IntKi), PARAMETER :: EddAmbT9N15D3 = 7698 - INTEGER(IntKi), PARAMETER :: EddAmbT9N15D4 = 7699 - INTEGER(IntKi), PARAMETER :: EddAmbT9N15D5 = 7700 - INTEGER(IntKi), PARAMETER :: EddAmbT9N15D6 = 7701 - INTEGER(IntKi), PARAMETER :: EddAmbT9N15D7 = 7702 - INTEGER(IntKi), PARAMETER :: EddAmbT9N15D8 = 7703 - INTEGER(IntKi), PARAMETER :: EddAmbT9N15D9 = 7704 - INTEGER(IntKi), PARAMETER :: EddAmbT9N16D1 = 7705 - INTEGER(IntKi), PARAMETER :: EddAmbT9N16D2 = 7706 - INTEGER(IntKi), PARAMETER :: EddAmbT9N16D3 = 7707 - INTEGER(IntKi), PARAMETER :: EddAmbT9N16D4 = 7708 - INTEGER(IntKi), PARAMETER :: EddAmbT9N16D5 = 7709 - INTEGER(IntKi), PARAMETER :: EddAmbT9N16D6 = 7710 - INTEGER(IntKi), PARAMETER :: EddAmbT9N16D7 = 7711 - INTEGER(IntKi), PARAMETER :: EddAmbT9N16D8 = 7712 - INTEGER(IntKi), PARAMETER :: EddAmbT9N16D9 = 7713 - INTEGER(IntKi), PARAMETER :: EddAmbT9N17D1 = 7714 - INTEGER(IntKi), PARAMETER :: EddAmbT9N17D2 = 7715 - INTEGER(IntKi), PARAMETER :: EddAmbT9N17D3 = 7716 - INTEGER(IntKi), PARAMETER :: EddAmbT9N17D4 = 7717 - INTEGER(IntKi), PARAMETER :: EddAmbT9N17D5 = 7718 - INTEGER(IntKi), PARAMETER :: EddAmbT9N17D6 = 7719 - INTEGER(IntKi), PARAMETER :: EddAmbT9N17D7 = 7720 - INTEGER(IntKi), PARAMETER :: EddAmbT9N17D8 = 7721 - INTEGER(IntKi), PARAMETER :: EddAmbT9N17D9 = 7722 - INTEGER(IntKi), PARAMETER :: EddAmbT9N18D1 = 7723 - INTEGER(IntKi), PARAMETER :: EddAmbT9N18D2 = 7724 - INTEGER(IntKi), PARAMETER :: EddAmbT9N18D3 = 7725 - INTEGER(IntKi), PARAMETER :: EddAmbT9N18D4 = 7726 - INTEGER(IntKi), PARAMETER :: EddAmbT9N18D5 = 7727 - INTEGER(IntKi), PARAMETER :: EddAmbT9N18D6 = 7728 - INTEGER(IntKi), PARAMETER :: EddAmbT9N18D7 = 7729 - INTEGER(IntKi), PARAMETER :: EddAmbT9N18D8 = 7730 - INTEGER(IntKi), PARAMETER :: EddAmbT9N18D9 = 7731 - INTEGER(IntKi), PARAMETER :: EddAmbT9N19D1 = 7732 - INTEGER(IntKi), PARAMETER :: EddAmbT9N19D2 = 7733 - INTEGER(IntKi), PARAMETER :: EddAmbT9N19D3 = 7734 - INTEGER(IntKi), PARAMETER :: EddAmbT9N19D4 = 7735 - INTEGER(IntKi), PARAMETER :: EddAmbT9N19D5 = 7736 - INTEGER(IntKi), PARAMETER :: EddAmbT9N19D6 = 7737 - INTEGER(IntKi), PARAMETER :: EddAmbT9N19D7 = 7738 - INTEGER(IntKi), PARAMETER :: EddAmbT9N19D8 = 7739 - INTEGER(IntKi), PARAMETER :: EddAmbT9N19D9 = 7740 - INTEGER(IntKi), PARAMETER :: EddAmbT9N20D1 = 7741 - INTEGER(IntKi), PARAMETER :: EddAmbT9N20D2 = 7742 - INTEGER(IntKi), PARAMETER :: EddAmbT9N20D3 = 7743 - INTEGER(IntKi), PARAMETER :: EddAmbT9N20D4 = 7744 - INTEGER(IntKi), PARAMETER :: EddAmbT9N20D5 = 7745 - INTEGER(IntKi), PARAMETER :: EddAmbT9N20D6 = 7746 - INTEGER(IntKi), PARAMETER :: EddAmbT9N20D7 = 7747 - INTEGER(IntKi), PARAMETER :: EddAmbT9N20D8 = 7748 - INTEGER(IntKi), PARAMETER :: EddAmbT9N20D9 = 7749 - INTEGER(IntKi), PARAMETER :: EddShrT1N01D1 = 7750 - INTEGER(IntKi), PARAMETER :: EddShrT1N01D2 = 7751 - INTEGER(IntKi), PARAMETER :: EddShrT1N01D3 = 7752 - INTEGER(IntKi), PARAMETER :: EddShrT1N01D4 = 7753 - INTEGER(IntKi), PARAMETER :: EddShrT1N01D5 = 7754 - INTEGER(IntKi), PARAMETER :: EddShrT1N01D6 = 7755 - INTEGER(IntKi), PARAMETER :: EddShrT1N01D7 = 7756 - INTEGER(IntKi), PARAMETER :: EddShrT1N01D8 = 7757 - INTEGER(IntKi), PARAMETER :: EddShrT1N01D9 = 7758 - INTEGER(IntKi), PARAMETER :: EddShrT1N02D1 = 7759 - INTEGER(IntKi), PARAMETER :: EddShrT1N02D2 = 7760 - INTEGER(IntKi), PARAMETER :: EddShrT1N02D3 = 7761 - INTEGER(IntKi), PARAMETER :: EddShrT1N02D4 = 7762 - INTEGER(IntKi), PARAMETER :: EddShrT1N02D5 = 7763 - INTEGER(IntKi), PARAMETER :: EddShrT1N02D6 = 7764 - INTEGER(IntKi), PARAMETER :: EddShrT1N02D7 = 7765 - INTEGER(IntKi), PARAMETER :: EddShrT1N02D8 = 7766 - INTEGER(IntKi), PARAMETER :: EddShrT1N02D9 = 7767 - INTEGER(IntKi), PARAMETER :: EddShrT1N03D1 = 7768 - INTEGER(IntKi), PARAMETER :: EddShrT1N03D2 = 7769 - INTEGER(IntKi), PARAMETER :: EddShrT1N03D3 = 7770 - INTEGER(IntKi), PARAMETER :: EddShrT1N03D4 = 7771 - INTEGER(IntKi), PARAMETER :: EddShrT1N03D5 = 7772 - INTEGER(IntKi), PARAMETER :: EddShrT1N03D6 = 7773 - INTEGER(IntKi), PARAMETER :: EddShrT1N03D7 = 7774 - INTEGER(IntKi), PARAMETER :: EddShrT1N03D8 = 7775 - INTEGER(IntKi), PARAMETER :: EddShrT1N03D9 = 7776 - INTEGER(IntKi), PARAMETER :: EddShrT1N04D1 = 7777 - INTEGER(IntKi), PARAMETER :: EddShrT1N04D2 = 7778 - INTEGER(IntKi), PARAMETER :: EddShrT1N04D3 = 7779 - INTEGER(IntKi), PARAMETER :: EddShrT1N04D4 = 7780 - INTEGER(IntKi), PARAMETER :: EddShrT1N04D5 = 7781 - INTEGER(IntKi), PARAMETER :: EddShrT1N04D6 = 7782 - INTEGER(IntKi), PARAMETER :: EddShrT1N04D7 = 7783 - INTEGER(IntKi), PARAMETER :: EddShrT1N04D8 = 7784 - INTEGER(IntKi), PARAMETER :: EddShrT1N04D9 = 7785 - INTEGER(IntKi), PARAMETER :: EddShrT1N05D1 = 7786 - INTEGER(IntKi), PARAMETER :: EddShrT1N05D2 = 7787 - INTEGER(IntKi), PARAMETER :: EddShrT1N05D3 = 7788 - INTEGER(IntKi), PARAMETER :: EddShrT1N05D4 = 7789 - INTEGER(IntKi), PARAMETER :: EddShrT1N05D5 = 7790 - INTEGER(IntKi), PARAMETER :: EddShrT1N05D6 = 7791 - INTEGER(IntKi), PARAMETER :: EddShrT1N05D7 = 7792 - INTEGER(IntKi), PARAMETER :: EddShrT1N05D8 = 7793 - INTEGER(IntKi), PARAMETER :: EddShrT1N05D9 = 7794 - INTEGER(IntKi), PARAMETER :: EddShrT1N06D1 = 7795 - INTEGER(IntKi), PARAMETER :: EddShrT1N06D2 = 7796 - INTEGER(IntKi), PARAMETER :: EddShrT1N06D3 = 7797 - INTEGER(IntKi), PARAMETER :: EddShrT1N06D4 = 7798 - INTEGER(IntKi), PARAMETER :: EddShrT1N06D5 = 7799 - INTEGER(IntKi), PARAMETER :: EddShrT1N06D6 = 7800 - INTEGER(IntKi), PARAMETER :: EddShrT1N06D7 = 7801 - INTEGER(IntKi), PARAMETER :: EddShrT1N06D8 = 7802 - INTEGER(IntKi), PARAMETER :: EddShrT1N06D9 = 7803 - INTEGER(IntKi), PARAMETER :: EddShrT1N07D1 = 7804 - INTEGER(IntKi), PARAMETER :: EddShrT1N07D2 = 7805 - INTEGER(IntKi), PARAMETER :: EddShrT1N07D3 = 7806 - INTEGER(IntKi), PARAMETER :: EddShrT1N07D4 = 7807 - INTEGER(IntKi), PARAMETER :: EddShrT1N07D5 = 7808 - INTEGER(IntKi), PARAMETER :: EddShrT1N07D6 = 7809 - INTEGER(IntKi), PARAMETER :: EddShrT1N07D7 = 7810 - INTEGER(IntKi), PARAMETER :: EddShrT1N07D8 = 7811 - INTEGER(IntKi), PARAMETER :: EddShrT1N07D9 = 7812 - INTEGER(IntKi), PARAMETER :: EddShrT1N08D1 = 7813 - INTEGER(IntKi), PARAMETER :: EddShrT1N08D2 = 7814 - INTEGER(IntKi), PARAMETER :: EddShrT1N08D3 = 7815 - INTEGER(IntKi), PARAMETER :: EddShrT1N08D4 = 7816 - INTEGER(IntKi), PARAMETER :: EddShrT1N08D5 = 7817 - INTEGER(IntKi), PARAMETER :: EddShrT1N08D6 = 7818 - INTEGER(IntKi), PARAMETER :: EddShrT1N08D7 = 7819 - INTEGER(IntKi), PARAMETER :: EddShrT1N08D8 = 7820 - INTEGER(IntKi), PARAMETER :: EddShrT1N08D9 = 7821 - INTEGER(IntKi), PARAMETER :: EddShrT1N09D1 = 7822 - INTEGER(IntKi), PARAMETER :: EddShrT1N09D2 = 7823 - INTEGER(IntKi), PARAMETER :: EddShrT1N09D3 = 7824 - INTEGER(IntKi), PARAMETER :: EddShrT1N09D4 = 7825 - INTEGER(IntKi), PARAMETER :: EddShrT1N09D5 = 7826 - INTEGER(IntKi), PARAMETER :: EddShrT1N09D6 = 7827 - INTEGER(IntKi), PARAMETER :: EddShrT1N09D7 = 7828 - INTEGER(IntKi), PARAMETER :: EddShrT1N09D8 = 7829 - INTEGER(IntKi), PARAMETER :: EddShrT1N09D9 = 7830 - INTEGER(IntKi), PARAMETER :: EddShrT1N10D1 = 7831 - INTEGER(IntKi), PARAMETER :: EddShrT1N10D2 = 7832 - INTEGER(IntKi), PARAMETER :: EddShrT1N10D3 = 7833 - INTEGER(IntKi), PARAMETER :: EddShrT1N10D4 = 7834 - INTEGER(IntKi), PARAMETER :: EddShrT1N10D5 = 7835 - INTEGER(IntKi), PARAMETER :: EddShrT1N10D6 = 7836 - INTEGER(IntKi), PARAMETER :: EddShrT1N10D7 = 7837 - INTEGER(IntKi), PARAMETER :: EddShrT1N10D8 = 7838 - INTEGER(IntKi), PARAMETER :: EddShrT1N10D9 = 7839 - INTEGER(IntKi), PARAMETER :: EddShrT1N11D1 = 7840 - INTEGER(IntKi), PARAMETER :: EddShrT1N11D2 = 7841 - INTEGER(IntKi), PARAMETER :: EddShrT1N11D3 = 7842 - INTEGER(IntKi), PARAMETER :: EddShrT1N11D4 = 7843 - INTEGER(IntKi), PARAMETER :: EddShrT1N11D5 = 7844 - INTEGER(IntKi), PARAMETER :: EddShrT1N11D6 = 7845 - INTEGER(IntKi), PARAMETER :: EddShrT1N11D7 = 7846 - INTEGER(IntKi), PARAMETER :: EddShrT1N11D8 = 7847 - INTEGER(IntKi), PARAMETER :: EddShrT1N11D9 = 7848 - INTEGER(IntKi), PARAMETER :: EddShrT1N12D1 = 7849 - INTEGER(IntKi), PARAMETER :: EddShrT1N12D2 = 7850 - INTEGER(IntKi), PARAMETER :: EddShrT1N12D3 = 7851 - INTEGER(IntKi), PARAMETER :: EddShrT1N12D4 = 7852 - INTEGER(IntKi), PARAMETER :: EddShrT1N12D5 = 7853 - INTEGER(IntKi), PARAMETER :: EddShrT1N12D6 = 7854 - INTEGER(IntKi), PARAMETER :: EddShrT1N12D7 = 7855 - INTEGER(IntKi), PARAMETER :: EddShrT1N12D8 = 7856 - INTEGER(IntKi), PARAMETER :: EddShrT1N12D9 = 7857 - INTEGER(IntKi), PARAMETER :: EddShrT1N13D1 = 7858 - INTEGER(IntKi), PARAMETER :: EddShrT1N13D2 = 7859 - INTEGER(IntKi), PARAMETER :: EddShrT1N13D3 = 7860 - INTEGER(IntKi), PARAMETER :: EddShrT1N13D4 = 7861 - INTEGER(IntKi), PARAMETER :: EddShrT1N13D5 = 7862 - INTEGER(IntKi), PARAMETER :: EddShrT1N13D6 = 7863 - INTEGER(IntKi), PARAMETER :: EddShrT1N13D7 = 7864 - INTEGER(IntKi), PARAMETER :: EddShrT1N13D8 = 7865 - INTEGER(IntKi), PARAMETER :: EddShrT1N13D9 = 7866 - INTEGER(IntKi), PARAMETER :: EddShrT1N14D1 = 7867 - INTEGER(IntKi), PARAMETER :: EddShrT1N14D2 = 7868 - INTEGER(IntKi), PARAMETER :: EddShrT1N14D3 = 7869 - INTEGER(IntKi), PARAMETER :: EddShrT1N14D4 = 7870 - INTEGER(IntKi), PARAMETER :: EddShrT1N14D5 = 7871 - INTEGER(IntKi), PARAMETER :: EddShrT1N14D6 = 7872 - INTEGER(IntKi), PARAMETER :: EddShrT1N14D7 = 7873 - INTEGER(IntKi), PARAMETER :: EddShrT1N14D8 = 7874 - INTEGER(IntKi), PARAMETER :: EddShrT1N14D9 = 7875 - INTEGER(IntKi), PARAMETER :: EddShrT1N15D1 = 7876 - INTEGER(IntKi), PARAMETER :: EddShrT1N15D2 = 7877 - INTEGER(IntKi), PARAMETER :: EddShrT1N15D3 = 7878 - INTEGER(IntKi), PARAMETER :: EddShrT1N15D4 = 7879 - INTEGER(IntKi), PARAMETER :: EddShrT1N15D5 = 7880 - INTEGER(IntKi), PARAMETER :: EddShrT1N15D6 = 7881 - INTEGER(IntKi), PARAMETER :: EddShrT1N15D7 = 7882 - INTEGER(IntKi), PARAMETER :: EddShrT1N15D8 = 7883 - INTEGER(IntKi), PARAMETER :: EddShrT1N15D9 = 7884 - INTEGER(IntKi), PARAMETER :: EddShrT1N16D1 = 7885 - INTEGER(IntKi), PARAMETER :: EddShrT1N16D2 = 7886 - INTEGER(IntKi), PARAMETER :: EddShrT1N16D3 = 7887 - INTEGER(IntKi), PARAMETER :: EddShrT1N16D4 = 7888 - INTEGER(IntKi), PARAMETER :: EddShrT1N16D5 = 7889 - INTEGER(IntKi), PARAMETER :: EddShrT1N16D6 = 7890 - INTEGER(IntKi), PARAMETER :: EddShrT1N16D7 = 7891 - INTEGER(IntKi), PARAMETER :: EddShrT1N16D8 = 7892 - INTEGER(IntKi), PARAMETER :: EddShrT1N16D9 = 7893 - INTEGER(IntKi), PARAMETER :: EddShrT1N17D1 = 7894 - INTEGER(IntKi), PARAMETER :: EddShrT1N17D2 = 7895 - INTEGER(IntKi), PARAMETER :: EddShrT1N17D3 = 7896 - INTEGER(IntKi), PARAMETER :: EddShrT1N17D4 = 7897 - INTEGER(IntKi), PARAMETER :: EddShrT1N17D5 = 7898 - INTEGER(IntKi), PARAMETER :: EddShrT1N17D6 = 7899 - INTEGER(IntKi), PARAMETER :: EddShrT1N17D7 = 7900 - INTEGER(IntKi), PARAMETER :: EddShrT1N17D8 = 7901 - INTEGER(IntKi), PARAMETER :: EddShrT1N17D9 = 7902 - INTEGER(IntKi), PARAMETER :: EddShrT1N18D1 = 7903 - INTEGER(IntKi), PARAMETER :: EddShrT1N18D2 = 7904 - INTEGER(IntKi), PARAMETER :: EddShrT1N18D3 = 7905 - INTEGER(IntKi), PARAMETER :: EddShrT1N18D4 = 7906 - INTEGER(IntKi), PARAMETER :: EddShrT1N18D5 = 7907 - INTEGER(IntKi), PARAMETER :: EddShrT1N18D6 = 7908 - INTEGER(IntKi), PARAMETER :: EddShrT1N18D7 = 7909 - INTEGER(IntKi), PARAMETER :: EddShrT1N18D8 = 7910 - INTEGER(IntKi), PARAMETER :: EddShrT1N18D9 = 7911 - INTEGER(IntKi), PARAMETER :: EddShrT1N19D1 = 7912 - INTEGER(IntKi), PARAMETER :: EddShrT1N19D2 = 7913 - INTEGER(IntKi), PARAMETER :: EddShrT1N19D3 = 7914 - INTEGER(IntKi), PARAMETER :: EddShrT1N19D4 = 7915 - INTEGER(IntKi), PARAMETER :: EddShrT1N19D5 = 7916 - INTEGER(IntKi), PARAMETER :: EddShrT1N19D6 = 7917 - INTEGER(IntKi), PARAMETER :: EddShrT1N19D7 = 7918 - INTEGER(IntKi), PARAMETER :: EddShrT1N19D8 = 7919 - INTEGER(IntKi), PARAMETER :: EddShrT1N19D9 = 7920 - INTEGER(IntKi), PARAMETER :: EddShrT1N20D1 = 7921 - INTEGER(IntKi), PARAMETER :: EddShrT1N20D2 = 7922 - INTEGER(IntKi), PARAMETER :: EddShrT1N20D3 = 7923 - INTEGER(IntKi), PARAMETER :: EddShrT1N20D4 = 7924 - INTEGER(IntKi), PARAMETER :: EddShrT1N20D5 = 7925 - INTEGER(IntKi), PARAMETER :: EddShrT1N20D6 = 7926 - INTEGER(IntKi), PARAMETER :: EddShrT1N20D7 = 7927 - INTEGER(IntKi), PARAMETER :: EddShrT1N20D8 = 7928 - INTEGER(IntKi), PARAMETER :: EddShrT1N20D9 = 7929 - INTEGER(IntKi), PARAMETER :: EddShrT2N01D1 = 7930 - INTEGER(IntKi), PARAMETER :: EddShrT2N01D2 = 7931 - INTEGER(IntKi), PARAMETER :: EddShrT2N01D3 = 7932 - INTEGER(IntKi), PARAMETER :: EddShrT2N01D4 = 7933 - INTEGER(IntKi), PARAMETER :: EddShrT2N01D5 = 7934 - INTEGER(IntKi), PARAMETER :: EddShrT2N01D6 = 7935 - INTEGER(IntKi), PARAMETER :: EddShrT2N01D7 = 7936 - INTEGER(IntKi), PARAMETER :: EddShrT2N01D8 = 7937 - INTEGER(IntKi), PARAMETER :: EddShrT2N01D9 = 7938 - INTEGER(IntKi), PARAMETER :: EddShrT2N02D1 = 7939 - INTEGER(IntKi), PARAMETER :: EddShrT2N02D2 = 7940 - INTEGER(IntKi), PARAMETER :: EddShrT2N02D3 = 7941 - INTEGER(IntKi), PARAMETER :: EddShrT2N02D4 = 7942 - INTEGER(IntKi), PARAMETER :: EddShrT2N02D5 = 7943 - INTEGER(IntKi), PARAMETER :: EddShrT2N02D6 = 7944 - INTEGER(IntKi), PARAMETER :: EddShrT2N02D7 = 7945 - INTEGER(IntKi), PARAMETER :: EddShrT2N02D8 = 7946 - INTEGER(IntKi), PARAMETER :: EddShrT2N02D9 = 7947 - INTEGER(IntKi), PARAMETER :: EddShrT2N03D1 = 7948 - INTEGER(IntKi), PARAMETER :: EddShrT2N03D2 = 7949 - INTEGER(IntKi), PARAMETER :: EddShrT2N03D3 = 7950 - INTEGER(IntKi), PARAMETER :: EddShrT2N03D4 = 7951 - INTEGER(IntKi), PARAMETER :: EddShrT2N03D5 = 7952 - INTEGER(IntKi), PARAMETER :: EddShrT2N03D6 = 7953 - INTEGER(IntKi), PARAMETER :: EddShrT2N03D7 = 7954 - INTEGER(IntKi), PARAMETER :: EddShrT2N03D8 = 7955 - INTEGER(IntKi), PARAMETER :: EddShrT2N03D9 = 7956 - INTEGER(IntKi), PARAMETER :: EddShrT2N04D1 = 7957 - INTEGER(IntKi), PARAMETER :: EddShrT2N04D2 = 7958 - INTEGER(IntKi), PARAMETER :: EddShrT2N04D3 = 7959 - INTEGER(IntKi), PARAMETER :: EddShrT2N04D4 = 7960 - INTEGER(IntKi), PARAMETER :: EddShrT2N04D5 = 7961 - INTEGER(IntKi), PARAMETER :: EddShrT2N04D6 = 7962 - INTEGER(IntKi), PARAMETER :: EddShrT2N04D7 = 7963 - INTEGER(IntKi), PARAMETER :: EddShrT2N04D8 = 7964 - INTEGER(IntKi), PARAMETER :: EddShrT2N04D9 = 7965 - INTEGER(IntKi), PARAMETER :: EddShrT2N05D1 = 7966 - INTEGER(IntKi), PARAMETER :: EddShrT2N05D2 = 7967 - INTEGER(IntKi), PARAMETER :: EddShrT2N05D3 = 7968 - INTEGER(IntKi), PARAMETER :: EddShrT2N05D4 = 7969 - INTEGER(IntKi), PARAMETER :: EddShrT2N05D5 = 7970 - INTEGER(IntKi), PARAMETER :: EddShrT2N05D6 = 7971 - INTEGER(IntKi), PARAMETER :: EddShrT2N05D7 = 7972 - INTEGER(IntKi), PARAMETER :: EddShrT2N05D8 = 7973 - INTEGER(IntKi), PARAMETER :: EddShrT2N05D9 = 7974 - INTEGER(IntKi), PARAMETER :: EddShrT2N06D1 = 7975 - INTEGER(IntKi), PARAMETER :: EddShrT2N06D2 = 7976 - INTEGER(IntKi), PARAMETER :: EddShrT2N06D3 = 7977 - INTEGER(IntKi), PARAMETER :: EddShrT2N06D4 = 7978 - INTEGER(IntKi), PARAMETER :: EddShrT2N06D5 = 7979 - INTEGER(IntKi), PARAMETER :: EddShrT2N06D6 = 7980 - INTEGER(IntKi), PARAMETER :: EddShrT2N06D7 = 7981 - INTEGER(IntKi), PARAMETER :: EddShrT2N06D8 = 7982 - INTEGER(IntKi), PARAMETER :: EddShrT2N06D9 = 7983 - INTEGER(IntKi), PARAMETER :: EddShrT2N07D1 = 7984 - INTEGER(IntKi), PARAMETER :: EddShrT2N07D2 = 7985 - INTEGER(IntKi), PARAMETER :: EddShrT2N07D3 = 7986 - INTEGER(IntKi), PARAMETER :: EddShrT2N07D4 = 7987 - INTEGER(IntKi), PARAMETER :: EddShrT2N07D5 = 7988 - INTEGER(IntKi), PARAMETER :: EddShrT2N07D6 = 7989 - INTEGER(IntKi), PARAMETER :: EddShrT2N07D7 = 7990 - INTEGER(IntKi), PARAMETER :: EddShrT2N07D8 = 7991 - INTEGER(IntKi), PARAMETER :: EddShrT2N07D9 = 7992 - INTEGER(IntKi), PARAMETER :: EddShrT2N08D1 = 7993 - INTEGER(IntKi), PARAMETER :: EddShrT2N08D2 = 7994 - INTEGER(IntKi), PARAMETER :: EddShrT2N08D3 = 7995 - INTEGER(IntKi), PARAMETER :: EddShrT2N08D4 = 7996 - INTEGER(IntKi), PARAMETER :: EddShrT2N08D5 = 7997 - INTEGER(IntKi), PARAMETER :: EddShrT2N08D6 = 7998 - INTEGER(IntKi), PARAMETER :: EddShrT2N08D7 = 7999 - INTEGER(IntKi), PARAMETER :: EddShrT2N08D8 = 8000 - INTEGER(IntKi), PARAMETER :: EddShrT2N08D9 = 8001 - INTEGER(IntKi), PARAMETER :: EddShrT2N09D1 = 8002 - INTEGER(IntKi), PARAMETER :: EddShrT2N09D2 = 8003 - INTEGER(IntKi), PARAMETER :: EddShrT2N09D3 = 8004 - INTEGER(IntKi), PARAMETER :: EddShrT2N09D4 = 8005 - INTEGER(IntKi), PARAMETER :: EddShrT2N09D5 = 8006 - INTEGER(IntKi), PARAMETER :: EddShrT2N09D6 = 8007 - INTEGER(IntKi), PARAMETER :: EddShrT2N09D7 = 8008 - INTEGER(IntKi), PARAMETER :: EddShrT2N09D8 = 8009 - INTEGER(IntKi), PARAMETER :: EddShrT2N09D9 = 8010 - INTEGER(IntKi), PARAMETER :: EddShrT2N10D1 = 8011 - INTEGER(IntKi), PARAMETER :: EddShrT2N10D2 = 8012 - INTEGER(IntKi), PARAMETER :: EddShrT2N10D3 = 8013 - INTEGER(IntKi), PARAMETER :: EddShrT2N10D4 = 8014 - INTEGER(IntKi), PARAMETER :: EddShrT2N10D5 = 8015 - INTEGER(IntKi), PARAMETER :: EddShrT2N10D6 = 8016 - INTEGER(IntKi), PARAMETER :: EddShrT2N10D7 = 8017 - INTEGER(IntKi), PARAMETER :: EddShrT2N10D8 = 8018 - INTEGER(IntKi), PARAMETER :: EddShrT2N10D9 = 8019 - INTEGER(IntKi), PARAMETER :: EddShrT2N11D1 = 8020 - INTEGER(IntKi), PARAMETER :: EddShrT2N11D2 = 8021 - INTEGER(IntKi), PARAMETER :: EddShrT2N11D3 = 8022 - INTEGER(IntKi), PARAMETER :: EddShrT2N11D4 = 8023 - INTEGER(IntKi), PARAMETER :: EddShrT2N11D5 = 8024 - INTEGER(IntKi), PARAMETER :: EddShrT2N11D6 = 8025 - INTEGER(IntKi), PARAMETER :: EddShrT2N11D7 = 8026 - INTEGER(IntKi), PARAMETER :: EddShrT2N11D8 = 8027 - INTEGER(IntKi), PARAMETER :: EddShrT2N11D9 = 8028 - INTEGER(IntKi), PARAMETER :: EddShrT2N12D1 = 8029 - INTEGER(IntKi), PARAMETER :: EddShrT2N12D2 = 8030 - INTEGER(IntKi), PARAMETER :: EddShrT2N12D3 = 8031 - INTEGER(IntKi), PARAMETER :: EddShrT2N12D4 = 8032 - INTEGER(IntKi), PARAMETER :: EddShrT2N12D5 = 8033 - INTEGER(IntKi), PARAMETER :: EddShrT2N12D6 = 8034 - INTEGER(IntKi), PARAMETER :: EddShrT2N12D7 = 8035 - INTEGER(IntKi), PARAMETER :: EddShrT2N12D8 = 8036 - INTEGER(IntKi), PARAMETER :: EddShrT2N12D9 = 8037 - INTEGER(IntKi), PARAMETER :: EddShrT2N13D1 = 8038 - INTEGER(IntKi), PARAMETER :: EddShrT2N13D2 = 8039 - INTEGER(IntKi), PARAMETER :: EddShrT2N13D3 = 8040 - INTEGER(IntKi), PARAMETER :: EddShrT2N13D4 = 8041 - INTEGER(IntKi), PARAMETER :: EddShrT2N13D5 = 8042 - INTEGER(IntKi), PARAMETER :: EddShrT2N13D6 = 8043 - INTEGER(IntKi), PARAMETER :: EddShrT2N13D7 = 8044 - INTEGER(IntKi), PARAMETER :: EddShrT2N13D8 = 8045 - INTEGER(IntKi), PARAMETER :: EddShrT2N13D9 = 8046 - INTEGER(IntKi), PARAMETER :: EddShrT2N14D1 = 8047 - INTEGER(IntKi), PARAMETER :: EddShrT2N14D2 = 8048 - INTEGER(IntKi), PARAMETER :: EddShrT2N14D3 = 8049 - INTEGER(IntKi), PARAMETER :: EddShrT2N14D4 = 8050 - INTEGER(IntKi), PARAMETER :: EddShrT2N14D5 = 8051 - INTEGER(IntKi), PARAMETER :: EddShrT2N14D6 = 8052 - INTEGER(IntKi), PARAMETER :: EddShrT2N14D7 = 8053 - INTEGER(IntKi), PARAMETER :: EddShrT2N14D8 = 8054 - INTEGER(IntKi), PARAMETER :: EddShrT2N14D9 = 8055 - INTEGER(IntKi), PARAMETER :: EddShrT2N15D1 = 8056 - INTEGER(IntKi), PARAMETER :: EddShrT2N15D2 = 8057 - INTEGER(IntKi), PARAMETER :: EddShrT2N15D3 = 8058 - INTEGER(IntKi), PARAMETER :: EddShrT2N15D4 = 8059 - INTEGER(IntKi), PARAMETER :: EddShrT2N15D5 = 8060 - INTEGER(IntKi), PARAMETER :: EddShrT2N15D6 = 8061 - INTEGER(IntKi), PARAMETER :: EddShrT2N15D7 = 8062 - INTEGER(IntKi), PARAMETER :: EddShrT2N15D8 = 8063 - INTEGER(IntKi), PARAMETER :: EddShrT2N15D9 = 8064 - INTEGER(IntKi), PARAMETER :: EddShrT2N16D1 = 8065 - INTEGER(IntKi), PARAMETER :: EddShrT2N16D2 = 8066 - INTEGER(IntKi), PARAMETER :: EddShrT2N16D3 = 8067 - INTEGER(IntKi), PARAMETER :: EddShrT2N16D4 = 8068 - INTEGER(IntKi), PARAMETER :: EddShrT2N16D5 = 8069 - INTEGER(IntKi), PARAMETER :: EddShrT2N16D6 = 8070 - INTEGER(IntKi), PARAMETER :: EddShrT2N16D7 = 8071 - INTEGER(IntKi), PARAMETER :: EddShrT2N16D8 = 8072 - INTEGER(IntKi), PARAMETER :: EddShrT2N16D9 = 8073 - INTEGER(IntKi), PARAMETER :: EddShrT2N17D1 = 8074 - INTEGER(IntKi), PARAMETER :: EddShrT2N17D2 = 8075 - INTEGER(IntKi), PARAMETER :: EddShrT2N17D3 = 8076 - INTEGER(IntKi), PARAMETER :: EddShrT2N17D4 = 8077 - INTEGER(IntKi), PARAMETER :: EddShrT2N17D5 = 8078 - INTEGER(IntKi), PARAMETER :: EddShrT2N17D6 = 8079 - INTEGER(IntKi), PARAMETER :: EddShrT2N17D7 = 8080 - INTEGER(IntKi), PARAMETER :: EddShrT2N17D8 = 8081 - INTEGER(IntKi), PARAMETER :: EddShrT2N17D9 = 8082 - INTEGER(IntKi), PARAMETER :: EddShrT2N18D1 = 8083 - INTEGER(IntKi), PARAMETER :: EddShrT2N18D2 = 8084 - INTEGER(IntKi), PARAMETER :: EddShrT2N18D3 = 8085 - INTEGER(IntKi), PARAMETER :: EddShrT2N18D4 = 8086 - INTEGER(IntKi), PARAMETER :: EddShrT2N18D5 = 8087 - INTEGER(IntKi), PARAMETER :: EddShrT2N18D6 = 8088 - INTEGER(IntKi), PARAMETER :: EddShrT2N18D7 = 8089 - INTEGER(IntKi), PARAMETER :: EddShrT2N18D8 = 8090 - INTEGER(IntKi), PARAMETER :: EddShrT2N18D9 = 8091 - INTEGER(IntKi), PARAMETER :: EddShrT2N19D1 = 8092 - INTEGER(IntKi), PARAMETER :: EddShrT2N19D2 = 8093 - INTEGER(IntKi), PARAMETER :: EddShrT2N19D3 = 8094 - INTEGER(IntKi), PARAMETER :: EddShrT2N19D4 = 8095 - INTEGER(IntKi), PARAMETER :: EddShrT2N19D5 = 8096 - INTEGER(IntKi), PARAMETER :: EddShrT2N19D6 = 8097 - INTEGER(IntKi), PARAMETER :: EddShrT2N19D7 = 8098 - INTEGER(IntKi), PARAMETER :: EddShrT2N19D8 = 8099 - INTEGER(IntKi), PARAMETER :: EddShrT2N19D9 = 8100 - INTEGER(IntKi), PARAMETER :: EddShrT2N20D1 = 8101 - INTEGER(IntKi), PARAMETER :: EddShrT2N20D2 = 8102 - INTEGER(IntKi), PARAMETER :: EddShrT2N20D3 = 8103 - INTEGER(IntKi), PARAMETER :: EddShrT2N20D4 = 8104 - INTEGER(IntKi), PARAMETER :: EddShrT2N20D5 = 8105 - INTEGER(IntKi), PARAMETER :: EddShrT2N20D6 = 8106 - INTEGER(IntKi), PARAMETER :: EddShrT2N20D7 = 8107 - INTEGER(IntKi), PARAMETER :: EddShrT2N20D8 = 8108 - INTEGER(IntKi), PARAMETER :: EddShrT2N20D9 = 8109 - INTEGER(IntKi), PARAMETER :: EddShrT3N01D1 = 8110 - INTEGER(IntKi), PARAMETER :: EddShrT3N01D2 = 8111 - INTEGER(IntKi), PARAMETER :: EddShrT3N01D3 = 8112 - INTEGER(IntKi), PARAMETER :: EddShrT3N01D4 = 8113 - INTEGER(IntKi), PARAMETER :: EddShrT3N01D5 = 8114 - INTEGER(IntKi), PARAMETER :: EddShrT3N01D6 = 8115 - INTEGER(IntKi), PARAMETER :: EddShrT3N01D7 = 8116 - INTEGER(IntKi), PARAMETER :: EddShrT3N01D8 = 8117 - INTEGER(IntKi), PARAMETER :: EddShrT3N01D9 = 8118 - INTEGER(IntKi), PARAMETER :: EddShrT3N02D1 = 8119 - INTEGER(IntKi), PARAMETER :: EddShrT3N02D2 = 8120 - INTEGER(IntKi), PARAMETER :: EddShrT3N02D3 = 8121 - INTEGER(IntKi), PARAMETER :: EddShrT3N02D4 = 8122 - INTEGER(IntKi), PARAMETER :: EddShrT3N02D5 = 8123 - INTEGER(IntKi), PARAMETER :: EddShrT3N02D6 = 8124 - INTEGER(IntKi), PARAMETER :: EddShrT3N02D7 = 8125 - INTEGER(IntKi), PARAMETER :: EddShrT3N02D8 = 8126 - INTEGER(IntKi), PARAMETER :: EddShrT3N02D9 = 8127 - INTEGER(IntKi), PARAMETER :: EddShrT3N03D1 = 8128 - INTEGER(IntKi), PARAMETER :: EddShrT3N03D2 = 8129 - INTEGER(IntKi), PARAMETER :: EddShrT3N03D3 = 8130 - INTEGER(IntKi), PARAMETER :: EddShrT3N03D4 = 8131 - INTEGER(IntKi), PARAMETER :: EddShrT3N03D5 = 8132 - INTEGER(IntKi), PARAMETER :: EddShrT3N03D6 = 8133 - INTEGER(IntKi), PARAMETER :: EddShrT3N03D7 = 8134 - INTEGER(IntKi), PARAMETER :: EddShrT3N03D8 = 8135 - INTEGER(IntKi), PARAMETER :: EddShrT3N03D9 = 8136 - INTEGER(IntKi), PARAMETER :: EddShrT3N04D1 = 8137 - INTEGER(IntKi), PARAMETER :: EddShrT3N04D2 = 8138 - INTEGER(IntKi), PARAMETER :: EddShrT3N04D3 = 8139 - INTEGER(IntKi), PARAMETER :: EddShrT3N04D4 = 8140 - INTEGER(IntKi), PARAMETER :: EddShrT3N04D5 = 8141 - INTEGER(IntKi), PARAMETER :: EddShrT3N04D6 = 8142 - INTEGER(IntKi), PARAMETER :: EddShrT3N04D7 = 8143 - INTEGER(IntKi), PARAMETER :: EddShrT3N04D8 = 8144 - INTEGER(IntKi), PARAMETER :: EddShrT3N04D9 = 8145 - INTEGER(IntKi), PARAMETER :: EddShrT3N05D1 = 8146 - INTEGER(IntKi), PARAMETER :: EddShrT3N05D2 = 8147 - INTEGER(IntKi), PARAMETER :: EddShrT3N05D3 = 8148 - INTEGER(IntKi), PARAMETER :: EddShrT3N05D4 = 8149 - INTEGER(IntKi), PARAMETER :: EddShrT3N05D5 = 8150 - INTEGER(IntKi), PARAMETER :: EddShrT3N05D6 = 8151 - INTEGER(IntKi), PARAMETER :: EddShrT3N05D7 = 8152 - INTEGER(IntKi), PARAMETER :: EddShrT3N05D8 = 8153 - INTEGER(IntKi), PARAMETER :: EddShrT3N05D9 = 8154 - INTEGER(IntKi), PARAMETER :: EddShrT3N06D1 = 8155 - INTEGER(IntKi), PARAMETER :: EddShrT3N06D2 = 8156 - INTEGER(IntKi), PARAMETER :: EddShrT3N06D3 = 8157 - INTEGER(IntKi), PARAMETER :: EddShrT3N06D4 = 8158 - INTEGER(IntKi), PARAMETER :: EddShrT3N06D5 = 8159 - INTEGER(IntKi), PARAMETER :: EddShrT3N06D6 = 8160 - INTEGER(IntKi), PARAMETER :: EddShrT3N06D7 = 8161 - INTEGER(IntKi), PARAMETER :: EddShrT3N06D8 = 8162 - INTEGER(IntKi), PARAMETER :: EddShrT3N06D9 = 8163 - INTEGER(IntKi), PARAMETER :: EddShrT3N07D1 = 8164 - INTEGER(IntKi), PARAMETER :: EddShrT3N07D2 = 8165 - INTEGER(IntKi), PARAMETER :: EddShrT3N07D3 = 8166 - INTEGER(IntKi), PARAMETER :: EddShrT3N07D4 = 8167 - INTEGER(IntKi), PARAMETER :: EddShrT3N07D5 = 8168 - INTEGER(IntKi), PARAMETER :: EddShrT3N07D6 = 8169 - INTEGER(IntKi), PARAMETER :: EddShrT3N07D7 = 8170 - INTEGER(IntKi), PARAMETER :: EddShrT3N07D8 = 8171 - INTEGER(IntKi), PARAMETER :: EddShrT3N07D9 = 8172 - INTEGER(IntKi), PARAMETER :: EddShrT3N08D1 = 8173 - INTEGER(IntKi), PARAMETER :: EddShrT3N08D2 = 8174 - INTEGER(IntKi), PARAMETER :: EddShrT3N08D3 = 8175 - INTEGER(IntKi), PARAMETER :: EddShrT3N08D4 = 8176 - INTEGER(IntKi), PARAMETER :: EddShrT3N08D5 = 8177 - INTEGER(IntKi), PARAMETER :: EddShrT3N08D6 = 8178 - INTEGER(IntKi), PARAMETER :: EddShrT3N08D7 = 8179 - INTEGER(IntKi), PARAMETER :: EddShrT3N08D8 = 8180 - INTEGER(IntKi), PARAMETER :: EddShrT3N08D9 = 8181 - INTEGER(IntKi), PARAMETER :: EddShrT3N09D1 = 8182 - INTEGER(IntKi), PARAMETER :: EddShrT3N09D2 = 8183 - INTEGER(IntKi), PARAMETER :: EddShrT3N09D3 = 8184 - INTEGER(IntKi), PARAMETER :: EddShrT3N09D4 = 8185 - INTEGER(IntKi), PARAMETER :: EddShrT3N09D5 = 8186 - INTEGER(IntKi), PARAMETER :: EddShrT3N09D6 = 8187 - INTEGER(IntKi), PARAMETER :: EddShrT3N09D7 = 8188 - INTEGER(IntKi), PARAMETER :: EddShrT3N09D8 = 8189 - INTEGER(IntKi), PARAMETER :: EddShrT3N09D9 = 8190 - INTEGER(IntKi), PARAMETER :: EddShrT3N10D1 = 8191 - INTEGER(IntKi), PARAMETER :: EddShrT3N10D2 = 8192 - INTEGER(IntKi), PARAMETER :: EddShrT3N10D3 = 8193 - INTEGER(IntKi), PARAMETER :: EddShrT3N10D4 = 8194 - INTEGER(IntKi), PARAMETER :: EddShrT3N10D5 = 8195 - INTEGER(IntKi), PARAMETER :: EddShrT3N10D6 = 8196 - INTEGER(IntKi), PARAMETER :: EddShrT3N10D7 = 8197 - INTEGER(IntKi), PARAMETER :: EddShrT3N10D8 = 8198 - INTEGER(IntKi), PARAMETER :: EddShrT3N10D9 = 8199 - INTEGER(IntKi), PARAMETER :: EddShrT3N11D1 = 8200 - INTEGER(IntKi), PARAMETER :: EddShrT3N11D2 = 8201 - INTEGER(IntKi), PARAMETER :: EddShrT3N11D3 = 8202 - INTEGER(IntKi), PARAMETER :: EddShrT3N11D4 = 8203 - INTEGER(IntKi), PARAMETER :: EddShrT3N11D5 = 8204 - INTEGER(IntKi), PARAMETER :: EddShrT3N11D6 = 8205 - INTEGER(IntKi), PARAMETER :: EddShrT3N11D7 = 8206 - INTEGER(IntKi), PARAMETER :: EddShrT3N11D8 = 8207 - INTEGER(IntKi), PARAMETER :: EddShrT3N11D9 = 8208 - INTEGER(IntKi), PARAMETER :: EddShrT3N12D1 = 8209 - INTEGER(IntKi), PARAMETER :: EddShrT3N12D2 = 8210 - INTEGER(IntKi), PARAMETER :: EddShrT3N12D3 = 8211 - INTEGER(IntKi), PARAMETER :: EddShrT3N12D4 = 8212 - INTEGER(IntKi), PARAMETER :: EddShrT3N12D5 = 8213 - INTEGER(IntKi), PARAMETER :: EddShrT3N12D6 = 8214 - INTEGER(IntKi), PARAMETER :: EddShrT3N12D7 = 8215 - INTEGER(IntKi), PARAMETER :: EddShrT3N12D8 = 8216 - INTEGER(IntKi), PARAMETER :: EddShrT3N12D9 = 8217 - INTEGER(IntKi), PARAMETER :: EddShrT3N13D1 = 8218 - INTEGER(IntKi), PARAMETER :: EddShrT3N13D2 = 8219 - INTEGER(IntKi), PARAMETER :: EddShrT3N13D3 = 8220 - INTEGER(IntKi), PARAMETER :: EddShrT3N13D4 = 8221 - INTEGER(IntKi), PARAMETER :: EddShrT3N13D5 = 8222 - INTEGER(IntKi), PARAMETER :: EddShrT3N13D6 = 8223 - INTEGER(IntKi), PARAMETER :: EddShrT3N13D7 = 8224 - INTEGER(IntKi), PARAMETER :: EddShrT3N13D8 = 8225 - INTEGER(IntKi), PARAMETER :: EddShrT3N13D9 = 8226 - INTEGER(IntKi), PARAMETER :: EddShrT3N14D1 = 8227 - INTEGER(IntKi), PARAMETER :: EddShrT3N14D2 = 8228 - INTEGER(IntKi), PARAMETER :: EddShrT3N14D3 = 8229 - INTEGER(IntKi), PARAMETER :: EddShrT3N14D4 = 8230 - INTEGER(IntKi), PARAMETER :: EddShrT3N14D5 = 8231 - INTEGER(IntKi), PARAMETER :: EddShrT3N14D6 = 8232 - INTEGER(IntKi), PARAMETER :: EddShrT3N14D7 = 8233 - INTEGER(IntKi), PARAMETER :: EddShrT3N14D8 = 8234 - INTEGER(IntKi), PARAMETER :: EddShrT3N14D9 = 8235 - INTEGER(IntKi), PARAMETER :: EddShrT3N15D1 = 8236 - INTEGER(IntKi), PARAMETER :: EddShrT3N15D2 = 8237 - INTEGER(IntKi), PARAMETER :: EddShrT3N15D3 = 8238 - INTEGER(IntKi), PARAMETER :: EddShrT3N15D4 = 8239 - INTEGER(IntKi), PARAMETER :: EddShrT3N15D5 = 8240 - INTEGER(IntKi), PARAMETER :: EddShrT3N15D6 = 8241 - INTEGER(IntKi), PARAMETER :: EddShrT3N15D7 = 8242 - INTEGER(IntKi), PARAMETER :: EddShrT3N15D8 = 8243 - INTEGER(IntKi), PARAMETER :: EddShrT3N15D9 = 8244 - INTEGER(IntKi), PARAMETER :: EddShrT3N16D1 = 8245 - INTEGER(IntKi), PARAMETER :: EddShrT3N16D2 = 8246 - INTEGER(IntKi), PARAMETER :: EddShrT3N16D3 = 8247 - INTEGER(IntKi), PARAMETER :: EddShrT3N16D4 = 8248 - INTEGER(IntKi), PARAMETER :: EddShrT3N16D5 = 8249 - INTEGER(IntKi), PARAMETER :: EddShrT3N16D6 = 8250 - INTEGER(IntKi), PARAMETER :: EddShrT3N16D7 = 8251 - INTEGER(IntKi), PARAMETER :: EddShrT3N16D8 = 8252 - INTEGER(IntKi), PARAMETER :: EddShrT3N16D9 = 8253 - INTEGER(IntKi), PARAMETER :: EddShrT3N17D1 = 8254 - INTEGER(IntKi), PARAMETER :: EddShrT3N17D2 = 8255 - INTEGER(IntKi), PARAMETER :: EddShrT3N17D3 = 8256 - INTEGER(IntKi), PARAMETER :: EddShrT3N17D4 = 8257 - INTEGER(IntKi), PARAMETER :: EddShrT3N17D5 = 8258 - INTEGER(IntKi), PARAMETER :: EddShrT3N17D6 = 8259 - INTEGER(IntKi), PARAMETER :: EddShrT3N17D7 = 8260 - INTEGER(IntKi), PARAMETER :: EddShrT3N17D8 = 8261 - INTEGER(IntKi), PARAMETER :: EddShrT3N17D9 = 8262 - INTEGER(IntKi), PARAMETER :: EddShrT3N18D1 = 8263 - INTEGER(IntKi), PARAMETER :: EddShrT3N18D2 = 8264 - INTEGER(IntKi), PARAMETER :: EddShrT3N18D3 = 8265 - INTEGER(IntKi), PARAMETER :: EddShrT3N18D4 = 8266 - INTEGER(IntKi), PARAMETER :: EddShrT3N18D5 = 8267 - INTEGER(IntKi), PARAMETER :: EddShrT3N18D6 = 8268 - INTEGER(IntKi), PARAMETER :: EddShrT3N18D7 = 8269 - INTEGER(IntKi), PARAMETER :: EddShrT3N18D8 = 8270 - INTEGER(IntKi), PARAMETER :: EddShrT3N18D9 = 8271 - INTEGER(IntKi), PARAMETER :: EddShrT3N19D1 = 8272 - INTEGER(IntKi), PARAMETER :: EddShrT3N19D2 = 8273 - INTEGER(IntKi), PARAMETER :: EddShrT3N19D3 = 8274 - INTEGER(IntKi), PARAMETER :: EddShrT3N19D4 = 8275 - INTEGER(IntKi), PARAMETER :: EddShrT3N19D5 = 8276 - INTEGER(IntKi), PARAMETER :: EddShrT3N19D6 = 8277 - INTEGER(IntKi), PARAMETER :: EddShrT3N19D7 = 8278 - INTEGER(IntKi), PARAMETER :: EddShrT3N19D8 = 8279 - INTEGER(IntKi), PARAMETER :: EddShrT3N19D9 = 8280 - INTEGER(IntKi), PARAMETER :: EddShrT3N20D1 = 8281 - INTEGER(IntKi), PARAMETER :: EddShrT3N20D2 = 8282 - INTEGER(IntKi), PARAMETER :: EddShrT3N20D3 = 8283 - INTEGER(IntKi), PARAMETER :: EddShrT3N20D4 = 8284 - INTEGER(IntKi), PARAMETER :: EddShrT3N20D5 = 8285 - INTEGER(IntKi), PARAMETER :: EddShrT3N20D6 = 8286 - INTEGER(IntKi), PARAMETER :: EddShrT3N20D7 = 8287 - INTEGER(IntKi), PARAMETER :: EddShrT3N20D8 = 8288 - INTEGER(IntKi), PARAMETER :: EddShrT3N20D9 = 8289 - INTEGER(IntKi), PARAMETER :: EddShrT4N01D1 = 8290 - INTEGER(IntKi), PARAMETER :: EddShrT4N01D2 = 8291 - INTEGER(IntKi), PARAMETER :: EddShrT4N01D3 = 8292 - INTEGER(IntKi), PARAMETER :: EddShrT4N01D4 = 8293 - INTEGER(IntKi), PARAMETER :: EddShrT4N01D5 = 8294 - INTEGER(IntKi), PARAMETER :: EddShrT4N01D6 = 8295 - INTEGER(IntKi), PARAMETER :: EddShrT4N01D7 = 8296 - INTEGER(IntKi), PARAMETER :: EddShrT4N01D8 = 8297 - INTEGER(IntKi), PARAMETER :: EddShrT4N01D9 = 8298 - INTEGER(IntKi), PARAMETER :: EddShrT4N02D1 = 8299 - INTEGER(IntKi), PARAMETER :: EddShrT4N02D2 = 8300 - INTEGER(IntKi), PARAMETER :: EddShrT4N02D3 = 8301 - INTEGER(IntKi), PARAMETER :: EddShrT4N02D4 = 8302 - INTEGER(IntKi), PARAMETER :: EddShrT4N02D5 = 8303 - INTEGER(IntKi), PARAMETER :: EddShrT4N02D6 = 8304 - INTEGER(IntKi), PARAMETER :: EddShrT4N02D7 = 8305 - INTEGER(IntKi), PARAMETER :: EddShrT4N02D8 = 8306 - INTEGER(IntKi), PARAMETER :: EddShrT4N02D9 = 8307 - INTEGER(IntKi), PARAMETER :: EddShrT4N03D1 = 8308 - INTEGER(IntKi), PARAMETER :: EddShrT4N03D2 = 8309 - INTEGER(IntKi), PARAMETER :: EddShrT4N03D3 = 8310 - INTEGER(IntKi), PARAMETER :: EddShrT4N03D4 = 8311 - INTEGER(IntKi), PARAMETER :: EddShrT4N03D5 = 8312 - INTEGER(IntKi), PARAMETER :: EddShrT4N03D6 = 8313 - INTEGER(IntKi), PARAMETER :: EddShrT4N03D7 = 8314 - INTEGER(IntKi), PARAMETER :: EddShrT4N03D8 = 8315 - INTEGER(IntKi), PARAMETER :: EddShrT4N03D9 = 8316 - INTEGER(IntKi), PARAMETER :: EddShrT4N04D1 = 8317 - INTEGER(IntKi), PARAMETER :: EddShrT4N04D2 = 8318 - INTEGER(IntKi), PARAMETER :: EddShrT4N04D3 = 8319 - INTEGER(IntKi), PARAMETER :: EddShrT4N04D4 = 8320 - INTEGER(IntKi), PARAMETER :: EddShrT4N04D5 = 8321 - INTEGER(IntKi), PARAMETER :: EddShrT4N04D6 = 8322 - INTEGER(IntKi), PARAMETER :: EddShrT4N04D7 = 8323 - INTEGER(IntKi), PARAMETER :: EddShrT4N04D8 = 8324 - INTEGER(IntKi), PARAMETER :: EddShrT4N04D9 = 8325 - INTEGER(IntKi), PARAMETER :: EddShrT4N05D1 = 8326 - INTEGER(IntKi), PARAMETER :: EddShrT4N05D2 = 8327 - INTEGER(IntKi), PARAMETER :: EddShrT4N05D3 = 8328 - INTEGER(IntKi), PARAMETER :: EddShrT4N05D4 = 8329 - INTEGER(IntKi), PARAMETER :: EddShrT4N05D5 = 8330 - INTEGER(IntKi), PARAMETER :: EddShrT4N05D6 = 8331 - INTEGER(IntKi), PARAMETER :: EddShrT4N05D7 = 8332 - INTEGER(IntKi), PARAMETER :: EddShrT4N05D8 = 8333 - INTEGER(IntKi), PARAMETER :: EddShrT4N05D9 = 8334 - INTEGER(IntKi), PARAMETER :: EddShrT4N06D1 = 8335 - INTEGER(IntKi), PARAMETER :: EddShrT4N06D2 = 8336 - INTEGER(IntKi), PARAMETER :: EddShrT4N06D3 = 8337 - INTEGER(IntKi), PARAMETER :: EddShrT4N06D4 = 8338 - INTEGER(IntKi), PARAMETER :: EddShrT4N06D5 = 8339 - INTEGER(IntKi), PARAMETER :: EddShrT4N06D6 = 8340 - INTEGER(IntKi), PARAMETER :: EddShrT4N06D7 = 8341 - INTEGER(IntKi), PARAMETER :: EddShrT4N06D8 = 8342 - INTEGER(IntKi), PARAMETER :: EddShrT4N06D9 = 8343 - INTEGER(IntKi), PARAMETER :: EddShrT4N07D1 = 8344 - INTEGER(IntKi), PARAMETER :: EddShrT4N07D2 = 8345 - INTEGER(IntKi), PARAMETER :: EddShrT4N07D3 = 8346 - INTEGER(IntKi), PARAMETER :: EddShrT4N07D4 = 8347 - INTEGER(IntKi), PARAMETER :: EddShrT4N07D5 = 8348 - INTEGER(IntKi), PARAMETER :: EddShrT4N07D6 = 8349 - INTEGER(IntKi), PARAMETER :: EddShrT4N07D7 = 8350 - INTEGER(IntKi), PARAMETER :: EddShrT4N07D8 = 8351 - INTEGER(IntKi), PARAMETER :: EddShrT4N07D9 = 8352 - INTEGER(IntKi), PARAMETER :: EddShrT4N08D1 = 8353 - INTEGER(IntKi), PARAMETER :: EddShrT4N08D2 = 8354 - INTEGER(IntKi), PARAMETER :: EddShrT4N08D3 = 8355 - INTEGER(IntKi), PARAMETER :: EddShrT4N08D4 = 8356 - INTEGER(IntKi), PARAMETER :: EddShrT4N08D5 = 8357 - INTEGER(IntKi), PARAMETER :: EddShrT4N08D6 = 8358 - INTEGER(IntKi), PARAMETER :: EddShrT4N08D7 = 8359 - INTEGER(IntKi), PARAMETER :: EddShrT4N08D8 = 8360 - INTEGER(IntKi), PARAMETER :: EddShrT4N08D9 = 8361 - INTEGER(IntKi), PARAMETER :: EddShrT4N09D1 = 8362 - INTEGER(IntKi), PARAMETER :: EddShrT4N09D2 = 8363 - INTEGER(IntKi), PARAMETER :: EddShrT4N09D3 = 8364 - INTEGER(IntKi), PARAMETER :: EddShrT4N09D4 = 8365 - INTEGER(IntKi), PARAMETER :: EddShrT4N09D5 = 8366 - INTEGER(IntKi), PARAMETER :: EddShrT4N09D6 = 8367 - INTEGER(IntKi), PARAMETER :: EddShrT4N09D7 = 8368 - INTEGER(IntKi), PARAMETER :: EddShrT4N09D8 = 8369 - INTEGER(IntKi), PARAMETER :: EddShrT4N09D9 = 8370 - INTEGER(IntKi), PARAMETER :: EddShrT4N10D1 = 8371 - INTEGER(IntKi), PARAMETER :: EddShrT4N10D2 = 8372 - INTEGER(IntKi), PARAMETER :: EddShrT4N10D3 = 8373 - INTEGER(IntKi), PARAMETER :: EddShrT4N10D4 = 8374 - INTEGER(IntKi), PARAMETER :: EddShrT4N10D5 = 8375 - INTEGER(IntKi), PARAMETER :: EddShrT4N10D6 = 8376 - INTEGER(IntKi), PARAMETER :: EddShrT4N10D7 = 8377 - INTEGER(IntKi), PARAMETER :: EddShrT4N10D8 = 8378 - INTEGER(IntKi), PARAMETER :: EddShrT4N10D9 = 8379 - INTEGER(IntKi), PARAMETER :: EddShrT4N11D1 = 8380 - INTEGER(IntKi), PARAMETER :: EddShrT4N11D2 = 8381 - INTEGER(IntKi), PARAMETER :: EddShrT4N11D3 = 8382 - INTEGER(IntKi), PARAMETER :: EddShrT4N11D4 = 8383 - INTEGER(IntKi), PARAMETER :: EddShrT4N11D5 = 8384 - INTEGER(IntKi), PARAMETER :: EddShrT4N11D6 = 8385 - INTEGER(IntKi), PARAMETER :: EddShrT4N11D7 = 8386 - INTEGER(IntKi), PARAMETER :: EddShrT4N11D8 = 8387 - INTEGER(IntKi), PARAMETER :: EddShrT4N11D9 = 8388 - INTEGER(IntKi), PARAMETER :: EddShrT4N12D1 = 8389 - INTEGER(IntKi), PARAMETER :: EddShrT4N12D2 = 8390 - INTEGER(IntKi), PARAMETER :: EddShrT4N12D3 = 8391 - INTEGER(IntKi), PARAMETER :: EddShrT4N12D4 = 8392 - INTEGER(IntKi), PARAMETER :: EddShrT4N12D5 = 8393 - INTEGER(IntKi), PARAMETER :: EddShrT4N12D6 = 8394 - INTEGER(IntKi), PARAMETER :: EddShrT4N12D7 = 8395 - INTEGER(IntKi), PARAMETER :: EddShrT4N12D8 = 8396 - INTEGER(IntKi), PARAMETER :: EddShrT4N12D9 = 8397 - INTEGER(IntKi), PARAMETER :: EddShrT4N13D1 = 8398 - INTEGER(IntKi), PARAMETER :: EddShrT4N13D2 = 8399 - INTEGER(IntKi), PARAMETER :: EddShrT4N13D3 = 8400 - INTEGER(IntKi), PARAMETER :: EddShrT4N13D4 = 8401 - INTEGER(IntKi), PARAMETER :: EddShrT4N13D5 = 8402 - INTEGER(IntKi), PARAMETER :: EddShrT4N13D6 = 8403 - INTEGER(IntKi), PARAMETER :: EddShrT4N13D7 = 8404 - INTEGER(IntKi), PARAMETER :: EddShrT4N13D8 = 8405 - INTEGER(IntKi), PARAMETER :: EddShrT4N13D9 = 8406 - INTEGER(IntKi), PARAMETER :: EddShrT4N14D1 = 8407 - INTEGER(IntKi), PARAMETER :: EddShrT4N14D2 = 8408 - INTEGER(IntKi), PARAMETER :: EddShrT4N14D3 = 8409 - INTEGER(IntKi), PARAMETER :: EddShrT4N14D4 = 8410 - INTEGER(IntKi), PARAMETER :: EddShrT4N14D5 = 8411 - INTEGER(IntKi), PARAMETER :: EddShrT4N14D6 = 8412 - INTEGER(IntKi), PARAMETER :: EddShrT4N14D7 = 8413 - INTEGER(IntKi), PARAMETER :: EddShrT4N14D8 = 8414 - INTEGER(IntKi), PARAMETER :: EddShrT4N14D9 = 8415 - INTEGER(IntKi), PARAMETER :: EddShrT4N15D1 = 8416 - INTEGER(IntKi), PARAMETER :: EddShrT4N15D2 = 8417 - INTEGER(IntKi), PARAMETER :: EddShrT4N15D3 = 8418 - INTEGER(IntKi), PARAMETER :: EddShrT4N15D4 = 8419 - INTEGER(IntKi), PARAMETER :: EddShrT4N15D5 = 8420 - INTEGER(IntKi), PARAMETER :: EddShrT4N15D6 = 8421 - INTEGER(IntKi), PARAMETER :: EddShrT4N15D7 = 8422 - INTEGER(IntKi), PARAMETER :: EddShrT4N15D8 = 8423 - INTEGER(IntKi), PARAMETER :: EddShrT4N15D9 = 8424 - INTEGER(IntKi), PARAMETER :: EddShrT4N16D1 = 8425 - INTEGER(IntKi), PARAMETER :: EddShrT4N16D2 = 8426 - INTEGER(IntKi), PARAMETER :: EddShrT4N16D3 = 8427 - INTEGER(IntKi), PARAMETER :: EddShrT4N16D4 = 8428 - INTEGER(IntKi), PARAMETER :: EddShrT4N16D5 = 8429 - INTEGER(IntKi), PARAMETER :: EddShrT4N16D6 = 8430 - INTEGER(IntKi), PARAMETER :: EddShrT4N16D7 = 8431 - INTEGER(IntKi), PARAMETER :: EddShrT4N16D8 = 8432 - INTEGER(IntKi), PARAMETER :: EddShrT4N16D9 = 8433 - INTEGER(IntKi), PARAMETER :: EddShrT4N17D1 = 8434 - INTEGER(IntKi), PARAMETER :: EddShrT4N17D2 = 8435 - INTEGER(IntKi), PARAMETER :: EddShrT4N17D3 = 8436 - INTEGER(IntKi), PARAMETER :: EddShrT4N17D4 = 8437 - INTEGER(IntKi), PARAMETER :: EddShrT4N17D5 = 8438 - INTEGER(IntKi), PARAMETER :: EddShrT4N17D6 = 8439 - INTEGER(IntKi), PARAMETER :: EddShrT4N17D7 = 8440 - INTEGER(IntKi), PARAMETER :: EddShrT4N17D8 = 8441 - INTEGER(IntKi), PARAMETER :: EddShrT4N17D9 = 8442 - INTEGER(IntKi), PARAMETER :: EddShrT4N18D1 = 8443 - INTEGER(IntKi), PARAMETER :: EddShrT4N18D2 = 8444 - INTEGER(IntKi), PARAMETER :: EddShrT4N18D3 = 8445 - INTEGER(IntKi), PARAMETER :: EddShrT4N18D4 = 8446 - INTEGER(IntKi), PARAMETER :: EddShrT4N18D5 = 8447 - INTEGER(IntKi), PARAMETER :: EddShrT4N18D6 = 8448 - INTEGER(IntKi), PARAMETER :: EddShrT4N18D7 = 8449 - INTEGER(IntKi), PARAMETER :: EddShrT4N18D8 = 8450 - INTEGER(IntKi), PARAMETER :: EddShrT4N18D9 = 8451 - INTEGER(IntKi), PARAMETER :: EddShrT4N19D1 = 8452 - INTEGER(IntKi), PARAMETER :: EddShrT4N19D2 = 8453 - INTEGER(IntKi), PARAMETER :: EddShrT4N19D3 = 8454 - INTEGER(IntKi), PARAMETER :: EddShrT4N19D4 = 8455 - INTEGER(IntKi), PARAMETER :: EddShrT4N19D5 = 8456 - INTEGER(IntKi), PARAMETER :: EddShrT4N19D6 = 8457 - INTEGER(IntKi), PARAMETER :: EddShrT4N19D7 = 8458 - INTEGER(IntKi), PARAMETER :: EddShrT4N19D8 = 8459 - INTEGER(IntKi), PARAMETER :: EddShrT4N19D9 = 8460 - INTEGER(IntKi), PARAMETER :: EddShrT4N20D1 = 8461 - INTEGER(IntKi), PARAMETER :: EddShrT4N20D2 = 8462 - INTEGER(IntKi), PARAMETER :: EddShrT4N20D3 = 8463 - INTEGER(IntKi), PARAMETER :: EddShrT4N20D4 = 8464 - INTEGER(IntKi), PARAMETER :: EddShrT4N20D5 = 8465 - INTEGER(IntKi), PARAMETER :: EddShrT4N20D6 = 8466 - INTEGER(IntKi), PARAMETER :: EddShrT4N20D7 = 8467 - INTEGER(IntKi), PARAMETER :: EddShrT4N20D8 = 8468 - INTEGER(IntKi), PARAMETER :: EddShrT4N20D9 = 8469 - INTEGER(IntKi), PARAMETER :: EddShrT5N01D1 = 8470 - INTEGER(IntKi), PARAMETER :: EddShrT5N01D2 = 8471 - INTEGER(IntKi), PARAMETER :: EddShrT5N01D3 = 8472 - INTEGER(IntKi), PARAMETER :: EddShrT5N01D4 = 8473 - INTEGER(IntKi), PARAMETER :: EddShrT5N01D5 = 8474 - INTEGER(IntKi), PARAMETER :: EddShrT5N01D6 = 8475 - INTEGER(IntKi), PARAMETER :: EddShrT5N01D7 = 8476 - INTEGER(IntKi), PARAMETER :: EddShrT5N01D8 = 8477 - INTEGER(IntKi), PARAMETER :: EddShrT5N01D9 = 8478 - INTEGER(IntKi), PARAMETER :: EddShrT5N02D1 = 8479 - INTEGER(IntKi), PARAMETER :: EddShrT5N02D2 = 8480 - INTEGER(IntKi), PARAMETER :: EddShrT5N02D3 = 8481 - INTEGER(IntKi), PARAMETER :: EddShrT5N02D4 = 8482 - INTEGER(IntKi), PARAMETER :: EddShrT5N02D5 = 8483 - INTEGER(IntKi), PARAMETER :: EddShrT5N02D6 = 8484 - INTEGER(IntKi), PARAMETER :: EddShrT5N02D7 = 8485 - INTEGER(IntKi), PARAMETER :: EddShrT5N02D8 = 8486 - INTEGER(IntKi), PARAMETER :: EddShrT5N02D9 = 8487 - INTEGER(IntKi), PARAMETER :: EddShrT5N03D1 = 8488 - INTEGER(IntKi), PARAMETER :: EddShrT5N03D2 = 8489 - INTEGER(IntKi), PARAMETER :: EddShrT5N03D3 = 8490 - INTEGER(IntKi), PARAMETER :: EddShrT5N03D4 = 8491 - INTEGER(IntKi), PARAMETER :: EddShrT5N03D5 = 8492 - INTEGER(IntKi), PARAMETER :: EddShrT5N03D6 = 8493 - INTEGER(IntKi), PARAMETER :: EddShrT5N03D7 = 8494 - INTEGER(IntKi), PARAMETER :: EddShrT5N03D8 = 8495 - INTEGER(IntKi), PARAMETER :: EddShrT5N03D9 = 8496 - INTEGER(IntKi), PARAMETER :: EddShrT5N04D1 = 8497 - INTEGER(IntKi), PARAMETER :: EddShrT5N04D2 = 8498 - INTEGER(IntKi), PARAMETER :: EddShrT5N04D3 = 8499 - INTEGER(IntKi), PARAMETER :: EddShrT5N04D4 = 8500 - INTEGER(IntKi), PARAMETER :: EddShrT5N04D5 = 8501 - INTEGER(IntKi), PARAMETER :: EddShrT5N04D6 = 8502 - INTEGER(IntKi), PARAMETER :: EddShrT5N04D7 = 8503 - INTEGER(IntKi), PARAMETER :: EddShrT5N04D8 = 8504 - INTEGER(IntKi), PARAMETER :: EddShrT5N04D9 = 8505 - INTEGER(IntKi), PARAMETER :: EddShrT5N05D1 = 8506 - INTEGER(IntKi), PARAMETER :: EddShrT5N05D2 = 8507 - INTEGER(IntKi), PARAMETER :: EddShrT5N05D3 = 8508 - INTEGER(IntKi), PARAMETER :: EddShrT5N05D4 = 8509 - INTEGER(IntKi), PARAMETER :: EddShrT5N05D5 = 8510 - INTEGER(IntKi), PARAMETER :: EddShrT5N05D6 = 8511 - INTEGER(IntKi), PARAMETER :: EddShrT5N05D7 = 8512 - INTEGER(IntKi), PARAMETER :: EddShrT5N05D8 = 8513 - INTEGER(IntKi), PARAMETER :: EddShrT5N05D9 = 8514 - INTEGER(IntKi), PARAMETER :: EddShrT5N06D1 = 8515 - INTEGER(IntKi), PARAMETER :: EddShrT5N06D2 = 8516 - INTEGER(IntKi), PARAMETER :: EddShrT5N06D3 = 8517 - INTEGER(IntKi), PARAMETER :: EddShrT5N06D4 = 8518 - INTEGER(IntKi), PARAMETER :: EddShrT5N06D5 = 8519 - INTEGER(IntKi), PARAMETER :: EddShrT5N06D6 = 8520 - INTEGER(IntKi), PARAMETER :: EddShrT5N06D7 = 8521 - INTEGER(IntKi), PARAMETER :: EddShrT5N06D8 = 8522 - INTEGER(IntKi), PARAMETER :: EddShrT5N06D9 = 8523 - INTEGER(IntKi), PARAMETER :: EddShrT5N07D1 = 8524 - INTEGER(IntKi), PARAMETER :: EddShrT5N07D2 = 8525 - INTEGER(IntKi), PARAMETER :: EddShrT5N07D3 = 8526 - INTEGER(IntKi), PARAMETER :: EddShrT5N07D4 = 8527 - INTEGER(IntKi), PARAMETER :: EddShrT5N07D5 = 8528 - INTEGER(IntKi), PARAMETER :: EddShrT5N07D6 = 8529 - INTEGER(IntKi), PARAMETER :: EddShrT5N07D7 = 8530 - INTEGER(IntKi), PARAMETER :: EddShrT5N07D8 = 8531 - INTEGER(IntKi), PARAMETER :: EddShrT5N07D9 = 8532 - INTEGER(IntKi), PARAMETER :: EddShrT5N08D1 = 8533 - INTEGER(IntKi), PARAMETER :: EddShrT5N08D2 = 8534 - INTEGER(IntKi), PARAMETER :: EddShrT5N08D3 = 8535 - INTEGER(IntKi), PARAMETER :: EddShrT5N08D4 = 8536 - INTEGER(IntKi), PARAMETER :: EddShrT5N08D5 = 8537 - INTEGER(IntKi), PARAMETER :: EddShrT5N08D6 = 8538 - INTEGER(IntKi), PARAMETER :: EddShrT5N08D7 = 8539 - INTEGER(IntKi), PARAMETER :: EddShrT5N08D8 = 8540 - INTEGER(IntKi), PARAMETER :: EddShrT5N08D9 = 8541 - INTEGER(IntKi), PARAMETER :: EddShrT5N09D1 = 8542 - INTEGER(IntKi), PARAMETER :: EddShrT5N09D2 = 8543 - INTEGER(IntKi), PARAMETER :: EddShrT5N09D3 = 8544 - INTEGER(IntKi), PARAMETER :: EddShrT5N09D4 = 8545 - INTEGER(IntKi), PARAMETER :: EddShrT5N09D5 = 8546 - INTEGER(IntKi), PARAMETER :: EddShrT5N09D6 = 8547 - INTEGER(IntKi), PARAMETER :: EddShrT5N09D7 = 8548 - INTEGER(IntKi), PARAMETER :: EddShrT5N09D8 = 8549 - INTEGER(IntKi), PARAMETER :: EddShrT5N09D9 = 8550 - INTEGER(IntKi), PARAMETER :: EddShrT5N10D1 = 8551 - INTEGER(IntKi), PARAMETER :: EddShrT5N10D2 = 8552 - INTEGER(IntKi), PARAMETER :: EddShrT5N10D3 = 8553 - INTEGER(IntKi), PARAMETER :: EddShrT5N10D4 = 8554 - INTEGER(IntKi), PARAMETER :: EddShrT5N10D5 = 8555 - INTEGER(IntKi), PARAMETER :: EddShrT5N10D6 = 8556 - INTEGER(IntKi), PARAMETER :: EddShrT5N10D7 = 8557 - INTEGER(IntKi), PARAMETER :: EddShrT5N10D8 = 8558 - INTEGER(IntKi), PARAMETER :: EddShrT5N10D9 = 8559 - INTEGER(IntKi), PARAMETER :: EddShrT5N11D1 = 8560 - INTEGER(IntKi), PARAMETER :: EddShrT5N11D2 = 8561 - INTEGER(IntKi), PARAMETER :: EddShrT5N11D3 = 8562 - INTEGER(IntKi), PARAMETER :: EddShrT5N11D4 = 8563 - INTEGER(IntKi), PARAMETER :: EddShrT5N11D5 = 8564 - INTEGER(IntKi), PARAMETER :: EddShrT5N11D6 = 8565 - INTEGER(IntKi), PARAMETER :: EddShrT5N11D7 = 8566 - INTEGER(IntKi), PARAMETER :: EddShrT5N11D8 = 8567 - INTEGER(IntKi), PARAMETER :: EddShrT5N11D9 = 8568 - INTEGER(IntKi), PARAMETER :: EddShrT5N12D1 = 8569 - INTEGER(IntKi), PARAMETER :: EddShrT5N12D2 = 8570 - INTEGER(IntKi), PARAMETER :: EddShrT5N12D3 = 8571 - INTEGER(IntKi), PARAMETER :: EddShrT5N12D4 = 8572 - INTEGER(IntKi), PARAMETER :: EddShrT5N12D5 = 8573 - INTEGER(IntKi), PARAMETER :: EddShrT5N12D6 = 8574 - INTEGER(IntKi), PARAMETER :: EddShrT5N12D7 = 8575 - INTEGER(IntKi), PARAMETER :: EddShrT5N12D8 = 8576 - INTEGER(IntKi), PARAMETER :: EddShrT5N12D9 = 8577 - INTEGER(IntKi), PARAMETER :: EddShrT5N13D1 = 8578 - INTEGER(IntKi), PARAMETER :: EddShrT5N13D2 = 8579 - INTEGER(IntKi), PARAMETER :: EddShrT5N13D3 = 8580 - INTEGER(IntKi), PARAMETER :: EddShrT5N13D4 = 8581 - INTEGER(IntKi), PARAMETER :: EddShrT5N13D5 = 8582 - INTEGER(IntKi), PARAMETER :: EddShrT5N13D6 = 8583 - INTEGER(IntKi), PARAMETER :: EddShrT5N13D7 = 8584 - INTEGER(IntKi), PARAMETER :: EddShrT5N13D8 = 8585 - INTEGER(IntKi), PARAMETER :: EddShrT5N13D9 = 8586 - INTEGER(IntKi), PARAMETER :: EddShrT5N14D1 = 8587 - INTEGER(IntKi), PARAMETER :: EddShrT5N14D2 = 8588 - INTEGER(IntKi), PARAMETER :: EddShrT5N14D3 = 8589 - INTEGER(IntKi), PARAMETER :: EddShrT5N14D4 = 8590 - INTEGER(IntKi), PARAMETER :: EddShrT5N14D5 = 8591 - INTEGER(IntKi), PARAMETER :: EddShrT5N14D6 = 8592 - INTEGER(IntKi), PARAMETER :: EddShrT5N14D7 = 8593 - INTEGER(IntKi), PARAMETER :: EddShrT5N14D8 = 8594 - INTEGER(IntKi), PARAMETER :: EddShrT5N14D9 = 8595 - INTEGER(IntKi), PARAMETER :: EddShrT5N15D1 = 8596 - INTEGER(IntKi), PARAMETER :: EddShrT5N15D2 = 8597 - INTEGER(IntKi), PARAMETER :: EddShrT5N15D3 = 8598 - INTEGER(IntKi), PARAMETER :: EddShrT5N15D4 = 8599 - INTEGER(IntKi), PARAMETER :: EddShrT5N15D5 = 8600 - INTEGER(IntKi), PARAMETER :: EddShrT5N15D6 = 8601 - INTEGER(IntKi), PARAMETER :: EddShrT5N15D7 = 8602 - INTEGER(IntKi), PARAMETER :: EddShrT5N15D8 = 8603 - INTEGER(IntKi), PARAMETER :: EddShrT5N15D9 = 8604 - INTEGER(IntKi), PARAMETER :: EddShrT5N16D1 = 8605 - INTEGER(IntKi), PARAMETER :: EddShrT5N16D2 = 8606 - INTEGER(IntKi), PARAMETER :: EddShrT5N16D3 = 8607 - INTEGER(IntKi), PARAMETER :: EddShrT5N16D4 = 8608 - INTEGER(IntKi), PARAMETER :: EddShrT5N16D5 = 8609 - INTEGER(IntKi), PARAMETER :: EddShrT5N16D6 = 8610 - INTEGER(IntKi), PARAMETER :: EddShrT5N16D7 = 8611 - INTEGER(IntKi), PARAMETER :: EddShrT5N16D8 = 8612 - INTEGER(IntKi), PARAMETER :: EddShrT5N16D9 = 8613 - INTEGER(IntKi), PARAMETER :: EddShrT5N17D1 = 8614 - INTEGER(IntKi), PARAMETER :: EddShrT5N17D2 = 8615 - INTEGER(IntKi), PARAMETER :: EddShrT5N17D3 = 8616 - INTEGER(IntKi), PARAMETER :: EddShrT5N17D4 = 8617 - INTEGER(IntKi), PARAMETER :: EddShrT5N17D5 = 8618 - INTEGER(IntKi), PARAMETER :: EddShrT5N17D6 = 8619 - INTEGER(IntKi), PARAMETER :: EddShrT5N17D7 = 8620 - INTEGER(IntKi), PARAMETER :: EddShrT5N17D8 = 8621 - INTEGER(IntKi), PARAMETER :: EddShrT5N17D9 = 8622 - INTEGER(IntKi), PARAMETER :: EddShrT5N18D1 = 8623 - INTEGER(IntKi), PARAMETER :: EddShrT5N18D2 = 8624 - INTEGER(IntKi), PARAMETER :: EddShrT5N18D3 = 8625 - INTEGER(IntKi), PARAMETER :: EddShrT5N18D4 = 8626 - INTEGER(IntKi), PARAMETER :: EddShrT5N18D5 = 8627 - INTEGER(IntKi), PARAMETER :: EddShrT5N18D6 = 8628 - INTEGER(IntKi), PARAMETER :: EddShrT5N18D7 = 8629 - INTEGER(IntKi), PARAMETER :: EddShrT5N18D8 = 8630 - INTEGER(IntKi), PARAMETER :: EddShrT5N18D9 = 8631 - INTEGER(IntKi), PARAMETER :: EddShrT5N19D1 = 8632 - INTEGER(IntKi), PARAMETER :: EddShrT5N19D2 = 8633 - INTEGER(IntKi), PARAMETER :: EddShrT5N19D3 = 8634 - INTEGER(IntKi), PARAMETER :: EddShrT5N19D4 = 8635 - INTEGER(IntKi), PARAMETER :: EddShrT5N19D5 = 8636 - INTEGER(IntKi), PARAMETER :: EddShrT5N19D6 = 8637 - INTEGER(IntKi), PARAMETER :: EddShrT5N19D7 = 8638 - INTEGER(IntKi), PARAMETER :: EddShrT5N19D8 = 8639 - INTEGER(IntKi), PARAMETER :: EddShrT5N19D9 = 8640 - INTEGER(IntKi), PARAMETER :: EddShrT5N20D1 = 8641 - INTEGER(IntKi), PARAMETER :: EddShrT5N20D2 = 8642 - INTEGER(IntKi), PARAMETER :: EddShrT5N20D3 = 8643 - INTEGER(IntKi), PARAMETER :: EddShrT5N20D4 = 8644 - INTEGER(IntKi), PARAMETER :: EddShrT5N20D5 = 8645 - INTEGER(IntKi), PARAMETER :: EddShrT5N20D6 = 8646 - INTEGER(IntKi), PARAMETER :: EddShrT5N20D7 = 8647 - INTEGER(IntKi), PARAMETER :: EddShrT5N20D8 = 8648 - INTEGER(IntKi), PARAMETER :: EddShrT5N20D9 = 8649 - INTEGER(IntKi), PARAMETER :: EddShrT6N01D1 = 8650 - INTEGER(IntKi), PARAMETER :: EddShrT6N01D2 = 8651 - INTEGER(IntKi), PARAMETER :: EddShrT6N01D3 = 8652 - INTEGER(IntKi), PARAMETER :: EddShrT6N01D4 = 8653 - INTEGER(IntKi), PARAMETER :: EddShrT6N01D5 = 8654 - INTEGER(IntKi), PARAMETER :: EddShrT6N01D6 = 8655 - INTEGER(IntKi), PARAMETER :: EddShrT6N01D7 = 8656 - INTEGER(IntKi), PARAMETER :: EddShrT6N01D8 = 8657 - INTEGER(IntKi), PARAMETER :: EddShrT6N01D9 = 8658 - INTEGER(IntKi), PARAMETER :: EddShrT6N02D1 = 8659 - INTEGER(IntKi), PARAMETER :: EddShrT6N02D2 = 8660 - INTEGER(IntKi), PARAMETER :: EddShrT6N02D3 = 8661 - INTEGER(IntKi), PARAMETER :: EddShrT6N02D4 = 8662 - INTEGER(IntKi), PARAMETER :: EddShrT6N02D5 = 8663 - INTEGER(IntKi), PARAMETER :: EddShrT6N02D6 = 8664 - INTEGER(IntKi), PARAMETER :: EddShrT6N02D7 = 8665 - INTEGER(IntKi), PARAMETER :: EddShrT6N02D8 = 8666 - INTEGER(IntKi), PARAMETER :: EddShrT6N02D9 = 8667 - INTEGER(IntKi), PARAMETER :: EddShrT6N03D1 = 8668 - INTEGER(IntKi), PARAMETER :: EddShrT6N03D2 = 8669 - INTEGER(IntKi), PARAMETER :: EddShrT6N03D3 = 8670 - INTEGER(IntKi), PARAMETER :: EddShrT6N03D4 = 8671 - INTEGER(IntKi), PARAMETER :: EddShrT6N03D5 = 8672 - INTEGER(IntKi), PARAMETER :: EddShrT6N03D6 = 8673 - INTEGER(IntKi), PARAMETER :: EddShrT6N03D7 = 8674 - INTEGER(IntKi), PARAMETER :: EddShrT6N03D8 = 8675 - INTEGER(IntKi), PARAMETER :: EddShrT6N03D9 = 8676 - INTEGER(IntKi), PARAMETER :: EddShrT6N04D1 = 8677 - INTEGER(IntKi), PARAMETER :: EddShrT6N04D2 = 8678 - INTEGER(IntKi), PARAMETER :: EddShrT6N04D3 = 8679 - INTEGER(IntKi), PARAMETER :: EddShrT6N04D4 = 8680 - INTEGER(IntKi), PARAMETER :: EddShrT6N04D5 = 8681 - INTEGER(IntKi), PARAMETER :: EddShrT6N04D6 = 8682 - INTEGER(IntKi), PARAMETER :: EddShrT6N04D7 = 8683 - INTEGER(IntKi), PARAMETER :: EddShrT6N04D8 = 8684 - INTEGER(IntKi), PARAMETER :: EddShrT6N04D9 = 8685 - INTEGER(IntKi), PARAMETER :: EddShrT6N05D1 = 8686 - INTEGER(IntKi), PARAMETER :: EddShrT6N05D2 = 8687 - INTEGER(IntKi), PARAMETER :: EddShrT6N05D3 = 8688 - INTEGER(IntKi), PARAMETER :: EddShrT6N05D4 = 8689 - INTEGER(IntKi), PARAMETER :: EddShrT6N05D5 = 8690 - INTEGER(IntKi), PARAMETER :: EddShrT6N05D6 = 8691 - INTEGER(IntKi), PARAMETER :: EddShrT6N05D7 = 8692 - INTEGER(IntKi), PARAMETER :: EddShrT6N05D8 = 8693 - INTEGER(IntKi), PARAMETER :: EddShrT6N05D9 = 8694 - INTEGER(IntKi), PARAMETER :: EddShrT6N06D1 = 8695 - INTEGER(IntKi), PARAMETER :: EddShrT6N06D2 = 8696 - INTEGER(IntKi), PARAMETER :: EddShrT6N06D3 = 8697 - INTEGER(IntKi), PARAMETER :: EddShrT6N06D4 = 8698 - INTEGER(IntKi), PARAMETER :: EddShrT6N06D5 = 8699 - INTEGER(IntKi), PARAMETER :: EddShrT6N06D6 = 8700 - INTEGER(IntKi), PARAMETER :: EddShrT6N06D7 = 8701 - INTEGER(IntKi), PARAMETER :: EddShrT6N06D8 = 8702 - INTEGER(IntKi), PARAMETER :: EddShrT6N06D9 = 8703 - INTEGER(IntKi), PARAMETER :: EddShrT6N07D1 = 8704 - INTEGER(IntKi), PARAMETER :: EddShrT6N07D2 = 8705 - INTEGER(IntKi), PARAMETER :: EddShrT6N07D3 = 8706 - INTEGER(IntKi), PARAMETER :: EddShrT6N07D4 = 8707 - INTEGER(IntKi), PARAMETER :: EddShrT6N07D5 = 8708 - INTEGER(IntKi), PARAMETER :: EddShrT6N07D6 = 8709 - INTEGER(IntKi), PARAMETER :: EddShrT6N07D7 = 8710 - INTEGER(IntKi), PARAMETER :: EddShrT6N07D8 = 8711 - INTEGER(IntKi), PARAMETER :: EddShrT6N07D9 = 8712 - INTEGER(IntKi), PARAMETER :: EddShrT6N08D1 = 8713 - INTEGER(IntKi), PARAMETER :: EddShrT6N08D2 = 8714 - INTEGER(IntKi), PARAMETER :: EddShrT6N08D3 = 8715 - INTEGER(IntKi), PARAMETER :: EddShrT6N08D4 = 8716 - INTEGER(IntKi), PARAMETER :: EddShrT6N08D5 = 8717 - INTEGER(IntKi), PARAMETER :: EddShrT6N08D6 = 8718 - INTEGER(IntKi), PARAMETER :: EddShrT6N08D7 = 8719 - INTEGER(IntKi), PARAMETER :: EddShrT6N08D8 = 8720 - INTEGER(IntKi), PARAMETER :: EddShrT6N08D9 = 8721 - INTEGER(IntKi), PARAMETER :: EddShrT6N09D1 = 8722 - INTEGER(IntKi), PARAMETER :: EddShrT6N09D2 = 8723 - INTEGER(IntKi), PARAMETER :: EddShrT6N09D3 = 8724 - INTEGER(IntKi), PARAMETER :: EddShrT6N09D4 = 8725 - INTEGER(IntKi), PARAMETER :: EddShrT6N09D5 = 8726 - INTEGER(IntKi), PARAMETER :: EddShrT6N09D6 = 8727 - INTEGER(IntKi), PARAMETER :: EddShrT6N09D7 = 8728 - INTEGER(IntKi), PARAMETER :: EddShrT6N09D8 = 8729 - INTEGER(IntKi), PARAMETER :: EddShrT6N09D9 = 8730 - INTEGER(IntKi), PARAMETER :: EddShrT6N10D1 = 8731 - INTEGER(IntKi), PARAMETER :: EddShrT6N10D2 = 8732 - INTEGER(IntKi), PARAMETER :: EddShrT6N10D3 = 8733 - INTEGER(IntKi), PARAMETER :: EddShrT6N10D4 = 8734 - INTEGER(IntKi), PARAMETER :: EddShrT6N10D5 = 8735 - INTEGER(IntKi), PARAMETER :: EddShrT6N10D6 = 8736 - INTEGER(IntKi), PARAMETER :: EddShrT6N10D7 = 8737 - INTEGER(IntKi), PARAMETER :: EddShrT6N10D8 = 8738 - INTEGER(IntKi), PARAMETER :: EddShrT6N10D9 = 8739 - INTEGER(IntKi), PARAMETER :: EddShrT6N11D1 = 8740 - INTEGER(IntKi), PARAMETER :: EddShrT6N11D2 = 8741 - INTEGER(IntKi), PARAMETER :: EddShrT6N11D3 = 8742 - INTEGER(IntKi), PARAMETER :: EddShrT6N11D4 = 8743 - INTEGER(IntKi), PARAMETER :: EddShrT6N11D5 = 8744 - INTEGER(IntKi), PARAMETER :: EddShrT6N11D6 = 8745 - INTEGER(IntKi), PARAMETER :: EddShrT6N11D7 = 8746 - INTEGER(IntKi), PARAMETER :: EddShrT6N11D8 = 8747 - INTEGER(IntKi), PARAMETER :: EddShrT6N11D9 = 8748 - INTEGER(IntKi), PARAMETER :: EddShrT6N12D1 = 8749 - INTEGER(IntKi), PARAMETER :: EddShrT6N12D2 = 8750 - INTEGER(IntKi), PARAMETER :: EddShrT6N12D3 = 8751 - INTEGER(IntKi), PARAMETER :: EddShrT6N12D4 = 8752 - INTEGER(IntKi), PARAMETER :: EddShrT6N12D5 = 8753 - INTEGER(IntKi), PARAMETER :: EddShrT6N12D6 = 8754 - INTEGER(IntKi), PARAMETER :: EddShrT6N12D7 = 8755 - INTEGER(IntKi), PARAMETER :: EddShrT6N12D8 = 8756 - INTEGER(IntKi), PARAMETER :: EddShrT6N12D9 = 8757 - INTEGER(IntKi), PARAMETER :: EddShrT6N13D1 = 8758 - INTEGER(IntKi), PARAMETER :: EddShrT6N13D2 = 8759 - INTEGER(IntKi), PARAMETER :: EddShrT6N13D3 = 8760 - INTEGER(IntKi), PARAMETER :: EddShrT6N13D4 = 8761 - INTEGER(IntKi), PARAMETER :: EddShrT6N13D5 = 8762 - INTEGER(IntKi), PARAMETER :: EddShrT6N13D6 = 8763 - INTEGER(IntKi), PARAMETER :: EddShrT6N13D7 = 8764 - INTEGER(IntKi), PARAMETER :: EddShrT6N13D8 = 8765 - INTEGER(IntKi), PARAMETER :: EddShrT6N13D9 = 8766 - INTEGER(IntKi), PARAMETER :: EddShrT6N14D1 = 8767 - INTEGER(IntKi), PARAMETER :: EddShrT6N14D2 = 8768 - INTEGER(IntKi), PARAMETER :: EddShrT6N14D3 = 8769 - INTEGER(IntKi), PARAMETER :: EddShrT6N14D4 = 8770 - INTEGER(IntKi), PARAMETER :: EddShrT6N14D5 = 8771 - INTEGER(IntKi), PARAMETER :: EddShrT6N14D6 = 8772 - INTEGER(IntKi), PARAMETER :: EddShrT6N14D7 = 8773 - INTEGER(IntKi), PARAMETER :: EddShrT6N14D8 = 8774 - INTEGER(IntKi), PARAMETER :: EddShrT6N14D9 = 8775 - INTEGER(IntKi), PARAMETER :: EddShrT6N15D1 = 8776 - INTEGER(IntKi), PARAMETER :: EddShrT6N15D2 = 8777 - INTEGER(IntKi), PARAMETER :: EddShrT6N15D3 = 8778 - INTEGER(IntKi), PARAMETER :: EddShrT6N15D4 = 8779 - INTEGER(IntKi), PARAMETER :: EddShrT6N15D5 = 8780 - INTEGER(IntKi), PARAMETER :: EddShrT6N15D6 = 8781 - INTEGER(IntKi), PARAMETER :: EddShrT6N15D7 = 8782 - INTEGER(IntKi), PARAMETER :: EddShrT6N15D8 = 8783 - INTEGER(IntKi), PARAMETER :: EddShrT6N15D9 = 8784 - INTEGER(IntKi), PARAMETER :: EddShrT6N16D1 = 8785 - INTEGER(IntKi), PARAMETER :: EddShrT6N16D2 = 8786 - INTEGER(IntKi), PARAMETER :: EddShrT6N16D3 = 8787 - INTEGER(IntKi), PARAMETER :: EddShrT6N16D4 = 8788 - INTEGER(IntKi), PARAMETER :: EddShrT6N16D5 = 8789 - INTEGER(IntKi), PARAMETER :: EddShrT6N16D6 = 8790 - INTEGER(IntKi), PARAMETER :: EddShrT6N16D7 = 8791 - INTEGER(IntKi), PARAMETER :: EddShrT6N16D8 = 8792 - INTEGER(IntKi), PARAMETER :: EddShrT6N16D9 = 8793 - INTEGER(IntKi), PARAMETER :: EddShrT6N17D1 = 8794 - INTEGER(IntKi), PARAMETER :: EddShrT6N17D2 = 8795 - INTEGER(IntKi), PARAMETER :: EddShrT6N17D3 = 8796 - INTEGER(IntKi), PARAMETER :: EddShrT6N17D4 = 8797 - INTEGER(IntKi), PARAMETER :: EddShrT6N17D5 = 8798 - INTEGER(IntKi), PARAMETER :: EddShrT6N17D6 = 8799 - INTEGER(IntKi), PARAMETER :: EddShrT6N17D7 = 8800 - INTEGER(IntKi), PARAMETER :: EddShrT6N17D8 = 8801 - INTEGER(IntKi), PARAMETER :: EddShrT6N17D9 = 8802 - INTEGER(IntKi), PARAMETER :: EddShrT6N18D1 = 8803 - INTEGER(IntKi), PARAMETER :: EddShrT6N18D2 = 8804 - INTEGER(IntKi), PARAMETER :: EddShrT6N18D3 = 8805 - INTEGER(IntKi), PARAMETER :: EddShrT6N18D4 = 8806 - INTEGER(IntKi), PARAMETER :: EddShrT6N18D5 = 8807 - INTEGER(IntKi), PARAMETER :: EddShrT6N18D6 = 8808 - INTEGER(IntKi), PARAMETER :: EddShrT6N18D7 = 8809 - INTEGER(IntKi), PARAMETER :: EddShrT6N18D8 = 8810 - INTEGER(IntKi), PARAMETER :: EddShrT6N18D9 = 8811 - INTEGER(IntKi), PARAMETER :: EddShrT6N19D1 = 8812 - INTEGER(IntKi), PARAMETER :: EddShrT6N19D2 = 8813 - INTEGER(IntKi), PARAMETER :: EddShrT6N19D3 = 8814 - INTEGER(IntKi), PARAMETER :: EddShrT6N19D4 = 8815 - INTEGER(IntKi), PARAMETER :: EddShrT6N19D5 = 8816 - INTEGER(IntKi), PARAMETER :: EddShrT6N19D6 = 8817 - INTEGER(IntKi), PARAMETER :: EddShrT6N19D7 = 8818 - INTEGER(IntKi), PARAMETER :: EddShrT6N19D8 = 8819 - INTEGER(IntKi), PARAMETER :: EddShrT6N19D9 = 8820 - INTEGER(IntKi), PARAMETER :: EddShrT6N20D1 = 8821 - INTEGER(IntKi), PARAMETER :: EddShrT6N20D2 = 8822 - INTEGER(IntKi), PARAMETER :: EddShrT6N20D3 = 8823 - INTEGER(IntKi), PARAMETER :: EddShrT6N20D4 = 8824 - INTEGER(IntKi), PARAMETER :: EddShrT6N20D5 = 8825 - INTEGER(IntKi), PARAMETER :: EddShrT6N20D6 = 8826 - INTEGER(IntKi), PARAMETER :: EddShrT6N20D7 = 8827 - INTEGER(IntKi), PARAMETER :: EddShrT6N20D8 = 8828 - INTEGER(IntKi), PARAMETER :: EddShrT6N20D9 = 8829 - INTEGER(IntKi), PARAMETER :: EddShrT7N01D1 = 8830 - INTEGER(IntKi), PARAMETER :: EddShrT7N01D2 = 8831 - INTEGER(IntKi), PARAMETER :: EddShrT7N01D3 = 8832 - INTEGER(IntKi), PARAMETER :: EddShrT7N01D4 = 8833 - INTEGER(IntKi), PARAMETER :: EddShrT7N01D5 = 8834 - INTEGER(IntKi), PARAMETER :: EddShrT7N01D6 = 8835 - INTEGER(IntKi), PARAMETER :: EddShrT7N01D7 = 8836 - INTEGER(IntKi), PARAMETER :: EddShrT7N01D8 = 8837 - INTEGER(IntKi), PARAMETER :: EddShrT7N01D9 = 8838 - INTEGER(IntKi), PARAMETER :: EddShrT7N02D1 = 8839 - INTEGER(IntKi), PARAMETER :: EddShrT7N02D2 = 8840 - INTEGER(IntKi), PARAMETER :: EddShrT7N02D3 = 8841 - INTEGER(IntKi), PARAMETER :: EddShrT7N02D4 = 8842 - INTEGER(IntKi), PARAMETER :: EddShrT7N02D5 = 8843 - INTEGER(IntKi), PARAMETER :: EddShrT7N02D6 = 8844 - INTEGER(IntKi), PARAMETER :: EddShrT7N02D7 = 8845 - INTEGER(IntKi), PARAMETER :: EddShrT7N02D8 = 8846 - INTEGER(IntKi), PARAMETER :: EddShrT7N02D9 = 8847 - INTEGER(IntKi), PARAMETER :: EddShrT7N03D1 = 8848 - INTEGER(IntKi), PARAMETER :: EddShrT7N03D2 = 8849 - INTEGER(IntKi), PARAMETER :: EddShrT7N03D3 = 8850 - INTEGER(IntKi), PARAMETER :: EddShrT7N03D4 = 8851 - INTEGER(IntKi), PARAMETER :: EddShrT7N03D5 = 8852 - INTEGER(IntKi), PARAMETER :: EddShrT7N03D6 = 8853 - INTEGER(IntKi), PARAMETER :: EddShrT7N03D7 = 8854 - INTEGER(IntKi), PARAMETER :: EddShrT7N03D8 = 8855 - INTEGER(IntKi), PARAMETER :: EddShrT7N03D9 = 8856 - INTEGER(IntKi), PARAMETER :: EddShrT7N04D1 = 8857 - INTEGER(IntKi), PARAMETER :: EddShrT7N04D2 = 8858 - INTEGER(IntKi), PARAMETER :: EddShrT7N04D3 = 8859 - INTEGER(IntKi), PARAMETER :: EddShrT7N04D4 = 8860 - INTEGER(IntKi), PARAMETER :: EddShrT7N04D5 = 8861 - INTEGER(IntKi), PARAMETER :: EddShrT7N04D6 = 8862 - INTEGER(IntKi), PARAMETER :: EddShrT7N04D7 = 8863 - INTEGER(IntKi), PARAMETER :: EddShrT7N04D8 = 8864 - INTEGER(IntKi), PARAMETER :: EddShrT7N04D9 = 8865 - INTEGER(IntKi), PARAMETER :: EddShrT7N05D1 = 8866 - INTEGER(IntKi), PARAMETER :: EddShrT7N05D2 = 8867 - INTEGER(IntKi), PARAMETER :: EddShrT7N05D3 = 8868 - INTEGER(IntKi), PARAMETER :: EddShrT7N05D4 = 8869 - INTEGER(IntKi), PARAMETER :: EddShrT7N05D5 = 8870 - INTEGER(IntKi), PARAMETER :: EddShrT7N05D6 = 8871 - INTEGER(IntKi), PARAMETER :: EddShrT7N05D7 = 8872 - INTEGER(IntKi), PARAMETER :: EddShrT7N05D8 = 8873 - INTEGER(IntKi), PARAMETER :: EddShrT7N05D9 = 8874 - INTEGER(IntKi), PARAMETER :: EddShrT7N06D1 = 8875 - INTEGER(IntKi), PARAMETER :: EddShrT7N06D2 = 8876 - INTEGER(IntKi), PARAMETER :: EddShrT7N06D3 = 8877 - INTEGER(IntKi), PARAMETER :: EddShrT7N06D4 = 8878 - INTEGER(IntKi), PARAMETER :: EddShrT7N06D5 = 8879 - INTEGER(IntKi), PARAMETER :: EddShrT7N06D6 = 8880 - INTEGER(IntKi), PARAMETER :: EddShrT7N06D7 = 8881 - INTEGER(IntKi), PARAMETER :: EddShrT7N06D8 = 8882 - INTEGER(IntKi), PARAMETER :: EddShrT7N06D9 = 8883 - INTEGER(IntKi), PARAMETER :: EddShrT7N07D1 = 8884 - INTEGER(IntKi), PARAMETER :: EddShrT7N07D2 = 8885 - INTEGER(IntKi), PARAMETER :: EddShrT7N07D3 = 8886 - INTEGER(IntKi), PARAMETER :: EddShrT7N07D4 = 8887 - INTEGER(IntKi), PARAMETER :: EddShrT7N07D5 = 8888 - INTEGER(IntKi), PARAMETER :: EddShrT7N07D6 = 8889 - INTEGER(IntKi), PARAMETER :: EddShrT7N07D7 = 8890 - INTEGER(IntKi), PARAMETER :: EddShrT7N07D8 = 8891 - INTEGER(IntKi), PARAMETER :: EddShrT7N07D9 = 8892 - INTEGER(IntKi), PARAMETER :: EddShrT7N08D1 = 8893 - INTEGER(IntKi), PARAMETER :: EddShrT7N08D2 = 8894 - INTEGER(IntKi), PARAMETER :: EddShrT7N08D3 = 8895 - INTEGER(IntKi), PARAMETER :: EddShrT7N08D4 = 8896 - INTEGER(IntKi), PARAMETER :: EddShrT7N08D5 = 8897 - INTEGER(IntKi), PARAMETER :: EddShrT7N08D6 = 8898 - INTEGER(IntKi), PARAMETER :: EddShrT7N08D7 = 8899 - INTEGER(IntKi), PARAMETER :: EddShrT7N08D8 = 8900 - INTEGER(IntKi), PARAMETER :: EddShrT7N08D9 = 8901 - INTEGER(IntKi), PARAMETER :: EddShrT7N09D1 = 8902 - INTEGER(IntKi), PARAMETER :: EddShrT7N09D2 = 8903 - INTEGER(IntKi), PARAMETER :: EddShrT7N09D3 = 8904 - INTEGER(IntKi), PARAMETER :: EddShrT7N09D4 = 8905 - INTEGER(IntKi), PARAMETER :: EddShrT7N09D5 = 8906 - INTEGER(IntKi), PARAMETER :: EddShrT7N09D6 = 8907 - INTEGER(IntKi), PARAMETER :: EddShrT7N09D7 = 8908 - INTEGER(IntKi), PARAMETER :: EddShrT7N09D8 = 8909 - INTEGER(IntKi), PARAMETER :: EddShrT7N09D9 = 8910 - INTEGER(IntKi), PARAMETER :: EddShrT7N10D1 = 8911 - INTEGER(IntKi), PARAMETER :: EddShrT7N10D2 = 8912 - INTEGER(IntKi), PARAMETER :: EddShrT7N10D3 = 8913 - INTEGER(IntKi), PARAMETER :: EddShrT7N10D4 = 8914 - INTEGER(IntKi), PARAMETER :: EddShrT7N10D5 = 8915 - INTEGER(IntKi), PARAMETER :: EddShrT7N10D6 = 8916 - INTEGER(IntKi), PARAMETER :: EddShrT7N10D7 = 8917 - INTEGER(IntKi), PARAMETER :: EddShrT7N10D8 = 8918 - INTEGER(IntKi), PARAMETER :: EddShrT7N10D9 = 8919 - INTEGER(IntKi), PARAMETER :: EddShrT7N11D1 = 8920 - INTEGER(IntKi), PARAMETER :: EddShrT7N11D2 = 8921 - INTEGER(IntKi), PARAMETER :: EddShrT7N11D3 = 8922 - INTEGER(IntKi), PARAMETER :: EddShrT7N11D4 = 8923 - INTEGER(IntKi), PARAMETER :: EddShrT7N11D5 = 8924 - INTEGER(IntKi), PARAMETER :: EddShrT7N11D6 = 8925 - INTEGER(IntKi), PARAMETER :: EddShrT7N11D7 = 8926 - INTEGER(IntKi), PARAMETER :: EddShrT7N11D8 = 8927 - INTEGER(IntKi), PARAMETER :: EddShrT7N11D9 = 8928 - INTEGER(IntKi), PARAMETER :: EddShrT7N12D1 = 8929 - INTEGER(IntKi), PARAMETER :: EddShrT7N12D2 = 8930 - INTEGER(IntKi), PARAMETER :: EddShrT7N12D3 = 8931 - INTEGER(IntKi), PARAMETER :: EddShrT7N12D4 = 8932 - INTEGER(IntKi), PARAMETER :: EddShrT7N12D5 = 8933 - INTEGER(IntKi), PARAMETER :: EddShrT7N12D6 = 8934 - INTEGER(IntKi), PARAMETER :: EddShrT7N12D7 = 8935 - INTEGER(IntKi), PARAMETER :: EddShrT7N12D8 = 8936 - INTEGER(IntKi), PARAMETER :: EddShrT7N12D9 = 8937 - INTEGER(IntKi), PARAMETER :: EddShrT7N13D1 = 8938 - INTEGER(IntKi), PARAMETER :: EddShrT7N13D2 = 8939 - INTEGER(IntKi), PARAMETER :: EddShrT7N13D3 = 8940 - INTEGER(IntKi), PARAMETER :: EddShrT7N13D4 = 8941 - INTEGER(IntKi), PARAMETER :: EddShrT7N13D5 = 8942 - INTEGER(IntKi), PARAMETER :: EddShrT7N13D6 = 8943 - INTEGER(IntKi), PARAMETER :: EddShrT7N13D7 = 8944 - INTEGER(IntKi), PARAMETER :: EddShrT7N13D8 = 8945 - INTEGER(IntKi), PARAMETER :: EddShrT7N13D9 = 8946 - INTEGER(IntKi), PARAMETER :: EddShrT7N14D1 = 8947 - INTEGER(IntKi), PARAMETER :: EddShrT7N14D2 = 8948 - INTEGER(IntKi), PARAMETER :: EddShrT7N14D3 = 8949 - INTEGER(IntKi), PARAMETER :: EddShrT7N14D4 = 8950 - INTEGER(IntKi), PARAMETER :: EddShrT7N14D5 = 8951 - INTEGER(IntKi), PARAMETER :: EddShrT7N14D6 = 8952 - INTEGER(IntKi), PARAMETER :: EddShrT7N14D7 = 8953 - INTEGER(IntKi), PARAMETER :: EddShrT7N14D8 = 8954 - INTEGER(IntKi), PARAMETER :: EddShrT7N14D9 = 8955 - INTEGER(IntKi), PARAMETER :: EddShrT7N15D1 = 8956 - INTEGER(IntKi), PARAMETER :: EddShrT7N15D2 = 8957 - INTEGER(IntKi), PARAMETER :: EddShrT7N15D3 = 8958 - INTEGER(IntKi), PARAMETER :: EddShrT7N15D4 = 8959 - INTEGER(IntKi), PARAMETER :: EddShrT7N15D5 = 8960 - INTEGER(IntKi), PARAMETER :: EddShrT7N15D6 = 8961 - INTEGER(IntKi), PARAMETER :: EddShrT7N15D7 = 8962 - INTEGER(IntKi), PARAMETER :: EddShrT7N15D8 = 8963 - INTEGER(IntKi), PARAMETER :: EddShrT7N15D9 = 8964 - INTEGER(IntKi), PARAMETER :: EddShrT7N16D1 = 8965 - INTEGER(IntKi), PARAMETER :: EddShrT7N16D2 = 8966 - INTEGER(IntKi), PARAMETER :: EddShrT7N16D3 = 8967 - INTEGER(IntKi), PARAMETER :: EddShrT7N16D4 = 8968 - INTEGER(IntKi), PARAMETER :: EddShrT7N16D5 = 8969 - INTEGER(IntKi), PARAMETER :: EddShrT7N16D6 = 8970 - INTEGER(IntKi), PARAMETER :: EddShrT7N16D7 = 8971 - INTEGER(IntKi), PARAMETER :: EddShrT7N16D8 = 8972 - INTEGER(IntKi), PARAMETER :: EddShrT7N16D9 = 8973 - INTEGER(IntKi), PARAMETER :: EddShrT7N17D1 = 8974 - INTEGER(IntKi), PARAMETER :: EddShrT7N17D2 = 8975 - INTEGER(IntKi), PARAMETER :: EddShrT7N17D3 = 8976 - INTEGER(IntKi), PARAMETER :: EddShrT7N17D4 = 8977 - INTEGER(IntKi), PARAMETER :: EddShrT7N17D5 = 8978 - INTEGER(IntKi), PARAMETER :: EddShrT7N17D6 = 8979 - INTEGER(IntKi), PARAMETER :: EddShrT7N17D7 = 8980 - INTEGER(IntKi), PARAMETER :: EddShrT7N17D8 = 8981 - INTEGER(IntKi), PARAMETER :: EddShrT7N17D9 = 8982 - INTEGER(IntKi), PARAMETER :: EddShrT7N18D1 = 8983 - INTEGER(IntKi), PARAMETER :: EddShrT7N18D2 = 8984 - INTEGER(IntKi), PARAMETER :: EddShrT7N18D3 = 8985 - INTEGER(IntKi), PARAMETER :: EddShrT7N18D4 = 8986 - INTEGER(IntKi), PARAMETER :: EddShrT7N18D5 = 8987 - INTEGER(IntKi), PARAMETER :: EddShrT7N18D6 = 8988 - INTEGER(IntKi), PARAMETER :: EddShrT7N18D7 = 8989 - INTEGER(IntKi), PARAMETER :: EddShrT7N18D8 = 8990 - INTEGER(IntKi), PARAMETER :: EddShrT7N18D9 = 8991 - INTEGER(IntKi), PARAMETER :: EddShrT7N19D1 = 8992 - INTEGER(IntKi), PARAMETER :: EddShrT7N19D2 = 8993 - INTEGER(IntKi), PARAMETER :: EddShrT7N19D3 = 8994 - INTEGER(IntKi), PARAMETER :: EddShrT7N19D4 = 8995 - INTEGER(IntKi), PARAMETER :: EddShrT7N19D5 = 8996 - INTEGER(IntKi), PARAMETER :: EddShrT7N19D6 = 8997 - INTEGER(IntKi), PARAMETER :: EddShrT7N19D7 = 8998 - INTEGER(IntKi), PARAMETER :: EddShrT7N19D8 = 8999 - INTEGER(IntKi), PARAMETER :: EddShrT7N19D9 = 9000 - INTEGER(IntKi), PARAMETER :: EddShrT7N20D1 = 9001 - INTEGER(IntKi), PARAMETER :: EddShrT7N20D2 = 9002 - INTEGER(IntKi), PARAMETER :: EddShrT7N20D3 = 9003 - INTEGER(IntKi), PARAMETER :: EddShrT7N20D4 = 9004 - INTEGER(IntKi), PARAMETER :: EddShrT7N20D5 = 9005 - INTEGER(IntKi), PARAMETER :: EddShrT7N20D6 = 9006 - INTEGER(IntKi), PARAMETER :: EddShrT7N20D7 = 9007 - INTEGER(IntKi), PARAMETER :: EddShrT7N20D8 = 9008 - INTEGER(IntKi), PARAMETER :: EddShrT7N20D9 = 9009 - INTEGER(IntKi), PARAMETER :: EddShrT8N01D1 = 9010 - INTEGER(IntKi), PARAMETER :: EddShrT8N01D2 = 9011 - INTEGER(IntKi), PARAMETER :: EddShrT8N01D3 = 9012 - INTEGER(IntKi), PARAMETER :: EddShrT8N01D4 = 9013 - INTEGER(IntKi), PARAMETER :: EddShrT8N01D5 = 9014 - INTEGER(IntKi), PARAMETER :: EddShrT8N01D6 = 9015 - INTEGER(IntKi), PARAMETER :: EddShrT8N01D7 = 9016 - INTEGER(IntKi), PARAMETER :: EddShrT8N01D8 = 9017 - INTEGER(IntKi), PARAMETER :: EddShrT8N01D9 = 9018 - INTEGER(IntKi), PARAMETER :: EddShrT8N02D1 = 9019 - INTEGER(IntKi), PARAMETER :: EddShrT8N02D2 = 9020 - INTEGER(IntKi), PARAMETER :: EddShrT8N02D3 = 9021 - INTEGER(IntKi), PARAMETER :: EddShrT8N02D4 = 9022 - INTEGER(IntKi), PARAMETER :: EddShrT8N02D5 = 9023 - INTEGER(IntKi), PARAMETER :: EddShrT8N02D6 = 9024 - INTEGER(IntKi), PARAMETER :: EddShrT8N02D7 = 9025 - INTEGER(IntKi), PARAMETER :: EddShrT8N02D8 = 9026 - INTEGER(IntKi), PARAMETER :: EddShrT8N02D9 = 9027 - INTEGER(IntKi), PARAMETER :: EddShrT8N03D1 = 9028 - INTEGER(IntKi), PARAMETER :: EddShrT8N03D2 = 9029 - INTEGER(IntKi), PARAMETER :: EddShrT8N03D3 = 9030 - INTEGER(IntKi), PARAMETER :: EddShrT8N03D4 = 9031 - INTEGER(IntKi), PARAMETER :: EddShrT8N03D5 = 9032 - INTEGER(IntKi), PARAMETER :: EddShrT8N03D6 = 9033 - INTEGER(IntKi), PARAMETER :: EddShrT8N03D7 = 9034 - INTEGER(IntKi), PARAMETER :: EddShrT8N03D8 = 9035 - INTEGER(IntKi), PARAMETER :: EddShrT8N03D9 = 9036 - INTEGER(IntKi), PARAMETER :: EddShrT8N04D1 = 9037 - INTEGER(IntKi), PARAMETER :: EddShrT8N04D2 = 9038 - INTEGER(IntKi), PARAMETER :: EddShrT8N04D3 = 9039 - INTEGER(IntKi), PARAMETER :: EddShrT8N04D4 = 9040 - INTEGER(IntKi), PARAMETER :: EddShrT8N04D5 = 9041 - INTEGER(IntKi), PARAMETER :: EddShrT8N04D6 = 9042 - INTEGER(IntKi), PARAMETER :: EddShrT8N04D7 = 9043 - INTEGER(IntKi), PARAMETER :: EddShrT8N04D8 = 9044 - INTEGER(IntKi), PARAMETER :: EddShrT8N04D9 = 9045 - INTEGER(IntKi), PARAMETER :: EddShrT8N05D1 = 9046 - INTEGER(IntKi), PARAMETER :: EddShrT8N05D2 = 9047 - INTEGER(IntKi), PARAMETER :: EddShrT8N05D3 = 9048 - INTEGER(IntKi), PARAMETER :: EddShrT8N05D4 = 9049 - INTEGER(IntKi), PARAMETER :: EddShrT8N05D5 = 9050 - INTEGER(IntKi), PARAMETER :: EddShrT8N05D6 = 9051 - INTEGER(IntKi), PARAMETER :: EddShrT8N05D7 = 9052 - INTEGER(IntKi), PARAMETER :: EddShrT8N05D8 = 9053 - INTEGER(IntKi), PARAMETER :: EddShrT8N05D9 = 9054 - INTEGER(IntKi), PARAMETER :: EddShrT8N06D1 = 9055 - INTEGER(IntKi), PARAMETER :: EddShrT8N06D2 = 9056 - INTEGER(IntKi), PARAMETER :: EddShrT8N06D3 = 9057 - INTEGER(IntKi), PARAMETER :: EddShrT8N06D4 = 9058 - INTEGER(IntKi), PARAMETER :: EddShrT8N06D5 = 9059 - INTEGER(IntKi), PARAMETER :: EddShrT8N06D6 = 9060 - INTEGER(IntKi), PARAMETER :: EddShrT8N06D7 = 9061 - INTEGER(IntKi), PARAMETER :: EddShrT8N06D8 = 9062 - INTEGER(IntKi), PARAMETER :: EddShrT8N06D9 = 9063 - INTEGER(IntKi), PARAMETER :: EddShrT8N07D1 = 9064 - INTEGER(IntKi), PARAMETER :: EddShrT8N07D2 = 9065 - INTEGER(IntKi), PARAMETER :: EddShrT8N07D3 = 9066 - INTEGER(IntKi), PARAMETER :: EddShrT8N07D4 = 9067 - INTEGER(IntKi), PARAMETER :: EddShrT8N07D5 = 9068 - INTEGER(IntKi), PARAMETER :: EddShrT8N07D6 = 9069 - INTEGER(IntKi), PARAMETER :: EddShrT8N07D7 = 9070 - INTEGER(IntKi), PARAMETER :: EddShrT8N07D8 = 9071 - INTEGER(IntKi), PARAMETER :: EddShrT8N07D9 = 9072 - INTEGER(IntKi), PARAMETER :: EddShrT8N08D1 = 9073 - INTEGER(IntKi), PARAMETER :: EddShrT8N08D2 = 9074 - INTEGER(IntKi), PARAMETER :: EddShrT8N08D3 = 9075 - INTEGER(IntKi), PARAMETER :: EddShrT8N08D4 = 9076 - INTEGER(IntKi), PARAMETER :: EddShrT8N08D5 = 9077 - INTEGER(IntKi), PARAMETER :: EddShrT8N08D6 = 9078 - INTEGER(IntKi), PARAMETER :: EddShrT8N08D7 = 9079 - INTEGER(IntKi), PARAMETER :: EddShrT8N08D8 = 9080 - INTEGER(IntKi), PARAMETER :: EddShrT8N08D9 = 9081 - INTEGER(IntKi), PARAMETER :: EddShrT8N09D1 = 9082 - INTEGER(IntKi), PARAMETER :: EddShrT8N09D2 = 9083 - INTEGER(IntKi), PARAMETER :: EddShrT8N09D3 = 9084 - INTEGER(IntKi), PARAMETER :: EddShrT8N09D4 = 9085 - INTEGER(IntKi), PARAMETER :: EddShrT8N09D5 = 9086 - INTEGER(IntKi), PARAMETER :: EddShrT8N09D6 = 9087 - INTEGER(IntKi), PARAMETER :: EddShrT8N09D7 = 9088 - INTEGER(IntKi), PARAMETER :: EddShrT8N09D8 = 9089 - INTEGER(IntKi), PARAMETER :: EddShrT8N09D9 = 9090 - INTEGER(IntKi), PARAMETER :: EddShrT8N10D1 = 9091 - INTEGER(IntKi), PARAMETER :: EddShrT8N10D2 = 9092 - INTEGER(IntKi), PARAMETER :: EddShrT8N10D3 = 9093 - INTEGER(IntKi), PARAMETER :: EddShrT8N10D4 = 9094 - INTEGER(IntKi), PARAMETER :: EddShrT8N10D5 = 9095 - INTEGER(IntKi), PARAMETER :: EddShrT8N10D6 = 9096 - INTEGER(IntKi), PARAMETER :: EddShrT8N10D7 = 9097 - INTEGER(IntKi), PARAMETER :: EddShrT8N10D8 = 9098 - INTEGER(IntKi), PARAMETER :: EddShrT8N10D9 = 9099 - INTEGER(IntKi), PARAMETER :: EddShrT8N11D1 = 9100 - INTEGER(IntKi), PARAMETER :: EddShrT8N11D2 = 9101 - INTEGER(IntKi), PARAMETER :: EddShrT8N11D3 = 9102 - INTEGER(IntKi), PARAMETER :: EddShrT8N11D4 = 9103 - INTEGER(IntKi), PARAMETER :: EddShrT8N11D5 = 9104 - INTEGER(IntKi), PARAMETER :: EddShrT8N11D6 = 9105 - INTEGER(IntKi), PARAMETER :: EddShrT8N11D7 = 9106 - INTEGER(IntKi), PARAMETER :: EddShrT8N11D8 = 9107 - INTEGER(IntKi), PARAMETER :: EddShrT8N11D9 = 9108 - INTEGER(IntKi), PARAMETER :: EddShrT8N12D1 = 9109 - INTEGER(IntKi), PARAMETER :: EddShrT8N12D2 = 9110 - INTEGER(IntKi), PARAMETER :: EddShrT8N12D3 = 9111 - INTEGER(IntKi), PARAMETER :: EddShrT8N12D4 = 9112 - INTEGER(IntKi), PARAMETER :: EddShrT8N12D5 = 9113 - INTEGER(IntKi), PARAMETER :: EddShrT8N12D6 = 9114 - INTEGER(IntKi), PARAMETER :: EddShrT8N12D7 = 9115 - INTEGER(IntKi), PARAMETER :: EddShrT8N12D8 = 9116 - INTEGER(IntKi), PARAMETER :: EddShrT8N12D9 = 9117 - INTEGER(IntKi), PARAMETER :: EddShrT8N13D1 = 9118 - INTEGER(IntKi), PARAMETER :: EddShrT8N13D2 = 9119 - INTEGER(IntKi), PARAMETER :: EddShrT8N13D3 = 9120 - INTEGER(IntKi), PARAMETER :: EddShrT8N13D4 = 9121 - INTEGER(IntKi), PARAMETER :: EddShrT8N13D5 = 9122 - INTEGER(IntKi), PARAMETER :: EddShrT8N13D6 = 9123 - INTEGER(IntKi), PARAMETER :: EddShrT8N13D7 = 9124 - INTEGER(IntKi), PARAMETER :: EddShrT8N13D8 = 9125 - INTEGER(IntKi), PARAMETER :: EddShrT8N13D9 = 9126 - INTEGER(IntKi), PARAMETER :: EddShrT8N14D1 = 9127 - INTEGER(IntKi), PARAMETER :: EddShrT8N14D2 = 9128 - INTEGER(IntKi), PARAMETER :: EddShrT8N14D3 = 9129 - INTEGER(IntKi), PARAMETER :: EddShrT8N14D4 = 9130 - INTEGER(IntKi), PARAMETER :: EddShrT8N14D5 = 9131 - INTEGER(IntKi), PARAMETER :: EddShrT8N14D6 = 9132 - INTEGER(IntKi), PARAMETER :: EddShrT8N14D7 = 9133 - INTEGER(IntKi), PARAMETER :: EddShrT8N14D8 = 9134 - INTEGER(IntKi), PARAMETER :: EddShrT8N14D9 = 9135 - INTEGER(IntKi), PARAMETER :: EddShrT8N15D1 = 9136 - INTEGER(IntKi), PARAMETER :: EddShrT8N15D2 = 9137 - INTEGER(IntKi), PARAMETER :: EddShrT8N15D3 = 9138 - INTEGER(IntKi), PARAMETER :: EddShrT8N15D4 = 9139 - INTEGER(IntKi), PARAMETER :: EddShrT8N15D5 = 9140 - INTEGER(IntKi), PARAMETER :: EddShrT8N15D6 = 9141 - INTEGER(IntKi), PARAMETER :: EddShrT8N15D7 = 9142 - INTEGER(IntKi), PARAMETER :: EddShrT8N15D8 = 9143 - INTEGER(IntKi), PARAMETER :: EddShrT8N15D9 = 9144 - INTEGER(IntKi), PARAMETER :: EddShrT8N16D1 = 9145 - INTEGER(IntKi), PARAMETER :: EddShrT8N16D2 = 9146 - INTEGER(IntKi), PARAMETER :: EddShrT8N16D3 = 9147 - INTEGER(IntKi), PARAMETER :: EddShrT8N16D4 = 9148 - INTEGER(IntKi), PARAMETER :: EddShrT8N16D5 = 9149 - INTEGER(IntKi), PARAMETER :: EddShrT8N16D6 = 9150 - INTEGER(IntKi), PARAMETER :: EddShrT8N16D7 = 9151 - INTEGER(IntKi), PARAMETER :: EddShrT8N16D8 = 9152 - INTEGER(IntKi), PARAMETER :: EddShrT8N16D9 = 9153 - INTEGER(IntKi), PARAMETER :: EddShrT8N17D1 = 9154 - INTEGER(IntKi), PARAMETER :: EddShrT8N17D2 = 9155 - INTEGER(IntKi), PARAMETER :: EddShrT8N17D3 = 9156 - INTEGER(IntKi), PARAMETER :: EddShrT8N17D4 = 9157 - INTEGER(IntKi), PARAMETER :: EddShrT8N17D5 = 9158 - INTEGER(IntKi), PARAMETER :: EddShrT8N17D6 = 9159 - INTEGER(IntKi), PARAMETER :: EddShrT8N17D7 = 9160 - INTEGER(IntKi), PARAMETER :: EddShrT8N17D8 = 9161 - INTEGER(IntKi), PARAMETER :: EddShrT8N17D9 = 9162 - INTEGER(IntKi), PARAMETER :: EddShrT8N18D1 = 9163 - INTEGER(IntKi), PARAMETER :: EddShrT8N18D2 = 9164 - INTEGER(IntKi), PARAMETER :: EddShrT8N18D3 = 9165 - INTEGER(IntKi), PARAMETER :: EddShrT8N18D4 = 9166 - INTEGER(IntKi), PARAMETER :: EddShrT8N18D5 = 9167 - INTEGER(IntKi), PARAMETER :: EddShrT8N18D6 = 9168 - INTEGER(IntKi), PARAMETER :: EddShrT8N18D7 = 9169 - INTEGER(IntKi), PARAMETER :: EddShrT8N18D8 = 9170 - INTEGER(IntKi), PARAMETER :: EddShrT8N18D9 = 9171 - INTEGER(IntKi), PARAMETER :: EddShrT8N19D1 = 9172 - INTEGER(IntKi), PARAMETER :: EddShrT8N19D2 = 9173 - INTEGER(IntKi), PARAMETER :: EddShrT8N19D3 = 9174 - INTEGER(IntKi), PARAMETER :: EddShrT8N19D4 = 9175 - INTEGER(IntKi), PARAMETER :: EddShrT8N19D5 = 9176 - INTEGER(IntKi), PARAMETER :: EddShrT8N19D6 = 9177 - INTEGER(IntKi), PARAMETER :: EddShrT8N19D7 = 9178 - INTEGER(IntKi), PARAMETER :: EddShrT8N19D8 = 9179 - INTEGER(IntKi), PARAMETER :: EddShrT8N19D9 = 9180 - INTEGER(IntKi), PARAMETER :: EddShrT8N20D1 = 9181 - INTEGER(IntKi), PARAMETER :: EddShrT8N20D2 = 9182 - INTEGER(IntKi), PARAMETER :: EddShrT8N20D3 = 9183 - INTEGER(IntKi), PARAMETER :: EddShrT8N20D4 = 9184 - INTEGER(IntKi), PARAMETER :: EddShrT8N20D5 = 9185 - INTEGER(IntKi), PARAMETER :: EddShrT8N20D6 = 9186 - INTEGER(IntKi), PARAMETER :: EddShrT8N20D7 = 9187 - INTEGER(IntKi), PARAMETER :: EddShrT8N20D8 = 9188 - INTEGER(IntKi), PARAMETER :: EddShrT8N20D9 = 9189 - INTEGER(IntKi), PARAMETER :: EddShrT9N01D1 = 9190 - INTEGER(IntKi), PARAMETER :: EddShrT9N01D2 = 9191 - INTEGER(IntKi), PARAMETER :: EddShrT9N01D3 = 9192 - INTEGER(IntKi), PARAMETER :: EddShrT9N01D4 = 9193 - INTEGER(IntKi), PARAMETER :: EddShrT9N01D5 = 9194 - INTEGER(IntKi), PARAMETER :: EddShrT9N01D6 = 9195 - INTEGER(IntKi), PARAMETER :: EddShrT9N01D7 = 9196 - INTEGER(IntKi), PARAMETER :: EddShrT9N01D8 = 9197 - INTEGER(IntKi), PARAMETER :: EddShrT9N01D9 = 9198 - INTEGER(IntKi), PARAMETER :: EddShrT9N02D1 = 9199 - INTEGER(IntKi), PARAMETER :: EddShrT9N02D2 = 9200 - INTEGER(IntKi), PARAMETER :: EddShrT9N02D3 = 9201 - INTEGER(IntKi), PARAMETER :: EddShrT9N02D4 = 9202 - INTEGER(IntKi), PARAMETER :: EddShrT9N02D5 = 9203 - INTEGER(IntKi), PARAMETER :: EddShrT9N02D6 = 9204 - INTEGER(IntKi), PARAMETER :: EddShrT9N02D7 = 9205 - INTEGER(IntKi), PARAMETER :: EddShrT9N02D8 = 9206 - INTEGER(IntKi), PARAMETER :: EddShrT9N02D9 = 9207 - INTEGER(IntKi), PARAMETER :: EddShrT9N03D1 = 9208 - INTEGER(IntKi), PARAMETER :: EddShrT9N03D2 = 9209 - INTEGER(IntKi), PARAMETER :: EddShrT9N03D3 = 9210 - INTEGER(IntKi), PARAMETER :: EddShrT9N03D4 = 9211 - INTEGER(IntKi), PARAMETER :: EddShrT9N03D5 = 9212 - INTEGER(IntKi), PARAMETER :: EddShrT9N03D6 = 9213 - INTEGER(IntKi), PARAMETER :: EddShrT9N03D7 = 9214 - INTEGER(IntKi), PARAMETER :: EddShrT9N03D8 = 9215 - INTEGER(IntKi), PARAMETER :: EddShrT9N03D9 = 9216 - INTEGER(IntKi), PARAMETER :: EddShrT9N04D1 = 9217 - INTEGER(IntKi), PARAMETER :: EddShrT9N04D2 = 9218 - INTEGER(IntKi), PARAMETER :: EddShrT9N04D3 = 9219 - INTEGER(IntKi), PARAMETER :: EddShrT9N04D4 = 9220 - INTEGER(IntKi), PARAMETER :: EddShrT9N04D5 = 9221 - INTEGER(IntKi), PARAMETER :: EddShrT9N04D6 = 9222 - INTEGER(IntKi), PARAMETER :: EddShrT9N04D7 = 9223 - INTEGER(IntKi), PARAMETER :: EddShrT9N04D8 = 9224 - INTEGER(IntKi), PARAMETER :: EddShrT9N04D9 = 9225 - INTEGER(IntKi), PARAMETER :: EddShrT9N05D1 = 9226 - INTEGER(IntKi), PARAMETER :: EddShrT9N05D2 = 9227 - INTEGER(IntKi), PARAMETER :: EddShrT9N05D3 = 9228 - INTEGER(IntKi), PARAMETER :: EddShrT9N05D4 = 9229 - INTEGER(IntKi), PARAMETER :: EddShrT9N05D5 = 9230 - INTEGER(IntKi), PARAMETER :: EddShrT9N05D6 = 9231 - INTEGER(IntKi), PARAMETER :: EddShrT9N05D7 = 9232 - INTEGER(IntKi), PARAMETER :: EddShrT9N05D8 = 9233 - INTEGER(IntKi), PARAMETER :: EddShrT9N05D9 = 9234 - INTEGER(IntKi), PARAMETER :: EddShrT9N06D1 = 9235 - INTEGER(IntKi), PARAMETER :: EddShrT9N06D2 = 9236 - INTEGER(IntKi), PARAMETER :: EddShrT9N06D3 = 9237 - INTEGER(IntKi), PARAMETER :: EddShrT9N06D4 = 9238 - INTEGER(IntKi), PARAMETER :: EddShrT9N06D5 = 9239 - INTEGER(IntKi), PARAMETER :: EddShrT9N06D6 = 9240 - INTEGER(IntKi), PARAMETER :: EddShrT9N06D7 = 9241 - INTEGER(IntKi), PARAMETER :: EddShrT9N06D8 = 9242 - INTEGER(IntKi), PARAMETER :: EddShrT9N06D9 = 9243 - INTEGER(IntKi), PARAMETER :: EddShrT9N07D1 = 9244 - INTEGER(IntKi), PARAMETER :: EddShrT9N07D2 = 9245 - INTEGER(IntKi), PARAMETER :: EddShrT9N07D3 = 9246 - INTEGER(IntKi), PARAMETER :: EddShrT9N07D4 = 9247 - INTEGER(IntKi), PARAMETER :: EddShrT9N07D5 = 9248 - INTEGER(IntKi), PARAMETER :: EddShrT9N07D6 = 9249 - INTEGER(IntKi), PARAMETER :: EddShrT9N07D7 = 9250 - INTEGER(IntKi), PARAMETER :: EddShrT9N07D8 = 9251 - INTEGER(IntKi), PARAMETER :: EddShrT9N07D9 = 9252 - INTEGER(IntKi), PARAMETER :: EddShrT9N08D1 = 9253 - INTEGER(IntKi), PARAMETER :: EddShrT9N08D2 = 9254 - INTEGER(IntKi), PARAMETER :: EddShrT9N08D3 = 9255 - INTEGER(IntKi), PARAMETER :: EddShrT9N08D4 = 9256 - INTEGER(IntKi), PARAMETER :: EddShrT9N08D5 = 9257 - INTEGER(IntKi), PARAMETER :: EddShrT9N08D6 = 9258 - INTEGER(IntKi), PARAMETER :: EddShrT9N08D7 = 9259 - INTEGER(IntKi), PARAMETER :: EddShrT9N08D8 = 9260 - INTEGER(IntKi), PARAMETER :: EddShrT9N08D9 = 9261 - INTEGER(IntKi), PARAMETER :: EddShrT9N09D1 = 9262 - INTEGER(IntKi), PARAMETER :: EddShrT9N09D2 = 9263 - INTEGER(IntKi), PARAMETER :: EddShrT9N09D3 = 9264 - INTEGER(IntKi), PARAMETER :: EddShrT9N09D4 = 9265 - INTEGER(IntKi), PARAMETER :: EddShrT9N09D5 = 9266 - INTEGER(IntKi), PARAMETER :: EddShrT9N09D6 = 9267 - INTEGER(IntKi), PARAMETER :: EddShrT9N09D7 = 9268 - INTEGER(IntKi), PARAMETER :: EddShrT9N09D8 = 9269 - INTEGER(IntKi), PARAMETER :: EddShrT9N09D9 = 9270 - INTEGER(IntKi), PARAMETER :: EddShrT9N10D1 = 9271 - INTEGER(IntKi), PARAMETER :: EddShrT9N10D2 = 9272 - INTEGER(IntKi), PARAMETER :: EddShrT9N10D3 = 9273 - INTEGER(IntKi), PARAMETER :: EddShrT9N10D4 = 9274 - INTEGER(IntKi), PARAMETER :: EddShrT9N10D5 = 9275 - INTEGER(IntKi), PARAMETER :: EddShrT9N10D6 = 9276 - INTEGER(IntKi), PARAMETER :: EddShrT9N10D7 = 9277 - INTEGER(IntKi), PARAMETER :: EddShrT9N10D8 = 9278 - INTEGER(IntKi), PARAMETER :: EddShrT9N10D9 = 9279 - INTEGER(IntKi), PARAMETER :: EddShrT9N11D1 = 9280 - INTEGER(IntKi), PARAMETER :: EddShrT9N11D2 = 9281 - INTEGER(IntKi), PARAMETER :: EddShrT9N11D3 = 9282 - INTEGER(IntKi), PARAMETER :: EddShrT9N11D4 = 9283 - INTEGER(IntKi), PARAMETER :: EddShrT9N11D5 = 9284 - INTEGER(IntKi), PARAMETER :: EddShrT9N11D6 = 9285 - INTEGER(IntKi), PARAMETER :: EddShrT9N11D7 = 9286 - INTEGER(IntKi), PARAMETER :: EddShrT9N11D8 = 9287 - INTEGER(IntKi), PARAMETER :: EddShrT9N11D9 = 9288 - INTEGER(IntKi), PARAMETER :: EddShrT9N12D1 = 9289 - INTEGER(IntKi), PARAMETER :: EddShrT9N12D2 = 9290 - INTEGER(IntKi), PARAMETER :: EddShrT9N12D3 = 9291 - INTEGER(IntKi), PARAMETER :: EddShrT9N12D4 = 9292 - INTEGER(IntKi), PARAMETER :: EddShrT9N12D5 = 9293 - INTEGER(IntKi), PARAMETER :: EddShrT9N12D6 = 9294 - INTEGER(IntKi), PARAMETER :: EddShrT9N12D7 = 9295 - INTEGER(IntKi), PARAMETER :: EddShrT9N12D8 = 9296 - INTEGER(IntKi), PARAMETER :: EddShrT9N12D9 = 9297 - INTEGER(IntKi), PARAMETER :: EddShrT9N13D1 = 9298 - INTEGER(IntKi), PARAMETER :: EddShrT9N13D2 = 9299 - INTEGER(IntKi), PARAMETER :: EddShrT9N13D3 = 9300 - INTEGER(IntKi), PARAMETER :: EddShrT9N13D4 = 9301 - INTEGER(IntKi), PARAMETER :: EddShrT9N13D5 = 9302 - INTEGER(IntKi), PARAMETER :: EddShrT9N13D6 = 9303 - INTEGER(IntKi), PARAMETER :: EddShrT9N13D7 = 9304 - INTEGER(IntKi), PARAMETER :: EddShrT9N13D8 = 9305 - INTEGER(IntKi), PARAMETER :: EddShrT9N13D9 = 9306 - INTEGER(IntKi), PARAMETER :: EddShrT9N14D1 = 9307 - INTEGER(IntKi), PARAMETER :: EddShrT9N14D2 = 9308 - INTEGER(IntKi), PARAMETER :: EddShrT9N14D3 = 9309 - INTEGER(IntKi), PARAMETER :: EddShrT9N14D4 = 9310 - INTEGER(IntKi), PARAMETER :: EddShrT9N14D5 = 9311 - INTEGER(IntKi), PARAMETER :: EddShrT9N14D6 = 9312 - INTEGER(IntKi), PARAMETER :: EddShrT9N14D7 = 9313 - INTEGER(IntKi), PARAMETER :: EddShrT9N14D8 = 9314 - INTEGER(IntKi), PARAMETER :: EddShrT9N14D9 = 9315 - INTEGER(IntKi), PARAMETER :: EddShrT9N15D1 = 9316 - INTEGER(IntKi), PARAMETER :: EddShrT9N15D2 = 9317 - INTEGER(IntKi), PARAMETER :: EddShrT9N15D3 = 9318 - INTEGER(IntKi), PARAMETER :: EddShrT9N15D4 = 9319 - INTEGER(IntKi), PARAMETER :: EddShrT9N15D5 = 9320 - INTEGER(IntKi), PARAMETER :: EddShrT9N15D6 = 9321 - INTEGER(IntKi), PARAMETER :: EddShrT9N15D7 = 9322 - INTEGER(IntKi), PARAMETER :: EddShrT9N15D8 = 9323 - INTEGER(IntKi), PARAMETER :: EddShrT9N15D9 = 9324 - INTEGER(IntKi), PARAMETER :: EddShrT9N16D1 = 9325 - INTEGER(IntKi), PARAMETER :: EddShrT9N16D2 = 9326 - INTEGER(IntKi), PARAMETER :: EddShrT9N16D3 = 9327 - INTEGER(IntKi), PARAMETER :: EddShrT9N16D4 = 9328 - INTEGER(IntKi), PARAMETER :: EddShrT9N16D5 = 9329 - INTEGER(IntKi), PARAMETER :: EddShrT9N16D6 = 9330 - INTEGER(IntKi), PARAMETER :: EddShrT9N16D7 = 9331 - INTEGER(IntKi), PARAMETER :: EddShrT9N16D8 = 9332 - INTEGER(IntKi), PARAMETER :: EddShrT9N16D9 = 9333 - INTEGER(IntKi), PARAMETER :: EddShrT9N17D1 = 9334 - INTEGER(IntKi), PARAMETER :: EddShrT9N17D2 = 9335 - INTEGER(IntKi), PARAMETER :: EddShrT9N17D3 = 9336 - INTEGER(IntKi), PARAMETER :: EddShrT9N17D4 = 9337 - INTEGER(IntKi), PARAMETER :: EddShrT9N17D5 = 9338 - INTEGER(IntKi), PARAMETER :: EddShrT9N17D6 = 9339 - INTEGER(IntKi), PARAMETER :: EddShrT9N17D7 = 9340 - INTEGER(IntKi), PARAMETER :: EddShrT9N17D8 = 9341 - INTEGER(IntKi), PARAMETER :: EddShrT9N17D9 = 9342 - INTEGER(IntKi), PARAMETER :: EddShrT9N18D1 = 9343 - INTEGER(IntKi), PARAMETER :: EddShrT9N18D2 = 9344 - INTEGER(IntKi), PARAMETER :: EddShrT9N18D3 = 9345 - INTEGER(IntKi), PARAMETER :: EddShrT9N18D4 = 9346 - INTEGER(IntKi), PARAMETER :: EddShrT9N18D5 = 9347 - INTEGER(IntKi), PARAMETER :: EddShrT9N18D6 = 9348 - INTEGER(IntKi), PARAMETER :: EddShrT9N18D7 = 9349 - INTEGER(IntKi), PARAMETER :: EddShrT9N18D8 = 9350 - INTEGER(IntKi), PARAMETER :: EddShrT9N18D9 = 9351 - INTEGER(IntKi), PARAMETER :: EddShrT9N19D1 = 9352 - INTEGER(IntKi), PARAMETER :: EddShrT9N19D2 = 9353 - INTEGER(IntKi), PARAMETER :: EddShrT9N19D3 = 9354 - INTEGER(IntKi), PARAMETER :: EddShrT9N19D4 = 9355 - INTEGER(IntKi), PARAMETER :: EddShrT9N19D5 = 9356 - INTEGER(IntKi), PARAMETER :: EddShrT9N19D6 = 9357 - INTEGER(IntKi), PARAMETER :: EddShrT9N19D7 = 9358 - INTEGER(IntKi), PARAMETER :: EddShrT9N19D8 = 9359 - INTEGER(IntKi), PARAMETER :: EddShrT9N19D9 = 9360 - INTEGER(IntKi), PARAMETER :: EddShrT9N20D1 = 9361 - INTEGER(IntKi), PARAMETER :: EddShrT9N20D2 = 9362 - INTEGER(IntKi), PARAMETER :: EddShrT9N20D3 = 9363 - INTEGER(IntKi), PARAMETER :: EddShrT9N20D4 = 9364 - INTEGER(IntKi), PARAMETER :: EddShrT9N20D5 = 9365 - INTEGER(IntKi), PARAMETER :: EddShrT9N20D6 = 9366 - INTEGER(IntKi), PARAMETER :: EddShrT9N20D7 = 9367 - INTEGER(IntKi), PARAMETER :: EddShrT9N20D8 = 9368 - INTEGER(IntKi), PARAMETER :: EddShrT9N20D9 = 9369 - - - ! Ambient Wind Velocity from Low-resolution Domain: - - INTEGER(IntKi), PARAMETER :: W1VAmbX = 9370 - INTEGER(IntKi), PARAMETER :: W2VAmbX = 9371 - INTEGER(IntKi), PARAMETER :: W3VAmbX = 9372 - INTEGER(IntKi), PARAMETER :: W4VAmbX = 9373 - INTEGER(IntKi), PARAMETER :: W5VAmbX = 9374 - INTEGER(IntKi), PARAMETER :: W6VAmbX = 9375 - INTEGER(IntKi), PARAMETER :: W7VAmbX = 9376 - INTEGER(IntKi), PARAMETER :: W8VAmbX = 9377 - INTEGER(IntKi), PARAMETER :: W9VAmbX = 9378 - INTEGER(IntKi), PARAMETER :: W1VAmbY = 9379 - INTEGER(IntKi), PARAMETER :: W2VAmbY = 9380 - INTEGER(IntKi), PARAMETER :: W3VAmbY = 9381 - INTEGER(IntKi), PARAMETER :: W4VAmbY = 9382 - INTEGER(IntKi), PARAMETER :: W5VAmbY = 9383 - INTEGER(IntKi), PARAMETER :: W6VAmbY = 9384 - INTEGER(IntKi), PARAMETER :: W7VAmbY = 9385 - INTEGER(IntKi), PARAMETER :: W8VAmbY = 9386 - INTEGER(IntKi), PARAMETER :: W9VAmbY = 9387 - INTEGER(IntKi), PARAMETER :: W1VAmbZ = 9388 - INTEGER(IntKi), PARAMETER :: W2VAmbZ = 9389 - INTEGER(IntKi), PARAMETER :: W3VAmbZ = 9390 - INTEGER(IntKi), PARAMETER :: W4VAmbZ = 9391 - INTEGER(IntKi), PARAMETER :: W5VAmbZ = 9392 - INTEGER(IntKi), PARAMETER :: W6VAmbZ = 9393 - INTEGER(IntKi), PARAMETER :: W7VAmbZ = 9394 - INTEGER(IntKi), PARAMETER :: W8VAmbZ = 9395 - INTEGER(IntKi), PARAMETER :: W9VAmbZ = 9396 - - - ! Disturbed Wind Velocity from Low-resolution Domain: - - INTEGER(IntKi), PARAMETER :: W1VDisX = 9397 - INTEGER(IntKi), PARAMETER :: W2VDisX = 9398 - INTEGER(IntKi), PARAMETER :: W3VDisX = 9399 - INTEGER(IntKi), PARAMETER :: W4VDisX = 9400 - INTEGER(IntKi), PARAMETER :: W5VDisX = 9401 - INTEGER(IntKi), PARAMETER :: W6VDisX = 9402 - INTEGER(IntKi), PARAMETER :: W7VDisX = 9403 - INTEGER(IntKi), PARAMETER :: W8VDisX = 9404 - INTEGER(IntKi), PARAMETER :: W9VDisX = 9405 - INTEGER(IntKi), PARAMETER :: W1VDisY = 9406 - INTEGER(IntKi), PARAMETER :: W2VDisY = 9407 - INTEGER(IntKi), PARAMETER :: W3VDisY = 9408 - INTEGER(IntKi), PARAMETER :: W4VDisY = 9409 - INTEGER(IntKi), PARAMETER :: W5VDisY = 9410 - INTEGER(IntKi), PARAMETER :: W6VDisY = 9411 - INTEGER(IntKi), PARAMETER :: W7VDisY = 9412 - INTEGER(IntKi), PARAMETER :: W8VDisY = 9413 - INTEGER(IntKi), PARAMETER :: W9VDisY = 9414 - INTEGER(IntKi), PARAMETER :: W1VDisZ = 9415 - INTEGER(IntKi), PARAMETER :: W2VDisZ = 9416 - INTEGER(IntKi), PARAMETER :: W3VDisZ = 9417 - INTEGER(IntKi), PARAMETER :: W4VDisZ = 9418 - INTEGER(IntKi), PARAMETER :: W5VDisZ = 9419 - INTEGER(IntKi), PARAMETER :: W6VDisZ = 9420 - INTEGER(IntKi), PARAMETER :: W7VDisZ = 9421 - INTEGER(IntKi), PARAMETER :: W8VDisZ = 9422 - INTEGER(IntKi), PARAMETER :: W9VDisZ = 9423 - - -!End of code generated by Matlab script -! =================================================================================================== + USE NWTC_Library + USE FAST_Farm_Types + USE FAST_Farm_IO_Params - INTEGER, PARAMETER :: SCGblIn(9) = (/SCGblIn1,SCGblIn2,SCGblIn3,SCGblIn4,SCGblIn5,SCGblIn6,SCGblIn7,SCGblIn8,SCGblIn9/) - INTEGER, PARAMETER :: SCGblOt(9) = (/SCGblOt1,SCGblOt2,SCGblOt3,SCGblOt4,SCGblOt5,SCGblOt6,SCGblOt7,SCGblOt8,SCGblOt9/) - INTEGER, PARAMETER :: SCTIn(9,9) = RESHAPE( & - (/SCT1In1 ,SCT1In2 ,SCT1In3 ,SCT1In4 ,SCT1In5 ,SCT1In6 ,SCT1In7 ,SCT1In8 ,SCT1In9, & - SCT2In1 ,SCT2In2 ,SCT2In3 ,SCT2In4 ,SCT2In5 ,SCT2In6 ,SCT2In7 ,SCT2In8 ,SCT2In9, & - SCT3In1 ,SCT3In2 ,SCT3In3 ,SCT3In4 ,SCT3In5 ,SCT3In6 ,SCT3In7 ,SCT3In8 ,SCT3In9, & - SCT4In1 ,SCT4In2 ,SCT4In3 ,SCT4In4 ,SCT4In5 ,SCT4In6 ,SCT4In7 ,SCT4In8 ,SCT4In9, & - SCT5In1 ,SCT5In2 ,SCT5In3 ,SCT5In4 ,SCT5In5 ,SCT5In6 ,SCT5In7 ,SCT5In8 ,SCT5In9, & - SCT6In1 ,SCT6In2 ,SCT6In3 ,SCT6In4 ,SCT6In5 ,SCT6In6 ,SCT6In7 ,SCT6In8 ,SCT6In9, & - SCT7In1 ,SCT7In2 ,SCT7In3 ,SCT7In4 ,SCT7In5 ,SCT7In6 ,SCT7In7 ,SCT7In8 ,SCT7In9, & - SCT8In1 ,SCT8In2 ,SCT8In3 ,SCT8In4 ,SCT8In5 ,SCT8In6 ,SCT8In7 ,SCT8In8 ,SCT8In9, & - SCT9In1 ,SCT9In2 ,SCT9In3 ,SCT9In4 ,SCT9In5 ,SCT9In6 ,SCT9In7 ,SCT9In8 ,SCT9In9/), (/9,9/) ) - INTEGER, PARAMETER :: SCTOt(9,9) = RESHAPE( & - (/SCT1Ot1 ,SCT1Ot2 ,SCT1Ot3 ,SCT1Ot4 ,SCT1Ot5 ,SCT1Ot6 ,SCT1Ot7 ,SCT1Ot8 ,SCT1Ot9, & - SCT2Ot1 ,SCT2Ot2 ,SCT2Ot3 ,SCT2Ot4 ,SCT2Ot5 ,SCT2Ot6 ,SCT2Ot7 ,SCT2Ot8 ,SCT2Ot9, & - SCT3Ot1 ,SCT3Ot2 ,SCT3Ot3 ,SCT3Ot4 ,SCT3Ot5 ,SCT3Ot6 ,SCT3Ot7 ,SCT3Ot8 ,SCT3Ot9, & - SCT4Ot1 ,SCT4Ot2 ,SCT4Ot3 ,SCT4Ot4 ,SCT4Ot5 ,SCT4Ot6 ,SCT4Ot7 ,SCT4Ot8 ,SCT4Ot9, & - SCT5Ot1 ,SCT5Ot2 ,SCT5Ot3 ,SCT5Ot4 ,SCT5Ot5 ,SCT5Ot6 ,SCT5Ot7 ,SCT5Ot8 ,SCT5Ot9, & - SCT6Ot1 ,SCT6Ot2 ,SCT6Ot3 ,SCT6Ot4 ,SCT6Ot5 ,SCT6Ot6 ,SCT6Ot7 ,SCT6Ot8 ,SCT6Ot9, & - SCT7Ot1 ,SCT7Ot2 ,SCT7Ot3 ,SCT7Ot4 ,SCT7Ot5 ,SCT7Ot6 ,SCT7Ot7 ,SCT7Ot8 ,SCT7Ot9, & - SCT8Ot1 ,SCT8Ot2 ,SCT8Ot3 ,SCT8Ot4 ,SCT8Ot5 ,SCT8Ot6 ,SCT8Ot7 ,SCT8Ot8 ,SCT8Ot9, & - SCT9Ot1 ,SCT9Ot2 ,SCT9Ot3 ,SCT9Ot4 ,SCT9Ot5 ,SCT9Ot6 ,SCT9Ot7 ,SCT9Ot8 ,SCT9Ot9/), (/9,9/) ) - - INTEGER, PARAMETER :: RtAxsXT(9) = (/RtAxsXT1,RtAxsXT2,RtAxsXT3,RtAxsXT4,RtAxsXT5,RtAxsXT6,RtAxsXT7,RtAxsXT8,RtAxsXT9/) - INTEGER, PARAMETER :: RtAxsYT(9) = (/RtAxsYT1,RtAxsYT2,RtAxsYT3,RtAxsYT4,RtAxsYT5,RtAxsYT6,RtAxsYT7,RtAxsYT8,RtAxsYT9/) - INTEGER, PARAMETER :: RtAxsZT(9) = (/RtAxsZT1,RtAxsZT2,RtAxsZT3,RtAxsZT4,RtAxsZT5,RtAxsZT6,RtAxsZT7,RtAxsZT8,RtAxsZT9/) - - INTEGER, PARAMETER :: RtPosXT(9) = (/RtPosXT1,RtPosXT2,RtPosXT3,RtPosXT4,RtPosXT5,RtPosXT6,RtPosXT7,RtPosXT8,RtPosXT9/) - INTEGER, PARAMETER :: RtPosYT(9) = (/RtPosYT1,RtPosYT2,RtPosYT3,RtPosYT4,RtPosYT5,RtPosYT6,RtPosYT7,RtPosYT8,RtPosYT9/) - INTEGER, PARAMETER :: RtPosZT(9) = (/RtPosZT1,RtPosZT2,RtPosZT3,RtPosZT4,RtPosZT5,RtPosZT6,RtPosZT7,RtPosZT8,RtPosZT9/) - - INTEGER, PARAMETER :: RtDiamT(9) = (/RtDiamT1,RtDiamT2,RtDiamT3,RtDiamT4,RtDiamT5,RtDiamT6,RtDiamT7,RtDiamT8,RtDiamT9/) - INTEGER, PARAMETER :: YawErrT(9) = (/YawErrT1,YawErrT2,YawErrT3,YawErrT4,YawErrT5,YawErrT6,YawErrT7,YawErrT8,YawErrT9/) - INTEGER, PARAMETER :: TIAmbT(9) = (/TIAmbT1,TIAmbT2,TIAmbT3,TIAmbT4,TIAmbT5,TIAmbT6,TIAmbT7,TIAmbT8,TIAmbT9/) - INTEGER, PARAMETER :: RtVAmbT(9) = (/RtVAmbT1,RtVAmbT2,RtVAmbT3,RtVAmbT4,RtVAmbT5,RtVAmbT6,RtVAmbT7,RtVAmbT8,RtVAmbT9/) - INTEGER, PARAMETER :: RTVRelT(9) = (/RTVRelT1,RTVRelT2,RTVRelT3,RTVRelT4,RTVRelT5,RTVRelT6,RTVRelT7,RTVRelT8,RTVRelT9/) - - INTEGER, PARAMETER :: CtTN(20,9) = RESHAPE( & - (/CtT1N01,CtT1N02,CtT1N03,CtT1N04,CtT1N05,CtT1N06,CtT1N07,CtT1N08,CtT1N09, CtT1N10, & - CtT1N11,CtT1N12,CtT1N13,CtT1N14,CtT1N15,CtT1N16,CtT1N17,CtT1N18,CtT1N19, CtT1N20, & - CtT2N01,CtT2N02,CtT2N03,CtT2N04,CtT2N05,CtT2N06,CtT2N07,CtT2N08,CtT2N09, CtT2N10, & - CtT2N11,CtT2N12,CtT2N13,CtT2N14,CtT2N15,CtT2N16,CtT2N17,CtT2N18,CtT2N19, CtT2N20, & - CtT3N01,CtT3N02,CtT3N03,CtT3N04,CtT3N05,CtT3N06,CtT3N07,CtT3N08,CtT3N09, CtT3N10, & - CtT3N11,CtT3N12,CtT3N13,CtT3N14,CtT3N15,CtT3N16,CtT3N17,CtT3N18,CtT3N19, CtT3N20, & - CtT4N01,CtT4N02,CtT4N03,CtT4N04,CtT4N05,CtT4N06,CtT4N07,CtT4N08,CtT4N09, CtT4N10, & - CtT4N11,CtT4N12,CtT4N13,CtT4N14,CtT4N15,CtT4N16,CtT4N17,CtT4N18,CtT4N19, CtT4N20, & - CtT5N01,CtT5N02,CtT5N03,CtT5N04,CtT5N05,CtT5N06,CtT5N07,CtT5N08,CtT5N09, CtT5N10, & - CtT5N11,CtT5N12,CtT5N13,CtT5N14,CtT5N15,CtT5N16,CtT5N17,CtT5N18,CtT5N19, CtT5N20, & - CtT6N01,CtT6N02,CtT6N03,CtT6N04,CtT6N05,CtT6N06,CtT6N07,CtT6N08,CtT6N09, CtT6N10, & - CtT6N11,CtT6N12,CtT6N13,CtT6N14,CtT6N15,CtT6N16,CtT6N17,CtT6N18,CtT6N19, CtT6N20, & - CtT7N01,CtT7N02,CtT7N03,CtT7N04,CtT7N05,CtT7N06,CtT7N07,CtT7N08,CtT7N09, CtT7N10, & - CtT7N11,CtT7N12,CtT7N13,CtT7N14,CtT7N15,CtT7N16,CtT7N17,CtT7N18,CtT7N19, CtT7N20, & - CtT8N01,CtT8N02,CtT8N03,CtT8N04,CtT8N05,CtT8N06,CtT8N07,CtT8N08,CtT8N09, CtT8N10, & - CtT8N11,CtT8N12,CtT8N13,CtT8N14,CtT8N15,CtT8N16,CtT8N17,CtT8N18,CtT8N19, CtT8N20, & - CtT9N01,CtT9N02,CtT9N03,CtT9N04,CtT9N05,CtT9N06,CtT9N07,CtT9N08,CtT9N09, CtT9N10, & - CtT9N11,CtT9N12,CtT9N13,CtT9N14,CtT9N15,CtT9N16,CtT9N17,CtT9N18,CtT9N19, CtT9N20/), (/20,9/) ) - - - - INTEGER, PARAMETER :: WkAxsXTD(9,9) = RESHAPE( & - (/WkAxsXT1D1,WkAxsXT1D2,WkAxsXT1D3,WkAxsXT1D4,WkAxsXT1D5,WkAxsXT1D6,WkAxsXT1D7,WkAxsXT1D8,WkAxsXT1D9, & - WkAxsXT2D1,WkAxsXT2D2,WkAxsXT2D3,WkAxsXT2D4,WkAxsXT2D5,WkAxsXT2D6,WkAxsXT2D7,WkAxsXT2D8,WkAxsXT2D9, & - WkAxsXT3D1,WkAxsXT3D2,WkAxsXT3D3,WkAxsXT3D4,WkAxsXT3D5,WkAxsXT3D6,WkAxsXT3D7,WkAxsXT3D8,WkAxsXT3D9, & - WkAxsXT4D1,WkAxsXT4D2,WkAxsXT4D3,WkAxsXT4D4,WkAxsXT4D5,WkAxsXT4D6,WkAxsXT4D7,WkAxsXT4D8,WkAxsXT4D9, & - WkAxsXT5D1,WkAxsXT5D2,WkAxsXT5D3,WkAxsXT5D4,WkAxsXT5D5,WkAxsXT5D6,WkAxsXT5D7,WkAxsXT5D8,WkAxsXT5D9, & - WkAxsXT6D1,WkAxsXT6D2,WkAxsXT6D3,WkAxsXT6D4,WkAxsXT6D5,WkAxsXT6D6,WkAxsXT6D7,WkAxsXT6D8,WkAxsXT6D9, & - WkAxsXT7D1,WkAxsXT7D2,WkAxsXT7D3,WkAxsXT7D4,WkAxsXT7D5,WkAxsXT7D6,WkAxsXT7D7,WkAxsXT7D8,WkAxsXT7D9, & - WkAxsXT8D1,WkAxsXT8D2,WkAxsXT8D3,WkAxsXT8D4,WkAxsXT8D5,WkAxsXT8D6,WkAxsXT8D7,WkAxsXT8D8,WkAxsXT8D9, & - WkAxsXT9D1,WkAxsXT9D2,WkAxsXT9D3,WkAxsXT9D4,WkAxsXT9D5,WkAxsXT9D6,WkAxsXT9D7,WkAxsXT9D8,WkAxsXT9D9/), (/9,9/) ) - - INTEGER, PARAMETER :: WkAxsYTD(9,9) = RESHAPE( & - (/WkAxsYT1D1,WkAxsYT1D2,WkAxsYT1D3,WkAxsYT1D4,WkAxsYT1D5,WkAxsYT1D6,WkAxsYT1D7,WkAxsYT1D8,WkAxsYT1D9, & - WkAxsYT2D1,WkAxsYT2D2,WkAxsYT2D3,WkAxsYT2D4,WkAxsYT2D5,WkAxsYT2D6,WkAxsYT2D7,WkAxsYT2D8,WkAxsYT2D9, & - WkAxsYT3D1,WkAxsYT3D2,WkAxsYT3D3,WkAxsYT3D4,WkAxsYT3D5,WkAxsYT3D6,WkAxsYT3D7,WkAxsYT3D8,WkAxsYT3D9, & - WkAxsYT4D1,WkAxsYT4D2,WkAxsYT4D3,WkAxsYT4D4,WkAxsYT4D5,WkAxsYT4D6,WkAxsYT4D7,WkAxsYT4D8,WkAxsYT4D9, & - WkAxsYT5D1,WkAxsYT5D2,WkAxsYT5D3,WkAxsYT5D4,WkAxsYT5D5,WkAxsYT5D6,WkAxsYT5D7,WkAxsYT5D8,WkAxsYT5D9, & - WkAxsYT6D1,WkAxsYT6D2,WkAxsYT6D3,WkAxsYT6D4,WkAxsYT6D5,WkAxsYT6D6,WkAxsYT6D7,WkAxsYT6D8,WkAxsYT6D9, & - WkAxsYT7D1,WkAxsYT7D2,WkAxsYT7D3,WkAxsYT7D4,WkAxsYT7D5,WkAxsYT7D6,WkAxsYT7D7,WkAxsYT7D8,WkAxsYT7D9, & - WkAxsYT8D1,WkAxsYT8D2,WkAxsYT8D3,WkAxsYT8D4,WkAxsYT8D5,WkAxsYT8D6,WkAxsYT8D7,WkAxsYT8D8,WkAxsYT8D9, & - WkAxsYT9D1,WkAxsYT9D2,WkAxsYT9D3,WkAxsYT9D4,WkAxsYT9D5,WkAxsYT9D6,WkAxsYT9D7,WkAxsYT9D8,WkAxsYT9D9/), (/9,9/) ) - - INTEGER, PARAMETER :: WkAxsZTD(9,9) = RESHAPE( & - (/WkAxsZT1D1,WkAxsZT1D2,WkAxsZT1D3,WkAxsZT1D4,WkAxsZT1D5,WkAxsZT1D6,WkAxsZT1D7,WkAxsZT1D8,WkAxsZT1D9, & - WkAxsZT2D1,WkAxsZT2D2,WkAxsZT2D3,WkAxsZT2D4,WkAxsZT2D5,WkAxsZT2D6,WkAxsZT2D7,WkAxsZT2D8,WkAxsZT2D9, & - WkAxsZT3D1,WkAxsZT3D2,WkAxsZT3D3,WkAxsZT3D4,WkAxsZT3D5,WkAxsZT3D6,WkAxsZT3D7,WkAxsZT3D8,WkAxsZT3D9, & - WkAxsZT4D1,WkAxsZT4D2,WkAxsZT4D3,WkAxsZT4D4,WkAxsZT4D5,WkAxsZT4D6,WkAxsZT4D7,WkAxsZT4D8,WkAxsZT4D9, & - WkAxsZT5D1,WkAxsZT5D2,WkAxsZT5D3,WkAxsZT5D4,WkAxsZT5D5,WkAxsZT5D6,WkAxsZT5D7,WkAxsZT5D8,WkAxsZT5D9, & - WkAxsZT6D1,WkAxsZT6D2,WkAxsZT6D3,WkAxsZT6D4,WkAxsZT6D5,WkAxsZT6D6,WkAxsZT6D7,WkAxsZT6D8,WkAxsZT6D9, & - WkAxsZT7D1,WkAxsZT7D2,WkAxsZT7D3,WkAxsZT7D4,WkAxsZT7D5,WkAxsZT7D6,WkAxsZT7D7,WkAxsZT7D8,WkAxsZT7D9, & - WkAxsZT8D1,WkAxsZT8D2,WkAxsZT8D3,WkAxsZT8D4,WkAxsZT8D5,WkAxsZT8D6,WkAxsZT8D7,WkAxsZT8D8,WkAxsZT8D9, & - WkAxsZT9D1,WkAxsZT9D2,WkAxsZT9D3,WkAxsZT9D4,WkAxsZT9D5,WkAxsZT9D6,WkAxsZT9D7,WkAxsZT9D8,WkAxsZT9D9/), (/9,9/) ) - - INTEGER, PARAMETER :: WkPosXTD(9,9) = RESHAPE( & - (/WkPosXT1D1,WkPosXT1D2,WkPosXT1D3,WkPosXT1D4,WkPosXT1D5,WkPosXT1D6,WkPosXT1D7,WkPosXT1D8,WkPosXT1D9, & - WkPosXT2D1,WkPosXT2D2,WkPosXT2D3,WkPosXT2D4,WkPosXT2D5,WkPosXT2D6,WkPosXT2D7,WkPosXT2D8,WkPosXT2D9, & - WkPosXT3D1,WkPosXT3D2,WkPosXT3D3,WkPosXT3D4,WkPosXT3D5,WkPosXT3D6,WkPosXT3D7,WkPosXT3D8,WkPosXT3D9, & - WkPosXT4D1,WkPosXT4D2,WkPosXT4D3,WkPosXT4D4,WkPosXT4D5,WkPosXT4D6,WkPosXT4D7,WkPosXT4D8,WkPosXT4D9, & - WkPosXT5D1,WkPosXT5D2,WkPosXT5D3,WkPosXT5D4,WkPosXT5D5,WkPosXT5D6,WkPosXT5D7,WkPosXT5D8,WkPosXT5D9, & - WkPosXT6D1,WkPosXT6D2,WkPosXT6D3,WkPosXT6D4,WkPosXT6D5,WkPosXT6D6,WkPosXT6D7,WkPosXT6D8,WkPosXT6D9, & - WkPosXT7D1,WkPosXT7D2,WkPosXT7D3,WkPosXT7D4,WkPosXT7D5,WkPosXT7D6,WkPosXT7D7,WkPosXT7D8,WkPosXT7D9, & - WkPosXT8D1,WkPosXT8D2,WkPosXT8D3,WkPosXT8D4,WkPosXT8D5,WkPosXT8D6,WkPosXT8D7,WkPosXT8D8,WkPosXT8D9, & - WkPosXT9D1,WkPosXT9D2,WkPosXT9D3,WkPosXT9D4,WkPosXT9D5,WkPosXT9D6,WkPosXT9D7,WkPosXT9D8,WkPosXT9D9/), (/9,9/) ) - - INTEGER, PARAMETER :: WkPosYTD(9,9) = RESHAPE( & - (/WkPosYT1D1,WkPosYT1D2,WkPosYT1D3,WkPosYT1D4,WkPosYT1D5,WkPosYT1D6,WkPosYT1D7,WkPosYT1D8,WkPosYT1D9, & - WkPosYT2D1,WkPosYT2D2,WkPosYT2D3,WkPosYT2D4,WkPosYT2D5,WkPosYT2D6,WkPosYT2D7,WkPosYT2D8,WkPosYT2D9, & - WkPosYT3D1,WkPosYT3D2,WkPosYT3D3,WkPosYT3D4,WkPosYT3D5,WkPosYT3D6,WkPosYT3D7,WkPosYT3D8,WkPosYT3D9, & - WkPosYT4D1,WkPosYT4D2,WkPosYT4D3,WkPosYT4D4,WkPosYT4D5,WkPosYT4D6,WkPosYT4D7,WkPosYT4D8,WkPosYT4D9, & - WkPosYT5D1,WkPosYT5D2,WkPosYT5D3,WkPosYT5D4,WkPosYT5D5,WkPosYT5D6,WkPosYT5D7,WkPosYT5D8,WkPosYT5D9, & - WkPosYT6D1,WkPosYT6D2,WkPosYT6D3,WkPosYT6D4,WkPosYT6D5,WkPosYT6D6,WkPosYT6D7,WkPosYT6D8,WkPosYT6D9, & - WkPosYT7D1,WkPosYT7D2,WkPosYT7D3,WkPosYT7D4,WkPosYT7D5,WkPosYT7D6,WkPosYT7D7,WkPosYT7D8,WkPosYT7D9, & - WkPosYT8D1,WkPosYT8D2,WkPosYT8D3,WkPosYT8D4,WkPosYT8D5,WkPosYT8D6,WkPosYT8D7,WkPosYT8D8,WkPosYT8D9, & - WkPosYT9D1,WkPosYT9D2,WkPosYT9D3,WkPosYT9D4,WkPosYT9D5,WkPosYT9D6,WkPosYT9D7,WkPosYT9D8,WkPosYT9D9/), (/9,9/) ) - - INTEGER, PARAMETER :: WkPosZTD(9,9) = RESHAPE( & - (/WkPosZT1D1,WkPosZT1D2,WkPosZT1D3,WkPosZT1D4,WkPosZT1D5,WkPosZT1D6,WkPosZT1D7,WkPosZT1D8,WkPosZT1D9, & - WkPosZT2D1,WkPosZT2D2,WkPosZT2D3,WkPosZT2D4,WkPosZT2D5,WkPosZT2D6,WkPosZT2D7,WkPosZT2D8,WkPosZT2D9, & - WkPosZT3D1,WkPosZT3D2,WkPosZT3D3,WkPosZT3D4,WkPosZT3D5,WkPosZT3D6,WkPosZT3D7,WkPosZT3D8,WkPosZT3D9, & - WkPosZT4D1,WkPosZT4D2,WkPosZT4D3,WkPosZT4D4,WkPosZT4D5,WkPosZT4D6,WkPosZT4D7,WkPosZT4D8,WkPosZT4D9, & - WkPosZT5D1,WkPosZT5D2,WkPosZT5D3,WkPosZT5D4,WkPosZT5D5,WkPosZT5D6,WkPosZT5D7,WkPosZT5D8,WkPosZT5D9, & - WkPosZT6D1,WkPosZT6D2,WkPosZT6D3,WkPosZT6D4,WkPosZT6D5,WkPosZT6D6,WkPosZT6D7,WkPosZT6D8,WkPosZT6D9, & - WkPosZT7D1,WkPosZT7D2,WkPosZT7D3,WkPosZT7D4,WkPosZT7D5,WkPosZT7D6,WkPosZT7D7,WkPosZT7D8,WkPosZT7D9, & - WkPosZT8D1,WkPosZT8D2,WkPosZT8D3,WkPosZT8D4,WkPosZT8D5,WkPosZT8D6,WkPosZT8D7,WkPosZT8D8,WkPosZT8D9, & - WkPosZT9D1,WkPosZT9D2,WkPosZT9D3,WkPosZT9D4,WkPosZT9D5,WkPosZT9D6,WkPosZT9D7,WkPosZT9D8,WkPosZT9D9/), (/9,9/) ) - - INTEGER, PARAMETER :: WkVelXTD(9,9) = RESHAPE( & - (/WkVelXT1D1,WkVelXT1D2,WkVelXT1D3,WkVelXT1D4,WkVelXT1D5,WkVelXT1D6,WkVelXT1D7,WkVelXT1D8,WkVelXT1D9, & - WkVelXT2D1,WkVelXT2D2,WkVelXT2D3,WkVelXT2D4,WkVelXT2D5,WkVelXT2D6,WkVelXT2D7,WkVelXT2D8,WkVelXT2D9, & - WkVelXT3D1,WkVelXT3D2,WkVelXT3D3,WkVelXT3D4,WkVelXT3D5,WkVelXT3D6,WkVelXT3D7,WkVelXT3D8,WkVelXT3D9, & - WkVelXT4D1,WkVelXT4D2,WkVelXT4D3,WkVelXT4D4,WkVelXT4D5,WkVelXT4D6,WkVelXT4D7,WkVelXT4D8,WkVelXT4D9, & - WkVelXT5D1,WkVelXT5D2,WkVelXT5D3,WkVelXT5D4,WkVelXT5D5,WkVelXT5D6,WkVelXT5D7,WkVelXT5D8,WkVelXT5D9, & - WkVelXT6D1,WkVelXT6D2,WkVelXT6D3,WkVelXT6D4,WkVelXT6D5,WkVelXT6D6,WkVelXT6D7,WkVelXT6D8,WkVelXT6D9, & - WkVelXT7D1,WkVelXT7D2,WkVelXT7D3,WkVelXT7D4,WkVelXT7D5,WkVelXT7D6,WkVelXT7D7,WkVelXT7D8,WkVelXT7D9, & - WkVelXT8D1,WkVelXT8D2,WkVelXT8D3,WkVelXT8D4,WkVelXT8D5,WkVelXT8D6,WkVelXT8D7,WkVelXT8D8,WkVelXT8D9, & - WkVelXT9D1,WkVelXT9D2,WkVelXT9D3,WkVelXT9D4,WkVelXT9D5,WkVelXT9D6,WkVelXT9D7,WkVelXT9D8,WkVelXT9D9/), (/9,9/) ) - - INTEGER, PARAMETER :: WkVelYTD(9,9) = RESHAPE( & - (/WkVelYT1D1,WkVelYT1D2,WkVelYT1D3,WkVelYT1D4,WkVelYT1D5,WkVelYT1D6,WkVelYT1D7,WkVelYT1D8,WkVelYT1D9, & - WkVelYT2D1,WkVelYT2D2,WkVelYT2D3,WkVelYT2D4,WkVelYT2D5,WkVelYT2D6,WkVelYT2D7,WkVelYT2D8,WkVelYT2D9, & - WkVelYT3D1,WkVelYT3D2,WkVelYT3D3,WkVelYT3D4,WkVelYT3D5,WkVelYT3D6,WkVelYT3D7,WkVelYT3D8,WkVelYT3D9, & - WkVelYT4D1,WkVelYT4D2,WkVelYT4D3,WkVelYT4D4,WkVelYT4D5,WkVelYT4D6,WkVelYT4D7,WkVelYT4D8,WkVelYT4D9, & - WkVelYT5D1,WkVelYT5D2,WkVelYT5D3,WkVelYT5D4,WkVelYT5D5,WkVelYT5D6,WkVelYT5D7,WkVelYT5D8,WkVelYT5D9, & - WkVelYT6D1,WkVelYT6D2,WkVelYT6D3,WkVelYT6D4,WkVelYT6D5,WkVelYT6D6,WkVelYT6D7,WkVelYT6D8,WkVelYT6D9, & - WkVelYT7D1,WkVelYT7D2,WkVelYT7D3,WkVelYT7D4,WkVelYT7D5,WkVelYT7D6,WkVelYT7D7,WkVelYT7D8,WkVelYT7D9, & - WkVelYT8D1,WkVelYT8D2,WkVelYT8D3,WkVelYT8D4,WkVelYT8D5,WkVelYT8D6,WkVelYT8D7,WkVelYT8D8,WkVelYT8D9, & - WkVelYT9D1,WkVelYT9D2,WkVelYT9D3,WkVelYT9D4,WkVelYT9D5,WkVelYT9D6,WkVelYT9D7,WkVelYT9D8,WkVelYT9D9/), (/9,9/) ) - - INTEGER, PARAMETER :: WkVelZTD(9,9) = RESHAPE( & - (/WkVelZT1D1,WkVelZT1D2,WkVelZT1D3,WkVelZT1D4,WkVelZT1D5,WkVelZT1D6,WkVelZT1D7,WkVelZT1D8,WkVelZT1D9, & - WkVelZT2D1,WkVelZT2D2,WkVelZT2D3,WkVelZT2D4,WkVelZT2D5,WkVelZT2D6,WkVelZT2D7,WkVelZT2D8,WkVelZT2D9, & - WkVelZT3D1,WkVelZT3D2,WkVelZT3D3,WkVelZT3D4,WkVelZT3D5,WkVelZT3D6,WkVelZT3D7,WkVelZT3D8,WkVelZT3D9, & - WkVelZT4D1,WkVelZT4D2,WkVelZT4D3,WkVelZT4D4,WkVelZT4D5,WkVelZT4D6,WkVelZT4D7,WkVelZT4D8,WkVelZT4D9, & - WkVelZT5D1,WkVelZT5D2,WkVelZT5D3,WkVelZT5D4,WkVelZT5D5,WkVelZT5D6,WkVelZT5D7,WkVelZT5D8,WkVelZT5D9, & - WkVelZT6D1,WkVelZT6D2,WkVelZT6D3,WkVelZT6D4,WkVelZT6D5,WkVelZT6D6,WkVelZT6D7,WkVelZT6D8,WkVelZT6D9, & - WkVelZT7D1,WkVelZT7D2,WkVelZT7D3,WkVelZT7D4,WkVelZT7D5,WkVelZT7D6,WkVelZT7D7,WkVelZT7D8,WkVelZT7D9, & - WkVelZT8D1,WkVelZT8D2,WkVelZT8D3,WkVelZT8D4,WkVelZT8D5,WkVelZT8D6,WkVelZT8D7,WkVelZT8D8,WkVelZT8D9, & - WkVelZT9D1,WkVelZT9D2,WkVelZT9D3,WkVelZT9D4,WkVelZT9D5,WkVelZT9D6,WkVelZT9D7,WkVelZT9D8,WkVelZT9D9/), (/9,9/) ) - - INTEGER, PARAMETER :: WkDiamTD(9,9) = RESHAPE( & - (/WkDiamT1D1,WkDiamT1D2,WkDiamT1D3,WkDiamT1D4,WkDiamT1D5,WkDiamT1D6,WkDiamT1D7,WkDiamT1D8,WkDiamT1D9, & - WkDiamT2D1,WkDiamT2D2,WkDiamT2D3,WkDiamT2D4,WkDiamT2D5,WkDiamT2D6,WkDiamT2D7,WkDiamT2D8,WkDiamT2D9, & - WkDiamT3D1,WkDiamT3D2,WkDiamT3D3,WkDiamT3D4,WkDiamT3D5,WkDiamT3D6,WkDiamT3D7,WkDiamT3D8,WkDiamT3D9, & - WkDiamT4D1,WkDiamT4D2,WkDiamT4D3,WkDiamT4D4,WkDiamT4D5,WkDiamT4D6,WkDiamT4D7,WkDiamT4D8,WkDiamT4D9, & - WkDiamT5D1,WkDiamT5D2,WkDiamT5D3,WkDiamT5D4,WkDiamT5D5,WkDiamT5D6,WkDiamT5D7,WkDiamT5D8,WkDiamT5D9, & - WkDiamT6D1,WkDiamT6D2,WkDiamT6D3,WkDiamT6D4,WkDiamT6D5,WkDiamT6D6,WkDiamT6D7,WkDiamT6D8,WkDiamT6D9, & - WkDiamT7D1,WkDiamT7D2,WkDiamT7D3,WkDiamT7D4,WkDiamT7D5,WkDiamT7D6,WkDiamT7D7,WkDiamT7D8,WkDiamT7D9, & - WkDiamT8D1,WkDiamT8D2,WkDiamT8D3,WkDiamT8D4,WkDiamT8D5,WkDiamT8D6,WkDiamT8D7,WkDiamT8D8,WkDiamT8D9, & - WkDiamT9D1,WkDiamT9D2,WkDiamT9D3,WkDiamT9D4,WkDiamT9D5,WkDiamT9D6,WkDiamT9D7,WkDiamT9D8,WkDiamT9D9/), (/9,9/) ) - - INTEGER, PARAMETER :: WVAmbX(9) = (/W1VAmbX, W2VAmbX, W3VAmbX, W4VAmbX, W5VAmbX, W6VAmbX, W7VAmbX, W8VAmbX, W9VAmbX/) - INTEGER, PARAMETER :: WVAmbY(9) = (/W1VAmbY, W2VAmbY, W3VAmbY, W4VAmbY, W5VAmbY, W6VAmbY, W7VAmbY, W8VAmbY, W9VAmbY/) - INTEGER, PARAMETER :: WVAmbZ(9) = (/W1VAmbZ, W2VAmbZ, W3VAmbZ, W4VAmbZ, W5VAmbZ, W6VAmbZ, W7VAmbZ, W8VAmbZ, W9VAmbZ/) - - INTEGER, PARAMETER :: WVDisX(9) = (/W1VDisX, W2VDisX, W3VDisX, W4VDisX, W5VDisX, W6VDisX, W7VDisX, W8VDisX, W9VDisX/) - INTEGER, PARAMETER :: WVDisY(9) = (/W1VDisY, W2VDisY, W3VDisY, W4VDisY, W5VDisY, W6VDisY, W7VDisY, W8VDisY, W9VDisY/) - INTEGER, PARAMETER :: WVDisZ(9) = (/W1VDisZ, W2VDisZ, W3VDisZ, W4VDisZ, W5VDisZ, W6VDisZ, W7VDisZ, W8VDisZ, W9VDisZ/) - - INTEGER(IntKi) :: WkDfVxTND(20,9,9) - INTEGER(IntKi) :: WkDfVrTND(20,9,9) - INTEGER(IntKi) :: EddVisTND(20,9,9) - INTEGER(IntKi) :: EddAmbTND(20,9,9) - INTEGER(IntKi) :: EddShrTND(20,9,9) - public:: WkDfVxTND, WkDfVrTND, EddVisTND, EddAmbTND, EddShrTND + IMPLICIT NONE - - - - + TYPE(ProgDesc), PARAMETER :: Farm_Ver = ProgDesc( 'FAST.Farm', '', '' ) !< module date/version information @@ -9938,882 +221,6 @@ SUBROUTINE Farm_PrintSum( farm, WD_InputFileData, ErrStat, ErrMsg ) RETURN END SUBROUTINE Farm_PrintSum - -! These must be set prior to usage in the SetOutParam routine -SUBROUTINE Farm_SetAggregatedChannelOutArrays() -WkDfVxTND(:,:,1) = RESHAPE( & - (/WkDfVxT1N01D1,WkDfVxT1N02D1,WkDfVxT1N03D1,WkDfVxT1N04D1,WkDfVxT1N05D1,WkDfVxT1N06D1,WkDfVxT1N07D1,WkDfVxT1N08D1,WkDfVxT1N09D1,WkDfVxT1N10D1, & - WkDfVxT1N11D1,WkDfVxT1N12D1,WkDfVxT1N13D1,WkDfVxT1N14D1,WkDfVxT1N15D1,WkDfVxT1N16D1,WkDfVxT1N17D1,WkDfVxT1N18D1,WkDfVxT1N19D1,WkDfVxT1N20D1, & - WkDfVxT1N01D2,WkDfVxT1N02D2,WkDfVxT1N03D2,WkDfVxT1N04D2,WkDfVxT1N05D2,WkDfVxT1N06D2,WkDfVxT1N07D2,WkDfVxT1N08D2,WkDfVxT1N09D2,WkDfVxT1N10D2, & - WkDfVxT1N11D2,WkDfVxT1N12D2,WkDfVxT1N13D2,WkDfVxT1N14D2,WkDfVxT1N15D2,WkDfVxT1N16D2,WkDfVxT1N17D2,WkDfVxT1N18D2,WkDfVxT1N19D2,WkDfVxT1N20D2, & - WkDfVxT1N01D3,WkDfVxT1N02D3,WkDfVxT1N03D3,WkDfVxT1N04D3,WkDfVxT1N05D3,WkDfVxT1N06D3,WkDfVxT1N07D3,WkDfVxT1N08D3,WkDfVxT1N09D3,WkDfVxT1N10D3, & - WkDfVxT1N11D3,WkDfVxT1N12D3,WkDfVxT1N13D3,WkDfVxT1N14D3,WkDfVxT1N15D3,WkDfVxT1N16D3,WkDfVxT1N17D3,WkDfVxT1N18D3,WkDfVxT1N19D3,WkDfVxT1N20D3, & - WkDfVxT1N01D4,WkDfVxT1N02D4,WkDfVxT1N03D4,WkDfVxT1N04D4,WkDfVxT1N05D4,WkDfVxT1N06D4,WkDfVxT1N07D4,WkDfVxT1N08D4,WkDfVxT1N09D4,WkDfVxT1N10D4, & - WkDfVxT1N11D4,WkDfVxT1N12D4,WkDfVxT1N13D4,WkDfVxT1N14D4,WkDfVxT1N15D4,WkDfVxT1N16D4,WkDfVxT1N17D4,WkDfVxT1N18D4,WkDfVxT1N19D4,WkDfVxT1N20D4, & - WkDfVxT1N01D5,WkDfVxT1N02D5,WkDfVxT1N03D5,WkDfVxT1N04D5,WkDfVxT1N05D5,WkDfVxT1N06D5,WkDfVxT1N07D5,WkDfVxT1N08D5,WkDfVxT1N09D5,WkDfVxT1N10D5, & - WkDfVxT1N11D5,WkDfVxT1N12D5,WkDfVxT1N13D5,WkDfVxT1N14D5,WkDfVxT1N15D5,WkDfVxT1N16D5,WkDfVxT1N17D5,WkDfVxT1N18D5,WkDfVxT1N19D5,WkDfVxT1N20D5, & - WkDfVxT1N01D6,WkDfVxT1N02D6,WkDfVxT1N03D6,WkDfVxT1N04D6,WkDfVxT1N05D6,WkDfVxT1N06D6,WkDfVxT1N07D6,WkDfVxT1N08D6,WkDfVxT1N09D6,WkDfVxT1N10D6, & - WkDfVxT1N11D6,WkDfVxT1N12D6,WkDfVxT1N13D6,WkDfVxT1N14D6,WkDfVxT1N15D6,WkDfVxT1N16D6,WkDfVxT1N17D6,WkDfVxT1N18D6,WkDfVxT1N19D6,WkDfVxT1N20D6, & - WkDfVxT1N01D7,WkDfVxT1N02D7,WkDfVxT1N03D7,WkDfVxT1N04D7,WkDfVxT1N05D7,WkDfVxT1N06D7,WkDfVxT1N07D7,WkDfVxT1N08D7,WkDfVxT1N09D7,WkDfVxT1N10D7, & - WkDfVxT1N11D7,WkDfVxT1N12D7,WkDfVxT1N13D7,WkDfVxT1N14D7,WkDfVxT1N15D7,WkDfVxT1N16D7,WkDfVxT1N17D7,WkDfVxT1N18D7,WkDfVxT1N19D7,WkDfVxT1N20D7, & - WkDfVxT1N01D8,WkDfVxT1N02D8,WkDfVxT1N03D8,WkDfVxT1N04D8,WkDfVxT1N05D8,WkDfVxT1N06D8,WkDfVxT1N07D8,WkDfVxT1N08D8,WkDfVxT1N09D8,WkDfVxT1N10D8, & - WkDfVxT1N11D8,WkDfVxT1N12D8,WkDfVxT1N13D8,WkDfVxT1N14D8,WkDfVxT1N15D8,WkDfVxT1N16D8,WkDfVxT1N17D8,WkDfVxT1N18D8,WkDfVxT1N19D8,WkDfVxT1N20D8, & - WkDfVxT1N01D9,WkDfVxT1N02D9,WkDfVxT1N03D9,WkDfVxT1N04D9,WkDfVxT1N05D9,WkDfVxT1N06D9,WkDfVxT1N07D9,WkDfVxT1N08D9,WkDfVxT1N09D9,WkDfVxT1N10D9, & - WkDfVxT1N11D9,WkDfVxT1N12D9,WkDfVxT1N13D9,WkDfVxT1N14D9,WkDfVxT1N15D9,WkDfVxT1N16D9,WkDfVxT1N17D9,WkDfVxT1N18D9,WkDfVxT1N19D9,WkDfVxT1N20D9/), (/20,9/) ) - -WkDfVxTND(:,:,2) = RESHAPE( & - (/WkDfVxT2N01D1,WkDfVxT2N02D1,WkDfVxT2N03D1,WkDfVxT2N04D1,WkDfVxT2N05D1,WkDfVxT2N06D1,WkDfVxT2N07D1,WkDfVxT2N08D1,WkDfVxT2N09D1,WkDfVxT2N10D1, & - WkDfVxT2N11D1,WkDfVxT2N12D1,WkDfVxT2N13D1,WkDfVxT2N14D1,WkDfVxT2N15D1,WkDfVxT2N16D1,WkDfVxT2N17D1,WkDfVxT2N18D1,WkDfVxT2N19D1,WkDfVxT2N20D1, & - WkDfVxT2N01D2,WkDfVxT2N02D2,WkDfVxT2N03D2,WkDfVxT2N04D2,WkDfVxT2N05D2,WkDfVxT2N06D2,WkDfVxT2N07D2,WkDfVxT2N08D2,WkDfVxT2N09D2,WkDfVxT2N10D2, & - WkDfVxT2N11D2,WkDfVxT2N12D2,WkDfVxT2N13D2,WkDfVxT2N14D2,WkDfVxT2N15D2,WkDfVxT2N16D2,WkDfVxT2N17D2,WkDfVxT2N18D2,WkDfVxT2N19D2,WkDfVxT2N20D2, & - WkDfVxT2N01D3,WkDfVxT2N02D3,WkDfVxT2N03D3,WkDfVxT2N04D3,WkDfVxT2N05D3,WkDfVxT2N06D3,WkDfVxT2N07D3,WkDfVxT2N08D3,WkDfVxT2N09D3,WkDfVxT2N10D3, & - WkDfVxT2N11D3,WkDfVxT2N12D3,WkDfVxT2N13D3,WkDfVxT2N14D3,WkDfVxT2N15D3,WkDfVxT2N16D3,WkDfVxT2N17D3,WkDfVxT2N18D3,WkDfVxT2N19D3,WkDfVxT2N20D3, & - WkDfVxT2N01D4,WkDfVxT2N02D4,WkDfVxT2N03D4,WkDfVxT2N04D4,WkDfVxT2N05D4,WkDfVxT2N06D4,WkDfVxT2N07D4,WkDfVxT2N08D4,WkDfVxT2N09D4,WkDfVxT2N10D4, & - WkDfVxT2N11D4,WkDfVxT2N12D4,WkDfVxT2N13D4,WkDfVxT2N14D4,WkDfVxT2N15D4,WkDfVxT2N16D4,WkDfVxT2N17D4,WkDfVxT2N18D4,WkDfVxT2N19D4,WkDfVxT2N20D4, & - WkDfVxT2N01D5,WkDfVxT2N02D5,WkDfVxT2N03D5,WkDfVxT2N04D5,WkDfVxT2N05D5,WkDfVxT2N06D5,WkDfVxT2N07D5,WkDfVxT2N08D5,WkDfVxT2N09D5,WkDfVxT2N10D5, & - WkDfVxT2N11D5,WkDfVxT2N12D5,WkDfVxT2N13D5,WkDfVxT2N14D5,WkDfVxT2N15D5,WkDfVxT2N16D5,WkDfVxT2N17D5,WkDfVxT2N18D5,WkDfVxT2N19D5,WkDfVxT2N20D5, & - WkDfVxT2N01D6,WkDfVxT2N02D6,WkDfVxT2N03D6,WkDfVxT2N04D6,WkDfVxT2N05D6,WkDfVxT2N06D6,WkDfVxT2N07D6,WkDfVxT2N08D6,WkDfVxT2N09D6,WkDfVxT2N10D6, & - WkDfVxT2N11D6,WkDfVxT2N12D6,WkDfVxT2N13D6,WkDfVxT2N14D6,WkDfVxT2N15D6,WkDfVxT2N16D6,WkDfVxT2N17D6,WkDfVxT2N18D6,WkDfVxT2N19D6,WkDfVxT2N20D6, & - WkDfVxT2N01D7,WkDfVxT2N02D7,WkDfVxT2N03D7,WkDfVxT2N04D7,WkDfVxT2N05D7,WkDfVxT2N06D7,WkDfVxT2N07D7,WkDfVxT2N08D7,WkDfVxT2N09D7,WkDfVxT2N10D7, & - WkDfVxT2N11D7,WkDfVxT2N12D7,WkDfVxT2N13D7,WkDfVxT2N14D7,WkDfVxT2N15D7,WkDfVxT2N16D7,WkDfVxT2N17D7,WkDfVxT2N18D7,WkDfVxT2N19D7,WkDfVxT2N20D7, & - WkDfVxT2N01D8,WkDfVxT2N02D8,WkDfVxT2N03D8,WkDfVxT2N04D8,WkDfVxT2N05D8,WkDfVxT2N06D8,WkDfVxT2N07D8,WkDfVxT2N08D8,WkDfVxT2N09D8,WkDfVxT2N10D8, & - WkDfVxT2N11D8,WkDfVxT2N12D8,WkDfVxT2N13D8,WkDfVxT2N14D8,WkDfVxT2N15D8,WkDfVxT2N16D8,WkDfVxT2N17D8,WkDfVxT2N18D8,WkDfVxT2N19D8,WkDfVxT2N20D8, & - WkDfVxT2N01D9,WkDfVxT2N02D9,WkDfVxT2N03D9,WkDfVxT2N04D9,WkDfVxT2N05D9,WkDfVxT2N06D9,WkDfVxT2N07D9,WkDfVxT2N08D9,WkDfVxT2N09D9,WkDfVxT2N10D9, & - WkDfVxT2N11D9,WkDfVxT2N12D9,WkDfVxT2N13D9,WkDfVxT2N14D9,WkDfVxT2N15D9,WkDfVxT2N16D9,WkDfVxT2N17D9,WkDfVxT2N18D9,WkDfVxT2N19D9,WkDfVxT2N20D9/), (/20,9/) ) -WkDfVxTND(:,:,3) = RESHAPE( & - (/WkDfVxT3N01D1,WkDfVxT3N02D1,WkDfVxT3N03D1,WkDfVxT3N04D1,WkDfVxT3N05D1,WkDfVxT3N06D1,WkDfVxT3N07D1,WkDfVxT3N08D1,WkDfVxT3N09D1,WkDfVxT3N10D1, & - WkDfVxT3N11D1,WkDfVxT3N12D1,WkDfVxT3N13D1,WkDfVxT3N14D1,WkDfVxT3N15D1,WkDfVxT3N16D1,WkDfVxT3N17D1,WkDfVxT3N18D1,WkDfVxT3N19D1,WkDfVxT3N20D1, & - WkDfVxT3N01D2,WkDfVxT3N02D2,WkDfVxT3N03D2,WkDfVxT3N04D2,WkDfVxT3N05D2,WkDfVxT3N06D2,WkDfVxT3N07D2,WkDfVxT3N08D2,WkDfVxT3N09D2,WkDfVxT3N10D2, & - WkDfVxT3N11D2,WkDfVxT3N12D2,WkDfVxT3N13D2,WkDfVxT3N14D2,WkDfVxT3N15D2,WkDfVxT3N16D2,WkDfVxT3N17D2,WkDfVxT3N18D2,WkDfVxT3N19D2,WkDfVxT3N20D2, & - WkDfVxT3N01D3,WkDfVxT3N02D3,WkDfVxT3N03D3,WkDfVxT3N04D3,WkDfVxT3N05D3,WkDfVxT3N06D3,WkDfVxT3N07D3,WkDfVxT3N08D3,WkDfVxT3N09D3,WkDfVxT3N10D3, & - WkDfVxT3N11D3,WkDfVxT3N12D3,WkDfVxT3N13D3,WkDfVxT3N14D3,WkDfVxT3N15D3,WkDfVxT3N16D3,WkDfVxT3N17D3,WkDfVxT3N18D3,WkDfVxT3N19D3,WkDfVxT3N20D3, & - WkDfVxT3N01D4,WkDfVxT3N02D4,WkDfVxT3N03D4,WkDfVxT3N04D4,WkDfVxT3N05D4,WkDfVxT3N06D4,WkDfVxT3N07D4,WkDfVxT3N08D4,WkDfVxT3N09D4,WkDfVxT3N10D4, & - WkDfVxT3N11D4,WkDfVxT3N12D4,WkDfVxT3N13D4,WkDfVxT3N14D4,WkDfVxT3N15D4,WkDfVxT3N16D4,WkDfVxT3N17D4,WkDfVxT3N18D4,WkDfVxT3N19D4,WkDfVxT3N20D4, & - WkDfVxT3N01D5,WkDfVxT3N02D5,WkDfVxT3N03D5,WkDfVxT3N04D5,WkDfVxT3N05D5,WkDfVxT3N06D5,WkDfVxT3N07D5,WkDfVxT3N08D5,WkDfVxT3N09D5,WkDfVxT3N10D5, & - WkDfVxT3N11D5,WkDfVxT3N12D5,WkDfVxT3N13D5,WkDfVxT3N14D5,WkDfVxT3N15D5,WkDfVxT3N16D5,WkDfVxT3N17D5,WkDfVxT3N18D5,WkDfVxT3N19D5,WkDfVxT3N20D5, & - WkDfVxT3N01D6,WkDfVxT3N02D6,WkDfVxT3N03D6,WkDfVxT3N04D6,WkDfVxT3N05D6,WkDfVxT3N06D6,WkDfVxT3N07D6,WkDfVxT3N08D6,WkDfVxT3N09D6,WkDfVxT3N10D6, & - WkDfVxT3N11D6,WkDfVxT3N12D6,WkDfVxT3N13D6,WkDfVxT3N14D6,WkDfVxT3N15D6,WkDfVxT3N16D6,WkDfVxT3N17D6,WkDfVxT3N18D6,WkDfVxT3N19D6,WkDfVxT3N20D6, & - WkDfVxT3N01D7,WkDfVxT3N02D7,WkDfVxT3N03D7,WkDfVxT3N04D7,WkDfVxT3N05D7,WkDfVxT3N06D7,WkDfVxT3N07D7,WkDfVxT3N08D7,WkDfVxT3N09D7,WkDfVxT3N10D7, & - WkDfVxT3N11D7,WkDfVxT3N12D7,WkDfVxT3N13D7,WkDfVxT3N14D7,WkDfVxT3N15D7,WkDfVxT3N16D7,WkDfVxT3N17D7,WkDfVxT3N18D7,WkDfVxT3N19D7,WkDfVxT3N20D7, & - WkDfVxT3N01D8,WkDfVxT3N02D8,WkDfVxT3N03D8,WkDfVxT3N04D8,WkDfVxT3N05D8,WkDfVxT3N06D8,WkDfVxT3N07D8,WkDfVxT3N08D8,WkDfVxT3N09D8,WkDfVxT3N10D8, & - WkDfVxT3N11D8,WkDfVxT3N12D8,WkDfVxT3N13D8,WkDfVxT3N14D8,WkDfVxT3N15D8,WkDfVxT3N16D8,WkDfVxT3N17D8,WkDfVxT3N18D8,WkDfVxT3N19D8,WkDfVxT3N20D8, & - WkDfVxT3N01D9,WkDfVxT3N02D9,WkDfVxT3N03D9,WkDfVxT3N04D9,WkDfVxT3N05D9,WkDfVxT3N06D9,WkDfVxT3N07D9,WkDfVxT3N08D9,WkDfVxT3N09D9,WkDfVxT3N10D9, & - WkDfVxT3N11D9,WkDfVxT3N12D9,WkDfVxT3N13D9,WkDfVxT3N14D9,WkDfVxT3N15D9,WkDfVxT3N16D9,WkDfVxT3N17D9,WkDfVxT3N18D9,WkDfVxT3N19D9,WkDfVxT3N20D9/), (/20,9/) ) -WkDfVxTND(:,:,4) = RESHAPE( & - (/WkDfVxT4N01D1,WkDfVxT4N02D1,WkDfVxT4N03D1,WkDfVxT4N04D1,WkDfVxT4N05D1,WkDfVxT4N06D1,WkDfVxT4N07D1,WkDfVxT4N08D1,WkDfVxT4N09D1,WkDfVxT4N10D1, & - WkDfVxT4N11D1,WkDfVxT4N12D1,WkDfVxT4N13D1,WkDfVxT4N14D1,WkDfVxT4N15D1,WkDfVxT4N16D1,WkDfVxT4N17D1,WkDfVxT4N18D1,WkDfVxT4N19D1,WkDfVxT4N20D1, & - WkDfVxT4N01D2,WkDfVxT4N02D2,WkDfVxT4N03D2,WkDfVxT4N04D2,WkDfVxT4N05D2,WkDfVxT4N06D2,WkDfVxT4N07D2,WkDfVxT4N08D2,WkDfVxT4N09D2,WkDfVxT4N10D2, & - WkDfVxT4N11D2,WkDfVxT4N12D2,WkDfVxT4N13D2,WkDfVxT4N14D2,WkDfVxT4N15D2,WkDfVxT4N16D2,WkDfVxT4N17D2,WkDfVxT4N18D2,WkDfVxT4N19D2,WkDfVxT4N20D2, & - WkDfVxT4N01D3,WkDfVxT4N02D3,WkDfVxT4N03D3,WkDfVxT4N04D3,WkDfVxT4N05D3,WkDfVxT4N06D3,WkDfVxT4N07D3,WkDfVxT4N08D3,WkDfVxT4N09D3,WkDfVxT4N10D3, & - WkDfVxT4N11D3,WkDfVxT4N12D3,WkDfVxT4N13D3,WkDfVxT4N14D3,WkDfVxT4N15D3,WkDfVxT4N16D3,WkDfVxT4N17D3,WkDfVxT4N18D3,WkDfVxT4N19D3,WkDfVxT4N20D3, & - WkDfVxT4N01D4,WkDfVxT4N02D4,WkDfVxT4N03D4,WkDfVxT4N04D4,WkDfVxT4N05D4,WkDfVxT4N06D4,WkDfVxT4N07D4,WkDfVxT4N08D4,WkDfVxT4N09D4,WkDfVxT4N10D4, & - WkDfVxT4N11D4,WkDfVxT4N12D4,WkDfVxT4N13D4,WkDfVxT4N14D4,WkDfVxT4N15D4,WkDfVxT4N16D4,WkDfVxT4N17D4,WkDfVxT4N18D4,WkDfVxT4N19D4,WkDfVxT4N20D4, & - WkDfVxT4N01D5,WkDfVxT4N02D5,WkDfVxT4N03D5,WkDfVxT4N04D5,WkDfVxT4N05D5,WkDfVxT4N06D5,WkDfVxT4N07D5,WkDfVxT4N08D5,WkDfVxT4N09D5,WkDfVxT4N10D5, & - WkDfVxT4N11D5,WkDfVxT4N12D5,WkDfVxT4N13D5,WkDfVxT4N14D5,WkDfVxT4N15D5,WkDfVxT4N16D5,WkDfVxT4N17D5,WkDfVxT4N18D5,WkDfVxT4N19D5,WkDfVxT4N20D5, & - WkDfVxT4N01D6,WkDfVxT4N02D6,WkDfVxT4N03D6,WkDfVxT4N04D6,WkDfVxT4N05D6,WkDfVxT4N06D6,WkDfVxT4N07D6,WkDfVxT4N08D6,WkDfVxT4N09D6,WkDfVxT4N10D6, & - WkDfVxT4N11D6,WkDfVxT4N12D6,WkDfVxT4N13D6,WkDfVxT4N14D6,WkDfVxT4N15D6,WkDfVxT4N16D6,WkDfVxT4N17D6,WkDfVxT4N18D6,WkDfVxT4N19D6,WkDfVxT4N20D6, & - WkDfVxT4N01D7,WkDfVxT4N02D7,WkDfVxT4N03D7,WkDfVxT4N04D7,WkDfVxT4N05D7,WkDfVxT4N06D7,WkDfVxT4N07D7,WkDfVxT4N08D7,WkDfVxT4N09D7,WkDfVxT4N10D7, & - WkDfVxT4N11D7,WkDfVxT4N12D7,WkDfVxT4N13D7,WkDfVxT4N14D7,WkDfVxT4N15D7,WkDfVxT4N16D7,WkDfVxT4N17D7,WkDfVxT4N18D7,WkDfVxT4N19D7,WkDfVxT4N20D7, & - WkDfVxT4N01D8,WkDfVxT4N02D8,WkDfVxT4N03D8,WkDfVxT4N04D8,WkDfVxT4N05D8,WkDfVxT4N06D8,WkDfVxT4N07D8,WkDfVxT4N08D8,WkDfVxT4N09D8,WkDfVxT4N10D8, & - WkDfVxT4N11D8,WkDfVxT4N12D8,WkDfVxT4N13D8,WkDfVxT4N14D8,WkDfVxT4N15D8,WkDfVxT4N16D8,WkDfVxT4N17D8,WkDfVxT4N18D8,WkDfVxT4N19D8,WkDfVxT4N20D8, & - WkDfVxT4N01D9,WkDfVxT4N02D9,WkDfVxT4N03D9,WkDfVxT4N04D9,WkDfVxT4N05D9,WkDfVxT4N06D9,WkDfVxT4N07D9,WkDfVxT4N08D9,WkDfVxT4N09D9,WkDfVxT4N10D9, & - WkDfVxT4N11D9,WkDfVxT4N12D9,WkDfVxT4N13D9,WkDfVxT4N14D9,WkDfVxT4N15D9,WkDfVxT4N16D9,WkDfVxT4N17D9,WkDfVxT4N18D9,WkDfVxT4N19D9,WkDfVxT4N20D9/), (/20,9/) ) - -WkDfVxTND(:,:,5) = RESHAPE( & - (/WkDfVxT5N01D1,WkDfVxT5N02D1,WkDfVxT5N03D1,WkDfVxT5N04D1,WkDfVxT5N05D1,WkDfVxT5N06D1,WkDfVxT5N07D1,WkDfVxT5N08D1,WkDfVxT5N09D1,WkDfVxT5N10D1, & - WkDfVxT5N11D1,WkDfVxT5N12D1,WkDfVxT5N13D1,WkDfVxT5N14D1,WkDfVxT5N15D1,WkDfVxT5N16D1,WkDfVxT5N17D1,WkDfVxT5N18D1,WkDfVxT5N19D1,WkDfVxT5N20D1, & - WkDfVxT5N01D2,WkDfVxT5N02D2,WkDfVxT5N03D2,WkDfVxT5N04D2,WkDfVxT5N05D2,WkDfVxT5N06D2,WkDfVxT5N07D2,WkDfVxT5N08D2,WkDfVxT5N09D2,WkDfVxT5N10D2, & - WkDfVxT5N11D2,WkDfVxT5N12D2,WkDfVxT5N13D2,WkDfVxT5N14D2,WkDfVxT5N15D2,WkDfVxT5N16D2,WkDfVxT5N17D2,WkDfVxT5N18D2,WkDfVxT5N19D2,WkDfVxT5N20D2, & - WkDfVxT5N01D3,WkDfVxT5N02D3,WkDfVxT5N03D3,WkDfVxT5N04D3,WkDfVxT5N05D3,WkDfVxT5N06D3,WkDfVxT5N07D3,WkDfVxT5N08D3,WkDfVxT5N09D3,WkDfVxT5N10D3, & - WkDfVxT5N11D3,WkDfVxT5N12D3,WkDfVxT5N13D3,WkDfVxT5N14D3,WkDfVxT5N15D3,WkDfVxT5N16D3,WkDfVxT5N17D3,WkDfVxT5N18D3,WkDfVxT5N19D3,WkDfVxT5N20D3, & - WkDfVxT5N01D4,WkDfVxT5N02D4,WkDfVxT5N03D4,WkDfVxT5N04D4,WkDfVxT5N05D4,WkDfVxT5N06D4,WkDfVxT5N07D4,WkDfVxT5N08D4,WkDfVxT5N09D4,WkDfVxT5N10D4, & - WkDfVxT5N11D4,WkDfVxT5N12D4,WkDfVxT5N13D4,WkDfVxT5N14D4,WkDfVxT5N15D4,WkDfVxT5N16D4,WkDfVxT5N17D4,WkDfVxT5N18D4,WkDfVxT5N19D4,WkDfVxT5N20D4, & - WkDfVxT5N01D5,WkDfVxT5N02D5,WkDfVxT5N03D5,WkDfVxT5N04D5,WkDfVxT5N05D5,WkDfVxT5N06D5,WkDfVxT5N07D5,WkDfVxT5N08D5,WkDfVxT5N09D5,WkDfVxT5N10D5, & - WkDfVxT5N11D5,WkDfVxT5N12D5,WkDfVxT5N13D5,WkDfVxT5N14D5,WkDfVxT5N15D5,WkDfVxT5N16D5,WkDfVxT5N17D5,WkDfVxT5N18D5,WkDfVxT5N19D5,WkDfVxT5N20D5, & - WkDfVxT5N01D6,WkDfVxT5N02D6,WkDfVxT5N03D6,WkDfVxT5N04D6,WkDfVxT5N05D6,WkDfVxT5N06D6,WkDfVxT5N07D6,WkDfVxT5N08D6,WkDfVxT5N09D6,WkDfVxT5N10D6, & - WkDfVxT5N11D6,WkDfVxT5N12D6,WkDfVxT5N13D6,WkDfVxT5N14D6,WkDfVxT5N15D6,WkDfVxT5N16D6,WkDfVxT5N17D6,WkDfVxT5N18D6,WkDfVxT5N19D6,WkDfVxT5N20D6, & - WkDfVxT5N01D7,WkDfVxT5N02D7,WkDfVxT5N03D7,WkDfVxT5N04D7,WkDfVxT5N05D7,WkDfVxT5N06D7,WkDfVxT5N07D7,WkDfVxT5N08D7,WkDfVxT5N09D7,WkDfVxT5N10D7, & - WkDfVxT5N11D7,WkDfVxT5N12D7,WkDfVxT5N13D7,WkDfVxT5N14D7,WkDfVxT5N15D7,WkDfVxT5N16D7,WkDfVxT5N17D7,WkDfVxT5N18D7,WkDfVxT5N19D7,WkDfVxT5N20D7, & - WkDfVxT5N01D8,WkDfVxT5N02D8,WkDfVxT5N03D8,WkDfVxT5N04D8,WkDfVxT5N05D8,WkDfVxT5N06D8,WkDfVxT5N07D8,WkDfVxT5N08D8,WkDfVxT5N09D8,WkDfVxT5N10D8, & - WkDfVxT5N11D8,WkDfVxT5N12D8,WkDfVxT5N13D8,WkDfVxT5N14D8,WkDfVxT5N15D8,WkDfVxT5N16D8,WkDfVxT5N17D8,WkDfVxT5N18D8,WkDfVxT5N19D8,WkDfVxT5N20D8, & - WkDfVxT5N01D9,WkDfVxT5N02D9,WkDfVxT5N03D9,WkDfVxT5N04D9,WkDfVxT5N05D9,WkDfVxT5N06D9,WkDfVxT5N07D9,WkDfVxT5N08D9,WkDfVxT5N09D9,WkDfVxT5N10D9, & - WkDfVxT5N11D9,WkDfVxT5N12D9,WkDfVxT5N13D9,WkDfVxT5N14D9,WkDfVxT5N15D9,WkDfVxT5N16D9,WkDfVxT5N17D9,WkDfVxT5N18D9,WkDfVxT5N19D9,WkDfVxT5N20D9/), (/20,9/) ) -WkDfVxTND(:,:,6) = RESHAPE( & - (/WkDfVxT6N01D1,WkDfVxT6N02D1,WkDfVxT6N03D1,WkDfVxT6N04D1,WkDfVxT6N05D1,WkDfVxT6N06D1,WkDfVxT6N07D1,WkDfVxT6N08D1,WkDfVxT6N09D1,WkDfVxT6N10D1, & - WkDfVxT6N11D1,WkDfVxT6N12D1,WkDfVxT6N13D1,WkDfVxT6N14D1,WkDfVxT6N15D1,WkDfVxT6N16D1,WkDfVxT6N17D1,WkDfVxT6N18D1,WkDfVxT6N19D1,WkDfVxT6N20D1, & - WkDfVxT6N01D2,WkDfVxT6N02D2,WkDfVxT6N03D2,WkDfVxT6N04D2,WkDfVxT6N05D2,WkDfVxT6N06D2,WkDfVxT6N07D2,WkDfVxT6N08D2,WkDfVxT6N09D2,WkDfVxT6N10D2, & - WkDfVxT6N11D2,WkDfVxT6N12D2,WkDfVxT6N13D2,WkDfVxT6N14D2,WkDfVxT6N15D2,WkDfVxT6N16D2,WkDfVxT6N17D2,WkDfVxT6N18D2,WkDfVxT6N19D2,WkDfVxT6N20D2, & - WkDfVxT6N01D3,WkDfVxT6N02D3,WkDfVxT6N03D3,WkDfVxT6N04D3,WkDfVxT6N05D3,WkDfVxT6N06D3,WkDfVxT6N07D3,WkDfVxT6N08D3,WkDfVxT6N09D3,WkDfVxT6N10D3, & - WkDfVxT6N11D3,WkDfVxT6N12D3,WkDfVxT6N13D3,WkDfVxT6N14D3,WkDfVxT6N15D3,WkDfVxT6N16D3,WkDfVxT6N17D3,WkDfVxT6N18D3,WkDfVxT6N19D3,WkDfVxT6N20D3, & - WkDfVxT6N01D4,WkDfVxT6N02D4,WkDfVxT6N03D4,WkDfVxT6N04D4,WkDfVxT6N05D4,WkDfVxT6N06D4,WkDfVxT6N07D4,WkDfVxT6N08D4,WkDfVxT6N09D4,WkDfVxT6N10D4, & - WkDfVxT6N11D4,WkDfVxT6N12D4,WkDfVxT6N13D4,WkDfVxT6N14D4,WkDfVxT6N15D4,WkDfVxT6N16D4,WkDfVxT6N17D4,WkDfVxT6N18D4,WkDfVxT6N19D4,WkDfVxT6N20D4, & - WkDfVxT6N01D5,WkDfVxT6N02D5,WkDfVxT6N03D5,WkDfVxT6N04D5,WkDfVxT6N05D5,WkDfVxT6N06D5,WkDfVxT6N07D5,WkDfVxT6N08D5,WkDfVxT6N09D5,WkDfVxT6N10D5, & - WkDfVxT6N11D5,WkDfVxT6N12D5,WkDfVxT6N13D5,WkDfVxT6N14D5,WkDfVxT6N15D5,WkDfVxT6N16D5,WkDfVxT6N17D5,WkDfVxT6N18D5,WkDfVxT6N19D5,WkDfVxT6N20D5, & - WkDfVxT6N01D6,WkDfVxT6N02D6,WkDfVxT6N03D6,WkDfVxT6N04D6,WkDfVxT6N05D6,WkDfVxT6N06D6,WkDfVxT6N07D6,WkDfVxT6N08D6,WkDfVxT6N09D6,WkDfVxT6N10D6, & - WkDfVxT6N11D6,WkDfVxT6N12D6,WkDfVxT6N13D6,WkDfVxT6N14D6,WkDfVxT6N15D6,WkDfVxT6N16D6,WkDfVxT6N17D6,WkDfVxT6N18D6,WkDfVxT6N19D6,WkDfVxT6N20D6, & - WkDfVxT6N01D7,WkDfVxT6N02D7,WkDfVxT6N03D7,WkDfVxT6N04D7,WkDfVxT6N05D7,WkDfVxT6N06D7,WkDfVxT6N07D7,WkDfVxT6N08D7,WkDfVxT6N09D7,WkDfVxT6N10D7, & - WkDfVxT6N11D7,WkDfVxT6N12D7,WkDfVxT6N13D7,WkDfVxT6N14D7,WkDfVxT6N15D7,WkDfVxT6N16D7,WkDfVxT6N17D7,WkDfVxT6N18D7,WkDfVxT6N19D7,WkDfVxT6N20D7, & - WkDfVxT6N01D8,WkDfVxT6N02D8,WkDfVxT6N03D8,WkDfVxT6N04D8,WkDfVxT6N05D8,WkDfVxT6N06D8,WkDfVxT6N07D8,WkDfVxT6N08D8,WkDfVxT6N09D8,WkDfVxT6N10D8, & - WkDfVxT6N11D8,WkDfVxT6N12D8,WkDfVxT6N13D8,WkDfVxT6N14D8,WkDfVxT6N15D8,WkDfVxT6N16D8,WkDfVxT6N17D8,WkDfVxT6N18D8,WkDfVxT6N19D8,WkDfVxT6N20D8, & - WkDfVxT6N01D9,WkDfVxT6N02D9,WkDfVxT6N03D9,WkDfVxT6N04D9,WkDfVxT6N05D9,WkDfVxT6N06D9,WkDfVxT6N07D9,WkDfVxT6N08D9,WkDfVxT6N09D9,WkDfVxT6N10D9, & - WkDfVxT6N11D9,WkDfVxT6N12D9,WkDfVxT6N13D9,WkDfVxT6N14D9,WkDfVxT6N15D9,WkDfVxT6N16D9,WkDfVxT6N17D9,WkDfVxT6N18D9,WkDfVxT6N19D9,WkDfVxT6N20D9/), (/20,9/) ) -WkDfVxTND(:,:,7) = RESHAPE( & - (/WkDfVxT7N01D1,WkDfVxT7N02D1,WkDfVxT7N03D1,WkDfVxT7N04D1,WkDfVxT7N05D1,WkDfVxT7N06D1,WkDfVxT7N07D1,WkDfVxT7N08D1,WkDfVxT7N09D1,WkDfVxT7N10D1, & - WkDfVxT7N11D1,WkDfVxT7N12D1,WkDfVxT7N13D1,WkDfVxT7N14D1,WkDfVxT7N15D1,WkDfVxT7N16D1,WkDfVxT7N17D1,WkDfVxT7N18D1,WkDfVxT7N19D1,WkDfVxT7N20D1, & - WkDfVxT7N01D2,WkDfVxT7N02D2,WkDfVxT7N03D2,WkDfVxT7N04D2,WkDfVxT7N05D2,WkDfVxT7N06D2,WkDfVxT7N07D2,WkDfVxT7N08D2,WkDfVxT7N09D2,WkDfVxT7N10D2, & - WkDfVxT7N11D2,WkDfVxT7N12D2,WkDfVxT7N13D2,WkDfVxT7N14D2,WkDfVxT7N15D2,WkDfVxT7N16D2,WkDfVxT7N17D2,WkDfVxT7N18D2,WkDfVxT7N19D2,WkDfVxT7N20D2, & - WkDfVxT7N01D3,WkDfVxT7N02D3,WkDfVxT7N03D3,WkDfVxT7N04D3,WkDfVxT7N05D3,WkDfVxT7N06D3,WkDfVxT7N07D3,WkDfVxT7N08D3,WkDfVxT7N09D3,WkDfVxT7N10D3, & - WkDfVxT7N11D3,WkDfVxT7N12D3,WkDfVxT7N13D3,WkDfVxT7N14D3,WkDfVxT7N15D3,WkDfVxT7N16D3,WkDfVxT7N17D3,WkDfVxT7N18D3,WkDfVxT7N19D3,WkDfVxT7N20D3, & - WkDfVxT7N01D4,WkDfVxT7N02D4,WkDfVxT7N03D4,WkDfVxT7N04D4,WkDfVxT7N05D4,WkDfVxT7N06D4,WkDfVxT7N07D4,WkDfVxT7N08D4,WkDfVxT7N09D4,WkDfVxT7N10D4, & - WkDfVxT7N11D4,WkDfVxT7N12D4,WkDfVxT7N13D4,WkDfVxT7N14D4,WkDfVxT7N15D4,WkDfVxT7N16D4,WkDfVxT7N17D4,WkDfVxT7N18D4,WkDfVxT7N19D4,WkDfVxT7N20D4, & - WkDfVxT7N01D5,WkDfVxT7N02D5,WkDfVxT7N03D5,WkDfVxT7N04D5,WkDfVxT7N05D5,WkDfVxT7N06D5,WkDfVxT7N07D5,WkDfVxT7N08D5,WkDfVxT7N09D5,WkDfVxT7N10D5, & - WkDfVxT7N11D5,WkDfVxT7N12D5,WkDfVxT7N13D5,WkDfVxT7N14D5,WkDfVxT7N15D5,WkDfVxT7N16D5,WkDfVxT7N17D5,WkDfVxT7N18D5,WkDfVxT7N19D5,WkDfVxT7N20D5, & - WkDfVxT7N01D6,WkDfVxT7N02D6,WkDfVxT7N03D6,WkDfVxT7N04D6,WkDfVxT7N05D6,WkDfVxT7N06D6,WkDfVxT7N07D6,WkDfVxT7N08D6,WkDfVxT7N09D6,WkDfVxT7N10D6, & - WkDfVxT7N11D6,WkDfVxT7N12D6,WkDfVxT7N13D6,WkDfVxT7N14D6,WkDfVxT7N15D6,WkDfVxT7N16D6,WkDfVxT7N17D6,WkDfVxT7N18D6,WkDfVxT7N19D6,WkDfVxT7N20D6, & - WkDfVxT7N01D7,WkDfVxT7N02D7,WkDfVxT7N03D7,WkDfVxT7N04D7,WkDfVxT7N05D7,WkDfVxT7N06D7,WkDfVxT7N07D7,WkDfVxT7N08D7,WkDfVxT7N09D7,WkDfVxT7N10D7, & - WkDfVxT7N11D7,WkDfVxT7N12D7,WkDfVxT7N13D7,WkDfVxT7N14D7,WkDfVxT7N15D7,WkDfVxT7N16D7,WkDfVxT7N17D7,WkDfVxT7N18D7,WkDfVxT7N19D7,WkDfVxT7N20D7, & - WkDfVxT7N01D8,WkDfVxT7N02D8,WkDfVxT7N03D8,WkDfVxT7N04D8,WkDfVxT7N05D8,WkDfVxT7N06D8,WkDfVxT7N07D8,WkDfVxT7N08D8,WkDfVxT7N09D8,WkDfVxT7N10D8, & - WkDfVxT7N11D8,WkDfVxT7N12D8,WkDfVxT7N13D8,WkDfVxT7N14D8,WkDfVxT7N15D8,WkDfVxT7N16D8,WkDfVxT7N17D8,WkDfVxT7N18D8,WkDfVxT7N19D8,WkDfVxT7N20D8, & - WkDfVxT7N01D9,WkDfVxT7N02D9,WkDfVxT7N03D9,WkDfVxT7N04D9,WkDfVxT7N05D9,WkDfVxT7N06D9,WkDfVxT7N07D9,WkDfVxT7N08D9,WkDfVxT7N09D9,WkDfVxT7N10D9, & - WkDfVxT7N11D9,WkDfVxT7N12D9,WkDfVxT7N13D9,WkDfVxT7N14D9,WkDfVxT7N15D9,WkDfVxT7N16D9,WkDfVxT7N17D9,WkDfVxT7N18D9,WkDfVxT7N19D9,WkDfVxT7N20D9/), (/20,9/) ) -WkDfVxTND(:,:,8) = RESHAPE( & - (/WkDfVxT8N01D1,WkDfVxT8N02D1,WkDfVxT8N03D1,WkDfVxT8N04D1,WkDfVxT8N05D1,WkDfVxT8N06D1,WkDfVxT8N07D1,WkDfVxT8N08D1,WkDfVxT8N09D1,WkDfVxT8N10D1, & - WkDfVxT8N11D1,WkDfVxT8N12D1,WkDfVxT8N13D1,WkDfVxT8N14D1,WkDfVxT8N15D1,WkDfVxT8N16D1,WkDfVxT8N17D1,WkDfVxT8N18D1,WkDfVxT8N19D1,WkDfVxT8N20D1, & - WkDfVxT8N01D2,WkDfVxT8N02D2,WkDfVxT8N03D2,WkDfVxT8N04D2,WkDfVxT8N05D2,WkDfVxT8N06D2,WkDfVxT8N07D2,WkDfVxT8N08D2,WkDfVxT8N09D2,WkDfVxT8N10D2, & - WkDfVxT8N11D2,WkDfVxT8N12D2,WkDfVxT8N13D2,WkDfVxT8N14D2,WkDfVxT8N15D2,WkDfVxT8N16D2,WkDfVxT8N17D2,WkDfVxT8N18D2,WkDfVxT8N19D2,WkDfVxT8N20D2, & - WkDfVxT8N01D3,WkDfVxT8N02D3,WkDfVxT8N03D3,WkDfVxT8N04D3,WkDfVxT8N05D3,WkDfVxT8N06D3,WkDfVxT8N07D3,WkDfVxT8N08D3,WkDfVxT8N09D3,WkDfVxT8N10D3, & - WkDfVxT8N11D3,WkDfVxT8N12D3,WkDfVxT8N13D3,WkDfVxT8N14D3,WkDfVxT8N15D3,WkDfVxT8N16D3,WkDfVxT8N17D3,WkDfVxT8N18D3,WkDfVxT8N19D3,WkDfVxT8N20D3, & - WkDfVxT8N01D4,WkDfVxT8N02D4,WkDfVxT8N03D4,WkDfVxT8N04D4,WkDfVxT8N05D4,WkDfVxT8N06D4,WkDfVxT8N07D4,WkDfVxT8N08D4,WkDfVxT8N09D4,WkDfVxT8N10D4, & - WkDfVxT8N11D4,WkDfVxT8N12D4,WkDfVxT8N13D4,WkDfVxT8N14D4,WkDfVxT8N15D4,WkDfVxT8N16D4,WkDfVxT8N17D4,WkDfVxT8N18D4,WkDfVxT8N19D4,WkDfVxT8N20D4, & - WkDfVxT8N01D5,WkDfVxT8N02D5,WkDfVxT8N03D5,WkDfVxT8N04D5,WkDfVxT8N05D5,WkDfVxT8N06D5,WkDfVxT8N07D5,WkDfVxT8N08D5,WkDfVxT8N09D5,WkDfVxT8N10D5, & - WkDfVxT8N11D5,WkDfVxT8N12D5,WkDfVxT8N13D5,WkDfVxT8N14D5,WkDfVxT8N15D5,WkDfVxT8N16D5,WkDfVxT8N17D5,WkDfVxT8N18D5,WkDfVxT8N19D5,WkDfVxT8N20D5, & - WkDfVxT8N01D6,WkDfVxT8N02D6,WkDfVxT8N03D6,WkDfVxT8N04D6,WkDfVxT8N05D6,WkDfVxT8N06D6,WkDfVxT8N07D6,WkDfVxT8N08D6,WkDfVxT8N09D6,WkDfVxT8N10D6, & - WkDfVxT8N11D6,WkDfVxT8N12D6,WkDfVxT8N13D6,WkDfVxT8N14D6,WkDfVxT8N15D6,WkDfVxT8N16D6,WkDfVxT8N17D6,WkDfVxT8N18D6,WkDfVxT8N19D6,WkDfVxT8N20D6, & - WkDfVxT8N01D7,WkDfVxT8N02D7,WkDfVxT8N03D7,WkDfVxT8N04D7,WkDfVxT8N05D7,WkDfVxT8N06D7,WkDfVxT8N07D7,WkDfVxT8N08D7,WkDfVxT8N09D7,WkDfVxT8N10D7, & - WkDfVxT8N11D7,WkDfVxT8N12D7,WkDfVxT8N13D7,WkDfVxT8N14D7,WkDfVxT8N15D7,WkDfVxT8N16D7,WkDfVxT8N17D7,WkDfVxT8N18D7,WkDfVxT8N19D7,WkDfVxT8N20D7, & - WkDfVxT8N01D8,WkDfVxT8N02D8,WkDfVxT8N03D8,WkDfVxT8N04D8,WkDfVxT8N05D8,WkDfVxT8N06D8,WkDfVxT8N07D8,WkDfVxT8N08D8,WkDfVxT8N09D8,WkDfVxT8N10D8, & - WkDfVxT8N11D8,WkDfVxT8N12D8,WkDfVxT8N13D8,WkDfVxT8N14D8,WkDfVxT8N15D8,WkDfVxT8N16D8,WkDfVxT8N17D8,WkDfVxT8N18D8,WkDfVxT8N19D8,WkDfVxT8N20D8, & - WkDfVxT8N01D9,WkDfVxT8N02D9,WkDfVxT8N03D9,WkDfVxT8N04D9,WkDfVxT8N05D9,WkDfVxT8N06D9,WkDfVxT8N07D9,WkDfVxT8N08D9,WkDfVxT8N09D9,WkDfVxT8N10D9, & - WkDfVxT8N11D9,WkDfVxT8N12D9,WkDfVxT8N13D9,WkDfVxT8N14D9,WkDfVxT8N15D9,WkDfVxT8N16D9,WkDfVxT8N17D9,WkDfVxT8N18D9,WkDfVxT8N19D9,WkDfVxT8N20D9/), (/20,9/) ) - -WkDfVxTND(:,:,9) = RESHAPE( & - (/WkDfVxT9N01D1,WkDfVxT9N02D1,WkDfVxT9N03D1,WkDfVxT9N04D1,WkDfVxT9N05D1,WkDfVxT9N06D1,WkDfVxT9N07D1,WkDfVxT9N08D1,WkDfVxT9N09D1,WkDfVxT9N10D1, & - WkDfVxT9N11D1,WkDfVxT9N12D1,WkDfVxT9N13D1,WkDfVxT9N14D1,WkDfVxT9N15D1,WkDfVxT9N16D1,WkDfVxT9N17D1,WkDfVxT9N18D1,WkDfVxT9N19D1,WkDfVxT9N20D1, & - WkDfVxT9N01D2,WkDfVxT9N02D2,WkDfVxT9N03D2,WkDfVxT9N04D2,WkDfVxT9N05D2,WkDfVxT9N06D2,WkDfVxT9N07D2,WkDfVxT9N08D2,WkDfVxT9N09D2,WkDfVxT9N10D2, & - WkDfVxT9N11D2,WkDfVxT9N12D2,WkDfVxT9N13D2,WkDfVxT9N14D2,WkDfVxT9N15D2,WkDfVxT9N16D2,WkDfVxT9N17D2,WkDfVxT9N18D2,WkDfVxT9N19D2,WkDfVxT9N20D2, & - WkDfVxT9N01D3,WkDfVxT9N02D3,WkDfVxT9N03D3,WkDfVxT9N04D3,WkDfVxT9N05D3,WkDfVxT9N06D3,WkDfVxT9N07D3,WkDfVxT9N08D3,WkDfVxT9N09D3,WkDfVxT9N10D3, & - WkDfVxT9N11D3,WkDfVxT9N12D3,WkDfVxT9N13D3,WkDfVxT9N14D3,WkDfVxT9N15D3,WkDfVxT9N16D3,WkDfVxT9N17D3,WkDfVxT9N18D3,WkDfVxT9N19D3,WkDfVxT9N20D3, & - WkDfVxT9N01D4,WkDfVxT9N02D4,WkDfVxT9N03D4,WkDfVxT9N04D4,WkDfVxT9N05D4,WkDfVxT9N06D4,WkDfVxT9N07D4,WkDfVxT9N08D4,WkDfVxT9N09D4,WkDfVxT9N10D4, & - WkDfVxT9N11D4,WkDfVxT9N12D4,WkDfVxT9N13D4,WkDfVxT9N14D4,WkDfVxT9N15D4,WkDfVxT9N16D4,WkDfVxT9N17D4,WkDfVxT9N18D4,WkDfVxT9N19D4,WkDfVxT9N20D4, & - WkDfVxT9N01D5,WkDfVxT9N02D5,WkDfVxT9N03D5,WkDfVxT9N04D5,WkDfVxT9N05D5,WkDfVxT9N06D5,WkDfVxT9N07D5,WkDfVxT9N08D5,WkDfVxT9N09D5,WkDfVxT9N10D5, & - WkDfVxT9N11D5,WkDfVxT9N12D5,WkDfVxT9N13D5,WkDfVxT9N14D5,WkDfVxT9N15D5,WkDfVxT9N16D5,WkDfVxT9N17D5,WkDfVxT9N18D5,WkDfVxT9N19D5,WkDfVxT9N20D5, & - WkDfVxT9N01D6,WkDfVxT9N02D6,WkDfVxT9N03D6,WkDfVxT9N04D6,WkDfVxT9N05D6,WkDfVxT9N06D6,WkDfVxT9N07D6,WkDfVxT9N08D6,WkDfVxT9N09D6,WkDfVxT9N10D6, & - WkDfVxT9N11D6,WkDfVxT9N12D6,WkDfVxT9N13D6,WkDfVxT9N14D6,WkDfVxT9N15D6,WkDfVxT9N16D6,WkDfVxT9N17D6,WkDfVxT9N18D6,WkDfVxT9N19D6,WkDfVxT9N20D6, & - WkDfVxT9N01D7,WkDfVxT9N02D7,WkDfVxT9N03D7,WkDfVxT9N04D7,WkDfVxT9N05D7,WkDfVxT9N06D7,WkDfVxT9N07D7,WkDfVxT9N08D7,WkDfVxT9N09D7,WkDfVxT9N10D7, & - WkDfVxT9N11D7,WkDfVxT9N12D7,WkDfVxT9N13D7,WkDfVxT9N14D7,WkDfVxT9N15D7,WkDfVxT9N16D7,WkDfVxT9N17D7,WkDfVxT9N18D7,WkDfVxT9N19D7,WkDfVxT9N20D7, & - WkDfVxT9N01D8,WkDfVxT9N02D8,WkDfVxT9N03D8,WkDfVxT9N04D8,WkDfVxT9N05D8,WkDfVxT9N06D8,WkDfVxT9N07D8,WkDfVxT9N08D8,WkDfVxT9N09D8,WkDfVxT9N10D8, & - WkDfVxT9N11D8,WkDfVxT9N12D8,WkDfVxT9N13D8,WkDfVxT9N14D8,WkDfVxT9N15D8,WkDfVxT9N16D8,WkDfVxT9N17D8,WkDfVxT9N18D8,WkDfVxT9N19D8,WkDfVxT9N20D8, & - WkDfVxT9N01D9,WkDfVxT9N02D9,WkDfVxT9N03D9,WkDfVxT9N04D9,WkDfVxT9N05D9,WkDfVxT9N06D9,WkDfVxT9N07D9,WkDfVxT9N08D9,WkDfVxT9N09D9,WkDfVxT9N10D9, & - WkDfVxT9N11D9,WkDfVxT9N12D9,WkDfVxT9N13D9,WkDfVxT9N14D9,WkDfVxT9N15D9,WkDfVxT9N16D9,WkDfVxT9N17D9,WkDfVxT9N18D9,WkDfVxT9N19D9,WkDfVxT9N20D9/), (/20,9/) ) - - -WkDfVrTND(:,:,1) = RESHAPE( & - (/WkDfVrT1N01D1,WkDfVrT1N02D1,WkDfVrT1N03D1,WkDfVrT1N04D1,WkDfVrT1N05D1,WkDfVrT1N06D1,WkDfVrT1N07D1,WkDfVrT1N08D1,WkDfVrT1N09D1,WkDfVrT1N10D1, & - WkDfVrT1N11D1,WkDfVrT1N12D1,WkDfVrT1N13D1,WkDfVrT1N14D1,WkDfVrT1N15D1,WkDfVrT1N16D1,WkDfVrT1N17D1,WkDfVrT1N18D1,WkDfVrT1N19D1,WkDfVrT1N20D1, & - WkDfVrT1N01D2,WkDfVrT1N02D2,WkDfVrT1N03D2,WkDfVrT1N04D2,WkDfVrT1N05D2,WkDfVrT1N06D2,WkDfVrT1N07D2,WkDfVrT1N08D2,WkDfVrT1N09D2,WkDfVrT1N10D2, & - WkDfVrT1N11D2,WkDfVrT1N12D2,WkDfVrT1N13D2,WkDfVrT1N14D2,WkDfVrT1N15D2,WkDfVrT1N16D2,WkDfVrT1N17D2,WkDfVrT1N18D2,WkDfVrT1N19D2,WkDfVrT1N20D2, & - WkDfVrT1N01D3,WkDfVrT1N02D3,WkDfVrT1N03D3,WkDfVrT1N04D3,WkDfVrT1N05D3,WkDfVrT1N06D3,WkDfVrT1N07D3,WkDfVrT1N08D3,WkDfVrT1N09D3,WkDfVrT1N10D3, & - WkDfVrT1N11D3,WkDfVrT1N12D3,WkDfVrT1N13D3,WkDfVrT1N14D3,WkDfVrT1N15D3,WkDfVrT1N16D3,WkDfVrT1N17D3,WkDfVrT1N18D3,WkDfVrT1N19D3,WkDfVrT1N20D3, & - WkDfVrT1N01D4,WkDfVrT1N02D4,WkDfVrT1N03D4,WkDfVrT1N04D4,WkDfVrT1N05D4,WkDfVrT1N06D4,WkDfVrT1N07D4,WkDfVrT1N08D4,WkDfVrT1N09D4,WkDfVrT1N10D4, & - WkDfVrT1N11D4,WkDfVrT1N12D4,WkDfVrT1N13D4,WkDfVrT1N14D4,WkDfVrT1N15D4,WkDfVrT1N16D4,WkDfVrT1N17D4,WkDfVrT1N18D4,WkDfVrT1N19D4,WkDfVrT1N20D4, & - WkDfVrT1N01D5,WkDfVrT1N02D5,WkDfVrT1N03D5,WkDfVrT1N04D5,WkDfVrT1N05D5,WkDfVrT1N06D5,WkDfVrT1N07D5,WkDfVrT1N08D5,WkDfVrT1N09D5,WkDfVrT1N10D5, & - WkDfVrT1N11D5,WkDfVrT1N12D5,WkDfVrT1N13D5,WkDfVrT1N14D5,WkDfVrT1N15D5,WkDfVrT1N16D5,WkDfVrT1N17D5,WkDfVrT1N18D5,WkDfVrT1N19D5,WkDfVrT1N20D5, & - WkDfVrT1N01D6,WkDfVrT1N02D6,WkDfVrT1N03D6,WkDfVrT1N04D6,WkDfVrT1N05D6,WkDfVrT1N06D6,WkDfVrT1N07D6,WkDfVrT1N08D6,WkDfVrT1N09D6,WkDfVrT1N10D6, & - WkDfVrT1N11D6,WkDfVrT1N12D6,WkDfVrT1N13D6,WkDfVrT1N14D6,WkDfVrT1N15D6,WkDfVrT1N16D6,WkDfVrT1N17D6,WkDfVrT1N18D6,WkDfVrT1N19D6,WkDfVrT1N20D6, & - WkDfVrT1N01D7,WkDfVrT1N02D7,WkDfVrT1N03D7,WkDfVrT1N04D7,WkDfVrT1N05D7,WkDfVrT1N06D7,WkDfVrT1N07D7,WkDfVrT1N08D7,WkDfVrT1N09D7,WkDfVrT1N10D7, & - WkDfVrT1N11D7,WkDfVrT1N12D7,WkDfVrT1N13D7,WkDfVrT1N14D7,WkDfVrT1N15D7,WkDfVrT1N16D7,WkDfVrT1N17D7,WkDfVrT1N18D7,WkDfVrT1N19D7,WkDfVrT1N20D7, & - WkDfVrT1N01D8,WkDfVrT1N02D8,WkDfVrT1N03D8,WkDfVrT1N04D8,WkDfVrT1N05D8,WkDfVrT1N06D8,WkDfVrT1N07D8,WkDfVrT1N08D8,WkDfVrT1N09D8,WkDfVrT1N10D8, & - WkDfVrT1N11D8,WkDfVrT1N12D8,WkDfVrT1N13D8,WkDfVrT1N14D8,WkDfVrT1N15D8,WkDfVrT1N16D8,WkDfVrT1N17D8,WkDfVrT1N18D8,WkDfVrT1N19D8,WkDfVrT1N20D8, & - WkDfVrT1N01D9,WkDfVrT1N02D9,WkDfVrT1N03D9,WkDfVrT1N04D9,WkDfVrT1N05D9,WkDfVrT1N06D9,WkDfVrT1N07D9,WkDfVrT1N08D9,WkDfVrT1N09D9,WkDfVrT1N10D9, & - WkDfVrT1N11D9,WkDfVrT1N12D9,WkDfVrT1N13D9,WkDfVrT1N14D9,WkDfVrT1N15D9,WkDfVrT1N16D9,WkDfVrT1N17D9,WkDfVrT1N18D9,WkDfVrT1N19D9,WkDfVrT1N20D9/), (/20,9/) ) -WkDfVrTND(:,:,2) = RESHAPE( & - (/WkDfVrT2N01D1,WkDfVrT2N02D1,WkDfVrT2N03D1,WkDfVrT2N04D1,WkDfVrT2N05D1,WkDfVrT2N06D1,WkDfVrT2N07D1,WkDfVrT2N08D1,WkDfVrT2N09D1,WkDfVrT2N10D1, & - WkDfVrT2N11D1,WkDfVrT2N12D1,WkDfVrT2N13D1,WkDfVrT2N14D1,WkDfVrT2N15D1,WkDfVrT2N16D1,WkDfVrT2N17D1,WkDfVrT2N18D1,WkDfVrT2N19D1,WkDfVrT2N20D1, & - WkDfVrT2N01D2,WkDfVrT2N02D2,WkDfVrT2N03D2,WkDfVrT2N04D2,WkDfVrT2N05D2,WkDfVrT2N06D2,WkDfVrT2N07D2,WkDfVrT2N08D2,WkDfVrT2N09D2,WkDfVrT2N10D2, & - WkDfVrT2N11D2,WkDfVrT2N12D2,WkDfVrT2N13D2,WkDfVrT2N14D2,WkDfVrT2N15D2,WkDfVrT2N16D2,WkDfVrT2N17D2,WkDfVrT2N18D2,WkDfVrT2N19D2,WkDfVrT2N20D2, & - WkDfVrT2N01D3,WkDfVrT2N02D3,WkDfVrT2N03D3,WkDfVrT2N04D3,WkDfVrT2N05D3,WkDfVrT2N06D3,WkDfVrT2N07D3,WkDfVrT2N08D3,WkDfVrT2N09D3,WkDfVrT2N10D3, & - WkDfVrT2N11D3,WkDfVrT2N12D3,WkDfVrT2N13D3,WkDfVrT2N14D3,WkDfVrT2N15D3,WkDfVrT2N16D3,WkDfVrT2N17D3,WkDfVrT2N18D3,WkDfVrT2N19D3,WkDfVrT2N20D3, & - WkDfVrT2N01D4,WkDfVrT2N02D4,WkDfVrT2N03D4,WkDfVrT2N04D4,WkDfVrT2N05D4,WkDfVrT2N06D4,WkDfVrT2N07D4,WkDfVrT2N08D4,WkDfVrT2N09D4,WkDfVrT2N10D4, & - WkDfVrT2N11D4,WkDfVrT2N12D4,WkDfVrT2N13D4,WkDfVrT2N14D4,WkDfVrT2N15D4,WkDfVrT2N16D4,WkDfVrT2N17D4,WkDfVrT2N18D4,WkDfVrT2N19D4,WkDfVrT2N20D4, & - WkDfVrT2N01D5,WkDfVrT2N02D5,WkDfVrT2N03D5,WkDfVrT2N04D5,WkDfVrT2N05D5,WkDfVrT2N06D5,WkDfVrT2N07D5,WkDfVrT2N08D5,WkDfVrT2N09D5,WkDfVrT2N10D5, & - WkDfVrT2N11D5,WkDfVrT2N12D5,WkDfVrT2N13D5,WkDfVrT2N14D5,WkDfVrT2N15D5,WkDfVrT2N16D5,WkDfVrT2N17D5,WkDfVrT2N18D5,WkDfVrT2N19D5,WkDfVrT2N20D5, & - WkDfVrT2N01D6,WkDfVrT2N02D6,WkDfVrT2N03D6,WkDfVrT2N04D6,WkDfVrT2N05D6,WkDfVrT2N06D6,WkDfVrT2N07D6,WkDfVrT2N08D6,WkDfVrT2N09D6,WkDfVrT2N10D6, & - WkDfVrT2N11D6,WkDfVrT2N12D6,WkDfVrT2N13D6,WkDfVrT2N14D6,WkDfVrT2N15D6,WkDfVrT2N16D6,WkDfVrT2N17D6,WkDfVrT2N18D6,WkDfVrT2N19D6,WkDfVrT2N20D6, & - WkDfVrT2N01D7,WkDfVrT2N02D7,WkDfVrT2N03D7,WkDfVrT2N04D7,WkDfVrT2N05D7,WkDfVrT2N06D7,WkDfVrT2N07D7,WkDfVrT2N08D7,WkDfVrT2N09D7,WkDfVrT2N10D7, & - WkDfVrT2N11D7,WkDfVrT2N12D7,WkDfVrT2N13D7,WkDfVrT2N14D7,WkDfVrT2N15D7,WkDfVrT2N16D7,WkDfVrT2N17D7,WkDfVrT2N18D7,WkDfVrT2N19D7,WkDfVrT2N20D7, & - WkDfVrT2N01D8,WkDfVrT2N02D8,WkDfVrT2N03D8,WkDfVrT2N04D8,WkDfVrT2N05D8,WkDfVrT2N06D8,WkDfVrT2N07D8,WkDfVrT2N08D8,WkDfVrT2N09D8,WkDfVrT2N10D8, & - WkDfVrT2N11D8,WkDfVrT2N12D8,WkDfVrT2N13D8,WkDfVrT2N14D8,WkDfVrT2N15D8,WkDfVrT2N16D8,WkDfVrT2N17D8,WkDfVrT2N18D8,WkDfVrT2N19D8,WkDfVrT2N20D8, & - WkDfVrT2N01D9,WkDfVrT2N02D9,WkDfVrT2N03D9,WkDfVrT2N04D9,WkDfVrT2N05D9,WkDfVrT2N06D9,WkDfVrT2N07D9,WkDfVrT2N08D9,WkDfVrT2N09D9,WkDfVrT2N10D9, & - WkDfVrT2N11D9,WkDfVrT2N12D9,WkDfVrT2N13D9,WkDfVrT2N14D9,WkDfVrT2N15D9,WkDfVrT2N16D9,WkDfVrT2N17D9,WkDfVrT2N18D9,WkDfVrT2N19D9,WkDfVrT2N20D9/), (/20,9/) ) -WkDfVrTND(:,:,3) = RESHAPE( & - (/WkDfVrT3N01D1,WkDfVrT3N02D1,WkDfVrT3N03D1,WkDfVrT3N04D1,WkDfVrT3N05D1,WkDfVrT3N06D1,WkDfVrT3N07D1,WkDfVrT3N08D1,WkDfVrT3N09D1,WkDfVrT3N10D1, & - WkDfVrT3N11D1,WkDfVrT3N12D1,WkDfVrT3N13D1,WkDfVrT3N14D1,WkDfVrT3N15D1,WkDfVrT3N16D1,WkDfVrT3N17D1,WkDfVrT3N18D1,WkDfVrT3N19D1,WkDfVrT3N20D1, & - WkDfVrT3N01D2,WkDfVrT3N02D2,WkDfVrT3N03D2,WkDfVrT3N04D2,WkDfVrT3N05D2,WkDfVrT3N06D2,WkDfVrT3N07D2,WkDfVrT3N08D2,WkDfVrT3N09D2,WkDfVrT3N10D2, & - WkDfVrT3N11D2,WkDfVrT3N12D2,WkDfVrT3N13D2,WkDfVrT3N14D2,WkDfVrT3N15D2,WkDfVrT3N16D2,WkDfVrT3N17D2,WkDfVrT3N18D2,WkDfVrT3N19D2,WkDfVrT3N20D2, & - WkDfVrT3N01D3,WkDfVrT3N02D3,WkDfVrT3N03D3,WkDfVrT3N04D3,WkDfVrT3N05D3,WkDfVrT3N06D3,WkDfVrT3N07D3,WkDfVrT3N08D3,WkDfVrT3N09D3,WkDfVrT3N10D3, & - WkDfVrT3N11D3,WkDfVrT3N12D3,WkDfVrT3N13D3,WkDfVrT3N14D3,WkDfVrT3N15D3,WkDfVrT3N16D3,WkDfVrT3N17D3,WkDfVrT3N18D3,WkDfVrT3N19D3,WkDfVrT3N20D3, & - WkDfVrT3N01D4,WkDfVrT3N02D4,WkDfVrT3N03D4,WkDfVrT3N04D4,WkDfVrT3N05D4,WkDfVrT3N06D4,WkDfVrT3N07D4,WkDfVrT3N08D4,WkDfVrT3N09D4,WkDfVrT3N10D4, & - WkDfVrT3N11D4,WkDfVrT3N12D4,WkDfVrT3N13D4,WkDfVrT3N14D4,WkDfVrT3N15D4,WkDfVrT3N16D4,WkDfVrT3N17D4,WkDfVrT3N18D4,WkDfVrT3N19D4,WkDfVrT3N20D4, & - WkDfVrT3N01D5,WkDfVrT3N02D5,WkDfVrT3N03D5,WkDfVrT3N04D5,WkDfVrT3N05D5,WkDfVrT3N06D5,WkDfVrT3N07D5,WkDfVrT3N08D5,WkDfVrT3N09D5,WkDfVrT3N10D5, & - WkDfVrT3N11D5,WkDfVrT3N12D5,WkDfVrT3N13D5,WkDfVrT3N14D5,WkDfVrT3N15D5,WkDfVrT3N16D5,WkDfVrT3N17D5,WkDfVrT3N18D5,WkDfVrT3N19D5,WkDfVrT3N20D5, & - WkDfVrT3N01D6,WkDfVrT3N02D6,WkDfVrT3N03D6,WkDfVrT3N04D6,WkDfVrT3N05D6,WkDfVrT3N06D6,WkDfVrT3N07D6,WkDfVrT3N08D6,WkDfVrT3N09D6,WkDfVrT3N10D6, & - WkDfVrT3N11D6,WkDfVrT3N12D6,WkDfVrT3N13D6,WkDfVrT3N14D6,WkDfVrT3N15D6,WkDfVrT3N16D6,WkDfVrT3N17D6,WkDfVrT3N18D6,WkDfVrT3N19D6,WkDfVrT3N20D6, & - WkDfVrT3N01D7,WkDfVrT3N02D7,WkDfVrT3N03D7,WkDfVrT3N04D7,WkDfVrT3N05D7,WkDfVrT3N06D7,WkDfVrT3N07D7,WkDfVrT3N08D7,WkDfVrT3N09D7,WkDfVrT3N10D7, & - WkDfVrT3N11D7,WkDfVrT3N12D7,WkDfVrT3N13D7,WkDfVrT3N14D7,WkDfVrT3N15D7,WkDfVrT3N16D7,WkDfVrT3N17D7,WkDfVrT3N18D7,WkDfVrT3N19D7,WkDfVrT3N20D7, & - WkDfVrT3N01D8,WkDfVrT3N02D8,WkDfVrT3N03D8,WkDfVrT3N04D8,WkDfVrT3N05D8,WkDfVrT3N06D8,WkDfVrT3N07D8,WkDfVrT3N08D8,WkDfVrT3N09D8,WkDfVrT3N10D8, & - WkDfVrT3N11D8,WkDfVrT3N12D8,WkDfVrT3N13D8,WkDfVrT3N14D8,WkDfVrT3N15D8,WkDfVrT3N16D8,WkDfVrT3N17D8,WkDfVrT3N18D8,WkDfVrT3N19D8,WkDfVrT3N20D8, & - WkDfVrT3N01D9,WkDfVrT3N02D9,WkDfVrT3N03D9,WkDfVrT3N04D9,WkDfVrT3N05D9,WkDfVrT3N06D9,WkDfVrT3N07D9,WkDfVrT3N08D9,WkDfVrT3N09D9,WkDfVrT3N10D9, & - WkDfVrT3N11D9,WkDfVrT3N12D9,WkDfVrT3N13D9,WkDfVrT3N14D9,WkDfVrT3N15D9,WkDfVrT3N16D9,WkDfVrT3N17D9,WkDfVrT3N18D9,WkDfVrT3N19D9,WkDfVrT3N20D9/), (/20,9/) ) -WkDfVrTND(:,:,4) = RESHAPE( & - (/WkDfVrT4N01D1,WkDfVrT4N02D1,WkDfVrT4N03D1,WkDfVrT4N04D1,WkDfVrT4N05D1,WkDfVrT4N06D1,WkDfVrT4N07D1,WkDfVrT4N08D1,WkDfVrT4N09D1,WkDfVrT4N10D1, & - WkDfVrT4N11D1,WkDfVrT4N12D1,WkDfVrT4N13D1,WkDfVrT4N14D1,WkDfVrT4N15D1,WkDfVrT4N16D1,WkDfVrT4N17D1,WkDfVrT4N18D1,WkDfVrT4N19D1,WkDfVrT4N20D1, & - WkDfVrT4N01D2,WkDfVrT4N02D2,WkDfVrT4N03D2,WkDfVrT4N04D2,WkDfVrT4N05D2,WkDfVrT4N06D2,WkDfVrT4N07D2,WkDfVrT4N08D2,WkDfVrT4N09D2,WkDfVrT4N10D2, & - WkDfVrT4N11D2,WkDfVrT4N12D2,WkDfVrT4N13D2,WkDfVrT4N14D2,WkDfVrT4N15D2,WkDfVrT4N16D2,WkDfVrT4N17D2,WkDfVrT4N18D2,WkDfVrT4N19D2,WkDfVrT4N20D2, & - WkDfVrT4N01D3,WkDfVrT4N02D3,WkDfVrT4N03D3,WkDfVrT4N04D3,WkDfVrT4N05D3,WkDfVrT4N06D3,WkDfVrT4N07D3,WkDfVrT4N08D3,WkDfVrT4N09D3,WkDfVrT4N10D3, & - WkDfVrT4N11D3,WkDfVrT4N12D3,WkDfVrT4N13D3,WkDfVrT4N14D3,WkDfVrT4N15D3,WkDfVrT4N16D3,WkDfVrT4N17D3,WkDfVrT4N18D3,WkDfVrT4N19D3,WkDfVrT4N20D3, & - WkDfVrT4N01D4,WkDfVrT4N02D4,WkDfVrT4N03D4,WkDfVrT4N04D4,WkDfVrT4N05D4,WkDfVrT4N06D4,WkDfVrT4N07D4,WkDfVrT4N08D4,WkDfVrT4N09D4,WkDfVrT4N10D4, & - WkDfVrT4N11D4,WkDfVrT4N12D4,WkDfVrT4N13D4,WkDfVrT4N14D4,WkDfVrT4N15D4,WkDfVrT4N16D4,WkDfVrT4N17D4,WkDfVrT4N18D4,WkDfVrT4N19D4,WkDfVrT4N20D4, & - WkDfVrT4N01D5,WkDfVrT4N02D5,WkDfVrT4N03D5,WkDfVrT4N04D5,WkDfVrT4N05D5,WkDfVrT4N06D5,WkDfVrT4N07D5,WkDfVrT4N08D5,WkDfVrT4N09D5,WkDfVrT4N10D5, & - WkDfVrT4N11D5,WkDfVrT4N12D5,WkDfVrT4N13D5,WkDfVrT4N14D5,WkDfVrT4N15D5,WkDfVrT4N16D5,WkDfVrT4N17D5,WkDfVrT4N18D5,WkDfVrT4N19D5,WkDfVrT4N20D5, & - WkDfVrT4N01D6,WkDfVrT4N02D6,WkDfVrT4N03D6,WkDfVrT4N04D6,WkDfVrT4N05D6,WkDfVrT4N06D6,WkDfVrT4N07D6,WkDfVrT4N08D6,WkDfVrT4N09D6,WkDfVrT4N10D6, & - WkDfVrT4N11D6,WkDfVrT4N12D6,WkDfVrT4N13D6,WkDfVrT4N14D6,WkDfVrT4N15D6,WkDfVrT4N16D6,WkDfVrT4N17D6,WkDfVrT4N18D6,WkDfVrT4N19D6,WkDfVrT4N20D6, & - WkDfVrT4N01D7,WkDfVrT4N02D7,WkDfVrT4N03D7,WkDfVrT4N04D7,WkDfVrT4N05D7,WkDfVrT4N06D7,WkDfVrT4N07D7,WkDfVrT4N08D7,WkDfVrT4N09D7,WkDfVrT4N10D7, & - WkDfVrT4N11D7,WkDfVrT4N12D7,WkDfVrT4N13D7,WkDfVrT4N14D7,WkDfVrT4N15D7,WkDfVrT4N16D7,WkDfVrT4N17D7,WkDfVrT4N18D7,WkDfVrT4N19D7,WkDfVrT4N20D7, & - WkDfVrT4N01D8,WkDfVrT4N02D8,WkDfVrT4N03D8,WkDfVrT4N04D8,WkDfVrT4N05D8,WkDfVrT4N06D8,WkDfVrT4N07D8,WkDfVrT4N08D8,WkDfVrT4N09D8,WkDfVrT4N10D8, & - WkDfVrT4N11D8,WkDfVrT4N12D8,WkDfVrT4N13D8,WkDfVrT4N14D8,WkDfVrT4N15D8,WkDfVrT4N16D8,WkDfVrT4N17D8,WkDfVrT4N18D8,WkDfVrT4N19D8,WkDfVrT4N20D8, & - WkDfVrT4N01D9,WkDfVrT4N02D9,WkDfVrT4N03D9,WkDfVrT4N04D9,WkDfVrT4N05D9,WkDfVrT4N06D9,WkDfVrT4N07D9,WkDfVrT4N08D9,WkDfVrT4N09D9,WkDfVrT4N10D9, & - WkDfVrT4N11D9,WkDfVrT4N12D9,WkDfVrT4N13D9,WkDfVrT4N14D9,WkDfVrT4N15D9,WkDfVrT4N16D9,WkDfVrT4N17D9,WkDfVrT4N18D9,WkDfVrT4N19D9,WkDfVrT4N20D9/), (/20,9/) ) - -WkDfVrTND(:,:,5) = RESHAPE( & - (/WkDfVrT5N01D1,WkDfVrT5N02D1,WkDfVrT5N03D1,WkDfVrT5N04D1,WkDfVrT5N05D1,WkDfVrT5N06D1,WkDfVrT5N07D1,WkDfVrT5N08D1,WkDfVrT5N09D1,WkDfVrT5N10D1, & - WkDfVrT5N11D1,WkDfVrT5N12D1,WkDfVrT5N13D1,WkDfVrT5N14D1,WkDfVrT5N15D1,WkDfVrT5N16D1,WkDfVrT5N17D1,WkDfVrT5N18D1,WkDfVrT5N19D1,WkDfVrT5N20D1, & - WkDfVrT5N01D2,WkDfVrT5N02D2,WkDfVrT5N03D2,WkDfVrT5N04D2,WkDfVrT5N05D2,WkDfVrT5N06D2,WkDfVrT5N07D2,WkDfVrT5N08D2,WkDfVrT5N09D2,WkDfVrT5N10D2, & - WkDfVrT5N11D2,WkDfVrT5N12D2,WkDfVrT5N13D2,WkDfVrT5N14D2,WkDfVrT5N15D2,WkDfVrT5N16D2,WkDfVrT5N17D2,WkDfVrT5N18D2,WkDfVrT5N19D2,WkDfVrT5N20D2, & - WkDfVrT5N01D3,WkDfVrT5N02D3,WkDfVrT5N03D3,WkDfVrT5N04D3,WkDfVrT5N05D3,WkDfVrT5N06D3,WkDfVrT5N07D3,WkDfVrT5N08D3,WkDfVrT5N09D3,WkDfVrT5N10D3, & - WkDfVrT5N11D3,WkDfVrT5N12D3,WkDfVrT5N13D3,WkDfVrT5N14D3,WkDfVrT5N15D3,WkDfVrT5N16D3,WkDfVrT5N17D3,WkDfVrT5N18D3,WkDfVrT5N19D3,WkDfVrT5N20D3, & - WkDfVrT5N01D4,WkDfVrT5N02D4,WkDfVrT5N03D4,WkDfVrT5N04D4,WkDfVrT5N05D4,WkDfVrT5N06D4,WkDfVrT5N07D4,WkDfVrT5N08D4,WkDfVrT5N09D4,WkDfVrT5N10D4, & - WkDfVrT5N11D4,WkDfVrT5N12D4,WkDfVrT5N13D4,WkDfVrT5N14D4,WkDfVrT5N15D4,WkDfVrT5N16D4,WkDfVrT5N17D4,WkDfVrT5N18D4,WkDfVrT5N19D4,WkDfVrT5N20D4, & - WkDfVrT5N01D5,WkDfVrT5N02D5,WkDfVrT5N03D5,WkDfVrT5N04D5,WkDfVrT5N05D5,WkDfVrT5N06D5,WkDfVrT5N07D5,WkDfVrT5N08D5,WkDfVrT5N09D5,WkDfVrT5N10D5, & - WkDfVrT5N11D5,WkDfVrT5N12D5,WkDfVrT5N13D5,WkDfVrT5N14D5,WkDfVrT5N15D5,WkDfVrT5N16D5,WkDfVrT5N17D5,WkDfVrT5N18D5,WkDfVrT5N19D5,WkDfVrT5N20D5, & - WkDfVrT5N01D6,WkDfVrT5N02D6,WkDfVrT5N03D6,WkDfVrT5N04D6,WkDfVrT5N05D6,WkDfVrT5N06D6,WkDfVrT5N07D6,WkDfVrT5N08D6,WkDfVrT5N09D6,WkDfVrT5N10D6, & - WkDfVrT5N11D6,WkDfVrT5N12D6,WkDfVrT5N13D6,WkDfVrT5N14D6,WkDfVrT5N15D6,WkDfVrT5N16D6,WkDfVrT5N17D6,WkDfVrT5N18D6,WkDfVrT5N19D6,WkDfVrT5N20D6, & - WkDfVrT5N01D7,WkDfVrT5N02D7,WkDfVrT5N03D7,WkDfVrT5N04D7,WkDfVrT5N05D7,WkDfVrT5N06D7,WkDfVrT5N07D7,WkDfVrT5N08D7,WkDfVrT5N09D7,WkDfVrT5N10D7, & - WkDfVrT5N11D7,WkDfVrT5N12D7,WkDfVrT5N13D7,WkDfVrT5N14D7,WkDfVrT5N15D7,WkDfVrT5N16D7,WkDfVrT5N17D7,WkDfVrT5N18D7,WkDfVrT5N19D7,WkDfVrT5N20D7, & - WkDfVrT5N01D8,WkDfVrT5N02D8,WkDfVrT5N03D8,WkDfVrT5N04D8,WkDfVrT5N05D8,WkDfVrT5N06D8,WkDfVrT5N07D8,WkDfVrT5N08D8,WkDfVrT5N09D8,WkDfVrT5N10D8, & - WkDfVrT5N11D8,WkDfVrT5N12D8,WkDfVrT5N13D8,WkDfVrT5N14D8,WkDfVrT5N15D8,WkDfVrT5N16D8,WkDfVrT5N17D8,WkDfVrT5N18D8,WkDfVrT5N19D8,WkDfVrT5N20D8, & - WkDfVrT5N01D9,WkDfVrT5N02D9,WkDfVrT5N03D9,WkDfVrT5N04D9,WkDfVrT5N05D9,WkDfVrT5N06D9,WkDfVrT5N07D9,WkDfVrT5N08D9,WkDfVrT5N09D9,WkDfVrT5N10D9, & - WkDfVrT5N11D9,WkDfVrT5N12D9,WkDfVrT5N13D9,WkDfVrT5N14D9,WkDfVrT5N15D9,WkDfVrT5N16D9,WkDfVrT5N17D9,WkDfVrT5N18D9,WkDfVrT5N19D9,WkDfVrT5N20D9/), (/20,9/) ) -WkDfVrTND(:,:,6) = RESHAPE( & - (/WkDfVrT6N01D1,WkDfVrT6N02D1,WkDfVrT6N03D1,WkDfVrT6N04D1,WkDfVrT6N05D1,WkDfVrT6N06D1,WkDfVrT6N07D1,WkDfVrT6N08D1,WkDfVrT6N09D1,WkDfVrT6N10D1, & - WkDfVrT6N11D1,WkDfVrT6N12D1,WkDfVrT6N13D1,WkDfVrT6N14D1,WkDfVrT6N15D1,WkDfVrT6N16D1,WkDfVrT6N17D1,WkDfVrT6N18D1,WkDfVrT6N19D1,WkDfVrT6N20D1, & - WkDfVrT6N01D2,WkDfVrT6N02D2,WkDfVrT6N03D2,WkDfVrT6N04D2,WkDfVrT6N05D2,WkDfVrT6N06D2,WkDfVrT6N07D2,WkDfVrT6N08D2,WkDfVrT6N09D2,WkDfVrT6N10D2, & - WkDfVrT6N11D2,WkDfVrT6N12D2,WkDfVrT6N13D2,WkDfVrT6N14D2,WkDfVrT6N15D2,WkDfVrT6N16D2,WkDfVrT6N17D2,WkDfVrT6N18D2,WkDfVrT6N19D2,WkDfVrT6N20D2, & - WkDfVrT6N01D3,WkDfVrT6N02D3,WkDfVrT6N03D3,WkDfVrT6N04D3,WkDfVrT6N05D3,WkDfVrT6N06D3,WkDfVrT6N07D3,WkDfVrT6N08D3,WkDfVrT6N09D3,WkDfVrT6N10D3, & - WkDfVrT6N11D3,WkDfVrT6N12D3,WkDfVrT6N13D3,WkDfVrT6N14D3,WkDfVrT6N15D3,WkDfVrT6N16D3,WkDfVrT6N17D3,WkDfVrT6N18D3,WkDfVrT6N19D3,WkDfVrT6N20D3, & - WkDfVrT6N01D4,WkDfVrT6N02D4,WkDfVrT6N03D4,WkDfVrT6N04D4,WkDfVrT6N05D4,WkDfVrT6N06D4,WkDfVrT6N07D4,WkDfVrT6N08D4,WkDfVrT6N09D4,WkDfVrT6N10D4, & - WkDfVrT6N11D4,WkDfVrT6N12D4,WkDfVrT6N13D4,WkDfVrT6N14D4,WkDfVrT6N15D4,WkDfVrT6N16D4,WkDfVrT6N17D4,WkDfVrT6N18D4,WkDfVrT6N19D4,WkDfVrT6N20D4, & - WkDfVrT6N01D5,WkDfVrT6N02D5,WkDfVrT6N03D5,WkDfVrT6N04D5,WkDfVrT6N05D5,WkDfVrT6N06D5,WkDfVrT6N07D5,WkDfVrT6N08D5,WkDfVrT6N09D5,WkDfVrT6N10D5, & - WkDfVrT6N11D5,WkDfVrT6N12D5,WkDfVrT6N13D5,WkDfVrT6N14D5,WkDfVrT6N15D5,WkDfVrT6N16D5,WkDfVrT6N17D5,WkDfVrT6N18D5,WkDfVrT6N19D5,WkDfVrT6N20D5, & - WkDfVrT6N01D6,WkDfVrT6N02D6,WkDfVrT6N03D6,WkDfVrT6N04D6,WkDfVrT6N05D6,WkDfVrT6N06D6,WkDfVrT6N07D6,WkDfVrT6N08D6,WkDfVrT6N09D6,WkDfVrT6N10D6, & - WkDfVrT6N11D6,WkDfVrT6N12D6,WkDfVrT6N13D6,WkDfVrT6N14D6,WkDfVrT6N15D6,WkDfVrT6N16D6,WkDfVrT6N17D6,WkDfVrT6N18D6,WkDfVrT6N19D6,WkDfVrT6N20D6, & - WkDfVrT6N01D7,WkDfVrT6N02D7,WkDfVrT6N03D7,WkDfVrT6N04D7,WkDfVrT6N05D7,WkDfVrT6N06D7,WkDfVrT6N07D7,WkDfVrT6N08D7,WkDfVrT6N09D7,WkDfVrT6N10D7, & - WkDfVrT6N11D7,WkDfVrT6N12D7,WkDfVrT6N13D7,WkDfVrT6N14D7,WkDfVrT6N15D7,WkDfVrT6N16D7,WkDfVrT6N17D7,WkDfVrT6N18D7,WkDfVrT6N19D7,WkDfVrT6N20D7, & - WkDfVrT6N01D8,WkDfVrT6N02D8,WkDfVrT6N03D8,WkDfVrT6N04D8,WkDfVrT6N05D8,WkDfVrT6N06D8,WkDfVrT6N07D8,WkDfVrT6N08D8,WkDfVrT6N09D8,WkDfVrT6N10D8, & - WkDfVrT6N11D8,WkDfVrT6N12D8,WkDfVrT6N13D8,WkDfVrT6N14D8,WkDfVrT6N15D8,WkDfVrT6N16D8,WkDfVrT6N17D8,WkDfVrT6N18D8,WkDfVrT6N19D8,WkDfVrT6N20D8, & - WkDfVrT6N01D9,WkDfVrT6N02D9,WkDfVrT6N03D9,WkDfVrT6N04D9,WkDfVrT6N05D9,WkDfVrT6N06D9,WkDfVrT6N07D9,WkDfVrT6N08D9,WkDfVrT6N09D9,WkDfVrT6N10D9, & - WkDfVrT6N11D9,WkDfVrT6N12D9,WkDfVrT6N13D9,WkDfVrT6N14D9,WkDfVrT6N15D9,WkDfVrT6N16D9,WkDfVrT6N17D9,WkDfVrT6N18D9,WkDfVrT6N19D9,WkDfVrT6N20D9/), (/20,9/) ) -WkDfVrTND(:,:,7) = RESHAPE( & - (/WkDfVrT7N01D1,WkDfVrT7N02D1,WkDfVrT7N03D1,WkDfVrT7N04D1,WkDfVrT7N05D1,WkDfVrT7N06D1,WkDfVrT7N07D1,WkDfVrT7N08D1,WkDfVrT7N09D1,WkDfVrT7N10D1, & - WkDfVrT7N11D1,WkDfVrT7N12D1,WkDfVrT7N13D1,WkDfVrT7N14D1,WkDfVrT7N15D1,WkDfVrT7N16D1,WkDfVrT7N17D1,WkDfVrT7N18D1,WkDfVrT7N19D1,WkDfVrT7N20D1, & - WkDfVrT7N01D2,WkDfVrT7N02D2,WkDfVrT7N03D2,WkDfVrT7N04D2,WkDfVrT7N05D2,WkDfVrT7N06D2,WkDfVrT7N07D2,WkDfVrT7N08D2,WkDfVrT7N09D2,WkDfVrT7N10D2, & - WkDfVrT7N11D2,WkDfVrT7N12D2,WkDfVrT7N13D2,WkDfVrT7N14D2,WkDfVrT7N15D2,WkDfVrT7N16D2,WkDfVrT7N17D2,WkDfVrT7N18D2,WkDfVrT7N19D2,WkDfVrT7N20D2, & - WkDfVrT7N01D3,WkDfVrT7N02D3,WkDfVrT7N03D3,WkDfVrT7N04D3,WkDfVrT7N05D3,WkDfVrT7N06D3,WkDfVrT7N07D3,WkDfVrT7N08D3,WkDfVrT7N09D3,WkDfVrT7N10D3, & - WkDfVrT7N11D3,WkDfVrT7N12D3,WkDfVrT7N13D3,WkDfVrT7N14D3,WkDfVrT7N15D3,WkDfVrT7N16D3,WkDfVrT7N17D3,WkDfVrT7N18D3,WkDfVrT7N19D3,WkDfVrT7N20D3, & - WkDfVrT7N01D4,WkDfVrT7N02D4,WkDfVrT7N03D4,WkDfVrT7N04D4,WkDfVrT7N05D4,WkDfVrT7N06D4,WkDfVrT7N07D4,WkDfVrT7N08D4,WkDfVrT7N09D4,WkDfVrT7N10D4, & - WkDfVrT7N11D4,WkDfVrT7N12D4,WkDfVrT7N13D4,WkDfVrT7N14D4,WkDfVrT7N15D4,WkDfVrT7N16D4,WkDfVrT7N17D4,WkDfVrT7N18D4,WkDfVrT7N19D4,WkDfVrT7N20D4, & - WkDfVrT7N01D5,WkDfVrT7N02D5,WkDfVrT7N03D5,WkDfVrT7N04D5,WkDfVrT7N05D5,WkDfVrT7N06D5,WkDfVrT7N07D5,WkDfVrT7N08D5,WkDfVrT7N09D5,WkDfVrT7N10D5, & - WkDfVrT7N11D5,WkDfVrT7N12D5,WkDfVrT7N13D5,WkDfVrT7N14D5,WkDfVrT7N15D5,WkDfVrT7N16D5,WkDfVrT7N17D5,WkDfVrT7N18D5,WkDfVrT7N19D5,WkDfVrT7N20D5, & - WkDfVrT7N01D6,WkDfVrT7N02D6,WkDfVrT7N03D6,WkDfVrT7N04D6,WkDfVrT7N05D6,WkDfVrT7N06D6,WkDfVrT7N07D6,WkDfVrT7N08D6,WkDfVrT7N09D6,WkDfVrT7N10D6, & - WkDfVrT7N11D6,WkDfVrT7N12D6,WkDfVrT7N13D6,WkDfVrT7N14D6,WkDfVrT7N15D6,WkDfVrT7N16D6,WkDfVrT7N17D6,WkDfVrT7N18D6,WkDfVrT7N19D6,WkDfVrT7N20D6, & - WkDfVrT7N01D7,WkDfVrT7N02D7,WkDfVrT7N03D7,WkDfVrT7N04D7,WkDfVrT7N05D7,WkDfVrT7N06D7,WkDfVrT7N07D7,WkDfVrT7N08D7,WkDfVrT7N09D7,WkDfVrT7N10D7, & - WkDfVrT7N11D7,WkDfVrT7N12D7,WkDfVrT7N13D7,WkDfVrT7N14D7,WkDfVrT7N15D7,WkDfVrT7N16D7,WkDfVrT7N17D7,WkDfVrT7N18D7,WkDfVrT7N19D7,WkDfVrT7N20D7, & - WkDfVrT7N01D8,WkDfVrT7N02D8,WkDfVrT7N03D8,WkDfVrT7N04D8,WkDfVrT7N05D8,WkDfVrT7N06D8,WkDfVrT7N07D8,WkDfVrT7N08D8,WkDfVrT7N09D8,WkDfVrT7N10D8, & - WkDfVrT7N11D8,WkDfVrT7N12D8,WkDfVrT7N13D8,WkDfVrT7N14D8,WkDfVrT7N15D8,WkDfVrT7N16D8,WkDfVrT7N17D8,WkDfVrT7N18D8,WkDfVrT7N19D8,WkDfVrT7N20D8, & - WkDfVrT7N01D9,WkDfVrT7N02D9,WkDfVrT7N03D9,WkDfVrT7N04D9,WkDfVrT7N05D9,WkDfVrT7N06D9,WkDfVrT7N07D9,WkDfVrT7N08D9,WkDfVrT7N09D9,WkDfVrT7N10D9, & - WkDfVrT7N11D9,WkDfVrT7N12D9,WkDfVrT7N13D9,WkDfVrT7N14D9,WkDfVrT7N15D9,WkDfVrT7N16D9,WkDfVrT7N17D9,WkDfVrT7N18D9,WkDfVrT7N19D9,WkDfVrT7N20D9/), (/20,9/) ) -WkDfVrTND(:,:,8) = RESHAPE( & - (/WkDfVrT8N01D1,WkDfVrT8N02D1,WkDfVrT8N03D1,WkDfVrT8N04D1,WkDfVrT8N05D1,WkDfVrT8N06D1,WkDfVrT8N07D1,WkDfVrT8N08D1,WkDfVrT8N09D1,WkDfVrT8N10D1, & - WkDfVrT8N11D1,WkDfVrT8N12D1,WkDfVrT8N13D1,WkDfVrT8N14D1,WkDfVrT8N15D1,WkDfVrT8N16D1,WkDfVrT8N17D1,WkDfVrT8N18D1,WkDfVrT8N19D1,WkDfVrT8N20D1, & - WkDfVrT8N01D2,WkDfVrT8N02D2,WkDfVrT8N03D2,WkDfVrT8N04D2,WkDfVrT8N05D2,WkDfVrT8N06D2,WkDfVrT8N07D2,WkDfVrT8N08D2,WkDfVrT8N09D2,WkDfVrT8N10D2, & - WkDfVrT8N11D2,WkDfVrT8N12D2,WkDfVrT8N13D2,WkDfVrT8N14D2,WkDfVrT8N15D2,WkDfVrT8N16D2,WkDfVrT8N17D2,WkDfVrT8N18D2,WkDfVrT8N19D2,WkDfVrT8N20D2, & - WkDfVrT8N01D3,WkDfVrT8N02D3,WkDfVrT8N03D3,WkDfVrT8N04D3,WkDfVrT8N05D3,WkDfVrT8N06D3,WkDfVrT8N07D3,WkDfVrT8N08D3,WkDfVrT8N09D3,WkDfVrT8N10D3, & - WkDfVrT8N11D3,WkDfVrT8N12D3,WkDfVrT8N13D3,WkDfVrT8N14D3,WkDfVrT8N15D3,WkDfVrT8N16D3,WkDfVrT8N17D3,WkDfVrT8N18D3,WkDfVrT8N19D3,WkDfVrT8N20D3, & - WkDfVrT8N01D4,WkDfVrT8N02D4,WkDfVrT8N03D4,WkDfVrT8N04D4,WkDfVrT8N05D4,WkDfVrT8N06D4,WkDfVrT8N07D4,WkDfVrT8N08D4,WkDfVrT8N09D4,WkDfVrT8N10D4, & - WkDfVrT8N11D4,WkDfVrT8N12D4,WkDfVrT8N13D4,WkDfVrT8N14D4,WkDfVrT8N15D4,WkDfVrT8N16D4,WkDfVrT8N17D4,WkDfVrT8N18D4,WkDfVrT8N19D4,WkDfVrT8N20D4, & - WkDfVrT8N01D5,WkDfVrT8N02D5,WkDfVrT8N03D5,WkDfVrT8N04D5,WkDfVrT8N05D5,WkDfVrT8N06D5,WkDfVrT8N07D5,WkDfVrT8N08D5,WkDfVrT8N09D5,WkDfVrT8N10D5, & - WkDfVrT8N11D5,WkDfVrT8N12D5,WkDfVrT8N13D5,WkDfVrT8N14D5,WkDfVrT8N15D5,WkDfVrT8N16D5,WkDfVrT8N17D5,WkDfVrT8N18D5,WkDfVrT8N19D5,WkDfVrT8N20D5, & - WkDfVrT8N01D6,WkDfVrT8N02D6,WkDfVrT8N03D6,WkDfVrT8N04D6,WkDfVrT8N05D6,WkDfVrT8N06D6,WkDfVrT8N07D6,WkDfVrT8N08D6,WkDfVrT8N09D6,WkDfVrT8N10D6, & - WkDfVrT8N11D6,WkDfVrT8N12D6,WkDfVrT8N13D6,WkDfVrT8N14D6,WkDfVrT8N15D6,WkDfVrT8N16D6,WkDfVrT8N17D6,WkDfVrT8N18D6,WkDfVrT8N19D6,WkDfVrT8N20D6, & - WkDfVrT8N01D7,WkDfVrT8N02D7,WkDfVrT8N03D7,WkDfVrT8N04D7,WkDfVrT8N05D7,WkDfVrT8N06D7,WkDfVrT8N07D7,WkDfVrT8N08D7,WkDfVrT8N09D7,WkDfVrT8N10D7, & - WkDfVrT8N11D7,WkDfVrT8N12D7,WkDfVrT8N13D7,WkDfVrT8N14D7,WkDfVrT8N15D7,WkDfVrT8N16D7,WkDfVrT8N17D7,WkDfVrT8N18D7,WkDfVrT8N19D7,WkDfVrT8N20D7, & - WkDfVrT8N01D8,WkDfVrT8N02D8,WkDfVrT8N03D8,WkDfVrT8N04D8,WkDfVrT8N05D8,WkDfVrT8N06D8,WkDfVrT8N07D8,WkDfVrT8N08D8,WkDfVrT8N09D8,WkDfVrT8N10D8, & - WkDfVrT8N11D8,WkDfVrT8N12D8,WkDfVrT8N13D8,WkDfVrT8N14D8,WkDfVrT8N15D8,WkDfVrT8N16D8,WkDfVrT8N17D8,WkDfVrT8N18D8,WkDfVrT8N19D8,WkDfVrT8N20D8, & - WkDfVrT8N01D9,WkDfVrT8N02D9,WkDfVrT8N03D9,WkDfVrT8N04D9,WkDfVrT8N05D9,WkDfVrT8N06D9,WkDfVrT8N07D9,WkDfVrT8N08D9,WkDfVrT8N09D9,WkDfVrT8N10D9, & - WkDfVrT8N11D9,WkDfVrT8N12D9,WkDfVrT8N13D9,WkDfVrT8N14D9,WkDfVrT8N15D9,WkDfVrT8N16D9,WkDfVrT8N17D9,WkDfVrT8N18D9,WkDfVrT8N19D9,WkDfVrT8N20D9/), (/20,9/) ) -WkDfVrTND(:,:,9) = RESHAPE( & - (/WkDfVrT9N01D1,WkDfVrT9N02D1,WkDfVrT9N03D1,WkDfVrT9N04D1,WkDfVrT9N05D1,WkDfVrT9N06D1,WkDfVrT9N07D1,WkDfVrT9N08D1,WkDfVrT9N09D1,WkDfVrT9N10D1, & - WkDfVrT9N11D1,WkDfVrT9N12D1,WkDfVrT9N13D1,WkDfVrT9N14D1,WkDfVrT9N15D1,WkDfVrT9N16D1,WkDfVrT9N17D1,WkDfVrT9N18D1,WkDfVrT9N19D1,WkDfVrT9N20D1, & - WkDfVrT9N01D2,WkDfVrT9N02D2,WkDfVrT9N03D2,WkDfVrT9N04D2,WkDfVrT9N05D2,WkDfVrT9N06D2,WkDfVrT9N07D2,WkDfVrT9N08D2,WkDfVrT9N09D2,WkDfVrT9N10D2, & - WkDfVrT9N11D2,WkDfVrT9N12D2,WkDfVrT9N13D2,WkDfVrT9N14D2,WkDfVrT9N15D2,WkDfVrT9N16D2,WkDfVrT9N17D2,WkDfVrT9N18D2,WkDfVrT9N19D2,WkDfVrT9N20D2, & - WkDfVrT9N01D3,WkDfVrT9N02D3,WkDfVrT9N03D3,WkDfVrT9N04D3,WkDfVrT9N05D3,WkDfVrT9N06D3,WkDfVrT9N07D3,WkDfVrT9N08D3,WkDfVrT9N09D3,WkDfVrT9N10D3, & - WkDfVrT9N11D3,WkDfVrT9N12D3,WkDfVrT9N13D3,WkDfVrT9N14D3,WkDfVrT9N15D3,WkDfVrT9N16D3,WkDfVrT9N17D3,WkDfVrT9N18D3,WkDfVrT9N19D3,WkDfVrT9N20D3, & - WkDfVrT9N01D4,WkDfVrT9N02D4,WkDfVrT9N03D4,WkDfVrT9N04D4,WkDfVrT9N05D4,WkDfVrT9N06D4,WkDfVrT9N07D4,WkDfVrT9N08D4,WkDfVrT9N09D4,WkDfVrT9N10D4, & - WkDfVrT9N11D4,WkDfVrT9N12D4,WkDfVrT9N13D4,WkDfVrT9N14D4,WkDfVrT9N15D4,WkDfVrT9N16D4,WkDfVrT9N17D4,WkDfVrT9N18D4,WkDfVrT9N19D4,WkDfVrT9N20D4, & - WkDfVrT9N01D5,WkDfVrT9N02D5,WkDfVrT9N03D5,WkDfVrT9N04D5,WkDfVrT9N05D5,WkDfVrT9N06D5,WkDfVrT9N07D5,WkDfVrT9N08D5,WkDfVrT9N09D5,WkDfVrT9N10D5, & - WkDfVrT9N11D5,WkDfVrT9N12D5,WkDfVrT9N13D5,WkDfVrT9N14D5,WkDfVrT9N15D5,WkDfVrT9N16D5,WkDfVrT9N17D5,WkDfVrT9N18D5,WkDfVrT9N19D5,WkDfVrT9N20D5, & - WkDfVrT9N01D6,WkDfVrT9N02D6,WkDfVrT9N03D6,WkDfVrT9N04D6,WkDfVrT9N05D6,WkDfVrT9N06D6,WkDfVrT9N07D6,WkDfVrT9N08D6,WkDfVrT9N09D6,WkDfVrT9N10D6, & - WkDfVrT9N11D6,WkDfVrT9N12D6,WkDfVrT9N13D6,WkDfVrT9N14D6,WkDfVrT9N15D6,WkDfVrT9N16D6,WkDfVrT9N17D6,WkDfVrT9N18D6,WkDfVrT9N19D6,WkDfVrT9N20D6, & - WkDfVrT9N01D7,WkDfVrT9N02D7,WkDfVrT9N03D7,WkDfVrT9N04D7,WkDfVrT9N05D7,WkDfVrT9N06D7,WkDfVrT9N07D7,WkDfVrT9N08D7,WkDfVrT9N09D7,WkDfVrT9N10D7, & - WkDfVrT9N11D7,WkDfVrT9N12D7,WkDfVrT9N13D7,WkDfVrT9N14D7,WkDfVrT9N15D7,WkDfVrT9N16D7,WkDfVrT9N17D7,WkDfVrT9N18D7,WkDfVrT9N19D7,WkDfVrT9N20D7, & - WkDfVrT9N01D8,WkDfVrT9N02D8,WkDfVrT9N03D8,WkDfVrT9N04D8,WkDfVrT9N05D8,WkDfVrT9N06D8,WkDfVrT9N07D8,WkDfVrT9N08D8,WkDfVrT9N09D8,WkDfVrT9N10D8, & - WkDfVrT9N11D8,WkDfVrT9N12D8,WkDfVrT9N13D8,WkDfVrT9N14D8,WkDfVrT9N15D8,WkDfVrT9N16D8,WkDfVrT9N17D8,WkDfVrT9N18D8,WkDfVrT9N19D8,WkDfVrT9N20D8, & - WkDfVrT9N01D9,WkDfVrT9N02D9,WkDfVrT9N03D9,WkDfVrT9N04D9,WkDfVrT9N05D9,WkDfVrT9N06D9,WkDfVrT9N07D9,WkDfVrT9N08D9,WkDfVrT9N09D9,WkDfVrT9N10D9, & - WkDfVrT9N11D9,WkDfVrT9N12D9,WkDfVrT9N13D9,WkDfVrT9N14D9,WkDfVrT9N15D9,WkDfVrT9N16D9,WkDfVrT9N17D9,WkDfVrT9N18D9,WkDfVrT9N19D9,WkDfVrT9N20D9/), (/20,9/) ) - -EddVisTND(:,:,1) = RESHAPE( & - (/EddVisT1N01D1,EddVisT1N02D1,EddVisT1N03D1,EddVisT1N04D1,EddVisT1N05D1,EddVisT1N06D1,EddVisT1N07D1,EddVisT1N08D1,EddVisT1N09D1,EddVisT1N10D1, & - EddVisT1N11D1,EddVisT1N12D1,EddVisT1N13D1,EddVisT1N14D1,EddVisT1N15D1,EddVisT1N16D1,EddVisT1N17D1,EddVisT1N18D1,EddVisT1N19D1,EddVisT1N20D1, & - EddVisT1N01D2,EddVisT1N02D2,EddVisT1N03D2,EddVisT1N04D2,EddVisT1N05D2,EddVisT1N06D2,EddVisT1N07D2,EddVisT1N08D2,EddVisT1N09D2,EddVisT1N10D2, & - EddVisT1N11D2,EddVisT1N12D2,EddVisT1N13D2,EddVisT1N14D2,EddVisT1N15D2,EddVisT1N16D2,EddVisT1N17D2,EddVisT1N18D2,EddVisT1N19D2,EddVisT1N20D2, & - EddVisT1N01D3,EddVisT1N02D3,EddVisT1N03D3,EddVisT1N04D3,EddVisT1N05D3,EddVisT1N06D3,EddVisT1N07D3,EddVisT1N08D3,EddVisT1N09D3,EddVisT1N10D3, & - EddVisT1N11D3,EddVisT1N12D3,EddVisT1N13D3,EddVisT1N14D3,EddVisT1N15D3,EddVisT1N16D3,EddVisT1N17D3,EddVisT1N18D3,EddVisT1N19D3,EddVisT1N20D3, & - EddVisT1N01D4,EddVisT1N02D4,EddVisT1N03D4,EddVisT1N04D4,EddVisT1N05D4,EddVisT1N06D4,EddVisT1N07D4,EddVisT1N08D4,EddVisT1N09D4,EddVisT1N10D4, & - EddVisT1N11D4,EddVisT1N12D4,EddVisT1N13D4,EddVisT1N14D4,EddVisT1N15D4,EddVisT1N16D4,EddVisT1N17D4,EddVisT1N18D4,EddVisT1N19D4,EddVisT1N20D4, & - EddVisT1N01D5,EddVisT1N02D5,EddVisT1N03D5,EddVisT1N04D5,EddVisT1N05D5,EddVisT1N06D5,EddVisT1N07D5,EddVisT1N08D5,EddVisT1N09D5,EddVisT1N10D5, & - EddVisT1N11D5,EddVisT1N12D5,EddVisT1N13D5,EddVisT1N14D5,EddVisT1N15D5,EddVisT1N16D5,EddVisT1N17D5,EddVisT1N18D5,EddVisT1N19D5,EddVisT1N20D5, & - EddVisT1N01D6,EddVisT1N02D6,EddVisT1N03D6,EddVisT1N04D6,EddVisT1N05D6,EddVisT1N06D6,EddVisT1N07D6,EddVisT1N08D6,EddVisT1N09D6,EddVisT1N10D6, & - EddVisT1N11D6,EddVisT1N12D6,EddVisT1N13D6,EddVisT1N14D6,EddVisT1N15D6,EddVisT1N16D6,EddVisT1N17D6,EddVisT1N18D6,EddVisT1N19D6,EddVisT1N20D6, & - EddVisT1N01D7,EddVisT1N02D7,EddVisT1N03D7,EddVisT1N04D7,EddVisT1N05D7,EddVisT1N06D7,EddVisT1N07D7,EddVisT1N08D7,EddVisT1N09D7,EddVisT1N10D7, & - EddVisT1N11D7,EddVisT1N12D7,EddVisT1N13D7,EddVisT1N14D7,EddVisT1N15D7,EddVisT1N16D7,EddVisT1N17D7,EddVisT1N18D7,EddVisT1N19D7,EddVisT1N20D7, & - EddVisT1N01D8,EddVisT1N02D8,EddVisT1N03D8,EddVisT1N04D8,EddVisT1N05D8,EddVisT1N06D8,EddVisT1N07D8,EddVisT1N08D8,EddVisT1N09D8,EddVisT1N10D8, & - EddVisT1N11D8,EddVisT1N12D8,EddVisT1N13D8,EddVisT1N14D8,EddVisT1N15D8,EddVisT1N16D8,EddVisT1N17D8,EddVisT1N18D8,EddVisT1N19D8,EddVisT1N20D8, & - EddVisT1N01D9,EddVisT1N02D9,EddVisT1N03D9,EddVisT1N04D9,EddVisT1N05D9,EddVisT1N06D9,EddVisT1N07D9,EddVisT1N08D9,EddVisT1N09D9,EddVisT1N10D9, & - EddVisT1N11D9,EddVisT1N12D9,EddVisT1N13D9,EddVisT1N14D9,EddVisT1N15D9,EddVisT1N16D9,EddVisT1N17D9,EddVisT1N18D9,EddVisT1N19D9,EddVisT1N20D9/), (/20,9/) ) -EddVisTND(:,:,2) = RESHAPE( & - (/EddVisT2N01D1,EddVisT2N02D1,EddVisT2N03D1,EddVisT2N04D1,EddVisT2N05D1,EddVisT2N06D1,EddVisT2N07D1,EddVisT2N08D1,EddVisT2N09D1,EddVisT2N10D1, & - EddVisT2N11D1,EddVisT2N12D1,EddVisT2N13D1,EddVisT2N14D1,EddVisT2N15D1,EddVisT2N16D1,EddVisT2N17D1,EddVisT2N18D1,EddVisT2N19D1,EddVisT2N20D1, & - EddVisT2N01D2,EddVisT2N02D2,EddVisT2N03D2,EddVisT2N04D2,EddVisT2N05D2,EddVisT2N06D2,EddVisT2N07D2,EddVisT2N08D2,EddVisT2N09D2,EddVisT2N10D2, & - EddVisT2N11D2,EddVisT2N12D2,EddVisT2N13D2,EddVisT2N14D2,EddVisT2N15D2,EddVisT2N16D2,EddVisT2N17D2,EddVisT2N18D2,EddVisT2N19D2,EddVisT2N20D2, & - EddVisT2N01D3,EddVisT2N02D3,EddVisT2N03D3,EddVisT2N04D3,EddVisT2N05D3,EddVisT2N06D3,EddVisT2N07D3,EddVisT2N08D3,EddVisT2N09D3,EddVisT2N10D3, & - EddVisT2N11D3,EddVisT2N12D3,EddVisT2N13D3,EddVisT2N14D3,EddVisT2N15D3,EddVisT2N16D3,EddVisT2N17D3,EddVisT2N18D3,EddVisT2N19D3,EddVisT2N20D3, & - EddVisT2N01D4,EddVisT2N02D4,EddVisT2N03D4,EddVisT2N04D4,EddVisT2N05D4,EddVisT2N06D4,EddVisT2N07D4,EddVisT2N08D4,EddVisT2N09D4,EddVisT2N10D4, & - EddVisT2N11D4,EddVisT2N12D4,EddVisT2N13D4,EddVisT2N14D4,EddVisT2N15D4,EddVisT2N16D4,EddVisT2N17D4,EddVisT2N18D4,EddVisT2N19D4,EddVisT2N20D4, & - EddVisT2N01D5,EddVisT2N02D5,EddVisT2N03D5,EddVisT2N04D5,EddVisT2N05D5,EddVisT2N06D5,EddVisT2N07D5,EddVisT2N08D5,EddVisT2N09D5,EddVisT2N10D5, & - EddVisT2N11D5,EddVisT2N12D5,EddVisT2N13D5,EddVisT2N14D5,EddVisT2N15D5,EddVisT2N16D5,EddVisT2N17D5,EddVisT2N18D5,EddVisT2N19D5,EddVisT2N20D5, & - EddVisT2N01D6,EddVisT2N02D6,EddVisT2N03D6,EddVisT2N04D6,EddVisT2N05D6,EddVisT2N06D6,EddVisT2N07D6,EddVisT2N08D6,EddVisT2N09D6,EddVisT2N10D6, & - EddVisT2N11D6,EddVisT2N12D6,EddVisT2N13D6,EddVisT2N14D6,EddVisT2N15D6,EddVisT2N16D6,EddVisT2N17D6,EddVisT2N18D6,EddVisT2N19D6,EddVisT2N20D6, & - EddVisT2N01D7,EddVisT2N02D7,EddVisT2N03D7,EddVisT2N04D7,EddVisT2N05D7,EddVisT2N06D7,EddVisT2N07D7,EddVisT2N08D7,EddVisT2N09D7,EddVisT2N10D7, & - EddVisT2N11D7,EddVisT2N12D7,EddVisT2N13D7,EddVisT2N14D7,EddVisT2N15D7,EddVisT2N16D7,EddVisT2N17D7,EddVisT2N18D7,EddVisT2N19D7,EddVisT2N20D7, & - EddVisT2N01D8,EddVisT2N02D8,EddVisT2N03D8,EddVisT2N04D8,EddVisT2N05D8,EddVisT2N06D8,EddVisT2N07D8,EddVisT2N08D8,EddVisT2N09D8,EddVisT2N10D8, & - EddVisT2N11D8,EddVisT2N12D8,EddVisT2N13D8,EddVisT2N14D8,EddVisT2N15D8,EddVisT2N16D8,EddVisT2N17D8,EddVisT2N18D8,EddVisT2N19D8,EddVisT2N20D8, & - EddVisT2N01D9,EddVisT2N02D9,EddVisT2N03D9,EddVisT2N04D9,EddVisT2N05D9,EddVisT2N06D9,EddVisT2N07D9,EddVisT2N08D9,EddVisT2N09D9,EddVisT2N10D9, & - EddVisT2N11D9,EddVisT2N12D9,EddVisT2N13D9,EddVisT2N14D9,EddVisT2N15D9,EddVisT2N16D9,EddVisT2N17D9,EddVisT2N18D9,EddVisT2N19D9,EddVisT2N20D9/), (/20,9/) ) -EddVisTND(:,:,3) = RESHAPE( & - (/EddVisT3N01D1,EddVisT3N02D1,EddVisT3N03D1,EddVisT3N04D1,EddVisT3N05D1,EddVisT3N06D1,EddVisT3N07D1,EddVisT3N08D1,EddVisT3N09D1,EddVisT3N10D1, & - EddVisT3N11D1,EddVisT3N12D1,EddVisT3N13D1,EddVisT3N14D1,EddVisT3N15D1,EddVisT3N16D1,EddVisT3N17D1,EddVisT3N18D1,EddVisT3N19D1,EddVisT3N20D1, & - EddVisT3N01D2,EddVisT3N02D2,EddVisT3N03D2,EddVisT3N04D2,EddVisT3N05D2,EddVisT3N06D2,EddVisT3N07D2,EddVisT3N08D2,EddVisT3N09D2,EddVisT3N10D2, & - EddVisT3N11D2,EddVisT3N12D2,EddVisT3N13D2,EddVisT3N14D2,EddVisT3N15D2,EddVisT3N16D2,EddVisT3N17D2,EddVisT3N18D2,EddVisT3N19D2,EddVisT3N20D2, & - EddVisT3N01D3,EddVisT3N02D3,EddVisT3N03D3,EddVisT3N04D3,EddVisT3N05D3,EddVisT3N06D3,EddVisT3N07D3,EddVisT3N08D3,EddVisT3N09D3,EddVisT3N10D3, & - EddVisT3N11D3,EddVisT3N12D3,EddVisT3N13D3,EddVisT3N14D3,EddVisT3N15D3,EddVisT3N16D3,EddVisT3N17D3,EddVisT3N18D3,EddVisT3N19D3,EddVisT3N20D3, & - EddVisT3N01D4,EddVisT3N02D4,EddVisT3N03D4,EddVisT3N04D4,EddVisT3N05D4,EddVisT3N06D4,EddVisT3N07D4,EddVisT3N08D4,EddVisT3N09D4,EddVisT3N10D4, & - EddVisT3N11D4,EddVisT3N12D4,EddVisT3N13D4,EddVisT3N14D4,EddVisT3N15D4,EddVisT3N16D4,EddVisT3N17D4,EddVisT3N18D4,EddVisT3N19D4,EddVisT3N20D4, & - EddVisT3N01D5,EddVisT3N02D5,EddVisT3N03D5,EddVisT3N04D5,EddVisT3N05D5,EddVisT3N06D5,EddVisT3N07D5,EddVisT3N08D5,EddVisT3N09D5,EddVisT3N10D5, & - EddVisT3N11D5,EddVisT3N12D5,EddVisT3N13D5,EddVisT3N14D5,EddVisT3N15D5,EddVisT3N16D5,EddVisT3N17D5,EddVisT3N18D5,EddVisT3N19D5,EddVisT3N20D5, & - EddVisT3N01D6,EddVisT3N02D6,EddVisT3N03D6,EddVisT3N04D6,EddVisT3N05D6,EddVisT3N06D6,EddVisT3N07D6,EddVisT3N08D6,EddVisT3N09D6,EddVisT3N10D6, & - EddVisT3N11D6,EddVisT3N12D6,EddVisT3N13D6,EddVisT3N14D6,EddVisT3N15D6,EddVisT3N16D6,EddVisT3N17D6,EddVisT3N18D6,EddVisT3N19D6,EddVisT3N20D6, & - EddVisT3N01D7,EddVisT3N02D7,EddVisT3N03D7,EddVisT3N04D7,EddVisT3N05D7,EddVisT3N06D7,EddVisT3N07D7,EddVisT3N08D7,EddVisT3N09D7,EddVisT3N10D7, & - EddVisT3N11D7,EddVisT3N12D7,EddVisT3N13D7,EddVisT3N14D7,EddVisT3N15D7,EddVisT3N16D7,EddVisT3N17D7,EddVisT3N18D7,EddVisT3N19D7,EddVisT3N20D7, & - EddVisT3N01D8,EddVisT3N02D8,EddVisT3N03D8,EddVisT3N04D8,EddVisT3N05D8,EddVisT3N06D8,EddVisT3N07D8,EddVisT3N08D8,EddVisT3N09D8,EddVisT3N10D8, & - EddVisT3N11D8,EddVisT3N12D8,EddVisT3N13D8,EddVisT3N14D8,EddVisT3N15D8,EddVisT3N16D8,EddVisT3N17D8,EddVisT3N18D8,EddVisT3N19D8,EddVisT3N20D8, & - EddVisT3N01D9,EddVisT3N02D9,EddVisT3N03D9,EddVisT3N04D9,EddVisT3N05D9,EddVisT3N06D9,EddVisT3N07D9,EddVisT3N08D9,EddVisT3N09D9,EddVisT3N10D9, & - EddVisT3N11D9,EddVisT3N12D9,EddVisT3N13D9,EddVisT3N14D9,EddVisT3N15D9,EddVisT3N16D9,EddVisT3N17D9,EddVisT3N18D9,EddVisT3N19D9,EddVisT3N20D9/), (/20,9/) ) -EddVisTND(:,:,4) = RESHAPE( & - (/EddVisT4N01D1,EddVisT4N02D1,EddVisT4N03D1,EddVisT4N04D1,EddVisT4N05D1,EddVisT4N06D1,EddVisT4N07D1,EddVisT4N08D1,EddVisT4N09D1,EddVisT4N10D1, & - EddVisT4N11D1,EddVisT4N12D1,EddVisT4N13D1,EddVisT4N14D1,EddVisT4N15D1,EddVisT4N16D1,EddVisT4N17D1,EddVisT4N18D1,EddVisT4N19D1,EddVisT4N20D1, & - EddVisT4N01D2,EddVisT4N02D2,EddVisT4N03D2,EddVisT4N04D2,EddVisT4N05D2,EddVisT4N06D2,EddVisT4N07D2,EddVisT4N08D2,EddVisT4N09D2,EddVisT4N10D2, & - EddVisT4N11D2,EddVisT4N12D2,EddVisT4N13D2,EddVisT4N14D2,EddVisT4N15D2,EddVisT4N16D2,EddVisT4N17D2,EddVisT4N18D2,EddVisT4N19D2,EddVisT4N20D2, & - EddVisT4N01D3,EddVisT4N02D3,EddVisT4N03D3,EddVisT4N04D3,EddVisT4N05D3,EddVisT4N06D3,EddVisT4N07D3,EddVisT4N08D3,EddVisT4N09D3,EddVisT4N10D3, & - EddVisT4N11D3,EddVisT4N12D3,EddVisT4N13D3,EddVisT4N14D3,EddVisT4N15D3,EddVisT4N16D3,EddVisT4N17D3,EddVisT4N18D3,EddVisT4N19D3,EddVisT4N20D3, & - EddVisT4N01D4,EddVisT4N02D4,EddVisT4N03D4,EddVisT4N04D4,EddVisT4N05D4,EddVisT4N06D4,EddVisT4N07D4,EddVisT4N08D4,EddVisT4N09D4,EddVisT4N10D4, & - EddVisT4N11D4,EddVisT4N12D4,EddVisT4N13D4,EddVisT4N14D4,EddVisT4N15D4,EddVisT4N16D4,EddVisT4N17D4,EddVisT4N18D4,EddVisT4N19D4,EddVisT4N20D4, & - EddVisT4N01D5,EddVisT4N02D5,EddVisT4N03D5,EddVisT4N04D5,EddVisT4N05D5,EddVisT4N06D5,EddVisT4N07D5,EddVisT4N08D5,EddVisT4N09D5,EddVisT4N10D5, & - EddVisT4N11D5,EddVisT4N12D5,EddVisT4N13D5,EddVisT4N14D5,EddVisT4N15D5,EddVisT4N16D5,EddVisT4N17D5,EddVisT4N18D5,EddVisT4N19D5,EddVisT4N20D5, & - EddVisT4N01D6,EddVisT4N02D6,EddVisT4N03D6,EddVisT4N04D6,EddVisT4N05D6,EddVisT4N06D6,EddVisT4N07D6,EddVisT4N08D6,EddVisT4N09D6,EddVisT4N10D6, & - EddVisT4N11D6,EddVisT4N12D6,EddVisT4N13D6,EddVisT4N14D6,EddVisT4N15D6,EddVisT4N16D6,EddVisT4N17D6,EddVisT4N18D6,EddVisT4N19D6,EddVisT4N20D6, & - EddVisT4N01D7,EddVisT4N02D7,EddVisT4N03D7,EddVisT4N04D7,EddVisT4N05D7,EddVisT4N06D7,EddVisT4N07D7,EddVisT4N08D7,EddVisT4N09D7,EddVisT4N10D7, & - EddVisT4N11D7,EddVisT4N12D7,EddVisT4N13D7,EddVisT4N14D7,EddVisT4N15D7,EddVisT4N16D7,EddVisT4N17D7,EddVisT4N18D7,EddVisT4N19D7,EddVisT4N20D7, & - EddVisT4N01D8,EddVisT4N02D8,EddVisT4N03D8,EddVisT4N04D8,EddVisT4N05D8,EddVisT4N06D8,EddVisT4N07D8,EddVisT4N08D8,EddVisT4N09D8,EddVisT4N10D8, & - EddVisT4N11D8,EddVisT4N12D8,EddVisT4N13D8,EddVisT4N14D8,EddVisT4N15D8,EddVisT4N16D8,EddVisT4N17D8,EddVisT4N18D8,EddVisT4N19D8,EddVisT4N20D8, & - EddVisT4N01D9,EddVisT4N02D9,EddVisT4N03D9,EddVisT4N04D9,EddVisT4N05D9,EddVisT4N06D9,EddVisT4N07D9,EddVisT4N08D9,EddVisT4N09D9,EddVisT4N10D9, & - EddVisT4N11D9,EddVisT4N12D9,EddVisT4N13D9,EddVisT4N14D9,EddVisT4N15D9,EddVisT4N16D9,EddVisT4N17D9,EddVisT4N18D9,EddVisT4N19D9,EddVisT4N20D9/), (/20,9/) ) - -EddVisTND(:,:,5) = RESHAPE( & - (/EddVisT5N01D1,EddVisT5N02D1,EddVisT5N03D1,EddVisT5N04D1,EddVisT5N05D1,EddVisT5N06D1,EddVisT5N07D1,EddVisT5N08D1,EddVisT5N09D1,EddVisT5N10D1, & - EddVisT5N11D1,EddVisT5N12D1,EddVisT5N13D1,EddVisT5N14D1,EddVisT5N15D1,EddVisT5N16D1,EddVisT5N17D1,EddVisT5N18D1,EddVisT5N19D1,EddVisT5N20D1, & - EddVisT5N01D2,EddVisT5N02D2,EddVisT5N03D2,EddVisT5N04D2,EddVisT5N05D2,EddVisT5N06D2,EddVisT5N07D2,EddVisT5N08D2,EddVisT5N09D2,EddVisT5N10D2, & - EddVisT5N11D2,EddVisT5N12D2,EddVisT5N13D2,EddVisT5N14D2,EddVisT5N15D2,EddVisT5N16D2,EddVisT5N17D2,EddVisT5N18D2,EddVisT5N19D2,EddVisT5N20D2, & - EddVisT5N01D3,EddVisT5N02D3,EddVisT5N03D3,EddVisT5N04D3,EddVisT5N05D3,EddVisT5N06D3,EddVisT5N07D3,EddVisT5N08D3,EddVisT5N09D3,EddVisT5N10D3, & - EddVisT5N11D3,EddVisT5N12D3,EddVisT5N13D3,EddVisT5N14D3,EddVisT5N15D3,EddVisT5N16D3,EddVisT5N17D3,EddVisT5N18D3,EddVisT5N19D3,EddVisT5N20D3, & - EddVisT5N01D4,EddVisT5N02D4,EddVisT5N03D4,EddVisT5N04D4,EddVisT5N05D4,EddVisT5N06D4,EddVisT5N07D4,EddVisT5N08D4,EddVisT5N09D4,EddVisT5N10D4, & - EddVisT5N11D4,EddVisT5N12D4,EddVisT5N13D4,EddVisT5N14D4,EddVisT5N15D4,EddVisT5N16D4,EddVisT5N17D4,EddVisT5N18D4,EddVisT5N19D4,EddVisT5N20D4, & - EddVisT5N01D5,EddVisT5N02D5,EddVisT5N03D5,EddVisT5N04D5,EddVisT5N05D5,EddVisT5N06D5,EddVisT5N07D5,EddVisT5N08D5,EddVisT5N09D5,EddVisT5N10D5, & - EddVisT5N11D5,EddVisT5N12D5,EddVisT5N13D5,EddVisT5N14D5,EddVisT5N15D5,EddVisT5N16D5,EddVisT5N17D5,EddVisT5N18D5,EddVisT5N19D5,EddVisT5N20D5, & - EddVisT5N01D6,EddVisT5N02D6,EddVisT5N03D6,EddVisT5N04D6,EddVisT5N05D6,EddVisT5N06D6,EddVisT5N07D6,EddVisT5N08D6,EddVisT5N09D6,EddVisT5N10D6, & - EddVisT5N11D6,EddVisT5N12D6,EddVisT5N13D6,EddVisT5N14D6,EddVisT5N15D6,EddVisT5N16D6,EddVisT5N17D6,EddVisT5N18D6,EddVisT5N19D6,EddVisT5N20D6, & - EddVisT5N01D7,EddVisT5N02D7,EddVisT5N03D7,EddVisT5N04D7,EddVisT5N05D7,EddVisT5N06D7,EddVisT5N07D7,EddVisT5N08D7,EddVisT5N09D7,EddVisT5N10D7, & - EddVisT5N11D7,EddVisT5N12D7,EddVisT5N13D7,EddVisT5N14D7,EddVisT5N15D7,EddVisT5N16D7,EddVisT5N17D7,EddVisT5N18D7,EddVisT5N19D7,EddVisT5N20D7, & - EddVisT5N01D8,EddVisT5N02D8,EddVisT5N03D8,EddVisT5N04D8,EddVisT5N05D8,EddVisT5N06D8,EddVisT5N07D8,EddVisT5N08D8,EddVisT5N09D8,EddVisT5N10D8, & - EddVisT5N11D8,EddVisT5N12D8,EddVisT5N13D8,EddVisT5N14D8,EddVisT5N15D8,EddVisT5N16D8,EddVisT5N17D8,EddVisT5N18D8,EddVisT5N19D8,EddVisT5N20D8, & - EddVisT5N01D9,EddVisT5N02D9,EddVisT5N03D9,EddVisT5N04D9,EddVisT5N05D9,EddVisT5N06D9,EddVisT5N07D9,EddVisT5N08D9,EddVisT5N09D9,EddVisT5N10D9, & - EddVisT5N11D9,EddVisT5N12D9,EddVisT5N13D9,EddVisT5N14D9,EddVisT5N15D9,EddVisT5N16D9,EddVisT5N17D9,EddVisT5N18D9,EddVisT5N19D9,EddVisT5N20D9/), (/20,9/) ) -EddVisTND(:,:,6) = RESHAPE( & - (/EddVisT6N01D1,EddVisT6N02D1,EddVisT6N03D1,EddVisT6N04D1,EddVisT6N05D1,EddVisT6N06D1,EddVisT6N07D1,EddVisT6N08D1,EddVisT6N09D1,EddVisT6N10D1, & - EddVisT6N11D1,EddVisT6N12D1,EddVisT6N13D1,EddVisT6N14D1,EddVisT6N15D1,EddVisT6N16D1,EddVisT6N17D1,EddVisT6N18D1,EddVisT6N19D1,EddVisT6N20D1, & - EddVisT6N01D2,EddVisT6N02D2,EddVisT6N03D2,EddVisT6N04D2,EddVisT6N05D2,EddVisT6N06D2,EddVisT6N07D2,EddVisT6N08D2,EddVisT6N09D2,EddVisT6N10D2, & - EddVisT6N11D2,EddVisT6N12D2,EddVisT6N13D2,EddVisT6N14D2,EddVisT6N15D2,EddVisT6N16D2,EddVisT6N17D2,EddVisT6N18D2,EddVisT6N19D2,EddVisT6N20D2, & - EddVisT6N01D3,EddVisT6N02D3,EddVisT6N03D3,EddVisT6N04D3,EddVisT6N05D3,EddVisT6N06D3,EddVisT6N07D3,EddVisT6N08D3,EddVisT6N09D3,EddVisT6N10D3, & - EddVisT6N11D3,EddVisT6N12D3,EddVisT6N13D3,EddVisT6N14D3,EddVisT6N15D3,EddVisT6N16D3,EddVisT6N17D3,EddVisT6N18D3,EddVisT6N19D3,EddVisT6N20D3, & - EddVisT6N01D4,EddVisT6N02D4,EddVisT6N03D4,EddVisT6N04D4,EddVisT6N05D4,EddVisT6N06D4,EddVisT6N07D4,EddVisT6N08D4,EddVisT6N09D4,EddVisT6N10D4, & - EddVisT6N11D4,EddVisT6N12D4,EddVisT6N13D4,EddVisT6N14D4,EddVisT6N15D4,EddVisT6N16D4,EddVisT6N17D4,EddVisT6N18D4,EddVisT6N19D4,EddVisT6N20D4, & - EddVisT6N01D5,EddVisT6N02D5,EddVisT6N03D5,EddVisT6N04D5,EddVisT6N05D5,EddVisT6N06D5,EddVisT6N07D5,EddVisT6N08D5,EddVisT6N09D5,EddVisT6N10D5, & - EddVisT6N11D5,EddVisT6N12D5,EddVisT6N13D5,EddVisT6N14D5,EddVisT6N15D5,EddVisT6N16D5,EddVisT6N17D5,EddVisT6N18D5,EddVisT6N19D5,EddVisT6N20D5, & - EddVisT6N01D6,EddVisT6N02D6,EddVisT6N03D6,EddVisT6N04D6,EddVisT6N05D6,EddVisT6N06D6,EddVisT6N07D6,EddVisT6N08D6,EddVisT6N09D6,EddVisT6N10D6, & - EddVisT6N11D6,EddVisT6N12D6,EddVisT6N13D6,EddVisT6N14D6,EddVisT6N15D6,EddVisT6N16D6,EddVisT6N17D6,EddVisT6N18D6,EddVisT6N19D6,EddVisT6N20D6, & - EddVisT6N01D7,EddVisT6N02D7,EddVisT6N03D7,EddVisT6N04D7,EddVisT6N05D7,EddVisT6N06D7,EddVisT6N07D7,EddVisT6N08D7,EddVisT6N09D7,EddVisT6N10D7, & - EddVisT6N11D7,EddVisT6N12D7,EddVisT6N13D7,EddVisT6N14D7,EddVisT6N15D7,EddVisT6N16D7,EddVisT6N17D7,EddVisT6N18D7,EddVisT6N19D7,EddVisT6N20D7, & - EddVisT6N01D8,EddVisT6N02D8,EddVisT6N03D8,EddVisT6N04D8,EddVisT6N05D8,EddVisT6N06D8,EddVisT6N07D8,EddVisT6N08D8,EddVisT6N09D8,EddVisT6N10D8, & - EddVisT6N11D8,EddVisT6N12D8,EddVisT6N13D8,EddVisT6N14D8,EddVisT6N15D8,EddVisT6N16D8,EddVisT6N17D8,EddVisT6N18D8,EddVisT6N19D8,EddVisT6N20D8, & - EddVisT6N01D9,EddVisT6N02D9,EddVisT6N03D9,EddVisT6N04D9,EddVisT6N05D9,EddVisT6N06D9,EddVisT6N07D9,EddVisT6N08D9,EddVisT6N09D9,EddVisT6N10D9, & - EddVisT6N11D9,EddVisT6N12D9,EddVisT6N13D9,EddVisT6N14D9,EddVisT6N15D9,EddVisT6N16D9,EddVisT6N17D9,EddVisT6N18D9,EddVisT6N19D9,EddVisT6N20D9/), (/20,9/) ) -EddVisTND(:,:,7) = RESHAPE( & - (/EddVisT7N01D1,EddVisT7N02D1,EddVisT7N03D1,EddVisT7N04D1,EddVisT7N05D1,EddVisT7N06D1,EddVisT7N07D1,EddVisT7N08D1,EddVisT7N09D1,EddVisT7N10D1, & - EddVisT7N11D1,EddVisT7N12D1,EddVisT7N13D1,EddVisT7N14D1,EddVisT7N15D1,EddVisT7N16D1,EddVisT7N17D1,EddVisT7N18D1,EddVisT7N19D1,EddVisT7N20D1, & - EddVisT7N01D2,EddVisT7N02D2,EddVisT7N03D2,EddVisT7N04D2,EddVisT7N05D2,EddVisT7N06D2,EddVisT7N07D2,EddVisT7N08D2,EddVisT7N09D2,EddVisT7N10D2, & - EddVisT7N11D2,EddVisT7N12D2,EddVisT7N13D2,EddVisT7N14D2,EddVisT7N15D2,EddVisT7N16D2,EddVisT7N17D2,EddVisT7N18D2,EddVisT7N19D2,EddVisT7N20D2, & - EddVisT7N01D3,EddVisT7N02D3,EddVisT7N03D3,EddVisT7N04D3,EddVisT7N05D3,EddVisT7N06D3,EddVisT7N07D3,EddVisT7N08D3,EddVisT7N09D3,EddVisT7N10D3, & - EddVisT7N11D3,EddVisT7N12D3,EddVisT7N13D3,EddVisT7N14D3,EddVisT7N15D3,EddVisT7N16D3,EddVisT7N17D3,EddVisT7N18D3,EddVisT7N19D3,EddVisT7N20D3, & - EddVisT7N01D4,EddVisT7N02D4,EddVisT7N03D4,EddVisT7N04D4,EddVisT7N05D4,EddVisT7N06D4,EddVisT7N07D4,EddVisT7N08D4,EddVisT7N09D4,EddVisT7N10D4, & - EddVisT7N11D4,EddVisT7N12D4,EddVisT7N13D4,EddVisT7N14D4,EddVisT7N15D4,EddVisT7N16D4,EddVisT7N17D4,EddVisT7N18D4,EddVisT7N19D4,EddVisT7N20D4, & - EddVisT7N01D5,EddVisT7N02D5,EddVisT7N03D5,EddVisT7N04D5,EddVisT7N05D5,EddVisT7N06D5,EddVisT7N07D5,EddVisT7N08D5,EddVisT7N09D5,EddVisT7N10D5, & - EddVisT7N11D5,EddVisT7N12D5,EddVisT7N13D5,EddVisT7N14D5,EddVisT7N15D5,EddVisT7N16D5,EddVisT7N17D5,EddVisT7N18D5,EddVisT7N19D5,EddVisT7N20D5, & - EddVisT7N01D6,EddVisT7N02D6,EddVisT7N03D6,EddVisT7N04D6,EddVisT7N05D6,EddVisT7N06D6,EddVisT7N07D6,EddVisT7N08D6,EddVisT7N09D6,EddVisT7N10D6, & - EddVisT7N11D6,EddVisT7N12D6,EddVisT7N13D6,EddVisT7N14D6,EddVisT7N15D6,EddVisT7N16D6,EddVisT7N17D6,EddVisT7N18D6,EddVisT7N19D6,EddVisT7N20D6, & - EddVisT7N01D7,EddVisT7N02D7,EddVisT7N03D7,EddVisT7N04D7,EddVisT7N05D7,EddVisT7N06D7,EddVisT7N07D7,EddVisT7N08D7,EddVisT7N09D7,EddVisT7N10D7, & - EddVisT7N11D7,EddVisT7N12D7,EddVisT7N13D7,EddVisT7N14D7,EddVisT7N15D7,EddVisT7N16D7,EddVisT7N17D7,EddVisT7N18D7,EddVisT7N19D7,EddVisT7N20D7, & - EddVisT7N01D8,EddVisT7N02D8,EddVisT7N03D8,EddVisT7N04D8,EddVisT7N05D8,EddVisT7N06D8,EddVisT7N07D8,EddVisT7N08D8,EddVisT7N09D8,EddVisT7N10D8, & - EddVisT7N11D8,EddVisT7N12D8,EddVisT7N13D8,EddVisT7N14D8,EddVisT7N15D8,EddVisT7N16D8,EddVisT7N17D8,EddVisT7N18D8,EddVisT7N19D8,EddVisT7N20D8, & - EddVisT7N01D9,EddVisT7N02D9,EddVisT7N03D9,EddVisT7N04D9,EddVisT7N05D9,EddVisT7N06D9,EddVisT7N07D9,EddVisT7N08D9,EddVisT7N09D9,EddVisT7N10D9, & - EddVisT7N11D9,EddVisT7N12D9,EddVisT7N13D9,EddVisT7N14D9,EddVisT7N15D9,EddVisT7N16D9,EddVisT7N17D9,EddVisT7N18D9,EddVisT7N19D9,EddVisT7N20D9/), (/20,9/) ) -EddVisTND(:,:,8) = RESHAPE( & - (/EddVisT8N01D1,EddVisT8N02D1,EddVisT8N03D1,EddVisT8N04D1,EddVisT8N05D1,EddVisT8N06D1,EddVisT8N07D1,EddVisT8N08D1,EddVisT8N09D1,EddVisT8N10D1, & - EddVisT8N11D1,EddVisT8N12D1,EddVisT8N13D1,EddVisT8N14D1,EddVisT8N15D1,EddVisT8N16D1,EddVisT8N17D1,EddVisT8N18D1,EddVisT8N19D1,EddVisT8N20D1, & - EddVisT8N01D2,EddVisT8N02D2,EddVisT8N03D2,EddVisT8N04D2,EddVisT8N05D2,EddVisT8N06D2,EddVisT8N07D2,EddVisT8N08D2,EddVisT8N09D2,EddVisT8N10D2, & - EddVisT8N11D2,EddVisT8N12D2,EddVisT8N13D2,EddVisT8N14D2,EddVisT8N15D2,EddVisT8N16D2,EddVisT8N17D2,EddVisT8N18D2,EddVisT8N19D2,EddVisT8N20D2, & - EddVisT8N01D3,EddVisT8N02D3,EddVisT8N03D3,EddVisT8N04D3,EddVisT8N05D3,EddVisT8N06D3,EddVisT8N07D3,EddVisT8N08D3,EddVisT8N09D3,EddVisT8N10D3, & - EddVisT8N11D3,EddVisT8N12D3,EddVisT8N13D3,EddVisT8N14D3,EddVisT8N15D3,EddVisT8N16D3,EddVisT8N17D3,EddVisT8N18D3,EddVisT8N19D3,EddVisT8N20D3, & - EddVisT8N01D4,EddVisT8N02D4,EddVisT8N03D4,EddVisT8N04D4,EddVisT8N05D4,EddVisT8N06D4,EddVisT8N07D4,EddVisT8N08D4,EddVisT8N09D4,EddVisT8N10D4, & - EddVisT8N11D4,EddVisT8N12D4,EddVisT8N13D4,EddVisT8N14D4,EddVisT8N15D4,EddVisT8N16D4,EddVisT8N17D4,EddVisT8N18D4,EddVisT8N19D4,EddVisT8N20D4, & - EddVisT8N01D5,EddVisT8N02D5,EddVisT8N03D5,EddVisT8N04D5,EddVisT8N05D5,EddVisT8N06D5,EddVisT8N07D5,EddVisT8N08D5,EddVisT8N09D5,EddVisT8N10D5, & - EddVisT8N11D5,EddVisT8N12D5,EddVisT8N13D5,EddVisT8N14D5,EddVisT8N15D5,EddVisT8N16D5,EddVisT8N17D5,EddVisT8N18D5,EddVisT8N19D5,EddVisT8N20D5, & - EddVisT8N01D6,EddVisT8N02D6,EddVisT8N03D6,EddVisT8N04D6,EddVisT8N05D6,EddVisT8N06D6,EddVisT8N07D6,EddVisT8N08D6,EddVisT8N09D6,EddVisT8N10D6, & - EddVisT8N11D6,EddVisT8N12D6,EddVisT8N13D6,EddVisT8N14D6,EddVisT8N15D6,EddVisT8N16D6,EddVisT8N17D6,EddVisT8N18D6,EddVisT8N19D6,EddVisT8N20D6, & - EddVisT8N01D7,EddVisT8N02D7,EddVisT8N03D7,EddVisT8N04D7,EddVisT8N05D7,EddVisT8N06D7,EddVisT8N07D7,EddVisT8N08D7,EddVisT8N09D7,EddVisT8N10D7, & - EddVisT8N11D7,EddVisT8N12D7,EddVisT8N13D7,EddVisT8N14D7,EddVisT8N15D7,EddVisT8N16D7,EddVisT8N17D7,EddVisT8N18D7,EddVisT8N19D7,EddVisT8N20D7, & - EddVisT8N01D8,EddVisT8N02D8,EddVisT8N03D8,EddVisT8N04D8,EddVisT8N05D8,EddVisT8N06D8,EddVisT8N07D8,EddVisT8N08D8,EddVisT8N09D8,EddVisT8N10D8, & - EddVisT8N11D8,EddVisT8N12D8,EddVisT8N13D8,EddVisT8N14D8,EddVisT8N15D8,EddVisT8N16D8,EddVisT8N17D8,EddVisT8N18D8,EddVisT8N19D8,EddVisT8N20D8, & - EddVisT8N01D9,EddVisT8N02D9,EddVisT8N03D9,EddVisT8N04D9,EddVisT8N05D9,EddVisT8N06D9,EddVisT8N07D9,EddVisT8N08D9,EddVisT8N09D9,EddVisT8N10D9, & - EddVisT8N11D9,EddVisT8N12D9,EddVisT8N13D9,EddVisT8N14D9,EddVisT8N15D9,EddVisT8N16D9,EddVisT8N17D9,EddVisT8N18D9,EddVisT8N19D9,EddVisT8N20D9/), (/20,9/) ) -EddVisTND(:,:,9) = RESHAPE( & - (/EddVisT9N01D1,EddVisT9N02D1,EddVisT9N03D1,EddVisT9N04D1,EddVisT9N05D1,EddVisT9N06D1,EddVisT9N07D1,EddVisT9N08D1,EddVisT9N09D1,EddVisT9N10D1, & - EddVisT9N11D1,EddVisT9N12D1,EddVisT9N13D1,EddVisT9N14D1,EddVisT9N15D1,EddVisT9N16D1,EddVisT9N17D1,EddVisT9N18D1,EddVisT9N19D1,EddVisT9N20D1, & - EddVisT9N01D2,EddVisT9N02D2,EddVisT9N03D2,EddVisT9N04D2,EddVisT9N05D2,EddVisT9N06D2,EddVisT9N07D2,EddVisT9N08D2,EddVisT9N09D2,EddVisT9N10D2, & - EddVisT9N11D2,EddVisT9N12D2,EddVisT9N13D2,EddVisT9N14D2,EddVisT9N15D2,EddVisT9N16D2,EddVisT9N17D2,EddVisT9N18D2,EddVisT9N19D2,EddVisT9N20D2, & - EddVisT9N01D3,EddVisT9N02D3,EddVisT9N03D3,EddVisT9N04D3,EddVisT9N05D3,EddVisT9N06D3,EddVisT9N07D3,EddVisT9N08D3,EddVisT9N09D3,EddVisT9N10D3, & - EddVisT9N11D3,EddVisT9N12D3,EddVisT9N13D3,EddVisT9N14D3,EddVisT9N15D3,EddVisT9N16D3,EddVisT9N17D3,EddVisT9N18D3,EddVisT9N19D3,EddVisT9N20D3, & - EddVisT9N01D4,EddVisT9N02D4,EddVisT9N03D4,EddVisT9N04D4,EddVisT9N05D4,EddVisT9N06D4,EddVisT9N07D4,EddVisT9N08D4,EddVisT9N09D4,EddVisT9N10D4, & - EddVisT9N11D4,EddVisT9N12D4,EddVisT9N13D4,EddVisT9N14D4,EddVisT9N15D4,EddVisT9N16D4,EddVisT9N17D4,EddVisT9N18D4,EddVisT9N19D4,EddVisT9N20D4, & - EddVisT9N01D5,EddVisT9N02D5,EddVisT9N03D5,EddVisT9N04D5,EddVisT9N05D5,EddVisT9N06D5,EddVisT9N07D5,EddVisT9N08D5,EddVisT9N09D5,EddVisT9N10D5, & - EddVisT9N11D5,EddVisT9N12D5,EddVisT9N13D5,EddVisT9N14D5,EddVisT9N15D5,EddVisT9N16D5,EddVisT9N17D5,EddVisT9N18D5,EddVisT9N19D5,EddVisT9N20D5, & - EddVisT9N01D6,EddVisT9N02D6,EddVisT9N03D6,EddVisT9N04D6,EddVisT9N05D6,EddVisT9N06D6,EddVisT9N07D6,EddVisT9N08D6,EddVisT9N09D6,EddVisT9N10D6, & - EddVisT9N11D6,EddVisT9N12D6,EddVisT9N13D6,EddVisT9N14D6,EddVisT9N15D6,EddVisT9N16D6,EddVisT9N17D6,EddVisT9N18D6,EddVisT9N19D6,EddVisT9N20D6, & - EddVisT9N01D7,EddVisT9N02D7,EddVisT9N03D7,EddVisT9N04D7,EddVisT9N05D7,EddVisT9N06D7,EddVisT9N07D7,EddVisT9N08D7,EddVisT9N09D7,EddVisT9N10D7, & - EddVisT9N11D7,EddVisT9N12D7,EddVisT9N13D7,EddVisT9N14D7,EddVisT9N15D7,EddVisT9N16D7,EddVisT9N17D7,EddVisT9N18D7,EddVisT9N19D7,EddVisT9N20D7, & - EddVisT9N01D8,EddVisT9N02D8,EddVisT9N03D8,EddVisT9N04D8,EddVisT9N05D8,EddVisT9N06D8,EddVisT9N07D8,EddVisT9N08D8,EddVisT9N09D8,EddVisT9N10D8, & - EddVisT9N11D8,EddVisT9N12D8,EddVisT9N13D8,EddVisT9N14D8,EddVisT9N15D8,EddVisT9N16D8,EddVisT9N17D8,EddVisT9N18D8,EddVisT9N19D8,EddVisT9N20D8, & - EddVisT9N01D9,EddVisT9N02D9,EddVisT9N03D9,EddVisT9N04D9,EddVisT9N05D9,EddVisT9N06D9,EddVisT9N07D9,EddVisT9N08D9,EddVisT9N09D9,EddVisT9N10D9, & - EddVisT9N11D9,EddVisT9N12D9,EddVisT9N13D9,EddVisT9N14D9,EddVisT9N15D9,EddVisT9N16D9,EddVisT9N17D9,EddVisT9N18D9,EddVisT9N19D9,EddVisT9N20D9/), (/20,9/) ) - - -EddAmbTND(:,:,1) = RESHAPE( & - (/EddAmbT1N01D1,EddAmbT1N02D1,EddAmbT1N03D1,EddAmbT1N04D1,EddAmbT1N05D1,EddAmbT1N06D1,EddAmbT1N07D1,EddAmbT1N08D1,EddAmbT1N09D1,EddAmbT1N10D1, & - EddAmbT1N11D1,EddAmbT1N12D1,EddAmbT1N13D1,EddAmbT1N14D1,EddAmbT1N15D1,EddAmbT1N16D1,EddAmbT1N17D1,EddAmbT1N18D1,EddAmbT1N19D1,EddAmbT1N20D1, & - EddAmbT1N01D2,EddAmbT1N02D2,EddAmbT1N03D2,EddAmbT1N04D2,EddAmbT1N05D2,EddAmbT1N06D2,EddAmbT1N07D2,EddAmbT1N08D2,EddAmbT1N09D2,EddAmbT1N10D2, & - EddAmbT1N11D2,EddAmbT1N12D2,EddAmbT1N13D2,EddAmbT1N14D2,EddAmbT1N15D2,EddAmbT1N16D2,EddAmbT1N17D2,EddAmbT1N18D2,EddAmbT1N19D2,EddAmbT1N20D2, & - EddAmbT1N01D3,EddAmbT1N02D3,EddAmbT1N03D3,EddAmbT1N04D3,EddAmbT1N05D3,EddAmbT1N06D3,EddAmbT1N07D3,EddAmbT1N08D3,EddAmbT1N09D3,EddAmbT1N10D3, & - EddAmbT1N11D3,EddAmbT1N12D3,EddAmbT1N13D3,EddAmbT1N14D3,EddAmbT1N15D3,EddAmbT1N16D3,EddAmbT1N17D3,EddAmbT1N18D3,EddAmbT1N19D3,EddAmbT1N20D3, & - EddAmbT1N01D4,EddAmbT1N02D4,EddAmbT1N03D4,EddAmbT1N04D4,EddAmbT1N05D4,EddAmbT1N06D4,EddAmbT1N07D4,EddAmbT1N08D4,EddAmbT1N09D4,EddAmbT1N10D4, & - EddAmbT1N11D4,EddAmbT1N12D4,EddAmbT1N13D4,EddAmbT1N14D4,EddAmbT1N15D4,EddAmbT1N16D4,EddAmbT1N17D4,EddAmbT1N18D4,EddAmbT1N19D4,EddAmbT1N20D4, & - EddAmbT1N01D5,EddAmbT1N02D5,EddAmbT1N03D5,EddAmbT1N04D5,EddAmbT1N05D5,EddAmbT1N06D5,EddAmbT1N07D5,EddAmbT1N08D5,EddAmbT1N09D5,EddAmbT1N10D5, & - EddAmbT1N11D5,EddAmbT1N12D5,EddAmbT1N13D5,EddAmbT1N14D5,EddAmbT1N15D5,EddAmbT1N16D5,EddAmbT1N17D5,EddAmbT1N18D5,EddAmbT1N19D5,EddAmbT1N20D5, & - EddAmbT1N01D6,EddAmbT1N02D6,EddAmbT1N03D6,EddAmbT1N04D6,EddAmbT1N05D6,EddAmbT1N06D6,EddAmbT1N07D6,EddAmbT1N08D6,EddAmbT1N09D6,EddAmbT1N10D6, & - EddAmbT1N11D6,EddAmbT1N12D6,EddAmbT1N13D6,EddAmbT1N14D6,EddAmbT1N15D6,EddAmbT1N16D6,EddAmbT1N17D6,EddAmbT1N18D6,EddAmbT1N19D6,EddAmbT1N20D6, & - EddAmbT1N01D7,EddAmbT1N02D7,EddAmbT1N03D7,EddAmbT1N04D7,EddAmbT1N05D7,EddAmbT1N06D7,EddAmbT1N07D7,EddAmbT1N08D7,EddAmbT1N09D7,EddAmbT1N10D7, & - EddAmbT1N11D7,EddAmbT1N12D7,EddAmbT1N13D7,EddAmbT1N14D7,EddAmbT1N15D7,EddAmbT1N16D7,EddAmbT1N17D7,EddAmbT1N18D7,EddAmbT1N19D7,EddAmbT1N20D7, & - EddAmbT1N01D8,EddAmbT1N02D8,EddAmbT1N03D8,EddAmbT1N04D8,EddAmbT1N05D8,EddAmbT1N06D8,EddAmbT1N07D8,EddAmbT1N08D8,EddAmbT1N09D8,EddAmbT1N10D8, & - EddAmbT1N11D8,EddAmbT1N12D8,EddAmbT1N13D8,EddAmbT1N14D8,EddAmbT1N15D8,EddAmbT1N16D8,EddAmbT1N17D8,EddAmbT1N18D8,EddAmbT1N19D8,EddAmbT1N20D8, & - EddAmbT1N01D9,EddAmbT1N02D9,EddAmbT1N03D9,EddAmbT1N04D9,EddAmbT1N05D9,EddAmbT1N06D9,EddAmbT1N07D9,EddAmbT1N08D9,EddAmbT1N09D9,EddAmbT1N10D9, & - EddAmbT1N11D9,EddAmbT1N12D9,EddAmbT1N13D9,EddAmbT1N14D9,EddAmbT1N15D9,EddAmbT1N16D9,EddAmbT1N17D9,EddAmbT1N18D9,EddAmbT1N19D9,EddAmbT1N20D9/), (/20,9/) ) -EddAmbTND(:,:,2) = RESHAPE( & - (/EddAmbT2N01D1,EddAmbT2N02D1,EddAmbT2N03D1,EddAmbT2N04D1,EddAmbT2N05D1,EddAmbT2N06D1,EddAmbT2N07D1,EddAmbT2N08D1,EddAmbT2N09D1,EddAmbT2N10D1, & - EddAmbT2N11D1,EddAmbT2N12D1,EddAmbT2N13D1,EddAmbT2N14D1,EddAmbT2N15D1,EddAmbT2N16D1,EddAmbT2N17D1,EddAmbT2N18D1,EddAmbT2N19D1,EddAmbT2N20D1, & - EddAmbT2N01D2,EddAmbT2N02D2,EddAmbT2N03D2,EddAmbT2N04D2,EddAmbT2N05D2,EddAmbT2N06D2,EddAmbT2N07D2,EddAmbT2N08D2,EddAmbT2N09D2,EddAmbT2N10D2, & - EddAmbT2N11D2,EddAmbT2N12D2,EddAmbT2N13D2,EddAmbT2N14D2,EddAmbT2N15D2,EddAmbT2N16D2,EddAmbT2N17D2,EddAmbT2N18D2,EddAmbT2N19D2,EddAmbT2N20D2, & - EddAmbT2N01D3,EddAmbT2N02D3,EddAmbT2N03D3,EddAmbT2N04D3,EddAmbT2N05D3,EddAmbT2N06D3,EddAmbT2N07D3,EddAmbT2N08D3,EddAmbT2N09D3,EddAmbT2N10D3, & - EddAmbT2N11D3,EddAmbT2N12D3,EddAmbT2N13D3,EddAmbT2N14D3,EddAmbT2N15D3,EddAmbT2N16D3,EddAmbT2N17D3,EddAmbT2N18D3,EddAmbT2N19D3,EddAmbT2N20D3, & - EddAmbT2N01D4,EddAmbT2N02D4,EddAmbT2N03D4,EddAmbT2N04D4,EddAmbT2N05D4,EddAmbT2N06D4,EddAmbT2N07D4,EddAmbT2N08D4,EddAmbT2N09D4,EddAmbT2N10D4, & - EddAmbT2N11D4,EddAmbT2N12D4,EddAmbT2N13D4,EddAmbT2N14D4,EddAmbT2N15D4,EddAmbT2N16D4,EddAmbT2N17D4,EddAmbT2N18D4,EddAmbT2N19D4,EddAmbT2N20D4, & - EddAmbT2N01D5,EddAmbT2N02D5,EddAmbT2N03D5,EddAmbT2N04D5,EddAmbT2N05D5,EddAmbT2N06D5,EddAmbT2N07D5,EddAmbT2N08D5,EddAmbT2N09D5,EddAmbT2N10D5, & - EddAmbT2N11D5,EddAmbT2N12D5,EddAmbT2N13D5,EddAmbT2N14D5,EddAmbT2N15D5,EddAmbT2N16D5,EddAmbT2N17D5,EddAmbT2N18D5,EddAmbT2N19D5,EddAmbT2N20D5, & - EddAmbT2N01D6,EddAmbT2N02D6,EddAmbT2N03D6,EddAmbT2N04D6,EddAmbT2N05D6,EddAmbT2N06D6,EddAmbT2N07D6,EddAmbT2N08D6,EddAmbT2N09D6,EddAmbT2N10D6, & - EddAmbT2N11D6,EddAmbT2N12D6,EddAmbT2N13D6,EddAmbT2N14D6,EddAmbT2N15D6,EddAmbT2N16D6,EddAmbT2N17D6,EddAmbT2N18D6,EddAmbT2N19D6,EddAmbT2N20D6, & - EddAmbT2N01D7,EddAmbT2N02D7,EddAmbT2N03D7,EddAmbT2N04D7,EddAmbT2N05D7,EddAmbT2N06D7,EddAmbT2N07D7,EddAmbT2N08D7,EddAmbT2N09D7,EddAmbT2N10D7, & - EddAmbT2N11D7,EddAmbT2N12D7,EddAmbT2N13D7,EddAmbT2N14D7,EddAmbT2N15D7,EddAmbT2N16D7,EddAmbT2N17D7,EddAmbT2N18D7,EddAmbT2N19D7,EddAmbT2N20D7, & - EddAmbT2N01D8,EddAmbT2N02D8,EddAmbT2N03D8,EddAmbT2N04D8,EddAmbT2N05D8,EddAmbT2N06D8,EddAmbT2N07D8,EddAmbT2N08D8,EddAmbT2N09D8,EddAmbT2N10D8, & - EddAmbT2N11D8,EddAmbT2N12D8,EddAmbT2N13D8,EddAmbT2N14D8,EddAmbT2N15D8,EddAmbT2N16D8,EddAmbT2N17D8,EddAmbT2N18D8,EddAmbT2N19D8,EddAmbT2N20D8, & - EddAmbT2N01D9,EddAmbT2N02D9,EddAmbT2N03D9,EddAmbT2N04D9,EddAmbT2N05D9,EddAmbT2N06D9,EddAmbT2N07D9,EddAmbT2N08D9,EddAmbT2N09D9,EddAmbT2N10D9, & - EddAmbT2N11D9,EddAmbT2N12D9,EddAmbT2N13D9,EddAmbT2N14D9,EddAmbT2N15D9,EddAmbT2N16D9,EddAmbT2N17D9,EddAmbT2N18D9,EddAmbT2N19D9,EddAmbT2N20D9/), (/20,9/) ) -EddAmbTND(:,:,3) = RESHAPE( & - (/EddAmbT3N01D1,EddAmbT3N02D1,EddAmbT3N03D1,EddAmbT3N04D1,EddAmbT3N05D1,EddAmbT3N06D1,EddAmbT3N07D1,EddAmbT3N08D1,EddAmbT3N09D1,EddAmbT3N10D1, & - EddAmbT3N11D1,EddAmbT3N12D1,EddAmbT3N13D1,EddAmbT3N14D1,EddAmbT3N15D1,EddAmbT3N16D1,EddAmbT3N17D1,EddAmbT3N18D1,EddAmbT3N19D1,EddAmbT3N20D1, & - EddAmbT3N01D2,EddAmbT3N02D2,EddAmbT3N03D2,EddAmbT3N04D2,EddAmbT3N05D2,EddAmbT3N06D2,EddAmbT3N07D2,EddAmbT3N08D2,EddAmbT3N09D2,EddAmbT3N10D2, & - EddAmbT3N11D2,EddAmbT3N12D2,EddAmbT3N13D2,EddAmbT3N14D2,EddAmbT3N15D2,EddAmbT3N16D2,EddAmbT3N17D2,EddAmbT3N18D2,EddAmbT3N19D2,EddAmbT3N20D2, & - EddAmbT3N01D3,EddAmbT3N02D3,EddAmbT3N03D3,EddAmbT3N04D3,EddAmbT3N05D3,EddAmbT3N06D3,EddAmbT3N07D3,EddAmbT3N08D3,EddAmbT3N09D3,EddAmbT3N10D3, & - EddAmbT3N11D3,EddAmbT3N12D3,EddAmbT3N13D3,EddAmbT3N14D3,EddAmbT3N15D3,EddAmbT3N16D3,EddAmbT3N17D3,EddAmbT3N18D3,EddAmbT3N19D3,EddAmbT3N20D3, & - EddAmbT3N01D4,EddAmbT3N02D4,EddAmbT3N03D4,EddAmbT3N04D4,EddAmbT3N05D4,EddAmbT3N06D4,EddAmbT3N07D4,EddAmbT3N08D4,EddAmbT3N09D4,EddAmbT3N10D4, & - EddAmbT3N11D4,EddAmbT3N12D4,EddAmbT3N13D4,EddAmbT3N14D4,EddAmbT3N15D4,EddAmbT3N16D4,EddAmbT3N17D4,EddAmbT3N18D4,EddAmbT3N19D4,EddAmbT3N20D4, & - EddAmbT3N01D5,EddAmbT3N02D5,EddAmbT3N03D5,EddAmbT3N04D5,EddAmbT3N05D5,EddAmbT3N06D5,EddAmbT3N07D5,EddAmbT3N08D5,EddAmbT3N09D5,EddAmbT3N10D5, & - EddAmbT3N11D5,EddAmbT3N12D5,EddAmbT3N13D5,EddAmbT3N14D5,EddAmbT3N15D5,EddAmbT3N16D5,EddAmbT3N17D5,EddAmbT3N18D5,EddAmbT3N19D5,EddAmbT3N20D5, & - EddAmbT3N01D6,EddAmbT3N02D6,EddAmbT3N03D6,EddAmbT3N04D6,EddAmbT3N05D6,EddAmbT3N06D6,EddAmbT3N07D6,EddAmbT3N08D6,EddAmbT3N09D6,EddAmbT3N10D6, & - EddAmbT3N11D6,EddAmbT3N12D6,EddAmbT3N13D6,EddAmbT3N14D6,EddAmbT3N15D6,EddAmbT3N16D6,EddAmbT3N17D6,EddAmbT3N18D6,EddAmbT3N19D6,EddAmbT3N20D6, & - EddAmbT3N01D7,EddAmbT3N02D7,EddAmbT3N03D7,EddAmbT3N04D7,EddAmbT3N05D7,EddAmbT3N06D7,EddAmbT3N07D7,EddAmbT3N08D7,EddAmbT3N09D7,EddAmbT3N10D7, & - EddAmbT3N11D7,EddAmbT3N12D7,EddAmbT3N13D7,EddAmbT3N14D7,EddAmbT3N15D7,EddAmbT3N16D7,EddAmbT3N17D7,EddAmbT3N18D7,EddAmbT3N19D7,EddAmbT3N20D7, & - EddAmbT3N01D8,EddAmbT3N02D8,EddAmbT3N03D8,EddAmbT3N04D8,EddAmbT3N05D8,EddAmbT3N06D8,EddAmbT3N07D8,EddAmbT3N08D8,EddAmbT3N09D8,EddAmbT3N10D8, & - EddAmbT3N11D8,EddAmbT3N12D8,EddAmbT3N13D8,EddAmbT3N14D8,EddAmbT3N15D8,EddAmbT3N16D8,EddAmbT3N17D8,EddAmbT3N18D8,EddAmbT3N19D8,EddAmbT3N20D8, & - EddAmbT3N01D9,EddAmbT3N02D9,EddAmbT3N03D9,EddAmbT3N04D9,EddAmbT3N05D9,EddAmbT3N06D9,EddAmbT3N07D9,EddAmbT3N08D9,EddAmbT3N09D9,EddAmbT3N10D9, & - EddAmbT3N11D9,EddAmbT3N12D9,EddAmbT3N13D9,EddAmbT3N14D9,EddAmbT3N15D9,EddAmbT3N16D9,EddAmbT3N17D9,EddAmbT3N18D9,EddAmbT3N19D9,EddAmbT3N20D9/), (/20,9/) ) -EddAmbTND(:,:,4) = RESHAPE( & - (/EddAmbT4N01D1,EddAmbT4N02D1,EddAmbT4N03D1,EddAmbT4N04D1,EddAmbT4N05D1,EddAmbT4N06D1,EddAmbT4N07D1,EddAmbT4N08D1,EddAmbT4N09D1,EddAmbT4N10D1, & - EddAmbT4N11D1,EddAmbT4N12D1,EddAmbT4N13D1,EddAmbT4N14D1,EddAmbT4N15D1,EddAmbT4N16D1,EddAmbT4N17D1,EddAmbT4N18D1,EddAmbT4N19D1,EddAmbT4N20D1, & - EddAmbT4N01D2,EddAmbT4N02D2,EddAmbT4N03D2,EddAmbT4N04D2,EddAmbT4N05D2,EddAmbT4N06D2,EddAmbT4N07D2,EddAmbT4N08D2,EddAmbT4N09D2,EddAmbT4N10D2, & - EddAmbT4N11D2,EddAmbT4N12D2,EddAmbT4N13D2,EddAmbT4N14D2,EddAmbT4N15D2,EddAmbT4N16D2,EddAmbT4N17D2,EddAmbT4N18D2,EddAmbT4N19D2,EddAmbT4N20D2, & - EddAmbT4N01D3,EddAmbT4N02D3,EddAmbT4N03D3,EddAmbT4N04D3,EddAmbT4N05D3,EddAmbT4N06D3,EddAmbT4N07D3,EddAmbT4N08D3,EddAmbT4N09D3,EddAmbT4N10D3, & - EddAmbT4N11D3,EddAmbT4N12D3,EddAmbT4N13D3,EddAmbT4N14D3,EddAmbT4N15D3,EddAmbT4N16D3,EddAmbT4N17D3,EddAmbT4N18D3,EddAmbT4N19D3,EddAmbT4N20D3, & - EddAmbT4N01D4,EddAmbT4N02D4,EddAmbT4N03D4,EddAmbT4N04D4,EddAmbT4N05D4,EddAmbT4N06D4,EddAmbT4N07D4,EddAmbT4N08D4,EddAmbT4N09D4,EddAmbT4N10D4, & - EddAmbT4N11D4,EddAmbT4N12D4,EddAmbT4N13D4,EddAmbT4N14D4,EddAmbT4N15D4,EddAmbT4N16D4,EddAmbT4N17D4,EddAmbT4N18D4,EddAmbT4N19D4,EddAmbT4N20D4, & - EddAmbT4N01D5,EddAmbT4N02D5,EddAmbT4N03D5,EddAmbT4N04D5,EddAmbT4N05D5,EddAmbT4N06D5,EddAmbT4N07D5,EddAmbT4N08D5,EddAmbT4N09D5,EddAmbT4N10D5, & - EddAmbT4N11D5,EddAmbT4N12D5,EddAmbT4N13D5,EddAmbT4N14D5,EddAmbT4N15D5,EddAmbT4N16D5,EddAmbT4N17D5,EddAmbT4N18D5,EddAmbT4N19D5,EddAmbT4N20D5, & - EddAmbT4N01D6,EddAmbT4N02D6,EddAmbT4N03D6,EddAmbT4N04D6,EddAmbT4N05D6,EddAmbT4N06D6,EddAmbT4N07D6,EddAmbT4N08D6,EddAmbT4N09D6,EddAmbT4N10D6, & - EddAmbT4N11D6,EddAmbT4N12D6,EddAmbT4N13D6,EddAmbT4N14D6,EddAmbT4N15D6,EddAmbT4N16D6,EddAmbT4N17D6,EddAmbT4N18D6,EddAmbT4N19D6,EddAmbT4N20D6, & - EddAmbT4N01D7,EddAmbT4N02D7,EddAmbT4N03D7,EddAmbT4N04D7,EddAmbT4N05D7,EddAmbT4N06D7,EddAmbT4N07D7,EddAmbT4N08D7,EddAmbT4N09D7,EddAmbT4N10D7, & - EddAmbT4N11D7,EddAmbT4N12D7,EddAmbT4N13D7,EddAmbT4N14D7,EddAmbT4N15D7,EddAmbT4N16D7,EddAmbT4N17D7,EddAmbT4N18D7,EddAmbT4N19D7,EddAmbT4N20D7, & - EddAmbT4N01D8,EddAmbT4N02D8,EddAmbT4N03D8,EddAmbT4N04D8,EddAmbT4N05D8,EddAmbT4N06D8,EddAmbT4N07D8,EddAmbT4N08D8,EddAmbT4N09D8,EddAmbT4N10D8, & - EddAmbT4N11D8,EddAmbT4N12D8,EddAmbT4N13D8,EddAmbT4N14D8,EddAmbT4N15D8,EddAmbT4N16D8,EddAmbT4N17D8,EddAmbT4N18D8,EddAmbT4N19D8,EddAmbT4N20D8, & - EddAmbT4N01D9,EddAmbT4N02D9,EddAmbT4N03D9,EddAmbT4N04D9,EddAmbT4N05D9,EddAmbT4N06D9,EddAmbT4N07D9,EddAmbT4N08D9,EddAmbT4N09D9,EddAmbT4N10D9, & - EddAmbT4N11D9,EddAmbT4N12D9,EddAmbT4N13D9,EddAmbT4N14D9,EddAmbT4N15D9,EddAmbT4N16D9,EddAmbT4N17D9,EddAmbT4N18D9,EddAmbT4N19D9,EddAmbT4N20D9/), (/20,9/) ) - -EddAmbTND(:,:,5) = RESHAPE( & - (/EddAmbT5N01D1,EddAmbT5N02D1,EddAmbT5N03D1,EddAmbT5N04D1,EddAmbT5N05D1,EddAmbT5N06D1,EddAmbT5N07D1,EddAmbT5N08D1,EddAmbT5N09D1,EddAmbT5N10D1, & - EddAmbT5N11D1,EddAmbT5N12D1,EddAmbT5N13D1,EddAmbT5N14D1,EddAmbT5N15D1,EddAmbT5N16D1,EddAmbT5N17D1,EddAmbT5N18D1,EddAmbT5N19D1,EddAmbT5N20D1, & - EddAmbT5N01D2,EddAmbT5N02D2,EddAmbT5N03D2,EddAmbT5N04D2,EddAmbT5N05D2,EddAmbT5N06D2,EddAmbT5N07D2,EddAmbT5N08D2,EddAmbT5N09D2,EddAmbT5N10D2, & - EddAmbT5N11D2,EddAmbT5N12D2,EddAmbT5N13D2,EddAmbT5N14D2,EddAmbT5N15D2,EddAmbT5N16D2,EddAmbT5N17D2,EddAmbT5N18D2,EddAmbT5N19D2,EddAmbT5N20D2, & - EddAmbT5N01D3,EddAmbT5N02D3,EddAmbT5N03D3,EddAmbT5N04D3,EddAmbT5N05D3,EddAmbT5N06D3,EddAmbT5N07D3,EddAmbT5N08D3,EddAmbT5N09D3,EddAmbT5N10D3, & - EddAmbT5N11D3,EddAmbT5N12D3,EddAmbT5N13D3,EddAmbT5N14D3,EddAmbT5N15D3,EddAmbT5N16D3,EddAmbT5N17D3,EddAmbT5N18D3,EddAmbT5N19D3,EddAmbT5N20D3, & - EddAmbT5N01D4,EddAmbT5N02D4,EddAmbT5N03D4,EddAmbT5N04D4,EddAmbT5N05D4,EddAmbT5N06D4,EddAmbT5N07D4,EddAmbT5N08D4,EddAmbT5N09D4,EddAmbT5N10D4, & - EddAmbT5N11D4,EddAmbT5N12D4,EddAmbT5N13D4,EddAmbT5N14D4,EddAmbT5N15D4,EddAmbT5N16D4,EddAmbT5N17D4,EddAmbT5N18D4,EddAmbT5N19D4,EddAmbT5N20D4, & - EddAmbT5N01D5,EddAmbT5N02D5,EddAmbT5N03D5,EddAmbT5N04D5,EddAmbT5N05D5,EddAmbT5N06D5,EddAmbT5N07D5,EddAmbT5N08D5,EddAmbT5N09D5,EddAmbT5N10D5, & - EddAmbT5N11D5,EddAmbT5N12D5,EddAmbT5N13D5,EddAmbT5N14D5,EddAmbT5N15D5,EddAmbT5N16D5,EddAmbT5N17D5,EddAmbT5N18D5,EddAmbT5N19D5,EddAmbT5N20D5, & - EddAmbT5N01D6,EddAmbT5N02D6,EddAmbT5N03D6,EddAmbT5N04D6,EddAmbT5N05D6,EddAmbT5N06D6,EddAmbT5N07D6,EddAmbT5N08D6,EddAmbT5N09D6,EddAmbT5N10D6, & - EddAmbT5N11D6,EddAmbT5N12D6,EddAmbT5N13D6,EddAmbT5N14D6,EddAmbT5N15D6,EddAmbT5N16D6,EddAmbT5N17D6,EddAmbT5N18D6,EddAmbT5N19D6,EddAmbT5N20D6, & - EddAmbT5N01D7,EddAmbT5N02D7,EddAmbT5N03D7,EddAmbT5N04D7,EddAmbT5N05D7,EddAmbT5N06D7,EddAmbT5N07D7,EddAmbT5N08D7,EddAmbT5N09D7,EddAmbT5N10D7, & - EddAmbT5N11D7,EddAmbT5N12D7,EddAmbT5N13D7,EddAmbT5N14D7,EddAmbT5N15D7,EddAmbT5N16D7,EddAmbT5N17D7,EddAmbT5N18D7,EddAmbT5N19D7,EddAmbT5N20D7, & - EddAmbT5N01D8,EddAmbT5N02D8,EddAmbT5N03D8,EddAmbT5N04D8,EddAmbT5N05D8,EddAmbT5N06D8,EddAmbT5N07D8,EddAmbT5N08D8,EddAmbT5N09D8,EddAmbT5N10D8, & - EddAmbT5N11D8,EddAmbT5N12D8,EddAmbT5N13D8,EddAmbT5N14D8,EddAmbT5N15D8,EddAmbT5N16D8,EddAmbT5N17D8,EddAmbT5N18D8,EddAmbT5N19D8,EddAmbT5N20D8, & - EddAmbT5N01D9,EddAmbT5N02D9,EddAmbT5N03D9,EddAmbT5N04D9,EddAmbT5N05D9,EddAmbT5N06D9,EddAmbT5N07D9,EddAmbT5N08D9,EddAmbT5N09D9,EddAmbT5N10D9, & - EddAmbT5N11D9,EddAmbT5N12D9,EddAmbT5N13D9,EddAmbT5N14D9,EddAmbT5N15D9,EddAmbT5N16D9,EddAmbT5N17D9,EddAmbT5N18D9,EddAmbT5N19D9,EddAmbT5N20D9/), (/20,9/) ) -EddAmbTND(:,:,6) = RESHAPE( & - (/EddAmbT6N01D1,EddAmbT6N02D1,EddAmbT6N03D1,EddAmbT6N04D1,EddAmbT6N05D1,EddAmbT6N06D1,EddAmbT6N07D1,EddAmbT6N08D1,EddAmbT6N09D1,EddAmbT6N10D1, & - EddAmbT6N11D1,EddAmbT6N12D1,EddAmbT6N13D1,EddAmbT6N14D1,EddAmbT6N15D1,EddAmbT6N16D1,EddAmbT6N17D1,EddAmbT6N18D1,EddAmbT6N19D1,EddAmbT6N20D1, & - EddAmbT6N01D2,EddAmbT6N02D2,EddAmbT6N03D2,EddAmbT6N04D2,EddAmbT6N05D2,EddAmbT6N06D2,EddAmbT6N07D2,EddAmbT6N08D2,EddAmbT6N09D2,EddAmbT6N10D2, & - EddAmbT6N11D2,EddAmbT6N12D2,EddAmbT6N13D2,EddAmbT6N14D2,EddAmbT6N15D2,EddAmbT6N16D2,EddAmbT6N17D2,EddAmbT6N18D2,EddAmbT6N19D2,EddAmbT6N20D2, & - EddAmbT6N01D3,EddAmbT6N02D3,EddAmbT6N03D3,EddAmbT6N04D3,EddAmbT6N05D3,EddAmbT6N06D3,EddAmbT6N07D3,EddAmbT6N08D3,EddAmbT6N09D3,EddAmbT6N10D3, & - EddAmbT6N11D3,EddAmbT6N12D3,EddAmbT6N13D3,EddAmbT6N14D3,EddAmbT6N15D3,EddAmbT6N16D3,EddAmbT6N17D3,EddAmbT6N18D3,EddAmbT6N19D3,EddAmbT6N20D3, & - EddAmbT6N01D4,EddAmbT6N02D4,EddAmbT6N03D4,EddAmbT6N04D4,EddAmbT6N05D4,EddAmbT6N06D4,EddAmbT6N07D4,EddAmbT6N08D4,EddAmbT6N09D4,EddAmbT6N10D4, & - EddAmbT6N11D4,EddAmbT6N12D4,EddAmbT6N13D4,EddAmbT6N14D4,EddAmbT6N15D4,EddAmbT6N16D4,EddAmbT6N17D4,EddAmbT6N18D4,EddAmbT6N19D4,EddAmbT6N20D4, & - EddAmbT6N01D5,EddAmbT6N02D5,EddAmbT6N03D5,EddAmbT6N04D5,EddAmbT6N05D5,EddAmbT6N06D5,EddAmbT6N07D5,EddAmbT6N08D5,EddAmbT6N09D5,EddAmbT6N10D5, & - EddAmbT6N11D5,EddAmbT6N12D5,EddAmbT6N13D5,EddAmbT6N14D5,EddAmbT6N15D5,EddAmbT6N16D5,EddAmbT6N17D5,EddAmbT6N18D5,EddAmbT6N19D5,EddAmbT6N20D5, & - EddAmbT6N01D6,EddAmbT6N02D6,EddAmbT6N03D6,EddAmbT6N04D6,EddAmbT6N05D6,EddAmbT6N06D6,EddAmbT6N07D6,EddAmbT6N08D6,EddAmbT6N09D6,EddAmbT6N10D6, & - EddAmbT6N11D6,EddAmbT6N12D6,EddAmbT6N13D6,EddAmbT6N14D6,EddAmbT6N15D6,EddAmbT6N16D6,EddAmbT6N17D6,EddAmbT6N18D6,EddAmbT6N19D6,EddAmbT6N20D6, & - EddAmbT6N01D7,EddAmbT6N02D7,EddAmbT6N03D7,EddAmbT6N04D7,EddAmbT6N05D7,EddAmbT6N06D7,EddAmbT6N07D7,EddAmbT6N08D7,EddAmbT6N09D7,EddAmbT6N10D7, & - EddAmbT6N11D7,EddAmbT6N12D7,EddAmbT6N13D7,EddAmbT6N14D7,EddAmbT6N15D7,EddAmbT6N16D7,EddAmbT6N17D7,EddAmbT6N18D7,EddAmbT6N19D7,EddAmbT6N20D7, & - EddAmbT6N01D8,EddAmbT6N02D8,EddAmbT6N03D8,EddAmbT6N04D8,EddAmbT6N05D8,EddAmbT6N06D8,EddAmbT6N07D8,EddAmbT6N08D8,EddAmbT6N09D8,EddAmbT6N10D8, & - EddAmbT6N11D8,EddAmbT6N12D8,EddAmbT6N13D8,EddAmbT6N14D8,EddAmbT6N15D8,EddAmbT6N16D8,EddAmbT6N17D8,EddAmbT6N18D8,EddAmbT6N19D8,EddAmbT6N20D8, & - EddAmbT6N01D9,EddAmbT6N02D9,EddAmbT6N03D9,EddAmbT6N04D9,EddAmbT6N05D9,EddAmbT6N06D9,EddAmbT6N07D9,EddAmbT6N08D9,EddAmbT6N09D9,EddAmbT6N10D9, & - EddAmbT6N11D9,EddAmbT6N12D9,EddAmbT6N13D9,EddAmbT6N14D9,EddAmbT6N15D9,EddAmbT6N16D9,EddAmbT6N17D9,EddAmbT6N18D9,EddAmbT6N19D9,EddAmbT6N20D9/), (/20,9/) ) -EddAmbTND(:,:,7) = RESHAPE( & - (/EddAmbT7N01D1,EddAmbT7N02D1,EddAmbT7N03D1,EddAmbT7N04D1,EddAmbT7N05D1,EddAmbT7N06D1,EddAmbT7N07D1,EddAmbT7N08D1,EddAmbT7N09D1,EddAmbT7N10D1, & - EddAmbT7N11D1,EddAmbT7N12D1,EddAmbT7N13D1,EddAmbT7N14D1,EddAmbT7N15D1,EddAmbT7N16D1,EddAmbT7N17D1,EddAmbT7N18D1,EddAmbT7N19D1,EddAmbT7N20D1, & - EddAmbT7N01D2,EddAmbT7N02D2,EddAmbT7N03D2,EddAmbT7N04D2,EddAmbT7N05D2,EddAmbT7N06D2,EddAmbT7N07D2,EddAmbT7N08D2,EddAmbT7N09D2,EddAmbT7N10D2, & - EddAmbT7N11D2,EddAmbT7N12D2,EddAmbT7N13D2,EddAmbT7N14D2,EddAmbT7N15D2,EddAmbT7N16D2,EddAmbT7N17D2,EddAmbT7N18D2,EddAmbT7N19D2,EddAmbT7N20D2, & - EddAmbT7N01D3,EddAmbT7N02D3,EddAmbT7N03D3,EddAmbT7N04D3,EddAmbT7N05D3,EddAmbT7N06D3,EddAmbT7N07D3,EddAmbT7N08D3,EddAmbT7N09D3,EddAmbT7N10D3, & - EddAmbT7N11D3,EddAmbT7N12D3,EddAmbT7N13D3,EddAmbT7N14D3,EddAmbT7N15D3,EddAmbT7N16D3,EddAmbT7N17D3,EddAmbT7N18D3,EddAmbT7N19D3,EddAmbT7N20D3, & - EddAmbT7N01D4,EddAmbT7N02D4,EddAmbT7N03D4,EddAmbT7N04D4,EddAmbT7N05D4,EddAmbT7N06D4,EddAmbT7N07D4,EddAmbT7N08D4,EddAmbT7N09D4,EddAmbT7N10D4, & - EddAmbT7N11D4,EddAmbT7N12D4,EddAmbT7N13D4,EddAmbT7N14D4,EddAmbT7N15D4,EddAmbT7N16D4,EddAmbT7N17D4,EddAmbT7N18D4,EddAmbT7N19D4,EddAmbT7N20D4, & - EddAmbT7N01D5,EddAmbT7N02D5,EddAmbT7N03D5,EddAmbT7N04D5,EddAmbT7N05D5,EddAmbT7N06D5,EddAmbT7N07D5,EddAmbT7N08D5,EddAmbT7N09D5,EddAmbT7N10D5, & - EddAmbT7N11D5,EddAmbT7N12D5,EddAmbT7N13D5,EddAmbT7N14D5,EddAmbT7N15D5,EddAmbT7N16D5,EddAmbT7N17D5,EddAmbT7N18D5,EddAmbT7N19D5,EddAmbT7N20D5, & - EddAmbT7N01D6,EddAmbT7N02D6,EddAmbT7N03D6,EddAmbT7N04D6,EddAmbT7N05D6,EddAmbT7N06D6,EddAmbT7N07D6,EddAmbT7N08D6,EddAmbT7N09D6,EddAmbT7N10D6, & - EddAmbT7N11D6,EddAmbT7N12D6,EddAmbT7N13D6,EddAmbT7N14D6,EddAmbT7N15D6,EddAmbT7N16D6,EddAmbT7N17D6,EddAmbT7N18D6,EddAmbT7N19D6,EddAmbT7N20D6, & - EddAmbT7N01D7,EddAmbT7N02D7,EddAmbT7N03D7,EddAmbT7N04D7,EddAmbT7N05D7,EddAmbT7N06D7,EddAmbT7N07D7,EddAmbT7N08D7,EddAmbT7N09D7,EddAmbT7N10D7, & - EddAmbT7N11D7,EddAmbT7N12D7,EddAmbT7N13D7,EddAmbT7N14D7,EddAmbT7N15D7,EddAmbT7N16D7,EddAmbT7N17D7,EddAmbT7N18D7,EddAmbT7N19D7,EddAmbT7N20D7, & - EddAmbT7N01D8,EddAmbT7N02D8,EddAmbT7N03D8,EddAmbT7N04D8,EddAmbT7N05D8,EddAmbT7N06D8,EddAmbT7N07D8,EddAmbT7N08D8,EddAmbT7N09D8,EddAmbT7N10D8, & - EddAmbT7N11D8,EddAmbT7N12D8,EddAmbT7N13D8,EddAmbT7N14D8,EddAmbT7N15D8,EddAmbT7N16D8,EddAmbT7N17D8,EddAmbT7N18D8,EddAmbT7N19D8,EddAmbT7N20D8, & - EddAmbT7N01D9,EddAmbT7N02D9,EddAmbT7N03D9,EddAmbT7N04D9,EddAmbT7N05D9,EddAmbT7N06D9,EddAmbT7N07D9,EddAmbT7N08D9,EddAmbT7N09D9,EddAmbT7N10D9, & - EddAmbT7N11D9,EddAmbT7N12D9,EddAmbT7N13D9,EddAmbT7N14D9,EddAmbT7N15D9,EddAmbT7N16D9,EddAmbT7N17D9,EddAmbT7N18D9,EddAmbT7N19D9,EddAmbT7N20D9/), (/20,9/) ) -EddAmbTND(:,:,8) = RESHAPE( & - (/EddAmbT8N01D1,EddAmbT8N02D1,EddAmbT8N03D1,EddAmbT8N04D1,EddAmbT8N05D1,EddAmbT8N06D1,EddAmbT8N07D1,EddAmbT8N08D1,EddAmbT8N09D1,EddAmbT8N10D1, & - EddAmbT8N11D1,EddAmbT8N12D1,EddAmbT8N13D1,EddAmbT8N14D1,EddAmbT8N15D1,EddAmbT8N16D1,EddAmbT8N17D1,EddAmbT8N18D1,EddAmbT8N19D1,EddAmbT8N20D1, & - EddAmbT8N01D2,EddAmbT8N02D2,EddAmbT8N03D2,EddAmbT8N04D2,EddAmbT8N05D2,EddAmbT8N06D2,EddAmbT8N07D2,EddAmbT8N08D2,EddAmbT8N09D2,EddAmbT8N10D2, & - EddAmbT8N11D2,EddAmbT8N12D2,EddAmbT8N13D2,EddAmbT8N14D2,EddAmbT8N15D2,EddAmbT8N16D2,EddAmbT8N17D2,EddAmbT8N18D2,EddAmbT8N19D2,EddAmbT8N20D2, & - EddAmbT8N01D3,EddAmbT8N02D3,EddAmbT8N03D3,EddAmbT8N04D3,EddAmbT8N05D3,EddAmbT8N06D3,EddAmbT8N07D3,EddAmbT8N08D3,EddAmbT8N09D3,EddAmbT8N10D3, & - EddAmbT8N11D3,EddAmbT8N12D3,EddAmbT8N13D3,EddAmbT8N14D3,EddAmbT8N15D3,EddAmbT8N16D3,EddAmbT8N17D3,EddAmbT8N18D3,EddAmbT8N19D3,EddAmbT8N20D3, & - EddAmbT8N01D4,EddAmbT8N02D4,EddAmbT8N03D4,EddAmbT8N04D4,EddAmbT8N05D4,EddAmbT8N06D4,EddAmbT8N07D4,EddAmbT8N08D4,EddAmbT8N09D4,EddAmbT8N10D4, & - EddAmbT8N11D4,EddAmbT8N12D4,EddAmbT8N13D4,EddAmbT8N14D4,EddAmbT8N15D4,EddAmbT8N16D4,EddAmbT8N17D4,EddAmbT8N18D4,EddAmbT8N19D4,EddAmbT8N20D4, & - EddAmbT8N01D5,EddAmbT8N02D5,EddAmbT8N03D5,EddAmbT8N04D5,EddAmbT8N05D5,EddAmbT8N06D5,EddAmbT8N07D5,EddAmbT8N08D5,EddAmbT8N09D5,EddAmbT8N10D5, & - EddAmbT8N11D5,EddAmbT8N12D5,EddAmbT8N13D5,EddAmbT8N14D5,EddAmbT8N15D5,EddAmbT8N16D5,EddAmbT8N17D5,EddAmbT8N18D5,EddAmbT8N19D5,EddAmbT8N20D5, & - EddAmbT8N01D6,EddAmbT8N02D6,EddAmbT8N03D6,EddAmbT8N04D6,EddAmbT8N05D6,EddAmbT8N06D6,EddAmbT8N07D6,EddAmbT8N08D6,EddAmbT8N09D6,EddAmbT8N10D6, & - EddAmbT8N11D6,EddAmbT8N12D6,EddAmbT8N13D6,EddAmbT8N14D6,EddAmbT8N15D6,EddAmbT8N16D6,EddAmbT8N17D6,EddAmbT8N18D6,EddAmbT8N19D6,EddAmbT8N20D6, & - EddAmbT8N01D7,EddAmbT8N02D7,EddAmbT8N03D7,EddAmbT8N04D7,EddAmbT8N05D7,EddAmbT8N06D7,EddAmbT8N07D7,EddAmbT8N08D7,EddAmbT8N09D7,EddAmbT8N10D7, & - EddAmbT8N11D7,EddAmbT8N12D7,EddAmbT8N13D7,EddAmbT8N14D7,EddAmbT8N15D7,EddAmbT8N16D7,EddAmbT8N17D7,EddAmbT8N18D7,EddAmbT8N19D7,EddAmbT8N20D7, & - EddAmbT8N01D8,EddAmbT8N02D8,EddAmbT8N03D8,EddAmbT8N04D8,EddAmbT8N05D8,EddAmbT8N06D8,EddAmbT8N07D8,EddAmbT8N08D8,EddAmbT8N09D8,EddAmbT8N10D8, & - EddAmbT8N11D8,EddAmbT8N12D8,EddAmbT8N13D8,EddAmbT8N14D8,EddAmbT8N15D8,EddAmbT8N16D8,EddAmbT8N17D8,EddAmbT8N18D8,EddAmbT8N19D8,EddAmbT8N20D8, & - EddAmbT8N01D9,EddAmbT8N02D9,EddAmbT8N03D9,EddAmbT8N04D9,EddAmbT8N05D9,EddAmbT8N06D9,EddAmbT8N07D9,EddAmbT8N08D9,EddAmbT8N09D9,EddAmbT8N10D9, & - EddAmbT8N11D9,EddAmbT8N12D9,EddAmbT8N13D9,EddAmbT8N14D9,EddAmbT8N15D9,EddAmbT8N16D9,EddAmbT8N17D9,EddAmbT8N18D9,EddAmbT8N19D9,EddAmbT8N20D9/), (/20,9/) ) -EddAmbTND(:,:,9) = RESHAPE( & - (/EddAmbT9N01D1,EddAmbT9N02D1,EddAmbT9N03D1,EddAmbT9N04D1,EddAmbT9N05D1,EddAmbT9N06D1,EddAmbT9N07D1,EddAmbT9N08D1,EddAmbT9N09D1,EddAmbT9N10D1, & - EddAmbT9N11D1,EddAmbT9N12D1,EddAmbT9N13D1,EddAmbT9N14D1,EddAmbT9N15D1,EddAmbT9N16D1,EddAmbT9N17D1,EddAmbT9N18D1,EddAmbT9N19D1,EddAmbT9N20D1, & - EddAmbT9N01D2,EddAmbT9N02D2,EddAmbT9N03D2,EddAmbT9N04D2,EddAmbT9N05D2,EddAmbT9N06D2,EddAmbT9N07D2,EddAmbT9N08D2,EddAmbT9N09D2,EddAmbT9N10D2, & - EddAmbT9N11D2,EddAmbT9N12D2,EddAmbT9N13D2,EddAmbT9N14D2,EddAmbT9N15D2,EddAmbT9N16D2,EddAmbT9N17D2,EddAmbT9N18D2,EddAmbT9N19D2,EddAmbT9N20D2, & - EddAmbT9N01D3,EddAmbT9N02D3,EddAmbT9N03D3,EddAmbT9N04D3,EddAmbT9N05D3,EddAmbT9N06D3,EddAmbT9N07D3,EddAmbT9N08D3,EddAmbT9N09D3,EddAmbT9N10D3, & - EddAmbT9N11D3,EddAmbT9N12D3,EddAmbT9N13D3,EddAmbT9N14D3,EddAmbT9N15D3,EddAmbT9N16D3,EddAmbT9N17D3,EddAmbT9N18D3,EddAmbT9N19D3,EddAmbT9N20D3, & - EddAmbT9N01D4,EddAmbT9N02D4,EddAmbT9N03D4,EddAmbT9N04D4,EddAmbT9N05D4,EddAmbT9N06D4,EddAmbT9N07D4,EddAmbT9N08D4,EddAmbT9N09D4,EddAmbT9N10D4, & - EddAmbT9N11D4,EddAmbT9N12D4,EddAmbT9N13D4,EddAmbT9N14D4,EddAmbT9N15D4,EddAmbT9N16D4,EddAmbT9N17D4,EddAmbT9N18D4,EddAmbT9N19D4,EddAmbT9N20D4, & - EddAmbT9N01D5,EddAmbT9N02D5,EddAmbT9N03D5,EddAmbT9N04D5,EddAmbT9N05D5,EddAmbT9N06D5,EddAmbT9N07D5,EddAmbT9N08D5,EddAmbT9N09D5,EddAmbT9N10D5, & - EddAmbT9N11D5,EddAmbT9N12D5,EddAmbT9N13D5,EddAmbT9N14D5,EddAmbT9N15D5,EddAmbT9N16D5,EddAmbT9N17D5,EddAmbT9N18D5,EddAmbT9N19D5,EddAmbT9N20D5, & - EddAmbT9N01D6,EddAmbT9N02D6,EddAmbT9N03D6,EddAmbT9N04D6,EddAmbT9N05D6,EddAmbT9N06D6,EddAmbT9N07D6,EddAmbT9N08D6,EddAmbT9N09D6,EddAmbT9N10D6, & - EddAmbT9N11D6,EddAmbT9N12D6,EddAmbT9N13D6,EddAmbT9N14D6,EddAmbT9N15D6,EddAmbT9N16D6,EddAmbT9N17D6,EddAmbT9N18D6,EddAmbT9N19D6,EddAmbT9N20D6, & - EddAmbT9N01D7,EddAmbT9N02D7,EddAmbT9N03D7,EddAmbT9N04D7,EddAmbT9N05D7,EddAmbT9N06D7,EddAmbT9N07D7,EddAmbT9N08D7,EddAmbT9N09D7,EddAmbT9N10D7, & - EddAmbT9N11D7,EddAmbT9N12D7,EddAmbT9N13D7,EddAmbT9N14D7,EddAmbT9N15D7,EddAmbT9N16D7,EddAmbT9N17D7,EddAmbT9N18D7,EddAmbT9N19D7,EddAmbT9N20D7, & - EddAmbT9N01D8,EddAmbT9N02D8,EddAmbT9N03D8,EddAmbT9N04D8,EddAmbT9N05D8,EddAmbT9N06D8,EddAmbT9N07D8,EddAmbT9N08D8,EddAmbT9N09D8,EddAmbT9N10D8, & - EddAmbT9N11D8,EddAmbT9N12D8,EddAmbT9N13D8,EddAmbT9N14D8,EddAmbT9N15D8,EddAmbT9N16D8,EddAmbT9N17D8,EddAmbT9N18D8,EddAmbT9N19D8,EddAmbT9N20D8, & - EddAmbT9N01D9,EddAmbT9N02D9,EddAmbT9N03D9,EddAmbT9N04D9,EddAmbT9N05D9,EddAmbT9N06D9,EddAmbT9N07D9,EddAmbT9N08D9,EddAmbT9N09D9,EddAmbT9N10D9, & - EddAmbT9N11D9,EddAmbT9N12D9,EddAmbT9N13D9,EddAmbT9N14D9,EddAmbT9N15D9,EddAmbT9N16D9,EddAmbT9N17D9,EddAmbT9N18D9,EddAmbT9N19D9,EddAmbT9N20D9/), (/20,9/) ) - - -EddShrTND(:,:,1) = RESHAPE( & - (/EddShrT1N01D1,EddShrT1N02D1,EddShrT1N03D1,EddShrT1N04D1,EddShrT1N05D1,EddShrT1N06D1,EddShrT1N07D1,EddShrT1N08D1,EddShrT1N09D1,EddShrT1N10D1, & - EddShrT1N11D1,EddShrT1N12D1,EddShrT1N13D1,EddShrT1N14D1,EddShrT1N15D1,EddShrT1N16D1,EddShrT1N17D1,EddShrT1N18D1,EddShrT1N19D1,EddShrT1N20D1, & - EddShrT1N01D2,EddShrT1N02D2,EddShrT1N03D2,EddShrT1N04D2,EddShrT1N05D2,EddShrT1N06D2,EddShrT1N07D2,EddShrT1N08D2,EddShrT1N09D2,EddShrT1N10D2, & - EddShrT1N11D2,EddShrT1N12D2,EddShrT1N13D2,EddShrT1N14D2,EddShrT1N15D2,EddShrT1N16D2,EddShrT1N17D2,EddShrT1N18D2,EddShrT1N19D2,EddShrT1N20D2, & - EddShrT1N01D3,EddShrT1N02D3,EddShrT1N03D3,EddShrT1N04D3,EddShrT1N05D3,EddShrT1N06D3,EddShrT1N07D3,EddShrT1N08D3,EddShrT1N09D3,EddShrT1N10D3, & - EddShrT1N11D3,EddShrT1N12D3,EddShrT1N13D3,EddShrT1N14D3,EddShrT1N15D3,EddShrT1N16D3,EddShrT1N17D3,EddShrT1N18D3,EddShrT1N19D3,EddShrT1N20D3, & - EddShrT1N01D4,EddShrT1N02D4,EddShrT1N03D4,EddShrT1N04D4,EddShrT1N05D4,EddShrT1N06D4,EddShrT1N07D4,EddShrT1N08D4,EddShrT1N09D4,EddShrT1N10D4, & - EddShrT1N11D4,EddShrT1N12D4,EddShrT1N13D4,EddShrT1N14D4,EddShrT1N15D4,EddShrT1N16D4,EddShrT1N17D4,EddShrT1N18D4,EddShrT1N19D4,EddShrT1N20D4, & - EddShrT1N01D5,EddShrT1N02D5,EddShrT1N03D5,EddShrT1N04D5,EddShrT1N05D5,EddShrT1N06D5,EddShrT1N07D5,EddShrT1N08D5,EddShrT1N09D5,EddShrT1N10D5, & - EddShrT1N11D5,EddShrT1N12D5,EddShrT1N13D5,EddShrT1N14D5,EddShrT1N15D5,EddShrT1N16D5,EddShrT1N17D5,EddShrT1N18D5,EddShrT1N19D5,EddShrT1N20D5, & - EddShrT1N01D6,EddShrT1N02D6,EddShrT1N03D6,EddShrT1N04D6,EddShrT1N05D6,EddShrT1N06D6,EddShrT1N07D6,EddShrT1N08D6,EddShrT1N09D6,EddShrT1N10D6, & - EddShrT1N11D6,EddShrT1N12D6,EddShrT1N13D6,EddShrT1N14D6,EddShrT1N15D6,EddShrT1N16D6,EddShrT1N17D6,EddShrT1N18D6,EddShrT1N19D6,EddShrT1N20D6, & - EddShrT1N01D7,EddShrT1N02D7,EddShrT1N03D7,EddShrT1N04D7,EddShrT1N05D7,EddShrT1N06D7,EddShrT1N07D7,EddShrT1N08D7,EddShrT1N09D7,EddShrT1N10D7, & - EddShrT1N11D7,EddShrT1N12D7,EddShrT1N13D7,EddShrT1N14D7,EddShrT1N15D7,EddShrT1N16D7,EddShrT1N17D7,EddShrT1N18D7,EddShrT1N19D7,EddShrT1N20D7, & - EddShrT1N01D8,EddShrT1N02D8,EddShrT1N03D8,EddShrT1N04D8,EddShrT1N05D8,EddShrT1N06D8,EddShrT1N07D8,EddShrT1N08D8,EddShrT1N09D8,EddShrT1N10D8, & - EddShrT1N11D8,EddShrT1N12D8,EddShrT1N13D8,EddShrT1N14D8,EddShrT1N15D8,EddShrT1N16D8,EddShrT1N17D8,EddShrT1N18D8,EddShrT1N19D8,EddShrT1N20D8, & - EddShrT1N01D9,EddShrT1N02D9,EddShrT1N03D9,EddShrT1N04D9,EddShrT1N05D9,EddShrT1N06D9,EddShrT1N07D9,EddShrT1N08D9,EddShrT1N09D9,EddShrT1N10D9, & - EddShrT1N11D9,EddShrT1N12D9,EddShrT1N13D9,EddShrT1N14D9,EddShrT1N15D9,EddShrT1N16D9,EddShrT1N17D9,EddShrT1N18D9,EddShrT1N19D9,EddShrT1N20D9/), (/20,9/) ) -EddShrTND(:,:,2) = RESHAPE( & - (/EddShrT2N01D1,EddShrT2N02D1,EddShrT2N03D1,EddShrT2N04D1,EddShrT2N05D1,EddShrT2N06D1,EddShrT2N07D1,EddShrT2N08D1,EddShrT2N09D1,EddShrT2N10D1, & - EddShrT2N11D1,EddShrT2N12D1,EddShrT2N13D1,EddShrT2N14D1,EddShrT2N15D1,EddShrT2N16D1,EddShrT2N17D1,EddShrT2N18D1,EddShrT2N19D1,EddShrT2N20D1, & - EddShrT2N01D2,EddShrT2N02D2,EddShrT2N03D2,EddShrT2N04D2,EddShrT2N05D2,EddShrT2N06D2,EddShrT2N07D2,EddShrT2N08D2,EddShrT2N09D2,EddShrT2N10D2, & - EddShrT2N11D2,EddShrT2N12D2,EddShrT2N13D2,EddShrT2N14D2,EddShrT2N15D2,EddShrT2N16D2,EddShrT2N17D2,EddShrT2N18D2,EddShrT2N19D2,EddShrT2N20D2, & - EddShrT2N01D3,EddShrT2N02D3,EddShrT2N03D3,EddShrT2N04D3,EddShrT2N05D3,EddShrT2N06D3,EddShrT2N07D3,EddShrT2N08D3,EddShrT2N09D3,EddShrT2N10D3, & - EddShrT2N11D3,EddShrT2N12D3,EddShrT2N13D3,EddShrT2N14D3,EddShrT2N15D3,EddShrT2N16D3,EddShrT2N17D3,EddShrT2N18D3,EddShrT2N19D3,EddShrT2N20D3, & - EddShrT2N01D4,EddShrT2N02D4,EddShrT2N03D4,EddShrT2N04D4,EddShrT2N05D4,EddShrT2N06D4,EddShrT2N07D4,EddShrT2N08D4,EddShrT2N09D4,EddShrT2N10D4, & - EddShrT2N11D4,EddShrT2N12D4,EddShrT2N13D4,EddShrT2N14D4,EddShrT2N15D4,EddShrT2N16D4,EddShrT2N17D4,EddShrT2N18D4,EddShrT2N19D4,EddShrT2N20D4, & - EddShrT2N01D5,EddShrT2N02D5,EddShrT2N03D5,EddShrT2N04D5,EddShrT2N05D5,EddShrT2N06D5,EddShrT2N07D5,EddShrT2N08D5,EddShrT2N09D5,EddShrT2N10D5, & - EddShrT2N11D5,EddShrT2N12D5,EddShrT2N13D5,EddShrT2N14D5,EddShrT2N15D5,EddShrT2N16D5,EddShrT2N17D5,EddShrT2N18D5,EddShrT2N19D5,EddShrT2N20D5, & - EddShrT2N01D6,EddShrT2N02D6,EddShrT2N03D6,EddShrT2N04D6,EddShrT2N05D6,EddShrT2N06D6,EddShrT2N07D6,EddShrT2N08D6,EddShrT2N09D6,EddShrT2N10D6, & - EddShrT2N11D6,EddShrT2N12D6,EddShrT2N13D6,EddShrT2N14D6,EddShrT2N15D6,EddShrT2N16D6,EddShrT2N17D6,EddShrT2N18D6,EddShrT2N19D6,EddShrT2N20D6, & - EddShrT2N01D7,EddShrT2N02D7,EddShrT2N03D7,EddShrT2N04D7,EddShrT2N05D7,EddShrT2N06D7,EddShrT2N07D7,EddShrT2N08D7,EddShrT2N09D7,EddShrT2N10D7, & - EddShrT2N11D7,EddShrT2N12D7,EddShrT2N13D7,EddShrT2N14D7,EddShrT2N15D7,EddShrT2N16D7,EddShrT2N17D7,EddShrT2N18D7,EddShrT2N19D7,EddShrT2N20D7, & - EddShrT2N01D8,EddShrT2N02D8,EddShrT2N03D8,EddShrT2N04D8,EddShrT2N05D8,EddShrT2N06D8,EddShrT2N07D8,EddShrT2N08D8,EddShrT2N09D8,EddShrT2N10D8, & - EddShrT2N11D8,EddShrT2N12D8,EddShrT2N13D8,EddShrT2N14D8,EddShrT2N15D8,EddShrT2N16D8,EddShrT2N17D8,EddShrT2N18D8,EddShrT2N19D8,EddShrT2N20D8, & - EddShrT2N01D9,EddShrT2N02D9,EddShrT2N03D9,EddShrT2N04D9,EddShrT2N05D9,EddShrT2N06D9,EddShrT2N07D9,EddShrT2N08D9,EddShrT2N09D9,EddShrT2N10D9, & - EddShrT2N11D9,EddShrT2N12D9,EddShrT2N13D9,EddShrT2N14D9,EddShrT2N15D9,EddShrT2N16D9,EddShrT2N17D9,EddShrT2N18D9,EddShrT2N19D9,EddShrT2N20D9/), (/20,9/) ) -EddShrTND(:,:,3) = RESHAPE( & - (/EddShrT3N01D1,EddShrT3N02D1,EddShrT3N03D1,EddShrT3N04D1,EddShrT3N05D1,EddShrT3N06D1,EddShrT3N07D1,EddShrT3N08D1,EddShrT3N09D1,EddShrT3N10D1, & - EddShrT3N11D1,EddShrT3N12D1,EddShrT3N13D1,EddShrT3N14D1,EddShrT3N15D1,EddShrT3N16D1,EddShrT3N17D1,EddShrT3N18D1,EddShrT3N19D1,EddShrT3N20D1, & - EddShrT3N01D2,EddShrT3N02D2,EddShrT3N03D2,EddShrT3N04D2,EddShrT3N05D2,EddShrT3N06D2,EddShrT3N07D2,EddShrT3N08D2,EddShrT3N09D2,EddShrT3N10D2, & - EddShrT3N11D2,EddShrT3N12D2,EddShrT3N13D2,EddShrT3N14D2,EddShrT3N15D2,EddShrT3N16D2,EddShrT3N17D2,EddShrT3N18D2,EddShrT3N19D2,EddShrT3N20D2, & - EddShrT3N01D3,EddShrT3N02D3,EddShrT3N03D3,EddShrT3N04D3,EddShrT3N05D3,EddShrT3N06D3,EddShrT3N07D3,EddShrT3N08D3,EddShrT3N09D3,EddShrT3N10D3, & - EddShrT3N11D3,EddShrT3N12D3,EddShrT3N13D3,EddShrT3N14D3,EddShrT3N15D3,EddShrT3N16D3,EddShrT3N17D3,EddShrT3N18D3,EddShrT3N19D3,EddShrT3N20D3, & - EddShrT3N01D4,EddShrT3N02D4,EddShrT3N03D4,EddShrT3N04D4,EddShrT3N05D4,EddShrT3N06D4,EddShrT3N07D4,EddShrT3N08D4,EddShrT3N09D4,EddShrT3N10D4, & - EddShrT3N11D4,EddShrT3N12D4,EddShrT3N13D4,EddShrT3N14D4,EddShrT3N15D4,EddShrT3N16D4,EddShrT3N17D4,EddShrT3N18D4,EddShrT3N19D4,EddShrT3N20D4, & - EddShrT3N01D5,EddShrT3N02D5,EddShrT3N03D5,EddShrT3N04D5,EddShrT3N05D5,EddShrT3N06D5,EddShrT3N07D5,EddShrT3N08D5,EddShrT3N09D5,EddShrT3N10D5, & - EddShrT3N11D5,EddShrT3N12D5,EddShrT3N13D5,EddShrT3N14D5,EddShrT3N15D5,EddShrT3N16D5,EddShrT3N17D5,EddShrT3N18D5,EddShrT3N19D5,EddShrT3N20D5, & - EddShrT3N01D6,EddShrT3N02D6,EddShrT3N03D6,EddShrT3N04D6,EddShrT3N05D6,EddShrT3N06D6,EddShrT3N07D6,EddShrT3N08D6,EddShrT3N09D6,EddShrT3N10D6, & - EddShrT3N11D6,EddShrT3N12D6,EddShrT3N13D6,EddShrT3N14D6,EddShrT3N15D6,EddShrT3N16D6,EddShrT3N17D6,EddShrT3N18D6,EddShrT3N19D6,EddShrT3N20D6, & - EddShrT3N01D7,EddShrT3N02D7,EddShrT3N03D7,EddShrT3N04D7,EddShrT3N05D7,EddShrT3N06D7,EddShrT3N07D7,EddShrT3N08D7,EddShrT3N09D7,EddShrT3N10D7, & - EddShrT3N11D7,EddShrT3N12D7,EddShrT3N13D7,EddShrT3N14D7,EddShrT3N15D7,EddShrT3N16D7,EddShrT3N17D7,EddShrT3N18D7,EddShrT3N19D7,EddShrT3N20D7, & - EddShrT3N01D8,EddShrT3N02D8,EddShrT3N03D8,EddShrT3N04D8,EddShrT3N05D8,EddShrT3N06D8,EddShrT3N07D8,EddShrT3N08D8,EddShrT3N09D8,EddShrT3N10D8, & - EddShrT3N11D8,EddShrT3N12D8,EddShrT3N13D8,EddShrT3N14D8,EddShrT3N15D8,EddShrT3N16D8,EddShrT3N17D8,EddShrT3N18D8,EddShrT3N19D8,EddShrT3N20D8, & - EddShrT3N01D9,EddShrT3N02D9,EddShrT3N03D9,EddShrT3N04D9,EddShrT3N05D9,EddShrT3N06D9,EddShrT3N07D9,EddShrT3N08D9,EddShrT3N09D9,EddShrT3N10D9, & - EddShrT3N11D9,EddShrT3N12D9,EddShrT3N13D9,EddShrT3N14D9,EddShrT3N15D9,EddShrT3N16D9,EddShrT3N17D9,EddShrT3N18D9,EddShrT3N19D9,EddShrT3N20D9/), (/20,9/) ) -EddShrTND(:,:,4) = RESHAPE( & - (/EddShrT4N01D1,EddShrT4N02D1,EddShrT4N03D1,EddShrT4N04D1,EddShrT4N05D1,EddShrT4N06D1,EddShrT4N07D1,EddShrT4N08D1,EddShrT4N09D1,EddShrT4N10D1, & - EddShrT4N11D1,EddShrT4N12D1,EddShrT4N13D1,EddShrT4N14D1,EddShrT4N15D1,EddShrT4N16D1,EddShrT4N17D1,EddShrT4N18D1,EddShrT4N19D1,EddShrT4N20D1, & - EddShrT4N01D2,EddShrT4N02D2,EddShrT4N03D2,EddShrT4N04D2,EddShrT4N05D2,EddShrT4N06D2,EddShrT4N07D2,EddShrT4N08D2,EddShrT4N09D2,EddShrT4N10D2, & - EddShrT4N11D2,EddShrT4N12D2,EddShrT4N13D2,EddShrT4N14D2,EddShrT4N15D2,EddShrT4N16D2,EddShrT4N17D2,EddShrT4N18D2,EddShrT4N19D2,EddShrT4N20D2, & - EddShrT4N01D3,EddShrT4N02D3,EddShrT4N03D3,EddShrT4N04D3,EddShrT4N05D3,EddShrT4N06D3,EddShrT4N07D3,EddShrT4N08D3,EddShrT4N09D3,EddShrT4N10D3, & - EddShrT4N11D3,EddShrT4N12D3,EddShrT4N13D3,EddShrT4N14D3,EddShrT4N15D3,EddShrT4N16D3,EddShrT4N17D3,EddShrT4N18D3,EddShrT4N19D3,EddShrT4N20D3, & - EddShrT4N01D4,EddShrT4N02D4,EddShrT4N03D4,EddShrT4N04D4,EddShrT4N05D4,EddShrT4N06D4,EddShrT4N07D4,EddShrT4N08D4,EddShrT4N09D4,EddShrT4N10D4, & - EddShrT4N11D4,EddShrT4N12D4,EddShrT4N13D4,EddShrT4N14D4,EddShrT4N15D4,EddShrT4N16D4,EddShrT4N17D4,EddShrT4N18D4,EddShrT4N19D4,EddShrT4N20D4, & - EddShrT4N01D5,EddShrT4N02D5,EddShrT4N03D5,EddShrT4N04D5,EddShrT4N05D5,EddShrT4N06D5,EddShrT4N07D5,EddShrT4N08D5,EddShrT4N09D5,EddShrT4N10D5, & - EddShrT4N11D5,EddShrT4N12D5,EddShrT4N13D5,EddShrT4N14D5,EddShrT4N15D5,EddShrT4N16D5,EddShrT4N17D5,EddShrT4N18D5,EddShrT4N19D5,EddShrT4N20D5, & - EddShrT4N01D6,EddShrT4N02D6,EddShrT4N03D6,EddShrT4N04D6,EddShrT4N05D6,EddShrT4N06D6,EddShrT4N07D6,EddShrT4N08D6,EddShrT4N09D6,EddShrT4N10D6, & - EddShrT4N11D6,EddShrT4N12D6,EddShrT4N13D6,EddShrT4N14D6,EddShrT4N15D6,EddShrT4N16D6,EddShrT4N17D6,EddShrT4N18D6,EddShrT4N19D6,EddShrT4N20D6, & - EddShrT4N01D7,EddShrT4N02D7,EddShrT4N03D7,EddShrT4N04D7,EddShrT4N05D7,EddShrT4N06D7,EddShrT4N07D7,EddShrT4N08D7,EddShrT4N09D7,EddShrT4N10D7, & - EddShrT4N11D7,EddShrT4N12D7,EddShrT4N13D7,EddShrT4N14D7,EddShrT4N15D7,EddShrT4N16D7,EddShrT4N17D7,EddShrT4N18D7,EddShrT4N19D7,EddShrT4N20D7, & - EddShrT4N01D8,EddShrT4N02D8,EddShrT4N03D8,EddShrT4N04D8,EddShrT4N05D8,EddShrT4N06D8,EddShrT4N07D8,EddShrT4N08D8,EddShrT4N09D8,EddShrT4N10D8, & - EddShrT4N11D8,EddShrT4N12D8,EddShrT4N13D8,EddShrT4N14D8,EddShrT4N15D8,EddShrT4N16D8,EddShrT4N17D8,EddShrT4N18D8,EddShrT4N19D8,EddShrT4N20D8, & - EddShrT4N01D9,EddShrT4N02D9,EddShrT4N03D9,EddShrT4N04D9,EddShrT4N05D9,EddShrT4N06D9,EddShrT4N07D9,EddShrT4N08D9,EddShrT4N09D9,EddShrT4N10D9, & - EddShrT4N11D9,EddShrT4N12D9,EddShrT4N13D9,EddShrT4N14D9,EddShrT4N15D9,EddShrT4N16D9,EddShrT4N17D9,EddShrT4N18D9,EddShrT4N19D9,EddShrT4N20D9/), (/20,9/) ) - -EddShrTND(:,:,5) = RESHAPE( & - (/EddShrT5N01D1,EddShrT5N02D1,EddShrT5N03D1,EddShrT5N04D1,EddShrT5N05D1,EddShrT5N06D1,EddShrT5N07D1,EddShrT5N08D1,EddShrT5N09D1,EddShrT5N10D1, & - EddShrT5N11D1,EddShrT5N12D1,EddShrT5N13D1,EddShrT5N14D1,EddShrT5N15D1,EddShrT5N16D1,EddShrT5N17D1,EddShrT5N18D1,EddShrT5N19D1,EddShrT5N20D1, & - EddShrT5N01D2,EddShrT5N02D2,EddShrT5N03D2,EddShrT5N04D2,EddShrT5N05D2,EddShrT5N06D2,EddShrT5N07D2,EddShrT5N08D2,EddShrT5N09D2,EddShrT5N10D2, & - EddShrT5N11D2,EddShrT5N12D2,EddShrT5N13D2,EddShrT5N14D2,EddShrT5N15D2,EddShrT5N16D2,EddShrT5N17D2,EddShrT5N18D2,EddShrT5N19D2,EddShrT5N20D2, & - EddShrT5N01D3,EddShrT5N02D3,EddShrT5N03D3,EddShrT5N04D3,EddShrT5N05D3,EddShrT5N06D3,EddShrT5N07D3,EddShrT5N08D3,EddShrT5N09D3,EddShrT5N10D3, & - EddShrT5N11D3,EddShrT5N12D3,EddShrT5N13D3,EddShrT5N14D3,EddShrT5N15D3,EddShrT5N16D3,EddShrT5N17D3,EddShrT5N18D3,EddShrT5N19D3,EddShrT5N20D3, & - EddShrT5N01D4,EddShrT5N02D4,EddShrT5N03D4,EddShrT5N04D4,EddShrT5N05D4,EddShrT5N06D4,EddShrT5N07D4,EddShrT5N08D4,EddShrT5N09D4,EddShrT5N10D4, & - EddShrT5N11D4,EddShrT5N12D4,EddShrT5N13D4,EddShrT5N14D4,EddShrT5N15D4,EddShrT5N16D4,EddShrT5N17D4,EddShrT5N18D4,EddShrT5N19D4,EddShrT5N20D4, & - EddShrT5N01D5,EddShrT5N02D5,EddShrT5N03D5,EddShrT5N04D5,EddShrT5N05D5,EddShrT5N06D5,EddShrT5N07D5,EddShrT5N08D5,EddShrT5N09D5,EddShrT5N10D5, & - EddShrT5N11D5,EddShrT5N12D5,EddShrT5N13D5,EddShrT5N14D5,EddShrT5N15D5,EddShrT5N16D5,EddShrT5N17D5,EddShrT5N18D5,EddShrT5N19D5,EddShrT5N20D5, & - EddShrT5N01D6,EddShrT5N02D6,EddShrT5N03D6,EddShrT5N04D6,EddShrT5N05D6,EddShrT5N06D6,EddShrT5N07D6,EddShrT5N08D6,EddShrT5N09D6,EddShrT5N10D6, & - EddShrT5N11D6,EddShrT5N12D6,EddShrT5N13D6,EddShrT5N14D6,EddShrT5N15D6,EddShrT5N16D6,EddShrT5N17D6,EddShrT5N18D6,EddShrT5N19D6,EddShrT5N20D6, & - EddShrT5N01D7,EddShrT5N02D7,EddShrT5N03D7,EddShrT5N04D7,EddShrT5N05D7,EddShrT5N06D7,EddShrT5N07D7,EddShrT5N08D7,EddShrT5N09D7,EddShrT5N10D7, & - EddShrT5N11D7,EddShrT5N12D7,EddShrT5N13D7,EddShrT5N14D7,EddShrT5N15D7,EddShrT5N16D7,EddShrT5N17D7,EddShrT5N18D7,EddShrT5N19D7,EddShrT5N20D7, & - EddShrT5N01D8,EddShrT5N02D8,EddShrT5N03D8,EddShrT5N04D8,EddShrT5N05D8,EddShrT5N06D8,EddShrT5N07D8,EddShrT5N08D8,EddShrT5N09D8,EddShrT5N10D8, & - EddShrT5N11D8,EddShrT5N12D8,EddShrT5N13D8,EddShrT5N14D8,EddShrT5N15D8,EddShrT5N16D8,EddShrT5N17D8,EddShrT5N18D8,EddShrT5N19D8,EddShrT5N20D8, & - EddShrT5N01D9,EddShrT5N02D9,EddShrT5N03D9,EddShrT5N04D9,EddShrT5N05D9,EddShrT5N06D9,EddShrT5N07D9,EddShrT5N08D9,EddShrT5N09D9,EddShrT5N10D9, & - EddShrT5N11D9,EddShrT5N12D9,EddShrT5N13D9,EddShrT5N14D9,EddShrT5N15D9,EddShrT5N16D9,EddShrT5N17D9,EddShrT5N18D9,EddShrT5N19D9,EddShrT5N20D9/), (/20,9/) ) -EddShrTND(:,:,6) = RESHAPE( & - (/EddShrT6N01D1,EddShrT6N02D1,EddShrT6N03D1,EddShrT6N04D1,EddShrT6N05D1,EddShrT6N06D1,EddShrT6N07D1,EddShrT6N08D1,EddShrT6N09D1,EddShrT6N10D1, & - EddShrT6N11D1,EddShrT6N12D1,EddShrT6N13D1,EddShrT6N14D1,EddShrT6N15D1,EddShrT6N16D1,EddShrT6N17D1,EddShrT6N18D1,EddShrT6N19D1,EddShrT6N20D1, & - EddShrT6N01D2,EddShrT6N02D2,EddShrT6N03D2,EddShrT6N04D2,EddShrT6N05D2,EddShrT6N06D2,EddShrT6N07D2,EddShrT6N08D2,EddShrT6N09D2,EddShrT6N10D2, & - EddShrT6N11D2,EddShrT6N12D2,EddShrT6N13D2,EddShrT6N14D2,EddShrT6N15D2,EddShrT6N16D2,EddShrT6N17D2,EddShrT6N18D2,EddShrT6N19D2,EddShrT6N20D2, & - EddShrT6N01D3,EddShrT6N02D3,EddShrT6N03D3,EddShrT6N04D3,EddShrT6N05D3,EddShrT6N06D3,EddShrT6N07D3,EddShrT6N08D3,EddShrT6N09D3,EddShrT6N10D3, & - EddShrT6N11D3,EddShrT6N12D3,EddShrT6N13D3,EddShrT6N14D3,EddShrT6N15D3,EddShrT6N16D3,EddShrT6N17D3,EddShrT6N18D3,EddShrT6N19D3,EddShrT6N20D3, & - EddShrT6N01D4,EddShrT6N02D4,EddShrT6N03D4,EddShrT6N04D4,EddShrT6N05D4,EddShrT6N06D4,EddShrT6N07D4,EddShrT6N08D4,EddShrT6N09D4,EddShrT6N10D4, & - EddShrT6N11D4,EddShrT6N12D4,EddShrT6N13D4,EddShrT6N14D4,EddShrT6N15D4,EddShrT6N16D4,EddShrT6N17D4,EddShrT6N18D4,EddShrT6N19D4,EddShrT6N20D4, & - EddShrT6N01D5,EddShrT6N02D5,EddShrT6N03D5,EddShrT6N04D5,EddShrT6N05D5,EddShrT6N06D5,EddShrT6N07D5,EddShrT6N08D5,EddShrT6N09D5,EddShrT6N10D5, & - EddShrT6N11D5,EddShrT6N12D5,EddShrT6N13D5,EddShrT6N14D5,EddShrT6N15D5,EddShrT6N16D5,EddShrT6N17D5,EddShrT6N18D5,EddShrT6N19D5,EddShrT6N20D5, & - EddShrT6N01D6,EddShrT6N02D6,EddShrT6N03D6,EddShrT6N04D6,EddShrT6N05D6,EddShrT6N06D6,EddShrT6N07D6,EddShrT6N08D6,EddShrT6N09D6,EddShrT6N10D6, & - EddShrT6N11D6,EddShrT6N12D6,EddShrT6N13D6,EddShrT6N14D6,EddShrT6N15D6,EddShrT6N16D6,EddShrT6N17D6,EddShrT6N18D6,EddShrT6N19D6,EddShrT6N20D6, & - EddShrT6N01D7,EddShrT6N02D7,EddShrT6N03D7,EddShrT6N04D7,EddShrT6N05D7,EddShrT6N06D7,EddShrT6N07D7,EddShrT6N08D7,EddShrT6N09D7,EddShrT6N10D7, & - EddShrT6N11D7,EddShrT6N12D7,EddShrT6N13D7,EddShrT6N14D7,EddShrT6N15D7,EddShrT6N16D7,EddShrT6N17D7,EddShrT6N18D7,EddShrT6N19D7,EddShrT6N20D7, & - EddShrT6N01D8,EddShrT6N02D8,EddShrT6N03D8,EddShrT6N04D8,EddShrT6N05D8,EddShrT6N06D8,EddShrT6N07D8,EddShrT6N08D8,EddShrT6N09D8,EddShrT6N10D8, & - EddShrT6N11D8,EddShrT6N12D8,EddShrT6N13D8,EddShrT6N14D8,EddShrT6N15D8,EddShrT6N16D8,EddShrT6N17D8,EddShrT6N18D8,EddShrT6N19D8,EddShrT6N20D8, & - EddShrT6N01D9,EddShrT6N02D9,EddShrT6N03D9,EddShrT6N04D9,EddShrT6N05D9,EddShrT6N06D9,EddShrT6N07D9,EddShrT6N08D9,EddShrT6N09D9,EddShrT6N10D9, & - EddShrT6N11D9,EddShrT6N12D9,EddShrT6N13D9,EddShrT6N14D9,EddShrT6N15D9,EddShrT6N16D9,EddShrT6N17D9,EddShrT6N18D9,EddShrT6N19D9,EddShrT6N20D9/), (/20,9/) ) -EddShrTND(:,:,7) = RESHAPE( & - (/EddShrT7N01D1,EddShrT7N02D1,EddShrT7N03D1,EddShrT7N04D1,EddShrT7N05D1,EddShrT7N06D1,EddShrT7N07D1,EddShrT7N08D1,EddShrT7N09D1,EddShrT7N10D1, & - EddShrT7N11D1,EddShrT7N12D1,EddShrT7N13D1,EddShrT7N14D1,EddShrT7N15D1,EddShrT7N16D1,EddShrT7N17D1,EddShrT7N18D1,EddShrT7N19D1,EddShrT7N20D1, & - EddShrT7N01D2,EddShrT7N02D2,EddShrT7N03D2,EddShrT7N04D2,EddShrT7N05D2,EddShrT7N06D2,EddShrT7N07D2,EddShrT7N08D2,EddShrT7N09D2,EddShrT7N10D2, & - EddShrT7N11D2,EddShrT7N12D2,EddShrT7N13D2,EddShrT7N14D2,EddShrT7N15D2,EddShrT7N16D2,EddShrT7N17D2,EddShrT7N18D2,EddShrT7N19D2,EddShrT7N20D2, & - EddShrT7N01D3,EddShrT7N02D3,EddShrT7N03D3,EddShrT7N04D3,EddShrT7N05D3,EddShrT7N06D3,EddShrT7N07D3,EddShrT7N08D3,EddShrT7N09D3,EddShrT7N10D3, & - EddShrT7N11D3,EddShrT7N12D3,EddShrT7N13D3,EddShrT7N14D3,EddShrT7N15D3,EddShrT7N16D3,EddShrT7N17D3,EddShrT7N18D3,EddShrT7N19D3,EddShrT7N20D3, & - EddShrT7N01D4,EddShrT7N02D4,EddShrT7N03D4,EddShrT7N04D4,EddShrT7N05D4,EddShrT7N06D4,EddShrT7N07D4,EddShrT7N08D4,EddShrT7N09D4,EddShrT7N10D4, & - EddShrT7N11D4,EddShrT7N12D4,EddShrT7N13D4,EddShrT7N14D4,EddShrT7N15D4,EddShrT7N16D4,EddShrT7N17D4,EddShrT7N18D4,EddShrT7N19D4,EddShrT7N20D4, & - EddShrT7N01D5,EddShrT7N02D5,EddShrT7N03D5,EddShrT7N04D5,EddShrT7N05D5,EddShrT7N06D5,EddShrT7N07D5,EddShrT7N08D5,EddShrT7N09D5,EddShrT7N10D5, & - EddShrT7N11D5,EddShrT7N12D5,EddShrT7N13D5,EddShrT7N14D5,EddShrT7N15D5,EddShrT7N16D5,EddShrT7N17D5,EddShrT7N18D5,EddShrT7N19D5,EddShrT7N20D5, & - EddShrT7N01D6,EddShrT7N02D6,EddShrT7N03D6,EddShrT7N04D6,EddShrT7N05D6,EddShrT7N06D6,EddShrT7N07D6,EddShrT7N08D6,EddShrT7N09D6,EddShrT7N10D6, & - EddShrT7N11D6,EddShrT7N12D6,EddShrT7N13D6,EddShrT7N14D6,EddShrT7N15D6,EddShrT7N16D6,EddShrT7N17D6,EddShrT7N18D6,EddShrT7N19D6,EddShrT7N20D6, & - EddShrT7N01D7,EddShrT7N02D7,EddShrT7N03D7,EddShrT7N04D7,EddShrT7N05D7,EddShrT7N06D7,EddShrT7N07D7,EddShrT7N08D7,EddShrT7N09D7,EddShrT7N10D7, & - EddShrT7N11D7,EddShrT7N12D7,EddShrT7N13D7,EddShrT7N14D7,EddShrT7N15D7,EddShrT7N16D7,EddShrT7N17D7,EddShrT7N18D7,EddShrT7N19D7,EddShrT7N20D7, & - EddShrT7N01D8,EddShrT7N02D8,EddShrT7N03D8,EddShrT7N04D8,EddShrT7N05D8,EddShrT7N06D8,EddShrT7N07D8,EddShrT7N08D8,EddShrT7N09D8,EddShrT7N10D8, & - EddShrT7N11D8,EddShrT7N12D8,EddShrT7N13D8,EddShrT7N14D8,EddShrT7N15D8,EddShrT7N16D8,EddShrT7N17D8,EddShrT7N18D8,EddShrT7N19D8,EddShrT7N20D8, & - EddShrT7N01D9,EddShrT7N02D9,EddShrT7N03D9,EddShrT7N04D9,EddShrT7N05D9,EddShrT7N06D9,EddShrT7N07D9,EddShrT7N08D9,EddShrT7N09D9,EddShrT7N10D9, & - EddShrT7N11D9,EddShrT7N12D9,EddShrT7N13D9,EddShrT7N14D9,EddShrT7N15D9,EddShrT7N16D9,EddShrT7N17D9,EddShrT7N18D9,EddShrT7N19D9,EddShrT7N20D9/), (/20,9/) ) -EddShrTND(:,:,8) = RESHAPE( & - (/EddShrT8N01D1,EddShrT8N02D1,EddShrT8N03D1,EddShrT8N04D1,EddShrT8N05D1,EddShrT8N06D1,EddShrT8N07D1,EddShrT8N08D1,EddShrT8N09D1,EddShrT8N10D1, & - EddShrT8N11D1,EddShrT8N12D1,EddShrT8N13D1,EddShrT8N14D1,EddShrT8N15D1,EddShrT8N16D1,EddShrT8N17D1,EddShrT8N18D1,EddShrT8N19D1,EddShrT8N20D1, & - EddShrT8N01D2,EddShrT8N02D2,EddShrT8N03D2,EddShrT8N04D2,EddShrT8N05D2,EddShrT8N06D2,EddShrT8N07D2,EddShrT8N08D2,EddShrT8N09D2,EddShrT8N10D2, & - EddShrT8N11D2,EddShrT8N12D2,EddShrT8N13D2,EddShrT8N14D2,EddShrT8N15D2,EddShrT8N16D2,EddShrT8N17D2,EddShrT8N18D2,EddShrT8N19D2,EddShrT8N20D2, & - EddShrT8N01D3,EddShrT8N02D3,EddShrT8N03D3,EddShrT8N04D3,EddShrT8N05D3,EddShrT8N06D3,EddShrT8N07D3,EddShrT8N08D3,EddShrT8N09D3,EddShrT8N10D3, & - EddShrT8N11D3,EddShrT8N12D3,EddShrT8N13D3,EddShrT8N14D3,EddShrT8N15D3,EddShrT8N16D3,EddShrT8N17D3,EddShrT8N18D3,EddShrT8N19D3,EddShrT8N20D3, & - EddShrT8N01D4,EddShrT8N02D4,EddShrT8N03D4,EddShrT8N04D4,EddShrT8N05D4,EddShrT8N06D4,EddShrT8N07D4,EddShrT8N08D4,EddShrT8N09D4,EddShrT8N10D4, & - EddShrT8N11D4,EddShrT8N12D4,EddShrT8N13D4,EddShrT8N14D4,EddShrT8N15D4,EddShrT8N16D4,EddShrT8N17D4,EddShrT8N18D4,EddShrT8N19D4,EddShrT8N20D4, & - EddShrT8N01D5,EddShrT8N02D5,EddShrT8N03D5,EddShrT8N04D5,EddShrT8N05D5,EddShrT8N06D5,EddShrT8N07D5,EddShrT8N08D5,EddShrT8N09D5,EddShrT8N10D5, & - EddShrT8N11D5,EddShrT8N12D5,EddShrT8N13D5,EddShrT8N14D5,EddShrT8N15D5,EddShrT8N16D5,EddShrT8N17D5,EddShrT8N18D5,EddShrT8N19D5,EddShrT8N20D5, & - EddShrT8N01D6,EddShrT8N02D6,EddShrT8N03D6,EddShrT8N04D6,EddShrT8N05D6,EddShrT8N06D6,EddShrT8N07D6,EddShrT8N08D6,EddShrT8N09D6,EddShrT8N10D6, & - EddShrT8N11D6,EddShrT8N12D6,EddShrT8N13D6,EddShrT8N14D6,EddShrT8N15D6,EddShrT8N16D6,EddShrT8N17D6,EddShrT8N18D6,EddShrT8N19D6,EddShrT8N20D6, & - EddShrT8N01D7,EddShrT8N02D7,EddShrT8N03D7,EddShrT8N04D7,EddShrT8N05D7,EddShrT8N06D7,EddShrT8N07D7,EddShrT8N08D7,EddShrT8N09D7,EddShrT8N10D7, & - EddShrT8N11D7,EddShrT8N12D7,EddShrT8N13D7,EddShrT8N14D7,EddShrT8N15D7,EddShrT8N16D7,EddShrT8N17D7,EddShrT8N18D7,EddShrT8N19D7,EddShrT8N20D7, & - EddShrT8N01D8,EddShrT8N02D8,EddShrT8N03D8,EddShrT8N04D8,EddShrT8N05D8,EddShrT8N06D8,EddShrT8N07D8,EddShrT8N08D8,EddShrT8N09D8,EddShrT8N10D8, & - EddShrT8N11D8,EddShrT8N12D8,EddShrT8N13D8,EddShrT8N14D8,EddShrT8N15D8,EddShrT8N16D8,EddShrT8N17D8,EddShrT8N18D8,EddShrT8N19D8,EddShrT8N20D8, & - EddShrT8N01D9,EddShrT8N02D9,EddShrT8N03D9,EddShrT8N04D9,EddShrT8N05D9,EddShrT8N06D9,EddShrT8N07D9,EddShrT8N08D9,EddShrT8N09D9,EddShrT8N10D9, & - EddShrT8N11D9,EddShrT8N12D9,EddShrT8N13D9,EddShrT8N14D9,EddShrT8N15D9,EddShrT8N16D9,EddShrT8N17D9,EddShrT8N18D9,EddShrT8N19D9,EddShrT8N20D9/), (/20,9/) ) -EddShrTND(:,:,9) = RESHAPE( & - (/EddShrT9N01D1,EddShrT9N02D1,EddShrT9N03D1,EddShrT9N04D1,EddShrT9N05D1,EddShrT9N06D1,EddShrT9N07D1,EddShrT9N08D1,EddShrT9N09D1,EddShrT9N10D1, & - EddShrT9N11D1,EddShrT9N12D1,EddShrT9N13D1,EddShrT9N14D1,EddShrT9N15D1,EddShrT9N16D1,EddShrT9N17D1,EddShrT9N18D1,EddShrT9N19D1,EddShrT9N20D1, & - EddShrT9N01D2,EddShrT9N02D2,EddShrT9N03D2,EddShrT9N04D2,EddShrT9N05D2,EddShrT9N06D2,EddShrT9N07D2,EddShrT9N08D2,EddShrT9N09D2,EddShrT9N10D2, & - EddShrT9N11D2,EddShrT9N12D2,EddShrT9N13D2,EddShrT9N14D2,EddShrT9N15D2,EddShrT9N16D2,EddShrT9N17D2,EddShrT9N18D2,EddShrT9N19D2,EddShrT9N20D2, & - EddShrT9N01D3,EddShrT9N02D3,EddShrT9N03D3,EddShrT9N04D3,EddShrT9N05D3,EddShrT9N06D3,EddShrT9N07D3,EddShrT9N08D3,EddShrT9N09D3,EddShrT9N10D3, & - EddShrT9N11D3,EddShrT9N12D3,EddShrT9N13D3,EddShrT9N14D3,EddShrT9N15D3,EddShrT9N16D3,EddShrT9N17D3,EddShrT9N18D3,EddShrT9N19D3,EddShrT9N20D3, & - EddShrT9N01D4,EddShrT9N02D4,EddShrT9N03D4,EddShrT9N04D4,EddShrT9N05D4,EddShrT9N06D4,EddShrT9N07D4,EddShrT9N08D4,EddShrT9N09D4,EddShrT9N10D4, & - EddShrT9N11D4,EddShrT9N12D4,EddShrT9N13D4,EddShrT9N14D4,EddShrT9N15D4,EddShrT9N16D4,EddShrT9N17D4,EddShrT9N18D4,EddShrT9N19D4,EddShrT9N20D4, & - EddShrT9N01D5,EddShrT9N02D5,EddShrT9N03D5,EddShrT9N04D5,EddShrT9N05D5,EddShrT9N06D5,EddShrT9N07D5,EddShrT9N08D5,EddShrT9N09D5,EddShrT9N10D5, & - EddShrT9N11D5,EddShrT9N12D5,EddShrT9N13D5,EddShrT9N14D5,EddShrT9N15D5,EddShrT9N16D5,EddShrT9N17D5,EddShrT9N18D5,EddShrT9N19D5,EddShrT9N20D5, & - EddShrT9N01D6,EddShrT9N02D6,EddShrT9N03D6,EddShrT9N04D6,EddShrT9N05D6,EddShrT9N06D6,EddShrT9N07D6,EddShrT9N08D6,EddShrT9N09D6,EddShrT9N10D6, & - EddShrT9N11D6,EddShrT9N12D6,EddShrT9N13D6,EddShrT9N14D6,EddShrT9N15D6,EddShrT9N16D6,EddShrT9N17D6,EddShrT9N18D6,EddShrT9N19D6,EddShrT9N20D6, & - EddShrT9N01D7,EddShrT9N02D7,EddShrT9N03D7,EddShrT9N04D7,EddShrT9N05D7,EddShrT9N06D7,EddShrT9N07D7,EddShrT9N08D7,EddShrT9N09D7,EddShrT9N10D7, & - EddShrT9N11D7,EddShrT9N12D7,EddShrT9N13D7,EddShrT9N14D7,EddShrT9N15D7,EddShrT9N16D7,EddShrT9N17D7,EddShrT9N18D7,EddShrT9N19D7,EddShrT9N20D7, & - EddShrT9N01D8,EddShrT9N02D8,EddShrT9N03D8,EddShrT9N04D8,EddShrT9N05D8,EddShrT9N06D8,EddShrT9N07D8,EddShrT9N08D8,EddShrT9N09D8,EddShrT9N10D8, & - EddShrT9N11D8,EddShrT9N12D8,EddShrT9N13D8,EddShrT9N14D8,EddShrT9N15D8,EddShrT9N16D8,EddShrT9N17D8,EddShrT9N18D8,EddShrT9N19D8,EddShrT9N20D8, & - EddShrT9N01D9,EddShrT9N02D9,EddShrT9N03D9,EddShrT9N04D9,EddShrT9N05D9,EddShrT9N06D9,EddShrT9N07D9,EddShrT9N08D9,EddShrT9N09D9,EddShrT9N10D9, & - EddShrT9N11D9,EddShrT9N12D9,EddShrT9N13D9,EddShrT9N14D9,EddShrT9N15D9,EddShrT9N16D9,EddShrT9N17D9,EddShrT9N18D9,EddShrT9N19D9,EddShrT9N20D9/), (/20,9/) ) -END SUBROUTINE Farm_SetAggregatedChannelOutArrays - - - !---------------------------------------------------------------------------------------------------------------------------------- !> This routine initializes the output for the glue code, including writing the header for the primary output file. SUBROUTINE Farm_InitOutput( farm, ErrStat, ErrMsg ) @@ -11151,3981 +558,4 @@ END SUBROUTINE WriteFarmOutputToFile -logical function PointInAABB(x, y, z, x0, y0, z0, x1, y1, z1) - real(ReKi), intent(in) :: x,y,z,x0,y0,z0,x1,y1,z1 - - ! default to return false - PointInAABB = .false.; - !Check if the point is less than max and greater than min - if (x >= x0 .and. x <= x1 .and. y >= y0 .and. y <= y1 .and. z >= z0 .and. z <= z1) PointInAABB = .true.; - - -end function PointInAABB - -!********************************************************************************************************************************** -! 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 routine checks to see if any requested output channel names (stored in the OutList(:)) are invalid. It returns a -!! warning if any of the channels are not available outputs from the module. -!! It assigns the settings for OutParam(:) (i.e, the index, name, and units of the output channels, WriteOutput(:)). -!! the sign is set to 0 if the channel is invalid. -!! It sets assumes the value p%NumOuts has been set before this routine has been called, and it sets the values of p%OutParam here. -!! -!! This routine was generated by Write_ChckOutLst.m using the parameters listed in OutListParameters.xlsx at 27-Mar-2017 17:26:42. -SUBROUTINE Farm_SetOutParam(OutList, farm, ErrStat, ErrMsg ) -!.................................................................................................................................. - - IMPLICIT NONE - - ! Passed variables - - CHARACTER(ChanLen), INTENT(IN) :: OutList(:) !< The list out user-requested outputs - type(All_FastFarm_Data), INTENT(INOUT) :: farm !< FAST.Farm data - INTEGER(IntKi), INTENT(OUT) :: ErrStat !< The error status code - CHARACTER(*), INTENT(OUT) :: ErrMsg !< The error message, if an error occurred - - ! Local variables - - INTEGER :: ErrStat2 ! temporary (local) error status - INTEGER :: I ! Generic loop-counting index - INTEGER :: J ! Generic loop-counting index - INTEGER :: INDX ! Index for valid arrays - - LOGICAL :: CheckOutListAgain ! Flag used to determine if output parameter starting with "M" is valid (or the negative of another parameter) - LOGICAL :: InvalidOutput(0:Farm_MaxOutPts) ! This array determines if the output channel is valid for this configuration - CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I) - CHARACTER(*), PARAMETER :: RoutineName = "SetOutParam" - - CHARACTER(Farm_OutStrLenM1) :: ValidParamAry(9423) ! This lists the names of the allowed parameters, which must be sorted alphabetically - INTEGER(IntKi) :: ParamIndxAry (9423) ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) CHARACTER(ChanLen), :: ParamUnitsAry(9423) ! This lists the units corresponding to the allowed parameters - CHARACTER(ChanLen) :: ParamUnitsAry(9423) ! This lists the units corresponding to the allowed parameters - - ValidParamAry(1:2040) = (/ & - "CTT1N01 ","CTT1N02 ","CTT1N03 ","CTT1N04 ","CTT1N05 ","CTT1N06 ","CTT1N07 ","CTT1N08 ", & - "CTT1N09 ","CTT1N10 ","CTT1N11 ","CTT1N12 ","CTT1N13 ","CTT1N14 ","CTT1N15 ","CTT1N16 ", & - "CTT1N17 ","CTT1N18 ","CTT1N19 ","CTT1N20 ","CTT2N01 ","CTT2N02 ","CTT2N03 ","CTT2N04 ", & - "CTT2N05 ","CTT2N06 ","CTT2N07 ","CTT2N08 ","CTT2N09 ","CTT2N10 ","CTT2N11 ","CTT2N12 ", & - "CTT2N13 ","CTT2N14 ","CTT2N15 ","CTT2N16 ","CTT2N17 ","CTT2N18 ","CTT2N19 ","CTT2N20 ", & - "CTT3N01 ","CTT3N02 ","CTT3N03 ","CTT3N04 ","CTT3N05 ","CTT3N06 ","CTT3N07 ","CTT3N08 ", & - "CTT3N09 ","CTT3N10 ","CTT3N11 ","CTT3N12 ","CTT3N13 ","CTT3N14 ","CTT3N15 ","CTT3N16 ", & - "CTT3N17 ","CTT3N18 ","CTT3N19 ","CTT3N20 ","CTT4N01 ","CTT4N02 ","CTT4N03 ","CTT4N04 ", & - "CTT4N05 ","CTT4N06 ","CTT4N07 ","CTT4N08 ","CTT4N09 ","CTT4N10 ","CTT4N11 ","CTT4N12 ", & - "CTT4N13 ","CTT4N14 ","CTT4N15 ","CTT4N16 ","CTT4N17 ","CTT4N18 ","CTT4N19 ","CTT4N20 ", & - "CTT5N01 ","CTT5N02 ","CTT5N03 ","CTT5N04 ","CTT5N05 ","CTT5N06 ","CTT5N07 ","CTT5N08 ", & - "CTT5N09 ","CTT5N10 ","CTT5N11 ","CTT5N12 ","CTT5N13 ","CTT5N14 ","CTT5N15 ","CTT5N16 ", & - "CTT5N17 ","CTT5N18 ","CTT5N19 ","CTT5N20 ","CTT6N01 ","CTT6N02 ","CTT6N03 ","CTT6N04 ", & - "CTT6N05 ","CTT6N06 ","CTT6N07 ","CTT6N08 ","CTT6N09 ","CTT6N10 ","CTT6N11 ","CTT6N12 ", & - "CTT6N13 ","CTT6N14 ","CTT6N15 ","CTT6N16 ","CTT6N17 ","CTT6N18 ","CTT6N19 ","CTT6N20 ", & - "CTT7N01 ","CTT7N02 ","CTT7N03 ","CTT7N04 ","CTT7N05 ","CTT7N06 ","CTT7N07 ","CTT7N08 ", & - "CTT7N09 ","CTT7N10 ","CTT7N11 ","CTT7N12 ","CTT7N13 ","CTT7N14 ","CTT7N15 ","CTT7N16 ", & - "CTT7N17 ","CTT7N18 ","CTT7N19 ","CTT7N20 ","CTT8N01 ","CTT8N02 ","CTT8N03 ","CTT8N04 ", & - "CTT8N05 ","CTT8N06 ","CTT8N07 ","CTT8N08 ","CTT8N09 ","CTT8N10 ","CTT8N11 ","CTT8N12 ", & - "CTT8N13 ","CTT8N14 ","CTT8N15 ","CTT8N16 ","CTT8N17 ","CTT8N18 ","CTT8N19 ","CTT8N20 ", & - "CTT9N01 ","CTT9N02 ","CTT9N03 ","CTT9N04 ","CTT9N05 ","CTT9N06 ","CTT9N07 ","CTT9N08 ", & - "CTT9N09 ","CTT9N10 ","CTT9N11 ","CTT9N12 ","CTT9N13 ","CTT9N14 ","CTT9N15 ","CTT9N16 ", & - "CTT9N17 ","CTT9N18 ","CTT9N19 ","CTT9N20 ","EDDAMBT1N01D1","EDDAMBT1N01D2","EDDAMBT1N01D3","EDDAMBT1N01D4", & - "EDDAMBT1N01D5","EDDAMBT1N01D6","EDDAMBT1N01D7","EDDAMBT1N01D8","EDDAMBT1N01D9","EDDAMBT1N02D1","EDDAMBT1N02D2","EDDAMBT1N02D3", & - "EDDAMBT1N02D4","EDDAMBT1N02D5","EDDAMBT1N02D6","EDDAMBT1N02D7","EDDAMBT1N02D8","EDDAMBT1N02D9","EDDAMBT1N03D1","EDDAMBT1N03D2", & - "EDDAMBT1N03D3","EDDAMBT1N03D4","EDDAMBT1N03D5","EDDAMBT1N03D6","EDDAMBT1N03D7","EDDAMBT1N03D8","EDDAMBT1N03D9","EDDAMBT1N04D1", & - "EDDAMBT1N04D2","EDDAMBT1N04D3","EDDAMBT1N04D4","EDDAMBT1N04D5","EDDAMBT1N04D6","EDDAMBT1N04D7","EDDAMBT1N04D8","EDDAMBT1N04D9", & - "EDDAMBT1N05D1","EDDAMBT1N05D2","EDDAMBT1N05D3","EDDAMBT1N05D4","EDDAMBT1N05D5","EDDAMBT1N05D6","EDDAMBT1N05D7","EDDAMBT1N05D8", & - "EDDAMBT1N05D9","EDDAMBT1N06D1","EDDAMBT1N06D2","EDDAMBT1N06D3","EDDAMBT1N06D4","EDDAMBT1N06D5","EDDAMBT1N06D6","EDDAMBT1N06D7", & - "EDDAMBT1N06D8","EDDAMBT1N06D9","EDDAMBT1N07D1","EDDAMBT1N07D2","EDDAMBT1N07D3","EDDAMBT1N07D4","EDDAMBT1N07D5","EDDAMBT1N07D6", & - "EDDAMBT1N07D7","EDDAMBT1N07D8","EDDAMBT1N07D9","EDDAMBT1N08D1","EDDAMBT1N08D2","EDDAMBT1N08D3","EDDAMBT1N08D4","EDDAMBT1N08D5", & - "EDDAMBT1N08D6","EDDAMBT1N08D7","EDDAMBT1N08D8","EDDAMBT1N08D9","EDDAMBT1N09D1","EDDAMBT1N09D2","EDDAMBT1N09D3","EDDAMBT1N09D4", & - "EDDAMBT1N09D5","EDDAMBT1N09D6","EDDAMBT1N09D7","EDDAMBT1N09D8","EDDAMBT1N09D9","EDDAMBT1N10D1","EDDAMBT1N10D2","EDDAMBT1N10D3", & - "EDDAMBT1N10D4","EDDAMBT1N10D5","EDDAMBT1N10D6","EDDAMBT1N10D7","EDDAMBT1N10D8","EDDAMBT1N10D9","EDDAMBT1N11D1","EDDAMBT1N11D2", & - "EDDAMBT1N11D3","EDDAMBT1N11D4","EDDAMBT1N11D5","EDDAMBT1N11D6","EDDAMBT1N11D7","EDDAMBT1N11D8","EDDAMBT1N11D9","EDDAMBT1N12D1", & - "EDDAMBT1N12D2","EDDAMBT1N12D3","EDDAMBT1N12D4","EDDAMBT1N12D5","EDDAMBT1N12D6","EDDAMBT1N12D7","EDDAMBT1N12D8","EDDAMBT1N12D9", & - "EDDAMBT1N13D1","EDDAMBT1N13D2","EDDAMBT1N13D3","EDDAMBT1N13D4","EDDAMBT1N13D5","EDDAMBT1N13D6","EDDAMBT1N13D7","EDDAMBT1N13D8", & - "EDDAMBT1N13D9","EDDAMBT1N14D1","EDDAMBT1N14D2","EDDAMBT1N14D3","EDDAMBT1N14D4","EDDAMBT1N14D5","EDDAMBT1N14D6","EDDAMBT1N14D7", & - "EDDAMBT1N14D8","EDDAMBT1N14D9","EDDAMBT1N15D1","EDDAMBT1N15D2","EDDAMBT1N15D3","EDDAMBT1N15D4","EDDAMBT1N15D5","EDDAMBT1N15D6", & - "EDDAMBT1N15D7","EDDAMBT1N15D8","EDDAMBT1N15D9","EDDAMBT1N16D1","EDDAMBT1N16D2","EDDAMBT1N16D3","EDDAMBT1N16D4","EDDAMBT1N16D5", & - "EDDAMBT1N16D6","EDDAMBT1N16D7","EDDAMBT1N16D8","EDDAMBT1N16D9","EDDAMBT1N17D1","EDDAMBT1N17D2","EDDAMBT1N17D3","EDDAMBT1N17D4", & - "EDDAMBT1N17D5","EDDAMBT1N17D6","EDDAMBT1N17D7","EDDAMBT1N17D8","EDDAMBT1N17D9","EDDAMBT1N18D1","EDDAMBT1N18D2","EDDAMBT1N18D3", & - "EDDAMBT1N18D4","EDDAMBT1N18D5","EDDAMBT1N18D6","EDDAMBT1N18D7","EDDAMBT1N18D8","EDDAMBT1N18D9","EDDAMBT1N19D1","EDDAMBT1N19D2", & - "EDDAMBT1N19D3","EDDAMBT1N19D4","EDDAMBT1N19D5","EDDAMBT1N19D6","EDDAMBT1N19D7","EDDAMBT1N19D8","EDDAMBT1N19D9","EDDAMBT1N20D1", & - "EDDAMBT1N20D2","EDDAMBT1N20D3","EDDAMBT1N20D4","EDDAMBT1N20D5","EDDAMBT1N20D6","EDDAMBT1N20D7","EDDAMBT1N20D8","EDDAMBT1N20D9", & - "EDDAMBT2N01D1","EDDAMBT2N01D2","EDDAMBT2N01D3","EDDAMBT2N01D4","EDDAMBT2N01D5","EDDAMBT2N01D6","EDDAMBT2N01D7","EDDAMBT2N01D8", & - "EDDAMBT2N01D9","EDDAMBT2N02D1","EDDAMBT2N02D2","EDDAMBT2N02D3","EDDAMBT2N02D4","EDDAMBT2N02D5","EDDAMBT2N02D6","EDDAMBT2N02D7", & - "EDDAMBT2N02D8","EDDAMBT2N02D9","EDDAMBT2N03D1","EDDAMBT2N03D2","EDDAMBT2N03D3","EDDAMBT2N03D4","EDDAMBT2N03D5","EDDAMBT2N03D6", & - "EDDAMBT2N03D7","EDDAMBT2N03D8","EDDAMBT2N03D9","EDDAMBT2N04D1","EDDAMBT2N04D2","EDDAMBT2N04D3","EDDAMBT2N04D4","EDDAMBT2N04D5", & - "EDDAMBT2N04D6","EDDAMBT2N04D7","EDDAMBT2N04D8","EDDAMBT2N04D9","EDDAMBT2N05D1","EDDAMBT2N05D2","EDDAMBT2N05D3","EDDAMBT2N05D4", & - "EDDAMBT2N05D5","EDDAMBT2N05D6","EDDAMBT2N05D7","EDDAMBT2N05D8","EDDAMBT2N05D9","EDDAMBT2N06D1","EDDAMBT2N06D2","EDDAMBT2N06D3", & - "EDDAMBT2N06D4","EDDAMBT2N06D5","EDDAMBT2N06D6","EDDAMBT2N06D7","EDDAMBT2N06D8","EDDAMBT2N06D9","EDDAMBT2N07D1","EDDAMBT2N07D2", & - "EDDAMBT2N07D3","EDDAMBT2N07D4","EDDAMBT2N07D5","EDDAMBT2N07D6","EDDAMBT2N07D7","EDDAMBT2N07D8","EDDAMBT2N07D9","EDDAMBT2N08D1", & - "EDDAMBT2N08D2","EDDAMBT2N08D3","EDDAMBT2N08D4","EDDAMBT2N08D5","EDDAMBT2N08D6","EDDAMBT2N08D7","EDDAMBT2N08D8","EDDAMBT2N08D9", & - "EDDAMBT2N09D1","EDDAMBT2N09D2","EDDAMBT2N09D3","EDDAMBT2N09D4","EDDAMBT2N09D5","EDDAMBT2N09D6","EDDAMBT2N09D7","EDDAMBT2N09D8", & - "EDDAMBT2N09D9","EDDAMBT2N10D1","EDDAMBT2N10D2","EDDAMBT2N10D3","EDDAMBT2N10D4","EDDAMBT2N10D5","EDDAMBT2N10D6","EDDAMBT2N10D7", & - "EDDAMBT2N10D8","EDDAMBT2N10D9","EDDAMBT2N11D1","EDDAMBT2N11D2","EDDAMBT2N11D3","EDDAMBT2N11D4","EDDAMBT2N11D5","EDDAMBT2N11D6", & - "EDDAMBT2N11D7","EDDAMBT2N11D8","EDDAMBT2N11D9","EDDAMBT2N12D1","EDDAMBT2N12D2","EDDAMBT2N12D3","EDDAMBT2N12D4","EDDAMBT2N12D5", & - "EDDAMBT2N12D6","EDDAMBT2N12D7","EDDAMBT2N12D8","EDDAMBT2N12D9","EDDAMBT2N13D1","EDDAMBT2N13D2","EDDAMBT2N13D3","EDDAMBT2N13D4", & - "EDDAMBT2N13D5","EDDAMBT2N13D6","EDDAMBT2N13D7","EDDAMBT2N13D8","EDDAMBT2N13D9","EDDAMBT2N14D1","EDDAMBT2N14D2","EDDAMBT2N14D3", & - "EDDAMBT2N14D4","EDDAMBT2N14D5","EDDAMBT2N14D6","EDDAMBT2N14D7","EDDAMBT2N14D8","EDDAMBT2N14D9","EDDAMBT2N15D1","EDDAMBT2N15D2", & - "EDDAMBT2N15D3","EDDAMBT2N15D4","EDDAMBT2N15D5","EDDAMBT2N15D6","EDDAMBT2N15D7","EDDAMBT2N15D8","EDDAMBT2N15D9","EDDAMBT2N16D1", & - "EDDAMBT2N16D2","EDDAMBT2N16D3","EDDAMBT2N16D4","EDDAMBT2N16D5","EDDAMBT2N16D6","EDDAMBT2N16D7","EDDAMBT2N16D8","EDDAMBT2N16D9", & - "EDDAMBT2N17D1","EDDAMBT2N17D2","EDDAMBT2N17D3","EDDAMBT2N17D4","EDDAMBT2N17D5","EDDAMBT2N17D6","EDDAMBT2N17D7","EDDAMBT2N17D8", & - "EDDAMBT2N17D9","EDDAMBT2N18D1","EDDAMBT2N18D2","EDDAMBT2N18D3","EDDAMBT2N18D4","EDDAMBT2N18D5","EDDAMBT2N18D6","EDDAMBT2N18D7", & - "EDDAMBT2N18D8","EDDAMBT2N18D9","EDDAMBT2N19D1","EDDAMBT2N19D2","EDDAMBT2N19D3","EDDAMBT2N19D4","EDDAMBT2N19D5","EDDAMBT2N19D6", & - "EDDAMBT2N19D7","EDDAMBT2N19D8","EDDAMBT2N19D9","EDDAMBT2N20D1","EDDAMBT2N20D2","EDDAMBT2N20D3","EDDAMBT2N20D4","EDDAMBT2N20D5", & - "EDDAMBT2N20D6","EDDAMBT2N20D7","EDDAMBT2N20D8","EDDAMBT2N20D9","EDDAMBT3N01D1","EDDAMBT3N01D2","EDDAMBT3N01D3","EDDAMBT3N01D4", & - "EDDAMBT3N01D5","EDDAMBT3N01D6","EDDAMBT3N01D7","EDDAMBT3N01D8","EDDAMBT3N01D9","EDDAMBT3N02D1","EDDAMBT3N02D2","EDDAMBT3N02D3", & - "EDDAMBT3N02D4","EDDAMBT3N02D5","EDDAMBT3N02D6","EDDAMBT3N02D7","EDDAMBT3N02D8","EDDAMBT3N02D9","EDDAMBT3N03D1","EDDAMBT3N03D2", & - "EDDAMBT3N03D3","EDDAMBT3N03D4","EDDAMBT3N03D5","EDDAMBT3N03D6","EDDAMBT3N03D7","EDDAMBT3N03D8","EDDAMBT3N03D9","EDDAMBT3N04D1", & - "EDDAMBT3N04D2","EDDAMBT3N04D3","EDDAMBT3N04D4","EDDAMBT3N04D5","EDDAMBT3N04D6","EDDAMBT3N04D7","EDDAMBT3N04D8","EDDAMBT3N04D9", & - "EDDAMBT3N05D1","EDDAMBT3N05D2","EDDAMBT3N05D3","EDDAMBT3N05D4","EDDAMBT3N05D5","EDDAMBT3N05D6","EDDAMBT3N05D7","EDDAMBT3N05D8", & - "EDDAMBT3N05D9","EDDAMBT3N06D1","EDDAMBT3N06D2","EDDAMBT3N06D3","EDDAMBT3N06D4","EDDAMBT3N06D5","EDDAMBT3N06D6","EDDAMBT3N06D7", & - "EDDAMBT3N06D8","EDDAMBT3N06D9","EDDAMBT3N07D1","EDDAMBT3N07D2","EDDAMBT3N07D3","EDDAMBT3N07D4","EDDAMBT3N07D5","EDDAMBT3N07D6", & - "EDDAMBT3N07D7","EDDAMBT3N07D8","EDDAMBT3N07D9","EDDAMBT3N08D1","EDDAMBT3N08D2","EDDAMBT3N08D3","EDDAMBT3N08D4","EDDAMBT3N08D5", & - "EDDAMBT3N08D6","EDDAMBT3N08D7","EDDAMBT3N08D8","EDDAMBT3N08D9","EDDAMBT3N09D1","EDDAMBT3N09D2","EDDAMBT3N09D3","EDDAMBT3N09D4", & - "EDDAMBT3N09D5","EDDAMBT3N09D6","EDDAMBT3N09D7","EDDAMBT3N09D8","EDDAMBT3N09D9","EDDAMBT3N10D1","EDDAMBT3N10D2","EDDAMBT3N10D3", & - "EDDAMBT3N10D4","EDDAMBT3N10D5","EDDAMBT3N10D6","EDDAMBT3N10D7","EDDAMBT3N10D8","EDDAMBT3N10D9","EDDAMBT3N11D1","EDDAMBT3N11D2", & - "EDDAMBT3N11D3","EDDAMBT3N11D4","EDDAMBT3N11D5","EDDAMBT3N11D6","EDDAMBT3N11D7","EDDAMBT3N11D8","EDDAMBT3N11D9","EDDAMBT3N12D1", & - "EDDAMBT3N12D2","EDDAMBT3N12D3","EDDAMBT3N12D4","EDDAMBT3N12D5","EDDAMBT3N12D6","EDDAMBT3N12D7","EDDAMBT3N12D8","EDDAMBT3N12D9", & - "EDDAMBT3N13D1","EDDAMBT3N13D2","EDDAMBT3N13D3","EDDAMBT3N13D4","EDDAMBT3N13D5","EDDAMBT3N13D6","EDDAMBT3N13D7","EDDAMBT3N13D8", & - "EDDAMBT3N13D9","EDDAMBT3N14D1","EDDAMBT3N14D2","EDDAMBT3N14D3","EDDAMBT3N14D4","EDDAMBT3N14D5","EDDAMBT3N14D6","EDDAMBT3N14D7", & - "EDDAMBT3N14D8","EDDAMBT3N14D9","EDDAMBT3N15D1","EDDAMBT3N15D2","EDDAMBT3N15D3","EDDAMBT3N15D4","EDDAMBT3N15D5","EDDAMBT3N15D6", & - "EDDAMBT3N15D7","EDDAMBT3N15D8","EDDAMBT3N15D9","EDDAMBT3N16D1","EDDAMBT3N16D2","EDDAMBT3N16D3","EDDAMBT3N16D4","EDDAMBT3N16D5", & - "EDDAMBT3N16D6","EDDAMBT3N16D7","EDDAMBT3N16D8","EDDAMBT3N16D9","EDDAMBT3N17D1","EDDAMBT3N17D2","EDDAMBT3N17D3","EDDAMBT3N17D4", & - "EDDAMBT3N17D5","EDDAMBT3N17D6","EDDAMBT3N17D7","EDDAMBT3N17D8","EDDAMBT3N17D9","EDDAMBT3N18D1","EDDAMBT3N18D2","EDDAMBT3N18D3", & - "EDDAMBT3N18D4","EDDAMBT3N18D5","EDDAMBT3N18D6","EDDAMBT3N18D7","EDDAMBT3N18D8","EDDAMBT3N18D9","EDDAMBT3N19D1","EDDAMBT3N19D2", & - "EDDAMBT3N19D3","EDDAMBT3N19D4","EDDAMBT3N19D5","EDDAMBT3N19D6","EDDAMBT3N19D7","EDDAMBT3N19D8","EDDAMBT3N19D9","EDDAMBT3N20D1", & - "EDDAMBT3N20D2","EDDAMBT3N20D3","EDDAMBT3N20D4","EDDAMBT3N20D5","EDDAMBT3N20D6","EDDAMBT3N20D7","EDDAMBT3N20D8","EDDAMBT3N20D9", & - "EDDAMBT4N01D1","EDDAMBT4N01D2","EDDAMBT4N01D3","EDDAMBT4N01D4","EDDAMBT4N01D5","EDDAMBT4N01D6","EDDAMBT4N01D7","EDDAMBT4N01D8", & - "EDDAMBT4N01D9","EDDAMBT4N02D1","EDDAMBT4N02D2","EDDAMBT4N02D3","EDDAMBT4N02D4","EDDAMBT4N02D5","EDDAMBT4N02D6","EDDAMBT4N02D7", & - "EDDAMBT4N02D8","EDDAMBT4N02D9","EDDAMBT4N03D1","EDDAMBT4N03D2","EDDAMBT4N03D3","EDDAMBT4N03D4","EDDAMBT4N03D5","EDDAMBT4N03D6", & - "EDDAMBT4N03D7","EDDAMBT4N03D8","EDDAMBT4N03D9","EDDAMBT4N04D1","EDDAMBT4N04D2","EDDAMBT4N04D3","EDDAMBT4N04D4","EDDAMBT4N04D5", & - "EDDAMBT4N04D6","EDDAMBT4N04D7","EDDAMBT4N04D8","EDDAMBT4N04D9","EDDAMBT4N05D1","EDDAMBT4N05D2","EDDAMBT4N05D3","EDDAMBT4N05D4", & - "EDDAMBT4N05D5","EDDAMBT4N05D6","EDDAMBT4N05D7","EDDAMBT4N05D8","EDDAMBT4N05D9","EDDAMBT4N06D1","EDDAMBT4N06D2","EDDAMBT4N06D3", & - "EDDAMBT4N06D4","EDDAMBT4N06D5","EDDAMBT4N06D6","EDDAMBT4N06D7","EDDAMBT4N06D8","EDDAMBT4N06D9","EDDAMBT4N07D1","EDDAMBT4N07D2", & - "EDDAMBT4N07D3","EDDAMBT4N07D4","EDDAMBT4N07D5","EDDAMBT4N07D6","EDDAMBT4N07D7","EDDAMBT4N07D8","EDDAMBT4N07D9","EDDAMBT4N08D1", & - "EDDAMBT4N08D2","EDDAMBT4N08D3","EDDAMBT4N08D4","EDDAMBT4N08D5","EDDAMBT4N08D6","EDDAMBT4N08D7","EDDAMBT4N08D8","EDDAMBT4N08D9", & - "EDDAMBT4N09D1","EDDAMBT4N09D2","EDDAMBT4N09D3","EDDAMBT4N09D4","EDDAMBT4N09D5","EDDAMBT4N09D6","EDDAMBT4N09D7","EDDAMBT4N09D8", & - "EDDAMBT4N09D9","EDDAMBT4N10D1","EDDAMBT4N10D2","EDDAMBT4N10D3","EDDAMBT4N10D4","EDDAMBT4N10D5","EDDAMBT4N10D6","EDDAMBT4N10D7", & - "EDDAMBT4N10D8","EDDAMBT4N10D9","EDDAMBT4N11D1","EDDAMBT4N11D2","EDDAMBT4N11D3","EDDAMBT4N11D4","EDDAMBT4N11D5","EDDAMBT4N11D6", & - "EDDAMBT4N11D7","EDDAMBT4N11D8","EDDAMBT4N11D9","EDDAMBT4N12D1","EDDAMBT4N12D2","EDDAMBT4N12D3","EDDAMBT4N12D4","EDDAMBT4N12D5", & - "EDDAMBT4N12D6","EDDAMBT4N12D7","EDDAMBT4N12D8","EDDAMBT4N12D9","EDDAMBT4N13D1","EDDAMBT4N13D2","EDDAMBT4N13D3","EDDAMBT4N13D4", & - "EDDAMBT4N13D5","EDDAMBT4N13D6","EDDAMBT4N13D7","EDDAMBT4N13D8","EDDAMBT4N13D9","EDDAMBT4N14D1","EDDAMBT4N14D2","EDDAMBT4N14D3", & - "EDDAMBT4N14D4","EDDAMBT4N14D5","EDDAMBT4N14D6","EDDAMBT4N14D7","EDDAMBT4N14D8","EDDAMBT4N14D9","EDDAMBT4N15D1","EDDAMBT4N15D2", & - "EDDAMBT4N15D3","EDDAMBT4N15D4","EDDAMBT4N15D5","EDDAMBT4N15D6","EDDAMBT4N15D7","EDDAMBT4N15D8","EDDAMBT4N15D9","EDDAMBT4N16D1", & - "EDDAMBT4N16D2","EDDAMBT4N16D3","EDDAMBT4N16D4","EDDAMBT4N16D5","EDDAMBT4N16D6","EDDAMBT4N16D7","EDDAMBT4N16D8","EDDAMBT4N16D9", & - "EDDAMBT4N17D1","EDDAMBT4N17D2","EDDAMBT4N17D3","EDDAMBT4N17D4","EDDAMBT4N17D5","EDDAMBT4N17D6","EDDAMBT4N17D7","EDDAMBT4N17D8", & - "EDDAMBT4N17D9","EDDAMBT4N18D1","EDDAMBT4N18D2","EDDAMBT4N18D3","EDDAMBT4N18D4","EDDAMBT4N18D5","EDDAMBT4N18D6","EDDAMBT4N18D7", & - "EDDAMBT4N18D8","EDDAMBT4N18D9","EDDAMBT4N19D1","EDDAMBT4N19D2","EDDAMBT4N19D3","EDDAMBT4N19D4","EDDAMBT4N19D5","EDDAMBT4N19D6", & - "EDDAMBT4N19D7","EDDAMBT4N19D8","EDDAMBT4N19D9","EDDAMBT4N20D1","EDDAMBT4N20D2","EDDAMBT4N20D3","EDDAMBT4N20D4","EDDAMBT4N20D5", & - "EDDAMBT4N20D6","EDDAMBT4N20D7","EDDAMBT4N20D8","EDDAMBT4N20D9","EDDAMBT5N01D1","EDDAMBT5N01D2","EDDAMBT5N01D3","EDDAMBT5N01D4", & - "EDDAMBT5N01D5","EDDAMBT5N01D6","EDDAMBT5N01D7","EDDAMBT5N01D8","EDDAMBT5N01D9","EDDAMBT5N02D1","EDDAMBT5N02D2","EDDAMBT5N02D3", & - "EDDAMBT5N02D4","EDDAMBT5N02D5","EDDAMBT5N02D6","EDDAMBT5N02D7","EDDAMBT5N02D8","EDDAMBT5N02D9","EDDAMBT5N03D1","EDDAMBT5N03D2", & - "EDDAMBT5N03D3","EDDAMBT5N03D4","EDDAMBT5N03D5","EDDAMBT5N03D6","EDDAMBT5N03D7","EDDAMBT5N03D8","EDDAMBT5N03D9","EDDAMBT5N04D1", & - "EDDAMBT5N04D2","EDDAMBT5N04D3","EDDAMBT5N04D4","EDDAMBT5N04D5","EDDAMBT5N04D6","EDDAMBT5N04D7","EDDAMBT5N04D8","EDDAMBT5N04D9", & - "EDDAMBT5N05D1","EDDAMBT5N05D2","EDDAMBT5N05D3","EDDAMBT5N05D4","EDDAMBT5N05D5","EDDAMBT5N05D6","EDDAMBT5N05D7","EDDAMBT5N05D8", & - "EDDAMBT5N05D9","EDDAMBT5N06D1","EDDAMBT5N06D2","EDDAMBT5N06D3","EDDAMBT5N06D4","EDDAMBT5N06D5","EDDAMBT5N06D6","EDDAMBT5N06D7", & - "EDDAMBT5N06D8","EDDAMBT5N06D9","EDDAMBT5N07D1","EDDAMBT5N07D2","EDDAMBT5N07D3","EDDAMBT5N07D4","EDDAMBT5N07D5","EDDAMBT5N07D6", & - "EDDAMBT5N07D7","EDDAMBT5N07D8","EDDAMBT5N07D9","EDDAMBT5N08D1","EDDAMBT5N08D2","EDDAMBT5N08D3","EDDAMBT5N08D4","EDDAMBT5N08D5", & - "EDDAMBT5N08D6","EDDAMBT5N08D7","EDDAMBT5N08D8","EDDAMBT5N08D9","EDDAMBT5N09D1","EDDAMBT5N09D2","EDDAMBT5N09D3","EDDAMBT5N09D4", & - "EDDAMBT5N09D5","EDDAMBT5N09D6","EDDAMBT5N09D7","EDDAMBT5N09D8","EDDAMBT5N09D9","EDDAMBT5N10D1","EDDAMBT5N10D2","EDDAMBT5N10D3", & - "EDDAMBT5N10D4","EDDAMBT5N10D5","EDDAMBT5N10D6","EDDAMBT5N10D7","EDDAMBT5N10D8","EDDAMBT5N10D9","EDDAMBT5N11D1","EDDAMBT5N11D2", & - "EDDAMBT5N11D3","EDDAMBT5N11D4","EDDAMBT5N11D5","EDDAMBT5N11D6","EDDAMBT5N11D7","EDDAMBT5N11D8","EDDAMBT5N11D9","EDDAMBT5N12D1", & - "EDDAMBT5N12D2","EDDAMBT5N12D3","EDDAMBT5N12D4","EDDAMBT5N12D5","EDDAMBT5N12D6","EDDAMBT5N12D7","EDDAMBT5N12D8","EDDAMBT5N12D9", & - "EDDAMBT5N13D1","EDDAMBT5N13D2","EDDAMBT5N13D3","EDDAMBT5N13D4","EDDAMBT5N13D5","EDDAMBT5N13D6","EDDAMBT5N13D7","EDDAMBT5N13D8", & - "EDDAMBT5N13D9","EDDAMBT5N14D1","EDDAMBT5N14D2","EDDAMBT5N14D3","EDDAMBT5N14D4","EDDAMBT5N14D5","EDDAMBT5N14D6","EDDAMBT5N14D7", & - "EDDAMBT5N14D8","EDDAMBT5N14D9","EDDAMBT5N15D1","EDDAMBT5N15D2","EDDAMBT5N15D3","EDDAMBT5N15D4","EDDAMBT5N15D5","EDDAMBT5N15D6", & - "EDDAMBT5N15D7","EDDAMBT5N15D8","EDDAMBT5N15D9","EDDAMBT5N16D1","EDDAMBT5N16D2","EDDAMBT5N16D3","EDDAMBT5N16D4","EDDAMBT5N16D5", & - "EDDAMBT5N16D6","EDDAMBT5N16D7","EDDAMBT5N16D8","EDDAMBT5N16D9","EDDAMBT5N17D1","EDDAMBT5N17D2","EDDAMBT5N17D3","EDDAMBT5N17D4", & - "EDDAMBT5N17D5","EDDAMBT5N17D6","EDDAMBT5N17D7","EDDAMBT5N17D8","EDDAMBT5N17D9","EDDAMBT5N18D1","EDDAMBT5N18D2","EDDAMBT5N18D3", & - "EDDAMBT5N18D4","EDDAMBT5N18D5","EDDAMBT5N18D6","EDDAMBT5N18D7","EDDAMBT5N18D8","EDDAMBT5N18D9","EDDAMBT5N19D1","EDDAMBT5N19D2", & - "EDDAMBT5N19D3","EDDAMBT5N19D4","EDDAMBT5N19D5","EDDAMBT5N19D6","EDDAMBT5N19D7","EDDAMBT5N19D8","EDDAMBT5N19D9","EDDAMBT5N20D1", & - "EDDAMBT5N20D2","EDDAMBT5N20D3","EDDAMBT5N20D4","EDDAMBT5N20D5","EDDAMBT5N20D6","EDDAMBT5N20D7","EDDAMBT5N20D8","EDDAMBT5N20D9", & - "EDDAMBT6N01D1","EDDAMBT6N01D2","EDDAMBT6N01D3","EDDAMBT6N01D4","EDDAMBT6N01D5","EDDAMBT6N01D6","EDDAMBT6N01D7","EDDAMBT6N01D8", & - "EDDAMBT6N01D9","EDDAMBT6N02D1","EDDAMBT6N02D2","EDDAMBT6N02D3","EDDAMBT6N02D4","EDDAMBT6N02D5","EDDAMBT6N02D6","EDDAMBT6N02D7", & - "EDDAMBT6N02D8","EDDAMBT6N02D9","EDDAMBT6N03D1","EDDAMBT6N03D2","EDDAMBT6N03D3","EDDAMBT6N03D4","EDDAMBT6N03D5","EDDAMBT6N03D6", & - "EDDAMBT6N03D7","EDDAMBT6N03D8","EDDAMBT6N03D9","EDDAMBT6N04D1","EDDAMBT6N04D2","EDDAMBT6N04D3","EDDAMBT6N04D4","EDDAMBT6N04D5", & - "EDDAMBT6N04D6","EDDAMBT6N04D7","EDDAMBT6N04D8","EDDAMBT6N04D9","EDDAMBT6N05D1","EDDAMBT6N05D2","EDDAMBT6N05D3","EDDAMBT6N05D4", & - "EDDAMBT6N05D5","EDDAMBT6N05D6","EDDAMBT6N05D7","EDDAMBT6N05D8","EDDAMBT6N05D9","EDDAMBT6N06D1","EDDAMBT6N06D2","EDDAMBT6N06D3", & - "EDDAMBT6N06D4","EDDAMBT6N06D5","EDDAMBT6N06D6","EDDAMBT6N06D7","EDDAMBT6N06D8","EDDAMBT6N06D9","EDDAMBT6N07D1","EDDAMBT6N07D2", & - "EDDAMBT6N07D3","EDDAMBT6N07D4","EDDAMBT6N07D5","EDDAMBT6N07D6","EDDAMBT6N07D7","EDDAMBT6N07D8","EDDAMBT6N07D9","EDDAMBT6N08D1", & - "EDDAMBT6N08D2","EDDAMBT6N08D3","EDDAMBT6N08D4","EDDAMBT6N08D5","EDDAMBT6N08D6","EDDAMBT6N08D7","EDDAMBT6N08D8","EDDAMBT6N08D9", & - "EDDAMBT6N09D1","EDDAMBT6N09D2","EDDAMBT6N09D3","EDDAMBT6N09D4","EDDAMBT6N09D5","EDDAMBT6N09D6","EDDAMBT6N09D7","EDDAMBT6N09D8", & - "EDDAMBT6N09D9","EDDAMBT6N10D1","EDDAMBT6N10D2","EDDAMBT6N10D3","EDDAMBT6N10D4","EDDAMBT6N10D5","EDDAMBT6N10D6","EDDAMBT6N10D7", & - "EDDAMBT6N10D8","EDDAMBT6N10D9","EDDAMBT6N11D1","EDDAMBT6N11D2","EDDAMBT6N11D3","EDDAMBT6N11D4","EDDAMBT6N11D5","EDDAMBT6N11D6", & - "EDDAMBT6N11D7","EDDAMBT6N11D8","EDDAMBT6N11D9","EDDAMBT6N12D1","EDDAMBT6N12D2","EDDAMBT6N12D3","EDDAMBT6N12D4","EDDAMBT6N12D5", & - "EDDAMBT6N12D6","EDDAMBT6N12D7","EDDAMBT6N12D8","EDDAMBT6N12D9","EDDAMBT6N13D1","EDDAMBT6N13D2","EDDAMBT6N13D3","EDDAMBT6N13D4", & - "EDDAMBT6N13D5","EDDAMBT6N13D6","EDDAMBT6N13D7","EDDAMBT6N13D8","EDDAMBT6N13D9","EDDAMBT6N14D1","EDDAMBT6N14D2","EDDAMBT6N14D3", & - "EDDAMBT6N14D4","EDDAMBT6N14D5","EDDAMBT6N14D6","EDDAMBT6N14D7","EDDAMBT6N14D8","EDDAMBT6N14D9","EDDAMBT6N15D1","EDDAMBT6N15D2", & - "EDDAMBT6N15D3","EDDAMBT6N15D4","EDDAMBT6N15D5","EDDAMBT6N15D6","EDDAMBT6N15D7","EDDAMBT6N15D8","EDDAMBT6N15D9","EDDAMBT6N16D1", & - "EDDAMBT6N16D2","EDDAMBT6N16D3","EDDAMBT6N16D4","EDDAMBT6N16D5","EDDAMBT6N16D6","EDDAMBT6N16D7","EDDAMBT6N16D8","EDDAMBT6N16D9", & - "EDDAMBT6N17D1","EDDAMBT6N17D2","EDDAMBT6N17D3","EDDAMBT6N17D4","EDDAMBT6N17D5","EDDAMBT6N17D6","EDDAMBT6N17D7","EDDAMBT6N17D8", & - "EDDAMBT6N17D9","EDDAMBT6N18D1","EDDAMBT6N18D2","EDDAMBT6N18D3","EDDAMBT6N18D4","EDDAMBT6N18D5","EDDAMBT6N18D6","EDDAMBT6N18D7", & - "EDDAMBT6N18D8","EDDAMBT6N18D9","EDDAMBT6N19D1","EDDAMBT6N19D2","EDDAMBT6N19D3","EDDAMBT6N19D4","EDDAMBT6N19D5","EDDAMBT6N19D6", & - "EDDAMBT6N19D7","EDDAMBT6N19D8","EDDAMBT6N19D9","EDDAMBT6N20D1","EDDAMBT6N20D2","EDDAMBT6N20D3","EDDAMBT6N20D4","EDDAMBT6N20D5", & - "EDDAMBT6N20D6","EDDAMBT6N20D7","EDDAMBT6N20D8","EDDAMBT6N20D9","EDDAMBT7N01D1","EDDAMBT7N01D2","EDDAMBT7N01D3","EDDAMBT7N01D4", & - "EDDAMBT7N01D5","EDDAMBT7N01D6","EDDAMBT7N01D7","EDDAMBT7N01D8","EDDAMBT7N01D9","EDDAMBT7N02D1","EDDAMBT7N02D2","EDDAMBT7N02D3", & - "EDDAMBT7N02D4","EDDAMBT7N02D5","EDDAMBT7N02D6","EDDAMBT7N02D7","EDDAMBT7N02D8","EDDAMBT7N02D9","EDDAMBT7N03D1","EDDAMBT7N03D2", & - "EDDAMBT7N03D3","EDDAMBT7N03D4","EDDAMBT7N03D5","EDDAMBT7N03D6","EDDAMBT7N03D7","EDDAMBT7N03D8","EDDAMBT7N03D9","EDDAMBT7N04D1", & - "EDDAMBT7N04D2","EDDAMBT7N04D3","EDDAMBT7N04D4","EDDAMBT7N04D5","EDDAMBT7N04D6","EDDAMBT7N04D7","EDDAMBT7N04D8","EDDAMBT7N04D9", & - "EDDAMBT7N05D1","EDDAMBT7N05D2","EDDAMBT7N05D3","EDDAMBT7N05D4","EDDAMBT7N05D5","EDDAMBT7N05D6","EDDAMBT7N05D7","EDDAMBT7N05D8", & - "EDDAMBT7N05D9","EDDAMBT7N06D1","EDDAMBT7N06D2","EDDAMBT7N06D3","EDDAMBT7N06D4","EDDAMBT7N06D5","EDDAMBT7N06D6","EDDAMBT7N06D7", & - "EDDAMBT7N06D8","EDDAMBT7N06D9","EDDAMBT7N07D1","EDDAMBT7N07D2","EDDAMBT7N07D3","EDDAMBT7N07D4","EDDAMBT7N07D5","EDDAMBT7N07D6", & - "EDDAMBT7N07D7","EDDAMBT7N07D8","EDDAMBT7N07D9","EDDAMBT7N08D1","EDDAMBT7N08D2","EDDAMBT7N08D3","EDDAMBT7N08D4","EDDAMBT7N08D5", & - "EDDAMBT7N08D6","EDDAMBT7N08D7","EDDAMBT7N08D8","EDDAMBT7N08D9","EDDAMBT7N09D1","EDDAMBT7N09D2","EDDAMBT7N09D3","EDDAMBT7N09D4", & - "EDDAMBT7N09D5","EDDAMBT7N09D6","EDDAMBT7N09D7","EDDAMBT7N09D8","EDDAMBT7N09D9","EDDAMBT7N10D1","EDDAMBT7N10D2","EDDAMBT7N10D3", & - "EDDAMBT7N10D4","EDDAMBT7N10D5","EDDAMBT7N10D6","EDDAMBT7N10D7","EDDAMBT7N10D8","EDDAMBT7N10D9","EDDAMBT7N11D1","EDDAMBT7N11D2", & - "EDDAMBT7N11D3","EDDAMBT7N11D4","EDDAMBT7N11D5","EDDAMBT7N11D6","EDDAMBT7N11D7","EDDAMBT7N11D8","EDDAMBT7N11D9","EDDAMBT7N12D1", & - "EDDAMBT7N12D2","EDDAMBT7N12D3","EDDAMBT7N12D4","EDDAMBT7N12D5","EDDAMBT7N12D6","EDDAMBT7N12D7","EDDAMBT7N12D8","EDDAMBT7N12D9", & - "EDDAMBT7N13D1","EDDAMBT7N13D2","EDDAMBT7N13D3","EDDAMBT7N13D4","EDDAMBT7N13D5","EDDAMBT7N13D6","EDDAMBT7N13D7","EDDAMBT7N13D8", & - "EDDAMBT7N13D9","EDDAMBT7N14D1","EDDAMBT7N14D2","EDDAMBT7N14D3","EDDAMBT7N14D4","EDDAMBT7N14D5","EDDAMBT7N14D6","EDDAMBT7N14D7", & - "EDDAMBT7N14D8","EDDAMBT7N14D9","EDDAMBT7N15D1","EDDAMBT7N15D2","EDDAMBT7N15D3","EDDAMBT7N15D4","EDDAMBT7N15D5","EDDAMBT7N15D6", & - "EDDAMBT7N15D7","EDDAMBT7N15D8","EDDAMBT7N15D9","EDDAMBT7N16D1","EDDAMBT7N16D2","EDDAMBT7N16D3","EDDAMBT7N16D4","EDDAMBT7N16D5", & - "EDDAMBT7N16D6","EDDAMBT7N16D7","EDDAMBT7N16D8","EDDAMBT7N16D9","EDDAMBT7N17D1","EDDAMBT7N17D2","EDDAMBT7N17D3","EDDAMBT7N17D4", & - "EDDAMBT7N17D5","EDDAMBT7N17D6","EDDAMBT7N17D7","EDDAMBT7N17D8","EDDAMBT7N17D9","EDDAMBT7N18D1","EDDAMBT7N18D2","EDDAMBT7N18D3", & - "EDDAMBT7N18D4","EDDAMBT7N18D5","EDDAMBT7N18D6","EDDAMBT7N18D7","EDDAMBT7N18D8","EDDAMBT7N18D9","EDDAMBT7N19D1","EDDAMBT7N19D2", & - "EDDAMBT7N19D3","EDDAMBT7N19D4","EDDAMBT7N19D5","EDDAMBT7N19D6","EDDAMBT7N19D7","EDDAMBT7N19D8","EDDAMBT7N19D9","EDDAMBT7N20D1", & - "EDDAMBT7N20D2","EDDAMBT7N20D3","EDDAMBT7N20D4","EDDAMBT7N20D5","EDDAMBT7N20D6","EDDAMBT7N20D7","EDDAMBT7N20D8","EDDAMBT7N20D9", & - "EDDAMBT8N01D1","EDDAMBT8N01D2","EDDAMBT8N01D3","EDDAMBT8N01D4","EDDAMBT8N01D5","EDDAMBT8N01D6","EDDAMBT8N01D7","EDDAMBT8N01D8", & - "EDDAMBT8N01D9","EDDAMBT8N02D1","EDDAMBT8N02D2","EDDAMBT8N02D3","EDDAMBT8N02D4","EDDAMBT8N02D5","EDDAMBT8N02D6","EDDAMBT8N02D7", & - "EDDAMBT8N02D8","EDDAMBT8N02D9","EDDAMBT8N03D1","EDDAMBT8N03D2","EDDAMBT8N03D3","EDDAMBT8N03D4","EDDAMBT8N03D5","EDDAMBT8N03D6", & - "EDDAMBT8N03D7","EDDAMBT8N03D8","EDDAMBT8N03D9","EDDAMBT8N04D1","EDDAMBT8N04D2","EDDAMBT8N04D3","EDDAMBT8N04D4","EDDAMBT8N04D5", & - "EDDAMBT8N04D6","EDDAMBT8N04D7","EDDAMBT8N04D8","EDDAMBT8N04D9","EDDAMBT8N05D1","EDDAMBT8N05D2","EDDAMBT8N05D3","EDDAMBT8N05D4", & - "EDDAMBT8N05D5","EDDAMBT8N05D6","EDDAMBT8N05D7","EDDAMBT8N05D8","EDDAMBT8N05D9","EDDAMBT8N06D1","EDDAMBT8N06D2","EDDAMBT8N06D3", & - "EDDAMBT8N06D4","EDDAMBT8N06D5","EDDAMBT8N06D6","EDDAMBT8N06D7","EDDAMBT8N06D8","EDDAMBT8N06D9","EDDAMBT8N07D1","EDDAMBT8N07D2", & - "EDDAMBT8N07D3","EDDAMBT8N07D4","EDDAMBT8N07D5","EDDAMBT8N07D6","EDDAMBT8N07D7","EDDAMBT8N07D8","EDDAMBT8N07D9","EDDAMBT8N08D1", & - "EDDAMBT8N08D2","EDDAMBT8N08D3","EDDAMBT8N08D4","EDDAMBT8N08D5","EDDAMBT8N08D6","EDDAMBT8N08D7","EDDAMBT8N08D8","EDDAMBT8N08D9", & - "EDDAMBT8N09D1","EDDAMBT8N09D2","EDDAMBT8N09D3","EDDAMBT8N09D4","EDDAMBT8N09D5","EDDAMBT8N09D6","EDDAMBT8N09D7","EDDAMBT8N09D8", & - "EDDAMBT8N09D9","EDDAMBT8N10D1","EDDAMBT8N10D2","EDDAMBT8N10D3","EDDAMBT8N10D4","EDDAMBT8N10D5","EDDAMBT8N10D6","EDDAMBT8N10D7", & - "EDDAMBT8N10D8","EDDAMBT8N10D9","EDDAMBT8N11D1","EDDAMBT8N11D2","EDDAMBT8N11D3","EDDAMBT8N11D4","EDDAMBT8N11D5","EDDAMBT8N11D6", & - "EDDAMBT8N11D7","EDDAMBT8N11D8","EDDAMBT8N11D9","EDDAMBT8N12D1","EDDAMBT8N12D2","EDDAMBT8N12D3","EDDAMBT8N12D4","EDDAMBT8N12D5", & - "EDDAMBT8N12D6","EDDAMBT8N12D7","EDDAMBT8N12D8","EDDAMBT8N12D9","EDDAMBT8N13D1","EDDAMBT8N13D2","EDDAMBT8N13D3","EDDAMBT8N13D4", & - "EDDAMBT8N13D5","EDDAMBT8N13D6","EDDAMBT8N13D7","EDDAMBT8N13D8","EDDAMBT8N13D9","EDDAMBT8N14D1","EDDAMBT8N14D2","EDDAMBT8N14D3", & - "EDDAMBT8N14D4","EDDAMBT8N14D5","EDDAMBT8N14D6","EDDAMBT8N14D7","EDDAMBT8N14D8","EDDAMBT8N14D9","EDDAMBT8N15D1","EDDAMBT8N15D2", & - "EDDAMBT8N15D3","EDDAMBT8N15D4","EDDAMBT8N15D5","EDDAMBT8N15D6","EDDAMBT8N15D7","EDDAMBT8N15D8","EDDAMBT8N15D9","EDDAMBT8N16D1", & - "EDDAMBT8N16D2","EDDAMBT8N16D3","EDDAMBT8N16D4","EDDAMBT8N16D5","EDDAMBT8N16D6","EDDAMBT8N16D7","EDDAMBT8N16D8","EDDAMBT8N16D9", & - "EDDAMBT8N17D1","EDDAMBT8N17D2","EDDAMBT8N17D3","EDDAMBT8N17D4","EDDAMBT8N17D5","EDDAMBT8N17D6","EDDAMBT8N17D7","EDDAMBT8N17D8", & - "EDDAMBT8N17D9","EDDAMBT8N18D1","EDDAMBT8N18D2","EDDAMBT8N18D3","EDDAMBT8N18D4","EDDAMBT8N18D5","EDDAMBT8N18D6","EDDAMBT8N18D7", & - "EDDAMBT8N18D8","EDDAMBT8N18D9","EDDAMBT8N19D1","EDDAMBT8N19D2","EDDAMBT8N19D3","EDDAMBT8N19D4","EDDAMBT8N19D5","EDDAMBT8N19D6", & - "EDDAMBT8N19D7","EDDAMBT8N19D8","EDDAMBT8N19D9","EDDAMBT8N20D1","EDDAMBT8N20D2","EDDAMBT8N20D3","EDDAMBT8N20D4","EDDAMBT8N20D5", & - "EDDAMBT8N20D6","EDDAMBT8N20D7","EDDAMBT8N20D8","EDDAMBT8N20D9","EDDAMBT9N01D1","EDDAMBT9N01D2","EDDAMBT9N01D3","EDDAMBT9N01D4", & - "EDDAMBT9N01D5","EDDAMBT9N01D6","EDDAMBT9N01D7","EDDAMBT9N01D8","EDDAMBT9N01D9","EDDAMBT9N02D1","EDDAMBT9N02D2","EDDAMBT9N02D3", & - "EDDAMBT9N02D4","EDDAMBT9N02D5","EDDAMBT9N02D6","EDDAMBT9N02D7","EDDAMBT9N02D8","EDDAMBT9N02D9","EDDAMBT9N03D1","EDDAMBT9N03D2", & - "EDDAMBT9N03D3","EDDAMBT9N03D4","EDDAMBT9N03D5","EDDAMBT9N03D6","EDDAMBT9N03D7","EDDAMBT9N03D8","EDDAMBT9N03D9","EDDAMBT9N04D1", & - "EDDAMBT9N04D2","EDDAMBT9N04D3","EDDAMBT9N04D4","EDDAMBT9N04D5","EDDAMBT9N04D6","EDDAMBT9N04D7","EDDAMBT9N04D8","EDDAMBT9N04D9", & - "EDDAMBT9N05D1","EDDAMBT9N05D2","EDDAMBT9N05D3","EDDAMBT9N05D4","EDDAMBT9N05D5","EDDAMBT9N05D6","EDDAMBT9N05D7","EDDAMBT9N05D8", & - "EDDAMBT9N05D9","EDDAMBT9N06D1","EDDAMBT9N06D2","EDDAMBT9N06D3","EDDAMBT9N06D4","EDDAMBT9N06D5","EDDAMBT9N06D6","EDDAMBT9N06D7", & - "EDDAMBT9N06D8","EDDAMBT9N06D9","EDDAMBT9N07D1","EDDAMBT9N07D2","EDDAMBT9N07D3","EDDAMBT9N07D4","EDDAMBT9N07D5","EDDAMBT9N07D6", & - "EDDAMBT9N07D7","EDDAMBT9N07D8","EDDAMBT9N07D9","EDDAMBT9N08D1","EDDAMBT9N08D2","EDDAMBT9N08D3","EDDAMBT9N08D4","EDDAMBT9N08D5", & - "EDDAMBT9N08D6","EDDAMBT9N08D7","EDDAMBT9N08D8","EDDAMBT9N08D9","EDDAMBT9N09D1","EDDAMBT9N09D2","EDDAMBT9N09D3","EDDAMBT9N09D4", & - "EDDAMBT9N09D5","EDDAMBT9N09D6","EDDAMBT9N09D7","EDDAMBT9N09D8","EDDAMBT9N09D9","EDDAMBT9N10D1","EDDAMBT9N10D2","EDDAMBT9N10D3", & - "EDDAMBT9N10D4","EDDAMBT9N10D5","EDDAMBT9N10D6","EDDAMBT9N10D7","EDDAMBT9N10D8","EDDAMBT9N10D9","EDDAMBT9N11D1","EDDAMBT9N11D2", & - "EDDAMBT9N11D3","EDDAMBT9N11D4","EDDAMBT9N11D5","EDDAMBT9N11D6","EDDAMBT9N11D7","EDDAMBT9N11D8","EDDAMBT9N11D9","EDDAMBT9N12D1", & - "EDDAMBT9N12D2","EDDAMBT9N12D3","EDDAMBT9N12D4","EDDAMBT9N12D5","EDDAMBT9N12D6","EDDAMBT9N12D7","EDDAMBT9N12D8","EDDAMBT9N12D9", & - "EDDAMBT9N13D1","EDDAMBT9N13D2","EDDAMBT9N13D3","EDDAMBT9N13D4","EDDAMBT9N13D5","EDDAMBT9N13D6","EDDAMBT9N13D7","EDDAMBT9N13D8", & - "EDDAMBT9N13D9","EDDAMBT9N14D1","EDDAMBT9N14D2","EDDAMBT9N14D3","EDDAMBT9N14D4","EDDAMBT9N14D5","EDDAMBT9N14D6","EDDAMBT9N14D7", & - "EDDAMBT9N14D8","EDDAMBT9N14D9","EDDAMBT9N15D1","EDDAMBT9N15D2","EDDAMBT9N15D3","EDDAMBT9N15D4","EDDAMBT9N15D5","EDDAMBT9N15D6", & - "EDDAMBT9N15D7","EDDAMBT9N15D8","EDDAMBT9N15D9","EDDAMBT9N16D1","EDDAMBT9N16D2","EDDAMBT9N16D3","EDDAMBT9N16D4","EDDAMBT9N16D5", & - "EDDAMBT9N16D6","EDDAMBT9N16D7","EDDAMBT9N16D8","EDDAMBT9N16D9","EDDAMBT9N17D1","EDDAMBT9N17D2","EDDAMBT9N17D3","EDDAMBT9N17D4", & - "EDDAMBT9N17D5","EDDAMBT9N17D6","EDDAMBT9N17D7","EDDAMBT9N17D8","EDDAMBT9N17D9","EDDAMBT9N18D1","EDDAMBT9N18D2","EDDAMBT9N18D3", & - "EDDAMBT9N18D4","EDDAMBT9N18D5","EDDAMBT9N18D6","EDDAMBT9N18D7","EDDAMBT9N18D8","EDDAMBT9N18D9","EDDAMBT9N19D1","EDDAMBT9N19D2", & - "EDDAMBT9N19D3","EDDAMBT9N19D4","EDDAMBT9N19D5","EDDAMBT9N19D6","EDDAMBT9N19D7","EDDAMBT9N19D8","EDDAMBT9N19D9","EDDAMBT9N20D1", & - "EDDAMBT9N20D2","EDDAMBT9N20D3","EDDAMBT9N20D4","EDDAMBT9N20D5","EDDAMBT9N20D6","EDDAMBT9N20D7","EDDAMBT9N20D8","EDDAMBT9N20D9", & - "EDDSHRT1N01D1","EDDSHRT1N01D2","EDDSHRT1N01D3","EDDSHRT1N01D4","EDDSHRT1N01D5","EDDSHRT1N01D6","EDDSHRT1N01D7","EDDSHRT1N01D8", & - "EDDSHRT1N01D9","EDDSHRT1N02D1","EDDSHRT1N02D2","EDDSHRT1N02D3","EDDSHRT1N02D4","EDDSHRT1N02D5","EDDSHRT1N02D6","EDDSHRT1N02D7", & - "EDDSHRT1N02D8","EDDSHRT1N02D9","EDDSHRT1N03D1","EDDSHRT1N03D2","EDDSHRT1N03D3","EDDSHRT1N03D4","EDDSHRT1N03D5","EDDSHRT1N03D6", & - "EDDSHRT1N03D7","EDDSHRT1N03D8","EDDSHRT1N03D9","EDDSHRT1N04D1","EDDSHRT1N04D2","EDDSHRT1N04D3","EDDSHRT1N04D4","EDDSHRT1N04D5", & - "EDDSHRT1N04D6","EDDSHRT1N04D7","EDDSHRT1N04D8","EDDSHRT1N04D9","EDDSHRT1N05D1","EDDSHRT1N05D2","EDDSHRT1N05D3","EDDSHRT1N05D4", & - "EDDSHRT1N05D5","EDDSHRT1N05D6","EDDSHRT1N05D7","EDDSHRT1N05D8","EDDSHRT1N05D9","EDDSHRT1N06D1","EDDSHRT1N06D2","EDDSHRT1N06D3", & - "EDDSHRT1N06D4","EDDSHRT1N06D5","EDDSHRT1N06D6","EDDSHRT1N06D7","EDDSHRT1N06D8","EDDSHRT1N06D9","EDDSHRT1N07D1","EDDSHRT1N07D2", & - "EDDSHRT1N07D3","EDDSHRT1N07D4","EDDSHRT1N07D5","EDDSHRT1N07D6","EDDSHRT1N07D7","EDDSHRT1N07D8","EDDSHRT1N07D9","EDDSHRT1N08D1", & - "EDDSHRT1N08D2","EDDSHRT1N08D3","EDDSHRT1N08D4","EDDSHRT1N08D5","EDDSHRT1N08D6","EDDSHRT1N08D7","EDDSHRT1N08D8","EDDSHRT1N08D9", & - "EDDSHRT1N09D1","EDDSHRT1N09D2","EDDSHRT1N09D3","EDDSHRT1N09D4","EDDSHRT1N09D5","EDDSHRT1N09D6","EDDSHRT1N09D7","EDDSHRT1N09D8", & - "EDDSHRT1N09D9","EDDSHRT1N10D1","EDDSHRT1N10D2","EDDSHRT1N10D3","EDDSHRT1N10D4","EDDSHRT1N10D5","EDDSHRT1N10D6","EDDSHRT1N10D7", & - "EDDSHRT1N10D8","EDDSHRT1N10D9","EDDSHRT1N11D1","EDDSHRT1N11D2","EDDSHRT1N11D3","EDDSHRT1N11D4","EDDSHRT1N11D5","EDDSHRT1N11D6", & - "EDDSHRT1N11D7","EDDSHRT1N11D8","EDDSHRT1N11D9","EDDSHRT1N12D1","EDDSHRT1N12D2","EDDSHRT1N12D3","EDDSHRT1N12D4","EDDSHRT1N12D5", & - "EDDSHRT1N12D6","EDDSHRT1N12D7","EDDSHRT1N12D8","EDDSHRT1N12D9","EDDSHRT1N13D1","EDDSHRT1N13D2","EDDSHRT1N13D3","EDDSHRT1N13D4", & - "EDDSHRT1N13D5","EDDSHRT1N13D6","EDDSHRT1N13D7","EDDSHRT1N13D8","EDDSHRT1N13D9","EDDSHRT1N14D1","EDDSHRT1N14D2","EDDSHRT1N14D3", & - "EDDSHRT1N14D4","EDDSHRT1N14D5","EDDSHRT1N14D6","EDDSHRT1N14D7","EDDSHRT1N14D8","EDDSHRT1N14D9","EDDSHRT1N15D1","EDDSHRT1N15D2", & - "EDDSHRT1N15D3","EDDSHRT1N15D4","EDDSHRT1N15D5","EDDSHRT1N15D6","EDDSHRT1N15D7","EDDSHRT1N15D8","EDDSHRT1N15D9","EDDSHRT1N16D1", & - "EDDSHRT1N16D2","EDDSHRT1N16D3","EDDSHRT1N16D4","EDDSHRT1N16D5","EDDSHRT1N16D6","EDDSHRT1N16D7","EDDSHRT1N16D8","EDDSHRT1N16D9", & - "EDDSHRT1N17D1","EDDSHRT1N17D2","EDDSHRT1N17D3","EDDSHRT1N17D4","EDDSHRT1N17D5","EDDSHRT1N17D6","EDDSHRT1N17D7","EDDSHRT1N17D8", & - "EDDSHRT1N17D9","EDDSHRT1N18D1","EDDSHRT1N18D2","EDDSHRT1N18D3","EDDSHRT1N18D4","EDDSHRT1N18D5","EDDSHRT1N18D6","EDDSHRT1N18D7", & - "EDDSHRT1N18D8","EDDSHRT1N18D9","EDDSHRT1N19D1","EDDSHRT1N19D2","EDDSHRT1N19D3","EDDSHRT1N19D4","EDDSHRT1N19D5","EDDSHRT1N19D6", & - "EDDSHRT1N19D7","EDDSHRT1N19D8","EDDSHRT1N19D9","EDDSHRT1N20D1","EDDSHRT1N20D2","EDDSHRT1N20D3","EDDSHRT1N20D4","EDDSHRT1N20D5", & - "EDDSHRT1N20D6","EDDSHRT1N20D7","EDDSHRT1N20D8","EDDSHRT1N20D9","EDDSHRT2N01D1","EDDSHRT2N01D2","EDDSHRT2N01D3","EDDSHRT2N01D4", & - "EDDSHRT2N01D5","EDDSHRT2N01D6","EDDSHRT2N01D7","EDDSHRT2N01D8","EDDSHRT2N01D9","EDDSHRT2N02D1","EDDSHRT2N02D2","EDDSHRT2N02D3", & - "EDDSHRT2N02D4","EDDSHRT2N02D5","EDDSHRT2N02D6","EDDSHRT2N02D7","EDDSHRT2N02D8","EDDSHRT2N02D9","EDDSHRT2N03D1","EDDSHRT2N03D2", & - "EDDSHRT2N03D3","EDDSHRT2N03D4","EDDSHRT2N03D5","EDDSHRT2N03D6","EDDSHRT2N03D7","EDDSHRT2N03D8","EDDSHRT2N03D9","EDDSHRT2N04D1", & - "EDDSHRT2N04D2","EDDSHRT2N04D3","EDDSHRT2N04D4","EDDSHRT2N04D5","EDDSHRT2N04D6","EDDSHRT2N04D7","EDDSHRT2N04D8","EDDSHRT2N04D9", & - "EDDSHRT2N05D1","EDDSHRT2N05D2","EDDSHRT2N05D3","EDDSHRT2N05D4","EDDSHRT2N05D5","EDDSHRT2N05D6","EDDSHRT2N05D7","EDDSHRT2N05D8", & - "EDDSHRT2N05D9","EDDSHRT2N06D1","EDDSHRT2N06D2","EDDSHRT2N06D3","EDDSHRT2N06D4","EDDSHRT2N06D5","EDDSHRT2N06D6","EDDSHRT2N06D7", & - "EDDSHRT2N06D8","EDDSHRT2N06D9","EDDSHRT2N07D1","EDDSHRT2N07D2","EDDSHRT2N07D3","EDDSHRT2N07D4","EDDSHRT2N07D5","EDDSHRT2N07D6"/) - ValidParamAry(2041:4080) = (/ & - "EDDSHRT2N07D7","EDDSHRT2N07D8","EDDSHRT2N07D9","EDDSHRT2N08D1","EDDSHRT2N08D2","EDDSHRT2N08D3","EDDSHRT2N08D4","EDDSHRT2N08D5", & - "EDDSHRT2N08D6","EDDSHRT2N08D7","EDDSHRT2N08D8","EDDSHRT2N08D9","EDDSHRT2N09D1","EDDSHRT2N09D2","EDDSHRT2N09D3","EDDSHRT2N09D4", & - "EDDSHRT2N09D5","EDDSHRT2N09D6","EDDSHRT2N09D7","EDDSHRT2N09D8","EDDSHRT2N09D9","EDDSHRT2N10D1","EDDSHRT2N10D2","EDDSHRT2N10D3", & - "EDDSHRT2N10D4","EDDSHRT2N10D5","EDDSHRT2N10D6","EDDSHRT2N10D7","EDDSHRT2N10D8","EDDSHRT2N10D9","EDDSHRT2N11D1","EDDSHRT2N11D2", & - "EDDSHRT2N11D3","EDDSHRT2N11D4","EDDSHRT2N11D5","EDDSHRT2N11D6","EDDSHRT2N11D7","EDDSHRT2N11D8","EDDSHRT2N11D9","EDDSHRT2N12D1", & - "EDDSHRT2N12D2","EDDSHRT2N12D3","EDDSHRT2N12D4","EDDSHRT2N12D5","EDDSHRT2N12D6","EDDSHRT2N12D7","EDDSHRT2N12D8","EDDSHRT2N12D9", & - "EDDSHRT2N13D1","EDDSHRT2N13D2","EDDSHRT2N13D3","EDDSHRT2N13D4","EDDSHRT2N13D5","EDDSHRT2N13D6","EDDSHRT2N13D7","EDDSHRT2N13D8", & - "EDDSHRT2N13D9","EDDSHRT2N14D1","EDDSHRT2N14D2","EDDSHRT2N14D3","EDDSHRT2N14D4","EDDSHRT2N14D5","EDDSHRT2N14D6","EDDSHRT2N14D7", & - "EDDSHRT2N14D8","EDDSHRT2N14D9","EDDSHRT2N15D1","EDDSHRT2N15D2","EDDSHRT2N15D3","EDDSHRT2N15D4","EDDSHRT2N15D5","EDDSHRT2N15D6", & - "EDDSHRT2N15D7","EDDSHRT2N15D8","EDDSHRT2N15D9","EDDSHRT2N16D1","EDDSHRT2N16D2","EDDSHRT2N16D3","EDDSHRT2N16D4","EDDSHRT2N16D5", & - "EDDSHRT2N16D6","EDDSHRT2N16D7","EDDSHRT2N16D8","EDDSHRT2N16D9","EDDSHRT2N17D1","EDDSHRT2N17D2","EDDSHRT2N17D3","EDDSHRT2N17D4", & - "EDDSHRT2N17D5","EDDSHRT2N17D6","EDDSHRT2N17D7","EDDSHRT2N17D8","EDDSHRT2N17D9","EDDSHRT2N18D1","EDDSHRT2N18D2","EDDSHRT2N18D3", & - "EDDSHRT2N18D4","EDDSHRT2N18D5","EDDSHRT2N18D6","EDDSHRT2N18D7","EDDSHRT2N18D8","EDDSHRT2N18D9","EDDSHRT2N19D1","EDDSHRT2N19D2", & - "EDDSHRT2N19D3","EDDSHRT2N19D4","EDDSHRT2N19D5","EDDSHRT2N19D6","EDDSHRT2N19D7","EDDSHRT2N19D8","EDDSHRT2N19D9","EDDSHRT2N20D1", & - "EDDSHRT2N20D2","EDDSHRT2N20D3","EDDSHRT2N20D4","EDDSHRT2N20D5","EDDSHRT2N20D6","EDDSHRT2N20D7","EDDSHRT2N20D8","EDDSHRT2N20D9", & - "EDDSHRT3N01D1","EDDSHRT3N01D2","EDDSHRT3N01D3","EDDSHRT3N01D4","EDDSHRT3N01D5","EDDSHRT3N01D6","EDDSHRT3N01D7","EDDSHRT3N01D8", & - "EDDSHRT3N01D9","EDDSHRT3N02D1","EDDSHRT3N02D2","EDDSHRT3N02D3","EDDSHRT3N02D4","EDDSHRT3N02D5","EDDSHRT3N02D6","EDDSHRT3N02D7", & - "EDDSHRT3N02D8","EDDSHRT3N02D9","EDDSHRT3N03D1","EDDSHRT3N03D2","EDDSHRT3N03D3","EDDSHRT3N03D4","EDDSHRT3N03D5","EDDSHRT3N03D6", & - "EDDSHRT3N03D7","EDDSHRT3N03D8","EDDSHRT3N03D9","EDDSHRT3N04D1","EDDSHRT3N04D2","EDDSHRT3N04D3","EDDSHRT3N04D4","EDDSHRT3N04D5", & - "EDDSHRT3N04D6","EDDSHRT3N04D7","EDDSHRT3N04D8","EDDSHRT3N04D9","EDDSHRT3N05D1","EDDSHRT3N05D2","EDDSHRT3N05D3","EDDSHRT3N05D4", & - "EDDSHRT3N05D5","EDDSHRT3N05D6","EDDSHRT3N05D7","EDDSHRT3N05D8","EDDSHRT3N05D9","EDDSHRT3N06D1","EDDSHRT3N06D2","EDDSHRT3N06D3", & - "EDDSHRT3N06D4","EDDSHRT3N06D5","EDDSHRT3N06D6","EDDSHRT3N06D7","EDDSHRT3N06D8","EDDSHRT3N06D9","EDDSHRT3N07D1","EDDSHRT3N07D2", & - "EDDSHRT3N07D3","EDDSHRT3N07D4","EDDSHRT3N07D5","EDDSHRT3N07D6","EDDSHRT3N07D7","EDDSHRT3N07D8","EDDSHRT3N07D9","EDDSHRT3N08D1", & - "EDDSHRT3N08D2","EDDSHRT3N08D3","EDDSHRT3N08D4","EDDSHRT3N08D5","EDDSHRT3N08D6","EDDSHRT3N08D7","EDDSHRT3N08D8","EDDSHRT3N08D9", & - "EDDSHRT3N09D1","EDDSHRT3N09D2","EDDSHRT3N09D3","EDDSHRT3N09D4","EDDSHRT3N09D5","EDDSHRT3N09D6","EDDSHRT3N09D7","EDDSHRT3N09D8", & - "EDDSHRT3N09D9","EDDSHRT3N10D1","EDDSHRT3N10D2","EDDSHRT3N10D3","EDDSHRT3N10D4","EDDSHRT3N10D5","EDDSHRT3N10D6","EDDSHRT3N10D7", & - "EDDSHRT3N10D8","EDDSHRT3N10D9","EDDSHRT3N11D1","EDDSHRT3N11D2","EDDSHRT3N11D3","EDDSHRT3N11D4","EDDSHRT3N11D5","EDDSHRT3N11D6", & - "EDDSHRT3N11D7","EDDSHRT3N11D8","EDDSHRT3N11D9","EDDSHRT3N12D1","EDDSHRT3N12D2","EDDSHRT3N12D3","EDDSHRT3N12D4","EDDSHRT3N12D5", & - "EDDSHRT3N12D6","EDDSHRT3N12D7","EDDSHRT3N12D8","EDDSHRT3N12D9","EDDSHRT3N13D1","EDDSHRT3N13D2","EDDSHRT3N13D3","EDDSHRT3N13D4", & - "EDDSHRT3N13D5","EDDSHRT3N13D6","EDDSHRT3N13D7","EDDSHRT3N13D8","EDDSHRT3N13D9","EDDSHRT3N14D1","EDDSHRT3N14D2","EDDSHRT3N14D3", & - "EDDSHRT3N14D4","EDDSHRT3N14D5","EDDSHRT3N14D6","EDDSHRT3N14D7","EDDSHRT3N14D8","EDDSHRT3N14D9","EDDSHRT3N15D1","EDDSHRT3N15D2", & - "EDDSHRT3N15D3","EDDSHRT3N15D4","EDDSHRT3N15D5","EDDSHRT3N15D6","EDDSHRT3N15D7","EDDSHRT3N15D8","EDDSHRT3N15D9","EDDSHRT3N16D1", & - "EDDSHRT3N16D2","EDDSHRT3N16D3","EDDSHRT3N16D4","EDDSHRT3N16D5","EDDSHRT3N16D6","EDDSHRT3N16D7","EDDSHRT3N16D8","EDDSHRT3N16D9", & - "EDDSHRT3N17D1","EDDSHRT3N17D2","EDDSHRT3N17D3","EDDSHRT3N17D4","EDDSHRT3N17D5","EDDSHRT3N17D6","EDDSHRT3N17D7","EDDSHRT3N17D8", & - "EDDSHRT3N17D9","EDDSHRT3N18D1","EDDSHRT3N18D2","EDDSHRT3N18D3","EDDSHRT3N18D4","EDDSHRT3N18D5","EDDSHRT3N18D6","EDDSHRT3N18D7", & - "EDDSHRT3N18D8","EDDSHRT3N18D9","EDDSHRT3N19D1","EDDSHRT3N19D2","EDDSHRT3N19D3","EDDSHRT3N19D4","EDDSHRT3N19D5","EDDSHRT3N19D6", & - "EDDSHRT3N19D7","EDDSHRT3N19D8","EDDSHRT3N19D9","EDDSHRT3N20D1","EDDSHRT3N20D2","EDDSHRT3N20D3","EDDSHRT3N20D4","EDDSHRT3N20D5", & - "EDDSHRT3N20D6","EDDSHRT3N20D7","EDDSHRT3N20D8","EDDSHRT3N20D9","EDDSHRT4N01D1","EDDSHRT4N01D2","EDDSHRT4N01D3","EDDSHRT4N01D4", & - "EDDSHRT4N01D5","EDDSHRT4N01D6","EDDSHRT4N01D7","EDDSHRT4N01D8","EDDSHRT4N01D9","EDDSHRT4N02D1","EDDSHRT4N02D2","EDDSHRT4N02D3", & - "EDDSHRT4N02D4","EDDSHRT4N02D5","EDDSHRT4N02D6","EDDSHRT4N02D7","EDDSHRT4N02D8","EDDSHRT4N02D9","EDDSHRT4N03D1","EDDSHRT4N03D2", & - "EDDSHRT4N03D3","EDDSHRT4N03D4","EDDSHRT4N03D5","EDDSHRT4N03D6","EDDSHRT4N03D7","EDDSHRT4N03D8","EDDSHRT4N03D9","EDDSHRT4N04D1", & - "EDDSHRT4N04D2","EDDSHRT4N04D3","EDDSHRT4N04D4","EDDSHRT4N04D5","EDDSHRT4N04D6","EDDSHRT4N04D7","EDDSHRT4N04D8","EDDSHRT4N04D9", & - "EDDSHRT4N05D1","EDDSHRT4N05D2","EDDSHRT4N05D3","EDDSHRT4N05D4","EDDSHRT4N05D5","EDDSHRT4N05D6","EDDSHRT4N05D7","EDDSHRT4N05D8", & - "EDDSHRT4N05D9","EDDSHRT4N06D1","EDDSHRT4N06D2","EDDSHRT4N06D3","EDDSHRT4N06D4","EDDSHRT4N06D5","EDDSHRT4N06D6","EDDSHRT4N06D7", & - "EDDSHRT4N06D8","EDDSHRT4N06D9","EDDSHRT4N07D1","EDDSHRT4N07D2","EDDSHRT4N07D3","EDDSHRT4N07D4","EDDSHRT4N07D5","EDDSHRT4N07D6", & - "EDDSHRT4N07D7","EDDSHRT4N07D8","EDDSHRT4N07D9","EDDSHRT4N08D1","EDDSHRT4N08D2","EDDSHRT4N08D3","EDDSHRT4N08D4","EDDSHRT4N08D5", & - "EDDSHRT4N08D6","EDDSHRT4N08D7","EDDSHRT4N08D8","EDDSHRT4N08D9","EDDSHRT4N09D1","EDDSHRT4N09D2","EDDSHRT4N09D3","EDDSHRT4N09D4", & - "EDDSHRT4N09D5","EDDSHRT4N09D6","EDDSHRT4N09D7","EDDSHRT4N09D8","EDDSHRT4N09D9","EDDSHRT4N10D1","EDDSHRT4N10D2","EDDSHRT4N10D3", & - "EDDSHRT4N10D4","EDDSHRT4N10D5","EDDSHRT4N10D6","EDDSHRT4N10D7","EDDSHRT4N10D8","EDDSHRT4N10D9","EDDSHRT4N11D1","EDDSHRT4N11D2", & - "EDDSHRT4N11D3","EDDSHRT4N11D4","EDDSHRT4N11D5","EDDSHRT4N11D6","EDDSHRT4N11D7","EDDSHRT4N11D8","EDDSHRT4N11D9","EDDSHRT4N12D1", & - "EDDSHRT4N12D2","EDDSHRT4N12D3","EDDSHRT4N12D4","EDDSHRT4N12D5","EDDSHRT4N12D6","EDDSHRT4N12D7","EDDSHRT4N12D8","EDDSHRT4N12D9", & - "EDDSHRT4N13D1","EDDSHRT4N13D2","EDDSHRT4N13D3","EDDSHRT4N13D4","EDDSHRT4N13D5","EDDSHRT4N13D6","EDDSHRT4N13D7","EDDSHRT4N13D8", & - "EDDSHRT4N13D9","EDDSHRT4N14D1","EDDSHRT4N14D2","EDDSHRT4N14D3","EDDSHRT4N14D4","EDDSHRT4N14D5","EDDSHRT4N14D6","EDDSHRT4N14D7", & - "EDDSHRT4N14D8","EDDSHRT4N14D9","EDDSHRT4N15D1","EDDSHRT4N15D2","EDDSHRT4N15D3","EDDSHRT4N15D4","EDDSHRT4N15D5","EDDSHRT4N15D6", & - "EDDSHRT4N15D7","EDDSHRT4N15D8","EDDSHRT4N15D9","EDDSHRT4N16D1","EDDSHRT4N16D2","EDDSHRT4N16D3","EDDSHRT4N16D4","EDDSHRT4N16D5", & - "EDDSHRT4N16D6","EDDSHRT4N16D7","EDDSHRT4N16D8","EDDSHRT4N16D9","EDDSHRT4N17D1","EDDSHRT4N17D2","EDDSHRT4N17D3","EDDSHRT4N17D4", & - "EDDSHRT4N17D5","EDDSHRT4N17D6","EDDSHRT4N17D7","EDDSHRT4N17D8","EDDSHRT4N17D9","EDDSHRT4N18D1","EDDSHRT4N18D2","EDDSHRT4N18D3", & - "EDDSHRT4N18D4","EDDSHRT4N18D5","EDDSHRT4N18D6","EDDSHRT4N18D7","EDDSHRT4N18D8","EDDSHRT4N18D9","EDDSHRT4N19D1","EDDSHRT4N19D2", & - "EDDSHRT4N19D3","EDDSHRT4N19D4","EDDSHRT4N19D5","EDDSHRT4N19D6","EDDSHRT4N19D7","EDDSHRT4N19D8","EDDSHRT4N19D9","EDDSHRT4N20D1", & - "EDDSHRT4N20D2","EDDSHRT4N20D3","EDDSHRT4N20D4","EDDSHRT4N20D5","EDDSHRT4N20D6","EDDSHRT4N20D7","EDDSHRT4N20D8","EDDSHRT4N20D9", & - "EDDSHRT5N01D1","EDDSHRT5N01D2","EDDSHRT5N01D3","EDDSHRT5N01D4","EDDSHRT5N01D5","EDDSHRT5N01D6","EDDSHRT5N01D7","EDDSHRT5N01D8", & - "EDDSHRT5N01D9","EDDSHRT5N02D1","EDDSHRT5N02D2","EDDSHRT5N02D3","EDDSHRT5N02D4","EDDSHRT5N02D5","EDDSHRT5N02D6","EDDSHRT5N02D7", & - "EDDSHRT5N02D8","EDDSHRT5N02D9","EDDSHRT5N03D1","EDDSHRT5N03D2","EDDSHRT5N03D3","EDDSHRT5N03D4","EDDSHRT5N03D5","EDDSHRT5N03D6", & - "EDDSHRT5N03D7","EDDSHRT5N03D8","EDDSHRT5N03D9","EDDSHRT5N04D1","EDDSHRT5N04D2","EDDSHRT5N04D3","EDDSHRT5N04D4","EDDSHRT5N04D5", & - "EDDSHRT5N04D6","EDDSHRT5N04D7","EDDSHRT5N04D8","EDDSHRT5N04D9","EDDSHRT5N05D1","EDDSHRT5N05D2","EDDSHRT5N05D3","EDDSHRT5N05D4", & - "EDDSHRT5N05D5","EDDSHRT5N05D6","EDDSHRT5N05D7","EDDSHRT5N05D8","EDDSHRT5N05D9","EDDSHRT5N06D1","EDDSHRT5N06D2","EDDSHRT5N06D3", & - "EDDSHRT5N06D4","EDDSHRT5N06D5","EDDSHRT5N06D6","EDDSHRT5N06D7","EDDSHRT5N06D8","EDDSHRT5N06D9","EDDSHRT5N07D1","EDDSHRT5N07D2", & - "EDDSHRT5N07D3","EDDSHRT5N07D4","EDDSHRT5N07D5","EDDSHRT5N07D6","EDDSHRT5N07D7","EDDSHRT5N07D8","EDDSHRT5N07D9","EDDSHRT5N08D1", & - "EDDSHRT5N08D2","EDDSHRT5N08D3","EDDSHRT5N08D4","EDDSHRT5N08D5","EDDSHRT5N08D6","EDDSHRT5N08D7","EDDSHRT5N08D8","EDDSHRT5N08D9", & - "EDDSHRT5N09D1","EDDSHRT5N09D2","EDDSHRT5N09D3","EDDSHRT5N09D4","EDDSHRT5N09D5","EDDSHRT5N09D6","EDDSHRT5N09D7","EDDSHRT5N09D8", & - "EDDSHRT5N09D9","EDDSHRT5N10D1","EDDSHRT5N10D2","EDDSHRT5N10D3","EDDSHRT5N10D4","EDDSHRT5N10D5","EDDSHRT5N10D6","EDDSHRT5N10D7", & - "EDDSHRT5N10D8","EDDSHRT5N10D9","EDDSHRT5N11D1","EDDSHRT5N11D2","EDDSHRT5N11D3","EDDSHRT5N11D4","EDDSHRT5N11D5","EDDSHRT5N11D6", & - "EDDSHRT5N11D7","EDDSHRT5N11D8","EDDSHRT5N11D9","EDDSHRT5N12D1","EDDSHRT5N12D2","EDDSHRT5N12D3","EDDSHRT5N12D4","EDDSHRT5N12D5", & - "EDDSHRT5N12D6","EDDSHRT5N12D7","EDDSHRT5N12D8","EDDSHRT5N12D9","EDDSHRT5N13D1","EDDSHRT5N13D2","EDDSHRT5N13D3","EDDSHRT5N13D4", & - "EDDSHRT5N13D5","EDDSHRT5N13D6","EDDSHRT5N13D7","EDDSHRT5N13D8","EDDSHRT5N13D9","EDDSHRT5N14D1","EDDSHRT5N14D2","EDDSHRT5N14D3", & - "EDDSHRT5N14D4","EDDSHRT5N14D5","EDDSHRT5N14D6","EDDSHRT5N14D7","EDDSHRT5N14D8","EDDSHRT5N14D9","EDDSHRT5N15D1","EDDSHRT5N15D2", & - "EDDSHRT5N15D3","EDDSHRT5N15D4","EDDSHRT5N15D5","EDDSHRT5N15D6","EDDSHRT5N15D7","EDDSHRT5N15D8","EDDSHRT5N15D9","EDDSHRT5N16D1", & - "EDDSHRT5N16D2","EDDSHRT5N16D3","EDDSHRT5N16D4","EDDSHRT5N16D5","EDDSHRT5N16D6","EDDSHRT5N16D7","EDDSHRT5N16D8","EDDSHRT5N16D9", & - "EDDSHRT5N17D1","EDDSHRT5N17D2","EDDSHRT5N17D3","EDDSHRT5N17D4","EDDSHRT5N17D5","EDDSHRT5N17D6","EDDSHRT5N17D7","EDDSHRT5N17D8", & - "EDDSHRT5N17D9","EDDSHRT5N18D1","EDDSHRT5N18D2","EDDSHRT5N18D3","EDDSHRT5N18D4","EDDSHRT5N18D5","EDDSHRT5N18D6","EDDSHRT5N18D7", & - "EDDSHRT5N18D8","EDDSHRT5N18D9","EDDSHRT5N19D1","EDDSHRT5N19D2","EDDSHRT5N19D3","EDDSHRT5N19D4","EDDSHRT5N19D5","EDDSHRT5N19D6", & - "EDDSHRT5N19D7","EDDSHRT5N19D8","EDDSHRT5N19D9","EDDSHRT5N20D1","EDDSHRT5N20D2","EDDSHRT5N20D3","EDDSHRT5N20D4","EDDSHRT5N20D5", & - "EDDSHRT5N20D6","EDDSHRT5N20D7","EDDSHRT5N20D8","EDDSHRT5N20D9","EDDSHRT6N01D1","EDDSHRT6N01D2","EDDSHRT6N01D3","EDDSHRT6N01D4", & - "EDDSHRT6N01D5","EDDSHRT6N01D6","EDDSHRT6N01D7","EDDSHRT6N01D8","EDDSHRT6N01D9","EDDSHRT6N02D1","EDDSHRT6N02D2","EDDSHRT6N02D3", & - "EDDSHRT6N02D4","EDDSHRT6N02D5","EDDSHRT6N02D6","EDDSHRT6N02D7","EDDSHRT6N02D8","EDDSHRT6N02D9","EDDSHRT6N03D1","EDDSHRT6N03D2", & - "EDDSHRT6N03D3","EDDSHRT6N03D4","EDDSHRT6N03D5","EDDSHRT6N03D6","EDDSHRT6N03D7","EDDSHRT6N03D8","EDDSHRT6N03D9","EDDSHRT6N04D1", & - "EDDSHRT6N04D2","EDDSHRT6N04D3","EDDSHRT6N04D4","EDDSHRT6N04D5","EDDSHRT6N04D6","EDDSHRT6N04D7","EDDSHRT6N04D8","EDDSHRT6N04D9", & - "EDDSHRT6N05D1","EDDSHRT6N05D2","EDDSHRT6N05D3","EDDSHRT6N05D4","EDDSHRT6N05D5","EDDSHRT6N05D6","EDDSHRT6N05D7","EDDSHRT6N05D8", & - "EDDSHRT6N05D9","EDDSHRT6N06D1","EDDSHRT6N06D2","EDDSHRT6N06D3","EDDSHRT6N06D4","EDDSHRT6N06D5","EDDSHRT6N06D6","EDDSHRT6N06D7", & - "EDDSHRT6N06D8","EDDSHRT6N06D9","EDDSHRT6N07D1","EDDSHRT6N07D2","EDDSHRT6N07D3","EDDSHRT6N07D4","EDDSHRT6N07D5","EDDSHRT6N07D6", & - "EDDSHRT6N07D7","EDDSHRT6N07D8","EDDSHRT6N07D9","EDDSHRT6N08D1","EDDSHRT6N08D2","EDDSHRT6N08D3","EDDSHRT6N08D4","EDDSHRT6N08D5", & - "EDDSHRT6N08D6","EDDSHRT6N08D7","EDDSHRT6N08D8","EDDSHRT6N08D9","EDDSHRT6N09D1","EDDSHRT6N09D2","EDDSHRT6N09D3","EDDSHRT6N09D4", & - "EDDSHRT6N09D5","EDDSHRT6N09D6","EDDSHRT6N09D7","EDDSHRT6N09D8","EDDSHRT6N09D9","EDDSHRT6N10D1","EDDSHRT6N10D2","EDDSHRT6N10D3", & - "EDDSHRT6N10D4","EDDSHRT6N10D5","EDDSHRT6N10D6","EDDSHRT6N10D7","EDDSHRT6N10D8","EDDSHRT6N10D9","EDDSHRT6N11D1","EDDSHRT6N11D2", & - "EDDSHRT6N11D3","EDDSHRT6N11D4","EDDSHRT6N11D5","EDDSHRT6N11D6","EDDSHRT6N11D7","EDDSHRT6N11D8","EDDSHRT6N11D9","EDDSHRT6N12D1", & - "EDDSHRT6N12D2","EDDSHRT6N12D3","EDDSHRT6N12D4","EDDSHRT6N12D5","EDDSHRT6N12D6","EDDSHRT6N12D7","EDDSHRT6N12D8","EDDSHRT6N12D9", & - "EDDSHRT6N13D1","EDDSHRT6N13D2","EDDSHRT6N13D3","EDDSHRT6N13D4","EDDSHRT6N13D5","EDDSHRT6N13D6","EDDSHRT6N13D7","EDDSHRT6N13D8", & - "EDDSHRT6N13D9","EDDSHRT6N14D1","EDDSHRT6N14D2","EDDSHRT6N14D3","EDDSHRT6N14D4","EDDSHRT6N14D5","EDDSHRT6N14D6","EDDSHRT6N14D7", & - "EDDSHRT6N14D8","EDDSHRT6N14D9","EDDSHRT6N15D1","EDDSHRT6N15D2","EDDSHRT6N15D3","EDDSHRT6N15D4","EDDSHRT6N15D5","EDDSHRT6N15D6", & - "EDDSHRT6N15D7","EDDSHRT6N15D8","EDDSHRT6N15D9","EDDSHRT6N16D1","EDDSHRT6N16D2","EDDSHRT6N16D3","EDDSHRT6N16D4","EDDSHRT6N16D5", & - "EDDSHRT6N16D6","EDDSHRT6N16D7","EDDSHRT6N16D8","EDDSHRT6N16D9","EDDSHRT6N17D1","EDDSHRT6N17D2","EDDSHRT6N17D3","EDDSHRT6N17D4", & - "EDDSHRT6N17D5","EDDSHRT6N17D6","EDDSHRT6N17D7","EDDSHRT6N17D8","EDDSHRT6N17D9","EDDSHRT6N18D1","EDDSHRT6N18D2","EDDSHRT6N18D3", & - "EDDSHRT6N18D4","EDDSHRT6N18D5","EDDSHRT6N18D6","EDDSHRT6N18D7","EDDSHRT6N18D8","EDDSHRT6N18D9","EDDSHRT6N19D1","EDDSHRT6N19D2", & - "EDDSHRT6N19D3","EDDSHRT6N19D4","EDDSHRT6N19D5","EDDSHRT6N19D6","EDDSHRT6N19D7","EDDSHRT6N19D8","EDDSHRT6N19D9","EDDSHRT6N20D1", & - "EDDSHRT6N20D2","EDDSHRT6N20D3","EDDSHRT6N20D4","EDDSHRT6N20D5","EDDSHRT6N20D6","EDDSHRT6N20D7","EDDSHRT6N20D8","EDDSHRT6N20D9", & - "EDDSHRT7N01D1","EDDSHRT7N01D2","EDDSHRT7N01D3","EDDSHRT7N01D4","EDDSHRT7N01D5","EDDSHRT7N01D6","EDDSHRT7N01D7","EDDSHRT7N01D8", & - "EDDSHRT7N01D9","EDDSHRT7N02D1","EDDSHRT7N02D2","EDDSHRT7N02D3","EDDSHRT7N02D4","EDDSHRT7N02D5","EDDSHRT7N02D6","EDDSHRT7N02D7", & - "EDDSHRT7N02D8","EDDSHRT7N02D9","EDDSHRT7N03D1","EDDSHRT7N03D2","EDDSHRT7N03D3","EDDSHRT7N03D4","EDDSHRT7N03D5","EDDSHRT7N03D6", & - "EDDSHRT7N03D7","EDDSHRT7N03D8","EDDSHRT7N03D9","EDDSHRT7N04D1","EDDSHRT7N04D2","EDDSHRT7N04D3","EDDSHRT7N04D4","EDDSHRT7N04D5", & - "EDDSHRT7N04D6","EDDSHRT7N04D7","EDDSHRT7N04D8","EDDSHRT7N04D9","EDDSHRT7N05D1","EDDSHRT7N05D2","EDDSHRT7N05D3","EDDSHRT7N05D4", & - "EDDSHRT7N05D5","EDDSHRT7N05D6","EDDSHRT7N05D7","EDDSHRT7N05D8","EDDSHRT7N05D9","EDDSHRT7N06D1","EDDSHRT7N06D2","EDDSHRT7N06D3", & - "EDDSHRT7N06D4","EDDSHRT7N06D5","EDDSHRT7N06D6","EDDSHRT7N06D7","EDDSHRT7N06D8","EDDSHRT7N06D9","EDDSHRT7N07D1","EDDSHRT7N07D2", & - "EDDSHRT7N07D3","EDDSHRT7N07D4","EDDSHRT7N07D5","EDDSHRT7N07D6","EDDSHRT7N07D7","EDDSHRT7N07D8","EDDSHRT7N07D9","EDDSHRT7N08D1", & - "EDDSHRT7N08D2","EDDSHRT7N08D3","EDDSHRT7N08D4","EDDSHRT7N08D5","EDDSHRT7N08D6","EDDSHRT7N08D7","EDDSHRT7N08D8","EDDSHRT7N08D9", & - "EDDSHRT7N09D1","EDDSHRT7N09D2","EDDSHRT7N09D3","EDDSHRT7N09D4","EDDSHRT7N09D5","EDDSHRT7N09D6","EDDSHRT7N09D7","EDDSHRT7N09D8", & - "EDDSHRT7N09D9","EDDSHRT7N10D1","EDDSHRT7N10D2","EDDSHRT7N10D3","EDDSHRT7N10D4","EDDSHRT7N10D5","EDDSHRT7N10D6","EDDSHRT7N10D7", & - "EDDSHRT7N10D8","EDDSHRT7N10D9","EDDSHRT7N11D1","EDDSHRT7N11D2","EDDSHRT7N11D3","EDDSHRT7N11D4","EDDSHRT7N11D5","EDDSHRT7N11D6", & - "EDDSHRT7N11D7","EDDSHRT7N11D8","EDDSHRT7N11D9","EDDSHRT7N12D1","EDDSHRT7N12D2","EDDSHRT7N12D3","EDDSHRT7N12D4","EDDSHRT7N12D5", & - "EDDSHRT7N12D6","EDDSHRT7N12D7","EDDSHRT7N12D8","EDDSHRT7N12D9","EDDSHRT7N13D1","EDDSHRT7N13D2","EDDSHRT7N13D3","EDDSHRT7N13D4", & - "EDDSHRT7N13D5","EDDSHRT7N13D6","EDDSHRT7N13D7","EDDSHRT7N13D8","EDDSHRT7N13D9","EDDSHRT7N14D1","EDDSHRT7N14D2","EDDSHRT7N14D3", & - "EDDSHRT7N14D4","EDDSHRT7N14D5","EDDSHRT7N14D6","EDDSHRT7N14D7","EDDSHRT7N14D8","EDDSHRT7N14D9","EDDSHRT7N15D1","EDDSHRT7N15D2", & - "EDDSHRT7N15D3","EDDSHRT7N15D4","EDDSHRT7N15D5","EDDSHRT7N15D6","EDDSHRT7N15D7","EDDSHRT7N15D8","EDDSHRT7N15D9","EDDSHRT7N16D1", & - "EDDSHRT7N16D2","EDDSHRT7N16D3","EDDSHRT7N16D4","EDDSHRT7N16D5","EDDSHRT7N16D6","EDDSHRT7N16D7","EDDSHRT7N16D8","EDDSHRT7N16D9", & - "EDDSHRT7N17D1","EDDSHRT7N17D2","EDDSHRT7N17D3","EDDSHRT7N17D4","EDDSHRT7N17D5","EDDSHRT7N17D6","EDDSHRT7N17D7","EDDSHRT7N17D8", & - "EDDSHRT7N17D9","EDDSHRT7N18D1","EDDSHRT7N18D2","EDDSHRT7N18D3","EDDSHRT7N18D4","EDDSHRT7N18D5","EDDSHRT7N18D6","EDDSHRT7N18D7", & - "EDDSHRT7N18D8","EDDSHRT7N18D9","EDDSHRT7N19D1","EDDSHRT7N19D2","EDDSHRT7N19D3","EDDSHRT7N19D4","EDDSHRT7N19D5","EDDSHRT7N19D6", & - "EDDSHRT7N19D7","EDDSHRT7N19D8","EDDSHRT7N19D9","EDDSHRT7N20D1","EDDSHRT7N20D2","EDDSHRT7N20D3","EDDSHRT7N20D4","EDDSHRT7N20D5", & - "EDDSHRT7N20D6","EDDSHRT7N20D7","EDDSHRT7N20D8","EDDSHRT7N20D9","EDDSHRT8N01D1","EDDSHRT8N01D2","EDDSHRT8N01D3","EDDSHRT8N01D4", & - "EDDSHRT8N01D5","EDDSHRT8N01D6","EDDSHRT8N01D7","EDDSHRT8N01D8","EDDSHRT8N01D9","EDDSHRT8N02D1","EDDSHRT8N02D2","EDDSHRT8N02D3", & - "EDDSHRT8N02D4","EDDSHRT8N02D5","EDDSHRT8N02D6","EDDSHRT8N02D7","EDDSHRT8N02D8","EDDSHRT8N02D9","EDDSHRT8N03D1","EDDSHRT8N03D2", & - "EDDSHRT8N03D3","EDDSHRT8N03D4","EDDSHRT8N03D5","EDDSHRT8N03D6","EDDSHRT8N03D7","EDDSHRT8N03D8","EDDSHRT8N03D9","EDDSHRT8N04D1", & - "EDDSHRT8N04D2","EDDSHRT8N04D3","EDDSHRT8N04D4","EDDSHRT8N04D5","EDDSHRT8N04D6","EDDSHRT8N04D7","EDDSHRT8N04D8","EDDSHRT8N04D9", & - "EDDSHRT8N05D1","EDDSHRT8N05D2","EDDSHRT8N05D3","EDDSHRT8N05D4","EDDSHRT8N05D5","EDDSHRT8N05D6","EDDSHRT8N05D7","EDDSHRT8N05D8", & - "EDDSHRT8N05D9","EDDSHRT8N06D1","EDDSHRT8N06D2","EDDSHRT8N06D3","EDDSHRT8N06D4","EDDSHRT8N06D5","EDDSHRT8N06D6","EDDSHRT8N06D7", & - "EDDSHRT8N06D8","EDDSHRT8N06D9","EDDSHRT8N07D1","EDDSHRT8N07D2","EDDSHRT8N07D3","EDDSHRT8N07D4","EDDSHRT8N07D5","EDDSHRT8N07D6", & - "EDDSHRT8N07D7","EDDSHRT8N07D8","EDDSHRT8N07D9","EDDSHRT8N08D1","EDDSHRT8N08D2","EDDSHRT8N08D3","EDDSHRT8N08D4","EDDSHRT8N08D5", & - "EDDSHRT8N08D6","EDDSHRT8N08D7","EDDSHRT8N08D8","EDDSHRT8N08D9","EDDSHRT8N09D1","EDDSHRT8N09D2","EDDSHRT8N09D3","EDDSHRT8N09D4", & - "EDDSHRT8N09D5","EDDSHRT8N09D6","EDDSHRT8N09D7","EDDSHRT8N09D8","EDDSHRT8N09D9","EDDSHRT8N10D1","EDDSHRT8N10D2","EDDSHRT8N10D3", & - "EDDSHRT8N10D4","EDDSHRT8N10D5","EDDSHRT8N10D6","EDDSHRT8N10D7","EDDSHRT8N10D8","EDDSHRT8N10D9","EDDSHRT8N11D1","EDDSHRT8N11D2", & - "EDDSHRT8N11D3","EDDSHRT8N11D4","EDDSHRT8N11D5","EDDSHRT8N11D6","EDDSHRT8N11D7","EDDSHRT8N11D8","EDDSHRT8N11D9","EDDSHRT8N12D1", & - "EDDSHRT8N12D2","EDDSHRT8N12D3","EDDSHRT8N12D4","EDDSHRT8N12D5","EDDSHRT8N12D6","EDDSHRT8N12D7","EDDSHRT8N12D8","EDDSHRT8N12D9", & - "EDDSHRT8N13D1","EDDSHRT8N13D2","EDDSHRT8N13D3","EDDSHRT8N13D4","EDDSHRT8N13D5","EDDSHRT8N13D6","EDDSHRT8N13D7","EDDSHRT8N13D8", & - "EDDSHRT8N13D9","EDDSHRT8N14D1","EDDSHRT8N14D2","EDDSHRT8N14D3","EDDSHRT8N14D4","EDDSHRT8N14D5","EDDSHRT8N14D6","EDDSHRT8N14D7", & - "EDDSHRT8N14D8","EDDSHRT8N14D9","EDDSHRT8N15D1","EDDSHRT8N15D2","EDDSHRT8N15D3","EDDSHRT8N15D4","EDDSHRT8N15D5","EDDSHRT8N15D6", & - "EDDSHRT8N15D7","EDDSHRT8N15D8","EDDSHRT8N15D9","EDDSHRT8N16D1","EDDSHRT8N16D2","EDDSHRT8N16D3","EDDSHRT8N16D4","EDDSHRT8N16D5", & - "EDDSHRT8N16D6","EDDSHRT8N16D7","EDDSHRT8N16D8","EDDSHRT8N16D9","EDDSHRT8N17D1","EDDSHRT8N17D2","EDDSHRT8N17D3","EDDSHRT8N17D4", & - "EDDSHRT8N17D5","EDDSHRT8N17D6","EDDSHRT8N17D7","EDDSHRT8N17D8","EDDSHRT8N17D9","EDDSHRT8N18D1","EDDSHRT8N18D2","EDDSHRT8N18D3", & - "EDDSHRT8N18D4","EDDSHRT8N18D5","EDDSHRT8N18D6","EDDSHRT8N18D7","EDDSHRT8N18D8","EDDSHRT8N18D9","EDDSHRT8N19D1","EDDSHRT8N19D2", & - "EDDSHRT8N19D3","EDDSHRT8N19D4","EDDSHRT8N19D5","EDDSHRT8N19D6","EDDSHRT8N19D7","EDDSHRT8N19D8","EDDSHRT8N19D9","EDDSHRT8N20D1", & - "EDDSHRT8N20D2","EDDSHRT8N20D3","EDDSHRT8N20D4","EDDSHRT8N20D5","EDDSHRT8N20D6","EDDSHRT8N20D7","EDDSHRT8N20D8","EDDSHRT8N20D9", & - "EDDSHRT9N01D1","EDDSHRT9N01D2","EDDSHRT9N01D3","EDDSHRT9N01D4","EDDSHRT9N01D5","EDDSHRT9N01D6","EDDSHRT9N01D7","EDDSHRT9N01D8", & - "EDDSHRT9N01D9","EDDSHRT9N02D1","EDDSHRT9N02D2","EDDSHRT9N02D3","EDDSHRT9N02D4","EDDSHRT9N02D5","EDDSHRT9N02D6","EDDSHRT9N02D7", & - "EDDSHRT9N02D8","EDDSHRT9N02D9","EDDSHRT9N03D1","EDDSHRT9N03D2","EDDSHRT9N03D3","EDDSHRT9N03D4","EDDSHRT9N03D5","EDDSHRT9N03D6", & - "EDDSHRT9N03D7","EDDSHRT9N03D8","EDDSHRT9N03D9","EDDSHRT9N04D1","EDDSHRT9N04D2","EDDSHRT9N04D3","EDDSHRT9N04D4","EDDSHRT9N04D5", & - "EDDSHRT9N04D6","EDDSHRT9N04D7","EDDSHRT9N04D8","EDDSHRT9N04D9","EDDSHRT9N05D1","EDDSHRT9N05D2","EDDSHRT9N05D3","EDDSHRT9N05D4", & - "EDDSHRT9N05D5","EDDSHRT9N05D6","EDDSHRT9N05D7","EDDSHRT9N05D8","EDDSHRT9N05D9","EDDSHRT9N06D1","EDDSHRT9N06D2","EDDSHRT9N06D3", & - "EDDSHRT9N06D4","EDDSHRT9N06D5","EDDSHRT9N06D6","EDDSHRT9N06D7","EDDSHRT9N06D8","EDDSHRT9N06D9","EDDSHRT9N07D1","EDDSHRT9N07D2", & - "EDDSHRT9N07D3","EDDSHRT9N07D4","EDDSHRT9N07D5","EDDSHRT9N07D6","EDDSHRT9N07D7","EDDSHRT9N07D8","EDDSHRT9N07D9","EDDSHRT9N08D1", & - "EDDSHRT9N08D2","EDDSHRT9N08D3","EDDSHRT9N08D4","EDDSHRT9N08D5","EDDSHRT9N08D6","EDDSHRT9N08D7","EDDSHRT9N08D8","EDDSHRT9N08D9", & - "EDDSHRT9N09D1","EDDSHRT9N09D2","EDDSHRT9N09D3","EDDSHRT9N09D4","EDDSHRT9N09D5","EDDSHRT9N09D6","EDDSHRT9N09D7","EDDSHRT9N09D8", & - "EDDSHRT9N09D9","EDDSHRT9N10D1","EDDSHRT9N10D2","EDDSHRT9N10D3","EDDSHRT9N10D4","EDDSHRT9N10D5","EDDSHRT9N10D6","EDDSHRT9N10D7", & - "EDDSHRT9N10D8","EDDSHRT9N10D9","EDDSHRT9N11D1","EDDSHRT9N11D2","EDDSHRT9N11D3","EDDSHRT9N11D4","EDDSHRT9N11D5","EDDSHRT9N11D6", & - "EDDSHRT9N11D7","EDDSHRT9N11D8","EDDSHRT9N11D9","EDDSHRT9N12D1","EDDSHRT9N12D2","EDDSHRT9N12D3","EDDSHRT9N12D4","EDDSHRT9N12D5", & - "EDDSHRT9N12D6","EDDSHRT9N12D7","EDDSHRT9N12D8","EDDSHRT9N12D9","EDDSHRT9N13D1","EDDSHRT9N13D2","EDDSHRT9N13D3","EDDSHRT9N13D4", & - "EDDSHRT9N13D5","EDDSHRT9N13D6","EDDSHRT9N13D7","EDDSHRT9N13D8","EDDSHRT9N13D9","EDDSHRT9N14D1","EDDSHRT9N14D2","EDDSHRT9N14D3", & - "EDDSHRT9N14D4","EDDSHRT9N14D5","EDDSHRT9N14D6","EDDSHRT9N14D7","EDDSHRT9N14D8","EDDSHRT9N14D9","EDDSHRT9N15D1","EDDSHRT9N15D2", & - "EDDSHRT9N15D3","EDDSHRT9N15D4","EDDSHRT9N15D5","EDDSHRT9N15D6","EDDSHRT9N15D7","EDDSHRT9N15D8","EDDSHRT9N15D9","EDDSHRT9N16D1", & - "EDDSHRT9N16D2","EDDSHRT9N16D3","EDDSHRT9N16D4","EDDSHRT9N16D5","EDDSHRT9N16D6","EDDSHRT9N16D7","EDDSHRT9N16D8","EDDSHRT9N16D9", & - "EDDSHRT9N17D1","EDDSHRT9N17D2","EDDSHRT9N17D3","EDDSHRT9N17D4","EDDSHRT9N17D5","EDDSHRT9N17D6","EDDSHRT9N17D7","EDDSHRT9N17D8", & - "EDDSHRT9N17D9","EDDSHRT9N18D1","EDDSHRT9N18D2","EDDSHRT9N18D3","EDDSHRT9N18D4","EDDSHRT9N18D5","EDDSHRT9N18D6","EDDSHRT9N18D7", & - "EDDSHRT9N18D8","EDDSHRT9N18D9","EDDSHRT9N19D1","EDDSHRT9N19D2","EDDSHRT9N19D3","EDDSHRT9N19D4","EDDSHRT9N19D5","EDDSHRT9N19D6", & - "EDDSHRT9N19D7","EDDSHRT9N19D8","EDDSHRT9N19D9","EDDSHRT9N20D1","EDDSHRT9N20D2","EDDSHRT9N20D3","EDDSHRT9N20D4","EDDSHRT9N20D5", & - "EDDSHRT9N20D6","EDDSHRT9N20D7","EDDSHRT9N20D8","EDDSHRT9N20D9","EDDVIST1N01D1","EDDVIST1N01D2","EDDVIST1N01D3","EDDVIST1N01D4", & - "EDDVIST1N01D5","EDDVIST1N01D6","EDDVIST1N01D7","EDDVIST1N01D8","EDDVIST1N01D9","EDDVIST1N02D1","EDDVIST1N02D2","EDDVIST1N02D3", & - "EDDVIST1N02D4","EDDVIST1N02D5","EDDVIST1N02D6","EDDVIST1N02D7","EDDVIST1N02D8","EDDVIST1N02D9","EDDVIST1N03D1","EDDVIST1N03D2", & - "EDDVIST1N03D3","EDDVIST1N03D4","EDDVIST1N03D5","EDDVIST1N03D6","EDDVIST1N03D7","EDDVIST1N03D8","EDDVIST1N03D9","EDDVIST1N04D1", & - "EDDVIST1N04D2","EDDVIST1N04D3","EDDVIST1N04D4","EDDVIST1N04D5","EDDVIST1N04D6","EDDVIST1N04D7","EDDVIST1N04D8","EDDVIST1N04D9", & - "EDDVIST1N05D1","EDDVIST1N05D2","EDDVIST1N05D3","EDDVIST1N05D4","EDDVIST1N05D5","EDDVIST1N05D6","EDDVIST1N05D7","EDDVIST1N05D8", & - "EDDVIST1N05D9","EDDVIST1N06D1","EDDVIST1N06D2","EDDVIST1N06D3","EDDVIST1N06D4","EDDVIST1N06D5","EDDVIST1N06D6","EDDVIST1N06D7", & - "EDDVIST1N06D8","EDDVIST1N06D9","EDDVIST1N07D1","EDDVIST1N07D2","EDDVIST1N07D3","EDDVIST1N07D4","EDDVIST1N07D5","EDDVIST1N07D6", & - "EDDVIST1N07D7","EDDVIST1N07D8","EDDVIST1N07D9","EDDVIST1N08D1","EDDVIST1N08D2","EDDVIST1N08D3","EDDVIST1N08D4","EDDVIST1N08D5", & - "EDDVIST1N08D6","EDDVIST1N08D7","EDDVIST1N08D8","EDDVIST1N08D9","EDDVIST1N09D1","EDDVIST1N09D2","EDDVIST1N09D3","EDDVIST1N09D4", & - "EDDVIST1N09D5","EDDVIST1N09D6","EDDVIST1N09D7","EDDVIST1N09D8","EDDVIST1N09D9","EDDVIST1N10D1","EDDVIST1N10D2","EDDVIST1N10D3", & - "EDDVIST1N10D4","EDDVIST1N10D5","EDDVIST1N10D6","EDDVIST1N10D7","EDDVIST1N10D8","EDDVIST1N10D9","EDDVIST1N11D1","EDDVIST1N11D2", & - "EDDVIST1N11D3","EDDVIST1N11D4","EDDVIST1N11D5","EDDVIST1N11D6","EDDVIST1N11D7","EDDVIST1N11D8","EDDVIST1N11D9","EDDVIST1N12D1", & - "EDDVIST1N12D2","EDDVIST1N12D3","EDDVIST1N12D4","EDDVIST1N12D5","EDDVIST1N12D6","EDDVIST1N12D7","EDDVIST1N12D8","EDDVIST1N12D9", & - "EDDVIST1N13D1","EDDVIST1N13D2","EDDVIST1N13D3","EDDVIST1N13D4","EDDVIST1N13D5","EDDVIST1N13D6","EDDVIST1N13D7","EDDVIST1N13D8", & - "EDDVIST1N13D9","EDDVIST1N14D1","EDDVIST1N14D2","EDDVIST1N14D3","EDDVIST1N14D4","EDDVIST1N14D5","EDDVIST1N14D6","EDDVIST1N14D7", & - "EDDVIST1N14D8","EDDVIST1N14D9","EDDVIST1N15D1","EDDVIST1N15D2","EDDVIST1N15D3","EDDVIST1N15D4","EDDVIST1N15D5","EDDVIST1N15D6", & - "EDDVIST1N15D7","EDDVIST1N15D8","EDDVIST1N15D9","EDDVIST1N16D1","EDDVIST1N16D2","EDDVIST1N16D3","EDDVIST1N16D4","EDDVIST1N16D5", & - "EDDVIST1N16D6","EDDVIST1N16D7","EDDVIST1N16D8","EDDVIST1N16D9","EDDVIST1N17D1","EDDVIST1N17D2","EDDVIST1N17D3","EDDVIST1N17D4", & - "EDDVIST1N17D5","EDDVIST1N17D6","EDDVIST1N17D7","EDDVIST1N17D8","EDDVIST1N17D9","EDDVIST1N18D1","EDDVIST1N18D2","EDDVIST1N18D3", & - "EDDVIST1N18D4","EDDVIST1N18D5","EDDVIST1N18D6","EDDVIST1N18D7","EDDVIST1N18D8","EDDVIST1N18D9","EDDVIST1N19D1","EDDVIST1N19D2", & - "EDDVIST1N19D3","EDDVIST1N19D4","EDDVIST1N19D5","EDDVIST1N19D6","EDDVIST1N19D7","EDDVIST1N19D8","EDDVIST1N19D9","EDDVIST1N20D1", & - "EDDVIST1N20D2","EDDVIST1N20D3","EDDVIST1N20D4","EDDVIST1N20D5","EDDVIST1N20D6","EDDVIST1N20D7","EDDVIST1N20D8","EDDVIST1N20D9", & - "EDDVIST2N01D1","EDDVIST2N01D2","EDDVIST2N01D3","EDDVIST2N01D4","EDDVIST2N01D5","EDDVIST2N01D6","EDDVIST2N01D7","EDDVIST2N01D8", & - "EDDVIST2N01D9","EDDVIST2N02D1","EDDVIST2N02D2","EDDVIST2N02D3","EDDVIST2N02D4","EDDVIST2N02D5","EDDVIST2N02D6","EDDVIST2N02D7", & - "EDDVIST2N02D8","EDDVIST2N02D9","EDDVIST2N03D1","EDDVIST2N03D2","EDDVIST2N03D3","EDDVIST2N03D4","EDDVIST2N03D5","EDDVIST2N03D6", & - "EDDVIST2N03D7","EDDVIST2N03D8","EDDVIST2N03D9","EDDVIST2N04D1","EDDVIST2N04D2","EDDVIST2N04D3","EDDVIST2N04D4","EDDVIST2N04D5", & - "EDDVIST2N04D6","EDDVIST2N04D7","EDDVIST2N04D8","EDDVIST2N04D9","EDDVIST2N05D1","EDDVIST2N05D2","EDDVIST2N05D3","EDDVIST2N05D4", & - "EDDVIST2N05D5","EDDVIST2N05D6","EDDVIST2N05D7","EDDVIST2N05D8","EDDVIST2N05D9","EDDVIST2N06D1","EDDVIST2N06D2","EDDVIST2N06D3", & - "EDDVIST2N06D4","EDDVIST2N06D5","EDDVIST2N06D6","EDDVIST2N06D7","EDDVIST2N06D8","EDDVIST2N06D9","EDDVIST2N07D1","EDDVIST2N07D2", & - "EDDVIST2N07D3","EDDVIST2N07D4","EDDVIST2N07D5","EDDVIST2N07D6","EDDVIST2N07D7","EDDVIST2N07D8","EDDVIST2N07D9","EDDVIST2N08D1", & - "EDDVIST2N08D2","EDDVIST2N08D3","EDDVIST2N08D4","EDDVIST2N08D5","EDDVIST2N08D6","EDDVIST2N08D7","EDDVIST2N08D8","EDDVIST2N08D9", & - "EDDVIST2N09D1","EDDVIST2N09D2","EDDVIST2N09D3","EDDVIST2N09D4","EDDVIST2N09D5","EDDVIST2N09D6","EDDVIST2N09D7","EDDVIST2N09D8", & - "EDDVIST2N09D9","EDDVIST2N10D1","EDDVIST2N10D2","EDDVIST2N10D3","EDDVIST2N10D4","EDDVIST2N10D5","EDDVIST2N10D6","EDDVIST2N10D7", & - "EDDVIST2N10D8","EDDVIST2N10D9","EDDVIST2N11D1","EDDVIST2N11D2","EDDVIST2N11D3","EDDVIST2N11D4","EDDVIST2N11D5","EDDVIST2N11D6", & - "EDDVIST2N11D7","EDDVIST2N11D8","EDDVIST2N11D9","EDDVIST2N12D1","EDDVIST2N12D2","EDDVIST2N12D3","EDDVIST2N12D4","EDDVIST2N12D5", & - "EDDVIST2N12D6","EDDVIST2N12D7","EDDVIST2N12D8","EDDVIST2N12D9","EDDVIST2N13D1","EDDVIST2N13D2","EDDVIST2N13D3","EDDVIST2N13D4", & - "EDDVIST2N13D5","EDDVIST2N13D6","EDDVIST2N13D7","EDDVIST2N13D8","EDDVIST2N13D9","EDDVIST2N14D1","EDDVIST2N14D2","EDDVIST2N14D3", & - "EDDVIST2N14D4","EDDVIST2N14D5","EDDVIST2N14D6","EDDVIST2N14D7","EDDVIST2N14D8","EDDVIST2N14D9","EDDVIST2N15D1","EDDVIST2N15D2", & - "EDDVIST2N15D3","EDDVIST2N15D4","EDDVIST2N15D5","EDDVIST2N15D6","EDDVIST2N15D7","EDDVIST2N15D8","EDDVIST2N15D9","EDDVIST2N16D1", & - "EDDVIST2N16D2","EDDVIST2N16D3","EDDVIST2N16D4","EDDVIST2N16D5","EDDVIST2N16D6","EDDVIST2N16D7","EDDVIST2N16D8","EDDVIST2N16D9", & - "EDDVIST2N17D1","EDDVIST2N17D2","EDDVIST2N17D3","EDDVIST2N17D4","EDDVIST2N17D5","EDDVIST2N17D6","EDDVIST2N17D7","EDDVIST2N17D8", & - "EDDVIST2N17D9","EDDVIST2N18D1","EDDVIST2N18D2","EDDVIST2N18D3","EDDVIST2N18D4","EDDVIST2N18D5","EDDVIST2N18D6","EDDVIST2N18D7", & - "EDDVIST2N18D8","EDDVIST2N18D9","EDDVIST2N19D1","EDDVIST2N19D2","EDDVIST2N19D3","EDDVIST2N19D4","EDDVIST2N19D5","EDDVIST2N19D6", & - "EDDVIST2N19D7","EDDVIST2N19D8","EDDVIST2N19D9","EDDVIST2N20D1","EDDVIST2N20D2","EDDVIST2N20D3","EDDVIST2N20D4","EDDVIST2N20D5", & - "EDDVIST2N20D6","EDDVIST2N20D7","EDDVIST2N20D8","EDDVIST2N20D9","EDDVIST3N01D1","EDDVIST3N01D2","EDDVIST3N01D3","EDDVIST3N01D4", & - "EDDVIST3N01D5","EDDVIST3N01D6","EDDVIST3N01D7","EDDVIST3N01D8","EDDVIST3N01D9","EDDVIST3N02D1","EDDVIST3N02D2","EDDVIST3N02D3", & - "EDDVIST3N02D4","EDDVIST3N02D5","EDDVIST3N02D6","EDDVIST3N02D7","EDDVIST3N02D8","EDDVIST3N02D9","EDDVIST3N03D1","EDDVIST3N03D2", & - "EDDVIST3N03D3","EDDVIST3N03D4","EDDVIST3N03D5","EDDVIST3N03D6","EDDVIST3N03D7","EDDVIST3N03D8","EDDVIST3N03D9","EDDVIST3N04D1", & - "EDDVIST3N04D2","EDDVIST3N04D3","EDDVIST3N04D4","EDDVIST3N04D5","EDDVIST3N04D6","EDDVIST3N04D7","EDDVIST3N04D8","EDDVIST3N04D9", & - "EDDVIST3N05D1","EDDVIST3N05D2","EDDVIST3N05D3","EDDVIST3N05D4","EDDVIST3N05D5","EDDVIST3N05D6","EDDVIST3N05D7","EDDVIST3N05D8", & - "EDDVIST3N05D9","EDDVIST3N06D1","EDDVIST3N06D2","EDDVIST3N06D3","EDDVIST3N06D4","EDDVIST3N06D5","EDDVIST3N06D6","EDDVIST3N06D7", & - "EDDVIST3N06D8","EDDVIST3N06D9","EDDVIST3N07D1","EDDVIST3N07D2","EDDVIST3N07D3","EDDVIST3N07D4","EDDVIST3N07D5","EDDVIST3N07D6", & - "EDDVIST3N07D7","EDDVIST3N07D8","EDDVIST3N07D9","EDDVIST3N08D1","EDDVIST3N08D2","EDDVIST3N08D3","EDDVIST3N08D4","EDDVIST3N08D5", & - "EDDVIST3N08D6","EDDVIST3N08D7","EDDVIST3N08D8","EDDVIST3N08D9","EDDVIST3N09D1","EDDVIST3N09D2","EDDVIST3N09D3","EDDVIST3N09D4", & - "EDDVIST3N09D5","EDDVIST3N09D6","EDDVIST3N09D7","EDDVIST3N09D8","EDDVIST3N09D9","EDDVIST3N10D1","EDDVIST3N10D2","EDDVIST3N10D3", & - "EDDVIST3N10D4","EDDVIST3N10D5","EDDVIST3N10D6","EDDVIST3N10D7","EDDVIST3N10D8","EDDVIST3N10D9","EDDVIST3N11D1","EDDVIST3N11D2", & - "EDDVIST3N11D3","EDDVIST3N11D4","EDDVIST3N11D5","EDDVIST3N11D6","EDDVIST3N11D7","EDDVIST3N11D8","EDDVIST3N11D9","EDDVIST3N12D1", & - "EDDVIST3N12D2","EDDVIST3N12D3","EDDVIST3N12D4","EDDVIST3N12D5","EDDVIST3N12D6","EDDVIST3N12D7","EDDVIST3N12D8","EDDVIST3N12D9", & - "EDDVIST3N13D1","EDDVIST3N13D2","EDDVIST3N13D3","EDDVIST3N13D4","EDDVIST3N13D5","EDDVIST3N13D6","EDDVIST3N13D7","EDDVIST3N13D8", & - "EDDVIST3N13D9","EDDVIST3N14D1","EDDVIST3N14D2","EDDVIST3N14D3","EDDVIST3N14D4","EDDVIST3N14D5","EDDVIST3N14D6","EDDVIST3N14D7", & - "EDDVIST3N14D8","EDDVIST3N14D9","EDDVIST3N15D1","EDDVIST3N15D2","EDDVIST3N15D3","EDDVIST3N15D4","EDDVIST3N15D5","EDDVIST3N15D6", & - "EDDVIST3N15D7","EDDVIST3N15D8","EDDVIST3N15D9","EDDVIST3N16D1","EDDVIST3N16D2","EDDVIST3N16D3","EDDVIST3N16D4","EDDVIST3N16D5", & - "EDDVIST3N16D6","EDDVIST3N16D7","EDDVIST3N16D8","EDDVIST3N16D9","EDDVIST3N17D1","EDDVIST3N17D2","EDDVIST3N17D3","EDDVIST3N17D4", & - "EDDVIST3N17D5","EDDVIST3N17D6","EDDVIST3N17D7","EDDVIST3N17D8","EDDVIST3N17D9","EDDVIST3N18D1","EDDVIST3N18D2","EDDVIST3N18D3", & - "EDDVIST3N18D4","EDDVIST3N18D5","EDDVIST3N18D6","EDDVIST3N18D7","EDDVIST3N18D8","EDDVIST3N18D9","EDDVIST3N19D1","EDDVIST3N19D2", & - "EDDVIST3N19D3","EDDVIST3N19D4","EDDVIST3N19D5","EDDVIST3N19D6","EDDVIST3N19D7","EDDVIST3N19D8","EDDVIST3N19D9","EDDVIST3N20D1", & - "EDDVIST3N20D2","EDDVIST3N20D3","EDDVIST3N20D4","EDDVIST3N20D5","EDDVIST3N20D6","EDDVIST3N20D7","EDDVIST3N20D8","EDDVIST3N20D9", & - "EDDVIST4N01D1","EDDVIST4N01D2","EDDVIST4N01D3","EDDVIST4N01D4","EDDVIST4N01D5","EDDVIST4N01D6","EDDVIST4N01D7","EDDVIST4N01D8", & - "EDDVIST4N01D9","EDDVIST4N02D1","EDDVIST4N02D2","EDDVIST4N02D3","EDDVIST4N02D4","EDDVIST4N02D5","EDDVIST4N02D6","EDDVIST4N02D7", & - "EDDVIST4N02D8","EDDVIST4N02D9","EDDVIST4N03D1","EDDVIST4N03D2","EDDVIST4N03D3","EDDVIST4N03D4","EDDVIST4N03D5","EDDVIST4N03D6", & - "EDDVIST4N03D7","EDDVIST4N03D8","EDDVIST4N03D9","EDDVIST4N04D1","EDDVIST4N04D2","EDDVIST4N04D3","EDDVIST4N04D4","EDDVIST4N04D5", & - "EDDVIST4N04D6","EDDVIST4N04D7","EDDVIST4N04D8","EDDVIST4N04D9","EDDVIST4N05D1","EDDVIST4N05D2","EDDVIST4N05D3","EDDVIST4N05D4", & - "EDDVIST4N05D5","EDDVIST4N05D6","EDDVIST4N05D7","EDDVIST4N05D8","EDDVIST4N05D9","EDDVIST4N06D1","EDDVIST4N06D2","EDDVIST4N06D3", & - "EDDVIST4N06D4","EDDVIST4N06D5","EDDVIST4N06D6","EDDVIST4N06D7","EDDVIST4N06D8","EDDVIST4N06D9","EDDVIST4N07D1","EDDVIST4N07D2", & - "EDDVIST4N07D3","EDDVIST4N07D4","EDDVIST4N07D5","EDDVIST4N07D6","EDDVIST4N07D7","EDDVIST4N07D8","EDDVIST4N07D9","EDDVIST4N08D1", & - "EDDVIST4N08D2","EDDVIST4N08D3","EDDVIST4N08D4","EDDVIST4N08D5","EDDVIST4N08D6","EDDVIST4N08D7","EDDVIST4N08D8","EDDVIST4N08D9", & - "EDDVIST4N09D1","EDDVIST4N09D2","EDDVIST4N09D3","EDDVIST4N09D4","EDDVIST4N09D5","EDDVIST4N09D6","EDDVIST4N09D7","EDDVIST4N09D8", & - "EDDVIST4N09D9","EDDVIST4N10D1","EDDVIST4N10D2","EDDVIST4N10D3","EDDVIST4N10D4","EDDVIST4N10D5","EDDVIST4N10D6","EDDVIST4N10D7", & - "EDDVIST4N10D8","EDDVIST4N10D9","EDDVIST4N11D1","EDDVIST4N11D2","EDDVIST4N11D3","EDDVIST4N11D4","EDDVIST4N11D5","EDDVIST4N11D6", & - "EDDVIST4N11D7","EDDVIST4N11D8","EDDVIST4N11D9","EDDVIST4N12D1","EDDVIST4N12D2","EDDVIST4N12D3","EDDVIST4N12D4","EDDVIST4N12D5", & - "EDDVIST4N12D6","EDDVIST4N12D7","EDDVIST4N12D8","EDDVIST4N12D9","EDDVIST4N13D1","EDDVIST4N13D2","EDDVIST4N13D3","EDDVIST4N13D4", & - "EDDVIST4N13D5","EDDVIST4N13D6","EDDVIST4N13D7","EDDVIST4N13D8","EDDVIST4N13D9","EDDVIST4N14D1","EDDVIST4N14D2","EDDVIST4N14D3"/) - ValidParamAry(4081:6120) = (/ & - "EDDVIST4N14D4","EDDVIST4N14D5","EDDVIST4N14D6","EDDVIST4N14D7","EDDVIST4N14D8","EDDVIST4N14D9","EDDVIST4N15D1","EDDVIST4N15D2", & - "EDDVIST4N15D3","EDDVIST4N15D4","EDDVIST4N15D5","EDDVIST4N15D6","EDDVIST4N15D7","EDDVIST4N15D8","EDDVIST4N15D9","EDDVIST4N16D1", & - "EDDVIST4N16D2","EDDVIST4N16D3","EDDVIST4N16D4","EDDVIST4N16D5","EDDVIST4N16D6","EDDVIST4N16D7","EDDVIST4N16D8","EDDVIST4N16D9", & - "EDDVIST4N17D1","EDDVIST4N17D2","EDDVIST4N17D3","EDDVIST4N17D4","EDDVIST4N17D5","EDDVIST4N17D6","EDDVIST4N17D7","EDDVIST4N17D8", & - "EDDVIST4N17D9","EDDVIST4N18D1","EDDVIST4N18D2","EDDVIST4N18D3","EDDVIST4N18D4","EDDVIST4N18D5","EDDVIST4N18D6","EDDVIST4N18D7", & - "EDDVIST4N18D8","EDDVIST4N18D9","EDDVIST4N19D1","EDDVIST4N19D2","EDDVIST4N19D3","EDDVIST4N19D4","EDDVIST4N19D5","EDDVIST4N19D6", & - "EDDVIST4N19D7","EDDVIST4N19D8","EDDVIST4N19D9","EDDVIST4N20D1","EDDVIST4N20D2","EDDVIST4N20D3","EDDVIST4N20D4","EDDVIST4N20D5", & - "EDDVIST4N20D6","EDDVIST4N20D7","EDDVIST4N20D8","EDDVIST4N20D9","EDDVIST5N01D1","EDDVIST5N01D2","EDDVIST5N01D3","EDDVIST5N01D4", & - "EDDVIST5N01D5","EDDVIST5N01D6","EDDVIST5N01D7","EDDVIST5N01D8","EDDVIST5N01D9","EDDVIST5N02D1","EDDVIST5N02D2","EDDVIST5N02D3", & - "EDDVIST5N02D4","EDDVIST5N02D5","EDDVIST5N02D6","EDDVIST5N02D7","EDDVIST5N02D8","EDDVIST5N02D9","EDDVIST5N03D1","EDDVIST5N03D2", & - "EDDVIST5N03D3","EDDVIST5N03D4","EDDVIST5N03D5","EDDVIST5N03D6","EDDVIST5N03D7","EDDVIST5N03D8","EDDVIST5N03D9","EDDVIST5N04D1", & - "EDDVIST5N04D2","EDDVIST5N04D3","EDDVIST5N04D4","EDDVIST5N04D5","EDDVIST5N04D6","EDDVIST5N04D7","EDDVIST5N04D8","EDDVIST5N04D9", & - "EDDVIST5N05D1","EDDVIST5N05D2","EDDVIST5N05D3","EDDVIST5N05D4","EDDVIST5N05D5","EDDVIST5N05D6","EDDVIST5N05D7","EDDVIST5N05D8", & - "EDDVIST5N05D9","EDDVIST5N06D1","EDDVIST5N06D2","EDDVIST5N06D3","EDDVIST5N06D4","EDDVIST5N06D5","EDDVIST5N06D6","EDDVIST5N06D7", & - "EDDVIST5N06D8","EDDVIST5N06D9","EDDVIST5N07D1","EDDVIST5N07D2","EDDVIST5N07D3","EDDVIST5N07D4","EDDVIST5N07D5","EDDVIST5N07D6", & - "EDDVIST5N07D7","EDDVIST5N07D8","EDDVIST5N07D9","EDDVIST5N08D1","EDDVIST5N08D2","EDDVIST5N08D3","EDDVIST5N08D4","EDDVIST5N08D5", & - "EDDVIST5N08D6","EDDVIST5N08D7","EDDVIST5N08D8","EDDVIST5N08D9","EDDVIST5N09D1","EDDVIST5N09D2","EDDVIST5N09D3","EDDVIST5N09D4", & - "EDDVIST5N09D5","EDDVIST5N09D6","EDDVIST5N09D7","EDDVIST5N09D8","EDDVIST5N09D9","EDDVIST5N10D1","EDDVIST5N10D2","EDDVIST5N10D3", & - "EDDVIST5N10D4","EDDVIST5N10D5","EDDVIST5N10D6","EDDVIST5N10D7","EDDVIST5N10D8","EDDVIST5N10D9","EDDVIST5N11D1","EDDVIST5N11D2", & - "EDDVIST5N11D3","EDDVIST5N11D4","EDDVIST5N11D5","EDDVIST5N11D6","EDDVIST5N11D7","EDDVIST5N11D8","EDDVIST5N11D9","EDDVIST5N12D1", & - "EDDVIST5N12D2","EDDVIST5N12D3","EDDVIST5N12D4","EDDVIST5N12D5","EDDVIST5N12D6","EDDVIST5N12D7","EDDVIST5N12D8","EDDVIST5N12D9", & - "EDDVIST5N13D1","EDDVIST5N13D2","EDDVIST5N13D3","EDDVIST5N13D4","EDDVIST5N13D5","EDDVIST5N13D6","EDDVIST5N13D7","EDDVIST5N13D8", & - "EDDVIST5N13D9","EDDVIST5N14D1","EDDVIST5N14D2","EDDVIST5N14D3","EDDVIST5N14D4","EDDVIST5N14D5","EDDVIST5N14D6","EDDVIST5N14D7", & - "EDDVIST5N14D8","EDDVIST5N14D9","EDDVIST5N15D1","EDDVIST5N15D2","EDDVIST5N15D3","EDDVIST5N15D4","EDDVIST5N15D5","EDDVIST5N15D6", & - "EDDVIST5N15D7","EDDVIST5N15D8","EDDVIST5N15D9","EDDVIST5N16D1","EDDVIST5N16D2","EDDVIST5N16D3","EDDVIST5N16D4","EDDVIST5N16D5", & - "EDDVIST5N16D6","EDDVIST5N16D7","EDDVIST5N16D8","EDDVIST5N16D9","EDDVIST5N17D1","EDDVIST5N17D2","EDDVIST5N17D3","EDDVIST5N17D4", & - "EDDVIST5N17D5","EDDVIST5N17D6","EDDVIST5N17D7","EDDVIST5N17D8","EDDVIST5N17D9","EDDVIST5N18D1","EDDVIST5N18D2","EDDVIST5N18D3", & - "EDDVIST5N18D4","EDDVIST5N18D5","EDDVIST5N18D6","EDDVIST5N18D7","EDDVIST5N18D8","EDDVIST5N18D9","EDDVIST5N19D1","EDDVIST5N19D2", & - "EDDVIST5N19D3","EDDVIST5N19D4","EDDVIST5N19D5","EDDVIST5N19D6","EDDVIST5N19D7","EDDVIST5N19D8","EDDVIST5N19D9","EDDVIST5N20D1", & - "EDDVIST5N20D2","EDDVIST5N20D3","EDDVIST5N20D4","EDDVIST5N20D5","EDDVIST5N20D6","EDDVIST5N20D7","EDDVIST5N20D8","EDDVIST5N20D9", & - "EDDVIST6N01D1","EDDVIST6N01D2","EDDVIST6N01D3","EDDVIST6N01D4","EDDVIST6N01D5","EDDVIST6N01D6","EDDVIST6N01D7","EDDVIST6N01D8", & - "EDDVIST6N01D9","EDDVIST6N02D1","EDDVIST6N02D2","EDDVIST6N02D3","EDDVIST6N02D4","EDDVIST6N02D5","EDDVIST6N02D6","EDDVIST6N02D7", & - "EDDVIST6N02D8","EDDVIST6N02D9","EDDVIST6N03D1","EDDVIST6N03D2","EDDVIST6N03D3","EDDVIST6N03D4","EDDVIST6N03D5","EDDVIST6N03D6", & - "EDDVIST6N03D7","EDDVIST6N03D8","EDDVIST6N03D9","EDDVIST6N04D1","EDDVIST6N04D2","EDDVIST6N04D3","EDDVIST6N04D4","EDDVIST6N04D5", & - "EDDVIST6N04D6","EDDVIST6N04D7","EDDVIST6N04D8","EDDVIST6N04D9","EDDVIST6N05D1","EDDVIST6N05D2","EDDVIST6N05D3","EDDVIST6N05D4", & - "EDDVIST6N05D5","EDDVIST6N05D6","EDDVIST6N05D7","EDDVIST6N05D8","EDDVIST6N05D9","EDDVIST6N06D1","EDDVIST6N06D2","EDDVIST6N06D3", & - "EDDVIST6N06D4","EDDVIST6N06D5","EDDVIST6N06D6","EDDVIST6N06D7","EDDVIST6N06D8","EDDVIST6N06D9","EDDVIST6N07D1","EDDVIST6N07D2", & - "EDDVIST6N07D3","EDDVIST6N07D4","EDDVIST6N07D5","EDDVIST6N07D6","EDDVIST6N07D7","EDDVIST6N07D8","EDDVIST6N07D9","EDDVIST6N08D1", & - "EDDVIST6N08D2","EDDVIST6N08D3","EDDVIST6N08D4","EDDVIST6N08D5","EDDVIST6N08D6","EDDVIST6N08D7","EDDVIST6N08D8","EDDVIST6N08D9", & - "EDDVIST6N09D1","EDDVIST6N09D2","EDDVIST6N09D3","EDDVIST6N09D4","EDDVIST6N09D5","EDDVIST6N09D6","EDDVIST6N09D7","EDDVIST6N09D8", & - "EDDVIST6N09D9","EDDVIST6N10D1","EDDVIST6N10D2","EDDVIST6N10D3","EDDVIST6N10D4","EDDVIST6N10D5","EDDVIST6N10D6","EDDVIST6N10D7", & - "EDDVIST6N10D8","EDDVIST6N10D9","EDDVIST6N11D1","EDDVIST6N11D2","EDDVIST6N11D3","EDDVIST6N11D4","EDDVIST6N11D5","EDDVIST6N11D6", & - "EDDVIST6N11D7","EDDVIST6N11D8","EDDVIST6N11D9","EDDVIST6N12D1","EDDVIST6N12D2","EDDVIST6N12D3","EDDVIST6N12D4","EDDVIST6N12D5", & - "EDDVIST6N12D6","EDDVIST6N12D7","EDDVIST6N12D8","EDDVIST6N12D9","EDDVIST6N13D1","EDDVIST6N13D2","EDDVIST6N13D3","EDDVIST6N13D4", & - "EDDVIST6N13D5","EDDVIST6N13D6","EDDVIST6N13D7","EDDVIST6N13D8","EDDVIST6N13D9","EDDVIST6N14D1","EDDVIST6N14D2","EDDVIST6N14D3", & - "EDDVIST6N14D4","EDDVIST6N14D5","EDDVIST6N14D6","EDDVIST6N14D7","EDDVIST6N14D8","EDDVIST6N14D9","EDDVIST6N15D1","EDDVIST6N15D2", & - "EDDVIST6N15D3","EDDVIST6N15D4","EDDVIST6N15D5","EDDVIST6N15D6","EDDVIST6N15D7","EDDVIST6N15D8","EDDVIST6N15D9","EDDVIST6N16D1", & - "EDDVIST6N16D2","EDDVIST6N16D3","EDDVIST6N16D4","EDDVIST6N16D5","EDDVIST6N16D6","EDDVIST6N16D7","EDDVIST6N16D8","EDDVIST6N16D9", & - "EDDVIST6N17D1","EDDVIST6N17D2","EDDVIST6N17D3","EDDVIST6N17D4","EDDVIST6N17D5","EDDVIST6N17D6","EDDVIST6N17D7","EDDVIST6N17D8", & - "EDDVIST6N17D9","EDDVIST6N18D1","EDDVIST6N18D2","EDDVIST6N18D3","EDDVIST6N18D4","EDDVIST6N18D5","EDDVIST6N18D6","EDDVIST6N18D7", & - "EDDVIST6N18D8","EDDVIST6N18D9","EDDVIST6N19D1","EDDVIST6N19D2","EDDVIST6N19D3","EDDVIST6N19D4","EDDVIST6N19D5","EDDVIST6N19D6", & - "EDDVIST6N19D7","EDDVIST6N19D8","EDDVIST6N19D9","EDDVIST6N20D1","EDDVIST6N20D2","EDDVIST6N20D3","EDDVIST6N20D4","EDDVIST6N20D5", & - "EDDVIST6N20D6","EDDVIST6N20D7","EDDVIST6N20D8","EDDVIST6N20D9","EDDVIST7N01D1","EDDVIST7N01D2","EDDVIST7N01D3","EDDVIST7N01D4", & - "EDDVIST7N01D5","EDDVIST7N01D6","EDDVIST7N01D7","EDDVIST7N01D8","EDDVIST7N01D9","EDDVIST7N02D1","EDDVIST7N02D2","EDDVIST7N02D3", & - "EDDVIST7N02D4","EDDVIST7N02D5","EDDVIST7N02D6","EDDVIST7N02D7","EDDVIST7N02D8","EDDVIST7N02D9","EDDVIST7N03D1","EDDVIST7N03D2", & - "EDDVIST7N03D3","EDDVIST7N03D4","EDDVIST7N03D5","EDDVIST7N03D6","EDDVIST7N03D7","EDDVIST7N03D8","EDDVIST7N03D9","EDDVIST7N04D1", & - "EDDVIST7N04D2","EDDVIST7N04D3","EDDVIST7N04D4","EDDVIST7N04D5","EDDVIST7N04D6","EDDVIST7N04D7","EDDVIST7N04D8","EDDVIST7N04D9", & - "EDDVIST7N05D1","EDDVIST7N05D2","EDDVIST7N05D3","EDDVIST7N05D4","EDDVIST7N05D5","EDDVIST7N05D6","EDDVIST7N05D7","EDDVIST7N05D8", & - "EDDVIST7N05D9","EDDVIST7N06D1","EDDVIST7N06D2","EDDVIST7N06D3","EDDVIST7N06D4","EDDVIST7N06D5","EDDVIST7N06D6","EDDVIST7N06D7", & - "EDDVIST7N06D8","EDDVIST7N06D9","EDDVIST7N07D1","EDDVIST7N07D2","EDDVIST7N07D3","EDDVIST7N07D4","EDDVIST7N07D5","EDDVIST7N07D6", & - "EDDVIST7N07D7","EDDVIST7N07D8","EDDVIST7N07D9","EDDVIST7N08D1","EDDVIST7N08D2","EDDVIST7N08D3","EDDVIST7N08D4","EDDVIST7N08D5", & - "EDDVIST7N08D6","EDDVIST7N08D7","EDDVIST7N08D8","EDDVIST7N08D9","EDDVIST7N09D1","EDDVIST7N09D2","EDDVIST7N09D3","EDDVIST7N09D4", & - "EDDVIST7N09D5","EDDVIST7N09D6","EDDVIST7N09D7","EDDVIST7N09D8","EDDVIST7N09D9","EDDVIST7N10D1","EDDVIST7N10D2","EDDVIST7N10D3", & - "EDDVIST7N10D4","EDDVIST7N10D5","EDDVIST7N10D6","EDDVIST7N10D7","EDDVIST7N10D8","EDDVIST7N10D9","EDDVIST7N11D1","EDDVIST7N11D2", & - "EDDVIST7N11D3","EDDVIST7N11D4","EDDVIST7N11D5","EDDVIST7N11D6","EDDVIST7N11D7","EDDVIST7N11D8","EDDVIST7N11D9","EDDVIST7N12D1", & - "EDDVIST7N12D2","EDDVIST7N12D3","EDDVIST7N12D4","EDDVIST7N12D5","EDDVIST7N12D6","EDDVIST7N12D7","EDDVIST7N12D8","EDDVIST7N12D9", & - "EDDVIST7N13D1","EDDVIST7N13D2","EDDVIST7N13D3","EDDVIST7N13D4","EDDVIST7N13D5","EDDVIST7N13D6","EDDVIST7N13D7","EDDVIST7N13D8", & - "EDDVIST7N13D9","EDDVIST7N14D1","EDDVIST7N14D2","EDDVIST7N14D3","EDDVIST7N14D4","EDDVIST7N14D5","EDDVIST7N14D6","EDDVIST7N14D7", & - "EDDVIST7N14D8","EDDVIST7N14D9","EDDVIST7N15D1","EDDVIST7N15D2","EDDVIST7N15D3","EDDVIST7N15D4","EDDVIST7N15D5","EDDVIST7N15D6", & - "EDDVIST7N15D7","EDDVIST7N15D8","EDDVIST7N15D9","EDDVIST7N16D1","EDDVIST7N16D2","EDDVIST7N16D3","EDDVIST7N16D4","EDDVIST7N16D5", & - "EDDVIST7N16D6","EDDVIST7N16D7","EDDVIST7N16D8","EDDVIST7N16D9","EDDVIST7N17D1","EDDVIST7N17D2","EDDVIST7N17D3","EDDVIST7N17D4", & - "EDDVIST7N17D5","EDDVIST7N17D6","EDDVIST7N17D7","EDDVIST7N17D8","EDDVIST7N17D9","EDDVIST7N18D1","EDDVIST7N18D2","EDDVIST7N18D3", & - "EDDVIST7N18D4","EDDVIST7N18D5","EDDVIST7N18D6","EDDVIST7N18D7","EDDVIST7N18D8","EDDVIST7N18D9","EDDVIST7N19D1","EDDVIST7N19D2", & - "EDDVIST7N19D3","EDDVIST7N19D4","EDDVIST7N19D5","EDDVIST7N19D6","EDDVIST7N19D7","EDDVIST7N19D8","EDDVIST7N19D9","EDDVIST7N20D1", & - "EDDVIST7N20D2","EDDVIST7N20D3","EDDVIST7N20D4","EDDVIST7N20D5","EDDVIST7N20D6","EDDVIST7N20D7","EDDVIST7N20D8","EDDVIST7N20D9", & - "EDDVIST8N01D1","EDDVIST8N01D2","EDDVIST8N01D3","EDDVIST8N01D4","EDDVIST8N01D5","EDDVIST8N01D6","EDDVIST8N01D7","EDDVIST8N01D8", & - "EDDVIST8N01D9","EDDVIST8N02D1","EDDVIST8N02D2","EDDVIST8N02D3","EDDVIST8N02D4","EDDVIST8N02D5","EDDVIST8N02D6","EDDVIST8N02D7", & - "EDDVIST8N02D8","EDDVIST8N02D9","EDDVIST8N03D1","EDDVIST8N03D2","EDDVIST8N03D3","EDDVIST8N03D4","EDDVIST8N03D5","EDDVIST8N03D6", & - "EDDVIST8N03D7","EDDVIST8N03D8","EDDVIST8N03D9","EDDVIST8N04D1","EDDVIST8N04D2","EDDVIST8N04D3","EDDVIST8N04D4","EDDVIST8N04D5", & - "EDDVIST8N04D6","EDDVIST8N04D7","EDDVIST8N04D8","EDDVIST8N04D9","EDDVIST8N05D1","EDDVIST8N05D2","EDDVIST8N05D3","EDDVIST8N05D4", & - "EDDVIST8N05D5","EDDVIST8N05D6","EDDVIST8N05D7","EDDVIST8N05D8","EDDVIST8N05D9","EDDVIST8N06D1","EDDVIST8N06D2","EDDVIST8N06D3", & - "EDDVIST8N06D4","EDDVIST8N06D5","EDDVIST8N06D6","EDDVIST8N06D7","EDDVIST8N06D8","EDDVIST8N06D9","EDDVIST8N07D1","EDDVIST8N07D2", & - "EDDVIST8N07D3","EDDVIST8N07D4","EDDVIST8N07D5","EDDVIST8N07D6","EDDVIST8N07D7","EDDVIST8N07D8","EDDVIST8N07D9","EDDVIST8N08D1", & - "EDDVIST8N08D2","EDDVIST8N08D3","EDDVIST8N08D4","EDDVIST8N08D5","EDDVIST8N08D6","EDDVIST8N08D7","EDDVIST8N08D8","EDDVIST8N08D9", & - "EDDVIST8N09D1","EDDVIST8N09D2","EDDVIST8N09D3","EDDVIST8N09D4","EDDVIST8N09D5","EDDVIST8N09D6","EDDVIST8N09D7","EDDVIST8N09D8", & - "EDDVIST8N09D9","EDDVIST8N10D1","EDDVIST8N10D2","EDDVIST8N10D3","EDDVIST8N10D4","EDDVIST8N10D5","EDDVIST8N10D6","EDDVIST8N10D7", & - "EDDVIST8N10D8","EDDVIST8N10D9","EDDVIST8N11D1","EDDVIST8N11D2","EDDVIST8N11D3","EDDVIST8N11D4","EDDVIST8N11D5","EDDVIST8N11D6", & - "EDDVIST8N11D7","EDDVIST8N11D8","EDDVIST8N11D9","EDDVIST8N12D1","EDDVIST8N12D2","EDDVIST8N12D3","EDDVIST8N12D4","EDDVIST8N12D5", & - "EDDVIST8N12D6","EDDVIST8N12D7","EDDVIST8N12D8","EDDVIST8N12D9","EDDVIST8N13D1","EDDVIST8N13D2","EDDVIST8N13D3","EDDVIST8N13D4", & - "EDDVIST8N13D5","EDDVIST8N13D6","EDDVIST8N13D7","EDDVIST8N13D8","EDDVIST8N13D9","EDDVIST8N14D1","EDDVIST8N14D2","EDDVIST8N14D3", & - "EDDVIST8N14D4","EDDVIST8N14D5","EDDVIST8N14D6","EDDVIST8N14D7","EDDVIST8N14D8","EDDVIST8N14D9","EDDVIST8N15D1","EDDVIST8N15D2", & - "EDDVIST8N15D3","EDDVIST8N15D4","EDDVIST8N15D5","EDDVIST8N15D6","EDDVIST8N15D7","EDDVIST8N15D8","EDDVIST8N15D9","EDDVIST8N16D1", & - "EDDVIST8N16D2","EDDVIST8N16D3","EDDVIST8N16D4","EDDVIST8N16D5","EDDVIST8N16D6","EDDVIST8N16D7","EDDVIST8N16D8","EDDVIST8N16D9", & - "EDDVIST8N17D1","EDDVIST8N17D2","EDDVIST8N17D3","EDDVIST8N17D4","EDDVIST8N17D5","EDDVIST8N17D6","EDDVIST8N17D7","EDDVIST8N17D8", & - "EDDVIST8N17D9","EDDVIST8N18D1","EDDVIST8N18D2","EDDVIST8N18D3","EDDVIST8N18D4","EDDVIST8N18D5","EDDVIST8N18D6","EDDVIST8N18D7", & - "EDDVIST8N18D8","EDDVIST8N18D9","EDDVIST8N19D1","EDDVIST8N19D2","EDDVIST8N19D3","EDDVIST8N19D4","EDDVIST8N19D5","EDDVIST8N19D6", & - "EDDVIST8N19D7","EDDVIST8N19D8","EDDVIST8N19D9","EDDVIST8N20D1","EDDVIST8N20D2","EDDVIST8N20D3","EDDVIST8N20D4","EDDVIST8N20D5", & - "EDDVIST8N20D6","EDDVIST8N20D7","EDDVIST8N20D8","EDDVIST8N20D9","EDDVIST9N01D1","EDDVIST9N01D2","EDDVIST9N01D3","EDDVIST9N01D4", & - "EDDVIST9N01D5","EDDVIST9N01D6","EDDVIST9N01D7","EDDVIST9N01D8","EDDVIST9N01D9","EDDVIST9N02D1","EDDVIST9N02D2","EDDVIST9N02D3", & - "EDDVIST9N02D4","EDDVIST9N02D5","EDDVIST9N02D6","EDDVIST9N02D7","EDDVIST9N02D8","EDDVIST9N02D9","EDDVIST9N03D1","EDDVIST9N03D2", & - "EDDVIST9N03D3","EDDVIST9N03D4","EDDVIST9N03D5","EDDVIST9N03D6","EDDVIST9N03D7","EDDVIST9N03D8","EDDVIST9N03D9","EDDVIST9N04D1", & - "EDDVIST9N04D2","EDDVIST9N04D3","EDDVIST9N04D4","EDDVIST9N04D5","EDDVIST9N04D6","EDDVIST9N04D7","EDDVIST9N04D8","EDDVIST9N04D9", & - "EDDVIST9N05D1","EDDVIST9N05D2","EDDVIST9N05D3","EDDVIST9N05D4","EDDVIST9N05D5","EDDVIST9N05D6","EDDVIST9N05D7","EDDVIST9N05D8", & - "EDDVIST9N05D9","EDDVIST9N06D1","EDDVIST9N06D2","EDDVIST9N06D3","EDDVIST9N06D4","EDDVIST9N06D5","EDDVIST9N06D6","EDDVIST9N06D7", & - "EDDVIST9N06D8","EDDVIST9N06D9","EDDVIST9N07D1","EDDVIST9N07D2","EDDVIST9N07D3","EDDVIST9N07D4","EDDVIST9N07D5","EDDVIST9N07D6", & - "EDDVIST9N07D7","EDDVIST9N07D8","EDDVIST9N07D9","EDDVIST9N08D1","EDDVIST9N08D2","EDDVIST9N08D3","EDDVIST9N08D4","EDDVIST9N08D5", & - "EDDVIST9N08D6","EDDVIST9N08D7","EDDVIST9N08D8","EDDVIST9N08D9","EDDVIST9N09D1","EDDVIST9N09D2","EDDVIST9N09D3","EDDVIST9N09D4", & - "EDDVIST9N09D5","EDDVIST9N09D6","EDDVIST9N09D7","EDDVIST9N09D8","EDDVIST9N09D9","EDDVIST9N10D1","EDDVIST9N10D2","EDDVIST9N10D3", & - "EDDVIST9N10D4","EDDVIST9N10D5","EDDVIST9N10D6","EDDVIST9N10D7","EDDVIST9N10D8","EDDVIST9N10D9","EDDVIST9N11D1","EDDVIST9N11D2", & - "EDDVIST9N11D3","EDDVIST9N11D4","EDDVIST9N11D5","EDDVIST9N11D6","EDDVIST9N11D7","EDDVIST9N11D8","EDDVIST9N11D9","EDDVIST9N12D1", & - "EDDVIST9N12D2","EDDVIST9N12D3","EDDVIST9N12D4","EDDVIST9N12D5","EDDVIST9N12D6","EDDVIST9N12D7","EDDVIST9N12D8","EDDVIST9N12D9", & - "EDDVIST9N13D1","EDDVIST9N13D2","EDDVIST9N13D3","EDDVIST9N13D4","EDDVIST9N13D5","EDDVIST9N13D6","EDDVIST9N13D7","EDDVIST9N13D8", & - "EDDVIST9N13D9","EDDVIST9N14D1","EDDVIST9N14D2","EDDVIST9N14D3","EDDVIST9N14D4","EDDVIST9N14D5","EDDVIST9N14D6","EDDVIST9N14D7", & - "EDDVIST9N14D8","EDDVIST9N14D9","EDDVIST9N15D1","EDDVIST9N15D2","EDDVIST9N15D3","EDDVIST9N15D4","EDDVIST9N15D5","EDDVIST9N15D6", & - "EDDVIST9N15D7","EDDVIST9N15D8","EDDVIST9N15D9","EDDVIST9N16D1","EDDVIST9N16D2","EDDVIST9N16D3","EDDVIST9N16D4","EDDVIST9N16D5", & - "EDDVIST9N16D6","EDDVIST9N16D7","EDDVIST9N16D8","EDDVIST9N16D9","EDDVIST9N17D1","EDDVIST9N17D2","EDDVIST9N17D3","EDDVIST9N17D4", & - "EDDVIST9N17D5","EDDVIST9N17D6","EDDVIST9N17D7","EDDVIST9N17D8","EDDVIST9N17D9","EDDVIST9N18D1","EDDVIST9N18D2","EDDVIST9N18D3", & - "EDDVIST9N18D4","EDDVIST9N18D5","EDDVIST9N18D6","EDDVIST9N18D7","EDDVIST9N18D8","EDDVIST9N18D9","EDDVIST9N19D1","EDDVIST9N19D2", & - "EDDVIST9N19D3","EDDVIST9N19D4","EDDVIST9N19D5","EDDVIST9N19D6","EDDVIST9N19D7","EDDVIST9N19D8","EDDVIST9N19D9","EDDVIST9N20D1", & - "EDDVIST9N20D2","EDDVIST9N20D3","EDDVIST9N20D4","EDDVIST9N20D5","EDDVIST9N20D6","EDDVIST9N20D7","EDDVIST9N20D8","EDDVIST9N20D9", & - "RTAXSXT1 ","RTAXSXT2 ","RTAXSXT3 ","RTAXSXT4 ","RTAXSXT5 ","RTAXSXT6 ","RTAXSXT7 ","RTAXSXT8 ", & - "RTAXSXT9 ","RTAXSYT1 ","RTAXSYT2 ","RTAXSYT3 ","RTAXSYT4 ","RTAXSYT5 ","RTAXSYT6 ","RTAXSYT7 ", & - "RTAXSYT8 ","RTAXSYT9 ","RTAXSZT1 ","RTAXSZT2 ","RTAXSZT3 ","RTAXSZT4 ","RTAXSZT5 ","RTAXSZT6 ", & - "RTAXSZT7 ","RTAXSZT8 ","RTAXSZT9 ","RTDIAMT1 ","RTDIAMT2 ","RTDIAMT3 ","RTDIAMT4 ","RTDIAMT5 ", & - "RTDIAMT6 ","RTDIAMT7 ","RTDIAMT8 ","RTDIAMT9 ","RTPOSXT1 ","RTPOSXT2 ","RTPOSXT3 ","RTPOSXT4 ", & - "RTPOSXT5 ","RTPOSXT6 ","RTPOSXT7 ","RTPOSXT8 ","RTPOSXT9 ","RTPOSYT1 ","RTPOSYT2 ","RTPOSYT3 ", & - "RTPOSYT4 ","RTPOSYT5 ","RTPOSYT6 ","RTPOSYT7 ","RTPOSYT8 ","RTPOSYT9 ","RTPOSZT1 ","RTPOSZT2 ", & - "RTPOSZT3 ","RTPOSZT4 ","RTPOSZT5 ","RTPOSZT6 ","RTPOSZT7 ","RTPOSZT8 ","RTPOSZT9 ","RTVAMBT1 ", & - "RTVAMBT2 ","RTVAMBT3 ","RTVAMBT4 ","RTVAMBT5 ","RTVAMBT6 ","RTVAMBT7 ","RTVAMBT8 ","RTVAMBT9 ", & - "RTVRELT1 ","RTVRELT2 ","RTVRELT3 ","RTVRELT4 ","RTVRELT5 ","RTVRELT6 ","RTVRELT7 ","RTVRELT8 ", & - "RTVRELT9 ","SCGBLIN1 ","SCGBLIN2 ","SCGBLIN3 ","SCGBLIN4 ","SCGBLIN5 ","SCGBLIN6 ","SCGBLIN7 ", & - "SCGBLIN8 ","SCGBLIN9 ","SCGBLOT1 ","SCGBLOT2 ","SCGBLOT3 ","SCGBLOT4 ","SCGBLOT5 ","SCGBLOT6 ", & - "SCGBLOT7 ","SCGBLOT8 ","SCGBLOT9 ","SCT1IN1 ","SCT1IN2 ","SCT1IN3 ","SCT1IN4 ","SCT1IN5 ", & - "SCT1IN6 ","SCT1IN7 ","SCT1IN8 ","SCT1IN9 ","SCT1OT1 ","SCT1OT2 ","SCT1OT3 ","SCT1OT4 ", & - "SCT1OT5 ","SCT1OT6 ","SCT1OT7 ","SCT1OT8 ","SCT1OT9 ","SCT2IN1 ","SCT2IN2 ","SCT2IN3 ", & - "SCT2IN4 ","SCT2IN5 ","SCT2IN6 ","SCT2IN7 ","SCT2IN8 ","SCT2IN9 ","SCT2OT1 ","SCT2OT2 ", & - "SCT2OT3 ","SCT2OT4 ","SCT2OT5 ","SCT2OT6 ","SCT2OT7 ","SCT2OT8 ","SCT2OT9 ","SCT3IN1 ", & - "SCT3IN2 ","SCT3IN3 ","SCT3IN4 ","SCT3IN5 ","SCT3IN6 ","SCT3IN7 ","SCT3IN8 ","SCT3IN9 ", & - "SCT3OT1 ","SCT3OT2 ","SCT3OT3 ","SCT3OT4 ","SCT3OT5 ","SCT3OT6 ","SCT3OT7 ","SCT3OT8 ", & - "SCT3OT9 ","SCT4IN1 ","SCT4IN2 ","SCT4IN3 ","SCT4IN4 ","SCT4IN5 ","SCT4IN6 ","SCT4IN7 ", & - "SCT4IN8 ","SCT4IN9 ","SCT4OT1 ","SCT4OT2 ","SCT4OT3 ","SCT4OT4 ","SCT4OT5 ","SCT4OT6 ", & - "SCT4OT7 ","SCT4OT8 ","SCT4OT9 ","SCT5IN1 ","SCT5IN2 ","SCT5IN3 ","SCT5IN4 ","SCT5IN5 ", & - "SCT5IN6 ","SCT5IN7 ","SCT5IN8 ","SCT5IN9 ","SCT5OT1 ","SCT5OT2 ","SCT5OT3 ","SCT5OT4 ", & - "SCT5OT5 ","SCT5OT6 ","SCT5OT7 ","SCT5OT8 ","SCT5OT9 ","SCT6IN1 ","SCT6IN2 ","SCT6IN3 ", & - "SCT6IN4 ","SCT6IN5 ","SCT6IN6 ","SCT6IN7 ","SCT6IN8 ","SCT6IN9 ","SCT6OT1 ","SCT6OT2 ", & - "SCT6OT3 ","SCT6OT4 ","SCT6OT5 ","SCT6OT6 ","SCT6OT7 ","SCT6OT8 ","SCT6OT9 ","SCT7IN1 ", & - "SCT7IN2 ","SCT7IN3 ","SCT7IN4 ","SCT7IN5 ","SCT7IN6 ","SCT7IN7 ","SCT7IN8 ","SCT7IN9 ", & - "SCT7OT1 ","SCT7OT2 ","SCT7OT3 ","SCT7OT4 ","SCT7OT5 ","SCT7OT6 ","SCT7OT7 ","SCT7OT8 ", & - "SCT7OT9 ","SCT8IN1 ","SCT8IN2 ","SCT8IN3 ","SCT8IN4 ","SCT8IN5 ","SCT8IN6 ","SCT8IN7 ", & - "SCT8IN8 ","SCT8IN9 ","SCT8OT1 ","SCT8OT2 ","SCT8OT3 ","SCT8OT4 ","SCT8OT5 ","SCT8OT6 ", & - "SCT8OT7 ","SCT8OT8 ","SCT8OT9 ","SCT9IN1 ","SCT9IN2 ","SCT9IN3 ","SCT9IN4 ","SCT9IN5 ", & - "SCT9IN6 ","SCT9IN7 ","SCT9IN8 ","SCT9IN9 ","SCT9OT1 ","SCT9OT2 ","SCT9OT3 ","SCT9OT4 ", & - "SCT9OT5 ","SCT9OT6 ","SCT9OT7 ","SCT9OT8 ","SCT9OT9 ","TIAMBT1 ","TIAMBT2 ","TIAMBT3 ", & - "TIAMBT4 ","TIAMBT5 ","TIAMBT6 ","TIAMBT7 ","TIAMBT8 ","TIAMBT9 ","W1VAMBX ","W1VAMBY ", & - "W1VAMBZ ","W1VDISX ","W1VDISY ","W1VDISZ ","W2VAMBX ","W2VAMBY ","W2VAMBZ ","W2VDISX ", & - "W2VDISY ","W2VDISZ ","W3VAMBX ","W3VAMBY ","W3VAMBZ ","W3VDISX ","W3VDISY ","W3VDISZ ", & - "W4VAMBX ","W4VAMBY ","W4VAMBZ ","W4VDISX ","W4VDISY ","W4VDISZ ","W5VAMBX ","W5VAMBY ", & - "W5VAMBZ ","W5VDISX ","W5VDISY ","W5VDISZ ","W6VAMBX ","W6VAMBY ","W6VAMBZ ","W6VDISX ", & - "W6VDISY ","W6VDISZ ","W7VAMBX ","W7VAMBY ","W7VAMBZ ","W7VDISX ","W7VDISY ","W7VDISZ ", & - "W8VAMBX ","W8VAMBY ","W8VAMBZ ","W8VDISX ","W8VDISY ","W8VDISZ ","W9VAMBX ","W9VAMBY ", & - "W9VAMBZ ","W9VDISX ","W9VDISY ","W9VDISZ ","WKAXSXT1D1 ","WKAXSXT1D2 ","WKAXSXT1D3 ","WKAXSXT1D4 ", & - "WKAXSXT1D5 ","WKAXSXT1D6 ","WKAXSXT1D7 ","WKAXSXT1D8 ","WKAXSXT1D9 ","WKAXSXT2D1 ","WKAXSXT2D2 ","WKAXSXT2D3 ", & - "WKAXSXT2D4 ","WKAXSXT2D5 ","WKAXSXT2D6 ","WKAXSXT2D7 ","WKAXSXT2D8 ","WKAXSXT2D9 ","WKAXSXT3D1 ","WKAXSXT3D2 ", & - "WKAXSXT3D3 ","WKAXSXT3D4 ","WKAXSXT3D5 ","WKAXSXT3D6 ","WKAXSXT3D7 ","WKAXSXT3D8 ","WKAXSXT3D9 ","WKAXSXT4D1 ", & - "WKAXSXT4D2 ","WKAXSXT4D3 ","WKAXSXT4D4 ","WKAXSXT4D5 ","WKAXSXT4D6 ","WKAXSXT4D7 ","WKAXSXT4D8 ","WKAXSXT4D9 ", & - "WKAXSXT5D1 ","WKAXSXT5D2 ","WKAXSXT5D3 ","WKAXSXT5D4 ","WKAXSXT5D5 ","WKAXSXT5D6 ","WKAXSXT5D7 ","WKAXSXT5D8 ", & - "WKAXSXT5D9 ","WKAXSXT6D1 ","WKAXSXT6D2 ","WKAXSXT6D3 ","WKAXSXT6D4 ","WKAXSXT6D5 ","WKAXSXT6D6 ","WKAXSXT6D7 ", & - "WKAXSXT6D8 ","WKAXSXT6D9 ","WKAXSXT7D1 ","WKAXSXT7D2 ","WKAXSXT7D3 ","WKAXSXT7D4 ","WKAXSXT7D5 ","WKAXSXT7D6 ", & - "WKAXSXT7D7 ","WKAXSXT7D8 ","WKAXSXT7D9 ","WKAXSXT8D1 ","WKAXSXT8D2 ","WKAXSXT8D3 ","WKAXSXT8D4 ","WKAXSXT8D5 ", & - "WKAXSXT8D6 ","WKAXSXT8D7 ","WKAXSXT8D8 ","WKAXSXT8D9 ","WKAXSXT9D1 ","WKAXSXT9D2 ","WKAXSXT9D3 ","WKAXSXT9D4 ", & - "WKAXSXT9D5 ","WKAXSXT9D6 ","WKAXSXT9D7 ","WKAXSXT9D8 ","WKAXSXT9D9 ","WKAXSYT1D1 ","WKAXSYT1D2 ","WKAXSYT1D3 ", & - "WKAXSYT1D4 ","WKAXSYT1D5 ","WKAXSYT1D6 ","WKAXSYT1D7 ","WKAXSYT1D8 ","WKAXSYT1D9 ","WKAXSYT2D1 ","WKAXSYT2D2 ", & - "WKAXSYT2D3 ","WKAXSYT2D4 ","WKAXSYT2D5 ","WKAXSYT2D6 ","WKAXSYT2D7 ","WKAXSYT2D8 ","WKAXSYT2D9 ","WKAXSYT3D1 ", & - "WKAXSYT3D2 ","WKAXSYT3D3 ","WKAXSYT3D4 ","WKAXSYT3D5 ","WKAXSYT3D6 ","WKAXSYT3D7 ","WKAXSYT3D8 ","WKAXSYT3D9 ", & - "WKAXSYT4D1 ","WKAXSYT4D2 ","WKAXSYT4D3 ","WKAXSYT4D4 ","WKAXSYT4D5 ","WKAXSYT4D6 ","WKAXSYT4D7 ","WKAXSYT4D8 ", & - "WKAXSYT4D9 ","WKAXSYT5D1 ","WKAXSYT5D2 ","WKAXSYT5D3 ","WKAXSYT5D4 ","WKAXSYT5D5 ","WKAXSYT5D6 ","WKAXSYT5D7 ", & - "WKAXSYT5D8 ","WKAXSYT5D9 ","WKAXSYT6D1 ","WKAXSYT6D2 ","WKAXSYT6D3 ","WKAXSYT6D4 ","WKAXSYT6D5 ","WKAXSYT6D6 ", & - "WKAXSYT6D7 ","WKAXSYT6D8 ","WKAXSYT6D9 ","WKAXSYT7D1 ","WKAXSYT7D2 ","WKAXSYT7D3 ","WKAXSYT7D4 ","WKAXSYT7D5 ", & - "WKAXSYT7D6 ","WKAXSYT7D7 ","WKAXSYT7D8 ","WKAXSYT7D9 ","WKAXSYT8D1 ","WKAXSYT8D2 ","WKAXSYT8D3 ","WKAXSYT8D4 ", & - "WKAXSYT8D5 ","WKAXSYT8D6 ","WKAXSYT8D7 ","WKAXSYT8D8 ","WKAXSYT8D9 ","WKAXSYT9D1 ","WKAXSYT9D2 ","WKAXSYT9D3 ", & - "WKAXSYT9D4 ","WKAXSYT9D5 ","WKAXSYT9D6 ","WKAXSYT9D7 ","WKAXSYT9D8 ","WKAXSYT9D9 ","WKAXSZT1D1 ","WKAXSZT1D2 ", & - "WKAXSZT1D3 ","WKAXSZT1D4 ","WKAXSZT1D5 ","WKAXSZT1D6 ","WKAXSZT1D7 ","WKAXSZT1D8 ","WKAXSZT1D9 ","WKAXSZT2D1 ", & - "WKAXSZT2D2 ","WKAXSZT2D3 ","WKAXSZT2D4 ","WKAXSZT2D5 ","WKAXSZT2D6 ","WKAXSZT2D7 ","WKAXSZT2D8 ","WKAXSZT2D9 ", & - "WKAXSZT3D1 ","WKAXSZT3D2 ","WKAXSZT3D3 ","WKAXSZT3D4 ","WKAXSZT3D5 ","WKAXSZT3D6 ","WKAXSZT3D7 ","WKAXSZT3D8 ", & - "WKAXSZT3D9 ","WKAXSZT4D1 ","WKAXSZT4D2 ","WKAXSZT4D3 ","WKAXSZT4D4 ","WKAXSZT4D5 ","WKAXSZT4D6 ","WKAXSZT4D7 ", & - "WKAXSZT4D8 ","WKAXSZT4D9 ","WKAXSZT5D1 ","WKAXSZT5D2 ","WKAXSZT5D3 ","WKAXSZT5D4 ","WKAXSZT5D5 ","WKAXSZT5D6 ", & - "WKAXSZT5D7 ","WKAXSZT5D8 ","WKAXSZT5D9 ","WKAXSZT6D1 ","WKAXSZT6D2 ","WKAXSZT6D3 ","WKAXSZT6D4 ","WKAXSZT6D5 ", & - "WKAXSZT6D6 ","WKAXSZT6D7 ","WKAXSZT6D8 ","WKAXSZT6D9 ","WKAXSZT7D1 ","WKAXSZT7D2 ","WKAXSZT7D3 ","WKAXSZT7D4 ", & - "WKAXSZT7D5 ","WKAXSZT7D6 ","WKAXSZT7D7 ","WKAXSZT7D8 ","WKAXSZT7D9 ","WKAXSZT8D1 ","WKAXSZT8D2 ","WKAXSZT8D3 ", & - "WKAXSZT8D4 ","WKAXSZT8D5 ","WKAXSZT8D6 ","WKAXSZT8D7 ","WKAXSZT8D8 ","WKAXSZT8D9 ","WKAXSZT9D1 ","WKAXSZT9D2 ", & - "WKAXSZT9D3 ","WKAXSZT9D4 ","WKAXSZT9D5 ","WKAXSZT9D6 ","WKAXSZT9D7 ","WKAXSZT9D8 ","WKAXSZT9D9 ","WKDFVRT1N01D1", & - "WKDFVRT1N01D2","WKDFVRT1N01D3","WKDFVRT1N01D4","WKDFVRT1N01D5","WKDFVRT1N01D6","WKDFVRT1N01D7","WKDFVRT1N01D8","WKDFVRT1N01D9", & - "WKDFVRT1N02D1","WKDFVRT1N02D2","WKDFVRT1N02D3","WKDFVRT1N02D4","WKDFVRT1N02D5","WKDFVRT1N02D6","WKDFVRT1N02D7","WKDFVRT1N02D8", & - "WKDFVRT1N02D9","WKDFVRT1N03D1","WKDFVRT1N03D2","WKDFVRT1N03D3","WKDFVRT1N03D4","WKDFVRT1N03D5","WKDFVRT1N03D6","WKDFVRT1N03D7", & - "WKDFVRT1N03D8","WKDFVRT1N03D9","WKDFVRT1N04D1","WKDFVRT1N04D2","WKDFVRT1N04D3","WKDFVRT1N04D4","WKDFVRT1N04D5","WKDFVRT1N04D6", & - "WKDFVRT1N04D7","WKDFVRT1N04D8","WKDFVRT1N04D9","WKDFVRT1N05D1","WKDFVRT1N05D2","WKDFVRT1N05D3","WKDFVRT1N05D4","WKDFVRT1N05D5", & - "WKDFVRT1N05D6","WKDFVRT1N05D7","WKDFVRT1N05D8","WKDFVRT1N05D9","WKDFVRT1N06D1","WKDFVRT1N06D2","WKDFVRT1N06D3","WKDFVRT1N06D4", & - "WKDFVRT1N06D5","WKDFVRT1N06D6","WKDFVRT1N06D7","WKDFVRT1N06D8","WKDFVRT1N06D9","WKDFVRT1N07D1","WKDFVRT1N07D2","WKDFVRT1N07D3", & - "WKDFVRT1N07D4","WKDFVRT1N07D5","WKDFVRT1N07D6","WKDFVRT1N07D7","WKDFVRT1N07D8","WKDFVRT1N07D9","WKDFVRT1N08D1","WKDFVRT1N08D2", & - "WKDFVRT1N08D3","WKDFVRT1N08D4","WKDFVRT1N08D5","WKDFVRT1N08D6","WKDFVRT1N08D7","WKDFVRT1N08D8","WKDFVRT1N08D9","WKDFVRT1N09D1", & - "WKDFVRT1N09D2","WKDFVRT1N09D3","WKDFVRT1N09D4","WKDFVRT1N09D5","WKDFVRT1N09D6","WKDFVRT1N09D7","WKDFVRT1N09D8","WKDFVRT1N09D9", & - "WKDFVRT1N10D1","WKDFVRT1N10D2","WKDFVRT1N10D3","WKDFVRT1N10D4","WKDFVRT1N10D5","WKDFVRT1N10D6","WKDFVRT1N10D7","WKDFVRT1N10D8", & - "WKDFVRT1N10D9","WKDFVRT1N11D1","WKDFVRT1N11D2","WKDFVRT1N11D3","WKDFVRT1N11D4","WKDFVRT1N11D5","WKDFVRT1N11D6","WKDFVRT1N11D7", & - "WKDFVRT1N11D8","WKDFVRT1N11D9","WKDFVRT1N12D1","WKDFVRT1N12D2","WKDFVRT1N12D3","WKDFVRT1N12D4","WKDFVRT1N12D5","WKDFVRT1N12D6", & - "WKDFVRT1N12D7","WKDFVRT1N12D8","WKDFVRT1N12D9","WKDFVRT1N13D1","WKDFVRT1N13D2","WKDFVRT1N13D3","WKDFVRT1N13D4","WKDFVRT1N13D5", & - "WKDFVRT1N13D6","WKDFVRT1N13D7","WKDFVRT1N13D8","WKDFVRT1N13D9","WKDFVRT1N14D1","WKDFVRT1N14D2","WKDFVRT1N14D3","WKDFVRT1N14D4", & - "WKDFVRT1N14D5","WKDFVRT1N14D6","WKDFVRT1N14D7","WKDFVRT1N14D8","WKDFVRT1N14D9","WKDFVRT1N15D1","WKDFVRT1N15D2","WKDFVRT1N15D3", & - "WKDFVRT1N15D4","WKDFVRT1N15D5","WKDFVRT1N15D6","WKDFVRT1N15D7","WKDFVRT1N15D8","WKDFVRT1N15D9","WKDFVRT1N16D1","WKDFVRT1N16D2", & - "WKDFVRT1N16D3","WKDFVRT1N16D4","WKDFVRT1N16D5","WKDFVRT1N16D6","WKDFVRT1N16D7","WKDFVRT1N16D8","WKDFVRT1N16D9","WKDFVRT1N17D1", & - "WKDFVRT1N17D2","WKDFVRT1N17D3","WKDFVRT1N17D4","WKDFVRT1N17D5","WKDFVRT1N17D6","WKDFVRT1N17D7","WKDFVRT1N17D8","WKDFVRT1N17D9", & - "WKDFVRT1N18D1","WKDFVRT1N18D2","WKDFVRT1N18D3","WKDFVRT1N18D4","WKDFVRT1N18D5","WKDFVRT1N18D6","WKDFVRT1N18D7","WKDFVRT1N18D8", & - "WKDFVRT1N18D9","WKDFVRT1N19D1","WKDFVRT1N19D2","WKDFVRT1N19D3","WKDFVRT1N19D4","WKDFVRT1N19D5","WKDFVRT1N19D6","WKDFVRT1N19D7", & - "WKDFVRT1N19D8","WKDFVRT1N19D9","WKDFVRT1N20D1","WKDFVRT1N20D2","WKDFVRT1N20D3","WKDFVRT1N20D4","WKDFVRT1N20D5","WKDFVRT1N20D6", & - "WKDFVRT1N20D7","WKDFVRT1N20D8","WKDFVRT1N20D9","WKDFVRT2N01D1","WKDFVRT2N01D2","WKDFVRT2N01D3","WKDFVRT2N01D4","WKDFVRT2N01D5", & - "WKDFVRT2N01D6","WKDFVRT2N01D7","WKDFVRT2N01D8","WKDFVRT2N01D9","WKDFVRT2N02D1","WKDFVRT2N02D2","WKDFVRT2N02D3","WKDFVRT2N02D4", & - "WKDFVRT2N02D5","WKDFVRT2N02D6","WKDFVRT2N02D7","WKDFVRT2N02D8","WKDFVRT2N02D9","WKDFVRT2N03D1","WKDFVRT2N03D2","WKDFVRT2N03D3", & - "WKDFVRT2N03D4","WKDFVRT2N03D5","WKDFVRT2N03D6","WKDFVRT2N03D7","WKDFVRT2N03D8","WKDFVRT2N03D9","WKDFVRT2N04D1","WKDFVRT2N04D2", & - "WKDFVRT2N04D3","WKDFVRT2N04D4","WKDFVRT2N04D5","WKDFVRT2N04D6","WKDFVRT2N04D7","WKDFVRT2N04D8","WKDFVRT2N04D9","WKDFVRT2N05D1", & - "WKDFVRT2N05D2","WKDFVRT2N05D3","WKDFVRT2N05D4","WKDFVRT2N05D5","WKDFVRT2N05D6","WKDFVRT2N05D7","WKDFVRT2N05D8","WKDFVRT2N05D9", & - "WKDFVRT2N06D1","WKDFVRT2N06D2","WKDFVRT2N06D3","WKDFVRT2N06D4","WKDFVRT2N06D5","WKDFVRT2N06D6","WKDFVRT2N06D7","WKDFVRT2N06D8", & - "WKDFVRT2N06D9","WKDFVRT2N07D1","WKDFVRT2N07D2","WKDFVRT2N07D3","WKDFVRT2N07D4","WKDFVRT2N07D5","WKDFVRT2N07D6","WKDFVRT2N07D7", & - "WKDFVRT2N07D8","WKDFVRT2N07D9","WKDFVRT2N08D1","WKDFVRT2N08D2","WKDFVRT2N08D3","WKDFVRT2N08D4","WKDFVRT2N08D5","WKDFVRT2N08D6", & - "WKDFVRT2N08D7","WKDFVRT2N08D8","WKDFVRT2N08D9","WKDFVRT2N09D1","WKDFVRT2N09D2","WKDFVRT2N09D3","WKDFVRT2N09D4","WKDFVRT2N09D5", & - "WKDFVRT2N09D6","WKDFVRT2N09D7","WKDFVRT2N09D8","WKDFVRT2N09D9","WKDFVRT2N10D1","WKDFVRT2N10D2","WKDFVRT2N10D3","WKDFVRT2N10D4", & - "WKDFVRT2N10D5","WKDFVRT2N10D6","WKDFVRT2N10D7","WKDFVRT2N10D8","WKDFVRT2N10D9","WKDFVRT2N11D1","WKDFVRT2N11D2","WKDFVRT2N11D3", & - "WKDFVRT2N11D4","WKDFVRT2N11D5","WKDFVRT2N11D6","WKDFVRT2N11D7","WKDFVRT2N11D8","WKDFVRT2N11D9","WKDFVRT2N12D1","WKDFVRT2N12D2", & - "WKDFVRT2N12D3","WKDFVRT2N12D4","WKDFVRT2N12D5","WKDFVRT2N12D6","WKDFVRT2N12D7","WKDFVRT2N12D8","WKDFVRT2N12D9","WKDFVRT2N13D1", & - "WKDFVRT2N13D2","WKDFVRT2N13D3","WKDFVRT2N13D4","WKDFVRT2N13D5","WKDFVRT2N13D6","WKDFVRT2N13D7","WKDFVRT2N13D8","WKDFVRT2N13D9", & - "WKDFVRT2N14D1","WKDFVRT2N14D2","WKDFVRT2N14D3","WKDFVRT2N14D4","WKDFVRT2N14D5","WKDFVRT2N14D6","WKDFVRT2N14D7","WKDFVRT2N14D8", & - "WKDFVRT2N14D9","WKDFVRT2N15D1","WKDFVRT2N15D2","WKDFVRT2N15D3","WKDFVRT2N15D4","WKDFVRT2N15D5","WKDFVRT2N15D6","WKDFVRT2N15D7", & - "WKDFVRT2N15D8","WKDFVRT2N15D9","WKDFVRT2N16D1","WKDFVRT2N16D2","WKDFVRT2N16D3","WKDFVRT2N16D4","WKDFVRT2N16D5","WKDFVRT2N16D6", & - "WKDFVRT2N16D7","WKDFVRT2N16D8","WKDFVRT2N16D9","WKDFVRT2N17D1","WKDFVRT2N17D2","WKDFVRT2N17D3","WKDFVRT2N17D4","WKDFVRT2N17D5", & - "WKDFVRT2N17D6","WKDFVRT2N17D7","WKDFVRT2N17D8","WKDFVRT2N17D9","WKDFVRT2N18D1","WKDFVRT2N18D2","WKDFVRT2N18D3","WKDFVRT2N18D4", & - "WKDFVRT2N18D5","WKDFVRT2N18D6","WKDFVRT2N18D7","WKDFVRT2N18D8","WKDFVRT2N18D9","WKDFVRT2N19D1","WKDFVRT2N19D2","WKDFVRT2N19D3", & - "WKDFVRT2N19D4","WKDFVRT2N19D5","WKDFVRT2N19D6","WKDFVRT2N19D7","WKDFVRT2N19D8","WKDFVRT2N19D9","WKDFVRT2N20D1","WKDFVRT2N20D2", & - "WKDFVRT2N20D3","WKDFVRT2N20D4","WKDFVRT2N20D5","WKDFVRT2N20D6","WKDFVRT2N20D7","WKDFVRT2N20D8","WKDFVRT2N20D9","WKDFVRT3N01D1", & - "WKDFVRT3N01D2","WKDFVRT3N01D3","WKDFVRT3N01D4","WKDFVRT3N01D5","WKDFVRT3N01D6","WKDFVRT3N01D7","WKDFVRT3N01D8","WKDFVRT3N01D9", & - "WKDFVRT3N02D1","WKDFVRT3N02D2","WKDFVRT3N02D3","WKDFVRT3N02D4","WKDFVRT3N02D5","WKDFVRT3N02D6","WKDFVRT3N02D7","WKDFVRT3N02D8", & - "WKDFVRT3N02D9","WKDFVRT3N03D1","WKDFVRT3N03D2","WKDFVRT3N03D3","WKDFVRT3N03D4","WKDFVRT3N03D5","WKDFVRT3N03D6","WKDFVRT3N03D7", & - "WKDFVRT3N03D8","WKDFVRT3N03D9","WKDFVRT3N04D1","WKDFVRT3N04D2","WKDFVRT3N04D3","WKDFVRT3N04D4","WKDFVRT3N04D5","WKDFVRT3N04D6", & - "WKDFVRT3N04D7","WKDFVRT3N04D8","WKDFVRT3N04D9","WKDFVRT3N05D1","WKDFVRT3N05D2","WKDFVRT3N05D3","WKDFVRT3N05D4","WKDFVRT3N05D5", & - "WKDFVRT3N05D6","WKDFVRT3N05D7","WKDFVRT3N05D8","WKDFVRT3N05D9","WKDFVRT3N06D1","WKDFVRT3N06D2","WKDFVRT3N06D3","WKDFVRT3N06D4", & - "WKDFVRT3N06D5","WKDFVRT3N06D6","WKDFVRT3N06D7","WKDFVRT3N06D8","WKDFVRT3N06D9","WKDFVRT3N07D1","WKDFVRT3N07D2","WKDFVRT3N07D3", & - "WKDFVRT3N07D4","WKDFVRT3N07D5","WKDFVRT3N07D6","WKDFVRT3N07D7","WKDFVRT3N07D8","WKDFVRT3N07D9","WKDFVRT3N08D1","WKDFVRT3N08D2", & - "WKDFVRT3N08D3","WKDFVRT3N08D4","WKDFVRT3N08D5","WKDFVRT3N08D6","WKDFVRT3N08D7","WKDFVRT3N08D8","WKDFVRT3N08D9","WKDFVRT3N09D1", & - "WKDFVRT3N09D2","WKDFVRT3N09D3","WKDFVRT3N09D4","WKDFVRT3N09D5","WKDFVRT3N09D6","WKDFVRT3N09D7","WKDFVRT3N09D8","WKDFVRT3N09D9", & - "WKDFVRT3N10D1","WKDFVRT3N10D2","WKDFVRT3N10D3","WKDFVRT3N10D4","WKDFVRT3N10D5","WKDFVRT3N10D6","WKDFVRT3N10D7","WKDFVRT3N10D8", & - "WKDFVRT3N10D9","WKDFVRT3N11D1","WKDFVRT3N11D2","WKDFVRT3N11D3","WKDFVRT3N11D4","WKDFVRT3N11D5","WKDFVRT3N11D6","WKDFVRT3N11D7", & - "WKDFVRT3N11D8","WKDFVRT3N11D9","WKDFVRT3N12D1","WKDFVRT3N12D2","WKDFVRT3N12D3","WKDFVRT3N12D4","WKDFVRT3N12D5","WKDFVRT3N12D6", & - "WKDFVRT3N12D7","WKDFVRT3N12D8","WKDFVRT3N12D9","WKDFVRT3N13D1","WKDFVRT3N13D2","WKDFVRT3N13D3","WKDFVRT3N13D4","WKDFVRT3N13D5", & - "WKDFVRT3N13D6","WKDFVRT3N13D7","WKDFVRT3N13D8","WKDFVRT3N13D9","WKDFVRT3N14D1","WKDFVRT3N14D2","WKDFVRT3N14D3","WKDFVRT3N14D4", & - "WKDFVRT3N14D5","WKDFVRT3N14D6","WKDFVRT3N14D7","WKDFVRT3N14D8","WKDFVRT3N14D9","WKDFVRT3N15D1","WKDFVRT3N15D2","WKDFVRT3N15D3", & - "WKDFVRT3N15D4","WKDFVRT3N15D5","WKDFVRT3N15D6","WKDFVRT3N15D7","WKDFVRT3N15D8","WKDFVRT3N15D9","WKDFVRT3N16D1","WKDFVRT3N16D2", & - "WKDFVRT3N16D3","WKDFVRT3N16D4","WKDFVRT3N16D5","WKDFVRT3N16D6","WKDFVRT3N16D7","WKDFVRT3N16D8","WKDFVRT3N16D9","WKDFVRT3N17D1", & - "WKDFVRT3N17D2","WKDFVRT3N17D3","WKDFVRT3N17D4","WKDFVRT3N17D5","WKDFVRT3N17D6","WKDFVRT3N17D7","WKDFVRT3N17D8","WKDFVRT3N17D9"/) - ValidParamAry(6121:8160) = (/ & - "WKDFVRT3N18D1","WKDFVRT3N18D2","WKDFVRT3N18D3","WKDFVRT3N18D4","WKDFVRT3N18D5","WKDFVRT3N18D6","WKDFVRT3N18D7","WKDFVRT3N18D8", & - "WKDFVRT3N18D9","WKDFVRT3N19D1","WKDFVRT3N19D2","WKDFVRT3N19D3","WKDFVRT3N19D4","WKDFVRT3N19D5","WKDFVRT3N19D6","WKDFVRT3N19D7", & - "WKDFVRT3N19D8","WKDFVRT3N19D9","WKDFVRT3N20D1","WKDFVRT3N20D2","WKDFVRT3N20D3","WKDFVRT3N20D4","WKDFVRT3N20D5","WKDFVRT3N20D6", & - "WKDFVRT3N20D7","WKDFVRT3N20D8","WKDFVRT3N20D9","WKDFVRT4N01D1","WKDFVRT4N01D2","WKDFVRT4N01D3","WKDFVRT4N01D4","WKDFVRT4N01D5", & - "WKDFVRT4N01D6","WKDFVRT4N01D7","WKDFVRT4N01D8","WKDFVRT4N01D9","WKDFVRT4N02D1","WKDFVRT4N02D2","WKDFVRT4N02D3","WKDFVRT4N02D4", & - "WKDFVRT4N02D5","WKDFVRT4N02D6","WKDFVRT4N02D7","WKDFVRT4N02D8","WKDFVRT4N02D9","WKDFVRT4N03D1","WKDFVRT4N03D2","WKDFVRT4N03D3", & - "WKDFVRT4N03D4","WKDFVRT4N03D5","WKDFVRT4N03D6","WKDFVRT4N03D7","WKDFVRT4N03D8","WKDFVRT4N03D9","WKDFVRT4N04D1","WKDFVRT4N04D2", & - "WKDFVRT4N04D3","WKDFVRT4N04D4","WKDFVRT4N04D5","WKDFVRT4N04D6","WKDFVRT4N04D7","WKDFVRT4N04D8","WKDFVRT4N04D9","WKDFVRT4N05D1", & - "WKDFVRT4N05D2","WKDFVRT4N05D3","WKDFVRT4N05D4","WKDFVRT4N05D5","WKDFVRT4N05D6","WKDFVRT4N05D7","WKDFVRT4N05D8","WKDFVRT4N05D9", & - "WKDFVRT4N06D1","WKDFVRT4N06D2","WKDFVRT4N06D3","WKDFVRT4N06D4","WKDFVRT4N06D5","WKDFVRT4N06D6","WKDFVRT4N06D7","WKDFVRT4N06D8", & - "WKDFVRT4N06D9","WKDFVRT4N07D1","WKDFVRT4N07D2","WKDFVRT4N07D3","WKDFVRT4N07D4","WKDFVRT4N07D5","WKDFVRT4N07D6","WKDFVRT4N07D7", & - "WKDFVRT4N07D8","WKDFVRT4N07D9","WKDFVRT4N08D1","WKDFVRT4N08D2","WKDFVRT4N08D3","WKDFVRT4N08D4","WKDFVRT4N08D5","WKDFVRT4N08D6", & - "WKDFVRT4N08D7","WKDFVRT4N08D8","WKDFVRT4N08D9","WKDFVRT4N09D1","WKDFVRT4N09D2","WKDFVRT4N09D3","WKDFVRT4N09D4","WKDFVRT4N09D5", & - "WKDFVRT4N09D6","WKDFVRT4N09D7","WKDFVRT4N09D8","WKDFVRT4N09D9","WKDFVRT4N10D1","WKDFVRT4N10D2","WKDFVRT4N10D3","WKDFVRT4N10D4", & - "WKDFVRT4N10D5","WKDFVRT4N10D6","WKDFVRT4N10D7","WKDFVRT4N10D8","WKDFVRT4N10D9","WKDFVRT4N11D1","WKDFVRT4N11D2","WKDFVRT4N11D3", & - "WKDFVRT4N11D4","WKDFVRT4N11D5","WKDFVRT4N11D6","WKDFVRT4N11D7","WKDFVRT4N11D8","WKDFVRT4N11D9","WKDFVRT4N12D1","WKDFVRT4N12D2", & - "WKDFVRT4N12D3","WKDFVRT4N12D4","WKDFVRT4N12D5","WKDFVRT4N12D6","WKDFVRT4N12D7","WKDFVRT4N12D8","WKDFVRT4N12D9","WKDFVRT4N13D1", & - "WKDFVRT4N13D2","WKDFVRT4N13D3","WKDFVRT4N13D4","WKDFVRT4N13D5","WKDFVRT4N13D6","WKDFVRT4N13D7","WKDFVRT4N13D8","WKDFVRT4N13D9", & - "WKDFVRT4N14D1","WKDFVRT4N14D2","WKDFVRT4N14D3","WKDFVRT4N14D4","WKDFVRT4N14D5","WKDFVRT4N14D6","WKDFVRT4N14D7","WKDFVRT4N14D8", & - "WKDFVRT4N14D9","WKDFVRT4N15D1","WKDFVRT4N15D2","WKDFVRT4N15D3","WKDFVRT4N15D4","WKDFVRT4N15D5","WKDFVRT4N15D6","WKDFVRT4N15D7", & - "WKDFVRT4N15D8","WKDFVRT4N15D9","WKDFVRT4N16D1","WKDFVRT4N16D2","WKDFVRT4N16D3","WKDFVRT4N16D4","WKDFVRT4N16D5","WKDFVRT4N16D6", & - "WKDFVRT4N16D7","WKDFVRT4N16D8","WKDFVRT4N16D9","WKDFVRT4N17D1","WKDFVRT4N17D2","WKDFVRT4N17D3","WKDFVRT4N17D4","WKDFVRT4N17D5", & - "WKDFVRT4N17D6","WKDFVRT4N17D7","WKDFVRT4N17D8","WKDFVRT4N17D9","WKDFVRT4N18D1","WKDFVRT4N18D2","WKDFVRT4N18D3","WKDFVRT4N18D4", & - "WKDFVRT4N18D5","WKDFVRT4N18D6","WKDFVRT4N18D7","WKDFVRT4N18D8","WKDFVRT4N18D9","WKDFVRT4N19D1","WKDFVRT4N19D2","WKDFVRT4N19D3", & - "WKDFVRT4N19D4","WKDFVRT4N19D5","WKDFVRT4N19D6","WKDFVRT4N19D7","WKDFVRT4N19D8","WKDFVRT4N19D9","WKDFVRT4N20D1","WKDFVRT4N20D2", & - "WKDFVRT4N20D3","WKDFVRT4N20D4","WKDFVRT4N20D5","WKDFVRT4N20D6","WKDFVRT4N20D7","WKDFVRT4N20D8","WKDFVRT4N20D9","WKDFVRT5N01D1", & - "WKDFVRT5N01D2","WKDFVRT5N01D3","WKDFVRT5N01D4","WKDFVRT5N01D5","WKDFVRT5N01D6","WKDFVRT5N01D7","WKDFVRT5N01D8","WKDFVRT5N01D9", & - "WKDFVRT5N02D1","WKDFVRT5N02D2","WKDFVRT5N02D3","WKDFVRT5N02D4","WKDFVRT5N02D5","WKDFVRT5N02D6","WKDFVRT5N02D7","WKDFVRT5N02D8", & - "WKDFVRT5N02D9","WKDFVRT5N03D1","WKDFVRT5N03D2","WKDFVRT5N03D3","WKDFVRT5N03D4","WKDFVRT5N03D5","WKDFVRT5N03D6","WKDFVRT5N03D7", & - "WKDFVRT5N03D8","WKDFVRT5N03D9","WKDFVRT5N04D1","WKDFVRT5N04D2","WKDFVRT5N04D3","WKDFVRT5N04D4","WKDFVRT5N04D5","WKDFVRT5N04D6", & - "WKDFVRT5N04D7","WKDFVRT5N04D8","WKDFVRT5N04D9","WKDFVRT5N05D1","WKDFVRT5N05D2","WKDFVRT5N05D3","WKDFVRT5N05D4","WKDFVRT5N05D5", & - "WKDFVRT5N05D6","WKDFVRT5N05D7","WKDFVRT5N05D8","WKDFVRT5N05D9","WKDFVRT5N06D1","WKDFVRT5N06D2","WKDFVRT5N06D3","WKDFVRT5N06D4", & - "WKDFVRT5N06D5","WKDFVRT5N06D6","WKDFVRT5N06D7","WKDFVRT5N06D8","WKDFVRT5N06D9","WKDFVRT5N07D1","WKDFVRT5N07D2","WKDFVRT5N07D3", & - "WKDFVRT5N07D4","WKDFVRT5N07D5","WKDFVRT5N07D6","WKDFVRT5N07D7","WKDFVRT5N07D8","WKDFVRT5N07D9","WKDFVRT5N08D1","WKDFVRT5N08D2", & - "WKDFVRT5N08D3","WKDFVRT5N08D4","WKDFVRT5N08D5","WKDFVRT5N08D6","WKDFVRT5N08D7","WKDFVRT5N08D8","WKDFVRT5N08D9","WKDFVRT5N09D1", & - "WKDFVRT5N09D2","WKDFVRT5N09D3","WKDFVRT5N09D4","WKDFVRT5N09D5","WKDFVRT5N09D6","WKDFVRT5N09D7","WKDFVRT5N09D8","WKDFVRT5N09D9", & - "WKDFVRT5N10D1","WKDFVRT5N10D2","WKDFVRT5N10D3","WKDFVRT5N10D4","WKDFVRT5N10D5","WKDFVRT5N10D6","WKDFVRT5N10D7","WKDFVRT5N10D8", & - "WKDFVRT5N10D9","WKDFVRT5N11D1","WKDFVRT5N11D2","WKDFVRT5N11D3","WKDFVRT5N11D4","WKDFVRT5N11D5","WKDFVRT5N11D6","WKDFVRT5N11D7", & - "WKDFVRT5N11D8","WKDFVRT5N11D9","WKDFVRT5N12D1","WKDFVRT5N12D2","WKDFVRT5N12D3","WKDFVRT5N12D4","WKDFVRT5N12D5","WKDFVRT5N12D6", & - "WKDFVRT5N12D7","WKDFVRT5N12D8","WKDFVRT5N12D9","WKDFVRT5N13D1","WKDFVRT5N13D2","WKDFVRT5N13D3","WKDFVRT5N13D4","WKDFVRT5N13D5", & - "WKDFVRT5N13D6","WKDFVRT5N13D7","WKDFVRT5N13D8","WKDFVRT5N13D9","WKDFVRT5N14D1","WKDFVRT5N14D2","WKDFVRT5N14D3","WKDFVRT5N14D4", & - "WKDFVRT5N14D5","WKDFVRT5N14D6","WKDFVRT5N14D7","WKDFVRT5N14D8","WKDFVRT5N14D9","WKDFVRT5N15D1","WKDFVRT5N15D2","WKDFVRT5N15D3", & - "WKDFVRT5N15D4","WKDFVRT5N15D5","WKDFVRT5N15D6","WKDFVRT5N15D7","WKDFVRT5N15D8","WKDFVRT5N15D9","WKDFVRT5N16D1","WKDFVRT5N16D2", & - "WKDFVRT5N16D3","WKDFVRT5N16D4","WKDFVRT5N16D5","WKDFVRT5N16D6","WKDFVRT5N16D7","WKDFVRT5N16D8","WKDFVRT5N16D9","WKDFVRT5N17D1", & - "WKDFVRT5N17D2","WKDFVRT5N17D3","WKDFVRT5N17D4","WKDFVRT5N17D5","WKDFVRT5N17D6","WKDFVRT5N17D7","WKDFVRT5N17D8","WKDFVRT5N17D9", & - "WKDFVRT5N18D1","WKDFVRT5N18D2","WKDFVRT5N18D3","WKDFVRT5N18D4","WKDFVRT5N18D5","WKDFVRT5N18D6","WKDFVRT5N18D7","WKDFVRT5N18D8", & - "WKDFVRT5N18D9","WKDFVRT5N19D1","WKDFVRT5N19D2","WKDFVRT5N19D3","WKDFVRT5N19D4","WKDFVRT5N19D5","WKDFVRT5N19D6","WKDFVRT5N19D7", & - "WKDFVRT5N19D8","WKDFVRT5N19D9","WKDFVRT5N20D1","WKDFVRT5N20D2","WKDFVRT5N20D3","WKDFVRT5N20D4","WKDFVRT5N20D5","WKDFVRT5N20D6", & - "WKDFVRT5N20D7","WKDFVRT5N20D8","WKDFVRT5N20D9","WKDFVRT6N01D1","WKDFVRT6N01D2","WKDFVRT6N01D3","WKDFVRT6N01D4","WKDFVRT6N01D5", & - "WKDFVRT6N01D6","WKDFVRT6N01D7","WKDFVRT6N01D8","WKDFVRT6N01D9","WKDFVRT6N02D1","WKDFVRT6N02D2","WKDFVRT6N02D3","WKDFVRT6N02D4", & - "WKDFVRT6N02D5","WKDFVRT6N02D6","WKDFVRT6N02D7","WKDFVRT6N02D8","WKDFVRT6N02D9","WKDFVRT6N03D1","WKDFVRT6N03D2","WKDFVRT6N03D3", & - "WKDFVRT6N03D4","WKDFVRT6N03D5","WKDFVRT6N03D6","WKDFVRT6N03D7","WKDFVRT6N03D8","WKDFVRT6N03D9","WKDFVRT6N04D1","WKDFVRT6N04D2", & - "WKDFVRT6N04D3","WKDFVRT6N04D4","WKDFVRT6N04D5","WKDFVRT6N04D6","WKDFVRT6N04D7","WKDFVRT6N04D8","WKDFVRT6N04D9","WKDFVRT6N05D1", & - "WKDFVRT6N05D2","WKDFVRT6N05D3","WKDFVRT6N05D4","WKDFVRT6N05D5","WKDFVRT6N05D6","WKDFVRT6N05D7","WKDFVRT6N05D8","WKDFVRT6N05D9", & - "WKDFVRT6N06D1","WKDFVRT6N06D2","WKDFVRT6N06D3","WKDFVRT6N06D4","WKDFVRT6N06D5","WKDFVRT6N06D6","WKDFVRT6N06D7","WKDFVRT6N06D8", & - "WKDFVRT6N06D9","WKDFVRT6N07D1","WKDFVRT6N07D2","WKDFVRT6N07D3","WKDFVRT6N07D4","WKDFVRT6N07D5","WKDFVRT6N07D6","WKDFVRT6N07D7", & - "WKDFVRT6N07D8","WKDFVRT6N07D9","WKDFVRT6N08D1","WKDFVRT6N08D2","WKDFVRT6N08D3","WKDFVRT6N08D4","WKDFVRT6N08D5","WKDFVRT6N08D6", & - "WKDFVRT6N08D7","WKDFVRT6N08D8","WKDFVRT6N08D9","WKDFVRT6N09D1","WKDFVRT6N09D2","WKDFVRT6N09D3","WKDFVRT6N09D4","WKDFVRT6N09D5", & - "WKDFVRT6N09D6","WKDFVRT6N09D7","WKDFVRT6N09D8","WKDFVRT6N09D9","WKDFVRT6N10D1","WKDFVRT6N10D2","WKDFVRT6N10D3","WKDFVRT6N10D4", & - "WKDFVRT6N10D5","WKDFVRT6N10D6","WKDFVRT6N10D7","WKDFVRT6N10D8","WKDFVRT6N10D9","WKDFVRT6N11D1","WKDFVRT6N11D2","WKDFVRT6N11D3", & - "WKDFVRT6N11D4","WKDFVRT6N11D5","WKDFVRT6N11D6","WKDFVRT6N11D7","WKDFVRT6N11D8","WKDFVRT6N11D9","WKDFVRT6N12D1","WKDFVRT6N12D2", & - "WKDFVRT6N12D3","WKDFVRT6N12D4","WKDFVRT6N12D5","WKDFVRT6N12D6","WKDFVRT6N12D7","WKDFVRT6N12D8","WKDFVRT6N12D9","WKDFVRT6N13D1", & - "WKDFVRT6N13D2","WKDFVRT6N13D3","WKDFVRT6N13D4","WKDFVRT6N13D5","WKDFVRT6N13D6","WKDFVRT6N13D7","WKDFVRT6N13D8","WKDFVRT6N13D9", & - "WKDFVRT6N14D1","WKDFVRT6N14D2","WKDFVRT6N14D3","WKDFVRT6N14D4","WKDFVRT6N14D5","WKDFVRT6N14D6","WKDFVRT6N14D7","WKDFVRT6N14D8", & - "WKDFVRT6N14D9","WKDFVRT6N15D1","WKDFVRT6N15D2","WKDFVRT6N15D3","WKDFVRT6N15D4","WKDFVRT6N15D5","WKDFVRT6N15D6","WKDFVRT6N15D7", & - "WKDFVRT6N15D8","WKDFVRT6N15D9","WKDFVRT6N16D1","WKDFVRT6N16D2","WKDFVRT6N16D3","WKDFVRT6N16D4","WKDFVRT6N16D5","WKDFVRT6N16D6", & - "WKDFVRT6N16D7","WKDFVRT6N16D8","WKDFVRT6N16D9","WKDFVRT6N17D1","WKDFVRT6N17D2","WKDFVRT6N17D3","WKDFVRT6N17D4","WKDFVRT6N17D5", & - "WKDFVRT6N17D6","WKDFVRT6N17D7","WKDFVRT6N17D8","WKDFVRT6N17D9","WKDFVRT6N18D1","WKDFVRT6N18D2","WKDFVRT6N18D3","WKDFVRT6N18D4", & - "WKDFVRT6N18D5","WKDFVRT6N18D6","WKDFVRT6N18D7","WKDFVRT6N18D8","WKDFVRT6N18D9","WKDFVRT6N19D1","WKDFVRT6N19D2","WKDFVRT6N19D3", & - "WKDFVRT6N19D4","WKDFVRT6N19D5","WKDFVRT6N19D6","WKDFVRT6N19D7","WKDFVRT6N19D8","WKDFVRT6N19D9","WKDFVRT6N20D1","WKDFVRT6N20D2", & - "WKDFVRT6N20D3","WKDFVRT6N20D4","WKDFVRT6N20D5","WKDFVRT6N20D6","WKDFVRT6N20D7","WKDFVRT6N20D8","WKDFVRT6N20D9","WKDFVRT7N01D1", & - "WKDFVRT7N01D2","WKDFVRT7N01D3","WKDFVRT7N01D4","WKDFVRT7N01D5","WKDFVRT7N01D6","WKDFVRT7N01D7","WKDFVRT7N01D8","WKDFVRT7N01D9", & - "WKDFVRT7N02D1","WKDFVRT7N02D2","WKDFVRT7N02D3","WKDFVRT7N02D4","WKDFVRT7N02D5","WKDFVRT7N02D6","WKDFVRT7N02D7","WKDFVRT7N02D8", & - "WKDFVRT7N02D9","WKDFVRT7N03D1","WKDFVRT7N03D2","WKDFVRT7N03D3","WKDFVRT7N03D4","WKDFVRT7N03D5","WKDFVRT7N03D6","WKDFVRT7N03D7", & - "WKDFVRT7N03D8","WKDFVRT7N03D9","WKDFVRT7N04D1","WKDFVRT7N04D2","WKDFVRT7N04D3","WKDFVRT7N04D4","WKDFVRT7N04D5","WKDFVRT7N04D6", & - "WKDFVRT7N04D7","WKDFVRT7N04D8","WKDFVRT7N04D9","WKDFVRT7N05D1","WKDFVRT7N05D2","WKDFVRT7N05D3","WKDFVRT7N05D4","WKDFVRT7N05D5", & - "WKDFVRT7N05D6","WKDFVRT7N05D7","WKDFVRT7N05D8","WKDFVRT7N05D9","WKDFVRT7N06D1","WKDFVRT7N06D2","WKDFVRT7N06D3","WKDFVRT7N06D4", & - "WKDFVRT7N06D5","WKDFVRT7N06D6","WKDFVRT7N06D7","WKDFVRT7N06D8","WKDFVRT7N06D9","WKDFVRT7N07D1","WKDFVRT7N07D2","WKDFVRT7N07D3", & - "WKDFVRT7N07D4","WKDFVRT7N07D5","WKDFVRT7N07D6","WKDFVRT7N07D7","WKDFVRT7N07D8","WKDFVRT7N07D9","WKDFVRT7N08D1","WKDFVRT7N08D2", & - "WKDFVRT7N08D3","WKDFVRT7N08D4","WKDFVRT7N08D5","WKDFVRT7N08D6","WKDFVRT7N08D7","WKDFVRT7N08D8","WKDFVRT7N08D9","WKDFVRT7N09D1", & - "WKDFVRT7N09D2","WKDFVRT7N09D3","WKDFVRT7N09D4","WKDFVRT7N09D5","WKDFVRT7N09D6","WKDFVRT7N09D7","WKDFVRT7N09D8","WKDFVRT7N09D9", & - "WKDFVRT7N10D1","WKDFVRT7N10D2","WKDFVRT7N10D3","WKDFVRT7N10D4","WKDFVRT7N10D5","WKDFVRT7N10D6","WKDFVRT7N10D7","WKDFVRT7N10D8", & - "WKDFVRT7N10D9","WKDFVRT7N11D1","WKDFVRT7N11D2","WKDFVRT7N11D3","WKDFVRT7N11D4","WKDFVRT7N11D5","WKDFVRT7N11D6","WKDFVRT7N11D7", & - "WKDFVRT7N11D8","WKDFVRT7N11D9","WKDFVRT7N12D1","WKDFVRT7N12D2","WKDFVRT7N12D3","WKDFVRT7N12D4","WKDFVRT7N12D5","WKDFVRT7N12D6", & - "WKDFVRT7N12D7","WKDFVRT7N12D8","WKDFVRT7N12D9","WKDFVRT7N13D1","WKDFVRT7N13D2","WKDFVRT7N13D3","WKDFVRT7N13D4","WKDFVRT7N13D5", & - "WKDFVRT7N13D6","WKDFVRT7N13D7","WKDFVRT7N13D8","WKDFVRT7N13D9","WKDFVRT7N14D1","WKDFVRT7N14D2","WKDFVRT7N14D3","WKDFVRT7N14D4", & - "WKDFVRT7N14D5","WKDFVRT7N14D6","WKDFVRT7N14D7","WKDFVRT7N14D8","WKDFVRT7N14D9","WKDFVRT7N15D1","WKDFVRT7N15D2","WKDFVRT7N15D3", & - "WKDFVRT7N15D4","WKDFVRT7N15D5","WKDFVRT7N15D6","WKDFVRT7N15D7","WKDFVRT7N15D8","WKDFVRT7N15D9","WKDFVRT7N16D1","WKDFVRT7N16D2", & - "WKDFVRT7N16D3","WKDFVRT7N16D4","WKDFVRT7N16D5","WKDFVRT7N16D6","WKDFVRT7N16D7","WKDFVRT7N16D8","WKDFVRT7N16D9","WKDFVRT7N17D1", & - "WKDFVRT7N17D2","WKDFVRT7N17D3","WKDFVRT7N17D4","WKDFVRT7N17D5","WKDFVRT7N17D6","WKDFVRT7N17D7","WKDFVRT7N17D8","WKDFVRT7N17D9", & - "WKDFVRT7N18D1","WKDFVRT7N18D2","WKDFVRT7N18D3","WKDFVRT7N18D4","WKDFVRT7N18D5","WKDFVRT7N18D6","WKDFVRT7N18D7","WKDFVRT7N18D8", & - "WKDFVRT7N18D9","WKDFVRT7N19D1","WKDFVRT7N19D2","WKDFVRT7N19D3","WKDFVRT7N19D4","WKDFVRT7N19D5","WKDFVRT7N19D6","WKDFVRT7N19D7", & - "WKDFVRT7N19D8","WKDFVRT7N19D9","WKDFVRT7N20D1","WKDFVRT7N20D2","WKDFVRT7N20D3","WKDFVRT7N20D4","WKDFVRT7N20D5","WKDFVRT7N20D6", & - "WKDFVRT7N20D7","WKDFVRT7N20D8","WKDFVRT7N20D9","WKDFVRT8N01D1","WKDFVRT8N01D2","WKDFVRT8N01D3","WKDFVRT8N01D4","WKDFVRT8N01D5", & - "WKDFVRT8N01D6","WKDFVRT8N01D7","WKDFVRT8N01D8","WKDFVRT8N01D9","WKDFVRT8N02D1","WKDFVRT8N02D2","WKDFVRT8N02D3","WKDFVRT8N02D4", & - "WKDFVRT8N02D5","WKDFVRT8N02D6","WKDFVRT8N02D7","WKDFVRT8N02D8","WKDFVRT8N02D9","WKDFVRT8N03D1","WKDFVRT8N03D2","WKDFVRT8N03D3", & - "WKDFVRT8N03D4","WKDFVRT8N03D5","WKDFVRT8N03D6","WKDFVRT8N03D7","WKDFVRT8N03D8","WKDFVRT8N03D9","WKDFVRT8N04D1","WKDFVRT8N04D2", & - "WKDFVRT8N04D3","WKDFVRT8N04D4","WKDFVRT8N04D5","WKDFVRT8N04D6","WKDFVRT8N04D7","WKDFVRT8N04D8","WKDFVRT8N04D9","WKDFVRT8N05D1", & - "WKDFVRT8N05D2","WKDFVRT8N05D3","WKDFVRT8N05D4","WKDFVRT8N05D5","WKDFVRT8N05D6","WKDFVRT8N05D7","WKDFVRT8N05D8","WKDFVRT8N05D9", & - "WKDFVRT8N06D1","WKDFVRT8N06D2","WKDFVRT8N06D3","WKDFVRT8N06D4","WKDFVRT8N06D5","WKDFVRT8N06D6","WKDFVRT8N06D7","WKDFVRT8N06D8", & - "WKDFVRT8N06D9","WKDFVRT8N07D1","WKDFVRT8N07D2","WKDFVRT8N07D3","WKDFVRT8N07D4","WKDFVRT8N07D5","WKDFVRT8N07D6","WKDFVRT8N07D7", & - "WKDFVRT8N07D8","WKDFVRT8N07D9","WKDFVRT8N08D1","WKDFVRT8N08D2","WKDFVRT8N08D3","WKDFVRT8N08D4","WKDFVRT8N08D5","WKDFVRT8N08D6", & - "WKDFVRT8N08D7","WKDFVRT8N08D8","WKDFVRT8N08D9","WKDFVRT8N09D1","WKDFVRT8N09D2","WKDFVRT8N09D3","WKDFVRT8N09D4","WKDFVRT8N09D5", & - "WKDFVRT8N09D6","WKDFVRT8N09D7","WKDFVRT8N09D8","WKDFVRT8N09D9","WKDFVRT8N10D1","WKDFVRT8N10D2","WKDFVRT8N10D3","WKDFVRT8N10D4", & - "WKDFVRT8N10D5","WKDFVRT8N10D6","WKDFVRT8N10D7","WKDFVRT8N10D8","WKDFVRT8N10D9","WKDFVRT8N11D1","WKDFVRT8N11D2","WKDFVRT8N11D3", & - "WKDFVRT8N11D4","WKDFVRT8N11D5","WKDFVRT8N11D6","WKDFVRT8N11D7","WKDFVRT8N11D8","WKDFVRT8N11D9","WKDFVRT8N12D1","WKDFVRT8N12D2", & - "WKDFVRT8N12D3","WKDFVRT8N12D4","WKDFVRT8N12D5","WKDFVRT8N12D6","WKDFVRT8N12D7","WKDFVRT8N12D8","WKDFVRT8N12D9","WKDFVRT8N13D1", & - "WKDFVRT8N13D2","WKDFVRT8N13D3","WKDFVRT8N13D4","WKDFVRT8N13D5","WKDFVRT8N13D6","WKDFVRT8N13D7","WKDFVRT8N13D8","WKDFVRT8N13D9", & - "WKDFVRT8N14D1","WKDFVRT8N14D2","WKDFVRT8N14D3","WKDFVRT8N14D4","WKDFVRT8N14D5","WKDFVRT8N14D6","WKDFVRT8N14D7","WKDFVRT8N14D8", & - "WKDFVRT8N14D9","WKDFVRT8N15D1","WKDFVRT8N15D2","WKDFVRT8N15D3","WKDFVRT8N15D4","WKDFVRT8N15D5","WKDFVRT8N15D6","WKDFVRT8N15D7", & - "WKDFVRT8N15D8","WKDFVRT8N15D9","WKDFVRT8N16D1","WKDFVRT8N16D2","WKDFVRT8N16D3","WKDFVRT8N16D4","WKDFVRT8N16D5","WKDFVRT8N16D6", & - "WKDFVRT8N16D7","WKDFVRT8N16D8","WKDFVRT8N16D9","WKDFVRT8N17D1","WKDFVRT8N17D2","WKDFVRT8N17D3","WKDFVRT8N17D4","WKDFVRT8N17D5", & - "WKDFVRT8N17D6","WKDFVRT8N17D7","WKDFVRT8N17D8","WKDFVRT8N17D9","WKDFVRT8N18D1","WKDFVRT8N18D2","WKDFVRT8N18D3","WKDFVRT8N18D4", & - "WKDFVRT8N18D5","WKDFVRT8N18D6","WKDFVRT8N18D7","WKDFVRT8N18D8","WKDFVRT8N18D9","WKDFVRT8N19D1","WKDFVRT8N19D2","WKDFVRT8N19D3", & - "WKDFVRT8N19D4","WKDFVRT8N19D5","WKDFVRT8N19D6","WKDFVRT8N19D7","WKDFVRT8N19D8","WKDFVRT8N19D9","WKDFVRT8N20D1","WKDFVRT8N20D2", & - "WKDFVRT8N20D3","WKDFVRT8N20D4","WKDFVRT8N20D5","WKDFVRT8N20D6","WKDFVRT8N20D7","WKDFVRT8N20D8","WKDFVRT8N20D9","WKDFVRT9N01D1", & - "WKDFVRT9N01D2","WKDFVRT9N01D3","WKDFVRT9N01D4","WKDFVRT9N01D5","WKDFVRT9N01D6","WKDFVRT9N01D7","WKDFVRT9N01D8","WKDFVRT9N01D9", & - "WKDFVRT9N02D1","WKDFVRT9N02D2","WKDFVRT9N02D3","WKDFVRT9N02D4","WKDFVRT9N02D5","WKDFVRT9N02D6","WKDFVRT9N02D7","WKDFVRT9N02D8", & - "WKDFVRT9N02D9","WKDFVRT9N03D1","WKDFVRT9N03D2","WKDFVRT9N03D3","WKDFVRT9N03D4","WKDFVRT9N03D5","WKDFVRT9N03D6","WKDFVRT9N03D7", & - "WKDFVRT9N03D8","WKDFVRT9N03D9","WKDFVRT9N04D1","WKDFVRT9N04D2","WKDFVRT9N04D3","WKDFVRT9N04D4","WKDFVRT9N04D5","WKDFVRT9N04D6", & - "WKDFVRT9N04D7","WKDFVRT9N04D8","WKDFVRT9N04D9","WKDFVRT9N05D1","WKDFVRT9N05D2","WKDFVRT9N05D3","WKDFVRT9N05D4","WKDFVRT9N05D5", & - "WKDFVRT9N05D6","WKDFVRT9N05D7","WKDFVRT9N05D8","WKDFVRT9N05D9","WKDFVRT9N06D1","WKDFVRT9N06D2","WKDFVRT9N06D3","WKDFVRT9N06D4", & - "WKDFVRT9N06D5","WKDFVRT9N06D6","WKDFVRT9N06D7","WKDFVRT9N06D8","WKDFVRT9N06D9","WKDFVRT9N07D1","WKDFVRT9N07D2","WKDFVRT9N07D3", & - "WKDFVRT9N07D4","WKDFVRT9N07D5","WKDFVRT9N07D6","WKDFVRT9N07D7","WKDFVRT9N07D8","WKDFVRT9N07D9","WKDFVRT9N08D1","WKDFVRT9N08D2", & - "WKDFVRT9N08D3","WKDFVRT9N08D4","WKDFVRT9N08D5","WKDFVRT9N08D6","WKDFVRT9N08D7","WKDFVRT9N08D8","WKDFVRT9N08D9","WKDFVRT9N09D1", & - "WKDFVRT9N09D2","WKDFVRT9N09D3","WKDFVRT9N09D4","WKDFVRT9N09D5","WKDFVRT9N09D6","WKDFVRT9N09D7","WKDFVRT9N09D8","WKDFVRT9N09D9", & - "WKDFVRT9N10D1","WKDFVRT9N10D2","WKDFVRT9N10D3","WKDFVRT9N10D4","WKDFVRT9N10D5","WKDFVRT9N10D6","WKDFVRT9N10D7","WKDFVRT9N10D8", & - "WKDFVRT9N10D9","WKDFVRT9N11D1","WKDFVRT9N11D2","WKDFVRT9N11D3","WKDFVRT9N11D4","WKDFVRT9N11D5","WKDFVRT9N11D6","WKDFVRT9N11D7", & - "WKDFVRT9N11D8","WKDFVRT9N11D9","WKDFVRT9N12D1","WKDFVRT9N12D2","WKDFVRT9N12D3","WKDFVRT9N12D4","WKDFVRT9N12D5","WKDFVRT9N12D6", & - "WKDFVRT9N12D7","WKDFVRT9N12D8","WKDFVRT9N12D9","WKDFVRT9N13D1","WKDFVRT9N13D2","WKDFVRT9N13D3","WKDFVRT9N13D4","WKDFVRT9N13D5", & - "WKDFVRT9N13D6","WKDFVRT9N13D7","WKDFVRT9N13D8","WKDFVRT9N13D9","WKDFVRT9N14D1","WKDFVRT9N14D2","WKDFVRT9N14D3","WKDFVRT9N14D4", & - "WKDFVRT9N14D5","WKDFVRT9N14D6","WKDFVRT9N14D7","WKDFVRT9N14D8","WKDFVRT9N14D9","WKDFVRT9N15D1","WKDFVRT9N15D2","WKDFVRT9N15D3", & - "WKDFVRT9N15D4","WKDFVRT9N15D5","WKDFVRT9N15D6","WKDFVRT9N15D7","WKDFVRT9N15D8","WKDFVRT9N15D9","WKDFVRT9N16D1","WKDFVRT9N16D2", & - "WKDFVRT9N16D3","WKDFVRT9N16D4","WKDFVRT9N16D5","WKDFVRT9N16D6","WKDFVRT9N16D7","WKDFVRT9N16D8","WKDFVRT9N16D9","WKDFVRT9N17D1", & - "WKDFVRT9N17D2","WKDFVRT9N17D3","WKDFVRT9N17D4","WKDFVRT9N17D5","WKDFVRT9N17D6","WKDFVRT9N17D7","WKDFVRT9N17D8","WKDFVRT9N17D9", & - "WKDFVRT9N18D1","WKDFVRT9N18D2","WKDFVRT9N18D3","WKDFVRT9N18D4","WKDFVRT9N18D5","WKDFVRT9N18D6","WKDFVRT9N18D7","WKDFVRT9N18D8", & - "WKDFVRT9N18D9","WKDFVRT9N19D1","WKDFVRT9N19D2","WKDFVRT9N19D3","WKDFVRT9N19D4","WKDFVRT9N19D5","WKDFVRT9N19D6","WKDFVRT9N19D7", & - "WKDFVRT9N19D8","WKDFVRT9N19D9","WKDFVRT9N20D1","WKDFVRT9N20D2","WKDFVRT9N20D3","WKDFVRT9N20D4","WKDFVRT9N20D5","WKDFVRT9N20D6", & - "WKDFVRT9N20D7","WKDFVRT9N20D8","WKDFVRT9N20D9","WKDFVXT1N01D1","WKDFVXT1N01D2","WKDFVXT1N01D3","WKDFVXT1N01D4","WKDFVXT1N01D5", & - "WKDFVXT1N01D6","WKDFVXT1N01D7","WKDFVXT1N01D8","WKDFVXT1N01D9","WKDFVXT1N02D1","WKDFVXT1N02D2","WKDFVXT1N02D3","WKDFVXT1N02D4", & - "WKDFVXT1N02D5","WKDFVXT1N02D6","WKDFVXT1N02D7","WKDFVXT1N02D8","WKDFVXT1N02D9","WKDFVXT1N03D1","WKDFVXT1N03D2","WKDFVXT1N03D3", & - "WKDFVXT1N03D4","WKDFVXT1N03D5","WKDFVXT1N03D6","WKDFVXT1N03D7","WKDFVXT1N03D8","WKDFVXT1N03D9","WKDFVXT1N04D1","WKDFVXT1N04D2", & - "WKDFVXT1N04D3","WKDFVXT1N04D4","WKDFVXT1N04D5","WKDFVXT1N04D6","WKDFVXT1N04D7","WKDFVXT1N04D8","WKDFVXT1N04D9","WKDFVXT1N05D1", & - "WKDFVXT1N05D2","WKDFVXT1N05D3","WKDFVXT1N05D4","WKDFVXT1N05D5","WKDFVXT1N05D6","WKDFVXT1N05D7","WKDFVXT1N05D8","WKDFVXT1N05D9", & - "WKDFVXT1N06D1","WKDFVXT1N06D2","WKDFVXT1N06D3","WKDFVXT1N06D4","WKDFVXT1N06D5","WKDFVXT1N06D6","WKDFVXT1N06D7","WKDFVXT1N06D8", & - "WKDFVXT1N06D9","WKDFVXT1N07D1","WKDFVXT1N07D2","WKDFVXT1N07D3","WKDFVXT1N07D4","WKDFVXT1N07D5","WKDFVXT1N07D6","WKDFVXT1N07D7", & - "WKDFVXT1N07D8","WKDFVXT1N07D9","WKDFVXT1N08D1","WKDFVXT1N08D2","WKDFVXT1N08D3","WKDFVXT1N08D4","WKDFVXT1N08D5","WKDFVXT1N08D6", & - "WKDFVXT1N08D7","WKDFVXT1N08D8","WKDFVXT1N08D9","WKDFVXT1N09D1","WKDFVXT1N09D2","WKDFVXT1N09D3","WKDFVXT1N09D4","WKDFVXT1N09D5", & - "WKDFVXT1N09D6","WKDFVXT1N09D7","WKDFVXT1N09D8","WKDFVXT1N09D9","WKDFVXT1N10D1","WKDFVXT1N10D2","WKDFVXT1N10D3","WKDFVXT1N10D4", & - "WKDFVXT1N10D5","WKDFVXT1N10D6","WKDFVXT1N10D7","WKDFVXT1N10D8","WKDFVXT1N10D9","WKDFVXT1N11D1","WKDFVXT1N11D2","WKDFVXT1N11D3", & - "WKDFVXT1N11D4","WKDFVXT1N11D5","WKDFVXT1N11D6","WKDFVXT1N11D7","WKDFVXT1N11D8","WKDFVXT1N11D9","WKDFVXT1N12D1","WKDFVXT1N12D2", & - "WKDFVXT1N12D3","WKDFVXT1N12D4","WKDFVXT1N12D5","WKDFVXT1N12D6","WKDFVXT1N12D7","WKDFVXT1N12D8","WKDFVXT1N12D9","WKDFVXT1N13D1", & - "WKDFVXT1N13D2","WKDFVXT1N13D3","WKDFVXT1N13D4","WKDFVXT1N13D5","WKDFVXT1N13D6","WKDFVXT1N13D7","WKDFVXT1N13D8","WKDFVXT1N13D9", & - "WKDFVXT1N14D1","WKDFVXT1N14D2","WKDFVXT1N14D3","WKDFVXT1N14D4","WKDFVXT1N14D5","WKDFVXT1N14D6","WKDFVXT1N14D7","WKDFVXT1N14D8", & - "WKDFVXT1N14D9","WKDFVXT1N15D1","WKDFVXT1N15D2","WKDFVXT1N15D3","WKDFVXT1N15D4","WKDFVXT1N15D5","WKDFVXT1N15D6","WKDFVXT1N15D7", & - "WKDFVXT1N15D8","WKDFVXT1N15D9","WKDFVXT1N16D1","WKDFVXT1N16D2","WKDFVXT1N16D3","WKDFVXT1N16D4","WKDFVXT1N16D5","WKDFVXT1N16D6", & - "WKDFVXT1N16D7","WKDFVXT1N16D8","WKDFVXT1N16D9","WKDFVXT1N17D1","WKDFVXT1N17D2","WKDFVXT1N17D3","WKDFVXT1N17D4","WKDFVXT1N17D5", & - "WKDFVXT1N17D6","WKDFVXT1N17D7","WKDFVXT1N17D8","WKDFVXT1N17D9","WKDFVXT1N18D1","WKDFVXT1N18D2","WKDFVXT1N18D3","WKDFVXT1N18D4", & - "WKDFVXT1N18D5","WKDFVXT1N18D6","WKDFVXT1N18D7","WKDFVXT1N18D8","WKDFVXT1N18D9","WKDFVXT1N19D1","WKDFVXT1N19D2","WKDFVXT1N19D3", & - "WKDFVXT1N19D4","WKDFVXT1N19D5","WKDFVXT1N19D6","WKDFVXT1N19D7","WKDFVXT1N19D8","WKDFVXT1N19D9","WKDFVXT1N20D1","WKDFVXT1N20D2", & - "WKDFVXT1N20D3","WKDFVXT1N20D4","WKDFVXT1N20D5","WKDFVXT1N20D6","WKDFVXT1N20D7","WKDFVXT1N20D8","WKDFVXT1N20D9","WKDFVXT2N01D1", & - "WKDFVXT2N01D2","WKDFVXT2N01D3","WKDFVXT2N01D4","WKDFVXT2N01D5","WKDFVXT2N01D6","WKDFVXT2N01D7","WKDFVXT2N01D8","WKDFVXT2N01D9", & - "WKDFVXT2N02D1","WKDFVXT2N02D2","WKDFVXT2N02D3","WKDFVXT2N02D4","WKDFVXT2N02D5","WKDFVXT2N02D6","WKDFVXT2N02D7","WKDFVXT2N02D8", & - "WKDFVXT2N02D9","WKDFVXT2N03D1","WKDFVXT2N03D2","WKDFVXT2N03D3","WKDFVXT2N03D4","WKDFVXT2N03D5","WKDFVXT2N03D6","WKDFVXT2N03D7", & - "WKDFVXT2N03D8","WKDFVXT2N03D9","WKDFVXT2N04D1","WKDFVXT2N04D2","WKDFVXT2N04D3","WKDFVXT2N04D4","WKDFVXT2N04D5","WKDFVXT2N04D6", & - "WKDFVXT2N04D7","WKDFVXT2N04D8","WKDFVXT2N04D9","WKDFVXT2N05D1","WKDFVXT2N05D2","WKDFVXT2N05D3","WKDFVXT2N05D4","WKDFVXT2N05D5", & - "WKDFVXT2N05D6","WKDFVXT2N05D7","WKDFVXT2N05D8","WKDFVXT2N05D9","WKDFVXT2N06D1","WKDFVXT2N06D2","WKDFVXT2N06D3","WKDFVXT2N06D4", & - "WKDFVXT2N06D5","WKDFVXT2N06D6","WKDFVXT2N06D7","WKDFVXT2N06D8","WKDFVXT2N06D9","WKDFVXT2N07D1","WKDFVXT2N07D2","WKDFVXT2N07D3", & - "WKDFVXT2N07D4","WKDFVXT2N07D5","WKDFVXT2N07D6","WKDFVXT2N07D7","WKDFVXT2N07D8","WKDFVXT2N07D9","WKDFVXT2N08D1","WKDFVXT2N08D2", & - "WKDFVXT2N08D3","WKDFVXT2N08D4","WKDFVXT2N08D5","WKDFVXT2N08D6","WKDFVXT2N08D7","WKDFVXT2N08D8","WKDFVXT2N08D9","WKDFVXT2N09D1", & - "WKDFVXT2N09D2","WKDFVXT2N09D3","WKDFVXT2N09D4","WKDFVXT2N09D5","WKDFVXT2N09D6","WKDFVXT2N09D7","WKDFVXT2N09D8","WKDFVXT2N09D9", & - "WKDFVXT2N10D1","WKDFVXT2N10D2","WKDFVXT2N10D3","WKDFVXT2N10D4","WKDFVXT2N10D5","WKDFVXT2N10D6","WKDFVXT2N10D7","WKDFVXT2N10D8", & - "WKDFVXT2N10D9","WKDFVXT2N11D1","WKDFVXT2N11D2","WKDFVXT2N11D3","WKDFVXT2N11D4","WKDFVXT2N11D5","WKDFVXT2N11D6","WKDFVXT2N11D7", & - "WKDFVXT2N11D8","WKDFVXT2N11D9","WKDFVXT2N12D1","WKDFVXT2N12D2","WKDFVXT2N12D3","WKDFVXT2N12D4","WKDFVXT2N12D5","WKDFVXT2N12D6", & - "WKDFVXT2N12D7","WKDFVXT2N12D8","WKDFVXT2N12D9","WKDFVXT2N13D1","WKDFVXT2N13D2","WKDFVXT2N13D3","WKDFVXT2N13D4","WKDFVXT2N13D5", & - "WKDFVXT2N13D6","WKDFVXT2N13D7","WKDFVXT2N13D8","WKDFVXT2N13D9","WKDFVXT2N14D1","WKDFVXT2N14D2","WKDFVXT2N14D3","WKDFVXT2N14D4", & - "WKDFVXT2N14D5","WKDFVXT2N14D6","WKDFVXT2N14D7","WKDFVXT2N14D8","WKDFVXT2N14D9","WKDFVXT2N15D1","WKDFVXT2N15D2","WKDFVXT2N15D3", & - "WKDFVXT2N15D4","WKDFVXT2N15D5","WKDFVXT2N15D6","WKDFVXT2N15D7","WKDFVXT2N15D8","WKDFVXT2N15D9","WKDFVXT2N16D1","WKDFVXT2N16D2", & - "WKDFVXT2N16D3","WKDFVXT2N16D4","WKDFVXT2N16D5","WKDFVXT2N16D6","WKDFVXT2N16D7","WKDFVXT2N16D8","WKDFVXT2N16D9","WKDFVXT2N17D1", & - "WKDFVXT2N17D2","WKDFVXT2N17D3","WKDFVXT2N17D4","WKDFVXT2N17D5","WKDFVXT2N17D6","WKDFVXT2N17D7","WKDFVXT2N17D8","WKDFVXT2N17D9", & - "WKDFVXT2N18D1","WKDFVXT2N18D2","WKDFVXT2N18D3","WKDFVXT2N18D4","WKDFVXT2N18D5","WKDFVXT2N18D6","WKDFVXT2N18D7","WKDFVXT2N18D8", & - "WKDFVXT2N18D9","WKDFVXT2N19D1","WKDFVXT2N19D2","WKDFVXT2N19D3","WKDFVXT2N19D4","WKDFVXT2N19D5","WKDFVXT2N19D6","WKDFVXT2N19D7", & - "WKDFVXT2N19D8","WKDFVXT2N19D9","WKDFVXT2N20D1","WKDFVXT2N20D2","WKDFVXT2N20D3","WKDFVXT2N20D4","WKDFVXT2N20D5","WKDFVXT2N20D6", & - "WKDFVXT2N20D7","WKDFVXT2N20D8","WKDFVXT2N20D9","WKDFVXT3N01D1","WKDFVXT3N01D2","WKDFVXT3N01D3","WKDFVXT3N01D4","WKDFVXT3N01D5", & - "WKDFVXT3N01D6","WKDFVXT3N01D7","WKDFVXT3N01D8","WKDFVXT3N01D9","WKDFVXT3N02D1","WKDFVXT3N02D2","WKDFVXT3N02D3","WKDFVXT3N02D4", & - "WKDFVXT3N02D5","WKDFVXT3N02D6","WKDFVXT3N02D7","WKDFVXT3N02D8","WKDFVXT3N02D9","WKDFVXT3N03D1","WKDFVXT3N03D2","WKDFVXT3N03D3", & - "WKDFVXT3N03D4","WKDFVXT3N03D5","WKDFVXT3N03D6","WKDFVXT3N03D7","WKDFVXT3N03D8","WKDFVXT3N03D9","WKDFVXT3N04D1","WKDFVXT3N04D2", & - "WKDFVXT3N04D3","WKDFVXT3N04D4","WKDFVXT3N04D5","WKDFVXT3N04D6","WKDFVXT3N04D7","WKDFVXT3N04D8","WKDFVXT3N04D9","WKDFVXT3N05D1", & - "WKDFVXT3N05D2","WKDFVXT3N05D3","WKDFVXT3N05D4","WKDFVXT3N05D5","WKDFVXT3N05D6","WKDFVXT3N05D7","WKDFVXT3N05D8","WKDFVXT3N05D9", & - "WKDFVXT3N06D1","WKDFVXT3N06D2","WKDFVXT3N06D3","WKDFVXT3N06D4","WKDFVXT3N06D5","WKDFVXT3N06D6","WKDFVXT3N06D7","WKDFVXT3N06D8", & - "WKDFVXT3N06D9","WKDFVXT3N07D1","WKDFVXT3N07D2","WKDFVXT3N07D3","WKDFVXT3N07D4","WKDFVXT3N07D5","WKDFVXT3N07D6","WKDFVXT3N07D7", & - "WKDFVXT3N07D8","WKDFVXT3N07D9","WKDFVXT3N08D1","WKDFVXT3N08D2","WKDFVXT3N08D3","WKDFVXT3N08D4","WKDFVXT3N08D5","WKDFVXT3N08D6", & - "WKDFVXT3N08D7","WKDFVXT3N08D8","WKDFVXT3N08D9","WKDFVXT3N09D1","WKDFVXT3N09D2","WKDFVXT3N09D3","WKDFVXT3N09D4","WKDFVXT3N09D5", & - "WKDFVXT3N09D6","WKDFVXT3N09D7","WKDFVXT3N09D8","WKDFVXT3N09D9","WKDFVXT3N10D1","WKDFVXT3N10D2","WKDFVXT3N10D3","WKDFVXT3N10D4", & - "WKDFVXT3N10D5","WKDFVXT3N10D6","WKDFVXT3N10D7","WKDFVXT3N10D8","WKDFVXT3N10D9","WKDFVXT3N11D1","WKDFVXT3N11D2","WKDFVXT3N11D3", & - "WKDFVXT3N11D4","WKDFVXT3N11D5","WKDFVXT3N11D6","WKDFVXT3N11D7","WKDFVXT3N11D8","WKDFVXT3N11D9","WKDFVXT3N12D1","WKDFVXT3N12D2", & - "WKDFVXT3N12D3","WKDFVXT3N12D4","WKDFVXT3N12D5","WKDFVXT3N12D6","WKDFVXT3N12D7","WKDFVXT3N12D8","WKDFVXT3N12D9","WKDFVXT3N13D1", & - "WKDFVXT3N13D2","WKDFVXT3N13D3","WKDFVXT3N13D4","WKDFVXT3N13D5","WKDFVXT3N13D6","WKDFVXT3N13D7","WKDFVXT3N13D8","WKDFVXT3N13D9", & - "WKDFVXT3N14D1","WKDFVXT3N14D2","WKDFVXT3N14D3","WKDFVXT3N14D4","WKDFVXT3N14D5","WKDFVXT3N14D6","WKDFVXT3N14D7","WKDFVXT3N14D8", & - "WKDFVXT3N14D9","WKDFVXT3N15D1","WKDFVXT3N15D2","WKDFVXT3N15D3","WKDFVXT3N15D4","WKDFVXT3N15D5","WKDFVXT3N15D6","WKDFVXT3N15D7", & - "WKDFVXT3N15D8","WKDFVXT3N15D9","WKDFVXT3N16D1","WKDFVXT3N16D2","WKDFVXT3N16D3","WKDFVXT3N16D4","WKDFVXT3N16D5","WKDFVXT3N16D6", & - "WKDFVXT3N16D7","WKDFVXT3N16D8","WKDFVXT3N16D9","WKDFVXT3N17D1","WKDFVXT3N17D2","WKDFVXT3N17D3","WKDFVXT3N17D4","WKDFVXT3N17D5", & - "WKDFVXT3N17D6","WKDFVXT3N17D7","WKDFVXT3N17D8","WKDFVXT3N17D9","WKDFVXT3N18D1","WKDFVXT3N18D2","WKDFVXT3N18D3","WKDFVXT3N18D4", & - "WKDFVXT3N18D5","WKDFVXT3N18D6","WKDFVXT3N18D7","WKDFVXT3N18D8","WKDFVXT3N18D9","WKDFVXT3N19D1","WKDFVXT3N19D2","WKDFVXT3N19D3", & - "WKDFVXT3N19D4","WKDFVXT3N19D5","WKDFVXT3N19D6","WKDFVXT3N19D7","WKDFVXT3N19D8","WKDFVXT3N19D9","WKDFVXT3N20D1","WKDFVXT3N20D2", & - "WKDFVXT3N20D3","WKDFVXT3N20D4","WKDFVXT3N20D5","WKDFVXT3N20D6","WKDFVXT3N20D7","WKDFVXT3N20D8","WKDFVXT3N20D9","WKDFVXT4N01D1", & - "WKDFVXT4N01D2","WKDFVXT4N01D3","WKDFVXT4N01D4","WKDFVXT4N01D5","WKDFVXT4N01D6","WKDFVXT4N01D7","WKDFVXT4N01D8","WKDFVXT4N01D9", & - "WKDFVXT4N02D1","WKDFVXT4N02D2","WKDFVXT4N02D3","WKDFVXT4N02D4","WKDFVXT4N02D5","WKDFVXT4N02D6","WKDFVXT4N02D7","WKDFVXT4N02D8", & - "WKDFVXT4N02D9","WKDFVXT4N03D1","WKDFVXT4N03D2","WKDFVXT4N03D3","WKDFVXT4N03D4","WKDFVXT4N03D5","WKDFVXT4N03D6","WKDFVXT4N03D7", & - "WKDFVXT4N03D8","WKDFVXT4N03D9","WKDFVXT4N04D1","WKDFVXT4N04D2","WKDFVXT4N04D3","WKDFVXT4N04D4","WKDFVXT4N04D5","WKDFVXT4N04D6", & - "WKDFVXT4N04D7","WKDFVXT4N04D8","WKDFVXT4N04D9","WKDFVXT4N05D1","WKDFVXT4N05D2","WKDFVXT4N05D3","WKDFVXT4N05D4","WKDFVXT4N05D5", & - "WKDFVXT4N05D6","WKDFVXT4N05D7","WKDFVXT4N05D8","WKDFVXT4N05D9","WKDFVXT4N06D1","WKDFVXT4N06D2","WKDFVXT4N06D3","WKDFVXT4N06D4", & - "WKDFVXT4N06D5","WKDFVXT4N06D6","WKDFVXT4N06D7","WKDFVXT4N06D8","WKDFVXT4N06D9","WKDFVXT4N07D1","WKDFVXT4N07D2","WKDFVXT4N07D3", & - "WKDFVXT4N07D4","WKDFVXT4N07D5","WKDFVXT4N07D6","WKDFVXT4N07D7","WKDFVXT4N07D8","WKDFVXT4N07D9","WKDFVXT4N08D1","WKDFVXT4N08D2", & - "WKDFVXT4N08D3","WKDFVXT4N08D4","WKDFVXT4N08D5","WKDFVXT4N08D6","WKDFVXT4N08D7","WKDFVXT4N08D8","WKDFVXT4N08D9","WKDFVXT4N09D1", & - "WKDFVXT4N09D2","WKDFVXT4N09D3","WKDFVXT4N09D4","WKDFVXT4N09D5","WKDFVXT4N09D6","WKDFVXT4N09D7","WKDFVXT4N09D8","WKDFVXT4N09D9", & - "WKDFVXT4N10D1","WKDFVXT4N10D2","WKDFVXT4N10D3","WKDFVXT4N10D4","WKDFVXT4N10D5","WKDFVXT4N10D6","WKDFVXT4N10D7","WKDFVXT4N10D8", & - "WKDFVXT4N10D9","WKDFVXT4N11D1","WKDFVXT4N11D2","WKDFVXT4N11D3","WKDFVXT4N11D4","WKDFVXT4N11D5","WKDFVXT4N11D6","WKDFVXT4N11D7", & - "WKDFVXT4N11D8","WKDFVXT4N11D9","WKDFVXT4N12D1","WKDFVXT4N12D2","WKDFVXT4N12D3","WKDFVXT4N12D4","WKDFVXT4N12D5","WKDFVXT4N12D6", & - "WKDFVXT4N12D7","WKDFVXT4N12D8","WKDFVXT4N12D9","WKDFVXT4N13D1","WKDFVXT4N13D2","WKDFVXT4N13D3","WKDFVXT4N13D4","WKDFVXT4N13D5", & - "WKDFVXT4N13D6","WKDFVXT4N13D7","WKDFVXT4N13D8","WKDFVXT4N13D9","WKDFVXT4N14D1","WKDFVXT4N14D2","WKDFVXT4N14D3","WKDFVXT4N14D4", & - "WKDFVXT4N14D5","WKDFVXT4N14D6","WKDFVXT4N14D7","WKDFVXT4N14D8","WKDFVXT4N14D9","WKDFVXT4N15D1","WKDFVXT4N15D2","WKDFVXT4N15D3", & - "WKDFVXT4N15D4","WKDFVXT4N15D5","WKDFVXT4N15D6","WKDFVXT4N15D7","WKDFVXT4N15D8","WKDFVXT4N15D9","WKDFVXT4N16D1","WKDFVXT4N16D2", & - "WKDFVXT4N16D3","WKDFVXT4N16D4","WKDFVXT4N16D5","WKDFVXT4N16D6","WKDFVXT4N16D7","WKDFVXT4N16D8","WKDFVXT4N16D9","WKDFVXT4N17D1", & - "WKDFVXT4N17D2","WKDFVXT4N17D3","WKDFVXT4N17D4","WKDFVXT4N17D5","WKDFVXT4N17D6","WKDFVXT4N17D7","WKDFVXT4N17D8","WKDFVXT4N17D9", & - "WKDFVXT4N18D1","WKDFVXT4N18D2","WKDFVXT4N18D3","WKDFVXT4N18D4","WKDFVXT4N18D5","WKDFVXT4N18D6","WKDFVXT4N18D7","WKDFVXT4N18D8", & - "WKDFVXT4N18D9","WKDFVXT4N19D1","WKDFVXT4N19D2","WKDFVXT4N19D3","WKDFVXT4N19D4","WKDFVXT4N19D5","WKDFVXT4N19D6","WKDFVXT4N19D7", & - "WKDFVXT4N19D8","WKDFVXT4N19D9","WKDFVXT4N20D1","WKDFVXT4N20D2","WKDFVXT4N20D3","WKDFVXT4N20D4","WKDFVXT4N20D5","WKDFVXT4N20D6", & - "WKDFVXT4N20D7","WKDFVXT4N20D8","WKDFVXT4N20D9","WKDFVXT5N01D1","WKDFVXT5N01D2","WKDFVXT5N01D3","WKDFVXT5N01D4","WKDFVXT5N01D5", & - "WKDFVXT5N01D6","WKDFVXT5N01D7","WKDFVXT5N01D8","WKDFVXT5N01D9","WKDFVXT5N02D1","WKDFVXT5N02D2","WKDFVXT5N02D3","WKDFVXT5N02D4", & - "WKDFVXT5N02D5","WKDFVXT5N02D6","WKDFVXT5N02D7","WKDFVXT5N02D8","WKDFVXT5N02D9","WKDFVXT5N03D1","WKDFVXT5N03D2","WKDFVXT5N03D3", & - "WKDFVXT5N03D4","WKDFVXT5N03D5","WKDFVXT5N03D6","WKDFVXT5N03D7","WKDFVXT5N03D8","WKDFVXT5N03D9","WKDFVXT5N04D1","WKDFVXT5N04D2", & - "WKDFVXT5N04D3","WKDFVXT5N04D4","WKDFVXT5N04D5","WKDFVXT5N04D6","WKDFVXT5N04D7","WKDFVXT5N04D8","WKDFVXT5N04D9","WKDFVXT5N05D1", & - "WKDFVXT5N05D2","WKDFVXT5N05D3","WKDFVXT5N05D4","WKDFVXT5N05D5","WKDFVXT5N05D6","WKDFVXT5N05D7","WKDFVXT5N05D8","WKDFVXT5N05D9", & - "WKDFVXT5N06D1","WKDFVXT5N06D2","WKDFVXT5N06D3","WKDFVXT5N06D4","WKDFVXT5N06D5","WKDFVXT5N06D6","WKDFVXT5N06D7","WKDFVXT5N06D8", & - "WKDFVXT5N06D9","WKDFVXT5N07D1","WKDFVXT5N07D2","WKDFVXT5N07D3","WKDFVXT5N07D4","WKDFVXT5N07D5","WKDFVXT5N07D6","WKDFVXT5N07D7", & - "WKDFVXT5N07D8","WKDFVXT5N07D9","WKDFVXT5N08D1","WKDFVXT5N08D2","WKDFVXT5N08D3","WKDFVXT5N08D4","WKDFVXT5N08D5","WKDFVXT5N08D6", & - "WKDFVXT5N08D7","WKDFVXT5N08D8","WKDFVXT5N08D9","WKDFVXT5N09D1","WKDFVXT5N09D2","WKDFVXT5N09D3","WKDFVXT5N09D4","WKDFVXT5N09D5", & - "WKDFVXT5N09D6","WKDFVXT5N09D7","WKDFVXT5N09D8","WKDFVXT5N09D9","WKDFVXT5N10D1","WKDFVXT5N10D2","WKDFVXT5N10D3","WKDFVXT5N10D4", & - "WKDFVXT5N10D5","WKDFVXT5N10D6","WKDFVXT5N10D7","WKDFVXT5N10D8","WKDFVXT5N10D9","WKDFVXT5N11D1","WKDFVXT5N11D2","WKDFVXT5N11D3", & - "WKDFVXT5N11D4","WKDFVXT5N11D5","WKDFVXT5N11D6","WKDFVXT5N11D7","WKDFVXT5N11D8","WKDFVXT5N11D9","WKDFVXT5N12D1","WKDFVXT5N12D2", & - "WKDFVXT5N12D3","WKDFVXT5N12D4","WKDFVXT5N12D5","WKDFVXT5N12D6","WKDFVXT5N12D7","WKDFVXT5N12D8","WKDFVXT5N12D9","WKDFVXT5N13D1", & - "WKDFVXT5N13D2","WKDFVXT5N13D3","WKDFVXT5N13D4","WKDFVXT5N13D5","WKDFVXT5N13D6","WKDFVXT5N13D7","WKDFVXT5N13D8","WKDFVXT5N13D9", & - "WKDFVXT5N14D1","WKDFVXT5N14D2","WKDFVXT5N14D3","WKDFVXT5N14D4","WKDFVXT5N14D5","WKDFVXT5N14D6","WKDFVXT5N14D7","WKDFVXT5N14D8", & - "WKDFVXT5N14D9","WKDFVXT5N15D1","WKDFVXT5N15D2","WKDFVXT5N15D3","WKDFVXT5N15D4","WKDFVXT5N15D5","WKDFVXT5N15D6","WKDFVXT5N15D7", & - "WKDFVXT5N15D8","WKDFVXT5N15D9","WKDFVXT5N16D1","WKDFVXT5N16D2","WKDFVXT5N16D3","WKDFVXT5N16D4","WKDFVXT5N16D5","WKDFVXT5N16D6", & - "WKDFVXT5N16D7","WKDFVXT5N16D8","WKDFVXT5N16D9","WKDFVXT5N17D1","WKDFVXT5N17D2","WKDFVXT5N17D3","WKDFVXT5N17D4","WKDFVXT5N17D5", & - "WKDFVXT5N17D6","WKDFVXT5N17D7","WKDFVXT5N17D8","WKDFVXT5N17D9","WKDFVXT5N18D1","WKDFVXT5N18D2","WKDFVXT5N18D3","WKDFVXT5N18D4", & - "WKDFVXT5N18D5","WKDFVXT5N18D6","WKDFVXT5N18D7","WKDFVXT5N18D8","WKDFVXT5N18D9","WKDFVXT5N19D1","WKDFVXT5N19D2","WKDFVXT5N19D3", & - "WKDFVXT5N19D4","WKDFVXT5N19D5","WKDFVXT5N19D6","WKDFVXT5N19D7","WKDFVXT5N19D8","WKDFVXT5N19D9","WKDFVXT5N20D1","WKDFVXT5N20D2", & - "WKDFVXT5N20D3","WKDFVXT5N20D4","WKDFVXT5N20D5","WKDFVXT5N20D6","WKDFVXT5N20D7","WKDFVXT5N20D8","WKDFVXT5N20D9","WKDFVXT6N01D1", & - "WKDFVXT6N01D2","WKDFVXT6N01D3","WKDFVXT6N01D4","WKDFVXT6N01D5","WKDFVXT6N01D6","WKDFVXT6N01D7","WKDFVXT6N01D8","WKDFVXT6N01D9", & - "WKDFVXT6N02D1","WKDFVXT6N02D2","WKDFVXT6N02D3","WKDFVXT6N02D4","WKDFVXT6N02D5","WKDFVXT6N02D6","WKDFVXT6N02D7","WKDFVXT6N02D8", & - "WKDFVXT6N02D9","WKDFVXT6N03D1","WKDFVXT6N03D2","WKDFVXT6N03D3","WKDFVXT6N03D4","WKDFVXT6N03D5","WKDFVXT6N03D6","WKDFVXT6N03D7", & - "WKDFVXT6N03D8","WKDFVXT6N03D9","WKDFVXT6N04D1","WKDFVXT6N04D2","WKDFVXT6N04D3","WKDFVXT6N04D4","WKDFVXT6N04D5","WKDFVXT6N04D6"/) - ValidParamAry(8161:9423) = (/ & - "WKDFVXT6N04D7","WKDFVXT6N04D8","WKDFVXT6N04D9","WKDFVXT6N05D1","WKDFVXT6N05D2","WKDFVXT6N05D3","WKDFVXT6N05D4","WKDFVXT6N05D5", & - "WKDFVXT6N05D6","WKDFVXT6N05D7","WKDFVXT6N05D8","WKDFVXT6N05D9","WKDFVXT6N06D1","WKDFVXT6N06D2","WKDFVXT6N06D3","WKDFVXT6N06D4", & - "WKDFVXT6N06D5","WKDFVXT6N06D6","WKDFVXT6N06D7","WKDFVXT6N06D8","WKDFVXT6N06D9","WKDFVXT6N07D1","WKDFVXT6N07D2","WKDFVXT6N07D3", & - "WKDFVXT6N07D4","WKDFVXT6N07D5","WKDFVXT6N07D6","WKDFVXT6N07D7","WKDFVXT6N07D8","WKDFVXT6N07D9","WKDFVXT6N08D1","WKDFVXT6N08D2", & - "WKDFVXT6N08D3","WKDFVXT6N08D4","WKDFVXT6N08D5","WKDFVXT6N08D6","WKDFVXT6N08D7","WKDFVXT6N08D8","WKDFVXT6N08D9","WKDFVXT6N09D1", & - "WKDFVXT6N09D2","WKDFVXT6N09D3","WKDFVXT6N09D4","WKDFVXT6N09D5","WKDFVXT6N09D6","WKDFVXT6N09D7","WKDFVXT6N09D8","WKDFVXT6N09D9", & - "WKDFVXT6N10D1","WKDFVXT6N10D2","WKDFVXT6N10D3","WKDFVXT6N10D4","WKDFVXT6N10D5","WKDFVXT6N10D6","WKDFVXT6N10D7","WKDFVXT6N10D8", & - "WKDFVXT6N10D9","WKDFVXT6N11D1","WKDFVXT6N11D2","WKDFVXT6N11D3","WKDFVXT6N11D4","WKDFVXT6N11D5","WKDFVXT6N11D6","WKDFVXT6N11D7", & - "WKDFVXT6N11D8","WKDFVXT6N11D9","WKDFVXT6N12D1","WKDFVXT6N12D2","WKDFVXT6N12D3","WKDFVXT6N12D4","WKDFVXT6N12D5","WKDFVXT6N12D6", & - "WKDFVXT6N12D7","WKDFVXT6N12D8","WKDFVXT6N12D9","WKDFVXT6N13D1","WKDFVXT6N13D2","WKDFVXT6N13D3","WKDFVXT6N13D4","WKDFVXT6N13D5", & - "WKDFVXT6N13D6","WKDFVXT6N13D7","WKDFVXT6N13D8","WKDFVXT6N13D9","WKDFVXT6N14D1","WKDFVXT6N14D2","WKDFVXT6N14D3","WKDFVXT6N14D4", & - "WKDFVXT6N14D5","WKDFVXT6N14D6","WKDFVXT6N14D7","WKDFVXT6N14D8","WKDFVXT6N14D9","WKDFVXT6N15D1","WKDFVXT6N15D2","WKDFVXT6N15D3", & - "WKDFVXT6N15D4","WKDFVXT6N15D5","WKDFVXT6N15D6","WKDFVXT6N15D7","WKDFVXT6N15D8","WKDFVXT6N15D9","WKDFVXT6N16D1","WKDFVXT6N16D2", & - "WKDFVXT6N16D3","WKDFVXT6N16D4","WKDFVXT6N16D5","WKDFVXT6N16D6","WKDFVXT6N16D7","WKDFVXT6N16D8","WKDFVXT6N16D9","WKDFVXT6N17D1", & - "WKDFVXT6N17D2","WKDFVXT6N17D3","WKDFVXT6N17D4","WKDFVXT6N17D5","WKDFVXT6N17D6","WKDFVXT6N17D7","WKDFVXT6N17D8","WKDFVXT6N17D9", & - "WKDFVXT6N18D1","WKDFVXT6N18D2","WKDFVXT6N18D3","WKDFVXT6N18D4","WKDFVXT6N18D5","WKDFVXT6N18D6","WKDFVXT6N18D7","WKDFVXT6N18D8", & - "WKDFVXT6N18D9","WKDFVXT6N19D1","WKDFVXT6N19D2","WKDFVXT6N19D3","WKDFVXT6N19D4","WKDFVXT6N19D5","WKDFVXT6N19D6","WKDFVXT6N19D7", & - "WKDFVXT6N19D8","WKDFVXT6N19D9","WKDFVXT6N20D1","WKDFVXT6N20D2","WKDFVXT6N20D3","WKDFVXT6N20D4","WKDFVXT6N20D5","WKDFVXT6N20D6", & - "WKDFVXT6N20D7","WKDFVXT6N20D8","WKDFVXT6N20D9","WKDFVXT7N01D1","WKDFVXT7N01D2","WKDFVXT7N01D3","WKDFVXT7N01D4","WKDFVXT7N01D5", & - "WKDFVXT7N01D6","WKDFVXT7N01D7","WKDFVXT7N01D8","WKDFVXT7N01D9","WKDFVXT7N02D1","WKDFVXT7N02D2","WKDFVXT7N02D3","WKDFVXT7N02D4", & - "WKDFVXT7N02D5","WKDFVXT7N02D6","WKDFVXT7N02D7","WKDFVXT7N02D8","WKDFVXT7N02D9","WKDFVXT7N03D1","WKDFVXT7N03D2","WKDFVXT7N03D3", & - "WKDFVXT7N03D4","WKDFVXT7N03D5","WKDFVXT7N03D6","WKDFVXT7N03D7","WKDFVXT7N03D8","WKDFVXT7N03D9","WKDFVXT7N04D1","WKDFVXT7N04D2", & - "WKDFVXT7N04D3","WKDFVXT7N04D4","WKDFVXT7N04D5","WKDFVXT7N04D6","WKDFVXT7N04D7","WKDFVXT7N04D8","WKDFVXT7N04D9","WKDFVXT7N05D1", & - "WKDFVXT7N05D2","WKDFVXT7N05D3","WKDFVXT7N05D4","WKDFVXT7N05D5","WKDFVXT7N05D6","WKDFVXT7N05D7","WKDFVXT7N05D8","WKDFVXT7N05D9", & - "WKDFVXT7N06D1","WKDFVXT7N06D2","WKDFVXT7N06D3","WKDFVXT7N06D4","WKDFVXT7N06D5","WKDFVXT7N06D6","WKDFVXT7N06D7","WKDFVXT7N06D8", & - "WKDFVXT7N06D9","WKDFVXT7N07D1","WKDFVXT7N07D2","WKDFVXT7N07D3","WKDFVXT7N07D4","WKDFVXT7N07D5","WKDFVXT7N07D6","WKDFVXT7N07D7", & - "WKDFVXT7N07D8","WKDFVXT7N07D9","WKDFVXT7N08D1","WKDFVXT7N08D2","WKDFVXT7N08D3","WKDFVXT7N08D4","WKDFVXT7N08D5","WKDFVXT7N08D6", & - "WKDFVXT7N08D7","WKDFVXT7N08D8","WKDFVXT7N08D9","WKDFVXT7N09D1","WKDFVXT7N09D2","WKDFVXT7N09D3","WKDFVXT7N09D4","WKDFVXT7N09D5", & - "WKDFVXT7N09D6","WKDFVXT7N09D7","WKDFVXT7N09D8","WKDFVXT7N09D9","WKDFVXT7N10D1","WKDFVXT7N10D2","WKDFVXT7N10D3","WKDFVXT7N10D4", & - "WKDFVXT7N10D5","WKDFVXT7N10D6","WKDFVXT7N10D7","WKDFVXT7N10D8","WKDFVXT7N10D9","WKDFVXT7N11D1","WKDFVXT7N11D2","WKDFVXT7N11D3", & - "WKDFVXT7N11D4","WKDFVXT7N11D5","WKDFVXT7N11D6","WKDFVXT7N11D7","WKDFVXT7N11D8","WKDFVXT7N11D9","WKDFVXT7N12D1","WKDFVXT7N12D2", & - "WKDFVXT7N12D3","WKDFVXT7N12D4","WKDFVXT7N12D5","WKDFVXT7N12D6","WKDFVXT7N12D7","WKDFVXT7N12D8","WKDFVXT7N12D9","WKDFVXT7N13D1", & - "WKDFVXT7N13D2","WKDFVXT7N13D3","WKDFVXT7N13D4","WKDFVXT7N13D5","WKDFVXT7N13D6","WKDFVXT7N13D7","WKDFVXT7N13D8","WKDFVXT7N13D9", & - "WKDFVXT7N14D1","WKDFVXT7N14D2","WKDFVXT7N14D3","WKDFVXT7N14D4","WKDFVXT7N14D5","WKDFVXT7N14D6","WKDFVXT7N14D7","WKDFVXT7N14D8", & - "WKDFVXT7N14D9","WKDFVXT7N15D1","WKDFVXT7N15D2","WKDFVXT7N15D3","WKDFVXT7N15D4","WKDFVXT7N15D5","WKDFVXT7N15D6","WKDFVXT7N15D7", & - "WKDFVXT7N15D8","WKDFVXT7N15D9","WKDFVXT7N16D1","WKDFVXT7N16D2","WKDFVXT7N16D3","WKDFVXT7N16D4","WKDFVXT7N16D5","WKDFVXT7N16D6", & - "WKDFVXT7N16D7","WKDFVXT7N16D8","WKDFVXT7N16D9","WKDFVXT7N17D1","WKDFVXT7N17D2","WKDFVXT7N17D3","WKDFVXT7N17D4","WKDFVXT7N17D5", & - "WKDFVXT7N17D6","WKDFVXT7N17D7","WKDFVXT7N17D8","WKDFVXT7N17D9","WKDFVXT7N18D1","WKDFVXT7N18D2","WKDFVXT7N18D3","WKDFVXT7N18D4", & - "WKDFVXT7N18D5","WKDFVXT7N18D6","WKDFVXT7N18D7","WKDFVXT7N18D8","WKDFVXT7N18D9","WKDFVXT7N19D1","WKDFVXT7N19D2","WKDFVXT7N19D3", & - "WKDFVXT7N19D4","WKDFVXT7N19D5","WKDFVXT7N19D6","WKDFVXT7N19D7","WKDFVXT7N19D8","WKDFVXT7N19D9","WKDFVXT7N20D1","WKDFVXT7N20D2", & - "WKDFVXT7N20D3","WKDFVXT7N20D4","WKDFVXT7N20D5","WKDFVXT7N20D6","WKDFVXT7N20D7","WKDFVXT7N20D8","WKDFVXT7N20D9","WKDFVXT8N01D1", & - "WKDFVXT8N01D2","WKDFVXT8N01D3","WKDFVXT8N01D4","WKDFVXT8N01D5","WKDFVXT8N01D6","WKDFVXT8N01D7","WKDFVXT8N01D8","WKDFVXT8N01D9", & - "WKDFVXT8N02D1","WKDFVXT8N02D2","WKDFVXT8N02D3","WKDFVXT8N02D4","WKDFVXT8N02D5","WKDFVXT8N02D6","WKDFVXT8N02D7","WKDFVXT8N02D8", & - "WKDFVXT8N02D9","WKDFVXT8N03D1","WKDFVXT8N03D2","WKDFVXT8N03D3","WKDFVXT8N03D4","WKDFVXT8N03D5","WKDFVXT8N03D6","WKDFVXT8N03D7", & - "WKDFVXT8N03D8","WKDFVXT8N03D9","WKDFVXT8N04D1","WKDFVXT8N04D2","WKDFVXT8N04D3","WKDFVXT8N04D4","WKDFVXT8N04D5","WKDFVXT8N04D6", & - "WKDFVXT8N04D7","WKDFVXT8N04D8","WKDFVXT8N04D9","WKDFVXT8N05D1","WKDFVXT8N05D2","WKDFVXT8N05D3","WKDFVXT8N05D4","WKDFVXT8N05D5", & - "WKDFVXT8N05D6","WKDFVXT8N05D7","WKDFVXT8N05D8","WKDFVXT8N05D9","WKDFVXT8N06D1","WKDFVXT8N06D2","WKDFVXT8N06D3","WKDFVXT8N06D4", & - "WKDFVXT8N06D5","WKDFVXT8N06D6","WKDFVXT8N06D7","WKDFVXT8N06D8","WKDFVXT8N06D9","WKDFVXT8N07D1","WKDFVXT8N07D2","WKDFVXT8N07D3", & - "WKDFVXT8N07D4","WKDFVXT8N07D5","WKDFVXT8N07D6","WKDFVXT8N07D7","WKDFVXT8N07D8","WKDFVXT8N07D9","WKDFVXT8N08D1","WKDFVXT8N08D2", & - "WKDFVXT8N08D3","WKDFVXT8N08D4","WKDFVXT8N08D5","WKDFVXT8N08D6","WKDFVXT8N08D7","WKDFVXT8N08D8","WKDFVXT8N08D9","WKDFVXT8N09D1", & - "WKDFVXT8N09D2","WKDFVXT8N09D3","WKDFVXT8N09D4","WKDFVXT8N09D5","WKDFVXT8N09D6","WKDFVXT8N09D7","WKDFVXT8N09D8","WKDFVXT8N09D9", & - "WKDFVXT8N10D1","WKDFVXT8N10D2","WKDFVXT8N10D3","WKDFVXT8N10D4","WKDFVXT8N10D5","WKDFVXT8N10D6","WKDFVXT8N10D7","WKDFVXT8N10D8", & - "WKDFVXT8N10D9","WKDFVXT8N11D1","WKDFVXT8N11D2","WKDFVXT8N11D3","WKDFVXT8N11D4","WKDFVXT8N11D5","WKDFVXT8N11D6","WKDFVXT8N11D7", & - "WKDFVXT8N11D8","WKDFVXT8N11D9","WKDFVXT8N12D1","WKDFVXT8N12D2","WKDFVXT8N12D3","WKDFVXT8N12D4","WKDFVXT8N12D5","WKDFVXT8N12D6", & - "WKDFVXT8N12D7","WKDFVXT8N12D8","WKDFVXT8N12D9","WKDFVXT8N13D1","WKDFVXT8N13D2","WKDFVXT8N13D3","WKDFVXT8N13D4","WKDFVXT8N13D5", & - "WKDFVXT8N13D6","WKDFVXT8N13D7","WKDFVXT8N13D8","WKDFVXT8N13D9","WKDFVXT8N14D1","WKDFVXT8N14D2","WKDFVXT8N14D3","WKDFVXT8N14D4", & - "WKDFVXT8N14D5","WKDFVXT8N14D6","WKDFVXT8N14D7","WKDFVXT8N14D8","WKDFVXT8N14D9","WKDFVXT8N15D1","WKDFVXT8N15D2","WKDFVXT8N15D3", & - "WKDFVXT8N15D4","WKDFVXT8N15D5","WKDFVXT8N15D6","WKDFVXT8N15D7","WKDFVXT8N15D8","WKDFVXT8N15D9","WKDFVXT8N16D1","WKDFVXT8N16D2", & - "WKDFVXT8N16D3","WKDFVXT8N16D4","WKDFVXT8N16D5","WKDFVXT8N16D6","WKDFVXT8N16D7","WKDFVXT8N16D8","WKDFVXT8N16D9","WKDFVXT8N17D1", & - "WKDFVXT8N17D2","WKDFVXT8N17D3","WKDFVXT8N17D4","WKDFVXT8N17D5","WKDFVXT8N17D6","WKDFVXT8N17D7","WKDFVXT8N17D8","WKDFVXT8N17D9", & - "WKDFVXT8N18D1","WKDFVXT8N18D2","WKDFVXT8N18D3","WKDFVXT8N18D4","WKDFVXT8N18D5","WKDFVXT8N18D6","WKDFVXT8N18D7","WKDFVXT8N18D8", & - "WKDFVXT8N18D9","WKDFVXT8N19D1","WKDFVXT8N19D2","WKDFVXT8N19D3","WKDFVXT8N19D4","WKDFVXT8N19D5","WKDFVXT8N19D6","WKDFVXT8N19D7", & - "WKDFVXT8N19D8","WKDFVXT8N19D9","WKDFVXT8N20D1","WKDFVXT8N20D2","WKDFVXT8N20D3","WKDFVXT8N20D4","WKDFVXT8N20D5","WKDFVXT8N20D6", & - "WKDFVXT8N20D7","WKDFVXT8N20D8","WKDFVXT8N20D9","WKDFVXT9N01D1","WKDFVXT9N01D2","WKDFVXT9N01D3","WKDFVXT9N01D4","WKDFVXT9N01D5", & - "WKDFVXT9N01D6","WKDFVXT9N01D7","WKDFVXT9N01D8","WKDFVXT9N01D9","WKDFVXT9N02D1","WKDFVXT9N02D2","WKDFVXT9N02D3","WKDFVXT9N02D4", & - "WKDFVXT9N02D5","WKDFVXT9N02D6","WKDFVXT9N02D7","WKDFVXT9N02D8","WKDFVXT9N02D9","WKDFVXT9N03D1","WKDFVXT9N03D2","WKDFVXT9N03D3", & - "WKDFVXT9N03D4","WKDFVXT9N03D5","WKDFVXT9N03D6","WKDFVXT9N03D7","WKDFVXT9N03D8","WKDFVXT9N03D9","WKDFVXT9N04D1","WKDFVXT9N04D2", & - "WKDFVXT9N04D3","WKDFVXT9N04D4","WKDFVXT9N04D5","WKDFVXT9N04D6","WKDFVXT9N04D7","WKDFVXT9N04D8","WKDFVXT9N04D9","WKDFVXT9N05D1", & - "WKDFVXT9N05D2","WKDFVXT9N05D3","WKDFVXT9N05D4","WKDFVXT9N05D5","WKDFVXT9N05D6","WKDFVXT9N05D7","WKDFVXT9N05D8","WKDFVXT9N05D9", & - "WKDFVXT9N06D1","WKDFVXT9N06D2","WKDFVXT9N06D3","WKDFVXT9N06D4","WKDFVXT9N06D5","WKDFVXT9N06D6","WKDFVXT9N06D7","WKDFVXT9N06D8", & - "WKDFVXT9N06D9","WKDFVXT9N07D1","WKDFVXT9N07D2","WKDFVXT9N07D3","WKDFVXT9N07D4","WKDFVXT9N07D5","WKDFVXT9N07D6","WKDFVXT9N07D7", & - "WKDFVXT9N07D8","WKDFVXT9N07D9","WKDFVXT9N08D1","WKDFVXT9N08D2","WKDFVXT9N08D3","WKDFVXT9N08D4","WKDFVXT9N08D5","WKDFVXT9N08D6", & - "WKDFVXT9N08D7","WKDFVXT9N08D8","WKDFVXT9N08D9","WKDFVXT9N09D1","WKDFVXT9N09D2","WKDFVXT9N09D3","WKDFVXT9N09D4","WKDFVXT9N09D5", & - "WKDFVXT9N09D6","WKDFVXT9N09D7","WKDFVXT9N09D8","WKDFVXT9N09D9","WKDFVXT9N10D1","WKDFVXT9N10D2","WKDFVXT9N10D3","WKDFVXT9N10D4", & - "WKDFVXT9N10D5","WKDFVXT9N10D6","WKDFVXT9N10D7","WKDFVXT9N10D8","WKDFVXT9N10D9","WKDFVXT9N11D1","WKDFVXT9N11D2","WKDFVXT9N11D3", & - "WKDFVXT9N11D4","WKDFVXT9N11D5","WKDFVXT9N11D6","WKDFVXT9N11D7","WKDFVXT9N11D8","WKDFVXT9N11D9","WKDFVXT9N12D1","WKDFVXT9N12D2", & - "WKDFVXT9N12D3","WKDFVXT9N12D4","WKDFVXT9N12D5","WKDFVXT9N12D6","WKDFVXT9N12D7","WKDFVXT9N12D8","WKDFVXT9N12D9","WKDFVXT9N13D1", & - "WKDFVXT9N13D2","WKDFVXT9N13D3","WKDFVXT9N13D4","WKDFVXT9N13D5","WKDFVXT9N13D6","WKDFVXT9N13D7","WKDFVXT9N13D8","WKDFVXT9N13D9", & - "WKDFVXT9N14D1","WKDFVXT9N14D2","WKDFVXT9N14D3","WKDFVXT9N14D4","WKDFVXT9N14D5","WKDFVXT9N14D6","WKDFVXT9N14D7","WKDFVXT9N14D8", & - "WKDFVXT9N14D9","WKDFVXT9N15D1","WKDFVXT9N15D2","WKDFVXT9N15D3","WKDFVXT9N15D4","WKDFVXT9N15D5","WKDFVXT9N15D6","WKDFVXT9N15D7", & - "WKDFVXT9N15D8","WKDFVXT9N15D9","WKDFVXT9N16D1","WKDFVXT9N16D2","WKDFVXT9N16D3","WKDFVXT9N16D4","WKDFVXT9N16D5","WKDFVXT9N16D6", & - "WKDFVXT9N16D7","WKDFVXT9N16D8","WKDFVXT9N16D9","WKDFVXT9N17D1","WKDFVXT9N17D2","WKDFVXT9N17D3","WKDFVXT9N17D4","WKDFVXT9N17D5", & - "WKDFVXT9N17D6","WKDFVXT9N17D7","WKDFVXT9N17D8","WKDFVXT9N17D9","WKDFVXT9N18D1","WKDFVXT9N18D2","WKDFVXT9N18D3","WKDFVXT9N18D4", & - "WKDFVXT9N18D5","WKDFVXT9N18D6","WKDFVXT9N18D7","WKDFVXT9N18D8","WKDFVXT9N18D9","WKDFVXT9N19D1","WKDFVXT9N19D2","WKDFVXT9N19D3", & - "WKDFVXT9N19D4","WKDFVXT9N19D5","WKDFVXT9N19D6","WKDFVXT9N19D7","WKDFVXT9N19D8","WKDFVXT9N19D9","WKDFVXT9N20D1","WKDFVXT9N20D2", & - "WKDFVXT9N20D3","WKDFVXT9N20D4","WKDFVXT9N20D5","WKDFVXT9N20D6","WKDFVXT9N20D7","WKDFVXT9N20D8","WKDFVXT9N20D9","WKDIAMT1D1 ", & - "WKDIAMT1D2 ","WKDIAMT1D3 ","WKDIAMT1D4 ","WKDIAMT1D5 ","WKDIAMT1D6 ","WKDIAMT1D7 ","WKDIAMT1D8 ","WKDIAMT1D9 ", & - "WKDIAMT2D1 ","WKDIAMT2D2 ","WKDIAMT2D3 ","WKDIAMT2D4 ","WKDIAMT2D5 ","WKDIAMT2D6 ","WKDIAMT2D7 ","WKDIAMT2D8 ", & - "WKDIAMT2D9 ","WKDIAMT3D1 ","WKDIAMT3D2 ","WKDIAMT3D3 ","WKDIAMT3D4 ","WKDIAMT3D5 ","WKDIAMT3D6 ","WKDIAMT3D7 ", & - "WKDIAMT3D8 ","WKDIAMT3D9 ","WKDIAMT4D1 ","WKDIAMT4D2 ","WKDIAMT4D3 ","WKDIAMT4D4 ","WKDIAMT4D5 ","WKDIAMT4D6 ", & - "WKDIAMT4D7 ","WKDIAMT4D8 ","WKDIAMT4D9 ","WKDIAMT5D1 ","WKDIAMT5D2 ","WKDIAMT5D3 ","WKDIAMT5D4 ","WKDIAMT5D5 ", & - "WKDIAMT5D6 ","WKDIAMT5D7 ","WKDIAMT5D8 ","WKDIAMT5D9 ","WKDIAMT6D1 ","WKDIAMT6D2 ","WKDIAMT6D3 ","WKDIAMT6D4 ", & - "WKDIAMT6D5 ","WKDIAMT6D6 ","WKDIAMT6D7 ","WKDIAMT6D8 ","WKDIAMT6D9 ","WKDIAMT7D1 ","WKDIAMT7D2 ","WKDIAMT7D3 ", & - "WKDIAMT7D4 ","WKDIAMT7D5 ","WKDIAMT7D6 ","WKDIAMT7D7 ","WKDIAMT7D8 ","WKDIAMT7D9 ","WKDIAMT8D1 ","WKDIAMT8D2 ", & - "WKDIAMT8D3 ","WKDIAMT8D4 ","WKDIAMT8D5 ","WKDIAMT8D6 ","WKDIAMT8D7 ","WKDIAMT8D8 ","WKDIAMT8D9 ","WKDIAMT9D1 ", & - "WKDIAMT9D2 ","WKDIAMT9D3 ","WKDIAMT9D4 ","WKDIAMT9D5 ","WKDIAMT9D6 ","WKDIAMT9D7 ","WKDIAMT9D8 ","WKDIAMT9D9 ", & - "WKPOSXT1D1 ","WKPOSXT1D2 ","WKPOSXT1D3 ","WKPOSXT1D4 ","WKPOSXT1D5 ","WKPOSXT1D6 ","WKPOSXT1D7 ","WKPOSXT1D8 ", & - "WKPOSXT1D9 ","WKPOSXT2D1 ","WKPOSXT2D2 ","WKPOSXT2D3 ","WKPOSXT2D4 ","WKPOSXT2D5 ","WKPOSXT2D6 ","WKPOSXT2D7 ", & - "WKPOSXT2D8 ","WKPOSXT2D9 ","WKPOSXT3D1 ","WKPOSXT3D2 ","WKPOSXT3D3 ","WKPOSXT3D4 ","WKPOSXT3D5 ","WKPOSXT3D6 ", & - "WKPOSXT3D7 ","WKPOSXT3D8 ","WKPOSXT3D9 ","WKPOSXT4D1 ","WKPOSXT4D2 ","WKPOSXT4D3 ","WKPOSXT4D4 ","WKPOSXT4D5 ", & - "WKPOSXT4D6 ","WKPOSXT4D7 ","WKPOSXT4D8 ","WKPOSXT4D9 ","WKPOSXT5D1 ","WKPOSXT5D2 ","WKPOSXT5D3 ","WKPOSXT5D4 ", & - "WKPOSXT5D5 ","WKPOSXT5D6 ","WKPOSXT5D7 ","WKPOSXT5D8 ","WKPOSXT5D9 ","WKPOSXT6D1 ","WKPOSXT6D2 ","WKPOSXT6D3 ", & - "WKPOSXT6D4 ","WKPOSXT6D5 ","WKPOSXT6D6 ","WKPOSXT6D7 ","WKPOSXT6D8 ","WKPOSXT6D9 ","WKPOSXT7D1 ","WKPOSXT7D2 ", & - "WKPOSXT7D3 ","WKPOSXT7D4 ","WKPOSXT7D5 ","WKPOSXT7D6 ","WKPOSXT7D7 ","WKPOSXT7D8 ","WKPOSXT7D9 ","WKPOSXT8D1 ", & - "WKPOSXT8D2 ","WKPOSXT8D3 ","WKPOSXT8D4 ","WKPOSXT8D5 ","WKPOSXT8D6 ","WKPOSXT8D7 ","WKPOSXT8D8 ","WKPOSXT8D9 ", & - "WKPOSXT9D1 ","WKPOSXT9D2 ","WKPOSXT9D3 ","WKPOSXT9D4 ","WKPOSXT9D5 ","WKPOSXT9D6 ","WKPOSXT9D7 ","WKPOSXT9D8 ", & - "WKPOSXT9D9 ","WKPOSYT1D1 ","WKPOSYT1D2 ","WKPOSYT1D3 ","WKPOSYT1D4 ","WKPOSYT1D5 ","WKPOSYT1D6 ","WKPOSYT1D7 ", & - "WKPOSYT1D8 ","WKPOSYT1D9 ","WKPOSYT2D1 ","WKPOSYT2D2 ","WKPOSYT2D3 ","WKPOSYT2D4 ","WKPOSYT2D5 ","WKPOSYT2D6 ", & - "WKPOSYT2D7 ","WKPOSYT2D8 ","WKPOSYT2D9 ","WKPOSYT3D1 ","WKPOSYT3D2 ","WKPOSYT3D3 ","WKPOSYT3D4 ","WKPOSYT3D5 ", & - "WKPOSYT3D6 ","WKPOSYT3D7 ","WKPOSYT3D8 ","WKPOSYT3D9 ","WKPOSYT4D1 ","WKPOSYT4D2 ","WKPOSYT4D3 ","WKPOSYT4D4 ", & - "WKPOSYT4D5 ","WKPOSYT4D6 ","WKPOSYT4D7 ","WKPOSYT4D8 ","WKPOSYT4D9 ","WKPOSYT5D1 ","WKPOSYT5D2 ","WKPOSYT5D3 ", & - "WKPOSYT5D4 ","WKPOSYT5D5 ","WKPOSYT5D6 ","WKPOSYT5D7 ","WKPOSYT5D8 ","WKPOSYT5D9 ","WKPOSYT6D1 ","WKPOSYT6D2 ", & - "WKPOSYT6D3 ","WKPOSYT6D4 ","WKPOSYT6D5 ","WKPOSYT6D6 ","WKPOSYT6D7 ","WKPOSYT6D8 ","WKPOSYT6D9 ","WKPOSYT7D1 ", & - "WKPOSYT7D2 ","WKPOSYT7D3 ","WKPOSYT7D4 ","WKPOSYT7D5 ","WKPOSYT7D6 ","WKPOSYT7D7 ","WKPOSYT7D8 ","WKPOSYT7D9 ", & - "WKPOSYT8D1 ","WKPOSYT8D2 ","WKPOSYT8D3 ","WKPOSYT8D4 ","WKPOSYT8D5 ","WKPOSYT8D6 ","WKPOSYT8D7 ","WKPOSYT8D8 ", & - "WKPOSYT8D9 ","WKPOSYT9D1 ","WKPOSYT9D2 ","WKPOSYT9D3 ","WKPOSYT9D4 ","WKPOSYT9D5 ","WKPOSYT9D6 ","WKPOSYT9D7 ", & - "WKPOSYT9D8 ","WKPOSYT9D9 ","WKPOSZT1D1 ","WKPOSZT1D2 ","WKPOSZT1D3 ","WKPOSZT1D4 ","WKPOSZT1D5 ","WKPOSZT1D6 ", & - "WKPOSZT1D7 ","WKPOSZT1D8 ","WKPOSZT1D9 ","WKPOSZT2D1 ","WKPOSZT2D2 ","WKPOSZT2D3 ","WKPOSZT2D4 ","WKPOSZT2D5 ", & - "WKPOSZT2D6 ","WKPOSZT2D7 ","WKPOSZT2D8 ","WKPOSZT2D9 ","WKPOSZT3D1 ","WKPOSZT3D2 ","WKPOSZT3D3 ","WKPOSZT3D4 ", & - "WKPOSZT3D5 ","WKPOSZT3D6 ","WKPOSZT3D7 ","WKPOSZT3D8 ","WKPOSZT3D9 ","WKPOSZT4D1 ","WKPOSZT4D2 ","WKPOSZT4D3 ", & - "WKPOSZT4D4 ","WKPOSZT4D5 ","WKPOSZT4D6 ","WKPOSZT4D7 ","WKPOSZT4D8 ","WKPOSZT4D9 ","WKPOSZT5D1 ","WKPOSZT5D2 ", & - "WKPOSZT5D3 ","WKPOSZT5D4 ","WKPOSZT5D5 ","WKPOSZT5D6 ","WKPOSZT5D7 ","WKPOSZT5D8 ","WKPOSZT5D9 ","WKPOSZT6D1 ", & - "WKPOSZT6D2 ","WKPOSZT6D3 ","WKPOSZT6D4 ","WKPOSZT6D5 ","WKPOSZT6D6 ","WKPOSZT6D7 ","WKPOSZT6D8 ","WKPOSZT6D9 ", & - "WKPOSZT7D1 ","WKPOSZT7D2 ","WKPOSZT7D3 ","WKPOSZT7D4 ","WKPOSZT7D5 ","WKPOSZT7D6 ","WKPOSZT7D7 ","WKPOSZT7D8 ", & - "WKPOSZT7D9 ","WKPOSZT8D1 ","WKPOSZT8D2 ","WKPOSZT8D3 ","WKPOSZT8D4 ","WKPOSZT8D5 ","WKPOSZT8D6 ","WKPOSZT8D7 ", & - "WKPOSZT8D8 ","WKPOSZT8D9 ","WKPOSZT9D1 ","WKPOSZT9D2 ","WKPOSZT9D3 ","WKPOSZT9D4 ","WKPOSZT9D5 ","WKPOSZT9D6 ", & - "WKPOSZT9D7 ","WKPOSZT9D8 ","WKPOSZT9D9 ","WKVELXT1D1 ","WKVELXT1D2 ","WKVELXT1D3 ","WKVELXT1D4 ","WKVELXT1D5 ", & - "WKVELXT1D6 ","WKVELXT1D7 ","WKVELXT1D8 ","WKVELXT1D9 ","WKVELXT2D1 ","WKVELXT2D2 ","WKVELXT2D3 ","WKVELXT2D4 ", & - "WKVELXT2D5 ","WKVELXT2D6 ","WKVELXT2D7 ","WKVELXT2D8 ","WKVELXT2D9 ","WKVELXT3D1 ","WKVELXT3D2 ","WKVELXT3D3 ", & - "WKVELXT3D4 ","WKVELXT3D5 ","WKVELXT3D6 ","WKVELXT3D7 ","WKVELXT3D8 ","WKVELXT3D9 ","WKVELXT4D1 ","WKVELXT4D2 ", & - "WKVELXT4D3 ","WKVELXT4D4 ","WKVELXT4D5 ","WKVELXT4D6 ","WKVELXT4D7 ","WKVELXT4D8 ","WKVELXT4D9 ","WKVELXT5D1 ", & - "WKVELXT5D2 ","WKVELXT5D3 ","WKVELXT5D4 ","WKVELXT5D5 ","WKVELXT5D6 ","WKVELXT5D7 ","WKVELXT5D8 ","WKVELXT5D9 ", & - "WKVELXT6D1 ","WKVELXT6D2 ","WKVELXT6D3 ","WKVELXT6D4 ","WKVELXT6D5 ","WKVELXT6D6 ","WKVELXT6D7 ","WKVELXT6D8 ", & - "WKVELXT6D9 ","WKVELXT7D1 ","WKVELXT7D2 ","WKVELXT7D3 ","WKVELXT7D4 ","WKVELXT7D5 ","WKVELXT7D6 ","WKVELXT7D7 ", & - "WKVELXT7D8 ","WKVELXT7D9 ","WKVELXT8D1 ","WKVELXT8D2 ","WKVELXT8D3 ","WKVELXT8D4 ","WKVELXT8D5 ","WKVELXT8D6 ", & - "WKVELXT8D7 ","WKVELXT8D8 ","WKVELXT8D9 ","WKVELXT9D1 ","WKVELXT9D2 ","WKVELXT9D3 ","WKVELXT9D4 ","WKVELXT9D5 ", & - "WKVELXT9D6 ","WKVELXT9D7 ","WKVELXT9D8 ","WKVELXT9D9 ","WKVELYT1D1 ","WKVELYT1D2 ","WKVELYT1D3 ","WKVELYT1D4 ", & - "WKVELYT1D5 ","WKVELYT1D6 ","WKVELYT1D7 ","WKVELYT1D8 ","WKVELYT1D9 ","WKVELYT2D1 ","WKVELYT2D2 ","WKVELYT2D3 ", & - "WKVELYT2D4 ","WKVELYT2D5 ","WKVELYT2D6 ","WKVELYT2D7 ","WKVELYT2D8 ","WKVELYT2D9 ","WKVELYT3D1 ","WKVELYT3D2 ", & - "WKVELYT3D3 ","WKVELYT3D4 ","WKVELYT3D5 ","WKVELYT3D6 ","WKVELYT3D7 ","WKVELYT3D8 ","WKVELYT3D9 ","WKVELYT4D1 ", & - "WKVELYT4D2 ","WKVELYT4D3 ","WKVELYT4D4 ","WKVELYT4D5 ","WKVELYT4D6 ","WKVELYT4D7 ","WKVELYT4D8 ","WKVELYT4D9 ", & - "WKVELYT5D1 ","WKVELYT5D2 ","WKVELYT5D3 ","WKVELYT5D4 ","WKVELYT5D5 ","WKVELYT5D6 ","WKVELYT5D7 ","WKVELYT5D8 ", & - "WKVELYT5D9 ","WKVELYT6D1 ","WKVELYT6D2 ","WKVELYT6D3 ","WKVELYT6D4 ","WKVELYT6D5 ","WKVELYT6D6 ","WKVELYT6D7 ", & - "WKVELYT6D8 ","WKVELYT6D9 ","WKVELYT7D1 ","WKVELYT7D2 ","WKVELYT7D3 ","WKVELYT7D4 ","WKVELYT7D5 ","WKVELYT7D6 ", & - "WKVELYT7D7 ","WKVELYT7D8 ","WKVELYT7D9 ","WKVELYT8D1 ","WKVELYT8D2 ","WKVELYT8D3 ","WKVELYT8D4 ","WKVELYT8D5 ", & - "WKVELYT8D6 ","WKVELYT8D7 ","WKVELYT8D8 ","WKVELYT8D9 ","WKVELYT9D1 ","WKVELYT9D2 ","WKVELYT9D3 ","WKVELYT9D4 ", & - "WKVELYT9D5 ","WKVELYT9D6 ","WKVELYT9D7 ","WKVELYT9D8 ","WKVELYT9D9 ","WKVELZT1D1 ","WKVELZT1D2 ","WKVELZT1D3 ", & - "WKVELZT1D4 ","WKVELZT1D5 ","WKVELZT1D6 ","WKVELZT1D7 ","WKVELZT1D8 ","WKVELZT1D9 ","WKVELZT2D1 ","WKVELZT2D2 ", & - "WKVELZT2D3 ","WKVELZT2D4 ","WKVELZT2D5 ","WKVELZT2D6 ","WKVELZT2D7 ","WKVELZT2D8 ","WKVELZT2D9 ","WKVELZT3D1 ", & - "WKVELZT3D2 ","WKVELZT3D3 ","WKVELZT3D4 ","WKVELZT3D5 ","WKVELZT3D6 ","WKVELZT3D7 ","WKVELZT3D8 ","WKVELZT3D9 ", & - "WKVELZT4D1 ","WKVELZT4D2 ","WKVELZT4D3 ","WKVELZT4D4 ","WKVELZT4D5 ","WKVELZT4D6 ","WKVELZT4D7 ","WKVELZT4D8 ", & - "WKVELZT4D9 ","WKVELZT5D1 ","WKVELZT5D2 ","WKVELZT5D3 ","WKVELZT5D4 ","WKVELZT5D5 ","WKVELZT5D6 ","WKVELZT5D7 ", & - "WKVELZT5D8 ","WKVELZT5D9 ","WKVELZT6D1 ","WKVELZT6D2 ","WKVELZT6D3 ","WKVELZT6D4 ","WKVELZT6D5 ","WKVELZT6D6 ", & - "WKVELZT6D7 ","WKVELZT6D8 ","WKVELZT6D9 ","WKVELZT7D1 ","WKVELZT7D2 ","WKVELZT7D3 ","WKVELZT7D4 ","WKVELZT7D5 ", & - "WKVELZT7D6 ","WKVELZT7D7 ","WKVELZT7D8 ","WKVELZT7D9 ","WKVELZT8D1 ","WKVELZT8D2 ","WKVELZT8D3 ","WKVELZT8D4 ", & - "WKVELZT8D5 ","WKVELZT8D6 ","WKVELZT8D7 ","WKVELZT8D8 ","WKVELZT8D9 ","WKVELZT9D1 ","WKVELZT9D2 ","WKVELZT9D3 ", & - "WKVELZT9D4 ","WKVELZT9D5 ","WKVELZT9D6 ","WKVELZT9D7 ","WKVELZT9D8 ","WKVELZT9D9 ","YAWERRT1 ","YAWERRT2 ", & - "YAWERRT3 ","YAWERRT4 ","YAWERRT5 ","YAWERRT6 ","YAWERRT7 ","YAWERRT8 ","YAWERRT9 "/) - ParamIndxAry(1:2040) = (/ & - CtT1N01 , CtT1N02 , CtT1N03 , CtT1N04 , CtT1N05 , CtT1N06 , CtT1N07 , CtT1N08 , & - CtT1N09 , CtT1N10 , CtT1N11 , CtT1N12 , CtT1N13 , CtT1N14 , CtT1N15 , CtT1N16 , & - CtT1N17 , CtT1N18 , CtT1N19 , CtT1N20 , CtT2N01 , CtT2N02 , CtT2N03 , CtT2N04 , & - CtT2N05 , CtT2N06 , CtT2N07 , CtT2N08 , CtT2N09 , CtT2N10 , CtT2N11 , CtT2N12 , & - CtT2N13 , CtT2N14 , CtT2N15 , CtT2N16 , CtT2N17 , CtT2N18 , CtT2N19 , CtT2N20 , & - CtT3N01 , CtT3N02 , CtT3N03 , CtT3N04 , CtT3N05 , CtT3N06 , CtT3N07 , CtT3N08 , & - CtT3N09 , CtT3N10 , CtT3N11 , CtT3N12 , CtT3N13 , CtT3N14 , CtT3N15 , CtT3N16 , & - CtT3N17 , CtT3N18 , CtT3N19 , CtT3N20 , CtT4N01 , CtT4N02 , CtT4N03 , CtT4N04 , & - CtT4N05 , CtT4N06 , CtT4N07 , CtT4N08 , CtT4N09 , CtT4N10 , CtT4N11 , CtT4N12 , & - CtT4N13 , CtT4N14 , CtT4N15 , CtT4N16 , CtT4N17 , CtT4N18 , CtT4N19 , CtT4N20 , & - CtT5N01 , CtT5N02 , CtT5N03 , CtT5N04 , CtT5N05 , CtT5N06 , CtT5N07 , CtT5N08 , & - CtT5N09 , CtT5N10 , CtT5N11 , CtT5N12 , CtT5N13 , CtT5N14 , CtT5N15 , CtT5N16 , & - CtT5N17 , CtT5N18 , CtT5N19 , CtT5N20 , CtT6N01 , CtT6N02 , CtT6N03 , CtT6N04 , & - CtT6N05 , CtT6N06 , CtT6N07 , CtT6N08 , CtT6N09 , CtT6N10 , CtT6N11 , CtT6N12 , & - CtT6N13 , CtT6N14 , CtT6N15 , CtT6N16 , CtT6N17 , CtT6N18 , CtT6N19 , CtT6N20 , & - CtT7N01 , CtT7N02 , CtT7N03 , CtT7N04 , CtT7N05 , CtT7N06 , CtT7N07 , CtT7N08 , & - CtT7N09 , CtT7N10 , CtT7N11 , CtT7N12 , CtT7N13 , CtT7N14 , CtT7N15 , CtT7N16 , & - CtT7N17 , CtT7N18 , CtT7N19 , CtT7N20 , CtT8N01 , CtT8N02 , CtT8N03 , CtT8N04 , & - CtT8N05 , CtT8N06 , CtT8N07 , CtT8N08 , CtT8N09 , CtT8N10 , CtT8N11 , CtT8N12 , & - CtT8N13 , CtT8N14 , CtT8N15 , CtT8N16 , CtT8N17 , CtT8N18 , CtT8N19 , CtT8N20 , & - CtT9N01 , CtT9N02 , CtT9N03 , CtT9N04 , CtT9N05 , CtT9N06 , CtT9N07 , CtT9N08 , & - CtT9N09 , CtT9N10 , CtT9N11 , CtT9N12 , CtT9N13 , CtT9N14 , CtT9N15 , CtT9N16 , & - CtT9N17 , CtT9N18 , CtT9N19 , CtT9N20 , EddAmbT1N01D1 , EddAmbT1N01D2 , EddAmbT1N01D3 , EddAmbT1N01D4 , & - EddAmbT1N01D5 , EddAmbT1N01D6 , EddAmbT1N01D7 , EddAmbT1N01D8 , EddAmbT1N01D9 , EddAmbT1N02D1 , EddAmbT1N02D2 , EddAmbT1N02D3 , & - EddAmbT1N02D4 , EddAmbT1N02D5 , EddAmbT1N02D6 , EddAmbT1N02D7 , EddAmbT1N02D8 , EddAmbT1N02D9 , EddAmbT1N03D1 , EddAmbT1N03D2 , & - EddAmbT1N03D3 , EddAmbT1N03D4 , EddAmbT1N03D5 , EddAmbT1N03D6 , EddAmbT1N03D7 , EddAmbT1N03D8 , EddAmbT1N03D9 , EddAmbT1N04D1 , & - EddAmbT1N04D2 , EddAmbT1N04D3 , EddAmbT1N04D4 , EddAmbT1N04D5 , EddAmbT1N04D6 , EddAmbT1N04D7 , EddAmbT1N04D8 , EddAmbT1N04D9 , & - EddAmbT1N05D1 , EddAmbT1N05D2 , EddAmbT1N05D3 , EddAmbT1N05D4 , EddAmbT1N05D5 , EddAmbT1N05D6 , EddAmbT1N05D7 , EddAmbT1N05D8 , & - EddAmbT1N05D9 , EddAmbT1N06D1 , EddAmbT1N06D2 , EddAmbT1N06D3 , EddAmbT1N06D4 , EddAmbT1N06D5 , EddAmbT1N06D6 , EddAmbT1N06D7 , & - EddAmbT1N06D8 , EddAmbT1N06D9 , EddAmbT1N07D1 , EddAmbT1N07D2 , EddAmbT1N07D3 , EddAmbT1N07D4 , EddAmbT1N07D5 , EddAmbT1N07D6 , & - EddAmbT1N07D7 , EddAmbT1N07D8 , EddAmbT1N07D9 , EddAmbT1N08D1 , EddAmbT1N08D2 , EddAmbT1N08D3 , EddAmbT1N08D4 , EddAmbT1N08D5 , & - EddAmbT1N08D6 , EddAmbT1N08D7 , EddAmbT1N08D8 , EddAmbT1N08D9 , EddAmbT1N09D1 , EddAmbT1N09D2 , EddAmbT1N09D3 , EddAmbT1N09D4 , & - EddAmbT1N09D5 , EddAmbT1N09D6 , EddAmbT1N09D7 , EddAmbT1N09D8 , EddAmbT1N09D9 , EddAmbT1N10D1 , EddAmbT1N10D2 , EddAmbT1N10D3 , & - EddAmbT1N10D4 , EddAmbT1N10D5 , EddAmbT1N10D6 , EddAmbT1N10D7 , EddAmbT1N10D8 , EddAmbT1N10D9 , EddAmbT1N11D1 , EddAmbT1N11D2 , & - EddAmbT1N11D3 , EddAmbT1N11D4 , EddAmbT1N11D5 , EddAmbT1N11D6 , EddAmbT1N11D7 , EddAmbT1N11D8 , EddAmbT1N11D9 , EddAmbT1N12D1 , & - EddAmbT1N12D2 , EddAmbT1N12D3 , EddAmbT1N12D4 , EddAmbT1N12D5 , EddAmbT1N12D6 , EddAmbT1N12D7 , EddAmbT1N12D8 , EddAmbT1N12D9 , & - EddAmbT1N13D1 , EddAmbT1N13D2 , EddAmbT1N13D3 , EddAmbT1N13D4 , EddAmbT1N13D5 , EddAmbT1N13D6 , EddAmbT1N13D7 , EddAmbT1N13D8 , & - EddAmbT1N13D9 , EddAmbT1N14D1 , EddAmbT1N14D2 , EddAmbT1N14D3 , EddAmbT1N14D4 , EddAmbT1N14D5 , EddAmbT1N14D6 , EddAmbT1N14D7 , & - EddAmbT1N14D8 , EddAmbT1N14D9 , EddAmbT1N15D1 , EddAmbT1N15D2 , EddAmbT1N15D3 , EddAmbT1N15D4 , EddAmbT1N15D5 , EddAmbT1N15D6 , & - EddAmbT1N15D7 , EddAmbT1N15D8 , EddAmbT1N15D9 , EddAmbT1N16D1 , EddAmbT1N16D2 , EddAmbT1N16D3 , EddAmbT1N16D4 , EddAmbT1N16D5 , & - EddAmbT1N16D6 , EddAmbT1N16D7 , EddAmbT1N16D8 , EddAmbT1N16D9 , EddAmbT1N17D1 , EddAmbT1N17D2 , EddAmbT1N17D3 , EddAmbT1N17D4 , & - EddAmbT1N17D5 , EddAmbT1N17D6 , EddAmbT1N17D7 , EddAmbT1N17D8 , EddAmbT1N17D9 , EddAmbT1N18D1 , EddAmbT1N18D2 , EddAmbT1N18D3 , & - EddAmbT1N18D4 , EddAmbT1N18D5 , EddAmbT1N18D6 , EddAmbT1N18D7 , EddAmbT1N18D8 , EddAmbT1N18D9 , EddAmbT1N19D1 , EddAmbT1N19D2 , & - EddAmbT1N19D3 , EddAmbT1N19D4 , EddAmbT1N19D5 , EddAmbT1N19D6 , EddAmbT1N19D7 , EddAmbT1N19D8 , EddAmbT1N19D9 , EddAmbT1N20D1 , & - EddAmbT1N20D2 , EddAmbT1N20D3 , EddAmbT1N20D4 , EddAmbT1N20D5 , EddAmbT1N20D6 , EddAmbT1N20D7 , EddAmbT1N20D8 , EddAmbT1N20D9 , & - EddAmbT2N01D1 , EddAmbT2N01D2 , EddAmbT2N01D3 , EddAmbT2N01D4 , EddAmbT2N01D5 , EddAmbT2N01D6 , EddAmbT2N01D7 , EddAmbT2N01D8 , & - EddAmbT2N01D9 , EddAmbT2N02D1 , EddAmbT2N02D2 , EddAmbT2N02D3 , EddAmbT2N02D4 , EddAmbT2N02D5 , EddAmbT2N02D6 , EddAmbT2N02D7 , & - EddAmbT2N02D8 , EddAmbT2N02D9 , EddAmbT2N03D1 , EddAmbT2N03D2 , EddAmbT2N03D3 , EddAmbT2N03D4 , EddAmbT2N03D5 , EddAmbT2N03D6 , & - EddAmbT2N03D7 , EddAmbT2N03D8 , EddAmbT2N03D9 , EddAmbT2N04D1 , EddAmbT2N04D2 , EddAmbT2N04D3 , EddAmbT2N04D4 , EddAmbT2N04D5 , & - EddAmbT2N04D6 , EddAmbT2N04D7 , EddAmbT2N04D8 , EddAmbT2N04D9 , EddAmbT2N05D1 , EddAmbT2N05D2 , EddAmbT2N05D3 , EddAmbT2N05D4 , & - EddAmbT2N05D5 , EddAmbT2N05D6 , EddAmbT2N05D7 , EddAmbT2N05D8 , EddAmbT2N05D9 , EddAmbT2N06D1 , EddAmbT2N06D2 , EddAmbT2N06D3 , & - EddAmbT2N06D4 , EddAmbT2N06D5 , EddAmbT2N06D6 , EddAmbT2N06D7 , EddAmbT2N06D8 , EddAmbT2N06D9 , EddAmbT2N07D1 , EddAmbT2N07D2 , & - EddAmbT2N07D3 , EddAmbT2N07D4 , EddAmbT2N07D5 , EddAmbT2N07D6 , EddAmbT2N07D7 , EddAmbT2N07D8 , EddAmbT2N07D9 , EddAmbT2N08D1 , & - EddAmbT2N08D2 , EddAmbT2N08D3 , EddAmbT2N08D4 , EddAmbT2N08D5 , EddAmbT2N08D6 , EddAmbT2N08D7 , EddAmbT2N08D8 , EddAmbT2N08D9 , & - EddAmbT2N09D1 , EddAmbT2N09D2 , EddAmbT2N09D3 , EddAmbT2N09D4 , EddAmbT2N09D5 , EddAmbT2N09D6 , EddAmbT2N09D7 , EddAmbT2N09D8 , & - EddAmbT2N09D9 , EddAmbT2N10D1 , EddAmbT2N10D2 , EddAmbT2N10D3 , EddAmbT2N10D4 , EddAmbT2N10D5 , EddAmbT2N10D6 , EddAmbT2N10D7 , & - EddAmbT2N10D8 , EddAmbT2N10D9 , EddAmbT2N11D1 , EddAmbT2N11D2 , EddAmbT2N11D3 , EddAmbT2N11D4 , EddAmbT2N11D5 , EddAmbT2N11D6 , & - EddAmbT2N11D7 , EddAmbT2N11D8 , EddAmbT2N11D9 , EddAmbT2N12D1 , EddAmbT2N12D2 , EddAmbT2N12D3 , EddAmbT2N12D4 , EddAmbT2N12D5 , & - EddAmbT2N12D6 , EddAmbT2N12D7 , EddAmbT2N12D8 , EddAmbT2N12D9 , EddAmbT2N13D1 , EddAmbT2N13D2 , EddAmbT2N13D3 , EddAmbT2N13D4 , & - EddAmbT2N13D5 , EddAmbT2N13D6 , EddAmbT2N13D7 , EddAmbT2N13D8 , EddAmbT2N13D9 , EddAmbT2N14D1 , EddAmbT2N14D2 , EddAmbT2N14D3 , & - EddAmbT2N14D4 , EddAmbT2N14D5 , EddAmbT2N14D6 , EddAmbT2N14D7 , EddAmbT2N14D8 , EddAmbT2N14D9 , EddAmbT2N15D1 , EddAmbT2N15D2 , & - EddAmbT2N15D3 , EddAmbT2N15D4 , EddAmbT2N15D5 , EddAmbT2N15D6 , EddAmbT2N15D7 , EddAmbT2N15D8 , EddAmbT2N15D9 , EddAmbT2N16D1 , & - EddAmbT2N16D2 , EddAmbT2N16D3 , EddAmbT2N16D4 , EddAmbT2N16D5 , EddAmbT2N16D6 , EddAmbT2N16D7 , EddAmbT2N16D8 , EddAmbT2N16D9 , & - EddAmbT2N17D1 , EddAmbT2N17D2 , EddAmbT2N17D3 , EddAmbT2N17D4 , EddAmbT2N17D5 , EddAmbT2N17D6 , EddAmbT2N17D7 , EddAmbT2N17D8 , & - EddAmbT2N17D9 , EddAmbT2N18D1 , EddAmbT2N18D2 , EddAmbT2N18D3 , EddAmbT2N18D4 , EddAmbT2N18D5 , EddAmbT2N18D6 , EddAmbT2N18D7 , & - EddAmbT2N18D8 , EddAmbT2N18D9 , EddAmbT2N19D1 , EddAmbT2N19D2 , EddAmbT2N19D3 , EddAmbT2N19D4 , EddAmbT2N19D5 , EddAmbT2N19D6 , & - EddAmbT2N19D7 , EddAmbT2N19D8 , EddAmbT2N19D9 , EddAmbT2N20D1 , EddAmbT2N20D2 , EddAmbT2N20D3 , EddAmbT2N20D4 , EddAmbT2N20D5 , & - EddAmbT2N20D6 , EddAmbT2N20D7 , EddAmbT2N20D8 , EddAmbT2N20D9 , EddAmbT3N01D1 , EddAmbT3N01D2 , EddAmbT3N01D3 , EddAmbT3N01D4 , & - EddAmbT3N01D5 , EddAmbT3N01D6 , EddAmbT3N01D7 , EddAmbT3N01D8 , EddAmbT3N01D9 , EddAmbT3N02D1 , EddAmbT3N02D2 , EddAmbT3N02D3 , & - EddAmbT3N02D4 , EddAmbT3N02D5 , EddAmbT3N02D6 , EddAmbT3N02D7 , EddAmbT3N02D8 , EddAmbT3N02D9 , EddAmbT3N03D1 , EddAmbT3N03D2 , & - EddAmbT3N03D3 , EddAmbT3N03D4 , EddAmbT3N03D5 , EddAmbT3N03D6 , EddAmbT3N03D7 , EddAmbT3N03D8 , EddAmbT3N03D9 , EddAmbT3N04D1 , & - EddAmbT3N04D2 , EddAmbT3N04D3 , EddAmbT3N04D4 , EddAmbT3N04D5 , EddAmbT3N04D6 , EddAmbT3N04D7 , EddAmbT3N04D8 , EddAmbT3N04D9 , & - EddAmbT3N05D1 , EddAmbT3N05D2 , EddAmbT3N05D3 , EddAmbT3N05D4 , EddAmbT3N05D5 , EddAmbT3N05D6 , EddAmbT3N05D7 , EddAmbT3N05D8 , & - EddAmbT3N05D9 , EddAmbT3N06D1 , EddAmbT3N06D2 , EddAmbT3N06D3 , EddAmbT3N06D4 , EddAmbT3N06D5 , EddAmbT3N06D6 , EddAmbT3N06D7 , & - EddAmbT3N06D8 , EddAmbT3N06D9 , EddAmbT3N07D1 , EddAmbT3N07D2 , EddAmbT3N07D3 , EddAmbT3N07D4 , EddAmbT3N07D5 , EddAmbT3N07D6 , & - EddAmbT3N07D7 , EddAmbT3N07D8 , EddAmbT3N07D9 , EddAmbT3N08D1 , EddAmbT3N08D2 , EddAmbT3N08D3 , EddAmbT3N08D4 , EddAmbT3N08D5 , & - EddAmbT3N08D6 , EddAmbT3N08D7 , EddAmbT3N08D8 , EddAmbT3N08D9 , EddAmbT3N09D1 , EddAmbT3N09D2 , EddAmbT3N09D3 , EddAmbT3N09D4 , & - EddAmbT3N09D5 , EddAmbT3N09D6 , EddAmbT3N09D7 , EddAmbT3N09D8 , EddAmbT3N09D9 , EddAmbT3N10D1 , EddAmbT3N10D2 , EddAmbT3N10D3 , & - EddAmbT3N10D4 , EddAmbT3N10D5 , EddAmbT3N10D6 , EddAmbT3N10D7 , EddAmbT3N10D8 , EddAmbT3N10D9 , EddAmbT3N11D1 , EddAmbT3N11D2 , & - EddAmbT3N11D3 , EddAmbT3N11D4 , EddAmbT3N11D5 , EddAmbT3N11D6 , EddAmbT3N11D7 , EddAmbT3N11D8 , EddAmbT3N11D9 , EddAmbT3N12D1 , & - EddAmbT3N12D2 , EddAmbT3N12D3 , EddAmbT3N12D4 , EddAmbT3N12D5 , EddAmbT3N12D6 , EddAmbT3N12D7 , EddAmbT3N12D8 , EddAmbT3N12D9 , & - EddAmbT3N13D1 , EddAmbT3N13D2 , EddAmbT3N13D3 , EddAmbT3N13D4 , EddAmbT3N13D5 , EddAmbT3N13D6 , EddAmbT3N13D7 , EddAmbT3N13D8 , & - EddAmbT3N13D9 , EddAmbT3N14D1 , EddAmbT3N14D2 , EddAmbT3N14D3 , EddAmbT3N14D4 , EddAmbT3N14D5 , EddAmbT3N14D6 , EddAmbT3N14D7 , & - EddAmbT3N14D8 , EddAmbT3N14D9 , EddAmbT3N15D1 , EddAmbT3N15D2 , EddAmbT3N15D3 , EddAmbT3N15D4 , EddAmbT3N15D5 , EddAmbT3N15D6 , & - EddAmbT3N15D7 , EddAmbT3N15D8 , EddAmbT3N15D9 , EddAmbT3N16D1 , EddAmbT3N16D2 , EddAmbT3N16D3 , EddAmbT3N16D4 , EddAmbT3N16D5 , & - EddAmbT3N16D6 , EddAmbT3N16D7 , EddAmbT3N16D8 , EddAmbT3N16D9 , EddAmbT3N17D1 , EddAmbT3N17D2 , EddAmbT3N17D3 , EddAmbT3N17D4 , & - EddAmbT3N17D5 , EddAmbT3N17D6 , EddAmbT3N17D7 , EddAmbT3N17D8 , EddAmbT3N17D9 , EddAmbT3N18D1 , EddAmbT3N18D2 , EddAmbT3N18D3 , & - EddAmbT3N18D4 , EddAmbT3N18D5 , EddAmbT3N18D6 , EddAmbT3N18D7 , EddAmbT3N18D8 , EddAmbT3N18D9 , EddAmbT3N19D1 , EddAmbT3N19D2 , & - EddAmbT3N19D3 , EddAmbT3N19D4 , EddAmbT3N19D5 , EddAmbT3N19D6 , EddAmbT3N19D7 , EddAmbT3N19D8 , EddAmbT3N19D9 , EddAmbT3N20D1 , & - EddAmbT3N20D2 , EddAmbT3N20D3 , EddAmbT3N20D4 , EddAmbT3N20D5 , EddAmbT3N20D6 , EddAmbT3N20D7 , EddAmbT3N20D8 , EddAmbT3N20D9 , & - EddAmbT4N01D1 , EddAmbT4N01D2 , EddAmbT4N01D3 , EddAmbT4N01D4 , EddAmbT4N01D5 , EddAmbT4N01D6 , EddAmbT4N01D7 , EddAmbT4N01D8 , & - EddAmbT4N01D9 , EddAmbT4N02D1 , EddAmbT4N02D2 , EddAmbT4N02D3 , EddAmbT4N02D4 , EddAmbT4N02D5 , EddAmbT4N02D6 , EddAmbT4N02D7 , & - EddAmbT4N02D8 , EddAmbT4N02D9 , EddAmbT4N03D1 , EddAmbT4N03D2 , EddAmbT4N03D3 , EddAmbT4N03D4 , EddAmbT4N03D5 , EddAmbT4N03D6 , & - EddAmbT4N03D7 , EddAmbT4N03D8 , EddAmbT4N03D9 , EddAmbT4N04D1 , EddAmbT4N04D2 , EddAmbT4N04D3 , EddAmbT4N04D4 , EddAmbT4N04D5 , & - EddAmbT4N04D6 , EddAmbT4N04D7 , EddAmbT4N04D8 , EddAmbT4N04D9 , EddAmbT4N05D1 , EddAmbT4N05D2 , EddAmbT4N05D3 , EddAmbT4N05D4 , & - EddAmbT4N05D5 , EddAmbT4N05D6 , EddAmbT4N05D7 , EddAmbT4N05D8 , EddAmbT4N05D9 , EddAmbT4N06D1 , EddAmbT4N06D2 , EddAmbT4N06D3 , & - EddAmbT4N06D4 , EddAmbT4N06D5 , EddAmbT4N06D6 , EddAmbT4N06D7 , EddAmbT4N06D8 , EddAmbT4N06D9 , EddAmbT4N07D1 , EddAmbT4N07D2 , & - EddAmbT4N07D3 , EddAmbT4N07D4 , EddAmbT4N07D5 , EddAmbT4N07D6 , EddAmbT4N07D7 , EddAmbT4N07D8 , EddAmbT4N07D9 , EddAmbT4N08D1 , & - EddAmbT4N08D2 , EddAmbT4N08D3 , EddAmbT4N08D4 , EddAmbT4N08D5 , EddAmbT4N08D6 , EddAmbT4N08D7 , EddAmbT4N08D8 , EddAmbT4N08D9 , & - EddAmbT4N09D1 , EddAmbT4N09D2 , EddAmbT4N09D3 , EddAmbT4N09D4 , EddAmbT4N09D5 , EddAmbT4N09D6 , EddAmbT4N09D7 , EddAmbT4N09D8 , & - EddAmbT4N09D9 , EddAmbT4N10D1 , EddAmbT4N10D2 , EddAmbT4N10D3 , EddAmbT4N10D4 , EddAmbT4N10D5 , EddAmbT4N10D6 , EddAmbT4N10D7 , & - EddAmbT4N10D8 , EddAmbT4N10D9 , EddAmbT4N11D1 , EddAmbT4N11D2 , EddAmbT4N11D3 , EddAmbT4N11D4 , EddAmbT4N11D5 , EddAmbT4N11D6 , & - EddAmbT4N11D7 , EddAmbT4N11D8 , EddAmbT4N11D9 , EddAmbT4N12D1 , EddAmbT4N12D2 , EddAmbT4N12D3 , EddAmbT4N12D4 , EddAmbT4N12D5 , & - EddAmbT4N12D6 , EddAmbT4N12D7 , EddAmbT4N12D8 , EddAmbT4N12D9 , EddAmbT4N13D1 , EddAmbT4N13D2 , EddAmbT4N13D3 , EddAmbT4N13D4 , & - EddAmbT4N13D5 , EddAmbT4N13D6 , EddAmbT4N13D7 , EddAmbT4N13D8 , EddAmbT4N13D9 , EddAmbT4N14D1 , EddAmbT4N14D2 , EddAmbT4N14D3 , & - EddAmbT4N14D4 , EddAmbT4N14D5 , EddAmbT4N14D6 , EddAmbT4N14D7 , EddAmbT4N14D8 , EddAmbT4N14D9 , EddAmbT4N15D1 , EddAmbT4N15D2 , & - EddAmbT4N15D3 , EddAmbT4N15D4 , EddAmbT4N15D5 , EddAmbT4N15D6 , EddAmbT4N15D7 , EddAmbT4N15D8 , EddAmbT4N15D9 , EddAmbT4N16D1 , & - EddAmbT4N16D2 , EddAmbT4N16D3 , EddAmbT4N16D4 , EddAmbT4N16D5 , EddAmbT4N16D6 , EddAmbT4N16D7 , EddAmbT4N16D8 , EddAmbT4N16D9 , & - EddAmbT4N17D1 , EddAmbT4N17D2 , EddAmbT4N17D3 , EddAmbT4N17D4 , EddAmbT4N17D5 , EddAmbT4N17D6 , EddAmbT4N17D7 , EddAmbT4N17D8 , & - EddAmbT4N17D9 , EddAmbT4N18D1 , EddAmbT4N18D2 , EddAmbT4N18D3 , EddAmbT4N18D4 , EddAmbT4N18D5 , EddAmbT4N18D6 , EddAmbT4N18D7 , & - EddAmbT4N18D8 , EddAmbT4N18D9 , EddAmbT4N19D1 , EddAmbT4N19D2 , EddAmbT4N19D3 , EddAmbT4N19D4 , EddAmbT4N19D5 , EddAmbT4N19D6 , & - EddAmbT4N19D7 , EddAmbT4N19D8 , EddAmbT4N19D9 , EddAmbT4N20D1 , EddAmbT4N20D2 , EddAmbT4N20D3 , EddAmbT4N20D4 , EddAmbT4N20D5 , & - EddAmbT4N20D6 , EddAmbT4N20D7 , EddAmbT4N20D8 , EddAmbT4N20D9 , EddAmbT5N01D1 , EddAmbT5N01D2 , EddAmbT5N01D3 , EddAmbT5N01D4 , & - EddAmbT5N01D5 , EddAmbT5N01D6 , EddAmbT5N01D7 , EddAmbT5N01D8 , EddAmbT5N01D9 , EddAmbT5N02D1 , EddAmbT5N02D2 , EddAmbT5N02D3 , & - EddAmbT5N02D4 , EddAmbT5N02D5 , EddAmbT5N02D6 , EddAmbT5N02D7 , EddAmbT5N02D8 , EddAmbT5N02D9 , EddAmbT5N03D1 , EddAmbT5N03D2 , & - EddAmbT5N03D3 , EddAmbT5N03D4 , EddAmbT5N03D5 , EddAmbT5N03D6 , EddAmbT5N03D7 , EddAmbT5N03D8 , EddAmbT5N03D9 , EddAmbT5N04D1 , & - EddAmbT5N04D2 , EddAmbT5N04D3 , EddAmbT5N04D4 , EddAmbT5N04D5 , EddAmbT5N04D6 , EddAmbT5N04D7 , EddAmbT5N04D8 , EddAmbT5N04D9 , & - EddAmbT5N05D1 , EddAmbT5N05D2 , EddAmbT5N05D3 , EddAmbT5N05D4 , EddAmbT5N05D5 , EddAmbT5N05D6 , EddAmbT5N05D7 , EddAmbT5N05D8 , & - EddAmbT5N05D9 , EddAmbT5N06D1 , EddAmbT5N06D2 , EddAmbT5N06D3 , EddAmbT5N06D4 , EddAmbT5N06D5 , EddAmbT5N06D6 , EddAmbT5N06D7 , & - EddAmbT5N06D8 , EddAmbT5N06D9 , EddAmbT5N07D1 , EddAmbT5N07D2 , EddAmbT5N07D3 , EddAmbT5N07D4 , EddAmbT5N07D5 , EddAmbT5N07D6 , & - EddAmbT5N07D7 , EddAmbT5N07D8 , EddAmbT5N07D9 , EddAmbT5N08D1 , EddAmbT5N08D2 , EddAmbT5N08D3 , EddAmbT5N08D4 , EddAmbT5N08D5 , & - EddAmbT5N08D6 , EddAmbT5N08D7 , EddAmbT5N08D8 , EddAmbT5N08D9 , EddAmbT5N09D1 , EddAmbT5N09D2 , EddAmbT5N09D3 , EddAmbT5N09D4 , & - EddAmbT5N09D5 , EddAmbT5N09D6 , EddAmbT5N09D7 , EddAmbT5N09D8 , EddAmbT5N09D9 , EddAmbT5N10D1 , EddAmbT5N10D2 , EddAmbT5N10D3 , & - EddAmbT5N10D4 , EddAmbT5N10D5 , EddAmbT5N10D6 , EddAmbT5N10D7 , EddAmbT5N10D8 , EddAmbT5N10D9 , EddAmbT5N11D1 , EddAmbT5N11D2 , & - EddAmbT5N11D3 , EddAmbT5N11D4 , EddAmbT5N11D5 , EddAmbT5N11D6 , EddAmbT5N11D7 , EddAmbT5N11D8 , EddAmbT5N11D9 , EddAmbT5N12D1 , & - EddAmbT5N12D2 , EddAmbT5N12D3 , EddAmbT5N12D4 , EddAmbT5N12D5 , EddAmbT5N12D6 , EddAmbT5N12D7 , EddAmbT5N12D8 , EddAmbT5N12D9 , & - EddAmbT5N13D1 , EddAmbT5N13D2 , EddAmbT5N13D3 , EddAmbT5N13D4 , EddAmbT5N13D5 , EddAmbT5N13D6 , EddAmbT5N13D7 , EddAmbT5N13D8 , & - EddAmbT5N13D9 , EddAmbT5N14D1 , EddAmbT5N14D2 , EddAmbT5N14D3 , EddAmbT5N14D4 , EddAmbT5N14D5 , EddAmbT5N14D6 , EddAmbT5N14D7 , & - EddAmbT5N14D8 , EddAmbT5N14D9 , EddAmbT5N15D1 , EddAmbT5N15D2 , EddAmbT5N15D3 , EddAmbT5N15D4 , EddAmbT5N15D5 , EddAmbT5N15D6 , & - EddAmbT5N15D7 , EddAmbT5N15D8 , EddAmbT5N15D9 , EddAmbT5N16D1 , EddAmbT5N16D2 , EddAmbT5N16D3 , EddAmbT5N16D4 , EddAmbT5N16D5 , & - EddAmbT5N16D6 , EddAmbT5N16D7 , EddAmbT5N16D8 , EddAmbT5N16D9 , EddAmbT5N17D1 , EddAmbT5N17D2 , EddAmbT5N17D3 , EddAmbT5N17D4 , & - EddAmbT5N17D5 , EddAmbT5N17D6 , EddAmbT5N17D7 , EddAmbT5N17D8 , EddAmbT5N17D9 , EddAmbT5N18D1 , EddAmbT5N18D2 , EddAmbT5N18D3 , & - EddAmbT5N18D4 , EddAmbT5N18D5 , EddAmbT5N18D6 , EddAmbT5N18D7 , EddAmbT5N18D8 , EddAmbT5N18D9 , EddAmbT5N19D1 , EddAmbT5N19D2 , & - EddAmbT5N19D3 , EddAmbT5N19D4 , EddAmbT5N19D5 , EddAmbT5N19D6 , EddAmbT5N19D7 , EddAmbT5N19D8 , EddAmbT5N19D9 , EddAmbT5N20D1 , & - EddAmbT5N20D2 , EddAmbT5N20D3 , EddAmbT5N20D4 , EddAmbT5N20D5 , EddAmbT5N20D6 , EddAmbT5N20D7 , EddAmbT5N20D8 , EddAmbT5N20D9 , & - EddAmbT6N01D1 , EddAmbT6N01D2 , EddAmbT6N01D3 , EddAmbT6N01D4 , EddAmbT6N01D5 , EddAmbT6N01D6 , EddAmbT6N01D7 , EddAmbT6N01D8 , & - EddAmbT6N01D9 , EddAmbT6N02D1 , EddAmbT6N02D2 , EddAmbT6N02D3 , EddAmbT6N02D4 , EddAmbT6N02D5 , EddAmbT6N02D6 , EddAmbT6N02D7 , & - EddAmbT6N02D8 , EddAmbT6N02D9 , EddAmbT6N03D1 , EddAmbT6N03D2 , EddAmbT6N03D3 , EddAmbT6N03D4 , EddAmbT6N03D5 , EddAmbT6N03D6 , & - EddAmbT6N03D7 , EddAmbT6N03D8 , EddAmbT6N03D9 , EddAmbT6N04D1 , EddAmbT6N04D2 , EddAmbT6N04D3 , EddAmbT6N04D4 , EddAmbT6N04D5 , & - EddAmbT6N04D6 , EddAmbT6N04D7 , EddAmbT6N04D8 , EddAmbT6N04D9 , EddAmbT6N05D1 , EddAmbT6N05D2 , EddAmbT6N05D3 , EddAmbT6N05D4 , & - EddAmbT6N05D5 , EddAmbT6N05D6 , EddAmbT6N05D7 , EddAmbT6N05D8 , EddAmbT6N05D9 , EddAmbT6N06D1 , EddAmbT6N06D2 , EddAmbT6N06D3 , & - EddAmbT6N06D4 , EddAmbT6N06D5 , EddAmbT6N06D6 , EddAmbT6N06D7 , EddAmbT6N06D8 , EddAmbT6N06D9 , EddAmbT6N07D1 , EddAmbT6N07D2 , & - EddAmbT6N07D3 , EddAmbT6N07D4 , EddAmbT6N07D5 , EddAmbT6N07D6 , EddAmbT6N07D7 , EddAmbT6N07D8 , EddAmbT6N07D9 , EddAmbT6N08D1 , & - EddAmbT6N08D2 , EddAmbT6N08D3 , EddAmbT6N08D4 , EddAmbT6N08D5 , EddAmbT6N08D6 , EddAmbT6N08D7 , EddAmbT6N08D8 , EddAmbT6N08D9 , & - EddAmbT6N09D1 , EddAmbT6N09D2 , EddAmbT6N09D3 , EddAmbT6N09D4 , EddAmbT6N09D5 , EddAmbT6N09D6 , EddAmbT6N09D7 , EddAmbT6N09D8 , & - EddAmbT6N09D9 , EddAmbT6N10D1 , EddAmbT6N10D2 , EddAmbT6N10D3 , EddAmbT6N10D4 , EddAmbT6N10D5 , EddAmbT6N10D6 , EddAmbT6N10D7 , & - EddAmbT6N10D8 , EddAmbT6N10D9 , EddAmbT6N11D1 , EddAmbT6N11D2 , EddAmbT6N11D3 , EddAmbT6N11D4 , EddAmbT6N11D5 , EddAmbT6N11D6 , & - EddAmbT6N11D7 , EddAmbT6N11D8 , EddAmbT6N11D9 , EddAmbT6N12D1 , EddAmbT6N12D2 , EddAmbT6N12D3 , EddAmbT6N12D4 , EddAmbT6N12D5 , & - EddAmbT6N12D6 , EddAmbT6N12D7 , EddAmbT6N12D8 , EddAmbT6N12D9 , EddAmbT6N13D1 , EddAmbT6N13D2 , EddAmbT6N13D3 , EddAmbT6N13D4 , & - EddAmbT6N13D5 , EddAmbT6N13D6 , EddAmbT6N13D7 , EddAmbT6N13D8 , EddAmbT6N13D9 , EddAmbT6N14D1 , EddAmbT6N14D2 , EddAmbT6N14D3 , & - EddAmbT6N14D4 , EddAmbT6N14D5 , EddAmbT6N14D6 , EddAmbT6N14D7 , EddAmbT6N14D8 , EddAmbT6N14D9 , EddAmbT6N15D1 , EddAmbT6N15D2 , & - EddAmbT6N15D3 , EddAmbT6N15D4 , EddAmbT6N15D5 , EddAmbT6N15D6 , EddAmbT6N15D7 , EddAmbT6N15D8 , EddAmbT6N15D9 , EddAmbT6N16D1 , & - EddAmbT6N16D2 , EddAmbT6N16D3 , EddAmbT6N16D4 , EddAmbT6N16D5 , EddAmbT6N16D6 , EddAmbT6N16D7 , EddAmbT6N16D8 , EddAmbT6N16D9 , & - EddAmbT6N17D1 , EddAmbT6N17D2 , EddAmbT6N17D3 , EddAmbT6N17D4 , EddAmbT6N17D5 , EddAmbT6N17D6 , EddAmbT6N17D7 , EddAmbT6N17D8 , & - EddAmbT6N17D9 , EddAmbT6N18D1 , EddAmbT6N18D2 , EddAmbT6N18D3 , EddAmbT6N18D4 , EddAmbT6N18D5 , EddAmbT6N18D6 , EddAmbT6N18D7 , & - EddAmbT6N18D8 , EddAmbT6N18D9 , EddAmbT6N19D1 , EddAmbT6N19D2 , EddAmbT6N19D3 , EddAmbT6N19D4 , EddAmbT6N19D5 , EddAmbT6N19D6 , & - EddAmbT6N19D7 , EddAmbT6N19D8 , EddAmbT6N19D9 , EddAmbT6N20D1 , EddAmbT6N20D2 , EddAmbT6N20D3 , EddAmbT6N20D4 , EddAmbT6N20D5 , & - EddAmbT6N20D6 , EddAmbT6N20D7 , EddAmbT6N20D8 , EddAmbT6N20D9 , EddAmbT7N01D1 , EddAmbT7N01D2 , EddAmbT7N01D3 , EddAmbT7N01D4 , & - EddAmbT7N01D5 , EddAmbT7N01D6 , EddAmbT7N01D7 , EddAmbT7N01D8 , EddAmbT7N01D9 , EddAmbT7N02D1 , EddAmbT7N02D2 , EddAmbT7N02D3 , & - EddAmbT7N02D4 , EddAmbT7N02D5 , EddAmbT7N02D6 , EddAmbT7N02D7 , EddAmbT7N02D8 , EddAmbT7N02D9 , EddAmbT7N03D1 , EddAmbT7N03D2 , & - EddAmbT7N03D3 , EddAmbT7N03D4 , EddAmbT7N03D5 , EddAmbT7N03D6 , EddAmbT7N03D7 , EddAmbT7N03D8 , EddAmbT7N03D9 , EddAmbT7N04D1 , & - EddAmbT7N04D2 , EddAmbT7N04D3 , EddAmbT7N04D4 , EddAmbT7N04D5 , EddAmbT7N04D6 , EddAmbT7N04D7 , EddAmbT7N04D8 , EddAmbT7N04D9 , & - EddAmbT7N05D1 , EddAmbT7N05D2 , EddAmbT7N05D3 , EddAmbT7N05D4 , EddAmbT7N05D5 , EddAmbT7N05D6 , EddAmbT7N05D7 , EddAmbT7N05D8 , & - EddAmbT7N05D9 , EddAmbT7N06D1 , EddAmbT7N06D2 , EddAmbT7N06D3 , EddAmbT7N06D4 , EddAmbT7N06D5 , EddAmbT7N06D6 , EddAmbT7N06D7 , & - EddAmbT7N06D8 , EddAmbT7N06D9 , EddAmbT7N07D1 , EddAmbT7N07D2 , EddAmbT7N07D3 , EddAmbT7N07D4 , EddAmbT7N07D5 , EddAmbT7N07D6 , & - EddAmbT7N07D7 , EddAmbT7N07D8 , EddAmbT7N07D9 , EddAmbT7N08D1 , EddAmbT7N08D2 , EddAmbT7N08D3 , EddAmbT7N08D4 , EddAmbT7N08D5 , & - EddAmbT7N08D6 , EddAmbT7N08D7 , EddAmbT7N08D8 , EddAmbT7N08D9 , EddAmbT7N09D1 , EddAmbT7N09D2 , EddAmbT7N09D3 , EddAmbT7N09D4 , & - EddAmbT7N09D5 , EddAmbT7N09D6 , EddAmbT7N09D7 , EddAmbT7N09D8 , EddAmbT7N09D9 , EddAmbT7N10D1 , EddAmbT7N10D2 , EddAmbT7N10D3 , & - EddAmbT7N10D4 , EddAmbT7N10D5 , EddAmbT7N10D6 , EddAmbT7N10D7 , EddAmbT7N10D8 , EddAmbT7N10D9 , EddAmbT7N11D1 , EddAmbT7N11D2 , & - EddAmbT7N11D3 , EddAmbT7N11D4 , EddAmbT7N11D5 , EddAmbT7N11D6 , EddAmbT7N11D7 , EddAmbT7N11D8 , EddAmbT7N11D9 , EddAmbT7N12D1 , & - EddAmbT7N12D2 , EddAmbT7N12D3 , EddAmbT7N12D4 , EddAmbT7N12D5 , EddAmbT7N12D6 , EddAmbT7N12D7 , EddAmbT7N12D8 , EddAmbT7N12D9 , & - EddAmbT7N13D1 , EddAmbT7N13D2 , EddAmbT7N13D3 , EddAmbT7N13D4 , EddAmbT7N13D5 , EddAmbT7N13D6 , EddAmbT7N13D7 , EddAmbT7N13D8 , & - EddAmbT7N13D9 , EddAmbT7N14D1 , EddAmbT7N14D2 , EddAmbT7N14D3 , EddAmbT7N14D4 , EddAmbT7N14D5 , EddAmbT7N14D6 , EddAmbT7N14D7 , & - EddAmbT7N14D8 , EddAmbT7N14D9 , EddAmbT7N15D1 , EddAmbT7N15D2 , EddAmbT7N15D3 , EddAmbT7N15D4 , EddAmbT7N15D5 , EddAmbT7N15D6 , & - EddAmbT7N15D7 , EddAmbT7N15D8 , EddAmbT7N15D9 , EddAmbT7N16D1 , EddAmbT7N16D2 , EddAmbT7N16D3 , EddAmbT7N16D4 , EddAmbT7N16D5 , & - EddAmbT7N16D6 , EddAmbT7N16D7 , EddAmbT7N16D8 , EddAmbT7N16D9 , EddAmbT7N17D1 , EddAmbT7N17D2 , EddAmbT7N17D3 , EddAmbT7N17D4 , & - EddAmbT7N17D5 , EddAmbT7N17D6 , EddAmbT7N17D7 , EddAmbT7N17D8 , EddAmbT7N17D9 , EddAmbT7N18D1 , EddAmbT7N18D2 , EddAmbT7N18D3 , & - EddAmbT7N18D4 , EddAmbT7N18D5 , EddAmbT7N18D6 , EddAmbT7N18D7 , EddAmbT7N18D8 , EddAmbT7N18D9 , EddAmbT7N19D1 , EddAmbT7N19D2 , & - EddAmbT7N19D3 , EddAmbT7N19D4 , EddAmbT7N19D5 , EddAmbT7N19D6 , EddAmbT7N19D7 , EddAmbT7N19D8 , EddAmbT7N19D9 , EddAmbT7N20D1 , & - EddAmbT7N20D2 , EddAmbT7N20D3 , EddAmbT7N20D4 , EddAmbT7N20D5 , EddAmbT7N20D6 , EddAmbT7N20D7 , EddAmbT7N20D8 , EddAmbT7N20D9 , & - EddAmbT8N01D1 , EddAmbT8N01D2 , EddAmbT8N01D3 , EddAmbT8N01D4 , EddAmbT8N01D5 , EddAmbT8N01D6 , EddAmbT8N01D7 , EddAmbT8N01D8 , & - EddAmbT8N01D9 , EddAmbT8N02D1 , EddAmbT8N02D2 , EddAmbT8N02D3 , EddAmbT8N02D4 , EddAmbT8N02D5 , EddAmbT8N02D6 , EddAmbT8N02D7 , & - EddAmbT8N02D8 , EddAmbT8N02D9 , EddAmbT8N03D1 , EddAmbT8N03D2 , EddAmbT8N03D3 , EddAmbT8N03D4 , EddAmbT8N03D5 , EddAmbT8N03D6 , & - EddAmbT8N03D7 , EddAmbT8N03D8 , EddAmbT8N03D9 , EddAmbT8N04D1 , EddAmbT8N04D2 , EddAmbT8N04D3 , EddAmbT8N04D4 , EddAmbT8N04D5 , & - EddAmbT8N04D6 , EddAmbT8N04D7 , EddAmbT8N04D8 , EddAmbT8N04D9 , EddAmbT8N05D1 , EddAmbT8N05D2 , EddAmbT8N05D3 , EddAmbT8N05D4 , & - EddAmbT8N05D5 , EddAmbT8N05D6 , EddAmbT8N05D7 , EddAmbT8N05D8 , EddAmbT8N05D9 , EddAmbT8N06D1 , EddAmbT8N06D2 , EddAmbT8N06D3 , & - EddAmbT8N06D4 , EddAmbT8N06D5 , EddAmbT8N06D6 , EddAmbT8N06D7 , EddAmbT8N06D8 , EddAmbT8N06D9 , EddAmbT8N07D1 , EddAmbT8N07D2 , & - EddAmbT8N07D3 , EddAmbT8N07D4 , EddAmbT8N07D5 , EddAmbT8N07D6 , EddAmbT8N07D7 , EddAmbT8N07D8 , EddAmbT8N07D9 , EddAmbT8N08D1 , & - EddAmbT8N08D2 , EddAmbT8N08D3 , EddAmbT8N08D4 , EddAmbT8N08D5 , EddAmbT8N08D6 , EddAmbT8N08D7 , EddAmbT8N08D8 , EddAmbT8N08D9 , & - EddAmbT8N09D1 , EddAmbT8N09D2 , EddAmbT8N09D3 , EddAmbT8N09D4 , EddAmbT8N09D5 , EddAmbT8N09D6 , EddAmbT8N09D7 , EddAmbT8N09D8 , & - EddAmbT8N09D9 , EddAmbT8N10D1 , EddAmbT8N10D2 , EddAmbT8N10D3 , EddAmbT8N10D4 , EddAmbT8N10D5 , EddAmbT8N10D6 , EddAmbT8N10D7 , & - EddAmbT8N10D8 , EddAmbT8N10D9 , EddAmbT8N11D1 , EddAmbT8N11D2 , EddAmbT8N11D3 , EddAmbT8N11D4 , EddAmbT8N11D5 , EddAmbT8N11D6 , & - EddAmbT8N11D7 , EddAmbT8N11D8 , EddAmbT8N11D9 , EddAmbT8N12D1 , EddAmbT8N12D2 , EddAmbT8N12D3 , EddAmbT8N12D4 , EddAmbT8N12D5 , & - EddAmbT8N12D6 , EddAmbT8N12D7 , EddAmbT8N12D8 , EddAmbT8N12D9 , EddAmbT8N13D1 , EddAmbT8N13D2 , EddAmbT8N13D3 , EddAmbT8N13D4 , & - EddAmbT8N13D5 , EddAmbT8N13D6 , EddAmbT8N13D7 , EddAmbT8N13D8 , EddAmbT8N13D9 , EddAmbT8N14D1 , EddAmbT8N14D2 , EddAmbT8N14D3 , & - EddAmbT8N14D4 , EddAmbT8N14D5 , EddAmbT8N14D6 , EddAmbT8N14D7 , EddAmbT8N14D8 , EddAmbT8N14D9 , EddAmbT8N15D1 , EddAmbT8N15D2 , & - EddAmbT8N15D3 , EddAmbT8N15D4 , EddAmbT8N15D5 , EddAmbT8N15D6 , EddAmbT8N15D7 , EddAmbT8N15D8 , EddAmbT8N15D9 , EddAmbT8N16D1 , & - EddAmbT8N16D2 , EddAmbT8N16D3 , EddAmbT8N16D4 , EddAmbT8N16D5 , EddAmbT8N16D6 , EddAmbT8N16D7 , EddAmbT8N16D8 , EddAmbT8N16D9 , & - EddAmbT8N17D1 , EddAmbT8N17D2 , EddAmbT8N17D3 , EddAmbT8N17D4 , EddAmbT8N17D5 , EddAmbT8N17D6 , EddAmbT8N17D7 , EddAmbT8N17D8 , & - EddAmbT8N17D9 , EddAmbT8N18D1 , EddAmbT8N18D2 , EddAmbT8N18D3 , EddAmbT8N18D4 , EddAmbT8N18D5 , EddAmbT8N18D6 , EddAmbT8N18D7 , & - EddAmbT8N18D8 , EddAmbT8N18D9 , EddAmbT8N19D1 , EddAmbT8N19D2 , EddAmbT8N19D3 , EddAmbT8N19D4 , EddAmbT8N19D5 , EddAmbT8N19D6 , & - EddAmbT8N19D7 , EddAmbT8N19D8 , EddAmbT8N19D9 , EddAmbT8N20D1 , EddAmbT8N20D2 , EddAmbT8N20D3 , EddAmbT8N20D4 , EddAmbT8N20D5 , & - EddAmbT8N20D6 , EddAmbT8N20D7 , EddAmbT8N20D8 , EddAmbT8N20D9 , EddAmbT9N01D1 , EddAmbT9N01D2 , EddAmbT9N01D3 , EddAmbT9N01D4 , & - EddAmbT9N01D5 , EddAmbT9N01D6 , EddAmbT9N01D7 , EddAmbT9N01D8 , EddAmbT9N01D9 , EddAmbT9N02D1 , EddAmbT9N02D2 , EddAmbT9N02D3 , & - EddAmbT9N02D4 , EddAmbT9N02D5 , EddAmbT9N02D6 , EddAmbT9N02D7 , EddAmbT9N02D8 , EddAmbT9N02D9 , EddAmbT9N03D1 , EddAmbT9N03D2 , & - EddAmbT9N03D3 , EddAmbT9N03D4 , EddAmbT9N03D5 , EddAmbT9N03D6 , EddAmbT9N03D7 , EddAmbT9N03D8 , EddAmbT9N03D9 , EddAmbT9N04D1 , & - EddAmbT9N04D2 , EddAmbT9N04D3 , EddAmbT9N04D4 , EddAmbT9N04D5 , EddAmbT9N04D6 , EddAmbT9N04D7 , EddAmbT9N04D8 , EddAmbT9N04D9 , & - EddAmbT9N05D1 , EddAmbT9N05D2 , EddAmbT9N05D3 , EddAmbT9N05D4 , EddAmbT9N05D5 , EddAmbT9N05D6 , EddAmbT9N05D7 , EddAmbT9N05D8 , & - EddAmbT9N05D9 , EddAmbT9N06D1 , EddAmbT9N06D2 , EddAmbT9N06D3 , EddAmbT9N06D4 , EddAmbT9N06D5 , EddAmbT9N06D6 , EddAmbT9N06D7 , & - EddAmbT9N06D8 , EddAmbT9N06D9 , EddAmbT9N07D1 , EddAmbT9N07D2 , EddAmbT9N07D3 , EddAmbT9N07D4 , EddAmbT9N07D5 , EddAmbT9N07D6 , & - EddAmbT9N07D7 , EddAmbT9N07D8 , EddAmbT9N07D9 , EddAmbT9N08D1 , EddAmbT9N08D2 , EddAmbT9N08D3 , EddAmbT9N08D4 , EddAmbT9N08D5 , & - EddAmbT9N08D6 , EddAmbT9N08D7 , EddAmbT9N08D8 , EddAmbT9N08D9 , EddAmbT9N09D1 , EddAmbT9N09D2 , EddAmbT9N09D3 , EddAmbT9N09D4 , & - EddAmbT9N09D5 , EddAmbT9N09D6 , EddAmbT9N09D7 , EddAmbT9N09D8 , EddAmbT9N09D9 , EddAmbT9N10D1 , EddAmbT9N10D2 , EddAmbT9N10D3 , & - EddAmbT9N10D4 , EddAmbT9N10D5 , EddAmbT9N10D6 , EddAmbT9N10D7 , EddAmbT9N10D8 , EddAmbT9N10D9 , EddAmbT9N11D1 , EddAmbT9N11D2 , & - EddAmbT9N11D3 , EddAmbT9N11D4 , EddAmbT9N11D5 , EddAmbT9N11D6 , EddAmbT9N11D7 , EddAmbT9N11D8 , EddAmbT9N11D9 , EddAmbT9N12D1 , & - EddAmbT9N12D2 , EddAmbT9N12D3 , EddAmbT9N12D4 , EddAmbT9N12D5 , EddAmbT9N12D6 , EddAmbT9N12D7 , EddAmbT9N12D8 , EddAmbT9N12D9 , & - EddAmbT9N13D1 , EddAmbT9N13D2 , EddAmbT9N13D3 , EddAmbT9N13D4 , EddAmbT9N13D5 , EddAmbT9N13D6 , EddAmbT9N13D7 , EddAmbT9N13D8 , & - EddAmbT9N13D9 , EddAmbT9N14D1 , EddAmbT9N14D2 , EddAmbT9N14D3 , EddAmbT9N14D4 , EddAmbT9N14D5 , EddAmbT9N14D6 , EddAmbT9N14D7 , & - EddAmbT9N14D8 , EddAmbT9N14D9 , EddAmbT9N15D1 , EddAmbT9N15D2 , EddAmbT9N15D3 , EddAmbT9N15D4 , EddAmbT9N15D5 , EddAmbT9N15D6 , & - EddAmbT9N15D7 , EddAmbT9N15D8 , EddAmbT9N15D9 , EddAmbT9N16D1 , EddAmbT9N16D2 , EddAmbT9N16D3 , EddAmbT9N16D4 , EddAmbT9N16D5 , & - EddAmbT9N16D6 , EddAmbT9N16D7 , EddAmbT9N16D8 , EddAmbT9N16D9 , EddAmbT9N17D1 , EddAmbT9N17D2 , EddAmbT9N17D3 , EddAmbT9N17D4 , & - EddAmbT9N17D5 , EddAmbT9N17D6 , EddAmbT9N17D7 , EddAmbT9N17D8 , EddAmbT9N17D9 , EddAmbT9N18D1 , EddAmbT9N18D2 , EddAmbT9N18D3 , & - EddAmbT9N18D4 , EddAmbT9N18D5 , EddAmbT9N18D6 , EddAmbT9N18D7 , EddAmbT9N18D8 , EddAmbT9N18D9 , EddAmbT9N19D1 , EddAmbT9N19D2 , & - EddAmbT9N19D3 , EddAmbT9N19D4 , EddAmbT9N19D5 , EddAmbT9N19D6 , EddAmbT9N19D7 , EddAmbT9N19D8 , EddAmbT9N19D9 , EddAmbT9N20D1 , & - EddAmbT9N20D2 , EddAmbT9N20D3 , EddAmbT9N20D4 , EddAmbT9N20D5 , EddAmbT9N20D6 , EddAmbT9N20D7 , EddAmbT9N20D8 , EddAmbT9N20D9 , & - EddShrT1N01D1 , EddShrT1N01D2 , EddShrT1N01D3 , EddShrT1N01D4 , EddShrT1N01D5 , EddShrT1N01D6 , EddShrT1N01D7 , EddShrT1N01D8 , & - EddShrT1N01D9 , EddShrT1N02D1 , EddShrT1N02D2 , EddShrT1N02D3 , EddShrT1N02D4 , EddShrT1N02D5 , EddShrT1N02D6 , EddShrT1N02D7 , & - EddShrT1N02D8 , EddShrT1N02D9 , EddShrT1N03D1 , EddShrT1N03D2 , EddShrT1N03D3 , EddShrT1N03D4 , EddShrT1N03D5 , EddShrT1N03D6 , & - EddShrT1N03D7 , EddShrT1N03D8 , EddShrT1N03D9 , EddShrT1N04D1 , EddShrT1N04D2 , EddShrT1N04D3 , EddShrT1N04D4 , EddShrT1N04D5 , & - EddShrT1N04D6 , EddShrT1N04D7 , EddShrT1N04D8 , EddShrT1N04D9 , EddShrT1N05D1 , EddShrT1N05D2 , EddShrT1N05D3 , EddShrT1N05D4 , & - EddShrT1N05D5 , EddShrT1N05D6 , EddShrT1N05D7 , EddShrT1N05D8 , EddShrT1N05D9 , EddShrT1N06D1 , EddShrT1N06D2 , EddShrT1N06D3 , & - EddShrT1N06D4 , EddShrT1N06D5 , EddShrT1N06D6 , EddShrT1N06D7 , EddShrT1N06D8 , EddShrT1N06D9 , EddShrT1N07D1 , EddShrT1N07D2 , & - EddShrT1N07D3 , EddShrT1N07D4 , EddShrT1N07D5 , EddShrT1N07D6 , EddShrT1N07D7 , EddShrT1N07D8 , EddShrT1N07D9 , EddShrT1N08D1 , & - EddShrT1N08D2 , EddShrT1N08D3 , EddShrT1N08D4 , EddShrT1N08D5 , EddShrT1N08D6 , EddShrT1N08D7 , EddShrT1N08D8 , EddShrT1N08D9 , & - EddShrT1N09D1 , EddShrT1N09D2 , EddShrT1N09D3 , EddShrT1N09D4 , EddShrT1N09D5 , EddShrT1N09D6 , EddShrT1N09D7 , EddShrT1N09D8 , & - EddShrT1N09D9 , EddShrT1N10D1 , EddShrT1N10D2 , EddShrT1N10D3 , EddShrT1N10D4 , EddShrT1N10D5 , EddShrT1N10D6 , EddShrT1N10D7 , & - EddShrT1N10D8 , EddShrT1N10D9 , EddShrT1N11D1 , EddShrT1N11D2 , EddShrT1N11D3 , EddShrT1N11D4 , EddShrT1N11D5 , EddShrT1N11D6 , & - EddShrT1N11D7 , EddShrT1N11D8 , EddShrT1N11D9 , EddShrT1N12D1 , EddShrT1N12D2 , EddShrT1N12D3 , EddShrT1N12D4 , EddShrT1N12D5 , & - EddShrT1N12D6 , EddShrT1N12D7 , EddShrT1N12D8 , EddShrT1N12D9 , EddShrT1N13D1 , EddShrT1N13D2 , EddShrT1N13D3 , EddShrT1N13D4 , & - EddShrT1N13D5 , EddShrT1N13D6 , EddShrT1N13D7 , EddShrT1N13D8 , EddShrT1N13D9 , EddShrT1N14D1 , EddShrT1N14D2 , EddShrT1N14D3 , & - EddShrT1N14D4 , EddShrT1N14D5 , EddShrT1N14D6 , EddShrT1N14D7 , EddShrT1N14D8 , EddShrT1N14D9 , EddShrT1N15D1 , EddShrT1N15D2 , & - EddShrT1N15D3 , EddShrT1N15D4 , EddShrT1N15D5 , EddShrT1N15D6 , EddShrT1N15D7 , EddShrT1N15D8 , EddShrT1N15D9 , EddShrT1N16D1 , & - EddShrT1N16D2 , EddShrT1N16D3 , EddShrT1N16D4 , EddShrT1N16D5 , EddShrT1N16D6 , EddShrT1N16D7 , EddShrT1N16D8 , EddShrT1N16D9 , & - EddShrT1N17D1 , EddShrT1N17D2 , EddShrT1N17D3 , EddShrT1N17D4 , EddShrT1N17D5 , EddShrT1N17D6 , EddShrT1N17D7 , EddShrT1N17D8 , & - EddShrT1N17D9 , EddShrT1N18D1 , EddShrT1N18D2 , EddShrT1N18D3 , EddShrT1N18D4 , EddShrT1N18D5 , EddShrT1N18D6 , EddShrT1N18D7 , & - EddShrT1N18D8 , EddShrT1N18D9 , EddShrT1N19D1 , EddShrT1N19D2 , EddShrT1N19D3 , EddShrT1N19D4 , EddShrT1N19D5 , EddShrT1N19D6 , & - EddShrT1N19D7 , EddShrT1N19D8 , EddShrT1N19D9 , EddShrT1N20D1 , EddShrT1N20D2 , EddShrT1N20D3 , EddShrT1N20D4 , EddShrT1N20D5 , & - EddShrT1N20D6 , EddShrT1N20D7 , EddShrT1N20D8 , EddShrT1N20D9 , EddShrT2N01D1 , EddShrT2N01D2 , EddShrT2N01D3 , EddShrT2N01D4 , & - EddShrT2N01D5 , EddShrT2N01D6 , EddShrT2N01D7 , EddShrT2N01D8 , EddShrT2N01D9 , EddShrT2N02D1 , EddShrT2N02D2 , EddShrT2N02D3 , & - EddShrT2N02D4 , EddShrT2N02D5 , EddShrT2N02D6 , EddShrT2N02D7 , EddShrT2N02D8 , EddShrT2N02D9 , EddShrT2N03D1 , EddShrT2N03D2 , & - EddShrT2N03D3 , EddShrT2N03D4 , EddShrT2N03D5 , EddShrT2N03D6 , EddShrT2N03D7 , EddShrT2N03D8 , EddShrT2N03D9 , EddShrT2N04D1 , & - EddShrT2N04D2 , EddShrT2N04D3 , EddShrT2N04D4 , EddShrT2N04D5 , EddShrT2N04D6 , EddShrT2N04D7 , EddShrT2N04D8 , EddShrT2N04D9 , & - EddShrT2N05D1 , EddShrT2N05D2 , EddShrT2N05D3 , EddShrT2N05D4 , EddShrT2N05D5 , EddShrT2N05D6 , EddShrT2N05D7 , EddShrT2N05D8 , & - EddShrT2N05D9 , EddShrT2N06D1 , EddShrT2N06D2 , EddShrT2N06D3 , EddShrT2N06D4 , EddShrT2N06D5 , EddShrT2N06D6 , EddShrT2N06D7 , & - EddShrT2N06D8 , EddShrT2N06D9 , EddShrT2N07D1 , EddShrT2N07D2 , EddShrT2N07D3 , EddShrT2N07D4 , EddShrT2N07D5 , EddShrT2N07D6 /) - ParamIndxAry(2041:4080) = (/ & - EddShrT2N07D7 , EddShrT2N07D8 , EddShrT2N07D9 , EddShrT2N08D1 , EddShrT2N08D2 , EddShrT2N08D3 , EddShrT2N08D4 , EddShrT2N08D5 , & - EddShrT2N08D6 , EddShrT2N08D7 , EddShrT2N08D8 , EddShrT2N08D9 , EddShrT2N09D1 , EddShrT2N09D2 , EddShrT2N09D3 , EddShrT2N09D4 , & - EddShrT2N09D5 , EddShrT2N09D6 , EddShrT2N09D7 , EddShrT2N09D8 , EddShrT2N09D9 , EddShrT2N10D1 , EddShrT2N10D2 , EddShrT2N10D3 , & - EddShrT2N10D4 , EddShrT2N10D5 , EddShrT2N10D6 , EddShrT2N10D7 , EddShrT2N10D8 , EddShrT2N10D9 , EddShrT2N11D1 , EddShrT2N11D2 , & - EddShrT2N11D3 , EddShrT2N11D4 , EddShrT2N11D5 , EddShrT2N11D6 , EddShrT2N11D7 , EddShrT2N11D8 , EddShrT2N11D9 , EddShrT2N12D1 , & - EddShrT2N12D2 , EddShrT2N12D3 , EddShrT2N12D4 , EddShrT2N12D5 , EddShrT2N12D6 , EddShrT2N12D7 , EddShrT2N12D8 , EddShrT2N12D9 , & - EddShrT2N13D1 , EddShrT2N13D2 , EddShrT2N13D3 , EddShrT2N13D4 , EddShrT2N13D5 , EddShrT2N13D6 , EddShrT2N13D7 , EddShrT2N13D8 , & - EddShrT2N13D9 , EddShrT2N14D1 , EddShrT2N14D2 , EddShrT2N14D3 , EddShrT2N14D4 , EddShrT2N14D5 , EddShrT2N14D6 , EddShrT2N14D7 , & - EddShrT2N14D8 , EddShrT2N14D9 , EddShrT2N15D1 , EddShrT2N15D2 , EddShrT2N15D3 , EddShrT2N15D4 , EddShrT2N15D5 , EddShrT2N15D6 , & - EddShrT2N15D7 , EddShrT2N15D8 , EddShrT2N15D9 , EddShrT2N16D1 , EddShrT2N16D2 , EddShrT2N16D3 , EddShrT2N16D4 , EddShrT2N16D5 , & - EddShrT2N16D6 , EddShrT2N16D7 , EddShrT2N16D8 , EddShrT2N16D9 , EddShrT2N17D1 , EddShrT2N17D2 , EddShrT2N17D3 , EddShrT2N17D4 , & - EddShrT2N17D5 , EddShrT2N17D6 , EddShrT2N17D7 , EddShrT2N17D8 , EddShrT2N17D9 , EddShrT2N18D1 , EddShrT2N18D2 , EddShrT2N18D3 , & - EddShrT2N18D4 , EddShrT2N18D5 , EddShrT2N18D6 , EddShrT2N18D7 , EddShrT2N18D8 , EddShrT2N18D9 , EddShrT2N19D1 , EddShrT2N19D2 , & - EddShrT2N19D3 , EddShrT2N19D4 , EddShrT2N19D5 , EddShrT2N19D6 , EddShrT2N19D7 , EddShrT2N19D8 , EddShrT2N19D9 , EddShrT2N20D1 , & - EddShrT2N20D2 , EddShrT2N20D3 , EddShrT2N20D4 , EddShrT2N20D5 , EddShrT2N20D6 , EddShrT2N20D7 , EddShrT2N20D8 , EddShrT2N20D9 , & - EddShrT3N01D1 , EddShrT3N01D2 , EddShrT3N01D3 , EddShrT3N01D4 , EddShrT3N01D5 , EddShrT3N01D6 , EddShrT3N01D7 , EddShrT3N01D8 , & - EddShrT3N01D9 , EddShrT3N02D1 , EddShrT3N02D2 , EddShrT3N02D3 , EddShrT3N02D4 , EddShrT3N02D5 , EddShrT3N02D6 , EddShrT3N02D7 , & - EddShrT3N02D8 , EddShrT3N02D9 , EddShrT3N03D1 , EddShrT3N03D2 , EddShrT3N03D3 , EddShrT3N03D4 , EddShrT3N03D5 , EddShrT3N03D6 , & - EddShrT3N03D7 , EddShrT3N03D8 , EddShrT3N03D9 , EddShrT3N04D1 , EddShrT3N04D2 , EddShrT3N04D3 , EddShrT3N04D4 , EddShrT3N04D5 , & - EddShrT3N04D6 , EddShrT3N04D7 , EddShrT3N04D8 , EddShrT3N04D9 , EddShrT3N05D1 , EddShrT3N05D2 , EddShrT3N05D3 , EddShrT3N05D4 , & - EddShrT3N05D5 , EddShrT3N05D6 , EddShrT3N05D7 , EddShrT3N05D8 , EddShrT3N05D9 , EddShrT3N06D1 , EddShrT3N06D2 , EddShrT3N06D3 , & - EddShrT3N06D4 , EddShrT3N06D5 , EddShrT3N06D6 , EddShrT3N06D7 , EddShrT3N06D8 , EddShrT3N06D9 , EddShrT3N07D1 , EddShrT3N07D2 , & - EddShrT3N07D3 , EddShrT3N07D4 , EddShrT3N07D5 , EddShrT3N07D6 , EddShrT3N07D7 , EddShrT3N07D8 , EddShrT3N07D9 , EddShrT3N08D1 , & - EddShrT3N08D2 , EddShrT3N08D3 , EddShrT3N08D4 , EddShrT3N08D5 , EddShrT3N08D6 , EddShrT3N08D7 , EddShrT3N08D8 , EddShrT3N08D9 , & - EddShrT3N09D1 , EddShrT3N09D2 , EddShrT3N09D3 , EddShrT3N09D4 , EddShrT3N09D5 , EddShrT3N09D6 , EddShrT3N09D7 , EddShrT3N09D8 , & - EddShrT3N09D9 , EddShrT3N10D1 , EddShrT3N10D2 , EddShrT3N10D3 , EddShrT3N10D4 , EddShrT3N10D5 , EddShrT3N10D6 , EddShrT3N10D7 , & - EddShrT3N10D8 , EddShrT3N10D9 , EddShrT3N11D1 , EddShrT3N11D2 , EddShrT3N11D3 , EddShrT3N11D4 , EddShrT3N11D5 , EddShrT3N11D6 , & - EddShrT3N11D7 , EddShrT3N11D8 , EddShrT3N11D9 , EddShrT3N12D1 , EddShrT3N12D2 , EddShrT3N12D3 , EddShrT3N12D4 , EddShrT3N12D5 , & - EddShrT3N12D6 , EddShrT3N12D7 , EddShrT3N12D8 , EddShrT3N12D9 , EddShrT3N13D1 , EddShrT3N13D2 , EddShrT3N13D3 , EddShrT3N13D4 , & - EddShrT3N13D5 , EddShrT3N13D6 , EddShrT3N13D7 , EddShrT3N13D8 , EddShrT3N13D9 , EddShrT3N14D1 , EddShrT3N14D2 , EddShrT3N14D3 , & - EddShrT3N14D4 , EddShrT3N14D5 , EddShrT3N14D6 , EddShrT3N14D7 , EddShrT3N14D8 , EddShrT3N14D9 , EddShrT3N15D1 , EddShrT3N15D2 , & - EddShrT3N15D3 , EddShrT3N15D4 , EddShrT3N15D5 , EddShrT3N15D6 , EddShrT3N15D7 , EddShrT3N15D8 , EddShrT3N15D9 , EddShrT3N16D1 , & - EddShrT3N16D2 , EddShrT3N16D3 , EddShrT3N16D4 , EddShrT3N16D5 , EddShrT3N16D6 , EddShrT3N16D7 , EddShrT3N16D8 , EddShrT3N16D9 , & - EddShrT3N17D1 , EddShrT3N17D2 , EddShrT3N17D3 , EddShrT3N17D4 , EddShrT3N17D5 , EddShrT3N17D6 , EddShrT3N17D7 , EddShrT3N17D8 , & - EddShrT3N17D9 , EddShrT3N18D1 , EddShrT3N18D2 , EddShrT3N18D3 , EddShrT3N18D4 , EddShrT3N18D5 , EddShrT3N18D6 , EddShrT3N18D7 , & - EddShrT3N18D8 , EddShrT3N18D9 , EddShrT3N19D1 , EddShrT3N19D2 , EddShrT3N19D3 , EddShrT3N19D4 , EddShrT3N19D5 , EddShrT3N19D6 , & - EddShrT3N19D7 , EddShrT3N19D8 , EddShrT3N19D9 , EddShrT3N20D1 , EddShrT3N20D2 , EddShrT3N20D3 , EddShrT3N20D4 , EddShrT3N20D5 , & - EddShrT3N20D6 , EddShrT3N20D7 , EddShrT3N20D8 , EddShrT3N20D9 , EddShrT4N01D1 , EddShrT4N01D2 , EddShrT4N01D3 , EddShrT4N01D4 , & - EddShrT4N01D5 , EddShrT4N01D6 , EddShrT4N01D7 , EddShrT4N01D8 , EddShrT4N01D9 , EddShrT4N02D1 , EddShrT4N02D2 , EddShrT4N02D3 , & - EddShrT4N02D4 , EddShrT4N02D5 , EddShrT4N02D6 , EddShrT4N02D7 , EddShrT4N02D8 , EddShrT4N02D9 , EddShrT4N03D1 , EddShrT4N03D2 , & - EddShrT4N03D3 , EddShrT4N03D4 , EddShrT4N03D5 , EddShrT4N03D6 , EddShrT4N03D7 , EddShrT4N03D8 , EddShrT4N03D9 , EddShrT4N04D1 , & - EddShrT4N04D2 , EddShrT4N04D3 , EddShrT4N04D4 , EddShrT4N04D5 , EddShrT4N04D6 , EddShrT4N04D7 , EddShrT4N04D8 , EddShrT4N04D9 , & - EddShrT4N05D1 , EddShrT4N05D2 , EddShrT4N05D3 , EddShrT4N05D4 , EddShrT4N05D5 , EddShrT4N05D6 , EddShrT4N05D7 , EddShrT4N05D8 , & - EddShrT4N05D9 , EddShrT4N06D1 , EddShrT4N06D2 , EddShrT4N06D3 , EddShrT4N06D4 , EddShrT4N06D5 , EddShrT4N06D6 , EddShrT4N06D7 , & - EddShrT4N06D8 , EddShrT4N06D9 , EddShrT4N07D1 , EddShrT4N07D2 , EddShrT4N07D3 , EddShrT4N07D4 , EddShrT4N07D5 , EddShrT4N07D6 , & - EddShrT4N07D7 , EddShrT4N07D8 , EddShrT4N07D9 , EddShrT4N08D1 , EddShrT4N08D2 , EddShrT4N08D3 , EddShrT4N08D4 , EddShrT4N08D5 , & - EddShrT4N08D6 , EddShrT4N08D7 , EddShrT4N08D8 , EddShrT4N08D9 , EddShrT4N09D1 , EddShrT4N09D2 , EddShrT4N09D3 , EddShrT4N09D4 , & - EddShrT4N09D5 , EddShrT4N09D6 , EddShrT4N09D7 , EddShrT4N09D8 , EddShrT4N09D9 , EddShrT4N10D1 , EddShrT4N10D2 , EddShrT4N10D3 , & - EddShrT4N10D4 , EddShrT4N10D5 , EddShrT4N10D6 , EddShrT4N10D7 , EddShrT4N10D8 , EddShrT4N10D9 , EddShrT4N11D1 , EddShrT4N11D2 , & - EddShrT4N11D3 , EddShrT4N11D4 , EddShrT4N11D5 , EddShrT4N11D6 , EddShrT4N11D7 , EddShrT4N11D8 , EddShrT4N11D9 , EddShrT4N12D1 , & - EddShrT4N12D2 , EddShrT4N12D3 , EddShrT4N12D4 , EddShrT4N12D5 , EddShrT4N12D6 , EddShrT4N12D7 , EddShrT4N12D8 , EddShrT4N12D9 , & - EddShrT4N13D1 , EddShrT4N13D2 , EddShrT4N13D3 , EddShrT4N13D4 , EddShrT4N13D5 , EddShrT4N13D6 , EddShrT4N13D7 , EddShrT4N13D8 , & - EddShrT4N13D9 , EddShrT4N14D1 , EddShrT4N14D2 , EddShrT4N14D3 , EddShrT4N14D4 , EddShrT4N14D5 , EddShrT4N14D6 , EddShrT4N14D7 , & - EddShrT4N14D8 , EddShrT4N14D9 , EddShrT4N15D1 , EddShrT4N15D2 , EddShrT4N15D3 , EddShrT4N15D4 , EddShrT4N15D5 , EddShrT4N15D6 , & - EddShrT4N15D7 , EddShrT4N15D8 , EddShrT4N15D9 , EddShrT4N16D1 , EddShrT4N16D2 , EddShrT4N16D3 , EddShrT4N16D4 , EddShrT4N16D5 , & - EddShrT4N16D6 , EddShrT4N16D7 , EddShrT4N16D8 , EddShrT4N16D9 , EddShrT4N17D1 , EddShrT4N17D2 , EddShrT4N17D3 , EddShrT4N17D4 , & - EddShrT4N17D5 , EddShrT4N17D6 , EddShrT4N17D7 , EddShrT4N17D8 , EddShrT4N17D9 , EddShrT4N18D1 , EddShrT4N18D2 , EddShrT4N18D3 , & - EddShrT4N18D4 , EddShrT4N18D5 , EddShrT4N18D6 , EddShrT4N18D7 , EddShrT4N18D8 , EddShrT4N18D9 , EddShrT4N19D1 , EddShrT4N19D2 , & - EddShrT4N19D3 , EddShrT4N19D4 , EddShrT4N19D5 , EddShrT4N19D6 , EddShrT4N19D7 , EddShrT4N19D8 , EddShrT4N19D9 , EddShrT4N20D1 , & - EddShrT4N20D2 , EddShrT4N20D3 , EddShrT4N20D4 , EddShrT4N20D5 , EddShrT4N20D6 , EddShrT4N20D7 , EddShrT4N20D8 , EddShrT4N20D9 , & - EddShrT5N01D1 , EddShrT5N01D2 , EddShrT5N01D3 , EddShrT5N01D4 , EddShrT5N01D5 , EddShrT5N01D6 , EddShrT5N01D7 , EddShrT5N01D8 , & - EddShrT5N01D9 , EddShrT5N02D1 , EddShrT5N02D2 , EddShrT5N02D3 , EddShrT5N02D4 , EddShrT5N02D5 , EddShrT5N02D6 , EddShrT5N02D7 , & - EddShrT5N02D8 , EddShrT5N02D9 , EddShrT5N03D1 , EddShrT5N03D2 , EddShrT5N03D3 , EddShrT5N03D4 , EddShrT5N03D5 , EddShrT5N03D6 , & - EddShrT5N03D7 , EddShrT5N03D8 , EddShrT5N03D9 , EddShrT5N04D1 , EddShrT5N04D2 , EddShrT5N04D3 , EddShrT5N04D4 , EddShrT5N04D5 , & - EddShrT5N04D6 , EddShrT5N04D7 , EddShrT5N04D8 , EddShrT5N04D9 , EddShrT5N05D1 , EddShrT5N05D2 , EddShrT5N05D3 , EddShrT5N05D4 , & - EddShrT5N05D5 , EddShrT5N05D6 , EddShrT5N05D7 , EddShrT5N05D8 , EddShrT5N05D9 , EddShrT5N06D1 , EddShrT5N06D2 , EddShrT5N06D3 , & - EddShrT5N06D4 , EddShrT5N06D5 , EddShrT5N06D6 , EddShrT5N06D7 , EddShrT5N06D8 , EddShrT5N06D9 , EddShrT5N07D1 , EddShrT5N07D2 , & - EddShrT5N07D3 , EddShrT5N07D4 , EddShrT5N07D5 , EddShrT5N07D6 , EddShrT5N07D7 , EddShrT5N07D8 , EddShrT5N07D9 , EddShrT5N08D1 , & - EddShrT5N08D2 , EddShrT5N08D3 , EddShrT5N08D4 , EddShrT5N08D5 , EddShrT5N08D6 , EddShrT5N08D7 , EddShrT5N08D8 , EddShrT5N08D9 , & - EddShrT5N09D1 , EddShrT5N09D2 , EddShrT5N09D3 , EddShrT5N09D4 , EddShrT5N09D5 , EddShrT5N09D6 , EddShrT5N09D7 , EddShrT5N09D8 , & - EddShrT5N09D9 , EddShrT5N10D1 , EddShrT5N10D2 , EddShrT5N10D3 , EddShrT5N10D4 , EddShrT5N10D5 , EddShrT5N10D6 , EddShrT5N10D7 , & - EddShrT5N10D8 , EddShrT5N10D9 , EddShrT5N11D1 , EddShrT5N11D2 , EddShrT5N11D3 , EddShrT5N11D4 , EddShrT5N11D5 , EddShrT5N11D6 , & - EddShrT5N11D7 , EddShrT5N11D8 , EddShrT5N11D9 , EddShrT5N12D1 , EddShrT5N12D2 , EddShrT5N12D3 , EddShrT5N12D4 , EddShrT5N12D5 , & - EddShrT5N12D6 , EddShrT5N12D7 , EddShrT5N12D8 , EddShrT5N12D9 , EddShrT5N13D1 , EddShrT5N13D2 , EddShrT5N13D3 , EddShrT5N13D4 , & - EddShrT5N13D5 , EddShrT5N13D6 , EddShrT5N13D7 , EddShrT5N13D8 , EddShrT5N13D9 , EddShrT5N14D1 , EddShrT5N14D2 , EddShrT5N14D3 , & - EddShrT5N14D4 , EddShrT5N14D5 , EddShrT5N14D6 , EddShrT5N14D7 , EddShrT5N14D8 , EddShrT5N14D9 , EddShrT5N15D1 , EddShrT5N15D2 , & - EddShrT5N15D3 , EddShrT5N15D4 , EddShrT5N15D5 , EddShrT5N15D6 , EddShrT5N15D7 , EddShrT5N15D8 , EddShrT5N15D9 , EddShrT5N16D1 , & - EddShrT5N16D2 , EddShrT5N16D3 , EddShrT5N16D4 , EddShrT5N16D5 , EddShrT5N16D6 , EddShrT5N16D7 , EddShrT5N16D8 , EddShrT5N16D9 , & - EddShrT5N17D1 , EddShrT5N17D2 , EddShrT5N17D3 , EddShrT5N17D4 , EddShrT5N17D5 , EddShrT5N17D6 , EddShrT5N17D7 , EddShrT5N17D8 , & - EddShrT5N17D9 , EddShrT5N18D1 , EddShrT5N18D2 , EddShrT5N18D3 , EddShrT5N18D4 , EddShrT5N18D5 , EddShrT5N18D6 , EddShrT5N18D7 , & - EddShrT5N18D8 , EddShrT5N18D9 , EddShrT5N19D1 , EddShrT5N19D2 , EddShrT5N19D3 , EddShrT5N19D4 , EddShrT5N19D5 , EddShrT5N19D6 , & - EddShrT5N19D7 , EddShrT5N19D8 , EddShrT5N19D9 , EddShrT5N20D1 , EddShrT5N20D2 , EddShrT5N20D3 , EddShrT5N20D4 , EddShrT5N20D5 , & - EddShrT5N20D6 , EddShrT5N20D7 , EddShrT5N20D8 , EddShrT5N20D9 , EddShrT6N01D1 , EddShrT6N01D2 , EddShrT6N01D3 , EddShrT6N01D4 , & - EddShrT6N01D5 , EddShrT6N01D6 , EddShrT6N01D7 , EddShrT6N01D8 , EddShrT6N01D9 , EddShrT6N02D1 , EddShrT6N02D2 , EddShrT6N02D3 , & - EddShrT6N02D4 , EddShrT6N02D5 , EddShrT6N02D6 , EddShrT6N02D7 , EddShrT6N02D8 , EddShrT6N02D9 , EddShrT6N03D1 , EddShrT6N03D2 , & - EddShrT6N03D3 , EddShrT6N03D4 , EddShrT6N03D5 , EddShrT6N03D6 , EddShrT6N03D7 , EddShrT6N03D8 , EddShrT6N03D9 , EddShrT6N04D1 , & - EddShrT6N04D2 , EddShrT6N04D3 , EddShrT6N04D4 , EddShrT6N04D5 , EddShrT6N04D6 , EddShrT6N04D7 , EddShrT6N04D8 , EddShrT6N04D9 , & - EddShrT6N05D1 , EddShrT6N05D2 , EddShrT6N05D3 , EddShrT6N05D4 , EddShrT6N05D5 , EddShrT6N05D6 , EddShrT6N05D7 , EddShrT6N05D8 , & - EddShrT6N05D9 , EddShrT6N06D1 , EddShrT6N06D2 , EddShrT6N06D3 , EddShrT6N06D4 , EddShrT6N06D5 , EddShrT6N06D6 , EddShrT6N06D7 , & - EddShrT6N06D8 , EddShrT6N06D9 , EddShrT6N07D1 , EddShrT6N07D2 , EddShrT6N07D3 , EddShrT6N07D4 , EddShrT6N07D5 , EddShrT6N07D6 , & - EddShrT6N07D7 , EddShrT6N07D8 , EddShrT6N07D9 , EddShrT6N08D1 , EddShrT6N08D2 , EddShrT6N08D3 , EddShrT6N08D4 , EddShrT6N08D5 , & - EddShrT6N08D6 , EddShrT6N08D7 , EddShrT6N08D8 , EddShrT6N08D9 , EddShrT6N09D1 , EddShrT6N09D2 , EddShrT6N09D3 , EddShrT6N09D4 , & - EddShrT6N09D5 , EddShrT6N09D6 , EddShrT6N09D7 , EddShrT6N09D8 , EddShrT6N09D9 , EddShrT6N10D1 , EddShrT6N10D2 , EddShrT6N10D3 , & - EddShrT6N10D4 , EddShrT6N10D5 , EddShrT6N10D6 , EddShrT6N10D7 , EddShrT6N10D8 , EddShrT6N10D9 , EddShrT6N11D1 , EddShrT6N11D2 , & - EddShrT6N11D3 , EddShrT6N11D4 , EddShrT6N11D5 , EddShrT6N11D6 , EddShrT6N11D7 , EddShrT6N11D8 , EddShrT6N11D9 , EddShrT6N12D1 , & - EddShrT6N12D2 , EddShrT6N12D3 , EddShrT6N12D4 , EddShrT6N12D5 , EddShrT6N12D6 , EddShrT6N12D7 , EddShrT6N12D8 , EddShrT6N12D9 , & - EddShrT6N13D1 , EddShrT6N13D2 , EddShrT6N13D3 , EddShrT6N13D4 , EddShrT6N13D5 , EddShrT6N13D6 , EddShrT6N13D7 , EddShrT6N13D8 , & - EddShrT6N13D9 , EddShrT6N14D1 , EddShrT6N14D2 , EddShrT6N14D3 , EddShrT6N14D4 , EddShrT6N14D5 , EddShrT6N14D6 , EddShrT6N14D7 , & - EddShrT6N14D8 , EddShrT6N14D9 , EddShrT6N15D1 , EddShrT6N15D2 , EddShrT6N15D3 , EddShrT6N15D4 , EddShrT6N15D5 , EddShrT6N15D6 , & - EddShrT6N15D7 , EddShrT6N15D8 , EddShrT6N15D9 , EddShrT6N16D1 , EddShrT6N16D2 , EddShrT6N16D3 , EddShrT6N16D4 , EddShrT6N16D5 , & - EddShrT6N16D6 , EddShrT6N16D7 , EddShrT6N16D8 , EddShrT6N16D9 , EddShrT6N17D1 , EddShrT6N17D2 , EddShrT6N17D3 , EddShrT6N17D4 , & - EddShrT6N17D5 , EddShrT6N17D6 , EddShrT6N17D7 , EddShrT6N17D8 , EddShrT6N17D9 , EddShrT6N18D1 , EddShrT6N18D2 , EddShrT6N18D3 , & - EddShrT6N18D4 , EddShrT6N18D5 , EddShrT6N18D6 , EddShrT6N18D7 , EddShrT6N18D8 , EddShrT6N18D9 , EddShrT6N19D1 , EddShrT6N19D2 , & - EddShrT6N19D3 , EddShrT6N19D4 , EddShrT6N19D5 , EddShrT6N19D6 , EddShrT6N19D7 , EddShrT6N19D8 , EddShrT6N19D9 , EddShrT6N20D1 , & - EddShrT6N20D2 , EddShrT6N20D3 , EddShrT6N20D4 , EddShrT6N20D5 , EddShrT6N20D6 , EddShrT6N20D7 , EddShrT6N20D8 , EddShrT6N20D9 , & - EddShrT7N01D1 , EddShrT7N01D2 , EddShrT7N01D3 , EddShrT7N01D4 , EddShrT7N01D5 , EddShrT7N01D6 , EddShrT7N01D7 , EddShrT7N01D8 , & - EddShrT7N01D9 , EddShrT7N02D1 , EddShrT7N02D2 , EddShrT7N02D3 , EddShrT7N02D4 , EddShrT7N02D5 , EddShrT7N02D6 , EddShrT7N02D7 , & - EddShrT7N02D8 , EddShrT7N02D9 , EddShrT7N03D1 , EddShrT7N03D2 , EddShrT7N03D3 , EddShrT7N03D4 , EddShrT7N03D5 , EddShrT7N03D6 , & - EddShrT7N03D7 , EddShrT7N03D8 , EddShrT7N03D9 , EddShrT7N04D1 , EddShrT7N04D2 , EddShrT7N04D3 , EddShrT7N04D4 , EddShrT7N04D5 , & - EddShrT7N04D6 , EddShrT7N04D7 , EddShrT7N04D8 , EddShrT7N04D9 , EddShrT7N05D1 , EddShrT7N05D2 , EddShrT7N05D3 , EddShrT7N05D4 , & - EddShrT7N05D5 , EddShrT7N05D6 , EddShrT7N05D7 , EddShrT7N05D8 , EddShrT7N05D9 , EddShrT7N06D1 , EddShrT7N06D2 , EddShrT7N06D3 , & - EddShrT7N06D4 , EddShrT7N06D5 , EddShrT7N06D6 , EddShrT7N06D7 , EddShrT7N06D8 , EddShrT7N06D9 , EddShrT7N07D1 , EddShrT7N07D2 , & - EddShrT7N07D3 , EddShrT7N07D4 , EddShrT7N07D5 , EddShrT7N07D6 , EddShrT7N07D7 , EddShrT7N07D8 , EddShrT7N07D9 , EddShrT7N08D1 , & - EddShrT7N08D2 , EddShrT7N08D3 , EddShrT7N08D4 , EddShrT7N08D5 , EddShrT7N08D6 , EddShrT7N08D7 , EddShrT7N08D8 , EddShrT7N08D9 , & - EddShrT7N09D1 , EddShrT7N09D2 , EddShrT7N09D3 , EddShrT7N09D4 , EddShrT7N09D5 , EddShrT7N09D6 , EddShrT7N09D7 , EddShrT7N09D8 , & - EddShrT7N09D9 , EddShrT7N10D1 , EddShrT7N10D2 , EddShrT7N10D3 , EddShrT7N10D4 , EddShrT7N10D5 , EddShrT7N10D6 , EddShrT7N10D7 , & - EddShrT7N10D8 , EddShrT7N10D9 , EddShrT7N11D1 , EddShrT7N11D2 , EddShrT7N11D3 , EddShrT7N11D4 , EddShrT7N11D5 , EddShrT7N11D6 , & - EddShrT7N11D7 , EddShrT7N11D8 , EddShrT7N11D9 , EddShrT7N12D1 , EddShrT7N12D2 , EddShrT7N12D3 , EddShrT7N12D4 , EddShrT7N12D5 , & - EddShrT7N12D6 , EddShrT7N12D7 , EddShrT7N12D8 , EddShrT7N12D9 , EddShrT7N13D1 , EddShrT7N13D2 , EddShrT7N13D3 , EddShrT7N13D4 , & - EddShrT7N13D5 , EddShrT7N13D6 , EddShrT7N13D7 , EddShrT7N13D8 , EddShrT7N13D9 , EddShrT7N14D1 , EddShrT7N14D2 , EddShrT7N14D3 , & - EddShrT7N14D4 , EddShrT7N14D5 , EddShrT7N14D6 , EddShrT7N14D7 , EddShrT7N14D8 , EddShrT7N14D9 , EddShrT7N15D1 , EddShrT7N15D2 , & - EddShrT7N15D3 , EddShrT7N15D4 , EddShrT7N15D5 , EddShrT7N15D6 , EddShrT7N15D7 , EddShrT7N15D8 , EddShrT7N15D9 , EddShrT7N16D1 , & - EddShrT7N16D2 , EddShrT7N16D3 , EddShrT7N16D4 , EddShrT7N16D5 , EddShrT7N16D6 , EddShrT7N16D7 , EddShrT7N16D8 , EddShrT7N16D9 , & - EddShrT7N17D1 , EddShrT7N17D2 , EddShrT7N17D3 , EddShrT7N17D4 , EddShrT7N17D5 , EddShrT7N17D6 , EddShrT7N17D7 , EddShrT7N17D8 , & - EddShrT7N17D9 , EddShrT7N18D1 , EddShrT7N18D2 , EddShrT7N18D3 , EddShrT7N18D4 , EddShrT7N18D5 , EddShrT7N18D6 , EddShrT7N18D7 , & - EddShrT7N18D8 , EddShrT7N18D9 , EddShrT7N19D1 , EddShrT7N19D2 , EddShrT7N19D3 , EddShrT7N19D4 , EddShrT7N19D5 , EddShrT7N19D6 , & - EddShrT7N19D7 , EddShrT7N19D8 , EddShrT7N19D9 , EddShrT7N20D1 , EddShrT7N20D2 , EddShrT7N20D3 , EddShrT7N20D4 , EddShrT7N20D5 , & - EddShrT7N20D6 , EddShrT7N20D7 , EddShrT7N20D8 , EddShrT7N20D9 , EddShrT8N01D1 , EddShrT8N01D2 , EddShrT8N01D3 , EddShrT8N01D4 , & - EddShrT8N01D5 , EddShrT8N01D6 , EddShrT8N01D7 , EddShrT8N01D8 , EddShrT8N01D9 , EddShrT8N02D1 , EddShrT8N02D2 , EddShrT8N02D3 , & - EddShrT8N02D4 , EddShrT8N02D5 , EddShrT8N02D6 , EddShrT8N02D7 , EddShrT8N02D8 , EddShrT8N02D9 , EddShrT8N03D1 , EddShrT8N03D2 , & - EddShrT8N03D3 , EddShrT8N03D4 , EddShrT8N03D5 , EddShrT8N03D6 , EddShrT8N03D7 , EddShrT8N03D8 , EddShrT8N03D9 , EddShrT8N04D1 , & - EddShrT8N04D2 , EddShrT8N04D3 , EddShrT8N04D4 , EddShrT8N04D5 , EddShrT8N04D6 , EddShrT8N04D7 , EddShrT8N04D8 , EddShrT8N04D9 , & - EddShrT8N05D1 , EddShrT8N05D2 , EddShrT8N05D3 , EddShrT8N05D4 , EddShrT8N05D5 , EddShrT8N05D6 , EddShrT8N05D7 , EddShrT8N05D8 , & - EddShrT8N05D9 , EddShrT8N06D1 , EddShrT8N06D2 , EddShrT8N06D3 , EddShrT8N06D4 , EddShrT8N06D5 , EddShrT8N06D6 , EddShrT8N06D7 , & - EddShrT8N06D8 , EddShrT8N06D9 , EddShrT8N07D1 , EddShrT8N07D2 , EddShrT8N07D3 , EddShrT8N07D4 , EddShrT8N07D5 , EddShrT8N07D6 , & - EddShrT8N07D7 , EddShrT8N07D8 , EddShrT8N07D9 , EddShrT8N08D1 , EddShrT8N08D2 , EddShrT8N08D3 , EddShrT8N08D4 , EddShrT8N08D5 , & - EddShrT8N08D6 , EddShrT8N08D7 , EddShrT8N08D8 , EddShrT8N08D9 , EddShrT8N09D1 , EddShrT8N09D2 , EddShrT8N09D3 , EddShrT8N09D4 , & - EddShrT8N09D5 , EddShrT8N09D6 , EddShrT8N09D7 , EddShrT8N09D8 , EddShrT8N09D9 , EddShrT8N10D1 , EddShrT8N10D2 , EddShrT8N10D3 , & - EddShrT8N10D4 , EddShrT8N10D5 , EddShrT8N10D6 , EddShrT8N10D7 , EddShrT8N10D8 , EddShrT8N10D9 , EddShrT8N11D1 , EddShrT8N11D2 , & - EddShrT8N11D3 , EddShrT8N11D4 , EddShrT8N11D5 , EddShrT8N11D6 , EddShrT8N11D7 , EddShrT8N11D8 , EddShrT8N11D9 , EddShrT8N12D1 , & - EddShrT8N12D2 , EddShrT8N12D3 , EddShrT8N12D4 , EddShrT8N12D5 , EddShrT8N12D6 , EddShrT8N12D7 , EddShrT8N12D8 , EddShrT8N12D9 , & - EddShrT8N13D1 , EddShrT8N13D2 , EddShrT8N13D3 , EddShrT8N13D4 , EddShrT8N13D5 , EddShrT8N13D6 , EddShrT8N13D7 , EddShrT8N13D8 , & - EddShrT8N13D9 , EddShrT8N14D1 , EddShrT8N14D2 , EddShrT8N14D3 , EddShrT8N14D4 , EddShrT8N14D5 , EddShrT8N14D6 , EddShrT8N14D7 , & - EddShrT8N14D8 , EddShrT8N14D9 , EddShrT8N15D1 , EddShrT8N15D2 , EddShrT8N15D3 , EddShrT8N15D4 , EddShrT8N15D5 , EddShrT8N15D6 , & - EddShrT8N15D7 , EddShrT8N15D8 , EddShrT8N15D9 , EddShrT8N16D1 , EddShrT8N16D2 , EddShrT8N16D3 , EddShrT8N16D4 , EddShrT8N16D5 , & - EddShrT8N16D6 , EddShrT8N16D7 , EddShrT8N16D8 , EddShrT8N16D9 , EddShrT8N17D1 , EddShrT8N17D2 , EddShrT8N17D3 , EddShrT8N17D4 , & - EddShrT8N17D5 , EddShrT8N17D6 , EddShrT8N17D7 , EddShrT8N17D8 , EddShrT8N17D9 , EddShrT8N18D1 , EddShrT8N18D2 , EddShrT8N18D3 , & - EddShrT8N18D4 , EddShrT8N18D5 , EddShrT8N18D6 , EddShrT8N18D7 , EddShrT8N18D8 , EddShrT8N18D9 , EddShrT8N19D1 , EddShrT8N19D2 , & - EddShrT8N19D3 , EddShrT8N19D4 , EddShrT8N19D5 , EddShrT8N19D6 , EddShrT8N19D7 , EddShrT8N19D8 , EddShrT8N19D9 , EddShrT8N20D1 , & - EddShrT8N20D2 , EddShrT8N20D3 , EddShrT8N20D4 , EddShrT8N20D5 , EddShrT8N20D6 , EddShrT8N20D7 , EddShrT8N20D8 , EddShrT8N20D9 , & - EddShrT9N01D1 , EddShrT9N01D2 , EddShrT9N01D3 , EddShrT9N01D4 , EddShrT9N01D5 , EddShrT9N01D6 , EddShrT9N01D7 , EddShrT9N01D8 , & - EddShrT9N01D9 , EddShrT9N02D1 , EddShrT9N02D2 , EddShrT9N02D3 , EddShrT9N02D4 , EddShrT9N02D5 , EddShrT9N02D6 , EddShrT9N02D7 , & - EddShrT9N02D8 , EddShrT9N02D9 , EddShrT9N03D1 , EddShrT9N03D2 , EddShrT9N03D3 , EddShrT9N03D4 , EddShrT9N03D5 , EddShrT9N03D6 , & - EddShrT9N03D7 , EddShrT9N03D8 , EddShrT9N03D9 , EddShrT9N04D1 , EddShrT9N04D2 , EddShrT9N04D3 , EddShrT9N04D4 , EddShrT9N04D5 , & - EddShrT9N04D6 , EddShrT9N04D7 , EddShrT9N04D8 , EddShrT9N04D9 , EddShrT9N05D1 , EddShrT9N05D2 , EddShrT9N05D3 , EddShrT9N05D4 , & - EddShrT9N05D5 , EddShrT9N05D6 , EddShrT9N05D7 , EddShrT9N05D8 , EddShrT9N05D9 , EddShrT9N06D1 , EddShrT9N06D2 , EddShrT9N06D3 , & - EddShrT9N06D4 , EddShrT9N06D5 , EddShrT9N06D6 , EddShrT9N06D7 , EddShrT9N06D8 , EddShrT9N06D9 , EddShrT9N07D1 , EddShrT9N07D2 , & - EddShrT9N07D3 , EddShrT9N07D4 , EddShrT9N07D5 , EddShrT9N07D6 , EddShrT9N07D7 , EddShrT9N07D8 , EddShrT9N07D9 , EddShrT9N08D1 , & - EddShrT9N08D2 , EddShrT9N08D3 , EddShrT9N08D4 , EddShrT9N08D5 , EddShrT9N08D6 , EddShrT9N08D7 , EddShrT9N08D8 , EddShrT9N08D9 , & - EddShrT9N09D1 , EddShrT9N09D2 , EddShrT9N09D3 , EddShrT9N09D4 , EddShrT9N09D5 , EddShrT9N09D6 , EddShrT9N09D7 , EddShrT9N09D8 , & - EddShrT9N09D9 , EddShrT9N10D1 , EddShrT9N10D2 , EddShrT9N10D3 , EddShrT9N10D4 , EddShrT9N10D5 , EddShrT9N10D6 , EddShrT9N10D7 , & - EddShrT9N10D8 , EddShrT9N10D9 , EddShrT9N11D1 , EddShrT9N11D2 , EddShrT9N11D3 , EddShrT9N11D4 , EddShrT9N11D5 , EddShrT9N11D6 , & - EddShrT9N11D7 , EddShrT9N11D8 , EddShrT9N11D9 , EddShrT9N12D1 , EddShrT9N12D2 , EddShrT9N12D3 , EddShrT9N12D4 , EddShrT9N12D5 , & - EddShrT9N12D6 , EddShrT9N12D7 , EddShrT9N12D8 , EddShrT9N12D9 , EddShrT9N13D1 , EddShrT9N13D2 , EddShrT9N13D3 , EddShrT9N13D4 , & - EddShrT9N13D5 , EddShrT9N13D6 , EddShrT9N13D7 , EddShrT9N13D8 , EddShrT9N13D9 , EddShrT9N14D1 , EddShrT9N14D2 , EddShrT9N14D3 , & - EddShrT9N14D4 , EddShrT9N14D5 , EddShrT9N14D6 , EddShrT9N14D7 , EddShrT9N14D8 , EddShrT9N14D9 , EddShrT9N15D1 , EddShrT9N15D2 , & - EddShrT9N15D3 , EddShrT9N15D4 , EddShrT9N15D5 , EddShrT9N15D6 , EddShrT9N15D7 , EddShrT9N15D8 , EddShrT9N15D9 , EddShrT9N16D1 , & - EddShrT9N16D2 , EddShrT9N16D3 , EddShrT9N16D4 , EddShrT9N16D5 , EddShrT9N16D6 , EddShrT9N16D7 , EddShrT9N16D8 , EddShrT9N16D9 , & - EddShrT9N17D1 , EddShrT9N17D2 , EddShrT9N17D3 , EddShrT9N17D4 , EddShrT9N17D5 , EddShrT9N17D6 , EddShrT9N17D7 , EddShrT9N17D8 , & - EddShrT9N17D9 , EddShrT9N18D1 , EddShrT9N18D2 , EddShrT9N18D3 , EddShrT9N18D4 , EddShrT9N18D5 , EddShrT9N18D6 , EddShrT9N18D7 , & - EddShrT9N18D8 , EddShrT9N18D9 , EddShrT9N19D1 , EddShrT9N19D2 , EddShrT9N19D3 , EddShrT9N19D4 , EddShrT9N19D5 , EddShrT9N19D6 , & - EddShrT9N19D7 , EddShrT9N19D8 , EddShrT9N19D9 , EddShrT9N20D1 , EddShrT9N20D2 , EddShrT9N20D3 , EddShrT9N20D4 , EddShrT9N20D5 , & - EddShrT9N20D6 , EddShrT9N20D7 , EddShrT9N20D8 , EddShrT9N20D9 , EddVisT1N01D1 , EddVisT1N01D2 , EddVisT1N01D3 , EddVisT1N01D4 , & - EddVisT1N01D5 , EddVisT1N01D6 , EddVisT1N01D7 , EddVisT1N01D8 , EddVisT1N01D9 , EddVisT1N02D1 , EddVisT1N02D2 , EddVisT1N02D3 , & - EddVisT1N02D4 , EddVisT1N02D5 , EddVisT1N02D6 , EddVisT1N02D7 , EddVisT1N02D8 , EddVisT1N02D9 , EddVisT1N03D1 , EddVisT1N03D2 , & - EddVisT1N03D3 , EddVisT1N03D4 , EddVisT1N03D5 , EddVisT1N03D6 , EddVisT1N03D7 , EddVisT1N03D8 , EddVisT1N03D9 , EddVisT1N04D1 , & - EddVisT1N04D2 , EddVisT1N04D3 , EddVisT1N04D4 , EddVisT1N04D5 , EddVisT1N04D6 , EddVisT1N04D7 , EddVisT1N04D8 , EddVisT1N04D9 , & - EddVisT1N05D1 , EddVisT1N05D2 , EddVisT1N05D3 , EddVisT1N05D4 , EddVisT1N05D5 , EddVisT1N05D6 , EddVisT1N05D7 , EddVisT1N05D8 , & - EddVisT1N05D9 , EddVisT1N06D1 , EddVisT1N06D2 , EddVisT1N06D3 , EddVisT1N06D4 , EddVisT1N06D5 , EddVisT1N06D6 , EddVisT1N06D7 , & - EddVisT1N06D8 , EddVisT1N06D9 , EddVisT1N07D1 , EddVisT1N07D2 , EddVisT1N07D3 , EddVisT1N07D4 , EddVisT1N07D5 , EddVisT1N07D6 , & - EddVisT1N07D7 , EddVisT1N07D8 , EddVisT1N07D9 , EddVisT1N08D1 , EddVisT1N08D2 , EddVisT1N08D3 , EddVisT1N08D4 , EddVisT1N08D5 , & - EddVisT1N08D6 , EddVisT1N08D7 , EddVisT1N08D8 , EddVisT1N08D9 , EddVisT1N09D1 , EddVisT1N09D2 , EddVisT1N09D3 , EddVisT1N09D4 , & - EddVisT1N09D5 , EddVisT1N09D6 , EddVisT1N09D7 , EddVisT1N09D8 , EddVisT1N09D9 , EddVisT1N10D1 , EddVisT1N10D2 , EddVisT1N10D3 , & - EddVisT1N10D4 , EddVisT1N10D5 , EddVisT1N10D6 , EddVisT1N10D7 , EddVisT1N10D8 , EddVisT1N10D9 , EddVisT1N11D1 , EddVisT1N11D2 , & - EddVisT1N11D3 , EddVisT1N11D4 , EddVisT1N11D5 , EddVisT1N11D6 , EddVisT1N11D7 , EddVisT1N11D8 , EddVisT1N11D9 , EddVisT1N12D1 , & - EddVisT1N12D2 , EddVisT1N12D3 , EddVisT1N12D4 , EddVisT1N12D5 , EddVisT1N12D6 , EddVisT1N12D7 , EddVisT1N12D8 , EddVisT1N12D9 , & - EddVisT1N13D1 , EddVisT1N13D2 , EddVisT1N13D3 , EddVisT1N13D4 , EddVisT1N13D5 , EddVisT1N13D6 , EddVisT1N13D7 , EddVisT1N13D8 , & - EddVisT1N13D9 , EddVisT1N14D1 , EddVisT1N14D2 , EddVisT1N14D3 , EddVisT1N14D4 , EddVisT1N14D5 , EddVisT1N14D6 , EddVisT1N14D7 , & - EddVisT1N14D8 , EddVisT1N14D9 , EddVisT1N15D1 , EddVisT1N15D2 , EddVisT1N15D3 , EddVisT1N15D4 , EddVisT1N15D5 , EddVisT1N15D6 , & - EddVisT1N15D7 , EddVisT1N15D8 , EddVisT1N15D9 , EddVisT1N16D1 , EddVisT1N16D2 , EddVisT1N16D3 , EddVisT1N16D4 , EddVisT1N16D5 , & - EddVisT1N16D6 , EddVisT1N16D7 , EddVisT1N16D8 , EddVisT1N16D9 , EddVisT1N17D1 , EddVisT1N17D2 , EddVisT1N17D3 , EddVisT1N17D4 , & - EddVisT1N17D5 , EddVisT1N17D6 , EddVisT1N17D7 , EddVisT1N17D8 , EddVisT1N17D9 , EddVisT1N18D1 , EddVisT1N18D2 , EddVisT1N18D3 , & - EddVisT1N18D4 , EddVisT1N18D5 , EddVisT1N18D6 , EddVisT1N18D7 , EddVisT1N18D8 , EddVisT1N18D9 , EddVisT1N19D1 , EddVisT1N19D2 , & - EddVisT1N19D3 , EddVisT1N19D4 , EddVisT1N19D5 , EddVisT1N19D6 , EddVisT1N19D7 , EddVisT1N19D8 , EddVisT1N19D9 , EddVisT1N20D1 , & - EddVisT1N20D2 , EddVisT1N20D3 , EddVisT1N20D4 , EddVisT1N20D5 , EddVisT1N20D6 , EddVisT1N20D7 , EddVisT1N20D8 , EddVisT1N20D9 , & - EddVisT2N01D1 , EddVisT2N01D2 , EddVisT2N01D3 , EddVisT2N01D4 , EddVisT2N01D5 , EddVisT2N01D6 , EddVisT2N01D7 , EddVisT2N01D8 , & - EddVisT2N01D9 , EddVisT2N02D1 , EddVisT2N02D2 , EddVisT2N02D3 , EddVisT2N02D4 , EddVisT2N02D5 , EddVisT2N02D6 , EddVisT2N02D7 , & - EddVisT2N02D8 , EddVisT2N02D9 , EddVisT2N03D1 , EddVisT2N03D2 , EddVisT2N03D3 , EddVisT2N03D4 , EddVisT2N03D5 , EddVisT2N03D6 , & - EddVisT2N03D7 , EddVisT2N03D8 , EddVisT2N03D9 , EddVisT2N04D1 , EddVisT2N04D2 , EddVisT2N04D3 , EddVisT2N04D4 , EddVisT2N04D5 , & - EddVisT2N04D6 , EddVisT2N04D7 , EddVisT2N04D8 , EddVisT2N04D9 , EddVisT2N05D1 , EddVisT2N05D2 , EddVisT2N05D3 , EddVisT2N05D4 , & - EddVisT2N05D5 , EddVisT2N05D6 , EddVisT2N05D7 , EddVisT2N05D8 , EddVisT2N05D9 , EddVisT2N06D1 , EddVisT2N06D2 , EddVisT2N06D3 , & - EddVisT2N06D4 , EddVisT2N06D5 , EddVisT2N06D6 , EddVisT2N06D7 , EddVisT2N06D8 , EddVisT2N06D9 , EddVisT2N07D1 , EddVisT2N07D2 , & - EddVisT2N07D3 , EddVisT2N07D4 , EddVisT2N07D5 , EddVisT2N07D6 , EddVisT2N07D7 , EddVisT2N07D8 , EddVisT2N07D9 , EddVisT2N08D1 , & - EddVisT2N08D2 , EddVisT2N08D3 , EddVisT2N08D4 , EddVisT2N08D5 , EddVisT2N08D6 , EddVisT2N08D7 , EddVisT2N08D8 , EddVisT2N08D9 , & - EddVisT2N09D1 , EddVisT2N09D2 , EddVisT2N09D3 , EddVisT2N09D4 , EddVisT2N09D5 , EddVisT2N09D6 , EddVisT2N09D7 , EddVisT2N09D8 , & - EddVisT2N09D9 , EddVisT2N10D1 , EddVisT2N10D2 , EddVisT2N10D3 , EddVisT2N10D4 , EddVisT2N10D5 , EddVisT2N10D6 , EddVisT2N10D7 , & - EddVisT2N10D8 , EddVisT2N10D9 , EddVisT2N11D1 , EddVisT2N11D2 , EddVisT2N11D3 , EddVisT2N11D4 , EddVisT2N11D5 , EddVisT2N11D6 , & - EddVisT2N11D7 , EddVisT2N11D8 , EddVisT2N11D9 , EddVisT2N12D1 , EddVisT2N12D2 , EddVisT2N12D3 , EddVisT2N12D4 , EddVisT2N12D5 , & - EddVisT2N12D6 , EddVisT2N12D7 , EddVisT2N12D8 , EddVisT2N12D9 , EddVisT2N13D1 , EddVisT2N13D2 , EddVisT2N13D3 , EddVisT2N13D4 , & - EddVisT2N13D5 , EddVisT2N13D6 , EddVisT2N13D7 , EddVisT2N13D8 , EddVisT2N13D9 , EddVisT2N14D1 , EddVisT2N14D2 , EddVisT2N14D3 , & - EddVisT2N14D4 , EddVisT2N14D5 , EddVisT2N14D6 , EddVisT2N14D7 , EddVisT2N14D8 , EddVisT2N14D9 , EddVisT2N15D1 , EddVisT2N15D2 , & - EddVisT2N15D3 , EddVisT2N15D4 , EddVisT2N15D5 , EddVisT2N15D6 , EddVisT2N15D7 , EddVisT2N15D8 , EddVisT2N15D9 , EddVisT2N16D1 , & - EddVisT2N16D2 , EddVisT2N16D3 , EddVisT2N16D4 , EddVisT2N16D5 , EddVisT2N16D6 , EddVisT2N16D7 , EddVisT2N16D8 , EddVisT2N16D9 , & - EddVisT2N17D1 , EddVisT2N17D2 , EddVisT2N17D3 , EddVisT2N17D4 , EddVisT2N17D5 , EddVisT2N17D6 , EddVisT2N17D7 , EddVisT2N17D8 , & - EddVisT2N17D9 , EddVisT2N18D1 , EddVisT2N18D2 , EddVisT2N18D3 , EddVisT2N18D4 , EddVisT2N18D5 , EddVisT2N18D6 , EddVisT2N18D7 , & - EddVisT2N18D8 , EddVisT2N18D9 , EddVisT2N19D1 , EddVisT2N19D2 , EddVisT2N19D3 , EddVisT2N19D4 , EddVisT2N19D5 , EddVisT2N19D6 , & - EddVisT2N19D7 , EddVisT2N19D8 , EddVisT2N19D9 , EddVisT2N20D1 , EddVisT2N20D2 , EddVisT2N20D3 , EddVisT2N20D4 , EddVisT2N20D5 , & - EddVisT2N20D6 , EddVisT2N20D7 , EddVisT2N20D8 , EddVisT2N20D9 , EddVisT3N01D1 , EddVisT3N01D2 , EddVisT3N01D3 , EddVisT3N01D4 , & - EddVisT3N01D5 , EddVisT3N01D6 , EddVisT3N01D7 , EddVisT3N01D8 , EddVisT3N01D9 , EddVisT3N02D1 , EddVisT3N02D2 , EddVisT3N02D3 , & - EddVisT3N02D4 , EddVisT3N02D5 , EddVisT3N02D6 , EddVisT3N02D7 , EddVisT3N02D8 , EddVisT3N02D9 , EddVisT3N03D1 , EddVisT3N03D2 , & - EddVisT3N03D3 , EddVisT3N03D4 , EddVisT3N03D5 , EddVisT3N03D6 , EddVisT3N03D7 , EddVisT3N03D8 , EddVisT3N03D9 , EddVisT3N04D1 , & - EddVisT3N04D2 , EddVisT3N04D3 , EddVisT3N04D4 , EddVisT3N04D5 , EddVisT3N04D6 , EddVisT3N04D7 , EddVisT3N04D8 , EddVisT3N04D9 , & - EddVisT3N05D1 , EddVisT3N05D2 , EddVisT3N05D3 , EddVisT3N05D4 , EddVisT3N05D5 , EddVisT3N05D6 , EddVisT3N05D7 , EddVisT3N05D8 , & - EddVisT3N05D9 , EddVisT3N06D1 , EddVisT3N06D2 , EddVisT3N06D3 , EddVisT3N06D4 , EddVisT3N06D5 , EddVisT3N06D6 , EddVisT3N06D7 , & - EddVisT3N06D8 , EddVisT3N06D9 , EddVisT3N07D1 , EddVisT3N07D2 , EddVisT3N07D3 , EddVisT3N07D4 , EddVisT3N07D5 , EddVisT3N07D6 , & - EddVisT3N07D7 , EddVisT3N07D8 , EddVisT3N07D9 , EddVisT3N08D1 , EddVisT3N08D2 , EddVisT3N08D3 , EddVisT3N08D4 , EddVisT3N08D5 , & - EddVisT3N08D6 , EddVisT3N08D7 , EddVisT3N08D8 , EddVisT3N08D9 , EddVisT3N09D1 , EddVisT3N09D2 , EddVisT3N09D3 , EddVisT3N09D4 , & - EddVisT3N09D5 , EddVisT3N09D6 , EddVisT3N09D7 , EddVisT3N09D8 , EddVisT3N09D9 , EddVisT3N10D1 , EddVisT3N10D2 , EddVisT3N10D3 , & - EddVisT3N10D4 , EddVisT3N10D5 , EddVisT3N10D6 , EddVisT3N10D7 , EddVisT3N10D8 , EddVisT3N10D9 , EddVisT3N11D1 , EddVisT3N11D2 , & - EddVisT3N11D3 , EddVisT3N11D4 , EddVisT3N11D5 , EddVisT3N11D6 , EddVisT3N11D7 , EddVisT3N11D8 , EddVisT3N11D9 , EddVisT3N12D1 , & - EddVisT3N12D2 , EddVisT3N12D3 , EddVisT3N12D4 , EddVisT3N12D5 , EddVisT3N12D6 , EddVisT3N12D7 , EddVisT3N12D8 , EddVisT3N12D9 , & - EddVisT3N13D1 , EddVisT3N13D2 , EddVisT3N13D3 , EddVisT3N13D4 , EddVisT3N13D5 , EddVisT3N13D6 , EddVisT3N13D7 , EddVisT3N13D8 , & - EddVisT3N13D9 , EddVisT3N14D1 , EddVisT3N14D2 , EddVisT3N14D3 , EddVisT3N14D4 , EddVisT3N14D5 , EddVisT3N14D6 , EddVisT3N14D7 , & - EddVisT3N14D8 , EddVisT3N14D9 , EddVisT3N15D1 , EddVisT3N15D2 , EddVisT3N15D3 , EddVisT3N15D4 , EddVisT3N15D5 , EddVisT3N15D6 , & - EddVisT3N15D7 , EddVisT3N15D8 , EddVisT3N15D9 , EddVisT3N16D1 , EddVisT3N16D2 , EddVisT3N16D3 , EddVisT3N16D4 , EddVisT3N16D5 , & - EddVisT3N16D6 , EddVisT3N16D7 , EddVisT3N16D8 , EddVisT3N16D9 , EddVisT3N17D1 , EddVisT3N17D2 , EddVisT3N17D3 , EddVisT3N17D4 , & - EddVisT3N17D5 , EddVisT3N17D6 , EddVisT3N17D7 , EddVisT3N17D8 , EddVisT3N17D9 , EddVisT3N18D1 , EddVisT3N18D2 , EddVisT3N18D3 , & - EddVisT3N18D4 , EddVisT3N18D5 , EddVisT3N18D6 , EddVisT3N18D7 , EddVisT3N18D8 , EddVisT3N18D9 , EddVisT3N19D1 , EddVisT3N19D2 , & - EddVisT3N19D3 , EddVisT3N19D4 , EddVisT3N19D5 , EddVisT3N19D6 , EddVisT3N19D7 , EddVisT3N19D8 , EddVisT3N19D9 , EddVisT3N20D1 , & - EddVisT3N20D2 , EddVisT3N20D3 , EddVisT3N20D4 , EddVisT3N20D5 , EddVisT3N20D6 , EddVisT3N20D7 , EddVisT3N20D8 , EddVisT3N20D9 , & - EddVisT4N01D1 , EddVisT4N01D2 , EddVisT4N01D3 , EddVisT4N01D4 , EddVisT4N01D5 , EddVisT4N01D6 , EddVisT4N01D7 , EddVisT4N01D8 , & - EddVisT4N01D9 , EddVisT4N02D1 , EddVisT4N02D2 , EddVisT4N02D3 , EddVisT4N02D4 , EddVisT4N02D5 , EddVisT4N02D6 , EddVisT4N02D7 , & - EddVisT4N02D8 , EddVisT4N02D9 , EddVisT4N03D1 , EddVisT4N03D2 , EddVisT4N03D3 , EddVisT4N03D4 , EddVisT4N03D5 , EddVisT4N03D6 , & - EddVisT4N03D7 , EddVisT4N03D8 , EddVisT4N03D9 , EddVisT4N04D1 , EddVisT4N04D2 , EddVisT4N04D3 , EddVisT4N04D4 , EddVisT4N04D5 , & - EddVisT4N04D6 , EddVisT4N04D7 , EddVisT4N04D8 , EddVisT4N04D9 , EddVisT4N05D1 , EddVisT4N05D2 , EddVisT4N05D3 , EddVisT4N05D4 , & - EddVisT4N05D5 , EddVisT4N05D6 , EddVisT4N05D7 , EddVisT4N05D8 , EddVisT4N05D9 , EddVisT4N06D1 , EddVisT4N06D2 , EddVisT4N06D3 , & - EddVisT4N06D4 , EddVisT4N06D5 , EddVisT4N06D6 , EddVisT4N06D7 , EddVisT4N06D8 , EddVisT4N06D9 , EddVisT4N07D1 , EddVisT4N07D2 , & - EddVisT4N07D3 , EddVisT4N07D4 , EddVisT4N07D5 , EddVisT4N07D6 , EddVisT4N07D7 , EddVisT4N07D8 , EddVisT4N07D9 , EddVisT4N08D1 , & - EddVisT4N08D2 , EddVisT4N08D3 , EddVisT4N08D4 , EddVisT4N08D5 , EddVisT4N08D6 , EddVisT4N08D7 , EddVisT4N08D8 , EddVisT4N08D9 , & - EddVisT4N09D1 , EddVisT4N09D2 , EddVisT4N09D3 , EddVisT4N09D4 , EddVisT4N09D5 , EddVisT4N09D6 , EddVisT4N09D7 , EddVisT4N09D8 , & - EddVisT4N09D9 , EddVisT4N10D1 , EddVisT4N10D2 , EddVisT4N10D3 , EddVisT4N10D4 , EddVisT4N10D5 , EddVisT4N10D6 , EddVisT4N10D7 , & - EddVisT4N10D8 , EddVisT4N10D9 , EddVisT4N11D1 , EddVisT4N11D2 , EddVisT4N11D3 , EddVisT4N11D4 , EddVisT4N11D5 , EddVisT4N11D6 , & - EddVisT4N11D7 , EddVisT4N11D8 , EddVisT4N11D9 , EddVisT4N12D1 , EddVisT4N12D2 , EddVisT4N12D3 , EddVisT4N12D4 , EddVisT4N12D5 , & - EddVisT4N12D6 , EddVisT4N12D7 , EddVisT4N12D8 , EddVisT4N12D9 , EddVisT4N13D1 , EddVisT4N13D2 , EddVisT4N13D3 , EddVisT4N13D4 , & - EddVisT4N13D5 , EddVisT4N13D6 , EddVisT4N13D7 , EddVisT4N13D8 , EddVisT4N13D9 , EddVisT4N14D1 , EddVisT4N14D2 , EddVisT4N14D3 /) - ParamIndxAry(4081:6120) = (/ & - EddVisT4N14D4 , EddVisT4N14D5 , EddVisT4N14D6 , EddVisT4N14D7 , EddVisT4N14D8 , EddVisT4N14D9 , EddVisT4N15D1 , EddVisT4N15D2 , & - EddVisT4N15D3 , EddVisT4N15D4 , EddVisT4N15D5 , EddVisT4N15D6 , EddVisT4N15D7 , EddVisT4N15D8 , EddVisT4N15D9 , EddVisT4N16D1 , & - EddVisT4N16D2 , EddVisT4N16D3 , EddVisT4N16D4 , EddVisT4N16D5 , EddVisT4N16D6 , EddVisT4N16D7 , EddVisT4N16D8 , EddVisT4N16D9 , & - EddVisT4N17D1 , EddVisT4N17D2 , EddVisT4N17D3 , EddVisT4N17D4 , EddVisT4N17D5 , EddVisT4N17D6 , EddVisT4N17D7 , EddVisT4N17D8 , & - EddVisT4N17D9 , EddVisT4N18D1 , EddVisT4N18D2 , EddVisT4N18D3 , EddVisT4N18D4 , EddVisT4N18D5 , EddVisT4N18D6 , EddVisT4N18D7 , & - EddVisT4N18D8 , EddVisT4N18D9 , EddVisT4N19D1 , EddVisT4N19D2 , EddVisT4N19D3 , EddVisT4N19D4 , EddVisT4N19D5 , EddVisT4N19D6 , & - EddVisT4N19D7 , EddVisT4N19D8 , EddVisT4N19D9 , EddVisT4N20D1 , EddVisT4N20D2 , EddVisT4N20D3 , EddVisT4N20D4 , EddVisT4N20D5 , & - EddVisT4N20D6 , EddVisT4N20D7 , EddVisT4N20D8 , EddVisT4N20D9 , EddVisT5N01D1 , EddVisT5N01D2 , EddVisT5N01D3 , EddVisT5N01D4 , & - EddVisT5N01D5 , EddVisT5N01D6 , EddVisT5N01D7 , EddVisT5N01D8 , EddVisT5N01D9 , EddVisT5N02D1 , EddVisT5N02D2 , EddVisT5N02D3 , & - EddVisT5N02D4 , EddVisT5N02D5 , EddVisT5N02D6 , EddVisT5N02D7 , EddVisT5N02D8 , EddVisT5N02D9 , EddVisT5N03D1 , EddVisT5N03D2 , & - EddVisT5N03D3 , EddVisT5N03D4 , EddVisT5N03D5 , EddVisT5N03D6 , EddVisT5N03D7 , EddVisT5N03D8 , EddVisT5N03D9 , EddVisT5N04D1 , & - EddVisT5N04D2 , EddVisT5N04D3 , EddVisT5N04D4 , EddVisT5N04D5 , EddVisT5N04D6 , EddVisT5N04D7 , EddVisT5N04D8 , EddVisT5N04D9 , & - EddVisT5N05D1 , EddVisT5N05D2 , EddVisT5N05D3 , EddVisT5N05D4 , EddVisT5N05D5 , EddVisT5N05D6 , EddVisT5N05D7 , EddVisT5N05D8 , & - EddVisT5N05D9 , EddVisT5N06D1 , EddVisT5N06D2 , EddVisT5N06D3 , EddVisT5N06D4 , EddVisT5N06D5 , EddVisT5N06D6 , EddVisT5N06D7 , & - EddVisT5N06D8 , EddVisT5N06D9 , EddVisT5N07D1 , EddVisT5N07D2 , EddVisT5N07D3 , EddVisT5N07D4 , EddVisT5N07D5 , EddVisT5N07D6 , & - EddVisT5N07D7 , EddVisT5N07D8 , EddVisT5N07D9 , EddVisT5N08D1 , EddVisT5N08D2 , EddVisT5N08D3 , EddVisT5N08D4 , EddVisT5N08D5 , & - EddVisT5N08D6 , EddVisT5N08D7 , EddVisT5N08D8 , EddVisT5N08D9 , EddVisT5N09D1 , EddVisT5N09D2 , EddVisT5N09D3 , EddVisT5N09D4 , & - EddVisT5N09D5 , EddVisT5N09D6 , EddVisT5N09D7 , EddVisT5N09D8 , EddVisT5N09D9 , EddVisT5N10D1 , EddVisT5N10D2 , EddVisT5N10D3 , & - EddVisT5N10D4 , EddVisT5N10D5 , EddVisT5N10D6 , EddVisT5N10D7 , EddVisT5N10D8 , EddVisT5N10D9 , EddVisT5N11D1 , EddVisT5N11D2 , & - EddVisT5N11D3 , EddVisT5N11D4 , EddVisT5N11D5 , EddVisT5N11D6 , EddVisT5N11D7 , EddVisT5N11D8 , EddVisT5N11D9 , EddVisT5N12D1 , & - EddVisT5N12D2 , EddVisT5N12D3 , EddVisT5N12D4 , EddVisT5N12D5 , EddVisT5N12D6 , EddVisT5N12D7 , EddVisT5N12D8 , EddVisT5N12D9 , & - EddVisT5N13D1 , EddVisT5N13D2 , EddVisT5N13D3 , EddVisT5N13D4 , EddVisT5N13D5 , EddVisT5N13D6 , EddVisT5N13D7 , EddVisT5N13D8 , & - EddVisT5N13D9 , EddVisT5N14D1 , EddVisT5N14D2 , EddVisT5N14D3 , EddVisT5N14D4 , EddVisT5N14D5 , EddVisT5N14D6 , EddVisT5N14D7 , & - EddVisT5N14D8 , EddVisT5N14D9 , EddVisT5N15D1 , EddVisT5N15D2 , EddVisT5N15D3 , EddVisT5N15D4 , EddVisT5N15D5 , EddVisT5N15D6 , & - EddVisT5N15D7 , EddVisT5N15D8 , EddVisT5N15D9 , EddVisT5N16D1 , EddVisT5N16D2 , EddVisT5N16D3 , EddVisT5N16D4 , EddVisT5N16D5 , & - EddVisT5N16D6 , EddVisT5N16D7 , EddVisT5N16D8 , EddVisT5N16D9 , EddVisT5N17D1 , EddVisT5N17D2 , EddVisT5N17D3 , EddVisT5N17D4 , & - EddVisT5N17D5 , EddVisT5N17D6 , EddVisT5N17D7 , EddVisT5N17D8 , EddVisT5N17D9 , EddVisT5N18D1 , EddVisT5N18D2 , EddVisT5N18D3 , & - EddVisT5N18D4 , EddVisT5N18D5 , EddVisT5N18D6 , EddVisT5N18D7 , EddVisT5N18D8 , EddVisT5N18D9 , EddVisT5N19D1 , EddVisT5N19D2 , & - EddVisT5N19D3 , EddVisT5N19D4 , EddVisT5N19D5 , EddVisT5N19D6 , EddVisT5N19D7 , EddVisT5N19D8 , EddVisT5N19D9 , EddVisT5N20D1 , & - EddVisT5N20D2 , EddVisT5N20D3 , EddVisT5N20D4 , EddVisT5N20D5 , EddVisT5N20D6 , EddVisT5N20D7 , EddVisT5N20D8 , EddVisT5N20D9 , & - EddVisT6N01D1 , EddVisT6N01D2 , EddVisT6N01D3 , EddVisT6N01D4 , EddVisT6N01D5 , EddVisT6N01D6 , EddVisT6N01D7 , EddVisT6N01D8 , & - EddVisT6N01D9 , EddVisT6N02D1 , EddVisT6N02D2 , EddVisT6N02D3 , EddVisT6N02D4 , EddVisT6N02D5 , EddVisT6N02D6 , EddVisT6N02D7 , & - EddVisT6N02D8 , EddVisT6N02D9 , EddVisT6N03D1 , EddVisT6N03D2 , EddVisT6N03D3 , EddVisT6N03D4 , EddVisT6N03D5 , EddVisT6N03D6 , & - EddVisT6N03D7 , EddVisT6N03D8 , EddVisT6N03D9 , EddVisT6N04D1 , EddVisT6N04D2 , EddVisT6N04D3 , EddVisT6N04D4 , EddVisT6N04D5 , & - EddVisT6N04D6 , EddVisT6N04D7 , EddVisT6N04D8 , EddVisT6N04D9 , EddVisT6N05D1 , EddVisT6N05D2 , EddVisT6N05D3 , EddVisT6N05D4 , & - EddVisT6N05D5 , EddVisT6N05D6 , EddVisT6N05D7 , EddVisT6N05D8 , EddVisT6N05D9 , EddVisT6N06D1 , EddVisT6N06D2 , EddVisT6N06D3 , & - EddVisT6N06D4 , EddVisT6N06D5 , EddVisT6N06D6 , EddVisT6N06D7 , EddVisT6N06D8 , EddVisT6N06D9 , EddVisT6N07D1 , EddVisT6N07D2 , & - EddVisT6N07D3 , EddVisT6N07D4 , EddVisT6N07D5 , EddVisT6N07D6 , EddVisT6N07D7 , EddVisT6N07D8 , EddVisT6N07D9 , EddVisT6N08D1 , & - EddVisT6N08D2 , EddVisT6N08D3 , EddVisT6N08D4 , EddVisT6N08D5 , EddVisT6N08D6 , EddVisT6N08D7 , EddVisT6N08D8 , EddVisT6N08D9 , & - EddVisT6N09D1 , EddVisT6N09D2 , EddVisT6N09D3 , EddVisT6N09D4 , EddVisT6N09D5 , EddVisT6N09D6 , EddVisT6N09D7 , EddVisT6N09D8 , & - EddVisT6N09D9 , EddVisT6N10D1 , EddVisT6N10D2 , EddVisT6N10D3 , EddVisT6N10D4 , EddVisT6N10D5 , EddVisT6N10D6 , EddVisT6N10D7 , & - EddVisT6N10D8 , EddVisT6N10D9 , EddVisT6N11D1 , EddVisT6N11D2 , EddVisT6N11D3 , EddVisT6N11D4 , EddVisT6N11D5 , EddVisT6N11D6 , & - EddVisT6N11D7 , EddVisT6N11D8 , EddVisT6N11D9 , EddVisT6N12D1 , EddVisT6N12D2 , EddVisT6N12D3 , EddVisT6N12D4 , EddVisT6N12D5 , & - EddVisT6N12D6 , EddVisT6N12D7 , EddVisT6N12D8 , EddVisT6N12D9 , EddVisT6N13D1 , EddVisT6N13D2 , EddVisT6N13D3 , EddVisT6N13D4 , & - EddVisT6N13D5 , EddVisT6N13D6 , EddVisT6N13D7 , EddVisT6N13D8 , EddVisT6N13D9 , EddVisT6N14D1 , EddVisT6N14D2 , EddVisT6N14D3 , & - EddVisT6N14D4 , EddVisT6N14D5 , EddVisT6N14D6 , EddVisT6N14D7 , EddVisT6N14D8 , EddVisT6N14D9 , EddVisT6N15D1 , EddVisT6N15D2 , & - EddVisT6N15D3 , EddVisT6N15D4 , EddVisT6N15D5 , EddVisT6N15D6 , EddVisT6N15D7 , EddVisT6N15D8 , EddVisT6N15D9 , EddVisT6N16D1 , & - EddVisT6N16D2 , EddVisT6N16D3 , EddVisT6N16D4 , EddVisT6N16D5 , EddVisT6N16D6 , EddVisT6N16D7 , EddVisT6N16D8 , EddVisT6N16D9 , & - EddVisT6N17D1 , EddVisT6N17D2 , EddVisT6N17D3 , EddVisT6N17D4 , EddVisT6N17D5 , EddVisT6N17D6 , EddVisT6N17D7 , EddVisT6N17D8 , & - EddVisT6N17D9 , EddVisT6N18D1 , EddVisT6N18D2 , EddVisT6N18D3 , EddVisT6N18D4 , EddVisT6N18D5 , EddVisT6N18D6 , EddVisT6N18D7 , & - EddVisT6N18D8 , EddVisT6N18D9 , EddVisT6N19D1 , EddVisT6N19D2 , EddVisT6N19D3 , EddVisT6N19D4 , EddVisT6N19D5 , EddVisT6N19D6 , & - EddVisT6N19D7 , EddVisT6N19D8 , EddVisT6N19D9 , EddVisT6N20D1 , EddVisT6N20D2 , EddVisT6N20D3 , EddVisT6N20D4 , EddVisT6N20D5 , & - EddVisT6N20D6 , EddVisT6N20D7 , EddVisT6N20D8 , EddVisT6N20D9 , EddVisT7N01D1 , EddVisT7N01D2 , EddVisT7N01D3 , EddVisT7N01D4 , & - EddVisT7N01D5 , EddVisT7N01D6 , EddVisT7N01D7 , EddVisT7N01D8 , EddVisT7N01D9 , EddVisT7N02D1 , EddVisT7N02D2 , EddVisT7N02D3 , & - EddVisT7N02D4 , EddVisT7N02D5 , EddVisT7N02D6 , EddVisT7N02D7 , EddVisT7N02D8 , EddVisT7N02D9 , EddVisT7N03D1 , EddVisT7N03D2 , & - EddVisT7N03D3 , EddVisT7N03D4 , EddVisT7N03D5 , EddVisT7N03D6 , EddVisT7N03D7 , EddVisT7N03D8 , EddVisT7N03D9 , EddVisT7N04D1 , & - EddVisT7N04D2 , EddVisT7N04D3 , EddVisT7N04D4 , EddVisT7N04D5 , EddVisT7N04D6 , EddVisT7N04D7 , EddVisT7N04D8 , EddVisT7N04D9 , & - EddVisT7N05D1 , EddVisT7N05D2 , EddVisT7N05D3 , EddVisT7N05D4 , EddVisT7N05D5 , EddVisT7N05D6 , EddVisT7N05D7 , EddVisT7N05D8 , & - EddVisT7N05D9 , EddVisT7N06D1 , EddVisT7N06D2 , EddVisT7N06D3 , EddVisT7N06D4 , EddVisT7N06D5 , EddVisT7N06D6 , EddVisT7N06D7 , & - EddVisT7N06D8 , EddVisT7N06D9 , EddVisT7N07D1 , EddVisT7N07D2 , EddVisT7N07D3 , EddVisT7N07D4 , EddVisT7N07D5 , EddVisT7N07D6 , & - EddVisT7N07D7 , EddVisT7N07D8 , EddVisT7N07D9 , EddVisT7N08D1 , EddVisT7N08D2 , EddVisT7N08D3 , EddVisT7N08D4 , EddVisT7N08D5 , & - EddVisT7N08D6 , EddVisT7N08D7 , EddVisT7N08D8 , EddVisT7N08D9 , EddVisT7N09D1 , EddVisT7N09D2 , EddVisT7N09D3 , EddVisT7N09D4 , & - EddVisT7N09D5 , EddVisT7N09D6 , EddVisT7N09D7 , EddVisT7N09D8 , EddVisT7N09D9 , EddVisT7N10D1 , EddVisT7N10D2 , EddVisT7N10D3 , & - EddVisT7N10D4 , EddVisT7N10D5 , EddVisT7N10D6 , EddVisT7N10D7 , EddVisT7N10D8 , EddVisT7N10D9 , EddVisT7N11D1 , EddVisT7N11D2 , & - EddVisT7N11D3 , EddVisT7N11D4 , EddVisT7N11D5 , EddVisT7N11D6 , EddVisT7N11D7 , EddVisT7N11D8 , EddVisT7N11D9 , EddVisT7N12D1 , & - EddVisT7N12D2 , EddVisT7N12D3 , EddVisT7N12D4 , EddVisT7N12D5 , EddVisT7N12D6 , EddVisT7N12D7 , EddVisT7N12D8 , EddVisT7N12D9 , & - EddVisT7N13D1 , EddVisT7N13D2 , EddVisT7N13D3 , EddVisT7N13D4 , EddVisT7N13D5 , EddVisT7N13D6 , EddVisT7N13D7 , EddVisT7N13D8 , & - EddVisT7N13D9 , EddVisT7N14D1 , EddVisT7N14D2 , EddVisT7N14D3 , EddVisT7N14D4 , EddVisT7N14D5 , EddVisT7N14D6 , EddVisT7N14D7 , & - EddVisT7N14D8 , EddVisT7N14D9 , EddVisT7N15D1 , EddVisT7N15D2 , EddVisT7N15D3 , EddVisT7N15D4 , EddVisT7N15D5 , EddVisT7N15D6 , & - EddVisT7N15D7 , EddVisT7N15D8 , EddVisT7N15D9 , EddVisT7N16D1 , EddVisT7N16D2 , EddVisT7N16D3 , EddVisT7N16D4 , EddVisT7N16D5 , & - EddVisT7N16D6 , EddVisT7N16D7 , EddVisT7N16D8 , EddVisT7N16D9 , EddVisT7N17D1 , EddVisT7N17D2 , EddVisT7N17D3 , EddVisT7N17D4 , & - EddVisT7N17D5 , EddVisT7N17D6 , EddVisT7N17D7 , EddVisT7N17D8 , EddVisT7N17D9 , EddVisT7N18D1 , EddVisT7N18D2 , EddVisT7N18D3 , & - EddVisT7N18D4 , EddVisT7N18D5 , EddVisT7N18D6 , EddVisT7N18D7 , EddVisT7N18D8 , EddVisT7N18D9 , EddVisT7N19D1 , EddVisT7N19D2 , & - EddVisT7N19D3 , EddVisT7N19D4 , EddVisT7N19D5 , EddVisT7N19D6 , EddVisT7N19D7 , EddVisT7N19D8 , EddVisT7N19D9 , EddVisT7N20D1 , & - EddVisT7N20D2 , EddVisT7N20D3 , EddVisT7N20D4 , EddVisT7N20D5 , EddVisT7N20D6 , EddVisT7N20D7 , EddVisT7N20D8 , EddVisT7N20D9 , & - EddVisT8N01D1 , EddVisT8N01D2 , EddVisT8N01D3 , EddVisT8N01D4 , EddVisT8N01D5 , EddVisT8N01D6 , EddVisT8N01D7 , EddVisT8N01D8 , & - EddVisT8N01D9 , EddVisT8N02D1 , EddVisT8N02D2 , EddVisT8N02D3 , EddVisT8N02D4 , EddVisT8N02D5 , EddVisT8N02D6 , EddVisT8N02D7 , & - EddVisT8N02D8 , EddVisT8N02D9 , EddVisT8N03D1 , EddVisT8N03D2 , EddVisT8N03D3 , EddVisT8N03D4 , EddVisT8N03D5 , EddVisT8N03D6 , & - EddVisT8N03D7 , EddVisT8N03D8 , EddVisT8N03D9 , EddVisT8N04D1 , EddVisT8N04D2 , EddVisT8N04D3 , EddVisT8N04D4 , EddVisT8N04D5 , & - EddVisT8N04D6 , EddVisT8N04D7 , EddVisT8N04D8 , EddVisT8N04D9 , EddVisT8N05D1 , EddVisT8N05D2 , EddVisT8N05D3 , EddVisT8N05D4 , & - EddVisT8N05D5 , EddVisT8N05D6 , EddVisT8N05D7 , EddVisT8N05D8 , EddVisT8N05D9 , EddVisT8N06D1 , EddVisT8N06D2 , EddVisT8N06D3 , & - EddVisT8N06D4 , EddVisT8N06D5 , EddVisT8N06D6 , EddVisT8N06D7 , EddVisT8N06D8 , EddVisT8N06D9 , EddVisT8N07D1 , EddVisT8N07D2 , & - EddVisT8N07D3 , EddVisT8N07D4 , EddVisT8N07D5 , EddVisT8N07D6 , EddVisT8N07D7 , EddVisT8N07D8 , EddVisT8N07D9 , EddVisT8N08D1 , & - EddVisT8N08D2 , EddVisT8N08D3 , EddVisT8N08D4 , EddVisT8N08D5 , EddVisT8N08D6 , EddVisT8N08D7 , EddVisT8N08D8 , EddVisT8N08D9 , & - EddVisT8N09D1 , EddVisT8N09D2 , EddVisT8N09D3 , EddVisT8N09D4 , EddVisT8N09D5 , EddVisT8N09D6 , EddVisT8N09D7 , EddVisT8N09D8 , & - EddVisT8N09D9 , EddVisT8N10D1 , EddVisT8N10D2 , EddVisT8N10D3 , EddVisT8N10D4 , EddVisT8N10D5 , EddVisT8N10D6 , EddVisT8N10D7 , & - EddVisT8N10D8 , EddVisT8N10D9 , EddVisT8N11D1 , EddVisT8N11D2 , EddVisT8N11D3 , EddVisT8N11D4 , EddVisT8N11D5 , EddVisT8N11D6 , & - EddVisT8N11D7 , EddVisT8N11D8 , EddVisT8N11D9 , EddVisT8N12D1 , EddVisT8N12D2 , EddVisT8N12D3 , EddVisT8N12D4 , EddVisT8N12D5 , & - EddVisT8N12D6 , EddVisT8N12D7 , EddVisT8N12D8 , EddVisT8N12D9 , EddVisT8N13D1 , EddVisT8N13D2 , EddVisT8N13D3 , EddVisT8N13D4 , & - EddVisT8N13D5 , EddVisT8N13D6 , EddVisT8N13D7 , EddVisT8N13D8 , EddVisT8N13D9 , EddVisT8N14D1 , EddVisT8N14D2 , EddVisT8N14D3 , & - EddVisT8N14D4 , EddVisT8N14D5 , EddVisT8N14D6 , EddVisT8N14D7 , EddVisT8N14D8 , EddVisT8N14D9 , EddVisT8N15D1 , EddVisT8N15D2 , & - EddVisT8N15D3 , EddVisT8N15D4 , EddVisT8N15D5 , EddVisT8N15D6 , EddVisT8N15D7 , EddVisT8N15D8 , EddVisT8N15D9 , EddVisT8N16D1 , & - EddVisT8N16D2 , EddVisT8N16D3 , EddVisT8N16D4 , EddVisT8N16D5 , EddVisT8N16D6 , EddVisT8N16D7 , EddVisT8N16D8 , EddVisT8N16D9 , & - EddVisT8N17D1 , EddVisT8N17D2 , EddVisT8N17D3 , EddVisT8N17D4 , EddVisT8N17D5 , EddVisT8N17D6 , EddVisT8N17D7 , EddVisT8N17D8 , & - EddVisT8N17D9 , EddVisT8N18D1 , EddVisT8N18D2 , EddVisT8N18D3 , EddVisT8N18D4 , EddVisT8N18D5 , EddVisT8N18D6 , EddVisT8N18D7 , & - EddVisT8N18D8 , EddVisT8N18D9 , EddVisT8N19D1 , EddVisT8N19D2 , EddVisT8N19D3 , EddVisT8N19D4 , EddVisT8N19D5 , EddVisT8N19D6 , & - EddVisT8N19D7 , EddVisT8N19D8 , EddVisT8N19D9 , EddVisT8N20D1 , EddVisT8N20D2 , EddVisT8N20D3 , EddVisT8N20D4 , EddVisT8N20D5 , & - EddVisT8N20D6 , EddVisT8N20D7 , EddVisT8N20D8 , EddVisT8N20D9 , EddVisT9N01D1 , EddVisT9N01D2 , EddVisT9N01D3 , EddVisT9N01D4 , & - EddVisT9N01D5 , EddVisT9N01D6 , EddVisT9N01D7 , EddVisT9N01D8 , EddVisT9N01D9 , EddVisT9N02D1 , EddVisT9N02D2 , EddVisT9N02D3 , & - EddVisT9N02D4 , EddVisT9N02D5 , EddVisT9N02D6 , EddVisT9N02D7 , EddVisT9N02D8 , EddVisT9N02D9 , EddVisT9N03D1 , EddVisT9N03D2 , & - EddVisT9N03D3 , EddVisT9N03D4 , EddVisT9N03D5 , EddVisT9N03D6 , EddVisT9N03D7 , EddVisT9N03D8 , EddVisT9N03D9 , EddVisT9N04D1 , & - EddVisT9N04D2 , EddVisT9N04D3 , EddVisT9N04D4 , EddVisT9N04D5 , EddVisT9N04D6 , EddVisT9N04D7 , EddVisT9N04D8 , EddVisT9N04D9 , & - EddVisT9N05D1 , EddVisT9N05D2 , EddVisT9N05D3 , EddVisT9N05D4 , EddVisT9N05D5 , EddVisT9N05D6 , EddVisT9N05D7 , EddVisT9N05D8 , & - EddVisT9N05D9 , EddVisT9N06D1 , EddVisT9N06D2 , EddVisT9N06D3 , EddVisT9N06D4 , EddVisT9N06D5 , EddVisT9N06D6 , EddVisT9N06D7 , & - EddVisT9N06D8 , EddVisT9N06D9 , EddVisT9N07D1 , EddVisT9N07D2 , EddVisT9N07D3 , EddVisT9N07D4 , EddVisT9N07D5 , EddVisT9N07D6 , & - EddVisT9N07D7 , EddVisT9N07D8 , EddVisT9N07D9 , EddVisT9N08D1 , EddVisT9N08D2 , EddVisT9N08D3 , EddVisT9N08D4 , EddVisT9N08D5 , & - EddVisT9N08D6 , EddVisT9N08D7 , EddVisT9N08D8 , EddVisT9N08D9 , EddVisT9N09D1 , EddVisT9N09D2 , EddVisT9N09D3 , EddVisT9N09D4 , & - EddVisT9N09D5 , EddVisT9N09D6 , EddVisT9N09D7 , EddVisT9N09D8 , EddVisT9N09D9 , EddVisT9N10D1 , EddVisT9N10D2 , EddVisT9N10D3 , & - EddVisT9N10D4 , EddVisT9N10D5 , EddVisT9N10D6 , EddVisT9N10D7 , EddVisT9N10D8 , EddVisT9N10D9 , EddVisT9N11D1 , EddVisT9N11D2 , & - EddVisT9N11D3 , EddVisT9N11D4 , EddVisT9N11D5 , EddVisT9N11D6 , EddVisT9N11D7 , EddVisT9N11D8 , EddVisT9N11D9 , EddVisT9N12D1 , & - EddVisT9N12D2 , EddVisT9N12D3 , EddVisT9N12D4 , EddVisT9N12D5 , EddVisT9N12D6 , EddVisT9N12D7 , EddVisT9N12D8 , EddVisT9N12D9 , & - EddVisT9N13D1 , EddVisT9N13D2 , EddVisT9N13D3 , EddVisT9N13D4 , EddVisT9N13D5 , EddVisT9N13D6 , EddVisT9N13D7 , EddVisT9N13D8 , & - EddVisT9N13D9 , EddVisT9N14D1 , EddVisT9N14D2 , EddVisT9N14D3 , EddVisT9N14D4 , EddVisT9N14D5 , EddVisT9N14D6 , EddVisT9N14D7 , & - EddVisT9N14D8 , EddVisT9N14D9 , EddVisT9N15D1 , EddVisT9N15D2 , EddVisT9N15D3 , EddVisT9N15D4 , EddVisT9N15D5 , EddVisT9N15D6 , & - EddVisT9N15D7 , EddVisT9N15D8 , EddVisT9N15D9 , EddVisT9N16D1 , EddVisT9N16D2 , EddVisT9N16D3 , EddVisT9N16D4 , EddVisT9N16D5 , & - EddVisT9N16D6 , EddVisT9N16D7 , EddVisT9N16D8 , EddVisT9N16D9 , EddVisT9N17D1 , EddVisT9N17D2 , EddVisT9N17D3 , EddVisT9N17D4 , & - EddVisT9N17D5 , EddVisT9N17D6 , EddVisT9N17D7 , EddVisT9N17D8 , EddVisT9N17D9 , EddVisT9N18D1 , EddVisT9N18D2 , EddVisT9N18D3 , & - EddVisT9N18D4 , EddVisT9N18D5 , EddVisT9N18D6 , EddVisT9N18D7 , EddVisT9N18D8 , EddVisT9N18D9 , EddVisT9N19D1 , EddVisT9N19D2 , & - EddVisT9N19D3 , EddVisT9N19D4 , EddVisT9N19D5 , EddVisT9N19D6 , EddVisT9N19D7 , EddVisT9N19D8 , EddVisT9N19D9 , EddVisT9N20D1 , & - EddVisT9N20D2 , EddVisT9N20D3 , EddVisT9N20D4 , EddVisT9N20D5 , EddVisT9N20D6 , EddVisT9N20D7 , EddVisT9N20D8 , EddVisT9N20D9 , & - RtAxsXT1 , RtAxsXT2 , RtAxsXT3 , RtAxsXT4 , RtAxsXT5 , RtAxsXT6 , RtAxsXT7 , RtAxsXT8 , & - RtAxsXT9 , RtAxsYT1 , RtAxsYT2 , RtAxsYT3 , RtAxsYT4 , RtAxsYT5 , RtAxsYT6 , RtAxsYT7 , & - RtAxsYT8 , RtAxsYT9 , RtAxsZT1 , RtAxsZT2 , RtAxsZT3 , RtAxsZT4 , RtAxsZT5 , RtAxsZT6 , & - RtAxsZT7 , RtAxsZT8 , RtAxsZT9 , RtDiamT1 , RtDiamT2 , RtDiamT3 , RtDiamT4 , RtDiamT5 , & - RtDiamT6 , RtDiamT7 , RtDiamT8 , RtDiamT9 , RtPosXT1 , RtPosXT2 , RtPosXT3 , RtPosXT4 , & - RtPosXT5 , RtPosXT6 , RtPosXT7 , RtPosXT8 , RtPosXT9 , RtPosYT1 , RtPosYT2 , RtPosYT3 , & - RtPosYT4 , RtPosYT5 , RtPosYT6 , RtPosYT7 , RtPosYT8 , RtPosYT9 , RtPosZT1 , RtPosZT2 , & - RtPosZT3 , RtPosZT4 , RtPosZT5 , RtPosZT6 , RtPosZT7 , RtPosZT8 , RtPosZT9 , RtVAmbT1 , & - RtVAmbT2 , RtVAmbT3 , RtVAmbT4 , RtVAmbT5 , RtVAmbT6 , RtVAmbT7 , RtVAmbT8 , RtVAmbT9 , & - RtVRelT1 , RtVRelT2 , RtVRelT3 , RtVRelT4 , RtVRelT5 , RtVRelT6 , RtVRelT7 , RtVRelT8 , & - RtVRelT9 , SCGblIn1 , SCGblIn2 , SCGblIn3 , SCGblIn4 , SCGblIn5 , SCGblIn6 , SCGblIn7 , & - SCGblIn8 , SCGblIn9 , SCGblOt1 , SCGblOt2 , SCGblOt3 , SCGblOt4 , SCGblOt5 , SCGblOt6 , & - SCGblOt7 , SCGblOt8 , SCGblOt9 , SCT1In1 , SCT1In2 , SCT1In3 , SCT1In4 , SCT1In5 , & - SCT1In6 , SCT1In7 , SCT1In8 , SCT1In9 , SCT1Ot1 , SCT1Ot2 , SCT1Ot3 , SCT1Ot4 , & - SCT1Ot5 , SCT1Ot6 , SCT1Ot7 , SCT1Ot8 , SCT1Ot9 , SCT2In1 , SCT2In2 , SCT2In3 , & - SCT2In4 , SCT2In5 , SCT2In6 , SCT2In7 , SCT2In8 , SCT2In9 , SCT2Ot1 , SCT2Ot2 , & - SCT2Ot3 , SCT2Ot4 , SCT2Ot5 , SCT2Ot6 , SCT2Ot7 , SCT2Ot8 , SCT2Ot9 , SCT3In1 , & - SCT3In2 , SCT3In3 , SCT3In4 , SCT3In5 , SCT3In6 , SCT3In7 , SCT3In8 , SCT3In9 , & - SCT3Ot1 , SCT3Ot2 , SCT3Ot3 , SCT3Ot4 , SCT3Ot5 , SCT3Ot6 , SCT3Ot7 , SCT3Ot8 , & - SCT3Ot9 , SCT4In1 , SCT4In2 , SCT4In3 , SCT4In4 , SCT4In5 , SCT4In6 , SCT4In7 , & - SCT4In8 , SCT4In9 , SCT4Ot1 , SCT4Ot2 , SCT4Ot3 , SCT4Ot4 , SCT4Ot5 , SCT4Ot6 , & - SCT4Ot7 , SCT4Ot8 , SCT4Ot9 , SCT5In1 , SCT5In2 , SCT5In3 , SCT5In4 , SCT5In5 , & - SCT5In6 , SCT5In7 , SCT5In8 , SCT5In9 , SCT5Ot1 , SCT5Ot2 , SCT5Ot3 , SCT5Ot4 , & - SCT5Ot5 , SCT5Ot6 , SCT5Ot7 , SCT5Ot8 , SCT5Ot9 , SCT6In1 , SCT6In2 , SCT6In3 , & - SCT6In4 , SCT6In5 , SCT6In6 , SCT6In7 , SCT6In8 , SCT6In9 , SCT6Ot1 , SCT6Ot2 , & - SCT6Ot3 , SCT6Ot4 , SCT6Ot5 , SCT6Ot6 , SCT6Ot7 , SCT6Ot8 , SCT6Ot9 , SCT7In1 , & - SCT7In2 , SCT7In3 , SCT7In4 , SCT7In5 , SCT7In6 , SCT7In7 , SCT7In8 , SCT7In9 , & - SCT7Ot1 , SCT7Ot2 , SCT7Ot3 , SCT7Ot4 , SCT7Ot5 , SCT7Ot6 , SCT7Ot7 , SCT7Ot8 , & - SCT7Ot9 , SCT8In1 , SCT8In2 , SCT8In3 , SCT8In4 , SCT8In5 , SCT8In6 , SCT8In7 , & - SCT8In8 , SCT8In9 , SCT8Ot1 , SCT8Ot2 , SCT8Ot3 , SCT8Ot4 , SCT8Ot5 , SCT8Ot6 , & - SCT8Ot7 , SCT8Ot8 , SCT8Ot9 , SCT9In1 , SCT9In2 , SCT9In3 , SCT9In4 , SCT9In5 , & - SCT9In6 , SCT9In7 , SCT9In8 , SCT9In9 , SCT9Ot1 , SCT9Ot2 , SCT9Ot3 , SCT9Ot4 , & - SCT9Ot5 , SCT9Ot6 , SCT9Ot7 , SCT9Ot8 , SCT9Ot9 , TIAmbT1 , TIAmbT2 , TIAmbT3 , & - TIAmbT4 , TIAmbT5 , TIAmbT6 , TIAmbT7 , TIAmbT8 , TIAmbT9 , W1VAmbX , W1VAmbY , & - W1VAmbZ , W1VDisX , W1VDisY , W1VDisZ , W2VAmbX , W2VAmbY , W2VAmbZ , W2VDisX , & - W2VDisY , W2VDisZ , W3VAmbX , W3VAmbY , W3VAmbZ , W3VDisX , W3VDisY , W3VDisZ , & - W4VAmbX , W4VAmbY , W4VAmbZ , W4VDisX , W4VDisY , W4VDisZ , W5VAmbX , W5VAmbY , & - W5VAmbZ , W5VDisX , W5VDisY , W5VDisZ , W6VAmbX , W6VAmbY , W6VAmbZ , W6VDisX , & - W6VDisY , W6VDisZ , W7VAmbX , W7VAmbY , W7VAmbZ , W7VDisX , W7VDisY , W7VDisZ , & - W8VAmbX , W8VAmbY , W8VAmbZ , W8VDisX , W8VDisY , W8VDisZ , W9VAmbX , W9VAmbY , & - W9VAmbZ , W9VDisX , W9VDisY , W9VDisZ , WkAxsXT1D1 , WkAxsXT1D2 , WkAxsXT1D3 , WkAxsXT1D4 , & - WkAxsXT1D5 , WkAxsXT1D6 , WkAxsXT1D7 , WkAxsXT1D8 , WkAxsXT1D9 , WkAxsXT2D1 , WkAxsXT2D2 , WkAxsXT2D3 , & - WkAxsXT2D4 , WkAxsXT2D5 , WkAxsXT2D6 , WkAxsXT2D7 , WkAxsXT2D8 , WkAxsXT2D9 , WkAxsXT3D1 , WkAxsXT3D2 , & - WkAxsXT3D3 , WkAxsXT3D4 , WkAxsXT3D5 , WkAxsXT3D6 , WkAxsXT3D7 , WkAxsXT3D8 , WkAxsXT3D9 , WkAxsXT4D1 , & - WkAxsXT4D2 , WkAxsXT4D3 , WkAxsXT4D4 , WkAxsXT4D5 , WkAxsXT4D6 , WkAxsXT4D7 , WkAxsXT4D8 , WkAxsXT4D9 , & - WkAxsXT5D1 , WkAxsXT5D2 , WkAxsXT5D3 , WkAxsXT5D4 , WkAxsXT5D5 , WkAxsXT5D6 , WkAxsXT5D7 , WkAxsXT5D8 , & - WkAxsXT5D9 , WkAxsXT6D1 , WkAxsXT6D2 , WkAxsXT6D3 , WkAxsXT6D4 , WkAxsXT6D5 , WkAxsXT6D6 , WkAxsXT6D7 , & - WkAxsXT6D8 , WkAxsXT6D9 , WkAxsXT7D1 , WkAxsXT7D2 , WkAxsXT7D3 , WkAxsXT7D4 , WkAxsXT7D5 , WkAxsXT7D6 , & - WkAxsXT7D7 , WkAxsXT7D8 , WkAxsXT7D9 , WkAxsXT8D1 , WkAxsXT8D2 , WkAxsXT8D3 , WkAxsXT8D4 , WkAxsXT8D5 , & - WkAxsXT8D6 , WkAxsXT8D7 , WkAxsXT8D8 , WkAxsXT8D9 , WkAxsXT9D1 , WkAxsXT9D2 , WkAxsXT9D3 , WkAxsXT9D4 , & - WkAxsXT9D5 , WkAxsXT9D6 , WkAxsXT9D7 , WkAxsXT9D8 , WkAxsXT9D9 , WkAxsYT1D1 , WkAxsYT1D2 , WkAxsYT1D3 , & - WkAxsYT1D4 , WkAxsYT1D5 , WkAxsYT1D6 , WkAxsYT1D7 , WkAxsYT1D8 , WkAxsYT1D9 , WkAxsYT2D1 , WkAxsYT2D2 , & - WkAxsYT2D3 , WkAxsYT2D4 , WkAxsYT2D5 , WkAxsYT2D6 , WkAxsYT2D7 , WkAxsYT2D8 , WkAxsYT2D9 , WkAxsYT3D1 , & - WkAxsYT3D2 , WkAxsYT3D3 , WkAxsYT3D4 , WkAxsYT3D5 , WkAxsYT3D6 , WkAxsYT3D7 , WkAxsYT3D8 , WkAxsYT3D9 , & - WkAxsYT4D1 , WkAxsYT4D2 , WkAxsYT4D3 , WkAxsYT4D4 , WkAxsYT4D5 , WkAxsYT4D6 , WkAxsYT4D7 , WkAxsYT4D8 , & - WkAxsYT4D9 , WkAxsYT5D1 , WkAxsYT5D2 , WkAxsYT5D3 , WkAxsYT5D4 , WkAxsYT5D5 , WkAxsYT5D6 , WkAxsYT5D7 , & - WkAxsYT5D8 , WkAxsYT5D9 , WkAxsYT6D1 , WkAxsYT6D2 , WkAxsYT6D3 , WkAxsYT6D4 , WkAxsYT6D5 , WkAxsYT6D6 , & - WkAxsYT6D7 , WkAxsYT6D8 , WkAxsYT6D9 , WkAxsYT7D1 , WkAxsYT7D2 , WkAxsYT7D3 , WkAxsYT7D4 , WkAxsYT7D5 , & - WkAxsYT7D6 , WkAxsYT7D7 , WkAxsYT7D8 , WkAxsYT7D9 , WkAxsYT8D1 , WkAxsYT8D2 , WkAxsYT8D3 , WkAxsYT8D4 , & - WkAxsYT8D5 , WkAxsYT8D6 , WkAxsYT8D7 , WkAxsYT8D8 , WkAxsYT8D9 , WkAxsYT9D1 , WkAxsYT9D2 , WkAxsYT9D3 , & - WkAxsYT9D4 , WkAxsYT9D5 , WkAxsYT9D6 , WkAxsYT9D7 , WkAxsYT9D8 , WkAxsYT9D9 , WkAxsZT1D1 , WkAxsZT1D2 , & - WkAxsZT1D3 , WkAxsZT1D4 , WkAxsZT1D5 , WkAxsZT1D6 , WkAxsZT1D7 , WkAxsZT1D8 , WkAxsZT1D9 , WkAxsZT2D1 , & - WkAxsZT2D2 , WkAxsZT2D3 , WkAxsZT2D4 , WkAxsZT2D5 , WkAxsZT2D6 , WkAxsZT2D7 , WkAxsZT2D8 , WkAxsZT2D9 , & - WkAxsZT3D1 , WkAxsZT3D2 , WkAxsZT3D3 , WkAxsZT3D4 , WkAxsZT3D5 , WkAxsZT3D6 , WkAxsZT3D7 , WkAxsZT3D8 , & - WkAxsZT3D9 , WkAxsZT4D1 , WkAxsZT4D2 , WkAxsZT4D3 , WkAxsZT4D4 , WkAxsZT4D5 , WkAxsZT4D6 , WkAxsZT4D7 , & - WkAxsZT4D8 , WkAxsZT4D9 , WkAxsZT5D1 , WkAxsZT5D2 , WkAxsZT5D3 , WkAxsZT5D4 , WkAxsZT5D5 , WkAxsZT5D6 , & - WkAxsZT5D7 , WkAxsZT5D8 , WkAxsZT5D9 , WkAxsZT6D1 , WkAxsZT6D2 , WkAxsZT6D3 , WkAxsZT6D4 , WkAxsZT6D5 , & - WkAxsZT6D6 , WkAxsZT6D7 , WkAxsZT6D8 , WkAxsZT6D9 , WkAxsZT7D1 , WkAxsZT7D2 , WkAxsZT7D3 , WkAxsZT7D4 , & - WkAxsZT7D5 , WkAxsZT7D6 , WkAxsZT7D7 , WkAxsZT7D8 , WkAxsZT7D9 , WkAxsZT8D1 , WkAxsZT8D2 , WkAxsZT8D3 , & - WkAxsZT8D4 , WkAxsZT8D5 , WkAxsZT8D6 , WkAxsZT8D7 , WkAxsZT8D8 , WkAxsZT8D9 , WkAxsZT9D1 , WkAxsZT9D2 , & - WkAxsZT9D3 , WkAxsZT9D4 , WkAxsZT9D5 , WkAxsZT9D6 , WkAxsZT9D7 , WkAxsZT9D8 , WkAxsZT9D9 , WkDfVrT1N01D1 , & - WkDfVrT1N01D2 , WkDfVrT1N01D3 , WkDfVrT1N01D4 , WkDfVrT1N01D5 , WkDfVrT1N01D6 , WkDfVrT1N01D7 , WkDfVrT1N01D8 , WkDfVrT1N01D9 , & - WkDfVrT1N02D1 , WkDfVrT1N02D2 , WkDfVrT1N02D3 , WkDfVrT1N02D4 , WkDfVrT1N02D5 , WkDfVrT1N02D6 , WkDfVrT1N02D7 , WkDfVrT1N02D8 , & - WkDfVrT1N02D9 , WkDfVrT1N03D1 , WkDfVrT1N03D2 , WkDfVrT1N03D3 , WkDfVrT1N03D4 , WkDfVrT1N03D5 , WkDfVrT1N03D6 , WkDfVrT1N03D7 , & - WkDfVrT1N03D8 , WkDfVrT1N03D9 , WkDfVrT1N04D1 , WkDfVrT1N04D2 , WkDfVrT1N04D3 , WkDfVrT1N04D4 , WkDfVrT1N04D5 , WkDfVrT1N04D6 , & - WkDfVrT1N04D7 , WkDfVrT1N04D8 , WkDfVrT1N04D9 , WkDfVrT1N05D1 , WkDfVrT1N05D2 , WkDfVrT1N05D3 , WkDfVrT1N05D4 , WkDfVrT1N05D5 , & - WkDfVrT1N05D6 , WkDfVrT1N05D7 , WkDfVrT1N05D8 , WkDfVrT1N05D9 , WkDfVrT1N06D1 , WkDfVrT1N06D2 , WkDfVrT1N06D3 , WkDfVrT1N06D4 , & - WkDfVrT1N06D5 , WkDfVrT1N06D6 , WkDfVrT1N06D7 , WkDfVrT1N06D8 , WkDfVrT1N06D9 , WkDfVrT1N07D1 , WkDfVrT1N07D2 , WkDfVrT1N07D3 , & - WkDfVrT1N07D4 , WkDfVrT1N07D5 , WkDfVrT1N07D6 , WkDfVrT1N07D7 , WkDfVrT1N07D8 , WkDfVrT1N07D9 , WkDfVrT1N08D1 , WkDfVrT1N08D2 , & - WkDfVrT1N08D3 , WkDfVrT1N08D4 , WkDfVrT1N08D5 , WkDfVrT1N08D6 , WkDfVrT1N08D7 , WkDfVrT1N08D8 , WkDfVrT1N08D9 , WkDfVrT1N09D1 , & - WkDfVrT1N09D2 , WkDfVrT1N09D3 , WkDfVrT1N09D4 , WkDfVrT1N09D5 , WkDfVrT1N09D6 , WkDfVrT1N09D7 , WkDfVrT1N09D8 , WkDfVrT1N09D9 , & - WkDfVrT1N10D1 , WkDfVrT1N10D2 , WkDfVrT1N10D3 , WkDfVrT1N10D4 , WkDfVrT1N10D5 , WkDfVrT1N10D6 , WkDfVrT1N10D7 , WkDfVrT1N10D8 , & - WkDfVrT1N10D9 , WkDfVrT1N11D1 , WkDfVrT1N11D2 , WkDfVrT1N11D3 , WkDfVrT1N11D4 , WkDfVrT1N11D5 , WkDfVrT1N11D6 , WkDfVrT1N11D7 , & - WkDfVrT1N11D8 , WkDfVrT1N11D9 , WkDfVrT1N12D1 , WkDfVrT1N12D2 , WkDfVrT1N12D3 , WkDfVrT1N12D4 , WkDfVrT1N12D5 , WkDfVrT1N12D6 , & - WkDfVrT1N12D7 , WkDfVrT1N12D8 , WkDfVrT1N12D9 , WkDfVrT1N13D1 , WkDfVrT1N13D2 , WkDfVrT1N13D3 , WkDfVrT1N13D4 , WkDfVrT1N13D5 , & - WkDfVrT1N13D6 , WkDfVrT1N13D7 , WkDfVrT1N13D8 , WkDfVrT1N13D9 , WkDfVrT1N14D1 , WkDfVrT1N14D2 , WkDfVrT1N14D3 , WkDfVrT1N14D4 , & - WkDfVrT1N14D5 , WkDfVrT1N14D6 , WkDfVrT1N14D7 , WkDfVrT1N14D8 , WkDfVrT1N14D9 , WkDfVrT1N15D1 , WkDfVrT1N15D2 , WkDfVrT1N15D3 , & - WkDfVrT1N15D4 , WkDfVrT1N15D5 , WkDfVrT1N15D6 , WkDfVrT1N15D7 , WkDfVrT1N15D8 , WkDfVrT1N15D9 , WkDfVrT1N16D1 , WkDfVrT1N16D2 , & - WkDfVrT1N16D3 , WkDfVrT1N16D4 , WkDfVrT1N16D5 , WkDfVrT1N16D6 , WkDfVrT1N16D7 , WkDfVrT1N16D8 , WkDfVrT1N16D9 , WkDfVrT1N17D1 , & - WkDfVrT1N17D2 , WkDfVrT1N17D3 , WkDfVrT1N17D4 , WkDfVrT1N17D5 , WkDfVrT1N17D6 , WkDfVrT1N17D7 , WkDfVrT1N17D8 , WkDfVrT1N17D9 , & - WkDfVrT1N18D1 , WkDfVrT1N18D2 , WkDfVrT1N18D3 , WkDfVrT1N18D4 , WkDfVrT1N18D5 , WkDfVrT1N18D6 , WkDfVrT1N18D7 , WkDfVrT1N18D8 , & - WkDfVrT1N18D9 , WkDfVrT1N19D1 , WkDfVrT1N19D2 , WkDfVrT1N19D3 , WkDfVrT1N19D4 , WkDfVrT1N19D5 , WkDfVrT1N19D6 , WkDfVrT1N19D7 , & - WkDfVrT1N19D8 , WkDfVrT1N19D9 , WkDfVrT1N20D1 , WkDfVrT1N20D2 , WkDfVrT1N20D3 , WkDfVrT1N20D4 , WkDfVrT1N20D5 , WkDfVrT1N20D6 , & - WkDfVrT1N20D7 , WkDfVrT1N20D8 , WkDfVrT1N20D9 , WkDfVrT2N01D1 , WkDfVrT2N01D2 , WkDfVrT2N01D3 , WkDfVrT2N01D4 , WkDfVrT2N01D5 , & - WkDfVrT2N01D6 , WkDfVrT2N01D7 , WkDfVrT2N01D8 , WkDfVrT2N01D9 , WkDfVrT2N02D1 , WkDfVrT2N02D2 , WkDfVrT2N02D3 , WkDfVrT2N02D4 , & - WkDfVrT2N02D5 , WkDfVrT2N02D6 , WkDfVrT2N02D7 , WkDfVrT2N02D8 , WkDfVrT2N02D9 , WkDfVrT2N03D1 , WkDfVrT2N03D2 , WkDfVrT2N03D3 , & - WkDfVrT2N03D4 , WkDfVrT2N03D5 , WkDfVrT2N03D6 , WkDfVrT2N03D7 , WkDfVrT2N03D8 , WkDfVrT2N03D9 , WkDfVrT2N04D1 , WkDfVrT2N04D2 , & - WkDfVrT2N04D3 , WkDfVrT2N04D4 , WkDfVrT2N04D5 , WkDfVrT2N04D6 , WkDfVrT2N04D7 , WkDfVrT2N04D8 , WkDfVrT2N04D9 , WkDfVrT2N05D1 , & - WkDfVrT2N05D2 , WkDfVrT2N05D3 , WkDfVrT2N05D4 , WkDfVrT2N05D5 , WkDfVrT2N05D6 , WkDfVrT2N05D7 , WkDfVrT2N05D8 , WkDfVrT2N05D9 , & - WkDfVrT2N06D1 , WkDfVrT2N06D2 , WkDfVrT2N06D3 , WkDfVrT2N06D4 , WkDfVrT2N06D5 , WkDfVrT2N06D6 , WkDfVrT2N06D7 , WkDfVrT2N06D8 , & - WkDfVrT2N06D9 , WkDfVrT2N07D1 , WkDfVrT2N07D2 , WkDfVrT2N07D3 , WkDfVrT2N07D4 , WkDfVrT2N07D5 , WkDfVrT2N07D6 , WkDfVrT2N07D7 , & - WkDfVrT2N07D8 , WkDfVrT2N07D9 , WkDfVrT2N08D1 , WkDfVrT2N08D2 , WkDfVrT2N08D3 , WkDfVrT2N08D4 , WkDfVrT2N08D5 , WkDfVrT2N08D6 , & - WkDfVrT2N08D7 , WkDfVrT2N08D8 , WkDfVrT2N08D9 , WkDfVrT2N09D1 , WkDfVrT2N09D2 , WkDfVrT2N09D3 , WkDfVrT2N09D4 , WkDfVrT2N09D5 , & - WkDfVrT2N09D6 , WkDfVrT2N09D7 , WkDfVrT2N09D8 , WkDfVrT2N09D9 , WkDfVrT2N10D1 , WkDfVrT2N10D2 , WkDfVrT2N10D3 , WkDfVrT2N10D4 , & - WkDfVrT2N10D5 , WkDfVrT2N10D6 , WkDfVrT2N10D7 , WkDfVrT2N10D8 , WkDfVrT2N10D9 , WkDfVrT2N11D1 , WkDfVrT2N11D2 , WkDfVrT2N11D3 , & - WkDfVrT2N11D4 , WkDfVrT2N11D5 , WkDfVrT2N11D6 , WkDfVrT2N11D7 , WkDfVrT2N11D8 , WkDfVrT2N11D9 , WkDfVrT2N12D1 , WkDfVrT2N12D2 , & - WkDfVrT2N12D3 , WkDfVrT2N12D4 , WkDfVrT2N12D5 , WkDfVrT2N12D6 , WkDfVrT2N12D7 , WkDfVrT2N12D8 , WkDfVrT2N12D9 , WkDfVrT2N13D1 , & - WkDfVrT2N13D2 , WkDfVrT2N13D3 , WkDfVrT2N13D4 , WkDfVrT2N13D5 , WkDfVrT2N13D6 , WkDfVrT2N13D7 , WkDfVrT2N13D8 , WkDfVrT2N13D9 , & - WkDfVrT2N14D1 , WkDfVrT2N14D2 , WkDfVrT2N14D3 , WkDfVrT2N14D4 , WkDfVrT2N14D5 , WkDfVrT2N14D6 , WkDfVrT2N14D7 , WkDfVrT2N14D8 , & - WkDfVrT2N14D9 , WkDfVrT2N15D1 , WkDfVrT2N15D2 , WkDfVrT2N15D3 , WkDfVrT2N15D4 , WkDfVrT2N15D5 , WkDfVrT2N15D6 , WkDfVrT2N15D7 , & - WkDfVrT2N15D8 , WkDfVrT2N15D9 , WkDfVrT2N16D1 , WkDfVrT2N16D2 , WkDfVrT2N16D3 , WkDfVrT2N16D4 , WkDfVrT2N16D5 , WkDfVrT2N16D6 , & - WkDfVrT2N16D7 , WkDfVrT2N16D8 , WkDfVrT2N16D9 , WkDfVrT2N17D1 , WkDfVrT2N17D2 , WkDfVrT2N17D3 , WkDfVrT2N17D4 , WkDfVrT2N17D5 , & - WkDfVrT2N17D6 , WkDfVrT2N17D7 , WkDfVrT2N17D8 , WkDfVrT2N17D9 , WkDfVrT2N18D1 , WkDfVrT2N18D2 , WkDfVrT2N18D3 , WkDfVrT2N18D4 , & - WkDfVrT2N18D5 , WkDfVrT2N18D6 , WkDfVrT2N18D7 , WkDfVrT2N18D8 , WkDfVrT2N18D9 , WkDfVrT2N19D1 , WkDfVrT2N19D2 , WkDfVrT2N19D3 , & - WkDfVrT2N19D4 , WkDfVrT2N19D5 , WkDfVrT2N19D6 , WkDfVrT2N19D7 , WkDfVrT2N19D8 , WkDfVrT2N19D9 , WkDfVrT2N20D1 , WkDfVrT2N20D2 , & - WkDfVrT2N20D3 , WkDfVrT2N20D4 , WkDfVrT2N20D5 , WkDfVrT2N20D6 , WkDfVrT2N20D7 , WkDfVrT2N20D8 , WkDfVrT2N20D9 , WkDfVrT3N01D1 , & - WkDfVrT3N01D2 , WkDfVrT3N01D3 , WkDfVrT3N01D4 , WkDfVrT3N01D5 , WkDfVrT3N01D6 , WkDfVrT3N01D7 , WkDfVrT3N01D8 , WkDfVrT3N01D9 , & - WkDfVrT3N02D1 , WkDfVrT3N02D2 , WkDfVrT3N02D3 , WkDfVrT3N02D4 , WkDfVrT3N02D5 , WkDfVrT3N02D6 , WkDfVrT3N02D7 , WkDfVrT3N02D8 , & - WkDfVrT3N02D9 , WkDfVrT3N03D1 , WkDfVrT3N03D2 , WkDfVrT3N03D3 , WkDfVrT3N03D4 , WkDfVrT3N03D5 , WkDfVrT3N03D6 , WkDfVrT3N03D7 , & - WkDfVrT3N03D8 , WkDfVrT3N03D9 , WkDfVrT3N04D1 , WkDfVrT3N04D2 , WkDfVrT3N04D3 , WkDfVrT3N04D4 , WkDfVrT3N04D5 , WkDfVrT3N04D6 , & - WkDfVrT3N04D7 , WkDfVrT3N04D8 , WkDfVrT3N04D9 , WkDfVrT3N05D1 , WkDfVrT3N05D2 , WkDfVrT3N05D3 , WkDfVrT3N05D4 , WkDfVrT3N05D5 , & - WkDfVrT3N05D6 , WkDfVrT3N05D7 , WkDfVrT3N05D8 , WkDfVrT3N05D9 , WkDfVrT3N06D1 , WkDfVrT3N06D2 , WkDfVrT3N06D3 , WkDfVrT3N06D4 , & - WkDfVrT3N06D5 , WkDfVrT3N06D6 , WkDfVrT3N06D7 , WkDfVrT3N06D8 , WkDfVrT3N06D9 , WkDfVrT3N07D1 , WkDfVrT3N07D2 , WkDfVrT3N07D3 , & - WkDfVrT3N07D4 , WkDfVrT3N07D5 , WkDfVrT3N07D6 , WkDfVrT3N07D7 , WkDfVrT3N07D8 , WkDfVrT3N07D9 , WkDfVrT3N08D1 , WkDfVrT3N08D2 , & - WkDfVrT3N08D3 , WkDfVrT3N08D4 , WkDfVrT3N08D5 , WkDfVrT3N08D6 , WkDfVrT3N08D7 , WkDfVrT3N08D8 , WkDfVrT3N08D9 , WkDfVrT3N09D1 , & - WkDfVrT3N09D2 , WkDfVrT3N09D3 , WkDfVrT3N09D4 , WkDfVrT3N09D5 , WkDfVrT3N09D6 , WkDfVrT3N09D7 , WkDfVrT3N09D8 , WkDfVrT3N09D9 , & - WkDfVrT3N10D1 , WkDfVrT3N10D2 , WkDfVrT3N10D3 , WkDfVrT3N10D4 , WkDfVrT3N10D5 , WkDfVrT3N10D6 , WkDfVrT3N10D7 , WkDfVrT3N10D8 , & - WkDfVrT3N10D9 , WkDfVrT3N11D1 , WkDfVrT3N11D2 , WkDfVrT3N11D3 , WkDfVrT3N11D4 , WkDfVrT3N11D5 , WkDfVrT3N11D6 , WkDfVrT3N11D7 , & - WkDfVrT3N11D8 , WkDfVrT3N11D9 , WkDfVrT3N12D1 , WkDfVrT3N12D2 , WkDfVrT3N12D3 , WkDfVrT3N12D4 , WkDfVrT3N12D5 , WkDfVrT3N12D6 , & - WkDfVrT3N12D7 , WkDfVrT3N12D8 , WkDfVrT3N12D9 , WkDfVrT3N13D1 , WkDfVrT3N13D2 , WkDfVrT3N13D3 , WkDfVrT3N13D4 , WkDfVrT3N13D5 , & - WkDfVrT3N13D6 , WkDfVrT3N13D7 , WkDfVrT3N13D8 , WkDfVrT3N13D9 , WkDfVrT3N14D1 , WkDfVrT3N14D2 , WkDfVrT3N14D3 , WkDfVrT3N14D4 , & - WkDfVrT3N14D5 , WkDfVrT3N14D6 , WkDfVrT3N14D7 , WkDfVrT3N14D8 , WkDfVrT3N14D9 , WkDfVrT3N15D1 , WkDfVrT3N15D2 , WkDfVrT3N15D3 , & - WkDfVrT3N15D4 , WkDfVrT3N15D5 , WkDfVrT3N15D6 , WkDfVrT3N15D7 , WkDfVrT3N15D8 , WkDfVrT3N15D9 , WkDfVrT3N16D1 , WkDfVrT3N16D2 , & - WkDfVrT3N16D3 , WkDfVrT3N16D4 , WkDfVrT3N16D5 , WkDfVrT3N16D6 , WkDfVrT3N16D7 , WkDfVrT3N16D8 , WkDfVrT3N16D9 , WkDfVrT3N17D1 , & - WkDfVrT3N17D2 , WkDfVrT3N17D3 , WkDfVrT3N17D4 , WkDfVrT3N17D5 , WkDfVrT3N17D6 , WkDfVrT3N17D7 , WkDfVrT3N17D8 , WkDfVrT3N17D9 /) - ParamIndxAry(6121:8160) = (/ & - WkDfVrT3N18D1 , WkDfVrT3N18D2 , WkDfVrT3N18D3 , WkDfVrT3N18D4 , WkDfVrT3N18D5 , WkDfVrT3N18D6 , WkDfVrT3N18D7 , WkDfVrT3N18D8 , & - WkDfVrT3N18D9 , WkDfVrT3N19D1 , WkDfVrT3N19D2 , WkDfVrT3N19D3 , WkDfVrT3N19D4 , WkDfVrT3N19D5 , WkDfVrT3N19D6 , WkDfVrT3N19D7 , & - WkDfVrT3N19D8 , WkDfVrT3N19D9 , WkDfVrT3N20D1 , WkDfVrT3N20D2 , WkDfVrT3N20D3 , WkDfVrT3N20D4 , WkDfVrT3N20D5 , WkDfVrT3N20D6 , & - WkDfVrT3N20D7 , WkDfVrT3N20D8 , WkDfVrT3N20D9 , WkDfVrT4N01D1 , WkDfVrT4N01D2 , WkDfVrT4N01D3 , WkDfVrT4N01D4 , WkDfVrT4N01D5 , & - WkDfVrT4N01D6 , WkDfVrT4N01D7 , WkDfVrT4N01D8 , WkDfVrT4N01D9 , WkDfVrT4N02D1 , WkDfVrT4N02D2 , WkDfVrT4N02D3 , WkDfVrT4N02D4 , & - WkDfVrT4N02D5 , WkDfVrT4N02D6 , WkDfVrT4N02D7 , WkDfVrT4N02D8 , WkDfVrT4N02D9 , WkDfVrT4N03D1 , WkDfVrT4N03D2 , WkDfVrT4N03D3 , & - WkDfVrT4N03D4 , WkDfVrT4N03D5 , WkDfVrT4N03D6 , WkDfVrT4N03D7 , WkDfVrT4N03D8 , WkDfVrT4N03D9 , WkDfVrT4N04D1 , WkDfVrT4N04D2 , & - WkDfVrT4N04D3 , WkDfVrT4N04D4 , WkDfVrT4N04D5 , WkDfVrT4N04D6 , WkDfVrT4N04D7 , WkDfVrT4N04D8 , WkDfVrT4N04D9 , WkDfVrT4N05D1 , & - WkDfVrT4N05D2 , WkDfVrT4N05D3 , WkDfVrT4N05D4 , WkDfVrT4N05D5 , WkDfVrT4N05D6 , WkDfVrT4N05D7 , WkDfVrT4N05D8 , WkDfVrT4N05D9 , & - WkDfVrT4N06D1 , WkDfVrT4N06D2 , WkDfVrT4N06D3 , WkDfVrT4N06D4 , WkDfVrT4N06D5 , WkDfVrT4N06D6 , WkDfVrT4N06D7 , WkDfVrT4N06D8 , & - WkDfVrT4N06D9 , WkDfVrT4N07D1 , WkDfVrT4N07D2 , WkDfVrT4N07D3 , WkDfVrT4N07D4 , WkDfVrT4N07D5 , WkDfVrT4N07D6 , WkDfVrT4N07D7 , & - WkDfVrT4N07D8 , WkDfVrT4N07D9 , WkDfVrT4N08D1 , WkDfVrT4N08D2 , WkDfVrT4N08D3 , WkDfVrT4N08D4 , WkDfVrT4N08D5 , WkDfVrT4N08D6 , & - WkDfVrT4N08D7 , WkDfVrT4N08D8 , WkDfVrT4N08D9 , WkDfVrT4N09D1 , WkDfVrT4N09D2 , WkDfVrT4N09D3 , WkDfVrT4N09D4 , WkDfVrT4N09D5 , & - WkDfVrT4N09D6 , WkDfVrT4N09D7 , WkDfVrT4N09D8 , WkDfVrT4N09D9 , WkDfVrT4N10D1 , WkDfVrT4N10D2 , WkDfVrT4N10D3 , WkDfVrT4N10D4 , & - WkDfVrT4N10D5 , WkDfVrT4N10D6 , WkDfVrT4N10D7 , WkDfVrT4N10D8 , WkDfVrT4N10D9 , WkDfVrT4N11D1 , WkDfVrT4N11D2 , WkDfVrT4N11D3 , & - WkDfVrT4N11D4 , WkDfVrT4N11D5 , WkDfVrT4N11D6 , WkDfVrT4N11D7 , WkDfVrT4N11D8 , WkDfVrT4N11D9 , WkDfVrT4N12D1 , WkDfVrT4N12D2 , & - WkDfVrT4N12D3 , WkDfVrT4N12D4 , WkDfVrT4N12D5 , WkDfVrT4N12D6 , WkDfVrT4N12D7 , WkDfVrT4N12D8 , WkDfVrT4N12D9 , WkDfVrT4N13D1 , & - WkDfVrT4N13D2 , WkDfVrT4N13D3 , WkDfVrT4N13D4 , WkDfVrT4N13D5 , WkDfVrT4N13D6 , WkDfVrT4N13D7 , WkDfVrT4N13D8 , WkDfVrT4N13D9 , & - WkDfVrT4N14D1 , WkDfVrT4N14D2 , WkDfVrT4N14D3 , WkDfVrT4N14D4 , WkDfVrT4N14D5 , WkDfVrT4N14D6 , WkDfVrT4N14D7 , WkDfVrT4N14D8 , & - WkDfVrT4N14D9 , WkDfVrT4N15D1 , WkDfVrT4N15D2 , WkDfVrT4N15D3 , WkDfVrT4N15D4 , WkDfVrT4N15D5 , WkDfVrT4N15D6 , WkDfVrT4N15D7 , & - WkDfVrT4N15D8 , WkDfVrT4N15D9 , WkDfVrT4N16D1 , WkDfVrT4N16D2 , WkDfVrT4N16D3 , WkDfVrT4N16D4 , WkDfVrT4N16D5 , WkDfVrT4N16D6 , & - WkDfVrT4N16D7 , WkDfVrT4N16D8 , WkDfVrT4N16D9 , WkDfVrT4N17D1 , WkDfVrT4N17D2 , WkDfVrT4N17D3 , WkDfVrT4N17D4 , WkDfVrT4N17D5 , & - WkDfVrT4N17D6 , WkDfVrT4N17D7 , WkDfVrT4N17D8 , WkDfVrT4N17D9 , WkDfVrT4N18D1 , WkDfVrT4N18D2 , WkDfVrT4N18D3 , WkDfVrT4N18D4 , & - WkDfVrT4N18D5 , WkDfVrT4N18D6 , WkDfVrT4N18D7 , WkDfVrT4N18D8 , WkDfVrT4N18D9 , WkDfVrT4N19D1 , WkDfVrT4N19D2 , WkDfVrT4N19D3 , & - WkDfVrT4N19D4 , WkDfVrT4N19D5 , WkDfVrT4N19D6 , WkDfVrT4N19D7 , WkDfVrT4N19D8 , WkDfVrT4N19D9 , WkDfVrT4N20D1 , WkDfVrT4N20D2 , & - WkDfVrT4N20D3 , WkDfVrT4N20D4 , WkDfVrT4N20D5 , WkDfVrT4N20D6 , WkDfVrT4N20D7 , WkDfVrT4N20D8 , WkDfVrT4N20D9 , WkDfVrT5N01D1 , & - WkDfVrT5N01D2 , WkDfVrT5N01D3 , WkDfVrT5N01D4 , WkDfVrT5N01D5 , WkDfVrT5N01D6 , WkDfVrT5N01D7 , WkDfVrT5N01D8 , WkDfVrT5N01D9 , & - WkDfVrT5N02D1 , WkDfVrT5N02D2 , WkDfVrT5N02D3 , WkDfVrT5N02D4 , WkDfVrT5N02D5 , WkDfVrT5N02D6 , WkDfVrT5N02D7 , WkDfVrT5N02D8 , & - WkDfVrT5N02D9 , WkDfVrT5N03D1 , WkDfVrT5N03D2 , WkDfVrT5N03D3 , WkDfVrT5N03D4 , WkDfVrT5N03D5 , WkDfVrT5N03D6 , WkDfVrT5N03D7 , & - WkDfVrT5N03D8 , WkDfVrT5N03D9 , WkDfVrT5N04D1 , WkDfVrT5N04D2 , WkDfVrT5N04D3 , WkDfVrT5N04D4 , WkDfVrT5N04D5 , WkDfVrT5N04D6 , & - WkDfVrT5N04D7 , WkDfVrT5N04D8 , WkDfVrT5N04D9 , WkDfVrT5N05D1 , WkDfVrT5N05D2 , WkDfVrT5N05D3 , WkDfVrT5N05D4 , WkDfVrT5N05D5 , & - WkDfVrT5N05D6 , WkDfVrT5N05D7 , WkDfVrT5N05D8 , WkDfVrT5N05D9 , WkDfVrT5N06D1 , WkDfVrT5N06D2 , WkDfVrT5N06D3 , WkDfVrT5N06D4 , & - WkDfVrT5N06D5 , WkDfVrT5N06D6 , WkDfVrT5N06D7 , WkDfVrT5N06D8 , WkDfVrT5N06D9 , WkDfVrT5N07D1 , WkDfVrT5N07D2 , WkDfVrT5N07D3 , & - WkDfVrT5N07D4 , WkDfVrT5N07D5 , WkDfVrT5N07D6 , WkDfVrT5N07D7 , WkDfVrT5N07D8 , WkDfVrT5N07D9 , WkDfVrT5N08D1 , WkDfVrT5N08D2 , & - WkDfVrT5N08D3 , WkDfVrT5N08D4 , WkDfVrT5N08D5 , WkDfVrT5N08D6 , WkDfVrT5N08D7 , WkDfVrT5N08D8 , WkDfVrT5N08D9 , WkDfVrT5N09D1 , & - WkDfVrT5N09D2 , WkDfVrT5N09D3 , WkDfVrT5N09D4 , WkDfVrT5N09D5 , WkDfVrT5N09D6 , WkDfVrT5N09D7 , WkDfVrT5N09D8 , WkDfVrT5N09D9 , & - WkDfVrT5N10D1 , WkDfVrT5N10D2 , WkDfVrT5N10D3 , WkDfVrT5N10D4 , WkDfVrT5N10D5 , WkDfVrT5N10D6 , WkDfVrT5N10D7 , WkDfVrT5N10D8 , & - WkDfVrT5N10D9 , WkDfVrT5N11D1 , WkDfVrT5N11D2 , WkDfVrT5N11D3 , WkDfVrT5N11D4 , WkDfVrT5N11D5 , WkDfVrT5N11D6 , WkDfVrT5N11D7 , & - WkDfVrT5N11D8 , WkDfVrT5N11D9 , WkDfVrT5N12D1 , WkDfVrT5N12D2 , WkDfVrT5N12D3 , WkDfVrT5N12D4 , WkDfVrT5N12D5 , WkDfVrT5N12D6 , & - WkDfVrT5N12D7 , WkDfVrT5N12D8 , WkDfVrT5N12D9 , WkDfVrT5N13D1 , WkDfVrT5N13D2 , WkDfVrT5N13D3 , WkDfVrT5N13D4 , WkDfVrT5N13D5 , & - WkDfVrT5N13D6 , WkDfVrT5N13D7 , WkDfVrT5N13D8 , WkDfVrT5N13D9 , WkDfVrT5N14D1 , WkDfVrT5N14D2 , WkDfVrT5N14D3 , WkDfVrT5N14D4 , & - WkDfVrT5N14D5 , WkDfVrT5N14D6 , WkDfVrT5N14D7 , WkDfVrT5N14D8 , WkDfVrT5N14D9 , WkDfVrT5N15D1 , WkDfVrT5N15D2 , WkDfVrT5N15D3 , & - WkDfVrT5N15D4 , WkDfVrT5N15D5 , WkDfVrT5N15D6 , WkDfVrT5N15D7 , WkDfVrT5N15D8 , WkDfVrT5N15D9 , WkDfVrT5N16D1 , WkDfVrT5N16D2 , & - WkDfVrT5N16D3 , WkDfVrT5N16D4 , WkDfVrT5N16D5 , WkDfVrT5N16D6 , WkDfVrT5N16D7 , WkDfVrT5N16D8 , WkDfVrT5N16D9 , WkDfVrT5N17D1 , & - WkDfVrT5N17D2 , WkDfVrT5N17D3 , WkDfVrT5N17D4 , WkDfVrT5N17D5 , WkDfVrT5N17D6 , WkDfVrT5N17D7 , WkDfVrT5N17D8 , WkDfVrT5N17D9 , & - WkDfVrT5N18D1 , WkDfVrT5N18D2 , WkDfVrT5N18D3 , WkDfVrT5N18D4 , WkDfVrT5N18D5 , WkDfVrT5N18D6 , WkDfVrT5N18D7 , WkDfVrT5N18D8 , & - WkDfVrT5N18D9 , WkDfVrT5N19D1 , WkDfVrT5N19D2 , WkDfVrT5N19D3 , WkDfVrT5N19D4 , WkDfVrT5N19D5 , WkDfVrT5N19D6 , WkDfVrT5N19D7 , & - WkDfVrT5N19D8 , WkDfVrT5N19D9 , WkDfVrT5N20D1 , WkDfVrT5N20D2 , WkDfVrT5N20D3 , WkDfVrT5N20D4 , WkDfVrT5N20D5 , WkDfVrT5N20D6 , & - WkDfVrT5N20D7 , WkDfVrT5N20D8 , WkDfVrT5N20D9 , WkDfVrT6N01D1 , WkDfVrT6N01D2 , WkDfVrT6N01D3 , WkDfVrT6N01D4 , WkDfVrT6N01D5 , & - WkDfVrT6N01D6 , WkDfVrT6N01D7 , WkDfVrT6N01D8 , WkDfVrT6N01D9 , WkDfVrT6N02D1 , WkDfVrT6N02D2 , WkDfVrT6N02D3 , WkDfVrT6N02D4 , & - WkDfVrT6N02D5 , WkDfVrT6N02D6 , WkDfVrT6N02D7 , WkDfVrT6N02D8 , WkDfVrT6N02D9 , WkDfVrT6N03D1 , WkDfVrT6N03D2 , WkDfVrT6N03D3 , & - WkDfVrT6N03D4 , WkDfVrT6N03D5 , WkDfVrT6N03D6 , WkDfVrT6N03D7 , WkDfVrT6N03D8 , WkDfVrT6N03D9 , WkDfVrT6N04D1 , WkDfVrT6N04D2 , & - WkDfVrT6N04D3 , WkDfVrT6N04D4 , WkDfVrT6N04D5 , WkDfVrT6N04D6 , WkDfVrT6N04D7 , WkDfVrT6N04D8 , WkDfVrT6N04D9 , WkDfVrT6N05D1 , & - WkDfVrT6N05D2 , WkDfVrT6N05D3 , WkDfVrT6N05D4 , WkDfVrT6N05D5 , WkDfVrT6N05D6 , WkDfVrT6N05D7 , WkDfVrT6N05D8 , WkDfVrT6N05D9 , & - WkDfVrT6N06D1 , WkDfVrT6N06D2 , WkDfVrT6N06D3 , WkDfVrT6N06D4 , WkDfVrT6N06D5 , WkDfVrT6N06D6 , WkDfVrT6N06D7 , WkDfVrT6N06D8 , & - WkDfVrT6N06D9 , WkDfVrT6N07D1 , WkDfVrT6N07D2 , WkDfVrT6N07D3 , WkDfVrT6N07D4 , WkDfVrT6N07D5 , WkDfVrT6N07D6 , WkDfVrT6N07D7 , & - WkDfVrT6N07D8 , WkDfVrT6N07D9 , WkDfVrT6N08D1 , WkDfVrT6N08D2 , WkDfVrT6N08D3 , WkDfVrT6N08D4 , WkDfVrT6N08D5 , WkDfVrT6N08D6 , & - WkDfVrT6N08D7 , WkDfVrT6N08D8 , WkDfVrT6N08D9 , WkDfVrT6N09D1 , WkDfVrT6N09D2 , WkDfVrT6N09D3 , WkDfVrT6N09D4 , WkDfVrT6N09D5 , & - WkDfVrT6N09D6 , WkDfVrT6N09D7 , WkDfVrT6N09D8 , WkDfVrT6N09D9 , WkDfVrT6N10D1 , WkDfVrT6N10D2 , WkDfVrT6N10D3 , WkDfVrT6N10D4 , & - WkDfVrT6N10D5 , WkDfVrT6N10D6 , WkDfVrT6N10D7 , WkDfVrT6N10D8 , WkDfVrT6N10D9 , WkDfVrT6N11D1 , WkDfVrT6N11D2 , WkDfVrT6N11D3 , & - WkDfVrT6N11D4 , WkDfVrT6N11D5 , WkDfVrT6N11D6 , WkDfVrT6N11D7 , WkDfVrT6N11D8 , WkDfVrT6N11D9 , WkDfVrT6N12D1 , WkDfVrT6N12D2 , & - WkDfVrT6N12D3 , WkDfVrT6N12D4 , WkDfVrT6N12D5 , WkDfVrT6N12D6 , WkDfVrT6N12D7 , WkDfVrT6N12D8 , WkDfVrT6N12D9 , WkDfVrT6N13D1 , & - WkDfVrT6N13D2 , WkDfVrT6N13D3 , WkDfVrT6N13D4 , WkDfVrT6N13D5 , WkDfVrT6N13D6 , WkDfVrT6N13D7 , WkDfVrT6N13D8 , WkDfVrT6N13D9 , & - WkDfVrT6N14D1 , WkDfVrT6N14D2 , WkDfVrT6N14D3 , WkDfVrT6N14D4 , WkDfVrT6N14D5 , WkDfVrT6N14D6 , WkDfVrT6N14D7 , WkDfVrT6N14D8 , & - WkDfVrT6N14D9 , WkDfVrT6N15D1 , WkDfVrT6N15D2 , WkDfVrT6N15D3 , WkDfVrT6N15D4 , WkDfVrT6N15D5 , WkDfVrT6N15D6 , WkDfVrT6N15D7 , & - WkDfVrT6N15D8 , WkDfVrT6N15D9 , WkDfVrT6N16D1 , WkDfVrT6N16D2 , WkDfVrT6N16D3 , WkDfVrT6N16D4 , WkDfVrT6N16D5 , WkDfVrT6N16D6 , & - WkDfVrT6N16D7 , WkDfVrT6N16D8 , WkDfVrT6N16D9 , WkDfVrT6N17D1 , WkDfVrT6N17D2 , WkDfVrT6N17D3 , WkDfVrT6N17D4 , WkDfVrT6N17D5 , & - WkDfVrT6N17D6 , WkDfVrT6N17D7 , WkDfVrT6N17D8 , WkDfVrT6N17D9 , WkDfVrT6N18D1 , WkDfVrT6N18D2 , WkDfVrT6N18D3 , WkDfVrT6N18D4 , & - WkDfVrT6N18D5 , WkDfVrT6N18D6 , WkDfVrT6N18D7 , WkDfVrT6N18D8 , WkDfVrT6N18D9 , WkDfVrT6N19D1 , WkDfVrT6N19D2 , WkDfVrT6N19D3 , & - WkDfVrT6N19D4 , WkDfVrT6N19D5 , WkDfVrT6N19D6 , WkDfVrT6N19D7 , WkDfVrT6N19D8 , WkDfVrT6N19D9 , WkDfVrT6N20D1 , WkDfVrT6N20D2 , & - WkDfVrT6N20D3 , WkDfVrT6N20D4 , WkDfVrT6N20D5 , WkDfVrT6N20D6 , WkDfVrT6N20D7 , WkDfVrT6N20D8 , WkDfVrT6N20D9 , WkDfVrT7N01D1 , & - WkDfVrT7N01D2 , WkDfVrT7N01D3 , WkDfVrT7N01D4 , WkDfVrT7N01D5 , WkDfVrT7N01D6 , WkDfVrT7N01D7 , WkDfVrT7N01D8 , WkDfVrT7N01D9 , & - WkDfVrT7N02D1 , WkDfVrT7N02D2 , WkDfVrT7N02D3 , WkDfVrT7N02D4 , WkDfVrT7N02D5 , WkDfVrT7N02D6 , WkDfVrT7N02D7 , WkDfVrT7N02D8 , & - WkDfVrT7N02D9 , WkDfVrT7N03D1 , WkDfVrT7N03D2 , WkDfVrT7N03D3 , WkDfVrT7N03D4 , WkDfVrT7N03D5 , WkDfVrT7N03D6 , WkDfVrT7N03D7 , & - WkDfVrT7N03D8 , WkDfVrT7N03D9 , WkDfVrT7N04D1 , WkDfVrT7N04D2 , WkDfVrT7N04D3 , WkDfVrT7N04D4 , WkDfVrT7N04D5 , WkDfVrT7N04D6 , & - WkDfVrT7N04D7 , WkDfVrT7N04D8 , WkDfVrT7N04D9 , WkDfVrT7N05D1 , WkDfVrT7N05D2 , WkDfVrT7N05D3 , WkDfVrT7N05D4 , WkDfVrT7N05D5 , & - WkDfVrT7N05D6 , WkDfVrT7N05D7 , WkDfVrT7N05D8 , WkDfVrT7N05D9 , WkDfVrT7N06D1 , WkDfVrT7N06D2 , WkDfVrT7N06D3 , WkDfVrT7N06D4 , & - WkDfVrT7N06D5 , WkDfVrT7N06D6 , WkDfVrT7N06D7 , WkDfVrT7N06D8 , WkDfVrT7N06D9 , WkDfVrT7N07D1 , WkDfVrT7N07D2 , WkDfVrT7N07D3 , & - WkDfVrT7N07D4 , WkDfVrT7N07D5 , WkDfVrT7N07D6 , WkDfVrT7N07D7 , WkDfVrT7N07D8 , WkDfVrT7N07D9 , WkDfVrT7N08D1 , WkDfVrT7N08D2 , & - WkDfVrT7N08D3 , WkDfVrT7N08D4 , WkDfVrT7N08D5 , WkDfVrT7N08D6 , WkDfVrT7N08D7 , WkDfVrT7N08D8 , WkDfVrT7N08D9 , WkDfVrT7N09D1 , & - WkDfVrT7N09D2 , WkDfVrT7N09D3 , WkDfVrT7N09D4 , WkDfVrT7N09D5 , WkDfVrT7N09D6 , WkDfVrT7N09D7 , WkDfVrT7N09D8 , WkDfVrT7N09D9 , & - WkDfVrT7N10D1 , WkDfVrT7N10D2 , WkDfVrT7N10D3 , WkDfVrT7N10D4 , WkDfVrT7N10D5 , WkDfVrT7N10D6 , WkDfVrT7N10D7 , WkDfVrT7N10D8 , & - WkDfVrT7N10D9 , WkDfVrT7N11D1 , WkDfVrT7N11D2 , WkDfVrT7N11D3 , WkDfVrT7N11D4 , WkDfVrT7N11D5 , WkDfVrT7N11D6 , WkDfVrT7N11D7 , & - WkDfVrT7N11D8 , WkDfVrT7N11D9 , WkDfVrT7N12D1 , WkDfVrT7N12D2 , WkDfVrT7N12D3 , WkDfVrT7N12D4 , WkDfVrT7N12D5 , WkDfVrT7N12D6 , & - WkDfVrT7N12D7 , WkDfVrT7N12D8 , WkDfVrT7N12D9 , WkDfVrT7N13D1 , WkDfVrT7N13D2 , WkDfVrT7N13D3 , WkDfVrT7N13D4 , WkDfVrT7N13D5 , & - WkDfVrT7N13D6 , WkDfVrT7N13D7 , WkDfVrT7N13D8 , WkDfVrT7N13D9 , WkDfVrT7N14D1 , WkDfVrT7N14D2 , WkDfVrT7N14D3 , WkDfVrT7N14D4 , & - WkDfVrT7N14D5 , WkDfVrT7N14D6 , WkDfVrT7N14D7 , WkDfVrT7N14D8 , WkDfVrT7N14D9 , WkDfVrT7N15D1 , WkDfVrT7N15D2 , WkDfVrT7N15D3 , & - WkDfVrT7N15D4 , WkDfVrT7N15D5 , WkDfVrT7N15D6 , WkDfVrT7N15D7 , WkDfVrT7N15D8 , WkDfVrT7N15D9 , WkDfVrT7N16D1 , WkDfVrT7N16D2 , & - WkDfVrT7N16D3 , WkDfVrT7N16D4 , WkDfVrT7N16D5 , WkDfVrT7N16D6 , WkDfVrT7N16D7 , WkDfVrT7N16D8 , WkDfVrT7N16D9 , WkDfVrT7N17D1 , & - WkDfVrT7N17D2 , WkDfVrT7N17D3 , WkDfVrT7N17D4 , WkDfVrT7N17D5 , WkDfVrT7N17D6 , WkDfVrT7N17D7 , WkDfVrT7N17D8 , WkDfVrT7N17D9 , & - WkDfVrT7N18D1 , WkDfVrT7N18D2 , WkDfVrT7N18D3 , WkDfVrT7N18D4 , WkDfVrT7N18D5 , WkDfVrT7N18D6 , WkDfVrT7N18D7 , WkDfVrT7N18D8 , & - WkDfVrT7N18D9 , WkDfVrT7N19D1 , WkDfVrT7N19D2 , WkDfVrT7N19D3 , WkDfVrT7N19D4 , WkDfVrT7N19D5 , WkDfVrT7N19D6 , WkDfVrT7N19D7 , & - WkDfVrT7N19D8 , WkDfVrT7N19D9 , WkDfVrT7N20D1 , WkDfVrT7N20D2 , WkDfVrT7N20D3 , WkDfVrT7N20D4 , WkDfVrT7N20D5 , WkDfVrT7N20D6 , & - WkDfVrT7N20D7 , WkDfVrT7N20D8 , WkDfVrT7N20D9 , WkDfVrT8N01D1 , WkDfVrT8N01D2 , WkDfVrT8N01D3 , WkDfVrT8N01D4 , WkDfVrT8N01D5 , & - WkDfVrT8N01D6 , WkDfVrT8N01D7 , WkDfVrT8N01D8 , WkDfVrT8N01D9 , WkDfVrT8N02D1 , WkDfVrT8N02D2 , WkDfVrT8N02D3 , WkDfVrT8N02D4 , & - WkDfVrT8N02D5 , WkDfVrT8N02D6 , WkDfVrT8N02D7 , WkDfVrT8N02D8 , WkDfVrT8N02D9 , WkDfVrT8N03D1 , WkDfVrT8N03D2 , WkDfVrT8N03D3 , & - WkDfVrT8N03D4 , WkDfVrT8N03D5 , WkDfVrT8N03D6 , WkDfVrT8N03D7 , WkDfVrT8N03D8 , WkDfVrT8N03D9 , WkDfVrT8N04D1 , WkDfVrT8N04D2 , & - WkDfVrT8N04D3 , WkDfVrT8N04D4 , WkDfVrT8N04D5 , WkDfVrT8N04D6 , WkDfVrT8N04D7 , WkDfVrT8N04D8 , WkDfVrT8N04D9 , WkDfVrT8N05D1 , & - WkDfVrT8N05D2 , WkDfVrT8N05D3 , WkDfVrT8N05D4 , WkDfVrT8N05D5 , WkDfVrT8N05D6 , WkDfVrT8N05D7 , WkDfVrT8N05D8 , WkDfVrT8N05D9 , & - WkDfVrT8N06D1 , WkDfVrT8N06D2 , WkDfVrT8N06D3 , WkDfVrT8N06D4 , WkDfVrT8N06D5 , WkDfVrT8N06D6 , WkDfVrT8N06D7 , WkDfVrT8N06D8 , & - WkDfVrT8N06D9 , WkDfVrT8N07D1 , WkDfVrT8N07D2 , WkDfVrT8N07D3 , WkDfVrT8N07D4 , WkDfVrT8N07D5 , WkDfVrT8N07D6 , WkDfVrT8N07D7 , & - WkDfVrT8N07D8 , WkDfVrT8N07D9 , WkDfVrT8N08D1 , WkDfVrT8N08D2 , WkDfVrT8N08D3 , WkDfVrT8N08D4 , WkDfVrT8N08D5 , WkDfVrT8N08D6 , & - WkDfVrT8N08D7 , WkDfVrT8N08D8 , WkDfVrT8N08D9 , WkDfVrT8N09D1 , WkDfVrT8N09D2 , WkDfVrT8N09D3 , WkDfVrT8N09D4 , WkDfVrT8N09D5 , & - WkDfVrT8N09D6 , WkDfVrT8N09D7 , WkDfVrT8N09D8 , WkDfVrT8N09D9 , WkDfVrT8N10D1 , WkDfVrT8N10D2 , WkDfVrT8N10D3 , WkDfVrT8N10D4 , & - WkDfVrT8N10D5 , WkDfVrT8N10D6 , WkDfVrT8N10D7 , WkDfVrT8N10D8 , WkDfVrT8N10D9 , WkDfVrT8N11D1 , WkDfVrT8N11D2 , WkDfVrT8N11D3 , & - WkDfVrT8N11D4 , WkDfVrT8N11D5 , WkDfVrT8N11D6 , WkDfVrT8N11D7 , WkDfVrT8N11D8 , WkDfVrT8N11D9 , WkDfVrT8N12D1 , WkDfVrT8N12D2 , & - WkDfVrT8N12D3 , WkDfVrT8N12D4 , WkDfVrT8N12D5 , WkDfVrT8N12D6 , WkDfVrT8N12D7 , WkDfVrT8N12D8 , WkDfVrT8N12D9 , WkDfVrT8N13D1 , & - WkDfVrT8N13D2 , WkDfVrT8N13D3 , WkDfVrT8N13D4 , WkDfVrT8N13D5 , WkDfVrT8N13D6 , WkDfVrT8N13D7 , WkDfVrT8N13D8 , WkDfVrT8N13D9 , & - WkDfVrT8N14D1 , WkDfVrT8N14D2 , WkDfVrT8N14D3 , WkDfVrT8N14D4 , WkDfVrT8N14D5 , WkDfVrT8N14D6 , WkDfVrT8N14D7 , WkDfVrT8N14D8 , & - WkDfVrT8N14D9 , WkDfVrT8N15D1 , WkDfVrT8N15D2 , WkDfVrT8N15D3 , WkDfVrT8N15D4 , WkDfVrT8N15D5 , WkDfVrT8N15D6 , WkDfVrT8N15D7 , & - WkDfVrT8N15D8 , WkDfVrT8N15D9 , WkDfVrT8N16D1 , WkDfVrT8N16D2 , WkDfVrT8N16D3 , WkDfVrT8N16D4 , WkDfVrT8N16D5 , WkDfVrT8N16D6 , & - WkDfVrT8N16D7 , WkDfVrT8N16D8 , WkDfVrT8N16D9 , WkDfVrT8N17D1 , WkDfVrT8N17D2 , WkDfVrT8N17D3 , WkDfVrT8N17D4 , WkDfVrT8N17D5 , & - WkDfVrT8N17D6 , WkDfVrT8N17D7 , WkDfVrT8N17D8 , WkDfVrT8N17D9 , WkDfVrT8N18D1 , WkDfVrT8N18D2 , WkDfVrT8N18D3 , WkDfVrT8N18D4 , & - WkDfVrT8N18D5 , WkDfVrT8N18D6 , WkDfVrT8N18D7 , WkDfVrT8N18D8 , WkDfVrT8N18D9 , WkDfVrT8N19D1 , WkDfVrT8N19D2 , WkDfVrT8N19D3 , & - WkDfVrT8N19D4 , WkDfVrT8N19D5 , WkDfVrT8N19D6 , WkDfVrT8N19D7 , WkDfVrT8N19D8 , WkDfVrT8N19D9 , WkDfVrT8N20D1 , WkDfVrT8N20D2 , & - WkDfVrT8N20D3 , WkDfVrT8N20D4 , WkDfVrT8N20D5 , WkDfVrT8N20D6 , WkDfVrT8N20D7 , WkDfVrT8N20D8 , WkDfVrT8N20D9 , WkDfVrT9N01D1 , & - WkDfVrT9N01D2 , WkDfVrT9N01D3 , WkDfVrT9N01D4 , WkDfVrT9N01D5 , WkDfVrT9N01D6 , WkDfVrT9N01D7 , WkDfVrT9N01D8 , WkDfVrT9N01D9 , & - WkDfVrT9N02D1 , WkDfVrT9N02D2 , WkDfVrT9N02D3 , WkDfVrT9N02D4 , WkDfVrT9N02D5 , WkDfVrT9N02D6 , WkDfVrT9N02D7 , WkDfVrT9N02D8 , & - WkDfVrT9N02D9 , WkDfVrT9N03D1 , WkDfVrT9N03D2 , WkDfVrT9N03D3 , WkDfVrT9N03D4 , WkDfVrT9N03D5 , WkDfVrT9N03D6 , WkDfVrT9N03D7 , & - WkDfVrT9N03D8 , WkDfVrT9N03D9 , WkDfVrT9N04D1 , WkDfVrT9N04D2 , WkDfVrT9N04D3 , WkDfVrT9N04D4 , WkDfVrT9N04D5 , WkDfVrT9N04D6 , & - WkDfVrT9N04D7 , WkDfVrT9N04D8 , WkDfVrT9N04D9 , WkDfVrT9N05D1 , WkDfVrT9N05D2 , WkDfVrT9N05D3 , WkDfVrT9N05D4 , WkDfVrT9N05D5 , & - WkDfVrT9N05D6 , WkDfVrT9N05D7 , WkDfVrT9N05D8 , WkDfVrT9N05D9 , WkDfVrT9N06D1 , WkDfVrT9N06D2 , WkDfVrT9N06D3 , WkDfVrT9N06D4 , & - WkDfVrT9N06D5 , WkDfVrT9N06D6 , WkDfVrT9N06D7 , WkDfVrT9N06D8 , WkDfVrT9N06D9 , WkDfVrT9N07D1 , WkDfVrT9N07D2 , WkDfVrT9N07D3 , & - WkDfVrT9N07D4 , WkDfVrT9N07D5 , WkDfVrT9N07D6 , WkDfVrT9N07D7 , WkDfVrT9N07D8 , WkDfVrT9N07D9 , WkDfVrT9N08D1 , WkDfVrT9N08D2 , & - WkDfVrT9N08D3 , WkDfVrT9N08D4 , WkDfVrT9N08D5 , WkDfVrT9N08D6 , WkDfVrT9N08D7 , WkDfVrT9N08D8 , WkDfVrT9N08D9 , WkDfVrT9N09D1 , & - WkDfVrT9N09D2 , WkDfVrT9N09D3 , WkDfVrT9N09D4 , WkDfVrT9N09D5 , WkDfVrT9N09D6 , WkDfVrT9N09D7 , WkDfVrT9N09D8 , WkDfVrT9N09D9 , & - WkDfVrT9N10D1 , WkDfVrT9N10D2 , WkDfVrT9N10D3 , WkDfVrT9N10D4 , WkDfVrT9N10D5 , WkDfVrT9N10D6 , WkDfVrT9N10D7 , WkDfVrT9N10D8 , & - WkDfVrT9N10D9 , WkDfVrT9N11D1 , WkDfVrT9N11D2 , WkDfVrT9N11D3 , WkDfVrT9N11D4 , WkDfVrT9N11D5 , WkDfVrT9N11D6 , WkDfVrT9N11D7 , & - WkDfVrT9N11D8 , WkDfVrT9N11D9 , WkDfVrT9N12D1 , WkDfVrT9N12D2 , WkDfVrT9N12D3 , WkDfVrT9N12D4 , WkDfVrT9N12D5 , WkDfVrT9N12D6 , & - WkDfVrT9N12D7 , WkDfVrT9N12D8 , WkDfVrT9N12D9 , WkDfVrT9N13D1 , WkDfVrT9N13D2 , WkDfVrT9N13D3 , WkDfVrT9N13D4 , WkDfVrT9N13D5 , & - WkDfVrT9N13D6 , WkDfVrT9N13D7 , WkDfVrT9N13D8 , WkDfVrT9N13D9 , WkDfVrT9N14D1 , WkDfVrT9N14D2 , WkDfVrT9N14D3 , WkDfVrT9N14D4 , & - WkDfVrT9N14D5 , WkDfVrT9N14D6 , WkDfVrT9N14D7 , WkDfVrT9N14D8 , WkDfVrT9N14D9 , WkDfVrT9N15D1 , WkDfVrT9N15D2 , WkDfVrT9N15D3 , & - WkDfVrT9N15D4 , WkDfVrT9N15D5 , WkDfVrT9N15D6 , WkDfVrT9N15D7 , WkDfVrT9N15D8 , WkDfVrT9N15D9 , WkDfVrT9N16D1 , WkDfVrT9N16D2 , & - WkDfVrT9N16D3 , WkDfVrT9N16D4 , WkDfVrT9N16D5 , WkDfVrT9N16D6 , WkDfVrT9N16D7 , WkDfVrT9N16D8 , WkDfVrT9N16D9 , WkDfVrT9N17D1 , & - WkDfVrT9N17D2 , WkDfVrT9N17D3 , WkDfVrT9N17D4 , WkDfVrT9N17D5 , WkDfVrT9N17D6 , WkDfVrT9N17D7 , WkDfVrT9N17D8 , WkDfVrT9N17D9 , & - WkDfVrT9N18D1 , WkDfVrT9N18D2 , WkDfVrT9N18D3 , WkDfVrT9N18D4 , WkDfVrT9N18D5 , WkDfVrT9N18D6 , WkDfVrT9N18D7 , WkDfVrT9N18D8 , & - WkDfVrT9N18D9 , WkDfVrT9N19D1 , WkDfVrT9N19D2 , WkDfVrT9N19D3 , WkDfVrT9N19D4 , WkDfVrT9N19D5 , WkDfVrT9N19D6 , WkDfVrT9N19D7 , & - WkDfVrT9N19D8 , WkDfVrT9N19D9 , WkDfVrT9N20D1 , WkDfVrT9N20D2 , WkDfVrT9N20D3 , WkDfVrT9N20D4 , WkDfVrT9N20D5 , WkDfVrT9N20D6 , & - WkDfVrT9N20D7 , WkDfVrT9N20D8 , WkDfVrT9N20D9 , WkDfVxT1N01D1 , WkDfVxT1N01D2 , WkDfVxT1N01D3 , WkDfVxT1N01D4 , WkDfVxT1N01D5 , & - WkDfVxT1N01D6 , WkDfVxT1N01D7 , WkDfVxT1N01D8 , WkDfVxT1N01D9 , WkDfVxT1N02D1 , WkDfVxT1N02D2 , WkDfVxT1N02D3 , WkDfVxT1N02D4 , & - WkDfVxT1N02D5 , WkDfVxT1N02D6 , WkDfVxT1N02D7 , WkDfVxT1N02D8 , WkDfVxT1N02D9 , WkDfVxT1N03D1 , WkDfVxT1N03D2 , WkDfVxT1N03D3 , & - WkDfVxT1N03D4 , WkDfVxT1N03D5 , WkDfVxT1N03D6 , WkDfVxT1N03D7 , WkDfVxT1N03D8 , WkDfVxT1N03D9 , WkDfVxT1N04D1 , WkDfVxT1N04D2 , & - WkDfVxT1N04D3 , WkDfVxT1N04D4 , WkDfVxT1N04D5 , WkDfVxT1N04D6 , WkDfVxT1N04D7 , WkDfVxT1N04D8 , WkDfVxT1N04D9 , WkDfVxT1N05D1 , & - WkDfVxT1N05D2 , WkDfVxT1N05D3 , WkDfVxT1N05D4 , WkDfVxT1N05D5 , WkDfVxT1N05D6 , WkDfVxT1N05D7 , WkDfVxT1N05D8 , WkDfVxT1N05D9 , & - WkDfVxT1N06D1 , WkDfVxT1N06D2 , WkDfVxT1N06D3 , WkDfVxT1N06D4 , WkDfVxT1N06D5 , WkDfVxT1N06D6 , WkDfVxT1N06D7 , WkDfVxT1N06D8 , & - WkDfVxT1N06D9 , WkDfVxT1N07D1 , WkDfVxT1N07D2 , WkDfVxT1N07D3 , WkDfVxT1N07D4 , WkDfVxT1N07D5 , WkDfVxT1N07D6 , WkDfVxT1N07D7 , & - WkDfVxT1N07D8 , WkDfVxT1N07D9 , WkDfVxT1N08D1 , WkDfVxT1N08D2 , WkDfVxT1N08D3 , WkDfVxT1N08D4 , WkDfVxT1N08D5 , WkDfVxT1N08D6 , & - WkDfVxT1N08D7 , WkDfVxT1N08D8 , WkDfVxT1N08D9 , WkDfVxT1N09D1 , WkDfVxT1N09D2 , WkDfVxT1N09D3 , WkDfVxT1N09D4 , WkDfVxT1N09D5 , & - WkDfVxT1N09D6 , WkDfVxT1N09D7 , WkDfVxT1N09D8 , WkDfVxT1N09D9 , WkDfVxT1N10D1 , WkDfVxT1N10D2 , WkDfVxT1N10D3 , WkDfVxT1N10D4 , & - WkDfVxT1N10D5 , WkDfVxT1N10D6 , WkDfVxT1N10D7 , WkDfVxT1N10D8 , WkDfVxT1N10D9 , WkDfVxT1N11D1 , WkDfVxT1N11D2 , WkDfVxT1N11D3 , & - WkDfVxT1N11D4 , WkDfVxT1N11D5 , WkDfVxT1N11D6 , WkDfVxT1N11D7 , WkDfVxT1N11D8 , WkDfVxT1N11D9 , WkDfVxT1N12D1 , WkDfVxT1N12D2 , & - WkDfVxT1N12D3 , WkDfVxT1N12D4 , WkDfVxT1N12D5 , WkDfVxT1N12D6 , WkDfVxT1N12D7 , WkDfVxT1N12D8 , WkDfVxT1N12D9 , WkDfVxT1N13D1 , & - WkDfVxT1N13D2 , WkDfVxT1N13D3 , WkDfVxT1N13D4 , WkDfVxT1N13D5 , WkDfVxT1N13D6 , WkDfVxT1N13D7 , WkDfVxT1N13D8 , WkDfVxT1N13D9 , & - WkDfVxT1N14D1 , WkDfVxT1N14D2 , WkDfVxT1N14D3 , WkDfVxT1N14D4 , WkDfVxT1N14D5 , WkDfVxT1N14D6 , WkDfVxT1N14D7 , WkDfVxT1N14D8 , & - WkDfVxT1N14D9 , WkDfVxT1N15D1 , WkDfVxT1N15D2 , WkDfVxT1N15D3 , WkDfVxT1N15D4 , WkDfVxT1N15D5 , WkDfVxT1N15D6 , WkDfVxT1N15D7 , & - WkDfVxT1N15D8 , WkDfVxT1N15D9 , WkDfVxT1N16D1 , WkDfVxT1N16D2 , WkDfVxT1N16D3 , WkDfVxT1N16D4 , WkDfVxT1N16D5 , WkDfVxT1N16D6 , & - WkDfVxT1N16D7 , WkDfVxT1N16D8 , WkDfVxT1N16D9 , WkDfVxT1N17D1 , WkDfVxT1N17D2 , WkDfVxT1N17D3 , WkDfVxT1N17D4 , WkDfVxT1N17D5 , & - WkDfVxT1N17D6 , WkDfVxT1N17D7 , WkDfVxT1N17D8 , WkDfVxT1N17D9 , WkDfVxT1N18D1 , WkDfVxT1N18D2 , WkDfVxT1N18D3 , WkDfVxT1N18D4 , & - WkDfVxT1N18D5 , WkDfVxT1N18D6 , WkDfVxT1N18D7 , WkDfVxT1N18D8 , WkDfVxT1N18D9 , WkDfVxT1N19D1 , WkDfVxT1N19D2 , WkDfVxT1N19D3 , & - WkDfVxT1N19D4 , WkDfVxT1N19D5 , WkDfVxT1N19D6 , WkDfVxT1N19D7 , WkDfVxT1N19D8 , WkDfVxT1N19D9 , WkDfVxT1N20D1 , WkDfVxT1N20D2 , & - WkDfVxT1N20D3 , WkDfVxT1N20D4 , WkDfVxT1N20D5 , WkDfVxT1N20D6 , WkDfVxT1N20D7 , WkDfVxT1N20D8 , WkDfVxT1N20D9 , WkDfVxT2N01D1 , & - WkDfVxT2N01D2 , WkDfVxT2N01D3 , WkDfVxT2N01D4 , WkDfVxT2N01D5 , WkDfVxT2N01D6 , WkDfVxT2N01D7 , WkDfVxT2N01D8 , WkDfVxT2N01D9 , & - WkDfVxT2N02D1 , WkDfVxT2N02D2 , WkDfVxT2N02D3 , WkDfVxT2N02D4 , WkDfVxT2N02D5 , WkDfVxT2N02D6 , WkDfVxT2N02D7 , WkDfVxT2N02D8 , & - WkDfVxT2N02D9 , WkDfVxT2N03D1 , WkDfVxT2N03D2 , WkDfVxT2N03D3 , WkDfVxT2N03D4 , WkDfVxT2N03D5 , WkDfVxT2N03D6 , WkDfVxT2N03D7 , & - WkDfVxT2N03D8 , WkDfVxT2N03D9 , WkDfVxT2N04D1 , WkDfVxT2N04D2 , WkDfVxT2N04D3 , WkDfVxT2N04D4 , WkDfVxT2N04D5 , WkDfVxT2N04D6 , & - WkDfVxT2N04D7 , WkDfVxT2N04D8 , WkDfVxT2N04D9 , WkDfVxT2N05D1 , WkDfVxT2N05D2 , WkDfVxT2N05D3 , WkDfVxT2N05D4 , WkDfVxT2N05D5 , & - WkDfVxT2N05D6 , WkDfVxT2N05D7 , WkDfVxT2N05D8 , WkDfVxT2N05D9 , WkDfVxT2N06D1 , WkDfVxT2N06D2 , WkDfVxT2N06D3 , WkDfVxT2N06D4 , & - WkDfVxT2N06D5 , WkDfVxT2N06D6 , WkDfVxT2N06D7 , WkDfVxT2N06D8 , WkDfVxT2N06D9 , WkDfVxT2N07D1 , WkDfVxT2N07D2 , WkDfVxT2N07D3 , & - WkDfVxT2N07D4 , WkDfVxT2N07D5 , WkDfVxT2N07D6 , WkDfVxT2N07D7 , WkDfVxT2N07D8 , WkDfVxT2N07D9 , WkDfVxT2N08D1 , WkDfVxT2N08D2 , & - WkDfVxT2N08D3 , WkDfVxT2N08D4 , WkDfVxT2N08D5 , WkDfVxT2N08D6 , WkDfVxT2N08D7 , WkDfVxT2N08D8 , WkDfVxT2N08D9 , WkDfVxT2N09D1 , & - WkDfVxT2N09D2 , WkDfVxT2N09D3 , WkDfVxT2N09D4 , WkDfVxT2N09D5 , WkDfVxT2N09D6 , WkDfVxT2N09D7 , WkDfVxT2N09D8 , WkDfVxT2N09D9 , & - WkDfVxT2N10D1 , WkDfVxT2N10D2 , WkDfVxT2N10D3 , WkDfVxT2N10D4 , WkDfVxT2N10D5 , WkDfVxT2N10D6 , WkDfVxT2N10D7 , WkDfVxT2N10D8 , & - WkDfVxT2N10D9 , WkDfVxT2N11D1 , WkDfVxT2N11D2 , WkDfVxT2N11D3 , WkDfVxT2N11D4 , WkDfVxT2N11D5 , WkDfVxT2N11D6 , WkDfVxT2N11D7 , & - WkDfVxT2N11D8 , WkDfVxT2N11D9 , WkDfVxT2N12D1 , WkDfVxT2N12D2 , WkDfVxT2N12D3 , WkDfVxT2N12D4 , WkDfVxT2N12D5 , WkDfVxT2N12D6 , & - WkDfVxT2N12D7 , WkDfVxT2N12D8 , WkDfVxT2N12D9 , WkDfVxT2N13D1 , WkDfVxT2N13D2 , WkDfVxT2N13D3 , WkDfVxT2N13D4 , WkDfVxT2N13D5 , & - WkDfVxT2N13D6 , WkDfVxT2N13D7 , WkDfVxT2N13D8 , WkDfVxT2N13D9 , WkDfVxT2N14D1 , WkDfVxT2N14D2 , WkDfVxT2N14D3 , WkDfVxT2N14D4 , & - WkDfVxT2N14D5 , WkDfVxT2N14D6 , WkDfVxT2N14D7 , WkDfVxT2N14D8 , WkDfVxT2N14D9 , WkDfVxT2N15D1 , WkDfVxT2N15D2 , WkDfVxT2N15D3 , & - WkDfVxT2N15D4 , WkDfVxT2N15D5 , WkDfVxT2N15D6 , WkDfVxT2N15D7 , WkDfVxT2N15D8 , WkDfVxT2N15D9 , WkDfVxT2N16D1 , WkDfVxT2N16D2 , & - WkDfVxT2N16D3 , WkDfVxT2N16D4 , WkDfVxT2N16D5 , WkDfVxT2N16D6 , WkDfVxT2N16D7 , WkDfVxT2N16D8 , WkDfVxT2N16D9 , WkDfVxT2N17D1 , & - WkDfVxT2N17D2 , WkDfVxT2N17D3 , WkDfVxT2N17D4 , WkDfVxT2N17D5 , WkDfVxT2N17D6 , WkDfVxT2N17D7 , WkDfVxT2N17D8 , WkDfVxT2N17D9 , & - WkDfVxT2N18D1 , WkDfVxT2N18D2 , WkDfVxT2N18D3 , WkDfVxT2N18D4 , WkDfVxT2N18D5 , WkDfVxT2N18D6 , WkDfVxT2N18D7 , WkDfVxT2N18D8 , & - WkDfVxT2N18D9 , WkDfVxT2N19D1 , WkDfVxT2N19D2 , WkDfVxT2N19D3 , WkDfVxT2N19D4 , WkDfVxT2N19D5 , WkDfVxT2N19D6 , WkDfVxT2N19D7 , & - WkDfVxT2N19D8 , WkDfVxT2N19D9 , WkDfVxT2N20D1 , WkDfVxT2N20D2 , WkDfVxT2N20D3 , WkDfVxT2N20D4 , WkDfVxT2N20D5 , WkDfVxT2N20D6 , & - WkDfVxT2N20D7 , WkDfVxT2N20D8 , WkDfVxT2N20D9 , WkDfVxT3N01D1 , WkDfVxT3N01D2 , WkDfVxT3N01D3 , WkDfVxT3N01D4 , WkDfVxT3N01D5 , & - WkDfVxT3N01D6 , WkDfVxT3N01D7 , WkDfVxT3N01D8 , WkDfVxT3N01D9 , WkDfVxT3N02D1 , WkDfVxT3N02D2 , WkDfVxT3N02D3 , WkDfVxT3N02D4 , & - WkDfVxT3N02D5 , WkDfVxT3N02D6 , WkDfVxT3N02D7 , WkDfVxT3N02D8 , WkDfVxT3N02D9 , WkDfVxT3N03D1 , WkDfVxT3N03D2 , WkDfVxT3N03D3 , & - WkDfVxT3N03D4 , WkDfVxT3N03D5 , WkDfVxT3N03D6 , WkDfVxT3N03D7 , WkDfVxT3N03D8 , WkDfVxT3N03D9 , WkDfVxT3N04D1 , WkDfVxT3N04D2 , & - WkDfVxT3N04D3 , WkDfVxT3N04D4 , WkDfVxT3N04D5 , WkDfVxT3N04D6 , WkDfVxT3N04D7 , WkDfVxT3N04D8 , WkDfVxT3N04D9 , WkDfVxT3N05D1 , & - WkDfVxT3N05D2 , WkDfVxT3N05D3 , WkDfVxT3N05D4 , WkDfVxT3N05D5 , WkDfVxT3N05D6 , WkDfVxT3N05D7 , WkDfVxT3N05D8 , WkDfVxT3N05D9 , & - WkDfVxT3N06D1 , WkDfVxT3N06D2 , WkDfVxT3N06D3 , WkDfVxT3N06D4 , WkDfVxT3N06D5 , WkDfVxT3N06D6 , WkDfVxT3N06D7 , WkDfVxT3N06D8 , & - WkDfVxT3N06D9 , WkDfVxT3N07D1 , WkDfVxT3N07D2 , WkDfVxT3N07D3 , WkDfVxT3N07D4 , WkDfVxT3N07D5 , WkDfVxT3N07D6 , WkDfVxT3N07D7 , & - WkDfVxT3N07D8 , WkDfVxT3N07D9 , WkDfVxT3N08D1 , WkDfVxT3N08D2 , WkDfVxT3N08D3 , WkDfVxT3N08D4 , WkDfVxT3N08D5 , WkDfVxT3N08D6 , & - WkDfVxT3N08D7 , WkDfVxT3N08D8 , WkDfVxT3N08D9 , WkDfVxT3N09D1 , WkDfVxT3N09D2 , WkDfVxT3N09D3 , WkDfVxT3N09D4 , WkDfVxT3N09D5 , & - WkDfVxT3N09D6 , WkDfVxT3N09D7 , WkDfVxT3N09D8 , WkDfVxT3N09D9 , WkDfVxT3N10D1 , WkDfVxT3N10D2 , WkDfVxT3N10D3 , WkDfVxT3N10D4 , & - WkDfVxT3N10D5 , WkDfVxT3N10D6 , WkDfVxT3N10D7 , WkDfVxT3N10D8 , WkDfVxT3N10D9 , WkDfVxT3N11D1 , WkDfVxT3N11D2 , WkDfVxT3N11D3 , & - WkDfVxT3N11D4 , WkDfVxT3N11D5 , WkDfVxT3N11D6 , WkDfVxT3N11D7 , WkDfVxT3N11D8 , WkDfVxT3N11D9 , WkDfVxT3N12D1 , WkDfVxT3N12D2 , & - WkDfVxT3N12D3 , WkDfVxT3N12D4 , WkDfVxT3N12D5 , WkDfVxT3N12D6 , WkDfVxT3N12D7 , WkDfVxT3N12D8 , WkDfVxT3N12D9 , WkDfVxT3N13D1 , & - WkDfVxT3N13D2 , WkDfVxT3N13D3 , WkDfVxT3N13D4 , WkDfVxT3N13D5 , WkDfVxT3N13D6 , WkDfVxT3N13D7 , WkDfVxT3N13D8 , WkDfVxT3N13D9 , & - WkDfVxT3N14D1 , WkDfVxT3N14D2 , WkDfVxT3N14D3 , WkDfVxT3N14D4 , WkDfVxT3N14D5 , WkDfVxT3N14D6 , WkDfVxT3N14D7 , WkDfVxT3N14D8 , & - WkDfVxT3N14D9 , WkDfVxT3N15D1 , WkDfVxT3N15D2 , WkDfVxT3N15D3 , WkDfVxT3N15D4 , WkDfVxT3N15D5 , WkDfVxT3N15D6 , WkDfVxT3N15D7 , & - WkDfVxT3N15D8 , WkDfVxT3N15D9 , WkDfVxT3N16D1 , WkDfVxT3N16D2 , WkDfVxT3N16D3 , WkDfVxT3N16D4 , WkDfVxT3N16D5 , WkDfVxT3N16D6 , & - WkDfVxT3N16D7 , WkDfVxT3N16D8 , WkDfVxT3N16D9 , WkDfVxT3N17D1 , WkDfVxT3N17D2 , WkDfVxT3N17D3 , WkDfVxT3N17D4 , WkDfVxT3N17D5 , & - WkDfVxT3N17D6 , WkDfVxT3N17D7 , WkDfVxT3N17D8 , WkDfVxT3N17D9 , WkDfVxT3N18D1 , WkDfVxT3N18D2 , WkDfVxT3N18D3 , WkDfVxT3N18D4 , & - WkDfVxT3N18D5 , WkDfVxT3N18D6 , WkDfVxT3N18D7 , WkDfVxT3N18D8 , WkDfVxT3N18D9 , WkDfVxT3N19D1 , WkDfVxT3N19D2 , WkDfVxT3N19D3 , & - WkDfVxT3N19D4 , WkDfVxT3N19D5 , WkDfVxT3N19D6 , WkDfVxT3N19D7 , WkDfVxT3N19D8 , WkDfVxT3N19D9 , WkDfVxT3N20D1 , WkDfVxT3N20D2 , & - WkDfVxT3N20D3 , WkDfVxT3N20D4 , WkDfVxT3N20D5 , WkDfVxT3N20D6 , WkDfVxT3N20D7 , WkDfVxT3N20D8 , WkDfVxT3N20D9 , WkDfVxT4N01D1 , & - WkDfVxT4N01D2 , WkDfVxT4N01D3 , WkDfVxT4N01D4 , WkDfVxT4N01D5 , WkDfVxT4N01D6 , WkDfVxT4N01D7 , WkDfVxT4N01D8 , WkDfVxT4N01D9 , & - WkDfVxT4N02D1 , WkDfVxT4N02D2 , WkDfVxT4N02D3 , WkDfVxT4N02D4 , WkDfVxT4N02D5 , WkDfVxT4N02D6 , WkDfVxT4N02D7 , WkDfVxT4N02D8 , & - WkDfVxT4N02D9 , WkDfVxT4N03D1 , WkDfVxT4N03D2 , WkDfVxT4N03D3 , WkDfVxT4N03D4 , WkDfVxT4N03D5 , WkDfVxT4N03D6 , WkDfVxT4N03D7 , & - WkDfVxT4N03D8 , WkDfVxT4N03D9 , WkDfVxT4N04D1 , WkDfVxT4N04D2 , WkDfVxT4N04D3 , WkDfVxT4N04D4 , WkDfVxT4N04D5 , WkDfVxT4N04D6 , & - WkDfVxT4N04D7 , WkDfVxT4N04D8 , WkDfVxT4N04D9 , WkDfVxT4N05D1 , WkDfVxT4N05D2 , WkDfVxT4N05D3 , WkDfVxT4N05D4 , WkDfVxT4N05D5 , & - WkDfVxT4N05D6 , WkDfVxT4N05D7 , WkDfVxT4N05D8 , WkDfVxT4N05D9 , WkDfVxT4N06D1 , WkDfVxT4N06D2 , WkDfVxT4N06D3 , WkDfVxT4N06D4 , & - WkDfVxT4N06D5 , WkDfVxT4N06D6 , WkDfVxT4N06D7 , WkDfVxT4N06D8 , WkDfVxT4N06D9 , WkDfVxT4N07D1 , WkDfVxT4N07D2 , WkDfVxT4N07D3 , & - WkDfVxT4N07D4 , WkDfVxT4N07D5 , WkDfVxT4N07D6 , WkDfVxT4N07D7 , WkDfVxT4N07D8 , WkDfVxT4N07D9 , WkDfVxT4N08D1 , WkDfVxT4N08D2 , & - WkDfVxT4N08D3 , WkDfVxT4N08D4 , WkDfVxT4N08D5 , WkDfVxT4N08D6 , WkDfVxT4N08D7 , WkDfVxT4N08D8 , WkDfVxT4N08D9 , WkDfVxT4N09D1 , & - WkDfVxT4N09D2 , WkDfVxT4N09D3 , WkDfVxT4N09D4 , WkDfVxT4N09D5 , WkDfVxT4N09D6 , WkDfVxT4N09D7 , WkDfVxT4N09D8 , WkDfVxT4N09D9 , & - WkDfVxT4N10D1 , WkDfVxT4N10D2 , WkDfVxT4N10D3 , WkDfVxT4N10D4 , WkDfVxT4N10D5 , WkDfVxT4N10D6 , WkDfVxT4N10D7 , WkDfVxT4N10D8 , & - WkDfVxT4N10D9 , WkDfVxT4N11D1 , WkDfVxT4N11D2 , WkDfVxT4N11D3 , WkDfVxT4N11D4 , WkDfVxT4N11D5 , WkDfVxT4N11D6 , WkDfVxT4N11D7 , & - WkDfVxT4N11D8 , WkDfVxT4N11D9 , WkDfVxT4N12D1 , WkDfVxT4N12D2 , WkDfVxT4N12D3 , WkDfVxT4N12D4 , WkDfVxT4N12D5 , WkDfVxT4N12D6 , & - WkDfVxT4N12D7 , WkDfVxT4N12D8 , WkDfVxT4N12D9 , WkDfVxT4N13D1 , WkDfVxT4N13D2 , WkDfVxT4N13D3 , WkDfVxT4N13D4 , WkDfVxT4N13D5 , & - WkDfVxT4N13D6 , WkDfVxT4N13D7 , WkDfVxT4N13D8 , WkDfVxT4N13D9 , WkDfVxT4N14D1 , WkDfVxT4N14D2 , WkDfVxT4N14D3 , WkDfVxT4N14D4 , & - WkDfVxT4N14D5 , WkDfVxT4N14D6 , WkDfVxT4N14D7 , WkDfVxT4N14D8 , WkDfVxT4N14D9 , WkDfVxT4N15D1 , WkDfVxT4N15D2 , WkDfVxT4N15D3 , & - WkDfVxT4N15D4 , WkDfVxT4N15D5 , WkDfVxT4N15D6 , WkDfVxT4N15D7 , WkDfVxT4N15D8 , WkDfVxT4N15D9 , WkDfVxT4N16D1 , WkDfVxT4N16D2 , & - WkDfVxT4N16D3 , WkDfVxT4N16D4 , WkDfVxT4N16D5 , WkDfVxT4N16D6 , WkDfVxT4N16D7 , WkDfVxT4N16D8 , WkDfVxT4N16D9 , WkDfVxT4N17D1 , & - WkDfVxT4N17D2 , WkDfVxT4N17D3 , WkDfVxT4N17D4 , WkDfVxT4N17D5 , WkDfVxT4N17D6 , WkDfVxT4N17D7 , WkDfVxT4N17D8 , WkDfVxT4N17D9 , & - WkDfVxT4N18D1 , WkDfVxT4N18D2 , WkDfVxT4N18D3 , WkDfVxT4N18D4 , WkDfVxT4N18D5 , WkDfVxT4N18D6 , WkDfVxT4N18D7 , WkDfVxT4N18D8 , & - WkDfVxT4N18D9 , WkDfVxT4N19D1 , WkDfVxT4N19D2 , WkDfVxT4N19D3 , WkDfVxT4N19D4 , WkDfVxT4N19D5 , WkDfVxT4N19D6 , WkDfVxT4N19D7 , & - WkDfVxT4N19D8 , WkDfVxT4N19D9 , WkDfVxT4N20D1 , WkDfVxT4N20D2 , WkDfVxT4N20D3 , WkDfVxT4N20D4 , WkDfVxT4N20D5 , WkDfVxT4N20D6 , & - WkDfVxT4N20D7 , WkDfVxT4N20D8 , WkDfVxT4N20D9 , WkDfVxT5N01D1 , WkDfVxT5N01D2 , WkDfVxT5N01D3 , WkDfVxT5N01D4 , WkDfVxT5N01D5 , & - WkDfVxT5N01D6 , WkDfVxT5N01D7 , WkDfVxT5N01D8 , WkDfVxT5N01D9 , WkDfVxT5N02D1 , WkDfVxT5N02D2 , WkDfVxT5N02D3 , WkDfVxT5N02D4 , & - WkDfVxT5N02D5 , WkDfVxT5N02D6 , WkDfVxT5N02D7 , WkDfVxT5N02D8 , WkDfVxT5N02D9 , WkDfVxT5N03D1 , WkDfVxT5N03D2 , WkDfVxT5N03D3 , & - WkDfVxT5N03D4 , WkDfVxT5N03D5 , WkDfVxT5N03D6 , WkDfVxT5N03D7 , WkDfVxT5N03D8 , WkDfVxT5N03D9 , WkDfVxT5N04D1 , WkDfVxT5N04D2 , & - WkDfVxT5N04D3 , WkDfVxT5N04D4 , WkDfVxT5N04D5 , WkDfVxT5N04D6 , WkDfVxT5N04D7 , WkDfVxT5N04D8 , WkDfVxT5N04D9 , WkDfVxT5N05D1 , & - WkDfVxT5N05D2 , WkDfVxT5N05D3 , WkDfVxT5N05D4 , WkDfVxT5N05D5 , WkDfVxT5N05D6 , WkDfVxT5N05D7 , WkDfVxT5N05D8 , WkDfVxT5N05D9 , & - WkDfVxT5N06D1 , WkDfVxT5N06D2 , WkDfVxT5N06D3 , WkDfVxT5N06D4 , WkDfVxT5N06D5 , WkDfVxT5N06D6 , WkDfVxT5N06D7 , WkDfVxT5N06D8 , & - WkDfVxT5N06D9 , WkDfVxT5N07D1 , WkDfVxT5N07D2 , WkDfVxT5N07D3 , WkDfVxT5N07D4 , WkDfVxT5N07D5 , WkDfVxT5N07D6 , WkDfVxT5N07D7 , & - WkDfVxT5N07D8 , WkDfVxT5N07D9 , WkDfVxT5N08D1 , WkDfVxT5N08D2 , WkDfVxT5N08D3 , WkDfVxT5N08D4 , WkDfVxT5N08D5 , WkDfVxT5N08D6 , & - WkDfVxT5N08D7 , WkDfVxT5N08D8 , WkDfVxT5N08D9 , WkDfVxT5N09D1 , WkDfVxT5N09D2 , WkDfVxT5N09D3 , WkDfVxT5N09D4 , WkDfVxT5N09D5 , & - WkDfVxT5N09D6 , WkDfVxT5N09D7 , WkDfVxT5N09D8 , WkDfVxT5N09D9 , WkDfVxT5N10D1 , WkDfVxT5N10D2 , WkDfVxT5N10D3 , WkDfVxT5N10D4 , & - WkDfVxT5N10D5 , WkDfVxT5N10D6 , WkDfVxT5N10D7 , WkDfVxT5N10D8 , WkDfVxT5N10D9 , WkDfVxT5N11D1 , WkDfVxT5N11D2 , WkDfVxT5N11D3 , & - WkDfVxT5N11D4 , WkDfVxT5N11D5 , WkDfVxT5N11D6 , WkDfVxT5N11D7 , WkDfVxT5N11D8 , WkDfVxT5N11D9 , WkDfVxT5N12D1 , WkDfVxT5N12D2 , & - WkDfVxT5N12D3 , WkDfVxT5N12D4 , WkDfVxT5N12D5 , WkDfVxT5N12D6 , WkDfVxT5N12D7 , WkDfVxT5N12D8 , WkDfVxT5N12D9 , WkDfVxT5N13D1 , & - WkDfVxT5N13D2 , WkDfVxT5N13D3 , WkDfVxT5N13D4 , WkDfVxT5N13D5 , WkDfVxT5N13D6 , WkDfVxT5N13D7 , WkDfVxT5N13D8 , WkDfVxT5N13D9 , & - WkDfVxT5N14D1 , WkDfVxT5N14D2 , WkDfVxT5N14D3 , WkDfVxT5N14D4 , WkDfVxT5N14D5 , WkDfVxT5N14D6 , WkDfVxT5N14D7 , WkDfVxT5N14D8 , & - WkDfVxT5N14D9 , WkDfVxT5N15D1 , WkDfVxT5N15D2 , WkDfVxT5N15D3 , WkDfVxT5N15D4 , WkDfVxT5N15D5 , WkDfVxT5N15D6 , WkDfVxT5N15D7 , & - WkDfVxT5N15D8 , WkDfVxT5N15D9 , WkDfVxT5N16D1 , WkDfVxT5N16D2 , WkDfVxT5N16D3 , WkDfVxT5N16D4 , WkDfVxT5N16D5 , WkDfVxT5N16D6 , & - WkDfVxT5N16D7 , WkDfVxT5N16D8 , WkDfVxT5N16D9 , WkDfVxT5N17D1 , WkDfVxT5N17D2 , WkDfVxT5N17D3 , WkDfVxT5N17D4 , WkDfVxT5N17D5 , & - WkDfVxT5N17D6 , WkDfVxT5N17D7 , WkDfVxT5N17D8 , WkDfVxT5N17D9 , WkDfVxT5N18D1 , WkDfVxT5N18D2 , WkDfVxT5N18D3 , WkDfVxT5N18D4 , & - WkDfVxT5N18D5 , WkDfVxT5N18D6 , WkDfVxT5N18D7 , WkDfVxT5N18D8 , WkDfVxT5N18D9 , WkDfVxT5N19D1 , WkDfVxT5N19D2 , WkDfVxT5N19D3 , & - WkDfVxT5N19D4 , WkDfVxT5N19D5 , WkDfVxT5N19D6 , WkDfVxT5N19D7 , WkDfVxT5N19D8 , WkDfVxT5N19D9 , WkDfVxT5N20D1 , WkDfVxT5N20D2 , & - WkDfVxT5N20D3 , WkDfVxT5N20D4 , WkDfVxT5N20D5 , WkDfVxT5N20D6 , WkDfVxT5N20D7 , WkDfVxT5N20D8 , WkDfVxT5N20D9 , WkDfVxT6N01D1 , & - WkDfVxT6N01D2 , WkDfVxT6N01D3 , WkDfVxT6N01D4 , WkDfVxT6N01D5 , WkDfVxT6N01D6 , WkDfVxT6N01D7 , WkDfVxT6N01D8 , WkDfVxT6N01D9 , & - WkDfVxT6N02D1 , WkDfVxT6N02D2 , WkDfVxT6N02D3 , WkDfVxT6N02D4 , WkDfVxT6N02D5 , WkDfVxT6N02D6 , WkDfVxT6N02D7 , WkDfVxT6N02D8 , & - WkDfVxT6N02D9 , WkDfVxT6N03D1 , WkDfVxT6N03D2 , WkDfVxT6N03D3 , WkDfVxT6N03D4 , WkDfVxT6N03D5 , WkDfVxT6N03D6 , WkDfVxT6N03D7 , & - WkDfVxT6N03D8 , WkDfVxT6N03D9 , WkDfVxT6N04D1 , WkDfVxT6N04D2 , WkDfVxT6N04D3 , WkDfVxT6N04D4 , WkDfVxT6N04D5 , WkDfVxT6N04D6 /) - ParamIndxAry(8161:9423) = (/ & - WkDfVxT6N04D7 , WkDfVxT6N04D8 , WkDfVxT6N04D9 , WkDfVxT6N05D1 , WkDfVxT6N05D2 , WkDfVxT6N05D3 , WkDfVxT6N05D4 , WkDfVxT6N05D5 , & - WkDfVxT6N05D6 , WkDfVxT6N05D7 , WkDfVxT6N05D8 , WkDfVxT6N05D9 , WkDfVxT6N06D1 , WkDfVxT6N06D2 , WkDfVxT6N06D3 , WkDfVxT6N06D4 , & - WkDfVxT6N06D5 , WkDfVxT6N06D6 , WkDfVxT6N06D7 , WkDfVxT6N06D8 , WkDfVxT6N06D9 , WkDfVxT6N07D1 , WkDfVxT6N07D2 , WkDfVxT6N07D3 , & - WkDfVxT6N07D4 , WkDfVxT6N07D5 , WkDfVxT6N07D6 , WkDfVxT6N07D7 , WkDfVxT6N07D8 , WkDfVxT6N07D9 , WkDfVxT6N08D1 , WkDfVxT6N08D2 , & - WkDfVxT6N08D3 , WkDfVxT6N08D4 , WkDfVxT6N08D5 , WkDfVxT6N08D6 , WkDfVxT6N08D7 , WkDfVxT6N08D8 , WkDfVxT6N08D9 , WkDfVxT6N09D1 , & - WkDfVxT6N09D2 , WkDfVxT6N09D3 , WkDfVxT6N09D4 , WkDfVxT6N09D5 , WkDfVxT6N09D6 , WkDfVxT6N09D7 , WkDfVxT6N09D8 , WkDfVxT6N09D9 , & - WkDfVxT6N10D1 , WkDfVxT6N10D2 , WkDfVxT6N10D3 , WkDfVxT6N10D4 , WkDfVxT6N10D5 , WkDfVxT6N10D6 , WkDfVxT6N10D7 , WkDfVxT6N10D8 , & - WkDfVxT6N10D9 , WkDfVxT6N11D1 , WkDfVxT6N11D2 , WkDfVxT6N11D3 , WkDfVxT6N11D4 , WkDfVxT6N11D5 , WkDfVxT6N11D6 , WkDfVxT6N11D7 , & - WkDfVxT6N11D8 , WkDfVxT6N11D9 , WkDfVxT6N12D1 , WkDfVxT6N12D2 , WkDfVxT6N12D3 , WkDfVxT6N12D4 , WkDfVxT6N12D5 , WkDfVxT6N12D6 , & - WkDfVxT6N12D7 , WkDfVxT6N12D8 , WkDfVxT6N12D9 , WkDfVxT6N13D1 , WkDfVxT6N13D2 , WkDfVxT6N13D3 , WkDfVxT6N13D4 , WkDfVxT6N13D5 , & - WkDfVxT6N13D6 , WkDfVxT6N13D7 , WkDfVxT6N13D8 , WkDfVxT6N13D9 , WkDfVxT6N14D1 , WkDfVxT6N14D2 , WkDfVxT6N14D3 , WkDfVxT6N14D4 , & - WkDfVxT6N14D5 , WkDfVxT6N14D6 , WkDfVxT6N14D7 , WkDfVxT6N14D8 , WkDfVxT6N14D9 , WkDfVxT6N15D1 , WkDfVxT6N15D2 , WkDfVxT6N15D3 , & - WkDfVxT6N15D4 , WkDfVxT6N15D5 , WkDfVxT6N15D6 , WkDfVxT6N15D7 , WkDfVxT6N15D8 , WkDfVxT6N15D9 , WkDfVxT6N16D1 , WkDfVxT6N16D2 , & - WkDfVxT6N16D3 , WkDfVxT6N16D4 , WkDfVxT6N16D5 , WkDfVxT6N16D6 , WkDfVxT6N16D7 , WkDfVxT6N16D8 , WkDfVxT6N16D9 , WkDfVxT6N17D1 , & - WkDfVxT6N17D2 , WkDfVxT6N17D3 , WkDfVxT6N17D4 , WkDfVxT6N17D5 , WkDfVxT6N17D6 , WkDfVxT6N17D7 , WkDfVxT6N17D8 , WkDfVxT6N17D9 , & - WkDfVxT6N18D1 , WkDfVxT6N18D2 , WkDfVxT6N18D3 , WkDfVxT6N18D4 , WkDfVxT6N18D5 , WkDfVxT6N18D6 , WkDfVxT6N18D7 , WkDfVxT6N18D8 , & - WkDfVxT6N18D9 , WkDfVxT6N19D1 , WkDfVxT6N19D2 , WkDfVxT6N19D3 , WkDfVxT6N19D4 , WkDfVxT6N19D5 , WkDfVxT6N19D6 , WkDfVxT6N19D7 , & - WkDfVxT6N19D8 , WkDfVxT6N19D9 , WkDfVxT6N20D1 , WkDfVxT6N20D2 , WkDfVxT6N20D3 , WkDfVxT6N20D4 , WkDfVxT6N20D5 , WkDfVxT6N20D6 , & - WkDfVxT6N20D7 , WkDfVxT6N20D8 , WkDfVxT6N20D9 , WkDfVxT7N01D1 , WkDfVxT7N01D2 , WkDfVxT7N01D3 , WkDfVxT7N01D4 , WkDfVxT7N01D5 , & - WkDfVxT7N01D6 , WkDfVxT7N01D7 , WkDfVxT7N01D8 , WkDfVxT7N01D9 , WkDfVxT7N02D1 , WkDfVxT7N02D2 , WkDfVxT7N02D3 , WkDfVxT7N02D4 , & - WkDfVxT7N02D5 , WkDfVxT7N02D6 , WkDfVxT7N02D7 , WkDfVxT7N02D8 , WkDfVxT7N02D9 , WkDfVxT7N03D1 , WkDfVxT7N03D2 , WkDfVxT7N03D3 , & - WkDfVxT7N03D4 , WkDfVxT7N03D5 , WkDfVxT7N03D6 , WkDfVxT7N03D7 , WkDfVxT7N03D8 , WkDfVxT7N03D9 , WkDfVxT7N04D1 , WkDfVxT7N04D2 , & - WkDfVxT7N04D3 , WkDfVxT7N04D4 , WkDfVxT7N04D5 , WkDfVxT7N04D6 , WkDfVxT7N04D7 , WkDfVxT7N04D8 , WkDfVxT7N04D9 , WkDfVxT7N05D1 , & - WkDfVxT7N05D2 , WkDfVxT7N05D3 , WkDfVxT7N05D4 , WkDfVxT7N05D5 , WkDfVxT7N05D6 , WkDfVxT7N05D7 , WkDfVxT7N05D8 , WkDfVxT7N05D9 , & - WkDfVxT7N06D1 , WkDfVxT7N06D2 , WkDfVxT7N06D3 , WkDfVxT7N06D4 , WkDfVxT7N06D5 , WkDfVxT7N06D6 , WkDfVxT7N06D7 , WkDfVxT7N06D8 , & - WkDfVxT7N06D9 , WkDfVxT7N07D1 , WkDfVxT7N07D2 , WkDfVxT7N07D3 , WkDfVxT7N07D4 , WkDfVxT7N07D5 , WkDfVxT7N07D6 , WkDfVxT7N07D7 , & - WkDfVxT7N07D8 , WkDfVxT7N07D9 , WkDfVxT7N08D1 , WkDfVxT7N08D2 , WkDfVxT7N08D3 , WkDfVxT7N08D4 , WkDfVxT7N08D5 , WkDfVxT7N08D6 , & - WkDfVxT7N08D7 , WkDfVxT7N08D8 , WkDfVxT7N08D9 , WkDfVxT7N09D1 , WkDfVxT7N09D2 , WkDfVxT7N09D3 , WkDfVxT7N09D4 , WkDfVxT7N09D5 , & - WkDfVxT7N09D6 , WkDfVxT7N09D7 , WkDfVxT7N09D8 , WkDfVxT7N09D9 , WkDfVxT7N10D1 , WkDfVxT7N10D2 , WkDfVxT7N10D3 , WkDfVxT7N10D4 , & - WkDfVxT7N10D5 , WkDfVxT7N10D6 , WkDfVxT7N10D7 , WkDfVxT7N10D8 , WkDfVxT7N10D9 , WkDfVxT7N11D1 , WkDfVxT7N11D2 , WkDfVxT7N11D3 , & - WkDfVxT7N11D4 , WkDfVxT7N11D5 , WkDfVxT7N11D6 , WkDfVxT7N11D7 , WkDfVxT7N11D8 , WkDfVxT7N11D9 , WkDfVxT7N12D1 , WkDfVxT7N12D2 , & - WkDfVxT7N12D3 , WkDfVxT7N12D4 , WkDfVxT7N12D5 , WkDfVxT7N12D6 , WkDfVxT7N12D7 , WkDfVxT7N12D8 , WkDfVxT7N12D9 , WkDfVxT7N13D1 , & - WkDfVxT7N13D2 , WkDfVxT7N13D3 , WkDfVxT7N13D4 , WkDfVxT7N13D5 , WkDfVxT7N13D6 , WkDfVxT7N13D7 , WkDfVxT7N13D8 , WkDfVxT7N13D9 , & - WkDfVxT7N14D1 , WkDfVxT7N14D2 , WkDfVxT7N14D3 , WkDfVxT7N14D4 , WkDfVxT7N14D5 , WkDfVxT7N14D6 , WkDfVxT7N14D7 , WkDfVxT7N14D8 , & - WkDfVxT7N14D9 , WkDfVxT7N15D1 , WkDfVxT7N15D2 , WkDfVxT7N15D3 , WkDfVxT7N15D4 , WkDfVxT7N15D5 , WkDfVxT7N15D6 , WkDfVxT7N15D7 , & - WkDfVxT7N15D8 , WkDfVxT7N15D9 , WkDfVxT7N16D1 , WkDfVxT7N16D2 , WkDfVxT7N16D3 , WkDfVxT7N16D4 , WkDfVxT7N16D5 , WkDfVxT7N16D6 , & - WkDfVxT7N16D7 , WkDfVxT7N16D8 , WkDfVxT7N16D9 , WkDfVxT7N17D1 , WkDfVxT7N17D2 , WkDfVxT7N17D3 , WkDfVxT7N17D4 , WkDfVxT7N17D5 , & - WkDfVxT7N17D6 , WkDfVxT7N17D7 , WkDfVxT7N17D8 , WkDfVxT7N17D9 , WkDfVxT7N18D1 , WkDfVxT7N18D2 , WkDfVxT7N18D3 , WkDfVxT7N18D4 , & - WkDfVxT7N18D5 , WkDfVxT7N18D6 , WkDfVxT7N18D7 , WkDfVxT7N18D8 , WkDfVxT7N18D9 , WkDfVxT7N19D1 , WkDfVxT7N19D2 , WkDfVxT7N19D3 , & - WkDfVxT7N19D4 , WkDfVxT7N19D5 , WkDfVxT7N19D6 , WkDfVxT7N19D7 , WkDfVxT7N19D8 , WkDfVxT7N19D9 , WkDfVxT7N20D1 , WkDfVxT7N20D2 , & - WkDfVxT7N20D3 , WkDfVxT7N20D4 , WkDfVxT7N20D5 , WkDfVxT7N20D6 , WkDfVxT7N20D7 , WkDfVxT7N20D8 , WkDfVxT7N20D9 , WkDfVxT8N01D1 , & - WkDfVxT8N01D2 , WkDfVxT8N01D3 , WkDfVxT8N01D4 , WkDfVxT8N01D5 , WkDfVxT8N01D6 , WkDfVxT8N01D7 , WkDfVxT8N01D8 , WkDfVxT8N01D9 , & - WkDfVxT8N02D1 , WkDfVxT8N02D2 , WkDfVxT8N02D3 , WkDfVxT8N02D4 , WkDfVxT8N02D5 , WkDfVxT8N02D6 , WkDfVxT8N02D7 , WkDfVxT8N02D8 , & - WkDfVxT8N02D9 , WkDfVxT8N03D1 , WkDfVxT8N03D2 , WkDfVxT8N03D3 , WkDfVxT8N03D4 , WkDfVxT8N03D5 , WkDfVxT8N03D6 , WkDfVxT8N03D7 , & - WkDfVxT8N03D8 , WkDfVxT8N03D9 , WkDfVxT8N04D1 , WkDfVxT8N04D2 , WkDfVxT8N04D3 , WkDfVxT8N04D4 , WkDfVxT8N04D5 , WkDfVxT8N04D6 , & - WkDfVxT8N04D7 , WkDfVxT8N04D8 , WkDfVxT8N04D9 , WkDfVxT8N05D1 , WkDfVxT8N05D2 , WkDfVxT8N05D3 , WkDfVxT8N05D4 , WkDfVxT8N05D5 , & - WkDfVxT8N05D6 , WkDfVxT8N05D7 , WkDfVxT8N05D8 , WkDfVxT8N05D9 , WkDfVxT8N06D1 , WkDfVxT8N06D2 , WkDfVxT8N06D3 , WkDfVxT8N06D4 , & - WkDfVxT8N06D5 , WkDfVxT8N06D6 , WkDfVxT8N06D7 , WkDfVxT8N06D8 , WkDfVxT8N06D9 , WkDfVxT8N07D1 , WkDfVxT8N07D2 , WkDfVxT8N07D3 , & - WkDfVxT8N07D4 , WkDfVxT8N07D5 , WkDfVxT8N07D6 , WkDfVxT8N07D7 , WkDfVxT8N07D8 , WkDfVxT8N07D9 , WkDfVxT8N08D1 , WkDfVxT8N08D2 , & - WkDfVxT8N08D3 , WkDfVxT8N08D4 , WkDfVxT8N08D5 , WkDfVxT8N08D6 , WkDfVxT8N08D7 , WkDfVxT8N08D8 , WkDfVxT8N08D9 , WkDfVxT8N09D1 , & - WkDfVxT8N09D2 , WkDfVxT8N09D3 , WkDfVxT8N09D4 , WkDfVxT8N09D5 , WkDfVxT8N09D6 , WkDfVxT8N09D7 , WkDfVxT8N09D8 , WkDfVxT8N09D9 , & - WkDfVxT8N10D1 , WkDfVxT8N10D2 , WkDfVxT8N10D3 , WkDfVxT8N10D4 , WkDfVxT8N10D5 , WkDfVxT8N10D6 , WkDfVxT8N10D7 , WkDfVxT8N10D8 , & - WkDfVxT8N10D9 , WkDfVxT8N11D1 , WkDfVxT8N11D2 , WkDfVxT8N11D3 , WkDfVxT8N11D4 , WkDfVxT8N11D5 , WkDfVxT8N11D6 , WkDfVxT8N11D7 , & - WkDfVxT8N11D8 , WkDfVxT8N11D9 , WkDfVxT8N12D1 , WkDfVxT8N12D2 , WkDfVxT8N12D3 , WkDfVxT8N12D4 , WkDfVxT8N12D5 , WkDfVxT8N12D6 , & - WkDfVxT8N12D7 , WkDfVxT8N12D8 , WkDfVxT8N12D9 , WkDfVxT8N13D1 , WkDfVxT8N13D2 , WkDfVxT8N13D3 , WkDfVxT8N13D4 , WkDfVxT8N13D5 , & - WkDfVxT8N13D6 , WkDfVxT8N13D7 , WkDfVxT8N13D8 , WkDfVxT8N13D9 , WkDfVxT8N14D1 , WkDfVxT8N14D2 , WkDfVxT8N14D3 , WkDfVxT8N14D4 , & - WkDfVxT8N14D5 , WkDfVxT8N14D6 , WkDfVxT8N14D7 , WkDfVxT8N14D8 , WkDfVxT8N14D9 , WkDfVxT8N15D1 , WkDfVxT8N15D2 , WkDfVxT8N15D3 , & - WkDfVxT8N15D4 , WkDfVxT8N15D5 , WkDfVxT8N15D6 , WkDfVxT8N15D7 , WkDfVxT8N15D8 , WkDfVxT8N15D9 , WkDfVxT8N16D1 , WkDfVxT8N16D2 , & - WkDfVxT8N16D3 , WkDfVxT8N16D4 , WkDfVxT8N16D5 , WkDfVxT8N16D6 , WkDfVxT8N16D7 , WkDfVxT8N16D8 , WkDfVxT8N16D9 , WkDfVxT8N17D1 , & - WkDfVxT8N17D2 , WkDfVxT8N17D3 , WkDfVxT8N17D4 , WkDfVxT8N17D5 , WkDfVxT8N17D6 , WkDfVxT8N17D7 , WkDfVxT8N17D8 , WkDfVxT8N17D9 , & - WkDfVxT8N18D1 , WkDfVxT8N18D2 , WkDfVxT8N18D3 , WkDfVxT8N18D4 , WkDfVxT8N18D5 , WkDfVxT8N18D6 , WkDfVxT8N18D7 , WkDfVxT8N18D8 , & - WkDfVxT8N18D9 , WkDfVxT8N19D1 , WkDfVxT8N19D2 , WkDfVxT8N19D3 , WkDfVxT8N19D4 , WkDfVxT8N19D5 , WkDfVxT8N19D6 , WkDfVxT8N19D7 , & - WkDfVxT8N19D8 , WkDfVxT8N19D9 , WkDfVxT8N20D1 , WkDfVxT8N20D2 , WkDfVxT8N20D3 , WkDfVxT8N20D4 , WkDfVxT8N20D5 , WkDfVxT8N20D6 , & - WkDfVxT8N20D7 , WkDfVxT8N20D8 , WkDfVxT8N20D9 , WkDfVxT9N01D1 , WkDfVxT9N01D2 , WkDfVxT9N01D3 , WkDfVxT9N01D4 , WkDfVxT9N01D5 , & - WkDfVxT9N01D6 , WkDfVxT9N01D7 , WkDfVxT9N01D8 , WkDfVxT9N01D9 , WkDfVxT9N02D1 , WkDfVxT9N02D2 , WkDfVxT9N02D3 , WkDfVxT9N02D4 , & - WkDfVxT9N02D5 , WkDfVxT9N02D6 , WkDfVxT9N02D7 , WkDfVxT9N02D8 , WkDfVxT9N02D9 , WkDfVxT9N03D1 , WkDfVxT9N03D2 , WkDfVxT9N03D3 , & - WkDfVxT9N03D4 , WkDfVxT9N03D5 , WkDfVxT9N03D6 , WkDfVxT9N03D7 , WkDfVxT9N03D8 , WkDfVxT9N03D9 , WkDfVxT9N04D1 , WkDfVxT9N04D2 , & - WkDfVxT9N04D3 , WkDfVxT9N04D4 , WkDfVxT9N04D5 , WkDfVxT9N04D6 , WkDfVxT9N04D7 , WkDfVxT9N04D8 , WkDfVxT9N04D9 , WkDfVxT9N05D1 , & - WkDfVxT9N05D2 , WkDfVxT9N05D3 , WkDfVxT9N05D4 , WkDfVxT9N05D5 , WkDfVxT9N05D6 , WkDfVxT9N05D7 , WkDfVxT9N05D8 , WkDfVxT9N05D9 , & - WkDfVxT9N06D1 , WkDfVxT9N06D2 , WkDfVxT9N06D3 , WkDfVxT9N06D4 , WkDfVxT9N06D5 , WkDfVxT9N06D6 , WkDfVxT9N06D7 , WkDfVxT9N06D8 , & - WkDfVxT9N06D9 , WkDfVxT9N07D1 , WkDfVxT9N07D2 , WkDfVxT9N07D3 , WkDfVxT9N07D4 , WkDfVxT9N07D5 , WkDfVxT9N07D6 , WkDfVxT9N07D7 , & - WkDfVxT9N07D8 , WkDfVxT9N07D9 , WkDfVxT9N08D1 , WkDfVxT9N08D2 , WkDfVxT9N08D3 , WkDfVxT9N08D4 , WkDfVxT9N08D5 , WkDfVxT9N08D6 , & - WkDfVxT9N08D7 , WkDfVxT9N08D8 , WkDfVxT9N08D9 , WkDfVxT9N09D1 , WkDfVxT9N09D2 , WkDfVxT9N09D3 , WkDfVxT9N09D4 , WkDfVxT9N09D5 , & - WkDfVxT9N09D6 , WkDfVxT9N09D7 , WkDfVxT9N09D8 , WkDfVxT9N09D9 , WkDfVxT9N10D1 , WkDfVxT9N10D2 , WkDfVxT9N10D3 , WkDfVxT9N10D4 , & - WkDfVxT9N10D5 , WkDfVxT9N10D6 , WkDfVxT9N10D7 , WkDfVxT9N10D8 , WkDfVxT9N10D9 , WkDfVxT9N11D1 , WkDfVxT9N11D2 , WkDfVxT9N11D3 , & - WkDfVxT9N11D4 , WkDfVxT9N11D5 , WkDfVxT9N11D6 , WkDfVxT9N11D7 , WkDfVxT9N11D8 , WkDfVxT9N11D9 , WkDfVxT9N12D1 , WkDfVxT9N12D2 , & - WkDfVxT9N12D3 , WkDfVxT9N12D4 , WkDfVxT9N12D5 , WkDfVxT9N12D6 , WkDfVxT9N12D7 , WkDfVxT9N12D8 , WkDfVxT9N12D9 , WkDfVxT9N13D1 , & - WkDfVxT9N13D2 , WkDfVxT9N13D3 , WkDfVxT9N13D4 , WkDfVxT9N13D5 , WkDfVxT9N13D6 , WkDfVxT9N13D7 , WkDfVxT9N13D8 , WkDfVxT9N13D9 , & - WkDfVxT9N14D1 , WkDfVxT9N14D2 , WkDfVxT9N14D3 , WkDfVxT9N14D4 , WkDfVxT9N14D5 , WkDfVxT9N14D6 , WkDfVxT9N14D7 , WkDfVxT9N14D8 , & - WkDfVxT9N14D9 , WkDfVxT9N15D1 , WkDfVxT9N15D2 , WkDfVxT9N15D3 , WkDfVxT9N15D4 , WkDfVxT9N15D5 , WkDfVxT9N15D6 , WkDfVxT9N15D7 , & - WkDfVxT9N15D8 , WkDfVxT9N15D9 , WkDfVxT9N16D1 , WkDfVxT9N16D2 , WkDfVxT9N16D3 , WkDfVxT9N16D4 , WkDfVxT9N16D5 , WkDfVxT9N16D6 , & - WkDfVxT9N16D7 , WkDfVxT9N16D8 , WkDfVxT9N16D9 , WkDfVxT9N17D1 , WkDfVxT9N17D2 , WkDfVxT9N17D3 , WkDfVxT9N17D4 , WkDfVxT9N17D5 , & - WkDfVxT9N17D6 , WkDfVxT9N17D7 , WkDfVxT9N17D8 , WkDfVxT9N17D9 , WkDfVxT9N18D1 , WkDfVxT9N18D2 , WkDfVxT9N18D3 , WkDfVxT9N18D4 , & - WkDfVxT9N18D5 , WkDfVxT9N18D6 , WkDfVxT9N18D7 , WkDfVxT9N18D8 , WkDfVxT9N18D9 , WkDfVxT9N19D1 , WkDfVxT9N19D2 , WkDfVxT9N19D3 , & - WkDfVxT9N19D4 , WkDfVxT9N19D5 , WkDfVxT9N19D6 , WkDfVxT9N19D7 , WkDfVxT9N19D8 , WkDfVxT9N19D9 , WkDfVxT9N20D1 , WkDfVxT9N20D2 , & - WkDfVxT9N20D3 , WkDfVxT9N20D4 , WkDfVxT9N20D5 , WkDfVxT9N20D6 , WkDfVxT9N20D7 , WkDfVxT9N20D8 , WkDfVxT9N20D9 , WkDiamT1D1 , & - WkDiamT1D2 , WkDiamT1D3 , WkDiamT1D4 , WkDiamT1D5 , WkDiamT1D6 , WkDiamT1D7 , WkDiamT1D8 , WkDiamT1D9 , & - WkDiamT2D1 , WkDiamT2D2 , WkDiamT2D3 , WkDiamT2D4 , WkDiamT2D5 , WkDiamT2D6 , WkDiamT2D7 , WkDiamT2D8 , & - WkDiamT2D9 , WkDiamT3D1 , WkDiamT3D2 , WkDiamT3D3 , WkDiamT3D4 , WkDiamT3D5 , WkDiamT3D6 , WkDiamT3D7 , & - WkDiamT3D8 , WkDiamT3D9 , WkDiamT4D1 , WkDiamT4D2 , WkDiamT4D3 , WkDiamT4D4 , WkDiamT4D5 , WkDiamT4D6 , & - WkDiamT4D7 , WkDiamT4D8 , WkDiamT4D9 , WkDiamT5D1 , WkDiamT5D2 , WkDiamT5D3 , WkDiamT5D4 , WkDiamT5D5 , & - WkDiamT5D6 , WkDiamT5D7 , WkDiamT5D8 , WkDiamT5D9 , WkDiamT6D1 , WkDiamT6D2 , WkDiamT6D3 , WkDiamT6D4 , & - WkDiamT6D5 , WkDiamT6D6 , WkDiamT6D7 , WkDiamT6D8 , WkDiamT6D9 , WkDiamT7D1 , WkDiamT7D2 , WkDiamT7D3 , & - WkDiamT7D4 , WkDiamT7D5 , WkDiamT7D6 , WkDiamT7D7 , WkDiamT7D8 , WkDiamT7D9 , WkDiamT8D1 , WkDiamT8D2 , & - WkDiamT8D3 , WkDiamT8D4 , WkDiamT8D5 , WkDiamT8D6 , WkDiamT8D7 , WkDiamT8D8 , WkDiamT8D9 , WkDiamT9D1 , & - WkDiamT9D2 , WkDiamT9D3 , WkDiamT9D4 , WkDiamT9D5 , WkDiamT9D6 , WkDiamT9D7 , WkDiamT9D8 , WkDiamT9D9 , & - WkPosXT1D1 , WkPosXT1D2 , WkPosXT1D3 , WkPosXT1D4 , WkPosXT1D5 , WkPosXT1D6 , WkPosXT1D7 , WkPosXT1D8 , & - WkPosXT1D9 , WkPosXT2D1 , WkPosXT2D2 , WkPosXT2D3 , WkPosXT2D4 , WkPosXT2D5 , WkPosXT2D6 , WkPosXT2D7 , & - WkPosXT2D8 , WkPosXT2D9 , WkPosXT3D1 , WkPosXT3D2 , WkPosXT3D3 , WkPosXT3D4 , WkPosXT3D5 , WkPosXT3D6 , & - WkPosXT3D7 , WkPosXT3D8 , WkPosXT3D9 , WkPosXT4D1 , WkPosXT4D2 , WkPosXT4D3 , WkPosXT4D4 , WkPosXT4D5 , & - WkPosXT4D6 , WkPosXT4D7 , WkPosXT4D8 , WkPosXT4D9 , WkPosXT5D1 , WkPosXT5D2 , WkPosXT5D3 , WkPosXT5D4 , & - WkPosXT5D5 , WkPosXT5D6 , WkPosXT5D7 , WkPosXT5D8 , WkPosXT5D9 , WkPosXT6D1 , WkPosXT6D2 , WkPosXT6D3 , & - WkPosXT6D4 , WkPosXT6D5 , WkPosXT6D6 , WkPosXT6D7 , WkPosXT6D8 , WkPosXT6D9 , WkPosXT7D1 , WkPosXT7D2 , & - WkPosXT7D3 , WkPosXT7D4 , WkPosXT7D5 , WkPosXT7D6 , WkPosXT7D7 , WkPosXT7D8 , WkPosXT7D9 , WkPosXT8D1 , & - WkPosXT8D2 , WkPosXT8D3 , WkPosXT8D4 , WkPosXT8D5 , WkPosXT8D6 , WkPosXT8D7 , WkPosXT8D8 , WkPosXT8D9 , & - WkPosXT9D1 , WkPosXT9D2 , WkPosXT9D3 , WkPosXT9D4 , WkPosXT9D5 , WkPosXT9D6 , WkPosXT9D7 , WkPosXT9D8 , & - WkPosXT9D9 , WkPosYT1D1 , WkPosYT1D2 , WkPosYT1D3 , WkPosYT1D4 , WkPosYT1D5 , WkPosYT1D6 , WkPosYT1D7 , & - WkPosYT1D8 , WkPosYT1D9 , WkPosYT2D1 , WkPosYT2D2 , WkPosYT2D3 , WkPosYT2D4 , WkPosYT2D5 , WkPosYT2D6 , & - WkPosYT2D7 , WkPosYT2D8 , WkPosYT2D9 , WkPosYT3D1 , WkPosYT3D2 , WkPosYT3D3 , WkPosYT3D4 , WkPosYT3D5 , & - WkPosYT3D6 , WkPosYT3D7 , WkPosYT3D8 , WkPosYT3D9 , WkPosYT4D1 , WkPosYT4D2 , WkPosYT4D3 , WkPosYT4D4 , & - WkPosYT4D5 , WkPosYT4D6 , WkPosYT4D7 , WkPosYT4D8 , WkPosYT4D9 , WkPosYT5D1 , WkPosYT5D2 , WkPosYT5D3 , & - WkPosYT5D4 , WkPosYT5D5 , WkPosYT5D6 , WkPosYT5D7 , WkPosYT5D8 , WkPosYT5D9 , WkPosYT6D1 , WkPosYT6D2 , & - WkPosYT6D3 , WkPosYT6D4 , WkPosYT6D5 , WkPosYT6D6 , WkPosYT6D7 , WkPosYT6D8 , WkPosYT6D9 , WkPosYT7D1 , & - WkPosYT7D2 , WkPosYT7D3 , WkPosYT7D4 , WkPosYT7D5 , WkPosYT7D6 , WkPosYT7D7 , WkPosYT7D8 , WkPosYT7D9 , & - WkPosYT8D1 , WkPosYT8D2 , WkPosYT8D3 , WkPosYT8D4 , WkPosYT8D5 , WkPosYT8D6 , WkPosYT8D7 , WkPosYT8D8 , & - WkPosYT8D9 , WkPosYT9D1 , WkPosYT9D2 , WkPosYT9D3 , WkPosYT9D4 , WkPosYT9D5 , WkPosYT9D6 , WkPosYT9D7 , & - WkPosYT9D8 , WkPosYT9D9 , WkPosZT1D1 , WkPosZT1D2 , WkPosZT1D3 , WkPosZT1D4 , WkPosZT1D5 , WkPosZT1D6 , & - WkPosZT1D7 , WkPosZT1D8 , WkPosZT1D9 , WkPosZT2D1 , WkPosZT2D2 , WkPosZT2D3 , WkPosZT2D4 , WkPosZT2D5 , & - WkPosZT2D6 , WkPosZT2D7 , WkPosZT2D8 , WkPosZT2D9 , WkPosZT3D1 , WkPosZT3D2 , WkPosZT3D3 , WkPosZT3D4 , & - WkPosZT3D5 , WkPosZT3D6 , WkPosZT3D7 , WkPosZT3D8 , WkPosZT3D9 , WkPosZT4D1 , WkPosZT4D2 , WkPosZT4D3 , & - WkPosZT4D4 , WkPosZT4D5 , WkPosZT4D6 , WkPosZT4D7 , WkPosZT4D8 , WkPosZT4D9 , WkPosZT5D1 , WkPosZT5D2 , & - WkPosZT5D3 , WkPosZT5D4 , WkPosZT5D5 , WkPosZT5D6 , WkPosZT5D7 , WkPosZT5D8 , WkPosZT5D9 , WkPosZT6D1 , & - WkPosZT6D2 , WkPosZT6D3 , WkPosZT6D4 , WkPosZT6D5 , WkPosZT6D6 , WkPosZT6D7 , WkPosZT6D8 , WkPosZT6D9 , & - WkPosZT7D1 , WkPosZT7D2 , WkPosZT7D3 , WkPosZT7D4 , WkPosZT7D5 , WkPosZT7D6 , WkPosZT7D7 , WkPosZT7D8 , & - WkPosZT7D9 , WkPosZT8D1 , WkPosZT8D2 , WkPosZT8D3 , WkPosZT8D4 , WkPosZT8D5 , WkPosZT8D6 , WkPosZT8D7 , & - WkPosZT8D8 , WkPosZT8D9 , WkPosZT9D1 , WkPosZT9D2 , WkPosZT9D3 , WkPosZT9D4 , WkPosZT9D5 , WkPosZT9D6 , & - WkPosZT9D7 , WkPosZT9D8 , WkPosZT9D9 , WkVelXT1D1 , WkVelXT1D2 , WkVelXT1D3 , WkVelXT1D4 , WkVelXT1D5 , & - WkVelXT1D6 , WkVelXT1D7 , WkVelXT1D8 , WkVelXT1D9 , WkVelXT2D1 , WkVelXT2D2 , WkVelXT2D3 , WkVelXT2D4 , & - WkVelXT2D5 , WkVelXT2D6 , WkVelXT2D7 , WkVelXT2D8 , WkVelXT2D9 , WkVelXT3D1 , WkVelXT3D2 , WkVelXT3D3 , & - WkVelXT3D4 , WkVelXT3D5 , WkVelXT3D6 , WkVelXT3D7 , WkVelXT3D8 , WkVelXT3D9 , WkVelXT4D1 , WkVelXT4D2 , & - WkVelXT4D3 , WkVelXT4D4 , WkVelXT4D5 , WkVelXT4D6 , WkVelXT4D7 , WkVelXT4D8 , WkVelXT4D9 , WkVelXT5D1 , & - WkVelXT5D2 , WkVelXT5D3 , WkVelXT5D4 , WkVelXT5D5 , WkVelXT5D6 , WkVelXT5D7 , WkVelXT5D8 , WkVelXT5D9 , & - WkVelXT6D1 , WkVelXT6D2 , WkVelXT6D3 , WkVelXT6D4 , WkVelXT6D5 , WkVelXT6D6 , WkVelXT6D7 , WkVelXT6D8 , & - WkVelXT6D9 , WkVelXT7D1 , WkVelXT7D2 , WkVelXT7D3 , WkVelXT7D4 , WkVelXT7D5 , WkVelXT7D6 , WkVelXT7D7 , & - WkVelXT7D8 , WkVelXT7D9 , WkVelXT8D1 , WkVelXT8D2 , WkVelXT8D3 , WkVelXT8D4 , WkVelXT8D5 , WkVelXT8D6 , & - WkVelXT8D7 , WkVelXT8D8 , WkVelXT8D9 , WkVelXT9D1 , WkVelXT9D2 , WkVelXT9D3 , WkVelXT9D4 , WkVelXT9D5 , & - WkVelXT9D6 , WkVelXT9D7 , WkVelXT9D8 , WkVelXT9D9 , WkVelYT1D1 , WkVelYT1D2 , WkVelYT1D3 , WkVelYT1D4 , & - WkVelYT1D5 , WkVelYT1D6 , WkVelYT1D7 , WkVelYT1D8 , WkVelYT1D9 , WkVelYT2D1 , WkVelYT2D2 , WkVelYT2D3 , & - WkVelYT2D4 , WkVelYT2D5 , WkVelYT2D6 , WkVelYT2D7 , WkVelYT2D8 , WkVelYT2D9 , WkVelYT3D1 , WkVelYT3D2 , & - WkVelYT3D3 , WkVelYT3D4 , WkVelYT3D5 , WkVelYT3D6 , WkVelYT3D7 , WkVelYT3D8 , WkVelYT3D9 , WkVelYT4D1 , & - WkVelYT4D2 , WkVelYT4D3 , WkVelYT4D4 , WkVelYT4D5 , WkVelYT4D6 , WkVelYT4D7 , WkVelYT4D8 , WkVelYT4D9 , & - WkVelYT5D1 , WkVelYT5D2 , WkVelYT5D3 , WkVelYT5D4 , WkVelYT5D5 , WkVelYT5D6 , WkVelYT5D7 , WkVelYT5D8 , & - WkVelYT5D9 , WkVelYT6D1 , WkVelYT6D2 , WkVelYT6D3 , WkVelYT6D4 , WkVelYT6D5 , WkVelYT6D6 , WkVelYT6D7 , & - WkVelYT6D8 , WkVelYT6D9 , WkVelYT7D1 , WkVelYT7D2 , WkVelYT7D3 , WkVelYT7D4 , WkVelYT7D5 , WkVelYT7D6 , & - WkVelYT7D7 , WkVelYT7D8 , WkVelYT7D9 , WkVelYT8D1 , WkVelYT8D2 , WkVelYT8D3 , WkVelYT8D4 , WkVelYT8D5 , & - WkVelYT8D6 , WkVelYT8D7 , WkVelYT8D8 , WkVelYT8D9 , WkVelYT9D1 , WkVelYT9D2 , WkVelYT9D3 , WkVelYT9D4 , & - WkVelYT9D5 , WkVelYT9D6 , WkVelYT9D7 , WkVelYT9D8 , WkVelYT9D9 , WkVelZT1D1 , WkVelZT1D2 , WkVelZT1D3 , & - WkVelZT1D4 , WkVelZT1D5 , WkVelZT1D6 , WkVelZT1D7 , WkVelZT1D8 , WkVelZT1D9 , WkVelZT2D1 , WkVelZT2D2 , & - WkVelZT2D3 , WkVelZT2D4 , WkVelZT2D5 , WkVelZT2D6 , WkVelZT2D7 , WkVelZT2D8 , WkVelZT2D9 , WkVelZT3D1 , & - WkVelZT3D2 , WkVelZT3D3 , WkVelZT3D4 , WkVelZT3D5 , WkVelZT3D6 , WkVelZT3D7 , WkVelZT3D8 , WkVelZT3D9 , & - WkVelZT4D1 , WkVelZT4D2 , WkVelZT4D3 , WkVelZT4D4 , WkVelZT4D5 , WkVelZT4D6 , WkVelZT4D7 , WkVelZT4D8 , & - WkVelZT4D9 , WkVelZT5D1 , WkVelZT5D2 , WkVelZT5D3 , WkVelZT5D4 , WkVelZT5D5 , WkVelZT5D6 , WkVelZT5D7 , & - WkVelZT5D8 , WkVelZT5D9 , WkVelZT6D1 , WkVelZT6D2 , WkVelZT6D3 , WkVelZT6D4 , WkVelZT6D5 , WkVelZT6D6 , & - WkVelZT6D7 , WkVelZT6D8 , WkVelZT6D9 , WkVelZT7D1 , WkVelZT7D2 , WkVelZT7D3 , WkVelZT7D4 , WkVelZT7D5 , & - WkVelZT7D6 , WkVelZT7D7 , WkVelZT7D8 , WkVelZT7D9 , WkVelZT8D1 , WkVelZT8D2 , WkVelZT8D3 , WkVelZT8D4 , & - WkVelZT8D5 , WkVelZT8D6 , WkVelZT8D7 , WkVelZT8D8 , WkVelZT8D9 , WkVelZT9D1 , WkVelZT9D2 , WkVelZT9D3 , & - WkVelZT9D4 , WkVelZT9D5 , WkVelZT9D6 , WkVelZT9D7 , WkVelZT9D8 , WkVelZT9D9 , YawErrT1 , YawErrT2 , & - YawErrT3 , YawErrT4 , YawErrT5 , YawErrT6 , YawErrT7 , YawErrT8 , YawErrT9 /) - ParamUnitsAry(1:2040) = (/ & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) "/) - ParamUnitsAry(2041:4080) = (/ & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) "/) - ParamUnitsAry(4081:6120) = (/ & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(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) ","(m) ","(m) ", & - "(m) ","(m) ","(m) ","(m) ","(m) ","(m) ","(m) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & - "(user) ","(user) ","(user) ","(user) ","(user) ","(percent) ","(percent) ","(percent) ", & - "(percent) ","(percent) ","(percent) ","(percent) ","(percent) ","(percent) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & - "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) "/) - ParamUnitsAry(6121:8160) = (/ & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) "/) - ParamUnitsAry(8161:9423) = (/ & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(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) ","(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) ","(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) ", & - "(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) ","(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) ","(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) ","(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) ","(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) ","(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) ","(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) ","(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) ", & - "(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) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(deg) ", & - "(deg) ","(deg) ","(deg) ","(deg) ","(deg) ","(deg) ","(deg) "/) - - - - ! Initialize values - ErrStat = ErrID_None - ErrMsg = "" - InvalidOutput = .FALSE. - - ! Setup the aggregated channel arrays used below - call Farm_SetAggregatedChannelOutArrays() - -! ..... Developer must add checking for invalid inputs here: ..... - - - ! Check Output radii and make sure they are >= 0 and <= Nr-1 : NOTE: This was actually already done during the input file read. - do i = 1,farm%p%NOutRadii - if ( (farm%p%OutRadii(i) < 0) .or. (farm%p%OutRadii(i) >= farm%AWAE%p%NumRadii) ) then - - InvalidOutput( CtTN (i, :) ) = .true. - InvalidOutput( WkDfVxTND(i,:,1) ) = .true. - InvalidOutput( WkDfVrTND(i,:,1) ) = .true. - InvalidOutput( EddVisTND(i,:,1) ) = .true. - InvalidOutput( EddAmbTND(i,:,1) ) = .true. - InvalidOutput( EddShrTND(i,:,1) ) = .true. - InvalidOutput( WkDfVxTND(i,:,2) ) = .true. - InvalidOutput( WkDfVrTND(i,:,2) ) = .true. - InvalidOutput( EddVisTND(i,:,2) ) = .true. - InvalidOutput( EddAmbTND(i,:,2) ) = .true. - InvalidOutput( EddShrTND(i,:,2) ) = .true. - InvalidOutput( WkDfVxTND(i,:,3) ) = .true. - InvalidOutput( WkDfVrTND(i,:,3) ) = .true. - InvalidOutput( EddVisTND(i,:,3) ) = .true. - InvalidOutput( EddAmbTND(i,:,3) ) = .true. - InvalidOutput( EddShrTND(i,:,3) ) = .true. - InvalidOutput( WkDfVxTND(i,:,4) ) = .true. - InvalidOutput( WkDfVrTND(i,:,4) ) = .true. - InvalidOutput( EddVisTND(i,:,4) ) = .true. - InvalidOutput( EddAmbTND(i,:,4) ) = .true. - InvalidOutput( EddShrTND(i,:,4) ) = .true. - InvalidOutput( WkDfVxTND(i,:,5) ) = .true. - InvalidOutput( WkDfVrTND(i,:,5) ) = .true. - InvalidOutput( EddVisTND(i,:,5) ) = .true. - InvalidOutput( EddAmbTND(i,:,5) ) = .true. - InvalidOutput( EddShrTND(i,:,5) ) = .true. - InvalidOutput( WkDfVxTND(i,:,6) ) = .true. - InvalidOutput( WkDfVrTND(i,:,6) ) = .true. - InvalidOutput( EddVisTND(i,:,6) ) = .true. - InvalidOutput( EddAmbTND(i,:,6) ) = .true. - InvalidOutput( EddShrTND(i,:,6) ) = .true. - InvalidOutput( WkDfVxTND(i,:,7) ) = .true. - InvalidOutput( WkDfVrTND(i,:,7) ) = .true. - InvalidOutput( EddVisTND(i,:,7) ) = .true. - InvalidOutput( EddAmbTND(i,:,7) ) = .true. - InvalidOutput( EddShrTND(i,:,7) ) = .true. - InvalidOutput( WkDfVxTND(i,:,8) ) = .true. - InvalidOutput( WkDfVrTND(i,:,8) ) = .true. - InvalidOutput( EddVisTND(i,:,8) ) = .true. - InvalidOutput( EddAmbTND(i,:,8) ) = .true. - InvalidOutput( EddShrTND(i,:,8) ) = .true. - InvalidOutput( WkDfVxTND(i,:,9) ) = .true. - InvalidOutput( WkDfVrTND(i,:,9) ) = .true. - InvalidOutput( EddVisTND(i,:,9) ) = .true. - InvalidOutput( EddAmbTND(i,:,9) ) = .true. - InvalidOutput( EddShrTND(i,:,9) ) = .true. - - end if - end do - - - DO i = farm%p%NOutRadii+1,20 - - InvalidOutput( CtTN (i, :) ) = .true. - InvalidOutput( WkDfVxTND(i,:,1) ) = .true. - InvalidOutput( WkDfVrTND(i,:,1) ) = .true. - InvalidOutput( EddVisTND(i,:,1) ) = .true. - InvalidOutput( EddAmbTND(i,:,1) ) = .true. - InvalidOutput( EddShrTND(i,:,1) ) = .true. - InvalidOutput( WkDfVxTND(i,:,2) ) = .true. - InvalidOutput( WkDfVrTND(i,:,2) ) = .true. - InvalidOutput( EddVisTND(i,:,2) ) = .true. - InvalidOutput( EddAmbTND(i,:,2) ) = .true. - InvalidOutput( EddShrTND(i,:,2) ) = .true. - InvalidOutput( WkDfVxTND(i,:,3) ) = .true. - InvalidOutput( WkDfVrTND(i,:,3) ) = .true. - InvalidOutput( EddVisTND(i,:,3) ) = .true. - InvalidOutput( EddAmbTND(i,:,3) ) = .true. - InvalidOutput( EddShrTND(i,:,3) ) = .true. - InvalidOutput( WkDfVxTND(i,:,4) ) = .true. - InvalidOutput( WkDfVrTND(i,:,4) ) = .true. - InvalidOutput( EddVisTND(i,:,4) ) = .true. - InvalidOutput( EddAmbTND(i,:,4) ) = .true. - InvalidOutput( EddShrTND(i,:,4) ) = .true. - InvalidOutput( WkDfVxTND(i,:,5) ) = .true. - InvalidOutput( WkDfVrTND(i,:,5) ) = .true. - InvalidOutput( EddVisTND(i,:,5) ) = .true. - InvalidOutput( EddAmbTND(i,:,5) ) = .true. - InvalidOutput( EddShrTND(i,:,5) ) = .true. - InvalidOutput( WkDfVxTND(i,:,6) ) = .true. - InvalidOutput( WkDfVrTND(i,:,6) ) = .true. - InvalidOutput( EddVisTND(i,:,6) ) = .true. - InvalidOutput( EddAmbTND(i,:,6) ) = .true. - InvalidOutput( EddShrTND(i,:,6) ) = .true. - InvalidOutput( WkDfVxTND(i,:,7) ) = .true. - InvalidOutput( WkDfVrTND(i,:,7) ) = .true. - InvalidOutput( EddVisTND(i,:,7) ) = .true. - InvalidOutput( EddAmbTND(i,:,7) ) = .true. - InvalidOutput( EddShrTND(i,:,7) ) = .true. - InvalidOutput( WkDfVxTND(i,:,8) ) = .true. - InvalidOutput( WkDfVrTND(i,:,8) ) = .true. - InvalidOutput( EddVisTND(i,:,8) ) = .true. - InvalidOutput( EddAmbTND(i,:,8) ) = .true. - InvalidOutput( EddShrTND(i,:,8) ) = .true. - InvalidOutput( WkDfVxTND(i,:,9) ) = .true. - InvalidOutput( WkDfVrTND(i,:,9) ) = .true. - InvalidOutput( EddVisTND(i,:,9) ) = .true. - InvalidOutput( EddAmbTND(i,:,9) ) = .true. - InvalidOutput( EddShrTND(i,:,9) ) = .true. - - END DO - - DO i = farm%p%NOutDist+1,9 - - InvalidOutput( WkAxsXTD ( i,:) ) = .true. - InvalidOutput( WkAxsYTD ( i,:) ) = .true. - InvalidOutput( WkAxsZTD ( i,:) ) = .true. - InvalidOutput( WkPosXTD ( i,:) ) = .true. - InvalidOutput( WkPosYTD ( i,:) ) = .true. - InvalidOutput( WkPosZTD ( i,:) ) = .true. - InvalidOutput( WkVelXTD ( i,:) ) = .true. - InvalidOutput( WkVelYTD ( i,:) ) = .true. - InvalidOutput( WkVelZTD ( i,:) ) = .true. - InvalidOutput( WkDiamTD ( i,:) ) = .true. - InvalidOutput( WkDfVxTND(:,i,1) ) = .true. - InvalidOutput( WkDfVrTND(:,i,1) ) = .true. - InvalidOutput( EddVisTND(:,i,1) ) = .true. - InvalidOutput( EddAmbTND(:,i,1) ) = .true. - InvalidOutput( EddShrTND(:,i,1) ) = .true. - InvalidOutput( WkDfVxTND(:,i,2) ) = .true. - InvalidOutput( WkDfVrTND(:,i,2) ) = .true. - InvalidOutput( EddVisTND(:,i,2) ) = .true. - InvalidOutput( EddAmbTND(:,i,2) ) = .true. - InvalidOutput( EddShrTND(:,i,2) ) = .true. - InvalidOutput( WkDfVxTND(:,i,3) ) = .true. - InvalidOutput( WkDfVrTND(:,i,3) ) = .true. - InvalidOutput( EddVisTND(:,i,3) ) = .true. - InvalidOutput( EddAmbTND(:,i,3) ) = .true. - InvalidOutput( EddShrTND(:,i,3) ) = .true. - InvalidOutput( WkDfVxTND(:,i,4) ) = .true. - InvalidOutput( WkDfVrTND(:,i,4) ) = .true. - InvalidOutput( EddVisTND(:,i,4) ) = .true. - InvalidOutput( EddAmbTND(:,i,4) ) = .true. - InvalidOutput( EddShrTND(:,i,4) ) = .true. - InvalidOutput( WkDfVxTND(:,i,5) ) = .true. - InvalidOutput( WkDfVrTND(:,i,5) ) = .true. - InvalidOutput( EddVisTND(:,i,5) ) = .true. - InvalidOutput( EddAmbTND(:,i,5) ) = .true. - InvalidOutput( EddShrTND(:,i,5) ) = .true. - InvalidOutput( WkDfVxTND(:,i,6) ) = .true. - InvalidOutput( WkDfVrTND(:,i,6) ) = .true. - InvalidOutput( EddVisTND(:,i,6) ) = .true. - InvalidOutput( EddAmbTND(:,i,6) ) = .true. - InvalidOutput( EddShrTND(:,i,6) ) = .true. - InvalidOutput( WkDfVxTND(:,i,7) ) = .true. - InvalidOutput( WkDfVrTND(:,i,7) ) = .true. - InvalidOutput( EddVisTND(:,i,7) ) = .true. - InvalidOutput( EddAmbTND(:,i,7) ) = .true. - InvalidOutput( EddShrTND(:,i,7) ) = .true. - InvalidOutput( WkDfVxTND(:,i,8) ) = .true. - InvalidOutput( WkDfVrTND(:,i,8) ) = .true. - InvalidOutput( EddVisTND(:,i,8) ) = .true. - InvalidOutput( EddAmbTND(:,i,8) ) = .true. - InvalidOutput( EddShrTND(:,i,8) ) = .true. - InvalidOutput( WkDfVxTND(:,i,9) ) = .true. - InvalidOutput( WkDfVrTND(:,i,9) ) = .true. - InvalidOutput( EddVisTND(:,i,9) ) = .true. - InvalidOutput( EddAmbTND(:,i,9) ) = .true. - InvalidOutput( EddShrTND(:,i,9) ) = .true. - - END DO - - do i = farm%p%NOutTurb+1,9 - - InvalidOutput( SCTIn ( :,i) ) = .true. - InvalidOutput( SCTOt ( :,i) ) = .true. - InvalidOutput( RtAxsXT (i) ) = .true. - InvalidOutput( RtAxsYT (i) ) = .true. - InvalidOutput( RtAxsZT (i) ) = .true. - InvalidOutput( RtPosXT (i) ) = .true. - InvalidOutput( RtPosYT (i) ) = .true. - InvalidOutput( RtPosZT (i) ) = .true. - InvalidOutput( RtDiamT (i) ) = .true. - InvalidOutput( YawErrT (i) ) = .true. - InvalidOutput( TIAmbT (i) ) = .true. - InvalidOutput( RtVAmbT (i) ) = .true. - InvalidOutput( RtVRelT (i) ) = .true. - InvalidOutput( CtTN (:, i) ) = .true. - InvalidOutput( WkAxsXTD ( :,i) ) = .true. - InvalidOutput( WkAxsYTD ( :,i) ) = .true. - InvalidOutput( WkAxsZTD ( :,i) ) = .true. - InvalidOutput( WkPosXTD ( :,i) ) = .true. - InvalidOutput( WkPosYTD ( :,i) ) = .true. - InvalidOutput( WkPosZTD ( :,i) ) = .true. - InvalidOutput( WkVelXTD ( :,i) ) = .true. - InvalidOutput( WkVelYTD ( :,i) ) = .true. - InvalidOutput( WkVelZTD ( :,i) ) = .true. - InvalidOutput( WkDiamTD ( :,i) ) = .true. - InvalidOutput( WkDfVxTND(:,1,i) ) = .true. - InvalidOutput( WkDfVrTND(:,1,i) ) = .true. - InvalidOutput( EddVisTND(:,1,i) ) = .true. - InvalidOutput( EddAmbTND(:,1,i) ) = .true. - InvalidOutput( EddShrTND(:,1,i) ) = .true. - InvalidOutput( WkDfVxTND(:,2,i) ) = .true. - InvalidOutput( WkDfVrTND(:,2,i) ) = .true. - InvalidOutput( EddVisTND(:,2,i) ) = .true. - InvalidOutput( EddAmbTND(:,2,i) ) = .true. - InvalidOutput( EddShrTND(:,2,i) ) = .true. - InvalidOutput( WkDfVxTND(:,3,i) ) = .true. - InvalidOutput( WkDfVrTND(:,3,i) ) = .true. - InvalidOutput( EddVisTND(:,3,i) ) = .true. - InvalidOutput( EddAmbTND(:,3,i) ) = .true. - InvalidOutput( EddShrTND(:,3,i) ) = .true. - InvalidOutput( WkDfVxTND(:,4,i) ) = .true. - InvalidOutput( WkDfVrTND(:,4,i) ) = .true. - InvalidOutput( EddVisTND(:,4,i) ) = .true. - InvalidOutput( EddAmbTND(:,4,i) ) = .true. - InvalidOutput( EddShrTND(:,4,i) ) = .true. - InvalidOutput( WkDfVxTND(:,5,i) ) = .true. - InvalidOutput( WkDfVrTND(:,5,i) ) = .true. - InvalidOutput( EddVisTND(:,5,i) ) = .true. - InvalidOutput( EddAmbTND(:,5,i) ) = .true. - InvalidOutput( EddShrTND(:,5,i) ) = .true. - InvalidOutput( WkDfVxTND(:,6,i) ) = .true. - InvalidOutput( WkDfVrTND(:,6,i) ) = .true. - InvalidOutput( EddVisTND(:,6,i) ) = .true. - InvalidOutput( EddAmbTND(:,6,i) ) = .true. - InvalidOutput( EddShrTND(:,6,i) ) = .true. - InvalidOutput( WkDfVxTND(:,7,i) ) = .true. - InvalidOutput( WkDfVrTND(:,7,i) ) = .true. - InvalidOutput( EddVisTND(:,7,i) ) = .true. - InvalidOutput( EddAmbTND(:,7,i) ) = .true. - InvalidOutput( EddShrTND(:,7,i) ) = .true. - InvalidOutput( WkDfVxTND(:,8,i) ) = .true. - InvalidOutput( WkDfVrTND(:,8,i) ) = .true. - InvalidOutput( EddVisTND(:,8,i) ) = .true. - InvalidOutput( EddAmbTND(:,8,i) ) = .true. - InvalidOutput( EddShrTND(:,8,i) ) = .true. - InvalidOutput( WkDfVxTND(:,9,i) ) = .true. - InvalidOutput( WkDfVrTND(:,9,i) ) = .true. - InvalidOutput( EddVisTND(:,9,i) ) = .true. - InvalidOutput( EddAmbTND(:,9,i) ) = .true. - InvalidOutput( EddShrTND(:,9,i) ) = .true. - - end do - - do i = farm%SC%p%nInpGlobal+1,9 - InvalidOutput( SCGblIn (i ) ) = .true. - end do - - do i = farm%SC%p%NumSC2CtrlGlob+1,9 - InvalidOutput( SCGblOt (i ) ) = .true. - end do - - do i = farm%SC%p%NumCtrl2SC+1,9 - InvalidOutput( SCTIn (i,:) ) = .true. - end do - - do i = farm%SC%p%NumSC2Ctrl+1,9 - InvalidOutput( SCTOt (i,:) ) = .true. - end do - - ! Add checks for the WindVel locations based on knowledge of the wind grids and NWindVel - do i = 1, farm%p%NWindVel - if (.not. PointInAABB(farm%p%WindVelX(i), farm%p%WindVelY(i), farm%p%WindVelZ(i), farm%AWAE%p%X0_low, farm%AWAE%p%Y0_low,farm%AWAE%p%Z0_low, farm%AWAE%p%X0_low+(farm%AWAE%p%nX_low-1)*farm%AWAE%p%dX_low, farm%AWAE%p%Y0_low+(farm%AWAE%p%nY_low-1)*farm%AWAE%p%dY_low, farm%AWAE%p%Z0_low+(farm%AWAE%p%nZ_low-1)*farm%AWAE%p%dZ_low) ) then - InvalidOutput( WVAmbX (i) ) = .true. - InvalidOutput( WVAmbY (i) ) = .true. - InvalidOutput( WVAmbZ (i) ) = .true. - InvalidOutput( WVDisX (i) ) = .true. - InvalidOutput( WVDisY (i) ) = .true. - InvalidOutput( WVDisZ (i) ) = .true. - end if - end do - - do i = farm%p%NWindVel+1, 9 - InvalidOutput( WVAmbX (i) ) = .true. - InvalidOutput( WVAmbY (i) ) = .true. - InvalidOutput( WVAmbZ (i) ) = .true. - InvalidOutput( WVDisX (i) ) = .true. - InvalidOutput( WVDisY (i) ) = .true. - InvalidOutput( WVDisZ (i) ) = .true. - end do - ! -! ................. End of validity checking ................. - - - !------------------------------------------------------------------------------------------------- - ! 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. - !------------------------------------------------------------------------------------------------- - - ALLOCATE ( farm%p%OutParam(0:farm%p%NumOuts) , STAT=ErrStat2 ) - IF ( ErrStat2 /= 0_IntKi ) THEN - CALL SetErrStat( ErrID_Fatal,"Error allocating memory for the fast-farm OutParam array.", ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ! Set index, name, and units for the time output channel: - - farm%p%OutParam(0)%Indx = Farm_Time_Indx - farm%p%OutParam(0)%Name = "Time" ! OutParam(0) is the time channel by default. - farm%p%OutParam(0)%Units = "(s)" - farm%p%OutParam(0)%SignM = 1 - - - ! Set index, name, and units for all of the output channels. - ! If a selected output channel is not available by this module set ErrStat = ErrID_Warn. - - DO I = 1,farm%p%NumOuts - - farm%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". - - - - IF ( INDEX( "-_", OutListTmp(1:1) ) > 0 ) THEN - farm%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 minus sign because no valid channels start with m or M) - CheckOutListAgain = .TRUE. - farm%p%OutParam(I)%SignM = -1 - OutListTmp = OutListTmp(2:) - ELSE - farm%p%OutParam(I)%SignM = 1 - END IF - - CALL Conv2UC( OutListTmp ) ! Convert OutListTmp to upper case - - Indx = IndexCharAry( OutListTmp(1:Farm_OutStrLenM1), ValidParamAry ) - - - ! If it started with an "M" (CheckOutListAgain) we didn't find the value in our list (Indx < 1) - - IF ( CheckOutListAgain .AND. Indx < 1 ) THEN ! Let's assume that "M" really meant "minus" and then test again - farm%p%OutParam(I)%SignM = -1 ! ex, "MTipDxc1" causes the sign of TipDxc1 to be switched. - OutListTmp = OutListTmp(2:) - - Indx = IndexCharAry( OutListTmp(1:Farm_OutStrLenM1), ValidParamAry ) - END IF - - - IF ( Indx > 0 ) THEN ! we found the channel name - farm%p%OutParam(I)%Indx = ParamIndxAry(Indx) - IF ( InvalidOutput( ParamIndxAry(Indx) ) ) THEN ! but, it isn't valid for these settings - farm%p%OutParam(I)%Units = "INVALID" - farm%p%OutParam(I)%SignM = 0 - ELSE - farm%p%OutParam(I)%Units = ParamUnitsAry(Indx) ! it's a valid output - END IF - ELSE ! this channel isn't valid - farm%p%OutParam(I)%Indx = Farm_Time_Indx ! pick any valid channel (I just picked "Time" here because it's universal) - farm%p%OutParam(I)%Units = "INVALID" - farm%p%OutParam(I)%SignM = 0 ! multiply all results by zero - - CALL SetErrStat(ErrID_Fatal, TRIM(farm%p%OutParam(I)%Name)//" is not an available output channel.",ErrStat,ErrMsg,RoutineName) - END IF - - END DO - - RETURN -END SUBROUTINE Farm_SetOutParam -!---------------------------------------------------------------------------------------------------------------------------------- -!End of code generated by Matlab script -!********************************************************************************************************************************** - - end module FAST_Farm_IO diff --git a/glue-codes/fast-farm/src/FAST_Farm_IO_Params.f90 b/glue-codes/fast-farm/src/FAST_Farm_IO_Params.f90 new file mode 100644 index 000000000..fd91730c8 --- /dev/null +++ b/glue-codes/fast-farm/src/FAST_Farm_IO_Params.f90 @@ -0,0 +1,15907 @@ +! =================================================================================================== +! 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". +MODULE FAST_Farm_IO_Params + + USE NWTC_Library + USE FAST_Farm_Types + + IMPLICIT NONE + + + ! 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 :: Farm_Time_Indx = 0 + + + ! Global Super Controller Input: + + INTEGER(IntKi), PARAMETER :: SCGblIn1 = 1 + INTEGER(IntKi), PARAMETER :: SCGblIn2 = 2 + INTEGER(IntKi), PARAMETER :: SCGblIn3 = 3 + INTEGER(IntKi), PARAMETER :: SCGblIn4 = 4 + INTEGER(IntKi), PARAMETER :: SCGblIn5 = 5 + INTEGER(IntKi), PARAMETER :: SCGblIn6 = 6 + INTEGER(IntKi), PARAMETER :: SCGblIn7 = 7 + INTEGER(IntKi), PARAMETER :: SCGblIn8 = 8 + INTEGER(IntKi), PARAMETER :: SCGblIn9 = 9 + + + ! Turbine-dependent Super Controller Input: + + INTEGER(IntKi), PARAMETER :: SCT1In1 = 10 + INTEGER(IntKi), PARAMETER :: SCT1In2 = 11 + INTEGER(IntKi), PARAMETER :: SCT1In3 = 12 + INTEGER(IntKi), PARAMETER :: SCT1In4 = 13 + INTEGER(IntKi), PARAMETER :: SCT1In5 = 14 + INTEGER(IntKi), PARAMETER :: SCT1In6 = 15 + INTEGER(IntKi), PARAMETER :: SCT1In7 = 16 + INTEGER(IntKi), PARAMETER :: SCT1In8 = 17 + INTEGER(IntKi), PARAMETER :: SCT1In9 = 18 + INTEGER(IntKi), PARAMETER :: SCT2In1 = 19 + INTEGER(IntKi), PARAMETER :: SCT2In2 = 20 + INTEGER(IntKi), PARAMETER :: SCT2In3 = 21 + INTEGER(IntKi), PARAMETER :: SCT2In4 = 22 + INTEGER(IntKi), PARAMETER :: SCT2In5 = 23 + INTEGER(IntKi), PARAMETER :: SCT2In6 = 24 + INTEGER(IntKi), PARAMETER :: SCT2In7 = 25 + INTEGER(IntKi), PARAMETER :: SCT2In8 = 26 + INTEGER(IntKi), PARAMETER :: SCT2In9 = 27 + INTEGER(IntKi), PARAMETER :: SCT3In1 = 28 + INTEGER(IntKi), PARAMETER :: SCT3In2 = 29 + INTEGER(IntKi), PARAMETER :: SCT3In3 = 30 + INTEGER(IntKi), PARAMETER :: SCT3In4 = 31 + INTEGER(IntKi), PARAMETER :: SCT3In5 = 32 + INTEGER(IntKi), PARAMETER :: SCT3In6 = 33 + INTEGER(IntKi), PARAMETER :: SCT3In7 = 34 + INTEGER(IntKi), PARAMETER :: SCT3In8 = 35 + INTEGER(IntKi), PARAMETER :: SCT3In9 = 36 + INTEGER(IntKi), PARAMETER :: SCT4In1 = 37 + INTEGER(IntKi), PARAMETER :: SCT4In2 = 38 + INTEGER(IntKi), PARAMETER :: SCT4In3 = 39 + INTEGER(IntKi), PARAMETER :: SCT4In4 = 40 + INTEGER(IntKi), PARAMETER :: SCT4In5 = 41 + INTEGER(IntKi), PARAMETER :: SCT4In6 = 42 + INTEGER(IntKi), PARAMETER :: SCT4In7 = 43 + INTEGER(IntKi), PARAMETER :: SCT4In8 = 44 + INTEGER(IntKi), PARAMETER :: SCT4In9 = 45 + INTEGER(IntKi), PARAMETER :: SCT5In1 = 46 + INTEGER(IntKi), PARAMETER :: SCT5In2 = 47 + INTEGER(IntKi), PARAMETER :: SCT5In3 = 48 + INTEGER(IntKi), PARAMETER :: SCT5In4 = 49 + INTEGER(IntKi), PARAMETER :: SCT5In5 = 50 + INTEGER(IntKi), PARAMETER :: SCT5In6 = 51 + INTEGER(IntKi), PARAMETER :: SCT5In7 = 52 + INTEGER(IntKi), PARAMETER :: SCT5In8 = 53 + INTEGER(IntKi), PARAMETER :: SCT5In9 = 54 + INTEGER(IntKi), PARAMETER :: SCT6In1 = 55 + INTEGER(IntKi), PARAMETER :: SCT6In2 = 56 + INTEGER(IntKi), PARAMETER :: SCT6In3 = 57 + INTEGER(IntKi), PARAMETER :: SCT6In4 = 58 + INTEGER(IntKi), PARAMETER :: SCT6In5 = 59 + INTEGER(IntKi), PARAMETER :: SCT6In6 = 60 + INTEGER(IntKi), PARAMETER :: SCT6In7 = 61 + INTEGER(IntKi), PARAMETER :: SCT6In8 = 62 + INTEGER(IntKi), PARAMETER :: SCT6In9 = 63 + INTEGER(IntKi), PARAMETER :: SCT7In1 = 64 + INTEGER(IntKi), PARAMETER :: SCT7In2 = 65 + INTEGER(IntKi), PARAMETER :: SCT7In3 = 66 + INTEGER(IntKi), PARAMETER :: SCT7In4 = 67 + INTEGER(IntKi), PARAMETER :: SCT7In5 = 68 + INTEGER(IntKi), PARAMETER :: SCT7In6 = 69 + INTEGER(IntKi), PARAMETER :: SCT7In7 = 70 + INTEGER(IntKi), PARAMETER :: SCT7In8 = 71 + INTEGER(IntKi), PARAMETER :: SCT7In9 = 72 + INTEGER(IntKi), PARAMETER :: SCT8In1 = 73 + INTEGER(IntKi), PARAMETER :: SCT8In2 = 74 + INTEGER(IntKi), PARAMETER :: SCT8In3 = 75 + INTEGER(IntKi), PARAMETER :: SCT8In4 = 76 + INTEGER(IntKi), PARAMETER :: SCT8In5 = 77 + INTEGER(IntKi), PARAMETER :: SCT8In6 = 78 + INTEGER(IntKi), PARAMETER :: SCT8In7 = 79 + INTEGER(IntKi), PARAMETER :: SCT8In8 = 80 + INTEGER(IntKi), PARAMETER :: SCT8In9 = 81 + INTEGER(IntKi), PARAMETER :: SCT9In1 = 82 + INTEGER(IntKi), PARAMETER :: SCT9In2 = 83 + INTEGER(IntKi), PARAMETER :: SCT9In3 = 84 + INTEGER(IntKi), PARAMETER :: SCT9In4 = 85 + INTEGER(IntKi), PARAMETER :: SCT9In5 = 86 + INTEGER(IntKi), PARAMETER :: SCT9In6 = 87 + INTEGER(IntKi), PARAMETER :: SCT9In7 = 88 + INTEGER(IntKi), PARAMETER :: SCT9In8 = 89 + INTEGER(IntKi), PARAMETER :: SCT9In9 = 90 + + + ! Global Super Controller Output: + + INTEGER(IntKi), PARAMETER :: SCGblOt1 = 91 + INTEGER(IntKi), PARAMETER :: SCGblOt2 = 92 + INTEGER(IntKi), PARAMETER :: SCGblOt3 = 93 + INTEGER(IntKi), PARAMETER :: SCGblOt4 = 94 + INTEGER(IntKi), PARAMETER :: SCGblOt5 = 95 + INTEGER(IntKi), PARAMETER :: SCGblOt6 = 96 + INTEGER(IntKi), PARAMETER :: SCGblOt7 = 97 + INTEGER(IntKi), PARAMETER :: SCGblOt8 = 98 + INTEGER(IntKi), PARAMETER :: SCGblOt9 = 99 + + + ! Turbine-dependent Super Controller Output: + + INTEGER(IntKi), PARAMETER :: SCT1Ot1 = 100 + INTEGER(IntKi), PARAMETER :: SCT1Ot2 = 101 + INTEGER(IntKi), PARAMETER :: SCT1Ot3 = 102 + INTEGER(IntKi), PARAMETER :: SCT1Ot4 = 103 + INTEGER(IntKi), PARAMETER :: SCT1Ot5 = 104 + INTEGER(IntKi), PARAMETER :: SCT1Ot6 = 105 + INTEGER(IntKi), PARAMETER :: SCT1Ot7 = 106 + INTEGER(IntKi), PARAMETER :: SCT1Ot8 = 107 + INTEGER(IntKi), PARAMETER :: SCT1Ot9 = 108 + INTEGER(IntKi), PARAMETER :: SCT2Ot1 = 109 + INTEGER(IntKi), PARAMETER :: SCT2Ot2 = 110 + INTEGER(IntKi), PARAMETER :: SCT2Ot3 = 111 + INTEGER(IntKi), PARAMETER :: SCT2Ot4 = 112 + INTEGER(IntKi), PARAMETER :: SCT2Ot5 = 113 + INTEGER(IntKi), PARAMETER :: SCT2Ot6 = 114 + INTEGER(IntKi), PARAMETER :: SCT2Ot7 = 115 + INTEGER(IntKi), PARAMETER :: SCT2Ot8 = 116 + INTEGER(IntKi), PARAMETER :: SCT2Ot9 = 117 + INTEGER(IntKi), PARAMETER :: SCT3Ot1 = 118 + INTEGER(IntKi), PARAMETER :: SCT3Ot2 = 119 + INTEGER(IntKi), PARAMETER :: SCT3Ot3 = 120 + INTEGER(IntKi), PARAMETER :: SCT3Ot4 = 121 + INTEGER(IntKi), PARAMETER :: SCT3Ot5 = 122 + INTEGER(IntKi), PARAMETER :: SCT3Ot6 = 123 + INTEGER(IntKi), PARAMETER :: SCT3Ot7 = 124 + INTEGER(IntKi), PARAMETER :: SCT3Ot8 = 125 + INTEGER(IntKi), PARAMETER :: SCT3Ot9 = 126 + INTEGER(IntKi), PARAMETER :: SCT4Ot1 = 127 + INTEGER(IntKi), PARAMETER :: SCT4Ot2 = 128 + INTEGER(IntKi), PARAMETER :: SCT4Ot3 = 129 + INTEGER(IntKi), PARAMETER :: SCT4Ot4 = 130 + INTEGER(IntKi), PARAMETER :: SCT4Ot5 = 131 + INTEGER(IntKi), PARAMETER :: SCT4Ot6 = 132 + INTEGER(IntKi), PARAMETER :: SCT4Ot7 = 133 + INTEGER(IntKi), PARAMETER :: SCT4Ot8 = 134 + INTEGER(IntKi), PARAMETER :: SCT4Ot9 = 135 + INTEGER(IntKi), PARAMETER :: SCT5Ot1 = 136 + INTEGER(IntKi), PARAMETER :: SCT5Ot2 = 137 + INTEGER(IntKi), PARAMETER :: SCT5Ot3 = 138 + INTEGER(IntKi), PARAMETER :: SCT5Ot4 = 139 + INTEGER(IntKi), PARAMETER :: SCT5Ot5 = 140 + INTEGER(IntKi), PARAMETER :: SCT5Ot6 = 141 + INTEGER(IntKi), PARAMETER :: SCT5Ot7 = 142 + INTEGER(IntKi), PARAMETER :: SCT5Ot8 = 143 + INTEGER(IntKi), PARAMETER :: SCT5Ot9 = 144 + INTEGER(IntKi), PARAMETER :: SCT6Ot1 = 145 + INTEGER(IntKi), PARAMETER :: SCT6Ot2 = 146 + INTEGER(IntKi), PARAMETER :: SCT6Ot3 = 147 + INTEGER(IntKi), PARAMETER :: SCT6Ot4 = 148 + INTEGER(IntKi), PARAMETER :: SCT6Ot5 = 149 + INTEGER(IntKi), PARAMETER :: SCT6Ot6 = 150 + INTEGER(IntKi), PARAMETER :: SCT6Ot7 = 151 + INTEGER(IntKi), PARAMETER :: SCT6Ot8 = 152 + INTEGER(IntKi), PARAMETER :: SCT6Ot9 = 153 + INTEGER(IntKi), PARAMETER :: SCT7Ot1 = 154 + INTEGER(IntKi), PARAMETER :: SCT7Ot2 = 155 + INTEGER(IntKi), PARAMETER :: SCT7Ot3 = 156 + INTEGER(IntKi), PARAMETER :: SCT7Ot4 = 157 + INTEGER(IntKi), PARAMETER :: SCT7Ot5 = 158 + INTEGER(IntKi), PARAMETER :: SCT7Ot6 = 159 + INTEGER(IntKi), PARAMETER :: SCT7Ot7 = 160 + INTEGER(IntKi), PARAMETER :: SCT7Ot8 = 161 + INTEGER(IntKi), PARAMETER :: SCT7Ot9 = 162 + INTEGER(IntKi), PARAMETER :: SCT8Ot1 = 163 + INTEGER(IntKi), PARAMETER :: SCT8Ot2 = 164 + INTEGER(IntKi), PARAMETER :: SCT8Ot3 = 165 + INTEGER(IntKi), PARAMETER :: SCT8Ot4 = 166 + INTEGER(IntKi), PARAMETER :: SCT8Ot5 = 167 + INTEGER(IntKi), PARAMETER :: SCT8Ot6 = 168 + INTEGER(IntKi), PARAMETER :: SCT8Ot7 = 169 + INTEGER(IntKi), PARAMETER :: SCT8Ot8 = 170 + INTEGER(IntKi), PARAMETER :: SCT8Ot9 = 171 + INTEGER(IntKi), PARAMETER :: SCT9Ot1 = 172 + INTEGER(IntKi), PARAMETER :: SCT9Ot2 = 173 + INTEGER(IntKi), PARAMETER :: SCT9Ot3 = 174 + INTEGER(IntKi), PARAMETER :: SCT9Ot4 = 175 + INTEGER(IntKi), PARAMETER :: SCT9Ot5 = 176 + INTEGER(IntKi), PARAMETER :: SCT9Ot6 = 177 + INTEGER(IntKi), PARAMETER :: SCT9Ot7 = 178 + INTEGER(IntKi), PARAMETER :: SCT9Ot8 = 179 + INTEGER(IntKi), PARAMETER :: SCT9Ot9 = 180 + + + ! Rotor centerline orientation: + + INTEGER(IntKi), PARAMETER :: RtAxsXT1 = 181 + INTEGER(IntKi), PARAMETER :: RtAxsXT2 = 182 + INTEGER(IntKi), PARAMETER :: RtAxsXT3 = 183 + INTEGER(IntKi), PARAMETER :: RtAxsXT4 = 184 + INTEGER(IntKi), PARAMETER :: RtAxsXT5 = 185 + INTEGER(IntKi), PARAMETER :: RtAxsXT6 = 186 + INTEGER(IntKi), PARAMETER :: RtAxsXT7 = 187 + INTEGER(IntKi), PARAMETER :: RtAxsXT8 = 188 + INTEGER(IntKi), PARAMETER :: RtAxsXT9 = 189 + INTEGER(IntKi), PARAMETER :: RtAxsYT1 = 190 + INTEGER(IntKi), PARAMETER :: RtAxsYT2 = 191 + INTEGER(IntKi), PARAMETER :: RtAxsYT3 = 192 + INTEGER(IntKi), PARAMETER :: RtAxsYT4 = 193 + INTEGER(IntKi), PARAMETER :: RtAxsYT5 = 194 + INTEGER(IntKi), PARAMETER :: RtAxsYT6 = 195 + INTEGER(IntKi), PARAMETER :: RtAxsYT7 = 196 + INTEGER(IntKi), PARAMETER :: RtAxsYT8 = 197 + INTEGER(IntKi), PARAMETER :: RtAxsYT9 = 198 + INTEGER(IntKi), PARAMETER :: RtAxsZT1 = 199 + INTEGER(IntKi), PARAMETER :: RtAxsZT2 = 200 + INTEGER(IntKi), PARAMETER :: RtAxsZT3 = 201 + INTEGER(IntKi), PARAMETER :: RtAxsZT4 = 202 + INTEGER(IntKi), PARAMETER :: RtAxsZT5 = 203 + INTEGER(IntKi), PARAMETER :: RtAxsZT6 = 204 + INTEGER(IntKi), PARAMETER :: RtAxsZT7 = 205 + INTEGER(IntKi), PARAMETER :: RtAxsZT8 = 206 + INTEGER(IntKi), PARAMETER :: RtAxsZT9 = 207 + + + ! Position of the Rotor (Hub) Center: + + INTEGER(IntKi), PARAMETER :: RtPosXT1 = 208 + INTEGER(IntKi), PARAMETER :: RtPosXT2 = 209 + INTEGER(IntKi), PARAMETER :: RtPosXT3 = 210 + INTEGER(IntKi), PARAMETER :: RtPosXT4 = 211 + INTEGER(IntKi), PARAMETER :: RtPosXT5 = 212 + INTEGER(IntKi), PARAMETER :: RtPosXT6 = 213 + INTEGER(IntKi), PARAMETER :: RtPosXT7 = 214 + INTEGER(IntKi), PARAMETER :: RtPosXT8 = 215 + INTEGER(IntKi), PARAMETER :: RtPosXT9 = 216 + INTEGER(IntKi), PARAMETER :: RtPosYT1 = 217 + INTEGER(IntKi), PARAMETER :: RtPosYT2 = 218 + INTEGER(IntKi), PARAMETER :: RtPosYT3 = 219 + INTEGER(IntKi), PARAMETER :: RtPosYT4 = 220 + INTEGER(IntKi), PARAMETER :: RtPosYT5 = 221 + INTEGER(IntKi), PARAMETER :: RtPosYT6 = 222 + INTEGER(IntKi), PARAMETER :: RtPosYT7 = 223 + INTEGER(IntKi), PARAMETER :: RtPosYT8 = 224 + INTEGER(IntKi), PARAMETER :: RtPosYT9 = 225 + INTEGER(IntKi), PARAMETER :: RtPosZT1 = 226 + INTEGER(IntKi), PARAMETER :: RtPosZT2 = 227 + INTEGER(IntKi), PARAMETER :: RtPosZT3 = 228 + INTEGER(IntKi), PARAMETER :: RtPosZT4 = 229 + INTEGER(IntKi), PARAMETER :: RtPosZT5 = 230 + INTEGER(IntKi), PARAMETER :: RtPosZT6 = 231 + INTEGER(IntKi), PARAMETER :: RtPosZT7 = 232 + INTEGER(IntKi), PARAMETER :: RtPosZT8 = 233 + INTEGER(IntKi), PARAMETER :: RtPosZT9 = 234 + + + ! Rotor Diameter: + + INTEGER(IntKi), PARAMETER :: RtDiamT1 = 235 + INTEGER(IntKi), PARAMETER :: RtDiamT2 = 236 + INTEGER(IntKi), PARAMETER :: RtDiamT3 = 237 + INTEGER(IntKi), PARAMETER :: RtDiamT4 = 238 + INTEGER(IntKi), PARAMETER :: RtDiamT5 = 239 + INTEGER(IntKi), PARAMETER :: RtDiamT6 = 240 + INTEGER(IntKi), PARAMETER :: RtDiamT7 = 241 + INTEGER(IntKi), PARAMETER :: RtDiamT8 = 242 + INTEGER(IntKi), PARAMETER :: RtDiamT9 = 243 + + + ! Nacelle-yaw Error: + + INTEGER(IntKi), PARAMETER :: YawErrT1 = 244 + INTEGER(IntKi), PARAMETER :: YawErrT2 = 245 + INTEGER(IntKi), PARAMETER :: YawErrT3 = 246 + INTEGER(IntKi), PARAMETER :: YawErrT4 = 247 + INTEGER(IntKi), PARAMETER :: YawErrT5 = 248 + INTEGER(IntKi), PARAMETER :: YawErrT6 = 249 + INTEGER(IntKi), PARAMETER :: YawErrT7 = 250 + INTEGER(IntKi), PARAMETER :: YawErrT8 = 251 + INTEGER(IntKi), PARAMETER :: YawErrT9 = 252 + + + ! Ambient Turbulence Intensity of the wind: + + INTEGER(IntKi), PARAMETER :: TIAmbT1 = 253 + INTEGER(IntKi), PARAMETER :: TIAmbT2 = 254 + INTEGER(IntKi), PARAMETER :: TIAmbT3 = 255 + INTEGER(IntKi), PARAMETER :: TIAmbT4 = 256 + INTEGER(IntKi), PARAMETER :: TIAmbT5 = 257 + INTEGER(IntKi), PARAMETER :: TIAmbT6 = 258 + INTEGER(IntKi), PARAMETER :: TIAmbT7 = 259 + INTEGER(IntKi), PARAMETER :: TIAmbT8 = 260 + INTEGER(IntKi), PARAMETER :: TIAmbT9 = 261 + + + ! Rotor-disk averaged ambient wind speed: + + INTEGER(IntKi), PARAMETER :: RtVAmbT1 = 262 + INTEGER(IntKi), PARAMETER :: RtVAmbT2 = 263 + INTEGER(IntKi), PARAMETER :: RtVAmbT3 = 264 + INTEGER(IntKi), PARAMETER :: RtVAmbT4 = 265 + INTEGER(IntKi), PARAMETER :: RtVAmbT5 = 266 + INTEGER(IntKi), PARAMETER :: RtVAmbT6 = 267 + INTEGER(IntKi), PARAMETER :: RtVAmbT7 = 268 + INTEGER(IntKi), PARAMETER :: RtVAmbT8 = 269 + INTEGER(IntKi), PARAMETER :: RtVAmbT9 = 270 + + + ! Rotor-disk averaged ambient wind speed (time-filtered): + + INTEGER(IntKi), PARAMETER :: RtVAmbFiltT1 = 271 + INTEGER(IntKi), PARAMETER :: RtVAmbFiltT2 = 272 + INTEGER(IntKi), PARAMETER :: RtVAmbFiltT3 = 273 + INTEGER(IntKi), PARAMETER :: RtVAmbFiltT4 = 274 + INTEGER(IntKi), PARAMETER :: RtVAmbFiltT5 = 275 + INTEGER(IntKi), PARAMETER :: RtVAmbFiltT6 = 276 + INTEGER(IntKi), PARAMETER :: RtVAmbFiltT7 = 277 + INTEGER(IntKi), PARAMETER :: RtVAmbFiltT8 = 278 + INTEGER(IntKi), PARAMETER :: RtVAmbFiltT9 = 279 + + + ! Rotor-disk averaged relative wind speed: + + INTEGER(IntKi), PARAMETER :: RtVRelT1 = 280 + INTEGER(IntKi), PARAMETER :: RtVRelT2 = 281 + INTEGER(IntKi), PARAMETER :: RtVRelT3 = 282 + INTEGER(IntKi), PARAMETER :: RtVRelT4 = 283 + INTEGER(IntKi), PARAMETER :: RtVRelT5 = 284 + INTEGER(IntKi), PARAMETER :: RtVRelT6 = 285 + INTEGER(IntKi), PARAMETER :: RtVRelT7 = 286 + INTEGER(IntKi), PARAMETER :: RtVRelT8 = 287 + INTEGER(IntKi), PARAMETER :: RtVRelT9 = 288 + + + ! Skew azimuth angle (instantaneous): + + INTEGER(IntKi), PARAMETER :: AziSkewT1 = 289 + INTEGER(IntKi), PARAMETER :: AziSkewT2 = 290 + INTEGER(IntKi), PARAMETER :: AziSkewT3 = 291 + INTEGER(IntKi), PARAMETER :: AziSkewT4 = 292 + INTEGER(IntKi), PARAMETER :: AziSkewT5 = 293 + INTEGER(IntKi), PARAMETER :: AziSkewT6 = 294 + INTEGER(IntKi), PARAMETER :: AziSkewT7 = 295 + INTEGER(IntKi), PARAMETER :: AziSkewT8 = 296 + INTEGER(IntKi), PARAMETER :: AziSkewT9 = 297 + + + ! Skew azimuth angle (time-filtered): + + INTEGER(IntKi), PARAMETER :: AziSkewFiltT1 = 298 + INTEGER(IntKi), PARAMETER :: AziSkewFiltT2 = 299 + INTEGER(IntKi), PARAMETER :: AziSkewFiltT3 = 300 + INTEGER(IntKi), PARAMETER :: AziSkewFiltT4 = 301 + INTEGER(IntKi), PARAMETER :: AziSkewFiltT5 = 302 + INTEGER(IntKi), PARAMETER :: AziSkewFiltT6 = 303 + INTEGER(IntKi), PARAMETER :: AziSkewFiltT7 = 304 + INTEGER(IntKi), PARAMETER :: AziSkewFiltT8 = 305 + INTEGER(IntKi), PARAMETER :: AziSkewFiltT9 = 306 + + + ! Skew angle (instantaneous): + + INTEGER(IntKi), PARAMETER :: RtSkewT1 = 307 + INTEGER(IntKi), PARAMETER :: RtSkewT2 = 308 + INTEGER(IntKi), PARAMETER :: RtSkewT3 = 309 + INTEGER(IntKi), PARAMETER :: RtSkewT4 = 310 + INTEGER(IntKi), PARAMETER :: RtSkewT5 = 311 + INTEGER(IntKi), PARAMETER :: RtSkewT6 = 312 + INTEGER(IntKi), PARAMETER :: RtSkewT7 = 313 + INTEGER(IntKi), PARAMETER :: RtSkewT8 = 314 + INTEGER(IntKi), PARAMETER :: RtSkewT9 = 315 + + + ! Skew angle (time-filtered): + + INTEGER(IntKi), PARAMETER :: RtSkewFiltT1 = 316 + INTEGER(IntKi), PARAMETER :: RtSkewFiltT2 = 317 + INTEGER(IntKi), PARAMETER :: RtSkewFiltT3 = 318 + INTEGER(IntKi), PARAMETER :: RtSkewFiltT4 = 319 + INTEGER(IntKi), PARAMETER :: RtSkewFiltT5 = 320 + INTEGER(IntKi), PARAMETER :: RtSkewFiltT6 = 321 + INTEGER(IntKi), PARAMETER :: RtSkewFiltT7 = 322 + INTEGER(IntKi), PARAMETER :: RtSkewFiltT8 = 323 + INTEGER(IntKi), PARAMETER :: RtSkewFiltT9 = 324 + + + ! Rotor circulation for curled-wake model: + + INTEGER(IntKi), PARAMETER :: RtGamCurlT1 = 325 + INTEGER(IntKi), PARAMETER :: RtGamCurlT2 = 326 + INTEGER(IntKi), PARAMETER :: RtGamCurlT3 = 327 + INTEGER(IntKi), PARAMETER :: RtGamCurlT4 = 328 + INTEGER(IntKi), PARAMETER :: RtGamCurlT5 = 329 + INTEGER(IntKi), PARAMETER :: RtGamCurlT6 = 330 + INTEGER(IntKi), PARAMETER :: RtGamCurlT7 = 331 + INTEGER(IntKi), PARAMETER :: RtGamCurlT8 = 332 + INTEGER(IntKi), PARAMETER :: RtGamCurlT9 = 333 + + + ! Rotor-disk averaged thrust coefficient: + + INTEGER(IntKi), PARAMETER :: RtCtAvgT1 = 334 + INTEGER(IntKi), PARAMETER :: RtCtAvgT2 = 335 + INTEGER(IntKi), PARAMETER :: RtCtAvgT3 = 336 + INTEGER(IntKi), PARAMETER :: RtCtAvgT4 = 337 + INTEGER(IntKi), PARAMETER :: RtCtAvgT5 = 338 + INTEGER(IntKi), PARAMETER :: RtCtAvgT6 = 339 + INTEGER(IntKi), PARAMETER :: RtCtAvgT7 = 340 + INTEGER(IntKi), PARAMETER :: RtCtAvgT8 = 341 + INTEGER(IntKi), PARAMETER :: RtCtAvgT9 = 342 + + + ! Azimuthally averaged thrust force coefficient: + + INTEGER(IntKi), PARAMETER :: CtT1N01 = 343 + INTEGER(IntKi), PARAMETER :: CtT1N02 = 344 + INTEGER(IntKi), PARAMETER :: CtT1N03 = 345 + INTEGER(IntKi), PARAMETER :: CtT1N04 = 346 + INTEGER(IntKi), PARAMETER :: CtT1N05 = 347 + INTEGER(IntKi), PARAMETER :: CtT1N06 = 348 + INTEGER(IntKi), PARAMETER :: CtT1N07 = 349 + INTEGER(IntKi), PARAMETER :: CtT1N08 = 350 + INTEGER(IntKi), PARAMETER :: CtT1N09 = 351 + INTEGER(IntKi), PARAMETER :: CtT1N10 = 352 + INTEGER(IntKi), PARAMETER :: CtT1N11 = 353 + INTEGER(IntKi), PARAMETER :: CtT1N12 = 354 + INTEGER(IntKi), PARAMETER :: CtT1N13 = 355 + INTEGER(IntKi), PARAMETER :: CtT1N14 = 356 + INTEGER(IntKi), PARAMETER :: CtT1N15 = 357 + INTEGER(IntKi), PARAMETER :: CtT1N16 = 358 + INTEGER(IntKi), PARAMETER :: CtT1N17 = 359 + INTEGER(IntKi), PARAMETER :: CtT1N18 = 360 + INTEGER(IntKi), PARAMETER :: CtT1N19 = 361 + INTEGER(IntKi), PARAMETER :: CtT1N20 = 362 + INTEGER(IntKi), PARAMETER :: CtT2N01 = 363 + INTEGER(IntKi), PARAMETER :: CtT2N02 = 364 + INTEGER(IntKi), PARAMETER :: CtT2N03 = 365 + INTEGER(IntKi), PARAMETER :: CtT2N04 = 366 + INTEGER(IntKi), PARAMETER :: CtT2N05 = 367 + INTEGER(IntKi), PARAMETER :: CtT2N06 = 368 + INTEGER(IntKi), PARAMETER :: CtT2N07 = 369 + INTEGER(IntKi), PARAMETER :: CtT2N08 = 370 + INTEGER(IntKi), PARAMETER :: CtT2N09 = 371 + INTEGER(IntKi), PARAMETER :: CtT2N10 = 372 + INTEGER(IntKi), PARAMETER :: CtT2N11 = 373 + INTEGER(IntKi), PARAMETER :: CtT2N12 = 374 + INTEGER(IntKi), PARAMETER :: CtT2N13 = 375 + INTEGER(IntKi), PARAMETER :: CtT2N14 = 376 + INTEGER(IntKi), PARAMETER :: CtT2N15 = 377 + INTEGER(IntKi), PARAMETER :: CtT2N16 = 378 + INTEGER(IntKi), PARAMETER :: CtT2N17 = 379 + INTEGER(IntKi), PARAMETER :: CtT2N18 = 380 + INTEGER(IntKi), PARAMETER :: CtT2N19 = 381 + INTEGER(IntKi), PARAMETER :: CtT2N20 = 382 + INTEGER(IntKi), PARAMETER :: CtT3N01 = 383 + INTEGER(IntKi), PARAMETER :: CtT3N02 = 384 + INTEGER(IntKi), PARAMETER :: CtT3N03 = 385 + INTEGER(IntKi), PARAMETER :: CtT3N04 = 386 + INTEGER(IntKi), PARAMETER :: CtT3N05 = 387 + INTEGER(IntKi), PARAMETER :: CtT3N06 = 388 + INTEGER(IntKi), PARAMETER :: CtT3N07 = 389 + INTEGER(IntKi), PARAMETER :: CtT3N08 = 390 + INTEGER(IntKi), PARAMETER :: CtT3N09 = 391 + INTEGER(IntKi), PARAMETER :: CtT3N10 = 392 + INTEGER(IntKi), PARAMETER :: CtT3N11 = 393 + INTEGER(IntKi), PARAMETER :: CtT3N12 = 394 + INTEGER(IntKi), PARAMETER :: CtT3N13 = 395 + INTEGER(IntKi), PARAMETER :: CtT3N14 = 396 + INTEGER(IntKi), PARAMETER :: CtT3N15 = 397 + INTEGER(IntKi), PARAMETER :: CtT3N16 = 398 + INTEGER(IntKi), PARAMETER :: CtT3N17 = 399 + INTEGER(IntKi), PARAMETER :: CtT3N18 = 400 + INTEGER(IntKi), PARAMETER :: CtT3N19 = 401 + INTEGER(IntKi), PARAMETER :: CtT3N20 = 402 + INTEGER(IntKi), PARAMETER :: CtT4N01 = 403 + INTEGER(IntKi), PARAMETER :: CtT4N02 = 404 + INTEGER(IntKi), PARAMETER :: CtT4N03 = 405 + INTEGER(IntKi), PARAMETER :: CtT4N04 = 406 + INTEGER(IntKi), PARAMETER :: CtT4N05 = 407 + INTEGER(IntKi), PARAMETER :: CtT4N06 = 408 + INTEGER(IntKi), PARAMETER :: CtT4N07 = 409 + INTEGER(IntKi), PARAMETER :: CtT4N08 = 410 + INTEGER(IntKi), PARAMETER :: CtT4N09 = 411 + INTEGER(IntKi), PARAMETER :: CtT4N10 = 412 + INTEGER(IntKi), PARAMETER :: CtT4N11 = 413 + INTEGER(IntKi), PARAMETER :: CtT4N12 = 414 + INTEGER(IntKi), PARAMETER :: CtT4N13 = 415 + INTEGER(IntKi), PARAMETER :: CtT4N14 = 416 + INTEGER(IntKi), PARAMETER :: CtT4N15 = 417 + INTEGER(IntKi), PARAMETER :: CtT4N16 = 418 + INTEGER(IntKi), PARAMETER :: CtT4N17 = 419 + INTEGER(IntKi), PARAMETER :: CtT4N18 = 420 + INTEGER(IntKi), PARAMETER :: CtT4N19 = 421 + INTEGER(IntKi), PARAMETER :: CtT4N20 = 422 + INTEGER(IntKi), PARAMETER :: CtT5N01 = 423 + INTEGER(IntKi), PARAMETER :: CtT5N02 = 424 + INTEGER(IntKi), PARAMETER :: CtT5N03 = 425 + INTEGER(IntKi), PARAMETER :: CtT5N04 = 426 + INTEGER(IntKi), PARAMETER :: CtT5N05 = 427 + INTEGER(IntKi), PARAMETER :: CtT5N06 = 428 + INTEGER(IntKi), PARAMETER :: CtT5N07 = 429 + INTEGER(IntKi), PARAMETER :: CtT5N08 = 430 + INTEGER(IntKi), PARAMETER :: CtT5N09 = 431 + INTEGER(IntKi), PARAMETER :: CtT5N10 = 432 + INTEGER(IntKi), PARAMETER :: CtT5N11 = 433 + INTEGER(IntKi), PARAMETER :: CtT5N12 = 434 + INTEGER(IntKi), PARAMETER :: CtT5N13 = 435 + INTEGER(IntKi), PARAMETER :: CtT5N14 = 436 + INTEGER(IntKi), PARAMETER :: CtT5N15 = 437 + INTEGER(IntKi), PARAMETER :: CtT5N16 = 438 + INTEGER(IntKi), PARAMETER :: CtT5N17 = 439 + INTEGER(IntKi), PARAMETER :: CtT5N18 = 440 + INTEGER(IntKi), PARAMETER :: CtT5N19 = 441 + INTEGER(IntKi), PARAMETER :: CtT5N20 = 442 + INTEGER(IntKi), PARAMETER :: CtT6N01 = 443 + INTEGER(IntKi), PARAMETER :: CtT6N02 = 444 + INTEGER(IntKi), PARAMETER :: CtT6N03 = 445 + INTEGER(IntKi), PARAMETER :: CtT6N04 = 446 + INTEGER(IntKi), PARAMETER :: CtT6N05 = 447 + INTEGER(IntKi), PARAMETER :: CtT6N06 = 448 + INTEGER(IntKi), PARAMETER :: CtT6N07 = 449 + INTEGER(IntKi), PARAMETER :: CtT6N08 = 450 + INTEGER(IntKi), PARAMETER :: CtT6N09 = 451 + INTEGER(IntKi), PARAMETER :: CtT6N10 = 452 + INTEGER(IntKi), PARAMETER :: CtT6N11 = 453 + INTEGER(IntKi), PARAMETER :: CtT6N12 = 454 + INTEGER(IntKi), PARAMETER :: CtT6N13 = 455 + INTEGER(IntKi), PARAMETER :: CtT6N14 = 456 + INTEGER(IntKi), PARAMETER :: CtT6N15 = 457 + INTEGER(IntKi), PARAMETER :: CtT6N16 = 458 + INTEGER(IntKi), PARAMETER :: CtT6N17 = 459 + INTEGER(IntKi), PARAMETER :: CtT6N18 = 460 + INTEGER(IntKi), PARAMETER :: CtT6N19 = 461 + INTEGER(IntKi), PARAMETER :: CtT6N20 = 462 + INTEGER(IntKi), PARAMETER :: CtT7N01 = 463 + INTEGER(IntKi), PARAMETER :: CtT7N02 = 464 + INTEGER(IntKi), PARAMETER :: CtT7N03 = 465 + INTEGER(IntKi), PARAMETER :: CtT7N04 = 466 + INTEGER(IntKi), PARAMETER :: CtT7N05 = 467 + INTEGER(IntKi), PARAMETER :: CtT7N06 = 468 + INTEGER(IntKi), PARAMETER :: CtT7N07 = 469 + INTEGER(IntKi), PARAMETER :: CtT7N08 = 470 + INTEGER(IntKi), PARAMETER :: CtT7N09 = 471 + INTEGER(IntKi), PARAMETER :: CtT7N10 = 472 + INTEGER(IntKi), PARAMETER :: CtT7N11 = 473 + INTEGER(IntKi), PARAMETER :: CtT7N12 = 474 + INTEGER(IntKi), PARAMETER :: CtT7N13 = 475 + INTEGER(IntKi), PARAMETER :: CtT7N14 = 476 + INTEGER(IntKi), PARAMETER :: CtT7N15 = 477 + INTEGER(IntKi), PARAMETER :: CtT7N16 = 478 + INTEGER(IntKi), PARAMETER :: CtT7N17 = 479 + INTEGER(IntKi), PARAMETER :: CtT7N18 = 480 + INTEGER(IntKi), PARAMETER :: CtT7N19 = 481 + INTEGER(IntKi), PARAMETER :: CtT7N20 = 482 + INTEGER(IntKi), PARAMETER :: CtT8N01 = 483 + INTEGER(IntKi), PARAMETER :: CtT8N02 = 484 + INTEGER(IntKi), PARAMETER :: CtT8N03 = 485 + INTEGER(IntKi), PARAMETER :: CtT8N04 = 486 + INTEGER(IntKi), PARAMETER :: CtT8N05 = 487 + INTEGER(IntKi), PARAMETER :: CtT8N06 = 488 + INTEGER(IntKi), PARAMETER :: CtT8N07 = 489 + INTEGER(IntKi), PARAMETER :: CtT8N08 = 490 + INTEGER(IntKi), PARAMETER :: CtT8N09 = 491 + INTEGER(IntKi), PARAMETER :: CtT8N10 = 492 + INTEGER(IntKi), PARAMETER :: CtT8N11 = 493 + INTEGER(IntKi), PARAMETER :: CtT8N12 = 494 + INTEGER(IntKi), PARAMETER :: CtT8N13 = 495 + INTEGER(IntKi), PARAMETER :: CtT8N14 = 496 + INTEGER(IntKi), PARAMETER :: CtT8N15 = 497 + INTEGER(IntKi), PARAMETER :: CtT8N16 = 498 + INTEGER(IntKi), PARAMETER :: CtT8N17 = 499 + INTEGER(IntKi), PARAMETER :: CtT8N18 = 500 + INTEGER(IntKi), PARAMETER :: CtT8N19 = 501 + INTEGER(IntKi), PARAMETER :: CtT8N20 = 502 + INTEGER(IntKi), PARAMETER :: CtT9N01 = 503 + INTEGER(IntKi), PARAMETER :: CtT9N02 = 504 + INTEGER(IntKi), PARAMETER :: CtT9N03 = 505 + INTEGER(IntKi), PARAMETER :: CtT9N04 = 506 + INTEGER(IntKi), PARAMETER :: CtT9N05 = 507 + INTEGER(IntKi), PARAMETER :: CtT9N06 = 508 + INTEGER(IntKi), PARAMETER :: CtT9N07 = 509 + INTEGER(IntKi), PARAMETER :: CtT9N08 = 510 + INTEGER(IntKi), PARAMETER :: CtT9N09 = 511 + INTEGER(IntKi), PARAMETER :: CtT9N10 = 512 + INTEGER(IntKi), PARAMETER :: CtT9N11 = 513 + INTEGER(IntKi), PARAMETER :: CtT9N12 = 514 + INTEGER(IntKi), PARAMETER :: CtT9N13 = 515 + INTEGER(IntKi), PARAMETER :: CtT9N14 = 516 + INTEGER(IntKi), PARAMETER :: CtT9N15 = 517 + INTEGER(IntKi), PARAMETER :: CtT9N16 = 518 + INTEGER(IntKi), PARAMETER :: CtT9N17 = 519 + INTEGER(IntKi), PARAMETER :: CtT9N18 = 520 + INTEGER(IntKi), PARAMETER :: CtT9N19 = 521 + INTEGER(IntKi), PARAMETER :: CtT9N20 = 522 + + + ! Orientation of the wake centerline: + + INTEGER(IntKi), PARAMETER :: WkAxsXT1D1 = 523 + INTEGER(IntKi), PARAMETER :: WkAxsXT1D2 = 524 + INTEGER(IntKi), PARAMETER :: WkAxsXT1D3 = 525 + INTEGER(IntKi), PARAMETER :: WkAxsXT1D4 = 526 + INTEGER(IntKi), PARAMETER :: WkAxsXT1D5 = 527 + INTEGER(IntKi), PARAMETER :: WkAxsXT1D6 = 528 + INTEGER(IntKi), PARAMETER :: WkAxsXT1D7 = 529 + INTEGER(IntKi), PARAMETER :: WkAxsXT1D8 = 530 + INTEGER(IntKi), PARAMETER :: WkAxsXT1D9 = 531 + INTEGER(IntKi), PARAMETER :: WkAxsXT2D1 = 532 + INTEGER(IntKi), PARAMETER :: WkAxsXT2D2 = 533 + INTEGER(IntKi), PARAMETER :: WkAxsXT2D3 = 534 + INTEGER(IntKi), PARAMETER :: WkAxsXT2D4 = 535 + INTEGER(IntKi), PARAMETER :: WkAxsXT2D5 = 536 + INTEGER(IntKi), PARAMETER :: WkAxsXT2D6 = 537 + INTEGER(IntKi), PARAMETER :: WkAxsXT2D7 = 538 + INTEGER(IntKi), PARAMETER :: WkAxsXT2D8 = 539 + INTEGER(IntKi), PARAMETER :: WkAxsXT2D9 = 540 + INTEGER(IntKi), PARAMETER :: WkAxsXT3D1 = 541 + INTEGER(IntKi), PARAMETER :: WkAxsXT3D2 = 542 + INTEGER(IntKi), PARAMETER :: WkAxsXT3D3 = 543 + INTEGER(IntKi), PARAMETER :: WkAxsXT3D4 = 544 + INTEGER(IntKi), PARAMETER :: WkAxsXT3D5 = 545 + INTEGER(IntKi), PARAMETER :: WkAxsXT3D6 = 546 + INTEGER(IntKi), PARAMETER :: WkAxsXT3D7 = 547 + INTEGER(IntKi), PARAMETER :: WkAxsXT3D8 = 548 + INTEGER(IntKi), PARAMETER :: WkAxsXT3D9 = 549 + INTEGER(IntKi), PARAMETER :: WkAxsXT4D1 = 550 + INTEGER(IntKi), PARAMETER :: WkAxsXT4D2 = 551 + INTEGER(IntKi), PARAMETER :: WkAxsXT4D3 = 552 + INTEGER(IntKi), PARAMETER :: WkAxsXT4D4 = 553 + INTEGER(IntKi), PARAMETER :: WkAxsXT4D5 = 554 + INTEGER(IntKi), PARAMETER :: WkAxsXT4D6 = 555 + INTEGER(IntKi), PARAMETER :: WkAxsXT4D7 = 556 + INTEGER(IntKi), PARAMETER :: WkAxsXT4D8 = 557 + INTEGER(IntKi), PARAMETER :: WkAxsXT4D9 = 558 + INTEGER(IntKi), PARAMETER :: WkAxsXT5D1 = 559 + INTEGER(IntKi), PARAMETER :: WkAxsXT5D2 = 560 + INTEGER(IntKi), PARAMETER :: WkAxsXT5D3 = 561 + INTEGER(IntKi), PARAMETER :: WkAxsXT5D4 = 562 + INTEGER(IntKi), PARAMETER :: WkAxsXT5D5 = 563 + INTEGER(IntKi), PARAMETER :: WkAxsXT5D6 = 564 + INTEGER(IntKi), PARAMETER :: WkAxsXT5D7 = 565 + INTEGER(IntKi), PARAMETER :: WkAxsXT5D8 = 566 + INTEGER(IntKi), PARAMETER :: WkAxsXT5D9 = 567 + INTEGER(IntKi), PARAMETER :: WkAxsXT6D1 = 568 + INTEGER(IntKi), PARAMETER :: WkAxsXT6D2 = 569 + INTEGER(IntKi), PARAMETER :: WkAxsXT6D3 = 570 + INTEGER(IntKi), PARAMETER :: WkAxsXT6D4 = 571 + INTEGER(IntKi), PARAMETER :: WkAxsXT6D5 = 572 + INTEGER(IntKi), PARAMETER :: WkAxsXT6D6 = 573 + INTEGER(IntKi), PARAMETER :: WkAxsXT6D7 = 574 + INTEGER(IntKi), PARAMETER :: WkAxsXT6D8 = 575 + INTEGER(IntKi), PARAMETER :: WkAxsXT6D9 = 576 + INTEGER(IntKi), PARAMETER :: WkAxsXT7D1 = 577 + INTEGER(IntKi), PARAMETER :: WkAxsXT7D2 = 578 + INTEGER(IntKi), PARAMETER :: WkAxsXT7D3 = 579 + INTEGER(IntKi), PARAMETER :: WkAxsXT7D4 = 580 + INTEGER(IntKi), PARAMETER :: WkAxsXT7D5 = 581 + INTEGER(IntKi), PARAMETER :: WkAxsXT7D6 = 582 + INTEGER(IntKi), PARAMETER :: WkAxsXT7D7 = 583 + INTEGER(IntKi), PARAMETER :: WkAxsXT7D8 = 584 + INTEGER(IntKi), PARAMETER :: WkAxsXT7D9 = 585 + INTEGER(IntKi), PARAMETER :: WkAxsXT8D1 = 586 + INTEGER(IntKi), PARAMETER :: WkAxsXT8D2 = 587 + INTEGER(IntKi), PARAMETER :: WkAxsXT8D3 = 588 + INTEGER(IntKi), PARAMETER :: WkAxsXT8D4 = 589 + INTEGER(IntKi), PARAMETER :: WkAxsXT8D5 = 590 + INTEGER(IntKi), PARAMETER :: WkAxsXT8D6 = 591 + INTEGER(IntKi), PARAMETER :: WkAxsXT8D7 = 592 + INTEGER(IntKi), PARAMETER :: WkAxsXT8D8 = 593 + INTEGER(IntKi), PARAMETER :: WkAxsXT8D9 = 594 + INTEGER(IntKi), PARAMETER :: WkAxsXT9D1 = 595 + INTEGER(IntKi), PARAMETER :: WkAxsXT9D2 = 596 + INTEGER(IntKi), PARAMETER :: WkAxsXT9D3 = 597 + INTEGER(IntKi), PARAMETER :: WkAxsXT9D4 = 598 + INTEGER(IntKi), PARAMETER :: WkAxsXT9D5 = 599 + INTEGER(IntKi), PARAMETER :: WkAxsXT9D6 = 600 + INTEGER(IntKi), PARAMETER :: WkAxsXT9D7 = 601 + INTEGER(IntKi), PARAMETER :: WkAxsXT9D8 = 602 + INTEGER(IntKi), PARAMETER :: WkAxsXT9D9 = 603 + INTEGER(IntKi), PARAMETER :: WkAxsYT1D1 = 604 + INTEGER(IntKi), PARAMETER :: WkAxsYT1D2 = 605 + INTEGER(IntKi), PARAMETER :: WkAxsYT1D3 = 606 + INTEGER(IntKi), PARAMETER :: WkAxsYT1D4 = 607 + INTEGER(IntKi), PARAMETER :: WkAxsYT1D5 = 608 + INTEGER(IntKi), PARAMETER :: WkAxsYT1D6 = 609 + INTEGER(IntKi), PARAMETER :: WkAxsYT1D7 = 610 + INTEGER(IntKi), PARAMETER :: WkAxsYT1D8 = 611 + INTEGER(IntKi), PARAMETER :: WkAxsYT1D9 = 612 + INTEGER(IntKi), PARAMETER :: WkAxsYT2D1 = 613 + INTEGER(IntKi), PARAMETER :: WkAxsYT2D2 = 614 + INTEGER(IntKi), PARAMETER :: WkAxsYT2D3 = 615 + INTEGER(IntKi), PARAMETER :: WkAxsYT2D4 = 616 + INTEGER(IntKi), PARAMETER :: WkAxsYT2D5 = 617 + INTEGER(IntKi), PARAMETER :: WkAxsYT2D6 = 618 + INTEGER(IntKi), PARAMETER :: WkAxsYT2D7 = 619 + INTEGER(IntKi), PARAMETER :: WkAxsYT2D8 = 620 + INTEGER(IntKi), PARAMETER :: WkAxsYT2D9 = 621 + INTEGER(IntKi), PARAMETER :: WkAxsYT3D1 = 622 + INTEGER(IntKi), PARAMETER :: WkAxsYT3D2 = 623 + INTEGER(IntKi), PARAMETER :: WkAxsYT3D3 = 624 + INTEGER(IntKi), PARAMETER :: WkAxsYT3D4 = 625 + INTEGER(IntKi), PARAMETER :: WkAxsYT3D5 = 626 + INTEGER(IntKi), PARAMETER :: WkAxsYT3D6 = 627 + INTEGER(IntKi), PARAMETER :: WkAxsYT3D7 = 628 + INTEGER(IntKi), PARAMETER :: WkAxsYT3D8 = 629 + INTEGER(IntKi), PARAMETER :: WkAxsYT3D9 = 630 + INTEGER(IntKi), PARAMETER :: WkAxsYT4D1 = 631 + INTEGER(IntKi), PARAMETER :: WkAxsYT4D2 = 632 + INTEGER(IntKi), PARAMETER :: WkAxsYT4D3 = 633 + INTEGER(IntKi), PARAMETER :: WkAxsYT4D4 = 634 + INTEGER(IntKi), PARAMETER :: WkAxsYT4D5 = 635 + INTEGER(IntKi), PARAMETER :: WkAxsYT4D6 = 636 + INTEGER(IntKi), PARAMETER :: WkAxsYT4D7 = 637 + INTEGER(IntKi), PARAMETER :: WkAxsYT4D8 = 638 + INTEGER(IntKi), PARAMETER :: WkAxsYT4D9 = 639 + INTEGER(IntKi), PARAMETER :: WkAxsYT5D1 = 640 + INTEGER(IntKi), PARAMETER :: WkAxsYT5D2 = 641 + INTEGER(IntKi), PARAMETER :: WkAxsYT5D3 = 642 + INTEGER(IntKi), PARAMETER :: WkAxsYT5D4 = 643 + INTEGER(IntKi), PARAMETER :: WkAxsYT5D5 = 644 + INTEGER(IntKi), PARAMETER :: WkAxsYT5D6 = 645 + INTEGER(IntKi), PARAMETER :: WkAxsYT5D7 = 646 + INTEGER(IntKi), PARAMETER :: WkAxsYT5D8 = 647 + INTEGER(IntKi), PARAMETER :: WkAxsYT5D9 = 648 + INTEGER(IntKi), PARAMETER :: WkAxsYT6D1 = 649 + INTEGER(IntKi), PARAMETER :: WkAxsYT6D2 = 650 + INTEGER(IntKi), PARAMETER :: WkAxsYT6D3 = 651 + INTEGER(IntKi), PARAMETER :: WkAxsYT6D4 = 652 + INTEGER(IntKi), PARAMETER :: WkAxsYT6D5 = 653 + INTEGER(IntKi), PARAMETER :: WkAxsYT6D6 = 654 + INTEGER(IntKi), PARAMETER :: WkAxsYT6D7 = 655 + INTEGER(IntKi), PARAMETER :: WkAxsYT6D8 = 656 + INTEGER(IntKi), PARAMETER :: WkAxsYT6D9 = 657 + INTEGER(IntKi), PARAMETER :: WkAxsYT7D1 = 658 + INTEGER(IntKi), PARAMETER :: WkAxsYT7D2 = 659 + INTEGER(IntKi), PARAMETER :: WkAxsYT7D3 = 660 + INTEGER(IntKi), PARAMETER :: WkAxsYT7D4 = 661 + INTEGER(IntKi), PARAMETER :: WkAxsYT7D5 = 662 + INTEGER(IntKi), PARAMETER :: WkAxsYT7D6 = 663 + INTEGER(IntKi), PARAMETER :: WkAxsYT7D7 = 664 + INTEGER(IntKi), PARAMETER :: WkAxsYT7D8 = 665 + INTEGER(IntKi), PARAMETER :: WkAxsYT7D9 = 666 + INTEGER(IntKi), PARAMETER :: WkAxsYT8D1 = 667 + INTEGER(IntKi), PARAMETER :: WkAxsYT8D2 = 668 + INTEGER(IntKi), PARAMETER :: WkAxsYT8D3 = 669 + INTEGER(IntKi), PARAMETER :: WkAxsYT8D4 = 670 + INTEGER(IntKi), PARAMETER :: WkAxsYT8D5 = 671 + INTEGER(IntKi), PARAMETER :: WkAxsYT8D6 = 672 + INTEGER(IntKi), PARAMETER :: WkAxsYT8D7 = 673 + INTEGER(IntKi), PARAMETER :: WkAxsYT8D8 = 674 + INTEGER(IntKi), PARAMETER :: WkAxsYT8D9 = 675 + INTEGER(IntKi), PARAMETER :: WkAxsYT9D1 = 676 + INTEGER(IntKi), PARAMETER :: WkAxsYT9D2 = 677 + INTEGER(IntKi), PARAMETER :: WkAxsYT9D3 = 678 + INTEGER(IntKi), PARAMETER :: WkAxsYT9D4 = 679 + INTEGER(IntKi), PARAMETER :: WkAxsYT9D5 = 680 + INTEGER(IntKi), PARAMETER :: WkAxsYT9D6 = 681 + INTEGER(IntKi), PARAMETER :: WkAxsYT9D7 = 682 + INTEGER(IntKi), PARAMETER :: WkAxsYT9D8 = 683 + INTEGER(IntKi), PARAMETER :: WkAxsYT9D9 = 684 + INTEGER(IntKi), PARAMETER :: WkAxsZT1D1 = 685 + INTEGER(IntKi), PARAMETER :: WkAxsZT1D2 = 686 + INTEGER(IntKi), PARAMETER :: WkAxsZT1D3 = 687 + INTEGER(IntKi), PARAMETER :: WkAxsZT1D4 = 688 + INTEGER(IntKi), PARAMETER :: WkAxsZT1D5 = 689 + INTEGER(IntKi), PARAMETER :: WkAxsZT1D6 = 690 + INTEGER(IntKi), PARAMETER :: WkAxsZT1D7 = 691 + INTEGER(IntKi), PARAMETER :: WkAxsZT1D8 = 692 + INTEGER(IntKi), PARAMETER :: WkAxsZT1D9 = 693 + INTEGER(IntKi), PARAMETER :: WkAxsZT2D1 = 694 + INTEGER(IntKi), PARAMETER :: WkAxsZT2D2 = 695 + INTEGER(IntKi), PARAMETER :: WkAxsZT2D3 = 696 + INTEGER(IntKi), PARAMETER :: WkAxsZT2D4 = 697 + INTEGER(IntKi), PARAMETER :: WkAxsZT2D5 = 698 + INTEGER(IntKi), PARAMETER :: WkAxsZT2D6 = 699 + INTEGER(IntKi), PARAMETER :: WkAxsZT2D7 = 700 + INTEGER(IntKi), PARAMETER :: WkAxsZT2D8 = 701 + INTEGER(IntKi), PARAMETER :: WkAxsZT2D9 = 702 + INTEGER(IntKi), PARAMETER :: WkAxsZT3D1 = 703 + INTEGER(IntKi), PARAMETER :: WkAxsZT3D2 = 704 + INTEGER(IntKi), PARAMETER :: WkAxsZT3D3 = 705 + INTEGER(IntKi), PARAMETER :: WkAxsZT3D4 = 706 + INTEGER(IntKi), PARAMETER :: WkAxsZT3D5 = 707 + INTEGER(IntKi), PARAMETER :: WkAxsZT3D6 = 708 + INTEGER(IntKi), PARAMETER :: WkAxsZT3D7 = 709 + INTEGER(IntKi), PARAMETER :: WkAxsZT3D8 = 710 + INTEGER(IntKi), PARAMETER :: WkAxsZT3D9 = 711 + INTEGER(IntKi), PARAMETER :: WkAxsZT4D1 = 712 + INTEGER(IntKi), PARAMETER :: WkAxsZT4D2 = 713 + INTEGER(IntKi), PARAMETER :: WkAxsZT4D3 = 714 + INTEGER(IntKi), PARAMETER :: WkAxsZT4D4 = 715 + INTEGER(IntKi), PARAMETER :: WkAxsZT4D5 = 716 + INTEGER(IntKi), PARAMETER :: WkAxsZT4D6 = 717 + INTEGER(IntKi), PARAMETER :: WkAxsZT4D7 = 718 + INTEGER(IntKi), PARAMETER :: WkAxsZT4D8 = 719 + INTEGER(IntKi), PARAMETER :: WkAxsZT4D9 = 720 + INTEGER(IntKi), PARAMETER :: WkAxsZT5D1 = 721 + INTEGER(IntKi), PARAMETER :: WkAxsZT5D2 = 722 + INTEGER(IntKi), PARAMETER :: WkAxsZT5D3 = 723 + INTEGER(IntKi), PARAMETER :: WkAxsZT5D4 = 724 + INTEGER(IntKi), PARAMETER :: WkAxsZT5D5 = 725 + INTEGER(IntKi), PARAMETER :: WkAxsZT5D6 = 726 + INTEGER(IntKi), PARAMETER :: WkAxsZT5D7 = 727 + INTEGER(IntKi), PARAMETER :: WkAxsZT5D8 = 728 + INTEGER(IntKi), PARAMETER :: WkAxsZT5D9 = 729 + INTEGER(IntKi), PARAMETER :: WkAxsZT6D1 = 730 + INTEGER(IntKi), PARAMETER :: WkAxsZT6D2 = 731 + INTEGER(IntKi), PARAMETER :: WkAxsZT6D3 = 732 + INTEGER(IntKi), PARAMETER :: WkAxsZT6D4 = 733 + INTEGER(IntKi), PARAMETER :: WkAxsZT6D5 = 734 + INTEGER(IntKi), PARAMETER :: WkAxsZT6D6 = 735 + INTEGER(IntKi), PARAMETER :: WkAxsZT6D7 = 736 + INTEGER(IntKi), PARAMETER :: WkAxsZT6D8 = 737 + INTEGER(IntKi), PARAMETER :: WkAxsZT6D9 = 738 + INTEGER(IntKi), PARAMETER :: WkAxsZT7D1 = 739 + INTEGER(IntKi), PARAMETER :: WkAxsZT7D2 = 740 + INTEGER(IntKi), PARAMETER :: WkAxsZT7D3 = 741 + INTEGER(IntKi), PARAMETER :: WkAxsZT7D4 = 742 + INTEGER(IntKi), PARAMETER :: WkAxsZT7D5 = 743 + INTEGER(IntKi), PARAMETER :: WkAxsZT7D6 = 744 + INTEGER(IntKi), PARAMETER :: WkAxsZT7D7 = 745 + INTEGER(IntKi), PARAMETER :: WkAxsZT7D8 = 746 + INTEGER(IntKi), PARAMETER :: WkAxsZT7D9 = 747 + INTEGER(IntKi), PARAMETER :: WkAxsZT8D1 = 748 + INTEGER(IntKi), PARAMETER :: WkAxsZT8D2 = 749 + INTEGER(IntKi), PARAMETER :: WkAxsZT8D3 = 750 + INTEGER(IntKi), PARAMETER :: WkAxsZT8D4 = 751 + INTEGER(IntKi), PARAMETER :: WkAxsZT8D5 = 752 + INTEGER(IntKi), PARAMETER :: WkAxsZT8D6 = 753 + INTEGER(IntKi), PARAMETER :: WkAxsZT8D7 = 754 + INTEGER(IntKi), PARAMETER :: WkAxsZT8D8 = 755 + INTEGER(IntKi), PARAMETER :: WkAxsZT8D9 = 756 + INTEGER(IntKi), PARAMETER :: WkAxsZT9D1 = 757 + INTEGER(IntKi), PARAMETER :: WkAxsZT9D2 = 758 + INTEGER(IntKi), PARAMETER :: WkAxsZT9D3 = 759 + INTEGER(IntKi), PARAMETER :: WkAxsZT9D4 = 760 + INTEGER(IntKi), PARAMETER :: WkAxsZT9D5 = 761 + INTEGER(IntKi), PARAMETER :: WkAxsZT9D6 = 762 + INTEGER(IntKi), PARAMETER :: WkAxsZT9D7 = 763 + INTEGER(IntKi), PARAMETER :: WkAxsZT9D8 = 764 + INTEGER(IntKi), PARAMETER :: WkAxsZT9D9 = 765 + + + ! Center position of the wake centerline: + + INTEGER(IntKi), PARAMETER :: WkPosXT1D1 = 766 + INTEGER(IntKi), PARAMETER :: WkPosXT1D2 = 767 + INTEGER(IntKi), PARAMETER :: WkPosXT1D3 = 768 + INTEGER(IntKi), PARAMETER :: WkPosXT1D4 = 769 + INTEGER(IntKi), PARAMETER :: WkPosXT1D5 = 770 + INTEGER(IntKi), PARAMETER :: WkPosXT1D6 = 771 + INTEGER(IntKi), PARAMETER :: WkPosXT1D7 = 772 + INTEGER(IntKi), PARAMETER :: WkPosXT1D8 = 773 + INTEGER(IntKi), PARAMETER :: WkPosXT1D9 = 774 + INTEGER(IntKi), PARAMETER :: WkPosXT2D1 = 775 + INTEGER(IntKi), PARAMETER :: WkPosXT2D2 = 776 + INTEGER(IntKi), PARAMETER :: WkPosXT2D3 = 777 + INTEGER(IntKi), PARAMETER :: WkPosXT2D4 = 778 + INTEGER(IntKi), PARAMETER :: WkPosXT2D5 = 779 + INTEGER(IntKi), PARAMETER :: WkPosXT2D6 = 780 + INTEGER(IntKi), PARAMETER :: WkPosXT2D7 = 781 + INTEGER(IntKi), PARAMETER :: WkPosXT2D8 = 782 + INTEGER(IntKi), PARAMETER :: WkPosXT2D9 = 783 + INTEGER(IntKi), PARAMETER :: WkPosXT3D1 = 784 + INTEGER(IntKi), PARAMETER :: WkPosXT3D2 = 785 + INTEGER(IntKi), PARAMETER :: WkPosXT3D3 = 786 + INTEGER(IntKi), PARAMETER :: WkPosXT3D4 = 787 + INTEGER(IntKi), PARAMETER :: WkPosXT3D5 = 788 + INTEGER(IntKi), PARAMETER :: WkPosXT3D6 = 789 + INTEGER(IntKi), PARAMETER :: WkPosXT3D7 = 790 + INTEGER(IntKi), PARAMETER :: WkPosXT3D8 = 791 + INTEGER(IntKi), PARAMETER :: WkPosXT3D9 = 792 + INTEGER(IntKi), PARAMETER :: WkPosXT4D1 = 793 + INTEGER(IntKi), PARAMETER :: WkPosXT4D2 = 794 + INTEGER(IntKi), PARAMETER :: WkPosXT4D3 = 795 + INTEGER(IntKi), PARAMETER :: WkPosXT4D4 = 796 + INTEGER(IntKi), PARAMETER :: WkPosXT4D5 = 797 + INTEGER(IntKi), PARAMETER :: WkPosXT4D6 = 798 + INTEGER(IntKi), PARAMETER :: WkPosXT4D7 = 799 + INTEGER(IntKi), PARAMETER :: WkPosXT4D8 = 800 + INTEGER(IntKi), PARAMETER :: WkPosXT4D9 = 801 + INTEGER(IntKi), PARAMETER :: WkPosXT5D1 = 802 + INTEGER(IntKi), PARAMETER :: WkPosXT5D2 = 803 + INTEGER(IntKi), PARAMETER :: WkPosXT5D3 = 804 + INTEGER(IntKi), PARAMETER :: WkPosXT5D4 = 805 + INTEGER(IntKi), PARAMETER :: WkPosXT5D5 = 806 + INTEGER(IntKi), PARAMETER :: WkPosXT5D6 = 807 + INTEGER(IntKi), PARAMETER :: WkPosXT5D7 = 808 + INTEGER(IntKi), PARAMETER :: WkPosXT5D8 = 809 + INTEGER(IntKi), PARAMETER :: WkPosXT5D9 = 810 + INTEGER(IntKi), PARAMETER :: WkPosXT6D1 = 811 + INTEGER(IntKi), PARAMETER :: WkPosXT6D2 = 812 + INTEGER(IntKi), PARAMETER :: WkPosXT6D3 = 813 + INTEGER(IntKi), PARAMETER :: WkPosXT6D4 = 814 + INTEGER(IntKi), PARAMETER :: WkPosXT6D5 = 815 + INTEGER(IntKi), PARAMETER :: WkPosXT6D6 = 816 + INTEGER(IntKi), PARAMETER :: WkPosXT6D7 = 817 + INTEGER(IntKi), PARAMETER :: WkPosXT6D8 = 818 + INTEGER(IntKi), PARAMETER :: WkPosXT6D9 = 819 + INTEGER(IntKi), PARAMETER :: WkPosXT7D1 = 820 + INTEGER(IntKi), PARAMETER :: WkPosXT7D2 = 821 + INTEGER(IntKi), PARAMETER :: WkPosXT7D3 = 822 + INTEGER(IntKi), PARAMETER :: WkPosXT7D4 = 823 + INTEGER(IntKi), PARAMETER :: WkPosXT7D5 = 824 + INTEGER(IntKi), PARAMETER :: WkPosXT7D6 = 825 + INTEGER(IntKi), PARAMETER :: WkPosXT7D7 = 826 + INTEGER(IntKi), PARAMETER :: WkPosXT7D8 = 827 + INTEGER(IntKi), PARAMETER :: WkPosXT7D9 = 828 + INTEGER(IntKi), PARAMETER :: WkPosXT8D1 = 829 + INTEGER(IntKi), PARAMETER :: WkPosXT8D2 = 830 + INTEGER(IntKi), PARAMETER :: WkPosXT8D3 = 831 + INTEGER(IntKi), PARAMETER :: WkPosXT8D4 = 832 + INTEGER(IntKi), PARAMETER :: WkPosXT8D5 = 833 + INTEGER(IntKi), PARAMETER :: WkPosXT8D6 = 834 + INTEGER(IntKi), PARAMETER :: WkPosXT8D7 = 835 + INTEGER(IntKi), PARAMETER :: WkPosXT8D8 = 836 + INTEGER(IntKi), PARAMETER :: WkPosXT8D9 = 837 + INTEGER(IntKi), PARAMETER :: WkPosXT9D1 = 838 + INTEGER(IntKi), PARAMETER :: WkPosXT9D2 = 839 + INTEGER(IntKi), PARAMETER :: WkPosXT9D3 = 840 + INTEGER(IntKi), PARAMETER :: WkPosXT9D4 = 841 + INTEGER(IntKi), PARAMETER :: WkPosXT9D5 = 842 + INTEGER(IntKi), PARAMETER :: WkPosXT9D6 = 843 + INTEGER(IntKi), PARAMETER :: WkPosXT9D7 = 844 + INTEGER(IntKi), PARAMETER :: WkPosXT9D8 = 845 + INTEGER(IntKi), PARAMETER :: WkPosXT9D9 = 846 + INTEGER(IntKi), PARAMETER :: WkPosYT1D1 = 847 + INTEGER(IntKi), PARAMETER :: WkPosYT1D2 = 848 + INTEGER(IntKi), PARAMETER :: WkPosYT1D3 = 849 + INTEGER(IntKi), PARAMETER :: WkPosYT1D4 = 850 + INTEGER(IntKi), PARAMETER :: WkPosYT1D5 = 851 + INTEGER(IntKi), PARAMETER :: WkPosYT1D6 = 852 + INTEGER(IntKi), PARAMETER :: WkPosYT1D7 = 853 + INTEGER(IntKi), PARAMETER :: WkPosYT1D8 = 854 + INTEGER(IntKi), PARAMETER :: WkPosYT1D9 = 855 + INTEGER(IntKi), PARAMETER :: WkPosYT2D1 = 856 + INTEGER(IntKi), PARAMETER :: WkPosYT2D2 = 857 + INTEGER(IntKi), PARAMETER :: WkPosYT2D3 = 858 + INTEGER(IntKi), PARAMETER :: WkPosYT2D4 = 859 + INTEGER(IntKi), PARAMETER :: WkPosYT2D5 = 860 + INTEGER(IntKi), PARAMETER :: WkPosYT2D6 = 861 + INTEGER(IntKi), PARAMETER :: WkPosYT2D7 = 862 + INTEGER(IntKi), PARAMETER :: WkPosYT2D8 = 863 + INTEGER(IntKi), PARAMETER :: WkPosYT2D9 = 864 + INTEGER(IntKi), PARAMETER :: WkPosYT3D1 = 865 + INTEGER(IntKi), PARAMETER :: WkPosYT3D2 = 866 + INTEGER(IntKi), PARAMETER :: WkPosYT3D3 = 867 + INTEGER(IntKi), PARAMETER :: WkPosYT3D4 = 868 + INTEGER(IntKi), PARAMETER :: WkPosYT3D5 = 869 + INTEGER(IntKi), PARAMETER :: WkPosYT3D6 = 870 + INTEGER(IntKi), PARAMETER :: WkPosYT3D7 = 871 + INTEGER(IntKi), PARAMETER :: WkPosYT3D8 = 872 + INTEGER(IntKi), PARAMETER :: WkPosYT3D9 = 873 + INTEGER(IntKi), PARAMETER :: WkPosYT4D1 = 874 + INTEGER(IntKi), PARAMETER :: WkPosYT4D2 = 875 + INTEGER(IntKi), PARAMETER :: WkPosYT4D3 = 876 + INTEGER(IntKi), PARAMETER :: WkPosYT4D4 = 877 + INTEGER(IntKi), PARAMETER :: WkPosYT4D5 = 878 + INTEGER(IntKi), PARAMETER :: WkPosYT4D6 = 879 + INTEGER(IntKi), PARAMETER :: WkPosYT4D7 = 880 + INTEGER(IntKi), PARAMETER :: WkPosYT4D8 = 881 + INTEGER(IntKi), PARAMETER :: WkPosYT4D9 = 882 + INTEGER(IntKi), PARAMETER :: WkPosYT5D1 = 883 + INTEGER(IntKi), PARAMETER :: WkPosYT5D2 = 884 + INTEGER(IntKi), PARAMETER :: WkPosYT5D3 = 885 + INTEGER(IntKi), PARAMETER :: WkPosYT5D4 = 886 + INTEGER(IntKi), PARAMETER :: WkPosYT5D5 = 887 + INTEGER(IntKi), PARAMETER :: WkPosYT5D6 = 888 + INTEGER(IntKi), PARAMETER :: WkPosYT5D7 = 889 + INTEGER(IntKi), PARAMETER :: WkPosYT5D8 = 890 + INTEGER(IntKi), PARAMETER :: WkPosYT5D9 = 891 + INTEGER(IntKi), PARAMETER :: WkPosYT6D1 = 892 + INTEGER(IntKi), PARAMETER :: WkPosYT6D2 = 893 + INTEGER(IntKi), PARAMETER :: WkPosYT6D3 = 894 + INTEGER(IntKi), PARAMETER :: WkPosYT6D4 = 895 + INTEGER(IntKi), PARAMETER :: WkPosYT6D5 = 896 + INTEGER(IntKi), PARAMETER :: WkPosYT6D6 = 897 + INTEGER(IntKi), PARAMETER :: WkPosYT6D7 = 898 + INTEGER(IntKi), PARAMETER :: WkPosYT6D8 = 899 + INTEGER(IntKi), PARAMETER :: WkPosYT6D9 = 900 + INTEGER(IntKi), PARAMETER :: WkPosYT7D1 = 901 + INTEGER(IntKi), PARAMETER :: WkPosYT7D2 = 902 + INTEGER(IntKi), PARAMETER :: WkPosYT7D3 = 903 + INTEGER(IntKi), PARAMETER :: WkPosYT7D4 = 904 + INTEGER(IntKi), PARAMETER :: WkPosYT7D5 = 905 + INTEGER(IntKi), PARAMETER :: WkPosYT7D6 = 906 + INTEGER(IntKi), PARAMETER :: WkPosYT7D7 = 907 + INTEGER(IntKi), PARAMETER :: WkPosYT7D8 = 908 + INTEGER(IntKi), PARAMETER :: WkPosYT7D9 = 909 + INTEGER(IntKi), PARAMETER :: WkPosYT8D1 = 910 + INTEGER(IntKi), PARAMETER :: WkPosYT8D2 = 911 + INTEGER(IntKi), PARAMETER :: WkPosYT8D3 = 912 + INTEGER(IntKi), PARAMETER :: WkPosYT8D4 = 913 + INTEGER(IntKi), PARAMETER :: WkPosYT8D5 = 914 + INTEGER(IntKi), PARAMETER :: WkPosYT8D6 = 915 + INTEGER(IntKi), PARAMETER :: WkPosYT8D7 = 916 + INTEGER(IntKi), PARAMETER :: WkPosYT8D8 = 917 + INTEGER(IntKi), PARAMETER :: WkPosYT8D9 = 918 + INTEGER(IntKi), PARAMETER :: WkPosYT9D1 = 919 + INTEGER(IntKi), PARAMETER :: WkPosYT9D2 = 920 + INTEGER(IntKi), PARAMETER :: WkPosYT9D3 = 921 + INTEGER(IntKi), PARAMETER :: WkPosYT9D4 = 922 + INTEGER(IntKi), PARAMETER :: WkPosYT9D5 = 923 + INTEGER(IntKi), PARAMETER :: WkPosYT9D6 = 924 + INTEGER(IntKi), PARAMETER :: WkPosYT9D7 = 925 + INTEGER(IntKi), PARAMETER :: WkPosYT9D8 = 926 + INTEGER(IntKi), PARAMETER :: WkPosYT9D9 = 927 + INTEGER(IntKi), PARAMETER :: WkPosZT1D1 = 928 + INTEGER(IntKi), PARAMETER :: WkPosZT1D2 = 929 + INTEGER(IntKi), PARAMETER :: WkPosZT1D3 = 930 + INTEGER(IntKi), PARAMETER :: WkPosZT1D4 = 931 + INTEGER(IntKi), PARAMETER :: WkPosZT1D5 = 932 + INTEGER(IntKi), PARAMETER :: WkPosZT1D6 = 933 + INTEGER(IntKi), PARAMETER :: WkPosZT1D7 = 934 + INTEGER(IntKi), PARAMETER :: WkPosZT1D8 = 935 + INTEGER(IntKi), PARAMETER :: WkPosZT1D9 = 936 + INTEGER(IntKi), PARAMETER :: WkPosZT2D1 = 937 + INTEGER(IntKi), PARAMETER :: WkPosZT2D2 = 938 + INTEGER(IntKi), PARAMETER :: WkPosZT2D3 = 939 + INTEGER(IntKi), PARAMETER :: WkPosZT2D4 = 940 + INTEGER(IntKi), PARAMETER :: WkPosZT2D5 = 941 + INTEGER(IntKi), PARAMETER :: WkPosZT2D6 = 942 + INTEGER(IntKi), PARAMETER :: WkPosZT2D7 = 943 + INTEGER(IntKi), PARAMETER :: WkPosZT2D8 = 944 + INTEGER(IntKi), PARAMETER :: WkPosZT2D9 = 945 + INTEGER(IntKi), PARAMETER :: WkPosZT3D1 = 946 + INTEGER(IntKi), PARAMETER :: WkPosZT3D2 = 947 + INTEGER(IntKi), PARAMETER :: WkPosZT3D3 = 948 + INTEGER(IntKi), PARAMETER :: WkPosZT3D4 = 949 + INTEGER(IntKi), PARAMETER :: WkPosZT3D5 = 950 + INTEGER(IntKi), PARAMETER :: WkPosZT3D6 = 951 + INTEGER(IntKi), PARAMETER :: WkPosZT3D7 = 952 + INTEGER(IntKi), PARAMETER :: WkPosZT3D8 = 953 + INTEGER(IntKi), PARAMETER :: WkPosZT3D9 = 954 + INTEGER(IntKi), PARAMETER :: WkPosZT4D1 = 955 + INTEGER(IntKi), PARAMETER :: WkPosZT4D2 = 956 + INTEGER(IntKi), PARAMETER :: WkPosZT4D3 = 957 + INTEGER(IntKi), PARAMETER :: WkPosZT4D4 = 958 + INTEGER(IntKi), PARAMETER :: WkPosZT4D5 = 959 + INTEGER(IntKi), PARAMETER :: WkPosZT4D6 = 960 + INTEGER(IntKi), PARAMETER :: WkPosZT4D7 = 961 + INTEGER(IntKi), PARAMETER :: WkPosZT4D8 = 962 + INTEGER(IntKi), PARAMETER :: WkPosZT4D9 = 963 + INTEGER(IntKi), PARAMETER :: WkPosZT5D1 = 964 + INTEGER(IntKi), PARAMETER :: WkPosZT5D2 = 965 + INTEGER(IntKi), PARAMETER :: WkPosZT5D3 = 966 + INTEGER(IntKi), PARAMETER :: WkPosZT5D4 = 967 + INTEGER(IntKi), PARAMETER :: WkPosZT5D5 = 968 + INTEGER(IntKi), PARAMETER :: WkPosZT5D6 = 969 + INTEGER(IntKi), PARAMETER :: WkPosZT5D7 = 970 + INTEGER(IntKi), PARAMETER :: WkPosZT5D8 = 971 + INTEGER(IntKi), PARAMETER :: WkPosZT5D9 = 972 + INTEGER(IntKi), PARAMETER :: WkPosZT6D1 = 973 + INTEGER(IntKi), PARAMETER :: WkPosZT6D2 = 974 + INTEGER(IntKi), PARAMETER :: WkPosZT6D3 = 975 + INTEGER(IntKi), PARAMETER :: WkPosZT6D4 = 976 + INTEGER(IntKi), PARAMETER :: WkPosZT6D5 = 977 + INTEGER(IntKi), PARAMETER :: WkPosZT6D6 = 978 + INTEGER(IntKi), PARAMETER :: WkPosZT6D7 = 979 + INTEGER(IntKi), PARAMETER :: WkPosZT6D8 = 980 + INTEGER(IntKi), PARAMETER :: WkPosZT6D9 = 981 + INTEGER(IntKi), PARAMETER :: WkPosZT7D1 = 982 + INTEGER(IntKi), PARAMETER :: WkPosZT7D2 = 983 + INTEGER(IntKi), PARAMETER :: WkPosZT7D3 = 984 + INTEGER(IntKi), PARAMETER :: WkPosZT7D4 = 985 + INTEGER(IntKi), PARAMETER :: WkPosZT7D5 = 986 + INTEGER(IntKi), PARAMETER :: WkPosZT7D6 = 987 + INTEGER(IntKi), PARAMETER :: WkPosZT7D7 = 988 + INTEGER(IntKi), PARAMETER :: WkPosZT7D8 = 989 + INTEGER(IntKi), PARAMETER :: WkPosZT7D9 = 990 + INTEGER(IntKi), PARAMETER :: WkPosZT8D1 = 991 + INTEGER(IntKi), PARAMETER :: WkPosZT8D2 = 992 + INTEGER(IntKi), PARAMETER :: WkPosZT8D3 = 993 + INTEGER(IntKi), PARAMETER :: WkPosZT8D4 = 994 + INTEGER(IntKi), PARAMETER :: WkPosZT8D5 = 995 + INTEGER(IntKi), PARAMETER :: WkPosZT8D6 = 996 + INTEGER(IntKi), PARAMETER :: WkPosZT8D7 = 997 + INTEGER(IntKi), PARAMETER :: WkPosZT8D8 = 998 + INTEGER(IntKi), PARAMETER :: WkPosZT8D9 = 999 + INTEGER(IntKi), PARAMETER :: WkPosZT9D1 = 1000 + INTEGER(IntKi), PARAMETER :: WkPosZT9D2 = 1001 + INTEGER(IntKi), PARAMETER :: WkPosZT9D3 = 1002 + INTEGER(IntKi), PARAMETER :: WkPosZT9D4 = 1003 + INTEGER(IntKi), PARAMETER :: WkPosZT9D5 = 1004 + INTEGER(IntKi), PARAMETER :: WkPosZT9D6 = 1005 + INTEGER(IntKi), PARAMETER :: WkPosZT9D7 = 1006 + INTEGER(IntKi), PARAMETER :: WkPosZT9D8 = 1007 + INTEGER(IntKi), PARAMETER :: WkPosZT9D9 = 1008 + + + ! Advection, deflection, and meandering velocity: + + INTEGER(IntKi), PARAMETER :: WkVelXT1D1 = 1009 + INTEGER(IntKi), PARAMETER :: WkVelXT1D2 = 1010 + INTEGER(IntKi), PARAMETER :: WkVelXT1D3 = 1011 + INTEGER(IntKi), PARAMETER :: WkVelXT1D4 = 1012 + INTEGER(IntKi), PARAMETER :: WkVelXT1D5 = 1013 + INTEGER(IntKi), PARAMETER :: WkVelXT1D6 = 1014 + INTEGER(IntKi), PARAMETER :: WkVelXT1D7 = 1015 + INTEGER(IntKi), PARAMETER :: WkVelXT1D8 = 1016 + INTEGER(IntKi), PARAMETER :: WkVelXT1D9 = 1017 + INTEGER(IntKi), PARAMETER :: WkVelXT2D1 = 1018 + INTEGER(IntKi), PARAMETER :: WkVelXT2D2 = 1019 + INTEGER(IntKi), PARAMETER :: WkVelXT2D3 = 1020 + INTEGER(IntKi), PARAMETER :: WkVelXT2D4 = 1021 + INTEGER(IntKi), PARAMETER :: WkVelXT2D5 = 1022 + INTEGER(IntKi), PARAMETER :: WkVelXT2D6 = 1023 + INTEGER(IntKi), PARAMETER :: WkVelXT2D7 = 1024 + INTEGER(IntKi), PARAMETER :: WkVelXT2D8 = 1025 + INTEGER(IntKi), PARAMETER :: WkVelXT2D9 = 1026 + INTEGER(IntKi), PARAMETER :: WkVelXT3D1 = 1027 + INTEGER(IntKi), PARAMETER :: WkVelXT3D2 = 1028 + INTEGER(IntKi), PARAMETER :: WkVelXT3D3 = 1029 + INTEGER(IntKi), PARAMETER :: WkVelXT3D4 = 1030 + INTEGER(IntKi), PARAMETER :: WkVelXT3D5 = 1031 + INTEGER(IntKi), PARAMETER :: WkVelXT3D6 = 1032 + INTEGER(IntKi), PARAMETER :: WkVelXT3D7 = 1033 + INTEGER(IntKi), PARAMETER :: WkVelXT3D8 = 1034 + INTEGER(IntKi), PARAMETER :: WkVelXT3D9 = 1035 + INTEGER(IntKi), PARAMETER :: WkVelXT4D1 = 1036 + INTEGER(IntKi), PARAMETER :: WkVelXT4D2 = 1037 + INTEGER(IntKi), PARAMETER :: WkVelXT4D3 = 1038 + INTEGER(IntKi), PARAMETER :: WkVelXT4D4 = 1039 + INTEGER(IntKi), PARAMETER :: WkVelXT4D5 = 1040 + INTEGER(IntKi), PARAMETER :: WkVelXT4D6 = 1041 + INTEGER(IntKi), PARAMETER :: WkVelXT4D7 = 1042 + INTEGER(IntKi), PARAMETER :: WkVelXT4D8 = 1043 + INTEGER(IntKi), PARAMETER :: WkVelXT4D9 = 1044 + INTEGER(IntKi), PARAMETER :: WkVelXT5D1 = 1045 + INTEGER(IntKi), PARAMETER :: WkVelXT5D2 = 1046 + INTEGER(IntKi), PARAMETER :: WkVelXT5D3 = 1047 + INTEGER(IntKi), PARAMETER :: WkVelXT5D4 = 1048 + INTEGER(IntKi), PARAMETER :: WkVelXT5D5 = 1049 + INTEGER(IntKi), PARAMETER :: WkVelXT5D6 = 1050 + INTEGER(IntKi), PARAMETER :: WkVelXT5D7 = 1051 + INTEGER(IntKi), PARAMETER :: WkVelXT5D8 = 1052 + INTEGER(IntKi), PARAMETER :: WkVelXT5D9 = 1053 + INTEGER(IntKi), PARAMETER :: WkVelXT6D1 = 1054 + INTEGER(IntKi), PARAMETER :: WkVelXT6D2 = 1055 + INTEGER(IntKi), PARAMETER :: WkVelXT6D3 = 1056 + INTEGER(IntKi), PARAMETER :: WkVelXT6D4 = 1057 + INTEGER(IntKi), PARAMETER :: WkVelXT6D5 = 1058 + INTEGER(IntKi), PARAMETER :: WkVelXT6D6 = 1059 + INTEGER(IntKi), PARAMETER :: WkVelXT6D7 = 1060 + INTEGER(IntKi), PARAMETER :: WkVelXT6D8 = 1061 + INTEGER(IntKi), PARAMETER :: WkVelXT6D9 = 1062 + INTEGER(IntKi), PARAMETER :: WkVelXT7D1 = 1063 + INTEGER(IntKi), PARAMETER :: WkVelXT7D2 = 1064 + INTEGER(IntKi), PARAMETER :: WkVelXT7D3 = 1065 + INTEGER(IntKi), PARAMETER :: WkVelXT7D4 = 1066 + INTEGER(IntKi), PARAMETER :: WkVelXT7D5 = 1067 + INTEGER(IntKi), PARAMETER :: WkVelXT7D6 = 1068 + INTEGER(IntKi), PARAMETER :: WkVelXT7D7 = 1069 + INTEGER(IntKi), PARAMETER :: WkVelXT7D8 = 1070 + INTEGER(IntKi), PARAMETER :: WkVelXT7D9 = 1071 + INTEGER(IntKi), PARAMETER :: WkVelXT8D1 = 1072 + INTEGER(IntKi), PARAMETER :: WkVelXT8D2 = 1073 + INTEGER(IntKi), PARAMETER :: WkVelXT8D3 = 1074 + INTEGER(IntKi), PARAMETER :: WkVelXT8D4 = 1075 + INTEGER(IntKi), PARAMETER :: WkVelXT8D5 = 1076 + INTEGER(IntKi), PARAMETER :: WkVelXT8D6 = 1077 + INTEGER(IntKi), PARAMETER :: WkVelXT8D7 = 1078 + INTEGER(IntKi), PARAMETER :: WkVelXT8D8 = 1079 + INTEGER(IntKi), PARAMETER :: WkVelXT8D9 = 1080 + INTEGER(IntKi), PARAMETER :: WkVelXT9D1 = 1081 + INTEGER(IntKi), PARAMETER :: WkVelXT9D2 = 1082 + INTEGER(IntKi), PARAMETER :: WkVelXT9D3 = 1083 + INTEGER(IntKi), PARAMETER :: WkVelXT9D4 = 1084 + INTEGER(IntKi), PARAMETER :: WkVelXT9D5 = 1085 + INTEGER(IntKi), PARAMETER :: WkVelXT9D6 = 1086 + INTEGER(IntKi), PARAMETER :: WkVelXT9D7 = 1087 + INTEGER(IntKi), PARAMETER :: WkVelXT9D8 = 1088 + INTEGER(IntKi), PARAMETER :: WkVelXT9D9 = 1089 + INTEGER(IntKi), PARAMETER :: WkVelYT1D1 = 1090 + INTEGER(IntKi), PARAMETER :: WkVelYT1D2 = 1091 + INTEGER(IntKi), PARAMETER :: WkVelYT1D3 = 1092 + INTEGER(IntKi), PARAMETER :: WkVelYT1D4 = 1093 + INTEGER(IntKi), PARAMETER :: WkVelYT1D5 = 1094 + INTEGER(IntKi), PARAMETER :: WkVelYT1D6 = 1095 + INTEGER(IntKi), PARAMETER :: WkVelYT1D7 = 1096 + INTEGER(IntKi), PARAMETER :: WkVelYT1D8 = 1097 + INTEGER(IntKi), PARAMETER :: WkVelYT1D9 = 1098 + INTEGER(IntKi), PARAMETER :: WkVelYT2D1 = 1099 + INTEGER(IntKi), PARAMETER :: WkVelYT2D2 = 1100 + INTEGER(IntKi), PARAMETER :: WkVelYT2D3 = 1101 + INTEGER(IntKi), PARAMETER :: WkVelYT2D4 = 1102 + INTEGER(IntKi), PARAMETER :: WkVelYT2D5 = 1103 + INTEGER(IntKi), PARAMETER :: WkVelYT2D6 = 1104 + INTEGER(IntKi), PARAMETER :: WkVelYT2D7 = 1105 + INTEGER(IntKi), PARAMETER :: WkVelYT2D8 = 1106 + INTEGER(IntKi), PARAMETER :: WkVelYT2D9 = 1107 + INTEGER(IntKi), PARAMETER :: WkVelYT3D1 = 1108 + INTEGER(IntKi), PARAMETER :: WkVelYT3D2 = 1109 + INTEGER(IntKi), PARAMETER :: WkVelYT3D3 = 1110 + INTEGER(IntKi), PARAMETER :: WkVelYT3D4 = 1111 + INTEGER(IntKi), PARAMETER :: WkVelYT3D5 = 1112 + INTEGER(IntKi), PARAMETER :: WkVelYT3D6 = 1113 + INTEGER(IntKi), PARAMETER :: WkVelYT3D7 = 1114 + INTEGER(IntKi), PARAMETER :: WkVelYT3D8 = 1115 + INTEGER(IntKi), PARAMETER :: WkVelYT3D9 = 1116 + INTEGER(IntKi), PARAMETER :: WkVelYT4D1 = 1117 + INTEGER(IntKi), PARAMETER :: WkVelYT4D2 = 1118 + INTEGER(IntKi), PARAMETER :: WkVelYT4D3 = 1119 + INTEGER(IntKi), PARAMETER :: WkVelYT4D4 = 1120 + INTEGER(IntKi), PARAMETER :: WkVelYT4D5 = 1121 + INTEGER(IntKi), PARAMETER :: WkVelYT4D6 = 1122 + INTEGER(IntKi), PARAMETER :: WkVelYT4D7 = 1123 + INTEGER(IntKi), PARAMETER :: WkVelYT4D8 = 1124 + INTEGER(IntKi), PARAMETER :: WkVelYT4D9 = 1125 + INTEGER(IntKi), PARAMETER :: WkVelYT5D1 = 1126 + INTEGER(IntKi), PARAMETER :: WkVelYT5D2 = 1127 + INTEGER(IntKi), PARAMETER :: WkVelYT5D3 = 1128 + INTEGER(IntKi), PARAMETER :: WkVelYT5D4 = 1129 + INTEGER(IntKi), PARAMETER :: WkVelYT5D5 = 1130 + INTEGER(IntKi), PARAMETER :: WkVelYT5D6 = 1131 + INTEGER(IntKi), PARAMETER :: WkVelYT5D7 = 1132 + INTEGER(IntKi), PARAMETER :: WkVelYT5D8 = 1133 + INTEGER(IntKi), PARAMETER :: WkVelYT5D9 = 1134 + INTEGER(IntKi), PARAMETER :: WkVelYT6D1 = 1135 + INTEGER(IntKi), PARAMETER :: WkVelYT6D2 = 1136 + INTEGER(IntKi), PARAMETER :: WkVelYT6D3 = 1137 + INTEGER(IntKi), PARAMETER :: WkVelYT6D4 = 1138 + INTEGER(IntKi), PARAMETER :: WkVelYT6D5 = 1139 + INTEGER(IntKi), PARAMETER :: WkVelYT6D6 = 1140 + INTEGER(IntKi), PARAMETER :: WkVelYT6D7 = 1141 + INTEGER(IntKi), PARAMETER :: WkVelYT6D8 = 1142 + INTEGER(IntKi), PARAMETER :: WkVelYT6D9 = 1143 + INTEGER(IntKi), PARAMETER :: WkVelYT7D1 = 1144 + INTEGER(IntKi), PARAMETER :: WkVelYT7D2 = 1145 + INTEGER(IntKi), PARAMETER :: WkVelYT7D3 = 1146 + INTEGER(IntKi), PARAMETER :: WkVelYT7D4 = 1147 + INTEGER(IntKi), PARAMETER :: WkVelYT7D5 = 1148 + INTEGER(IntKi), PARAMETER :: WkVelYT7D6 = 1149 + INTEGER(IntKi), PARAMETER :: WkVelYT7D7 = 1150 + INTEGER(IntKi), PARAMETER :: WkVelYT7D8 = 1151 + INTEGER(IntKi), PARAMETER :: WkVelYT7D9 = 1152 + INTEGER(IntKi), PARAMETER :: WkVelYT8D1 = 1153 + INTEGER(IntKi), PARAMETER :: WkVelYT8D2 = 1154 + INTEGER(IntKi), PARAMETER :: WkVelYT8D3 = 1155 + INTEGER(IntKi), PARAMETER :: WkVelYT8D4 = 1156 + INTEGER(IntKi), PARAMETER :: WkVelYT8D5 = 1157 + INTEGER(IntKi), PARAMETER :: WkVelYT8D6 = 1158 + INTEGER(IntKi), PARAMETER :: WkVelYT8D7 = 1159 + INTEGER(IntKi), PARAMETER :: WkVelYT8D8 = 1160 + INTEGER(IntKi), PARAMETER :: WkVelYT8D9 = 1161 + INTEGER(IntKi), PARAMETER :: WkVelYT9D1 = 1162 + INTEGER(IntKi), PARAMETER :: WkVelYT9D2 = 1163 + INTEGER(IntKi), PARAMETER :: WkVelYT9D3 = 1164 + INTEGER(IntKi), PARAMETER :: WkVelYT9D4 = 1165 + INTEGER(IntKi), PARAMETER :: WkVelYT9D5 = 1166 + INTEGER(IntKi), PARAMETER :: WkVelYT9D6 = 1167 + INTEGER(IntKi), PARAMETER :: WkVelYT9D7 = 1168 + INTEGER(IntKi), PARAMETER :: WkVelYT9D8 = 1169 + INTEGER(IntKi), PARAMETER :: WkVelYT9D9 = 1170 + INTEGER(IntKi), PARAMETER :: WkVelZT1D1 = 1171 + INTEGER(IntKi), PARAMETER :: WkVelZT1D2 = 1172 + INTEGER(IntKi), PARAMETER :: WkVelZT1D3 = 1173 + INTEGER(IntKi), PARAMETER :: WkVelZT1D4 = 1174 + INTEGER(IntKi), PARAMETER :: WkVelZT1D5 = 1175 + INTEGER(IntKi), PARAMETER :: WkVelZT1D6 = 1176 + INTEGER(IntKi), PARAMETER :: WkVelZT1D7 = 1177 + INTEGER(IntKi), PARAMETER :: WkVelZT1D8 = 1178 + INTEGER(IntKi), PARAMETER :: WkVelZT1D9 = 1179 + INTEGER(IntKi), PARAMETER :: WkVelZT2D1 = 1180 + INTEGER(IntKi), PARAMETER :: WkVelZT2D2 = 1181 + INTEGER(IntKi), PARAMETER :: WkVelZT2D3 = 1182 + INTEGER(IntKi), PARAMETER :: WkVelZT2D4 = 1183 + INTEGER(IntKi), PARAMETER :: WkVelZT2D5 = 1184 + INTEGER(IntKi), PARAMETER :: WkVelZT2D6 = 1185 + INTEGER(IntKi), PARAMETER :: WkVelZT2D7 = 1186 + INTEGER(IntKi), PARAMETER :: WkVelZT2D8 = 1187 + INTEGER(IntKi), PARAMETER :: WkVelZT2D9 = 1188 + INTEGER(IntKi), PARAMETER :: WkVelZT3D1 = 1189 + INTEGER(IntKi), PARAMETER :: WkVelZT3D2 = 1190 + INTEGER(IntKi), PARAMETER :: WkVelZT3D3 = 1191 + INTEGER(IntKi), PARAMETER :: WkVelZT3D4 = 1192 + INTEGER(IntKi), PARAMETER :: WkVelZT3D5 = 1193 + INTEGER(IntKi), PARAMETER :: WkVelZT3D6 = 1194 + INTEGER(IntKi), PARAMETER :: WkVelZT3D7 = 1195 + INTEGER(IntKi), PARAMETER :: WkVelZT3D8 = 1196 + INTEGER(IntKi), PARAMETER :: WkVelZT3D9 = 1197 + INTEGER(IntKi), PARAMETER :: WkVelZT4D1 = 1198 + INTEGER(IntKi), PARAMETER :: WkVelZT4D2 = 1199 + INTEGER(IntKi), PARAMETER :: WkVelZT4D3 = 1200 + INTEGER(IntKi), PARAMETER :: WkVelZT4D4 = 1201 + INTEGER(IntKi), PARAMETER :: WkVelZT4D5 = 1202 + INTEGER(IntKi), PARAMETER :: WkVelZT4D6 = 1203 + INTEGER(IntKi), PARAMETER :: WkVelZT4D7 = 1204 + INTEGER(IntKi), PARAMETER :: WkVelZT4D8 = 1205 + INTEGER(IntKi), PARAMETER :: WkVelZT4D9 = 1206 + INTEGER(IntKi), PARAMETER :: WkVelZT5D1 = 1207 + INTEGER(IntKi), PARAMETER :: WkVelZT5D2 = 1208 + INTEGER(IntKi), PARAMETER :: WkVelZT5D3 = 1209 + INTEGER(IntKi), PARAMETER :: WkVelZT5D4 = 1210 + INTEGER(IntKi), PARAMETER :: WkVelZT5D5 = 1211 + INTEGER(IntKi), PARAMETER :: WkVelZT5D6 = 1212 + INTEGER(IntKi), PARAMETER :: WkVelZT5D7 = 1213 + INTEGER(IntKi), PARAMETER :: WkVelZT5D8 = 1214 + INTEGER(IntKi), PARAMETER :: WkVelZT5D9 = 1215 + INTEGER(IntKi), PARAMETER :: WkVelZT6D1 = 1216 + INTEGER(IntKi), PARAMETER :: WkVelZT6D2 = 1217 + INTEGER(IntKi), PARAMETER :: WkVelZT6D3 = 1218 + INTEGER(IntKi), PARAMETER :: WkVelZT6D4 = 1219 + INTEGER(IntKi), PARAMETER :: WkVelZT6D5 = 1220 + INTEGER(IntKi), PARAMETER :: WkVelZT6D6 = 1221 + INTEGER(IntKi), PARAMETER :: WkVelZT6D7 = 1222 + INTEGER(IntKi), PARAMETER :: WkVelZT6D8 = 1223 + INTEGER(IntKi), PARAMETER :: WkVelZT6D9 = 1224 + INTEGER(IntKi), PARAMETER :: WkVelZT7D1 = 1225 + INTEGER(IntKi), PARAMETER :: WkVelZT7D2 = 1226 + INTEGER(IntKi), PARAMETER :: WkVelZT7D3 = 1227 + INTEGER(IntKi), PARAMETER :: WkVelZT7D4 = 1228 + INTEGER(IntKi), PARAMETER :: WkVelZT7D5 = 1229 + INTEGER(IntKi), PARAMETER :: WkVelZT7D6 = 1230 + INTEGER(IntKi), PARAMETER :: WkVelZT7D7 = 1231 + INTEGER(IntKi), PARAMETER :: WkVelZT7D8 = 1232 + INTEGER(IntKi), PARAMETER :: WkVelZT7D9 = 1233 + INTEGER(IntKi), PARAMETER :: WkVelZT8D1 = 1234 + INTEGER(IntKi), PARAMETER :: WkVelZT8D2 = 1235 + INTEGER(IntKi), PARAMETER :: WkVelZT8D3 = 1236 + INTEGER(IntKi), PARAMETER :: WkVelZT8D4 = 1237 + INTEGER(IntKi), PARAMETER :: WkVelZT8D5 = 1238 + INTEGER(IntKi), PARAMETER :: WkVelZT8D6 = 1239 + INTEGER(IntKi), PARAMETER :: WkVelZT8D7 = 1240 + INTEGER(IntKi), PARAMETER :: WkVelZT8D8 = 1241 + INTEGER(IntKi), PARAMETER :: WkVelZT8D9 = 1242 + INTEGER(IntKi), PARAMETER :: WkVelZT9D1 = 1243 + INTEGER(IntKi), PARAMETER :: WkVelZT9D2 = 1244 + INTEGER(IntKi), PARAMETER :: WkVelZT9D3 = 1245 + INTEGER(IntKi), PARAMETER :: WkVelZT9D4 = 1246 + INTEGER(IntKi), PARAMETER :: WkVelZT9D5 = 1247 + INTEGER(IntKi), PARAMETER :: WkVelZT9D6 = 1248 + INTEGER(IntKi), PARAMETER :: WkVelZT9D7 = 1249 + INTEGER(IntKi), PARAMETER :: WkVelZT9D8 = 1250 + INTEGER(IntKi), PARAMETER :: WkVelZT9D9 = 1251 + + + ! Wake Diameter: + + INTEGER(IntKi), PARAMETER :: WkDiamT1D1 = 1252 + INTEGER(IntKi), PARAMETER :: WkDiamT1D2 = 1253 + INTEGER(IntKi), PARAMETER :: WkDiamT1D3 = 1254 + INTEGER(IntKi), PARAMETER :: WkDiamT1D4 = 1255 + INTEGER(IntKi), PARAMETER :: WkDiamT1D5 = 1256 + INTEGER(IntKi), PARAMETER :: WkDiamT1D6 = 1257 + INTEGER(IntKi), PARAMETER :: WkDiamT1D7 = 1258 + INTEGER(IntKi), PARAMETER :: WkDiamT1D8 = 1259 + INTEGER(IntKi), PARAMETER :: WkDiamT1D9 = 1260 + INTEGER(IntKi), PARAMETER :: WkDiamT2D1 = 1261 + INTEGER(IntKi), PARAMETER :: WkDiamT2D2 = 1262 + INTEGER(IntKi), PARAMETER :: WkDiamT2D3 = 1263 + INTEGER(IntKi), PARAMETER :: WkDiamT2D4 = 1264 + INTEGER(IntKi), PARAMETER :: WkDiamT2D5 = 1265 + INTEGER(IntKi), PARAMETER :: WkDiamT2D6 = 1266 + INTEGER(IntKi), PARAMETER :: WkDiamT2D7 = 1267 + INTEGER(IntKi), PARAMETER :: WkDiamT2D8 = 1268 + INTEGER(IntKi), PARAMETER :: WkDiamT2D9 = 1269 + INTEGER(IntKi), PARAMETER :: WkDiamT3D1 = 1270 + INTEGER(IntKi), PARAMETER :: WkDiamT3D2 = 1271 + INTEGER(IntKi), PARAMETER :: WkDiamT3D3 = 1272 + INTEGER(IntKi), PARAMETER :: WkDiamT3D4 = 1273 + INTEGER(IntKi), PARAMETER :: WkDiamT3D5 = 1274 + INTEGER(IntKi), PARAMETER :: WkDiamT3D6 = 1275 + INTEGER(IntKi), PARAMETER :: WkDiamT3D7 = 1276 + INTEGER(IntKi), PARAMETER :: WkDiamT3D8 = 1277 + INTEGER(IntKi), PARAMETER :: WkDiamT3D9 = 1278 + INTEGER(IntKi), PARAMETER :: WkDiamT4D1 = 1279 + INTEGER(IntKi), PARAMETER :: WkDiamT4D2 = 1280 + INTEGER(IntKi), PARAMETER :: WkDiamT4D3 = 1281 + INTEGER(IntKi), PARAMETER :: WkDiamT4D4 = 1282 + INTEGER(IntKi), PARAMETER :: WkDiamT4D5 = 1283 + INTEGER(IntKi), PARAMETER :: WkDiamT4D6 = 1284 + INTEGER(IntKi), PARAMETER :: WkDiamT4D7 = 1285 + INTEGER(IntKi), PARAMETER :: WkDiamT4D8 = 1286 + INTEGER(IntKi), PARAMETER :: WkDiamT4D9 = 1287 + INTEGER(IntKi), PARAMETER :: WkDiamT5D1 = 1288 + INTEGER(IntKi), PARAMETER :: WkDiamT5D2 = 1289 + INTEGER(IntKi), PARAMETER :: WkDiamT5D3 = 1290 + INTEGER(IntKi), PARAMETER :: WkDiamT5D4 = 1291 + INTEGER(IntKi), PARAMETER :: WkDiamT5D5 = 1292 + INTEGER(IntKi), PARAMETER :: WkDiamT5D6 = 1293 + INTEGER(IntKi), PARAMETER :: WkDiamT5D7 = 1294 + INTEGER(IntKi), PARAMETER :: WkDiamT5D8 = 1295 + INTEGER(IntKi), PARAMETER :: WkDiamT5D9 = 1296 + INTEGER(IntKi), PARAMETER :: WkDiamT6D1 = 1297 + INTEGER(IntKi), PARAMETER :: WkDiamT6D2 = 1298 + INTEGER(IntKi), PARAMETER :: WkDiamT6D3 = 1299 + INTEGER(IntKi), PARAMETER :: WkDiamT6D4 = 1300 + INTEGER(IntKi), PARAMETER :: WkDiamT6D5 = 1301 + INTEGER(IntKi), PARAMETER :: WkDiamT6D6 = 1302 + INTEGER(IntKi), PARAMETER :: WkDiamT6D7 = 1303 + INTEGER(IntKi), PARAMETER :: WkDiamT6D8 = 1304 + INTEGER(IntKi), PARAMETER :: WkDiamT6D9 = 1305 + INTEGER(IntKi), PARAMETER :: WkDiamT7D1 = 1306 + INTEGER(IntKi), PARAMETER :: WkDiamT7D2 = 1307 + INTEGER(IntKi), PARAMETER :: WkDiamT7D3 = 1308 + INTEGER(IntKi), PARAMETER :: WkDiamT7D4 = 1309 + INTEGER(IntKi), PARAMETER :: WkDiamT7D5 = 1310 + INTEGER(IntKi), PARAMETER :: WkDiamT7D6 = 1311 + INTEGER(IntKi), PARAMETER :: WkDiamT7D7 = 1312 + INTEGER(IntKi), PARAMETER :: WkDiamT7D8 = 1313 + INTEGER(IntKi), PARAMETER :: WkDiamT7D9 = 1314 + INTEGER(IntKi), PARAMETER :: WkDiamT8D1 = 1315 + INTEGER(IntKi), PARAMETER :: WkDiamT8D2 = 1316 + INTEGER(IntKi), PARAMETER :: WkDiamT8D3 = 1317 + INTEGER(IntKi), PARAMETER :: WkDiamT8D4 = 1318 + INTEGER(IntKi), PARAMETER :: WkDiamT8D5 = 1319 + INTEGER(IntKi), PARAMETER :: WkDiamT8D6 = 1320 + INTEGER(IntKi), PARAMETER :: WkDiamT8D7 = 1321 + INTEGER(IntKi), PARAMETER :: WkDiamT8D8 = 1322 + INTEGER(IntKi), PARAMETER :: WkDiamT8D9 = 1323 + INTEGER(IntKi), PARAMETER :: WkDiamT9D1 = 1324 + INTEGER(IntKi), PARAMETER :: WkDiamT9D2 = 1325 + INTEGER(IntKi), PARAMETER :: WkDiamT9D3 = 1326 + INTEGER(IntKi), PARAMETER :: WkDiamT9D4 = 1327 + INTEGER(IntKi), PARAMETER :: WkDiamT9D5 = 1328 + INTEGER(IntKi), PARAMETER :: WkDiamT9D6 = 1329 + INTEGER(IntKi), PARAMETER :: WkDiamT9D7 = 1330 + INTEGER(IntKi), PARAMETER :: WkDiamT9D8 = 1331 + INTEGER(IntKi), PARAMETER :: WkDiamT9D9 = 1332 + + + ! Axial Wake Velocity Deficits: + + INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D1 = 1333 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D2 = 1334 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D3 = 1335 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D4 = 1336 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D5 = 1337 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D6 = 1338 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D7 = 1339 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D8 = 1340 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N01D9 = 1341 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D1 = 1342 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D2 = 1343 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D3 = 1344 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D4 = 1345 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D5 = 1346 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D6 = 1347 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D7 = 1348 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D8 = 1349 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N02D9 = 1350 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D1 = 1351 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D2 = 1352 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D3 = 1353 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D4 = 1354 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D5 = 1355 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D6 = 1356 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D7 = 1357 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D8 = 1358 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N03D9 = 1359 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D1 = 1360 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D2 = 1361 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D3 = 1362 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D4 = 1363 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D5 = 1364 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D6 = 1365 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D7 = 1366 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D8 = 1367 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N04D9 = 1368 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D1 = 1369 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D2 = 1370 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D3 = 1371 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D4 = 1372 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D5 = 1373 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D6 = 1374 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D7 = 1375 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D8 = 1376 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N05D9 = 1377 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D1 = 1378 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D2 = 1379 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D3 = 1380 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D4 = 1381 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D5 = 1382 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D6 = 1383 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D7 = 1384 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D8 = 1385 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N06D9 = 1386 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D1 = 1387 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D2 = 1388 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D3 = 1389 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D4 = 1390 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D5 = 1391 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D6 = 1392 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D7 = 1393 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D8 = 1394 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N07D9 = 1395 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D1 = 1396 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D2 = 1397 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D3 = 1398 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D4 = 1399 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D5 = 1400 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D6 = 1401 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D7 = 1402 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D8 = 1403 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N08D9 = 1404 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D1 = 1405 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D2 = 1406 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D3 = 1407 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D4 = 1408 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D5 = 1409 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D6 = 1410 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D7 = 1411 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D8 = 1412 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N09D9 = 1413 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D1 = 1414 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D2 = 1415 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D3 = 1416 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D4 = 1417 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D5 = 1418 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D6 = 1419 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D7 = 1420 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D8 = 1421 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N10D9 = 1422 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D1 = 1423 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D2 = 1424 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D3 = 1425 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D4 = 1426 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D5 = 1427 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D6 = 1428 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D7 = 1429 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D8 = 1430 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N11D9 = 1431 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D1 = 1432 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D2 = 1433 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D3 = 1434 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D4 = 1435 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D5 = 1436 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D6 = 1437 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D7 = 1438 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D8 = 1439 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N12D9 = 1440 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D1 = 1441 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D2 = 1442 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D3 = 1443 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D4 = 1444 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D5 = 1445 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D6 = 1446 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D7 = 1447 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D8 = 1448 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N13D9 = 1449 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D1 = 1450 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D2 = 1451 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D3 = 1452 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D4 = 1453 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D5 = 1454 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D6 = 1455 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D7 = 1456 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D8 = 1457 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N14D9 = 1458 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D1 = 1459 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D2 = 1460 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D3 = 1461 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D4 = 1462 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D5 = 1463 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D6 = 1464 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D7 = 1465 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D8 = 1466 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N15D9 = 1467 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D1 = 1468 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D2 = 1469 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D3 = 1470 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D4 = 1471 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D5 = 1472 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D6 = 1473 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D7 = 1474 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D8 = 1475 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N16D9 = 1476 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D1 = 1477 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D2 = 1478 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D3 = 1479 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D4 = 1480 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D5 = 1481 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D6 = 1482 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D7 = 1483 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D8 = 1484 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N17D9 = 1485 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D1 = 1486 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D2 = 1487 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D3 = 1488 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D4 = 1489 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D5 = 1490 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D6 = 1491 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D7 = 1492 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D8 = 1493 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N18D9 = 1494 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D1 = 1495 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D2 = 1496 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D3 = 1497 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D4 = 1498 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D5 = 1499 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D6 = 1500 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D7 = 1501 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D8 = 1502 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N19D9 = 1503 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D1 = 1504 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D2 = 1505 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D3 = 1506 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D4 = 1507 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D5 = 1508 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D6 = 1509 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D7 = 1510 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D8 = 1511 + INTEGER(IntKi), PARAMETER :: WkDfVxT1N20D9 = 1512 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D1 = 1513 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D2 = 1514 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D3 = 1515 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D4 = 1516 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D5 = 1517 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D6 = 1518 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D7 = 1519 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D8 = 1520 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N01D9 = 1521 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D1 = 1522 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D2 = 1523 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D3 = 1524 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D4 = 1525 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D5 = 1526 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D6 = 1527 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D7 = 1528 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D8 = 1529 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N02D9 = 1530 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D1 = 1531 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D2 = 1532 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D3 = 1533 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D4 = 1534 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D5 = 1535 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D6 = 1536 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D7 = 1537 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D8 = 1538 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N03D9 = 1539 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D1 = 1540 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D2 = 1541 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D3 = 1542 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D4 = 1543 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D5 = 1544 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D6 = 1545 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D7 = 1546 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D8 = 1547 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N04D9 = 1548 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D1 = 1549 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D2 = 1550 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D3 = 1551 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D4 = 1552 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D5 = 1553 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D6 = 1554 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D7 = 1555 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D8 = 1556 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N05D9 = 1557 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D1 = 1558 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D2 = 1559 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D3 = 1560 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D4 = 1561 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D5 = 1562 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D6 = 1563 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D7 = 1564 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D8 = 1565 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N06D9 = 1566 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D1 = 1567 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D2 = 1568 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D3 = 1569 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D4 = 1570 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D5 = 1571 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D6 = 1572 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D7 = 1573 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D8 = 1574 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N07D9 = 1575 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D1 = 1576 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D2 = 1577 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D3 = 1578 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D4 = 1579 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D5 = 1580 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D6 = 1581 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D7 = 1582 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D8 = 1583 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N08D9 = 1584 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D1 = 1585 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D2 = 1586 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D3 = 1587 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D4 = 1588 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D5 = 1589 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D6 = 1590 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D7 = 1591 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D8 = 1592 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N09D9 = 1593 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D1 = 1594 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D2 = 1595 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D3 = 1596 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D4 = 1597 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D5 = 1598 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D6 = 1599 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D7 = 1600 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D8 = 1601 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N10D9 = 1602 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D1 = 1603 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D2 = 1604 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D3 = 1605 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D4 = 1606 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D5 = 1607 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D6 = 1608 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D7 = 1609 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D8 = 1610 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N11D9 = 1611 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D1 = 1612 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D2 = 1613 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D3 = 1614 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D4 = 1615 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D5 = 1616 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D6 = 1617 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D7 = 1618 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D8 = 1619 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N12D9 = 1620 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D1 = 1621 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D2 = 1622 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D3 = 1623 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D4 = 1624 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D5 = 1625 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D6 = 1626 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D7 = 1627 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D8 = 1628 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N13D9 = 1629 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D1 = 1630 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D2 = 1631 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D3 = 1632 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D4 = 1633 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D5 = 1634 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D6 = 1635 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D7 = 1636 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D8 = 1637 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N14D9 = 1638 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D1 = 1639 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D2 = 1640 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D3 = 1641 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D4 = 1642 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D5 = 1643 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D6 = 1644 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D7 = 1645 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D8 = 1646 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N15D9 = 1647 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D1 = 1648 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D2 = 1649 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D3 = 1650 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D4 = 1651 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D5 = 1652 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D6 = 1653 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D7 = 1654 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D8 = 1655 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N16D9 = 1656 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D1 = 1657 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D2 = 1658 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D3 = 1659 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D4 = 1660 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D5 = 1661 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D6 = 1662 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D7 = 1663 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D8 = 1664 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N17D9 = 1665 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D1 = 1666 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D2 = 1667 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D3 = 1668 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D4 = 1669 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D5 = 1670 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D6 = 1671 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D7 = 1672 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D8 = 1673 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N18D9 = 1674 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D1 = 1675 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D2 = 1676 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D3 = 1677 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D4 = 1678 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D5 = 1679 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D6 = 1680 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D7 = 1681 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D8 = 1682 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N19D9 = 1683 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D1 = 1684 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D2 = 1685 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D3 = 1686 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D4 = 1687 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D5 = 1688 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D6 = 1689 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D7 = 1690 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D8 = 1691 + INTEGER(IntKi), PARAMETER :: WkDfVxT2N20D9 = 1692 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D1 = 1693 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D2 = 1694 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D3 = 1695 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D4 = 1696 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D5 = 1697 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D6 = 1698 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D7 = 1699 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D8 = 1700 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N01D9 = 1701 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D1 = 1702 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D2 = 1703 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D3 = 1704 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D4 = 1705 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D5 = 1706 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D6 = 1707 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D7 = 1708 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D8 = 1709 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N02D9 = 1710 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D1 = 1711 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D2 = 1712 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D3 = 1713 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D4 = 1714 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D5 = 1715 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D6 = 1716 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D7 = 1717 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D8 = 1718 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N03D9 = 1719 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D1 = 1720 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D2 = 1721 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D3 = 1722 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D4 = 1723 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D5 = 1724 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D6 = 1725 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D7 = 1726 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D8 = 1727 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N04D9 = 1728 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D1 = 1729 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D2 = 1730 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D3 = 1731 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D4 = 1732 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D5 = 1733 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D6 = 1734 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D7 = 1735 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D8 = 1736 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N05D9 = 1737 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D1 = 1738 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D2 = 1739 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D3 = 1740 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D4 = 1741 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D5 = 1742 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D6 = 1743 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D7 = 1744 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D8 = 1745 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N06D9 = 1746 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D1 = 1747 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D2 = 1748 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D3 = 1749 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D4 = 1750 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D5 = 1751 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D6 = 1752 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D7 = 1753 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D8 = 1754 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N07D9 = 1755 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D1 = 1756 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D2 = 1757 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D3 = 1758 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D4 = 1759 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D5 = 1760 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D6 = 1761 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D7 = 1762 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D8 = 1763 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N08D9 = 1764 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D1 = 1765 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D2 = 1766 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D3 = 1767 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D4 = 1768 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D5 = 1769 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D6 = 1770 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D7 = 1771 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D8 = 1772 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N09D9 = 1773 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D1 = 1774 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D2 = 1775 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D3 = 1776 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D4 = 1777 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D5 = 1778 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D6 = 1779 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D7 = 1780 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D8 = 1781 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N10D9 = 1782 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D1 = 1783 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D2 = 1784 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D3 = 1785 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D4 = 1786 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D5 = 1787 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D6 = 1788 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D7 = 1789 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D8 = 1790 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N11D9 = 1791 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D1 = 1792 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D2 = 1793 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D3 = 1794 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D4 = 1795 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D5 = 1796 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D6 = 1797 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D7 = 1798 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D8 = 1799 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N12D9 = 1800 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D1 = 1801 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D2 = 1802 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D3 = 1803 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D4 = 1804 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D5 = 1805 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D6 = 1806 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D7 = 1807 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D8 = 1808 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N13D9 = 1809 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D1 = 1810 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D2 = 1811 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D3 = 1812 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D4 = 1813 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D5 = 1814 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D6 = 1815 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D7 = 1816 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D8 = 1817 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N14D9 = 1818 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D1 = 1819 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D2 = 1820 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D3 = 1821 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D4 = 1822 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D5 = 1823 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D6 = 1824 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D7 = 1825 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D8 = 1826 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N15D9 = 1827 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D1 = 1828 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D2 = 1829 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D3 = 1830 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D4 = 1831 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D5 = 1832 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D6 = 1833 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D7 = 1834 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D8 = 1835 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N16D9 = 1836 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D1 = 1837 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D2 = 1838 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D3 = 1839 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D4 = 1840 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D5 = 1841 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D6 = 1842 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D7 = 1843 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D8 = 1844 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N17D9 = 1845 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D1 = 1846 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D2 = 1847 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D3 = 1848 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D4 = 1849 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D5 = 1850 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D6 = 1851 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D7 = 1852 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D8 = 1853 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N18D9 = 1854 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D1 = 1855 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D2 = 1856 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D3 = 1857 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D4 = 1858 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D5 = 1859 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D6 = 1860 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D7 = 1861 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D8 = 1862 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N19D9 = 1863 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D1 = 1864 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D2 = 1865 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D3 = 1866 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D4 = 1867 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D5 = 1868 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D6 = 1869 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D7 = 1870 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D8 = 1871 + INTEGER(IntKi), PARAMETER :: WkDfVxT3N20D9 = 1872 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D1 = 1873 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D2 = 1874 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D3 = 1875 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D4 = 1876 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D5 = 1877 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D6 = 1878 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D7 = 1879 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D8 = 1880 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N01D9 = 1881 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D1 = 1882 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D2 = 1883 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D3 = 1884 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D4 = 1885 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D5 = 1886 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D6 = 1887 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D7 = 1888 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D8 = 1889 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N02D9 = 1890 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D1 = 1891 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D2 = 1892 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D3 = 1893 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D4 = 1894 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D5 = 1895 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D6 = 1896 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D7 = 1897 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D8 = 1898 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N03D9 = 1899 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D1 = 1900 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D2 = 1901 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D3 = 1902 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D4 = 1903 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D5 = 1904 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D6 = 1905 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D7 = 1906 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D8 = 1907 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N04D9 = 1908 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D1 = 1909 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D2 = 1910 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D3 = 1911 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D4 = 1912 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D5 = 1913 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D6 = 1914 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D7 = 1915 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D8 = 1916 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N05D9 = 1917 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D1 = 1918 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D2 = 1919 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D3 = 1920 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D4 = 1921 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D5 = 1922 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D6 = 1923 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D7 = 1924 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D8 = 1925 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N06D9 = 1926 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D1 = 1927 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D2 = 1928 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D3 = 1929 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D4 = 1930 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D5 = 1931 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D6 = 1932 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D7 = 1933 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D8 = 1934 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N07D9 = 1935 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D1 = 1936 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D2 = 1937 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D3 = 1938 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D4 = 1939 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D5 = 1940 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D6 = 1941 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D7 = 1942 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D8 = 1943 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N08D9 = 1944 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D1 = 1945 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D2 = 1946 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D3 = 1947 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D4 = 1948 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D5 = 1949 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D6 = 1950 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D7 = 1951 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D8 = 1952 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N09D9 = 1953 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D1 = 1954 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D2 = 1955 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D3 = 1956 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D4 = 1957 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D5 = 1958 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D6 = 1959 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D7 = 1960 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D8 = 1961 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N10D9 = 1962 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D1 = 1963 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D2 = 1964 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D3 = 1965 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D4 = 1966 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D5 = 1967 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D6 = 1968 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D7 = 1969 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D8 = 1970 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N11D9 = 1971 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D1 = 1972 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D2 = 1973 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D3 = 1974 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D4 = 1975 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D5 = 1976 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D6 = 1977 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D7 = 1978 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D8 = 1979 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N12D9 = 1980 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D1 = 1981 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D2 = 1982 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D3 = 1983 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D4 = 1984 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D5 = 1985 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D6 = 1986 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D7 = 1987 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D8 = 1988 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N13D9 = 1989 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D1 = 1990 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D2 = 1991 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D3 = 1992 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D4 = 1993 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D5 = 1994 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D6 = 1995 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D7 = 1996 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D8 = 1997 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N14D9 = 1998 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D1 = 1999 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D2 = 2000 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D3 = 2001 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D4 = 2002 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D5 = 2003 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D6 = 2004 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D7 = 2005 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D8 = 2006 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N15D9 = 2007 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D1 = 2008 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D2 = 2009 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D3 = 2010 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D4 = 2011 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D5 = 2012 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D6 = 2013 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D7 = 2014 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D8 = 2015 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N16D9 = 2016 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D1 = 2017 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D2 = 2018 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D3 = 2019 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D4 = 2020 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D5 = 2021 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D6 = 2022 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D7 = 2023 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D8 = 2024 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N17D9 = 2025 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D1 = 2026 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D2 = 2027 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D3 = 2028 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D4 = 2029 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D5 = 2030 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D6 = 2031 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D7 = 2032 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D8 = 2033 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N18D9 = 2034 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D1 = 2035 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D2 = 2036 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D3 = 2037 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D4 = 2038 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D5 = 2039 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D6 = 2040 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D7 = 2041 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D8 = 2042 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N19D9 = 2043 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D1 = 2044 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D2 = 2045 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D3 = 2046 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D4 = 2047 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D5 = 2048 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D6 = 2049 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D7 = 2050 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D8 = 2051 + INTEGER(IntKi), PARAMETER :: WkDfVxT4N20D9 = 2052 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D1 = 2053 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D2 = 2054 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D3 = 2055 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D4 = 2056 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D5 = 2057 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D6 = 2058 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D7 = 2059 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D8 = 2060 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N01D9 = 2061 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D1 = 2062 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D2 = 2063 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D3 = 2064 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D4 = 2065 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D5 = 2066 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D6 = 2067 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D7 = 2068 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D8 = 2069 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N02D9 = 2070 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D1 = 2071 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D2 = 2072 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D3 = 2073 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D4 = 2074 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D5 = 2075 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D6 = 2076 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D7 = 2077 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D8 = 2078 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N03D9 = 2079 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D1 = 2080 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D2 = 2081 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D3 = 2082 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D4 = 2083 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D5 = 2084 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D6 = 2085 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D7 = 2086 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D8 = 2087 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N04D9 = 2088 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D1 = 2089 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D2 = 2090 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D3 = 2091 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D4 = 2092 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D5 = 2093 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D6 = 2094 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D7 = 2095 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D8 = 2096 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N05D9 = 2097 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D1 = 2098 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D2 = 2099 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D3 = 2100 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D4 = 2101 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D5 = 2102 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D6 = 2103 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D7 = 2104 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D8 = 2105 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N06D9 = 2106 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D1 = 2107 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D2 = 2108 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D3 = 2109 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D4 = 2110 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D5 = 2111 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D6 = 2112 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D7 = 2113 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D8 = 2114 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N07D9 = 2115 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D1 = 2116 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D2 = 2117 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D3 = 2118 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D4 = 2119 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D5 = 2120 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D6 = 2121 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D7 = 2122 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D8 = 2123 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N08D9 = 2124 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D1 = 2125 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D2 = 2126 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D3 = 2127 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D4 = 2128 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D5 = 2129 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D6 = 2130 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D7 = 2131 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D8 = 2132 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N09D9 = 2133 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D1 = 2134 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D2 = 2135 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D3 = 2136 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D4 = 2137 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D5 = 2138 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D6 = 2139 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D7 = 2140 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D8 = 2141 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N10D9 = 2142 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D1 = 2143 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D2 = 2144 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D3 = 2145 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D4 = 2146 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D5 = 2147 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D6 = 2148 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D7 = 2149 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D8 = 2150 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N11D9 = 2151 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D1 = 2152 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D2 = 2153 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D3 = 2154 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D4 = 2155 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D5 = 2156 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D6 = 2157 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D7 = 2158 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D8 = 2159 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N12D9 = 2160 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D1 = 2161 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D2 = 2162 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D3 = 2163 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D4 = 2164 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D5 = 2165 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D6 = 2166 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D7 = 2167 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D8 = 2168 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N13D9 = 2169 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D1 = 2170 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D2 = 2171 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D3 = 2172 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D4 = 2173 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D5 = 2174 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D6 = 2175 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D7 = 2176 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D8 = 2177 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N14D9 = 2178 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D1 = 2179 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D2 = 2180 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D3 = 2181 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D4 = 2182 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D5 = 2183 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D6 = 2184 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D7 = 2185 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D8 = 2186 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N15D9 = 2187 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D1 = 2188 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D2 = 2189 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D3 = 2190 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D4 = 2191 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D5 = 2192 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D6 = 2193 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D7 = 2194 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D8 = 2195 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N16D9 = 2196 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D1 = 2197 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D2 = 2198 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D3 = 2199 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D4 = 2200 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D5 = 2201 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D6 = 2202 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D7 = 2203 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D8 = 2204 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N17D9 = 2205 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D1 = 2206 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D2 = 2207 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D3 = 2208 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D4 = 2209 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D5 = 2210 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D6 = 2211 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D7 = 2212 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D8 = 2213 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N18D9 = 2214 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D1 = 2215 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D2 = 2216 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D3 = 2217 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D4 = 2218 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D5 = 2219 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D6 = 2220 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D7 = 2221 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D8 = 2222 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N19D9 = 2223 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D1 = 2224 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D2 = 2225 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D3 = 2226 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D4 = 2227 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D5 = 2228 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D6 = 2229 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D7 = 2230 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D8 = 2231 + INTEGER(IntKi), PARAMETER :: WkDfVxT5N20D9 = 2232 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D1 = 2233 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D2 = 2234 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D3 = 2235 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D4 = 2236 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D5 = 2237 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D6 = 2238 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D7 = 2239 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D8 = 2240 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N01D9 = 2241 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D1 = 2242 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D2 = 2243 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D3 = 2244 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D4 = 2245 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D5 = 2246 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D6 = 2247 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D7 = 2248 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D8 = 2249 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N02D9 = 2250 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D1 = 2251 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D2 = 2252 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D3 = 2253 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D4 = 2254 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D5 = 2255 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D6 = 2256 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D7 = 2257 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D8 = 2258 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N03D9 = 2259 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D1 = 2260 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D2 = 2261 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D3 = 2262 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D4 = 2263 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D5 = 2264 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D6 = 2265 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D7 = 2266 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D8 = 2267 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N04D9 = 2268 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D1 = 2269 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D2 = 2270 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D3 = 2271 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D4 = 2272 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D5 = 2273 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D6 = 2274 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D7 = 2275 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D8 = 2276 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N05D9 = 2277 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D1 = 2278 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D2 = 2279 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D3 = 2280 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D4 = 2281 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D5 = 2282 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D6 = 2283 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D7 = 2284 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D8 = 2285 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N06D9 = 2286 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D1 = 2287 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D2 = 2288 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D3 = 2289 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D4 = 2290 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D5 = 2291 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D6 = 2292 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D7 = 2293 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D8 = 2294 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N07D9 = 2295 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D1 = 2296 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D2 = 2297 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D3 = 2298 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D4 = 2299 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D5 = 2300 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D6 = 2301 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D7 = 2302 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D8 = 2303 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N08D9 = 2304 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D1 = 2305 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D2 = 2306 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D3 = 2307 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D4 = 2308 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D5 = 2309 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D6 = 2310 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D7 = 2311 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D8 = 2312 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N09D9 = 2313 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D1 = 2314 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D2 = 2315 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D3 = 2316 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D4 = 2317 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D5 = 2318 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D6 = 2319 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D7 = 2320 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D8 = 2321 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N10D9 = 2322 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D1 = 2323 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D2 = 2324 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D3 = 2325 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D4 = 2326 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D5 = 2327 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D6 = 2328 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D7 = 2329 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D8 = 2330 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N11D9 = 2331 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D1 = 2332 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D2 = 2333 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D3 = 2334 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D4 = 2335 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D5 = 2336 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D6 = 2337 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D7 = 2338 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D8 = 2339 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N12D9 = 2340 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D1 = 2341 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D2 = 2342 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D3 = 2343 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D4 = 2344 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D5 = 2345 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D6 = 2346 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D7 = 2347 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D8 = 2348 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N13D9 = 2349 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D1 = 2350 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D2 = 2351 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D3 = 2352 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D4 = 2353 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D5 = 2354 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D6 = 2355 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D7 = 2356 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D8 = 2357 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N14D9 = 2358 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D1 = 2359 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D2 = 2360 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D3 = 2361 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D4 = 2362 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D5 = 2363 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D6 = 2364 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D7 = 2365 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D8 = 2366 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N15D9 = 2367 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D1 = 2368 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D2 = 2369 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D3 = 2370 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D4 = 2371 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D5 = 2372 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D6 = 2373 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D7 = 2374 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D8 = 2375 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N16D9 = 2376 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D1 = 2377 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D2 = 2378 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D3 = 2379 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D4 = 2380 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D5 = 2381 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D6 = 2382 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D7 = 2383 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D8 = 2384 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N17D9 = 2385 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D1 = 2386 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D2 = 2387 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D3 = 2388 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D4 = 2389 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D5 = 2390 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D6 = 2391 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D7 = 2392 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D8 = 2393 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N18D9 = 2394 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D1 = 2395 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D2 = 2396 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D3 = 2397 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D4 = 2398 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D5 = 2399 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D6 = 2400 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D7 = 2401 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D8 = 2402 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N19D9 = 2403 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D1 = 2404 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D2 = 2405 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D3 = 2406 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D4 = 2407 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D5 = 2408 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D6 = 2409 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D7 = 2410 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D8 = 2411 + INTEGER(IntKi), PARAMETER :: WkDfVxT6N20D9 = 2412 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D1 = 2413 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D2 = 2414 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D3 = 2415 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D4 = 2416 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D5 = 2417 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D6 = 2418 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D7 = 2419 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D8 = 2420 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N01D9 = 2421 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D1 = 2422 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D2 = 2423 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D3 = 2424 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D4 = 2425 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D5 = 2426 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D6 = 2427 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D7 = 2428 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D8 = 2429 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N02D9 = 2430 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D1 = 2431 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D2 = 2432 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D3 = 2433 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D4 = 2434 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D5 = 2435 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D6 = 2436 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D7 = 2437 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D8 = 2438 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N03D9 = 2439 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D1 = 2440 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D2 = 2441 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D3 = 2442 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D4 = 2443 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D5 = 2444 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D6 = 2445 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D7 = 2446 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D8 = 2447 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N04D9 = 2448 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D1 = 2449 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D2 = 2450 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D3 = 2451 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D4 = 2452 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D5 = 2453 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D6 = 2454 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D7 = 2455 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D8 = 2456 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N05D9 = 2457 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D1 = 2458 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D2 = 2459 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D3 = 2460 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D4 = 2461 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D5 = 2462 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D6 = 2463 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D7 = 2464 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D8 = 2465 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N06D9 = 2466 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D1 = 2467 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D2 = 2468 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D3 = 2469 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D4 = 2470 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D5 = 2471 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D6 = 2472 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D7 = 2473 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D8 = 2474 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N07D9 = 2475 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D1 = 2476 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D2 = 2477 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D3 = 2478 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D4 = 2479 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D5 = 2480 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D6 = 2481 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D7 = 2482 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D8 = 2483 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N08D9 = 2484 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D1 = 2485 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D2 = 2486 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D3 = 2487 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D4 = 2488 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D5 = 2489 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D6 = 2490 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D7 = 2491 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D8 = 2492 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N09D9 = 2493 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D1 = 2494 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D2 = 2495 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D3 = 2496 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D4 = 2497 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D5 = 2498 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D6 = 2499 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D7 = 2500 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D8 = 2501 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N10D9 = 2502 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D1 = 2503 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D2 = 2504 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D3 = 2505 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D4 = 2506 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D5 = 2507 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D6 = 2508 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D7 = 2509 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D8 = 2510 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N11D9 = 2511 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D1 = 2512 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D2 = 2513 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D3 = 2514 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D4 = 2515 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D5 = 2516 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D6 = 2517 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D7 = 2518 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D8 = 2519 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N12D9 = 2520 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D1 = 2521 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D2 = 2522 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D3 = 2523 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D4 = 2524 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D5 = 2525 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D6 = 2526 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D7 = 2527 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D8 = 2528 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N13D9 = 2529 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D1 = 2530 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D2 = 2531 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D3 = 2532 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D4 = 2533 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D5 = 2534 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D6 = 2535 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D7 = 2536 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D8 = 2537 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N14D9 = 2538 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D1 = 2539 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D2 = 2540 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D3 = 2541 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D4 = 2542 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D5 = 2543 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D6 = 2544 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D7 = 2545 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D8 = 2546 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N15D9 = 2547 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D1 = 2548 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D2 = 2549 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D3 = 2550 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D4 = 2551 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D5 = 2552 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D6 = 2553 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D7 = 2554 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D8 = 2555 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N16D9 = 2556 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D1 = 2557 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D2 = 2558 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D3 = 2559 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D4 = 2560 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D5 = 2561 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D6 = 2562 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D7 = 2563 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D8 = 2564 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N17D9 = 2565 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D1 = 2566 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D2 = 2567 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D3 = 2568 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D4 = 2569 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D5 = 2570 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D6 = 2571 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D7 = 2572 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D8 = 2573 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N18D9 = 2574 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D1 = 2575 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D2 = 2576 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D3 = 2577 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D4 = 2578 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D5 = 2579 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D6 = 2580 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D7 = 2581 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D8 = 2582 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N19D9 = 2583 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D1 = 2584 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D2 = 2585 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D3 = 2586 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D4 = 2587 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D5 = 2588 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D6 = 2589 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D7 = 2590 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D8 = 2591 + INTEGER(IntKi), PARAMETER :: WkDfVxT7N20D9 = 2592 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D1 = 2593 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D2 = 2594 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D3 = 2595 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D4 = 2596 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D5 = 2597 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D6 = 2598 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D7 = 2599 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D8 = 2600 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N01D9 = 2601 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D1 = 2602 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D2 = 2603 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D3 = 2604 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D4 = 2605 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D5 = 2606 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D6 = 2607 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D7 = 2608 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D8 = 2609 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N02D9 = 2610 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D1 = 2611 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D2 = 2612 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D3 = 2613 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D4 = 2614 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D5 = 2615 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D6 = 2616 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D7 = 2617 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D8 = 2618 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N03D9 = 2619 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D1 = 2620 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D2 = 2621 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D3 = 2622 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D4 = 2623 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D5 = 2624 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D6 = 2625 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D7 = 2626 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D8 = 2627 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N04D9 = 2628 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D1 = 2629 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D2 = 2630 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D3 = 2631 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D4 = 2632 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D5 = 2633 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D6 = 2634 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D7 = 2635 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D8 = 2636 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N05D9 = 2637 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D1 = 2638 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D2 = 2639 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D3 = 2640 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D4 = 2641 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D5 = 2642 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D6 = 2643 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D7 = 2644 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D8 = 2645 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N06D9 = 2646 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D1 = 2647 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D2 = 2648 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D3 = 2649 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D4 = 2650 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D5 = 2651 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D6 = 2652 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D7 = 2653 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D8 = 2654 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N07D9 = 2655 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D1 = 2656 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D2 = 2657 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D3 = 2658 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D4 = 2659 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D5 = 2660 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D6 = 2661 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D7 = 2662 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D8 = 2663 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N08D9 = 2664 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D1 = 2665 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D2 = 2666 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D3 = 2667 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D4 = 2668 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D5 = 2669 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D6 = 2670 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D7 = 2671 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D8 = 2672 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N09D9 = 2673 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D1 = 2674 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D2 = 2675 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D3 = 2676 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D4 = 2677 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D5 = 2678 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D6 = 2679 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D7 = 2680 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D8 = 2681 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N10D9 = 2682 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D1 = 2683 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D2 = 2684 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D3 = 2685 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D4 = 2686 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D5 = 2687 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D6 = 2688 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D7 = 2689 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D8 = 2690 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N11D9 = 2691 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D1 = 2692 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D2 = 2693 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D3 = 2694 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D4 = 2695 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D5 = 2696 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D6 = 2697 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D7 = 2698 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D8 = 2699 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N12D9 = 2700 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D1 = 2701 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D2 = 2702 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D3 = 2703 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D4 = 2704 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D5 = 2705 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D6 = 2706 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D7 = 2707 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D8 = 2708 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N13D9 = 2709 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D1 = 2710 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D2 = 2711 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D3 = 2712 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D4 = 2713 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D5 = 2714 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D6 = 2715 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D7 = 2716 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D8 = 2717 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N14D9 = 2718 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D1 = 2719 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D2 = 2720 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D3 = 2721 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D4 = 2722 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D5 = 2723 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D6 = 2724 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D7 = 2725 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D8 = 2726 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N15D9 = 2727 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D1 = 2728 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D2 = 2729 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D3 = 2730 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D4 = 2731 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D5 = 2732 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D6 = 2733 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D7 = 2734 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D8 = 2735 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N16D9 = 2736 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D1 = 2737 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D2 = 2738 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D3 = 2739 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D4 = 2740 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D5 = 2741 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D6 = 2742 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D7 = 2743 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D8 = 2744 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N17D9 = 2745 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D1 = 2746 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D2 = 2747 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D3 = 2748 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D4 = 2749 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D5 = 2750 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D6 = 2751 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D7 = 2752 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D8 = 2753 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N18D9 = 2754 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D1 = 2755 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D2 = 2756 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D3 = 2757 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D4 = 2758 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D5 = 2759 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D6 = 2760 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D7 = 2761 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D8 = 2762 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N19D9 = 2763 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D1 = 2764 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D2 = 2765 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D3 = 2766 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D4 = 2767 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D5 = 2768 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D6 = 2769 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D7 = 2770 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D8 = 2771 + INTEGER(IntKi), PARAMETER :: WkDfVxT8N20D9 = 2772 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D1 = 2773 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D2 = 2774 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D3 = 2775 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D4 = 2776 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D5 = 2777 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D6 = 2778 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D7 = 2779 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D8 = 2780 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N01D9 = 2781 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D1 = 2782 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D2 = 2783 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D3 = 2784 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D4 = 2785 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D5 = 2786 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D6 = 2787 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D7 = 2788 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D8 = 2789 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N02D9 = 2790 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D1 = 2791 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D2 = 2792 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D3 = 2793 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D4 = 2794 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D5 = 2795 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D6 = 2796 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D7 = 2797 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D8 = 2798 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N03D9 = 2799 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D1 = 2800 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D2 = 2801 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D3 = 2802 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D4 = 2803 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D5 = 2804 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D6 = 2805 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D7 = 2806 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D8 = 2807 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N04D9 = 2808 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D1 = 2809 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D2 = 2810 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D3 = 2811 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D4 = 2812 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D5 = 2813 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D6 = 2814 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D7 = 2815 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D8 = 2816 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N05D9 = 2817 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D1 = 2818 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D2 = 2819 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D3 = 2820 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D4 = 2821 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D5 = 2822 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D6 = 2823 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D7 = 2824 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D8 = 2825 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N06D9 = 2826 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D1 = 2827 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D2 = 2828 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D3 = 2829 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D4 = 2830 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D5 = 2831 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D6 = 2832 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D7 = 2833 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D8 = 2834 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N07D9 = 2835 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D1 = 2836 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D2 = 2837 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D3 = 2838 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D4 = 2839 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D5 = 2840 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D6 = 2841 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D7 = 2842 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D8 = 2843 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N08D9 = 2844 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D1 = 2845 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D2 = 2846 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D3 = 2847 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D4 = 2848 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D5 = 2849 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D6 = 2850 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D7 = 2851 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D8 = 2852 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N09D9 = 2853 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D1 = 2854 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D2 = 2855 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D3 = 2856 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D4 = 2857 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D5 = 2858 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D6 = 2859 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D7 = 2860 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D8 = 2861 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N10D9 = 2862 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D1 = 2863 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D2 = 2864 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D3 = 2865 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D4 = 2866 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D5 = 2867 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D6 = 2868 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D7 = 2869 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D8 = 2870 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N11D9 = 2871 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D1 = 2872 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D2 = 2873 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D3 = 2874 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D4 = 2875 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D5 = 2876 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D6 = 2877 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D7 = 2878 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D8 = 2879 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N12D9 = 2880 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D1 = 2881 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D2 = 2882 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D3 = 2883 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D4 = 2884 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D5 = 2885 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D6 = 2886 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D7 = 2887 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D8 = 2888 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N13D9 = 2889 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D1 = 2890 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D2 = 2891 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D3 = 2892 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D4 = 2893 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D5 = 2894 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D6 = 2895 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D7 = 2896 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D8 = 2897 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N14D9 = 2898 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D1 = 2899 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D2 = 2900 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D3 = 2901 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D4 = 2902 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D5 = 2903 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D6 = 2904 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D7 = 2905 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D8 = 2906 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N15D9 = 2907 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D1 = 2908 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D2 = 2909 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D3 = 2910 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D4 = 2911 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D5 = 2912 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D6 = 2913 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D7 = 2914 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D8 = 2915 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N16D9 = 2916 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D1 = 2917 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D2 = 2918 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D3 = 2919 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D4 = 2920 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D5 = 2921 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D6 = 2922 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D7 = 2923 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D8 = 2924 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N17D9 = 2925 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D1 = 2926 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D2 = 2927 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D3 = 2928 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D4 = 2929 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D5 = 2930 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D6 = 2931 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D7 = 2932 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D8 = 2933 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N18D9 = 2934 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D1 = 2935 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D2 = 2936 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D3 = 2937 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D4 = 2938 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D5 = 2939 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D6 = 2940 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D7 = 2941 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D8 = 2942 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N19D9 = 2943 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D1 = 2944 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D2 = 2945 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D3 = 2946 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D4 = 2947 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D5 = 2948 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D6 = 2949 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D7 = 2950 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D8 = 2951 + INTEGER(IntKi), PARAMETER :: WkDfVxT9N20D9 = 2952 + + + ! Radial Wake Velocity Deficits: + + INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D1 = 2953 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D2 = 2954 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D3 = 2955 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D4 = 2956 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D5 = 2957 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D6 = 2958 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D7 = 2959 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D8 = 2960 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N01D9 = 2961 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D1 = 2962 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D2 = 2963 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D3 = 2964 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D4 = 2965 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D5 = 2966 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D6 = 2967 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D7 = 2968 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D8 = 2969 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N02D9 = 2970 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D1 = 2971 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D2 = 2972 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D3 = 2973 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D4 = 2974 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D5 = 2975 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D6 = 2976 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D7 = 2977 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D8 = 2978 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N03D9 = 2979 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D1 = 2980 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D2 = 2981 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D3 = 2982 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D4 = 2983 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D5 = 2984 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D6 = 2985 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D7 = 2986 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D8 = 2987 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N04D9 = 2988 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D1 = 2989 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D2 = 2990 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D3 = 2991 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D4 = 2992 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D5 = 2993 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D6 = 2994 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D7 = 2995 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D8 = 2996 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N05D9 = 2997 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D1 = 2998 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D2 = 2999 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D3 = 3000 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D4 = 3001 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D5 = 3002 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D6 = 3003 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D7 = 3004 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D8 = 3005 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N06D9 = 3006 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D1 = 3007 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D2 = 3008 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D3 = 3009 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D4 = 3010 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D5 = 3011 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D6 = 3012 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D7 = 3013 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D8 = 3014 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N07D9 = 3015 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D1 = 3016 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D2 = 3017 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D3 = 3018 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D4 = 3019 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D5 = 3020 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D6 = 3021 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D7 = 3022 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D8 = 3023 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N08D9 = 3024 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D1 = 3025 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D2 = 3026 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D3 = 3027 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D4 = 3028 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D5 = 3029 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D6 = 3030 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D7 = 3031 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D8 = 3032 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N09D9 = 3033 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D1 = 3034 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D2 = 3035 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D3 = 3036 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D4 = 3037 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D5 = 3038 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D6 = 3039 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D7 = 3040 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D8 = 3041 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N10D9 = 3042 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D1 = 3043 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D2 = 3044 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D3 = 3045 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D4 = 3046 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D5 = 3047 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D6 = 3048 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D7 = 3049 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D8 = 3050 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N11D9 = 3051 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D1 = 3052 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D2 = 3053 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D3 = 3054 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D4 = 3055 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D5 = 3056 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D6 = 3057 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D7 = 3058 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D8 = 3059 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N12D9 = 3060 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D1 = 3061 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D2 = 3062 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D3 = 3063 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D4 = 3064 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D5 = 3065 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D6 = 3066 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D7 = 3067 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D8 = 3068 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N13D9 = 3069 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D1 = 3070 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D2 = 3071 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D3 = 3072 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D4 = 3073 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D5 = 3074 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D6 = 3075 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D7 = 3076 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D8 = 3077 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N14D9 = 3078 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D1 = 3079 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D2 = 3080 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D3 = 3081 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D4 = 3082 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D5 = 3083 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D6 = 3084 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D7 = 3085 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D8 = 3086 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N15D9 = 3087 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D1 = 3088 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D2 = 3089 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D3 = 3090 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D4 = 3091 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D5 = 3092 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D6 = 3093 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D7 = 3094 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D8 = 3095 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N16D9 = 3096 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D1 = 3097 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D2 = 3098 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D3 = 3099 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D4 = 3100 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D5 = 3101 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D6 = 3102 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D7 = 3103 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D8 = 3104 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N17D9 = 3105 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D1 = 3106 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D2 = 3107 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D3 = 3108 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D4 = 3109 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D5 = 3110 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D6 = 3111 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D7 = 3112 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D8 = 3113 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N18D9 = 3114 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D1 = 3115 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D2 = 3116 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D3 = 3117 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D4 = 3118 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D5 = 3119 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D6 = 3120 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D7 = 3121 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D8 = 3122 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N19D9 = 3123 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D1 = 3124 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D2 = 3125 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D3 = 3126 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D4 = 3127 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D5 = 3128 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D6 = 3129 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D7 = 3130 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D8 = 3131 + INTEGER(IntKi), PARAMETER :: WkDfVrT1N20D9 = 3132 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D1 = 3133 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D2 = 3134 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D3 = 3135 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D4 = 3136 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D5 = 3137 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D6 = 3138 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D7 = 3139 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D8 = 3140 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N01D9 = 3141 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D1 = 3142 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D2 = 3143 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D3 = 3144 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D4 = 3145 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D5 = 3146 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D6 = 3147 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D7 = 3148 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D8 = 3149 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N02D9 = 3150 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D1 = 3151 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D2 = 3152 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D3 = 3153 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D4 = 3154 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D5 = 3155 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D6 = 3156 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D7 = 3157 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D8 = 3158 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N03D9 = 3159 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D1 = 3160 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D2 = 3161 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D3 = 3162 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D4 = 3163 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D5 = 3164 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D6 = 3165 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D7 = 3166 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D8 = 3167 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N04D9 = 3168 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D1 = 3169 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D2 = 3170 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D3 = 3171 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D4 = 3172 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D5 = 3173 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D6 = 3174 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D7 = 3175 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D8 = 3176 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N05D9 = 3177 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D1 = 3178 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D2 = 3179 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D3 = 3180 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D4 = 3181 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D5 = 3182 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D6 = 3183 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D7 = 3184 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D8 = 3185 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N06D9 = 3186 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D1 = 3187 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D2 = 3188 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D3 = 3189 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D4 = 3190 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D5 = 3191 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D6 = 3192 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D7 = 3193 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D8 = 3194 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N07D9 = 3195 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D1 = 3196 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D2 = 3197 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D3 = 3198 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D4 = 3199 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D5 = 3200 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D6 = 3201 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D7 = 3202 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D8 = 3203 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N08D9 = 3204 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D1 = 3205 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D2 = 3206 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D3 = 3207 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D4 = 3208 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D5 = 3209 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D6 = 3210 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D7 = 3211 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D8 = 3212 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N09D9 = 3213 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D1 = 3214 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D2 = 3215 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D3 = 3216 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D4 = 3217 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D5 = 3218 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D6 = 3219 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D7 = 3220 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D8 = 3221 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N10D9 = 3222 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D1 = 3223 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D2 = 3224 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D3 = 3225 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D4 = 3226 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D5 = 3227 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D6 = 3228 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D7 = 3229 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D8 = 3230 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N11D9 = 3231 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D1 = 3232 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D2 = 3233 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D3 = 3234 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D4 = 3235 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D5 = 3236 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D6 = 3237 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D7 = 3238 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D8 = 3239 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N12D9 = 3240 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D1 = 3241 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D2 = 3242 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D3 = 3243 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D4 = 3244 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D5 = 3245 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D6 = 3246 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D7 = 3247 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D8 = 3248 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N13D9 = 3249 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D1 = 3250 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D2 = 3251 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D3 = 3252 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D4 = 3253 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D5 = 3254 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D6 = 3255 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D7 = 3256 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D8 = 3257 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N14D9 = 3258 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D1 = 3259 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D2 = 3260 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D3 = 3261 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D4 = 3262 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D5 = 3263 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D6 = 3264 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D7 = 3265 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D8 = 3266 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N15D9 = 3267 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D1 = 3268 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D2 = 3269 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D3 = 3270 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D4 = 3271 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D5 = 3272 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D6 = 3273 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D7 = 3274 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D8 = 3275 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N16D9 = 3276 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D1 = 3277 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D2 = 3278 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D3 = 3279 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D4 = 3280 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D5 = 3281 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D6 = 3282 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D7 = 3283 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D8 = 3284 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N17D9 = 3285 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D1 = 3286 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D2 = 3287 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D3 = 3288 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D4 = 3289 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D5 = 3290 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D6 = 3291 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D7 = 3292 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D8 = 3293 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N18D9 = 3294 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D1 = 3295 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D2 = 3296 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D3 = 3297 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D4 = 3298 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D5 = 3299 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D6 = 3300 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D7 = 3301 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D8 = 3302 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N19D9 = 3303 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D1 = 3304 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D2 = 3305 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D3 = 3306 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D4 = 3307 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D5 = 3308 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D6 = 3309 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D7 = 3310 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D8 = 3311 + INTEGER(IntKi), PARAMETER :: WkDfVrT2N20D9 = 3312 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D1 = 3313 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D2 = 3314 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D3 = 3315 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D4 = 3316 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D5 = 3317 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D6 = 3318 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D7 = 3319 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D8 = 3320 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N01D9 = 3321 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D1 = 3322 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D2 = 3323 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D3 = 3324 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D4 = 3325 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D5 = 3326 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D6 = 3327 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D7 = 3328 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D8 = 3329 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N02D9 = 3330 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D1 = 3331 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D2 = 3332 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D3 = 3333 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D4 = 3334 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D5 = 3335 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D6 = 3336 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D7 = 3337 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D8 = 3338 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N03D9 = 3339 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D1 = 3340 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D2 = 3341 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D3 = 3342 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D4 = 3343 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D5 = 3344 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D6 = 3345 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D7 = 3346 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D8 = 3347 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N04D9 = 3348 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D1 = 3349 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D2 = 3350 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D3 = 3351 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D4 = 3352 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D5 = 3353 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D6 = 3354 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D7 = 3355 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D8 = 3356 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N05D9 = 3357 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D1 = 3358 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D2 = 3359 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D3 = 3360 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D4 = 3361 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D5 = 3362 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D6 = 3363 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D7 = 3364 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D8 = 3365 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N06D9 = 3366 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D1 = 3367 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D2 = 3368 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D3 = 3369 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D4 = 3370 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D5 = 3371 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D6 = 3372 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D7 = 3373 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D8 = 3374 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N07D9 = 3375 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D1 = 3376 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D2 = 3377 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D3 = 3378 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D4 = 3379 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D5 = 3380 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D6 = 3381 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D7 = 3382 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D8 = 3383 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N08D9 = 3384 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D1 = 3385 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D2 = 3386 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D3 = 3387 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D4 = 3388 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D5 = 3389 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D6 = 3390 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D7 = 3391 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D8 = 3392 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N09D9 = 3393 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D1 = 3394 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D2 = 3395 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D3 = 3396 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D4 = 3397 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D5 = 3398 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D6 = 3399 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D7 = 3400 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D8 = 3401 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N10D9 = 3402 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D1 = 3403 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D2 = 3404 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D3 = 3405 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D4 = 3406 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D5 = 3407 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D6 = 3408 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D7 = 3409 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D8 = 3410 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N11D9 = 3411 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D1 = 3412 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D2 = 3413 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D3 = 3414 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D4 = 3415 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D5 = 3416 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D6 = 3417 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D7 = 3418 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D8 = 3419 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N12D9 = 3420 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D1 = 3421 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D2 = 3422 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D3 = 3423 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D4 = 3424 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D5 = 3425 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D6 = 3426 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D7 = 3427 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D8 = 3428 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N13D9 = 3429 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D1 = 3430 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D2 = 3431 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D3 = 3432 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D4 = 3433 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D5 = 3434 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D6 = 3435 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D7 = 3436 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D8 = 3437 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N14D9 = 3438 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D1 = 3439 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D2 = 3440 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D3 = 3441 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D4 = 3442 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D5 = 3443 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D6 = 3444 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D7 = 3445 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D8 = 3446 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N15D9 = 3447 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D1 = 3448 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D2 = 3449 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D3 = 3450 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D4 = 3451 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D5 = 3452 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D6 = 3453 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D7 = 3454 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D8 = 3455 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N16D9 = 3456 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D1 = 3457 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D2 = 3458 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D3 = 3459 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D4 = 3460 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D5 = 3461 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D6 = 3462 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D7 = 3463 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D8 = 3464 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N17D9 = 3465 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D1 = 3466 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D2 = 3467 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D3 = 3468 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D4 = 3469 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D5 = 3470 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D6 = 3471 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D7 = 3472 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D8 = 3473 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N18D9 = 3474 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D1 = 3475 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D2 = 3476 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D3 = 3477 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D4 = 3478 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D5 = 3479 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D6 = 3480 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D7 = 3481 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D8 = 3482 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N19D9 = 3483 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D1 = 3484 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D2 = 3485 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D3 = 3486 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D4 = 3487 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D5 = 3488 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D6 = 3489 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D7 = 3490 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D8 = 3491 + INTEGER(IntKi), PARAMETER :: WkDfVrT3N20D9 = 3492 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D1 = 3493 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D2 = 3494 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D3 = 3495 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D4 = 3496 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D5 = 3497 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D6 = 3498 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D7 = 3499 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D8 = 3500 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N01D9 = 3501 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D1 = 3502 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D2 = 3503 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D3 = 3504 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D4 = 3505 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D5 = 3506 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D6 = 3507 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D7 = 3508 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D8 = 3509 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N02D9 = 3510 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D1 = 3511 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D2 = 3512 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D3 = 3513 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D4 = 3514 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D5 = 3515 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D6 = 3516 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D7 = 3517 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D8 = 3518 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N03D9 = 3519 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D1 = 3520 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D2 = 3521 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D3 = 3522 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D4 = 3523 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D5 = 3524 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D6 = 3525 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D7 = 3526 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D8 = 3527 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N04D9 = 3528 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D1 = 3529 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D2 = 3530 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D3 = 3531 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D4 = 3532 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D5 = 3533 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D6 = 3534 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D7 = 3535 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D8 = 3536 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N05D9 = 3537 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D1 = 3538 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D2 = 3539 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D3 = 3540 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D4 = 3541 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D5 = 3542 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D6 = 3543 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D7 = 3544 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D8 = 3545 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N06D9 = 3546 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D1 = 3547 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D2 = 3548 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D3 = 3549 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D4 = 3550 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D5 = 3551 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D6 = 3552 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D7 = 3553 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D8 = 3554 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N07D9 = 3555 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D1 = 3556 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D2 = 3557 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D3 = 3558 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D4 = 3559 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D5 = 3560 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D6 = 3561 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D7 = 3562 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D8 = 3563 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N08D9 = 3564 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D1 = 3565 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D2 = 3566 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D3 = 3567 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D4 = 3568 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D5 = 3569 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D6 = 3570 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D7 = 3571 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D8 = 3572 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N09D9 = 3573 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D1 = 3574 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D2 = 3575 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D3 = 3576 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D4 = 3577 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D5 = 3578 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D6 = 3579 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D7 = 3580 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D8 = 3581 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N10D9 = 3582 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D1 = 3583 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D2 = 3584 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D3 = 3585 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D4 = 3586 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D5 = 3587 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D6 = 3588 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D7 = 3589 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D8 = 3590 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N11D9 = 3591 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D1 = 3592 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D2 = 3593 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D3 = 3594 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D4 = 3595 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D5 = 3596 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D6 = 3597 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D7 = 3598 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D8 = 3599 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N12D9 = 3600 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D1 = 3601 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D2 = 3602 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D3 = 3603 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D4 = 3604 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D5 = 3605 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D6 = 3606 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D7 = 3607 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D8 = 3608 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N13D9 = 3609 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D1 = 3610 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D2 = 3611 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D3 = 3612 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D4 = 3613 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D5 = 3614 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D6 = 3615 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D7 = 3616 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D8 = 3617 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N14D9 = 3618 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D1 = 3619 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D2 = 3620 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D3 = 3621 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D4 = 3622 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D5 = 3623 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D6 = 3624 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D7 = 3625 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D8 = 3626 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N15D9 = 3627 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D1 = 3628 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D2 = 3629 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D3 = 3630 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D4 = 3631 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D5 = 3632 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D6 = 3633 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D7 = 3634 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D8 = 3635 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N16D9 = 3636 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D1 = 3637 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D2 = 3638 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D3 = 3639 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D4 = 3640 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D5 = 3641 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D6 = 3642 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D7 = 3643 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D8 = 3644 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N17D9 = 3645 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D1 = 3646 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D2 = 3647 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D3 = 3648 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D4 = 3649 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D5 = 3650 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D6 = 3651 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D7 = 3652 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D8 = 3653 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N18D9 = 3654 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D1 = 3655 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D2 = 3656 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D3 = 3657 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D4 = 3658 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D5 = 3659 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D6 = 3660 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D7 = 3661 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D8 = 3662 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N19D9 = 3663 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D1 = 3664 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D2 = 3665 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D3 = 3666 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D4 = 3667 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D5 = 3668 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D6 = 3669 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D7 = 3670 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D8 = 3671 + INTEGER(IntKi), PARAMETER :: WkDfVrT4N20D9 = 3672 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D1 = 3673 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D2 = 3674 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D3 = 3675 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D4 = 3676 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D5 = 3677 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D6 = 3678 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D7 = 3679 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D8 = 3680 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N01D9 = 3681 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D1 = 3682 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D2 = 3683 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D3 = 3684 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D4 = 3685 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D5 = 3686 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D6 = 3687 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D7 = 3688 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D8 = 3689 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N02D9 = 3690 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D1 = 3691 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D2 = 3692 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D3 = 3693 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D4 = 3694 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D5 = 3695 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D6 = 3696 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D7 = 3697 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D8 = 3698 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N03D9 = 3699 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D1 = 3700 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D2 = 3701 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D3 = 3702 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D4 = 3703 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D5 = 3704 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D6 = 3705 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D7 = 3706 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D8 = 3707 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N04D9 = 3708 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D1 = 3709 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D2 = 3710 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D3 = 3711 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D4 = 3712 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D5 = 3713 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D6 = 3714 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D7 = 3715 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D8 = 3716 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N05D9 = 3717 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D1 = 3718 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D2 = 3719 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D3 = 3720 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D4 = 3721 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D5 = 3722 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D6 = 3723 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D7 = 3724 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D8 = 3725 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N06D9 = 3726 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D1 = 3727 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D2 = 3728 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D3 = 3729 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D4 = 3730 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D5 = 3731 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D6 = 3732 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D7 = 3733 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D8 = 3734 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N07D9 = 3735 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D1 = 3736 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D2 = 3737 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D3 = 3738 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D4 = 3739 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D5 = 3740 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D6 = 3741 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D7 = 3742 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D8 = 3743 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N08D9 = 3744 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D1 = 3745 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D2 = 3746 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D3 = 3747 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D4 = 3748 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D5 = 3749 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D6 = 3750 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D7 = 3751 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D8 = 3752 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N09D9 = 3753 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D1 = 3754 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D2 = 3755 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D3 = 3756 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D4 = 3757 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D5 = 3758 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D6 = 3759 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D7 = 3760 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D8 = 3761 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N10D9 = 3762 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D1 = 3763 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D2 = 3764 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D3 = 3765 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D4 = 3766 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D5 = 3767 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D6 = 3768 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D7 = 3769 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D8 = 3770 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N11D9 = 3771 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D1 = 3772 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D2 = 3773 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D3 = 3774 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D4 = 3775 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D5 = 3776 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D6 = 3777 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D7 = 3778 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D8 = 3779 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N12D9 = 3780 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D1 = 3781 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D2 = 3782 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D3 = 3783 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D4 = 3784 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D5 = 3785 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D6 = 3786 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D7 = 3787 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D8 = 3788 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N13D9 = 3789 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D1 = 3790 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D2 = 3791 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D3 = 3792 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D4 = 3793 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D5 = 3794 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D6 = 3795 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D7 = 3796 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D8 = 3797 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N14D9 = 3798 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D1 = 3799 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D2 = 3800 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D3 = 3801 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D4 = 3802 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D5 = 3803 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D6 = 3804 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D7 = 3805 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D8 = 3806 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N15D9 = 3807 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D1 = 3808 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D2 = 3809 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D3 = 3810 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D4 = 3811 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D5 = 3812 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D6 = 3813 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D7 = 3814 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D8 = 3815 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N16D9 = 3816 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D1 = 3817 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D2 = 3818 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D3 = 3819 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D4 = 3820 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D5 = 3821 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D6 = 3822 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D7 = 3823 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D8 = 3824 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N17D9 = 3825 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D1 = 3826 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D2 = 3827 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D3 = 3828 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D4 = 3829 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D5 = 3830 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D6 = 3831 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D7 = 3832 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D8 = 3833 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N18D9 = 3834 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D1 = 3835 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D2 = 3836 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D3 = 3837 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D4 = 3838 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D5 = 3839 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D6 = 3840 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D7 = 3841 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D8 = 3842 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N19D9 = 3843 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D1 = 3844 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D2 = 3845 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D3 = 3846 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D4 = 3847 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D5 = 3848 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D6 = 3849 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D7 = 3850 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D8 = 3851 + INTEGER(IntKi), PARAMETER :: WkDfVrT5N20D9 = 3852 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D1 = 3853 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D2 = 3854 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D3 = 3855 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D4 = 3856 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D5 = 3857 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D6 = 3858 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D7 = 3859 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D8 = 3860 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N01D9 = 3861 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D1 = 3862 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D2 = 3863 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D3 = 3864 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D4 = 3865 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D5 = 3866 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D6 = 3867 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D7 = 3868 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D8 = 3869 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N02D9 = 3870 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D1 = 3871 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D2 = 3872 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D3 = 3873 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D4 = 3874 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D5 = 3875 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D6 = 3876 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D7 = 3877 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D8 = 3878 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N03D9 = 3879 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D1 = 3880 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D2 = 3881 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D3 = 3882 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D4 = 3883 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D5 = 3884 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D6 = 3885 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D7 = 3886 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D8 = 3887 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N04D9 = 3888 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D1 = 3889 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D2 = 3890 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D3 = 3891 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D4 = 3892 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D5 = 3893 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D6 = 3894 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D7 = 3895 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D8 = 3896 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N05D9 = 3897 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D1 = 3898 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D2 = 3899 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D3 = 3900 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D4 = 3901 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D5 = 3902 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D6 = 3903 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D7 = 3904 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D8 = 3905 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N06D9 = 3906 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D1 = 3907 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D2 = 3908 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D3 = 3909 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D4 = 3910 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D5 = 3911 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D6 = 3912 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D7 = 3913 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D8 = 3914 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N07D9 = 3915 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D1 = 3916 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D2 = 3917 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D3 = 3918 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D4 = 3919 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D5 = 3920 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D6 = 3921 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D7 = 3922 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D8 = 3923 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N08D9 = 3924 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D1 = 3925 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D2 = 3926 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D3 = 3927 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D4 = 3928 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D5 = 3929 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D6 = 3930 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D7 = 3931 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D8 = 3932 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N09D9 = 3933 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D1 = 3934 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D2 = 3935 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D3 = 3936 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D4 = 3937 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D5 = 3938 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D6 = 3939 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D7 = 3940 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D8 = 3941 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N10D9 = 3942 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D1 = 3943 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D2 = 3944 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D3 = 3945 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D4 = 3946 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D5 = 3947 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D6 = 3948 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D7 = 3949 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D8 = 3950 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N11D9 = 3951 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D1 = 3952 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D2 = 3953 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D3 = 3954 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D4 = 3955 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D5 = 3956 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D6 = 3957 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D7 = 3958 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D8 = 3959 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N12D9 = 3960 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D1 = 3961 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D2 = 3962 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D3 = 3963 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D4 = 3964 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D5 = 3965 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D6 = 3966 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D7 = 3967 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D8 = 3968 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N13D9 = 3969 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D1 = 3970 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D2 = 3971 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D3 = 3972 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D4 = 3973 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D5 = 3974 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D6 = 3975 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D7 = 3976 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D8 = 3977 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N14D9 = 3978 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D1 = 3979 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D2 = 3980 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D3 = 3981 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D4 = 3982 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D5 = 3983 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D6 = 3984 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D7 = 3985 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D8 = 3986 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N15D9 = 3987 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D1 = 3988 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D2 = 3989 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D3 = 3990 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D4 = 3991 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D5 = 3992 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D6 = 3993 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D7 = 3994 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D8 = 3995 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N16D9 = 3996 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D1 = 3997 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D2 = 3998 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D3 = 3999 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D4 = 4000 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D5 = 4001 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D6 = 4002 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D7 = 4003 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D8 = 4004 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N17D9 = 4005 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D1 = 4006 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D2 = 4007 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D3 = 4008 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D4 = 4009 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D5 = 4010 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D6 = 4011 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D7 = 4012 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D8 = 4013 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N18D9 = 4014 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D1 = 4015 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D2 = 4016 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D3 = 4017 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D4 = 4018 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D5 = 4019 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D6 = 4020 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D7 = 4021 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D8 = 4022 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N19D9 = 4023 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D1 = 4024 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D2 = 4025 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D3 = 4026 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D4 = 4027 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D5 = 4028 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D6 = 4029 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D7 = 4030 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D8 = 4031 + INTEGER(IntKi), PARAMETER :: WkDfVrT6N20D9 = 4032 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D1 = 4033 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D2 = 4034 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D3 = 4035 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D4 = 4036 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D5 = 4037 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D6 = 4038 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D7 = 4039 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D8 = 4040 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N01D9 = 4041 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D1 = 4042 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D2 = 4043 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D3 = 4044 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D4 = 4045 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D5 = 4046 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D6 = 4047 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D7 = 4048 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D8 = 4049 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N02D9 = 4050 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D1 = 4051 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D2 = 4052 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D3 = 4053 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D4 = 4054 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D5 = 4055 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D6 = 4056 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D7 = 4057 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D8 = 4058 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N03D9 = 4059 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D1 = 4060 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D2 = 4061 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D3 = 4062 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D4 = 4063 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D5 = 4064 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D6 = 4065 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D7 = 4066 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D8 = 4067 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N04D9 = 4068 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D1 = 4069 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D2 = 4070 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D3 = 4071 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D4 = 4072 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D5 = 4073 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D6 = 4074 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D7 = 4075 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D8 = 4076 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N05D9 = 4077 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D1 = 4078 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D2 = 4079 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D3 = 4080 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D4 = 4081 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D5 = 4082 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D6 = 4083 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D7 = 4084 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D8 = 4085 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N06D9 = 4086 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D1 = 4087 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D2 = 4088 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D3 = 4089 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D4 = 4090 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D5 = 4091 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D6 = 4092 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D7 = 4093 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D8 = 4094 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N07D9 = 4095 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D1 = 4096 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D2 = 4097 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D3 = 4098 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D4 = 4099 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D5 = 4100 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D6 = 4101 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D7 = 4102 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D8 = 4103 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N08D9 = 4104 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D1 = 4105 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D2 = 4106 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D3 = 4107 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D4 = 4108 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D5 = 4109 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D6 = 4110 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D7 = 4111 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D8 = 4112 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N09D9 = 4113 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D1 = 4114 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D2 = 4115 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D3 = 4116 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D4 = 4117 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D5 = 4118 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D6 = 4119 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D7 = 4120 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D8 = 4121 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N10D9 = 4122 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D1 = 4123 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D2 = 4124 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D3 = 4125 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D4 = 4126 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D5 = 4127 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D6 = 4128 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D7 = 4129 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D8 = 4130 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N11D9 = 4131 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D1 = 4132 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D2 = 4133 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D3 = 4134 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D4 = 4135 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D5 = 4136 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D6 = 4137 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D7 = 4138 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D8 = 4139 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N12D9 = 4140 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D1 = 4141 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D2 = 4142 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D3 = 4143 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D4 = 4144 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D5 = 4145 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D6 = 4146 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D7 = 4147 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D8 = 4148 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N13D9 = 4149 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D1 = 4150 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D2 = 4151 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D3 = 4152 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D4 = 4153 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D5 = 4154 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D6 = 4155 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D7 = 4156 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D8 = 4157 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N14D9 = 4158 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D1 = 4159 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D2 = 4160 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D3 = 4161 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D4 = 4162 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D5 = 4163 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D6 = 4164 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D7 = 4165 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D8 = 4166 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N15D9 = 4167 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D1 = 4168 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D2 = 4169 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D3 = 4170 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D4 = 4171 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D5 = 4172 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D6 = 4173 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D7 = 4174 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D8 = 4175 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N16D9 = 4176 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D1 = 4177 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D2 = 4178 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D3 = 4179 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D4 = 4180 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D5 = 4181 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D6 = 4182 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D7 = 4183 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D8 = 4184 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N17D9 = 4185 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D1 = 4186 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D2 = 4187 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D3 = 4188 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D4 = 4189 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D5 = 4190 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D6 = 4191 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D7 = 4192 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D8 = 4193 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N18D9 = 4194 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D1 = 4195 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D2 = 4196 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D3 = 4197 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D4 = 4198 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D5 = 4199 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D6 = 4200 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D7 = 4201 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D8 = 4202 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N19D9 = 4203 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D1 = 4204 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D2 = 4205 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D3 = 4206 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D4 = 4207 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D5 = 4208 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D6 = 4209 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D7 = 4210 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D8 = 4211 + INTEGER(IntKi), PARAMETER :: WkDfVrT7N20D9 = 4212 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D1 = 4213 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D2 = 4214 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D3 = 4215 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D4 = 4216 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D5 = 4217 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D6 = 4218 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D7 = 4219 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D8 = 4220 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N01D9 = 4221 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D1 = 4222 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D2 = 4223 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D3 = 4224 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D4 = 4225 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D5 = 4226 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D6 = 4227 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D7 = 4228 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D8 = 4229 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N02D9 = 4230 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D1 = 4231 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D2 = 4232 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D3 = 4233 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D4 = 4234 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D5 = 4235 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D6 = 4236 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D7 = 4237 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D8 = 4238 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N03D9 = 4239 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D1 = 4240 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D2 = 4241 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D3 = 4242 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D4 = 4243 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D5 = 4244 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D6 = 4245 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D7 = 4246 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D8 = 4247 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N04D9 = 4248 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D1 = 4249 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D2 = 4250 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D3 = 4251 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D4 = 4252 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D5 = 4253 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D6 = 4254 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D7 = 4255 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D8 = 4256 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N05D9 = 4257 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D1 = 4258 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D2 = 4259 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D3 = 4260 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D4 = 4261 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D5 = 4262 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D6 = 4263 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D7 = 4264 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D8 = 4265 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N06D9 = 4266 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D1 = 4267 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D2 = 4268 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D3 = 4269 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D4 = 4270 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D5 = 4271 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D6 = 4272 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D7 = 4273 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D8 = 4274 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N07D9 = 4275 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D1 = 4276 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D2 = 4277 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D3 = 4278 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D4 = 4279 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D5 = 4280 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D6 = 4281 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D7 = 4282 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D8 = 4283 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N08D9 = 4284 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D1 = 4285 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D2 = 4286 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D3 = 4287 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D4 = 4288 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D5 = 4289 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D6 = 4290 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D7 = 4291 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D8 = 4292 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N09D9 = 4293 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D1 = 4294 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D2 = 4295 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D3 = 4296 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D4 = 4297 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D5 = 4298 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D6 = 4299 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D7 = 4300 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D8 = 4301 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N10D9 = 4302 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D1 = 4303 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D2 = 4304 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D3 = 4305 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D4 = 4306 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D5 = 4307 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D6 = 4308 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D7 = 4309 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D8 = 4310 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N11D9 = 4311 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D1 = 4312 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D2 = 4313 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D3 = 4314 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D4 = 4315 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D5 = 4316 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D6 = 4317 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D7 = 4318 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D8 = 4319 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N12D9 = 4320 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D1 = 4321 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D2 = 4322 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D3 = 4323 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D4 = 4324 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D5 = 4325 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D6 = 4326 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D7 = 4327 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D8 = 4328 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N13D9 = 4329 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D1 = 4330 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D2 = 4331 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D3 = 4332 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D4 = 4333 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D5 = 4334 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D6 = 4335 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D7 = 4336 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D8 = 4337 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N14D9 = 4338 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D1 = 4339 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D2 = 4340 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D3 = 4341 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D4 = 4342 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D5 = 4343 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D6 = 4344 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D7 = 4345 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D8 = 4346 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N15D9 = 4347 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D1 = 4348 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D2 = 4349 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D3 = 4350 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D4 = 4351 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D5 = 4352 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D6 = 4353 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D7 = 4354 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D8 = 4355 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N16D9 = 4356 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D1 = 4357 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D2 = 4358 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D3 = 4359 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D4 = 4360 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D5 = 4361 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D6 = 4362 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D7 = 4363 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D8 = 4364 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N17D9 = 4365 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D1 = 4366 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D2 = 4367 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D3 = 4368 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D4 = 4369 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D5 = 4370 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D6 = 4371 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D7 = 4372 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D8 = 4373 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N18D9 = 4374 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D1 = 4375 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D2 = 4376 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D3 = 4377 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D4 = 4378 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D5 = 4379 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D6 = 4380 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D7 = 4381 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D8 = 4382 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N19D9 = 4383 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D1 = 4384 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D2 = 4385 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D3 = 4386 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D4 = 4387 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D5 = 4388 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D6 = 4389 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D7 = 4390 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D8 = 4391 + INTEGER(IntKi), PARAMETER :: WkDfVrT8N20D9 = 4392 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D1 = 4393 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D2 = 4394 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D3 = 4395 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D4 = 4396 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D5 = 4397 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D6 = 4398 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D7 = 4399 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D8 = 4400 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N01D9 = 4401 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D1 = 4402 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D2 = 4403 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D3 = 4404 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D4 = 4405 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D5 = 4406 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D6 = 4407 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D7 = 4408 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D8 = 4409 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N02D9 = 4410 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D1 = 4411 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D2 = 4412 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D3 = 4413 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D4 = 4414 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D5 = 4415 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D6 = 4416 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D7 = 4417 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D8 = 4418 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N03D9 = 4419 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D1 = 4420 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D2 = 4421 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D3 = 4422 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D4 = 4423 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D5 = 4424 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D6 = 4425 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D7 = 4426 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D8 = 4427 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N04D9 = 4428 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D1 = 4429 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D2 = 4430 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D3 = 4431 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D4 = 4432 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D5 = 4433 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D6 = 4434 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D7 = 4435 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D8 = 4436 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N05D9 = 4437 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D1 = 4438 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D2 = 4439 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D3 = 4440 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D4 = 4441 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D5 = 4442 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D6 = 4443 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D7 = 4444 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D8 = 4445 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N06D9 = 4446 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D1 = 4447 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D2 = 4448 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D3 = 4449 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D4 = 4450 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D5 = 4451 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D6 = 4452 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D7 = 4453 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D8 = 4454 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N07D9 = 4455 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D1 = 4456 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D2 = 4457 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D3 = 4458 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D4 = 4459 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D5 = 4460 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D6 = 4461 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D7 = 4462 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D8 = 4463 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N08D9 = 4464 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D1 = 4465 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D2 = 4466 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D3 = 4467 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D4 = 4468 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D5 = 4469 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D6 = 4470 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D7 = 4471 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D8 = 4472 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N09D9 = 4473 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D1 = 4474 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D2 = 4475 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D3 = 4476 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D4 = 4477 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D5 = 4478 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D6 = 4479 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D7 = 4480 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D8 = 4481 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N10D9 = 4482 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D1 = 4483 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D2 = 4484 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D3 = 4485 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D4 = 4486 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D5 = 4487 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D6 = 4488 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D7 = 4489 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D8 = 4490 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N11D9 = 4491 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D1 = 4492 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D2 = 4493 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D3 = 4494 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D4 = 4495 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D5 = 4496 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D6 = 4497 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D7 = 4498 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D8 = 4499 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N12D9 = 4500 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D1 = 4501 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D2 = 4502 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D3 = 4503 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D4 = 4504 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D5 = 4505 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D6 = 4506 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D7 = 4507 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D8 = 4508 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N13D9 = 4509 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D1 = 4510 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D2 = 4511 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D3 = 4512 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D4 = 4513 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D5 = 4514 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D6 = 4515 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D7 = 4516 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D8 = 4517 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N14D9 = 4518 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D1 = 4519 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D2 = 4520 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D3 = 4521 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D4 = 4522 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D5 = 4523 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D6 = 4524 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D7 = 4525 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D8 = 4526 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N15D9 = 4527 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D1 = 4528 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D2 = 4529 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D3 = 4530 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D4 = 4531 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D5 = 4532 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D6 = 4533 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D7 = 4534 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D8 = 4535 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N16D9 = 4536 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D1 = 4537 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D2 = 4538 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D3 = 4539 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D4 = 4540 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D5 = 4541 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D6 = 4542 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D7 = 4543 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D8 = 4544 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N17D9 = 4545 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D1 = 4546 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D2 = 4547 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D3 = 4548 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D4 = 4549 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D5 = 4550 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D6 = 4551 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D7 = 4552 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D8 = 4553 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N18D9 = 4554 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D1 = 4555 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D2 = 4556 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D3 = 4557 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D4 = 4558 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D5 = 4559 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D6 = 4560 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D7 = 4561 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D8 = 4562 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N19D9 = 4563 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D1 = 4564 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D2 = 4565 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D3 = 4566 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D4 = 4567 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D5 = 4568 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D6 = 4569 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D7 = 4570 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D8 = 4571 + INTEGER(IntKi), PARAMETER :: WkDfVrT9N20D9 = 4572 + + + ! Total eddy viscosity: + + INTEGER(IntKi), PARAMETER :: EddVisT1N01D1 = 4573 + INTEGER(IntKi), PARAMETER :: EddVisT1N01D2 = 4574 + INTEGER(IntKi), PARAMETER :: EddVisT1N01D3 = 4575 + INTEGER(IntKi), PARAMETER :: EddVisT1N01D4 = 4576 + INTEGER(IntKi), PARAMETER :: EddVisT1N01D5 = 4577 + INTEGER(IntKi), PARAMETER :: EddVisT1N01D6 = 4578 + INTEGER(IntKi), PARAMETER :: EddVisT1N01D7 = 4579 + INTEGER(IntKi), PARAMETER :: EddVisT1N01D8 = 4580 + INTEGER(IntKi), PARAMETER :: EddVisT1N01D9 = 4581 + INTEGER(IntKi), PARAMETER :: EddVisT1N02D1 = 4582 + INTEGER(IntKi), PARAMETER :: EddVisT1N02D2 = 4583 + INTEGER(IntKi), PARAMETER :: EddVisT1N02D3 = 4584 + INTEGER(IntKi), PARAMETER :: EddVisT1N02D4 = 4585 + INTEGER(IntKi), PARAMETER :: EddVisT1N02D5 = 4586 + INTEGER(IntKi), PARAMETER :: EddVisT1N02D6 = 4587 + INTEGER(IntKi), PARAMETER :: EddVisT1N02D7 = 4588 + INTEGER(IntKi), PARAMETER :: EddVisT1N02D8 = 4589 + INTEGER(IntKi), PARAMETER :: EddVisT1N02D9 = 4590 + INTEGER(IntKi), PARAMETER :: EddVisT1N03D1 = 4591 + INTEGER(IntKi), PARAMETER :: EddVisT1N03D2 = 4592 + INTEGER(IntKi), PARAMETER :: EddVisT1N03D3 = 4593 + INTEGER(IntKi), PARAMETER :: EddVisT1N03D4 = 4594 + INTEGER(IntKi), PARAMETER :: EddVisT1N03D5 = 4595 + INTEGER(IntKi), PARAMETER :: EddVisT1N03D6 = 4596 + INTEGER(IntKi), PARAMETER :: EddVisT1N03D7 = 4597 + INTEGER(IntKi), PARAMETER :: EddVisT1N03D8 = 4598 + INTEGER(IntKi), PARAMETER :: EddVisT1N03D9 = 4599 + INTEGER(IntKi), PARAMETER :: EddVisT1N04D1 = 4600 + INTEGER(IntKi), PARAMETER :: EddVisT1N04D2 = 4601 + INTEGER(IntKi), PARAMETER :: EddVisT1N04D3 = 4602 + INTEGER(IntKi), PARAMETER :: EddVisT1N04D4 = 4603 + INTEGER(IntKi), PARAMETER :: EddVisT1N04D5 = 4604 + INTEGER(IntKi), PARAMETER :: EddVisT1N04D6 = 4605 + INTEGER(IntKi), PARAMETER :: EddVisT1N04D7 = 4606 + INTEGER(IntKi), PARAMETER :: EddVisT1N04D8 = 4607 + INTEGER(IntKi), PARAMETER :: EddVisT1N04D9 = 4608 + INTEGER(IntKi), PARAMETER :: EddVisT1N05D1 = 4609 + INTEGER(IntKi), PARAMETER :: EddVisT1N05D2 = 4610 + INTEGER(IntKi), PARAMETER :: EddVisT1N05D3 = 4611 + INTEGER(IntKi), PARAMETER :: EddVisT1N05D4 = 4612 + INTEGER(IntKi), PARAMETER :: EddVisT1N05D5 = 4613 + INTEGER(IntKi), PARAMETER :: EddVisT1N05D6 = 4614 + INTEGER(IntKi), PARAMETER :: EddVisT1N05D7 = 4615 + INTEGER(IntKi), PARAMETER :: EddVisT1N05D8 = 4616 + INTEGER(IntKi), PARAMETER :: EddVisT1N05D9 = 4617 + INTEGER(IntKi), PARAMETER :: EddVisT1N06D1 = 4618 + INTEGER(IntKi), PARAMETER :: EddVisT1N06D2 = 4619 + INTEGER(IntKi), PARAMETER :: EddVisT1N06D3 = 4620 + INTEGER(IntKi), PARAMETER :: EddVisT1N06D4 = 4621 + INTEGER(IntKi), PARAMETER :: EddVisT1N06D5 = 4622 + INTEGER(IntKi), PARAMETER :: EddVisT1N06D6 = 4623 + INTEGER(IntKi), PARAMETER :: EddVisT1N06D7 = 4624 + INTEGER(IntKi), PARAMETER :: EddVisT1N06D8 = 4625 + INTEGER(IntKi), PARAMETER :: EddVisT1N06D9 = 4626 + INTEGER(IntKi), PARAMETER :: EddVisT1N07D1 = 4627 + INTEGER(IntKi), PARAMETER :: EddVisT1N07D2 = 4628 + INTEGER(IntKi), PARAMETER :: EddVisT1N07D3 = 4629 + INTEGER(IntKi), PARAMETER :: EddVisT1N07D4 = 4630 + INTEGER(IntKi), PARAMETER :: EddVisT1N07D5 = 4631 + INTEGER(IntKi), PARAMETER :: EddVisT1N07D6 = 4632 + INTEGER(IntKi), PARAMETER :: EddVisT1N07D7 = 4633 + INTEGER(IntKi), PARAMETER :: EddVisT1N07D8 = 4634 + INTEGER(IntKi), PARAMETER :: EddVisT1N07D9 = 4635 + INTEGER(IntKi), PARAMETER :: EddVisT1N08D1 = 4636 + INTEGER(IntKi), PARAMETER :: EddVisT1N08D2 = 4637 + INTEGER(IntKi), PARAMETER :: EddVisT1N08D3 = 4638 + INTEGER(IntKi), PARAMETER :: EddVisT1N08D4 = 4639 + INTEGER(IntKi), PARAMETER :: EddVisT1N08D5 = 4640 + INTEGER(IntKi), PARAMETER :: EddVisT1N08D6 = 4641 + INTEGER(IntKi), PARAMETER :: EddVisT1N08D7 = 4642 + INTEGER(IntKi), PARAMETER :: EddVisT1N08D8 = 4643 + INTEGER(IntKi), PARAMETER :: EddVisT1N08D9 = 4644 + INTEGER(IntKi), PARAMETER :: EddVisT1N09D1 = 4645 + INTEGER(IntKi), PARAMETER :: EddVisT1N09D2 = 4646 + INTEGER(IntKi), PARAMETER :: EddVisT1N09D3 = 4647 + INTEGER(IntKi), PARAMETER :: EddVisT1N09D4 = 4648 + INTEGER(IntKi), PARAMETER :: EddVisT1N09D5 = 4649 + INTEGER(IntKi), PARAMETER :: EddVisT1N09D6 = 4650 + INTEGER(IntKi), PARAMETER :: EddVisT1N09D7 = 4651 + INTEGER(IntKi), PARAMETER :: EddVisT1N09D8 = 4652 + INTEGER(IntKi), PARAMETER :: EddVisT1N09D9 = 4653 + INTEGER(IntKi), PARAMETER :: EddVisT1N10D1 = 4654 + INTEGER(IntKi), PARAMETER :: EddVisT1N10D2 = 4655 + INTEGER(IntKi), PARAMETER :: EddVisT1N10D3 = 4656 + INTEGER(IntKi), PARAMETER :: EddVisT1N10D4 = 4657 + INTEGER(IntKi), PARAMETER :: EddVisT1N10D5 = 4658 + INTEGER(IntKi), PARAMETER :: EddVisT1N10D6 = 4659 + INTEGER(IntKi), PARAMETER :: EddVisT1N10D7 = 4660 + INTEGER(IntKi), PARAMETER :: EddVisT1N10D8 = 4661 + INTEGER(IntKi), PARAMETER :: EddVisT1N10D9 = 4662 + INTEGER(IntKi), PARAMETER :: EddVisT1N11D1 = 4663 + INTEGER(IntKi), PARAMETER :: EddVisT1N11D2 = 4664 + INTEGER(IntKi), PARAMETER :: EddVisT1N11D3 = 4665 + INTEGER(IntKi), PARAMETER :: EddVisT1N11D4 = 4666 + INTEGER(IntKi), PARAMETER :: EddVisT1N11D5 = 4667 + INTEGER(IntKi), PARAMETER :: EddVisT1N11D6 = 4668 + INTEGER(IntKi), PARAMETER :: EddVisT1N11D7 = 4669 + INTEGER(IntKi), PARAMETER :: EddVisT1N11D8 = 4670 + INTEGER(IntKi), PARAMETER :: EddVisT1N11D9 = 4671 + INTEGER(IntKi), PARAMETER :: EddVisT1N12D1 = 4672 + INTEGER(IntKi), PARAMETER :: EddVisT1N12D2 = 4673 + INTEGER(IntKi), PARAMETER :: EddVisT1N12D3 = 4674 + INTEGER(IntKi), PARAMETER :: EddVisT1N12D4 = 4675 + INTEGER(IntKi), PARAMETER :: EddVisT1N12D5 = 4676 + INTEGER(IntKi), PARAMETER :: EddVisT1N12D6 = 4677 + INTEGER(IntKi), PARAMETER :: EddVisT1N12D7 = 4678 + INTEGER(IntKi), PARAMETER :: EddVisT1N12D8 = 4679 + INTEGER(IntKi), PARAMETER :: EddVisT1N12D9 = 4680 + INTEGER(IntKi), PARAMETER :: EddVisT1N13D1 = 4681 + INTEGER(IntKi), PARAMETER :: EddVisT1N13D2 = 4682 + INTEGER(IntKi), PARAMETER :: EddVisT1N13D3 = 4683 + INTEGER(IntKi), PARAMETER :: EddVisT1N13D4 = 4684 + INTEGER(IntKi), PARAMETER :: EddVisT1N13D5 = 4685 + INTEGER(IntKi), PARAMETER :: EddVisT1N13D6 = 4686 + INTEGER(IntKi), PARAMETER :: EddVisT1N13D7 = 4687 + INTEGER(IntKi), PARAMETER :: EddVisT1N13D8 = 4688 + INTEGER(IntKi), PARAMETER :: EddVisT1N13D9 = 4689 + INTEGER(IntKi), PARAMETER :: EddVisT1N14D1 = 4690 + INTEGER(IntKi), PARAMETER :: EddVisT1N14D2 = 4691 + INTEGER(IntKi), PARAMETER :: EddVisT1N14D3 = 4692 + INTEGER(IntKi), PARAMETER :: EddVisT1N14D4 = 4693 + INTEGER(IntKi), PARAMETER :: EddVisT1N14D5 = 4694 + INTEGER(IntKi), PARAMETER :: EddVisT1N14D6 = 4695 + INTEGER(IntKi), PARAMETER :: EddVisT1N14D7 = 4696 + INTEGER(IntKi), PARAMETER :: EddVisT1N14D8 = 4697 + INTEGER(IntKi), PARAMETER :: EddVisT1N14D9 = 4698 + INTEGER(IntKi), PARAMETER :: EddVisT1N15D1 = 4699 + INTEGER(IntKi), PARAMETER :: EddVisT1N15D2 = 4700 + INTEGER(IntKi), PARAMETER :: EddVisT1N15D3 = 4701 + INTEGER(IntKi), PARAMETER :: EddVisT1N15D4 = 4702 + INTEGER(IntKi), PARAMETER :: EddVisT1N15D5 = 4703 + INTEGER(IntKi), PARAMETER :: EddVisT1N15D6 = 4704 + INTEGER(IntKi), PARAMETER :: EddVisT1N15D7 = 4705 + INTEGER(IntKi), PARAMETER :: EddVisT1N15D8 = 4706 + INTEGER(IntKi), PARAMETER :: EddVisT1N15D9 = 4707 + INTEGER(IntKi), PARAMETER :: EddVisT1N16D1 = 4708 + INTEGER(IntKi), PARAMETER :: EddVisT1N16D2 = 4709 + INTEGER(IntKi), PARAMETER :: EddVisT1N16D3 = 4710 + INTEGER(IntKi), PARAMETER :: EddVisT1N16D4 = 4711 + INTEGER(IntKi), PARAMETER :: EddVisT1N16D5 = 4712 + INTEGER(IntKi), PARAMETER :: EddVisT1N16D6 = 4713 + INTEGER(IntKi), PARAMETER :: EddVisT1N16D7 = 4714 + INTEGER(IntKi), PARAMETER :: EddVisT1N16D8 = 4715 + INTEGER(IntKi), PARAMETER :: EddVisT1N16D9 = 4716 + INTEGER(IntKi), PARAMETER :: EddVisT1N17D1 = 4717 + INTEGER(IntKi), PARAMETER :: EddVisT1N17D2 = 4718 + INTEGER(IntKi), PARAMETER :: EddVisT1N17D3 = 4719 + INTEGER(IntKi), PARAMETER :: EddVisT1N17D4 = 4720 + INTEGER(IntKi), PARAMETER :: EddVisT1N17D5 = 4721 + INTEGER(IntKi), PARAMETER :: EddVisT1N17D6 = 4722 + INTEGER(IntKi), PARAMETER :: EddVisT1N17D7 = 4723 + INTEGER(IntKi), PARAMETER :: EddVisT1N17D8 = 4724 + INTEGER(IntKi), PARAMETER :: EddVisT1N17D9 = 4725 + INTEGER(IntKi), PARAMETER :: EddVisT1N18D1 = 4726 + INTEGER(IntKi), PARAMETER :: EddVisT1N18D2 = 4727 + INTEGER(IntKi), PARAMETER :: EddVisT1N18D3 = 4728 + INTEGER(IntKi), PARAMETER :: EddVisT1N18D4 = 4729 + INTEGER(IntKi), PARAMETER :: EddVisT1N18D5 = 4730 + INTEGER(IntKi), PARAMETER :: EddVisT1N18D6 = 4731 + INTEGER(IntKi), PARAMETER :: EddVisT1N18D7 = 4732 + INTEGER(IntKi), PARAMETER :: EddVisT1N18D8 = 4733 + INTEGER(IntKi), PARAMETER :: EddVisT1N18D9 = 4734 + INTEGER(IntKi), PARAMETER :: EddVisT1N19D1 = 4735 + INTEGER(IntKi), PARAMETER :: EddVisT1N19D2 = 4736 + INTEGER(IntKi), PARAMETER :: EddVisT1N19D3 = 4737 + INTEGER(IntKi), PARAMETER :: EddVisT1N19D4 = 4738 + INTEGER(IntKi), PARAMETER :: EddVisT1N19D5 = 4739 + INTEGER(IntKi), PARAMETER :: EddVisT1N19D6 = 4740 + INTEGER(IntKi), PARAMETER :: EddVisT1N19D7 = 4741 + INTEGER(IntKi), PARAMETER :: EddVisT1N19D8 = 4742 + INTEGER(IntKi), PARAMETER :: EddVisT1N19D9 = 4743 + INTEGER(IntKi), PARAMETER :: EddVisT1N20D1 = 4744 + INTEGER(IntKi), PARAMETER :: EddVisT1N20D2 = 4745 + INTEGER(IntKi), PARAMETER :: EddVisT1N20D3 = 4746 + INTEGER(IntKi), PARAMETER :: EddVisT1N20D4 = 4747 + INTEGER(IntKi), PARAMETER :: EddVisT1N20D5 = 4748 + INTEGER(IntKi), PARAMETER :: EddVisT1N20D6 = 4749 + INTEGER(IntKi), PARAMETER :: EddVisT1N20D7 = 4750 + INTEGER(IntKi), PARAMETER :: EddVisT1N20D8 = 4751 + INTEGER(IntKi), PARAMETER :: EddVisT1N20D9 = 4752 + INTEGER(IntKi), PARAMETER :: EddVisT2N01D1 = 4753 + INTEGER(IntKi), PARAMETER :: EddVisT2N01D2 = 4754 + INTEGER(IntKi), PARAMETER :: EddVisT2N01D3 = 4755 + INTEGER(IntKi), PARAMETER :: EddVisT2N01D4 = 4756 + INTEGER(IntKi), PARAMETER :: EddVisT2N01D5 = 4757 + INTEGER(IntKi), PARAMETER :: EddVisT2N01D6 = 4758 + INTEGER(IntKi), PARAMETER :: EddVisT2N01D7 = 4759 + INTEGER(IntKi), PARAMETER :: EddVisT2N01D8 = 4760 + INTEGER(IntKi), PARAMETER :: EddVisT2N01D9 = 4761 + INTEGER(IntKi), PARAMETER :: EddVisT2N02D1 = 4762 + INTEGER(IntKi), PARAMETER :: EddVisT2N02D2 = 4763 + INTEGER(IntKi), PARAMETER :: EddVisT2N02D3 = 4764 + INTEGER(IntKi), PARAMETER :: EddVisT2N02D4 = 4765 + INTEGER(IntKi), PARAMETER :: EddVisT2N02D5 = 4766 + INTEGER(IntKi), PARAMETER :: EddVisT2N02D6 = 4767 + INTEGER(IntKi), PARAMETER :: EddVisT2N02D7 = 4768 + INTEGER(IntKi), PARAMETER :: EddVisT2N02D8 = 4769 + INTEGER(IntKi), PARAMETER :: EddVisT2N02D9 = 4770 + INTEGER(IntKi), PARAMETER :: EddVisT2N03D1 = 4771 + INTEGER(IntKi), PARAMETER :: EddVisT2N03D2 = 4772 + INTEGER(IntKi), PARAMETER :: EddVisT2N03D3 = 4773 + INTEGER(IntKi), PARAMETER :: EddVisT2N03D4 = 4774 + INTEGER(IntKi), PARAMETER :: EddVisT2N03D5 = 4775 + INTEGER(IntKi), PARAMETER :: EddVisT2N03D6 = 4776 + INTEGER(IntKi), PARAMETER :: EddVisT2N03D7 = 4777 + INTEGER(IntKi), PARAMETER :: EddVisT2N03D8 = 4778 + INTEGER(IntKi), PARAMETER :: EddVisT2N03D9 = 4779 + INTEGER(IntKi), PARAMETER :: EddVisT2N04D1 = 4780 + INTEGER(IntKi), PARAMETER :: EddVisT2N04D2 = 4781 + INTEGER(IntKi), PARAMETER :: EddVisT2N04D3 = 4782 + INTEGER(IntKi), PARAMETER :: EddVisT2N04D4 = 4783 + INTEGER(IntKi), PARAMETER :: EddVisT2N04D5 = 4784 + INTEGER(IntKi), PARAMETER :: EddVisT2N04D6 = 4785 + INTEGER(IntKi), PARAMETER :: EddVisT2N04D7 = 4786 + INTEGER(IntKi), PARAMETER :: EddVisT2N04D8 = 4787 + INTEGER(IntKi), PARAMETER :: EddVisT2N04D9 = 4788 + INTEGER(IntKi), PARAMETER :: EddVisT2N05D1 = 4789 + INTEGER(IntKi), PARAMETER :: EddVisT2N05D2 = 4790 + INTEGER(IntKi), PARAMETER :: EddVisT2N05D3 = 4791 + INTEGER(IntKi), PARAMETER :: EddVisT2N05D4 = 4792 + INTEGER(IntKi), PARAMETER :: EddVisT2N05D5 = 4793 + INTEGER(IntKi), PARAMETER :: EddVisT2N05D6 = 4794 + INTEGER(IntKi), PARAMETER :: EddVisT2N05D7 = 4795 + INTEGER(IntKi), PARAMETER :: EddVisT2N05D8 = 4796 + INTEGER(IntKi), PARAMETER :: EddVisT2N05D9 = 4797 + INTEGER(IntKi), PARAMETER :: EddVisT2N06D1 = 4798 + INTEGER(IntKi), PARAMETER :: EddVisT2N06D2 = 4799 + INTEGER(IntKi), PARAMETER :: EddVisT2N06D3 = 4800 + INTEGER(IntKi), PARAMETER :: EddVisT2N06D4 = 4801 + INTEGER(IntKi), PARAMETER :: EddVisT2N06D5 = 4802 + INTEGER(IntKi), PARAMETER :: EddVisT2N06D6 = 4803 + INTEGER(IntKi), PARAMETER :: EddVisT2N06D7 = 4804 + INTEGER(IntKi), PARAMETER :: EddVisT2N06D8 = 4805 + INTEGER(IntKi), PARAMETER :: EddVisT2N06D9 = 4806 + INTEGER(IntKi), PARAMETER :: EddVisT2N07D1 = 4807 + INTEGER(IntKi), PARAMETER :: EddVisT2N07D2 = 4808 + INTEGER(IntKi), PARAMETER :: EddVisT2N07D3 = 4809 + INTEGER(IntKi), PARAMETER :: EddVisT2N07D4 = 4810 + INTEGER(IntKi), PARAMETER :: EddVisT2N07D5 = 4811 + INTEGER(IntKi), PARAMETER :: EddVisT2N07D6 = 4812 + INTEGER(IntKi), PARAMETER :: EddVisT2N07D7 = 4813 + INTEGER(IntKi), PARAMETER :: EddVisT2N07D8 = 4814 + INTEGER(IntKi), PARAMETER :: EddVisT2N07D9 = 4815 + INTEGER(IntKi), PARAMETER :: EddVisT2N08D1 = 4816 + INTEGER(IntKi), PARAMETER :: EddVisT2N08D2 = 4817 + INTEGER(IntKi), PARAMETER :: EddVisT2N08D3 = 4818 + INTEGER(IntKi), PARAMETER :: EddVisT2N08D4 = 4819 + INTEGER(IntKi), PARAMETER :: EddVisT2N08D5 = 4820 + INTEGER(IntKi), PARAMETER :: EddVisT2N08D6 = 4821 + INTEGER(IntKi), PARAMETER :: EddVisT2N08D7 = 4822 + INTEGER(IntKi), PARAMETER :: EddVisT2N08D8 = 4823 + INTEGER(IntKi), PARAMETER :: EddVisT2N08D9 = 4824 + INTEGER(IntKi), PARAMETER :: EddVisT2N09D1 = 4825 + INTEGER(IntKi), PARAMETER :: EddVisT2N09D2 = 4826 + INTEGER(IntKi), PARAMETER :: EddVisT2N09D3 = 4827 + INTEGER(IntKi), PARAMETER :: EddVisT2N09D4 = 4828 + INTEGER(IntKi), PARAMETER :: EddVisT2N09D5 = 4829 + INTEGER(IntKi), PARAMETER :: EddVisT2N09D6 = 4830 + INTEGER(IntKi), PARAMETER :: EddVisT2N09D7 = 4831 + INTEGER(IntKi), PARAMETER :: EddVisT2N09D8 = 4832 + INTEGER(IntKi), PARAMETER :: EddVisT2N09D9 = 4833 + INTEGER(IntKi), PARAMETER :: EddVisT2N10D1 = 4834 + INTEGER(IntKi), PARAMETER :: EddVisT2N10D2 = 4835 + INTEGER(IntKi), PARAMETER :: EddVisT2N10D3 = 4836 + INTEGER(IntKi), PARAMETER :: EddVisT2N10D4 = 4837 + INTEGER(IntKi), PARAMETER :: EddVisT2N10D5 = 4838 + INTEGER(IntKi), PARAMETER :: EddVisT2N10D6 = 4839 + INTEGER(IntKi), PARAMETER :: EddVisT2N10D7 = 4840 + INTEGER(IntKi), PARAMETER :: EddVisT2N10D8 = 4841 + INTEGER(IntKi), PARAMETER :: EddVisT2N10D9 = 4842 + INTEGER(IntKi), PARAMETER :: EddVisT2N11D1 = 4843 + INTEGER(IntKi), PARAMETER :: EddVisT2N11D2 = 4844 + INTEGER(IntKi), PARAMETER :: EddVisT2N11D3 = 4845 + INTEGER(IntKi), PARAMETER :: EddVisT2N11D4 = 4846 + INTEGER(IntKi), PARAMETER :: EddVisT2N11D5 = 4847 + INTEGER(IntKi), PARAMETER :: EddVisT2N11D6 = 4848 + INTEGER(IntKi), PARAMETER :: EddVisT2N11D7 = 4849 + INTEGER(IntKi), PARAMETER :: EddVisT2N11D8 = 4850 + INTEGER(IntKi), PARAMETER :: EddVisT2N11D9 = 4851 + INTEGER(IntKi), PARAMETER :: EddVisT2N12D1 = 4852 + INTEGER(IntKi), PARAMETER :: EddVisT2N12D2 = 4853 + INTEGER(IntKi), PARAMETER :: EddVisT2N12D3 = 4854 + INTEGER(IntKi), PARAMETER :: EddVisT2N12D4 = 4855 + INTEGER(IntKi), PARAMETER :: EddVisT2N12D5 = 4856 + INTEGER(IntKi), PARAMETER :: EddVisT2N12D6 = 4857 + INTEGER(IntKi), PARAMETER :: EddVisT2N12D7 = 4858 + INTEGER(IntKi), PARAMETER :: EddVisT2N12D8 = 4859 + INTEGER(IntKi), PARAMETER :: EddVisT2N12D9 = 4860 + INTEGER(IntKi), PARAMETER :: EddVisT2N13D1 = 4861 + INTEGER(IntKi), PARAMETER :: EddVisT2N13D2 = 4862 + INTEGER(IntKi), PARAMETER :: EddVisT2N13D3 = 4863 + INTEGER(IntKi), PARAMETER :: EddVisT2N13D4 = 4864 + INTEGER(IntKi), PARAMETER :: EddVisT2N13D5 = 4865 + INTEGER(IntKi), PARAMETER :: EddVisT2N13D6 = 4866 + INTEGER(IntKi), PARAMETER :: EddVisT2N13D7 = 4867 + INTEGER(IntKi), PARAMETER :: EddVisT2N13D8 = 4868 + INTEGER(IntKi), PARAMETER :: EddVisT2N13D9 = 4869 + INTEGER(IntKi), PARAMETER :: EddVisT2N14D1 = 4870 + INTEGER(IntKi), PARAMETER :: EddVisT2N14D2 = 4871 + INTEGER(IntKi), PARAMETER :: EddVisT2N14D3 = 4872 + INTEGER(IntKi), PARAMETER :: EddVisT2N14D4 = 4873 + INTEGER(IntKi), PARAMETER :: EddVisT2N14D5 = 4874 + INTEGER(IntKi), PARAMETER :: EddVisT2N14D6 = 4875 + INTEGER(IntKi), PARAMETER :: EddVisT2N14D7 = 4876 + INTEGER(IntKi), PARAMETER :: EddVisT2N14D8 = 4877 + INTEGER(IntKi), PARAMETER :: EddVisT2N14D9 = 4878 + INTEGER(IntKi), PARAMETER :: EddVisT2N15D1 = 4879 + INTEGER(IntKi), PARAMETER :: EddVisT2N15D2 = 4880 + INTEGER(IntKi), PARAMETER :: EddVisT2N15D3 = 4881 + INTEGER(IntKi), PARAMETER :: EddVisT2N15D4 = 4882 + INTEGER(IntKi), PARAMETER :: EddVisT2N15D5 = 4883 + INTEGER(IntKi), PARAMETER :: EddVisT2N15D6 = 4884 + INTEGER(IntKi), PARAMETER :: EddVisT2N15D7 = 4885 + INTEGER(IntKi), PARAMETER :: EddVisT2N15D8 = 4886 + INTEGER(IntKi), PARAMETER :: EddVisT2N15D9 = 4887 + INTEGER(IntKi), PARAMETER :: EddVisT2N16D1 = 4888 + INTEGER(IntKi), PARAMETER :: EddVisT2N16D2 = 4889 + INTEGER(IntKi), PARAMETER :: EddVisT2N16D3 = 4890 + INTEGER(IntKi), PARAMETER :: EddVisT2N16D4 = 4891 + INTEGER(IntKi), PARAMETER :: EddVisT2N16D5 = 4892 + INTEGER(IntKi), PARAMETER :: EddVisT2N16D6 = 4893 + INTEGER(IntKi), PARAMETER :: EddVisT2N16D7 = 4894 + INTEGER(IntKi), PARAMETER :: EddVisT2N16D8 = 4895 + INTEGER(IntKi), PARAMETER :: EddVisT2N16D9 = 4896 + INTEGER(IntKi), PARAMETER :: EddVisT2N17D1 = 4897 + INTEGER(IntKi), PARAMETER :: EddVisT2N17D2 = 4898 + INTEGER(IntKi), PARAMETER :: EddVisT2N17D3 = 4899 + INTEGER(IntKi), PARAMETER :: EddVisT2N17D4 = 4900 + INTEGER(IntKi), PARAMETER :: EddVisT2N17D5 = 4901 + INTEGER(IntKi), PARAMETER :: EddVisT2N17D6 = 4902 + INTEGER(IntKi), PARAMETER :: EddVisT2N17D7 = 4903 + INTEGER(IntKi), PARAMETER :: EddVisT2N17D8 = 4904 + INTEGER(IntKi), PARAMETER :: EddVisT2N17D9 = 4905 + INTEGER(IntKi), PARAMETER :: EddVisT2N18D1 = 4906 + INTEGER(IntKi), PARAMETER :: EddVisT2N18D2 = 4907 + INTEGER(IntKi), PARAMETER :: EddVisT2N18D3 = 4908 + INTEGER(IntKi), PARAMETER :: EddVisT2N18D4 = 4909 + INTEGER(IntKi), PARAMETER :: EddVisT2N18D5 = 4910 + INTEGER(IntKi), PARAMETER :: EddVisT2N18D6 = 4911 + INTEGER(IntKi), PARAMETER :: EddVisT2N18D7 = 4912 + INTEGER(IntKi), PARAMETER :: EddVisT2N18D8 = 4913 + INTEGER(IntKi), PARAMETER :: EddVisT2N18D9 = 4914 + INTEGER(IntKi), PARAMETER :: EddVisT2N19D1 = 4915 + INTEGER(IntKi), PARAMETER :: EddVisT2N19D2 = 4916 + INTEGER(IntKi), PARAMETER :: EddVisT2N19D3 = 4917 + INTEGER(IntKi), PARAMETER :: EddVisT2N19D4 = 4918 + INTEGER(IntKi), PARAMETER :: EddVisT2N19D5 = 4919 + INTEGER(IntKi), PARAMETER :: EddVisT2N19D6 = 4920 + INTEGER(IntKi), PARAMETER :: EddVisT2N19D7 = 4921 + INTEGER(IntKi), PARAMETER :: EddVisT2N19D8 = 4922 + INTEGER(IntKi), PARAMETER :: EddVisT2N19D9 = 4923 + INTEGER(IntKi), PARAMETER :: EddVisT2N20D1 = 4924 + INTEGER(IntKi), PARAMETER :: EddVisT2N20D2 = 4925 + INTEGER(IntKi), PARAMETER :: EddVisT2N20D3 = 4926 + INTEGER(IntKi), PARAMETER :: EddVisT2N20D4 = 4927 + INTEGER(IntKi), PARAMETER :: EddVisT2N20D5 = 4928 + INTEGER(IntKi), PARAMETER :: EddVisT2N20D6 = 4929 + INTEGER(IntKi), PARAMETER :: EddVisT2N20D7 = 4930 + INTEGER(IntKi), PARAMETER :: EddVisT2N20D8 = 4931 + INTEGER(IntKi), PARAMETER :: EddVisT2N20D9 = 4932 + INTEGER(IntKi), PARAMETER :: EddVisT3N01D1 = 4933 + INTEGER(IntKi), PARAMETER :: EddVisT3N01D2 = 4934 + INTEGER(IntKi), PARAMETER :: EddVisT3N01D3 = 4935 + INTEGER(IntKi), PARAMETER :: EddVisT3N01D4 = 4936 + INTEGER(IntKi), PARAMETER :: EddVisT3N01D5 = 4937 + INTEGER(IntKi), PARAMETER :: EddVisT3N01D6 = 4938 + INTEGER(IntKi), PARAMETER :: EddVisT3N01D7 = 4939 + INTEGER(IntKi), PARAMETER :: EddVisT3N01D8 = 4940 + INTEGER(IntKi), PARAMETER :: EddVisT3N01D9 = 4941 + INTEGER(IntKi), PARAMETER :: EddVisT3N02D1 = 4942 + INTEGER(IntKi), PARAMETER :: EddVisT3N02D2 = 4943 + INTEGER(IntKi), PARAMETER :: EddVisT3N02D3 = 4944 + INTEGER(IntKi), PARAMETER :: EddVisT3N02D4 = 4945 + INTEGER(IntKi), PARAMETER :: EddVisT3N02D5 = 4946 + INTEGER(IntKi), PARAMETER :: EddVisT3N02D6 = 4947 + INTEGER(IntKi), PARAMETER :: EddVisT3N02D7 = 4948 + INTEGER(IntKi), PARAMETER :: EddVisT3N02D8 = 4949 + INTEGER(IntKi), PARAMETER :: EddVisT3N02D9 = 4950 + INTEGER(IntKi), PARAMETER :: EddVisT3N03D1 = 4951 + INTEGER(IntKi), PARAMETER :: EddVisT3N03D2 = 4952 + INTEGER(IntKi), PARAMETER :: EddVisT3N03D3 = 4953 + INTEGER(IntKi), PARAMETER :: EddVisT3N03D4 = 4954 + INTEGER(IntKi), PARAMETER :: EddVisT3N03D5 = 4955 + INTEGER(IntKi), PARAMETER :: EddVisT3N03D6 = 4956 + INTEGER(IntKi), PARAMETER :: EddVisT3N03D7 = 4957 + INTEGER(IntKi), PARAMETER :: EddVisT3N03D8 = 4958 + INTEGER(IntKi), PARAMETER :: EddVisT3N03D9 = 4959 + INTEGER(IntKi), PARAMETER :: EddVisT3N04D1 = 4960 + INTEGER(IntKi), PARAMETER :: EddVisT3N04D2 = 4961 + INTEGER(IntKi), PARAMETER :: EddVisT3N04D3 = 4962 + INTEGER(IntKi), PARAMETER :: EddVisT3N04D4 = 4963 + INTEGER(IntKi), PARAMETER :: EddVisT3N04D5 = 4964 + INTEGER(IntKi), PARAMETER :: EddVisT3N04D6 = 4965 + INTEGER(IntKi), PARAMETER :: EddVisT3N04D7 = 4966 + INTEGER(IntKi), PARAMETER :: EddVisT3N04D8 = 4967 + INTEGER(IntKi), PARAMETER :: EddVisT3N04D9 = 4968 + INTEGER(IntKi), PARAMETER :: EddVisT3N05D1 = 4969 + INTEGER(IntKi), PARAMETER :: EddVisT3N05D2 = 4970 + INTEGER(IntKi), PARAMETER :: EddVisT3N05D3 = 4971 + INTEGER(IntKi), PARAMETER :: EddVisT3N05D4 = 4972 + INTEGER(IntKi), PARAMETER :: EddVisT3N05D5 = 4973 + INTEGER(IntKi), PARAMETER :: EddVisT3N05D6 = 4974 + INTEGER(IntKi), PARAMETER :: EddVisT3N05D7 = 4975 + INTEGER(IntKi), PARAMETER :: EddVisT3N05D8 = 4976 + INTEGER(IntKi), PARAMETER :: EddVisT3N05D9 = 4977 + INTEGER(IntKi), PARAMETER :: EddVisT3N06D1 = 4978 + INTEGER(IntKi), PARAMETER :: EddVisT3N06D2 = 4979 + INTEGER(IntKi), PARAMETER :: EddVisT3N06D3 = 4980 + INTEGER(IntKi), PARAMETER :: EddVisT3N06D4 = 4981 + INTEGER(IntKi), PARAMETER :: EddVisT3N06D5 = 4982 + INTEGER(IntKi), PARAMETER :: EddVisT3N06D6 = 4983 + INTEGER(IntKi), PARAMETER :: EddVisT3N06D7 = 4984 + INTEGER(IntKi), PARAMETER :: EddVisT3N06D8 = 4985 + INTEGER(IntKi), PARAMETER :: EddVisT3N06D9 = 4986 + INTEGER(IntKi), PARAMETER :: EddVisT3N07D1 = 4987 + INTEGER(IntKi), PARAMETER :: EddVisT3N07D2 = 4988 + INTEGER(IntKi), PARAMETER :: EddVisT3N07D3 = 4989 + INTEGER(IntKi), PARAMETER :: EddVisT3N07D4 = 4990 + INTEGER(IntKi), PARAMETER :: EddVisT3N07D5 = 4991 + INTEGER(IntKi), PARAMETER :: EddVisT3N07D6 = 4992 + INTEGER(IntKi), PARAMETER :: EddVisT3N07D7 = 4993 + INTEGER(IntKi), PARAMETER :: EddVisT3N07D8 = 4994 + INTEGER(IntKi), PARAMETER :: EddVisT3N07D9 = 4995 + INTEGER(IntKi), PARAMETER :: EddVisT3N08D1 = 4996 + INTEGER(IntKi), PARAMETER :: EddVisT3N08D2 = 4997 + INTEGER(IntKi), PARAMETER :: EddVisT3N08D3 = 4998 + INTEGER(IntKi), PARAMETER :: EddVisT3N08D4 = 4999 + INTEGER(IntKi), PARAMETER :: EddVisT3N08D5 = 5000 + INTEGER(IntKi), PARAMETER :: EddVisT3N08D6 = 5001 + INTEGER(IntKi), PARAMETER :: EddVisT3N08D7 = 5002 + INTEGER(IntKi), PARAMETER :: EddVisT3N08D8 = 5003 + INTEGER(IntKi), PARAMETER :: EddVisT3N08D9 = 5004 + INTEGER(IntKi), PARAMETER :: EddVisT3N09D1 = 5005 + INTEGER(IntKi), PARAMETER :: EddVisT3N09D2 = 5006 + INTEGER(IntKi), PARAMETER :: EddVisT3N09D3 = 5007 + INTEGER(IntKi), PARAMETER :: EddVisT3N09D4 = 5008 + INTEGER(IntKi), PARAMETER :: EddVisT3N09D5 = 5009 + INTEGER(IntKi), PARAMETER :: EddVisT3N09D6 = 5010 + INTEGER(IntKi), PARAMETER :: EddVisT3N09D7 = 5011 + INTEGER(IntKi), PARAMETER :: EddVisT3N09D8 = 5012 + INTEGER(IntKi), PARAMETER :: EddVisT3N09D9 = 5013 + INTEGER(IntKi), PARAMETER :: EddVisT3N10D1 = 5014 + INTEGER(IntKi), PARAMETER :: EddVisT3N10D2 = 5015 + INTEGER(IntKi), PARAMETER :: EddVisT3N10D3 = 5016 + INTEGER(IntKi), PARAMETER :: EddVisT3N10D4 = 5017 + INTEGER(IntKi), PARAMETER :: EddVisT3N10D5 = 5018 + INTEGER(IntKi), PARAMETER :: EddVisT3N10D6 = 5019 + INTEGER(IntKi), PARAMETER :: EddVisT3N10D7 = 5020 + INTEGER(IntKi), PARAMETER :: EddVisT3N10D8 = 5021 + INTEGER(IntKi), PARAMETER :: EddVisT3N10D9 = 5022 + INTEGER(IntKi), PARAMETER :: EddVisT3N11D1 = 5023 + INTEGER(IntKi), PARAMETER :: EddVisT3N11D2 = 5024 + INTEGER(IntKi), PARAMETER :: EddVisT3N11D3 = 5025 + INTEGER(IntKi), PARAMETER :: EddVisT3N11D4 = 5026 + INTEGER(IntKi), PARAMETER :: EddVisT3N11D5 = 5027 + INTEGER(IntKi), PARAMETER :: EddVisT3N11D6 = 5028 + INTEGER(IntKi), PARAMETER :: EddVisT3N11D7 = 5029 + INTEGER(IntKi), PARAMETER :: EddVisT3N11D8 = 5030 + INTEGER(IntKi), PARAMETER :: EddVisT3N11D9 = 5031 + INTEGER(IntKi), PARAMETER :: EddVisT3N12D1 = 5032 + INTEGER(IntKi), PARAMETER :: EddVisT3N12D2 = 5033 + INTEGER(IntKi), PARAMETER :: EddVisT3N12D3 = 5034 + INTEGER(IntKi), PARAMETER :: EddVisT3N12D4 = 5035 + INTEGER(IntKi), PARAMETER :: EddVisT3N12D5 = 5036 + INTEGER(IntKi), PARAMETER :: EddVisT3N12D6 = 5037 + INTEGER(IntKi), PARAMETER :: EddVisT3N12D7 = 5038 + INTEGER(IntKi), PARAMETER :: EddVisT3N12D8 = 5039 + INTEGER(IntKi), PARAMETER :: EddVisT3N12D9 = 5040 + INTEGER(IntKi), PARAMETER :: EddVisT3N13D1 = 5041 + INTEGER(IntKi), PARAMETER :: EddVisT3N13D2 = 5042 + INTEGER(IntKi), PARAMETER :: EddVisT3N13D3 = 5043 + INTEGER(IntKi), PARAMETER :: EddVisT3N13D4 = 5044 + INTEGER(IntKi), PARAMETER :: EddVisT3N13D5 = 5045 + INTEGER(IntKi), PARAMETER :: EddVisT3N13D6 = 5046 + INTEGER(IntKi), PARAMETER :: EddVisT3N13D7 = 5047 + INTEGER(IntKi), PARAMETER :: EddVisT3N13D8 = 5048 + INTEGER(IntKi), PARAMETER :: EddVisT3N13D9 = 5049 + INTEGER(IntKi), PARAMETER :: EddVisT3N14D1 = 5050 + INTEGER(IntKi), PARAMETER :: EddVisT3N14D2 = 5051 + INTEGER(IntKi), PARAMETER :: EddVisT3N14D3 = 5052 + INTEGER(IntKi), PARAMETER :: EddVisT3N14D4 = 5053 + INTEGER(IntKi), PARAMETER :: EddVisT3N14D5 = 5054 + INTEGER(IntKi), PARAMETER :: EddVisT3N14D6 = 5055 + INTEGER(IntKi), PARAMETER :: EddVisT3N14D7 = 5056 + INTEGER(IntKi), PARAMETER :: EddVisT3N14D8 = 5057 + INTEGER(IntKi), PARAMETER :: EddVisT3N14D9 = 5058 + INTEGER(IntKi), PARAMETER :: EddVisT3N15D1 = 5059 + INTEGER(IntKi), PARAMETER :: EddVisT3N15D2 = 5060 + INTEGER(IntKi), PARAMETER :: EddVisT3N15D3 = 5061 + INTEGER(IntKi), PARAMETER :: EddVisT3N15D4 = 5062 + INTEGER(IntKi), PARAMETER :: EddVisT3N15D5 = 5063 + INTEGER(IntKi), PARAMETER :: EddVisT3N15D6 = 5064 + INTEGER(IntKi), PARAMETER :: EddVisT3N15D7 = 5065 + INTEGER(IntKi), PARAMETER :: EddVisT3N15D8 = 5066 + INTEGER(IntKi), PARAMETER :: EddVisT3N15D9 = 5067 + INTEGER(IntKi), PARAMETER :: EddVisT3N16D1 = 5068 + INTEGER(IntKi), PARAMETER :: EddVisT3N16D2 = 5069 + INTEGER(IntKi), PARAMETER :: EddVisT3N16D3 = 5070 + INTEGER(IntKi), PARAMETER :: EddVisT3N16D4 = 5071 + INTEGER(IntKi), PARAMETER :: EddVisT3N16D5 = 5072 + INTEGER(IntKi), PARAMETER :: EddVisT3N16D6 = 5073 + INTEGER(IntKi), PARAMETER :: EddVisT3N16D7 = 5074 + INTEGER(IntKi), PARAMETER :: EddVisT3N16D8 = 5075 + INTEGER(IntKi), PARAMETER :: EddVisT3N16D9 = 5076 + INTEGER(IntKi), PARAMETER :: EddVisT3N17D1 = 5077 + INTEGER(IntKi), PARAMETER :: EddVisT3N17D2 = 5078 + INTEGER(IntKi), PARAMETER :: EddVisT3N17D3 = 5079 + INTEGER(IntKi), PARAMETER :: EddVisT3N17D4 = 5080 + INTEGER(IntKi), PARAMETER :: EddVisT3N17D5 = 5081 + INTEGER(IntKi), PARAMETER :: EddVisT3N17D6 = 5082 + INTEGER(IntKi), PARAMETER :: EddVisT3N17D7 = 5083 + INTEGER(IntKi), PARAMETER :: EddVisT3N17D8 = 5084 + INTEGER(IntKi), PARAMETER :: EddVisT3N17D9 = 5085 + INTEGER(IntKi), PARAMETER :: EddVisT3N18D1 = 5086 + INTEGER(IntKi), PARAMETER :: EddVisT3N18D2 = 5087 + INTEGER(IntKi), PARAMETER :: EddVisT3N18D3 = 5088 + INTEGER(IntKi), PARAMETER :: EddVisT3N18D4 = 5089 + INTEGER(IntKi), PARAMETER :: EddVisT3N18D5 = 5090 + INTEGER(IntKi), PARAMETER :: EddVisT3N18D6 = 5091 + INTEGER(IntKi), PARAMETER :: EddVisT3N18D7 = 5092 + INTEGER(IntKi), PARAMETER :: EddVisT3N18D8 = 5093 + INTEGER(IntKi), PARAMETER :: EddVisT3N18D9 = 5094 + INTEGER(IntKi), PARAMETER :: EddVisT3N19D1 = 5095 + INTEGER(IntKi), PARAMETER :: EddVisT3N19D2 = 5096 + INTEGER(IntKi), PARAMETER :: EddVisT3N19D3 = 5097 + INTEGER(IntKi), PARAMETER :: EddVisT3N19D4 = 5098 + INTEGER(IntKi), PARAMETER :: EddVisT3N19D5 = 5099 + INTEGER(IntKi), PARAMETER :: EddVisT3N19D6 = 5100 + INTEGER(IntKi), PARAMETER :: EddVisT3N19D7 = 5101 + INTEGER(IntKi), PARAMETER :: EddVisT3N19D8 = 5102 + INTEGER(IntKi), PARAMETER :: EddVisT3N19D9 = 5103 + INTEGER(IntKi), PARAMETER :: EddVisT3N20D1 = 5104 + INTEGER(IntKi), PARAMETER :: EddVisT3N20D2 = 5105 + INTEGER(IntKi), PARAMETER :: EddVisT3N20D3 = 5106 + INTEGER(IntKi), PARAMETER :: EddVisT3N20D4 = 5107 + INTEGER(IntKi), PARAMETER :: EddVisT3N20D5 = 5108 + INTEGER(IntKi), PARAMETER :: EddVisT3N20D6 = 5109 + INTEGER(IntKi), PARAMETER :: EddVisT3N20D7 = 5110 + INTEGER(IntKi), PARAMETER :: EddVisT3N20D8 = 5111 + INTEGER(IntKi), PARAMETER :: EddVisT3N20D9 = 5112 + INTEGER(IntKi), PARAMETER :: EddVisT4N01D1 = 5113 + INTEGER(IntKi), PARAMETER :: EddVisT4N01D2 = 5114 + INTEGER(IntKi), PARAMETER :: EddVisT4N01D3 = 5115 + INTEGER(IntKi), PARAMETER :: EddVisT4N01D4 = 5116 + INTEGER(IntKi), PARAMETER :: EddVisT4N01D5 = 5117 + INTEGER(IntKi), PARAMETER :: EddVisT4N01D6 = 5118 + INTEGER(IntKi), PARAMETER :: EddVisT4N01D7 = 5119 + INTEGER(IntKi), PARAMETER :: EddVisT4N01D8 = 5120 + INTEGER(IntKi), PARAMETER :: EddVisT4N01D9 = 5121 + INTEGER(IntKi), PARAMETER :: EddVisT4N02D1 = 5122 + INTEGER(IntKi), PARAMETER :: EddVisT4N02D2 = 5123 + INTEGER(IntKi), PARAMETER :: EddVisT4N02D3 = 5124 + INTEGER(IntKi), PARAMETER :: EddVisT4N02D4 = 5125 + INTEGER(IntKi), PARAMETER :: EddVisT4N02D5 = 5126 + INTEGER(IntKi), PARAMETER :: EddVisT4N02D6 = 5127 + INTEGER(IntKi), PARAMETER :: EddVisT4N02D7 = 5128 + INTEGER(IntKi), PARAMETER :: EddVisT4N02D8 = 5129 + INTEGER(IntKi), PARAMETER :: EddVisT4N02D9 = 5130 + INTEGER(IntKi), PARAMETER :: EddVisT4N03D1 = 5131 + INTEGER(IntKi), PARAMETER :: EddVisT4N03D2 = 5132 + INTEGER(IntKi), PARAMETER :: EddVisT4N03D3 = 5133 + INTEGER(IntKi), PARAMETER :: EddVisT4N03D4 = 5134 + INTEGER(IntKi), PARAMETER :: EddVisT4N03D5 = 5135 + INTEGER(IntKi), PARAMETER :: EddVisT4N03D6 = 5136 + INTEGER(IntKi), PARAMETER :: EddVisT4N03D7 = 5137 + INTEGER(IntKi), PARAMETER :: EddVisT4N03D8 = 5138 + INTEGER(IntKi), PARAMETER :: EddVisT4N03D9 = 5139 + INTEGER(IntKi), PARAMETER :: EddVisT4N04D1 = 5140 + INTEGER(IntKi), PARAMETER :: EddVisT4N04D2 = 5141 + INTEGER(IntKi), PARAMETER :: EddVisT4N04D3 = 5142 + INTEGER(IntKi), PARAMETER :: EddVisT4N04D4 = 5143 + INTEGER(IntKi), PARAMETER :: EddVisT4N04D5 = 5144 + INTEGER(IntKi), PARAMETER :: EddVisT4N04D6 = 5145 + INTEGER(IntKi), PARAMETER :: EddVisT4N04D7 = 5146 + INTEGER(IntKi), PARAMETER :: EddVisT4N04D8 = 5147 + INTEGER(IntKi), PARAMETER :: EddVisT4N04D9 = 5148 + INTEGER(IntKi), PARAMETER :: EddVisT4N05D1 = 5149 + INTEGER(IntKi), PARAMETER :: EddVisT4N05D2 = 5150 + INTEGER(IntKi), PARAMETER :: EddVisT4N05D3 = 5151 + INTEGER(IntKi), PARAMETER :: EddVisT4N05D4 = 5152 + INTEGER(IntKi), PARAMETER :: EddVisT4N05D5 = 5153 + INTEGER(IntKi), PARAMETER :: EddVisT4N05D6 = 5154 + INTEGER(IntKi), PARAMETER :: EddVisT4N05D7 = 5155 + INTEGER(IntKi), PARAMETER :: EddVisT4N05D8 = 5156 + INTEGER(IntKi), PARAMETER :: EddVisT4N05D9 = 5157 + INTEGER(IntKi), PARAMETER :: EddVisT4N06D1 = 5158 + INTEGER(IntKi), PARAMETER :: EddVisT4N06D2 = 5159 + INTEGER(IntKi), PARAMETER :: EddVisT4N06D3 = 5160 + INTEGER(IntKi), PARAMETER :: EddVisT4N06D4 = 5161 + INTEGER(IntKi), PARAMETER :: EddVisT4N06D5 = 5162 + INTEGER(IntKi), PARAMETER :: EddVisT4N06D6 = 5163 + INTEGER(IntKi), PARAMETER :: EddVisT4N06D7 = 5164 + INTEGER(IntKi), PARAMETER :: EddVisT4N06D8 = 5165 + INTEGER(IntKi), PARAMETER :: EddVisT4N06D9 = 5166 + INTEGER(IntKi), PARAMETER :: EddVisT4N07D1 = 5167 + INTEGER(IntKi), PARAMETER :: EddVisT4N07D2 = 5168 + INTEGER(IntKi), PARAMETER :: EddVisT4N07D3 = 5169 + INTEGER(IntKi), PARAMETER :: EddVisT4N07D4 = 5170 + INTEGER(IntKi), PARAMETER :: EddVisT4N07D5 = 5171 + INTEGER(IntKi), PARAMETER :: EddVisT4N07D6 = 5172 + INTEGER(IntKi), PARAMETER :: EddVisT4N07D7 = 5173 + INTEGER(IntKi), PARAMETER :: EddVisT4N07D8 = 5174 + INTEGER(IntKi), PARAMETER :: EddVisT4N07D9 = 5175 + INTEGER(IntKi), PARAMETER :: EddVisT4N08D1 = 5176 + INTEGER(IntKi), PARAMETER :: EddVisT4N08D2 = 5177 + INTEGER(IntKi), PARAMETER :: EddVisT4N08D3 = 5178 + INTEGER(IntKi), PARAMETER :: EddVisT4N08D4 = 5179 + INTEGER(IntKi), PARAMETER :: EddVisT4N08D5 = 5180 + INTEGER(IntKi), PARAMETER :: EddVisT4N08D6 = 5181 + INTEGER(IntKi), PARAMETER :: EddVisT4N08D7 = 5182 + INTEGER(IntKi), PARAMETER :: EddVisT4N08D8 = 5183 + INTEGER(IntKi), PARAMETER :: EddVisT4N08D9 = 5184 + INTEGER(IntKi), PARAMETER :: EddVisT4N09D1 = 5185 + INTEGER(IntKi), PARAMETER :: EddVisT4N09D2 = 5186 + INTEGER(IntKi), PARAMETER :: EddVisT4N09D3 = 5187 + INTEGER(IntKi), PARAMETER :: EddVisT4N09D4 = 5188 + INTEGER(IntKi), PARAMETER :: EddVisT4N09D5 = 5189 + INTEGER(IntKi), PARAMETER :: EddVisT4N09D6 = 5190 + INTEGER(IntKi), PARAMETER :: EddVisT4N09D7 = 5191 + INTEGER(IntKi), PARAMETER :: EddVisT4N09D8 = 5192 + INTEGER(IntKi), PARAMETER :: EddVisT4N09D9 = 5193 + INTEGER(IntKi), PARAMETER :: EddVisT4N10D1 = 5194 + INTEGER(IntKi), PARAMETER :: EddVisT4N10D2 = 5195 + INTEGER(IntKi), PARAMETER :: EddVisT4N10D3 = 5196 + INTEGER(IntKi), PARAMETER :: EddVisT4N10D4 = 5197 + INTEGER(IntKi), PARAMETER :: EddVisT4N10D5 = 5198 + INTEGER(IntKi), PARAMETER :: EddVisT4N10D6 = 5199 + INTEGER(IntKi), PARAMETER :: EddVisT4N10D7 = 5200 + INTEGER(IntKi), PARAMETER :: EddVisT4N10D8 = 5201 + INTEGER(IntKi), PARAMETER :: EddVisT4N10D9 = 5202 + INTEGER(IntKi), PARAMETER :: EddVisT4N11D1 = 5203 + INTEGER(IntKi), PARAMETER :: EddVisT4N11D2 = 5204 + INTEGER(IntKi), PARAMETER :: EddVisT4N11D3 = 5205 + INTEGER(IntKi), PARAMETER :: EddVisT4N11D4 = 5206 + INTEGER(IntKi), PARAMETER :: EddVisT4N11D5 = 5207 + INTEGER(IntKi), PARAMETER :: EddVisT4N11D6 = 5208 + INTEGER(IntKi), PARAMETER :: EddVisT4N11D7 = 5209 + INTEGER(IntKi), PARAMETER :: EddVisT4N11D8 = 5210 + INTEGER(IntKi), PARAMETER :: EddVisT4N11D9 = 5211 + INTEGER(IntKi), PARAMETER :: EddVisT4N12D1 = 5212 + INTEGER(IntKi), PARAMETER :: EddVisT4N12D2 = 5213 + INTEGER(IntKi), PARAMETER :: EddVisT4N12D3 = 5214 + INTEGER(IntKi), PARAMETER :: EddVisT4N12D4 = 5215 + INTEGER(IntKi), PARAMETER :: EddVisT4N12D5 = 5216 + INTEGER(IntKi), PARAMETER :: EddVisT4N12D6 = 5217 + INTEGER(IntKi), PARAMETER :: EddVisT4N12D7 = 5218 + INTEGER(IntKi), PARAMETER :: EddVisT4N12D8 = 5219 + INTEGER(IntKi), PARAMETER :: EddVisT4N12D9 = 5220 + INTEGER(IntKi), PARAMETER :: EddVisT4N13D1 = 5221 + INTEGER(IntKi), PARAMETER :: EddVisT4N13D2 = 5222 + INTEGER(IntKi), PARAMETER :: EddVisT4N13D3 = 5223 + INTEGER(IntKi), PARAMETER :: EddVisT4N13D4 = 5224 + INTEGER(IntKi), PARAMETER :: EddVisT4N13D5 = 5225 + INTEGER(IntKi), PARAMETER :: EddVisT4N13D6 = 5226 + INTEGER(IntKi), PARAMETER :: EddVisT4N13D7 = 5227 + INTEGER(IntKi), PARAMETER :: EddVisT4N13D8 = 5228 + INTEGER(IntKi), PARAMETER :: EddVisT4N13D9 = 5229 + INTEGER(IntKi), PARAMETER :: EddVisT4N14D1 = 5230 + INTEGER(IntKi), PARAMETER :: EddVisT4N14D2 = 5231 + INTEGER(IntKi), PARAMETER :: EddVisT4N14D3 = 5232 + INTEGER(IntKi), PARAMETER :: EddVisT4N14D4 = 5233 + INTEGER(IntKi), PARAMETER :: EddVisT4N14D5 = 5234 + INTEGER(IntKi), PARAMETER :: EddVisT4N14D6 = 5235 + INTEGER(IntKi), PARAMETER :: EddVisT4N14D7 = 5236 + INTEGER(IntKi), PARAMETER :: EddVisT4N14D8 = 5237 + INTEGER(IntKi), PARAMETER :: EddVisT4N14D9 = 5238 + INTEGER(IntKi), PARAMETER :: EddVisT4N15D1 = 5239 + INTEGER(IntKi), PARAMETER :: EddVisT4N15D2 = 5240 + INTEGER(IntKi), PARAMETER :: EddVisT4N15D3 = 5241 + INTEGER(IntKi), PARAMETER :: EddVisT4N15D4 = 5242 + INTEGER(IntKi), PARAMETER :: EddVisT4N15D5 = 5243 + INTEGER(IntKi), PARAMETER :: EddVisT4N15D6 = 5244 + INTEGER(IntKi), PARAMETER :: EddVisT4N15D7 = 5245 + INTEGER(IntKi), PARAMETER :: EddVisT4N15D8 = 5246 + INTEGER(IntKi), PARAMETER :: EddVisT4N15D9 = 5247 + INTEGER(IntKi), PARAMETER :: EddVisT4N16D1 = 5248 + INTEGER(IntKi), PARAMETER :: EddVisT4N16D2 = 5249 + INTEGER(IntKi), PARAMETER :: EddVisT4N16D3 = 5250 + INTEGER(IntKi), PARAMETER :: EddVisT4N16D4 = 5251 + INTEGER(IntKi), PARAMETER :: EddVisT4N16D5 = 5252 + INTEGER(IntKi), PARAMETER :: EddVisT4N16D6 = 5253 + INTEGER(IntKi), PARAMETER :: EddVisT4N16D7 = 5254 + INTEGER(IntKi), PARAMETER :: EddVisT4N16D8 = 5255 + INTEGER(IntKi), PARAMETER :: EddVisT4N16D9 = 5256 + INTEGER(IntKi), PARAMETER :: EddVisT4N17D1 = 5257 + INTEGER(IntKi), PARAMETER :: EddVisT4N17D2 = 5258 + INTEGER(IntKi), PARAMETER :: EddVisT4N17D3 = 5259 + INTEGER(IntKi), PARAMETER :: EddVisT4N17D4 = 5260 + INTEGER(IntKi), PARAMETER :: EddVisT4N17D5 = 5261 + INTEGER(IntKi), PARAMETER :: EddVisT4N17D6 = 5262 + INTEGER(IntKi), PARAMETER :: EddVisT4N17D7 = 5263 + INTEGER(IntKi), PARAMETER :: EddVisT4N17D8 = 5264 + INTEGER(IntKi), PARAMETER :: EddVisT4N17D9 = 5265 + INTEGER(IntKi), PARAMETER :: EddVisT4N18D1 = 5266 + INTEGER(IntKi), PARAMETER :: EddVisT4N18D2 = 5267 + INTEGER(IntKi), PARAMETER :: EddVisT4N18D3 = 5268 + INTEGER(IntKi), PARAMETER :: EddVisT4N18D4 = 5269 + INTEGER(IntKi), PARAMETER :: EddVisT4N18D5 = 5270 + INTEGER(IntKi), PARAMETER :: EddVisT4N18D6 = 5271 + INTEGER(IntKi), PARAMETER :: EddVisT4N18D7 = 5272 + INTEGER(IntKi), PARAMETER :: EddVisT4N18D8 = 5273 + INTEGER(IntKi), PARAMETER :: EddVisT4N18D9 = 5274 + INTEGER(IntKi), PARAMETER :: EddVisT4N19D1 = 5275 + INTEGER(IntKi), PARAMETER :: EddVisT4N19D2 = 5276 + INTEGER(IntKi), PARAMETER :: EddVisT4N19D3 = 5277 + INTEGER(IntKi), PARAMETER :: EddVisT4N19D4 = 5278 + INTEGER(IntKi), PARAMETER :: EddVisT4N19D5 = 5279 + INTEGER(IntKi), PARAMETER :: EddVisT4N19D6 = 5280 + INTEGER(IntKi), PARAMETER :: EddVisT4N19D7 = 5281 + INTEGER(IntKi), PARAMETER :: EddVisT4N19D8 = 5282 + INTEGER(IntKi), PARAMETER :: EddVisT4N19D9 = 5283 + INTEGER(IntKi), PARAMETER :: EddVisT4N20D1 = 5284 + INTEGER(IntKi), PARAMETER :: EddVisT4N20D2 = 5285 + INTEGER(IntKi), PARAMETER :: EddVisT4N20D3 = 5286 + INTEGER(IntKi), PARAMETER :: EddVisT4N20D4 = 5287 + INTEGER(IntKi), PARAMETER :: EddVisT4N20D5 = 5288 + INTEGER(IntKi), PARAMETER :: EddVisT4N20D6 = 5289 + INTEGER(IntKi), PARAMETER :: EddVisT4N20D7 = 5290 + INTEGER(IntKi), PARAMETER :: EddVisT4N20D8 = 5291 + INTEGER(IntKi), PARAMETER :: EddVisT4N20D9 = 5292 + INTEGER(IntKi), PARAMETER :: EddVisT5N01D1 = 5293 + INTEGER(IntKi), PARAMETER :: EddVisT5N01D2 = 5294 + INTEGER(IntKi), PARAMETER :: EddVisT5N01D3 = 5295 + INTEGER(IntKi), PARAMETER :: EddVisT5N01D4 = 5296 + INTEGER(IntKi), PARAMETER :: EddVisT5N01D5 = 5297 + INTEGER(IntKi), PARAMETER :: EddVisT5N01D6 = 5298 + INTEGER(IntKi), PARAMETER :: EddVisT5N01D7 = 5299 + INTEGER(IntKi), PARAMETER :: EddVisT5N01D8 = 5300 + INTEGER(IntKi), PARAMETER :: EddVisT5N01D9 = 5301 + INTEGER(IntKi), PARAMETER :: EddVisT5N02D1 = 5302 + INTEGER(IntKi), PARAMETER :: EddVisT5N02D2 = 5303 + INTEGER(IntKi), PARAMETER :: EddVisT5N02D3 = 5304 + INTEGER(IntKi), PARAMETER :: EddVisT5N02D4 = 5305 + INTEGER(IntKi), PARAMETER :: EddVisT5N02D5 = 5306 + INTEGER(IntKi), PARAMETER :: EddVisT5N02D6 = 5307 + INTEGER(IntKi), PARAMETER :: EddVisT5N02D7 = 5308 + INTEGER(IntKi), PARAMETER :: EddVisT5N02D8 = 5309 + INTEGER(IntKi), PARAMETER :: EddVisT5N02D9 = 5310 + INTEGER(IntKi), PARAMETER :: EddVisT5N03D1 = 5311 + INTEGER(IntKi), PARAMETER :: EddVisT5N03D2 = 5312 + INTEGER(IntKi), PARAMETER :: EddVisT5N03D3 = 5313 + INTEGER(IntKi), PARAMETER :: EddVisT5N03D4 = 5314 + INTEGER(IntKi), PARAMETER :: EddVisT5N03D5 = 5315 + INTEGER(IntKi), PARAMETER :: EddVisT5N03D6 = 5316 + INTEGER(IntKi), PARAMETER :: EddVisT5N03D7 = 5317 + INTEGER(IntKi), PARAMETER :: EddVisT5N03D8 = 5318 + INTEGER(IntKi), PARAMETER :: EddVisT5N03D9 = 5319 + INTEGER(IntKi), PARAMETER :: EddVisT5N04D1 = 5320 + INTEGER(IntKi), PARAMETER :: EddVisT5N04D2 = 5321 + INTEGER(IntKi), PARAMETER :: EddVisT5N04D3 = 5322 + INTEGER(IntKi), PARAMETER :: EddVisT5N04D4 = 5323 + INTEGER(IntKi), PARAMETER :: EddVisT5N04D5 = 5324 + INTEGER(IntKi), PARAMETER :: EddVisT5N04D6 = 5325 + INTEGER(IntKi), PARAMETER :: EddVisT5N04D7 = 5326 + INTEGER(IntKi), PARAMETER :: EddVisT5N04D8 = 5327 + INTEGER(IntKi), PARAMETER :: EddVisT5N04D9 = 5328 + INTEGER(IntKi), PARAMETER :: EddVisT5N05D1 = 5329 + INTEGER(IntKi), PARAMETER :: EddVisT5N05D2 = 5330 + INTEGER(IntKi), PARAMETER :: EddVisT5N05D3 = 5331 + INTEGER(IntKi), PARAMETER :: EddVisT5N05D4 = 5332 + INTEGER(IntKi), PARAMETER :: EddVisT5N05D5 = 5333 + INTEGER(IntKi), PARAMETER :: EddVisT5N05D6 = 5334 + INTEGER(IntKi), PARAMETER :: EddVisT5N05D7 = 5335 + INTEGER(IntKi), PARAMETER :: EddVisT5N05D8 = 5336 + INTEGER(IntKi), PARAMETER :: EddVisT5N05D9 = 5337 + INTEGER(IntKi), PARAMETER :: EddVisT5N06D1 = 5338 + INTEGER(IntKi), PARAMETER :: EddVisT5N06D2 = 5339 + INTEGER(IntKi), PARAMETER :: EddVisT5N06D3 = 5340 + INTEGER(IntKi), PARAMETER :: EddVisT5N06D4 = 5341 + INTEGER(IntKi), PARAMETER :: EddVisT5N06D5 = 5342 + INTEGER(IntKi), PARAMETER :: EddVisT5N06D6 = 5343 + INTEGER(IntKi), PARAMETER :: EddVisT5N06D7 = 5344 + INTEGER(IntKi), PARAMETER :: EddVisT5N06D8 = 5345 + INTEGER(IntKi), PARAMETER :: EddVisT5N06D9 = 5346 + INTEGER(IntKi), PARAMETER :: EddVisT5N07D1 = 5347 + INTEGER(IntKi), PARAMETER :: EddVisT5N07D2 = 5348 + INTEGER(IntKi), PARAMETER :: EddVisT5N07D3 = 5349 + INTEGER(IntKi), PARAMETER :: EddVisT5N07D4 = 5350 + INTEGER(IntKi), PARAMETER :: EddVisT5N07D5 = 5351 + INTEGER(IntKi), PARAMETER :: EddVisT5N07D6 = 5352 + INTEGER(IntKi), PARAMETER :: EddVisT5N07D7 = 5353 + INTEGER(IntKi), PARAMETER :: EddVisT5N07D8 = 5354 + INTEGER(IntKi), PARAMETER :: EddVisT5N07D9 = 5355 + INTEGER(IntKi), PARAMETER :: EddVisT5N08D1 = 5356 + INTEGER(IntKi), PARAMETER :: EddVisT5N08D2 = 5357 + INTEGER(IntKi), PARAMETER :: EddVisT5N08D3 = 5358 + INTEGER(IntKi), PARAMETER :: EddVisT5N08D4 = 5359 + INTEGER(IntKi), PARAMETER :: EddVisT5N08D5 = 5360 + INTEGER(IntKi), PARAMETER :: EddVisT5N08D6 = 5361 + INTEGER(IntKi), PARAMETER :: EddVisT5N08D7 = 5362 + INTEGER(IntKi), PARAMETER :: EddVisT5N08D8 = 5363 + INTEGER(IntKi), PARAMETER :: EddVisT5N08D9 = 5364 + INTEGER(IntKi), PARAMETER :: EddVisT5N09D1 = 5365 + INTEGER(IntKi), PARAMETER :: EddVisT5N09D2 = 5366 + INTEGER(IntKi), PARAMETER :: EddVisT5N09D3 = 5367 + INTEGER(IntKi), PARAMETER :: EddVisT5N09D4 = 5368 + INTEGER(IntKi), PARAMETER :: EddVisT5N09D5 = 5369 + INTEGER(IntKi), PARAMETER :: EddVisT5N09D6 = 5370 + INTEGER(IntKi), PARAMETER :: EddVisT5N09D7 = 5371 + INTEGER(IntKi), PARAMETER :: EddVisT5N09D8 = 5372 + INTEGER(IntKi), PARAMETER :: EddVisT5N09D9 = 5373 + INTEGER(IntKi), PARAMETER :: EddVisT5N10D1 = 5374 + INTEGER(IntKi), PARAMETER :: EddVisT5N10D2 = 5375 + INTEGER(IntKi), PARAMETER :: EddVisT5N10D3 = 5376 + INTEGER(IntKi), PARAMETER :: EddVisT5N10D4 = 5377 + INTEGER(IntKi), PARAMETER :: EddVisT5N10D5 = 5378 + INTEGER(IntKi), PARAMETER :: EddVisT5N10D6 = 5379 + INTEGER(IntKi), PARAMETER :: EddVisT5N10D7 = 5380 + INTEGER(IntKi), PARAMETER :: EddVisT5N10D8 = 5381 + INTEGER(IntKi), PARAMETER :: EddVisT5N10D9 = 5382 + INTEGER(IntKi), PARAMETER :: EddVisT5N11D1 = 5383 + INTEGER(IntKi), PARAMETER :: EddVisT5N11D2 = 5384 + INTEGER(IntKi), PARAMETER :: EddVisT5N11D3 = 5385 + INTEGER(IntKi), PARAMETER :: EddVisT5N11D4 = 5386 + INTEGER(IntKi), PARAMETER :: EddVisT5N11D5 = 5387 + INTEGER(IntKi), PARAMETER :: EddVisT5N11D6 = 5388 + INTEGER(IntKi), PARAMETER :: EddVisT5N11D7 = 5389 + INTEGER(IntKi), PARAMETER :: EddVisT5N11D8 = 5390 + INTEGER(IntKi), PARAMETER :: EddVisT5N11D9 = 5391 + INTEGER(IntKi), PARAMETER :: EddVisT5N12D1 = 5392 + INTEGER(IntKi), PARAMETER :: EddVisT5N12D2 = 5393 + INTEGER(IntKi), PARAMETER :: EddVisT5N12D3 = 5394 + INTEGER(IntKi), PARAMETER :: EddVisT5N12D4 = 5395 + INTEGER(IntKi), PARAMETER :: EddVisT5N12D5 = 5396 + INTEGER(IntKi), PARAMETER :: EddVisT5N12D6 = 5397 + INTEGER(IntKi), PARAMETER :: EddVisT5N12D7 = 5398 + INTEGER(IntKi), PARAMETER :: EddVisT5N12D8 = 5399 + INTEGER(IntKi), PARAMETER :: EddVisT5N12D9 = 5400 + INTEGER(IntKi), PARAMETER :: EddVisT5N13D1 = 5401 + INTEGER(IntKi), PARAMETER :: EddVisT5N13D2 = 5402 + INTEGER(IntKi), PARAMETER :: EddVisT5N13D3 = 5403 + INTEGER(IntKi), PARAMETER :: EddVisT5N13D4 = 5404 + INTEGER(IntKi), PARAMETER :: EddVisT5N13D5 = 5405 + INTEGER(IntKi), PARAMETER :: EddVisT5N13D6 = 5406 + INTEGER(IntKi), PARAMETER :: EddVisT5N13D7 = 5407 + INTEGER(IntKi), PARAMETER :: EddVisT5N13D8 = 5408 + INTEGER(IntKi), PARAMETER :: EddVisT5N13D9 = 5409 + INTEGER(IntKi), PARAMETER :: EddVisT5N14D1 = 5410 + INTEGER(IntKi), PARAMETER :: EddVisT5N14D2 = 5411 + INTEGER(IntKi), PARAMETER :: EddVisT5N14D3 = 5412 + INTEGER(IntKi), PARAMETER :: EddVisT5N14D4 = 5413 + INTEGER(IntKi), PARAMETER :: EddVisT5N14D5 = 5414 + INTEGER(IntKi), PARAMETER :: EddVisT5N14D6 = 5415 + INTEGER(IntKi), PARAMETER :: EddVisT5N14D7 = 5416 + INTEGER(IntKi), PARAMETER :: EddVisT5N14D8 = 5417 + INTEGER(IntKi), PARAMETER :: EddVisT5N14D9 = 5418 + INTEGER(IntKi), PARAMETER :: EddVisT5N15D1 = 5419 + INTEGER(IntKi), PARAMETER :: EddVisT5N15D2 = 5420 + INTEGER(IntKi), PARAMETER :: EddVisT5N15D3 = 5421 + INTEGER(IntKi), PARAMETER :: EddVisT5N15D4 = 5422 + INTEGER(IntKi), PARAMETER :: EddVisT5N15D5 = 5423 + INTEGER(IntKi), PARAMETER :: EddVisT5N15D6 = 5424 + INTEGER(IntKi), PARAMETER :: EddVisT5N15D7 = 5425 + INTEGER(IntKi), PARAMETER :: EddVisT5N15D8 = 5426 + INTEGER(IntKi), PARAMETER :: EddVisT5N15D9 = 5427 + INTEGER(IntKi), PARAMETER :: EddVisT5N16D1 = 5428 + INTEGER(IntKi), PARAMETER :: EddVisT5N16D2 = 5429 + INTEGER(IntKi), PARAMETER :: EddVisT5N16D3 = 5430 + INTEGER(IntKi), PARAMETER :: EddVisT5N16D4 = 5431 + INTEGER(IntKi), PARAMETER :: EddVisT5N16D5 = 5432 + INTEGER(IntKi), PARAMETER :: EddVisT5N16D6 = 5433 + INTEGER(IntKi), PARAMETER :: EddVisT5N16D7 = 5434 + INTEGER(IntKi), PARAMETER :: EddVisT5N16D8 = 5435 + INTEGER(IntKi), PARAMETER :: EddVisT5N16D9 = 5436 + INTEGER(IntKi), PARAMETER :: EddVisT5N17D1 = 5437 + INTEGER(IntKi), PARAMETER :: EddVisT5N17D2 = 5438 + INTEGER(IntKi), PARAMETER :: EddVisT5N17D3 = 5439 + INTEGER(IntKi), PARAMETER :: EddVisT5N17D4 = 5440 + INTEGER(IntKi), PARAMETER :: EddVisT5N17D5 = 5441 + INTEGER(IntKi), PARAMETER :: EddVisT5N17D6 = 5442 + INTEGER(IntKi), PARAMETER :: EddVisT5N17D7 = 5443 + INTEGER(IntKi), PARAMETER :: EddVisT5N17D8 = 5444 + INTEGER(IntKi), PARAMETER :: EddVisT5N17D9 = 5445 + INTEGER(IntKi), PARAMETER :: EddVisT5N18D1 = 5446 + INTEGER(IntKi), PARAMETER :: EddVisT5N18D2 = 5447 + INTEGER(IntKi), PARAMETER :: EddVisT5N18D3 = 5448 + INTEGER(IntKi), PARAMETER :: EddVisT5N18D4 = 5449 + INTEGER(IntKi), PARAMETER :: EddVisT5N18D5 = 5450 + INTEGER(IntKi), PARAMETER :: EddVisT5N18D6 = 5451 + INTEGER(IntKi), PARAMETER :: EddVisT5N18D7 = 5452 + INTEGER(IntKi), PARAMETER :: EddVisT5N18D8 = 5453 + INTEGER(IntKi), PARAMETER :: EddVisT5N18D9 = 5454 + INTEGER(IntKi), PARAMETER :: EddVisT5N19D1 = 5455 + INTEGER(IntKi), PARAMETER :: EddVisT5N19D2 = 5456 + INTEGER(IntKi), PARAMETER :: EddVisT5N19D3 = 5457 + INTEGER(IntKi), PARAMETER :: EddVisT5N19D4 = 5458 + INTEGER(IntKi), PARAMETER :: EddVisT5N19D5 = 5459 + INTEGER(IntKi), PARAMETER :: EddVisT5N19D6 = 5460 + INTEGER(IntKi), PARAMETER :: EddVisT5N19D7 = 5461 + INTEGER(IntKi), PARAMETER :: EddVisT5N19D8 = 5462 + INTEGER(IntKi), PARAMETER :: EddVisT5N19D9 = 5463 + INTEGER(IntKi), PARAMETER :: EddVisT5N20D1 = 5464 + INTEGER(IntKi), PARAMETER :: EddVisT5N20D2 = 5465 + INTEGER(IntKi), PARAMETER :: EddVisT5N20D3 = 5466 + INTEGER(IntKi), PARAMETER :: EddVisT5N20D4 = 5467 + INTEGER(IntKi), PARAMETER :: EddVisT5N20D5 = 5468 + INTEGER(IntKi), PARAMETER :: EddVisT5N20D6 = 5469 + INTEGER(IntKi), PARAMETER :: EddVisT5N20D7 = 5470 + INTEGER(IntKi), PARAMETER :: EddVisT5N20D8 = 5471 + INTEGER(IntKi), PARAMETER :: EddVisT5N20D9 = 5472 + INTEGER(IntKi), PARAMETER :: EddVisT6N01D1 = 5473 + INTEGER(IntKi), PARAMETER :: EddVisT6N01D2 = 5474 + INTEGER(IntKi), PARAMETER :: EddVisT6N01D3 = 5475 + INTEGER(IntKi), PARAMETER :: EddVisT6N01D4 = 5476 + INTEGER(IntKi), PARAMETER :: EddVisT6N01D5 = 5477 + INTEGER(IntKi), PARAMETER :: EddVisT6N01D6 = 5478 + INTEGER(IntKi), PARAMETER :: EddVisT6N01D7 = 5479 + INTEGER(IntKi), PARAMETER :: EddVisT6N01D8 = 5480 + INTEGER(IntKi), PARAMETER :: EddVisT6N01D9 = 5481 + INTEGER(IntKi), PARAMETER :: EddVisT6N02D1 = 5482 + INTEGER(IntKi), PARAMETER :: EddVisT6N02D2 = 5483 + INTEGER(IntKi), PARAMETER :: EddVisT6N02D3 = 5484 + INTEGER(IntKi), PARAMETER :: EddVisT6N02D4 = 5485 + INTEGER(IntKi), PARAMETER :: EddVisT6N02D5 = 5486 + INTEGER(IntKi), PARAMETER :: EddVisT6N02D6 = 5487 + INTEGER(IntKi), PARAMETER :: EddVisT6N02D7 = 5488 + INTEGER(IntKi), PARAMETER :: EddVisT6N02D8 = 5489 + INTEGER(IntKi), PARAMETER :: EddVisT6N02D9 = 5490 + INTEGER(IntKi), PARAMETER :: EddVisT6N03D1 = 5491 + INTEGER(IntKi), PARAMETER :: EddVisT6N03D2 = 5492 + INTEGER(IntKi), PARAMETER :: EddVisT6N03D3 = 5493 + INTEGER(IntKi), PARAMETER :: EddVisT6N03D4 = 5494 + INTEGER(IntKi), PARAMETER :: EddVisT6N03D5 = 5495 + INTEGER(IntKi), PARAMETER :: EddVisT6N03D6 = 5496 + INTEGER(IntKi), PARAMETER :: EddVisT6N03D7 = 5497 + INTEGER(IntKi), PARAMETER :: EddVisT6N03D8 = 5498 + INTEGER(IntKi), PARAMETER :: EddVisT6N03D9 = 5499 + INTEGER(IntKi), PARAMETER :: EddVisT6N04D1 = 5500 + INTEGER(IntKi), PARAMETER :: EddVisT6N04D2 = 5501 + INTEGER(IntKi), PARAMETER :: EddVisT6N04D3 = 5502 + INTEGER(IntKi), PARAMETER :: EddVisT6N04D4 = 5503 + INTEGER(IntKi), PARAMETER :: EddVisT6N04D5 = 5504 + INTEGER(IntKi), PARAMETER :: EddVisT6N04D6 = 5505 + INTEGER(IntKi), PARAMETER :: EddVisT6N04D7 = 5506 + INTEGER(IntKi), PARAMETER :: EddVisT6N04D8 = 5507 + INTEGER(IntKi), PARAMETER :: EddVisT6N04D9 = 5508 + INTEGER(IntKi), PARAMETER :: EddVisT6N05D1 = 5509 + INTEGER(IntKi), PARAMETER :: EddVisT6N05D2 = 5510 + INTEGER(IntKi), PARAMETER :: EddVisT6N05D3 = 5511 + INTEGER(IntKi), PARAMETER :: EddVisT6N05D4 = 5512 + INTEGER(IntKi), PARAMETER :: EddVisT6N05D5 = 5513 + INTEGER(IntKi), PARAMETER :: EddVisT6N05D6 = 5514 + INTEGER(IntKi), PARAMETER :: EddVisT6N05D7 = 5515 + INTEGER(IntKi), PARAMETER :: EddVisT6N05D8 = 5516 + INTEGER(IntKi), PARAMETER :: EddVisT6N05D9 = 5517 + INTEGER(IntKi), PARAMETER :: EddVisT6N06D1 = 5518 + INTEGER(IntKi), PARAMETER :: EddVisT6N06D2 = 5519 + INTEGER(IntKi), PARAMETER :: EddVisT6N06D3 = 5520 + INTEGER(IntKi), PARAMETER :: EddVisT6N06D4 = 5521 + INTEGER(IntKi), PARAMETER :: EddVisT6N06D5 = 5522 + INTEGER(IntKi), PARAMETER :: EddVisT6N06D6 = 5523 + INTEGER(IntKi), PARAMETER :: EddVisT6N06D7 = 5524 + INTEGER(IntKi), PARAMETER :: EddVisT6N06D8 = 5525 + INTEGER(IntKi), PARAMETER :: EddVisT6N06D9 = 5526 + INTEGER(IntKi), PARAMETER :: EddVisT6N07D1 = 5527 + INTEGER(IntKi), PARAMETER :: EddVisT6N07D2 = 5528 + INTEGER(IntKi), PARAMETER :: EddVisT6N07D3 = 5529 + INTEGER(IntKi), PARAMETER :: EddVisT6N07D4 = 5530 + INTEGER(IntKi), PARAMETER :: EddVisT6N07D5 = 5531 + INTEGER(IntKi), PARAMETER :: EddVisT6N07D6 = 5532 + INTEGER(IntKi), PARAMETER :: EddVisT6N07D7 = 5533 + INTEGER(IntKi), PARAMETER :: EddVisT6N07D8 = 5534 + INTEGER(IntKi), PARAMETER :: EddVisT6N07D9 = 5535 + INTEGER(IntKi), PARAMETER :: EddVisT6N08D1 = 5536 + INTEGER(IntKi), PARAMETER :: EddVisT6N08D2 = 5537 + INTEGER(IntKi), PARAMETER :: EddVisT6N08D3 = 5538 + INTEGER(IntKi), PARAMETER :: EddVisT6N08D4 = 5539 + INTEGER(IntKi), PARAMETER :: EddVisT6N08D5 = 5540 + INTEGER(IntKi), PARAMETER :: EddVisT6N08D6 = 5541 + INTEGER(IntKi), PARAMETER :: EddVisT6N08D7 = 5542 + INTEGER(IntKi), PARAMETER :: EddVisT6N08D8 = 5543 + INTEGER(IntKi), PARAMETER :: EddVisT6N08D9 = 5544 + INTEGER(IntKi), PARAMETER :: EddVisT6N09D1 = 5545 + INTEGER(IntKi), PARAMETER :: EddVisT6N09D2 = 5546 + INTEGER(IntKi), PARAMETER :: EddVisT6N09D3 = 5547 + INTEGER(IntKi), PARAMETER :: EddVisT6N09D4 = 5548 + INTEGER(IntKi), PARAMETER :: EddVisT6N09D5 = 5549 + INTEGER(IntKi), PARAMETER :: EddVisT6N09D6 = 5550 + INTEGER(IntKi), PARAMETER :: EddVisT6N09D7 = 5551 + INTEGER(IntKi), PARAMETER :: EddVisT6N09D8 = 5552 + INTEGER(IntKi), PARAMETER :: EddVisT6N09D9 = 5553 + INTEGER(IntKi), PARAMETER :: EddVisT6N10D1 = 5554 + INTEGER(IntKi), PARAMETER :: EddVisT6N10D2 = 5555 + INTEGER(IntKi), PARAMETER :: EddVisT6N10D3 = 5556 + INTEGER(IntKi), PARAMETER :: EddVisT6N10D4 = 5557 + INTEGER(IntKi), PARAMETER :: EddVisT6N10D5 = 5558 + INTEGER(IntKi), PARAMETER :: EddVisT6N10D6 = 5559 + INTEGER(IntKi), PARAMETER :: EddVisT6N10D7 = 5560 + INTEGER(IntKi), PARAMETER :: EddVisT6N10D8 = 5561 + INTEGER(IntKi), PARAMETER :: EddVisT6N10D9 = 5562 + INTEGER(IntKi), PARAMETER :: EddVisT6N11D1 = 5563 + INTEGER(IntKi), PARAMETER :: EddVisT6N11D2 = 5564 + INTEGER(IntKi), PARAMETER :: EddVisT6N11D3 = 5565 + INTEGER(IntKi), PARAMETER :: EddVisT6N11D4 = 5566 + INTEGER(IntKi), PARAMETER :: EddVisT6N11D5 = 5567 + INTEGER(IntKi), PARAMETER :: EddVisT6N11D6 = 5568 + INTEGER(IntKi), PARAMETER :: EddVisT6N11D7 = 5569 + INTEGER(IntKi), PARAMETER :: EddVisT6N11D8 = 5570 + INTEGER(IntKi), PARAMETER :: EddVisT6N11D9 = 5571 + INTEGER(IntKi), PARAMETER :: EddVisT6N12D1 = 5572 + INTEGER(IntKi), PARAMETER :: EddVisT6N12D2 = 5573 + INTEGER(IntKi), PARAMETER :: EddVisT6N12D3 = 5574 + INTEGER(IntKi), PARAMETER :: EddVisT6N12D4 = 5575 + INTEGER(IntKi), PARAMETER :: EddVisT6N12D5 = 5576 + INTEGER(IntKi), PARAMETER :: EddVisT6N12D6 = 5577 + INTEGER(IntKi), PARAMETER :: EddVisT6N12D7 = 5578 + INTEGER(IntKi), PARAMETER :: EddVisT6N12D8 = 5579 + INTEGER(IntKi), PARAMETER :: EddVisT6N12D9 = 5580 + INTEGER(IntKi), PARAMETER :: EddVisT6N13D1 = 5581 + INTEGER(IntKi), PARAMETER :: EddVisT6N13D2 = 5582 + INTEGER(IntKi), PARAMETER :: EddVisT6N13D3 = 5583 + INTEGER(IntKi), PARAMETER :: EddVisT6N13D4 = 5584 + INTEGER(IntKi), PARAMETER :: EddVisT6N13D5 = 5585 + INTEGER(IntKi), PARAMETER :: EddVisT6N13D6 = 5586 + INTEGER(IntKi), PARAMETER :: EddVisT6N13D7 = 5587 + INTEGER(IntKi), PARAMETER :: EddVisT6N13D8 = 5588 + INTEGER(IntKi), PARAMETER :: EddVisT6N13D9 = 5589 + INTEGER(IntKi), PARAMETER :: EddVisT6N14D1 = 5590 + INTEGER(IntKi), PARAMETER :: EddVisT6N14D2 = 5591 + INTEGER(IntKi), PARAMETER :: EddVisT6N14D3 = 5592 + INTEGER(IntKi), PARAMETER :: EddVisT6N14D4 = 5593 + INTEGER(IntKi), PARAMETER :: EddVisT6N14D5 = 5594 + INTEGER(IntKi), PARAMETER :: EddVisT6N14D6 = 5595 + INTEGER(IntKi), PARAMETER :: EddVisT6N14D7 = 5596 + INTEGER(IntKi), PARAMETER :: EddVisT6N14D8 = 5597 + INTEGER(IntKi), PARAMETER :: EddVisT6N14D9 = 5598 + INTEGER(IntKi), PARAMETER :: EddVisT6N15D1 = 5599 + INTEGER(IntKi), PARAMETER :: EddVisT6N15D2 = 5600 + INTEGER(IntKi), PARAMETER :: EddVisT6N15D3 = 5601 + INTEGER(IntKi), PARAMETER :: EddVisT6N15D4 = 5602 + INTEGER(IntKi), PARAMETER :: EddVisT6N15D5 = 5603 + INTEGER(IntKi), PARAMETER :: EddVisT6N15D6 = 5604 + INTEGER(IntKi), PARAMETER :: EddVisT6N15D7 = 5605 + INTEGER(IntKi), PARAMETER :: EddVisT6N15D8 = 5606 + INTEGER(IntKi), PARAMETER :: EddVisT6N15D9 = 5607 + INTEGER(IntKi), PARAMETER :: EddVisT6N16D1 = 5608 + INTEGER(IntKi), PARAMETER :: EddVisT6N16D2 = 5609 + INTEGER(IntKi), PARAMETER :: EddVisT6N16D3 = 5610 + INTEGER(IntKi), PARAMETER :: EddVisT6N16D4 = 5611 + INTEGER(IntKi), PARAMETER :: EddVisT6N16D5 = 5612 + INTEGER(IntKi), PARAMETER :: EddVisT6N16D6 = 5613 + INTEGER(IntKi), PARAMETER :: EddVisT6N16D7 = 5614 + INTEGER(IntKi), PARAMETER :: EddVisT6N16D8 = 5615 + INTEGER(IntKi), PARAMETER :: EddVisT6N16D9 = 5616 + INTEGER(IntKi), PARAMETER :: EddVisT6N17D1 = 5617 + INTEGER(IntKi), PARAMETER :: EddVisT6N17D2 = 5618 + INTEGER(IntKi), PARAMETER :: EddVisT6N17D3 = 5619 + INTEGER(IntKi), PARAMETER :: EddVisT6N17D4 = 5620 + INTEGER(IntKi), PARAMETER :: EddVisT6N17D5 = 5621 + INTEGER(IntKi), PARAMETER :: EddVisT6N17D6 = 5622 + INTEGER(IntKi), PARAMETER :: EddVisT6N17D7 = 5623 + INTEGER(IntKi), PARAMETER :: EddVisT6N17D8 = 5624 + INTEGER(IntKi), PARAMETER :: EddVisT6N17D9 = 5625 + INTEGER(IntKi), PARAMETER :: EddVisT6N18D1 = 5626 + INTEGER(IntKi), PARAMETER :: EddVisT6N18D2 = 5627 + INTEGER(IntKi), PARAMETER :: EddVisT6N18D3 = 5628 + INTEGER(IntKi), PARAMETER :: EddVisT6N18D4 = 5629 + INTEGER(IntKi), PARAMETER :: EddVisT6N18D5 = 5630 + INTEGER(IntKi), PARAMETER :: EddVisT6N18D6 = 5631 + INTEGER(IntKi), PARAMETER :: EddVisT6N18D7 = 5632 + INTEGER(IntKi), PARAMETER :: EddVisT6N18D8 = 5633 + INTEGER(IntKi), PARAMETER :: EddVisT6N18D9 = 5634 + INTEGER(IntKi), PARAMETER :: EddVisT6N19D1 = 5635 + INTEGER(IntKi), PARAMETER :: EddVisT6N19D2 = 5636 + INTEGER(IntKi), PARAMETER :: EddVisT6N19D3 = 5637 + INTEGER(IntKi), PARAMETER :: EddVisT6N19D4 = 5638 + INTEGER(IntKi), PARAMETER :: EddVisT6N19D5 = 5639 + INTEGER(IntKi), PARAMETER :: EddVisT6N19D6 = 5640 + INTEGER(IntKi), PARAMETER :: EddVisT6N19D7 = 5641 + INTEGER(IntKi), PARAMETER :: EddVisT6N19D8 = 5642 + INTEGER(IntKi), PARAMETER :: EddVisT6N19D9 = 5643 + INTEGER(IntKi), PARAMETER :: EddVisT6N20D1 = 5644 + INTEGER(IntKi), PARAMETER :: EddVisT6N20D2 = 5645 + INTEGER(IntKi), PARAMETER :: EddVisT6N20D3 = 5646 + INTEGER(IntKi), PARAMETER :: EddVisT6N20D4 = 5647 + INTEGER(IntKi), PARAMETER :: EddVisT6N20D5 = 5648 + INTEGER(IntKi), PARAMETER :: EddVisT6N20D6 = 5649 + INTEGER(IntKi), PARAMETER :: EddVisT6N20D7 = 5650 + INTEGER(IntKi), PARAMETER :: EddVisT6N20D8 = 5651 + INTEGER(IntKi), PARAMETER :: EddVisT6N20D9 = 5652 + INTEGER(IntKi), PARAMETER :: EddVisT7N01D1 = 5653 + INTEGER(IntKi), PARAMETER :: EddVisT7N01D2 = 5654 + INTEGER(IntKi), PARAMETER :: EddVisT7N01D3 = 5655 + INTEGER(IntKi), PARAMETER :: EddVisT7N01D4 = 5656 + INTEGER(IntKi), PARAMETER :: EddVisT7N01D5 = 5657 + INTEGER(IntKi), PARAMETER :: EddVisT7N01D6 = 5658 + INTEGER(IntKi), PARAMETER :: EddVisT7N01D7 = 5659 + INTEGER(IntKi), PARAMETER :: EddVisT7N01D8 = 5660 + INTEGER(IntKi), PARAMETER :: EddVisT7N01D9 = 5661 + INTEGER(IntKi), PARAMETER :: EddVisT7N02D1 = 5662 + INTEGER(IntKi), PARAMETER :: EddVisT7N02D2 = 5663 + INTEGER(IntKi), PARAMETER :: EddVisT7N02D3 = 5664 + INTEGER(IntKi), PARAMETER :: EddVisT7N02D4 = 5665 + INTEGER(IntKi), PARAMETER :: EddVisT7N02D5 = 5666 + INTEGER(IntKi), PARAMETER :: EddVisT7N02D6 = 5667 + INTEGER(IntKi), PARAMETER :: EddVisT7N02D7 = 5668 + INTEGER(IntKi), PARAMETER :: EddVisT7N02D8 = 5669 + INTEGER(IntKi), PARAMETER :: EddVisT7N02D9 = 5670 + INTEGER(IntKi), PARAMETER :: EddVisT7N03D1 = 5671 + INTEGER(IntKi), PARAMETER :: EddVisT7N03D2 = 5672 + INTEGER(IntKi), PARAMETER :: EddVisT7N03D3 = 5673 + INTEGER(IntKi), PARAMETER :: EddVisT7N03D4 = 5674 + INTEGER(IntKi), PARAMETER :: EddVisT7N03D5 = 5675 + INTEGER(IntKi), PARAMETER :: EddVisT7N03D6 = 5676 + INTEGER(IntKi), PARAMETER :: EddVisT7N03D7 = 5677 + INTEGER(IntKi), PARAMETER :: EddVisT7N03D8 = 5678 + INTEGER(IntKi), PARAMETER :: EddVisT7N03D9 = 5679 + INTEGER(IntKi), PARAMETER :: EddVisT7N04D1 = 5680 + INTEGER(IntKi), PARAMETER :: EddVisT7N04D2 = 5681 + INTEGER(IntKi), PARAMETER :: EddVisT7N04D3 = 5682 + INTEGER(IntKi), PARAMETER :: EddVisT7N04D4 = 5683 + INTEGER(IntKi), PARAMETER :: EddVisT7N04D5 = 5684 + INTEGER(IntKi), PARAMETER :: EddVisT7N04D6 = 5685 + INTEGER(IntKi), PARAMETER :: EddVisT7N04D7 = 5686 + INTEGER(IntKi), PARAMETER :: EddVisT7N04D8 = 5687 + INTEGER(IntKi), PARAMETER :: EddVisT7N04D9 = 5688 + INTEGER(IntKi), PARAMETER :: EddVisT7N05D1 = 5689 + INTEGER(IntKi), PARAMETER :: EddVisT7N05D2 = 5690 + INTEGER(IntKi), PARAMETER :: EddVisT7N05D3 = 5691 + INTEGER(IntKi), PARAMETER :: EddVisT7N05D4 = 5692 + INTEGER(IntKi), PARAMETER :: EddVisT7N05D5 = 5693 + INTEGER(IntKi), PARAMETER :: EddVisT7N05D6 = 5694 + INTEGER(IntKi), PARAMETER :: EddVisT7N05D7 = 5695 + INTEGER(IntKi), PARAMETER :: EddVisT7N05D8 = 5696 + INTEGER(IntKi), PARAMETER :: EddVisT7N05D9 = 5697 + INTEGER(IntKi), PARAMETER :: EddVisT7N06D1 = 5698 + INTEGER(IntKi), PARAMETER :: EddVisT7N06D2 = 5699 + INTEGER(IntKi), PARAMETER :: EddVisT7N06D3 = 5700 + INTEGER(IntKi), PARAMETER :: EddVisT7N06D4 = 5701 + INTEGER(IntKi), PARAMETER :: EddVisT7N06D5 = 5702 + INTEGER(IntKi), PARAMETER :: EddVisT7N06D6 = 5703 + INTEGER(IntKi), PARAMETER :: EddVisT7N06D7 = 5704 + INTEGER(IntKi), PARAMETER :: EddVisT7N06D8 = 5705 + INTEGER(IntKi), PARAMETER :: EddVisT7N06D9 = 5706 + INTEGER(IntKi), PARAMETER :: EddVisT7N07D1 = 5707 + INTEGER(IntKi), PARAMETER :: EddVisT7N07D2 = 5708 + INTEGER(IntKi), PARAMETER :: EddVisT7N07D3 = 5709 + INTEGER(IntKi), PARAMETER :: EddVisT7N07D4 = 5710 + INTEGER(IntKi), PARAMETER :: EddVisT7N07D5 = 5711 + INTEGER(IntKi), PARAMETER :: EddVisT7N07D6 = 5712 + INTEGER(IntKi), PARAMETER :: EddVisT7N07D7 = 5713 + INTEGER(IntKi), PARAMETER :: EddVisT7N07D8 = 5714 + INTEGER(IntKi), PARAMETER :: EddVisT7N07D9 = 5715 + INTEGER(IntKi), PARAMETER :: EddVisT7N08D1 = 5716 + INTEGER(IntKi), PARAMETER :: EddVisT7N08D2 = 5717 + INTEGER(IntKi), PARAMETER :: EddVisT7N08D3 = 5718 + INTEGER(IntKi), PARAMETER :: EddVisT7N08D4 = 5719 + INTEGER(IntKi), PARAMETER :: EddVisT7N08D5 = 5720 + INTEGER(IntKi), PARAMETER :: EddVisT7N08D6 = 5721 + INTEGER(IntKi), PARAMETER :: EddVisT7N08D7 = 5722 + INTEGER(IntKi), PARAMETER :: EddVisT7N08D8 = 5723 + INTEGER(IntKi), PARAMETER :: EddVisT7N08D9 = 5724 + INTEGER(IntKi), PARAMETER :: EddVisT7N09D1 = 5725 + INTEGER(IntKi), PARAMETER :: EddVisT7N09D2 = 5726 + INTEGER(IntKi), PARAMETER :: EddVisT7N09D3 = 5727 + INTEGER(IntKi), PARAMETER :: EddVisT7N09D4 = 5728 + INTEGER(IntKi), PARAMETER :: EddVisT7N09D5 = 5729 + INTEGER(IntKi), PARAMETER :: EddVisT7N09D6 = 5730 + INTEGER(IntKi), PARAMETER :: EddVisT7N09D7 = 5731 + INTEGER(IntKi), PARAMETER :: EddVisT7N09D8 = 5732 + INTEGER(IntKi), PARAMETER :: EddVisT7N09D9 = 5733 + INTEGER(IntKi), PARAMETER :: EddVisT7N10D1 = 5734 + INTEGER(IntKi), PARAMETER :: EddVisT7N10D2 = 5735 + INTEGER(IntKi), PARAMETER :: EddVisT7N10D3 = 5736 + INTEGER(IntKi), PARAMETER :: EddVisT7N10D4 = 5737 + INTEGER(IntKi), PARAMETER :: EddVisT7N10D5 = 5738 + INTEGER(IntKi), PARAMETER :: EddVisT7N10D6 = 5739 + INTEGER(IntKi), PARAMETER :: EddVisT7N10D7 = 5740 + INTEGER(IntKi), PARAMETER :: EddVisT7N10D8 = 5741 + INTEGER(IntKi), PARAMETER :: EddVisT7N10D9 = 5742 + INTEGER(IntKi), PARAMETER :: EddVisT7N11D1 = 5743 + INTEGER(IntKi), PARAMETER :: EddVisT7N11D2 = 5744 + INTEGER(IntKi), PARAMETER :: EddVisT7N11D3 = 5745 + INTEGER(IntKi), PARAMETER :: EddVisT7N11D4 = 5746 + INTEGER(IntKi), PARAMETER :: EddVisT7N11D5 = 5747 + INTEGER(IntKi), PARAMETER :: EddVisT7N11D6 = 5748 + INTEGER(IntKi), PARAMETER :: EddVisT7N11D7 = 5749 + INTEGER(IntKi), PARAMETER :: EddVisT7N11D8 = 5750 + INTEGER(IntKi), PARAMETER :: EddVisT7N11D9 = 5751 + INTEGER(IntKi), PARAMETER :: EddVisT7N12D1 = 5752 + INTEGER(IntKi), PARAMETER :: EddVisT7N12D2 = 5753 + INTEGER(IntKi), PARAMETER :: EddVisT7N12D3 = 5754 + INTEGER(IntKi), PARAMETER :: EddVisT7N12D4 = 5755 + INTEGER(IntKi), PARAMETER :: EddVisT7N12D5 = 5756 + INTEGER(IntKi), PARAMETER :: EddVisT7N12D6 = 5757 + INTEGER(IntKi), PARAMETER :: EddVisT7N12D7 = 5758 + INTEGER(IntKi), PARAMETER :: EddVisT7N12D8 = 5759 + INTEGER(IntKi), PARAMETER :: EddVisT7N12D9 = 5760 + INTEGER(IntKi), PARAMETER :: EddVisT7N13D1 = 5761 + INTEGER(IntKi), PARAMETER :: EddVisT7N13D2 = 5762 + INTEGER(IntKi), PARAMETER :: EddVisT7N13D3 = 5763 + INTEGER(IntKi), PARAMETER :: EddVisT7N13D4 = 5764 + INTEGER(IntKi), PARAMETER :: EddVisT7N13D5 = 5765 + INTEGER(IntKi), PARAMETER :: EddVisT7N13D6 = 5766 + INTEGER(IntKi), PARAMETER :: EddVisT7N13D7 = 5767 + INTEGER(IntKi), PARAMETER :: EddVisT7N13D8 = 5768 + INTEGER(IntKi), PARAMETER :: EddVisT7N13D9 = 5769 + INTEGER(IntKi), PARAMETER :: EddVisT7N14D1 = 5770 + INTEGER(IntKi), PARAMETER :: EddVisT7N14D2 = 5771 + INTEGER(IntKi), PARAMETER :: EddVisT7N14D3 = 5772 + INTEGER(IntKi), PARAMETER :: EddVisT7N14D4 = 5773 + INTEGER(IntKi), PARAMETER :: EddVisT7N14D5 = 5774 + INTEGER(IntKi), PARAMETER :: EddVisT7N14D6 = 5775 + INTEGER(IntKi), PARAMETER :: EddVisT7N14D7 = 5776 + INTEGER(IntKi), PARAMETER :: EddVisT7N14D8 = 5777 + INTEGER(IntKi), PARAMETER :: EddVisT7N14D9 = 5778 + INTEGER(IntKi), PARAMETER :: EddVisT7N15D1 = 5779 + INTEGER(IntKi), PARAMETER :: EddVisT7N15D2 = 5780 + INTEGER(IntKi), PARAMETER :: EddVisT7N15D3 = 5781 + INTEGER(IntKi), PARAMETER :: EddVisT7N15D4 = 5782 + INTEGER(IntKi), PARAMETER :: EddVisT7N15D5 = 5783 + INTEGER(IntKi), PARAMETER :: EddVisT7N15D6 = 5784 + INTEGER(IntKi), PARAMETER :: EddVisT7N15D7 = 5785 + INTEGER(IntKi), PARAMETER :: EddVisT7N15D8 = 5786 + INTEGER(IntKi), PARAMETER :: EddVisT7N15D9 = 5787 + INTEGER(IntKi), PARAMETER :: EddVisT7N16D1 = 5788 + INTEGER(IntKi), PARAMETER :: EddVisT7N16D2 = 5789 + INTEGER(IntKi), PARAMETER :: EddVisT7N16D3 = 5790 + INTEGER(IntKi), PARAMETER :: EddVisT7N16D4 = 5791 + INTEGER(IntKi), PARAMETER :: EddVisT7N16D5 = 5792 + INTEGER(IntKi), PARAMETER :: EddVisT7N16D6 = 5793 + INTEGER(IntKi), PARAMETER :: EddVisT7N16D7 = 5794 + INTEGER(IntKi), PARAMETER :: EddVisT7N16D8 = 5795 + INTEGER(IntKi), PARAMETER :: EddVisT7N16D9 = 5796 + INTEGER(IntKi), PARAMETER :: EddVisT7N17D1 = 5797 + INTEGER(IntKi), PARAMETER :: EddVisT7N17D2 = 5798 + INTEGER(IntKi), PARAMETER :: EddVisT7N17D3 = 5799 + INTEGER(IntKi), PARAMETER :: EddVisT7N17D4 = 5800 + INTEGER(IntKi), PARAMETER :: EddVisT7N17D5 = 5801 + INTEGER(IntKi), PARAMETER :: EddVisT7N17D6 = 5802 + INTEGER(IntKi), PARAMETER :: EddVisT7N17D7 = 5803 + INTEGER(IntKi), PARAMETER :: EddVisT7N17D8 = 5804 + INTEGER(IntKi), PARAMETER :: EddVisT7N17D9 = 5805 + INTEGER(IntKi), PARAMETER :: EddVisT7N18D1 = 5806 + INTEGER(IntKi), PARAMETER :: EddVisT7N18D2 = 5807 + INTEGER(IntKi), PARAMETER :: EddVisT7N18D3 = 5808 + INTEGER(IntKi), PARAMETER :: EddVisT7N18D4 = 5809 + INTEGER(IntKi), PARAMETER :: EddVisT7N18D5 = 5810 + INTEGER(IntKi), PARAMETER :: EddVisT7N18D6 = 5811 + INTEGER(IntKi), PARAMETER :: EddVisT7N18D7 = 5812 + INTEGER(IntKi), PARAMETER :: EddVisT7N18D8 = 5813 + INTEGER(IntKi), PARAMETER :: EddVisT7N18D9 = 5814 + INTEGER(IntKi), PARAMETER :: EddVisT7N19D1 = 5815 + INTEGER(IntKi), PARAMETER :: EddVisT7N19D2 = 5816 + INTEGER(IntKi), PARAMETER :: EddVisT7N19D3 = 5817 + INTEGER(IntKi), PARAMETER :: EddVisT7N19D4 = 5818 + INTEGER(IntKi), PARAMETER :: EddVisT7N19D5 = 5819 + INTEGER(IntKi), PARAMETER :: EddVisT7N19D6 = 5820 + INTEGER(IntKi), PARAMETER :: EddVisT7N19D7 = 5821 + INTEGER(IntKi), PARAMETER :: EddVisT7N19D8 = 5822 + INTEGER(IntKi), PARAMETER :: EddVisT7N19D9 = 5823 + INTEGER(IntKi), PARAMETER :: EddVisT7N20D1 = 5824 + INTEGER(IntKi), PARAMETER :: EddVisT7N20D2 = 5825 + INTEGER(IntKi), PARAMETER :: EddVisT7N20D3 = 5826 + INTEGER(IntKi), PARAMETER :: EddVisT7N20D4 = 5827 + INTEGER(IntKi), PARAMETER :: EddVisT7N20D5 = 5828 + INTEGER(IntKi), PARAMETER :: EddVisT7N20D6 = 5829 + INTEGER(IntKi), PARAMETER :: EddVisT7N20D7 = 5830 + INTEGER(IntKi), PARAMETER :: EddVisT7N20D8 = 5831 + INTEGER(IntKi), PARAMETER :: EddVisT7N20D9 = 5832 + INTEGER(IntKi), PARAMETER :: EddVisT8N01D1 = 5833 + INTEGER(IntKi), PARAMETER :: EddVisT8N01D2 = 5834 + INTEGER(IntKi), PARAMETER :: EddVisT8N01D3 = 5835 + INTEGER(IntKi), PARAMETER :: EddVisT8N01D4 = 5836 + INTEGER(IntKi), PARAMETER :: EddVisT8N01D5 = 5837 + INTEGER(IntKi), PARAMETER :: EddVisT8N01D6 = 5838 + INTEGER(IntKi), PARAMETER :: EddVisT8N01D7 = 5839 + INTEGER(IntKi), PARAMETER :: EddVisT8N01D8 = 5840 + INTEGER(IntKi), PARAMETER :: EddVisT8N01D9 = 5841 + INTEGER(IntKi), PARAMETER :: EddVisT8N02D1 = 5842 + INTEGER(IntKi), PARAMETER :: EddVisT8N02D2 = 5843 + INTEGER(IntKi), PARAMETER :: EddVisT8N02D3 = 5844 + INTEGER(IntKi), PARAMETER :: EddVisT8N02D4 = 5845 + INTEGER(IntKi), PARAMETER :: EddVisT8N02D5 = 5846 + INTEGER(IntKi), PARAMETER :: EddVisT8N02D6 = 5847 + INTEGER(IntKi), PARAMETER :: EddVisT8N02D7 = 5848 + INTEGER(IntKi), PARAMETER :: EddVisT8N02D8 = 5849 + INTEGER(IntKi), PARAMETER :: EddVisT8N02D9 = 5850 + INTEGER(IntKi), PARAMETER :: EddVisT8N03D1 = 5851 + INTEGER(IntKi), PARAMETER :: EddVisT8N03D2 = 5852 + INTEGER(IntKi), PARAMETER :: EddVisT8N03D3 = 5853 + INTEGER(IntKi), PARAMETER :: EddVisT8N03D4 = 5854 + INTEGER(IntKi), PARAMETER :: EddVisT8N03D5 = 5855 + INTEGER(IntKi), PARAMETER :: EddVisT8N03D6 = 5856 + INTEGER(IntKi), PARAMETER :: EddVisT8N03D7 = 5857 + INTEGER(IntKi), PARAMETER :: EddVisT8N03D8 = 5858 + INTEGER(IntKi), PARAMETER :: EddVisT8N03D9 = 5859 + INTEGER(IntKi), PARAMETER :: EddVisT8N04D1 = 5860 + INTEGER(IntKi), PARAMETER :: EddVisT8N04D2 = 5861 + INTEGER(IntKi), PARAMETER :: EddVisT8N04D3 = 5862 + INTEGER(IntKi), PARAMETER :: EddVisT8N04D4 = 5863 + INTEGER(IntKi), PARAMETER :: EddVisT8N04D5 = 5864 + INTEGER(IntKi), PARAMETER :: EddVisT8N04D6 = 5865 + INTEGER(IntKi), PARAMETER :: EddVisT8N04D7 = 5866 + INTEGER(IntKi), PARAMETER :: EddVisT8N04D8 = 5867 + INTEGER(IntKi), PARAMETER :: EddVisT8N04D9 = 5868 + INTEGER(IntKi), PARAMETER :: EddVisT8N05D1 = 5869 + INTEGER(IntKi), PARAMETER :: EddVisT8N05D2 = 5870 + INTEGER(IntKi), PARAMETER :: EddVisT8N05D3 = 5871 + INTEGER(IntKi), PARAMETER :: EddVisT8N05D4 = 5872 + INTEGER(IntKi), PARAMETER :: EddVisT8N05D5 = 5873 + INTEGER(IntKi), PARAMETER :: EddVisT8N05D6 = 5874 + INTEGER(IntKi), PARAMETER :: EddVisT8N05D7 = 5875 + INTEGER(IntKi), PARAMETER :: EddVisT8N05D8 = 5876 + INTEGER(IntKi), PARAMETER :: EddVisT8N05D9 = 5877 + INTEGER(IntKi), PARAMETER :: EddVisT8N06D1 = 5878 + INTEGER(IntKi), PARAMETER :: EddVisT8N06D2 = 5879 + INTEGER(IntKi), PARAMETER :: EddVisT8N06D3 = 5880 + INTEGER(IntKi), PARAMETER :: EddVisT8N06D4 = 5881 + INTEGER(IntKi), PARAMETER :: EddVisT8N06D5 = 5882 + INTEGER(IntKi), PARAMETER :: EddVisT8N06D6 = 5883 + INTEGER(IntKi), PARAMETER :: EddVisT8N06D7 = 5884 + INTEGER(IntKi), PARAMETER :: EddVisT8N06D8 = 5885 + INTEGER(IntKi), PARAMETER :: EddVisT8N06D9 = 5886 + INTEGER(IntKi), PARAMETER :: EddVisT8N07D1 = 5887 + INTEGER(IntKi), PARAMETER :: EddVisT8N07D2 = 5888 + INTEGER(IntKi), PARAMETER :: EddVisT8N07D3 = 5889 + INTEGER(IntKi), PARAMETER :: EddVisT8N07D4 = 5890 + INTEGER(IntKi), PARAMETER :: EddVisT8N07D5 = 5891 + INTEGER(IntKi), PARAMETER :: EddVisT8N07D6 = 5892 + INTEGER(IntKi), PARAMETER :: EddVisT8N07D7 = 5893 + INTEGER(IntKi), PARAMETER :: EddVisT8N07D8 = 5894 + INTEGER(IntKi), PARAMETER :: EddVisT8N07D9 = 5895 + INTEGER(IntKi), PARAMETER :: EddVisT8N08D1 = 5896 + INTEGER(IntKi), PARAMETER :: EddVisT8N08D2 = 5897 + INTEGER(IntKi), PARAMETER :: EddVisT8N08D3 = 5898 + INTEGER(IntKi), PARAMETER :: EddVisT8N08D4 = 5899 + INTEGER(IntKi), PARAMETER :: EddVisT8N08D5 = 5900 + INTEGER(IntKi), PARAMETER :: EddVisT8N08D6 = 5901 + INTEGER(IntKi), PARAMETER :: EddVisT8N08D7 = 5902 + INTEGER(IntKi), PARAMETER :: EddVisT8N08D8 = 5903 + INTEGER(IntKi), PARAMETER :: EddVisT8N08D9 = 5904 + INTEGER(IntKi), PARAMETER :: EddVisT8N09D1 = 5905 + INTEGER(IntKi), PARAMETER :: EddVisT8N09D2 = 5906 + INTEGER(IntKi), PARAMETER :: EddVisT8N09D3 = 5907 + INTEGER(IntKi), PARAMETER :: EddVisT8N09D4 = 5908 + INTEGER(IntKi), PARAMETER :: EddVisT8N09D5 = 5909 + INTEGER(IntKi), PARAMETER :: EddVisT8N09D6 = 5910 + INTEGER(IntKi), PARAMETER :: EddVisT8N09D7 = 5911 + INTEGER(IntKi), PARAMETER :: EddVisT8N09D8 = 5912 + INTEGER(IntKi), PARAMETER :: EddVisT8N09D9 = 5913 + INTEGER(IntKi), PARAMETER :: EddVisT8N10D1 = 5914 + INTEGER(IntKi), PARAMETER :: EddVisT8N10D2 = 5915 + INTEGER(IntKi), PARAMETER :: EddVisT8N10D3 = 5916 + INTEGER(IntKi), PARAMETER :: EddVisT8N10D4 = 5917 + INTEGER(IntKi), PARAMETER :: EddVisT8N10D5 = 5918 + INTEGER(IntKi), PARAMETER :: EddVisT8N10D6 = 5919 + INTEGER(IntKi), PARAMETER :: EddVisT8N10D7 = 5920 + INTEGER(IntKi), PARAMETER :: EddVisT8N10D8 = 5921 + INTEGER(IntKi), PARAMETER :: EddVisT8N10D9 = 5922 + INTEGER(IntKi), PARAMETER :: EddVisT8N11D1 = 5923 + INTEGER(IntKi), PARAMETER :: EddVisT8N11D2 = 5924 + INTEGER(IntKi), PARAMETER :: EddVisT8N11D3 = 5925 + INTEGER(IntKi), PARAMETER :: EddVisT8N11D4 = 5926 + INTEGER(IntKi), PARAMETER :: EddVisT8N11D5 = 5927 + INTEGER(IntKi), PARAMETER :: EddVisT8N11D6 = 5928 + INTEGER(IntKi), PARAMETER :: EddVisT8N11D7 = 5929 + INTEGER(IntKi), PARAMETER :: EddVisT8N11D8 = 5930 + INTEGER(IntKi), PARAMETER :: EddVisT8N11D9 = 5931 + INTEGER(IntKi), PARAMETER :: EddVisT8N12D1 = 5932 + INTEGER(IntKi), PARAMETER :: EddVisT8N12D2 = 5933 + INTEGER(IntKi), PARAMETER :: EddVisT8N12D3 = 5934 + INTEGER(IntKi), PARAMETER :: EddVisT8N12D4 = 5935 + INTEGER(IntKi), PARAMETER :: EddVisT8N12D5 = 5936 + INTEGER(IntKi), PARAMETER :: EddVisT8N12D6 = 5937 + INTEGER(IntKi), PARAMETER :: EddVisT8N12D7 = 5938 + INTEGER(IntKi), PARAMETER :: EddVisT8N12D8 = 5939 + INTEGER(IntKi), PARAMETER :: EddVisT8N12D9 = 5940 + INTEGER(IntKi), PARAMETER :: EddVisT8N13D1 = 5941 + INTEGER(IntKi), PARAMETER :: EddVisT8N13D2 = 5942 + INTEGER(IntKi), PARAMETER :: EddVisT8N13D3 = 5943 + INTEGER(IntKi), PARAMETER :: EddVisT8N13D4 = 5944 + INTEGER(IntKi), PARAMETER :: EddVisT8N13D5 = 5945 + INTEGER(IntKi), PARAMETER :: EddVisT8N13D6 = 5946 + INTEGER(IntKi), PARAMETER :: EddVisT8N13D7 = 5947 + INTEGER(IntKi), PARAMETER :: EddVisT8N13D8 = 5948 + INTEGER(IntKi), PARAMETER :: EddVisT8N13D9 = 5949 + INTEGER(IntKi), PARAMETER :: EddVisT8N14D1 = 5950 + INTEGER(IntKi), PARAMETER :: EddVisT8N14D2 = 5951 + INTEGER(IntKi), PARAMETER :: EddVisT8N14D3 = 5952 + INTEGER(IntKi), PARAMETER :: EddVisT8N14D4 = 5953 + INTEGER(IntKi), PARAMETER :: EddVisT8N14D5 = 5954 + INTEGER(IntKi), PARAMETER :: EddVisT8N14D6 = 5955 + INTEGER(IntKi), PARAMETER :: EddVisT8N14D7 = 5956 + INTEGER(IntKi), PARAMETER :: EddVisT8N14D8 = 5957 + INTEGER(IntKi), PARAMETER :: EddVisT8N14D9 = 5958 + INTEGER(IntKi), PARAMETER :: EddVisT8N15D1 = 5959 + INTEGER(IntKi), PARAMETER :: EddVisT8N15D2 = 5960 + INTEGER(IntKi), PARAMETER :: EddVisT8N15D3 = 5961 + INTEGER(IntKi), PARAMETER :: EddVisT8N15D4 = 5962 + INTEGER(IntKi), PARAMETER :: EddVisT8N15D5 = 5963 + INTEGER(IntKi), PARAMETER :: EddVisT8N15D6 = 5964 + INTEGER(IntKi), PARAMETER :: EddVisT8N15D7 = 5965 + INTEGER(IntKi), PARAMETER :: EddVisT8N15D8 = 5966 + INTEGER(IntKi), PARAMETER :: EddVisT8N15D9 = 5967 + INTEGER(IntKi), PARAMETER :: EddVisT8N16D1 = 5968 + INTEGER(IntKi), PARAMETER :: EddVisT8N16D2 = 5969 + INTEGER(IntKi), PARAMETER :: EddVisT8N16D3 = 5970 + INTEGER(IntKi), PARAMETER :: EddVisT8N16D4 = 5971 + INTEGER(IntKi), PARAMETER :: EddVisT8N16D5 = 5972 + INTEGER(IntKi), PARAMETER :: EddVisT8N16D6 = 5973 + INTEGER(IntKi), PARAMETER :: EddVisT8N16D7 = 5974 + INTEGER(IntKi), PARAMETER :: EddVisT8N16D8 = 5975 + INTEGER(IntKi), PARAMETER :: EddVisT8N16D9 = 5976 + INTEGER(IntKi), PARAMETER :: EddVisT8N17D1 = 5977 + INTEGER(IntKi), PARAMETER :: EddVisT8N17D2 = 5978 + INTEGER(IntKi), PARAMETER :: EddVisT8N17D3 = 5979 + INTEGER(IntKi), PARAMETER :: EddVisT8N17D4 = 5980 + INTEGER(IntKi), PARAMETER :: EddVisT8N17D5 = 5981 + INTEGER(IntKi), PARAMETER :: EddVisT8N17D6 = 5982 + INTEGER(IntKi), PARAMETER :: EddVisT8N17D7 = 5983 + INTEGER(IntKi), PARAMETER :: EddVisT8N17D8 = 5984 + INTEGER(IntKi), PARAMETER :: EddVisT8N17D9 = 5985 + INTEGER(IntKi), PARAMETER :: EddVisT8N18D1 = 5986 + INTEGER(IntKi), PARAMETER :: EddVisT8N18D2 = 5987 + INTEGER(IntKi), PARAMETER :: EddVisT8N18D3 = 5988 + INTEGER(IntKi), PARAMETER :: EddVisT8N18D4 = 5989 + INTEGER(IntKi), PARAMETER :: EddVisT8N18D5 = 5990 + INTEGER(IntKi), PARAMETER :: EddVisT8N18D6 = 5991 + INTEGER(IntKi), PARAMETER :: EddVisT8N18D7 = 5992 + INTEGER(IntKi), PARAMETER :: EddVisT8N18D8 = 5993 + INTEGER(IntKi), PARAMETER :: EddVisT8N18D9 = 5994 + INTEGER(IntKi), PARAMETER :: EddVisT8N19D1 = 5995 + INTEGER(IntKi), PARAMETER :: EddVisT8N19D2 = 5996 + INTEGER(IntKi), PARAMETER :: EddVisT8N19D3 = 5997 + INTEGER(IntKi), PARAMETER :: EddVisT8N19D4 = 5998 + INTEGER(IntKi), PARAMETER :: EddVisT8N19D5 = 5999 + INTEGER(IntKi), PARAMETER :: EddVisT8N19D6 = 6000 + INTEGER(IntKi), PARAMETER :: EddVisT8N19D7 = 6001 + INTEGER(IntKi), PARAMETER :: EddVisT8N19D8 = 6002 + INTEGER(IntKi), PARAMETER :: EddVisT8N19D9 = 6003 + INTEGER(IntKi), PARAMETER :: EddVisT8N20D1 = 6004 + INTEGER(IntKi), PARAMETER :: EddVisT8N20D2 = 6005 + INTEGER(IntKi), PARAMETER :: EddVisT8N20D3 = 6006 + INTEGER(IntKi), PARAMETER :: EddVisT8N20D4 = 6007 + INTEGER(IntKi), PARAMETER :: EddVisT8N20D5 = 6008 + INTEGER(IntKi), PARAMETER :: EddVisT8N20D6 = 6009 + INTEGER(IntKi), PARAMETER :: EddVisT8N20D7 = 6010 + INTEGER(IntKi), PARAMETER :: EddVisT8N20D8 = 6011 + INTEGER(IntKi), PARAMETER :: EddVisT8N20D9 = 6012 + INTEGER(IntKi), PARAMETER :: EddVisT9N01D1 = 6013 + INTEGER(IntKi), PARAMETER :: EddVisT9N01D2 = 6014 + INTEGER(IntKi), PARAMETER :: EddVisT9N01D3 = 6015 + INTEGER(IntKi), PARAMETER :: EddVisT9N01D4 = 6016 + INTEGER(IntKi), PARAMETER :: EddVisT9N01D5 = 6017 + INTEGER(IntKi), PARAMETER :: EddVisT9N01D6 = 6018 + INTEGER(IntKi), PARAMETER :: EddVisT9N01D7 = 6019 + INTEGER(IntKi), PARAMETER :: EddVisT9N01D8 = 6020 + INTEGER(IntKi), PARAMETER :: EddVisT9N01D9 = 6021 + INTEGER(IntKi), PARAMETER :: EddVisT9N02D1 = 6022 + INTEGER(IntKi), PARAMETER :: EddVisT9N02D2 = 6023 + INTEGER(IntKi), PARAMETER :: EddVisT9N02D3 = 6024 + INTEGER(IntKi), PARAMETER :: EddVisT9N02D4 = 6025 + INTEGER(IntKi), PARAMETER :: EddVisT9N02D5 = 6026 + INTEGER(IntKi), PARAMETER :: EddVisT9N02D6 = 6027 + INTEGER(IntKi), PARAMETER :: EddVisT9N02D7 = 6028 + INTEGER(IntKi), PARAMETER :: EddVisT9N02D8 = 6029 + INTEGER(IntKi), PARAMETER :: EddVisT9N02D9 = 6030 + INTEGER(IntKi), PARAMETER :: EddVisT9N03D1 = 6031 + INTEGER(IntKi), PARAMETER :: EddVisT9N03D2 = 6032 + INTEGER(IntKi), PARAMETER :: EddVisT9N03D3 = 6033 + INTEGER(IntKi), PARAMETER :: EddVisT9N03D4 = 6034 + INTEGER(IntKi), PARAMETER :: EddVisT9N03D5 = 6035 + INTEGER(IntKi), PARAMETER :: EddVisT9N03D6 = 6036 + INTEGER(IntKi), PARAMETER :: EddVisT9N03D7 = 6037 + INTEGER(IntKi), PARAMETER :: EddVisT9N03D8 = 6038 + INTEGER(IntKi), PARAMETER :: EddVisT9N03D9 = 6039 + INTEGER(IntKi), PARAMETER :: EddVisT9N04D1 = 6040 + INTEGER(IntKi), PARAMETER :: EddVisT9N04D2 = 6041 + INTEGER(IntKi), PARAMETER :: EddVisT9N04D3 = 6042 + INTEGER(IntKi), PARAMETER :: EddVisT9N04D4 = 6043 + INTEGER(IntKi), PARAMETER :: EddVisT9N04D5 = 6044 + INTEGER(IntKi), PARAMETER :: EddVisT9N04D6 = 6045 + INTEGER(IntKi), PARAMETER :: EddVisT9N04D7 = 6046 + INTEGER(IntKi), PARAMETER :: EddVisT9N04D8 = 6047 + INTEGER(IntKi), PARAMETER :: EddVisT9N04D9 = 6048 + INTEGER(IntKi), PARAMETER :: EddVisT9N05D1 = 6049 + INTEGER(IntKi), PARAMETER :: EddVisT9N05D2 = 6050 + INTEGER(IntKi), PARAMETER :: EddVisT9N05D3 = 6051 + INTEGER(IntKi), PARAMETER :: EddVisT9N05D4 = 6052 + INTEGER(IntKi), PARAMETER :: EddVisT9N05D5 = 6053 + INTEGER(IntKi), PARAMETER :: EddVisT9N05D6 = 6054 + INTEGER(IntKi), PARAMETER :: EddVisT9N05D7 = 6055 + INTEGER(IntKi), PARAMETER :: EddVisT9N05D8 = 6056 + INTEGER(IntKi), PARAMETER :: EddVisT9N05D9 = 6057 + INTEGER(IntKi), PARAMETER :: EddVisT9N06D1 = 6058 + INTEGER(IntKi), PARAMETER :: EddVisT9N06D2 = 6059 + INTEGER(IntKi), PARAMETER :: EddVisT9N06D3 = 6060 + INTEGER(IntKi), PARAMETER :: EddVisT9N06D4 = 6061 + INTEGER(IntKi), PARAMETER :: EddVisT9N06D5 = 6062 + INTEGER(IntKi), PARAMETER :: EddVisT9N06D6 = 6063 + INTEGER(IntKi), PARAMETER :: EddVisT9N06D7 = 6064 + INTEGER(IntKi), PARAMETER :: EddVisT9N06D8 = 6065 + INTEGER(IntKi), PARAMETER :: EddVisT9N06D9 = 6066 + INTEGER(IntKi), PARAMETER :: EddVisT9N07D1 = 6067 + INTEGER(IntKi), PARAMETER :: EddVisT9N07D2 = 6068 + INTEGER(IntKi), PARAMETER :: EddVisT9N07D3 = 6069 + INTEGER(IntKi), PARAMETER :: EddVisT9N07D4 = 6070 + INTEGER(IntKi), PARAMETER :: EddVisT9N07D5 = 6071 + INTEGER(IntKi), PARAMETER :: EddVisT9N07D6 = 6072 + INTEGER(IntKi), PARAMETER :: EddVisT9N07D7 = 6073 + INTEGER(IntKi), PARAMETER :: EddVisT9N07D8 = 6074 + INTEGER(IntKi), PARAMETER :: EddVisT9N07D9 = 6075 + INTEGER(IntKi), PARAMETER :: EddVisT9N08D1 = 6076 + INTEGER(IntKi), PARAMETER :: EddVisT9N08D2 = 6077 + INTEGER(IntKi), PARAMETER :: EddVisT9N08D3 = 6078 + INTEGER(IntKi), PARAMETER :: EddVisT9N08D4 = 6079 + INTEGER(IntKi), PARAMETER :: EddVisT9N08D5 = 6080 + INTEGER(IntKi), PARAMETER :: EddVisT9N08D6 = 6081 + INTEGER(IntKi), PARAMETER :: EddVisT9N08D7 = 6082 + INTEGER(IntKi), PARAMETER :: EddVisT9N08D8 = 6083 + INTEGER(IntKi), PARAMETER :: EddVisT9N08D9 = 6084 + INTEGER(IntKi), PARAMETER :: EddVisT9N09D1 = 6085 + INTEGER(IntKi), PARAMETER :: EddVisT9N09D2 = 6086 + INTEGER(IntKi), PARAMETER :: EddVisT9N09D3 = 6087 + INTEGER(IntKi), PARAMETER :: EddVisT9N09D4 = 6088 + INTEGER(IntKi), PARAMETER :: EddVisT9N09D5 = 6089 + INTEGER(IntKi), PARAMETER :: EddVisT9N09D6 = 6090 + INTEGER(IntKi), PARAMETER :: EddVisT9N09D7 = 6091 + INTEGER(IntKi), PARAMETER :: EddVisT9N09D8 = 6092 + INTEGER(IntKi), PARAMETER :: EddVisT9N09D9 = 6093 + INTEGER(IntKi), PARAMETER :: EddVisT9N10D1 = 6094 + INTEGER(IntKi), PARAMETER :: EddVisT9N10D2 = 6095 + INTEGER(IntKi), PARAMETER :: EddVisT9N10D3 = 6096 + INTEGER(IntKi), PARAMETER :: EddVisT9N10D4 = 6097 + INTEGER(IntKi), PARAMETER :: EddVisT9N10D5 = 6098 + INTEGER(IntKi), PARAMETER :: EddVisT9N10D6 = 6099 + INTEGER(IntKi), PARAMETER :: EddVisT9N10D7 = 6100 + INTEGER(IntKi), PARAMETER :: EddVisT9N10D8 = 6101 + INTEGER(IntKi), PARAMETER :: EddVisT9N10D9 = 6102 + INTEGER(IntKi), PARAMETER :: EddVisT9N11D1 = 6103 + INTEGER(IntKi), PARAMETER :: EddVisT9N11D2 = 6104 + INTEGER(IntKi), PARAMETER :: EddVisT9N11D3 = 6105 + INTEGER(IntKi), PARAMETER :: EddVisT9N11D4 = 6106 + INTEGER(IntKi), PARAMETER :: EddVisT9N11D5 = 6107 + INTEGER(IntKi), PARAMETER :: EddVisT9N11D6 = 6108 + INTEGER(IntKi), PARAMETER :: EddVisT9N11D7 = 6109 + INTEGER(IntKi), PARAMETER :: EddVisT9N11D8 = 6110 + INTEGER(IntKi), PARAMETER :: EddVisT9N11D9 = 6111 + INTEGER(IntKi), PARAMETER :: EddVisT9N12D1 = 6112 + INTEGER(IntKi), PARAMETER :: EddVisT9N12D2 = 6113 + INTEGER(IntKi), PARAMETER :: EddVisT9N12D3 = 6114 + INTEGER(IntKi), PARAMETER :: EddVisT9N12D4 = 6115 + INTEGER(IntKi), PARAMETER :: EddVisT9N12D5 = 6116 + INTEGER(IntKi), PARAMETER :: EddVisT9N12D6 = 6117 + INTEGER(IntKi), PARAMETER :: EddVisT9N12D7 = 6118 + INTEGER(IntKi), PARAMETER :: EddVisT9N12D8 = 6119 + INTEGER(IntKi), PARAMETER :: EddVisT9N12D9 = 6120 + INTEGER(IntKi), PARAMETER :: EddVisT9N13D1 = 6121 + INTEGER(IntKi), PARAMETER :: EddVisT9N13D2 = 6122 + INTEGER(IntKi), PARAMETER :: EddVisT9N13D3 = 6123 + INTEGER(IntKi), PARAMETER :: EddVisT9N13D4 = 6124 + INTEGER(IntKi), PARAMETER :: EddVisT9N13D5 = 6125 + INTEGER(IntKi), PARAMETER :: EddVisT9N13D6 = 6126 + INTEGER(IntKi), PARAMETER :: EddVisT9N13D7 = 6127 + INTEGER(IntKi), PARAMETER :: EddVisT9N13D8 = 6128 + INTEGER(IntKi), PARAMETER :: EddVisT9N13D9 = 6129 + INTEGER(IntKi), PARAMETER :: EddVisT9N14D1 = 6130 + INTEGER(IntKi), PARAMETER :: EddVisT9N14D2 = 6131 + INTEGER(IntKi), PARAMETER :: EddVisT9N14D3 = 6132 + INTEGER(IntKi), PARAMETER :: EddVisT9N14D4 = 6133 + INTEGER(IntKi), PARAMETER :: EddVisT9N14D5 = 6134 + INTEGER(IntKi), PARAMETER :: EddVisT9N14D6 = 6135 + INTEGER(IntKi), PARAMETER :: EddVisT9N14D7 = 6136 + INTEGER(IntKi), PARAMETER :: EddVisT9N14D8 = 6137 + INTEGER(IntKi), PARAMETER :: EddVisT9N14D9 = 6138 + INTEGER(IntKi), PARAMETER :: EddVisT9N15D1 = 6139 + INTEGER(IntKi), PARAMETER :: EddVisT9N15D2 = 6140 + INTEGER(IntKi), PARAMETER :: EddVisT9N15D3 = 6141 + INTEGER(IntKi), PARAMETER :: EddVisT9N15D4 = 6142 + INTEGER(IntKi), PARAMETER :: EddVisT9N15D5 = 6143 + INTEGER(IntKi), PARAMETER :: EddVisT9N15D6 = 6144 + INTEGER(IntKi), PARAMETER :: EddVisT9N15D7 = 6145 + INTEGER(IntKi), PARAMETER :: EddVisT9N15D8 = 6146 + INTEGER(IntKi), PARAMETER :: EddVisT9N15D9 = 6147 + INTEGER(IntKi), PARAMETER :: EddVisT9N16D1 = 6148 + INTEGER(IntKi), PARAMETER :: EddVisT9N16D2 = 6149 + INTEGER(IntKi), PARAMETER :: EddVisT9N16D3 = 6150 + INTEGER(IntKi), PARAMETER :: EddVisT9N16D4 = 6151 + INTEGER(IntKi), PARAMETER :: EddVisT9N16D5 = 6152 + INTEGER(IntKi), PARAMETER :: EddVisT9N16D6 = 6153 + INTEGER(IntKi), PARAMETER :: EddVisT9N16D7 = 6154 + INTEGER(IntKi), PARAMETER :: EddVisT9N16D8 = 6155 + INTEGER(IntKi), PARAMETER :: EddVisT9N16D9 = 6156 + INTEGER(IntKi), PARAMETER :: EddVisT9N17D1 = 6157 + INTEGER(IntKi), PARAMETER :: EddVisT9N17D2 = 6158 + INTEGER(IntKi), PARAMETER :: EddVisT9N17D3 = 6159 + INTEGER(IntKi), PARAMETER :: EddVisT9N17D4 = 6160 + INTEGER(IntKi), PARAMETER :: EddVisT9N17D5 = 6161 + INTEGER(IntKi), PARAMETER :: EddVisT9N17D6 = 6162 + INTEGER(IntKi), PARAMETER :: EddVisT9N17D7 = 6163 + INTEGER(IntKi), PARAMETER :: EddVisT9N17D8 = 6164 + INTEGER(IntKi), PARAMETER :: EddVisT9N17D9 = 6165 + INTEGER(IntKi), PARAMETER :: EddVisT9N18D1 = 6166 + INTEGER(IntKi), PARAMETER :: EddVisT9N18D2 = 6167 + INTEGER(IntKi), PARAMETER :: EddVisT9N18D3 = 6168 + INTEGER(IntKi), PARAMETER :: EddVisT9N18D4 = 6169 + INTEGER(IntKi), PARAMETER :: EddVisT9N18D5 = 6170 + INTEGER(IntKi), PARAMETER :: EddVisT9N18D6 = 6171 + INTEGER(IntKi), PARAMETER :: EddVisT9N18D7 = 6172 + INTEGER(IntKi), PARAMETER :: EddVisT9N18D8 = 6173 + INTEGER(IntKi), PARAMETER :: EddVisT9N18D9 = 6174 + INTEGER(IntKi), PARAMETER :: EddVisT9N19D1 = 6175 + INTEGER(IntKi), PARAMETER :: EddVisT9N19D2 = 6176 + INTEGER(IntKi), PARAMETER :: EddVisT9N19D3 = 6177 + INTEGER(IntKi), PARAMETER :: EddVisT9N19D4 = 6178 + INTEGER(IntKi), PARAMETER :: EddVisT9N19D5 = 6179 + INTEGER(IntKi), PARAMETER :: EddVisT9N19D6 = 6180 + INTEGER(IntKi), PARAMETER :: EddVisT9N19D7 = 6181 + INTEGER(IntKi), PARAMETER :: EddVisT9N19D8 = 6182 + INTEGER(IntKi), PARAMETER :: EddVisT9N19D9 = 6183 + INTEGER(IntKi), PARAMETER :: EddVisT9N20D1 = 6184 + INTEGER(IntKi), PARAMETER :: EddVisT9N20D2 = 6185 + INTEGER(IntKi), PARAMETER :: EddVisT9N20D3 = 6186 + INTEGER(IntKi), PARAMETER :: EddVisT9N20D4 = 6187 + INTEGER(IntKi), PARAMETER :: EddVisT9N20D5 = 6188 + INTEGER(IntKi), PARAMETER :: EddVisT9N20D6 = 6189 + INTEGER(IntKi), PARAMETER :: EddVisT9N20D7 = 6190 + INTEGER(IntKi), PARAMETER :: EddVisT9N20D8 = 6191 + INTEGER(IntKi), PARAMETER :: EddVisT9N20D9 = 6192 + + + ! Contribution to eddy viscosity from ambient turbulence: + + INTEGER(IntKi), PARAMETER :: EddAmbT1N01D1 = 6193 + INTEGER(IntKi), PARAMETER :: EddAmbT1N01D2 = 6194 + INTEGER(IntKi), PARAMETER :: EddAmbT1N01D3 = 6195 + INTEGER(IntKi), PARAMETER :: EddAmbT1N01D4 = 6196 + INTEGER(IntKi), PARAMETER :: EddAmbT1N01D5 = 6197 + INTEGER(IntKi), PARAMETER :: EddAmbT1N01D6 = 6198 + INTEGER(IntKi), PARAMETER :: EddAmbT1N01D7 = 6199 + INTEGER(IntKi), PARAMETER :: EddAmbT1N01D8 = 6200 + INTEGER(IntKi), PARAMETER :: EddAmbT1N01D9 = 6201 + INTEGER(IntKi), PARAMETER :: EddAmbT1N02D1 = 6202 + INTEGER(IntKi), PARAMETER :: EddAmbT1N02D2 = 6203 + INTEGER(IntKi), PARAMETER :: EddAmbT1N02D3 = 6204 + INTEGER(IntKi), PARAMETER :: EddAmbT1N02D4 = 6205 + INTEGER(IntKi), PARAMETER :: EddAmbT1N02D5 = 6206 + INTEGER(IntKi), PARAMETER :: EddAmbT1N02D6 = 6207 + INTEGER(IntKi), PARAMETER :: EddAmbT1N02D7 = 6208 + INTEGER(IntKi), PARAMETER :: EddAmbT1N02D8 = 6209 + INTEGER(IntKi), PARAMETER :: EddAmbT1N02D9 = 6210 + INTEGER(IntKi), PARAMETER :: EddAmbT1N03D1 = 6211 + INTEGER(IntKi), PARAMETER :: EddAmbT1N03D2 = 6212 + INTEGER(IntKi), PARAMETER :: EddAmbT1N03D3 = 6213 + INTEGER(IntKi), PARAMETER :: EddAmbT1N03D4 = 6214 + INTEGER(IntKi), PARAMETER :: EddAmbT1N03D5 = 6215 + INTEGER(IntKi), PARAMETER :: EddAmbT1N03D6 = 6216 + INTEGER(IntKi), PARAMETER :: EddAmbT1N03D7 = 6217 + INTEGER(IntKi), PARAMETER :: EddAmbT1N03D8 = 6218 + INTEGER(IntKi), PARAMETER :: EddAmbT1N03D9 = 6219 + INTEGER(IntKi), PARAMETER :: EddAmbT1N04D1 = 6220 + INTEGER(IntKi), PARAMETER :: EddAmbT1N04D2 = 6221 + INTEGER(IntKi), PARAMETER :: EddAmbT1N04D3 = 6222 + INTEGER(IntKi), PARAMETER :: EddAmbT1N04D4 = 6223 + INTEGER(IntKi), PARAMETER :: EddAmbT1N04D5 = 6224 + INTEGER(IntKi), PARAMETER :: EddAmbT1N04D6 = 6225 + INTEGER(IntKi), PARAMETER :: EddAmbT1N04D7 = 6226 + INTEGER(IntKi), PARAMETER :: EddAmbT1N04D8 = 6227 + INTEGER(IntKi), PARAMETER :: EddAmbT1N04D9 = 6228 + INTEGER(IntKi), PARAMETER :: EddAmbT1N05D1 = 6229 + INTEGER(IntKi), PARAMETER :: EddAmbT1N05D2 = 6230 + INTEGER(IntKi), PARAMETER :: EddAmbT1N05D3 = 6231 + INTEGER(IntKi), PARAMETER :: EddAmbT1N05D4 = 6232 + INTEGER(IntKi), PARAMETER :: EddAmbT1N05D5 = 6233 + INTEGER(IntKi), PARAMETER :: EddAmbT1N05D6 = 6234 + INTEGER(IntKi), PARAMETER :: EddAmbT1N05D7 = 6235 + INTEGER(IntKi), PARAMETER :: EddAmbT1N05D8 = 6236 + INTEGER(IntKi), PARAMETER :: EddAmbT1N05D9 = 6237 + INTEGER(IntKi), PARAMETER :: EddAmbT1N06D1 = 6238 + INTEGER(IntKi), PARAMETER :: EddAmbT1N06D2 = 6239 + INTEGER(IntKi), PARAMETER :: EddAmbT1N06D3 = 6240 + INTEGER(IntKi), PARAMETER :: EddAmbT1N06D4 = 6241 + INTEGER(IntKi), PARAMETER :: EddAmbT1N06D5 = 6242 + INTEGER(IntKi), PARAMETER :: EddAmbT1N06D6 = 6243 + INTEGER(IntKi), PARAMETER :: EddAmbT1N06D7 = 6244 + INTEGER(IntKi), PARAMETER :: EddAmbT1N06D8 = 6245 + INTEGER(IntKi), PARAMETER :: EddAmbT1N06D9 = 6246 + INTEGER(IntKi), PARAMETER :: EddAmbT1N07D1 = 6247 + INTEGER(IntKi), PARAMETER :: EddAmbT1N07D2 = 6248 + INTEGER(IntKi), PARAMETER :: EddAmbT1N07D3 = 6249 + INTEGER(IntKi), PARAMETER :: EddAmbT1N07D4 = 6250 + INTEGER(IntKi), PARAMETER :: EddAmbT1N07D5 = 6251 + INTEGER(IntKi), PARAMETER :: EddAmbT1N07D6 = 6252 + INTEGER(IntKi), PARAMETER :: EddAmbT1N07D7 = 6253 + INTEGER(IntKi), PARAMETER :: EddAmbT1N07D8 = 6254 + INTEGER(IntKi), PARAMETER :: EddAmbT1N07D9 = 6255 + INTEGER(IntKi), PARAMETER :: EddAmbT1N08D1 = 6256 + INTEGER(IntKi), PARAMETER :: EddAmbT1N08D2 = 6257 + INTEGER(IntKi), PARAMETER :: EddAmbT1N08D3 = 6258 + INTEGER(IntKi), PARAMETER :: EddAmbT1N08D4 = 6259 + INTEGER(IntKi), PARAMETER :: EddAmbT1N08D5 = 6260 + INTEGER(IntKi), PARAMETER :: EddAmbT1N08D6 = 6261 + INTEGER(IntKi), PARAMETER :: EddAmbT1N08D7 = 6262 + INTEGER(IntKi), PARAMETER :: EddAmbT1N08D8 = 6263 + INTEGER(IntKi), PARAMETER :: EddAmbT1N08D9 = 6264 + INTEGER(IntKi), PARAMETER :: EddAmbT1N09D1 = 6265 + INTEGER(IntKi), PARAMETER :: EddAmbT1N09D2 = 6266 + INTEGER(IntKi), PARAMETER :: EddAmbT1N09D3 = 6267 + INTEGER(IntKi), PARAMETER :: EddAmbT1N09D4 = 6268 + INTEGER(IntKi), PARAMETER :: EddAmbT1N09D5 = 6269 + INTEGER(IntKi), PARAMETER :: EddAmbT1N09D6 = 6270 + INTEGER(IntKi), PARAMETER :: EddAmbT1N09D7 = 6271 + INTEGER(IntKi), PARAMETER :: EddAmbT1N09D8 = 6272 + INTEGER(IntKi), PARAMETER :: EddAmbT1N09D9 = 6273 + INTEGER(IntKi), PARAMETER :: EddAmbT1N10D1 = 6274 + INTEGER(IntKi), PARAMETER :: EddAmbT1N10D2 = 6275 + INTEGER(IntKi), PARAMETER :: EddAmbT1N10D3 = 6276 + INTEGER(IntKi), PARAMETER :: EddAmbT1N10D4 = 6277 + INTEGER(IntKi), PARAMETER :: EddAmbT1N10D5 = 6278 + INTEGER(IntKi), PARAMETER :: EddAmbT1N10D6 = 6279 + INTEGER(IntKi), PARAMETER :: EddAmbT1N10D7 = 6280 + INTEGER(IntKi), PARAMETER :: EddAmbT1N10D8 = 6281 + INTEGER(IntKi), PARAMETER :: EddAmbT1N10D9 = 6282 + INTEGER(IntKi), PARAMETER :: EddAmbT1N11D1 = 6283 + INTEGER(IntKi), PARAMETER :: EddAmbT1N11D2 = 6284 + INTEGER(IntKi), PARAMETER :: EddAmbT1N11D3 = 6285 + INTEGER(IntKi), PARAMETER :: EddAmbT1N11D4 = 6286 + INTEGER(IntKi), PARAMETER :: EddAmbT1N11D5 = 6287 + INTEGER(IntKi), PARAMETER :: EddAmbT1N11D6 = 6288 + INTEGER(IntKi), PARAMETER :: EddAmbT1N11D7 = 6289 + INTEGER(IntKi), PARAMETER :: EddAmbT1N11D8 = 6290 + INTEGER(IntKi), PARAMETER :: EddAmbT1N11D9 = 6291 + INTEGER(IntKi), PARAMETER :: EddAmbT1N12D1 = 6292 + INTEGER(IntKi), PARAMETER :: EddAmbT1N12D2 = 6293 + INTEGER(IntKi), PARAMETER :: EddAmbT1N12D3 = 6294 + INTEGER(IntKi), PARAMETER :: EddAmbT1N12D4 = 6295 + INTEGER(IntKi), PARAMETER :: EddAmbT1N12D5 = 6296 + INTEGER(IntKi), PARAMETER :: EddAmbT1N12D6 = 6297 + INTEGER(IntKi), PARAMETER :: EddAmbT1N12D7 = 6298 + INTEGER(IntKi), PARAMETER :: EddAmbT1N12D8 = 6299 + INTEGER(IntKi), PARAMETER :: EddAmbT1N12D9 = 6300 + INTEGER(IntKi), PARAMETER :: EddAmbT1N13D1 = 6301 + INTEGER(IntKi), PARAMETER :: EddAmbT1N13D2 = 6302 + INTEGER(IntKi), PARAMETER :: EddAmbT1N13D3 = 6303 + INTEGER(IntKi), PARAMETER :: EddAmbT1N13D4 = 6304 + INTEGER(IntKi), PARAMETER :: EddAmbT1N13D5 = 6305 + INTEGER(IntKi), PARAMETER :: EddAmbT1N13D6 = 6306 + INTEGER(IntKi), PARAMETER :: EddAmbT1N13D7 = 6307 + INTEGER(IntKi), PARAMETER :: EddAmbT1N13D8 = 6308 + INTEGER(IntKi), PARAMETER :: EddAmbT1N13D9 = 6309 + INTEGER(IntKi), PARAMETER :: EddAmbT1N14D1 = 6310 + INTEGER(IntKi), PARAMETER :: EddAmbT1N14D2 = 6311 + INTEGER(IntKi), PARAMETER :: EddAmbT1N14D3 = 6312 + INTEGER(IntKi), PARAMETER :: EddAmbT1N14D4 = 6313 + INTEGER(IntKi), PARAMETER :: EddAmbT1N14D5 = 6314 + INTEGER(IntKi), PARAMETER :: EddAmbT1N14D6 = 6315 + INTEGER(IntKi), PARAMETER :: EddAmbT1N14D7 = 6316 + INTEGER(IntKi), PARAMETER :: EddAmbT1N14D8 = 6317 + INTEGER(IntKi), PARAMETER :: EddAmbT1N14D9 = 6318 + INTEGER(IntKi), PARAMETER :: EddAmbT1N15D1 = 6319 + INTEGER(IntKi), PARAMETER :: EddAmbT1N15D2 = 6320 + INTEGER(IntKi), PARAMETER :: EddAmbT1N15D3 = 6321 + INTEGER(IntKi), PARAMETER :: EddAmbT1N15D4 = 6322 + INTEGER(IntKi), PARAMETER :: EddAmbT1N15D5 = 6323 + INTEGER(IntKi), PARAMETER :: EddAmbT1N15D6 = 6324 + INTEGER(IntKi), PARAMETER :: EddAmbT1N15D7 = 6325 + INTEGER(IntKi), PARAMETER :: EddAmbT1N15D8 = 6326 + INTEGER(IntKi), PARAMETER :: EddAmbT1N15D9 = 6327 + INTEGER(IntKi), PARAMETER :: EddAmbT1N16D1 = 6328 + INTEGER(IntKi), PARAMETER :: EddAmbT1N16D2 = 6329 + INTEGER(IntKi), PARAMETER :: EddAmbT1N16D3 = 6330 + INTEGER(IntKi), PARAMETER :: EddAmbT1N16D4 = 6331 + INTEGER(IntKi), PARAMETER :: EddAmbT1N16D5 = 6332 + INTEGER(IntKi), PARAMETER :: EddAmbT1N16D6 = 6333 + INTEGER(IntKi), PARAMETER :: EddAmbT1N16D7 = 6334 + INTEGER(IntKi), PARAMETER :: EddAmbT1N16D8 = 6335 + INTEGER(IntKi), PARAMETER :: EddAmbT1N16D9 = 6336 + INTEGER(IntKi), PARAMETER :: EddAmbT1N17D1 = 6337 + INTEGER(IntKi), PARAMETER :: EddAmbT1N17D2 = 6338 + INTEGER(IntKi), PARAMETER :: EddAmbT1N17D3 = 6339 + INTEGER(IntKi), PARAMETER :: EddAmbT1N17D4 = 6340 + INTEGER(IntKi), PARAMETER :: EddAmbT1N17D5 = 6341 + INTEGER(IntKi), PARAMETER :: EddAmbT1N17D6 = 6342 + INTEGER(IntKi), PARAMETER :: EddAmbT1N17D7 = 6343 + INTEGER(IntKi), PARAMETER :: EddAmbT1N17D8 = 6344 + INTEGER(IntKi), PARAMETER :: EddAmbT1N17D9 = 6345 + INTEGER(IntKi), PARAMETER :: EddAmbT1N18D1 = 6346 + INTEGER(IntKi), PARAMETER :: EddAmbT1N18D2 = 6347 + INTEGER(IntKi), PARAMETER :: EddAmbT1N18D3 = 6348 + INTEGER(IntKi), PARAMETER :: EddAmbT1N18D4 = 6349 + INTEGER(IntKi), PARAMETER :: EddAmbT1N18D5 = 6350 + INTEGER(IntKi), PARAMETER :: EddAmbT1N18D6 = 6351 + INTEGER(IntKi), PARAMETER :: EddAmbT1N18D7 = 6352 + INTEGER(IntKi), PARAMETER :: EddAmbT1N18D8 = 6353 + INTEGER(IntKi), PARAMETER :: EddAmbT1N18D9 = 6354 + INTEGER(IntKi), PARAMETER :: EddAmbT1N19D1 = 6355 + INTEGER(IntKi), PARAMETER :: EddAmbT1N19D2 = 6356 + INTEGER(IntKi), PARAMETER :: EddAmbT1N19D3 = 6357 + INTEGER(IntKi), PARAMETER :: EddAmbT1N19D4 = 6358 + INTEGER(IntKi), PARAMETER :: EddAmbT1N19D5 = 6359 + INTEGER(IntKi), PARAMETER :: EddAmbT1N19D6 = 6360 + INTEGER(IntKi), PARAMETER :: EddAmbT1N19D7 = 6361 + INTEGER(IntKi), PARAMETER :: EddAmbT1N19D8 = 6362 + INTEGER(IntKi), PARAMETER :: EddAmbT1N19D9 = 6363 + INTEGER(IntKi), PARAMETER :: EddAmbT1N20D1 = 6364 + INTEGER(IntKi), PARAMETER :: EddAmbT1N20D2 = 6365 + INTEGER(IntKi), PARAMETER :: EddAmbT1N20D3 = 6366 + INTEGER(IntKi), PARAMETER :: EddAmbT1N20D4 = 6367 + INTEGER(IntKi), PARAMETER :: EddAmbT1N20D5 = 6368 + INTEGER(IntKi), PARAMETER :: EddAmbT1N20D6 = 6369 + INTEGER(IntKi), PARAMETER :: EddAmbT1N20D7 = 6370 + INTEGER(IntKi), PARAMETER :: EddAmbT1N20D8 = 6371 + INTEGER(IntKi), PARAMETER :: EddAmbT1N20D9 = 6372 + INTEGER(IntKi), PARAMETER :: EddAmbT2N01D1 = 6373 + INTEGER(IntKi), PARAMETER :: EddAmbT2N01D2 = 6374 + INTEGER(IntKi), PARAMETER :: EddAmbT2N01D3 = 6375 + INTEGER(IntKi), PARAMETER :: EddAmbT2N01D4 = 6376 + INTEGER(IntKi), PARAMETER :: EddAmbT2N01D5 = 6377 + INTEGER(IntKi), PARAMETER :: EddAmbT2N01D6 = 6378 + INTEGER(IntKi), PARAMETER :: EddAmbT2N01D7 = 6379 + INTEGER(IntKi), PARAMETER :: EddAmbT2N01D8 = 6380 + INTEGER(IntKi), PARAMETER :: EddAmbT2N01D9 = 6381 + INTEGER(IntKi), PARAMETER :: EddAmbT2N02D1 = 6382 + INTEGER(IntKi), PARAMETER :: EddAmbT2N02D2 = 6383 + INTEGER(IntKi), PARAMETER :: EddAmbT2N02D3 = 6384 + INTEGER(IntKi), PARAMETER :: EddAmbT2N02D4 = 6385 + INTEGER(IntKi), PARAMETER :: EddAmbT2N02D5 = 6386 + INTEGER(IntKi), PARAMETER :: EddAmbT2N02D6 = 6387 + INTEGER(IntKi), PARAMETER :: EddAmbT2N02D7 = 6388 + INTEGER(IntKi), PARAMETER :: EddAmbT2N02D8 = 6389 + INTEGER(IntKi), PARAMETER :: EddAmbT2N02D9 = 6390 + INTEGER(IntKi), PARAMETER :: EddAmbT2N03D1 = 6391 + INTEGER(IntKi), PARAMETER :: EddAmbT2N03D2 = 6392 + INTEGER(IntKi), PARAMETER :: EddAmbT2N03D3 = 6393 + INTEGER(IntKi), PARAMETER :: EddAmbT2N03D4 = 6394 + INTEGER(IntKi), PARAMETER :: EddAmbT2N03D5 = 6395 + INTEGER(IntKi), PARAMETER :: EddAmbT2N03D6 = 6396 + INTEGER(IntKi), PARAMETER :: EddAmbT2N03D7 = 6397 + INTEGER(IntKi), PARAMETER :: EddAmbT2N03D8 = 6398 + INTEGER(IntKi), PARAMETER :: EddAmbT2N03D9 = 6399 + INTEGER(IntKi), PARAMETER :: EddAmbT2N04D1 = 6400 + INTEGER(IntKi), PARAMETER :: EddAmbT2N04D2 = 6401 + INTEGER(IntKi), PARAMETER :: EddAmbT2N04D3 = 6402 + INTEGER(IntKi), PARAMETER :: EddAmbT2N04D4 = 6403 + INTEGER(IntKi), PARAMETER :: EddAmbT2N04D5 = 6404 + INTEGER(IntKi), PARAMETER :: EddAmbT2N04D6 = 6405 + INTEGER(IntKi), PARAMETER :: EddAmbT2N04D7 = 6406 + INTEGER(IntKi), PARAMETER :: EddAmbT2N04D8 = 6407 + INTEGER(IntKi), PARAMETER :: EddAmbT2N04D9 = 6408 + INTEGER(IntKi), PARAMETER :: EddAmbT2N05D1 = 6409 + INTEGER(IntKi), PARAMETER :: EddAmbT2N05D2 = 6410 + INTEGER(IntKi), PARAMETER :: EddAmbT2N05D3 = 6411 + INTEGER(IntKi), PARAMETER :: EddAmbT2N05D4 = 6412 + INTEGER(IntKi), PARAMETER :: EddAmbT2N05D5 = 6413 + INTEGER(IntKi), PARAMETER :: EddAmbT2N05D6 = 6414 + INTEGER(IntKi), PARAMETER :: EddAmbT2N05D7 = 6415 + INTEGER(IntKi), PARAMETER :: EddAmbT2N05D8 = 6416 + INTEGER(IntKi), PARAMETER :: EddAmbT2N05D9 = 6417 + INTEGER(IntKi), PARAMETER :: EddAmbT2N06D1 = 6418 + INTEGER(IntKi), PARAMETER :: EddAmbT2N06D2 = 6419 + INTEGER(IntKi), PARAMETER :: EddAmbT2N06D3 = 6420 + INTEGER(IntKi), PARAMETER :: EddAmbT2N06D4 = 6421 + INTEGER(IntKi), PARAMETER :: EddAmbT2N06D5 = 6422 + INTEGER(IntKi), PARAMETER :: EddAmbT2N06D6 = 6423 + INTEGER(IntKi), PARAMETER :: EddAmbT2N06D7 = 6424 + INTEGER(IntKi), PARAMETER :: EddAmbT2N06D8 = 6425 + INTEGER(IntKi), PARAMETER :: EddAmbT2N06D9 = 6426 + INTEGER(IntKi), PARAMETER :: EddAmbT2N07D1 = 6427 + INTEGER(IntKi), PARAMETER :: EddAmbT2N07D2 = 6428 + INTEGER(IntKi), PARAMETER :: EddAmbT2N07D3 = 6429 + INTEGER(IntKi), PARAMETER :: EddAmbT2N07D4 = 6430 + INTEGER(IntKi), PARAMETER :: EddAmbT2N07D5 = 6431 + INTEGER(IntKi), PARAMETER :: EddAmbT2N07D6 = 6432 + INTEGER(IntKi), PARAMETER :: EddAmbT2N07D7 = 6433 + INTEGER(IntKi), PARAMETER :: EddAmbT2N07D8 = 6434 + INTEGER(IntKi), PARAMETER :: EddAmbT2N07D9 = 6435 + INTEGER(IntKi), PARAMETER :: EddAmbT2N08D1 = 6436 + INTEGER(IntKi), PARAMETER :: EddAmbT2N08D2 = 6437 + INTEGER(IntKi), PARAMETER :: EddAmbT2N08D3 = 6438 + INTEGER(IntKi), PARAMETER :: EddAmbT2N08D4 = 6439 + INTEGER(IntKi), PARAMETER :: EddAmbT2N08D5 = 6440 + INTEGER(IntKi), PARAMETER :: EddAmbT2N08D6 = 6441 + INTEGER(IntKi), PARAMETER :: EddAmbT2N08D7 = 6442 + INTEGER(IntKi), PARAMETER :: EddAmbT2N08D8 = 6443 + INTEGER(IntKi), PARAMETER :: EddAmbT2N08D9 = 6444 + INTEGER(IntKi), PARAMETER :: EddAmbT2N09D1 = 6445 + INTEGER(IntKi), PARAMETER :: EddAmbT2N09D2 = 6446 + INTEGER(IntKi), PARAMETER :: EddAmbT2N09D3 = 6447 + INTEGER(IntKi), PARAMETER :: EddAmbT2N09D4 = 6448 + INTEGER(IntKi), PARAMETER :: EddAmbT2N09D5 = 6449 + INTEGER(IntKi), PARAMETER :: EddAmbT2N09D6 = 6450 + INTEGER(IntKi), PARAMETER :: EddAmbT2N09D7 = 6451 + INTEGER(IntKi), PARAMETER :: EddAmbT2N09D8 = 6452 + INTEGER(IntKi), PARAMETER :: EddAmbT2N09D9 = 6453 + INTEGER(IntKi), PARAMETER :: EddAmbT2N10D1 = 6454 + INTEGER(IntKi), PARAMETER :: EddAmbT2N10D2 = 6455 + INTEGER(IntKi), PARAMETER :: EddAmbT2N10D3 = 6456 + INTEGER(IntKi), PARAMETER :: EddAmbT2N10D4 = 6457 + INTEGER(IntKi), PARAMETER :: EddAmbT2N10D5 = 6458 + INTEGER(IntKi), PARAMETER :: EddAmbT2N10D6 = 6459 + INTEGER(IntKi), PARAMETER :: EddAmbT2N10D7 = 6460 + INTEGER(IntKi), PARAMETER :: EddAmbT2N10D8 = 6461 + INTEGER(IntKi), PARAMETER :: EddAmbT2N10D9 = 6462 + INTEGER(IntKi), PARAMETER :: EddAmbT2N11D1 = 6463 + INTEGER(IntKi), PARAMETER :: EddAmbT2N11D2 = 6464 + INTEGER(IntKi), PARAMETER :: EddAmbT2N11D3 = 6465 + INTEGER(IntKi), PARAMETER :: EddAmbT2N11D4 = 6466 + INTEGER(IntKi), PARAMETER :: EddAmbT2N11D5 = 6467 + INTEGER(IntKi), PARAMETER :: EddAmbT2N11D6 = 6468 + INTEGER(IntKi), PARAMETER :: EddAmbT2N11D7 = 6469 + INTEGER(IntKi), PARAMETER :: EddAmbT2N11D8 = 6470 + INTEGER(IntKi), PARAMETER :: EddAmbT2N11D9 = 6471 + INTEGER(IntKi), PARAMETER :: EddAmbT2N12D1 = 6472 + INTEGER(IntKi), PARAMETER :: EddAmbT2N12D2 = 6473 + INTEGER(IntKi), PARAMETER :: EddAmbT2N12D3 = 6474 + INTEGER(IntKi), PARAMETER :: EddAmbT2N12D4 = 6475 + INTEGER(IntKi), PARAMETER :: EddAmbT2N12D5 = 6476 + INTEGER(IntKi), PARAMETER :: EddAmbT2N12D6 = 6477 + INTEGER(IntKi), PARAMETER :: EddAmbT2N12D7 = 6478 + INTEGER(IntKi), PARAMETER :: EddAmbT2N12D8 = 6479 + INTEGER(IntKi), PARAMETER :: EddAmbT2N12D9 = 6480 + INTEGER(IntKi), PARAMETER :: EddAmbT2N13D1 = 6481 + INTEGER(IntKi), PARAMETER :: EddAmbT2N13D2 = 6482 + INTEGER(IntKi), PARAMETER :: EddAmbT2N13D3 = 6483 + INTEGER(IntKi), PARAMETER :: EddAmbT2N13D4 = 6484 + INTEGER(IntKi), PARAMETER :: EddAmbT2N13D5 = 6485 + INTEGER(IntKi), PARAMETER :: EddAmbT2N13D6 = 6486 + INTEGER(IntKi), PARAMETER :: EddAmbT2N13D7 = 6487 + INTEGER(IntKi), PARAMETER :: EddAmbT2N13D8 = 6488 + INTEGER(IntKi), PARAMETER :: EddAmbT2N13D9 = 6489 + INTEGER(IntKi), PARAMETER :: EddAmbT2N14D1 = 6490 + INTEGER(IntKi), PARAMETER :: EddAmbT2N14D2 = 6491 + INTEGER(IntKi), PARAMETER :: EddAmbT2N14D3 = 6492 + INTEGER(IntKi), PARAMETER :: EddAmbT2N14D4 = 6493 + INTEGER(IntKi), PARAMETER :: EddAmbT2N14D5 = 6494 + INTEGER(IntKi), PARAMETER :: EddAmbT2N14D6 = 6495 + INTEGER(IntKi), PARAMETER :: EddAmbT2N14D7 = 6496 + INTEGER(IntKi), PARAMETER :: EddAmbT2N14D8 = 6497 + INTEGER(IntKi), PARAMETER :: EddAmbT2N14D9 = 6498 + INTEGER(IntKi), PARAMETER :: EddAmbT2N15D1 = 6499 + INTEGER(IntKi), PARAMETER :: EddAmbT2N15D2 = 6500 + INTEGER(IntKi), PARAMETER :: EddAmbT2N15D3 = 6501 + INTEGER(IntKi), PARAMETER :: EddAmbT2N15D4 = 6502 + INTEGER(IntKi), PARAMETER :: EddAmbT2N15D5 = 6503 + INTEGER(IntKi), PARAMETER :: EddAmbT2N15D6 = 6504 + INTEGER(IntKi), PARAMETER :: EddAmbT2N15D7 = 6505 + INTEGER(IntKi), PARAMETER :: EddAmbT2N15D8 = 6506 + INTEGER(IntKi), PARAMETER :: EddAmbT2N15D9 = 6507 + INTEGER(IntKi), PARAMETER :: EddAmbT2N16D1 = 6508 + INTEGER(IntKi), PARAMETER :: EddAmbT2N16D2 = 6509 + INTEGER(IntKi), PARAMETER :: EddAmbT2N16D3 = 6510 + INTEGER(IntKi), PARAMETER :: EddAmbT2N16D4 = 6511 + INTEGER(IntKi), PARAMETER :: EddAmbT2N16D5 = 6512 + INTEGER(IntKi), PARAMETER :: EddAmbT2N16D6 = 6513 + INTEGER(IntKi), PARAMETER :: EddAmbT2N16D7 = 6514 + INTEGER(IntKi), PARAMETER :: EddAmbT2N16D8 = 6515 + INTEGER(IntKi), PARAMETER :: EddAmbT2N16D9 = 6516 + INTEGER(IntKi), PARAMETER :: EddAmbT2N17D1 = 6517 + INTEGER(IntKi), PARAMETER :: EddAmbT2N17D2 = 6518 + INTEGER(IntKi), PARAMETER :: EddAmbT2N17D3 = 6519 + INTEGER(IntKi), PARAMETER :: EddAmbT2N17D4 = 6520 + INTEGER(IntKi), PARAMETER :: EddAmbT2N17D5 = 6521 + INTEGER(IntKi), PARAMETER :: EddAmbT2N17D6 = 6522 + INTEGER(IntKi), PARAMETER :: EddAmbT2N17D7 = 6523 + INTEGER(IntKi), PARAMETER :: EddAmbT2N17D8 = 6524 + INTEGER(IntKi), PARAMETER :: EddAmbT2N17D9 = 6525 + INTEGER(IntKi), PARAMETER :: EddAmbT2N18D1 = 6526 + INTEGER(IntKi), PARAMETER :: EddAmbT2N18D2 = 6527 + INTEGER(IntKi), PARAMETER :: EddAmbT2N18D3 = 6528 + INTEGER(IntKi), PARAMETER :: EddAmbT2N18D4 = 6529 + INTEGER(IntKi), PARAMETER :: EddAmbT2N18D5 = 6530 + INTEGER(IntKi), PARAMETER :: EddAmbT2N18D6 = 6531 + INTEGER(IntKi), PARAMETER :: EddAmbT2N18D7 = 6532 + INTEGER(IntKi), PARAMETER :: EddAmbT2N18D8 = 6533 + INTEGER(IntKi), PARAMETER :: EddAmbT2N18D9 = 6534 + INTEGER(IntKi), PARAMETER :: EddAmbT2N19D1 = 6535 + INTEGER(IntKi), PARAMETER :: EddAmbT2N19D2 = 6536 + INTEGER(IntKi), PARAMETER :: EddAmbT2N19D3 = 6537 + INTEGER(IntKi), PARAMETER :: EddAmbT2N19D4 = 6538 + INTEGER(IntKi), PARAMETER :: EddAmbT2N19D5 = 6539 + INTEGER(IntKi), PARAMETER :: EddAmbT2N19D6 = 6540 + INTEGER(IntKi), PARAMETER :: EddAmbT2N19D7 = 6541 + INTEGER(IntKi), PARAMETER :: EddAmbT2N19D8 = 6542 + INTEGER(IntKi), PARAMETER :: EddAmbT2N19D9 = 6543 + INTEGER(IntKi), PARAMETER :: EddAmbT2N20D1 = 6544 + INTEGER(IntKi), PARAMETER :: EddAmbT2N20D2 = 6545 + INTEGER(IntKi), PARAMETER :: EddAmbT2N20D3 = 6546 + INTEGER(IntKi), PARAMETER :: EddAmbT2N20D4 = 6547 + INTEGER(IntKi), PARAMETER :: EddAmbT2N20D5 = 6548 + INTEGER(IntKi), PARAMETER :: EddAmbT2N20D6 = 6549 + INTEGER(IntKi), PARAMETER :: EddAmbT2N20D7 = 6550 + INTEGER(IntKi), PARAMETER :: EddAmbT2N20D8 = 6551 + INTEGER(IntKi), PARAMETER :: EddAmbT2N20D9 = 6552 + INTEGER(IntKi), PARAMETER :: EddAmbT3N01D1 = 6553 + INTEGER(IntKi), PARAMETER :: EddAmbT3N01D2 = 6554 + INTEGER(IntKi), PARAMETER :: EddAmbT3N01D3 = 6555 + INTEGER(IntKi), PARAMETER :: EddAmbT3N01D4 = 6556 + INTEGER(IntKi), PARAMETER :: EddAmbT3N01D5 = 6557 + INTEGER(IntKi), PARAMETER :: EddAmbT3N01D6 = 6558 + INTEGER(IntKi), PARAMETER :: EddAmbT3N01D7 = 6559 + INTEGER(IntKi), PARAMETER :: EddAmbT3N01D8 = 6560 + INTEGER(IntKi), PARAMETER :: EddAmbT3N01D9 = 6561 + INTEGER(IntKi), PARAMETER :: EddAmbT3N02D1 = 6562 + INTEGER(IntKi), PARAMETER :: EddAmbT3N02D2 = 6563 + INTEGER(IntKi), PARAMETER :: EddAmbT3N02D3 = 6564 + INTEGER(IntKi), PARAMETER :: EddAmbT3N02D4 = 6565 + INTEGER(IntKi), PARAMETER :: EddAmbT3N02D5 = 6566 + INTEGER(IntKi), PARAMETER :: EddAmbT3N02D6 = 6567 + INTEGER(IntKi), PARAMETER :: EddAmbT3N02D7 = 6568 + INTEGER(IntKi), PARAMETER :: EddAmbT3N02D8 = 6569 + INTEGER(IntKi), PARAMETER :: EddAmbT3N02D9 = 6570 + INTEGER(IntKi), PARAMETER :: EddAmbT3N03D1 = 6571 + INTEGER(IntKi), PARAMETER :: EddAmbT3N03D2 = 6572 + INTEGER(IntKi), PARAMETER :: EddAmbT3N03D3 = 6573 + INTEGER(IntKi), PARAMETER :: EddAmbT3N03D4 = 6574 + INTEGER(IntKi), PARAMETER :: EddAmbT3N03D5 = 6575 + INTEGER(IntKi), PARAMETER :: EddAmbT3N03D6 = 6576 + INTEGER(IntKi), PARAMETER :: EddAmbT3N03D7 = 6577 + INTEGER(IntKi), PARAMETER :: EddAmbT3N03D8 = 6578 + INTEGER(IntKi), PARAMETER :: EddAmbT3N03D9 = 6579 + INTEGER(IntKi), PARAMETER :: EddAmbT3N04D1 = 6580 + INTEGER(IntKi), PARAMETER :: EddAmbT3N04D2 = 6581 + INTEGER(IntKi), PARAMETER :: EddAmbT3N04D3 = 6582 + INTEGER(IntKi), PARAMETER :: EddAmbT3N04D4 = 6583 + INTEGER(IntKi), PARAMETER :: EddAmbT3N04D5 = 6584 + INTEGER(IntKi), PARAMETER :: EddAmbT3N04D6 = 6585 + INTEGER(IntKi), PARAMETER :: EddAmbT3N04D7 = 6586 + INTEGER(IntKi), PARAMETER :: EddAmbT3N04D8 = 6587 + INTEGER(IntKi), PARAMETER :: EddAmbT3N04D9 = 6588 + INTEGER(IntKi), PARAMETER :: EddAmbT3N05D1 = 6589 + INTEGER(IntKi), PARAMETER :: EddAmbT3N05D2 = 6590 + INTEGER(IntKi), PARAMETER :: EddAmbT3N05D3 = 6591 + INTEGER(IntKi), PARAMETER :: EddAmbT3N05D4 = 6592 + INTEGER(IntKi), PARAMETER :: EddAmbT3N05D5 = 6593 + INTEGER(IntKi), PARAMETER :: EddAmbT3N05D6 = 6594 + INTEGER(IntKi), PARAMETER :: EddAmbT3N05D7 = 6595 + INTEGER(IntKi), PARAMETER :: EddAmbT3N05D8 = 6596 + INTEGER(IntKi), PARAMETER :: EddAmbT3N05D9 = 6597 + INTEGER(IntKi), PARAMETER :: EddAmbT3N06D1 = 6598 + INTEGER(IntKi), PARAMETER :: EddAmbT3N06D2 = 6599 + INTEGER(IntKi), PARAMETER :: EddAmbT3N06D3 = 6600 + INTEGER(IntKi), PARAMETER :: EddAmbT3N06D4 = 6601 + INTEGER(IntKi), PARAMETER :: EddAmbT3N06D5 = 6602 + INTEGER(IntKi), PARAMETER :: EddAmbT3N06D6 = 6603 + INTEGER(IntKi), PARAMETER :: EddAmbT3N06D7 = 6604 + INTEGER(IntKi), PARAMETER :: EddAmbT3N06D8 = 6605 + INTEGER(IntKi), PARAMETER :: EddAmbT3N06D9 = 6606 + INTEGER(IntKi), PARAMETER :: EddAmbT3N07D1 = 6607 + INTEGER(IntKi), PARAMETER :: EddAmbT3N07D2 = 6608 + INTEGER(IntKi), PARAMETER :: EddAmbT3N07D3 = 6609 + INTEGER(IntKi), PARAMETER :: EddAmbT3N07D4 = 6610 + INTEGER(IntKi), PARAMETER :: EddAmbT3N07D5 = 6611 + INTEGER(IntKi), PARAMETER :: EddAmbT3N07D6 = 6612 + INTEGER(IntKi), PARAMETER :: EddAmbT3N07D7 = 6613 + INTEGER(IntKi), PARAMETER :: EddAmbT3N07D8 = 6614 + INTEGER(IntKi), PARAMETER :: EddAmbT3N07D9 = 6615 + INTEGER(IntKi), PARAMETER :: EddAmbT3N08D1 = 6616 + INTEGER(IntKi), PARAMETER :: EddAmbT3N08D2 = 6617 + INTEGER(IntKi), PARAMETER :: EddAmbT3N08D3 = 6618 + INTEGER(IntKi), PARAMETER :: EddAmbT3N08D4 = 6619 + INTEGER(IntKi), PARAMETER :: EddAmbT3N08D5 = 6620 + INTEGER(IntKi), PARAMETER :: EddAmbT3N08D6 = 6621 + INTEGER(IntKi), PARAMETER :: EddAmbT3N08D7 = 6622 + INTEGER(IntKi), PARAMETER :: EddAmbT3N08D8 = 6623 + INTEGER(IntKi), PARAMETER :: EddAmbT3N08D9 = 6624 + INTEGER(IntKi), PARAMETER :: EddAmbT3N09D1 = 6625 + INTEGER(IntKi), PARAMETER :: EddAmbT3N09D2 = 6626 + INTEGER(IntKi), PARAMETER :: EddAmbT3N09D3 = 6627 + INTEGER(IntKi), PARAMETER :: EddAmbT3N09D4 = 6628 + INTEGER(IntKi), PARAMETER :: EddAmbT3N09D5 = 6629 + INTEGER(IntKi), PARAMETER :: EddAmbT3N09D6 = 6630 + INTEGER(IntKi), PARAMETER :: EddAmbT3N09D7 = 6631 + INTEGER(IntKi), PARAMETER :: EddAmbT3N09D8 = 6632 + INTEGER(IntKi), PARAMETER :: EddAmbT3N09D9 = 6633 + INTEGER(IntKi), PARAMETER :: EddAmbT3N10D1 = 6634 + INTEGER(IntKi), PARAMETER :: EddAmbT3N10D2 = 6635 + INTEGER(IntKi), PARAMETER :: EddAmbT3N10D3 = 6636 + INTEGER(IntKi), PARAMETER :: EddAmbT3N10D4 = 6637 + INTEGER(IntKi), PARAMETER :: EddAmbT3N10D5 = 6638 + INTEGER(IntKi), PARAMETER :: EddAmbT3N10D6 = 6639 + INTEGER(IntKi), PARAMETER :: EddAmbT3N10D7 = 6640 + INTEGER(IntKi), PARAMETER :: EddAmbT3N10D8 = 6641 + INTEGER(IntKi), PARAMETER :: EddAmbT3N10D9 = 6642 + INTEGER(IntKi), PARAMETER :: EddAmbT3N11D1 = 6643 + INTEGER(IntKi), PARAMETER :: EddAmbT3N11D2 = 6644 + INTEGER(IntKi), PARAMETER :: EddAmbT3N11D3 = 6645 + INTEGER(IntKi), PARAMETER :: EddAmbT3N11D4 = 6646 + INTEGER(IntKi), PARAMETER :: EddAmbT3N11D5 = 6647 + INTEGER(IntKi), PARAMETER :: EddAmbT3N11D6 = 6648 + INTEGER(IntKi), PARAMETER :: EddAmbT3N11D7 = 6649 + INTEGER(IntKi), PARAMETER :: EddAmbT3N11D8 = 6650 + INTEGER(IntKi), PARAMETER :: EddAmbT3N11D9 = 6651 + INTEGER(IntKi), PARAMETER :: EddAmbT3N12D1 = 6652 + INTEGER(IntKi), PARAMETER :: EddAmbT3N12D2 = 6653 + INTEGER(IntKi), PARAMETER :: EddAmbT3N12D3 = 6654 + INTEGER(IntKi), PARAMETER :: EddAmbT3N12D4 = 6655 + INTEGER(IntKi), PARAMETER :: EddAmbT3N12D5 = 6656 + INTEGER(IntKi), PARAMETER :: EddAmbT3N12D6 = 6657 + INTEGER(IntKi), PARAMETER :: EddAmbT3N12D7 = 6658 + INTEGER(IntKi), PARAMETER :: EddAmbT3N12D8 = 6659 + INTEGER(IntKi), PARAMETER :: EddAmbT3N12D9 = 6660 + INTEGER(IntKi), PARAMETER :: EddAmbT3N13D1 = 6661 + INTEGER(IntKi), PARAMETER :: EddAmbT3N13D2 = 6662 + INTEGER(IntKi), PARAMETER :: EddAmbT3N13D3 = 6663 + INTEGER(IntKi), PARAMETER :: EddAmbT3N13D4 = 6664 + INTEGER(IntKi), PARAMETER :: EddAmbT3N13D5 = 6665 + INTEGER(IntKi), PARAMETER :: EddAmbT3N13D6 = 6666 + INTEGER(IntKi), PARAMETER :: EddAmbT3N13D7 = 6667 + INTEGER(IntKi), PARAMETER :: EddAmbT3N13D8 = 6668 + INTEGER(IntKi), PARAMETER :: EddAmbT3N13D9 = 6669 + INTEGER(IntKi), PARAMETER :: EddAmbT3N14D1 = 6670 + INTEGER(IntKi), PARAMETER :: EddAmbT3N14D2 = 6671 + INTEGER(IntKi), PARAMETER :: EddAmbT3N14D3 = 6672 + INTEGER(IntKi), PARAMETER :: EddAmbT3N14D4 = 6673 + INTEGER(IntKi), PARAMETER :: EddAmbT3N14D5 = 6674 + INTEGER(IntKi), PARAMETER :: EddAmbT3N14D6 = 6675 + INTEGER(IntKi), PARAMETER :: EddAmbT3N14D7 = 6676 + INTEGER(IntKi), PARAMETER :: EddAmbT3N14D8 = 6677 + INTEGER(IntKi), PARAMETER :: EddAmbT3N14D9 = 6678 + INTEGER(IntKi), PARAMETER :: EddAmbT3N15D1 = 6679 + INTEGER(IntKi), PARAMETER :: EddAmbT3N15D2 = 6680 + INTEGER(IntKi), PARAMETER :: EddAmbT3N15D3 = 6681 + INTEGER(IntKi), PARAMETER :: EddAmbT3N15D4 = 6682 + INTEGER(IntKi), PARAMETER :: EddAmbT3N15D5 = 6683 + INTEGER(IntKi), PARAMETER :: EddAmbT3N15D6 = 6684 + INTEGER(IntKi), PARAMETER :: EddAmbT3N15D7 = 6685 + INTEGER(IntKi), PARAMETER :: EddAmbT3N15D8 = 6686 + INTEGER(IntKi), PARAMETER :: EddAmbT3N15D9 = 6687 + INTEGER(IntKi), PARAMETER :: EddAmbT3N16D1 = 6688 + INTEGER(IntKi), PARAMETER :: EddAmbT3N16D2 = 6689 + INTEGER(IntKi), PARAMETER :: EddAmbT3N16D3 = 6690 + INTEGER(IntKi), PARAMETER :: EddAmbT3N16D4 = 6691 + INTEGER(IntKi), PARAMETER :: EddAmbT3N16D5 = 6692 + INTEGER(IntKi), PARAMETER :: EddAmbT3N16D6 = 6693 + INTEGER(IntKi), PARAMETER :: EddAmbT3N16D7 = 6694 + INTEGER(IntKi), PARAMETER :: EddAmbT3N16D8 = 6695 + INTEGER(IntKi), PARAMETER :: EddAmbT3N16D9 = 6696 + INTEGER(IntKi), PARAMETER :: EddAmbT3N17D1 = 6697 + INTEGER(IntKi), PARAMETER :: EddAmbT3N17D2 = 6698 + INTEGER(IntKi), PARAMETER :: EddAmbT3N17D3 = 6699 + INTEGER(IntKi), PARAMETER :: EddAmbT3N17D4 = 6700 + INTEGER(IntKi), PARAMETER :: EddAmbT3N17D5 = 6701 + INTEGER(IntKi), PARAMETER :: EddAmbT3N17D6 = 6702 + INTEGER(IntKi), PARAMETER :: EddAmbT3N17D7 = 6703 + INTEGER(IntKi), PARAMETER :: EddAmbT3N17D8 = 6704 + INTEGER(IntKi), PARAMETER :: EddAmbT3N17D9 = 6705 + INTEGER(IntKi), PARAMETER :: EddAmbT3N18D1 = 6706 + INTEGER(IntKi), PARAMETER :: EddAmbT3N18D2 = 6707 + INTEGER(IntKi), PARAMETER :: EddAmbT3N18D3 = 6708 + INTEGER(IntKi), PARAMETER :: EddAmbT3N18D4 = 6709 + INTEGER(IntKi), PARAMETER :: EddAmbT3N18D5 = 6710 + INTEGER(IntKi), PARAMETER :: EddAmbT3N18D6 = 6711 + INTEGER(IntKi), PARAMETER :: EddAmbT3N18D7 = 6712 + INTEGER(IntKi), PARAMETER :: EddAmbT3N18D8 = 6713 + INTEGER(IntKi), PARAMETER :: EddAmbT3N18D9 = 6714 + INTEGER(IntKi), PARAMETER :: EddAmbT3N19D1 = 6715 + INTEGER(IntKi), PARAMETER :: EddAmbT3N19D2 = 6716 + INTEGER(IntKi), PARAMETER :: EddAmbT3N19D3 = 6717 + INTEGER(IntKi), PARAMETER :: EddAmbT3N19D4 = 6718 + INTEGER(IntKi), PARAMETER :: EddAmbT3N19D5 = 6719 + INTEGER(IntKi), PARAMETER :: EddAmbT3N19D6 = 6720 + INTEGER(IntKi), PARAMETER :: EddAmbT3N19D7 = 6721 + INTEGER(IntKi), PARAMETER :: EddAmbT3N19D8 = 6722 + INTEGER(IntKi), PARAMETER :: EddAmbT3N19D9 = 6723 + INTEGER(IntKi), PARAMETER :: EddAmbT3N20D1 = 6724 + INTEGER(IntKi), PARAMETER :: EddAmbT3N20D2 = 6725 + INTEGER(IntKi), PARAMETER :: EddAmbT3N20D3 = 6726 + INTEGER(IntKi), PARAMETER :: EddAmbT3N20D4 = 6727 + INTEGER(IntKi), PARAMETER :: EddAmbT3N20D5 = 6728 + INTEGER(IntKi), PARAMETER :: EddAmbT3N20D6 = 6729 + INTEGER(IntKi), PARAMETER :: EddAmbT3N20D7 = 6730 + INTEGER(IntKi), PARAMETER :: EddAmbT3N20D8 = 6731 + INTEGER(IntKi), PARAMETER :: EddAmbT3N20D9 = 6732 + INTEGER(IntKi), PARAMETER :: EddAmbT4N01D1 = 6733 + INTEGER(IntKi), PARAMETER :: EddAmbT4N01D2 = 6734 + INTEGER(IntKi), PARAMETER :: EddAmbT4N01D3 = 6735 + INTEGER(IntKi), PARAMETER :: EddAmbT4N01D4 = 6736 + INTEGER(IntKi), PARAMETER :: EddAmbT4N01D5 = 6737 + INTEGER(IntKi), PARAMETER :: EddAmbT4N01D6 = 6738 + INTEGER(IntKi), PARAMETER :: EddAmbT4N01D7 = 6739 + INTEGER(IntKi), PARAMETER :: EddAmbT4N01D8 = 6740 + INTEGER(IntKi), PARAMETER :: EddAmbT4N01D9 = 6741 + INTEGER(IntKi), PARAMETER :: EddAmbT4N02D1 = 6742 + INTEGER(IntKi), PARAMETER :: EddAmbT4N02D2 = 6743 + INTEGER(IntKi), PARAMETER :: EddAmbT4N02D3 = 6744 + INTEGER(IntKi), PARAMETER :: EddAmbT4N02D4 = 6745 + INTEGER(IntKi), PARAMETER :: EddAmbT4N02D5 = 6746 + INTEGER(IntKi), PARAMETER :: EddAmbT4N02D6 = 6747 + INTEGER(IntKi), PARAMETER :: EddAmbT4N02D7 = 6748 + INTEGER(IntKi), PARAMETER :: EddAmbT4N02D8 = 6749 + INTEGER(IntKi), PARAMETER :: EddAmbT4N02D9 = 6750 + INTEGER(IntKi), PARAMETER :: EddAmbT4N03D1 = 6751 + INTEGER(IntKi), PARAMETER :: EddAmbT4N03D2 = 6752 + INTEGER(IntKi), PARAMETER :: EddAmbT4N03D3 = 6753 + INTEGER(IntKi), PARAMETER :: EddAmbT4N03D4 = 6754 + INTEGER(IntKi), PARAMETER :: EddAmbT4N03D5 = 6755 + INTEGER(IntKi), PARAMETER :: EddAmbT4N03D6 = 6756 + INTEGER(IntKi), PARAMETER :: EddAmbT4N03D7 = 6757 + INTEGER(IntKi), PARAMETER :: EddAmbT4N03D8 = 6758 + INTEGER(IntKi), PARAMETER :: EddAmbT4N03D9 = 6759 + INTEGER(IntKi), PARAMETER :: EddAmbT4N04D1 = 6760 + INTEGER(IntKi), PARAMETER :: EddAmbT4N04D2 = 6761 + INTEGER(IntKi), PARAMETER :: EddAmbT4N04D3 = 6762 + INTEGER(IntKi), PARAMETER :: EddAmbT4N04D4 = 6763 + INTEGER(IntKi), PARAMETER :: EddAmbT4N04D5 = 6764 + INTEGER(IntKi), PARAMETER :: EddAmbT4N04D6 = 6765 + INTEGER(IntKi), PARAMETER :: EddAmbT4N04D7 = 6766 + INTEGER(IntKi), PARAMETER :: EddAmbT4N04D8 = 6767 + INTEGER(IntKi), PARAMETER :: EddAmbT4N04D9 = 6768 + INTEGER(IntKi), PARAMETER :: EddAmbT4N05D1 = 6769 + INTEGER(IntKi), PARAMETER :: EddAmbT4N05D2 = 6770 + INTEGER(IntKi), PARAMETER :: EddAmbT4N05D3 = 6771 + INTEGER(IntKi), PARAMETER :: EddAmbT4N05D4 = 6772 + INTEGER(IntKi), PARAMETER :: EddAmbT4N05D5 = 6773 + INTEGER(IntKi), PARAMETER :: EddAmbT4N05D6 = 6774 + INTEGER(IntKi), PARAMETER :: EddAmbT4N05D7 = 6775 + INTEGER(IntKi), PARAMETER :: EddAmbT4N05D8 = 6776 + INTEGER(IntKi), PARAMETER :: EddAmbT4N05D9 = 6777 + INTEGER(IntKi), PARAMETER :: EddAmbT4N06D1 = 6778 + INTEGER(IntKi), PARAMETER :: EddAmbT4N06D2 = 6779 + INTEGER(IntKi), PARAMETER :: EddAmbT4N06D3 = 6780 + INTEGER(IntKi), PARAMETER :: EddAmbT4N06D4 = 6781 + INTEGER(IntKi), PARAMETER :: EddAmbT4N06D5 = 6782 + INTEGER(IntKi), PARAMETER :: EddAmbT4N06D6 = 6783 + INTEGER(IntKi), PARAMETER :: EddAmbT4N06D7 = 6784 + INTEGER(IntKi), PARAMETER :: EddAmbT4N06D8 = 6785 + INTEGER(IntKi), PARAMETER :: EddAmbT4N06D9 = 6786 + INTEGER(IntKi), PARAMETER :: EddAmbT4N07D1 = 6787 + INTEGER(IntKi), PARAMETER :: EddAmbT4N07D2 = 6788 + INTEGER(IntKi), PARAMETER :: EddAmbT4N07D3 = 6789 + INTEGER(IntKi), PARAMETER :: EddAmbT4N07D4 = 6790 + INTEGER(IntKi), PARAMETER :: EddAmbT4N07D5 = 6791 + INTEGER(IntKi), PARAMETER :: EddAmbT4N07D6 = 6792 + INTEGER(IntKi), PARAMETER :: EddAmbT4N07D7 = 6793 + INTEGER(IntKi), PARAMETER :: EddAmbT4N07D8 = 6794 + INTEGER(IntKi), PARAMETER :: EddAmbT4N07D9 = 6795 + INTEGER(IntKi), PARAMETER :: EddAmbT4N08D1 = 6796 + INTEGER(IntKi), PARAMETER :: EddAmbT4N08D2 = 6797 + INTEGER(IntKi), PARAMETER :: EddAmbT4N08D3 = 6798 + INTEGER(IntKi), PARAMETER :: EddAmbT4N08D4 = 6799 + INTEGER(IntKi), PARAMETER :: EddAmbT4N08D5 = 6800 + INTEGER(IntKi), PARAMETER :: EddAmbT4N08D6 = 6801 + INTEGER(IntKi), PARAMETER :: EddAmbT4N08D7 = 6802 + INTEGER(IntKi), PARAMETER :: EddAmbT4N08D8 = 6803 + INTEGER(IntKi), PARAMETER :: EddAmbT4N08D9 = 6804 + INTEGER(IntKi), PARAMETER :: EddAmbT4N09D1 = 6805 + INTEGER(IntKi), PARAMETER :: EddAmbT4N09D2 = 6806 + INTEGER(IntKi), PARAMETER :: EddAmbT4N09D3 = 6807 + INTEGER(IntKi), PARAMETER :: EddAmbT4N09D4 = 6808 + INTEGER(IntKi), PARAMETER :: EddAmbT4N09D5 = 6809 + INTEGER(IntKi), PARAMETER :: EddAmbT4N09D6 = 6810 + INTEGER(IntKi), PARAMETER :: EddAmbT4N09D7 = 6811 + INTEGER(IntKi), PARAMETER :: EddAmbT4N09D8 = 6812 + INTEGER(IntKi), PARAMETER :: EddAmbT4N09D9 = 6813 + INTEGER(IntKi), PARAMETER :: EddAmbT4N10D1 = 6814 + INTEGER(IntKi), PARAMETER :: EddAmbT4N10D2 = 6815 + INTEGER(IntKi), PARAMETER :: EddAmbT4N10D3 = 6816 + INTEGER(IntKi), PARAMETER :: EddAmbT4N10D4 = 6817 + INTEGER(IntKi), PARAMETER :: EddAmbT4N10D5 = 6818 + INTEGER(IntKi), PARAMETER :: EddAmbT4N10D6 = 6819 + INTEGER(IntKi), PARAMETER :: EddAmbT4N10D7 = 6820 + INTEGER(IntKi), PARAMETER :: EddAmbT4N10D8 = 6821 + INTEGER(IntKi), PARAMETER :: EddAmbT4N10D9 = 6822 + INTEGER(IntKi), PARAMETER :: EddAmbT4N11D1 = 6823 + INTEGER(IntKi), PARAMETER :: EddAmbT4N11D2 = 6824 + INTEGER(IntKi), PARAMETER :: EddAmbT4N11D3 = 6825 + INTEGER(IntKi), PARAMETER :: EddAmbT4N11D4 = 6826 + INTEGER(IntKi), PARAMETER :: EddAmbT4N11D5 = 6827 + INTEGER(IntKi), PARAMETER :: EddAmbT4N11D6 = 6828 + INTEGER(IntKi), PARAMETER :: EddAmbT4N11D7 = 6829 + INTEGER(IntKi), PARAMETER :: EddAmbT4N11D8 = 6830 + INTEGER(IntKi), PARAMETER :: EddAmbT4N11D9 = 6831 + INTEGER(IntKi), PARAMETER :: EddAmbT4N12D1 = 6832 + INTEGER(IntKi), PARAMETER :: EddAmbT4N12D2 = 6833 + INTEGER(IntKi), PARAMETER :: EddAmbT4N12D3 = 6834 + INTEGER(IntKi), PARAMETER :: EddAmbT4N12D4 = 6835 + INTEGER(IntKi), PARAMETER :: EddAmbT4N12D5 = 6836 + INTEGER(IntKi), PARAMETER :: EddAmbT4N12D6 = 6837 + INTEGER(IntKi), PARAMETER :: EddAmbT4N12D7 = 6838 + INTEGER(IntKi), PARAMETER :: EddAmbT4N12D8 = 6839 + INTEGER(IntKi), PARAMETER :: EddAmbT4N12D9 = 6840 + INTEGER(IntKi), PARAMETER :: EddAmbT4N13D1 = 6841 + INTEGER(IntKi), PARAMETER :: EddAmbT4N13D2 = 6842 + INTEGER(IntKi), PARAMETER :: EddAmbT4N13D3 = 6843 + INTEGER(IntKi), PARAMETER :: EddAmbT4N13D4 = 6844 + INTEGER(IntKi), PARAMETER :: EddAmbT4N13D5 = 6845 + INTEGER(IntKi), PARAMETER :: EddAmbT4N13D6 = 6846 + INTEGER(IntKi), PARAMETER :: EddAmbT4N13D7 = 6847 + INTEGER(IntKi), PARAMETER :: EddAmbT4N13D8 = 6848 + INTEGER(IntKi), PARAMETER :: EddAmbT4N13D9 = 6849 + INTEGER(IntKi), PARAMETER :: EddAmbT4N14D1 = 6850 + INTEGER(IntKi), PARAMETER :: EddAmbT4N14D2 = 6851 + INTEGER(IntKi), PARAMETER :: EddAmbT4N14D3 = 6852 + INTEGER(IntKi), PARAMETER :: EddAmbT4N14D4 = 6853 + INTEGER(IntKi), PARAMETER :: EddAmbT4N14D5 = 6854 + INTEGER(IntKi), PARAMETER :: EddAmbT4N14D6 = 6855 + INTEGER(IntKi), PARAMETER :: EddAmbT4N14D7 = 6856 + INTEGER(IntKi), PARAMETER :: EddAmbT4N14D8 = 6857 + INTEGER(IntKi), PARAMETER :: EddAmbT4N14D9 = 6858 + INTEGER(IntKi), PARAMETER :: EddAmbT4N15D1 = 6859 + INTEGER(IntKi), PARAMETER :: EddAmbT4N15D2 = 6860 + INTEGER(IntKi), PARAMETER :: EddAmbT4N15D3 = 6861 + INTEGER(IntKi), PARAMETER :: EddAmbT4N15D4 = 6862 + INTEGER(IntKi), PARAMETER :: EddAmbT4N15D5 = 6863 + INTEGER(IntKi), PARAMETER :: EddAmbT4N15D6 = 6864 + INTEGER(IntKi), PARAMETER :: EddAmbT4N15D7 = 6865 + INTEGER(IntKi), PARAMETER :: EddAmbT4N15D8 = 6866 + INTEGER(IntKi), PARAMETER :: EddAmbT4N15D9 = 6867 + INTEGER(IntKi), PARAMETER :: EddAmbT4N16D1 = 6868 + INTEGER(IntKi), PARAMETER :: EddAmbT4N16D2 = 6869 + INTEGER(IntKi), PARAMETER :: EddAmbT4N16D3 = 6870 + INTEGER(IntKi), PARAMETER :: EddAmbT4N16D4 = 6871 + INTEGER(IntKi), PARAMETER :: EddAmbT4N16D5 = 6872 + INTEGER(IntKi), PARAMETER :: EddAmbT4N16D6 = 6873 + INTEGER(IntKi), PARAMETER :: EddAmbT4N16D7 = 6874 + INTEGER(IntKi), PARAMETER :: EddAmbT4N16D8 = 6875 + INTEGER(IntKi), PARAMETER :: EddAmbT4N16D9 = 6876 + INTEGER(IntKi), PARAMETER :: EddAmbT4N17D1 = 6877 + INTEGER(IntKi), PARAMETER :: EddAmbT4N17D2 = 6878 + INTEGER(IntKi), PARAMETER :: EddAmbT4N17D3 = 6879 + INTEGER(IntKi), PARAMETER :: EddAmbT4N17D4 = 6880 + INTEGER(IntKi), PARAMETER :: EddAmbT4N17D5 = 6881 + INTEGER(IntKi), PARAMETER :: EddAmbT4N17D6 = 6882 + INTEGER(IntKi), PARAMETER :: EddAmbT4N17D7 = 6883 + INTEGER(IntKi), PARAMETER :: EddAmbT4N17D8 = 6884 + INTEGER(IntKi), PARAMETER :: EddAmbT4N17D9 = 6885 + INTEGER(IntKi), PARAMETER :: EddAmbT4N18D1 = 6886 + INTEGER(IntKi), PARAMETER :: EddAmbT4N18D2 = 6887 + INTEGER(IntKi), PARAMETER :: EddAmbT4N18D3 = 6888 + INTEGER(IntKi), PARAMETER :: EddAmbT4N18D4 = 6889 + INTEGER(IntKi), PARAMETER :: EddAmbT4N18D5 = 6890 + INTEGER(IntKi), PARAMETER :: EddAmbT4N18D6 = 6891 + INTEGER(IntKi), PARAMETER :: EddAmbT4N18D7 = 6892 + INTEGER(IntKi), PARAMETER :: EddAmbT4N18D8 = 6893 + INTEGER(IntKi), PARAMETER :: EddAmbT4N18D9 = 6894 + INTEGER(IntKi), PARAMETER :: EddAmbT4N19D1 = 6895 + INTEGER(IntKi), PARAMETER :: EddAmbT4N19D2 = 6896 + INTEGER(IntKi), PARAMETER :: EddAmbT4N19D3 = 6897 + INTEGER(IntKi), PARAMETER :: EddAmbT4N19D4 = 6898 + INTEGER(IntKi), PARAMETER :: EddAmbT4N19D5 = 6899 + INTEGER(IntKi), PARAMETER :: EddAmbT4N19D6 = 6900 + INTEGER(IntKi), PARAMETER :: EddAmbT4N19D7 = 6901 + INTEGER(IntKi), PARAMETER :: EddAmbT4N19D8 = 6902 + INTEGER(IntKi), PARAMETER :: EddAmbT4N19D9 = 6903 + INTEGER(IntKi), PARAMETER :: EddAmbT4N20D1 = 6904 + INTEGER(IntKi), PARAMETER :: EddAmbT4N20D2 = 6905 + INTEGER(IntKi), PARAMETER :: EddAmbT4N20D3 = 6906 + INTEGER(IntKi), PARAMETER :: EddAmbT4N20D4 = 6907 + INTEGER(IntKi), PARAMETER :: EddAmbT4N20D5 = 6908 + INTEGER(IntKi), PARAMETER :: EddAmbT4N20D6 = 6909 + INTEGER(IntKi), PARAMETER :: EddAmbT4N20D7 = 6910 + INTEGER(IntKi), PARAMETER :: EddAmbT4N20D8 = 6911 + INTEGER(IntKi), PARAMETER :: EddAmbT4N20D9 = 6912 + INTEGER(IntKi), PARAMETER :: EddAmbT5N01D1 = 6913 + INTEGER(IntKi), PARAMETER :: EddAmbT5N01D2 = 6914 + INTEGER(IntKi), PARAMETER :: EddAmbT5N01D3 = 6915 + INTEGER(IntKi), PARAMETER :: EddAmbT5N01D4 = 6916 + INTEGER(IntKi), PARAMETER :: EddAmbT5N01D5 = 6917 + INTEGER(IntKi), PARAMETER :: EddAmbT5N01D6 = 6918 + INTEGER(IntKi), PARAMETER :: EddAmbT5N01D7 = 6919 + INTEGER(IntKi), PARAMETER :: EddAmbT5N01D8 = 6920 + INTEGER(IntKi), PARAMETER :: EddAmbT5N01D9 = 6921 + INTEGER(IntKi), PARAMETER :: EddAmbT5N02D1 = 6922 + INTEGER(IntKi), PARAMETER :: EddAmbT5N02D2 = 6923 + INTEGER(IntKi), PARAMETER :: EddAmbT5N02D3 = 6924 + INTEGER(IntKi), PARAMETER :: EddAmbT5N02D4 = 6925 + INTEGER(IntKi), PARAMETER :: EddAmbT5N02D5 = 6926 + INTEGER(IntKi), PARAMETER :: EddAmbT5N02D6 = 6927 + INTEGER(IntKi), PARAMETER :: EddAmbT5N02D7 = 6928 + INTEGER(IntKi), PARAMETER :: EddAmbT5N02D8 = 6929 + INTEGER(IntKi), PARAMETER :: EddAmbT5N02D9 = 6930 + INTEGER(IntKi), PARAMETER :: EddAmbT5N03D1 = 6931 + INTEGER(IntKi), PARAMETER :: EddAmbT5N03D2 = 6932 + INTEGER(IntKi), PARAMETER :: EddAmbT5N03D3 = 6933 + INTEGER(IntKi), PARAMETER :: EddAmbT5N03D4 = 6934 + INTEGER(IntKi), PARAMETER :: EddAmbT5N03D5 = 6935 + INTEGER(IntKi), PARAMETER :: EddAmbT5N03D6 = 6936 + INTEGER(IntKi), PARAMETER :: EddAmbT5N03D7 = 6937 + INTEGER(IntKi), PARAMETER :: EddAmbT5N03D8 = 6938 + INTEGER(IntKi), PARAMETER :: EddAmbT5N03D9 = 6939 + INTEGER(IntKi), PARAMETER :: EddAmbT5N04D1 = 6940 + INTEGER(IntKi), PARAMETER :: EddAmbT5N04D2 = 6941 + INTEGER(IntKi), PARAMETER :: EddAmbT5N04D3 = 6942 + INTEGER(IntKi), PARAMETER :: EddAmbT5N04D4 = 6943 + INTEGER(IntKi), PARAMETER :: EddAmbT5N04D5 = 6944 + INTEGER(IntKi), PARAMETER :: EddAmbT5N04D6 = 6945 + INTEGER(IntKi), PARAMETER :: EddAmbT5N04D7 = 6946 + INTEGER(IntKi), PARAMETER :: EddAmbT5N04D8 = 6947 + INTEGER(IntKi), PARAMETER :: EddAmbT5N04D9 = 6948 + INTEGER(IntKi), PARAMETER :: EddAmbT5N05D1 = 6949 + INTEGER(IntKi), PARAMETER :: EddAmbT5N05D2 = 6950 + INTEGER(IntKi), PARAMETER :: EddAmbT5N05D3 = 6951 + INTEGER(IntKi), PARAMETER :: EddAmbT5N05D4 = 6952 + INTEGER(IntKi), PARAMETER :: EddAmbT5N05D5 = 6953 + INTEGER(IntKi), PARAMETER :: EddAmbT5N05D6 = 6954 + INTEGER(IntKi), PARAMETER :: EddAmbT5N05D7 = 6955 + INTEGER(IntKi), PARAMETER :: EddAmbT5N05D8 = 6956 + INTEGER(IntKi), PARAMETER :: EddAmbT5N05D9 = 6957 + INTEGER(IntKi), PARAMETER :: EddAmbT5N06D1 = 6958 + INTEGER(IntKi), PARAMETER :: EddAmbT5N06D2 = 6959 + INTEGER(IntKi), PARAMETER :: EddAmbT5N06D3 = 6960 + INTEGER(IntKi), PARAMETER :: EddAmbT5N06D4 = 6961 + INTEGER(IntKi), PARAMETER :: EddAmbT5N06D5 = 6962 + INTEGER(IntKi), PARAMETER :: EddAmbT5N06D6 = 6963 + INTEGER(IntKi), PARAMETER :: EddAmbT5N06D7 = 6964 + INTEGER(IntKi), PARAMETER :: EddAmbT5N06D8 = 6965 + INTEGER(IntKi), PARAMETER :: EddAmbT5N06D9 = 6966 + INTEGER(IntKi), PARAMETER :: EddAmbT5N07D1 = 6967 + INTEGER(IntKi), PARAMETER :: EddAmbT5N07D2 = 6968 + INTEGER(IntKi), PARAMETER :: EddAmbT5N07D3 = 6969 + INTEGER(IntKi), PARAMETER :: EddAmbT5N07D4 = 6970 + INTEGER(IntKi), PARAMETER :: EddAmbT5N07D5 = 6971 + INTEGER(IntKi), PARAMETER :: EddAmbT5N07D6 = 6972 + INTEGER(IntKi), PARAMETER :: EddAmbT5N07D7 = 6973 + INTEGER(IntKi), PARAMETER :: EddAmbT5N07D8 = 6974 + INTEGER(IntKi), PARAMETER :: EddAmbT5N07D9 = 6975 + INTEGER(IntKi), PARAMETER :: EddAmbT5N08D1 = 6976 + INTEGER(IntKi), PARAMETER :: EddAmbT5N08D2 = 6977 + INTEGER(IntKi), PARAMETER :: EddAmbT5N08D3 = 6978 + INTEGER(IntKi), PARAMETER :: EddAmbT5N08D4 = 6979 + INTEGER(IntKi), PARAMETER :: EddAmbT5N08D5 = 6980 + INTEGER(IntKi), PARAMETER :: EddAmbT5N08D6 = 6981 + INTEGER(IntKi), PARAMETER :: EddAmbT5N08D7 = 6982 + INTEGER(IntKi), PARAMETER :: EddAmbT5N08D8 = 6983 + INTEGER(IntKi), PARAMETER :: EddAmbT5N08D9 = 6984 + INTEGER(IntKi), PARAMETER :: EddAmbT5N09D1 = 6985 + INTEGER(IntKi), PARAMETER :: EddAmbT5N09D2 = 6986 + INTEGER(IntKi), PARAMETER :: EddAmbT5N09D3 = 6987 + INTEGER(IntKi), PARAMETER :: EddAmbT5N09D4 = 6988 + INTEGER(IntKi), PARAMETER :: EddAmbT5N09D5 = 6989 + INTEGER(IntKi), PARAMETER :: EddAmbT5N09D6 = 6990 + INTEGER(IntKi), PARAMETER :: EddAmbT5N09D7 = 6991 + INTEGER(IntKi), PARAMETER :: EddAmbT5N09D8 = 6992 + INTEGER(IntKi), PARAMETER :: EddAmbT5N09D9 = 6993 + INTEGER(IntKi), PARAMETER :: EddAmbT5N10D1 = 6994 + INTEGER(IntKi), PARAMETER :: EddAmbT5N10D2 = 6995 + INTEGER(IntKi), PARAMETER :: EddAmbT5N10D3 = 6996 + INTEGER(IntKi), PARAMETER :: EddAmbT5N10D4 = 6997 + INTEGER(IntKi), PARAMETER :: EddAmbT5N10D5 = 6998 + INTEGER(IntKi), PARAMETER :: EddAmbT5N10D6 = 6999 + INTEGER(IntKi), PARAMETER :: EddAmbT5N10D7 = 7000 + INTEGER(IntKi), PARAMETER :: EddAmbT5N10D8 = 7001 + INTEGER(IntKi), PARAMETER :: EddAmbT5N10D9 = 7002 + INTEGER(IntKi), PARAMETER :: EddAmbT5N11D1 = 7003 + INTEGER(IntKi), PARAMETER :: EddAmbT5N11D2 = 7004 + INTEGER(IntKi), PARAMETER :: EddAmbT5N11D3 = 7005 + INTEGER(IntKi), PARAMETER :: EddAmbT5N11D4 = 7006 + INTEGER(IntKi), PARAMETER :: EddAmbT5N11D5 = 7007 + INTEGER(IntKi), PARAMETER :: EddAmbT5N11D6 = 7008 + INTEGER(IntKi), PARAMETER :: EddAmbT5N11D7 = 7009 + INTEGER(IntKi), PARAMETER :: EddAmbT5N11D8 = 7010 + INTEGER(IntKi), PARAMETER :: EddAmbT5N11D9 = 7011 + INTEGER(IntKi), PARAMETER :: EddAmbT5N12D1 = 7012 + INTEGER(IntKi), PARAMETER :: EddAmbT5N12D2 = 7013 + INTEGER(IntKi), PARAMETER :: EddAmbT5N12D3 = 7014 + INTEGER(IntKi), PARAMETER :: EddAmbT5N12D4 = 7015 + INTEGER(IntKi), PARAMETER :: EddAmbT5N12D5 = 7016 + INTEGER(IntKi), PARAMETER :: EddAmbT5N12D6 = 7017 + INTEGER(IntKi), PARAMETER :: EddAmbT5N12D7 = 7018 + INTEGER(IntKi), PARAMETER :: EddAmbT5N12D8 = 7019 + INTEGER(IntKi), PARAMETER :: EddAmbT5N12D9 = 7020 + INTEGER(IntKi), PARAMETER :: EddAmbT5N13D1 = 7021 + INTEGER(IntKi), PARAMETER :: EddAmbT5N13D2 = 7022 + INTEGER(IntKi), PARAMETER :: EddAmbT5N13D3 = 7023 + INTEGER(IntKi), PARAMETER :: EddAmbT5N13D4 = 7024 + INTEGER(IntKi), PARAMETER :: EddAmbT5N13D5 = 7025 + INTEGER(IntKi), PARAMETER :: EddAmbT5N13D6 = 7026 + INTEGER(IntKi), PARAMETER :: EddAmbT5N13D7 = 7027 + INTEGER(IntKi), PARAMETER :: EddAmbT5N13D8 = 7028 + INTEGER(IntKi), PARAMETER :: EddAmbT5N13D9 = 7029 + INTEGER(IntKi), PARAMETER :: EddAmbT5N14D1 = 7030 + INTEGER(IntKi), PARAMETER :: EddAmbT5N14D2 = 7031 + INTEGER(IntKi), PARAMETER :: EddAmbT5N14D3 = 7032 + INTEGER(IntKi), PARAMETER :: EddAmbT5N14D4 = 7033 + INTEGER(IntKi), PARAMETER :: EddAmbT5N14D5 = 7034 + INTEGER(IntKi), PARAMETER :: EddAmbT5N14D6 = 7035 + INTEGER(IntKi), PARAMETER :: EddAmbT5N14D7 = 7036 + INTEGER(IntKi), PARAMETER :: EddAmbT5N14D8 = 7037 + INTEGER(IntKi), PARAMETER :: EddAmbT5N14D9 = 7038 + INTEGER(IntKi), PARAMETER :: EddAmbT5N15D1 = 7039 + INTEGER(IntKi), PARAMETER :: EddAmbT5N15D2 = 7040 + INTEGER(IntKi), PARAMETER :: EddAmbT5N15D3 = 7041 + INTEGER(IntKi), PARAMETER :: EddAmbT5N15D4 = 7042 + INTEGER(IntKi), PARAMETER :: EddAmbT5N15D5 = 7043 + INTEGER(IntKi), PARAMETER :: EddAmbT5N15D6 = 7044 + INTEGER(IntKi), PARAMETER :: EddAmbT5N15D7 = 7045 + INTEGER(IntKi), PARAMETER :: EddAmbT5N15D8 = 7046 + INTEGER(IntKi), PARAMETER :: EddAmbT5N15D9 = 7047 + INTEGER(IntKi), PARAMETER :: EddAmbT5N16D1 = 7048 + INTEGER(IntKi), PARAMETER :: EddAmbT5N16D2 = 7049 + INTEGER(IntKi), PARAMETER :: EddAmbT5N16D3 = 7050 + INTEGER(IntKi), PARAMETER :: EddAmbT5N16D4 = 7051 + INTEGER(IntKi), PARAMETER :: EddAmbT5N16D5 = 7052 + INTEGER(IntKi), PARAMETER :: EddAmbT5N16D6 = 7053 + INTEGER(IntKi), PARAMETER :: EddAmbT5N16D7 = 7054 + INTEGER(IntKi), PARAMETER :: EddAmbT5N16D8 = 7055 + INTEGER(IntKi), PARAMETER :: EddAmbT5N16D9 = 7056 + INTEGER(IntKi), PARAMETER :: EddAmbT5N17D1 = 7057 + INTEGER(IntKi), PARAMETER :: EddAmbT5N17D2 = 7058 + INTEGER(IntKi), PARAMETER :: EddAmbT5N17D3 = 7059 + INTEGER(IntKi), PARAMETER :: EddAmbT5N17D4 = 7060 + INTEGER(IntKi), PARAMETER :: EddAmbT5N17D5 = 7061 + INTEGER(IntKi), PARAMETER :: EddAmbT5N17D6 = 7062 + INTEGER(IntKi), PARAMETER :: EddAmbT5N17D7 = 7063 + INTEGER(IntKi), PARAMETER :: EddAmbT5N17D8 = 7064 + INTEGER(IntKi), PARAMETER :: EddAmbT5N17D9 = 7065 + INTEGER(IntKi), PARAMETER :: EddAmbT5N18D1 = 7066 + INTEGER(IntKi), PARAMETER :: EddAmbT5N18D2 = 7067 + INTEGER(IntKi), PARAMETER :: EddAmbT5N18D3 = 7068 + INTEGER(IntKi), PARAMETER :: EddAmbT5N18D4 = 7069 + INTEGER(IntKi), PARAMETER :: EddAmbT5N18D5 = 7070 + INTEGER(IntKi), PARAMETER :: EddAmbT5N18D6 = 7071 + INTEGER(IntKi), PARAMETER :: EddAmbT5N18D7 = 7072 + INTEGER(IntKi), PARAMETER :: EddAmbT5N18D8 = 7073 + INTEGER(IntKi), PARAMETER :: EddAmbT5N18D9 = 7074 + INTEGER(IntKi), PARAMETER :: EddAmbT5N19D1 = 7075 + INTEGER(IntKi), PARAMETER :: EddAmbT5N19D2 = 7076 + INTEGER(IntKi), PARAMETER :: EddAmbT5N19D3 = 7077 + INTEGER(IntKi), PARAMETER :: EddAmbT5N19D4 = 7078 + INTEGER(IntKi), PARAMETER :: EddAmbT5N19D5 = 7079 + INTEGER(IntKi), PARAMETER :: EddAmbT5N19D6 = 7080 + INTEGER(IntKi), PARAMETER :: EddAmbT5N19D7 = 7081 + INTEGER(IntKi), PARAMETER :: EddAmbT5N19D8 = 7082 + INTEGER(IntKi), PARAMETER :: EddAmbT5N19D9 = 7083 + INTEGER(IntKi), PARAMETER :: EddAmbT5N20D1 = 7084 + INTEGER(IntKi), PARAMETER :: EddAmbT5N20D2 = 7085 + INTEGER(IntKi), PARAMETER :: EddAmbT5N20D3 = 7086 + INTEGER(IntKi), PARAMETER :: EddAmbT5N20D4 = 7087 + INTEGER(IntKi), PARAMETER :: EddAmbT5N20D5 = 7088 + INTEGER(IntKi), PARAMETER :: EddAmbT5N20D6 = 7089 + INTEGER(IntKi), PARAMETER :: EddAmbT5N20D7 = 7090 + INTEGER(IntKi), PARAMETER :: EddAmbT5N20D8 = 7091 + INTEGER(IntKi), PARAMETER :: EddAmbT5N20D9 = 7092 + INTEGER(IntKi), PARAMETER :: EddAmbT6N01D1 = 7093 + INTEGER(IntKi), PARAMETER :: EddAmbT6N01D2 = 7094 + INTEGER(IntKi), PARAMETER :: EddAmbT6N01D3 = 7095 + INTEGER(IntKi), PARAMETER :: EddAmbT6N01D4 = 7096 + INTEGER(IntKi), PARAMETER :: EddAmbT6N01D5 = 7097 + INTEGER(IntKi), PARAMETER :: EddAmbT6N01D6 = 7098 + INTEGER(IntKi), PARAMETER :: EddAmbT6N01D7 = 7099 + INTEGER(IntKi), PARAMETER :: EddAmbT6N01D8 = 7100 + INTEGER(IntKi), PARAMETER :: EddAmbT6N01D9 = 7101 + INTEGER(IntKi), PARAMETER :: EddAmbT6N02D1 = 7102 + INTEGER(IntKi), PARAMETER :: EddAmbT6N02D2 = 7103 + INTEGER(IntKi), PARAMETER :: EddAmbT6N02D3 = 7104 + INTEGER(IntKi), PARAMETER :: EddAmbT6N02D4 = 7105 + INTEGER(IntKi), PARAMETER :: EddAmbT6N02D5 = 7106 + INTEGER(IntKi), PARAMETER :: EddAmbT6N02D6 = 7107 + INTEGER(IntKi), PARAMETER :: EddAmbT6N02D7 = 7108 + INTEGER(IntKi), PARAMETER :: EddAmbT6N02D8 = 7109 + INTEGER(IntKi), PARAMETER :: EddAmbT6N02D9 = 7110 + INTEGER(IntKi), PARAMETER :: EddAmbT6N03D1 = 7111 + INTEGER(IntKi), PARAMETER :: EddAmbT6N03D2 = 7112 + INTEGER(IntKi), PARAMETER :: EddAmbT6N03D3 = 7113 + INTEGER(IntKi), PARAMETER :: EddAmbT6N03D4 = 7114 + INTEGER(IntKi), PARAMETER :: EddAmbT6N03D5 = 7115 + INTEGER(IntKi), PARAMETER :: EddAmbT6N03D6 = 7116 + INTEGER(IntKi), PARAMETER :: EddAmbT6N03D7 = 7117 + INTEGER(IntKi), PARAMETER :: EddAmbT6N03D8 = 7118 + INTEGER(IntKi), PARAMETER :: EddAmbT6N03D9 = 7119 + INTEGER(IntKi), PARAMETER :: EddAmbT6N04D1 = 7120 + INTEGER(IntKi), PARAMETER :: EddAmbT6N04D2 = 7121 + INTEGER(IntKi), PARAMETER :: EddAmbT6N04D3 = 7122 + INTEGER(IntKi), PARAMETER :: EddAmbT6N04D4 = 7123 + INTEGER(IntKi), PARAMETER :: EddAmbT6N04D5 = 7124 + INTEGER(IntKi), PARAMETER :: EddAmbT6N04D6 = 7125 + INTEGER(IntKi), PARAMETER :: EddAmbT6N04D7 = 7126 + INTEGER(IntKi), PARAMETER :: EddAmbT6N04D8 = 7127 + INTEGER(IntKi), PARAMETER :: EddAmbT6N04D9 = 7128 + INTEGER(IntKi), PARAMETER :: EddAmbT6N05D1 = 7129 + INTEGER(IntKi), PARAMETER :: EddAmbT6N05D2 = 7130 + INTEGER(IntKi), PARAMETER :: EddAmbT6N05D3 = 7131 + INTEGER(IntKi), PARAMETER :: EddAmbT6N05D4 = 7132 + INTEGER(IntKi), PARAMETER :: EddAmbT6N05D5 = 7133 + INTEGER(IntKi), PARAMETER :: EddAmbT6N05D6 = 7134 + INTEGER(IntKi), PARAMETER :: EddAmbT6N05D7 = 7135 + INTEGER(IntKi), PARAMETER :: EddAmbT6N05D8 = 7136 + INTEGER(IntKi), PARAMETER :: EddAmbT6N05D9 = 7137 + INTEGER(IntKi), PARAMETER :: EddAmbT6N06D1 = 7138 + INTEGER(IntKi), PARAMETER :: EddAmbT6N06D2 = 7139 + INTEGER(IntKi), PARAMETER :: EddAmbT6N06D3 = 7140 + INTEGER(IntKi), PARAMETER :: EddAmbT6N06D4 = 7141 + INTEGER(IntKi), PARAMETER :: EddAmbT6N06D5 = 7142 + INTEGER(IntKi), PARAMETER :: EddAmbT6N06D6 = 7143 + INTEGER(IntKi), PARAMETER :: EddAmbT6N06D7 = 7144 + INTEGER(IntKi), PARAMETER :: EddAmbT6N06D8 = 7145 + INTEGER(IntKi), PARAMETER :: EddAmbT6N06D9 = 7146 + INTEGER(IntKi), PARAMETER :: EddAmbT6N07D1 = 7147 + INTEGER(IntKi), PARAMETER :: EddAmbT6N07D2 = 7148 + INTEGER(IntKi), PARAMETER :: EddAmbT6N07D3 = 7149 + INTEGER(IntKi), PARAMETER :: EddAmbT6N07D4 = 7150 + INTEGER(IntKi), PARAMETER :: EddAmbT6N07D5 = 7151 + INTEGER(IntKi), PARAMETER :: EddAmbT6N07D6 = 7152 + INTEGER(IntKi), PARAMETER :: EddAmbT6N07D7 = 7153 + INTEGER(IntKi), PARAMETER :: EddAmbT6N07D8 = 7154 + INTEGER(IntKi), PARAMETER :: EddAmbT6N07D9 = 7155 + INTEGER(IntKi), PARAMETER :: EddAmbT6N08D1 = 7156 + INTEGER(IntKi), PARAMETER :: EddAmbT6N08D2 = 7157 + INTEGER(IntKi), PARAMETER :: EddAmbT6N08D3 = 7158 + INTEGER(IntKi), PARAMETER :: EddAmbT6N08D4 = 7159 + INTEGER(IntKi), PARAMETER :: EddAmbT6N08D5 = 7160 + INTEGER(IntKi), PARAMETER :: EddAmbT6N08D6 = 7161 + INTEGER(IntKi), PARAMETER :: EddAmbT6N08D7 = 7162 + INTEGER(IntKi), PARAMETER :: EddAmbT6N08D8 = 7163 + INTEGER(IntKi), PARAMETER :: EddAmbT6N08D9 = 7164 + INTEGER(IntKi), PARAMETER :: EddAmbT6N09D1 = 7165 + INTEGER(IntKi), PARAMETER :: EddAmbT6N09D2 = 7166 + INTEGER(IntKi), PARAMETER :: EddAmbT6N09D3 = 7167 + INTEGER(IntKi), PARAMETER :: EddAmbT6N09D4 = 7168 + INTEGER(IntKi), PARAMETER :: EddAmbT6N09D5 = 7169 + INTEGER(IntKi), PARAMETER :: EddAmbT6N09D6 = 7170 + INTEGER(IntKi), PARAMETER :: EddAmbT6N09D7 = 7171 + INTEGER(IntKi), PARAMETER :: EddAmbT6N09D8 = 7172 + INTEGER(IntKi), PARAMETER :: EddAmbT6N09D9 = 7173 + INTEGER(IntKi), PARAMETER :: EddAmbT6N10D1 = 7174 + INTEGER(IntKi), PARAMETER :: EddAmbT6N10D2 = 7175 + INTEGER(IntKi), PARAMETER :: EddAmbT6N10D3 = 7176 + INTEGER(IntKi), PARAMETER :: EddAmbT6N10D4 = 7177 + INTEGER(IntKi), PARAMETER :: EddAmbT6N10D5 = 7178 + INTEGER(IntKi), PARAMETER :: EddAmbT6N10D6 = 7179 + INTEGER(IntKi), PARAMETER :: EddAmbT6N10D7 = 7180 + INTEGER(IntKi), PARAMETER :: EddAmbT6N10D8 = 7181 + INTEGER(IntKi), PARAMETER :: EddAmbT6N10D9 = 7182 + INTEGER(IntKi), PARAMETER :: EddAmbT6N11D1 = 7183 + INTEGER(IntKi), PARAMETER :: EddAmbT6N11D2 = 7184 + INTEGER(IntKi), PARAMETER :: EddAmbT6N11D3 = 7185 + INTEGER(IntKi), PARAMETER :: EddAmbT6N11D4 = 7186 + INTEGER(IntKi), PARAMETER :: EddAmbT6N11D5 = 7187 + INTEGER(IntKi), PARAMETER :: EddAmbT6N11D6 = 7188 + INTEGER(IntKi), PARAMETER :: EddAmbT6N11D7 = 7189 + INTEGER(IntKi), PARAMETER :: EddAmbT6N11D8 = 7190 + INTEGER(IntKi), PARAMETER :: EddAmbT6N11D9 = 7191 + INTEGER(IntKi), PARAMETER :: EddAmbT6N12D1 = 7192 + INTEGER(IntKi), PARAMETER :: EddAmbT6N12D2 = 7193 + INTEGER(IntKi), PARAMETER :: EddAmbT6N12D3 = 7194 + INTEGER(IntKi), PARAMETER :: EddAmbT6N12D4 = 7195 + INTEGER(IntKi), PARAMETER :: EddAmbT6N12D5 = 7196 + INTEGER(IntKi), PARAMETER :: EddAmbT6N12D6 = 7197 + INTEGER(IntKi), PARAMETER :: EddAmbT6N12D7 = 7198 + INTEGER(IntKi), PARAMETER :: EddAmbT6N12D8 = 7199 + INTEGER(IntKi), PARAMETER :: EddAmbT6N12D9 = 7200 + INTEGER(IntKi), PARAMETER :: EddAmbT6N13D1 = 7201 + INTEGER(IntKi), PARAMETER :: EddAmbT6N13D2 = 7202 + INTEGER(IntKi), PARAMETER :: EddAmbT6N13D3 = 7203 + INTEGER(IntKi), PARAMETER :: EddAmbT6N13D4 = 7204 + INTEGER(IntKi), PARAMETER :: EddAmbT6N13D5 = 7205 + INTEGER(IntKi), PARAMETER :: EddAmbT6N13D6 = 7206 + INTEGER(IntKi), PARAMETER :: EddAmbT6N13D7 = 7207 + INTEGER(IntKi), PARAMETER :: EddAmbT6N13D8 = 7208 + INTEGER(IntKi), PARAMETER :: EddAmbT6N13D9 = 7209 + INTEGER(IntKi), PARAMETER :: EddAmbT6N14D1 = 7210 + INTEGER(IntKi), PARAMETER :: EddAmbT6N14D2 = 7211 + INTEGER(IntKi), PARAMETER :: EddAmbT6N14D3 = 7212 + INTEGER(IntKi), PARAMETER :: EddAmbT6N14D4 = 7213 + INTEGER(IntKi), PARAMETER :: EddAmbT6N14D5 = 7214 + INTEGER(IntKi), PARAMETER :: EddAmbT6N14D6 = 7215 + INTEGER(IntKi), PARAMETER :: EddAmbT6N14D7 = 7216 + INTEGER(IntKi), PARAMETER :: EddAmbT6N14D8 = 7217 + INTEGER(IntKi), PARAMETER :: EddAmbT6N14D9 = 7218 + INTEGER(IntKi), PARAMETER :: EddAmbT6N15D1 = 7219 + INTEGER(IntKi), PARAMETER :: EddAmbT6N15D2 = 7220 + INTEGER(IntKi), PARAMETER :: EddAmbT6N15D3 = 7221 + INTEGER(IntKi), PARAMETER :: EddAmbT6N15D4 = 7222 + INTEGER(IntKi), PARAMETER :: EddAmbT6N15D5 = 7223 + INTEGER(IntKi), PARAMETER :: EddAmbT6N15D6 = 7224 + INTEGER(IntKi), PARAMETER :: EddAmbT6N15D7 = 7225 + INTEGER(IntKi), PARAMETER :: EddAmbT6N15D8 = 7226 + INTEGER(IntKi), PARAMETER :: EddAmbT6N15D9 = 7227 + INTEGER(IntKi), PARAMETER :: EddAmbT6N16D1 = 7228 + INTEGER(IntKi), PARAMETER :: EddAmbT6N16D2 = 7229 + INTEGER(IntKi), PARAMETER :: EddAmbT6N16D3 = 7230 + INTEGER(IntKi), PARAMETER :: EddAmbT6N16D4 = 7231 + INTEGER(IntKi), PARAMETER :: EddAmbT6N16D5 = 7232 + INTEGER(IntKi), PARAMETER :: EddAmbT6N16D6 = 7233 + INTEGER(IntKi), PARAMETER :: EddAmbT6N16D7 = 7234 + INTEGER(IntKi), PARAMETER :: EddAmbT6N16D8 = 7235 + INTEGER(IntKi), PARAMETER :: EddAmbT6N16D9 = 7236 + INTEGER(IntKi), PARAMETER :: EddAmbT6N17D1 = 7237 + INTEGER(IntKi), PARAMETER :: EddAmbT6N17D2 = 7238 + INTEGER(IntKi), PARAMETER :: EddAmbT6N17D3 = 7239 + INTEGER(IntKi), PARAMETER :: EddAmbT6N17D4 = 7240 + INTEGER(IntKi), PARAMETER :: EddAmbT6N17D5 = 7241 + INTEGER(IntKi), PARAMETER :: EddAmbT6N17D6 = 7242 + INTEGER(IntKi), PARAMETER :: EddAmbT6N17D7 = 7243 + INTEGER(IntKi), PARAMETER :: EddAmbT6N17D8 = 7244 + INTEGER(IntKi), PARAMETER :: EddAmbT6N17D9 = 7245 + INTEGER(IntKi), PARAMETER :: EddAmbT6N18D1 = 7246 + INTEGER(IntKi), PARAMETER :: EddAmbT6N18D2 = 7247 + INTEGER(IntKi), PARAMETER :: EddAmbT6N18D3 = 7248 + INTEGER(IntKi), PARAMETER :: EddAmbT6N18D4 = 7249 + INTEGER(IntKi), PARAMETER :: EddAmbT6N18D5 = 7250 + INTEGER(IntKi), PARAMETER :: EddAmbT6N18D6 = 7251 + INTEGER(IntKi), PARAMETER :: EddAmbT6N18D7 = 7252 + INTEGER(IntKi), PARAMETER :: EddAmbT6N18D8 = 7253 + INTEGER(IntKi), PARAMETER :: EddAmbT6N18D9 = 7254 + INTEGER(IntKi), PARAMETER :: EddAmbT6N19D1 = 7255 + INTEGER(IntKi), PARAMETER :: EddAmbT6N19D2 = 7256 + INTEGER(IntKi), PARAMETER :: EddAmbT6N19D3 = 7257 + INTEGER(IntKi), PARAMETER :: EddAmbT6N19D4 = 7258 + INTEGER(IntKi), PARAMETER :: EddAmbT6N19D5 = 7259 + INTEGER(IntKi), PARAMETER :: EddAmbT6N19D6 = 7260 + INTEGER(IntKi), PARAMETER :: EddAmbT6N19D7 = 7261 + INTEGER(IntKi), PARAMETER :: EddAmbT6N19D8 = 7262 + INTEGER(IntKi), PARAMETER :: EddAmbT6N19D9 = 7263 + INTEGER(IntKi), PARAMETER :: EddAmbT6N20D1 = 7264 + INTEGER(IntKi), PARAMETER :: EddAmbT6N20D2 = 7265 + INTEGER(IntKi), PARAMETER :: EddAmbT6N20D3 = 7266 + INTEGER(IntKi), PARAMETER :: EddAmbT6N20D4 = 7267 + INTEGER(IntKi), PARAMETER :: EddAmbT6N20D5 = 7268 + INTEGER(IntKi), PARAMETER :: EddAmbT6N20D6 = 7269 + INTEGER(IntKi), PARAMETER :: EddAmbT6N20D7 = 7270 + INTEGER(IntKi), PARAMETER :: EddAmbT6N20D8 = 7271 + INTEGER(IntKi), PARAMETER :: EddAmbT6N20D9 = 7272 + INTEGER(IntKi), PARAMETER :: EddAmbT7N01D1 = 7273 + INTEGER(IntKi), PARAMETER :: EddAmbT7N01D2 = 7274 + INTEGER(IntKi), PARAMETER :: EddAmbT7N01D3 = 7275 + INTEGER(IntKi), PARAMETER :: EddAmbT7N01D4 = 7276 + INTEGER(IntKi), PARAMETER :: EddAmbT7N01D5 = 7277 + INTEGER(IntKi), PARAMETER :: EddAmbT7N01D6 = 7278 + INTEGER(IntKi), PARAMETER :: EddAmbT7N01D7 = 7279 + INTEGER(IntKi), PARAMETER :: EddAmbT7N01D8 = 7280 + INTEGER(IntKi), PARAMETER :: EddAmbT7N01D9 = 7281 + INTEGER(IntKi), PARAMETER :: EddAmbT7N02D1 = 7282 + INTEGER(IntKi), PARAMETER :: EddAmbT7N02D2 = 7283 + INTEGER(IntKi), PARAMETER :: EddAmbT7N02D3 = 7284 + INTEGER(IntKi), PARAMETER :: EddAmbT7N02D4 = 7285 + INTEGER(IntKi), PARAMETER :: EddAmbT7N02D5 = 7286 + INTEGER(IntKi), PARAMETER :: EddAmbT7N02D6 = 7287 + INTEGER(IntKi), PARAMETER :: EddAmbT7N02D7 = 7288 + INTEGER(IntKi), PARAMETER :: EddAmbT7N02D8 = 7289 + INTEGER(IntKi), PARAMETER :: EddAmbT7N02D9 = 7290 + INTEGER(IntKi), PARAMETER :: EddAmbT7N03D1 = 7291 + INTEGER(IntKi), PARAMETER :: EddAmbT7N03D2 = 7292 + INTEGER(IntKi), PARAMETER :: EddAmbT7N03D3 = 7293 + INTEGER(IntKi), PARAMETER :: EddAmbT7N03D4 = 7294 + INTEGER(IntKi), PARAMETER :: EddAmbT7N03D5 = 7295 + INTEGER(IntKi), PARAMETER :: EddAmbT7N03D6 = 7296 + INTEGER(IntKi), PARAMETER :: EddAmbT7N03D7 = 7297 + INTEGER(IntKi), PARAMETER :: EddAmbT7N03D8 = 7298 + INTEGER(IntKi), PARAMETER :: EddAmbT7N03D9 = 7299 + INTEGER(IntKi), PARAMETER :: EddAmbT7N04D1 = 7300 + INTEGER(IntKi), PARAMETER :: EddAmbT7N04D2 = 7301 + INTEGER(IntKi), PARAMETER :: EddAmbT7N04D3 = 7302 + INTEGER(IntKi), PARAMETER :: EddAmbT7N04D4 = 7303 + INTEGER(IntKi), PARAMETER :: EddAmbT7N04D5 = 7304 + INTEGER(IntKi), PARAMETER :: EddAmbT7N04D6 = 7305 + INTEGER(IntKi), PARAMETER :: EddAmbT7N04D7 = 7306 + INTEGER(IntKi), PARAMETER :: EddAmbT7N04D8 = 7307 + INTEGER(IntKi), PARAMETER :: EddAmbT7N04D9 = 7308 + INTEGER(IntKi), PARAMETER :: EddAmbT7N05D1 = 7309 + INTEGER(IntKi), PARAMETER :: EddAmbT7N05D2 = 7310 + INTEGER(IntKi), PARAMETER :: EddAmbT7N05D3 = 7311 + INTEGER(IntKi), PARAMETER :: EddAmbT7N05D4 = 7312 + INTEGER(IntKi), PARAMETER :: EddAmbT7N05D5 = 7313 + INTEGER(IntKi), PARAMETER :: EddAmbT7N05D6 = 7314 + INTEGER(IntKi), PARAMETER :: EddAmbT7N05D7 = 7315 + INTEGER(IntKi), PARAMETER :: EddAmbT7N05D8 = 7316 + INTEGER(IntKi), PARAMETER :: EddAmbT7N05D9 = 7317 + INTEGER(IntKi), PARAMETER :: EddAmbT7N06D1 = 7318 + INTEGER(IntKi), PARAMETER :: EddAmbT7N06D2 = 7319 + INTEGER(IntKi), PARAMETER :: EddAmbT7N06D3 = 7320 + INTEGER(IntKi), PARAMETER :: EddAmbT7N06D4 = 7321 + INTEGER(IntKi), PARAMETER :: EddAmbT7N06D5 = 7322 + INTEGER(IntKi), PARAMETER :: EddAmbT7N06D6 = 7323 + INTEGER(IntKi), PARAMETER :: EddAmbT7N06D7 = 7324 + INTEGER(IntKi), PARAMETER :: EddAmbT7N06D8 = 7325 + INTEGER(IntKi), PARAMETER :: EddAmbT7N06D9 = 7326 + INTEGER(IntKi), PARAMETER :: EddAmbT7N07D1 = 7327 + INTEGER(IntKi), PARAMETER :: EddAmbT7N07D2 = 7328 + INTEGER(IntKi), PARAMETER :: EddAmbT7N07D3 = 7329 + INTEGER(IntKi), PARAMETER :: EddAmbT7N07D4 = 7330 + INTEGER(IntKi), PARAMETER :: EddAmbT7N07D5 = 7331 + INTEGER(IntKi), PARAMETER :: EddAmbT7N07D6 = 7332 + INTEGER(IntKi), PARAMETER :: EddAmbT7N07D7 = 7333 + INTEGER(IntKi), PARAMETER :: EddAmbT7N07D8 = 7334 + INTEGER(IntKi), PARAMETER :: EddAmbT7N07D9 = 7335 + INTEGER(IntKi), PARAMETER :: EddAmbT7N08D1 = 7336 + INTEGER(IntKi), PARAMETER :: EddAmbT7N08D2 = 7337 + INTEGER(IntKi), PARAMETER :: EddAmbT7N08D3 = 7338 + INTEGER(IntKi), PARAMETER :: EddAmbT7N08D4 = 7339 + INTEGER(IntKi), PARAMETER :: EddAmbT7N08D5 = 7340 + INTEGER(IntKi), PARAMETER :: EddAmbT7N08D6 = 7341 + INTEGER(IntKi), PARAMETER :: EddAmbT7N08D7 = 7342 + INTEGER(IntKi), PARAMETER :: EddAmbT7N08D8 = 7343 + INTEGER(IntKi), PARAMETER :: EddAmbT7N08D9 = 7344 + INTEGER(IntKi), PARAMETER :: EddAmbT7N09D1 = 7345 + INTEGER(IntKi), PARAMETER :: EddAmbT7N09D2 = 7346 + INTEGER(IntKi), PARAMETER :: EddAmbT7N09D3 = 7347 + INTEGER(IntKi), PARAMETER :: EddAmbT7N09D4 = 7348 + INTEGER(IntKi), PARAMETER :: EddAmbT7N09D5 = 7349 + INTEGER(IntKi), PARAMETER :: EddAmbT7N09D6 = 7350 + INTEGER(IntKi), PARAMETER :: EddAmbT7N09D7 = 7351 + INTEGER(IntKi), PARAMETER :: EddAmbT7N09D8 = 7352 + INTEGER(IntKi), PARAMETER :: EddAmbT7N09D9 = 7353 + INTEGER(IntKi), PARAMETER :: EddAmbT7N10D1 = 7354 + INTEGER(IntKi), PARAMETER :: EddAmbT7N10D2 = 7355 + INTEGER(IntKi), PARAMETER :: EddAmbT7N10D3 = 7356 + INTEGER(IntKi), PARAMETER :: EddAmbT7N10D4 = 7357 + INTEGER(IntKi), PARAMETER :: EddAmbT7N10D5 = 7358 + INTEGER(IntKi), PARAMETER :: EddAmbT7N10D6 = 7359 + INTEGER(IntKi), PARAMETER :: EddAmbT7N10D7 = 7360 + INTEGER(IntKi), PARAMETER :: EddAmbT7N10D8 = 7361 + INTEGER(IntKi), PARAMETER :: EddAmbT7N10D9 = 7362 + INTEGER(IntKi), PARAMETER :: EddAmbT7N11D1 = 7363 + INTEGER(IntKi), PARAMETER :: EddAmbT7N11D2 = 7364 + INTEGER(IntKi), PARAMETER :: EddAmbT7N11D3 = 7365 + INTEGER(IntKi), PARAMETER :: EddAmbT7N11D4 = 7366 + INTEGER(IntKi), PARAMETER :: EddAmbT7N11D5 = 7367 + INTEGER(IntKi), PARAMETER :: EddAmbT7N11D6 = 7368 + INTEGER(IntKi), PARAMETER :: EddAmbT7N11D7 = 7369 + INTEGER(IntKi), PARAMETER :: EddAmbT7N11D8 = 7370 + INTEGER(IntKi), PARAMETER :: EddAmbT7N11D9 = 7371 + INTEGER(IntKi), PARAMETER :: EddAmbT7N12D1 = 7372 + INTEGER(IntKi), PARAMETER :: EddAmbT7N12D2 = 7373 + INTEGER(IntKi), PARAMETER :: EddAmbT7N12D3 = 7374 + INTEGER(IntKi), PARAMETER :: EddAmbT7N12D4 = 7375 + INTEGER(IntKi), PARAMETER :: EddAmbT7N12D5 = 7376 + INTEGER(IntKi), PARAMETER :: EddAmbT7N12D6 = 7377 + INTEGER(IntKi), PARAMETER :: EddAmbT7N12D7 = 7378 + INTEGER(IntKi), PARAMETER :: EddAmbT7N12D8 = 7379 + INTEGER(IntKi), PARAMETER :: EddAmbT7N12D9 = 7380 + INTEGER(IntKi), PARAMETER :: EddAmbT7N13D1 = 7381 + INTEGER(IntKi), PARAMETER :: EddAmbT7N13D2 = 7382 + INTEGER(IntKi), PARAMETER :: EddAmbT7N13D3 = 7383 + INTEGER(IntKi), PARAMETER :: EddAmbT7N13D4 = 7384 + INTEGER(IntKi), PARAMETER :: EddAmbT7N13D5 = 7385 + INTEGER(IntKi), PARAMETER :: EddAmbT7N13D6 = 7386 + INTEGER(IntKi), PARAMETER :: EddAmbT7N13D7 = 7387 + INTEGER(IntKi), PARAMETER :: EddAmbT7N13D8 = 7388 + INTEGER(IntKi), PARAMETER :: EddAmbT7N13D9 = 7389 + INTEGER(IntKi), PARAMETER :: EddAmbT7N14D1 = 7390 + INTEGER(IntKi), PARAMETER :: EddAmbT7N14D2 = 7391 + INTEGER(IntKi), PARAMETER :: EddAmbT7N14D3 = 7392 + INTEGER(IntKi), PARAMETER :: EddAmbT7N14D4 = 7393 + INTEGER(IntKi), PARAMETER :: EddAmbT7N14D5 = 7394 + INTEGER(IntKi), PARAMETER :: EddAmbT7N14D6 = 7395 + INTEGER(IntKi), PARAMETER :: EddAmbT7N14D7 = 7396 + INTEGER(IntKi), PARAMETER :: EddAmbT7N14D8 = 7397 + INTEGER(IntKi), PARAMETER :: EddAmbT7N14D9 = 7398 + INTEGER(IntKi), PARAMETER :: EddAmbT7N15D1 = 7399 + INTEGER(IntKi), PARAMETER :: EddAmbT7N15D2 = 7400 + INTEGER(IntKi), PARAMETER :: EddAmbT7N15D3 = 7401 + INTEGER(IntKi), PARAMETER :: EddAmbT7N15D4 = 7402 + INTEGER(IntKi), PARAMETER :: EddAmbT7N15D5 = 7403 + INTEGER(IntKi), PARAMETER :: EddAmbT7N15D6 = 7404 + INTEGER(IntKi), PARAMETER :: EddAmbT7N15D7 = 7405 + INTEGER(IntKi), PARAMETER :: EddAmbT7N15D8 = 7406 + INTEGER(IntKi), PARAMETER :: EddAmbT7N15D9 = 7407 + INTEGER(IntKi), PARAMETER :: EddAmbT7N16D1 = 7408 + INTEGER(IntKi), PARAMETER :: EddAmbT7N16D2 = 7409 + INTEGER(IntKi), PARAMETER :: EddAmbT7N16D3 = 7410 + INTEGER(IntKi), PARAMETER :: EddAmbT7N16D4 = 7411 + INTEGER(IntKi), PARAMETER :: EddAmbT7N16D5 = 7412 + INTEGER(IntKi), PARAMETER :: EddAmbT7N16D6 = 7413 + INTEGER(IntKi), PARAMETER :: EddAmbT7N16D7 = 7414 + INTEGER(IntKi), PARAMETER :: EddAmbT7N16D8 = 7415 + INTEGER(IntKi), PARAMETER :: EddAmbT7N16D9 = 7416 + INTEGER(IntKi), PARAMETER :: EddAmbT7N17D1 = 7417 + INTEGER(IntKi), PARAMETER :: EddAmbT7N17D2 = 7418 + INTEGER(IntKi), PARAMETER :: EddAmbT7N17D3 = 7419 + INTEGER(IntKi), PARAMETER :: EddAmbT7N17D4 = 7420 + INTEGER(IntKi), PARAMETER :: EddAmbT7N17D5 = 7421 + INTEGER(IntKi), PARAMETER :: EddAmbT7N17D6 = 7422 + INTEGER(IntKi), PARAMETER :: EddAmbT7N17D7 = 7423 + INTEGER(IntKi), PARAMETER :: EddAmbT7N17D8 = 7424 + INTEGER(IntKi), PARAMETER :: EddAmbT7N17D9 = 7425 + INTEGER(IntKi), PARAMETER :: EddAmbT7N18D1 = 7426 + INTEGER(IntKi), PARAMETER :: EddAmbT7N18D2 = 7427 + INTEGER(IntKi), PARAMETER :: EddAmbT7N18D3 = 7428 + INTEGER(IntKi), PARAMETER :: EddAmbT7N18D4 = 7429 + INTEGER(IntKi), PARAMETER :: EddAmbT7N18D5 = 7430 + INTEGER(IntKi), PARAMETER :: EddAmbT7N18D6 = 7431 + INTEGER(IntKi), PARAMETER :: EddAmbT7N18D7 = 7432 + INTEGER(IntKi), PARAMETER :: EddAmbT7N18D8 = 7433 + INTEGER(IntKi), PARAMETER :: EddAmbT7N18D9 = 7434 + INTEGER(IntKi), PARAMETER :: EddAmbT7N19D1 = 7435 + INTEGER(IntKi), PARAMETER :: EddAmbT7N19D2 = 7436 + INTEGER(IntKi), PARAMETER :: EddAmbT7N19D3 = 7437 + INTEGER(IntKi), PARAMETER :: EddAmbT7N19D4 = 7438 + INTEGER(IntKi), PARAMETER :: EddAmbT7N19D5 = 7439 + INTEGER(IntKi), PARAMETER :: EddAmbT7N19D6 = 7440 + INTEGER(IntKi), PARAMETER :: EddAmbT7N19D7 = 7441 + INTEGER(IntKi), PARAMETER :: EddAmbT7N19D8 = 7442 + INTEGER(IntKi), PARAMETER :: EddAmbT7N19D9 = 7443 + INTEGER(IntKi), PARAMETER :: EddAmbT7N20D1 = 7444 + INTEGER(IntKi), PARAMETER :: EddAmbT7N20D2 = 7445 + INTEGER(IntKi), PARAMETER :: EddAmbT7N20D3 = 7446 + INTEGER(IntKi), PARAMETER :: EddAmbT7N20D4 = 7447 + INTEGER(IntKi), PARAMETER :: EddAmbT7N20D5 = 7448 + INTEGER(IntKi), PARAMETER :: EddAmbT7N20D6 = 7449 + INTEGER(IntKi), PARAMETER :: EddAmbT7N20D7 = 7450 + INTEGER(IntKi), PARAMETER :: EddAmbT7N20D8 = 7451 + INTEGER(IntKi), PARAMETER :: EddAmbT7N20D9 = 7452 + INTEGER(IntKi), PARAMETER :: EddAmbT8N01D1 = 7453 + INTEGER(IntKi), PARAMETER :: EddAmbT8N01D2 = 7454 + INTEGER(IntKi), PARAMETER :: EddAmbT8N01D3 = 7455 + INTEGER(IntKi), PARAMETER :: EddAmbT8N01D4 = 7456 + INTEGER(IntKi), PARAMETER :: EddAmbT8N01D5 = 7457 + INTEGER(IntKi), PARAMETER :: EddAmbT8N01D6 = 7458 + INTEGER(IntKi), PARAMETER :: EddAmbT8N01D7 = 7459 + INTEGER(IntKi), PARAMETER :: EddAmbT8N01D8 = 7460 + INTEGER(IntKi), PARAMETER :: EddAmbT8N01D9 = 7461 + INTEGER(IntKi), PARAMETER :: EddAmbT8N02D1 = 7462 + INTEGER(IntKi), PARAMETER :: EddAmbT8N02D2 = 7463 + INTEGER(IntKi), PARAMETER :: EddAmbT8N02D3 = 7464 + INTEGER(IntKi), PARAMETER :: EddAmbT8N02D4 = 7465 + INTEGER(IntKi), PARAMETER :: EddAmbT8N02D5 = 7466 + INTEGER(IntKi), PARAMETER :: EddAmbT8N02D6 = 7467 + INTEGER(IntKi), PARAMETER :: EddAmbT8N02D7 = 7468 + INTEGER(IntKi), PARAMETER :: EddAmbT8N02D8 = 7469 + INTEGER(IntKi), PARAMETER :: EddAmbT8N02D9 = 7470 + INTEGER(IntKi), PARAMETER :: EddAmbT8N03D1 = 7471 + INTEGER(IntKi), PARAMETER :: EddAmbT8N03D2 = 7472 + INTEGER(IntKi), PARAMETER :: EddAmbT8N03D3 = 7473 + INTEGER(IntKi), PARAMETER :: EddAmbT8N03D4 = 7474 + INTEGER(IntKi), PARAMETER :: EddAmbT8N03D5 = 7475 + INTEGER(IntKi), PARAMETER :: EddAmbT8N03D6 = 7476 + INTEGER(IntKi), PARAMETER :: EddAmbT8N03D7 = 7477 + INTEGER(IntKi), PARAMETER :: EddAmbT8N03D8 = 7478 + INTEGER(IntKi), PARAMETER :: EddAmbT8N03D9 = 7479 + INTEGER(IntKi), PARAMETER :: EddAmbT8N04D1 = 7480 + INTEGER(IntKi), PARAMETER :: EddAmbT8N04D2 = 7481 + INTEGER(IntKi), PARAMETER :: EddAmbT8N04D3 = 7482 + INTEGER(IntKi), PARAMETER :: EddAmbT8N04D4 = 7483 + INTEGER(IntKi), PARAMETER :: EddAmbT8N04D5 = 7484 + INTEGER(IntKi), PARAMETER :: EddAmbT8N04D6 = 7485 + INTEGER(IntKi), PARAMETER :: EddAmbT8N04D7 = 7486 + INTEGER(IntKi), PARAMETER :: EddAmbT8N04D8 = 7487 + INTEGER(IntKi), PARAMETER :: EddAmbT8N04D9 = 7488 + INTEGER(IntKi), PARAMETER :: EddAmbT8N05D1 = 7489 + INTEGER(IntKi), PARAMETER :: EddAmbT8N05D2 = 7490 + INTEGER(IntKi), PARAMETER :: EddAmbT8N05D3 = 7491 + INTEGER(IntKi), PARAMETER :: EddAmbT8N05D4 = 7492 + INTEGER(IntKi), PARAMETER :: EddAmbT8N05D5 = 7493 + INTEGER(IntKi), PARAMETER :: EddAmbT8N05D6 = 7494 + INTEGER(IntKi), PARAMETER :: EddAmbT8N05D7 = 7495 + INTEGER(IntKi), PARAMETER :: EddAmbT8N05D8 = 7496 + INTEGER(IntKi), PARAMETER :: EddAmbT8N05D9 = 7497 + INTEGER(IntKi), PARAMETER :: EddAmbT8N06D1 = 7498 + INTEGER(IntKi), PARAMETER :: EddAmbT8N06D2 = 7499 + INTEGER(IntKi), PARAMETER :: EddAmbT8N06D3 = 7500 + INTEGER(IntKi), PARAMETER :: EddAmbT8N06D4 = 7501 + INTEGER(IntKi), PARAMETER :: EddAmbT8N06D5 = 7502 + INTEGER(IntKi), PARAMETER :: EddAmbT8N06D6 = 7503 + INTEGER(IntKi), PARAMETER :: EddAmbT8N06D7 = 7504 + INTEGER(IntKi), PARAMETER :: EddAmbT8N06D8 = 7505 + INTEGER(IntKi), PARAMETER :: EddAmbT8N06D9 = 7506 + INTEGER(IntKi), PARAMETER :: EddAmbT8N07D1 = 7507 + INTEGER(IntKi), PARAMETER :: EddAmbT8N07D2 = 7508 + INTEGER(IntKi), PARAMETER :: EddAmbT8N07D3 = 7509 + INTEGER(IntKi), PARAMETER :: EddAmbT8N07D4 = 7510 + INTEGER(IntKi), PARAMETER :: EddAmbT8N07D5 = 7511 + INTEGER(IntKi), PARAMETER :: EddAmbT8N07D6 = 7512 + INTEGER(IntKi), PARAMETER :: EddAmbT8N07D7 = 7513 + INTEGER(IntKi), PARAMETER :: EddAmbT8N07D8 = 7514 + INTEGER(IntKi), PARAMETER :: EddAmbT8N07D9 = 7515 + INTEGER(IntKi), PARAMETER :: EddAmbT8N08D1 = 7516 + INTEGER(IntKi), PARAMETER :: EddAmbT8N08D2 = 7517 + INTEGER(IntKi), PARAMETER :: EddAmbT8N08D3 = 7518 + INTEGER(IntKi), PARAMETER :: EddAmbT8N08D4 = 7519 + INTEGER(IntKi), PARAMETER :: EddAmbT8N08D5 = 7520 + INTEGER(IntKi), PARAMETER :: EddAmbT8N08D6 = 7521 + INTEGER(IntKi), PARAMETER :: EddAmbT8N08D7 = 7522 + INTEGER(IntKi), PARAMETER :: EddAmbT8N08D8 = 7523 + INTEGER(IntKi), PARAMETER :: EddAmbT8N08D9 = 7524 + INTEGER(IntKi), PARAMETER :: EddAmbT8N09D1 = 7525 + INTEGER(IntKi), PARAMETER :: EddAmbT8N09D2 = 7526 + INTEGER(IntKi), PARAMETER :: EddAmbT8N09D3 = 7527 + INTEGER(IntKi), PARAMETER :: EddAmbT8N09D4 = 7528 + INTEGER(IntKi), PARAMETER :: EddAmbT8N09D5 = 7529 + INTEGER(IntKi), PARAMETER :: EddAmbT8N09D6 = 7530 + INTEGER(IntKi), PARAMETER :: EddAmbT8N09D7 = 7531 + INTEGER(IntKi), PARAMETER :: EddAmbT8N09D8 = 7532 + INTEGER(IntKi), PARAMETER :: EddAmbT8N09D9 = 7533 + INTEGER(IntKi), PARAMETER :: EddAmbT8N10D1 = 7534 + INTEGER(IntKi), PARAMETER :: EddAmbT8N10D2 = 7535 + INTEGER(IntKi), PARAMETER :: EddAmbT8N10D3 = 7536 + INTEGER(IntKi), PARAMETER :: EddAmbT8N10D4 = 7537 + INTEGER(IntKi), PARAMETER :: EddAmbT8N10D5 = 7538 + INTEGER(IntKi), PARAMETER :: EddAmbT8N10D6 = 7539 + INTEGER(IntKi), PARAMETER :: EddAmbT8N10D7 = 7540 + INTEGER(IntKi), PARAMETER :: EddAmbT8N10D8 = 7541 + INTEGER(IntKi), PARAMETER :: EddAmbT8N10D9 = 7542 + INTEGER(IntKi), PARAMETER :: EddAmbT8N11D1 = 7543 + INTEGER(IntKi), PARAMETER :: EddAmbT8N11D2 = 7544 + INTEGER(IntKi), PARAMETER :: EddAmbT8N11D3 = 7545 + INTEGER(IntKi), PARAMETER :: EddAmbT8N11D4 = 7546 + INTEGER(IntKi), PARAMETER :: EddAmbT8N11D5 = 7547 + INTEGER(IntKi), PARAMETER :: EddAmbT8N11D6 = 7548 + INTEGER(IntKi), PARAMETER :: EddAmbT8N11D7 = 7549 + INTEGER(IntKi), PARAMETER :: EddAmbT8N11D8 = 7550 + INTEGER(IntKi), PARAMETER :: EddAmbT8N11D9 = 7551 + INTEGER(IntKi), PARAMETER :: EddAmbT8N12D1 = 7552 + INTEGER(IntKi), PARAMETER :: EddAmbT8N12D2 = 7553 + INTEGER(IntKi), PARAMETER :: EddAmbT8N12D3 = 7554 + INTEGER(IntKi), PARAMETER :: EddAmbT8N12D4 = 7555 + INTEGER(IntKi), PARAMETER :: EddAmbT8N12D5 = 7556 + INTEGER(IntKi), PARAMETER :: EddAmbT8N12D6 = 7557 + INTEGER(IntKi), PARAMETER :: EddAmbT8N12D7 = 7558 + INTEGER(IntKi), PARAMETER :: EddAmbT8N12D8 = 7559 + INTEGER(IntKi), PARAMETER :: EddAmbT8N12D9 = 7560 + INTEGER(IntKi), PARAMETER :: EddAmbT8N13D1 = 7561 + INTEGER(IntKi), PARAMETER :: EddAmbT8N13D2 = 7562 + INTEGER(IntKi), PARAMETER :: EddAmbT8N13D3 = 7563 + INTEGER(IntKi), PARAMETER :: EddAmbT8N13D4 = 7564 + INTEGER(IntKi), PARAMETER :: EddAmbT8N13D5 = 7565 + INTEGER(IntKi), PARAMETER :: EddAmbT8N13D6 = 7566 + INTEGER(IntKi), PARAMETER :: EddAmbT8N13D7 = 7567 + INTEGER(IntKi), PARAMETER :: EddAmbT8N13D8 = 7568 + INTEGER(IntKi), PARAMETER :: EddAmbT8N13D9 = 7569 + INTEGER(IntKi), PARAMETER :: EddAmbT8N14D1 = 7570 + INTEGER(IntKi), PARAMETER :: EddAmbT8N14D2 = 7571 + INTEGER(IntKi), PARAMETER :: EddAmbT8N14D3 = 7572 + INTEGER(IntKi), PARAMETER :: EddAmbT8N14D4 = 7573 + INTEGER(IntKi), PARAMETER :: EddAmbT8N14D5 = 7574 + INTEGER(IntKi), PARAMETER :: EddAmbT8N14D6 = 7575 + INTEGER(IntKi), PARAMETER :: EddAmbT8N14D7 = 7576 + INTEGER(IntKi), PARAMETER :: EddAmbT8N14D8 = 7577 + INTEGER(IntKi), PARAMETER :: EddAmbT8N14D9 = 7578 + INTEGER(IntKi), PARAMETER :: EddAmbT8N15D1 = 7579 + INTEGER(IntKi), PARAMETER :: EddAmbT8N15D2 = 7580 + INTEGER(IntKi), PARAMETER :: EddAmbT8N15D3 = 7581 + INTEGER(IntKi), PARAMETER :: EddAmbT8N15D4 = 7582 + INTEGER(IntKi), PARAMETER :: EddAmbT8N15D5 = 7583 + INTEGER(IntKi), PARAMETER :: EddAmbT8N15D6 = 7584 + INTEGER(IntKi), PARAMETER :: EddAmbT8N15D7 = 7585 + INTEGER(IntKi), PARAMETER :: EddAmbT8N15D8 = 7586 + INTEGER(IntKi), PARAMETER :: EddAmbT8N15D9 = 7587 + INTEGER(IntKi), PARAMETER :: EddAmbT8N16D1 = 7588 + INTEGER(IntKi), PARAMETER :: EddAmbT8N16D2 = 7589 + INTEGER(IntKi), PARAMETER :: EddAmbT8N16D3 = 7590 + INTEGER(IntKi), PARAMETER :: EddAmbT8N16D4 = 7591 + INTEGER(IntKi), PARAMETER :: EddAmbT8N16D5 = 7592 + INTEGER(IntKi), PARAMETER :: EddAmbT8N16D6 = 7593 + INTEGER(IntKi), PARAMETER :: EddAmbT8N16D7 = 7594 + INTEGER(IntKi), PARAMETER :: EddAmbT8N16D8 = 7595 + INTEGER(IntKi), PARAMETER :: EddAmbT8N16D9 = 7596 + INTEGER(IntKi), PARAMETER :: EddAmbT8N17D1 = 7597 + INTEGER(IntKi), PARAMETER :: EddAmbT8N17D2 = 7598 + INTEGER(IntKi), PARAMETER :: EddAmbT8N17D3 = 7599 + INTEGER(IntKi), PARAMETER :: EddAmbT8N17D4 = 7600 + INTEGER(IntKi), PARAMETER :: EddAmbT8N17D5 = 7601 + INTEGER(IntKi), PARAMETER :: EddAmbT8N17D6 = 7602 + INTEGER(IntKi), PARAMETER :: EddAmbT8N17D7 = 7603 + INTEGER(IntKi), PARAMETER :: EddAmbT8N17D8 = 7604 + INTEGER(IntKi), PARAMETER :: EddAmbT8N17D9 = 7605 + INTEGER(IntKi), PARAMETER :: EddAmbT8N18D1 = 7606 + INTEGER(IntKi), PARAMETER :: EddAmbT8N18D2 = 7607 + INTEGER(IntKi), PARAMETER :: EddAmbT8N18D3 = 7608 + INTEGER(IntKi), PARAMETER :: EddAmbT8N18D4 = 7609 + INTEGER(IntKi), PARAMETER :: EddAmbT8N18D5 = 7610 + INTEGER(IntKi), PARAMETER :: EddAmbT8N18D6 = 7611 + INTEGER(IntKi), PARAMETER :: EddAmbT8N18D7 = 7612 + INTEGER(IntKi), PARAMETER :: EddAmbT8N18D8 = 7613 + INTEGER(IntKi), PARAMETER :: EddAmbT8N18D9 = 7614 + INTEGER(IntKi), PARAMETER :: EddAmbT8N19D1 = 7615 + INTEGER(IntKi), PARAMETER :: EddAmbT8N19D2 = 7616 + INTEGER(IntKi), PARAMETER :: EddAmbT8N19D3 = 7617 + INTEGER(IntKi), PARAMETER :: EddAmbT8N19D4 = 7618 + INTEGER(IntKi), PARAMETER :: EddAmbT8N19D5 = 7619 + INTEGER(IntKi), PARAMETER :: EddAmbT8N19D6 = 7620 + INTEGER(IntKi), PARAMETER :: EddAmbT8N19D7 = 7621 + INTEGER(IntKi), PARAMETER :: EddAmbT8N19D8 = 7622 + INTEGER(IntKi), PARAMETER :: EddAmbT8N19D9 = 7623 + INTEGER(IntKi), PARAMETER :: EddAmbT8N20D1 = 7624 + INTEGER(IntKi), PARAMETER :: EddAmbT8N20D2 = 7625 + INTEGER(IntKi), PARAMETER :: EddAmbT8N20D3 = 7626 + INTEGER(IntKi), PARAMETER :: EddAmbT8N20D4 = 7627 + INTEGER(IntKi), PARAMETER :: EddAmbT8N20D5 = 7628 + INTEGER(IntKi), PARAMETER :: EddAmbT8N20D6 = 7629 + INTEGER(IntKi), PARAMETER :: EddAmbT8N20D7 = 7630 + INTEGER(IntKi), PARAMETER :: EddAmbT8N20D8 = 7631 + INTEGER(IntKi), PARAMETER :: EddAmbT8N20D9 = 7632 + INTEGER(IntKi), PARAMETER :: EddAmbT9N01D1 = 7633 + INTEGER(IntKi), PARAMETER :: EddAmbT9N01D2 = 7634 + INTEGER(IntKi), PARAMETER :: EddAmbT9N01D3 = 7635 + INTEGER(IntKi), PARAMETER :: EddAmbT9N01D4 = 7636 + INTEGER(IntKi), PARAMETER :: EddAmbT9N01D5 = 7637 + INTEGER(IntKi), PARAMETER :: EddAmbT9N01D6 = 7638 + INTEGER(IntKi), PARAMETER :: EddAmbT9N01D7 = 7639 + INTEGER(IntKi), PARAMETER :: EddAmbT9N01D8 = 7640 + INTEGER(IntKi), PARAMETER :: EddAmbT9N01D9 = 7641 + INTEGER(IntKi), PARAMETER :: EddAmbT9N02D1 = 7642 + INTEGER(IntKi), PARAMETER :: EddAmbT9N02D2 = 7643 + INTEGER(IntKi), PARAMETER :: EddAmbT9N02D3 = 7644 + INTEGER(IntKi), PARAMETER :: EddAmbT9N02D4 = 7645 + INTEGER(IntKi), PARAMETER :: EddAmbT9N02D5 = 7646 + INTEGER(IntKi), PARAMETER :: EddAmbT9N02D6 = 7647 + INTEGER(IntKi), PARAMETER :: EddAmbT9N02D7 = 7648 + INTEGER(IntKi), PARAMETER :: EddAmbT9N02D8 = 7649 + INTEGER(IntKi), PARAMETER :: EddAmbT9N02D9 = 7650 + INTEGER(IntKi), PARAMETER :: EddAmbT9N03D1 = 7651 + INTEGER(IntKi), PARAMETER :: EddAmbT9N03D2 = 7652 + INTEGER(IntKi), PARAMETER :: EddAmbT9N03D3 = 7653 + INTEGER(IntKi), PARAMETER :: EddAmbT9N03D4 = 7654 + INTEGER(IntKi), PARAMETER :: EddAmbT9N03D5 = 7655 + INTEGER(IntKi), PARAMETER :: EddAmbT9N03D6 = 7656 + INTEGER(IntKi), PARAMETER :: EddAmbT9N03D7 = 7657 + INTEGER(IntKi), PARAMETER :: EddAmbT9N03D8 = 7658 + INTEGER(IntKi), PARAMETER :: EddAmbT9N03D9 = 7659 + INTEGER(IntKi), PARAMETER :: EddAmbT9N04D1 = 7660 + INTEGER(IntKi), PARAMETER :: EddAmbT9N04D2 = 7661 + INTEGER(IntKi), PARAMETER :: EddAmbT9N04D3 = 7662 + INTEGER(IntKi), PARAMETER :: EddAmbT9N04D4 = 7663 + INTEGER(IntKi), PARAMETER :: EddAmbT9N04D5 = 7664 + INTEGER(IntKi), PARAMETER :: EddAmbT9N04D6 = 7665 + INTEGER(IntKi), PARAMETER :: EddAmbT9N04D7 = 7666 + INTEGER(IntKi), PARAMETER :: EddAmbT9N04D8 = 7667 + INTEGER(IntKi), PARAMETER :: EddAmbT9N04D9 = 7668 + INTEGER(IntKi), PARAMETER :: EddAmbT9N05D1 = 7669 + INTEGER(IntKi), PARAMETER :: EddAmbT9N05D2 = 7670 + INTEGER(IntKi), PARAMETER :: EddAmbT9N05D3 = 7671 + INTEGER(IntKi), PARAMETER :: EddAmbT9N05D4 = 7672 + INTEGER(IntKi), PARAMETER :: EddAmbT9N05D5 = 7673 + INTEGER(IntKi), PARAMETER :: EddAmbT9N05D6 = 7674 + INTEGER(IntKi), PARAMETER :: EddAmbT9N05D7 = 7675 + INTEGER(IntKi), PARAMETER :: EddAmbT9N05D8 = 7676 + INTEGER(IntKi), PARAMETER :: EddAmbT9N05D9 = 7677 + INTEGER(IntKi), PARAMETER :: EddAmbT9N06D1 = 7678 + INTEGER(IntKi), PARAMETER :: EddAmbT9N06D2 = 7679 + INTEGER(IntKi), PARAMETER :: EddAmbT9N06D3 = 7680 + INTEGER(IntKi), PARAMETER :: EddAmbT9N06D4 = 7681 + INTEGER(IntKi), PARAMETER :: EddAmbT9N06D5 = 7682 + INTEGER(IntKi), PARAMETER :: EddAmbT9N06D6 = 7683 + INTEGER(IntKi), PARAMETER :: EddAmbT9N06D7 = 7684 + INTEGER(IntKi), PARAMETER :: EddAmbT9N06D8 = 7685 + INTEGER(IntKi), PARAMETER :: EddAmbT9N06D9 = 7686 + INTEGER(IntKi), PARAMETER :: EddAmbT9N07D1 = 7687 + INTEGER(IntKi), PARAMETER :: EddAmbT9N07D2 = 7688 + INTEGER(IntKi), PARAMETER :: EddAmbT9N07D3 = 7689 + INTEGER(IntKi), PARAMETER :: EddAmbT9N07D4 = 7690 + INTEGER(IntKi), PARAMETER :: EddAmbT9N07D5 = 7691 + INTEGER(IntKi), PARAMETER :: EddAmbT9N07D6 = 7692 + INTEGER(IntKi), PARAMETER :: EddAmbT9N07D7 = 7693 + INTEGER(IntKi), PARAMETER :: EddAmbT9N07D8 = 7694 + INTEGER(IntKi), PARAMETER :: EddAmbT9N07D9 = 7695 + INTEGER(IntKi), PARAMETER :: EddAmbT9N08D1 = 7696 + INTEGER(IntKi), PARAMETER :: EddAmbT9N08D2 = 7697 + INTEGER(IntKi), PARAMETER :: EddAmbT9N08D3 = 7698 + INTEGER(IntKi), PARAMETER :: EddAmbT9N08D4 = 7699 + INTEGER(IntKi), PARAMETER :: EddAmbT9N08D5 = 7700 + INTEGER(IntKi), PARAMETER :: EddAmbT9N08D6 = 7701 + INTEGER(IntKi), PARAMETER :: EddAmbT9N08D7 = 7702 + INTEGER(IntKi), PARAMETER :: EddAmbT9N08D8 = 7703 + INTEGER(IntKi), PARAMETER :: EddAmbT9N08D9 = 7704 + INTEGER(IntKi), PARAMETER :: EddAmbT9N09D1 = 7705 + INTEGER(IntKi), PARAMETER :: EddAmbT9N09D2 = 7706 + INTEGER(IntKi), PARAMETER :: EddAmbT9N09D3 = 7707 + INTEGER(IntKi), PARAMETER :: EddAmbT9N09D4 = 7708 + INTEGER(IntKi), PARAMETER :: EddAmbT9N09D5 = 7709 + INTEGER(IntKi), PARAMETER :: EddAmbT9N09D6 = 7710 + INTEGER(IntKi), PARAMETER :: EddAmbT9N09D7 = 7711 + INTEGER(IntKi), PARAMETER :: EddAmbT9N09D8 = 7712 + INTEGER(IntKi), PARAMETER :: EddAmbT9N09D9 = 7713 + INTEGER(IntKi), PARAMETER :: EddAmbT9N10D1 = 7714 + INTEGER(IntKi), PARAMETER :: EddAmbT9N10D2 = 7715 + INTEGER(IntKi), PARAMETER :: EddAmbT9N10D3 = 7716 + INTEGER(IntKi), PARAMETER :: EddAmbT9N10D4 = 7717 + INTEGER(IntKi), PARAMETER :: EddAmbT9N10D5 = 7718 + INTEGER(IntKi), PARAMETER :: EddAmbT9N10D6 = 7719 + INTEGER(IntKi), PARAMETER :: EddAmbT9N10D7 = 7720 + INTEGER(IntKi), PARAMETER :: EddAmbT9N10D8 = 7721 + INTEGER(IntKi), PARAMETER :: EddAmbT9N10D9 = 7722 + INTEGER(IntKi), PARAMETER :: EddAmbT9N11D1 = 7723 + INTEGER(IntKi), PARAMETER :: EddAmbT9N11D2 = 7724 + INTEGER(IntKi), PARAMETER :: EddAmbT9N11D3 = 7725 + INTEGER(IntKi), PARAMETER :: EddAmbT9N11D4 = 7726 + INTEGER(IntKi), PARAMETER :: EddAmbT9N11D5 = 7727 + INTEGER(IntKi), PARAMETER :: EddAmbT9N11D6 = 7728 + INTEGER(IntKi), PARAMETER :: EddAmbT9N11D7 = 7729 + INTEGER(IntKi), PARAMETER :: EddAmbT9N11D8 = 7730 + INTEGER(IntKi), PARAMETER :: EddAmbT9N11D9 = 7731 + INTEGER(IntKi), PARAMETER :: EddAmbT9N12D1 = 7732 + INTEGER(IntKi), PARAMETER :: EddAmbT9N12D2 = 7733 + INTEGER(IntKi), PARAMETER :: EddAmbT9N12D3 = 7734 + INTEGER(IntKi), PARAMETER :: EddAmbT9N12D4 = 7735 + INTEGER(IntKi), PARAMETER :: EddAmbT9N12D5 = 7736 + INTEGER(IntKi), PARAMETER :: EddAmbT9N12D6 = 7737 + INTEGER(IntKi), PARAMETER :: EddAmbT9N12D7 = 7738 + INTEGER(IntKi), PARAMETER :: EddAmbT9N12D8 = 7739 + INTEGER(IntKi), PARAMETER :: EddAmbT9N12D9 = 7740 + INTEGER(IntKi), PARAMETER :: EddAmbT9N13D1 = 7741 + INTEGER(IntKi), PARAMETER :: EddAmbT9N13D2 = 7742 + INTEGER(IntKi), PARAMETER :: EddAmbT9N13D3 = 7743 + INTEGER(IntKi), PARAMETER :: EddAmbT9N13D4 = 7744 + INTEGER(IntKi), PARAMETER :: EddAmbT9N13D5 = 7745 + INTEGER(IntKi), PARAMETER :: EddAmbT9N13D6 = 7746 + INTEGER(IntKi), PARAMETER :: EddAmbT9N13D7 = 7747 + INTEGER(IntKi), PARAMETER :: EddAmbT9N13D8 = 7748 + INTEGER(IntKi), PARAMETER :: EddAmbT9N13D9 = 7749 + INTEGER(IntKi), PARAMETER :: EddAmbT9N14D1 = 7750 + INTEGER(IntKi), PARAMETER :: EddAmbT9N14D2 = 7751 + INTEGER(IntKi), PARAMETER :: EddAmbT9N14D3 = 7752 + INTEGER(IntKi), PARAMETER :: EddAmbT9N14D4 = 7753 + INTEGER(IntKi), PARAMETER :: EddAmbT9N14D5 = 7754 + INTEGER(IntKi), PARAMETER :: EddAmbT9N14D6 = 7755 + INTEGER(IntKi), PARAMETER :: EddAmbT9N14D7 = 7756 + INTEGER(IntKi), PARAMETER :: EddAmbT9N14D8 = 7757 + INTEGER(IntKi), PARAMETER :: EddAmbT9N14D9 = 7758 + INTEGER(IntKi), PARAMETER :: EddAmbT9N15D1 = 7759 + INTEGER(IntKi), PARAMETER :: EddAmbT9N15D2 = 7760 + INTEGER(IntKi), PARAMETER :: EddAmbT9N15D3 = 7761 + INTEGER(IntKi), PARAMETER :: EddAmbT9N15D4 = 7762 + INTEGER(IntKi), PARAMETER :: EddAmbT9N15D5 = 7763 + INTEGER(IntKi), PARAMETER :: EddAmbT9N15D6 = 7764 + INTEGER(IntKi), PARAMETER :: EddAmbT9N15D7 = 7765 + INTEGER(IntKi), PARAMETER :: EddAmbT9N15D8 = 7766 + INTEGER(IntKi), PARAMETER :: EddAmbT9N15D9 = 7767 + INTEGER(IntKi), PARAMETER :: EddAmbT9N16D1 = 7768 + INTEGER(IntKi), PARAMETER :: EddAmbT9N16D2 = 7769 + INTEGER(IntKi), PARAMETER :: EddAmbT9N16D3 = 7770 + INTEGER(IntKi), PARAMETER :: EddAmbT9N16D4 = 7771 + INTEGER(IntKi), PARAMETER :: EddAmbT9N16D5 = 7772 + INTEGER(IntKi), PARAMETER :: EddAmbT9N16D6 = 7773 + INTEGER(IntKi), PARAMETER :: EddAmbT9N16D7 = 7774 + INTEGER(IntKi), PARAMETER :: EddAmbT9N16D8 = 7775 + INTEGER(IntKi), PARAMETER :: EddAmbT9N16D9 = 7776 + INTEGER(IntKi), PARAMETER :: EddAmbT9N17D1 = 7777 + INTEGER(IntKi), PARAMETER :: EddAmbT9N17D2 = 7778 + INTEGER(IntKi), PARAMETER :: EddAmbT9N17D3 = 7779 + INTEGER(IntKi), PARAMETER :: EddAmbT9N17D4 = 7780 + INTEGER(IntKi), PARAMETER :: EddAmbT9N17D5 = 7781 + INTEGER(IntKi), PARAMETER :: EddAmbT9N17D6 = 7782 + INTEGER(IntKi), PARAMETER :: EddAmbT9N17D7 = 7783 + INTEGER(IntKi), PARAMETER :: EddAmbT9N17D8 = 7784 + INTEGER(IntKi), PARAMETER :: EddAmbT9N17D9 = 7785 + INTEGER(IntKi), PARAMETER :: EddAmbT9N18D1 = 7786 + INTEGER(IntKi), PARAMETER :: EddAmbT9N18D2 = 7787 + INTEGER(IntKi), PARAMETER :: EddAmbT9N18D3 = 7788 + INTEGER(IntKi), PARAMETER :: EddAmbT9N18D4 = 7789 + INTEGER(IntKi), PARAMETER :: EddAmbT9N18D5 = 7790 + INTEGER(IntKi), PARAMETER :: EddAmbT9N18D6 = 7791 + INTEGER(IntKi), PARAMETER :: EddAmbT9N18D7 = 7792 + INTEGER(IntKi), PARAMETER :: EddAmbT9N18D8 = 7793 + INTEGER(IntKi), PARAMETER :: EddAmbT9N18D9 = 7794 + INTEGER(IntKi), PARAMETER :: EddAmbT9N19D1 = 7795 + INTEGER(IntKi), PARAMETER :: EddAmbT9N19D2 = 7796 + INTEGER(IntKi), PARAMETER :: EddAmbT9N19D3 = 7797 + INTEGER(IntKi), PARAMETER :: EddAmbT9N19D4 = 7798 + INTEGER(IntKi), PARAMETER :: EddAmbT9N19D5 = 7799 + INTEGER(IntKi), PARAMETER :: EddAmbT9N19D6 = 7800 + INTEGER(IntKi), PARAMETER :: EddAmbT9N19D7 = 7801 + INTEGER(IntKi), PARAMETER :: EddAmbT9N19D8 = 7802 + INTEGER(IntKi), PARAMETER :: EddAmbT9N19D9 = 7803 + INTEGER(IntKi), PARAMETER :: EddAmbT9N20D1 = 7804 + INTEGER(IntKi), PARAMETER :: EddAmbT9N20D2 = 7805 + INTEGER(IntKi), PARAMETER :: EddAmbT9N20D3 = 7806 + INTEGER(IntKi), PARAMETER :: EddAmbT9N20D4 = 7807 + INTEGER(IntKi), PARAMETER :: EddAmbT9N20D5 = 7808 + INTEGER(IntKi), PARAMETER :: EddAmbT9N20D6 = 7809 + INTEGER(IntKi), PARAMETER :: EddAmbT9N20D7 = 7810 + INTEGER(IntKi), PARAMETER :: EddAmbT9N20D8 = 7811 + INTEGER(IntKi), PARAMETER :: EddAmbT9N20D9 = 7812 + + + ! Contribution to eddy viscosity from shear layer: + + INTEGER(IntKi), PARAMETER :: EddShrT1N01D1 = 7813 + INTEGER(IntKi), PARAMETER :: EddShrT1N01D2 = 7814 + INTEGER(IntKi), PARAMETER :: EddShrT1N01D3 = 7815 + INTEGER(IntKi), PARAMETER :: EddShrT1N01D4 = 7816 + INTEGER(IntKi), PARAMETER :: EddShrT1N01D5 = 7817 + INTEGER(IntKi), PARAMETER :: EddShrT1N01D6 = 7818 + INTEGER(IntKi), PARAMETER :: EddShrT1N01D7 = 7819 + INTEGER(IntKi), PARAMETER :: EddShrT1N01D8 = 7820 + INTEGER(IntKi), PARAMETER :: EddShrT1N01D9 = 7821 + INTEGER(IntKi), PARAMETER :: EddShrT1N02D1 = 7822 + INTEGER(IntKi), PARAMETER :: EddShrT1N02D2 = 7823 + INTEGER(IntKi), PARAMETER :: EddShrT1N02D3 = 7824 + INTEGER(IntKi), PARAMETER :: EddShrT1N02D4 = 7825 + INTEGER(IntKi), PARAMETER :: EddShrT1N02D5 = 7826 + INTEGER(IntKi), PARAMETER :: EddShrT1N02D6 = 7827 + INTEGER(IntKi), PARAMETER :: EddShrT1N02D7 = 7828 + INTEGER(IntKi), PARAMETER :: EddShrT1N02D8 = 7829 + INTEGER(IntKi), PARAMETER :: EddShrT1N02D9 = 7830 + INTEGER(IntKi), PARAMETER :: EddShrT1N03D1 = 7831 + INTEGER(IntKi), PARAMETER :: EddShrT1N03D2 = 7832 + INTEGER(IntKi), PARAMETER :: EddShrT1N03D3 = 7833 + INTEGER(IntKi), PARAMETER :: EddShrT1N03D4 = 7834 + INTEGER(IntKi), PARAMETER :: EddShrT1N03D5 = 7835 + INTEGER(IntKi), PARAMETER :: EddShrT1N03D6 = 7836 + INTEGER(IntKi), PARAMETER :: EddShrT1N03D7 = 7837 + INTEGER(IntKi), PARAMETER :: EddShrT1N03D8 = 7838 + INTEGER(IntKi), PARAMETER :: EddShrT1N03D9 = 7839 + INTEGER(IntKi), PARAMETER :: EddShrT1N04D1 = 7840 + INTEGER(IntKi), PARAMETER :: EddShrT1N04D2 = 7841 + INTEGER(IntKi), PARAMETER :: EddShrT1N04D3 = 7842 + INTEGER(IntKi), PARAMETER :: EddShrT1N04D4 = 7843 + INTEGER(IntKi), PARAMETER :: EddShrT1N04D5 = 7844 + INTEGER(IntKi), PARAMETER :: EddShrT1N04D6 = 7845 + INTEGER(IntKi), PARAMETER :: EddShrT1N04D7 = 7846 + INTEGER(IntKi), PARAMETER :: EddShrT1N04D8 = 7847 + INTEGER(IntKi), PARAMETER :: EddShrT1N04D9 = 7848 + INTEGER(IntKi), PARAMETER :: EddShrT1N05D1 = 7849 + INTEGER(IntKi), PARAMETER :: EddShrT1N05D2 = 7850 + INTEGER(IntKi), PARAMETER :: EddShrT1N05D3 = 7851 + INTEGER(IntKi), PARAMETER :: EddShrT1N05D4 = 7852 + INTEGER(IntKi), PARAMETER :: EddShrT1N05D5 = 7853 + INTEGER(IntKi), PARAMETER :: EddShrT1N05D6 = 7854 + INTEGER(IntKi), PARAMETER :: EddShrT1N05D7 = 7855 + INTEGER(IntKi), PARAMETER :: EddShrT1N05D8 = 7856 + INTEGER(IntKi), PARAMETER :: EddShrT1N05D9 = 7857 + INTEGER(IntKi), PARAMETER :: EddShrT1N06D1 = 7858 + INTEGER(IntKi), PARAMETER :: EddShrT1N06D2 = 7859 + INTEGER(IntKi), PARAMETER :: EddShrT1N06D3 = 7860 + INTEGER(IntKi), PARAMETER :: EddShrT1N06D4 = 7861 + INTEGER(IntKi), PARAMETER :: EddShrT1N06D5 = 7862 + INTEGER(IntKi), PARAMETER :: EddShrT1N06D6 = 7863 + INTEGER(IntKi), PARAMETER :: EddShrT1N06D7 = 7864 + INTEGER(IntKi), PARAMETER :: EddShrT1N06D8 = 7865 + INTEGER(IntKi), PARAMETER :: EddShrT1N06D9 = 7866 + INTEGER(IntKi), PARAMETER :: EddShrT1N07D1 = 7867 + INTEGER(IntKi), PARAMETER :: EddShrT1N07D2 = 7868 + INTEGER(IntKi), PARAMETER :: EddShrT1N07D3 = 7869 + INTEGER(IntKi), PARAMETER :: EddShrT1N07D4 = 7870 + INTEGER(IntKi), PARAMETER :: EddShrT1N07D5 = 7871 + INTEGER(IntKi), PARAMETER :: EddShrT1N07D6 = 7872 + INTEGER(IntKi), PARAMETER :: EddShrT1N07D7 = 7873 + INTEGER(IntKi), PARAMETER :: EddShrT1N07D8 = 7874 + INTEGER(IntKi), PARAMETER :: EddShrT1N07D9 = 7875 + INTEGER(IntKi), PARAMETER :: EddShrT1N08D1 = 7876 + INTEGER(IntKi), PARAMETER :: EddShrT1N08D2 = 7877 + INTEGER(IntKi), PARAMETER :: EddShrT1N08D3 = 7878 + INTEGER(IntKi), PARAMETER :: EddShrT1N08D4 = 7879 + INTEGER(IntKi), PARAMETER :: EddShrT1N08D5 = 7880 + INTEGER(IntKi), PARAMETER :: EddShrT1N08D6 = 7881 + INTEGER(IntKi), PARAMETER :: EddShrT1N08D7 = 7882 + INTEGER(IntKi), PARAMETER :: EddShrT1N08D8 = 7883 + INTEGER(IntKi), PARAMETER :: EddShrT1N08D9 = 7884 + INTEGER(IntKi), PARAMETER :: EddShrT1N09D1 = 7885 + INTEGER(IntKi), PARAMETER :: EddShrT1N09D2 = 7886 + INTEGER(IntKi), PARAMETER :: EddShrT1N09D3 = 7887 + INTEGER(IntKi), PARAMETER :: EddShrT1N09D4 = 7888 + INTEGER(IntKi), PARAMETER :: EddShrT1N09D5 = 7889 + INTEGER(IntKi), PARAMETER :: EddShrT1N09D6 = 7890 + INTEGER(IntKi), PARAMETER :: EddShrT1N09D7 = 7891 + INTEGER(IntKi), PARAMETER :: EddShrT1N09D8 = 7892 + INTEGER(IntKi), PARAMETER :: EddShrT1N09D9 = 7893 + INTEGER(IntKi), PARAMETER :: EddShrT1N10D1 = 7894 + INTEGER(IntKi), PARAMETER :: EddShrT1N10D2 = 7895 + INTEGER(IntKi), PARAMETER :: EddShrT1N10D3 = 7896 + INTEGER(IntKi), PARAMETER :: EddShrT1N10D4 = 7897 + INTEGER(IntKi), PARAMETER :: EddShrT1N10D5 = 7898 + INTEGER(IntKi), PARAMETER :: EddShrT1N10D6 = 7899 + INTEGER(IntKi), PARAMETER :: EddShrT1N10D7 = 7900 + INTEGER(IntKi), PARAMETER :: EddShrT1N10D8 = 7901 + INTEGER(IntKi), PARAMETER :: EddShrT1N10D9 = 7902 + INTEGER(IntKi), PARAMETER :: EddShrT1N11D1 = 7903 + INTEGER(IntKi), PARAMETER :: EddShrT1N11D2 = 7904 + INTEGER(IntKi), PARAMETER :: EddShrT1N11D3 = 7905 + INTEGER(IntKi), PARAMETER :: EddShrT1N11D4 = 7906 + INTEGER(IntKi), PARAMETER :: EddShrT1N11D5 = 7907 + INTEGER(IntKi), PARAMETER :: EddShrT1N11D6 = 7908 + INTEGER(IntKi), PARAMETER :: EddShrT1N11D7 = 7909 + INTEGER(IntKi), PARAMETER :: EddShrT1N11D8 = 7910 + INTEGER(IntKi), PARAMETER :: EddShrT1N11D9 = 7911 + INTEGER(IntKi), PARAMETER :: EddShrT1N12D1 = 7912 + INTEGER(IntKi), PARAMETER :: EddShrT1N12D2 = 7913 + INTEGER(IntKi), PARAMETER :: EddShrT1N12D3 = 7914 + INTEGER(IntKi), PARAMETER :: EddShrT1N12D4 = 7915 + INTEGER(IntKi), PARAMETER :: EddShrT1N12D5 = 7916 + INTEGER(IntKi), PARAMETER :: EddShrT1N12D6 = 7917 + INTEGER(IntKi), PARAMETER :: EddShrT1N12D7 = 7918 + INTEGER(IntKi), PARAMETER :: EddShrT1N12D8 = 7919 + INTEGER(IntKi), PARAMETER :: EddShrT1N12D9 = 7920 + INTEGER(IntKi), PARAMETER :: EddShrT1N13D1 = 7921 + INTEGER(IntKi), PARAMETER :: EddShrT1N13D2 = 7922 + INTEGER(IntKi), PARAMETER :: EddShrT1N13D3 = 7923 + INTEGER(IntKi), PARAMETER :: EddShrT1N13D4 = 7924 + INTEGER(IntKi), PARAMETER :: EddShrT1N13D5 = 7925 + INTEGER(IntKi), PARAMETER :: EddShrT1N13D6 = 7926 + INTEGER(IntKi), PARAMETER :: EddShrT1N13D7 = 7927 + INTEGER(IntKi), PARAMETER :: EddShrT1N13D8 = 7928 + INTEGER(IntKi), PARAMETER :: EddShrT1N13D9 = 7929 + INTEGER(IntKi), PARAMETER :: EddShrT1N14D1 = 7930 + INTEGER(IntKi), PARAMETER :: EddShrT1N14D2 = 7931 + INTEGER(IntKi), PARAMETER :: EddShrT1N14D3 = 7932 + INTEGER(IntKi), PARAMETER :: EddShrT1N14D4 = 7933 + INTEGER(IntKi), PARAMETER :: EddShrT1N14D5 = 7934 + INTEGER(IntKi), PARAMETER :: EddShrT1N14D6 = 7935 + INTEGER(IntKi), PARAMETER :: EddShrT1N14D7 = 7936 + INTEGER(IntKi), PARAMETER :: EddShrT1N14D8 = 7937 + INTEGER(IntKi), PARAMETER :: EddShrT1N14D9 = 7938 + INTEGER(IntKi), PARAMETER :: EddShrT1N15D1 = 7939 + INTEGER(IntKi), PARAMETER :: EddShrT1N15D2 = 7940 + INTEGER(IntKi), PARAMETER :: EddShrT1N15D3 = 7941 + INTEGER(IntKi), PARAMETER :: EddShrT1N15D4 = 7942 + INTEGER(IntKi), PARAMETER :: EddShrT1N15D5 = 7943 + INTEGER(IntKi), PARAMETER :: EddShrT1N15D6 = 7944 + INTEGER(IntKi), PARAMETER :: EddShrT1N15D7 = 7945 + INTEGER(IntKi), PARAMETER :: EddShrT1N15D8 = 7946 + INTEGER(IntKi), PARAMETER :: EddShrT1N15D9 = 7947 + INTEGER(IntKi), PARAMETER :: EddShrT1N16D1 = 7948 + INTEGER(IntKi), PARAMETER :: EddShrT1N16D2 = 7949 + INTEGER(IntKi), PARAMETER :: EddShrT1N16D3 = 7950 + INTEGER(IntKi), PARAMETER :: EddShrT1N16D4 = 7951 + INTEGER(IntKi), PARAMETER :: EddShrT1N16D5 = 7952 + INTEGER(IntKi), PARAMETER :: EddShrT1N16D6 = 7953 + INTEGER(IntKi), PARAMETER :: EddShrT1N16D7 = 7954 + INTEGER(IntKi), PARAMETER :: EddShrT1N16D8 = 7955 + INTEGER(IntKi), PARAMETER :: EddShrT1N16D9 = 7956 + INTEGER(IntKi), PARAMETER :: EddShrT1N17D1 = 7957 + INTEGER(IntKi), PARAMETER :: EddShrT1N17D2 = 7958 + INTEGER(IntKi), PARAMETER :: EddShrT1N17D3 = 7959 + INTEGER(IntKi), PARAMETER :: EddShrT1N17D4 = 7960 + INTEGER(IntKi), PARAMETER :: EddShrT1N17D5 = 7961 + INTEGER(IntKi), PARAMETER :: EddShrT1N17D6 = 7962 + INTEGER(IntKi), PARAMETER :: EddShrT1N17D7 = 7963 + INTEGER(IntKi), PARAMETER :: EddShrT1N17D8 = 7964 + INTEGER(IntKi), PARAMETER :: EddShrT1N17D9 = 7965 + INTEGER(IntKi), PARAMETER :: EddShrT1N18D1 = 7966 + INTEGER(IntKi), PARAMETER :: EddShrT1N18D2 = 7967 + INTEGER(IntKi), PARAMETER :: EddShrT1N18D3 = 7968 + INTEGER(IntKi), PARAMETER :: EddShrT1N18D4 = 7969 + INTEGER(IntKi), PARAMETER :: EddShrT1N18D5 = 7970 + INTEGER(IntKi), PARAMETER :: EddShrT1N18D6 = 7971 + INTEGER(IntKi), PARAMETER :: EddShrT1N18D7 = 7972 + INTEGER(IntKi), PARAMETER :: EddShrT1N18D8 = 7973 + INTEGER(IntKi), PARAMETER :: EddShrT1N18D9 = 7974 + INTEGER(IntKi), PARAMETER :: EddShrT1N19D1 = 7975 + INTEGER(IntKi), PARAMETER :: EddShrT1N19D2 = 7976 + INTEGER(IntKi), PARAMETER :: EddShrT1N19D3 = 7977 + INTEGER(IntKi), PARAMETER :: EddShrT1N19D4 = 7978 + INTEGER(IntKi), PARAMETER :: EddShrT1N19D5 = 7979 + INTEGER(IntKi), PARAMETER :: EddShrT1N19D6 = 7980 + INTEGER(IntKi), PARAMETER :: EddShrT1N19D7 = 7981 + INTEGER(IntKi), PARAMETER :: EddShrT1N19D8 = 7982 + INTEGER(IntKi), PARAMETER :: EddShrT1N19D9 = 7983 + INTEGER(IntKi), PARAMETER :: EddShrT1N20D1 = 7984 + INTEGER(IntKi), PARAMETER :: EddShrT1N20D2 = 7985 + INTEGER(IntKi), PARAMETER :: EddShrT1N20D3 = 7986 + INTEGER(IntKi), PARAMETER :: EddShrT1N20D4 = 7987 + INTEGER(IntKi), PARAMETER :: EddShrT1N20D5 = 7988 + INTEGER(IntKi), PARAMETER :: EddShrT1N20D6 = 7989 + INTEGER(IntKi), PARAMETER :: EddShrT1N20D7 = 7990 + INTEGER(IntKi), PARAMETER :: EddShrT1N20D8 = 7991 + INTEGER(IntKi), PARAMETER :: EddShrT1N20D9 = 7992 + INTEGER(IntKi), PARAMETER :: EddShrT2N01D1 = 7993 + INTEGER(IntKi), PARAMETER :: EddShrT2N01D2 = 7994 + INTEGER(IntKi), PARAMETER :: EddShrT2N01D3 = 7995 + INTEGER(IntKi), PARAMETER :: EddShrT2N01D4 = 7996 + INTEGER(IntKi), PARAMETER :: EddShrT2N01D5 = 7997 + INTEGER(IntKi), PARAMETER :: EddShrT2N01D6 = 7998 + INTEGER(IntKi), PARAMETER :: EddShrT2N01D7 = 7999 + INTEGER(IntKi), PARAMETER :: EddShrT2N01D8 = 8000 + INTEGER(IntKi), PARAMETER :: EddShrT2N01D9 = 8001 + INTEGER(IntKi), PARAMETER :: EddShrT2N02D1 = 8002 + INTEGER(IntKi), PARAMETER :: EddShrT2N02D2 = 8003 + INTEGER(IntKi), PARAMETER :: EddShrT2N02D3 = 8004 + INTEGER(IntKi), PARAMETER :: EddShrT2N02D4 = 8005 + INTEGER(IntKi), PARAMETER :: EddShrT2N02D5 = 8006 + INTEGER(IntKi), PARAMETER :: EddShrT2N02D6 = 8007 + INTEGER(IntKi), PARAMETER :: EddShrT2N02D7 = 8008 + INTEGER(IntKi), PARAMETER :: EddShrT2N02D8 = 8009 + INTEGER(IntKi), PARAMETER :: EddShrT2N02D9 = 8010 + INTEGER(IntKi), PARAMETER :: EddShrT2N03D1 = 8011 + INTEGER(IntKi), PARAMETER :: EddShrT2N03D2 = 8012 + INTEGER(IntKi), PARAMETER :: EddShrT2N03D3 = 8013 + INTEGER(IntKi), PARAMETER :: EddShrT2N03D4 = 8014 + INTEGER(IntKi), PARAMETER :: EddShrT2N03D5 = 8015 + INTEGER(IntKi), PARAMETER :: EddShrT2N03D6 = 8016 + INTEGER(IntKi), PARAMETER :: EddShrT2N03D7 = 8017 + INTEGER(IntKi), PARAMETER :: EddShrT2N03D8 = 8018 + INTEGER(IntKi), PARAMETER :: EddShrT2N03D9 = 8019 + INTEGER(IntKi), PARAMETER :: EddShrT2N04D1 = 8020 + INTEGER(IntKi), PARAMETER :: EddShrT2N04D2 = 8021 + INTEGER(IntKi), PARAMETER :: EddShrT2N04D3 = 8022 + INTEGER(IntKi), PARAMETER :: EddShrT2N04D4 = 8023 + INTEGER(IntKi), PARAMETER :: EddShrT2N04D5 = 8024 + INTEGER(IntKi), PARAMETER :: EddShrT2N04D6 = 8025 + INTEGER(IntKi), PARAMETER :: EddShrT2N04D7 = 8026 + INTEGER(IntKi), PARAMETER :: EddShrT2N04D8 = 8027 + INTEGER(IntKi), PARAMETER :: EddShrT2N04D9 = 8028 + INTEGER(IntKi), PARAMETER :: EddShrT2N05D1 = 8029 + INTEGER(IntKi), PARAMETER :: EddShrT2N05D2 = 8030 + INTEGER(IntKi), PARAMETER :: EddShrT2N05D3 = 8031 + INTEGER(IntKi), PARAMETER :: EddShrT2N05D4 = 8032 + INTEGER(IntKi), PARAMETER :: EddShrT2N05D5 = 8033 + INTEGER(IntKi), PARAMETER :: EddShrT2N05D6 = 8034 + INTEGER(IntKi), PARAMETER :: EddShrT2N05D7 = 8035 + INTEGER(IntKi), PARAMETER :: EddShrT2N05D8 = 8036 + INTEGER(IntKi), PARAMETER :: EddShrT2N05D9 = 8037 + INTEGER(IntKi), PARAMETER :: EddShrT2N06D1 = 8038 + INTEGER(IntKi), PARAMETER :: EddShrT2N06D2 = 8039 + INTEGER(IntKi), PARAMETER :: EddShrT2N06D3 = 8040 + INTEGER(IntKi), PARAMETER :: EddShrT2N06D4 = 8041 + INTEGER(IntKi), PARAMETER :: EddShrT2N06D5 = 8042 + INTEGER(IntKi), PARAMETER :: EddShrT2N06D6 = 8043 + INTEGER(IntKi), PARAMETER :: EddShrT2N06D7 = 8044 + INTEGER(IntKi), PARAMETER :: EddShrT2N06D8 = 8045 + INTEGER(IntKi), PARAMETER :: EddShrT2N06D9 = 8046 + INTEGER(IntKi), PARAMETER :: EddShrT2N07D1 = 8047 + INTEGER(IntKi), PARAMETER :: EddShrT2N07D2 = 8048 + INTEGER(IntKi), PARAMETER :: EddShrT2N07D3 = 8049 + INTEGER(IntKi), PARAMETER :: EddShrT2N07D4 = 8050 + INTEGER(IntKi), PARAMETER :: EddShrT2N07D5 = 8051 + INTEGER(IntKi), PARAMETER :: EddShrT2N07D6 = 8052 + INTEGER(IntKi), PARAMETER :: EddShrT2N07D7 = 8053 + INTEGER(IntKi), PARAMETER :: EddShrT2N07D8 = 8054 + INTEGER(IntKi), PARAMETER :: EddShrT2N07D9 = 8055 + INTEGER(IntKi), PARAMETER :: EddShrT2N08D1 = 8056 + INTEGER(IntKi), PARAMETER :: EddShrT2N08D2 = 8057 + INTEGER(IntKi), PARAMETER :: EddShrT2N08D3 = 8058 + INTEGER(IntKi), PARAMETER :: EddShrT2N08D4 = 8059 + INTEGER(IntKi), PARAMETER :: EddShrT2N08D5 = 8060 + INTEGER(IntKi), PARAMETER :: EddShrT2N08D6 = 8061 + INTEGER(IntKi), PARAMETER :: EddShrT2N08D7 = 8062 + INTEGER(IntKi), PARAMETER :: EddShrT2N08D8 = 8063 + INTEGER(IntKi), PARAMETER :: EddShrT2N08D9 = 8064 + INTEGER(IntKi), PARAMETER :: EddShrT2N09D1 = 8065 + INTEGER(IntKi), PARAMETER :: EddShrT2N09D2 = 8066 + INTEGER(IntKi), PARAMETER :: EddShrT2N09D3 = 8067 + INTEGER(IntKi), PARAMETER :: EddShrT2N09D4 = 8068 + INTEGER(IntKi), PARAMETER :: EddShrT2N09D5 = 8069 + INTEGER(IntKi), PARAMETER :: EddShrT2N09D6 = 8070 + INTEGER(IntKi), PARAMETER :: EddShrT2N09D7 = 8071 + INTEGER(IntKi), PARAMETER :: EddShrT2N09D8 = 8072 + INTEGER(IntKi), PARAMETER :: EddShrT2N09D9 = 8073 + INTEGER(IntKi), PARAMETER :: EddShrT2N10D1 = 8074 + INTEGER(IntKi), PARAMETER :: EddShrT2N10D2 = 8075 + INTEGER(IntKi), PARAMETER :: EddShrT2N10D3 = 8076 + INTEGER(IntKi), PARAMETER :: EddShrT2N10D4 = 8077 + INTEGER(IntKi), PARAMETER :: EddShrT2N10D5 = 8078 + INTEGER(IntKi), PARAMETER :: EddShrT2N10D6 = 8079 + INTEGER(IntKi), PARAMETER :: EddShrT2N10D7 = 8080 + INTEGER(IntKi), PARAMETER :: EddShrT2N10D8 = 8081 + INTEGER(IntKi), PARAMETER :: EddShrT2N10D9 = 8082 + INTEGER(IntKi), PARAMETER :: EddShrT2N11D1 = 8083 + INTEGER(IntKi), PARAMETER :: EddShrT2N11D2 = 8084 + INTEGER(IntKi), PARAMETER :: EddShrT2N11D3 = 8085 + INTEGER(IntKi), PARAMETER :: EddShrT2N11D4 = 8086 + INTEGER(IntKi), PARAMETER :: EddShrT2N11D5 = 8087 + INTEGER(IntKi), PARAMETER :: EddShrT2N11D6 = 8088 + INTEGER(IntKi), PARAMETER :: EddShrT2N11D7 = 8089 + INTEGER(IntKi), PARAMETER :: EddShrT2N11D8 = 8090 + INTEGER(IntKi), PARAMETER :: EddShrT2N11D9 = 8091 + INTEGER(IntKi), PARAMETER :: EddShrT2N12D1 = 8092 + INTEGER(IntKi), PARAMETER :: EddShrT2N12D2 = 8093 + INTEGER(IntKi), PARAMETER :: EddShrT2N12D3 = 8094 + INTEGER(IntKi), PARAMETER :: EddShrT2N12D4 = 8095 + INTEGER(IntKi), PARAMETER :: EddShrT2N12D5 = 8096 + INTEGER(IntKi), PARAMETER :: EddShrT2N12D6 = 8097 + INTEGER(IntKi), PARAMETER :: EddShrT2N12D7 = 8098 + INTEGER(IntKi), PARAMETER :: EddShrT2N12D8 = 8099 + INTEGER(IntKi), PARAMETER :: EddShrT2N12D9 = 8100 + INTEGER(IntKi), PARAMETER :: EddShrT2N13D1 = 8101 + INTEGER(IntKi), PARAMETER :: EddShrT2N13D2 = 8102 + INTEGER(IntKi), PARAMETER :: EddShrT2N13D3 = 8103 + INTEGER(IntKi), PARAMETER :: EddShrT2N13D4 = 8104 + INTEGER(IntKi), PARAMETER :: EddShrT2N13D5 = 8105 + INTEGER(IntKi), PARAMETER :: EddShrT2N13D6 = 8106 + INTEGER(IntKi), PARAMETER :: EddShrT2N13D7 = 8107 + INTEGER(IntKi), PARAMETER :: EddShrT2N13D8 = 8108 + INTEGER(IntKi), PARAMETER :: EddShrT2N13D9 = 8109 + INTEGER(IntKi), PARAMETER :: EddShrT2N14D1 = 8110 + INTEGER(IntKi), PARAMETER :: EddShrT2N14D2 = 8111 + INTEGER(IntKi), PARAMETER :: EddShrT2N14D3 = 8112 + INTEGER(IntKi), PARAMETER :: EddShrT2N14D4 = 8113 + INTEGER(IntKi), PARAMETER :: EddShrT2N14D5 = 8114 + INTEGER(IntKi), PARAMETER :: EddShrT2N14D6 = 8115 + INTEGER(IntKi), PARAMETER :: EddShrT2N14D7 = 8116 + INTEGER(IntKi), PARAMETER :: EddShrT2N14D8 = 8117 + INTEGER(IntKi), PARAMETER :: EddShrT2N14D9 = 8118 + INTEGER(IntKi), PARAMETER :: EddShrT2N15D1 = 8119 + INTEGER(IntKi), PARAMETER :: EddShrT2N15D2 = 8120 + INTEGER(IntKi), PARAMETER :: EddShrT2N15D3 = 8121 + INTEGER(IntKi), PARAMETER :: EddShrT2N15D4 = 8122 + INTEGER(IntKi), PARAMETER :: EddShrT2N15D5 = 8123 + INTEGER(IntKi), PARAMETER :: EddShrT2N15D6 = 8124 + INTEGER(IntKi), PARAMETER :: EddShrT2N15D7 = 8125 + INTEGER(IntKi), PARAMETER :: EddShrT2N15D8 = 8126 + INTEGER(IntKi), PARAMETER :: EddShrT2N15D9 = 8127 + INTEGER(IntKi), PARAMETER :: EddShrT2N16D1 = 8128 + INTEGER(IntKi), PARAMETER :: EddShrT2N16D2 = 8129 + INTEGER(IntKi), PARAMETER :: EddShrT2N16D3 = 8130 + INTEGER(IntKi), PARAMETER :: EddShrT2N16D4 = 8131 + INTEGER(IntKi), PARAMETER :: EddShrT2N16D5 = 8132 + INTEGER(IntKi), PARAMETER :: EddShrT2N16D6 = 8133 + INTEGER(IntKi), PARAMETER :: EddShrT2N16D7 = 8134 + INTEGER(IntKi), PARAMETER :: EddShrT2N16D8 = 8135 + INTEGER(IntKi), PARAMETER :: EddShrT2N16D9 = 8136 + INTEGER(IntKi), PARAMETER :: EddShrT2N17D1 = 8137 + INTEGER(IntKi), PARAMETER :: EddShrT2N17D2 = 8138 + INTEGER(IntKi), PARAMETER :: EddShrT2N17D3 = 8139 + INTEGER(IntKi), PARAMETER :: EddShrT2N17D4 = 8140 + INTEGER(IntKi), PARAMETER :: EddShrT2N17D5 = 8141 + INTEGER(IntKi), PARAMETER :: EddShrT2N17D6 = 8142 + INTEGER(IntKi), PARAMETER :: EddShrT2N17D7 = 8143 + INTEGER(IntKi), PARAMETER :: EddShrT2N17D8 = 8144 + INTEGER(IntKi), PARAMETER :: EddShrT2N17D9 = 8145 + INTEGER(IntKi), PARAMETER :: EddShrT2N18D1 = 8146 + INTEGER(IntKi), PARAMETER :: EddShrT2N18D2 = 8147 + INTEGER(IntKi), PARAMETER :: EddShrT2N18D3 = 8148 + INTEGER(IntKi), PARAMETER :: EddShrT2N18D4 = 8149 + INTEGER(IntKi), PARAMETER :: EddShrT2N18D5 = 8150 + INTEGER(IntKi), PARAMETER :: EddShrT2N18D6 = 8151 + INTEGER(IntKi), PARAMETER :: EddShrT2N18D7 = 8152 + INTEGER(IntKi), PARAMETER :: EddShrT2N18D8 = 8153 + INTEGER(IntKi), PARAMETER :: EddShrT2N18D9 = 8154 + INTEGER(IntKi), PARAMETER :: EddShrT2N19D1 = 8155 + INTEGER(IntKi), PARAMETER :: EddShrT2N19D2 = 8156 + INTEGER(IntKi), PARAMETER :: EddShrT2N19D3 = 8157 + INTEGER(IntKi), PARAMETER :: EddShrT2N19D4 = 8158 + INTEGER(IntKi), PARAMETER :: EddShrT2N19D5 = 8159 + INTEGER(IntKi), PARAMETER :: EddShrT2N19D6 = 8160 + INTEGER(IntKi), PARAMETER :: EddShrT2N19D7 = 8161 + INTEGER(IntKi), PARAMETER :: EddShrT2N19D8 = 8162 + INTEGER(IntKi), PARAMETER :: EddShrT2N19D9 = 8163 + INTEGER(IntKi), PARAMETER :: EddShrT2N20D1 = 8164 + INTEGER(IntKi), PARAMETER :: EddShrT2N20D2 = 8165 + INTEGER(IntKi), PARAMETER :: EddShrT2N20D3 = 8166 + INTEGER(IntKi), PARAMETER :: EddShrT2N20D4 = 8167 + INTEGER(IntKi), PARAMETER :: EddShrT2N20D5 = 8168 + INTEGER(IntKi), PARAMETER :: EddShrT2N20D6 = 8169 + INTEGER(IntKi), PARAMETER :: EddShrT2N20D7 = 8170 + INTEGER(IntKi), PARAMETER :: EddShrT2N20D8 = 8171 + INTEGER(IntKi), PARAMETER :: EddShrT2N20D9 = 8172 + INTEGER(IntKi), PARAMETER :: EddShrT3N01D1 = 8173 + INTEGER(IntKi), PARAMETER :: EddShrT3N01D2 = 8174 + INTEGER(IntKi), PARAMETER :: EddShrT3N01D3 = 8175 + INTEGER(IntKi), PARAMETER :: EddShrT3N01D4 = 8176 + INTEGER(IntKi), PARAMETER :: EddShrT3N01D5 = 8177 + INTEGER(IntKi), PARAMETER :: EddShrT3N01D6 = 8178 + INTEGER(IntKi), PARAMETER :: EddShrT3N01D7 = 8179 + INTEGER(IntKi), PARAMETER :: EddShrT3N01D8 = 8180 + INTEGER(IntKi), PARAMETER :: EddShrT3N01D9 = 8181 + INTEGER(IntKi), PARAMETER :: EddShrT3N02D1 = 8182 + INTEGER(IntKi), PARAMETER :: EddShrT3N02D2 = 8183 + INTEGER(IntKi), PARAMETER :: EddShrT3N02D3 = 8184 + INTEGER(IntKi), PARAMETER :: EddShrT3N02D4 = 8185 + INTEGER(IntKi), PARAMETER :: EddShrT3N02D5 = 8186 + INTEGER(IntKi), PARAMETER :: EddShrT3N02D6 = 8187 + INTEGER(IntKi), PARAMETER :: EddShrT3N02D7 = 8188 + INTEGER(IntKi), PARAMETER :: EddShrT3N02D8 = 8189 + INTEGER(IntKi), PARAMETER :: EddShrT3N02D9 = 8190 + INTEGER(IntKi), PARAMETER :: EddShrT3N03D1 = 8191 + INTEGER(IntKi), PARAMETER :: EddShrT3N03D2 = 8192 + INTEGER(IntKi), PARAMETER :: EddShrT3N03D3 = 8193 + INTEGER(IntKi), PARAMETER :: EddShrT3N03D4 = 8194 + INTEGER(IntKi), PARAMETER :: EddShrT3N03D5 = 8195 + INTEGER(IntKi), PARAMETER :: EddShrT3N03D6 = 8196 + INTEGER(IntKi), PARAMETER :: EddShrT3N03D7 = 8197 + INTEGER(IntKi), PARAMETER :: EddShrT3N03D8 = 8198 + INTEGER(IntKi), PARAMETER :: EddShrT3N03D9 = 8199 + INTEGER(IntKi), PARAMETER :: EddShrT3N04D1 = 8200 + INTEGER(IntKi), PARAMETER :: EddShrT3N04D2 = 8201 + INTEGER(IntKi), PARAMETER :: EddShrT3N04D3 = 8202 + INTEGER(IntKi), PARAMETER :: EddShrT3N04D4 = 8203 + INTEGER(IntKi), PARAMETER :: EddShrT3N04D5 = 8204 + INTEGER(IntKi), PARAMETER :: EddShrT3N04D6 = 8205 + INTEGER(IntKi), PARAMETER :: EddShrT3N04D7 = 8206 + INTEGER(IntKi), PARAMETER :: EddShrT3N04D8 = 8207 + INTEGER(IntKi), PARAMETER :: EddShrT3N04D9 = 8208 + INTEGER(IntKi), PARAMETER :: EddShrT3N05D1 = 8209 + INTEGER(IntKi), PARAMETER :: EddShrT3N05D2 = 8210 + INTEGER(IntKi), PARAMETER :: EddShrT3N05D3 = 8211 + INTEGER(IntKi), PARAMETER :: EddShrT3N05D4 = 8212 + INTEGER(IntKi), PARAMETER :: EddShrT3N05D5 = 8213 + INTEGER(IntKi), PARAMETER :: EddShrT3N05D6 = 8214 + INTEGER(IntKi), PARAMETER :: EddShrT3N05D7 = 8215 + INTEGER(IntKi), PARAMETER :: EddShrT3N05D8 = 8216 + INTEGER(IntKi), PARAMETER :: EddShrT3N05D9 = 8217 + INTEGER(IntKi), PARAMETER :: EddShrT3N06D1 = 8218 + INTEGER(IntKi), PARAMETER :: EddShrT3N06D2 = 8219 + INTEGER(IntKi), PARAMETER :: EddShrT3N06D3 = 8220 + INTEGER(IntKi), PARAMETER :: EddShrT3N06D4 = 8221 + INTEGER(IntKi), PARAMETER :: EddShrT3N06D5 = 8222 + INTEGER(IntKi), PARAMETER :: EddShrT3N06D6 = 8223 + INTEGER(IntKi), PARAMETER :: EddShrT3N06D7 = 8224 + INTEGER(IntKi), PARAMETER :: EddShrT3N06D8 = 8225 + INTEGER(IntKi), PARAMETER :: EddShrT3N06D9 = 8226 + INTEGER(IntKi), PARAMETER :: EddShrT3N07D1 = 8227 + INTEGER(IntKi), PARAMETER :: EddShrT3N07D2 = 8228 + INTEGER(IntKi), PARAMETER :: EddShrT3N07D3 = 8229 + INTEGER(IntKi), PARAMETER :: EddShrT3N07D4 = 8230 + INTEGER(IntKi), PARAMETER :: EddShrT3N07D5 = 8231 + INTEGER(IntKi), PARAMETER :: EddShrT3N07D6 = 8232 + INTEGER(IntKi), PARAMETER :: EddShrT3N07D7 = 8233 + INTEGER(IntKi), PARAMETER :: EddShrT3N07D8 = 8234 + INTEGER(IntKi), PARAMETER :: EddShrT3N07D9 = 8235 + INTEGER(IntKi), PARAMETER :: EddShrT3N08D1 = 8236 + INTEGER(IntKi), PARAMETER :: EddShrT3N08D2 = 8237 + INTEGER(IntKi), PARAMETER :: EddShrT3N08D3 = 8238 + INTEGER(IntKi), PARAMETER :: EddShrT3N08D4 = 8239 + INTEGER(IntKi), PARAMETER :: EddShrT3N08D5 = 8240 + INTEGER(IntKi), PARAMETER :: EddShrT3N08D6 = 8241 + INTEGER(IntKi), PARAMETER :: EddShrT3N08D7 = 8242 + INTEGER(IntKi), PARAMETER :: EddShrT3N08D8 = 8243 + INTEGER(IntKi), PARAMETER :: EddShrT3N08D9 = 8244 + INTEGER(IntKi), PARAMETER :: EddShrT3N09D1 = 8245 + INTEGER(IntKi), PARAMETER :: EddShrT3N09D2 = 8246 + INTEGER(IntKi), PARAMETER :: EddShrT3N09D3 = 8247 + INTEGER(IntKi), PARAMETER :: EddShrT3N09D4 = 8248 + INTEGER(IntKi), PARAMETER :: EddShrT3N09D5 = 8249 + INTEGER(IntKi), PARAMETER :: EddShrT3N09D6 = 8250 + INTEGER(IntKi), PARAMETER :: EddShrT3N09D7 = 8251 + INTEGER(IntKi), PARAMETER :: EddShrT3N09D8 = 8252 + INTEGER(IntKi), PARAMETER :: EddShrT3N09D9 = 8253 + INTEGER(IntKi), PARAMETER :: EddShrT3N10D1 = 8254 + INTEGER(IntKi), PARAMETER :: EddShrT3N10D2 = 8255 + INTEGER(IntKi), PARAMETER :: EddShrT3N10D3 = 8256 + INTEGER(IntKi), PARAMETER :: EddShrT3N10D4 = 8257 + INTEGER(IntKi), PARAMETER :: EddShrT3N10D5 = 8258 + INTEGER(IntKi), PARAMETER :: EddShrT3N10D6 = 8259 + INTEGER(IntKi), PARAMETER :: EddShrT3N10D7 = 8260 + INTEGER(IntKi), PARAMETER :: EddShrT3N10D8 = 8261 + INTEGER(IntKi), PARAMETER :: EddShrT3N10D9 = 8262 + INTEGER(IntKi), PARAMETER :: EddShrT3N11D1 = 8263 + INTEGER(IntKi), PARAMETER :: EddShrT3N11D2 = 8264 + INTEGER(IntKi), PARAMETER :: EddShrT3N11D3 = 8265 + INTEGER(IntKi), PARAMETER :: EddShrT3N11D4 = 8266 + INTEGER(IntKi), PARAMETER :: EddShrT3N11D5 = 8267 + INTEGER(IntKi), PARAMETER :: EddShrT3N11D6 = 8268 + INTEGER(IntKi), PARAMETER :: EddShrT3N11D7 = 8269 + INTEGER(IntKi), PARAMETER :: EddShrT3N11D8 = 8270 + INTEGER(IntKi), PARAMETER :: EddShrT3N11D9 = 8271 + INTEGER(IntKi), PARAMETER :: EddShrT3N12D1 = 8272 + INTEGER(IntKi), PARAMETER :: EddShrT3N12D2 = 8273 + INTEGER(IntKi), PARAMETER :: EddShrT3N12D3 = 8274 + INTEGER(IntKi), PARAMETER :: EddShrT3N12D4 = 8275 + INTEGER(IntKi), PARAMETER :: EddShrT3N12D5 = 8276 + INTEGER(IntKi), PARAMETER :: EddShrT3N12D6 = 8277 + INTEGER(IntKi), PARAMETER :: EddShrT3N12D7 = 8278 + INTEGER(IntKi), PARAMETER :: EddShrT3N12D8 = 8279 + INTEGER(IntKi), PARAMETER :: EddShrT3N12D9 = 8280 + INTEGER(IntKi), PARAMETER :: EddShrT3N13D1 = 8281 + INTEGER(IntKi), PARAMETER :: EddShrT3N13D2 = 8282 + INTEGER(IntKi), PARAMETER :: EddShrT3N13D3 = 8283 + INTEGER(IntKi), PARAMETER :: EddShrT3N13D4 = 8284 + INTEGER(IntKi), PARAMETER :: EddShrT3N13D5 = 8285 + INTEGER(IntKi), PARAMETER :: EddShrT3N13D6 = 8286 + INTEGER(IntKi), PARAMETER :: EddShrT3N13D7 = 8287 + INTEGER(IntKi), PARAMETER :: EddShrT3N13D8 = 8288 + INTEGER(IntKi), PARAMETER :: EddShrT3N13D9 = 8289 + INTEGER(IntKi), PARAMETER :: EddShrT3N14D1 = 8290 + INTEGER(IntKi), PARAMETER :: EddShrT3N14D2 = 8291 + INTEGER(IntKi), PARAMETER :: EddShrT3N14D3 = 8292 + INTEGER(IntKi), PARAMETER :: EddShrT3N14D4 = 8293 + INTEGER(IntKi), PARAMETER :: EddShrT3N14D5 = 8294 + INTEGER(IntKi), PARAMETER :: EddShrT3N14D6 = 8295 + INTEGER(IntKi), PARAMETER :: EddShrT3N14D7 = 8296 + INTEGER(IntKi), PARAMETER :: EddShrT3N14D8 = 8297 + INTEGER(IntKi), PARAMETER :: EddShrT3N14D9 = 8298 + INTEGER(IntKi), PARAMETER :: EddShrT3N15D1 = 8299 + INTEGER(IntKi), PARAMETER :: EddShrT3N15D2 = 8300 + INTEGER(IntKi), PARAMETER :: EddShrT3N15D3 = 8301 + INTEGER(IntKi), PARAMETER :: EddShrT3N15D4 = 8302 + INTEGER(IntKi), PARAMETER :: EddShrT3N15D5 = 8303 + INTEGER(IntKi), PARAMETER :: EddShrT3N15D6 = 8304 + INTEGER(IntKi), PARAMETER :: EddShrT3N15D7 = 8305 + INTEGER(IntKi), PARAMETER :: EddShrT3N15D8 = 8306 + INTEGER(IntKi), PARAMETER :: EddShrT3N15D9 = 8307 + INTEGER(IntKi), PARAMETER :: EddShrT3N16D1 = 8308 + INTEGER(IntKi), PARAMETER :: EddShrT3N16D2 = 8309 + INTEGER(IntKi), PARAMETER :: EddShrT3N16D3 = 8310 + INTEGER(IntKi), PARAMETER :: EddShrT3N16D4 = 8311 + INTEGER(IntKi), PARAMETER :: EddShrT3N16D5 = 8312 + INTEGER(IntKi), PARAMETER :: EddShrT3N16D6 = 8313 + INTEGER(IntKi), PARAMETER :: EddShrT3N16D7 = 8314 + INTEGER(IntKi), PARAMETER :: EddShrT3N16D8 = 8315 + INTEGER(IntKi), PARAMETER :: EddShrT3N16D9 = 8316 + INTEGER(IntKi), PARAMETER :: EddShrT3N17D1 = 8317 + INTEGER(IntKi), PARAMETER :: EddShrT3N17D2 = 8318 + INTEGER(IntKi), PARAMETER :: EddShrT3N17D3 = 8319 + INTEGER(IntKi), PARAMETER :: EddShrT3N17D4 = 8320 + INTEGER(IntKi), PARAMETER :: EddShrT3N17D5 = 8321 + INTEGER(IntKi), PARAMETER :: EddShrT3N17D6 = 8322 + INTEGER(IntKi), PARAMETER :: EddShrT3N17D7 = 8323 + INTEGER(IntKi), PARAMETER :: EddShrT3N17D8 = 8324 + INTEGER(IntKi), PARAMETER :: EddShrT3N17D9 = 8325 + INTEGER(IntKi), PARAMETER :: EddShrT3N18D1 = 8326 + INTEGER(IntKi), PARAMETER :: EddShrT3N18D2 = 8327 + INTEGER(IntKi), PARAMETER :: EddShrT3N18D3 = 8328 + INTEGER(IntKi), PARAMETER :: EddShrT3N18D4 = 8329 + INTEGER(IntKi), PARAMETER :: EddShrT3N18D5 = 8330 + INTEGER(IntKi), PARAMETER :: EddShrT3N18D6 = 8331 + INTEGER(IntKi), PARAMETER :: EddShrT3N18D7 = 8332 + INTEGER(IntKi), PARAMETER :: EddShrT3N18D8 = 8333 + INTEGER(IntKi), PARAMETER :: EddShrT3N18D9 = 8334 + INTEGER(IntKi), PARAMETER :: EddShrT3N19D1 = 8335 + INTEGER(IntKi), PARAMETER :: EddShrT3N19D2 = 8336 + INTEGER(IntKi), PARAMETER :: EddShrT3N19D3 = 8337 + INTEGER(IntKi), PARAMETER :: EddShrT3N19D4 = 8338 + INTEGER(IntKi), PARAMETER :: EddShrT3N19D5 = 8339 + INTEGER(IntKi), PARAMETER :: EddShrT3N19D6 = 8340 + INTEGER(IntKi), PARAMETER :: EddShrT3N19D7 = 8341 + INTEGER(IntKi), PARAMETER :: EddShrT3N19D8 = 8342 + INTEGER(IntKi), PARAMETER :: EddShrT3N19D9 = 8343 + INTEGER(IntKi), PARAMETER :: EddShrT3N20D1 = 8344 + INTEGER(IntKi), PARAMETER :: EddShrT3N20D2 = 8345 + INTEGER(IntKi), PARAMETER :: EddShrT3N20D3 = 8346 + INTEGER(IntKi), PARAMETER :: EddShrT3N20D4 = 8347 + INTEGER(IntKi), PARAMETER :: EddShrT3N20D5 = 8348 + INTEGER(IntKi), PARAMETER :: EddShrT3N20D6 = 8349 + INTEGER(IntKi), PARAMETER :: EddShrT3N20D7 = 8350 + INTEGER(IntKi), PARAMETER :: EddShrT3N20D8 = 8351 + INTEGER(IntKi), PARAMETER :: EddShrT3N20D9 = 8352 + INTEGER(IntKi), PARAMETER :: EddShrT4N01D1 = 8353 + INTEGER(IntKi), PARAMETER :: EddShrT4N01D2 = 8354 + INTEGER(IntKi), PARAMETER :: EddShrT4N01D3 = 8355 + INTEGER(IntKi), PARAMETER :: EddShrT4N01D4 = 8356 + INTEGER(IntKi), PARAMETER :: EddShrT4N01D5 = 8357 + INTEGER(IntKi), PARAMETER :: EddShrT4N01D6 = 8358 + INTEGER(IntKi), PARAMETER :: EddShrT4N01D7 = 8359 + INTEGER(IntKi), PARAMETER :: EddShrT4N01D8 = 8360 + INTEGER(IntKi), PARAMETER :: EddShrT4N01D9 = 8361 + INTEGER(IntKi), PARAMETER :: EddShrT4N02D1 = 8362 + INTEGER(IntKi), PARAMETER :: EddShrT4N02D2 = 8363 + INTEGER(IntKi), PARAMETER :: EddShrT4N02D3 = 8364 + INTEGER(IntKi), PARAMETER :: EddShrT4N02D4 = 8365 + INTEGER(IntKi), PARAMETER :: EddShrT4N02D5 = 8366 + INTEGER(IntKi), PARAMETER :: EddShrT4N02D6 = 8367 + INTEGER(IntKi), PARAMETER :: EddShrT4N02D7 = 8368 + INTEGER(IntKi), PARAMETER :: EddShrT4N02D8 = 8369 + INTEGER(IntKi), PARAMETER :: EddShrT4N02D9 = 8370 + INTEGER(IntKi), PARAMETER :: EddShrT4N03D1 = 8371 + INTEGER(IntKi), PARAMETER :: EddShrT4N03D2 = 8372 + INTEGER(IntKi), PARAMETER :: EddShrT4N03D3 = 8373 + INTEGER(IntKi), PARAMETER :: EddShrT4N03D4 = 8374 + INTEGER(IntKi), PARAMETER :: EddShrT4N03D5 = 8375 + INTEGER(IntKi), PARAMETER :: EddShrT4N03D6 = 8376 + INTEGER(IntKi), PARAMETER :: EddShrT4N03D7 = 8377 + INTEGER(IntKi), PARAMETER :: EddShrT4N03D8 = 8378 + INTEGER(IntKi), PARAMETER :: EddShrT4N03D9 = 8379 + INTEGER(IntKi), PARAMETER :: EddShrT4N04D1 = 8380 + INTEGER(IntKi), PARAMETER :: EddShrT4N04D2 = 8381 + INTEGER(IntKi), PARAMETER :: EddShrT4N04D3 = 8382 + INTEGER(IntKi), PARAMETER :: EddShrT4N04D4 = 8383 + INTEGER(IntKi), PARAMETER :: EddShrT4N04D5 = 8384 + INTEGER(IntKi), PARAMETER :: EddShrT4N04D6 = 8385 + INTEGER(IntKi), PARAMETER :: EddShrT4N04D7 = 8386 + INTEGER(IntKi), PARAMETER :: EddShrT4N04D8 = 8387 + INTEGER(IntKi), PARAMETER :: EddShrT4N04D9 = 8388 + INTEGER(IntKi), PARAMETER :: EddShrT4N05D1 = 8389 + INTEGER(IntKi), PARAMETER :: EddShrT4N05D2 = 8390 + INTEGER(IntKi), PARAMETER :: EddShrT4N05D3 = 8391 + INTEGER(IntKi), PARAMETER :: EddShrT4N05D4 = 8392 + INTEGER(IntKi), PARAMETER :: EddShrT4N05D5 = 8393 + INTEGER(IntKi), PARAMETER :: EddShrT4N05D6 = 8394 + INTEGER(IntKi), PARAMETER :: EddShrT4N05D7 = 8395 + INTEGER(IntKi), PARAMETER :: EddShrT4N05D8 = 8396 + INTEGER(IntKi), PARAMETER :: EddShrT4N05D9 = 8397 + INTEGER(IntKi), PARAMETER :: EddShrT4N06D1 = 8398 + INTEGER(IntKi), PARAMETER :: EddShrT4N06D2 = 8399 + INTEGER(IntKi), PARAMETER :: EddShrT4N06D3 = 8400 + INTEGER(IntKi), PARAMETER :: EddShrT4N06D4 = 8401 + INTEGER(IntKi), PARAMETER :: EddShrT4N06D5 = 8402 + INTEGER(IntKi), PARAMETER :: EddShrT4N06D6 = 8403 + INTEGER(IntKi), PARAMETER :: EddShrT4N06D7 = 8404 + INTEGER(IntKi), PARAMETER :: EddShrT4N06D8 = 8405 + INTEGER(IntKi), PARAMETER :: EddShrT4N06D9 = 8406 + INTEGER(IntKi), PARAMETER :: EddShrT4N07D1 = 8407 + INTEGER(IntKi), PARAMETER :: EddShrT4N07D2 = 8408 + INTEGER(IntKi), PARAMETER :: EddShrT4N07D3 = 8409 + INTEGER(IntKi), PARAMETER :: EddShrT4N07D4 = 8410 + INTEGER(IntKi), PARAMETER :: EddShrT4N07D5 = 8411 + INTEGER(IntKi), PARAMETER :: EddShrT4N07D6 = 8412 + INTEGER(IntKi), PARAMETER :: EddShrT4N07D7 = 8413 + INTEGER(IntKi), PARAMETER :: EddShrT4N07D8 = 8414 + INTEGER(IntKi), PARAMETER :: EddShrT4N07D9 = 8415 + INTEGER(IntKi), PARAMETER :: EddShrT4N08D1 = 8416 + INTEGER(IntKi), PARAMETER :: EddShrT4N08D2 = 8417 + INTEGER(IntKi), PARAMETER :: EddShrT4N08D3 = 8418 + INTEGER(IntKi), PARAMETER :: EddShrT4N08D4 = 8419 + INTEGER(IntKi), PARAMETER :: EddShrT4N08D5 = 8420 + INTEGER(IntKi), PARAMETER :: EddShrT4N08D6 = 8421 + INTEGER(IntKi), PARAMETER :: EddShrT4N08D7 = 8422 + INTEGER(IntKi), PARAMETER :: EddShrT4N08D8 = 8423 + INTEGER(IntKi), PARAMETER :: EddShrT4N08D9 = 8424 + INTEGER(IntKi), PARAMETER :: EddShrT4N09D1 = 8425 + INTEGER(IntKi), PARAMETER :: EddShrT4N09D2 = 8426 + INTEGER(IntKi), PARAMETER :: EddShrT4N09D3 = 8427 + INTEGER(IntKi), PARAMETER :: EddShrT4N09D4 = 8428 + INTEGER(IntKi), PARAMETER :: EddShrT4N09D5 = 8429 + INTEGER(IntKi), PARAMETER :: EddShrT4N09D6 = 8430 + INTEGER(IntKi), PARAMETER :: EddShrT4N09D7 = 8431 + INTEGER(IntKi), PARAMETER :: EddShrT4N09D8 = 8432 + INTEGER(IntKi), PARAMETER :: EddShrT4N09D9 = 8433 + INTEGER(IntKi), PARAMETER :: EddShrT4N10D1 = 8434 + INTEGER(IntKi), PARAMETER :: EddShrT4N10D2 = 8435 + INTEGER(IntKi), PARAMETER :: EddShrT4N10D3 = 8436 + INTEGER(IntKi), PARAMETER :: EddShrT4N10D4 = 8437 + INTEGER(IntKi), PARAMETER :: EddShrT4N10D5 = 8438 + INTEGER(IntKi), PARAMETER :: EddShrT4N10D6 = 8439 + INTEGER(IntKi), PARAMETER :: EddShrT4N10D7 = 8440 + INTEGER(IntKi), PARAMETER :: EddShrT4N10D8 = 8441 + INTEGER(IntKi), PARAMETER :: EddShrT4N10D9 = 8442 + INTEGER(IntKi), PARAMETER :: EddShrT4N11D1 = 8443 + INTEGER(IntKi), PARAMETER :: EddShrT4N11D2 = 8444 + INTEGER(IntKi), PARAMETER :: EddShrT4N11D3 = 8445 + INTEGER(IntKi), PARAMETER :: EddShrT4N11D4 = 8446 + INTEGER(IntKi), PARAMETER :: EddShrT4N11D5 = 8447 + INTEGER(IntKi), PARAMETER :: EddShrT4N11D6 = 8448 + INTEGER(IntKi), PARAMETER :: EddShrT4N11D7 = 8449 + INTEGER(IntKi), PARAMETER :: EddShrT4N11D8 = 8450 + INTEGER(IntKi), PARAMETER :: EddShrT4N11D9 = 8451 + INTEGER(IntKi), PARAMETER :: EddShrT4N12D1 = 8452 + INTEGER(IntKi), PARAMETER :: EddShrT4N12D2 = 8453 + INTEGER(IntKi), PARAMETER :: EddShrT4N12D3 = 8454 + INTEGER(IntKi), PARAMETER :: EddShrT4N12D4 = 8455 + INTEGER(IntKi), PARAMETER :: EddShrT4N12D5 = 8456 + INTEGER(IntKi), PARAMETER :: EddShrT4N12D6 = 8457 + INTEGER(IntKi), PARAMETER :: EddShrT4N12D7 = 8458 + INTEGER(IntKi), PARAMETER :: EddShrT4N12D8 = 8459 + INTEGER(IntKi), PARAMETER :: EddShrT4N12D9 = 8460 + INTEGER(IntKi), PARAMETER :: EddShrT4N13D1 = 8461 + INTEGER(IntKi), PARAMETER :: EddShrT4N13D2 = 8462 + INTEGER(IntKi), PARAMETER :: EddShrT4N13D3 = 8463 + INTEGER(IntKi), PARAMETER :: EddShrT4N13D4 = 8464 + INTEGER(IntKi), PARAMETER :: EddShrT4N13D5 = 8465 + INTEGER(IntKi), PARAMETER :: EddShrT4N13D6 = 8466 + INTEGER(IntKi), PARAMETER :: EddShrT4N13D7 = 8467 + INTEGER(IntKi), PARAMETER :: EddShrT4N13D8 = 8468 + INTEGER(IntKi), PARAMETER :: EddShrT4N13D9 = 8469 + INTEGER(IntKi), PARAMETER :: EddShrT4N14D1 = 8470 + INTEGER(IntKi), PARAMETER :: EddShrT4N14D2 = 8471 + INTEGER(IntKi), PARAMETER :: EddShrT4N14D3 = 8472 + INTEGER(IntKi), PARAMETER :: EddShrT4N14D4 = 8473 + INTEGER(IntKi), PARAMETER :: EddShrT4N14D5 = 8474 + INTEGER(IntKi), PARAMETER :: EddShrT4N14D6 = 8475 + INTEGER(IntKi), PARAMETER :: EddShrT4N14D7 = 8476 + INTEGER(IntKi), PARAMETER :: EddShrT4N14D8 = 8477 + INTEGER(IntKi), PARAMETER :: EddShrT4N14D9 = 8478 + INTEGER(IntKi), PARAMETER :: EddShrT4N15D1 = 8479 + INTEGER(IntKi), PARAMETER :: EddShrT4N15D2 = 8480 + INTEGER(IntKi), PARAMETER :: EddShrT4N15D3 = 8481 + INTEGER(IntKi), PARAMETER :: EddShrT4N15D4 = 8482 + INTEGER(IntKi), PARAMETER :: EddShrT4N15D5 = 8483 + INTEGER(IntKi), PARAMETER :: EddShrT4N15D6 = 8484 + INTEGER(IntKi), PARAMETER :: EddShrT4N15D7 = 8485 + INTEGER(IntKi), PARAMETER :: EddShrT4N15D8 = 8486 + INTEGER(IntKi), PARAMETER :: EddShrT4N15D9 = 8487 + INTEGER(IntKi), PARAMETER :: EddShrT4N16D1 = 8488 + INTEGER(IntKi), PARAMETER :: EddShrT4N16D2 = 8489 + INTEGER(IntKi), PARAMETER :: EddShrT4N16D3 = 8490 + INTEGER(IntKi), PARAMETER :: EddShrT4N16D4 = 8491 + INTEGER(IntKi), PARAMETER :: EddShrT4N16D5 = 8492 + INTEGER(IntKi), PARAMETER :: EddShrT4N16D6 = 8493 + INTEGER(IntKi), PARAMETER :: EddShrT4N16D7 = 8494 + INTEGER(IntKi), PARAMETER :: EddShrT4N16D8 = 8495 + INTEGER(IntKi), PARAMETER :: EddShrT4N16D9 = 8496 + INTEGER(IntKi), PARAMETER :: EddShrT4N17D1 = 8497 + INTEGER(IntKi), PARAMETER :: EddShrT4N17D2 = 8498 + INTEGER(IntKi), PARAMETER :: EddShrT4N17D3 = 8499 + INTEGER(IntKi), PARAMETER :: EddShrT4N17D4 = 8500 + INTEGER(IntKi), PARAMETER :: EddShrT4N17D5 = 8501 + INTEGER(IntKi), PARAMETER :: EddShrT4N17D6 = 8502 + INTEGER(IntKi), PARAMETER :: EddShrT4N17D7 = 8503 + INTEGER(IntKi), PARAMETER :: EddShrT4N17D8 = 8504 + INTEGER(IntKi), PARAMETER :: EddShrT4N17D9 = 8505 + INTEGER(IntKi), PARAMETER :: EddShrT4N18D1 = 8506 + INTEGER(IntKi), PARAMETER :: EddShrT4N18D2 = 8507 + INTEGER(IntKi), PARAMETER :: EddShrT4N18D3 = 8508 + INTEGER(IntKi), PARAMETER :: EddShrT4N18D4 = 8509 + INTEGER(IntKi), PARAMETER :: EddShrT4N18D5 = 8510 + INTEGER(IntKi), PARAMETER :: EddShrT4N18D6 = 8511 + INTEGER(IntKi), PARAMETER :: EddShrT4N18D7 = 8512 + INTEGER(IntKi), PARAMETER :: EddShrT4N18D8 = 8513 + INTEGER(IntKi), PARAMETER :: EddShrT4N18D9 = 8514 + INTEGER(IntKi), PARAMETER :: EddShrT4N19D1 = 8515 + INTEGER(IntKi), PARAMETER :: EddShrT4N19D2 = 8516 + INTEGER(IntKi), PARAMETER :: EddShrT4N19D3 = 8517 + INTEGER(IntKi), PARAMETER :: EddShrT4N19D4 = 8518 + INTEGER(IntKi), PARAMETER :: EddShrT4N19D5 = 8519 + INTEGER(IntKi), PARAMETER :: EddShrT4N19D6 = 8520 + INTEGER(IntKi), PARAMETER :: EddShrT4N19D7 = 8521 + INTEGER(IntKi), PARAMETER :: EddShrT4N19D8 = 8522 + INTEGER(IntKi), PARAMETER :: EddShrT4N19D9 = 8523 + INTEGER(IntKi), PARAMETER :: EddShrT4N20D1 = 8524 + INTEGER(IntKi), PARAMETER :: EddShrT4N20D2 = 8525 + INTEGER(IntKi), PARAMETER :: EddShrT4N20D3 = 8526 + INTEGER(IntKi), PARAMETER :: EddShrT4N20D4 = 8527 + INTEGER(IntKi), PARAMETER :: EddShrT4N20D5 = 8528 + INTEGER(IntKi), PARAMETER :: EddShrT4N20D6 = 8529 + INTEGER(IntKi), PARAMETER :: EddShrT4N20D7 = 8530 + INTEGER(IntKi), PARAMETER :: EddShrT4N20D8 = 8531 + INTEGER(IntKi), PARAMETER :: EddShrT4N20D9 = 8532 + INTEGER(IntKi), PARAMETER :: EddShrT5N01D1 = 8533 + INTEGER(IntKi), PARAMETER :: EddShrT5N01D2 = 8534 + INTEGER(IntKi), PARAMETER :: EddShrT5N01D3 = 8535 + INTEGER(IntKi), PARAMETER :: EddShrT5N01D4 = 8536 + INTEGER(IntKi), PARAMETER :: EddShrT5N01D5 = 8537 + INTEGER(IntKi), PARAMETER :: EddShrT5N01D6 = 8538 + INTEGER(IntKi), PARAMETER :: EddShrT5N01D7 = 8539 + INTEGER(IntKi), PARAMETER :: EddShrT5N01D8 = 8540 + INTEGER(IntKi), PARAMETER :: EddShrT5N01D9 = 8541 + INTEGER(IntKi), PARAMETER :: EddShrT5N02D1 = 8542 + INTEGER(IntKi), PARAMETER :: EddShrT5N02D2 = 8543 + INTEGER(IntKi), PARAMETER :: EddShrT5N02D3 = 8544 + INTEGER(IntKi), PARAMETER :: EddShrT5N02D4 = 8545 + INTEGER(IntKi), PARAMETER :: EddShrT5N02D5 = 8546 + INTEGER(IntKi), PARAMETER :: EddShrT5N02D6 = 8547 + INTEGER(IntKi), PARAMETER :: EddShrT5N02D7 = 8548 + INTEGER(IntKi), PARAMETER :: EddShrT5N02D8 = 8549 + INTEGER(IntKi), PARAMETER :: EddShrT5N02D9 = 8550 + INTEGER(IntKi), PARAMETER :: EddShrT5N03D1 = 8551 + INTEGER(IntKi), PARAMETER :: EddShrT5N03D2 = 8552 + INTEGER(IntKi), PARAMETER :: EddShrT5N03D3 = 8553 + INTEGER(IntKi), PARAMETER :: EddShrT5N03D4 = 8554 + INTEGER(IntKi), PARAMETER :: EddShrT5N03D5 = 8555 + INTEGER(IntKi), PARAMETER :: EddShrT5N03D6 = 8556 + INTEGER(IntKi), PARAMETER :: EddShrT5N03D7 = 8557 + INTEGER(IntKi), PARAMETER :: EddShrT5N03D8 = 8558 + INTEGER(IntKi), PARAMETER :: EddShrT5N03D9 = 8559 + INTEGER(IntKi), PARAMETER :: EddShrT5N04D1 = 8560 + INTEGER(IntKi), PARAMETER :: EddShrT5N04D2 = 8561 + INTEGER(IntKi), PARAMETER :: EddShrT5N04D3 = 8562 + INTEGER(IntKi), PARAMETER :: EddShrT5N04D4 = 8563 + INTEGER(IntKi), PARAMETER :: EddShrT5N04D5 = 8564 + INTEGER(IntKi), PARAMETER :: EddShrT5N04D6 = 8565 + INTEGER(IntKi), PARAMETER :: EddShrT5N04D7 = 8566 + INTEGER(IntKi), PARAMETER :: EddShrT5N04D8 = 8567 + INTEGER(IntKi), PARAMETER :: EddShrT5N04D9 = 8568 + INTEGER(IntKi), PARAMETER :: EddShrT5N05D1 = 8569 + INTEGER(IntKi), PARAMETER :: EddShrT5N05D2 = 8570 + INTEGER(IntKi), PARAMETER :: EddShrT5N05D3 = 8571 + INTEGER(IntKi), PARAMETER :: EddShrT5N05D4 = 8572 + INTEGER(IntKi), PARAMETER :: EddShrT5N05D5 = 8573 + INTEGER(IntKi), PARAMETER :: EddShrT5N05D6 = 8574 + INTEGER(IntKi), PARAMETER :: EddShrT5N05D7 = 8575 + INTEGER(IntKi), PARAMETER :: EddShrT5N05D8 = 8576 + INTEGER(IntKi), PARAMETER :: EddShrT5N05D9 = 8577 + INTEGER(IntKi), PARAMETER :: EddShrT5N06D1 = 8578 + INTEGER(IntKi), PARAMETER :: EddShrT5N06D2 = 8579 + INTEGER(IntKi), PARAMETER :: EddShrT5N06D3 = 8580 + INTEGER(IntKi), PARAMETER :: EddShrT5N06D4 = 8581 + INTEGER(IntKi), PARAMETER :: EddShrT5N06D5 = 8582 + INTEGER(IntKi), PARAMETER :: EddShrT5N06D6 = 8583 + INTEGER(IntKi), PARAMETER :: EddShrT5N06D7 = 8584 + INTEGER(IntKi), PARAMETER :: EddShrT5N06D8 = 8585 + INTEGER(IntKi), PARAMETER :: EddShrT5N06D9 = 8586 + INTEGER(IntKi), PARAMETER :: EddShrT5N07D1 = 8587 + INTEGER(IntKi), PARAMETER :: EddShrT5N07D2 = 8588 + INTEGER(IntKi), PARAMETER :: EddShrT5N07D3 = 8589 + INTEGER(IntKi), PARAMETER :: EddShrT5N07D4 = 8590 + INTEGER(IntKi), PARAMETER :: EddShrT5N07D5 = 8591 + INTEGER(IntKi), PARAMETER :: EddShrT5N07D6 = 8592 + INTEGER(IntKi), PARAMETER :: EddShrT5N07D7 = 8593 + INTEGER(IntKi), PARAMETER :: EddShrT5N07D8 = 8594 + INTEGER(IntKi), PARAMETER :: EddShrT5N07D9 = 8595 + INTEGER(IntKi), PARAMETER :: EddShrT5N08D1 = 8596 + INTEGER(IntKi), PARAMETER :: EddShrT5N08D2 = 8597 + INTEGER(IntKi), PARAMETER :: EddShrT5N08D3 = 8598 + INTEGER(IntKi), PARAMETER :: EddShrT5N08D4 = 8599 + INTEGER(IntKi), PARAMETER :: EddShrT5N08D5 = 8600 + INTEGER(IntKi), PARAMETER :: EddShrT5N08D6 = 8601 + INTEGER(IntKi), PARAMETER :: EddShrT5N08D7 = 8602 + INTEGER(IntKi), PARAMETER :: EddShrT5N08D8 = 8603 + INTEGER(IntKi), PARAMETER :: EddShrT5N08D9 = 8604 + INTEGER(IntKi), PARAMETER :: EddShrT5N09D1 = 8605 + INTEGER(IntKi), PARAMETER :: EddShrT5N09D2 = 8606 + INTEGER(IntKi), PARAMETER :: EddShrT5N09D3 = 8607 + INTEGER(IntKi), PARAMETER :: EddShrT5N09D4 = 8608 + INTEGER(IntKi), PARAMETER :: EddShrT5N09D5 = 8609 + INTEGER(IntKi), PARAMETER :: EddShrT5N09D6 = 8610 + INTEGER(IntKi), PARAMETER :: EddShrT5N09D7 = 8611 + INTEGER(IntKi), PARAMETER :: EddShrT5N09D8 = 8612 + INTEGER(IntKi), PARAMETER :: EddShrT5N09D9 = 8613 + INTEGER(IntKi), PARAMETER :: EddShrT5N10D1 = 8614 + INTEGER(IntKi), PARAMETER :: EddShrT5N10D2 = 8615 + INTEGER(IntKi), PARAMETER :: EddShrT5N10D3 = 8616 + INTEGER(IntKi), PARAMETER :: EddShrT5N10D4 = 8617 + INTEGER(IntKi), PARAMETER :: EddShrT5N10D5 = 8618 + INTEGER(IntKi), PARAMETER :: EddShrT5N10D6 = 8619 + INTEGER(IntKi), PARAMETER :: EddShrT5N10D7 = 8620 + INTEGER(IntKi), PARAMETER :: EddShrT5N10D8 = 8621 + INTEGER(IntKi), PARAMETER :: EddShrT5N10D9 = 8622 + INTEGER(IntKi), PARAMETER :: EddShrT5N11D1 = 8623 + INTEGER(IntKi), PARAMETER :: EddShrT5N11D2 = 8624 + INTEGER(IntKi), PARAMETER :: EddShrT5N11D3 = 8625 + INTEGER(IntKi), PARAMETER :: EddShrT5N11D4 = 8626 + INTEGER(IntKi), PARAMETER :: EddShrT5N11D5 = 8627 + INTEGER(IntKi), PARAMETER :: EddShrT5N11D6 = 8628 + INTEGER(IntKi), PARAMETER :: EddShrT5N11D7 = 8629 + INTEGER(IntKi), PARAMETER :: EddShrT5N11D8 = 8630 + INTEGER(IntKi), PARAMETER :: EddShrT5N11D9 = 8631 + INTEGER(IntKi), PARAMETER :: EddShrT5N12D1 = 8632 + INTEGER(IntKi), PARAMETER :: EddShrT5N12D2 = 8633 + INTEGER(IntKi), PARAMETER :: EddShrT5N12D3 = 8634 + INTEGER(IntKi), PARAMETER :: EddShrT5N12D4 = 8635 + INTEGER(IntKi), PARAMETER :: EddShrT5N12D5 = 8636 + INTEGER(IntKi), PARAMETER :: EddShrT5N12D6 = 8637 + INTEGER(IntKi), PARAMETER :: EddShrT5N12D7 = 8638 + INTEGER(IntKi), PARAMETER :: EddShrT5N12D8 = 8639 + INTEGER(IntKi), PARAMETER :: EddShrT5N12D9 = 8640 + INTEGER(IntKi), PARAMETER :: EddShrT5N13D1 = 8641 + INTEGER(IntKi), PARAMETER :: EddShrT5N13D2 = 8642 + INTEGER(IntKi), PARAMETER :: EddShrT5N13D3 = 8643 + INTEGER(IntKi), PARAMETER :: EddShrT5N13D4 = 8644 + INTEGER(IntKi), PARAMETER :: EddShrT5N13D5 = 8645 + INTEGER(IntKi), PARAMETER :: EddShrT5N13D6 = 8646 + INTEGER(IntKi), PARAMETER :: EddShrT5N13D7 = 8647 + INTEGER(IntKi), PARAMETER :: EddShrT5N13D8 = 8648 + INTEGER(IntKi), PARAMETER :: EddShrT5N13D9 = 8649 + INTEGER(IntKi), PARAMETER :: EddShrT5N14D1 = 8650 + INTEGER(IntKi), PARAMETER :: EddShrT5N14D2 = 8651 + INTEGER(IntKi), PARAMETER :: EddShrT5N14D3 = 8652 + INTEGER(IntKi), PARAMETER :: EddShrT5N14D4 = 8653 + INTEGER(IntKi), PARAMETER :: EddShrT5N14D5 = 8654 + INTEGER(IntKi), PARAMETER :: EddShrT5N14D6 = 8655 + INTEGER(IntKi), PARAMETER :: EddShrT5N14D7 = 8656 + INTEGER(IntKi), PARAMETER :: EddShrT5N14D8 = 8657 + INTEGER(IntKi), PARAMETER :: EddShrT5N14D9 = 8658 + INTEGER(IntKi), PARAMETER :: EddShrT5N15D1 = 8659 + INTEGER(IntKi), PARAMETER :: EddShrT5N15D2 = 8660 + INTEGER(IntKi), PARAMETER :: EddShrT5N15D3 = 8661 + INTEGER(IntKi), PARAMETER :: EddShrT5N15D4 = 8662 + INTEGER(IntKi), PARAMETER :: EddShrT5N15D5 = 8663 + INTEGER(IntKi), PARAMETER :: EddShrT5N15D6 = 8664 + INTEGER(IntKi), PARAMETER :: EddShrT5N15D7 = 8665 + INTEGER(IntKi), PARAMETER :: EddShrT5N15D8 = 8666 + INTEGER(IntKi), PARAMETER :: EddShrT5N15D9 = 8667 + INTEGER(IntKi), PARAMETER :: EddShrT5N16D1 = 8668 + INTEGER(IntKi), PARAMETER :: EddShrT5N16D2 = 8669 + INTEGER(IntKi), PARAMETER :: EddShrT5N16D3 = 8670 + INTEGER(IntKi), PARAMETER :: EddShrT5N16D4 = 8671 + INTEGER(IntKi), PARAMETER :: EddShrT5N16D5 = 8672 + INTEGER(IntKi), PARAMETER :: EddShrT5N16D6 = 8673 + INTEGER(IntKi), PARAMETER :: EddShrT5N16D7 = 8674 + INTEGER(IntKi), PARAMETER :: EddShrT5N16D8 = 8675 + INTEGER(IntKi), PARAMETER :: EddShrT5N16D9 = 8676 + INTEGER(IntKi), PARAMETER :: EddShrT5N17D1 = 8677 + INTEGER(IntKi), PARAMETER :: EddShrT5N17D2 = 8678 + INTEGER(IntKi), PARAMETER :: EddShrT5N17D3 = 8679 + INTEGER(IntKi), PARAMETER :: EddShrT5N17D4 = 8680 + INTEGER(IntKi), PARAMETER :: EddShrT5N17D5 = 8681 + INTEGER(IntKi), PARAMETER :: EddShrT5N17D6 = 8682 + INTEGER(IntKi), PARAMETER :: EddShrT5N17D7 = 8683 + INTEGER(IntKi), PARAMETER :: EddShrT5N17D8 = 8684 + INTEGER(IntKi), PARAMETER :: EddShrT5N17D9 = 8685 + INTEGER(IntKi), PARAMETER :: EddShrT5N18D1 = 8686 + INTEGER(IntKi), PARAMETER :: EddShrT5N18D2 = 8687 + INTEGER(IntKi), PARAMETER :: EddShrT5N18D3 = 8688 + INTEGER(IntKi), PARAMETER :: EddShrT5N18D4 = 8689 + INTEGER(IntKi), PARAMETER :: EddShrT5N18D5 = 8690 + INTEGER(IntKi), PARAMETER :: EddShrT5N18D6 = 8691 + INTEGER(IntKi), PARAMETER :: EddShrT5N18D7 = 8692 + INTEGER(IntKi), PARAMETER :: EddShrT5N18D8 = 8693 + INTEGER(IntKi), PARAMETER :: EddShrT5N18D9 = 8694 + INTEGER(IntKi), PARAMETER :: EddShrT5N19D1 = 8695 + INTEGER(IntKi), PARAMETER :: EddShrT5N19D2 = 8696 + INTEGER(IntKi), PARAMETER :: EddShrT5N19D3 = 8697 + INTEGER(IntKi), PARAMETER :: EddShrT5N19D4 = 8698 + INTEGER(IntKi), PARAMETER :: EddShrT5N19D5 = 8699 + INTEGER(IntKi), PARAMETER :: EddShrT5N19D6 = 8700 + INTEGER(IntKi), PARAMETER :: EddShrT5N19D7 = 8701 + INTEGER(IntKi), PARAMETER :: EddShrT5N19D8 = 8702 + INTEGER(IntKi), PARAMETER :: EddShrT5N19D9 = 8703 + INTEGER(IntKi), PARAMETER :: EddShrT5N20D1 = 8704 + INTEGER(IntKi), PARAMETER :: EddShrT5N20D2 = 8705 + INTEGER(IntKi), PARAMETER :: EddShrT5N20D3 = 8706 + INTEGER(IntKi), PARAMETER :: EddShrT5N20D4 = 8707 + INTEGER(IntKi), PARAMETER :: EddShrT5N20D5 = 8708 + INTEGER(IntKi), PARAMETER :: EddShrT5N20D6 = 8709 + INTEGER(IntKi), PARAMETER :: EddShrT5N20D7 = 8710 + INTEGER(IntKi), PARAMETER :: EddShrT5N20D8 = 8711 + INTEGER(IntKi), PARAMETER :: EddShrT5N20D9 = 8712 + INTEGER(IntKi), PARAMETER :: EddShrT6N01D1 = 8713 + INTEGER(IntKi), PARAMETER :: EddShrT6N01D2 = 8714 + INTEGER(IntKi), PARAMETER :: EddShrT6N01D3 = 8715 + INTEGER(IntKi), PARAMETER :: EddShrT6N01D4 = 8716 + INTEGER(IntKi), PARAMETER :: EddShrT6N01D5 = 8717 + INTEGER(IntKi), PARAMETER :: EddShrT6N01D6 = 8718 + INTEGER(IntKi), PARAMETER :: EddShrT6N01D7 = 8719 + INTEGER(IntKi), PARAMETER :: EddShrT6N01D8 = 8720 + INTEGER(IntKi), PARAMETER :: EddShrT6N01D9 = 8721 + INTEGER(IntKi), PARAMETER :: EddShrT6N02D1 = 8722 + INTEGER(IntKi), PARAMETER :: EddShrT6N02D2 = 8723 + INTEGER(IntKi), PARAMETER :: EddShrT6N02D3 = 8724 + INTEGER(IntKi), PARAMETER :: EddShrT6N02D4 = 8725 + INTEGER(IntKi), PARAMETER :: EddShrT6N02D5 = 8726 + INTEGER(IntKi), PARAMETER :: EddShrT6N02D6 = 8727 + INTEGER(IntKi), PARAMETER :: EddShrT6N02D7 = 8728 + INTEGER(IntKi), PARAMETER :: EddShrT6N02D8 = 8729 + INTEGER(IntKi), PARAMETER :: EddShrT6N02D9 = 8730 + INTEGER(IntKi), PARAMETER :: EddShrT6N03D1 = 8731 + INTEGER(IntKi), PARAMETER :: EddShrT6N03D2 = 8732 + INTEGER(IntKi), PARAMETER :: EddShrT6N03D3 = 8733 + INTEGER(IntKi), PARAMETER :: EddShrT6N03D4 = 8734 + INTEGER(IntKi), PARAMETER :: EddShrT6N03D5 = 8735 + INTEGER(IntKi), PARAMETER :: EddShrT6N03D6 = 8736 + INTEGER(IntKi), PARAMETER :: EddShrT6N03D7 = 8737 + INTEGER(IntKi), PARAMETER :: EddShrT6N03D8 = 8738 + INTEGER(IntKi), PARAMETER :: EddShrT6N03D9 = 8739 + INTEGER(IntKi), PARAMETER :: EddShrT6N04D1 = 8740 + INTEGER(IntKi), PARAMETER :: EddShrT6N04D2 = 8741 + INTEGER(IntKi), PARAMETER :: EddShrT6N04D3 = 8742 + INTEGER(IntKi), PARAMETER :: EddShrT6N04D4 = 8743 + INTEGER(IntKi), PARAMETER :: EddShrT6N04D5 = 8744 + INTEGER(IntKi), PARAMETER :: EddShrT6N04D6 = 8745 + INTEGER(IntKi), PARAMETER :: EddShrT6N04D7 = 8746 + INTEGER(IntKi), PARAMETER :: EddShrT6N04D8 = 8747 + INTEGER(IntKi), PARAMETER :: EddShrT6N04D9 = 8748 + INTEGER(IntKi), PARAMETER :: EddShrT6N05D1 = 8749 + INTEGER(IntKi), PARAMETER :: EddShrT6N05D2 = 8750 + INTEGER(IntKi), PARAMETER :: EddShrT6N05D3 = 8751 + INTEGER(IntKi), PARAMETER :: EddShrT6N05D4 = 8752 + INTEGER(IntKi), PARAMETER :: EddShrT6N05D5 = 8753 + INTEGER(IntKi), PARAMETER :: EddShrT6N05D6 = 8754 + INTEGER(IntKi), PARAMETER :: EddShrT6N05D7 = 8755 + INTEGER(IntKi), PARAMETER :: EddShrT6N05D8 = 8756 + INTEGER(IntKi), PARAMETER :: EddShrT6N05D9 = 8757 + INTEGER(IntKi), PARAMETER :: EddShrT6N06D1 = 8758 + INTEGER(IntKi), PARAMETER :: EddShrT6N06D2 = 8759 + INTEGER(IntKi), PARAMETER :: EddShrT6N06D3 = 8760 + INTEGER(IntKi), PARAMETER :: EddShrT6N06D4 = 8761 + INTEGER(IntKi), PARAMETER :: EddShrT6N06D5 = 8762 + INTEGER(IntKi), PARAMETER :: EddShrT6N06D6 = 8763 + INTEGER(IntKi), PARAMETER :: EddShrT6N06D7 = 8764 + INTEGER(IntKi), PARAMETER :: EddShrT6N06D8 = 8765 + INTEGER(IntKi), PARAMETER :: EddShrT6N06D9 = 8766 + INTEGER(IntKi), PARAMETER :: EddShrT6N07D1 = 8767 + INTEGER(IntKi), PARAMETER :: EddShrT6N07D2 = 8768 + INTEGER(IntKi), PARAMETER :: EddShrT6N07D3 = 8769 + INTEGER(IntKi), PARAMETER :: EddShrT6N07D4 = 8770 + INTEGER(IntKi), PARAMETER :: EddShrT6N07D5 = 8771 + INTEGER(IntKi), PARAMETER :: EddShrT6N07D6 = 8772 + INTEGER(IntKi), PARAMETER :: EddShrT6N07D7 = 8773 + INTEGER(IntKi), PARAMETER :: EddShrT6N07D8 = 8774 + INTEGER(IntKi), PARAMETER :: EddShrT6N07D9 = 8775 + INTEGER(IntKi), PARAMETER :: EddShrT6N08D1 = 8776 + INTEGER(IntKi), PARAMETER :: EddShrT6N08D2 = 8777 + INTEGER(IntKi), PARAMETER :: EddShrT6N08D3 = 8778 + INTEGER(IntKi), PARAMETER :: EddShrT6N08D4 = 8779 + INTEGER(IntKi), PARAMETER :: EddShrT6N08D5 = 8780 + INTEGER(IntKi), PARAMETER :: EddShrT6N08D6 = 8781 + INTEGER(IntKi), PARAMETER :: EddShrT6N08D7 = 8782 + INTEGER(IntKi), PARAMETER :: EddShrT6N08D8 = 8783 + INTEGER(IntKi), PARAMETER :: EddShrT6N08D9 = 8784 + INTEGER(IntKi), PARAMETER :: EddShrT6N09D1 = 8785 + INTEGER(IntKi), PARAMETER :: EddShrT6N09D2 = 8786 + INTEGER(IntKi), PARAMETER :: EddShrT6N09D3 = 8787 + INTEGER(IntKi), PARAMETER :: EddShrT6N09D4 = 8788 + INTEGER(IntKi), PARAMETER :: EddShrT6N09D5 = 8789 + INTEGER(IntKi), PARAMETER :: EddShrT6N09D6 = 8790 + INTEGER(IntKi), PARAMETER :: EddShrT6N09D7 = 8791 + INTEGER(IntKi), PARAMETER :: EddShrT6N09D8 = 8792 + INTEGER(IntKi), PARAMETER :: EddShrT6N09D9 = 8793 + INTEGER(IntKi), PARAMETER :: EddShrT6N10D1 = 8794 + INTEGER(IntKi), PARAMETER :: EddShrT6N10D2 = 8795 + INTEGER(IntKi), PARAMETER :: EddShrT6N10D3 = 8796 + INTEGER(IntKi), PARAMETER :: EddShrT6N10D4 = 8797 + INTEGER(IntKi), PARAMETER :: EddShrT6N10D5 = 8798 + INTEGER(IntKi), PARAMETER :: EddShrT6N10D6 = 8799 + INTEGER(IntKi), PARAMETER :: EddShrT6N10D7 = 8800 + INTEGER(IntKi), PARAMETER :: EddShrT6N10D8 = 8801 + INTEGER(IntKi), PARAMETER :: EddShrT6N10D9 = 8802 + INTEGER(IntKi), PARAMETER :: EddShrT6N11D1 = 8803 + INTEGER(IntKi), PARAMETER :: EddShrT6N11D2 = 8804 + INTEGER(IntKi), PARAMETER :: EddShrT6N11D3 = 8805 + INTEGER(IntKi), PARAMETER :: EddShrT6N11D4 = 8806 + INTEGER(IntKi), PARAMETER :: EddShrT6N11D5 = 8807 + INTEGER(IntKi), PARAMETER :: EddShrT6N11D6 = 8808 + INTEGER(IntKi), PARAMETER :: EddShrT6N11D7 = 8809 + INTEGER(IntKi), PARAMETER :: EddShrT6N11D8 = 8810 + INTEGER(IntKi), PARAMETER :: EddShrT6N11D9 = 8811 + INTEGER(IntKi), PARAMETER :: EddShrT6N12D1 = 8812 + INTEGER(IntKi), PARAMETER :: EddShrT6N12D2 = 8813 + INTEGER(IntKi), PARAMETER :: EddShrT6N12D3 = 8814 + INTEGER(IntKi), PARAMETER :: EddShrT6N12D4 = 8815 + INTEGER(IntKi), PARAMETER :: EddShrT6N12D5 = 8816 + INTEGER(IntKi), PARAMETER :: EddShrT6N12D6 = 8817 + INTEGER(IntKi), PARAMETER :: EddShrT6N12D7 = 8818 + INTEGER(IntKi), PARAMETER :: EddShrT6N12D8 = 8819 + INTEGER(IntKi), PARAMETER :: EddShrT6N12D9 = 8820 + INTEGER(IntKi), PARAMETER :: EddShrT6N13D1 = 8821 + INTEGER(IntKi), PARAMETER :: EddShrT6N13D2 = 8822 + INTEGER(IntKi), PARAMETER :: EddShrT6N13D3 = 8823 + INTEGER(IntKi), PARAMETER :: EddShrT6N13D4 = 8824 + INTEGER(IntKi), PARAMETER :: EddShrT6N13D5 = 8825 + INTEGER(IntKi), PARAMETER :: EddShrT6N13D6 = 8826 + INTEGER(IntKi), PARAMETER :: EddShrT6N13D7 = 8827 + INTEGER(IntKi), PARAMETER :: EddShrT6N13D8 = 8828 + INTEGER(IntKi), PARAMETER :: EddShrT6N13D9 = 8829 + INTEGER(IntKi), PARAMETER :: EddShrT6N14D1 = 8830 + INTEGER(IntKi), PARAMETER :: EddShrT6N14D2 = 8831 + INTEGER(IntKi), PARAMETER :: EddShrT6N14D3 = 8832 + INTEGER(IntKi), PARAMETER :: EddShrT6N14D4 = 8833 + INTEGER(IntKi), PARAMETER :: EddShrT6N14D5 = 8834 + INTEGER(IntKi), PARAMETER :: EddShrT6N14D6 = 8835 + INTEGER(IntKi), PARAMETER :: EddShrT6N14D7 = 8836 + INTEGER(IntKi), PARAMETER :: EddShrT6N14D8 = 8837 + INTEGER(IntKi), PARAMETER :: EddShrT6N14D9 = 8838 + INTEGER(IntKi), PARAMETER :: EddShrT6N15D1 = 8839 + INTEGER(IntKi), PARAMETER :: EddShrT6N15D2 = 8840 + INTEGER(IntKi), PARAMETER :: EddShrT6N15D3 = 8841 + INTEGER(IntKi), PARAMETER :: EddShrT6N15D4 = 8842 + INTEGER(IntKi), PARAMETER :: EddShrT6N15D5 = 8843 + INTEGER(IntKi), PARAMETER :: EddShrT6N15D6 = 8844 + INTEGER(IntKi), PARAMETER :: EddShrT6N15D7 = 8845 + INTEGER(IntKi), PARAMETER :: EddShrT6N15D8 = 8846 + INTEGER(IntKi), PARAMETER :: EddShrT6N15D9 = 8847 + INTEGER(IntKi), PARAMETER :: EddShrT6N16D1 = 8848 + INTEGER(IntKi), PARAMETER :: EddShrT6N16D2 = 8849 + INTEGER(IntKi), PARAMETER :: EddShrT6N16D3 = 8850 + INTEGER(IntKi), PARAMETER :: EddShrT6N16D4 = 8851 + INTEGER(IntKi), PARAMETER :: EddShrT6N16D5 = 8852 + INTEGER(IntKi), PARAMETER :: EddShrT6N16D6 = 8853 + INTEGER(IntKi), PARAMETER :: EddShrT6N16D7 = 8854 + INTEGER(IntKi), PARAMETER :: EddShrT6N16D8 = 8855 + INTEGER(IntKi), PARAMETER :: EddShrT6N16D9 = 8856 + INTEGER(IntKi), PARAMETER :: EddShrT6N17D1 = 8857 + INTEGER(IntKi), PARAMETER :: EddShrT6N17D2 = 8858 + INTEGER(IntKi), PARAMETER :: EddShrT6N17D3 = 8859 + INTEGER(IntKi), PARAMETER :: EddShrT6N17D4 = 8860 + INTEGER(IntKi), PARAMETER :: EddShrT6N17D5 = 8861 + INTEGER(IntKi), PARAMETER :: EddShrT6N17D6 = 8862 + INTEGER(IntKi), PARAMETER :: EddShrT6N17D7 = 8863 + INTEGER(IntKi), PARAMETER :: EddShrT6N17D8 = 8864 + INTEGER(IntKi), PARAMETER :: EddShrT6N17D9 = 8865 + INTEGER(IntKi), PARAMETER :: EddShrT6N18D1 = 8866 + INTEGER(IntKi), PARAMETER :: EddShrT6N18D2 = 8867 + INTEGER(IntKi), PARAMETER :: EddShrT6N18D3 = 8868 + INTEGER(IntKi), PARAMETER :: EddShrT6N18D4 = 8869 + INTEGER(IntKi), PARAMETER :: EddShrT6N18D5 = 8870 + INTEGER(IntKi), PARAMETER :: EddShrT6N18D6 = 8871 + INTEGER(IntKi), PARAMETER :: EddShrT6N18D7 = 8872 + INTEGER(IntKi), PARAMETER :: EddShrT6N18D8 = 8873 + INTEGER(IntKi), PARAMETER :: EddShrT6N18D9 = 8874 + INTEGER(IntKi), PARAMETER :: EddShrT6N19D1 = 8875 + INTEGER(IntKi), PARAMETER :: EddShrT6N19D2 = 8876 + INTEGER(IntKi), PARAMETER :: EddShrT6N19D3 = 8877 + INTEGER(IntKi), PARAMETER :: EddShrT6N19D4 = 8878 + INTEGER(IntKi), PARAMETER :: EddShrT6N19D5 = 8879 + INTEGER(IntKi), PARAMETER :: EddShrT6N19D6 = 8880 + INTEGER(IntKi), PARAMETER :: EddShrT6N19D7 = 8881 + INTEGER(IntKi), PARAMETER :: EddShrT6N19D8 = 8882 + INTEGER(IntKi), PARAMETER :: EddShrT6N19D9 = 8883 + INTEGER(IntKi), PARAMETER :: EddShrT6N20D1 = 8884 + INTEGER(IntKi), PARAMETER :: EddShrT6N20D2 = 8885 + INTEGER(IntKi), PARAMETER :: EddShrT6N20D3 = 8886 + INTEGER(IntKi), PARAMETER :: EddShrT6N20D4 = 8887 + INTEGER(IntKi), PARAMETER :: EddShrT6N20D5 = 8888 + INTEGER(IntKi), PARAMETER :: EddShrT6N20D6 = 8889 + INTEGER(IntKi), PARAMETER :: EddShrT6N20D7 = 8890 + INTEGER(IntKi), PARAMETER :: EddShrT6N20D8 = 8891 + INTEGER(IntKi), PARAMETER :: EddShrT6N20D9 = 8892 + INTEGER(IntKi), PARAMETER :: EddShrT7N01D1 = 8893 + INTEGER(IntKi), PARAMETER :: EddShrT7N01D2 = 8894 + INTEGER(IntKi), PARAMETER :: EddShrT7N01D3 = 8895 + INTEGER(IntKi), PARAMETER :: EddShrT7N01D4 = 8896 + INTEGER(IntKi), PARAMETER :: EddShrT7N01D5 = 8897 + INTEGER(IntKi), PARAMETER :: EddShrT7N01D6 = 8898 + INTEGER(IntKi), PARAMETER :: EddShrT7N01D7 = 8899 + INTEGER(IntKi), PARAMETER :: EddShrT7N01D8 = 8900 + INTEGER(IntKi), PARAMETER :: EddShrT7N01D9 = 8901 + INTEGER(IntKi), PARAMETER :: EddShrT7N02D1 = 8902 + INTEGER(IntKi), PARAMETER :: EddShrT7N02D2 = 8903 + INTEGER(IntKi), PARAMETER :: EddShrT7N02D3 = 8904 + INTEGER(IntKi), PARAMETER :: EddShrT7N02D4 = 8905 + INTEGER(IntKi), PARAMETER :: EddShrT7N02D5 = 8906 + INTEGER(IntKi), PARAMETER :: EddShrT7N02D6 = 8907 + INTEGER(IntKi), PARAMETER :: EddShrT7N02D7 = 8908 + INTEGER(IntKi), PARAMETER :: EddShrT7N02D8 = 8909 + INTEGER(IntKi), PARAMETER :: EddShrT7N02D9 = 8910 + INTEGER(IntKi), PARAMETER :: EddShrT7N03D1 = 8911 + INTEGER(IntKi), PARAMETER :: EddShrT7N03D2 = 8912 + INTEGER(IntKi), PARAMETER :: EddShrT7N03D3 = 8913 + INTEGER(IntKi), PARAMETER :: EddShrT7N03D4 = 8914 + INTEGER(IntKi), PARAMETER :: EddShrT7N03D5 = 8915 + INTEGER(IntKi), PARAMETER :: EddShrT7N03D6 = 8916 + INTEGER(IntKi), PARAMETER :: EddShrT7N03D7 = 8917 + INTEGER(IntKi), PARAMETER :: EddShrT7N03D8 = 8918 + INTEGER(IntKi), PARAMETER :: EddShrT7N03D9 = 8919 + INTEGER(IntKi), PARAMETER :: EddShrT7N04D1 = 8920 + INTEGER(IntKi), PARAMETER :: EddShrT7N04D2 = 8921 + INTEGER(IntKi), PARAMETER :: EddShrT7N04D3 = 8922 + INTEGER(IntKi), PARAMETER :: EddShrT7N04D4 = 8923 + INTEGER(IntKi), PARAMETER :: EddShrT7N04D5 = 8924 + INTEGER(IntKi), PARAMETER :: EddShrT7N04D6 = 8925 + INTEGER(IntKi), PARAMETER :: EddShrT7N04D7 = 8926 + INTEGER(IntKi), PARAMETER :: EddShrT7N04D8 = 8927 + INTEGER(IntKi), PARAMETER :: EddShrT7N04D9 = 8928 + INTEGER(IntKi), PARAMETER :: EddShrT7N05D1 = 8929 + INTEGER(IntKi), PARAMETER :: EddShrT7N05D2 = 8930 + INTEGER(IntKi), PARAMETER :: EddShrT7N05D3 = 8931 + INTEGER(IntKi), PARAMETER :: EddShrT7N05D4 = 8932 + INTEGER(IntKi), PARAMETER :: EddShrT7N05D5 = 8933 + INTEGER(IntKi), PARAMETER :: EddShrT7N05D6 = 8934 + INTEGER(IntKi), PARAMETER :: EddShrT7N05D7 = 8935 + INTEGER(IntKi), PARAMETER :: EddShrT7N05D8 = 8936 + INTEGER(IntKi), PARAMETER :: EddShrT7N05D9 = 8937 + INTEGER(IntKi), PARAMETER :: EddShrT7N06D1 = 8938 + INTEGER(IntKi), PARAMETER :: EddShrT7N06D2 = 8939 + INTEGER(IntKi), PARAMETER :: EddShrT7N06D3 = 8940 + INTEGER(IntKi), PARAMETER :: EddShrT7N06D4 = 8941 + INTEGER(IntKi), PARAMETER :: EddShrT7N06D5 = 8942 + INTEGER(IntKi), PARAMETER :: EddShrT7N06D6 = 8943 + INTEGER(IntKi), PARAMETER :: EddShrT7N06D7 = 8944 + INTEGER(IntKi), PARAMETER :: EddShrT7N06D8 = 8945 + INTEGER(IntKi), PARAMETER :: EddShrT7N06D9 = 8946 + INTEGER(IntKi), PARAMETER :: EddShrT7N07D1 = 8947 + INTEGER(IntKi), PARAMETER :: EddShrT7N07D2 = 8948 + INTEGER(IntKi), PARAMETER :: EddShrT7N07D3 = 8949 + INTEGER(IntKi), PARAMETER :: EddShrT7N07D4 = 8950 + INTEGER(IntKi), PARAMETER :: EddShrT7N07D5 = 8951 + INTEGER(IntKi), PARAMETER :: EddShrT7N07D6 = 8952 + INTEGER(IntKi), PARAMETER :: EddShrT7N07D7 = 8953 + INTEGER(IntKi), PARAMETER :: EddShrT7N07D8 = 8954 + INTEGER(IntKi), PARAMETER :: EddShrT7N07D9 = 8955 + INTEGER(IntKi), PARAMETER :: EddShrT7N08D1 = 8956 + INTEGER(IntKi), PARAMETER :: EddShrT7N08D2 = 8957 + INTEGER(IntKi), PARAMETER :: EddShrT7N08D3 = 8958 + INTEGER(IntKi), PARAMETER :: EddShrT7N08D4 = 8959 + INTEGER(IntKi), PARAMETER :: EddShrT7N08D5 = 8960 + INTEGER(IntKi), PARAMETER :: EddShrT7N08D6 = 8961 + INTEGER(IntKi), PARAMETER :: EddShrT7N08D7 = 8962 + INTEGER(IntKi), PARAMETER :: EddShrT7N08D8 = 8963 + INTEGER(IntKi), PARAMETER :: EddShrT7N08D9 = 8964 + INTEGER(IntKi), PARAMETER :: EddShrT7N09D1 = 8965 + INTEGER(IntKi), PARAMETER :: EddShrT7N09D2 = 8966 + INTEGER(IntKi), PARAMETER :: EddShrT7N09D3 = 8967 + INTEGER(IntKi), PARAMETER :: EddShrT7N09D4 = 8968 + INTEGER(IntKi), PARAMETER :: EddShrT7N09D5 = 8969 + INTEGER(IntKi), PARAMETER :: EddShrT7N09D6 = 8970 + INTEGER(IntKi), PARAMETER :: EddShrT7N09D7 = 8971 + INTEGER(IntKi), PARAMETER :: EddShrT7N09D8 = 8972 + INTEGER(IntKi), PARAMETER :: EddShrT7N09D9 = 8973 + INTEGER(IntKi), PARAMETER :: EddShrT7N10D1 = 8974 + INTEGER(IntKi), PARAMETER :: EddShrT7N10D2 = 8975 + INTEGER(IntKi), PARAMETER :: EddShrT7N10D3 = 8976 + INTEGER(IntKi), PARAMETER :: EddShrT7N10D4 = 8977 + INTEGER(IntKi), PARAMETER :: EddShrT7N10D5 = 8978 + INTEGER(IntKi), PARAMETER :: EddShrT7N10D6 = 8979 + INTEGER(IntKi), PARAMETER :: EddShrT7N10D7 = 8980 + INTEGER(IntKi), PARAMETER :: EddShrT7N10D8 = 8981 + INTEGER(IntKi), PARAMETER :: EddShrT7N10D9 = 8982 + INTEGER(IntKi), PARAMETER :: EddShrT7N11D1 = 8983 + INTEGER(IntKi), PARAMETER :: EddShrT7N11D2 = 8984 + INTEGER(IntKi), PARAMETER :: EddShrT7N11D3 = 8985 + INTEGER(IntKi), PARAMETER :: EddShrT7N11D4 = 8986 + INTEGER(IntKi), PARAMETER :: EddShrT7N11D5 = 8987 + INTEGER(IntKi), PARAMETER :: EddShrT7N11D6 = 8988 + INTEGER(IntKi), PARAMETER :: EddShrT7N11D7 = 8989 + INTEGER(IntKi), PARAMETER :: EddShrT7N11D8 = 8990 + INTEGER(IntKi), PARAMETER :: EddShrT7N11D9 = 8991 + INTEGER(IntKi), PARAMETER :: EddShrT7N12D1 = 8992 + INTEGER(IntKi), PARAMETER :: EddShrT7N12D2 = 8993 + INTEGER(IntKi), PARAMETER :: EddShrT7N12D3 = 8994 + INTEGER(IntKi), PARAMETER :: EddShrT7N12D4 = 8995 + INTEGER(IntKi), PARAMETER :: EddShrT7N12D5 = 8996 + INTEGER(IntKi), PARAMETER :: EddShrT7N12D6 = 8997 + INTEGER(IntKi), PARAMETER :: EddShrT7N12D7 = 8998 + INTEGER(IntKi), PARAMETER :: EddShrT7N12D8 = 8999 + INTEGER(IntKi), PARAMETER :: EddShrT7N12D9 = 9000 + INTEGER(IntKi), PARAMETER :: EddShrT7N13D1 = 9001 + INTEGER(IntKi), PARAMETER :: EddShrT7N13D2 = 9002 + INTEGER(IntKi), PARAMETER :: EddShrT7N13D3 = 9003 + INTEGER(IntKi), PARAMETER :: EddShrT7N13D4 = 9004 + INTEGER(IntKi), PARAMETER :: EddShrT7N13D5 = 9005 + INTEGER(IntKi), PARAMETER :: EddShrT7N13D6 = 9006 + INTEGER(IntKi), PARAMETER :: EddShrT7N13D7 = 9007 + INTEGER(IntKi), PARAMETER :: EddShrT7N13D8 = 9008 + INTEGER(IntKi), PARAMETER :: EddShrT7N13D9 = 9009 + INTEGER(IntKi), PARAMETER :: EddShrT7N14D1 = 9010 + INTEGER(IntKi), PARAMETER :: EddShrT7N14D2 = 9011 + INTEGER(IntKi), PARAMETER :: EddShrT7N14D3 = 9012 + INTEGER(IntKi), PARAMETER :: EddShrT7N14D4 = 9013 + INTEGER(IntKi), PARAMETER :: EddShrT7N14D5 = 9014 + INTEGER(IntKi), PARAMETER :: EddShrT7N14D6 = 9015 + INTEGER(IntKi), PARAMETER :: EddShrT7N14D7 = 9016 + INTEGER(IntKi), PARAMETER :: EddShrT7N14D8 = 9017 + INTEGER(IntKi), PARAMETER :: EddShrT7N14D9 = 9018 + INTEGER(IntKi), PARAMETER :: EddShrT7N15D1 = 9019 + INTEGER(IntKi), PARAMETER :: EddShrT7N15D2 = 9020 + INTEGER(IntKi), PARAMETER :: EddShrT7N15D3 = 9021 + INTEGER(IntKi), PARAMETER :: EddShrT7N15D4 = 9022 + INTEGER(IntKi), PARAMETER :: EddShrT7N15D5 = 9023 + INTEGER(IntKi), PARAMETER :: EddShrT7N15D6 = 9024 + INTEGER(IntKi), PARAMETER :: EddShrT7N15D7 = 9025 + INTEGER(IntKi), PARAMETER :: EddShrT7N15D8 = 9026 + INTEGER(IntKi), PARAMETER :: EddShrT7N15D9 = 9027 + INTEGER(IntKi), PARAMETER :: EddShrT7N16D1 = 9028 + INTEGER(IntKi), PARAMETER :: EddShrT7N16D2 = 9029 + INTEGER(IntKi), PARAMETER :: EddShrT7N16D3 = 9030 + INTEGER(IntKi), PARAMETER :: EddShrT7N16D4 = 9031 + INTEGER(IntKi), PARAMETER :: EddShrT7N16D5 = 9032 + INTEGER(IntKi), PARAMETER :: EddShrT7N16D6 = 9033 + INTEGER(IntKi), PARAMETER :: EddShrT7N16D7 = 9034 + INTEGER(IntKi), PARAMETER :: EddShrT7N16D8 = 9035 + INTEGER(IntKi), PARAMETER :: EddShrT7N16D9 = 9036 + INTEGER(IntKi), PARAMETER :: EddShrT7N17D1 = 9037 + INTEGER(IntKi), PARAMETER :: EddShrT7N17D2 = 9038 + INTEGER(IntKi), PARAMETER :: EddShrT7N17D3 = 9039 + INTEGER(IntKi), PARAMETER :: EddShrT7N17D4 = 9040 + INTEGER(IntKi), PARAMETER :: EddShrT7N17D5 = 9041 + INTEGER(IntKi), PARAMETER :: EddShrT7N17D6 = 9042 + INTEGER(IntKi), PARAMETER :: EddShrT7N17D7 = 9043 + INTEGER(IntKi), PARAMETER :: EddShrT7N17D8 = 9044 + INTEGER(IntKi), PARAMETER :: EddShrT7N17D9 = 9045 + INTEGER(IntKi), PARAMETER :: EddShrT7N18D1 = 9046 + INTEGER(IntKi), PARAMETER :: EddShrT7N18D2 = 9047 + INTEGER(IntKi), PARAMETER :: EddShrT7N18D3 = 9048 + INTEGER(IntKi), PARAMETER :: EddShrT7N18D4 = 9049 + INTEGER(IntKi), PARAMETER :: EddShrT7N18D5 = 9050 + INTEGER(IntKi), PARAMETER :: EddShrT7N18D6 = 9051 + INTEGER(IntKi), PARAMETER :: EddShrT7N18D7 = 9052 + INTEGER(IntKi), PARAMETER :: EddShrT7N18D8 = 9053 + INTEGER(IntKi), PARAMETER :: EddShrT7N18D9 = 9054 + INTEGER(IntKi), PARAMETER :: EddShrT7N19D1 = 9055 + INTEGER(IntKi), PARAMETER :: EddShrT7N19D2 = 9056 + INTEGER(IntKi), PARAMETER :: EddShrT7N19D3 = 9057 + INTEGER(IntKi), PARAMETER :: EddShrT7N19D4 = 9058 + INTEGER(IntKi), PARAMETER :: EddShrT7N19D5 = 9059 + INTEGER(IntKi), PARAMETER :: EddShrT7N19D6 = 9060 + INTEGER(IntKi), PARAMETER :: EddShrT7N19D7 = 9061 + INTEGER(IntKi), PARAMETER :: EddShrT7N19D8 = 9062 + INTEGER(IntKi), PARAMETER :: EddShrT7N19D9 = 9063 + INTEGER(IntKi), PARAMETER :: EddShrT7N20D1 = 9064 + INTEGER(IntKi), PARAMETER :: EddShrT7N20D2 = 9065 + INTEGER(IntKi), PARAMETER :: EddShrT7N20D3 = 9066 + INTEGER(IntKi), PARAMETER :: EddShrT7N20D4 = 9067 + INTEGER(IntKi), PARAMETER :: EddShrT7N20D5 = 9068 + INTEGER(IntKi), PARAMETER :: EddShrT7N20D6 = 9069 + INTEGER(IntKi), PARAMETER :: EddShrT7N20D7 = 9070 + INTEGER(IntKi), PARAMETER :: EddShrT7N20D8 = 9071 + INTEGER(IntKi), PARAMETER :: EddShrT7N20D9 = 9072 + INTEGER(IntKi), PARAMETER :: EddShrT8N01D1 = 9073 + INTEGER(IntKi), PARAMETER :: EddShrT8N01D2 = 9074 + INTEGER(IntKi), PARAMETER :: EddShrT8N01D3 = 9075 + INTEGER(IntKi), PARAMETER :: EddShrT8N01D4 = 9076 + INTEGER(IntKi), PARAMETER :: EddShrT8N01D5 = 9077 + INTEGER(IntKi), PARAMETER :: EddShrT8N01D6 = 9078 + INTEGER(IntKi), PARAMETER :: EddShrT8N01D7 = 9079 + INTEGER(IntKi), PARAMETER :: EddShrT8N01D8 = 9080 + INTEGER(IntKi), PARAMETER :: EddShrT8N01D9 = 9081 + INTEGER(IntKi), PARAMETER :: EddShrT8N02D1 = 9082 + INTEGER(IntKi), PARAMETER :: EddShrT8N02D2 = 9083 + INTEGER(IntKi), PARAMETER :: EddShrT8N02D3 = 9084 + INTEGER(IntKi), PARAMETER :: EddShrT8N02D4 = 9085 + INTEGER(IntKi), PARAMETER :: EddShrT8N02D5 = 9086 + INTEGER(IntKi), PARAMETER :: EddShrT8N02D6 = 9087 + INTEGER(IntKi), PARAMETER :: EddShrT8N02D7 = 9088 + INTEGER(IntKi), PARAMETER :: EddShrT8N02D8 = 9089 + INTEGER(IntKi), PARAMETER :: EddShrT8N02D9 = 9090 + INTEGER(IntKi), PARAMETER :: EddShrT8N03D1 = 9091 + INTEGER(IntKi), PARAMETER :: EddShrT8N03D2 = 9092 + INTEGER(IntKi), PARAMETER :: EddShrT8N03D3 = 9093 + INTEGER(IntKi), PARAMETER :: EddShrT8N03D4 = 9094 + INTEGER(IntKi), PARAMETER :: EddShrT8N03D5 = 9095 + INTEGER(IntKi), PARAMETER :: EddShrT8N03D6 = 9096 + INTEGER(IntKi), PARAMETER :: EddShrT8N03D7 = 9097 + INTEGER(IntKi), PARAMETER :: EddShrT8N03D8 = 9098 + INTEGER(IntKi), PARAMETER :: EddShrT8N03D9 = 9099 + INTEGER(IntKi), PARAMETER :: EddShrT8N04D1 = 9100 + INTEGER(IntKi), PARAMETER :: EddShrT8N04D2 = 9101 + INTEGER(IntKi), PARAMETER :: EddShrT8N04D3 = 9102 + INTEGER(IntKi), PARAMETER :: EddShrT8N04D4 = 9103 + INTEGER(IntKi), PARAMETER :: EddShrT8N04D5 = 9104 + INTEGER(IntKi), PARAMETER :: EddShrT8N04D6 = 9105 + INTEGER(IntKi), PARAMETER :: EddShrT8N04D7 = 9106 + INTEGER(IntKi), PARAMETER :: EddShrT8N04D8 = 9107 + INTEGER(IntKi), PARAMETER :: EddShrT8N04D9 = 9108 + INTEGER(IntKi), PARAMETER :: EddShrT8N05D1 = 9109 + INTEGER(IntKi), PARAMETER :: EddShrT8N05D2 = 9110 + INTEGER(IntKi), PARAMETER :: EddShrT8N05D3 = 9111 + INTEGER(IntKi), PARAMETER :: EddShrT8N05D4 = 9112 + INTEGER(IntKi), PARAMETER :: EddShrT8N05D5 = 9113 + INTEGER(IntKi), PARAMETER :: EddShrT8N05D6 = 9114 + INTEGER(IntKi), PARAMETER :: EddShrT8N05D7 = 9115 + INTEGER(IntKi), PARAMETER :: EddShrT8N05D8 = 9116 + INTEGER(IntKi), PARAMETER :: EddShrT8N05D9 = 9117 + INTEGER(IntKi), PARAMETER :: EddShrT8N06D1 = 9118 + INTEGER(IntKi), PARAMETER :: EddShrT8N06D2 = 9119 + INTEGER(IntKi), PARAMETER :: EddShrT8N06D3 = 9120 + INTEGER(IntKi), PARAMETER :: EddShrT8N06D4 = 9121 + INTEGER(IntKi), PARAMETER :: EddShrT8N06D5 = 9122 + INTEGER(IntKi), PARAMETER :: EddShrT8N06D6 = 9123 + INTEGER(IntKi), PARAMETER :: EddShrT8N06D7 = 9124 + INTEGER(IntKi), PARAMETER :: EddShrT8N06D8 = 9125 + INTEGER(IntKi), PARAMETER :: EddShrT8N06D9 = 9126 + INTEGER(IntKi), PARAMETER :: EddShrT8N07D1 = 9127 + INTEGER(IntKi), PARAMETER :: EddShrT8N07D2 = 9128 + INTEGER(IntKi), PARAMETER :: EddShrT8N07D3 = 9129 + INTEGER(IntKi), PARAMETER :: EddShrT8N07D4 = 9130 + INTEGER(IntKi), PARAMETER :: EddShrT8N07D5 = 9131 + INTEGER(IntKi), PARAMETER :: EddShrT8N07D6 = 9132 + INTEGER(IntKi), PARAMETER :: EddShrT8N07D7 = 9133 + INTEGER(IntKi), PARAMETER :: EddShrT8N07D8 = 9134 + INTEGER(IntKi), PARAMETER :: EddShrT8N07D9 = 9135 + INTEGER(IntKi), PARAMETER :: EddShrT8N08D1 = 9136 + INTEGER(IntKi), PARAMETER :: EddShrT8N08D2 = 9137 + INTEGER(IntKi), PARAMETER :: EddShrT8N08D3 = 9138 + INTEGER(IntKi), PARAMETER :: EddShrT8N08D4 = 9139 + INTEGER(IntKi), PARAMETER :: EddShrT8N08D5 = 9140 + INTEGER(IntKi), PARAMETER :: EddShrT8N08D6 = 9141 + INTEGER(IntKi), PARAMETER :: EddShrT8N08D7 = 9142 + INTEGER(IntKi), PARAMETER :: EddShrT8N08D8 = 9143 + INTEGER(IntKi), PARAMETER :: EddShrT8N08D9 = 9144 + INTEGER(IntKi), PARAMETER :: EddShrT8N09D1 = 9145 + INTEGER(IntKi), PARAMETER :: EddShrT8N09D2 = 9146 + INTEGER(IntKi), PARAMETER :: EddShrT8N09D3 = 9147 + INTEGER(IntKi), PARAMETER :: EddShrT8N09D4 = 9148 + INTEGER(IntKi), PARAMETER :: EddShrT8N09D5 = 9149 + INTEGER(IntKi), PARAMETER :: EddShrT8N09D6 = 9150 + INTEGER(IntKi), PARAMETER :: EddShrT8N09D7 = 9151 + INTEGER(IntKi), PARAMETER :: EddShrT8N09D8 = 9152 + INTEGER(IntKi), PARAMETER :: EddShrT8N09D9 = 9153 + INTEGER(IntKi), PARAMETER :: EddShrT8N10D1 = 9154 + INTEGER(IntKi), PARAMETER :: EddShrT8N10D2 = 9155 + INTEGER(IntKi), PARAMETER :: EddShrT8N10D3 = 9156 + INTEGER(IntKi), PARAMETER :: EddShrT8N10D4 = 9157 + INTEGER(IntKi), PARAMETER :: EddShrT8N10D5 = 9158 + INTEGER(IntKi), PARAMETER :: EddShrT8N10D6 = 9159 + INTEGER(IntKi), PARAMETER :: EddShrT8N10D7 = 9160 + INTEGER(IntKi), PARAMETER :: EddShrT8N10D8 = 9161 + INTEGER(IntKi), PARAMETER :: EddShrT8N10D9 = 9162 + INTEGER(IntKi), PARAMETER :: EddShrT8N11D1 = 9163 + INTEGER(IntKi), PARAMETER :: EddShrT8N11D2 = 9164 + INTEGER(IntKi), PARAMETER :: EddShrT8N11D3 = 9165 + INTEGER(IntKi), PARAMETER :: EddShrT8N11D4 = 9166 + INTEGER(IntKi), PARAMETER :: EddShrT8N11D5 = 9167 + INTEGER(IntKi), PARAMETER :: EddShrT8N11D6 = 9168 + INTEGER(IntKi), PARAMETER :: EddShrT8N11D7 = 9169 + INTEGER(IntKi), PARAMETER :: EddShrT8N11D8 = 9170 + INTEGER(IntKi), PARAMETER :: EddShrT8N11D9 = 9171 + INTEGER(IntKi), PARAMETER :: EddShrT8N12D1 = 9172 + INTEGER(IntKi), PARAMETER :: EddShrT8N12D2 = 9173 + INTEGER(IntKi), PARAMETER :: EddShrT8N12D3 = 9174 + INTEGER(IntKi), PARAMETER :: EddShrT8N12D4 = 9175 + INTEGER(IntKi), PARAMETER :: EddShrT8N12D5 = 9176 + INTEGER(IntKi), PARAMETER :: EddShrT8N12D6 = 9177 + INTEGER(IntKi), PARAMETER :: EddShrT8N12D7 = 9178 + INTEGER(IntKi), PARAMETER :: EddShrT8N12D8 = 9179 + INTEGER(IntKi), PARAMETER :: EddShrT8N12D9 = 9180 + INTEGER(IntKi), PARAMETER :: EddShrT8N13D1 = 9181 + INTEGER(IntKi), PARAMETER :: EddShrT8N13D2 = 9182 + INTEGER(IntKi), PARAMETER :: EddShrT8N13D3 = 9183 + INTEGER(IntKi), PARAMETER :: EddShrT8N13D4 = 9184 + INTEGER(IntKi), PARAMETER :: EddShrT8N13D5 = 9185 + INTEGER(IntKi), PARAMETER :: EddShrT8N13D6 = 9186 + INTEGER(IntKi), PARAMETER :: EddShrT8N13D7 = 9187 + INTEGER(IntKi), PARAMETER :: EddShrT8N13D8 = 9188 + INTEGER(IntKi), PARAMETER :: EddShrT8N13D9 = 9189 + INTEGER(IntKi), PARAMETER :: EddShrT8N14D1 = 9190 + INTEGER(IntKi), PARAMETER :: EddShrT8N14D2 = 9191 + INTEGER(IntKi), PARAMETER :: EddShrT8N14D3 = 9192 + INTEGER(IntKi), PARAMETER :: EddShrT8N14D4 = 9193 + INTEGER(IntKi), PARAMETER :: EddShrT8N14D5 = 9194 + INTEGER(IntKi), PARAMETER :: EddShrT8N14D6 = 9195 + INTEGER(IntKi), PARAMETER :: EddShrT8N14D7 = 9196 + INTEGER(IntKi), PARAMETER :: EddShrT8N14D8 = 9197 + INTEGER(IntKi), PARAMETER :: EddShrT8N14D9 = 9198 + INTEGER(IntKi), PARAMETER :: EddShrT8N15D1 = 9199 + INTEGER(IntKi), PARAMETER :: EddShrT8N15D2 = 9200 + INTEGER(IntKi), PARAMETER :: EddShrT8N15D3 = 9201 + INTEGER(IntKi), PARAMETER :: EddShrT8N15D4 = 9202 + INTEGER(IntKi), PARAMETER :: EddShrT8N15D5 = 9203 + INTEGER(IntKi), PARAMETER :: EddShrT8N15D6 = 9204 + INTEGER(IntKi), PARAMETER :: EddShrT8N15D7 = 9205 + INTEGER(IntKi), PARAMETER :: EddShrT8N15D8 = 9206 + INTEGER(IntKi), PARAMETER :: EddShrT8N15D9 = 9207 + INTEGER(IntKi), PARAMETER :: EddShrT8N16D1 = 9208 + INTEGER(IntKi), PARAMETER :: EddShrT8N16D2 = 9209 + INTEGER(IntKi), PARAMETER :: EddShrT8N16D3 = 9210 + INTEGER(IntKi), PARAMETER :: EddShrT8N16D4 = 9211 + INTEGER(IntKi), PARAMETER :: EddShrT8N16D5 = 9212 + INTEGER(IntKi), PARAMETER :: EddShrT8N16D6 = 9213 + INTEGER(IntKi), PARAMETER :: EddShrT8N16D7 = 9214 + INTEGER(IntKi), PARAMETER :: EddShrT8N16D8 = 9215 + INTEGER(IntKi), PARAMETER :: EddShrT8N16D9 = 9216 + INTEGER(IntKi), PARAMETER :: EddShrT8N17D1 = 9217 + INTEGER(IntKi), PARAMETER :: EddShrT8N17D2 = 9218 + INTEGER(IntKi), PARAMETER :: EddShrT8N17D3 = 9219 + INTEGER(IntKi), PARAMETER :: EddShrT8N17D4 = 9220 + INTEGER(IntKi), PARAMETER :: EddShrT8N17D5 = 9221 + INTEGER(IntKi), PARAMETER :: EddShrT8N17D6 = 9222 + INTEGER(IntKi), PARAMETER :: EddShrT8N17D7 = 9223 + INTEGER(IntKi), PARAMETER :: EddShrT8N17D8 = 9224 + INTEGER(IntKi), PARAMETER :: EddShrT8N17D9 = 9225 + INTEGER(IntKi), PARAMETER :: EddShrT8N18D1 = 9226 + INTEGER(IntKi), PARAMETER :: EddShrT8N18D2 = 9227 + INTEGER(IntKi), PARAMETER :: EddShrT8N18D3 = 9228 + INTEGER(IntKi), PARAMETER :: EddShrT8N18D4 = 9229 + INTEGER(IntKi), PARAMETER :: EddShrT8N18D5 = 9230 + INTEGER(IntKi), PARAMETER :: EddShrT8N18D6 = 9231 + INTEGER(IntKi), PARAMETER :: EddShrT8N18D7 = 9232 + INTEGER(IntKi), PARAMETER :: EddShrT8N18D8 = 9233 + INTEGER(IntKi), PARAMETER :: EddShrT8N18D9 = 9234 + INTEGER(IntKi), PARAMETER :: EddShrT8N19D1 = 9235 + INTEGER(IntKi), PARAMETER :: EddShrT8N19D2 = 9236 + INTEGER(IntKi), PARAMETER :: EddShrT8N19D3 = 9237 + INTEGER(IntKi), PARAMETER :: EddShrT8N19D4 = 9238 + INTEGER(IntKi), PARAMETER :: EddShrT8N19D5 = 9239 + INTEGER(IntKi), PARAMETER :: EddShrT8N19D6 = 9240 + INTEGER(IntKi), PARAMETER :: EddShrT8N19D7 = 9241 + INTEGER(IntKi), PARAMETER :: EddShrT8N19D8 = 9242 + INTEGER(IntKi), PARAMETER :: EddShrT8N19D9 = 9243 + INTEGER(IntKi), PARAMETER :: EddShrT8N20D1 = 9244 + INTEGER(IntKi), PARAMETER :: EddShrT8N20D2 = 9245 + INTEGER(IntKi), PARAMETER :: EddShrT8N20D3 = 9246 + INTEGER(IntKi), PARAMETER :: EddShrT8N20D4 = 9247 + INTEGER(IntKi), PARAMETER :: EddShrT8N20D5 = 9248 + INTEGER(IntKi), PARAMETER :: EddShrT8N20D6 = 9249 + INTEGER(IntKi), PARAMETER :: EddShrT8N20D7 = 9250 + INTEGER(IntKi), PARAMETER :: EddShrT8N20D8 = 9251 + INTEGER(IntKi), PARAMETER :: EddShrT8N20D9 = 9252 + INTEGER(IntKi), PARAMETER :: EddShrT9N01D1 = 9253 + INTEGER(IntKi), PARAMETER :: EddShrT9N01D2 = 9254 + INTEGER(IntKi), PARAMETER :: EddShrT9N01D3 = 9255 + INTEGER(IntKi), PARAMETER :: EddShrT9N01D4 = 9256 + INTEGER(IntKi), PARAMETER :: EddShrT9N01D5 = 9257 + INTEGER(IntKi), PARAMETER :: EddShrT9N01D6 = 9258 + INTEGER(IntKi), PARAMETER :: EddShrT9N01D7 = 9259 + INTEGER(IntKi), PARAMETER :: EddShrT9N01D8 = 9260 + INTEGER(IntKi), PARAMETER :: EddShrT9N01D9 = 9261 + INTEGER(IntKi), PARAMETER :: EddShrT9N02D1 = 9262 + INTEGER(IntKi), PARAMETER :: EddShrT9N02D2 = 9263 + INTEGER(IntKi), PARAMETER :: EddShrT9N02D3 = 9264 + INTEGER(IntKi), PARAMETER :: EddShrT9N02D4 = 9265 + INTEGER(IntKi), PARAMETER :: EddShrT9N02D5 = 9266 + INTEGER(IntKi), PARAMETER :: EddShrT9N02D6 = 9267 + INTEGER(IntKi), PARAMETER :: EddShrT9N02D7 = 9268 + INTEGER(IntKi), PARAMETER :: EddShrT9N02D8 = 9269 + INTEGER(IntKi), PARAMETER :: EddShrT9N02D9 = 9270 + INTEGER(IntKi), PARAMETER :: EddShrT9N03D1 = 9271 + INTEGER(IntKi), PARAMETER :: EddShrT9N03D2 = 9272 + INTEGER(IntKi), PARAMETER :: EddShrT9N03D3 = 9273 + INTEGER(IntKi), PARAMETER :: EddShrT9N03D4 = 9274 + INTEGER(IntKi), PARAMETER :: EddShrT9N03D5 = 9275 + INTEGER(IntKi), PARAMETER :: EddShrT9N03D6 = 9276 + INTEGER(IntKi), PARAMETER :: EddShrT9N03D7 = 9277 + INTEGER(IntKi), PARAMETER :: EddShrT9N03D8 = 9278 + INTEGER(IntKi), PARAMETER :: EddShrT9N03D9 = 9279 + INTEGER(IntKi), PARAMETER :: EddShrT9N04D1 = 9280 + INTEGER(IntKi), PARAMETER :: EddShrT9N04D2 = 9281 + INTEGER(IntKi), PARAMETER :: EddShrT9N04D3 = 9282 + INTEGER(IntKi), PARAMETER :: EddShrT9N04D4 = 9283 + INTEGER(IntKi), PARAMETER :: EddShrT9N04D5 = 9284 + INTEGER(IntKi), PARAMETER :: EddShrT9N04D6 = 9285 + INTEGER(IntKi), PARAMETER :: EddShrT9N04D7 = 9286 + INTEGER(IntKi), PARAMETER :: EddShrT9N04D8 = 9287 + INTEGER(IntKi), PARAMETER :: EddShrT9N04D9 = 9288 + INTEGER(IntKi), PARAMETER :: EddShrT9N05D1 = 9289 + INTEGER(IntKi), PARAMETER :: EddShrT9N05D2 = 9290 + INTEGER(IntKi), PARAMETER :: EddShrT9N05D3 = 9291 + INTEGER(IntKi), PARAMETER :: EddShrT9N05D4 = 9292 + INTEGER(IntKi), PARAMETER :: EddShrT9N05D5 = 9293 + INTEGER(IntKi), PARAMETER :: EddShrT9N05D6 = 9294 + INTEGER(IntKi), PARAMETER :: EddShrT9N05D7 = 9295 + INTEGER(IntKi), PARAMETER :: EddShrT9N05D8 = 9296 + INTEGER(IntKi), PARAMETER :: EddShrT9N05D9 = 9297 + INTEGER(IntKi), PARAMETER :: EddShrT9N06D1 = 9298 + INTEGER(IntKi), PARAMETER :: EddShrT9N06D2 = 9299 + INTEGER(IntKi), PARAMETER :: EddShrT9N06D3 = 9300 + INTEGER(IntKi), PARAMETER :: EddShrT9N06D4 = 9301 + INTEGER(IntKi), PARAMETER :: EddShrT9N06D5 = 9302 + INTEGER(IntKi), PARAMETER :: EddShrT9N06D6 = 9303 + INTEGER(IntKi), PARAMETER :: EddShrT9N06D7 = 9304 + INTEGER(IntKi), PARAMETER :: EddShrT9N06D8 = 9305 + INTEGER(IntKi), PARAMETER :: EddShrT9N06D9 = 9306 + INTEGER(IntKi), PARAMETER :: EddShrT9N07D1 = 9307 + INTEGER(IntKi), PARAMETER :: EddShrT9N07D2 = 9308 + INTEGER(IntKi), PARAMETER :: EddShrT9N07D3 = 9309 + INTEGER(IntKi), PARAMETER :: EddShrT9N07D4 = 9310 + INTEGER(IntKi), PARAMETER :: EddShrT9N07D5 = 9311 + INTEGER(IntKi), PARAMETER :: EddShrT9N07D6 = 9312 + INTEGER(IntKi), PARAMETER :: EddShrT9N07D7 = 9313 + INTEGER(IntKi), PARAMETER :: EddShrT9N07D8 = 9314 + INTEGER(IntKi), PARAMETER :: EddShrT9N07D9 = 9315 + INTEGER(IntKi), PARAMETER :: EddShrT9N08D1 = 9316 + INTEGER(IntKi), PARAMETER :: EddShrT9N08D2 = 9317 + INTEGER(IntKi), PARAMETER :: EddShrT9N08D3 = 9318 + INTEGER(IntKi), PARAMETER :: EddShrT9N08D4 = 9319 + INTEGER(IntKi), PARAMETER :: EddShrT9N08D5 = 9320 + INTEGER(IntKi), PARAMETER :: EddShrT9N08D6 = 9321 + INTEGER(IntKi), PARAMETER :: EddShrT9N08D7 = 9322 + INTEGER(IntKi), PARAMETER :: EddShrT9N08D8 = 9323 + INTEGER(IntKi), PARAMETER :: EddShrT9N08D9 = 9324 + INTEGER(IntKi), PARAMETER :: EddShrT9N09D1 = 9325 + INTEGER(IntKi), PARAMETER :: EddShrT9N09D2 = 9326 + INTEGER(IntKi), PARAMETER :: EddShrT9N09D3 = 9327 + INTEGER(IntKi), PARAMETER :: EddShrT9N09D4 = 9328 + INTEGER(IntKi), PARAMETER :: EddShrT9N09D5 = 9329 + INTEGER(IntKi), PARAMETER :: EddShrT9N09D6 = 9330 + INTEGER(IntKi), PARAMETER :: EddShrT9N09D7 = 9331 + INTEGER(IntKi), PARAMETER :: EddShrT9N09D8 = 9332 + INTEGER(IntKi), PARAMETER :: EddShrT9N09D9 = 9333 + INTEGER(IntKi), PARAMETER :: EddShrT9N10D1 = 9334 + INTEGER(IntKi), PARAMETER :: EddShrT9N10D2 = 9335 + INTEGER(IntKi), PARAMETER :: EddShrT9N10D3 = 9336 + INTEGER(IntKi), PARAMETER :: EddShrT9N10D4 = 9337 + INTEGER(IntKi), PARAMETER :: EddShrT9N10D5 = 9338 + INTEGER(IntKi), PARAMETER :: EddShrT9N10D6 = 9339 + INTEGER(IntKi), PARAMETER :: EddShrT9N10D7 = 9340 + INTEGER(IntKi), PARAMETER :: EddShrT9N10D8 = 9341 + INTEGER(IntKi), PARAMETER :: EddShrT9N10D9 = 9342 + INTEGER(IntKi), PARAMETER :: EddShrT9N11D1 = 9343 + INTEGER(IntKi), PARAMETER :: EddShrT9N11D2 = 9344 + INTEGER(IntKi), PARAMETER :: EddShrT9N11D3 = 9345 + INTEGER(IntKi), PARAMETER :: EddShrT9N11D4 = 9346 + INTEGER(IntKi), PARAMETER :: EddShrT9N11D5 = 9347 + INTEGER(IntKi), PARAMETER :: EddShrT9N11D6 = 9348 + INTEGER(IntKi), PARAMETER :: EddShrT9N11D7 = 9349 + INTEGER(IntKi), PARAMETER :: EddShrT9N11D8 = 9350 + INTEGER(IntKi), PARAMETER :: EddShrT9N11D9 = 9351 + INTEGER(IntKi), PARAMETER :: EddShrT9N12D1 = 9352 + INTEGER(IntKi), PARAMETER :: EddShrT9N12D2 = 9353 + INTEGER(IntKi), PARAMETER :: EddShrT9N12D3 = 9354 + INTEGER(IntKi), PARAMETER :: EddShrT9N12D4 = 9355 + INTEGER(IntKi), PARAMETER :: EddShrT9N12D5 = 9356 + INTEGER(IntKi), PARAMETER :: EddShrT9N12D6 = 9357 + INTEGER(IntKi), PARAMETER :: EddShrT9N12D7 = 9358 + INTEGER(IntKi), PARAMETER :: EddShrT9N12D8 = 9359 + INTEGER(IntKi), PARAMETER :: EddShrT9N12D9 = 9360 + INTEGER(IntKi), PARAMETER :: EddShrT9N13D1 = 9361 + INTEGER(IntKi), PARAMETER :: EddShrT9N13D2 = 9362 + INTEGER(IntKi), PARAMETER :: EddShrT9N13D3 = 9363 + INTEGER(IntKi), PARAMETER :: EddShrT9N13D4 = 9364 + INTEGER(IntKi), PARAMETER :: EddShrT9N13D5 = 9365 + INTEGER(IntKi), PARAMETER :: EddShrT9N13D6 = 9366 + INTEGER(IntKi), PARAMETER :: EddShrT9N13D7 = 9367 + INTEGER(IntKi), PARAMETER :: EddShrT9N13D8 = 9368 + INTEGER(IntKi), PARAMETER :: EddShrT9N13D9 = 9369 + INTEGER(IntKi), PARAMETER :: EddShrT9N14D1 = 9370 + INTEGER(IntKi), PARAMETER :: EddShrT9N14D2 = 9371 + INTEGER(IntKi), PARAMETER :: EddShrT9N14D3 = 9372 + INTEGER(IntKi), PARAMETER :: EddShrT9N14D4 = 9373 + INTEGER(IntKi), PARAMETER :: EddShrT9N14D5 = 9374 + INTEGER(IntKi), PARAMETER :: EddShrT9N14D6 = 9375 + INTEGER(IntKi), PARAMETER :: EddShrT9N14D7 = 9376 + INTEGER(IntKi), PARAMETER :: EddShrT9N14D8 = 9377 + INTEGER(IntKi), PARAMETER :: EddShrT9N14D9 = 9378 + INTEGER(IntKi), PARAMETER :: EddShrT9N15D1 = 9379 + INTEGER(IntKi), PARAMETER :: EddShrT9N15D2 = 9380 + INTEGER(IntKi), PARAMETER :: EddShrT9N15D3 = 9381 + INTEGER(IntKi), PARAMETER :: EddShrT9N15D4 = 9382 + INTEGER(IntKi), PARAMETER :: EddShrT9N15D5 = 9383 + INTEGER(IntKi), PARAMETER :: EddShrT9N15D6 = 9384 + INTEGER(IntKi), PARAMETER :: EddShrT9N15D7 = 9385 + INTEGER(IntKi), PARAMETER :: EddShrT9N15D8 = 9386 + INTEGER(IntKi), PARAMETER :: EddShrT9N15D9 = 9387 + INTEGER(IntKi), PARAMETER :: EddShrT9N16D1 = 9388 + INTEGER(IntKi), PARAMETER :: EddShrT9N16D2 = 9389 + INTEGER(IntKi), PARAMETER :: EddShrT9N16D3 = 9390 + INTEGER(IntKi), PARAMETER :: EddShrT9N16D4 = 9391 + INTEGER(IntKi), PARAMETER :: EddShrT9N16D5 = 9392 + INTEGER(IntKi), PARAMETER :: EddShrT9N16D6 = 9393 + INTEGER(IntKi), PARAMETER :: EddShrT9N16D7 = 9394 + INTEGER(IntKi), PARAMETER :: EddShrT9N16D8 = 9395 + INTEGER(IntKi), PARAMETER :: EddShrT9N16D9 = 9396 + INTEGER(IntKi), PARAMETER :: EddShrT9N17D1 = 9397 + INTEGER(IntKi), PARAMETER :: EddShrT9N17D2 = 9398 + INTEGER(IntKi), PARAMETER :: EddShrT9N17D3 = 9399 + INTEGER(IntKi), PARAMETER :: EddShrT9N17D4 = 9400 + INTEGER(IntKi), PARAMETER :: EddShrT9N17D5 = 9401 + INTEGER(IntKi), PARAMETER :: EddShrT9N17D6 = 9402 + INTEGER(IntKi), PARAMETER :: EddShrT9N17D7 = 9403 + INTEGER(IntKi), PARAMETER :: EddShrT9N17D8 = 9404 + INTEGER(IntKi), PARAMETER :: EddShrT9N17D9 = 9405 + INTEGER(IntKi), PARAMETER :: EddShrT9N18D1 = 9406 + INTEGER(IntKi), PARAMETER :: EddShrT9N18D2 = 9407 + INTEGER(IntKi), PARAMETER :: EddShrT9N18D3 = 9408 + INTEGER(IntKi), PARAMETER :: EddShrT9N18D4 = 9409 + INTEGER(IntKi), PARAMETER :: EddShrT9N18D5 = 9410 + INTEGER(IntKi), PARAMETER :: EddShrT9N18D6 = 9411 + INTEGER(IntKi), PARAMETER :: EddShrT9N18D7 = 9412 + INTEGER(IntKi), PARAMETER :: EddShrT9N18D8 = 9413 + INTEGER(IntKi), PARAMETER :: EddShrT9N18D9 = 9414 + INTEGER(IntKi), PARAMETER :: EddShrT9N19D1 = 9415 + INTEGER(IntKi), PARAMETER :: EddShrT9N19D2 = 9416 + INTEGER(IntKi), PARAMETER :: EddShrT9N19D3 = 9417 + INTEGER(IntKi), PARAMETER :: EddShrT9N19D4 = 9418 + INTEGER(IntKi), PARAMETER :: EddShrT9N19D5 = 9419 + INTEGER(IntKi), PARAMETER :: EddShrT9N19D6 = 9420 + INTEGER(IntKi), PARAMETER :: EddShrT9N19D7 = 9421 + INTEGER(IntKi), PARAMETER :: EddShrT9N19D8 = 9422 + INTEGER(IntKi), PARAMETER :: EddShrT9N19D9 = 9423 + INTEGER(IntKi), PARAMETER :: EddShrT9N20D1 = 9424 + INTEGER(IntKi), PARAMETER :: EddShrT9N20D2 = 9425 + INTEGER(IntKi), PARAMETER :: EddShrT9N20D3 = 9426 + INTEGER(IntKi), PARAMETER :: EddShrT9N20D4 = 9427 + INTEGER(IntKi), PARAMETER :: EddShrT9N20D5 = 9428 + INTEGER(IntKi), PARAMETER :: EddShrT9N20D6 = 9429 + INTEGER(IntKi), PARAMETER :: EddShrT9N20D7 = 9430 + INTEGER(IntKi), PARAMETER :: EddShrT9N20D8 = 9431 + INTEGER(IntKi), PARAMETER :: EddShrT9N20D9 = 9432 + + + ! Ambient Wind Velocity: + + INTEGER(IntKi), PARAMETER :: W1VAmbX = 9433 + INTEGER(IntKi), PARAMETER :: W2VAmbX = 9434 + INTEGER(IntKi), PARAMETER :: W3VAmbX = 9435 + INTEGER(IntKi), PARAMETER :: W4VAmbX = 9436 + INTEGER(IntKi), PARAMETER :: W5VAmbX = 9437 + INTEGER(IntKi), PARAMETER :: W6VAmbX = 9438 + INTEGER(IntKi), PARAMETER :: W7VAmbX = 9439 + INTEGER(IntKi), PARAMETER :: W8VAmbX = 9440 + INTEGER(IntKi), PARAMETER :: W9VAmbX = 9441 + INTEGER(IntKi), PARAMETER :: W1VAmbY = 9442 + INTEGER(IntKi), PARAMETER :: W2VAmbY = 9443 + INTEGER(IntKi), PARAMETER :: W3VAmbY = 9444 + INTEGER(IntKi), PARAMETER :: W4VAmbY = 9445 + INTEGER(IntKi), PARAMETER :: W5VAmbY = 9446 + INTEGER(IntKi), PARAMETER :: W6VAmbY = 9447 + INTEGER(IntKi), PARAMETER :: W7VAmbY = 9448 + INTEGER(IntKi), PARAMETER :: W8VAmbY = 9449 + INTEGER(IntKi), PARAMETER :: W9VAmbY = 9450 + INTEGER(IntKi), PARAMETER :: W1VAmbZ = 9451 + INTEGER(IntKi), PARAMETER :: W2VAmbZ = 9452 + INTEGER(IntKi), PARAMETER :: W3VAmbZ = 9453 + INTEGER(IntKi), PARAMETER :: W4VAmbZ = 9454 + INTEGER(IntKi), PARAMETER :: W5VAmbZ = 9455 + INTEGER(IntKi), PARAMETER :: W6VAmbZ = 9456 + INTEGER(IntKi), PARAMETER :: W7VAmbZ = 9457 + INTEGER(IntKi), PARAMETER :: W8VAmbZ = 9458 + INTEGER(IntKi), PARAMETER :: W9VAmbZ = 9459 + + + ! Disturbed Wind Velocity: + + INTEGER(IntKi), PARAMETER :: W1VDisX = 9460 + INTEGER(IntKi), PARAMETER :: W2VDisX = 9461 + INTEGER(IntKi), PARAMETER :: W3VDisX = 9462 + INTEGER(IntKi), PARAMETER :: W4VDisX = 9463 + INTEGER(IntKi), PARAMETER :: W5VDisX = 9464 + INTEGER(IntKi), PARAMETER :: W6VDisX = 9465 + INTEGER(IntKi), PARAMETER :: W7VDisX = 9466 + INTEGER(IntKi), PARAMETER :: W8VDisX = 9467 + INTEGER(IntKi), PARAMETER :: W9VDisX = 9468 + INTEGER(IntKi), PARAMETER :: W1VDisY = 9469 + INTEGER(IntKi), PARAMETER :: W2VDisY = 9470 + INTEGER(IntKi), PARAMETER :: W3VDisY = 9471 + INTEGER(IntKi), PARAMETER :: W4VDisY = 9472 + INTEGER(IntKi), PARAMETER :: W5VDisY = 9473 + INTEGER(IntKi), PARAMETER :: W6VDisY = 9474 + INTEGER(IntKi), PARAMETER :: W7VDisY = 9475 + INTEGER(IntKi), PARAMETER :: W8VDisY = 9476 + INTEGER(IntKi), PARAMETER :: W9VDisY = 9477 + INTEGER(IntKi), PARAMETER :: W1VDisZ = 9478 + INTEGER(IntKi), PARAMETER :: W2VDisZ = 9479 + INTEGER(IntKi), PARAMETER :: W3VDisZ = 9480 + INTEGER(IntKi), PARAMETER :: W4VDisZ = 9481 + INTEGER(IntKi), PARAMETER :: W5VDisZ = 9482 + INTEGER(IntKi), PARAMETER :: W6VDisZ = 9483 + INTEGER(IntKi), PARAMETER :: W7VDisZ = 9484 + INTEGER(IntKi), PARAMETER :: W8VDisZ = 9485 + INTEGER(IntKi), PARAMETER :: W9VDisZ = 9486 + + + ! Disturbed Wind Velocity: + + + + ! The maximum number of output channels which can be output by the code. + INTEGER(IntKi), PARAMETER :: Farm_MaxOutPts = 9486 + +!End of code generated by Matlab script Write_ChckOutLst +! =================================================================================================== + + INTEGER, PARAMETER :: SCGblIn(9) = (/SCGblIn1,SCGblIn2,SCGblIn3,SCGblIn4,SCGblIn5,SCGblIn6,SCGblIn7,SCGblIn8,SCGblIn9/) + INTEGER, PARAMETER :: SCGblOt(9) = (/SCGblOt1,SCGblOt2,SCGblOt3,SCGblOt4,SCGblOt5,SCGblOt6,SCGblOt7,SCGblOt8,SCGblOt9/) + INTEGER, PARAMETER :: SCTIn(9,9) = RESHAPE( & + (/SCT1In1 ,SCT1In2 ,SCT1In3 ,SCT1In4 ,SCT1In5 ,SCT1In6 ,SCT1In7 ,SCT1In8 ,SCT1In9, & + SCT2In1 ,SCT2In2 ,SCT2In3 ,SCT2In4 ,SCT2In5 ,SCT2In6 ,SCT2In7 ,SCT2In8 ,SCT2In9, & + SCT3In1 ,SCT3In2 ,SCT3In3 ,SCT3In4 ,SCT3In5 ,SCT3In6 ,SCT3In7 ,SCT3In8 ,SCT3In9, & + SCT4In1 ,SCT4In2 ,SCT4In3 ,SCT4In4 ,SCT4In5 ,SCT4In6 ,SCT4In7 ,SCT4In8 ,SCT4In9, & + SCT5In1 ,SCT5In2 ,SCT5In3 ,SCT5In4 ,SCT5In5 ,SCT5In6 ,SCT5In7 ,SCT5In8 ,SCT5In9, & + SCT6In1 ,SCT6In2 ,SCT6In3 ,SCT6In4 ,SCT6In5 ,SCT6In6 ,SCT6In7 ,SCT6In8 ,SCT6In9, & + SCT7In1 ,SCT7In2 ,SCT7In3 ,SCT7In4 ,SCT7In5 ,SCT7In6 ,SCT7In7 ,SCT7In8 ,SCT7In9, & + SCT8In1 ,SCT8In2 ,SCT8In3 ,SCT8In4 ,SCT8In5 ,SCT8In6 ,SCT8In7 ,SCT8In8 ,SCT8In9, & + SCT9In1 ,SCT9In2 ,SCT9In3 ,SCT9In4 ,SCT9In5 ,SCT9In6 ,SCT9In7 ,SCT9In8 ,SCT9In9/), (/9,9/) ) + INTEGER, PARAMETER :: SCTOt(9,9) = RESHAPE( & + (/SCT1Ot1 ,SCT1Ot2 ,SCT1Ot3 ,SCT1Ot4 ,SCT1Ot5 ,SCT1Ot6 ,SCT1Ot7 ,SCT1Ot8 ,SCT1Ot9, & + SCT2Ot1 ,SCT2Ot2 ,SCT2Ot3 ,SCT2Ot4 ,SCT2Ot5 ,SCT2Ot6 ,SCT2Ot7 ,SCT2Ot8 ,SCT2Ot9, & + SCT3Ot1 ,SCT3Ot2 ,SCT3Ot3 ,SCT3Ot4 ,SCT3Ot5 ,SCT3Ot6 ,SCT3Ot7 ,SCT3Ot8 ,SCT3Ot9, & + SCT4Ot1 ,SCT4Ot2 ,SCT4Ot3 ,SCT4Ot4 ,SCT4Ot5 ,SCT4Ot6 ,SCT4Ot7 ,SCT4Ot8 ,SCT4Ot9, & + SCT5Ot1 ,SCT5Ot2 ,SCT5Ot3 ,SCT5Ot4 ,SCT5Ot5 ,SCT5Ot6 ,SCT5Ot7 ,SCT5Ot8 ,SCT5Ot9, & + SCT6Ot1 ,SCT6Ot2 ,SCT6Ot3 ,SCT6Ot4 ,SCT6Ot5 ,SCT6Ot6 ,SCT6Ot7 ,SCT6Ot8 ,SCT6Ot9, & + SCT7Ot1 ,SCT7Ot2 ,SCT7Ot3 ,SCT7Ot4 ,SCT7Ot5 ,SCT7Ot6 ,SCT7Ot7 ,SCT7Ot8 ,SCT7Ot9, & + SCT8Ot1 ,SCT8Ot2 ,SCT8Ot3 ,SCT8Ot4 ,SCT8Ot5 ,SCT8Ot6 ,SCT8Ot7 ,SCT8Ot8 ,SCT8Ot9, & + SCT9Ot1 ,SCT9Ot2 ,SCT9Ot3 ,SCT9Ot4 ,SCT9Ot5 ,SCT9Ot6 ,SCT9Ot7 ,SCT9Ot8 ,SCT9Ot9/), (/9,9/) ) + + INTEGER, PARAMETER :: RtAxsXT(9) = (/RtAxsXT1,RtAxsXT2,RtAxsXT3,RtAxsXT4,RtAxsXT5,RtAxsXT6,RtAxsXT7,RtAxsXT8,RtAxsXT9/) + INTEGER, PARAMETER :: RtAxsYT(9) = (/RtAxsYT1,RtAxsYT2,RtAxsYT3,RtAxsYT4,RtAxsYT5,RtAxsYT6,RtAxsYT7,RtAxsYT8,RtAxsYT9/) + INTEGER, PARAMETER :: RtAxsZT(9) = (/RtAxsZT1,RtAxsZT2,RtAxsZT3,RtAxsZT4,RtAxsZT5,RtAxsZT6,RtAxsZT7,RtAxsZT8,RtAxsZT9/) + + INTEGER, PARAMETER :: RtPosXT(9) = (/RtPosXT1,RtPosXT2,RtPosXT3,RtPosXT4,RtPosXT5,RtPosXT6,RtPosXT7,RtPosXT8,RtPosXT9/) + INTEGER, PARAMETER :: RtPosYT(9) = (/RtPosYT1,RtPosYT2,RtPosYT3,RtPosYT4,RtPosYT5,RtPosYT6,RtPosYT7,RtPosYT8,RtPosYT9/) + INTEGER, PARAMETER :: RtPosZT(9) = (/RtPosZT1,RtPosZT2,RtPosZT3,RtPosZT4,RtPosZT5,RtPosZT6,RtPosZT7,RtPosZT8,RtPosZT9/) + + INTEGER, PARAMETER :: RtDiamT(9) = (/RtDiamT1,RtDiamT2,RtDiamT3,RtDiamT4,RtDiamT5,RtDiamT6,RtDiamT7,RtDiamT8,RtDiamT9/) + INTEGER, PARAMETER :: YawErrT(9) = (/YawErrT1,YawErrT2,YawErrT3,YawErrT4,YawErrT5,YawErrT6,YawErrT7,YawErrT8,YawErrT9/) + INTEGER, PARAMETER :: TIAmbT(9) = (/TIAmbT1,TIAmbT2,TIAmbT3,TIAmbT4,TIAmbT5,TIAmbT6,TIAmbT7,TIAmbT8,TIAmbT9/) + INTEGER, PARAMETER :: RtVAmbT(9) = (/RtVAmbT1,RtVAmbT2,RtVAmbT3,RtVAmbT4,RtVAmbT5,RtVAmbT6,RtVAmbT7,RtVAmbT8,RtVAmbT9/) + INTEGER, PARAMETER :: RTVRelT(9) = (/RTVRelT1,RTVRelT2,RTVRelT3,RTVRelT4,RTVRelT5,RTVRelT6,RTVRelT7,RTVRelT8,RTVRelT9/) + INTEGER, PARAMETER :: RtVAmbFiltT(9) = (/RtVAmbFiltT1,RtVAmbFiltT2,RtVAmbFiltT3,RtVAmbFiltT4,RtVAmbFiltT5,RtVAmbFiltT6,RtVAmbFiltT7,RtVAmbFiltT8,RtVAmbFiltT9/) + INTEGER, PARAMETER :: AziSkewT(9) = (/AziSkewT1,AziSkewT2,AziSkewT3,AziSkewT4,AziSkewT5,AziSkewT6,AziSkewT7,AziSkewT8,AziSkewT9/) + INTEGER, PARAMETER :: AziSkewFiltT(9) = (/AziSkewFiltT1,AziSkewFiltT2,AziSkewFiltT3,AziSkewFiltT4,AziSkewFiltT5,AziSkewFiltT6,AziSkewFiltT7,AziSkewFiltT8,AziSkewFiltT9/) + INTEGER, PARAMETER :: RtSkewT(9) = (/RtSkewT1,RtSkewT2,RtSkewT3,RtSkewT4,RtSkewT5,RtSkewT6,RtSkewT7,RtSkewT8,RtSkewT9/) + INTEGER, PARAMETER :: RtSkewFiltT(9) = (/RtSkewFiltT1,RtSkewFiltT2,RtSkewFiltT3,RtSkewFiltT4,RtSkewFiltT5,RtSkewFiltT6,RtSkewFiltT7,RtSkewFiltT8,RtSkewFiltT9/) + INTEGER, PARAMETER :: RtGamCurlT(9) = (/RtGamCurlT1,RtGamCurlT2,RtGamCurlT3,RtGamCurlT4,RtGamCurlT5,RtGamCurlT6,RtGamCurlT7,RtGamCurlT8,RtGamCurlT9/) + INTEGER, PARAMETER :: RtCtAvgT(9) = (/RtCtAvgT1,RtCtAvgT2,RtCtAvgT3,RtCtAvgT4,RtCtAvgT5,RtCtAvgT6,RtCtAvgT7,RtCtAvgT8,RtCtAvgT9/) + + INTEGER, PARAMETER :: CtTN(20,9) = RESHAPE( & + (/CtT1N01,CtT1N02,CtT1N03,CtT1N04,CtT1N05,CtT1N06,CtT1N07,CtT1N08,CtT1N09, CtT1N10, & + CtT1N11,CtT1N12,CtT1N13,CtT1N14,CtT1N15,CtT1N16,CtT1N17,CtT1N18,CtT1N19, CtT1N20, & + CtT2N01,CtT2N02,CtT2N03,CtT2N04,CtT2N05,CtT2N06,CtT2N07,CtT2N08,CtT2N09, CtT2N10, & + CtT2N11,CtT2N12,CtT2N13,CtT2N14,CtT2N15,CtT2N16,CtT2N17,CtT2N18,CtT2N19, CtT2N20, & + CtT3N01,CtT3N02,CtT3N03,CtT3N04,CtT3N05,CtT3N06,CtT3N07,CtT3N08,CtT3N09, CtT3N10, & + CtT3N11,CtT3N12,CtT3N13,CtT3N14,CtT3N15,CtT3N16,CtT3N17,CtT3N18,CtT3N19, CtT3N20, & + CtT4N01,CtT4N02,CtT4N03,CtT4N04,CtT4N05,CtT4N06,CtT4N07,CtT4N08,CtT4N09, CtT4N10, & + CtT4N11,CtT4N12,CtT4N13,CtT4N14,CtT4N15,CtT4N16,CtT4N17,CtT4N18,CtT4N19, CtT4N20, & + CtT5N01,CtT5N02,CtT5N03,CtT5N04,CtT5N05,CtT5N06,CtT5N07,CtT5N08,CtT5N09, CtT5N10, & + CtT5N11,CtT5N12,CtT5N13,CtT5N14,CtT5N15,CtT5N16,CtT5N17,CtT5N18,CtT5N19, CtT5N20, & + CtT6N01,CtT6N02,CtT6N03,CtT6N04,CtT6N05,CtT6N06,CtT6N07,CtT6N08,CtT6N09, CtT6N10, & + CtT6N11,CtT6N12,CtT6N13,CtT6N14,CtT6N15,CtT6N16,CtT6N17,CtT6N18,CtT6N19, CtT6N20, & + CtT7N01,CtT7N02,CtT7N03,CtT7N04,CtT7N05,CtT7N06,CtT7N07,CtT7N08,CtT7N09, CtT7N10, & + CtT7N11,CtT7N12,CtT7N13,CtT7N14,CtT7N15,CtT7N16,CtT7N17,CtT7N18,CtT7N19, CtT7N20, & + CtT8N01,CtT8N02,CtT8N03,CtT8N04,CtT8N05,CtT8N06,CtT8N07,CtT8N08,CtT8N09, CtT8N10, & + CtT8N11,CtT8N12,CtT8N13,CtT8N14,CtT8N15,CtT8N16,CtT8N17,CtT8N18,CtT8N19, CtT8N20, & + CtT9N01,CtT9N02,CtT9N03,CtT9N04,CtT9N05,CtT9N06,CtT9N07,CtT9N08,CtT9N09, CtT9N10, & + CtT9N11,CtT9N12,CtT9N13,CtT9N14,CtT9N15,CtT9N16,CtT9N17,CtT9N18,CtT9N19, CtT9N20/), (/20,9/) ) + + + + INTEGER, PARAMETER :: WkAxsXTD(9,9) = RESHAPE( & + (/WkAxsXT1D1,WkAxsXT1D2,WkAxsXT1D3,WkAxsXT1D4,WkAxsXT1D5,WkAxsXT1D6,WkAxsXT1D7,WkAxsXT1D8,WkAxsXT1D9, & + WkAxsXT2D1,WkAxsXT2D2,WkAxsXT2D3,WkAxsXT2D4,WkAxsXT2D5,WkAxsXT2D6,WkAxsXT2D7,WkAxsXT2D8,WkAxsXT2D9, & + WkAxsXT3D1,WkAxsXT3D2,WkAxsXT3D3,WkAxsXT3D4,WkAxsXT3D5,WkAxsXT3D6,WkAxsXT3D7,WkAxsXT3D8,WkAxsXT3D9, & + WkAxsXT4D1,WkAxsXT4D2,WkAxsXT4D3,WkAxsXT4D4,WkAxsXT4D5,WkAxsXT4D6,WkAxsXT4D7,WkAxsXT4D8,WkAxsXT4D9, & + WkAxsXT5D1,WkAxsXT5D2,WkAxsXT5D3,WkAxsXT5D4,WkAxsXT5D5,WkAxsXT5D6,WkAxsXT5D7,WkAxsXT5D8,WkAxsXT5D9, & + WkAxsXT6D1,WkAxsXT6D2,WkAxsXT6D3,WkAxsXT6D4,WkAxsXT6D5,WkAxsXT6D6,WkAxsXT6D7,WkAxsXT6D8,WkAxsXT6D9, & + WkAxsXT7D1,WkAxsXT7D2,WkAxsXT7D3,WkAxsXT7D4,WkAxsXT7D5,WkAxsXT7D6,WkAxsXT7D7,WkAxsXT7D8,WkAxsXT7D9, & + WkAxsXT8D1,WkAxsXT8D2,WkAxsXT8D3,WkAxsXT8D4,WkAxsXT8D5,WkAxsXT8D6,WkAxsXT8D7,WkAxsXT8D8,WkAxsXT8D9, & + WkAxsXT9D1,WkAxsXT9D2,WkAxsXT9D3,WkAxsXT9D4,WkAxsXT9D5,WkAxsXT9D6,WkAxsXT9D7,WkAxsXT9D8,WkAxsXT9D9/), (/9,9/) ) + + INTEGER, PARAMETER :: WkAxsYTD(9,9) = RESHAPE( & + (/WkAxsYT1D1,WkAxsYT1D2,WkAxsYT1D3,WkAxsYT1D4,WkAxsYT1D5,WkAxsYT1D6,WkAxsYT1D7,WkAxsYT1D8,WkAxsYT1D9, & + WkAxsYT2D1,WkAxsYT2D2,WkAxsYT2D3,WkAxsYT2D4,WkAxsYT2D5,WkAxsYT2D6,WkAxsYT2D7,WkAxsYT2D8,WkAxsYT2D9, & + WkAxsYT3D1,WkAxsYT3D2,WkAxsYT3D3,WkAxsYT3D4,WkAxsYT3D5,WkAxsYT3D6,WkAxsYT3D7,WkAxsYT3D8,WkAxsYT3D9, & + WkAxsYT4D1,WkAxsYT4D2,WkAxsYT4D3,WkAxsYT4D4,WkAxsYT4D5,WkAxsYT4D6,WkAxsYT4D7,WkAxsYT4D8,WkAxsYT4D9, & + WkAxsYT5D1,WkAxsYT5D2,WkAxsYT5D3,WkAxsYT5D4,WkAxsYT5D5,WkAxsYT5D6,WkAxsYT5D7,WkAxsYT5D8,WkAxsYT5D9, & + WkAxsYT6D1,WkAxsYT6D2,WkAxsYT6D3,WkAxsYT6D4,WkAxsYT6D5,WkAxsYT6D6,WkAxsYT6D7,WkAxsYT6D8,WkAxsYT6D9, & + WkAxsYT7D1,WkAxsYT7D2,WkAxsYT7D3,WkAxsYT7D4,WkAxsYT7D5,WkAxsYT7D6,WkAxsYT7D7,WkAxsYT7D8,WkAxsYT7D9, & + WkAxsYT8D1,WkAxsYT8D2,WkAxsYT8D3,WkAxsYT8D4,WkAxsYT8D5,WkAxsYT8D6,WkAxsYT8D7,WkAxsYT8D8,WkAxsYT8D9, & + WkAxsYT9D1,WkAxsYT9D2,WkAxsYT9D3,WkAxsYT9D4,WkAxsYT9D5,WkAxsYT9D6,WkAxsYT9D7,WkAxsYT9D8,WkAxsYT9D9/), (/9,9/) ) + + INTEGER, PARAMETER :: WkAxsZTD(9,9) = RESHAPE( & + (/WkAxsZT1D1,WkAxsZT1D2,WkAxsZT1D3,WkAxsZT1D4,WkAxsZT1D5,WkAxsZT1D6,WkAxsZT1D7,WkAxsZT1D8,WkAxsZT1D9, & + WkAxsZT2D1,WkAxsZT2D2,WkAxsZT2D3,WkAxsZT2D4,WkAxsZT2D5,WkAxsZT2D6,WkAxsZT2D7,WkAxsZT2D8,WkAxsZT2D9, & + WkAxsZT3D1,WkAxsZT3D2,WkAxsZT3D3,WkAxsZT3D4,WkAxsZT3D5,WkAxsZT3D6,WkAxsZT3D7,WkAxsZT3D8,WkAxsZT3D9, & + WkAxsZT4D1,WkAxsZT4D2,WkAxsZT4D3,WkAxsZT4D4,WkAxsZT4D5,WkAxsZT4D6,WkAxsZT4D7,WkAxsZT4D8,WkAxsZT4D9, & + WkAxsZT5D1,WkAxsZT5D2,WkAxsZT5D3,WkAxsZT5D4,WkAxsZT5D5,WkAxsZT5D6,WkAxsZT5D7,WkAxsZT5D8,WkAxsZT5D9, & + WkAxsZT6D1,WkAxsZT6D2,WkAxsZT6D3,WkAxsZT6D4,WkAxsZT6D5,WkAxsZT6D6,WkAxsZT6D7,WkAxsZT6D8,WkAxsZT6D9, & + WkAxsZT7D1,WkAxsZT7D2,WkAxsZT7D3,WkAxsZT7D4,WkAxsZT7D5,WkAxsZT7D6,WkAxsZT7D7,WkAxsZT7D8,WkAxsZT7D9, & + WkAxsZT8D1,WkAxsZT8D2,WkAxsZT8D3,WkAxsZT8D4,WkAxsZT8D5,WkAxsZT8D6,WkAxsZT8D7,WkAxsZT8D8,WkAxsZT8D9, & + WkAxsZT9D1,WkAxsZT9D2,WkAxsZT9D3,WkAxsZT9D4,WkAxsZT9D5,WkAxsZT9D6,WkAxsZT9D7,WkAxsZT9D8,WkAxsZT9D9/), (/9,9/) ) + + INTEGER, PARAMETER :: WkPosXTD(9,9) = RESHAPE( & + (/WkPosXT1D1,WkPosXT1D2,WkPosXT1D3,WkPosXT1D4,WkPosXT1D5,WkPosXT1D6,WkPosXT1D7,WkPosXT1D8,WkPosXT1D9, & + WkPosXT2D1,WkPosXT2D2,WkPosXT2D3,WkPosXT2D4,WkPosXT2D5,WkPosXT2D6,WkPosXT2D7,WkPosXT2D8,WkPosXT2D9, & + WkPosXT3D1,WkPosXT3D2,WkPosXT3D3,WkPosXT3D4,WkPosXT3D5,WkPosXT3D6,WkPosXT3D7,WkPosXT3D8,WkPosXT3D9, & + WkPosXT4D1,WkPosXT4D2,WkPosXT4D3,WkPosXT4D4,WkPosXT4D5,WkPosXT4D6,WkPosXT4D7,WkPosXT4D8,WkPosXT4D9, & + WkPosXT5D1,WkPosXT5D2,WkPosXT5D3,WkPosXT5D4,WkPosXT5D5,WkPosXT5D6,WkPosXT5D7,WkPosXT5D8,WkPosXT5D9, & + WkPosXT6D1,WkPosXT6D2,WkPosXT6D3,WkPosXT6D4,WkPosXT6D5,WkPosXT6D6,WkPosXT6D7,WkPosXT6D8,WkPosXT6D9, & + WkPosXT7D1,WkPosXT7D2,WkPosXT7D3,WkPosXT7D4,WkPosXT7D5,WkPosXT7D6,WkPosXT7D7,WkPosXT7D8,WkPosXT7D9, & + WkPosXT8D1,WkPosXT8D2,WkPosXT8D3,WkPosXT8D4,WkPosXT8D5,WkPosXT8D6,WkPosXT8D7,WkPosXT8D8,WkPosXT8D9, & + WkPosXT9D1,WkPosXT9D2,WkPosXT9D3,WkPosXT9D4,WkPosXT9D5,WkPosXT9D6,WkPosXT9D7,WkPosXT9D8,WkPosXT9D9/), (/9,9/) ) + + INTEGER, PARAMETER :: WkPosYTD(9,9) = RESHAPE( & + (/WkPosYT1D1,WkPosYT1D2,WkPosYT1D3,WkPosYT1D4,WkPosYT1D5,WkPosYT1D6,WkPosYT1D7,WkPosYT1D8,WkPosYT1D9, & + WkPosYT2D1,WkPosYT2D2,WkPosYT2D3,WkPosYT2D4,WkPosYT2D5,WkPosYT2D6,WkPosYT2D7,WkPosYT2D8,WkPosYT2D9, & + WkPosYT3D1,WkPosYT3D2,WkPosYT3D3,WkPosYT3D4,WkPosYT3D5,WkPosYT3D6,WkPosYT3D7,WkPosYT3D8,WkPosYT3D9, & + WkPosYT4D1,WkPosYT4D2,WkPosYT4D3,WkPosYT4D4,WkPosYT4D5,WkPosYT4D6,WkPosYT4D7,WkPosYT4D8,WkPosYT4D9, & + WkPosYT5D1,WkPosYT5D2,WkPosYT5D3,WkPosYT5D4,WkPosYT5D5,WkPosYT5D6,WkPosYT5D7,WkPosYT5D8,WkPosYT5D9, & + WkPosYT6D1,WkPosYT6D2,WkPosYT6D3,WkPosYT6D4,WkPosYT6D5,WkPosYT6D6,WkPosYT6D7,WkPosYT6D8,WkPosYT6D9, & + WkPosYT7D1,WkPosYT7D2,WkPosYT7D3,WkPosYT7D4,WkPosYT7D5,WkPosYT7D6,WkPosYT7D7,WkPosYT7D8,WkPosYT7D9, & + WkPosYT8D1,WkPosYT8D2,WkPosYT8D3,WkPosYT8D4,WkPosYT8D5,WkPosYT8D6,WkPosYT8D7,WkPosYT8D8,WkPosYT8D9, & + WkPosYT9D1,WkPosYT9D2,WkPosYT9D3,WkPosYT9D4,WkPosYT9D5,WkPosYT9D6,WkPosYT9D7,WkPosYT9D8,WkPosYT9D9/), (/9,9/) ) + + INTEGER, PARAMETER :: WkPosZTD(9,9) = RESHAPE( & + (/WkPosZT1D1,WkPosZT1D2,WkPosZT1D3,WkPosZT1D4,WkPosZT1D5,WkPosZT1D6,WkPosZT1D7,WkPosZT1D8,WkPosZT1D9, & + WkPosZT2D1,WkPosZT2D2,WkPosZT2D3,WkPosZT2D4,WkPosZT2D5,WkPosZT2D6,WkPosZT2D7,WkPosZT2D8,WkPosZT2D9, & + WkPosZT3D1,WkPosZT3D2,WkPosZT3D3,WkPosZT3D4,WkPosZT3D5,WkPosZT3D6,WkPosZT3D7,WkPosZT3D8,WkPosZT3D9, & + WkPosZT4D1,WkPosZT4D2,WkPosZT4D3,WkPosZT4D4,WkPosZT4D5,WkPosZT4D6,WkPosZT4D7,WkPosZT4D8,WkPosZT4D9, & + WkPosZT5D1,WkPosZT5D2,WkPosZT5D3,WkPosZT5D4,WkPosZT5D5,WkPosZT5D6,WkPosZT5D7,WkPosZT5D8,WkPosZT5D9, & + WkPosZT6D1,WkPosZT6D2,WkPosZT6D3,WkPosZT6D4,WkPosZT6D5,WkPosZT6D6,WkPosZT6D7,WkPosZT6D8,WkPosZT6D9, & + WkPosZT7D1,WkPosZT7D2,WkPosZT7D3,WkPosZT7D4,WkPosZT7D5,WkPosZT7D6,WkPosZT7D7,WkPosZT7D8,WkPosZT7D9, & + WkPosZT8D1,WkPosZT8D2,WkPosZT8D3,WkPosZT8D4,WkPosZT8D5,WkPosZT8D6,WkPosZT8D7,WkPosZT8D8,WkPosZT8D9, & + WkPosZT9D1,WkPosZT9D2,WkPosZT9D3,WkPosZT9D4,WkPosZT9D5,WkPosZT9D6,WkPosZT9D7,WkPosZT9D8,WkPosZT9D9/), (/9,9/) ) + + INTEGER, PARAMETER :: WkVelXTD(9,9) = RESHAPE( & + (/WkVelXT1D1,WkVelXT1D2,WkVelXT1D3,WkVelXT1D4,WkVelXT1D5,WkVelXT1D6,WkVelXT1D7,WkVelXT1D8,WkVelXT1D9, & + WkVelXT2D1,WkVelXT2D2,WkVelXT2D3,WkVelXT2D4,WkVelXT2D5,WkVelXT2D6,WkVelXT2D7,WkVelXT2D8,WkVelXT2D9, & + WkVelXT3D1,WkVelXT3D2,WkVelXT3D3,WkVelXT3D4,WkVelXT3D5,WkVelXT3D6,WkVelXT3D7,WkVelXT3D8,WkVelXT3D9, & + WkVelXT4D1,WkVelXT4D2,WkVelXT4D3,WkVelXT4D4,WkVelXT4D5,WkVelXT4D6,WkVelXT4D7,WkVelXT4D8,WkVelXT4D9, & + WkVelXT5D1,WkVelXT5D2,WkVelXT5D3,WkVelXT5D4,WkVelXT5D5,WkVelXT5D6,WkVelXT5D7,WkVelXT5D8,WkVelXT5D9, & + WkVelXT6D1,WkVelXT6D2,WkVelXT6D3,WkVelXT6D4,WkVelXT6D5,WkVelXT6D6,WkVelXT6D7,WkVelXT6D8,WkVelXT6D9, & + WkVelXT7D1,WkVelXT7D2,WkVelXT7D3,WkVelXT7D4,WkVelXT7D5,WkVelXT7D6,WkVelXT7D7,WkVelXT7D8,WkVelXT7D9, & + WkVelXT8D1,WkVelXT8D2,WkVelXT8D3,WkVelXT8D4,WkVelXT8D5,WkVelXT8D6,WkVelXT8D7,WkVelXT8D8,WkVelXT8D9, & + WkVelXT9D1,WkVelXT9D2,WkVelXT9D3,WkVelXT9D4,WkVelXT9D5,WkVelXT9D6,WkVelXT9D7,WkVelXT9D8,WkVelXT9D9/), (/9,9/) ) + + INTEGER, PARAMETER :: WkVelYTD(9,9) = RESHAPE( & + (/WkVelYT1D1,WkVelYT1D2,WkVelYT1D3,WkVelYT1D4,WkVelYT1D5,WkVelYT1D6,WkVelYT1D7,WkVelYT1D8,WkVelYT1D9, & + WkVelYT2D1,WkVelYT2D2,WkVelYT2D3,WkVelYT2D4,WkVelYT2D5,WkVelYT2D6,WkVelYT2D7,WkVelYT2D8,WkVelYT2D9, & + WkVelYT3D1,WkVelYT3D2,WkVelYT3D3,WkVelYT3D4,WkVelYT3D5,WkVelYT3D6,WkVelYT3D7,WkVelYT3D8,WkVelYT3D9, & + WkVelYT4D1,WkVelYT4D2,WkVelYT4D3,WkVelYT4D4,WkVelYT4D5,WkVelYT4D6,WkVelYT4D7,WkVelYT4D8,WkVelYT4D9, & + WkVelYT5D1,WkVelYT5D2,WkVelYT5D3,WkVelYT5D4,WkVelYT5D5,WkVelYT5D6,WkVelYT5D7,WkVelYT5D8,WkVelYT5D9, & + WkVelYT6D1,WkVelYT6D2,WkVelYT6D3,WkVelYT6D4,WkVelYT6D5,WkVelYT6D6,WkVelYT6D7,WkVelYT6D8,WkVelYT6D9, & + WkVelYT7D1,WkVelYT7D2,WkVelYT7D3,WkVelYT7D4,WkVelYT7D5,WkVelYT7D6,WkVelYT7D7,WkVelYT7D8,WkVelYT7D9, & + WkVelYT8D1,WkVelYT8D2,WkVelYT8D3,WkVelYT8D4,WkVelYT8D5,WkVelYT8D6,WkVelYT8D7,WkVelYT8D8,WkVelYT8D9, & + WkVelYT9D1,WkVelYT9D2,WkVelYT9D3,WkVelYT9D4,WkVelYT9D5,WkVelYT9D6,WkVelYT9D7,WkVelYT9D8,WkVelYT9D9/), (/9,9/) ) + + INTEGER, PARAMETER :: WkVelZTD(9,9) = RESHAPE( & + (/WkVelZT1D1,WkVelZT1D2,WkVelZT1D3,WkVelZT1D4,WkVelZT1D5,WkVelZT1D6,WkVelZT1D7,WkVelZT1D8,WkVelZT1D9, & + WkVelZT2D1,WkVelZT2D2,WkVelZT2D3,WkVelZT2D4,WkVelZT2D5,WkVelZT2D6,WkVelZT2D7,WkVelZT2D8,WkVelZT2D9, & + WkVelZT3D1,WkVelZT3D2,WkVelZT3D3,WkVelZT3D4,WkVelZT3D5,WkVelZT3D6,WkVelZT3D7,WkVelZT3D8,WkVelZT3D9, & + WkVelZT4D1,WkVelZT4D2,WkVelZT4D3,WkVelZT4D4,WkVelZT4D5,WkVelZT4D6,WkVelZT4D7,WkVelZT4D8,WkVelZT4D9, & + WkVelZT5D1,WkVelZT5D2,WkVelZT5D3,WkVelZT5D4,WkVelZT5D5,WkVelZT5D6,WkVelZT5D7,WkVelZT5D8,WkVelZT5D9, & + WkVelZT6D1,WkVelZT6D2,WkVelZT6D3,WkVelZT6D4,WkVelZT6D5,WkVelZT6D6,WkVelZT6D7,WkVelZT6D8,WkVelZT6D9, & + WkVelZT7D1,WkVelZT7D2,WkVelZT7D3,WkVelZT7D4,WkVelZT7D5,WkVelZT7D6,WkVelZT7D7,WkVelZT7D8,WkVelZT7D9, & + WkVelZT8D1,WkVelZT8D2,WkVelZT8D3,WkVelZT8D4,WkVelZT8D5,WkVelZT8D6,WkVelZT8D7,WkVelZT8D8,WkVelZT8D9, & + WkVelZT9D1,WkVelZT9D2,WkVelZT9D3,WkVelZT9D4,WkVelZT9D5,WkVelZT9D6,WkVelZT9D7,WkVelZT9D8,WkVelZT9D9/), (/9,9/) ) + + INTEGER, PARAMETER :: WkDiamTD(9,9) = RESHAPE( & + (/WkDiamT1D1,WkDiamT1D2,WkDiamT1D3,WkDiamT1D4,WkDiamT1D5,WkDiamT1D6,WkDiamT1D7,WkDiamT1D8,WkDiamT1D9, & + WkDiamT2D1,WkDiamT2D2,WkDiamT2D3,WkDiamT2D4,WkDiamT2D5,WkDiamT2D6,WkDiamT2D7,WkDiamT2D8,WkDiamT2D9, & + WkDiamT3D1,WkDiamT3D2,WkDiamT3D3,WkDiamT3D4,WkDiamT3D5,WkDiamT3D6,WkDiamT3D7,WkDiamT3D8,WkDiamT3D9, & + WkDiamT4D1,WkDiamT4D2,WkDiamT4D3,WkDiamT4D4,WkDiamT4D5,WkDiamT4D6,WkDiamT4D7,WkDiamT4D8,WkDiamT4D9, & + WkDiamT5D1,WkDiamT5D2,WkDiamT5D3,WkDiamT5D4,WkDiamT5D5,WkDiamT5D6,WkDiamT5D7,WkDiamT5D8,WkDiamT5D9, & + WkDiamT6D1,WkDiamT6D2,WkDiamT6D3,WkDiamT6D4,WkDiamT6D5,WkDiamT6D6,WkDiamT6D7,WkDiamT6D8,WkDiamT6D9, & + WkDiamT7D1,WkDiamT7D2,WkDiamT7D3,WkDiamT7D4,WkDiamT7D5,WkDiamT7D6,WkDiamT7D7,WkDiamT7D8,WkDiamT7D9, & + WkDiamT8D1,WkDiamT8D2,WkDiamT8D3,WkDiamT8D4,WkDiamT8D5,WkDiamT8D6,WkDiamT8D7,WkDiamT8D8,WkDiamT8D9, & + WkDiamT9D1,WkDiamT9D2,WkDiamT9D3,WkDiamT9D4,WkDiamT9D5,WkDiamT9D6,WkDiamT9D7,WkDiamT9D8,WkDiamT9D9/), (/9,9/) ) + + INTEGER, PARAMETER :: WVAmbX(9) = (/W1VAmbX, W2VAmbX, W3VAmbX, W4VAmbX, W5VAmbX, W6VAmbX, W7VAmbX, W8VAmbX, W9VAmbX/) + INTEGER, PARAMETER :: WVAmbY(9) = (/W1VAmbY, W2VAmbY, W3VAmbY, W4VAmbY, W5VAmbY, W6VAmbY, W7VAmbY, W8VAmbY, W9VAmbY/) + INTEGER, PARAMETER :: WVAmbZ(9) = (/W1VAmbZ, W2VAmbZ, W3VAmbZ, W4VAmbZ, W5VAmbZ, W6VAmbZ, W7VAmbZ, W8VAmbZ, W9VAmbZ/) + + INTEGER, PARAMETER :: WVDisX(9) = (/W1VDisX, W2VDisX, W3VDisX, W4VDisX, W5VDisX, W6VDisX, W7VDisX, W8VDisX, W9VDisX/) + INTEGER, PARAMETER :: WVDisY(9) = (/W1VDisY, W2VDisY, W3VDisY, W4VDisY, W5VDisY, W6VDisY, W7VDisY, W8VDisY, W9VDisY/) + INTEGER, PARAMETER :: WVDisZ(9) = (/W1VDisZ, W2VDisZ, W3VDisZ, W4VDisZ, W5VDisZ, W6VDisZ, W7VDisZ, W8VDisZ, W9VDisZ/) + + INTEGER(IntKi) :: WkDfVxTND(20,9,9) + INTEGER(IntKi) :: WkDfVrTND(20,9,9) + INTEGER(IntKi) :: EddVisTND(20,9,9) + INTEGER(IntKi) :: EddAmbTND(20,9,9) + INTEGER(IntKi) :: EddShrTND(20,9,9) + public:: WkDfVxTND, WkDfVrTND, EddVisTND, EddAmbTND, EddShrTND + + + + + + + + + + + contains + +! --- Functions not automatically generated +logical function PointInAABB(x, y, z, x0, y0, z0, x1, y1, z1) + real(ReKi), intent(in) :: x,y,z,x0,y0,z0,x1,y1,z1 + + ! default to return false + PointInAABB = .false.; + !Check if the point is less than max and greater than min + if (x >= x0 .and. x <= x1 .and. y >= y0 .and. y <= y1 .and. z >= z0 .and. z <= z1) PointInAABB = .true.; + + +end function PointInAABB + +! These must be set prior to usage in the SetOutParam routine +SUBROUTINE Farm_SetAggregatedChannelOutArrays() +WkDfVxTND(:,:,1) = RESHAPE( & + (/WkDfVxT1N01D1,WkDfVxT1N02D1,WkDfVxT1N03D1,WkDfVxT1N04D1,WkDfVxT1N05D1,WkDfVxT1N06D1,WkDfVxT1N07D1,WkDfVxT1N08D1,WkDfVxT1N09D1,WkDfVxT1N10D1, & + WkDfVxT1N11D1,WkDfVxT1N12D1,WkDfVxT1N13D1,WkDfVxT1N14D1,WkDfVxT1N15D1,WkDfVxT1N16D1,WkDfVxT1N17D1,WkDfVxT1N18D1,WkDfVxT1N19D1,WkDfVxT1N20D1, & + WkDfVxT1N01D2,WkDfVxT1N02D2,WkDfVxT1N03D2,WkDfVxT1N04D2,WkDfVxT1N05D2,WkDfVxT1N06D2,WkDfVxT1N07D2,WkDfVxT1N08D2,WkDfVxT1N09D2,WkDfVxT1N10D2, & + WkDfVxT1N11D2,WkDfVxT1N12D2,WkDfVxT1N13D2,WkDfVxT1N14D2,WkDfVxT1N15D2,WkDfVxT1N16D2,WkDfVxT1N17D2,WkDfVxT1N18D2,WkDfVxT1N19D2,WkDfVxT1N20D2, & + WkDfVxT1N01D3,WkDfVxT1N02D3,WkDfVxT1N03D3,WkDfVxT1N04D3,WkDfVxT1N05D3,WkDfVxT1N06D3,WkDfVxT1N07D3,WkDfVxT1N08D3,WkDfVxT1N09D3,WkDfVxT1N10D3, & + WkDfVxT1N11D3,WkDfVxT1N12D3,WkDfVxT1N13D3,WkDfVxT1N14D3,WkDfVxT1N15D3,WkDfVxT1N16D3,WkDfVxT1N17D3,WkDfVxT1N18D3,WkDfVxT1N19D3,WkDfVxT1N20D3, & + WkDfVxT1N01D4,WkDfVxT1N02D4,WkDfVxT1N03D4,WkDfVxT1N04D4,WkDfVxT1N05D4,WkDfVxT1N06D4,WkDfVxT1N07D4,WkDfVxT1N08D4,WkDfVxT1N09D4,WkDfVxT1N10D4, & + WkDfVxT1N11D4,WkDfVxT1N12D4,WkDfVxT1N13D4,WkDfVxT1N14D4,WkDfVxT1N15D4,WkDfVxT1N16D4,WkDfVxT1N17D4,WkDfVxT1N18D4,WkDfVxT1N19D4,WkDfVxT1N20D4, & + WkDfVxT1N01D5,WkDfVxT1N02D5,WkDfVxT1N03D5,WkDfVxT1N04D5,WkDfVxT1N05D5,WkDfVxT1N06D5,WkDfVxT1N07D5,WkDfVxT1N08D5,WkDfVxT1N09D5,WkDfVxT1N10D5, & + WkDfVxT1N11D5,WkDfVxT1N12D5,WkDfVxT1N13D5,WkDfVxT1N14D5,WkDfVxT1N15D5,WkDfVxT1N16D5,WkDfVxT1N17D5,WkDfVxT1N18D5,WkDfVxT1N19D5,WkDfVxT1N20D5, & + WkDfVxT1N01D6,WkDfVxT1N02D6,WkDfVxT1N03D6,WkDfVxT1N04D6,WkDfVxT1N05D6,WkDfVxT1N06D6,WkDfVxT1N07D6,WkDfVxT1N08D6,WkDfVxT1N09D6,WkDfVxT1N10D6, & + WkDfVxT1N11D6,WkDfVxT1N12D6,WkDfVxT1N13D6,WkDfVxT1N14D6,WkDfVxT1N15D6,WkDfVxT1N16D6,WkDfVxT1N17D6,WkDfVxT1N18D6,WkDfVxT1N19D6,WkDfVxT1N20D6, & + WkDfVxT1N01D7,WkDfVxT1N02D7,WkDfVxT1N03D7,WkDfVxT1N04D7,WkDfVxT1N05D7,WkDfVxT1N06D7,WkDfVxT1N07D7,WkDfVxT1N08D7,WkDfVxT1N09D7,WkDfVxT1N10D7, & + WkDfVxT1N11D7,WkDfVxT1N12D7,WkDfVxT1N13D7,WkDfVxT1N14D7,WkDfVxT1N15D7,WkDfVxT1N16D7,WkDfVxT1N17D7,WkDfVxT1N18D7,WkDfVxT1N19D7,WkDfVxT1N20D7, & + WkDfVxT1N01D8,WkDfVxT1N02D8,WkDfVxT1N03D8,WkDfVxT1N04D8,WkDfVxT1N05D8,WkDfVxT1N06D8,WkDfVxT1N07D8,WkDfVxT1N08D8,WkDfVxT1N09D8,WkDfVxT1N10D8, & + WkDfVxT1N11D8,WkDfVxT1N12D8,WkDfVxT1N13D8,WkDfVxT1N14D8,WkDfVxT1N15D8,WkDfVxT1N16D8,WkDfVxT1N17D8,WkDfVxT1N18D8,WkDfVxT1N19D8,WkDfVxT1N20D8, & + WkDfVxT1N01D9,WkDfVxT1N02D9,WkDfVxT1N03D9,WkDfVxT1N04D9,WkDfVxT1N05D9,WkDfVxT1N06D9,WkDfVxT1N07D9,WkDfVxT1N08D9,WkDfVxT1N09D9,WkDfVxT1N10D9, & + WkDfVxT1N11D9,WkDfVxT1N12D9,WkDfVxT1N13D9,WkDfVxT1N14D9,WkDfVxT1N15D9,WkDfVxT1N16D9,WkDfVxT1N17D9,WkDfVxT1N18D9,WkDfVxT1N19D9,WkDfVxT1N20D9/), (/20,9/) ) + +WkDfVxTND(:,:,2) = RESHAPE( & + (/WkDfVxT2N01D1,WkDfVxT2N02D1,WkDfVxT2N03D1,WkDfVxT2N04D1,WkDfVxT2N05D1,WkDfVxT2N06D1,WkDfVxT2N07D1,WkDfVxT2N08D1,WkDfVxT2N09D1,WkDfVxT2N10D1, & + WkDfVxT2N11D1,WkDfVxT2N12D1,WkDfVxT2N13D1,WkDfVxT2N14D1,WkDfVxT2N15D1,WkDfVxT2N16D1,WkDfVxT2N17D1,WkDfVxT2N18D1,WkDfVxT2N19D1,WkDfVxT2N20D1, & + WkDfVxT2N01D2,WkDfVxT2N02D2,WkDfVxT2N03D2,WkDfVxT2N04D2,WkDfVxT2N05D2,WkDfVxT2N06D2,WkDfVxT2N07D2,WkDfVxT2N08D2,WkDfVxT2N09D2,WkDfVxT2N10D2, & + WkDfVxT2N11D2,WkDfVxT2N12D2,WkDfVxT2N13D2,WkDfVxT2N14D2,WkDfVxT2N15D2,WkDfVxT2N16D2,WkDfVxT2N17D2,WkDfVxT2N18D2,WkDfVxT2N19D2,WkDfVxT2N20D2, & + WkDfVxT2N01D3,WkDfVxT2N02D3,WkDfVxT2N03D3,WkDfVxT2N04D3,WkDfVxT2N05D3,WkDfVxT2N06D3,WkDfVxT2N07D3,WkDfVxT2N08D3,WkDfVxT2N09D3,WkDfVxT2N10D3, & + WkDfVxT2N11D3,WkDfVxT2N12D3,WkDfVxT2N13D3,WkDfVxT2N14D3,WkDfVxT2N15D3,WkDfVxT2N16D3,WkDfVxT2N17D3,WkDfVxT2N18D3,WkDfVxT2N19D3,WkDfVxT2N20D3, & + WkDfVxT2N01D4,WkDfVxT2N02D4,WkDfVxT2N03D4,WkDfVxT2N04D4,WkDfVxT2N05D4,WkDfVxT2N06D4,WkDfVxT2N07D4,WkDfVxT2N08D4,WkDfVxT2N09D4,WkDfVxT2N10D4, & + WkDfVxT2N11D4,WkDfVxT2N12D4,WkDfVxT2N13D4,WkDfVxT2N14D4,WkDfVxT2N15D4,WkDfVxT2N16D4,WkDfVxT2N17D4,WkDfVxT2N18D4,WkDfVxT2N19D4,WkDfVxT2N20D4, & + WkDfVxT2N01D5,WkDfVxT2N02D5,WkDfVxT2N03D5,WkDfVxT2N04D5,WkDfVxT2N05D5,WkDfVxT2N06D5,WkDfVxT2N07D5,WkDfVxT2N08D5,WkDfVxT2N09D5,WkDfVxT2N10D5, & + WkDfVxT2N11D5,WkDfVxT2N12D5,WkDfVxT2N13D5,WkDfVxT2N14D5,WkDfVxT2N15D5,WkDfVxT2N16D5,WkDfVxT2N17D5,WkDfVxT2N18D5,WkDfVxT2N19D5,WkDfVxT2N20D5, & + WkDfVxT2N01D6,WkDfVxT2N02D6,WkDfVxT2N03D6,WkDfVxT2N04D6,WkDfVxT2N05D6,WkDfVxT2N06D6,WkDfVxT2N07D6,WkDfVxT2N08D6,WkDfVxT2N09D6,WkDfVxT2N10D6, & + WkDfVxT2N11D6,WkDfVxT2N12D6,WkDfVxT2N13D6,WkDfVxT2N14D6,WkDfVxT2N15D6,WkDfVxT2N16D6,WkDfVxT2N17D6,WkDfVxT2N18D6,WkDfVxT2N19D6,WkDfVxT2N20D6, & + WkDfVxT2N01D7,WkDfVxT2N02D7,WkDfVxT2N03D7,WkDfVxT2N04D7,WkDfVxT2N05D7,WkDfVxT2N06D7,WkDfVxT2N07D7,WkDfVxT2N08D7,WkDfVxT2N09D7,WkDfVxT2N10D7, & + WkDfVxT2N11D7,WkDfVxT2N12D7,WkDfVxT2N13D7,WkDfVxT2N14D7,WkDfVxT2N15D7,WkDfVxT2N16D7,WkDfVxT2N17D7,WkDfVxT2N18D7,WkDfVxT2N19D7,WkDfVxT2N20D7, & + WkDfVxT2N01D8,WkDfVxT2N02D8,WkDfVxT2N03D8,WkDfVxT2N04D8,WkDfVxT2N05D8,WkDfVxT2N06D8,WkDfVxT2N07D8,WkDfVxT2N08D8,WkDfVxT2N09D8,WkDfVxT2N10D8, & + WkDfVxT2N11D8,WkDfVxT2N12D8,WkDfVxT2N13D8,WkDfVxT2N14D8,WkDfVxT2N15D8,WkDfVxT2N16D8,WkDfVxT2N17D8,WkDfVxT2N18D8,WkDfVxT2N19D8,WkDfVxT2N20D8, & + WkDfVxT2N01D9,WkDfVxT2N02D9,WkDfVxT2N03D9,WkDfVxT2N04D9,WkDfVxT2N05D9,WkDfVxT2N06D9,WkDfVxT2N07D9,WkDfVxT2N08D9,WkDfVxT2N09D9,WkDfVxT2N10D9, & + WkDfVxT2N11D9,WkDfVxT2N12D9,WkDfVxT2N13D9,WkDfVxT2N14D9,WkDfVxT2N15D9,WkDfVxT2N16D9,WkDfVxT2N17D9,WkDfVxT2N18D9,WkDfVxT2N19D9,WkDfVxT2N20D9/), (/20,9/) ) +WkDfVxTND(:,:,3) = RESHAPE( & + (/WkDfVxT3N01D1,WkDfVxT3N02D1,WkDfVxT3N03D1,WkDfVxT3N04D1,WkDfVxT3N05D1,WkDfVxT3N06D1,WkDfVxT3N07D1,WkDfVxT3N08D1,WkDfVxT3N09D1,WkDfVxT3N10D1, & + WkDfVxT3N11D1,WkDfVxT3N12D1,WkDfVxT3N13D1,WkDfVxT3N14D1,WkDfVxT3N15D1,WkDfVxT3N16D1,WkDfVxT3N17D1,WkDfVxT3N18D1,WkDfVxT3N19D1,WkDfVxT3N20D1, & + WkDfVxT3N01D2,WkDfVxT3N02D2,WkDfVxT3N03D2,WkDfVxT3N04D2,WkDfVxT3N05D2,WkDfVxT3N06D2,WkDfVxT3N07D2,WkDfVxT3N08D2,WkDfVxT3N09D2,WkDfVxT3N10D2, & + WkDfVxT3N11D2,WkDfVxT3N12D2,WkDfVxT3N13D2,WkDfVxT3N14D2,WkDfVxT3N15D2,WkDfVxT3N16D2,WkDfVxT3N17D2,WkDfVxT3N18D2,WkDfVxT3N19D2,WkDfVxT3N20D2, & + WkDfVxT3N01D3,WkDfVxT3N02D3,WkDfVxT3N03D3,WkDfVxT3N04D3,WkDfVxT3N05D3,WkDfVxT3N06D3,WkDfVxT3N07D3,WkDfVxT3N08D3,WkDfVxT3N09D3,WkDfVxT3N10D3, & + WkDfVxT3N11D3,WkDfVxT3N12D3,WkDfVxT3N13D3,WkDfVxT3N14D3,WkDfVxT3N15D3,WkDfVxT3N16D3,WkDfVxT3N17D3,WkDfVxT3N18D3,WkDfVxT3N19D3,WkDfVxT3N20D3, & + WkDfVxT3N01D4,WkDfVxT3N02D4,WkDfVxT3N03D4,WkDfVxT3N04D4,WkDfVxT3N05D4,WkDfVxT3N06D4,WkDfVxT3N07D4,WkDfVxT3N08D4,WkDfVxT3N09D4,WkDfVxT3N10D4, & + WkDfVxT3N11D4,WkDfVxT3N12D4,WkDfVxT3N13D4,WkDfVxT3N14D4,WkDfVxT3N15D4,WkDfVxT3N16D4,WkDfVxT3N17D4,WkDfVxT3N18D4,WkDfVxT3N19D4,WkDfVxT3N20D4, & + WkDfVxT3N01D5,WkDfVxT3N02D5,WkDfVxT3N03D5,WkDfVxT3N04D5,WkDfVxT3N05D5,WkDfVxT3N06D5,WkDfVxT3N07D5,WkDfVxT3N08D5,WkDfVxT3N09D5,WkDfVxT3N10D5, & + WkDfVxT3N11D5,WkDfVxT3N12D5,WkDfVxT3N13D5,WkDfVxT3N14D5,WkDfVxT3N15D5,WkDfVxT3N16D5,WkDfVxT3N17D5,WkDfVxT3N18D5,WkDfVxT3N19D5,WkDfVxT3N20D5, & + WkDfVxT3N01D6,WkDfVxT3N02D6,WkDfVxT3N03D6,WkDfVxT3N04D6,WkDfVxT3N05D6,WkDfVxT3N06D6,WkDfVxT3N07D6,WkDfVxT3N08D6,WkDfVxT3N09D6,WkDfVxT3N10D6, & + WkDfVxT3N11D6,WkDfVxT3N12D6,WkDfVxT3N13D6,WkDfVxT3N14D6,WkDfVxT3N15D6,WkDfVxT3N16D6,WkDfVxT3N17D6,WkDfVxT3N18D6,WkDfVxT3N19D6,WkDfVxT3N20D6, & + WkDfVxT3N01D7,WkDfVxT3N02D7,WkDfVxT3N03D7,WkDfVxT3N04D7,WkDfVxT3N05D7,WkDfVxT3N06D7,WkDfVxT3N07D7,WkDfVxT3N08D7,WkDfVxT3N09D7,WkDfVxT3N10D7, & + WkDfVxT3N11D7,WkDfVxT3N12D7,WkDfVxT3N13D7,WkDfVxT3N14D7,WkDfVxT3N15D7,WkDfVxT3N16D7,WkDfVxT3N17D7,WkDfVxT3N18D7,WkDfVxT3N19D7,WkDfVxT3N20D7, & + WkDfVxT3N01D8,WkDfVxT3N02D8,WkDfVxT3N03D8,WkDfVxT3N04D8,WkDfVxT3N05D8,WkDfVxT3N06D8,WkDfVxT3N07D8,WkDfVxT3N08D8,WkDfVxT3N09D8,WkDfVxT3N10D8, & + WkDfVxT3N11D8,WkDfVxT3N12D8,WkDfVxT3N13D8,WkDfVxT3N14D8,WkDfVxT3N15D8,WkDfVxT3N16D8,WkDfVxT3N17D8,WkDfVxT3N18D8,WkDfVxT3N19D8,WkDfVxT3N20D8, & + WkDfVxT3N01D9,WkDfVxT3N02D9,WkDfVxT3N03D9,WkDfVxT3N04D9,WkDfVxT3N05D9,WkDfVxT3N06D9,WkDfVxT3N07D9,WkDfVxT3N08D9,WkDfVxT3N09D9,WkDfVxT3N10D9, & + WkDfVxT3N11D9,WkDfVxT3N12D9,WkDfVxT3N13D9,WkDfVxT3N14D9,WkDfVxT3N15D9,WkDfVxT3N16D9,WkDfVxT3N17D9,WkDfVxT3N18D9,WkDfVxT3N19D9,WkDfVxT3N20D9/), (/20,9/) ) +WkDfVxTND(:,:,4) = RESHAPE( & + (/WkDfVxT4N01D1,WkDfVxT4N02D1,WkDfVxT4N03D1,WkDfVxT4N04D1,WkDfVxT4N05D1,WkDfVxT4N06D1,WkDfVxT4N07D1,WkDfVxT4N08D1,WkDfVxT4N09D1,WkDfVxT4N10D1, & + WkDfVxT4N11D1,WkDfVxT4N12D1,WkDfVxT4N13D1,WkDfVxT4N14D1,WkDfVxT4N15D1,WkDfVxT4N16D1,WkDfVxT4N17D1,WkDfVxT4N18D1,WkDfVxT4N19D1,WkDfVxT4N20D1, & + WkDfVxT4N01D2,WkDfVxT4N02D2,WkDfVxT4N03D2,WkDfVxT4N04D2,WkDfVxT4N05D2,WkDfVxT4N06D2,WkDfVxT4N07D2,WkDfVxT4N08D2,WkDfVxT4N09D2,WkDfVxT4N10D2, & + WkDfVxT4N11D2,WkDfVxT4N12D2,WkDfVxT4N13D2,WkDfVxT4N14D2,WkDfVxT4N15D2,WkDfVxT4N16D2,WkDfVxT4N17D2,WkDfVxT4N18D2,WkDfVxT4N19D2,WkDfVxT4N20D2, & + WkDfVxT4N01D3,WkDfVxT4N02D3,WkDfVxT4N03D3,WkDfVxT4N04D3,WkDfVxT4N05D3,WkDfVxT4N06D3,WkDfVxT4N07D3,WkDfVxT4N08D3,WkDfVxT4N09D3,WkDfVxT4N10D3, & + WkDfVxT4N11D3,WkDfVxT4N12D3,WkDfVxT4N13D3,WkDfVxT4N14D3,WkDfVxT4N15D3,WkDfVxT4N16D3,WkDfVxT4N17D3,WkDfVxT4N18D3,WkDfVxT4N19D3,WkDfVxT4N20D3, & + WkDfVxT4N01D4,WkDfVxT4N02D4,WkDfVxT4N03D4,WkDfVxT4N04D4,WkDfVxT4N05D4,WkDfVxT4N06D4,WkDfVxT4N07D4,WkDfVxT4N08D4,WkDfVxT4N09D4,WkDfVxT4N10D4, & + WkDfVxT4N11D4,WkDfVxT4N12D4,WkDfVxT4N13D4,WkDfVxT4N14D4,WkDfVxT4N15D4,WkDfVxT4N16D4,WkDfVxT4N17D4,WkDfVxT4N18D4,WkDfVxT4N19D4,WkDfVxT4N20D4, & + WkDfVxT4N01D5,WkDfVxT4N02D5,WkDfVxT4N03D5,WkDfVxT4N04D5,WkDfVxT4N05D5,WkDfVxT4N06D5,WkDfVxT4N07D5,WkDfVxT4N08D5,WkDfVxT4N09D5,WkDfVxT4N10D5, & + WkDfVxT4N11D5,WkDfVxT4N12D5,WkDfVxT4N13D5,WkDfVxT4N14D5,WkDfVxT4N15D5,WkDfVxT4N16D5,WkDfVxT4N17D5,WkDfVxT4N18D5,WkDfVxT4N19D5,WkDfVxT4N20D5, & + WkDfVxT4N01D6,WkDfVxT4N02D6,WkDfVxT4N03D6,WkDfVxT4N04D6,WkDfVxT4N05D6,WkDfVxT4N06D6,WkDfVxT4N07D6,WkDfVxT4N08D6,WkDfVxT4N09D6,WkDfVxT4N10D6, & + WkDfVxT4N11D6,WkDfVxT4N12D6,WkDfVxT4N13D6,WkDfVxT4N14D6,WkDfVxT4N15D6,WkDfVxT4N16D6,WkDfVxT4N17D6,WkDfVxT4N18D6,WkDfVxT4N19D6,WkDfVxT4N20D6, & + WkDfVxT4N01D7,WkDfVxT4N02D7,WkDfVxT4N03D7,WkDfVxT4N04D7,WkDfVxT4N05D7,WkDfVxT4N06D7,WkDfVxT4N07D7,WkDfVxT4N08D7,WkDfVxT4N09D7,WkDfVxT4N10D7, & + WkDfVxT4N11D7,WkDfVxT4N12D7,WkDfVxT4N13D7,WkDfVxT4N14D7,WkDfVxT4N15D7,WkDfVxT4N16D7,WkDfVxT4N17D7,WkDfVxT4N18D7,WkDfVxT4N19D7,WkDfVxT4N20D7, & + WkDfVxT4N01D8,WkDfVxT4N02D8,WkDfVxT4N03D8,WkDfVxT4N04D8,WkDfVxT4N05D8,WkDfVxT4N06D8,WkDfVxT4N07D8,WkDfVxT4N08D8,WkDfVxT4N09D8,WkDfVxT4N10D8, & + WkDfVxT4N11D8,WkDfVxT4N12D8,WkDfVxT4N13D8,WkDfVxT4N14D8,WkDfVxT4N15D8,WkDfVxT4N16D8,WkDfVxT4N17D8,WkDfVxT4N18D8,WkDfVxT4N19D8,WkDfVxT4N20D8, & + WkDfVxT4N01D9,WkDfVxT4N02D9,WkDfVxT4N03D9,WkDfVxT4N04D9,WkDfVxT4N05D9,WkDfVxT4N06D9,WkDfVxT4N07D9,WkDfVxT4N08D9,WkDfVxT4N09D9,WkDfVxT4N10D9, & + WkDfVxT4N11D9,WkDfVxT4N12D9,WkDfVxT4N13D9,WkDfVxT4N14D9,WkDfVxT4N15D9,WkDfVxT4N16D9,WkDfVxT4N17D9,WkDfVxT4N18D9,WkDfVxT4N19D9,WkDfVxT4N20D9/), (/20,9/) ) + +WkDfVxTND(:,:,5) = RESHAPE( & + (/WkDfVxT5N01D1,WkDfVxT5N02D1,WkDfVxT5N03D1,WkDfVxT5N04D1,WkDfVxT5N05D1,WkDfVxT5N06D1,WkDfVxT5N07D1,WkDfVxT5N08D1,WkDfVxT5N09D1,WkDfVxT5N10D1, & + WkDfVxT5N11D1,WkDfVxT5N12D1,WkDfVxT5N13D1,WkDfVxT5N14D1,WkDfVxT5N15D1,WkDfVxT5N16D1,WkDfVxT5N17D1,WkDfVxT5N18D1,WkDfVxT5N19D1,WkDfVxT5N20D1, & + WkDfVxT5N01D2,WkDfVxT5N02D2,WkDfVxT5N03D2,WkDfVxT5N04D2,WkDfVxT5N05D2,WkDfVxT5N06D2,WkDfVxT5N07D2,WkDfVxT5N08D2,WkDfVxT5N09D2,WkDfVxT5N10D2, & + WkDfVxT5N11D2,WkDfVxT5N12D2,WkDfVxT5N13D2,WkDfVxT5N14D2,WkDfVxT5N15D2,WkDfVxT5N16D2,WkDfVxT5N17D2,WkDfVxT5N18D2,WkDfVxT5N19D2,WkDfVxT5N20D2, & + WkDfVxT5N01D3,WkDfVxT5N02D3,WkDfVxT5N03D3,WkDfVxT5N04D3,WkDfVxT5N05D3,WkDfVxT5N06D3,WkDfVxT5N07D3,WkDfVxT5N08D3,WkDfVxT5N09D3,WkDfVxT5N10D3, & + WkDfVxT5N11D3,WkDfVxT5N12D3,WkDfVxT5N13D3,WkDfVxT5N14D3,WkDfVxT5N15D3,WkDfVxT5N16D3,WkDfVxT5N17D3,WkDfVxT5N18D3,WkDfVxT5N19D3,WkDfVxT5N20D3, & + WkDfVxT5N01D4,WkDfVxT5N02D4,WkDfVxT5N03D4,WkDfVxT5N04D4,WkDfVxT5N05D4,WkDfVxT5N06D4,WkDfVxT5N07D4,WkDfVxT5N08D4,WkDfVxT5N09D4,WkDfVxT5N10D4, & + WkDfVxT5N11D4,WkDfVxT5N12D4,WkDfVxT5N13D4,WkDfVxT5N14D4,WkDfVxT5N15D4,WkDfVxT5N16D4,WkDfVxT5N17D4,WkDfVxT5N18D4,WkDfVxT5N19D4,WkDfVxT5N20D4, & + WkDfVxT5N01D5,WkDfVxT5N02D5,WkDfVxT5N03D5,WkDfVxT5N04D5,WkDfVxT5N05D5,WkDfVxT5N06D5,WkDfVxT5N07D5,WkDfVxT5N08D5,WkDfVxT5N09D5,WkDfVxT5N10D5, & + WkDfVxT5N11D5,WkDfVxT5N12D5,WkDfVxT5N13D5,WkDfVxT5N14D5,WkDfVxT5N15D5,WkDfVxT5N16D5,WkDfVxT5N17D5,WkDfVxT5N18D5,WkDfVxT5N19D5,WkDfVxT5N20D5, & + WkDfVxT5N01D6,WkDfVxT5N02D6,WkDfVxT5N03D6,WkDfVxT5N04D6,WkDfVxT5N05D6,WkDfVxT5N06D6,WkDfVxT5N07D6,WkDfVxT5N08D6,WkDfVxT5N09D6,WkDfVxT5N10D6, & + WkDfVxT5N11D6,WkDfVxT5N12D6,WkDfVxT5N13D6,WkDfVxT5N14D6,WkDfVxT5N15D6,WkDfVxT5N16D6,WkDfVxT5N17D6,WkDfVxT5N18D6,WkDfVxT5N19D6,WkDfVxT5N20D6, & + WkDfVxT5N01D7,WkDfVxT5N02D7,WkDfVxT5N03D7,WkDfVxT5N04D7,WkDfVxT5N05D7,WkDfVxT5N06D7,WkDfVxT5N07D7,WkDfVxT5N08D7,WkDfVxT5N09D7,WkDfVxT5N10D7, & + WkDfVxT5N11D7,WkDfVxT5N12D7,WkDfVxT5N13D7,WkDfVxT5N14D7,WkDfVxT5N15D7,WkDfVxT5N16D7,WkDfVxT5N17D7,WkDfVxT5N18D7,WkDfVxT5N19D7,WkDfVxT5N20D7, & + WkDfVxT5N01D8,WkDfVxT5N02D8,WkDfVxT5N03D8,WkDfVxT5N04D8,WkDfVxT5N05D8,WkDfVxT5N06D8,WkDfVxT5N07D8,WkDfVxT5N08D8,WkDfVxT5N09D8,WkDfVxT5N10D8, & + WkDfVxT5N11D8,WkDfVxT5N12D8,WkDfVxT5N13D8,WkDfVxT5N14D8,WkDfVxT5N15D8,WkDfVxT5N16D8,WkDfVxT5N17D8,WkDfVxT5N18D8,WkDfVxT5N19D8,WkDfVxT5N20D8, & + WkDfVxT5N01D9,WkDfVxT5N02D9,WkDfVxT5N03D9,WkDfVxT5N04D9,WkDfVxT5N05D9,WkDfVxT5N06D9,WkDfVxT5N07D9,WkDfVxT5N08D9,WkDfVxT5N09D9,WkDfVxT5N10D9, & + WkDfVxT5N11D9,WkDfVxT5N12D9,WkDfVxT5N13D9,WkDfVxT5N14D9,WkDfVxT5N15D9,WkDfVxT5N16D9,WkDfVxT5N17D9,WkDfVxT5N18D9,WkDfVxT5N19D9,WkDfVxT5N20D9/), (/20,9/) ) +WkDfVxTND(:,:,6) = RESHAPE( & + (/WkDfVxT6N01D1,WkDfVxT6N02D1,WkDfVxT6N03D1,WkDfVxT6N04D1,WkDfVxT6N05D1,WkDfVxT6N06D1,WkDfVxT6N07D1,WkDfVxT6N08D1,WkDfVxT6N09D1,WkDfVxT6N10D1, & + WkDfVxT6N11D1,WkDfVxT6N12D1,WkDfVxT6N13D1,WkDfVxT6N14D1,WkDfVxT6N15D1,WkDfVxT6N16D1,WkDfVxT6N17D1,WkDfVxT6N18D1,WkDfVxT6N19D1,WkDfVxT6N20D1, & + WkDfVxT6N01D2,WkDfVxT6N02D2,WkDfVxT6N03D2,WkDfVxT6N04D2,WkDfVxT6N05D2,WkDfVxT6N06D2,WkDfVxT6N07D2,WkDfVxT6N08D2,WkDfVxT6N09D2,WkDfVxT6N10D2, & + WkDfVxT6N11D2,WkDfVxT6N12D2,WkDfVxT6N13D2,WkDfVxT6N14D2,WkDfVxT6N15D2,WkDfVxT6N16D2,WkDfVxT6N17D2,WkDfVxT6N18D2,WkDfVxT6N19D2,WkDfVxT6N20D2, & + WkDfVxT6N01D3,WkDfVxT6N02D3,WkDfVxT6N03D3,WkDfVxT6N04D3,WkDfVxT6N05D3,WkDfVxT6N06D3,WkDfVxT6N07D3,WkDfVxT6N08D3,WkDfVxT6N09D3,WkDfVxT6N10D3, & + WkDfVxT6N11D3,WkDfVxT6N12D3,WkDfVxT6N13D3,WkDfVxT6N14D3,WkDfVxT6N15D3,WkDfVxT6N16D3,WkDfVxT6N17D3,WkDfVxT6N18D3,WkDfVxT6N19D3,WkDfVxT6N20D3, & + WkDfVxT6N01D4,WkDfVxT6N02D4,WkDfVxT6N03D4,WkDfVxT6N04D4,WkDfVxT6N05D4,WkDfVxT6N06D4,WkDfVxT6N07D4,WkDfVxT6N08D4,WkDfVxT6N09D4,WkDfVxT6N10D4, & + WkDfVxT6N11D4,WkDfVxT6N12D4,WkDfVxT6N13D4,WkDfVxT6N14D4,WkDfVxT6N15D4,WkDfVxT6N16D4,WkDfVxT6N17D4,WkDfVxT6N18D4,WkDfVxT6N19D4,WkDfVxT6N20D4, & + WkDfVxT6N01D5,WkDfVxT6N02D5,WkDfVxT6N03D5,WkDfVxT6N04D5,WkDfVxT6N05D5,WkDfVxT6N06D5,WkDfVxT6N07D5,WkDfVxT6N08D5,WkDfVxT6N09D5,WkDfVxT6N10D5, & + WkDfVxT6N11D5,WkDfVxT6N12D5,WkDfVxT6N13D5,WkDfVxT6N14D5,WkDfVxT6N15D5,WkDfVxT6N16D5,WkDfVxT6N17D5,WkDfVxT6N18D5,WkDfVxT6N19D5,WkDfVxT6N20D5, & + WkDfVxT6N01D6,WkDfVxT6N02D6,WkDfVxT6N03D6,WkDfVxT6N04D6,WkDfVxT6N05D6,WkDfVxT6N06D6,WkDfVxT6N07D6,WkDfVxT6N08D6,WkDfVxT6N09D6,WkDfVxT6N10D6, & + WkDfVxT6N11D6,WkDfVxT6N12D6,WkDfVxT6N13D6,WkDfVxT6N14D6,WkDfVxT6N15D6,WkDfVxT6N16D6,WkDfVxT6N17D6,WkDfVxT6N18D6,WkDfVxT6N19D6,WkDfVxT6N20D6, & + WkDfVxT6N01D7,WkDfVxT6N02D7,WkDfVxT6N03D7,WkDfVxT6N04D7,WkDfVxT6N05D7,WkDfVxT6N06D7,WkDfVxT6N07D7,WkDfVxT6N08D7,WkDfVxT6N09D7,WkDfVxT6N10D7, & + WkDfVxT6N11D7,WkDfVxT6N12D7,WkDfVxT6N13D7,WkDfVxT6N14D7,WkDfVxT6N15D7,WkDfVxT6N16D7,WkDfVxT6N17D7,WkDfVxT6N18D7,WkDfVxT6N19D7,WkDfVxT6N20D7, & + WkDfVxT6N01D8,WkDfVxT6N02D8,WkDfVxT6N03D8,WkDfVxT6N04D8,WkDfVxT6N05D8,WkDfVxT6N06D8,WkDfVxT6N07D8,WkDfVxT6N08D8,WkDfVxT6N09D8,WkDfVxT6N10D8, & + WkDfVxT6N11D8,WkDfVxT6N12D8,WkDfVxT6N13D8,WkDfVxT6N14D8,WkDfVxT6N15D8,WkDfVxT6N16D8,WkDfVxT6N17D8,WkDfVxT6N18D8,WkDfVxT6N19D8,WkDfVxT6N20D8, & + WkDfVxT6N01D9,WkDfVxT6N02D9,WkDfVxT6N03D9,WkDfVxT6N04D9,WkDfVxT6N05D9,WkDfVxT6N06D9,WkDfVxT6N07D9,WkDfVxT6N08D9,WkDfVxT6N09D9,WkDfVxT6N10D9, & + WkDfVxT6N11D9,WkDfVxT6N12D9,WkDfVxT6N13D9,WkDfVxT6N14D9,WkDfVxT6N15D9,WkDfVxT6N16D9,WkDfVxT6N17D9,WkDfVxT6N18D9,WkDfVxT6N19D9,WkDfVxT6N20D9/), (/20,9/) ) +WkDfVxTND(:,:,7) = RESHAPE( & + (/WkDfVxT7N01D1,WkDfVxT7N02D1,WkDfVxT7N03D1,WkDfVxT7N04D1,WkDfVxT7N05D1,WkDfVxT7N06D1,WkDfVxT7N07D1,WkDfVxT7N08D1,WkDfVxT7N09D1,WkDfVxT7N10D1, & + WkDfVxT7N11D1,WkDfVxT7N12D1,WkDfVxT7N13D1,WkDfVxT7N14D1,WkDfVxT7N15D1,WkDfVxT7N16D1,WkDfVxT7N17D1,WkDfVxT7N18D1,WkDfVxT7N19D1,WkDfVxT7N20D1, & + WkDfVxT7N01D2,WkDfVxT7N02D2,WkDfVxT7N03D2,WkDfVxT7N04D2,WkDfVxT7N05D2,WkDfVxT7N06D2,WkDfVxT7N07D2,WkDfVxT7N08D2,WkDfVxT7N09D2,WkDfVxT7N10D2, & + WkDfVxT7N11D2,WkDfVxT7N12D2,WkDfVxT7N13D2,WkDfVxT7N14D2,WkDfVxT7N15D2,WkDfVxT7N16D2,WkDfVxT7N17D2,WkDfVxT7N18D2,WkDfVxT7N19D2,WkDfVxT7N20D2, & + WkDfVxT7N01D3,WkDfVxT7N02D3,WkDfVxT7N03D3,WkDfVxT7N04D3,WkDfVxT7N05D3,WkDfVxT7N06D3,WkDfVxT7N07D3,WkDfVxT7N08D3,WkDfVxT7N09D3,WkDfVxT7N10D3, & + WkDfVxT7N11D3,WkDfVxT7N12D3,WkDfVxT7N13D3,WkDfVxT7N14D3,WkDfVxT7N15D3,WkDfVxT7N16D3,WkDfVxT7N17D3,WkDfVxT7N18D3,WkDfVxT7N19D3,WkDfVxT7N20D3, & + WkDfVxT7N01D4,WkDfVxT7N02D4,WkDfVxT7N03D4,WkDfVxT7N04D4,WkDfVxT7N05D4,WkDfVxT7N06D4,WkDfVxT7N07D4,WkDfVxT7N08D4,WkDfVxT7N09D4,WkDfVxT7N10D4, & + WkDfVxT7N11D4,WkDfVxT7N12D4,WkDfVxT7N13D4,WkDfVxT7N14D4,WkDfVxT7N15D4,WkDfVxT7N16D4,WkDfVxT7N17D4,WkDfVxT7N18D4,WkDfVxT7N19D4,WkDfVxT7N20D4, & + WkDfVxT7N01D5,WkDfVxT7N02D5,WkDfVxT7N03D5,WkDfVxT7N04D5,WkDfVxT7N05D5,WkDfVxT7N06D5,WkDfVxT7N07D5,WkDfVxT7N08D5,WkDfVxT7N09D5,WkDfVxT7N10D5, & + WkDfVxT7N11D5,WkDfVxT7N12D5,WkDfVxT7N13D5,WkDfVxT7N14D5,WkDfVxT7N15D5,WkDfVxT7N16D5,WkDfVxT7N17D5,WkDfVxT7N18D5,WkDfVxT7N19D5,WkDfVxT7N20D5, & + WkDfVxT7N01D6,WkDfVxT7N02D6,WkDfVxT7N03D6,WkDfVxT7N04D6,WkDfVxT7N05D6,WkDfVxT7N06D6,WkDfVxT7N07D6,WkDfVxT7N08D6,WkDfVxT7N09D6,WkDfVxT7N10D6, & + WkDfVxT7N11D6,WkDfVxT7N12D6,WkDfVxT7N13D6,WkDfVxT7N14D6,WkDfVxT7N15D6,WkDfVxT7N16D6,WkDfVxT7N17D6,WkDfVxT7N18D6,WkDfVxT7N19D6,WkDfVxT7N20D6, & + WkDfVxT7N01D7,WkDfVxT7N02D7,WkDfVxT7N03D7,WkDfVxT7N04D7,WkDfVxT7N05D7,WkDfVxT7N06D7,WkDfVxT7N07D7,WkDfVxT7N08D7,WkDfVxT7N09D7,WkDfVxT7N10D7, & + WkDfVxT7N11D7,WkDfVxT7N12D7,WkDfVxT7N13D7,WkDfVxT7N14D7,WkDfVxT7N15D7,WkDfVxT7N16D7,WkDfVxT7N17D7,WkDfVxT7N18D7,WkDfVxT7N19D7,WkDfVxT7N20D7, & + WkDfVxT7N01D8,WkDfVxT7N02D8,WkDfVxT7N03D8,WkDfVxT7N04D8,WkDfVxT7N05D8,WkDfVxT7N06D8,WkDfVxT7N07D8,WkDfVxT7N08D8,WkDfVxT7N09D8,WkDfVxT7N10D8, & + WkDfVxT7N11D8,WkDfVxT7N12D8,WkDfVxT7N13D8,WkDfVxT7N14D8,WkDfVxT7N15D8,WkDfVxT7N16D8,WkDfVxT7N17D8,WkDfVxT7N18D8,WkDfVxT7N19D8,WkDfVxT7N20D8, & + WkDfVxT7N01D9,WkDfVxT7N02D9,WkDfVxT7N03D9,WkDfVxT7N04D9,WkDfVxT7N05D9,WkDfVxT7N06D9,WkDfVxT7N07D9,WkDfVxT7N08D9,WkDfVxT7N09D9,WkDfVxT7N10D9, & + WkDfVxT7N11D9,WkDfVxT7N12D9,WkDfVxT7N13D9,WkDfVxT7N14D9,WkDfVxT7N15D9,WkDfVxT7N16D9,WkDfVxT7N17D9,WkDfVxT7N18D9,WkDfVxT7N19D9,WkDfVxT7N20D9/), (/20,9/) ) +WkDfVxTND(:,:,8) = RESHAPE( & + (/WkDfVxT8N01D1,WkDfVxT8N02D1,WkDfVxT8N03D1,WkDfVxT8N04D1,WkDfVxT8N05D1,WkDfVxT8N06D1,WkDfVxT8N07D1,WkDfVxT8N08D1,WkDfVxT8N09D1,WkDfVxT8N10D1, & + WkDfVxT8N11D1,WkDfVxT8N12D1,WkDfVxT8N13D1,WkDfVxT8N14D1,WkDfVxT8N15D1,WkDfVxT8N16D1,WkDfVxT8N17D1,WkDfVxT8N18D1,WkDfVxT8N19D1,WkDfVxT8N20D1, & + WkDfVxT8N01D2,WkDfVxT8N02D2,WkDfVxT8N03D2,WkDfVxT8N04D2,WkDfVxT8N05D2,WkDfVxT8N06D2,WkDfVxT8N07D2,WkDfVxT8N08D2,WkDfVxT8N09D2,WkDfVxT8N10D2, & + WkDfVxT8N11D2,WkDfVxT8N12D2,WkDfVxT8N13D2,WkDfVxT8N14D2,WkDfVxT8N15D2,WkDfVxT8N16D2,WkDfVxT8N17D2,WkDfVxT8N18D2,WkDfVxT8N19D2,WkDfVxT8N20D2, & + WkDfVxT8N01D3,WkDfVxT8N02D3,WkDfVxT8N03D3,WkDfVxT8N04D3,WkDfVxT8N05D3,WkDfVxT8N06D3,WkDfVxT8N07D3,WkDfVxT8N08D3,WkDfVxT8N09D3,WkDfVxT8N10D3, & + WkDfVxT8N11D3,WkDfVxT8N12D3,WkDfVxT8N13D3,WkDfVxT8N14D3,WkDfVxT8N15D3,WkDfVxT8N16D3,WkDfVxT8N17D3,WkDfVxT8N18D3,WkDfVxT8N19D3,WkDfVxT8N20D3, & + WkDfVxT8N01D4,WkDfVxT8N02D4,WkDfVxT8N03D4,WkDfVxT8N04D4,WkDfVxT8N05D4,WkDfVxT8N06D4,WkDfVxT8N07D4,WkDfVxT8N08D4,WkDfVxT8N09D4,WkDfVxT8N10D4, & + WkDfVxT8N11D4,WkDfVxT8N12D4,WkDfVxT8N13D4,WkDfVxT8N14D4,WkDfVxT8N15D4,WkDfVxT8N16D4,WkDfVxT8N17D4,WkDfVxT8N18D4,WkDfVxT8N19D4,WkDfVxT8N20D4, & + WkDfVxT8N01D5,WkDfVxT8N02D5,WkDfVxT8N03D5,WkDfVxT8N04D5,WkDfVxT8N05D5,WkDfVxT8N06D5,WkDfVxT8N07D5,WkDfVxT8N08D5,WkDfVxT8N09D5,WkDfVxT8N10D5, & + WkDfVxT8N11D5,WkDfVxT8N12D5,WkDfVxT8N13D5,WkDfVxT8N14D5,WkDfVxT8N15D5,WkDfVxT8N16D5,WkDfVxT8N17D5,WkDfVxT8N18D5,WkDfVxT8N19D5,WkDfVxT8N20D5, & + WkDfVxT8N01D6,WkDfVxT8N02D6,WkDfVxT8N03D6,WkDfVxT8N04D6,WkDfVxT8N05D6,WkDfVxT8N06D6,WkDfVxT8N07D6,WkDfVxT8N08D6,WkDfVxT8N09D6,WkDfVxT8N10D6, & + WkDfVxT8N11D6,WkDfVxT8N12D6,WkDfVxT8N13D6,WkDfVxT8N14D6,WkDfVxT8N15D6,WkDfVxT8N16D6,WkDfVxT8N17D6,WkDfVxT8N18D6,WkDfVxT8N19D6,WkDfVxT8N20D6, & + WkDfVxT8N01D7,WkDfVxT8N02D7,WkDfVxT8N03D7,WkDfVxT8N04D7,WkDfVxT8N05D7,WkDfVxT8N06D7,WkDfVxT8N07D7,WkDfVxT8N08D7,WkDfVxT8N09D7,WkDfVxT8N10D7, & + WkDfVxT8N11D7,WkDfVxT8N12D7,WkDfVxT8N13D7,WkDfVxT8N14D7,WkDfVxT8N15D7,WkDfVxT8N16D7,WkDfVxT8N17D7,WkDfVxT8N18D7,WkDfVxT8N19D7,WkDfVxT8N20D7, & + WkDfVxT8N01D8,WkDfVxT8N02D8,WkDfVxT8N03D8,WkDfVxT8N04D8,WkDfVxT8N05D8,WkDfVxT8N06D8,WkDfVxT8N07D8,WkDfVxT8N08D8,WkDfVxT8N09D8,WkDfVxT8N10D8, & + WkDfVxT8N11D8,WkDfVxT8N12D8,WkDfVxT8N13D8,WkDfVxT8N14D8,WkDfVxT8N15D8,WkDfVxT8N16D8,WkDfVxT8N17D8,WkDfVxT8N18D8,WkDfVxT8N19D8,WkDfVxT8N20D8, & + WkDfVxT8N01D9,WkDfVxT8N02D9,WkDfVxT8N03D9,WkDfVxT8N04D9,WkDfVxT8N05D9,WkDfVxT8N06D9,WkDfVxT8N07D9,WkDfVxT8N08D9,WkDfVxT8N09D9,WkDfVxT8N10D9, & + WkDfVxT8N11D9,WkDfVxT8N12D9,WkDfVxT8N13D9,WkDfVxT8N14D9,WkDfVxT8N15D9,WkDfVxT8N16D9,WkDfVxT8N17D9,WkDfVxT8N18D9,WkDfVxT8N19D9,WkDfVxT8N20D9/), (/20,9/) ) + +WkDfVxTND(:,:,9) = RESHAPE( & + (/WkDfVxT9N01D1,WkDfVxT9N02D1,WkDfVxT9N03D1,WkDfVxT9N04D1,WkDfVxT9N05D1,WkDfVxT9N06D1,WkDfVxT9N07D1,WkDfVxT9N08D1,WkDfVxT9N09D1,WkDfVxT9N10D1, & + WkDfVxT9N11D1,WkDfVxT9N12D1,WkDfVxT9N13D1,WkDfVxT9N14D1,WkDfVxT9N15D1,WkDfVxT9N16D1,WkDfVxT9N17D1,WkDfVxT9N18D1,WkDfVxT9N19D1,WkDfVxT9N20D1, & + WkDfVxT9N01D2,WkDfVxT9N02D2,WkDfVxT9N03D2,WkDfVxT9N04D2,WkDfVxT9N05D2,WkDfVxT9N06D2,WkDfVxT9N07D2,WkDfVxT9N08D2,WkDfVxT9N09D2,WkDfVxT9N10D2, & + WkDfVxT9N11D2,WkDfVxT9N12D2,WkDfVxT9N13D2,WkDfVxT9N14D2,WkDfVxT9N15D2,WkDfVxT9N16D2,WkDfVxT9N17D2,WkDfVxT9N18D2,WkDfVxT9N19D2,WkDfVxT9N20D2, & + WkDfVxT9N01D3,WkDfVxT9N02D3,WkDfVxT9N03D3,WkDfVxT9N04D3,WkDfVxT9N05D3,WkDfVxT9N06D3,WkDfVxT9N07D3,WkDfVxT9N08D3,WkDfVxT9N09D3,WkDfVxT9N10D3, & + WkDfVxT9N11D3,WkDfVxT9N12D3,WkDfVxT9N13D3,WkDfVxT9N14D3,WkDfVxT9N15D3,WkDfVxT9N16D3,WkDfVxT9N17D3,WkDfVxT9N18D3,WkDfVxT9N19D3,WkDfVxT9N20D3, & + WkDfVxT9N01D4,WkDfVxT9N02D4,WkDfVxT9N03D4,WkDfVxT9N04D4,WkDfVxT9N05D4,WkDfVxT9N06D4,WkDfVxT9N07D4,WkDfVxT9N08D4,WkDfVxT9N09D4,WkDfVxT9N10D4, & + WkDfVxT9N11D4,WkDfVxT9N12D4,WkDfVxT9N13D4,WkDfVxT9N14D4,WkDfVxT9N15D4,WkDfVxT9N16D4,WkDfVxT9N17D4,WkDfVxT9N18D4,WkDfVxT9N19D4,WkDfVxT9N20D4, & + WkDfVxT9N01D5,WkDfVxT9N02D5,WkDfVxT9N03D5,WkDfVxT9N04D5,WkDfVxT9N05D5,WkDfVxT9N06D5,WkDfVxT9N07D5,WkDfVxT9N08D5,WkDfVxT9N09D5,WkDfVxT9N10D5, & + WkDfVxT9N11D5,WkDfVxT9N12D5,WkDfVxT9N13D5,WkDfVxT9N14D5,WkDfVxT9N15D5,WkDfVxT9N16D5,WkDfVxT9N17D5,WkDfVxT9N18D5,WkDfVxT9N19D5,WkDfVxT9N20D5, & + WkDfVxT9N01D6,WkDfVxT9N02D6,WkDfVxT9N03D6,WkDfVxT9N04D6,WkDfVxT9N05D6,WkDfVxT9N06D6,WkDfVxT9N07D6,WkDfVxT9N08D6,WkDfVxT9N09D6,WkDfVxT9N10D6, & + WkDfVxT9N11D6,WkDfVxT9N12D6,WkDfVxT9N13D6,WkDfVxT9N14D6,WkDfVxT9N15D6,WkDfVxT9N16D6,WkDfVxT9N17D6,WkDfVxT9N18D6,WkDfVxT9N19D6,WkDfVxT9N20D6, & + WkDfVxT9N01D7,WkDfVxT9N02D7,WkDfVxT9N03D7,WkDfVxT9N04D7,WkDfVxT9N05D7,WkDfVxT9N06D7,WkDfVxT9N07D7,WkDfVxT9N08D7,WkDfVxT9N09D7,WkDfVxT9N10D7, & + WkDfVxT9N11D7,WkDfVxT9N12D7,WkDfVxT9N13D7,WkDfVxT9N14D7,WkDfVxT9N15D7,WkDfVxT9N16D7,WkDfVxT9N17D7,WkDfVxT9N18D7,WkDfVxT9N19D7,WkDfVxT9N20D7, & + WkDfVxT9N01D8,WkDfVxT9N02D8,WkDfVxT9N03D8,WkDfVxT9N04D8,WkDfVxT9N05D8,WkDfVxT9N06D8,WkDfVxT9N07D8,WkDfVxT9N08D8,WkDfVxT9N09D8,WkDfVxT9N10D8, & + WkDfVxT9N11D8,WkDfVxT9N12D8,WkDfVxT9N13D8,WkDfVxT9N14D8,WkDfVxT9N15D8,WkDfVxT9N16D8,WkDfVxT9N17D8,WkDfVxT9N18D8,WkDfVxT9N19D8,WkDfVxT9N20D8, & + WkDfVxT9N01D9,WkDfVxT9N02D9,WkDfVxT9N03D9,WkDfVxT9N04D9,WkDfVxT9N05D9,WkDfVxT9N06D9,WkDfVxT9N07D9,WkDfVxT9N08D9,WkDfVxT9N09D9,WkDfVxT9N10D9, & + WkDfVxT9N11D9,WkDfVxT9N12D9,WkDfVxT9N13D9,WkDfVxT9N14D9,WkDfVxT9N15D9,WkDfVxT9N16D9,WkDfVxT9N17D9,WkDfVxT9N18D9,WkDfVxT9N19D9,WkDfVxT9N20D9/), (/20,9/) ) + + +WkDfVrTND(:,:,1) = RESHAPE( & + (/WkDfVrT1N01D1,WkDfVrT1N02D1,WkDfVrT1N03D1,WkDfVrT1N04D1,WkDfVrT1N05D1,WkDfVrT1N06D1,WkDfVrT1N07D1,WkDfVrT1N08D1,WkDfVrT1N09D1,WkDfVrT1N10D1, & + WkDfVrT1N11D1,WkDfVrT1N12D1,WkDfVrT1N13D1,WkDfVrT1N14D1,WkDfVrT1N15D1,WkDfVrT1N16D1,WkDfVrT1N17D1,WkDfVrT1N18D1,WkDfVrT1N19D1,WkDfVrT1N20D1, & + WkDfVrT1N01D2,WkDfVrT1N02D2,WkDfVrT1N03D2,WkDfVrT1N04D2,WkDfVrT1N05D2,WkDfVrT1N06D2,WkDfVrT1N07D2,WkDfVrT1N08D2,WkDfVrT1N09D2,WkDfVrT1N10D2, & + WkDfVrT1N11D2,WkDfVrT1N12D2,WkDfVrT1N13D2,WkDfVrT1N14D2,WkDfVrT1N15D2,WkDfVrT1N16D2,WkDfVrT1N17D2,WkDfVrT1N18D2,WkDfVrT1N19D2,WkDfVrT1N20D2, & + WkDfVrT1N01D3,WkDfVrT1N02D3,WkDfVrT1N03D3,WkDfVrT1N04D3,WkDfVrT1N05D3,WkDfVrT1N06D3,WkDfVrT1N07D3,WkDfVrT1N08D3,WkDfVrT1N09D3,WkDfVrT1N10D3, & + WkDfVrT1N11D3,WkDfVrT1N12D3,WkDfVrT1N13D3,WkDfVrT1N14D3,WkDfVrT1N15D3,WkDfVrT1N16D3,WkDfVrT1N17D3,WkDfVrT1N18D3,WkDfVrT1N19D3,WkDfVrT1N20D3, & + WkDfVrT1N01D4,WkDfVrT1N02D4,WkDfVrT1N03D4,WkDfVrT1N04D4,WkDfVrT1N05D4,WkDfVrT1N06D4,WkDfVrT1N07D4,WkDfVrT1N08D4,WkDfVrT1N09D4,WkDfVrT1N10D4, & + WkDfVrT1N11D4,WkDfVrT1N12D4,WkDfVrT1N13D4,WkDfVrT1N14D4,WkDfVrT1N15D4,WkDfVrT1N16D4,WkDfVrT1N17D4,WkDfVrT1N18D4,WkDfVrT1N19D4,WkDfVrT1N20D4, & + WkDfVrT1N01D5,WkDfVrT1N02D5,WkDfVrT1N03D5,WkDfVrT1N04D5,WkDfVrT1N05D5,WkDfVrT1N06D5,WkDfVrT1N07D5,WkDfVrT1N08D5,WkDfVrT1N09D5,WkDfVrT1N10D5, & + WkDfVrT1N11D5,WkDfVrT1N12D5,WkDfVrT1N13D5,WkDfVrT1N14D5,WkDfVrT1N15D5,WkDfVrT1N16D5,WkDfVrT1N17D5,WkDfVrT1N18D5,WkDfVrT1N19D5,WkDfVrT1N20D5, & + WkDfVrT1N01D6,WkDfVrT1N02D6,WkDfVrT1N03D6,WkDfVrT1N04D6,WkDfVrT1N05D6,WkDfVrT1N06D6,WkDfVrT1N07D6,WkDfVrT1N08D6,WkDfVrT1N09D6,WkDfVrT1N10D6, & + WkDfVrT1N11D6,WkDfVrT1N12D6,WkDfVrT1N13D6,WkDfVrT1N14D6,WkDfVrT1N15D6,WkDfVrT1N16D6,WkDfVrT1N17D6,WkDfVrT1N18D6,WkDfVrT1N19D6,WkDfVrT1N20D6, & + WkDfVrT1N01D7,WkDfVrT1N02D7,WkDfVrT1N03D7,WkDfVrT1N04D7,WkDfVrT1N05D7,WkDfVrT1N06D7,WkDfVrT1N07D7,WkDfVrT1N08D7,WkDfVrT1N09D7,WkDfVrT1N10D7, & + WkDfVrT1N11D7,WkDfVrT1N12D7,WkDfVrT1N13D7,WkDfVrT1N14D7,WkDfVrT1N15D7,WkDfVrT1N16D7,WkDfVrT1N17D7,WkDfVrT1N18D7,WkDfVrT1N19D7,WkDfVrT1N20D7, & + WkDfVrT1N01D8,WkDfVrT1N02D8,WkDfVrT1N03D8,WkDfVrT1N04D8,WkDfVrT1N05D8,WkDfVrT1N06D8,WkDfVrT1N07D8,WkDfVrT1N08D8,WkDfVrT1N09D8,WkDfVrT1N10D8, & + WkDfVrT1N11D8,WkDfVrT1N12D8,WkDfVrT1N13D8,WkDfVrT1N14D8,WkDfVrT1N15D8,WkDfVrT1N16D8,WkDfVrT1N17D8,WkDfVrT1N18D8,WkDfVrT1N19D8,WkDfVrT1N20D8, & + WkDfVrT1N01D9,WkDfVrT1N02D9,WkDfVrT1N03D9,WkDfVrT1N04D9,WkDfVrT1N05D9,WkDfVrT1N06D9,WkDfVrT1N07D9,WkDfVrT1N08D9,WkDfVrT1N09D9,WkDfVrT1N10D9, & + WkDfVrT1N11D9,WkDfVrT1N12D9,WkDfVrT1N13D9,WkDfVrT1N14D9,WkDfVrT1N15D9,WkDfVrT1N16D9,WkDfVrT1N17D9,WkDfVrT1N18D9,WkDfVrT1N19D9,WkDfVrT1N20D9/), (/20,9/) ) +WkDfVrTND(:,:,2) = RESHAPE( & + (/WkDfVrT2N01D1,WkDfVrT2N02D1,WkDfVrT2N03D1,WkDfVrT2N04D1,WkDfVrT2N05D1,WkDfVrT2N06D1,WkDfVrT2N07D1,WkDfVrT2N08D1,WkDfVrT2N09D1,WkDfVrT2N10D1, & + WkDfVrT2N11D1,WkDfVrT2N12D1,WkDfVrT2N13D1,WkDfVrT2N14D1,WkDfVrT2N15D1,WkDfVrT2N16D1,WkDfVrT2N17D1,WkDfVrT2N18D1,WkDfVrT2N19D1,WkDfVrT2N20D1, & + WkDfVrT2N01D2,WkDfVrT2N02D2,WkDfVrT2N03D2,WkDfVrT2N04D2,WkDfVrT2N05D2,WkDfVrT2N06D2,WkDfVrT2N07D2,WkDfVrT2N08D2,WkDfVrT2N09D2,WkDfVrT2N10D2, & + WkDfVrT2N11D2,WkDfVrT2N12D2,WkDfVrT2N13D2,WkDfVrT2N14D2,WkDfVrT2N15D2,WkDfVrT2N16D2,WkDfVrT2N17D2,WkDfVrT2N18D2,WkDfVrT2N19D2,WkDfVrT2N20D2, & + WkDfVrT2N01D3,WkDfVrT2N02D3,WkDfVrT2N03D3,WkDfVrT2N04D3,WkDfVrT2N05D3,WkDfVrT2N06D3,WkDfVrT2N07D3,WkDfVrT2N08D3,WkDfVrT2N09D3,WkDfVrT2N10D3, & + WkDfVrT2N11D3,WkDfVrT2N12D3,WkDfVrT2N13D3,WkDfVrT2N14D3,WkDfVrT2N15D3,WkDfVrT2N16D3,WkDfVrT2N17D3,WkDfVrT2N18D3,WkDfVrT2N19D3,WkDfVrT2N20D3, & + WkDfVrT2N01D4,WkDfVrT2N02D4,WkDfVrT2N03D4,WkDfVrT2N04D4,WkDfVrT2N05D4,WkDfVrT2N06D4,WkDfVrT2N07D4,WkDfVrT2N08D4,WkDfVrT2N09D4,WkDfVrT2N10D4, & + WkDfVrT2N11D4,WkDfVrT2N12D4,WkDfVrT2N13D4,WkDfVrT2N14D4,WkDfVrT2N15D4,WkDfVrT2N16D4,WkDfVrT2N17D4,WkDfVrT2N18D4,WkDfVrT2N19D4,WkDfVrT2N20D4, & + WkDfVrT2N01D5,WkDfVrT2N02D5,WkDfVrT2N03D5,WkDfVrT2N04D5,WkDfVrT2N05D5,WkDfVrT2N06D5,WkDfVrT2N07D5,WkDfVrT2N08D5,WkDfVrT2N09D5,WkDfVrT2N10D5, & + WkDfVrT2N11D5,WkDfVrT2N12D5,WkDfVrT2N13D5,WkDfVrT2N14D5,WkDfVrT2N15D5,WkDfVrT2N16D5,WkDfVrT2N17D5,WkDfVrT2N18D5,WkDfVrT2N19D5,WkDfVrT2N20D5, & + WkDfVrT2N01D6,WkDfVrT2N02D6,WkDfVrT2N03D6,WkDfVrT2N04D6,WkDfVrT2N05D6,WkDfVrT2N06D6,WkDfVrT2N07D6,WkDfVrT2N08D6,WkDfVrT2N09D6,WkDfVrT2N10D6, & + WkDfVrT2N11D6,WkDfVrT2N12D6,WkDfVrT2N13D6,WkDfVrT2N14D6,WkDfVrT2N15D6,WkDfVrT2N16D6,WkDfVrT2N17D6,WkDfVrT2N18D6,WkDfVrT2N19D6,WkDfVrT2N20D6, & + WkDfVrT2N01D7,WkDfVrT2N02D7,WkDfVrT2N03D7,WkDfVrT2N04D7,WkDfVrT2N05D7,WkDfVrT2N06D7,WkDfVrT2N07D7,WkDfVrT2N08D7,WkDfVrT2N09D7,WkDfVrT2N10D7, & + WkDfVrT2N11D7,WkDfVrT2N12D7,WkDfVrT2N13D7,WkDfVrT2N14D7,WkDfVrT2N15D7,WkDfVrT2N16D7,WkDfVrT2N17D7,WkDfVrT2N18D7,WkDfVrT2N19D7,WkDfVrT2N20D7, & + WkDfVrT2N01D8,WkDfVrT2N02D8,WkDfVrT2N03D8,WkDfVrT2N04D8,WkDfVrT2N05D8,WkDfVrT2N06D8,WkDfVrT2N07D8,WkDfVrT2N08D8,WkDfVrT2N09D8,WkDfVrT2N10D8, & + WkDfVrT2N11D8,WkDfVrT2N12D8,WkDfVrT2N13D8,WkDfVrT2N14D8,WkDfVrT2N15D8,WkDfVrT2N16D8,WkDfVrT2N17D8,WkDfVrT2N18D8,WkDfVrT2N19D8,WkDfVrT2N20D8, & + WkDfVrT2N01D9,WkDfVrT2N02D9,WkDfVrT2N03D9,WkDfVrT2N04D9,WkDfVrT2N05D9,WkDfVrT2N06D9,WkDfVrT2N07D9,WkDfVrT2N08D9,WkDfVrT2N09D9,WkDfVrT2N10D9, & + WkDfVrT2N11D9,WkDfVrT2N12D9,WkDfVrT2N13D9,WkDfVrT2N14D9,WkDfVrT2N15D9,WkDfVrT2N16D9,WkDfVrT2N17D9,WkDfVrT2N18D9,WkDfVrT2N19D9,WkDfVrT2N20D9/), (/20,9/) ) +WkDfVrTND(:,:,3) = RESHAPE( & + (/WkDfVrT3N01D1,WkDfVrT3N02D1,WkDfVrT3N03D1,WkDfVrT3N04D1,WkDfVrT3N05D1,WkDfVrT3N06D1,WkDfVrT3N07D1,WkDfVrT3N08D1,WkDfVrT3N09D1,WkDfVrT3N10D1, & + WkDfVrT3N11D1,WkDfVrT3N12D1,WkDfVrT3N13D1,WkDfVrT3N14D1,WkDfVrT3N15D1,WkDfVrT3N16D1,WkDfVrT3N17D1,WkDfVrT3N18D1,WkDfVrT3N19D1,WkDfVrT3N20D1, & + WkDfVrT3N01D2,WkDfVrT3N02D2,WkDfVrT3N03D2,WkDfVrT3N04D2,WkDfVrT3N05D2,WkDfVrT3N06D2,WkDfVrT3N07D2,WkDfVrT3N08D2,WkDfVrT3N09D2,WkDfVrT3N10D2, & + WkDfVrT3N11D2,WkDfVrT3N12D2,WkDfVrT3N13D2,WkDfVrT3N14D2,WkDfVrT3N15D2,WkDfVrT3N16D2,WkDfVrT3N17D2,WkDfVrT3N18D2,WkDfVrT3N19D2,WkDfVrT3N20D2, & + WkDfVrT3N01D3,WkDfVrT3N02D3,WkDfVrT3N03D3,WkDfVrT3N04D3,WkDfVrT3N05D3,WkDfVrT3N06D3,WkDfVrT3N07D3,WkDfVrT3N08D3,WkDfVrT3N09D3,WkDfVrT3N10D3, & + WkDfVrT3N11D3,WkDfVrT3N12D3,WkDfVrT3N13D3,WkDfVrT3N14D3,WkDfVrT3N15D3,WkDfVrT3N16D3,WkDfVrT3N17D3,WkDfVrT3N18D3,WkDfVrT3N19D3,WkDfVrT3N20D3, & + WkDfVrT3N01D4,WkDfVrT3N02D4,WkDfVrT3N03D4,WkDfVrT3N04D4,WkDfVrT3N05D4,WkDfVrT3N06D4,WkDfVrT3N07D4,WkDfVrT3N08D4,WkDfVrT3N09D4,WkDfVrT3N10D4, & + WkDfVrT3N11D4,WkDfVrT3N12D4,WkDfVrT3N13D4,WkDfVrT3N14D4,WkDfVrT3N15D4,WkDfVrT3N16D4,WkDfVrT3N17D4,WkDfVrT3N18D4,WkDfVrT3N19D4,WkDfVrT3N20D4, & + WkDfVrT3N01D5,WkDfVrT3N02D5,WkDfVrT3N03D5,WkDfVrT3N04D5,WkDfVrT3N05D5,WkDfVrT3N06D5,WkDfVrT3N07D5,WkDfVrT3N08D5,WkDfVrT3N09D5,WkDfVrT3N10D5, & + WkDfVrT3N11D5,WkDfVrT3N12D5,WkDfVrT3N13D5,WkDfVrT3N14D5,WkDfVrT3N15D5,WkDfVrT3N16D5,WkDfVrT3N17D5,WkDfVrT3N18D5,WkDfVrT3N19D5,WkDfVrT3N20D5, & + WkDfVrT3N01D6,WkDfVrT3N02D6,WkDfVrT3N03D6,WkDfVrT3N04D6,WkDfVrT3N05D6,WkDfVrT3N06D6,WkDfVrT3N07D6,WkDfVrT3N08D6,WkDfVrT3N09D6,WkDfVrT3N10D6, & + WkDfVrT3N11D6,WkDfVrT3N12D6,WkDfVrT3N13D6,WkDfVrT3N14D6,WkDfVrT3N15D6,WkDfVrT3N16D6,WkDfVrT3N17D6,WkDfVrT3N18D6,WkDfVrT3N19D6,WkDfVrT3N20D6, & + WkDfVrT3N01D7,WkDfVrT3N02D7,WkDfVrT3N03D7,WkDfVrT3N04D7,WkDfVrT3N05D7,WkDfVrT3N06D7,WkDfVrT3N07D7,WkDfVrT3N08D7,WkDfVrT3N09D7,WkDfVrT3N10D7, & + WkDfVrT3N11D7,WkDfVrT3N12D7,WkDfVrT3N13D7,WkDfVrT3N14D7,WkDfVrT3N15D7,WkDfVrT3N16D7,WkDfVrT3N17D7,WkDfVrT3N18D7,WkDfVrT3N19D7,WkDfVrT3N20D7, & + WkDfVrT3N01D8,WkDfVrT3N02D8,WkDfVrT3N03D8,WkDfVrT3N04D8,WkDfVrT3N05D8,WkDfVrT3N06D8,WkDfVrT3N07D8,WkDfVrT3N08D8,WkDfVrT3N09D8,WkDfVrT3N10D8, & + WkDfVrT3N11D8,WkDfVrT3N12D8,WkDfVrT3N13D8,WkDfVrT3N14D8,WkDfVrT3N15D8,WkDfVrT3N16D8,WkDfVrT3N17D8,WkDfVrT3N18D8,WkDfVrT3N19D8,WkDfVrT3N20D8, & + WkDfVrT3N01D9,WkDfVrT3N02D9,WkDfVrT3N03D9,WkDfVrT3N04D9,WkDfVrT3N05D9,WkDfVrT3N06D9,WkDfVrT3N07D9,WkDfVrT3N08D9,WkDfVrT3N09D9,WkDfVrT3N10D9, & + WkDfVrT3N11D9,WkDfVrT3N12D9,WkDfVrT3N13D9,WkDfVrT3N14D9,WkDfVrT3N15D9,WkDfVrT3N16D9,WkDfVrT3N17D9,WkDfVrT3N18D9,WkDfVrT3N19D9,WkDfVrT3N20D9/), (/20,9/) ) +WkDfVrTND(:,:,4) = RESHAPE( & + (/WkDfVrT4N01D1,WkDfVrT4N02D1,WkDfVrT4N03D1,WkDfVrT4N04D1,WkDfVrT4N05D1,WkDfVrT4N06D1,WkDfVrT4N07D1,WkDfVrT4N08D1,WkDfVrT4N09D1,WkDfVrT4N10D1, & + WkDfVrT4N11D1,WkDfVrT4N12D1,WkDfVrT4N13D1,WkDfVrT4N14D1,WkDfVrT4N15D1,WkDfVrT4N16D1,WkDfVrT4N17D1,WkDfVrT4N18D1,WkDfVrT4N19D1,WkDfVrT4N20D1, & + WkDfVrT4N01D2,WkDfVrT4N02D2,WkDfVrT4N03D2,WkDfVrT4N04D2,WkDfVrT4N05D2,WkDfVrT4N06D2,WkDfVrT4N07D2,WkDfVrT4N08D2,WkDfVrT4N09D2,WkDfVrT4N10D2, & + WkDfVrT4N11D2,WkDfVrT4N12D2,WkDfVrT4N13D2,WkDfVrT4N14D2,WkDfVrT4N15D2,WkDfVrT4N16D2,WkDfVrT4N17D2,WkDfVrT4N18D2,WkDfVrT4N19D2,WkDfVrT4N20D2, & + WkDfVrT4N01D3,WkDfVrT4N02D3,WkDfVrT4N03D3,WkDfVrT4N04D3,WkDfVrT4N05D3,WkDfVrT4N06D3,WkDfVrT4N07D3,WkDfVrT4N08D3,WkDfVrT4N09D3,WkDfVrT4N10D3, & + WkDfVrT4N11D3,WkDfVrT4N12D3,WkDfVrT4N13D3,WkDfVrT4N14D3,WkDfVrT4N15D3,WkDfVrT4N16D3,WkDfVrT4N17D3,WkDfVrT4N18D3,WkDfVrT4N19D3,WkDfVrT4N20D3, & + WkDfVrT4N01D4,WkDfVrT4N02D4,WkDfVrT4N03D4,WkDfVrT4N04D4,WkDfVrT4N05D4,WkDfVrT4N06D4,WkDfVrT4N07D4,WkDfVrT4N08D4,WkDfVrT4N09D4,WkDfVrT4N10D4, & + WkDfVrT4N11D4,WkDfVrT4N12D4,WkDfVrT4N13D4,WkDfVrT4N14D4,WkDfVrT4N15D4,WkDfVrT4N16D4,WkDfVrT4N17D4,WkDfVrT4N18D4,WkDfVrT4N19D4,WkDfVrT4N20D4, & + WkDfVrT4N01D5,WkDfVrT4N02D5,WkDfVrT4N03D5,WkDfVrT4N04D5,WkDfVrT4N05D5,WkDfVrT4N06D5,WkDfVrT4N07D5,WkDfVrT4N08D5,WkDfVrT4N09D5,WkDfVrT4N10D5, & + WkDfVrT4N11D5,WkDfVrT4N12D5,WkDfVrT4N13D5,WkDfVrT4N14D5,WkDfVrT4N15D5,WkDfVrT4N16D5,WkDfVrT4N17D5,WkDfVrT4N18D5,WkDfVrT4N19D5,WkDfVrT4N20D5, & + WkDfVrT4N01D6,WkDfVrT4N02D6,WkDfVrT4N03D6,WkDfVrT4N04D6,WkDfVrT4N05D6,WkDfVrT4N06D6,WkDfVrT4N07D6,WkDfVrT4N08D6,WkDfVrT4N09D6,WkDfVrT4N10D6, & + WkDfVrT4N11D6,WkDfVrT4N12D6,WkDfVrT4N13D6,WkDfVrT4N14D6,WkDfVrT4N15D6,WkDfVrT4N16D6,WkDfVrT4N17D6,WkDfVrT4N18D6,WkDfVrT4N19D6,WkDfVrT4N20D6, & + WkDfVrT4N01D7,WkDfVrT4N02D7,WkDfVrT4N03D7,WkDfVrT4N04D7,WkDfVrT4N05D7,WkDfVrT4N06D7,WkDfVrT4N07D7,WkDfVrT4N08D7,WkDfVrT4N09D7,WkDfVrT4N10D7, & + WkDfVrT4N11D7,WkDfVrT4N12D7,WkDfVrT4N13D7,WkDfVrT4N14D7,WkDfVrT4N15D7,WkDfVrT4N16D7,WkDfVrT4N17D7,WkDfVrT4N18D7,WkDfVrT4N19D7,WkDfVrT4N20D7, & + WkDfVrT4N01D8,WkDfVrT4N02D8,WkDfVrT4N03D8,WkDfVrT4N04D8,WkDfVrT4N05D8,WkDfVrT4N06D8,WkDfVrT4N07D8,WkDfVrT4N08D8,WkDfVrT4N09D8,WkDfVrT4N10D8, & + WkDfVrT4N11D8,WkDfVrT4N12D8,WkDfVrT4N13D8,WkDfVrT4N14D8,WkDfVrT4N15D8,WkDfVrT4N16D8,WkDfVrT4N17D8,WkDfVrT4N18D8,WkDfVrT4N19D8,WkDfVrT4N20D8, & + WkDfVrT4N01D9,WkDfVrT4N02D9,WkDfVrT4N03D9,WkDfVrT4N04D9,WkDfVrT4N05D9,WkDfVrT4N06D9,WkDfVrT4N07D9,WkDfVrT4N08D9,WkDfVrT4N09D9,WkDfVrT4N10D9, & + WkDfVrT4N11D9,WkDfVrT4N12D9,WkDfVrT4N13D9,WkDfVrT4N14D9,WkDfVrT4N15D9,WkDfVrT4N16D9,WkDfVrT4N17D9,WkDfVrT4N18D9,WkDfVrT4N19D9,WkDfVrT4N20D9/), (/20,9/) ) + +WkDfVrTND(:,:,5) = RESHAPE( & + (/WkDfVrT5N01D1,WkDfVrT5N02D1,WkDfVrT5N03D1,WkDfVrT5N04D1,WkDfVrT5N05D1,WkDfVrT5N06D1,WkDfVrT5N07D1,WkDfVrT5N08D1,WkDfVrT5N09D1,WkDfVrT5N10D1, & + WkDfVrT5N11D1,WkDfVrT5N12D1,WkDfVrT5N13D1,WkDfVrT5N14D1,WkDfVrT5N15D1,WkDfVrT5N16D1,WkDfVrT5N17D1,WkDfVrT5N18D1,WkDfVrT5N19D1,WkDfVrT5N20D1, & + WkDfVrT5N01D2,WkDfVrT5N02D2,WkDfVrT5N03D2,WkDfVrT5N04D2,WkDfVrT5N05D2,WkDfVrT5N06D2,WkDfVrT5N07D2,WkDfVrT5N08D2,WkDfVrT5N09D2,WkDfVrT5N10D2, & + WkDfVrT5N11D2,WkDfVrT5N12D2,WkDfVrT5N13D2,WkDfVrT5N14D2,WkDfVrT5N15D2,WkDfVrT5N16D2,WkDfVrT5N17D2,WkDfVrT5N18D2,WkDfVrT5N19D2,WkDfVrT5N20D2, & + WkDfVrT5N01D3,WkDfVrT5N02D3,WkDfVrT5N03D3,WkDfVrT5N04D3,WkDfVrT5N05D3,WkDfVrT5N06D3,WkDfVrT5N07D3,WkDfVrT5N08D3,WkDfVrT5N09D3,WkDfVrT5N10D3, & + WkDfVrT5N11D3,WkDfVrT5N12D3,WkDfVrT5N13D3,WkDfVrT5N14D3,WkDfVrT5N15D3,WkDfVrT5N16D3,WkDfVrT5N17D3,WkDfVrT5N18D3,WkDfVrT5N19D3,WkDfVrT5N20D3, & + WkDfVrT5N01D4,WkDfVrT5N02D4,WkDfVrT5N03D4,WkDfVrT5N04D4,WkDfVrT5N05D4,WkDfVrT5N06D4,WkDfVrT5N07D4,WkDfVrT5N08D4,WkDfVrT5N09D4,WkDfVrT5N10D4, & + WkDfVrT5N11D4,WkDfVrT5N12D4,WkDfVrT5N13D4,WkDfVrT5N14D4,WkDfVrT5N15D4,WkDfVrT5N16D4,WkDfVrT5N17D4,WkDfVrT5N18D4,WkDfVrT5N19D4,WkDfVrT5N20D4, & + WkDfVrT5N01D5,WkDfVrT5N02D5,WkDfVrT5N03D5,WkDfVrT5N04D5,WkDfVrT5N05D5,WkDfVrT5N06D5,WkDfVrT5N07D5,WkDfVrT5N08D5,WkDfVrT5N09D5,WkDfVrT5N10D5, & + WkDfVrT5N11D5,WkDfVrT5N12D5,WkDfVrT5N13D5,WkDfVrT5N14D5,WkDfVrT5N15D5,WkDfVrT5N16D5,WkDfVrT5N17D5,WkDfVrT5N18D5,WkDfVrT5N19D5,WkDfVrT5N20D5, & + WkDfVrT5N01D6,WkDfVrT5N02D6,WkDfVrT5N03D6,WkDfVrT5N04D6,WkDfVrT5N05D6,WkDfVrT5N06D6,WkDfVrT5N07D6,WkDfVrT5N08D6,WkDfVrT5N09D6,WkDfVrT5N10D6, & + WkDfVrT5N11D6,WkDfVrT5N12D6,WkDfVrT5N13D6,WkDfVrT5N14D6,WkDfVrT5N15D6,WkDfVrT5N16D6,WkDfVrT5N17D6,WkDfVrT5N18D6,WkDfVrT5N19D6,WkDfVrT5N20D6, & + WkDfVrT5N01D7,WkDfVrT5N02D7,WkDfVrT5N03D7,WkDfVrT5N04D7,WkDfVrT5N05D7,WkDfVrT5N06D7,WkDfVrT5N07D7,WkDfVrT5N08D7,WkDfVrT5N09D7,WkDfVrT5N10D7, & + WkDfVrT5N11D7,WkDfVrT5N12D7,WkDfVrT5N13D7,WkDfVrT5N14D7,WkDfVrT5N15D7,WkDfVrT5N16D7,WkDfVrT5N17D7,WkDfVrT5N18D7,WkDfVrT5N19D7,WkDfVrT5N20D7, & + WkDfVrT5N01D8,WkDfVrT5N02D8,WkDfVrT5N03D8,WkDfVrT5N04D8,WkDfVrT5N05D8,WkDfVrT5N06D8,WkDfVrT5N07D8,WkDfVrT5N08D8,WkDfVrT5N09D8,WkDfVrT5N10D8, & + WkDfVrT5N11D8,WkDfVrT5N12D8,WkDfVrT5N13D8,WkDfVrT5N14D8,WkDfVrT5N15D8,WkDfVrT5N16D8,WkDfVrT5N17D8,WkDfVrT5N18D8,WkDfVrT5N19D8,WkDfVrT5N20D8, & + WkDfVrT5N01D9,WkDfVrT5N02D9,WkDfVrT5N03D9,WkDfVrT5N04D9,WkDfVrT5N05D9,WkDfVrT5N06D9,WkDfVrT5N07D9,WkDfVrT5N08D9,WkDfVrT5N09D9,WkDfVrT5N10D9, & + WkDfVrT5N11D9,WkDfVrT5N12D9,WkDfVrT5N13D9,WkDfVrT5N14D9,WkDfVrT5N15D9,WkDfVrT5N16D9,WkDfVrT5N17D9,WkDfVrT5N18D9,WkDfVrT5N19D9,WkDfVrT5N20D9/), (/20,9/) ) +WkDfVrTND(:,:,6) = RESHAPE( & + (/WkDfVrT6N01D1,WkDfVrT6N02D1,WkDfVrT6N03D1,WkDfVrT6N04D1,WkDfVrT6N05D1,WkDfVrT6N06D1,WkDfVrT6N07D1,WkDfVrT6N08D1,WkDfVrT6N09D1,WkDfVrT6N10D1, & + WkDfVrT6N11D1,WkDfVrT6N12D1,WkDfVrT6N13D1,WkDfVrT6N14D1,WkDfVrT6N15D1,WkDfVrT6N16D1,WkDfVrT6N17D1,WkDfVrT6N18D1,WkDfVrT6N19D1,WkDfVrT6N20D1, & + WkDfVrT6N01D2,WkDfVrT6N02D2,WkDfVrT6N03D2,WkDfVrT6N04D2,WkDfVrT6N05D2,WkDfVrT6N06D2,WkDfVrT6N07D2,WkDfVrT6N08D2,WkDfVrT6N09D2,WkDfVrT6N10D2, & + WkDfVrT6N11D2,WkDfVrT6N12D2,WkDfVrT6N13D2,WkDfVrT6N14D2,WkDfVrT6N15D2,WkDfVrT6N16D2,WkDfVrT6N17D2,WkDfVrT6N18D2,WkDfVrT6N19D2,WkDfVrT6N20D2, & + WkDfVrT6N01D3,WkDfVrT6N02D3,WkDfVrT6N03D3,WkDfVrT6N04D3,WkDfVrT6N05D3,WkDfVrT6N06D3,WkDfVrT6N07D3,WkDfVrT6N08D3,WkDfVrT6N09D3,WkDfVrT6N10D3, & + WkDfVrT6N11D3,WkDfVrT6N12D3,WkDfVrT6N13D3,WkDfVrT6N14D3,WkDfVrT6N15D3,WkDfVrT6N16D3,WkDfVrT6N17D3,WkDfVrT6N18D3,WkDfVrT6N19D3,WkDfVrT6N20D3, & + WkDfVrT6N01D4,WkDfVrT6N02D4,WkDfVrT6N03D4,WkDfVrT6N04D4,WkDfVrT6N05D4,WkDfVrT6N06D4,WkDfVrT6N07D4,WkDfVrT6N08D4,WkDfVrT6N09D4,WkDfVrT6N10D4, & + WkDfVrT6N11D4,WkDfVrT6N12D4,WkDfVrT6N13D4,WkDfVrT6N14D4,WkDfVrT6N15D4,WkDfVrT6N16D4,WkDfVrT6N17D4,WkDfVrT6N18D4,WkDfVrT6N19D4,WkDfVrT6N20D4, & + WkDfVrT6N01D5,WkDfVrT6N02D5,WkDfVrT6N03D5,WkDfVrT6N04D5,WkDfVrT6N05D5,WkDfVrT6N06D5,WkDfVrT6N07D5,WkDfVrT6N08D5,WkDfVrT6N09D5,WkDfVrT6N10D5, & + WkDfVrT6N11D5,WkDfVrT6N12D5,WkDfVrT6N13D5,WkDfVrT6N14D5,WkDfVrT6N15D5,WkDfVrT6N16D5,WkDfVrT6N17D5,WkDfVrT6N18D5,WkDfVrT6N19D5,WkDfVrT6N20D5, & + WkDfVrT6N01D6,WkDfVrT6N02D6,WkDfVrT6N03D6,WkDfVrT6N04D6,WkDfVrT6N05D6,WkDfVrT6N06D6,WkDfVrT6N07D6,WkDfVrT6N08D6,WkDfVrT6N09D6,WkDfVrT6N10D6, & + WkDfVrT6N11D6,WkDfVrT6N12D6,WkDfVrT6N13D6,WkDfVrT6N14D6,WkDfVrT6N15D6,WkDfVrT6N16D6,WkDfVrT6N17D6,WkDfVrT6N18D6,WkDfVrT6N19D6,WkDfVrT6N20D6, & + WkDfVrT6N01D7,WkDfVrT6N02D7,WkDfVrT6N03D7,WkDfVrT6N04D7,WkDfVrT6N05D7,WkDfVrT6N06D7,WkDfVrT6N07D7,WkDfVrT6N08D7,WkDfVrT6N09D7,WkDfVrT6N10D7, & + WkDfVrT6N11D7,WkDfVrT6N12D7,WkDfVrT6N13D7,WkDfVrT6N14D7,WkDfVrT6N15D7,WkDfVrT6N16D7,WkDfVrT6N17D7,WkDfVrT6N18D7,WkDfVrT6N19D7,WkDfVrT6N20D7, & + WkDfVrT6N01D8,WkDfVrT6N02D8,WkDfVrT6N03D8,WkDfVrT6N04D8,WkDfVrT6N05D8,WkDfVrT6N06D8,WkDfVrT6N07D8,WkDfVrT6N08D8,WkDfVrT6N09D8,WkDfVrT6N10D8, & + WkDfVrT6N11D8,WkDfVrT6N12D8,WkDfVrT6N13D8,WkDfVrT6N14D8,WkDfVrT6N15D8,WkDfVrT6N16D8,WkDfVrT6N17D8,WkDfVrT6N18D8,WkDfVrT6N19D8,WkDfVrT6N20D8, & + WkDfVrT6N01D9,WkDfVrT6N02D9,WkDfVrT6N03D9,WkDfVrT6N04D9,WkDfVrT6N05D9,WkDfVrT6N06D9,WkDfVrT6N07D9,WkDfVrT6N08D9,WkDfVrT6N09D9,WkDfVrT6N10D9, & + WkDfVrT6N11D9,WkDfVrT6N12D9,WkDfVrT6N13D9,WkDfVrT6N14D9,WkDfVrT6N15D9,WkDfVrT6N16D9,WkDfVrT6N17D9,WkDfVrT6N18D9,WkDfVrT6N19D9,WkDfVrT6N20D9/), (/20,9/) ) +WkDfVrTND(:,:,7) = RESHAPE( & + (/WkDfVrT7N01D1,WkDfVrT7N02D1,WkDfVrT7N03D1,WkDfVrT7N04D1,WkDfVrT7N05D1,WkDfVrT7N06D1,WkDfVrT7N07D1,WkDfVrT7N08D1,WkDfVrT7N09D1,WkDfVrT7N10D1, & + WkDfVrT7N11D1,WkDfVrT7N12D1,WkDfVrT7N13D1,WkDfVrT7N14D1,WkDfVrT7N15D1,WkDfVrT7N16D1,WkDfVrT7N17D1,WkDfVrT7N18D1,WkDfVrT7N19D1,WkDfVrT7N20D1, & + WkDfVrT7N01D2,WkDfVrT7N02D2,WkDfVrT7N03D2,WkDfVrT7N04D2,WkDfVrT7N05D2,WkDfVrT7N06D2,WkDfVrT7N07D2,WkDfVrT7N08D2,WkDfVrT7N09D2,WkDfVrT7N10D2, & + WkDfVrT7N11D2,WkDfVrT7N12D2,WkDfVrT7N13D2,WkDfVrT7N14D2,WkDfVrT7N15D2,WkDfVrT7N16D2,WkDfVrT7N17D2,WkDfVrT7N18D2,WkDfVrT7N19D2,WkDfVrT7N20D2, & + WkDfVrT7N01D3,WkDfVrT7N02D3,WkDfVrT7N03D3,WkDfVrT7N04D3,WkDfVrT7N05D3,WkDfVrT7N06D3,WkDfVrT7N07D3,WkDfVrT7N08D3,WkDfVrT7N09D3,WkDfVrT7N10D3, & + WkDfVrT7N11D3,WkDfVrT7N12D3,WkDfVrT7N13D3,WkDfVrT7N14D3,WkDfVrT7N15D3,WkDfVrT7N16D3,WkDfVrT7N17D3,WkDfVrT7N18D3,WkDfVrT7N19D3,WkDfVrT7N20D3, & + WkDfVrT7N01D4,WkDfVrT7N02D4,WkDfVrT7N03D4,WkDfVrT7N04D4,WkDfVrT7N05D4,WkDfVrT7N06D4,WkDfVrT7N07D4,WkDfVrT7N08D4,WkDfVrT7N09D4,WkDfVrT7N10D4, & + WkDfVrT7N11D4,WkDfVrT7N12D4,WkDfVrT7N13D4,WkDfVrT7N14D4,WkDfVrT7N15D4,WkDfVrT7N16D4,WkDfVrT7N17D4,WkDfVrT7N18D4,WkDfVrT7N19D4,WkDfVrT7N20D4, & + WkDfVrT7N01D5,WkDfVrT7N02D5,WkDfVrT7N03D5,WkDfVrT7N04D5,WkDfVrT7N05D5,WkDfVrT7N06D5,WkDfVrT7N07D5,WkDfVrT7N08D5,WkDfVrT7N09D5,WkDfVrT7N10D5, & + WkDfVrT7N11D5,WkDfVrT7N12D5,WkDfVrT7N13D5,WkDfVrT7N14D5,WkDfVrT7N15D5,WkDfVrT7N16D5,WkDfVrT7N17D5,WkDfVrT7N18D5,WkDfVrT7N19D5,WkDfVrT7N20D5, & + WkDfVrT7N01D6,WkDfVrT7N02D6,WkDfVrT7N03D6,WkDfVrT7N04D6,WkDfVrT7N05D6,WkDfVrT7N06D6,WkDfVrT7N07D6,WkDfVrT7N08D6,WkDfVrT7N09D6,WkDfVrT7N10D6, & + WkDfVrT7N11D6,WkDfVrT7N12D6,WkDfVrT7N13D6,WkDfVrT7N14D6,WkDfVrT7N15D6,WkDfVrT7N16D6,WkDfVrT7N17D6,WkDfVrT7N18D6,WkDfVrT7N19D6,WkDfVrT7N20D6, & + WkDfVrT7N01D7,WkDfVrT7N02D7,WkDfVrT7N03D7,WkDfVrT7N04D7,WkDfVrT7N05D7,WkDfVrT7N06D7,WkDfVrT7N07D7,WkDfVrT7N08D7,WkDfVrT7N09D7,WkDfVrT7N10D7, & + WkDfVrT7N11D7,WkDfVrT7N12D7,WkDfVrT7N13D7,WkDfVrT7N14D7,WkDfVrT7N15D7,WkDfVrT7N16D7,WkDfVrT7N17D7,WkDfVrT7N18D7,WkDfVrT7N19D7,WkDfVrT7N20D7, & + WkDfVrT7N01D8,WkDfVrT7N02D8,WkDfVrT7N03D8,WkDfVrT7N04D8,WkDfVrT7N05D8,WkDfVrT7N06D8,WkDfVrT7N07D8,WkDfVrT7N08D8,WkDfVrT7N09D8,WkDfVrT7N10D8, & + WkDfVrT7N11D8,WkDfVrT7N12D8,WkDfVrT7N13D8,WkDfVrT7N14D8,WkDfVrT7N15D8,WkDfVrT7N16D8,WkDfVrT7N17D8,WkDfVrT7N18D8,WkDfVrT7N19D8,WkDfVrT7N20D8, & + WkDfVrT7N01D9,WkDfVrT7N02D9,WkDfVrT7N03D9,WkDfVrT7N04D9,WkDfVrT7N05D9,WkDfVrT7N06D9,WkDfVrT7N07D9,WkDfVrT7N08D9,WkDfVrT7N09D9,WkDfVrT7N10D9, & + WkDfVrT7N11D9,WkDfVrT7N12D9,WkDfVrT7N13D9,WkDfVrT7N14D9,WkDfVrT7N15D9,WkDfVrT7N16D9,WkDfVrT7N17D9,WkDfVrT7N18D9,WkDfVrT7N19D9,WkDfVrT7N20D9/), (/20,9/) ) +WkDfVrTND(:,:,8) = RESHAPE( & + (/WkDfVrT8N01D1,WkDfVrT8N02D1,WkDfVrT8N03D1,WkDfVrT8N04D1,WkDfVrT8N05D1,WkDfVrT8N06D1,WkDfVrT8N07D1,WkDfVrT8N08D1,WkDfVrT8N09D1,WkDfVrT8N10D1, & + WkDfVrT8N11D1,WkDfVrT8N12D1,WkDfVrT8N13D1,WkDfVrT8N14D1,WkDfVrT8N15D1,WkDfVrT8N16D1,WkDfVrT8N17D1,WkDfVrT8N18D1,WkDfVrT8N19D1,WkDfVrT8N20D1, & + WkDfVrT8N01D2,WkDfVrT8N02D2,WkDfVrT8N03D2,WkDfVrT8N04D2,WkDfVrT8N05D2,WkDfVrT8N06D2,WkDfVrT8N07D2,WkDfVrT8N08D2,WkDfVrT8N09D2,WkDfVrT8N10D2, & + WkDfVrT8N11D2,WkDfVrT8N12D2,WkDfVrT8N13D2,WkDfVrT8N14D2,WkDfVrT8N15D2,WkDfVrT8N16D2,WkDfVrT8N17D2,WkDfVrT8N18D2,WkDfVrT8N19D2,WkDfVrT8N20D2, & + WkDfVrT8N01D3,WkDfVrT8N02D3,WkDfVrT8N03D3,WkDfVrT8N04D3,WkDfVrT8N05D3,WkDfVrT8N06D3,WkDfVrT8N07D3,WkDfVrT8N08D3,WkDfVrT8N09D3,WkDfVrT8N10D3, & + WkDfVrT8N11D3,WkDfVrT8N12D3,WkDfVrT8N13D3,WkDfVrT8N14D3,WkDfVrT8N15D3,WkDfVrT8N16D3,WkDfVrT8N17D3,WkDfVrT8N18D3,WkDfVrT8N19D3,WkDfVrT8N20D3, & + WkDfVrT8N01D4,WkDfVrT8N02D4,WkDfVrT8N03D4,WkDfVrT8N04D4,WkDfVrT8N05D4,WkDfVrT8N06D4,WkDfVrT8N07D4,WkDfVrT8N08D4,WkDfVrT8N09D4,WkDfVrT8N10D4, & + WkDfVrT8N11D4,WkDfVrT8N12D4,WkDfVrT8N13D4,WkDfVrT8N14D4,WkDfVrT8N15D4,WkDfVrT8N16D4,WkDfVrT8N17D4,WkDfVrT8N18D4,WkDfVrT8N19D4,WkDfVrT8N20D4, & + WkDfVrT8N01D5,WkDfVrT8N02D5,WkDfVrT8N03D5,WkDfVrT8N04D5,WkDfVrT8N05D5,WkDfVrT8N06D5,WkDfVrT8N07D5,WkDfVrT8N08D5,WkDfVrT8N09D5,WkDfVrT8N10D5, & + WkDfVrT8N11D5,WkDfVrT8N12D5,WkDfVrT8N13D5,WkDfVrT8N14D5,WkDfVrT8N15D5,WkDfVrT8N16D5,WkDfVrT8N17D5,WkDfVrT8N18D5,WkDfVrT8N19D5,WkDfVrT8N20D5, & + WkDfVrT8N01D6,WkDfVrT8N02D6,WkDfVrT8N03D6,WkDfVrT8N04D6,WkDfVrT8N05D6,WkDfVrT8N06D6,WkDfVrT8N07D6,WkDfVrT8N08D6,WkDfVrT8N09D6,WkDfVrT8N10D6, & + WkDfVrT8N11D6,WkDfVrT8N12D6,WkDfVrT8N13D6,WkDfVrT8N14D6,WkDfVrT8N15D6,WkDfVrT8N16D6,WkDfVrT8N17D6,WkDfVrT8N18D6,WkDfVrT8N19D6,WkDfVrT8N20D6, & + WkDfVrT8N01D7,WkDfVrT8N02D7,WkDfVrT8N03D7,WkDfVrT8N04D7,WkDfVrT8N05D7,WkDfVrT8N06D7,WkDfVrT8N07D7,WkDfVrT8N08D7,WkDfVrT8N09D7,WkDfVrT8N10D7, & + WkDfVrT8N11D7,WkDfVrT8N12D7,WkDfVrT8N13D7,WkDfVrT8N14D7,WkDfVrT8N15D7,WkDfVrT8N16D7,WkDfVrT8N17D7,WkDfVrT8N18D7,WkDfVrT8N19D7,WkDfVrT8N20D7, & + WkDfVrT8N01D8,WkDfVrT8N02D8,WkDfVrT8N03D8,WkDfVrT8N04D8,WkDfVrT8N05D8,WkDfVrT8N06D8,WkDfVrT8N07D8,WkDfVrT8N08D8,WkDfVrT8N09D8,WkDfVrT8N10D8, & + WkDfVrT8N11D8,WkDfVrT8N12D8,WkDfVrT8N13D8,WkDfVrT8N14D8,WkDfVrT8N15D8,WkDfVrT8N16D8,WkDfVrT8N17D8,WkDfVrT8N18D8,WkDfVrT8N19D8,WkDfVrT8N20D8, & + WkDfVrT8N01D9,WkDfVrT8N02D9,WkDfVrT8N03D9,WkDfVrT8N04D9,WkDfVrT8N05D9,WkDfVrT8N06D9,WkDfVrT8N07D9,WkDfVrT8N08D9,WkDfVrT8N09D9,WkDfVrT8N10D9, & + WkDfVrT8N11D9,WkDfVrT8N12D9,WkDfVrT8N13D9,WkDfVrT8N14D9,WkDfVrT8N15D9,WkDfVrT8N16D9,WkDfVrT8N17D9,WkDfVrT8N18D9,WkDfVrT8N19D9,WkDfVrT8N20D9/), (/20,9/) ) +WkDfVrTND(:,:,9) = RESHAPE( & + (/WkDfVrT9N01D1,WkDfVrT9N02D1,WkDfVrT9N03D1,WkDfVrT9N04D1,WkDfVrT9N05D1,WkDfVrT9N06D1,WkDfVrT9N07D1,WkDfVrT9N08D1,WkDfVrT9N09D1,WkDfVrT9N10D1, & + WkDfVrT9N11D1,WkDfVrT9N12D1,WkDfVrT9N13D1,WkDfVrT9N14D1,WkDfVrT9N15D1,WkDfVrT9N16D1,WkDfVrT9N17D1,WkDfVrT9N18D1,WkDfVrT9N19D1,WkDfVrT9N20D1, & + WkDfVrT9N01D2,WkDfVrT9N02D2,WkDfVrT9N03D2,WkDfVrT9N04D2,WkDfVrT9N05D2,WkDfVrT9N06D2,WkDfVrT9N07D2,WkDfVrT9N08D2,WkDfVrT9N09D2,WkDfVrT9N10D2, & + WkDfVrT9N11D2,WkDfVrT9N12D2,WkDfVrT9N13D2,WkDfVrT9N14D2,WkDfVrT9N15D2,WkDfVrT9N16D2,WkDfVrT9N17D2,WkDfVrT9N18D2,WkDfVrT9N19D2,WkDfVrT9N20D2, & + WkDfVrT9N01D3,WkDfVrT9N02D3,WkDfVrT9N03D3,WkDfVrT9N04D3,WkDfVrT9N05D3,WkDfVrT9N06D3,WkDfVrT9N07D3,WkDfVrT9N08D3,WkDfVrT9N09D3,WkDfVrT9N10D3, & + WkDfVrT9N11D3,WkDfVrT9N12D3,WkDfVrT9N13D3,WkDfVrT9N14D3,WkDfVrT9N15D3,WkDfVrT9N16D3,WkDfVrT9N17D3,WkDfVrT9N18D3,WkDfVrT9N19D3,WkDfVrT9N20D3, & + WkDfVrT9N01D4,WkDfVrT9N02D4,WkDfVrT9N03D4,WkDfVrT9N04D4,WkDfVrT9N05D4,WkDfVrT9N06D4,WkDfVrT9N07D4,WkDfVrT9N08D4,WkDfVrT9N09D4,WkDfVrT9N10D4, & + WkDfVrT9N11D4,WkDfVrT9N12D4,WkDfVrT9N13D4,WkDfVrT9N14D4,WkDfVrT9N15D4,WkDfVrT9N16D4,WkDfVrT9N17D4,WkDfVrT9N18D4,WkDfVrT9N19D4,WkDfVrT9N20D4, & + WkDfVrT9N01D5,WkDfVrT9N02D5,WkDfVrT9N03D5,WkDfVrT9N04D5,WkDfVrT9N05D5,WkDfVrT9N06D5,WkDfVrT9N07D5,WkDfVrT9N08D5,WkDfVrT9N09D5,WkDfVrT9N10D5, & + WkDfVrT9N11D5,WkDfVrT9N12D5,WkDfVrT9N13D5,WkDfVrT9N14D5,WkDfVrT9N15D5,WkDfVrT9N16D5,WkDfVrT9N17D5,WkDfVrT9N18D5,WkDfVrT9N19D5,WkDfVrT9N20D5, & + WkDfVrT9N01D6,WkDfVrT9N02D6,WkDfVrT9N03D6,WkDfVrT9N04D6,WkDfVrT9N05D6,WkDfVrT9N06D6,WkDfVrT9N07D6,WkDfVrT9N08D6,WkDfVrT9N09D6,WkDfVrT9N10D6, & + WkDfVrT9N11D6,WkDfVrT9N12D6,WkDfVrT9N13D6,WkDfVrT9N14D6,WkDfVrT9N15D6,WkDfVrT9N16D6,WkDfVrT9N17D6,WkDfVrT9N18D6,WkDfVrT9N19D6,WkDfVrT9N20D6, & + WkDfVrT9N01D7,WkDfVrT9N02D7,WkDfVrT9N03D7,WkDfVrT9N04D7,WkDfVrT9N05D7,WkDfVrT9N06D7,WkDfVrT9N07D7,WkDfVrT9N08D7,WkDfVrT9N09D7,WkDfVrT9N10D7, & + WkDfVrT9N11D7,WkDfVrT9N12D7,WkDfVrT9N13D7,WkDfVrT9N14D7,WkDfVrT9N15D7,WkDfVrT9N16D7,WkDfVrT9N17D7,WkDfVrT9N18D7,WkDfVrT9N19D7,WkDfVrT9N20D7, & + WkDfVrT9N01D8,WkDfVrT9N02D8,WkDfVrT9N03D8,WkDfVrT9N04D8,WkDfVrT9N05D8,WkDfVrT9N06D8,WkDfVrT9N07D8,WkDfVrT9N08D8,WkDfVrT9N09D8,WkDfVrT9N10D8, & + WkDfVrT9N11D8,WkDfVrT9N12D8,WkDfVrT9N13D8,WkDfVrT9N14D8,WkDfVrT9N15D8,WkDfVrT9N16D8,WkDfVrT9N17D8,WkDfVrT9N18D8,WkDfVrT9N19D8,WkDfVrT9N20D8, & + WkDfVrT9N01D9,WkDfVrT9N02D9,WkDfVrT9N03D9,WkDfVrT9N04D9,WkDfVrT9N05D9,WkDfVrT9N06D9,WkDfVrT9N07D9,WkDfVrT9N08D9,WkDfVrT9N09D9,WkDfVrT9N10D9, & + WkDfVrT9N11D9,WkDfVrT9N12D9,WkDfVrT9N13D9,WkDfVrT9N14D9,WkDfVrT9N15D9,WkDfVrT9N16D9,WkDfVrT9N17D9,WkDfVrT9N18D9,WkDfVrT9N19D9,WkDfVrT9N20D9/), (/20,9/) ) + +EddVisTND(:,:,1) = RESHAPE( & + (/EddVisT1N01D1,EddVisT1N02D1,EddVisT1N03D1,EddVisT1N04D1,EddVisT1N05D1,EddVisT1N06D1,EddVisT1N07D1,EddVisT1N08D1,EddVisT1N09D1,EddVisT1N10D1, & + EddVisT1N11D1,EddVisT1N12D1,EddVisT1N13D1,EddVisT1N14D1,EddVisT1N15D1,EddVisT1N16D1,EddVisT1N17D1,EddVisT1N18D1,EddVisT1N19D1,EddVisT1N20D1, & + EddVisT1N01D2,EddVisT1N02D2,EddVisT1N03D2,EddVisT1N04D2,EddVisT1N05D2,EddVisT1N06D2,EddVisT1N07D2,EddVisT1N08D2,EddVisT1N09D2,EddVisT1N10D2, & + EddVisT1N11D2,EddVisT1N12D2,EddVisT1N13D2,EddVisT1N14D2,EddVisT1N15D2,EddVisT1N16D2,EddVisT1N17D2,EddVisT1N18D2,EddVisT1N19D2,EddVisT1N20D2, & + EddVisT1N01D3,EddVisT1N02D3,EddVisT1N03D3,EddVisT1N04D3,EddVisT1N05D3,EddVisT1N06D3,EddVisT1N07D3,EddVisT1N08D3,EddVisT1N09D3,EddVisT1N10D3, & + EddVisT1N11D3,EddVisT1N12D3,EddVisT1N13D3,EddVisT1N14D3,EddVisT1N15D3,EddVisT1N16D3,EddVisT1N17D3,EddVisT1N18D3,EddVisT1N19D3,EddVisT1N20D3, & + EddVisT1N01D4,EddVisT1N02D4,EddVisT1N03D4,EddVisT1N04D4,EddVisT1N05D4,EddVisT1N06D4,EddVisT1N07D4,EddVisT1N08D4,EddVisT1N09D4,EddVisT1N10D4, & + EddVisT1N11D4,EddVisT1N12D4,EddVisT1N13D4,EddVisT1N14D4,EddVisT1N15D4,EddVisT1N16D4,EddVisT1N17D4,EddVisT1N18D4,EddVisT1N19D4,EddVisT1N20D4, & + EddVisT1N01D5,EddVisT1N02D5,EddVisT1N03D5,EddVisT1N04D5,EddVisT1N05D5,EddVisT1N06D5,EddVisT1N07D5,EddVisT1N08D5,EddVisT1N09D5,EddVisT1N10D5, & + EddVisT1N11D5,EddVisT1N12D5,EddVisT1N13D5,EddVisT1N14D5,EddVisT1N15D5,EddVisT1N16D5,EddVisT1N17D5,EddVisT1N18D5,EddVisT1N19D5,EddVisT1N20D5, & + EddVisT1N01D6,EddVisT1N02D6,EddVisT1N03D6,EddVisT1N04D6,EddVisT1N05D6,EddVisT1N06D6,EddVisT1N07D6,EddVisT1N08D6,EddVisT1N09D6,EddVisT1N10D6, & + EddVisT1N11D6,EddVisT1N12D6,EddVisT1N13D6,EddVisT1N14D6,EddVisT1N15D6,EddVisT1N16D6,EddVisT1N17D6,EddVisT1N18D6,EddVisT1N19D6,EddVisT1N20D6, & + EddVisT1N01D7,EddVisT1N02D7,EddVisT1N03D7,EddVisT1N04D7,EddVisT1N05D7,EddVisT1N06D7,EddVisT1N07D7,EddVisT1N08D7,EddVisT1N09D7,EddVisT1N10D7, & + EddVisT1N11D7,EddVisT1N12D7,EddVisT1N13D7,EddVisT1N14D7,EddVisT1N15D7,EddVisT1N16D7,EddVisT1N17D7,EddVisT1N18D7,EddVisT1N19D7,EddVisT1N20D7, & + EddVisT1N01D8,EddVisT1N02D8,EddVisT1N03D8,EddVisT1N04D8,EddVisT1N05D8,EddVisT1N06D8,EddVisT1N07D8,EddVisT1N08D8,EddVisT1N09D8,EddVisT1N10D8, & + EddVisT1N11D8,EddVisT1N12D8,EddVisT1N13D8,EddVisT1N14D8,EddVisT1N15D8,EddVisT1N16D8,EddVisT1N17D8,EddVisT1N18D8,EddVisT1N19D8,EddVisT1N20D8, & + EddVisT1N01D9,EddVisT1N02D9,EddVisT1N03D9,EddVisT1N04D9,EddVisT1N05D9,EddVisT1N06D9,EddVisT1N07D9,EddVisT1N08D9,EddVisT1N09D9,EddVisT1N10D9, & + EddVisT1N11D9,EddVisT1N12D9,EddVisT1N13D9,EddVisT1N14D9,EddVisT1N15D9,EddVisT1N16D9,EddVisT1N17D9,EddVisT1N18D9,EddVisT1N19D9,EddVisT1N20D9/), (/20,9/) ) +EddVisTND(:,:,2) = RESHAPE( & + (/EddVisT2N01D1,EddVisT2N02D1,EddVisT2N03D1,EddVisT2N04D1,EddVisT2N05D1,EddVisT2N06D1,EddVisT2N07D1,EddVisT2N08D1,EddVisT2N09D1,EddVisT2N10D1, & + EddVisT2N11D1,EddVisT2N12D1,EddVisT2N13D1,EddVisT2N14D1,EddVisT2N15D1,EddVisT2N16D1,EddVisT2N17D1,EddVisT2N18D1,EddVisT2N19D1,EddVisT2N20D1, & + EddVisT2N01D2,EddVisT2N02D2,EddVisT2N03D2,EddVisT2N04D2,EddVisT2N05D2,EddVisT2N06D2,EddVisT2N07D2,EddVisT2N08D2,EddVisT2N09D2,EddVisT2N10D2, & + EddVisT2N11D2,EddVisT2N12D2,EddVisT2N13D2,EddVisT2N14D2,EddVisT2N15D2,EddVisT2N16D2,EddVisT2N17D2,EddVisT2N18D2,EddVisT2N19D2,EddVisT2N20D2, & + EddVisT2N01D3,EddVisT2N02D3,EddVisT2N03D3,EddVisT2N04D3,EddVisT2N05D3,EddVisT2N06D3,EddVisT2N07D3,EddVisT2N08D3,EddVisT2N09D3,EddVisT2N10D3, & + EddVisT2N11D3,EddVisT2N12D3,EddVisT2N13D3,EddVisT2N14D3,EddVisT2N15D3,EddVisT2N16D3,EddVisT2N17D3,EddVisT2N18D3,EddVisT2N19D3,EddVisT2N20D3, & + EddVisT2N01D4,EddVisT2N02D4,EddVisT2N03D4,EddVisT2N04D4,EddVisT2N05D4,EddVisT2N06D4,EddVisT2N07D4,EddVisT2N08D4,EddVisT2N09D4,EddVisT2N10D4, & + EddVisT2N11D4,EddVisT2N12D4,EddVisT2N13D4,EddVisT2N14D4,EddVisT2N15D4,EddVisT2N16D4,EddVisT2N17D4,EddVisT2N18D4,EddVisT2N19D4,EddVisT2N20D4, & + EddVisT2N01D5,EddVisT2N02D5,EddVisT2N03D5,EddVisT2N04D5,EddVisT2N05D5,EddVisT2N06D5,EddVisT2N07D5,EddVisT2N08D5,EddVisT2N09D5,EddVisT2N10D5, & + EddVisT2N11D5,EddVisT2N12D5,EddVisT2N13D5,EddVisT2N14D5,EddVisT2N15D5,EddVisT2N16D5,EddVisT2N17D5,EddVisT2N18D5,EddVisT2N19D5,EddVisT2N20D5, & + EddVisT2N01D6,EddVisT2N02D6,EddVisT2N03D6,EddVisT2N04D6,EddVisT2N05D6,EddVisT2N06D6,EddVisT2N07D6,EddVisT2N08D6,EddVisT2N09D6,EddVisT2N10D6, & + EddVisT2N11D6,EddVisT2N12D6,EddVisT2N13D6,EddVisT2N14D6,EddVisT2N15D6,EddVisT2N16D6,EddVisT2N17D6,EddVisT2N18D6,EddVisT2N19D6,EddVisT2N20D6, & + EddVisT2N01D7,EddVisT2N02D7,EddVisT2N03D7,EddVisT2N04D7,EddVisT2N05D7,EddVisT2N06D7,EddVisT2N07D7,EddVisT2N08D7,EddVisT2N09D7,EddVisT2N10D7, & + EddVisT2N11D7,EddVisT2N12D7,EddVisT2N13D7,EddVisT2N14D7,EddVisT2N15D7,EddVisT2N16D7,EddVisT2N17D7,EddVisT2N18D7,EddVisT2N19D7,EddVisT2N20D7, & + EddVisT2N01D8,EddVisT2N02D8,EddVisT2N03D8,EddVisT2N04D8,EddVisT2N05D8,EddVisT2N06D8,EddVisT2N07D8,EddVisT2N08D8,EddVisT2N09D8,EddVisT2N10D8, & + EddVisT2N11D8,EddVisT2N12D8,EddVisT2N13D8,EddVisT2N14D8,EddVisT2N15D8,EddVisT2N16D8,EddVisT2N17D8,EddVisT2N18D8,EddVisT2N19D8,EddVisT2N20D8, & + EddVisT2N01D9,EddVisT2N02D9,EddVisT2N03D9,EddVisT2N04D9,EddVisT2N05D9,EddVisT2N06D9,EddVisT2N07D9,EddVisT2N08D9,EddVisT2N09D9,EddVisT2N10D9, & + EddVisT2N11D9,EddVisT2N12D9,EddVisT2N13D9,EddVisT2N14D9,EddVisT2N15D9,EddVisT2N16D9,EddVisT2N17D9,EddVisT2N18D9,EddVisT2N19D9,EddVisT2N20D9/), (/20,9/) ) +EddVisTND(:,:,3) = RESHAPE( & + (/EddVisT3N01D1,EddVisT3N02D1,EddVisT3N03D1,EddVisT3N04D1,EddVisT3N05D1,EddVisT3N06D1,EddVisT3N07D1,EddVisT3N08D1,EddVisT3N09D1,EddVisT3N10D1, & + EddVisT3N11D1,EddVisT3N12D1,EddVisT3N13D1,EddVisT3N14D1,EddVisT3N15D1,EddVisT3N16D1,EddVisT3N17D1,EddVisT3N18D1,EddVisT3N19D1,EddVisT3N20D1, & + EddVisT3N01D2,EddVisT3N02D2,EddVisT3N03D2,EddVisT3N04D2,EddVisT3N05D2,EddVisT3N06D2,EddVisT3N07D2,EddVisT3N08D2,EddVisT3N09D2,EddVisT3N10D2, & + EddVisT3N11D2,EddVisT3N12D2,EddVisT3N13D2,EddVisT3N14D2,EddVisT3N15D2,EddVisT3N16D2,EddVisT3N17D2,EddVisT3N18D2,EddVisT3N19D2,EddVisT3N20D2, & + EddVisT3N01D3,EddVisT3N02D3,EddVisT3N03D3,EddVisT3N04D3,EddVisT3N05D3,EddVisT3N06D3,EddVisT3N07D3,EddVisT3N08D3,EddVisT3N09D3,EddVisT3N10D3, & + EddVisT3N11D3,EddVisT3N12D3,EddVisT3N13D3,EddVisT3N14D3,EddVisT3N15D3,EddVisT3N16D3,EddVisT3N17D3,EddVisT3N18D3,EddVisT3N19D3,EddVisT3N20D3, & + EddVisT3N01D4,EddVisT3N02D4,EddVisT3N03D4,EddVisT3N04D4,EddVisT3N05D4,EddVisT3N06D4,EddVisT3N07D4,EddVisT3N08D4,EddVisT3N09D4,EddVisT3N10D4, & + EddVisT3N11D4,EddVisT3N12D4,EddVisT3N13D4,EddVisT3N14D4,EddVisT3N15D4,EddVisT3N16D4,EddVisT3N17D4,EddVisT3N18D4,EddVisT3N19D4,EddVisT3N20D4, & + EddVisT3N01D5,EddVisT3N02D5,EddVisT3N03D5,EddVisT3N04D5,EddVisT3N05D5,EddVisT3N06D5,EddVisT3N07D5,EddVisT3N08D5,EddVisT3N09D5,EddVisT3N10D5, & + EddVisT3N11D5,EddVisT3N12D5,EddVisT3N13D5,EddVisT3N14D5,EddVisT3N15D5,EddVisT3N16D5,EddVisT3N17D5,EddVisT3N18D5,EddVisT3N19D5,EddVisT3N20D5, & + EddVisT3N01D6,EddVisT3N02D6,EddVisT3N03D6,EddVisT3N04D6,EddVisT3N05D6,EddVisT3N06D6,EddVisT3N07D6,EddVisT3N08D6,EddVisT3N09D6,EddVisT3N10D6, & + EddVisT3N11D6,EddVisT3N12D6,EddVisT3N13D6,EddVisT3N14D6,EddVisT3N15D6,EddVisT3N16D6,EddVisT3N17D6,EddVisT3N18D6,EddVisT3N19D6,EddVisT3N20D6, & + EddVisT3N01D7,EddVisT3N02D7,EddVisT3N03D7,EddVisT3N04D7,EddVisT3N05D7,EddVisT3N06D7,EddVisT3N07D7,EddVisT3N08D7,EddVisT3N09D7,EddVisT3N10D7, & + EddVisT3N11D7,EddVisT3N12D7,EddVisT3N13D7,EddVisT3N14D7,EddVisT3N15D7,EddVisT3N16D7,EddVisT3N17D7,EddVisT3N18D7,EddVisT3N19D7,EddVisT3N20D7, & + EddVisT3N01D8,EddVisT3N02D8,EddVisT3N03D8,EddVisT3N04D8,EddVisT3N05D8,EddVisT3N06D8,EddVisT3N07D8,EddVisT3N08D8,EddVisT3N09D8,EddVisT3N10D8, & + EddVisT3N11D8,EddVisT3N12D8,EddVisT3N13D8,EddVisT3N14D8,EddVisT3N15D8,EddVisT3N16D8,EddVisT3N17D8,EddVisT3N18D8,EddVisT3N19D8,EddVisT3N20D8, & + EddVisT3N01D9,EddVisT3N02D9,EddVisT3N03D9,EddVisT3N04D9,EddVisT3N05D9,EddVisT3N06D9,EddVisT3N07D9,EddVisT3N08D9,EddVisT3N09D9,EddVisT3N10D9, & + EddVisT3N11D9,EddVisT3N12D9,EddVisT3N13D9,EddVisT3N14D9,EddVisT3N15D9,EddVisT3N16D9,EddVisT3N17D9,EddVisT3N18D9,EddVisT3N19D9,EddVisT3N20D9/), (/20,9/) ) +EddVisTND(:,:,4) = RESHAPE( & + (/EddVisT4N01D1,EddVisT4N02D1,EddVisT4N03D1,EddVisT4N04D1,EddVisT4N05D1,EddVisT4N06D1,EddVisT4N07D1,EddVisT4N08D1,EddVisT4N09D1,EddVisT4N10D1, & + EddVisT4N11D1,EddVisT4N12D1,EddVisT4N13D1,EddVisT4N14D1,EddVisT4N15D1,EddVisT4N16D1,EddVisT4N17D1,EddVisT4N18D1,EddVisT4N19D1,EddVisT4N20D1, & + EddVisT4N01D2,EddVisT4N02D2,EddVisT4N03D2,EddVisT4N04D2,EddVisT4N05D2,EddVisT4N06D2,EddVisT4N07D2,EddVisT4N08D2,EddVisT4N09D2,EddVisT4N10D2, & + EddVisT4N11D2,EddVisT4N12D2,EddVisT4N13D2,EddVisT4N14D2,EddVisT4N15D2,EddVisT4N16D2,EddVisT4N17D2,EddVisT4N18D2,EddVisT4N19D2,EddVisT4N20D2, & + EddVisT4N01D3,EddVisT4N02D3,EddVisT4N03D3,EddVisT4N04D3,EddVisT4N05D3,EddVisT4N06D3,EddVisT4N07D3,EddVisT4N08D3,EddVisT4N09D3,EddVisT4N10D3, & + EddVisT4N11D3,EddVisT4N12D3,EddVisT4N13D3,EddVisT4N14D3,EddVisT4N15D3,EddVisT4N16D3,EddVisT4N17D3,EddVisT4N18D3,EddVisT4N19D3,EddVisT4N20D3, & + EddVisT4N01D4,EddVisT4N02D4,EddVisT4N03D4,EddVisT4N04D4,EddVisT4N05D4,EddVisT4N06D4,EddVisT4N07D4,EddVisT4N08D4,EddVisT4N09D4,EddVisT4N10D4, & + EddVisT4N11D4,EddVisT4N12D4,EddVisT4N13D4,EddVisT4N14D4,EddVisT4N15D4,EddVisT4N16D4,EddVisT4N17D4,EddVisT4N18D4,EddVisT4N19D4,EddVisT4N20D4, & + EddVisT4N01D5,EddVisT4N02D5,EddVisT4N03D5,EddVisT4N04D5,EddVisT4N05D5,EddVisT4N06D5,EddVisT4N07D5,EddVisT4N08D5,EddVisT4N09D5,EddVisT4N10D5, & + EddVisT4N11D5,EddVisT4N12D5,EddVisT4N13D5,EddVisT4N14D5,EddVisT4N15D5,EddVisT4N16D5,EddVisT4N17D5,EddVisT4N18D5,EddVisT4N19D5,EddVisT4N20D5, & + EddVisT4N01D6,EddVisT4N02D6,EddVisT4N03D6,EddVisT4N04D6,EddVisT4N05D6,EddVisT4N06D6,EddVisT4N07D6,EddVisT4N08D6,EddVisT4N09D6,EddVisT4N10D6, & + EddVisT4N11D6,EddVisT4N12D6,EddVisT4N13D6,EddVisT4N14D6,EddVisT4N15D6,EddVisT4N16D6,EddVisT4N17D6,EddVisT4N18D6,EddVisT4N19D6,EddVisT4N20D6, & + EddVisT4N01D7,EddVisT4N02D7,EddVisT4N03D7,EddVisT4N04D7,EddVisT4N05D7,EddVisT4N06D7,EddVisT4N07D7,EddVisT4N08D7,EddVisT4N09D7,EddVisT4N10D7, & + EddVisT4N11D7,EddVisT4N12D7,EddVisT4N13D7,EddVisT4N14D7,EddVisT4N15D7,EddVisT4N16D7,EddVisT4N17D7,EddVisT4N18D7,EddVisT4N19D7,EddVisT4N20D7, & + EddVisT4N01D8,EddVisT4N02D8,EddVisT4N03D8,EddVisT4N04D8,EddVisT4N05D8,EddVisT4N06D8,EddVisT4N07D8,EddVisT4N08D8,EddVisT4N09D8,EddVisT4N10D8, & + EddVisT4N11D8,EddVisT4N12D8,EddVisT4N13D8,EddVisT4N14D8,EddVisT4N15D8,EddVisT4N16D8,EddVisT4N17D8,EddVisT4N18D8,EddVisT4N19D8,EddVisT4N20D8, & + EddVisT4N01D9,EddVisT4N02D9,EddVisT4N03D9,EddVisT4N04D9,EddVisT4N05D9,EddVisT4N06D9,EddVisT4N07D9,EddVisT4N08D9,EddVisT4N09D9,EddVisT4N10D9, & + EddVisT4N11D9,EddVisT4N12D9,EddVisT4N13D9,EddVisT4N14D9,EddVisT4N15D9,EddVisT4N16D9,EddVisT4N17D9,EddVisT4N18D9,EddVisT4N19D9,EddVisT4N20D9/), (/20,9/) ) + +EddVisTND(:,:,5) = RESHAPE( & + (/EddVisT5N01D1,EddVisT5N02D1,EddVisT5N03D1,EddVisT5N04D1,EddVisT5N05D1,EddVisT5N06D1,EddVisT5N07D1,EddVisT5N08D1,EddVisT5N09D1,EddVisT5N10D1, & + EddVisT5N11D1,EddVisT5N12D1,EddVisT5N13D1,EddVisT5N14D1,EddVisT5N15D1,EddVisT5N16D1,EddVisT5N17D1,EddVisT5N18D1,EddVisT5N19D1,EddVisT5N20D1, & + EddVisT5N01D2,EddVisT5N02D2,EddVisT5N03D2,EddVisT5N04D2,EddVisT5N05D2,EddVisT5N06D2,EddVisT5N07D2,EddVisT5N08D2,EddVisT5N09D2,EddVisT5N10D2, & + EddVisT5N11D2,EddVisT5N12D2,EddVisT5N13D2,EddVisT5N14D2,EddVisT5N15D2,EddVisT5N16D2,EddVisT5N17D2,EddVisT5N18D2,EddVisT5N19D2,EddVisT5N20D2, & + EddVisT5N01D3,EddVisT5N02D3,EddVisT5N03D3,EddVisT5N04D3,EddVisT5N05D3,EddVisT5N06D3,EddVisT5N07D3,EddVisT5N08D3,EddVisT5N09D3,EddVisT5N10D3, & + EddVisT5N11D3,EddVisT5N12D3,EddVisT5N13D3,EddVisT5N14D3,EddVisT5N15D3,EddVisT5N16D3,EddVisT5N17D3,EddVisT5N18D3,EddVisT5N19D3,EddVisT5N20D3, & + EddVisT5N01D4,EddVisT5N02D4,EddVisT5N03D4,EddVisT5N04D4,EddVisT5N05D4,EddVisT5N06D4,EddVisT5N07D4,EddVisT5N08D4,EddVisT5N09D4,EddVisT5N10D4, & + EddVisT5N11D4,EddVisT5N12D4,EddVisT5N13D4,EddVisT5N14D4,EddVisT5N15D4,EddVisT5N16D4,EddVisT5N17D4,EddVisT5N18D4,EddVisT5N19D4,EddVisT5N20D4, & + EddVisT5N01D5,EddVisT5N02D5,EddVisT5N03D5,EddVisT5N04D5,EddVisT5N05D5,EddVisT5N06D5,EddVisT5N07D5,EddVisT5N08D5,EddVisT5N09D5,EddVisT5N10D5, & + EddVisT5N11D5,EddVisT5N12D5,EddVisT5N13D5,EddVisT5N14D5,EddVisT5N15D5,EddVisT5N16D5,EddVisT5N17D5,EddVisT5N18D5,EddVisT5N19D5,EddVisT5N20D5, & + EddVisT5N01D6,EddVisT5N02D6,EddVisT5N03D6,EddVisT5N04D6,EddVisT5N05D6,EddVisT5N06D6,EddVisT5N07D6,EddVisT5N08D6,EddVisT5N09D6,EddVisT5N10D6, & + EddVisT5N11D6,EddVisT5N12D6,EddVisT5N13D6,EddVisT5N14D6,EddVisT5N15D6,EddVisT5N16D6,EddVisT5N17D6,EddVisT5N18D6,EddVisT5N19D6,EddVisT5N20D6, & + EddVisT5N01D7,EddVisT5N02D7,EddVisT5N03D7,EddVisT5N04D7,EddVisT5N05D7,EddVisT5N06D7,EddVisT5N07D7,EddVisT5N08D7,EddVisT5N09D7,EddVisT5N10D7, & + EddVisT5N11D7,EddVisT5N12D7,EddVisT5N13D7,EddVisT5N14D7,EddVisT5N15D7,EddVisT5N16D7,EddVisT5N17D7,EddVisT5N18D7,EddVisT5N19D7,EddVisT5N20D7, & + EddVisT5N01D8,EddVisT5N02D8,EddVisT5N03D8,EddVisT5N04D8,EddVisT5N05D8,EddVisT5N06D8,EddVisT5N07D8,EddVisT5N08D8,EddVisT5N09D8,EddVisT5N10D8, & + EddVisT5N11D8,EddVisT5N12D8,EddVisT5N13D8,EddVisT5N14D8,EddVisT5N15D8,EddVisT5N16D8,EddVisT5N17D8,EddVisT5N18D8,EddVisT5N19D8,EddVisT5N20D8, & + EddVisT5N01D9,EddVisT5N02D9,EddVisT5N03D9,EddVisT5N04D9,EddVisT5N05D9,EddVisT5N06D9,EddVisT5N07D9,EddVisT5N08D9,EddVisT5N09D9,EddVisT5N10D9, & + EddVisT5N11D9,EddVisT5N12D9,EddVisT5N13D9,EddVisT5N14D9,EddVisT5N15D9,EddVisT5N16D9,EddVisT5N17D9,EddVisT5N18D9,EddVisT5N19D9,EddVisT5N20D9/), (/20,9/) ) +EddVisTND(:,:,6) = RESHAPE( & + (/EddVisT6N01D1,EddVisT6N02D1,EddVisT6N03D1,EddVisT6N04D1,EddVisT6N05D1,EddVisT6N06D1,EddVisT6N07D1,EddVisT6N08D1,EddVisT6N09D1,EddVisT6N10D1, & + EddVisT6N11D1,EddVisT6N12D1,EddVisT6N13D1,EddVisT6N14D1,EddVisT6N15D1,EddVisT6N16D1,EddVisT6N17D1,EddVisT6N18D1,EddVisT6N19D1,EddVisT6N20D1, & + EddVisT6N01D2,EddVisT6N02D2,EddVisT6N03D2,EddVisT6N04D2,EddVisT6N05D2,EddVisT6N06D2,EddVisT6N07D2,EddVisT6N08D2,EddVisT6N09D2,EddVisT6N10D2, & + EddVisT6N11D2,EddVisT6N12D2,EddVisT6N13D2,EddVisT6N14D2,EddVisT6N15D2,EddVisT6N16D2,EddVisT6N17D2,EddVisT6N18D2,EddVisT6N19D2,EddVisT6N20D2, & + EddVisT6N01D3,EddVisT6N02D3,EddVisT6N03D3,EddVisT6N04D3,EddVisT6N05D3,EddVisT6N06D3,EddVisT6N07D3,EddVisT6N08D3,EddVisT6N09D3,EddVisT6N10D3, & + EddVisT6N11D3,EddVisT6N12D3,EddVisT6N13D3,EddVisT6N14D3,EddVisT6N15D3,EddVisT6N16D3,EddVisT6N17D3,EddVisT6N18D3,EddVisT6N19D3,EddVisT6N20D3, & + EddVisT6N01D4,EddVisT6N02D4,EddVisT6N03D4,EddVisT6N04D4,EddVisT6N05D4,EddVisT6N06D4,EddVisT6N07D4,EddVisT6N08D4,EddVisT6N09D4,EddVisT6N10D4, & + EddVisT6N11D4,EddVisT6N12D4,EddVisT6N13D4,EddVisT6N14D4,EddVisT6N15D4,EddVisT6N16D4,EddVisT6N17D4,EddVisT6N18D4,EddVisT6N19D4,EddVisT6N20D4, & + EddVisT6N01D5,EddVisT6N02D5,EddVisT6N03D5,EddVisT6N04D5,EddVisT6N05D5,EddVisT6N06D5,EddVisT6N07D5,EddVisT6N08D5,EddVisT6N09D5,EddVisT6N10D5, & + EddVisT6N11D5,EddVisT6N12D5,EddVisT6N13D5,EddVisT6N14D5,EddVisT6N15D5,EddVisT6N16D5,EddVisT6N17D5,EddVisT6N18D5,EddVisT6N19D5,EddVisT6N20D5, & + EddVisT6N01D6,EddVisT6N02D6,EddVisT6N03D6,EddVisT6N04D6,EddVisT6N05D6,EddVisT6N06D6,EddVisT6N07D6,EddVisT6N08D6,EddVisT6N09D6,EddVisT6N10D6, & + EddVisT6N11D6,EddVisT6N12D6,EddVisT6N13D6,EddVisT6N14D6,EddVisT6N15D6,EddVisT6N16D6,EddVisT6N17D6,EddVisT6N18D6,EddVisT6N19D6,EddVisT6N20D6, & + EddVisT6N01D7,EddVisT6N02D7,EddVisT6N03D7,EddVisT6N04D7,EddVisT6N05D7,EddVisT6N06D7,EddVisT6N07D7,EddVisT6N08D7,EddVisT6N09D7,EddVisT6N10D7, & + EddVisT6N11D7,EddVisT6N12D7,EddVisT6N13D7,EddVisT6N14D7,EddVisT6N15D7,EddVisT6N16D7,EddVisT6N17D7,EddVisT6N18D7,EddVisT6N19D7,EddVisT6N20D7, & + EddVisT6N01D8,EddVisT6N02D8,EddVisT6N03D8,EddVisT6N04D8,EddVisT6N05D8,EddVisT6N06D8,EddVisT6N07D8,EddVisT6N08D8,EddVisT6N09D8,EddVisT6N10D8, & + EddVisT6N11D8,EddVisT6N12D8,EddVisT6N13D8,EddVisT6N14D8,EddVisT6N15D8,EddVisT6N16D8,EddVisT6N17D8,EddVisT6N18D8,EddVisT6N19D8,EddVisT6N20D8, & + EddVisT6N01D9,EddVisT6N02D9,EddVisT6N03D9,EddVisT6N04D9,EddVisT6N05D9,EddVisT6N06D9,EddVisT6N07D9,EddVisT6N08D9,EddVisT6N09D9,EddVisT6N10D9, & + EddVisT6N11D9,EddVisT6N12D9,EddVisT6N13D9,EddVisT6N14D9,EddVisT6N15D9,EddVisT6N16D9,EddVisT6N17D9,EddVisT6N18D9,EddVisT6N19D9,EddVisT6N20D9/), (/20,9/) ) +EddVisTND(:,:,7) = RESHAPE( & + (/EddVisT7N01D1,EddVisT7N02D1,EddVisT7N03D1,EddVisT7N04D1,EddVisT7N05D1,EddVisT7N06D1,EddVisT7N07D1,EddVisT7N08D1,EddVisT7N09D1,EddVisT7N10D1, & + EddVisT7N11D1,EddVisT7N12D1,EddVisT7N13D1,EddVisT7N14D1,EddVisT7N15D1,EddVisT7N16D1,EddVisT7N17D1,EddVisT7N18D1,EddVisT7N19D1,EddVisT7N20D1, & + EddVisT7N01D2,EddVisT7N02D2,EddVisT7N03D2,EddVisT7N04D2,EddVisT7N05D2,EddVisT7N06D2,EddVisT7N07D2,EddVisT7N08D2,EddVisT7N09D2,EddVisT7N10D2, & + EddVisT7N11D2,EddVisT7N12D2,EddVisT7N13D2,EddVisT7N14D2,EddVisT7N15D2,EddVisT7N16D2,EddVisT7N17D2,EddVisT7N18D2,EddVisT7N19D2,EddVisT7N20D2, & + EddVisT7N01D3,EddVisT7N02D3,EddVisT7N03D3,EddVisT7N04D3,EddVisT7N05D3,EddVisT7N06D3,EddVisT7N07D3,EddVisT7N08D3,EddVisT7N09D3,EddVisT7N10D3, & + EddVisT7N11D3,EddVisT7N12D3,EddVisT7N13D3,EddVisT7N14D3,EddVisT7N15D3,EddVisT7N16D3,EddVisT7N17D3,EddVisT7N18D3,EddVisT7N19D3,EddVisT7N20D3, & + EddVisT7N01D4,EddVisT7N02D4,EddVisT7N03D4,EddVisT7N04D4,EddVisT7N05D4,EddVisT7N06D4,EddVisT7N07D4,EddVisT7N08D4,EddVisT7N09D4,EddVisT7N10D4, & + EddVisT7N11D4,EddVisT7N12D4,EddVisT7N13D4,EddVisT7N14D4,EddVisT7N15D4,EddVisT7N16D4,EddVisT7N17D4,EddVisT7N18D4,EddVisT7N19D4,EddVisT7N20D4, & + EddVisT7N01D5,EddVisT7N02D5,EddVisT7N03D5,EddVisT7N04D5,EddVisT7N05D5,EddVisT7N06D5,EddVisT7N07D5,EddVisT7N08D5,EddVisT7N09D5,EddVisT7N10D5, & + EddVisT7N11D5,EddVisT7N12D5,EddVisT7N13D5,EddVisT7N14D5,EddVisT7N15D5,EddVisT7N16D5,EddVisT7N17D5,EddVisT7N18D5,EddVisT7N19D5,EddVisT7N20D5, & + EddVisT7N01D6,EddVisT7N02D6,EddVisT7N03D6,EddVisT7N04D6,EddVisT7N05D6,EddVisT7N06D6,EddVisT7N07D6,EddVisT7N08D6,EddVisT7N09D6,EddVisT7N10D6, & + EddVisT7N11D6,EddVisT7N12D6,EddVisT7N13D6,EddVisT7N14D6,EddVisT7N15D6,EddVisT7N16D6,EddVisT7N17D6,EddVisT7N18D6,EddVisT7N19D6,EddVisT7N20D6, & + EddVisT7N01D7,EddVisT7N02D7,EddVisT7N03D7,EddVisT7N04D7,EddVisT7N05D7,EddVisT7N06D7,EddVisT7N07D7,EddVisT7N08D7,EddVisT7N09D7,EddVisT7N10D7, & + EddVisT7N11D7,EddVisT7N12D7,EddVisT7N13D7,EddVisT7N14D7,EddVisT7N15D7,EddVisT7N16D7,EddVisT7N17D7,EddVisT7N18D7,EddVisT7N19D7,EddVisT7N20D7, & + EddVisT7N01D8,EddVisT7N02D8,EddVisT7N03D8,EddVisT7N04D8,EddVisT7N05D8,EddVisT7N06D8,EddVisT7N07D8,EddVisT7N08D8,EddVisT7N09D8,EddVisT7N10D8, & + EddVisT7N11D8,EddVisT7N12D8,EddVisT7N13D8,EddVisT7N14D8,EddVisT7N15D8,EddVisT7N16D8,EddVisT7N17D8,EddVisT7N18D8,EddVisT7N19D8,EddVisT7N20D8, & + EddVisT7N01D9,EddVisT7N02D9,EddVisT7N03D9,EddVisT7N04D9,EddVisT7N05D9,EddVisT7N06D9,EddVisT7N07D9,EddVisT7N08D9,EddVisT7N09D9,EddVisT7N10D9, & + EddVisT7N11D9,EddVisT7N12D9,EddVisT7N13D9,EddVisT7N14D9,EddVisT7N15D9,EddVisT7N16D9,EddVisT7N17D9,EddVisT7N18D9,EddVisT7N19D9,EddVisT7N20D9/), (/20,9/) ) +EddVisTND(:,:,8) = RESHAPE( & + (/EddVisT8N01D1,EddVisT8N02D1,EddVisT8N03D1,EddVisT8N04D1,EddVisT8N05D1,EddVisT8N06D1,EddVisT8N07D1,EddVisT8N08D1,EddVisT8N09D1,EddVisT8N10D1, & + EddVisT8N11D1,EddVisT8N12D1,EddVisT8N13D1,EddVisT8N14D1,EddVisT8N15D1,EddVisT8N16D1,EddVisT8N17D1,EddVisT8N18D1,EddVisT8N19D1,EddVisT8N20D1, & + EddVisT8N01D2,EddVisT8N02D2,EddVisT8N03D2,EddVisT8N04D2,EddVisT8N05D2,EddVisT8N06D2,EddVisT8N07D2,EddVisT8N08D2,EddVisT8N09D2,EddVisT8N10D2, & + EddVisT8N11D2,EddVisT8N12D2,EddVisT8N13D2,EddVisT8N14D2,EddVisT8N15D2,EddVisT8N16D2,EddVisT8N17D2,EddVisT8N18D2,EddVisT8N19D2,EddVisT8N20D2, & + EddVisT8N01D3,EddVisT8N02D3,EddVisT8N03D3,EddVisT8N04D3,EddVisT8N05D3,EddVisT8N06D3,EddVisT8N07D3,EddVisT8N08D3,EddVisT8N09D3,EddVisT8N10D3, & + EddVisT8N11D3,EddVisT8N12D3,EddVisT8N13D3,EddVisT8N14D3,EddVisT8N15D3,EddVisT8N16D3,EddVisT8N17D3,EddVisT8N18D3,EddVisT8N19D3,EddVisT8N20D3, & + EddVisT8N01D4,EddVisT8N02D4,EddVisT8N03D4,EddVisT8N04D4,EddVisT8N05D4,EddVisT8N06D4,EddVisT8N07D4,EddVisT8N08D4,EddVisT8N09D4,EddVisT8N10D4, & + EddVisT8N11D4,EddVisT8N12D4,EddVisT8N13D4,EddVisT8N14D4,EddVisT8N15D4,EddVisT8N16D4,EddVisT8N17D4,EddVisT8N18D4,EddVisT8N19D4,EddVisT8N20D4, & + EddVisT8N01D5,EddVisT8N02D5,EddVisT8N03D5,EddVisT8N04D5,EddVisT8N05D5,EddVisT8N06D5,EddVisT8N07D5,EddVisT8N08D5,EddVisT8N09D5,EddVisT8N10D5, & + EddVisT8N11D5,EddVisT8N12D5,EddVisT8N13D5,EddVisT8N14D5,EddVisT8N15D5,EddVisT8N16D5,EddVisT8N17D5,EddVisT8N18D5,EddVisT8N19D5,EddVisT8N20D5, & + EddVisT8N01D6,EddVisT8N02D6,EddVisT8N03D6,EddVisT8N04D6,EddVisT8N05D6,EddVisT8N06D6,EddVisT8N07D6,EddVisT8N08D6,EddVisT8N09D6,EddVisT8N10D6, & + EddVisT8N11D6,EddVisT8N12D6,EddVisT8N13D6,EddVisT8N14D6,EddVisT8N15D6,EddVisT8N16D6,EddVisT8N17D6,EddVisT8N18D6,EddVisT8N19D6,EddVisT8N20D6, & + EddVisT8N01D7,EddVisT8N02D7,EddVisT8N03D7,EddVisT8N04D7,EddVisT8N05D7,EddVisT8N06D7,EddVisT8N07D7,EddVisT8N08D7,EddVisT8N09D7,EddVisT8N10D7, & + EddVisT8N11D7,EddVisT8N12D7,EddVisT8N13D7,EddVisT8N14D7,EddVisT8N15D7,EddVisT8N16D7,EddVisT8N17D7,EddVisT8N18D7,EddVisT8N19D7,EddVisT8N20D7, & + EddVisT8N01D8,EddVisT8N02D8,EddVisT8N03D8,EddVisT8N04D8,EddVisT8N05D8,EddVisT8N06D8,EddVisT8N07D8,EddVisT8N08D8,EddVisT8N09D8,EddVisT8N10D8, & + EddVisT8N11D8,EddVisT8N12D8,EddVisT8N13D8,EddVisT8N14D8,EddVisT8N15D8,EddVisT8N16D8,EddVisT8N17D8,EddVisT8N18D8,EddVisT8N19D8,EddVisT8N20D8, & + EddVisT8N01D9,EddVisT8N02D9,EddVisT8N03D9,EddVisT8N04D9,EddVisT8N05D9,EddVisT8N06D9,EddVisT8N07D9,EddVisT8N08D9,EddVisT8N09D9,EddVisT8N10D9, & + EddVisT8N11D9,EddVisT8N12D9,EddVisT8N13D9,EddVisT8N14D9,EddVisT8N15D9,EddVisT8N16D9,EddVisT8N17D9,EddVisT8N18D9,EddVisT8N19D9,EddVisT8N20D9/), (/20,9/) ) +EddVisTND(:,:,9) = RESHAPE( & + (/EddVisT9N01D1,EddVisT9N02D1,EddVisT9N03D1,EddVisT9N04D1,EddVisT9N05D1,EddVisT9N06D1,EddVisT9N07D1,EddVisT9N08D1,EddVisT9N09D1,EddVisT9N10D1, & + EddVisT9N11D1,EddVisT9N12D1,EddVisT9N13D1,EddVisT9N14D1,EddVisT9N15D1,EddVisT9N16D1,EddVisT9N17D1,EddVisT9N18D1,EddVisT9N19D1,EddVisT9N20D1, & + EddVisT9N01D2,EddVisT9N02D2,EddVisT9N03D2,EddVisT9N04D2,EddVisT9N05D2,EddVisT9N06D2,EddVisT9N07D2,EddVisT9N08D2,EddVisT9N09D2,EddVisT9N10D2, & + EddVisT9N11D2,EddVisT9N12D2,EddVisT9N13D2,EddVisT9N14D2,EddVisT9N15D2,EddVisT9N16D2,EddVisT9N17D2,EddVisT9N18D2,EddVisT9N19D2,EddVisT9N20D2, & + EddVisT9N01D3,EddVisT9N02D3,EddVisT9N03D3,EddVisT9N04D3,EddVisT9N05D3,EddVisT9N06D3,EddVisT9N07D3,EddVisT9N08D3,EddVisT9N09D3,EddVisT9N10D3, & + EddVisT9N11D3,EddVisT9N12D3,EddVisT9N13D3,EddVisT9N14D3,EddVisT9N15D3,EddVisT9N16D3,EddVisT9N17D3,EddVisT9N18D3,EddVisT9N19D3,EddVisT9N20D3, & + EddVisT9N01D4,EddVisT9N02D4,EddVisT9N03D4,EddVisT9N04D4,EddVisT9N05D4,EddVisT9N06D4,EddVisT9N07D4,EddVisT9N08D4,EddVisT9N09D4,EddVisT9N10D4, & + EddVisT9N11D4,EddVisT9N12D4,EddVisT9N13D4,EddVisT9N14D4,EddVisT9N15D4,EddVisT9N16D4,EddVisT9N17D4,EddVisT9N18D4,EddVisT9N19D4,EddVisT9N20D4, & + EddVisT9N01D5,EddVisT9N02D5,EddVisT9N03D5,EddVisT9N04D5,EddVisT9N05D5,EddVisT9N06D5,EddVisT9N07D5,EddVisT9N08D5,EddVisT9N09D5,EddVisT9N10D5, & + EddVisT9N11D5,EddVisT9N12D5,EddVisT9N13D5,EddVisT9N14D5,EddVisT9N15D5,EddVisT9N16D5,EddVisT9N17D5,EddVisT9N18D5,EddVisT9N19D5,EddVisT9N20D5, & + EddVisT9N01D6,EddVisT9N02D6,EddVisT9N03D6,EddVisT9N04D6,EddVisT9N05D6,EddVisT9N06D6,EddVisT9N07D6,EddVisT9N08D6,EddVisT9N09D6,EddVisT9N10D6, & + EddVisT9N11D6,EddVisT9N12D6,EddVisT9N13D6,EddVisT9N14D6,EddVisT9N15D6,EddVisT9N16D6,EddVisT9N17D6,EddVisT9N18D6,EddVisT9N19D6,EddVisT9N20D6, & + EddVisT9N01D7,EddVisT9N02D7,EddVisT9N03D7,EddVisT9N04D7,EddVisT9N05D7,EddVisT9N06D7,EddVisT9N07D7,EddVisT9N08D7,EddVisT9N09D7,EddVisT9N10D7, & + EddVisT9N11D7,EddVisT9N12D7,EddVisT9N13D7,EddVisT9N14D7,EddVisT9N15D7,EddVisT9N16D7,EddVisT9N17D7,EddVisT9N18D7,EddVisT9N19D7,EddVisT9N20D7, & + EddVisT9N01D8,EddVisT9N02D8,EddVisT9N03D8,EddVisT9N04D8,EddVisT9N05D8,EddVisT9N06D8,EddVisT9N07D8,EddVisT9N08D8,EddVisT9N09D8,EddVisT9N10D8, & + EddVisT9N11D8,EddVisT9N12D8,EddVisT9N13D8,EddVisT9N14D8,EddVisT9N15D8,EddVisT9N16D8,EddVisT9N17D8,EddVisT9N18D8,EddVisT9N19D8,EddVisT9N20D8, & + EddVisT9N01D9,EddVisT9N02D9,EddVisT9N03D9,EddVisT9N04D9,EddVisT9N05D9,EddVisT9N06D9,EddVisT9N07D9,EddVisT9N08D9,EddVisT9N09D9,EddVisT9N10D9, & + EddVisT9N11D9,EddVisT9N12D9,EddVisT9N13D9,EddVisT9N14D9,EddVisT9N15D9,EddVisT9N16D9,EddVisT9N17D9,EddVisT9N18D9,EddVisT9N19D9,EddVisT9N20D9/), (/20,9/) ) + + +EddAmbTND(:,:,1) = RESHAPE( & + (/EddAmbT1N01D1,EddAmbT1N02D1,EddAmbT1N03D1,EddAmbT1N04D1,EddAmbT1N05D1,EddAmbT1N06D1,EddAmbT1N07D1,EddAmbT1N08D1,EddAmbT1N09D1,EddAmbT1N10D1, & + EddAmbT1N11D1,EddAmbT1N12D1,EddAmbT1N13D1,EddAmbT1N14D1,EddAmbT1N15D1,EddAmbT1N16D1,EddAmbT1N17D1,EddAmbT1N18D1,EddAmbT1N19D1,EddAmbT1N20D1, & + EddAmbT1N01D2,EddAmbT1N02D2,EddAmbT1N03D2,EddAmbT1N04D2,EddAmbT1N05D2,EddAmbT1N06D2,EddAmbT1N07D2,EddAmbT1N08D2,EddAmbT1N09D2,EddAmbT1N10D2, & + EddAmbT1N11D2,EddAmbT1N12D2,EddAmbT1N13D2,EddAmbT1N14D2,EddAmbT1N15D2,EddAmbT1N16D2,EddAmbT1N17D2,EddAmbT1N18D2,EddAmbT1N19D2,EddAmbT1N20D2, & + EddAmbT1N01D3,EddAmbT1N02D3,EddAmbT1N03D3,EddAmbT1N04D3,EddAmbT1N05D3,EddAmbT1N06D3,EddAmbT1N07D3,EddAmbT1N08D3,EddAmbT1N09D3,EddAmbT1N10D3, & + EddAmbT1N11D3,EddAmbT1N12D3,EddAmbT1N13D3,EddAmbT1N14D3,EddAmbT1N15D3,EddAmbT1N16D3,EddAmbT1N17D3,EddAmbT1N18D3,EddAmbT1N19D3,EddAmbT1N20D3, & + EddAmbT1N01D4,EddAmbT1N02D4,EddAmbT1N03D4,EddAmbT1N04D4,EddAmbT1N05D4,EddAmbT1N06D4,EddAmbT1N07D4,EddAmbT1N08D4,EddAmbT1N09D4,EddAmbT1N10D4, & + EddAmbT1N11D4,EddAmbT1N12D4,EddAmbT1N13D4,EddAmbT1N14D4,EddAmbT1N15D4,EddAmbT1N16D4,EddAmbT1N17D4,EddAmbT1N18D4,EddAmbT1N19D4,EddAmbT1N20D4, & + EddAmbT1N01D5,EddAmbT1N02D5,EddAmbT1N03D5,EddAmbT1N04D5,EddAmbT1N05D5,EddAmbT1N06D5,EddAmbT1N07D5,EddAmbT1N08D5,EddAmbT1N09D5,EddAmbT1N10D5, & + EddAmbT1N11D5,EddAmbT1N12D5,EddAmbT1N13D5,EddAmbT1N14D5,EddAmbT1N15D5,EddAmbT1N16D5,EddAmbT1N17D5,EddAmbT1N18D5,EddAmbT1N19D5,EddAmbT1N20D5, & + EddAmbT1N01D6,EddAmbT1N02D6,EddAmbT1N03D6,EddAmbT1N04D6,EddAmbT1N05D6,EddAmbT1N06D6,EddAmbT1N07D6,EddAmbT1N08D6,EddAmbT1N09D6,EddAmbT1N10D6, & + EddAmbT1N11D6,EddAmbT1N12D6,EddAmbT1N13D6,EddAmbT1N14D6,EddAmbT1N15D6,EddAmbT1N16D6,EddAmbT1N17D6,EddAmbT1N18D6,EddAmbT1N19D6,EddAmbT1N20D6, & + EddAmbT1N01D7,EddAmbT1N02D7,EddAmbT1N03D7,EddAmbT1N04D7,EddAmbT1N05D7,EddAmbT1N06D7,EddAmbT1N07D7,EddAmbT1N08D7,EddAmbT1N09D7,EddAmbT1N10D7, & + EddAmbT1N11D7,EddAmbT1N12D7,EddAmbT1N13D7,EddAmbT1N14D7,EddAmbT1N15D7,EddAmbT1N16D7,EddAmbT1N17D7,EddAmbT1N18D7,EddAmbT1N19D7,EddAmbT1N20D7, & + EddAmbT1N01D8,EddAmbT1N02D8,EddAmbT1N03D8,EddAmbT1N04D8,EddAmbT1N05D8,EddAmbT1N06D8,EddAmbT1N07D8,EddAmbT1N08D8,EddAmbT1N09D8,EddAmbT1N10D8, & + EddAmbT1N11D8,EddAmbT1N12D8,EddAmbT1N13D8,EddAmbT1N14D8,EddAmbT1N15D8,EddAmbT1N16D8,EddAmbT1N17D8,EddAmbT1N18D8,EddAmbT1N19D8,EddAmbT1N20D8, & + EddAmbT1N01D9,EddAmbT1N02D9,EddAmbT1N03D9,EddAmbT1N04D9,EddAmbT1N05D9,EddAmbT1N06D9,EddAmbT1N07D9,EddAmbT1N08D9,EddAmbT1N09D9,EddAmbT1N10D9, & + EddAmbT1N11D9,EddAmbT1N12D9,EddAmbT1N13D9,EddAmbT1N14D9,EddAmbT1N15D9,EddAmbT1N16D9,EddAmbT1N17D9,EddAmbT1N18D9,EddAmbT1N19D9,EddAmbT1N20D9/), (/20,9/) ) +EddAmbTND(:,:,2) = RESHAPE( & + (/EddAmbT2N01D1,EddAmbT2N02D1,EddAmbT2N03D1,EddAmbT2N04D1,EddAmbT2N05D1,EddAmbT2N06D1,EddAmbT2N07D1,EddAmbT2N08D1,EddAmbT2N09D1,EddAmbT2N10D1, & + EddAmbT2N11D1,EddAmbT2N12D1,EddAmbT2N13D1,EddAmbT2N14D1,EddAmbT2N15D1,EddAmbT2N16D1,EddAmbT2N17D1,EddAmbT2N18D1,EddAmbT2N19D1,EddAmbT2N20D1, & + EddAmbT2N01D2,EddAmbT2N02D2,EddAmbT2N03D2,EddAmbT2N04D2,EddAmbT2N05D2,EddAmbT2N06D2,EddAmbT2N07D2,EddAmbT2N08D2,EddAmbT2N09D2,EddAmbT2N10D2, & + EddAmbT2N11D2,EddAmbT2N12D2,EddAmbT2N13D2,EddAmbT2N14D2,EddAmbT2N15D2,EddAmbT2N16D2,EddAmbT2N17D2,EddAmbT2N18D2,EddAmbT2N19D2,EddAmbT2N20D2, & + EddAmbT2N01D3,EddAmbT2N02D3,EddAmbT2N03D3,EddAmbT2N04D3,EddAmbT2N05D3,EddAmbT2N06D3,EddAmbT2N07D3,EddAmbT2N08D3,EddAmbT2N09D3,EddAmbT2N10D3, & + EddAmbT2N11D3,EddAmbT2N12D3,EddAmbT2N13D3,EddAmbT2N14D3,EddAmbT2N15D3,EddAmbT2N16D3,EddAmbT2N17D3,EddAmbT2N18D3,EddAmbT2N19D3,EddAmbT2N20D3, & + EddAmbT2N01D4,EddAmbT2N02D4,EddAmbT2N03D4,EddAmbT2N04D4,EddAmbT2N05D4,EddAmbT2N06D4,EddAmbT2N07D4,EddAmbT2N08D4,EddAmbT2N09D4,EddAmbT2N10D4, & + EddAmbT2N11D4,EddAmbT2N12D4,EddAmbT2N13D4,EddAmbT2N14D4,EddAmbT2N15D4,EddAmbT2N16D4,EddAmbT2N17D4,EddAmbT2N18D4,EddAmbT2N19D4,EddAmbT2N20D4, & + EddAmbT2N01D5,EddAmbT2N02D5,EddAmbT2N03D5,EddAmbT2N04D5,EddAmbT2N05D5,EddAmbT2N06D5,EddAmbT2N07D5,EddAmbT2N08D5,EddAmbT2N09D5,EddAmbT2N10D5, & + EddAmbT2N11D5,EddAmbT2N12D5,EddAmbT2N13D5,EddAmbT2N14D5,EddAmbT2N15D5,EddAmbT2N16D5,EddAmbT2N17D5,EddAmbT2N18D5,EddAmbT2N19D5,EddAmbT2N20D5, & + EddAmbT2N01D6,EddAmbT2N02D6,EddAmbT2N03D6,EddAmbT2N04D6,EddAmbT2N05D6,EddAmbT2N06D6,EddAmbT2N07D6,EddAmbT2N08D6,EddAmbT2N09D6,EddAmbT2N10D6, & + EddAmbT2N11D6,EddAmbT2N12D6,EddAmbT2N13D6,EddAmbT2N14D6,EddAmbT2N15D6,EddAmbT2N16D6,EddAmbT2N17D6,EddAmbT2N18D6,EddAmbT2N19D6,EddAmbT2N20D6, & + EddAmbT2N01D7,EddAmbT2N02D7,EddAmbT2N03D7,EddAmbT2N04D7,EddAmbT2N05D7,EddAmbT2N06D7,EddAmbT2N07D7,EddAmbT2N08D7,EddAmbT2N09D7,EddAmbT2N10D7, & + EddAmbT2N11D7,EddAmbT2N12D7,EddAmbT2N13D7,EddAmbT2N14D7,EddAmbT2N15D7,EddAmbT2N16D7,EddAmbT2N17D7,EddAmbT2N18D7,EddAmbT2N19D7,EddAmbT2N20D7, & + EddAmbT2N01D8,EddAmbT2N02D8,EddAmbT2N03D8,EddAmbT2N04D8,EddAmbT2N05D8,EddAmbT2N06D8,EddAmbT2N07D8,EddAmbT2N08D8,EddAmbT2N09D8,EddAmbT2N10D8, & + EddAmbT2N11D8,EddAmbT2N12D8,EddAmbT2N13D8,EddAmbT2N14D8,EddAmbT2N15D8,EddAmbT2N16D8,EddAmbT2N17D8,EddAmbT2N18D8,EddAmbT2N19D8,EddAmbT2N20D8, & + EddAmbT2N01D9,EddAmbT2N02D9,EddAmbT2N03D9,EddAmbT2N04D9,EddAmbT2N05D9,EddAmbT2N06D9,EddAmbT2N07D9,EddAmbT2N08D9,EddAmbT2N09D9,EddAmbT2N10D9, & + EddAmbT2N11D9,EddAmbT2N12D9,EddAmbT2N13D9,EddAmbT2N14D9,EddAmbT2N15D9,EddAmbT2N16D9,EddAmbT2N17D9,EddAmbT2N18D9,EddAmbT2N19D9,EddAmbT2N20D9/), (/20,9/) ) +EddAmbTND(:,:,3) = RESHAPE( & + (/EddAmbT3N01D1,EddAmbT3N02D1,EddAmbT3N03D1,EddAmbT3N04D1,EddAmbT3N05D1,EddAmbT3N06D1,EddAmbT3N07D1,EddAmbT3N08D1,EddAmbT3N09D1,EddAmbT3N10D1, & + EddAmbT3N11D1,EddAmbT3N12D1,EddAmbT3N13D1,EddAmbT3N14D1,EddAmbT3N15D1,EddAmbT3N16D1,EddAmbT3N17D1,EddAmbT3N18D1,EddAmbT3N19D1,EddAmbT3N20D1, & + EddAmbT3N01D2,EddAmbT3N02D2,EddAmbT3N03D2,EddAmbT3N04D2,EddAmbT3N05D2,EddAmbT3N06D2,EddAmbT3N07D2,EddAmbT3N08D2,EddAmbT3N09D2,EddAmbT3N10D2, & + EddAmbT3N11D2,EddAmbT3N12D2,EddAmbT3N13D2,EddAmbT3N14D2,EddAmbT3N15D2,EddAmbT3N16D2,EddAmbT3N17D2,EddAmbT3N18D2,EddAmbT3N19D2,EddAmbT3N20D2, & + EddAmbT3N01D3,EddAmbT3N02D3,EddAmbT3N03D3,EddAmbT3N04D3,EddAmbT3N05D3,EddAmbT3N06D3,EddAmbT3N07D3,EddAmbT3N08D3,EddAmbT3N09D3,EddAmbT3N10D3, & + EddAmbT3N11D3,EddAmbT3N12D3,EddAmbT3N13D3,EddAmbT3N14D3,EddAmbT3N15D3,EddAmbT3N16D3,EddAmbT3N17D3,EddAmbT3N18D3,EddAmbT3N19D3,EddAmbT3N20D3, & + EddAmbT3N01D4,EddAmbT3N02D4,EddAmbT3N03D4,EddAmbT3N04D4,EddAmbT3N05D4,EddAmbT3N06D4,EddAmbT3N07D4,EddAmbT3N08D4,EddAmbT3N09D4,EddAmbT3N10D4, & + EddAmbT3N11D4,EddAmbT3N12D4,EddAmbT3N13D4,EddAmbT3N14D4,EddAmbT3N15D4,EddAmbT3N16D4,EddAmbT3N17D4,EddAmbT3N18D4,EddAmbT3N19D4,EddAmbT3N20D4, & + EddAmbT3N01D5,EddAmbT3N02D5,EddAmbT3N03D5,EddAmbT3N04D5,EddAmbT3N05D5,EddAmbT3N06D5,EddAmbT3N07D5,EddAmbT3N08D5,EddAmbT3N09D5,EddAmbT3N10D5, & + EddAmbT3N11D5,EddAmbT3N12D5,EddAmbT3N13D5,EddAmbT3N14D5,EddAmbT3N15D5,EddAmbT3N16D5,EddAmbT3N17D5,EddAmbT3N18D5,EddAmbT3N19D5,EddAmbT3N20D5, & + EddAmbT3N01D6,EddAmbT3N02D6,EddAmbT3N03D6,EddAmbT3N04D6,EddAmbT3N05D6,EddAmbT3N06D6,EddAmbT3N07D6,EddAmbT3N08D6,EddAmbT3N09D6,EddAmbT3N10D6, & + EddAmbT3N11D6,EddAmbT3N12D6,EddAmbT3N13D6,EddAmbT3N14D6,EddAmbT3N15D6,EddAmbT3N16D6,EddAmbT3N17D6,EddAmbT3N18D6,EddAmbT3N19D6,EddAmbT3N20D6, & + EddAmbT3N01D7,EddAmbT3N02D7,EddAmbT3N03D7,EddAmbT3N04D7,EddAmbT3N05D7,EddAmbT3N06D7,EddAmbT3N07D7,EddAmbT3N08D7,EddAmbT3N09D7,EddAmbT3N10D7, & + EddAmbT3N11D7,EddAmbT3N12D7,EddAmbT3N13D7,EddAmbT3N14D7,EddAmbT3N15D7,EddAmbT3N16D7,EddAmbT3N17D7,EddAmbT3N18D7,EddAmbT3N19D7,EddAmbT3N20D7, & + EddAmbT3N01D8,EddAmbT3N02D8,EddAmbT3N03D8,EddAmbT3N04D8,EddAmbT3N05D8,EddAmbT3N06D8,EddAmbT3N07D8,EddAmbT3N08D8,EddAmbT3N09D8,EddAmbT3N10D8, & + EddAmbT3N11D8,EddAmbT3N12D8,EddAmbT3N13D8,EddAmbT3N14D8,EddAmbT3N15D8,EddAmbT3N16D8,EddAmbT3N17D8,EddAmbT3N18D8,EddAmbT3N19D8,EddAmbT3N20D8, & + EddAmbT3N01D9,EddAmbT3N02D9,EddAmbT3N03D9,EddAmbT3N04D9,EddAmbT3N05D9,EddAmbT3N06D9,EddAmbT3N07D9,EddAmbT3N08D9,EddAmbT3N09D9,EddAmbT3N10D9, & + EddAmbT3N11D9,EddAmbT3N12D9,EddAmbT3N13D9,EddAmbT3N14D9,EddAmbT3N15D9,EddAmbT3N16D9,EddAmbT3N17D9,EddAmbT3N18D9,EddAmbT3N19D9,EddAmbT3N20D9/), (/20,9/) ) +EddAmbTND(:,:,4) = RESHAPE( & + (/EddAmbT4N01D1,EddAmbT4N02D1,EddAmbT4N03D1,EddAmbT4N04D1,EddAmbT4N05D1,EddAmbT4N06D1,EddAmbT4N07D1,EddAmbT4N08D1,EddAmbT4N09D1,EddAmbT4N10D1, & + EddAmbT4N11D1,EddAmbT4N12D1,EddAmbT4N13D1,EddAmbT4N14D1,EddAmbT4N15D1,EddAmbT4N16D1,EddAmbT4N17D1,EddAmbT4N18D1,EddAmbT4N19D1,EddAmbT4N20D1, & + EddAmbT4N01D2,EddAmbT4N02D2,EddAmbT4N03D2,EddAmbT4N04D2,EddAmbT4N05D2,EddAmbT4N06D2,EddAmbT4N07D2,EddAmbT4N08D2,EddAmbT4N09D2,EddAmbT4N10D2, & + EddAmbT4N11D2,EddAmbT4N12D2,EddAmbT4N13D2,EddAmbT4N14D2,EddAmbT4N15D2,EddAmbT4N16D2,EddAmbT4N17D2,EddAmbT4N18D2,EddAmbT4N19D2,EddAmbT4N20D2, & + EddAmbT4N01D3,EddAmbT4N02D3,EddAmbT4N03D3,EddAmbT4N04D3,EddAmbT4N05D3,EddAmbT4N06D3,EddAmbT4N07D3,EddAmbT4N08D3,EddAmbT4N09D3,EddAmbT4N10D3, & + EddAmbT4N11D3,EddAmbT4N12D3,EddAmbT4N13D3,EddAmbT4N14D3,EddAmbT4N15D3,EddAmbT4N16D3,EddAmbT4N17D3,EddAmbT4N18D3,EddAmbT4N19D3,EddAmbT4N20D3, & + EddAmbT4N01D4,EddAmbT4N02D4,EddAmbT4N03D4,EddAmbT4N04D4,EddAmbT4N05D4,EddAmbT4N06D4,EddAmbT4N07D4,EddAmbT4N08D4,EddAmbT4N09D4,EddAmbT4N10D4, & + EddAmbT4N11D4,EddAmbT4N12D4,EddAmbT4N13D4,EddAmbT4N14D4,EddAmbT4N15D4,EddAmbT4N16D4,EddAmbT4N17D4,EddAmbT4N18D4,EddAmbT4N19D4,EddAmbT4N20D4, & + EddAmbT4N01D5,EddAmbT4N02D5,EddAmbT4N03D5,EddAmbT4N04D5,EddAmbT4N05D5,EddAmbT4N06D5,EddAmbT4N07D5,EddAmbT4N08D5,EddAmbT4N09D5,EddAmbT4N10D5, & + EddAmbT4N11D5,EddAmbT4N12D5,EddAmbT4N13D5,EddAmbT4N14D5,EddAmbT4N15D5,EddAmbT4N16D5,EddAmbT4N17D5,EddAmbT4N18D5,EddAmbT4N19D5,EddAmbT4N20D5, & + EddAmbT4N01D6,EddAmbT4N02D6,EddAmbT4N03D6,EddAmbT4N04D6,EddAmbT4N05D6,EddAmbT4N06D6,EddAmbT4N07D6,EddAmbT4N08D6,EddAmbT4N09D6,EddAmbT4N10D6, & + EddAmbT4N11D6,EddAmbT4N12D6,EddAmbT4N13D6,EddAmbT4N14D6,EddAmbT4N15D6,EddAmbT4N16D6,EddAmbT4N17D6,EddAmbT4N18D6,EddAmbT4N19D6,EddAmbT4N20D6, & + EddAmbT4N01D7,EddAmbT4N02D7,EddAmbT4N03D7,EddAmbT4N04D7,EddAmbT4N05D7,EddAmbT4N06D7,EddAmbT4N07D7,EddAmbT4N08D7,EddAmbT4N09D7,EddAmbT4N10D7, & + EddAmbT4N11D7,EddAmbT4N12D7,EddAmbT4N13D7,EddAmbT4N14D7,EddAmbT4N15D7,EddAmbT4N16D7,EddAmbT4N17D7,EddAmbT4N18D7,EddAmbT4N19D7,EddAmbT4N20D7, & + EddAmbT4N01D8,EddAmbT4N02D8,EddAmbT4N03D8,EddAmbT4N04D8,EddAmbT4N05D8,EddAmbT4N06D8,EddAmbT4N07D8,EddAmbT4N08D8,EddAmbT4N09D8,EddAmbT4N10D8, & + EddAmbT4N11D8,EddAmbT4N12D8,EddAmbT4N13D8,EddAmbT4N14D8,EddAmbT4N15D8,EddAmbT4N16D8,EddAmbT4N17D8,EddAmbT4N18D8,EddAmbT4N19D8,EddAmbT4N20D8, & + EddAmbT4N01D9,EddAmbT4N02D9,EddAmbT4N03D9,EddAmbT4N04D9,EddAmbT4N05D9,EddAmbT4N06D9,EddAmbT4N07D9,EddAmbT4N08D9,EddAmbT4N09D9,EddAmbT4N10D9, & + EddAmbT4N11D9,EddAmbT4N12D9,EddAmbT4N13D9,EddAmbT4N14D9,EddAmbT4N15D9,EddAmbT4N16D9,EddAmbT4N17D9,EddAmbT4N18D9,EddAmbT4N19D9,EddAmbT4N20D9/), (/20,9/) ) + +EddAmbTND(:,:,5) = RESHAPE( & + (/EddAmbT5N01D1,EddAmbT5N02D1,EddAmbT5N03D1,EddAmbT5N04D1,EddAmbT5N05D1,EddAmbT5N06D1,EddAmbT5N07D1,EddAmbT5N08D1,EddAmbT5N09D1,EddAmbT5N10D1, & + EddAmbT5N11D1,EddAmbT5N12D1,EddAmbT5N13D1,EddAmbT5N14D1,EddAmbT5N15D1,EddAmbT5N16D1,EddAmbT5N17D1,EddAmbT5N18D1,EddAmbT5N19D1,EddAmbT5N20D1, & + EddAmbT5N01D2,EddAmbT5N02D2,EddAmbT5N03D2,EddAmbT5N04D2,EddAmbT5N05D2,EddAmbT5N06D2,EddAmbT5N07D2,EddAmbT5N08D2,EddAmbT5N09D2,EddAmbT5N10D2, & + EddAmbT5N11D2,EddAmbT5N12D2,EddAmbT5N13D2,EddAmbT5N14D2,EddAmbT5N15D2,EddAmbT5N16D2,EddAmbT5N17D2,EddAmbT5N18D2,EddAmbT5N19D2,EddAmbT5N20D2, & + EddAmbT5N01D3,EddAmbT5N02D3,EddAmbT5N03D3,EddAmbT5N04D3,EddAmbT5N05D3,EddAmbT5N06D3,EddAmbT5N07D3,EddAmbT5N08D3,EddAmbT5N09D3,EddAmbT5N10D3, & + EddAmbT5N11D3,EddAmbT5N12D3,EddAmbT5N13D3,EddAmbT5N14D3,EddAmbT5N15D3,EddAmbT5N16D3,EddAmbT5N17D3,EddAmbT5N18D3,EddAmbT5N19D3,EddAmbT5N20D3, & + EddAmbT5N01D4,EddAmbT5N02D4,EddAmbT5N03D4,EddAmbT5N04D4,EddAmbT5N05D4,EddAmbT5N06D4,EddAmbT5N07D4,EddAmbT5N08D4,EddAmbT5N09D4,EddAmbT5N10D4, & + EddAmbT5N11D4,EddAmbT5N12D4,EddAmbT5N13D4,EddAmbT5N14D4,EddAmbT5N15D4,EddAmbT5N16D4,EddAmbT5N17D4,EddAmbT5N18D4,EddAmbT5N19D4,EddAmbT5N20D4, & + EddAmbT5N01D5,EddAmbT5N02D5,EddAmbT5N03D5,EddAmbT5N04D5,EddAmbT5N05D5,EddAmbT5N06D5,EddAmbT5N07D5,EddAmbT5N08D5,EddAmbT5N09D5,EddAmbT5N10D5, & + EddAmbT5N11D5,EddAmbT5N12D5,EddAmbT5N13D5,EddAmbT5N14D5,EddAmbT5N15D5,EddAmbT5N16D5,EddAmbT5N17D5,EddAmbT5N18D5,EddAmbT5N19D5,EddAmbT5N20D5, & + EddAmbT5N01D6,EddAmbT5N02D6,EddAmbT5N03D6,EddAmbT5N04D6,EddAmbT5N05D6,EddAmbT5N06D6,EddAmbT5N07D6,EddAmbT5N08D6,EddAmbT5N09D6,EddAmbT5N10D6, & + EddAmbT5N11D6,EddAmbT5N12D6,EddAmbT5N13D6,EddAmbT5N14D6,EddAmbT5N15D6,EddAmbT5N16D6,EddAmbT5N17D6,EddAmbT5N18D6,EddAmbT5N19D6,EddAmbT5N20D6, & + EddAmbT5N01D7,EddAmbT5N02D7,EddAmbT5N03D7,EddAmbT5N04D7,EddAmbT5N05D7,EddAmbT5N06D7,EddAmbT5N07D7,EddAmbT5N08D7,EddAmbT5N09D7,EddAmbT5N10D7, & + EddAmbT5N11D7,EddAmbT5N12D7,EddAmbT5N13D7,EddAmbT5N14D7,EddAmbT5N15D7,EddAmbT5N16D7,EddAmbT5N17D7,EddAmbT5N18D7,EddAmbT5N19D7,EddAmbT5N20D7, & + EddAmbT5N01D8,EddAmbT5N02D8,EddAmbT5N03D8,EddAmbT5N04D8,EddAmbT5N05D8,EddAmbT5N06D8,EddAmbT5N07D8,EddAmbT5N08D8,EddAmbT5N09D8,EddAmbT5N10D8, & + EddAmbT5N11D8,EddAmbT5N12D8,EddAmbT5N13D8,EddAmbT5N14D8,EddAmbT5N15D8,EddAmbT5N16D8,EddAmbT5N17D8,EddAmbT5N18D8,EddAmbT5N19D8,EddAmbT5N20D8, & + EddAmbT5N01D9,EddAmbT5N02D9,EddAmbT5N03D9,EddAmbT5N04D9,EddAmbT5N05D9,EddAmbT5N06D9,EddAmbT5N07D9,EddAmbT5N08D9,EddAmbT5N09D9,EddAmbT5N10D9, & + EddAmbT5N11D9,EddAmbT5N12D9,EddAmbT5N13D9,EddAmbT5N14D9,EddAmbT5N15D9,EddAmbT5N16D9,EddAmbT5N17D9,EddAmbT5N18D9,EddAmbT5N19D9,EddAmbT5N20D9/), (/20,9/) ) +EddAmbTND(:,:,6) = RESHAPE( & + (/EddAmbT6N01D1,EddAmbT6N02D1,EddAmbT6N03D1,EddAmbT6N04D1,EddAmbT6N05D1,EddAmbT6N06D1,EddAmbT6N07D1,EddAmbT6N08D1,EddAmbT6N09D1,EddAmbT6N10D1, & + EddAmbT6N11D1,EddAmbT6N12D1,EddAmbT6N13D1,EddAmbT6N14D1,EddAmbT6N15D1,EddAmbT6N16D1,EddAmbT6N17D1,EddAmbT6N18D1,EddAmbT6N19D1,EddAmbT6N20D1, & + EddAmbT6N01D2,EddAmbT6N02D2,EddAmbT6N03D2,EddAmbT6N04D2,EddAmbT6N05D2,EddAmbT6N06D2,EddAmbT6N07D2,EddAmbT6N08D2,EddAmbT6N09D2,EddAmbT6N10D2, & + EddAmbT6N11D2,EddAmbT6N12D2,EddAmbT6N13D2,EddAmbT6N14D2,EddAmbT6N15D2,EddAmbT6N16D2,EddAmbT6N17D2,EddAmbT6N18D2,EddAmbT6N19D2,EddAmbT6N20D2, & + EddAmbT6N01D3,EddAmbT6N02D3,EddAmbT6N03D3,EddAmbT6N04D3,EddAmbT6N05D3,EddAmbT6N06D3,EddAmbT6N07D3,EddAmbT6N08D3,EddAmbT6N09D3,EddAmbT6N10D3, & + EddAmbT6N11D3,EddAmbT6N12D3,EddAmbT6N13D3,EddAmbT6N14D3,EddAmbT6N15D3,EddAmbT6N16D3,EddAmbT6N17D3,EddAmbT6N18D3,EddAmbT6N19D3,EddAmbT6N20D3, & + EddAmbT6N01D4,EddAmbT6N02D4,EddAmbT6N03D4,EddAmbT6N04D4,EddAmbT6N05D4,EddAmbT6N06D4,EddAmbT6N07D4,EddAmbT6N08D4,EddAmbT6N09D4,EddAmbT6N10D4, & + EddAmbT6N11D4,EddAmbT6N12D4,EddAmbT6N13D4,EddAmbT6N14D4,EddAmbT6N15D4,EddAmbT6N16D4,EddAmbT6N17D4,EddAmbT6N18D4,EddAmbT6N19D4,EddAmbT6N20D4, & + EddAmbT6N01D5,EddAmbT6N02D5,EddAmbT6N03D5,EddAmbT6N04D5,EddAmbT6N05D5,EddAmbT6N06D5,EddAmbT6N07D5,EddAmbT6N08D5,EddAmbT6N09D5,EddAmbT6N10D5, & + EddAmbT6N11D5,EddAmbT6N12D5,EddAmbT6N13D5,EddAmbT6N14D5,EddAmbT6N15D5,EddAmbT6N16D5,EddAmbT6N17D5,EddAmbT6N18D5,EddAmbT6N19D5,EddAmbT6N20D5, & + EddAmbT6N01D6,EddAmbT6N02D6,EddAmbT6N03D6,EddAmbT6N04D6,EddAmbT6N05D6,EddAmbT6N06D6,EddAmbT6N07D6,EddAmbT6N08D6,EddAmbT6N09D6,EddAmbT6N10D6, & + EddAmbT6N11D6,EddAmbT6N12D6,EddAmbT6N13D6,EddAmbT6N14D6,EddAmbT6N15D6,EddAmbT6N16D6,EddAmbT6N17D6,EddAmbT6N18D6,EddAmbT6N19D6,EddAmbT6N20D6, & + EddAmbT6N01D7,EddAmbT6N02D7,EddAmbT6N03D7,EddAmbT6N04D7,EddAmbT6N05D7,EddAmbT6N06D7,EddAmbT6N07D7,EddAmbT6N08D7,EddAmbT6N09D7,EddAmbT6N10D7, & + EddAmbT6N11D7,EddAmbT6N12D7,EddAmbT6N13D7,EddAmbT6N14D7,EddAmbT6N15D7,EddAmbT6N16D7,EddAmbT6N17D7,EddAmbT6N18D7,EddAmbT6N19D7,EddAmbT6N20D7, & + EddAmbT6N01D8,EddAmbT6N02D8,EddAmbT6N03D8,EddAmbT6N04D8,EddAmbT6N05D8,EddAmbT6N06D8,EddAmbT6N07D8,EddAmbT6N08D8,EddAmbT6N09D8,EddAmbT6N10D8, & + EddAmbT6N11D8,EddAmbT6N12D8,EddAmbT6N13D8,EddAmbT6N14D8,EddAmbT6N15D8,EddAmbT6N16D8,EddAmbT6N17D8,EddAmbT6N18D8,EddAmbT6N19D8,EddAmbT6N20D8, & + EddAmbT6N01D9,EddAmbT6N02D9,EddAmbT6N03D9,EddAmbT6N04D9,EddAmbT6N05D9,EddAmbT6N06D9,EddAmbT6N07D9,EddAmbT6N08D9,EddAmbT6N09D9,EddAmbT6N10D9, & + EddAmbT6N11D9,EddAmbT6N12D9,EddAmbT6N13D9,EddAmbT6N14D9,EddAmbT6N15D9,EddAmbT6N16D9,EddAmbT6N17D9,EddAmbT6N18D9,EddAmbT6N19D9,EddAmbT6N20D9/), (/20,9/) ) +EddAmbTND(:,:,7) = RESHAPE( & + (/EddAmbT7N01D1,EddAmbT7N02D1,EddAmbT7N03D1,EddAmbT7N04D1,EddAmbT7N05D1,EddAmbT7N06D1,EddAmbT7N07D1,EddAmbT7N08D1,EddAmbT7N09D1,EddAmbT7N10D1, & + EddAmbT7N11D1,EddAmbT7N12D1,EddAmbT7N13D1,EddAmbT7N14D1,EddAmbT7N15D1,EddAmbT7N16D1,EddAmbT7N17D1,EddAmbT7N18D1,EddAmbT7N19D1,EddAmbT7N20D1, & + EddAmbT7N01D2,EddAmbT7N02D2,EddAmbT7N03D2,EddAmbT7N04D2,EddAmbT7N05D2,EddAmbT7N06D2,EddAmbT7N07D2,EddAmbT7N08D2,EddAmbT7N09D2,EddAmbT7N10D2, & + EddAmbT7N11D2,EddAmbT7N12D2,EddAmbT7N13D2,EddAmbT7N14D2,EddAmbT7N15D2,EddAmbT7N16D2,EddAmbT7N17D2,EddAmbT7N18D2,EddAmbT7N19D2,EddAmbT7N20D2, & + EddAmbT7N01D3,EddAmbT7N02D3,EddAmbT7N03D3,EddAmbT7N04D3,EddAmbT7N05D3,EddAmbT7N06D3,EddAmbT7N07D3,EddAmbT7N08D3,EddAmbT7N09D3,EddAmbT7N10D3, & + EddAmbT7N11D3,EddAmbT7N12D3,EddAmbT7N13D3,EddAmbT7N14D3,EddAmbT7N15D3,EddAmbT7N16D3,EddAmbT7N17D3,EddAmbT7N18D3,EddAmbT7N19D3,EddAmbT7N20D3, & + EddAmbT7N01D4,EddAmbT7N02D4,EddAmbT7N03D4,EddAmbT7N04D4,EddAmbT7N05D4,EddAmbT7N06D4,EddAmbT7N07D4,EddAmbT7N08D4,EddAmbT7N09D4,EddAmbT7N10D4, & + EddAmbT7N11D4,EddAmbT7N12D4,EddAmbT7N13D4,EddAmbT7N14D4,EddAmbT7N15D4,EddAmbT7N16D4,EddAmbT7N17D4,EddAmbT7N18D4,EddAmbT7N19D4,EddAmbT7N20D4, & + EddAmbT7N01D5,EddAmbT7N02D5,EddAmbT7N03D5,EddAmbT7N04D5,EddAmbT7N05D5,EddAmbT7N06D5,EddAmbT7N07D5,EddAmbT7N08D5,EddAmbT7N09D5,EddAmbT7N10D5, & + EddAmbT7N11D5,EddAmbT7N12D5,EddAmbT7N13D5,EddAmbT7N14D5,EddAmbT7N15D5,EddAmbT7N16D5,EddAmbT7N17D5,EddAmbT7N18D5,EddAmbT7N19D5,EddAmbT7N20D5, & + EddAmbT7N01D6,EddAmbT7N02D6,EddAmbT7N03D6,EddAmbT7N04D6,EddAmbT7N05D6,EddAmbT7N06D6,EddAmbT7N07D6,EddAmbT7N08D6,EddAmbT7N09D6,EddAmbT7N10D6, & + EddAmbT7N11D6,EddAmbT7N12D6,EddAmbT7N13D6,EddAmbT7N14D6,EddAmbT7N15D6,EddAmbT7N16D6,EddAmbT7N17D6,EddAmbT7N18D6,EddAmbT7N19D6,EddAmbT7N20D6, & + EddAmbT7N01D7,EddAmbT7N02D7,EddAmbT7N03D7,EddAmbT7N04D7,EddAmbT7N05D7,EddAmbT7N06D7,EddAmbT7N07D7,EddAmbT7N08D7,EddAmbT7N09D7,EddAmbT7N10D7, & + EddAmbT7N11D7,EddAmbT7N12D7,EddAmbT7N13D7,EddAmbT7N14D7,EddAmbT7N15D7,EddAmbT7N16D7,EddAmbT7N17D7,EddAmbT7N18D7,EddAmbT7N19D7,EddAmbT7N20D7, & + EddAmbT7N01D8,EddAmbT7N02D8,EddAmbT7N03D8,EddAmbT7N04D8,EddAmbT7N05D8,EddAmbT7N06D8,EddAmbT7N07D8,EddAmbT7N08D8,EddAmbT7N09D8,EddAmbT7N10D8, & + EddAmbT7N11D8,EddAmbT7N12D8,EddAmbT7N13D8,EddAmbT7N14D8,EddAmbT7N15D8,EddAmbT7N16D8,EddAmbT7N17D8,EddAmbT7N18D8,EddAmbT7N19D8,EddAmbT7N20D8, & + EddAmbT7N01D9,EddAmbT7N02D9,EddAmbT7N03D9,EddAmbT7N04D9,EddAmbT7N05D9,EddAmbT7N06D9,EddAmbT7N07D9,EddAmbT7N08D9,EddAmbT7N09D9,EddAmbT7N10D9, & + EddAmbT7N11D9,EddAmbT7N12D9,EddAmbT7N13D9,EddAmbT7N14D9,EddAmbT7N15D9,EddAmbT7N16D9,EddAmbT7N17D9,EddAmbT7N18D9,EddAmbT7N19D9,EddAmbT7N20D9/), (/20,9/) ) +EddAmbTND(:,:,8) = RESHAPE( & + (/EddAmbT8N01D1,EddAmbT8N02D1,EddAmbT8N03D1,EddAmbT8N04D1,EddAmbT8N05D1,EddAmbT8N06D1,EddAmbT8N07D1,EddAmbT8N08D1,EddAmbT8N09D1,EddAmbT8N10D1, & + EddAmbT8N11D1,EddAmbT8N12D1,EddAmbT8N13D1,EddAmbT8N14D1,EddAmbT8N15D1,EddAmbT8N16D1,EddAmbT8N17D1,EddAmbT8N18D1,EddAmbT8N19D1,EddAmbT8N20D1, & + EddAmbT8N01D2,EddAmbT8N02D2,EddAmbT8N03D2,EddAmbT8N04D2,EddAmbT8N05D2,EddAmbT8N06D2,EddAmbT8N07D2,EddAmbT8N08D2,EddAmbT8N09D2,EddAmbT8N10D2, & + EddAmbT8N11D2,EddAmbT8N12D2,EddAmbT8N13D2,EddAmbT8N14D2,EddAmbT8N15D2,EddAmbT8N16D2,EddAmbT8N17D2,EddAmbT8N18D2,EddAmbT8N19D2,EddAmbT8N20D2, & + EddAmbT8N01D3,EddAmbT8N02D3,EddAmbT8N03D3,EddAmbT8N04D3,EddAmbT8N05D3,EddAmbT8N06D3,EddAmbT8N07D3,EddAmbT8N08D3,EddAmbT8N09D3,EddAmbT8N10D3, & + EddAmbT8N11D3,EddAmbT8N12D3,EddAmbT8N13D3,EddAmbT8N14D3,EddAmbT8N15D3,EddAmbT8N16D3,EddAmbT8N17D3,EddAmbT8N18D3,EddAmbT8N19D3,EddAmbT8N20D3, & + EddAmbT8N01D4,EddAmbT8N02D4,EddAmbT8N03D4,EddAmbT8N04D4,EddAmbT8N05D4,EddAmbT8N06D4,EddAmbT8N07D4,EddAmbT8N08D4,EddAmbT8N09D4,EddAmbT8N10D4, & + EddAmbT8N11D4,EddAmbT8N12D4,EddAmbT8N13D4,EddAmbT8N14D4,EddAmbT8N15D4,EddAmbT8N16D4,EddAmbT8N17D4,EddAmbT8N18D4,EddAmbT8N19D4,EddAmbT8N20D4, & + EddAmbT8N01D5,EddAmbT8N02D5,EddAmbT8N03D5,EddAmbT8N04D5,EddAmbT8N05D5,EddAmbT8N06D5,EddAmbT8N07D5,EddAmbT8N08D5,EddAmbT8N09D5,EddAmbT8N10D5, & + EddAmbT8N11D5,EddAmbT8N12D5,EddAmbT8N13D5,EddAmbT8N14D5,EddAmbT8N15D5,EddAmbT8N16D5,EddAmbT8N17D5,EddAmbT8N18D5,EddAmbT8N19D5,EddAmbT8N20D5, & + EddAmbT8N01D6,EddAmbT8N02D6,EddAmbT8N03D6,EddAmbT8N04D6,EddAmbT8N05D6,EddAmbT8N06D6,EddAmbT8N07D6,EddAmbT8N08D6,EddAmbT8N09D6,EddAmbT8N10D6, & + EddAmbT8N11D6,EddAmbT8N12D6,EddAmbT8N13D6,EddAmbT8N14D6,EddAmbT8N15D6,EddAmbT8N16D6,EddAmbT8N17D6,EddAmbT8N18D6,EddAmbT8N19D6,EddAmbT8N20D6, & + EddAmbT8N01D7,EddAmbT8N02D7,EddAmbT8N03D7,EddAmbT8N04D7,EddAmbT8N05D7,EddAmbT8N06D7,EddAmbT8N07D7,EddAmbT8N08D7,EddAmbT8N09D7,EddAmbT8N10D7, & + EddAmbT8N11D7,EddAmbT8N12D7,EddAmbT8N13D7,EddAmbT8N14D7,EddAmbT8N15D7,EddAmbT8N16D7,EddAmbT8N17D7,EddAmbT8N18D7,EddAmbT8N19D7,EddAmbT8N20D7, & + EddAmbT8N01D8,EddAmbT8N02D8,EddAmbT8N03D8,EddAmbT8N04D8,EddAmbT8N05D8,EddAmbT8N06D8,EddAmbT8N07D8,EddAmbT8N08D8,EddAmbT8N09D8,EddAmbT8N10D8, & + EddAmbT8N11D8,EddAmbT8N12D8,EddAmbT8N13D8,EddAmbT8N14D8,EddAmbT8N15D8,EddAmbT8N16D8,EddAmbT8N17D8,EddAmbT8N18D8,EddAmbT8N19D8,EddAmbT8N20D8, & + EddAmbT8N01D9,EddAmbT8N02D9,EddAmbT8N03D9,EddAmbT8N04D9,EddAmbT8N05D9,EddAmbT8N06D9,EddAmbT8N07D9,EddAmbT8N08D9,EddAmbT8N09D9,EddAmbT8N10D9, & + EddAmbT8N11D9,EddAmbT8N12D9,EddAmbT8N13D9,EddAmbT8N14D9,EddAmbT8N15D9,EddAmbT8N16D9,EddAmbT8N17D9,EddAmbT8N18D9,EddAmbT8N19D9,EddAmbT8N20D9/), (/20,9/) ) +EddAmbTND(:,:,9) = RESHAPE( & + (/EddAmbT9N01D1,EddAmbT9N02D1,EddAmbT9N03D1,EddAmbT9N04D1,EddAmbT9N05D1,EddAmbT9N06D1,EddAmbT9N07D1,EddAmbT9N08D1,EddAmbT9N09D1,EddAmbT9N10D1, & + EddAmbT9N11D1,EddAmbT9N12D1,EddAmbT9N13D1,EddAmbT9N14D1,EddAmbT9N15D1,EddAmbT9N16D1,EddAmbT9N17D1,EddAmbT9N18D1,EddAmbT9N19D1,EddAmbT9N20D1, & + EddAmbT9N01D2,EddAmbT9N02D2,EddAmbT9N03D2,EddAmbT9N04D2,EddAmbT9N05D2,EddAmbT9N06D2,EddAmbT9N07D2,EddAmbT9N08D2,EddAmbT9N09D2,EddAmbT9N10D2, & + EddAmbT9N11D2,EddAmbT9N12D2,EddAmbT9N13D2,EddAmbT9N14D2,EddAmbT9N15D2,EddAmbT9N16D2,EddAmbT9N17D2,EddAmbT9N18D2,EddAmbT9N19D2,EddAmbT9N20D2, & + EddAmbT9N01D3,EddAmbT9N02D3,EddAmbT9N03D3,EddAmbT9N04D3,EddAmbT9N05D3,EddAmbT9N06D3,EddAmbT9N07D3,EddAmbT9N08D3,EddAmbT9N09D3,EddAmbT9N10D3, & + EddAmbT9N11D3,EddAmbT9N12D3,EddAmbT9N13D3,EddAmbT9N14D3,EddAmbT9N15D3,EddAmbT9N16D3,EddAmbT9N17D3,EddAmbT9N18D3,EddAmbT9N19D3,EddAmbT9N20D3, & + EddAmbT9N01D4,EddAmbT9N02D4,EddAmbT9N03D4,EddAmbT9N04D4,EddAmbT9N05D4,EddAmbT9N06D4,EddAmbT9N07D4,EddAmbT9N08D4,EddAmbT9N09D4,EddAmbT9N10D4, & + EddAmbT9N11D4,EddAmbT9N12D4,EddAmbT9N13D4,EddAmbT9N14D4,EddAmbT9N15D4,EddAmbT9N16D4,EddAmbT9N17D4,EddAmbT9N18D4,EddAmbT9N19D4,EddAmbT9N20D4, & + EddAmbT9N01D5,EddAmbT9N02D5,EddAmbT9N03D5,EddAmbT9N04D5,EddAmbT9N05D5,EddAmbT9N06D5,EddAmbT9N07D5,EddAmbT9N08D5,EddAmbT9N09D5,EddAmbT9N10D5, & + EddAmbT9N11D5,EddAmbT9N12D5,EddAmbT9N13D5,EddAmbT9N14D5,EddAmbT9N15D5,EddAmbT9N16D5,EddAmbT9N17D5,EddAmbT9N18D5,EddAmbT9N19D5,EddAmbT9N20D5, & + EddAmbT9N01D6,EddAmbT9N02D6,EddAmbT9N03D6,EddAmbT9N04D6,EddAmbT9N05D6,EddAmbT9N06D6,EddAmbT9N07D6,EddAmbT9N08D6,EddAmbT9N09D6,EddAmbT9N10D6, & + EddAmbT9N11D6,EddAmbT9N12D6,EddAmbT9N13D6,EddAmbT9N14D6,EddAmbT9N15D6,EddAmbT9N16D6,EddAmbT9N17D6,EddAmbT9N18D6,EddAmbT9N19D6,EddAmbT9N20D6, & + EddAmbT9N01D7,EddAmbT9N02D7,EddAmbT9N03D7,EddAmbT9N04D7,EddAmbT9N05D7,EddAmbT9N06D7,EddAmbT9N07D7,EddAmbT9N08D7,EddAmbT9N09D7,EddAmbT9N10D7, & + EddAmbT9N11D7,EddAmbT9N12D7,EddAmbT9N13D7,EddAmbT9N14D7,EddAmbT9N15D7,EddAmbT9N16D7,EddAmbT9N17D7,EddAmbT9N18D7,EddAmbT9N19D7,EddAmbT9N20D7, & + EddAmbT9N01D8,EddAmbT9N02D8,EddAmbT9N03D8,EddAmbT9N04D8,EddAmbT9N05D8,EddAmbT9N06D8,EddAmbT9N07D8,EddAmbT9N08D8,EddAmbT9N09D8,EddAmbT9N10D8, & + EddAmbT9N11D8,EddAmbT9N12D8,EddAmbT9N13D8,EddAmbT9N14D8,EddAmbT9N15D8,EddAmbT9N16D8,EddAmbT9N17D8,EddAmbT9N18D8,EddAmbT9N19D8,EddAmbT9N20D8, & + EddAmbT9N01D9,EddAmbT9N02D9,EddAmbT9N03D9,EddAmbT9N04D9,EddAmbT9N05D9,EddAmbT9N06D9,EddAmbT9N07D9,EddAmbT9N08D9,EddAmbT9N09D9,EddAmbT9N10D9, & + EddAmbT9N11D9,EddAmbT9N12D9,EddAmbT9N13D9,EddAmbT9N14D9,EddAmbT9N15D9,EddAmbT9N16D9,EddAmbT9N17D9,EddAmbT9N18D9,EddAmbT9N19D9,EddAmbT9N20D9/), (/20,9/) ) + + +EddShrTND(:,:,1) = RESHAPE( & + (/EddShrT1N01D1,EddShrT1N02D1,EddShrT1N03D1,EddShrT1N04D1,EddShrT1N05D1,EddShrT1N06D1,EddShrT1N07D1,EddShrT1N08D1,EddShrT1N09D1,EddShrT1N10D1, & + EddShrT1N11D1,EddShrT1N12D1,EddShrT1N13D1,EddShrT1N14D1,EddShrT1N15D1,EddShrT1N16D1,EddShrT1N17D1,EddShrT1N18D1,EddShrT1N19D1,EddShrT1N20D1, & + EddShrT1N01D2,EddShrT1N02D2,EddShrT1N03D2,EddShrT1N04D2,EddShrT1N05D2,EddShrT1N06D2,EddShrT1N07D2,EddShrT1N08D2,EddShrT1N09D2,EddShrT1N10D2, & + EddShrT1N11D2,EddShrT1N12D2,EddShrT1N13D2,EddShrT1N14D2,EddShrT1N15D2,EddShrT1N16D2,EddShrT1N17D2,EddShrT1N18D2,EddShrT1N19D2,EddShrT1N20D2, & + EddShrT1N01D3,EddShrT1N02D3,EddShrT1N03D3,EddShrT1N04D3,EddShrT1N05D3,EddShrT1N06D3,EddShrT1N07D3,EddShrT1N08D3,EddShrT1N09D3,EddShrT1N10D3, & + EddShrT1N11D3,EddShrT1N12D3,EddShrT1N13D3,EddShrT1N14D3,EddShrT1N15D3,EddShrT1N16D3,EddShrT1N17D3,EddShrT1N18D3,EddShrT1N19D3,EddShrT1N20D3, & + EddShrT1N01D4,EddShrT1N02D4,EddShrT1N03D4,EddShrT1N04D4,EddShrT1N05D4,EddShrT1N06D4,EddShrT1N07D4,EddShrT1N08D4,EddShrT1N09D4,EddShrT1N10D4, & + EddShrT1N11D4,EddShrT1N12D4,EddShrT1N13D4,EddShrT1N14D4,EddShrT1N15D4,EddShrT1N16D4,EddShrT1N17D4,EddShrT1N18D4,EddShrT1N19D4,EddShrT1N20D4, & + EddShrT1N01D5,EddShrT1N02D5,EddShrT1N03D5,EddShrT1N04D5,EddShrT1N05D5,EddShrT1N06D5,EddShrT1N07D5,EddShrT1N08D5,EddShrT1N09D5,EddShrT1N10D5, & + EddShrT1N11D5,EddShrT1N12D5,EddShrT1N13D5,EddShrT1N14D5,EddShrT1N15D5,EddShrT1N16D5,EddShrT1N17D5,EddShrT1N18D5,EddShrT1N19D5,EddShrT1N20D5, & + EddShrT1N01D6,EddShrT1N02D6,EddShrT1N03D6,EddShrT1N04D6,EddShrT1N05D6,EddShrT1N06D6,EddShrT1N07D6,EddShrT1N08D6,EddShrT1N09D6,EddShrT1N10D6, & + EddShrT1N11D6,EddShrT1N12D6,EddShrT1N13D6,EddShrT1N14D6,EddShrT1N15D6,EddShrT1N16D6,EddShrT1N17D6,EddShrT1N18D6,EddShrT1N19D6,EddShrT1N20D6, & + EddShrT1N01D7,EddShrT1N02D7,EddShrT1N03D7,EddShrT1N04D7,EddShrT1N05D7,EddShrT1N06D7,EddShrT1N07D7,EddShrT1N08D7,EddShrT1N09D7,EddShrT1N10D7, & + EddShrT1N11D7,EddShrT1N12D7,EddShrT1N13D7,EddShrT1N14D7,EddShrT1N15D7,EddShrT1N16D7,EddShrT1N17D7,EddShrT1N18D7,EddShrT1N19D7,EddShrT1N20D7, & + EddShrT1N01D8,EddShrT1N02D8,EddShrT1N03D8,EddShrT1N04D8,EddShrT1N05D8,EddShrT1N06D8,EddShrT1N07D8,EddShrT1N08D8,EddShrT1N09D8,EddShrT1N10D8, & + EddShrT1N11D8,EddShrT1N12D8,EddShrT1N13D8,EddShrT1N14D8,EddShrT1N15D8,EddShrT1N16D8,EddShrT1N17D8,EddShrT1N18D8,EddShrT1N19D8,EddShrT1N20D8, & + EddShrT1N01D9,EddShrT1N02D9,EddShrT1N03D9,EddShrT1N04D9,EddShrT1N05D9,EddShrT1N06D9,EddShrT1N07D9,EddShrT1N08D9,EddShrT1N09D9,EddShrT1N10D9, & + EddShrT1N11D9,EddShrT1N12D9,EddShrT1N13D9,EddShrT1N14D9,EddShrT1N15D9,EddShrT1N16D9,EddShrT1N17D9,EddShrT1N18D9,EddShrT1N19D9,EddShrT1N20D9/), (/20,9/) ) +EddShrTND(:,:,2) = RESHAPE( & + (/EddShrT2N01D1,EddShrT2N02D1,EddShrT2N03D1,EddShrT2N04D1,EddShrT2N05D1,EddShrT2N06D1,EddShrT2N07D1,EddShrT2N08D1,EddShrT2N09D1,EddShrT2N10D1, & + EddShrT2N11D1,EddShrT2N12D1,EddShrT2N13D1,EddShrT2N14D1,EddShrT2N15D1,EddShrT2N16D1,EddShrT2N17D1,EddShrT2N18D1,EddShrT2N19D1,EddShrT2N20D1, & + EddShrT2N01D2,EddShrT2N02D2,EddShrT2N03D2,EddShrT2N04D2,EddShrT2N05D2,EddShrT2N06D2,EddShrT2N07D2,EddShrT2N08D2,EddShrT2N09D2,EddShrT2N10D2, & + EddShrT2N11D2,EddShrT2N12D2,EddShrT2N13D2,EddShrT2N14D2,EddShrT2N15D2,EddShrT2N16D2,EddShrT2N17D2,EddShrT2N18D2,EddShrT2N19D2,EddShrT2N20D2, & + EddShrT2N01D3,EddShrT2N02D3,EddShrT2N03D3,EddShrT2N04D3,EddShrT2N05D3,EddShrT2N06D3,EddShrT2N07D3,EddShrT2N08D3,EddShrT2N09D3,EddShrT2N10D3, & + EddShrT2N11D3,EddShrT2N12D3,EddShrT2N13D3,EddShrT2N14D3,EddShrT2N15D3,EddShrT2N16D3,EddShrT2N17D3,EddShrT2N18D3,EddShrT2N19D3,EddShrT2N20D3, & + EddShrT2N01D4,EddShrT2N02D4,EddShrT2N03D4,EddShrT2N04D4,EddShrT2N05D4,EddShrT2N06D4,EddShrT2N07D4,EddShrT2N08D4,EddShrT2N09D4,EddShrT2N10D4, & + EddShrT2N11D4,EddShrT2N12D4,EddShrT2N13D4,EddShrT2N14D4,EddShrT2N15D4,EddShrT2N16D4,EddShrT2N17D4,EddShrT2N18D4,EddShrT2N19D4,EddShrT2N20D4, & + EddShrT2N01D5,EddShrT2N02D5,EddShrT2N03D5,EddShrT2N04D5,EddShrT2N05D5,EddShrT2N06D5,EddShrT2N07D5,EddShrT2N08D5,EddShrT2N09D5,EddShrT2N10D5, & + EddShrT2N11D5,EddShrT2N12D5,EddShrT2N13D5,EddShrT2N14D5,EddShrT2N15D5,EddShrT2N16D5,EddShrT2N17D5,EddShrT2N18D5,EddShrT2N19D5,EddShrT2N20D5, & + EddShrT2N01D6,EddShrT2N02D6,EddShrT2N03D6,EddShrT2N04D6,EddShrT2N05D6,EddShrT2N06D6,EddShrT2N07D6,EddShrT2N08D6,EddShrT2N09D6,EddShrT2N10D6, & + EddShrT2N11D6,EddShrT2N12D6,EddShrT2N13D6,EddShrT2N14D6,EddShrT2N15D6,EddShrT2N16D6,EddShrT2N17D6,EddShrT2N18D6,EddShrT2N19D6,EddShrT2N20D6, & + EddShrT2N01D7,EddShrT2N02D7,EddShrT2N03D7,EddShrT2N04D7,EddShrT2N05D7,EddShrT2N06D7,EddShrT2N07D7,EddShrT2N08D7,EddShrT2N09D7,EddShrT2N10D7, & + EddShrT2N11D7,EddShrT2N12D7,EddShrT2N13D7,EddShrT2N14D7,EddShrT2N15D7,EddShrT2N16D7,EddShrT2N17D7,EddShrT2N18D7,EddShrT2N19D7,EddShrT2N20D7, & + EddShrT2N01D8,EddShrT2N02D8,EddShrT2N03D8,EddShrT2N04D8,EddShrT2N05D8,EddShrT2N06D8,EddShrT2N07D8,EddShrT2N08D8,EddShrT2N09D8,EddShrT2N10D8, & + EddShrT2N11D8,EddShrT2N12D8,EddShrT2N13D8,EddShrT2N14D8,EddShrT2N15D8,EddShrT2N16D8,EddShrT2N17D8,EddShrT2N18D8,EddShrT2N19D8,EddShrT2N20D8, & + EddShrT2N01D9,EddShrT2N02D9,EddShrT2N03D9,EddShrT2N04D9,EddShrT2N05D9,EddShrT2N06D9,EddShrT2N07D9,EddShrT2N08D9,EddShrT2N09D9,EddShrT2N10D9, & + EddShrT2N11D9,EddShrT2N12D9,EddShrT2N13D9,EddShrT2N14D9,EddShrT2N15D9,EddShrT2N16D9,EddShrT2N17D9,EddShrT2N18D9,EddShrT2N19D9,EddShrT2N20D9/), (/20,9/) ) +EddShrTND(:,:,3) = RESHAPE( & + (/EddShrT3N01D1,EddShrT3N02D1,EddShrT3N03D1,EddShrT3N04D1,EddShrT3N05D1,EddShrT3N06D1,EddShrT3N07D1,EddShrT3N08D1,EddShrT3N09D1,EddShrT3N10D1, & + EddShrT3N11D1,EddShrT3N12D1,EddShrT3N13D1,EddShrT3N14D1,EddShrT3N15D1,EddShrT3N16D1,EddShrT3N17D1,EddShrT3N18D1,EddShrT3N19D1,EddShrT3N20D1, & + EddShrT3N01D2,EddShrT3N02D2,EddShrT3N03D2,EddShrT3N04D2,EddShrT3N05D2,EddShrT3N06D2,EddShrT3N07D2,EddShrT3N08D2,EddShrT3N09D2,EddShrT3N10D2, & + EddShrT3N11D2,EddShrT3N12D2,EddShrT3N13D2,EddShrT3N14D2,EddShrT3N15D2,EddShrT3N16D2,EddShrT3N17D2,EddShrT3N18D2,EddShrT3N19D2,EddShrT3N20D2, & + EddShrT3N01D3,EddShrT3N02D3,EddShrT3N03D3,EddShrT3N04D3,EddShrT3N05D3,EddShrT3N06D3,EddShrT3N07D3,EddShrT3N08D3,EddShrT3N09D3,EddShrT3N10D3, & + EddShrT3N11D3,EddShrT3N12D3,EddShrT3N13D3,EddShrT3N14D3,EddShrT3N15D3,EddShrT3N16D3,EddShrT3N17D3,EddShrT3N18D3,EddShrT3N19D3,EddShrT3N20D3, & + EddShrT3N01D4,EddShrT3N02D4,EddShrT3N03D4,EddShrT3N04D4,EddShrT3N05D4,EddShrT3N06D4,EddShrT3N07D4,EddShrT3N08D4,EddShrT3N09D4,EddShrT3N10D4, & + EddShrT3N11D4,EddShrT3N12D4,EddShrT3N13D4,EddShrT3N14D4,EddShrT3N15D4,EddShrT3N16D4,EddShrT3N17D4,EddShrT3N18D4,EddShrT3N19D4,EddShrT3N20D4, & + EddShrT3N01D5,EddShrT3N02D5,EddShrT3N03D5,EddShrT3N04D5,EddShrT3N05D5,EddShrT3N06D5,EddShrT3N07D5,EddShrT3N08D5,EddShrT3N09D5,EddShrT3N10D5, & + EddShrT3N11D5,EddShrT3N12D5,EddShrT3N13D5,EddShrT3N14D5,EddShrT3N15D5,EddShrT3N16D5,EddShrT3N17D5,EddShrT3N18D5,EddShrT3N19D5,EddShrT3N20D5, & + EddShrT3N01D6,EddShrT3N02D6,EddShrT3N03D6,EddShrT3N04D6,EddShrT3N05D6,EddShrT3N06D6,EddShrT3N07D6,EddShrT3N08D6,EddShrT3N09D6,EddShrT3N10D6, & + EddShrT3N11D6,EddShrT3N12D6,EddShrT3N13D6,EddShrT3N14D6,EddShrT3N15D6,EddShrT3N16D6,EddShrT3N17D6,EddShrT3N18D6,EddShrT3N19D6,EddShrT3N20D6, & + EddShrT3N01D7,EddShrT3N02D7,EddShrT3N03D7,EddShrT3N04D7,EddShrT3N05D7,EddShrT3N06D7,EddShrT3N07D7,EddShrT3N08D7,EddShrT3N09D7,EddShrT3N10D7, & + EddShrT3N11D7,EddShrT3N12D7,EddShrT3N13D7,EddShrT3N14D7,EddShrT3N15D7,EddShrT3N16D7,EddShrT3N17D7,EddShrT3N18D7,EddShrT3N19D7,EddShrT3N20D7, & + EddShrT3N01D8,EddShrT3N02D8,EddShrT3N03D8,EddShrT3N04D8,EddShrT3N05D8,EddShrT3N06D8,EddShrT3N07D8,EddShrT3N08D8,EddShrT3N09D8,EddShrT3N10D8, & + EddShrT3N11D8,EddShrT3N12D8,EddShrT3N13D8,EddShrT3N14D8,EddShrT3N15D8,EddShrT3N16D8,EddShrT3N17D8,EddShrT3N18D8,EddShrT3N19D8,EddShrT3N20D8, & + EddShrT3N01D9,EddShrT3N02D9,EddShrT3N03D9,EddShrT3N04D9,EddShrT3N05D9,EddShrT3N06D9,EddShrT3N07D9,EddShrT3N08D9,EddShrT3N09D9,EddShrT3N10D9, & + EddShrT3N11D9,EddShrT3N12D9,EddShrT3N13D9,EddShrT3N14D9,EddShrT3N15D9,EddShrT3N16D9,EddShrT3N17D9,EddShrT3N18D9,EddShrT3N19D9,EddShrT3N20D9/), (/20,9/) ) +EddShrTND(:,:,4) = RESHAPE( & + (/EddShrT4N01D1,EddShrT4N02D1,EddShrT4N03D1,EddShrT4N04D1,EddShrT4N05D1,EddShrT4N06D1,EddShrT4N07D1,EddShrT4N08D1,EddShrT4N09D1,EddShrT4N10D1, & + EddShrT4N11D1,EddShrT4N12D1,EddShrT4N13D1,EddShrT4N14D1,EddShrT4N15D1,EddShrT4N16D1,EddShrT4N17D1,EddShrT4N18D1,EddShrT4N19D1,EddShrT4N20D1, & + EddShrT4N01D2,EddShrT4N02D2,EddShrT4N03D2,EddShrT4N04D2,EddShrT4N05D2,EddShrT4N06D2,EddShrT4N07D2,EddShrT4N08D2,EddShrT4N09D2,EddShrT4N10D2, & + EddShrT4N11D2,EddShrT4N12D2,EddShrT4N13D2,EddShrT4N14D2,EddShrT4N15D2,EddShrT4N16D2,EddShrT4N17D2,EddShrT4N18D2,EddShrT4N19D2,EddShrT4N20D2, & + EddShrT4N01D3,EddShrT4N02D3,EddShrT4N03D3,EddShrT4N04D3,EddShrT4N05D3,EddShrT4N06D3,EddShrT4N07D3,EddShrT4N08D3,EddShrT4N09D3,EddShrT4N10D3, & + EddShrT4N11D3,EddShrT4N12D3,EddShrT4N13D3,EddShrT4N14D3,EddShrT4N15D3,EddShrT4N16D3,EddShrT4N17D3,EddShrT4N18D3,EddShrT4N19D3,EddShrT4N20D3, & + EddShrT4N01D4,EddShrT4N02D4,EddShrT4N03D4,EddShrT4N04D4,EddShrT4N05D4,EddShrT4N06D4,EddShrT4N07D4,EddShrT4N08D4,EddShrT4N09D4,EddShrT4N10D4, & + EddShrT4N11D4,EddShrT4N12D4,EddShrT4N13D4,EddShrT4N14D4,EddShrT4N15D4,EddShrT4N16D4,EddShrT4N17D4,EddShrT4N18D4,EddShrT4N19D4,EddShrT4N20D4, & + EddShrT4N01D5,EddShrT4N02D5,EddShrT4N03D5,EddShrT4N04D5,EddShrT4N05D5,EddShrT4N06D5,EddShrT4N07D5,EddShrT4N08D5,EddShrT4N09D5,EddShrT4N10D5, & + EddShrT4N11D5,EddShrT4N12D5,EddShrT4N13D5,EddShrT4N14D5,EddShrT4N15D5,EddShrT4N16D5,EddShrT4N17D5,EddShrT4N18D5,EddShrT4N19D5,EddShrT4N20D5, & + EddShrT4N01D6,EddShrT4N02D6,EddShrT4N03D6,EddShrT4N04D6,EddShrT4N05D6,EddShrT4N06D6,EddShrT4N07D6,EddShrT4N08D6,EddShrT4N09D6,EddShrT4N10D6, & + EddShrT4N11D6,EddShrT4N12D6,EddShrT4N13D6,EddShrT4N14D6,EddShrT4N15D6,EddShrT4N16D6,EddShrT4N17D6,EddShrT4N18D6,EddShrT4N19D6,EddShrT4N20D6, & + EddShrT4N01D7,EddShrT4N02D7,EddShrT4N03D7,EddShrT4N04D7,EddShrT4N05D7,EddShrT4N06D7,EddShrT4N07D7,EddShrT4N08D7,EddShrT4N09D7,EddShrT4N10D7, & + EddShrT4N11D7,EddShrT4N12D7,EddShrT4N13D7,EddShrT4N14D7,EddShrT4N15D7,EddShrT4N16D7,EddShrT4N17D7,EddShrT4N18D7,EddShrT4N19D7,EddShrT4N20D7, & + EddShrT4N01D8,EddShrT4N02D8,EddShrT4N03D8,EddShrT4N04D8,EddShrT4N05D8,EddShrT4N06D8,EddShrT4N07D8,EddShrT4N08D8,EddShrT4N09D8,EddShrT4N10D8, & + EddShrT4N11D8,EddShrT4N12D8,EddShrT4N13D8,EddShrT4N14D8,EddShrT4N15D8,EddShrT4N16D8,EddShrT4N17D8,EddShrT4N18D8,EddShrT4N19D8,EddShrT4N20D8, & + EddShrT4N01D9,EddShrT4N02D9,EddShrT4N03D9,EddShrT4N04D9,EddShrT4N05D9,EddShrT4N06D9,EddShrT4N07D9,EddShrT4N08D9,EddShrT4N09D9,EddShrT4N10D9, & + EddShrT4N11D9,EddShrT4N12D9,EddShrT4N13D9,EddShrT4N14D9,EddShrT4N15D9,EddShrT4N16D9,EddShrT4N17D9,EddShrT4N18D9,EddShrT4N19D9,EddShrT4N20D9/), (/20,9/) ) + +EddShrTND(:,:,5) = RESHAPE( & + (/EddShrT5N01D1,EddShrT5N02D1,EddShrT5N03D1,EddShrT5N04D1,EddShrT5N05D1,EddShrT5N06D1,EddShrT5N07D1,EddShrT5N08D1,EddShrT5N09D1,EddShrT5N10D1, & + EddShrT5N11D1,EddShrT5N12D1,EddShrT5N13D1,EddShrT5N14D1,EddShrT5N15D1,EddShrT5N16D1,EddShrT5N17D1,EddShrT5N18D1,EddShrT5N19D1,EddShrT5N20D1, & + EddShrT5N01D2,EddShrT5N02D2,EddShrT5N03D2,EddShrT5N04D2,EddShrT5N05D2,EddShrT5N06D2,EddShrT5N07D2,EddShrT5N08D2,EddShrT5N09D2,EddShrT5N10D2, & + EddShrT5N11D2,EddShrT5N12D2,EddShrT5N13D2,EddShrT5N14D2,EddShrT5N15D2,EddShrT5N16D2,EddShrT5N17D2,EddShrT5N18D2,EddShrT5N19D2,EddShrT5N20D2, & + EddShrT5N01D3,EddShrT5N02D3,EddShrT5N03D3,EddShrT5N04D3,EddShrT5N05D3,EddShrT5N06D3,EddShrT5N07D3,EddShrT5N08D3,EddShrT5N09D3,EddShrT5N10D3, & + EddShrT5N11D3,EddShrT5N12D3,EddShrT5N13D3,EddShrT5N14D3,EddShrT5N15D3,EddShrT5N16D3,EddShrT5N17D3,EddShrT5N18D3,EddShrT5N19D3,EddShrT5N20D3, & + EddShrT5N01D4,EddShrT5N02D4,EddShrT5N03D4,EddShrT5N04D4,EddShrT5N05D4,EddShrT5N06D4,EddShrT5N07D4,EddShrT5N08D4,EddShrT5N09D4,EddShrT5N10D4, & + EddShrT5N11D4,EddShrT5N12D4,EddShrT5N13D4,EddShrT5N14D4,EddShrT5N15D4,EddShrT5N16D4,EddShrT5N17D4,EddShrT5N18D4,EddShrT5N19D4,EddShrT5N20D4, & + EddShrT5N01D5,EddShrT5N02D5,EddShrT5N03D5,EddShrT5N04D5,EddShrT5N05D5,EddShrT5N06D5,EddShrT5N07D5,EddShrT5N08D5,EddShrT5N09D5,EddShrT5N10D5, & + EddShrT5N11D5,EddShrT5N12D5,EddShrT5N13D5,EddShrT5N14D5,EddShrT5N15D5,EddShrT5N16D5,EddShrT5N17D5,EddShrT5N18D5,EddShrT5N19D5,EddShrT5N20D5, & + EddShrT5N01D6,EddShrT5N02D6,EddShrT5N03D6,EddShrT5N04D6,EddShrT5N05D6,EddShrT5N06D6,EddShrT5N07D6,EddShrT5N08D6,EddShrT5N09D6,EddShrT5N10D6, & + EddShrT5N11D6,EddShrT5N12D6,EddShrT5N13D6,EddShrT5N14D6,EddShrT5N15D6,EddShrT5N16D6,EddShrT5N17D6,EddShrT5N18D6,EddShrT5N19D6,EddShrT5N20D6, & + EddShrT5N01D7,EddShrT5N02D7,EddShrT5N03D7,EddShrT5N04D7,EddShrT5N05D7,EddShrT5N06D7,EddShrT5N07D7,EddShrT5N08D7,EddShrT5N09D7,EddShrT5N10D7, & + EddShrT5N11D7,EddShrT5N12D7,EddShrT5N13D7,EddShrT5N14D7,EddShrT5N15D7,EddShrT5N16D7,EddShrT5N17D7,EddShrT5N18D7,EddShrT5N19D7,EddShrT5N20D7, & + EddShrT5N01D8,EddShrT5N02D8,EddShrT5N03D8,EddShrT5N04D8,EddShrT5N05D8,EddShrT5N06D8,EddShrT5N07D8,EddShrT5N08D8,EddShrT5N09D8,EddShrT5N10D8, & + EddShrT5N11D8,EddShrT5N12D8,EddShrT5N13D8,EddShrT5N14D8,EddShrT5N15D8,EddShrT5N16D8,EddShrT5N17D8,EddShrT5N18D8,EddShrT5N19D8,EddShrT5N20D8, & + EddShrT5N01D9,EddShrT5N02D9,EddShrT5N03D9,EddShrT5N04D9,EddShrT5N05D9,EddShrT5N06D9,EddShrT5N07D9,EddShrT5N08D9,EddShrT5N09D9,EddShrT5N10D9, & + EddShrT5N11D9,EddShrT5N12D9,EddShrT5N13D9,EddShrT5N14D9,EddShrT5N15D9,EddShrT5N16D9,EddShrT5N17D9,EddShrT5N18D9,EddShrT5N19D9,EddShrT5N20D9/), (/20,9/) ) +EddShrTND(:,:,6) = RESHAPE( & + (/EddShrT6N01D1,EddShrT6N02D1,EddShrT6N03D1,EddShrT6N04D1,EddShrT6N05D1,EddShrT6N06D1,EddShrT6N07D1,EddShrT6N08D1,EddShrT6N09D1,EddShrT6N10D1, & + EddShrT6N11D1,EddShrT6N12D1,EddShrT6N13D1,EddShrT6N14D1,EddShrT6N15D1,EddShrT6N16D1,EddShrT6N17D1,EddShrT6N18D1,EddShrT6N19D1,EddShrT6N20D1, & + EddShrT6N01D2,EddShrT6N02D2,EddShrT6N03D2,EddShrT6N04D2,EddShrT6N05D2,EddShrT6N06D2,EddShrT6N07D2,EddShrT6N08D2,EddShrT6N09D2,EddShrT6N10D2, & + EddShrT6N11D2,EddShrT6N12D2,EddShrT6N13D2,EddShrT6N14D2,EddShrT6N15D2,EddShrT6N16D2,EddShrT6N17D2,EddShrT6N18D2,EddShrT6N19D2,EddShrT6N20D2, & + EddShrT6N01D3,EddShrT6N02D3,EddShrT6N03D3,EddShrT6N04D3,EddShrT6N05D3,EddShrT6N06D3,EddShrT6N07D3,EddShrT6N08D3,EddShrT6N09D3,EddShrT6N10D3, & + EddShrT6N11D3,EddShrT6N12D3,EddShrT6N13D3,EddShrT6N14D3,EddShrT6N15D3,EddShrT6N16D3,EddShrT6N17D3,EddShrT6N18D3,EddShrT6N19D3,EddShrT6N20D3, & + EddShrT6N01D4,EddShrT6N02D4,EddShrT6N03D4,EddShrT6N04D4,EddShrT6N05D4,EddShrT6N06D4,EddShrT6N07D4,EddShrT6N08D4,EddShrT6N09D4,EddShrT6N10D4, & + EddShrT6N11D4,EddShrT6N12D4,EddShrT6N13D4,EddShrT6N14D4,EddShrT6N15D4,EddShrT6N16D4,EddShrT6N17D4,EddShrT6N18D4,EddShrT6N19D4,EddShrT6N20D4, & + EddShrT6N01D5,EddShrT6N02D5,EddShrT6N03D5,EddShrT6N04D5,EddShrT6N05D5,EddShrT6N06D5,EddShrT6N07D5,EddShrT6N08D5,EddShrT6N09D5,EddShrT6N10D5, & + EddShrT6N11D5,EddShrT6N12D5,EddShrT6N13D5,EddShrT6N14D5,EddShrT6N15D5,EddShrT6N16D5,EddShrT6N17D5,EddShrT6N18D5,EddShrT6N19D5,EddShrT6N20D5, & + EddShrT6N01D6,EddShrT6N02D6,EddShrT6N03D6,EddShrT6N04D6,EddShrT6N05D6,EddShrT6N06D6,EddShrT6N07D6,EddShrT6N08D6,EddShrT6N09D6,EddShrT6N10D6, & + EddShrT6N11D6,EddShrT6N12D6,EddShrT6N13D6,EddShrT6N14D6,EddShrT6N15D6,EddShrT6N16D6,EddShrT6N17D6,EddShrT6N18D6,EddShrT6N19D6,EddShrT6N20D6, & + EddShrT6N01D7,EddShrT6N02D7,EddShrT6N03D7,EddShrT6N04D7,EddShrT6N05D7,EddShrT6N06D7,EddShrT6N07D7,EddShrT6N08D7,EddShrT6N09D7,EddShrT6N10D7, & + EddShrT6N11D7,EddShrT6N12D7,EddShrT6N13D7,EddShrT6N14D7,EddShrT6N15D7,EddShrT6N16D7,EddShrT6N17D7,EddShrT6N18D7,EddShrT6N19D7,EddShrT6N20D7, & + EddShrT6N01D8,EddShrT6N02D8,EddShrT6N03D8,EddShrT6N04D8,EddShrT6N05D8,EddShrT6N06D8,EddShrT6N07D8,EddShrT6N08D8,EddShrT6N09D8,EddShrT6N10D8, & + EddShrT6N11D8,EddShrT6N12D8,EddShrT6N13D8,EddShrT6N14D8,EddShrT6N15D8,EddShrT6N16D8,EddShrT6N17D8,EddShrT6N18D8,EddShrT6N19D8,EddShrT6N20D8, & + EddShrT6N01D9,EddShrT6N02D9,EddShrT6N03D9,EddShrT6N04D9,EddShrT6N05D9,EddShrT6N06D9,EddShrT6N07D9,EddShrT6N08D9,EddShrT6N09D9,EddShrT6N10D9, & + EddShrT6N11D9,EddShrT6N12D9,EddShrT6N13D9,EddShrT6N14D9,EddShrT6N15D9,EddShrT6N16D9,EddShrT6N17D9,EddShrT6N18D9,EddShrT6N19D9,EddShrT6N20D9/), (/20,9/) ) +EddShrTND(:,:,7) = RESHAPE( & + (/EddShrT7N01D1,EddShrT7N02D1,EddShrT7N03D1,EddShrT7N04D1,EddShrT7N05D1,EddShrT7N06D1,EddShrT7N07D1,EddShrT7N08D1,EddShrT7N09D1,EddShrT7N10D1, & + EddShrT7N11D1,EddShrT7N12D1,EddShrT7N13D1,EddShrT7N14D1,EddShrT7N15D1,EddShrT7N16D1,EddShrT7N17D1,EddShrT7N18D1,EddShrT7N19D1,EddShrT7N20D1, & + EddShrT7N01D2,EddShrT7N02D2,EddShrT7N03D2,EddShrT7N04D2,EddShrT7N05D2,EddShrT7N06D2,EddShrT7N07D2,EddShrT7N08D2,EddShrT7N09D2,EddShrT7N10D2, & + EddShrT7N11D2,EddShrT7N12D2,EddShrT7N13D2,EddShrT7N14D2,EddShrT7N15D2,EddShrT7N16D2,EddShrT7N17D2,EddShrT7N18D2,EddShrT7N19D2,EddShrT7N20D2, & + EddShrT7N01D3,EddShrT7N02D3,EddShrT7N03D3,EddShrT7N04D3,EddShrT7N05D3,EddShrT7N06D3,EddShrT7N07D3,EddShrT7N08D3,EddShrT7N09D3,EddShrT7N10D3, & + EddShrT7N11D3,EddShrT7N12D3,EddShrT7N13D3,EddShrT7N14D3,EddShrT7N15D3,EddShrT7N16D3,EddShrT7N17D3,EddShrT7N18D3,EddShrT7N19D3,EddShrT7N20D3, & + EddShrT7N01D4,EddShrT7N02D4,EddShrT7N03D4,EddShrT7N04D4,EddShrT7N05D4,EddShrT7N06D4,EddShrT7N07D4,EddShrT7N08D4,EddShrT7N09D4,EddShrT7N10D4, & + EddShrT7N11D4,EddShrT7N12D4,EddShrT7N13D4,EddShrT7N14D4,EddShrT7N15D4,EddShrT7N16D4,EddShrT7N17D4,EddShrT7N18D4,EddShrT7N19D4,EddShrT7N20D4, & + EddShrT7N01D5,EddShrT7N02D5,EddShrT7N03D5,EddShrT7N04D5,EddShrT7N05D5,EddShrT7N06D5,EddShrT7N07D5,EddShrT7N08D5,EddShrT7N09D5,EddShrT7N10D5, & + EddShrT7N11D5,EddShrT7N12D5,EddShrT7N13D5,EddShrT7N14D5,EddShrT7N15D5,EddShrT7N16D5,EddShrT7N17D5,EddShrT7N18D5,EddShrT7N19D5,EddShrT7N20D5, & + EddShrT7N01D6,EddShrT7N02D6,EddShrT7N03D6,EddShrT7N04D6,EddShrT7N05D6,EddShrT7N06D6,EddShrT7N07D6,EddShrT7N08D6,EddShrT7N09D6,EddShrT7N10D6, & + EddShrT7N11D6,EddShrT7N12D6,EddShrT7N13D6,EddShrT7N14D6,EddShrT7N15D6,EddShrT7N16D6,EddShrT7N17D6,EddShrT7N18D6,EddShrT7N19D6,EddShrT7N20D6, & + EddShrT7N01D7,EddShrT7N02D7,EddShrT7N03D7,EddShrT7N04D7,EddShrT7N05D7,EddShrT7N06D7,EddShrT7N07D7,EddShrT7N08D7,EddShrT7N09D7,EddShrT7N10D7, & + EddShrT7N11D7,EddShrT7N12D7,EddShrT7N13D7,EddShrT7N14D7,EddShrT7N15D7,EddShrT7N16D7,EddShrT7N17D7,EddShrT7N18D7,EddShrT7N19D7,EddShrT7N20D7, & + EddShrT7N01D8,EddShrT7N02D8,EddShrT7N03D8,EddShrT7N04D8,EddShrT7N05D8,EddShrT7N06D8,EddShrT7N07D8,EddShrT7N08D8,EddShrT7N09D8,EddShrT7N10D8, & + EddShrT7N11D8,EddShrT7N12D8,EddShrT7N13D8,EddShrT7N14D8,EddShrT7N15D8,EddShrT7N16D8,EddShrT7N17D8,EddShrT7N18D8,EddShrT7N19D8,EddShrT7N20D8, & + EddShrT7N01D9,EddShrT7N02D9,EddShrT7N03D9,EddShrT7N04D9,EddShrT7N05D9,EddShrT7N06D9,EddShrT7N07D9,EddShrT7N08D9,EddShrT7N09D9,EddShrT7N10D9, & + EddShrT7N11D9,EddShrT7N12D9,EddShrT7N13D9,EddShrT7N14D9,EddShrT7N15D9,EddShrT7N16D9,EddShrT7N17D9,EddShrT7N18D9,EddShrT7N19D9,EddShrT7N20D9/), (/20,9/) ) +EddShrTND(:,:,8) = RESHAPE( & + (/EddShrT8N01D1,EddShrT8N02D1,EddShrT8N03D1,EddShrT8N04D1,EddShrT8N05D1,EddShrT8N06D1,EddShrT8N07D1,EddShrT8N08D1,EddShrT8N09D1,EddShrT8N10D1, & + EddShrT8N11D1,EddShrT8N12D1,EddShrT8N13D1,EddShrT8N14D1,EddShrT8N15D1,EddShrT8N16D1,EddShrT8N17D1,EddShrT8N18D1,EddShrT8N19D1,EddShrT8N20D1, & + EddShrT8N01D2,EddShrT8N02D2,EddShrT8N03D2,EddShrT8N04D2,EddShrT8N05D2,EddShrT8N06D2,EddShrT8N07D2,EddShrT8N08D2,EddShrT8N09D2,EddShrT8N10D2, & + EddShrT8N11D2,EddShrT8N12D2,EddShrT8N13D2,EddShrT8N14D2,EddShrT8N15D2,EddShrT8N16D2,EddShrT8N17D2,EddShrT8N18D2,EddShrT8N19D2,EddShrT8N20D2, & + EddShrT8N01D3,EddShrT8N02D3,EddShrT8N03D3,EddShrT8N04D3,EddShrT8N05D3,EddShrT8N06D3,EddShrT8N07D3,EddShrT8N08D3,EddShrT8N09D3,EddShrT8N10D3, & + EddShrT8N11D3,EddShrT8N12D3,EddShrT8N13D3,EddShrT8N14D3,EddShrT8N15D3,EddShrT8N16D3,EddShrT8N17D3,EddShrT8N18D3,EddShrT8N19D3,EddShrT8N20D3, & + EddShrT8N01D4,EddShrT8N02D4,EddShrT8N03D4,EddShrT8N04D4,EddShrT8N05D4,EddShrT8N06D4,EddShrT8N07D4,EddShrT8N08D4,EddShrT8N09D4,EddShrT8N10D4, & + EddShrT8N11D4,EddShrT8N12D4,EddShrT8N13D4,EddShrT8N14D4,EddShrT8N15D4,EddShrT8N16D4,EddShrT8N17D4,EddShrT8N18D4,EddShrT8N19D4,EddShrT8N20D4, & + EddShrT8N01D5,EddShrT8N02D5,EddShrT8N03D5,EddShrT8N04D5,EddShrT8N05D5,EddShrT8N06D5,EddShrT8N07D5,EddShrT8N08D5,EddShrT8N09D5,EddShrT8N10D5, & + EddShrT8N11D5,EddShrT8N12D5,EddShrT8N13D5,EddShrT8N14D5,EddShrT8N15D5,EddShrT8N16D5,EddShrT8N17D5,EddShrT8N18D5,EddShrT8N19D5,EddShrT8N20D5, & + EddShrT8N01D6,EddShrT8N02D6,EddShrT8N03D6,EddShrT8N04D6,EddShrT8N05D6,EddShrT8N06D6,EddShrT8N07D6,EddShrT8N08D6,EddShrT8N09D6,EddShrT8N10D6, & + EddShrT8N11D6,EddShrT8N12D6,EddShrT8N13D6,EddShrT8N14D6,EddShrT8N15D6,EddShrT8N16D6,EddShrT8N17D6,EddShrT8N18D6,EddShrT8N19D6,EddShrT8N20D6, & + EddShrT8N01D7,EddShrT8N02D7,EddShrT8N03D7,EddShrT8N04D7,EddShrT8N05D7,EddShrT8N06D7,EddShrT8N07D7,EddShrT8N08D7,EddShrT8N09D7,EddShrT8N10D7, & + EddShrT8N11D7,EddShrT8N12D7,EddShrT8N13D7,EddShrT8N14D7,EddShrT8N15D7,EddShrT8N16D7,EddShrT8N17D7,EddShrT8N18D7,EddShrT8N19D7,EddShrT8N20D7, & + EddShrT8N01D8,EddShrT8N02D8,EddShrT8N03D8,EddShrT8N04D8,EddShrT8N05D8,EddShrT8N06D8,EddShrT8N07D8,EddShrT8N08D8,EddShrT8N09D8,EddShrT8N10D8, & + EddShrT8N11D8,EddShrT8N12D8,EddShrT8N13D8,EddShrT8N14D8,EddShrT8N15D8,EddShrT8N16D8,EddShrT8N17D8,EddShrT8N18D8,EddShrT8N19D8,EddShrT8N20D8, & + EddShrT8N01D9,EddShrT8N02D9,EddShrT8N03D9,EddShrT8N04D9,EddShrT8N05D9,EddShrT8N06D9,EddShrT8N07D9,EddShrT8N08D9,EddShrT8N09D9,EddShrT8N10D9, & + EddShrT8N11D9,EddShrT8N12D9,EddShrT8N13D9,EddShrT8N14D9,EddShrT8N15D9,EddShrT8N16D9,EddShrT8N17D9,EddShrT8N18D9,EddShrT8N19D9,EddShrT8N20D9/), (/20,9/) ) +EddShrTND(:,:,9) = RESHAPE( & + (/EddShrT9N01D1,EddShrT9N02D1,EddShrT9N03D1,EddShrT9N04D1,EddShrT9N05D1,EddShrT9N06D1,EddShrT9N07D1,EddShrT9N08D1,EddShrT9N09D1,EddShrT9N10D1, & + EddShrT9N11D1,EddShrT9N12D1,EddShrT9N13D1,EddShrT9N14D1,EddShrT9N15D1,EddShrT9N16D1,EddShrT9N17D1,EddShrT9N18D1,EddShrT9N19D1,EddShrT9N20D1, & + EddShrT9N01D2,EddShrT9N02D2,EddShrT9N03D2,EddShrT9N04D2,EddShrT9N05D2,EddShrT9N06D2,EddShrT9N07D2,EddShrT9N08D2,EddShrT9N09D2,EddShrT9N10D2, & + EddShrT9N11D2,EddShrT9N12D2,EddShrT9N13D2,EddShrT9N14D2,EddShrT9N15D2,EddShrT9N16D2,EddShrT9N17D2,EddShrT9N18D2,EddShrT9N19D2,EddShrT9N20D2, & + EddShrT9N01D3,EddShrT9N02D3,EddShrT9N03D3,EddShrT9N04D3,EddShrT9N05D3,EddShrT9N06D3,EddShrT9N07D3,EddShrT9N08D3,EddShrT9N09D3,EddShrT9N10D3, & + EddShrT9N11D3,EddShrT9N12D3,EddShrT9N13D3,EddShrT9N14D3,EddShrT9N15D3,EddShrT9N16D3,EddShrT9N17D3,EddShrT9N18D3,EddShrT9N19D3,EddShrT9N20D3, & + EddShrT9N01D4,EddShrT9N02D4,EddShrT9N03D4,EddShrT9N04D4,EddShrT9N05D4,EddShrT9N06D4,EddShrT9N07D4,EddShrT9N08D4,EddShrT9N09D4,EddShrT9N10D4, & + EddShrT9N11D4,EddShrT9N12D4,EddShrT9N13D4,EddShrT9N14D4,EddShrT9N15D4,EddShrT9N16D4,EddShrT9N17D4,EddShrT9N18D4,EddShrT9N19D4,EddShrT9N20D4, & + EddShrT9N01D5,EddShrT9N02D5,EddShrT9N03D5,EddShrT9N04D5,EddShrT9N05D5,EddShrT9N06D5,EddShrT9N07D5,EddShrT9N08D5,EddShrT9N09D5,EddShrT9N10D5, & + EddShrT9N11D5,EddShrT9N12D5,EddShrT9N13D5,EddShrT9N14D5,EddShrT9N15D5,EddShrT9N16D5,EddShrT9N17D5,EddShrT9N18D5,EddShrT9N19D5,EddShrT9N20D5, & + EddShrT9N01D6,EddShrT9N02D6,EddShrT9N03D6,EddShrT9N04D6,EddShrT9N05D6,EddShrT9N06D6,EddShrT9N07D6,EddShrT9N08D6,EddShrT9N09D6,EddShrT9N10D6, & + EddShrT9N11D6,EddShrT9N12D6,EddShrT9N13D6,EddShrT9N14D6,EddShrT9N15D6,EddShrT9N16D6,EddShrT9N17D6,EddShrT9N18D6,EddShrT9N19D6,EddShrT9N20D6, & + EddShrT9N01D7,EddShrT9N02D7,EddShrT9N03D7,EddShrT9N04D7,EddShrT9N05D7,EddShrT9N06D7,EddShrT9N07D7,EddShrT9N08D7,EddShrT9N09D7,EddShrT9N10D7, & + EddShrT9N11D7,EddShrT9N12D7,EddShrT9N13D7,EddShrT9N14D7,EddShrT9N15D7,EddShrT9N16D7,EddShrT9N17D7,EddShrT9N18D7,EddShrT9N19D7,EddShrT9N20D7, & + EddShrT9N01D8,EddShrT9N02D8,EddShrT9N03D8,EddShrT9N04D8,EddShrT9N05D8,EddShrT9N06D8,EddShrT9N07D8,EddShrT9N08D8,EddShrT9N09D8,EddShrT9N10D8, & + EddShrT9N11D8,EddShrT9N12D8,EddShrT9N13D8,EddShrT9N14D8,EddShrT9N15D8,EddShrT9N16D8,EddShrT9N17D8,EddShrT9N18D8,EddShrT9N19D8,EddShrT9N20D8, & + EddShrT9N01D9,EddShrT9N02D9,EddShrT9N03D9,EddShrT9N04D9,EddShrT9N05D9,EddShrT9N06D9,EddShrT9N07D9,EddShrT9N08D9,EddShrT9N09D9,EddShrT9N10D9, & + EddShrT9N11D9,EddShrT9N12D9,EddShrT9N13D9,EddShrT9N14D9,EddShrT9N15D9,EddShrT9N16D9,EddShrT9N17D9,EddShrT9N18D9,EddShrT9N19D9,EddShrT9N20D9/), (/20,9/) ) +END SUBROUTINE Farm_SetAggregatedChannelOutArrays + +!********************************************************************************************************************************** +! 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 routine checks to see if any requested output channel names (stored in the OutList(:)) are invalid. It returns a +!! warning if any of the channels are not available outputs from the module. +!! It assigns the settings for OutParam(:) (i.e, the index, name, and units of the output channels, WriteOutput(:)). +!! the sign is set to 0 if the channel is invalid. +!! It sets assumes the value p%NumOuts has been set before this routine has been called, and it sets the values of p%OutParam here. +!! +!! This routine was generated by Write_ChckOutLst.m using the parameters listed in OutListParameters.xlsx +SUBROUTINE Farm_SetOutParam(OutList, farm, ErrStat, ErrMsg ) +!.................................................................................................................................. + + IMPLICIT NONE + + ! Passed variables + + CHARACTER(ChanLen), INTENT(IN) :: OutList(:) !< The list out user-requested outputs + type(All_FastFarm_Data), INTENT(INOUT) :: farm !< FAST.Farm data + INTEGER(IntKi), INTENT(OUT) :: ErrStat !< The error status code + CHARACTER(*), INTENT(OUT) :: ErrMsg !< The error message, if an error occurred + + ! Local variables + + INTEGER :: ErrStat2 ! temporary (local) error status + INTEGER :: I ! Generic loop-counting index + INTEGER :: J ! Generic loop-counting index + INTEGER :: INDX ! Index for valid arrays + + LOGICAL :: InvalidOutput(0:Farm_MaxOutPts) ! This array determines if the output channel is valid for this configuration + CHARACTER(*), PARAMETER :: RoutineName = "SetOutParam" + + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry1(1356) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "AZISKEWFILTT1","AZISKEWFILTT2","AZISKEWFILTT3","AZISKEWFILTT4","AZISKEWFILTT5","AZISKEWFILTT6", & + "AZISKEWFILTT7","AZISKEWFILTT8","AZISKEWFILTT9","AZISKEWT1 ","AZISKEWT2 ","AZISKEWT3 ", & + "AZISKEWT4 ","AZISKEWT5 ","AZISKEWT6 ","AZISKEWT7 ","AZISKEWT8 ","AZISKEWT9 ", & + "CTT1N01 ","CTT1N02 ","CTT1N03 ","CTT1N04 ","CTT1N05 ","CTT1N06 ", & + "CTT1N07 ","CTT1N08 ","CTT1N09 ","CTT1N10 ","CTT1N11 ","CTT1N12 ", & + "CTT1N13 ","CTT1N14 ","CTT1N15 ","CTT1N16 ","CTT1N17 ","CTT1N18 ", & + "CTT1N19 ","CTT1N20 ","CTT2N01 ","CTT2N02 ","CTT2N03 ","CTT2N04 ", & + "CTT2N05 ","CTT2N06 ","CTT2N07 ","CTT2N08 ","CTT2N09 ","CTT2N10 ", & + "CTT2N11 ","CTT2N12 ","CTT2N13 ","CTT2N14 ","CTT2N15 ","CTT2N16 ", & + "CTT2N17 ","CTT2N18 ","CTT2N19 ","CTT2N20 ","CTT3N01 ","CTT3N02 ", & + "CTT3N03 ","CTT3N04 ","CTT3N05 ","CTT3N06 ","CTT3N07 ","CTT3N08 ", & + "CTT3N09 ","CTT3N10 ","CTT3N11 ","CTT3N12 ","CTT3N13 ","CTT3N14 ", & + "CTT3N15 ","CTT3N16 ","CTT3N17 ","CTT3N18 ","CTT3N19 ","CTT3N20 ", & + "CTT4N01 ","CTT4N02 ","CTT4N03 ","CTT4N04 ","CTT4N05 ","CTT4N06 ", & + "CTT4N07 ","CTT4N08 ","CTT4N09 ","CTT4N10 ","CTT4N11 ","CTT4N12 ", & + "CTT4N13 ","CTT4N14 ","CTT4N15 ","CTT4N16 ","CTT4N17 ","CTT4N18 ", & + "CTT4N19 ","CTT4N20 ","CTT5N01 ","CTT5N02 ","CTT5N03 ","CTT5N04 ", & + "CTT5N05 ","CTT5N06 ","CTT5N07 ","CTT5N08 ","CTT5N09 ","CTT5N10 ", & + "CTT5N11 ","CTT5N12 ","CTT5N13 ","CTT5N14 ","CTT5N15 ","CTT5N16 ", & + "CTT5N17 ","CTT5N18 ","CTT5N19 ","CTT5N20 ","CTT6N01 ","CTT6N02 ", & + "CTT6N03 ","CTT6N04 ","CTT6N05 ","CTT6N06 ","CTT6N07 ","CTT6N08 ", & + "CTT6N09 ","CTT6N10 ","CTT6N11 ","CTT6N12 ","CTT6N13 ","CTT6N14 ", & + "CTT6N15 ","CTT6N16 ","CTT6N17 ","CTT6N18 ","CTT6N19 ","CTT6N20 ", & + "CTT7N01 ","CTT7N02 ","CTT7N03 ","CTT7N04 ","CTT7N05 ","CTT7N06 ", & + "CTT7N07 ","CTT7N08 ","CTT7N09 ","CTT7N10 ","CTT7N11 ","CTT7N12 ", & + "CTT7N13 ","CTT7N14 ","CTT7N15 ","CTT7N16 ","CTT7N17 ","CTT7N18 ", & + "CTT7N19 ","CTT7N20 ","CTT8N01 ","CTT8N02 ","CTT8N03 ","CTT8N04 ", & + "CTT8N05 ","CTT8N06 ","CTT8N07 ","CTT8N08 ","CTT8N09 ","CTT8N10 ", & + "CTT8N11 ","CTT8N12 ","CTT8N13 ","CTT8N14 ","CTT8N15 ","CTT8N16 ", & + "CTT8N17 ","CTT8N18 ","CTT8N19 ","CTT8N20 ","CTT9N01 ","CTT9N02 ", & + "CTT9N03 ","CTT9N04 ","CTT9N05 ","CTT9N06 ","CTT9N07 ","CTT9N08 ", & + "CTT9N09 ","CTT9N10 ","CTT9N11 ","CTT9N12 ","CTT9N13 ","CTT9N14 ", & + "CTT9N15 ","CTT9N16 ","CTT9N17 ","CTT9N18 ","CTT9N19 ","CTT9N20 ", & + "EDDAMBT1N01D1","EDDAMBT1N01D2","EDDAMBT1N01D3","EDDAMBT1N01D4","EDDAMBT1N01D5","EDDAMBT1N01D6", & + "EDDAMBT1N01D7","EDDAMBT1N01D8","EDDAMBT1N01D9","EDDAMBT1N02D1","EDDAMBT1N02D2","EDDAMBT1N02D3", & + "EDDAMBT1N02D4","EDDAMBT1N02D5","EDDAMBT1N02D6","EDDAMBT1N02D7","EDDAMBT1N02D8","EDDAMBT1N02D9", & + "EDDAMBT1N03D1","EDDAMBT1N03D2","EDDAMBT1N03D3","EDDAMBT1N03D4","EDDAMBT1N03D5","EDDAMBT1N03D6", & + "EDDAMBT1N03D7","EDDAMBT1N03D8","EDDAMBT1N03D9","EDDAMBT1N04D1","EDDAMBT1N04D2","EDDAMBT1N04D3", & + "EDDAMBT1N04D4","EDDAMBT1N04D5","EDDAMBT1N04D6","EDDAMBT1N04D7","EDDAMBT1N04D8","EDDAMBT1N04D9", & + "EDDAMBT1N05D1","EDDAMBT1N05D2","EDDAMBT1N05D3","EDDAMBT1N05D4","EDDAMBT1N05D5","EDDAMBT1N05D6", & + "EDDAMBT1N05D7","EDDAMBT1N05D8","EDDAMBT1N05D9","EDDAMBT1N06D1","EDDAMBT1N06D2","EDDAMBT1N06D3", & + "EDDAMBT1N06D4","EDDAMBT1N06D5","EDDAMBT1N06D6","EDDAMBT1N06D7","EDDAMBT1N06D8","EDDAMBT1N06D9", & + "EDDAMBT1N07D1","EDDAMBT1N07D2","EDDAMBT1N07D3","EDDAMBT1N07D4","EDDAMBT1N07D5","EDDAMBT1N07D6", & + "EDDAMBT1N07D7","EDDAMBT1N07D8","EDDAMBT1N07D9","EDDAMBT1N08D1","EDDAMBT1N08D2","EDDAMBT1N08D3", & + "EDDAMBT1N08D4","EDDAMBT1N08D5","EDDAMBT1N08D6","EDDAMBT1N08D7","EDDAMBT1N08D8","EDDAMBT1N08D9", & + "EDDAMBT1N09D1","EDDAMBT1N09D2","EDDAMBT1N09D3","EDDAMBT1N09D4","EDDAMBT1N09D5","EDDAMBT1N09D6", & + "EDDAMBT1N09D7","EDDAMBT1N09D8","EDDAMBT1N09D9","EDDAMBT1N10D1","EDDAMBT1N10D2","EDDAMBT1N10D3", & + "EDDAMBT1N10D4","EDDAMBT1N10D5","EDDAMBT1N10D6","EDDAMBT1N10D7","EDDAMBT1N10D8","EDDAMBT1N10D9", & + "EDDAMBT1N11D1","EDDAMBT1N11D2","EDDAMBT1N11D3","EDDAMBT1N11D4","EDDAMBT1N11D5","EDDAMBT1N11D6", & + "EDDAMBT1N11D7","EDDAMBT1N11D8","EDDAMBT1N11D9","EDDAMBT1N12D1","EDDAMBT1N12D2","EDDAMBT1N12D3", & + "EDDAMBT1N12D4","EDDAMBT1N12D5","EDDAMBT1N12D6","EDDAMBT1N12D7","EDDAMBT1N12D8","EDDAMBT1N12D9", & + "EDDAMBT1N13D1","EDDAMBT1N13D2","EDDAMBT1N13D3","EDDAMBT1N13D4","EDDAMBT1N13D5","EDDAMBT1N13D6", & + "EDDAMBT1N13D7","EDDAMBT1N13D8","EDDAMBT1N13D9","EDDAMBT1N14D1","EDDAMBT1N14D2","EDDAMBT1N14D3", & + "EDDAMBT1N14D4","EDDAMBT1N14D5","EDDAMBT1N14D6","EDDAMBT1N14D7","EDDAMBT1N14D8","EDDAMBT1N14D9", & + "EDDAMBT1N15D1","EDDAMBT1N15D2","EDDAMBT1N15D3","EDDAMBT1N15D4","EDDAMBT1N15D5","EDDAMBT1N15D6", & + "EDDAMBT1N15D7","EDDAMBT1N15D8","EDDAMBT1N15D9","EDDAMBT1N16D1","EDDAMBT1N16D2","EDDAMBT1N16D3", & + "EDDAMBT1N16D4","EDDAMBT1N16D5","EDDAMBT1N16D6","EDDAMBT1N16D7","EDDAMBT1N16D8","EDDAMBT1N16D9", & + "EDDAMBT1N17D1","EDDAMBT1N17D2","EDDAMBT1N17D3","EDDAMBT1N17D4","EDDAMBT1N17D5","EDDAMBT1N17D6", & + "EDDAMBT1N17D7","EDDAMBT1N17D8","EDDAMBT1N17D9","EDDAMBT1N18D1","EDDAMBT1N18D2","EDDAMBT1N18D3", & + "EDDAMBT1N18D4","EDDAMBT1N18D5","EDDAMBT1N18D6","EDDAMBT1N18D7","EDDAMBT1N18D8","EDDAMBT1N18D9", & + "EDDAMBT1N19D1","EDDAMBT1N19D2","EDDAMBT1N19D3","EDDAMBT1N19D4","EDDAMBT1N19D5","EDDAMBT1N19D6", & + "EDDAMBT1N19D7","EDDAMBT1N19D8","EDDAMBT1N19D9","EDDAMBT1N20D1","EDDAMBT1N20D2","EDDAMBT1N20D3", & + "EDDAMBT1N20D4","EDDAMBT1N20D5","EDDAMBT1N20D6","EDDAMBT1N20D7","EDDAMBT1N20D8","EDDAMBT1N20D9", & + "EDDAMBT2N01D1","EDDAMBT2N01D2","EDDAMBT2N01D3","EDDAMBT2N01D4","EDDAMBT2N01D5","EDDAMBT2N01D6", & + "EDDAMBT2N01D7","EDDAMBT2N01D8","EDDAMBT2N01D9","EDDAMBT2N02D1","EDDAMBT2N02D2","EDDAMBT2N02D3", & + "EDDAMBT2N02D4","EDDAMBT2N02D5","EDDAMBT2N02D6","EDDAMBT2N02D7","EDDAMBT2N02D8","EDDAMBT2N02D9", & + "EDDAMBT2N03D1","EDDAMBT2N03D2","EDDAMBT2N03D3","EDDAMBT2N03D4","EDDAMBT2N03D5","EDDAMBT2N03D6", & + "EDDAMBT2N03D7","EDDAMBT2N03D8","EDDAMBT2N03D9","EDDAMBT2N04D1","EDDAMBT2N04D2","EDDAMBT2N04D3", & + "EDDAMBT2N04D4","EDDAMBT2N04D5","EDDAMBT2N04D6","EDDAMBT2N04D7","EDDAMBT2N04D8","EDDAMBT2N04D9", & + "EDDAMBT2N05D1","EDDAMBT2N05D2","EDDAMBT2N05D3","EDDAMBT2N05D4","EDDAMBT2N05D5","EDDAMBT2N05D6", & + "EDDAMBT2N05D7","EDDAMBT2N05D8","EDDAMBT2N05D9","EDDAMBT2N06D1","EDDAMBT2N06D2","EDDAMBT2N06D3", & + "EDDAMBT2N06D4","EDDAMBT2N06D5","EDDAMBT2N06D6","EDDAMBT2N06D7","EDDAMBT2N06D8","EDDAMBT2N06D9", & + "EDDAMBT2N07D1","EDDAMBT2N07D2","EDDAMBT2N07D3","EDDAMBT2N07D4","EDDAMBT2N07D5","EDDAMBT2N07D6", & + "EDDAMBT2N07D7","EDDAMBT2N07D8","EDDAMBT2N07D9","EDDAMBT2N08D1","EDDAMBT2N08D2","EDDAMBT2N08D3", & + "EDDAMBT2N08D4","EDDAMBT2N08D5","EDDAMBT2N08D6","EDDAMBT2N08D7","EDDAMBT2N08D8","EDDAMBT2N08D9", & + "EDDAMBT2N09D1","EDDAMBT2N09D2","EDDAMBT2N09D3","EDDAMBT2N09D4","EDDAMBT2N09D5","EDDAMBT2N09D6", & + "EDDAMBT2N09D7","EDDAMBT2N09D8","EDDAMBT2N09D9","EDDAMBT2N10D1","EDDAMBT2N10D2","EDDAMBT2N10D3", & + "EDDAMBT2N10D4","EDDAMBT2N10D5","EDDAMBT2N10D6","EDDAMBT2N10D7","EDDAMBT2N10D8","EDDAMBT2N10D9", & + "EDDAMBT2N11D1","EDDAMBT2N11D2","EDDAMBT2N11D3","EDDAMBT2N11D4","EDDAMBT2N11D5","EDDAMBT2N11D6", & + "EDDAMBT2N11D7","EDDAMBT2N11D8","EDDAMBT2N11D9","EDDAMBT2N12D1","EDDAMBT2N12D2","EDDAMBT2N12D3", & + "EDDAMBT2N12D4","EDDAMBT2N12D5","EDDAMBT2N12D6","EDDAMBT2N12D7","EDDAMBT2N12D8","EDDAMBT2N12D9", & + "EDDAMBT2N13D1","EDDAMBT2N13D2","EDDAMBT2N13D3","EDDAMBT2N13D4","EDDAMBT2N13D5","EDDAMBT2N13D6", & + "EDDAMBT2N13D7","EDDAMBT2N13D8","EDDAMBT2N13D9","EDDAMBT2N14D1","EDDAMBT2N14D2","EDDAMBT2N14D3", & + "EDDAMBT2N14D4","EDDAMBT2N14D5","EDDAMBT2N14D6","EDDAMBT2N14D7","EDDAMBT2N14D8","EDDAMBT2N14D9", & + "EDDAMBT2N15D1","EDDAMBT2N15D2","EDDAMBT2N15D3","EDDAMBT2N15D4","EDDAMBT2N15D5","EDDAMBT2N15D6", & + "EDDAMBT2N15D7","EDDAMBT2N15D8","EDDAMBT2N15D9","EDDAMBT2N16D1","EDDAMBT2N16D2","EDDAMBT2N16D3", & + "EDDAMBT2N16D4","EDDAMBT2N16D5","EDDAMBT2N16D6","EDDAMBT2N16D7","EDDAMBT2N16D8","EDDAMBT2N16D9", & + "EDDAMBT2N17D1","EDDAMBT2N17D2","EDDAMBT2N17D3","EDDAMBT2N17D4","EDDAMBT2N17D5","EDDAMBT2N17D6", & + "EDDAMBT2N17D7","EDDAMBT2N17D8","EDDAMBT2N17D9","EDDAMBT2N18D1","EDDAMBT2N18D2","EDDAMBT2N18D3", & + "EDDAMBT2N18D4","EDDAMBT2N18D5","EDDAMBT2N18D6","EDDAMBT2N18D7","EDDAMBT2N18D8","EDDAMBT2N18D9", & + "EDDAMBT2N19D1","EDDAMBT2N19D2","EDDAMBT2N19D3","EDDAMBT2N19D4","EDDAMBT2N19D5","EDDAMBT2N19D6", & + "EDDAMBT2N19D7","EDDAMBT2N19D8","EDDAMBT2N19D9","EDDAMBT2N20D1","EDDAMBT2N20D2","EDDAMBT2N20D3", & + "EDDAMBT2N20D4","EDDAMBT2N20D5","EDDAMBT2N20D6","EDDAMBT2N20D7","EDDAMBT2N20D8","EDDAMBT2N20D9", & + "EDDAMBT3N01D1","EDDAMBT3N01D2","EDDAMBT3N01D3","EDDAMBT3N01D4","EDDAMBT3N01D5","EDDAMBT3N01D6", & + "EDDAMBT3N01D7","EDDAMBT3N01D8","EDDAMBT3N01D9","EDDAMBT3N02D1","EDDAMBT3N02D2","EDDAMBT3N02D3", & + "EDDAMBT3N02D4","EDDAMBT3N02D5","EDDAMBT3N02D6","EDDAMBT3N02D7","EDDAMBT3N02D8","EDDAMBT3N02D9", & + "EDDAMBT3N03D1","EDDAMBT3N03D2","EDDAMBT3N03D3","EDDAMBT3N03D4","EDDAMBT3N03D5","EDDAMBT3N03D6", & + "EDDAMBT3N03D7","EDDAMBT3N03D8","EDDAMBT3N03D9","EDDAMBT3N04D1","EDDAMBT3N04D2","EDDAMBT3N04D3", & + "EDDAMBT3N04D4","EDDAMBT3N04D5","EDDAMBT3N04D6","EDDAMBT3N04D7","EDDAMBT3N04D8","EDDAMBT3N04D9", & + "EDDAMBT3N05D1","EDDAMBT3N05D2","EDDAMBT3N05D3","EDDAMBT3N05D4","EDDAMBT3N05D5","EDDAMBT3N05D6", & + "EDDAMBT3N05D7","EDDAMBT3N05D8","EDDAMBT3N05D9","EDDAMBT3N06D1","EDDAMBT3N06D2","EDDAMBT3N06D3", & + "EDDAMBT3N06D4","EDDAMBT3N06D5","EDDAMBT3N06D6","EDDAMBT3N06D7","EDDAMBT3N06D8","EDDAMBT3N06D9", & + "EDDAMBT3N07D1","EDDAMBT3N07D2","EDDAMBT3N07D3","EDDAMBT3N07D4","EDDAMBT3N07D5","EDDAMBT3N07D6", & + "EDDAMBT3N07D7","EDDAMBT3N07D8","EDDAMBT3N07D9","EDDAMBT3N08D1","EDDAMBT3N08D2","EDDAMBT3N08D3", & + "EDDAMBT3N08D4","EDDAMBT3N08D5","EDDAMBT3N08D6","EDDAMBT3N08D7","EDDAMBT3N08D8","EDDAMBT3N08D9", & + "EDDAMBT3N09D1","EDDAMBT3N09D2","EDDAMBT3N09D3","EDDAMBT3N09D4","EDDAMBT3N09D5","EDDAMBT3N09D6", & + "EDDAMBT3N09D7","EDDAMBT3N09D8","EDDAMBT3N09D9","EDDAMBT3N10D1","EDDAMBT3N10D2","EDDAMBT3N10D3", & + "EDDAMBT3N10D4","EDDAMBT3N10D5","EDDAMBT3N10D6","EDDAMBT3N10D7","EDDAMBT3N10D8","EDDAMBT3N10D9", & + "EDDAMBT3N11D1","EDDAMBT3N11D2","EDDAMBT3N11D3","EDDAMBT3N11D4","EDDAMBT3N11D5","EDDAMBT3N11D6", & + "EDDAMBT3N11D7","EDDAMBT3N11D8","EDDAMBT3N11D9","EDDAMBT3N12D1","EDDAMBT3N12D2","EDDAMBT3N12D3", & + "EDDAMBT3N12D4","EDDAMBT3N12D5","EDDAMBT3N12D6","EDDAMBT3N12D7","EDDAMBT3N12D8","EDDAMBT3N12D9", & + "EDDAMBT3N13D1","EDDAMBT3N13D2","EDDAMBT3N13D3","EDDAMBT3N13D4","EDDAMBT3N13D5","EDDAMBT3N13D6", & + "EDDAMBT3N13D7","EDDAMBT3N13D8","EDDAMBT3N13D9","EDDAMBT3N14D1","EDDAMBT3N14D2","EDDAMBT3N14D3", & + "EDDAMBT3N14D4","EDDAMBT3N14D5","EDDAMBT3N14D6","EDDAMBT3N14D7","EDDAMBT3N14D8","EDDAMBT3N14D9", & + "EDDAMBT3N15D1","EDDAMBT3N15D2","EDDAMBT3N15D3","EDDAMBT3N15D4","EDDAMBT3N15D5","EDDAMBT3N15D6", & + "EDDAMBT3N15D7","EDDAMBT3N15D8","EDDAMBT3N15D9","EDDAMBT3N16D1","EDDAMBT3N16D2","EDDAMBT3N16D3", & + "EDDAMBT3N16D4","EDDAMBT3N16D5","EDDAMBT3N16D6","EDDAMBT3N16D7","EDDAMBT3N16D8","EDDAMBT3N16D9", & + "EDDAMBT3N17D1","EDDAMBT3N17D2","EDDAMBT3N17D3","EDDAMBT3N17D4","EDDAMBT3N17D5","EDDAMBT3N17D6", & + "EDDAMBT3N17D7","EDDAMBT3N17D8","EDDAMBT3N17D9","EDDAMBT3N18D1","EDDAMBT3N18D2","EDDAMBT3N18D3", & + "EDDAMBT3N18D4","EDDAMBT3N18D5","EDDAMBT3N18D6","EDDAMBT3N18D7","EDDAMBT3N18D8","EDDAMBT3N18D9", & + "EDDAMBT3N19D1","EDDAMBT3N19D2","EDDAMBT3N19D3","EDDAMBT3N19D4","EDDAMBT3N19D5","EDDAMBT3N19D6", & + "EDDAMBT3N19D7","EDDAMBT3N19D8","EDDAMBT3N19D9","EDDAMBT3N20D1","EDDAMBT3N20D2","EDDAMBT3N20D3", & + "EDDAMBT3N20D4","EDDAMBT3N20D5","EDDAMBT3N20D6","EDDAMBT3N20D7","EDDAMBT3N20D8","EDDAMBT3N20D9", & + "EDDAMBT4N01D1","EDDAMBT4N01D2","EDDAMBT4N01D3","EDDAMBT4N01D4","EDDAMBT4N01D5","EDDAMBT4N01D6", & + "EDDAMBT4N01D7","EDDAMBT4N01D8","EDDAMBT4N01D9","EDDAMBT4N02D1","EDDAMBT4N02D2","EDDAMBT4N02D3", & + "EDDAMBT4N02D4","EDDAMBT4N02D5","EDDAMBT4N02D6","EDDAMBT4N02D7","EDDAMBT4N02D8","EDDAMBT4N02D9", & + "EDDAMBT4N03D1","EDDAMBT4N03D2","EDDAMBT4N03D3","EDDAMBT4N03D4","EDDAMBT4N03D5","EDDAMBT4N03D6", & + "EDDAMBT4N03D7","EDDAMBT4N03D8","EDDAMBT4N03D9","EDDAMBT4N04D1","EDDAMBT4N04D2","EDDAMBT4N04D3", & + "EDDAMBT4N04D4","EDDAMBT4N04D5","EDDAMBT4N04D6","EDDAMBT4N04D7","EDDAMBT4N04D8","EDDAMBT4N04D9", & + "EDDAMBT4N05D1","EDDAMBT4N05D2","EDDAMBT4N05D3","EDDAMBT4N05D4","EDDAMBT4N05D5","EDDAMBT4N05D6", & + "EDDAMBT4N05D7","EDDAMBT4N05D8","EDDAMBT4N05D9","EDDAMBT4N06D1","EDDAMBT4N06D2","EDDAMBT4N06D3", & + "EDDAMBT4N06D4","EDDAMBT4N06D5","EDDAMBT4N06D6","EDDAMBT4N06D7","EDDAMBT4N06D8","EDDAMBT4N06D9", & + "EDDAMBT4N07D1","EDDAMBT4N07D2","EDDAMBT4N07D3","EDDAMBT4N07D4","EDDAMBT4N07D5","EDDAMBT4N07D6", & + "EDDAMBT4N07D7","EDDAMBT4N07D8","EDDAMBT4N07D9","EDDAMBT4N08D1","EDDAMBT4N08D2","EDDAMBT4N08D3", & + "EDDAMBT4N08D4","EDDAMBT4N08D5","EDDAMBT4N08D6","EDDAMBT4N08D7","EDDAMBT4N08D8","EDDAMBT4N08D9", & + "EDDAMBT4N09D1","EDDAMBT4N09D2","EDDAMBT4N09D3","EDDAMBT4N09D4","EDDAMBT4N09D5","EDDAMBT4N09D6", & + "EDDAMBT4N09D7","EDDAMBT4N09D8","EDDAMBT4N09D9","EDDAMBT4N10D1","EDDAMBT4N10D2","EDDAMBT4N10D3", & + "EDDAMBT4N10D4","EDDAMBT4N10D5","EDDAMBT4N10D6","EDDAMBT4N10D7","EDDAMBT4N10D8","EDDAMBT4N10D9", & + "EDDAMBT4N11D1","EDDAMBT4N11D2","EDDAMBT4N11D3","EDDAMBT4N11D4","EDDAMBT4N11D5","EDDAMBT4N11D6", & + "EDDAMBT4N11D7","EDDAMBT4N11D8","EDDAMBT4N11D9","EDDAMBT4N12D1","EDDAMBT4N12D2","EDDAMBT4N12D3", & + "EDDAMBT4N12D4","EDDAMBT4N12D5","EDDAMBT4N12D6","EDDAMBT4N12D7","EDDAMBT4N12D8","EDDAMBT4N12D9", & + "EDDAMBT4N13D1","EDDAMBT4N13D2","EDDAMBT4N13D3","EDDAMBT4N13D4","EDDAMBT4N13D5","EDDAMBT4N13D6", & + "EDDAMBT4N13D7","EDDAMBT4N13D8","EDDAMBT4N13D9","EDDAMBT4N14D1","EDDAMBT4N14D2","EDDAMBT4N14D3", & + "EDDAMBT4N14D4","EDDAMBT4N14D5","EDDAMBT4N14D6","EDDAMBT4N14D7","EDDAMBT4N14D8","EDDAMBT4N14D9", & + "EDDAMBT4N15D1","EDDAMBT4N15D2","EDDAMBT4N15D3","EDDAMBT4N15D4","EDDAMBT4N15D5","EDDAMBT4N15D6", & + "EDDAMBT4N15D7","EDDAMBT4N15D8","EDDAMBT4N15D9","EDDAMBT4N16D1","EDDAMBT4N16D2","EDDAMBT4N16D3", & + "EDDAMBT4N16D4","EDDAMBT4N16D5","EDDAMBT4N16D6","EDDAMBT4N16D7","EDDAMBT4N16D8","EDDAMBT4N16D9", & + "EDDAMBT4N17D1","EDDAMBT4N17D2","EDDAMBT4N17D3","EDDAMBT4N17D4","EDDAMBT4N17D5","EDDAMBT4N17D6", & + "EDDAMBT4N17D7","EDDAMBT4N17D8","EDDAMBT4N17D9","EDDAMBT4N18D1","EDDAMBT4N18D2","EDDAMBT4N18D3", & + "EDDAMBT4N18D4","EDDAMBT4N18D5","EDDAMBT4N18D6","EDDAMBT4N18D7","EDDAMBT4N18D8","EDDAMBT4N18D9", & + "EDDAMBT4N19D1","EDDAMBT4N19D2","EDDAMBT4N19D3","EDDAMBT4N19D4","EDDAMBT4N19D5","EDDAMBT4N19D6", & + "EDDAMBT4N19D7","EDDAMBT4N19D8","EDDAMBT4N19D9","EDDAMBT4N20D1","EDDAMBT4N20D2","EDDAMBT4N20D3", & + "EDDAMBT4N20D4","EDDAMBT4N20D5","EDDAMBT4N20D6","EDDAMBT4N20D7","EDDAMBT4N20D8","EDDAMBT4N20D9", & + "EDDAMBT5N01D1","EDDAMBT5N01D2","EDDAMBT5N01D3","EDDAMBT5N01D4","EDDAMBT5N01D5","EDDAMBT5N01D6", & + "EDDAMBT5N01D7","EDDAMBT5N01D8","EDDAMBT5N01D9","EDDAMBT5N02D1","EDDAMBT5N02D2","EDDAMBT5N02D3", & + "EDDAMBT5N02D4","EDDAMBT5N02D5","EDDAMBT5N02D6","EDDAMBT5N02D7","EDDAMBT5N02D8","EDDAMBT5N02D9", & + "EDDAMBT5N03D1","EDDAMBT5N03D2","EDDAMBT5N03D3","EDDAMBT5N03D4","EDDAMBT5N03D5","EDDAMBT5N03D6", & + "EDDAMBT5N03D7","EDDAMBT5N03D8","EDDAMBT5N03D9","EDDAMBT5N04D1","EDDAMBT5N04D2","EDDAMBT5N04D3", & + "EDDAMBT5N04D4","EDDAMBT5N04D5","EDDAMBT5N04D6","EDDAMBT5N04D7","EDDAMBT5N04D8","EDDAMBT5N04D9", & + "EDDAMBT5N05D1","EDDAMBT5N05D2","EDDAMBT5N05D3","EDDAMBT5N05D4","EDDAMBT5N05D5","EDDAMBT5N05D6", & + "EDDAMBT5N05D7","EDDAMBT5N05D8","EDDAMBT5N05D9","EDDAMBT5N06D1","EDDAMBT5N06D2","EDDAMBT5N06D3", & + "EDDAMBT5N06D4","EDDAMBT5N06D5","EDDAMBT5N06D6","EDDAMBT5N06D7","EDDAMBT5N06D8","EDDAMBT5N06D9", & + "EDDAMBT5N07D1","EDDAMBT5N07D2","EDDAMBT5N07D3","EDDAMBT5N07D4","EDDAMBT5N07D5","EDDAMBT5N07D6", & + "EDDAMBT5N07D7","EDDAMBT5N07D8","EDDAMBT5N07D9","EDDAMBT5N08D1","EDDAMBT5N08D2","EDDAMBT5N08D3", & + "EDDAMBT5N08D4","EDDAMBT5N08D5","EDDAMBT5N08D6","EDDAMBT5N08D7","EDDAMBT5N08D8","EDDAMBT5N08D9", & + "EDDAMBT5N09D1","EDDAMBT5N09D2","EDDAMBT5N09D3","EDDAMBT5N09D4","EDDAMBT5N09D5","EDDAMBT5N09D6", & + "EDDAMBT5N09D7","EDDAMBT5N09D8","EDDAMBT5N09D9","EDDAMBT5N10D1","EDDAMBT5N10D2","EDDAMBT5N10D3", & + "EDDAMBT5N10D4","EDDAMBT5N10D5","EDDAMBT5N10D6","EDDAMBT5N10D7","EDDAMBT5N10D8","EDDAMBT5N10D9", & + "EDDAMBT5N11D1","EDDAMBT5N11D2","EDDAMBT5N11D3","EDDAMBT5N11D4","EDDAMBT5N11D5","EDDAMBT5N11D6", & + "EDDAMBT5N11D7","EDDAMBT5N11D8","EDDAMBT5N11D9","EDDAMBT5N12D1","EDDAMBT5N12D2","EDDAMBT5N12D3", & + "EDDAMBT5N12D4","EDDAMBT5N12D5","EDDAMBT5N12D6","EDDAMBT5N12D7","EDDAMBT5N12D8","EDDAMBT5N12D9", & + "EDDAMBT5N13D1","EDDAMBT5N13D2","EDDAMBT5N13D3","EDDAMBT5N13D4","EDDAMBT5N13D5","EDDAMBT5N13D6", & + "EDDAMBT5N13D7","EDDAMBT5N13D8","EDDAMBT5N13D9","EDDAMBT5N14D1","EDDAMBT5N14D2","EDDAMBT5N14D3", & + "EDDAMBT5N14D4","EDDAMBT5N14D5","EDDAMBT5N14D6","EDDAMBT5N14D7","EDDAMBT5N14D8","EDDAMBT5N14D9", & + "EDDAMBT5N15D1","EDDAMBT5N15D2","EDDAMBT5N15D3","EDDAMBT5N15D4","EDDAMBT5N15D5","EDDAMBT5N15D6", & + "EDDAMBT5N15D7","EDDAMBT5N15D8","EDDAMBT5N15D9","EDDAMBT5N16D1","EDDAMBT5N16D2","EDDAMBT5N16D3", & + "EDDAMBT5N16D4","EDDAMBT5N16D5","EDDAMBT5N16D6","EDDAMBT5N16D7","EDDAMBT5N16D8","EDDAMBT5N16D9", & + "EDDAMBT5N17D1","EDDAMBT5N17D2","EDDAMBT5N17D3","EDDAMBT5N17D4","EDDAMBT5N17D5","EDDAMBT5N17D6", & + "EDDAMBT5N17D7","EDDAMBT5N17D8","EDDAMBT5N17D9","EDDAMBT5N18D1","EDDAMBT5N18D2","EDDAMBT5N18D3", & + "EDDAMBT5N18D4","EDDAMBT5N18D5","EDDAMBT5N18D6","EDDAMBT5N18D7","EDDAMBT5N18D8","EDDAMBT5N18D9", & + "EDDAMBT5N19D1","EDDAMBT5N19D2","EDDAMBT5N19D3","EDDAMBT5N19D4","EDDAMBT5N19D5","EDDAMBT5N19D6", & + "EDDAMBT5N19D7","EDDAMBT5N19D8","EDDAMBT5N19D9","EDDAMBT5N20D1","EDDAMBT5N20D2","EDDAMBT5N20D3", & + "EDDAMBT5N20D4","EDDAMBT5N20D5","EDDAMBT5N20D6","EDDAMBT5N20D7","EDDAMBT5N20D8","EDDAMBT5N20D9", & + "EDDAMBT6N01D1","EDDAMBT6N01D2","EDDAMBT6N01D3","EDDAMBT6N01D4","EDDAMBT6N01D5","EDDAMBT6N01D6", & + "EDDAMBT6N01D7","EDDAMBT6N01D8","EDDAMBT6N01D9","EDDAMBT6N02D1","EDDAMBT6N02D2","EDDAMBT6N02D3", & + "EDDAMBT6N02D4","EDDAMBT6N02D5","EDDAMBT6N02D6","EDDAMBT6N02D7","EDDAMBT6N02D8","EDDAMBT6N02D9", & + "EDDAMBT6N03D1","EDDAMBT6N03D2","EDDAMBT6N03D3","EDDAMBT6N03D4","EDDAMBT6N03D5","EDDAMBT6N03D6", & + "EDDAMBT6N03D7","EDDAMBT6N03D8","EDDAMBT6N03D9","EDDAMBT6N04D1","EDDAMBT6N04D2","EDDAMBT6N04D3", & + "EDDAMBT6N04D4","EDDAMBT6N04D5","EDDAMBT6N04D6","EDDAMBT6N04D7","EDDAMBT6N04D8","EDDAMBT6N04D9", & + "EDDAMBT6N05D1","EDDAMBT6N05D2","EDDAMBT6N05D3","EDDAMBT6N05D4","EDDAMBT6N05D5","EDDAMBT6N05D6", & + "EDDAMBT6N05D7","EDDAMBT6N05D8","EDDAMBT6N05D9","EDDAMBT6N06D1","EDDAMBT6N06D2","EDDAMBT6N06D3", & + "EDDAMBT6N06D4","EDDAMBT6N06D5","EDDAMBT6N06D6","EDDAMBT6N06D7","EDDAMBT6N06D8","EDDAMBT6N06D9", & + "EDDAMBT6N07D1","EDDAMBT6N07D2","EDDAMBT6N07D3","EDDAMBT6N07D4","EDDAMBT6N07D5","EDDAMBT6N07D6", & + "EDDAMBT6N07D7","EDDAMBT6N07D8","EDDAMBT6N07D9","EDDAMBT6N08D1","EDDAMBT6N08D2","EDDAMBT6N08D3", & + "EDDAMBT6N08D4","EDDAMBT6N08D5","EDDAMBT6N08D6","EDDAMBT6N08D7","EDDAMBT6N08D8","EDDAMBT6N08D9", & + "EDDAMBT6N09D1","EDDAMBT6N09D2","EDDAMBT6N09D3","EDDAMBT6N09D4","EDDAMBT6N09D5","EDDAMBT6N09D6", & + "EDDAMBT6N09D7","EDDAMBT6N09D8","EDDAMBT6N09D9","EDDAMBT6N10D1","EDDAMBT6N10D2","EDDAMBT6N10D3", & + "EDDAMBT6N10D4","EDDAMBT6N10D5","EDDAMBT6N10D6","EDDAMBT6N10D7","EDDAMBT6N10D8","EDDAMBT6N10D9", & + "EDDAMBT6N11D1","EDDAMBT6N11D2","EDDAMBT6N11D3","EDDAMBT6N11D4","EDDAMBT6N11D5","EDDAMBT6N11D6", & + "EDDAMBT6N11D7","EDDAMBT6N11D8","EDDAMBT6N11D9","EDDAMBT6N12D1","EDDAMBT6N12D2","EDDAMBT6N12D3", & + "EDDAMBT6N12D4","EDDAMBT6N12D5","EDDAMBT6N12D6","EDDAMBT6N12D7","EDDAMBT6N12D8","EDDAMBT6N12D9", & + "EDDAMBT6N13D1","EDDAMBT6N13D2","EDDAMBT6N13D3","EDDAMBT6N13D4","EDDAMBT6N13D5","EDDAMBT6N13D6", & + "EDDAMBT6N13D7","EDDAMBT6N13D8","EDDAMBT6N13D9","EDDAMBT6N14D1","EDDAMBT6N14D2","EDDAMBT6N14D3", & + "EDDAMBT6N14D4","EDDAMBT6N14D5","EDDAMBT6N14D6","EDDAMBT6N14D7","EDDAMBT6N14D8","EDDAMBT6N14D9", & + "EDDAMBT6N15D1","EDDAMBT6N15D2","EDDAMBT6N15D3","EDDAMBT6N15D4","EDDAMBT6N15D5","EDDAMBT6N15D6", & + "EDDAMBT6N15D7","EDDAMBT6N15D8","EDDAMBT6N15D9","EDDAMBT6N16D1","EDDAMBT6N16D2","EDDAMBT6N16D3", & + "EDDAMBT6N16D4","EDDAMBT6N16D5","EDDAMBT6N16D6","EDDAMBT6N16D7","EDDAMBT6N16D8","EDDAMBT6N16D9", & + "EDDAMBT6N17D1","EDDAMBT6N17D2","EDDAMBT6N17D3","EDDAMBT6N17D4","EDDAMBT6N17D5","EDDAMBT6N17D6", & + "EDDAMBT6N17D7","EDDAMBT6N17D8","EDDAMBT6N17D9","EDDAMBT6N18D1","EDDAMBT6N18D2","EDDAMBT6N18D3", & + "EDDAMBT6N18D4","EDDAMBT6N18D5","EDDAMBT6N18D6","EDDAMBT6N18D7","EDDAMBT6N18D8","EDDAMBT6N18D9", & + "EDDAMBT6N19D1","EDDAMBT6N19D2","EDDAMBT6N19D3","EDDAMBT6N19D4","EDDAMBT6N19D5","EDDAMBT6N19D6", & + "EDDAMBT6N19D7","EDDAMBT6N19D8","EDDAMBT6N19D9","EDDAMBT6N20D1","EDDAMBT6N20D2","EDDAMBT6N20D3", & + "EDDAMBT6N20D4","EDDAMBT6N20D5","EDDAMBT6N20D6","EDDAMBT6N20D7","EDDAMBT6N20D8","EDDAMBT6N20D9", & + "EDDAMBT7N01D1","EDDAMBT7N01D2","EDDAMBT7N01D3","EDDAMBT7N01D4","EDDAMBT7N01D5","EDDAMBT7N01D6", & + "EDDAMBT7N01D7","EDDAMBT7N01D8","EDDAMBT7N01D9","EDDAMBT7N02D1","EDDAMBT7N02D2","EDDAMBT7N02D3", & + "EDDAMBT7N02D4","EDDAMBT7N02D5","EDDAMBT7N02D6","EDDAMBT7N02D7","EDDAMBT7N02D8","EDDAMBT7N02D9", & + "EDDAMBT7N03D1","EDDAMBT7N03D2","EDDAMBT7N03D3","EDDAMBT7N03D4","EDDAMBT7N03D5","EDDAMBT7N03D6", & + "EDDAMBT7N03D7","EDDAMBT7N03D8","EDDAMBT7N03D9","EDDAMBT7N04D1","EDDAMBT7N04D2","EDDAMBT7N04D3", & + "EDDAMBT7N04D4","EDDAMBT7N04D5","EDDAMBT7N04D6","EDDAMBT7N04D7","EDDAMBT7N04D8","EDDAMBT7N04D9", & + "EDDAMBT7N05D1","EDDAMBT7N05D2","EDDAMBT7N05D3","EDDAMBT7N05D4","EDDAMBT7N05D5","EDDAMBT7N05D6", & + "EDDAMBT7N05D7","EDDAMBT7N05D8","EDDAMBT7N05D9","EDDAMBT7N06D1","EDDAMBT7N06D2","EDDAMBT7N06D3", & + "EDDAMBT7N06D4","EDDAMBT7N06D5","EDDAMBT7N06D6","EDDAMBT7N06D7","EDDAMBT7N06D8","EDDAMBT7N06D9", & + "EDDAMBT7N07D1","EDDAMBT7N07D2","EDDAMBT7N07D3","EDDAMBT7N07D4","EDDAMBT7N07D5","EDDAMBT7N07D6", & + "EDDAMBT7N07D7","EDDAMBT7N07D8","EDDAMBT7N07D9","EDDAMBT7N08D1","EDDAMBT7N08D2","EDDAMBT7N08D3", & + "EDDAMBT7N08D4","EDDAMBT7N08D5","EDDAMBT7N08D6","EDDAMBT7N08D7","EDDAMBT7N08D8","EDDAMBT7N08D9", & + "EDDAMBT7N09D1","EDDAMBT7N09D2","EDDAMBT7N09D3","EDDAMBT7N09D4","EDDAMBT7N09D5","EDDAMBT7N09D6"/) + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry2(1356) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "EDDAMBT7N09D7","EDDAMBT7N09D8","EDDAMBT7N09D9","EDDAMBT7N10D1","EDDAMBT7N10D2","EDDAMBT7N10D3", & + "EDDAMBT7N10D4","EDDAMBT7N10D5","EDDAMBT7N10D6","EDDAMBT7N10D7","EDDAMBT7N10D8","EDDAMBT7N10D9", & + "EDDAMBT7N11D1","EDDAMBT7N11D2","EDDAMBT7N11D3","EDDAMBT7N11D4","EDDAMBT7N11D5","EDDAMBT7N11D6", & + "EDDAMBT7N11D7","EDDAMBT7N11D8","EDDAMBT7N11D9","EDDAMBT7N12D1","EDDAMBT7N12D2","EDDAMBT7N12D3", & + "EDDAMBT7N12D4","EDDAMBT7N12D5","EDDAMBT7N12D6","EDDAMBT7N12D7","EDDAMBT7N12D8","EDDAMBT7N12D9", & + "EDDAMBT7N13D1","EDDAMBT7N13D2","EDDAMBT7N13D3","EDDAMBT7N13D4","EDDAMBT7N13D5","EDDAMBT7N13D6", & + "EDDAMBT7N13D7","EDDAMBT7N13D8","EDDAMBT7N13D9","EDDAMBT7N14D1","EDDAMBT7N14D2","EDDAMBT7N14D3", & + "EDDAMBT7N14D4","EDDAMBT7N14D5","EDDAMBT7N14D6","EDDAMBT7N14D7","EDDAMBT7N14D8","EDDAMBT7N14D9", & + "EDDAMBT7N15D1","EDDAMBT7N15D2","EDDAMBT7N15D3","EDDAMBT7N15D4","EDDAMBT7N15D5","EDDAMBT7N15D6", & + "EDDAMBT7N15D7","EDDAMBT7N15D8","EDDAMBT7N15D9","EDDAMBT7N16D1","EDDAMBT7N16D2","EDDAMBT7N16D3", & + "EDDAMBT7N16D4","EDDAMBT7N16D5","EDDAMBT7N16D6","EDDAMBT7N16D7","EDDAMBT7N16D8","EDDAMBT7N16D9", & + "EDDAMBT7N17D1","EDDAMBT7N17D2","EDDAMBT7N17D3","EDDAMBT7N17D4","EDDAMBT7N17D5","EDDAMBT7N17D6", & + "EDDAMBT7N17D7","EDDAMBT7N17D8","EDDAMBT7N17D9","EDDAMBT7N18D1","EDDAMBT7N18D2","EDDAMBT7N18D3", & + "EDDAMBT7N18D4","EDDAMBT7N18D5","EDDAMBT7N18D6","EDDAMBT7N18D7","EDDAMBT7N18D8","EDDAMBT7N18D9", & + "EDDAMBT7N19D1","EDDAMBT7N19D2","EDDAMBT7N19D3","EDDAMBT7N19D4","EDDAMBT7N19D5","EDDAMBT7N19D6", & + "EDDAMBT7N19D7","EDDAMBT7N19D8","EDDAMBT7N19D9","EDDAMBT7N20D1","EDDAMBT7N20D2","EDDAMBT7N20D3", & + "EDDAMBT7N20D4","EDDAMBT7N20D5","EDDAMBT7N20D6","EDDAMBT7N20D7","EDDAMBT7N20D8","EDDAMBT7N20D9", & + "EDDAMBT8N01D1","EDDAMBT8N01D2","EDDAMBT8N01D3","EDDAMBT8N01D4","EDDAMBT8N01D5","EDDAMBT8N01D6", & + "EDDAMBT8N01D7","EDDAMBT8N01D8","EDDAMBT8N01D9","EDDAMBT8N02D1","EDDAMBT8N02D2","EDDAMBT8N02D3", & + "EDDAMBT8N02D4","EDDAMBT8N02D5","EDDAMBT8N02D6","EDDAMBT8N02D7","EDDAMBT8N02D8","EDDAMBT8N02D9", & + "EDDAMBT8N03D1","EDDAMBT8N03D2","EDDAMBT8N03D3","EDDAMBT8N03D4","EDDAMBT8N03D5","EDDAMBT8N03D6", & + "EDDAMBT8N03D7","EDDAMBT8N03D8","EDDAMBT8N03D9","EDDAMBT8N04D1","EDDAMBT8N04D2","EDDAMBT8N04D3", & + "EDDAMBT8N04D4","EDDAMBT8N04D5","EDDAMBT8N04D6","EDDAMBT8N04D7","EDDAMBT8N04D8","EDDAMBT8N04D9", & + "EDDAMBT8N05D1","EDDAMBT8N05D2","EDDAMBT8N05D3","EDDAMBT8N05D4","EDDAMBT8N05D5","EDDAMBT8N05D6", & + "EDDAMBT8N05D7","EDDAMBT8N05D8","EDDAMBT8N05D9","EDDAMBT8N06D1","EDDAMBT8N06D2","EDDAMBT8N06D3", & + "EDDAMBT8N06D4","EDDAMBT8N06D5","EDDAMBT8N06D6","EDDAMBT8N06D7","EDDAMBT8N06D8","EDDAMBT8N06D9", & + "EDDAMBT8N07D1","EDDAMBT8N07D2","EDDAMBT8N07D3","EDDAMBT8N07D4","EDDAMBT8N07D5","EDDAMBT8N07D6", & + "EDDAMBT8N07D7","EDDAMBT8N07D8","EDDAMBT8N07D9","EDDAMBT8N08D1","EDDAMBT8N08D2","EDDAMBT8N08D3", & + "EDDAMBT8N08D4","EDDAMBT8N08D5","EDDAMBT8N08D6","EDDAMBT8N08D7","EDDAMBT8N08D8","EDDAMBT8N08D9", & + "EDDAMBT8N09D1","EDDAMBT8N09D2","EDDAMBT8N09D3","EDDAMBT8N09D4","EDDAMBT8N09D5","EDDAMBT8N09D6", & + "EDDAMBT8N09D7","EDDAMBT8N09D8","EDDAMBT8N09D9","EDDAMBT8N10D1","EDDAMBT8N10D2","EDDAMBT8N10D3", & + "EDDAMBT8N10D4","EDDAMBT8N10D5","EDDAMBT8N10D6","EDDAMBT8N10D7","EDDAMBT8N10D8","EDDAMBT8N10D9", & + "EDDAMBT8N11D1","EDDAMBT8N11D2","EDDAMBT8N11D3","EDDAMBT8N11D4","EDDAMBT8N11D5","EDDAMBT8N11D6", & + "EDDAMBT8N11D7","EDDAMBT8N11D8","EDDAMBT8N11D9","EDDAMBT8N12D1","EDDAMBT8N12D2","EDDAMBT8N12D3", & + "EDDAMBT8N12D4","EDDAMBT8N12D5","EDDAMBT8N12D6","EDDAMBT8N12D7","EDDAMBT8N12D8","EDDAMBT8N12D9", & + "EDDAMBT8N13D1","EDDAMBT8N13D2","EDDAMBT8N13D3","EDDAMBT8N13D4","EDDAMBT8N13D5","EDDAMBT8N13D6", & + "EDDAMBT8N13D7","EDDAMBT8N13D8","EDDAMBT8N13D9","EDDAMBT8N14D1","EDDAMBT8N14D2","EDDAMBT8N14D3", & + "EDDAMBT8N14D4","EDDAMBT8N14D5","EDDAMBT8N14D6","EDDAMBT8N14D7","EDDAMBT8N14D8","EDDAMBT8N14D9", & + "EDDAMBT8N15D1","EDDAMBT8N15D2","EDDAMBT8N15D3","EDDAMBT8N15D4","EDDAMBT8N15D5","EDDAMBT8N15D6", & + "EDDAMBT8N15D7","EDDAMBT8N15D8","EDDAMBT8N15D9","EDDAMBT8N16D1","EDDAMBT8N16D2","EDDAMBT8N16D3", & + "EDDAMBT8N16D4","EDDAMBT8N16D5","EDDAMBT8N16D6","EDDAMBT8N16D7","EDDAMBT8N16D8","EDDAMBT8N16D9", & + "EDDAMBT8N17D1","EDDAMBT8N17D2","EDDAMBT8N17D3","EDDAMBT8N17D4","EDDAMBT8N17D5","EDDAMBT8N17D6", & + "EDDAMBT8N17D7","EDDAMBT8N17D8","EDDAMBT8N17D9","EDDAMBT8N18D1","EDDAMBT8N18D2","EDDAMBT8N18D3", & + "EDDAMBT8N18D4","EDDAMBT8N18D5","EDDAMBT8N18D6","EDDAMBT8N18D7","EDDAMBT8N18D8","EDDAMBT8N18D9", & + "EDDAMBT8N19D1","EDDAMBT8N19D2","EDDAMBT8N19D3","EDDAMBT8N19D4","EDDAMBT8N19D5","EDDAMBT8N19D6", & + "EDDAMBT8N19D7","EDDAMBT8N19D8","EDDAMBT8N19D9","EDDAMBT8N20D1","EDDAMBT8N20D2","EDDAMBT8N20D3", & + "EDDAMBT8N20D4","EDDAMBT8N20D5","EDDAMBT8N20D6","EDDAMBT8N20D7","EDDAMBT8N20D8","EDDAMBT8N20D9", & + "EDDAMBT9N01D1","EDDAMBT9N01D2","EDDAMBT9N01D3","EDDAMBT9N01D4","EDDAMBT9N01D5","EDDAMBT9N01D6", & + "EDDAMBT9N01D7","EDDAMBT9N01D8","EDDAMBT9N01D9","EDDAMBT9N02D1","EDDAMBT9N02D2","EDDAMBT9N02D3", & + "EDDAMBT9N02D4","EDDAMBT9N02D5","EDDAMBT9N02D6","EDDAMBT9N02D7","EDDAMBT9N02D8","EDDAMBT9N02D9", & + "EDDAMBT9N03D1","EDDAMBT9N03D2","EDDAMBT9N03D3","EDDAMBT9N03D4","EDDAMBT9N03D5","EDDAMBT9N03D6", & + "EDDAMBT9N03D7","EDDAMBT9N03D8","EDDAMBT9N03D9","EDDAMBT9N04D1","EDDAMBT9N04D2","EDDAMBT9N04D3", & + "EDDAMBT9N04D4","EDDAMBT9N04D5","EDDAMBT9N04D6","EDDAMBT9N04D7","EDDAMBT9N04D8","EDDAMBT9N04D9", & + "EDDAMBT9N05D1","EDDAMBT9N05D2","EDDAMBT9N05D3","EDDAMBT9N05D4","EDDAMBT9N05D5","EDDAMBT9N05D6", & + "EDDAMBT9N05D7","EDDAMBT9N05D8","EDDAMBT9N05D9","EDDAMBT9N06D1","EDDAMBT9N06D2","EDDAMBT9N06D3", & + "EDDAMBT9N06D4","EDDAMBT9N06D5","EDDAMBT9N06D6","EDDAMBT9N06D7","EDDAMBT9N06D8","EDDAMBT9N06D9", & + "EDDAMBT9N07D1","EDDAMBT9N07D2","EDDAMBT9N07D3","EDDAMBT9N07D4","EDDAMBT9N07D5","EDDAMBT9N07D6", & + "EDDAMBT9N07D7","EDDAMBT9N07D8","EDDAMBT9N07D9","EDDAMBT9N08D1","EDDAMBT9N08D2","EDDAMBT9N08D3", & + "EDDAMBT9N08D4","EDDAMBT9N08D5","EDDAMBT9N08D6","EDDAMBT9N08D7","EDDAMBT9N08D8","EDDAMBT9N08D9", & + "EDDAMBT9N09D1","EDDAMBT9N09D2","EDDAMBT9N09D3","EDDAMBT9N09D4","EDDAMBT9N09D5","EDDAMBT9N09D6", & + "EDDAMBT9N09D7","EDDAMBT9N09D8","EDDAMBT9N09D9","EDDAMBT9N10D1","EDDAMBT9N10D2","EDDAMBT9N10D3", & + "EDDAMBT9N10D4","EDDAMBT9N10D5","EDDAMBT9N10D6","EDDAMBT9N10D7","EDDAMBT9N10D8","EDDAMBT9N10D9", & + "EDDAMBT9N11D1","EDDAMBT9N11D2","EDDAMBT9N11D3","EDDAMBT9N11D4","EDDAMBT9N11D5","EDDAMBT9N11D6", & + "EDDAMBT9N11D7","EDDAMBT9N11D8","EDDAMBT9N11D9","EDDAMBT9N12D1","EDDAMBT9N12D2","EDDAMBT9N12D3", & + "EDDAMBT9N12D4","EDDAMBT9N12D5","EDDAMBT9N12D6","EDDAMBT9N12D7","EDDAMBT9N12D8","EDDAMBT9N12D9", & + "EDDAMBT9N13D1","EDDAMBT9N13D2","EDDAMBT9N13D3","EDDAMBT9N13D4","EDDAMBT9N13D5","EDDAMBT9N13D6", & + "EDDAMBT9N13D7","EDDAMBT9N13D8","EDDAMBT9N13D9","EDDAMBT9N14D1","EDDAMBT9N14D2","EDDAMBT9N14D3", & + "EDDAMBT9N14D4","EDDAMBT9N14D5","EDDAMBT9N14D6","EDDAMBT9N14D7","EDDAMBT9N14D8","EDDAMBT9N14D9", & + "EDDAMBT9N15D1","EDDAMBT9N15D2","EDDAMBT9N15D3","EDDAMBT9N15D4","EDDAMBT9N15D5","EDDAMBT9N15D6", & + "EDDAMBT9N15D7","EDDAMBT9N15D8","EDDAMBT9N15D9","EDDAMBT9N16D1","EDDAMBT9N16D2","EDDAMBT9N16D3", & + "EDDAMBT9N16D4","EDDAMBT9N16D5","EDDAMBT9N16D6","EDDAMBT9N16D7","EDDAMBT9N16D8","EDDAMBT9N16D9", & + "EDDAMBT9N17D1","EDDAMBT9N17D2","EDDAMBT9N17D3","EDDAMBT9N17D4","EDDAMBT9N17D5","EDDAMBT9N17D6", & + "EDDAMBT9N17D7","EDDAMBT9N17D8","EDDAMBT9N17D9","EDDAMBT9N18D1","EDDAMBT9N18D2","EDDAMBT9N18D3", & + "EDDAMBT9N18D4","EDDAMBT9N18D5","EDDAMBT9N18D6","EDDAMBT9N18D7","EDDAMBT9N18D8","EDDAMBT9N18D9", & + "EDDAMBT9N19D1","EDDAMBT9N19D2","EDDAMBT9N19D3","EDDAMBT9N19D4","EDDAMBT9N19D5","EDDAMBT9N19D6", & + "EDDAMBT9N19D7","EDDAMBT9N19D8","EDDAMBT9N19D9","EDDAMBT9N20D1","EDDAMBT9N20D2","EDDAMBT9N20D3", & + "EDDAMBT9N20D4","EDDAMBT9N20D5","EDDAMBT9N20D6","EDDAMBT9N20D7","EDDAMBT9N20D8","EDDAMBT9N20D9", & + "EDDSHRT1N01D1","EDDSHRT1N01D2","EDDSHRT1N01D3","EDDSHRT1N01D4","EDDSHRT1N01D5","EDDSHRT1N01D6", & + "EDDSHRT1N01D7","EDDSHRT1N01D8","EDDSHRT1N01D9","EDDSHRT1N02D1","EDDSHRT1N02D2","EDDSHRT1N02D3", & + "EDDSHRT1N02D4","EDDSHRT1N02D5","EDDSHRT1N02D6","EDDSHRT1N02D7","EDDSHRT1N02D8","EDDSHRT1N02D9", & + "EDDSHRT1N03D1","EDDSHRT1N03D2","EDDSHRT1N03D3","EDDSHRT1N03D4","EDDSHRT1N03D5","EDDSHRT1N03D6", & + "EDDSHRT1N03D7","EDDSHRT1N03D8","EDDSHRT1N03D9","EDDSHRT1N04D1","EDDSHRT1N04D2","EDDSHRT1N04D3", & + "EDDSHRT1N04D4","EDDSHRT1N04D5","EDDSHRT1N04D6","EDDSHRT1N04D7","EDDSHRT1N04D8","EDDSHRT1N04D9", & + "EDDSHRT1N05D1","EDDSHRT1N05D2","EDDSHRT1N05D3","EDDSHRT1N05D4","EDDSHRT1N05D5","EDDSHRT1N05D6", & + "EDDSHRT1N05D7","EDDSHRT1N05D8","EDDSHRT1N05D9","EDDSHRT1N06D1","EDDSHRT1N06D2","EDDSHRT1N06D3", & + "EDDSHRT1N06D4","EDDSHRT1N06D5","EDDSHRT1N06D6","EDDSHRT1N06D7","EDDSHRT1N06D8","EDDSHRT1N06D9", & + "EDDSHRT1N07D1","EDDSHRT1N07D2","EDDSHRT1N07D3","EDDSHRT1N07D4","EDDSHRT1N07D5","EDDSHRT1N07D6", & + "EDDSHRT1N07D7","EDDSHRT1N07D8","EDDSHRT1N07D9","EDDSHRT1N08D1","EDDSHRT1N08D2","EDDSHRT1N08D3", & + "EDDSHRT1N08D4","EDDSHRT1N08D5","EDDSHRT1N08D6","EDDSHRT1N08D7","EDDSHRT1N08D8","EDDSHRT1N08D9", & + "EDDSHRT1N09D1","EDDSHRT1N09D2","EDDSHRT1N09D3","EDDSHRT1N09D4","EDDSHRT1N09D5","EDDSHRT1N09D6", & + "EDDSHRT1N09D7","EDDSHRT1N09D8","EDDSHRT1N09D9","EDDSHRT1N10D1","EDDSHRT1N10D2","EDDSHRT1N10D3", & + "EDDSHRT1N10D4","EDDSHRT1N10D5","EDDSHRT1N10D6","EDDSHRT1N10D7","EDDSHRT1N10D8","EDDSHRT1N10D9", & + "EDDSHRT1N11D1","EDDSHRT1N11D2","EDDSHRT1N11D3","EDDSHRT1N11D4","EDDSHRT1N11D5","EDDSHRT1N11D6", & + "EDDSHRT1N11D7","EDDSHRT1N11D8","EDDSHRT1N11D9","EDDSHRT1N12D1","EDDSHRT1N12D2","EDDSHRT1N12D3", & + "EDDSHRT1N12D4","EDDSHRT1N12D5","EDDSHRT1N12D6","EDDSHRT1N12D7","EDDSHRT1N12D8","EDDSHRT1N12D9", & + "EDDSHRT1N13D1","EDDSHRT1N13D2","EDDSHRT1N13D3","EDDSHRT1N13D4","EDDSHRT1N13D5","EDDSHRT1N13D6", & + "EDDSHRT1N13D7","EDDSHRT1N13D8","EDDSHRT1N13D9","EDDSHRT1N14D1","EDDSHRT1N14D2","EDDSHRT1N14D3", & + "EDDSHRT1N14D4","EDDSHRT1N14D5","EDDSHRT1N14D6","EDDSHRT1N14D7","EDDSHRT1N14D8","EDDSHRT1N14D9", & + "EDDSHRT1N15D1","EDDSHRT1N15D2","EDDSHRT1N15D3","EDDSHRT1N15D4","EDDSHRT1N15D5","EDDSHRT1N15D6", & + "EDDSHRT1N15D7","EDDSHRT1N15D8","EDDSHRT1N15D9","EDDSHRT1N16D1","EDDSHRT1N16D2","EDDSHRT1N16D3", & + "EDDSHRT1N16D4","EDDSHRT1N16D5","EDDSHRT1N16D6","EDDSHRT1N16D7","EDDSHRT1N16D8","EDDSHRT1N16D9", & + "EDDSHRT1N17D1","EDDSHRT1N17D2","EDDSHRT1N17D3","EDDSHRT1N17D4","EDDSHRT1N17D5","EDDSHRT1N17D6", & + "EDDSHRT1N17D7","EDDSHRT1N17D8","EDDSHRT1N17D9","EDDSHRT1N18D1","EDDSHRT1N18D2","EDDSHRT1N18D3", & + "EDDSHRT1N18D4","EDDSHRT1N18D5","EDDSHRT1N18D6","EDDSHRT1N18D7","EDDSHRT1N18D8","EDDSHRT1N18D9", & + "EDDSHRT1N19D1","EDDSHRT1N19D2","EDDSHRT1N19D3","EDDSHRT1N19D4","EDDSHRT1N19D5","EDDSHRT1N19D6", & + "EDDSHRT1N19D7","EDDSHRT1N19D8","EDDSHRT1N19D9","EDDSHRT1N20D1","EDDSHRT1N20D2","EDDSHRT1N20D3", & + "EDDSHRT1N20D4","EDDSHRT1N20D5","EDDSHRT1N20D6","EDDSHRT1N20D7","EDDSHRT1N20D8","EDDSHRT1N20D9", & + "EDDSHRT2N01D1","EDDSHRT2N01D2","EDDSHRT2N01D3","EDDSHRT2N01D4","EDDSHRT2N01D5","EDDSHRT2N01D6", & + "EDDSHRT2N01D7","EDDSHRT2N01D8","EDDSHRT2N01D9","EDDSHRT2N02D1","EDDSHRT2N02D2","EDDSHRT2N02D3", & + "EDDSHRT2N02D4","EDDSHRT2N02D5","EDDSHRT2N02D6","EDDSHRT2N02D7","EDDSHRT2N02D8","EDDSHRT2N02D9", & + "EDDSHRT2N03D1","EDDSHRT2N03D2","EDDSHRT2N03D3","EDDSHRT2N03D4","EDDSHRT2N03D5","EDDSHRT2N03D6", & + "EDDSHRT2N03D7","EDDSHRT2N03D8","EDDSHRT2N03D9","EDDSHRT2N04D1","EDDSHRT2N04D2","EDDSHRT2N04D3", & + "EDDSHRT2N04D4","EDDSHRT2N04D5","EDDSHRT2N04D6","EDDSHRT2N04D7","EDDSHRT2N04D8","EDDSHRT2N04D9", & + "EDDSHRT2N05D1","EDDSHRT2N05D2","EDDSHRT2N05D3","EDDSHRT2N05D4","EDDSHRT2N05D5","EDDSHRT2N05D6", & + "EDDSHRT2N05D7","EDDSHRT2N05D8","EDDSHRT2N05D9","EDDSHRT2N06D1","EDDSHRT2N06D2","EDDSHRT2N06D3", & + "EDDSHRT2N06D4","EDDSHRT2N06D5","EDDSHRT2N06D6","EDDSHRT2N06D7","EDDSHRT2N06D8","EDDSHRT2N06D9", & + "EDDSHRT2N07D1","EDDSHRT2N07D2","EDDSHRT2N07D3","EDDSHRT2N07D4","EDDSHRT2N07D5","EDDSHRT2N07D6", & + "EDDSHRT2N07D7","EDDSHRT2N07D8","EDDSHRT2N07D9","EDDSHRT2N08D1","EDDSHRT2N08D2","EDDSHRT2N08D3", & + "EDDSHRT2N08D4","EDDSHRT2N08D5","EDDSHRT2N08D6","EDDSHRT2N08D7","EDDSHRT2N08D8","EDDSHRT2N08D9", & + "EDDSHRT2N09D1","EDDSHRT2N09D2","EDDSHRT2N09D3","EDDSHRT2N09D4","EDDSHRT2N09D5","EDDSHRT2N09D6", & + "EDDSHRT2N09D7","EDDSHRT2N09D8","EDDSHRT2N09D9","EDDSHRT2N10D1","EDDSHRT2N10D2","EDDSHRT2N10D3", & + "EDDSHRT2N10D4","EDDSHRT2N10D5","EDDSHRT2N10D6","EDDSHRT2N10D7","EDDSHRT2N10D8","EDDSHRT2N10D9", & + "EDDSHRT2N11D1","EDDSHRT2N11D2","EDDSHRT2N11D3","EDDSHRT2N11D4","EDDSHRT2N11D5","EDDSHRT2N11D6", & + "EDDSHRT2N11D7","EDDSHRT2N11D8","EDDSHRT2N11D9","EDDSHRT2N12D1","EDDSHRT2N12D2","EDDSHRT2N12D3", & + "EDDSHRT2N12D4","EDDSHRT2N12D5","EDDSHRT2N12D6","EDDSHRT2N12D7","EDDSHRT2N12D8","EDDSHRT2N12D9", & + "EDDSHRT2N13D1","EDDSHRT2N13D2","EDDSHRT2N13D3","EDDSHRT2N13D4","EDDSHRT2N13D5","EDDSHRT2N13D6", & + "EDDSHRT2N13D7","EDDSHRT2N13D8","EDDSHRT2N13D9","EDDSHRT2N14D1","EDDSHRT2N14D2","EDDSHRT2N14D3", & + "EDDSHRT2N14D4","EDDSHRT2N14D5","EDDSHRT2N14D6","EDDSHRT2N14D7","EDDSHRT2N14D8","EDDSHRT2N14D9", & + "EDDSHRT2N15D1","EDDSHRT2N15D2","EDDSHRT2N15D3","EDDSHRT2N15D4","EDDSHRT2N15D5","EDDSHRT2N15D6", & + "EDDSHRT2N15D7","EDDSHRT2N15D8","EDDSHRT2N15D9","EDDSHRT2N16D1","EDDSHRT2N16D2","EDDSHRT2N16D3", & + "EDDSHRT2N16D4","EDDSHRT2N16D5","EDDSHRT2N16D6","EDDSHRT2N16D7","EDDSHRT2N16D8","EDDSHRT2N16D9", & + "EDDSHRT2N17D1","EDDSHRT2N17D2","EDDSHRT2N17D3","EDDSHRT2N17D4","EDDSHRT2N17D5","EDDSHRT2N17D6", & + "EDDSHRT2N17D7","EDDSHRT2N17D8","EDDSHRT2N17D9","EDDSHRT2N18D1","EDDSHRT2N18D2","EDDSHRT2N18D3", & + "EDDSHRT2N18D4","EDDSHRT2N18D5","EDDSHRT2N18D6","EDDSHRT2N18D7","EDDSHRT2N18D8","EDDSHRT2N18D9", & + "EDDSHRT2N19D1","EDDSHRT2N19D2","EDDSHRT2N19D3","EDDSHRT2N19D4","EDDSHRT2N19D5","EDDSHRT2N19D6", & + "EDDSHRT2N19D7","EDDSHRT2N19D8","EDDSHRT2N19D9","EDDSHRT2N20D1","EDDSHRT2N20D2","EDDSHRT2N20D3", & + "EDDSHRT2N20D4","EDDSHRT2N20D5","EDDSHRT2N20D6","EDDSHRT2N20D7","EDDSHRT2N20D8","EDDSHRT2N20D9", & + "EDDSHRT3N01D1","EDDSHRT3N01D2","EDDSHRT3N01D3","EDDSHRT3N01D4","EDDSHRT3N01D5","EDDSHRT3N01D6", & + "EDDSHRT3N01D7","EDDSHRT3N01D8","EDDSHRT3N01D9","EDDSHRT3N02D1","EDDSHRT3N02D2","EDDSHRT3N02D3", & + "EDDSHRT3N02D4","EDDSHRT3N02D5","EDDSHRT3N02D6","EDDSHRT3N02D7","EDDSHRT3N02D8","EDDSHRT3N02D9", & + "EDDSHRT3N03D1","EDDSHRT3N03D2","EDDSHRT3N03D3","EDDSHRT3N03D4","EDDSHRT3N03D5","EDDSHRT3N03D6", & + "EDDSHRT3N03D7","EDDSHRT3N03D8","EDDSHRT3N03D9","EDDSHRT3N04D1","EDDSHRT3N04D2","EDDSHRT3N04D3", & + "EDDSHRT3N04D4","EDDSHRT3N04D5","EDDSHRT3N04D6","EDDSHRT3N04D7","EDDSHRT3N04D8","EDDSHRT3N04D9", & + "EDDSHRT3N05D1","EDDSHRT3N05D2","EDDSHRT3N05D3","EDDSHRT3N05D4","EDDSHRT3N05D5","EDDSHRT3N05D6", & + "EDDSHRT3N05D7","EDDSHRT3N05D8","EDDSHRT3N05D9","EDDSHRT3N06D1","EDDSHRT3N06D2","EDDSHRT3N06D3", & + "EDDSHRT3N06D4","EDDSHRT3N06D5","EDDSHRT3N06D6","EDDSHRT3N06D7","EDDSHRT3N06D8","EDDSHRT3N06D9", & + "EDDSHRT3N07D1","EDDSHRT3N07D2","EDDSHRT3N07D3","EDDSHRT3N07D4","EDDSHRT3N07D5","EDDSHRT3N07D6", & + "EDDSHRT3N07D7","EDDSHRT3N07D8","EDDSHRT3N07D9","EDDSHRT3N08D1","EDDSHRT3N08D2","EDDSHRT3N08D3", & + "EDDSHRT3N08D4","EDDSHRT3N08D5","EDDSHRT3N08D6","EDDSHRT3N08D7","EDDSHRT3N08D8","EDDSHRT3N08D9", & + "EDDSHRT3N09D1","EDDSHRT3N09D2","EDDSHRT3N09D3","EDDSHRT3N09D4","EDDSHRT3N09D5","EDDSHRT3N09D6", & + "EDDSHRT3N09D7","EDDSHRT3N09D8","EDDSHRT3N09D9","EDDSHRT3N10D1","EDDSHRT3N10D2","EDDSHRT3N10D3", & + "EDDSHRT3N10D4","EDDSHRT3N10D5","EDDSHRT3N10D6","EDDSHRT3N10D7","EDDSHRT3N10D8","EDDSHRT3N10D9", & + "EDDSHRT3N11D1","EDDSHRT3N11D2","EDDSHRT3N11D3","EDDSHRT3N11D4","EDDSHRT3N11D5","EDDSHRT3N11D6", & + "EDDSHRT3N11D7","EDDSHRT3N11D8","EDDSHRT3N11D9","EDDSHRT3N12D1","EDDSHRT3N12D2","EDDSHRT3N12D3", & + "EDDSHRT3N12D4","EDDSHRT3N12D5","EDDSHRT3N12D6","EDDSHRT3N12D7","EDDSHRT3N12D8","EDDSHRT3N12D9", & + "EDDSHRT3N13D1","EDDSHRT3N13D2","EDDSHRT3N13D3","EDDSHRT3N13D4","EDDSHRT3N13D5","EDDSHRT3N13D6", & + "EDDSHRT3N13D7","EDDSHRT3N13D8","EDDSHRT3N13D9","EDDSHRT3N14D1","EDDSHRT3N14D2","EDDSHRT3N14D3", & + "EDDSHRT3N14D4","EDDSHRT3N14D5","EDDSHRT3N14D6","EDDSHRT3N14D7","EDDSHRT3N14D8","EDDSHRT3N14D9", & + "EDDSHRT3N15D1","EDDSHRT3N15D2","EDDSHRT3N15D3","EDDSHRT3N15D4","EDDSHRT3N15D5","EDDSHRT3N15D6", & + "EDDSHRT3N15D7","EDDSHRT3N15D8","EDDSHRT3N15D9","EDDSHRT3N16D1","EDDSHRT3N16D2","EDDSHRT3N16D3", & + "EDDSHRT3N16D4","EDDSHRT3N16D5","EDDSHRT3N16D6","EDDSHRT3N16D7","EDDSHRT3N16D8","EDDSHRT3N16D9", & + "EDDSHRT3N17D1","EDDSHRT3N17D2","EDDSHRT3N17D3","EDDSHRT3N17D4","EDDSHRT3N17D5","EDDSHRT3N17D6", & + "EDDSHRT3N17D7","EDDSHRT3N17D8","EDDSHRT3N17D9","EDDSHRT3N18D1","EDDSHRT3N18D2","EDDSHRT3N18D3", & + "EDDSHRT3N18D4","EDDSHRT3N18D5","EDDSHRT3N18D6","EDDSHRT3N18D7","EDDSHRT3N18D8","EDDSHRT3N18D9", & + "EDDSHRT3N19D1","EDDSHRT3N19D2","EDDSHRT3N19D3","EDDSHRT3N19D4","EDDSHRT3N19D5","EDDSHRT3N19D6", & + "EDDSHRT3N19D7","EDDSHRT3N19D8","EDDSHRT3N19D9","EDDSHRT3N20D1","EDDSHRT3N20D2","EDDSHRT3N20D3", & + "EDDSHRT3N20D4","EDDSHRT3N20D5","EDDSHRT3N20D6","EDDSHRT3N20D7","EDDSHRT3N20D8","EDDSHRT3N20D9", & + "EDDSHRT4N01D1","EDDSHRT4N01D2","EDDSHRT4N01D3","EDDSHRT4N01D4","EDDSHRT4N01D5","EDDSHRT4N01D6", & + "EDDSHRT4N01D7","EDDSHRT4N01D8","EDDSHRT4N01D9","EDDSHRT4N02D1","EDDSHRT4N02D2","EDDSHRT4N02D3", & + "EDDSHRT4N02D4","EDDSHRT4N02D5","EDDSHRT4N02D6","EDDSHRT4N02D7","EDDSHRT4N02D8","EDDSHRT4N02D9", & + "EDDSHRT4N03D1","EDDSHRT4N03D2","EDDSHRT4N03D3","EDDSHRT4N03D4","EDDSHRT4N03D5","EDDSHRT4N03D6", & + "EDDSHRT4N03D7","EDDSHRT4N03D8","EDDSHRT4N03D9","EDDSHRT4N04D1","EDDSHRT4N04D2","EDDSHRT4N04D3", & + "EDDSHRT4N04D4","EDDSHRT4N04D5","EDDSHRT4N04D6","EDDSHRT4N04D7","EDDSHRT4N04D8","EDDSHRT4N04D9", & + "EDDSHRT4N05D1","EDDSHRT4N05D2","EDDSHRT4N05D3","EDDSHRT4N05D4","EDDSHRT4N05D5","EDDSHRT4N05D6", & + "EDDSHRT4N05D7","EDDSHRT4N05D8","EDDSHRT4N05D9","EDDSHRT4N06D1","EDDSHRT4N06D2","EDDSHRT4N06D3", & + "EDDSHRT4N06D4","EDDSHRT4N06D5","EDDSHRT4N06D6","EDDSHRT4N06D7","EDDSHRT4N06D8","EDDSHRT4N06D9", & + "EDDSHRT4N07D1","EDDSHRT4N07D2","EDDSHRT4N07D3","EDDSHRT4N07D4","EDDSHRT4N07D5","EDDSHRT4N07D6", & + "EDDSHRT4N07D7","EDDSHRT4N07D8","EDDSHRT4N07D9","EDDSHRT4N08D1","EDDSHRT4N08D2","EDDSHRT4N08D3", & + "EDDSHRT4N08D4","EDDSHRT4N08D5","EDDSHRT4N08D6","EDDSHRT4N08D7","EDDSHRT4N08D8","EDDSHRT4N08D9", & + "EDDSHRT4N09D1","EDDSHRT4N09D2","EDDSHRT4N09D3","EDDSHRT4N09D4","EDDSHRT4N09D5","EDDSHRT4N09D6", & + "EDDSHRT4N09D7","EDDSHRT4N09D8","EDDSHRT4N09D9","EDDSHRT4N10D1","EDDSHRT4N10D2","EDDSHRT4N10D3", & + "EDDSHRT4N10D4","EDDSHRT4N10D5","EDDSHRT4N10D6","EDDSHRT4N10D7","EDDSHRT4N10D8","EDDSHRT4N10D9", & + "EDDSHRT4N11D1","EDDSHRT4N11D2","EDDSHRT4N11D3","EDDSHRT4N11D4","EDDSHRT4N11D5","EDDSHRT4N11D6", & + "EDDSHRT4N11D7","EDDSHRT4N11D8","EDDSHRT4N11D9","EDDSHRT4N12D1","EDDSHRT4N12D2","EDDSHRT4N12D3", & + "EDDSHRT4N12D4","EDDSHRT4N12D5","EDDSHRT4N12D6","EDDSHRT4N12D7","EDDSHRT4N12D8","EDDSHRT4N12D9", & + "EDDSHRT4N13D1","EDDSHRT4N13D2","EDDSHRT4N13D3","EDDSHRT4N13D4","EDDSHRT4N13D5","EDDSHRT4N13D6", & + "EDDSHRT4N13D7","EDDSHRT4N13D8","EDDSHRT4N13D9","EDDSHRT4N14D1","EDDSHRT4N14D2","EDDSHRT4N14D3", & + "EDDSHRT4N14D4","EDDSHRT4N14D5","EDDSHRT4N14D6","EDDSHRT4N14D7","EDDSHRT4N14D8","EDDSHRT4N14D9", & + "EDDSHRT4N15D1","EDDSHRT4N15D2","EDDSHRT4N15D3","EDDSHRT4N15D4","EDDSHRT4N15D5","EDDSHRT4N15D6", & + "EDDSHRT4N15D7","EDDSHRT4N15D8","EDDSHRT4N15D9","EDDSHRT4N16D1","EDDSHRT4N16D2","EDDSHRT4N16D3", & + "EDDSHRT4N16D4","EDDSHRT4N16D5","EDDSHRT4N16D6","EDDSHRT4N16D7","EDDSHRT4N16D8","EDDSHRT4N16D9", & + "EDDSHRT4N17D1","EDDSHRT4N17D2","EDDSHRT4N17D3","EDDSHRT4N17D4","EDDSHRT4N17D5","EDDSHRT4N17D6", & + "EDDSHRT4N17D7","EDDSHRT4N17D8","EDDSHRT4N17D9","EDDSHRT4N18D1","EDDSHRT4N18D2","EDDSHRT4N18D3", & + "EDDSHRT4N18D4","EDDSHRT4N18D5","EDDSHRT4N18D6","EDDSHRT4N18D7","EDDSHRT4N18D8","EDDSHRT4N18D9", & + "EDDSHRT4N19D1","EDDSHRT4N19D2","EDDSHRT4N19D3","EDDSHRT4N19D4","EDDSHRT4N19D5","EDDSHRT4N19D6", & + "EDDSHRT4N19D7","EDDSHRT4N19D8","EDDSHRT4N19D9","EDDSHRT4N20D1","EDDSHRT4N20D2","EDDSHRT4N20D3", & + "EDDSHRT4N20D4","EDDSHRT4N20D5","EDDSHRT4N20D6","EDDSHRT4N20D7","EDDSHRT4N20D8","EDDSHRT4N20D9", & + "EDDSHRT5N01D1","EDDSHRT5N01D2","EDDSHRT5N01D3","EDDSHRT5N01D4","EDDSHRT5N01D5","EDDSHRT5N01D6", & + "EDDSHRT5N01D7","EDDSHRT5N01D8","EDDSHRT5N01D9","EDDSHRT5N02D1","EDDSHRT5N02D2","EDDSHRT5N02D3", & + "EDDSHRT5N02D4","EDDSHRT5N02D5","EDDSHRT5N02D6","EDDSHRT5N02D7","EDDSHRT5N02D8","EDDSHRT5N02D9", & + "EDDSHRT5N03D1","EDDSHRT5N03D2","EDDSHRT5N03D3","EDDSHRT5N03D4","EDDSHRT5N03D5","EDDSHRT5N03D6", & + "EDDSHRT5N03D7","EDDSHRT5N03D8","EDDSHRT5N03D9","EDDSHRT5N04D1","EDDSHRT5N04D2","EDDSHRT5N04D3", & + "EDDSHRT5N04D4","EDDSHRT5N04D5","EDDSHRT5N04D6","EDDSHRT5N04D7","EDDSHRT5N04D8","EDDSHRT5N04D9", & + "EDDSHRT5N05D1","EDDSHRT5N05D2","EDDSHRT5N05D3","EDDSHRT5N05D4","EDDSHRT5N05D5","EDDSHRT5N05D6", & + "EDDSHRT5N05D7","EDDSHRT5N05D8","EDDSHRT5N05D9","EDDSHRT5N06D1","EDDSHRT5N06D2","EDDSHRT5N06D3", & + "EDDSHRT5N06D4","EDDSHRT5N06D5","EDDSHRT5N06D6","EDDSHRT5N06D7","EDDSHRT5N06D8","EDDSHRT5N06D9", & + "EDDSHRT5N07D1","EDDSHRT5N07D2","EDDSHRT5N07D3","EDDSHRT5N07D4","EDDSHRT5N07D5","EDDSHRT5N07D6", & + "EDDSHRT5N07D7","EDDSHRT5N07D8","EDDSHRT5N07D9","EDDSHRT5N08D1","EDDSHRT5N08D2","EDDSHRT5N08D3", & + "EDDSHRT5N08D4","EDDSHRT5N08D5","EDDSHRT5N08D6","EDDSHRT5N08D7","EDDSHRT5N08D8","EDDSHRT5N08D9", & + "EDDSHRT5N09D1","EDDSHRT5N09D2","EDDSHRT5N09D3","EDDSHRT5N09D4","EDDSHRT5N09D5","EDDSHRT5N09D6", & + "EDDSHRT5N09D7","EDDSHRT5N09D8","EDDSHRT5N09D9","EDDSHRT5N10D1","EDDSHRT5N10D2","EDDSHRT5N10D3", & + "EDDSHRT5N10D4","EDDSHRT5N10D5","EDDSHRT5N10D6","EDDSHRT5N10D7","EDDSHRT5N10D8","EDDSHRT5N10D9", & + "EDDSHRT5N11D1","EDDSHRT5N11D2","EDDSHRT5N11D3","EDDSHRT5N11D4","EDDSHRT5N11D5","EDDSHRT5N11D6", & + "EDDSHRT5N11D7","EDDSHRT5N11D8","EDDSHRT5N11D9","EDDSHRT5N12D1","EDDSHRT5N12D2","EDDSHRT5N12D3", & + "EDDSHRT5N12D4","EDDSHRT5N12D5","EDDSHRT5N12D6","EDDSHRT5N12D7","EDDSHRT5N12D8","EDDSHRT5N12D9", & + "EDDSHRT5N13D1","EDDSHRT5N13D2","EDDSHRT5N13D3","EDDSHRT5N13D4","EDDSHRT5N13D5","EDDSHRT5N13D6", & + "EDDSHRT5N13D7","EDDSHRT5N13D8","EDDSHRT5N13D9","EDDSHRT5N14D1","EDDSHRT5N14D2","EDDSHRT5N14D3", & + "EDDSHRT5N14D4","EDDSHRT5N14D5","EDDSHRT5N14D6","EDDSHRT5N14D7","EDDSHRT5N14D8","EDDSHRT5N14D9", & + "EDDSHRT5N15D1","EDDSHRT5N15D2","EDDSHRT5N15D3","EDDSHRT5N15D4","EDDSHRT5N15D5","EDDSHRT5N15D6", & + "EDDSHRT5N15D7","EDDSHRT5N15D8","EDDSHRT5N15D9","EDDSHRT5N16D1","EDDSHRT5N16D2","EDDSHRT5N16D3", & + "EDDSHRT5N16D4","EDDSHRT5N16D5","EDDSHRT5N16D6","EDDSHRT5N16D7","EDDSHRT5N16D8","EDDSHRT5N16D9", & + "EDDSHRT5N17D1","EDDSHRT5N17D2","EDDSHRT5N17D3","EDDSHRT5N17D4","EDDSHRT5N17D5","EDDSHRT5N17D6", & + "EDDSHRT5N17D7","EDDSHRT5N17D8","EDDSHRT5N17D9","EDDSHRT5N18D1","EDDSHRT5N18D2","EDDSHRT5N18D3", & + "EDDSHRT5N18D4","EDDSHRT5N18D5","EDDSHRT5N18D6","EDDSHRT5N18D7","EDDSHRT5N18D8","EDDSHRT5N18D9", & + "EDDSHRT5N19D1","EDDSHRT5N19D2","EDDSHRT5N19D3","EDDSHRT5N19D4","EDDSHRT5N19D5","EDDSHRT5N19D6", & + "EDDSHRT5N19D7","EDDSHRT5N19D8","EDDSHRT5N19D9","EDDSHRT5N20D1","EDDSHRT5N20D2","EDDSHRT5N20D3"/) + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry3(1356) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "EDDSHRT5N20D4","EDDSHRT5N20D5","EDDSHRT5N20D6","EDDSHRT5N20D7","EDDSHRT5N20D8","EDDSHRT5N20D9", & + "EDDSHRT6N01D1","EDDSHRT6N01D2","EDDSHRT6N01D3","EDDSHRT6N01D4","EDDSHRT6N01D5","EDDSHRT6N01D6", & + "EDDSHRT6N01D7","EDDSHRT6N01D8","EDDSHRT6N01D9","EDDSHRT6N02D1","EDDSHRT6N02D2","EDDSHRT6N02D3", & + "EDDSHRT6N02D4","EDDSHRT6N02D5","EDDSHRT6N02D6","EDDSHRT6N02D7","EDDSHRT6N02D8","EDDSHRT6N02D9", & + "EDDSHRT6N03D1","EDDSHRT6N03D2","EDDSHRT6N03D3","EDDSHRT6N03D4","EDDSHRT6N03D5","EDDSHRT6N03D6", & + "EDDSHRT6N03D7","EDDSHRT6N03D8","EDDSHRT6N03D9","EDDSHRT6N04D1","EDDSHRT6N04D2","EDDSHRT6N04D3", & + "EDDSHRT6N04D4","EDDSHRT6N04D5","EDDSHRT6N04D6","EDDSHRT6N04D7","EDDSHRT6N04D8","EDDSHRT6N04D9", & + "EDDSHRT6N05D1","EDDSHRT6N05D2","EDDSHRT6N05D3","EDDSHRT6N05D4","EDDSHRT6N05D5","EDDSHRT6N05D6", & + "EDDSHRT6N05D7","EDDSHRT6N05D8","EDDSHRT6N05D9","EDDSHRT6N06D1","EDDSHRT6N06D2","EDDSHRT6N06D3", & + "EDDSHRT6N06D4","EDDSHRT6N06D5","EDDSHRT6N06D6","EDDSHRT6N06D7","EDDSHRT6N06D8","EDDSHRT6N06D9", & + "EDDSHRT6N07D1","EDDSHRT6N07D2","EDDSHRT6N07D3","EDDSHRT6N07D4","EDDSHRT6N07D5","EDDSHRT6N07D6", & + "EDDSHRT6N07D7","EDDSHRT6N07D8","EDDSHRT6N07D9","EDDSHRT6N08D1","EDDSHRT6N08D2","EDDSHRT6N08D3", & + "EDDSHRT6N08D4","EDDSHRT6N08D5","EDDSHRT6N08D6","EDDSHRT6N08D7","EDDSHRT6N08D8","EDDSHRT6N08D9", & + "EDDSHRT6N09D1","EDDSHRT6N09D2","EDDSHRT6N09D3","EDDSHRT6N09D4","EDDSHRT6N09D5","EDDSHRT6N09D6", & + "EDDSHRT6N09D7","EDDSHRT6N09D8","EDDSHRT6N09D9","EDDSHRT6N10D1","EDDSHRT6N10D2","EDDSHRT6N10D3", & + "EDDSHRT6N10D4","EDDSHRT6N10D5","EDDSHRT6N10D6","EDDSHRT6N10D7","EDDSHRT6N10D8","EDDSHRT6N10D9", & + "EDDSHRT6N11D1","EDDSHRT6N11D2","EDDSHRT6N11D3","EDDSHRT6N11D4","EDDSHRT6N11D5","EDDSHRT6N11D6", & + "EDDSHRT6N11D7","EDDSHRT6N11D8","EDDSHRT6N11D9","EDDSHRT6N12D1","EDDSHRT6N12D2","EDDSHRT6N12D3", & + "EDDSHRT6N12D4","EDDSHRT6N12D5","EDDSHRT6N12D6","EDDSHRT6N12D7","EDDSHRT6N12D8","EDDSHRT6N12D9", & + "EDDSHRT6N13D1","EDDSHRT6N13D2","EDDSHRT6N13D3","EDDSHRT6N13D4","EDDSHRT6N13D5","EDDSHRT6N13D6", & + "EDDSHRT6N13D7","EDDSHRT6N13D8","EDDSHRT6N13D9","EDDSHRT6N14D1","EDDSHRT6N14D2","EDDSHRT6N14D3", & + "EDDSHRT6N14D4","EDDSHRT6N14D5","EDDSHRT6N14D6","EDDSHRT6N14D7","EDDSHRT6N14D8","EDDSHRT6N14D9", & + "EDDSHRT6N15D1","EDDSHRT6N15D2","EDDSHRT6N15D3","EDDSHRT6N15D4","EDDSHRT6N15D5","EDDSHRT6N15D6", & + "EDDSHRT6N15D7","EDDSHRT6N15D8","EDDSHRT6N15D9","EDDSHRT6N16D1","EDDSHRT6N16D2","EDDSHRT6N16D3", & + "EDDSHRT6N16D4","EDDSHRT6N16D5","EDDSHRT6N16D6","EDDSHRT6N16D7","EDDSHRT6N16D8","EDDSHRT6N16D9", & + "EDDSHRT6N17D1","EDDSHRT6N17D2","EDDSHRT6N17D3","EDDSHRT6N17D4","EDDSHRT6N17D5","EDDSHRT6N17D6", & + "EDDSHRT6N17D7","EDDSHRT6N17D8","EDDSHRT6N17D9","EDDSHRT6N18D1","EDDSHRT6N18D2","EDDSHRT6N18D3", & + "EDDSHRT6N18D4","EDDSHRT6N18D5","EDDSHRT6N18D6","EDDSHRT6N18D7","EDDSHRT6N18D8","EDDSHRT6N18D9", & + "EDDSHRT6N19D1","EDDSHRT6N19D2","EDDSHRT6N19D3","EDDSHRT6N19D4","EDDSHRT6N19D5","EDDSHRT6N19D6", & + "EDDSHRT6N19D7","EDDSHRT6N19D8","EDDSHRT6N19D9","EDDSHRT6N20D1","EDDSHRT6N20D2","EDDSHRT6N20D3", & + "EDDSHRT6N20D4","EDDSHRT6N20D5","EDDSHRT6N20D6","EDDSHRT6N20D7","EDDSHRT6N20D8","EDDSHRT6N20D9", & + "EDDSHRT7N01D1","EDDSHRT7N01D2","EDDSHRT7N01D3","EDDSHRT7N01D4","EDDSHRT7N01D5","EDDSHRT7N01D6", & + "EDDSHRT7N01D7","EDDSHRT7N01D8","EDDSHRT7N01D9","EDDSHRT7N02D1","EDDSHRT7N02D2","EDDSHRT7N02D3", & + "EDDSHRT7N02D4","EDDSHRT7N02D5","EDDSHRT7N02D6","EDDSHRT7N02D7","EDDSHRT7N02D8","EDDSHRT7N02D9", & + "EDDSHRT7N03D1","EDDSHRT7N03D2","EDDSHRT7N03D3","EDDSHRT7N03D4","EDDSHRT7N03D5","EDDSHRT7N03D6", & + "EDDSHRT7N03D7","EDDSHRT7N03D8","EDDSHRT7N03D9","EDDSHRT7N04D1","EDDSHRT7N04D2","EDDSHRT7N04D3", & + "EDDSHRT7N04D4","EDDSHRT7N04D5","EDDSHRT7N04D6","EDDSHRT7N04D7","EDDSHRT7N04D8","EDDSHRT7N04D9", & + "EDDSHRT7N05D1","EDDSHRT7N05D2","EDDSHRT7N05D3","EDDSHRT7N05D4","EDDSHRT7N05D5","EDDSHRT7N05D6", & + "EDDSHRT7N05D7","EDDSHRT7N05D8","EDDSHRT7N05D9","EDDSHRT7N06D1","EDDSHRT7N06D2","EDDSHRT7N06D3", & + "EDDSHRT7N06D4","EDDSHRT7N06D5","EDDSHRT7N06D6","EDDSHRT7N06D7","EDDSHRT7N06D8","EDDSHRT7N06D9", & + "EDDSHRT7N07D1","EDDSHRT7N07D2","EDDSHRT7N07D3","EDDSHRT7N07D4","EDDSHRT7N07D5","EDDSHRT7N07D6", & + "EDDSHRT7N07D7","EDDSHRT7N07D8","EDDSHRT7N07D9","EDDSHRT7N08D1","EDDSHRT7N08D2","EDDSHRT7N08D3", & + "EDDSHRT7N08D4","EDDSHRT7N08D5","EDDSHRT7N08D6","EDDSHRT7N08D7","EDDSHRT7N08D8","EDDSHRT7N08D9", & + "EDDSHRT7N09D1","EDDSHRT7N09D2","EDDSHRT7N09D3","EDDSHRT7N09D4","EDDSHRT7N09D5","EDDSHRT7N09D6", & + "EDDSHRT7N09D7","EDDSHRT7N09D8","EDDSHRT7N09D9","EDDSHRT7N10D1","EDDSHRT7N10D2","EDDSHRT7N10D3", & + "EDDSHRT7N10D4","EDDSHRT7N10D5","EDDSHRT7N10D6","EDDSHRT7N10D7","EDDSHRT7N10D8","EDDSHRT7N10D9", & + "EDDSHRT7N11D1","EDDSHRT7N11D2","EDDSHRT7N11D3","EDDSHRT7N11D4","EDDSHRT7N11D5","EDDSHRT7N11D6", & + "EDDSHRT7N11D7","EDDSHRT7N11D8","EDDSHRT7N11D9","EDDSHRT7N12D1","EDDSHRT7N12D2","EDDSHRT7N12D3", & + "EDDSHRT7N12D4","EDDSHRT7N12D5","EDDSHRT7N12D6","EDDSHRT7N12D7","EDDSHRT7N12D8","EDDSHRT7N12D9", & + "EDDSHRT7N13D1","EDDSHRT7N13D2","EDDSHRT7N13D3","EDDSHRT7N13D4","EDDSHRT7N13D5","EDDSHRT7N13D6", & + "EDDSHRT7N13D7","EDDSHRT7N13D8","EDDSHRT7N13D9","EDDSHRT7N14D1","EDDSHRT7N14D2","EDDSHRT7N14D3", & + "EDDSHRT7N14D4","EDDSHRT7N14D5","EDDSHRT7N14D6","EDDSHRT7N14D7","EDDSHRT7N14D8","EDDSHRT7N14D9", & + "EDDSHRT7N15D1","EDDSHRT7N15D2","EDDSHRT7N15D3","EDDSHRT7N15D4","EDDSHRT7N15D5","EDDSHRT7N15D6", & + "EDDSHRT7N15D7","EDDSHRT7N15D8","EDDSHRT7N15D9","EDDSHRT7N16D1","EDDSHRT7N16D2","EDDSHRT7N16D3", & + "EDDSHRT7N16D4","EDDSHRT7N16D5","EDDSHRT7N16D6","EDDSHRT7N16D7","EDDSHRT7N16D8","EDDSHRT7N16D9", & + "EDDSHRT7N17D1","EDDSHRT7N17D2","EDDSHRT7N17D3","EDDSHRT7N17D4","EDDSHRT7N17D5","EDDSHRT7N17D6", & + "EDDSHRT7N17D7","EDDSHRT7N17D8","EDDSHRT7N17D9","EDDSHRT7N18D1","EDDSHRT7N18D2","EDDSHRT7N18D3", & + "EDDSHRT7N18D4","EDDSHRT7N18D5","EDDSHRT7N18D6","EDDSHRT7N18D7","EDDSHRT7N18D8","EDDSHRT7N18D9", & + "EDDSHRT7N19D1","EDDSHRT7N19D2","EDDSHRT7N19D3","EDDSHRT7N19D4","EDDSHRT7N19D5","EDDSHRT7N19D6", & + "EDDSHRT7N19D7","EDDSHRT7N19D8","EDDSHRT7N19D9","EDDSHRT7N20D1","EDDSHRT7N20D2","EDDSHRT7N20D3", & + "EDDSHRT7N20D4","EDDSHRT7N20D5","EDDSHRT7N20D6","EDDSHRT7N20D7","EDDSHRT7N20D8","EDDSHRT7N20D9", & + "EDDSHRT8N01D1","EDDSHRT8N01D2","EDDSHRT8N01D3","EDDSHRT8N01D4","EDDSHRT8N01D5","EDDSHRT8N01D6", & + "EDDSHRT8N01D7","EDDSHRT8N01D8","EDDSHRT8N01D9","EDDSHRT8N02D1","EDDSHRT8N02D2","EDDSHRT8N02D3", & + "EDDSHRT8N02D4","EDDSHRT8N02D5","EDDSHRT8N02D6","EDDSHRT8N02D7","EDDSHRT8N02D8","EDDSHRT8N02D9", & + "EDDSHRT8N03D1","EDDSHRT8N03D2","EDDSHRT8N03D3","EDDSHRT8N03D4","EDDSHRT8N03D5","EDDSHRT8N03D6", & + "EDDSHRT8N03D7","EDDSHRT8N03D8","EDDSHRT8N03D9","EDDSHRT8N04D1","EDDSHRT8N04D2","EDDSHRT8N04D3", & + "EDDSHRT8N04D4","EDDSHRT8N04D5","EDDSHRT8N04D6","EDDSHRT8N04D7","EDDSHRT8N04D8","EDDSHRT8N04D9", & + "EDDSHRT8N05D1","EDDSHRT8N05D2","EDDSHRT8N05D3","EDDSHRT8N05D4","EDDSHRT8N05D5","EDDSHRT8N05D6", & + "EDDSHRT8N05D7","EDDSHRT8N05D8","EDDSHRT8N05D9","EDDSHRT8N06D1","EDDSHRT8N06D2","EDDSHRT8N06D3", & + "EDDSHRT8N06D4","EDDSHRT8N06D5","EDDSHRT8N06D6","EDDSHRT8N06D7","EDDSHRT8N06D8","EDDSHRT8N06D9", & + "EDDSHRT8N07D1","EDDSHRT8N07D2","EDDSHRT8N07D3","EDDSHRT8N07D4","EDDSHRT8N07D5","EDDSHRT8N07D6", & + "EDDSHRT8N07D7","EDDSHRT8N07D8","EDDSHRT8N07D9","EDDSHRT8N08D1","EDDSHRT8N08D2","EDDSHRT8N08D3", & + "EDDSHRT8N08D4","EDDSHRT8N08D5","EDDSHRT8N08D6","EDDSHRT8N08D7","EDDSHRT8N08D8","EDDSHRT8N08D9", & + "EDDSHRT8N09D1","EDDSHRT8N09D2","EDDSHRT8N09D3","EDDSHRT8N09D4","EDDSHRT8N09D5","EDDSHRT8N09D6", & + "EDDSHRT8N09D7","EDDSHRT8N09D8","EDDSHRT8N09D9","EDDSHRT8N10D1","EDDSHRT8N10D2","EDDSHRT8N10D3", & + "EDDSHRT8N10D4","EDDSHRT8N10D5","EDDSHRT8N10D6","EDDSHRT8N10D7","EDDSHRT8N10D8","EDDSHRT8N10D9", & + "EDDSHRT8N11D1","EDDSHRT8N11D2","EDDSHRT8N11D3","EDDSHRT8N11D4","EDDSHRT8N11D5","EDDSHRT8N11D6", & + "EDDSHRT8N11D7","EDDSHRT8N11D8","EDDSHRT8N11D9","EDDSHRT8N12D1","EDDSHRT8N12D2","EDDSHRT8N12D3", & + "EDDSHRT8N12D4","EDDSHRT8N12D5","EDDSHRT8N12D6","EDDSHRT8N12D7","EDDSHRT8N12D8","EDDSHRT8N12D9", & + "EDDSHRT8N13D1","EDDSHRT8N13D2","EDDSHRT8N13D3","EDDSHRT8N13D4","EDDSHRT8N13D5","EDDSHRT8N13D6", & + "EDDSHRT8N13D7","EDDSHRT8N13D8","EDDSHRT8N13D9","EDDSHRT8N14D1","EDDSHRT8N14D2","EDDSHRT8N14D3", & + "EDDSHRT8N14D4","EDDSHRT8N14D5","EDDSHRT8N14D6","EDDSHRT8N14D7","EDDSHRT8N14D8","EDDSHRT8N14D9", & + "EDDSHRT8N15D1","EDDSHRT8N15D2","EDDSHRT8N15D3","EDDSHRT8N15D4","EDDSHRT8N15D5","EDDSHRT8N15D6", & + "EDDSHRT8N15D7","EDDSHRT8N15D8","EDDSHRT8N15D9","EDDSHRT8N16D1","EDDSHRT8N16D2","EDDSHRT8N16D3", & + "EDDSHRT8N16D4","EDDSHRT8N16D5","EDDSHRT8N16D6","EDDSHRT8N16D7","EDDSHRT8N16D8","EDDSHRT8N16D9", & + "EDDSHRT8N17D1","EDDSHRT8N17D2","EDDSHRT8N17D3","EDDSHRT8N17D4","EDDSHRT8N17D5","EDDSHRT8N17D6", & + "EDDSHRT8N17D7","EDDSHRT8N17D8","EDDSHRT8N17D9","EDDSHRT8N18D1","EDDSHRT8N18D2","EDDSHRT8N18D3", & + "EDDSHRT8N18D4","EDDSHRT8N18D5","EDDSHRT8N18D6","EDDSHRT8N18D7","EDDSHRT8N18D8","EDDSHRT8N18D9", & + "EDDSHRT8N19D1","EDDSHRT8N19D2","EDDSHRT8N19D3","EDDSHRT8N19D4","EDDSHRT8N19D5","EDDSHRT8N19D6", & + "EDDSHRT8N19D7","EDDSHRT8N19D8","EDDSHRT8N19D9","EDDSHRT8N20D1","EDDSHRT8N20D2","EDDSHRT8N20D3", & + "EDDSHRT8N20D4","EDDSHRT8N20D5","EDDSHRT8N20D6","EDDSHRT8N20D7","EDDSHRT8N20D8","EDDSHRT8N20D9", & + "EDDSHRT9N01D1","EDDSHRT9N01D2","EDDSHRT9N01D3","EDDSHRT9N01D4","EDDSHRT9N01D5","EDDSHRT9N01D6", & + "EDDSHRT9N01D7","EDDSHRT9N01D8","EDDSHRT9N01D9","EDDSHRT9N02D1","EDDSHRT9N02D2","EDDSHRT9N02D3", & + "EDDSHRT9N02D4","EDDSHRT9N02D5","EDDSHRT9N02D6","EDDSHRT9N02D7","EDDSHRT9N02D8","EDDSHRT9N02D9", & + "EDDSHRT9N03D1","EDDSHRT9N03D2","EDDSHRT9N03D3","EDDSHRT9N03D4","EDDSHRT9N03D5","EDDSHRT9N03D6", & + "EDDSHRT9N03D7","EDDSHRT9N03D8","EDDSHRT9N03D9","EDDSHRT9N04D1","EDDSHRT9N04D2","EDDSHRT9N04D3", & + "EDDSHRT9N04D4","EDDSHRT9N04D5","EDDSHRT9N04D6","EDDSHRT9N04D7","EDDSHRT9N04D8","EDDSHRT9N04D9", & + "EDDSHRT9N05D1","EDDSHRT9N05D2","EDDSHRT9N05D3","EDDSHRT9N05D4","EDDSHRT9N05D5","EDDSHRT9N05D6", & + "EDDSHRT9N05D7","EDDSHRT9N05D8","EDDSHRT9N05D9","EDDSHRT9N06D1","EDDSHRT9N06D2","EDDSHRT9N06D3", & + "EDDSHRT9N06D4","EDDSHRT9N06D5","EDDSHRT9N06D6","EDDSHRT9N06D7","EDDSHRT9N06D8","EDDSHRT9N06D9", & + "EDDSHRT9N07D1","EDDSHRT9N07D2","EDDSHRT9N07D3","EDDSHRT9N07D4","EDDSHRT9N07D5","EDDSHRT9N07D6", & + "EDDSHRT9N07D7","EDDSHRT9N07D8","EDDSHRT9N07D9","EDDSHRT9N08D1","EDDSHRT9N08D2","EDDSHRT9N08D3", & + "EDDSHRT9N08D4","EDDSHRT9N08D5","EDDSHRT9N08D6","EDDSHRT9N08D7","EDDSHRT9N08D8","EDDSHRT9N08D9", & + "EDDSHRT9N09D1","EDDSHRT9N09D2","EDDSHRT9N09D3","EDDSHRT9N09D4","EDDSHRT9N09D5","EDDSHRT9N09D6", & + "EDDSHRT9N09D7","EDDSHRT9N09D8","EDDSHRT9N09D9","EDDSHRT9N10D1","EDDSHRT9N10D2","EDDSHRT9N10D3", & + "EDDSHRT9N10D4","EDDSHRT9N10D5","EDDSHRT9N10D6","EDDSHRT9N10D7","EDDSHRT9N10D8","EDDSHRT9N10D9", & + "EDDSHRT9N11D1","EDDSHRT9N11D2","EDDSHRT9N11D3","EDDSHRT9N11D4","EDDSHRT9N11D5","EDDSHRT9N11D6", & + "EDDSHRT9N11D7","EDDSHRT9N11D8","EDDSHRT9N11D9","EDDSHRT9N12D1","EDDSHRT9N12D2","EDDSHRT9N12D3", & + "EDDSHRT9N12D4","EDDSHRT9N12D5","EDDSHRT9N12D6","EDDSHRT9N12D7","EDDSHRT9N12D8","EDDSHRT9N12D9", & + "EDDSHRT9N13D1","EDDSHRT9N13D2","EDDSHRT9N13D3","EDDSHRT9N13D4","EDDSHRT9N13D5","EDDSHRT9N13D6", & + "EDDSHRT9N13D7","EDDSHRT9N13D8","EDDSHRT9N13D9","EDDSHRT9N14D1","EDDSHRT9N14D2","EDDSHRT9N14D3", & + "EDDSHRT9N14D4","EDDSHRT9N14D5","EDDSHRT9N14D6","EDDSHRT9N14D7","EDDSHRT9N14D8","EDDSHRT9N14D9", & + "EDDSHRT9N15D1","EDDSHRT9N15D2","EDDSHRT9N15D3","EDDSHRT9N15D4","EDDSHRT9N15D5","EDDSHRT9N15D6", & + "EDDSHRT9N15D7","EDDSHRT9N15D8","EDDSHRT9N15D9","EDDSHRT9N16D1","EDDSHRT9N16D2","EDDSHRT9N16D3", & + "EDDSHRT9N16D4","EDDSHRT9N16D5","EDDSHRT9N16D6","EDDSHRT9N16D7","EDDSHRT9N16D8","EDDSHRT9N16D9", & + "EDDSHRT9N17D1","EDDSHRT9N17D2","EDDSHRT9N17D3","EDDSHRT9N17D4","EDDSHRT9N17D5","EDDSHRT9N17D6", & + "EDDSHRT9N17D7","EDDSHRT9N17D8","EDDSHRT9N17D9","EDDSHRT9N18D1","EDDSHRT9N18D2","EDDSHRT9N18D3", & + "EDDSHRT9N18D4","EDDSHRT9N18D5","EDDSHRT9N18D6","EDDSHRT9N18D7","EDDSHRT9N18D8","EDDSHRT9N18D9", & + "EDDSHRT9N19D1","EDDSHRT9N19D2","EDDSHRT9N19D3","EDDSHRT9N19D4","EDDSHRT9N19D5","EDDSHRT9N19D6", & + "EDDSHRT9N19D7","EDDSHRT9N19D8","EDDSHRT9N19D9","EDDSHRT9N20D1","EDDSHRT9N20D2","EDDSHRT9N20D3", & + "EDDSHRT9N20D4","EDDSHRT9N20D5","EDDSHRT9N20D6","EDDSHRT9N20D7","EDDSHRT9N20D8","EDDSHRT9N20D9", & + "EDDVIST1N01D1","EDDVIST1N01D2","EDDVIST1N01D3","EDDVIST1N01D4","EDDVIST1N01D5","EDDVIST1N01D6", & + "EDDVIST1N01D7","EDDVIST1N01D8","EDDVIST1N01D9","EDDVIST1N02D1","EDDVIST1N02D2","EDDVIST1N02D3", & + "EDDVIST1N02D4","EDDVIST1N02D5","EDDVIST1N02D6","EDDVIST1N02D7","EDDVIST1N02D8","EDDVIST1N02D9", & + "EDDVIST1N03D1","EDDVIST1N03D2","EDDVIST1N03D3","EDDVIST1N03D4","EDDVIST1N03D5","EDDVIST1N03D6", & + "EDDVIST1N03D7","EDDVIST1N03D8","EDDVIST1N03D9","EDDVIST1N04D1","EDDVIST1N04D2","EDDVIST1N04D3", & + "EDDVIST1N04D4","EDDVIST1N04D5","EDDVIST1N04D6","EDDVIST1N04D7","EDDVIST1N04D8","EDDVIST1N04D9", & + "EDDVIST1N05D1","EDDVIST1N05D2","EDDVIST1N05D3","EDDVIST1N05D4","EDDVIST1N05D5","EDDVIST1N05D6", & + "EDDVIST1N05D7","EDDVIST1N05D8","EDDVIST1N05D9","EDDVIST1N06D1","EDDVIST1N06D2","EDDVIST1N06D3", & + "EDDVIST1N06D4","EDDVIST1N06D5","EDDVIST1N06D6","EDDVIST1N06D7","EDDVIST1N06D8","EDDVIST1N06D9", & + "EDDVIST1N07D1","EDDVIST1N07D2","EDDVIST1N07D3","EDDVIST1N07D4","EDDVIST1N07D5","EDDVIST1N07D6", & + "EDDVIST1N07D7","EDDVIST1N07D8","EDDVIST1N07D9","EDDVIST1N08D1","EDDVIST1N08D2","EDDVIST1N08D3", & + "EDDVIST1N08D4","EDDVIST1N08D5","EDDVIST1N08D6","EDDVIST1N08D7","EDDVIST1N08D8","EDDVIST1N08D9", & + "EDDVIST1N09D1","EDDVIST1N09D2","EDDVIST1N09D3","EDDVIST1N09D4","EDDVIST1N09D5","EDDVIST1N09D6", & + "EDDVIST1N09D7","EDDVIST1N09D8","EDDVIST1N09D9","EDDVIST1N10D1","EDDVIST1N10D2","EDDVIST1N10D3", & + "EDDVIST1N10D4","EDDVIST1N10D5","EDDVIST1N10D6","EDDVIST1N10D7","EDDVIST1N10D8","EDDVIST1N10D9", & + "EDDVIST1N11D1","EDDVIST1N11D2","EDDVIST1N11D3","EDDVIST1N11D4","EDDVIST1N11D5","EDDVIST1N11D6", & + "EDDVIST1N11D7","EDDVIST1N11D8","EDDVIST1N11D9","EDDVIST1N12D1","EDDVIST1N12D2","EDDVIST1N12D3", & + "EDDVIST1N12D4","EDDVIST1N12D5","EDDVIST1N12D6","EDDVIST1N12D7","EDDVIST1N12D8","EDDVIST1N12D9", & + "EDDVIST1N13D1","EDDVIST1N13D2","EDDVIST1N13D3","EDDVIST1N13D4","EDDVIST1N13D5","EDDVIST1N13D6", & + "EDDVIST1N13D7","EDDVIST1N13D8","EDDVIST1N13D9","EDDVIST1N14D1","EDDVIST1N14D2","EDDVIST1N14D3", & + "EDDVIST1N14D4","EDDVIST1N14D5","EDDVIST1N14D6","EDDVIST1N14D7","EDDVIST1N14D8","EDDVIST1N14D9", & + "EDDVIST1N15D1","EDDVIST1N15D2","EDDVIST1N15D3","EDDVIST1N15D4","EDDVIST1N15D5","EDDVIST1N15D6", & + "EDDVIST1N15D7","EDDVIST1N15D8","EDDVIST1N15D9","EDDVIST1N16D1","EDDVIST1N16D2","EDDVIST1N16D3", & + "EDDVIST1N16D4","EDDVIST1N16D5","EDDVIST1N16D6","EDDVIST1N16D7","EDDVIST1N16D8","EDDVIST1N16D9", & + "EDDVIST1N17D1","EDDVIST1N17D2","EDDVIST1N17D3","EDDVIST1N17D4","EDDVIST1N17D5","EDDVIST1N17D6", & + "EDDVIST1N17D7","EDDVIST1N17D8","EDDVIST1N17D9","EDDVIST1N18D1","EDDVIST1N18D2","EDDVIST1N18D3", & + "EDDVIST1N18D4","EDDVIST1N18D5","EDDVIST1N18D6","EDDVIST1N18D7","EDDVIST1N18D8","EDDVIST1N18D9", & + "EDDVIST1N19D1","EDDVIST1N19D2","EDDVIST1N19D3","EDDVIST1N19D4","EDDVIST1N19D5","EDDVIST1N19D6", & + "EDDVIST1N19D7","EDDVIST1N19D8","EDDVIST1N19D9","EDDVIST1N20D1","EDDVIST1N20D2","EDDVIST1N20D3", & + "EDDVIST1N20D4","EDDVIST1N20D5","EDDVIST1N20D6","EDDVIST1N20D7","EDDVIST1N20D8","EDDVIST1N20D9", & + "EDDVIST2N01D1","EDDVIST2N01D2","EDDVIST2N01D3","EDDVIST2N01D4","EDDVIST2N01D5","EDDVIST2N01D6", & + "EDDVIST2N01D7","EDDVIST2N01D8","EDDVIST2N01D9","EDDVIST2N02D1","EDDVIST2N02D2","EDDVIST2N02D3", & + "EDDVIST2N02D4","EDDVIST2N02D5","EDDVIST2N02D6","EDDVIST2N02D7","EDDVIST2N02D8","EDDVIST2N02D9", & + "EDDVIST2N03D1","EDDVIST2N03D2","EDDVIST2N03D3","EDDVIST2N03D4","EDDVIST2N03D5","EDDVIST2N03D6", & + "EDDVIST2N03D7","EDDVIST2N03D8","EDDVIST2N03D9","EDDVIST2N04D1","EDDVIST2N04D2","EDDVIST2N04D3", & + "EDDVIST2N04D4","EDDVIST2N04D5","EDDVIST2N04D6","EDDVIST2N04D7","EDDVIST2N04D8","EDDVIST2N04D9", & + "EDDVIST2N05D1","EDDVIST2N05D2","EDDVIST2N05D3","EDDVIST2N05D4","EDDVIST2N05D5","EDDVIST2N05D6", & + "EDDVIST2N05D7","EDDVIST2N05D8","EDDVIST2N05D9","EDDVIST2N06D1","EDDVIST2N06D2","EDDVIST2N06D3", & + "EDDVIST2N06D4","EDDVIST2N06D5","EDDVIST2N06D6","EDDVIST2N06D7","EDDVIST2N06D8","EDDVIST2N06D9", & + "EDDVIST2N07D1","EDDVIST2N07D2","EDDVIST2N07D3","EDDVIST2N07D4","EDDVIST2N07D5","EDDVIST2N07D6", & + "EDDVIST2N07D7","EDDVIST2N07D8","EDDVIST2N07D9","EDDVIST2N08D1","EDDVIST2N08D2","EDDVIST2N08D3", & + "EDDVIST2N08D4","EDDVIST2N08D5","EDDVIST2N08D6","EDDVIST2N08D7","EDDVIST2N08D8","EDDVIST2N08D9", & + "EDDVIST2N09D1","EDDVIST2N09D2","EDDVIST2N09D3","EDDVIST2N09D4","EDDVIST2N09D5","EDDVIST2N09D6", & + "EDDVIST2N09D7","EDDVIST2N09D8","EDDVIST2N09D9","EDDVIST2N10D1","EDDVIST2N10D2","EDDVIST2N10D3", & + "EDDVIST2N10D4","EDDVIST2N10D5","EDDVIST2N10D6","EDDVIST2N10D7","EDDVIST2N10D8","EDDVIST2N10D9", & + "EDDVIST2N11D1","EDDVIST2N11D2","EDDVIST2N11D3","EDDVIST2N11D4","EDDVIST2N11D5","EDDVIST2N11D6", & + "EDDVIST2N11D7","EDDVIST2N11D8","EDDVIST2N11D9","EDDVIST2N12D1","EDDVIST2N12D2","EDDVIST2N12D3", & + "EDDVIST2N12D4","EDDVIST2N12D5","EDDVIST2N12D6","EDDVIST2N12D7","EDDVIST2N12D8","EDDVIST2N12D9", & + "EDDVIST2N13D1","EDDVIST2N13D2","EDDVIST2N13D3","EDDVIST2N13D4","EDDVIST2N13D5","EDDVIST2N13D6", & + "EDDVIST2N13D7","EDDVIST2N13D8","EDDVIST2N13D9","EDDVIST2N14D1","EDDVIST2N14D2","EDDVIST2N14D3", & + "EDDVIST2N14D4","EDDVIST2N14D5","EDDVIST2N14D6","EDDVIST2N14D7","EDDVIST2N14D8","EDDVIST2N14D9", & + "EDDVIST2N15D1","EDDVIST2N15D2","EDDVIST2N15D3","EDDVIST2N15D4","EDDVIST2N15D5","EDDVIST2N15D6", & + "EDDVIST2N15D7","EDDVIST2N15D8","EDDVIST2N15D9","EDDVIST2N16D1","EDDVIST2N16D2","EDDVIST2N16D3", & + "EDDVIST2N16D4","EDDVIST2N16D5","EDDVIST2N16D6","EDDVIST2N16D7","EDDVIST2N16D8","EDDVIST2N16D9", & + "EDDVIST2N17D1","EDDVIST2N17D2","EDDVIST2N17D3","EDDVIST2N17D4","EDDVIST2N17D5","EDDVIST2N17D6", & + "EDDVIST2N17D7","EDDVIST2N17D8","EDDVIST2N17D9","EDDVIST2N18D1","EDDVIST2N18D2","EDDVIST2N18D3", & + "EDDVIST2N18D4","EDDVIST2N18D5","EDDVIST2N18D6","EDDVIST2N18D7","EDDVIST2N18D8","EDDVIST2N18D9", & + "EDDVIST2N19D1","EDDVIST2N19D2","EDDVIST2N19D3","EDDVIST2N19D4","EDDVIST2N19D5","EDDVIST2N19D6", & + "EDDVIST2N19D7","EDDVIST2N19D8","EDDVIST2N19D9","EDDVIST2N20D1","EDDVIST2N20D2","EDDVIST2N20D3", & + "EDDVIST2N20D4","EDDVIST2N20D5","EDDVIST2N20D6","EDDVIST2N20D7","EDDVIST2N20D8","EDDVIST2N20D9", & + "EDDVIST3N01D1","EDDVIST3N01D2","EDDVIST3N01D3","EDDVIST3N01D4","EDDVIST3N01D5","EDDVIST3N01D6", & + "EDDVIST3N01D7","EDDVIST3N01D8","EDDVIST3N01D9","EDDVIST3N02D1","EDDVIST3N02D2","EDDVIST3N02D3", & + "EDDVIST3N02D4","EDDVIST3N02D5","EDDVIST3N02D6","EDDVIST3N02D7","EDDVIST3N02D8","EDDVIST3N02D9", & + "EDDVIST3N03D1","EDDVIST3N03D2","EDDVIST3N03D3","EDDVIST3N03D4","EDDVIST3N03D5","EDDVIST3N03D6", & + "EDDVIST3N03D7","EDDVIST3N03D8","EDDVIST3N03D9","EDDVIST3N04D1","EDDVIST3N04D2","EDDVIST3N04D3", & + "EDDVIST3N04D4","EDDVIST3N04D5","EDDVIST3N04D6","EDDVIST3N04D7","EDDVIST3N04D8","EDDVIST3N04D9", & + "EDDVIST3N05D1","EDDVIST3N05D2","EDDVIST3N05D3","EDDVIST3N05D4","EDDVIST3N05D5","EDDVIST3N05D6", & + "EDDVIST3N05D7","EDDVIST3N05D8","EDDVIST3N05D9","EDDVIST3N06D1","EDDVIST3N06D2","EDDVIST3N06D3", & + "EDDVIST3N06D4","EDDVIST3N06D5","EDDVIST3N06D6","EDDVIST3N06D7","EDDVIST3N06D8","EDDVIST3N06D9", & + "EDDVIST3N07D1","EDDVIST3N07D2","EDDVIST3N07D3","EDDVIST3N07D4","EDDVIST3N07D5","EDDVIST3N07D6", & + "EDDVIST3N07D7","EDDVIST3N07D8","EDDVIST3N07D9","EDDVIST3N08D1","EDDVIST3N08D2","EDDVIST3N08D3", & + "EDDVIST3N08D4","EDDVIST3N08D5","EDDVIST3N08D6","EDDVIST3N08D7","EDDVIST3N08D8","EDDVIST3N08D9", & + "EDDVIST3N09D1","EDDVIST3N09D2","EDDVIST3N09D3","EDDVIST3N09D4","EDDVIST3N09D5","EDDVIST3N09D6", & + "EDDVIST3N09D7","EDDVIST3N09D8","EDDVIST3N09D9","EDDVIST3N10D1","EDDVIST3N10D2","EDDVIST3N10D3", & + "EDDVIST3N10D4","EDDVIST3N10D5","EDDVIST3N10D6","EDDVIST3N10D7","EDDVIST3N10D8","EDDVIST3N10D9", & + "EDDVIST3N11D1","EDDVIST3N11D2","EDDVIST3N11D3","EDDVIST3N11D4","EDDVIST3N11D5","EDDVIST3N11D6", & + "EDDVIST3N11D7","EDDVIST3N11D8","EDDVIST3N11D9","EDDVIST3N12D1","EDDVIST3N12D2","EDDVIST3N12D3", & + "EDDVIST3N12D4","EDDVIST3N12D5","EDDVIST3N12D6","EDDVIST3N12D7","EDDVIST3N12D8","EDDVIST3N12D9", & + "EDDVIST3N13D1","EDDVIST3N13D2","EDDVIST3N13D3","EDDVIST3N13D4","EDDVIST3N13D5","EDDVIST3N13D6", & + "EDDVIST3N13D7","EDDVIST3N13D8","EDDVIST3N13D9","EDDVIST3N14D1","EDDVIST3N14D2","EDDVIST3N14D3", & + "EDDVIST3N14D4","EDDVIST3N14D5","EDDVIST3N14D6","EDDVIST3N14D7","EDDVIST3N14D8","EDDVIST3N14D9", & + "EDDVIST3N15D1","EDDVIST3N15D2","EDDVIST3N15D3","EDDVIST3N15D4","EDDVIST3N15D5","EDDVIST3N15D6", & + "EDDVIST3N15D7","EDDVIST3N15D8","EDDVIST3N15D9","EDDVIST3N16D1","EDDVIST3N16D2","EDDVIST3N16D3", & + "EDDVIST3N16D4","EDDVIST3N16D5","EDDVIST3N16D6","EDDVIST3N16D7","EDDVIST3N16D8","EDDVIST3N16D9", & + "EDDVIST3N17D1","EDDVIST3N17D2","EDDVIST3N17D3","EDDVIST3N17D4","EDDVIST3N17D5","EDDVIST3N17D6", & + "EDDVIST3N17D7","EDDVIST3N17D8","EDDVIST3N17D9","EDDVIST3N18D1","EDDVIST3N18D2","EDDVIST3N18D3", & + "EDDVIST3N18D4","EDDVIST3N18D5","EDDVIST3N18D6","EDDVIST3N18D7","EDDVIST3N18D8","EDDVIST3N18D9", & + "EDDVIST3N19D1","EDDVIST3N19D2","EDDVIST3N19D3","EDDVIST3N19D4","EDDVIST3N19D5","EDDVIST3N19D6", & + "EDDVIST3N19D7","EDDVIST3N19D8","EDDVIST3N19D9","EDDVIST3N20D1","EDDVIST3N20D2","EDDVIST3N20D3", & + "EDDVIST3N20D4","EDDVIST3N20D5","EDDVIST3N20D6","EDDVIST3N20D7","EDDVIST3N20D8","EDDVIST3N20D9", & + "EDDVIST4N01D1","EDDVIST4N01D2","EDDVIST4N01D3","EDDVIST4N01D4","EDDVIST4N01D5","EDDVIST4N01D6", & + "EDDVIST4N01D7","EDDVIST4N01D8","EDDVIST4N01D9","EDDVIST4N02D1","EDDVIST4N02D2","EDDVIST4N02D3", & + "EDDVIST4N02D4","EDDVIST4N02D5","EDDVIST4N02D6","EDDVIST4N02D7","EDDVIST4N02D8","EDDVIST4N02D9", & + "EDDVIST4N03D1","EDDVIST4N03D2","EDDVIST4N03D3","EDDVIST4N03D4","EDDVIST4N03D5","EDDVIST4N03D6", & + "EDDVIST4N03D7","EDDVIST4N03D8","EDDVIST4N03D9","EDDVIST4N04D1","EDDVIST4N04D2","EDDVIST4N04D3", & + "EDDVIST4N04D4","EDDVIST4N04D5","EDDVIST4N04D6","EDDVIST4N04D7","EDDVIST4N04D8","EDDVIST4N04D9", & + "EDDVIST4N05D1","EDDVIST4N05D2","EDDVIST4N05D3","EDDVIST4N05D4","EDDVIST4N05D5","EDDVIST4N05D6", & + "EDDVIST4N05D7","EDDVIST4N05D8","EDDVIST4N05D9","EDDVIST4N06D1","EDDVIST4N06D2","EDDVIST4N06D3", & + "EDDVIST4N06D4","EDDVIST4N06D5","EDDVIST4N06D6","EDDVIST4N06D7","EDDVIST4N06D8","EDDVIST4N06D9", & + "EDDVIST4N07D1","EDDVIST4N07D2","EDDVIST4N07D3","EDDVIST4N07D4","EDDVIST4N07D5","EDDVIST4N07D6", & + "EDDVIST4N07D7","EDDVIST4N07D8","EDDVIST4N07D9","EDDVIST4N08D1","EDDVIST4N08D2","EDDVIST4N08D3", & + "EDDVIST4N08D4","EDDVIST4N08D5","EDDVIST4N08D6","EDDVIST4N08D7","EDDVIST4N08D8","EDDVIST4N08D9", & + "EDDVIST4N09D1","EDDVIST4N09D2","EDDVIST4N09D3","EDDVIST4N09D4","EDDVIST4N09D5","EDDVIST4N09D6", & + "EDDVIST4N09D7","EDDVIST4N09D8","EDDVIST4N09D9","EDDVIST4N10D1","EDDVIST4N10D2","EDDVIST4N10D3", & + "EDDVIST4N10D4","EDDVIST4N10D5","EDDVIST4N10D6","EDDVIST4N10D7","EDDVIST4N10D8","EDDVIST4N10D9"/) + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry4(1356) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "EDDVIST4N11D1","EDDVIST4N11D2","EDDVIST4N11D3","EDDVIST4N11D4","EDDVIST4N11D5","EDDVIST4N11D6", & + "EDDVIST4N11D7","EDDVIST4N11D8","EDDVIST4N11D9","EDDVIST4N12D1","EDDVIST4N12D2","EDDVIST4N12D3", & + "EDDVIST4N12D4","EDDVIST4N12D5","EDDVIST4N12D6","EDDVIST4N12D7","EDDVIST4N12D8","EDDVIST4N12D9", & + "EDDVIST4N13D1","EDDVIST4N13D2","EDDVIST4N13D3","EDDVIST4N13D4","EDDVIST4N13D5","EDDVIST4N13D6", & + "EDDVIST4N13D7","EDDVIST4N13D8","EDDVIST4N13D9","EDDVIST4N14D1","EDDVIST4N14D2","EDDVIST4N14D3", & + "EDDVIST4N14D4","EDDVIST4N14D5","EDDVIST4N14D6","EDDVIST4N14D7","EDDVIST4N14D8","EDDVIST4N14D9", & + "EDDVIST4N15D1","EDDVIST4N15D2","EDDVIST4N15D3","EDDVIST4N15D4","EDDVIST4N15D5","EDDVIST4N15D6", & + "EDDVIST4N15D7","EDDVIST4N15D8","EDDVIST4N15D9","EDDVIST4N16D1","EDDVIST4N16D2","EDDVIST4N16D3", & + "EDDVIST4N16D4","EDDVIST4N16D5","EDDVIST4N16D6","EDDVIST4N16D7","EDDVIST4N16D8","EDDVIST4N16D9", & + "EDDVIST4N17D1","EDDVIST4N17D2","EDDVIST4N17D3","EDDVIST4N17D4","EDDVIST4N17D5","EDDVIST4N17D6", & + "EDDVIST4N17D7","EDDVIST4N17D8","EDDVIST4N17D9","EDDVIST4N18D1","EDDVIST4N18D2","EDDVIST4N18D3", & + "EDDVIST4N18D4","EDDVIST4N18D5","EDDVIST4N18D6","EDDVIST4N18D7","EDDVIST4N18D8","EDDVIST4N18D9", & + "EDDVIST4N19D1","EDDVIST4N19D2","EDDVIST4N19D3","EDDVIST4N19D4","EDDVIST4N19D5","EDDVIST4N19D6", & + "EDDVIST4N19D7","EDDVIST4N19D8","EDDVIST4N19D9","EDDVIST4N20D1","EDDVIST4N20D2","EDDVIST4N20D3", & + "EDDVIST4N20D4","EDDVIST4N20D5","EDDVIST4N20D6","EDDVIST4N20D7","EDDVIST4N20D8","EDDVIST4N20D9", & + "EDDVIST5N01D1","EDDVIST5N01D2","EDDVIST5N01D3","EDDVIST5N01D4","EDDVIST5N01D5","EDDVIST5N01D6", & + "EDDVIST5N01D7","EDDVIST5N01D8","EDDVIST5N01D9","EDDVIST5N02D1","EDDVIST5N02D2","EDDVIST5N02D3", & + "EDDVIST5N02D4","EDDVIST5N02D5","EDDVIST5N02D6","EDDVIST5N02D7","EDDVIST5N02D8","EDDVIST5N02D9", & + "EDDVIST5N03D1","EDDVIST5N03D2","EDDVIST5N03D3","EDDVIST5N03D4","EDDVIST5N03D5","EDDVIST5N03D6", & + "EDDVIST5N03D7","EDDVIST5N03D8","EDDVIST5N03D9","EDDVIST5N04D1","EDDVIST5N04D2","EDDVIST5N04D3", & + "EDDVIST5N04D4","EDDVIST5N04D5","EDDVIST5N04D6","EDDVIST5N04D7","EDDVIST5N04D8","EDDVIST5N04D9", & + "EDDVIST5N05D1","EDDVIST5N05D2","EDDVIST5N05D3","EDDVIST5N05D4","EDDVIST5N05D5","EDDVIST5N05D6", & + "EDDVIST5N05D7","EDDVIST5N05D8","EDDVIST5N05D9","EDDVIST5N06D1","EDDVIST5N06D2","EDDVIST5N06D3", & + "EDDVIST5N06D4","EDDVIST5N06D5","EDDVIST5N06D6","EDDVIST5N06D7","EDDVIST5N06D8","EDDVIST5N06D9", & + "EDDVIST5N07D1","EDDVIST5N07D2","EDDVIST5N07D3","EDDVIST5N07D4","EDDVIST5N07D5","EDDVIST5N07D6", & + "EDDVIST5N07D7","EDDVIST5N07D8","EDDVIST5N07D9","EDDVIST5N08D1","EDDVIST5N08D2","EDDVIST5N08D3", & + "EDDVIST5N08D4","EDDVIST5N08D5","EDDVIST5N08D6","EDDVIST5N08D7","EDDVIST5N08D8","EDDVIST5N08D9", & + "EDDVIST5N09D1","EDDVIST5N09D2","EDDVIST5N09D3","EDDVIST5N09D4","EDDVIST5N09D5","EDDVIST5N09D6", & + "EDDVIST5N09D7","EDDVIST5N09D8","EDDVIST5N09D9","EDDVIST5N10D1","EDDVIST5N10D2","EDDVIST5N10D3", & + "EDDVIST5N10D4","EDDVIST5N10D5","EDDVIST5N10D6","EDDVIST5N10D7","EDDVIST5N10D8","EDDVIST5N10D9", & + "EDDVIST5N11D1","EDDVIST5N11D2","EDDVIST5N11D3","EDDVIST5N11D4","EDDVIST5N11D5","EDDVIST5N11D6", & + "EDDVIST5N11D7","EDDVIST5N11D8","EDDVIST5N11D9","EDDVIST5N12D1","EDDVIST5N12D2","EDDVIST5N12D3", & + "EDDVIST5N12D4","EDDVIST5N12D5","EDDVIST5N12D6","EDDVIST5N12D7","EDDVIST5N12D8","EDDVIST5N12D9", & + "EDDVIST5N13D1","EDDVIST5N13D2","EDDVIST5N13D3","EDDVIST5N13D4","EDDVIST5N13D5","EDDVIST5N13D6", & + "EDDVIST5N13D7","EDDVIST5N13D8","EDDVIST5N13D9","EDDVIST5N14D1","EDDVIST5N14D2","EDDVIST5N14D3", & + "EDDVIST5N14D4","EDDVIST5N14D5","EDDVIST5N14D6","EDDVIST5N14D7","EDDVIST5N14D8","EDDVIST5N14D9", & + "EDDVIST5N15D1","EDDVIST5N15D2","EDDVIST5N15D3","EDDVIST5N15D4","EDDVIST5N15D5","EDDVIST5N15D6", & + "EDDVIST5N15D7","EDDVIST5N15D8","EDDVIST5N15D9","EDDVIST5N16D1","EDDVIST5N16D2","EDDVIST5N16D3", & + "EDDVIST5N16D4","EDDVIST5N16D5","EDDVIST5N16D6","EDDVIST5N16D7","EDDVIST5N16D8","EDDVIST5N16D9", & + "EDDVIST5N17D1","EDDVIST5N17D2","EDDVIST5N17D3","EDDVIST5N17D4","EDDVIST5N17D5","EDDVIST5N17D6", & + "EDDVIST5N17D7","EDDVIST5N17D8","EDDVIST5N17D9","EDDVIST5N18D1","EDDVIST5N18D2","EDDVIST5N18D3", & + "EDDVIST5N18D4","EDDVIST5N18D5","EDDVIST5N18D6","EDDVIST5N18D7","EDDVIST5N18D8","EDDVIST5N18D9", & + "EDDVIST5N19D1","EDDVIST5N19D2","EDDVIST5N19D3","EDDVIST5N19D4","EDDVIST5N19D5","EDDVIST5N19D6", & + "EDDVIST5N19D7","EDDVIST5N19D8","EDDVIST5N19D9","EDDVIST5N20D1","EDDVIST5N20D2","EDDVIST5N20D3", & + "EDDVIST5N20D4","EDDVIST5N20D5","EDDVIST5N20D6","EDDVIST5N20D7","EDDVIST5N20D8","EDDVIST5N20D9", & + "EDDVIST6N01D1","EDDVIST6N01D2","EDDVIST6N01D3","EDDVIST6N01D4","EDDVIST6N01D5","EDDVIST6N01D6", & + "EDDVIST6N01D7","EDDVIST6N01D8","EDDVIST6N01D9","EDDVIST6N02D1","EDDVIST6N02D2","EDDVIST6N02D3", & + "EDDVIST6N02D4","EDDVIST6N02D5","EDDVIST6N02D6","EDDVIST6N02D7","EDDVIST6N02D8","EDDVIST6N02D9", & + "EDDVIST6N03D1","EDDVIST6N03D2","EDDVIST6N03D3","EDDVIST6N03D4","EDDVIST6N03D5","EDDVIST6N03D6", & + "EDDVIST6N03D7","EDDVIST6N03D8","EDDVIST6N03D9","EDDVIST6N04D1","EDDVIST6N04D2","EDDVIST6N04D3", & + "EDDVIST6N04D4","EDDVIST6N04D5","EDDVIST6N04D6","EDDVIST6N04D7","EDDVIST6N04D8","EDDVIST6N04D9", & + "EDDVIST6N05D1","EDDVIST6N05D2","EDDVIST6N05D3","EDDVIST6N05D4","EDDVIST6N05D5","EDDVIST6N05D6", & + "EDDVIST6N05D7","EDDVIST6N05D8","EDDVIST6N05D9","EDDVIST6N06D1","EDDVIST6N06D2","EDDVIST6N06D3", & + "EDDVIST6N06D4","EDDVIST6N06D5","EDDVIST6N06D6","EDDVIST6N06D7","EDDVIST6N06D8","EDDVIST6N06D9", & + "EDDVIST6N07D1","EDDVIST6N07D2","EDDVIST6N07D3","EDDVIST6N07D4","EDDVIST6N07D5","EDDVIST6N07D6", & + "EDDVIST6N07D7","EDDVIST6N07D8","EDDVIST6N07D9","EDDVIST6N08D1","EDDVIST6N08D2","EDDVIST6N08D3", & + "EDDVIST6N08D4","EDDVIST6N08D5","EDDVIST6N08D6","EDDVIST6N08D7","EDDVIST6N08D8","EDDVIST6N08D9", & + "EDDVIST6N09D1","EDDVIST6N09D2","EDDVIST6N09D3","EDDVIST6N09D4","EDDVIST6N09D5","EDDVIST6N09D6", & + "EDDVIST6N09D7","EDDVIST6N09D8","EDDVIST6N09D9","EDDVIST6N10D1","EDDVIST6N10D2","EDDVIST6N10D3", & + "EDDVIST6N10D4","EDDVIST6N10D5","EDDVIST6N10D6","EDDVIST6N10D7","EDDVIST6N10D8","EDDVIST6N10D9", & + "EDDVIST6N11D1","EDDVIST6N11D2","EDDVIST6N11D3","EDDVIST6N11D4","EDDVIST6N11D5","EDDVIST6N11D6", & + "EDDVIST6N11D7","EDDVIST6N11D8","EDDVIST6N11D9","EDDVIST6N12D1","EDDVIST6N12D2","EDDVIST6N12D3", & + "EDDVIST6N12D4","EDDVIST6N12D5","EDDVIST6N12D6","EDDVIST6N12D7","EDDVIST6N12D8","EDDVIST6N12D9", & + "EDDVIST6N13D1","EDDVIST6N13D2","EDDVIST6N13D3","EDDVIST6N13D4","EDDVIST6N13D5","EDDVIST6N13D6", & + "EDDVIST6N13D7","EDDVIST6N13D8","EDDVIST6N13D9","EDDVIST6N14D1","EDDVIST6N14D2","EDDVIST6N14D3", & + "EDDVIST6N14D4","EDDVIST6N14D5","EDDVIST6N14D6","EDDVIST6N14D7","EDDVIST6N14D8","EDDVIST6N14D9", & + "EDDVIST6N15D1","EDDVIST6N15D2","EDDVIST6N15D3","EDDVIST6N15D4","EDDVIST6N15D5","EDDVIST6N15D6", & + "EDDVIST6N15D7","EDDVIST6N15D8","EDDVIST6N15D9","EDDVIST6N16D1","EDDVIST6N16D2","EDDVIST6N16D3", & + "EDDVIST6N16D4","EDDVIST6N16D5","EDDVIST6N16D6","EDDVIST6N16D7","EDDVIST6N16D8","EDDVIST6N16D9", & + "EDDVIST6N17D1","EDDVIST6N17D2","EDDVIST6N17D3","EDDVIST6N17D4","EDDVIST6N17D5","EDDVIST6N17D6", & + "EDDVIST6N17D7","EDDVIST6N17D8","EDDVIST6N17D9","EDDVIST6N18D1","EDDVIST6N18D2","EDDVIST6N18D3", & + "EDDVIST6N18D4","EDDVIST6N18D5","EDDVIST6N18D6","EDDVIST6N18D7","EDDVIST6N18D8","EDDVIST6N18D9", & + "EDDVIST6N19D1","EDDVIST6N19D2","EDDVIST6N19D3","EDDVIST6N19D4","EDDVIST6N19D5","EDDVIST6N19D6", & + "EDDVIST6N19D7","EDDVIST6N19D8","EDDVIST6N19D9","EDDVIST6N20D1","EDDVIST6N20D2","EDDVIST6N20D3", & + "EDDVIST6N20D4","EDDVIST6N20D5","EDDVIST6N20D6","EDDVIST6N20D7","EDDVIST6N20D8","EDDVIST6N20D9", & + "EDDVIST7N01D1","EDDVIST7N01D2","EDDVIST7N01D3","EDDVIST7N01D4","EDDVIST7N01D5","EDDVIST7N01D6", & + "EDDVIST7N01D7","EDDVIST7N01D8","EDDVIST7N01D9","EDDVIST7N02D1","EDDVIST7N02D2","EDDVIST7N02D3", & + "EDDVIST7N02D4","EDDVIST7N02D5","EDDVIST7N02D6","EDDVIST7N02D7","EDDVIST7N02D8","EDDVIST7N02D9", & + "EDDVIST7N03D1","EDDVIST7N03D2","EDDVIST7N03D3","EDDVIST7N03D4","EDDVIST7N03D5","EDDVIST7N03D6", & + "EDDVIST7N03D7","EDDVIST7N03D8","EDDVIST7N03D9","EDDVIST7N04D1","EDDVIST7N04D2","EDDVIST7N04D3", & + "EDDVIST7N04D4","EDDVIST7N04D5","EDDVIST7N04D6","EDDVIST7N04D7","EDDVIST7N04D8","EDDVIST7N04D9", & + "EDDVIST7N05D1","EDDVIST7N05D2","EDDVIST7N05D3","EDDVIST7N05D4","EDDVIST7N05D5","EDDVIST7N05D6", & + "EDDVIST7N05D7","EDDVIST7N05D8","EDDVIST7N05D9","EDDVIST7N06D1","EDDVIST7N06D2","EDDVIST7N06D3", & + "EDDVIST7N06D4","EDDVIST7N06D5","EDDVIST7N06D6","EDDVIST7N06D7","EDDVIST7N06D8","EDDVIST7N06D9", & + "EDDVIST7N07D1","EDDVIST7N07D2","EDDVIST7N07D3","EDDVIST7N07D4","EDDVIST7N07D5","EDDVIST7N07D6", & + "EDDVIST7N07D7","EDDVIST7N07D8","EDDVIST7N07D9","EDDVIST7N08D1","EDDVIST7N08D2","EDDVIST7N08D3", & + "EDDVIST7N08D4","EDDVIST7N08D5","EDDVIST7N08D6","EDDVIST7N08D7","EDDVIST7N08D8","EDDVIST7N08D9", & + "EDDVIST7N09D1","EDDVIST7N09D2","EDDVIST7N09D3","EDDVIST7N09D4","EDDVIST7N09D5","EDDVIST7N09D6", & + "EDDVIST7N09D7","EDDVIST7N09D8","EDDVIST7N09D9","EDDVIST7N10D1","EDDVIST7N10D2","EDDVIST7N10D3", & + "EDDVIST7N10D4","EDDVIST7N10D5","EDDVIST7N10D6","EDDVIST7N10D7","EDDVIST7N10D8","EDDVIST7N10D9", & + "EDDVIST7N11D1","EDDVIST7N11D2","EDDVIST7N11D3","EDDVIST7N11D4","EDDVIST7N11D5","EDDVIST7N11D6", & + "EDDVIST7N11D7","EDDVIST7N11D8","EDDVIST7N11D9","EDDVIST7N12D1","EDDVIST7N12D2","EDDVIST7N12D3", & + "EDDVIST7N12D4","EDDVIST7N12D5","EDDVIST7N12D6","EDDVIST7N12D7","EDDVIST7N12D8","EDDVIST7N12D9", & + "EDDVIST7N13D1","EDDVIST7N13D2","EDDVIST7N13D3","EDDVIST7N13D4","EDDVIST7N13D5","EDDVIST7N13D6", & + "EDDVIST7N13D7","EDDVIST7N13D8","EDDVIST7N13D9","EDDVIST7N14D1","EDDVIST7N14D2","EDDVIST7N14D3", & + "EDDVIST7N14D4","EDDVIST7N14D5","EDDVIST7N14D6","EDDVIST7N14D7","EDDVIST7N14D8","EDDVIST7N14D9", & + "EDDVIST7N15D1","EDDVIST7N15D2","EDDVIST7N15D3","EDDVIST7N15D4","EDDVIST7N15D5","EDDVIST7N15D6", & + "EDDVIST7N15D7","EDDVIST7N15D8","EDDVIST7N15D9","EDDVIST7N16D1","EDDVIST7N16D2","EDDVIST7N16D3", & + "EDDVIST7N16D4","EDDVIST7N16D5","EDDVIST7N16D6","EDDVIST7N16D7","EDDVIST7N16D8","EDDVIST7N16D9", & + "EDDVIST7N17D1","EDDVIST7N17D2","EDDVIST7N17D3","EDDVIST7N17D4","EDDVIST7N17D5","EDDVIST7N17D6", & + "EDDVIST7N17D7","EDDVIST7N17D8","EDDVIST7N17D9","EDDVIST7N18D1","EDDVIST7N18D2","EDDVIST7N18D3", & + "EDDVIST7N18D4","EDDVIST7N18D5","EDDVIST7N18D6","EDDVIST7N18D7","EDDVIST7N18D8","EDDVIST7N18D9", & + "EDDVIST7N19D1","EDDVIST7N19D2","EDDVIST7N19D3","EDDVIST7N19D4","EDDVIST7N19D5","EDDVIST7N19D6", & + "EDDVIST7N19D7","EDDVIST7N19D8","EDDVIST7N19D9","EDDVIST7N20D1","EDDVIST7N20D2","EDDVIST7N20D3", & + "EDDVIST7N20D4","EDDVIST7N20D5","EDDVIST7N20D6","EDDVIST7N20D7","EDDVIST7N20D8","EDDVIST7N20D9", & + "EDDVIST8N01D1","EDDVIST8N01D2","EDDVIST8N01D3","EDDVIST8N01D4","EDDVIST8N01D5","EDDVIST8N01D6", & + "EDDVIST8N01D7","EDDVIST8N01D8","EDDVIST8N01D9","EDDVIST8N02D1","EDDVIST8N02D2","EDDVIST8N02D3", & + "EDDVIST8N02D4","EDDVIST8N02D5","EDDVIST8N02D6","EDDVIST8N02D7","EDDVIST8N02D8","EDDVIST8N02D9", & + "EDDVIST8N03D1","EDDVIST8N03D2","EDDVIST8N03D3","EDDVIST8N03D4","EDDVIST8N03D5","EDDVIST8N03D6", & + "EDDVIST8N03D7","EDDVIST8N03D8","EDDVIST8N03D9","EDDVIST8N04D1","EDDVIST8N04D2","EDDVIST8N04D3", & + "EDDVIST8N04D4","EDDVIST8N04D5","EDDVIST8N04D6","EDDVIST8N04D7","EDDVIST8N04D8","EDDVIST8N04D9", & + "EDDVIST8N05D1","EDDVIST8N05D2","EDDVIST8N05D3","EDDVIST8N05D4","EDDVIST8N05D5","EDDVIST8N05D6", & + "EDDVIST8N05D7","EDDVIST8N05D8","EDDVIST8N05D9","EDDVIST8N06D1","EDDVIST8N06D2","EDDVIST8N06D3", & + "EDDVIST8N06D4","EDDVIST8N06D5","EDDVIST8N06D6","EDDVIST8N06D7","EDDVIST8N06D8","EDDVIST8N06D9", & + "EDDVIST8N07D1","EDDVIST8N07D2","EDDVIST8N07D3","EDDVIST8N07D4","EDDVIST8N07D5","EDDVIST8N07D6", & + "EDDVIST8N07D7","EDDVIST8N07D8","EDDVIST8N07D9","EDDVIST8N08D1","EDDVIST8N08D2","EDDVIST8N08D3", & + "EDDVIST8N08D4","EDDVIST8N08D5","EDDVIST8N08D6","EDDVIST8N08D7","EDDVIST8N08D8","EDDVIST8N08D9", & + "EDDVIST8N09D1","EDDVIST8N09D2","EDDVIST8N09D3","EDDVIST8N09D4","EDDVIST8N09D5","EDDVIST8N09D6", & + "EDDVIST8N09D7","EDDVIST8N09D8","EDDVIST8N09D9","EDDVIST8N10D1","EDDVIST8N10D2","EDDVIST8N10D3", & + "EDDVIST8N10D4","EDDVIST8N10D5","EDDVIST8N10D6","EDDVIST8N10D7","EDDVIST8N10D8","EDDVIST8N10D9", & + "EDDVIST8N11D1","EDDVIST8N11D2","EDDVIST8N11D3","EDDVIST8N11D4","EDDVIST8N11D5","EDDVIST8N11D6", & + "EDDVIST8N11D7","EDDVIST8N11D8","EDDVIST8N11D9","EDDVIST8N12D1","EDDVIST8N12D2","EDDVIST8N12D3", & + "EDDVIST8N12D4","EDDVIST8N12D5","EDDVIST8N12D6","EDDVIST8N12D7","EDDVIST8N12D8","EDDVIST8N12D9", & + "EDDVIST8N13D1","EDDVIST8N13D2","EDDVIST8N13D3","EDDVIST8N13D4","EDDVIST8N13D5","EDDVIST8N13D6", & + "EDDVIST8N13D7","EDDVIST8N13D8","EDDVIST8N13D9","EDDVIST8N14D1","EDDVIST8N14D2","EDDVIST8N14D3", & + "EDDVIST8N14D4","EDDVIST8N14D5","EDDVIST8N14D6","EDDVIST8N14D7","EDDVIST8N14D8","EDDVIST8N14D9", & + "EDDVIST8N15D1","EDDVIST8N15D2","EDDVIST8N15D3","EDDVIST8N15D4","EDDVIST8N15D5","EDDVIST8N15D6", & + "EDDVIST8N15D7","EDDVIST8N15D8","EDDVIST8N15D9","EDDVIST8N16D1","EDDVIST8N16D2","EDDVIST8N16D3", & + "EDDVIST8N16D4","EDDVIST8N16D5","EDDVIST8N16D6","EDDVIST8N16D7","EDDVIST8N16D8","EDDVIST8N16D9", & + "EDDVIST8N17D1","EDDVIST8N17D2","EDDVIST8N17D3","EDDVIST8N17D4","EDDVIST8N17D5","EDDVIST8N17D6", & + "EDDVIST8N17D7","EDDVIST8N17D8","EDDVIST8N17D9","EDDVIST8N18D1","EDDVIST8N18D2","EDDVIST8N18D3", & + "EDDVIST8N18D4","EDDVIST8N18D5","EDDVIST8N18D6","EDDVIST8N18D7","EDDVIST8N18D8","EDDVIST8N18D9", & + "EDDVIST8N19D1","EDDVIST8N19D2","EDDVIST8N19D3","EDDVIST8N19D4","EDDVIST8N19D5","EDDVIST8N19D6", & + "EDDVIST8N19D7","EDDVIST8N19D8","EDDVIST8N19D9","EDDVIST8N20D1","EDDVIST8N20D2","EDDVIST8N20D3", & + "EDDVIST8N20D4","EDDVIST8N20D5","EDDVIST8N20D6","EDDVIST8N20D7","EDDVIST8N20D8","EDDVIST8N20D9", & + "EDDVIST9N01D1","EDDVIST9N01D2","EDDVIST9N01D3","EDDVIST9N01D4","EDDVIST9N01D5","EDDVIST9N01D6", & + "EDDVIST9N01D7","EDDVIST9N01D8","EDDVIST9N01D9","EDDVIST9N02D1","EDDVIST9N02D2","EDDVIST9N02D3", & + "EDDVIST9N02D4","EDDVIST9N02D5","EDDVIST9N02D6","EDDVIST9N02D7","EDDVIST9N02D8","EDDVIST9N02D9", & + "EDDVIST9N03D1","EDDVIST9N03D2","EDDVIST9N03D3","EDDVIST9N03D4","EDDVIST9N03D5","EDDVIST9N03D6", & + "EDDVIST9N03D7","EDDVIST9N03D8","EDDVIST9N03D9","EDDVIST9N04D1","EDDVIST9N04D2","EDDVIST9N04D3", & + "EDDVIST9N04D4","EDDVIST9N04D5","EDDVIST9N04D6","EDDVIST9N04D7","EDDVIST9N04D8","EDDVIST9N04D9", & + "EDDVIST9N05D1","EDDVIST9N05D2","EDDVIST9N05D3","EDDVIST9N05D4","EDDVIST9N05D5","EDDVIST9N05D6", & + "EDDVIST9N05D7","EDDVIST9N05D8","EDDVIST9N05D9","EDDVIST9N06D1","EDDVIST9N06D2","EDDVIST9N06D3", & + "EDDVIST9N06D4","EDDVIST9N06D5","EDDVIST9N06D6","EDDVIST9N06D7","EDDVIST9N06D8","EDDVIST9N06D9", & + "EDDVIST9N07D1","EDDVIST9N07D2","EDDVIST9N07D3","EDDVIST9N07D4","EDDVIST9N07D5","EDDVIST9N07D6", & + "EDDVIST9N07D7","EDDVIST9N07D8","EDDVIST9N07D9","EDDVIST9N08D1","EDDVIST9N08D2","EDDVIST9N08D3", & + "EDDVIST9N08D4","EDDVIST9N08D5","EDDVIST9N08D6","EDDVIST9N08D7","EDDVIST9N08D8","EDDVIST9N08D9", & + "EDDVIST9N09D1","EDDVIST9N09D2","EDDVIST9N09D3","EDDVIST9N09D4","EDDVIST9N09D5","EDDVIST9N09D6", & + "EDDVIST9N09D7","EDDVIST9N09D8","EDDVIST9N09D9","EDDVIST9N10D1","EDDVIST9N10D2","EDDVIST9N10D3", & + "EDDVIST9N10D4","EDDVIST9N10D5","EDDVIST9N10D6","EDDVIST9N10D7","EDDVIST9N10D8","EDDVIST9N10D9", & + "EDDVIST9N11D1","EDDVIST9N11D2","EDDVIST9N11D3","EDDVIST9N11D4","EDDVIST9N11D5","EDDVIST9N11D6", & + "EDDVIST9N11D7","EDDVIST9N11D8","EDDVIST9N11D9","EDDVIST9N12D1","EDDVIST9N12D2","EDDVIST9N12D3", & + "EDDVIST9N12D4","EDDVIST9N12D5","EDDVIST9N12D6","EDDVIST9N12D7","EDDVIST9N12D8","EDDVIST9N12D9", & + "EDDVIST9N13D1","EDDVIST9N13D2","EDDVIST9N13D3","EDDVIST9N13D4","EDDVIST9N13D5","EDDVIST9N13D6", & + "EDDVIST9N13D7","EDDVIST9N13D8","EDDVIST9N13D9","EDDVIST9N14D1","EDDVIST9N14D2","EDDVIST9N14D3", & + "EDDVIST9N14D4","EDDVIST9N14D5","EDDVIST9N14D6","EDDVIST9N14D7","EDDVIST9N14D8","EDDVIST9N14D9", & + "EDDVIST9N15D1","EDDVIST9N15D2","EDDVIST9N15D3","EDDVIST9N15D4","EDDVIST9N15D5","EDDVIST9N15D6", & + "EDDVIST9N15D7","EDDVIST9N15D8","EDDVIST9N15D9","EDDVIST9N16D1","EDDVIST9N16D2","EDDVIST9N16D3", & + "EDDVIST9N16D4","EDDVIST9N16D5","EDDVIST9N16D6","EDDVIST9N16D7","EDDVIST9N16D8","EDDVIST9N16D9", & + "EDDVIST9N17D1","EDDVIST9N17D2","EDDVIST9N17D3","EDDVIST9N17D4","EDDVIST9N17D5","EDDVIST9N17D6", & + "EDDVIST9N17D7","EDDVIST9N17D8","EDDVIST9N17D9","EDDVIST9N18D1","EDDVIST9N18D2","EDDVIST9N18D3", & + "EDDVIST9N18D4","EDDVIST9N18D5","EDDVIST9N18D6","EDDVIST9N18D7","EDDVIST9N18D8","EDDVIST9N18D9", & + "EDDVIST9N19D1","EDDVIST9N19D2","EDDVIST9N19D3","EDDVIST9N19D4","EDDVIST9N19D5","EDDVIST9N19D6", & + "EDDVIST9N19D7","EDDVIST9N19D8","EDDVIST9N19D9","EDDVIST9N20D1","EDDVIST9N20D2","EDDVIST9N20D3", & + "EDDVIST9N20D4","EDDVIST9N20D5","EDDVIST9N20D6","EDDVIST9N20D7","EDDVIST9N20D8","EDDVIST9N20D9", & + "RTAXSXT1 ","RTAXSXT2 ","RTAXSXT3 ","RTAXSXT4 ","RTAXSXT5 ","RTAXSXT6 ", & + "RTAXSXT7 ","RTAXSXT8 ","RTAXSXT9 ","RTAXSYT1 ","RTAXSYT2 ","RTAXSYT3 ", & + "RTAXSYT4 ","RTAXSYT5 ","RTAXSYT6 ","RTAXSYT7 ","RTAXSYT8 ","RTAXSYT9 ", & + "RTAXSZT1 ","RTAXSZT2 ","RTAXSZT3 ","RTAXSZT4 ","RTAXSZT5 ","RTAXSZT6 ", & + "RTAXSZT7 ","RTAXSZT8 ","RTAXSZT9 ","RTCTAVGT1 ","RTCTAVGT2 ","RTCTAVGT3 ", & + "RTCTAVGT4 ","RTCTAVGT5 ","RTCTAVGT6 ","RTCTAVGT7 ","RTCTAVGT8 ","RTCTAVGT9 ", & + "RTDIAMT1 ","RTDIAMT2 ","RTDIAMT3 ","RTDIAMT4 ","RTDIAMT5 ","RTDIAMT6 ", & + "RTDIAMT7 ","RTDIAMT8 ","RTDIAMT9 ","RTGAMCURLT1 ","RTGAMCURLT2 ","RTGAMCURLT3 ", & + "RTGAMCURLT4 ","RTGAMCURLT5 ","RTGAMCURLT6 ","RTGAMCURLT7 ","RTGAMCURLT8 ","RTGAMCURLT9 ", & + "RTPOSXT1 ","RTPOSXT2 ","RTPOSXT3 ","RTPOSXT4 ","RTPOSXT5 ","RTPOSXT6 ", & + "RTPOSXT7 ","RTPOSXT8 ","RTPOSXT9 ","RTPOSYT1 ","RTPOSYT2 ","RTPOSYT3 ", & + "RTPOSYT4 ","RTPOSYT5 ","RTPOSYT6 ","RTPOSYT7 ","RTPOSYT8 ","RTPOSYT9 ", & + "RTPOSZT1 ","RTPOSZT2 ","RTPOSZT3 ","RTPOSZT4 ","RTPOSZT5 ","RTPOSZT6 ", & + "RTPOSZT7 ","RTPOSZT8 ","RTPOSZT9 ","RTSKEWFILTT1 ","RTSKEWFILTT2 ","RTSKEWFILTT3 ", & + "RTSKEWFILTT4 ","RTSKEWFILTT5 ","RTSKEWFILTT6 ","RTSKEWFILTT7 ","RTSKEWFILTT8 ","RTSKEWFILTT9 ", & + "RTSKEWT1 ","RTSKEWT2 ","RTSKEWT3 ","RTSKEWT4 ","RTSKEWT5 ","RTSKEWT6 ", & + "RTSKEWT7 ","RTSKEWT8 ","RTSKEWT9 ","RTVAMBFILTT1 ","RTVAMBFILTT2 ","RTVAMBFILTT3 ", & + "RTVAMBFILTT4 ","RTVAMBFILTT5 ","RTVAMBFILTT6 ","RTVAMBFILTT7 ","RTVAMBFILTT8 ","RTVAMBFILTT9 ", & + "RTVAMBT1 ","RTVAMBT2 ","RTVAMBT3 ","RTVAMBT4 ","RTVAMBT5 ","RTVAMBT6 ", & + "RTVAMBT7 ","RTVAMBT8 ","RTVAMBT9 ","RTVRELT1 ","RTVRELT2 ","RTVRELT3 ", & + "RTVRELT4 ","RTVRELT5 ","RTVRELT6 ","RTVRELT7 ","RTVRELT8 ","RTVRELT9 ", & + "SCGBLIN1 ","SCGBLIN2 ","SCGBLIN3 ","SCGBLIN4 ","SCGBLIN5 ","SCGBLIN6 ", & + "SCGBLIN7 ","SCGBLIN8 ","SCGBLIN9 ","SCGBLOT1 ","SCGBLOT2 ","SCGBLOT3 ", & + "SCGBLOT4 ","SCGBLOT5 ","SCGBLOT6 ","SCGBLOT7 ","SCGBLOT8 ","SCGBLOT9 ", & + "SCT1IN1 ","SCT1IN2 ","SCT1IN3 ","SCT1IN4 ","SCT1IN5 ","SCT1IN6 ", & + "SCT1IN7 ","SCT1IN8 ","SCT1IN9 ","SCT1OT1 ","SCT1OT2 ","SCT1OT3 ", & + "SCT1OT4 ","SCT1OT5 ","SCT1OT6 ","SCT1OT7 ","SCT1OT8 ","SCT1OT9 ", & + "SCT2IN1 ","SCT2IN2 ","SCT2IN3 ","SCT2IN4 ","SCT2IN5 ","SCT2IN6 ", & + "SCT2IN7 ","SCT2IN8 ","SCT2IN9 ","SCT2OT1 ","SCT2OT2 ","SCT2OT3 ", & + "SCT2OT4 ","SCT2OT5 ","SCT2OT6 ","SCT2OT7 ","SCT2OT8 ","SCT2OT9 ", & + "SCT3IN1 ","SCT3IN2 ","SCT3IN3 ","SCT3IN4 ","SCT3IN5 ","SCT3IN6 ", & + "SCT3IN7 ","SCT3IN8 ","SCT3IN9 ","SCT3OT1 ","SCT3OT2 ","SCT3OT3 ", & + "SCT3OT4 ","SCT3OT5 ","SCT3OT6 ","SCT3OT7 ","SCT3OT8 ","SCT3OT9 ", & + "SCT4IN1 ","SCT4IN2 ","SCT4IN3 ","SCT4IN4 ","SCT4IN5 ","SCT4IN6 ", & + "SCT4IN7 ","SCT4IN8 ","SCT4IN9 ","SCT4OT1 ","SCT4OT2 ","SCT4OT3 ", & + "SCT4OT4 ","SCT4OT5 ","SCT4OT6 ","SCT4OT7 ","SCT4OT8 ","SCT4OT9 ", & + "SCT5IN1 ","SCT5IN2 ","SCT5IN3 ","SCT5IN4 ","SCT5IN5 ","SCT5IN6 ", & + "SCT5IN7 ","SCT5IN8 ","SCT5IN9 ","SCT5OT1 ","SCT5OT2 ","SCT5OT3 ", & + "SCT5OT4 ","SCT5OT5 ","SCT5OT6 ","SCT5OT7 ","SCT5OT8 ","SCT5OT9 ", & + "SCT6IN1 ","SCT6IN2 ","SCT6IN3 ","SCT6IN4 ","SCT6IN5 ","SCT6IN6 ", & + "SCT6IN7 ","SCT6IN8 ","SCT6IN9 ","SCT6OT1 ","SCT6OT2 ","SCT6OT3 ", & + "SCT6OT4 ","SCT6OT5 ","SCT6OT6 ","SCT6OT7 ","SCT6OT8 ","SCT6OT9 ", & + "SCT7IN1 ","SCT7IN2 ","SCT7IN3 ","SCT7IN4 ","SCT7IN5 ","SCT7IN6 ", & + "SCT7IN7 ","SCT7IN8 ","SCT7IN9 ","SCT7OT1 ","SCT7OT2 ","SCT7OT3 ", & + "SCT7OT4 ","SCT7OT5 ","SCT7OT6 ","SCT7OT7 ","SCT7OT8 ","SCT7OT9 ", & + "SCT8IN1 ","SCT8IN2 ","SCT8IN3 ","SCT8IN4 ","SCT8IN5 ","SCT8IN6 ", & + "SCT8IN7 ","SCT8IN8 ","SCT8IN9 ","SCT8OT1 ","SCT8OT2 ","SCT8OT3 ", & + "SCT8OT4 ","SCT8OT5 ","SCT8OT6 ","SCT8OT7 ","SCT8OT8 ","SCT8OT9 ", & + "SCT9IN1 ","SCT9IN2 ","SCT9IN3 ","SCT9IN4 ","SCT9IN5 ","SCT9IN6 ", & + "SCT9IN7 ","SCT9IN8 ","SCT9IN9 ","SCT9OT1 ","SCT9OT2 ","SCT9OT3 ", & + "SCT9OT4 ","SCT9OT5 ","SCT9OT6 ","SCT9OT7 ","SCT9OT8 ","SCT9OT9 ", & + "TIAMBT1 ","TIAMBT2 ","TIAMBT3 ","TIAMBT4 ","TIAMBT5 ","TIAMBT6 ", & + "TIAMBT7 ","TIAMBT8 ","TIAMBT9 ","W1VAMBX ","W1VAMBY ","W1VAMBZ ", & + "W1VDISX ","W1VDISY ","W1VDISZ ","W2VAMBX ","W2VAMBY ","W2VAMBZ ", & + "W2VDISX ","W2VDISY ","W2VDISZ ","W3VAMBX ","W3VAMBY ","W3VAMBZ ", & + "W3VDISX ","W3VDISY ","W3VDISZ ","W4VAMBX ","W4VAMBY ","W4VAMBZ ", & + "W4VDISX ","W4VDISY ","W4VDISZ ","W5VAMBX ","W5VAMBY ","W5VAMBZ ", & + "W5VDISX ","W5VDISY ","W5VDISZ ","W6VAMBX ","W6VAMBY ","W6VAMBZ ", & + "W6VDISX ","W6VDISY ","W6VDISZ ","W7VAMBX ","W7VAMBY ","W7VAMBZ ", & + "W7VDISX ","W7VDISY ","W7VDISZ ","W8VAMBX ","W8VAMBY ","W8VAMBZ ", & + "W8VDISX ","W8VDISY ","W8VDISZ ","W9VAMBX ","W9VAMBY ","W9VAMBZ "/) + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry5(1356) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "W9VDISX ","W9VDISY ","W9VDISZ ","WKAXSXT1D1 ","WKAXSXT1D2 ","WKAXSXT1D3 ", & + "WKAXSXT1D4 ","WKAXSXT1D5 ","WKAXSXT1D6 ","WKAXSXT1D7 ","WKAXSXT1D8 ","WKAXSXT1D9 ", & + "WKAXSXT2D1 ","WKAXSXT2D2 ","WKAXSXT2D3 ","WKAXSXT2D4 ","WKAXSXT2D5 ","WKAXSXT2D6 ", & + "WKAXSXT2D7 ","WKAXSXT2D8 ","WKAXSXT2D9 ","WKAXSXT3D1 ","WKAXSXT3D2 ","WKAXSXT3D3 ", & + "WKAXSXT3D4 ","WKAXSXT3D5 ","WKAXSXT3D6 ","WKAXSXT3D7 ","WKAXSXT3D8 ","WKAXSXT3D9 ", & + "WKAXSXT4D1 ","WKAXSXT4D2 ","WKAXSXT4D3 ","WKAXSXT4D4 ","WKAXSXT4D5 ","WKAXSXT4D6 ", & + "WKAXSXT4D7 ","WKAXSXT4D8 ","WKAXSXT4D9 ","WKAXSXT5D1 ","WKAXSXT5D2 ","WKAXSXT5D3 ", & + "WKAXSXT5D4 ","WKAXSXT5D5 ","WKAXSXT5D6 ","WKAXSXT5D7 ","WKAXSXT5D8 ","WKAXSXT5D9 ", & + "WKAXSXT6D1 ","WKAXSXT6D2 ","WKAXSXT6D3 ","WKAXSXT6D4 ","WKAXSXT6D5 ","WKAXSXT6D6 ", & + "WKAXSXT6D7 ","WKAXSXT6D8 ","WKAXSXT6D9 ","WKAXSXT7D1 ","WKAXSXT7D2 ","WKAXSXT7D3 ", & + "WKAXSXT7D4 ","WKAXSXT7D5 ","WKAXSXT7D6 ","WKAXSXT7D7 ","WKAXSXT7D8 ","WKAXSXT7D9 ", & + "WKAXSXT8D1 ","WKAXSXT8D2 ","WKAXSXT8D3 ","WKAXSXT8D4 ","WKAXSXT8D5 ","WKAXSXT8D6 ", & + "WKAXSXT8D7 ","WKAXSXT8D8 ","WKAXSXT8D9 ","WKAXSXT9D1 ","WKAXSXT9D2 ","WKAXSXT9D3 ", & + "WKAXSXT9D4 ","WKAXSXT9D5 ","WKAXSXT9D6 ","WKAXSXT9D7 ","WKAXSXT9D8 ","WKAXSXT9D9 ", & + "WKAXSYT1D1 ","WKAXSYT1D2 ","WKAXSYT1D3 ","WKAXSYT1D4 ","WKAXSYT1D5 ","WKAXSYT1D6 ", & + "WKAXSYT1D7 ","WKAXSYT1D8 ","WKAXSYT1D9 ","WKAXSYT2D1 ","WKAXSYT2D2 ","WKAXSYT2D3 ", & + "WKAXSYT2D4 ","WKAXSYT2D5 ","WKAXSYT2D6 ","WKAXSYT2D7 ","WKAXSYT2D8 ","WKAXSYT2D9 ", & + "WKAXSYT3D1 ","WKAXSYT3D2 ","WKAXSYT3D3 ","WKAXSYT3D4 ","WKAXSYT3D5 ","WKAXSYT3D6 ", & + "WKAXSYT3D7 ","WKAXSYT3D8 ","WKAXSYT3D9 ","WKAXSYT4D1 ","WKAXSYT4D2 ","WKAXSYT4D3 ", & + "WKAXSYT4D4 ","WKAXSYT4D5 ","WKAXSYT4D6 ","WKAXSYT4D7 ","WKAXSYT4D8 ","WKAXSYT4D9 ", & + "WKAXSYT5D1 ","WKAXSYT5D2 ","WKAXSYT5D3 ","WKAXSYT5D4 ","WKAXSYT5D5 ","WKAXSYT5D6 ", & + "WKAXSYT5D7 ","WKAXSYT5D8 ","WKAXSYT5D9 ","WKAXSYT6D1 ","WKAXSYT6D2 ","WKAXSYT6D3 ", & + "WKAXSYT6D4 ","WKAXSYT6D5 ","WKAXSYT6D6 ","WKAXSYT6D7 ","WKAXSYT6D8 ","WKAXSYT6D9 ", & + "WKAXSYT7D1 ","WKAXSYT7D2 ","WKAXSYT7D3 ","WKAXSYT7D4 ","WKAXSYT7D5 ","WKAXSYT7D6 ", & + "WKAXSYT7D7 ","WKAXSYT7D8 ","WKAXSYT7D9 ","WKAXSYT8D1 ","WKAXSYT8D2 ","WKAXSYT8D3 ", & + "WKAXSYT8D4 ","WKAXSYT8D5 ","WKAXSYT8D6 ","WKAXSYT8D7 ","WKAXSYT8D8 ","WKAXSYT8D9 ", & + "WKAXSYT9D1 ","WKAXSYT9D2 ","WKAXSYT9D3 ","WKAXSYT9D4 ","WKAXSYT9D5 ","WKAXSYT9D6 ", & + "WKAXSYT9D7 ","WKAXSYT9D8 ","WKAXSYT9D9 ","WKAXSZT1D1 ","WKAXSZT1D2 ","WKAXSZT1D3 ", & + "WKAXSZT1D4 ","WKAXSZT1D5 ","WKAXSZT1D6 ","WKAXSZT1D7 ","WKAXSZT1D8 ","WKAXSZT1D9 ", & + "WKAXSZT2D1 ","WKAXSZT2D2 ","WKAXSZT2D3 ","WKAXSZT2D4 ","WKAXSZT2D5 ","WKAXSZT2D6 ", & + "WKAXSZT2D7 ","WKAXSZT2D8 ","WKAXSZT2D9 ","WKAXSZT3D1 ","WKAXSZT3D2 ","WKAXSZT3D3 ", & + "WKAXSZT3D4 ","WKAXSZT3D5 ","WKAXSZT3D6 ","WKAXSZT3D7 ","WKAXSZT3D8 ","WKAXSZT3D9 ", & + "WKAXSZT4D1 ","WKAXSZT4D2 ","WKAXSZT4D3 ","WKAXSZT4D4 ","WKAXSZT4D5 ","WKAXSZT4D6 ", & + "WKAXSZT4D7 ","WKAXSZT4D8 ","WKAXSZT4D9 ","WKAXSZT5D1 ","WKAXSZT5D2 ","WKAXSZT5D3 ", & + "WKAXSZT5D4 ","WKAXSZT5D5 ","WKAXSZT5D6 ","WKAXSZT5D7 ","WKAXSZT5D8 ","WKAXSZT5D9 ", & + "WKAXSZT6D1 ","WKAXSZT6D2 ","WKAXSZT6D3 ","WKAXSZT6D4 ","WKAXSZT6D5 ","WKAXSZT6D6 ", & + "WKAXSZT6D7 ","WKAXSZT6D8 ","WKAXSZT6D9 ","WKAXSZT7D1 ","WKAXSZT7D2 ","WKAXSZT7D3 ", & + "WKAXSZT7D4 ","WKAXSZT7D5 ","WKAXSZT7D6 ","WKAXSZT7D7 ","WKAXSZT7D8 ","WKAXSZT7D9 ", & + "WKAXSZT8D1 ","WKAXSZT8D2 ","WKAXSZT8D3 ","WKAXSZT8D4 ","WKAXSZT8D5 ","WKAXSZT8D6 ", & + "WKAXSZT8D7 ","WKAXSZT8D8 ","WKAXSZT8D9 ","WKAXSZT9D1 ","WKAXSZT9D2 ","WKAXSZT9D3 ", & + "WKAXSZT9D4 ","WKAXSZT9D5 ","WKAXSZT9D6 ","WKAXSZT9D7 ","WKAXSZT9D8 ","WKAXSZT9D9 ", & + "WKDFVRT1N01D1","WKDFVRT1N01D2","WKDFVRT1N01D3","WKDFVRT1N01D4","WKDFVRT1N01D5","WKDFVRT1N01D6", & + "WKDFVRT1N01D7","WKDFVRT1N01D8","WKDFVRT1N01D9","WKDFVRT1N02D1","WKDFVRT1N02D2","WKDFVRT1N02D3", & + "WKDFVRT1N02D4","WKDFVRT1N02D5","WKDFVRT1N02D6","WKDFVRT1N02D7","WKDFVRT1N02D8","WKDFVRT1N02D9", & + "WKDFVRT1N03D1","WKDFVRT1N03D2","WKDFVRT1N03D3","WKDFVRT1N03D4","WKDFVRT1N03D5","WKDFVRT1N03D6", & + "WKDFVRT1N03D7","WKDFVRT1N03D8","WKDFVRT1N03D9","WKDFVRT1N04D1","WKDFVRT1N04D2","WKDFVRT1N04D3", & + "WKDFVRT1N04D4","WKDFVRT1N04D5","WKDFVRT1N04D6","WKDFVRT1N04D7","WKDFVRT1N04D8","WKDFVRT1N04D9", & + "WKDFVRT1N05D1","WKDFVRT1N05D2","WKDFVRT1N05D3","WKDFVRT1N05D4","WKDFVRT1N05D5","WKDFVRT1N05D6", & + "WKDFVRT1N05D7","WKDFVRT1N05D8","WKDFVRT1N05D9","WKDFVRT1N06D1","WKDFVRT1N06D2","WKDFVRT1N06D3", & + "WKDFVRT1N06D4","WKDFVRT1N06D5","WKDFVRT1N06D6","WKDFVRT1N06D7","WKDFVRT1N06D8","WKDFVRT1N06D9", & + "WKDFVRT1N07D1","WKDFVRT1N07D2","WKDFVRT1N07D3","WKDFVRT1N07D4","WKDFVRT1N07D5","WKDFVRT1N07D6", & + "WKDFVRT1N07D7","WKDFVRT1N07D8","WKDFVRT1N07D9","WKDFVRT1N08D1","WKDFVRT1N08D2","WKDFVRT1N08D3", & + "WKDFVRT1N08D4","WKDFVRT1N08D5","WKDFVRT1N08D6","WKDFVRT1N08D7","WKDFVRT1N08D8","WKDFVRT1N08D9", & + "WKDFVRT1N09D1","WKDFVRT1N09D2","WKDFVRT1N09D3","WKDFVRT1N09D4","WKDFVRT1N09D5","WKDFVRT1N09D6", & + "WKDFVRT1N09D7","WKDFVRT1N09D8","WKDFVRT1N09D9","WKDFVRT1N10D1","WKDFVRT1N10D2","WKDFVRT1N10D3", & + "WKDFVRT1N10D4","WKDFVRT1N10D5","WKDFVRT1N10D6","WKDFVRT1N10D7","WKDFVRT1N10D8","WKDFVRT1N10D9", & + "WKDFVRT1N11D1","WKDFVRT1N11D2","WKDFVRT1N11D3","WKDFVRT1N11D4","WKDFVRT1N11D5","WKDFVRT1N11D6", & + "WKDFVRT1N11D7","WKDFVRT1N11D8","WKDFVRT1N11D9","WKDFVRT1N12D1","WKDFVRT1N12D2","WKDFVRT1N12D3", & + "WKDFVRT1N12D4","WKDFVRT1N12D5","WKDFVRT1N12D6","WKDFVRT1N12D7","WKDFVRT1N12D8","WKDFVRT1N12D9", & + "WKDFVRT1N13D1","WKDFVRT1N13D2","WKDFVRT1N13D3","WKDFVRT1N13D4","WKDFVRT1N13D5","WKDFVRT1N13D6", & + "WKDFVRT1N13D7","WKDFVRT1N13D8","WKDFVRT1N13D9","WKDFVRT1N14D1","WKDFVRT1N14D2","WKDFVRT1N14D3", & + "WKDFVRT1N14D4","WKDFVRT1N14D5","WKDFVRT1N14D6","WKDFVRT1N14D7","WKDFVRT1N14D8","WKDFVRT1N14D9", & + "WKDFVRT1N15D1","WKDFVRT1N15D2","WKDFVRT1N15D3","WKDFVRT1N15D4","WKDFVRT1N15D5","WKDFVRT1N15D6", & + "WKDFVRT1N15D7","WKDFVRT1N15D8","WKDFVRT1N15D9","WKDFVRT1N16D1","WKDFVRT1N16D2","WKDFVRT1N16D3", & + "WKDFVRT1N16D4","WKDFVRT1N16D5","WKDFVRT1N16D6","WKDFVRT1N16D7","WKDFVRT1N16D8","WKDFVRT1N16D9", & + "WKDFVRT1N17D1","WKDFVRT1N17D2","WKDFVRT1N17D3","WKDFVRT1N17D4","WKDFVRT1N17D5","WKDFVRT1N17D6", & + "WKDFVRT1N17D7","WKDFVRT1N17D8","WKDFVRT1N17D9","WKDFVRT1N18D1","WKDFVRT1N18D2","WKDFVRT1N18D3", & + "WKDFVRT1N18D4","WKDFVRT1N18D5","WKDFVRT1N18D6","WKDFVRT1N18D7","WKDFVRT1N18D8","WKDFVRT1N18D9", & + "WKDFVRT1N19D1","WKDFVRT1N19D2","WKDFVRT1N19D3","WKDFVRT1N19D4","WKDFVRT1N19D5","WKDFVRT1N19D6", & + "WKDFVRT1N19D7","WKDFVRT1N19D8","WKDFVRT1N19D9","WKDFVRT1N20D1","WKDFVRT1N20D2","WKDFVRT1N20D3", & + "WKDFVRT1N20D4","WKDFVRT1N20D5","WKDFVRT1N20D6","WKDFVRT1N20D7","WKDFVRT1N20D8","WKDFVRT1N20D9", & + "WKDFVRT2N01D1","WKDFVRT2N01D2","WKDFVRT2N01D3","WKDFVRT2N01D4","WKDFVRT2N01D5","WKDFVRT2N01D6", & + "WKDFVRT2N01D7","WKDFVRT2N01D8","WKDFVRT2N01D9","WKDFVRT2N02D1","WKDFVRT2N02D2","WKDFVRT2N02D3", & + "WKDFVRT2N02D4","WKDFVRT2N02D5","WKDFVRT2N02D6","WKDFVRT2N02D7","WKDFVRT2N02D8","WKDFVRT2N02D9", & + "WKDFVRT2N03D1","WKDFVRT2N03D2","WKDFVRT2N03D3","WKDFVRT2N03D4","WKDFVRT2N03D5","WKDFVRT2N03D6", & + "WKDFVRT2N03D7","WKDFVRT2N03D8","WKDFVRT2N03D9","WKDFVRT2N04D1","WKDFVRT2N04D2","WKDFVRT2N04D3", & + "WKDFVRT2N04D4","WKDFVRT2N04D5","WKDFVRT2N04D6","WKDFVRT2N04D7","WKDFVRT2N04D8","WKDFVRT2N04D9", & + "WKDFVRT2N05D1","WKDFVRT2N05D2","WKDFVRT2N05D3","WKDFVRT2N05D4","WKDFVRT2N05D5","WKDFVRT2N05D6", & + "WKDFVRT2N05D7","WKDFVRT2N05D8","WKDFVRT2N05D9","WKDFVRT2N06D1","WKDFVRT2N06D2","WKDFVRT2N06D3", & + "WKDFVRT2N06D4","WKDFVRT2N06D5","WKDFVRT2N06D6","WKDFVRT2N06D7","WKDFVRT2N06D8","WKDFVRT2N06D9", & + "WKDFVRT2N07D1","WKDFVRT2N07D2","WKDFVRT2N07D3","WKDFVRT2N07D4","WKDFVRT2N07D5","WKDFVRT2N07D6", & + "WKDFVRT2N07D7","WKDFVRT2N07D8","WKDFVRT2N07D9","WKDFVRT2N08D1","WKDFVRT2N08D2","WKDFVRT2N08D3", & + "WKDFVRT2N08D4","WKDFVRT2N08D5","WKDFVRT2N08D6","WKDFVRT2N08D7","WKDFVRT2N08D8","WKDFVRT2N08D9", & + "WKDFVRT2N09D1","WKDFVRT2N09D2","WKDFVRT2N09D3","WKDFVRT2N09D4","WKDFVRT2N09D5","WKDFVRT2N09D6", & + "WKDFVRT2N09D7","WKDFVRT2N09D8","WKDFVRT2N09D9","WKDFVRT2N10D1","WKDFVRT2N10D2","WKDFVRT2N10D3", & + "WKDFVRT2N10D4","WKDFVRT2N10D5","WKDFVRT2N10D6","WKDFVRT2N10D7","WKDFVRT2N10D8","WKDFVRT2N10D9", & + "WKDFVRT2N11D1","WKDFVRT2N11D2","WKDFVRT2N11D3","WKDFVRT2N11D4","WKDFVRT2N11D5","WKDFVRT2N11D6", & + "WKDFVRT2N11D7","WKDFVRT2N11D8","WKDFVRT2N11D9","WKDFVRT2N12D1","WKDFVRT2N12D2","WKDFVRT2N12D3", & + "WKDFVRT2N12D4","WKDFVRT2N12D5","WKDFVRT2N12D6","WKDFVRT2N12D7","WKDFVRT2N12D8","WKDFVRT2N12D9", & + "WKDFVRT2N13D1","WKDFVRT2N13D2","WKDFVRT2N13D3","WKDFVRT2N13D4","WKDFVRT2N13D5","WKDFVRT2N13D6", & + "WKDFVRT2N13D7","WKDFVRT2N13D8","WKDFVRT2N13D9","WKDFVRT2N14D1","WKDFVRT2N14D2","WKDFVRT2N14D3", & + "WKDFVRT2N14D4","WKDFVRT2N14D5","WKDFVRT2N14D6","WKDFVRT2N14D7","WKDFVRT2N14D8","WKDFVRT2N14D9", & + "WKDFVRT2N15D1","WKDFVRT2N15D2","WKDFVRT2N15D3","WKDFVRT2N15D4","WKDFVRT2N15D5","WKDFVRT2N15D6", & + "WKDFVRT2N15D7","WKDFVRT2N15D8","WKDFVRT2N15D9","WKDFVRT2N16D1","WKDFVRT2N16D2","WKDFVRT2N16D3", & + "WKDFVRT2N16D4","WKDFVRT2N16D5","WKDFVRT2N16D6","WKDFVRT2N16D7","WKDFVRT2N16D8","WKDFVRT2N16D9", & + "WKDFVRT2N17D1","WKDFVRT2N17D2","WKDFVRT2N17D3","WKDFVRT2N17D4","WKDFVRT2N17D5","WKDFVRT2N17D6", & + "WKDFVRT2N17D7","WKDFVRT2N17D8","WKDFVRT2N17D9","WKDFVRT2N18D1","WKDFVRT2N18D2","WKDFVRT2N18D3", & + "WKDFVRT2N18D4","WKDFVRT2N18D5","WKDFVRT2N18D6","WKDFVRT2N18D7","WKDFVRT2N18D8","WKDFVRT2N18D9", & + "WKDFVRT2N19D1","WKDFVRT2N19D2","WKDFVRT2N19D3","WKDFVRT2N19D4","WKDFVRT2N19D5","WKDFVRT2N19D6", & + "WKDFVRT2N19D7","WKDFVRT2N19D8","WKDFVRT2N19D9","WKDFVRT2N20D1","WKDFVRT2N20D2","WKDFVRT2N20D3", & + "WKDFVRT2N20D4","WKDFVRT2N20D5","WKDFVRT2N20D6","WKDFVRT2N20D7","WKDFVRT2N20D8","WKDFVRT2N20D9", & + "WKDFVRT3N01D1","WKDFVRT3N01D2","WKDFVRT3N01D3","WKDFVRT3N01D4","WKDFVRT3N01D5","WKDFVRT3N01D6", & + "WKDFVRT3N01D7","WKDFVRT3N01D8","WKDFVRT3N01D9","WKDFVRT3N02D1","WKDFVRT3N02D2","WKDFVRT3N02D3", & + "WKDFVRT3N02D4","WKDFVRT3N02D5","WKDFVRT3N02D6","WKDFVRT3N02D7","WKDFVRT3N02D8","WKDFVRT3N02D9", & + "WKDFVRT3N03D1","WKDFVRT3N03D2","WKDFVRT3N03D3","WKDFVRT3N03D4","WKDFVRT3N03D5","WKDFVRT3N03D6", & + "WKDFVRT3N03D7","WKDFVRT3N03D8","WKDFVRT3N03D9","WKDFVRT3N04D1","WKDFVRT3N04D2","WKDFVRT3N04D3", & + "WKDFVRT3N04D4","WKDFVRT3N04D5","WKDFVRT3N04D6","WKDFVRT3N04D7","WKDFVRT3N04D8","WKDFVRT3N04D9", & + "WKDFVRT3N05D1","WKDFVRT3N05D2","WKDFVRT3N05D3","WKDFVRT3N05D4","WKDFVRT3N05D5","WKDFVRT3N05D6", & + "WKDFVRT3N05D7","WKDFVRT3N05D8","WKDFVRT3N05D9","WKDFVRT3N06D1","WKDFVRT3N06D2","WKDFVRT3N06D3", & + "WKDFVRT3N06D4","WKDFVRT3N06D5","WKDFVRT3N06D6","WKDFVRT3N06D7","WKDFVRT3N06D8","WKDFVRT3N06D9", & + "WKDFVRT3N07D1","WKDFVRT3N07D2","WKDFVRT3N07D3","WKDFVRT3N07D4","WKDFVRT3N07D5","WKDFVRT3N07D6", & + "WKDFVRT3N07D7","WKDFVRT3N07D8","WKDFVRT3N07D9","WKDFVRT3N08D1","WKDFVRT3N08D2","WKDFVRT3N08D3", & + "WKDFVRT3N08D4","WKDFVRT3N08D5","WKDFVRT3N08D6","WKDFVRT3N08D7","WKDFVRT3N08D8","WKDFVRT3N08D9", & + "WKDFVRT3N09D1","WKDFVRT3N09D2","WKDFVRT3N09D3","WKDFVRT3N09D4","WKDFVRT3N09D5","WKDFVRT3N09D6", & + "WKDFVRT3N09D7","WKDFVRT3N09D8","WKDFVRT3N09D9","WKDFVRT3N10D1","WKDFVRT3N10D2","WKDFVRT3N10D3", & + "WKDFVRT3N10D4","WKDFVRT3N10D5","WKDFVRT3N10D6","WKDFVRT3N10D7","WKDFVRT3N10D8","WKDFVRT3N10D9", & + "WKDFVRT3N11D1","WKDFVRT3N11D2","WKDFVRT3N11D3","WKDFVRT3N11D4","WKDFVRT3N11D5","WKDFVRT3N11D6", & + "WKDFVRT3N11D7","WKDFVRT3N11D8","WKDFVRT3N11D9","WKDFVRT3N12D1","WKDFVRT3N12D2","WKDFVRT3N12D3", & + "WKDFVRT3N12D4","WKDFVRT3N12D5","WKDFVRT3N12D6","WKDFVRT3N12D7","WKDFVRT3N12D8","WKDFVRT3N12D9", & + "WKDFVRT3N13D1","WKDFVRT3N13D2","WKDFVRT3N13D3","WKDFVRT3N13D4","WKDFVRT3N13D5","WKDFVRT3N13D6", & + "WKDFVRT3N13D7","WKDFVRT3N13D8","WKDFVRT3N13D9","WKDFVRT3N14D1","WKDFVRT3N14D2","WKDFVRT3N14D3", & + "WKDFVRT3N14D4","WKDFVRT3N14D5","WKDFVRT3N14D6","WKDFVRT3N14D7","WKDFVRT3N14D8","WKDFVRT3N14D9", & + "WKDFVRT3N15D1","WKDFVRT3N15D2","WKDFVRT3N15D3","WKDFVRT3N15D4","WKDFVRT3N15D5","WKDFVRT3N15D6", & + "WKDFVRT3N15D7","WKDFVRT3N15D8","WKDFVRT3N15D9","WKDFVRT3N16D1","WKDFVRT3N16D2","WKDFVRT3N16D3", & + "WKDFVRT3N16D4","WKDFVRT3N16D5","WKDFVRT3N16D6","WKDFVRT3N16D7","WKDFVRT3N16D8","WKDFVRT3N16D9", & + "WKDFVRT3N17D1","WKDFVRT3N17D2","WKDFVRT3N17D3","WKDFVRT3N17D4","WKDFVRT3N17D5","WKDFVRT3N17D6", & + "WKDFVRT3N17D7","WKDFVRT3N17D8","WKDFVRT3N17D9","WKDFVRT3N18D1","WKDFVRT3N18D2","WKDFVRT3N18D3", & + "WKDFVRT3N18D4","WKDFVRT3N18D5","WKDFVRT3N18D6","WKDFVRT3N18D7","WKDFVRT3N18D8","WKDFVRT3N18D9", & + "WKDFVRT3N19D1","WKDFVRT3N19D2","WKDFVRT3N19D3","WKDFVRT3N19D4","WKDFVRT3N19D5","WKDFVRT3N19D6", & + "WKDFVRT3N19D7","WKDFVRT3N19D8","WKDFVRT3N19D9","WKDFVRT3N20D1","WKDFVRT3N20D2","WKDFVRT3N20D3", & + "WKDFVRT3N20D4","WKDFVRT3N20D5","WKDFVRT3N20D6","WKDFVRT3N20D7","WKDFVRT3N20D8","WKDFVRT3N20D9", & + "WKDFVRT4N01D1","WKDFVRT4N01D2","WKDFVRT4N01D3","WKDFVRT4N01D4","WKDFVRT4N01D5","WKDFVRT4N01D6", & + "WKDFVRT4N01D7","WKDFVRT4N01D8","WKDFVRT4N01D9","WKDFVRT4N02D1","WKDFVRT4N02D2","WKDFVRT4N02D3", & + "WKDFVRT4N02D4","WKDFVRT4N02D5","WKDFVRT4N02D6","WKDFVRT4N02D7","WKDFVRT4N02D8","WKDFVRT4N02D9", & + "WKDFVRT4N03D1","WKDFVRT4N03D2","WKDFVRT4N03D3","WKDFVRT4N03D4","WKDFVRT4N03D5","WKDFVRT4N03D6", & + "WKDFVRT4N03D7","WKDFVRT4N03D8","WKDFVRT4N03D9","WKDFVRT4N04D1","WKDFVRT4N04D2","WKDFVRT4N04D3", & + "WKDFVRT4N04D4","WKDFVRT4N04D5","WKDFVRT4N04D6","WKDFVRT4N04D7","WKDFVRT4N04D8","WKDFVRT4N04D9", & + "WKDFVRT4N05D1","WKDFVRT4N05D2","WKDFVRT4N05D3","WKDFVRT4N05D4","WKDFVRT4N05D5","WKDFVRT4N05D6", & + "WKDFVRT4N05D7","WKDFVRT4N05D8","WKDFVRT4N05D9","WKDFVRT4N06D1","WKDFVRT4N06D2","WKDFVRT4N06D3", & + "WKDFVRT4N06D4","WKDFVRT4N06D5","WKDFVRT4N06D6","WKDFVRT4N06D7","WKDFVRT4N06D8","WKDFVRT4N06D9", & + "WKDFVRT4N07D1","WKDFVRT4N07D2","WKDFVRT4N07D3","WKDFVRT4N07D4","WKDFVRT4N07D5","WKDFVRT4N07D6", & + "WKDFVRT4N07D7","WKDFVRT4N07D8","WKDFVRT4N07D9","WKDFVRT4N08D1","WKDFVRT4N08D2","WKDFVRT4N08D3", & + "WKDFVRT4N08D4","WKDFVRT4N08D5","WKDFVRT4N08D6","WKDFVRT4N08D7","WKDFVRT4N08D8","WKDFVRT4N08D9", & + "WKDFVRT4N09D1","WKDFVRT4N09D2","WKDFVRT4N09D3","WKDFVRT4N09D4","WKDFVRT4N09D5","WKDFVRT4N09D6", & + "WKDFVRT4N09D7","WKDFVRT4N09D8","WKDFVRT4N09D9","WKDFVRT4N10D1","WKDFVRT4N10D2","WKDFVRT4N10D3", & + "WKDFVRT4N10D4","WKDFVRT4N10D5","WKDFVRT4N10D6","WKDFVRT4N10D7","WKDFVRT4N10D8","WKDFVRT4N10D9", & + "WKDFVRT4N11D1","WKDFVRT4N11D2","WKDFVRT4N11D3","WKDFVRT4N11D4","WKDFVRT4N11D5","WKDFVRT4N11D6", & + "WKDFVRT4N11D7","WKDFVRT4N11D8","WKDFVRT4N11D9","WKDFVRT4N12D1","WKDFVRT4N12D2","WKDFVRT4N12D3", & + "WKDFVRT4N12D4","WKDFVRT4N12D5","WKDFVRT4N12D6","WKDFVRT4N12D7","WKDFVRT4N12D8","WKDFVRT4N12D9", & + "WKDFVRT4N13D1","WKDFVRT4N13D2","WKDFVRT4N13D3","WKDFVRT4N13D4","WKDFVRT4N13D5","WKDFVRT4N13D6", & + "WKDFVRT4N13D7","WKDFVRT4N13D8","WKDFVRT4N13D9","WKDFVRT4N14D1","WKDFVRT4N14D2","WKDFVRT4N14D3", & + "WKDFVRT4N14D4","WKDFVRT4N14D5","WKDFVRT4N14D6","WKDFVRT4N14D7","WKDFVRT4N14D8","WKDFVRT4N14D9", & + "WKDFVRT4N15D1","WKDFVRT4N15D2","WKDFVRT4N15D3","WKDFVRT4N15D4","WKDFVRT4N15D5","WKDFVRT4N15D6", & + "WKDFVRT4N15D7","WKDFVRT4N15D8","WKDFVRT4N15D9","WKDFVRT4N16D1","WKDFVRT4N16D2","WKDFVRT4N16D3", & + "WKDFVRT4N16D4","WKDFVRT4N16D5","WKDFVRT4N16D6","WKDFVRT4N16D7","WKDFVRT4N16D8","WKDFVRT4N16D9", & + "WKDFVRT4N17D1","WKDFVRT4N17D2","WKDFVRT4N17D3","WKDFVRT4N17D4","WKDFVRT4N17D5","WKDFVRT4N17D6", & + "WKDFVRT4N17D7","WKDFVRT4N17D8","WKDFVRT4N17D9","WKDFVRT4N18D1","WKDFVRT4N18D2","WKDFVRT4N18D3", & + "WKDFVRT4N18D4","WKDFVRT4N18D5","WKDFVRT4N18D6","WKDFVRT4N18D7","WKDFVRT4N18D8","WKDFVRT4N18D9", & + "WKDFVRT4N19D1","WKDFVRT4N19D2","WKDFVRT4N19D3","WKDFVRT4N19D4","WKDFVRT4N19D5","WKDFVRT4N19D6", & + "WKDFVRT4N19D7","WKDFVRT4N19D8","WKDFVRT4N19D9","WKDFVRT4N20D1","WKDFVRT4N20D2","WKDFVRT4N20D3", & + "WKDFVRT4N20D4","WKDFVRT4N20D5","WKDFVRT4N20D6","WKDFVRT4N20D7","WKDFVRT4N20D8","WKDFVRT4N20D9", & + "WKDFVRT5N01D1","WKDFVRT5N01D2","WKDFVRT5N01D3","WKDFVRT5N01D4","WKDFVRT5N01D5","WKDFVRT5N01D6", & + "WKDFVRT5N01D7","WKDFVRT5N01D8","WKDFVRT5N01D9","WKDFVRT5N02D1","WKDFVRT5N02D2","WKDFVRT5N02D3", & + "WKDFVRT5N02D4","WKDFVRT5N02D5","WKDFVRT5N02D6","WKDFVRT5N02D7","WKDFVRT5N02D8","WKDFVRT5N02D9", & + "WKDFVRT5N03D1","WKDFVRT5N03D2","WKDFVRT5N03D3","WKDFVRT5N03D4","WKDFVRT5N03D5","WKDFVRT5N03D6", & + "WKDFVRT5N03D7","WKDFVRT5N03D8","WKDFVRT5N03D9","WKDFVRT5N04D1","WKDFVRT5N04D2","WKDFVRT5N04D3", & + "WKDFVRT5N04D4","WKDFVRT5N04D5","WKDFVRT5N04D6","WKDFVRT5N04D7","WKDFVRT5N04D8","WKDFVRT5N04D9", & + "WKDFVRT5N05D1","WKDFVRT5N05D2","WKDFVRT5N05D3","WKDFVRT5N05D4","WKDFVRT5N05D5","WKDFVRT5N05D6", & + "WKDFVRT5N05D7","WKDFVRT5N05D8","WKDFVRT5N05D9","WKDFVRT5N06D1","WKDFVRT5N06D2","WKDFVRT5N06D3", & + "WKDFVRT5N06D4","WKDFVRT5N06D5","WKDFVRT5N06D6","WKDFVRT5N06D7","WKDFVRT5N06D8","WKDFVRT5N06D9", & + "WKDFVRT5N07D1","WKDFVRT5N07D2","WKDFVRT5N07D3","WKDFVRT5N07D4","WKDFVRT5N07D5","WKDFVRT5N07D6", & + "WKDFVRT5N07D7","WKDFVRT5N07D8","WKDFVRT5N07D9","WKDFVRT5N08D1","WKDFVRT5N08D2","WKDFVRT5N08D3", & + "WKDFVRT5N08D4","WKDFVRT5N08D5","WKDFVRT5N08D6","WKDFVRT5N08D7","WKDFVRT5N08D8","WKDFVRT5N08D9", & + "WKDFVRT5N09D1","WKDFVRT5N09D2","WKDFVRT5N09D3","WKDFVRT5N09D4","WKDFVRT5N09D5","WKDFVRT5N09D6", & + "WKDFVRT5N09D7","WKDFVRT5N09D8","WKDFVRT5N09D9","WKDFVRT5N10D1","WKDFVRT5N10D2","WKDFVRT5N10D3", & + "WKDFVRT5N10D4","WKDFVRT5N10D5","WKDFVRT5N10D6","WKDFVRT5N10D7","WKDFVRT5N10D8","WKDFVRT5N10D9", & + "WKDFVRT5N11D1","WKDFVRT5N11D2","WKDFVRT5N11D3","WKDFVRT5N11D4","WKDFVRT5N11D5","WKDFVRT5N11D6", & + "WKDFVRT5N11D7","WKDFVRT5N11D8","WKDFVRT5N11D9","WKDFVRT5N12D1","WKDFVRT5N12D2","WKDFVRT5N12D3", & + "WKDFVRT5N12D4","WKDFVRT5N12D5","WKDFVRT5N12D6","WKDFVRT5N12D7","WKDFVRT5N12D8","WKDFVRT5N12D9", & + "WKDFVRT5N13D1","WKDFVRT5N13D2","WKDFVRT5N13D3","WKDFVRT5N13D4","WKDFVRT5N13D5","WKDFVRT5N13D6", & + "WKDFVRT5N13D7","WKDFVRT5N13D8","WKDFVRT5N13D9","WKDFVRT5N14D1","WKDFVRT5N14D2","WKDFVRT5N14D3", & + "WKDFVRT5N14D4","WKDFVRT5N14D5","WKDFVRT5N14D6","WKDFVRT5N14D7","WKDFVRT5N14D8","WKDFVRT5N14D9", & + "WKDFVRT5N15D1","WKDFVRT5N15D2","WKDFVRT5N15D3","WKDFVRT5N15D4","WKDFVRT5N15D5","WKDFVRT5N15D6", & + "WKDFVRT5N15D7","WKDFVRT5N15D8","WKDFVRT5N15D9","WKDFVRT5N16D1","WKDFVRT5N16D2","WKDFVRT5N16D3", & + "WKDFVRT5N16D4","WKDFVRT5N16D5","WKDFVRT5N16D6","WKDFVRT5N16D7","WKDFVRT5N16D8","WKDFVRT5N16D9", & + "WKDFVRT5N17D1","WKDFVRT5N17D2","WKDFVRT5N17D3","WKDFVRT5N17D4","WKDFVRT5N17D5","WKDFVRT5N17D6", & + "WKDFVRT5N17D7","WKDFVRT5N17D8","WKDFVRT5N17D9","WKDFVRT5N18D1","WKDFVRT5N18D2","WKDFVRT5N18D3", & + "WKDFVRT5N18D4","WKDFVRT5N18D5","WKDFVRT5N18D6","WKDFVRT5N18D7","WKDFVRT5N18D8","WKDFVRT5N18D9", & + "WKDFVRT5N19D1","WKDFVRT5N19D2","WKDFVRT5N19D3","WKDFVRT5N19D4","WKDFVRT5N19D5","WKDFVRT5N19D6", & + "WKDFVRT5N19D7","WKDFVRT5N19D8","WKDFVRT5N19D9","WKDFVRT5N20D1","WKDFVRT5N20D2","WKDFVRT5N20D3", & + "WKDFVRT5N20D4","WKDFVRT5N20D5","WKDFVRT5N20D6","WKDFVRT5N20D7","WKDFVRT5N20D8","WKDFVRT5N20D9", & + "WKDFVRT6N01D1","WKDFVRT6N01D2","WKDFVRT6N01D3","WKDFVRT6N01D4","WKDFVRT6N01D5","WKDFVRT6N01D6", & + "WKDFVRT6N01D7","WKDFVRT6N01D8","WKDFVRT6N01D9","WKDFVRT6N02D1","WKDFVRT6N02D2","WKDFVRT6N02D3", & + "WKDFVRT6N02D4","WKDFVRT6N02D5","WKDFVRT6N02D6","WKDFVRT6N02D7","WKDFVRT6N02D8","WKDFVRT6N02D9", & + "WKDFVRT6N03D1","WKDFVRT6N03D2","WKDFVRT6N03D3","WKDFVRT6N03D4","WKDFVRT6N03D5","WKDFVRT6N03D6", & + "WKDFVRT6N03D7","WKDFVRT6N03D8","WKDFVRT6N03D9","WKDFVRT6N04D1","WKDFVRT6N04D2","WKDFVRT6N04D3", & + "WKDFVRT6N04D4","WKDFVRT6N04D5","WKDFVRT6N04D6","WKDFVRT6N04D7","WKDFVRT6N04D8","WKDFVRT6N04D9", & + "WKDFVRT6N05D1","WKDFVRT6N05D2","WKDFVRT6N05D3","WKDFVRT6N05D4","WKDFVRT6N05D5","WKDFVRT6N05D6", & + "WKDFVRT6N05D7","WKDFVRT6N05D8","WKDFVRT6N05D9","WKDFVRT6N06D1","WKDFVRT6N06D2","WKDFVRT6N06D3", & + "WKDFVRT6N06D4","WKDFVRT6N06D5","WKDFVRT6N06D6","WKDFVRT6N06D7","WKDFVRT6N06D8","WKDFVRT6N06D9", & + "WKDFVRT6N07D1","WKDFVRT6N07D2","WKDFVRT6N07D3","WKDFVRT6N07D4","WKDFVRT6N07D5","WKDFVRT6N07D6", & + "WKDFVRT6N07D7","WKDFVRT6N07D8","WKDFVRT6N07D9","WKDFVRT6N08D1","WKDFVRT6N08D2","WKDFVRT6N08D3", & + "WKDFVRT6N08D4","WKDFVRT6N08D5","WKDFVRT6N08D6","WKDFVRT6N08D7","WKDFVRT6N08D8","WKDFVRT6N08D9", & + "WKDFVRT6N09D1","WKDFVRT6N09D2","WKDFVRT6N09D3","WKDFVRT6N09D4","WKDFVRT6N09D5","WKDFVRT6N09D6", & + "WKDFVRT6N09D7","WKDFVRT6N09D8","WKDFVRT6N09D9","WKDFVRT6N10D1","WKDFVRT6N10D2","WKDFVRT6N10D3", & + "WKDFVRT6N10D4","WKDFVRT6N10D5","WKDFVRT6N10D6","WKDFVRT6N10D7","WKDFVRT6N10D8","WKDFVRT6N10D9", & + "WKDFVRT6N11D1","WKDFVRT6N11D2","WKDFVRT6N11D3","WKDFVRT6N11D4","WKDFVRT6N11D5","WKDFVRT6N11D6", & + "WKDFVRT6N11D7","WKDFVRT6N11D8","WKDFVRT6N11D9","WKDFVRT6N12D1","WKDFVRT6N12D2","WKDFVRT6N12D3", & + "WKDFVRT6N12D4","WKDFVRT6N12D5","WKDFVRT6N12D6","WKDFVRT6N12D7","WKDFVRT6N12D8","WKDFVRT6N12D9", & + "WKDFVRT6N13D1","WKDFVRT6N13D2","WKDFVRT6N13D3","WKDFVRT6N13D4","WKDFVRT6N13D5","WKDFVRT6N13D6", & + "WKDFVRT6N13D7","WKDFVRT6N13D8","WKDFVRT6N13D9","WKDFVRT6N14D1","WKDFVRT6N14D2","WKDFVRT6N14D3", & + "WKDFVRT6N14D4","WKDFVRT6N14D5","WKDFVRT6N14D6","WKDFVRT6N14D7","WKDFVRT6N14D8","WKDFVRT6N14D9", & + "WKDFVRT6N15D1","WKDFVRT6N15D2","WKDFVRT6N15D3","WKDFVRT6N15D4","WKDFVRT6N15D5","WKDFVRT6N15D6", & + "WKDFVRT6N15D7","WKDFVRT6N15D8","WKDFVRT6N15D9","WKDFVRT6N16D1","WKDFVRT6N16D2","WKDFVRT6N16D3", & + "WKDFVRT6N16D4","WKDFVRT6N16D5","WKDFVRT6N16D6","WKDFVRT6N16D7","WKDFVRT6N16D8","WKDFVRT6N16D9", & + "WKDFVRT6N17D1","WKDFVRT6N17D2","WKDFVRT6N17D3","WKDFVRT6N17D4","WKDFVRT6N17D5","WKDFVRT6N17D6", & + "WKDFVRT6N17D7","WKDFVRT6N17D8","WKDFVRT6N17D9","WKDFVRT6N18D1","WKDFVRT6N18D2","WKDFVRT6N18D3", & + "WKDFVRT6N18D4","WKDFVRT6N18D5","WKDFVRT6N18D6","WKDFVRT6N18D7","WKDFVRT6N18D8","WKDFVRT6N18D9", & + "WKDFVRT6N19D1","WKDFVRT6N19D2","WKDFVRT6N19D3","WKDFVRT6N19D4","WKDFVRT6N19D5","WKDFVRT6N19D6", & + "WKDFVRT6N19D7","WKDFVRT6N19D8","WKDFVRT6N19D9","WKDFVRT6N20D1","WKDFVRT6N20D2","WKDFVRT6N20D3", & + "WKDFVRT6N20D4","WKDFVRT6N20D5","WKDFVRT6N20D6","WKDFVRT6N20D7","WKDFVRT6N20D8","WKDFVRT6N20D9", & + "WKDFVRT7N01D1","WKDFVRT7N01D2","WKDFVRT7N01D3","WKDFVRT7N01D4","WKDFVRT7N01D5","WKDFVRT7N01D6", & + "WKDFVRT7N01D7","WKDFVRT7N01D8","WKDFVRT7N01D9","WKDFVRT7N02D1","WKDFVRT7N02D2","WKDFVRT7N02D3", & + "WKDFVRT7N02D4","WKDFVRT7N02D5","WKDFVRT7N02D6","WKDFVRT7N02D7","WKDFVRT7N02D8","WKDFVRT7N02D9", & + "WKDFVRT7N03D1","WKDFVRT7N03D2","WKDFVRT7N03D3","WKDFVRT7N03D4","WKDFVRT7N03D5","WKDFVRT7N03D6", & + "WKDFVRT7N03D7","WKDFVRT7N03D8","WKDFVRT7N03D9","WKDFVRT7N04D1","WKDFVRT7N04D2","WKDFVRT7N04D3"/) + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry6(1356) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "WKDFVRT7N04D4","WKDFVRT7N04D5","WKDFVRT7N04D6","WKDFVRT7N04D7","WKDFVRT7N04D8","WKDFVRT7N04D9", & + "WKDFVRT7N05D1","WKDFVRT7N05D2","WKDFVRT7N05D3","WKDFVRT7N05D4","WKDFVRT7N05D5","WKDFVRT7N05D6", & + "WKDFVRT7N05D7","WKDFVRT7N05D8","WKDFVRT7N05D9","WKDFVRT7N06D1","WKDFVRT7N06D2","WKDFVRT7N06D3", & + "WKDFVRT7N06D4","WKDFVRT7N06D5","WKDFVRT7N06D6","WKDFVRT7N06D7","WKDFVRT7N06D8","WKDFVRT7N06D9", & + "WKDFVRT7N07D1","WKDFVRT7N07D2","WKDFVRT7N07D3","WKDFVRT7N07D4","WKDFVRT7N07D5","WKDFVRT7N07D6", & + "WKDFVRT7N07D7","WKDFVRT7N07D8","WKDFVRT7N07D9","WKDFVRT7N08D1","WKDFVRT7N08D2","WKDFVRT7N08D3", & + "WKDFVRT7N08D4","WKDFVRT7N08D5","WKDFVRT7N08D6","WKDFVRT7N08D7","WKDFVRT7N08D8","WKDFVRT7N08D9", & + "WKDFVRT7N09D1","WKDFVRT7N09D2","WKDFVRT7N09D3","WKDFVRT7N09D4","WKDFVRT7N09D5","WKDFVRT7N09D6", & + "WKDFVRT7N09D7","WKDFVRT7N09D8","WKDFVRT7N09D9","WKDFVRT7N10D1","WKDFVRT7N10D2","WKDFVRT7N10D3", & + "WKDFVRT7N10D4","WKDFVRT7N10D5","WKDFVRT7N10D6","WKDFVRT7N10D7","WKDFVRT7N10D8","WKDFVRT7N10D9", & + "WKDFVRT7N11D1","WKDFVRT7N11D2","WKDFVRT7N11D3","WKDFVRT7N11D4","WKDFVRT7N11D5","WKDFVRT7N11D6", & + "WKDFVRT7N11D7","WKDFVRT7N11D8","WKDFVRT7N11D9","WKDFVRT7N12D1","WKDFVRT7N12D2","WKDFVRT7N12D3", & + "WKDFVRT7N12D4","WKDFVRT7N12D5","WKDFVRT7N12D6","WKDFVRT7N12D7","WKDFVRT7N12D8","WKDFVRT7N12D9", & + "WKDFVRT7N13D1","WKDFVRT7N13D2","WKDFVRT7N13D3","WKDFVRT7N13D4","WKDFVRT7N13D5","WKDFVRT7N13D6", & + "WKDFVRT7N13D7","WKDFVRT7N13D8","WKDFVRT7N13D9","WKDFVRT7N14D1","WKDFVRT7N14D2","WKDFVRT7N14D3", & + "WKDFVRT7N14D4","WKDFVRT7N14D5","WKDFVRT7N14D6","WKDFVRT7N14D7","WKDFVRT7N14D8","WKDFVRT7N14D9", & + "WKDFVRT7N15D1","WKDFVRT7N15D2","WKDFVRT7N15D3","WKDFVRT7N15D4","WKDFVRT7N15D5","WKDFVRT7N15D6", & + "WKDFVRT7N15D7","WKDFVRT7N15D8","WKDFVRT7N15D9","WKDFVRT7N16D1","WKDFVRT7N16D2","WKDFVRT7N16D3", & + "WKDFVRT7N16D4","WKDFVRT7N16D5","WKDFVRT7N16D6","WKDFVRT7N16D7","WKDFVRT7N16D8","WKDFVRT7N16D9", & + "WKDFVRT7N17D1","WKDFVRT7N17D2","WKDFVRT7N17D3","WKDFVRT7N17D4","WKDFVRT7N17D5","WKDFVRT7N17D6", & + "WKDFVRT7N17D7","WKDFVRT7N17D8","WKDFVRT7N17D9","WKDFVRT7N18D1","WKDFVRT7N18D2","WKDFVRT7N18D3", & + "WKDFVRT7N18D4","WKDFVRT7N18D5","WKDFVRT7N18D6","WKDFVRT7N18D7","WKDFVRT7N18D8","WKDFVRT7N18D9", & + "WKDFVRT7N19D1","WKDFVRT7N19D2","WKDFVRT7N19D3","WKDFVRT7N19D4","WKDFVRT7N19D5","WKDFVRT7N19D6", & + "WKDFVRT7N19D7","WKDFVRT7N19D8","WKDFVRT7N19D9","WKDFVRT7N20D1","WKDFVRT7N20D2","WKDFVRT7N20D3", & + "WKDFVRT7N20D4","WKDFVRT7N20D5","WKDFVRT7N20D6","WKDFVRT7N20D7","WKDFVRT7N20D8","WKDFVRT7N20D9", & + "WKDFVRT8N01D1","WKDFVRT8N01D2","WKDFVRT8N01D3","WKDFVRT8N01D4","WKDFVRT8N01D5","WKDFVRT8N01D6", & + "WKDFVRT8N01D7","WKDFVRT8N01D8","WKDFVRT8N01D9","WKDFVRT8N02D1","WKDFVRT8N02D2","WKDFVRT8N02D3", & + "WKDFVRT8N02D4","WKDFVRT8N02D5","WKDFVRT8N02D6","WKDFVRT8N02D7","WKDFVRT8N02D8","WKDFVRT8N02D9", & + "WKDFVRT8N03D1","WKDFVRT8N03D2","WKDFVRT8N03D3","WKDFVRT8N03D4","WKDFVRT8N03D5","WKDFVRT8N03D6", & + "WKDFVRT8N03D7","WKDFVRT8N03D8","WKDFVRT8N03D9","WKDFVRT8N04D1","WKDFVRT8N04D2","WKDFVRT8N04D3", & + "WKDFVRT8N04D4","WKDFVRT8N04D5","WKDFVRT8N04D6","WKDFVRT8N04D7","WKDFVRT8N04D8","WKDFVRT8N04D9", & + "WKDFVRT8N05D1","WKDFVRT8N05D2","WKDFVRT8N05D3","WKDFVRT8N05D4","WKDFVRT8N05D5","WKDFVRT8N05D6", & + "WKDFVRT8N05D7","WKDFVRT8N05D8","WKDFVRT8N05D9","WKDFVRT8N06D1","WKDFVRT8N06D2","WKDFVRT8N06D3", & + "WKDFVRT8N06D4","WKDFVRT8N06D5","WKDFVRT8N06D6","WKDFVRT8N06D7","WKDFVRT8N06D8","WKDFVRT8N06D9", & + "WKDFVRT8N07D1","WKDFVRT8N07D2","WKDFVRT8N07D3","WKDFVRT8N07D4","WKDFVRT8N07D5","WKDFVRT8N07D6", & + "WKDFVRT8N07D7","WKDFVRT8N07D8","WKDFVRT8N07D9","WKDFVRT8N08D1","WKDFVRT8N08D2","WKDFVRT8N08D3", & + "WKDFVRT8N08D4","WKDFVRT8N08D5","WKDFVRT8N08D6","WKDFVRT8N08D7","WKDFVRT8N08D8","WKDFVRT8N08D9", & + "WKDFVRT8N09D1","WKDFVRT8N09D2","WKDFVRT8N09D3","WKDFVRT8N09D4","WKDFVRT8N09D5","WKDFVRT8N09D6", & + "WKDFVRT8N09D7","WKDFVRT8N09D8","WKDFVRT8N09D9","WKDFVRT8N10D1","WKDFVRT8N10D2","WKDFVRT8N10D3", & + "WKDFVRT8N10D4","WKDFVRT8N10D5","WKDFVRT8N10D6","WKDFVRT8N10D7","WKDFVRT8N10D8","WKDFVRT8N10D9", & + "WKDFVRT8N11D1","WKDFVRT8N11D2","WKDFVRT8N11D3","WKDFVRT8N11D4","WKDFVRT8N11D5","WKDFVRT8N11D6", & + "WKDFVRT8N11D7","WKDFVRT8N11D8","WKDFVRT8N11D9","WKDFVRT8N12D1","WKDFVRT8N12D2","WKDFVRT8N12D3", & + "WKDFVRT8N12D4","WKDFVRT8N12D5","WKDFVRT8N12D6","WKDFVRT8N12D7","WKDFVRT8N12D8","WKDFVRT8N12D9", & + "WKDFVRT8N13D1","WKDFVRT8N13D2","WKDFVRT8N13D3","WKDFVRT8N13D4","WKDFVRT8N13D5","WKDFVRT8N13D6", & + "WKDFVRT8N13D7","WKDFVRT8N13D8","WKDFVRT8N13D9","WKDFVRT8N14D1","WKDFVRT8N14D2","WKDFVRT8N14D3", & + "WKDFVRT8N14D4","WKDFVRT8N14D5","WKDFVRT8N14D6","WKDFVRT8N14D7","WKDFVRT8N14D8","WKDFVRT8N14D9", & + "WKDFVRT8N15D1","WKDFVRT8N15D2","WKDFVRT8N15D3","WKDFVRT8N15D4","WKDFVRT8N15D5","WKDFVRT8N15D6", & + "WKDFVRT8N15D7","WKDFVRT8N15D8","WKDFVRT8N15D9","WKDFVRT8N16D1","WKDFVRT8N16D2","WKDFVRT8N16D3", & + "WKDFVRT8N16D4","WKDFVRT8N16D5","WKDFVRT8N16D6","WKDFVRT8N16D7","WKDFVRT8N16D8","WKDFVRT8N16D9", & + "WKDFVRT8N17D1","WKDFVRT8N17D2","WKDFVRT8N17D3","WKDFVRT8N17D4","WKDFVRT8N17D5","WKDFVRT8N17D6", & + "WKDFVRT8N17D7","WKDFVRT8N17D8","WKDFVRT8N17D9","WKDFVRT8N18D1","WKDFVRT8N18D2","WKDFVRT8N18D3", & + "WKDFVRT8N18D4","WKDFVRT8N18D5","WKDFVRT8N18D6","WKDFVRT8N18D7","WKDFVRT8N18D8","WKDFVRT8N18D9", & + "WKDFVRT8N19D1","WKDFVRT8N19D2","WKDFVRT8N19D3","WKDFVRT8N19D4","WKDFVRT8N19D5","WKDFVRT8N19D6", & + "WKDFVRT8N19D7","WKDFVRT8N19D8","WKDFVRT8N19D9","WKDFVRT8N20D1","WKDFVRT8N20D2","WKDFVRT8N20D3", & + "WKDFVRT8N20D4","WKDFVRT8N20D5","WKDFVRT8N20D6","WKDFVRT8N20D7","WKDFVRT8N20D8","WKDFVRT8N20D9", & + "WKDFVRT9N01D1","WKDFVRT9N01D2","WKDFVRT9N01D3","WKDFVRT9N01D4","WKDFVRT9N01D5","WKDFVRT9N01D6", & + "WKDFVRT9N01D7","WKDFVRT9N01D8","WKDFVRT9N01D9","WKDFVRT9N02D1","WKDFVRT9N02D2","WKDFVRT9N02D3", & + "WKDFVRT9N02D4","WKDFVRT9N02D5","WKDFVRT9N02D6","WKDFVRT9N02D7","WKDFVRT9N02D8","WKDFVRT9N02D9", & + "WKDFVRT9N03D1","WKDFVRT9N03D2","WKDFVRT9N03D3","WKDFVRT9N03D4","WKDFVRT9N03D5","WKDFVRT9N03D6", & + "WKDFVRT9N03D7","WKDFVRT9N03D8","WKDFVRT9N03D9","WKDFVRT9N04D1","WKDFVRT9N04D2","WKDFVRT9N04D3", & + "WKDFVRT9N04D4","WKDFVRT9N04D5","WKDFVRT9N04D6","WKDFVRT9N04D7","WKDFVRT9N04D8","WKDFVRT9N04D9", & + "WKDFVRT9N05D1","WKDFVRT9N05D2","WKDFVRT9N05D3","WKDFVRT9N05D4","WKDFVRT9N05D5","WKDFVRT9N05D6", & + "WKDFVRT9N05D7","WKDFVRT9N05D8","WKDFVRT9N05D9","WKDFVRT9N06D1","WKDFVRT9N06D2","WKDFVRT9N06D3", & + "WKDFVRT9N06D4","WKDFVRT9N06D5","WKDFVRT9N06D6","WKDFVRT9N06D7","WKDFVRT9N06D8","WKDFVRT9N06D9", & + "WKDFVRT9N07D1","WKDFVRT9N07D2","WKDFVRT9N07D3","WKDFVRT9N07D4","WKDFVRT9N07D5","WKDFVRT9N07D6", & + "WKDFVRT9N07D7","WKDFVRT9N07D8","WKDFVRT9N07D9","WKDFVRT9N08D1","WKDFVRT9N08D2","WKDFVRT9N08D3", & + "WKDFVRT9N08D4","WKDFVRT9N08D5","WKDFVRT9N08D6","WKDFVRT9N08D7","WKDFVRT9N08D8","WKDFVRT9N08D9", & + "WKDFVRT9N09D1","WKDFVRT9N09D2","WKDFVRT9N09D3","WKDFVRT9N09D4","WKDFVRT9N09D5","WKDFVRT9N09D6", & + "WKDFVRT9N09D7","WKDFVRT9N09D8","WKDFVRT9N09D9","WKDFVRT9N10D1","WKDFVRT9N10D2","WKDFVRT9N10D3", & + "WKDFVRT9N10D4","WKDFVRT9N10D5","WKDFVRT9N10D6","WKDFVRT9N10D7","WKDFVRT9N10D8","WKDFVRT9N10D9", & + "WKDFVRT9N11D1","WKDFVRT9N11D2","WKDFVRT9N11D3","WKDFVRT9N11D4","WKDFVRT9N11D5","WKDFVRT9N11D6", & + "WKDFVRT9N11D7","WKDFVRT9N11D8","WKDFVRT9N11D9","WKDFVRT9N12D1","WKDFVRT9N12D2","WKDFVRT9N12D3", & + "WKDFVRT9N12D4","WKDFVRT9N12D5","WKDFVRT9N12D6","WKDFVRT9N12D7","WKDFVRT9N12D8","WKDFVRT9N12D9", & + "WKDFVRT9N13D1","WKDFVRT9N13D2","WKDFVRT9N13D3","WKDFVRT9N13D4","WKDFVRT9N13D5","WKDFVRT9N13D6", & + "WKDFVRT9N13D7","WKDFVRT9N13D8","WKDFVRT9N13D9","WKDFVRT9N14D1","WKDFVRT9N14D2","WKDFVRT9N14D3", & + "WKDFVRT9N14D4","WKDFVRT9N14D5","WKDFVRT9N14D6","WKDFVRT9N14D7","WKDFVRT9N14D8","WKDFVRT9N14D9", & + "WKDFVRT9N15D1","WKDFVRT9N15D2","WKDFVRT9N15D3","WKDFVRT9N15D4","WKDFVRT9N15D5","WKDFVRT9N15D6", & + "WKDFVRT9N15D7","WKDFVRT9N15D8","WKDFVRT9N15D9","WKDFVRT9N16D1","WKDFVRT9N16D2","WKDFVRT9N16D3", & + "WKDFVRT9N16D4","WKDFVRT9N16D5","WKDFVRT9N16D6","WKDFVRT9N16D7","WKDFVRT9N16D8","WKDFVRT9N16D9", & + "WKDFVRT9N17D1","WKDFVRT9N17D2","WKDFVRT9N17D3","WKDFVRT9N17D4","WKDFVRT9N17D5","WKDFVRT9N17D6", & + "WKDFVRT9N17D7","WKDFVRT9N17D8","WKDFVRT9N17D9","WKDFVRT9N18D1","WKDFVRT9N18D2","WKDFVRT9N18D3", & + "WKDFVRT9N18D4","WKDFVRT9N18D5","WKDFVRT9N18D6","WKDFVRT9N18D7","WKDFVRT9N18D8","WKDFVRT9N18D9", & + "WKDFVRT9N19D1","WKDFVRT9N19D2","WKDFVRT9N19D3","WKDFVRT9N19D4","WKDFVRT9N19D5","WKDFVRT9N19D6", & + "WKDFVRT9N19D7","WKDFVRT9N19D8","WKDFVRT9N19D9","WKDFVRT9N20D1","WKDFVRT9N20D2","WKDFVRT9N20D3", & + "WKDFVRT9N20D4","WKDFVRT9N20D5","WKDFVRT9N20D6","WKDFVRT9N20D7","WKDFVRT9N20D8","WKDFVRT9N20D9", & + "WKDFVXT1N01D1","WKDFVXT1N01D2","WKDFVXT1N01D3","WKDFVXT1N01D4","WKDFVXT1N01D5","WKDFVXT1N01D6", & + "WKDFVXT1N01D7","WKDFVXT1N01D8","WKDFVXT1N01D9","WKDFVXT1N02D1","WKDFVXT1N02D2","WKDFVXT1N02D3", & + "WKDFVXT1N02D4","WKDFVXT1N02D5","WKDFVXT1N02D6","WKDFVXT1N02D7","WKDFVXT1N02D8","WKDFVXT1N02D9", & + "WKDFVXT1N03D1","WKDFVXT1N03D2","WKDFVXT1N03D3","WKDFVXT1N03D4","WKDFVXT1N03D5","WKDFVXT1N03D6", & + "WKDFVXT1N03D7","WKDFVXT1N03D8","WKDFVXT1N03D9","WKDFVXT1N04D1","WKDFVXT1N04D2","WKDFVXT1N04D3", & + "WKDFVXT1N04D4","WKDFVXT1N04D5","WKDFVXT1N04D6","WKDFVXT1N04D7","WKDFVXT1N04D8","WKDFVXT1N04D9", & + "WKDFVXT1N05D1","WKDFVXT1N05D2","WKDFVXT1N05D3","WKDFVXT1N05D4","WKDFVXT1N05D5","WKDFVXT1N05D6", & + "WKDFVXT1N05D7","WKDFVXT1N05D8","WKDFVXT1N05D9","WKDFVXT1N06D1","WKDFVXT1N06D2","WKDFVXT1N06D3", & + "WKDFVXT1N06D4","WKDFVXT1N06D5","WKDFVXT1N06D6","WKDFVXT1N06D7","WKDFVXT1N06D8","WKDFVXT1N06D9", & + "WKDFVXT1N07D1","WKDFVXT1N07D2","WKDFVXT1N07D3","WKDFVXT1N07D4","WKDFVXT1N07D5","WKDFVXT1N07D6", & + "WKDFVXT1N07D7","WKDFVXT1N07D8","WKDFVXT1N07D9","WKDFVXT1N08D1","WKDFVXT1N08D2","WKDFVXT1N08D3", & + "WKDFVXT1N08D4","WKDFVXT1N08D5","WKDFVXT1N08D6","WKDFVXT1N08D7","WKDFVXT1N08D8","WKDFVXT1N08D9", & + "WKDFVXT1N09D1","WKDFVXT1N09D2","WKDFVXT1N09D3","WKDFVXT1N09D4","WKDFVXT1N09D5","WKDFVXT1N09D6", & + "WKDFVXT1N09D7","WKDFVXT1N09D8","WKDFVXT1N09D9","WKDFVXT1N10D1","WKDFVXT1N10D2","WKDFVXT1N10D3", & + "WKDFVXT1N10D4","WKDFVXT1N10D5","WKDFVXT1N10D6","WKDFVXT1N10D7","WKDFVXT1N10D8","WKDFVXT1N10D9", & + "WKDFVXT1N11D1","WKDFVXT1N11D2","WKDFVXT1N11D3","WKDFVXT1N11D4","WKDFVXT1N11D5","WKDFVXT1N11D6", & + "WKDFVXT1N11D7","WKDFVXT1N11D8","WKDFVXT1N11D9","WKDFVXT1N12D1","WKDFVXT1N12D2","WKDFVXT1N12D3", & + "WKDFVXT1N12D4","WKDFVXT1N12D5","WKDFVXT1N12D6","WKDFVXT1N12D7","WKDFVXT1N12D8","WKDFVXT1N12D9", & + "WKDFVXT1N13D1","WKDFVXT1N13D2","WKDFVXT1N13D3","WKDFVXT1N13D4","WKDFVXT1N13D5","WKDFVXT1N13D6", & + "WKDFVXT1N13D7","WKDFVXT1N13D8","WKDFVXT1N13D9","WKDFVXT1N14D1","WKDFVXT1N14D2","WKDFVXT1N14D3", & + "WKDFVXT1N14D4","WKDFVXT1N14D5","WKDFVXT1N14D6","WKDFVXT1N14D7","WKDFVXT1N14D8","WKDFVXT1N14D9", & + "WKDFVXT1N15D1","WKDFVXT1N15D2","WKDFVXT1N15D3","WKDFVXT1N15D4","WKDFVXT1N15D5","WKDFVXT1N15D6", & + "WKDFVXT1N15D7","WKDFVXT1N15D8","WKDFVXT1N15D9","WKDFVXT1N16D1","WKDFVXT1N16D2","WKDFVXT1N16D3", & + "WKDFVXT1N16D4","WKDFVXT1N16D5","WKDFVXT1N16D6","WKDFVXT1N16D7","WKDFVXT1N16D8","WKDFVXT1N16D9", & + "WKDFVXT1N17D1","WKDFVXT1N17D2","WKDFVXT1N17D3","WKDFVXT1N17D4","WKDFVXT1N17D5","WKDFVXT1N17D6", & + "WKDFVXT1N17D7","WKDFVXT1N17D8","WKDFVXT1N17D9","WKDFVXT1N18D1","WKDFVXT1N18D2","WKDFVXT1N18D3", & + "WKDFVXT1N18D4","WKDFVXT1N18D5","WKDFVXT1N18D6","WKDFVXT1N18D7","WKDFVXT1N18D8","WKDFVXT1N18D9", & + "WKDFVXT1N19D1","WKDFVXT1N19D2","WKDFVXT1N19D3","WKDFVXT1N19D4","WKDFVXT1N19D5","WKDFVXT1N19D6", & + "WKDFVXT1N19D7","WKDFVXT1N19D8","WKDFVXT1N19D9","WKDFVXT1N20D1","WKDFVXT1N20D2","WKDFVXT1N20D3", & + "WKDFVXT1N20D4","WKDFVXT1N20D5","WKDFVXT1N20D6","WKDFVXT1N20D7","WKDFVXT1N20D8","WKDFVXT1N20D9", & + "WKDFVXT2N01D1","WKDFVXT2N01D2","WKDFVXT2N01D3","WKDFVXT2N01D4","WKDFVXT2N01D5","WKDFVXT2N01D6", & + "WKDFVXT2N01D7","WKDFVXT2N01D8","WKDFVXT2N01D9","WKDFVXT2N02D1","WKDFVXT2N02D2","WKDFVXT2N02D3", & + "WKDFVXT2N02D4","WKDFVXT2N02D5","WKDFVXT2N02D6","WKDFVXT2N02D7","WKDFVXT2N02D8","WKDFVXT2N02D9", & + "WKDFVXT2N03D1","WKDFVXT2N03D2","WKDFVXT2N03D3","WKDFVXT2N03D4","WKDFVXT2N03D5","WKDFVXT2N03D6", & + "WKDFVXT2N03D7","WKDFVXT2N03D8","WKDFVXT2N03D9","WKDFVXT2N04D1","WKDFVXT2N04D2","WKDFVXT2N04D3", & + "WKDFVXT2N04D4","WKDFVXT2N04D5","WKDFVXT2N04D6","WKDFVXT2N04D7","WKDFVXT2N04D8","WKDFVXT2N04D9", & + "WKDFVXT2N05D1","WKDFVXT2N05D2","WKDFVXT2N05D3","WKDFVXT2N05D4","WKDFVXT2N05D5","WKDFVXT2N05D6", & + "WKDFVXT2N05D7","WKDFVXT2N05D8","WKDFVXT2N05D9","WKDFVXT2N06D1","WKDFVXT2N06D2","WKDFVXT2N06D3", & + "WKDFVXT2N06D4","WKDFVXT2N06D5","WKDFVXT2N06D6","WKDFVXT2N06D7","WKDFVXT2N06D8","WKDFVXT2N06D9", & + "WKDFVXT2N07D1","WKDFVXT2N07D2","WKDFVXT2N07D3","WKDFVXT2N07D4","WKDFVXT2N07D5","WKDFVXT2N07D6", & + "WKDFVXT2N07D7","WKDFVXT2N07D8","WKDFVXT2N07D9","WKDFVXT2N08D1","WKDFVXT2N08D2","WKDFVXT2N08D3", & + "WKDFVXT2N08D4","WKDFVXT2N08D5","WKDFVXT2N08D6","WKDFVXT2N08D7","WKDFVXT2N08D8","WKDFVXT2N08D9", & + "WKDFVXT2N09D1","WKDFVXT2N09D2","WKDFVXT2N09D3","WKDFVXT2N09D4","WKDFVXT2N09D5","WKDFVXT2N09D6", & + "WKDFVXT2N09D7","WKDFVXT2N09D8","WKDFVXT2N09D9","WKDFVXT2N10D1","WKDFVXT2N10D2","WKDFVXT2N10D3", & + "WKDFVXT2N10D4","WKDFVXT2N10D5","WKDFVXT2N10D6","WKDFVXT2N10D7","WKDFVXT2N10D8","WKDFVXT2N10D9", & + "WKDFVXT2N11D1","WKDFVXT2N11D2","WKDFVXT2N11D3","WKDFVXT2N11D4","WKDFVXT2N11D5","WKDFVXT2N11D6", & + "WKDFVXT2N11D7","WKDFVXT2N11D8","WKDFVXT2N11D9","WKDFVXT2N12D1","WKDFVXT2N12D2","WKDFVXT2N12D3", & + "WKDFVXT2N12D4","WKDFVXT2N12D5","WKDFVXT2N12D6","WKDFVXT2N12D7","WKDFVXT2N12D8","WKDFVXT2N12D9", & + "WKDFVXT2N13D1","WKDFVXT2N13D2","WKDFVXT2N13D3","WKDFVXT2N13D4","WKDFVXT2N13D5","WKDFVXT2N13D6", & + "WKDFVXT2N13D7","WKDFVXT2N13D8","WKDFVXT2N13D9","WKDFVXT2N14D1","WKDFVXT2N14D2","WKDFVXT2N14D3", & + "WKDFVXT2N14D4","WKDFVXT2N14D5","WKDFVXT2N14D6","WKDFVXT2N14D7","WKDFVXT2N14D8","WKDFVXT2N14D9", & + "WKDFVXT2N15D1","WKDFVXT2N15D2","WKDFVXT2N15D3","WKDFVXT2N15D4","WKDFVXT2N15D5","WKDFVXT2N15D6", & + "WKDFVXT2N15D7","WKDFVXT2N15D8","WKDFVXT2N15D9","WKDFVXT2N16D1","WKDFVXT2N16D2","WKDFVXT2N16D3", & + "WKDFVXT2N16D4","WKDFVXT2N16D5","WKDFVXT2N16D6","WKDFVXT2N16D7","WKDFVXT2N16D8","WKDFVXT2N16D9", & + "WKDFVXT2N17D1","WKDFVXT2N17D2","WKDFVXT2N17D3","WKDFVXT2N17D4","WKDFVXT2N17D5","WKDFVXT2N17D6", & + "WKDFVXT2N17D7","WKDFVXT2N17D8","WKDFVXT2N17D9","WKDFVXT2N18D1","WKDFVXT2N18D2","WKDFVXT2N18D3", & + "WKDFVXT2N18D4","WKDFVXT2N18D5","WKDFVXT2N18D6","WKDFVXT2N18D7","WKDFVXT2N18D8","WKDFVXT2N18D9", & + "WKDFVXT2N19D1","WKDFVXT2N19D2","WKDFVXT2N19D3","WKDFVXT2N19D4","WKDFVXT2N19D5","WKDFVXT2N19D6", & + "WKDFVXT2N19D7","WKDFVXT2N19D8","WKDFVXT2N19D9","WKDFVXT2N20D1","WKDFVXT2N20D2","WKDFVXT2N20D3", & + "WKDFVXT2N20D4","WKDFVXT2N20D5","WKDFVXT2N20D6","WKDFVXT2N20D7","WKDFVXT2N20D8","WKDFVXT2N20D9", & + "WKDFVXT3N01D1","WKDFVXT3N01D2","WKDFVXT3N01D3","WKDFVXT3N01D4","WKDFVXT3N01D5","WKDFVXT3N01D6", & + "WKDFVXT3N01D7","WKDFVXT3N01D8","WKDFVXT3N01D9","WKDFVXT3N02D1","WKDFVXT3N02D2","WKDFVXT3N02D3", & + "WKDFVXT3N02D4","WKDFVXT3N02D5","WKDFVXT3N02D6","WKDFVXT3N02D7","WKDFVXT3N02D8","WKDFVXT3N02D9", & + "WKDFVXT3N03D1","WKDFVXT3N03D2","WKDFVXT3N03D3","WKDFVXT3N03D4","WKDFVXT3N03D5","WKDFVXT3N03D6", & + "WKDFVXT3N03D7","WKDFVXT3N03D8","WKDFVXT3N03D9","WKDFVXT3N04D1","WKDFVXT3N04D2","WKDFVXT3N04D3", & + "WKDFVXT3N04D4","WKDFVXT3N04D5","WKDFVXT3N04D6","WKDFVXT3N04D7","WKDFVXT3N04D8","WKDFVXT3N04D9", & + "WKDFVXT3N05D1","WKDFVXT3N05D2","WKDFVXT3N05D3","WKDFVXT3N05D4","WKDFVXT3N05D5","WKDFVXT3N05D6", & + "WKDFVXT3N05D7","WKDFVXT3N05D8","WKDFVXT3N05D9","WKDFVXT3N06D1","WKDFVXT3N06D2","WKDFVXT3N06D3", & + "WKDFVXT3N06D4","WKDFVXT3N06D5","WKDFVXT3N06D6","WKDFVXT3N06D7","WKDFVXT3N06D8","WKDFVXT3N06D9", & + "WKDFVXT3N07D1","WKDFVXT3N07D2","WKDFVXT3N07D3","WKDFVXT3N07D4","WKDFVXT3N07D5","WKDFVXT3N07D6", & + "WKDFVXT3N07D7","WKDFVXT3N07D8","WKDFVXT3N07D9","WKDFVXT3N08D1","WKDFVXT3N08D2","WKDFVXT3N08D3", & + "WKDFVXT3N08D4","WKDFVXT3N08D5","WKDFVXT3N08D6","WKDFVXT3N08D7","WKDFVXT3N08D8","WKDFVXT3N08D9", & + "WKDFVXT3N09D1","WKDFVXT3N09D2","WKDFVXT3N09D3","WKDFVXT3N09D4","WKDFVXT3N09D5","WKDFVXT3N09D6", & + "WKDFVXT3N09D7","WKDFVXT3N09D8","WKDFVXT3N09D9","WKDFVXT3N10D1","WKDFVXT3N10D2","WKDFVXT3N10D3", & + "WKDFVXT3N10D4","WKDFVXT3N10D5","WKDFVXT3N10D6","WKDFVXT3N10D7","WKDFVXT3N10D8","WKDFVXT3N10D9", & + "WKDFVXT3N11D1","WKDFVXT3N11D2","WKDFVXT3N11D3","WKDFVXT3N11D4","WKDFVXT3N11D5","WKDFVXT3N11D6", & + "WKDFVXT3N11D7","WKDFVXT3N11D8","WKDFVXT3N11D9","WKDFVXT3N12D1","WKDFVXT3N12D2","WKDFVXT3N12D3", & + "WKDFVXT3N12D4","WKDFVXT3N12D5","WKDFVXT3N12D6","WKDFVXT3N12D7","WKDFVXT3N12D8","WKDFVXT3N12D9", & + "WKDFVXT3N13D1","WKDFVXT3N13D2","WKDFVXT3N13D3","WKDFVXT3N13D4","WKDFVXT3N13D5","WKDFVXT3N13D6", & + "WKDFVXT3N13D7","WKDFVXT3N13D8","WKDFVXT3N13D9","WKDFVXT3N14D1","WKDFVXT3N14D2","WKDFVXT3N14D3", & + "WKDFVXT3N14D4","WKDFVXT3N14D5","WKDFVXT3N14D6","WKDFVXT3N14D7","WKDFVXT3N14D8","WKDFVXT3N14D9", & + "WKDFVXT3N15D1","WKDFVXT3N15D2","WKDFVXT3N15D3","WKDFVXT3N15D4","WKDFVXT3N15D5","WKDFVXT3N15D6", & + "WKDFVXT3N15D7","WKDFVXT3N15D8","WKDFVXT3N15D9","WKDFVXT3N16D1","WKDFVXT3N16D2","WKDFVXT3N16D3", & + "WKDFVXT3N16D4","WKDFVXT3N16D5","WKDFVXT3N16D6","WKDFVXT3N16D7","WKDFVXT3N16D8","WKDFVXT3N16D9", & + "WKDFVXT3N17D1","WKDFVXT3N17D2","WKDFVXT3N17D3","WKDFVXT3N17D4","WKDFVXT3N17D5","WKDFVXT3N17D6", & + "WKDFVXT3N17D7","WKDFVXT3N17D8","WKDFVXT3N17D9","WKDFVXT3N18D1","WKDFVXT3N18D2","WKDFVXT3N18D3", & + "WKDFVXT3N18D4","WKDFVXT3N18D5","WKDFVXT3N18D6","WKDFVXT3N18D7","WKDFVXT3N18D8","WKDFVXT3N18D9", & + "WKDFVXT3N19D1","WKDFVXT3N19D2","WKDFVXT3N19D3","WKDFVXT3N19D4","WKDFVXT3N19D5","WKDFVXT3N19D6", & + "WKDFVXT3N19D7","WKDFVXT3N19D8","WKDFVXT3N19D9","WKDFVXT3N20D1","WKDFVXT3N20D2","WKDFVXT3N20D3", & + "WKDFVXT3N20D4","WKDFVXT3N20D5","WKDFVXT3N20D6","WKDFVXT3N20D7","WKDFVXT3N20D8","WKDFVXT3N20D9", & + "WKDFVXT4N01D1","WKDFVXT4N01D2","WKDFVXT4N01D3","WKDFVXT4N01D4","WKDFVXT4N01D5","WKDFVXT4N01D6", & + "WKDFVXT4N01D7","WKDFVXT4N01D8","WKDFVXT4N01D9","WKDFVXT4N02D1","WKDFVXT4N02D2","WKDFVXT4N02D3", & + "WKDFVXT4N02D4","WKDFVXT4N02D5","WKDFVXT4N02D6","WKDFVXT4N02D7","WKDFVXT4N02D8","WKDFVXT4N02D9", & + "WKDFVXT4N03D1","WKDFVXT4N03D2","WKDFVXT4N03D3","WKDFVXT4N03D4","WKDFVXT4N03D5","WKDFVXT4N03D6", & + "WKDFVXT4N03D7","WKDFVXT4N03D8","WKDFVXT4N03D9","WKDFVXT4N04D1","WKDFVXT4N04D2","WKDFVXT4N04D3", & + "WKDFVXT4N04D4","WKDFVXT4N04D5","WKDFVXT4N04D6","WKDFVXT4N04D7","WKDFVXT4N04D8","WKDFVXT4N04D9", & + "WKDFVXT4N05D1","WKDFVXT4N05D2","WKDFVXT4N05D3","WKDFVXT4N05D4","WKDFVXT4N05D5","WKDFVXT4N05D6", & + "WKDFVXT4N05D7","WKDFVXT4N05D8","WKDFVXT4N05D9","WKDFVXT4N06D1","WKDFVXT4N06D2","WKDFVXT4N06D3", & + "WKDFVXT4N06D4","WKDFVXT4N06D5","WKDFVXT4N06D6","WKDFVXT4N06D7","WKDFVXT4N06D8","WKDFVXT4N06D9", & + "WKDFVXT4N07D1","WKDFVXT4N07D2","WKDFVXT4N07D3","WKDFVXT4N07D4","WKDFVXT4N07D5","WKDFVXT4N07D6", & + "WKDFVXT4N07D7","WKDFVXT4N07D8","WKDFVXT4N07D9","WKDFVXT4N08D1","WKDFVXT4N08D2","WKDFVXT4N08D3", & + "WKDFVXT4N08D4","WKDFVXT4N08D5","WKDFVXT4N08D6","WKDFVXT4N08D7","WKDFVXT4N08D8","WKDFVXT4N08D9", & + "WKDFVXT4N09D1","WKDFVXT4N09D2","WKDFVXT4N09D3","WKDFVXT4N09D4","WKDFVXT4N09D5","WKDFVXT4N09D6", & + "WKDFVXT4N09D7","WKDFVXT4N09D8","WKDFVXT4N09D9","WKDFVXT4N10D1","WKDFVXT4N10D2","WKDFVXT4N10D3", & + "WKDFVXT4N10D4","WKDFVXT4N10D5","WKDFVXT4N10D6","WKDFVXT4N10D7","WKDFVXT4N10D8","WKDFVXT4N10D9", & + "WKDFVXT4N11D1","WKDFVXT4N11D2","WKDFVXT4N11D3","WKDFVXT4N11D4","WKDFVXT4N11D5","WKDFVXT4N11D6", & + "WKDFVXT4N11D7","WKDFVXT4N11D8","WKDFVXT4N11D9","WKDFVXT4N12D1","WKDFVXT4N12D2","WKDFVXT4N12D3", & + "WKDFVXT4N12D4","WKDFVXT4N12D5","WKDFVXT4N12D6","WKDFVXT4N12D7","WKDFVXT4N12D8","WKDFVXT4N12D9", & + "WKDFVXT4N13D1","WKDFVXT4N13D2","WKDFVXT4N13D3","WKDFVXT4N13D4","WKDFVXT4N13D5","WKDFVXT4N13D6", & + "WKDFVXT4N13D7","WKDFVXT4N13D8","WKDFVXT4N13D9","WKDFVXT4N14D1","WKDFVXT4N14D2","WKDFVXT4N14D3", & + "WKDFVXT4N14D4","WKDFVXT4N14D5","WKDFVXT4N14D6","WKDFVXT4N14D7","WKDFVXT4N14D8","WKDFVXT4N14D9", & + "WKDFVXT4N15D1","WKDFVXT4N15D2","WKDFVXT4N15D3","WKDFVXT4N15D4","WKDFVXT4N15D5","WKDFVXT4N15D6", & + "WKDFVXT4N15D7","WKDFVXT4N15D8","WKDFVXT4N15D9","WKDFVXT4N16D1","WKDFVXT4N16D2","WKDFVXT4N16D3", & + "WKDFVXT4N16D4","WKDFVXT4N16D5","WKDFVXT4N16D6","WKDFVXT4N16D7","WKDFVXT4N16D8","WKDFVXT4N16D9", & + "WKDFVXT4N17D1","WKDFVXT4N17D2","WKDFVXT4N17D3","WKDFVXT4N17D4","WKDFVXT4N17D5","WKDFVXT4N17D6", & + "WKDFVXT4N17D7","WKDFVXT4N17D8","WKDFVXT4N17D9","WKDFVXT4N18D1","WKDFVXT4N18D2","WKDFVXT4N18D3", & + "WKDFVXT4N18D4","WKDFVXT4N18D5","WKDFVXT4N18D6","WKDFVXT4N18D7","WKDFVXT4N18D8","WKDFVXT4N18D9", & + "WKDFVXT4N19D1","WKDFVXT4N19D2","WKDFVXT4N19D3","WKDFVXT4N19D4","WKDFVXT4N19D5","WKDFVXT4N19D6", & + "WKDFVXT4N19D7","WKDFVXT4N19D8","WKDFVXT4N19D9","WKDFVXT4N20D1","WKDFVXT4N20D2","WKDFVXT4N20D3", & + "WKDFVXT4N20D4","WKDFVXT4N20D5","WKDFVXT4N20D6","WKDFVXT4N20D7","WKDFVXT4N20D8","WKDFVXT4N20D9", & + "WKDFVXT5N01D1","WKDFVXT5N01D2","WKDFVXT5N01D3","WKDFVXT5N01D4","WKDFVXT5N01D5","WKDFVXT5N01D6", & + "WKDFVXT5N01D7","WKDFVXT5N01D8","WKDFVXT5N01D9","WKDFVXT5N02D1","WKDFVXT5N02D2","WKDFVXT5N02D3", & + "WKDFVXT5N02D4","WKDFVXT5N02D5","WKDFVXT5N02D6","WKDFVXT5N02D7","WKDFVXT5N02D8","WKDFVXT5N02D9", & + "WKDFVXT5N03D1","WKDFVXT5N03D2","WKDFVXT5N03D3","WKDFVXT5N03D4","WKDFVXT5N03D5","WKDFVXT5N03D6", & + "WKDFVXT5N03D7","WKDFVXT5N03D8","WKDFVXT5N03D9","WKDFVXT5N04D1","WKDFVXT5N04D2","WKDFVXT5N04D3", & + "WKDFVXT5N04D4","WKDFVXT5N04D5","WKDFVXT5N04D6","WKDFVXT5N04D7","WKDFVXT5N04D8","WKDFVXT5N04D9", & + "WKDFVXT5N05D1","WKDFVXT5N05D2","WKDFVXT5N05D3","WKDFVXT5N05D4","WKDFVXT5N05D5","WKDFVXT5N05D6", & + "WKDFVXT5N05D7","WKDFVXT5N05D8","WKDFVXT5N05D9","WKDFVXT5N06D1","WKDFVXT5N06D2","WKDFVXT5N06D3", & + "WKDFVXT5N06D4","WKDFVXT5N06D5","WKDFVXT5N06D6","WKDFVXT5N06D7","WKDFVXT5N06D8","WKDFVXT5N06D9", & + "WKDFVXT5N07D1","WKDFVXT5N07D2","WKDFVXT5N07D3","WKDFVXT5N07D4","WKDFVXT5N07D5","WKDFVXT5N07D6", & + "WKDFVXT5N07D7","WKDFVXT5N07D8","WKDFVXT5N07D9","WKDFVXT5N08D1","WKDFVXT5N08D2","WKDFVXT5N08D3", & + "WKDFVXT5N08D4","WKDFVXT5N08D5","WKDFVXT5N08D6","WKDFVXT5N08D7","WKDFVXT5N08D8","WKDFVXT5N08D9", & + "WKDFVXT5N09D1","WKDFVXT5N09D2","WKDFVXT5N09D3","WKDFVXT5N09D4","WKDFVXT5N09D5","WKDFVXT5N09D6", & + "WKDFVXT5N09D7","WKDFVXT5N09D8","WKDFVXT5N09D9","WKDFVXT5N10D1","WKDFVXT5N10D2","WKDFVXT5N10D3", & + "WKDFVXT5N10D4","WKDFVXT5N10D5","WKDFVXT5N10D6","WKDFVXT5N10D7","WKDFVXT5N10D8","WKDFVXT5N10D9", & + "WKDFVXT5N11D1","WKDFVXT5N11D2","WKDFVXT5N11D3","WKDFVXT5N11D4","WKDFVXT5N11D5","WKDFVXT5N11D6", & + "WKDFVXT5N11D7","WKDFVXT5N11D8","WKDFVXT5N11D9","WKDFVXT5N12D1","WKDFVXT5N12D2","WKDFVXT5N12D3", & + "WKDFVXT5N12D4","WKDFVXT5N12D5","WKDFVXT5N12D6","WKDFVXT5N12D7","WKDFVXT5N12D8","WKDFVXT5N12D9", & + "WKDFVXT5N13D1","WKDFVXT5N13D2","WKDFVXT5N13D3","WKDFVXT5N13D4","WKDFVXT5N13D5","WKDFVXT5N13D6", & + "WKDFVXT5N13D7","WKDFVXT5N13D8","WKDFVXT5N13D9","WKDFVXT5N14D1","WKDFVXT5N14D2","WKDFVXT5N14D3", & + "WKDFVXT5N14D4","WKDFVXT5N14D5","WKDFVXT5N14D6","WKDFVXT5N14D7","WKDFVXT5N14D8","WKDFVXT5N14D9"/) + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry7(1350) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "WKDFVXT5N15D1","WKDFVXT5N15D2","WKDFVXT5N15D3","WKDFVXT5N15D4","WKDFVXT5N15D5","WKDFVXT5N15D6", & + "WKDFVXT5N15D7","WKDFVXT5N15D8","WKDFVXT5N15D9","WKDFVXT5N16D1","WKDFVXT5N16D2","WKDFVXT5N16D3", & + "WKDFVXT5N16D4","WKDFVXT5N16D5","WKDFVXT5N16D6","WKDFVXT5N16D7","WKDFVXT5N16D8","WKDFVXT5N16D9", & + "WKDFVXT5N17D1","WKDFVXT5N17D2","WKDFVXT5N17D3","WKDFVXT5N17D4","WKDFVXT5N17D5","WKDFVXT5N17D6", & + "WKDFVXT5N17D7","WKDFVXT5N17D8","WKDFVXT5N17D9","WKDFVXT5N18D1","WKDFVXT5N18D2","WKDFVXT5N18D3", & + "WKDFVXT5N18D4","WKDFVXT5N18D5","WKDFVXT5N18D6","WKDFVXT5N18D7","WKDFVXT5N18D8","WKDFVXT5N18D9", & + "WKDFVXT5N19D1","WKDFVXT5N19D2","WKDFVXT5N19D3","WKDFVXT5N19D4","WKDFVXT5N19D5","WKDFVXT5N19D6", & + "WKDFVXT5N19D7","WKDFVXT5N19D8","WKDFVXT5N19D9","WKDFVXT5N20D1","WKDFVXT5N20D2","WKDFVXT5N20D3", & + "WKDFVXT5N20D4","WKDFVXT5N20D5","WKDFVXT5N20D6","WKDFVXT5N20D7","WKDFVXT5N20D8","WKDFVXT5N20D9", & + "WKDFVXT6N01D1","WKDFVXT6N01D2","WKDFVXT6N01D3","WKDFVXT6N01D4","WKDFVXT6N01D5","WKDFVXT6N01D6", & + "WKDFVXT6N01D7","WKDFVXT6N01D8","WKDFVXT6N01D9","WKDFVXT6N02D1","WKDFVXT6N02D2","WKDFVXT6N02D3", & + "WKDFVXT6N02D4","WKDFVXT6N02D5","WKDFVXT6N02D6","WKDFVXT6N02D7","WKDFVXT6N02D8","WKDFVXT6N02D9", & + "WKDFVXT6N03D1","WKDFVXT6N03D2","WKDFVXT6N03D3","WKDFVXT6N03D4","WKDFVXT6N03D5","WKDFVXT6N03D6", & + "WKDFVXT6N03D7","WKDFVXT6N03D8","WKDFVXT6N03D9","WKDFVXT6N04D1","WKDFVXT6N04D2","WKDFVXT6N04D3", & + "WKDFVXT6N04D4","WKDFVXT6N04D5","WKDFVXT6N04D6","WKDFVXT6N04D7","WKDFVXT6N04D8","WKDFVXT6N04D9", & + "WKDFVXT6N05D1","WKDFVXT6N05D2","WKDFVXT6N05D3","WKDFVXT6N05D4","WKDFVXT6N05D5","WKDFVXT6N05D6", & + "WKDFVXT6N05D7","WKDFVXT6N05D8","WKDFVXT6N05D9","WKDFVXT6N06D1","WKDFVXT6N06D2","WKDFVXT6N06D3", & + "WKDFVXT6N06D4","WKDFVXT6N06D5","WKDFVXT6N06D6","WKDFVXT6N06D7","WKDFVXT6N06D8","WKDFVXT6N06D9", & + "WKDFVXT6N07D1","WKDFVXT6N07D2","WKDFVXT6N07D3","WKDFVXT6N07D4","WKDFVXT6N07D5","WKDFVXT6N07D6", & + "WKDFVXT6N07D7","WKDFVXT6N07D8","WKDFVXT6N07D9","WKDFVXT6N08D1","WKDFVXT6N08D2","WKDFVXT6N08D3", & + "WKDFVXT6N08D4","WKDFVXT6N08D5","WKDFVXT6N08D6","WKDFVXT6N08D7","WKDFVXT6N08D8","WKDFVXT6N08D9", & + "WKDFVXT6N09D1","WKDFVXT6N09D2","WKDFVXT6N09D3","WKDFVXT6N09D4","WKDFVXT6N09D5","WKDFVXT6N09D6", & + "WKDFVXT6N09D7","WKDFVXT6N09D8","WKDFVXT6N09D9","WKDFVXT6N10D1","WKDFVXT6N10D2","WKDFVXT6N10D3", & + "WKDFVXT6N10D4","WKDFVXT6N10D5","WKDFVXT6N10D6","WKDFVXT6N10D7","WKDFVXT6N10D8","WKDFVXT6N10D9", & + "WKDFVXT6N11D1","WKDFVXT6N11D2","WKDFVXT6N11D3","WKDFVXT6N11D4","WKDFVXT6N11D5","WKDFVXT6N11D6", & + "WKDFVXT6N11D7","WKDFVXT6N11D8","WKDFVXT6N11D9","WKDFVXT6N12D1","WKDFVXT6N12D2","WKDFVXT6N12D3", & + "WKDFVXT6N12D4","WKDFVXT6N12D5","WKDFVXT6N12D6","WKDFVXT6N12D7","WKDFVXT6N12D8","WKDFVXT6N12D9", & + "WKDFVXT6N13D1","WKDFVXT6N13D2","WKDFVXT6N13D3","WKDFVXT6N13D4","WKDFVXT6N13D5","WKDFVXT6N13D6", & + "WKDFVXT6N13D7","WKDFVXT6N13D8","WKDFVXT6N13D9","WKDFVXT6N14D1","WKDFVXT6N14D2","WKDFVXT6N14D3", & + "WKDFVXT6N14D4","WKDFVXT6N14D5","WKDFVXT6N14D6","WKDFVXT6N14D7","WKDFVXT6N14D8","WKDFVXT6N14D9", & + "WKDFVXT6N15D1","WKDFVXT6N15D2","WKDFVXT6N15D3","WKDFVXT6N15D4","WKDFVXT6N15D5","WKDFVXT6N15D6", & + "WKDFVXT6N15D7","WKDFVXT6N15D8","WKDFVXT6N15D9","WKDFVXT6N16D1","WKDFVXT6N16D2","WKDFVXT6N16D3", & + "WKDFVXT6N16D4","WKDFVXT6N16D5","WKDFVXT6N16D6","WKDFVXT6N16D7","WKDFVXT6N16D8","WKDFVXT6N16D9", & + "WKDFVXT6N17D1","WKDFVXT6N17D2","WKDFVXT6N17D3","WKDFVXT6N17D4","WKDFVXT6N17D5","WKDFVXT6N17D6", & + "WKDFVXT6N17D7","WKDFVXT6N17D8","WKDFVXT6N17D9","WKDFVXT6N18D1","WKDFVXT6N18D2","WKDFVXT6N18D3", & + "WKDFVXT6N18D4","WKDFVXT6N18D5","WKDFVXT6N18D6","WKDFVXT6N18D7","WKDFVXT6N18D8","WKDFVXT6N18D9", & + "WKDFVXT6N19D1","WKDFVXT6N19D2","WKDFVXT6N19D3","WKDFVXT6N19D4","WKDFVXT6N19D5","WKDFVXT6N19D6", & + "WKDFVXT6N19D7","WKDFVXT6N19D8","WKDFVXT6N19D9","WKDFVXT6N20D1","WKDFVXT6N20D2","WKDFVXT6N20D3", & + "WKDFVXT6N20D4","WKDFVXT6N20D5","WKDFVXT6N20D6","WKDFVXT6N20D7","WKDFVXT6N20D8","WKDFVXT6N20D9", & + "WKDFVXT7N01D1","WKDFVXT7N01D2","WKDFVXT7N01D3","WKDFVXT7N01D4","WKDFVXT7N01D5","WKDFVXT7N01D6", & + "WKDFVXT7N01D7","WKDFVXT7N01D8","WKDFVXT7N01D9","WKDFVXT7N02D1","WKDFVXT7N02D2","WKDFVXT7N02D3", & + "WKDFVXT7N02D4","WKDFVXT7N02D5","WKDFVXT7N02D6","WKDFVXT7N02D7","WKDFVXT7N02D8","WKDFVXT7N02D9", & + "WKDFVXT7N03D1","WKDFVXT7N03D2","WKDFVXT7N03D3","WKDFVXT7N03D4","WKDFVXT7N03D5","WKDFVXT7N03D6", & + "WKDFVXT7N03D7","WKDFVXT7N03D8","WKDFVXT7N03D9","WKDFVXT7N04D1","WKDFVXT7N04D2","WKDFVXT7N04D3", & + "WKDFVXT7N04D4","WKDFVXT7N04D5","WKDFVXT7N04D6","WKDFVXT7N04D7","WKDFVXT7N04D8","WKDFVXT7N04D9", & + "WKDFVXT7N05D1","WKDFVXT7N05D2","WKDFVXT7N05D3","WKDFVXT7N05D4","WKDFVXT7N05D5","WKDFVXT7N05D6", & + "WKDFVXT7N05D7","WKDFVXT7N05D8","WKDFVXT7N05D9","WKDFVXT7N06D1","WKDFVXT7N06D2","WKDFVXT7N06D3", & + "WKDFVXT7N06D4","WKDFVXT7N06D5","WKDFVXT7N06D6","WKDFVXT7N06D7","WKDFVXT7N06D8","WKDFVXT7N06D9", & + "WKDFVXT7N07D1","WKDFVXT7N07D2","WKDFVXT7N07D3","WKDFVXT7N07D4","WKDFVXT7N07D5","WKDFVXT7N07D6", & + "WKDFVXT7N07D7","WKDFVXT7N07D8","WKDFVXT7N07D9","WKDFVXT7N08D1","WKDFVXT7N08D2","WKDFVXT7N08D3", & + "WKDFVXT7N08D4","WKDFVXT7N08D5","WKDFVXT7N08D6","WKDFVXT7N08D7","WKDFVXT7N08D8","WKDFVXT7N08D9", & + "WKDFVXT7N09D1","WKDFVXT7N09D2","WKDFVXT7N09D3","WKDFVXT7N09D4","WKDFVXT7N09D5","WKDFVXT7N09D6", & + "WKDFVXT7N09D7","WKDFVXT7N09D8","WKDFVXT7N09D9","WKDFVXT7N10D1","WKDFVXT7N10D2","WKDFVXT7N10D3", & + "WKDFVXT7N10D4","WKDFVXT7N10D5","WKDFVXT7N10D6","WKDFVXT7N10D7","WKDFVXT7N10D8","WKDFVXT7N10D9", & + "WKDFVXT7N11D1","WKDFVXT7N11D2","WKDFVXT7N11D3","WKDFVXT7N11D4","WKDFVXT7N11D5","WKDFVXT7N11D6", & + "WKDFVXT7N11D7","WKDFVXT7N11D8","WKDFVXT7N11D9","WKDFVXT7N12D1","WKDFVXT7N12D2","WKDFVXT7N12D3", & + "WKDFVXT7N12D4","WKDFVXT7N12D5","WKDFVXT7N12D6","WKDFVXT7N12D7","WKDFVXT7N12D8","WKDFVXT7N12D9", & + "WKDFVXT7N13D1","WKDFVXT7N13D2","WKDFVXT7N13D3","WKDFVXT7N13D4","WKDFVXT7N13D5","WKDFVXT7N13D6", & + "WKDFVXT7N13D7","WKDFVXT7N13D8","WKDFVXT7N13D9","WKDFVXT7N14D1","WKDFVXT7N14D2","WKDFVXT7N14D3", & + "WKDFVXT7N14D4","WKDFVXT7N14D5","WKDFVXT7N14D6","WKDFVXT7N14D7","WKDFVXT7N14D8","WKDFVXT7N14D9", & + "WKDFVXT7N15D1","WKDFVXT7N15D2","WKDFVXT7N15D3","WKDFVXT7N15D4","WKDFVXT7N15D5","WKDFVXT7N15D6", & + "WKDFVXT7N15D7","WKDFVXT7N15D8","WKDFVXT7N15D9","WKDFVXT7N16D1","WKDFVXT7N16D2","WKDFVXT7N16D3", & + "WKDFVXT7N16D4","WKDFVXT7N16D5","WKDFVXT7N16D6","WKDFVXT7N16D7","WKDFVXT7N16D8","WKDFVXT7N16D9", & + "WKDFVXT7N17D1","WKDFVXT7N17D2","WKDFVXT7N17D3","WKDFVXT7N17D4","WKDFVXT7N17D5","WKDFVXT7N17D6", & + "WKDFVXT7N17D7","WKDFVXT7N17D8","WKDFVXT7N17D9","WKDFVXT7N18D1","WKDFVXT7N18D2","WKDFVXT7N18D3", & + "WKDFVXT7N18D4","WKDFVXT7N18D5","WKDFVXT7N18D6","WKDFVXT7N18D7","WKDFVXT7N18D8","WKDFVXT7N18D9", & + "WKDFVXT7N19D1","WKDFVXT7N19D2","WKDFVXT7N19D3","WKDFVXT7N19D4","WKDFVXT7N19D5","WKDFVXT7N19D6", & + "WKDFVXT7N19D7","WKDFVXT7N19D8","WKDFVXT7N19D9","WKDFVXT7N20D1","WKDFVXT7N20D2","WKDFVXT7N20D3", & + "WKDFVXT7N20D4","WKDFVXT7N20D5","WKDFVXT7N20D6","WKDFVXT7N20D7","WKDFVXT7N20D8","WKDFVXT7N20D9", & + "WKDFVXT8N01D1","WKDFVXT8N01D2","WKDFVXT8N01D3","WKDFVXT8N01D4","WKDFVXT8N01D5","WKDFVXT8N01D6", & + "WKDFVXT8N01D7","WKDFVXT8N01D8","WKDFVXT8N01D9","WKDFVXT8N02D1","WKDFVXT8N02D2","WKDFVXT8N02D3", & + "WKDFVXT8N02D4","WKDFVXT8N02D5","WKDFVXT8N02D6","WKDFVXT8N02D7","WKDFVXT8N02D8","WKDFVXT8N02D9", & + "WKDFVXT8N03D1","WKDFVXT8N03D2","WKDFVXT8N03D3","WKDFVXT8N03D4","WKDFVXT8N03D5","WKDFVXT8N03D6", & + "WKDFVXT8N03D7","WKDFVXT8N03D8","WKDFVXT8N03D9","WKDFVXT8N04D1","WKDFVXT8N04D2","WKDFVXT8N04D3", & + "WKDFVXT8N04D4","WKDFVXT8N04D5","WKDFVXT8N04D6","WKDFVXT8N04D7","WKDFVXT8N04D8","WKDFVXT8N04D9", & + "WKDFVXT8N05D1","WKDFVXT8N05D2","WKDFVXT8N05D3","WKDFVXT8N05D4","WKDFVXT8N05D5","WKDFVXT8N05D6", & + "WKDFVXT8N05D7","WKDFVXT8N05D8","WKDFVXT8N05D9","WKDFVXT8N06D1","WKDFVXT8N06D2","WKDFVXT8N06D3", & + "WKDFVXT8N06D4","WKDFVXT8N06D5","WKDFVXT8N06D6","WKDFVXT8N06D7","WKDFVXT8N06D8","WKDFVXT8N06D9", & + "WKDFVXT8N07D1","WKDFVXT8N07D2","WKDFVXT8N07D3","WKDFVXT8N07D4","WKDFVXT8N07D5","WKDFVXT8N07D6", & + "WKDFVXT8N07D7","WKDFVXT8N07D8","WKDFVXT8N07D9","WKDFVXT8N08D1","WKDFVXT8N08D2","WKDFVXT8N08D3", & + "WKDFVXT8N08D4","WKDFVXT8N08D5","WKDFVXT8N08D6","WKDFVXT8N08D7","WKDFVXT8N08D8","WKDFVXT8N08D9", & + "WKDFVXT8N09D1","WKDFVXT8N09D2","WKDFVXT8N09D3","WKDFVXT8N09D4","WKDFVXT8N09D5","WKDFVXT8N09D6", & + "WKDFVXT8N09D7","WKDFVXT8N09D8","WKDFVXT8N09D9","WKDFVXT8N10D1","WKDFVXT8N10D2","WKDFVXT8N10D3", & + "WKDFVXT8N10D4","WKDFVXT8N10D5","WKDFVXT8N10D6","WKDFVXT8N10D7","WKDFVXT8N10D8","WKDFVXT8N10D9", & + "WKDFVXT8N11D1","WKDFVXT8N11D2","WKDFVXT8N11D3","WKDFVXT8N11D4","WKDFVXT8N11D5","WKDFVXT8N11D6", & + "WKDFVXT8N11D7","WKDFVXT8N11D8","WKDFVXT8N11D9","WKDFVXT8N12D1","WKDFVXT8N12D2","WKDFVXT8N12D3", & + "WKDFVXT8N12D4","WKDFVXT8N12D5","WKDFVXT8N12D6","WKDFVXT8N12D7","WKDFVXT8N12D8","WKDFVXT8N12D9", & + "WKDFVXT8N13D1","WKDFVXT8N13D2","WKDFVXT8N13D3","WKDFVXT8N13D4","WKDFVXT8N13D5","WKDFVXT8N13D6", & + "WKDFVXT8N13D7","WKDFVXT8N13D8","WKDFVXT8N13D9","WKDFVXT8N14D1","WKDFVXT8N14D2","WKDFVXT8N14D3", & + "WKDFVXT8N14D4","WKDFVXT8N14D5","WKDFVXT8N14D6","WKDFVXT8N14D7","WKDFVXT8N14D8","WKDFVXT8N14D9", & + "WKDFVXT8N15D1","WKDFVXT8N15D2","WKDFVXT8N15D3","WKDFVXT8N15D4","WKDFVXT8N15D5","WKDFVXT8N15D6", & + "WKDFVXT8N15D7","WKDFVXT8N15D8","WKDFVXT8N15D9","WKDFVXT8N16D1","WKDFVXT8N16D2","WKDFVXT8N16D3", & + "WKDFVXT8N16D4","WKDFVXT8N16D5","WKDFVXT8N16D6","WKDFVXT8N16D7","WKDFVXT8N16D8","WKDFVXT8N16D9", & + "WKDFVXT8N17D1","WKDFVXT8N17D2","WKDFVXT8N17D3","WKDFVXT8N17D4","WKDFVXT8N17D5","WKDFVXT8N17D6", & + "WKDFVXT8N17D7","WKDFVXT8N17D8","WKDFVXT8N17D9","WKDFVXT8N18D1","WKDFVXT8N18D2","WKDFVXT8N18D3", & + "WKDFVXT8N18D4","WKDFVXT8N18D5","WKDFVXT8N18D6","WKDFVXT8N18D7","WKDFVXT8N18D8","WKDFVXT8N18D9", & + "WKDFVXT8N19D1","WKDFVXT8N19D2","WKDFVXT8N19D3","WKDFVXT8N19D4","WKDFVXT8N19D5","WKDFVXT8N19D6", & + "WKDFVXT8N19D7","WKDFVXT8N19D8","WKDFVXT8N19D9","WKDFVXT8N20D1","WKDFVXT8N20D2","WKDFVXT8N20D3", & + "WKDFVXT8N20D4","WKDFVXT8N20D5","WKDFVXT8N20D6","WKDFVXT8N20D7","WKDFVXT8N20D8","WKDFVXT8N20D9", & + "WKDFVXT9N01D1","WKDFVXT9N01D2","WKDFVXT9N01D3","WKDFVXT9N01D4","WKDFVXT9N01D5","WKDFVXT9N01D6", & + "WKDFVXT9N01D7","WKDFVXT9N01D8","WKDFVXT9N01D9","WKDFVXT9N02D1","WKDFVXT9N02D2","WKDFVXT9N02D3", & + "WKDFVXT9N02D4","WKDFVXT9N02D5","WKDFVXT9N02D6","WKDFVXT9N02D7","WKDFVXT9N02D8","WKDFVXT9N02D9", & + "WKDFVXT9N03D1","WKDFVXT9N03D2","WKDFVXT9N03D3","WKDFVXT9N03D4","WKDFVXT9N03D5","WKDFVXT9N03D6", & + "WKDFVXT9N03D7","WKDFVXT9N03D8","WKDFVXT9N03D9","WKDFVXT9N04D1","WKDFVXT9N04D2","WKDFVXT9N04D3", & + "WKDFVXT9N04D4","WKDFVXT9N04D5","WKDFVXT9N04D6","WKDFVXT9N04D7","WKDFVXT9N04D8","WKDFVXT9N04D9", & + "WKDFVXT9N05D1","WKDFVXT9N05D2","WKDFVXT9N05D3","WKDFVXT9N05D4","WKDFVXT9N05D5","WKDFVXT9N05D6", & + "WKDFVXT9N05D7","WKDFVXT9N05D8","WKDFVXT9N05D9","WKDFVXT9N06D1","WKDFVXT9N06D2","WKDFVXT9N06D3", & + "WKDFVXT9N06D4","WKDFVXT9N06D5","WKDFVXT9N06D6","WKDFVXT9N06D7","WKDFVXT9N06D8","WKDFVXT9N06D9", & + "WKDFVXT9N07D1","WKDFVXT9N07D2","WKDFVXT9N07D3","WKDFVXT9N07D4","WKDFVXT9N07D5","WKDFVXT9N07D6", & + "WKDFVXT9N07D7","WKDFVXT9N07D8","WKDFVXT9N07D9","WKDFVXT9N08D1","WKDFVXT9N08D2","WKDFVXT9N08D3", & + "WKDFVXT9N08D4","WKDFVXT9N08D5","WKDFVXT9N08D6","WKDFVXT9N08D7","WKDFVXT9N08D8","WKDFVXT9N08D9", & + "WKDFVXT9N09D1","WKDFVXT9N09D2","WKDFVXT9N09D3","WKDFVXT9N09D4","WKDFVXT9N09D5","WKDFVXT9N09D6", & + "WKDFVXT9N09D7","WKDFVXT9N09D8","WKDFVXT9N09D9","WKDFVXT9N10D1","WKDFVXT9N10D2","WKDFVXT9N10D3", & + "WKDFVXT9N10D4","WKDFVXT9N10D5","WKDFVXT9N10D6","WKDFVXT9N10D7","WKDFVXT9N10D8","WKDFVXT9N10D9", & + "WKDFVXT9N11D1","WKDFVXT9N11D2","WKDFVXT9N11D3","WKDFVXT9N11D4","WKDFVXT9N11D5","WKDFVXT9N11D6", & + "WKDFVXT9N11D7","WKDFVXT9N11D8","WKDFVXT9N11D9","WKDFVXT9N12D1","WKDFVXT9N12D2","WKDFVXT9N12D3", & + "WKDFVXT9N12D4","WKDFVXT9N12D5","WKDFVXT9N12D6","WKDFVXT9N12D7","WKDFVXT9N12D8","WKDFVXT9N12D9", & + "WKDFVXT9N13D1","WKDFVXT9N13D2","WKDFVXT9N13D3","WKDFVXT9N13D4","WKDFVXT9N13D5","WKDFVXT9N13D6", & + "WKDFVXT9N13D7","WKDFVXT9N13D8","WKDFVXT9N13D9","WKDFVXT9N14D1","WKDFVXT9N14D2","WKDFVXT9N14D3", & + "WKDFVXT9N14D4","WKDFVXT9N14D5","WKDFVXT9N14D6","WKDFVXT9N14D7","WKDFVXT9N14D8","WKDFVXT9N14D9", & + "WKDFVXT9N15D1","WKDFVXT9N15D2","WKDFVXT9N15D3","WKDFVXT9N15D4","WKDFVXT9N15D5","WKDFVXT9N15D6", & + "WKDFVXT9N15D7","WKDFVXT9N15D8","WKDFVXT9N15D9","WKDFVXT9N16D1","WKDFVXT9N16D2","WKDFVXT9N16D3", & + "WKDFVXT9N16D4","WKDFVXT9N16D5","WKDFVXT9N16D6","WKDFVXT9N16D7","WKDFVXT9N16D8","WKDFVXT9N16D9", & + "WKDFVXT9N17D1","WKDFVXT9N17D2","WKDFVXT9N17D3","WKDFVXT9N17D4","WKDFVXT9N17D5","WKDFVXT9N17D6", & + "WKDFVXT9N17D7","WKDFVXT9N17D8","WKDFVXT9N17D9","WKDFVXT9N18D1","WKDFVXT9N18D2","WKDFVXT9N18D3", & + "WKDFVXT9N18D4","WKDFVXT9N18D5","WKDFVXT9N18D6","WKDFVXT9N18D7","WKDFVXT9N18D8","WKDFVXT9N18D9", & + "WKDFVXT9N19D1","WKDFVXT9N19D2","WKDFVXT9N19D3","WKDFVXT9N19D4","WKDFVXT9N19D5","WKDFVXT9N19D6", & + "WKDFVXT9N19D7","WKDFVXT9N19D8","WKDFVXT9N19D9","WKDFVXT9N20D1","WKDFVXT9N20D2","WKDFVXT9N20D3", & + "WKDFVXT9N20D4","WKDFVXT9N20D5","WKDFVXT9N20D6","WKDFVXT9N20D7","WKDFVXT9N20D8","WKDFVXT9N20D9", & + "WKDIAMT1D1 ","WKDIAMT1D2 ","WKDIAMT1D3 ","WKDIAMT1D4 ","WKDIAMT1D5 ","WKDIAMT1D6 ", & + "WKDIAMT1D7 ","WKDIAMT1D8 ","WKDIAMT1D9 ","WKDIAMT2D1 ","WKDIAMT2D2 ","WKDIAMT2D3 ", & + "WKDIAMT2D4 ","WKDIAMT2D5 ","WKDIAMT2D6 ","WKDIAMT2D7 ","WKDIAMT2D8 ","WKDIAMT2D9 ", & + "WKDIAMT3D1 ","WKDIAMT3D2 ","WKDIAMT3D3 ","WKDIAMT3D4 ","WKDIAMT3D5 ","WKDIAMT3D6 ", & + "WKDIAMT3D7 ","WKDIAMT3D8 ","WKDIAMT3D9 ","WKDIAMT4D1 ","WKDIAMT4D2 ","WKDIAMT4D3 ", & + "WKDIAMT4D4 ","WKDIAMT4D5 ","WKDIAMT4D6 ","WKDIAMT4D7 ","WKDIAMT4D8 ","WKDIAMT4D9 ", & + "WKDIAMT5D1 ","WKDIAMT5D2 ","WKDIAMT5D3 ","WKDIAMT5D4 ","WKDIAMT5D5 ","WKDIAMT5D6 ", & + "WKDIAMT5D7 ","WKDIAMT5D8 ","WKDIAMT5D9 ","WKDIAMT6D1 ","WKDIAMT6D2 ","WKDIAMT6D3 ", & + "WKDIAMT6D4 ","WKDIAMT6D5 ","WKDIAMT6D6 ","WKDIAMT6D7 ","WKDIAMT6D8 ","WKDIAMT6D9 ", & + "WKDIAMT7D1 ","WKDIAMT7D2 ","WKDIAMT7D3 ","WKDIAMT7D4 ","WKDIAMT7D5 ","WKDIAMT7D6 ", & + "WKDIAMT7D7 ","WKDIAMT7D8 ","WKDIAMT7D9 ","WKDIAMT8D1 ","WKDIAMT8D2 ","WKDIAMT8D3 ", & + "WKDIAMT8D4 ","WKDIAMT8D5 ","WKDIAMT8D6 ","WKDIAMT8D7 ","WKDIAMT8D8 ","WKDIAMT8D9 ", & + "WKDIAMT9D1 ","WKDIAMT9D2 ","WKDIAMT9D3 ","WKDIAMT9D4 ","WKDIAMT9D5 ","WKDIAMT9D6 ", & + "WKDIAMT9D7 ","WKDIAMT9D8 ","WKDIAMT9D9 ","WKPOSXT1D1 ","WKPOSXT1D2 ","WKPOSXT1D3 ", & + "WKPOSXT1D4 ","WKPOSXT1D5 ","WKPOSXT1D6 ","WKPOSXT1D7 ","WKPOSXT1D8 ","WKPOSXT1D9 ", & + "WKPOSXT2D1 ","WKPOSXT2D2 ","WKPOSXT2D3 ","WKPOSXT2D4 ","WKPOSXT2D5 ","WKPOSXT2D6 ", & + "WKPOSXT2D7 ","WKPOSXT2D8 ","WKPOSXT2D9 ","WKPOSXT3D1 ","WKPOSXT3D2 ","WKPOSXT3D3 ", & + "WKPOSXT3D4 ","WKPOSXT3D5 ","WKPOSXT3D6 ","WKPOSXT3D7 ","WKPOSXT3D8 ","WKPOSXT3D9 ", & + "WKPOSXT4D1 ","WKPOSXT4D2 ","WKPOSXT4D3 ","WKPOSXT4D4 ","WKPOSXT4D5 ","WKPOSXT4D6 ", & + "WKPOSXT4D7 ","WKPOSXT4D8 ","WKPOSXT4D9 ","WKPOSXT5D1 ","WKPOSXT5D2 ","WKPOSXT5D3 ", & + "WKPOSXT5D4 ","WKPOSXT5D5 ","WKPOSXT5D6 ","WKPOSXT5D7 ","WKPOSXT5D8 ","WKPOSXT5D9 ", & + "WKPOSXT6D1 ","WKPOSXT6D2 ","WKPOSXT6D3 ","WKPOSXT6D4 ","WKPOSXT6D5 ","WKPOSXT6D6 ", & + "WKPOSXT6D7 ","WKPOSXT6D8 ","WKPOSXT6D9 ","WKPOSXT7D1 ","WKPOSXT7D2 ","WKPOSXT7D3 ", & + "WKPOSXT7D4 ","WKPOSXT7D5 ","WKPOSXT7D6 ","WKPOSXT7D7 ","WKPOSXT7D8 ","WKPOSXT7D9 ", & + "WKPOSXT8D1 ","WKPOSXT8D2 ","WKPOSXT8D3 ","WKPOSXT8D4 ","WKPOSXT8D5 ","WKPOSXT8D6 ", & + "WKPOSXT8D7 ","WKPOSXT8D8 ","WKPOSXT8D9 ","WKPOSXT9D1 ","WKPOSXT9D2 ","WKPOSXT9D3 ", & + "WKPOSXT9D4 ","WKPOSXT9D5 ","WKPOSXT9D6 ","WKPOSXT9D7 ","WKPOSXT9D8 ","WKPOSXT9D9 ", & + "WKPOSYT1D1 ","WKPOSYT1D2 ","WKPOSYT1D3 ","WKPOSYT1D4 ","WKPOSYT1D5 ","WKPOSYT1D6 ", & + "WKPOSYT1D7 ","WKPOSYT1D8 ","WKPOSYT1D9 ","WKPOSYT2D1 ","WKPOSYT2D2 ","WKPOSYT2D3 ", & + "WKPOSYT2D4 ","WKPOSYT2D5 ","WKPOSYT2D6 ","WKPOSYT2D7 ","WKPOSYT2D8 ","WKPOSYT2D9 ", & + "WKPOSYT3D1 ","WKPOSYT3D2 ","WKPOSYT3D3 ","WKPOSYT3D4 ","WKPOSYT3D5 ","WKPOSYT3D6 ", & + "WKPOSYT3D7 ","WKPOSYT3D8 ","WKPOSYT3D9 ","WKPOSYT4D1 ","WKPOSYT4D2 ","WKPOSYT4D3 ", & + "WKPOSYT4D4 ","WKPOSYT4D5 ","WKPOSYT4D6 ","WKPOSYT4D7 ","WKPOSYT4D8 ","WKPOSYT4D9 ", & + "WKPOSYT5D1 ","WKPOSYT5D2 ","WKPOSYT5D3 ","WKPOSYT5D4 ","WKPOSYT5D5 ","WKPOSYT5D6 ", & + "WKPOSYT5D7 ","WKPOSYT5D8 ","WKPOSYT5D9 ","WKPOSYT6D1 ","WKPOSYT6D2 ","WKPOSYT6D3 ", & + "WKPOSYT6D4 ","WKPOSYT6D5 ","WKPOSYT6D6 ","WKPOSYT6D7 ","WKPOSYT6D8 ","WKPOSYT6D9 ", & + "WKPOSYT7D1 ","WKPOSYT7D2 ","WKPOSYT7D3 ","WKPOSYT7D4 ","WKPOSYT7D5 ","WKPOSYT7D6 ", & + "WKPOSYT7D7 ","WKPOSYT7D8 ","WKPOSYT7D9 ","WKPOSYT8D1 ","WKPOSYT8D2 ","WKPOSYT8D3 ", & + "WKPOSYT8D4 ","WKPOSYT8D5 ","WKPOSYT8D6 ","WKPOSYT8D7 ","WKPOSYT8D8 ","WKPOSYT8D9 ", & + "WKPOSYT9D1 ","WKPOSYT9D2 ","WKPOSYT9D3 ","WKPOSYT9D4 ","WKPOSYT9D5 ","WKPOSYT9D6 ", & + "WKPOSYT9D7 ","WKPOSYT9D8 ","WKPOSYT9D9 ","WKPOSZT1D1 ","WKPOSZT1D2 ","WKPOSZT1D3 ", & + "WKPOSZT1D4 ","WKPOSZT1D5 ","WKPOSZT1D6 ","WKPOSZT1D7 ","WKPOSZT1D8 ","WKPOSZT1D9 ", & + "WKPOSZT2D1 ","WKPOSZT2D2 ","WKPOSZT2D3 ","WKPOSZT2D4 ","WKPOSZT2D5 ","WKPOSZT2D6 ", & + "WKPOSZT2D7 ","WKPOSZT2D8 ","WKPOSZT2D9 ","WKPOSZT3D1 ","WKPOSZT3D2 ","WKPOSZT3D3 ", & + "WKPOSZT3D4 ","WKPOSZT3D5 ","WKPOSZT3D6 ","WKPOSZT3D7 ","WKPOSZT3D8 ","WKPOSZT3D9 ", & + "WKPOSZT4D1 ","WKPOSZT4D2 ","WKPOSZT4D3 ","WKPOSZT4D4 ","WKPOSZT4D5 ","WKPOSZT4D6 ", & + "WKPOSZT4D7 ","WKPOSZT4D8 ","WKPOSZT4D9 ","WKPOSZT5D1 ","WKPOSZT5D2 ","WKPOSZT5D3 ", & + "WKPOSZT5D4 ","WKPOSZT5D5 ","WKPOSZT5D6 ","WKPOSZT5D7 ","WKPOSZT5D8 ","WKPOSZT5D9 ", & + "WKPOSZT6D1 ","WKPOSZT6D2 ","WKPOSZT6D3 ","WKPOSZT6D4 ","WKPOSZT6D5 ","WKPOSZT6D6 ", & + "WKPOSZT6D7 ","WKPOSZT6D8 ","WKPOSZT6D9 ","WKPOSZT7D1 ","WKPOSZT7D2 ","WKPOSZT7D3 ", & + "WKPOSZT7D4 ","WKPOSZT7D5 ","WKPOSZT7D6 ","WKPOSZT7D7 ","WKPOSZT7D8 ","WKPOSZT7D9 ", & + "WKPOSZT8D1 ","WKPOSZT8D2 ","WKPOSZT8D3 ","WKPOSZT8D4 ","WKPOSZT8D5 ","WKPOSZT8D6 ", & + "WKPOSZT8D7 ","WKPOSZT8D8 ","WKPOSZT8D9 ","WKPOSZT9D1 ","WKPOSZT9D2 ","WKPOSZT9D3 ", & + "WKPOSZT9D4 ","WKPOSZT9D5 ","WKPOSZT9D6 ","WKPOSZT9D7 ","WKPOSZT9D8 ","WKPOSZT9D9 ", & + "WKVELXT1D1 ","WKVELXT1D2 ","WKVELXT1D3 ","WKVELXT1D4 ","WKVELXT1D5 ","WKVELXT1D6 ", & + "WKVELXT1D7 ","WKVELXT1D8 ","WKVELXT1D9 ","WKVELXT2D1 ","WKVELXT2D2 ","WKVELXT2D3 ", & + "WKVELXT2D4 ","WKVELXT2D5 ","WKVELXT2D6 ","WKVELXT2D7 ","WKVELXT2D8 ","WKVELXT2D9 ", & + "WKVELXT3D1 ","WKVELXT3D2 ","WKVELXT3D3 ","WKVELXT3D4 ","WKVELXT3D5 ","WKVELXT3D6 ", & + "WKVELXT3D7 ","WKVELXT3D8 ","WKVELXT3D9 ","WKVELXT4D1 ","WKVELXT4D2 ","WKVELXT4D3 ", & + "WKVELXT4D4 ","WKVELXT4D5 ","WKVELXT4D6 ","WKVELXT4D7 ","WKVELXT4D8 ","WKVELXT4D9 ", & + "WKVELXT5D1 ","WKVELXT5D2 ","WKVELXT5D3 ","WKVELXT5D4 ","WKVELXT5D5 ","WKVELXT5D6 ", & + "WKVELXT5D7 ","WKVELXT5D8 ","WKVELXT5D9 ","WKVELXT6D1 ","WKVELXT6D2 ","WKVELXT6D3 ", & + "WKVELXT6D4 ","WKVELXT6D5 ","WKVELXT6D6 ","WKVELXT6D7 ","WKVELXT6D8 ","WKVELXT6D9 ", & + "WKVELXT7D1 ","WKVELXT7D2 ","WKVELXT7D3 ","WKVELXT7D4 ","WKVELXT7D5 ","WKVELXT7D6 ", & + "WKVELXT7D7 ","WKVELXT7D8 ","WKVELXT7D9 ","WKVELXT8D1 ","WKVELXT8D2 ","WKVELXT8D3 ", & + "WKVELXT8D4 ","WKVELXT8D5 ","WKVELXT8D6 ","WKVELXT8D7 ","WKVELXT8D8 ","WKVELXT8D9 ", & + "WKVELXT9D1 ","WKVELXT9D2 ","WKVELXT9D3 ","WKVELXT9D4 ","WKVELXT9D5 ","WKVELXT9D6 ", & + "WKVELXT9D7 ","WKVELXT9D8 ","WKVELXT9D9 ","WKVELYT1D1 ","WKVELYT1D2 ","WKVELYT1D3 ", & + "WKVELYT1D4 ","WKVELYT1D5 ","WKVELYT1D6 ","WKVELYT1D7 ","WKVELYT1D8 ","WKVELYT1D9 ", & + "WKVELYT2D1 ","WKVELYT2D2 ","WKVELYT2D3 ","WKVELYT2D4 ","WKVELYT2D5 ","WKVELYT2D6 ", & + "WKVELYT2D7 ","WKVELYT2D8 ","WKVELYT2D9 ","WKVELYT3D1 ","WKVELYT3D2 ","WKVELYT3D3 ", & + "WKVELYT3D4 ","WKVELYT3D5 ","WKVELYT3D6 ","WKVELYT3D7 ","WKVELYT3D8 ","WKVELYT3D9 ", & + "WKVELYT4D1 ","WKVELYT4D2 ","WKVELYT4D3 ","WKVELYT4D4 ","WKVELYT4D5 ","WKVELYT4D6 ", & + "WKVELYT4D7 ","WKVELYT4D8 ","WKVELYT4D9 ","WKVELYT5D1 ","WKVELYT5D2 ","WKVELYT5D3 ", & + "WKVELYT5D4 ","WKVELYT5D5 ","WKVELYT5D6 ","WKVELYT5D7 ","WKVELYT5D8 ","WKVELYT5D9 ", & + "WKVELYT6D1 ","WKVELYT6D2 ","WKVELYT6D3 ","WKVELYT6D4 ","WKVELYT6D5 ","WKVELYT6D6 ", & + "WKVELYT6D7 ","WKVELYT6D8 ","WKVELYT6D9 ","WKVELYT7D1 ","WKVELYT7D2 ","WKVELYT7D3 ", & + "WKVELYT7D4 ","WKVELYT7D5 ","WKVELYT7D6 ","WKVELYT7D7 ","WKVELYT7D8 ","WKVELYT7D9 ", & + "WKVELYT8D1 ","WKVELYT8D2 ","WKVELYT8D3 ","WKVELYT8D4 ","WKVELYT8D5 ","WKVELYT8D6 ", & + "WKVELYT8D7 ","WKVELYT8D8 ","WKVELYT8D9 ","WKVELYT9D1 ","WKVELYT9D2 ","WKVELYT9D3 ", & + "WKVELYT9D4 ","WKVELYT9D5 ","WKVELYT9D6 ","WKVELYT9D7 ","WKVELYT9D8 ","WKVELYT9D9 ", & + "WKVELZT1D1 ","WKVELZT1D2 ","WKVELZT1D3 ","WKVELZT1D4 ","WKVELZT1D5 ","WKVELZT1D6 ", & + "WKVELZT1D7 ","WKVELZT1D8 ","WKVELZT1D9 ","WKVELZT2D1 ","WKVELZT2D2 ","WKVELZT2D3 ", & + "WKVELZT2D4 ","WKVELZT2D5 ","WKVELZT2D6 ","WKVELZT2D7 ","WKVELZT2D8 ","WKVELZT2D9 ", & + "WKVELZT3D1 ","WKVELZT3D2 ","WKVELZT3D3 ","WKVELZT3D4 ","WKVELZT3D5 ","WKVELZT3D6 ", & + "WKVELZT3D7 ","WKVELZT3D8 ","WKVELZT3D9 ","WKVELZT4D1 ","WKVELZT4D2 ","WKVELZT4D3 ", & + "WKVELZT4D4 ","WKVELZT4D5 ","WKVELZT4D6 ","WKVELZT4D7 ","WKVELZT4D8 ","WKVELZT4D9 ", & + "WKVELZT5D1 ","WKVELZT5D2 ","WKVELZT5D3 ","WKVELZT5D4 ","WKVELZT5D5 ","WKVELZT5D6 ", & + "WKVELZT5D7 ","WKVELZT5D8 ","WKVELZT5D9 ","WKVELZT6D1 ","WKVELZT6D2 ","WKVELZT6D3 ", & + "WKVELZT6D4 ","WKVELZT6D5 ","WKVELZT6D6 ","WKVELZT6D7 ","WKVELZT6D8 ","WKVELZT6D9 ", & + "WKVELZT7D1 ","WKVELZT7D2 ","WKVELZT7D3 ","WKVELZT7D4 ","WKVELZT7D5 ","WKVELZT7D6 ", & + "WKVELZT7D7 ","WKVELZT7D8 ","WKVELZT7D9 ","WKVELZT8D1 ","WKVELZT8D2 ","WKVELZT8D3 ", & + "WKVELZT8D4 ","WKVELZT8D5 ","WKVELZT8D6 ","WKVELZT8D7 ","WKVELZT8D8 ","WKVELZT8D9 ", & + "WKVELZT9D1 ","WKVELZT9D2 ","WKVELZT9D3 ","WKVELZT9D4 ","WKVELZT9D5 ","WKVELZT9D6 ", & + "WKVELZT9D7 ","WKVELZT9D8 ","WKVELZT9D9 ","YAWERRT1 ","YAWERRT2 ","YAWERRT3 ", & + "YAWERRT4 ","YAWERRT5 ","YAWERRT6 ","YAWERRT7 ","YAWERRT8 ","YAWERRT9 "/) + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(9486) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + ValidParamAry1, ValidParamAry2, ValidParamAry3, ValidParamAry4, ValidParamAry5, ValidParamAry6, ValidParamAry7/) + + INTEGER(IntKi), PARAMETER :: ParamIndxAry1(1356) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + AziSkewFiltT1 , AziSkewFiltT2 , AziSkewFiltT3 , AziSkewFiltT4 , AziSkewFiltT5 , AziSkewFiltT6 , & + AziSkewFiltT7 , AziSkewFiltT8 , AziSkewFiltT9 , AziSkewT1 , AziSkewT2 , AziSkewT3 , & + AziSkewT4 , AziSkewT5 , AziSkewT6 , AziSkewT7 , AziSkewT8 , AziSkewT9 , & + CtT1N01 , CtT1N02 , CtT1N03 , CtT1N04 , CtT1N05 , CtT1N06 , & + CtT1N07 , CtT1N08 , CtT1N09 , CtT1N10 , CtT1N11 , CtT1N12 , & + CtT1N13 , CtT1N14 , CtT1N15 , CtT1N16 , CtT1N17 , CtT1N18 , & + CtT1N19 , CtT1N20 , CtT2N01 , CtT2N02 , CtT2N03 , CtT2N04 , & + CtT2N05 , CtT2N06 , CtT2N07 , CtT2N08 , CtT2N09 , CtT2N10 , & + CtT2N11 , CtT2N12 , CtT2N13 , CtT2N14 , CtT2N15 , CtT2N16 , & + CtT2N17 , CtT2N18 , CtT2N19 , CtT2N20 , CtT3N01 , CtT3N02 , & + CtT3N03 , CtT3N04 , CtT3N05 , CtT3N06 , CtT3N07 , CtT3N08 , & + CtT3N09 , CtT3N10 , CtT3N11 , CtT3N12 , CtT3N13 , CtT3N14 , & + CtT3N15 , CtT3N16 , CtT3N17 , CtT3N18 , CtT3N19 , CtT3N20 , & + CtT4N01 , CtT4N02 , CtT4N03 , CtT4N04 , CtT4N05 , CtT4N06 , & + CtT4N07 , CtT4N08 , CtT4N09 , CtT4N10 , CtT4N11 , CtT4N12 , & + CtT4N13 , CtT4N14 , CtT4N15 , CtT4N16 , CtT4N17 , CtT4N18 , & + CtT4N19 , CtT4N20 , CtT5N01 , CtT5N02 , CtT5N03 , CtT5N04 , & + CtT5N05 , CtT5N06 , CtT5N07 , CtT5N08 , CtT5N09 , CtT5N10 , & + CtT5N11 , CtT5N12 , CtT5N13 , CtT5N14 , CtT5N15 , CtT5N16 , & + CtT5N17 , CtT5N18 , CtT5N19 , CtT5N20 , CtT6N01 , CtT6N02 , & + CtT6N03 , CtT6N04 , CtT6N05 , CtT6N06 , CtT6N07 , CtT6N08 , & + CtT6N09 , CtT6N10 , CtT6N11 , CtT6N12 , CtT6N13 , CtT6N14 , & + CtT6N15 , CtT6N16 , CtT6N17 , CtT6N18 , CtT6N19 , CtT6N20 , & + CtT7N01 , CtT7N02 , CtT7N03 , CtT7N04 , CtT7N05 , CtT7N06 , & + CtT7N07 , CtT7N08 , CtT7N09 , CtT7N10 , CtT7N11 , CtT7N12 , & + CtT7N13 , CtT7N14 , CtT7N15 , CtT7N16 , CtT7N17 , CtT7N18 , & + CtT7N19 , CtT7N20 , CtT8N01 , CtT8N02 , CtT8N03 , CtT8N04 , & + CtT8N05 , CtT8N06 , CtT8N07 , CtT8N08 , CtT8N09 , CtT8N10 , & + CtT8N11 , CtT8N12 , CtT8N13 , CtT8N14 , CtT8N15 , CtT8N16 , & + CtT8N17 , CtT8N18 , CtT8N19 , CtT8N20 , CtT9N01 , CtT9N02 , & + CtT9N03 , CtT9N04 , CtT9N05 , CtT9N06 , CtT9N07 , CtT9N08 , & + CtT9N09 , CtT9N10 , CtT9N11 , CtT9N12 , CtT9N13 , CtT9N14 , & + CtT9N15 , CtT9N16 , CtT9N17 , CtT9N18 , CtT9N19 , CtT9N20 , & + EddAmbT1N01D1 , EddAmbT1N01D2 , EddAmbT1N01D3 , EddAmbT1N01D4 , EddAmbT1N01D5 , EddAmbT1N01D6 , & + EddAmbT1N01D7 , EddAmbT1N01D8 , EddAmbT1N01D9 , EddAmbT1N02D1 , EddAmbT1N02D2 , EddAmbT1N02D3 , & + EddAmbT1N02D4 , EddAmbT1N02D5 , EddAmbT1N02D6 , EddAmbT1N02D7 , EddAmbT1N02D8 , EddAmbT1N02D9 , & + EddAmbT1N03D1 , EddAmbT1N03D2 , EddAmbT1N03D3 , EddAmbT1N03D4 , EddAmbT1N03D5 , EddAmbT1N03D6 , & + EddAmbT1N03D7 , EddAmbT1N03D8 , EddAmbT1N03D9 , EddAmbT1N04D1 , EddAmbT1N04D2 , EddAmbT1N04D3 , & + EddAmbT1N04D4 , EddAmbT1N04D5 , EddAmbT1N04D6 , EddAmbT1N04D7 , EddAmbT1N04D8 , EddAmbT1N04D9 , & + EddAmbT1N05D1 , EddAmbT1N05D2 , EddAmbT1N05D3 , EddAmbT1N05D4 , EddAmbT1N05D5 , EddAmbT1N05D6 , & + EddAmbT1N05D7 , EddAmbT1N05D8 , EddAmbT1N05D9 , EddAmbT1N06D1 , EddAmbT1N06D2 , EddAmbT1N06D3 , & + EddAmbT1N06D4 , EddAmbT1N06D5 , EddAmbT1N06D6 , EddAmbT1N06D7 , EddAmbT1N06D8 , EddAmbT1N06D9 , & + EddAmbT1N07D1 , EddAmbT1N07D2 , EddAmbT1N07D3 , EddAmbT1N07D4 , EddAmbT1N07D5 , EddAmbT1N07D6 , & + EddAmbT1N07D7 , EddAmbT1N07D8 , EddAmbT1N07D9 , EddAmbT1N08D1 , EddAmbT1N08D2 , EddAmbT1N08D3 , & + EddAmbT1N08D4 , EddAmbT1N08D5 , EddAmbT1N08D6 , EddAmbT1N08D7 , EddAmbT1N08D8 , EddAmbT1N08D9 , & + EddAmbT1N09D1 , EddAmbT1N09D2 , EddAmbT1N09D3 , EddAmbT1N09D4 , EddAmbT1N09D5 , EddAmbT1N09D6 , & + EddAmbT1N09D7 , EddAmbT1N09D8 , EddAmbT1N09D9 , EddAmbT1N10D1 , EddAmbT1N10D2 , EddAmbT1N10D3 , & + EddAmbT1N10D4 , EddAmbT1N10D5 , EddAmbT1N10D6 , EddAmbT1N10D7 , EddAmbT1N10D8 , EddAmbT1N10D9 , & + EddAmbT1N11D1 , EddAmbT1N11D2 , EddAmbT1N11D3 , EddAmbT1N11D4 , EddAmbT1N11D5 , EddAmbT1N11D6 , & + EddAmbT1N11D7 , EddAmbT1N11D8 , EddAmbT1N11D9 , EddAmbT1N12D1 , EddAmbT1N12D2 , EddAmbT1N12D3 , & + EddAmbT1N12D4 , EddAmbT1N12D5 , EddAmbT1N12D6 , EddAmbT1N12D7 , EddAmbT1N12D8 , EddAmbT1N12D9 , & + EddAmbT1N13D1 , EddAmbT1N13D2 , EddAmbT1N13D3 , EddAmbT1N13D4 , EddAmbT1N13D5 , EddAmbT1N13D6 , & + EddAmbT1N13D7 , EddAmbT1N13D8 , EddAmbT1N13D9 , EddAmbT1N14D1 , EddAmbT1N14D2 , EddAmbT1N14D3 , & + EddAmbT1N14D4 , EddAmbT1N14D5 , EddAmbT1N14D6 , EddAmbT1N14D7 , EddAmbT1N14D8 , EddAmbT1N14D9 , & + EddAmbT1N15D1 , EddAmbT1N15D2 , EddAmbT1N15D3 , EddAmbT1N15D4 , EddAmbT1N15D5 , EddAmbT1N15D6 , & + EddAmbT1N15D7 , EddAmbT1N15D8 , EddAmbT1N15D9 , EddAmbT1N16D1 , EddAmbT1N16D2 , EddAmbT1N16D3 , & + EddAmbT1N16D4 , EddAmbT1N16D5 , EddAmbT1N16D6 , EddAmbT1N16D7 , EddAmbT1N16D8 , EddAmbT1N16D9 , & + EddAmbT1N17D1 , EddAmbT1N17D2 , EddAmbT1N17D3 , EddAmbT1N17D4 , EddAmbT1N17D5 , EddAmbT1N17D6 , & + EddAmbT1N17D7 , EddAmbT1N17D8 , EddAmbT1N17D9 , EddAmbT1N18D1 , EddAmbT1N18D2 , EddAmbT1N18D3 , & + EddAmbT1N18D4 , EddAmbT1N18D5 , EddAmbT1N18D6 , EddAmbT1N18D7 , EddAmbT1N18D8 , EddAmbT1N18D9 , & + EddAmbT1N19D1 , EddAmbT1N19D2 , EddAmbT1N19D3 , EddAmbT1N19D4 , EddAmbT1N19D5 , EddAmbT1N19D6 , & + EddAmbT1N19D7 , EddAmbT1N19D8 , EddAmbT1N19D9 , EddAmbT1N20D1 , EddAmbT1N20D2 , EddAmbT1N20D3 , & + EddAmbT1N20D4 , EddAmbT1N20D5 , EddAmbT1N20D6 , EddAmbT1N20D7 , EddAmbT1N20D8 , EddAmbT1N20D9 , & + EddAmbT2N01D1 , EddAmbT2N01D2 , EddAmbT2N01D3 , EddAmbT2N01D4 , EddAmbT2N01D5 , EddAmbT2N01D6 , & + EddAmbT2N01D7 , EddAmbT2N01D8 , EddAmbT2N01D9 , EddAmbT2N02D1 , EddAmbT2N02D2 , EddAmbT2N02D3 , & + EddAmbT2N02D4 , EddAmbT2N02D5 , EddAmbT2N02D6 , EddAmbT2N02D7 , EddAmbT2N02D8 , EddAmbT2N02D9 , & + EddAmbT2N03D1 , EddAmbT2N03D2 , EddAmbT2N03D3 , EddAmbT2N03D4 , EddAmbT2N03D5 , EddAmbT2N03D6 , & + EddAmbT2N03D7 , EddAmbT2N03D8 , EddAmbT2N03D9 , EddAmbT2N04D1 , EddAmbT2N04D2 , EddAmbT2N04D3 , & + EddAmbT2N04D4 , EddAmbT2N04D5 , EddAmbT2N04D6 , EddAmbT2N04D7 , EddAmbT2N04D8 , EddAmbT2N04D9 , & + EddAmbT2N05D1 , EddAmbT2N05D2 , EddAmbT2N05D3 , EddAmbT2N05D4 , EddAmbT2N05D5 , EddAmbT2N05D6 , & + EddAmbT2N05D7 , EddAmbT2N05D8 , EddAmbT2N05D9 , EddAmbT2N06D1 , EddAmbT2N06D2 , EddAmbT2N06D3 , & + EddAmbT2N06D4 , EddAmbT2N06D5 , EddAmbT2N06D6 , EddAmbT2N06D7 , EddAmbT2N06D8 , EddAmbT2N06D9 , & + EddAmbT2N07D1 , EddAmbT2N07D2 , EddAmbT2N07D3 , EddAmbT2N07D4 , EddAmbT2N07D5 , EddAmbT2N07D6 , & + EddAmbT2N07D7 , EddAmbT2N07D8 , EddAmbT2N07D9 , EddAmbT2N08D1 , EddAmbT2N08D2 , EddAmbT2N08D3 , & + EddAmbT2N08D4 , EddAmbT2N08D5 , EddAmbT2N08D6 , EddAmbT2N08D7 , EddAmbT2N08D8 , EddAmbT2N08D9 , & + EddAmbT2N09D1 , EddAmbT2N09D2 , EddAmbT2N09D3 , EddAmbT2N09D4 , EddAmbT2N09D5 , EddAmbT2N09D6 , & + EddAmbT2N09D7 , EddAmbT2N09D8 , EddAmbT2N09D9 , EddAmbT2N10D1 , EddAmbT2N10D2 , EddAmbT2N10D3 , & + EddAmbT2N10D4 , EddAmbT2N10D5 , EddAmbT2N10D6 , EddAmbT2N10D7 , EddAmbT2N10D8 , EddAmbT2N10D9 , & + EddAmbT2N11D1 , EddAmbT2N11D2 , EddAmbT2N11D3 , EddAmbT2N11D4 , EddAmbT2N11D5 , EddAmbT2N11D6 , & + EddAmbT2N11D7 , EddAmbT2N11D8 , EddAmbT2N11D9 , EddAmbT2N12D1 , EddAmbT2N12D2 , EddAmbT2N12D3 , & + EddAmbT2N12D4 , EddAmbT2N12D5 , EddAmbT2N12D6 , EddAmbT2N12D7 , EddAmbT2N12D8 , EddAmbT2N12D9 , & + EddAmbT2N13D1 , EddAmbT2N13D2 , EddAmbT2N13D3 , EddAmbT2N13D4 , EddAmbT2N13D5 , EddAmbT2N13D6 , & + EddAmbT2N13D7 , EddAmbT2N13D8 , EddAmbT2N13D9 , EddAmbT2N14D1 , EddAmbT2N14D2 , EddAmbT2N14D3 , & + EddAmbT2N14D4 , EddAmbT2N14D5 , EddAmbT2N14D6 , EddAmbT2N14D7 , EddAmbT2N14D8 , EddAmbT2N14D9 , & + EddAmbT2N15D1 , EddAmbT2N15D2 , EddAmbT2N15D3 , EddAmbT2N15D4 , EddAmbT2N15D5 , EddAmbT2N15D6 , & + EddAmbT2N15D7 , EddAmbT2N15D8 , EddAmbT2N15D9 , EddAmbT2N16D1 , EddAmbT2N16D2 , EddAmbT2N16D3 , & + EddAmbT2N16D4 , EddAmbT2N16D5 , EddAmbT2N16D6 , EddAmbT2N16D7 , EddAmbT2N16D8 , EddAmbT2N16D9 , & + EddAmbT2N17D1 , EddAmbT2N17D2 , EddAmbT2N17D3 , EddAmbT2N17D4 , EddAmbT2N17D5 , EddAmbT2N17D6 , & + EddAmbT2N17D7 , EddAmbT2N17D8 , EddAmbT2N17D9 , EddAmbT2N18D1 , EddAmbT2N18D2 , EddAmbT2N18D3 , & + EddAmbT2N18D4 , EddAmbT2N18D5 , EddAmbT2N18D6 , EddAmbT2N18D7 , EddAmbT2N18D8 , EddAmbT2N18D9 , & + EddAmbT2N19D1 , EddAmbT2N19D2 , EddAmbT2N19D3 , EddAmbT2N19D4 , EddAmbT2N19D5 , EddAmbT2N19D6 , & + EddAmbT2N19D7 , EddAmbT2N19D8 , EddAmbT2N19D9 , EddAmbT2N20D1 , EddAmbT2N20D2 , EddAmbT2N20D3 , & + EddAmbT2N20D4 , EddAmbT2N20D5 , EddAmbT2N20D6 , EddAmbT2N20D7 , EddAmbT2N20D8 , EddAmbT2N20D9 , & + EddAmbT3N01D1 , EddAmbT3N01D2 , EddAmbT3N01D3 , EddAmbT3N01D4 , EddAmbT3N01D5 , EddAmbT3N01D6 , & + EddAmbT3N01D7 , EddAmbT3N01D8 , EddAmbT3N01D9 , EddAmbT3N02D1 , EddAmbT3N02D2 , EddAmbT3N02D3 , & + EddAmbT3N02D4 , EddAmbT3N02D5 , EddAmbT3N02D6 , EddAmbT3N02D7 , EddAmbT3N02D8 , EddAmbT3N02D9 , & + EddAmbT3N03D1 , EddAmbT3N03D2 , EddAmbT3N03D3 , EddAmbT3N03D4 , EddAmbT3N03D5 , EddAmbT3N03D6 , & + EddAmbT3N03D7 , EddAmbT3N03D8 , EddAmbT3N03D9 , EddAmbT3N04D1 , EddAmbT3N04D2 , EddAmbT3N04D3 , & + EddAmbT3N04D4 , EddAmbT3N04D5 , EddAmbT3N04D6 , EddAmbT3N04D7 , EddAmbT3N04D8 , EddAmbT3N04D9 , & + EddAmbT3N05D1 , EddAmbT3N05D2 , EddAmbT3N05D3 , EddAmbT3N05D4 , EddAmbT3N05D5 , EddAmbT3N05D6 , & + EddAmbT3N05D7 , EddAmbT3N05D8 , EddAmbT3N05D9 , EddAmbT3N06D1 , EddAmbT3N06D2 , EddAmbT3N06D3 , & + EddAmbT3N06D4 , EddAmbT3N06D5 , EddAmbT3N06D6 , EddAmbT3N06D7 , EddAmbT3N06D8 , EddAmbT3N06D9 , & + EddAmbT3N07D1 , EddAmbT3N07D2 , EddAmbT3N07D3 , EddAmbT3N07D4 , EddAmbT3N07D5 , EddAmbT3N07D6 , & + EddAmbT3N07D7 , EddAmbT3N07D8 , EddAmbT3N07D9 , EddAmbT3N08D1 , EddAmbT3N08D2 , EddAmbT3N08D3 , & + EddAmbT3N08D4 , EddAmbT3N08D5 , EddAmbT3N08D6 , EddAmbT3N08D7 , EddAmbT3N08D8 , EddAmbT3N08D9 , & + EddAmbT3N09D1 , EddAmbT3N09D2 , EddAmbT3N09D3 , EddAmbT3N09D4 , EddAmbT3N09D5 , EddAmbT3N09D6 , & + EddAmbT3N09D7 , EddAmbT3N09D8 , EddAmbT3N09D9 , EddAmbT3N10D1 , EddAmbT3N10D2 , EddAmbT3N10D3 , & + EddAmbT3N10D4 , EddAmbT3N10D5 , EddAmbT3N10D6 , EddAmbT3N10D7 , EddAmbT3N10D8 , EddAmbT3N10D9 , & + EddAmbT3N11D1 , EddAmbT3N11D2 , EddAmbT3N11D3 , EddAmbT3N11D4 , EddAmbT3N11D5 , EddAmbT3N11D6 , & + EddAmbT3N11D7 , EddAmbT3N11D8 , EddAmbT3N11D9 , EddAmbT3N12D1 , EddAmbT3N12D2 , EddAmbT3N12D3 , & + EddAmbT3N12D4 , EddAmbT3N12D5 , EddAmbT3N12D6 , EddAmbT3N12D7 , EddAmbT3N12D8 , EddAmbT3N12D9 , & + EddAmbT3N13D1 , EddAmbT3N13D2 , EddAmbT3N13D3 , EddAmbT3N13D4 , EddAmbT3N13D5 , EddAmbT3N13D6 , & + EddAmbT3N13D7 , EddAmbT3N13D8 , EddAmbT3N13D9 , EddAmbT3N14D1 , EddAmbT3N14D2 , EddAmbT3N14D3 , & + EddAmbT3N14D4 , EddAmbT3N14D5 , EddAmbT3N14D6 , EddAmbT3N14D7 , EddAmbT3N14D8 , EddAmbT3N14D9 , & + EddAmbT3N15D1 , EddAmbT3N15D2 , EddAmbT3N15D3 , EddAmbT3N15D4 , EddAmbT3N15D5 , EddAmbT3N15D6 , & + EddAmbT3N15D7 , EddAmbT3N15D8 , EddAmbT3N15D9 , EddAmbT3N16D1 , EddAmbT3N16D2 , EddAmbT3N16D3 , & + EddAmbT3N16D4 , EddAmbT3N16D5 , EddAmbT3N16D6 , EddAmbT3N16D7 , EddAmbT3N16D8 , EddAmbT3N16D9 , & + EddAmbT3N17D1 , EddAmbT3N17D2 , EddAmbT3N17D3 , EddAmbT3N17D4 , EddAmbT3N17D5 , EddAmbT3N17D6 , & + EddAmbT3N17D7 , EddAmbT3N17D8 , EddAmbT3N17D9 , EddAmbT3N18D1 , EddAmbT3N18D2 , EddAmbT3N18D3 , & + EddAmbT3N18D4 , EddAmbT3N18D5 , EddAmbT3N18D6 , EddAmbT3N18D7 , EddAmbT3N18D8 , EddAmbT3N18D9 , & + EddAmbT3N19D1 , EddAmbT3N19D2 , EddAmbT3N19D3 , EddAmbT3N19D4 , EddAmbT3N19D5 , EddAmbT3N19D6 , & + EddAmbT3N19D7 , EddAmbT3N19D8 , EddAmbT3N19D9 , EddAmbT3N20D1 , EddAmbT3N20D2 , EddAmbT3N20D3 , & + EddAmbT3N20D4 , EddAmbT3N20D5 , EddAmbT3N20D6 , EddAmbT3N20D7 , EddAmbT3N20D8 , EddAmbT3N20D9 , & + EddAmbT4N01D1 , EddAmbT4N01D2 , EddAmbT4N01D3 , EddAmbT4N01D4 , EddAmbT4N01D5 , EddAmbT4N01D6 , & + EddAmbT4N01D7 , EddAmbT4N01D8 , EddAmbT4N01D9 , EddAmbT4N02D1 , EddAmbT4N02D2 , EddAmbT4N02D3 , & + EddAmbT4N02D4 , EddAmbT4N02D5 , EddAmbT4N02D6 , EddAmbT4N02D7 , EddAmbT4N02D8 , EddAmbT4N02D9 , & + EddAmbT4N03D1 , EddAmbT4N03D2 , EddAmbT4N03D3 , EddAmbT4N03D4 , EddAmbT4N03D5 , EddAmbT4N03D6 , & + EddAmbT4N03D7 , EddAmbT4N03D8 , EddAmbT4N03D9 , EddAmbT4N04D1 , EddAmbT4N04D2 , EddAmbT4N04D3 , & + EddAmbT4N04D4 , EddAmbT4N04D5 , EddAmbT4N04D6 , EddAmbT4N04D7 , EddAmbT4N04D8 , EddAmbT4N04D9 , & + EddAmbT4N05D1 , EddAmbT4N05D2 , EddAmbT4N05D3 , EddAmbT4N05D4 , EddAmbT4N05D5 , EddAmbT4N05D6 , & + EddAmbT4N05D7 , EddAmbT4N05D8 , EddAmbT4N05D9 , EddAmbT4N06D1 , EddAmbT4N06D2 , EddAmbT4N06D3 , & + EddAmbT4N06D4 , EddAmbT4N06D5 , EddAmbT4N06D6 , EddAmbT4N06D7 , EddAmbT4N06D8 , EddAmbT4N06D9 , & + EddAmbT4N07D1 , EddAmbT4N07D2 , EddAmbT4N07D3 , EddAmbT4N07D4 , EddAmbT4N07D5 , EddAmbT4N07D6 , & + EddAmbT4N07D7 , EddAmbT4N07D8 , EddAmbT4N07D9 , EddAmbT4N08D1 , EddAmbT4N08D2 , EddAmbT4N08D3 , & + EddAmbT4N08D4 , EddAmbT4N08D5 , EddAmbT4N08D6 , EddAmbT4N08D7 , EddAmbT4N08D8 , EddAmbT4N08D9 , & + EddAmbT4N09D1 , EddAmbT4N09D2 , EddAmbT4N09D3 , EddAmbT4N09D4 , EddAmbT4N09D5 , EddAmbT4N09D6 , & + EddAmbT4N09D7 , EddAmbT4N09D8 , EddAmbT4N09D9 , EddAmbT4N10D1 , EddAmbT4N10D2 , EddAmbT4N10D3 , & + EddAmbT4N10D4 , EddAmbT4N10D5 , EddAmbT4N10D6 , EddAmbT4N10D7 , EddAmbT4N10D8 , EddAmbT4N10D9 , & + EddAmbT4N11D1 , EddAmbT4N11D2 , EddAmbT4N11D3 , EddAmbT4N11D4 , EddAmbT4N11D5 , EddAmbT4N11D6 , & + EddAmbT4N11D7 , EddAmbT4N11D8 , EddAmbT4N11D9 , EddAmbT4N12D1 , EddAmbT4N12D2 , EddAmbT4N12D3 , & + EddAmbT4N12D4 , EddAmbT4N12D5 , EddAmbT4N12D6 , EddAmbT4N12D7 , EddAmbT4N12D8 , EddAmbT4N12D9 , & + EddAmbT4N13D1 , EddAmbT4N13D2 , EddAmbT4N13D3 , EddAmbT4N13D4 , EddAmbT4N13D5 , EddAmbT4N13D6 , & + EddAmbT4N13D7 , EddAmbT4N13D8 , EddAmbT4N13D9 , EddAmbT4N14D1 , EddAmbT4N14D2 , EddAmbT4N14D3 , & + EddAmbT4N14D4 , EddAmbT4N14D5 , EddAmbT4N14D6 , EddAmbT4N14D7 , EddAmbT4N14D8 , EddAmbT4N14D9 , & + EddAmbT4N15D1 , EddAmbT4N15D2 , EddAmbT4N15D3 , EddAmbT4N15D4 , EddAmbT4N15D5 , EddAmbT4N15D6 , & + EddAmbT4N15D7 , EddAmbT4N15D8 , EddAmbT4N15D9 , EddAmbT4N16D1 , EddAmbT4N16D2 , EddAmbT4N16D3 , & + EddAmbT4N16D4 , EddAmbT4N16D5 , EddAmbT4N16D6 , EddAmbT4N16D7 , EddAmbT4N16D8 , EddAmbT4N16D9 , & + EddAmbT4N17D1 , EddAmbT4N17D2 , EddAmbT4N17D3 , EddAmbT4N17D4 , EddAmbT4N17D5 , EddAmbT4N17D6 , & + EddAmbT4N17D7 , EddAmbT4N17D8 , EddAmbT4N17D9 , EddAmbT4N18D1 , EddAmbT4N18D2 , EddAmbT4N18D3 , & + EddAmbT4N18D4 , EddAmbT4N18D5 , EddAmbT4N18D6 , EddAmbT4N18D7 , EddAmbT4N18D8 , EddAmbT4N18D9 , & + EddAmbT4N19D1 , EddAmbT4N19D2 , EddAmbT4N19D3 , EddAmbT4N19D4 , EddAmbT4N19D5 , EddAmbT4N19D6 , & + EddAmbT4N19D7 , EddAmbT4N19D8 , EddAmbT4N19D9 , EddAmbT4N20D1 , EddAmbT4N20D2 , EddAmbT4N20D3 , & + EddAmbT4N20D4 , EddAmbT4N20D5 , EddAmbT4N20D6 , EddAmbT4N20D7 , EddAmbT4N20D8 , EddAmbT4N20D9 , & + EddAmbT5N01D1 , EddAmbT5N01D2 , EddAmbT5N01D3 , EddAmbT5N01D4 , EddAmbT5N01D5 , EddAmbT5N01D6 , & + EddAmbT5N01D7 , EddAmbT5N01D8 , EddAmbT5N01D9 , EddAmbT5N02D1 , EddAmbT5N02D2 , EddAmbT5N02D3 , & + EddAmbT5N02D4 , EddAmbT5N02D5 , EddAmbT5N02D6 , EddAmbT5N02D7 , EddAmbT5N02D8 , EddAmbT5N02D9 , & + EddAmbT5N03D1 , EddAmbT5N03D2 , EddAmbT5N03D3 , EddAmbT5N03D4 , EddAmbT5N03D5 , EddAmbT5N03D6 , & + EddAmbT5N03D7 , EddAmbT5N03D8 , EddAmbT5N03D9 , EddAmbT5N04D1 , EddAmbT5N04D2 , EddAmbT5N04D3 , & + EddAmbT5N04D4 , EddAmbT5N04D5 , EddAmbT5N04D6 , EddAmbT5N04D7 , EddAmbT5N04D8 , EddAmbT5N04D9 , & + EddAmbT5N05D1 , EddAmbT5N05D2 , EddAmbT5N05D3 , EddAmbT5N05D4 , EddAmbT5N05D5 , EddAmbT5N05D6 , & + EddAmbT5N05D7 , EddAmbT5N05D8 , EddAmbT5N05D9 , EddAmbT5N06D1 , EddAmbT5N06D2 , EddAmbT5N06D3 , & + EddAmbT5N06D4 , EddAmbT5N06D5 , EddAmbT5N06D6 , EddAmbT5N06D7 , EddAmbT5N06D8 , EddAmbT5N06D9 , & + EddAmbT5N07D1 , EddAmbT5N07D2 , EddAmbT5N07D3 , EddAmbT5N07D4 , EddAmbT5N07D5 , EddAmbT5N07D6 , & + EddAmbT5N07D7 , EddAmbT5N07D8 , EddAmbT5N07D9 , EddAmbT5N08D1 , EddAmbT5N08D2 , EddAmbT5N08D3 , & + EddAmbT5N08D4 , EddAmbT5N08D5 , EddAmbT5N08D6 , EddAmbT5N08D7 , EddAmbT5N08D8 , EddAmbT5N08D9 , & + EddAmbT5N09D1 , EddAmbT5N09D2 , EddAmbT5N09D3 , EddAmbT5N09D4 , EddAmbT5N09D5 , EddAmbT5N09D6 , & + EddAmbT5N09D7 , EddAmbT5N09D8 , EddAmbT5N09D9 , EddAmbT5N10D1 , EddAmbT5N10D2 , EddAmbT5N10D3 , & + EddAmbT5N10D4 , EddAmbT5N10D5 , EddAmbT5N10D6 , EddAmbT5N10D7 , EddAmbT5N10D8 , EddAmbT5N10D9 , & + EddAmbT5N11D1 , EddAmbT5N11D2 , EddAmbT5N11D3 , EddAmbT5N11D4 , EddAmbT5N11D5 , EddAmbT5N11D6 , & + EddAmbT5N11D7 , EddAmbT5N11D8 , EddAmbT5N11D9 , EddAmbT5N12D1 , EddAmbT5N12D2 , EddAmbT5N12D3 , & + EddAmbT5N12D4 , EddAmbT5N12D5 , EddAmbT5N12D6 , EddAmbT5N12D7 , EddAmbT5N12D8 , EddAmbT5N12D9 , & + EddAmbT5N13D1 , EddAmbT5N13D2 , EddAmbT5N13D3 , EddAmbT5N13D4 , EddAmbT5N13D5 , EddAmbT5N13D6 , & + EddAmbT5N13D7 , EddAmbT5N13D8 , EddAmbT5N13D9 , EddAmbT5N14D1 , EddAmbT5N14D2 , EddAmbT5N14D3 , & + EddAmbT5N14D4 , EddAmbT5N14D5 , EddAmbT5N14D6 , EddAmbT5N14D7 , EddAmbT5N14D8 , EddAmbT5N14D9 , & + EddAmbT5N15D1 , EddAmbT5N15D2 , EddAmbT5N15D3 , EddAmbT5N15D4 , EddAmbT5N15D5 , EddAmbT5N15D6 , & + EddAmbT5N15D7 , EddAmbT5N15D8 , EddAmbT5N15D9 , EddAmbT5N16D1 , EddAmbT5N16D2 , EddAmbT5N16D3 , & + EddAmbT5N16D4 , EddAmbT5N16D5 , EddAmbT5N16D6 , EddAmbT5N16D7 , EddAmbT5N16D8 , EddAmbT5N16D9 , & + EddAmbT5N17D1 , EddAmbT5N17D2 , EddAmbT5N17D3 , EddAmbT5N17D4 , EddAmbT5N17D5 , EddAmbT5N17D6 , & + EddAmbT5N17D7 , EddAmbT5N17D8 , EddAmbT5N17D9 , EddAmbT5N18D1 , EddAmbT5N18D2 , EddAmbT5N18D3 , & + EddAmbT5N18D4 , EddAmbT5N18D5 , EddAmbT5N18D6 , EddAmbT5N18D7 , EddAmbT5N18D8 , EddAmbT5N18D9 , & + EddAmbT5N19D1 , EddAmbT5N19D2 , EddAmbT5N19D3 , EddAmbT5N19D4 , EddAmbT5N19D5 , EddAmbT5N19D6 , & + EddAmbT5N19D7 , EddAmbT5N19D8 , EddAmbT5N19D9 , EddAmbT5N20D1 , EddAmbT5N20D2 , EddAmbT5N20D3 , & + EddAmbT5N20D4 , EddAmbT5N20D5 , EddAmbT5N20D6 , EddAmbT5N20D7 , EddAmbT5N20D8 , EddAmbT5N20D9 , & + EddAmbT6N01D1 , EddAmbT6N01D2 , EddAmbT6N01D3 , EddAmbT6N01D4 , EddAmbT6N01D5 , EddAmbT6N01D6 , & + EddAmbT6N01D7 , EddAmbT6N01D8 , EddAmbT6N01D9 , EddAmbT6N02D1 , EddAmbT6N02D2 , EddAmbT6N02D3 , & + EddAmbT6N02D4 , EddAmbT6N02D5 , EddAmbT6N02D6 , EddAmbT6N02D7 , EddAmbT6N02D8 , EddAmbT6N02D9 , & + EddAmbT6N03D1 , EddAmbT6N03D2 , EddAmbT6N03D3 , EddAmbT6N03D4 , EddAmbT6N03D5 , EddAmbT6N03D6 , & + EddAmbT6N03D7 , EddAmbT6N03D8 , EddAmbT6N03D9 , EddAmbT6N04D1 , EddAmbT6N04D2 , EddAmbT6N04D3 , & + EddAmbT6N04D4 , EddAmbT6N04D5 , EddAmbT6N04D6 , EddAmbT6N04D7 , EddAmbT6N04D8 , EddAmbT6N04D9 , & + EddAmbT6N05D1 , EddAmbT6N05D2 , EddAmbT6N05D3 , EddAmbT6N05D4 , EddAmbT6N05D5 , EddAmbT6N05D6 , & + EddAmbT6N05D7 , EddAmbT6N05D8 , EddAmbT6N05D9 , EddAmbT6N06D1 , EddAmbT6N06D2 , EddAmbT6N06D3 , & + EddAmbT6N06D4 , EddAmbT6N06D5 , EddAmbT6N06D6 , EddAmbT6N06D7 , EddAmbT6N06D8 , EddAmbT6N06D9 , & + EddAmbT6N07D1 , EddAmbT6N07D2 , EddAmbT6N07D3 , EddAmbT6N07D4 , EddAmbT6N07D5 , EddAmbT6N07D6 , & + EddAmbT6N07D7 , EddAmbT6N07D8 , EddAmbT6N07D9 , EddAmbT6N08D1 , EddAmbT6N08D2 , EddAmbT6N08D3 , & + EddAmbT6N08D4 , EddAmbT6N08D5 , EddAmbT6N08D6 , EddAmbT6N08D7 , EddAmbT6N08D8 , EddAmbT6N08D9 , & + EddAmbT6N09D1 , EddAmbT6N09D2 , EddAmbT6N09D3 , EddAmbT6N09D4 , EddAmbT6N09D5 , EddAmbT6N09D6 , & + EddAmbT6N09D7 , EddAmbT6N09D8 , EddAmbT6N09D9 , EddAmbT6N10D1 , EddAmbT6N10D2 , EddAmbT6N10D3 , & + EddAmbT6N10D4 , EddAmbT6N10D5 , EddAmbT6N10D6 , EddAmbT6N10D7 , EddAmbT6N10D8 , EddAmbT6N10D9 , & + EddAmbT6N11D1 , EddAmbT6N11D2 , EddAmbT6N11D3 , EddAmbT6N11D4 , EddAmbT6N11D5 , EddAmbT6N11D6 , & + EddAmbT6N11D7 , EddAmbT6N11D8 , EddAmbT6N11D9 , EddAmbT6N12D1 , EddAmbT6N12D2 , EddAmbT6N12D3 , & + EddAmbT6N12D4 , EddAmbT6N12D5 , EddAmbT6N12D6 , EddAmbT6N12D7 , EddAmbT6N12D8 , EddAmbT6N12D9 , & + EddAmbT6N13D1 , EddAmbT6N13D2 , EddAmbT6N13D3 , EddAmbT6N13D4 , EddAmbT6N13D5 , EddAmbT6N13D6 , & + EddAmbT6N13D7 , EddAmbT6N13D8 , EddAmbT6N13D9 , EddAmbT6N14D1 , EddAmbT6N14D2 , EddAmbT6N14D3 , & + EddAmbT6N14D4 , EddAmbT6N14D5 , EddAmbT6N14D6 , EddAmbT6N14D7 , EddAmbT6N14D8 , EddAmbT6N14D9 , & + EddAmbT6N15D1 , EddAmbT6N15D2 , EddAmbT6N15D3 , EddAmbT6N15D4 , EddAmbT6N15D5 , EddAmbT6N15D6 , & + EddAmbT6N15D7 , EddAmbT6N15D8 , EddAmbT6N15D9 , EddAmbT6N16D1 , EddAmbT6N16D2 , EddAmbT6N16D3 , & + EddAmbT6N16D4 , EddAmbT6N16D5 , EddAmbT6N16D6 , EddAmbT6N16D7 , EddAmbT6N16D8 , EddAmbT6N16D9 , & + EddAmbT6N17D1 , EddAmbT6N17D2 , EddAmbT6N17D3 , EddAmbT6N17D4 , EddAmbT6N17D5 , EddAmbT6N17D6 , & + EddAmbT6N17D7 , EddAmbT6N17D8 , EddAmbT6N17D9 , EddAmbT6N18D1 , EddAmbT6N18D2 , EddAmbT6N18D3 , & + EddAmbT6N18D4 , EddAmbT6N18D5 , EddAmbT6N18D6 , EddAmbT6N18D7 , EddAmbT6N18D8 , EddAmbT6N18D9 , & + EddAmbT6N19D1 , EddAmbT6N19D2 , EddAmbT6N19D3 , EddAmbT6N19D4 , EddAmbT6N19D5 , EddAmbT6N19D6 , & + EddAmbT6N19D7 , EddAmbT6N19D8 , EddAmbT6N19D9 , EddAmbT6N20D1 , EddAmbT6N20D2 , EddAmbT6N20D3 , & + EddAmbT6N20D4 , EddAmbT6N20D5 , EddAmbT6N20D6 , EddAmbT6N20D7 , EddAmbT6N20D8 , EddAmbT6N20D9 , & + EddAmbT7N01D1 , EddAmbT7N01D2 , EddAmbT7N01D3 , EddAmbT7N01D4 , EddAmbT7N01D5 , EddAmbT7N01D6 , & + EddAmbT7N01D7 , EddAmbT7N01D8 , EddAmbT7N01D9 , EddAmbT7N02D1 , EddAmbT7N02D2 , EddAmbT7N02D3 , & + EddAmbT7N02D4 , EddAmbT7N02D5 , EddAmbT7N02D6 , EddAmbT7N02D7 , EddAmbT7N02D8 , EddAmbT7N02D9 , & + EddAmbT7N03D1 , EddAmbT7N03D2 , EddAmbT7N03D3 , EddAmbT7N03D4 , EddAmbT7N03D5 , EddAmbT7N03D6 , & + EddAmbT7N03D7 , EddAmbT7N03D8 , EddAmbT7N03D9 , EddAmbT7N04D1 , EddAmbT7N04D2 , EddAmbT7N04D3 , & + EddAmbT7N04D4 , EddAmbT7N04D5 , EddAmbT7N04D6 , EddAmbT7N04D7 , EddAmbT7N04D8 , EddAmbT7N04D9 , & + EddAmbT7N05D1 , EddAmbT7N05D2 , EddAmbT7N05D3 , EddAmbT7N05D4 , EddAmbT7N05D5 , EddAmbT7N05D6 , & + EddAmbT7N05D7 , EddAmbT7N05D8 , EddAmbT7N05D9 , EddAmbT7N06D1 , EddAmbT7N06D2 , EddAmbT7N06D3 , & + EddAmbT7N06D4 , EddAmbT7N06D5 , EddAmbT7N06D6 , EddAmbT7N06D7 , EddAmbT7N06D8 , EddAmbT7N06D9 , & + EddAmbT7N07D1 , EddAmbT7N07D2 , EddAmbT7N07D3 , EddAmbT7N07D4 , EddAmbT7N07D5 , EddAmbT7N07D6 , & + EddAmbT7N07D7 , EddAmbT7N07D8 , EddAmbT7N07D9 , EddAmbT7N08D1 , EddAmbT7N08D2 , EddAmbT7N08D3 , & + EddAmbT7N08D4 , EddAmbT7N08D5 , EddAmbT7N08D6 , EddAmbT7N08D7 , EddAmbT7N08D8 , EddAmbT7N08D9 , & + EddAmbT7N09D1 , EddAmbT7N09D2 , EddAmbT7N09D3 , EddAmbT7N09D4 , EddAmbT7N09D5 , EddAmbT7N09D6 /) + INTEGER(IntKi), PARAMETER :: ParamIndxAry2(1356) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + EddAmbT7N09D7 , EddAmbT7N09D8 , EddAmbT7N09D9 , EddAmbT7N10D1 , EddAmbT7N10D2 , EddAmbT7N10D3 , & + EddAmbT7N10D4 , EddAmbT7N10D5 , EddAmbT7N10D6 , EddAmbT7N10D7 , EddAmbT7N10D8 , EddAmbT7N10D9 , & + EddAmbT7N11D1 , EddAmbT7N11D2 , EddAmbT7N11D3 , EddAmbT7N11D4 , EddAmbT7N11D5 , EddAmbT7N11D6 , & + EddAmbT7N11D7 , EddAmbT7N11D8 , EddAmbT7N11D9 , EddAmbT7N12D1 , EddAmbT7N12D2 , EddAmbT7N12D3 , & + EddAmbT7N12D4 , EddAmbT7N12D5 , EddAmbT7N12D6 , EddAmbT7N12D7 , EddAmbT7N12D8 , EddAmbT7N12D9 , & + EddAmbT7N13D1 , EddAmbT7N13D2 , EddAmbT7N13D3 , EddAmbT7N13D4 , EddAmbT7N13D5 , EddAmbT7N13D6 , & + EddAmbT7N13D7 , EddAmbT7N13D8 , EddAmbT7N13D9 , EddAmbT7N14D1 , EddAmbT7N14D2 , EddAmbT7N14D3 , & + EddAmbT7N14D4 , EddAmbT7N14D5 , EddAmbT7N14D6 , EddAmbT7N14D7 , EddAmbT7N14D8 , EddAmbT7N14D9 , & + EddAmbT7N15D1 , EddAmbT7N15D2 , EddAmbT7N15D3 , EddAmbT7N15D4 , EddAmbT7N15D5 , EddAmbT7N15D6 , & + EddAmbT7N15D7 , EddAmbT7N15D8 , EddAmbT7N15D9 , EddAmbT7N16D1 , EddAmbT7N16D2 , EddAmbT7N16D3 , & + EddAmbT7N16D4 , EddAmbT7N16D5 , EddAmbT7N16D6 , EddAmbT7N16D7 , EddAmbT7N16D8 , EddAmbT7N16D9 , & + EddAmbT7N17D1 , EddAmbT7N17D2 , EddAmbT7N17D3 , EddAmbT7N17D4 , EddAmbT7N17D5 , EddAmbT7N17D6 , & + EddAmbT7N17D7 , EddAmbT7N17D8 , EddAmbT7N17D9 , EddAmbT7N18D1 , EddAmbT7N18D2 , EddAmbT7N18D3 , & + EddAmbT7N18D4 , EddAmbT7N18D5 , EddAmbT7N18D6 , EddAmbT7N18D7 , EddAmbT7N18D8 , EddAmbT7N18D9 , & + EddAmbT7N19D1 , EddAmbT7N19D2 , EddAmbT7N19D3 , EddAmbT7N19D4 , EddAmbT7N19D5 , EddAmbT7N19D6 , & + EddAmbT7N19D7 , EddAmbT7N19D8 , EddAmbT7N19D9 , EddAmbT7N20D1 , EddAmbT7N20D2 , EddAmbT7N20D3 , & + EddAmbT7N20D4 , EddAmbT7N20D5 , EddAmbT7N20D6 , EddAmbT7N20D7 , EddAmbT7N20D8 , EddAmbT7N20D9 , & + EddAmbT8N01D1 , EddAmbT8N01D2 , EddAmbT8N01D3 , EddAmbT8N01D4 , EddAmbT8N01D5 , EddAmbT8N01D6 , & + EddAmbT8N01D7 , EddAmbT8N01D8 , EddAmbT8N01D9 , EddAmbT8N02D1 , EddAmbT8N02D2 , EddAmbT8N02D3 , & + EddAmbT8N02D4 , EddAmbT8N02D5 , EddAmbT8N02D6 , EddAmbT8N02D7 , EddAmbT8N02D8 , EddAmbT8N02D9 , & + EddAmbT8N03D1 , EddAmbT8N03D2 , EddAmbT8N03D3 , EddAmbT8N03D4 , EddAmbT8N03D5 , EddAmbT8N03D6 , & + EddAmbT8N03D7 , EddAmbT8N03D8 , EddAmbT8N03D9 , EddAmbT8N04D1 , EddAmbT8N04D2 , EddAmbT8N04D3 , & + EddAmbT8N04D4 , EddAmbT8N04D5 , EddAmbT8N04D6 , EddAmbT8N04D7 , EddAmbT8N04D8 , EddAmbT8N04D9 , & + EddAmbT8N05D1 , EddAmbT8N05D2 , EddAmbT8N05D3 , EddAmbT8N05D4 , EddAmbT8N05D5 , EddAmbT8N05D6 , & + EddAmbT8N05D7 , EddAmbT8N05D8 , EddAmbT8N05D9 , EddAmbT8N06D1 , EddAmbT8N06D2 , EddAmbT8N06D3 , & + EddAmbT8N06D4 , EddAmbT8N06D5 , EddAmbT8N06D6 , EddAmbT8N06D7 , EddAmbT8N06D8 , EddAmbT8N06D9 , & + EddAmbT8N07D1 , EddAmbT8N07D2 , EddAmbT8N07D3 , EddAmbT8N07D4 , EddAmbT8N07D5 , EddAmbT8N07D6 , & + EddAmbT8N07D7 , EddAmbT8N07D8 , EddAmbT8N07D9 , EddAmbT8N08D1 , EddAmbT8N08D2 , EddAmbT8N08D3 , & + EddAmbT8N08D4 , EddAmbT8N08D5 , EddAmbT8N08D6 , EddAmbT8N08D7 , EddAmbT8N08D8 , EddAmbT8N08D9 , & + EddAmbT8N09D1 , EddAmbT8N09D2 , EddAmbT8N09D3 , EddAmbT8N09D4 , EddAmbT8N09D5 , EddAmbT8N09D6 , & + EddAmbT8N09D7 , EddAmbT8N09D8 , EddAmbT8N09D9 , EddAmbT8N10D1 , EddAmbT8N10D2 , EddAmbT8N10D3 , & + EddAmbT8N10D4 , EddAmbT8N10D5 , EddAmbT8N10D6 , EddAmbT8N10D7 , EddAmbT8N10D8 , EddAmbT8N10D9 , & + EddAmbT8N11D1 , EddAmbT8N11D2 , EddAmbT8N11D3 , EddAmbT8N11D4 , EddAmbT8N11D5 , EddAmbT8N11D6 , & + EddAmbT8N11D7 , EddAmbT8N11D8 , EddAmbT8N11D9 , EddAmbT8N12D1 , EddAmbT8N12D2 , EddAmbT8N12D3 , & + EddAmbT8N12D4 , EddAmbT8N12D5 , EddAmbT8N12D6 , EddAmbT8N12D7 , EddAmbT8N12D8 , EddAmbT8N12D9 , & + EddAmbT8N13D1 , EddAmbT8N13D2 , EddAmbT8N13D3 , EddAmbT8N13D4 , EddAmbT8N13D5 , EddAmbT8N13D6 , & + EddAmbT8N13D7 , EddAmbT8N13D8 , EddAmbT8N13D9 , EddAmbT8N14D1 , EddAmbT8N14D2 , EddAmbT8N14D3 , & + EddAmbT8N14D4 , EddAmbT8N14D5 , EddAmbT8N14D6 , EddAmbT8N14D7 , EddAmbT8N14D8 , EddAmbT8N14D9 , & + EddAmbT8N15D1 , EddAmbT8N15D2 , EddAmbT8N15D3 , EddAmbT8N15D4 , EddAmbT8N15D5 , EddAmbT8N15D6 , & + EddAmbT8N15D7 , EddAmbT8N15D8 , EddAmbT8N15D9 , EddAmbT8N16D1 , EddAmbT8N16D2 , EddAmbT8N16D3 , & + EddAmbT8N16D4 , EddAmbT8N16D5 , EddAmbT8N16D6 , EddAmbT8N16D7 , EddAmbT8N16D8 , EddAmbT8N16D9 , & + EddAmbT8N17D1 , EddAmbT8N17D2 , EddAmbT8N17D3 , EddAmbT8N17D4 , EddAmbT8N17D5 , EddAmbT8N17D6 , & + EddAmbT8N17D7 , EddAmbT8N17D8 , EddAmbT8N17D9 , EddAmbT8N18D1 , EddAmbT8N18D2 , EddAmbT8N18D3 , & + EddAmbT8N18D4 , EddAmbT8N18D5 , EddAmbT8N18D6 , EddAmbT8N18D7 , EddAmbT8N18D8 , EddAmbT8N18D9 , & + EddAmbT8N19D1 , EddAmbT8N19D2 , EddAmbT8N19D3 , EddAmbT8N19D4 , EddAmbT8N19D5 , EddAmbT8N19D6 , & + EddAmbT8N19D7 , EddAmbT8N19D8 , EddAmbT8N19D9 , EddAmbT8N20D1 , EddAmbT8N20D2 , EddAmbT8N20D3 , & + EddAmbT8N20D4 , EddAmbT8N20D5 , EddAmbT8N20D6 , EddAmbT8N20D7 , EddAmbT8N20D8 , EddAmbT8N20D9 , & + EddAmbT9N01D1 , EddAmbT9N01D2 , EddAmbT9N01D3 , EddAmbT9N01D4 , EddAmbT9N01D5 , EddAmbT9N01D6 , & + EddAmbT9N01D7 , EddAmbT9N01D8 , EddAmbT9N01D9 , EddAmbT9N02D1 , EddAmbT9N02D2 , EddAmbT9N02D3 , & + EddAmbT9N02D4 , EddAmbT9N02D5 , EddAmbT9N02D6 , EddAmbT9N02D7 , EddAmbT9N02D8 , EddAmbT9N02D9 , & + EddAmbT9N03D1 , EddAmbT9N03D2 , EddAmbT9N03D3 , EddAmbT9N03D4 , EddAmbT9N03D5 , EddAmbT9N03D6 , & + EddAmbT9N03D7 , EddAmbT9N03D8 , EddAmbT9N03D9 , EddAmbT9N04D1 , EddAmbT9N04D2 , EddAmbT9N04D3 , & + EddAmbT9N04D4 , EddAmbT9N04D5 , EddAmbT9N04D6 , EddAmbT9N04D7 , EddAmbT9N04D8 , EddAmbT9N04D9 , & + EddAmbT9N05D1 , EddAmbT9N05D2 , EddAmbT9N05D3 , EddAmbT9N05D4 , EddAmbT9N05D5 , EddAmbT9N05D6 , & + EddAmbT9N05D7 , EddAmbT9N05D8 , EddAmbT9N05D9 , EddAmbT9N06D1 , EddAmbT9N06D2 , EddAmbT9N06D3 , & + EddAmbT9N06D4 , EddAmbT9N06D5 , EddAmbT9N06D6 , EddAmbT9N06D7 , EddAmbT9N06D8 , EddAmbT9N06D9 , & + EddAmbT9N07D1 , EddAmbT9N07D2 , EddAmbT9N07D3 , EddAmbT9N07D4 , EddAmbT9N07D5 , EddAmbT9N07D6 , & + EddAmbT9N07D7 , EddAmbT9N07D8 , EddAmbT9N07D9 , EddAmbT9N08D1 , EddAmbT9N08D2 , EddAmbT9N08D3 , & + EddAmbT9N08D4 , EddAmbT9N08D5 , EddAmbT9N08D6 , EddAmbT9N08D7 , EddAmbT9N08D8 , EddAmbT9N08D9 , & + EddAmbT9N09D1 , EddAmbT9N09D2 , EddAmbT9N09D3 , EddAmbT9N09D4 , EddAmbT9N09D5 , EddAmbT9N09D6 , & + EddAmbT9N09D7 , EddAmbT9N09D8 , EddAmbT9N09D9 , EddAmbT9N10D1 , EddAmbT9N10D2 , EddAmbT9N10D3 , & + EddAmbT9N10D4 , EddAmbT9N10D5 , EddAmbT9N10D6 , EddAmbT9N10D7 , EddAmbT9N10D8 , EddAmbT9N10D9 , & + EddAmbT9N11D1 , EddAmbT9N11D2 , EddAmbT9N11D3 , EddAmbT9N11D4 , EddAmbT9N11D5 , EddAmbT9N11D6 , & + EddAmbT9N11D7 , EddAmbT9N11D8 , EddAmbT9N11D9 , EddAmbT9N12D1 , EddAmbT9N12D2 , EddAmbT9N12D3 , & + EddAmbT9N12D4 , EddAmbT9N12D5 , EddAmbT9N12D6 , EddAmbT9N12D7 , EddAmbT9N12D8 , EddAmbT9N12D9 , & + EddAmbT9N13D1 , EddAmbT9N13D2 , EddAmbT9N13D3 , EddAmbT9N13D4 , EddAmbT9N13D5 , EddAmbT9N13D6 , & + EddAmbT9N13D7 , EddAmbT9N13D8 , EddAmbT9N13D9 , EddAmbT9N14D1 , EddAmbT9N14D2 , EddAmbT9N14D3 , & + EddAmbT9N14D4 , EddAmbT9N14D5 , EddAmbT9N14D6 , EddAmbT9N14D7 , EddAmbT9N14D8 , EddAmbT9N14D9 , & + EddAmbT9N15D1 , EddAmbT9N15D2 , EddAmbT9N15D3 , EddAmbT9N15D4 , EddAmbT9N15D5 , EddAmbT9N15D6 , & + EddAmbT9N15D7 , EddAmbT9N15D8 , EddAmbT9N15D9 , EddAmbT9N16D1 , EddAmbT9N16D2 , EddAmbT9N16D3 , & + EddAmbT9N16D4 , EddAmbT9N16D5 , EddAmbT9N16D6 , EddAmbT9N16D7 , EddAmbT9N16D8 , EddAmbT9N16D9 , & + EddAmbT9N17D1 , EddAmbT9N17D2 , EddAmbT9N17D3 , EddAmbT9N17D4 , EddAmbT9N17D5 , EddAmbT9N17D6 , & + EddAmbT9N17D7 , EddAmbT9N17D8 , EddAmbT9N17D9 , EddAmbT9N18D1 , EddAmbT9N18D2 , EddAmbT9N18D3 , & + EddAmbT9N18D4 , EddAmbT9N18D5 , EddAmbT9N18D6 , EddAmbT9N18D7 , EddAmbT9N18D8 , EddAmbT9N18D9 , & + EddAmbT9N19D1 , EddAmbT9N19D2 , EddAmbT9N19D3 , EddAmbT9N19D4 , EddAmbT9N19D5 , EddAmbT9N19D6 , & + EddAmbT9N19D7 , EddAmbT9N19D8 , EddAmbT9N19D9 , EddAmbT9N20D1 , EddAmbT9N20D2 , EddAmbT9N20D3 , & + EddAmbT9N20D4 , EddAmbT9N20D5 , EddAmbT9N20D6 , EddAmbT9N20D7 , EddAmbT9N20D8 , EddAmbT9N20D9 , & + EddShrT1N01D1 , EddShrT1N01D2 , EddShrT1N01D3 , EddShrT1N01D4 , EddShrT1N01D5 , EddShrT1N01D6 , & + EddShrT1N01D7 , EddShrT1N01D8 , EddShrT1N01D9 , EddShrT1N02D1 , EddShrT1N02D2 , EddShrT1N02D3 , & + EddShrT1N02D4 , EddShrT1N02D5 , EddShrT1N02D6 , EddShrT1N02D7 , EddShrT1N02D8 , EddShrT1N02D9 , & + EddShrT1N03D1 , EddShrT1N03D2 , EddShrT1N03D3 , EddShrT1N03D4 , EddShrT1N03D5 , EddShrT1N03D6 , & + EddShrT1N03D7 , EddShrT1N03D8 , EddShrT1N03D9 , EddShrT1N04D1 , EddShrT1N04D2 , EddShrT1N04D3 , & + EddShrT1N04D4 , EddShrT1N04D5 , EddShrT1N04D6 , EddShrT1N04D7 , EddShrT1N04D8 , EddShrT1N04D9 , & + EddShrT1N05D1 , EddShrT1N05D2 , EddShrT1N05D3 , EddShrT1N05D4 , EddShrT1N05D5 , EddShrT1N05D6 , & + EddShrT1N05D7 , EddShrT1N05D8 , EddShrT1N05D9 , EddShrT1N06D1 , EddShrT1N06D2 , EddShrT1N06D3 , & + EddShrT1N06D4 , EddShrT1N06D5 , EddShrT1N06D6 , EddShrT1N06D7 , EddShrT1N06D8 , EddShrT1N06D9 , & + EddShrT1N07D1 , EddShrT1N07D2 , EddShrT1N07D3 , EddShrT1N07D4 , EddShrT1N07D5 , EddShrT1N07D6 , & + EddShrT1N07D7 , EddShrT1N07D8 , EddShrT1N07D9 , EddShrT1N08D1 , EddShrT1N08D2 , EddShrT1N08D3 , & + EddShrT1N08D4 , EddShrT1N08D5 , EddShrT1N08D6 , EddShrT1N08D7 , EddShrT1N08D8 , EddShrT1N08D9 , & + EddShrT1N09D1 , EddShrT1N09D2 , EddShrT1N09D3 , EddShrT1N09D4 , EddShrT1N09D5 , EddShrT1N09D6 , & + EddShrT1N09D7 , EddShrT1N09D8 , EddShrT1N09D9 , EddShrT1N10D1 , EddShrT1N10D2 , EddShrT1N10D3 , & + EddShrT1N10D4 , EddShrT1N10D5 , EddShrT1N10D6 , EddShrT1N10D7 , EddShrT1N10D8 , EddShrT1N10D9 , & + EddShrT1N11D1 , EddShrT1N11D2 , EddShrT1N11D3 , EddShrT1N11D4 , EddShrT1N11D5 , EddShrT1N11D6 , & + EddShrT1N11D7 , EddShrT1N11D8 , EddShrT1N11D9 , EddShrT1N12D1 , EddShrT1N12D2 , EddShrT1N12D3 , & + EddShrT1N12D4 , EddShrT1N12D5 , EddShrT1N12D6 , EddShrT1N12D7 , EddShrT1N12D8 , EddShrT1N12D9 , & + EddShrT1N13D1 , EddShrT1N13D2 , EddShrT1N13D3 , EddShrT1N13D4 , EddShrT1N13D5 , EddShrT1N13D6 , & + EddShrT1N13D7 , EddShrT1N13D8 , EddShrT1N13D9 , EddShrT1N14D1 , EddShrT1N14D2 , EddShrT1N14D3 , & + EddShrT1N14D4 , EddShrT1N14D5 , EddShrT1N14D6 , EddShrT1N14D7 , EddShrT1N14D8 , EddShrT1N14D9 , & + EddShrT1N15D1 , EddShrT1N15D2 , EddShrT1N15D3 , EddShrT1N15D4 , EddShrT1N15D5 , EddShrT1N15D6 , & + EddShrT1N15D7 , EddShrT1N15D8 , EddShrT1N15D9 , EddShrT1N16D1 , EddShrT1N16D2 , EddShrT1N16D3 , & + EddShrT1N16D4 , EddShrT1N16D5 , EddShrT1N16D6 , EddShrT1N16D7 , EddShrT1N16D8 , EddShrT1N16D9 , & + EddShrT1N17D1 , EddShrT1N17D2 , EddShrT1N17D3 , EddShrT1N17D4 , EddShrT1N17D5 , EddShrT1N17D6 , & + EddShrT1N17D7 , EddShrT1N17D8 , EddShrT1N17D9 , EddShrT1N18D1 , EddShrT1N18D2 , EddShrT1N18D3 , & + EddShrT1N18D4 , EddShrT1N18D5 , EddShrT1N18D6 , EddShrT1N18D7 , EddShrT1N18D8 , EddShrT1N18D9 , & + EddShrT1N19D1 , EddShrT1N19D2 , EddShrT1N19D3 , EddShrT1N19D4 , EddShrT1N19D5 , EddShrT1N19D6 , & + EddShrT1N19D7 , EddShrT1N19D8 , EddShrT1N19D9 , EddShrT1N20D1 , EddShrT1N20D2 , EddShrT1N20D3 , & + EddShrT1N20D4 , EddShrT1N20D5 , EddShrT1N20D6 , EddShrT1N20D7 , EddShrT1N20D8 , EddShrT1N20D9 , & + EddShrT2N01D1 , EddShrT2N01D2 , EddShrT2N01D3 , EddShrT2N01D4 , EddShrT2N01D5 , EddShrT2N01D6 , & + EddShrT2N01D7 , EddShrT2N01D8 , EddShrT2N01D9 , EddShrT2N02D1 , EddShrT2N02D2 , EddShrT2N02D3 , & + EddShrT2N02D4 , EddShrT2N02D5 , EddShrT2N02D6 , EddShrT2N02D7 , EddShrT2N02D8 , EddShrT2N02D9 , & + EddShrT2N03D1 , EddShrT2N03D2 , EddShrT2N03D3 , EddShrT2N03D4 , EddShrT2N03D5 , EddShrT2N03D6 , & + EddShrT2N03D7 , EddShrT2N03D8 , EddShrT2N03D9 , EddShrT2N04D1 , EddShrT2N04D2 , EddShrT2N04D3 , & + EddShrT2N04D4 , EddShrT2N04D5 , EddShrT2N04D6 , EddShrT2N04D7 , EddShrT2N04D8 , EddShrT2N04D9 , & + EddShrT2N05D1 , EddShrT2N05D2 , EddShrT2N05D3 , EddShrT2N05D4 , EddShrT2N05D5 , EddShrT2N05D6 , & + EddShrT2N05D7 , EddShrT2N05D8 , EddShrT2N05D9 , EddShrT2N06D1 , EddShrT2N06D2 , EddShrT2N06D3 , & + EddShrT2N06D4 , EddShrT2N06D5 , EddShrT2N06D6 , EddShrT2N06D7 , EddShrT2N06D8 , EddShrT2N06D9 , & + EddShrT2N07D1 , EddShrT2N07D2 , EddShrT2N07D3 , EddShrT2N07D4 , EddShrT2N07D5 , EddShrT2N07D6 , & + EddShrT2N07D7 , EddShrT2N07D8 , EddShrT2N07D9 , EddShrT2N08D1 , EddShrT2N08D2 , EddShrT2N08D3 , & + EddShrT2N08D4 , EddShrT2N08D5 , EddShrT2N08D6 , EddShrT2N08D7 , EddShrT2N08D8 , EddShrT2N08D9 , & + EddShrT2N09D1 , EddShrT2N09D2 , EddShrT2N09D3 , EddShrT2N09D4 , EddShrT2N09D5 , EddShrT2N09D6 , & + EddShrT2N09D7 , EddShrT2N09D8 , EddShrT2N09D9 , EddShrT2N10D1 , EddShrT2N10D2 , EddShrT2N10D3 , & + EddShrT2N10D4 , EddShrT2N10D5 , EddShrT2N10D6 , EddShrT2N10D7 , EddShrT2N10D8 , EddShrT2N10D9 , & + EddShrT2N11D1 , EddShrT2N11D2 , EddShrT2N11D3 , EddShrT2N11D4 , EddShrT2N11D5 , EddShrT2N11D6 , & + EddShrT2N11D7 , EddShrT2N11D8 , EddShrT2N11D9 , EddShrT2N12D1 , EddShrT2N12D2 , EddShrT2N12D3 , & + EddShrT2N12D4 , EddShrT2N12D5 , EddShrT2N12D6 , EddShrT2N12D7 , EddShrT2N12D8 , EddShrT2N12D9 , & + EddShrT2N13D1 , EddShrT2N13D2 , EddShrT2N13D3 , EddShrT2N13D4 , EddShrT2N13D5 , EddShrT2N13D6 , & + EddShrT2N13D7 , EddShrT2N13D8 , EddShrT2N13D9 , EddShrT2N14D1 , EddShrT2N14D2 , EddShrT2N14D3 , & + EddShrT2N14D4 , EddShrT2N14D5 , EddShrT2N14D6 , EddShrT2N14D7 , EddShrT2N14D8 , EddShrT2N14D9 , & + EddShrT2N15D1 , EddShrT2N15D2 , EddShrT2N15D3 , EddShrT2N15D4 , EddShrT2N15D5 , EddShrT2N15D6 , & + EddShrT2N15D7 , EddShrT2N15D8 , EddShrT2N15D9 , EddShrT2N16D1 , EddShrT2N16D2 , EddShrT2N16D3 , & + EddShrT2N16D4 , EddShrT2N16D5 , EddShrT2N16D6 , EddShrT2N16D7 , EddShrT2N16D8 , EddShrT2N16D9 , & + EddShrT2N17D1 , EddShrT2N17D2 , EddShrT2N17D3 , EddShrT2N17D4 , EddShrT2N17D5 , EddShrT2N17D6 , & + EddShrT2N17D7 , EddShrT2N17D8 , EddShrT2N17D9 , EddShrT2N18D1 , EddShrT2N18D2 , EddShrT2N18D3 , & + EddShrT2N18D4 , EddShrT2N18D5 , EddShrT2N18D6 , EddShrT2N18D7 , EddShrT2N18D8 , EddShrT2N18D9 , & + EddShrT2N19D1 , EddShrT2N19D2 , EddShrT2N19D3 , EddShrT2N19D4 , EddShrT2N19D5 , EddShrT2N19D6 , & + EddShrT2N19D7 , EddShrT2N19D8 , EddShrT2N19D9 , EddShrT2N20D1 , EddShrT2N20D2 , EddShrT2N20D3 , & + EddShrT2N20D4 , EddShrT2N20D5 , EddShrT2N20D6 , EddShrT2N20D7 , EddShrT2N20D8 , EddShrT2N20D9 , & + EddShrT3N01D1 , EddShrT3N01D2 , EddShrT3N01D3 , EddShrT3N01D4 , EddShrT3N01D5 , EddShrT3N01D6 , & + EddShrT3N01D7 , EddShrT3N01D8 , EddShrT3N01D9 , EddShrT3N02D1 , EddShrT3N02D2 , EddShrT3N02D3 , & + EddShrT3N02D4 , EddShrT3N02D5 , EddShrT3N02D6 , EddShrT3N02D7 , EddShrT3N02D8 , EddShrT3N02D9 , & + EddShrT3N03D1 , EddShrT3N03D2 , EddShrT3N03D3 , EddShrT3N03D4 , EddShrT3N03D5 , EddShrT3N03D6 , & + EddShrT3N03D7 , EddShrT3N03D8 , EddShrT3N03D9 , EddShrT3N04D1 , EddShrT3N04D2 , EddShrT3N04D3 , & + EddShrT3N04D4 , EddShrT3N04D5 , EddShrT3N04D6 , EddShrT3N04D7 , EddShrT3N04D8 , EddShrT3N04D9 , & + EddShrT3N05D1 , EddShrT3N05D2 , EddShrT3N05D3 , EddShrT3N05D4 , EddShrT3N05D5 , EddShrT3N05D6 , & + EddShrT3N05D7 , EddShrT3N05D8 , EddShrT3N05D9 , EddShrT3N06D1 , EddShrT3N06D2 , EddShrT3N06D3 , & + EddShrT3N06D4 , EddShrT3N06D5 , EddShrT3N06D6 , EddShrT3N06D7 , EddShrT3N06D8 , EddShrT3N06D9 , & + EddShrT3N07D1 , EddShrT3N07D2 , EddShrT3N07D3 , EddShrT3N07D4 , EddShrT3N07D5 , EddShrT3N07D6 , & + EddShrT3N07D7 , EddShrT3N07D8 , EddShrT3N07D9 , EddShrT3N08D1 , EddShrT3N08D2 , EddShrT3N08D3 , & + EddShrT3N08D4 , EddShrT3N08D5 , EddShrT3N08D6 , EddShrT3N08D7 , EddShrT3N08D8 , EddShrT3N08D9 , & + EddShrT3N09D1 , EddShrT3N09D2 , EddShrT3N09D3 , EddShrT3N09D4 , EddShrT3N09D5 , EddShrT3N09D6 , & + EddShrT3N09D7 , EddShrT3N09D8 , EddShrT3N09D9 , EddShrT3N10D1 , EddShrT3N10D2 , EddShrT3N10D3 , & + EddShrT3N10D4 , EddShrT3N10D5 , EddShrT3N10D6 , EddShrT3N10D7 , EddShrT3N10D8 , EddShrT3N10D9 , & + EddShrT3N11D1 , EddShrT3N11D2 , EddShrT3N11D3 , EddShrT3N11D4 , EddShrT3N11D5 , EddShrT3N11D6 , & + EddShrT3N11D7 , EddShrT3N11D8 , EddShrT3N11D9 , EddShrT3N12D1 , EddShrT3N12D2 , EddShrT3N12D3 , & + EddShrT3N12D4 , EddShrT3N12D5 , EddShrT3N12D6 , EddShrT3N12D7 , EddShrT3N12D8 , EddShrT3N12D9 , & + EddShrT3N13D1 , EddShrT3N13D2 , EddShrT3N13D3 , EddShrT3N13D4 , EddShrT3N13D5 , EddShrT3N13D6 , & + EddShrT3N13D7 , EddShrT3N13D8 , EddShrT3N13D9 , EddShrT3N14D1 , EddShrT3N14D2 , EddShrT3N14D3 , & + EddShrT3N14D4 , EddShrT3N14D5 , EddShrT3N14D6 , EddShrT3N14D7 , EddShrT3N14D8 , EddShrT3N14D9 , & + EddShrT3N15D1 , EddShrT3N15D2 , EddShrT3N15D3 , EddShrT3N15D4 , EddShrT3N15D5 , EddShrT3N15D6 , & + EddShrT3N15D7 , EddShrT3N15D8 , EddShrT3N15D9 , EddShrT3N16D1 , EddShrT3N16D2 , EddShrT3N16D3 , & + EddShrT3N16D4 , EddShrT3N16D5 , EddShrT3N16D6 , EddShrT3N16D7 , EddShrT3N16D8 , EddShrT3N16D9 , & + EddShrT3N17D1 , EddShrT3N17D2 , EddShrT3N17D3 , EddShrT3N17D4 , EddShrT3N17D5 , EddShrT3N17D6 , & + EddShrT3N17D7 , EddShrT3N17D8 , EddShrT3N17D9 , EddShrT3N18D1 , EddShrT3N18D2 , EddShrT3N18D3 , & + EddShrT3N18D4 , EddShrT3N18D5 , EddShrT3N18D6 , EddShrT3N18D7 , EddShrT3N18D8 , EddShrT3N18D9 , & + EddShrT3N19D1 , EddShrT3N19D2 , EddShrT3N19D3 , EddShrT3N19D4 , EddShrT3N19D5 , EddShrT3N19D6 , & + EddShrT3N19D7 , EddShrT3N19D8 , EddShrT3N19D9 , EddShrT3N20D1 , EddShrT3N20D2 , EddShrT3N20D3 , & + EddShrT3N20D4 , EddShrT3N20D5 , EddShrT3N20D6 , EddShrT3N20D7 , EddShrT3N20D8 , EddShrT3N20D9 , & + EddShrT4N01D1 , EddShrT4N01D2 , EddShrT4N01D3 , EddShrT4N01D4 , EddShrT4N01D5 , EddShrT4N01D6 , & + EddShrT4N01D7 , EddShrT4N01D8 , EddShrT4N01D9 , EddShrT4N02D1 , EddShrT4N02D2 , EddShrT4N02D3 , & + EddShrT4N02D4 , EddShrT4N02D5 , EddShrT4N02D6 , EddShrT4N02D7 , EddShrT4N02D8 , EddShrT4N02D9 , & + EddShrT4N03D1 , EddShrT4N03D2 , EddShrT4N03D3 , EddShrT4N03D4 , EddShrT4N03D5 , EddShrT4N03D6 , & + EddShrT4N03D7 , EddShrT4N03D8 , EddShrT4N03D9 , EddShrT4N04D1 , EddShrT4N04D2 , EddShrT4N04D3 , & + EddShrT4N04D4 , EddShrT4N04D5 , EddShrT4N04D6 , EddShrT4N04D7 , EddShrT4N04D8 , EddShrT4N04D9 , & + EddShrT4N05D1 , EddShrT4N05D2 , EddShrT4N05D3 , EddShrT4N05D4 , EddShrT4N05D5 , EddShrT4N05D6 , & + EddShrT4N05D7 , EddShrT4N05D8 , EddShrT4N05D9 , EddShrT4N06D1 , EddShrT4N06D2 , EddShrT4N06D3 , & + EddShrT4N06D4 , EddShrT4N06D5 , EddShrT4N06D6 , EddShrT4N06D7 , EddShrT4N06D8 , EddShrT4N06D9 , & + EddShrT4N07D1 , EddShrT4N07D2 , EddShrT4N07D3 , EddShrT4N07D4 , EddShrT4N07D5 , EddShrT4N07D6 , & + EddShrT4N07D7 , EddShrT4N07D8 , EddShrT4N07D9 , EddShrT4N08D1 , EddShrT4N08D2 , EddShrT4N08D3 , & + EddShrT4N08D4 , EddShrT4N08D5 , EddShrT4N08D6 , EddShrT4N08D7 , EddShrT4N08D8 , EddShrT4N08D9 , & + EddShrT4N09D1 , EddShrT4N09D2 , EddShrT4N09D3 , EddShrT4N09D4 , EddShrT4N09D5 , EddShrT4N09D6 , & + EddShrT4N09D7 , EddShrT4N09D8 , EddShrT4N09D9 , EddShrT4N10D1 , EddShrT4N10D2 , EddShrT4N10D3 , & + EddShrT4N10D4 , EddShrT4N10D5 , EddShrT4N10D6 , EddShrT4N10D7 , EddShrT4N10D8 , EddShrT4N10D9 , & + EddShrT4N11D1 , EddShrT4N11D2 , EddShrT4N11D3 , EddShrT4N11D4 , EddShrT4N11D5 , EddShrT4N11D6 , & + EddShrT4N11D7 , EddShrT4N11D8 , EddShrT4N11D9 , EddShrT4N12D1 , EddShrT4N12D2 , EddShrT4N12D3 , & + EddShrT4N12D4 , EddShrT4N12D5 , EddShrT4N12D6 , EddShrT4N12D7 , EddShrT4N12D8 , EddShrT4N12D9 , & + EddShrT4N13D1 , EddShrT4N13D2 , EddShrT4N13D3 , EddShrT4N13D4 , EddShrT4N13D5 , EddShrT4N13D6 , & + EddShrT4N13D7 , EddShrT4N13D8 , EddShrT4N13D9 , EddShrT4N14D1 , EddShrT4N14D2 , EddShrT4N14D3 , & + EddShrT4N14D4 , EddShrT4N14D5 , EddShrT4N14D6 , EddShrT4N14D7 , EddShrT4N14D8 , EddShrT4N14D9 , & + EddShrT4N15D1 , EddShrT4N15D2 , EddShrT4N15D3 , EddShrT4N15D4 , EddShrT4N15D5 , EddShrT4N15D6 , & + EddShrT4N15D7 , EddShrT4N15D8 , EddShrT4N15D9 , EddShrT4N16D1 , EddShrT4N16D2 , EddShrT4N16D3 , & + EddShrT4N16D4 , EddShrT4N16D5 , EddShrT4N16D6 , EddShrT4N16D7 , EddShrT4N16D8 , EddShrT4N16D9 , & + EddShrT4N17D1 , EddShrT4N17D2 , EddShrT4N17D3 , EddShrT4N17D4 , EddShrT4N17D5 , EddShrT4N17D6 , & + EddShrT4N17D7 , EddShrT4N17D8 , EddShrT4N17D9 , EddShrT4N18D1 , EddShrT4N18D2 , EddShrT4N18D3 , & + EddShrT4N18D4 , EddShrT4N18D5 , EddShrT4N18D6 , EddShrT4N18D7 , EddShrT4N18D8 , EddShrT4N18D9 , & + EddShrT4N19D1 , EddShrT4N19D2 , EddShrT4N19D3 , EddShrT4N19D4 , EddShrT4N19D5 , EddShrT4N19D6 , & + EddShrT4N19D7 , EddShrT4N19D8 , EddShrT4N19D9 , EddShrT4N20D1 , EddShrT4N20D2 , EddShrT4N20D3 , & + EddShrT4N20D4 , EddShrT4N20D5 , EddShrT4N20D6 , EddShrT4N20D7 , EddShrT4N20D8 , EddShrT4N20D9 , & + EddShrT5N01D1 , EddShrT5N01D2 , EddShrT5N01D3 , EddShrT5N01D4 , EddShrT5N01D5 , EddShrT5N01D6 , & + EddShrT5N01D7 , EddShrT5N01D8 , EddShrT5N01D9 , EddShrT5N02D1 , EddShrT5N02D2 , EddShrT5N02D3 , & + EddShrT5N02D4 , EddShrT5N02D5 , EddShrT5N02D6 , EddShrT5N02D7 , EddShrT5N02D8 , EddShrT5N02D9 , & + EddShrT5N03D1 , EddShrT5N03D2 , EddShrT5N03D3 , EddShrT5N03D4 , EddShrT5N03D5 , EddShrT5N03D6 , & + EddShrT5N03D7 , EddShrT5N03D8 , EddShrT5N03D9 , EddShrT5N04D1 , EddShrT5N04D2 , EddShrT5N04D3 , & + EddShrT5N04D4 , EddShrT5N04D5 , EddShrT5N04D6 , EddShrT5N04D7 , EddShrT5N04D8 , EddShrT5N04D9 , & + EddShrT5N05D1 , EddShrT5N05D2 , EddShrT5N05D3 , EddShrT5N05D4 , EddShrT5N05D5 , EddShrT5N05D6 , & + EddShrT5N05D7 , EddShrT5N05D8 , EddShrT5N05D9 , EddShrT5N06D1 , EddShrT5N06D2 , EddShrT5N06D3 , & + EddShrT5N06D4 , EddShrT5N06D5 , EddShrT5N06D6 , EddShrT5N06D7 , EddShrT5N06D8 , EddShrT5N06D9 , & + EddShrT5N07D1 , EddShrT5N07D2 , EddShrT5N07D3 , EddShrT5N07D4 , EddShrT5N07D5 , EddShrT5N07D6 , & + EddShrT5N07D7 , EddShrT5N07D8 , EddShrT5N07D9 , EddShrT5N08D1 , EddShrT5N08D2 , EddShrT5N08D3 , & + EddShrT5N08D4 , EddShrT5N08D5 , EddShrT5N08D6 , EddShrT5N08D7 , EddShrT5N08D8 , EddShrT5N08D9 , & + EddShrT5N09D1 , EddShrT5N09D2 , EddShrT5N09D3 , EddShrT5N09D4 , EddShrT5N09D5 , EddShrT5N09D6 , & + EddShrT5N09D7 , EddShrT5N09D8 , EddShrT5N09D9 , EddShrT5N10D1 , EddShrT5N10D2 , EddShrT5N10D3 , & + EddShrT5N10D4 , EddShrT5N10D5 , EddShrT5N10D6 , EddShrT5N10D7 , EddShrT5N10D8 , EddShrT5N10D9 , & + EddShrT5N11D1 , EddShrT5N11D2 , EddShrT5N11D3 , EddShrT5N11D4 , EddShrT5N11D5 , EddShrT5N11D6 , & + EddShrT5N11D7 , EddShrT5N11D8 , EddShrT5N11D9 , EddShrT5N12D1 , EddShrT5N12D2 , EddShrT5N12D3 , & + EddShrT5N12D4 , EddShrT5N12D5 , EddShrT5N12D6 , EddShrT5N12D7 , EddShrT5N12D8 , EddShrT5N12D9 , & + EddShrT5N13D1 , EddShrT5N13D2 , EddShrT5N13D3 , EddShrT5N13D4 , EddShrT5N13D5 , EddShrT5N13D6 , & + EddShrT5N13D7 , EddShrT5N13D8 , EddShrT5N13D9 , EddShrT5N14D1 , EddShrT5N14D2 , EddShrT5N14D3 , & + EddShrT5N14D4 , EddShrT5N14D5 , EddShrT5N14D6 , EddShrT5N14D7 , EddShrT5N14D8 , EddShrT5N14D9 , & + EddShrT5N15D1 , EddShrT5N15D2 , EddShrT5N15D3 , EddShrT5N15D4 , EddShrT5N15D5 , EddShrT5N15D6 , & + EddShrT5N15D7 , EddShrT5N15D8 , EddShrT5N15D9 , EddShrT5N16D1 , EddShrT5N16D2 , EddShrT5N16D3 , & + EddShrT5N16D4 , EddShrT5N16D5 , EddShrT5N16D6 , EddShrT5N16D7 , EddShrT5N16D8 , EddShrT5N16D9 , & + EddShrT5N17D1 , EddShrT5N17D2 , EddShrT5N17D3 , EddShrT5N17D4 , EddShrT5N17D5 , EddShrT5N17D6 , & + EddShrT5N17D7 , EddShrT5N17D8 , EddShrT5N17D9 , EddShrT5N18D1 , EddShrT5N18D2 , EddShrT5N18D3 , & + EddShrT5N18D4 , EddShrT5N18D5 , EddShrT5N18D6 , EddShrT5N18D7 , EddShrT5N18D8 , EddShrT5N18D9 , & + EddShrT5N19D1 , EddShrT5N19D2 , EddShrT5N19D3 , EddShrT5N19D4 , EddShrT5N19D5 , EddShrT5N19D6 , & + EddShrT5N19D7 , EddShrT5N19D8 , EddShrT5N19D9 , EddShrT5N20D1 , EddShrT5N20D2 , EddShrT5N20D3 /) + INTEGER(IntKi), PARAMETER :: ParamIndxAry3(1356) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + EddShrT5N20D4 , EddShrT5N20D5 , EddShrT5N20D6 , EddShrT5N20D7 , EddShrT5N20D8 , EddShrT5N20D9 , & + EddShrT6N01D1 , EddShrT6N01D2 , EddShrT6N01D3 , EddShrT6N01D4 , EddShrT6N01D5 , EddShrT6N01D6 , & + EddShrT6N01D7 , EddShrT6N01D8 , EddShrT6N01D9 , EddShrT6N02D1 , EddShrT6N02D2 , EddShrT6N02D3 , & + EddShrT6N02D4 , EddShrT6N02D5 , EddShrT6N02D6 , EddShrT6N02D7 , EddShrT6N02D8 , EddShrT6N02D9 , & + EddShrT6N03D1 , EddShrT6N03D2 , EddShrT6N03D3 , EddShrT6N03D4 , EddShrT6N03D5 , EddShrT6N03D6 , & + EddShrT6N03D7 , EddShrT6N03D8 , EddShrT6N03D9 , EddShrT6N04D1 , EddShrT6N04D2 , EddShrT6N04D3 , & + EddShrT6N04D4 , EddShrT6N04D5 , EddShrT6N04D6 , EddShrT6N04D7 , EddShrT6N04D8 , EddShrT6N04D9 , & + EddShrT6N05D1 , EddShrT6N05D2 , EddShrT6N05D3 , EddShrT6N05D4 , EddShrT6N05D5 , EddShrT6N05D6 , & + EddShrT6N05D7 , EddShrT6N05D8 , EddShrT6N05D9 , EddShrT6N06D1 , EddShrT6N06D2 , EddShrT6N06D3 , & + EddShrT6N06D4 , EddShrT6N06D5 , EddShrT6N06D6 , EddShrT6N06D7 , EddShrT6N06D8 , EddShrT6N06D9 , & + EddShrT6N07D1 , EddShrT6N07D2 , EddShrT6N07D3 , EddShrT6N07D4 , EddShrT6N07D5 , EddShrT6N07D6 , & + EddShrT6N07D7 , EddShrT6N07D8 , EddShrT6N07D9 , EddShrT6N08D1 , EddShrT6N08D2 , EddShrT6N08D3 , & + EddShrT6N08D4 , EddShrT6N08D5 , EddShrT6N08D6 , EddShrT6N08D7 , EddShrT6N08D8 , EddShrT6N08D9 , & + EddShrT6N09D1 , EddShrT6N09D2 , EddShrT6N09D3 , EddShrT6N09D4 , EddShrT6N09D5 , EddShrT6N09D6 , & + EddShrT6N09D7 , EddShrT6N09D8 , EddShrT6N09D9 , EddShrT6N10D1 , EddShrT6N10D2 , EddShrT6N10D3 , & + EddShrT6N10D4 , EddShrT6N10D5 , EddShrT6N10D6 , EddShrT6N10D7 , EddShrT6N10D8 , EddShrT6N10D9 , & + EddShrT6N11D1 , EddShrT6N11D2 , EddShrT6N11D3 , EddShrT6N11D4 , EddShrT6N11D5 , EddShrT6N11D6 , & + EddShrT6N11D7 , EddShrT6N11D8 , EddShrT6N11D9 , EddShrT6N12D1 , EddShrT6N12D2 , EddShrT6N12D3 , & + EddShrT6N12D4 , EddShrT6N12D5 , EddShrT6N12D6 , EddShrT6N12D7 , EddShrT6N12D8 , EddShrT6N12D9 , & + EddShrT6N13D1 , EddShrT6N13D2 , EddShrT6N13D3 , EddShrT6N13D4 , EddShrT6N13D5 , EddShrT6N13D6 , & + EddShrT6N13D7 , EddShrT6N13D8 , EddShrT6N13D9 , EddShrT6N14D1 , EddShrT6N14D2 , EddShrT6N14D3 , & + EddShrT6N14D4 , EddShrT6N14D5 , EddShrT6N14D6 , EddShrT6N14D7 , EddShrT6N14D8 , EddShrT6N14D9 , & + EddShrT6N15D1 , EddShrT6N15D2 , EddShrT6N15D3 , EddShrT6N15D4 , EddShrT6N15D5 , EddShrT6N15D6 , & + EddShrT6N15D7 , EddShrT6N15D8 , EddShrT6N15D9 , EddShrT6N16D1 , EddShrT6N16D2 , EddShrT6N16D3 , & + EddShrT6N16D4 , EddShrT6N16D5 , EddShrT6N16D6 , EddShrT6N16D7 , EddShrT6N16D8 , EddShrT6N16D9 , & + EddShrT6N17D1 , EddShrT6N17D2 , EddShrT6N17D3 , EddShrT6N17D4 , EddShrT6N17D5 , EddShrT6N17D6 , & + EddShrT6N17D7 , EddShrT6N17D8 , EddShrT6N17D9 , EddShrT6N18D1 , EddShrT6N18D2 , EddShrT6N18D3 , & + EddShrT6N18D4 , EddShrT6N18D5 , EddShrT6N18D6 , EddShrT6N18D7 , EddShrT6N18D8 , EddShrT6N18D9 , & + EddShrT6N19D1 , EddShrT6N19D2 , EddShrT6N19D3 , EddShrT6N19D4 , EddShrT6N19D5 , EddShrT6N19D6 , & + EddShrT6N19D7 , EddShrT6N19D8 , EddShrT6N19D9 , EddShrT6N20D1 , EddShrT6N20D2 , EddShrT6N20D3 , & + EddShrT6N20D4 , EddShrT6N20D5 , EddShrT6N20D6 , EddShrT6N20D7 , EddShrT6N20D8 , EddShrT6N20D9 , & + EddShrT7N01D1 , EddShrT7N01D2 , EddShrT7N01D3 , EddShrT7N01D4 , EddShrT7N01D5 , EddShrT7N01D6 , & + EddShrT7N01D7 , EddShrT7N01D8 , EddShrT7N01D9 , EddShrT7N02D1 , EddShrT7N02D2 , EddShrT7N02D3 , & + EddShrT7N02D4 , EddShrT7N02D5 , EddShrT7N02D6 , EddShrT7N02D7 , EddShrT7N02D8 , EddShrT7N02D9 , & + EddShrT7N03D1 , EddShrT7N03D2 , EddShrT7N03D3 , EddShrT7N03D4 , EddShrT7N03D5 , EddShrT7N03D6 , & + EddShrT7N03D7 , EddShrT7N03D8 , EddShrT7N03D9 , EddShrT7N04D1 , EddShrT7N04D2 , EddShrT7N04D3 , & + EddShrT7N04D4 , EddShrT7N04D5 , EddShrT7N04D6 , EddShrT7N04D7 , EddShrT7N04D8 , EddShrT7N04D9 , & + EddShrT7N05D1 , EddShrT7N05D2 , EddShrT7N05D3 , EddShrT7N05D4 , EddShrT7N05D5 , EddShrT7N05D6 , & + EddShrT7N05D7 , EddShrT7N05D8 , EddShrT7N05D9 , EddShrT7N06D1 , EddShrT7N06D2 , EddShrT7N06D3 , & + EddShrT7N06D4 , EddShrT7N06D5 , EddShrT7N06D6 , EddShrT7N06D7 , EddShrT7N06D8 , EddShrT7N06D9 , & + EddShrT7N07D1 , EddShrT7N07D2 , EddShrT7N07D3 , EddShrT7N07D4 , EddShrT7N07D5 , EddShrT7N07D6 , & + EddShrT7N07D7 , EddShrT7N07D8 , EddShrT7N07D9 , EddShrT7N08D1 , EddShrT7N08D2 , EddShrT7N08D3 , & + EddShrT7N08D4 , EddShrT7N08D5 , EddShrT7N08D6 , EddShrT7N08D7 , EddShrT7N08D8 , EddShrT7N08D9 , & + EddShrT7N09D1 , EddShrT7N09D2 , EddShrT7N09D3 , EddShrT7N09D4 , EddShrT7N09D5 , EddShrT7N09D6 , & + EddShrT7N09D7 , EddShrT7N09D8 , EddShrT7N09D9 , EddShrT7N10D1 , EddShrT7N10D2 , EddShrT7N10D3 , & + EddShrT7N10D4 , EddShrT7N10D5 , EddShrT7N10D6 , EddShrT7N10D7 , EddShrT7N10D8 , EddShrT7N10D9 , & + EddShrT7N11D1 , EddShrT7N11D2 , EddShrT7N11D3 , EddShrT7N11D4 , EddShrT7N11D5 , EddShrT7N11D6 , & + EddShrT7N11D7 , EddShrT7N11D8 , EddShrT7N11D9 , EddShrT7N12D1 , EddShrT7N12D2 , EddShrT7N12D3 , & + EddShrT7N12D4 , EddShrT7N12D5 , EddShrT7N12D6 , EddShrT7N12D7 , EddShrT7N12D8 , EddShrT7N12D9 , & + EddShrT7N13D1 , EddShrT7N13D2 , EddShrT7N13D3 , EddShrT7N13D4 , EddShrT7N13D5 , EddShrT7N13D6 , & + EddShrT7N13D7 , EddShrT7N13D8 , EddShrT7N13D9 , EddShrT7N14D1 , EddShrT7N14D2 , EddShrT7N14D3 , & + EddShrT7N14D4 , EddShrT7N14D5 , EddShrT7N14D6 , EddShrT7N14D7 , EddShrT7N14D8 , EddShrT7N14D9 , & + EddShrT7N15D1 , EddShrT7N15D2 , EddShrT7N15D3 , EddShrT7N15D4 , EddShrT7N15D5 , EddShrT7N15D6 , & + EddShrT7N15D7 , EddShrT7N15D8 , EddShrT7N15D9 , EddShrT7N16D1 , EddShrT7N16D2 , EddShrT7N16D3 , & + EddShrT7N16D4 , EddShrT7N16D5 , EddShrT7N16D6 , EddShrT7N16D7 , EddShrT7N16D8 , EddShrT7N16D9 , & + EddShrT7N17D1 , EddShrT7N17D2 , EddShrT7N17D3 , EddShrT7N17D4 , EddShrT7N17D5 , EddShrT7N17D6 , & + EddShrT7N17D7 , EddShrT7N17D8 , EddShrT7N17D9 , EddShrT7N18D1 , EddShrT7N18D2 , EddShrT7N18D3 , & + EddShrT7N18D4 , EddShrT7N18D5 , EddShrT7N18D6 , EddShrT7N18D7 , EddShrT7N18D8 , EddShrT7N18D9 , & + EddShrT7N19D1 , EddShrT7N19D2 , EddShrT7N19D3 , EddShrT7N19D4 , EddShrT7N19D5 , EddShrT7N19D6 , & + EddShrT7N19D7 , EddShrT7N19D8 , EddShrT7N19D9 , EddShrT7N20D1 , EddShrT7N20D2 , EddShrT7N20D3 , & + EddShrT7N20D4 , EddShrT7N20D5 , EddShrT7N20D6 , EddShrT7N20D7 , EddShrT7N20D8 , EddShrT7N20D9 , & + EddShrT8N01D1 , EddShrT8N01D2 , EddShrT8N01D3 , EddShrT8N01D4 , EddShrT8N01D5 , EddShrT8N01D6 , & + EddShrT8N01D7 , EddShrT8N01D8 , EddShrT8N01D9 , EddShrT8N02D1 , EddShrT8N02D2 , EddShrT8N02D3 , & + EddShrT8N02D4 , EddShrT8N02D5 , EddShrT8N02D6 , EddShrT8N02D7 , EddShrT8N02D8 , EddShrT8N02D9 , & + EddShrT8N03D1 , EddShrT8N03D2 , EddShrT8N03D3 , EddShrT8N03D4 , EddShrT8N03D5 , EddShrT8N03D6 , & + EddShrT8N03D7 , EddShrT8N03D8 , EddShrT8N03D9 , EddShrT8N04D1 , EddShrT8N04D2 , EddShrT8N04D3 , & + EddShrT8N04D4 , EddShrT8N04D5 , EddShrT8N04D6 , EddShrT8N04D7 , EddShrT8N04D8 , EddShrT8N04D9 , & + EddShrT8N05D1 , EddShrT8N05D2 , EddShrT8N05D3 , EddShrT8N05D4 , EddShrT8N05D5 , EddShrT8N05D6 , & + EddShrT8N05D7 , EddShrT8N05D8 , EddShrT8N05D9 , EddShrT8N06D1 , EddShrT8N06D2 , EddShrT8N06D3 , & + EddShrT8N06D4 , EddShrT8N06D5 , EddShrT8N06D6 , EddShrT8N06D7 , EddShrT8N06D8 , EddShrT8N06D9 , & + EddShrT8N07D1 , EddShrT8N07D2 , EddShrT8N07D3 , EddShrT8N07D4 , EddShrT8N07D5 , EddShrT8N07D6 , & + EddShrT8N07D7 , EddShrT8N07D8 , EddShrT8N07D9 , EddShrT8N08D1 , EddShrT8N08D2 , EddShrT8N08D3 , & + EddShrT8N08D4 , EddShrT8N08D5 , EddShrT8N08D6 , EddShrT8N08D7 , EddShrT8N08D8 , EddShrT8N08D9 , & + EddShrT8N09D1 , EddShrT8N09D2 , EddShrT8N09D3 , EddShrT8N09D4 , EddShrT8N09D5 , EddShrT8N09D6 , & + EddShrT8N09D7 , EddShrT8N09D8 , EddShrT8N09D9 , EddShrT8N10D1 , EddShrT8N10D2 , EddShrT8N10D3 , & + EddShrT8N10D4 , EddShrT8N10D5 , EddShrT8N10D6 , EddShrT8N10D7 , EddShrT8N10D8 , EddShrT8N10D9 , & + EddShrT8N11D1 , EddShrT8N11D2 , EddShrT8N11D3 , EddShrT8N11D4 , EddShrT8N11D5 , EddShrT8N11D6 , & + EddShrT8N11D7 , EddShrT8N11D8 , EddShrT8N11D9 , EddShrT8N12D1 , EddShrT8N12D2 , EddShrT8N12D3 , & + EddShrT8N12D4 , EddShrT8N12D5 , EddShrT8N12D6 , EddShrT8N12D7 , EddShrT8N12D8 , EddShrT8N12D9 , & + EddShrT8N13D1 , EddShrT8N13D2 , EddShrT8N13D3 , EddShrT8N13D4 , EddShrT8N13D5 , EddShrT8N13D6 , & + EddShrT8N13D7 , EddShrT8N13D8 , EddShrT8N13D9 , EddShrT8N14D1 , EddShrT8N14D2 , EddShrT8N14D3 , & + EddShrT8N14D4 , EddShrT8N14D5 , EddShrT8N14D6 , EddShrT8N14D7 , EddShrT8N14D8 , EddShrT8N14D9 , & + EddShrT8N15D1 , EddShrT8N15D2 , EddShrT8N15D3 , EddShrT8N15D4 , EddShrT8N15D5 , EddShrT8N15D6 , & + EddShrT8N15D7 , EddShrT8N15D8 , EddShrT8N15D9 , EddShrT8N16D1 , EddShrT8N16D2 , EddShrT8N16D3 , & + EddShrT8N16D4 , EddShrT8N16D5 , EddShrT8N16D6 , EddShrT8N16D7 , EddShrT8N16D8 , EddShrT8N16D9 , & + EddShrT8N17D1 , EddShrT8N17D2 , EddShrT8N17D3 , EddShrT8N17D4 , EddShrT8N17D5 , EddShrT8N17D6 , & + EddShrT8N17D7 , EddShrT8N17D8 , EddShrT8N17D9 , EddShrT8N18D1 , EddShrT8N18D2 , EddShrT8N18D3 , & + EddShrT8N18D4 , EddShrT8N18D5 , EddShrT8N18D6 , EddShrT8N18D7 , EddShrT8N18D8 , EddShrT8N18D9 , & + EddShrT8N19D1 , EddShrT8N19D2 , EddShrT8N19D3 , EddShrT8N19D4 , EddShrT8N19D5 , EddShrT8N19D6 , & + EddShrT8N19D7 , EddShrT8N19D8 , EddShrT8N19D9 , EddShrT8N20D1 , EddShrT8N20D2 , EddShrT8N20D3 , & + EddShrT8N20D4 , EddShrT8N20D5 , EddShrT8N20D6 , EddShrT8N20D7 , EddShrT8N20D8 , EddShrT8N20D9 , & + EddShrT9N01D1 , EddShrT9N01D2 , EddShrT9N01D3 , EddShrT9N01D4 , EddShrT9N01D5 , EddShrT9N01D6 , & + EddShrT9N01D7 , EddShrT9N01D8 , EddShrT9N01D9 , EddShrT9N02D1 , EddShrT9N02D2 , EddShrT9N02D3 , & + EddShrT9N02D4 , EddShrT9N02D5 , EddShrT9N02D6 , EddShrT9N02D7 , EddShrT9N02D8 , EddShrT9N02D9 , & + EddShrT9N03D1 , EddShrT9N03D2 , EddShrT9N03D3 , EddShrT9N03D4 , EddShrT9N03D5 , EddShrT9N03D6 , & + EddShrT9N03D7 , EddShrT9N03D8 , EddShrT9N03D9 , EddShrT9N04D1 , EddShrT9N04D2 , EddShrT9N04D3 , & + EddShrT9N04D4 , EddShrT9N04D5 , EddShrT9N04D6 , EddShrT9N04D7 , EddShrT9N04D8 , EddShrT9N04D9 , & + EddShrT9N05D1 , EddShrT9N05D2 , EddShrT9N05D3 , EddShrT9N05D4 , EddShrT9N05D5 , EddShrT9N05D6 , & + EddShrT9N05D7 , EddShrT9N05D8 , EddShrT9N05D9 , EddShrT9N06D1 , EddShrT9N06D2 , EddShrT9N06D3 , & + EddShrT9N06D4 , EddShrT9N06D5 , EddShrT9N06D6 , EddShrT9N06D7 , EddShrT9N06D8 , EddShrT9N06D9 , & + EddShrT9N07D1 , EddShrT9N07D2 , EddShrT9N07D3 , EddShrT9N07D4 , EddShrT9N07D5 , EddShrT9N07D6 , & + EddShrT9N07D7 , EddShrT9N07D8 , EddShrT9N07D9 , EddShrT9N08D1 , EddShrT9N08D2 , EddShrT9N08D3 , & + EddShrT9N08D4 , EddShrT9N08D5 , EddShrT9N08D6 , EddShrT9N08D7 , EddShrT9N08D8 , EddShrT9N08D9 , & + EddShrT9N09D1 , EddShrT9N09D2 , EddShrT9N09D3 , EddShrT9N09D4 , EddShrT9N09D5 , EddShrT9N09D6 , & + EddShrT9N09D7 , EddShrT9N09D8 , EddShrT9N09D9 , EddShrT9N10D1 , EddShrT9N10D2 , EddShrT9N10D3 , & + EddShrT9N10D4 , EddShrT9N10D5 , EddShrT9N10D6 , EddShrT9N10D7 , EddShrT9N10D8 , EddShrT9N10D9 , & + EddShrT9N11D1 , EddShrT9N11D2 , EddShrT9N11D3 , EddShrT9N11D4 , EddShrT9N11D5 , EddShrT9N11D6 , & + EddShrT9N11D7 , EddShrT9N11D8 , EddShrT9N11D9 , EddShrT9N12D1 , EddShrT9N12D2 , EddShrT9N12D3 , & + EddShrT9N12D4 , EddShrT9N12D5 , EddShrT9N12D6 , EddShrT9N12D7 , EddShrT9N12D8 , EddShrT9N12D9 , & + EddShrT9N13D1 , EddShrT9N13D2 , EddShrT9N13D3 , EddShrT9N13D4 , EddShrT9N13D5 , EddShrT9N13D6 , & + EddShrT9N13D7 , EddShrT9N13D8 , EddShrT9N13D9 , EddShrT9N14D1 , EddShrT9N14D2 , EddShrT9N14D3 , & + EddShrT9N14D4 , EddShrT9N14D5 , EddShrT9N14D6 , EddShrT9N14D7 , EddShrT9N14D8 , EddShrT9N14D9 , & + EddShrT9N15D1 , EddShrT9N15D2 , EddShrT9N15D3 , EddShrT9N15D4 , EddShrT9N15D5 , EddShrT9N15D6 , & + EddShrT9N15D7 , EddShrT9N15D8 , EddShrT9N15D9 , EddShrT9N16D1 , EddShrT9N16D2 , EddShrT9N16D3 , & + EddShrT9N16D4 , EddShrT9N16D5 , EddShrT9N16D6 , EddShrT9N16D7 , EddShrT9N16D8 , EddShrT9N16D9 , & + EddShrT9N17D1 , EddShrT9N17D2 , EddShrT9N17D3 , EddShrT9N17D4 , EddShrT9N17D5 , EddShrT9N17D6 , & + EddShrT9N17D7 , EddShrT9N17D8 , EddShrT9N17D9 , EddShrT9N18D1 , EddShrT9N18D2 , EddShrT9N18D3 , & + EddShrT9N18D4 , EddShrT9N18D5 , EddShrT9N18D6 , EddShrT9N18D7 , EddShrT9N18D8 , EddShrT9N18D9 , & + EddShrT9N19D1 , EddShrT9N19D2 , EddShrT9N19D3 , EddShrT9N19D4 , EddShrT9N19D5 , EddShrT9N19D6 , & + EddShrT9N19D7 , EddShrT9N19D8 , EddShrT9N19D9 , EddShrT9N20D1 , EddShrT9N20D2 , EddShrT9N20D3 , & + EddShrT9N20D4 , EddShrT9N20D5 , EddShrT9N20D6 , EddShrT9N20D7 , EddShrT9N20D8 , EddShrT9N20D9 , & + EddVisT1N01D1 , EddVisT1N01D2 , EddVisT1N01D3 , EddVisT1N01D4 , EddVisT1N01D5 , EddVisT1N01D6 , & + EddVisT1N01D7 , EddVisT1N01D8 , EddVisT1N01D9 , EddVisT1N02D1 , EddVisT1N02D2 , EddVisT1N02D3 , & + EddVisT1N02D4 , EddVisT1N02D5 , EddVisT1N02D6 , EddVisT1N02D7 , EddVisT1N02D8 , EddVisT1N02D9 , & + EddVisT1N03D1 , EddVisT1N03D2 , EddVisT1N03D3 , EddVisT1N03D4 , EddVisT1N03D5 , EddVisT1N03D6 , & + EddVisT1N03D7 , EddVisT1N03D8 , EddVisT1N03D9 , EddVisT1N04D1 , EddVisT1N04D2 , EddVisT1N04D3 , & + EddVisT1N04D4 , EddVisT1N04D5 , EddVisT1N04D6 , EddVisT1N04D7 , EddVisT1N04D8 , EddVisT1N04D9 , & + EddVisT1N05D1 , EddVisT1N05D2 , EddVisT1N05D3 , EddVisT1N05D4 , EddVisT1N05D5 , EddVisT1N05D6 , & + EddVisT1N05D7 , EddVisT1N05D8 , EddVisT1N05D9 , EddVisT1N06D1 , EddVisT1N06D2 , EddVisT1N06D3 , & + EddVisT1N06D4 , EddVisT1N06D5 , EddVisT1N06D6 , EddVisT1N06D7 , EddVisT1N06D8 , EddVisT1N06D9 , & + EddVisT1N07D1 , EddVisT1N07D2 , EddVisT1N07D3 , EddVisT1N07D4 , EddVisT1N07D5 , EddVisT1N07D6 , & + EddVisT1N07D7 , EddVisT1N07D8 , EddVisT1N07D9 , EddVisT1N08D1 , EddVisT1N08D2 , EddVisT1N08D3 , & + EddVisT1N08D4 , EddVisT1N08D5 , EddVisT1N08D6 , EddVisT1N08D7 , EddVisT1N08D8 , EddVisT1N08D9 , & + EddVisT1N09D1 , EddVisT1N09D2 , EddVisT1N09D3 , EddVisT1N09D4 , EddVisT1N09D5 , EddVisT1N09D6 , & + EddVisT1N09D7 , EddVisT1N09D8 , EddVisT1N09D9 , EddVisT1N10D1 , EddVisT1N10D2 , EddVisT1N10D3 , & + EddVisT1N10D4 , EddVisT1N10D5 , EddVisT1N10D6 , EddVisT1N10D7 , EddVisT1N10D8 , EddVisT1N10D9 , & + EddVisT1N11D1 , EddVisT1N11D2 , EddVisT1N11D3 , EddVisT1N11D4 , EddVisT1N11D5 , EddVisT1N11D6 , & + EddVisT1N11D7 , EddVisT1N11D8 , EddVisT1N11D9 , EddVisT1N12D1 , EddVisT1N12D2 , EddVisT1N12D3 , & + EddVisT1N12D4 , EddVisT1N12D5 , EddVisT1N12D6 , EddVisT1N12D7 , EddVisT1N12D8 , EddVisT1N12D9 , & + EddVisT1N13D1 , EddVisT1N13D2 , EddVisT1N13D3 , EddVisT1N13D4 , EddVisT1N13D5 , EddVisT1N13D6 , & + EddVisT1N13D7 , EddVisT1N13D8 , EddVisT1N13D9 , EddVisT1N14D1 , EddVisT1N14D2 , EddVisT1N14D3 , & + EddVisT1N14D4 , EddVisT1N14D5 , EddVisT1N14D6 , EddVisT1N14D7 , EddVisT1N14D8 , EddVisT1N14D9 , & + EddVisT1N15D1 , EddVisT1N15D2 , EddVisT1N15D3 , EddVisT1N15D4 , EddVisT1N15D5 , EddVisT1N15D6 , & + EddVisT1N15D7 , EddVisT1N15D8 , EddVisT1N15D9 , EddVisT1N16D1 , EddVisT1N16D2 , EddVisT1N16D3 , & + EddVisT1N16D4 , EddVisT1N16D5 , EddVisT1N16D6 , EddVisT1N16D7 , EddVisT1N16D8 , EddVisT1N16D9 , & + EddVisT1N17D1 , EddVisT1N17D2 , EddVisT1N17D3 , EddVisT1N17D4 , EddVisT1N17D5 , EddVisT1N17D6 , & + EddVisT1N17D7 , EddVisT1N17D8 , EddVisT1N17D9 , EddVisT1N18D1 , EddVisT1N18D2 , EddVisT1N18D3 , & + EddVisT1N18D4 , EddVisT1N18D5 , EddVisT1N18D6 , EddVisT1N18D7 , EddVisT1N18D8 , EddVisT1N18D9 , & + EddVisT1N19D1 , EddVisT1N19D2 , EddVisT1N19D3 , EddVisT1N19D4 , EddVisT1N19D5 , EddVisT1N19D6 , & + EddVisT1N19D7 , EddVisT1N19D8 , EddVisT1N19D9 , EddVisT1N20D1 , EddVisT1N20D2 , EddVisT1N20D3 , & + EddVisT1N20D4 , EddVisT1N20D5 , EddVisT1N20D6 , EddVisT1N20D7 , EddVisT1N20D8 , EddVisT1N20D9 , & + EddVisT2N01D1 , EddVisT2N01D2 , EddVisT2N01D3 , EddVisT2N01D4 , EddVisT2N01D5 , EddVisT2N01D6 , & + EddVisT2N01D7 , EddVisT2N01D8 , EddVisT2N01D9 , EddVisT2N02D1 , EddVisT2N02D2 , EddVisT2N02D3 , & + EddVisT2N02D4 , EddVisT2N02D5 , EddVisT2N02D6 , EddVisT2N02D7 , EddVisT2N02D8 , EddVisT2N02D9 , & + EddVisT2N03D1 , EddVisT2N03D2 , EddVisT2N03D3 , EddVisT2N03D4 , EddVisT2N03D5 , EddVisT2N03D6 , & + EddVisT2N03D7 , EddVisT2N03D8 , EddVisT2N03D9 , EddVisT2N04D1 , EddVisT2N04D2 , EddVisT2N04D3 , & + EddVisT2N04D4 , EddVisT2N04D5 , EddVisT2N04D6 , EddVisT2N04D7 , EddVisT2N04D8 , EddVisT2N04D9 , & + EddVisT2N05D1 , EddVisT2N05D2 , EddVisT2N05D3 , EddVisT2N05D4 , EddVisT2N05D5 , EddVisT2N05D6 , & + EddVisT2N05D7 , EddVisT2N05D8 , EddVisT2N05D9 , EddVisT2N06D1 , EddVisT2N06D2 , EddVisT2N06D3 , & + EddVisT2N06D4 , EddVisT2N06D5 , EddVisT2N06D6 , EddVisT2N06D7 , EddVisT2N06D8 , EddVisT2N06D9 , & + EddVisT2N07D1 , EddVisT2N07D2 , EddVisT2N07D3 , EddVisT2N07D4 , EddVisT2N07D5 , EddVisT2N07D6 , & + EddVisT2N07D7 , EddVisT2N07D8 , EddVisT2N07D9 , EddVisT2N08D1 , EddVisT2N08D2 , EddVisT2N08D3 , & + EddVisT2N08D4 , EddVisT2N08D5 , EddVisT2N08D6 , EddVisT2N08D7 , EddVisT2N08D8 , EddVisT2N08D9 , & + EddVisT2N09D1 , EddVisT2N09D2 , EddVisT2N09D3 , EddVisT2N09D4 , EddVisT2N09D5 , EddVisT2N09D6 , & + EddVisT2N09D7 , EddVisT2N09D8 , EddVisT2N09D9 , EddVisT2N10D1 , EddVisT2N10D2 , EddVisT2N10D3 , & + EddVisT2N10D4 , EddVisT2N10D5 , EddVisT2N10D6 , EddVisT2N10D7 , EddVisT2N10D8 , EddVisT2N10D9 , & + EddVisT2N11D1 , EddVisT2N11D2 , EddVisT2N11D3 , EddVisT2N11D4 , EddVisT2N11D5 , EddVisT2N11D6 , & + EddVisT2N11D7 , EddVisT2N11D8 , EddVisT2N11D9 , EddVisT2N12D1 , EddVisT2N12D2 , EddVisT2N12D3 , & + EddVisT2N12D4 , EddVisT2N12D5 , EddVisT2N12D6 , EddVisT2N12D7 , EddVisT2N12D8 , EddVisT2N12D9 , & + EddVisT2N13D1 , EddVisT2N13D2 , EddVisT2N13D3 , EddVisT2N13D4 , EddVisT2N13D5 , EddVisT2N13D6 , & + EddVisT2N13D7 , EddVisT2N13D8 , EddVisT2N13D9 , EddVisT2N14D1 , EddVisT2N14D2 , EddVisT2N14D3 , & + EddVisT2N14D4 , EddVisT2N14D5 , EddVisT2N14D6 , EddVisT2N14D7 , EddVisT2N14D8 , EddVisT2N14D9 , & + EddVisT2N15D1 , EddVisT2N15D2 , EddVisT2N15D3 , EddVisT2N15D4 , EddVisT2N15D5 , EddVisT2N15D6 , & + EddVisT2N15D7 , EddVisT2N15D8 , EddVisT2N15D9 , EddVisT2N16D1 , EddVisT2N16D2 , EddVisT2N16D3 , & + EddVisT2N16D4 , EddVisT2N16D5 , EddVisT2N16D6 , EddVisT2N16D7 , EddVisT2N16D8 , EddVisT2N16D9 , & + EddVisT2N17D1 , EddVisT2N17D2 , EddVisT2N17D3 , EddVisT2N17D4 , EddVisT2N17D5 , EddVisT2N17D6 , & + EddVisT2N17D7 , EddVisT2N17D8 , EddVisT2N17D9 , EddVisT2N18D1 , EddVisT2N18D2 , EddVisT2N18D3 , & + EddVisT2N18D4 , EddVisT2N18D5 , EddVisT2N18D6 , EddVisT2N18D7 , EddVisT2N18D8 , EddVisT2N18D9 , & + EddVisT2N19D1 , EddVisT2N19D2 , EddVisT2N19D3 , EddVisT2N19D4 , EddVisT2N19D5 , EddVisT2N19D6 , & + EddVisT2N19D7 , EddVisT2N19D8 , EddVisT2N19D9 , EddVisT2N20D1 , EddVisT2N20D2 , EddVisT2N20D3 , & + EddVisT2N20D4 , EddVisT2N20D5 , EddVisT2N20D6 , EddVisT2N20D7 , EddVisT2N20D8 , EddVisT2N20D9 , & + EddVisT3N01D1 , EddVisT3N01D2 , EddVisT3N01D3 , EddVisT3N01D4 , EddVisT3N01D5 , EddVisT3N01D6 , & + EddVisT3N01D7 , EddVisT3N01D8 , EddVisT3N01D9 , EddVisT3N02D1 , EddVisT3N02D2 , EddVisT3N02D3 , & + EddVisT3N02D4 , EddVisT3N02D5 , EddVisT3N02D6 , EddVisT3N02D7 , EddVisT3N02D8 , EddVisT3N02D9 , & + EddVisT3N03D1 , EddVisT3N03D2 , EddVisT3N03D3 , EddVisT3N03D4 , EddVisT3N03D5 , EddVisT3N03D6 , & + EddVisT3N03D7 , EddVisT3N03D8 , EddVisT3N03D9 , EddVisT3N04D1 , EddVisT3N04D2 , EddVisT3N04D3 , & + EddVisT3N04D4 , EddVisT3N04D5 , EddVisT3N04D6 , EddVisT3N04D7 , EddVisT3N04D8 , EddVisT3N04D9 , & + EddVisT3N05D1 , EddVisT3N05D2 , EddVisT3N05D3 , EddVisT3N05D4 , EddVisT3N05D5 , EddVisT3N05D6 , & + EddVisT3N05D7 , EddVisT3N05D8 , EddVisT3N05D9 , EddVisT3N06D1 , EddVisT3N06D2 , EddVisT3N06D3 , & + EddVisT3N06D4 , EddVisT3N06D5 , EddVisT3N06D6 , EddVisT3N06D7 , EddVisT3N06D8 , EddVisT3N06D9 , & + EddVisT3N07D1 , EddVisT3N07D2 , EddVisT3N07D3 , EddVisT3N07D4 , EddVisT3N07D5 , EddVisT3N07D6 , & + EddVisT3N07D7 , EddVisT3N07D8 , EddVisT3N07D9 , EddVisT3N08D1 , EddVisT3N08D2 , EddVisT3N08D3 , & + EddVisT3N08D4 , EddVisT3N08D5 , EddVisT3N08D6 , EddVisT3N08D7 , EddVisT3N08D8 , EddVisT3N08D9 , & + EddVisT3N09D1 , EddVisT3N09D2 , EddVisT3N09D3 , EddVisT3N09D4 , EddVisT3N09D5 , EddVisT3N09D6 , & + EddVisT3N09D7 , EddVisT3N09D8 , EddVisT3N09D9 , EddVisT3N10D1 , EddVisT3N10D2 , EddVisT3N10D3 , & + EddVisT3N10D4 , EddVisT3N10D5 , EddVisT3N10D6 , EddVisT3N10D7 , EddVisT3N10D8 , EddVisT3N10D9 , & + EddVisT3N11D1 , EddVisT3N11D2 , EddVisT3N11D3 , EddVisT3N11D4 , EddVisT3N11D5 , EddVisT3N11D6 , & + EddVisT3N11D7 , EddVisT3N11D8 , EddVisT3N11D9 , EddVisT3N12D1 , EddVisT3N12D2 , EddVisT3N12D3 , & + EddVisT3N12D4 , EddVisT3N12D5 , EddVisT3N12D6 , EddVisT3N12D7 , EddVisT3N12D8 , EddVisT3N12D9 , & + EddVisT3N13D1 , EddVisT3N13D2 , EddVisT3N13D3 , EddVisT3N13D4 , EddVisT3N13D5 , EddVisT3N13D6 , & + EddVisT3N13D7 , EddVisT3N13D8 , EddVisT3N13D9 , EddVisT3N14D1 , EddVisT3N14D2 , EddVisT3N14D3 , & + EddVisT3N14D4 , EddVisT3N14D5 , EddVisT3N14D6 , EddVisT3N14D7 , EddVisT3N14D8 , EddVisT3N14D9 , & + EddVisT3N15D1 , EddVisT3N15D2 , EddVisT3N15D3 , EddVisT3N15D4 , EddVisT3N15D5 , EddVisT3N15D6 , & + EddVisT3N15D7 , EddVisT3N15D8 , EddVisT3N15D9 , EddVisT3N16D1 , EddVisT3N16D2 , EddVisT3N16D3 , & + EddVisT3N16D4 , EddVisT3N16D5 , EddVisT3N16D6 , EddVisT3N16D7 , EddVisT3N16D8 , EddVisT3N16D9 , & + EddVisT3N17D1 , EddVisT3N17D2 , EddVisT3N17D3 , EddVisT3N17D4 , EddVisT3N17D5 , EddVisT3N17D6 , & + EddVisT3N17D7 , EddVisT3N17D8 , EddVisT3N17D9 , EddVisT3N18D1 , EddVisT3N18D2 , EddVisT3N18D3 , & + EddVisT3N18D4 , EddVisT3N18D5 , EddVisT3N18D6 , EddVisT3N18D7 , EddVisT3N18D8 , EddVisT3N18D9 , & + EddVisT3N19D1 , EddVisT3N19D2 , EddVisT3N19D3 , EddVisT3N19D4 , EddVisT3N19D5 , EddVisT3N19D6 , & + EddVisT3N19D7 , EddVisT3N19D8 , EddVisT3N19D9 , EddVisT3N20D1 , EddVisT3N20D2 , EddVisT3N20D3 , & + EddVisT3N20D4 , EddVisT3N20D5 , EddVisT3N20D6 , EddVisT3N20D7 , EddVisT3N20D8 , EddVisT3N20D9 , & + EddVisT4N01D1 , EddVisT4N01D2 , EddVisT4N01D3 , EddVisT4N01D4 , EddVisT4N01D5 , EddVisT4N01D6 , & + EddVisT4N01D7 , EddVisT4N01D8 , EddVisT4N01D9 , EddVisT4N02D1 , EddVisT4N02D2 , EddVisT4N02D3 , & + EddVisT4N02D4 , EddVisT4N02D5 , EddVisT4N02D6 , EddVisT4N02D7 , EddVisT4N02D8 , EddVisT4N02D9 , & + EddVisT4N03D1 , EddVisT4N03D2 , EddVisT4N03D3 , EddVisT4N03D4 , EddVisT4N03D5 , EddVisT4N03D6 , & + EddVisT4N03D7 , EddVisT4N03D8 , EddVisT4N03D9 , EddVisT4N04D1 , EddVisT4N04D2 , EddVisT4N04D3 , & + EddVisT4N04D4 , EddVisT4N04D5 , EddVisT4N04D6 , EddVisT4N04D7 , EddVisT4N04D8 , EddVisT4N04D9 , & + EddVisT4N05D1 , EddVisT4N05D2 , EddVisT4N05D3 , EddVisT4N05D4 , EddVisT4N05D5 , EddVisT4N05D6 , & + EddVisT4N05D7 , EddVisT4N05D8 , EddVisT4N05D9 , EddVisT4N06D1 , EddVisT4N06D2 , EddVisT4N06D3 , & + EddVisT4N06D4 , EddVisT4N06D5 , EddVisT4N06D6 , EddVisT4N06D7 , EddVisT4N06D8 , EddVisT4N06D9 , & + EddVisT4N07D1 , EddVisT4N07D2 , EddVisT4N07D3 , EddVisT4N07D4 , EddVisT4N07D5 , EddVisT4N07D6 , & + EddVisT4N07D7 , EddVisT4N07D8 , EddVisT4N07D9 , EddVisT4N08D1 , EddVisT4N08D2 , EddVisT4N08D3 , & + EddVisT4N08D4 , EddVisT4N08D5 , EddVisT4N08D6 , EddVisT4N08D7 , EddVisT4N08D8 , EddVisT4N08D9 , & + EddVisT4N09D1 , EddVisT4N09D2 , EddVisT4N09D3 , EddVisT4N09D4 , EddVisT4N09D5 , EddVisT4N09D6 , & + EddVisT4N09D7 , EddVisT4N09D8 , EddVisT4N09D9 , EddVisT4N10D1 , EddVisT4N10D2 , EddVisT4N10D3 , & + EddVisT4N10D4 , EddVisT4N10D5 , EddVisT4N10D6 , EddVisT4N10D7 , EddVisT4N10D8 , EddVisT4N10D9 /) + INTEGER(IntKi), PARAMETER :: ParamIndxAry4(1356) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + EddVisT4N11D1 , EddVisT4N11D2 , EddVisT4N11D3 , EddVisT4N11D4 , EddVisT4N11D5 , EddVisT4N11D6 , & + EddVisT4N11D7 , EddVisT4N11D8 , EddVisT4N11D9 , EddVisT4N12D1 , EddVisT4N12D2 , EddVisT4N12D3 , & + EddVisT4N12D4 , EddVisT4N12D5 , EddVisT4N12D6 , EddVisT4N12D7 , EddVisT4N12D8 , EddVisT4N12D9 , & + EddVisT4N13D1 , EddVisT4N13D2 , EddVisT4N13D3 , EddVisT4N13D4 , EddVisT4N13D5 , EddVisT4N13D6 , & + EddVisT4N13D7 , EddVisT4N13D8 , EddVisT4N13D9 , EddVisT4N14D1 , EddVisT4N14D2 , EddVisT4N14D3 , & + EddVisT4N14D4 , EddVisT4N14D5 , EddVisT4N14D6 , EddVisT4N14D7 , EddVisT4N14D8 , EddVisT4N14D9 , & + EddVisT4N15D1 , EddVisT4N15D2 , EddVisT4N15D3 , EddVisT4N15D4 , EddVisT4N15D5 , EddVisT4N15D6 , & + EddVisT4N15D7 , EddVisT4N15D8 , EddVisT4N15D9 , EddVisT4N16D1 , EddVisT4N16D2 , EddVisT4N16D3 , & + EddVisT4N16D4 , EddVisT4N16D5 , EddVisT4N16D6 , EddVisT4N16D7 , EddVisT4N16D8 , EddVisT4N16D9 , & + EddVisT4N17D1 , EddVisT4N17D2 , EddVisT4N17D3 , EddVisT4N17D4 , EddVisT4N17D5 , EddVisT4N17D6 , & + EddVisT4N17D7 , EddVisT4N17D8 , EddVisT4N17D9 , EddVisT4N18D1 , EddVisT4N18D2 , EddVisT4N18D3 , & + EddVisT4N18D4 , EddVisT4N18D5 , EddVisT4N18D6 , EddVisT4N18D7 , EddVisT4N18D8 , EddVisT4N18D9 , & + EddVisT4N19D1 , EddVisT4N19D2 , EddVisT4N19D3 , EddVisT4N19D4 , EddVisT4N19D5 , EddVisT4N19D6 , & + EddVisT4N19D7 , EddVisT4N19D8 , EddVisT4N19D9 , EddVisT4N20D1 , EddVisT4N20D2 , EddVisT4N20D3 , & + EddVisT4N20D4 , EddVisT4N20D5 , EddVisT4N20D6 , EddVisT4N20D7 , EddVisT4N20D8 , EddVisT4N20D9 , & + EddVisT5N01D1 , EddVisT5N01D2 , EddVisT5N01D3 , EddVisT5N01D4 , EddVisT5N01D5 , EddVisT5N01D6 , & + EddVisT5N01D7 , EddVisT5N01D8 , EddVisT5N01D9 , EddVisT5N02D1 , EddVisT5N02D2 , EddVisT5N02D3 , & + EddVisT5N02D4 , EddVisT5N02D5 , EddVisT5N02D6 , EddVisT5N02D7 , EddVisT5N02D8 , EddVisT5N02D9 , & + EddVisT5N03D1 , EddVisT5N03D2 , EddVisT5N03D3 , EddVisT5N03D4 , EddVisT5N03D5 , EddVisT5N03D6 , & + EddVisT5N03D7 , EddVisT5N03D8 , EddVisT5N03D9 , EddVisT5N04D1 , EddVisT5N04D2 , EddVisT5N04D3 , & + EddVisT5N04D4 , EddVisT5N04D5 , EddVisT5N04D6 , EddVisT5N04D7 , EddVisT5N04D8 , EddVisT5N04D9 , & + EddVisT5N05D1 , EddVisT5N05D2 , EddVisT5N05D3 , EddVisT5N05D4 , EddVisT5N05D5 , EddVisT5N05D6 , & + EddVisT5N05D7 , EddVisT5N05D8 , EddVisT5N05D9 , EddVisT5N06D1 , EddVisT5N06D2 , EddVisT5N06D3 , & + EddVisT5N06D4 , EddVisT5N06D5 , EddVisT5N06D6 , EddVisT5N06D7 , EddVisT5N06D8 , EddVisT5N06D9 , & + EddVisT5N07D1 , EddVisT5N07D2 , EddVisT5N07D3 , EddVisT5N07D4 , EddVisT5N07D5 , EddVisT5N07D6 , & + EddVisT5N07D7 , EddVisT5N07D8 , EddVisT5N07D9 , EddVisT5N08D1 , EddVisT5N08D2 , EddVisT5N08D3 , & + EddVisT5N08D4 , EddVisT5N08D5 , EddVisT5N08D6 , EddVisT5N08D7 , EddVisT5N08D8 , EddVisT5N08D9 , & + EddVisT5N09D1 , EddVisT5N09D2 , EddVisT5N09D3 , EddVisT5N09D4 , EddVisT5N09D5 , EddVisT5N09D6 , & + EddVisT5N09D7 , EddVisT5N09D8 , EddVisT5N09D9 , EddVisT5N10D1 , EddVisT5N10D2 , EddVisT5N10D3 , & + EddVisT5N10D4 , EddVisT5N10D5 , EddVisT5N10D6 , EddVisT5N10D7 , EddVisT5N10D8 , EddVisT5N10D9 , & + EddVisT5N11D1 , EddVisT5N11D2 , EddVisT5N11D3 , EddVisT5N11D4 , EddVisT5N11D5 , EddVisT5N11D6 , & + EddVisT5N11D7 , EddVisT5N11D8 , EddVisT5N11D9 , EddVisT5N12D1 , EddVisT5N12D2 , EddVisT5N12D3 , & + EddVisT5N12D4 , EddVisT5N12D5 , EddVisT5N12D6 , EddVisT5N12D7 , EddVisT5N12D8 , EddVisT5N12D9 , & + EddVisT5N13D1 , EddVisT5N13D2 , EddVisT5N13D3 , EddVisT5N13D4 , EddVisT5N13D5 , EddVisT5N13D6 , & + EddVisT5N13D7 , EddVisT5N13D8 , EddVisT5N13D9 , EddVisT5N14D1 , EddVisT5N14D2 , EddVisT5N14D3 , & + EddVisT5N14D4 , EddVisT5N14D5 , EddVisT5N14D6 , EddVisT5N14D7 , EddVisT5N14D8 , EddVisT5N14D9 , & + EddVisT5N15D1 , EddVisT5N15D2 , EddVisT5N15D3 , EddVisT5N15D4 , EddVisT5N15D5 , EddVisT5N15D6 , & + EddVisT5N15D7 , EddVisT5N15D8 , EddVisT5N15D9 , EddVisT5N16D1 , EddVisT5N16D2 , EddVisT5N16D3 , & + EddVisT5N16D4 , EddVisT5N16D5 , EddVisT5N16D6 , EddVisT5N16D7 , EddVisT5N16D8 , EddVisT5N16D9 , & + EddVisT5N17D1 , EddVisT5N17D2 , EddVisT5N17D3 , EddVisT5N17D4 , EddVisT5N17D5 , EddVisT5N17D6 , & + EddVisT5N17D7 , EddVisT5N17D8 , EddVisT5N17D9 , EddVisT5N18D1 , EddVisT5N18D2 , EddVisT5N18D3 , & + EddVisT5N18D4 , EddVisT5N18D5 , EddVisT5N18D6 , EddVisT5N18D7 , EddVisT5N18D8 , EddVisT5N18D9 , & + EddVisT5N19D1 , EddVisT5N19D2 , EddVisT5N19D3 , EddVisT5N19D4 , EddVisT5N19D5 , EddVisT5N19D6 , & + EddVisT5N19D7 , EddVisT5N19D8 , EddVisT5N19D9 , EddVisT5N20D1 , EddVisT5N20D2 , EddVisT5N20D3 , & + EddVisT5N20D4 , EddVisT5N20D5 , EddVisT5N20D6 , EddVisT5N20D7 , EddVisT5N20D8 , EddVisT5N20D9 , & + EddVisT6N01D1 , EddVisT6N01D2 , EddVisT6N01D3 , EddVisT6N01D4 , EddVisT6N01D5 , EddVisT6N01D6 , & + EddVisT6N01D7 , EddVisT6N01D8 , EddVisT6N01D9 , EddVisT6N02D1 , EddVisT6N02D2 , EddVisT6N02D3 , & + EddVisT6N02D4 , EddVisT6N02D5 , EddVisT6N02D6 , EddVisT6N02D7 , EddVisT6N02D8 , EddVisT6N02D9 , & + EddVisT6N03D1 , EddVisT6N03D2 , EddVisT6N03D3 , EddVisT6N03D4 , EddVisT6N03D5 , EddVisT6N03D6 , & + EddVisT6N03D7 , EddVisT6N03D8 , EddVisT6N03D9 , EddVisT6N04D1 , EddVisT6N04D2 , EddVisT6N04D3 , & + EddVisT6N04D4 , EddVisT6N04D5 , EddVisT6N04D6 , EddVisT6N04D7 , EddVisT6N04D8 , EddVisT6N04D9 , & + EddVisT6N05D1 , EddVisT6N05D2 , EddVisT6N05D3 , EddVisT6N05D4 , EddVisT6N05D5 , EddVisT6N05D6 , & + EddVisT6N05D7 , EddVisT6N05D8 , EddVisT6N05D9 , EddVisT6N06D1 , EddVisT6N06D2 , EddVisT6N06D3 , & + EddVisT6N06D4 , EddVisT6N06D5 , EddVisT6N06D6 , EddVisT6N06D7 , EddVisT6N06D8 , EddVisT6N06D9 , & + EddVisT6N07D1 , EddVisT6N07D2 , EddVisT6N07D3 , EddVisT6N07D4 , EddVisT6N07D5 , EddVisT6N07D6 , & + EddVisT6N07D7 , EddVisT6N07D8 , EddVisT6N07D9 , EddVisT6N08D1 , EddVisT6N08D2 , EddVisT6N08D3 , & + EddVisT6N08D4 , EddVisT6N08D5 , EddVisT6N08D6 , EddVisT6N08D7 , EddVisT6N08D8 , EddVisT6N08D9 , & + EddVisT6N09D1 , EddVisT6N09D2 , EddVisT6N09D3 , EddVisT6N09D4 , EddVisT6N09D5 , EddVisT6N09D6 , & + EddVisT6N09D7 , EddVisT6N09D8 , EddVisT6N09D9 , EddVisT6N10D1 , EddVisT6N10D2 , EddVisT6N10D3 , & + EddVisT6N10D4 , EddVisT6N10D5 , EddVisT6N10D6 , EddVisT6N10D7 , EddVisT6N10D8 , EddVisT6N10D9 , & + EddVisT6N11D1 , EddVisT6N11D2 , EddVisT6N11D3 , EddVisT6N11D4 , EddVisT6N11D5 , EddVisT6N11D6 , & + EddVisT6N11D7 , EddVisT6N11D8 , EddVisT6N11D9 , EddVisT6N12D1 , EddVisT6N12D2 , EddVisT6N12D3 , & + EddVisT6N12D4 , EddVisT6N12D5 , EddVisT6N12D6 , EddVisT6N12D7 , EddVisT6N12D8 , EddVisT6N12D9 , & + EddVisT6N13D1 , EddVisT6N13D2 , EddVisT6N13D3 , EddVisT6N13D4 , EddVisT6N13D5 , EddVisT6N13D6 , & + EddVisT6N13D7 , EddVisT6N13D8 , EddVisT6N13D9 , EddVisT6N14D1 , EddVisT6N14D2 , EddVisT6N14D3 , & + EddVisT6N14D4 , EddVisT6N14D5 , EddVisT6N14D6 , EddVisT6N14D7 , EddVisT6N14D8 , EddVisT6N14D9 , & + EddVisT6N15D1 , EddVisT6N15D2 , EddVisT6N15D3 , EddVisT6N15D4 , EddVisT6N15D5 , EddVisT6N15D6 , & + EddVisT6N15D7 , EddVisT6N15D8 , EddVisT6N15D9 , EddVisT6N16D1 , EddVisT6N16D2 , EddVisT6N16D3 , & + EddVisT6N16D4 , EddVisT6N16D5 , EddVisT6N16D6 , EddVisT6N16D7 , EddVisT6N16D8 , EddVisT6N16D9 , & + EddVisT6N17D1 , EddVisT6N17D2 , EddVisT6N17D3 , EddVisT6N17D4 , EddVisT6N17D5 , EddVisT6N17D6 , & + EddVisT6N17D7 , EddVisT6N17D8 , EddVisT6N17D9 , EddVisT6N18D1 , EddVisT6N18D2 , EddVisT6N18D3 , & + EddVisT6N18D4 , EddVisT6N18D5 , EddVisT6N18D6 , EddVisT6N18D7 , EddVisT6N18D8 , EddVisT6N18D9 , & + EddVisT6N19D1 , EddVisT6N19D2 , EddVisT6N19D3 , EddVisT6N19D4 , EddVisT6N19D5 , EddVisT6N19D6 , & + EddVisT6N19D7 , EddVisT6N19D8 , EddVisT6N19D9 , EddVisT6N20D1 , EddVisT6N20D2 , EddVisT6N20D3 , & + EddVisT6N20D4 , EddVisT6N20D5 , EddVisT6N20D6 , EddVisT6N20D7 , EddVisT6N20D8 , EddVisT6N20D9 , & + EddVisT7N01D1 , EddVisT7N01D2 , EddVisT7N01D3 , EddVisT7N01D4 , EddVisT7N01D5 , EddVisT7N01D6 , & + EddVisT7N01D7 , EddVisT7N01D8 , EddVisT7N01D9 , EddVisT7N02D1 , EddVisT7N02D2 , EddVisT7N02D3 , & + EddVisT7N02D4 , EddVisT7N02D5 , EddVisT7N02D6 , EddVisT7N02D7 , EddVisT7N02D8 , EddVisT7N02D9 , & + EddVisT7N03D1 , EddVisT7N03D2 , EddVisT7N03D3 , EddVisT7N03D4 , EddVisT7N03D5 , EddVisT7N03D6 , & + EddVisT7N03D7 , EddVisT7N03D8 , EddVisT7N03D9 , EddVisT7N04D1 , EddVisT7N04D2 , EddVisT7N04D3 , & + EddVisT7N04D4 , EddVisT7N04D5 , EddVisT7N04D6 , EddVisT7N04D7 , EddVisT7N04D8 , EddVisT7N04D9 , & + EddVisT7N05D1 , EddVisT7N05D2 , EddVisT7N05D3 , EddVisT7N05D4 , EddVisT7N05D5 , EddVisT7N05D6 , & + EddVisT7N05D7 , EddVisT7N05D8 , EddVisT7N05D9 , EddVisT7N06D1 , EddVisT7N06D2 , EddVisT7N06D3 , & + EddVisT7N06D4 , EddVisT7N06D5 , EddVisT7N06D6 , EddVisT7N06D7 , EddVisT7N06D8 , EddVisT7N06D9 , & + EddVisT7N07D1 , EddVisT7N07D2 , EddVisT7N07D3 , EddVisT7N07D4 , EddVisT7N07D5 , EddVisT7N07D6 , & + EddVisT7N07D7 , EddVisT7N07D8 , EddVisT7N07D9 , EddVisT7N08D1 , EddVisT7N08D2 , EddVisT7N08D3 , & + EddVisT7N08D4 , EddVisT7N08D5 , EddVisT7N08D6 , EddVisT7N08D7 , EddVisT7N08D8 , EddVisT7N08D9 , & + EddVisT7N09D1 , EddVisT7N09D2 , EddVisT7N09D3 , EddVisT7N09D4 , EddVisT7N09D5 , EddVisT7N09D6 , & + EddVisT7N09D7 , EddVisT7N09D8 , EddVisT7N09D9 , EddVisT7N10D1 , EddVisT7N10D2 , EddVisT7N10D3 , & + EddVisT7N10D4 , EddVisT7N10D5 , EddVisT7N10D6 , EddVisT7N10D7 , EddVisT7N10D8 , EddVisT7N10D9 , & + EddVisT7N11D1 , EddVisT7N11D2 , EddVisT7N11D3 , EddVisT7N11D4 , EddVisT7N11D5 , EddVisT7N11D6 , & + EddVisT7N11D7 , EddVisT7N11D8 , EddVisT7N11D9 , EddVisT7N12D1 , EddVisT7N12D2 , EddVisT7N12D3 , & + EddVisT7N12D4 , EddVisT7N12D5 , EddVisT7N12D6 , EddVisT7N12D7 , EddVisT7N12D8 , EddVisT7N12D9 , & + EddVisT7N13D1 , EddVisT7N13D2 , EddVisT7N13D3 , EddVisT7N13D4 , EddVisT7N13D5 , EddVisT7N13D6 , & + EddVisT7N13D7 , EddVisT7N13D8 , EddVisT7N13D9 , EddVisT7N14D1 , EddVisT7N14D2 , EddVisT7N14D3 , & + EddVisT7N14D4 , EddVisT7N14D5 , EddVisT7N14D6 , EddVisT7N14D7 , EddVisT7N14D8 , EddVisT7N14D9 , & + EddVisT7N15D1 , EddVisT7N15D2 , EddVisT7N15D3 , EddVisT7N15D4 , EddVisT7N15D5 , EddVisT7N15D6 , & + EddVisT7N15D7 , EddVisT7N15D8 , EddVisT7N15D9 , EddVisT7N16D1 , EddVisT7N16D2 , EddVisT7N16D3 , & + EddVisT7N16D4 , EddVisT7N16D5 , EddVisT7N16D6 , EddVisT7N16D7 , EddVisT7N16D8 , EddVisT7N16D9 , & + EddVisT7N17D1 , EddVisT7N17D2 , EddVisT7N17D3 , EddVisT7N17D4 , EddVisT7N17D5 , EddVisT7N17D6 , & + EddVisT7N17D7 , EddVisT7N17D8 , EddVisT7N17D9 , EddVisT7N18D1 , EddVisT7N18D2 , EddVisT7N18D3 , & + EddVisT7N18D4 , EddVisT7N18D5 , EddVisT7N18D6 , EddVisT7N18D7 , EddVisT7N18D8 , EddVisT7N18D9 , & + EddVisT7N19D1 , EddVisT7N19D2 , EddVisT7N19D3 , EddVisT7N19D4 , EddVisT7N19D5 , EddVisT7N19D6 , & + EddVisT7N19D7 , EddVisT7N19D8 , EddVisT7N19D9 , EddVisT7N20D1 , EddVisT7N20D2 , EddVisT7N20D3 , & + EddVisT7N20D4 , EddVisT7N20D5 , EddVisT7N20D6 , EddVisT7N20D7 , EddVisT7N20D8 , EddVisT7N20D9 , & + EddVisT8N01D1 , EddVisT8N01D2 , EddVisT8N01D3 , EddVisT8N01D4 , EddVisT8N01D5 , EddVisT8N01D6 , & + EddVisT8N01D7 , EddVisT8N01D8 , EddVisT8N01D9 , EddVisT8N02D1 , EddVisT8N02D2 , EddVisT8N02D3 , & + EddVisT8N02D4 , EddVisT8N02D5 , EddVisT8N02D6 , EddVisT8N02D7 , EddVisT8N02D8 , EddVisT8N02D9 , & + EddVisT8N03D1 , EddVisT8N03D2 , EddVisT8N03D3 , EddVisT8N03D4 , EddVisT8N03D5 , EddVisT8N03D6 , & + EddVisT8N03D7 , EddVisT8N03D8 , EddVisT8N03D9 , EddVisT8N04D1 , EddVisT8N04D2 , EddVisT8N04D3 , & + EddVisT8N04D4 , EddVisT8N04D5 , EddVisT8N04D6 , EddVisT8N04D7 , EddVisT8N04D8 , EddVisT8N04D9 , & + EddVisT8N05D1 , EddVisT8N05D2 , EddVisT8N05D3 , EddVisT8N05D4 , EddVisT8N05D5 , EddVisT8N05D6 , & + EddVisT8N05D7 , EddVisT8N05D8 , EddVisT8N05D9 , EddVisT8N06D1 , EddVisT8N06D2 , EddVisT8N06D3 , & + EddVisT8N06D4 , EddVisT8N06D5 , EddVisT8N06D6 , EddVisT8N06D7 , EddVisT8N06D8 , EddVisT8N06D9 , & + EddVisT8N07D1 , EddVisT8N07D2 , EddVisT8N07D3 , EddVisT8N07D4 , EddVisT8N07D5 , EddVisT8N07D6 , & + EddVisT8N07D7 , EddVisT8N07D8 , EddVisT8N07D9 , EddVisT8N08D1 , EddVisT8N08D2 , EddVisT8N08D3 , & + EddVisT8N08D4 , EddVisT8N08D5 , EddVisT8N08D6 , EddVisT8N08D7 , EddVisT8N08D8 , EddVisT8N08D9 , & + EddVisT8N09D1 , EddVisT8N09D2 , EddVisT8N09D3 , EddVisT8N09D4 , EddVisT8N09D5 , EddVisT8N09D6 , & + EddVisT8N09D7 , EddVisT8N09D8 , EddVisT8N09D9 , EddVisT8N10D1 , EddVisT8N10D2 , EddVisT8N10D3 , & + EddVisT8N10D4 , EddVisT8N10D5 , EddVisT8N10D6 , EddVisT8N10D7 , EddVisT8N10D8 , EddVisT8N10D9 , & + EddVisT8N11D1 , EddVisT8N11D2 , EddVisT8N11D3 , EddVisT8N11D4 , EddVisT8N11D5 , EddVisT8N11D6 , & + EddVisT8N11D7 , EddVisT8N11D8 , EddVisT8N11D9 , EddVisT8N12D1 , EddVisT8N12D2 , EddVisT8N12D3 , & + EddVisT8N12D4 , EddVisT8N12D5 , EddVisT8N12D6 , EddVisT8N12D7 , EddVisT8N12D8 , EddVisT8N12D9 , & + EddVisT8N13D1 , EddVisT8N13D2 , EddVisT8N13D3 , EddVisT8N13D4 , EddVisT8N13D5 , EddVisT8N13D6 , & + EddVisT8N13D7 , EddVisT8N13D8 , EddVisT8N13D9 , EddVisT8N14D1 , EddVisT8N14D2 , EddVisT8N14D3 , & + EddVisT8N14D4 , EddVisT8N14D5 , EddVisT8N14D6 , EddVisT8N14D7 , EddVisT8N14D8 , EddVisT8N14D9 , & + EddVisT8N15D1 , EddVisT8N15D2 , EddVisT8N15D3 , EddVisT8N15D4 , EddVisT8N15D5 , EddVisT8N15D6 , & + EddVisT8N15D7 , EddVisT8N15D8 , EddVisT8N15D9 , EddVisT8N16D1 , EddVisT8N16D2 , EddVisT8N16D3 , & + EddVisT8N16D4 , EddVisT8N16D5 , EddVisT8N16D6 , EddVisT8N16D7 , EddVisT8N16D8 , EddVisT8N16D9 , & + EddVisT8N17D1 , EddVisT8N17D2 , EddVisT8N17D3 , EddVisT8N17D4 , EddVisT8N17D5 , EddVisT8N17D6 , & + EddVisT8N17D7 , EddVisT8N17D8 , EddVisT8N17D9 , EddVisT8N18D1 , EddVisT8N18D2 , EddVisT8N18D3 , & + EddVisT8N18D4 , EddVisT8N18D5 , EddVisT8N18D6 , EddVisT8N18D7 , EddVisT8N18D8 , EddVisT8N18D9 , & + EddVisT8N19D1 , EddVisT8N19D2 , EddVisT8N19D3 , EddVisT8N19D4 , EddVisT8N19D5 , EddVisT8N19D6 , & + EddVisT8N19D7 , EddVisT8N19D8 , EddVisT8N19D9 , EddVisT8N20D1 , EddVisT8N20D2 , EddVisT8N20D3 , & + EddVisT8N20D4 , EddVisT8N20D5 , EddVisT8N20D6 , EddVisT8N20D7 , EddVisT8N20D8 , EddVisT8N20D9 , & + EddVisT9N01D1 , EddVisT9N01D2 , EddVisT9N01D3 , EddVisT9N01D4 , EddVisT9N01D5 , EddVisT9N01D6 , & + EddVisT9N01D7 , EddVisT9N01D8 , EddVisT9N01D9 , EddVisT9N02D1 , EddVisT9N02D2 , EddVisT9N02D3 , & + EddVisT9N02D4 , EddVisT9N02D5 , EddVisT9N02D6 , EddVisT9N02D7 , EddVisT9N02D8 , EddVisT9N02D9 , & + EddVisT9N03D1 , EddVisT9N03D2 , EddVisT9N03D3 , EddVisT9N03D4 , EddVisT9N03D5 , EddVisT9N03D6 , & + EddVisT9N03D7 , EddVisT9N03D8 , EddVisT9N03D9 , EddVisT9N04D1 , EddVisT9N04D2 , EddVisT9N04D3 , & + EddVisT9N04D4 , EddVisT9N04D5 , EddVisT9N04D6 , EddVisT9N04D7 , EddVisT9N04D8 , EddVisT9N04D9 , & + EddVisT9N05D1 , EddVisT9N05D2 , EddVisT9N05D3 , EddVisT9N05D4 , EddVisT9N05D5 , EddVisT9N05D6 , & + EddVisT9N05D7 , EddVisT9N05D8 , EddVisT9N05D9 , EddVisT9N06D1 , EddVisT9N06D2 , EddVisT9N06D3 , & + EddVisT9N06D4 , EddVisT9N06D5 , EddVisT9N06D6 , EddVisT9N06D7 , EddVisT9N06D8 , EddVisT9N06D9 , & + EddVisT9N07D1 , EddVisT9N07D2 , EddVisT9N07D3 , EddVisT9N07D4 , EddVisT9N07D5 , EddVisT9N07D6 , & + EddVisT9N07D7 , EddVisT9N07D8 , EddVisT9N07D9 , EddVisT9N08D1 , EddVisT9N08D2 , EddVisT9N08D3 , & + EddVisT9N08D4 , EddVisT9N08D5 , EddVisT9N08D6 , EddVisT9N08D7 , EddVisT9N08D8 , EddVisT9N08D9 , & + EddVisT9N09D1 , EddVisT9N09D2 , EddVisT9N09D3 , EddVisT9N09D4 , EddVisT9N09D5 , EddVisT9N09D6 , & + EddVisT9N09D7 , EddVisT9N09D8 , EddVisT9N09D9 , EddVisT9N10D1 , EddVisT9N10D2 , EddVisT9N10D3 , & + EddVisT9N10D4 , EddVisT9N10D5 , EddVisT9N10D6 , EddVisT9N10D7 , EddVisT9N10D8 , EddVisT9N10D9 , & + EddVisT9N11D1 , EddVisT9N11D2 , EddVisT9N11D3 , EddVisT9N11D4 , EddVisT9N11D5 , EddVisT9N11D6 , & + EddVisT9N11D7 , EddVisT9N11D8 , EddVisT9N11D9 , EddVisT9N12D1 , EddVisT9N12D2 , EddVisT9N12D3 , & + EddVisT9N12D4 , EddVisT9N12D5 , EddVisT9N12D6 , EddVisT9N12D7 , EddVisT9N12D8 , EddVisT9N12D9 , & + EddVisT9N13D1 , EddVisT9N13D2 , EddVisT9N13D3 , EddVisT9N13D4 , EddVisT9N13D5 , EddVisT9N13D6 , & + EddVisT9N13D7 , EddVisT9N13D8 , EddVisT9N13D9 , EddVisT9N14D1 , EddVisT9N14D2 , EddVisT9N14D3 , & + EddVisT9N14D4 , EddVisT9N14D5 , EddVisT9N14D6 , EddVisT9N14D7 , EddVisT9N14D8 , EddVisT9N14D9 , & + EddVisT9N15D1 , EddVisT9N15D2 , EddVisT9N15D3 , EddVisT9N15D4 , EddVisT9N15D5 , EddVisT9N15D6 , & + EddVisT9N15D7 , EddVisT9N15D8 , EddVisT9N15D9 , EddVisT9N16D1 , EddVisT9N16D2 , EddVisT9N16D3 , & + EddVisT9N16D4 , EddVisT9N16D5 , EddVisT9N16D6 , EddVisT9N16D7 , EddVisT9N16D8 , EddVisT9N16D9 , & + EddVisT9N17D1 , EddVisT9N17D2 , EddVisT9N17D3 , EddVisT9N17D4 , EddVisT9N17D5 , EddVisT9N17D6 , & + EddVisT9N17D7 , EddVisT9N17D8 , EddVisT9N17D9 , EddVisT9N18D1 , EddVisT9N18D2 , EddVisT9N18D3 , & + EddVisT9N18D4 , EddVisT9N18D5 , EddVisT9N18D6 , EddVisT9N18D7 , EddVisT9N18D8 , EddVisT9N18D9 , & + EddVisT9N19D1 , EddVisT9N19D2 , EddVisT9N19D3 , EddVisT9N19D4 , EddVisT9N19D5 , EddVisT9N19D6 , & + EddVisT9N19D7 , EddVisT9N19D8 , EddVisT9N19D9 , EddVisT9N20D1 , EddVisT9N20D2 , EddVisT9N20D3 , & + EddVisT9N20D4 , EddVisT9N20D5 , EddVisT9N20D6 , EddVisT9N20D7 , EddVisT9N20D8 , EddVisT9N20D9 , & + RtAxsXT1 , RtAxsXT2 , RtAxsXT3 , RtAxsXT4 , RtAxsXT5 , RtAxsXT6 , & + RtAxsXT7 , RtAxsXT8 , RtAxsXT9 , RtAxsYT1 , RtAxsYT2 , RtAxsYT3 , & + RtAxsYT4 , RtAxsYT5 , RtAxsYT6 , RtAxsYT7 , RtAxsYT8 , RtAxsYT9 , & + RtAxsZT1 , RtAxsZT2 , RtAxsZT3 , RtAxsZT4 , RtAxsZT5 , RtAxsZT6 , & + RtAxsZT7 , RtAxsZT8 , RtAxsZT9 , RtCtAvgT1 , RtCtAvgT2 , RtCtAvgT3 , & + RtCtAvgT4 , RtCtAvgT5 , RtCtAvgT6 , RtCtAvgT7 , RtCtAvgT8 , RtCtAvgT9 , & + RtDiamT1 , RtDiamT2 , RtDiamT3 , RtDiamT4 , RtDiamT5 , RtDiamT6 , & + RtDiamT7 , RtDiamT8 , RtDiamT9 , RtGamCurlT1 , RtGamCurlT2 , RtGamCurlT3 , & + RtGamCurlT4 , RtGamCurlT5 , RtGamCurlT6 , RtGamCurlT7 , RtGamCurlT8 , RtGamCurlT9 , & + RtPosXT1 , RtPosXT2 , RtPosXT3 , RtPosXT4 , RtPosXT5 , RtPosXT6 , & + RtPosXT7 , RtPosXT8 , RtPosXT9 , RtPosYT1 , RtPosYT2 , RtPosYT3 , & + RtPosYT4 , RtPosYT5 , RtPosYT6 , RtPosYT7 , RtPosYT8 , RtPosYT9 , & + RtPosZT1 , RtPosZT2 , RtPosZT3 , RtPosZT4 , RtPosZT5 , RtPosZT6 , & + RtPosZT7 , RtPosZT8 , RtPosZT9 , RtSkewFiltT1 , RtSkewFiltT2 , RtSkewFiltT3 , & + RtSkewFiltT4 , RtSkewFiltT5 , RtSkewFiltT6 , RtSkewFiltT7 , RtSkewFiltT8 , RtSkewFiltT9 , & + RtSkewT1 , RtSkewT2 , RtSkewT3 , RtSkewT4 , RtSkewT5 , RtSkewT6 , & + RtSkewT7 , RtSkewT8 , RtSkewT9 , RtVAmbFiltT1 , RtVAmbFiltT2 , RtVAmbFiltT3 , & + RtVAmbFiltT4 , RtVAmbFiltT5 , RtVAmbFiltT6 , RtVAmbFiltT7 , RtVAmbFiltT8 , RtVAmbFiltT9 , & + RtVAmbT1 , RtVAmbT2 , RtVAmbT3 , RtVAmbT4 , RtVAmbT5 , RtVAmbT6 , & + RtVAmbT7 , RtVAmbT8 , RtVAmbT9 , RtVRelT1 , RtVRelT2 , RtVRelT3 , & + RtVRelT4 , RtVRelT5 , RtVRelT6 , RtVRelT7 , RtVRelT8 , RtVRelT9 , & + SCGblIn1 , SCGblIn2 , SCGblIn3 , SCGblIn4 , SCGblIn5 , SCGblIn6 , & + SCGblIn7 , SCGblIn8 , SCGblIn9 , SCGblOt1 , SCGblOt2 , SCGblOt3 , & + SCGblOt4 , SCGblOt5 , SCGblOt6 , SCGblOt7 , SCGblOt8 , SCGblOt9 , & + SCT1In1 , SCT1In2 , SCT1In3 , SCT1In4 , SCT1In5 , SCT1In6 , & + SCT1In7 , SCT1In8 , SCT1In9 , SCT1Ot1 , SCT1Ot2 , SCT1Ot3 , & + SCT1Ot4 , SCT1Ot5 , SCT1Ot6 , SCT1Ot7 , SCT1Ot8 , SCT1Ot9 , & + SCT2In1 , SCT2In2 , SCT2In3 , SCT2In4 , SCT2In5 , SCT2In6 , & + SCT2In7 , SCT2In8 , SCT2In9 , SCT2Ot1 , SCT2Ot2 , SCT2Ot3 , & + SCT2Ot4 , SCT2Ot5 , SCT2Ot6 , SCT2Ot7 , SCT2Ot8 , SCT2Ot9 , & + SCT3In1 , SCT3In2 , SCT3In3 , SCT3In4 , SCT3In5 , SCT3In6 , & + SCT3In7 , SCT3In8 , SCT3In9 , SCT3Ot1 , SCT3Ot2 , SCT3Ot3 , & + SCT3Ot4 , SCT3Ot5 , SCT3Ot6 , SCT3Ot7 , SCT3Ot8 , SCT3Ot9 , & + SCT4In1 , SCT4In2 , SCT4In3 , SCT4In4 , SCT4In5 , SCT4In6 , & + SCT4In7 , SCT4In8 , SCT4In9 , SCT4Ot1 , SCT4Ot2 , SCT4Ot3 , & + SCT4Ot4 , SCT4Ot5 , SCT4Ot6 , SCT4Ot7 , SCT4Ot8 , SCT4Ot9 , & + SCT5In1 , SCT5In2 , SCT5In3 , SCT5In4 , SCT5In5 , SCT5In6 , & + SCT5In7 , SCT5In8 , SCT5In9 , SCT5Ot1 , SCT5Ot2 , SCT5Ot3 , & + SCT5Ot4 , SCT5Ot5 , SCT5Ot6 , SCT5Ot7 , SCT5Ot8 , SCT5Ot9 , & + SCT6In1 , SCT6In2 , SCT6In3 , SCT6In4 , SCT6In5 , SCT6In6 , & + SCT6In7 , SCT6In8 , SCT6In9 , SCT6Ot1 , SCT6Ot2 , SCT6Ot3 , & + SCT6Ot4 , SCT6Ot5 , SCT6Ot6 , SCT6Ot7 , SCT6Ot8 , SCT6Ot9 , & + SCT7In1 , SCT7In2 , SCT7In3 , SCT7In4 , SCT7In5 , SCT7In6 , & + SCT7In7 , SCT7In8 , SCT7In9 , SCT7Ot1 , SCT7Ot2 , SCT7Ot3 , & + SCT7Ot4 , SCT7Ot5 , SCT7Ot6 , SCT7Ot7 , SCT7Ot8 , SCT7Ot9 , & + SCT8In1 , SCT8In2 , SCT8In3 , SCT8In4 , SCT8In5 , SCT8In6 , & + SCT8In7 , SCT8In8 , SCT8In9 , SCT8Ot1 , SCT8Ot2 , SCT8Ot3 , & + SCT8Ot4 , SCT8Ot5 , SCT8Ot6 , SCT8Ot7 , SCT8Ot8 , SCT8Ot9 , & + SCT9In1 , SCT9In2 , SCT9In3 , SCT9In4 , SCT9In5 , SCT9In6 , & + SCT9In7 , SCT9In8 , SCT9In9 , SCT9Ot1 , SCT9Ot2 , SCT9Ot3 , & + SCT9Ot4 , SCT9Ot5 , SCT9Ot6 , SCT9Ot7 , SCT9Ot8 , SCT9Ot9 , & + TIAmbT1 , TIAmbT2 , TIAmbT3 , TIAmbT4 , TIAmbT5 , TIAmbT6 , & + TIAmbT7 , TIAmbT8 , TIAmbT9 , W1VAmbX , W1VAmbY , W1VAmbZ , & + W1VDisX , W1VDisY , W1VDisZ , W2VAmbX , W2VAmbY , W2VAmbZ , & + W2VDisX , W2VDisY , W2VDisZ , W3VAmbX , W3VAmbY , W3VAmbZ , & + W3VDisX , W3VDisY , W3VDisZ , W4VAmbX , W4VAmbY , W4VAmbZ , & + W4VDisX , W4VDisY , W4VDisZ , W5VAmbX , W5VAmbY , W5VAmbZ , & + W5VDisX , W5VDisY , W5VDisZ , W6VAmbX , W6VAmbY , W6VAmbZ , & + W6VDisX , W6VDisY , W6VDisZ , W7VAmbX , W7VAmbY , W7VAmbZ , & + W7VDisX , W7VDisY , W7VDisZ , W8VAmbX , W8VAmbY , W8VAmbZ , & + W8VDisX , W8VDisY , W8VDisZ , W9VAmbX , W9VAmbY , W9VAmbZ /) + INTEGER(IntKi), PARAMETER :: ParamIndxAry5(1356) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + W9VDisX , W9VDisY , W9VDisZ , WkAxsXT1D1 , WkAxsXT1D2 , WkAxsXT1D3 , & + WkAxsXT1D4 , WkAxsXT1D5 , WkAxsXT1D6 , WkAxsXT1D7 , WkAxsXT1D8 , WkAxsXT1D9 , & + WkAxsXT2D1 , WkAxsXT2D2 , WkAxsXT2D3 , WkAxsXT2D4 , WkAxsXT2D5 , WkAxsXT2D6 , & + WkAxsXT2D7 , WkAxsXT2D8 , WkAxsXT2D9 , WkAxsXT3D1 , WkAxsXT3D2 , WkAxsXT3D3 , & + WkAxsXT3D4 , WkAxsXT3D5 , WkAxsXT3D6 , WkAxsXT3D7 , WkAxsXT3D8 , WkAxsXT3D9 , & + WkAxsXT4D1 , WkAxsXT4D2 , WkAxsXT4D3 , WkAxsXT4D4 , WkAxsXT4D5 , WkAxsXT4D6 , & + WkAxsXT4D7 , WkAxsXT4D8 , WkAxsXT4D9 , WkAxsXT5D1 , WkAxsXT5D2 , WkAxsXT5D3 , & + WkAxsXT5D4 , WkAxsXT5D5 , WkAxsXT5D6 , WkAxsXT5D7 , WkAxsXT5D8 , WkAxsXT5D9 , & + WkAxsXT6D1 , WkAxsXT6D2 , WkAxsXT6D3 , WkAxsXT6D4 , WkAxsXT6D5 , WkAxsXT6D6 , & + WkAxsXT6D7 , WkAxsXT6D8 , WkAxsXT6D9 , WkAxsXT7D1 , WkAxsXT7D2 , WkAxsXT7D3 , & + WkAxsXT7D4 , WkAxsXT7D5 , WkAxsXT7D6 , WkAxsXT7D7 , WkAxsXT7D8 , WkAxsXT7D9 , & + WkAxsXT8D1 , WkAxsXT8D2 , WkAxsXT8D3 , WkAxsXT8D4 , WkAxsXT8D5 , WkAxsXT8D6 , & + WkAxsXT8D7 , WkAxsXT8D8 , WkAxsXT8D9 , WkAxsXT9D1 , WkAxsXT9D2 , WkAxsXT9D3 , & + WkAxsXT9D4 , WkAxsXT9D5 , WkAxsXT9D6 , WkAxsXT9D7 , WkAxsXT9D8 , WkAxsXT9D9 , & + WkAxsYT1D1 , WkAxsYT1D2 , WkAxsYT1D3 , WkAxsYT1D4 , WkAxsYT1D5 , WkAxsYT1D6 , & + WkAxsYT1D7 , WkAxsYT1D8 , WkAxsYT1D9 , WkAxsYT2D1 , WkAxsYT2D2 , WkAxsYT2D3 , & + WkAxsYT2D4 , WkAxsYT2D5 , WkAxsYT2D6 , WkAxsYT2D7 , WkAxsYT2D8 , WkAxsYT2D9 , & + WkAxsYT3D1 , WkAxsYT3D2 , WkAxsYT3D3 , WkAxsYT3D4 , WkAxsYT3D5 , WkAxsYT3D6 , & + WkAxsYT3D7 , WkAxsYT3D8 , WkAxsYT3D9 , WkAxsYT4D1 , WkAxsYT4D2 , WkAxsYT4D3 , & + WkAxsYT4D4 , WkAxsYT4D5 , WkAxsYT4D6 , WkAxsYT4D7 , WkAxsYT4D8 , WkAxsYT4D9 , & + WkAxsYT5D1 , WkAxsYT5D2 , WkAxsYT5D3 , WkAxsYT5D4 , WkAxsYT5D5 , WkAxsYT5D6 , & + WkAxsYT5D7 , WkAxsYT5D8 , WkAxsYT5D9 , WkAxsYT6D1 , WkAxsYT6D2 , WkAxsYT6D3 , & + WkAxsYT6D4 , WkAxsYT6D5 , WkAxsYT6D6 , WkAxsYT6D7 , WkAxsYT6D8 , WkAxsYT6D9 , & + WkAxsYT7D1 , WkAxsYT7D2 , WkAxsYT7D3 , WkAxsYT7D4 , WkAxsYT7D5 , WkAxsYT7D6 , & + WkAxsYT7D7 , WkAxsYT7D8 , WkAxsYT7D9 , WkAxsYT8D1 , WkAxsYT8D2 , WkAxsYT8D3 , & + WkAxsYT8D4 , WkAxsYT8D5 , WkAxsYT8D6 , WkAxsYT8D7 , WkAxsYT8D8 , WkAxsYT8D9 , & + WkAxsYT9D1 , WkAxsYT9D2 , WkAxsYT9D3 , WkAxsYT9D4 , WkAxsYT9D5 , WkAxsYT9D6 , & + WkAxsYT9D7 , WkAxsYT9D8 , WkAxsYT9D9 , WkAxsZT1D1 , WkAxsZT1D2 , WkAxsZT1D3 , & + WkAxsZT1D4 , WkAxsZT1D5 , WkAxsZT1D6 , WkAxsZT1D7 , WkAxsZT1D8 , WkAxsZT1D9 , & + WkAxsZT2D1 , WkAxsZT2D2 , WkAxsZT2D3 , WkAxsZT2D4 , WkAxsZT2D5 , WkAxsZT2D6 , & + WkAxsZT2D7 , WkAxsZT2D8 , WkAxsZT2D9 , WkAxsZT3D1 , WkAxsZT3D2 , WkAxsZT3D3 , & + WkAxsZT3D4 , WkAxsZT3D5 , WkAxsZT3D6 , WkAxsZT3D7 , WkAxsZT3D8 , WkAxsZT3D9 , & + WkAxsZT4D1 , WkAxsZT4D2 , WkAxsZT4D3 , WkAxsZT4D4 , WkAxsZT4D5 , WkAxsZT4D6 , & + WkAxsZT4D7 , WkAxsZT4D8 , WkAxsZT4D9 , WkAxsZT5D1 , WkAxsZT5D2 , WkAxsZT5D3 , & + WkAxsZT5D4 , WkAxsZT5D5 , WkAxsZT5D6 , WkAxsZT5D7 , WkAxsZT5D8 , WkAxsZT5D9 , & + WkAxsZT6D1 , WkAxsZT6D2 , WkAxsZT6D3 , WkAxsZT6D4 , WkAxsZT6D5 , WkAxsZT6D6 , & + WkAxsZT6D7 , WkAxsZT6D8 , WkAxsZT6D9 , WkAxsZT7D1 , WkAxsZT7D2 , WkAxsZT7D3 , & + WkAxsZT7D4 , WkAxsZT7D5 , WkAxsZT7D6 , WkAxsZT7D7 , WkAxsZT7D8 , WkAxsZT7D9 , & + WkAxsZT8D1 , WkAxsZT8D2 , WkAxsZT8D3 , WkAxsZT8D4 , WkAxsZT8D5 , WkAxsZT8D6 , & + WkAxsZT8D7 , WkAxsZT8D8 , WkAxsZT8D9 , WkAxsZT9D1 , WkAxsZT9D2 , WkAxsZT9D3 , & + WkAxsZT9D4 , WkAxsZT9D5 , WkAxsZT9D6 , WkAxsZT9D7 , WkAxsZT9D8 , WkAxsZT9D9 , & + WkDfVrT1N01D1 , WkDfVrT1N01D2 , WkDfVrT1N01D3 , WkDfVrT1N01D4 , WkDfVrT1N01D5 , WkDfVrT1N01D6 , & + WkDfVrT1N01D7 , WkDfVrT1N01D8 , WkDfVrT1N01D9 , WkDfVrT1N02D1 , WkDfVrT1N02D2 , WkDfVrT1N02D3 , & + WkDfVrT1N02D4 , WkDfVrT1N02D5 , WkDfVrT1N02D6 , WkDfVrT1N02D7 , WkDfVrT1N02D8 , WkDfVrT1N02D9 , & + WkDfVrT1N03D1 , WkDfVrT1N03D2 , WkDfVrT1N03D3 , WkDfVrT1N03D4 , WkDfVrT1N03D5 , WkDfVrT1N03D6 , & + WkDfVrT1N03D7 , WkDfVrT1N03D8 , WkDfVrT1N03D9 , WkDfVrT1N04D1 , WkDfVrT1N04D2 , WkDfVrT1N04D3 , & + WkDfVrT1N04D4 , WkDfVrT1N04D5 , WkDfVrT1N04D6 , WkDfVrT1N04D7 , WkDfVrT1N04D8 , WkDfVrT1N04D9 , & + WkDfVrT1N05D1 , WkDfVrT1N05D2 , WkDfVrT1N05D3 , WkDfVrT1N05D4 , WkDfVrT1N05D5 , WkDfVrT1N05D6 , & + WkDfVrT1N05D7 , WkDfVrT1N05D8 , WkDfVrT1N05D9 , WkDfVrT1N06D1 , WkDfVrT1N06D2 , WkDfVrT1N06D3 , & + WkDfVrT1N06D4 , WkDfVrT1N06D5 , WkDfVrT1N06D6 , WkDfVrT1N06D7 , WkDfVrT1N06D8 , WkDfVrT1N06D9 , & + WkDfVrT1N07D1 , WkDfVrT1N07D2 , WkDfVrT1N07D3 , WkDfVrT1N07D4 , WkDfVrT1N07D5 , WkDfVrT1N07D6 , & + WkDfVrT1N07D7 , WkDfVrT1N07D8 , WkDfVrT1N07D9 , WkDfVrT1N08D1 , WkDfVrT1N08D2 , WkDfVrT1N08D3 , & + WkDfVrT1N08D4 , WkDfVrT1N08D5 , WkDfVrT1N08D6 , WkDfVrT1N08D7 , WkDfVrT1N08D8 , WkDfVrT1N08D9 , & + WkDfVrT1N09D1 , WkDfVrT1N09D2 , WkDfVrT1N09D3 , WkDfVrT1N09D4 , WkDfVrT1N09D5 , WkDfVrT1N09D6 , & + WkDfVrT1N09D7 , WkDfVrT1N09D8 , WkDfVrT1N09D9 , WkDfVrT1N10D1 , WkDfVrT1N10D2 , WkDfVrT1N10D3 , & + WkDfVrT1N10D4 , WkDfVrT1N10D5 , WkDfVrT1N10D6 , WkDfVrT1N10D7 , WkDfVrT1N10D8 , WkDfVrT1N10D9 , & + WkDfVrT1N11D1 , WkDfVrT1N11D2 , WkDfVrT1N11D3 , WkDfVrT1N11D4 , WkDfVrT1N11D5 , WkDfVrT1N11D6 , & + WkDfVrT1N11D7 , WkDfVrT1N11D8 , WkDfVrT1N11D9 , WkDfVrT1N12D1 , WkDfVrT1N12D2 , WkDfVrT1N12D3 , & + WkDfVrT1N12D4 , WkDfVrT1N12D5 , WkDfVrT1N12D6 , WkDfVrT1N12D7 , WkDfVrT1N12D8 , WkDfVrT1N12D9 , & + WkDfVrT1N13D1 , WkDfVrT1N13D2 , WkDfVrT1N13D3 , WkDfVrT1N13D4 , WkDfVrT1N13D5 , WkDfVrT1N13D6 , & + WkDfVrT1N13D7 , WkDfVrT1N13D8 , WkDfVrT1N13D9 , WkDfVrT1N14D1 , WkDfVrT1N14D2 , WkDfVrT1N14D3 , & + WkDfVrT1N14D4 , WkDfVrT1N14D5 , WkDfVrT1N14D6 , WkDfVrT1N14D7 , WkDfVrT1N14D8 , WkDfVrT1N14D9 , & + WkDfVrT1N15D1 , WkDfVrT1N15D2 , WkDfVrT1N15D3 , WkDfVrT1N15D4 , WkDfVrT1N15D5 , WkDfVrT1N15D6 , & + WkDfVrT1N15D7 , WkDfVrT1N15D8 , WkDfVrT1N15D9 , WkDfVrT1N16D1 , WkDfVrT1N16D2 , WkDfVrT1N16D3 , & + WkDfVrT1N16D4 , WkDfVrT1N16D5 , WkDfVrT1N16D6 , WkDfVrT1N16D7 , WkDfVrT1N16D8 , WkDfVrT1N16D9 , & + WkDfVrT1N17D1 , WkDfVrT1N17D2 , WkDfVrT1N17D3 , WkDfVrT1N17D4 , WkDfVrT1N17D5 , WkDfVrT1N17D6 , & + WkDfVrT1N17D7 , WkDfVrT1N17D8 , WkDfVrT1N17D9 , WkDfVrT1N18D1 , WkDfVrT1N18D2 , WkDfVrT1N18D3 , & + WkDfVrT1N18D4 , WkDfVrT1N18D5 , WkDfVrT1N18D6 , WkDfVrT1N18D7 , WkDfVrT1N18D8 , WkDfVrT1N18D9 , & + WkDfVrT1N19D1 , WkDfVrT1N19D2 , WkDfVrT1N19D3 , WkDfVrT1N19D4 , WkDfVrT1N19D5 , WkDfVrT1N19D6 , & + WkDfVrT1N19D7 , WkDfVrT1N19D8 , WkDfVrT1N19D9 , WkDfVrT1N20D1 , WkDfVrT1N20D2 , WkDfVrT1N20D3 , & + WkDfVrT1N20D4 , WkDfVrT1N20D5 , WkDfVrT1N20D6 , WkDfVrT1N20D7 , WkDfVrT1N20D8 , WkDfVrT1N20D9 , & + WkDfVrT2N01D1 , WkDfVrT2N01D2 , WkDfVrT2N01D3 , WkDfVrT2N01D4 , WkDfVrT2N01D5 , WkDfVrT2N01D6 , & + WkDfVrT2N01D7 , WkDfVrT2N01D8 , WkDfVrT2N01D9 , WkDfVrT2N02D1 , WkDfVrT2N02D2 , WkDfVrT2N02D3 , & + WkDfVrT2N02D4 , WkDfVrT2N02D5 , WkDfVrT2N02D6 , WkDfVrT2N02D7 , WkDfVrT2N02D8 , WkDfVrT2N02D9 , & + WkDfVrT2N03D1 , WkDfVrT2N03D2 , WkDfVrT2N03D3 , WkDfVrT2N03D4 , WkDfVrT2N03D5 , WkDfVrT2N03D6 , & + WkDfVrT2N03D7 , WkDfVrT2N03D8 , WkDfVrT2N03D9 , WkDfVrT2N04D1 , WkDfVrT2N04D2 , WkDfVrT2N04D3 , & + WkDfVrT2N04D4 , WkDfVrT2N04D5 , WkDfVrT2N04D6 , WkDfVrT2N04D7 , WkDfVrT2N04D8 , WkDfVrT2N04D9 , & + WkDfVrT2N05D1 , WkDfVrT2N05D2 , WkDfVrT2N05D3 , WkDfVrT2N05D4 , WkDfVrT2N05D5 , WkDfVrT2N05D6 , & + WkDfVrT2N05D7 , WkDfVrT2N05D8 , WkDfVrT2N05D9 , WkDfVrT2N06D1 , WkDfVrT2N06D2 , WkDfVrT2N06D3 , & + WkDfVrT2N06D4 , WkDfVrT2N06D5 , WkDfVrT2N06D6 , WkDfVrT2N06D7 , WkDfVrT2N06D8 , WkDfVrT2N06D9 , & + WkDfVrT2N07D1 , WkDfVrT2N07D2 , WkDfVrT2N07D3 , WkDfVrT2N07D4 , WkDfVrT2N07D5 , WkDfVrT2N07D6 , & + WkDfVrT2N07D7 , WkDfVrT2N07D8 , WkDfVrT2N07D9 , WkDfVrT2N08D1 , WkDfVrT2N08D2 , WkDfVrT2N08D3 , & + WkDfVrT2N08D4 , WkDfVrT2N08D5 , WkDfVrT2N08D6 , WkDfVrT2N08D7 , WkDfVrT2N08D8 , WkDfVrT2N08D9 , & + WkDfVrT2N09D1 , WkDfVrT2N09D2 , WkDfVrT2N09D3 , WkDfVrT2N09D4 , WkDfVrT2N09D5 , WkDfVrT2N09D6 , & + WkDfVrT2N09D7 , WkDfVrT2N09D8 , WkDfVrT2N09D9 , WkDfVrT2N10D1 , WkDfVrT2N10D2 , WkDfVrT2N10D3 , & + WkDfVrT2N10D4 , WkDfVrT2N10D5 , WkDfVrT2N10D6 , WkDfVrT2N10D7 , WkDfVrT2N10D8 , WkDfVrT2N10D9 , & + WkDfVrT2N11D1 , WkDfVrT2N11D2 , WkDfVrT2N11D3 , WkDfVrT2N11D4 , WkDfVrT2N11D5 , WkDfVrT2N11D6 , & + WkDfVrT2N11D7 , WkDfVrT2N11D8 , WkDfVrT2N11D9 , WkDfVrT2N12D1 , WkDfVrT2N12D2 , WkDfVrT2N12D3 , & + WkDfVrT2N12D4 , WkDfVrT2N12D5 , WkDfVrT2N12D6 , WkDfVrT2N12D7 , WkDfVrT2N12D8 , WkDfVrT2N12D9 , & + WkDfVrT2N13D1 , WkDfVrT2N13D2 , WkDfVrT2N13D3 , WkDfVrT2N13D4 , WkDfVrT2N13D5 , WkDfVrT2N13D6 , & + WkDfVrT2N13D7 , WkDfVrT2N13D8 , WkDfVrT2N13D9 , WkDfVrT2N14D1 , WkDfVrT2N14D2 , WkDfVrT2N14D3 , & + WkDfVrT2N14D4 , WkDfVrT2N14D5 , WkDfVrT2N14D6 , WkDfVrT2N14D7 , WkDfVrT2N14D8 , WkDfVrT2N14D9 , & + WkDfVrT2N15D1 , WkDfVrT2N15D2 , WkDfVrT2N15D3 , WkDfVrT2N15D4 , WkDfVrT2N15D5 , WkDfVrT2N15D6 , & + WkDfVrT2N15D7 , WkDfVrT2N15D8 , WkDfVrT2N15D9 , WkDfVrT2N16D1 , WkDfVrT2N16D2 , WkDfVrT2N16D3 , & + WkDfVrT2N16D4 , WkDfVrT2N16D5 , WkDfVrT2N16D6 , WkDfVrT2N16D7 , WkDfVrT2N16D8 , WkDfVrT2N16D9 , & + WkDfVrT2N17D1 , WkDfVrT2N17D2 , WkDfVrT2N17D3 , WkDfVrT2N17D4 , WkDfVrT2N17D5 , WkDfVrT2N17D6 , & + WkDfVrT2N17D7 , WkDfVrT2N17D8 , WkDfVrT2N17D9 , WkDfVrT2N18D1 , WkDfVrT2N18D2 , WkDfVrT2N18D3 , & + WkDfVrT2N18D4 , WkDfVrT2N18D5 , WkDfVrT2N18D6 , WkDfVrT2N18D7 , WkDfVrT2N18D8 , WkDfVrT2N18D9 , & + WkDfVrT2N19D1 , WkDfVrT2N19D2 , WkDfVrT2N19D3 , WkDfVrT2N19D4 , WkDfVrT2N19D5 , WkDfVrT2N19D6 , & + WkDfVrT2N19D7 , WkDfVrT2N19D8 , WkDfVrT2N19D9 , WkDfVrT2N20D1 , WkDfVrT2N20D2 , WkDfVrT2N20D3 , & + WkDfVrT2N20D4 , WkDfVrT2N20D5 , WkDfVrT2N20D6 , WkDfVrT2N20D7 , WkDfVrT2N20D8 , WkDfVrT2N20D9 , & + WkDfVrT3N01D1 , WkDfVrT3N01D2 , WkDfVrT3N01D3 , WkDfVrT3N01D4 , WkDfVrT3N01D5 , WkDfVrT3N01D6 , & + WkDfVrT3N01D7 , WkDfVrT3N01D8 , WkDfVrT3N01D9 , WkDfVrT3N02D1 , WkDfVrT3N02D2 , WkDfVrT3N02D3 , & + WkDfVrT3N02D4 , WkDfVrT3N02D5 , WkDfVrT3N02D6 , WkDfVrT3N02D7 , WkDfVrT3N02D8 , WkDfVrT3N02D9 , & + WkDfVrT3N03D1 , WkDfVrT3N03D2 , WkDfVrT3N03D3 , WkDfVrT3N03D4 , WkDfVrT3N03D5 , WkDfVrT3N03D6 , & + WkDfVrT3N03D7 , WkDfVrT3N03D8 , WkDfVrT3N03D9 , WkDfVrT3N04D1 , WkDfVrT3N04D2 , WkDfVrT3N04D3 , & + WkDfVrT3N04D4 , WkDfVrT3N04D5 , WkDfVrT3N04D6 , WkDfVrT3N04D7 , WkDfVrT3N04D8 , WkDfVrT3N04D9 , & + WkDfVrT3N05D1 , WkDfVrT3N05D2 , WkDfVrT3N05D3 , WkDfVrT3N05D4 , WkDfVrT3N05D5 , WkDfVrT3N05D6 , & + WkDfVrT3N05D7 , WkDfVrT3N05D8 , WkDfVrT3N05D9 , WkDfVrT3N06D1 , WkDfVrT3N06D2 , WkDfVrT3N06D3 , & + WkDfVrT3N06D4 , WkDfVrT3N06D5 , WkDfVrT3N06D6 , WkDfVrT3N06D7 , WkDfVrT3N06D8 , WkDfVrT3N06D9 , & + WkDfVrT3N07D1 , WkDfVrT3N07D2 , WkDfVrT3N07D3 , WkDfVrT3N07D4 , WkDfVrT3N07D5 , WkDfVrT3N07D6 , & + WkDfVrT3N07D7 , WkDfVrT3N07D8 , WkDfVrT3N07D9 , WkDfVrT3N08D1 , WkDfVrT3N08D2 , WkDfVrT3N08D3 , & + WkDfVrT3N08D4 , WkDfVrT3N08D5 , WkDfVrT3N08D6 , WkDfVrT3N08D7 , WkDfVrT3N08D8 , WkDfVrT3N08D9 , & + WkDfVrT3N09D1 , WkDfVrT3N09D2 , WkDfVrT3N09D3 , WkDfVrT3N09D4 , WkDfVrT3N09D5 , WkDfVrT3N09D6 , & + WkDfVrT3N09D7 , WkDfVrT3N09D8 , WkDfVrT3N09D9 , WkDfVrT3N10D1 , WkDfVrT3N10D2 , WkDfVrT3N10D3 , & + WkDfVrT3N10D4 , WkDfVrT3N10D5 , WkDfVrT3N10D6 , WkDfVrT3N10D7 , WkDfVrT3N10D8 , WkDfVrT3N10D9 , & + WkDfVrT3N11D1 , WkDfVrT3N11D2 , WkDfVrT3N11D3 , WkDfVrT3N11D4 , WkDfVrT3N11D5 , WkDfVrT3N11D6 , & + WkDfVrT3N11D7 , WkDfVrT3N11D8 , WkDfVrT3N11D9 , WkDfVrT3N12D1 , WkDfVrT3N12D2 , WkDfVrT3N12D3 , & + WkDfVrT3N12D4 , WkDfVrT3N12D5 , WkDfVrT3N12D6 , WkDfVrT3N12D7 , WkDfVrT3N12D8 , WkDfVrT3N12D9 , & + WkDfVrT3N13D1 , WkDfVrT3N13D2 , WkDfVrT3N13D3 , WkDfVrT3N13D4 , WkDfVrT3N13D5 , WkDfVrT3N13D6 , & + WkDfVrT3N13D7 , WkDfVrT3N13D8 , WkDfVrT3N13D9 , WkDfVrT3N14D1 , WkDfVrT3N14D2 , WkDfVrT3N14D3 , & + WkDfVrT3N14D4 , WkDfVrT3N14D5 , WkDfVrT3N14D6 , WkDfVrT3N14D7 , WkDfVrT3N14D8 , WkDfVrT3N14D9 , & + WkDfVrT3N15D1 , WkDfVrT3N15D2 , WkDfVrT3N15D3 , WkDfVrT3N15D4 , WkDfVrT3N15D5 , WkDfVrT3N15D6 , & + WkDfVrT3N15D7 , WkDfVrT3N15D8 , WkDfVrT3N15D9 , WkDfVrT3N16D1 , WkDfVrT3N16D2 , WkDfVrT3N16D3 , & + WkDfVrT3N16D4 , WkDfVrT3N16D5 , WkDfVrT3N16D6 , WkDfVrT3N16D7 , WkDfVrT3N16D8 , WkDfVrT3N16D9 , & + WkDfVrT3N17D1 , WkDfVrT3N17D2 , WkDfVrT3N17D3 , WkDfVrT3N17D4 , WkDfVrT3N17D5 , WkDfVrT3N17D6 , & + WkDfVrT3N17D7 , WkDfVrT3N17D8 , WkDfVrT3N17D9 , WkDfVrT3N18D1 , WkDfVrT3N18D2 , WkDfVrT3N18D3 , & + WkDfVrT3N18D4 , WkDfVrT3N18D5 , WkDfVrT3N18D6 , WkDfVrT3N18D7 , WkDfVrT3N18D8 , WkDfVrT3N18D9 , & + WkDfVrT3N19D1 , WkDfVrT3N19D2 , WkDfVrT3N19D3 , WkDfVrT3N19D4 , WkDfVrT3N19D5 , WkDfVrT3N19D6 , & + WkDfVrT3N19D7 , WkDfVrT3N19D8 , WkDfVrT3N19D9 , WkDfVrT3N20D1 , WkDfVrT3N20D2 , WkDfVrT3N20D3 , & + WkDfVrT3N20D4 , WkDfVrT3N20D5 , WkDfVrT3N20D6 , WkDfVrT3N20D7 , WkDfVrT3N20D8 , WkDfVrT3N20D9 , & + WkDfVrT4N01D1 , WkDfVrT4N01D2 , WkDfVrT4N01D3 , WkDfVrT4N01D4 , WkDfVrT4N01D5 , WkDfVrT4N01D6 , & + WkDfVrT4N01D7 , WkDfVrT4N01D8 , WkDfVrT4N01D9 , WkDfVrT4N02D1 , WkDfVrT4N02D2 , WkDfVrT4N02D3 , & + WkDfVrT4N02D4 , WkDfVrT4N02D5 , WkDfVrT4N02D6 , WkDfVrT4N02D7 , WkDfVrT4N02D8 , WkDfVrT4N02D9 , & + WkDfVrT4N03D1 , WkDfVrT4N03D2 , WkDfVrT4N03D3 , WkDfVrT4N03D4 , WkDfVrT4N03D5 , WkDfVrT4N03D6 , & + WkDfVrT4N03D7 , WkDfVrT4N03D8 , WkDfVrT4N03D9 , WkDfVrT4N04D1 , WkDfVrT4N04D2 , WkDfVrT4N04D3 , & + WkDfVrT4N04D4 , WkDfVrT4N04D5 , WkDfVrT4N04D6 , WkDfVrT4N04D7 , WkDfVrT4N04D8 , WkDfVrT4N04D9 , & + WkDfVrT4N05D1 , WkDfVrT4N05D2 , WkDfVrT4N05D3 , WkDfVrT4N05D4 , WkDfVrT4N05D5 , WkDfVrT4N05D6 , & + WkDfVrT4N05D7 , WkDfVrT4N05D8 , WkDfVrT4N05D9 , WkDfVrT4N06D1 , WkDfVrT4N06D2 , WkDfVrT4N06D3 , & + WkDfVrT4N06D4 , WkDfVrT4N06D5 , WkDfVrT4N06D6 , WkDfVrT4N06D7 , WkDfVrT4N06D8 , WkDfVrT4N06D9 , & + WkDfVrT4N07D1 , WkDfVrT4N07D2 , WkDfVrT4N07D3 , WkDfVrT4N07D4 , WkDfVrT4N07D5 , WkDfVrT4N07D6 , & + WkDfVrT4N07D7 , WkDfVrT4N07D8 , WkDfVrT4N07D9 , WkDfVrT4N08D1 , WkDfVrT4N08D2 , WkDfVrT4N08D3 , & + WkDfVrT4N08D4 , WkDfVrT4N08D5 , WkDfVrT4N08D6 , WkDfVrT4N08D7 , WkDfVrT4N08D8 , WkDfVrT4N08D9 , & + WkDfVrT4N09D1 , WkDfVrT4N09D2 , WkDfVrT4N09D3 , WkDfVrT4N09D4 , WkDfVrT4N09D5 , WkDfVrT4N09D6 , & + WkDfVrT4N09D7 , WkDfVrT4N09D8 , WkDfVrT4N09D9 , WkDfVrT4N10D1 , WkDfVrT4N10D2 , WkDfVrT4N10D3 , & + WkDfVrT4N10D4 , WkDfVrT4N10D5 , WkDfVrT4N10D6 , WkDfVrT4N10D7 , WkDfVrT4N10D8 , WkDfVrT4N10D9 , & + WkDfVrT4N11D1 , WkDfVrT4N11D2 , WkDfVrT4N11D3 , WkDfVrT4N11D4 , WkDfVrT4N11D5 , WkDfVrT4N11D6 , & + WkDfVrT4N11D7 , WkDfVrT4N11D8 , WkDfVrT4N11D9 , WkDfVrT4N12D1 , WkDfVrT4N12D2 , WkDfVrT4N12D3 , & + WkDfVrT4N12D4 , WkDfVrT4N12D5 , WkDfVrT4N12D6 , WkDfVrT4N12D7 , WkDfVrT4N12D8 , WkDfVrT4N12D9 , & + WkDfVrT4N13D1 , WkDfVrT4N13D2 , WkDfVrT4N13D3 , WkDfVrT4N13D4 , WkDfVrT4N13D5 , WkDfVrT4N13D6 , & + WkDfVrT4N13D7 , WkDfVrT4N13D8 , WkDfVrT4N13D9 , WkDfVrT4N14D1 , WkDfVrT4N14D2 , WkDfVrT4N14D3 , & + WkDfVrT4N14D4 , WkDfVrT4N14D5 , WkDfVrT4N14D6 , WkDfVrT4N14D7 , WkDfVrT4N14D8 , WkDfVrT4N14D9 , & + WkDfVrT4N15D1 , WkDfVrT4N15D2 , WkDfVrT4N15D3 , WkDfVrT4N15D4 , WkDfVrT4N15D5 , WkDfVrT4N15D6 , & + WkDfVrT4N15D7 , WkDfVrT4N15D8 , WkDfVrT4N15D9 , WkDfVrT4N16D1 , WkDfVrT4N16D2 , WkDfVrT4N16D3 , & + WkDfVrT4N16D4 , WkDfVrT4N16D5 , WkDfVrT4N16D6 , WkDfVrT4N16D7 , WkDfVrT4N16D8 , WkDfVrT4N16D9 , & + WkDfVrT4N17D1 , WkDfVrT4N17D2 , WkDfVrT4N17D3 , WkDfVrT4N17D4 , WkDfVrT4N17D5 , WkDfVrT4N17D6 , & + WkDfVrT4N17D7 , WkDfVrT4N17D8 , WkDfVrT4N17D9 , WkDfVrT4N18D1 , WkDfVrT4N18D2 , WkDfVrT4N18D3 , & + WkDfVrT4N18D4 , WkDfVrT4N18D5 , WkDfVrT4N18D6 , WkDfVrT4N18D7 , WkDfVrT4N18D8 , WkDfVrT4N18D9 , & + WkDfVrT4N19D1 , WkDfVrT4N19D2 , WkDfVrT4N19D3 , WkDfVrT4N19D4 , WkDfVrT4N19D5 , WkDfVrT4N19D6 , & + WkDfVrT4N19D7 , WkDfVrT4N19D8 , WkDfVrT4N19D9 , WkDfVrT4N20D1 , WkDfVrT4N20D2 , WkDfVrT4N20D3 , & + WkDfVrT4N20D4 , WkDfVrT4N20D5 , WkDfVrT4N20D6 , WkDfVrT4N20D7 , WkDfVrT4N20D8 , WkDfVrT4N20D9 , & + WkDfVrT5N01D1 , WkDfVrT5N01D2 , WkDfVrT5N01D3 , WkDfVrT5N01D4 , WkDfVrT5N01D5 , WkDfVrT5N01D6 , & + WkDfVrT5N01D7 , WkDfVrT5N01D8 , WkDfVrT5N01D9 , WkDfVrT5N02D1 , WkDfVrT5N02D2 , WkDfVrT5N02D3 , & + WkDfVrT5N02D4 , WkDfVrT5N02D5 , WkDfVrT5N02D6 , WkDfVrT5N02D7 , WkDfVrT5N02D8 , WkDfVrT5N02D9 , & + WkDfVrT5N03D1 , WkDfVrT5N03D2 , WkDfVrT5N03D3 , WkDfVrT5N03D4 , WkDfVrT5N03D5 , WkDfVrT5N03D6 , & + WkDfVrT5N03D7 , WkDfVrT5N03D8 , WkDfVrT5N03D9 , WkDfVrT5N04D1 , WkDfVrT5N04D2 , WkDfVrT5N04D3 , & + WkDfVrT5N04D4 , WkDfVrT5N04D5 , WkDfVrT5N04D6 , WkDfVrT5N04D7 , WkDfVrT5N04D8 , WkDfVrT5N04D9 , & + WkDfVrT5N05D1 , WkDfVrT5N05D2 , WkDfVrT5N05D3 , WkDfVrT5N05D4 , WkDfVrT5N05D5 , WkDfVrT5N05D6 , & + WkDfVrT5N05D7 , WkDfVrT5N05D8 , WkDfVrT5N05D9 , WkDfVrT5N06D1 , WkDfVrT5N06D2 , WkDfVrT5N06D3 , & + WkDfVrT5N06D4 , WkDfVrT5N06D5 , WkDfVrT5N06D6 , WkDfVrT5N06D7 , WkDfVrT5N06D8 , WkDfVrT5N06D9 , & + WkDfVrT5N07D1 , WkDfVrT5N07D2 , WkDfVrT5N07D3 , WkDfVrT5N07D4 , WkDfVrT5N07D5 , WkDfVrT5N07D6 , & + WkDfVrT5N07D7 , WkDfVrT5N07D8 , WkDfVrT5N07D9 , WkDfVrT5N08D1 , WkDfVrT5N08D2 , WkDfVrT5N08D3 , & + WkDfVrT5N08D4 , WkDfVrT5N08D5 , WkDfVrT5N08D6 , WkDfVrT5N08D7 , WkDfVrT5N08D8 , WkDfVrT5N08D9 , & + WkDfVrT5N09D1 , WkDfVrT5N09D2 , WkDfVrT5N09D3 , WkDfVrT5N09D4 , WkDfVrT5N09D5 , WkDfVrT5N09D6 , & + WkDfVrT5N09D7 , WkDfVrT5N09D8 , WkDfVrT5N09D9 , WkDfVrT5N10D1 , WkDfVrT5N10D2 , WkDfVrT5N10D3 , & + WkDfVrT5N10D4 , WkDfVrT5N10D5 , WkDfVrT5N10D6 , WkDfVrT5N10D7 , WkDfVrT5N10D8 , WkDfVrT5N10D9 , & + WkDfVrT5N11D1 , WkDfVrT5N11D2 , WkDfVrT5N11D3 , WkDfVrT5N11D4 , WkDfVrT5N11D5 , WkDfVrT5N11D6 , & + WkDfVrT5N11D7 , WkDfVrT5N11D8 , WkDfVrT5N11D9 , WkDfVrT5N12D1 , WkDfVrT5N12D2 , WkDfVrT5N12D3 , & + WkDfVrT5N12D4 , WkDfVrT5N12D5 , WkDfVrT5N12D6 , WkDfVrT5N12D7 , WkDfVrT5N12D8 , WkDfVrT5N12D9 , & + WkDfVrT5N13D1 , WkDfVrT5N13D2 , WkDfVrT5N13D3 , WkDfVrT5N13D4 , WkDfVrT5N13D5 , WkDfVrT5N13D6 , & + WkDfVrT5N13D7 , WkDfVrT5N13D8 , WkDfVrT5N13D9 , WkDfVrT5N14D1 , WkDfVrT5N14D2 , WkDfVrT5N14D3 , & + WkDfVrT5N14D4 , WkDfVrT5N14D5 , WkDfVrT5N14D6 , WkDfVrT5N14D7 , WkDfVrT5N14D8 , WkDfVrT5N14D9 , & + WkDfVrT5N15D1 , WkDfVrT5N15D2 , WkDfVrT5N15D3 , WkDfVrT5N15D4 , WkDfVrT5N15D5 , WkDfVrT5N15D6 , & + WkDfVrT5N15D7 , WkDfVrT5N15D8 , WkDfVrT5N15D9 , WkDfVrT5N16D1 , WkDfVrT5N16D2 , WkDfVrT5N16D3 , & + WkDfVrT5N16D4 , WkDfVrT5N16D5 , WkDfVrT5N16D6 , WkDfVrT5N16D7 , WkDfVrT5N16D8 , WkDfVrT5N16D9 , & + WkDfVrT5N17D1 , WkDfVrT5N17D2 , WkDfVrT5N17D3 , WkDfVrT5N17D4 , WkDfVrT5N17D5 , WkDfVrT5N17D6 , & + WkDfVrT5N17D7 , WkDfVrT5N17D8 , WkDfVrT5N17D9 , WkDfVrT5N18D1 , WkDfVrT5N18D2 , WkDfVrT5N18D3 , & + WkDfVrT5N18D4 , WkDfVrT5N18D5 , WkDfVrT5N18D6 , WkDfVrT5N18D7 , WkDfVrT5N18D8 , WkDfVrT5N18D9 , & + WkDfVrT5N19D1 , WkDfVrT5N19D2 , WkDfVrT5N19D3 , WkDfVrT5N19D4 , WkDfVrT5N19D5 , WkDfVrT5N19D6 , & + WkDfVrT5N19D7 , WkDfVrT5N19D8 , WkDfVrT5N19D9 , WkDfVrT5N20D1 , WkDfVrT5N20D2 , WkDfVrT5N20D3 , & + WkDfVrT5N20D4 , WkDfVrT5N20D5 , WkDfVrT5N20D6 , WkDfVrT5N20D7 , WkDfVrT5N20D8 , WkDfVrT5N20D9 , & + WkDfVrT6N01D1 , WkDfVrT6N01D2 , WkDfVrT6N01D3 , WkDfVrT6N01D4 , WkDfVrT6N01D5 , WkDfVrT6N01D6 , & + WkDfVrT6N01D7 , WkDfVrT6N01D8 , WkDfVrT6N01D9 , WkDfVrT6N02D1 , WkDfVrT6N02D2 , WkDfVrT6N02D3 , & + WkDfVrT6N02D4 , WkDfVrT6N02D5 , WkDfVrT6N02D6 , WkDfVrT6N02D7 , WkDfVrT6N02D8 , WkDfVrT6N02D9 , & + WkDfVrT6N03D1 , WkDfVrT6N03D2 , WkDfVrT6N03D3 , WkDfVrT6N03D4 , WkDfVrT6N03D5 , WkDfVrT6N03D6 , & + WkDfVrT6N03D7 , WkDfVrT6N03D8 , WkDfVrT6N03D9 , WkDfVrT6N04D1 , WkDfVrT6N04D2 , WkDfVrT6N04D3 , & + WkDfVrT6N04D4 , WkDfVrT6N04D5 , WkDfVrT6N04D6 , WkDfVrT6N04D7 , WkDfVrT6N04D8 , WkDfVrT6N04D9 , & + WkDfVrT6N05D1 , WkDfVrT6N05D2 , WkDfVrT6N05D3 , WkDfVrT6N05D4 , WkDfVrT6N05D5 , WkDfVrT6N05D6 , & + WkDfVrT6N05D7 , WkDfVrT6N05D8 , WkDfVrT6N05D9 , WkDfVrT6N06D1 , WkDfVrT6N06D2 , WkDfVrT6N06D3 , & + WkDfVrT6N06D4 , WkDfVrT6N06D5 , WkDfVrT6N06D6 , WkDfVrT6N06D7 , WkDfVrT6N06D8 , WkDfVrT6N06D9 , & + WkDfVrT6N07D1 , WkDfVrT6N07D2 , WkDfVrT6N07D3 , WkDfVrT6N07D4 , WkDfVrT6N07D5 , WkDfVrT6N07D6 , & + WkDfVrT6N07D7 , WkDfVrT6N07D8 , WkDfVrT6N07D9 , WkDfVrT6N08D1 , WkDfVrT6N08D2 , WkDfVrT6N08D3 , & + WkDfVrT6N08D4 , WkDfVrT6N08D5 , WkDfVrT6N08D6 , WkDfVrT6N08D7 , WkDfVrT6N08D8 , WkDfVrT6N08D9 , & + WkDfVrT6N09D1 , WkDfVrT6N09D2 , WkDfVrT6N09D3 , WkDfVrT6N09D4 , WkDfVrT6N09D5 , WkDfVrT6N09D6 , & + WkDfVrT6N09D7 , WkDfVrT6N09D8 , WkDfVrT6N09D9 , WkDfVrT6N10D1 , WkDfVrT6N10D2 , WkDfVrT6N10D3 , & + WkDfVrT6N10D4 , WkDfVrT6N10D5 , WkDfVrT6N10D6 , WkDfVrT6N10D7 , WkDfVrT6N10D8 , WkDfVrT6N10D9 , & + WkDfVrT6N11D1 , WkDfVrT6N11D2 , WkDfVrT6N11D3 , WkDfVrT6N11D4 , WkDfVrT6N11D5 , WkDfVrT6N11D6 , & + WkDfVrT6N11D7 , WkDfVrT6N11D8 , WkDfVrT6N11D9 , WkDfVrT6N12D1 , WkDfVrT6N12D2 , WkDfVrT6N12D3 , & + WkDfVrT6N12D4 , WkDfVrT6N12D5 , WkDfVrT6N12D6 , WkDfVrT6N12D7 , WkDfVrT6N12D8 , WkDfVrT6N12D9 , & + WkDfVrT6N13D1 , WkDfVrT6N13D2 , WkDfVrT6N13D3 , WkDfVrT6N13D4 , WkDfVrT6N13D5 , WkDfVrT6N13D6 , & + WkDfVrT6N13D7 , WkDfVrT6N13D8 , WkDfVrT6N13D9 , WkDfVrT6N14D1 , WkDfVrT6N14D2 , WkDfVrT6N14D3 , & + WkDfVrT6N14D4 , WkDfVrT6N14D5 , WkDfVrT6N14D6 , WkDfVrT6N14D7 , WkDfVrT6N14D8 , WkDfVrT6N14D9 , & + WkDfVrT6N15D1 , WkDfVrT6N15D2 , WkDfVrT6N15D3 , WkDfVrT6N15D4 , WkDfVrT6N15D5 , WkDfVrT6N15D6 , & + WkDfVrT6N15D7 , WkDfVrT6N15D8 , WkDfVrT6N15D9 , WkDfVrT6N16D1 , WkDfVrT6N16D2 , WkDfVrT6N16D3 , & + WkDfVrT6N16D4 , WkDfVrT6N16D5 , WkDfVrT6N16D6 , WkDfVrT6N16D7 , WkDfVrT6N16D8 , WkDfVrT6N16D9 , & + WkDfVrT6N17D1 , WkDfVrT6N17D2 , WkDfVrT6N17D3 , WkDfVrT6N17D4 , WkDfVrT6N17D5 , WkDfVrT6N17D6 , & + WkDfVrT6N17D7 , WkDfVrT6N17D8 , WkDfVrT6N17D9 , WkDfVrT6N18D1 , WkDfVrT6N18D2 , WkDfVrT6N18D3 , & + WkDfVrT6N18D4 , WkDfVrT6N18D5 , WkDfVrT6N18D6 , WkDfVrT6N18D7 , WkDfVrT6N18D8 , WkDfVrT6N18D9 , & + WkDfVrT6N19D1 , WkDfVrT6N19D2 , WkDfVrT6N19D3 , WkDfVrT6N19D4 , WkDfVrT6N19D5 , WkDfVrT6N19D6 , & + WkDfVrT6N19D7 , WkDfVrT6N19D8 , WkDfVrT6N19D9 , WkDfVrT6N20D1 , WkDfVrT6N20D2 , WkDfVrT6N20D3 , & + WkDfVrT6N20D4 , WkDfVrT6N20D5 , WkDfVrT6N20D6 , WkDfVrT6N20D7 , WkDfVrT6N20D8 , WkDfVrT6N20D9 , & + WkDfVrT7N01D1 , WkDfVrT7N01D2 , WkDfVrT7N01D3 , WkDfVrT7N01D4 , WkDfVrT7N01D5 , WkDfVrT7N01D6 , & + WkDfVrT7N01D7 , WkDfVrT7N01D8 , WkDfVrT7N01D9 , WkDfVrT7N02D1 , WkDfVrT7N02D2 , WkDfVrT7N02D3 , & + WkDfVrT7N02D4 , WkDfVrT7N02D5 , WkDfVrT7N02D6 , WkDfVrT7N02D7 , WkDfVrT7N02D8 , WkDfVrT7N02D9 , & + WkDfVrT7N03D1 , WkDfVrT7N03D2 , WkDfVrT7N03D3 , WkDfVrT7N03D4 , WkDfVrT7N03D5 , WkDfVrT7N03D6 , & + WkDfVrT7N03D7 , WkDfVrT7N03D8 , WkDfVrT7N03D9 , WkDfVrT7N04D1 , WkDfVrT7N04D2 , WkDfVrT7N04D3 /) + INTEGER(IntKi), PARAMETER :: ParamIndxAry6(1356) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + WkDfVrT7N04D4 , WkDfVrT7N04D5 , WkDfVrT7N04D6 , WkDfVrT7N04D7 , WkDfVrT7N04D8 , WkDfVrT7N04D9 , & + WkDfVrT7N05D1 , WkDfVrT7N05D2 , WkDfVrT7N05D3 , WkDfVrT7N05D4 , WkDfVrT7N05D5 , WkDfVrT7N05D6 , & + WkDfVrT7N05D7 , WkDfVrT7N05D8 , WkDfVrT7N05D9 , WkDfVrT7N06D1 , WkDfVrT7N06D2 , WkDfVrT7N06D3 , & + WkDfVrT7N06D4 , WkDfVrT7N06D5 , WkDfVrT7N06D6 , WkDfVrT7N06D7 , WkDfVrT7N06D8 , WkDfVrT7N06D9 , & + WkDfVrT7N07D1 , WkDfVrT7N07D2 , WkDfVrT7N07D3 , WkDfVrT7N07D4 , WkDfVrT7N07D5 , WkDfVrT7N07D6 , & + WkDfVrT7N07D7 , WkDfVrT7N07D8 , WkDfVrT7N07D9 , WkDfVrT7N08D1 , WkDfVrT7N08D2 , WkDfVrT7N08D3 , & + WkDfVrT7N08D4 , WkDfVrT7N08D5 , WkDfVrT7N08D6 , WkDfVrT7N08D7 , WkDfVrT7N08D8 , WkDfVrT7N08D9 , & + WkDfVrT7N09D1 , WkDfVrT7N09D2 , WkDfVrT7N09D3 , WkDfVrT7N09D4 , WkDfVrT7N09D5 , WkDfVrT7N09D6 , & + WkDfVrT7N09D7 , WkDfVrT7N09D8 , WkDfVrT7N09D9 , WkDfVrT7N10D1 , WkDfVrT7N10D2 , WkDfVrT7N10D3 , & + WkDfVrT7N10D4 , WkDfVrT7N10D5 , WkDfVrT7N10D6 , WkDfVrT7N10D7 , WkDfVrT7N10D8 , WkDfVrT7N10D9 , & + WkDfVrT7N11D1 , WkDfVrT7N11D2 , WkDfVrT7N11D3 , WkDfVrT7N11D4 , WkDfVrT7N11D5 , WkDfVrT7N11D6 , & + WkDfVrT7N11D7 , WkDfVrT7N11D8 , WkDfVrT7N11D9 , WkDfVrT7N12D1 , WkDfVrT7N12D2 , WkDfVrT7N12D3 , & + WkDfVrT7N12D4 , WkDfVrT7N12D5 , WkDfVrT7N12D6 , WkDfVrT7N12D7 , WkDfVrT7N12D8 , WkDfVrT7N12D9 , & + WkDfVrT7N13D1 , WkDfVrT7N13D2 , WkDfVrT7N13D3 , WkDfVrT7N13D4 , WkDfVrT7N13D5 , WkDfVrT7N13D6 , & + WkDfVrT7N13D7 , WkDfVrT7N13D8 , WkDfVrT7N13D9 , WkDfVrT7N14D1 , WkDfVrT7N14D2 , WkDfVrT7N14D3 , & + WkDfVrT7N14D4 , WkDfVrT7N14D5 , WkDfVrT7N14D6 , WkDfVrT7N14D7 , WkDfVrT7N14D8 , WkDfVrT7N14D9 , & + WkDfVrT7N15D1 , WkDfVrT7N15D2 , WkDfVrT7N15D3 , WkDfVrT7N15D4 , WkDfVrT7N15D5 , WkDfVrT7N15D6 , & + WkDfVrT7N15D7 , WkDfVrT7N15D8 , WkDfVrT7N15D9 , WkDfVrT7N16D1 , WkDfVrT7N16D2 , WkDfVrT7N16D3 , & + WkDfVrT7N16D4 , WkDfVrT7N16D5 , WkDfVrT7N16D6 , WkDfVrT7N16D7 , WkDfVrT7N16D8 , WkDfVrT7N16D9 , & + WkDfVrT7N17D1 , WkDfVrT7N17D2 , WkDfVrT7N17D3 , WkDfVrT7N17D4 , WkDfVrT7N17D5 , WkDfVrT7N17D6 , & + WkDfVrT7N17D7 , WkDfVrT7N17D8 , WkDfVrT7N17D9 , WkDfVrT7N18D1 , WkDfVrT7N18D2 , WkDfVrT7N18D3 , & + WkDfVrT7N18D4 , WkDfVrT7N18D5 , WkDfVrT7N18D6 , WkDfVrT7N18D7 , WkDfVrT7N18D8 , WkDfVrT7N18D9 , & + WkDfVrT7N19D1 , WkDfVrT7N19D2 , WkDfVrT7N19D3 , WkDfVrT7N19D4 , WkDfVrT7N19D5 , WkDfVrT7N19D6 , & + WkDfVrT7N19D7 , WkDfVrT7N19D8 , WkDfVrT7N19D9 , WkDfVrT7N20D1 , WkDfVrT7N20D2 , WkDfVrT7N20D3 , & + WkDfVrT7N20D4 , WkDfVrT7N20D5 , WkDfVrT7N20D6 , WkDfVrT7N20D7 , WkDfVrT7N20D8 , WkDfVrT7N20D9 , & + WkDfVrT8N01D1 , WkDfVrT8N01D2 , WkDfVrT8N01D3 , WkDfVrT8N01D4 , WkDfVrT8N01D5 , WkDfVrT8N01D6 , & + WkDfVrT8N01D7 , WkDfVrT8N01D8 , WkDfVrT8N01D9 , WkDfVrT8N02D1 , WkDfVrT8N02D2 , WkDfVrT8N02D3 , & + WkDfVrT8N02D4 , WkDfVrT8N02D5 , WkDfVrT8N02D6 , WkDfVrT8N02D7 , WkDfVrT8N02D8 , WkDfVrT8N02D9 , & + WkDfVrT8N03D1 , WkDfVrT8N03D2 , WkDfVrT8N03D3 , WkDfVrT8N03D4 , WkDfVrT8N03D5 , WkDfVrT8N03D6 , & + WkDfVrT8N03D7 , WkDfVrT8N03D8 , WkDfVrT8N03D9 , WkDfVrT8N04D1 , WkDfVrT8N04D2 , WkDfVrT8N04D3 , & + WkDfVrT8N04D4 , WkDfVrT8N04D5 , WkDfVrT8N04D6 , WkDfVrT8N04D7 , WkDfVrT8N04D8 , WkDfVrT8N04D9 , & + WkDfVrT8N05D1 , WkDfVrT8N05D2 , WkDfVrT8N05D3 , WkDfVrT8N05D4 , WkDfVrT8N05D5 , WkDfVrT8N05D6 , & + WkDfVrT8N05D7 , WkDfVrT8N05D8 , WkDfVrT8N05D9 , WkDfVrT8N06D1 , WkDfVrT8N06D2 , WkDfVrT8N06D3 , & + WkDfVrT8N06D4 , WkDfVrT8N06D5 , WkDfVrT8N06D6 , WkDfVrT8N06D7 , WkDfVrT8N06D8 , WkDfVrT8N06D9 , & + WkDfVrT8N07D1 , WkDfVrT8N07D2 , WkDfVrT8N07D3 , WkDfVrT8N07D4 , WkDfVrT8N07D5 , WkDfVrT8N07D6 , & + WkDfVrT8N07D7 , WkDfVrT8N07D8 , WkDfVrT8N07D9 , WkDfVrT8N08D1 , WkDfVrT8N08D2 , WkDfVrT8N08D3 , & + WkDfVrT8N08D4 , WkDfVrT8N08D5 , WkDfVrT8N08D6 , WkDfVrT8N08D7 , WkDfVrT8N08D8 , WkDfVrT8N08D9 , & + WkDfVrT8N09D1 , WkDfVrT8N09D2 , WkDfVrT8N09D3 , WkDfVrT8N09D4 , WkDfVrT8N09D5 , WkDfVrT8N09D6 , & + WkDfVrT8N09D7 , WkDfVrT8N09D8 , WkDfVrT8N09D9 , WkDfVrT8N10D1 , WkDfVrT8N10D2 , WkDfVrT8N10D3 , & + WkDfVrT8N10D4 , WkDfVrT8N10D5 , WkDfVrT8N10D6 , WkDfVrT8N10D7 , WkDfVrT8N10D8 , WkDfVrT8N10D9 , & + WkDfVrT8N11D1 , WkDfVrT8N11D2 , WkDfVrT8N11D3 , WkDfVrT8N11D4 , WkDfVrT8N11D5 , WkDfVrT8N11D6 , & + WkDfVrT8N11D7 , WkDfVrT8N11D8 , WkDfVrT8N11D9 , WkDfVrT8N12D1 , WkDfVrT8N12D2 , WkDfVrT8N12D3 , & + WkDfVrT8N12D4 , WkDfVrT8N12D5 , WkDfVrT8N12D6 , WkDfVrT8N12D7 , WkDfVrT8N12D8 , WkDfVrT8N12D9 , & + WkDfVrT8N13D1 , WkDfVrT8N13D2 , WkDfVrT8N13D3 , WkDfVrT8N13D4 , WkDfVrT8N13D5 , WkDfVrT8N13D6 , & + WkDfVrT8N13D7 , WkDfVrT8N13D8 , WkDfVrT8N13D9 , WkDfVrT8N14D1 , WkDfVrT8N14D2 , WkDfVrT8N14D3 , & + WkDfVrT8N14D4 , WkDfVrT8N14D5 , WkDfVrT8N14D6 , WkDfVrT8N14D7 , WkDfVrT8N14D8 , WkDfVrT8N14D9 , & + WkDfVrT8N15D1 , WkDfVrT8N15D2 , WkDfVrT8N15D3 , WkDfVrT8N15D4 , WkDfVrT8N15D5 , WkDfVrT8N15D6 , & + WkDfVrT8N15D7 , WkDfVrT8N15D8 , WkDfVrT8N15D9 , WkDfVrT8N16D1 , WkDfVrT8N16D2 , WkDfVrT8N16D3 , & + WkDfVrT8N16D4 , WkDfVrT8N16D5 , WkDfVrT8N16D6 , WkDfVrT8N16D7 , WkDfVrT8N16D8 , WkDfVrT8N16D9 , & + WkDfVrT8N17D1 , WkDfVrT8N17D2 , WkDfVrT8N17D3 , WkDfVrT8N17D4 , WkDfVrT8N17D5 , WkDfVrT8N17D6 , & + WkDfVrT8N17D7 , WkDfVrT8N17D8 , WkDfVrT8N17D9 , WkDfVrT8N18D1 , WkDfVrT8N18D2 , WkDfVrT8N18D3 , & + WkDfVrT8N18D4 , WkDfVrT8N18D5 , WkDfVrT8N18D6 , WkDfVrT8N18D7 , WkDfVrT8N18D8 , WkDfVrT8N18D9 , & + WkDfVrT8N19D1 , WkDfVrT8N19D2 , WkDfVrT8N19D3 , WkDfVrT8N19D4 , WkDfVrT8N19D5 , WkDfVrT8N19D6 , & + WkDfVrT8N19D7 , WkDfVrT8N19D8 , WkDfVrT8N19D9 , WkDfVrT8N20D1 , WkDfVrT8N20D2 , WkDfVrT8N20D3 , & + WkDfVrT8N20D4 , WkDfVrT8N20D5 , WkDfVrT8N20D6 , WkDfVrT8N20D7 , WkDfVrT8N20D8 , WkDfVrT8N20D9 , & + WkDfVrT9N01D1 , WkDfVrT9N01D2 , WkDfVrT9N01D3 , WkDfVrT9N01D4 , WkDfVrT9N01D5 , WkDfVrT9N01D6 , & + WkDfVrT9N01D7 , WkDfVrT9N01D8 , WkDfVrT9N01D9 , WkDfVrT9N02D1 , WkDfVrT9N02D2 , WkDfVrT9N02D3 , & + WkDfVrT9N02D4 , WkDfVrT9N02D5 , WkDfVrT9N02D6 , WkDfVrT9N02D7 , WkDfVrT9N02D8 , WkDfVrT9N02D9 , & + WkDfVrT9N03D1 , WkDfVrT9N03D2 , WkDfVrT9N03D3 , WkDfVrT9N03D4 , WkDfVrT9N03D5 , WkDfVrT9N03D6 , & + WkDfVrT9N03D7 , WkDfVrT9N03D8 , WkDfVrT9N03D9 , WkDfVrT9N04D1 , WkDfVrT9N04D2 , WkDfVrT9N04D3 , & + WkDfVrT9N04D4 , WkDfVrT9N04D5 , WkDfVrT9N04D6 , WkDfVrT9N04D7 , WkDfVrT9N04D8 , WkDfVrT9N04D9 , & + WkDfVrT9N05D1 , WkDfVrT9N05D2 , WkDfVrT9N05D3 , WkDfVrT9N05D4 , WkDfVrT9N05D5 , WkDfVrT9N05D6 , & + WkDfVrT9N05D7 , WkDfVrT9N05D8 , WkDfVrT9N05D9 , WkDfVrT9N06D1 , WkDfVrT9N06D2 , WkDfVrT9N06D3 , & + WkDfVrT9N06D4 , WkDfVrT9N06D5 , WkDfVrT9N06D6 , WkDfVrT9N06D7 , WkDfVrT9N06D8 , WkDfVrT9N06D9 , & + WkDfVrT9N07D1 , WkDfVrT9N07D2 , WkDfVrT9N07D3 , WkDfVrT9N07D4 , WkDfVrT9N07D5 , WkDfVrT9N07D6 , & + WkDfVrT9N07D7 , WkDfVrT9N07D8 , WkDfVrT9N07D9 , WkDfVrT9N08D1 , WkDfVrT9N08D2 , WkDfVrT9N08D3 , & + WkDfVrT9N08D4 , WkDfVrT9N08D5 , WkDfVrT9N08D6 , WkDfVrT9N08D7 , WkDfVrT9N08D8 , WkDfVrT9N08D9 , & + WkDfVrT9N09D1 , WkDfVrT9N09D2 , WkDfVrT9N09D3 , WkDfVrT9N09D4 , WkDfVrT9N09D5 , WkDfVrT9N09D6 , & + WkDfVrT9N09D7 , WkDfVrT9N09D8 , WkDfVrT9N09D9 , WkDfVrT9N10D1 , WkDfVrT9N10D2 , WkDfVrT9N10D3 , & + WkDfVrT9N10D4 , WkDfVrT9N10D5 , WkDfVrT9N10D6 , WkDfVrT9N10D7 , WkDfVrT9N10D8 , WkDfVrT9N10D9 , & + WkDfVrT9N11D1 , WkDfVrT9N11D2 , WkDfVrT9N11D3 , WkDfVrT9N11D4 , WkDfVrT9N11D5 , WkDfVrT9N11D6 , & + WkDfVrT9N11D7 , WkDfVrT9N11D8 , WkDfVrT9N11D9 , WkDfVrT9N12D1 , WkDfVrT9N12D2 , WkDfVrT9N12D3 , & + WkDfVrT9N12D4 , WkDfVrT9N12D5 , WkDfVrT9N12D6 , WkDfVrT9N12D7 , WkDfVrT9N12D8 , WkDfVrT9N12D9 , & + WkDfVrT9N13D1 , WkDfVrT9N13D2 , WkDfVrT9N13D3 , WkDfVrT9N13D4 , WkDfVrT9N13D5 , WkDfVrT9N13D6 , & + WkDfVrT9N13D7 , WkDfVrT9N13D8 , WkDfVrT9N13D9 , WkDfVrT9N14D1 , WkDfVrT9N14D2 , WkDfVrT9N14D3 , & + WkDfVrT9N14D4 , WkDfVrT9N14D5 , WkDfVrT9N14D6 , WkDfVrT9N14D7 , WkDfVrT9N14D8 , WkDfVrT9N14D9 , & + WkDfVrT9N15D1 , WkDfVrT9N15D2 , WkDfVrT9N15D3 , WkDfVrT9N15D4 , WkDfVrT9N15D5 , WkDfVrT9N15D6 , & + WkDfVrT9N15D7 , WkDfVrT9N15D8 , WkDfVrT9N15D9 , WkDfVrT9N16D1 , WkDfVrT9N16D2 , WkDfVrT9N16D3 , & + WkDfVrT9N16D4 , WkDfVrT9N16D5 , WkDfVrT9N16D6 , WkDfVrT9N16D7 , WkDfVrT9N16D8 , WkDfVrT9N16D9 , & + WkDfVrT9N17D1 , WkDfVrT9N17D2 , WkDfVrT9N17D3 , WkDfVrT9N17D4 , WkDfVrT9N17D5 , WkDfVrT9N17D6 , & + WkDfVrT9N17D7 , WkDfVrT9N17D8 , WkDfVrT9N17D9 , WkDfVrT9N18D1 , WkDfVrT9N18D2 , WkDfVrT9N18D3 , & + WkDfVrT9N18D4 , WkDfVrT9N18D5 , WkDfVrT9N18D6 , WkDfVrT9N18D7 , WkDfVrT9N18D8 , WkDfVrT9N18D9 , & + WkDfVrT9N19D1 , WkDfVrT9N19D2 , WkDfVrT9N19D3 , WkDfVrT9N19D4 , WkDfVrT9N19D5 , WkDfVrT9N19D6 , & + WkDfVrT9N19D7 , WkDfVrT9N19D8 , WkDfVrT9N19D9 , WkDfVrT9N20D1 , WkDfVrT9N20D2 , WkDfVrT9N20D3 , & + WkDfVrT9N20D4 , WkDfVrT9N20D5 , WkDfVrT9N20D6 , WkDfVrT9N20D7 , WkDfVrT9N20D8 , WkDfVrT9N20D9 , & + WkDfVxT1N01D1 , WkDfVxT1N01D2 , WkDfVxT1N01D3 , WkDfVxT1N01D4 , WkDfVxT1N01D5 , WkDfVxT1N01D6 , & + WkDfVxT1N01D7 , WkDfVxT1N01D8 , WkDfVxT1N01D9 , WkDfVxT1N02D1 , WkDfVxT1N02D2 , WkDfVxT1N02D3 , & + WkDfVxT1N02D4 , WkDfVxT1N02D5 , WkDfVxT1N02D6 , WkDfVxT1N02D7 , WkDfVxT1N02D8 , WkDfVxT1N02D9 , & + WkDfVxT1N03D1 , WkDfVxT1N03D2 , WkDfVxT1N03D3 , WkDfVxT1N03D4 , WkDfVxT1N03D5 , WkDfVxT1N03D6 , & + WkDfVxT1N03D7 , WkDfVxT1N03D8 , WkDfVxT1N03D9 , WkDfVxT1N04D1 , WkDfVxT1N04D2 , WkDfVxT1N04D3 , & + WkDfVxT1N04D4 , WkDfVxT1N04D5 , WkDfVxT1N04D6 , WkDfVxT1N04D7 , WkDfVxT1N04D8 , WkDfVxT1N04D9 , & + WkDfVxT1N05D1 , WkDfVxT1N05D2 , WkDfVxT1N05D3 , WkDfVxT1N05D4 , WkDfVxT1N05D5 , WkDfVxT1N05D6 , & + WkDfVxT1N05D7 , WkDfVxT1N05D8 , WkDfVxT1N05D9 , WkDfVxT1N06D1 , WkDfVxT1N06D2 , WkDfVxT1N06D3 , & + WkDfVxT1N06D4 , WkDfVxT1N06D5 , WkDfVxT1N06D6 , WkDfVxT1N06D7 , WkDfVxT1N06D8 , WkDfVxT1N06D9 , & + WkDfVxT1N07D1 , WkDfVxT1N07D2 , WkDfVxT1N07D3 , WkDfVxT1N07D4 , WkDfVxT1N07D5 , WkDfVxT1N07D6 , & + WkDfVxT1N07D7 , WkDfVxT1N07D8 , WkDfVxT1N07D9 , WkDfVxT1N08D1 , WkDfVxT1N08D2 , WkDfVxT1N08D3 , & + WkDfVxT1N08D4 , WkDfVxT1N08D5 , WkDfVxT1N08D6 , WkDfVxT1N08D7 , WkDfVxT1N08D8 , WkDfVxT1N08D9 , & + WkDfVxT1N09D1 , WkDfVxT1N09D2 , WkDfVxT1N09D3 , WkDfVxT1N09D4 , WkDfVxT1N09D5 , WkDfVxT1N09D6 , & + WkDfVxT1N09D7 , WkDfVxT1N09D8 , WkDfVxT1N09D9 , WkDfVxT1N10D1 , WkDfVxT1N10D2 , WkDfVxT1N10D3 , & + WkDfVxT1N10D4 , WkDfVxT1N10D5 , WkDfVxT1N10D6 , WkDfVxT1N10D7 , WkDfVxT1N10D8 , WkDfVxT1N10D9 , & + WkDfVxT1N11D1 , WkDfVxT1N11D2 , WkDfVxT1N11D3 , WkDfVxT1N11D4 , WkDfVxT1N11D5 , WkDfVxT1N11D6 , & + WkDfVxT1N11D7 , WkDfVxT1N11D8 , WkDfVxT1N11D9 , WkDfVxT1N12D1 , WkDfVxT1N12D2 , WkDfVxT1N12D3 , & + WkDfVxT1N12D4 , WkDfVxT1N12D5 , WkDfVxT1N12D6 , WkDfVxT1N12D7 , WkDfVxT1N12D8 , WkDfVxT1N12D9 , & + WkDfVxT1N13D1 , WkDfVxT1N13D2 , WkDfVxT1N13D3 , WkDfVxT1N13D4 , WkDfVxT1N13D5 , WkDfVxT1N13D6 , & + WkDfVxT1N13D7 , WkDfVxT1N13D8 , WkDfVxT1N13D9 , WkDfVxT1N14D1 , WkDfVxT1N14D2 , WkDfVxT1N14D3 , & + WkDfVxT1N14D4 , WkDfVxT1N14D5 , WkDfVxT1N14D6 , WkDfVxT1N14D7 , WkDfVxT1N14D8 , WkDfVxT1N14D9 , & + WkDfVxT1N15D1 , WkDfVxT1N15D2 , WkDfVxT1N15D3 , WkDfVxT1N15D4 , WkDfVxT1N15D5 , WkDfVxT1N15D6 , & + WkDfVxT1N15D7 , WkDfVxT1N15D8 , WkDfVxT1N15D9 , WkDfVxT1N16D1 , WkDfVxT1N16D2 , WkDfVxT1N16D3 , & + WkDfVxT1N16D4 , WkDfVxT1N16D5 , WkDfVxT1N16D6 , WkDfVxT1N16D7 , WkDfVxT1N16D8 , WkDfVxT1N16D9 , & + WkDfVxT1N17D1 , WkDfVxT1N17D2 , WkDfVxT1N17D3 , WkDfVxT1N17D4 , WkDfVxT1N17D5 , WkDfVxT1N17D6 , & + WkDfVxT1N17D7 , WkDfVxT1N17D8 , WkDfVxT1N17D9 , WkDfVxT1N18D1 , WkDfVxT1N18D2 , WkDfVxT1N18D3 , & + WkDfVxT1N18D4 , WkDfVxT1N18D5 , WkDfVxT1N18D6 , WkDfVxT1N18D7 , WkDfVxT1N18D8 , WkDfVxT1N18D9 , & + WkDfVxT1N19D1 , WkDfVxT1N19D2 , WkDfVxT1N19D3 , WkDfVxT1N19D4 , WkDfVxT1N19D5 , WkDfVxT1N19D6 , & + WkDfVxT1N19D7 , WkDfVxT1N19D8 , WkDfVxT1N19D9 , WkDfVxT1N20D1 , WkDfVxT1N20D2 , WkDfVxT1N20D3 , & + WkDfVxT1N20D4 , WkDfVxT1N20D5 , WkDfVxT1N20D6 , WkDfVxT1N20D7 , WkDfVxT1N20D8 , WkDfVxT1N20D9 , & + WkDfVxT2N01D1 , WkDfVxT2N01D2 , WkDfVxT2N01D3 , WkDfVxT2N01D4 , WkDfVxT2N01D5 , WkDfVxT2N01D6 , & + WkDfVxT2N01D7 , WkDfVxT2N01D8 , WkDfVxT2N01D9 , WkDfVxT2N02D1 , WkDfVxT2N02D2 , WkDfVxT2N02D3 , & + WkDfVxT2N02D4 , WkDfVxT2N02D5 , WkDfVxT2N02D6 , WkDfVxT2N02D7 , WkDfVxT2N02D8 , WkDfVxT2N02D9 , & + WkDfVxT2N03D1 , WkDfVxT2N03D2 , WkDfVxT2N03D3 , WkDfVxT2N03D4 , WkDfVxT2N03D5 , WkDfVxT2N03D6 , & + WkDfVxT2N03D7 , WkDfVxT2N03D8 , WkDfVxT2N03D9 , WkDfVxT2N04D1 , WkDfVxT2N04D2 , WkDfVxT2N04D3 , & + WkDfVxT2N04D4 , WkDfVxT2N04D5 , WkDfVxT2N04D6 , WkDfVxT2N04D7 , WkDfVxT2N04D8 , WkDfVxT2N04D9 , & + WkDfVxT2N05D1 , WkDfVxT2N05D2 , WkDfVxT2N05D3 , WkDfVxT2N05D4 , WkDfVxT2N05D5 , WkDfVxT2N05D6 , & + WkDfVxT2N05D7 , WkDfVxT2N05D8 , WkDfVxT2N05D9 , WkDfVxT2N06D1 , WkDfVxT2N06D2 , WkDfVxT2N06D3 , & + WkDfVxT2N06D4 , WkDfVxT2N06D5 , WkDfVxT2N06D6 , WkDfVxT2N06D7 , WkDfVxT2N06D8 , WkDfVxT2N06D9 , & + WkDfVxT2N07D1 , WkDfVxT2N07D2 , WkDfVxT2N07D3 , WkDfVxT2N07D4 , WkDfVxT2N07D5 , WkDfVxT2N07D6 , & + WkDfVxT2N07D7 , WkDfVxT2N07D8 , WkDfVxT2N07D9 , WkDfVxT2N08D1 , WkDfVxT2N08D2 , WkDfVxT2N08D3 , & + WkDfVxT2N08D4 , WkDfVxT2N08D5 , WkDfVxT2N08D6 , WkDfVxT2N08D7 , WkDfVxT2N08D8 , WkDfVxT2N08D9 , & + WkDfVxT2N09D1 , WkDfVxT2N09D2 , WkDfVxT2N09D3 , WkDfVxT2N09D4 , WkDfVxT2N09D5 , WkDfVxT2N09D6 , & + WkDfVxT2N09D7 , WkDfVxT2N09D8 , WkDfVxT2N09D9 , WkDfVxT2N10D1 , WkDfVxT2N10D2 , WkDfVxT2N10D3 , & + WkDfVxT2N10D4 , WkDfVxT2N10D5 , WkDfVxT2N10D6 , WkDfVxT2N10D7 , WkDfVxT2N10D8 , WkDfVxT2N10D9 , & + WkDfVxT2N11D1 , WkDfVxT2N11D2 , WkDfVxT2N11D3 , WkDfVxT2N11D4 , WkDfVxT2N11D5 , WkDfVxT2N11D6 , & + WkDfVxT2N11D7 , WkDfVxT2N11D8 , WkDfVxT2N11D9 , WkDfVxT2N12D1 , WkDfVxT2N12D2 , WkDfVxT2N12D3 , & + WkDfVxT2N12D4 , WkDfVxT2N12D5 , WkDfVxT2N12D6 , WkDfVxT2N12D7 , WkDfVxT2N12D8 , WkDfVxT2N12D9 , & + WkDfVxT2N13D1 , WkDfVxT2N13D2 , WkDfVxT2N13D3 , WkDfVxT2N13D4 , WkDfVxT2N13D5 , WkDfVxT2N13D6 , & + WkDfVxT2N13D7 , WkDfVxT2N13D8 , WkDfVxT2N13D9 , WkDfVxT2N14D1 , WkDfVxT2N14D2 , WkDfVxT2N14D3 , & + WkDfVxT2N14D4 , WkDfVxT2N14D5 , WkDfVxT2N14D6 , WkDfVxT2N14D7 , WkDfVxT2N14D8 , WkDfVxT2N14D9 , & + WkDfVxT2N15D1 , WkDfVxT2N15D2 , WkDfVxT2N15D3 , WkDfVxT2N15D4 , WkDfVxT2N15D5 , WkDfVxT2N15D6 , & + WkDfVxT2N15D7 , WkDfVxT2N15D8 , WkDfVxT2N15D9 , WkDfVxT2N16D1 , WkDfVxT2N16D2 , WkDfVxT2N16D3 , & + WkDfVxT2N16D4 , WkDfVxT2N16D5 , WkDfVxT2N16D6 , WkDfVxT2N16D7 , WkDfVxT2N16D8 , WkDfVxT2N16D9 , & + WkDfVxT2N17D1 , WkDfVxT2N17D2 , WkDfVxT2N17D3 , WkDfVxT2N17D4 , WkDfVxT2N17D5 , WkDfVxT2N17D6 , & + WkDfVxT2N17D7 , WkDfVxT2N17D8 , WkDfVxT2N17D9 , WkDfVxT2N18D1 , WkDfVxT2N18D2 , WkDfVxT2N18D3 , & + WkDfVxT2N18D4 , WkDfVxT2N18D5 , WkDfVxT2N18D6 , WkDfVxT2N18D7 , WkDfVxT2N18D8 , WkDfVxT2N18D9 , & + WkDfVxT2N19D1 , WkDfVxT2N19D2 , WkDfVxT2N19D3 , WkDfVxT2N19D4 , WkDfVxT2N19D5 , WkDfVxT2N19D6 , & + WkDfVxT2N19D7 , WkDfVxT2N19D8 , WkDfVxT2N19D9 , WkDfVxT2N20D1 , WkDfVxT2N20D2 , WkDfVxT2N20D3 , & + WkDfVxT2N20D4 , WkDfVxT2N20D5 , WkDfVxT2N20D6 , WkDfVxT2N20D7 , WkDfVxT2N20D8 , WkDfVxT2N20D9 , & + WkDfVxT3N01D1 , WkDfVxT3N01D2 , WkDfVxT3N01D3 , WkDfVxT3N01D4 , WkDfVxT3N01D5 , WkDfVxT3N01D6 , & + WkDfVxT3N01D7 , WkDfVxT3N01D8 , WkDfVxT3N01D9 , WkDfVxT3N02D1 , WkDfVxT3N02D2 , WkDfVxT3N02D3 , & + WkDfVxT3N02D4 , WkDfVxT3N02D5 , WkDfVxT3N02D6 , WkDfVxT3N02D7 , WkDfVxT3N02D8 , WkDfVxT3N02D9 , & + WkDfVxT3N03D1 , WkDfVxT3N03D2 , WkDfVxT3N03D3 , WkDfVxT3N03D4 , WkDfVxT3N03D5 , WkDfVxT3N03D6 , & + WkDfVxT3N03D7 , WkDfVxT3N03D8 , WkDfVxT3N03D9 , WkDfVxT3N04D1 , WkDfVxT3N04D2 , WkDfVxT3N04D3 , & + WkDfVxT3N04D4 , WkDfVxT3N04D5 , WkDfVxT3N04D6 , WkDfVxT3N04D7 , WkDfVxT3N04D8 , WkDfVxT3N04D9 , & + WkDfVxT3N05D1 , WkDfVxT3N05D2 , WkDfVxT3N05D3 , WkDfVxT3N05D4 , WkDfVxT3N05D5 , WkDfVxT3N05D6 , & + WkDfVxT3N05D7 , WkDfVxT3N05D8 , WkDfVxT3N05D9 , WkDfVxT3N06D1 , WkDfVxT3N06D2 , WkDfVxT3N06D3 , & + WkDfVxT3N06D4 , WkDfVxT3N06D5 , WkDfVxT3N06D6 , WkDfVxT3N06D7 , WkDfVxT3N06D8 , WkDfVxT3N06D9 , & + WkDfVxT3N07D1 , WkDfVxT3N07D2 , WkDfVxT3N07D3 , WkDfVxT3N07D4 , WkDfVxT3N07D5 , WkDfVxT3N07D6 , & + WkDfVxT3N07D7 , WkDfVxT3N07D8 , WkDfVxT3N07D9 , WkDfVxT3N08D1 , WkDfVxT3N08D2 , WkDfVxT3N08D3 , & + WkDfVxT3N08D4 , WkDfVxT3N08D5 , WkDfVxT3N08D6 , WkDfVxT3N08D7 , WkDfVxT3N08D8 , WkDfVxT3N08D9 , & + WkDfVxT3N09D1 , WkDfVxT3N09D2 , WkDfVxT3N09D3 , WkDfVxT3N09D4 , WkDfVxT3N09D5 , WkDfVxT3N09D6 , & + WkDfVxT3N09D7 , WkDfVxT3N09D8 , WkDfVxT3N09D9 , WkDfVxT3N10D1 , WkDfVxT3N10D2 , WkDfVxT3N10D3 , & + WkDfVxT3N10D4 , WkDfVxT3N10D5 , WkDfVxT3N10D6 , WkDfVxT3N10D7 , WkDfVxT3N10D8 , WkDfVxT3N10D9 , & + WkDfVxT3N11D1 , WkDfVxT3N11D2 , WkDfVxT3N11D3 , WkDfVxT3N11D4 , WkDfVxT3N11D5 , WkDfVxT3N11D6 , & + WkDfVxT3N11D7 , WkDfVxT3N11D8 , WkDfVxT3N11D9 , WkDfVxT3N12D1 , WkDfVxT3N12D2 , WkDfVxT3N12D3 , & + WkDfVxT3N12D4 , WkDfVxT3N12D5 , WkDfVxT3N12D6 , WkDfVxT3N12D7 , WkDfVxT3N12D8 , WkDfVxT3N12D9 , & + WkDfVxT3N13D1 , WkDfVxT3N13D2 , WkDfVxT3N13D3 , WkDfVxT3N13D4 , WkDfVxT3N13D5 , WkDfVxT3N13D6 , & + WkDfVxT3N13D7 , WkDfVxT3N13D8 , WkDfVxT3N13D9 , WkDfVxT3N14D1 , WkDfVxT3N14D2 , WkDfVxT3N14D3 , & + WkDfVxT3N14D4 , WkDfVxT3N14D5 , WkDfVxT3N14D6 , WkDfVxT3N14D7 , WkDfVxT3N14D8 , WkDfVxT3N14D9 , & + WkDfVxT3N15D1 , WkDfVxT3N15D2 , WkDfVxT3N15D3 , WkDfVxT3N15D4 , WkDfVxT3N15D5 , WkDfVxT3N15D6 , & + WkDfVxT3N15D7 , WkDfVxT3N15D8 , WkDfVxT3N15D9 , WkDfVxT3N16D1 , WkDfVxT3N16D2 , WkDfVxT3N16D3 , & + WkDfVxT3N16D4 , WkDfVxT3N16D5 , WkDfVxT3N16D6 , WkDfVxT3N16D7 , WkDfVxT3N16D8 , WkDfVxT3N16D9 , & + WkDfVxT3N17D1 , WkDfVxT3N17D2 , WkDfVxT3N17D3 , WkDfVxT3N17D4 , WkDfVxT3N17D5 , WkDfVxT3N17D6 , & + WkDfVxT3N17D7 , WkDfVxT3N17D8 , WkDfVxT3N17D9 , WkDfVxT3N18D1 , WkDfVxT3N18D2 , WkDfVxT3N18D3 , & + WkDfVxT3N18D4 , WkDfVxT3N18D5 , WkDfVxT3N18D6 , WkDfVxT3N18D7 , WkDfVxT3N18D8 , WkDfVxT3N18D9 , & + WkDfVxT3N19D1 , WkDfVxT3N19D2 , WkDfVxT3N19D3 , WkDfVxT3N19D4 , WkDfVxT3N19D5 , WkDfVxT3N19D6 , & + WkDfVxT3N19D7 , WkDfVxT3N19D8 , WkDfVxT3N19D9 , WkDfVxT3N20D1 , WkDfVxT3N20D2 , WkDfVxT3N20D3 , & + WkDfVxT3N20D4 , WkDfVxT3N20D5 , WkDfVxT3N20D6 , WkDfVxT3N20D7 , WkDfVxT3N20D8 , WkDfVxT3N20D9 , & + WkDfVxT4N01D1 , WkDfVxT4N01D2 , WkDfVxT4N01D3 , WkDfVxT4N01D4 , WkDfVxT4N01D5 , WkDfVxT4N01D6 , & + WkDfVxT4N01D7 , WkDfVxT4N01D8 , WkDfVxT4N01D9 , WkDfVxT4N02D1 , WkDfVxT4N02D2 , WkDfVxT4N02D3 , & + WkDfVxT4N02D4 , WkDfVxT4N02D5 , WkDfVxT4N02D6 , WkDfVxT4N02D7 , WkDfVxT4N02D8 , WkDfVxT4N02D9 , & + WkDfVxT4N03D1 , WkDfVxT4N03D2 , WkDfVxT4N03D3 , WkDfVxT4N03D4 , WkDfVxT4N03D5 , WkDfVxT4N03D6 , & + WkDfVxT4N03D7 , WkDfVxT4N03D8 , WkDfVxT4N03D9 , WkDfVxT4N04D1 , WkDfVxT4N04D2 , WkDfVxT4N04D3 , & + WkDfVxT4N04D4 , WkDfVxT4N04D5 , WkDfVxT4N04D6 , WkDfVxT4N04D7 , WkDfVxT4N04D8 , WkDfVxT4N04D9 , & + WkDfVxT4N05D1 , WkDfVxT4N05D2 , WkDfVxT4N05D3 , WkDfVxT4N05D4 , WkDfVxT4N05D5 , WkDfVxT4N05D6 , & + WkDfVxT4N05D7 , WkDfVxT4N05D8 , WkDfVxT4N05D9 , WkDfVxT4N06D1 , WkDfVxT4N06D2 , WkDfVxT4N06D3 , & + WkDfVxT4N06D4 , WkDfVxT4N06D5 , WkDfVxT4N06D6 , WkDfVxT4N06D7 , WkDfVxT4N06D8 , WkDfVxT4N06D9 , & + WkDfVxT4N07D1 , WkDfVxT4N07D2 , WkDfVxT4N07D3 , WkDfVxT4N07D4 , WkDfVxT4N07D5 , WkDfVxT4N07D6 , & + WkDfVxT4N07D7 , WkDfVxT4N07D8 , WkDfVxT4N07D9 , WkDfVxT4N08D1 , WkDfVxT4N08D2 , WkDfVxT4N08D3 , & + WkDfVxT4N08D4 , WkDfVxT4N08D5 , WkDfVxT4N08D6 , WkDfVxT4N08D7 , WkDfVxT4N08D8 , WkDfVxT4N08D9 , & + WkDfVxT4N09D1 , WkDfVxT4N09D2 , WkDfVxT4N09D3 , WkDfVxT4N09D4 , WkDfVxT4N09D5 , WkDfVxT4N09D6 , & + WkDfVxT4N09D7 , WkDfVxT4N09D8 , WkDfVxT4N09D9 , WkDfVxT4N10D1 , WkDfVxT4N10D2 , WkDfVxT4N10D3 , & + WkDfVxT4N10D4 , WkDfVxT4N10D5 , WkDfVxT4N10D6 , WkDfVxT4N10D7 , WkDfVxT4N10D8 , WkDfVxT4N10D9 , & + WkDfVxT4N11D1 , WkDfVxT4N11D2 , WkDfVxT4N11D3 , WkDfVxT4N11D4 , WkDfVxT4N11D5 , WkDfVxT4N11D6 , & + WkDfVxT4N11D7 , WkDfVxT4N11D8 , WkDfVxT4N11D9 , WkDfVxT4N12D1 , WkDfVxT4N12D2 , WkDfVxT4N12D3 , & + WkDfVxT4N12D4 , WkDfVxT4N12D5 , WkDfVxT4N12D6 , WkDfVxT4N12D7 , WkDfVxT4N12D8 , WkDfVxT4N12D9 , & + WkDfVxT4N13D1 , WkDfVxT4N13D2 , WkDfVxT4N13D3 , WkDfVxT4N13D4 , WkDfVxT4N13D5 , WkDfVxT4N13D6 , & + WkDfVxT4N13D7 , WkDfVxT4N13D8 , WkDfVxT4N13D9 , WkDfVxT4N14D1 , WkDfVxT4N14D2 , WkDfVxT4N14D3 , & + WkDfVxT4N14D4 , WkDfVxT4N14D5 , WkDfVxT4N14D6 , WkDfVxT4N14D7 , WkDfVxT4N14D8 , WkDfVxT4N14D9 , & + WkDfVxT4N15D1 , WkDfVxT4N15D2 , WkDfVxT4N15D3 , WkDfVxT4N15D4 , WkDfVxT4N15D5 , WkDfVxT4N15D6 , & + WkDfVxT4N15D7 , WkDfVxT4N15D8 , WkDfVxT4N15D9 , WkDfVxT4N16D1 , WkDfVxT4N16D2 , WkDfVxT4N16D3 , & + WkDfVxT4N16D4 , WkDfVxT4N16D5 , WkDfVxT4N16D6 , WkDfVxT4N16D7 , WkDfVxT4N16D8 , WkDfVxT4N16D9 , & + WkDfVxT4N17D1 , WkDfVxT4N17D2 , WkDfVxT4N17D3 , WkDfVxT4N17D4 , WkDfVxT4N17D5 , WkDfVxT4N17D6 , & + WkDfVxT4N17D7 , WkDfVxT4N17D8 , WkDfVxT4N17D9 , WkDfVxT4N18D1 , WkDfVxT4N18D2 , WkDfVxT4N18D3 , & + WkDfVxT4N18D4 , WkDfVxT4N18D5 , WkDfVxT4N18D6 , WkDfVxT4N18D7 , WkDfVxT4N18D8 , WkDfVxT4N18D9 , & + WkDfVxT4N19D1 , WkDfVxT4N19D2 , WkDfVxT4N19D3 , WkDfVxT4N19D4 , WkDfVxT4N19D5 , WkDfVxT4N19D6 , & + WkDfVxT4N19D7 , WkDfVxT4N19D8 , WkDfVxT4N19D9 , WkDfVxT4N20D1 , WkDfVxT4N20D2 , WkDfVxT4N20D3 , & + WkDfVxT4N20D4 , WkDfVxT4N20D5 , WkDfVxT4N20D6 , WkDfVxT4N20D7 , WkDfVxT4N20D8 , WkDfVxT4N20D9 , & + WkDfVxT5N01D1 , WkDfVxT5N01D2 , WkDfVxT5N01D3 , WkDfVxT5N01D4 , WkDfVxT5N01D5 , WkDfVxT5N01D6 , & + WkDfVxT5N01D7 , WkDfVxT5N01D8 , WkDfVxT5N01D9 , WkDfVxT5N02D1 , WkDfVxT5N02D2 , WkDfVxT5N02D3 , & + WkDfVxT5N02D4 , WkDfVxT5N02D5 , WkDfVxT5N02D6 , WkDfVxT5N02D7 , WkDfVxT5N02D8 , WkDfVxT5N02D9 , & + WkDfVxT5N03D1 , WkDfVxT5N03D2 , WkDfVxT5N03D3 , WkDfVxT5N03D4 , WkDfVxT5N03D5 , WkDfVxT5N03D6 , & + WkDfVxT5N03D7 , WkDfVxT5N03D8 , WkDfVxT5N03D9 , WkDfVxT5N04D1 , WkDfVxT5N04D2 , WkDfVxT5N04D3 , & + WkDfVxT5N04D4 , WkDfVxT5N04D5 , WkDfVxT5N04D6 , WkDfVxT5N04D7 , WkDfVxT5N04D8 , WkDfVxT5N04D9 , & + WkDfVxT5N05D1 , WkDfVxT5N05D2 , WkDfVxT5N05D3 , WkDfVxT5N05D4 , WkDfVxT5N05D5 , WkDfVxT5N05D6 , & + WkDfVxT5N05D7 , WkDfVxT5N05D8 , WkDfVxT5N05D9 , WkDfVxT5N06D1 , WkDfVxT5N06D2 , WkDfVxT5N06D3 , & + WkDfVxT5N06D4 , WkDfVxT5N06D5 , WkDfVxT5N06D6 , WkDfVxT5N06D7 , WkDfVxT5N06D8 , WkDfVxT5N06D9 , & + WkDfVxT5N07D1 , WkDfVxT5N07D2 , WkDfVxT5N07D3 , WkDfVxT5N07D4 , WkDfVxT5N07D5 , WkDfVxT5N07D6 , & + WkDfVxT5N07D7 , WkDfVxT5N07D8 , WkDfVxT5N07D9 , WkDfVxT5N08D1 , WkDfVxT5N08D2 , WkDfVxT5N08D3 , & + WkDfVxT5N08D4 , WkDfVxT5N08D5 , WkDfVxT5N08D6 , WkDfVxT5N08D7 , WkDfVxT5N08D8 , WkDfVxT5N08D9 , & + WkDfVxT5N09D1 , WkDfVxT5N09D2 , WkDfVxT5N09D3 , WkDfVxT5N09D4 , WkDfVxT5N09D5 , WkDfVxT5N09D6 , & + WkDfVxT5N09D7 , WkDfVxT5N09D8 , WkDfVxT5N09D9 , WkDfVxT5N10D1 , WkDfVxT5N10D2 , WkDfVxT5N10D3 , & + WkDfVxT5N10D4 , WkDfVxT5N10D5 , WkDfVxT5N10D6 , WkDfVxT5N10D7 , WkDfVxT5N10D8 , WkDfVxT5N10D9 , & + WkDfVxT5N11D1 , WkDfVxT5N11D2 , WkDfVxT5N11D3 , WkDfVxT5N11D4 , WkDfVxT5N11D5 , WkDfVxT5N11D6 , & + WkDfVxT5N11D7 , WkDfVxT5N11D8 , WkDfVxT5N11D9 , WkDfVxT5N12D1 , WkDfVxT5N12D2 , WkDfVxT5N12D3 , & + WkDfVxT5N12D4 , WkDfVxT5N12D5 , WkDfVxT5N12D6 , WkDfVxT5N12D7 , WkDfVxT5N12D8 , WkDfVxT5N12D9 , & + WkDfVxT5N13D1 , WkDfVxT5N13D2 , WkDfVxT5N13D3 , WkDfVxT5N13D4 , WkDfVxT5N13D5 , WkDfVxT5N13D6 , & + WkDfVxT5N13D7 , WkDfVxT5N13D8 , WkDfVxT5N13D9 , WkDfVxT5N14D1 , WkDfVxT5N14D2 , WkDfVxT5N14D3 , & + WkDfVxT5N14D4 , WkDfVxT5N14D5 , WkDfVxT5N14D6 , WkDfVxT5N14D7 , WkDfVxT5N14D8 , WkDfVxT5N14D9 /) + INTEGER(IntKi), PARAMETER :: ParamIndxAry7(1350) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + WkDfVxT5N15D1 , WkDfVxT5N15D2 , WkDfVxT5N15D3 , WkDfVxT5N15D4 , WkDfVxT5N15D5 , WkDfVxT5N15D6 , & + WkDfVxT5N15D7 , WkDfVxT5N15D8 , WkDfVxT5N15D9 , WkDfVxT5N16D1 , WkDfVxT5N16D2 , WkDfVxT5N16D3 , & + WkDfVxT5N16D4 , WkDfVxT5N16D5 , WkDfVxT5N16D6 , WkDfVxT5N16D7 , WkDfVxT5N16D8 , WkDfVxT5N16D9 , & + WkDfVxT5N17D1 , WkDfVxT5N17D2 , WkDfVxT5N17D3 , WkDfVxT5N17D4 , WkDfVxT5N17D5 , WkDfVxT5N17D6 , & + WkDfVxT5N17D7 , WkDfVxT5N17D8 , WkDfVxT5N17D9 , WkDfVxT5N18D1 , WkDfVxT5N18D2 , WkDfVxT5N18D3 , & + WkDfVxT5N18D4 , WkDfVxT5N18D5 , WkDfVxT5N18D6 , WkDfVxT5N18D7 , WkDfVxT5N18D8 , WkDfVxT5N18D9 , & + WkDfVxT5N19D1 , WkDfVxT5N19D2 , WkDfVxT5N19D3 , WkDfVxT5N19D4 , WkDfVxT5N19D5 , WkDfVxT5N19D6 , & + WkDfVxT5N19D7 , WkDfVxT5N19D8 , WkDfVxT5N19D9 , WkDfVxT5N20D1 , WkDfVxT5N20D2 , WkDfVxT5N20D3 , & + WkDfVxT5N20D4 , WkDfVxT5N20D5 , WkDfVxT5N20D6 , WkDfVxT5N20D7 , WkDfVxT5N20D8 , WkDfVxT5N20D9 , & + WkDfVxT6N01D1 , WkDfVxT6N01D2 , WkDfVxT6N01D3 , WkDfVxT6N01D4 , WkDfVxT6N01D5 , WkDfVxT6N01D6 , & + WkDfVxT6N01D7 , WkDfVxT6N01D8 , WkDfVxT6N01D9 , WkDfVxT6N02D1 , WkDfVxT6N02D2 , WkDfVxT6N02D3 , & + WkDfVxT6N02D4 , WkDfVxT6N02D5 , WkDfVxT6N02D6 , WkDfVxT6N02D7 , WkDfVxT6N02D8 , WkDfVxT6N02D9 , & + WkDfVxT6N03D1 , WkDfVxT6N03D2 , WkDfVxT6N03D3 , WkDfVxT6N03D4 , WkDfVxT6N03D5 , WkDfVxT6N03D6 , & + WkDfVxT6N03D7 , WkDfVxT6N03D8 , WkDfVxT6N03D9 , WkDfVxT6N04D1 , WkDfVxT6N04D2 , WkDfVxT6N04D3 , & + WkDfVxT6N04D4 , WkDfVxT6N04D5 , WkDfVxT6N04D6 , WkDfVxT6N04D7 , WkDfVxT6N04D8 , WkDfVxT6N04D9 , & + WkDfVxT6N05D1 , WkDfVxT6N05D2 , WkDfVxT6N05D3 , WkDfVxT6N05D4 , WkDfVxT6N05D5 , WkDfVxT6N05D6 , & + WkDfVxT6N05D7 , WkDfVxT6N05D8 , WkDfVxT6N05D9 , WkDfVxT6N06D1 , WkDfVxT6N06D2 , WkDfVxT6N06D3 , & + WkDfVxT6N06D4 , WkDfVxT6N06D5 , WkDfVxT6N06D6 , WkDfVxT6N06D7 , WkDfVxT6N06D8 , WkDfVxT6N06D9 , & + WkDfVxT6N07D1 , WkDfVxT6N07D2 , WkDfVxT6N07D3 , WkDfVxT6N07D4 , WkDfVxT6N07D5 , WkDfVxT6N07D6 , & + WkDfVxT6N07D7 , WkDfVxT6N07D8 , WkDfVxT6N07D9 , WkDfVxT6N08D1 , WkDfVxT6N08D2 , WkDfVxT6N08D3 , & + WkDfVxT6N08D4 , WkDfVxT6N08D5 , WkDfVxT6N08D6 , WkDfVxT6N08D7 , WkDfVxT6N08D8 , WkDfVxT6N08D9 , & + WkDfVxT6N09D1 , WkDfVxT6N09D2 , WkDfVxT6N09D3 , WkDfVxT6N09D4 , WkDfVxT6N09D5 , WkDfVxT6N09D6 , & + WkDfVxT6N09D7 , WkDfVxT6N09D8 , WkDfVxT6N09D9 , WkDfVxT6N10D1 , WkDfVxT6N10D2 , WkDfVxT6N10D3 , & + WkDfVxT6N10D4 , WkDfVxT6N10D5 , WkDfVxT6N10D6 , WkDfVxT6N10D7 , WkDfVxT6N10D8 , WkDfVxT6N10D9 , & + WkDfVxT6N11D1 , WkDfVxT6N11D2 , WkDfVxT6N11D3 , WkDfVxT6N11D4 , WkDfVxT6N11D5 , WkDfVxT6N11D6 , & + WkDfVxT6N11D7 , WkDfVxT6N11D8 , WkDfVxT6N11D9 , WkDfVxT6N12D1 , WkDfVxT6N12D2 , WkDfVxT6N12D3 , & + WkDfVxT6N12D4 , WkDfVxT6N12D5 , WkDfVxT6N12D6 , WkDfVxT6N12D7 , WkDfVxT6N12D8 , WkDfVxT6N12D9 , & + WkDfVxT6N13D1 , WkDfVxT6N13D2 , WkDfVxT6N13D3 , WkDfVxT6N13D4 , WkDfVxT6N13D5 , WkDfVxT6N13D6 , & + WkDfVxT6N13D7 , WkDfVxT6N13D8 , WkDfVxT6N13D9 , WkDfVxT6N14D1 , WkDfVxT6N14D2 , WkDfVxT6N14D3 , & + WkDfVxT6N14D4 , WkDfVxT6N14D5 , WkDfVxT6N14D6 , WkDfVxT6N14D7 , WkDfVxT6N14D8 , WkDfVxT6N14D9 , & + WkDfVxT6N15D1 , WkDfVxT6N15D2 , WkDfVxT6N15D3 , WkDfVxT6N15D4 , WkDfVxT6N15D5 , WkDfVxT6N15D6 , & + WkDfVxT6N15D7 , WkDfVxT6N15D8 , WkDfVxT6N15D9 , WkDfVxT6N16D1 , WkDfVxT6N16D2 , WkDfVxT6N16D3 , & + WkDfVxT6N16D4 , WkDfVxT6N16D5 , WkDfVxT6N16D6 , WkDfVxT6N16D7 , WkDfVxT6N16D8 , WkDfVxT6N16D9 , & + WkDfVxT6N17D1 , WkDfVxT6N17D2 , WkDfVxT6N17D3 , WkDfVxT6N17D4 , WkDfVxT6N17D5 , WkDfVxT6N17D6 , & + WkDfVxT6N17D7 , WkDfVxT6N17D8 , WkDfVxT6N17D9 , WkDfVxT6N18D1 , WkDfVxT6N18D2 , WkDfVxT6N18D3 , & + WkDfVxT6N18D4 , WkDfVxT6N18D5 , WkDfVxT6N18D6 , WkDfVxT6N18D7 , WkDfVxT6N18D8 , WkDfVxT6N18D9 , & + WkDfVxT6N19D1 , WkDfVxT6N19D2 , WkDfVxT6N19D3 , WkDfVxT6N19D4 , WkDfVxT6N19D5 , WkDfVxT6N19D6 , & + WkDfVxT6N19D7 , WkDfVxT6N19D8 , WkDfVxT6N19D9 , WkDfVxT6N20D1 , WkDfVxT6N20D2 , WkDfVxT6N20D3 , & + WkDfVxT6N20D4 , WkDfVxT6N20D5 , WkDfVxT6N20D6 , WkDfVxT6N20D7 , WkDfVxT6N20D8 , WkDfVxT6N20D9 , & + WkDfVxT7N01D1 , WkDfVxT7N01D2 , WkDfVxT7N01D3 , WkDfVxT7N01D4 , WkDfVxT7N01D5 , WkDfVxT7N01D6 , & + WkDfVxT7N01D7 , WkDfVxT7N01D8 , WkDfVxT7N01D9 , WkDfVxT7N02D1 , WkDfVxT7N02D2 , WkDfVxT7N02D3 , & + WkDfVxT7N02D4 , WkDfVxT7N02D5 , WkDfVxT7N02D6 , WkDfVxT7N02D7 , WkDfVxT7N02D8 , WkDfVxT7N02D9 , & + WkDfVxT7N03D1 , WkDfVxT7N03D2 , WkDfVxT7N03D3 , WkDfVxT7N03D4 , WkDfVxT7N03D5 , WkDfVxT7N03D6 , & + WkDfVxT7N03D7 , WkDfVxT7N03D8 , WkDfVxT7N03D9 , WkDfVxT7N04D1 , WkDfVxT7N04D2 , WkDfVxT7N04D3 , & + WkDfVxT7N04D4 , WkDfVxT7N04D5 , WkDfVxT7N04D6 , WkDfVxT7N04D7 , WkDfVxT7N04D8 , WkDfVxT7N04D9 , & + WkDfVxT7N05D1 , WkDfVxT7N05D2 , WkDfVxT7N05D3 , WkDfVxT7N05D4 , WkDfVxT7N05D5 , WkDfVxT7N05D6 , & + WkDfVxT7N05D7 , WkDfVxT7N05D8 , WkDfVxT7N05D9 , WkDfVxT7N06D1 , WkDfVxT7N06D2 , WkDfVxT7N06D3 , & + WkDfVxT7N06D4 , WkDfVxT7N06D5 , WkDfVxT7N06D6 , WkDfVxT7N06D7 , WkDfVxT7N06D8 , WkDfVxT7N06D9 , & + WkDfVxT7N07D1 , WkDfVxT7N07D2 , WkDfVxT7N07D3 , WkDfVxT7N07D4 , WkDfVxT7N07D5 , WkDfVxT7N07D6 , & + WkDfVxT7N07D7 , WkDfVxT7N07D8 , WkDfVxT7N07D9 , WkDfVxT7N08D1 , WkDfVxT7N08D2 , WkDfVxT7N08D3 , & + WkDfVxT7N08D4 , WkDfVxT7N08D5 , WkDfVxT7N08D6 , WkDfVxT7N08D7 , WkDfVxT7N08D8 , WkDfVxT7N08D9 , & + WkDfVxT7N09D1 , WkDfVxT7N09D2 , WkDfVxT7N09D3 , WkDfVxT7N09D4 , WkDfVxT7N09D5 , WkDfVxT7N09D6 , & + WkDfVxT7N09D7 , WkDfVxT7N09D8 , WkDfVxT7N09D9 , WkDfVxT7N10D1 , WkDfVxT7N10D2 , WkDfVxT7N10D3 , & + WkDfVxT7N10D4 , WkDfVxT7N10D5 , WkDfVxT7N10D6 , WkDfVxT7N10D7 , WkDfVxT7N10D8 , WkDfVxT7N10D9 , & + WkDfVxT7N11D1 , WkDfVxT7N11D2 , WkDfVxT7N11D3 , WkDfVxT7N11D4 , WkDfVxT7N11D5 , WkDfVxT7N11D6 , & + WkDfVxT7N11D7 , WkDfVxT7N11D8 , WkDfVxT7N11D9 , WkDfVxT7N12D1 , WkDfVxT7N12D2 , WkDfVxT7N12D3 , & + WkDfVxT7N12D4 , WkDfVxT7N12D5 , WkDfVxT7N12D6 , WkDfVxT7N12D7 , WkDfVxT7N12D8 , WkDfVxT7N12D9 , & + WkDfVxT7N13D1 , WkDfVxT7N13D2 , WkDfVxT7N13D3 , WkDfVxT7N13D4 , WkDfVxT7N13D5 , WkDfVxT7N13D6 , & + WkDfVxT7N13D7 , WkDfVxT7N13D8 , WkDfVxT7N13D9 , WkDfVxT7N14D1 , WkDfVxT7N14D2 , WkDfVxT7N14D3 , & + WkDfVxT7N14D4 , WkDfVxT7N14D5 , WkDfVxT7N14D6 , WkDfVxT7N14D7 , WkDfVxT7N14D8 , WkDfVxT7N14D9 , & + WkDfVxT7N15D1 , WkDfVxT7N15D2 , WkDfVxT7N15D3 , WkDfVxT7N15D4 , WkDfVxT7N15D5 , WkDfVxT7N15D6 , & + WkDfVxT7N15D7 , WkDfVxT7N15D8 , WkDfVxT7N15D9 , WkDfVxT7N16D1 , WkDfVxT7N16D2 , WkDfVxT7N16D3 , & + WkDfVxT7N16D4 , WkDfVxT7N16D5 , WkDfVxT7N16D6 , WkDfVxT7N16D7 , WkDfVxT7N16D8 , WkDfVxT7N16D9 , & + WkDfVxT7N17D1 , WkDfVxT7N17D2 , WkDfVxT7N17D3 , WkDfVxT7N17D4 , WkDfVxT7N17D5 , WkDfVxT7N17D6 , & + WkDfVxT7N17D7 , WkDfVxT7N17D8 , WkDfVxT7N17D9 , WkDfVxT7N18D1 , WkDfVxT7N18D2 , WkDfVxT7N18D3 , & + WkDfVxT7N18D4 , WkDfVxT7N18D5 , WkDfVxT7N18D6 , WkDfVxT7N18D7 , WkDfVxT7N18D8 , WkDfVxT7N18D9 , & + WkDfVxT7N19D1 , WkDfVxT7N19D2 , WkDfVxT7N19D3 , WkDfVxT7N19D4 , WkDfVxT7N19D5 , WkDfVxT7N19D6 , & + WkDfVxT7N19D7 , WkDfVxT7N19D8 , WkDfVxT7N19D9 , WkDfVxT7N20D1 , WkDfVxT7N20D2 , WkDfVxT7N20D3 , & + WkDfVxT7N20D4 , WkDfVxT7N20D5 , WkDfVxT7N20D6 , WkDfVxT7N20D7 , WkDfVxT7N20D8 , WkDfVxT7N20D9 , & + WkDfVxT8N01D1 , WkDfVxT8N01D2 , WkDfVxT8N01D3 , WkDfVxT8N01D4 , WkDfVxT8N01D5 , WkDfVxT8N01D6 , & + WkDfVxT8N01D7 , WkDfVxT8N01D8 , WkDfVxT8N01D9 , WkDfVxT8N02D1 , WkDfVxT8N02D2 , WkDfVxT8N02D3 , & + WkDfVxT8N02D4 , WkDfVxT8N02D5 , WkDfVxT8N02D6 , WkDfVxT8N02D7 , WkDfVxT8N02D8 , WkDfVxT8N02D9 , & + WkDfVxT8N03D1 , WkDfVxT8N03D2 , WkDfVxT8N03D3 , WkDfVxT8N03D4 , WkDfVxT8N03D5 , WkDfVxT8N03D6 , & + WkDfVxT8N03D7 , WkDfVxT8N03D8 , WkDfVxT8N03D9 , WkDfVxT8N04D1 , WkDfVxT8N04D2 , WkDfVxT8N04D3 , & + WkDfVxT8N04D4 , WkDfVxT8N04D5 , WkDfVxT8N04D6 , WkDfVxT8N04D7 , WkDfVxT8N04D8 , WkDfVxT8N04D9 , & + WkDfVxT8N05D1 , WkDfVxT8N05D2 , WkDfVxT8N05D3 , WkDfVxT8N05D4 , WkDfVxT8N05D5 , WkDfVxT8N05D6 , & + WkDfVxT8N05D7 , WkDfVxT8N05D8 , WkDfVxT8N05D9 , WkDfVxT8N06D1 , WkDfVxT8N06D2 , WkDfVxT8N06D3 , & + WkDfVxT8N06D4 , WkDfVxT8N06D5 , WkDfVxT8N06D6 , WkDfVxT8N06D7 , WkDfVxT8N06D8 , WkDfVxT8N06D9 , & + WkDfVxT8N07D1 , WkDfVxT8N07D2 , WkDfVxT8N07D3 , WkDfVxT8N07D4 , WkDfVxT8N07D5 , WkDfVxT8N07D6 , & + WkDfVxT8N07D7 , WkDfVxT8N07D8 , WkDfVxT8N07D9 , WkDfVxT8N08D1 , WkDfVxT8N08D2 , WkDfVxT8N08D3 , & + WkDfVxT8N08D4 , WkDfVxT8N08D5 , WkDfVxT8N08D6 , WkDfVxT8N08D7 , WkDfVxT8N08D8 , WkDfVxT8N08D9 , & + WkDfVxT8N09D1 , WkDfVxT8N09D2 , WkDfVxT8N09D3 , WkDfVxT8N09D4 , WkDfVxT8N09D5 , WkDfVxT8N09D6 , & + WkDfVxT8N09D7 , WkDfVxT8N09D8 , WkDfVxT8N09D9 , WkDfVxT8N10D1 , WkDfVxT8N10D2 , WkDfVxT8N10D3 , & + WkDfVxT8N10D4 , WkDfVxT8N10D5 , WkDfVxT8N10D6 , WkDfVxT8N10D7 , WkDfVxT8N10D8 , WkDfVxT8N10D9 , & + WkDfVxT8N11D1 , WkDfVxT8N11D2 , WkDfVxT8N11D3 , WkDfVxT8N11D4 , WkDfVxT8N11D5 , WkDfVxT8N11D6 , & + WkDfVxT8N11D7 , WkDfVxT8N11D8 , WkDfVxT8N11D9 , WkDfVxT8N12D1 , WkDfVxT8N12D2 , WkDfVxT8N12D3 , & + WkDfVxT8N12D4 , WkDfVxT8N12D5 , WkDfVxT8N12D6 , WkDfVxT8N12D7 , WkDfVxT8N12D8 , WkDfVxT8N12D9 , & + WkDfVxT8N13D1 , WkDfVxT8N13D2 , WkDfVxT8N13D3 , WkDfVxT8N13D4 , WkDfVxT8N13D5 , WkDfVxT8N13D6 , & + WkDfVxT8N13D7 , WkDfVxT8N13D8 , WkDfVxT8N13D9 , WkDfVxT8N14D1 , WkDfVxT8N14D2 , WkDfVxT8N14D3 , & + WkDfVxT8N14D4 , WkDfVxT8N14D5 , WkDfVxT8N14D6 , WkDfVxT8N14D7 , WkDfVxT8N14D8 , WkDfVxT8N14D9 , & + WkDfVxT8N15D1 , WkDfVxT8N15D2 , WkDfVxT8N15D3 , WkDfVxT8N15D4 , WkDfVxT8N15D5 , WkDfVxT8N15D6 , & + WkDfVxT8N15D7 , WkDfVxT8N15D8 , WkDfVxT8N15D9 , WkDfVxT8N16D1 , WkDfVxT8N16D2 , WkDfVxT8N16D3 , & + WkDfVxT8N16D4 , WkDfVxT8N16D5 , WkDfVxT8N16D6 , WkDfVxT8N16D7 , WkDfVxT8N16D8 , WkDfVxT8N16D9 , & + WkDfVxT8N17D1 , WkDfVxT8N17D2 , WkDfVxT8N17D3 , WkDfVxT8N17D4 , WkDfVxT8N17D5 , WkDfVxT8N17D6 , & + WkDfVxT8N17D7 , WkDfVxT8N17D8 , WkDfVxT8N17D9 , WkDfVxT8N18D1 , WkDfVxT8N18D2 , WkDfVxT8N18D3 , & + WkDfVxT8N18D4 , WkDfVxT8N18D5 , WkDfVxT8N18D6 , WkDfVxT8N18D7 , WkDfVxT8N18D8 , WkDfVxT8N18D9 , & + WkDfVxT8N19D1 , WkDfVxT8N19D2 , WkDfVxT8N19D3 , WkDfVxT8N19D4 , WkDfVxT8N19D5 , WkDfVxT8N19D6 , & + WkDfVxT8N19D7 , WkDfVxT8N19D8 , WkDfVxT8N19D9 , WkDfVxT8N20D1 , WkDfVxT8N20D2 , WkDfVxT8N20D3 , & + WkDfVxT8N20D4 , WkDfVxT8N20D5 , WkDfVxT8N20D6 , WkDfVxT8N20D7 , WkDfVxT8N20D8 , WkDfVxT8N20D9 , & + WkDfVxT9N01D1 , WkDfVxT9N01D2 , WkDfVxT9N01D3 , WkDfVxT9N01D4 , WkDfVxT9N01D5 , WkDfVxT9N01D6 , & + WkDfVxT9N01D7 , WkDfVxT9N01D8 , WkDfVxT9N01D9 , WkDfVxT9N02D1 , WkDfVxT9N02D2 , WkDfVxT9N02D3 , & + WkDfVxT9N02D4 , WkDfVxT9N02D5 , WkDfVxT9N02D6 , WkDfVxT9N02D7 , WkDfVxT9N02D8 , WkDfVxT9N02D9 , & + WkDfVxT9N03D1 , WkDfVxT9N03D2 , WkDfVxT9N03D3 , WkDfVxT9N03D4 , WkDfVxT9N03D5 , WkDfVxT9N03D6 , & + WkDfVxT9N03D7 , WkDfVxT9N03D8 , WkDfVxT9N03D9 , WkDfVxT9N04D1 , WkDfVxT9N04D2 , WkDfVxT9N04D3 , & + WkDfVxT9N04D4 , WkDfVxT9N04D5 , WkDfVxT9N04D6 , WkDfVxT9N04D7 , WkDfVxT9N04D8 , WkDfVxT9N04D9 , & + WkDfVxT9N05D1 , WkDfVxT9N05D2 , WkDfVxT9N05D3 , WkDfVxT9N05D4 , WkDfVxT9N05D5 , WkDfVxT9N05D6 , & + WkDfVxT9N05D7 , WkDfVxT9N05D8 , WkDfVxT9N05D9 , WkDfVxT9N06D1 , WkDfVxT9N06D2 , WkDfVxT9N06D3 , & + WkDfVxT9N06D4 , WkDfVxT9N06D5 , WkDfVxT9N06D6 , WkDfVxT9N06D7 , WkDfVxT9N06D8 , WkDfVxT9N06D9 , & + WkDfVxT9N07D1 , WkDfVxT9N07D2 , WkDfVxT9N07D3 , WkDfVxT9N07D4 , WkDfVxT9N07D5 , WkDfVxT9N07D6 , & + WkDfVxT9N07D7 , WkDfVxT9N07D8 , WkDfVxT9N07D9 , WkDfVxT9N08D1 , WkDfVxT9N08D2 , WkDfVxT9N08D3 , & + WkDfVxT9N08D4 , WkDfVxT9N08D5 , WkDfVxT9N08D6 , WkDfVxT9N08D7 , WkDfVxT9N08D8 , WkDfVxT9N08D9 , & + WkDfVxT9N09D1 , WkDfVxT9N09D2 , WkDfVxT9N09D3 , WkDfVxT9N09D4 , WkDfVxT9N09D5 , WkDfVxT9N09D6 , & + WkDfVxT9N09D7 , WkDfVxT9N09D8 , WkDfVxT9N09D9 , WkDfVxT9N10D1 , WkDfVxT9N10D2 , WkDfVxT9N10D3 , & + WkDfVxT9N10D4 , WkDfVxT9N10D5 , WkDfVxT9N10D6 , WkDfVxT9N10D7 , WkDfVxT9N10D8 , WkDfVxT9N10D9 , & + WkDfVxT9N11D1 , WkDfVxT9N11D2 , WkDfVxT9N11D3 , WkDfVxT9N11D4 , WkDfVxT9N11D5 , WkDfVxT9N11D6 , & + WkDfVxT9N11D7 , WkDfVxT9N11D8 , WkDfVxT9N11D9 , WkDfVxT9N12D1 , WkDfVxT9N12D2 , WkDfVxT9N12D3 , & + WkDfVxT9N12D4 , WkDfVxT9N12D5 , WkDfVxT9N12D6 , WkDfVxT9N12D7 , WkDfVxT9N12D8 , WkDfVxT9N12D9 , & + WkDfVxT9N13D1 , WkDfVxT9N13D2 , WkDfVxT9N13D3 , WkDfVxT9N13D4 , WkDfVxT9N13D5 , WkDfVxT9N13D6 , & + WkDfVxT9N13D7 , WkDfVxT9N13D8 , WkDfVxT9N13D9 , WkDfVxT9N14D1 , WkDfVxT9N14D2 , WkDfVxT9N14D3 , & + WkDfVxT9N14D4 , WkDfVxT9N14D5 , WkDfVxT9N14D6 , WkDfVxT9N14D7 , WkDfVxT9N14D8 , WkDfVxT9N14D9 , & + WkDfVxT9N15D1 , WkDfVxT9N15D2 , WkDfVxT9N15D3 , WkDfVxT9N15D4 , WkDfVxT9N15D5 , WkDfVxT9N15D6 , & + WkDfVxT9N15D7 , WkDfVxT9N15D8 , WkDfVxT9N15D9 , WkDfVxT9N16D1 , WkDfVxT9N16D2 , WkDfVxT9N16D3 , & + WkDfVxT9N16D4 , WkDfVxT9N16D5 , WkDfVxT9N16D6 , WkDfVxT9N16D7 , WkDfVxT9N16D8 , WkDfVxT9N16D9 , & + WkDfVxT9N17D1 , WkDfVxT9N17D2 , WkDfVxT9N17D3 , WkDfVxT9N17D4 , WkDfVxT9N17D5 , WkDfVxT9N17D6 , & + WkDfVxT9N17D7 , WkDfVxT9N17D8 , WkDfVxT9N17D9 , WkDfVxT9N18D1 , WkDfVxT9N18D2 , WkDfVxT9N18D3 , & + WkDfVxT9N18D4 , WkDfVxT9N18D5 , WkDfVxT9N18D6 , WkDfVxT9N18D7 , WkDfVxT9N18D8 , WkDfVxT9N18D9 , & + WkDfVxT9N19D1 , WkDfVxT9N19D2 , WkDfVxT9N19D3 , WkDfVxT9N19D4 , WkDfVxT9N19D5 , WkDfVxT9N19D6 , & + WkDfVxT9N19D7 , WkDfVxT9N19D8 , WkDfVxT9N19D9 , WkDfVxT9N20D1 , WkDfVxT9N20D2 , WkDfVxT9N20D3 , & + WkDfVxT9N20D4 , WkDfVxT9N20D5 , WkDfVxT9N20D6 , WkDfVxT9N20D7 , WkDfVxT9N20D8 , WkDfVxT9N20D9 , & + WkDiamT1D1 , WkDiamT1D2 , WkDiamT1D3 , WkDiamT1D4 , WkDiamT1D5 , WkDiamT1D6 , & + WkDiamT1D7 , WkDiamT1D8 , WkDiamT1D9 , WkDiamT2D1 , WkDiamT2D2 , WkDiamT2D3 , & + WkDiamT2D4 , WkDiamT2D5 , WkDiamT2D6 , WkDiamT2D7 , WkDiamT2D8 , WkDiamT2D9 , & + WkDiamT3D1 , WkDiamT3D2 , WkDiamT3D3 , WkDiamT3D4 , WkDiamT3D5 , WkDiamT3D6 , & + WkDiamT3D7 , WkDiamT3D8 , WkDiamT3D9 , WkDiamT4D1 , WkDiamT4D2 , WkDiamT4D3 , & + WkDiamT4D4 , WkDiamT4D5 , WkDiamT4D6 , WkDiamT4D7 , WkDiamT4D8 , WkDiamT4D9 , & + WkDiamT5D1 , WkDiamT5D2 , WkDiamT5D3 , WkDiamT5D4 , WkDiamT5D5 , WkDiamT5D6 , & + WkDiamT5D7 , WkDiamT5D8 , WkDiamT5D9 , WkDiamT6D1 , WkDiamT6D2 , WkDiamT6D3 , & + WkDiamT6D4 , WkDiamT6D5 , WkDiamT6D6 , WkDiamT6D7 , WkDiamT6D8 , WkDiamT6D9 , & + WkDiamT7D1 , WkDiamT7D2 , WkDiamT7D3 , WkDiamT7D4 , WkDiamT7D5 , WkDiamT7D6 , & + WkDiamT7D7 , WkDiamT7D8 , WkDiamT7D9 , WkDiamT8D1 , WkDiamT8D2 , WkDiamT8D3 , & + WkDiamT8D4 , WkDiamT8D5 , WkDiamT8D6 , WkDiamT8D7 , WkDiamT8D8 , WkDiamT8D9 , & + WkDiamT9D1 , WkDiamT9D2 , WkDiamT9D3 , WkDiamT9D4 , WkDiamT9D5 , WkDiamT9D6 , & + WkDiamT9D7 , WkDiamT9D8 , WkDiamT9D9 , WkPosXT1D1 , WkPosXT1D2 , WkPosXT1D3 , & + WkPosXT1D4 , WkPosXT1D5 , WkPosXT1D6 , WkPosXT1D7 , WkPosXT1D8 , WkPosXT1D9 , & + WkPosXT2D1 , WkPosXT2D2 , WkPosXT2D3 , WkPosXT2D4 , WkPosXT2D5 , WkPosXT2D6 , & + WkPosXT2D7 , WkPosXT2D8 , WkPosXT2D9 , WkPosXT3D1 , WkPosXT3D2 , WkPosXT3D3 , & + WkPosXT3D4 , WkPosXT3D5 , WkPosXT3D6 , WkPosXT3D7 , WkPosXT3D8 , WkPosXT3D9 , & + WkPosXT4D1 , WkPosXT4D2 , WkPosXT4D3 , WkPosXT4D4 , WkPosXT4D5 , WkPosXT4D6 , & + WkPosXT4D7 , WkPosXT4D8 , WkPosXT4D9 , WkPosXT5D1 , WkPosXT5D2 , WkPosXT5D3 , & + WkPosXT5D4 , WkPosXT5D5 , WkPosXT5D6 , WkPosXT5D7 , WkPosXT5D8 , WkPosXT5D9 , & + WkPosXT6D1 , WkPosXT6D2 , WkPosXT6D3 , WkPosXT6D4 , WkPosXT6D5 , WkPosXT6D6 , & + WkPosXT6D7 , WkPosXT6D8 , WkPosXT6D9 , WkPosXT7D1 , WkPosXT7D2 , WkPosXT7D3 , & + WkPosXT7D4 , WkPosXT7D5 , WkPosXT7D6 , WkPosXT7D7 , WkPosXT7D8 , WkPosXT7D9 , & + WkPosXT8D1 , WkPosXT8D2 , WkPosXT8D3 , WkPosXT8D4 , WkPosXT8D5 , WkPosXT8D6 , & + WkPosXT8D7 , WkPosXT8D8 , WkPosXT8D9 , WkPosXT9D1 , WkPosXT9D2 , WkPosXT9D3 , & + WkPosXT9D4 , WkPosXT9D5 , WkPosXT9D6 , WkPosXT9D7 , WkPosXT9D8 , WkPosXT9D9 , & + WkPosYT1D1 , WkPosYT1D2 , WkPosYT1D3 , WkPosYT1D4 , WkPosYT1D5 , WkPosYT1D6 , & + WkPosYT1D7 , WkPosYT1D8 , WkPosYT1D9 , WkPosYT2D1 , WkPosYT2D2 , WkPosYT2D3 , & + WkPosYT2D4 , WkPosYT2D5 , WkPosYT2D6 , WkPosYT2D7 , WkPosYT2D8 , WkPosYT2D9 , & + WkPosYT3D1 , WkPosYT3D2 , WkPosYT3D3 , WkPosYT3D4 , WkPosYT3D5 , WkPosYT3D6 , & + WkPosYT3D7 , WkPosYT3D8 , WkPosYT3D9 , WkPosYT4D1 , WkPosYT4D2 , WkPosYT4D3 , & + WkPosYT4D4 , WkPosYT4D5 , WkPosYT4D6 , WkPosYT4D7 , WkPosYT4D8 , WkPosYT4D9 , & + WkPosYT5D1 , WkPosYT5D2 , WkPosYT5D3 , WkPosYT5D4 , WkPosYT5D5 , WkPosYT5D6 , & + WkPosYT5D7 , WkPosYT5D8 , WkPosYT5D9 , WkPosYT6D1 , WkPosYT6D2 , WkPosYT6D3 , & + WkPosYT6D4 , WkPosYT6D5 , WkPosYT6D6 , WkPosYT6D7 , WkPosYT6D8 , WkPosYT6D9 , & + WkPosYT7D1 , WkPosYT7D2 , WkPosYT7D3 , WkPosYT7D4 , WkPosYT7D5 , WkPosYT7D6 , & + WkPosYT7D7 , WkPosYT7D8 , WkPosYT7D9 , WkPosYT8D1 , WkPosYT8D2 , WkPosYT8D3 , & + WkPosYT8D4 , WkPosYT8D5 , WkPosYT8D6 , WkPosYT8D7 , WkPosYT8D8 , WkPosYT8D9 , & + WkPosYT9D1 , WkPosYT9D2 , WkPosYT9D3 , WkPosYT9D4 , WkPosYT9D5 , WkPosYT9D6 , & + WkPosYT9D7 , WkPosYT9D8 , WkPosYT9D9 , WkPosZT1D1 , WkPosZT1D2 , WkPosZT1D3 , & + WkPosZT1D4 , WkPosZT1D5 , WkPosZT1D6 , WkPosZT1D7 , WkPosZT1D8 , WkPosZT1D9 , & + WkPosZT2D1 , WkPosZT2D2 , WkPosZT2D3 , WkPosZT2D4 , WkPosZT2D5 , WkPosZT2D6 , & + WkPosZT2D7 , WkPosZT2D8 , WkPosZT2D9 , WkPosZT3D1 , WkPosZT3D2 , WkPosZT3D3 , & + WkPosZT3D4 , WkPosZT3D5 , WkPosZT3D6 , WkPosZT3D7 , WkPosZT3D8 , WkPosZT3D9 , & + WkPosZT4D1 , WkPosZT4D2 , WkPosZT4D3 , WkPosZT4D4 , WkPosZT4D5 , WkPosZT4D6 , & + WkPosZT4D7 , WkPosZT4D8 , WkPosZT4D9 , WkPosZT5D1 , WkPosZT5D2 , WkPosZT5D3 , & + WkPosZT5D4 , WkPosZT5D5 , WkPosZT5D6 , WkPosZT5D7 , WkPosZT5D8 , WkPosZT5D9 , & + WkPosZT6D1 , WkPosZT6D2 , WkPosZT6D3 , WkPosZT6D4 , WkPosZT6D5 , WkPosZT6D6 , & + WkPosZT6D7 , WkPosZT6D8 , WkPosZT6D9 , WkPosZT7D1 , WkPosZT7D2 , WkPosZT7D3 , & + WkPosZT7D4 , WkPosZT7D5 , WkPosZT7D6 , WkPosZT7D7 , WkPosZT7D8 , WkPosZT7D9 , & + WkPosZT8D1 , WkPosZT8D2 , WkPosZT8D3 , WkPosZT8D4 , WkPosZT8D5 , WkPosZT8D6 , & + WkPosZT8D7 , WkPosZT8D8 , WkPosZT8D9 , WkPosZT9D1 , WkPosZT9D2 , WkPosZT9D3 , & + WkPosZT9D4 , WkPosZT9D5 , WkPosZT9D6 , WkPosZT9D7 , WkPosZT9D8 , WkPosZT9D9 , & + WkVelXT1D1 , WkVelXT1D2 , WkVelXT1D3 , WkVelXT1D4 , WkVelXT1D5 , WkVelXT1D6 , & + WkVelXT1D7 , WkVelXT1D8 , WkVelXT1D9 , WkVelXT2D1 , WkVelXT2D2 , WkVelXT2D3 , & + WkVelXT2D4 , WkVelXT2D5 , WkVelXT2D6 , WkVelXT2D7 , WkVelXT2D8 , WkVelXT2D9 , & + WkVelXT3D1 , WkVelXT3D2 , WkVelXT3D3 , WkVelXT3D4 , WkVelXT3D5 , WkVelXT3D6 , & + WkVelXT3D7 , WkVelXT3D8 , WkVelXT3D9 , WkVelXT4D1 , WkVelXT4D2 , WkVelXT4D3 , & + WkVelXT4D4 , WkVelXT4D5 , WkVelXT4D6 , WkVelXT4D7 , WkVelXT4D8 , WkVelXT4D9 , & + WkVelXT5D1 , WkVelXT5D2 , WkVelXT5D3 , WkVelXT5D4 , WkVelXT5D5 , WkVelXT5D6 , & + WkVelXT5D7 , WkVelXT5D8 , WkVelXT5D9 , WkVelXT6D1 , WkVelXT6D2 , WkVelXT6D3 , & + WkVelXT6D4 , WkVelXT6D5 , WkVelXT6D6 , WkVelXT6D7 , WkVelXT6D8 , WkVelXT6D9 , & + WkVelXT7D1 , WkVelXT7D2 , WkVelXT7D3 , WkVelXT7D4 , WkVelXT7D5 , WkVelXT7D6 , & + WkVelXT7D7 , WkVelXT7D8 , WkVelXT7D9 , WkVelXT8D1 , WkVelXT8D2 , WkVelXT8D3 , & + WkVelXT8D4 , WkVelXT8D5 , WkVelXT8D6 , WkVelXT8D7 , WkVelXT8D8 , WkVelXT8D9 , & + WkVelXT9D1 , WkVelXT9D2 , WkVelXT9D3 , WkVelXT9D4 , WkVelXT9D5 , WkVelXT9D6 , & + WkVelXT9D7 , WkVelXT9D8 , WkVelXT9D9 , WkVelYT1D1 , WkVelYT1D2 , WkVelYT1D3 , & + WkVelYT1D4 , WkVelYT1D5 , WkVelYT1D6 , WkVelYT1D7 , WkVelYT1D8 , WkVelYT1D9 , & + WkVelYT2D1 , WkVelYT2D2 , WkVelYT2D3 , WkVelYT2D4 , WkVelYT2D5 , WkVelYT2D6 , & + WkVelYT2D7 , WkVelYT2D8 , WkVelYT2D9 , WkVelYT3D1 , WkVelYT3D2 , WkVelYT3D3 , & + WkVelYT3D4 , WkVelYT3D5 , WkVelYT3D6 , WkVelYT3D7 , WkVelYT3D8 , WkVelYT3D9 , & + WkVelYT4D1 , WkVelYT4D2 , WkVelYT4D3 , WkVelYT4D4 , WkVelYT4D5 , WkVelYT4D6 , & + WkVelYT4D7 , WkVelYT4D8 , WkVelYT4D9 , WkVelYT5D1 , WkVelYT5D2 , WkVelYT5D3 , & + WkVelYT5D4 , WkVelYT5D5 , WkVelYT5D6 , WkVelYT5D7 , WkVelYT5D8 , WkVelYT5D9 , & + WkVelYT6D1 , WkVelYT6D2 , WkVelYT6D3 , WkVelYT6D4 , WkVelYT6D5 , WkVelYT6D6 , & + WkVelYT6D7 , WkVelYT6D8 , WkVelYT6D9 , WkVelYT7D1 , WkVelYT7D2 , WkVelYT7D3 , & + WkVelYT7D4 , WkVelYT7D5 , WkVelYT7D6 , WkVelYT7D7 , WkVelYT7D8 , WkVelYT7D9 , & + WkVelYT8D1 , WkVelYT8D2 , WkVelYT8D3 , WkVelYT8D4 , WkVelYT8D5 , WkVelYT8D6 , & + WkVelYT8D7 , WkVelYT8D8 , WkVelYT8D9 , WkVelYT9D1 , WkVelYT9D2 , WkVelYT9D3 , & + WkVelYT9D4 , WkVelYT9D5 , WkVelYT9D6 , WkVelYT9D7 , WkVelYT9D8 , WkVelYT9D9 , & + WkVelZT1D1 , WkVelZT1D2 , WkVelZT1D3 , WkVelZT1D4 , WkVelZT1D5 , WkVelZT1D6 , & + WkVelZT1D7 , WkVelZT1D8 , WkVelZT1D9 , WkVelZT2D1 , WkVelZT2D2 , WkVelZT2D3 , & + WkVelZT2D4 , WkVelZT2D5 , WkVelZT2D6 , WkVelZT2D7 , WkVelZT2D8 , WkVelZT2D9 , & + WkVelZT3D1 , WkVelZT3D2 , WkVelZT3D3 , WkVelZT3D4 , WkVelZT3D5 , WkVelZT3D6 , & + WkVelZT3D7 , WkVelZT3D8 , WkVelZT3D9 , WkVelZT4D1 , WkVelZT4D2 , WkVelZT4D3 , & + WkVelZT4D4 , WkVelZT4D5 , WkVelZT4D6 , WkVelZT4D7 , WkVelZT4D8 , WkVelZT4D9 , & + WkVelZT5D1 , WkVelZT5D2 , WkVelZT5D3 , WkVelZT5D4 , WkVelZT5D5 , WkVelZT5D6 , & + WkVelZT5D7 , WkVelZT5D8 , WkVelZT5D9 , WkVelZT6D1 , WkVelZT6D2 , WkVelZT6D3 , & + WkVelZT6D4 , WkVelZT6D5 , WkVelZT6D6 , WkVelZT6D7 , WkVelZT6D8 , WkVelZT6D9 , & + WkVelZT7D1 , WkVelZT7D2 , WkVelZT7D3 , WkVelZT7D4 , WkVelZT7D5 , WkVelZT7D6 , & + WkVelZT7D7 , WkVelZT7D8 , WkVelZT7D9 , WkVelZT8D1 , WkVelZT8D2 , WkVelZT8D3 , & + WkVelZT8D4 , WkVelZT8D5 , WkVelZT8D6 , WkVelZT8D7 , WkVelZT8D8 , WkVelZT8D9 , & + WkVelZT9D1 , WkVelZT9D2 , WkVelZT9D3 , WkVelZT9D4 , WkVelZT9D5 , WkVelZT9D6 , & + WkVelZT9D7 , WkVelZT9D8 , WkVelZT9D9 , YawErrT1 , YawErrT2 , YawErrT3 , & + YawErrT4 , YawErrT5 , YawErrT6 , YawErrT7 , YawErrT8 , YawErrT9 /) + INTEGER(IntKi), PARAMETER :: ParamIndxAry(9486) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + ParamIndxAry1, ParamIndxAry2, ParamIndxAry3, ParamIndxAry4, ParamIndxAry5, ParamIndxAry6, ParamIndxAry7/) + + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry1(1356) = (/ character(ChanLen) :: & ! This lists the units corresponding to the allowed parameters + "(deg) ","(deg) ","(deg) ","(deg) ","(deg) ","(deg) ", & + "(deg) ","(deg) ","(deg) ","(deg) ","(deg) ","(deg) ", & + "(deg) ","(deg) ","(deg) ","(deg) ","(deg) ","(deg) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) "/) + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry2(1356) = (/ character(ChanLen) :: & ! This lists the units corresponding to the allowed parameters + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) "/) + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry3(1356) = (/ character(ChanLen) :: & ! This lists the units corresponding to the allowed parameters + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) "/) + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry4(1356) = (/ character(ChanLen) :: & ! This lists the units corresponding to the allowed parameters + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(m) ","(m) ","(m) ","(m) ","(m) ","(m) ", & + "(m) ","(m) ","(m) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ","(m^2/s) ", & + "(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) ","(deg) ","(deg) ","(deg) ", & + "(deg) ","(deg) ","(deg) ","(deg) ","(deg) ","(deg) ", & + "(deg) ","(deg) ","(deg) ","(deg) ","(deg) ","(deg) ", & + "(deg) ","(deg) ","(deg) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(user) ","(user) ","(user) ","(user) ","(user) ","(user) ", & + "(percent)","(percent)","(percent)","(percent)","(percent)","(percent)", & + "(percent)","(percent)","(percent)","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) "/) + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry5(1356) = (/ character(ChanLen) :: & ! This lists the units corresponding to the allowed parameters + "(m/s) ","(m/s) ","(m/s) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(-) ","(-) ","(-) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) "/) + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry6(1356) = (/ character(ChanLen) :: & ! This lists the units corresponding to the allowed parameters + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) "/) + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry7(1350) = (/ character(ChanLen) :: & ! This lists the units corresponding to the allowed parameters + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(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) ","(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) ", & + "(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) ","(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) ", & + "(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) ","(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) ", & + "(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) ","(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) ", & + "(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) ","(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) ", & + "(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) ","(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) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(deg) ","(deg) ", & + "(deg) ","(deg) ","(deg) ","(deg) ","(deg) ","(deg) "/) + CHARACTER(OutStrLenM1), PARAMETER :: ParamUnitsAry(9486) = (/ & ! This lists the units corresponding to the allowed parameters + ParamUnitsAry1, ParamUnitsAry2, ParamUnitsAry3, ParamUnitsAry4, ParamUnitsAry5, ParamUnitsAry6, ParamUnitsAry7/) + + + + ! Initialize values + ErrStat = ErrID_None + ErrMsg = "" + InvalidOutput = .FALSE. + + ! Setup the aggregated channel arrays used below + call Farm_SetAggregatedChannelOutArrays() + +! ..... Developer must add checking for invalid inputs here: ..... + + + ! Check Output radii and make sure they are >= 0 and <= Nr-1 : NOTE: This was actually already done during the input file read. + do i = 1,farm%p%NOutRadii + if ( (farm%p%OutRadii(i) < 0) .or. (farm%p%OutRadii(i) >= farm%AWAE%p%NumRadii) ) then + + InvalidOutput( CtTN (i, :) ) = .true. + InvalidOutput( WkDfVxTND(i,:,1) ) = .true. + InvalidOutput( WkDfVrTND(i,:,1) ) = .true. + InvalidOutput( EddVisTND(i,:,1) ) = .true. + InvalidOutput( EddAmbTND(i,:,1) ) = .true. + InvalidOutput( EddShrTND(i,:,1) ) = .true. + InvalidOutput( WkDfVxTND(i,:,2) ) = .true. + InvalidOutput( WkDfVrTND(i,:,2) ) = .true. + InvalidOutput( EddVisTND(i,:,2) ) = .true. + InvalidOutput( EddAmbTND(i,:,2) ) = .true. + InvalidOutput( EddShrTND(i,:,2) ) = .true. + InvalidOutput( WkDfVxTND(i,:,3) ) = .true. + InvalidOutput( WkDfVrTND(i,:,3) ) = .true. + InvalidOutput( EddVisTND(i,:,3) ) = .true. + InvalidOutput( EddAmbTND(i,:,3) ) = .true. + InvalidOutput( EddShrTND(i,:,3) ) = .true. + InvalidOutput( WkDfVxTND(i,:,4) ) = .true. + InvalidOutput( WkDfVrTND(i,:,4) ) = .true. + InvalidOutput( EddVisTND(i,:,4) ) = .true. + InvalidOutput( EddAmbTND(i,:,4) ) = .true. + InvalidOutput( EddShrTND(i,:,4) ) = .true. + InvalidOutput( WkDfVxTND(i,:,5) ) = .true. + InvalidOutput( WkDfVrTND(i,:,5) ) = .true. + InvalidOutput( EddVisTND(i,:,5) ) = .true. + InvalidOutput( EddAmbTND(i,:,5) ) = .true. + InvalidOutput( EddShrTND(i,:,5) ) = .true. + InvalidOutput( WkDfVxTND(i,:,6) ) = .true. + InvalidOutput( WkDfVrTND(i,:,6) ) = .true. + InvalidOutput( EddVisTND(i,:,6) ) = .true. + InvalidOutput( EddAmbTND(i,:,6) ) = .true. + InvalidOutput( EddShrTND(i,:,6) ) = .true. + InvalidOutput( WkDfVxTND(i,:,7) ) = .true. + InvalidOutput( WkDfVrTND(i,:,7) ) = .true. + InvalidOutput( EddVisTND(i,:,7) ) = .true. + InvalidOutput( EddAmbTND(i,:,7) ) = .true. + InvalidOutput( EddShrTND(i,:,7) ) = .true. + InvalidOutput( WkDfVxTND(i,:,8) ) = .true. + InvalidOutput( WkDfVrTND(i,:,8) ) = .true. + InvalidOutput( EddVisTND(i,:,8) ) = .true. + InvalidOutput( EddAmbTND(i,:,8) ) = .true. + InvalidOutput( EddShrTND(i,:,8) ) = .true. + InvalidOutput( WkDfVxTND(i,:,9) ) = .true. + InvalidOutput( WkDfVrTND(i,:,9) ) = .true. + InvalidOutput( EddVisTND(i,:,9) ) = .true. + InvalidOutput( EddAmbTND(i,:,9) ) = .true. + InvalidOutput( EddShrTND(i,:,9) ) = .true. + + end if + end do + + + DO i = farm%p%NOutRadii+1,20 + + InvalidOutput( CtTN (i, :) ) = .true. + InvalidOutput( WkDfVxTND(i,:,1) ) = .true. + InvalidOutput( WkDfVrTND(i,:,1) ) = .true. + InvalidOutput( EddVisTND(i,:,1) ) = .true. + InvalidOutput( EddAmbTND(i,:,1) ) = .true. + InvalidOutput( EddShrTND(i,:,1) ) = .true. + InvalidOutput( WkDfVxTND(i,:,2) ) = .true. + InvalidOutput( WkDfVrTND(i,:,2) ) = .true. + InvalidOutput( EddVisTND(i,:,2) ) = .true. + InvalidOutput( EddAmbTND(i,:,2) ) = .true. + InvalidOutput( EddShrTND(i,:,2) ) = .true. + InvalidOutput( WkDfVxTND(i,:,3) ) = .true. + InvalidOutput( WkDfVrTND(i,:,3) ) = .true. + InvalidOutput( EddVisTND(i,:,3) ) = .true. + InvalidOutput( EddAmbTND(i,:,3) ) = .true. + InvalidOutput( EddShrTND(i,:,3) ) = .true. + InvalidOutput( WkDfVxTND(i,:,4) ) = .true. + InvalidOutput( WkDfVrTND(i,:,4) ) = .true. + InvalidOutput( EddVisTND(i,:,4) ) = .true. + InvalidOutput( EddAmbTND(i,:,4) ) = .true. + InvalidOutput( EddShrTND(i,:,4) ) = .true. + InvalidOutput( WkDfVxTND(i,:,5) ) = .true. + InvalidOutput( WkDfVrTND(i,:,5) ) = .true. + InvalidOutput( EddVisTND(i,:,5) ) = .true. + InvalidOutput( EddAmbTND(i,:,5) ) = .true. + InvalidOutput( EddShrTND(i,:,5) ) = .true. + InvalidOutput( WkDfVxTND(i,:,6) ) = .true. + InvalidOutput( WkDfVrTND(i,:,6) ) = .true. + InvalidOutput( EddVisTND(i,:,6) ) = .true. + InvalidOutput( EddAmbTND(i,:,6) ) = .true. + InvalidOutput( EddShrTND(i,:,6) ) = .true. + InvalidOutput( WkDfVxTND(i,:,7) ) = .true. + InvalidOutput( WkDfVrTND(i,:,7) ) = .true. + InvalidOutput( EddVisTND(i,:,7) ) = .true. + InvalidOutput( EddAmbTND(i,:,7) ) = .true. + InvalidOutput( EddShrTND(i,:,7) ) = .true. + InvalidOutput( WkDfVxTND(i,:,8) ) = .true. + InvalidOutput( WkDfVrTND(i,:,8) ) = .true. + InvalidOutput( EddVisTND(i,:,8) ) = .true. + InvalidOutput( EddAmbTND(i,:,8) ) = .true. + InvalidOutput( EddShrTND(i,:,8) ) = .true. + InvalidOutput( WkDfVxTND(i,:,9) ) = .true. + InvalidOutput( WkDfVrTND(i,:,9) ) = .true. + InvalidOutput( EddVisTND(i,:,9) ) = .true. + InvalidOutput( EddAmbTND(i,:,9) ) = .true. + InvalidOutput( EddShrTND(i,:,9) ) = .true. + + END DO + + DO i = farm%p%NOutDist+1,9 + + InvalidOutput( WkAxsXTD ( i,:) ) = .true. + InvalidOutput( WkAxsYTD ( i,:) ) = .true. + InvalidOutput( WkAxsZTD ( i,:) ) = .true. + InvalidOutput( WkPosXTD ( i,:) ) = .true. + InvalidOutput( WkPosYTD ( i,:) ) = .true. + InvalidOutput( WkPosZTD ( i,:) ) = .true. + InvalidOutput( WkVelXTD ( i,:) ) = .true. + InvalidOutput( WkVelYTD ( i,:) ) = .true. + InvalidOutput( WkVelZTD ( i,:) ) = .true. + InvalidOutput( WkDiamTD ( i,:) ) = .true. + InvalidOutput( WkDfVxTND(:,i,1) ) = .true. + InvalidOutput( WkDfVrTND(:,i,1) ) = .true. + InvalidOutput( EddVisTND(:,i,1) ) = .true. + InvalidOutput( EddAmbTND(:,i,1) ) = .true. + InvalidOutput( EddShrTND(:,i,1) ) = .true. + InvalidOutput( WkDfVxTND(:,i,2) ) = .true. + InvalidOutput( WkDfVrTND(:,i,2) ) = .true. + InvalidOutput( EddVisTND(:,i,2) ) = .true. + InvalidOutput( EddAmbTND(:,i,2) ) = .true. + InvalidOutput( EddShrTND(:,i,2) ) = .true. + InvalidOutput( WkDfVxTND(:,i,3) ) = .true. + InvalidOutput( WkDfVrTND(:,i,3) ) = .true. + InvalidOutput( EddVisTND(:,i,3) ) = .true. + InvalidOutput( EddAmbTND(:,i,3) ) = .true. + InvalidOutput( EddShrTND(:,i,3) ) = .true. + InvalidOutput( WkDfVxTND(:,i,4) ) = .true. + InvalidOutput( WkDfVrTND(:,i,4) ) = .true. + InvalidOutput( EddVisTND(:,i,4) ) = .true. + InvalidOutput( EddAmbTND(:,i,4) ) = .true. + InvalidOutput( EddShrTND(:,i,4) ) = .true. + InvalidOutput( WkDfVxTND(:,i,5) ) = .true. + InvalidOutput( WkDfVrTND(:,i,5) ) = .true. + InvalidOutput( EddVisTND(:,i,5) ) = .true. + InvalidOutput( EddAmbTND(:,i,5) ) = .true. + InvalidOutput( EddShrTND(:,i,5) ) = .true. + InvalidOutput( WkDfVxTND(:,i,6) ) = .true. + InvalidOutput( WkDfVrTND(:,i,6) ) = .true. + InvalidOutput( EddVisTND(:,i,6) ) = .true. + InvalidOutput( EddAmbTND(:,i,6) ) = .true. + InvalidOutput( EddShrTND(:,i,6) ) = .true. + InvalidOutput( WkDfVxTND(:,i,7) ) = .true. + InvalidOutput( WkDfVrTND(:,i,7) ) = .true. + InvalidOutput( EddVisTND(:,i,7) ) = .true. + InvalidOutput( EddAmbTND(:,i,7) ) = .true. + InvalidOutput( EddShrTND(:,i,7) ) = .true. + InvalidOutput( WkDfVxTND(:,i,8) ) = .true. + InvalidOutput( WkDfVrTND(:,i,8) ) = .true. + InvalidOutput( EddVisTND(:,i,8) ) = .true. + InvalidOutput( EddAmbTND(:,i,8) ) = .true. + InvalidOutput( EddShrTND(:,i,8) ) = .true. + InvalidOutput( WkDfVxTND(:,i,9) ) = .true. + InvalidOutput( WkDfVrTND(:,i,9) ) = .true. + InvalidOutput( EddVisTND(:,i,9) ) = .true. + InvalidOutput( EddAmbTND(:,i,9) ) = .true. + InvalidOutput( EddShrTND(:,i,9) ) = .true. + + END DO + + do i = farm%p%NOutTurb+1,9 + + InvalidOutput( SCTIn ( :,i) ) = .true. + InvalidOutput( SCTOt ( :,i) ) = .true. + InvalidOutput( RtAxsXT (i) ) = .true. + InvalidOutput( RtAxsYT (i) ) = .true. + InvalidOutput( RtAxsZT (i) ) = .true. + InvalidOutput( RtPosXT (i) ) = .true. + InvalidOutput( RtPosYT (i) ) = .true. + InvalidOutput( RtPosZT (i) ) = .true. + InvalidOutput( RtDiamT (i) ) = .true. + InvalidOutput( YawErrT (i) ) = .true. + InvalidOutput( TIAmbT (i) ) = .true. + InvalidOutput( RtVAmbT (i) ) = .true. + InvalidOutput( RtVRelT (i) ) = .true. + InvalidOutput( RtVAmbFiltT (i) ) = .true. + InvalidOutput( AziSkewT (i) ) = .true. + InvalidOutput( AziSkewFiltT(i) ) = .true. + InvalidOutput( RtSkewT (i) ) = .true. + InvalidOutput( RtSkewFiltT (i) ) = .true. + InvalidOutput( RtGamCurlT (i) ) = .true. + InvalidOutput( RtCtAvgT (i) ) = .true. + InvalidOutput( CtTN (:, i) ) = .true. + InvalidOutput( WkAxsXTD ( :,i) ) = .true. + InvalidOutput( WkAxsYTD ( :,i) ) = .true. + InvalidOutput( WkAxsZTD ( :,i) ) = .true. + InvalidOutput( WkPosXTD ( :,i) ) = .true. + InvalidOutput( WkPosYTD ( :,i) ) = .true. + InvalidOutput( WkPosZTD ( :,i) ) = .true. + InvalidOutput( WkVelXTD ( :,i) ) = .true. + InvalidOutput( WkVelYTD ( :,i) ) = .true. + InvalidOutput( WkVelZTD ( :,i) ) = .true. + InvalidOutput( WkDiamTD ( :,i) ) = .true. + InvalidOutput( WkDfVxTND(:,1,i) ) = .true. + InvalidOutput( WkDfVrTND(:,1,i) ) = .true. + InvalidOutput( EddVisTND(:,1,i) ) = .true. + InvalidOutput( EddAmbTND(:,1,i) ) = .true. + InvalidOutput( EddShrTND(:,1,i) ) = .true. + InvalidOutput( WkDfVxTND(:,2,i) ) = .true. + InvalidOutput( WkDfVrTND(:,2,i) ) = .true. + InvalidOutput( EddVisTND(:,2,i) ) = .true. + InvalidOutput( EddAmbTND(:,2,i) ) = .true. + InvalidOutput( EddShrTND(:,2,i) ) = .true. + InvalidOutput( WkDfVxTND(:,3,i) ) = .true. + InvalidOutput( WkDfVrTND(:,3,i) ) = .true. + InvalidOutput( EddVisTND(:,3,i) ) = .true. + InvalidOutput( EddAmbTND(:,3,i) ) = .true. + InvalidOutput( EddShrTND(:,3,i) ) = .true. + InvalidOutput( WkDfVxTND(:,4,i) ) = .true. + InvalidOutput( WkDfVrTND(:,4,i) ) = .true. + InvalidOutput( EddVisTND(:,4,i) ) = .true. + InvalidOutput( EddAmbTND(:,4,i) ) = .true. + InvalidOutput( EddShrTND(:,4,i) ) = .true. + InvalidOutput( WkDfVxTND(:,5,i) ) = .true. + InvalidOutput( WkDfVrTND(:,5,i) ) = .true. + InvalidOutput( EddVisTND(:,5,i) ) = .true. + InvalidOutput( EddAmbTND(:,5,i) ) = .true. + InvalidOutput( EddShrTND(:,5,i) ) = .true. + InvalidOutput( WkDfVxTND(:,6,i) ) = .true. + InvalidOutput( WkDfVrTND(:,6,i) ) = .true. + InvalidOutput( EddVisTND(:,6,i) ) = .true. + InvalidOutput( EddAmbTND(:,6,i) ) = .true. + InvalidOutput( EddShrTND(:,6,i) ) = .true. + InvalidOutput( WkDfVxTND(:,7,i) ) = .true. + InvalidOutput( WkDfVrTND(:,7,i) ) = .true. + InvalidOutput( EddVisTND(:,7,i) ) = .true. + InvalidOutput( EddAmbTND(:,7,i) ) = .true. + InvalidOutput( EddShrTND(:,7,i) ) = .true. + InvalidOutput( WkDfVxTND(:,8,i) ) = .true. + InvalidOutput( WkDfVrTND(:,8,i) ) = .true. + InvalidOutput( EddVisTND(:,8,i) ) = .true. + InvalidOutput( EddAmbTND(:,8,i) ) = .true. + InvalidOutput( EddShrTND(:,8,i) ) = .true. + InvalidOutput( WkDfVxTND(:,9,i) ) = .true. + InvalidOutput( WkDfVrTND(:,9,i) ) = .true. + InvalidOutput( EddVisTND(:,9,i) ) = .true. + InvalidOutput( EddAmbTND(:,9,i) ) = .true. + InvalidOutput( EddShrTND(:,9,i) ) = .true. + + end do + + + ! Curled/Cartesian wake checks + do i = 1,farm%p%NOutTurb ! Valid turbine number + if (farm%WD(i)%p%Mod_Wake /= Mod_Wake_Polar) then + ! Polar outputs not available + do j =1, 9 ! Diameters + InvalidOutput( WkDfVxTND(:,j,i) ) = .true. + InvalidOutput( WkDfVrTND(:,j,i) ) = .true. + InvalidOutput( EddVisTND(:,j,i) ) = .true. + InvalidOutput( EddAmbTND(:,j,i) ) = .true. + InvalidOutput( EddShrTND(:,j,i) ) = .true. + enddo + endif + if (farm%WD(i)%p%Mod_Wake /= Mod_Wake_Curl) then + ! Curled variables not valid + InvalidOutput( RtGamCurlT (i) ) = .true. + endif + end do + + do i = farm%SC%p%nInpGlobal+1,9 + InvalidOutput( SCGblIn (i ) ) = .true. + end do + + do i = farm%SC%p%NumSC2CtrlGlob+1,9 + InvalidOutput( SCGblOt (i ) ) = .true. + end do + + do i = farm%SC%p%NumCtrl2SC+1,9 + InvalidOutput( SCTIn (i,:) ) = .true. + end do + + do i = farm%SC%p%NumSC2Ctrl+1,9 + InvalidOutput( SCTOt (i,:) ) = .true. + end do + + ! Add checks for the WindVel locations based on knowledge of the wind grids and NWindVel + do i = 1, farm%p%NWindVel + if (.not. PointInAABB(farm%p%WindVelX(i), farm%p%WindVelY(i), farm%p%WindVelZ(i), farm%AWAE%p%X0_low, farm%AWAE%p%Y0_low,farm%AWAE%p%Z0_low, farm%AWAE%p%X0_low+(farm%AWAE%p%nX_low-1)*farm%AWAE%p%dX_low, farm%AWAE%p%Y0_low+(farm%AWAE%p%nY_low-1)*farm%AWAE%p%dY_low, farm%AWAE%p%Z0_low+(farm%AWAE%p%nZ_low-1)*farm%AWAE%p%dZ_low) ) then + InvalidOutput( WVAmbX (i) ) = .true. + InvalidOutput( WVAmbY (i) ) = .true. + InvalidOutput( WVAmbZ (i) ) = .true. + InvalidOutput( WVDisX (i) ) = .true. + InvalidOutput( WVDisY (i) ) = .true. + InvalidOutput( WVDisZ (i) ) = .true. + end if + end do + + do i = farm%p%NWindVel+1, 9 + InvalidOutput( WVAmbX (i) ) = .true. + InvalidOutput( WVAmbY (i) ) = .true. + InvalidOutput( WVAmbZ (i) ) = .true. + InvalidOutput( WVDisX (i) ) = .true. + InvalidOutput( WVDisY (i) ) = .true. + InvalidOutput( WVDisZ (i) ) = .true. + end do + ! +! ................. End of validity checking ................. + + + !------------------------------------------------------------------------------------------------- + ! 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. + !------------------------------------------------------------------------------------------------- + + ALLOCATE ( farm%p%OutParam(0:farm%p%NumOuts) , STAT=ErrStat2 ) + IF ( ErrStat2 /= 0_IntKi ) THEN + CALL SetErrStat( ErrID_Fatal,"Error allocating memory for the fast-farm OutParam array.", ErrStat, ErrMsg, RoutineName ) + RETURN + ENDIF + + ! Set index, name, and units for the time output channel: + + farm%p%OutParam(0)%Indx = Farm_Time_Indx + farm%p%OutParam(0)%Name = "Time" ! OutParam(0) is the time channel by default. + farm%p%OutParam(0)%Units = "(s)" + farm%p%OutParam(0)%SignM = 1 + + + ! Set index, name, and units for all of the output channels. + ! If a selected output channel is not available by this module set ErrStat = ErrID_Warn. + + DO I = 1,farm%p%NumOuts + + farm%p%OutParam(I)%Name = OutList(I) + + Indx = FindValidChannelIndx(OutList(I), ValidParamAry, farm%p%OutParam(I)%SignM) + + + IF ( Indx > 0 ) THEN ! we found the channel name + IF ( InvalidOutput( ParamIndxAry(Indx) ) ) THEN ! but, it isn't valid for these settings + farm%p%OutParam(I)%Indx = 0 ! pick any valid channel (I just picked "Time=0" here because it's universal) + farm%p%OutParam(I)%Units = "INVALID" + farm%p%OutParam(I)%SignM = 0 + ELSE + farm%p%OutParam(I)%Indx = ParamIndxAry(Indx) + farm%p%OutParam(I)%Units = ParamUnitsAry(Indx) ! it's a valid output + END IF + ELSE ! this channel isn't valid + farm%p%OutParam(I)%Indx = 0 ! pick any valid channel (I just picked "Time=0" here because it's universal) + farm%p%OutParam(I)%Units = "INVALID" + farm%p%OutParam(I)%SignM = 0 ! multiply all results by zero + + CALL SetErrStat(ErrID_Fatal, TRIM(farm%p%OutParam(I)%Name)//" is not an available output channel.",ErrStat,ErrMsg,RoutineName) + END IF + + END DO + + RETURN +END SUBROUTINE Farm_SetOutParam +!---------------------------------------------------------------------------------------------------------------------------------- +!End of code generated by Matlab script +!********************************************************************************************************************************** +END MODULE FAST_Farm_IO_Params diff --git a/glue-codes/fast-farm/src/FAST_Farm_Registry.txt b/glue-codes/fast-farm/src/FAST_Farm_Registry.txt index 0f20a1d3f..9f595b55c 100644 --- a/glue-codes/fast-farm/src/FAST_Farm_Registry.txt +++ b/glue-codes/fast-farm/src/FAST_Farm_Registry.txt @@ -17,12 +17,13 @@ usefrom WakeDynamics_Registry.txt usefrom AWAE_Registry.txt usefrom SuperController_Registry.txt -param FAST_Farm/Farm - INTEGER NumFFModules - 4 - "The number of modules available in FAST.Farm" - +param FAST_Farm/Farm - INTEGER NumFFModules - 5 - "The number of modules available in FAST.Farm" - param ^ - INTEGER ModuleFF_None - 0 - "No module selected" - param ^ - INTEGER ModuleFF_SC - 1 - "Super Controller" - param ^ - INTEGER ModuleFF_FWrap - 2 - "FAST Wrapper" - param ^ - INTEGER ModuleFF_WD - 3 - "Wake Dynamics" - param ^ - INTEGER ModuleFF_AWAE - 4 - "Ambient Wind and Array Effects" - +param ^ - INTEGER ModuleFF_MD - 5 - "Farm-level MoorDyn" - # ..... Parameters ................................................................................................................ typedef FAST_Farm/Farm ParameterType DbKi DT_low - - - "Time step for low-resolution wind data input files; will be used as the global FAST.Farm time step" seconds typedef ^ ParameterType DbKi DT_high - - - "High-resolution time step" seconds @@ -31,8 +32,13 @@ typedef ^ ParameterType IntKi n_high_low - typedef ^ ParameterType IntKi NumTurbines - - - "Number of turbines in the simulation" - typedef ^ ParameterType CHARACTER(1024) WindFilePath - - - "Path name of wind data files from ABLSolver precursor" - typedef ^ ParameterType CHARACTER(1024) SC_FileName - - - "Name/location of the dynamic library {.dll [Windows] or .so [Linux]} containing the Super Controller algorithms" - -typedef ^ ParameterType LOGICAL UseSC - - - "Use a super controller?" - +typedef ^ ParameterType LOGICAL UseSC - - - "Use a super controller?" - typedef ^ ParameterType ReKi WT_Position {:}{:} - - "X-Y-Z position of each wind turbine; index 1 = XYZ; index 2 = turbine number" meters +typedef ^ ParameterType IntKi WaveFieldMod - - - "Wave field handling (-) (switch) {0: use individual HydroDyn inputs without adjustment, 1: adjust wave phases based on turbine offsets from farm origin}" - +typedef ^ ParameterType IntKi MooringMod - - - "Mod_SharedMooring is a flag for array-level mooring. (switch) {0: none, 3: yes/MoorDyn}" - +typedef ^ ParameterType CHARACTER(1024) MD_FileName - - - "Name/location of the farm-level MoorDyn input file" - +typedef ^ ParameterType DbKi DT_mooring - - - "Time step for farm-levem mooring coupling with each turbine [used only when Mod_SharedMooring > 0]" seconds +typedef ^ ParameterType IntKi n_mooring - - - "Number of FAST and MoorDyn time steps per FAST.Farm timestep when mooring > 0" - typedef ^ ParameterType CHARACTER(1024) WT_FASTInFile {:} - - "Name of input file for each turbine" - typedef ^ ParameterType CHARACTER(1024) FTitle - - - "The description line from the primary FAST.Farm input file" - typedef ^ ParameterType CHARACTER(1024) OutFileRoot - - - "The root name derived from the primary FAST.Farm input file" - @@ -79,6 +85,10 @@ typedef ^ ^ DbKi TimeData {:} - - "Array typedef ^ ^ ReKi AllOutData {:}{:} - - "Array to contain all the output data (time history of all outputs); Index 1 is NumOuts, Index 2 is Time step" typedef ^ ^ IntKi n_Out - - - "Time index into the AllOutData array" +typedef ^ MiscVarType MeshMapType FWrap_2_MD {:} - - "Map platform kinematics from each FAST instance to MD" +typedef ^ MiscVarType MeshMapType MD_2_FWrap {:} - - "Map MD loads at the array level to each FAST instance" + + # ..... FASTWrapper data ....................................................................................................... typedef ^ FASTWrapper_Data FWrap_ContinuousStateType x - - - "Continuous states" typedef ^ ^ FWrap_DiscreteStateType xd - - - "Discrete states" @@ -122,6 +132,18 @@ typedef ^ ^ DbKi utimes {1} - typedef ^ ^ SC_OutputType y - - - "System outputs" typedef ^ ^ SC_MiscVarType m - - - "Misc/optimization variables" typedef ^ ^ logical IsInitialized - .FALSE. - "Has SC_Init been called" +# ..... MD data ....................................................................................................... +typedef ^ MD_Data MD_ContinuousStateType x - - - "Continuous states" +typedef ^ ^ MD_DiscreteStateType xd - - - "Discrete states" +typedef ^ ^ MD_ConstraintStateType z - - - "Constraint states" +typedef ^ ^ MD_OtherStateType OtherSt - - - "Other states" +typedef ^ ^ MD_ParameterType p - - - "Parameters" +typedef ^ ^ MD_InputType u - - - "Extrapolated system inputs" +typedef ^ ^ MD_InputType Input {:} - - "System inputs" +typedef ^ ^ DbKi InputTimes {:} - - "Current time" s +typedef ^ ^ MD_OutputType y - - - "System outputs" +typedef ^ ^ MD_MiscVarType m - - - "Misc/optimization variables" +typedef ^ ^ logical IsInitialized - .FALSE. - "Has MD_Init been called" # ..... All submodules' variables................................................................................................. typedef ^ All_FastFarm_Data Farm_ParameterType p - - - "FAST.Farm parameter data" - typedef ^ All_FastFarm_Data Farm_MiscVarType m - - - "FAST.Farm misc var data" - @@ -129,5 +151,6 @@ typedef ^ All_FastFarm_Data FASTWrapper_Data FWrap {:} - - typedef ^ All_FastFarm_Data WakeDynamics_Data WD {:} - - "WakeDynamics (WD) data" - typedef ^ All_FastFarm_Data AWAE_Data AWAE - - - "Ambient Wind & Array Effects (AWAE) data" - typedef ^ All_FastFarm_Data SC_Data SC - - - "Super Controller (SC) data" - +typedef ^ All_FastFarm_Data MD_Data MD - - - "Farm-level MoorDyn model data" - # ..... FAST.Farm data ................................................................................................................ # diff --git a/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 b/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 index 6bcae36be..8fa232a62 100644 --- a/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 +++ b/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 @@ -44,6 +44,7 @@ MODULE FAST_Farm_Subs integer, parameter :: maxOutputPoints = 9 + integer, parameter :: maxOutputPlanes = 99 ! Allow up to 99 outpt planes CONTAINS @@ -294,8 +295,8 @@ SUBROUTINE Farm_Initialize( farm, InputFile, ErrStat, ErrMsg ) SC_InitOut%NumSC2CtrlGlob = 0 SC_InitOut%NumSC2Ctrl = 0 SC_InitOut%NumCtrl2SC = 0 - allocate(farm%SC%y%fromscglob(0)) - allocate(farm%SC%y%fromsc(0)) + allocate(farm%SC%y%fromSCglob(0)) + allocate(farm%SC%y%fromSC(0)) end if !------------------- @@ -319,6 +320,19 @@ SUBROUTINE Farm_Initialize( farm, InputFile, ErrStat, ErrMsg ) CALL Cleanup() RETURN END IF + + !............................................................................................................................... + ! step 4.5: initialize farm-level MoorDyn if applicable + !............................................................................................................................... + + if (farm%p%MooringMod == 3) then + CALL Farm_InitMD( farm, ErrStat2, ErrMsg2) ! FAST instances must be initialized first so that turbine initial positions are known + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF (ErrStat >= AbortErrLev) THEN + CALL Cleanup() + RETURN + END IF + end if !............................................................................................................................... ! step 5: Open output file (or set up output file handling) @@ -395,6 +409,8 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init INTEGER(IntKi) :: ErrStat2 ! Temporary Error status CHARACTER(ErrMsgLen) :: ErrMsg2 ! Temporary Error message CHARACTER(*), PARAMETER :: RoutineName = 'Farm_ReadPrimaryFile' + Real(ReKi) :: DefaultReVal ! Default real value + Real(ReKi) :: EstimatedRotorRadius ! Estimated rotor radius ! Initialize some variables: @@ -537,6 +553,22 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init RETURN end if + ! Mod_WaveField - Wave field handling (-) (switch) {1: use individual HydroDyn inputs without adjustment, 2: adjust wave phases based on turbine offsets from farm origin} + CALL ReadVar( UnIn, InputFile, p%WaveFieldMod, "Mod_WaveField", "Wave field handling (-) (switch) {1: use individual HydroDyn inputs without adjustment, 2: adjust wave phases based on turbine offsets from farm origin}", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if ( ErrStat >= AbortErrLev ) then + call cleanup() + RETURN + end if + + ! Mod_SharedMooring - flag for array-level mooring. (switch) 0: none, 3: yes/MoorDyn + CALL ReadVar( UnIn, InputFile, p%MooringMod, "Mod_SharedMooring", "Array-level mooring handling (-) (switch) {0: none; 3: array-level MoorDyn model}", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if ( ErrStat >= AbortErrLev ) then + call cleanup() + RETURN + end if + !---------------------- SUPER CONTROLLER ------------------------------------------------------------------ CALL ReadCom( UnIn, InputFile, 'Section Header: Super Controller', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -554,6 +586,31 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init end if IF ( PathIsRelative( p%SC_FileName ) ) p%SC_FileName = TRIM(PriPath)//TRIM(p%SC_FileName) SC_InitInp%DLL_FileName = p%SC_FileName + + !---------------------- SHARED MOORING SYSTEM ------------------------------------------------------------------ + CALL ReadCom( UnIn, InputFile, 'Section Header: SHARED MOORING SYSTEM', ErrStat2, ErrMsg2, UnEc ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if ( ErrStat >= AbortErrLev ) then + call cleanup() + RETURN + end if + + ! MD_FileName - Name/location of the farm-level MoorDyn input file (quoated string): + CALL ReadVar( UnIn, InputFile, p%MD_FileName, "MD_FileName", "Name/location of the dynamic library {.dll [Windows] or .so [Linux]} containing the Super Controller algorithms (quoated string)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if ( ErrStat >= AbortErrLev ) then + call cleanup() + RETURN + end if + IF ( PathIsRelative( p%MD_FileName ) ) p%MD_FileName = TRIM(PriPath)//TRIM(p%MD_FileName) + + ! DT_Mooring - time step for farm-level mooring coupling with each turbine [used only when Mod_SharedMooring > 0] (s) [>0.0]: + CALL ReadVar( UnIn, InputFile, p%DT_mooring, "DT_Mooring", "Time step for farm-levem mooring coupling with each turbine [used only when Mod_SharedMooring > 0] (s) [>0.0]", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if ( ErrStat >= AbortErrLev ) then + call cleanup() + RETURN + end if !---------------------- AMBIENT WIND: PRECURSOR IN VTK FORMAT --------------------------------------------- CALL ReadCom( UnIn, InputFile, 'Section Header: Ambient Wind: Precursor in VTK Format', ErrStat2, ErrMsg2, UnEc ) @@ -817,34 +874,19 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init end if - ! dr - Radial increment of radial finite-difference grid (m) [>0.0]: - CALL ReadVar( UnIn, InputFile, WD_InitInp%dr, "dr", "Radial increment of radial finite-difference grid (m) [>0.0]", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - if ( ErrStat >= AbortErrLev ) then - call cleanup() - RETURN - end if + CALL ReadVar( UnIn, InputFile, WD_InitInp%Mod_Wake, "Mod_Wake", "Wake model", ErrStat2, ErrMsg2, UnEc); if(failed()) return + CALL ReadVar( UnIn, InputFile, WD_InitInp%dr , "dr", "Radial increment of radial finite-difference grid (m) [>0.0]", ErrStat2, ErrMsg2, UnEc); if(failed()) return + CALL ReadVar( UnIn, InputFile, WD_InitInp%NumRadii, "NumRadii", "Number of radii in the radial finite-difference grid (-) [>=2]", ErrStat2, ErrMsg2, UnEc); if(failed()) return + CALL ReadVar( UnIn, InputFile, WD_InitInp%NumPlanes,"NumPlanes", "Number of wake planes (-) [>=2]", ErrStat2, ErrMsg2, UnEc); if(failed()) return - ! NumRadii - Number of radii in the radial finite-difference grid (-) [>=2]: - CALL ReadVar( UnIn, InputFile, WD_InitInp%NumRadii, "NumRadii", "Number of radii in the radial finite-difference grid (-) [>=2]", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - if ( ErrStat >= AbortErrLev ) then - call cleanup() - RETURN - end if - - ! NumPlanes - Number of wake planes (-) [>=2]: - CALL ReadVar( UnIn, InputFile, WD_InitInp%NumPlanes, "NumPlanes", "Number of wake planes (-) [>=2]", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - if ( ErrStat >= AbortErrLev ) then - call cleanup() - RETURN - end if - + ! Estimate rotor raidus based on grid size, if user follow approximately the guidelines + EstimatedRotorRadius = (WD_InitInp%dr * WD_InitInp%NumRadii) / 3._ReKi + ! f_c - Cut-off (corner) frequency of the low-pass time-filter for the wake advection, deflection, and meandering model (Hz) [>0.0] or DEFAULT [DEFAULT=0.0007]: + DefaultReVal = 12.5_ReKi/EstimatedRotorRadius ! Eq. (32) of https://doi.org/10.1002/we.2785, with U=10, a=1/3 CALL ReadVarWDefault( UnIn, InputFile, WD_InitInp%f_c, "f_c", & "Cut-off (corner) frequency of the low-pass time-filter for the wake advection, deflection, and meandering model (Hz) [>0.0] or DEFAULT [DEFAULT=0.0007]", & - 0.0007_ReKi, ErrStat2, ErrMsg2, UnEc) + DefaultReVal, ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() @@ -862,9 +904,14 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init end if ! C_HWkDfl_OY - Calibrated parameter in the correction for wake deflection defining the horizontal offset at the rotor scaled with yaw error (m/deg) or DEFAULT [DEFAULT=0.3]: + if (WD_InitInp%Mod_Wake == Mod_Wake_Curl) then + DefaultReVal = 0.0_ReKi + else + DefaultReVal = 0.3_ReKi + endif CALL ReadVarWDefault( UnIn, InputFile, WD_InitInp%C_HWkDfl_OY, "C_HWkDfl_OY", & "Calibrated parameter in the correction for wake deflection defining the horizontal offset at the rotor scaled with yaw error (m/deg) or DEFAULT [DEFAULT=0.3]", & - 0.3_ReKi, ErrStat2, ErrMsg2, UnEc) + DefaultReVal, ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() @@ -883,9 +930,14 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init end if ! C_HWkDfl_xY - Calibrated parameter in the correction for wake deflection defining the horizontal offset scaled with downstream distance and yaw error (1/deg) or DEFAULT [DEFAULT=-0.004]: + if (WD_InitInp%Mod_Wake == Mod_Wake_Curl) then + DefaultReVal = 0.0_ReKi + else + DefaultReVal = -0.004_ReKi + endif CALL ReadVarWDefault( UnIn, InputFile, WD_InitInp%C_HWkDfl_xY, "C_HWkDfl_xY", & "Calibrated parameter in the correction for wake deflection defining the horizontal offset scaled with downstream distance and yaw error (1/deg) or DEFAULT [DEFAULT=-0.004]", & - -0.004_ReKi, ErrStat2, ErrMsg2, UnEc) + DefaultReVal, ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() @@ -1022,7 +1074,7 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init if ( ErrStat >= AbortErrLev ) then call cleanup() RETURN - end if + end if ! Mod_Meander - Spatial filter model for wake meandering (-) (switch) {1: uniform, 2: truncated jinc, 3: windowed jinc} or DEFAULT [DEFAULT=3]: CALL ReadVarWDefault( UnIn, InputFile, AWAE_InitInp%Mod_Meander, "Mod_Meander", & @@ -1044,6 +1096,37 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init RETURN end if + !----------------------- CURL WAKE PARAMETERS ------------------------------------------ + CALL ReadCom ( UnIn, InputFile, "Section Header: Curl wake parameters", ErrStat2, ErrMsg2, UnEc ); if(failed()) return + CALL ReadVarWDefault( UnIn, InputFile, WD_InitInp%Swirl , "Swirl", "Swirl switch", .True., ErrStat2, ErrMsg2, UnEc); if(failed()) return + CALL ReadVarWDefault( UnIn, InputFile, WD_InitInp%k_VortexDecay, "k_VortexDecay", "Vortex decay constant", 0.01, ErrStat2, ErrMsg2, UnEc); if(failed()) return + CALL ReadVarWDefault( UnIn, InputFile, WD_InitInp%NumVortices, "NumVortices", "Number of vortices in the curled wake", 100, ErrStat2, ErrMsg2, UnEc); if(failed()) return + CALL ReadVarWDefault( UnIn, InputFile, WD_InitInp%sigma_D, "sigma_D", "Gaussian vortex width", 0.2, ErrStat2, ErrMsg2, UnEc); if(failed()) return + CALL ReadVarWDefault( UnIn, InputFile, WD_InitInp%FilterInit, "FilterInit", "Filter Init", 1 , ErrStat2, ErrMsg2, UnEc); if(failed()) return + CALL ReadVarWDefault( UnIn, InputFile, WD_InitInp%k_vCurl, "k_vCurl", "Eddy viscosity for curl", 2.0 , ErrStat2, ErrMsg2, UnEc); if(failed()) return + CALL ReadVarWDefault( UnIn, InputFile, AWAE_InitInp%Mod_Projection, "Mod_Projection", "Mod_Projection", -1 , ErrStat2, ErrMsg2, UnEc); if(failed()) return + if (AWAE_InitInp%Mod_Projection==-1) then + ! -1 means the user selected "default" + if (WD_InitInp%Mod_Wake==Mod_Wake_Curl) then + AWAE_InitInp%Mod_Projection=2 + else + AWAE_InitInp%Mod_Projection=1 + endif + endif + !----------------------- WAKE-ADDED TURBULENCE ------------------------------------------ + ! Read WAT variables + WD_InitInp%WAT_k_Def =1.0_ReKi + WD_InitInp%WAT_k_Grad =1.0_ReKi + WD_InitInp%WAT = .false. ! initialize to false to avoid segfault + !CALL ReadCom( UnIn, InputFile, 'Section Header: Wake-added turbulence', ErrStat2, ErrMsg2, UnEc ) + !CALL ReadVar( UnIn, InputFile, WD_InitInp%WAT, "WAT", "Switch for turning on and off wake-added turbulence", ErrStat2, ErrMsg2, UnEc); if(failed()) return + !CALL ReadCom( UnIn, InputFile, 'dummy predef', ErrStat2, ErrMsg2, UnEc ) + !CALL ReadCom( UnIn, InputFile, 'dummy user', ErrStat2, ErrMsg2, UnEc ) + !CALL ReadCom( UnIn, InputFile, 'dummy userdx', ErrStat2, ErrMsg2, UnEc ) + !CALL ReadVarWDefault( UnIn, InputFile, WD_InitInp%WAT_k_Def, "WAT_k_Def, "Calibrated parameter for the influence of the wake deficit in the wake-added Turbulence (-) [>=0.0] or DEFAULT [DEFAULT=1.44]", 1.44_ReKi, ErrStat2, ErrMsg2, UnEc); if(failed()) return + !CALL ReadVarWDefault( UnIn, InputFile, WD_InitInp%WAT_k_Grad, "WAT_k_Grad", "Calibrated parameter for the influence of the radial velocity gradient of the wake deficit in the wake-added Turbulence (-) [>=0.0] or DEFAULT [DEFAULT=0.84]", 0.84_ReKi, ErrStat2, ErrMsg2, UnEc); if(failed()) return + !IF ( PathIsRelative( p%File ) )p%File = TRIM(PriPath)//TRIM(p%File) + !---------------------- VISUALIZATION -------------------------------------------------- CALL ReadCom( UnIn, InputFile, 'Section Header: Visualization', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -1057,7 +1140,7 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init end if ! NOutDisWindXY - Number of XY planes for output of disturbed wind data across the low-resolution domain to .Low.DisXY..t.vtk (-) [0 to 9]: - CALL ReadVar( UnIn, InputFile, AWAE_InitInp%NOutDisWindXY, "NOutDisWindXY", "Number of XY planes for output of disturbed wind data across the low-resolution domain to .Low.DisXY..t.vtk (-) [0 to 9]", ErrStat2, ErrMsg2, UnEc) + CALL ReadVar( UnIn, InputFile, AWAE_InitInp%NOutDisWindXY, "NOutDisWindXY", "Number of XY planes for output of disturbed wind data across the low-resolution domain to .Low.DisXY..t.vtk (-) [0 to 99]", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() @@ -1080,7 +1163,7 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init end if ! NOutDisWindYZ - Number of YZ planes for output of disturbed wind data across the low-resolution domain to .Low.DisYZ..t.vtk (-) [0 to 9]: - CALL ReadVar( UnIn, InputFile, AWAE_InitInp%NOutDisWindYZ, "NOutDisWindYZ", "Number of YZ planes for output of disturbed wind data across the low-resolution domain to .Low.DisYZ..t.vtk (-) [0 to 9]", ErrStat2, ErrMsg2, UnEc) + CALL ReadVar( UnIn, InputFile, AWAE_InitInp%NOutDisWindYZ, "NOutDisWindYZ", "Number of YZ planes for output of disturbed wind data across the low-resolution domain to .Low.DisYZ..t.vtk (-) [0 to 99]", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() @@ -1103,7 +1186,7 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init end if ! NOutDisWindXZ - Number of XZ planes for output of disturbed wind data across the low-resolution domain to .Low/DisXZ..t.vtk (-) [0 to 9]: - CALL ReadVar( UnIn, InputFile, AWAE_InitInp%NOutDisWindXZ, "NOutDisWindXZ", "Number of XZ planes for output of disturbed wind data across the low-resolution domain to .Low/DisXZ..t.vtk (-) [0 to 9]", ErrStat2, ErrMsg2, UnEc) + CALL ReadVar( UnIn, InputFile, AWAE_InitInp%NOutDisWindXZ, "NOutDisWindXZ", "Number of XZ planes for output of disturbed wind data across the low-resolution domain to .Low/DisXZ..t.vtk (-) [0 to 99]", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if ( ErrStat >= AbortErrLev ) then call cleanup() @@ -1231,6 +1314,10 @@ SUBROUTINE Farm_ReadPrimaryFile( InputFile, p, WD_InitInp, AWAE_InitInp, SC_Init RETURN end if + + CALL ReadVarWDefault( UnIn, InputFile, WD_InitInp%OutAllPlanes, "OutAllPlanes", "Output all planes", .False., ErrStat2, ErrMsg2, UnEc); if(failed()) return + + ! NOutRadii - Number of radial nodes for wake output for an individual rotor (-) [0 to 20]: CALL ReadVar( UnIn, InputFile, p%NOutRadii, "NOutRadii", "Number of radial nodes for wake output for an individual rotor (-) [0 to 20]", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -1345,6 +1432,12 @@ subroutine cleanup() CLOSE( UnIn ) IF ( UnEc > 0 ) CLOSE ( UnEc ) end subroutine cleanup + + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + Failed = ErrStat >= AbortErrLev + if (Failed) call cleanup() + end function Failed !............................................................................................................................... END SUBROUTINE Farm_ReadPrimaryFile !---------------------------------------------------------------------------------------------------------------------------------- @@ -1367,6 +1460,12 @@ SUBROUTINE Farm_ValidateInput( p, WD_InitInp, AWAE_InitInp, SC_InitInp, ErrStat, ErrStat = ErrID_None ErrMsg = "" + + ! --- SIMULATION CONTROL --- + IF ((p%WaveFieldMod .ne. 1) .and. (p%WaveFieldMod .ne. 2)) CALL SetErrStat(ErrID_Fatal,'WaveFieldMod must be 1 or 2.',ErrStat,ErrMsg,RoutineName) + IF ((p%MooringMod .ne. 0) .and. (p%MooringMod .ne. 3)) CALL SetErrStat(ErrID_Fatal,'MooringMod must be 0 or 3.',ErrStat,ErrMsg,RoutineName) + + IF (p%DT_low <= 0.0_ReKi) CALL SetErrStat(ErrID_Fatal,'DT_low must be positive.',ErrStat,ErrMsg,RoutineName) IF (p%DT_high <= 0.0_ReKi) CALL SetErrStat(ErrID_Fatal,'DT_high must be positive.',ErrStat,ErrMsg,RoutineName) IF (p%TMax < 0.0_ReKi) CALL SetErrStat(ErrID_Fatal,'TMax must not be negative.',ErrStat,ErrMsg,RoutineName) @@ -1375,16 +1474,24 @@ SUBROUTINE Farm_ValidateInput( p, WD_InitInp, AWAE_InitInp, SC_InitInp, ErrStat, ! --- SUPER CONTROLLER --- ! TODO : Verify that the DLL file exists - + ! --- SHARED MOORING SYSTEM --- + ! TODO : Verify that p%MD_FileName file exists + if ((p%DT_mooring <= 0.0_ReKi) .or. (p%DT_mooring > p%DT_high)) CALL SetErrStat(ErrID_Fatal,'DT_mooring must be greater than zero and no greater than dt_high.',ErrStat,ErrMsg,RoutineName) + ! --- WAKE DYNAMICS --- + IF (WD_InitInp%Mod_Wake < 1 .or. WD_InitInp%Mod_Wake >3 ) CALL SetErrStat(ErrID_Fatal,'Mod_Wake needs to be 1,2 or 3',ErrStat,ErrMsg,RoutineName) IF (WD_InitInp%dr <= 0.0_ReKi) CALL SetErrStat(ErrID_Fatal,'dr (radial increment) must be larger than 0.',ErrStat,ErrMsg,RoutineName) IF (WD_InitInp%NumRadii < 2) CALL SetErrStat(ErrID_Fatal,'NumRadii (number of radii) must be at least 2.',ErrStat,ErrMsg,RoutineName) IF (WD_InitInp%NumPlanes < 2) CALL SetErrStat(ErrID_Fatal,'NumPlanes (number of wake planes) must be at least 2.',ErrStat,ErrMsg,RoutineName) + IF (WD_InitInp%k_VortexDecay < 0.0_ReKi) CALL SetErrStat(ErrID_Fatal,'k_VortexDecay needs to be postive',ErrStat,ErrMsg,RoutineName) + IF (WD_InitInp%NumVortices < 2) CALL SetErrStat(ErrID_Fatal,'NumVorticies needs to be greater than 1',ErrStat,ErrMsg,RoutineName) + IF (WD_InitInp%sigma_D < 0.0_ReKi) CALL SetErrStat(ErrID_Fatal,'sigma_D needs to be postive',ErrStat,ErrMsg,RoutineName) IF (WD_InitInp%f_c <= 0.0_ReKi) CALL SetErrStat(ErrID_Fatal,'f_c (cut-off [corner] frequency) must be more than 0 Hz.',ErrStat,ErrMsg,RoutineName) IF (WD_InitInp%C_NearWake <= 1.0_Reki) CALL SetErrStat(ErrID_Fatal,'C_NearWake parameter must be greater than 1.',ErrStat,ErrMsg,RoutineName) IF (WD_InitInp%k_vAmb < 0.0_Reki) CALL SetErrStat(ErrID_Fatal,'k_vAmb parameter must not be negative.',ErrStat,ErrMsg,RoutineName) IF (WD_InitInp%k_vShr < 0.0_Reki) CALL SetErrStat(ErrID_Fatal,'k_vShr parameter must not be negative.',ErrStat,ErrMsg,RoutineName) + IF (WD_InitInp%k_vCurl < 0.0_Reki) CALL SetErrStat(ErrID_Fatal,'k_vCurl parameter must not be negative.',ErrStat,ErrMsg,RoutineName) IF (WD_InitInp%C_vAmb_DMin < 0.0_Reki) CALL SetErrStat(ErrID_Fatal,'C_vAmb_DMin parameter must not be negative.',ErrStat,ErrMsg,RoutineName) IF (WD_InitInp%C_vAmb_DMax <= WD_InitInp%C_vAmb_DMin) CALL SetErrStat(ErrID_Fatal,'C_vAmb_DMax parameter must be larger than C_vAmb_DMin.',ErrStat,ErrMsg,RoutineName) @@ -1406,14 +1513,23 @@ SUBROUTINE Farm_ValidateInput( p, WD_InitInp, AWAE_InitInp, SC_InitInp, ErrStat, END IF END IF - IF (AWAE_InitInp%Mod_Meander < MeanderMod_Uniform .or. AWAE_InitInp%Mod_Meander > MeanderMod_WndwdJinc) THEN - call SetErrStat(ErrID_Fatal,'Spatial filter model for wake meandering, Mod_Meander, must be 1 (uniform), 2 (truncated jinc), 3 (windowed jinc) or DEFAULT.',ErrStat,ErrMsg,RoutineName) - END IF + IF (AWAE_InitInp%C_Meander < 1.0_Reki) THEN CALL SetErrStat(ErrID_Fatal,'C_Meander parameter must not be less than 1.',ErrStat,ErrMsg,RoutineName) END IF + + ! --- CURL + IF (WD_InitInp%FilterInit < 0 ) CALL SetErrStat(ErrID_Fatal,'FilterInit needs to >= 0',ErrStat,ErrMsg,RoutineName) + IF (AWAE_InitInp%Mod_Meander < MeanderMod_Uniform .or. AWAE_InitInp%Mod_Meander > MeanderMod_WndwdJinc) THEN + call SetErrStat(ErrID_Fatal,'Spatial filter model for wake meandering, Mod_Meander, must be 1 (uniform), 2 (truncated jinc), 3 (windowed jinc) or DEFAULT.',ErrStat,ErrMsg,RoutineName) + END IF + IF (.not.(ANY((/1,2/)==AWAE_InitInp%Mod_Projection))) CALL SetErrStat(ErrID_Fatal,'Mod_Projection needs to be 1 or 2',ErrStat,ErrMsg,RoutineName) + ! --- WAT + IF (WD_InitInp%WAT_k_Def <= 0.0_Reki) CALL SetErrStat(ErrID_Fatal,'WAT_k_Def parameter must be positive.',ErrStat,ErrMsg,RoutineName) + IF (WD_InitInp%WAT_k_Grad <= 0.0_Reki) CALL SetErrStat(ErrID_Fatal,'WAT_k_Grad parameter must be positive.',ErrStat,ErrMsg,RoutineName) + !--- OUTPUT --- IF ( p%n_ChkptTime < 1_IntKi ) CALL SetErrStat( ErrID_Fatal, 'ChkptTime must be greater than 0 seconds.', ErrStat, ErrMsg, RoutineName ) IF (p%TStart < 0.0_ReKi) CALL SetErrStat(ErrID_Fatal,'TStart must not be negative.',ErrStat,ErrMsg,RoutineName) @@ -1430,9 +1546,9 @@ SUBROUTINE Farm_ValidateInput( p, WD_InitInp, AWAE_InitInp, SC_InitInp, ErrStat, AWAE_InitInp%WrDisDT = p%DT_low * n_disDT_dt - if (AWAE_InitInp%NOutDisWindXY < 0 .or. AWAE_InitInp%NOutDisWindXY > maxOutputPoints ) CALL SetErrStat( ErrID_Fatal, 'NOutDisWindXY must be in the range [0, 9].', ErrStat, ErrMsg, RoutineName ) - if (AWAE_InitInp%NOutDisWindYZ < 0 .or. AWAE_InitInp%NOutDisWindYZ > maxOutputPoints ) CALL SetErrStat( ErrID_Fatal, 'NOutDisWindYZ must be in the range [0, 9].', ErrStat, ErrMsg, RoutineName ) - if (AWAE_InitInp%NOutDisWindXZ < 0 .or. AWAE_InitInp%NOutDisWindXZ > maxOutputPoints ) CALL SetErrStat( ErrID_Fatal, 'NOutDisWindXZ must be in the range [0, 9].', ErrStat, ErrMsg, RoutineName ) + if (AWAE_InitInp%NOutDisWindXY < 0 .or. AWAE_InitInp%NOutDisWindXY > maxOutputPlanes ) CALL SetErrStat( ErrID_Fatal, 'NOutDisWindXY must be in the range [0, 99].', ErrStat, ErrMsg, RoutineName ) + if (AWAE_InitInp%NOutDisWindYZ < 0 .or. AWAE_InitInp%NOutDisWindYZ > maxOutputPlanes ) CALL SetErrStat( ErrID_Fatal, 'NOutDisWindYZ must be in the range [0, 99].', ErrStat, ErrMsg, RoutineName ) + if (AWAE_InitInp%NOutDisWindXZ < 0 .or. AWAE_InitInp%NOutDisWindXZ > maxOutputPlanes ) CALL SetErrStat( ErrID_Fatal, 'NOutDisWindXZ must be in the range [0, 99].', ErrStat, ErrMsg, RoutineName ) if (p%NOutDist < 0 .or. p%NOutDist > maxOutputPoints ) then CALL SetErrStat( ErrID_Fatal, 'NOutDist must be in the range [0, 9].', ErrStat, ErrMsg, RoutineName ) else @@ -1505,6 +1621,7 @@ SUBROUTINE Farm_InitWD( farm, WD_InitInp, ErrStat, ErrMsg ) !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ WD_InitInp%TurbNum = nt + WD_InitInp%OutFileRoot = farm%p%OutFileRoot ! note that WD_Init has Interval as INTENT(IN) so, we don't need to worry about overwriting farm%p%dt_low here: call WD_Init( WD_InitInp, farm%WD(nt)%u, farm%WD(nt)%p, farm%WD(nt)%x, farm%WD(nt)%xd, farm%WD(nt)%z, & @@ -1544,7 +1661,8 @@ SUBROUTINE Farm_InitFAST( farm, WD_InitInp, AWAE_InitOutput, SC_InitOutput, SC_y ! local variables type(FWrap_InitInputType) :: FWrap_InitInp - type(FWrap_InitOutputType) :: FWrap_InitOut + type(FWrap_InitOutputType) :: FWrap_InitOut + REAL(DbKi) :: FWrap_Interval !< Coupling interval that FWrap is called at (affected by MooringMod) INTEGER(IntKi) :: nt ! loop counter for rotor number INTEGER(IntKi) :: ErrStat2 ! Temporary Error status @@ -1577,12 +1695,28 @@ SUBROUTINE Farm_InitFAST( farm, WD_InitInp, AWAE_InitOutput, SC_InitOutput, SC_y FWrap_InitInp%NumSC2Ctrl = SC_InitOutput%NumSC2Ctrl FWrap_InitInp%NumSC2CtrlGlob= SC_InitOutput%NumSC2CtrlGlob FWrap_InitInp%NumCtrl2SC = SC_InitOutput%NumCtrl2SC - allocate(FWrap_InitInp%fromSCglob(SC_InitOutput%NumSC2CtrlGlob)) - FWrap_InitInp%fromSCglob = SC_y%fromSCglob + allocate(FWrap_InitInp%fromSCglob(SC_InitOutput%NumSC2CtrlGlob), stat=ErrStat2) + if (ErrStat2 /= 0) then + CALL SetErrStat( ErrID_Fatal, 'Could not allocate memory for FAST Wrapper data `fromSCglob`', ErrStat, ErrMsg, RoutineName ) + return + end if + if (SC_InitOutput%NumSC2CtrlGlob>0) then + FWrap_InitInp%fromSCglob = SC_y%fromSCglob + endif - allocate(FWrap_InitInp%fromSC(SC_InitOutput%NumSC2Ctrl)) + allocate(FWrap_InitInp%fromSC(SC_InitOutput%NumSC2Ctrl), stat=ErrStat2) + if (ErrStat2 /= 0) then + CALL SetErrStat( ErrID_Fatal, 'Could not allocate memory for FAST Wrapper data `fromSC`', ErrStat, ErrMsg, RoutineName ) + return + end if + if (farm%p%MooringMod > 0) then + FWrap_Interval = farm%p%dt_mooring ! when there is a farm-level mooring model, FASTWrapper will be called at the mooring coupling time step + else + FWrap_Interval = farm%p%dt_low ! otherwise FASTWrapper will be called at the regular FAST.Farm time step + end if + !OMP PARALLEL DO default(shared) PRIVATE(nt, FWrap_InitOut, ErrStat2, ErrMsg2) schedule(runtime) DO nt = 1,farm%p%NumTurbines !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! initialization can be done in parallel (careful for FWrap_InitInp, though) @@ -1590,6 +1724,7 @@ SUBROUTINE Farm_InitFAST( farm, WD_InitInp, AWAE_InitOutput, SC_InitOutput, SC_y FWrap_InitInp%FASTInFile = farm%p%WT_FASTInFile(nt) FWrap_InitInp%p_ref_Turbine = farm%p%WT_Position(:,nt) + FWrap_InitInp%WaveFieldMod = farm%p%WaveFieldMod FWrap_InitInp%TurbNum = nt FWrap_InitInp%RootName = trim(farm%p%OutFileRoot)//'.T'//num2lstr(nt) @@ -1605,18 +1740,25 @@ SUBROUTINE Farm_InitFAST( farm, WD_InitInp, AWAE_InitOutput, SC_InitOutput, SC_y FWrap_InitInp%fromSC = SC_y%fromSC((nt-1)*SC_InitOutput%NumSC2Ctrl+1:nt*SC_InitOutput%NumSC2Ctrl) end if ! note that FWrap_Init has Interval as INTENT(IN) so, we don't need to worry about overwriting farm%p%dt_low here: + ! NOTE: FWrap_interval, and FWrap_InitOut appear unused call FWrap_Init( FWrap_InitInp, farm%FWrap(nt)%u, farm%FWrap(nt)%p, farm%FWrap(nt)%x, farm%FWrap(nt)%xd, farm%FWrap(nt)%z, & - farm%FWrap(nt)%OtherSt, farm%FWrap(nt)%y, farm%FWrap(nt)%m, farm%p%dt_low, FWrap_InitOut, ErrStat2, ErrMsg2 ) + farm%FWrap(nt)%OtherSt, farm%FWrap(nt)%y, farm%FWrap(nt)%m, FWrap_Interval, FWrap_InitOut, ErrStat2, ErrMsg2 ) farm%FWrap(nt)%IsInitialized = .true. + if (ErrStat2 >= AbortErrLev) then + !OMP CRITICAL ! Needed to avoid data race on ErrStat and ErrMsg CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'T'//trim(num2lstr(nt))//':'//RoutineName) - if (ErrStat >= AbortErrLev) then - call cleanup() - return - end if + !OMP END CRITICAL + endif END DO + !OMP END PARALLEL DO + + if (ErrStat >= AbortErrLev) then + call cleanup() + return + end if farm%p%Module_Ver( ModuleFF_FWrap ) = FWrap_InitOut%Ver @@ -1629,6 +1771,268 @@ subroutine cleanup() end subroutine cleanup END SUBROUTINE Farm_InitFAST !---------------------------------------------------------------------------------------------------------------------------------- +!> This routine initializes a farm-level instance of MoorDyn if applicable +SUBROUTINE Farm_InitMD( farm, ErrStat, ErrMsg ) + + ! Passed variables + type(All_FastFarm_Data), INTENT(INOUT) :: farm !< FAST.Farm data + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message + + ! local variables + type(MD_InitInputType) :: MD_InitInp + type(MD_InitOutputType) :: MD_InitOut + + INTEGER(IntKi) :: nt ! loop counter for rotor number + INTEGER(IntKi) :: ErrStat2 ! Temporary Error status + CHARACTER(ErrMsgLen) :: ErrMsg2 ! Temporary Error message + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_InitMD' + + + ErrStat = ErrID_None + ErrMsg = "" + + CALL WrScr(" --------- in FARM_InitMD, to initiailze farm-level MoorDyn ------- ") + + + ! sort out how many times FASt and MoorDyn will be called per FAST.Farm time step based on DT_low and DT_mooring + IF ( EqualRealNos( farm%p%dt_mooring, farm%p%DT_low ) ) THEN + farm%p%n_mooring = 1 + ELSE + IF ( farm%p%dt_mooring > farm%p%DT_low ) THEN + ErrStat = ErrID_Fatal + ErrMsg = "The farm mooring coupling time step ("//TRIM(Num2LStr(farm%p%dt_mooring))// & + " s) cannot be larger than FAST.Farm time step ("//TRIM(Num2LStr(farm%p%DT_low))//" s)." + ELSE + ! calculate the number of FAST-MoorDyn subcycles: + farm%p%n_mooring = NINT( farm%p%DT_low / farm%p%dt_mooring ) + + ! let's make sure the FAST DT is an exact integer divisor of the global (FAST.Farm) time step: + IF ( .NOT. EqualRealNos( farm%p%DT_low, farm%p%dt_mooring * farm%p%n_mooring ) ) THEN + ErrStat = ErrID_Fatal + ErrMsg = "The MoorDyn coupling time step, DT_mooring ("//TRIM(Num2LStr(farm%p%dt_mooring))// & + " s) must be an integer divisor of the FAST.Farm time step ("//TRIM(Num2LStr(farm%p%DT_low))//" s)." + END IF + + END IF + END IF + + + !................. + ! MoorDyn initialization inputs... + !................ + !FWrap_InitInp%tmax = farm%p%TMax + !FWrap_InitInp%n_high_low = farm%p%n_high_low + 1 ! Add 1 because the FAST wrapper uses an index that starts at 1 + !FWrap_InitInp%dt_high = farm%p%dt_high + + + MD_InitInp%FileName = farm%p%MD_FileName ! input file name and path + MD_InitInp%RootName = trim(farm%p%OutFileRoot)//'.FarmMD' ! root of output files + MD_InitInp%FarmSize = farm%p%NumTurbines ! number of turbines in the array. >0 tells MoorDyn to operate in farm mode + + ALLOCATE( MD_InitInp%PtfmInit(6,farm%p%NumTurbines), MD_InitInp%TurbineRefPos(3,farm%p%NumTurbines), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating MoorDyn PtfmInit and TurbineRefPos initialization inputs in FAST.Farm.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + + ! gather spatial initialization inputs for Farm-level MoorDyn + DO nt = 1,farm%p%NumTurbines + MD_InitInp%PtfmInit(:,nt) = farm%FWrap(nt)%m%Turbine%MD%m%PtfmInit ! turbine PRP initial positions and rotations in their respective coordinate systems from each FAST/MD instance + MD_InitInp%TurbineRefPos(:,nt) = farm%p%WT_Position(:,nt) ! reference positions of each turbine in the farm global coordinate system + END DO + + ! These aren't currently handled at the FAST.Farm level, so just give the farm's MoorDyn default values, which can be overwridden by its input file + MD_InitInp%g = 9.81 + MD_InitInp%rhoW = 1025.0 + MD_InitInp%WtrDepth = 0.0 !TODO: eventually connect this to a global depth input variable <<< + + + ! allocate MoorDyn inputs (assuming size 2 for linear interpolation/extrapolation... > + ALLOCATE( farm%MD%Input( 2 ), farm%MD%InputTimes( 2 ), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating MD%Input and MD%InputTimes.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + + ! initialize MoorDyn + CALL MD_Init( MD_InitInp, farm%MD%Input(1), farm%MD%p, farm%MD%x, farm%MD%xd, farm%MD%z, & + farm%MD%OtherSt, farm%MD%y, farm%MD%m, farm%p%DT_mooring, MD_InitOut, ErrStat2, ErrMsg2 ) + + farm%MD%IsInitialized = .true. + + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call cleanup() + return + end if + + + ! Copy MD inputs over into the 2nd entry of the input array, to allow the first extrapolation in FARM_MD_Increment + CALL MD_CopyInput (farm%MD%Input(1), farm%MD%Input(2), MESH_NEWCOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + farm%MD%InputTimes(2) = -0.1_DbKi + + CALL MD_CopyInput (farm%MD%Input(1), farm%MD%u, MESH_NEWCOPY, Errstat2, ErrMsg2) ! do this to initialize meshes/allocatable arrays for output of ExtrapInterp routine + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + + + ! Set up mesh maps between MoorDyn and floating platforms. + ! (for now assuming ElastoDyn - eventually could differentiate at the turbine level) + + ! allocate mesh mappings for coupling farm-level MoorDyn with OpenFAST instances + ALLOCATE( farm%m%MD_2_FWrap(farm%p%NumTurbines), farm%m%FWrap_2_MD(farm%p%NumTurbines), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating MD_2_FWrap and FWrap_2_MD.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF + + ! MoorDyn point mesh to/from ElastoDyn (or SubDyn) point mesh + do nt = 1,farm%p%NumTurbines + !if (farm%MD%p%NFairs(nt) > 0 ) then ! only set up a mesh map if MoorDyn has connections to this turbine + + ! loads + CALL MeshMapCreate( farm%MD%y%CoupledLoads(nt), & + farm%FWrap(nt)%m%Turbine%MeshMapData%u_ED_PlatformPtMesh_MDf, farm%m%MD_2_FWrap(nt), ErrStat2, ErrMsg2 ) + + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':MD_2_FWrap' ) + + ! kinematics + CALL MeshMapCreate( farm%FWrap(nt)%m%Turbine%ED%y%PlatformPtMesh, & + farm%MD%Input(1)%CoupledKinematics(nt), farm%m%FWrap_2_MD(nt), ErrStat2, ErrMsg2 ) + + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':FWrap_2_MD' ) + + ! Since SubDyn connections are not enabled yet, issue warning + if (allocated(farm%FWrap(nt)%m%Turbine%SD%Input)) then + call SetErrStat( ErrID_Warn, 'Turbine '//trim(Num2LStr(nt))//': Farm moorings connected to ElastoDyn platform reference instead of SubDyn', Errstat, ErrMsg, RoutineName//':MD_2_FWrap' ) + endif + + ! SubDyn alternative: + !CALL MeshMapCreate( farm%MD%y%CoupledLoads(nt), & + ! farm%FWrap(nt)%m%Turbine%SD%Input(1)%LMesh, farm%m%MD_2_FWrap, ErrStat2, ErrMsg2 ) + ! + !CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':MD_2_FWrap' ) + ! + !CALL MeshMapCreate( farm%FWrap(nt)%m%Turbine%SD%y%y2Mesh, & + ! farm%MD%Input(1)%CoupledKinematics(nt), farm%m%FWrap_2_MD, ErrStat2, ErrMsg2 ) + ! + !CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':FWrap_2_MD' ) + !end if + end do + + + farm%p%Module_Ver( ModuleFF_MD) = MD_InitOut%Ver + + call cleanup() + +contains + subroutine cleanup() + call MD_DestroyInitInput( MD_InitInp, ErrStat2, ErrMsg2 ) + call MD_DestroyInitOutput( MD_InitOut, ErrStat2, ErrMsg2 ) + end subroutine cleanup +END SUBROUTINE Farm_InitMD +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine moves a farm-level MoorDyn simulation one step forward, to catch up with FWrap_Increment +subroutine FARM_MD_Increment(t, n, farm, ErrStat, ErrMsg) + REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds + INTEGER(IntKi), INTENT(IN ) :: n !< Current step of the simulation in FARM MoorDyn terms + type(All_FastFarm_Data), INTENT(INOUT) :: farm !< FAST.Farm data + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message + + INTEGER(IntKi) :: nt + INTEGER(IntKi) :: n_ss + INTEGER(IntKi) :: n_FMD + REAL(DbKi) :: t_next ! time at next step after this one (s) + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FARM_MD_Increment' + + ErrStat = ErrID_None + ErrMsg = "" + + ! ----- extrapolate MD inputs ----- + t_next = t + farm%p%DT_mooring + + ! Do a linear extrapolation to estimate MoorDyn inputs at time n_ss+1 + CALL MD_Input_ExtrapInterp(farm%MD%Input, farm%MD%InputTimes, farm%MD%u, t_next, ErrStat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + + ! Shift "window" of MD%Input: move values of Input and InputTimes from index 1 to index 2 + CALL MD_CopyInput (farm%MD%Input(1), farm%MD%Input(2), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + farm%MD%InputTimes(2) = farm%MD%InputTimes(1) + + ! update index 1 entries with the new extrapolated values + CALL MD_CopyInput (farm%MD%u, farm%MD%Input(1), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + farm%MD%InputTimes(1) = t_next + + + ! ----- map substructure kinematics to MoorDyn inputs ----- (from mapping called at start of CalcOutputs Solve INputs) + + do nt = 1,farm%p%NumTurbines + !if (farm%MD%p%NFairs(nt) > 0 ) then + + CALL Transfer_Point_to_Point( farm%FWrap(nt)%m%Turbine%ED%y%PlatformPtMesh, farm%MD%Input(1)%CoupledKinematics(nt), & + farm%m%FWrap_2_MD(nt), ErrStat2, ErrMsg2 ) + + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName//'u_MD%CoupledKinematics' ) + + ! SubDyn alternative + !CALL Transfer_Point_to_Point( farm%FWrap(nt)%m%Turbine%SD%y%y2Mesh, farm%MD%Input(1)%CoupledKinematics(nt), farm%m%FWrap_2_MD(nt), ErrStat, ErrMsg ) + !end if + end do + + + ! ----- update states and calculate outputs ----- + + CALL MD_UpdateStates( t, n_FMD, farm%MD%Input, farm%MD%InputTimes, farm%MD%p, farm%MD%x, & + farm%MD%xd, farm%MD%z, farm%MD%OtherSt, farm%MD%m, ErrStat2, ErrMsg2 ) + + CALL SetErrStat( Errstat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL MD_CalcOutput( t, farm%MD%Input(1), farm%MD%p, farm%MD%x, farm%MD%xd, farm%MD%z, & + farm%MD%OtherSt, farm%MD%y, farm%MD%m, ErrStat2, ErrMsg2 ) + + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + + ! ----- map MD load outputs to each turbine's substructure ----- (taken from U FullOpt1...) + do nt = 1,farm%p%NumTurbines + + if (farm%MD%p%nCpldCons(nt) > 0 ) then ! only map loads if MoorDyn has connections to this turbine (currently considering only Point connections <<< ) + + ! copy the MD output mesh for this turbine into a copy mesh within the FAST instance + !CALL MeshCopy ( farm%MD%y%CoupledLoads(nt), farm%FWrap(nt)%m%Turbine%MeshMapData%u_FarmMD_CoupledLoads, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) + ! CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':MeshCopy CoupledLoads' ) + + + ! mapping + CALL Transfer_Point_to_Point( farm%MD%y%CoupledLoads(nt), farm%FWrap(nt)%m%Turbine%MeshMapData%u_ED_PlatformPtMesh_MDf, & + farm%m%MD_2_FWrap(nt), ErrStat2, ErrMsg2, & + farm%MD%Input(1)%CoupledKinematics(nt), farm%FWrap(nt)%m%Turbine%ED%y%PlatformPtMesh ) !u_MD and y_ED contain the displacements needed for moment calculations + + CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) + + ! SubDyn alternative + !CALL Transfer_Point_to_Point( farm%MD%y%CoupledLoads(nt), farm%FWrap(nt)%m%Turbine%MeshMapData%u_SD_LMesh_2, & + ! farm%m%MD_2_FWrap(nt), ErrStat2, ErrMsg2, & + ! farm%MD%Input(1)%CoupledKinematics(nt), farm%FWrap(nt)%m%Turbine%SD%y%y2Mesh ) !u_MD and y_SD contain the displacements needed for moment calculations + ! + !farm%FWrap(nt)%m%Turbine%MeshMapData%u_SD_LMesh%Force = farm%FWrap(nt)%m%Turbine%MeshMapData%u_SD_LMesh%Force + farm%FWrap(nt)%m%Turbine%MeshMapData%u_SD_LMesh_2%Force + !farm%FWrap(nt)%m%Turbine%MeshMapData%u_SD_LMesh%Moment = farm%FWrap(nt)%m%Turbine%MeshMapData%u_SD_LMesh%Moment + farm%FWrap(nt)%m%Turbine%MeshMapData%u_SD_LMesh_2%Moment + end if + end do + + +end subroutine Farm_MD_Increment +!---------------------------------------------------------------------------------------------------------------------------------- !> This routine performs the initial call to calculate outputs (at t=0). !! The Initial Calculate Output algorithm: \n !! - In parallel: @@ -1667,7 +2071,8 @@ subroutine FARM_InitialCO(farm, ErrStat, ErrMsg) farm%AWAE%u%xhat_plane = 0.0_ReKi ! Orientations of wake planes, normal to wake planes, for each turbine farm%AWAE%u%p_plane = 0.0_ReKi ! Center positions of wake planes for each turbine farm%AWAE%u%Vx_wake = 0.0_ReKi ! Axial wake velocity deficit at wake planes, distributed radially, for each turbine - farm%AWAE%u%Vr_wake = 0.0_ReKi ! Radial wake velocity deficit at wake planes, distributed radially, for each turbine + farm%AWAE%u%Vy_wake = 0.0_ReKi ! Horizontal wake velocity deficit at wake planes, distributed radially, for each turbine + farm%AWAE%u%Vz_wake = 0.0_ReKi ! "Vertical" wake velocity deficit at wake planes, distributed radially, for each turbine farm%AWAE%u%D_wake = 0.0_ReKi ! Wake diameters at wake planes for each turbine !-------------------- @@ -1800,23 +2205,32 @@ subroutine FARM_UpdateStates(t, n, farm, ErrStat, ErrMsg) INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message - INTEGER(IntKi) :: nt - INTEGER(IntKi) :: ErrStatWD, ErrStat2 - INTEGER(IntKi), ALLOCATABLE :: ErrStatF(:) ! Temporary Error status - CHARACTER(ErrMsgLen) :: ErrMsgWD - CHARACTER(ErrMsgLen), ALLOCATABLE :: ErrMsgF (:) ! Temporary Error message + INTEGER(IntKi) :: nt + INTEGER(IntKi) :: n_ss + INTEGER(IntKi) :: n_FMD + REAL(DbKi) :: t2 ! time within the FAST-MoorDyn substepping loop for shared moorings + INTEGER(IntKi) :: ErrStatAWAE, ErrStatMD, ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(ErrMsgLen) :: ErrMsgAWAE + CHARACTER(ErrMsgLen) :: ErrMsgMD + INTEGER(IntKi), ALLOCATABLE :: ErrStatF(:) ! Temporary Error status for FAST + CHARACTER(ErrMsgLen), ALLOCATABLE :: ErrMsgF (:) ! Temporary Error message for FAST CHARACTER(*), PARAMETER :: RoutineName = 'FARM_UpdateStates' -! REAL(DbKi) :: tm1,tm2,tm3 + REAL(DbKi) :: tm1,tm2,tm3, tm01, tm02, tm03, tmSF, tmSM ! timer variables ErrStat = ErrID_None ErrMsg = "" - allocate ( ErrStatF ( farm%p%NumTurbines + 1 ), STAT=errStat2 ) + allocate ( ErrStatF ( farm%p%NumTurbines ), STAT=errStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for ErrStatF.', errStat, errMsg, RoutineName ) - allocate ( ErrMsgF ( farm%p%NumTurbines + 1 ), STAT=errStat2 ) + allocate ( ErrMsgF ( farm%p%NumTurbines ), STAT=errStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for ErrMsgF.', errStat, errMsg, RoutineName ) if (ErrStat >= AbortErrLev) return + + + + !....................................................................................... ! update module states (steps 1. and 2. and 3. and 4. can be done in parallel) !....................................................................................... @@ -1824,13 +2238,24 @@ subroutine FARM_UpdateStates(t, n, farm, ErrStat, ErrMsg) !-------------------- ! 1. CALL WD_US + !$OMP PARALLEL default(shared) + !$OMP do private(nt, ErrStat2, ErrMsg2) schedule(runtime) DO nt = 1,farm%p%NumTurbines call WD_UpdateStates( t, n, farm%WD(nt)%u, farm%WD(nt)%p, farm%WD(nt)%x, farm%WD(nt)%xd, farm%WD(nt)%z, & - farm%WD(nt)%OtherSt, farm%WD(nt)%m, ErrStatWD, ErrMsgWD ) - call SetErrStat(ErrStatWD, ErrMsgWD, ErrStat, ErrMsg, 'T'//trim(num2lstr(nt))//':FARM_UpdateStates') + farm%WD(nt)%OtherSt, farm%WD(nt)%m, ErrStat2, ErrMsg2 ) + + + ! Error handling + if (errStat2 /= ErrID_None) then + !$OMP CRITICAL ! Needed to avoid data race on ErrStat and ErrMsg + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'T'//trim(num2lstr(nt))//':FARM_UpdateStates') + !$OMP END CRITICAL + endif END DO + !$OMP END DO + !$OMP END PARALLEL if (ErrStat >= AbortErrLev) return @@ -1843,57 +2268,112 @@ subroutine FARM_UpdateStates(t, n, farm, ErrStat, ErrMsg) if (errStat >= AbortErrLev) return end if + !-------------------- - ! 3. CALL F_Increment and 4. CALL AWAE_UpdateStates -!#ifdef _OPENMP -! tm1 = omp_get_wtime() -!#endif - !$OMP PARALLEL DO DEFAULT(Shared) Private(nt) !Private(nt,tm2,tm3) - DO nt = 1,farm%p%NumTurbines+1 - if(nt.ne.farm%p%NumTurbines+1) then -!#ifdef _OPENMP -! tm3 = omp_get_wtime() -!#endif + ! 3. CALL F_Increment (and FARM_MD_Increment) and 4. CALL AWAE_UpdateStates + + + ! set the inputs needed for FAST (these are slow-varying so can just be done once per farm time step) + do nt = 1,farm%p%NumTurbines + call FWrap_SetInputs(farm%FWrap(nt)%u, farm%FWrap(nt)%m, t) + end do + + + !#ifdef printthreads + ! tm1 = omp_get_wtime() + ! tmSF = 0.0_DbKi + ! tmSM = 0.0_DbKi + !#endif + ! Original case: no shared moorings + if (farm%p%MooringMod == 0) then + + !$OMP PARALLEL DO DEFAULT(Shared) Private(nt) + DO nt = 1,farm%p%NumTurbines call FWrap_Increment( t, n, farm%FWrap(nt)%u, farm%FWrap(nt)%p, farm%FWrap(nt)%x, farm%FWrap(nt)%xd, farm%FWrap(nt)%z, & farm%FWrap(nt)%OtherSt, farm%FWrap(nt)%y, farm%FWrap(nt)%m, ErrStatF(nt), ErrMsgF(nt) ) - -!#ifdef _OPENMP -! tm2 = omp_get_wtime() -! write(*,*) ' FWrap_Increment for turbine #'//trim(num2lstr(nt))//' using thread #'//trim(num2lstr(omp_get_thread_num()))//' taking '//trim(num2lstr(tm2-tm3))//' seconds' -!#endif + END DO + !$OMP END PARALLEL DO + + ! Farm-level moorings case using MoorDyn + else if (farm%p%MooringMod == 3) then + + + ! This is the FAST-MoorDyn farm-level substepping loop + do n_ss = 1, farm%p%n_mooring ! do n_mooring substeps (number of FAST/FarmMD steps per Farm time step) + + n_FMD = n*farm%p%n_mooring + n_ss - 1 ! number of the current time step of the call to FAST and MoorDyn + t2 = t + farm%p%DT_mooring*(n_ss - 1) ! current time in the loop - else -!#ifdef _OPENMP -! tm3 = omp_get_wtime() -!#endif - call AWAE_UpdateStates( t, n, farm%AWAE%u, farm%AWAE%p, farm%AWAE%x, farm%AWAE%xd, farm%AWAE%z, & - farm%AWAE%OtherSt, farm%AWAE%m, errStatF(nt), errMsgF(nt) ) - -!#ifdef _OPENMP -! tm2 = omp_get_wtime() -! write(*,*) ' AWAE_UpdateStates using thread #'//trim(num2lstr(omp_get_thread_num()))//' taking '//trim(num2lstr(tm2-tm3))//' seconds' -!#endif - endif + !#ifdef printthreads + ! tm01 = omp_get_wtime() + !#endif + + ! A nested parallel for loop to call each instance of OpenFAST in parallel + !$OMP PARALLEL DO DEFAULT(Shared) Private(nt) + DO nt = 1,farm%p%NumTurbines + call FWrap_Increment( t2, n_FMD, farm%FWrap(nt)%u, farm%FWrap(nt)%p, farm%FWrap(nt)%x, farm%FWrap(nt)%xd, farm%FWrap(nt)%z, & + farm%FWrap(nt)%OtherSt, farm%FWrap(nt)%y, farm%FWrap(nt)%m, ErrStatF(nt), ErrMsgF(nt) ) + END DO + !$OMP END PARALLEL DO + + !#ifdef printthreads + ! tm02 = omp_get_wtime() + !#endif - END DO - !$OMP END PARALLEL DO + ! call farm-level MoorDyn time step here (can't multithread this with FAST since it needs inputs from all FAST instances) + call Farm_MD_Increment( t2, n_FMD, farm, ErrStatMD, ErrMsgMD) + call SetErrStat(ErrStatMD, ErrMsgMD, ErrStat, ErrMsg, 'FARM_UpdateStates') ! MD error status <<<<< + + !#ifdef printthreads + ! tm03 = omp_get_wtime() + ! tmSF = tmSF + tm02-tm01 + ! tmSM = tmSM + tm03-tm02 + !#endif + + end do ! n_ss substepping + + !#ifdef printthreads + ! tm2 = omp_get_wtime() + ! write(*,*) ' Time on FAST sims: '//trim(num2lstr(tmSF))//' s. Time on Farm MoorDyn: '//trim(num2lstr(tmSM))//' seconds' + !#endif + + + else + CALL SetErrStat( ErrID_Fatal, 'MooringMod must be 0 or 3.', ErrStat, ErrMsg, RoutineName ) + end if + !#ifdef printthreads + ! tm2 = omp_get_wtime() + ! write(*,*) 'Total FAST and Moordyn for FF_US took '//trim(num2lstr(tm2-tm1))//' seconds.' + !#endif + + call AWAE_UpdateStates( t, n, farm%AWAE%u, farm%AWAE%p, farm%AWAE%x, farm%AWAE%xd, farm%AWAE%z, & + farm%AWAE%OtherSt, farm%AWAE%m, ErrStatAWAE, ErrMsgAWAE ) + !#ifdef printthreads + ! tm3 = omp_get_wtime() + ! write(*,*) 'AWAE_US took '//trim(num2lstr(tm3-tm2))//' seconds.' + ! write(*,*) 'Total Farm_US took '//trim(num2lstr(tm3-tm1))//' seconds.' + !#endif + + ! update error messages from FAST's and AWAE's time steps DO nt = 1,farm%p%NumTurbines - call SetErrStat(ErrStatF(nt), ErrMsgF(nt), ErrStat, ErrMsg, 'T'//trim(num2lstr(nt))//':FARM_UpdateStates') + call SetErrStat(ErrStatF(nt), ErrMsgF(nt), ErrStat, ErrMsg, 'T'//trim(num2lstr(nt))//':FARM_UpdateStates') ! FAST error status END DO + + call SetErrStat(ErrStatAWAE, ErrMsgAWAE, ErrStat, ErrMsg, 'FARM_UpdateStates') ! AWAE error status + + ! calculate outputs from FAST as needed by FAST.Farm + do nt = 1,farm%p%NumTurbines + call FWrap_CalcOutput(farm%FWrap(nt)%p, farm%FWrap(nt)%u, farm%FWrap(nt)%y, farm%FWrap(nt)%m, ErrStat2, ErrMsg2) + call setErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + end do - call SetErrStat(ErrStatF(farm%p%NumTurbines+1), ErrMsgF(farm%p%NumTurbines+1), ErrStat, ErrMsg, 'FARM_UpdateStates') - + if (ErrStat >= AbortErrLev) return -!#ifdef _OPENMP -! tm2 = omp_get_wtime() -! write(*,*) 'Total Farm_US took '//trim(num2lstr(tm2-tm1))//' seconds.' -!#endif - end subroutine FARM_UpdateStates - +!---------------------------------------------------------------------------------------------------------------------------------- subroutine Farm_WriteOutput(n, t, farm, ErrStat, ErrMsg) INTEGER(IntKi), INTENT(IN ) :: n !< Time step increment number REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds @@ -1972,13 +2452,35 @@ subroutine Farm_WriteOutput(n, t, farm, ErrStat, ErrMsg) ! Rotor-disk-averaged ambient wind speed (normal to disk, not including structural motion, local induction or wakes from upstream turbines), m/s farm%m%AllOuts(RtVAmbT(nt)) = farm%AWAE%y%Vx_wind_disk(nt) + ! Time-filtered rotor-disk-averaged ambient wind speed (normal to disk, not including structural motion, local induction or wakes from upstream turbines), m/s + farm%m%AllOuts(RtVAmbFiltT(nt)) = farm%WD(nt)%xd%Vx_wind_disk_filt(0) ! NOTE: filtered value will be 0 at t=0 + ! Rotor-disk-averaged relative wind speed (normal to disk, including structural motion and wakes from upstream turbines, but not including local induction), m/s farm%m%AllOuts(RtVRelT(nt)) = farm%FWrap(nt)%y%DiskAvg_Vx_Rel + + ! Skew azimuth angle (instantaneous) + farm%m%AllOuts(AziSkewT(nt)) = farm%FWrap(nt)%y%psi_skew* R2D + + ! Skew azimuth angle (time-filtered) + farm%m%AllOuts(AziSkewFiltT(nt)) = farm%WD(nt)%xd%psi_skew_filt*R2D ! NOTE: filtered value will be 0 at t=0 + + ! Skew angle (instantaneous) + farm%m%AllOuts(RtSkewT(nt)) = farm%FWrap(nt)%y%chi_skew * R2D + + ! Skew angle (time-filtered) + farm%m%AllOuts(RtSkewFiltT(nt)) = farm%WD(nt)%xd%chi_skew_filt*R2D ! NOTE: filtered value will be 0 at t=0 + + ! Rotor circulation for curled-wake model + farm%m%AllOuts(RtGamCurlT(nt)) = farm%WD(nt)%m%GammaCurl + + !Rotor-disk averaged thrust coefficient + farm%m%AllOuts(RtCtAvgT(nt)) = farm%WD(nt)%m%Ct_avg ! Azimuthally averaged thrust force coefficient (normal to disk), distributed radially, - do ir = 1, farm%p%NOutRadii farm%m%AllOuts(CtTN(ir, nt)) = farm%FWrap(nt)%y%AzimAvg_Ct(farm%p%OutRadii(ir)+1) ! y%AzimAvg_Ct is a 1-based array but the user specifies 0-based node indices, so we need to add 1 end do + !....................................................................................... ! Wake (for an Individual Rotor) @@ -2059,20 +2561,23 @@ subroutine Farm_WriteOutput(n, t, farm, ErrStat, ErrMsg) ! Wake diameter for downstream wake volume, np, of turbine, nt, m farm%m%AllOuts(WkDiamTD(iOutDist,nt)) = delta*farm%WD(nt)%y%D_wake(np+1) + deltad*farm%WD(nt)%y%D_wake(np) !farm%AWAE%u%D_wake(np,nt) + if (farm%WD(nt)%p%Mod_Wake == Mod_Wake_Polar) then + do ir = 1, farm%p%NOutRadii + + ! Axial and radial wake velocity deficits for radial node, OutRadii(ir), and downstream wake volume, np, of turbine, nt, m/s + farm%m%AllOuts(WkDfVxTND(ir,iOutDist,nt)) = delta*farm%WD(nt)%y%Vx_wake(farm%p%OutRadii(ir),np+1) + deltad*farm%WD(nt)%y%Vx_wake(farm%p%OutRadii(ir),np) + farm%m%AllOuts(WkDfVrTND(ir,iOutDist,nt)) = delta*farm%WD(nt)%y%Vr_wake(farm%p%OutRadii(ir),np+1) + deltad*farm%WD(nt)%y%Vr_wake(farm%p%OutRadii(ir),np) - do ir = 1, farm%p%NOutRadii - - ! Axial and radial wake velocity deficits for radial node, OutRadii(ir), and downstream wake volume, np, of turbine, nt, m/s - farm%m%AllOuts(WkDfVxTND(ir,iOutDist,nt)) = delta*farm%WD(nt)%y%Vx_wake(farm%p%OutRadii(ir),np+1) + deltad*farm%WD(nt)%y%Vx_wake(farm%p%OutRadii(ir),np) - farm%m%AllOuts(WkDfVrTND(ir,iOutDist,nt)) = delta*farm%WD(nt)%y%Vr_wake(farm%p%OutRadii(ir),np+1) + deltad*farm%WD(nt)%y%Vr_wake(farm%p%OutRadii(ir),np) - - ! Total eddy viscosity, and individual contributions to the eddy viscosity from ambient turbulence and the shear layer, - ! or radial node, OutRadii(ir), and downstream wake volume, np, of turbine, nt, m/s - farm%m%AllOuts(EddVisTND(ir,iOutDist,nt)) = delta*farm%WD(nt)%m%vt_tot(farm%p%OutRadii(ir),np+1) + deltad*farm%WD(nt)%m%vt_tot(farm%p%OutRadii(ir),np) - farm%m%AllOuts(EddAmbTND(ir,iOutDist,nt)) = delta*farm%WD(nt)%m%vt_amb(farm%p%OutRadii(ir),np+1) + deltad*farm%WD(nt)%m%vt_amb(farm%p%OutRadii(ir),np) - farm%m%AllOuts(EddShrTND(ir,iOutDist,nt)) = delta*farm%WD(nt)%m%vt_shr(farm%p%OutRadii(ir),np+1) + deltad*farm%WD(nt)%m%vt_shr(farm%p%OutRadii(ir),np) - - end do + ! Total eddy viscosity, and individual contributions to the eddy viscosity from ambient turbulence and the shear layer, + ! or radial node, OutRadii(ir), and downstream wake volume, np, of turbine, nt, m/s + farm%m%AllOuts(EddVisTND(ir,iOutDist,nt)) = delta*farm%WD(nt)%m%vt_tot(farm%p%OutRadii(ir),np+1) + deltad*farm%WD(nt)%m%vt_tot(farm%p%OutRadii(ir),np) + farm%m%AllOuts(EddAmbTND(ir,iOutDist,nt)) = delta*farm%WD(nt)%m%vt_amb(farm%p%OutRadii(ir),np+1) + deltad*farm%WD(nt)%m%vt_amb(farm%p%OutRadii(ir),np) + farm%m%AllOuts(EddShrTND(ir,iOutDist,nt)) = delta*farm%WD(nt)%m%vt_shr(farm%p%OutRadii(ir),np+1) + deltad*farm%WD(nt)%m%vt_shr(farm%p%OutRadii(ir),np) + + end do + else + ! These outputs are invalid for Curl and Cartesian + endif else if ( ( farm%p%OutDist(iOutDist) >= farm%WD(nt)%y%x_plane(np+1) ) .and. ( farm%p%OutDist(iOutDist) < farm%WD(nt)%y%x_plane(np) ) ) then ! Overlapping wake volumes result in invalid output @@ -2191,13 +2696,18 @@ subroutine FARM_CalcOutput(t, farm, ErrStat, ErrMsg) !-------------------- ! 1. call WD_CO and transfer y_WD to u_AWAE + !$OMP PARALLEL DO DEFAULT (shared) PRIVATE(nt, ErrStat2, ErrMsg2) schedule(runtime) DO nt = 1,farm%p%NumTurbines call WD_CalcOutput( t, farm%WD(nt)%u, farm%WD(nt)%p, farm%WD(nt)%x, farm%WD(nt)%xd, farm%WD(nt)%z, & farm%WD(nt)%OtherSt, farm%WD(nt)%y, farm%WD(nt)%m, ErrStat2, ErrMsg2 ) + if (ErrStat2 >= AbortErrLev) then + !$OMP CRITICAL ! Needed to avoid data race on ErrStat and ErrMsg call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'T'//trim(num2lstr(nt))//':'//RoutineName) - + !$OMP END CRITICAL + endif END DO + !$OMP END PARALLEL DO if (ErrStat >= AbortErrLev) return call Transfer_WD_to_AWAE(farm) @@ -2334,6 +2844,15 @@ subroutine FARM_End(farm, ErrStat, ErrMsg) end if + !-------------- + ! 5. End farm-level MoorDyn + if (farm%p%MooringMod == 3) then + call MD_End(farm%MD%Input(1), farm%MD%p, farm%MD%x, farm%MD%xd, farm%MD%z, farm%MD%OtherSt, farm%MD%y, farm%MD%m, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + !TODO: any related items need to be cleared? + end if + + !....................................................................................... ! close output file !....................................................................................... @@ -2356,10 +2875,13 @@ SUBROUTINE Transfer_FAST_to_WD(farm) DO nt = 1,farm%p%NumTurbines farm%WD(nt)%u%xhat_disk = farm%FWrap(nt)%y%xHat_Disk ! Orientation of rotor centerline, normal to disk + farm%WD(nt)%u%psi_skew = farm%FWrap(nt)%y%psi_skew ! Azimuth angle from the nominally vertical axis in the disk plane to the vector about which the inflow skew angle is defined + farm%WD(nt)%u%chi_skew = farm%FWrap(nt)%y%chi_skew ! Inflow skew angle farm%WD(nt)%u%p_hub = farm%FWrap(nt)%y%p_hub ! Center position of hub, m farm%WD(nt)%u%D_rotor = farm%FWrap(nt)%y%D_rotor ! Rotor diameter, m farm%WD(nt)%u%Vx_rel_disk = farm%FWrap(nt)%y%DiskAvg_Vx_Rel ! Rotor-disk-averaged relative wind speed (ambient + deficits + motion), normal to disk, m/s farm%WD(nt)%u%Ct_azavg = farm%FWrap(nt)%y%AzimAvg_Ct ! Azimuthally averaged thrust force coefficient (normal to disk), distributed radially, - + farm%WD(nt)%u%Cq_azavg = farm%FWrap(nt)%y%AzimAvg_Cq ! Azimuthally averaged torque force coefficient (normal to disk), distributed radially, - farm%WD(nt)%u%YawErr = farm%FWrap(nt)%y%YawErr ! Nacelle-yaw error at the wake planes, rad END DO @@ -2398,8 +2920,9 @@ SUBROUTINE Transfer_WD_to_AWAE(farm) DO nt = 1,farm%p%NumTurbines farm%AWAE%u%xhat_plane(:,:,nt) = farm%WD(nt)%y%xhat_plane ! Orientations of wake planes, normal to wake planes, for each turbine farm%AWAE%u%p_plane(:,:,nt) = farm%WD(nt)%y%p_plane ! Center positions of wake planes for each turbine - farm%AWAE%u%Vx_wake(:,:,nt) = farm%WD(nt)%y%Vx_wake ! Axial wake velocity deficit at wake planes, distributed radially, for each turbine - farm%AWAE%u%Vr_wake(:,:,nt) = farm%WD(nt)%y%Vr_wake ! Radial wake velocity deficit at wake planes, distributed radially, for each turbine + farm%AWAE%u%Vx_wake(:,:,:,nt) = farm%WD(nt)%y%Vx_wake2 ! Axial wake velocity deficit at wake planes, distributed radially, for each turbine + farm%AWAE%u%Vy_wake(:,:,:,nt) = farm%WD(nt)%y%Vy_wake2 ! Horizontal wake velocity deficit at wake planes, distributed radially, for each turbine + farm%AWAE%u%Vz_wake(:,:,:,nt) = farm%WD(nt)%y%Vz_wake2 ! "Vertical" wake velocity deficit at wake planes, distributed radially, for each turbine farm%AWAE%u%D_wake(:,nt) = farm%WD(nt)%y%D_wake ! Wake diameters at wake planes for each turbine END DO diff --git a/glue-codes/fast-farm/src/FAST_Farm_Types.f90 b/glue-codes/fast-farm/src/FAST_Farm_Types.f90 index 9d3cc3ffe..540dc80c5 100644 --- a/glue-codes/fast-farm/src/FAST_Farm_Types.f90 +++ b/glue-codes/fast-farm/src/FAST_Farm_Types.f90 @@ -37,12 +37,13 @@ MODULE FAST_Farm_Types USE SuperController_Types USE NWTC_Library IMPLICIT NONE - INTEGER(IntKi), PUBLIC, PARAMETER :: NumFFModules = 4 ! The number of modules available in FAST.Farm [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: NumFFModules = 5 ! The number of modules available in FAST.Farm [-] INTEGER(IntKi), PUBLIC, PARAMETER :: ModuleFF_None = 0 ! No module selected [-] INTEGER(IntKi), PUBLIC, PARAMETER :: ModuleFF_SC = 1 ! Super Controller [-] INTEGER(IntKi), PUBLIC, PARAMETER :: ModuleFF_FWrap = 2 ! FAST Wrapper [-] INTEGER(IntKi), PUBLIC, PARAMETER :: ModuleFF_WD = 3 ! Wake Dynamics [-] INTEGER(IntKi), PUBLIC, PARAMETER :: ModuleFF_AWAE = 4 ! Ambient Wind and Array Effects [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: ModuleFF_MD = 5 ! Farm-level MoorDyn [-] ! ========= Farm_ParameterType ======= TYPE, PUBLIC :: Farm_ParameterType REAL(DbKi) :: DT_low !< Time step for low-resolution wind data input files; will be used as the global FAST.Farm time step [seconds] @@ -54,6 +55,11 @@ MODULE FAST_Farm_Types CHARACTER(1024) :: SC_FileName !< Name/location of the dynamic library {.dll [Windows] or .so [Linux]} containing the Super Controller algorithms [-] LOGICAL :: UseSC !< Use a super controller? [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WT_Position !< X-Y-Z position of each wind turbine; index 1 = XYZ; index 2 = turbine number [meters] + INTEGER(IntKi) :: WaveFieldMod !< Wave field handling (-) (switch) {0: use individual HydroDyn inputs without adjustment, 1: adjust wave phases based on turbine offsets from farm origin} [-] + INTEGER(IntKi) :: MooringMod !< Mod_SharedMooring is a flag for array-level mooring. (switch) {0: none, 3: yes/MoorDyn} [-] + CHARACTER(1024) :: MD_FileName !< Name/location of the farm-level MoorDyn input file [-] + REAL(DbKi) :: DT_mooring !< Time step for farm-levem mooring coupling with each turbine [used only when Mod_SharedMooring > 0] [seconds] + INTEGER(IntKi) :: n_mooring !< Number of FAST and MoorDyn time steps per FAST.Farm timestep when mooring > 0 [-] CHARACTER(1024) , DIMENSION(:), ALLOCATABLE :: WT_FASTInFile !< Name of input file for each turbine [-] CHARACTER(1024) :: FTitle !< The description line from the primary FAST.Farm input file [-] CHARACTER(1024) :: OutFileRoot !< The root name derived from the primary FAST.Farm input file [-] @@ -100,6 +106,8 @@ MODULE FAST_Farm_Types REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: TimeData !< Array to contain the time output data for the binary file (first output time and a time [fixed] increment) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: AllOutData !< Array to contain all the output data (time history of all outputs); Index 1 is NumOuts, Index 2 is Time step [-] INTEGER(IntKi) :: n_Out !< Time index into the AllOutData array [-] + TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: FWrap_2_MD !< Map platform kinematics from each FAST instance to MD [-] + TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: MD_2_FWrap !< Map MD loads at the array level to each FAST instance [-] END TYPE Farm_MiscVarType ! ======================= ! ========= FASTWrapper_Data ======= @@ -155,6 +163,21 @@ MODULE FAST_Farm_Types LOGICAL :: IsInitialized = .FALSE. !< Has SC_Init been called [-] END TYPE SC_Data ! ======================= +! ========= MD_Data ======= + TYPE, PUBLIC :: MD_Data + TYPE(MD_ContinuousStateType) :: x !< Continuous states [-] + TYPE(MD_DiscreteStateType) :: xd !< Discrete states [-] + TYPE(MD_ConstraintStateType) :: z !< Constraint states [-] + TYPE(MD_OtherStateType) :: OtherSt !< Other states [-] + TYPE(MD_ParameterType) :: p !< Parameters [-] + TYPE(MD_InputType) :: u !< Extrapolated system inputs [-] + TYPE(MD_InputType) , DIMENSION(:), ALLOCATABLE :: Input !< System inputs [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: InputTimes !< Current time [s] + TYPE(MD_OutputType) :: y !< System outputs [-] + TYPE(MD_MiscVarType) :: m !< Misc/optimization variables [-] + LOGICAL :: IsInitialized = .FALSE. !< Has MD_Init been called [-] + END TYPE MD_Data +! ======================= ! ========= All_FastFarm_Data ======= TYPE, PUBLIC :: All_FastFarm_Data TYPE(Farm_ParameterType) :: p !< FAST.Farm parameter data [-] @@ -163,6 +186,7 @@ MODULE FAST_Farm_Types TYPE(WakeDynamics_Data) , DIMENSION(:), ALLOCATABLE :: WD !< WakeDynamics (WD) data [-] TYPE(AWAE_Data) :: AWAE !< Ambient Wind & Array Effects (AWAE) data [-] TYPE(SC_Data) :: SC !< Super Controller (SC) data [-] + TYPE(MD_Data) :: MD !< Farm-level MoorDyn model data [-] END TYPE All_FastFarm_Data ! ======================= CONTAINS @@ -204,6 +228,11 @@ SUBROUTINE Farm_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg END IF DstParamData%WT_Position = SrcParamData%WT_Position ENDIF + DstParamData%WaveFieldMod = SrcParamData%WaveFieldMod + DstParamData%MooringMod = SrcParamData%MooringMod + DstParamData%MD_FileName = SrcParamData%MD_FileName + DstParamData%DT_mooring = SrcParamData%DT_mooring + DstParamData%n_mooring = SrcParamData%n_mooring IF (ALLOCATED(SrcParamData%WT_FASTInFile)) THEN i1_l = LBOUND(SrcParamData%WT_FASTInFile,1) i1_u = UBOUND(SrcParamData%WT_FASTInFile,1) @@ -329,15 +358,27 @@ SUBROUTINE Farm_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%Z0_low = SrcParamData%Z0_low END SUBROUTINE Farm_CopyParam - SUBROUTINE Farm_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE Farm_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Farm_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%WT_Position)) THEN DEALLOCATE(ParamData%WT_Position) ENDIF @@ -361,12 +402,14 @@ SUBROUTINE Farm_DestroyParam( ParamData, ErrStat, ErrMsg ) 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 ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF DO i1 = LBOUND(ParamData%Module_Ver,1), UBOUND(ParamData%Module_Ver,1) - CALL NWTC_Library_Destroyprogdesc( ParamData%Module_Ver(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( ParamData%Module_Ver(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO END SUBROUTINE Farm_DestroyParam @@ -418,6 +461,11 @@ SUBROUTINE Farm_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 2*2 ! WT_Position upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WT_Position) ! WT_Position END IF + Int_BufSz = Int_BufSz + 1 ! WaveFieldMod + Int_BufSz = Int_BufSz + 1 ! MooringMod + Int_BufSz = Int_BufSz + 1*LEN(InData%MD_FileName) ! MD_FileName + Db_BufSz = Db_BufSz + 1 ! DT_mooring + Int_BufSz = Int_BufSz + 1 ! n_mooring Int_BufSz = Int_BufSz + 1 ! WT_FASTInFile allocated yes/no IF ( ALLOCATED(InData%WT_FASTInFile) ) THEN Int_BufSz = Int_BufSz + 2*1 ! WT_FASTInFile upper/lower bounds for each dimension @@ -588,6 +636,18 @@ SUBROUTINE Farm_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END DO END DO END IF + IntKiBuf(Int_Xferred) = InData%WaveFieldMod + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%MooringMod + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(InData%MD_FileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%MD_FileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DbKiBuf(Db_Xferred) = InData%DT_mooring + Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%n_mooring + Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%WT_FASTInFile) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -898,6 +958,18 @@ SUBROUTINE Farm_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END DO END DO END IF + OutData%WaveFieldMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%MooringMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(OutData%MD_FileName) + OutData%MD_FileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%DT_mooring = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%n_mooring = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WT_FASTInFile not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -1187,7 +1259,7 @@ SUBROUTINE Farm_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END SUBROUTINE Farm_UnPackParam SUBROUTINE Farm_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(Farm_MiscVarType), INTENT(IN) :: SrcMiscData + TYPE(Farm_MiscVarType), INTENT(INOUT) :: SrcMiscData TYPE(Farm_MiscVarType), INTENT(INOUT) :: DstMiscData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat @@ -1241,17 +1313,61 @@ SUBROUTINE Farm_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%AllOutData = SrcMiscData%AllOutData ENDIF DstMiscData%n_Out = SrcMiscData%n_Out +IF (ALLOCATED(SrcMiscData%FWrap_2_MD)) THEN + i1_l = LBOUND(SrcMiscData%FWrap_2_MD,1) + i1_u = UBOUND(SrcMiscData%FWrap_2_MD,1) + IF (.NOT. ALLOCATED(DstMiscData%FWrap_2_MD)) THEN + ALLOCATE(DstMiscData%FWrap_2_MD(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%FWrap_2_MD.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%FWrap_2_MD,1), UBOUND(SrcMiscData%FWrap_2_MD,1) + CALL NWTC_Library_Copymeshmaptype( SrcMiscData%FWrap_2_MD(i1), DstMiscData%FWrap_2_MD(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcMiscData%MD_2_FWrap)) THEN + i1_l = LBOUND(SrcMiscData%MD_2_FWrap,1) + i1_u = UBOUND(SrcMiscData%MD_2_FWrap,1) + IF (.NOT. ALLOCATED(DstMiscData%MD_2_FWrap)) THEN + ALLOCATE(DstMiscData%MD_2_FWrap(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%MD_2_FWrap.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%MD_2_FWrap,1), UBOUND(SrcMiscData%MD_2_FWrap,1) + CALL NWTC_Library_Copymeshmaptype( SrcMiscData%MD_2_FWrap(i1), DstMiscData%MD_2_FWrap(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF END SUBROUTINE Farm_CopyMisc - SUBROUTINE Farm_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE Farm_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Farm_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%AllOuts)) THEN DEALLOCATE(MiscData%AllOuts) ENDIF @@ -1260,6 +1376,20 @@ SUBROUTINE Farm_DestroyMisc( MiscData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(MiscData%AllOutData)) THEN DEALLOCATE(MiscData%AllOutData) +ENDIF +IF (ALLOCATED(MiscData%FWrap_2_MD)) THEN +DO i1 = LBOUND(MiscData%FWrap_2_MD,1), UBOUND(MiscData%FWrap_2_MD,1) + CALL NWTC_Library_Destroymeshmaptype( MiscData%FWrap_2_MD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MiscData%FWrap_2_MD) +ENDIF +IF (ALLOCATED(MiscData%MD_2_FWrap)) THEN +DO i1 = LBOUND(MiscData%MD_2_FWrap,1), UBOUND(MiscData%MD_2_FWrap,1) + CALL NWTC_Library_Destroymeshmaptype( MiscData%MD_2_FWrap(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MiscData%MD_2_FWrap) ENDIF END SUBROUTINE Farm_DestroyMisc @@ -1314,6 +1444,53 @@ SUBROUTINE Farm_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Re_BufSz = Re_BufSz + SIZE(InData%AllOutData) ! AllOutData END IF Int_BufSz = Int_BufSz + 1 ! n_Out + Int_BufSz = Int_BufSz + 1 ! FWrap_2_MD allocated yes/no + IF ( ALLOCATED(InData%FWrap_2_MD) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FWrap_2_MD upper/lower bounds for each dimension + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%FWrap_2_MD,1), UBOUND(InData%FWrap_2_MD,1) + Int_BufSz = Int_BufSz + 3 ! FWrap_2_MD: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%FWrap_2_MD(i1), ErrStat2, ErrMsg2, .TRUE. ) ! FWrap_2_MD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! FWrap_2_MD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! FWrap_2_MD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! FWrap_2_MD + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! MD_2_FWrap allocated yes/no + IF ( ALLOCATED(InData%MD_2_FWrap) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MD_2_FWrap upper/lower bounds for each dimension + DO i1 = LBOUND(InData%MD_2_FWrap,1), UBOUND(InData%MD_2_FWrap,1) + Int_BufSz = Int_BufSz + 3 ! MD_2_FWrap: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%MD_2_FWrap(i1), ErrStat2, ErrMsg2, .TRUE. ) ! MD_2_FWrap + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! MD_2_FWrap + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! MD_2_FWrap + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! MD_2_FWrap + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1393,6 +1570,88 @@ SUBROUTINE Farm_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S END IF IntKiBuf(Int_Xferred) = InData%n_Out Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%FWrap_2_MD) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FWrap_2_MD,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FWrap_2_MD,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%FWrap_2_MD,1), UBOUND(InData%FWrap_2_MD,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%FWrap_2_MD(i1), ErrStat2, ErrMsg2, OnlySize ) ! FWrap_2_MD + 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%MD_2_FWrap) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MD_2_FWrap,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MD_2_FWrap,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MD_2_FWrap,1), UBOUND(InData%MD_2_FWrap,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%MD_2_FWrap(i1), ErrStat2, ErrMsg2, OnlySize ) ! MD_2_FWrap + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF END SUBROUTINE Farm_PackMisc SUBROUTINE Farm_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1484,6 +1743,118 @@ SUBROUTINE Farm_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END IF OutData%n_Out = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FWrap_2_MD not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FWrap_2_MD)) DEALLOCATE(OutData%FWrap_2_MD) + ALLOCATE(OutData%FWrap_2_MD(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FWrap_2_MD.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%FWrap_2_MD,1), UBOUND(OutData%FWrap_2_MD,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%FWrap_2_MD(i1), ErrStat2, ErrMsg2 ) ! FWrap_2_MD + 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 ! MD_2_FWrap not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MD_2_FWrap)) DEALLOCATE(OutData%MD_2_FWrap) + ALLOCATE(OutData%MD_2_FWrap(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MD_2_FWrap.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MD_2_FWrap,1), UBOUND(OutData%MD_2_FWrap,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%MD_2_FWrap(i1), ErrStat2, ErrMsg2 ) ! MD_2_FWrap + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF END SUBROUTINE Farm_UnPackMisc SUBROUTINE Farm_CopyFASTWrapper_Data( SrcFASTWrapper_DataData, DstFASTWrapper_DataData, CtrlCode, ErrStat, ErrMsg ) @@ -1527,23 +1898,43 @@ SUBROUTINE Farm_CopyFASTWrapper_Data( SrcFASTWrapper_DataData, DstFASTWrapper_Da DstFASTWrapper_DataData%IsInitialized = SrcFASTWrapper_DataData%IsInitialized END SUBROUTINE Farm_CopyFASTWrapper_Data - SUBROUTINE Farm_DestroyFASTWrapper_Data( FASTWrapper_DataData, ErrStat, ErrMsg ) + SUBROUTINE Farm_DestroyFASTWrapper_Data( FASTWrapper_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FASTWrapper_Data), INTENT(INOUT) :: FASTWrapper_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroyFASTWrapper_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL FWrap_DestroyContState( FASTWrapper_DataData%x, ErrStat, ErrMsg ) - CALL FWrap_DestroyDiscState( FASTWrapper_DataData%xd, ErrStat, ErrMsg ) - CALL FWrap_DestroyConstrState( FASTWrapper_DataData%z, ErrStat, ErrMsg ) - CALL FWrap_DestroyOtherState( FASTWrapper_DataData%OtherSt, ErrStat, ErrMsg ) - CALL FWrap_DestroyParam( FASTWrapper_DataData%p, ErrStat, ErrMsg ) - CALL FWrap_DestroyInput( FASTWrapper_DataData%u, ErrStat, ErrMsg ) - CALL FWrap_DestroyOutput( FASTWrapper_DataData%y, ErrStat, ErrMsg ) - CALL FWrap_DestroyMisc( FASTWrapper_DataData%m, ErrStat, ErrMsg ) + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroyFASTWrapper_Data' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL FWrap_DestroyContState( FASTWrapper_DataData%x, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FWrap_DestroyDiscState( FASTWrapper_DataData%xd, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FWrap_DestroyConstrState( FASTWrapper_DataData%z, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FWrap_DestroyOtherState( FASTWrapper_DataData%OtherSt, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FWrap_DestroyParam( FASTWrapper_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FWrap_DestroyInput( FASTWrapper_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FWrap_DestroyOutput( FASTWrapper_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FWrap_DestroyMisc( FASTWrapper_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE Farm_DestroyFASTWrapper_Data SUBROUTINE Farm_PackFASTWrapper_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2365,23 +2756,43 @@ SUBROUTINE Farm_CopyWakeDynamics_Data( SrcWakeDynamics_DataData, DstWakeDynamics DstWakeDynamics_DataData%IsInitialized = SrcWakeDynamics_DataData%IsInitialized END SUBROUTINE Farm_CopyWakeDynamics_Data - SUBROUTINE Farm_DestroyWakeDynamics_Data( WakeDynamics_DataData, ErrStat, ErrMsg ) + SUBROUTINE Farm_DestroyWakeDynamics_Data( WakeDynamics_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WakeDynamics_Data), INTENT(INOUT) :: WakeDynamics_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroyWakeDynamics_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroyWakeDynamics_Data' + ErrStat = ErrID_None ErrMsg = "" - CALL WD_DestroyContState( WakeDynamics_DataData%x, ErrStat, ErrMsg ) - CALL WD_DestroyDiscState( WakeDynamics_DataData%xd, ErrStat, ErrMsg ) - CALL WD_DestroyConstrState( WakeDynamics_DataData%z, ErrStat, ErrMsg ) - CALL WD_DestroyOtherState( WakeDynamics_DataData%OtherSt, ErrStat, ErrMsg ) - CALL WD_DestroyParam( WakeDynamics_DataData%p, ErrStat, ErrMsg ) - CALL WD_DestroyInput( WakeDynamics_DataData%u, ErrStat, ErrMsg ) - CALL WD_DestroyOutput( WakeDynamics_DataData%y, ErrStat, ErrMsg ) - CALL WD_DestroyMisc( WakeDynamics_DataData%m, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL WD_DestroyContState( WakeDynamics_DataData%x, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL WD_DestroyDiscState( WakeDynamics_DataData%xd, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL WD_DestroyConstrState( WakeDynamics_DataData%z, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL WD_DestroyOtherState( WakeDynamics_DataData%OtherSt, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL WD_DestroyParam( WakeDynamics_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL WD_DestroyInput( WakeDynamics_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL WD_DestroyOutput( WakeDynamics_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL WD_DestroyMisc( WakeDynamics_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE Farm_DestroyWakeDynamics_Data SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2421,7 +2832,865 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt Int_BufSz = 0 ! Allocate buffers for subtypes, if any (we'll get sizes from these) Int_BufSz = Int_BufSz + 3 ! x: size of buffers for each call to pack subtype - CALL WD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, .TRUE. ) ! x + CALL WD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, .TRUE. ) ! x + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! x + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! x + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! x + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! xd: size of buffers for each call to pack subtype + CALL WD_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, .TRUE. ) ! xd + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! xd + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! xd + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! xd + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! z: size of buffers for each call to pack subtype + CALL WD_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, .TRUE. ) ! z + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! z + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! z + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! z + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! OtherSt: size of buffers for each call to pack subtype + CALL WD_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, .TRUE. ) ! OtherSt + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! OtherSt + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! OtherSt + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! OtherSt + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! p: size of buffers for each call to pack subtype + CALL WD_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! p + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! p + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! p + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! u: size of buffers for each call to pack subtype + CALL WD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, .TRUE. ) ! u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! u + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! u + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! u + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! y: size of buffers for each call to pack subtype + CALL WD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! y + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! y + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! y + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! m: size of buffers for each call to pack subtype + CALL WD_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! m + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! m + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! m + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! IsInitialized + 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 WD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, OnlySize ) ! x + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL WD_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, OnlySize ) ! xd + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL WD_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, OnlySize ) ! z + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL WD_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, OnlySize ) ! OtherSt + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL WD_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL WD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, OnlySize ) ! u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL WD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL WD_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IntKiBuf(Int_Xferred) = TRANSFER(InData%IsInitialized, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE Farm_PackWakeDynamics_Data + + SUBROUTINE Farm_UnPackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(WakeDynamics_Data), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_UnPackWakeDynamics_Data' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + 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 WD_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%x, ErrStat2, ErrMsg2 ) ! x + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + 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 WD_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%xd, ErrStat2, ErrMsg2 ) ! xd + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + 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 WD_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%z, ErrStat2, ErrMsg2 ) ! z + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + 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 WD_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%OtherSt, ErrStat2, ErrMsg2 ) ! OtherSt + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + 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 WD_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%p, ErrStat2, ErrMsg2 ) ! p + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL WD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u, ErrStat2, ErrMsg2 ) ! u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL WD_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL WD_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + OutData%IsInitialized = TRANSFER(IntKiBuf(Int_Xferred), OutData%IsInitialized) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE Farm_UnPackWakeDynamics_Data + + SUBROUTINE Farm_CopyAWAE_Data( SrcAWAE_DataData, DstAWAE_DataData, CtrlCode, ErrStat, ErrMsg ) + TYPE(AWAE_Data), INTENT(IN) :: SrcAWAE_DataData + TYPE(AWAE_Data), INTENT(INOUT) :: DstAWAE_DataData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_CopyAWAE_Data' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL AWAE_CopyContState( SrcAWAE_DataData%x, DstAWAE_DataData%x, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL AWAE_CopyDiscState( SrcAWAE_DataData%xd, DstAWAE_DataData%xd, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL AWAE_CopyConstrState( SrcAWAE_DataData%z, DstAWAE_DataData%z, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL AWAE_CopyOtherState( SrcAWAE_DataData%OtherSt, DstAWAE_DataData%OtherSt, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL AWAE_CopyParam( SrcAWAE_DataData%p, DstAWAE_DataData%p, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL AWAE_CopyInput( SrcAWAE_DataData%u, DstAWAE_DataData%u, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL AWAE_CopyOutput( SrcAWAE_DataData%y, DstAWAE_DataData%y, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL AWAE_CopyMisc( SrcAWAE_DataData%m, DstAWAE_DataData%m, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstAWAE_DataData%IsInitialized = SrcAWAE_DataData%IsInitialized + END SUBROUTINE Farm_CopyAWAE_Data + + SUBROUTINE Farm_DestroyAWAE_Data( AWAE_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(AWAE_Data), INTENT(INOUT) :: AWAE_DataData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroyAWAE_Data' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AWAE_DestroyContState( AWAE_DataData%x, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AWAE_DestroyDiscState( AWAE_DataData%xd, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AWAE_DestroyConstrState( AWAE_DataData%z, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AWAE_DestroyOtherState( AWAE_DataData%OtherSt, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AWAE_DestroyParam( AWAE_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AWAE_DestroyInput( AWAE_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AWAE_DestroyOutput( AWAE_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AWAE_DestroyMisc( AWAE_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE Farm_DestroyAWAE_Data + + SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(AWAE_Data), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_PackAWAE_Data' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! x: size of buffers for each call to pack subtype + CALL AWAE_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, .TRUE. ) ! x CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2438,7 +3707,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! xd: size of buffers for each call to pack subtype - CALL WD_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, .TRUE. ) ! xd + CALL AWAE_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, .TRUE. ) ! xd CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2455,7 +3724,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! z: size of buffers for each call to pack subtype - CALL WD_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, .TRUE. ) ! z + CALL AWAE_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, .TRUE. ) ! z CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2472,7 +3741,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! OtherSt: size of buffers for each call to pack subtype - CALL WD_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, .TRUE. ) ! OtherSt + CALL AWAE_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, .TRUE. ) ! OtherSt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2489,7 +3758,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! p: size of buffers for each call to pack subtype - CALL WD_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p + CALL AWAE_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2506,7 +3775,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! u: size of buffers for each call to pack subtype - CALL WD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, .TRUE. ) ! u + CALL AWAE_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, .TRUE. ) ! u CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2523,7 +3792,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! y: size of buffers for each call to pack subtype - CALL WD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y + CALL AWAE_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2540,7 +3809,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! m: size of buffers for each call to pack subtype - CALL WD_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m + CALL AWAE_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2584,7 +3853,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt Db_Xferred = 1 Int_Xferred = 1 - CALL WD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, OnlySize ) ! x + CALL AWAE_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, OnlySize ) ! x CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2612,7 +3881,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WD_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, OnlySize ) ! xd + CALL AWAE_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, OnlySize ) ! xd CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2640,7 +3909,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WD_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, OnlySize ) ! z + CALL AWAE_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, OnlySize ) ! z CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2668,7 +3937,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WD_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, OnlySize ) ! OtherSt + CALL AWAE_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, OnlySize ) ! OtherSt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2696,7 +3965,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WD_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p + CALL AWAE_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2724,7 +3993,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, OnlySize ) ! u + CALL AWAE_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, OnlySize ) ! u CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2752,7 +4021,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y + CALL AWAE_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2780,7 +4049,7 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL WD_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m + CALL AWAE_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2810,13 +4079,13 @@ SUBROUTINE Farm_PackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt ENDIF IntKiBuf(Int_Xferred) = TRANSFER(InData%IsInitialized, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - END SUBROUTINE Farm_PackWakeDynamics_Data + END SUBROUTINE Farm_PackAWAE_Data - SUBROUTINE Farm_UnPackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE Farm_UnPackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(WakeDynamics_Data), INTENT(INOUT) :: OutData + TYPE(AWAE_Data), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -2827,7 +4096,7 @@ SUBROUTINE Farm_UnPackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Er INTEGER(IntKi) :: i INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'Farm_UnPackWakeDynamics_Data' + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_UnPackAWAE_Data' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -2871,7 +4140,7 @@ SUBROUTINE Farm_UnPackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WD_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%x, ErrStat2, ErrMsg2 ) ! x + CALL AWAE_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%x, ErrStat2, ErrMsg2 ) ! x CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2911,7 +4180,7 @@ SUBROUTINE Farm_UnPackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WD_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%xd, ErrStat2, ErrMsg2 ) ! xd + CALL AWAE_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%xd, ErrStat2, ErrMsg2 ) ! xd CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2951,7 +4220,7 @@ SUBROUTINE Farm_UnPackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WD_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%z, ErrStat2, ErrMsg2 ) ! z + CALL AWAE_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%z, ErrStat2, ErrMsg2 ) ! z CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2991,7 +4260,7 @@ SUBROUTINE Farm_UnPackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WD_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%OtherSt, ErrStat2, ErrMsg2 ) ! OtherSt + CALL AWAE_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%OtherSt, ErrStat2, ErrMsg2 ) ! OtherSt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3031,7 +4300,7 @@ SUBROUTINE Farm_UnPackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WD_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%p, ErrStat2, ErrMsg2 ) ! p + CALL AWAE_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%p, ErrStat2, ErrMsg2 ) ! p CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3071,7 +4340,7 @@ SUBROUTINE Farm_UnPackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u, ErrStat2, ErrMsg2 ) ! u + CALL AWAE_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u, ErrStat2, ErrMsg2 ) ! u CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3111,7 +4380,7 @@ SUBROUTINE Farm_UnPackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WD_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y + CALL AWAE_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3151,7 +4420,7 @@ SUBROUTINE Farm_UnPackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Er Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL WD_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m + CALL AWAE_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3160,73 +4429,95 @@ SUBROUTINE Farm_UnPackWakeDynamics_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Er IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) OutData%IsInitialized = TRANSFER(IntKiBuf(Int_Xferred), OutData%IsInitialized) Int_Xferred = Int_Xferred + 1 - END SUBROUTINE Farm_UnPackWakeDynamics_Data + END SUBROUTINE Farm_UnPackAWAE_Data - SUBROUTINE Farm_CopyAWAE_Data( SrcAWAE_DataData, DstAWAE_DataData, CtrlCode, ErrStat, ErrMsg ) - TYPE(AWAE_Data), INTENT(IN) :: SrcAWAE_DataData - TYPE(AWAE_Data), INTENT(INOUT) :: DstAWAE_DataData + SUBROUTINE Farm_CopySC_Data( SrcSC_DataData, DstSC_DataData, CtrlCode, ErrStat, ErrMsg ) + TYPE(SC_Data), INTENT(IN) :: SrcSC_DataData + TYPE(SC_Data), INTENT(INOUT) :: DstSC_DataData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'Farm_CopyAWAE_Data' + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_CopySC_Data' ! ErrStat = ErrID_None ErrMsg = "" - CALL AWAE_CopyContState( SrcAWAE_DataData%x, DstAWAE_DataData%x, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SC_CopyContState( SrcSC_DataData%x, DstSC_DataData%x, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AWAE_CopyDiscState( SrcAWAE_DataData%xd, DstAWAE_DataData%xd, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SC_CopyDiscState( SrcSC_DataData%xd, DstSC_DataData%xd, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AWAE_CopyConstrState( SrcAWAE_DataData%z, DstAWAE_DataData%z, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SC_CopyConstrState( SrcSC_DataData%z, DstSC_DataData%z, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AWAE_CopyOtherState( SrcAWAE_DataData%OtherSt, DstAWAE_DataData%OtherSt, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SC_CopyOtherState( SrcSC_DataData%OtherState, DstSC_DataData%OtherState, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AWAE_CopyParam( SrcAWAE_DataData%p, DstAWAE_DataData%p, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SC_CopyParam( SrcSC_DataData%p, DstSC_DataData%p, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AWAE_CopyInput( SrcAWAE_DataData%u, DstAWAE_DataData%u, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SC_CopyInput( SrcSC_DataData%uInputs, DstSC_DataData%uInputs, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AWAE_CopyOutput( SrcAWAE_DataData%y, DstAWAE_DataData%y, CtrlCode, ErrStat2, ErrMsg2 ) + DstSC_DataData%utimes = SrcSC_DataData%utimes + CALL SC_CopyOutput( SrcSC_DataData%y, DstSC_DataData%y, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AWAE_CopyMisc( SrcAWAE_DataData%m, DstAWAE_DataData%m, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SC_CopyMisc( SrcSC_DataData%m, DstSC_DataData%m, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - DstAWAE_DataData%IsInitialized = SrcAWAE_DataData%IsInitialized - END SUBROUTINE Farm_CopyAWAE_Data + DstSC_DataData%IsInitialized = SrcSC_DataData%IsInitialized + END SUBROUTINE Farm_CopySC_Data - SUBROUTINE Farm_DestroyAWAE_Data( AWAE_DataData, ErrStat, ErrMsg ) - TYPE(AWAE_Data), INTENT(INOUT) :: AWAE_DataData + SUBROUTINE Farm_DestroySC_Data( SC_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(SC_Data), INTENT(INOUT) :: SC_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroyAWAE_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroySC_Data' + ErrStat = ErrID_None ErrMsg = "" - CALL AWAE_DestroyContState( AWAE_DataData%x, ErrStat, ErrMsg ) - CALL AWAE_DestroyDiscState( AWAE_DataData%xd, ErrStat, ErrMsg ) - CALL AWAE_DestroyConstrState( AWAE_DataData%z, ErrStat, ErrMsg ) - CALL AWAE_DestroyOtherState( AWAE_DataData%OtherSt, ErrStat, ErrMsg ) - CALL AWAE_DestroyParam( AWAE_DataData%p, ErrStat, ErrMsg ) - CALL AWAE_DestroyInput( AWAE_DataData%u, ErrStat, ErrMsg ) - CALL AWAE_DestroyOutput( AWAE_DataData%y, ErrStat, ErrMsg ) - CALL AWAE_DestroyMisc( AWAE_DataData%m, ErrStat, ErrMsg ) - END SUBROUTINE Farm_DestroyAWAE_Data - SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL SC_DestroyContState( SC_DataData%x, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SC_DestroyDiscState( SC_DataData%xd, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SC_DestroyConstrState( SC_DataData%z, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SC_DestroyOtherState( SC_DataData%OtherState, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SC_DestroyParam( SC_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SC_DestroyInput( SC_DataData%uInputs, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SC_DestroyOutput( SC_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SC_DestroyMisc( SC_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE Farm_DestroySC_Data + + SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(AWAE_Data), INTENT(IN) :: InData + TYPE(SC_Data), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -3241,7 +4532,7 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'Farm_PackAWAE_Data' + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_PackSC_Data' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -3259,7 +4550,7 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Int_BufSz = 0 ! Allocate buffers for subtypes, if any (we'll get sizes from these) Int_BufSz = Int_BufSz + 3 ! x: size of buffers for each call to pack subtype - CALL AWAE_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, .TRUE. ) ! x + CALL SC_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, .TRUE. ) ! x CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3276,7 +4567,7 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! xd: size of buffers for each call to pack subtype - CALL AWAE_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, .TRUE. ) ! xd + CALL SC_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, .TRUE. ) ! xd CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3293,7 +4584,7 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! z: size of buffers for each call to pack subtype - CALL AWAE_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, .TRUE. ) ! z + CALL SC_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, .TRUE. ) ! z CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3309,25 +4600,25 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! OtherSt: size of buffers for each call to pack subtype - CALL AWAE_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, .TRUE. ) ! OtherSt + Int_BufSz = Int_BufSz + 3 ! OtherState: size of buffers for each call to pack subtype + CALL SC_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherState, ErrStat2, ErrMsg2, .TRUE. ) ! OtherState CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! OtherSt + IF(ALLOCATED(Re_Buf)) THEN ! OtherState Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! OtherSt + IF(ALLOCATED(Db_Buf)) THEN ! OtherState Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! OtherSt + IF(ALLOCATED(Int_Buf)) THEN ! OtherState Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! p: size of buffers for each call to pack subtype - CALL AWAE_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p + CALL SC_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3343,25 +4634,26 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! u: size of buffers for each call to pack subtype - CALL AWAE_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, .TRUE. ) ! u + Int_BufSz = Int_BufSz + 3 ! uInputs: size of buffers for each call to pack subtype + CALL SC_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%uInputs, ErrStat2, ErrMsg2, .TRUE. ) ! uInputs CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! u + IF(ALLOCATED(Re_Buf)) THEN ! uInputs Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! u + IF(ALLOCATED(Db_Buf)) THEN ! uInputs Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! u + IF(ALLOCATED(Int_Buf)) THEN ! uInputs Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Db_BufSz = Db_BufSz + SIZE(InData%utimes) ! utimes Int_BufSz = Int_BufSz + 3 ! y: size of buffers for each call to pack subtype - CALL AWAE_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y + CALL SC_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3378,7 +4670,7 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! m: size of buffers for each call to pack subtype - CALL AWAE_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m + CALL SC_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3422,7 +4714,7 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Db_Xferred = 1 Int_Xferred = 1 - CALL AWAE_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, OnlySize ) ! x + CALL SC_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, OnlySize ) ! x CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3450,7 +4742,7 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL AWAE_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, OnlySize ) ! xd + CALL SC_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, OnlySize ) ! xd CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3478,7 +4770,7 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL AWAE_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, OnlySize ) ! z + CALL SC_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, OnlySize ) ! z CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3506,7 +4798,7 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL AWAE_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, OnlySize ) ! OtherSt + CALL SC_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherState, ErrStat2, ErrMsg2, OnlySize ) ! OtherState CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3534,7 +4826,7 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL AWAE_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p + CALL SC_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3562,7 +4854,7 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL AWAE_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, OnlySize ) ! u + CALL SC_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%uInputs, ErrStat2, ErrMsg2, OnlySize ) ! uInputs CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3590,7 +4882,11 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL AWAE_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y + DO i1 = LBOUND(InData%utimes,1), UBOUND(InData%utimes,1) + DbKiBuf(Db_Xferred) = InData%utimes(i1) + Db_Xferred = Db_Xferred + 1 + END DO + CALL SC_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3618,7 +4914,7 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL AWAE_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m + CALL SC_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3648,13 +4944,13 @@ SUBROUTINE Farm_PackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ENDIF IntKiBuf(Int_Xferred) = TRANSFER(InData%IsInitialized, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - END SUBROUTINE Farm_PackAWAE_Data + END SUBROUTINE Farm_PackSC_Data - SUBROUTINE Farm_UnPackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE Farm_UnPackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(AWAE_Data), INTENT(INOUT) :: OutData + TYPE(SC_Data), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -3663,9 +4959,10 @@ SUBROUTINE Farm_UnPackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E 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 = 'Farm_UnPackAWAE_Data' + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_UnPackSC_Data' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -3709,7 +5006,7 @@ SUBROUTINE Farm_UnPackAWAE_Data( 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 AWAE_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%x, ErrStat2, ErrMsg2 ) ! x + CALL SC_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%x, ErrStat2, ErrMsg2 ) ! x CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3749,7 +5046,7 @@ SUBROUTINE Farm_UnPackAWAE_Data( 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 AWAE_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%xd, ErrStat2, ErrMsg2 ) ! xd + CALL SC_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%xd, ErrStat2, ErrMsg2 ) ! xd CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3789,7 +5086,7 @@ SUBROUTINE Farm_UnPackAWAE_Data( 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 AWAE_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%z, ErrStat2, ErrMsg2 ) ! z + CALL SC_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%z, ErrStat2, ErrMsg2 ) ! z CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3829,7 +5126,7 @@ SUBROUTINE Farm_UnPackAWAE_Data( 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 AWAE_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%OtherSt, ErrStat2, ErrMsg2 ) ! OtherSt + CALL SC_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%OtherState, ErrStat2, ErrMsg2 ) ! OtherState CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3869,7 +5166,7 @@ SUBROUTINE Farm_UnPackAWAE_Data( 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 AWAE_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%p, ErrStat2, ErrMsg2 ) ! p + CALL SC_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%p, ErrStat2, ErrMsg2 ) ! p CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3909,13 +5206,19 @@ SUBROUTINE Farm_UnPackAWAE_Data( 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 AWAE_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u, ErrStat2, ErrMsg2 ) ! u + CALL SC_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%uInputs, ErrStat2, ErrMsg2 ) ! uInputs CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + i1_l = LBOUND(OutData%utimes,1) + i1_u = UBOUND(OutData%utimes,1) + DO i1 = LBOUND(OutData%utimes,1), UBOUND(OutData%utimes,1) + OutData%utimes(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -3949,7 +5252,7 @@ SUBROUTINE Farm_UnPackAWAE_Data( 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 AWAE_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y + CALL SC_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3989,7 +5292,7 @@ SUBROUTINE Farm_UnPackAWAE_Data( 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 AWAE_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m + CALL SC_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3998,11 +5301,11 @@ SUBROUTINE Farm_UnPackAWAE_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) OutData%IsInitialized = TRANSFER(IntKiBuf(Int_Xferred), OutData%IsInitialized) Int_Xferred = Int_Xferred + 1 - END SUBROUTINE Farm_UnPackAWAE_Data + END SUBROUTINE Farm_UnPackSC_Data - SUBROUTINE Farm_CopySC_Data( SrcSC_DataData, DstSC_DataData, CtrlCode, ErrStat, ErrMsg ) - TYPE(SC_Data), INTENT(IN) :: SrcSC_DataData - TYPE(SC_Data), INTENT(INOUT) :: DstSC_DataData + SUBROUTINE Farm_CopyMD_Data( SrcMD_DataData, DstMD_DataData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_Data), INTENT(INOUT) :: SrcMD_DataData + TYPE(MD_Data), INTENT(INOUT) :: DstMD_DataData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -4011,62 +5314,119 @@ SUBROUTINE Farm_CopySC_Data( SrcSC_DataData, DstSC_DataData, CtrlCode, ErrStat, INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'Farm_CopySC_Data' + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_CopyMD_Data' ! ErrStat = ErrID_None ErrMsg = "" - CALL SC_CopyContState( SrcSC_DataData%x, DstSC_DataData%x, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MD_CopyContState( SrcMD_DataData%x, DstMD_DataData%x, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL SC_CopyDiscState( SrcSC_DataData%xd, DstSC_DataData%xd, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MD_CopyDiscState( SrcMD_DataData%xd, DstMD_DataData%xd, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL SC_CopyConstrState( SrcSC_DataData%z, DstSC_DataData%z, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MD_CopyConstrState( SrcMD_DataData%z, DstMD_DataData%z, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL SC_CopyOtherState( SrcSC_DataData%OtherState, DstSC_DataData%OtherState, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MD_CopyOtherState( SrcMD_DataData%OtherSt, DstMD_DataData%OtherSt, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL SC_CopyParam( SrcSC_DataData%p, DstSC_DataData%p, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MD_CopyParam( SrcMD_DataData%p, DstMD_DataData%p, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL SC_CopyInput( SrcSC_DataData%uInputs, DstSC_DataData%uInputs, CtrlCode, ErrStat2, ErrMsg2 ) + CALL MD_CopyInput( SrcMD_DataData%u, DstMD_DataData%u, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - DstSC_DataData%utimes = SrcSC_DataData%utimes - CALL SC_CopyOutput( SrcSC_DataData%y, DstSC_DataData%y, CtrlCode, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(SrcMD_DataData%Input)) THEN + i1_l = LBOUND(SrcMD_DataData%Input,1) + i1_u = UBOUND(SrcMD_DataData%Input,1) + IF (.NOT. ALLOCATED(DstMD_DataData%Input)) THEN + ALLOCATE(DstMD_DataData%Input(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMD_DataData%Input.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMD_DataData%Input,1), UBOUND(SrcMD_DataData%Input,1) + CALL MD_CopyInput( SrcMD_DataData%Input(i1), DstMD_DataData%Input(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL SC_CopyMisc( SrcSC_DataData%m, DstSC_DataData%m, CtrlCode, ErrStat2, ErrMsg2 ) + ENDDO +ENDIF +IF (ALLOCATED(SrcMD_DataData%InputTimes)) THEN + i1_l = LBOUND(SrcMD_DataData%InputTimes,1) + i1_u = UBOUND(SrcMD_DataData%InputTimes,1) + IF (.NOT. ALLOCATED(DstMD_DataData%InputTimes)) THEN + ALLOCATE(DstMD_DataData%InputTimes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMD_DataData%InputTimes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMD_DataData%InputTimes = SrcMD_DataData%InputTimes +ENDIF + CALL MD_CopyOutput( SrcMD_DataData%y, DstMD_DataData%y, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - DstSC_DataData%IsInitialized = SrcSC_DataData%IsInitialized - END SUBROUTINE Farm_CopySC_Data + CALL MD_CopyMisc( SrcMD_DataData%m, DstMD_DataData%m, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstMD_DataData%IsInitialized = SrcMD_DataData%IsInitialized + END SUBROUTINE Farm_CopyMD_Data - SUBROUTINE Farm_DestroySC_Data( SC_DataData, ErrStat, ErrMsg ) - TYPE(SC_Data), INTENT(INOUT) :: SC_DataData + SUBROUTINE Farm_DestroyMD_Data( MD_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_Data), INTENT(INOUT) :: MD_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroySC_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroyMD_Data' + ErrStat = ErrID_None ErrMsg = "" - CALL SC_DestroyContState( SC_DataData%x, ErrStat, ErrMsg ) - CALL SC_DestroyDiscState( SC_DataData%xd, ErrStat, ErrMsg ) - CALL SC_DestroyConstrState( SC_DataData%z, ErrStat, ErrMsg ) - CALL SC_DestroyOtherState( SC_DataData%OtherState, ErrStat, ErrMsg ) - CALL SC_DestroyParam( SC_DataData%p, ErrStat, ErrMsg ) - CALL SC_DestroyInput( SC_DataData%uInputs, ErrStat, ErrMsg ) - CALL SC_DestroyOutput( SC_DataData%y, ErrStat, ErrMsg ) - CALL SC_DestroyMisc( SC_DataData%m, ErrStat, ErrMsg ) - END SUBROUTINE Farm_DestroySC_Data - SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MD_DestroyContState( MD_DataData%x, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MD_DestroyDiscState( MD_DataData%xd, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MD_DestroyConstrState( MD_DataData%z, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MD_DestroyOtherState( MD_DataData%OtherSt, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MD_DestroyParam( MD_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MD_DestroyInput( MD_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(MD_DataData%Input)) THEN +DO i1 = LBOUND(MD_DataData%Input,1), UBOUND(MD_DataData%Input,1) + CALL MD_DestroyInput( MD_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MD_DataData%Input) +ENDIF +IF (ALLOCATED(MD_DataData%InputTimes)) THEN + DEALLOCATE(MD_DataData%InputTimes) +ENDIF + CALL MD_DestroyOutput( MD_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MD_DestroyMisc( MD_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE Farm_DestroyMD_Data + + SUBROUTINE Farm_PackMD_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(SC_Data), INTENT(IN) :: InData + TYPE(MD_Data), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -4081,7 +5441,7 @@ SUBROUTINE Farm_PackSC_Data( 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 = 'Farm_PackSC_Data' + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_PackMD_Data' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -4099,7 +5459,7 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = 0 ! Allocate buffers for subtypes, if any (we'll get sizes from these) Int_BufSz = Int_BufSz + 3 ! x: size of buffers for each call to pack subtype - CALL SC_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, .TRUE. ) ! x + CALL MD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, .TRUE. ) ! x CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4116,7 +5476,7 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! xd: size of buffers for each call to pack subtype - CALL SC_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, .TRUE. ) ! xd + CALL MD_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, .TRUE. ) ! xd CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4133,7 +5493,7 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! z: size of buffers for each call to pack subtype - CALL SC_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, .TRUE. ) ! z + CALL MD_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, .TRUE. ) ! z CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4145,64 +5505,91 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! z + IF(ALLOCATED(Int_Buf)) THEN ! z + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! OtherSt: size of buffers for each call to pack subtype + CALL MD_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, .TRUE. ) ! OtherSt + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! OtherSt + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! OtherSt + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! OtherSt Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! OtherState: size of buffers for each call to pack subtype - CALL SC_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherState, ErrStat2, ErrMsg2, .TRUE. ) ! OtherState + Int_BufSz = Int_BufSz + 3 ! p: size of buffers for each call to pack subtype + CALL MD_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! OtherState + IF(ALLOCATED(Re_Buf)) THEN ! p Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! OtherState + IF(ALLOCATED(Db_Buf)) THEN ! p Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! OtherState + IF(ALLOCATED(Int_Buf)) THEN ! p Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! p: size of buffers for each call to pack subtype - CALL SC_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p + Int_BufSz = Int_BufSz + 3 ! u: size of buffers for each call to pack subtype + CALL MD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, .TRUE. ) ! u CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! p + IF(ALLOCATED(Re_Buf)) THEN ! u Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! p + IF(ALLOCATED(Db_Buf)) THEN ! u Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! p + IF(ALLOCATED(Int_Buf)) THEN ! u Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! uInputs: size of buffers for each call to pack subtype - CALL SC_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%uInputs, ErrStat2, ErrMsg2, .TRUE. ) ! uInputs + Int_BufSz = Int_BufSz + 1 ! Input allocated yes/no + IF ( ALLOCATED(InData%Input) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Input upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Input,1), UBOUND(InData%Input,1) + Int_BufSz = Int_BufSz + 3 ! Input: size of buffers for each call to pack subtype + CALL MD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Input CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! uInputs + IF(ALLOCATED(Re_Buf)) THEN ! Input Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! uInputs + IF(ALLOCATED(Db_Buf)) THEN ! Input Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! uInputs + IF(ALLOCATED(Int_Buf)) THEN ! Input Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Db_BufSz = Db_BufSz + SIZE(InData%utimes) ! utimes + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! InputTimes allocated yes/no + IF ( ALLOCATED(InData%InputTimes) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! InputTimes upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes + END IF Int_BufSz = Int_BufSz + 3 ! y: size of buffers for each call to pack subtype - CALL SC_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y + CALL MD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4219,7 +5606,7 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! m: size of buffers for each call to pack subtype - CALL SC_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m + CALL MD_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4263,7 +5650,7 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Db_Xferred = 1 Int_Xferred = 1 - CALL SC_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, OnlySize ) ! x + CALL MD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, OnlySize ) ! x CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4291,7 +5678,7 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL SC_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, OnlySize ) ! xd + CALL MD_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, OnlySize ) ! xd CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4319,7 +5706,7 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL SC_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, OnlySize ) ! z + CALL MD_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, OnlySize ) ! z CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4347,7 +5734,7 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL SC_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherState, ErrStat2, ErrMsg2, OnlySize ) ! OtherState + CALL MD_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, OnlySize ) ! OtherSt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4375,7 +5762,7 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL SC_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p + CALL MD_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4403,7 +5790,46 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL SC_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%uInputs, ErrStat2, ErrMsg2, OnlySize ) ! uInputs + CALL MD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, OnlySize ) ! u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF ( .NOT. ALLOCATED(InData%Input) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Input,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Input,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Input,1), UBOUND(InData%Input,1) + CALL MD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%Input(i1), ErrStat2, ErrMsg2, OnlySize ) ! Input CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4431,11 +5857,24 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - DO i1 = LBOUND(InData%utimes,1), UBOUND(InData%utimes,1) - DbKiBuf(Db_Xferred) = InData%utimes(i1) - Db_Xferred = Db_Xferred + 1 END DO - CALL SC_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y + END IF + IF ( .NOT. ALLOCATED(InData%InputTimes) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%InputTimes,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InputTimes,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%InputTimes,1), UBOUND(InData%InputTimes,1) + DbKiBuf(Db_Xferred) = InData%InputTimes(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + CALL MD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4463,7 +5902,7 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL SC_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m + CALL MD_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4493,13 +5932,13 @@ SUBROUTINE Farm_PackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ENDIF IntKiBuf(Int_Xferred) = TRANSFER(InData%IsInitialized, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - END SUBROUTINE Farm_PackSC_Data + END SUBROUTINE Farm_PackMD_Data - SUBROUTINE Farm_UnPackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE Farm_UnPackMD_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(SC_Data), INTENT(INOUT) :: OutData + TYPE(MD_Data), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -4511,7 +5950,7 @@ SUBROUTINE Farm_UnPackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'Farm_UnPackSC_Data' + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_UnPackMD_Data' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -4555,7 +5994,7 @@ SUBROUTINE Farm_UnPackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL SC_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%x, ErrStat2, ErrMsg2 ) ! x + CALL MD_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%x, ErrStat2, ErrMsg2 ) ! x CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4595,7 +6034,7 @@ SUBROUTINE Farm_UnPackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL SC_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%xd, ErrStat2, ErrMsg2 ) ! xd + CALL MD_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%xd, ErrStat2, ErrMsg2 ) ! xd CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4635,7 +6074,7 @@ SUBROUTINE Farm_UnPackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL SC_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%z, ErrStat2, ErrMsg2 ) ! z + CALL MD_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%z, ErrStat2, ErrMsg2 ) ! z CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4675,7 +6114,7 @@ SUBROUTINE Farm_UnPackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL SC_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%OtherState, ErrStat2, ErrMsg2 ) ! OtherState + CALL MD_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%OtherSt, ErrStat2, ErrMsg2 ) ! OtherSt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4715,7 +6154,7 @@ SUBROUTINE Farm_UnPackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL SC_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%p, ErrStat2, ErrMsg2 ) ! p + CALL MD_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%p, ErrStat2, ErrMsg2 ) ! p CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4755,19 +6194,87 @@ SUBROUTINE Farm_UnPackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL SC_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%uInputs, ErrStat2, ErrMsg2 ) ! uInputs + CALL MD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u, ErrStat2, ErrMsg2 ) ! u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Input not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Input)) DEALLOCATE(OutData%Input) + ALLOCATE(OutData%Input(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Input.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Input,1), UBOUND(OutData%Input,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%Input(i1), ErrStat2, ErrMsg2 ) ! Input CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - i1_l = LBOUND(OutData%utimes,1) - i1_u = UBOUND(OutData%utimes,1) - DO i1 = LBOUND(OutData%utimes,1), UBOUND(OutData%utimes,1) - OutData%utimes(i1) = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InputTimes not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%InputTimes)) DEALLOCATE(OutData%InputTimes) + ALLOCATE(OutData%InputTimes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InputTimes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%InputTimes,1), UBOUND(OutData%InputTimes,1) + OutData%InputTimes(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -4801,7 +6308,7 @@ SUBROUTINE Farm_UnPackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL SC_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y + CALL MD_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4841,7 +6348,7 @@ SUBROUTINE Farm_UnPackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL SC_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m + CALL MD_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4850,7 +6357,7 @@ SUBROUTINE Farm_UnPackSC_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) OutData%IsInitialized = TRANSFER(IntKiBuf(Int_Xferred), OutData%IsInitialized) Int_Xferred = Int_Xferred + 1 - END SUBROUTINE Farm_UnPackSC_Data + END SUBROUTINE Farm_UnPackMD_Data SUBROUTINE Farm_CopyAll_FastFarm_Data( SrcAll_FastFarm_DataData, DstAll_FastFarm_DataData, CtrlCode, ErrStat, ErrMsg ) TYPE(All_FastFarm_Data), INTENT(INOUT) :: SrcAll_FastFarm_DataData @@ -4911,33 +6418,56 @@ SUBROUTINE Farm_CopyAll_FastFarm_Data( SrcAll_FastFarm_DataData, DstAll_FastFarm CALL Farm_Copysc_data( SrcAll_FastFarm_DataData%SC, DstAll_FastFarm_DataData%SC, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + CALL Farm_Copymd_data( SrcAll_FastFarm_DataData%MD, DstAll_FastFarm_DataData%MD, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE Farm_CopyAll_FastFarm_Data - SUBROUTINE Farm_DestroyAll_FastFarm_Data( All_FastFarm_DataData, ErrStat, ErrMsg ) + SUBROUTINE Farm_DestroyAll_FastFarm_Data( All_FastFarm_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(All_FastFarm_Data), INTENT(INOUT) :: All_FastFarm_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroyAll_FastFarm_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Farm_DestroyAll_FastFarm_Data' + ErrStat = ErrID_None ErrMsg = "" - CALL Farm_DestroyParam( All_FastFarm_DataData%p, ErrStat, ErrMsg ) - CALL Farm_DestroyMisc( All_FastFarm_DataData%m, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL Farm_DestroyParam( All_FastFarm_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Farm_DestroyMisc( All_FastFarm_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(All_FastFarm_DataData%FWrap)) THEN DO i1 = LBOUND(All_FastFarm_DataData%FWrap,1), UBOUND(All_FastFarm_DataData%FWrap,1) - CALL Farm_Destroyfastwrapper_data( All_FastFarm_DataData%FWrap(i1), ErrStat, ErrMsg ) + CALL Farm_Destroyfastwrapper_data( All_FastFarm_DataData%FWrap(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(All_FastFarm_DataData%FWrap) ENDIF IF (ALLOCATED(All_FastFarm_DataData%WD)) THEN DO i1 = LBOUND(All_FastFarm_DataData%WD,1), UBOUND(All_FastFarm_DataData%WD,1) - CALL Farm_Destroywakedynamics_data( All_FastFarm_DataData%WD(i1), ErrStat, ErrMsg ) + CALL Farm_Destroywakedynamics_data( All_FastFarm_DataData%WD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(All_FastFarm_DataData%WD) ENDIF - CALL Farm_Destroyawae_data( All_FastFarm_DataData%AWAE, ErrStat, ErrMsg ) - CALL Farm_Destroysc_data( All_FastFarm_DataData%SC, ErrStat, ErrMsg ) + CALL Farm_Destroyawae_data( All_FastFarm_DataData%AWAE, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Farm_Destroysc_data( All_FastFarm_DataData%SC, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Farm_Destroymd_data( All_FastFarm_DataData%MD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE Farm_DestroyAll_FastFarm_Data SUBROUTINE Farm_PackAll_FastFarm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -5090,6 +6620,23 @@ SUBROUTINE Farm_PackAll_FastFarm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 3 ! MD: size of buffers for each call to pack subtype + CALL Farm_Packmd_data( Re_Buf, Db_Buf, Int_Buf, InData%MD, ErrStat2, ErrMsg2, .TRUE. ) ! MD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! MD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! MD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! MD + 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 @@ -5311,6 +6858,34 @@ SUBROUTINE Farm_PackAll_FastFarm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + CALL Farm_Packmd_data( Re_Buf, Db_Buf, Int_Buf, InData%MD, ErrStat2, ErrMsg2, OnlySize ) ! MD + 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 Farm_PackAll_FastFarm_Data SUBROUTINE Farm_UnPackAll_FastFarm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -5612,6 +7187,46 @@ SUBROUTINE Farm_UnPackAll_FastFarm_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Er 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 Farm_Unpackmd_data( Re_Buf, Db_Buf, Int_Buf, OutData%MD, ErrStat2, ErrMsg2 ) ! MD + 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 Farm_UnPackAll_FastFarm_Data END MODULE FAST_Farm_Types diff --git a/glue-codes/openfast-cpp/CMakeLists.txt b/glue-codes/openfast-cpp/CMakeLists.txt index c08ebe66f..1b9cc76bf 100644 --- a/glue-codes/openfast-cpp/CMakeLists.txt +++ b/glue-codes/openfast-cpp/CMakeLists.txt @@ -18,6 +18,8 @@ if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12.0") cmake_policy(SET CMP0074 NEW) endif() +enable_language(CXX Fortran) + set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -27,18 +29,7 @@ find_package(ZLIB REQUIRED) find_package(HDF5 REQUIRED COMPONENTS C HL) find_package(yaml-cpp REQUIRED) -include_directories(${YAML_CPP_INCLUDE_DIRS}) -include_directories(${HDF5_INCLUDES}) -include_directories(${HDF5_INCLUDE_DIR}) -include_directories(${ZLIB_INCLUDES}) -include_directories(${LIBXML2_INCLUDE_DIR}) -include_directories(${CMAKE_SOURCE_DIR}/modules/openfast-library/src/) -include_directories(${CMAKE_BINARY_DIR}/modules/openfoam/) -include_directories(${CMAKE_BINARY_DIR}/modules/supercontroller/) -include_directories(${MPI_INCLUDE_PATH}) - -add_library(openfastcpplib - src/OpenFAST.cpp src/SC.cpp) +add_library(openfastcpplib src/OpenFAST.cpp src/SC.cpp) set_property(TARGET openfastcpplib PROPERTY POSITION_INDEPENDENT_CODE ON) target_link_libraries(openfastcpplib openfastlib @@ -47,17 +38,23 @@ target_link_libraries(openfastcpplib ${ZLIB_LIBRARIES} ${LIBXML2_LIBRARIES} ${MPI_LIBRARIES} - ${CMAKE_DL_LIBS}) +) +target_include_directories(openfastcpplib PUBLIC + ${HDF5_INCLUDES} + ${HDF5_INCLUDE_DIR} + ${ZLIB_INCLUDES} + ${LIBXML2_INCLUDE_DIR} + ${MPI_INCLUDE_PATH} +) +set_target_properties(openfastcpplib PROPERTIES PUBLIC_HEADER "src/OpenFAST.H;src/SC.h") add_executable(openfastcpp src/FAST_Prog.cpp) -target_link_libraries(openfastcpp openfastcpplib openfastlib - ${MPI_LIBRARIES} +target_link_libraries(openfastcpp ${YAML_CPP_LIBRARIES} - ${HDF5_C_LIBRARIES} - ${HDF5_HL_LIBRARIES} - ${ZLIB_LIBRARIES} - ${LIBXML2_LIBRARIES} - ${CMAKE_DL_LIBS}) + openfastcpplib +) +target_include_directories(openfastcpp PRIVATE ${YAML_CPP_INCLUDE_DIR}) +set_target_properties(openfastcpp PROPERTIES LINKER_LANGUAGE CXX) if(MPI_COMPILE_FLAGS) set_target_properties(openfastcpp PROPERTIES @@ -69,17 +66,10 @@ if(MPI_LINK_FLAGS) LINK_FLAGS "${MPI_LINK_FLAGS}") endif(MPI_LINK_FLAGS) -set_property(TARGET openfastcpp PROPERTY LINKER_LANGUAGE CXX) - -install(TARGETS openfastcpplib +install(TARGETS openfastcpp openfastcpplib EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION lib ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) - -install(FILES - src/OpenFAST.H src/SC.h - DESTINATION include) - -install(TARGETS openfastcpp - RUNTIME DESTINATION bin) + LIBRARY DESTINATION lib + PUBLIC_HEADER DESTINATION include +) diff --git a/glue-codes/openfast-cpp/src/OpenFAST.H b/glue-codes/openfast-cpp/src/OpenFAST.H index f823da27e..21ed980aa 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.H +++ b/glue-codes/openfast-cpp/src/OpenFAST.H @@ -28,6 +28,7 @@ struct globTurbineDataType { std::string FASTRestartFileName; std::vector TurbineBasePos; std::vector TurbineHubPos; + std::string forcePtsBladeDistributionType; int numForcePtsBlade; int numForcePtsTwr; float nacelle_cd{0.0}; @@ -104,6 +105,7 @@ class OpenFAST { int ntStart; // The time step to start the FAST simulation int nEveryCheckPoint; // Check point files will be written every 'nEveryCheckPoint' time steps std::vector numBlades; // Number of blades + std::vector forcePtsBladeDistributionType; std::vector numForcePtsBlade; std::vector numForcePtsTwr; std::vector numVelPtsBlade; diff --git a/glue-codes/openfast-cpp/src/OpenFAST.cpp b/glue-codes/openfast-cpp/src/OpenFAST.cpp index 8a415ced2..7a26e2017 100644 --- a/glue-codes/openfast-cpp/src/OpenFAST.cpp +++ b/glue-codes/openfast-cpp/src/OpenFAST.cpp @@ -106,6 +106,11 @@ void fast::OpenFAST::init() { // this calls the Init() routines of each module for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + int nodeClusterType = 0; + if (forcePtsBladeDistributionType[iTurb] == "chordClustered") + { + nodeClusterType = 1; + } std::copy( FASTInputFileName[iTurb].data(), FASTInputFileName[iTurb].data() + (FASTInputFileName[iTurb].size() + 1), @@ -128,6 +133,7 @@ void fast::OpenFAST::init() { &dtFAST, &numBlades[iTurb], &numVelPtsBlade[iTurb], + &nodeClusterType, &cDriver_Input_from_FAST[iTurb], &cDriver_Output_to_FAST[iTurb], &sc.ip_from_FAST[iTurb], @@ -170,6 +176,11 @@ void fast::OpenFAST::init() { } for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) { + int nodeClusterType = 0; + if (forcePtsBladeDistributionType[iTurb] == "chordClustered") + { + nodeClusterType = 1; + } std::copy( FASTInputFileName[iTurb].data(), FASTInputFileName[iTurb].data() + (FASTInputFileName[iTurb].size() + 1), @@ -192,6 +203,7 @@ void fast::OpenFAST::init() { &dtFAST, &numBlades[iTurb], &numVelPtsBlade[iTurb], + &nodeClusterType, &cDriver_Input_from_FAST[iTurb], &cDriver_Output_to_FAST[iTurb], &sc.ip_from_FAST[iTurb], @@ -807,6 +819,7 @@ void fast::OpenFAST::allocateMemory() { nacelle_area.resize(nTurbinesProc); air_density.resize(nTurbinesProc); numBlades.resize(nTurbinesProc); + forcePtsBladeDistributionType.resize(nTurbinesProc); numForcePtsBlade.resize(nTurbinesProc); numForcePtsTwr.resize(nTurbinesProc); numVelPtsBlade.resize(nTurbinesProc); @@ -824,6 +837,7 @@ void fast::OpenFAST::allocateMemory() { for(int i=0;i<3;i++) { TurbineBasePos[iTurb][i] = globTurbineData[globProc].TurbineBasePos[i]; } + forcePtsBladeDistributionType[iTurb] = globTurbineData[globProc].forcePtsBladeDistributionType; numForcePtsBlade[iTurb] = globTurbineData[globProc].numForcePtsBlade; numForcePtsTwr[iTurb] = globTurbineData[globProc].numForcePtsTwr; nacelle_cd[iTurb] = globTurbineData[globProc].nacelle_cd; @@ -837,7 +851,7 @@ void fast::OpenFAST::allocateMemory() { // Allocate memory for OpFM Input types in FAST cDriver_Input_from_FAST.resize(nTurbinesProc) ; cDriver_Output_to_FAST.resize(nTurbinesProc) ; - + if(scStatus) { std::cout << "Use of Supercontroller is not supported through the C++ API right now" << std::endl; // scio.from_SC.resize(nTurbinesProc); diff --git a/glue-codes/openfast/CMakeLists.txt b/glue-codes/openfast/CMakeLists.txt index b6de649e2..24dcb4d84 100644 --- a/glue-codes/openfast/CMakeLists.txt +++ b/glue-codes/openfast/CMakeLists.txt @@ -17,21 +17,18 @@ set (CMAKE_CXX_STANDARD 11) add_executable(openfast src/FAST_Prog.f90) -target_link_libraries(openfast openfast_postlib foamfastlib) -set_property(TARGET openfast PROPERTY LINKER_LANGUAGE Fortran) +target_link_libraries(openfast openfastlib_static) +set_target_properties(openfast PROPERTIES LINKER_LANGUAGE Fortran) -include_directories(${CMAKE_SOURCE_DIR}/modules/openfast-library/src/) -include_directories(${CMAKE_BINARY_DIR}/modules/openfoam/) -include_directories(${CMAKE_BINARY_DIR}/modules/supercontroller/) add_executable(openfast_cpp src/FAST_Prog.cpp src/FastLibAPI.cpp) target_link_libraries(openfast_cpp openfastlib) 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") +if (${_compiler_id} STREQUAL "GNU" AND NOT ${VARIABLE_TRACKING}) # 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. + # restarts with this option off. Disabling avoids this problem when compiling with + # full optimizations. However, variable tracking should be enabled when actively debugging + # for better runtime debugging output. # https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html set_source_files_properties(src/FAST_Prog.f90 PROPERTIES COMPILE_FLAGS "-fno-var-tracking -fno-var-tracking-assignments") endif() diff --git a/glue-codes/openfast/src/FastLibAPI.cpp b/glue-codes/openfast/src/FastLibAPI.cpp index 98c47ed64..12f58a7c7 100644 --- a/glue-codes/openfast/src/FastLibAPI.cpp +++ b/glue-codes/openfast/src/FastLibAPI.cpp @@ -1,6 +1,7 @@ #include "FastLibAPI.h" #include +#include #include #include #include @@ -12,6 +13,7 @@ FastLibAPI::FastLibAPI(std::string input_file): n_turbines(1), i_turb(0), dt(0.0), +dt_out(0.0), t_max(0.0), abort_error_level(4), end_early(false), @@ -33,6 +35,7 @@ bool FastLibAPI::fatal_error(int error_status) { void FastLibAPI::fast_init() { int _error_status = 0; char _error_message[INTERFACE_STRING_LENGTH]; + char channel_names[MAXIMUM_OUTPUTS * CHANNEL_LENGTH + 1]; std::cout << input_file_name; @@ -51,6 +54,7 @@ void FastLibAPI::fast_init() { &abort_error_level, &num_outs, &dt, + &dt_out, &t_max, &_error_status, _error_message, @@ -61,16 +65,16 @@ void FastLibAPI::fast_init() { } // Allocate the data for the outputs - - // Create a dynamic array of pointers - // Then, create a row for every pointer and initialize all elements to 0.0 - output_values = new double *[total_time_steps()]; - for (int i=0; i(num_outs, 0)); + + // Get output channel names + std::istringstream ss(channel_names); + std::string channel_name; + output_channel_names.clear(); + while (ss >> channel_name) + { + output_channel_names.push_back(channel_name); } - - output_array.resize(num_outs); } void FastLibAPI::fast_sim() { @@ -82,28 +86,32 @@ void FastLibAPI::fast_sim() { &num_inputs, &num_outs, inp_array, - output_array.data(), + output_values[0].data(), &_error_status, _error_message ); - output_values[0] = output_array.data(); if (fatal_error(_error_status)) { fast_deinit(); throw std::runtime_error( "Error " + std::to_string(_error_status) + ": " + _error_message ); } + int output_frequency = round(dt_out/dt); + int i_out = 1; + for (int i=1; i output_array; - double **output_values; + std::vector> output_values; public: @@ -48,7 +46,8 @@ class FastLibAPI { void fast_deinit(); void fast_run(); int total_time_steps(); - std::string output_channel_names(); + int total_output_steps(); + std::vector output_channel_names; void get_hub_position(float *absolute_position, float *rotational_velocity, double *orientation_dcm); }; diff --git a/glue-codes/python/openfast_library.py b/glue-codes/python/openfast_library.py index 234e21361..b354b4041 100644 --- a/glue-codes/python/openfast_library.py +++ b/glue-codes/python/openfast_library.py @@ -32,11 +32,12 @@ def __init__(self, library_path: str, input_file_name: str): self.n_turbines = c_int(1) self.i_turb = c_int(0) self.dt = c_double(0.0) + self.dt_out = c_double(0.0) self.t_max = c_double(0.0) self.abort_error_level = c_int(4) # Initialize to 4 (ErrID_Fatal) and reset to user-given value in FAST_Sizes self.end_early = c_bool(False) self.num_outs = c_int(0) - self.channel_names = create_string_buffer(20 * 4000) + self.output_channel_names = [] self.ended = False # The inputs are meant to be from Simulink. @@ -48,9 +49,7 @@ def __init__(self, library_path: str, input_file_name: str): self.inp_array = (c_double * self.num_inputs.value)(0.0, ) # These arrays hold the outputs from OpenFAST - # output_array is a 1D array for the values from a single step - # output_values is a 2D array for the values from all steps in the simulation - self.output_array = None + # output_values is a 2D array for the values from all output steps in the simulation self.output_values = None @@ -68,6 +67,7 @@ def _initialize_routines(self) -> None: POINTER(c_int), # AbortErrLev_c OUT POINTER(c_int), # NumOuts_c OUT POINTER(c_double), # dt_c OUT + POINTER(c_double), # dt_out_c OUT POINTER(c_double), # tmax_c OUT POINTER(c_int), # ErrStat_c OUT POINTER(c_char), # ErrMsg_c OUT @@ -139,28 +139,38 @@ def fast_init(self) -> None: if self.fatal_error(_error_status): raise RuntimeError(f"Error {_error_status.value}: {_error_message.value}") + # Create channel names argument + channel_names = create_string_buffer(20 * 4000) + self.FAST_Sizes( byref(self.i_turb), self.input_file_name, byref(self.abort_error_level), byref(self.num_outs), byref(self.dt), + byref(self.dt_out), byref(self.t_max), byref(_error_status), _error_message, - self.channel_names, + channel_names, None, # Optional arguments must pass C-Null pointer; with ctypes, use None. None # Optional arguments must pass C-Null pointer; with ctypes, use None. ) if self.fatal_error(_error_status): raise RuntimeError(f"Error {_error_status.value}: {_error_message.value}") + # Extract channel name strings from argument + if len(channel_names.value.split()) == 0: + self.output_channel_names = [] + else: + self.output_channel_names = [n.decode('UTF-8') for n in channel_names.value.split()] + # Allocate the data for the outputs - # NOTE: The ctypes array allocation (output_array) must be after the output_values - # allocation, or otherwise seg fault. - self.output_values = np.empty( (self.total_time_steps, self.num_outs.value) ) - self.output_array = (c_double * self.num_outs.value)(0.0, ) + self.output_values = np.zeros( (self.total_output_steps, self.num_outs.value), dtype=c_double, order='C' ) + # Delete error message and channel name character buffers + del _error_message + del channel_names def fast_sim(self) -> None: _error_status = c_int(0) @@ -171,27 +181,31 @@ def fast_sim(self) -> None: byref(self.num_inputs), byref(self.num_outs), byref(self.inp_array), - byref(self.output_array), + self.output_values[0].ctypes.data_as(POINTER(c_double)), byref(_error_status), _error_message ) - self.output_values[0] = self.output_array[:] if self.fatal_error(_error_status): self.fast_deinit() raise RuntimeError(f"Error {_error_status.value}: {_error_message.value}") + # Calculate output frequency and initialize output index + output_frequency = round(self.dt_out.value/self.dt.value) + i_out = 1 + for i in range( 1, self.total_time_steps ): self.FAST_Update( byref(self.i_turb), byref(self.num_inputs), byref(self.num_outs), byref(self.inp_array), - byref(self.output_array), + self.output_values[i_out].ctypes.data_as(POINTER(c_double)), byref(self.end_early), byref(_error_status), _error_message ) - self.output_values[i] = self.output_array[:] + if i%output_frequency == 0: + i_out += 1 if self.fatal_error(_error_status): self.fast_deinit() raise RuntimeError(f"Error {_error_status.value}: {_error_message.value}") @@ -241,16 +255,14 @@ def total_time_steps(self) -> int: # and that's why we have the +1 below # # We assume here t_initial is always 0 - return math.ceil( self.t_max.value / self.dt.value) + 1 + return math.ceil( self.t_max.value / self.dt.value) + 1 @property - def output_channel_names(self) -> List: - if len(self.channel_names.value.split()) == 0: - return [] - output_channel_names = self.channel_names.value.split() - output_channel_names = [n.decode('UTF-8') for n in output_channel_names] - return output_channel_names + def total_output_steps(self) -> int: + # From FAST_Subs ValidateInputData: DT_out == DT or DT_out is a multiple of DT + # So the number of output steps can be calculated the same as the total time steps + return math.ceil(self.t_max.value / self.dt_out.value) + 1 def get_hub_position(self) -> Tuple: diff --git a/glue-codes/simulink/CMakeLists.txt b/glue-codes/simulink/CMakeLists.txt new file mode 100644 index 000000000..f4251c35c --- /dev/null +++ b/glue-codes/simulink/CMakeLists.txt @@ -0,0 +1,77 @@ +# +# Copyright 2023 National Renewable Energy Laboratory +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# 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. +# + +# Build the matlab shared library (mex) using the current toolchain. +# Recommpiles FAST_* files with COMPILE_SIMULINK defined. +# Links directly to library files, bypassing dependencies so MATLAB specific +# libraries can be substituted (nwtclibs and servodynlib). openfast_postlib +# is used as a dependency to ensure that all library files exist before +# the FAST_SFunc target is built. +matlab_add_mex( + NAME FAST_SFunc + SRC + src/FAST_SFunc.c + ${PROJECT_SOURCE_DIR}/modules/openfast-library/src/FAST_Subs.f90 + ${PROJECT_SOURCE_DIR}/modules/openfast-library/src/FAST_Lin.f90 + ${PROJECT_SOURCE_DIR}/modules/openfast-library/src/FAST_Mods.f90 + ${PROJECT_SOURCE_DIR}/modules/openfast-library/src/FAST_Solver.f90 + ${PROJECT_SOURCE_DIR}/modules/openfast-library/src/FAST_Library.f90 + LINK_TO + $ # MATLAB Specific + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ # MATLAB Specific + $ + $ + $ + $ + ${LAPACK_LIBRARIES} + ${CMAKE_DL_LIBS} + ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES} +) +add_dependencies(FAST_SFunc openfast_postlib nwtclibs-matlab servodynlib-matlab) +target_compile_definitions(FAST_SFunc PUBLIC COMPILE_SIMULINK) +set_target_properties(FAST_SFunc PROPERTIES + Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/matlab) +target_include_directories(FAST_SFunc PUBLIC + $ + $ + $ +) +if(APPLE OR UNIX) + target_compile_definitions(FAST_SFunc PRIVATE IMPLICIT_DLLEXPORT) +endif() + +install(TARGETS FAST_SFunc + EXPORT "${CMAKE_PROJECT_NAME}Libraries" + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/glue-codes/simulink/README.md b/glue-codes/simulink/README.md new file mode 100644 index 000000000..a6509128b --- /dev/null +++ b/glue-codes/simulink/README.md @@ -0,0 +1,5 @@ +OpenFAST expects a set of channels passed from Simulink to the library. The number channels may change between OpenFAST releases. + +For list of control channels, see comments at end of source file modules/openfast-library/src/FAST_Library.h + +The examples included here inclue all the channels listed in the FAST_Library.h file. diff --git a/glue-codes/simulink/src/FAST_SFunc.c b/glue-codes/simulink/src/FAST_SFunc.c index b03d689a9..d18665a53 100644 --- a/glue-codes/simulink/src/FAST_SFunc.c +++ b/glue-codes/simulink/src/FAST_SFunc.c @@ -45,6 +45,7 @@ static double dt = 0; +static double dt_out = 0; static double TMax = 0; static int NumInputs = NumFixedInputs; static int NumAddInputs = 0; // number of additional inputs @@ -203,7 +204,7 @@ static void mdlInitializeSizes(SimStruct *S) FAST_AllocateTurbines(&nTurbines, &ErrStat, ErrMsg); if (checkError(S)) return; - FAST_Sizes(&iTurb, InputFileName, &AbortErrLev, &NumOutputs, &dt, &TMax, &ErrStat, ErrMsg, ChannelNames, &TMax, InitInputAry); + FAST_Sizes(&iTurb, InputFileName, &AbortErrLev, &NumOutputs, &dt, &dt_out, &TMax, &ErrStat, ErrMsg, ChannelNames, &TMax, InitInputAry); n_t_global = -1; if (checkError(S)) return; diff --git a/glue-codes/simulink/src/create_FAST_SFunc.m b/glue-codes/simulink/src/create_FAST_SFunc.m index 548f23529..4a7c6fdf5 100644 --- a/glue-codes/simulink/src/create_FAST_SFunc.m +++ b/glue-codes/simulink/src/create_FAST_SFunc.m @@ -1,4 +1,8 @@ %% INSTRUCTIONS +% This script is used to manually build a Simulink mex file which uses the openfastlib shared library (.dll, .so, .dylib). +% If you are building OpenFAST with CMake on linux or macOS or windows, you can automatically generate the mex file +% by specifying -DBUILD_OPENFAST_SIMULINK_API=ON when running cmake, you do not need to use this script. +% % Before running this script, you must have compiled OpenFAST for Simulink to create a DLL (i.e., a shared library like .so, .dylib, .lib, etc.). % - If cmake was used, make sure the install directory is specified properly in the `installDir` variable below, % and if using Windows, set `built_with_visualStudio` to false. @@ -12,10 +16,9 @@ % % Run `mex -setup` in Matlab to configure a C compiler if you have not already done so. - mexname = 'FAST_SFunc'; % base name of the resulting mex file -built_with_visualStudio = true; %if the libraries were built with cmake, set to false +built_with_visualStudio = false; %if the libraries were built with cmake, set to false if (ispc && built_with_visualStudio) @@ -48,26 +51,48 @@ % If there are shared libraries does it work for outDir to be the local directory? else installDir = '../../../install'; - outDir = fullfile(installDir, 'lib'); + outDir = '.'; end libDir = fullfile(installDir, 'lib'); includeDir = fullfile(installDir, 'include'); - libName = 'openfastlib'; + libName = 'openfastlib_mex'; end %% BUILD COMMAND fprintf( '\n----------------------------\n' ); fprintf( 'Creating %s\n\n', [outDir filesep mexname '.' mexext] ); -mex('-largeArrayDims', ... - ... % '-v', ... %add this line for "verbose" output (for debugging) - ['-L' libDir], ... - ['-l' libName], ... - ['-I' includeDir], ... - '-I../../../modules/supercontroller/src', ... % needed for visual studio builds to find "SuperController_Types.h" - '-I../../../modules/openfoam/src', ... % needed for visual studio builds to find "OpenFOAM_Types.h" - '-outdir', outDir, ... - ['COMPFLAGS=$COMPFLAGS -MT -DS_FUNCTION_NAME=' mexname], ... - '-output', mexname, ... - 'FAST_SFunc.c'); +if ispc () % Windows PC + + mex('-largeArrayDims', ... + ... % '-v', ... %add this line for "verbose" output (for debugging) + ['-L' libDir], ... + ['-l' libName], ... + ['-I' includeDir], ... + '-I../../../modules/supercontroller/src', ... % needed for visual studio builds to find "SuperController_Types.h" + '-I../../../modules/openfoam/src', ... % needed for visual studio builds to find "OpenFOAM_Types.h" + '-outdir', outDir, ... + ['COMPFLAGS=$COMPFLAGS -MT -DS_FUNCTION_NAME=' mexname], ... + '-output', mexname, ... + 'FAST_SFunc.c'); + +else % mac/unix + + mex('-largeArrayDims', ... + ... '-v', ... %add this line for "verbose" output (for debugging) + ['-L', libDir], ... + ['-l', libName], ... + '-lgfortran', ... + '-lquadmath', ... + '-llapack', ... + '-lblas', ... + '-ldl', ... + ['-I', includeDir], ... + '-outdir', outDir, ... + ['CFLAGS=$CFLAGS -DS_FUNCTION_NAME=' mexname], ... + ... ['CXXFLAGS=$CXXFLAGS -DS_FUNCTION_NAME=' mexname], ... + '-output', mexname, ... + 'FAST_SFunc.c'); + +end diff --git a/modules/aerodyn/CMakeLists.txt b/modules/aerodyn/CMakeLists.txt index 77ca78776..0248f647e 100644 --- a/modules/aerodyn/CMakeLists.txt +++ b/modules/aerodyn/CMakeLists.txt @@ -15,9 +15,10 @@ # if (GENERATE_TYPES) - generate_f90_types(src/AeroAcoustics_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/AeroAcoustics_Types.f90) + generate_f90_types(src/AeroAcoustics_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/AeroAcoustics_Types.f90 -noextrap) generate_f90_types(src/AeroDyn_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/AeroDyn_Types.f90) - generate_f90_types(src/AirfoilInfo_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/AirfoilInfo_Types.f90) + generate_f90_types(src/AeroDyn_Inflow_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/AeroDyn_Inflow_Types.f90 -noextrap) + generate_f90_types(src/AirfoilInfo_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/AirfoilInfo_Types.f90 -noextrap) generate_f90_types(src/BEMT_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/BEMT_Types.f90) generate_f90_types(src/DBEMT_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/DBEMT_Types.f90) generate_f90_types(src/UnsteadyAero_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/UnsteadyAero_Types.f90) @@ -25,18 +26,10 @@ if (GENERATE_TYPES) generate_f90_types(src/FVW_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/FVW_Types.f90) endif() - -# AeroAcoustics - Main -set(AEROACOUSTIC_SOURCES - src/AeroAcoustics_TNO.f90 - src/AeroAcoustics.f90 - src/AeroAcoustics_IO.f90 - src/AeroAcoustics_Types.f90 -) - -# AeroDyn lib -set(AD_LIBS_SOURCES +# AeroDyn Library +add_library(aerodynlib src/AeroDyn.f90 + src/AeroDyn_IO_Params.f90 src/AeroDyn_IO.f90 src/AeroDyn_AllBldNdOuts_IO.f90 src/BEMT.f90 @@ -46,22 +39,22 @@ set(AD_LIBS_SOURCES src/AeroDyn_Types.f90 src/BEMT_Types.f90 src/DBEMT_Types.f90 -) -# UnsteadyAero lib -set(UA_LIBS_SOURCES + # AeroAcoustics - Main + src/AeroAcoustics_TNO.f90 + src/AeroAcoustics.f90 + src/AeroAcoustics_IO.f90 + src/AeroAcoustics_Types.f90 + + # UnsteadyAero lib src/UnsteadyAero.f90 src/UnsteadyAero_Types.f90 -) -# AirFoil Info lib -set(AFINFO_LIBS_SOURCES + # AirFoil Info lib src/AirfoilInfo.f90 src/AirfoilInfo_Types.f90 -) -# FVW lib -set(FVW_LIBS_SOURCES + # FVW lib src/FVW.f90 src/FVW_IO.f90 src/FVW_VortexTools.f90 @@ -70,49 +63,45 @@ set(FVW_LIBS_SOURCES src/FVW_BiotSavart.f90 src/FVW_Tests.f90 src/FVW_Types.f90 - src/FVW_VTK.f90 -) - -# UnsteadyAero lib -add_library(uaaerolib ${UA_LIBS_SOURCES}) -target_link_libraries(uaaerolib afinfolib nwtclibs) - -# AirfoilInfo lib -add_library(afinfolib ${AFINFO_LIBS_SOURCES}) -target_link_libraries(afinfolib nwtclibs) - -# this lib is only for the ctest -add_library(fvwlib ${FVW_LIBS_SOURCES}) -target_link_libraries(fvwlib uaaerolib afinfolib nwtclibs) -# Aero acoustics -add_library(aeroacoustics ${AEROACOUSTIC_SOURCES}) -target_link_libraries(aeroacoustics afinfolib nwtclibs) - -add_library(aerodynlib ${AD_LIBS_SOURCES}) -target_link_libraries(aerodynlib fvwlib uaaerolib afinfolib nwtclibs aeroacoustics) + # ADI lib + src/AeroDyn_Inflow.f90 + src/AeroDyn_Inflow_Types.f90 +) +target_link_libraries(aerodynlib ifwlib nwtclibs) -# AeroDyn driver -set(AD_DRIVER_SOURCES - src/AeroDyn_Driver.f90 +# AeroDyn Driver Subs Library +add_library(aerodyn_driver_subs src/AeroDyn_Driver_Subs.f90 src/AeroDyn_Driver_Types.f90 ) +target_link_libraries(aerodyn_driver_subs aerodynlib versioninfolib) -add_executable(aerodyn_driver ${AD_DRIVER_SOURCES}) -target_link_libraries(aerodyn_driver ifwlib aerodynlib fvwlib uaaerolib afinfolib nwtclibs versioninfolib aeroacoustics ${CMAKE_DL_LIBS}) - +# AeroDyn Driver +add_executable(aerodyn_driver + src/AeroDyn_Driver.f90 +) +target_link_libraries(aerodyn_driver aerodyn_driver_subs) -# UnsteadyAero driver -set(UA_DRIVER_SOURCES +# UnsteadyAero Driver +add_executable(unsteadyaero_driver src/UnsteadyAero_Driver.f90 src/UA_Dvr_Subs.f90 ) -add_executable(unsteadyaero_driver ${UA_DRIVER_SOURCES}) -target_link_libraries(unsteadyaero_driver aerodynlib fvwlib uaaerolib afinfolib nwtclibs versioninfolib ${CMAKE_DL_LIBS}) +target_link_libraries(unsteadyaero_driver aerodyn_driver_subs) -install(TARGETS unsteadyaero_driver aerodyn_driver aerodynlib fvwlib uaaerolib afinfolib aeroacoustics +# AeroDyn-InflowWind c-bindings interface library +add_library(aerodyn_inflow_c_binding SHARED + src/AeroDyn_Inflow_C_Binding.f90 +) +target_link_libraries(aerodyn_inflow_c_binding aerodyn_driver_subs versioninfolib) +if(APPLE OR UNIX) + target_compile_definitions(aerodyn_inflow_c_binding PRIVATE IMPLICIT_DLLEXPORT) +endif() + +install(TARGETS aerodynlib aerodyn_driver_subs aerodyn_driver unsteadyaero_driver aerodyn_inflow_c_binding EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) + ARCHIVE DESTINATION lib +) diff --git a/modules/aerodyn/python-lib/aerodyn_inflow_library.py b/modules/aerodyn/python-lib/aerodyn_inflow_library.py new file mode 100644 index 000000000..508d42c47 --- /dev/null +++ b/modules/aerodyn/python-lib/aerodyn_inflow_library.py @@ -0,0 +1,970 @@ +#********************************************************************************************************************************** +# LICENSING +# Copyright (C) 2021 National Renewable Energy Laboratory +# +# This file is part of InflowWind. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#********************************************************************************************************************************** +# +# This is the Python-C interface library for AeroDyn with InflowWind. This may +# be used directly with Python based codes to call and run AeroDyn and +# InflowWind together. An example of using this library from Python is given +# in the accompanying Python driver program. Additional notes and information +# on the interfacing is included there. +# +# +from ctypes import ( + CDLL, + POINTER, + create_string_buffer, + byref, + c_byte, + c_int, + c_double, + c_float, + c_char, + c_char_p, + c_wchar, + c_wchar_p, + c_bool +) +import numpy as np +import datetime + +class AeroDynInflowLib(CDLL): + # Human readable error levels from IfW. + error_levels = { + 0: "None", + 1: "Info", + 2: "Warning", + 3: "Severe Error", + 4: "Fatal Error" + } + + # NOTE: the error message length in Fortran is controlled by the + # ErrMsgLen variable in the NWTC_Base.f90 file. If that ever + # changes, it may be necessary to update the corresponding size + # here. + error_msg_c_len = 1025 + + # NOTE: the length of the name used for any output file written by the + # HD Fortran code is 1025. + default_str_c_len = 1025 + + def __init__(self, library_path): + super().__init__(library_path) + self.library_path = library_path + + self._initialize_routines() + self.ended = False # For error handling at end + + # Input file handling + self.ADinputPass = True # Assume passing of input file as a string + self.IfWinputPass = True # Assume passing of input file as a string + + # Create buffers for class data + self.abort_error_level = 4 + self.error_status_c = c_int(0) + self.error_message_c = create_string_buffer(self.error_msg_c_len) + + # This is not sufficient for AD + #FIXME: ChanLen may not always be 20 -- could be as much as 256 + # Possible fix is to pass this length over to Fortran side. + # Also may want to convert this at some point to C_NULL_CHAR + # delimeter instead of fixed width. Future problem though. + # Number of channel names may exceeed 5000 + self._channel_names_c = create_string_buffer(20 * 8000) + self._channel_units_c = create_string_buffer(20 * 8000) + + # Initial environmental conditions + #self.MHK = false # MHK turbine type switch -- disabled for now + self.gravity = 9.80665 # Gravitational acceleration (m/s^2) + self.defFldDens = 1.225 # Air density (kg/m^3) + self.defKinVisc = 1.464E-05 # Kinematic viscosity of working fluid (m^2/s) + self.defSpdSound = 335.0 # Speed of sound in working fluid (m/s) + self.defPatm = 103500.0 # Atmospheric pressure (Pa) [used only for an MHK turbine cavitation check] + self.defPvap = 1700.0 # Vapour pressure of working fluid (Pa) [used only for an MHK turbine cavitation check] + self.WtrDpth = 0.0 # Water depth (m) + self.MSL2SWL = 0.0 # Offset between still-water level and mean sea level (m) [positive upward] + + # flags + self.storeHHVel = False + self.transposeDCM= False + + # VTK + self.WrVTK = 0 # default of no vtk output + self.WrVTK_Type = 1 # default of surface meshes + self.VTKNacDim = np.array([-2.5,-2.5,0,10,5,5], dtype="float32") # default nacelle dimension for VTK surface rendering [x0,y0,z0,Lx,Ly,Lz] (m) + self.VTKHubRad = 1.5 # default hub radius for VTK surface rendering + + # Output file + self.wrOuts = 0 # wrOuts -- file format for writing outputs + self.DT_Outs = 0.0 # DT_Outs -- timestep for outputs to file + + # Interpolation order (must be 1: linear, or 2: quadratic) + self.InterpOrder = 1 # default of linear interpolation + + # Initial time related variables + self.dt = 0.1 # typical default for HD + self.tmax = 600.0 # typical default for HD waves FFT + #FIXME: check tmax/total_time and note exactly what is different between them. + self.total_time = 0.0 # may be longer than tmax + self.numTimeSteps= 0 + + # number of output channels + self.numChannels = 0 # Number of channels returned + + # Aero calculation method -- AeroProjMod + # APM_BEM_NoSweepPitchTwist - 1 - "Original AeroDyn model where momentum balance is done in the WithoutSweepPitchTwist system" + # APM_BEM_Polar - 2 - "Use staggered polar grid for momentum balance in each annulus" + # APM_LiftingLine - 3 - "Use the blade lifting line (i.e. the structural) orientation (currently for OLAF with VAWT)" + self.AeroProjMod = 1 + + # Initial position of hub and blades + # used for setup of AD, not used after init. + self.initHubPos = np.zeros(shape=(3),dtype=c_float) + self.initHubOrient = np.zeros(shape=(9),dtype=c_double) + self.initNacellePos = np.zeros(shape=(3),dtype=c_float) + self.initNacelleOrient = np.zeros(shape=(9),dtype=c_double) + self.numBlades = 3 + self.initRootPos = np.zeros(shape=(self.numBlades,3),dtype=c_float) + self.initRootOrient = np.zeros(shape=(self.numBlades,9),dtype=c_double) + + # Structural Mesh + # The number of nodes must be constant throughout simulation. The + # initial position is given in the initMeshPos array (resize as + # needed, should be Nx6). + # Rotations are given in radians assuming small angles. See note at + # top of this file. + self.numMeshPts = 1 + self.initMeshPos = np.zeros(shape=(self.numMeshPts,3),dtype=c_float ) # Nx3 array [x,y,z] + self.initMeshOrient = np.zeros(shape=(self.numMeshPts,9),dtype=c_double) # Nx9 array [r11,r12,r13,r21,r22,r23,r31,r32,r33] + + # OutRootName + # If HD writes a file (echo, summary, or other), use this for the + # root of the file name. + self.outRootName = "Output_ADIlib_default" + + # _initialize_routines() ------------------------------------------------------------------------------------------------------------ + def _initialize_routines(self): + self.AeroDyn_Inflow_C_Init.argtypes = [ + POINTER(c_bool), # AD input file passed as string + POINTER(c_char_p), # AD input file as string + POINTER(c_int), # AD input file string length + POINTER(c_bool), # IfW input file passed as string + POINTER(c_char_p), # IfW input file as string + POINTER(c_int), # IfW input file string length + POINTER(c_char), # OutRootName + POINTER(c_float), # gravity + POINTER(c_float), # defFldDens + POINTER(c_float), # defKinVisc + POINTER(c_float), # defSpdSound + POINTER(c_float), # defPatm + POINTER(c_float), # defPvap + POINTER(c_float), # WtrDpth + POINTER(c_float), # MSL2SWL + POINTER(c_int), # AeroProjMod + POINTER(c_int), # InterpOrder + POINTER(c_double), # dt + POINTER(c_double), # tmax + POINTER(c_bool), # storeHHVel + POINTER(c_bool), # transposeDCM + POINTER(c_int), # WrVTK + POINTER(c_int), # WrVTK_Type + POINTER(c_float), # VTKNacDim + POINTER(c_float), # VTKHubRad + POINTER(c_int), # wrOuts -- file format for writing outputs + POINTER(c_double), # DT_Outs -- timestep for outputs to file + POINTER(c_float), # initHubPos + POINTER(c_double), # initHubOrient_flat + POINTER(c_float), # initNacellePos + POINTER(c_double), # initNacelleOrient_flat + POINTER(c_int), # numBlades + POINTER(c_float), # initRootPos_flat + POINTER(c_double), # initRootOrient_flat + POINTER(c_int), # numMeshPts + POINTER(c_float), # initMeshPos_flat + POINTER(c_double), # initMeshOrient_flat + POINTER(c_int), # number of channels + POINTER(c_char), # output channel names + POINTER(c_char), # output channel units + POINTER(c_int), # ErrStat_C + POINTER(c_char) # ErrMsg_C + ] + self.AeroDyn_Inflow_C_Init.restype = c_int + + #self.AeroDyn_Inflow_C_ReInit.argtypes = [ + # POINTER(c_double), # t_initial + # POINTER(c_double), # dt + # POINTER(c_double), # tmax + # POINTER(c_int), # ErrStat_C + # POINTER(c_char) # ErrMsg_C + #] + #self.AeroDyn_Inflow_C_ReInit.restype = c_int + + self.AeroDyn_Inflow_C_CalcOutput.argtypes = [ + POINTER(c_double), # Time_C + POINTER(c_float), # HubPos + POINTER(c_double), # HubOrient_flat + POINTER(c_float), # HubVel + POINTER(c_float), # HubAcc + POINTER(c_float), # NacPos + POINTER(c_double), # NacOrient_flat + POINTER(c_float), # NacVel + POINTER(c_float), # NacAcc + POINTER(c_float), # RootPos + POINTER(c_double), # RootOrient_flat + POINTER(c_float), # RootVel + POINTER(c_float), # RootAcc + POINTER(c_int), # numMeshPts + POINTER(c_float), # MeshPos + POINTER(c_double), # MeshOrient_flat + POINTER(c_float), # MeshVel + POINTER(c_float), # MeshAcc + POINTER(c_float), # meshFrc -- mesh forces/moments in flat array of 6*numMeshPts + POINTER(c_float), # Output Channel Values + POINTER(c_int), # ErrStat_C + POINTER(c_char) # ErrMsg_C + ] + self.AeroDyn_Inflow_C_CalcOutput.restype = c_int + + self.AeroDyn_Inflow_C_UpdateStates.argtypes = [ + POINTER(c_double), # Time_C + POINTER(c_double), # TimeNext_C + POINTER(c_float), # HubPos + POINTER(c_double), # HubOrient_flat + POINTER(c_float), # HubVel + POINTER(c_float), # HubAcc + POINTER(c_float), # NacPos + POINTER(c_double), # NacOrient_flat + POINTER(c_float), # NacVel + POINTER(c_float), # NacAcc + POINTER(c_float), # RootPos + POINTER(c_double), # RootOrient_flat + POINTER(c_float), # RootVel + POINTER(c_float), # RootAcc + POINTER(c_int), # numMeshPts + POINTER(c_float), # MeshPos + POINTER(c_double), # MeshOrient_flat + POINTER(c_float), # MeshVel + POINTER(c_float), # MeshAcc + POINTER(c_int), # ErrStat_C + POINTER(c_char) # ErrMsg_C + ] + self.AeroDyn_Inflow_C_UpdateStates.restype = c_int + + self.AeroDyn_Inflow_C_End.argtypes = [ + POINTER(c_int), # ErrStat_C + POINTER(c_char) # ErrMsg_C + ] + self.AeroDyn_Inflow_C_End.restype = c_int + + # aerodyn_inflow_init ------------------------------------------------------------------------------------------------------------ + def aerodyn_inflow_init(self, AD_input_string_array, IfW_input_string_array): + # some bookkeeping initialization + self._numChannels_c = c_int(0) + self._initNumMeshPts = self.numMeshPts + self._initNumBlades = self.numBlades + + # Primary input file will be passed as a single string joined by + # C_NULL_CHAR. + AD_input_string = '\x00'.join(AD_input_string_array) + AD_input_string = AD_input_string.encode('utf-8') + AD_input_string_length = len(AD_input_string) + + # Primary input file will be passed as a single string joined by + # C_NULL_CHAR. + IfW_input_string = '\x00'.join(IfW_input_string_array) + IfW_input_string = IfW_input_string.encode('utf-8') + IfW_input_string_length = len(IfW_input_string) + + # Rootname for ADI output files (echo etc). + _outRootName_c = create_string_buffer((self.outRootName.ljust(self.default_str_c_len)).encode('utf-8')) + + # check hub and root points for initialization + self.check_init_hubroot() + + # Check initial mesh positions + self.check_init_mesh() + + # Flatten arrays to pass + # [x2,y1,z1, x2,y2,z2 ...] + VTKNacDim_c = (c_float * len(self.VTKNacDim ))(*self.VTKNacDim ) + initHubPos_c = (c_float * len(self.initHubPos ))(*self.initHubPos ) + initHubOrient_c = (c_double * len(self.initHubOrient ))(*self.initHubOrient ) + initNacellePos_c = (c_float * len(self.initNacellePos ))(*self.initNacellePos ) + initNacelleOrient_c = (c_double * len(self.initNacelleOrient))(*self.initNacelleOrient) + initRootPos_flat_c = self.flatPosArr( self._initNumBlades, self.numBlades,self.initRootPos, 'Init','RootPos') + initRootOrient_flat_c = self.flatOrientArr(self._initNumBlades, self.numBlades,self.initRootOrient, 'Init','RootOrient') + initMeshPos_flat_c = self.flatPosArr( self._initNumMeshPts,self.numMeshPts,self.initMeshPos, 'Init','MeshPos') + initMeshOrient_flat_c = self.flatOrientArr(self._initNumMeshPts,self.numMeshPts,self.initMeshOrient,'Init','MeshOrient') + + + # call AeroDyn_Inflow_C_Init + self.AeroDyn_Inflow_C_Init( + byref(c_bool(self.ADinputPass)), # IN: AD input file is passed + c_char_p(AD_input_string), # IN: AD input file as string (or filename if ADinputPass is false) + byref(c_int(AD_input_string_length)), # IN: AD input file string length + byref(c_bool(self.IfWinputPass)), # IN: IfW input file is passed + c_char_p(IfW_input_string), # IN: IfW input file as string (or filename if IfWinputPass is false) + byref(c_int(IfW_input_string_length)), # IN: IfW input file string length + _outRootName_c, # IN: rootname for ADI file writing + byref(c_float(self.gravity)), # IN: gravity + byref(c_float(self.defFldDens)), # IN: defFldDens + byref(c_float(self.defKinVisc)), # IN: defKinVisc + byref(c_float(self.defSpdSound)), # IN: defSpdSound + byref(c_float(self.defPatm)), # IN: defPatm + byref(c_float(self.defPvap)), # IN: defPvap + byref(c_float(self.WtrDpth)), # IN: WtrDpth + byref(c_float(self.MSL2SWL)), # IN: MSL2SWL + byref(c_int(self.AeroProjMod)), # IN: AeroProjMod + byref(c_int(self.InterpOrder)), # IN: InterpOrder (1: linear, 2: quadratic) + byref(c_double(self.dt)), # IN: time step (dt) + byref(c_double(self.tmax)), # IN: tmax + byref(c_bool(self.storeHHVel)), # IN: storeHHVel + byref(c_bool(self.transposeDCM)), # IN: transposeDCM + byref(c_int(self.WrVTK)), # IN: WrVTK + byref(c_int(self.WrVTK_Type)), # IN: WrVTK_Type + VTKNacDim_c, # IN: VTKNacDim + byref(c_float(self.VTKHubRad)), # IN: VTKHubRad + byref(c_int(self.wrOuts)), # IN: wrOuts -- file format for writing outputs + byref(c_double(self.DT_Outs)), # IN: DT_Outs -- timestep for outputs to file + initHubPos_c, # IN: initHubPos -- initial hub position + initHubOrient_c, # IN: initHubOrient -- initial hub orientation DCM in flat array of 9 elements + initNacellePos_c, # IN: initNacellePos -- initial hub position + initNacelleOrient_c, # IN: initNacelleOrient -- initial hub orientation DCM in flat array of 9 elements + byref(c_int(self.numBlades)), # IN: number of blades (matches number of blade root positions) + initRootPos_flat_c, # IN: initBladeRootPos -- initial node positions in flat array of 3*numBlades + initRootOrient_flat_c, # IN: initBladeRootOrient -- initial blade root orientation DCMs in flat array of 9*numBlades + byref(c_int(self.numMeshPts)), # IN: number of attachment points expected (where motions are transferred into HD) + initMeshPos_flat_c, # IN: initMeshPos -- initial node positions in flat array of 3*numMeshPts + initMeshOrient_flat_c, # IN: initMeshOrient -- initial node orientation DCMs in flat array of 9*numMeshPts + byref(self._numChannels_c), # OUT: number of channels + self._channel_names_c, # OUT: output channel names + self._channel_units_c, # OUT: output channel units + byref(self.error_status_c), # OUT: ErrStat_C + self.error_message_c # OUT: ErrMsg_C + ) + + self.check_error() + + # Initialize output channels + self.numChannels = self._numChannels_c.value + + + ## aerodyn_inflow_reinit ------------------------------------------------------------------------------------------------------------ + #def aerodyn_inflow_reinit(self): + # #FIXME: need to pass something in here I think. Not sure what. + # + # # call AeroDyn_Inflow_C_ReInit + # self.AeroDyn_Inflow_C_ReInit( + # byref(c_double(self.dt)), # IN: time step (dt) + # byref(c_double(self.tmax)), # IN: tmax + # byref(self.error_status_c), # OUT: ErrStat_C + # self.error_message_c # OUT: ErrMsg_C + # ) + # + # self.check_error() + # #FIXME: anything coming out that needs handling/passing? + + + # aerodyn_inflow_calcOutput ------------------------------------------------------------------------------------------------------------ + def aerodyn_inflow_calcOutput(self, time, hubPos, hubOrient, hubVel, hubAcc, \ + nacPos, nacOrient, nacVel, nacAcc, \ + rootPos, rootOrient, rootVel, rootAcc, \ + meshPos, meshOrient, meshVel, meshAcc, \ + meshFrcMom, outputChannelValues): + + # Check input motion info + self.check_input_motions_hubNac(hubPos,hubOrient,hubVel,hubAcc,'hub') + self.check_input_motions_hubNac(nacPos,nacOrient,nacVel,nacAcc,'nacelle') + self.check_input_motions_root(rootPos,rootOrient,rootVel,rootAcc) + self.check_input_motions_mesh(meshPos,meshOrient,meshVel,meshAcc) + + _hubPos_c = (c_float * len(np.squeeze(hubPos) ))(*np.squeeze(hubPos) ) + _hubOrient_c = (c_double * len(np.squeeze(hubOrient)))(*np.squeeze(hubOrient)) + _hubVel_c = (c_float * len(np.squeeze(hubVel) ))(*np.squeeze(hubVel) ) + _hubAcc_c = (c_float * len(np.squeeze(hubAcc) ))(*np.squeeze(hubAcc) ) + _nacPos_c = (c_float * len(np.squeeze(nacPos) ))(*np.squeeze(nacPos) ) + _nacOrient_c = (c_double * len(np.squeeze(nacOrient)))(*np.squeeze(nacOrient)) + _nacVel_c = (c_float * len(np.squeeze(nacVel) ))(*np.squeeze(nacVel) ) + _nacAcc_c = (c_float * len(np.squeeze(nacAcc) ))(*np.squeeze(nacAcc) ) + # Make a flat 1D arrays of motion info: + # [x2,y1,z1, x2,y2,z2 ...] + _rootPos_flat_c = self.flatPosArr( self._initNumBlades,self.numBlades,rootPos, time,'MeshPos') + _rootOrient_flat_c = self.flatOrientArr(self._initNumBlades,self.numBlades,rootOrient,time,'MeshOrient') + _rootVel_flat_c = self.flatVelAccArr(self._initNumBlades,self.numBlades,rootVel, time,'MeshVel') + _rootAcc_flat_c = self.flatVelAccArr(self._initNumBlades,self.numBlades,rootAcc, time,'MeshAcc') + # Make a flat 1D arrays of motion info: + # [x2,y1,z1, x2,y2,z2 ...] + _meshPos_flat_c = self.flatPosArr( self._initNumMeshPts,self.numMeshPts,meshPos, time,'MeshPos') + _meshOrient_flat_c = self.flatOrientArr(self._initNumMeshPts,self.numMeshPts,meshOrient,time,'MeshOrient') + _meshVel_flat_c = self.flatVelAccArr(self._initNumMeshPts,self.numMeshPts,meshVel, time,'MeshVel') + _meshAcc_flat_c = self.flatVelAccArr(self._initNumMeshPts,self.numMeshPts,meshAcc, time,'MeshAcc') + + # Resulting Forces/moments -- [Fx1,Fy1,Fz1,Mx1,My1,Mz1, Fx2,Fy2,Fz2,Mx2,My2,Mz2 ...] + _meshFrc_flat_c = (c_float * (6 * self.numMeshPts))(0.0,) + + # Set up output channels + outputChannelValues_c = (c_float * self.numChannels)(0.0,) + + # Run AeroDyn_Inflow_C_CalcOutput + self.AeroDyn_Inflow_C_CalcOutput( + byref(c_double(time)), # IN: time at which to calculate output forces + _hubPos_c, # IN: hub positions + _hubOrient_c, # IN: hub orientations + _hubVel_c, # IN: hub velocity [TVx,TVy,TVz,RVx,RVy,RVz] + _hubAcc_c, # IN: hub acclerations [TAx,TAy,TAz,RAx,RAy,RAz] + _nacPos_c, # IN: nac positions + _nacOrient_c, # IN: nac orientations + _nacVel_c, # IN: nac velocity [TVx,TVy,TVz,RVx,RVy,RVz] + _nacAcc_c, # IN: nac acclerations [TAx,TAy,TAz,RAx,RAy,RAz] + _rootPos_flat_c, # IN: positions + _rootOrient_flat_c, # IN: Orientations (DCM) + _rootVel_flat_c, # IN: velocities at desired positions + _rootAcc_flat_c, # IN: accelerations at desired positions + byref(c_int(self.numMeshPts)), # IN: number of attachment points expected (where motions are transferred into HD) + _meshPos_flat_c, # IN: positions + _meshOrient_flat_c, # IN: Orientations (DCM) + _meshVel_flat_c, # IN: velocities at desired positions + _meshAcc_flat_c, # IN: accelerations at desired positions + _meshFrc_flat_c, # OUT: resulting forces/moments array + outputChannelValues_c, # OUT: output channel values as described in input file + byref(self.error_status_c), # OUT: ErrStat_C + self.error_message_c # OUT: ErrMsg_C + ) + + self.check_error() + + ## Reshape Force/Moment into [N,6] + count = 0 + for j in range(0,self.numMeshPts): + meshFrcMom[j,0] = _meshFrc_flat_c[count] + meshFrcMom[j,1] = _meshFrc_flat_c[count+1] + meshFrcMom[j,2] = _meshFrc_flat_c[count+2] + meshFrcMom[j,3] = _meshFrc_flat_c[count+3] + meshFrcMom[j,4] = _meshFrc_flat_c[count+4] + meshFrcMom[j,5] = _meshFrc_flat_c[count+5] + count = count + 6 + + # Convert output channel values back into python + for k in range(0,self.numChannels): + outputChannelValues[k] = float(outputChannelValues_c[k]) + + # aerodyn_inflow_updateStates ------------------------------------------------------------------------------------------------------------ + def aerodyn_inflow_updateStates(self, time, timeNext, \ + hubPos, hubOrient, hubVel, hubAcc, \ + nacPos, nacOrient, nacVel, nacAcc, \ + rootPos, rootOrient, rootVel, rootAcc, \ + meshPos, meshOrient, meshVel, meshAcc): + + # Check input motion info + self.check_input_motions_hubNac(hubPos,hubOrient,hubVel,hubAcc,'hub') + self.check_input_motions_hubNac(nacPos,nacOrient,nacVel,nacAcc,'nacelle') + self.check_input_motions_root(rootPos,rootOrient,rootVel,rootAcc) + self.check_input_motions_mesh(meshPos,meshOrient,meshVel,meshAcc) + + _hubPos_c = (c_float * len(np.squeeze(hubPos) ))(*np.squeeze(hubPos) ) + _hubOrient_c = (c_double * len(np.squeeze(hubOrient)))(*np.squeeze(hubOrient)) + _hubVel_c = (c_float * len(np.squeeze(hubVel) ))(*np.squeeze(hubVel) ) + _hubAcc_c = (c_float * len(np.squeeze(hubAcc) ))(*np.squeeze(hubAcc) ) + _nacPos_c = (c_float * len(np.squeeze(nacPos) ))(*np.squeeze(nacPos) ) + _nacOrient_c = (c_double * len(np.squeeze(nacOrient)))(*np.squeeze(nacOrient)) + _nacVel_c = (c_float * len(np.squeeze(nacVel) ))(*np.squeeze(nacVel) ) + _nacAcc_c = (c_float * len(np.squeeze(nacAcc) ))(*np.squeeze(nacAcc) ) + # Make a flat 1D arrays of motion info: + # [x2,y1,z1, x2,y2,z2 ...] + _rootPos_flat_c = self.flatPosArr( self._initNumBlades,self.numBlades,rootPos, time,'MeshPos') + _rootOrient_flat_c = self.flatOrientArr(self._initNumBlades,self.numBlades,rootOrient,time,'MeshOrient') + _rootVel_flat_c = self.flatVelAccArr(self._initNumBlades,self.numBlades,rootVel, time,'MeshVel') + _rootAcc_flat_c = self.flatVelAccArr(self._initNumBlades,self.numBlades,rootAcc, time,'MeshAcc') + # Make a flat 1D arrays of motion info: + # [x2,y1,z1, x2,y2,z2 ...] + _meshPos_flat_c = self.flatPosArr( self._initNumMeshPts,self.numMeshPts,meshPos, time,'MeshPos') + _meshOrient_flat_c = self.flatOrientArr(self._initNumMeshPts,self.numMeshPts,meshOrient,time,'MeshOrient') + _meshVel_flat_c = self.flatVelAccArr(self._initNumMeshPts,self.numMeshPts,meshVel, time,'MeshVel') + _meshAcc_flat_c = self.flatVelAccArr(self._initNumMeshPts,self.numMeshPts,meshAcc, time,'MeshAcc') + + # Resulting Forces/moments -- [Fx1,Fy1,Fz1,Mx1,My1,Mz1, Fx2,Fy2,Fz2,Mx2,My2,Mz2 ...] + _meshFrc_flat_c = (c_float * (6 * self.numMeshPts))(0.0,) + + # Run AeroDyn_Inflow_UpdateStates_c + self.AeroDyn_Inflow_C_UpdateStates( + byref(c_double(time)), # IN: time at which to calculate output forces + byref(c_double(timeNext)), # IN: time T+dt we are stepping to + _hubPos_c, # IN: hub positions + _hubOrient_c, # IN: hub orientations + _hubVel_c, # IN: hub velocity [TVx,TVy,TVz,RVx,RVy,RVz] + _hubAcc_c, # IN: hub acclerations [TAx,TAy,TAz,RAx,RAy,RAz] + _nacPos_c, # IN: nac positions + _nacOrient_c, # IN: nac orientations + _nacVel_c, # IN: nac velocity [TVx,TVy,TVz,RVx,RVy,RVz] + _nacAcc_c, # IN: nac acclerations [TAx,TAy,TAz,RAx,RAy,RAz] + _rootPos_flat_c, # IN: positions + _rootOrient_flat_c, # IN: Orientations (DCM) + _rootVel_flat_c, # IN: velocities at desired positions + _rootAcc_flat_c, # IN: accelerations at desired positions + byref(c_int(self.numMeshPts)), # IN: number of attachment points expected (where motions are transferred into HD) + _meshPos_flat_c, # IN: positions + _meshOrient_flat_c, # IN: Orientations (DCM) + _meshVel_flat_c, # IN: velocities at desired positions + _meshAcc_flat_c, # IN: accelerations at desired positions + byref(self.error_status_c), # OUT: ErrStat_C + self.error_message_c # OUT: ErrMsg_C + ) + + self.check_error() + + # aerodyn_inflow_end ------------------------------------------------------------------------------------------------------------ + def aerodyn_inflow_end(self): + if not self.ended: + self.ended = True + # Run AeroDyn_Inflow_C_End + self.AeroDyn_Inflow_C_End( + byref(self.error_status_c), + self.error_message_c + ) + + self.check_error() + + # other functions ---------------------------------------------------------------------------------------------------------- + def check_error(self): + if self.error_status_c.value == 0: + return + elif self.error_status_c.value < self.abort_error_level: + print(f"AeroDyn/InflowWind error status: {self.error_levels[self.error_status_c.value]}: {self.error_message_c.value.decode('ascii')}") + else: + print(f"AeroDyn/InflowWind error status: {self.error_levels[self.error_status_c.value]}: {self.error_message_c.value.decode('ascii')}") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/InflowWind terminated prematurely.") + + + def flatPosArr(self,initNumMeshPts,numPts,MeshPosArr,time,name): + if initNumMeshPts != numPts: + print(f"At time {time}, the number of {name} points changed from initial value of {initNumMeshPts}. This is not permitted during the simulation.") + self.aerodyn_inflow_end() + raise Exception("\nError in calling AeroDyn/InflowWind library.") + meshPos_flat = [pp for p in MeshPosArr for pp in p] + meshPos_flat_c = (c_float * (3 * numPts))(0.0,) + for i, p in enumerate(meshPos_flat): + meshPos_flat_c[i] = c_float(p) + return meshPos_flat_c + + + def flatOrientArr(self,initNumMeshPts,numPts,MeshOrientArr,time,name): + if initNumMeshPts != numPts: + print(f"At time {time}, the number of {name} points changed from initial value of {initNumMeshPts}. This is not permitted during the simulation.") + self.aerodyn_inflow_end() + raise Exception("\nError in calling AeroDyn/InflowWind library.") + meshOrient_flat = [pp for p in MeshOrientArr for pp in p] + meshOrient_flat_c = (c_double * (9 * numPts))(0.0,) + for i, p in enumerate(meshOrient_flat): + meshOrient_flat_c[i] = c_double(p) + return meshOrient_flat_c + + + def flatVelAccArr(self,initNumMeshPts,numPts,MeshArr,time,name): + if initNumMeshPts != numPts: + print(f"At time {time}, the number of {name} points changed from initial value of {initNumMeshPts}. This is not permitted during the simulation.") + self.aerodyn_inflow_end() + raise Exception("\nError in calling AeroDyn/InflowWind library.") + # Velocity -- [Vx2,Vy1,Vz1,RVx1,RVy1,RVz1, Vx2,Vy2,Vz2,RVx2,RVy2,RVz2 ...] + meshVel_flat = [pp for p in MeshArr for pp in p] + meshVel_flat_c = (c_float * (6 * self.numMeshPts))(0.0,) + for i, p in enumerate(meshVel_flat): + meshVel_flat_c[i] = c_float(p) + return meshVel_flat_c + + + def check_init_hubroot(self): + #print("shape of initRootPos ", self.initRootPos.shape) + #print(" ndim ", np.squeeze(self.initRootPos.ndim)) + #print(" size 0 ", self.initRootPos.shape[0]) + #print(" size 1 ", self.initRootPos.shape[1]) + #print("shape of initRootOrient ", self.initRootOrient.shape) + #print(" ndim ", np.squeeze(self.initRootPos.ndim)) + #print(" size 0 ", self.initRootOrient.shape[0]) + #print(" size 1 ", self.initRootOrient.shape[1]) + #print(" float ", type(self.initRootOrient[0,0])) + #print("shape of initHubPos ", self.initHubPos.shape) + #print(" ndim ", np.squeeze(self.initHubPos.ndim)) + #print(" size 0 ", self.initHubPos.shape[0]) + #print("shape of initHubOrient ", self.initHubOrient.shape) + #print(" ndim ", np.squeeze(self.initHubOrient.ndim)) + #print(" size 0 ", self.initHubOrient.shape[0]) + #print("shape of initNacellePos ", self.initNacellePos.shape) + #print(" ndim ", np.squeeze(self.initNacellePos.ndim)) + #print(" size 0 ", self.initNacellePos.shape[0]) + #print("shape of initNacelleOrient ", self.initNacelleOrient.shape) + #print(" ndim ", np.squeeze(self.initNacelleOrient.ndim)) + #print(" size 0 ", self.initNacelleOrient.shape[0]) + if self.numBlades < 1: + print("No blades. Set numBlades to number of AD blades in the model") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + if self.initRootPos.shape[1] != 3: + print("Expecting a Nx3 array of blade root positions (initRootPos) with second index for [x,y,z]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + if self.initRootPos.shape[0] != self.numBlades: + print("Expecting a Nx3 array of blade root positions (initRootPos) with first index for blade number") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + if self.initRootOrient.shape[1] != 9: + print("Expecting a Nx9 array of blade root orientations as DCMs (initRootOrient) with second index for [r11,r12,r13,r21,r22,r23,r31,r32,r33]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + if self.initRootOrient.shape[0] != self.numBlades: + print("Expecting a Nx3 array of blade root orientations (initRootOrient) with first index for blade number") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + if np.squeeze(self.initHubPos.ndim) > 1 or self.initHubPos.shape[0] != 3: + print("Expecting a 3 element array for initHubPos [x,y,z]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + if np.squeeze(self.initHubOrient.ndim) > 1 or self.initHubOrient.shape[0] != 9: + print("Expecting a 9 element array for initHubOrient DCM [r11,r12,r13,r21,r22,r23,r31,r32,r33]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + if np.squeeze(self.initNacellePos.ndim) > 1 or self.initNacellePos.shape[0] != 3: + print("Expecting a 3 element array for initNacellePos [x,y,z]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + if np.squeeze(self.initNacelleOrient.ndim) > 1 or self.initNacelleOrient.shape[0] != 9: + print("Expecting a 9 element array for initNacelleOrient DCM [r11,r12,r13,r21,r22,r23,r31,r32,r33]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + + + def check_init_mesh(self): + #print("shape of initMeshPos ", self.initMeshPos.shape) + #print(" size 0 ", self.initMeshPos.shape[0]) + #print(" size 1 ", self.initMeshPos.shape[1]) + #print("shape of initMeshOrient ", self.initMeshOrient.shape) + #print(" size 0 ", self.initMeshOrient.shape[0]) + #print(" size 1 ", self.initMeshOrient.shape[1]) + #print(" float ", type(self.initMeshOrient[0,0])) + # initMeshPos + # Verify that the shape of initMeshPos is correct + if self.initMeshPos.shape[0] != self.initMeshOrient.shape[0]: + print("Different number of meshs in inital position and orientation arrays") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + if self.initMeshPos.shape[1] != 3: + print("Expecting a Nx3 array of initial mesh positions (initMeshPos) with second index for [x,y,z]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + if self.initMeshPos.shape[0] != self.numMeshPts: + print("Expecting a Nx3 array of initial mesh positions (initMeshPos) with first index for mesh number.") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + if self.initMeshOrient.shape[1] != 9: + print("Expecting a Nx9 array of initial mesh orientations as DCMs (initMeshOrient) with second index for [r11,r12,r13,r21,r22,r23,r31,r32,r33]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + if self.initMeshOrient.shape[0] != self.numMeshPts: + print("Expecting a Nx3 array of initial mesh orientations (initMeshOrient) with first index for mesh number.") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn terminated prematurely.") + + + def check_input_motions_hubNac(self,nodePos,nodeOrient,nodeVel,nodeAcc,_name): + # Verify that the shape of positions array is correct + if nodePos.size != 3: + print("Expecting a Nx3 array of "+_name+" positions with second index for [x,y,z]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + + # Verify that the shape of orientations array is correct + if nodeOrient.size != 9: + print("Expecting a Nx9 array of "+_name+" orientations with second index for [r11,r12,r13,r21,r22,r23,r31,r32,r33]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + + # Verify that the shape of velocities array is correct + if nodeVel.size != 6: + print("Expecting a Nx6 array of "+_name+" velocities with second index for [x,y,z,Rx,Ry,Rz]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + + # Verify that the shape of accelerations array is correct + if nodeAcc.size != 6: + print("Expecting a Nx6 array of "+_name+" accelerations with second index for [x,y,z,Rx,Ry,Rz]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + + def check_input_motions_root(self,rootPos,rootOrient,rootVel,rootAcc): + # make sure number of roots didn't change for some reason + if self._initNumBlades != self.numBlades: + print(f"At time {time}, the number of root points changed from initial value of {self._initNumBlades}. This is not permitted during the simulation.") + self.aerodyn_inflow_end() + raise Exception("\nError in calling AeroDyn/AeroDyn library.") + + # Verify that the shape of positions array is correct + if rootPos.shape[1] != 3: + print("Expecting a Nx3 array of root positions (rootOrient) with second index for [x,y,z]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + if rootPos.shape[0] != self.numBlades: + print("Expecting a Nx3 array of root positions (rootOrient) with first index for root number.") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + + # Verify that the shape of orientations array is correct + if rootOrient.shape[1] != 9: + print("Expecting a Nx9 array of root orientations (rootPos) with second index for [r11,r12,r13,r21,r22,r23,r31,r32,r33]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + if rootOrient.shape[0] != self.numBlades: + print("Expecting a Nx9 array of root orientations (rootPos) with first index for root number.") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + + # Verify that the shape of velocities array is correct + if rootVel.shape[1] != 6: + print("Expecting a Nx6 array of root velocities (rootVel) with second index for [x,y,z,Rx,Ry,Rz]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + if rootVel.shape[0] != self.numBlades: + print("Expecting a Nx6 array of root velocities (rootVel) with first index for root number.") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + + # Verify that the shape of accelerations array is correct + if rootAcc.shape[1] != 6: + print("Expecting a Nx6 array of root accelerations (rootAcc) with second index for [x,y,z,Rx,Ry,Rz]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + if rootAcc.shape[0] != self.numBlades: + print("Expecting a Nx6 array of root accelerations (rootAcc) with first index for root number.") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + + + def check_input_motions_mesh(self,meshPos,meshOrient,meshVel,meshAcc): + # make sure number of meshs didn't change for some reason + if self._initNumMeshPts != self.numMeshPts: + print(f"At time {time}, the number of mesh points changed from initial value of {self._initNumMeshPts}. This is not permitted during the simulation.") + self.aerodyn_inflow_end() + raise Exception("\nError in calling AeroDyn/AeroDyn library.") + + # Verify that the shape of positions array is correct + if meshPos.shape[1] != 3: + print("Expecting a Nx3 array of mesh positions (meshOrient) with second index for [x,y,z]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + if meshPos.shape[0] != self.numMeshPts: + print("Expecting a Nx3 array of mesh positions (meshOrient) with first index for mesh number.") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + + # Verify that the shape of orientations array is correct + if meshOrient.shape[1] != 9: + print("Expecting a Nx9 array of mesh orientations (meshPos) with second index for [r11,r12,r13,r21,r22,r23,r31,r32,r33]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + if meshOrient.shape[0] != self.numMeshPts: + print("Expecting a Nx9 array of mesh orientations (meshPos) with first index for mesh number.") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + + # Verify that the shape of velocities array is correct + if meshVel.shape[1] != 6: + print("Expecting a Nx6 array of mesh velocities (meshVel) with second index for [x,y,z,Rx,Ry,Rz]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + if meshVel.shape[0] != self.numMeshPts: + print("Expecting a Nx6 array of mesh velocities (meshVel) with first index for mesh number.") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + + # Verify that the shape of accelerations array is correct + if meshAcc.shape[1] != 6: + print("Expecting a Nx6 array of mesh accelerations (meshAcc) with second index for [x,y,z,Rx,Ry,Rz]") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + if meshAcc.shape[0] != self.numMeshPts: + print("Expecting a Nx6 array of mesh accelerations (meshAcc) with first index for mesh number.") + self.aerodyn_inflow_end() + raise Exception("\nAeroDyn/AeroDyn terminated prematurely.") + + + + @property + def output_channel_names(self): + if len(self._channel_names_c.value.split()) == 0: + return [] + output_channel_names = self._channel_names_c.value.split() + output_channel_names = [n.decode('UTF-8') for n in output_channel_names] + return output_channel_names + + @property + def output_channel_units(self): + if len(self._channel_units_c.value.split()) == 0: + return [] + output_channel_units = self._channel_units_c.value.split() + output_channel_units = [n.decode('UTF-8') for n in output_channel_units] + return output_channel_units + + +#=============================================================================== +# Helper class for debugging the interface. This will write out all the +# input position/orientation, velocities, accelerations, and the resulting +# forces and moments at each input mesh point. If all is functioning +# correctly, this will be identical to the corresponding values in the +# AeroDyn/InflowWind output channels. + +#FIXME: this is incorrect +class DriverDbg(): + """ + This is only for debugging purposes only. The input motions and resulting + forces can be written to file with this class to verify the data I/O to the + Fortran library. + When coupled to another code, the force/moment array would be passed back + to the calling code for use in the structural solver. + """ + def __init__(self,filename,numMeshPts): + self.DbgFile=open(filename,'wt') # open output file and write header info + self.numMeshPts=numMeshPts + # write file header + t_string=datetime.datetime.now() + dt_string=datetime.date.today() + self.DbgFile.write(f"## This file was generated by aerodyn_inflow_c_lib on {dt_string.strftime('%b-%d-%Y')} at {t_string.strftime('%H:%M:%S')}\n") + self.DbgFile.write(f"## This file contains the resulting forces/moments at each of {self.numMeshPts} mesh points passed into the aerodyn_inflow_c_lib\n") + self.DbgFile.write("#\n") + self.DbgFile.write("#\n") + self.DbgFile.write("#\n") + self.DbgFile.write("#\n") + f_string = "{:^25s}" + self.DbgFile.write(" Time ") + for i in range(1,self.numMeshPts+1): + f_num = "N{0:04d}_".format(i) + self.DbgFile.write(f_string.format(f_num+"x" )) + self.DbgFile.write(f_string.format(f_num+"y" )) + self.DbgFile.write(f_string.format(f_num+"z" )) + #self.DbgFile.write(f_string.format(f_num+"Rx" )) + #self.DbgFile.write(f_string.format(f_num+"Ry" )) + #self.DbgFile.write(f_string.format(f_num+"Rz" )) + self.DbgFile.write(f_string.format(f_num+"Vx" )) + self.DbgFile.write(f_string.format(f_num+"Vy" )) + self.DbgFile.write(f_string.format(f_num+"Vz" )) + self.DbgFile.write(f_string.format(f_num+"RVx")) + self.DbgFile.write(f_string.format(f_num+"RVy")) + self.DbgFile.write(f_string.format(f_num+"RVz")) + self.DbgFile.write(f_string.format(f_num+"Ax" )) + self.DbgFile.write(f_string.format(f_num+"Ay" )) + self.DbgFile.write(f_string.format(f_num+"Az" )) + self.DbgFile.write(f_string.format(f_num+"RAx")) + self.DbgFile.write(f_string.format(f_num+"RAy")) + self.DbgFile.write(f_string.format(f_num+"RAz")) + self.DbgFile.write(f_string.format(f_num+"Fx" )) + self.DbgFile.write(f_string.format(f_num+"Fy" )) + self.DbgFile.write(f_string.format(f_num+"Fz" )) + self.DbgFile.write(f_string.format(f_num+"Mx" )) + self.DbgFile.write(f_string.format(f_num+"My" )) + self.DbgFile.write(f_string.format(f_num+"Mz" )) + self.DbgFile.write("\n") + self.DbgFile.write(" (s) ") + for i in range(1,self.numMeshPts+1): + self.DbgFile.write(f_string.format("(m)" )) + self.DbgFile.write(f_string.format("(m)" )) + self.DbgFile.write(f_string.format("(m)" )) + #self.DbgFile.write(f_string.format("(rad)" )) + #self.DbgFile.write(f_string.format("(rad)" )) + #self.DbgFile.write(f_string.format("(rad)" )) + self.DbgFile.write(f_string.format("(m/s)" )) + self.DbgFile.write(f_string.format("(m/s)" )) + self.DbgFile.write(f_string.format("(m/s)" )) + self.DbgFile.write(f_string.format("(rad/s)" )) + self.DbgFile.write(f_string.format("(rad/s)" )) + self.DbgFile.write(f_string.format("(rad/s)" )) + self.DbgFile.write(f_string.format("(m/s^2)" )) + self.DbgFile.write(f_string.format("(m/s^2)" )) + self.DbgFile.write(f_string.format("(m/s^2)" )) + self.DbgFile.write(f_string.format("(rad/s^2)")) + self.DbgFile.write(f_string.format("(rad/s^2)")) + self.DbgFile.write(f_string.format("(rad/s^2)")) + self.DbgFile.write(f_string.format("(N)" )) + self.DbgFile.write(f_string.format("(N)" )) + self.DbgFile.write(f_string.format("(N)" )) + self.DbgFile.write(f_string.format("(N-m)" )) + self.DbgFile.write(f_string.format("(N-m)" )) + self.DbgFile.write(f_string.format("(N-m)" )) + self.DbgFile.write("\n") + self.opened = True + + def write(self,t,meshPos,meshVel,meshAcc,meshFrc): + t_string = "{:10.4f}" + f_string3 = "{:25.7e}"*3 + f_string6 = "{:25.7e}"*6 + self.DbgFile.write(t_string.format(t)) + for i in range(0,self.numMeshPts): + self.DbgFile.write(f_string3.format(*meshPos[i,:])) + self.DbgFile.write(f_string6.format(*meshVel[i,:])) + self.DbgFile.write(f_string6.format(*meshAcc[i,:])) + self.DbgFile.write(f_string6.format(*meshFrc[i,:])) + self.DbgFile.write("\n") + + def end(self): + if self.opened: + self.DbgFile.close() + self.opened = False + + +#=============================================================================== +# Helper class for writing channels to file. +# for the regression testing to mirror the output from the AD15 and InfowWind +# from an OpenFAST simulation. This may also have value for debugging +# interfacing to the AeroDyn_Inflow_C_Binding library + +class WriteOutChans(): + """ + This is only for testing purposes. Since we are not returning the + output channels to anything, we will write them to file. When coupled to + another code, this data would be passed back for inclusion the any output + file there. + """ + def __init__(self,filename,chan_names,chan_units): + chan_names.insert(0,'Time') # add time index header + chan_units.insert(0,'(s)') # add time index unit + self.OutFile=open(filename,'wt') # open output file and write header info + # write file header + t_string=datetime.datetime.now() + dt_string=datetime.date.today() + self.OutFile.write(f"## This file was generated by AeroDyn_Inflow_Driver on {dt_string.strftime('%b-%d-%Y')} at {t_string.strftime('%H:%M:%S')}\n") + self.OutFile.write(f"## This file contains output channels requested from the OutList section of the AD15 and IfW input files") + self.OutFile.write(f"{filename}\n") + self.OutFile.write("#\n") + self.OutFile.write("#\n") + self.OutFile.write("#\n") + self.OutFile.write("#\n") + l = len(chan_names) + f_string = "{:^15s}"+" {:^20s} "*(l-1) + self.OutFile.write(f_string.format(*chan_names) + '\n') + self.OutFile.write(f_string.format(*chan_units) + '\n') + self.opened = True + + def write(self,chan_data): + l = chan_data.shape[1] + f_string = "{:10.4f}"+"{:25.7f}"*(l-1) + for i in range(0,chan_data.shape[0]): + self.OutFile.write(f_string.format(*chan_data[i,:]) + '\n') + #if i==0: + # print(f"{chan_data[i,:]}") + + def end(self): + if self.opened: + self.OutFile.close() + self.opened = False diff --git a/modules/aerodyn/src/AeroAcoustics.f90 b/modules/aerodyn/src/AeroAcoustics.f90 index e463a8e34..77449b40b 100644 --- a/modules/aerodyn/src/AeroAcoustics.f90 +++ b/modules/aerodyn/src/AeroAcoustics.f90 @@ -1,6 +1,27 @@ !********************************************************************************************************************************** -! File last committed: 2020-02-12 +! LICENSING +! Copyright (C) 2015-2016 National Renewable Energy Laboratory +! Copyright (C) 2016-2017 Envision Energy USA, LTD +! +! This file is part of AeroDyn. +! +! 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. +! !********************************************************************************************************************************** +! +! References: +! [1] Brooks, T. F.; Pope, D. S. & Marcolini, M. A., Airfoil self-noise and prediction, +! NASA, NASA, 1989. https://ntrs.nasa.gov/search.jsp?R=19890016302 module AeroAcoustics use NWTC_Library @@ -44,7 +65,6 @@ subroutine AA_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut integer(IntKi), intent( out) :: errStat !< Error status of the operation character(*), intent( out) :: errMsg !< Error message if ErrStat /= ErrID_None ! Local variables - integer(IntKi) :: i ! loop counter integer(IntKi) :: errStat2 ! temporary error status of the operation character(ErrMsgLen) :: errMsg2 ! temporary error message type(AA_InputFile) :: InputFileData ! Data stored in the module's input file @@ -70,7 +90,7 @@ subroutine AA_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut p%RootName = TRIM(InitInp%RootName)//'.NN' ! Read the primary AeroAcoustics input file in AeroAcoustics_IO - call ReadInputFiles( InitInp%InputFile, InitInp%AFInfo%BL_file, InputFileData, interval, p%RootName, p%NumBlades, UnEcho, ErrStat2, ErrMsg2 ) + call ReadInputFiles( InitInp%InputFile, InitInp%AFInfo, InputFileData, interval, p%RootName, UnEcho, ErrStat2, ErrMsg2 ) if (Failed()) return ! Validate the inputs @@ -85,7 +105,7 @@ subroutine AA_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut ! Define parameters call SetParameters( InitInp, InputFileData, p, ErrStat2, ErrMsg2 ); if(Failed()) return ! Define and initialize inputs - call Init_u( u, p, InputFileData, InitInp, errStat2, errMsg2 ); if(Failed()) return + call Init_u( u, p, errStat2, errMsg2 ); if(Failed()) return ! Define outputs here call Init_y(y, u, p, errStat2, errMsg2); if(Failed()) return @@ -95,7 +115,7 @@ subroutine AA_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut call Init_States(xd, p, errStat2, errMsg2); if(Failed()) return ! Define initialization output here - call AA_SetInitOut(p, InputFileData, InitOut, errStat2, errMsg2); if(Failed()) return + call AA_SetInitOut(p, InitOut, errStat2, errMsg2); if(Failed()) return call AA_InitializeOutputFile(p, InputFileData,InitOut,errStat2, errMsg2); if(Failed()) return call Cleanup() @@ -122,10 +142,10 @@ subroutine SetParameters( InitInp, InputFileData, p, ErrStat, ErrMsg ) ! Local variables CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat / = ErrID_None INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation - INTEGER(IntKi) :: simcou,coun ! simple loop counter +! INTEGER(IntKi) :: simcou,coun ! simple loop counter INTEGER(IntKi) :: I,J,whichairfoil,K,i1_1,i10_1,i1_2,i10_2,iLE character(*), parameter :: RoutineName = 'SetParameters' - LOGICAL :: tr,tri,exist,LE_flag + LOGICAL :: tri,LE_flag REAL(ReKi) :: val1,val10,f2,f4,lefttip,rightip,jumpreg, dist1, dist10 ! Initialize variables for this routine ErrStat = ErrID_None @@ -188,8 +208,8 @@ subroutine SetParameters( InitInp, InputFileData, p, ErrStat, ErrMsg ) DO k=1,size(p%AFInfo) ! if any of the airfoil coordinates are missing change calculation method IF( (size(p%AFInfo(k)%X_Coord) .lt. 5) .or. (size(p%AFInfo(k)%Y_Coord).lt.5) )then IF (tri) then ! Print the message for once only - print*, 'Airfoil coordinates are missing: If Full or Simplified Guidati or Bl Calculation is on coordinates are needed ' - print*, 'Calculation methods enforced as BPM for TBLTE and only Amiet for inflow ' + CALL WrScr( 'Airfoil coordinates are missing: If Full or Simplified Guidati or Bl Calculation is on coordinates are needed ' ) + CALL WrScr( 'Calculation methods enforced as BPM for TBLTE and only Amiet for inflow ' ) p%ITURB = 1 p%IInflow = 1 tri=.false. @@ -201,7 +221,7 @@ subroutine SetParameters( InitInp, InputFileData, p, ErrStat, ErrMsg ) ! Check 2 ! if passed the first check and if tno, turn on boundary layer calculation IF( (p%ITURB.eq.2)) then - p%X_BLMethod=2 + p%X_BLMethod=X_BLMethod_Tables ENDIF ! Check 3 @@ -306,7 +326,7 @@ subroutine SetParameters( InitInp, InputFileData, p, ErrStat, ErrMsg ) ENDDO ENDDO - if (p%X_BLMethod.eq.2) then + if (p%X_BLMethod .eq. X_BLMethod_Tables) then ! Copying inputdata list of AOA and Reynolds to parameters call AllocAry( p%AOAListBL, size(InputFileData%AOAListBL), 'p%AOAListBL', errStat2, errMsg2); if(Failed()) return @@ -440,11 +460,9 @@ end function Failed end subroutine SetParameters !---------------------------------------------------------------------------------------------------------------------------------- !> This routine initializes AeroAcoustics module input array variables for use during the simulation. -subroutine Init_u( u, p, InputFileData, InitInp, errStat, errMsg ) +subroutine Init_u( u, p, errStat, errMsg ) type(AA_InputType), intent( out) :: u !< Input data type(AA_ParameterType), intent(in ) :: p !< Parameters - type(AA_InputFile), intent(in ) :: InputFileData !< Data stored in the module's input file - type(AA_InitInputType), intent(in ) :: InitInp !< Input data for AD initialization routine integer(IntKi), intent( out) :: errStat !< Error status of the operation character(*), intent( out) :: errMsg !< Error message if ErrStat /= ErrID_None !local variables @@ -477,7 +495,6 @@ subroutine Init_y(y, u, p, errStat, errMsg) integer(IntKi), intent( out) :: errStat !< Error status of the operation character(*), intent( out) :: errMsg !< Error message if ErrStat /= ErrID_None ! Local variables - integer(intKi) :: k ! loop counter for blades integer(intKi) :: ErrStat2 ! temporary Error status character(ErrMsgLen) :: ErrMsg2 ! temporary Error message character(*), parameter :: RoutineName = 'Init_y' @@ -530,7 +547,6 @@ subroutine Init_MiscVars(m, p, u, y, errStat, errMsg) integer(IntKi), intent( out) :: errStat !< Error status of the operation character(*), intent( out) :: errMsg !< Error message if ErrStat /= ErrID_None ! Local variables - integer(intKi) :: k integer(intKi) :: ErrStat2 ! temporary Error status character(ErrMsgLen) :: ErrMsg2 ! temporary Error message character(*), parameter :: RoutineName = 'Init_MiscVars' @@ -652,13 +668,12 @@ subroutine AA_UpdateStates( t, n, m, u, p, xd, errStat, errMsg ) integer(IntKi), intent( out) :: errStat !< Error status of the operation character(*), intent( out) :: errMsg !< Error message if ErrStat /= ErrID_None ! local variables - integer(intKi) :: ErrStat2 ! temporary Error status - character(ErrMsgLen) :: ErrMsg2 ! temporary Error message +! integer(intKi) :: ErrStat2 ! temporary Error status +! character(ErrMsgLen) :: ErrMsg2 ! temporary Error message character(*), parameter :: RoutineName = 'AA_UpdateStates' REAL(ReKi),DIMENSION(p%NumBlNds,p%numBlades) :: TEMPSTD ! temporary standard deviation variable REAL(ReKi) :: tempsingle,tempmean,angletemp,abs_le_x,ti_vx,U1,U2 ! temporary standard deviation variable integer(intKi) :: i,j,k,rco, y0_a,y1_a,z0_a,z1_a - logical :: exist REAL(ReKi) :: yi_a,zi_a,yd_a,zd_a,c00_a,c10_a ErrStat = ErrID_None @@ -684,7 +699,7 @@ subroutine AA_UpdateStates( t, n, m, u, p, xd, errStat, errMsg ) ELSEIF ((abs_le_x.gt.0).and.(m%LE_Location(2,j,i).gt.0)) THEN angletemp=ATAN( m%LE_Location(2,j,i)/abs_le_x ) * R2D_D ELSE - print*, 'problem in angletemp Aeroacoustics module' + CALL WrScr( 'problem in angletemp Aeroacoustics module' ) ENDIF !abs_le_x=ABS(abs_le_x) do k=1,size(p%rotorregionlimitsrad) @@ -733,7 +748,7 @@ subroutine AA_UpdateStates( t, n, m, u, p, xd, errStat, errMsg ) ti_vx = (1.0_ReKi-zd_a)*c00_a+zd_a*c10_a ! With some velocity triangles, we convert it into the incident turbulence intensity, i.e. the TI used by the Amiet model U1 = u%Vrel(J,I) - U2 = SQRT((p%AvgV*(1.+ti_vx))**2. + U1**2. - p%AvgV**2.) + U2 = SQRT((p%AvgV*(1.+ti_vx))**2 + U1**2 - p%AvgV**2) ! xd%TIVx(j,i)=(U2-U1)/U1 xd%TIVx(j,i)=p%AvgV*ti_vx/U1 @@ -799,7 +814,6 @@ subroutine AA_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg) CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None ! Local variables integer, parameter :: indx = 1 ! m%BEMT_u(1) is at t; m%BEMT_u(2) is t+dt - integer(intKi) :: i integer(intKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 character(*), parameter :: RoutineName = 'AA_CalcOutput' @@ -846,10 +860,9 @@ SUBROUTINE CalcObserve(t,p,m,u,xd,errStat,errMsg) INTEGER(intKi) :: I ! I A generic index for DO loops. INTEGER(intKi) :: J ! J A generic index for DO loops. INTEGER(intKi) :: K ! K A generic index for DO loops. - INTEGER(intKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 +! INTEGER(intKi) :: ErrStat2 +! CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), parameter :: RoutineName = 'CalcObserveDist' - LOGICAL :: exist ErrStat = ErrID_None ErrMsg = "" @@ -932,16 +945,16 @@ SUBROUTINE CalcAeroAcousticsOutput(u,p,m,xd,y,errStat,errMsg) integer(intKi) :: III !III A generic index for DO loops. integer(intKi) :: I !I A generic index for DO loops. integer(intKi) :: J !J A generic index for DO loops. - integer(intKi) :: K,liop,cou ,JTEMP !K A generic index for DO loops. + integer(intKi) :: K !,liop,cou ,JTEMP !K A generic index for DO loops. integer(intKi) :: oi !K A generic index for DO loops. REAL(ReKi) :: AlphaNoise ! REAL(ReKi) :: UNoise ! REAL(ReKi) :: elementspan ! - REAL(ReKi),DIMENSION(p%NumBlNds) ::tempdel - REAL(ReKi),DIMENSION(p%NrObsLoc,p%NumBlNds,p%numBlades) ::OASPLTBLAll +! REAL(ReKi),DIMENSION(p%NumBlNds) ::tempdel +! REAL(ReKi),DIMENSION(p%NrObsLoc,p%NumBlNds,p%numBlades) ::OASPLTBLAll REAL(ReKi),DIMENSION(p%NrObsLoc,p%NumBlNds,p%numBlades,size(p%FreqList)) ::ForMaxLoc REAL(ReKi),DIMENSION(size(y%OASPL_Mech,1),size(p%FreqList),p%NrObsLoc,p%NumBlNds,p%numBlades) :: ForMaxLoc3 - REAL(ReKi),DIMENSION(size(p%FreqList),p%NrObsLoc,p%numBlades) ::SPL_Out +! REAL(ReKi),DIMENSION(size(p%FreqList),p%NrObsLoc,p%numBlades) ::SPL_Out REAL(ReKi),DIMENSION(p%NumBlNds,p%numBlades) ::temp_dispthick REAL(ReKi),DIMENSION(p%NumBlNds,p%numBlades) ::temp_dispthickchord @@ -960,16 +973,15 @@ SUBROUTINE CalcAeroAcousticsOutput(u,p,m,xd,y,errStat,errMsg) real(ReKi) :: PTBLALH real(ReKi) :: PTip real(ReKi) :: PTI - real(ReKi) :: PBLNT,adforma - REAL(ReKi),DIMENSION(2) :: Cf ,d99, d_star - TYPE(FFT_DataType) :: FFT_Data !< the instance of the FFT module we're using - REAL(ReKi),DIMENSION(p%total_sample) :: spect_signal - REAL(ReKi),DIMENSION(p%total_sample/2) :: spectra - real(ReKi),ALLOCATABLE :: fft_freq(:) + real(ReKi) :: PBLNT !,adforma +! REAL(ReKi),DIMENSION(2) :: Cf ,d99, d_star +! TYPE(FFT_DataType) :: FFT_Data !< the instance of the FFT module we're using +! REAL(ReKi),DIMENSION(p%total_sample) :: spect_signal +! REAL(ReKi),DIMENSION(p%total_sample/2) :: spectra +! real(ReKi),ALLOCATABLE :: fft_freq(:) integer(intKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 character(*), parameter :: RoutineName = 'CalcAeroAcousticsOutput' - logical :: exist ErrStat = ErrID_None ErrMsg = "" @@ -1056,7 +1068,7 @@ SUBROUTINE CalcAeroAcousticsOutput(u,p,m,xd,y,errStat,errMsg) !--------Read in Boundary Layer Data-------------------------! - IF (p%X_BLMethod .EQ. 2) THEN + IF (p%X_BLMethod .EQ. X_BLMethod_Tables) THEN call BL_Param_Interp(p,m,Unoise,AlphaNoise,p%BlChord(J,I),p%BlAFID(J,I), errStat2, errMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) temp_dispthick(J,I) = m%d99Var(1) @@ -1079,13 +1091,13 @@ SUBROUTINE CalcAeroAcousticsOutput(u,p,m,xd,y,errStat,errMsg) !--------Turbulent Boundary Layer Trailing Edge Noise----------------------------! IF ( (p%ITURB .EQ. 1) .or. (p%ITURB .EQ. 2) ) THEN CALL TBLTE(AlphaNoise,p%BlChord(J,I),UNoise,m%ChordAngleTE(K,J,I),m%SpanAngleTE(K,J,I), & - elementspan,m%rTEtoObserve(K,J,I), p, j,i,k,m%d99Var(2),m%dstarVar(1),m%dstarVar(2),p%StallStart(J,I), & + elementspan,m%rTEtoObserve(K,J,I), p, m%d99Var(2),m%dstarVar(1),m%dstarVar(2),p%StallStart(J,I), & m%SPLP,m%SPLS,m%SPLALPH,m%SPLTBL,errStat2,errMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF (p%ITURB .EQ. 2) THEN m%SPLP=0.0_ReKi;m%SPLS=0.0_ReKi;m%SPLTBL=0.0_ReKi; m%EdgeVelVar(1)=1.000d0;m%EdgeVelVar(2)=m%EdgeVelVar(1); - CALL TBLTE_TNO(AlphaNoise,p%BlChord(J,I),UNoise,m%ChordAngleTE(K,J,I),m%SpanAngleTE(K,J,I), & + CALL TBLTE_TNO(UNoise,m%ChordAngleTE(K,J,I),m%SpanAngleTE(K,J,I), & elementspan,m%rTEtoObserve(K,J,I),m%CfVar,m%d99var,m%EdgeVelVar ,p, & m%SPLP,m%SPLS,m%SPLALPH,m%SPLTBL,errStat2 ,errMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -1110,7 +1122,7 @@ SUBROUTINE CalcAeroAcousticsOutput(u,p,m,xd,y,errStat,errMsg) ! Amiet's Inflow Noise Model is Calculated as long as InflowNoise is On CALL InflowNoise(AlphaNoise,p%BlChord(J,I),Unoise,m%ChordAngleLE(K,J,I),m%SpanAngleLE(K,J,I),& - elementspan,m%rLEtoObserve(K,J,I),xd%MeanVxVyVz(J,I),xd%TIVx(J,I),m%LE_Location(3,J,I),0.050,p,m%SPLti,errStat2,errMsg2 ) + elementspan,m%rLEtoObserve(K,J,I),xd%TIVx(J,I),p,m%SPLti,errStat2,errMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! If Guidati model (simplified or full version) is also on then the 'SPL correction' to Amiet's model will be added IF ( p%IInflow .EQ. 2 ) THEN @@ -1119,7 +1131,7 @@ SUBROUTINE CalcAeroAcousticsOutput(u,p,m,xd,y,errStat,errMsg) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) m%SPLti=m%SPLti+m%SPLTIGui + 10. ! +10 is fudge factor to match NLR data ELSEIF ( p%IInflow .EQ. 3 ) THEN - print*,'Full Guidati removed' + CALL WrScr('Full Guidati removed') STOP ENDIF ENDIF @@ -1324,12 +1336,12 @@ SUBROUTINE LBLVS(ALPSTAR,C,U,THETA,PHI,L,R,p,d99Var2,dstarVar1,dstarVar2,SPLLAM, M = U / p%SpdSound ! MACH NUMBER RC = U * C/p%KinVisc ! REYNOLDS NUMBER BASED ON CHORD ! compute boundary layer thicknesses - IF (p%X_BLMethod .eq. 2) THEN + IF (p%X_BLMethod .eq. X_BLMethod_Tables) THEN DELTAP = d99Var2 DSTRS = dstarVar1 DSTRP = dstarVar2 ELSE - CALL THICK(C,M,RC,ALPSTAR,p,DELTAP,DSTRS,DSTRP,StallVal,errStat2,errMsg2) + CALL THICK(C,RC,ALPSTAR,p,DELTAP,DSTRS,DSTRP,StallVal,errStat2,errMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ENDIF ! compute directivity function @@ -1353,7 +1365,7 @@ SUBROUTINE LBLVS(ALPSTAR,C,U,THETA,PHI,L,R,p,d99Var2,dstarVar1,dstarVar2,SPLLAM, D = RC / RC0 ! Used in Eq 58 from BPM Airfoil Self-noise and Prediction paper IF (D .LE. .3237) G2 =77.852*LOG10(D)+15.328 ! Begin Eq 58 from BPM Airfoil Self-noise and Prediction paper IF ((D .GT. .3237).AND.(D .LE. .5689)) G2 = 65.188*LOG10(D) + 9.125 - IF ((D .GT. .5689).AND.(D .LE. 1.7579)) G2 = -114.052 * LOG10(D)**2. + IF ((D .GT. .5689).AND.(D .LE. 1.7579)) G2 = -114.052 * LOG10(D)**2 IF ((D .GT. 1.7579).AND.(D .LE. 3.0889)) G2 = -65.188*LOG10(D)+9.125 IF (D .GT. 3.0889) G2 =-77.852*LOG10(D)+15.328 ! end ! compute angle-dependent level for shape curve @@ -1365,14 +1377,14 @@ SUBROUTINE LBLVS(ALPSTAR,C,U,THETA,PHI,L,R,p,d99Var2,dstarVar1,dstarVar2,SPLLAM, E = STPRIM / STPKPRM ! Used in Eq 57 from BPM Airfoil Self-noise and Prediction paper IF (E .LE. .5974) G1 = 39.8*LOG10(E)-11.12 ! Begin Eq 57 from BPM Airfoil Self-noise and Prediction paper IF ((E .GT. .5974).AND.(E .LE. .8545)) G1 = 98.409 * LOG10(E) + 2.0 - IF ((E .GT. .8545).AND.(E .LE. 1.17)) G1 = -5.076+SQRT(2.484-506.25*(LOG10(E))**2.) + IF ((E .GT. .8545).AND.(E .LE. 1.17)) G1 = -5.076+SQRT(2.484-506.25*(LOG10(E))**2) IF ((E .GT. 1.17).AND.(E .LE. 1.674)) G1 = -98.409 * LOG10(E) + 2.0 IF (E .GT. 1.674) G1 = -39.80*LOG10(E)-11.12 ! end SPLLAM(I) = G1 + G2 + G3 + SCALE ! Eq 53 from BPM Airfoil Self-noise and Prediction paper ENDDO END SUBROUTINE LBLVS !==================================================================================================================================! -SUBROUTINE TBLTE(ALPSTAR,C,U,THETA,PHI,L,R,p,jj,ii,kk,d99Var2,dstarVar1,dstarVar2,StallVal,SPLP,SPLS,SPLALPH,SPLTBL,errStat,errMsg) +SUBROUTINE TBLTE(ALPSTAR,C,U,THETA,PHI,L,R,p,d99Var2,dstarVar1,dstarVar2,StallVal,SPLP,SPLS,SPLALPH,SPLTBL,errStat,errMsg) REAL(ReKi), INTENT(IN ) :: ALPSTAR ! AOA(deg) REAL(ReKi), INTENT(IN ) :: C ! Chord Length (m) ! REAL(ReKi), INTENT(IN ) :: U ! Unoise(m/s) @@ -1393,10 +1405,7 @@ SUBROUTINE TBLTE(ALPSTAR,C,U,THETA,PHI,L,R,p,jj,ii,kk,d99Var2,dstarVar1,dstarVar REAL(ReKi), INTENT(IN ) :: dstarVar1 ! REAL(ReKi), INTENT(IN ) :: dstarVar2 ! REAL(ReKi), INTENT(IN ) :: StallVal ! - INTEGER(IntKi), INTENT( IN) :: jj ! Error status of the operation - INTEGER(IntKi), INTENT( IN) :: ii ! Error status of the operation - INTEGER(IntKi), INTENT( IN) :: kk ! Error status of the operation TYPE(AA_ParameterType), INTENT(IN ) :: p ! Noise Module Parameters REAL(ReKi),DIMENSION(size(p%FreqList)), INTENT( OUT) :: SPLP ! SOUND PRESSURE LEVEL DUE TO PRESSURE SIDE OF AIRFOIL (db) REAL(ReKi),DIMENSION(size(p%FreqList)), INTENT( OUT) :: SPLS ! SOUND PRESSURE LEVEL DUE TO SUCTION SIDE OF AIRFOIL (db) @@ -1469,12 +1478,12 @@ SUBROUTINE TBLTE(ALPSTAR,C,U,THETA,PHI,L,R,p,jj,ii,kk,d99Var2,dstarVar1,dstarVar M = U / p%SpdSound RC = U * C/p%KinVisc ! Compute boundary layer thicknesses - IF (p%X_BLMethod .eq. 2) THEN + IF (p%X_BLMethod .eq. X_BLMethod_Tables) THEN DELTAP = d99Var2 DSTRS = dstarVar1 DSTRP = dstarVar2 ELSE - CALL THICK(C,M,RC,ALPSTAR,p,DELTAP,DSTRS,DSTRP,StallVal,errStat2,errMsg2) + CALL THICK(C,RC,ALPSTAR,p,DELTAP,DSTRS,DSTRP,StallVal,errStat2,errMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ENDIF ! Compute directivity function @@ -1495,7 +1504,7 @@ SUBROUTINE TBLTE(ALPSTAR,C,U,THETA,PHI,L,R,p,jj,ii,kk,d99Var2,dstarVar1,dstarVar ST1 = .02 * M ** (-.6) ! Eq 32 from BPM Airfoil Self-noise and Prediction paper ! Eq 34 from BPM Airfoil Self-noise and Prediction paper IF (ALPSTAR .LE. 1.333) ST2 = ST1 - IF ((ALPSTAR .GT. 1.333).AND.(ALPSTAR .LE. StallVal)) ST2 = ST1*10.**(.0054*(ALPSTAR-1.333)**2.) + IF ((ALPSTAR .GT. 1.333).AND.(ALPSTAR .LE. StallVal)) ST2 = ST1*10.**(.0054*(ALPSTAR-1.333)**2) IF (ALPSTAR .GT. StallVal) ST2 = 4.72 * ST1 ST1PRIM = (ST1+ST2)/2. ! Eq 33 from BPM Airfoil Self-noise and Prediction paper CALL A0COMP(RC,A0) ! compute -20 dB dropout (returns A0) @@ -1511,7 +1520,7 @@ SUBROUTINE TBLTE(ALPSTAR,C,U,THETA,PHI,L,R,p,jj,ii,kk,d99Var2,dstarVar1,dstarVar ! Compute b0 to be used in 'b' curve calculations ! Eq 44 from BPM Airfoil Self-noise and Prediction paper IF (RC .LT. 9.52E+04) B0 = .30 IF ((RC .GE. 9.52E+04).AND.(RC .LT. 8.57E+05)) & - B0 = (-4.48E-13)*(RC-8.57E+05)**2. + .56 + B0 = (-4.48E-13)*(RC-8.57E+05)**2 + .56 IF (RC .GE. 8.57E+05) B0 = .56 ! Evaluate minimum and maximum 'b' curves at b0 CALL BMIN(B0,BMINB0) @@ -1534,7 +1543,7 @@ SUBROUTINE TBLTE(ALPSTAR,C,U,THETA,PHI,L,R,p,jj,ii,kk,d99Var2,dstarVar1,dstarVar IF (ALPSTAR .LE. (GAMMA0-GAMMA)) K2 = -1000.0 ! Begin Eq 49 from BPM Airfoil Self-noise and Prediction paper IF ((ALPSTAR.GT.(GAMMA0-GAMMA)).AND.(ALPSTAR.LE.(GAMMA0+GAMMA))) & - K2=SQRT(BETA**2.-(BETA/GAMMA)**2.*(ALPSTAR-GAMMA0)**2.)+BETA0 + K2=SQRT(BETA**2-(BETA/GAMMA)**2*(ALPSTAR-GAMMA0)**2)+BETA0 IF (ALPSTAR .GT. (GAMMA0+GAMMA)) K2 = -12.0 K2 = K2 + K1 ! end ! Check for 'a' computation for suction side @@ -1551,7 +1560,7 @@ SUBROUTINE TBLTE(ALPSTAR,C,U,THETA,PHI,L,R,p,jj,ii,kk,d99Var2,dstarVar1,dstarVar CALL AMAX(A,AMAXA) AA = AMINA + ARA0 * (AMAXA - AMINA) ! Eq 40 from BPM Airfoil Self-noise and Prediction paper - SPLP(I)=AA+K1-3.+10.*LOG10(DSTRP*M**5.*DBARH*L/R**2.)+DELK1 ! Eq 25 from BPM Airfoil Self-noise and Prediction paper + SPLP(I)=AA+K1-3.+10.*LOG10(DSTRP*M**5*DBARH*L/R**2)+DELK1 ! Eq 25 from BPM Airfoil Self-noise and Prediction paper STS = p%FreqList(I) * DSTRS / U ! Eq 31 from BPM Airfoil Self-noise and Prediction paper IF (.NOT. SWITCH) THEN @@ -1559,25 +1568,25 @@ SUBROUTINE TBLTE(ALPSTAR,C,U,THETA,PHI,L,R,p,jj,ii,kk,d99Var2,dstarVar1,dstarVar CALL AMIN(A,AMINA) CALL AMAX(A,AMAXA) AA = AMINA + ARA0 * (AMAXA - AMINA) - SPLS(I) = AA+K1-3.+10.*LOG10(DSTRS*M**5.*DBARH* L/R**2.) ! Eq 26 from BPM Airfoil Self-noise and Prediction paper + SPLS(I) = AA+K1-3.+10.*LOG10(DSTRS*M**5*DBARH* L/R**2) ! Eq 26 from BPM Airfoil Self-noise and Prediction paper ! 'B' CURVE COMPUTATION ! B = ABS(LOG10(STS / ST2)) B = LOG10(STS / ST2) ! abs not needed absolute taken in the AMAX,AMIN ! Eq 43 from BPM Airfoil Self-noise and Prediction paper CALL BMIN(B,BMINB) CALL BMAX(B,BMAXB) BB = BMINB + BRB0 * (BMAXB-BMINB) ! Eq 46 from BPM Airfoil Self-noise and Prediction paper - SPLALPH(I)=BB+K2+10.*LOG10(DSTRS*M**5.*DBARH*L/R**2.) ! Eq 27 from BPM Airfoil Self-noise and Prediction paper + SPLALPH(I)=BB+K2+10.*LOG10(DSTRS*M**5*DBARH*L/R**2) ! Eq 27 from BPM Airfoil Self-noise and Prediction paper ELSE ! The 'a' computation is dropped if 'switch' is true - SPLS(I) = 10.*LOG10(DSTRS*M**5.*DBARL*L/R**2.) - ! SPLP(I) = 0.0 + 10.*LOG10(DSTRS*M**5.*DBARL*L/R**2.) ! changed the line below because the SPLP should be calculatd with DSTRP not with DSTRS - SPLP(I) = 10.*LOG10(DSTRP*M**5.*DBARL*L/R**2.) ! this is correct + SPLS(I) = 10.*LOG10(DSTRS*M**5*DBARL*L/R**2) + ! SPLP(I) = 0.0 + 10.*LOG10(DSTRS*M**5*DBARL*L/R**2) ! changed the line below because the SPLP should be calculatd with DSTRP not with DSTRS + SPLP(I) = 10.*LOG10(DSTRP*M**5*DBARL*L/R**2) ! this is correct ! B = ABS(LOG10(STS / ST2)) B = LOG10(STS / ST2) ! abs not needed absolute taken in the AMAX,AMIN CALL AMIN(B,AMINB) CALL AMAX(B,AMAXB) BB = AMINB + ARA02 * (AMAXB-AMINB) - SPLALPH(I)=BB+K2+10.*LOG10(DSTRS*M**5.*DBARL*L/R**2.) + SPLALPH(I)=BB+K2+10.*LOG10(DSTRS*M**5*DBARL*L/R**2) ENDIF ! Sum all contributions from 'a' and 'b' on both pressure and suction side on a mean-square pressure basis IF (SPLP(I) .LT. -100.) SPLP(I) = -100. ! Similar to Eq 28 of BPM Airfoil Self-noise and Prediction paper @@ -1647,7 +1656,7 @@ SUBROUTINE TIPNOIS(ALPHTIP,ALPRAT2,C,U ,THETA,PHI, R,p,SPLTIP, errStat, errMsg) ENDIF MM = (1. + .036*ALPTIPP) * M ! Eq 64 from BPM Airfoil Self-noise and Prediction paper UM = MM * p%SpdSound ! Eq 65 from BPM Airfoil Self-noise and Prediction paper - TERM = M*M*MM**3.*L**2.*DBARH/R**2. ! TERM = M^2 * M_max^5 *l^2 *D / r^2 according to Semi-Empirical Aeroacoustic Noise Prediction Code for Wind Turbines paper + TERM = M*M*MM**3*L**2*DBARH/R**2 ! TERM = M^2 * M_max^5 *l^2 *D / r^2 according to Semi-Empirical Aeroacoustic Noise Prediction Code for Wind Turbines paper ! Term is correct according to Eq 61 from BPM Airfoil self-noise and Prediction paper IF (TERM .NE. 0.0) THEN SCALE = 10.*LOG10(TERM) @@ -1656,34 +1665,23 @@ SUBROUTINE TIPNOIS(ALPHTIP,ALPRAT2,C,U ,THETA,PHI, R,p,SPLTIP, errStat, errMsg) ENDIF DO I=1,size(p%FreqList) STPP = p%FreqList(I) * L / UM ! Eq 62 from BPM Airfoil Self-noise and Prediction paper - SPLTIP(I) = 126.-30.5*(LOG10(STPP)+.3)**2. + SCALE ! Eq 61 from BPM Airfoil Self-noise and Prediction paper + SPLTIP(I) = 126.-30.5*(LOG10(STPP)+.3)**2 + SCALE ! Eq 61 from BPM Airfoil Self-noise and Prediction paper ENDDO END SUBROUTINE TipNois !==================================================================================================================================! -SUBROUTINE InflowNoise(AlphaNoise,Chord,U,THETA,PHI,d,RObs,MeanVNoise,TINoise,LE_Location,dissip,p,SPLti,errStat,errMsg) -! REAL(ReKi), INTENT(IN ) :: AlphaNoise ! AOA -! REAL(ReKi), INTENT(IN ) :: Chord ! Chord Length -! REAL(ReKi), INTENT(IN ) :: U ! -! REAL(ReKi), INTENT(IN ) :: d ! element span -! REAL(ReKi), INTENT(IN ) :: RObs ! distance to observer -! REAL(ReKi), INTENT(IN ) :: THETA ! -! REAL(ReKi), INTENT(IN ) :: PHI ! Spanwise directivity angle +SUBROUTINE InflowNoise(AlphaNoise,Chord,U,THETA,PHI,d,RObs,TINoise,p,SPLti,errStat,errMsg) + REAL(ReKi), INTENT(IN ) :: AlphaNoise ! AOA + REAL(ReKi), INTENT(IN ) :: Chord ! Chord Length + REAL(ReKi), INTENT(IN ) :: U ! + REAL(ReKi), INTENT(IN ) :: THETA ! + REAL(ReKi), INTENT(IN ) :: PHI ! Spanwise directivity angle + REAL(ReKi), INTENT(IN ) :: d ! element span + REAL(ReKi), INTENT(IN ) :: RObs ! distance to observer ! REAL(ReKi), INTENT(IN ) :: MeanVNoise ! -! REAL(ReKi), INTENT(IN ) :: TINoise ! + REAL(ReKi), INTENT(IN ) :: TINoise ! ! REAL(ReKi), INTENT(IN ) :: LE_Location ! - - REAL(ReKi) :: AlphaNoise ! AOA - REAL(ReKi) :: Chord ! Chord Length - REAL(ReKi) :: U ! - REAL(ReKi) :: d ! element span - REAL(ReKi) :: RObs ! distance to observer - REAL(ReKi) :: THETA ! - REAL(ReKi) :: PHI ! Spanwise directivity angle - REAL(ReKi) :: MeanVNoise ! - REAL(ReKi) :: TINoise ! - REAL(ReKi) :: LE_Location ! - - REAL(ReKi), INTENT(IN ) :: dissip ! + +! REAL(ReKi), INTENT(IN ) :: dissip ! TYPE(AA_ParameterType), INTENT(IN ) :: p ! Parameters REAL(ReKi),DIMENSION(size(p%FreqList)), INTENT( OUT) :: SPLti ! INTEGER(IntKi), INTENT( OUT) :: errStat ! Error status of the operation @@ -1701,13 +1699,14 @@ SUBROUTINE InflowNoise(AlphaNoise,Chord,U,THETA,PHI,d,RObs,MeanVNoise,TINoise,LE REAL(ReKi) :: Mach ! local mach number REAL(ReKi) :: Sears ! Sears function REAL(ReKi) :: SPLhigh ! predicted high frequency sound pressure level - REAL(ReKi) :: Ums ! mean square turbulence level +! REAL(ReKi) :: Ums ! mean square turbulence level REAL(ReKi) :: WaveNumber ! wave number - non-dimensional frequency REAL(ReKi) :: Kbar ! nafnoise - REAL(ReKi) :: khat,Kh ! nafnoise + REAL(ReKi) :: khat ! nafnoise +! REAL(ReKi) :: Kh ! nafnoise REAL(ReKi) :: ke ! nafnoise REAL(ReKi) :: alpstar ! nafnoise - REAL(ReKi) :: mu ! nafnoise +! REAL(ReKi) :: mu ! nafnoise REAL(ReKi) :: tinooisess ! nafnoise ! REAL(ReKi) :: L_Gammas ! nafnoise @@ -1957,7 +1956,6 @@ SUBROUTINE BLUNT(ALPSTAR,C,U ,THETA,PHI,L,R,H,PSI,p,d99Var2,dstarVar1,dstarVar2, ! real(ReKi) :: G5 ! SPECTRUM SHAPE FUNCTION DB REAL(ReKi),DIMENSION(size(p%FreqList)) :: G5 ! SPECTRUM SHAPE FUNCTION DB ! corrected (EB_DTU) real(ReKi) :: G5Sum ! SPECTRUM SHAPE FUNCTION DB - real(ReKi) :: F4TEMP ! G5 EVALUATED AT MINIMUM HDSTARP DB real(ReKi) :: SCALE ! SCALING FACTOR --- ErrStat = ErrID_None @@ -1967,12 +1965,12 @@ SUBROUTINE BLUNT(ALPSTAR,C,U ,THETA,PHI,L,R,H,PSI,p,d99Var2,dstarVar1,dstarVar2, M = U / p%SpdSound RC = U * C/p%KinVisc ! Compute boundary layer thicknesses - IF (p%X_BLMethod .eq. 2) THEN + IF (p%X_BLMethod .eq. X_BLMethod_Tables) THEN DELTAP = d99Var2 DSTRS = dstarVar1 DSTRP = dstarVar2 ELSE - CALL THICK(C,M,RC,ALPSTAR,p,DELTAP,DSTRS,DSTRP,StallVal,errStat2,errMsg2) + CALL THICK(C,RC,ALPSTAR,p,DELTAP,DSTRS,DSTRP,StallVal,errStat2,errMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ENDIF ! Compute average displacement thickness @@ -1989,7 +1987,7 @@ SUBROUTINE BLUNT(ALPSTAR,C,U ,THETA,PHI,L,R,H,PSI,p,d99Var2,dstarVar1,dstarVar2, ! Compute peak strouhal number eq 72 in BPM Airfoil Self-noise and Prediction paper ATERM = .212 - .0045 * PSI IF (HDSTAR .GE. .2) & - STPEAK = ATERM / (1.+.235*DSTARH-.0132*DSTARH**2.) ! this is what it used to be in nafnoise and fast noise module + STPEAK = ATERM / (1.+.235*DSTARH-.0132*DSTARH**2) ! this is what it used to be in nafnoise and fast noise module !! STPEAK = ATERM / (1+0.235*(DSTARH)**(-1)-0.0132*DSTARH**(-2)) ! check if this one is correct (EB_DTU) IF (HDSTAR .LT. .2) & STPEAK = .1 * HDSTAR + .095 - .00243 * PSI @@ -1997,7 +1995,7 @@ SUBROUTINE BLUNT(ALPSTAR,C,U ,THETA,PHI,L,R,H,PSI,p,d99Var2,dstarVar1,dstarVar2, IF (HDSTAR .LE. 5.) G4=17.5*LOG10(HDSTAR)+157.5-1.114*PSI IF (HDSTAR .GT. 5.) G4=169.7 - 1.114 * PSI ! For each frequency, compute spectrum shape referenced to 0 db - SCALE = 10. * LOG10(M**5.5*H*DBARH*L/R**2.) + SCALE = 10. * LOG10(M**5.5*H*DBARH*L/R**2) G5Sum=0.0_Reki DO I=1,SIZE(p%FreqList) STPPP = p%FreqList(I) * H / U @@ -2005,7 +2003,7 @@ SUBROUTINE BLUNT(ALPSTAR,C,U ,THETA,PHI,L,R,H,PSI,p,d99Var2,dstarVar1,dstarVar2, HDSTARL = HDSTAR CALL G5COMP(HDSTARL,ETA,G514,errStat2,errMsg2 ) ! compute G5 for Phi=14deg CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - HDSTARP = 6.724 * HDSTAR **2.-4.019*HDSTAR+1.107 ! eq 82 from BPM Airfoil Self-noise and Prediction paper + HDSTARP = 6.724 * HDSTAR **2-4.019*HDSTAR+1.107 ! eq 82 from BPM Airfoil Self-noise and Prediction paper CALL G5COMP(HDSTARP,ETA,G50,errStat2,errMsg2 ) ! recompute G5 for Phi=0deg CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) G5(I) = G50 + .0714 * PSI * (G514-G50) ! interpolate G5 from G50 and G514 @@ -2022,8 +2020,8 @@ SUBROUTINE G5COMP(HDSTAR,ETA,G5,errStat,errMsg) INTEGER(IntKi), INTENT( OUT) :: errStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: errMsg !< Error message if ErrStat /= ErrID_None ! Local variables - INTEGER(intKi) :: ErrStat2 ! temporary Error status - CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message +! INTEGER(intKi) :: ErrStat2 ! temporary Error status +! CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message CHARACTER(*), parameter :: RoutineName = 'BLUNT' real(ReKi) :: K real(ReKi) :: M @@ -2044,11 +2042,11 @@ SUBROUTINE G5COMP(HDSTAR,ETA,G5,errStat,errMsg) IF ( HDSTAR .GT. 1.2 ) M = 268.344 IF ( M .LT. 0.0 ) M = 0.0 ! end ETA0 = -SQRT((M*M*MU**4)/(6.25+M*M*MU*MU)) ! eq 80 from BPM Airfoil Self-noise and Prediction paper - K = 2.5*SQRT(1.-(ETA0/MU)**2.)-2.5-M*ETA0 ! eq 81 from BPM Airfoil Self-noise and Prediction paper + K = 2.5*SQRT(1.-(ETA0/MU)**2)-2.5-M*ETA0 ! eq 81 from BPM Airfoil Self-noise and Prediction paper ETALIMIT = 0.03615995 ! one of the bounds given in eq 76 of BPM Airfoil Self-noise and Prediction paper IF (ETA .LE. ETA0) G5 = M * ETA + K ! begin eq 76 from BPM Airfoil Self-noise and Prediction paper - IF((ETA.GT.ETA0).AND.(ETA .LE. 0.)) G5 = 2.5*SQRT(1.-(ETA/MU)**2.)-2.5 - IF((ETA.GT.0. ).AND.(ETA.LE.ETALIMIT)) G5 = SQRT(1.5625-1194.99*ETA**2.)-1.25 + IF((ETA.GT.ETA0).AND.(ETA .LE. 0.)) G5 = 2.5*SQRT(1.-(ETA/MU)**2)-2.5 + IF((ETA.GT.0. ).AND.(ETA.LE.ETALIMIT)) G5 = SQRT(1.5625-1194.99*ETA**2)-1.25 IF (ETA.GT.ETALIMIT) G5 = -155.543 * ETA + 4.375 ! end END SUBROUTINE G5Comp !==================================================================================================== @@ -2058,9 +2056,9 @@ SUBROUTINE AMIN(A,AMINA) REAL(ReKi), INTENT(OUT ) :: AMINA REAL(ReKi) :: X1 X1 = ABS(A) - IF (X1 .LE. .204) AMINA=SQRT(67.552-886.788*X1**2.)-8.219 + IF (X1 .LE. .204) AMINA=SQRT(67.552-886.788*X1**2)-8.219 IF((X1 .GT. .204).AND.(X1 .LE. .244))AMINA=-32.665*X1+3.981 - IF (X1 .GT. .244)AMINA=-142.795*X1**3.+103.656*X1**2.-57.757*X1+6.006 + IF (X1 .GT. .244)AMINA=-142.795*X1**3+103.656*X1**2-57.757*X1+6.006 END SUBROUTINE AMIN !==================================================================================================== !> This subroutine defines the curve fit corresponding to the a-curve for the maximum allowed reynolds number. @@ -2069,9 +2067,9 @@ SUBROUTINE AMAX(A,AMAXA) REAL(ReKi), INTENT(OUT ) :: AMAXA REAL(ReKi) :: X1 X1 = ABS(A) - IF (X1 .LE. .13)AMAXA=SQRT(67.552-886.788*X1**2.)-8.219 + IF (X1 .LE. .13)AMAXA=SQRT(67.552-886.788*X1**2)-8.219 IF((X1 .GT. .13).AND.(X1 .LE. .321))AMAXA=-15.901*X1+1.098 - IF (X1 .GT. .321)AMAXA=-4.669*X1**3.+3.491*X1**2.-16.699*X1+1.149 + IF (X1 .GT. .321)AMAXA=-4.669*X1**3+3.491*X1**2-16.699*X1+1.149 END SUBROUTINE AMAX !==================================================================================================== !> This subroutine defines the curve fit corresponding to the b-curve for the minimum allowed reynolds number. @@ -2080,9 +2078,9 @@ SUBROUTINE BMIN(B,BMINB) REAL(ReKi), INTENT(OUT ) :: BMINB REAL(ReKi) :: X1 X1 = ABS(B) - IF (X1 .LE. .13)BMINB=SQRT(16.888-886.788*X1**2.)-4.109 + IF (X1 .LE. .13)BMINB=SQRT(16.888-886.788*X1**2)-4.109 IF((X1 .GT. .13).AND.(X1 .LE. .145))BMINB=-83.607*X1+8.138 - IF (X1.GT..145)BMINB=-817.81*X1**3.+355.21*X1**2.-135.024*X1+10.619 + IF (X1.GT..145)BMINB=-817.81*X1**3+355.21*X1**2-135.024*X1+10.619 END SUBROUTINE BMin !==================================================================================================== !> Define the curve fit corresponding to the b-curve for the maximum allowed reynolds number. @@ -2091,9 +2089,9 @@ SUBROUTINE BMAX(B,BMAXB) REAL(ReKi), INTENT(OUT ) :: BMAXB REAL(ReKi) :: X1 X1 = ABS(B) - IF (X1 .LE. .1) BMAXB=SQRT(16.888-886.788*X1**2.)-4.109 + IF (X1 .LE. .1) BMAXB=SQRT(16.888-886.788*X1**2)-4.109 IF((X1 .GT. .1).AND.(X1 .LE. .187))BMAXB=-31.313*X1+1.854 - IF (X1.GT..187)BMAXB=-80.541*X1**3.+44.174*X1**2.-39.381*X1+2.344 + IF (X1.GT..187)BMAXB=-80.541*X1**3+44.174*X1**2-39.381*X1+2.344 END SUBROUTINE BMax !==================================================================================================== !> Determine where the a-curve takes on a value of -20 db. @@ -2102,12 +2100,12 @@ SUBROUTINE A0COMP(RC,A0) REAL(ReKi), INTENT(OUT ) :: A0 IF (RC .LT. 9.52E+04) A0 = .57 IF ((RC .GE. 9.52E+04).AND.(RC .LT. 8.57E+05)) & - A0 = (-9.57E-13)*(RC-8.57E+05)**2. + 1.13 + A0 = (-9.57E-13)*(RC-8.57E+05)**2 + 1.13 IF (RC .GE. 8.57E+05) A0 = 1.13 END SUBROUTINE A0COMP !==================================================================================================== !> Compute zero angle of attack boundary layer thickness (meters) and reynolds number -SUBROUTINE THICK(C,M,RC,ALPSTAR,p,DELTAP,DSTRS,DSTRP,StallVal,errStat,errMsg) +SUBROUTINE THICK(C,RC,ALPSTAR,p,DELTAP,DSTRS,DSTRP,StallVal,errStat,errMsg) !! VARIABLE NAME DEFINITION UNITS !! ------------- ---------- ----- !! ALPSTAR ANGLE OF ATTACK DEGREES @@ -2124,14 +2122,12 @@ SUBROUTINE THICK(C,M,RC,ALPSTAR,p,DELTAP,DSTRS,DSTRP,StallVal,errStat,errMsg) !! DSTRS SUCTION SIDE DISPLACEMENT !! THICKNESS METERS !! ITRIP TRIGGER FOR BOUNDARY LAYER TRIPPING --- -!! M MACH NUMBER --- !! RC REYNOLDS NUMBER BASED ON CHORD --- !! U FREESTREAM VELOCITY METERS/SEC !! KinViscosity KINEMATIC VISCOSITY M2/SEC REAL(ReKi), INTENT(IN ) :: ALPSTAR !< AOA REAL(ReKi), INTENT(IN ) :: C !< Chord Length REAL(ReKi), INTENT(IN ) :: RC !< RC= U*C/KinViscosity - REAL(ReKi), INTENT(IN ) :: M !< M = U/C0 TYPE(AA_ParameterType), INTENT(IN ) :: p !< Parameters REAL(ReKi), INTENT( OUT) :: DELTAP !< REAL(ReKi), INTENT( OUT) :: DSTRS !< @@ -2140,38 +2136,43 @@ SUBROUTINE THICK(C,M,RC,ALPSTAR,p,DELTAP,DSTRS,DSTRP,StallVal,errStat,errMsg) INTEGER(IntKi), INTENT( OUT) :: errStat !< Error status of the operation character(*), INTENT( OUT) :: errMsg !< Error message if ErrStat /= ErrID_None ! Local variables - integer(intKi) :: ErrStat2 ! temporary Error status - character(ErrMsgLen) :: ErrMsg2 ! temporary Error message +! integer(intKi) :: ErrStat2 ! temporary Error status +! character(ErrMsgLen) :: ErrMsg2 ! temporary Error message character(*), parameter :: RoutineName = 'Thick' real(ReKi) :: DELTA0 ! BOUNDARY LAYER THICKNESS AT ZERO ANGLE OF ATTACK METERS real(ReKi) :: DSTR0 ! DISPLACEMENT THICKNESS AT ZERO ANGLE OF ATTACK METERS ErrStat = ErrID_None ErrMsg = "" - ! - DELTA0 = 10.**(1.6569-.9045*LOG10(RC)+.0596*LOG10(RC)**2.)*C - IF (p%ITRIP .GT. 0) DELTA0 = 10.**(1.892-0.9045*LOG(RC)+0.0596*LOG(RC)**2.)*C + ! Boundary layer thickness + DELTA0 = 10.**(1.6569-0.9045*LOG10(RC)+0.0596*LOG10(RC)**2)*C ! (untripped) Eq. (5) of [1] + IF (p%ITRIP .GT. 0) DELTA0 = 10.**(1.892 -0.9045*LOG10(RC)+0.0596*LOG10(RC)**2)*C ! (heavily tripped) Eq. (2) of [1] IF (p%ITRIP .EQ. 2) DELTA0=.6*DELTA0 - ! Pressure side boundary layer thickness - DELTAP = 10.**(-.04175*ALPSTAR+.00106*ALPSTAR**2.)*DELTA0 + ! Pressure side boundary layer thickness, Eq (8) of [1] + DELTAP = 10.**(-.04175*ALPSTAR+.00106*ALPSTAR**2)*DELTA0 ! Compute zero angle of attack displacement thickness IF ((p%ITRIP .EQ. 1) .OR. (p%ITRIP .EQ. 2)) THEN + ! Heavily tripped, Eq. (3) of [1] IF (RC .LE. .3E+06) DSTR0 = .0601 * RC **(-.114)*C IF (RC .GT. .3E+06) & - DSTR0=10.**(3.411-1.5397*LOG10(RC)+.1059*LOG10(RC)**2.)*C + DSTR0=10.**(3.411-1.5397*LOG10(RC)+.1059*LOG10(RC)**2)*C + ! Lightly tripped IF (p%ITRIP .EQ. 2) DSTR0 = DSTR0 * .6 ELSE - DSTR0=10.**(3.0187-1.5397*LOG10(RC)+.1059*LOG10(RC)**2.)*C + ! Untripped, Eq. (6) of [1] + DSTR0=10.**(3.0187-1.5397*LOG10(RC)+.1059*LOG10(RC)**2)*C ENDIF - ! Pressure side displacement thickness - DSTRP = 10.**(-.0432*ALPSTAR+.00113*ALPSTAR**2.)*DSTR0 + ! Pressure side displacement thickness, Eq. (9) of [1] + DSTRP = 10.**(-.0432*ALPSTAR+.00113*ALPSTAR**2)*DSTR0 ! IF (p%ITRIP .EQ. 3) DSTRP = DSTRP * 1.48 ! commented since itrip is never 3 check if meant 2.(EB_DTU) ! Suction side displacement thickness IF (p%ITRIP .EQ. 1) THEN + ! Heavily tripped, Eq. (12) of [1] IF (ALPSTAR .LE. 5.) DSTRS=10.**(.0679*ALPSTAR)*DSTR0 IF((ALPSTAR .GT. 5.).AND.(ALPSTAR .LE. StallVal)) & DSTRS = .381*10.**(.1516*ALPSTAR)*DSTR0 IF (ALPSTAR .GT. StallVal)DSTRS=14.296*10.**(.0258*ALPSTAR)*DSTR0 ELSE + ! Untripped or lightly tripped, Eq. (15) of [1] IF (ALPSTAR .LE. 7.5)DSTRS =10.**(.0679*ALPSTAR)*DSTR0 IF((ALPSTAR .GT. 7.5).AND.(ALPSTAR .LE. StallVal)) & DSTRS = .0162*10.**(.3066*ALPSTAR)*DSTR0 @@ -2199,7 +2200,7 @@ SUBROUTINE DIRECTH_TE(M,THETA,PHI,DBAR, errStat, errMsg) MC = .8 * M THETAR = THETA * DEGRAD PHIR = PHI * DEGRAD - DBAR = 2.*SIN(THETAR/2.)**2.*SIN(PHIR)**2./((1.+M*COS(THETAR))* (1.+(M-MC)*COS(THETAR))**2.) ! eq B1 in BPM Airfoil Self-noise and Prediction paper + DBAR = 2.*SIN(THETAR/2.)**2*SIN(PHIR)**2/((1.+M*COS(THETAR))* (1.+(M-MC)*COS(THETAR))**2) ! eq B1 in BPM Airfoil Self-noise and Prediction paper END SUBROUTINE DIRECTH_TE !==================================================================================================== @@ -2221,7 +2222,7 @@ SUBROUTINE DIRECTH_LE(M,THETA,PHI,DBAR, errStat, errMsg) DEGRAD = .017453 THETAR = THETA * DEGRAD PHIR = PHI * DEGRAD - DBAR = 2.*COS(THETAR/2.)**2.*SIN(PHIR)**2./(1.+M*COS(THETAR))**3. + DBAR = 2.*COS(THETAR/2.)**2*SIN(PHIR)**2/(1.+M*COS(THETAR))**3 END SUBROUTINE DIRECTH_LE !==================================================================================================== @@ -2264,12 +2265,13 @@ SUBROUTINE Simple_Guidati(U,Chord,thick_10p,thick_1p,p,SPLti,errStat,errMsg) INTEGER(IntKi), INTENT( OUT) :: errStat ! Error status of the operation character(*), INTENT( OUT) :: errMsg ! Error message if ErrStat /= ErrID_None ! local variables - integer(intKi) :: ErrStat2 ! temporary Error status - character(ErrMsgLen) :: ErrMsg2 ! temporary Error message +! integer(intKi) :: ErrStat2 ! temporary Error status +! character(ErrMsgLen) :: ErrMsg2 ! temporary Error message character(*), parameter :: RoutineName = 'Simple_Guidati' INTEGER(intKi) :: loop1 ! temporary REAL(ReKi) :: TI_Param ! Temporary variable thickness ratio dependent REAL(ReKi) :: slope ! Temporary variable thickness ratio dependent + ErrStat = ErrID_None ErrMsg = "" @@ -2282,10 +2284,8 @@ END SUBROUTINE Simple_Guidati !==================================================================================================================================! !================================ Turbulent Boundary Layer Trailing Edge Noise ====================================================! !=================================================== TNO START ====================================================================! -SUBROUTINE TBLTE_TNO(ALPSTAR,C,U,THETA,PHI,D,R,Cfall,d99all,EdgeVelAll,p,SPLP,SPLS,SPLALPH,SPLTBL,errStat,errMsgn) +SUBROUTINE TBLTE_TNO(U,THETA,PHI,D,R,Cfall,d99all,EdgeVelAll,p,SPLP,SPLS,SPLALPH,SPLTBL,errStat,errMsgn) USE TNO, only: SPL_integrate - REAL(ReKi), INTENT(IN ) :: ALPSTAR !< AOA (deg) - REAL(ReKi), INTENT(IN ) :: C !< Chord Length (m) REAL(ReKi), INTENT(IN ) :: U !< Unoise (m/s) REAL(ReKi), INTENT(IN ) :: THETA !< DIRECTIVITY ANGLE (deg) REAL(ReKi), INTENT(IN ) :: PHI !< DIRECTIVITY ANGLE (deg) @@ -2346,7 +2346,7 @@ SUBROUTINE TBLTE_TNO(ALPSTAR,C,U,THETA,PHI,D,R,Cfall,d99all,EdgeVelAll,p,SPLP,SP answer = SPL_integrate(omega=omega,limits=int_limits,ISSUCTION=.true., & Mach=Mach,SpdSound=p%SpdSound,AirDens=p%AirDens,KinVisc=p%KinVisc, & Cfall=Cfall,d99all=d99all,EdgeVelAll=EdgeVelAll) - Spectrum = D/(4.*pi*R**2.)*answer + Spectrum = D/(4.*pi*R**2)*answer SPL_suction = 10.*log10(Spectrum*DBARH/2.e-5/2.e-5) SPLS(i_omega) = SPL_suction + 10.*log10(band_width) ENDIF @@ -2355,7 +2355,7 @@ SUBROUTINE TBLTE_TNO(ALPSTAR,C,U,THETA,PHI,D,R,Cfall,d99all,EdgeVelAll,p,SPLP,SP answer = SPL_integrate(omega=omega,limits=int_limits,ISSUCTION=.FALSE., & Mach=Mach,SpdSound=p%SpdSound,AirDens=p%AirDens,KinVisc=p%KinVisc, & Cfall=Cfall,d99all=d99all,EdgeVelAll=EdgeVelAll) - Spectrum = D/(4.*pi*R**2.)*answer + Spectrum = D/(4.*pi*R**2)*answer SPL_press = 10.*log10(Spectrum*DBARH/2.e-5/2.e-5) SPLP(i_omega) = SPL_press + 10.*log10(band_width) ENDIF @@ -2441,9 +2441,9 @@ SUBROUTINE BL_Param_Interp(p,m,U,AlphaNoise,C,whichairfoil, errStat, errMsg) if (loop2 .eq. (size(p%AOAListBL)-1) ) then if (AlphaNoise .gt. p%AOAListBL(size(p%AOAListBL))) then - print*, 'Warning AeroAcoustics Module - Angle of attack (AoA) range is not in the range provided by the user' - print*, 'Station ',whichairfoil - print*, 'Airfoil AoA ',AlphaNoise,' Using the closest AoA ',p%AOAListBL(loop2+1) + CALL WrScr( 'Warning AeroAcoustics Module - Angle of attack (AoA) range is not in the range provided by the user') + CALL WrScr( 'Station '// trim(num2lstr(whichairfoil)) ) + CALL WrScr( 'Airfoil AoA '//trim(num2lstr(AlphaNoise))//'; Using the closest AoA '//trim(num2lstr(p%AOAListBL(loop2+1)))) m%dStarVar (1) = ( p%dstarall1 (loop2+1,loop1+1,whichairfoil)*redif2 + p%dstarall1 (loop2+1,loop1,whichairfoil)*redif1 )/(redif1+redif2) m%dStarVar (2) = ( p%dstarall2 (loop2+1,loop1+1,whichairfoil)*redif2 + p%dstarall2 (loop2+1,loop1,whichairfoil)*redif1 )/(redif1+redif2) m%d99Var (1) = ( p%d99all1 (loop2+1,loop1+1,whichairfoil)*redif2 + p%d99all1 (loop2+1,loop1,whichairfoil)*redif1 )/(redif1+redif2) @@ -2453,9 +2453,9 @@ SUBROUTINE BL_Param_Interp(p,m,U,AlphaNoise,C,whichairfoil, errStat, errMsg) m%EdgeVelVar(1) = ( p%EdgeVelRat1(loop2+1,loop1+1,whichairfoil)*redif2 + p%EdgeVelRat1(loop2+1,loop1,whichairfoil)*redif1 )/(redif1+redif2) m%EdgeVelVar(2) = ( p%EdgeVelRat2(loop2+1,loop1+1,whichairfoil)*redif2 + p%EdgeVelRat2(loop2+1,loop1,whichairfoil)*redif1 )/(redif1+redif2) elseif (AlphaNoise .lt. p%AOAListBL(1)) then - print*, 'Warning AeroAcoustics Module - Angle of attack (AoA) range is not in the range provided by the user' - print*, 'Station ',whichairfoil - print*, 'Airfoil AoA ',AlphaNoise,' Using the closest AoA ',p%AOAListBL(1) + CALL WrScr( 'Warning AeroAcoustics Module - Angle of attack (AoA) range is not in the range provided by the user') + CALL WrScr( 'Station '// trim(num2lstr(whichairfoil)) ) + CALL WrScr( 'Airfoil AoA '//trim(num2lstr(AlphaNoise))//'; Using the closest AoA '//trim(num2lstr(p%AOAListBL(1))) ) m%dStarVar(1) = ( p%dstarall1 (1,loop1+1,whichairfoil)*redif2 + p%dstarall1 (1,loop1,whichairfoil)*redif1 ) / (redif1+redif2) m%dStarVar(2) = ( p%dstarall2 (1,loop1+1,whichairfoil)*redif2 + p%dstarall2 (1,loop1,whichairfoil)*redif1 ) / (redif1+redif2) m%d99Var(1) = ( p%d99all1 (1,loop1+1,whichairfoil)*redif2 + p%d99all1 (1,loop1,whichairfoil)*redif1 ) / (redif1+redif2) @@ -2487,7 +2487,7 @@ SUBROUTINE Aero_Tests() !m%SPLP=0.0_ReKi;m%SPLS=0.0_ReKi;m%SPLTBL=0.0_ReKi; !m%EdgeVelVar(1)=1.000d0;m%EdgeVelVar(2)=m%EdgeVelVar(1); !m%CfVar(1) = 0.0003785760d0;m%CfVar(2) = 0.001984380d0;m%d99var(1)= 0.01105860d0; m%d99var(2)= 0.007465830d0;m%EdgeVelVar(1)=1.000d0;m%EdgeVelVar(2)=m%EdgeVelVar(1); - !CALL TBLTE_TNO(3.0_Reki,0.22860_Reki,63.9200_Reki,90.00_Reki,90.0_Reki,0.5090_Reki,1.220_Reki, & + !CALL TBLTE_TNO(0.22860_Reki,63.9200_Reki,90.00_Reki,90.0_Reki,0.5090_Reki,1.220_Reki, & ! m%CfVar,m%d99var,m%EdgeVelVar, p, m%SPLP,m%SPLS,m%SPLALPH,m%SPLTBL,ErrStat2 ,errMsg2) !--------Blunt Trailing Edge Noise----------------------------------------------! !CALL BLUNT(3.0d0,0.22860d0,63.920d0,90.0d0,90.0d0,0.5090d0,1.220d0,& @@ -2496,8 +2496,7 @@ SUBROUTINE Aero_Tests() !CALL TIPNOIS(AlphaNoise,p%ALpRAT,p%BlChord(J,I),UNoise,m%ChordAngleTE(K,J,I),m%SpanAngleTE(K,J,I), & ! m%rTEtoObserve(K,J,I), p, m%SPLTIP,ErrStat2,errMsg2) !--------Inflow Turbulence Noise ------------------------------------------------! - !CALL InflowNoise(3.0d0,0.22860d0,63.920d0,90.0d0,90.0d0,0.5090d0,1.220d0, & - ! xd%MeanVrel(J,I),0.050d0,0.050d0,p,m%SPLti,ErrStat2,errMsg2 ) + !CALL InflowNoise(3.0d0,0.22860d0,63.920d0,90.0d0,90.0d0,0.5090d0,1.220d0, xd%TIVx(J,I),0.050d0,p,m%SPLti,ErrStat2,errMsg2 ) !CALL FullGuidati(3.0d0,63.920d0,0.22860d0,0.5090d0,1.220d0,90.0d0,90.0d0,xd%MeanVrel(J,I),xd%TIVrel(J,I), & ! p,p%BlAFID(J,I),m%SPLTIGui,ErrStat2 ) !CALL Simple_Guidati(UNoise,0.22860d0,0.120d0,0.020d0,p,m%SPLTIGui,ErrStat2,errMsg2 ) diff --git a/modules/aerodyn/src/AeroAcoustics_IO.f90 b/modules/aerodyn/src/AeroAcoustics_IO.f90 index cbb1666d5..28679b599 100644 --- a/modules/aerodyn/src/AeroAcoustics_IO.f90 +++ b/modules/aerodyn/src/AeroAcoustics_IO.f90 @@ -15,10 +15,6 @@ MODULE AeroAcoustics_IO INTEGER(IntKi), PARAMETER :: Time = 0 - ! Parameters related to output length (number of characters allowed in the output data headers): - - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 - INTEGER(IntKi), PARAMETER :: MaxBl = 3 ! Maximum number of blades allowed in simulation ! model identifiers @@ -58,22 +54,20 @@ MODULE AeroAcoustics_IO contains !---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE ReadInputFiles( InputFileName, BL_Files, InputFileData, Default_DT, OutFileRoot, NumBlades, UnEcho, ErrStat, ErrMsg ) +SUBROUTINE ReadInputFiles( InputFileName, AFI, InputFileData, Default_DT, OutFileRoot, UnEcho, ErrStat, ErrMsg ) ! This subroutine reads the input file and stores all the data in the AA_InputFile structure. ! It does not perform data validation. !.................................................................................................................................. ! Passed variables REAL(DbKi), INTENT(IN) :: Default_DT ! The default DT (from glue code) CHARACTER(*), INTENT(IN) :: InputFileName ! Name of the aeroacoustics input file - CHARACTER(*), dimension(:), INTENT(IN) :: BL_Files ! Name of the BL input file + TYPE(AFI_ParameterType), INTENT(IN) :: AFI(:) ! airfoil array: contains names of the BL input file CHARACTER(*), INTENT(IN) :: OutFileRoot ! The rootname of all the output files written by this routine. TYPE(AA_InputFile), INTENT(OUT) :: 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 INTEGER(IntKi), INTENT(OUT) :: ErrStat ! The error status code CHARACTER(*), INTENT(OUT) :: ErrMsg ! The error message, if an error occurred ! local variables - INTEGER(IntKi) :: I INTEGER(IntKi) :: ErrStat2 ! The error status code CHARACTER(ErrMsgLen) :: ErrMsg2 ! The error message, if an error occurred CHARACTER(*), PARAMETER :: RoutineName = 'ReadInputFiles' @@ -88,15 +82,15 @@ SUBROUTINE ReadInputFiles( InputFileName, BL_Files, InputFileData, Default_DT, O if(Failed()) return ! get the blade input-file data - ALLOCATE( InputFileData%BladeProps( size(BL_Files) ), STAT = ErrStat2 ) + ALLOCATE( InputFileData%BladeProps( size(AFI) ), STAT = ErrStat2 ) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal,"Error allocating memory for BladeProps.", ErrStat, ErrMsg, RoutineName) return END IF - if ((InputFileData%ITURB==2) .or. (InputFileData%X_BLMethod==2) .or. (InputFileData%IBLUNT==1)) then + if ((InputFileData%ITURB==2) .or. (InputFileData%X_BLMethod==X_BLMethod_Tables) .or. (InputFileData%IBLUNT==1)) then ! We need to read the BL tables - CALL ReadBLTables( InputFileName, BL_Files, InputFileData, ErrStat2, ErrMsg2 ) + CALL ReadBLTables( InputFileName, AFI, InputFileData, ErrStat2, ErrMsg2 ) if (Failed())return endif @@ -123,10 +117,8 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, Default_DT, OutFileRoot, U character(*), intent(in) :: OutFileRoot ! The rootname of the echo file, possibly opened in this routine type(AA_InputFile), intent(inout) :: InputFileData ! All the data in the Noise input file ! Local variables: - real(ReKi) :: TmpAry(3) ! array to help read tower properties table integer(IntKi) :: I ! loop counter integer(IntKi) :: UnIn,UnIn2 ! Unit number for reading file - integer(IntKi) :: loop1 ! loop counter character(1024) :: ObserverFile ! name of the files containing obesever location integer(IntKi) :: ErrStat2, IOS,cou ! Temporary Error status logical :: Echo ! Determines if an echo file should be written @@ -134,7 +126,6 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, Default_DT, OutFileRoot, U character(1024) :: PriPath ! Path name of the primary file character(200) :: Line ! Temporary storage of a line from the input file (to compare with "default") character(*), parameter :: RoutineName = 'ReadPrimaryFile' - integer(IntKi) :: n ! dummy integer ! Initialize some variables: ErrStat = ErrID_None ErrMsg = "" @@ -144,8 +135,8 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, Default_DT, OutFileRoot, U CALL GetPath( InputFile, PriPath ) ! Input files will be relative to the path where the primary input file is located. ! Open the Primary input file. - CALL GetNewUnit( UnIn, ErrStat2, ErrMsg2 ); call check - CALL OpenFInpFile ( UnIn, InputFile, ErrStat2, ErrMsg2 ); call check + CALL GetNewUnit( UnIn, ErrStat2, ErrMsg2 ); call check() + CALL OpenFInpFile ( UnIn, InputFile, ErrStat2, ErrMsg2 ); call check() IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN @@ -157,21 +148,21 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, Default_DT, OutFileRoot, U 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 check - CALL ReadStr( UnIn, InputFile, InputFileData%FTitle, 'FTitle', 'File Header: File Description (line 2)', ErrStat2, ErrMsg2, UnEc ); call check + CALL ReadCom( UnIn, InputFile, 'File header: Module Version (line 1)', ErrStat2, ErrMsg2, UnEc ); call check() + CALL ReadStr( UnIn, InputFile, InputFileData%FTitle, 'FTitle', 'File Header: File Description (line 2)', ErrStat2, ErrMsg2, UnEc ); call check() IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF !----------- GENERAL OPTIONS ---------------------------------------------------- - CALL ReadCom( UnIn, InputFile, 'Section Header: General Options', ErrStat2, ErrMsg2, UnEc ); call check + CALL ReadCom( UnIn, InputFile, 'Section Header: General Options', ErrStat2, ErrMsg2, UnEc ); call check() ! Echo - Echo input to ".AD.ech". - CALL ReadVar( UnIn, InputFile, Echo, 'Echo', 'Echo flag', ErrStat2, ErrMsg2, UnEc); call check + CALL ReadVar( UnIn, InputFile, Echo, 'Echo', 'Echo flag', ErrStat2, ErrMsg2, UnEc); call check() 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, AA_Ver ); call check + CALL OpenEcho ( UnEc, TRIM(OutFileRoot)//'.ech', ErrStat2, ErrMsg2, AA_Ver ); call check() IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN @@ -192,12 +183,12 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, Default_DT, OutFileRoot, U ! DT_AA - Time interval for aerodynamic calculations {or default} (s): Line = "" - CALL ReadVar( UnIn, InputFile, Line, "DT_AA", "Time interval for aeroacoustics calculations {or default} (s)", ErrStat2, ErrMsg2, UnEc); call check + CALL ReadVar( UnIn, InputFile, Line, "DT_AA", "Time interval for aeroacoustics calculations {or default} (s)", ErrStat2, ErrMsg2, UnEc); call check() CALL Conv2UC( Line ) IF ( INDEX(Line, "DEFAULT" ) /= 1 ) THEN ! If DT_AA is not "default", read it and make sure it is a multiple of DTAero from AeroDyn. Else, just use DTAero READ( Line, *, IOSTAT=IOS) InputFileData%DT_AA - CALL CheckIOS ( IOS, InputFile, 'DT_AA', NumType, ErrStat2, ErrMsg2 ); call check + CALL CheckIOS ( IOS, InputFile, 'DT_AA', NumType, ErrStat2, ErrMsg2 ); call check() IF (abs(InputFileData%DT_AA / Default_DT - NINT(InputFileData%DT_AA / Default_DT)) .gt. 1E-10) THEN CALL SetErrStat(ErrID_Fatal,"The Aeroacoustics input DT_AA must be a multiple of DTAero.", ErrStat, ErrMsg, RoutineName) @@ -207,21 +198,21 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, Default_DT, OutFileRoot, U InputFileData%DT_AA = Default_DT END IF - CALL ReadVar(UnIn,InputFile,InputFileData%AAStart ,"AAStart" ,"" ,ErrStat2,ErrMsg2,UnEc); call check - CALL ReadVar(UnIn,InputFile,InputFileData%AA_Bl_Prcntge,"BldPrcnt" ,"-",ErrStat2,ErrMsg2,UnEc); call check - CALL ReadCom( UnIn, InputFile, 'Section Header: Aeroacoustic Models', ErrStat2, ErrMsg2, UnEc ); call check - CALL ReadVar(UnIn,InputFile,InputFileData%IInflow ,"InflowMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check - CALL ReadVar(UnIn,InputFile,InputFileData%TICalcMeth ,"TICalcMeth" ,"" ,ErrStat2,ErrMsg2,UnEc); call check - CALL ReadVAr(UnIn,InputFile,InputFileData%TICalcTabFile,"TICalcTabFile","" ,ErrStat2,ErrMsg2,UnEc); call check - CALL ReadVar(UnIn,InputFile,InputFileData%Lturb ,"Lturb" ,"" ,ErrStat2,ErrMsg2,UnEc); call check - CALL ReadVar(UnIn,InputFile,InputFileData%ITURB ,"TurbMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check ! ITURB - TBLTE NOISE - CALL ReadVar(UnIn,InputFile,InputFileData%X_BLMethod ,"BLMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check - CALL ReadVar(UnIn,InputFile,InputFileData%ITRIP ,"TripMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check - CALL ReadVar(UnIn,InputFile,InputFileData%ILAM ,"LamMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check - CALL ReadVar(UnIn,InputFile,InputFileData%ITIP ,"TipMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check - CALL ReadVar(UnIn,InputFile,InputFileData%ROUND ,"RoundTip" ,"" ,ErrStat2,ErrMsg2,UnEc); call check - CALL ReadVar(UnIn,InputFile,InputFileData%ALPRAT ,"ALPRAT" ,"" ,ErrStat2,ErrMsg2,UnEc); call check - CALL ReadVar(UnIn,InputFile,InputFileData%IBLUNT ,"BluntMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check + CALL ReadVar(UnIn,InputFile,InputFileData%AAStart ,"AAStart" ,"" ,ErrStat2,ErrMsg2,UnEc); call check() + CALL ReadVar(UnIn,InputFile,InputFileData%AA_Bl_Prcntge,"BldPrcnt" ,"-",ErrStat2,ErrMsg2,UnEc); call check() + CALL ReadCom( UnIn, InputFile, 'Section Header: Aeroacoustic Models', ErrStat2, ErrMsg2, UnEc ); call check() + CALL ReadVar(UnIn,InputFile,InputFileData%IInflow ,"InflowMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check() + CALL ReadVar(UnIn,InputFile,InputFileData%TICalcMeth ,"TICalcMeth" ,"" ,ErrStat2,ErrMsg2,UnEc); call check() + CALL ReadVAr(UnIn,InputFile,InputFileData%TICalcTabFile,"TICalcTabFile","" ,ErrStat2,ErrMsg2,UnEc); call check() + CALL ReadVar(UnIn,InputFile,InputFileData%Lturb ,"Lturb" ,"" ,ErrStat2,ErrMsg2,UnEc); call check() + CALL ReadVar(UnIn,InputFile,InputFileData%ITURB ,"TurbMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check() ! ITURB - TBLTE NOISE + CALL ReadVar(UnIn,InputFile,InputFileData%X_BLMethod ,"BLMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check() + CALL ReadVar(UnIn,InputFile,InputFileData%ITRIP ,"TripMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check() + CALL ReadVar(UnIn,InputFile,InputFileData%ILAM ,"LamMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check() + CALL ReadVar(UnIn,InputFile,InputFileData%ITIP ,"TipMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check() + CALL ReadVar(UnIn,InputFile,InputFileData%ROUND ,"RoundTip" ,"" ,ErrStat2,ErrMsg2,UnEc); call check() + CALL ReadVar(UnIn,InputFile,InputFileData%ALPRAT ,"ALPRAT" ,"" ,ErrStat2,ErrMsg2,UnEc); call check() + CALL ReadVar(UnIn,InputFile,InputFileData%IBLUNT ,"BluntMod" ,"" ,ErrStat2,ErrMsg2,UnEc); call check() ! Return on error at end of section IF ( ErrStat >= AbortErrLev ) THEN @@ -230,29 +221,29 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, Default_DT, OutFileRoot, U END IF !----------- OBSERVER INPUT ------------------------------ - CALL ReadCom( UnIn, InputFile, 'Section Header: Observer Input ', ErrStat2, ErrMsg2, UnEc ); call check + CALL ReadCom( UnIn, InputFile, 'Section Header: Observer Input ', ErrStat2, ErrMsg2, UnEc ); call check() !----- read from observer file - CALL ReadVar ( UnIn, InputFile, ObserverFile, ObserverFile, 'Name of file observer locations', ErrStat2, ErrMsg2, UnEc ); call check + CALL ReadVar ( UnIn, InputFile, ObserverFile, ObserverFile, 'Name of file observer locations', ErrStat2, ErrMsg2, UnEc ); call check() IF ( PathIsRelative( ObserverFile ) ) ObserverFile = TRIM(PriPath)//TRIM(ObserverFile) - CALL GetNewUnit( UnIn2, ErrStat2, ErrMsg2 ); call check + CALL GetNewUnit( UnIn2, ErrStat2, ErrMsg2 ); call check() - CALL OpenFInpFile ( UnIn2, ObserverFile, ErrStat2, ErrMsg2 ); call check + CALL OpenFInpFile ( UnIn2, ObserverFile, ErrStat2, ErrMsg2 ); call check() IF ( ErrStat >= AbortErrLev ) RETURN ! NrObsLoc - Nr of Observers (-): - CALL ReadVar( UnIn2, ObserverFile, InputFileData%NrObsLoc, "NrObsLoc", "Nr of Observers (-)", ErrStat2, ErrMsg2, UnEc); call check + CALL ReadVar( UnIn2, ObserverFile, InputFileData%NrObsLoc, "NrObsLoc", "Nr of Observers (-)", ErrStat2, ErrMsg2, UnEc); call check() ! Observer location in tower-base coordinate (m): - CALL AllocAry( InputFileData%ObsX,InputFileData%NrObsLoc, 'ObsX', ErrStat2, ErrMsg2); call check - CALL AllocAry( InputFileData%ObsY,InputFileData%NrObsLoc, 'ObsY', ErrStat2, ErrMsg2); call check - CALL AllocAry( InputFileData%ObsZ,InputFileData%NrObsLoc, 'ObsZ', ErrStat2, ErrMsg2); call check + CALL AllocAry( InputFileData%ObsX,InputFileData%NrObsLoc, 'ObsX', ErrStat2, ErrMsg2); call check() + CALL AllocAry( InputFileData%ObsY,InputFileData%NrObsLoc, 'ObsY', ErrStat2, ErrMsg2); call check() + CALL AllocAry( InputFileData%ObsZ,InputFileData%NrObsLoc, 'ObsZ', ErrStat2, ErrMsg2); call check() - CALL ReadCom( UnIn2, InputFile, ' Header', ErrStat2, ErrMsg2, UnEc ); call check + CALL ReadCom( UnIn2, InputFile, ' Header', ErrStat2, ErrMsg2, UnEc ); call check() DO cou=1,InputFileData%NrObsLoc READ( UnIn2, *, IOStat=IOS ) InputFileData%ObsX(cou), InputFileData%ObsY(cou), InputFileData%ObsZ(cou) - CALL CheckIOS( IOS, ObserverFile, 'Obeserver Locations '//TRIM(Num2LStr(cou)), NumType, ErrStat2, ErrMsg2 ); call check + CALL CheckIOS( IOS, ObserverFile, 'Obeserver Locations '//TRIM(Num2LStr(cou)), NumType, ErrStat2, ErrMsg2 ); call check() ! Return on error if we couldn't read this line IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -263,11 +254,11 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, Default_DT, OutFileRoot, U !----- end read from observer file !----------- OUTPUTS ----------------------------------------------------------- - CALL ReadCom( UnIn, InputFile, 'Section Header: Outputs', ErrStat2, ErrMsg2, UnEc); call check - CALL ReadVar( UnIn,InputFile,InputFileData%aweightflag ,"AWeighting" ,"" ,ErrStat2,ErrMsg2,UnEc); call check - CALL ReadVar( UnIn, InputFile, InputFileData%NrOutFile, "NrOutFile", "Nr of Output Files (-)", ErrStat2, ErrMsg2, UnEc); call check - CALL AllocAry( InputFileData%AAOutFile,InputFileData%NrOutFile, 'AAOutFile', ErrStat2, ErrMsg2); call check - CALL ReadVar ( UnIn, InputFile, InputFileData%AAOutFile(1), 'AAOutFile', 'Name of output file ', ErrStat2, ErrMsg2, UnEc ); call check + CALL ReadCom( UnIn, InputFile, 'Section Header: Outputs', ErrStat2, ErrMsg2, UnEc); call check() + CALL ReadVar( UnIn,InputFile,InputFileData%aweightflag ,"AWeighting" ,"" ,ErrStat2,ErrMsg2,UnEc); call check() + CALL ReadVar( UnIn, InputFile, InputFileData%NrOutFile, "NrOutFile", "Nr of Output Files (-)", ErrStat2, ErrMsg2, UnEc); call check() + CALL AllocAry( InputFileData%AAOutFile,InputFileData%NrOutFile, 'AAOutFile', ErrStat2, ErrMsg2); call check() + CALL ReadVar ( UnIn, InputFile, InputFileData%AAOutFile(1), 'AAOutFile', 'Name of output file ', ErrStat2, ErrMsg2, UnEc ); call check() DO I=InputFileData%NrOutFile,1,-1 ! one file name is given by the user and the XXFile1.out XXFile2.out XXFile3.out is generated IF ( PathIsRelative( InputFileData%AAOutFile(I) ) ) InputFileData%AAOutFile(I) = TRIM(PriPath)//TRIM(InputFileData%AAOutFile(1))//TRIM(Num2Lstr(I))//".out" @@ -322,38 +313,37 @@ subroutine ReadRealMatrix(fid, FileName, Mat, VarName, nLines,nRows, iStat, Msg, -SUBROUTINE ReadBLTables( InputFile, BL_Files, InputFileData, ErrStat, ErrMsg ) +SUBROUTINE ReadBLTables( InputFile, AFI, InputFileData, ErrStat, ErrMsg ) ! Passed variables character(*), intent(in) :: InputFile ! Name of the file containing the primary input data - character(*), dimension(:), intent(in) :: BL_Files ! Name of the file containing the primary input data -type(AA_InputFile), intent(inout) :: InputFileData ! All the data in the Noise input file + TYPE(AFI_ParameterType), INTENT(IN) :: AFI(:) ! airfoil array: contains names of the BL input file + type(AA_InputFile), intent(inout) :: InputFileData ! All the data in the Noise input file integer(IntKi), intent(out) :: ErrStat ! Error status character(*), intent(out) :: ErrMsg ! Error message + ! Local variables: - integer(IntKi) :: UnIn,UnIn2 ! Unit number for reading file - character(1024) :: FileName ! name of the files containing obesever location - integer(IntKi) :: ErrStat2 ! Temporary Error status - logical :: Echo ! Determines if an echo file should be written + integer(IntKi) :: UnIn ! Unit number for reading file + character(1024) :: FileName ! name of the files containing obesever location + integer(IntKi) :: ErrStat2 ! Temporary Error status character(ErrMsgLen) :: ErrMsg2 ! 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 = 'readbltable' - integer(IntKi) :: nRe, nAoA, nAirfoils ! Number of Reynolds number, angle of attack, and number of airfoils listed - integer(IntKi) :: iAF , iRe, iAoA, iDummy, iBuffer ! loop counters - real(DbKi),dimension(:,:),ALLOCATABLE :: Buffer - integer :: iLine + character(*), parameter :: RoutineName = 'ReadBLTables' + integer(IntKi) :: nRe, nAoA, nAirfoils ! Number of Reynolds number, angle of attack, and number of airfoils listed + integer(IntKi) :: iAF , iRe, iAoA ! loop counters + real(DbKi), ALLOCATABLE :: Buffer(:,:) + integer :: iLine + ! Initialize some variables: ErrStat = ErrID_None ErrMsg = "" CALL GetPath( InputFile, PriPath ) ! Input files will be relative to the path where the primary input file is located. - nAirfoils = size(BL_Files) + nAirfoils = size(AFI) do iAF=1,nAirfoils - FileName = trim(BL_Files(iAF)) + FileName = trim(AFI(iAF)%BL_file) - print*,'AeroAcoustics_IO: reading BL table:'//trim(Filename) + call WrScr('AeroAcoustics_IO: reading BL table:'//trim(Filename)) CALL GetNewUnit(UnIn, ErrStat2, ErrMsg2); if(Failed()) return CALL OpenFInpFile(UnIn, FileName, ErrStat2, ErrMsg2); if(Failed()) return @@ -440,16 +430,11 @@ SUBROUTINE ReadTICalcTables(InputFile, InputFileData, ErrStat, ErrMsg) type(AA_InputFile), intent(inout) :: InputFileData ! All the data in the Noise input file character(*), intent(in) :: InputFile ! Name of the file containing the primary input data ! Local variables: - integer(IntKi) :: I ! loop counter - integer(IntKi) :: UnIn,UnIn2 ! Unit number for reading file - integer(IntKi) :: loop1 ! loop counter - character(1024) :: FileName ! name of the files containing obesever location - integer(IntKi) :: ErrStat2, IOS,cou ! Temporary Error status - logical :: Echo ! Determines if an echo file should be written + integer(IntKi) :: UnIn ! Unit number for reading file + character(1024) :: FileName ! name of the files containing obesever location + integer(IntKi) :: ErrStat2 ! Temporary Error status character(ErrMsgLen) :: ErrMsg2 ! 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 = 'REadTICalcTables' integer(IntKi) :: GridY ! integer(IntKi) :: GridZ ! @@ -464,16 +449,16 @@ SUBROUTINE ReadTICalcTables(InputFile, InputFileData, ErrStat, ErrMsg) CALL GetNewUnit( UnIn, ErrStat2, ErrMsg2); call check() CALL OpenFInpFile ( UnIn, FileName, ErrStat2, ErrMsg2 ); if(Failed()) return - CALL ReadCom(UnIn, FileName, 'Text Line', ErrStat2, ErrMsg2); call check - CALL ReadVar(UnIn, FileName, InputFileData%AvgV, 'AvgV', 'Echo flag', ErrStat2, ErrMsg2); call check - CALL ReadCom(UnIn, FileName, 'Text Line', ErrStat2, ErrMsg2); call check - CALL ReadVar(UnIn, FileName, GridY, 'GridY', 'Echo flag', ErrStat2, ErrMsg2); call check - CALL ReadCom(UnIn, FileName, 'Text Line', ErrStat2, ErrMsg2);call check - CALL ReadVar(UnIn, FileName, GridZ, 'GridZ', 'Echo flag', ErrStat2, ErrMsg2); call check - CALL ReadCom(UnIn, FileName, 'Text Line', ErrStat2, ErrMsg2); call check - CALL ReadVar(UnIn, FileName, InputFileData%dy_turb_in, 'InputFileData%dy_turb_in', 'Echo flag', ErrStat2, ErrMsg2); call check - CALL ReadCom(UnIn, FileName, 'Text Line', ErrStat2, ErrMsg2); call check - CALL ReadVar(UnIn, FileName, InputFileData%dz_turb_in, 'InputFileData%dz_turb_in', 'Echo flag', ErrStat2, ErrMsg2); call check + CALL ReadCom(UnIn, FileName, 'Text Line', ErrStat2, ErrMsg2); call check() + CALL ReadVar(UnIn, FileName, InputFileData%AvgV, 'AvgV', 'Echo flag', ErrStat2, ErrMsg2); call check() + CALL ReadCom(UnIn, FileName, 'Text Line', ErrStat2, ErrMsg2); call check() + CALL ReadVar(UnIn, FileName, GridY, 'GridY', 'Echo flag', ErrStat2, ErrMsg2); call check() + CALL ReadCom(UnIn, FileName, 'Text Line', ErrStat2, ErrMsg2);call check() + CALL ReadVar(UnIn, FileName, GridZ, 'GridZ', 'Echo flag', ErrStat2, ErrMsg2); call check() + CALL ReadCom(UnIn, FileName, 'Text Line', ErrStat2, ErrMsg2); call check() + CALL ReadVar(UnIn, FileName, InputFileData%dy_turb_in, 'InputFileData%dy_turb_in', 'Echo flag', ErrStat2, ErrMsg2); call check() + CALL ReadCom(UnIn, FileName, 'Text Line', ErrStat2, ErrMsg2); call check() + CALL ReadVar(UnIn, FileName, InputFileData%dz_turb_in, 'InputFileData%dz_turb_in', 'Echo flag', ErrStat2, ErrMsg2); call check() if(Failed()) return CALL AllocAry( InputFileData%TI_Grid_In,GridZ,GridY,'InputFileData%TI_Grid_In', ErrStat2, ErrMsg2); @@ -505,8 +490,6 @@ SUBROUTINE ValidateInputData( InputFileData, NumBl, ErrStat, ErrMsg ) integer(IntKi), intent(out) :: ErrStat !< Error status character(*), intent(out) :: ErrMsg !< Error message ! local variables - integer(IntKi) :: k ! Blade number - integer(IntKi) :: j ! node number character(*), parameter :: RoutineName = 'ValidateInputData' ErrStat = ErrID_None ErrMsg = "" @@ -553,33 +536,10 @@ SUBROUTINE ValidateInputData( InputFileData, NumBl, ErrStat, ErrMsg ) END SUBROUTINE ValidateInputData !---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE AA_PrintSum( InputFileData, p, u, y, ErrStat, ErrMsg ) - ! This routine generates the summary file, which contains a summary of input file options. - ! passed variables - TYPE(AA_InputFile), INTENT(IN) :: InputFileData ! Input-file data - TYPE(AA_ParameterType), INTENT(IN) :: p ! Parameters - TYPE(AA_InputType), INTENT(IN) :: u ! inputs - TYPE(AA_OutputType), INTENT(IN) :: y ! outputs - INTEGER(IntKi), INTENT(OUT) :: ErrStat - CHARACTER(*), INTENT(OUT) :: ErrMsg - ! Local variables. - INTEGER(IntKi) :: I ! Index for the nodes. - INTEGER(IntKi) :: UnSu ! I/O unit number for the summary output file - CHARACTER(*), PARAMETER :: FmtDat = '(A,T35,1(:,F13.3))' ! Format for outputting mass and modal data. - CHARACTER(*), PARAMETER :: FmtDatT = '(A,T35,1(:,F13.8))' ! Format for outputting time steps. - CHARACTER(30) :: OutPFmt ! Format to print list of selected output channels to summary file - CHARACTER(100) :: Msg ! temporary string for writing appropriate text to summary file - ! Open the summary file and give it a heading. - ErrStat = ErrID_None - ErrMsg = "" - RETURN -END SUBROUTINE AA_PrintSum -!.................................................................................................................................. !> This subroutine sets the initialization output data structure, which contains data to be returned to the calling program (e.g., !! FAST or AeroAcoustics_Driver) -subroutine AA_SetInitOut(p, InputFileData, InitOut, errStat, errMsg) +subroutine AA_SetInitOut(p, InitOut, errStat, errMsg) type(AA_InitOutputType), intent( out) :: InitOut ! output data - type(AA_InputFile), intent(in ) :: InputFileData ! input file data (for setting airfoil shape outputs) type(AA_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 @@ -587,9 +547,7 @@ subroutine AA_SetInitOut(p, InputFileData, InitOut, errStat, errMsg) integer(intKi) :: ErrStat2 ! temporary Error status character(ErrMsgLen) :: ErrMsg2 ! temporary Error message character(*), parameter :: RoutineName = 'AA_SetInitOut' - integer(IntKi) :: i, j, k,m,oi - integer(IntKi) :: NumCoords - character(500) :: chanPrefix + integer(IntKi) :: i, j, k,oi ! Initialize variables for this routine errStat = ErrID_None errMsg = "" @@ -668,8 +626,7 @@ subroutine AA_InitializeOutputFile(p, InputFileData,InitOut,errStat, errMsg) ! locals integer(IntKi) :: i integer(IntKi) :: numOuts - character(200) :: frmt ! A string to hold a format specifier - character(15) :: tmpStr ! temporary string to print the time output as text + ! FIRST FILE IF (InputFileData%NrOutFile .gt.0) THEN call GetNewUnit( p%unOutFile, ErrStat, ErrMsg ) @@ -880,8 +837,8 @@ SUBROUTINE Calc_WriteOutput( p, u, m, y, ErrStat, ErrMsg ) CHARACTER(*), INTENT( OUT) :: ErrMsg ! The error message, if an error occurred ! local variables CHARACTER(*), PARAMETER :: RoutineName = 'Calc_WriteOutput' - INTEGER(intKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 +! INTEGER(intKi) :: ErrStat2 +! CHARACTER(ErrMsgLen) :: ErrMsg2 INTEGER(IntKi) :: j,k,counter,i,oi,III ! start routine: ErrStat = ErrID_None diff --git a/modules/aerodyn/src/AeroAcoustics_TNO.f90 b/modules/aerodyn/src/AeroAcoustics_TNO.f90 index a2d9ab2b8..761f45ad1 100644 --- a/modules/aerodyn/src/AeroAcoustics_TNO.f90 +++ b/modules/aerodyn/src/AeroAcoustics_TNO.f90 @@ -169,7 +169,6 @@ END FUNCTION f_int2 FUNCTION Pressure(k1_in) ! Variables REAL(TNOKi) :: a,b,answer - REAL(TNOKi) :: omega REAL(TNOKi) :: abserr,resabs,resasc REAL(TNOKi) :: k1_in real(TNOKi) :: Pressure @@ -189,7 +188,7 @@ FUNCTION Pressure(k1_in) CALL slatec_qk61(f_int1,a,b,answer,abserr,resabs,resasc) - Pressure = 4.*rho**2*k1**2./(k1**2.+k3**2.)*answer + Pressure = 4.0_TNOKi*rho**2 * k1**2 / (k1**2 + k3**2)*answer RETURN END FUNCTION Pressure diff --git a/modules/aerodyn/src/AeroAcoustics_Types.f90 b/modules/aerodyn/src/AeroAcoustics_Types.f90 index 21b3557bc..8a702ba2f 100644 --- a/modules/aerodyn/src/AeroAcoustics_Types.f90 +++ b/modules/aerodyn/src/AeroAcoustics_Types.f90 @@ -300,15 +300,27 @@ SUBROUTINE AA_CopyBladePropsType( SrcBladePropsTypeData, DstBladePropsTypeData, DstBladePropsTypeData%TEAngle = SrcBladePropsTypeData%TEAngle END SUBROUTINE AA_CopyBladePropsType - SUBROUTINE AA_DestroyBladePropsType( BladePropsTypeData, ErrStat, ErrMsg ) + SUBROUTINE AA_DestroyBladePropsType( BladePropsTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AA_BladePropsType), INTENT(INOUT) :: BladePropsTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyBladePropsType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyBladePropsType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AA_DestroyBladePropsType SUBROUTINE AA_PackBladePropsType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -501,15 +513,27 @@ SUBROUTINE AA_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrSt ENDIF END SUBROUTINE AA_CopyInitInput - SUBROUTINE AA_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE AA_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AA_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%BlSpn)) THEN DEALLOCATE(InitInputData%BlSpn) ENDIF @@ -521,7 +545,8 @@ SUBROUTINE AA_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(InitInputData%AFInfo)) THEN DO i1 = LBOUND(InitInputData%AFInfo,1), UBOUND(InitInputData%AFInfo,1) - CALL AFI_DestroyParam( InitInputData%AFInfo(i1), ErrStat, ErrMsg ) + CALL AFI_DestroyParam( InitInputData%AFInfo(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%AFInfo) ENDIF @@ -1052,15 +1077,27 @@ SUBROUTINE AA_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, Er DstInitOutputData%AirDens = SrcInitOutputData%AirDens END SUBROUTINE AA_CopyInitOutput - SUBROUTINE AA_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE AA_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AA_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF @@ -1085,7 +1122,8 @@ SUBROUTINE AA_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) IF (ALLOCATED(InitOutputData%WriteOutputUntNodes)) THEN DEALLOCATE(InitOutputData%WriteOutputUntNodes) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AA_DestroyInitOutput SUBROUTINE AA_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1889,15 +1927,27 @@ SUBROUTINE AA_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrSt DstInputFileData%dy_turb_in = SrcInputFileData%dy_turb_in END SUBROUTINE AA_CopyInputFile - SUBROUTINE AA_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) + SUBROUTINE AA_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AA_InputFile), INTENT(INOUT) :: InputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyInputFile' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyInputFile' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputFileData%ObsX)) THEN DEALLOCATE(InputFileData%ObsX) ENDIF @@ -1909,7 +1959,8 @@ SUBROUTINE AA_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(InputFileData%BladeProps)) THEN DO i1 = LBOUND(InputFileData%BladeProps,1), UBOUND(InputFileData%BladeProps,1) - CALL AA_Destroybladepropstype( InputFileData%BladeProps(i1), ErrStat, ErrMsg ) + CALL AA_Destroybladepropstype( InputFileData%BladeProps(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InputFileData%BladeProps) ENDIF @@ -3051,15 +3102,27 @@ SUBROUTINE AA_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrSt DstContStateData%DummyContState = SrcContStateData%DummyContState END SUBROUTINE AA_CopyContState - SUBROUTINE AA_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE AA_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AA_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AA_DestroyContState SUBROUTINE AA_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -3336,15 +3399,27 @@ SUBROUTINE AA_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt ENDIF END SUBROUTINE AA_CopyDiscState - SUBROUTINE AA_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE AA_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AA_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(DiscStateData%MeanVrel)) THEN DEALLOCATE(DiscStateData%MeanVrel) ENDIF @@ -4040,15 +4115,27 @@ SUBROUTINE AA_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE AA_CopyConstrState - SUBROUTINE AA_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE AA_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AA_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AA_DestroyConstrState SUBROUTINE AA_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -4165,15 +4252,27 @@ SUBROUTINE AA_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, Er DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState END SUBROUTINE AA_CopyOtherState - SUBROUTINE AA_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE AA_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AA_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AA_DestroyOtherState SUBROUTINE AA_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -4575,15 +4674,27 @@ SUBROUTINE AA_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%filesopen = SrcMiscData%filesopen END SUBROUTINE AA_CopyMisc - SUBROUTINE AA_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE AA_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AA_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%AllOuts)) THEN DEALLOCATE(MiscData%AllOuts) ENDIF @@ -6213,15 +6324,27 @@ SUBROUTINE AA_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) ENDIF END SUBROUTINE AA_CopyParam - SUBROUTINE AA_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE AA_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AA_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%rotorregionlimitsVert)) THEN DEALLOCATE(ParamData%rotorregionlimitsVert) ENDIF @@ -6254,7 +6377,8 @@ SUBROUTINE AA_DestroyParam( ParamData, ErrStat, ErrMsg ) 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 ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF @@ -6275,7 +6399,8 @@ SUBROUTINE AA_DestroyParam( ParamData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(ParamData%AFInfo)) THEN DO i1 = LBOUND(ParamData%AFInfo,1), UBOUND(ParamData%AFInfo,1) - CALL AFI_DestroyParam( ParamData%AFInfo(i1), ErrStat, ErrMsg ) + CALL AFI_DestroyParam( ParamData%AFInfo(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%AFInfo) ENDIF @@ -8441,15 +8566,27 @@ SUBROUTINE AA_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) ENDIF END SUBROUTINE AA_CopyInput - SUBROUTINE AA_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE AA_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AA_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%RotGtoL)) THEN DEALLOCATE(InputData%RotGtoL) ENDIF @@ -9021,15 +9158,27 @@ SUBROUTINE AA_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs ENDIF END SUBROUTINE AA_CopyOutput - SUBROUTINE AA_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE AA_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AA_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AA_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%SumSpecNoise)) THEN DEALLOCATE(OutputData%SumSpecNoise) ENDIF @@ -9709,633 +9858,5 @@ SUBROUTINE AA_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END IF END SUBROUTINE AA_UnPackOutput - - SUBROUTINE AA_Input_ExtrapInterp(u, t, u_out, t_out, ErrStat, ErrMsg ) -! -! This subroutine calculates a extrapolated (or interpolated) Input u_out at time t_out, from previous/future time -! values of u (which has values associated with times in t). Order of the interpolation is given by the size of u -! -! expressions below based on either -! -! f(t) = a -! f(t) = a + b * t, or -! f(t) = a + b * t + c * t**2 -! -! where a, b and c are determined as the solution to -! f(t1) = u1, f(t2) = u2, f(t3) = u3 (as appropriate) -! -!.................................................................................................................................. - - TYPE(AA_InputType), INTENT(IN) :: u(:) ! Input at t1 > t2 > t3 - REAL(DbKi), INTENT(IN ) :: t(:) ! Times associated with the Inputs - TYPE(AA_InputType), INTENT(INOUT) :: u_out ! Input at tin_out - REAL(DbKi), INTENT(IN ) :: t_out ! time to be extrap/interp'd to - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - ! local variables - INTEGER(IntKi) :: order ! order of polynomial fit (max 2) - INTEGER(IntKi) :: ErrStat2 ! local errors - CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors - CHARACTER(*), PARAMETER :: RoutineName = 'AA_Input_ExtrapInterp' - ! Initialize ErrStat - ErrStat = ErrID_None - ErrMsg = "" - if ( size(t) .ne. size(u)) then - CALL SetErrStat(ErrID_Fatal,'size(t) must equal size(u)',ErrStat,ErrMsg,RoutineName) - RETURN - endif - order = SIZE(u) - 1 - IF ( order .eq. 0 ) THEN - CALL AA_CopyInput(u(1), u_out, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - ELSE IF ( order .eq. 1 ) THEN - CALL AA_Input_ExtrapInterp1(u(1), u(2), t, u_out, t_out, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - ELSE IF ( order .eq. 2 ) THEN - CALL AA_Input_ExtrapInterp2(u(1), u(2), u(3), t, u_out, t_out, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - ELSE - CALL SetErrStat(ErrID_Fatal,'size(u) must be less than 4 (order must be less than 3).',ErrStat,ErrMsg,RoutineName) - RETURN - ENDIF - END SUBROUTINE AA_Input_ExtrapInterp - - - SUBROUTINE AA_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg ) -! -! This subroutine calculates a extrapolated (or interpolated) Input u_out at time t_out, from previous/future time -! values of u (which has values associated with times in t). Order of the interpolation is 1. -! -! f(t) = a + b * t, or -! -! where a and b are determined as the solution to -! f(t1) = u1, f(t2) = u2 -! -!.................................................................................................................................. - - TYPE(AA_InputType), INTENT(IN) :: u1 ! Input at t1 > t2 - TYPE(AA_InputType), INTENT(IN) :: u2 ! Input at t2 - REAL(DbKi), INTENT(IN ) :: tin(2) ! Times associated with the Inputs - TYPE(AA_InputType), INTENT(INOUT) :: u_out ! Input at tin_out - REAL(DbKi), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - ! local variables - REAL(DbKi) :: t(2) ! Times associated with the Inputs - REAL(DbKi) :: t_out ! Time to which to be extrap/interpd - CHARACTER(*), PARAMETER :: RoutineName = 'AA_Input_ExtrapInterp1' - REAL(DbKi) :: b ! temporary for extrapolation/interpolation - REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation - INTEGER(IntKi) :: ErrStat2 ! local errors - CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors - INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts - INTEGER :: i02 ! dim2 level 0 counter variable for arrays of ddts - INTEGER :: i03 ! dim3 level 0 counter variable for arrays of ddts - INTEGER :: i04 ! dim4 level 0 counter variable for arrays of ddts - INTEGER :: i1 ! dim1 counter variable for arrays - INTEGER :: i2 ! dim2 counter variable for arrays - INTEGER :: i3 ! dim3 counter variable for arrays - INTEGER :: i4 ! dim4 counter variable for arrays - ! Initialize ErrStat - ErrStat = ErrID_None - ErrMsg = "" - ! we'll subtract a constant from the times to resolve some - ! numerical issues when t gets large (and to simplify the equations) - t = tin - tin(1) - t_out = tin_out - tin(1) - - IF ( EqualRealNos( t(1), t(2) ) ) THEN - CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - - ScaleFactor = t_out / t(2) -IF (ALLOCATED(u_out%RotGtoL) .AND. ALLOCATED(u1%RotGtoL)) THEN - DO i4 = LBOUND(u_out%RotGtoL,4),UBOUND(u_out%RotGtoL,4) - DO i3 = LBOUND(u_out%RotGtoL,3),UBOUND(u_out%RotGtoL,3) - DO i2 = LBOUND(u_out%RotGtoL,2),UBOUND(u_out%RotGtoL,2) - DO i1 = LBOUND(u_out%RotGtoL,1),UBOUND(u_out%RotGtoL,1) - b = -(u1%RotGtoL(i1,i2,i3,i4) - u2%RotGtoL(i1,i2,i3,i4)) - u_out%RotGtoL(i1,i2,i3,i4) = u1%RotGtoL(i1,i2,i3,i4) + b * ScaleFactor - END DO - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(u_out%AeroCent_G) .AND. ALLOCATED(u1%AeroCent_G)) THEN - DO i3 = LBOUND(u_out%AeroCent_G,3),UBOUND(u_out%AeroCent_G,3) - DO i2 = LBOUND(u_out%AeroCent_G,2),UBOUND(u_out%AeroCent_G,2) - DO i1 = LBOUND(u_out%AeroCent_G,1),UBOUND(u_out%AeroCent_G,1) - b = -(u1%AeroCent_G(i1,i2,i3) - u2%AeroCent_G(i1,i2,i3)) - u_out%AeroCent_G(i1,i2,i3) = u1%AeroCent_G(i1,i2,i3) + b * ScaleFactor - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(u_out%Vrel) .AND. ALLOCATED(u1%Vrel)) THEN - DO i2 = LBOUND(u_out%Vrel,2),UBOUND(u_out%Vrel,2) - DO i1 = LBOUND(u_out%Vrel,1),UBOUND(u_out%Vrel,1) - b = -(u1%Vrel(i1,i2) - u2%Vrel(i1,i2)) - u_out%Vrel(i1,i2) = u1%Vrel(i1,i2) + b * ScaleFactor - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(u_out%AoANoise) .AND. ALLOCATED(u1%AoANoise)) THEN - DO i2 = LBOUND(u_out%AoANoise,2),UBOUND(u_out%AoANoise,2) - DO i1 = LBOUND(u_out%AoANoise,1),UBOUND(u_out%AoANoise,1) - b = -(u1%AoANoise(i1,i2) - u2%AoANoise(i1,i2)) - u_out%AoANoise(i1,i2) = u1%AoANoise(i1,i2) + b * ScaleFactor - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(u_out%Inflow) .AND. ALLOCATED(u1%Inflow)) THEN - DO i3 = LBOUND(u_out%Inflow,3),UBOUND(u_out%Inflow,3) - DO i2 = LBOUND(u_out%Inflow,2),UBOUND(u_out%Inflow,2) - DO i1 = LBOUND(u_out%Inflow,1),UBOUND(u_out%Inflow,1) - b = -(u1%Inflow(i1,i2,i3) - u2%Inflow(i1,i2,i3)) - u_out%Inflow(i1,i2,i3) = u1%Inflow(i1,i2,i3) + b * ScaleFactor - END DO - END DO - END DO -END IF ! check if allocated - END SUBROUTINE AA_Input_ExtrapInterp1 - - - SUBROUTINE AA_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, ErrMsg ) -! -! This subroutine calculates a extrapolated (or interpolated) Input u_out at time t_out, from previous/future time -! values of u (which has values associated with times in t). Order of the interpolation is 2. -! -! expressions below based on either -! -! f(t) = a + b * t + c * t**2 -! -! where a, b and c are determined as the solution to -! f(t1) = u1, f(t2) = u2, f(t3) = u3 -! -!.................................................................................................................................. - - TYPE(AA_InputType), INTENT(IN) :: u1 ! Input at t1 > t2 > t3 - TYPE(AA_InputType), INTENT(IN) :: u2 ! Input at t2 > t3 - TYPE(AA_InputType), INTENT(IN) :: u3 ! Input at t3 - REAL(DbKi), INTENT(IN ) :: tin(3) ! Times associated with the Inputs - TYPE(AA_InputType), INTENT(INOUT) :: u_out ! Input at tin_out - REAL(DbKi), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - ! local variables - REAL(DbKi) :: t(3) ! Times associated with the Inputs - REAL(DbKi) :: t_out ! Time to which to be extrap/interpd - INTEGER(IntKi) :: order ! order of polynomial fit (max 2) - REAL(DbKi) :: b ! temporary for extrapolation/interpolation - REAL(DbKi) :: c ! temporary for extrapolation/interpolation - REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation - INTEGER(IntKi) :: ErrStat2 ! local errors - CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors - CHARACTER(*), PARAMETER :: RoutineName = 'AA_Input_ExtrapInterp2' - INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts - INTEGER :: i02 ! dim2 level 0 counter variable for arrays of ddts - INTEGER :: i03 ! dim3 level 0 counter variable for arrays of ddts - INTEGER :: i04 ! dim4 level 0 counter variable for arrays of ddts - INTEGER :: i1 ! dim1 counter variable for arrays - INTEGER :: i2 ! dim2 counter variable for arrays - INTEGER :: i3 ! dim3 counter variable for arrays - INTEGER :: i4 ! dim4 counter variable for arrays - ! Initialize ErrStat - ErrStat = ErrID_None - ErrMsg = "" - ! we'll subtract a constant from the times to resolve some - ! numerical issues when t gets large (and to simplify the equations) - t = tin - tin(1) - t_out = tin_out - tin(1) - - IF ( EqualRealNos( t(1), t(2) ) ) THEN - CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) - RETURN - ELSE IF ( EqualRealNos( t(2), t(3) ) ) THEN - CALL SetErrStat(ErrID_Fatal, 't(2) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) - RETURN - ELSE IF ( EqualRealNos( t(1), t(3) ) ) THEN - CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - - ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) -IF (ALLOCATED(u_out%RotGtoL) .AND. ALLOCATED(u1%RotGtoL)) THEN - DO i4 = LBOUND(u_out%RotGtoL,4),UBOUND(u_out%RotGtoL,4) - DO i3 = LBOUND(u_out%RotGtoL,3),UBOUND(u_out%RotGtoL,3) - DO i2 = LBOUND(u_out%RotGtoL,2),UBOUND(u_out%RotGtoL,2) - DO i1 = LBOUND(u_out%RotGtoL,1),UBOUND(u_out%RotGtoL,1) - b = (t(3)**2*(u1%RotGtoL(i1,i2,i3,i4) - u2%RotGtoL(i1,i2,i3,i4)) + t(2)**2*(-u1%RotGtoL(i1,i2,i3,i4) + u3%RotGtoL(i1,i2,i3,i4)))* scaleFactor - c = ( (t(2)-t(3))*u1%RotGtoL(i1,i2,i3,i4) + t(3)*u2%RotGtoL(i1,i2,i3,i4) - t(2)*u3%RotGtoL(i1,i2,i3,i4) ) * scaleFactor - u_out%RotGtoL(i1,i2,i3,i4) = u1%RotGtoL(i1,i2,i3,i4) + b + c * t_out - END DO - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(u_out%AeroCent_G) .AND. ALLOCATED(u1%AeroCent_G)) THEN - DO i3 = LBOUND(u_out%AeroCent_G,3),UBOUND(u_out%AeroCent_G,3) - DO i2 = LBOUND(u_out%AeroCent_G,2),UBOUND(u_out%AeroCent_G,2) - DO i1 = LBOUND(u_out%AeroCent_G,1),UBOUND(u_out%AeroCent_G,1) - b = (t(3)**2*(u1%AeroCent_G(i1,i2,i3) - u2%AeroCent_G(i1,i2,i3)) + t(2)**2*(-u1%AeroCent_G(i1,i2,i3) + u3%AeroCent_G(i1,i2,i3)))* scaleFactor - c = ( (t(2)-t(3))*u1%AeroCent_G(i1,i2,i3) + t(3)*u2%AeroCent_G(i1,i2,i3) - t(2)*u3%AeroCent_G(i1,i2,i3) ) * scaleFactor - u_out%AeroCent_G(i1,i2,i3) = u1%AeroCent_G(i1,i2,i3) + b + c * t_out - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(u_out%Vrel) .AND. ALLOCATED(u1%Vrel)) THEN - DO i2 = LBOUND(u_out%Vrel,2),UBOUND(u_out%Vrel,2) - DO i1 = LBOUND(u_out%Vrel,1),UBOUND(u_out%Vrel,1) - b = (t(3)**2*(u1%Vrel(i1,i2) - u2%Vrel(i1,i2)) + t(2)**2*(-u1%Vrel(i1,i2) + u3%Vrel(i1,i2)))* scaleFactor - c = ( (t(2)-t(3))*u1%Vrel(i1,i2) + t(3)*u2%Vrel(i1,i2) - t(2)*u3%Vrel(i1,i2) ) * scaleFactor - u_out%Vrel(i1,i2) = u1%Vrel(i1,i2) + b + c * t_out - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(u_out%AoANoise) .AND. ALLOCATED(u1%AoANoise)) THEN - DO i2 = LBOUND(u_out%AoANoise,2),UBOUND(u_out%AoANoise,2) - DO i1 = LBOUND(u_out%AoANoise,1),UBOUND(u_out%AoANoise,1) - b = (t(3)**2*(u1%AoANoise(i1,i2) - u2%AoANoise(i1,i2)) + t(2)**2*(-u1%AoANoise(i1,i2) + u3%AoANoise(i1,i2)))* scaleFactor - c = ( (t(2)-t(3))*u1%AoANoise(i1,i2) + t(3)*u2%AoANoise(i1,i2) - t(2)*u3%AoANoise(i1,i2) ) * scaleFactor - u_out%AoANoise(i1,i2) = u1%AoANoise(i1,i2) + b + c * t_out - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(u_out%Inflow) .AND. ALLOCATED(u1%Inflow)) THEN - DO i3 = LBOUND(u_out%Inflow,3),UBOUND(u_out%Inflow,3) - DO i2 = LBOUND(u_out%Inflow,2),UBOUND(u_out%Inflow,2) - DO i1 = LBOUND(u_out%Inflow,1),UBOUND(u_out%Inflow,1) - b = (t(3)**2*(u1%Inflow(i1,i2,i3) - u2%Inflow(i1,i2,i3)) + t(2)**2*(-u1%Inflow(i1,i2,i3) + u3%Inflow(i1,i2,i3)))* scaleFactor - c = ( (t(2)-t(3))*u1%Inflow(i1,i2,i3) + t(3)*u2%Inflow(i1,i2,i3) - t(2)*u3%Inflow(i1,i2,i3) ) * scaleFactor - u_out%Inflow(i1,i2,i3) = u1%Inflow(i1,i2,i3) + b + c * t_out - END DO - END DO - END DO -END IF ! check if allocated - END SUBROUTINE AA_Input_ExtrapInterp2 - - - SUBROUTINE AA_Output_ExtrapInterp(y, t, y_out, t_out, ErrStat, ErrMsg ) -! -! This subroutine calculates a extrapolated (or interpolated) Output y_out at time t_out, from previous/future time -! values of y (which has values associated with times in t). Order of the interpolation is given by the size of y -! -! expressions below based on either -! -! f(t) = a -! f(t) = a + b * t, or -! f(t) = a + b * t + c * t**2 -! -! where a, b and c are determined as the solution to -! f(t1) = y1, f(t2) = y2, f(t3) = y3 (as appropriate) -! -!.................................................................................................................................. - - TYPE(AA_OutputType), INTENT(IN) :: y(:) ! Output at t1 > t2 > t3 - REAL(DbKi), INTENT(IN ) :: t(:) ! Times associated with the Outputs - TYPE(AA_OutputType), INTENT(INOUT) :: y_out ! Output at tin_out - REAL(DbKi), INTENT(IN ) :: t_out ! time to be extrap/interp'd to - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - ! local variables - INTEGER(IntKi) :: order ! order of polynomial fit (max 2) - INTEGER(IntKi) :: ErrStat2 ! local errors - CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors - CHARACTER(*), PARAMETER :: RoutineName = 'AA_Output_ExtrapInterp' - ! Initialize ErrStat - ErrStat = ErrID_None - ErrMsg = "" - if ( size(t) .ne. size(y)) then - CALL SetErrStat(ErrID_Fatal,'size(t) must equal size(y)',ErrStat,ErrMsg,RoutineName) - RETURN - endif - order = SIZE(y) - 1 - IF ( order .eq. 0 ) THEN - CALL AA_CopyOutput(y(1), y_out, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - ELSE IF ( order .eq. 1 ) THEN - CALL AA_Output_ExtrapInterp1(y(1), y(2), t, y_out, t_out, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - ELSE IF ( order .eq. 2 ) THEN - CALL AA_Output_ExtrapInterp2(y(1), y(2), y(3), t, y_out, t_out, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - ELSE - CALL SetErrStat(ErrID_Fatal,'size(y) must be less than 4 (order must be less than 3).',ErrStat,ErrMsg,RoutineName) - RETURN - ENDIF - END SUBROUTINE AA_Output_ExtrapInterp - - - SUBROUTINE AA_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, ErrMsg ) -! -! This subroutine calculates a extrapolated (or interpolated) Output y_out at time t_out, from previous/future time -! values of y (which has values associated with times in t). Order of the interpolation is 1. -! -! f(t) = a + b * t, or -! -! where a and b are determined as the solution to -! f(t1) = y1, f(t2) = y2 -! -!.................................................................................................................................. - - TYPE(AA_OutputType), INTENT(IN) :: y1 ! Output at t1 > t2 - TYPE(AA_OutputType), INTENT(IN) :: y2 ! Output at t2 - REAL(DbKi), INTENT(IN ) :: tin(2) ! Times associated with the Outputs - TYPE(AA_OutputType), INTENT(INOUT) :: y_out ! Output at tin_out - REAL(DbKi), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - ! local variables - REAL(DbKi) :: t(2) ! Times associated with the Outputs - REAL(DbKi) :: t_out ! Time to which to be extrap/interpd - CHARACTER(*), PARAMETER :: RoutineName = 'AA_Output_ExtrapInterp1' - REAL(DbKi) :: b ! temporary for extrapolation/interpolation - REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation - INTEGER(IntKi) :: ErrStat2 ! local errors - CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors - INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts - INTEGER :: i02 ! dim2 level 0 counter variable for arrays of ddts - INTEGER :: i03 ! dim3 level 0 counter variable for arrays of ddts - INTEGER :: i04 ! dim4 level 0 counter variable for arrays of ddts - INTEGER :: i1 ! dim1 counter variable for arrays - INTEGER :: i2 ! dim2 counter variable for arrays - INTEGER :: i3 ! dim3 counter variable for arrays - INTEGER :: i4 ! dim4 counter variable for arrays - ! Initialize ErrStat - ErrStat = ErrID_None - ErrMsg = "" - ! we'll subtract a constant from the times to resolve some - ! numerical issues when t gets large (and to simplify the equations) - t = tin - tin(1) - t_out = tin_out - tin(1) - - IF ( EqualRealNos( t(1), t(2) ) ) THEN - CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - - ScaleFactor = t_out / t(2) -IF (ALLOCATED(y_out%SumSpecNoise) .AND. ALLOCATED(y1%SumSpecNoise)) THEN - DO i3 = LBOUND(y_out%SumSpecNoise,3),UBOUND(y_out%SumSpecNoise,3) - DO i2 = LBOUND(y_out%SumSpecNoise,2),UBOUND(y_out%SumSpecNoise,2) - DO i1 = LBOUND(y_out%SumSpecNoise,1),UBOUND(y_out%SumSpecNoise,1) - b = -(y1%SumSpecNoise(i1,i2,i3) - y2%SumSpecNoise(i1,i2,i3)) - y_out%SumSpecNoise(i1,i2,i3) = y1%SumSpecNoise(i1,i2,i3) + b * ScaleFactor - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%SumSpecNoiseSep) .AND. ALLOCATED(y1%SumSpecNoiseSep)) THEN - DO i3 = LBOUND(y_out%SumSpecNoiseSep,3),UBOUND(y_out%SumSpecNoiseSep,3) - DO i2 = LBOUND(y_out%SumSpecNoiseSep,2),UBOUND(y_out%SumSpecNoiseSep,2) - DO i1 = LBOUND(y_out%SumSpecNoiseSep,1),UBOUND(y_out%SumSpecNoiseSep,1) - b = -(y1%SumSpecNoiseSep(i1,i2,i3) - y2%SumSpecNoiseSep(i1,i2,i3)) - y_out%SumSpecNoiseSep(i1,i2,i3) = y1%SumSpecNoiseSep(i1,i2,i3) + b * ScaleFactor - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%OASPL) .AND. ALLOCATED(y1%OASPL)) THEN - DO i3 = LBOUND(y_out%OASPL,3),UBOUND(y_out%OASPL,3) - DO i2 = LBOUND(y_out%OASPL,2),UBOUND(y_out%OASPL,2) - DO i1 = LBOUND(y_out%OASPL,1),UBOUND(y_out%OASPL,1) - b = -(y1%OASPL(i1,i2,i3) - y2%OASPL(i1,i2,i3)) - y_out%OASPL(i1,i2,i3) = y1%OASPL(i1,i2,i3) + b * ScaleFactor - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%OASPL_Mech) .AND. ALLOCATED(y1%OASPL_Mech)) THEN - DO i4 = LBOUND(y_out%OASPL_Mech,4),UBOUND(y_out%OASPL_Mech,4) - DO i3 = LBOUND(y_out%OASPL_Mech,3),UBOUND(y_out%OASPL_Mech,3) - DO i2 = LBOUND(y_out%OASPL_Mech,2),UBOUND(y_out%OASPL_Mech,2) - DO i1 = LBOUND(y_out%OASPL_Mech,1),UBOUND(y_out%OASPL_Mech,1) - b = -(y1%OASPL_Mech(i1,i2,i3,i4) - y2%OASPL_Mech(i1,i2,i3,i4)) - y_out%OASPL_Mech(i1,i2,i3,i4) = y1%OASPL_Mech(i1,i2,i3,i4) + b * ScaleFactor - END DO - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%DirectiviOutput) .AND. ALLOCATED(y1%DirectiviOutput)) THEN - DO i1 = LBOUND(y_out%DirectiviOutput,1),UBOUND(y_out%DirectiviOutput,1) - b = -(y1%DirectiviOutput(i1) - y2%DirectiviOutput(i1)) - y_out%DirectiviOutput(i1) = y1%DirectiviOutput(i1) + b * ScaleFactor - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%OutLECoords) .AND. ALLOCATED(y1%OutLECoords)) THEN - DO i4 = LBOUND(y_out%OutLECoords,4),UBOUND(y_out%OutLECoords,4) - DO i3 = LBOUND(y_out%OutLECoords,3),UBOUND(y_out%OutLECoords,3) - DO i2 = LBOUND(y_out%OutLECoords,2),UBOUND(y_out%OutLECoords,2) - DO i1 = LBOUND(y_out%OutLECoords,1),UBOUND(y_out%OutLECoords,1) - b = -(y1%OutLECoords(i1,i2,i3,i4) - y2%OutLECoords(i1,i2,i3,i4)) - y_out%OutLECoords(i1,i2,i3,i4) = y1%OutLECoords(i1,i2,i3,i4) + b * ScaleFactor - END DO - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%PtotalFreq) .AND. ALLOCATED(y1%PtotalFreq)) THEN - DO i2 = LBOUND(y_out%PtotalFreq,2),UBOUND(y_out%PtotalFreq,2) - DO i1 = LBOUND(y_out%PtotalFreq,1),UBOUND(y_out%PtotalFreq,1) - b = -(y1%PtotalFreq(i1,i2) - y2%PtotalFreq(i1,i2)) - y_out%PtotalFreq(i1,i2) = y1%PtotalFreq(i1,i2) + b * ScaleFactor - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%WriteOutputForPE) .AND. ALLOCATED(y1%WriteOutputForPE)) THEN - DO i1 = LBOUND(y_out%WriteOutputForPE,1),UBOUND(y_out%WriteOutputForPE,1) - b = -(y1%WriteOutputForPE(i1) - y2%WriteOutputForPE(i1)) - y_out%WriteOutputForPE(i1) = y1%WriteOutputForPE(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 -IF (ALLOCATED(y_out%WriteOutputSep) .AND. ALLOCATED(y1%WriteOutputSep)) THEN - DO i1 = LBOUND(y_out%WriteOutputSep,1),UBOUND(y_out%WriteOutputSep,1) - b = -(y1%WriteOutputSep(i1) - y2%WriteOutputSep(i1)) - y_out%WriteOutputSep(i1) = y1%WriteOutputSep(i1) + b * ScaleFactor - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%WriteOutputNode) .AND. ALLOCATED(y1%WriteOutputNode)) THEN - DO i1 = LBOUND(y_out%WriteOutputNode,1),UBOUND(y_out%WriteOutputNode,1) - b = -(y1%WriteOutputNode(i1) - y2%WriteOutputNode(i1)) - y_out%WriteOutputNode(i1) = y1%WriteOutputNode(i1) + b * ScaleFactor - END DO -END IF ! check if allocated - END SUBROUTINE AA_Output_ExtrapInterp1 - - - SUBROUTINE AA_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, ErrMsg ) -! -! This subroutine calculates a extrapolated (or interpolated) Output y_out at time t_out, from previous/future time -! values of y (which has values associated with times in t). Order of the interpolation is 2. -! -! expressions below based on either -! -! f(t) = a + b * t + c * t**2 -! -! where a, b and c are determined as the solution to -! f(t1) = y1, f(t2) = y2, f(t3) = y3 -! -!.................................................................................................................................. - - TYPE(AA_OutputType), INTENT(IN) :: y1 ! Output at t1 > t2 > t3 - TYPE(AA_OutputType), INTENT(IN) :: y2 ! Output at t2 > t3 - TYPE(AA_OutputType), INTENT(IN) :: y3 ! Output at t3 - REAL(DbKi), INTENT(IN ) :: tin(3) ! Times associated with the Outputs - TYPE(AA_OutputType), INTENT(INOUT) :: y_out ! Output at tin_out - REAL(DbKi), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - ! local variables - REAL(DbKi) :: t(3) ! Times associated with the Outputs - REAL(DbKi) :: t_out ! Time to which to be extrap/interpd - INTEGER(IntKi) :: order ! order of polynomial fit (max 2) - REAL(DbKi) :: b ! temporary for extrapolation/interpolation - REAL(DbKi) :: c ! temporary for extrapolation/interpolation - REAL(DbKi) :: ScaleFactor ! temporary for extrapolation/interpolation - INTEGER(IntKi) :: ErrStat2 ! local errors - CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors - CHARACTER(*), PARAMETER :: RoutineName = 'AA_Output_ExtrapInterp2' - INTEGER :: i01 ! dim1 level 0 counter variable for arrays of ddts - INTEGER :: i02 ! dim2 level 0 counter variable for arrays of ddts - INTEGER :: i03 ! dim3 level 0 counter variable for arrays of ddts - INTEGER :: i04 ! dim4 level 0 counter variable for arrays of ddts - INTEGER :: i1 ! dim1 counter variable for arrays - INTEGER :: i2 ! dim2 counter variable for arrays - INTEGER :: i3 ! dim3 counter variable for arrays - INTEGER :: i4 ! dim4 counter variable for arrays - ! Initialize ErrStat - ErrStat = ErrID_None - ErrMsg = "" - ! we'll subtract a constant from the times to resolve some - ! numerical issues when t gets large (and to simplify the equations) - t = tin - tin(1) - t_out = tin_out - tin(1) - - IF ( EqualRealNos( t(1), t(2) ) ) THEN - CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) - RETURN - ELSE IF ( EqualRealNos( t(2), t(3) ) ) THEN - CALL SetErrStat(ErrID_Fatal, 't(2) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) - RETURN - ELSE IF ( EqualRealNos( t(1), t(3) ) ) THEN - CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - - ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) -IF (ALLOCATED(y_out%SumSpecNoise) .AND. ALLOCATED(y1%SumSpecNoise)) THEN - DO i3 = LBOUND(y_out%SumSpecNoise,3),UBOUND(y_out%SumSpecNoise,3) - DO i2 = LBOUND(y_out%SumSpecNoise,2),UBOUND(y_out%SumSpecNoise,2) - DO i1 = LBOUND(y_out%SumSpecNoise,1),UBOUND(y_out%SumSpecNoise,1) - b = (t(3)**2*(y1%SumSpecNoise(i1,i2,i3) - y2%SumSpecNoise(i1,i2,i3)) + t(2)**2*(-y1%SumSpecNoise(i1,i2,i3) + y3%SumSpecNoise(i1,i2,i3)))* scaleFactor - c = ( (t(2)-t(3))*y1%SumSpecNoise(i1,i2,i3) + t(3)*y2%SumSpecNoise(i1,i2,i3) - t(2)*y3%SumSpecNoise(i1,i2,i3) ) * scaleFactor - y_out%SumSpecNoise(i1,i2,i3) = y1%SumSpecNoise(i1,i2,i3) + b + c * t_out - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%SumSpecNoiseSep) .AND. ALLOCATED(y1%SumSpecNoiseSep)) THEN - DO i3 = LBOUND(y_out%SumSpecNoiseSep,3),UBOUND(y_out%SumSpecNoiseSep,3) - DO i2 = LBOUND(y_out%SumSpecNoiseSep,2),UBOUND(y_out%SumSpecNoiseSep,2) - DO i1 = LBOUND(y_out%SumSpecNoiseSep,1),UBOUND(y_out%SumSpecNoiseSep,1) - b = (t(3)**2*(y1%SumSpecNoiseSep(i1,i2,i3) - y2%SumSpecNoiseSep(i1,i2,i3)) + t(2)**2*(-y1%SumSpecNoiseSep(i1,i2,i3) + y3%SumSpecNoiseSep(i1,i2,i3)))* scaleFactor - c = ( (t(2)-t(3))*y1%SumSpecNoiseSep(i1,i2,i3) + t(3)*y2%SumSpecNoiseSep(i1,i2,i3) - t(2)*y3%SumSpecNoiseSep(i1,i2,i3) ) * scaleFactor - y_out%SumSpecNoiseSep(i1,i2,i3) = y1%SumSpecNoiseSep(i1,i2,i3) + b + c * t_out - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%OASPL) .AND. ALLOCATED(y1%OASPL)) THEN - DO i3 = LBOUND(y_out%OASPL,3),UBOUND(y_out%OASPL,3) - DO i2 = LBOUND(y_out%OASPL,2),UBOUND(y_out%OASPL,2) - DO i1 = LBOUND(y_out%OASPL,1),UBOUND(y_out%OASPL,1) - b = (t(3)**2*(y1%OASPL(i1,i2,i3) - y2%OASPL(i1,i2,i3)) + t(2)**2*(-y1%OASPL(i1,i2,i3) + y3%OASPL(i1,i2,i3)))* scaleFactor - c = ( (t(2)-t(3))*y1%OASPL(i1,i2,i3) + t(3)*y2%OASPL(i1,i2,i3) - t(2)*y3%OASPL(i1,i2,i3) ) * scaleFactor - y_out%OASPL(i1,i2,i3) = y1%OASPL(i1,i2,i3) + b + c * t_out - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%OASPL_Mech) .AND. ALLOCATED(y1%OASPL_Mech)) THEN - DO i4 = LBOUND(y_out%OASPL_Mech,4),UBOUND(y_out%OASPL_Mech,4) - DO i3 = LBOUND(y_out%OASPL_Mech,3),UBOUND(y_out%OASPL_Mech,3) - DO i2 = LBOUND(y_out%OASPL_Mech,2),UBOUND(y_out%OASPL_Mech,2) - DO i1 = LBOUND(y_out%OASPL_Mech,1),UBOUND(y_out%OASPL_Mech,1) - b = (t(3)**2*(y1%OASPL_Mech(i1,i2,i3,i4) - y2%OASPL_Mech(i1,i2,i3,i4)) + t(2)**2*(-y1%OASPL_Mech(i1,i2,i3,i4) + y3%OASPL_Mech(i1,i2,i3,i4)))* scaleFactor - c = ( (t(2)-t(3))*y1%OASPL_Mech(i1,i2,i3,i4) + t(3)*y2%OASPL_Mech(i1,i2,i3,i4) - t(2)*y3%OASPL_Mech(i1,i2,i3,i4) ) * scaleFactor - y_out%OASPL_Mech(i1,i2,i3,i4) = y1%OASPL_Mech(i1,i2,i3,i4) + b + c * t_out - END DO - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%DirectiviOutput) .AND. ALLOCATED(y1%DirectiviOutput)) THEN - DO i1 = LBOUND(y_out%DirectiviOutput,1),UBOUND(y_out%DirectiviOutput,1) - b = (t(3)**2*(y1%DirectiviOutput(i1) - y2%DirectiviOutput(i1)) + t(2)**2*(-y1%DirectiviOutput(i1) + y3%DirectiviOutput(i1)))* scaleFactor - c = ( (t(2)-t(3))*y1%DirectiviOutput(i1) + t(3)*y2%DirectiviOutput(i1) - t(2)*y3%DirectiviOutput(i1) ) * scaleFactor - y_out%DirectiviOutput(i1) = y1%DirectiviOutput(i1) + b + c * t_out - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%OutLECoords) .AND. ALLOCATED(y1%OutLECoords)) THEN - DO i4 = LBOUND(y_out%OutLECoords,4),UBOUND(y_out%OutLECoords,4) - DO i3 = LBOUND(y_out%OutLECoords,3),UBOUND(y_out%OutLECoords,3) - DO i2 = LBOUND(y_out%OutLECoords,2),UBOUND(y_out%OutLECoords,2) - DO i1 = LBOUND(y_out%OutLECoords,1),UBOUND(y_out%OutLECoords,1) - b = (t(3)**2*(y1%OutLECoords(i1,i2,i3,i4) - y2%OutLECoords(i1,i2,i3,i4)) + t(2)**2*(-y1%OutLECoords(i1,i2,i3,i4) + y3%OutLECoords(i1,i2,i3,i4)))* scaleFactor - c = ( (t(2)-t(3))*y1%OutLECoords(i1,i2,i3,i4) + t(3)*y2%OutLECoords(i1,i2,i3,i4) - t(2)*y3%OutLECoords(i1,i2,i3,i4) ) * scaleFactor - y_out%OutLECoords(i1,i2,i3,i4) = y1%OutLECoords(i1,i2,i3,i4) + b + c * t_out - END DO - END DO - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%PtotalFreq) .AND. ALLOCATED(y1%PtotalFreq)) THEN - DO i2 = LBOUND(y_out%PtotalFreq,2),UBOUND(y_out%PtotalFreq,2) - DO i1 = LBOUND(y_out%PtotalFreq,1),UBOUND(y_out%PtotalFreq,1) - b = (t(3)**2*(y1%PtotalFreq(i1,i2) - y2%PtotalFreq(i1,i2)) + t(2)**2*(-y1%PtotalFreq(i1,i2) + y3%PtotalFreq(i1,i2)))* scaleFactor - c = ( (t(2)-t(3))*y1%PtotalFreq(i1,i2) + t(3)*y2%PtotalFreq(i1,i2) - t(2)*y3%PtotalFreq(i1,i2) ) * scaleFactor - y_out%PtotalFreq(i1,i2) = y1%PtotalFreq(i1,i2) + b + c * t_out - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%WriteOutputForPE) .AND. ALLOCATED(y1%WriteOutputForPE)) THEN - DO i1 = LBOUND(y_out%WriteOutputForPE,1),UBOUND(y_out%WriteOutputForPE,1) - b = (t(3)**2*(y1%WriteOutputForPE(i1) - y2%WriteOutputForPE(i1)) + t(2)**2*(-y1%WriteOutputForPE(i1) + y3%WriteOutputForPE(i1)))* scaleFactor - c = ( (t(2)-t(3))*y1%WriteOutputForPE(i1) + t(3)*y2%WriteOutputForPE(i1) - t(2)*y3%WriteOutputForPE(i1) ) * scaleFactor - y_out%WriteOutputForPE(i1) = y1%WriteOutputForPE(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 -IF (ALLOCATED(y_out%WriteOutputSep) .AND. ALLOCATED(y1%WriteOutputSep)) THEN - DO i1 = LBOUND(y_out%WriteOutputSep,1),UBOUND(y_out%WriteOutputSep,1) - b = (t(3)**2*(y1%WriteOutputSep(i1) - y2%WriteOutputSep(i1)) + t(2)**2*(-y1%WriteOutputSep(i1) + y3%WriteOutputSep(i1)))* scaleFactor - c = ( (t(2)-t(3))*y1%WriteOutputSep(i1) + t(3)*y2%WriteOutputSep(i1) - t(2)*y3%WriteOutputSep(i1) ) * scaleFactor - y_out%WriteOutputSep(i1) = y1%WriteOutputSep(i1) + b + c * t_out - END DO -END IF ! check if allocated -IF (ALLOCATED(y_out%WriteOutputNode) .AND. ALLOCATED(y1%WriteOutputNode)) THEN - DO i1 = LBOUND(y_out%WriteOutputNode,1),UBOUND(y_out%WriteOutputNode,1) - b = (t(3)**2*(y1%WriteOutputNode(i1) - y2%WriteOutputNode(i1)) + t(2)**2*(-y1%WriteOutputNode(i1) + y3%WriteOutputNode(i1)))* scaleFactor - c = ( (t(2)-t(3))*y1%WriteOutputNode(i1) + t(3)*y2%WriteOutputNode(i1) - t(2)*y3%WriteOutputNode(i1) ) * scaleFactor - y_out%WriteOutputNode(i1) = y1%WriteOutputNode(i1) + b + c * t_out - END DO -END IF ! check if allocated - END SUBROUTINE AA_Output_ExtrapInterp2 - END MODULE AeroAcoustics_Types !ENDOFREGISTRYGENERATEDFILE diff --git a/modules/aerodyn/src/AeroDyn.f90 b/modules/aerodyn/src/AeroDyn.f90 index 14c1705cd..2ef0eed64 100644 --- a/modules/aerodyn/src/AeroDyn.f90 +++ b/modules/aerodyn/src/AeroDyn.f90 @@ -61,13 +61,19 @@ module AeroDyn ! states(z) PUBLIC :: AD_GetOP !< Routine to pack the operating point values (for linearization) into arrays + PUBLIC :: AD_NumWindPoints !< Routine to return then number of windpoints required by AeroDyn + PUBLIC :: AD_BoxExceedPointsIdx !< Routine to set the start of the OLAF wind points + PUBLIC :: AD_GetExternalWind !< Set the external wind into AeroDyn inputs + PUBLIC :: AD_SetExternalWindPositions !< Set the external wind points needed by AeroDyn inputs contains !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine sets the initialization output data structure, which contains data to be returned to the calling program (e.g., !! FAST or AeroDyn_Driver) -subroutine AD_SetInitOut(p, p_AD, InputFileData, InitOut, errStat, errMsg) +subroutine AD_SetInitOut(MHK, WtrDpth, p, p_AD, InputFileData, InitOut, errStat, errMsg) + integer(IntKi), intent(in ) :: MHK ! MHK flag + real(ReKi), intent(in ) :: WtrDpth ! water depth type(RotInitOutputType), intent( out) :: InitOut ! output data type(RotInputFile), intent(in ) :: InputFileData ! input file data (for setting airfoil shape outputs) type(RotParameterType), intent(in ) :: p ! Parameters @@ -109,7 +115,7 @@ subroutine AD_SetInitOut(p, p_AD, InputFileData, InitOut, errStat, errMsg) ! Set the info in WriteOutputHdr and WriteOutputUnt - CALL AllBldNdOuts_InitOut( InitOut, p, p_AD, InputFileData, ErrStat2, ErrMsg2 ) + CALL AllBldNdOuts_InitOut( InitOut, p, InputFileData, ErrStat2, ErrMsg2 ) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -181,7 +187,11 @@ subroutine AD_SetInitOut(p, p_AD, InputFileData, InitOut, errStat, errMsg) CALL SetErrStat(ErrID_Fatal,"Error allocating memory for TwrElev.", ErrStat, ErrMsg, RoutineName) RETURN END IF - InitOut%TwrElev(:) = InputFileData%TwrElev(:) + IF ( MHK == 1 ) THEN + InitOut%TwrElev(:) = InputFileData%TwrElev(:) - WtrDpth + ELSE + InitOut%TwrElev(:) = InputFileData%TwrElev(:) + END IF ALLOCATE(InitOut%TwrDiam(p%NumTwrNds), STAT = ErrStat2) IF (ErrStat2 /= 0) THEN @@ -230,10 +240,11 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut 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 integer(IntKi) :: nRotors ! Number of rotors integer(IntKi), allocatable, dimension(:) :: NumBlades ! Number of blades per rotor + integer(IntKi) , allocatable, dimension(:) :: AeroProjMod ! AeroProjMod per rotor + character(*), parameter :: RoutineName = 'AD_Init' @@ -262,6 +273,11 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut if (errStat/=0) call SetErrStat( ErrID_Fatal, 'Allocating rotor input/outputs', errStat, errMsg, RoutineName ) allocate(p%rotors(nRotors), m%rotors(nRotors), stat=errStat) if (errStat/=0) call SetErrStat( ErrID_Fatal, 'Allocating rotor params/misc', errStat, errMsg, RoutineName ) + allocate(NumBlades(nRotors), stat=errStat ) ! temp array to pass NumBlades + if (errStat/=0) call SetErrStat( ErrID_Fatal, 'Allocating numblades per rotor', errStat, errMsg, RoutineName ) + allocate(AeroProjMod(nRotors), stat=errStat ) ! temp array to pass AeroProjMod + AeroProjMod=-1 + if (errStat/=0) call SetErrStat( ErrID_Fatal, 'Allocating AeroProjMod per rotor', errStat, errMsg, RoutineName ) if (errStat/=ErrID_None) then call Cleanup() return @@ -270,12 +286,12 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut ! set a few parameters needed while reading the input file - allocate(NumBlades(nRotors)) do iR = 1, nRotors call ValidateNumBlades( InitInp%rotors(iR)%NumBlades, ErrStat2, ErrMsg2 ) if (Failed()) return; NumBlades(iR) = InitInp%rotors(iR)%NumBlades p%rotors(iR)%NumBlades = InitInp%rotors(iR)%NumBlades + AeroProjMod(iR) = InitInp%rotors(iR)%AeroProjMod ! NOTE: we allow this to be overwritten if (nRotors > 1) then p%rotors(iR)%RootName = TRIM(InitInp%RootName)//'.AD.R'//trim(num2lstr(iR)) else @@ -305,10 +321,25 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut CALL ParsePrimaryFileInfo( PriPath, InitInp, InitInp%InputFile, p%RootName, NumBlades, interval, FileInfo_In, InputFileData, UnEcho, ErrStat2, ErrMsg2 ) if (Failed()) return; + ! Temporary HACK, for WakeMod=10, 11 or 12 use AeroProjMod 2 (will trigger PolarBEM) + if (InputFileData%WakeMod==10) then + call WrScr(' WARNING: WakeMod=10 is a temporary hack. Using new projection method with WakeMod=0.') + InputFileData%WakeMod = 0 + AeroProjMod(:) = 2 + elseif (InputFileData%WakeMod==11) then + call WrScr(' WARNING: WakeMod=11 is a temporary hack. Using new projection method with WakeMod=1.') + InputFileData%WakeMod = 1 + AeroProjMod(:) = 2 + elseif (InputFileData%WakeMod==12) then + call WrScr(' WARNING: WakeMod=12 is a temporary hack. Using new projection method with WakeMod=2.') + InputFileData%WakeMod = 2 + AeroProjMod(:) = 2 + endif + ! ----------------------------------------------------------------- ! 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, NumBlades, UnEcho, ErrStat2, ErrMsg2 ) + call ReadInputFiles( InitInp%InputFile, InputFileData, interval, p%RootName, NumBlades, AeroProjMod, UnEcho, ErrStat2, ErrMsg2 ) if (Failed()) return; ! Validate the inputs @@ -327,19 +358,39 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut ! set the rest of the parameters p%SkewMod = InputFileData%SkewMod do iR = 1, nRotors - p%rotors(iR)%AeroProjMod = InitInp%rotors(iR)%AeroProjMod + !p%rotors(iR)%AeroProjMod = InitInp%rotors(iR)%AeroProjMod + p%rotors(iR)%AeroProjMod = AeroProjMod(iR) + p%rotors(iR)%AeroBEM_Mod = InitInp%rotors(iR)%AeroBEM_Mod call SetParameters( InitInp, InputFileData, InputFileData%rotors(iR), p%rotors(iR), p, ErrStat2, ErrMsg2 ) if (Failed()) return; enddo + ! TailFin parameters + do iR = 1, nRotors + p%rotors(iR)%TFinAero = InputFileData%rotors(iR)%TFinAero + p%rotors(iR)%TFin%TFinMod = InputFileData%rotors(iR)%TFin%TFinMod + p%rotors(iR)%TFin%TFinChord = InputFileData%rotors(iR)%TFin%TFinChord + p%rotors(iR)%TFin%TFinArea = InputFileData%rotors(iR)%TFin%TFinArea + p%rotors(iR)%TFin%TFinIndMod = InputFileData%rotors(iR)%TFin%TFinIndMod + p%rotors(iR)%TFin%TFinAFID = InputFileData%rotors(iR)%TFin%TFinAFID + enddo !............................................................................................ ! Define and initialize inputs here !............................................................................................ do iR = 1, nRotors - call Init_u( u%rotors(iR), p%rotors(iR), p, InputFileData%rotors(iR), InitInp%rotors(iR), errStat2, errMsg2 ) + call Init_u( u%rotors(iR), p%rotors(iR), p, InputFileData%rotors(iR), InitInp%MHK, InitInp%WtrDpth, InitInp%rotors(iR), errStat2, errMsg2 ) if (Failed()) return; enddo + !............................................................................................ + ! Calculate buoyancy parameters + !............................................................................................ + do iR = 1, nRotors + if ( p%rotors(iR)%Buoyancy ) then + call SetBuoyancyParameters( InputFileData%rotors(iR), u%rotors(iR), p%rotors(iR), ErrStat2, ErrMsg2 ) + if (Failed()) return; + end if + end do !............................................................................................ ! Initialize the BEMT module (also sets other variables for sub module) @@ -420,7 +471,7 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut !............................................................................................ InitOut%Ver = AD_Ver do iR = 1, nRotors - call AD_SetInitOut(p%rotors(iR), p, InputFileData%rotors(iR), InitOut%rotors(iR), errStat2, errMsg2) + call AD_SetInitOut(InitInp%MHK, InitInp%WtrDpth, p%rotors(iR), p, InputFileData%rotors(iR), InitOut%rotors(iR), errStat2, errMsg2) if (Failed()) return; enddo @@ -523,6 +574,9 @@ subroutine AD_ReInit(p, x, xd, z, OtherState, m, Interval, ErrStat, ErrMsg ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) end if enddo + else + ErrStat = ErrID_Fatal + ErrMsg = 'AD_ReInit: Cannot reinitialize AeroDyn with OLAF' end if @@ -533,13 +587,14 @@ subroutine Init_MiscVars(m, p, u, y, errStat, errMsg) type(RotMiscVarType), intent(inout) :: m !< misc/optimization data (not defined in submodules) type(RotParameterType), intent(in ) :: p !< Parameters type(RotInputType), intent(inout) :: u !< input for HubMotion mesh (create sibling mesh here) - type(RotOutputType), intent(in ) :: y !< output (create mapping between output and otherstate mesh here) + type(RotOutputType), intent(inout) :: y !< output (create mapping between output and otherstate mesh here) integer(IntKi), intent( out) :: errStat !< Error status of the operation character(*), intent( out) :: errMsg !< Error message if ErrStat /= ErrID_None ! Local variables integer(intKi) :: k + integer(intKi) :: j integer(intKi) :: ErrStat2 ! temporary Error status character(ErrMsgLen) :: ErrMsg2 ! temporary Error message character(*), parameter :: RoutineName = 'Init_MiscVars' @@ -551,7 +606,7 @@ subroutine Init_MiscVars(m, p, u, y, errStat, errMsg) call AllocAry( m%DisturbedInflow, 3_IntKi, p%NumBlNds, p%numBlades, 'OtherState%DisturbedInflow', ErrStat2, ErrMsg2 ) ! must be same size as u%InflowOnBlade call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - call AllocAry( m%WithoutSweepPitchTwist, 3_IntKi, 3_IntKi, p%NumBlNds, p%numBlades, 'OtherState%WithoutSweepPitchTwist', ErrStat2, ErrMsg2 ) + call AllocAry( m%orientationAnnulus, 3_IntKi, 3_IntKi, p%NumBlNds, p%numBlades, 'OtherState%orientationAnnulus', ErrStat2, ErrMsg2 ) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) call allocAry( m%SigmaCavit, p%NumBlNds, p%numBlades, 'm%SigmaCavit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -586,9 +641,16 @@ subroutine Init_MiscVars(m, p, u, y, errStat, errMsg) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) call AllocAry( m%Y, p%NumBlNds, p%NumBlades, 'm%Y', ErrStat2, ErrMsg2 ) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - call AllocAry( m%M, p%NumBlNds, p%NumBlades, 'm%M', ErrStat2, ErrMsg2 ) + call AllocAry( m%Z, p%NumBlNds, p%NumBlades, 'm%Z', ErrStat2, ErrMsg2 ) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) call AllocAry( m%hub_theta_x_root, p%NumBlades, 'm%hub_theta_x_root', ErrStat2, ErrMsg2 ) + call AllocAry( m%M, p%NumBlNds, p%NumBlades, 'm%M', ErrStat2, ErrMsg2 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + call AllocAry( m%Mx, p%NumBlNds, p%NumBlades, 'm%Mx', ErrStat2, ErrMsg2 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + call AllocAry( m%My, p%NumBlNds, p%NumBlades, 'm%My', ErrStat2, ErrMsg2 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + call AllocAry( m%Mz, p%NumBlNds, p%NumBlades, 'm%Mz', ErrStat2, ErrMsg2 ) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) ! mesh mapping data for integrating load over entire rotor: allocate( m%B_L_2_H_P(p%NumBlades), Stat = ErrStat2) @@ -596,16 +658,8 @@ subroutine Init_MiscVars(m, p, u, y, errStat, errMsg) call SetErrStat( ErrID_Fatal, "Error allocating B_L_2_H_P mapping structure.", errStat, errMsg, RoutineName ) return end if - - call MeshCopy ( SrcMesh = u%HubMotion & - , DestMesh = m%HubLoad & - , CtrlCode = MESH_SIBLING & - , IOS = COMPONENT_OUTPUT & - , force = .TRUE. & - , moment = .TRUE. & - , ErrStat = ErrStat2 & - , ErrMess = ErrMsg2 ) - + + call MeshCopy( y%HubLoad, m%HubLoad, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) if (ErrStat >= AbortErrLev) RETURN @@ -650,6 +704,160 @@ subroutine Init_MiscVars(m, p, u, y, errStat, errMsg) if (ErrStat >= AbortErrLev) RETURN + if (p%Buoyancy) then + ! Point mesh for blade buoyant loads + allocate(m%BladeBuoyLoadPoint(p%NumBlades), Stat = ErrStat2) + if (ErrStat2 /= 0) then + call SetErrStat(ErrID_Fatal, "Error allocating BladeBuoyLoadPoint mesh array.", errStat, errMsg, RoutineName) + return + end if + ! Line mesh for blade buoyant loads + allocate(m%BladeBuoyLoad(p%NumBlades), Stat = ErrStat2) + if (ErrStat2 /= 0) then + call SetErrStat(ErrID_Fatal, "Error allocating BladeBuoyLoad mesh array.", errStat, errMsg, RoutineName) + return + end if + ! Mesh mapping for blade buoyant loads from point to line + allocate(m%B_P_2_B_L(p%NumBlades), Stat = ErrStat2) + if (ErrStat2 /= 0) then + call SetErrStat(ErrID_Fatal, "Error allocating B_P_2_B_L mapping structure.", errStat, errMsg, RoutineName) + return + end if + + do k=1,p%NumBlades + call MeshCreate ( BlankMesh = m%BladeBuoyLoadPoint(k) & + , IOS = COMPONENT_OUTPUT & + , Nnodes = p%NumBlNds & + , force = .TRUE. & + , moment = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + if (ErrStat >= AbortErrLev) return + + do j = 1,p%NumBlNds + call MeshPositionNode(m%BladeBuoyLoadPoint(k), j, u%BladeMotion(k)%Position(:,j), errStat2, errMsg2, u%BladeMotion(k)%RefOrientation(:,:,j)) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) + call MeshConstructElement(m%BladeBuoyLoadPoint(k), ELEMENT_POINT, errStat2, errMsg2, p1=j) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) + end do !j=nodes + + call MeshCommit(m%BladeBuoyLoadPoint(k), errStat2, errMsg2) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName//':BladeBuoyLoadPoint'//trim(num2lstr(k))) + + if (errStat >= AbortErrLev) return + + m%BladeBuoyLoadPoint(k)%Force = 0.0_ReKi + m%BladeBuoyLoadPoint(k)%Moment = 0.0_ReKi + end do !k=blades + + do k=1,p%NumBlades + call MeshCreate ( BlankMesh = m%BladeBuoyLoad(k) & + , IOS = COMPONENT_OUTPUT & + , Nnodes = p%NumBlNds & + , force = .TRUE. & + , moment = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + if (ErrStat >= AbortErrLev) return + + do j = 1,p%NumBlNds + call MeshPositionNode(m%BladeBuoyLoad(k), j, u%BladeMotion(k)%Position(:,j), errStat2, errMsg2, u%BladeMotion(k)%RefOrientation(:,:,j)) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) + end do !j=nodes + do j = 1,p%NumBlNds-1 + call MeshConstructElement(m%BladeBuoyLoad(k), ELEMENT_LINE2, errStat2, errMsg2, p1=j, p2=j+1) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) + end do !j=nodes + + call MeshCommit(m%BladeBuoyLoad(k), errStat2, errMsg2) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName//':BladeBuoyLoad'//trim(num2lstr(k))) + + if (errStat >= AbortErrLev) return + + m%BladeBuoyLoad(k)%Force = 0.0_ReKi + m%BladeBuoyLoad(k)%Moment = 0.0_ReKi + end do !k=blades + + do k=1,p%NumBlades + call MeshMapCreate(m%BladeBuoyLoadPoint(k), m%BladeBuoyLoad(k), m%B_P_2_B_L(k), ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':B_P_2_B_L('//TRIM(Num2LStr(K))//')') + end do !k=blades + + if (ErrStat >= AbortErrLev) RETURN + + if ( p%NumTwrNds > 0 ) then + + call MeshCreate ( BlankMesh = m%TwrBuoyLoadPoint & + , IOS = COMPONENT_OUTPUT & + , Nnodes = p%NumTwrNds & + , force = .TRUE. & + , moment = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + if (ErrStat >= AbortErrLev) return + + do j = 1,p%NumTwrNds + call MeshPositionNode(m%TwrBuoyLoadPoint, j, u%TowerMotion%Position(:,j), errStat2, errMsg2, u%TowerMotion%RefOrientation(:,:,j)) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) + call MeshConstructElement(m%TwrBuoyLoadPoint, ELEMENT_POINT, errStat2, errMsg2, p1=j) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) + end do !j=nodes + + call MeshCommit(m%TwrBuoyLoadPoint, errStat2, errMsg2) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName//':TwrBuoyLoadPoint') + + if (errStat >= AbortErrLev) return + + m%TwrBuoyLoadPoint%Force = 0.0_ReKi + m%TwrBuoyLoadPoint%Moment = 0.0_ReKi + + call MeshCreate ( BlankMesh = m%TwrBuoyLoad & + , IOS = COMPONENT_OUTPUT & + , Nnodes = p%NumTwrNds & + , force = .TRUE. & + , moment = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + if (ErrStat >= AbortErrLev) return + + do j = 1,p%NumTwrNds + call MeshPositionNode(m%TwrBuoyLoad, j, u%TowerMotion%Position(:,j), errStat2, errMsg2, u%TowerMotion%RefOrientation(:,:,j)) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) + end do !j=nodes + do j = 1,p%NumTwrNds-1 + call MeshConstructElement(m%TwrBuoyLoad, ELEMENT_LINE2, errStat2, errMsg2, p1=j, p2=j+1) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) + end do !j=nodes + + call MeshCommit(m%TwrBuoyLoad, errStat2, errMsg2) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName//':TwrBuoyLoad') + + if (errStat >= AbortErrLev) return + + m%TwrBuoyLoad%Force = 0.0_ReKi + m%TwrBuoyLoad%Moment = 0.0_ReKi + + call MeshMapCreate(m%TwrBuoyLoadPoint, m%TwrBuoyLoad, m%T_P_2_T_L, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':T_P_2_T_L') + + if (ErrStat >= AbortErrLev) RETURN + + end if + + end if + ! if (p%NumTwrNds > 0) then m%W_Twr = 0.0_ReKi @@ -657,7 +865,7 @@ subroutine Init_MiscVars(m, p, u, y, errStat, errMsg) m%Y_Twr = 0.0_ReKi end if - + m%FirstWarn_TowerStrike = .true. end subroutine Init_MiscVars !---------------------------------------------------------------------------------------------------------------------------------- @@ -704,7 +912,7 @@ subroutine Init_y(y, u, p, errStat, errMsg) errMsg = "" - if (p%TwrAero) then + if (p%TwrAero .or. p%Buoyancy .and. p%NumTwrNds > 0) then call MeshCopy ( SrcMesh = u%TowerMotion & , DestMesh = y%TowerLoad & @@ -724,6 +932,7 @@ subroutine Init_y(y, u, p, errStat, errMsg) y%TowerLoad%nnodes = 0 end if + call MeshCopy ( SrcMesh = u%NacelleMotion & , DestMesh = y%NacelleLoad & , CtrlCode = MESH_SIBLING & @@ -735,6 +944,36 @@ subroutine Init_y(y, u, p, errStat, errMsg) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) if (ErrStat >= AbortErrLev) RETURN + + ! --- TailFin + if (p%TFinAero) then + call MeshCopy ( SrcMesh = u%TFinMotion & + , DestMesh = y%TFinLoad & + , CtrlCode = MESH_SIBLING & + , IOS = COMPONENT_OUTPUT & + , force = .TRUE. & + , moment = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (ErrStat >= AbortErrLev) RETURN + else + y%TFinLoad%NNodes = 0 + endif + + + call MeshCopy ( SrcMesh = u%HubMotion & + , DestMesh = y%HubLoad & + , CtrlCode = MESH_SIBLING & + , IOS = COMPONENT_OUTPUT & + , force = .TRUE. & + , moment = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (ErrStat >= AbortErrLev) RETURN allocate( y%BladeLoad(p%numBlades), stat=ErrStat2 ) if (errStat2 /= 0) then @@ -767,13 +1006,15 @@ subroutine Init_y(y, u, p, errStat, errMsg) end subroutine Init_y !---------------------------------------------------------------------------------------------------------------------------------- !> This routine initializes AeroDyn meshes and input array variables for use during the simulation. -subroutine Init_u( u, p, p_AD, InputFileData, InitInp, errStat, errMsg ) +subroutine Init_u( u, p, p_AD, InputFileData, MHK, WtrDpth, InitInp, errStat, errMsg ) !.................................................................................................................................. type(RotInputType), intent( out) :: u !< Input data type(RotParameterType), intent(in ) :: p !< Parameters type(AD_ParameterType), intent(in ) :: p_AD !< Parameters type(RotInputFile), intent(in ) :: InputFileData !< Data stored in the module's input file + integer(IntKi), intent(in ) :: MHK ! MHK flag + real(ReKi), intent(in ) :: WtrDpth ! water depth type(RotInitInputType), intent(in ) :: InitInp !< Input data for AD initialization routine integer(IntKi), intent( out) :: errStat !< Error status of the operation character(*), intent( out) :: errMsg !< Error message if ErrStat /= ErrID_None @@ -813,7 +1054,9 @@ subroutine Init_u( u, p, p_AD, InputFileData, InitInp, errStat, errMsg ) u%InflowOnBlade = 0.0_ReKi u%UserProp = 0.0_ReKi + u%InflowOnHub = 0.0_ReKi u%InflowOnNacelle = 0.0_ReKi + u%InflowOnTailFin = 0.0_ReKi ! Meshes for motion inputs (ElastoDyn and/or BeamDyn) !................ @@ -831,6 +1074,7 @@ subroutine Init_u( u, p, p_AD, InputFileData, InitInp, errStat, errMsg ) ,Orientation = .true. & ,TranslationDisp = .true. & ,TranslationVel = .true. & + ,TranslationAcc = .TRUE. & ! tower acceleration used for tower VIV ) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) @@ -839,7 +1083,11 @@ subroutine Init_u( u, p, p_AD, InputFileData, InitInp, errStat, errMsg ) ! set node initial position/orientation position = 0.0_ReKi do j=1,p%NumTwrNds - position(3) = InputFileData%TwrElev(j) + IF ( MHK == 1 ) THEN + position(3) = InputFileData%TwrElev(j) - WtrDpth + ELSE + position(3) = InputFileData%TwrElev(j) + END IF call MeshPositionNode(u%TowerMotion, j, position, errStat2, errMsg2) ! orientation is identity by default call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) @@ -863,40 +1111,28 @@ subroutine Init_u( u, p, p_AD, InputFileData, InitInp, errStat, errMsg ) end if ! we compute tower loads - !................ - ! hub - !................ - - call MeshCreate ( BlankMesh = u%HubMotion & - ,IOS = COMPONENT_INPUT & - ,Nnodes = 1 & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & - ,Orientation = .true. & - ,TranslationDisp = .true. & - ,RotationVel = .true. & - ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - if (errStat >= AbortErrLev) return - - call MeshPositionNode(u%HubMotion, 1, InitInp%HubPosition, errStat2, errMsg2, InitInp%HubOrientation) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - call MeshConstructElement( u%HubMotion, ELEMENT_POINT, errStat2, errMsg2, p1=1 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - call MeshCommit(u%HubMotion, errStat2, errMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName//':HubMotion' ) - - if (errStat >= AbortErrLev) return + !................ + ! hub + !................ + call CreatePointMesh(u%HubMotion, InitInp%HubPosition, InitInp%HubOrientation, errStat2, errMsg2, hasMotion=.True., hasLoads=.False., hasAcc=.False.) + if (Failed()) return + + !................ + ! TailFin Motion Mesh + !................ + if (p%TFinAero) then + position = InitInp%NacellePosition + matmul(transpose(InitInp%NacelleOrientation), InputFileData%TFin%TFinRefP_n) + theta(1) = InputFileData%TFin%TFinAngles(1) + theta(2) = InputFileData%TFin%TFinAngles(2) + theta(3) = InputFileData%TFin%TFinAngles(3) + orientationL = EulerConstructZYX( theta ) ! nac2tf + orientation = matmul(orientationL, InitInp%NacelleOrientation) ! gl2tf = nac2tf * gl2nac + call CreatePointMesh(u%TFinMotion, position, orientation, errStat2, errMsg2, hasMotion=.True., hasLoads=.False., hasAcc=.False.) + if (Failed()) return + else + u%TFinMotion%NNodes = 0 + endif - - u%HubMotion%Orientation = u%HubMotion%RefOrientation - u%HubMotion%TranslationDisp = 0.0_R8Ki - u%HubMotion%RotationVel = 0.0_ReKi - - !................ ! blade roots !................ @@ -908,33 +1144,8 @@ subroutine Init_u( u, p, p_AD, InputFileData, InitInp, errStat, errMsg ) end if do k=1,p%NumBlades - call MeshCreate ( BlankMesh = u%BladeRootMotion(k) & - ,IOS = COMPONENT_INPUT & - ,Nnodes = 1 & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & - ,Orientation = .true. & - ,TranslationDisp=.true., TranslationVel=.true. & - ,RotationVel=.true., TranslationAcc=.true., RotationAcc=.true. & - ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - if (errStat >= AbortErrLev) return - - call MeshPositionNode(u%BladeRootMotion(k), 1, InitInp%BladeRootPosition(:,k), errStat2, errMsg2, InitInp%BladeRootOrientation(:,:,k)) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - call MeshConstructElement( u%BladeRootMotion(k), ELEMENT_POINT, errStat2, errMsg2, p1=1 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - call MeshCommit(u%BladeRootMotion(k), errStat2, errMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName//':BladeRootMotion' ) - - if (errStat >= AbortErrLev) return - - - u%BladeRootMotion(k)%Orientation = u%BladeRootMotion(k)%RefOrientation - + call CreatePointMesh(u%BladeRootMotion(k), InitInp%BladeRootPosition(:,k), InitInp%BladeRootOrientation(:,:,k), errStat2, errMsg2, hasMotion=.True., hasLoads=.False.) + if (Failed()) return end do !k=numBlades @@ -1015,38 +1226,18 @@ subroutine Init_u( u, p, p_AD, InputFileData, InitInp, errStat, errMsg ) - !................ - ! Nacelle - !................ - call MeshCreate ( BlankMesh = u%NacelleMotion & - ,IOS = COMPONENT_INPUT & - ,Nnodes = 1 & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & - ,Orientation = .true. & - ,TranslationDisp = .true. & - ,TranslationVel = .true. & - ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - if (errStat >= AbortErrLev) return - - ! set node initial position/orientation - position = InitInp%NacellePosition - - call MeshPositionNode(u%NacelleMotion, 1, position, errStat2, errMsg2, orient=InitInp%NacelleOrientation) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - call MeshConstructElement( u%NacelleMotion, ELEMENT_POINT, errStat2, errMsg2, p1=1 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - call MeshCommit(u%NacelleMotion, errStat2, errMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - if (errStat >= AbortErrLev) return + !................ + ! Nacelle + !................ + position = real(InitInp%NacellePosition, ReKi) + call CreatePointMesh(u%NacelleMotion, position, InitInp%NacelleOrientation, errStat2, errMsg2, hasMotion=.True., hasLoads=.False., hasAcc=.False.) + if (Failed()) return - - +contains + logical function Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + Failed = ErrStat >= AbortErrLev + end function Failed end subroutine Init_u !---------------------------------------------------------------------------------------------------------------------------------- !> This routine sets AeroDyn parameters for use during the simulation; these variables are not changed after AD_Init. @@ -1063,7 +1254,7 @@ subroutine SetParameters( InitInp, InputFileData, RotData, p, p_AD, ErrStat, Err ! Local variables CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation - !INTEGER(IntKi) :: i, j + INTEGER(IntKi) :: j, k character(*), parameter :: RoutineName = 'SetParameters' ! Initialize variables for this routine @@ -1072,6 +1263,7 @@ subroutine SetParameters( InitInp, InputFileData, RotData, p, p_AD, ErrStat, Err ErrMsg = "" p_AD%UA_Flag = InputFileData%AFAeroMod == AFAeroMod_BL_unsteady + p%MHK = InitInp%MHK p_AD%DT = InputFileData%DTAero p_AD%WakeMod = InputFileData%WakeMod @@ -1079,6 +1271,7 @@ subroutine SetParameters( InitInp, InputFileData, RotData, p, p_AD, ErrStat, Err p%TwrShadow = InputFileData%TwrShadow p%TwrAero = InputFileData%TwrAero p%CavitCheck = InputFileData%CavitCheck + p%Buoyancy = InputFileData%Buoyancy if (InitInp%Linearize .and. InputFileData%WakeMod == WakeMod_BEMT) then @@ -1089,22 +1282,52 @@ subroutine SetParameters( InitInp, InputFileData, RotData, p, p_AD, ErrStat, Err p%CompAA = InputFileData%CompAA - ! NOTE: In the following we use InputFileData%BladeProps(1)%NumBlNds as the number of aero nodes on EACH blade, + ! NOTE: In the following we use RotData%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?) ! if (p%NumBlades>0) then p%NumBlNds = RotData%BladeProps(1)%NumBlNds else p%NumBlNds = 0 endif - if (p%TwrPotent == TwrPotent_none .and. p%TwrShadow == TwrShadow_none .and. .not. p%TwrAero) then + + if (p%NumBlades>0 .and. p%Buoyancy) then + call AllocAry( p%BlCenBn, p%NumBlNds, p%NumBlades, 'BlCenBn', ErrStat2, ErrMsg2 ) + call AllocAry( p%BlCenBt, p%NumBlNds, p%NumBlades, 'BlCenBt', ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + endif + + if (p%TwrPotent == TwrPotent_none .and. p%TwrShadow == TwrShadow_none .and. .not. p%TwrAero .and. .not. p%Buoyancy ) then p%NumTwrNds = 0 + elseif (p%TwrPotent == TwrPotent_none .and. p%TwrShadow == TwrShadow_none .and. .not. p%TwrAero .and. p%Buoyancy .and. RotData%NumTwrNds <= 0 ) then + p%NumTwrNds = 0 + elseif (p%TwrPotent == TwrPotent_none .and. p%TwrShadow == TwrShadow_none .and. .not. p%TwrAero .and. p%Buoyancy .and. RotData%NumTwrNds > 0 ) then + p%NumTwrNds = RotData%NumTwrNds + + call move_alloc( RotData%TwrDiam, p%TwrDiam ) + call move_alloc( RotData%TwrCd, p%TwrCd ) + call move_alloc( RotData%TwrTI, p%TwrTI ) + call move_alloc( RotData%TwrCb, p%TwrCb ) else p%NumTwrNds = RotData%NumTwrNds call move_alloc( RotData%TwrDiam, p%TwrDiam ) call move_alloc( RotData%TwrCd, p%TwrCd ) - call move_alloc( RotData%TwrTI, p%TwrTI ) + call move_alloc( RotData%TwrTI, p%TwrTI ) + call move_alloc( RotData%TwrCb, p%TwrCb ) + end if + + if (p%Buoyancy) then + do k = 1,p%NumBlades + p%BlCenBn(:,k) = RotData%BladeProps(k)%BlCenBn + p%BlCenBt(:,k) = RotData%BladeProps(k)%BlCenBt + end do end if + p%VolHub = RotData%VolHub + p%HubCenBx = RotData%HubCenBx + p%VolNac = RotData%VolNac + p%NacCenB = RotData%NacCenB + p%VolBl = 0.0_ReKi + p%VolTwr = 0.0_ReKi p%Gravity = InitInp%Gravity p%AirDens = InputFileData%AirDens @@ -1115,10 +1338,21 @@ subroutine SetParameters( InitInp, InputFileData, RotData, p, p_AD, ErrStat, Err p%WtrDpth = InitInp%WtrDpth p%MSL2SWL = InitInp%MSL2SWL + call AllocAry(p%BlTwist, p%NumBlNds, p%numBlades, 'p%BlTwist', ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + if (ErrStat >= AbortErrLev) return + + do k=1,p%numBlades + do j=1,p%NumBlNds + p%BlTwist(j,k) = RotData%BladeProps(k)%BlTwist(j) + end do + end do + + !p%AFI ! set in call to AFI_Init() [called early because it wants to use the same echo file as AD] !p%BEMT ! set in call to BEMT_Init() - !p%RootName = TRIM(InitInp%RootName)//'.AD' ! set earlier to it could be used + !p%RootName = TRIM(InitInp%RootName)//'.AD' ! set earlier so it could be used p%numOuts = InputFileData%NumOuts p%NBlOuts = InputFileData%NBlOuts @@ -1136,8 +1370,6 @@ subroutine SetParameters( InitInp, InputFileData, RotData, p, p_AD, ErrStat, Err if (ErrStat >= AbortErrLev) return - - ! Set the nodal output parameters. Note there is some validation in this, so we might get an error from here. CALL AllBldNdOuts_SetParameters( InputFileData, p, p_AD, ErrStat2, ErrMsg2 ) call setErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -1147,6 +1379,97 @@ subroutine SetParameters( InitInp, InputFileData, RotData, p, p_AD, ErrStat, Err end subroutine SetParameters !---------------------------------------------------------------------------------------------------------------------------------- +!> This routine sets parameters for use during the buoyancy calculation; these variables are not changed after AD_Init. +subroutine SetBuoyancyParameters( InputFileData, u, p, ErrStat, ErrMsg ) + TYPE(RotInputFile), INTENT(IN ) :: InputFileData !< All the data in the AeroDyn input file + TYPE(RotInputType), INTENT(IN ) :: u !< AD inputs - used for mesh node positions + TYPE(RotParameterType), 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) :: ErrStat2 !< Temporary error status of the operation + CHARACTER(ErrMsgLen) :: ErrMsg2 !< Temporary error message if ErrStat /= ErrID_None + INTEGER(IntKi) :: k !< Loop counter for blades + INTEGER(IntKi) :: j !< Loop counter for nodes + REAL(ReKi), DIMENSION(3) :: posCBu !< Global undisplaced position of the center of buoyancy of node j + REAL(ReKi), DIMENSION(3) :: posCBuplus !< Global undisplaced position of the center of buoyancy of node j+1 + REAL(ReKi), DIMENSION(3) :: tempVolBl !< Individual blade buoyancy volume + + CHARACTER(*), PARAMETER :: RoutineName = 'SetBuoyancyParameters' + + + ! Initialize variables for this routine + ErrStat = ErrID_None + ErrMsg = "" + tempVolBl = 0.0_ReKi + + + ! Allocate buoyancy parameters + call AllocAry( p%BlRad, p%NumBlNds, p%NumBlades, 'BlRad', ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( p%BlDL, p%NumBlNds-1, p%NumBlades, 'BlDL', ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( p%BlTaper, p%NumBlNds-1, p%NumBlades, 'BlTaper', ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( p%BlAxCent, p%NumBlNds-1, p%NumBlades, 'BlAxCent', ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + if ( p%NumTwrNds > 0 ) then + call AllocAry( p%TwrRad, p%NumTwrNds, 'TwrRad', ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( p%TwrDL, p%NumTwrNds-1, 'TwrDL', ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( p%TwrTaper, p%NumTwrNds-1, 'TwrTaper', ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call AllocAry( p%TwrAxCent, p%NumTwrNds-1, 'TwrAxCent', ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + end if + + ! Calculate blade buoyancy parameters + do k = 1,p%NumBlades ! loop through all blades + + do j = 1,p%NumBlNds ! loop through all nodes + p%BlRad(j,k) = InputFileData%BladeProps(k)%BlChord(j) * sqrt( InputFileData%BladeProps(k)%BlCb(j) ) / 2 ! node j equivalent radius + end do ! j = nodes + + do j = 1,p%NumBlNds - 1 ! loop through all nodes, except the last + posCBu = matmul( [InputFileData%BladeProps(k)%BlCenBn(j), InputFileData%BladeProps(k)%BlCenBt(j), 0.0_ReKi ], u%BladeMotion(k)%RefOrientation(:,:,j) ) + u%BladeMotion(k)%Position(:,j) ! blade node j center of buoyancy global undisplaced position + posCBuplus = matmul( [InputFileData%BladeProps(k)%BlCenBn(j+1), InputFileData%BladeProps(k)%BlCenBt(j+1), 0.0_ReKi ], u%BladeMotion(k)%RefOrientation(:,:,j+1) ) + u%BladeMotion(k)%Position(:,j+1) ! blade node j+1 center of buoyancy global undisplaced position + p%BlDL(j,k) = sqrt( ( posCBuplus(1) - posCBu(1) )**2 + ( posCBuplus(2) - posCBu(2) )**2 + ( posCBuplus(3) - posCBu(3) )**2 ) ! element j undisplaced length based on CB coordinates + p%BlTaper(j,k) = ( p%BlRad(j+1,k) - p%BlRad(j,k) ) / p%BlDL(j,k) ! element j taper + if ( p%BlRad(j,k) == 0.0_ReKi .and. p%BlRad(j+1,k) == 0.0_ReKi ) then + p%BlAxCent(j,k) = 0.0_ReKi ! Trap NaN case and set to zero + else + p%BlAxCent(j,k) = ( p%BlRad(j,k)**2 + 2.0_ReKi*p%BlRad(j,k)*p%BlRad(j+1,k) + 3.0_ReKi*p%BlRad(j+1,k)**2 ) / ( 4.0_ReKi*( p%BlRad(j,k)**2 + p%BlRad(j,k)*p%BlRad(j+1,k) + p%BlRad(j+1,k)**2) ) ! fractional axial centroid of element j + end if + tempVolBl(k) = tempVolBl(k) + pi/3.0_ReKi * ( p%BlRad(j,k)**2 + p%BlRad(j,k)*p%BlRad(j+1,k) + p%BlRad(j+1,k)**2 ) * p%BlDL(j,k) + end do ! j = nodes + p%VolBl = p%VolBl + tempVolBl(k) + + end do ! k = blades + + if ( p%NumTwrNds > 0 ) then + ! Calculate tower buoyancy parameters + do j = 1,p%NumTwrNds ! loop through all nodes + p%TwrRad(j) = p%TwrDiam(j) * sqrt( p%TwrCb(j) ) / 2 ! node j equivalent radius + end do ! j = nodes + + do j = 1,p%NumTwrNds - 1 ! loop through all nodes, except the last + p%TwrDL(j) = abs(InputFileData%TwrElev(j+1) - InputFileData%TwrElev(j)) ! element j undisplaced length + p%TwrTaper(j) = ( p%TwrRad(j+1) - p%TwrRad(j) ) / p%TwrDL(j) ! element j taper + if ( p%TwrRad(j) == 0.0_ReKi .and. p%TwrRad(j+1) == 0.0_ReKi ) then + p%TwrAxCent(j) = 0.0_ReKi ! Trap NaN case and set to zero + else + p%TwrAxCent(j) = ( p%TwrRad(j)**2 + 2.0_ReKi*p%TwrRad(j)*p%TwrRad(j+1) + 3.0_ReKi*p%TwrRad(j+1)**2 ) / ( 4.0_ReKi*( p%TwrRad(j)**2 + p%TwrRad(j)*p%TwrRad(j+1) + p%TwrRad(j+1)**2) ) ! fractional axial centroid of element j + end if + p%VolTwr = p%VolTwr + pi/3.0_ReKi * ( p%TwrRad(j)**2 + p%TwrRad(j)*p%TwrRad(j+1) + p%TwrRad(j+1)**2 ) * p%TwrDL(j) + end do ! j = nodes + end if + +end subroutine SetBuoyancyParameters +!---------------------------------------------------------------------------------------------------------------------------------- !> This routine is called at the end of the simulation. subroutine AD_End( u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) !.................................................................................................................................. @@ -1242,6 +1565,8 @@ subroutine AD_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, m, errStat ! local variables integer(intKi) :: iR ! Counter on rotors + integer :: i + real(DbKi) :: BEMT_utimes(2) !< Times associated with m%BEMT_u(:), in seconds type(AD_InputType) :: uInterp ! Interpolated/Extrapolated input integer(intKi) :: ErrStat2 ! temporary Error status character(ErrMsgLen) :: ErrMsg2 ! temporary Error message @@ -1258,33 +1583,27 @@ subroutine AD_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, m, errStat return end if - ! set values of m%BEMT_u(2) from inputs interpolated at t+dt: - ! NOTE: this is different than OpenFAST, which has t+dt at u(1) - call AD_Input_ExtrapInterp(u,utimes,uInterp,t+p%DT, errStat2, errMsg2) + ! set values of m%BEMT_u(2) from inputs interpolated at t+dt; + ! set values of m%BEMT_u(1) from inputs (uInterp) interpolated at t + ! NOTE: this is different than glue code, which has t+dt at u(1) + BEMT_utimes(2) = t+p%DT + BEMT_utimes(1) = t + do i=2,1,-1 ! I'm calculating values for t second in case we want the other misc vars at t as before, but I don't think it matters) + call AD_Input_ExtrapInterp(u,utimes,uInterp,BEMT_utimes(i), errStat2, errMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) do iR = 1,size(p%rotors) - call SetInputs(p%rotors(iR), p, uInterp%rotors(iR), m%rotors(iR), 2, errStat2, errMsg2) + call SetInputs(p%rotors(iR), p, uInterp%rotors(iR), m%rotors(iR), i, errStat2, errMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) enddo - - ! set values of m%BEMT_u(1) from inputs (uInterp) interpolated at t: - ! NOTE: this is different than OpenFAST, which has t at u(2) - ! I'm doing this second in case we want the other misc vars at t as before, but I don't think it matters - call AD_Input_ExtrapInterp(u,utimes,uInterp, t, errStat2, errMsg2) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - - do iR = 1,size(p%rotors) - call SetInputs(p%rotors(iR), p, uInterp%rotors(iR), m%rotors(iR), 1, errStat2, errMsg2) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) enddo + if (p%WakeMod /= WakeMod_FVW) then do iR = 1,size(p%rotors) ! Call into the BEMT update states NOTE: This is a non-standard framework interface!!!!! GJH - ! Also note BEMT_u(1) and BEMT_u(2) are not following the OpenFAST convention for t+dt, t - call BEMT_UpdateStates(t, n, m%rotors(iR)%BEMT_u(1), m%rotors(iR)%BEMT_u(2), p%rotors(iR)%BEMT, x%rotors(iR)%BEMT, xd%rotors(iR)%BEMT, z%rotors(iR)%BEMT, OtherState%rotors(iR)%BEMT, p%AFI, m%rotors(iR)%BEMT, errStat2, errMsg2) + call BEMT_UpdateStates(t, n, m%rotors(iR)%BEMT_u(:), BEMT_utimes, p%rotors(iR)%BEMT, x%rotors(iR)%BEMT, xd%rotors(iR)%BEMT, z%rotors(iR)%BEMT, OtherState%rotors(iR)%BEMT, p%AFI, m%rotors(iR)%BEMT, errStat2, errMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ! Call AeroAcoustics updates states @@ -1347,9 +1666,6 @@ subroutine AD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, LOGICAL, OPTIONAL, INTENT(IN ) :: NeedWriteOutput !< Flag to determine if WriteOutput values need to be calculated in this call - ! NOTE: m%BEMT_u(i) indices are set differently from the way OpenFAST typically sets up the u and uTimes arrays - integer, parameter :: indx = 1 ! m%BEMT_u(1) is at t; m%BEMT_u(2) is t+dt - integer(intKi) :: i integer(intKi) :: iR ! Loop on rotors integer(intKi) :: ErrStat2 @@ -1369,7 +1685,9 @@ subroutine AD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, ! SetInputs, Calc BEM Outputs and Twr Outputs do iR=1,size(p%rotors) - call RotCalcOutput( t, u%rotors(iR), p%rotors(iR), p, x%rotors(iR), xd%rotors(iR), z%rotors(iR), OtherState%rotors(iR), y%rotors(iR), m%rotors(iR), ErrStat, ErrMsg) + call RotCalcOutput( t, u%rotors(iR), p%rotors(iR), p, x%rotors(iR), xd%rotors(iR), z%rotors(iR), OtherState%rotors(iR), y%rotors(iR), m%rotors(iR), m, iR, ErrStat2, ErrMsg2, .false.) + call SetErrStat(ErrStat2, ErrMSg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return enddo if (p%WakeMod == WakeMod_FVW) then @@ -1377,72 +1695,64 @@ subroutine AD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, call SetInputsForFVW(p, (/u/), m, errStat2, errMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ! Calculate Outputs at time t - CALL FVW_CalcOutput( t, m%FVW_u(1), p%FVW, x%FVW, xd%FVW, z%FVW, OtherState%FVW, p%AFI, m%FVW_y, m%FVW, ErrStat2, ErrMsg2 ) + CALL FVW_CalcOutput( t, m%FVW_u(1), p%FVW, x%FVW, xd%FVW, z%FVW, OtherState%FVW, m%FVW_y, m%FVW, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call SetOutputsFromFVW( t, u, p, OtherState, x, xd, m, y, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) endif + ! Cavitation check + call AD_CavtCrit(u, p, m, errStat2, errMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + ! Calculate buoyant loads + do iR = 1,size(p%rotors) + if ( p%rotors(iR)%Buoyancy ) then + call CalcBuoyantLoads( u%rotors(iR), p%rotors(iR), m%rotors(iR), y%rotors(iR), ErrStat, ErrMsg ) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + end if + end do !------------------------------------------------------- ! get values to output to file: !------------------------------------------------------- if (CalcWriteOutput) then do iR = 1,size(p%rotors) - if (p%rotors(iR)%NumOuts > 0) then - call Calc_WriteOutput( p%rotors(iR), p, u%rotors(iR), m%rotors(iR), m, y%rotors(iR), OtherState%rotors(iR), xd%rotors(iR), indx, iR, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - - !............................................................................................................................... - ! Place the selected output channels into the WriteOutput(:) array with the proper sign: - !............................................................................................................................... - - do i = 1,p%rotors(iR)%NumOuts ! Loop through all selected output channels - y%rotors(iR)%WriteOutput(i) = p%rotors(iR)%OutParam(i)%SignM * m%rotors(iR)%AllOuts( p%rotors(iR)%OutParam(i)%Indx ) - end do ! i - All selected output channels - - end if - - y%rotors(iR)%WriteOutput(p%rotors(iR)%NumOuts+1:) = 0.0_ReKi - - ! Now we need to populate the blade node outputs here - if (p%rotors(iR)%NumBlades > 0) then - call Calc_WriteAllBldNdOutput( p%rotors(iR), p, u%rotors(iR), m%rotors(iR), m, x%rotors(iR), y%rotors(iR), OtherState%rotors(iR), indx, iR, ErrStat2, ErrMsg2 ) ! Call after normal writeoutput. Will just postpend data on here. - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - endif - enddo + call RotWriteOutputs(t, u%rotors(iR), p%rotors(iR), p, x%rotors(iR), xd%rotors(iR), z%rotors(iR), OtherState%rotors(iR), y%rotors(iR), m%rotors(iR), m, iR, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMSg2, ErrStat, ErrMsg, RoutineName) + end do end if - end subroutine AD_CalcOutput - - -subroutine RotCalcOutput( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrStat, ErrMsg) +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine RotCalcOutput( t, u, p, p_AD, x, xd, z, OtherState, y, m, m_AD, iRot, ErrStat, ErrMsg, NeedWriteOutput) ! NOTE: no matter how many channels are selected for output, all of the outputs are calculated ! All of the calculated output channels are placed into the m%AllOuts(:), while the channels selected for outputs are ! placed in the y%WriteOutput(:) array. !.................................................................................................................................. - REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds - TYPE(RotInputType), INTENT(IN ) :: u !< Inputs at Time t - TYPE(RotParameterType), INTENT(IN ) :: p !< Parameters - TYPE(AD_ParameterType), INTENT(IN ) :: p_AD !< Parameters - TYPE(RotContinuousStateType), INTENT(IN ) :: x !< Continuous states at t - TYPE(RotDiscreteStateType), INTENT(IN ) :: xd !< Discrete states at t - TYPE(RotConstraintStateType), INTENT(IN ) :: z !< Constraint states at t - TYPE(RotOtherStateType), INTENT(IN ) :: OtherState !< Other states at t - TYPE(RotOutputType), INTENT(INOUT) :: y !< Outputs computed at t (Input only so that mesh con- - !! nectivity information does not have to be recalculated) - type(RotMiscVarType), 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(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds + TYPE(RotInputType), INTENT(IN ) :: u !< Inputs at Time t + TYPE(RotParameterType), INTENT(IN ) :: p !< Parameters + TYPE(AD_ParameterType), INTENT(IN ) :: p_AD !< Parameters + TYPE(RotContinuousStateType), INTENT(IN ) :: x !< Continuous states at t + TYPE(RotDiscreteStateType), INTENT(IN ) :: xd !< Discrete states at t + TYPE(RotConstraintStateType), INTENT(IN ) :: z !< Constraint states at t + TYPE(RotOtherStateType), INTENT(IN ) :: OtherState !< Other states at t + TYPE(RotOutputType), INTENT(INOUT) :: y !< Outputs computed at t (Input only so that mesh con- + !! nectivity information does not have to be recalculated) + type(RotMiscVarType), intent(inout) :: m !< Misc/optimization variables + TYPE(AD_MiscVarType), INTENT(INOUT) :: m_AD !< misc variables + INTEGER, INTENT(IN ) :: iRot !< Rotor index, needed for OLAF + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + LOGICAL, OPTIONAL, INTENT(IN ) :: NeedWriteOutput !< Flag to determine if WriteOutput values need to be calculated in this call + ! NOTE: m%BEMT_u(i) indices are set differently from the way OpenFAST typically sets up the u and uTimes arrays integer, parameter :: indx = 1 ! m%BEMT_u(1) is at t; m%BEMT_u(2) is t+dt - integer(intKi) :: i - integer(intKi) :: j - integer(intKi) :: iR ! Loop on rotors integer(intKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 @@ -1451,7 +1761,13 @@ subroutine RotCalcOutput( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrStat, Er ErrStat = ErrID_None ErrMsg = "" - + + if (present(NeedWriteOutput)) then + CalcWriteOutput = NeedWriteOutput + else + CalcWriteOutput = .true. ! by default, calculate WriteOutput unless told that we do not need it + end if + call SetInputs(p, p_AD, u, m, indx, errStat2, errMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -1462,7 +1778,7 @@ subroutine RotCalcOutput( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrStat, Er call BEMT_CalcOutput(t, m%BEMT_u(indx), p%BEMT, x%BEMT, xd%BEMT, z%BEMT, OtherState%BEMT, p_AD%AFI, m%BEMT_y, m%BEMT, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - call SetOutputsFromBEMT( p, m, y ) + call SetOutputsFromBEMT( p, u, m, y ) if ( p%CompAA ) then ! We need the outputs from BEMT as inputs to AeroAcoustics module @@ -1471,65 +1787,543 @@ subroutine RotCalcOutput( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrStat, Er call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call AA_CalcOutput(t, m%AA_u, p%AA, x%AA, xd%AA, z%AA, OtherState%AA, m%AA_y, m%AA, errStat2, errMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - end if + end if endif + if ( p%TwrAero ) then call ADTwr_CalcOutput(p, u, m, y, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) endif - call AD_CavtCrit(u, p, m, errStat2, errMsg2) - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + ! --- Tail Fin + if (p%TFinAero) then + call TFin_CalcOutput(p, p_AD, u, m, y, ErrStat2, ErrMsg2) + endif + + + !------------------------------------------------------- + ! get values to output to file: + !------------------------------------------------------- + if (CalcWriteOutput) then + call RotWriteOutputs(t, u, p, p_AD, x, xd, z, OtherState, y, m, m_AD, iRot, ErrStat, ErrMsg) + end if end subroutine RotCalcOutput +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine RotWriteOutputs( t, u, p, p_AD, x, xd, z, OtherState, y, m, m_AD, iRot, ErrStat, ErrMsg) +! NOTE: no matter how many channels are selected for output, all of the outputs are calculated +! All of the calculated output channels are placed into the m%AllOuts(:), while the channels selected for outputs are +! placed in the y%WriteOutput(:) array. +!.................................................................................................................................. + + REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds + TYPE(RotInputType), INTENT(IN ) :: u !< Inputs at Time t + TYPE(RotParameterType), INTENT(IN ) :: p !< Parameters + TYPE(AD_ParameterType), INTENT(IN ) :: p_AD !< Parameters + TYPE(RotContinuousStateType), INTENT(IN ) :: x !< Continuous states at t + TYPE(RotDiscreteStateType), INTENT(IN ) :: xd !< Discrete states at t + TYPE(RotConstraintStateType), INTENT(IN ) :: z !< Constraint states at t + TYPE(RotOtherStateType), INTENT(IN ) :: OtherState !< Other states at t + TYPE(RotOutputType), INTENT(INOUT) :: y !< Outputs computed at t (Input only so that mesh con- + !! nectivity information does not have to be recalculated) + type(RotMiscVarType), intent(inout) :: m !< Misc/optimization variables + TYPE(AD_MiscVarType), INTENT(INOUT) :: m_AD !< misc variables + INTEGER, INTENT(IN ) :: iRot !< Rotor index, needed for OLAF + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + + ! NOTE: m%BEMT_u(i) indices are set differently from the way OpenFAST typically sets up the u and uTimes arrays + integer, parameter :: indx = 1 ! m%BEMT_u(1) is at t; m%BEMT_u(2) is t+dt + integer(intKi) :: i + + integer(intKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + character(*), parameter :: RoutineName = 'RotCalcOutput' +! LOGICAL :: CalcWriteOutput + !------------------------------------------------------- + ! get values to output to file: + !------------------------------------------------------- + if (p%NumOuts > 0) then + call Calc_WriteOutput( p, p_AD, u, x, m, m_AD, y, OtherState, xd, indx, iRot, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + !............................................................................................................................... + ! Place the selected output channels into the WriteOutput(:) array with the proper sign: + !............................................................................................................................... + + do i = 1,p%NumOuts ! Loop through all selected output channels + y%WriteOutput(i) = p%OutParam(i)%SignM * m%AllOuts( p%OutParam(i)%Indx ) + end do ! i - All selected output channels + + end if + + if (p%BldNd_TotNumOuts > 0) then + y%WriteOutput(p%NumOuts+1:) = 0.0_ReKi + ! Now we need to populate the blade node outputs here + if (p%NumBlades > 0) then + call Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, indx, iRot, ErrStat2, ErrMsg2 ) ! Call after normal writeoutput. Will just postpend data on here. + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if + end if + +end subroutine RotWriteOutputs +!---------------------------------------------------------------------------------------------------------------------------------- subroutine AD_CavtCrit(u, p, m, errStat, errMsg) - TYPE(RotInputType), INTENT(IN ) :: u !< Inputs at Time t - TYPE(RotParameterType), INTENT(IN ) :: p !< Parameters - TYPE(RotMiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - !! nectivity information does not have to be recalculated) + TYPE(AD_InputType), INTENT(IN ) :: u !< Inputs at time t + TYPE(AD_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(AD_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 :: i,j - real(ReKi) :: SigmaCavitCrit, SigmaCavit + + ! Local variables + integer :: i, j + integer(intKi) :: iR, iW + real(ReKi) :: SigmaCavitCrit, SigmaCavit + real(ReKi) :: Vreltemp + real(ReKi) :: Cpmintemp errStat = ErrID_None errMsg = '' - if ( p%CavitCheck ) then ! Calculate the cavitation number for the airfoil at the node in quesiton, and compare to the critical cavitation number based on the vapour pressure and submerged depth - do j = 1,p%numBlades ! Loop through all blades - do i = 1,p%NumBlNds ! Loop through all nodes + do iR = 1,size(p%rotors) + if ( p%rotors(iR)%CavitCheck ) then ! Calculate the cavitation number for the airfoil at the node in quesiton, and compare to the critical cavitation number based on the vapour pressure and submerged depth + do j = 1,p%rotors(iR)%numBlades ! Loop through all blades + do i = 1,p%rotors(iR)%NumBlNds ! Loop through all nodes - if ( EqualRealNos( m%BEMT_y%Vrel(i,j), 0.0_ReKi ) ) call SetErrStat( ErrID_Fatal, 'Vrel cannot be zero to do a cavitation check', ErrStat, ErrMsg, 'AD_CavtCrit') - if (ErrStat >= AbortErrLev) return - - SigmaCavit= -1* m%BEMT_y%Cpmin(i,j) ! Local cavitation number on node j - SigmaCavitCrit= ( ( p%Patm + ( p%Gravity * (p%WtrDpth - ( u%HubMotion%Position(3,1)+u%HubMotion%TranslationDisp(3,1) ) - ( u%BladeMotion(j)%Position(3,i) + u%BladeMotion(j)%TranslationDisp(3,i) - u%HubMotion%Position(3,1))) * p%airDens) - p%Pvap ) / ( 0.5_ReKi * p%airDens * m%BEMT_y%Vrel(i,j)**2)) ! Critical value of Sigma, cavitation occurs if local cavitation number is greater than this + if ( p%WakeMod == WakeMod_BEMT .or. p%WakeMod == WakeMod_DBEMT ) then + Vreltemp = m%rotors(iR)%BEMT_y%Vrel(i,j) + Cpmintemp = m%rotors(iR)%BEMT_y%Cpmin(i,j) + else if ( p%WakeMod == WakeMod_FVW ) then + iW = p%FVW%Bld2Wings(iR,j) + Vreltemp = m%FVW%W(iW)%BN_Vrel(i) + Cpmintemp = m%FVW%W(iW)%BN_Cpmin(i) + end if + + if ( EqualRealNos( Vreltemp, 0.0_ReKi ) ) call SetErrStat( ErrID_Fatal, 'Vrel cannot be zero to do a cavitation check', ErrStat, ErrMsg, 'AD_CavtCrit' ) + if ( ErrStat >= AbortErrLev ) return + + SigmaCavit = -1 * Cpmintemp ! Local cavitation number on node j + SigmaCavitCrit = ( p%rotors(iR)%Patm + ( p%rotors(iR)%Gravity * ( abs( u%rotors(iR)%BladeMotion(j)%Position(3,i) + u%rotors(iR)%BladeMotion(j)%TranslationDisp(3,i) ) + p%rotors(iR)%MSL2SWL ) * p%rotors(iR)%airDens ) - p%rotors(iR)%Pvap ) / ( 0.5_ReKi * p%rotors(iR)%airDens * Vreltemp**2 ) ! Critical value of Sigma, cavitation occurs if local cavitation number is greater than this - if ( (SigmaCavitCrit < SigmaCavit) .and. (.not. (m%CavitWarnSet(i,j)) ) ) then - call WrScr( NewLine//'Cavitation occurred at blade '//trim(num2lstr(j))//' and node '//trim(num2lstr(i))//'.' ) - m%CavitWarnSet(i,j) = .true. + if ( ( SigmaCavitCrit < SigmaCavit ) .and. ( .not. ( m%rotors(iR)%CavitWarnSet(i,j) ) ) ) then + call WrScr( NewLine//'Cavitation occurred at blade '//trim(num2lstr(j))//' and node '//trim(num2lstr(i))//'.' ) + m%rotors(iR)%CavitWarnSet(i,j) = .true. end if - m%SigmaCavit(i,j)= SigmaCavit - m%SigmaCavitCrit(i,j)=SigmaCavitCrit + m%rotors(iR)%SigmaCavit(i,j) = SigmaCavit + m%rotors(iR)%SigmaCavitCrit(i,j) = SigmaCavitCrit - end do ! p%NumBlNds - end do ! p%numBlades - end if ! Cavitation check + end do ! p%NumBlNds + end do ! p%numBlades + end if ! Cavitation check + end do ! p%numRotors end subroutine AD_CavtCrit +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine calculates buoyant loads on an MHK turbine. +subroutine CalcBuoyantLoads( u, p, m, y, ErrStat, ErrMsg ) + TYPE(RotInputType), INTENT(IN ) :: u !< AD inputs - used for mesh node positions + TYPE(RotParameterType), INTENT(IN ) :: p !< Parameters + TYPE(RotMiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + TYPE(RotOutputType), INTENT(INOUT) :: y !< Outputs computed at t + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + + ! Local variables + INTEGER(IntKi) :: k !< Loop counter for blades + INTEGER(IntKi) :: j !< Loop counter for nodes + REAL(ReKi), DIMENSION(3) :: BlglobCB !< Global offset between aerodynamic center and center of buoyancy of blade node j + REAL(ReKi), DIMENSION(3) :: BlglobCBplus !< Global offset between aerodynamic center and center of buoyancy of blade node j+1 + REAL(ReKi), DIMENSION(3) :: HubglobCB !< Global offset between aerodynamic center and center of buoyancy of hub node + REAL(ReKi), DIMENSION(3) :: NacglobCB !< Global offset between nacelle reference position and center of buoyancy of nacelle node + REAL(ReKi), DIMENSION(3) :: BltmpPos !< Global position of blade node j + REAL(ReKi), DIMENSION(3) :: BltmpPosplus !< Global position of blade node j+1 + REAL(ReKi), DIMENSION(3) :: TwrtmpPos !< Global position of tower node j + REAL(ReKi), DIMENSION(3) :: TwrtmpPosplus !< Global position of tower node j+1 + REAL(ReKi), DIMENSION(3) :: HubtmpPos !< Global position of hub node + REAL(ReKi), DIMENSION(3) :: NactmpPos !< Global position of nacelle node + REAL(ReKi), DIMENSION(3) :: BlposCB !< Global position of the center of buoyancy of blade node j + REAL(ReKi), DIMENSION(3) :: BlposCBplus !< Global position of the center of buoyancy of blade node j+1 + REAL(ReKi), DIMENSION(3,p%NumBlades) :: Blposroot !< Global position of the center of buoyancy of blade root + REAL(ReKi), DIMENSION(3) :: Twrpostop !< Global position of the center of buoyancy of tower top + REAL(ReKi) :: BlheadAng !< Heading angle of blade element j + REAL(ReKi) :: BlinclAng !< Inclination angle of blade element j + REAL(ReKi) :: TwrheadAng !< Heading angle of tower element j + REAL(ReKi) :: TwrinclAng !< Inclination angle of tower element j + REAL(ReKi) :: BlforceAx !< Axial buoyant force at blade node j + REAL(ReKi) :: BlforceRad !< Radial buoyant force at blade node j + REAL(ReKi) :: Blmoment0 !< Nominal buoyant moment at blade node j + REAL(ReKi) :: Blmoment !< Buoyant moment at node j, adjusted for distribution of radial force bewteen blade nodes j and j+1 + REAL(ReKi) :: TwrforceAx !< Axial buoyant force at tower node j + REAL(ReKi) :: TwrforceRad !< Radial buoyant force at tower node j + REAL(ReKi) :: Twrmoment0 !< Nominal buoyant moment at tower node j + REAL(ReKi) :: Twrmoment !< Buoyant moment at tower j, adjusted for distribution of radial force bewteen tower nodes j and j+1 + REAL(ReKi), DIMENSION(3) :: BlforceB !< Buoyant force at blade node j in global coordinates + REAL(ReKi), DIMENSION(3) :: BlforceBplus !< Buoyant force at blade node j+1 in global coordinates + REAL(ReKi), DIMENSION(3) :: BlmomentB !< Buoyant moment at blade node j in global coordinates + REAL(ReKi), DIMENSION(3) :: BlmomentBplus !< Buoyant moment at blade node j+1 in global coordinates + REAL(ReKi), DIMENSION(3) :: TwrforceB !< Buoyant force at tower node j in global coordinates + REAL(ReKi), DIMENSION(3) :: TwrforceBplus !< Buoyant force at tower node j+1 in global coordinates + REAL(ReKi), DIMENSION(3) :: TwrmomentB !< Buoyant moment at tower node j in global coordinates + REAL(ReKi), DIMENSION(3) :: TwrmomentBplus !< Buoyant moment at tower node j+1 in global coordinates + REAL(ReKi), DIMENSION(3) :: HubforceB !< Buoyant force at hub node in global coordinates + REAL(ReKi), DIMENSION(3) :: HubmomentB !< Buoyant moment at hub node in global coordinates + REAL(ReKi), DIMENSION(3) :: NacforceB !< Buoyant force at nacelle node in global coordinates + REAL(ReKi), DIMENSION(3) :: NacmomentB !< Buoyant moment at nacelle node in global coordinates + REAL(ReKi), DIMENSION(3,p%NumBlades) :: BlforceBroot !< Buoyant force on blade root in global coordinates + REAL(ReKi), DIMENSION(3,p%NumBlades) :: BlmomentBroot !< Buoyant moment on blade root in global coordinates + REAL(ReKi), DIMENSION(3,p%NumBlades) :: BlforceRoot !< Buoyant force on element root in global coordinates + REAL(ReKi), DIMENSION(3,p%NumBlades) :: BlmomentRoot !< Buoyant moment on element root in global coordinates + REAL(ReKi), DIMENSION(3) :: BlforceTip !< Buoyant force on element tip in global coordinates + REAL(ReKi), DIMENSION(3) :: BlmomentTip !< Buoyant moment on element tip in global coordinates + REAL(ReKi), DIMENSION(3) :: TwrforceBtop !< Buoyant force on tower top in global coordinates + REAL(ReKi), DIMENSION(3) :: TwrmomentBtop !< Buoyant moment on tower top in global coordinates + REAL(ReKi), DIMENSION(p%NumBlNds,p%NumBlades,3) :: BlFBtmp !< Buoyant force at blade nodes in global coordinates + REAL(ReKi), DIMENSION(p%NumBlNds,p%NumBlades,3) :: BlMBtmp !< Buoyant moment at blade nodes in global coordinates + REAL(ReKi), DIMENSION(p%NumTwrNds,3) :: TwrFBtmp !< Buoyant force at tower nodes in global coordinates + REAL(ReKi), DIMENSION(p%NumTwrNds,3) :: TwrMBtmp !< Buoyant moment at tower nodes in global coordinates + REAL(ReKi), DIMENSION(3) :: HubFBtmp !< Buoyant force at hub node in global coordinates, passed to m%HubFB + REAL(ReKi), DIMENSION(3) :: HubMBtmp !< Buoyant moment at hub node in global coordinates, passed to m%HubMB + REAL(ReKi), DIMENSION(3) :: NacFBtmp !< Buoyant force at nacelle node in global coordinates, passed to m%NacFB + REAL(ReKi), DIMENSION(3) :: NacMBtmp !< Buoyant moment at nacelle node in global coordinates, passed to m%NacMB + REAL(ReKi), DIMENSION(3,p%NumBlades) :: MovvectorBR !< Vector from hub center to center of buoyancy of blade root + REAL(ReKi), DIMENSION(3,p%NumBlades) :: MovmomentBR !< Moment from moving blade root buoyant force from blade root to hub center + REAL(ReKi), DIMENSION(3) :: MovvectorTT !< Vector from nacelle reference position to center of buoyancy of tower top + REAL(ReKi), DIMENSION(3) :: MovmomentTT !< Moment from moving tower top buoyant force from tower top to nacelle reference position + CHARACTER(*), PARAMETER :: RoutineName = 'CalcBuoyantLoads' + + + ! Initialize variables for this routine + ErrStat = ErrID_None + ErrMsg = "" + BlFBtmp = 0.0_ReKi + BlMBtmp = 0.0_ReKi + TwrFBtmp = 0.0_ReKi + TwrMBtmp = 0.0_ReKi + HubFBtmp = 0.0_ReKi + HubMBtmp = 0.0_ReKi + NacFBtmp = 0.0_ReKi + NacMBtmp = 0.0_ReKi + TwrforceBtop = 0.0_ReKi + TwrmomentBtop = 0.0_ReKi + Twrpostop = 0.0_ReKi + + ! Blades + do k = 1,p%NumBlades ! loop through all blades + do j = 1,p%NumBlNds ! loop through all nodes + + ! Check that blade nodes do not go beneath the seabed or pierce the free surface + if ( u%BladeMotion(k)%Position(3,j) + u%BladeMotion(k)%TranslationDisp(3,j) >= p%MSL2SWL .OR. u%BladeMotion(k)%Position(3,j) + u%BladeMotion(k)%TranslationDisp(3,j) <= -p%WtrDpth ) & + call SetErrStat( ErrID_Fatal, 'Blades cannot go beneath the seabed or pierce the free surface', ErrStat, ErrMsg, 'CalcBuoyantLoads' ) + if ( ErrStat >= AbortErrLev ) return + + end do ! j = nodes + + do j = 1,p%NumBlNds - 1 ! loop through all nodes, except the last + + ! Global position of blade node + BltmpPos = u%BladeMotion(k)%Position(:,j) + u%BladeMotion(k)%TranslationDisp(:,j) - (/ 0.0_ReKi, 0.0_ReKi, p%MSL2SWL /) + BltmpPosplus = u%BladeMotion(k)%Position(:,j+1) + u%BladeMotion(k)%TranslationDisp(:,j+1) - (/ 0.0_ReKi, 0.0_ReKi, p%MSL2SWL /) + + ! Global offset between aerodynamic center and center of buoyancy of blade node + BlglobCB = matmul( [p%BlCenBn(j,k), p%BlCenBt(j,k), 0.0_ReKi ], u%BladeMotion(k)%Orientation(:,:,j) ) + BlglobCBplus = matmul( [p%BlCenBn(j+1,k), p%BlCenBt(j+1,k), 0.0_ReKi ], u%BladeMotion(k)%Orientation(:,:,j+1) ) + + ! Global position of the center of buoyancy of blade node + BlposCB = BltmpPos + BlglobCB + BlposCBplus = BltmpPosplus + BlglobCBplus + + ! Heading and inclination angles of blade element + BlheadAng = atan2( BlposCBplus(2) - BlposCB(2), BlposCBplus(1) - BlposCB(1) ) + BlinclAng = atan2( sqrt( (BlposCBplus(1) - BlposCB(1))**2 + (BlposCBplus(2) - BlposCB(2))**2 ), BlposCBplus(3) - BlposCB(3) ) + + ! Axial and radial buoyant forces and nominal buoyant moment at blade node + BlforceAx = -2.0_ReKi * pi * p%BlTaper(j,k) * p%AirDens * p%Gravity * p%BlDL(j,k) * ( BlposCB(3) * p%BlRad(j,k) + 0.5_ReKi * ( BlposCB(3) * p%BlTaper(j,k) + p%BlRad(j,k) * cos( BlinclAng ) ) * p%BlDL(j,k) & + + p%BlTaper(j,k) * cos( BlinclAng ) * p%BlDL(j,k)**2 / 3.0_ReKi ) + BlforceRad = -pi * p%AirDens * p%Gravity * p%BlDL(j,k) * ( p%BlRad(j,k)**2 + p%BlTaper(j,k) * p%BlRad(j,k) * p%BlDL(j,k) + p%BlTaper(j,k)**2 * p%BlDL(j,k)**2 / 3.0_ReKi ) * sin( BlinclAng ) + Blmoment0 = -pi * p%AirDens * p%Gravity * p%BlDL(j,k) * ( p%BlDL(j,k)**3 * p%BlTaper(j,k)**4 / 4.0_ReKi + p%BlDL(j,k)**3 * p%BlTaper(j,k)**2 / 4.0_ReKi + p%BlDL(j,k)**2 * p%BlTaper(j,k)**3 * p%BlRad(j,k) & + + 2.0_ReKi * p%BlDL(j,k)**2 * p%BlTaper(j,k) * p%BlRad(j,k) / 3.0_ReKi + 3.0_ReKi * p%BlDL(j,k) * p%BlTaper(j,k)**2 * p%BlRad(j,k)**2 / 2.0_ReKi + p%BlDL(j,k) * p%BlRad(j,k)**2 / 2.0_ReKi & + + p%BlTaper(j,k) * p%BlRad(j,k)**3 ) * sin( BlinclAng ) + + ! Buoyant moment at blade node, adjusted for distribution of radial force bewteen blade nodes j and j+1 + Blmoment = Blmoment0 - BlforceRad * p%BlAxCent(j,k) * p%BlDL(j,k) + + ! Buoyant force and moment at blade node in global coordinates + BlforceB(1) = cos( BlheadAng ) * ( BlforceAx * sin( BlinclAng ) + BlforceRad * cos( BlinclAng ) ) + BlforceB(2) = sin( BlheadAng ) * ( BlforceAx * sin( BlinclAng ) + BlforceRad * cos( BlinclAng ) ) + BlforceB(3) = BlforceAx * cos( BlinclAng ) - BlforceRad * sin( BlinclAng ) + BlmomentB(1) = -Blmoment * sin( BlheadAng ) + BlmomentB(2) = Blmoment * cos( BlheadAng ) + BlmomentB(3) = 0.0_ReKi + + ! Buoyant force and moment in global coordinates, distributed between adjacent nodes + BlforceBplus = BlforceB * p%BlAxCent(j,k) + BlforceB = BlforceB * ( 1 - p%BlAxCent(j,k) ) + BlmomentBplus = BlmomentB * p%BlAxCent(j,k) + BlmomentB = BlmomentB * ( 1 - p%BlAxCent(j,k) ) + + ! Buoyant force and moment on element "root" in global coordinates, added to existing force and moment + BlforceRoot(1,k) = -p%AirDens * p%Gravity * pi * p%BlRad(j,k)**2 * BlposCB(3) * sin( BlinclAng ) * cos( BlheadAng ) + BlforceRoot(2,k) = -p%AirDens * p%Gravity * pi * p%BlRad(j,k)**2 * BlposCB(3) * sin( BlinclAng ) * sin( BlheadAng ) + BlforceRoot(3,k) = -p%AirDens * p%Gravity * pi * p%BlRad(j,k)**2 * BlposCB(3) * cos( BlinclAng ) + BlmomentRoot(1,k) = p%AirDens * p%Gravity * pi * p%BlRad(j,k)**4 / 4.0_ReKi * sin( BlinclAng ) * sin( BlheadAng ) + BlmomentRoot(2,k) = -p%AirDens * p%Gravity * pi * p%BlRad(j,k)**4 / 4.0_ReKi * sin( BlinclAng ) * cos( BlheadAng ) + BlmomentRoot(3,k) = 0.0_ReKi + if ( j==1 ) then ! Buoyant force and moment on blade root and node position in global coordinates, saved for later use + BlforceBroot(:,k) = BlforceRoot(:,k) + BlmomentBroot(:,k) = BlmomentRoot(:,k) + Blposroot(:,k) = BlposCB + else + BlforceB = BlforceB + BlforceRoot(:,k) + BlmomentB = BlmomentB + BlmomentRoot(:,k) + end if + + ! Buoyant force and moment on element "tip" in global coordinates, added to existing force and moment + BlforceTip(1) = p%AirDens * p%Gravity * pi * p%BlRad(j+1,k)**2 * BlposCBplus(3) * sin( BlinclAng ) * cos( BlheadAng ) + BlforceTip(2) = p%AirDens * p%Gravity * pi * p%BlRad(j+1,k)**2 * BlposCBplus(3) * sin( BlinclAng ) * sin( BlheadAng ) + BlforceTip(3) = p%AirDens * p%Gravity * pi * p%BlRad(j+1,k)**2 * BlposCBplus(3) * cos( BlinclAng ) + BlmomentTip(1) = -p%AirDens * p%Gravity * pi * p%BlRad(j+1,k)**4 / 4.0_ReKi * sin( BlinclAng ) * sin( BlheadAng ) + BlmomentTip(2) = p%AirDens * p%Gravity * pi * p%BlRad(j+1,k)**4 / 4.0_ReKi * sin( BlinclAng ) * cos( BlheadAng ) + BlmomentTip(3) = 0.0_ReKi + + BlforceBplus = BlforceBplus + BlforceTip + BlmomentBplus = BlmomentBplus + BlmomentTip + + ! Buoyant moment in global coordinates, moved from center of buoyancy to aerodynamic center + BlmomentB(1) = BlmomentB(1) + BlglobCB(2) * BlforceB(3) - BlglobCB(3) * BlforceB(2) + BlmomentB(2) = BlmomentB(2) + BlglobCB(3) * BlforceB(1) - BlglobCB(1) * BlforceB(3) + BlmomentB(3) = BlmomentB(3) + BlglobCB(1) * BlforceB(2) - BlglobCB(2) * BlforceB(1) + BlmomentBplus(1) = BlmomentBplus(1) + BlglobCBplus(2) * BlforceBplus(3) - BlglobCBplus(3) * BlforceBplus(2) + BlmomentBplus(2) = BlmomentBplus(2) + BlglobCBplus(3) * BlforceBplus(1) - BlglobCBplus(1) * BlforceBplus(3) + BlmomentBplus(3) = BlmomentBplus(3) + BlglobCBplus(1) * BlforceBplus(2) - BlglobCBplus(2) * BlforceBplus(1) + + ! Sum loads at each node + BlFBtmp(j,k,:) = BlFBtmp(j,k,:) + BlforceB + BlFBtmp(j+1,k,:) = BlFBtmp(j+1,k,:) + BlforceBplus + BlMBtmp(j,k,:) = BlMBtmp(j,k,:) + BlmomentB + BlMBtmp(j+1,k,:) = BlMBtmp(j+1,k,:) + BlmomentBplus + + end do ! j = nodes + + ! Assign loads to point mesh + do j = 1,p%NumBlNds + m%BladeBuoyLoadPoint(k)%Force(:,j) = BlFBtmp(j,k,:) + m%BladeBuoyLoadPoint(k)%Moment(:,j) = BlMBtmp(j,k,:) + end do ! j = nodes + + ! Map point loads to line mesh + call Transfer_Point_to_Line2( m%BladeBuoyLoadPoint(k), m%BladeBuoyLoad(k), m%B_P_2_B_L(k), ErrStat, ErrMsg, u%BladeMotion(k), u%BladeMotion(k) ) + + end do ! k = blades + + ! Add buoyant loads to aerodynamic loads + do k = 1,p%NumBlades ! loop through all blades + do j = 1,p%NumBlNds ! loop through all nodes + y%BladeLoad(k)%Force(:,j) = y%BladeLoad(k)%Force(:,j) + m%BladeBuoyLoad(k)%Force(:,j) + y%BladeLoad(k)%Moment(:,j) = y%BladeLoad(k)%Moment(:,j) + m%BladeBuoyLoad(k)%Moment(:,j) + end do ! j = nodes + end do ! k = blades + + ! Tower + if ( p%NumTwrNds > 0 ) then + + do j = 1,p%NumTwrNds ! loop through all nodes + ! Check that tower nodes do not go beneath the seabed or pierce the free surface + if ( u%TowerMotion%Position(3,j) + u%TowerMotion%TranslationDisp(3,j) >= p%MSL2SWL .OR. u%TowerMotion%Position(3,j) + u%TowerMotion%TranslationDisp(3,j) < -p%WtrDpth ) & + call SetErrStat( ErrID_Fatal, 'The tower cannot go beneath the seabed or pierce the free surface', ErrStat, ErrMsg, 'CalcBuoyantLoads' ) + if ( ErrStat >= AbortErrLev ) return + end do + + do j = 1,p%NumTwrNds - 1 ! loop through all nodes, except the last + ! Global position of tower node + TwrtmpPos = u%TowerMotion%Position(:,j) + u%TowerMotion%TranslationDisp(:,j) - (/ 0.0_ReKi, 0.0_ReKi, p%MSL2SWL /) + TwrtmpPosplus = u%TowerMotion%Position(:,j+1) + u%TowerMotion%TranslationDisp(:,j+1) - (/ 0.0_ReKi, 0.0_ReKi, p%MSL2SWL /) + + ! Heading and inclination angles of tower element + TwrheadAng = atan2( TwrtmpPosplus(2) - TwrtmpPos(2), TwrtmpPosplus(1) - TwrtmpPos(1) ) + TwrinclAng = atan2( sqrt( (TwrtmpPosplus(1) - TwrtmpPos(1))**2 + (TwrtmpPosplus(2) - TwrtmpPos(2))**2 ), TwrtmpPosplus(3) - TwrtmpPos(3) ) + + ! Axial and radial buoyant forces and nominal buoyant moment at tower node + TwrforceAx = -2.0_ReKi * pi * p%TwrTaper(j) * p%AirDens * p%Gravity * p%TwrDL(j) * ( TwrtmpPos(3) * p%TwrRad(j) + 0.5_ReKi * ( TwrtmpPos(3) * p%TwrTaper(j) + p%TwrRad(j) * cos( TwrinclAng ) ) * p%TwrDL(j) & + + p%TwrTaper(j) * cos( TwrinclAng ) * p%TwrDL(j)**2 / 3.0_ReKi ) + TwrforceRad = -pi * p%AirDens * p%Gravity * p%TwrDL(j) * ( p%TwrRad(j)**2 + p%TwrTaper(j) * p%TwrRad(j) * p%TwrDL(j) + p%TwrTaper(j)**2 * p%TwrDL(j)**2 / 3.0_ReKi ) * sin( TwrinclAng ) + Twrmoment0 = -pi * p%AirDens * p%Gravity * p%TwrDL(j) * ( p%TwrDL(j)**3 * p%TwrTaper(j)**4 / 4.0_ReKi + p%TwrDL(j)**3 * p%TwrTaper(j)**2 / 4.0_ReKi + p%TwrDL(j)**2 * p%TwrTaper(j)**3 * p%TwrRad(j) & + + 2.0_ReKi * p%TwrDL(j)**2 * p%TwrTaper(j) * p%TwrRad(j) / 3.0_ReKi + 3.0_ReKi * p%TwrDL(j) * p%TwrTaper(j)**2 * p%TwrRad(j)**2 / 2.0_ReKi + p%TwrDL(j) * p%TwrRad(j)**2 / 2.0_ReKi & + + p%TwrTaper(j) * p%TwrRad(j)**3 ) * sin( TwrinclAng ) + + ! Buoyant moment at tower node, adjusted for distribution of radial force bewteen tower nodes j and j+1 + Twrmoment = Twrmoment0 - TwrforceRad * p%TwrAxCent(j) * p%TwrDL(j) + + ! Buoyant force and moment at tower node in global coordinates + TwrforceB(1) = cos( TwrheadAng ) * ( TwrforceAx * sin( TwrinclAng ) + TwrforceRad * cos( TwrinclAng ) ) + TwrforceB(2) = sin( TwrheadAng ) * ( TwrforceAx * sin( TwrinclAng ) + TwrforceRad * cos( TwrinclAng ) ) + TwrforceB(3) = TwrforceAx * cos( TwrinclAng ) - TwrforceRad * sin( TwrinclAng ) + TwrmomentB(1) = -Twrmoment * sin( TwrheadAng ) + TwrmomentB(2) = Twrmoment * cos( TwrheadAng ) + TwrmomentB(3) = 0.0_ReKi + + ! Buoyant force and moment in global coordinates, distributed between adjacent nodes + TwrforceBplus = TwrforceB * p%TwrAxCent(j) + TwrforceB = TwrforceB * ( 1 - p%TwrAxCent(j) ) + TwrmomentBplus = TwrmomentB * p%TwrAxCent(j) + TwrmomentB = TwrmomentB * ( 1 - p%TwrAxCent(j) ) + + ! Buoyant force and moment on tower top and node position in global coordinates, saved for later use + if ( j==p%NumTwrNds - 1 ) then + TwrforceBtop(1) = p%AirDens * p%Gravity * pi * p%TwrRad(j+1)**2 * TwrtmpPosplus(3) * sin( TwrinclAng ) * cos( TwrheadAng ) + TwrforceBtop(2) = p%AirDens * p%Gravity * pi * p%TwrRad(j+1)**2 * TwrtmpPosplus(3) * sin( TwrinclAng ) * sin( TwrheadAng ) + TwrforceBtop(3) = p%AirDens * p%Gravity * pi * p%TwrRad(j+1)**2 * TwrtmpPosplus(3) * cos( TwrinclAng ) + TwrmomentBtop(1) = -p%AirDens * p%Gravity * pi * p%TwrRad(j+1)**4 / 4.0_ReKi * sin( TwrinclAng ) * sin( TwrheadAng ) + TwrmomentBtop(2) = p%AirDens * p%Gravity * pi * p%TwrRad(j+1)**4 / 4.0_ReKi * sin( TwrinclAng ) * cos( TwrheadAng ) + TwrmomentBtop(3) = 0.0_ReKi + Twrpostop = TwrtmpPosplus + end if + + ! Sum loads at each node + TwrFBtmp(j,:) = TwrFBtmp(j,:) + TwrforceB + TwrFBtmp(j+1,:) = TwrFBtmp(j+1,:) + TwrforceBplus + TwrMBtmp(j,:) = TwrMBtmp(j,:) + TwrmomentB + TwrMBtmp(j+1,:) = TwrMBtmp(j+1,:) + TwrmomentBplus + + end do ! j = nodes + + ! Assign loads to point mesh + do j = 1,p%NumTwrNds + m%TwrBuoyLoadPoint%Force(:,j) = TwrFBtmp(j,:) + m%TwrBuoyLoadPoint%Moment(:,j) = TwrMBtmp(j,:) + end do ! j = nodes + + ! Map point loads to line mesh + call Transfer_Point_to_Line2( m%TwrBuoyLoadPoint, m%TwrBuoyLoad, m%T_P_2_T_L, ErrStat, ErrMsg, u%TowerMotion, u%TowerMotion ) + + end if + ! Add buoyant loads to aerodynamic loads + if ( p%TwrAero ) then + do j = 1,p%NumTwrNds ! loop through all nodes + y%TowerLoad%Force(:,j) = y%TowerLoad%Force(:,j) + m%TwrBuoyLoad%Force(:,j) + y%TowerLoad%Moment(:,j) = y%TowerLoad%Moment(:,j) + m%TwrBuoyLoad%Moment(:,j) + end do ! j = nodes + else + do j = 1,p%NumTwrNds ! loop through all nodes + y%TowerLoad%Force(:,j) = m%TwrBuoyLoad%Force(:,j) + y%TowerLoad%Moment(:,j) = m%TwrBuoyLoad%Moment(:,j) + end do ! j = nodes + end if + + ! Hub + + ! Set forces and moments to zero if VolHub is zero + if ( p%VolHub == 0 ) then + m%HubFB = HubFBtmp + m%HubMB = HubMBtmp + else + ! Check that hub node does not go beneath the seabed or pierce the free surface + if ( u%HubMotion%Position(3,1) + u%HubMotion%TranslationDisp(3,1) >= p%MSL2SWL .OR. u%HubMotion%Position(3,1) + u%HubMotion%TranslationDisp(3,1) <= -p%WtrDpth ) & + call SetErrStat( ErrID_Fatal, 'The hub cannot go beneath the seabed or pierce the free surface', ErrStat, ErrMsg, 'CalcBuoyantLoads' ) + if ( ErrStat >= AbortErrLev ) return + + ! Global position of hub node + HubtmpPos = u%HubMotion%Position(:,1) + u%HubMotion%TranslationDisp(:,1) - (/ 0.0_ReKi, 0.0_ReKi, p%MSL2SWL /) + + ! Global offset between hub center and center of buoyancy of hub node + HubglobCB = matmul( [p%HubCenBx, 0.0_ReKi, 0.0_ReKi ], u%HubMotion%Orientation(:,:,1) ) + + ! Buoyant force at hub node in global coordinates + HubforceB(1) = 0.0_ReKi + HubforceB(2) = 0.0_ReKi + HubforceB(3) = p%AirDens * p%Gravity * p%VolHub + + ! Buoyant moment in global coordinates, caused by moving buoyant force from center of buoyancy to hub center + HubmomentB(1) = HubglobCB(2) * HubforceB(3) + HubmomentB(2) = -HubglobCB(1) * HubforceB(3) + HubmomentB(3) = 0.0_ReKi + + ! Moment caused by moving blade root buoyant force from blade root to hub center + do k = 1,p%NumBlades ! loop through all blades + MovvectorBR(:,k) = Blposroot(:,k) - HubtmpPos + MovmomentBR(1,k) = MovvectorBR(2,k) * BlforceBroot(3,k) - MovvectorBR(3,k) * BlforceBroot(2,k) + MovmomentBR(2,k) = MovvectorBR(3,k) * BlforceBroot(1,k) - MovvectorBR(1,k) * BlforceBroot(3,k) + MovmomentBR(3,k) = MovvectorBR(1,k) * BlforceBroot(2,k) - MovvectorBR(2,k) * BlforceBroot(1,k) + end do ! k = blades + + ! Buoyant forces and moments in global coordinates, combined at hub center + HubFBtmp = HubforceB + HubMBtmp = HubmomentB + do k = 1,p%NumBlades ! loop through all blades + HubFBtmp = HubFBtmp + BlforceBroot(:,k) + HubMBtmp = HubMBtmp + BlmomentBroot(:,k) + MovmomentBR(:,k) + end do ! k = blades + + ! Pass to m variable + m%HubFB = HubFBtmp + m%HubMB = HubMBtmp + end if + + ! Assign buoyant loads to hub mesh + y%HubLoad%Force(:,1) = HubFBtmp + y%HubLoad%Moment(:,1) = HubMBtmp + + ! Nacelle + + ! Set forces and moments to zero if VolNac is zero + if ( p%VolNac == 0 ) then + m%NacFB = NacFBtmp + m%NacMB = NacMBtmp + else + ! Check that nacelle node does not go beneath the seabed or pierce the free surface + if ( u%NacelleMotion%Position(3,1) + u%NacelleMotion%TranslationDisp(3,1) >= p%MSL2SWL .OR. u%NacelleMotion%Position(3,1) + u%NacelleMotion%TranslationDisp(3,1) <= -p%WtrDpth ) & + call SetErrStat( ErrID_Fatal, 'The nacelle cannot go beneath the seabed or pierce the free surface', ErrStat, ErrMsg, 'CalcBuoyantLoads' ) + if ( ErrStat >= AbortErrLev ) return + + ! Global position of nacelle node + NactmpPos = u%NacelleMotion%Position(:,1) + u%NacelleMotion%TranslationDisp(:,1) - (/ 0.0_ReKi, 0.0_ReKi, p%MSL2SWL /) + + ! Global offset between nacelle reference position and center of buoyancy of nacelle node + NacglobCB = matmul( p%NacCenB, u%NacelleMotion%Orientation(:,:,1) ) + + ! Buoyant force at nacelle node in global coordinates + NacforceB(1) = 0.0_ReKi + NacforceB(2) = 0.0_ReKi + NacforceB(3) = p%AirDens * p%Gravity * p%VolNac + + ! Buoyant moment in global coordinates, caused by moving buoyant force from center of buoyancy to nacelle reference point + NacmomentB(1) = NacglobCB(2) * NacforceB(3) + NacmomentB(2) = -NacglobCB(1) * NacforceB(3) + NacmomentB(3) = 0.0_ReKi + + ! Moment caused by moving tower top buoyant force from tower top to nacelle reference point + MovvectorTT = Twrpostop - NactmpPos + MovmomentTT(1) = MovvectorTT(2) * TwrforceBtop(3) - MovvectorTT(3) * TwrforceBtop(2) + MovmomentTT(2) = MovvectorTT(3) * TwrforceBtop(1) - MovvectorTT(1) * TwrforceBtop(3) + MovmomentTT(3) = MovvectorTT(1) * TwrforceBtop(2) - MovvectorTT(2) * TwrforceBtop(1) + + ! Buoyant forces and moments in global coordinates, combined at nacelle reference point + NacFBtmp = NacforceB + TwrforceBtop + NacMBtmp = NacmomentB + TwrmomentBtop + MovmomentTT + + ! Pass to m variable + m%NacFB = NacFBtmp + m%NacMB = NacMBtmp + end if + + ! Assign buoyant loads to nacelle mesh + y%NacelleLoad%Force(:,1) = NacFBtmp + y%NacelleLoad%Moment(:,1) = NacMBtmp + +end subroutine CalcBuoyantLoads !---------------------------------------------------------------------------------------------------------------------------------- !> Tight coupling routine for solving for the residual of the constraint state equations -subroutine AD_CalcConstrStateResidual( Time, u, p, p_AD, x, xd, z, OtherState, m, z_residual, ErrStat, ErrMsg ) +subroutine AD_CalcConstrStateResidual( Time, u, p, x, xd, z, OtherState, m, z_residual, ErrStat, ErrMsg ) !.................................................................................................................................. REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds TYPE(AD_InputType), INTENT(IN ) :: u !< Inputs at Time TYPE(AD_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(AD_ParameterType), INTENT(IN ) :: p_AD !< Parameters TYPE(AD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time TYPE(AD_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at Time TYPE(AD_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at Time (possibly a guess) @@ -1553,12 +2347,12 @@ subroutine AD_CalcConstrStateResidual( Time, u, p, p_AD, x, xd, z, OtherState, m do iR=1, size(p%rotors) - call RotCalcConstrStateResidual( Time, u%rotors(iR), p%rotors(iR), p_AD, x%rotors(iR), xd%rotors(iR), z%rotors(iR), OtherState%rotors(iR), m%rotors(iR), z_residual%rotors(iR), ErrStat, ErrMsg ) + call RotCalcConstrStateResidual( Time, u%rotors(iR), p%rotors(iR), p, x%rotors(iR), xd%rotors(iR), z%rotors(iR), OtherState%rotors(iR), m%rotors(iR), z_residual%rotors(iR), ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) enddo end subroutine AD_CalcConstrStateResidual - +!---------------------------------------------------------------------------------------------------------------------------------- !> Tight coupling routine for solving for the residual of the constraint state equations subroutine RotCalcConstrStateResidual( Time, u, p, p_AD, x, xd, z, OtherState, m, z_residual, ErrStat, ErrMsg ) !.................................................................................................................................. @@ -1579,7 +2373,6 @@ subroutine RotCalcConstrStateResidual( Time, u, p, p_AD, x, xd, z, OtherState, m ! Local variables integer, parameter :: indx = 1 ! m%BEMT_u(1) is at t; m%BEMT_u(2) is t+dt - integer(intKi) :: iR ! rotor index integer(intKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 character(*), parameter :: RoutineName = 'RotCalcConstrStateResidual' @@ -1622,7 +2415,6 @@ subroutine RotCalcContStateDeriv( t, u, p, p_AD, x, xd, z, OtherState, m, dxdt, CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! local variables - INTEGER(IntKi) :: iR ! 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(*), PARAMETER :: RoutineName = 'RotCalcContStateDeriv' @@ -1730,88 +2522,280 @@ subroutine SetInputsForBEMT(p, u, m, indx, errStat, errMsg) real(ReKi) :: rmax real(R8Ki) :: thetaBladeNds(p%NumBlNds,p%NumBlades) real(R8Ki) :: Azimuth(p%NumBlades) - integer(intKi) :: j ! loop counter for nodes integer(intKi) :: k ! loop counter for blades integer(intKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 - character(*), parameter :: RoutineName = 'SetInputsForBEMT' - - ! note ErrStat and ErrMsg are set in GeomWithoutSweepPitchTwist: + character(*), parameter :: RoutineName = 'SetInputsForBEMT' + ! NEW VAR + real(ReKi) :: numer, denom, ratio, signOfAngle ! helper variables for calculating u%chi0 + real(ReKi) :: tilt, yaw + real(ReKi) :: SkewVec(3), tmp_skewVec(3), x_hat_wind(3), tmpD(3), tmpW(3) + real(R8Ki) :: windCrossDisk(3) + real(R8Ki) :: windCrossDiskMag + real(R8Ki) :: x_vec(3), y_vec(3), z_vec(3) + real(R8Ki) :: elemPosRelToHub(3,p%NUMBLNDS) + real(R8Ki) :: elemPosRotorProj(3,p%NUMBLNDS) + real(R8Ki) :: dr(3), dz(3) + real(R8Ki) :: theta(3) + real(R8Ki) :: orientation(3,3) + real(R8Ki) :: orientationBladeAzimuth(3,3,1) + ErrStat = ErrID_None + ErrMsg = "" ! Get disk average values and orientations - call DiskAvgValues(p, u, m, x_hat_disk, y_hat_disk, z_hat_disk, Azimuth) - call GeomWithoutSweepPitchTwist(p,u,m,thetaBladeNds,ErrStat,ErrMsg) - if (ErrStat >= AbortErrLev) return + call DiskAvgValues(p, u, m, x_hat_disk, y_hat_disk, z_hat_disk, Azimuth) ! also sets m%V_diskAvg, m%V_dot_x + + ! Velocity in disk normal + m%BEMT_u(indx)%V0 = m%AvgDiskVelDist ! Note: used for SkewWake Cont + m%BEMT_u(indx)%x_hat_disk = x_hat_disk + if (p%AeroProjMod==APM_BEM_NoSweepPitchTwist .or. p%AeroProjMod==APM_LiftingLine) then + ! NOTE: m%V_diskAvg contains translational velocity and disturbed wind + m%BEMT_u(indx)%Un_disk = dot_product( m%V_diskAvg, x_hat_disk ) ! NOTE: used for DBEMT only + elseif (p%AeroProjMod==APM_BEM_Polar) then + ! NOTE: m%AvgDiskVel contains undisturbed wind only + m%BEMT_u(indx)%Un_disk = dot_product( m%AvgDiskVel, x_hat_disk ) ! NOTE: used for DBEMT only + endif - ! Velocity in disk normal - m%BEMT_u(indx)%Un_disk = m%V_dot_x + ! Calculate Yaw and Tilt for use in xVelCorr + ! Define a vector wrt which the yaw is defined + denom = twonorm(m%V_diskAvg) + if (EqualRealNos(denom, 0.0_ReKi)) then + x_hat_wind = 0.0_ReKi + else + x_hat_wind = m%V_diskAvg/denom + end if + ! Yaw + tmpD = x_hat_disk + tmpD(3) = 0.0 + tmpW = x_hat_wind + tmpW(3) = 0.0 + denom = TwoNorm(tmpD)*TwoNorm(tmpW) + if (EqualRealNos(denom, 0.0_ReKi)) then + yaw = 0.0_ReKi + else + yaw = acos(max(-1.0_ReKi,min(1.0_ReKi,dot_product(tmpD,tmpW)/denom))) + end if + tmp_skewVec = cross_product(tmpW,tmpD); + yaw = sign(yaw,tmp_skewVec(3)) + m%Yaw = yaw + + ! Tilt + tmpD = x_hat_disk + tmpD(2) = 0.0 + tmpW = x_hat_wind + tmpW(2) = 0.0 + denom = TwoNorm(tmpD)*TwoNorm(tmpW) + if (EqualRealNos(denom, 0.0_Reki)) then + tilt = 0.0_ReKi + else + tilt = acos(max(-1.0_ReKi,min(1.0_ReKi,dot_product(tmpD,tmpW)/denom))) + end if + + tmp_skewVec = cross_product(tmpW,tmpD) + tilt = sign(tilt,tmp_skewVec(2)) + m%tilt = tilt - ! "Angular velocity of rotor" rad/s + ! "Angular velocity of rotor" rad/s m%BEMT_u(indx)%omega = dot_product( u%HubMotion%RotationVel(:,1), x_hat_disk ) - ! "Angle between the vector normal to the rotor plane and the wind vector (e.g., the yaw angle in the case of no tilt)" rad - tmp_sz = TwoNorm( m%V_diskAvg ) - if ( EqualRealNos( tmp_sz, 0.0_ReKi ) ) then + ! "Angle between the vector normal to the rotor plane and the wind vector (e.g., the yaw angle in the case of no tilt)" rad + denom = TwoNorm( m%V_diskAvg ) + if (EqualRealNos(0.0_ReKi, denom)) then m%BEMT_u(indx)%chi0 = 0.0_ReKi else ! make sure we don't have numerical issues that make the ratio outside +/-1 - tmp_sz_y = min( 1.0_ReKi, m%V_dot_x / tmp_sz ) - tmp_sz_y = max( -1.0_ReKi, tmp_sz_y ) + numer = m%V_dot_x + ratio = numer / denom + m%BEMT_u(indx)%chi0 = acos( max( min( ratio, 1.0_ReKi ), -1.0_ReKi ) ) + + SkewVec = cross_product( m%V_diskAvg, x_hat_disk ) + ! NOTE: chi0 is used only as cos(chi0), tan(chi0)**2, or abs(chi0), so the sign calculated here is only for output purposes + ! Depending on yaw and/or tilt, z and/or y component of the cross product above will dicatate the sign of chi0. + ! Pending Test: What happens when y or z are of similar magnitude + if (abs(SkewVec(2))>abs(SkewVec(3))) then + signofAngle = sign(1.0_ReKi,SkewVec(2)) + else + signofAngle = sign(1.0_ReKi,SkewVec(3)) + endif + + if (p%AeroBEM_Mod /= BEMMod_2D) then + m%BEMT_u(indx)%chi0 = sign( m%BEMT_u(indx)%chi0, signOfAngle ) + endif + end if + + + !.......................... + ! Compute skew azimuth angle + !.......................... + if (p%AeroProjMod==APM_BEM_NoSweepPitchTwist .or. p%AeroProjMod==APM_LiftingLine) then + + m%BEMT_u(indx)%psi = Azimuth + elseif (p%AeroProjMod==APM_BEM_Polar) then + + do k=1,p%NumBlades + ! Determine current azimuth angle and pitch axis vector of blade k + call Calculate_MeshOrientation_Rel2Hub(u%BladeRootMotion(k), u%HubMotion, x_hat_disk, orientationBladeAzimuth) + + ! Extract azimuth angle for blade k + ! NOTE: EB, this might need improvements (express wrt hub, also deal with case hubRad=0). This is likely not psi_skew. + theta = -EulerExtract( transpose(orientationBladeAzimuth(:,:,1)) ) + m%BEMT_u(indx)%psi(k) = theta(1) + end do !k=blades + + ! Find the most-downwind azimuth angle needed by the skewed wake correction model + windCrossDisk = cross_product( x_hat_wind, x_hat_disk ) + windCrossDiskMag = TwoNorm( windCrossDisk ) + if (windCrossDiskMag <= 0.01_ReKi) then + m%BEMT_u(indx)%psiSkewOffset = PiBy2 + else + ! Assemble blade azimuth unit vectors and orientation matrix + z_vec = windCrossDisk / windCrossDiskMag + x_vec = x_hat_disk + y_vec = cross_product( z_vec, x_vec ) + orientation(1,:) = x_vec + orientation(2,:) = y_vec + orientation(3,:) = z_vec + ! Extract azimuth angle for most down-wind blade orientation + theta = -EulerExtract( transpose(orientation) ) + m%BEMT_u(indx)%psiSkewOffset = theta(1)+PiBy2 ! cross-product of wind vector and rotor axis will lead downwind blade azimuth by 90 degrees + end if + + + else + call WrScr('AeroProjMod not supported - should never happen') + STOP + endif + + !.......................... + ! Compute pitch and blade azimuth (stored in misc) + !.......................... + call StorePitchAndAzimuth(p, u, m, ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + !.......................... + ! Set main geometry parameters (orientatioAnnulus, Curve, rLocal) + !.......................... + if (p%AeroProjMod==APM_BEM_NoSweepPitchTwist .or. p%AeroProjMod==APM_LiftingLine) then + + ! orientationAnnulus and curve + if (p%AeroProjMod==APM_BEM_NoSweepPitchTwist) then + call Calculate_MeshOrientation_NoSweepPitchTwist(p, u, m, ErrStat=ErrStat, ErrMsg=ErrMsg, thetaBladeNds=thetaBladeNds) + else + call Calculate_MeshOrientation_LiftingLine(p, u, m, ErrStat=ErrStat, ErrMsg=ErrMsg, thetaBladeNds=thetaBladeNds) + endif + + ! local radius (normalized distance from rotor centerline) + do k=1,p%NumBlades + call Calculate_MeshOrientation_Rel2Hub(u%BladeMotion(k), u%HubMotion, x_hat_disk, elemPosRelToHub_save=elemPosRelToHub, elemPosRotorProj_save=elemPosRotorProj) + do j=1,p%NumBlNds + m%BEMT_u(indx)%rLocal(j,k) = TwoNorm( elemPosRotorProj(:,j) ) + end do !j=nodes + end do !k=blades - m%BEMT_u(indx)%chi0 = acos( tmp_sz_y ) + elseif (p%AeroProjMod==APM_BEM_Polar) then + do k=1,p%NumBlades + + ! Determine current azimuth angle and pitch axis vector of blade k, element j + call Calculate_MeshOrientation_Rel2Hub(u%BladeMotion(k), u%HubMotion, x_hat_disk, m%orientationAnnulus(:,:,:,k), elemPosRelToHub_save=elemPosRelToHub, elemPosRotorProj_save=elemPosRotorProj) + + !.......................... + ! Compute local radius + !.......................... + do j=1,p%NumBlNds + m%BEMT_u(indx)%rLocal(j,k) = TwoNorm( elemPosRotorProj(:,j) ) + end do !j=nodes - end if + !.......................... + ! Determine local J = dr/dz + !.......................... + do j=2,p%NumBlNds + ! Get element orientation vectors to compute J = dr/dz + ! and (future) override orientation information in BladeMotion%Orientation + dr(:) = elemPosRotorProj(:,j) - elemPosRotorProj(:,j-1) + dz(:) = elemPosRelToHub(:,j) - elemPosRelToHub(:,j-1) + + denom = TwoNorm(dz(:)) + if (EqualRealNos(denom,0.0_ReKi)) then ! this should not happen, but we'll check anyway + m%BEMT_u(indx)%drdz(j,k) = 0.0_ReKi + else + m%BEMT_u(indx)%drdz(j,k) = TwoNorm(dr(:)) / denom + end if + end do ! j + m%BEMT_u(indx)%drdz(1,k) = m%BEMT_u(indx)%drdz(2,k) + end do !k=blades + else + call WrScr('AeroProjMod not supported - should never happen') + STOP + endif ! ProjMod + - ! "Azimuth angle" rad - m%bemt_u(indx)%psi = Azimuth + !.......................... + ! local blade angles + !.......................... + if (p%AeroProjMod==APM_BEM_NoSweepPitchTwist .or. p%AeroProjMod==APM_LiftingLine) then + ! Theta + do k=1,p%NumBlades + do j=1,p%NumBlNds + m%BEMT_u(indx)%theta(j,k) = thetaBladeNds(j,k) ! local pitch + twist (aerodyanmic + elastic) angle of the jth node in the kth blade + + ! NOTE: curve computed by Calculate_MeshOrientation_* + m%BEMT_u(indx)%toeAngle(j,k) = 0.0_ReKi + m%BEMT_u(indx)%cantAngle(j,k) = 0.0_ReKi + end do !j=nodes + end do !k=blades + elseif (p%AeroProjMod==APM_BEM_Polar) then + do k=1,p%NumBlades + do j=1,p%NumBlNds + ! Get local blade cant angle and twist + orientation = matmul( u%BladeMotion(k)%Orientation(:,:,j), transpose( m%orientationAnnulus(:,:,j,k) ) ) + theta = EulerExtract( orientation ) + ! Get toe angle + m%BEMT_u(indx)%toeAngle(j,k) = theta(1) + ! cant angle (including aeroelastic deformation) + m%BEMT_u(indx)%cantAngle(j,k) = theta(2) + m%Curve(j,k) = theta(2) + ! twist (including pitch and aeroelastic deformation) + m%BEMT_u(indx)%theta(j,k) = -theta(3) + end do !j=nodes + end do !k=blades + else + call WrScr('AeroProjMod not supported - should never happen') + STOP + endif ! ProjMod - ! theta, "Twist angle (includes all sources of twist)" rad - ! Vx, "Local axial velocity at node" m/s - ! Vy, "Local tangential velocity at node" m/s + !.......................... + ! Get normal, tangential and radial velocity components of the jth node in the kth blade + !.......................... do k=1,p%NumBlades do j=1,p%NumBlNds - - m%BEMT_u(indx)%theta(j,k) = thetaBladeNds(j,k) ! local pitch + twist (aerodyanmic + elastic) angle of the jth node in the kth blade - - x_hat = m%WithoutSweepPitchTwist(1,:,j,k) - y_hat = m%WithoutSweepPitchTwist(2,:,j,k) + ! Velocity in "p" or "w" system (depending) on AeroProjMod tmp = m%DisturbedInflow(:,j,k) - u%BladeMotion(k)%TranslationVel(:,j) ! rel_V(j)_Blade(k) - - m%BEMT_u(indx)%Vx(j,k) = dot_product( tmp, x_hat ) ! normal component (normal to the plane, not chord) of the inflow velocity of the jth node in the kth blade - m%BEMT_u(indx)%Vy(j,k) = dot_product( tmp, y_hat ) ! tangential component (tangential to the plane, not chord) of the inflow velocity of the jth node in the kth blade + m%BEMT_u(indx)%Vx(j,k) = dot_product( tmp, m%orientationAnnulus(1,:,j,k) ) ! normal component (normal to the plane, not chord) of the inflow velocity of the jth node in the kth blade + m%BEMT_u(indx)%Vy(j,k) = dot_product( tmp, m%orientationAnnulus(2,:,j,k) ) !+ TwoNorm(m%DisturbedInflow(:,j,k))*(sin()*sin(tilt)*)! tangential component (tangential to the plane, not chord) of the inflow velocity of the jth node in the kth blade + m%BEMT_u(indx)%Vz(j,k) = dot_product( tmp, m%orientationAnnulus(3,:,j,k) ) ! radial component (tangential to the plane, not chord) of the inflow velocity of the jth node in the kth blade - - !jmj says omega_z and PitchRate are the same things - ! inputs for DBEMT (DBEMT_Mod == DBEMT_cont_tauConst) - if (allocated(m%BEMT_u(indx)%Vx_elast_dot)) then - m%BEMT_u(indx)%Vx_elast_dot(j,k) = dot_product( u%BladeMotion(k)%TranslationAcc(:,j), x_hat ) ! normal component (normal to the plane, not chord) of the inflow velocity of the jth node in the kth blade - m%BEMT_u(indx)%Vy_elast_dot(j,k) = dot_product( u%BladeMotion(k)%TranslationAcc(:,j), y_hat ) ! tangential component (tangential to the plane, not chord) of the inflow velocity of the jth node in the kth blade - end if + ! NOTE: We'll likely remove that: + m%BEMT_u(indx)%xVelCorr(j,k) = TwoNorm(m%DisturbedInflow(:,j,k))*( sin(yaw)*sin(-m%BEMT_u(indx)%cantAngle(j,k))*sin(m%BEMT_u(indx)%psi(k)) & + + sin(tilt)*cos(yaw)*sin(-m%BEMT_u(indx)%cantAngle(j,k))*cos(m%BEMT_u(indx)%psi(k)) ) !m%BEMT_u(indx)%Vy(j,k)*sin(-theta(2))*sin(m%BEMT_u(indx)%psi(k)) + end do !j=nodes + end do !k=blades + + !.......................... + ! inputs for CDBEMT and CUA + !.......................... + do k=1,p%NumBlades + do j=1,p%NumBlNds ! inputs for CUA (and CDBEMT): - m%BEMT_u(indx)%omega_z(j,k) = dot_product( u%BladeMotion(k)%RotationVel( :,j), m%WithoutSweepPitchTwist(3,:,j,k) ) ! rotation of no-sweep-pitch coordinate system around z of the jth node in the kth blade + m%BEMT_u(indx)%omega_z(j,k) = dot_product( u%BladeMotion(k)%RotationVel( :,j), m%orientationAnnulus(3,:,j,k) ) ! rotation of no-sweep-pitch coordinate system around z of the jth node in the kth blade end do !j=nodes end do !k=blades - ! "Radial distance from center-of-rotation to node" m - - do k=1,p%NumBlades - do j=1,p%NumBlNds - - ! displaced position of the jth node in the kth blade relative to the hub: - tmp = u%BladeMotion(k)%Position(:,j) + u%BladeMotion(k)%TranslationDisp(:,j) & - - u%HubMotion%Position(:,1) - u%HubMotion%TranslationDisp(:,1) - - ! local radius (normalized distance from rotor centerline) - tmp_sz_y = dot_product( tmp, y_hat_disk )**2 - tmp_sz = dot_product( tmp, z_hat_disk )**2 - m%BEMT_u(indx)%rLocal(j,k) = sqrt( tmp_sz + tmp_sz_y ) - - end do !j=nodes - end do !k=blades - + !.......................... + ! User/Control property for AFI + !.......................... m%BEMT_u(indx)%UserProp = u%UserProp @@ -1837,57 +2821,176 @@ subroutine DiskAvgValues(p, u, m, x_hat_disk, y_hat_disk, z_hat_disk, Azimuth) type(RotInputType), intent(in ) :: u !< AD Inputs at Time type(RotMiscVarType), intent(inout) :: m !< Misc/optimization variables real(R8Ki), intent( out) :: x_hat_disk(3) - real(R8Ki), intent( out) :: y_hat_disk(3) - real(R8Ki), intent( out) :: z_hat_disk(3) - real(R8Ki), intent( out) :: Azimuth(p%NumBlades) + real(R8Ki), optional, intent( out) :: y_hat_disk(3) + real(R8Ki), optional, intent( out) :: z_hat_disk(3) + real(R8Ki), optional, intent( out) :: Azimuth(p%NumBlades) real(ReKi) :: z_hat(3) real(ReKi) :: tmp(3) + real(ReKi) :: V_elast_diskAvg(3) real(ReKi) :: tmp_sz, tmp_sz_y integer(intKi) :: j ! loop counter for nodes integer(intKi) :: k ! loop counter for blades - ! calculate disk-averaged relative wind speed, V_DiskAvg - m%V_diskAvg = 0.0_ReKi + ! calculate disk-averaged velocities + m%AvgDiskVel = 0.0_ReKi + m%AvgDiskVelDist = 0.0_ReKi ! TODO potentially get rid of that in the future do k=1,p%NumBlades do j=1,p%NumBlNds - tmp = m%DisturbedInflow(:,j,k) - u%BladeMotion(k)%TranslationVel(:,j) - m%V_diskAvg = m%V_diskAvg + tmp + m%AvgDiskVelDist = m%AvgDiskVelDist + m%DisturbedInflow(:,j,k) + m%AvgDiskVel = m%AvgDiskVel + u%InflowOnBlade(:,j,k) end do end do - m%V_diskAvg = m%V_diskAvg / real( p%NumBlades * p%NumBlNds, ReKi ) + m%AvgDiskVelDist = m%AvgDiskVelDist / real( p%NumBlades * p%NumBlNds, ReKi ) + m%AvgDiskVel = m%AvgDiskVel / real( p%NumBlades * p%NumBlNds, ReKi ) + ! calculate disk-averaged elastic velocity + V_elast_diskAvg = 0.0_ReKi + do k=1,p%NumBlades + do j=1,p%NumBlNds + V_elast_diskAvg = V_elast_diskAvg + u%BladeMotion(k)%TranslationVel(:,j) + end do + end do + V_elast_diskAvg = V_elast_diskAvg / real( p%NumBlades * p%NumBlNds, ReKi ) + + ! calculate disk-averaged relative wind speed, V_DiskAvg + m%V_diskAvg = m%AvgDiskVelDist - V_elast_diskAvg + + ! orientation vectors: x_hat_disk = u%HubMotion%Orientation(1,:,1) !actually also x_hat_hub m%V_dot_x = dot_product( m%V_diskAvg, x_hat_disk ) - tmp = m%V_dot_x * x_hat_disk - m%V_diskAvg - tmp_sz = TwoNorm(tmp) - if ( EqualRealNos( tmp_sz, 0.0_ReKi ) ) then - y_hat_disk = u%HubMotion%Orientation(2,:,1) - z_hat_disk = u%HubMotion%Orientation(3,:,1) - else - y_hat_disk = tmp / tmp_sz - z_hat_disk = cross_product( m%V_diskAvg, x_hat_disk ) / tmp_sz - end if + + + ! These values are not used in the Envision code base; stored here only for easier merging from OpenFAST: + if (present(y_hat_disk)) then + + tmp = m%V_dot_x * x_hat_disk - m%V_diskAvg + tmp_sz = TwoNorm(tmp) + if ( EqualRealNos( tmp_sz, 0.0_ReKi ) ) then + y_hat_disk = u%HubMotion%Orientation(2,:,1) + z_hat_disk = u%HubMotion%Orientation(3,:,1) + else + y_hat_disk = tmp / tmp_sz + z_hat_disk = cross_product( m%V_diskAvg, x_hat_disk ) / tmp_sz + end if + + ! "Azimuth angle" rad + do k=1,p%NumBlades + z_hat = u%BladeRootMotion(k)%Orientation(3,:,1) + tmp_sz_y = -1.0*dot_product(z_hat,y_hat_disk) + tmp_sz = dot_product(z_hat,z_hat_disk) + if ( EqualRealNos(tmp_sz_y,0.0_ReKi) .and. EqualRealNos(tmp_sz,0.0_ReKi) ) then + Azimuth(k) = 0.0_ReKi + else + Azimuth(k) = atan2( tmp_sz_y, tmp_sz ) + end if + end do + + end if + +end subroutine DiskAvgValues +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine StorePitchAndAzimuth(p, u, m, ErrStat,ErrMsg) + type(RotParameterType), intent(in ) :: p !< AD parameters + type(RotInputType), intent(in ) :: u !< AD Inputs at Time + type(RotMiscVarType), 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) :: theta(3) + real(R8Ki) :: orientation(3,3) + integer(intKi) :: k ! loop counter for blades + integer(intKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + character(*), parameter :: RoutineName = 'StorePitchAndAzimuth' + + ErrStat = ErrID_None + ErrMsg = "" - ! "Azimuth angle" rad + ! theta, "Twist angle (includes all sources of twist)" rad do k=1,p%NumBlades - z_hat = u%BladeRootMotion(k)%Orientation(3,:,1) - tmp_sz_y = -1.0*dot_product(z_hat,y_hat_disk) - tmp_sz = dot_product(z_hat,z_hat_disk) - if ( EqualRealNos(tmp_sz_y,0.0_ReKi) .and. EqualRealNos(tmp_sz,0.0_ReKi) ) then - Azimuth(k) = 0.0_ReKi - else - Azimuth(k) = atan2( tmp_sz_y, tmp_sz ) + ! orientation = rotation from hub 2 bl + ! orientation = matmul( u%BladeRootMotion(k)%Orientation(:,:,1), transpose( u%HubMotion%Orientation(:,:,1) ) ) + call LAPACK_gemm( 'n', 't', 1.0_R8Ki, u%BladeRootMotion(k)%Orientation(:,:,1), u%HubMotion%Orientation(:,:,1), 0.0_R8Ki, orientation, errStat2, errMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + theta = EulerExtract( orientation ) !hub_theta_root(k) + if (k<=size(BPitch)) then + m%AllOuts( BPitch( k) ) = -theta(3)*R2D ! save this value of pitch for potential output + endif + if (k<=size(m%hub_theta_x_root)) then + m%hub_theta_x_root(k) = theta(1) ! save this value for FAST.Farm (Azimuth wrt hub motion) + end if + enddo + +endsubroutine StorePitchAndAzimuth +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine Calculate_MeshOrientation_Rel2Hub(Mesh1, HubMotion, x_hat_disk, orientationAnnulus, elemPosRelToHub_save, elemPosRotorProj_save) + TYPE(MeshType), intent(in) :: Mesh1 !< either BladeMotion or BladeRootMotion mesh + TYPE(MeshType), intent(in) :: HubMotion !< HubMotion mesh + REAL(R8Ki), intent(in) :: x_hat_disk(3) + REAL(R8Ki), optional, intent(out) :: orientationAnnulus(3,3,Mesh1%NNodes) + real(R8Ki), optional, intent(out) :: elemPosRelToHub_save( 3,Mesh1%NNodes) + real(R8Ki), optional, intent(out) :: elemPosRotorProj_save(3,Mesh1%NNodes) + + real(R8Ki) :: x_hat_annulus(3) ! rotor normal unit vector (local rotor reference frame) + real(R8Ki) :: y_hat_annulus(3) ! annulus tangent unit vector (local rotor reference frame) + real(R8Ki) :: z_hat_annulus(3) ! annulus radial unit vector (local rotor reference frame) +! real(R8Ki) :: chordVec(3) + + integer(intKi) :: j ! loop counter for nodes + + REAL(R8Ki) :: HubAbsPosition(3) + real(R8Ki) :: elemPosRelToHub(3) ! local copies of + real(R8Ki) :: elemPosRotorProj(3) ! local copies of + + + HubAbsPosition = HubMotion%Position(:,1) + HubMotion%TranslationDisp(:,1) + + !.......................... + ! orientation + !.......................... + + do j=1,Mesh1%NNodes + !chordVec(:,j) = Mesh1%orientation(:,2,j) + ! Project element position onto the rotor plane + elemPosRelToHub = Mesh1%Position(:,j) + Mesh1%TranslationDisp(:,j) - HubAbsPosition ! + 0.00_ReKi*chordVec(:,j)*p%BEMT%chord(j,k) + elemPosRotorProj = elemPosRelToHub - x_hat_disk * dot_product( x_hat_disk, elemPosRelToHub ) + + if (present(orientationAnnulus)) then + ! Get unit vectors of the local annulus reference frame + z_hat_annulus = elemPosRotorProj / TwoNorm( elemPosRotorProj ) + x_hat_annulus = x_hat_disk + y_hat_annulus = cross_product( z_hat_annulus, x_hat_annulus ) + + ! Form a orientation matrix for the annulus reference frame + orientationAnnulus(1,:,j) = x_hat_annulus + orientationAnnulus(2,:,j) = y_hat_annulus + orientationAnnulus(3,:,j) = z_hat_annulus end if + + if (present(elemPosRelToHub_save) ) elemPosRelToHub_save( :,j) = elemPosRelToHub + if (present(elemPosRotorProj_save)) elemPosRotorProj_save(:,j) = elemPosRotorProj end do -end subroutine DiskAvgValues + + ! orientation = matmul( Mesh1(k)%Orientation(:,:,j), transpose( orientationAnnulus(:,:,j) ) ) + ! theta = EulerExtract( orientation ) + ! ! Get toe angle + ! toeAngle(j) = theta(1) + ! ! cant angle (including aeroelastic deformation) + ! cantAngle(j) = theta(2) + ! Curve(j) = theta(2) + ! ! twist (including pitch and aeroelastic deformation) + ! thetaNds(j) = -theta(3) + +end subroutine Calculate_MeshOrientation_Rel2Hub !---------------------------------------------------------------------------------------------------------------------------------- -subroutine GeomWithoutSweepPitchTwist(p,u,m,thetaBladeNds,ErrStat,ErrMsg) +! Calculate_MeshOrientation_NoSweepPitchTwist sets orientationAnnulus, Curve and potential Blades nodes angles +subroutine Calculate_MeshOrientation_NoSweepPitchTwist(p, u, m, thetaBladeNds, toeBladeNds, ErrStat, ErrMsg) type(RotParameterType), intent(in ) :: p !< AD parameters type(RotInputType), intent(in ) :: u !< AD Inputs at Time type(RotMiscVarType), intent(inout) :: m !< Misc/optimization variables - real(R8Ki), intent( out) :: thetaBladeNds(p%NumBlNds,p%NumBlades) + real(R8Ki), optional, intent( out) :: thetaBladeNds(p%NumBlNds,p%NumBlades) + real(R8Ki), optional, intent( out) :: toeBladeNds(p%NumBlNds,p%NumBlades) integer(IntKi), intent( out) :: ErrStat !< Error status of the operation character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None real(R8Ki) :: theta(3) @@ -1898,66 +3001,78 @@ subroutine GeomWithoutSweepPitchTwist(p,u,m,thetaBladeNds,ErrStat,ErrMsg) integer(intKi) :: k ! loop counter for blades integer(intKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 - character(*), parameter :: RoutineName = 'GeomWithoutSweepPitchTwist' + character(*), parameter :: RoutineName = 'Calculate_MeshOrientation_NoSweepPitchTwist' ErrStat = ErrID_None ErrMsg = "" - if (p%AeroProjMod==0) then - ! theta, "Twist angle (includes all sources of twist)" rad - ! Vx, "Local axial velocity at node" m/s - ! Vy, "Local tangential velocity at node" m/s - do k=1,p%NumBlades - ! construct system equivalent to u%BladeRootMotion(k)%Orientation, but without the blade-pitch angle: - ! orientation = rotation from hub 2 bl - call LAPACK_gemm( 'n', 't', 1.0_R8Ki, u%BladeRootMotion(k)%Orientation(:,:,1), u%HubMotion%Orientation(:,:,1), 0.0_R8Ki, orientation, errStat2, errMsg2) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - theta = EulerExtract( orientation ) !hub_theta_root(k) - if (k<=3) then - m%AllOuts( BPitch( k) ) = -theta(3)*R2D ! save this value of pitch for potential output - endif - theta(3) = 0.0_ReKi - m%hub_theta_x_root(k) = theta(1) ! save this value for FAST.Farm - - orientation = EulerConstruct( theta ) ! rotation from hub 2 non-pitched blade - orientation_nopitch = matmul( orientation, u%HubMotion%Orientation(:,:,1) ) ! withoutPitch_theta_Root(k) ! rotation from global 2 non-pitched blade + do k=1,p%NumBlades + ! orientation = rotation from hub 2 bl + call LAPACK_gemm( 'n', 't', 1.0_R8Ki, u%BladeRootMotion(k)%Orientation(:,:,1), u%HubMotion%Orientation(:,:,1), 0.0_R8Ki, orientation, errStat2, errMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + theta = EulerExtract( orientation ) !hub_theta_root(k) + theta(3) = 0.0_ReKi - do j=1,p%NumBlNds + ! construct system equivalent to u%BladeRootMotion(k)%Orientation, but without the blade-pitch angle: + orientation = EulerConstruct( theta ) ! rotation from hub 2 non-pitched blade + orientation_nopitch = matmul( orientation, u%HubMotion%Orientation(:,:,1) ) ! withoutPitch_theta_Root(k) ! rotation from global 2 non-pitched blade - ! form coordinate system equivalent to u%BladeMotion(k)%Orientation(:,:,j) but without live sweep (due to in-plane - ! deflection), blade-pitch and twist (aerodynamic + elastic) angles: + do j=1,p%NumBlNds - ! orientation = matmul( u%BladeMotion(k)%Orientation(:,:,j), transpose(orientation_nopitch) ) - ! orientation = rotation from non pitched blade 2 balde section - call LAPACK_gemm( 'n', 't', 1.0_R8Ki, u%BladeMotion(k)%Orientation(:,:,j), orientation_nopitch, 0.0_R8Ki, orientation, errStat2, errMsg2) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - theta = EulerExtract( orientation ) !root(k)WithoutPitch_theta(j)_blade(k) + ! form coordinate system equivalent to u%BladeMotion(k)%Orientation(:,:,j) but without live sweep (due to in-plane + ! deflection), blade-pitch and twist (aerodynamic + elastic) angles: - thetaBladeNds(j,k) = -theta(3) ! local pitch + twist (aerodyanmic + elastic) angle of the jth node in the kth blade + ! orientation = matmul( u%BladeMotion(k)%Orientation(:,:,j), transpose(orientation_nopitch) ) + ! orientation = rotation from non pitched blade 2 balde section + call LAPACK_gemm( 'n', 't', 1.0_R8Ki, u%BladeMotion(k)%Orientation(:,:,j), orientation_nopitch, 0.0_R8Ki, orientation, errStat2, errMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + theta = EulerExtract( orientation ) !root(k)WithoutPitch_theta(j)_blade(k) + m%Curve( j,k) = theta(2) ! save value for possible output later + if (present(thetaBladeNds)) thetaBladeNds(j,k) = -theta(3) ! local pitch + twist (aerodyanmic + elastic) angle of the jth node in the kth blade + if (present(toeBladeNds )) toeBladeNds( j,k) = theta(1) - theta(1) = 0.0_ReKi - theta(3) = 0.0_ReKi - m%Curve(j,k) = theta(2) ! save value for possible output later - m%WithoutSweepPitchTwist(:,:,j,k) = matmul( EulerConstruct( theta ), orientation_nopitch ) ! WithoutSweepPitch+Twist_theta(j)_Blade(k) + theta(1) = 0.0_ReKi + theta(3) = 0.0_ReKi + m%orientationAnnulus(:,:,j,k) = matmul( EulerConstruct( theta ), orientation_nopitch ) ! WithoutSweepPitch+Twist_theta(j)_Blade(k) - end do !j=nodes - end do !k=blades - else if (p%AeroProjMod==1) then - ! Generic blade, we don't assume where the axes are, and we keep the default orientation - do k=1,p%NumBlades - m%hub_theta_x_root(k) = 0.0_ReKi ! ill-defined, TODO - do j=1,p%NumBlNds - thetaBladeNds(j,k) = 0.0_ReKi ! local pitch + twist (aerodyanmic + elastic) angle of the jth node in the kth blade - m%Curve(j,k) = 0.0_ReKi ! ill-defined, TODO - m%WithoutSweepPitchTwist(:,:,j,k) = u%BladeMotion(k)%Orientation(:,:,j) - enddo + end do !j=nodes + end do !k=blades +end subroutine Calculate_MeshOrientation_NoSweepPitchTwist +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine Calculate_MeshOrientation_LiftingLine(p, u, m, thetaBladeNds, toeBladeNds, ErrStat, ErrMsg) + type(RotParameterType), intent(in ) :: p !< AD parameters + type(RotInputType), intent(in ) :: u !< AD Inputs at Time + type(RotMiscVarType), intent(inout) :: m !< Misc/optimization variables + real(R8Ki), optional, intent( out) :: thetaBladeNds(p%NumBlNds,p%NumBlades) + real(R8Ki), optional, intent( out) :: toeBladeNds(p%NumBlNds,p%NumBlades) + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + real(R8Ki) :: theta(3) + real(R8Ki) :: orientation(3,3) + integer(intKi) :: j ! loop counter for nodes + integer(intKi) :: k ! loop counter for blades + integer(intKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + character(*), parameter :: RoutineName = 'Calculate_MeshOrientation_LiftingLine' + ErrStat = ErrID_None + ErrMsg = "" + + do k=1,p%NumBlades + do j=1,p%NumBlNds + m%orientationAnnulus(:,:,j,k) = u%BladeMotion(k)%Orientation(:,:,j) + enddo + + do j=1,p%NumBlNds + orientation = matmul( u%BladeMotion(k)%Orientation(:,:,j), transpose( m%orientationAnnulus(:,:,j,k) ) ) + theta = EulerExtract( orientation ) + m%Curve( j,k) = theta(2) ! TODO + if (present(thetaBladeNds)) thetaBladeNds(j,k) = -theta(3) + if (present(toeBladeNds )) toeBladeNds( j,k) = theta(1) enddo - else - ErrStat = ErrID_Fatal - ErrMsg ='GeomWithoutSweepPitchTwist: AeroProjMod not supported '//trim(num2lstr(p%AeroProjMod)) - endif -end subroutine GeomWithoutSweepPitchTwist + end do !k=blades + +end subroutine Calculate_MeshOrientation_LiftingLine !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine sets m%FVW_u(indx). subroutine SetInputsForFVW(p, u, m, errStat, errMsg) @@ -1969,26 +3084,32 @@ subroutine SetInputsForFVW(p, u, m, errStat, errMsg) character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None real(R8Ki) :: x_hat_disk(3) - real(R8Ki) :: y_hat_disk(3) - real(R8Ki) :: z_hat_disk(3) real(R8Ki), allocatable :: thetaBladeNds(:,:) - real(R8Ki), allocatable :: Azimuth(:) integer(intKi) :: tIndx integer(intKi) :: iR ! Loop on rotors integer(intKi) :: j, k ! loop counter for blades + integer(intKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 character(*), parameter :: RoutineName = 'SetInputsForFVW' integer :: iW - integer :: nWings + + ErrStat = ErrID_None + ErrMsg = "" do tIndx=1,size(u) do iR =1, size(p%rotors) allocate(thetaBladeNds(p%rotors(iR)%NumBlNds, p%rotors(iR)%NumBlades)) - allocate(azimuth(p%rotors(iR)%NumBlades)) ! Get disk average values and orientations ! NOTE: needed because it sets m%V_diskAvg and m%V_dot_x, needed by CalcOutput.. - call DiskAvgValues(p%rotors(iR), u(tIndx)%rotors(iR), m%rotors(iR), x_hat_disk, y_hat_disk, z_hat_disk, Azimuth) - call GeomWithoutSweepPitchTwist(p%rotors(iR),u(tIndx)%rotors(iR), m%rotors(iR), thetaBladeNds,ErrStat,ErrMsg) + call DiskAvgValues(p%rotors(iR), u(tIndx)%rotors(iR), m%rotors(iR), x_hat_disk) ! also sets m%V_diskAvg and m%V_dot_x + if (p%rotors(iR)%AeroProjMod==APM_BEM_NoSweepPitchTwist) then + call Calculate_MeshOrientation_NoSweepPitchTwist(p%rotors(iR),u(tIndx)%rotors(iR), m%rotors(iR), thetaBladeNds,ErrStat=ErrStat2,ErrMsg=ErrMsg2) ! sets m%orientationAnnulus, m%Curve + else if (p%rotors(iR)%AeroProjMod==APM_LiftingLine) then + call Calculate_MeshOrientation_LiftingLine (p%rotors(iR),u(tIndx)%rotors(iR), m%rotors(iR), thetaBladeNds,ErrStat=ErrStat2,ErrMsg=ErrMsg2) ! sets m%orientationAnnulus, m%Curve + endif + call StorePitchAndAzimuth(p%rotors(iR), u(tIndx)%rotors(iR), m%rotors(iR), ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat >= AbortErrLev) return ! Rather than use a meshcopy, we will just copy what we need to the WingsMesh @@ -1998,8 +3119,7 @@ subroutine SetInputsForFVW(p, u, m, errStat, errMsg) iW=p%FVW%Bld2Wings(iR,k) if ( u(tIndx)%rotors(iR)%BladeMotion(k)%nNodes /= m%FVW_u(tIndx)%WingsMesh(iW)%nNodes ) then - ErrStat = ErrID_Fatal - ErrMsg = RoutineName//": WingsMesh contains different number of nodes than the BladeMotion mesh" + call SetErrStat(ErrID_Fatal,"WingsMesh contains different number of nodes than the BladeMotion mesh",ErrStat,ErrMsg,RoutineName) return endif m%FVW%W(iW)%PitchAndTwist(:) = thetaBladeNds(:,k) ! local pitch + twist (aerodyanmic + elastic) angle of the jth node in the kth blade @@ -2012,11 +3132,10 @@ subroutine SetInputsForFVW(p, u, m, errStat, errMsg) ! Inputs for dynamic stall (see SetInputsForBEMT) do j=1,p%rotors(iR)%NumBlNds ! inputs for CUA, section pitch/torsion rate - m%FVW_u(tIndx)%W(iW)%omega_z(j) = dot_product( u(tIndx)%rotors(iR)%BladeMotion(k)%RotationVel( :,j), m%rotors(iR)%WithoutSweepPitchTwist(3,:,j,k) ) ! rotation of no-sweep-pitch coordinate system around z of the jth node in the kth blade + m%FVW_u(tIndx)%W(iW)%omega_z(j) = dot_product( u(tIndx)%rotors(iR)%BladeMotion(k)%RotationVel( :,j), m%rotors(iR)%orientationAnnulus(3,:,j,k) ) ! rotation of no-sweep-pitch coordinate system around z of the jth node in the kth blade end do !j=nodes enddo ! k blades if (allocated(thetaBladeNds)) deallocate(thetaBladeNds) - if (allocated(azimuth)) deallocate(azimuth) enddo ! iR, rotors if (ALLOCATED(m%FVW_u(tIndx)%V_wind)) then @@ -2026,7 +3145,8 @@ subroutine SetInputsForFVW(p, u, m, errStat, errMsg) if (p%FVW%TwrShadowOnWake) then do iR =1, size(p%rotors) if (p%rotors(iR)%TwrPotent /= TwrPotent_none .or. p%rotors(iR)%TwrShadow /= TwrShadow_none) then - call TwrInflArray( p%rotors(iR), u(tIndx)%rotors(iR), m%rotors(iR), m%FVW%r_wind, m%FVW_u(tIndx)%V_wind, ErrStat, ErrMsg ) + call TwrInflArray( p%rotors(iR), u(tIndx)%rotors(iR), m%rotors(iR), m%FVW%r_wind, m%FVW_u(tIndx)%V_wind, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat >= AbortErrLev) return endif enddo @@ -2034,7 +3154,8 @@ subroutine SetInputsForFVW(p, u, m, errStat, errMsg) endif do iR =1, size(p%rotors) ! Disturbed inflow for UA on Lifting line Mesh Points - call SetDisturbedInflow(p%rotors(iR), p, u(tIndx)%rotors(iR), m%rotors(iR), errStat, errMsg) + call SetDisturbedInflow(p%rotors(iR), p, u(tIndx)%rotors(iR), m%rotors(iR), errStat2, errMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) do k=1,p%rotors(iR)%NumBlades iW=p%FVW%Bld2Wings(iR,k) m%FVW_u(tIndx)%W(iW)%Vwnd_LL(1:3,:) = m%rotors(iR)%DisturbedInflow(1:3,:,k) @@ -2079,46 +3200,79 @@ subroutine SetInputsForAA(p, u, m, errStat, errMsg) end do end do end subroutine SetInputsForAA -!---------------------------------------------------------------------------------------------------------------------------------- - !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine converts outputs from BEMT (stored in m%BEMT_y) into values on the AeroDyn BladeLoad output mesh. -subroutine SetOutputsFromBEMT(p, m, y ) +subroutine SetOutputsFromBEMT( p, u, m, y ) type(RotParameterType), intent(in ) :: p !< AD parameters + type(RotInputType), intent(in ) :: u !< AD Inputs at Time type(RotOutputType), intent(inout) :: y !< AD outputs type(RotMiscVarType), intent(inout) :: m !< Misc/optimization variables - !type(BEMT_OutputType), intent(in ) :: BEMT_y ! BEMT outputs - !real(ReKi), intent(in ) :: WithoutSweepPitchTwist(:,:,:,:) ! modified orientation matrix integer(intKi) :: j ! loop counter for nodes integer(intKi) :: k ! loop counter for blades - real(reki) :: force(3) - real(reki) :: moment(3) - real(reki) :: q + real(reki) :: force(3),forceAirfoil(3) + real(reki) :: moment(3),momentAirfoil(3) + real(reki) :: q ! local dynamic pressure + real(reki) :: c ! local chord length + real(reki) :: aoa ! local angle of attack + real(reki) :: Cl,Cd,Cm ! local airfoil lift, drag and pitching moment coefficients + real(reki) :: Cn,Ct ! local airfoil normal and tangential force coefficients - - force(3) = 0.0_ReKi - moment(1:2) = 0.0_ReKi do k=1,p%NumBlades do j=1,p%NumBlNds + ! Compute local Cn and Ct in the airfoil reference frame + aoa = m%BEMT_y%AOA(j,k) + Cl = m%BEMT_y%cl(j,k) + Cd = m%BEMT_y%cd(j,k) + Cm = m%BEMT_y%cm(j,k) + Cn = Cl*cos(aoa) + Cd*sin(aoa) + Ct = -Cl*sin(aoa) + Cd*cos(aoa) ! NOTE: this is not Ct but Cy_a (y_a going towards the TE) + + ! Dimensionalize the aero forces and moment q = 0.5 * p%airDens * m%BEMT_y%Vrel(j,k)**2 ! dynamic pressure of the jth node in the kth blade + c = p%BEMT%chord(j,k) + forceAirfoil(1) = Cn * q * c + forceAirfoil(2) = Ct * q * c + forceAirfoil(3) = 0.0_reki + momentAirfoil(1) = 0.0_reki + momentAirfoil(2) = 0.0_reki + momentAirfoil(3) = Cm * q * c**2 + m%M(j,k) = momentAirfoil(3) ! TODO EB + + ! NOTE! - NOTE! - NOTE! - NOTE! - NOTE! - NOTE! - NOTE! - NOTE! - NOTE! - NOTE! - NOTE! - NOTE! - NOTE! - NOTE! + !EAM (fix this!) These output variables are possibly not what they should be + ! relative to the original AeroDyn manual and intent !!!! force(1) = m%BEMT_y%cx(j,k) * q * p%BEMT%chord(j,k) ! X = normal force per unit length (normal to the plane, not chord) of the jth node in the kth blade force(2) = -m%BEMT_y%cy(j,k) * q * p%BEMT%chord(j,k) ! Y = tangential force per unit length (tangential to the plane, not chord) of the jth node in the kth blade - moment(3)= m%BEMT_y%cm(j,k) * q * p%BEMT%chord(j,k)**2 ! M = pitching moment per unit length of the jth node in the kth blade + force(3) = m%BEMT_y%cz(j,k) * q * p%BEMT%chord(j,k) ! Z = axial force per unit length of the jth node in the kth blade + + moment(1)= m%BEMT_y%Cmx(j,k) * q * p%BEMT%chord(j,k)**2 ! Mx = pitching moment (x-component) per unit length of the jth node in the kth blade + moment(2)= m%BEMT_y%Cmy(j,k) * q * p%BEMT%chord(j,k)**2 ! My = pitching moment (y-component) per unit length of the jth node in the kth blade + moment(3)= m%BEMT_y%Cmz(j,k) * q * p%BEMT%chord(j,k)**2 ! Mz = pitching moment (z-component) per unit length of the jth node in the kth blade ! save these values for possible output later: m%X(j,k) = force(1) m%Y(j,k) = force(2) - m%M(j,k) = moment(3) + m%Z(j,k) = force(3) + m%Mx(j,k) = moment(1) + m%My(j,k) = moment(2) + m%Mz(j,k) = moment(3) + + if (p%BEMT%BEM_Mod==BEMMod_2D) then ! note: because force and moment are 1-d arrays, I'm calculating the transpose of the force and moment outputs - ! so that I don't have to take the transpose of WithoutSweepPitchTwist(:,:,j,k) - y%BladeLoad(k)%Force(:,j) = matmul( force, m%WithoutSweepPitchTwist(:,:,j,k) ) ! force per unit length of the jth node in the kth blade - y%BladeLoad(k)%Moment(:,j) = matmul( moment, m%WithoutSweepPitchTwist(:,:,j,k) ) ! moment per unit length of the jth node in the kth blade + ! so that I don't have to take the transpose of orientationAnnulus(:,:,j,k) + y%BladeLoad(k)%Force(:,j) = matmul( force, m%orientationAnnulus(:,:,j,k) ) ! force per unit length of the jth node in the kth blade + y%BladeLoad(k)%Moment(:,j) = matmul( moment, m%orientationAnnulus(:,:,j,k) ) ! moment per unit length of the jth node in the kth blade + else + ! Transfer loads from the airfoil frame to the blade frame + y%BladeLoad(k)%Force(:,j) = matmul( forceAirfoil, u%BladeMotion(k)%Orientation(:,:,j) ) ! force per unit length of the jth node in the kth blade + y%BladeLoad(k)%Moment(:,j) = matmul( momentAirfoil, u%BladeMotion(k)%Orientation(:,:,j) ) ! moment per unit length of the jth node in the kth blade + endif end do !j=nodes end do !k=blades @@ -2157,7 +3311,7 @@ subroutine SetOutputsFromFVW(t, u, p, OtherState, x, xd, m, y, ErrStat, ErrMsg) type(AFI_OutputType) :: AFI_interp ! Resulting values from lookup table real(ReKi) :: UrelWind_s(3) ! Relative wind (wind+str) in section coords real(ReKi) :: Cx, Cy - real(ReKi) :: Cl_Static, Cd_Static, Cm_Static + real(ReKi) :: Cl_Static, Cd_Static, Cm_Static, Cpmin real(ReKi) :: Cl_dyn, Cd_dyn, Cm_dyn type(UA_InputType), pointer :: u_UA ! Alias to shorten notations integer(IntKi), parameter :: InputIndex=1 ! we will always use values at t in this routine @@ -2181,7 +3335,7 @@ subroutine SetOutputsFromFVW(t, u, p, OtherState, x, xd, m, y, ErrStat, ErrMsg) Vstr = u%rotors(iR)%BladeMotion(k)%TranslationVel(1:3,j) Vwnd = m%rotors(iR)%DisturbedInflow(1:3,j,k) ! NOTE: contains tower shadow theta = m%FVW%W(iW)%PitchAndTwist(j) ! TODO - call FVW_AeroOuts( m%rotors(iR)%WithoutSweepPitchTwist(1:3,1:3,j,k), u%rotors(iR)%BladeMotion(k)%Orientation(1:3,1:3,j), & ! inputs + call FVW_AeroOuts( m%rotors(iR)%orientationAnnulus(1:3,1:3,j,k), u%rotors(iR)%BladeMotion(k)%Orientation(1:3,1:3,j), & ! inputs theta, Vstr(1:3), Vind(1:3), VWnd(1:3), p%rotors(iR)%KinVisc, p%FVW%W(iW)%chord_LL(j), & ! inputs AxInd, TanInd, Vrel, phi, alpha, Re, UrelWind_s(1:3), ErrStat2, ErrMsg2 ) ! outputs call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SetOutputsFromFVW') @@ -2191,6 +3345,7 @@ subroutine SetOutputsFromFVW(t, u, p, OtherState, x, xd, m, y, ErrStat, ErrMsg) Cl_Static = AFI_interp%Cl Cd_Static = AFI_interp%Cd Cm_Static = AFI_interp%Cm + Cpmin = AFI_interp%Cpmin ! Set dynamic to the (will be same as static if UA_Flag is false) Cl_dyn = AFI_interp%Cl @@ -2207,7 +3362,7 @@ subroutine SetOutputsFromFVW(t, u, p, OtherState, x, xd, m, y, ErrStat, ErrMsg) u_UA%v_ac(1) = sin(u_UA%alpha)*u_UA%U u_UA%v_ac(2) = cos(u_UA%alpha)*u_UA%U - ! calculated in m%FVW%u_UA??? : u_UA%omega = dot_product( u%rotors(iR)%BladeMotion(k)%RotationVel( :,j), m%rotors(iR)%WithoutSweepPitchTwist(3,:,j,k) ) ! rotation of no-sweep-pitch coordinate system around z of the jth node in the kth blade + ! calculated in m%FVW%u_UA??? : u_UA%omega = dot_product( u%rotors(iR)%BladeMotion(k)%RotationVel( :,j), m%rotors(iR)%orientationAnnulus(3,:,j,k) ) ! rotation of no-sweep-pitch coordinate system around z of the jth node in the kth blade call UA_CalcOutput(j, 1, t, u_UA, m%FVW%W(iW)%p_UA, x%FVW%UA(iW), xd%FVW%UA(iW), OtherState%FVW%UA(iW), p%AFI(p%FVW%W(iW)%AFindx(j,1)), m%FVW%W(iW)%y_UA, m%FVW%W(iW)%m_UA, errStat2, errMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SetOutputsFromFVW') Cl_dyn = m%FVW%W(iW)%y_UA%Cl @@ -2227,12 +3382,16 @@ subroutine SetOutputsFromFVW(t, u, p, OtherState, x, xd, m, y, ErrStat, ErrMsg) ! save these values for possible output later: m%rotors(iR)%X(j,k) = force(1) m%rotors(iR)%Y(j,k) = force(2) - m%rotors(iR)%M(j,k) = moment(3) + m%rotors(iR)%Z(j,k) = 0.0_ReKi + m%rotors(iR)%Mx(j,k) = 0.0_ReKi + m%rotors(iR)%My(j,k) = 0.0_ReKi + m%rotors(iR)%Mz(j,k) = moment(3) + m%rotors(iR)%M(j,k) = moment(3) ! TODO EB ! note: because force and moment are 1-d arrays, I'm calculating the transpose of the force and moment outputs - ! so that I don't have to take the transpose of WithoutSweepPitchTwist(:,:,j,k) - y%rotors(iR)%BladeLoad(k)%Force(:,j) = matmul( force, m%rotors(iR)%WithoutSweepPitchTwist(:,:,j,k) ) ! force per unit length of the jth node in the kth blade - y%rotors(iR)%BladeLoad(k)%Moment(:,j) = matmul( moment, m%rotors(iR)%WithoutSweepPitchTwist(:,:,j,k) ) ! moment per unit length of the jth node in the kth blade + ! so that I don't have to take the transpose of orientationAnnulus(:,:,j,k) + y%rotors(iR)%BladeLoad(k)%Force(:,j) = matmul( force, m%rotors(iR)%orientationAnnulus(:,:,j,k) ) ! force per unit length of the jth node in the kth blade + y%rotors(iR)%BladeLoad(k)%Moment(:,j) = matmul( moment, m%rotors(iR)%orientationAnnulus(:,:,j,k) ) ! moment per unit length of the jth node in the kth blade ! Save results for outputs so we don't have to recalculate them all when we write outputs m%FVW%W(iW)%BN_AxInd(j) = AxInd @@ -2245,6 +3404,7 @@ subroutine SetOutputsFromFVW(t, u, p, OtherState, x, xd, m, y, ErrStat, ErrMsg) m%FVW%W(iW)%BN_Cl_Static(j) = Cl_Static m%FVW%W(iW)%BN_Cd_Static(j) = Cd_Static m%FVW%W(iW)%BN_Cm_Static(j) = Cm_Static + m%FVW%W(iW)%BN_Cpmin(j) = Cpmin m%FVW%W(iW)%BN_Cl(j) = Cl_dyn m%FVW%W(iW)%BN_Cd(j) = Cd_dyn m%FVW%W(iW)%BN_Cm(j) = Cm_dyn @@ -2263,7 +3423,7 @@ subroutine SetOutputsFromFVW(t, u, p, OtherState, x, xd, m, y, ErrStat, ErrMsg) end subroutine SetOutputsFromFVW !---------------------------------------------------------------------------------------------------------------------------------- -!> This routine validates the inputs from the AeroDyn input files. +!> This routine validates the number of blades on each rotor. SUBROUTINE ValidateNumBlades( NumBl, ErrStat, ErrMsg ) integer(IntKi), intent(in) :: NumBl !< Number of blades integer(IntKi), intent(out) :: ErrStat !< Error status @@ -2281,7 +3441,7 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) type(AD_InitInputType), intent(in ) :: InitInp !< Input data for initialization routine type(AD_InputFile), intent(in) :: InputFileData !< All the data in the AeroDyn input file - integer(IntKi), intent(in) :: NumBl(:) !< Number of blades + integer(IntKi), intent(in) :: NumBl(:) !< Number of blades: size(NumBl) = number of rotors integer(IntKi), intent(out) :: ErrStat !< Error status character(*), intent(out) :: ErrMsg !< Error message @@ -2295,6 +3455,17 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) ErrStat = ErrID_None ErrMsg = "" +! do iR = 1,size(NumBl) +! if (NumBl(iR) < 1) then +! call SetErrStat( ErrID_Fatal, 'Number of blades must be at least 1.', ErrStat, ErrMsg, RoutineName ) +! return ! return early because InputFileData%BladeProps may not be allocated properly otherwise... +! else +! if (NumBl(iR) > AD_MaxBl_Out .and. InitInp%Linearize) then +! call SetErrStat( ErrID_Fatal, 'Number of blades must be no larger than '//trim(num2lstr(AD_MaxBl_Out))//' for linearizaton analysis.', ErrStat, ErrMsg, RoutineName ) +! return ! return early because InputFileData%BladeProps may not be allocated properly otherwise... +! end if +! end if +! end do 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 @@ -2335,9 +3506,13 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) enddo endif - !if (InitInp%MHK == 0 .and. InputFileData%CavitCheck) call SetErrStat ( ErrID_Fatal, 'A cavitation check can only be performed for an MHK turbine.', ErrStat, ErrMsg, RoutineName ) ! hkr (5/5/21) Uncomment after buoyancy and added mass are implemented + if (InitInp%MHK == 0 .and. InputFileData%CavitCheck) call SetErrStat ( ErrID_Fatal, 'A cavitation check can only be performed for an MHK turbine.', ErrStat, ErrMsg, RoutineName ) + if (InitInp%MHK == 0 .and. InputFileData%Buoyancy) call SetErrStat ( ErrID_Fatal, 'Buoyancy can only be calculated for an MHK turbine.', ErrStat, ErrMsg, RoutineName ) if (InitInp%MHK == 1 .and. InputFileData%CompAA .or. InitInp%MHK == 2 .and. InputFileData%CompAA) call SetErrStat ( ErrID_Fatal, 'The aeroacoustics module cannot be used with an MHK turbine.', ErrStat, ErrMsg, RoutineName ) - + do iR = 1,size(NumBl) + if (InitInp%MHK == 1 .and. InputFileData%rotors(iR)%TFinAero .or. InitInp%MHK == 2 .and. InputFileData%rotors(iR)%TFinAero) call SetErrStat ( ErrID_Fatal, 'A tail fin cannot be modeled for an MHK turbine.', ErrStat, ErrMsg, RoutineName ) + enddo + if (InputFileData%AirDens <= 0.0) call SetErrStat ( ErrID_Fatal, 'The density of the working fluid 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 ) if (InputFileData%SpdSound <= 0.0) call SetErrStat ( ErrID_Fatal, 'The speed of sound (SpdSound) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) @@ -2412,17 +3587,28 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) end if end do ! j=nodes end do ! k=blades + + ! If the Buoyancy flag is True, check that the blade buoyancy coefficients are >= 0. + if ( InputFileData%Buoyancy ) then + do k=1,NumBl(iR) + do j=1,InputFileData%rotors(iR)%BladeProps(k)%NumBlNds + if ( InputFileData%rotors(iR)%BladeProps(k)%BlCb(j) < 0.0_ReKi ) then + call SetErrStat( ErrID_Fatal, 'The buoyancy coefficient for blade '//trim(Num2LStr(k))//' node '//trim(Num2LStr(j)) & + //' must be greater than or equal to 0.', ErrStat, ErrMsg, RoutineName ) + endif + end do ! j=nodes + end do ! k=blades + end if end do ! iR rotor - + ! ............................. ! check tower mesh data: - ! ............................. - if (InputFileData%TwrPotent /= TwrPotent_none .or. InputFileData%TwrShadow /= TwrShadow_none .or. InputFileData%TwrAero ) then - - - ! Check that the tower diameter is > 0. - do iR = 1,size(NumBl) + ! ............................. + do iR = 1,size(NumBl) + if (InputFileData%TwrPotent /= TwrPotent_none .or. InputFileData%TwrShadow /= TwrShadow_none .or. InputFileData%TwrAero .or. InputFileData%Buoyancy .and. InputFileData%rotors(iR)%NumTwrNds > 0 ) then if (InputFileData%rotors(iR)%NumTwrNds < 2) call SetErrStat( ErrID_Fatal, 'There must be at least two nodes on the tower.',ErrStat, ErrMsg, RoutineName ) + + ! Check that the tower diameter is > 0. do j=1,InputFileData%rotors(iR)%NumTwrNds if ( InputFileData%rotors(iR)%TwrDiam(j) <= 0.0_ReKi ) then call SetErrStat( ErrID_Fatal, 'The diameter for tower node '//trim(Num2LStr(j))//' must be greater than 0.' & @@ -2432,15 +3618,61 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) ! check that the elevation is increasing: do j=2,InputFileData%rotors(iR)%NumTwrNds - if ( InputFileData%rotors(iR)%TwrElev(j) <= InputFileData%rotors(iR)%TwrElev(j-1) ) then - call SetErrStat( ErrID_Fatal, 'The tower nodes must be entered in increasing elevation.', ErrStat, ErrMsg, RoutineName ) - exit + if ( InitInp%MHK /= 2 ) then + if ( InputFileData%rotors(iR)%TwrElev(j) <= InputFileData%rotors(iR)%TwrElev(j-1) ) then + call SetErrStat( ErrID_Fatal, 'The tower nodes must be entered in increasing elevation.', ErrStat, ErrMsg, RoutineName ) + exit + end if + else if ( InitInp%MHK == 2 ) then + if ( InputFileData%rotors(iR)%TwrElev(j) >= InputFileData%rotors(iR)%TwrElev(j-1) ) then + call SetErrStat( ErrID_Fatal, 'The tower nodes must be entered in decreasing elevation for a floating MHK turbine.', ErrStat, ErrMsg, RoutineName ) + exit + end if end if end do ! j=nodes - end do ! iR rotor + + ! If the Buoyancy flag is True, check that the tower buoyancy coefficients are >= 0. + if ( InputFileData%Buoyancy .and. InputFileData%rotors(iR)%NumTwrNds > 0 ) then + do j=1,InputFileData%rotors(iR)%NumTwrNds + if ( InputFileData%rotors(iR)%TwrCb(j) < 0.0_ReKi ) then + call SetErrStat( ErrID_Fatal, 'The buoyancy coefficient for tower node '//trim(Num2LStr(j))//' must be greater than or equal to 0.', ErrStat, ErrMsg, RoutineName ) + endif + end do ! j=nodes + end if + + end if + end do ! iR rotor - end if + + + ! ............................. + ! check hub mesh data: + ! ............................. + if ( InputFileData%Buoyancy ) then + + ! Check that the hub volume is >= 0. + do iR = 1,size(NumBl) + if ( InputFileData%rotors(iR)%VolHub < 0.0_ReKi ) then + call SetErrStat( ErrID_Fatal, 'The hub volume must be greater than or equal to 0.', ErrStat, ErrMsg, RoutineName ) + endif + end do ! iR rotor + end if + + ! ............................. + ! check nacelle mesh data: + ! ............................. + if ( InputFileData%Buoyancy ) then + + ! Check that the nacelle volume is >= 0. + do iR = 1,size(NumBl) + if ( InputFileData%rotors(iR)%VolNac < 0.0_ReKi ) then + call SetErrStat( ErrID_Fatal, 'The nacelle volume must be greater than or equal to 0.', ErrStat, ErrMsg, RoutineName ) + endif + end do ! iR rotor + + end if + ! ............................. ! check outputs: ! ............................. @@ -2480,29 +3712,46 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) end do ! iR, rotor end if + + !.................. + ! Tail fin checks + !.................. + do iR = 1,size(NumBl) + if (InputFileData%rotors(iR)%TFinAero) then + ! Check AFID + if (InputFileData%rotors(iR)%TFin%TFinMod==TFinAero_polar) then + k = InputFileData%rotors(iR)%TFin%TFinAFID + j = InputFileData%NumAFfiles + if (k<1 .or. k>j) call Fatal('The variable TFinAFID (in AeroDyn TailFin file) needs to be between 1 and NumAFfiles ('//trim(num2lstr(j))//'), currently: '//trim(num2lstr(k))) + endif + endif + enddo ! iR, rotor !.................. ! check for linearization !.................. if (InitInp%Linearize) then if (InputFileData%AFAeroMod /= AFAeroMod_Steady) then -!bjj: REMOVE when linearization has been tested - call SetErrStat( ErrID_Fatal, 'Steady blade airfoil aerodynamics must be used for linearization. Set AFAeroMod=1.', ErrStat, ErrMsg, RoutineName ) - !if (InputFileData%UAMod /= UA_HGM) then - ! call SetErrStat( ErrID_Fatal, 'When AFAeroMod=2, UAMod must be 4 for linearization. Set AFAeroMod=1 or UAMod=4.', ErrStat, ErrMsg, RoutineName ) - !end if + if (InputFileData%UAMod /= UA_HGM .and. InputFileData%UAMod /= UA_HGMV .and. InputFileData%UAMod /= UA_OYE) then + call SetErrStat( ErrID_Fatal, 'When AFAeroMod=2, UAMod must be 4, 5, or 6 for linearization. Set AFAeroMod=1, or, set UAMod=4, 5, or 6.', ErrStat, ErrMsg, RoutineName ) + end if end if - if (InputFileData%WakeMod == WakeMod_FVW) then + if (InputFileData%WakeMod == WakeMod_FVW) then !bjj: note: among other things, WriteOutput values will not be calculated properly in AD Jacobians if FVW this is allowed call SetErrStat( ErrID_Fatal, 'FVW cannot currently be used for linearization. Set WakeMod=0 or WakeMod=1.', ErrStat, ErrMsg, RoutineName ) else if (InputFileData%WakeMod == WakeMod_DBEMT) then -!bjj: when linearization has been tested - call SetErrStat( ErrID_Fatal, 'DBEMT cannot currently be used for linearization. Set WakeMod=0 or WakeMod=1.', ErrStat, ErrMsg, RoutineName ) - !if (InputFileData%DBEMT_Mod /= DBEMT_cont_tauConst) then - ! call SetErrStat( ErrID_Fatal, 'DBEMT requires the continuous formulation with constant tau1 for linearization. Set DBEMT_Mod=3 or set WakeMod to 0 or 1.', ErrStat, ErrMsg, RoutineName ) - !end if + if (InputFileData%DBEMT_Mod /= DBEMT_cont_tauConst) then + call SetErrStat( ErrID_Fatal, 'DBEMT requires the continuous formulation with constant tau1 for linearization. Set DBEMT_Mod=3 or set WakeMod to 0 or 1.', ErrStat, ErrMsg, RoutineName ) + end if end if end if + +contains + + SUBROUTINE Fatal(ErrMsg_in) + character(len=*), intent(in) :: ErrMsg_in + call SetErrStat(ErrID_Fatal, ErrMsg_in, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE Fatal END SUBROUTINE ValidateInputData !---------------------------------------------------------------------------------------------------------------------------------- @@ -2546,7 +3795,7 @@ SUBROUTINE Init_AFIparams( InputFileData, p_AFI, UnEc, ErrStat, ErrMsg ) 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 - AFI_InitInputs%UA_f_cn = InputFileData%UAMod /= UA_HGM ! HGM uses the separation function based on cl instead of cn + AFI_InitInputs%UA_f_cn = (InputFileData%UAMod /= UA_HGM).and.(InputFileData%UAMod /= UA_OYE) ! HGM and OYE use the separation function based on cl instead of cn ! Call AFI_Init to read in and process the airfoil files. ! This includes creating the spline coefficients to be used for interpolation. @@ -2701,6 +3950,7 @@ SUBROUTINE Init_BEMTmodule( InputFileData, RotInputFileData, u_AD, u, p, p_AD, x real(ReKi) :: tmp(3), tmp_sz_y, tmp_sz real(ReKi) :: y_hat_disk(3) real(ReKi) :: z_hat_disk(3) + real(ReKi) :: position(3) real(ReKi) :: rMax real(ReKi) :: frac integer(IntKi) :: ErrStat2 @@ -2739,7 +3989,7 @@ SUBROUTINE Init_BEMTmodule( InputFileData, RotInputFileData, u_AD, u, p, p_AD, x call AllocAry(InitInp%zLocal,InitInp%numBladeNodes,InitInp%numBlades,'zLocal', ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call AllocAry(InitInp%rLocal,InitInp%numBladeNodes,InitInp%numBlades,'rLocal', ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call AllocAry(InitInp%zTip, InitInp%numBlades,'zTip', ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - + call AllocAry(InitInp%rTipFix, InitInp%numBlades,'rTipFix',ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call AllocAry(InitInp%UAOff_innerNode, InitInp%numBlades,'UAOff_innerNode',ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call AllocAry(InitInp%UAOff_outerNode, InitInp%numBlades,'UAOff_outerNode',ErrStat2,ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -2749,7 +3999,7 @@ SUBROUTINE Init_BEMTmodule( InputFileData, RotInputFileData, u_AD, u, p, p_AD, x end if - ! Compute zLocal, zHub, zTip, rLocal, rMax + ! Compute zLocal, zHub, zTip, rLocal, rMax, rTipFix rMax = 0.0_ReKi do k=1,p%numBlades @@ -2776,7 +4026,25 @@ SUBROUTINE Init_BEMTmodule( InputFileData, RotInputFileData, u_AD, u, p, p_AD, x tmp_sz = dot_product( tmp, z_hat_disk )**2 InitInp%rLocal(j,k) = sqrt( tmp_sz + tmp_sz_y ) rMax = max(rMax, InitInp%rLocal(j,k)) - end do !j=nodes + end do !j=nodes + + + !......... + ! compute fixed rLocal at tip node (without prebend) for Bladed-like calculations: + !......... + tmp(1) = 0.0_ReKi !RotInputFile%BladeProps(k)%BlCrvAC(p%NumBlNds) + tmp(2) = 0.0_ReKi !RotInputFile%BladeProps(k)%BlSwpAC(p%NumBlNds) + tmp(3) = RotInputFileData%BladeProps(k)%BlSpn(p%NumBlNds) + position = u_AD%BladeRootMotion(k)%Position(:,1) + matmul(tmp,u_AD%BladeRootMotion(k)%RefOrientation(:,:,1)) ! note that because positionL is a 1-D array, we're doing the transpose of matmul(transpose(u%BladeRootMotion(k)%RefOrientation),positionL) + + ! position of the coned tip node in the kth blade relative to the hub: + tmp = position - u_AD%HubMotion%Position(:,1) + + ! local radius (normalized distance from rotor centerline) + tmp_sz_y = dot_product( tmp, y_hat_disk )**2 + tmp_sz = dot_product( tmp, z_hat_disk )**2 + InitInp%rTipFix(k) = sqrt( tmp_sz + tmp_sz_y ) + end do !k=blades @@ -2806,8 +4074,25 @@ SUBROUTINE Init_BEMTmodule( InputFileData, RotInputFileData, u_AD, u, p, p_AD, x InitInp%UAMod = InputFileData%UAMod InitInp%Flookup = InputFileData%Flookup InitInp%a_s = InputFileData%SpdSound + InitInp%MomentumCorr = .FALSE. ! TODO EB InitInp%SumPrint = InputFileData%SumPrint InitInp%RootName = p%RootName + InitInp%BEM_Mod = p%AeroBEM_Mod + + + if (p%AeroBEM_Mod==-1) then + !call WrSCr('WARNING: AeroDyn: BEM_Mod is -1, using default BEM_Mod based on projection') + if (p%AeroProjMod == APM_BEM_NoSweepPitchTwist) then + InitInp%BEM_Mod = BEMMod_2D + else if (p%AeroProjMod == APM_BEM_Polar) then + InitInp%BEM_Mod = BEMMod_3D + else + InitInp%BEM_Mod = -1 + call SetErrStat(ErrID_Fatal, "AeroProjMod needs to be 1 or 2 when used with BEM", ErrStat, ErrMsg, RoutineName) + endif + endif + p%AeroBEM_Mod = InitInp%BEM_Mod ! Very important, for consistency + !call WrScr(' AeroDyn: projMod: '//trim(num2lstr(p%AeroProjMod))//', BEM_Mod:'//trim(num2lstr(InitInp%BEM_Mod))) ! remove the ".AD" from the RootName k = len_trim(InitInp%RootName) if (k>3) then @@ -2905,6 +4190,8 @@ SUBROUTINE Init_OLAF( InputFileData, u_AD, u, p, x, xd, z, OtherState, m, ErrSta InitInp%numBladeNodes = p%rotors(iR)%numBlNds ! TODO TODO TODO per wing InitInp%KinVisc = p%rotors(iR)%KinVisc + InitInp%MHK = p%rotors(iR)%MHK + InitInp%WtrDpth = p%rotors(iR)%WtrDpth InitInp%RootName = p%RootName(1:len_trim(p%RootName)-2) ! Removing "AD" ! Blades/Wings @@ -2926,6 +4213,7 @@ SUBROUTINE Init_OLAF( InputFileData, u_AD, u, p, x, xd, z, OtherState, m, ErrSta ! displaced position of the jth node in the kth blade relative to the hub: tmp = u_AD%rotors(iR)%BladeMotion(iB)%Position(:,j) - u_AD%rotors(iR)%HubMotion%Position(:,1) ! local radius (normalized distance from rotor centerline) + ! NOTE: rLocal is not necessary a good distance for VAWT tmp_sz_y = dot_product( tmp, y_hat_disk )**2 tmp_sz = dot_product( tmp, z_hat_disk )**2 rLocal(j) = sqrt( tmp_sz + tmp_sz_y ) @@ -2979,6 +4267,7 @@ SUBROUTINE Init_OLAF( InputFileData, u_AD, u, p, x, xd, z, OtherState, m, ErrSta ! set the size of the input and xd arrays for passing wind info to FVW. call AllocAry(u_AD%InflowWakeVel, 3, size(m%FVW%r_wind,DIM=2), 'InflowWakeVel', ErrStat2,ErrMsg2); if(Failed()) return + u_AD%InflowWakeVel = 0.0_ReKi ! initialize for safety if (.not. equalRealNos(Interval, p%DT) ) then errStat2=ErrID_Fatal; errMsg2="DTAero was changed in Init_FVWmodule(); this is not allowed yet."; if(Failed()) return @@ -3001,6 +4290,96 @@ end function Failed END SUBROUTINE Init_OLAF !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine calculates the tower loads for the AeroDyn TowerLoad output mesh. +SUBROUTINE TFin_CalcOutput(p, p_AD, u, m, y, ErrStat, ErrMsg ) + + TYPE(RotInputType), INTENT(IN ) :: u !< Inputs at Time t + TYPE(RotParameterType), INTENT(IN ) :: p !< Parameters + TYPE(AD_ParameterType), INTENT(IN ) :: p_AD !< Parameters + TYPE(RotMiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + TYPE(RotOutputType), INTENT(INOUT) :: y !< Outputs computed at t + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + real(ReKi) :: PRef(3) ! ref point + real(ReKi) :: V_rel_tf(3) ! relative wind speed in tailfin coordinate system + real(ReKi) :: V_rel_orth2 ! square norm of V_rel_tf in orthogonal plane + real(ReKi) :: V_rel(3) ! relative wind speed + real(ReKi) :: V_wnd(3) ! wind velocity + real(ReKi) :: V_ind(3) ! induced velocity + real(ReKi) :: V_str(3) ! structural velocity + real(ReKi) :: force_tf(3) ! force in tf system + real(ReKi) :: moment_tf(3) ! moment in tf system + real(ReKi) :: alpha, Re, Cx, Cy, q ! Cl, Cd, Cm, + type(AFI_OutputType) :: AFI_interp ! Resulting values from lookup table + integer(intKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + character(*), parameter :: RoutineName = 'TFin_CalcOutput' + + ErrStat = ErrID_None + ErrMsg = "" + + + ! TODO TailFin: compute tower influence + V_wnd = u%InflowOnTailFin + V_str = u%TFinMotion%TranslationVel(:,1) + + if (p%TFin%TFinIndMod==TFinIndMod_none) then + V_ind = 0.0_ReKi + elseif(p%TFin%TFinIndMod==TFinIndMod_rotavg) then + ! TODO TODO + print*,'TODO TailFin: compute rotor average induced velocity' + V_ind = 0.0_ReKi + else + STOP ! Will never happen + endif + V_rel = V_wnd - V_str + V_ind + V_rel_tf = matmul(u%TFinMotion%Orientation(:,:,1), V_rel) ! from inertial to tf system + alpha = atan2( V_rel_tf(2), V_rel_tf(1)) ! angle of attack + V_rel_orth2 = V_rel_tf(1)**2 + V_rel_tf(2)**2 ! square norm of Vrel in tf system + + if (p%TFin%TFinMod==TFinAero_none) then + y%TFinLoad%Force(1:3,1) = 0.0_ReKi + y%TFinLoad%Moment(1:3,1) = 0.0_ReKi + + elseif (p%TFin%TFinMod==TFinAero_polar) then + ! Airfoil coefficients + Re = sqrt(V_rel_orth2) * p%TFin%TFinChord/p%KinVisc + call AFI_ComputeAirfoilCoefs( alpha, Re, 0.0_ReKi, p_AD%AFI(p%TFin%TFinAFID), AFI_interp, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + Cx = -AFI_interp%Cl * sin(alpha) + AFI_interp%Cd * cos(alpha) + Cy = AFI_interp%Cl * cos(alpha) + AFI_interp%Cd * sin(alpha) + ! Forces in tailfin system + q = 0.5 * p%airDens * V_rel_orth2 * p%TFin%TFinArea + force_tf(:) = 0.0_ReKi + moment_tf(:) = 0.0_ReKi + force_tf(1) = Cx * q + force_tf(2) = Cy * q * p%TFin%TFinChord + force_tf(3) = 0.0_ReKi + moment_tf(1:2) = 0.0_ReKi + moment_tf(3) = AFI_interp%Cm * q * p%TFin%TFinChord + ! Transfer to global + y%TFinLoad%Force(1:3,1) = matmul(transpose(u%TFinMotion%Orientation(:,:,1)), force_tf) + y%TFinLoad%Moment(1:3,1) = matmul(transpose(u%TFinMotion%Orientation(:,:,1)), moment_tf) + + elseif (p%TFin%TFinMod==TFinAero_USB) then + call SetErrStat(ErrID_Fatal, 'Tail fin USB model not yet available', ErrStat, ErrMsg, RoutineName ) + return + endif + + ! --- Store + m%TFinAlpha = alpha + m%TFinRe = Re + m%TFinVrel = sqrt(V_rel_orth2) + m%TFinVund_i = V_wnd + m%TFinVind_i = V_ind + m%TFinVrel_i = V_rel + m%TFinSTV_i = V_str + m%TFinF_i = y%TFinLoad%Force(1:3,1) + m%TFinM_i = y%TFinLoad%Moment(1:3,1) + +END SUBROUTINE TFin_CalcOutput +!---------------------------------------------------------------------------------------------------------------------------------- +!> This subroutine calculates the tower loads for the AeroDyn TowerLoad output mesh. SUBROUTINE ADTwr_CalcOutput(p, u, m, y, ErrStat, ErrMsg ) TYPE(RotInputType), INTENT(IN ) :: u !< Inputs at Time t @@ -3112,15 +4491,11 @@ SUBROUTINE TwrInfl( p, u, m, ErrStat, ErrMsg ) real(ReKi) :: BladeNodePosition(3) ! local blade node position - - 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 + logical :: FirstWarn_TowerStrike + logical :: DisturbInflow + integer(IntKi) :: j, k ! loop counters for elements, blades integer(intKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 @@ -3130,6 +4505,7 @@ SUBROUTINE TwrInfl( p, u, m, ErrStat, ErrMsg ) ErrStat = ErrID_None ErrMsg = "" + FirstWarn_TowerStrike = .true. ! these models are valid for only small tower deflections; check for potential division-by-zero errors: call CheckTwrInfl( u, ErrStat2, ErrMsg2 ) @@ -3144,70 +4520,17 @@ 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, TwrTI, 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), FirstWarn_TowerStrike, DisturbInflow, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + if (.not. FirstWarn_TowerStrike) call SetErrStat(ErrID_Fatal, "Tower strike.", ErrStat, ErrMsg, RoutineName ) if (ErrStat >= AbortErrLev) return - - - ! calculate tower influence: - if ( abs(zbar) < 1.0_ReKi .and. p%TwrPotent /= TwrPotent_none ) then - if ( p%TwrPotent == TwrPotent_baseline ) then - - denom = (xbar**2 + ybar**2)**2 - - if (equalRealNos(denom,0.0_ReKi)) then - u_TwrPotent = 0.0_ReKi - v_TwrPotent = 0.0_ReKi - else - u_TwrPotent = ( -1.0*xbar**2 + ybar**2 ) / denom - v_TwrPotent = ( -2.0*xbar * ybar ) / denom - end if - - elseif (p%TwrPotent == TwrPotent_Bak) then - - xbar = xbar + 0.1 - - denom = (xbar**2 + ybar**2)**2 - if (equalRealNos(denom,0.0_ReKi)) then - u_TwrPotent = 0.0_ReKi - v_TwrPotent = 0.0_ReKi - else - u_TwrPotent = ( -1.0*xbar**2 + ybar**2 ) / denom - v_TwrPotent = ( -2.0*xbar * ybar ) / denom - - denom = TwoPi*(xbar**2 + ybar**2) - u_TwrPotent = u_TwrPotent + TwrCd*xbar / denom - v_TwrPotent = v_TwrPotent + TwrCd*ybar / denom - end if - - end if + + if ( DisturbInflow ) then + v = CalculateTowerInfluence(p, xbar, ybar, zbar, W_tower, TwrCd, TwrTI) + m%DisturbedInflow(:,j,k) = u%InflowOnBlade(:,j,k) + matmul( theta_tower_trans, v ) else - u_TwrPotent = 0.0_ReKi - v_TwrPotent = 0.0_ReKi + m%DisturbedInflow(:,j,k) = u%InflowOnBlade(:,j,k) 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 - v(3) = 0.0_ReKi - - m%DisturbedInflow(:,j,k) = u%InflowOnBlade(:,j,k) + matmul( theta_tower_trans, v ) end do !j=NumBlNds end do ! NumBlades @@ -3235,109 +4558,125 @@ SUBROUTINE TwrInflArray( p, u, m, Positions, Inflow, ErrStat, ErrMsg ) 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 - real(ReKi) :: r_TowerBlade(3) ! distance vector from tower to blade - real(ReKi) :: TwrDiam ! local tower diameter - logical :: found + logical :: FirstWarn_TowerStrike + logical :: DisturbInflow integer(intKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 character(*), parameter :: RoutineName = 'TwrInflArray' ErrStat = ErrID_None ErrMsg = "" + + + FirstWarn_TowerStrike = .false. ! we aren't going to end due to an assumed "tower-strike" + ! these models are valid for only small tower deflections; check for potential division-by-zero errors: 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,TwrTI,TwrClrnc,TwrDiam,found,denom,exponential,u_TwrPotent,v_TwrPotent,u_TwrShadow,v) schedule(runtime) + !$OMP do private(i,Pos,theta_tower_trans,W_tower,xbar,ybar,zbar,TwrCd,TwrTI,TwrClrnc,FirstWarn_TowerStrike,DisturbInflow,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, 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, TwrTI, TwrDiam) + call getLocalTowerProps(p, u, Pos, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrTI, TwrClrnc, FirstWarn_TowerStrike, DisturbInflow, ErrStat2, ErrMsg2) + + if ( DisturbInflow ) then + v = CalculateTowerInfluence(p, xbar, ybar, zbar, W_tower, TwrCd, TwrTI) + Inflow(1:3,i) = Inflow(1:3,i) + matmul( theta_tower_trans, v ) end if - TwrClrnc = TwoNorm(r_TowerBlade) - 0.5_ReKi*TwrDiam + + enddo ! loop on points + !$OMP END DO + !$OMP END PARALLEL +END SUBROUTINE TwrInflArray +!---------------------------------------------------------------------------------------------------------------------------------- +FUNCTION CalculateTowerInfluence(p, xbar_in, ybar, zbar, W_tower, TwrCd, TwrTI) RESULT(v) - if ( TwrClrnc>20*TwrDiam) then - ! Far away, we skip the computation and keep undisturbed inflow - elseif ( TwrClrnc<=0.01_ReKi*TwrDiam) then - ! Inside the tower, or very close, (will happen for vortex elements) we keep undisturbed inflow - ! We don't want to reach the stagnation points - else - ! calculate tower influence: - if ( abs(zbar) < 1.0_ReKi .and. p%TwrPotent /= TwrPotent_none ) then - - if ( p%TwrPotent == TwrPotent_baseline ) then - denom = (xbar**2 + ybar**2)**2 - u_TwrPotent = ( -1.0*xbar**2 + ybar**2 ) / denom - v_TwrPotent = ( -2.0*xbar * ybar ) / denom - - elseif (p%TwrPotent == TwrPotent_Bak) then - xbar = xbar + 0.1 - denom = (xbar**2 + ybar**2)**2 - u_TwrPotent = ( -1.0*xbar**2 + ybar**2 ) / denom - v_TwrPotent = ( -2.0*xbar * ybar ) / denom - denom = TwoPi*(xbar**2 + ybar**2) - u_TwrPotent = u_TwrPotent + TwrCd*xbar / denom - v_TwrPotent = v_TwrPotent + TwrCd*ybar / denom + TYPE(RotParameterType), INTENT(IN ) :: p !< Parameters + real(ReKi), intent(in ) :: xbar_in ! local x^ component of r_TowerBlade (distance from tower to blade) normalized by tower radius + real(ReKi), intent(in) :: ybar ! local y^ component of r_TowerBlade (distance from tower to blade) normalized by tower radius + real(ReKi), intent(in) :: zbar ! local z^ component of r_TowerBlade (distance from tower to blade) normalized by tower radius + real(ReKi), intent(in) :: W_tower ! local relative wind speed normal to the tower + real(ReKi), intent(in) :: TwrCd ! local tower drag coefficient + real(ReKi), intent(in) :: TwrTI ! local tower TI (for Eames tower shadow model) + real(ReKi) :: v(3) ! modified velocity vector + + real(ReKi) :: denom ! denominator + real(ReKi) :: exponential ! exponential term + real(ReKi) :: xbar ! potentially modified version of xbar_in + 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 + + + u_TwrShadow = 0.0_ReKi + u_TwrPotent = 0.0_ReKi + v_TwrPotent = 0.0_ReKi + xbar = xbar_in + + ! calculate tower influence: + if ( abs(zbar) < 1.0_ReKi .and. p%TwrPotent /= TwrPotent_none ) then + + if ( p%TwrPotent == TwrPotent_baseline ) then + denom = (xbar**2 + ybar**2)**2 + u_TwrPotent = ( -1.0*xbar**2 + ybar**2 ) / denom + v_TwrPotent = ( -2.0*xbar * ybar ) / denom + + elseif (p%TwrPotent == TwrPotent_Bak) then + xbar = xbar + 0.1 + denom = (xbar**2 + ybar**2)**2 + u_TwrPotent = ( -1.0*xbar**2 + ybar**2 ) / denom + v_TwrPotent = ( -2.0*xbar * ybar ) / denom + denom = TwoPi*(xbar**2 + ybar**2) + u_TwrPotent = u_TwrPotent + TwrCd*xbar / denom + v_TwrPotent = v_TwrPotent + TwrCd*ybar / denom + end if + end if + + 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 - else - u_TwrPotent = 0.0_ReKi - v_TwrPotent = 0.0_ReKi 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 + + ! We limit the deficit to avoid having too much flow reversal and accumulation of vorticity behind the tower + ! Limit to -0.5 the wind speed at the tower + u_TwrShadow =max(u_TwrShadow, -0.5_ReKi) - 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 - ! We limit the deficit to avoid having too much flow reversal and accumulation of vorticity behind the tower - ! Limit to -0.5 the wind speed at the tower - u_TwrShadow =max(u_TwrShadow, -0.5) - end select - - v(1) = (u_TwrPotent + u_TwrShadow)*W_tower - v(2) = v_TwrPotent*W_tower - v(3) = 0.0_ReKi - Inflow(1:3,i) = Inflow(1:3,i) + matmul( theta_tower_trans, v ) - endif ! Check if point far away or in tower - enddo ! loop on points - !$OMP END DO - !$OMP END PARALLEL -END SUBROUTINE TwrInflArray + v(1) = (u_TwrPotent + u_TwrShadow)*W_tower + v(2) = v_TwrPotent*W_tower + v(3) = 0.0_ReKi + + +END FUNCTION CalculateTowerInfluence !---------------------------------------------------------------------------------------------------------------------------------- !> 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, TwrTI, TwrClrnc, ErrStat, ErrMsg) +SUBROUTINE getLocalTowerProps(p, u, BladeNodePosition, theta_tower_trans, W_tower, xbar, ybar, zbar, TwrCd, TwrTI, TwrClrnc, FirstWarn_TowerStrike, DisturbInflow, ErrStat, ErrMsg) !.................................................................................................................................. TYPE(RotInputType), INTENT(IN ) :: u !< Inputs at Time t TYPE(RotParameterType), INTENT(IN ) :: p !< Parameters REAL(ReKi) ,INTENT(IN ) :: BladeNodePosition(3) !< local blade node position REAL(ReKi) ,INTENT( OUT) :: theta_tower_trans(3,3) !< transpose of local tower orientation expressed as a DCM + LOGICAL ,INTENT(INOUT) :: FirstWarn_TowerStrike !< Whether we should check and warn for a tower strike + LOGICAL ,INTENT( OUT) :: DisturbInflow !< Whether tower clearance is in the range of values where it should disturb the inflow REAL(ReKi) ,INTENT( OUT) :: W_tower !< local relative wind speed normal to the tower REAL(ReKi) ,INTENT( OUT) :: xbar !< local x^ component of r_TowerBlade normalized by tower radius REAL(ReKi) ,INTENT( OUT) :: ybar !< local y^ component of r_TowerBlade normalized by tower radius @@ -3372,11 +4711,31 @@ SUBROUTINE getLocalTowerProps(p, u, BladeNodePosition, theta_tower_trans, W_towe end if TwrClrnc = TwoNorm(r_TowerBlade) - 0.5_ReKi*TwrDiam - if ( TwrClrnc <= 0.0_ReKi ) then - call SetErrStat(ErrID_Fatal, "Tower strike.", ErrStat, ErrMsg, RoutineName) + + if (FirstWarn_TowerStrike) then + if ( TwrClrnc <= 0.0_ReKi ) then + !call SetErrStat(ErrID_Fatal, "Tower strike.", ErrStat, ErrMsg, RoutineName) + !call SetErrStat(ErrID_Severe, NewLine//NewLine//"** WARNING: Tower strike. ** This warning will not be repeated though the condition may persist."//NewLine//NewLine//, ErrStat, ErrMsg, RoutineName) + call WrScr( NewLine//NewLine//"** WARNING: Tower strike. ** This warning will not be repeated though the condition may persist."//NewLine//NewLine ) + FirstWarn_TowerStrike = .false. + end if end if + - + if ( TwrClrnc>20.0_ReKi*TwrDiam) then + ! Far away, we skip the computation and keep undisturbed inflow + DisturbInflow = .false. + elseif ( TwrClrnc<=0.01_ReKi*TwrDiam) then + ! Inside the tower, or very close, (will happen for vortex elements) we keep undisturbed inflow + ! We don't want to reach the stagnation points + DisturbInflow = .false. + !elseif ( TwrClrnc<= 0.0_ReKi) then + ! ! Tower strike + ! DisturbInflow = .false. + else + DisturbInflow = .true. + end if + END SUBROUTINE getLocalTowerProps !---------------------------------------------------------------------------------------------------------------------------------- !> Option 1: Find the nearest-neighbor line2 element of the tower mesh for which the blade line2-element node projects orthogonally onto @@ -3534,7 +4893,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) :: TwrTI !< local tower TI (for Eames tower shadow model) REAL(ReKi) ,INTENT( OUT) :: TwrDiam !< local tower diameter ! local variables @@ -3682,14 +5041,14 @@ SUBROUTINE AD_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrM return endif - call Rot_JacobianPInput( t, u%rotors(iR), p%rotors(iR), p, x%rotors(iR), xd%rotors(iR), z%rotors(iR), OtherState%rotors(iR), y%rotors(iR), m%rotors(iR), ErrStat, ErrMsg, dYdu, dXdu, dXddu, dZdu) + call Rot_JacobianPInput( t, u%rotors(iR), p%rotors(iR), p, x%rotors(iR), xd%rotors(iR), z%rotors(iR), OtherState%rotors(iR), y%rotors(iR), m%rotors(iR), m, iR, ErrStat, ErrMsg, dYdu, dXdu, dXddu, dZdu) END SUBROUTINE AD_JacobianPInput !! respect to the inputs (u) [intent in to avoid deallocation] !> 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 Rot_JacobianPInput( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, dYdu, dXdu, dXddu, dZdu) +SUBROUTINE Rot_JacobianPInput( t, u, p, p_AD, x, xd, z, OtherState, y, m, m_AD, iRot, ErrStat, ErrMsg, dYdu, dXdu, dXddu, dZdu) !.................................................................................................................................. REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point @@ -3705,6 +5064,8 @@ SUBROUTINE Rot_JacobianPInput( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrSta !! available here so that mesh parameter information (i.e., !! connectivity) does not have to be recalculated for dYdu. TYPE(RotMiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + TYPE(AD_MiscVarType), INTENT(INOUT) :: m_AD !< misc variables + INTEGER, INTENT(IN ) :: iRot !< Rotor index, needed for OLAF 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) with respect @@ -3832,7 +5193,7 @@ SUBROUTINE Rot_JacobianPInput( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrSta call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ! we shouldn't have any errors about allocating memory here so I'm not going to return-on-error until later ! compute y at u_op + delta_p u - call RotCalcOutput( t, u_perturb, p, p_AD, x_init, xd, z_copy, OtherState_copy, y_p, m, ErrStat2, ErrMsg2 ) + call RotCalcOutput( t, u_perturb, p, p_AD, x_init, xd, z_copy, OtherState_copy, y_p, m, m_AD, iRot, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ! we shouldn't have any errors about allocating memory here so I'm not going to return-on-error until later @@ -3855,12 +5216,12 @@ SUBROUTINE Rot_JacobianPInput( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrSta call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ! we shouldn't have any errors about allocating memory here so I'm not going to return-on-error until later ! compute y at u_op - delta_m u - call RotCalcOutput( t, u_perturb, p, p_AD, x_init, xd, z_copy, OtherState_copy, y_m, m, ErrStat2, ErrMsg2 ) + call RotCalcOutput( t, u_perturb, p, p_AD, x_init, xd, z_copy, OtherState_copy, y_m, m, m_AD, iRot, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ! we shouldn't have any errors about allocating memory here so I'm not going to return-on-error until later ! get central difference: - call Compute_dY( p, y_p, y_m, delta_p, delta_m, dYdu(:,i) ) + call Compute_dY( p, p_AD, y_p, y_m, delta_p, delta_m, dYdu(:,i) ) end do @@ -3995,7 +5356,7 @@ SUBROUTINE AD_JacobianPContState( t, u, p, x, xd, z, OtherState, y, m, ErrStat, return endif - call RotJacobianPContState( t, u%rotors(iR), p%rotors(iR), p, x%rotors(iR), xd%rotors(iR), z%rotors(iR), OtherState%rotors(iR), y%rotors(iR), m%rotors(iR), ErrStat, ErrMsg, dYdx, dXdx, dXddx, dZdx ) + call RotJacobianPContState( t, u%rotors(iR), p%rotors(iR), p, x%rotors(iR), xd%rotors(iR), z%rotors(iR), OtherState%rotors(iR), y%rotors(iR), m%rotors(iR), m, iR, ErrStat, ErrMsg, dYdx, dXdx, dXddx, dZdx ) END SUBROUTINE AD_JacobianPContState @@ -4003,7 +5364,7 @@ END SUBROUTINE AD_JacobianPContState !---------------------------------------------------------------------------------------------------------------------------------- !> 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 RotJacobianPContState( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, dYdx, dXdx, dXddx, dZdx ) +SUBROUTINE RotJacobianPContState( t, u, p, p_AD, x, xd, z, OtherState, y, m, m_AD, iRot, ErrStat, ErrMsg, dYdx, dXdx, dXddx, dZdx ) !.................................................................................................................................. REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point @@ -4019,6 +5380,8 @@ SUBROUTINE RotJacobianPContState( t, u, p, p_AD, x, xd, z, OtherState, y, m, Err !! available here so that mesh parameter information (i.e., !! connectivity) does not have to be recalculated for dYdx. TYPE(RotMiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + TYPE(AD_MiscVarType), INTENT(INOUT) :: m_AD !< misc variables + INTEGER, INTENT(IN ) :: iRot !< Rotor index, needed for OLAF 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 @@ -4124,7 +5487,7 @@ SUBROUTINE RotJacobianPContState( t, u, p, p_AD, x, xd, z, OtherState, y, m, Err ! compute y at x_op + delta_p x ! NOTE: z_op is the same as z because x_perturb does not affect the values of phi, thus I am not updating the states or calling UpdatePhi to get z_perturb. - call RotCalcOutput( t, u, p, p_AD, x_perturb, xd, z, OtherState_init, y_p, m, ErrStat2, ErrMsg2 ) + call RotCalcOutput( t, u, p, p_AD, x_perturb, xd, z, OtherState_init, y_p, m, m_AD, iRot, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ! we shouldn't have any errors about allocating memory here so I'm not going to return-on-error until later @@ -4135,12 +5498,12 @@ SUBROUTINE RotJacobianPContState( t, u, p, p_AD, x, xd, z, OtherState, y, m, Err ! compute y at x_op - delta_m x ! NOTE: z_op is the same as z because x_perturb does not affect the values of phi, thus I am not updating the states or calling UpdatePhi to get z_perturb. - call RotCalcOutput( t, u, p, p_AD, x_perturb, xd, z, OtherState_init, y_m, m, ErrStat2, ErrMsg2 ) + call RotCalcOutput( t, u, p, p_AD, x_perturb, xd, z, OtherState_init, y_m, m, m_AD, iRot, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ! we shouldn't have any errors about allocating memory here so I'm not going to return-on-error until later ! get central difference: - call Compute_dY( p, y_p, y_m, delta_p, delta_m, dYdx(:,i) ) + call Compute_dY( p, p_AD, y_p, y_m, delta_p, delta_m, dYdx(:,i) ) end do @@ -4364,13 +5727,13 @@ SUBROUTINE AD_JacobianPConstrState( t, u, p, x, xd, z, OtherState, y, m, ErrStat return endif - call RotJacobianPConstrState( t, u%rotors(iR), p%rotors(iR), p, x%rotors(iR), xd%rotors(iR), z%rotors(iR), OtherState%rotors(iR), y%rotors(iR), m%rotors(iR), errStat, errMsg, dYdz, dXdz, dXddz, dZdz ) + call RotJacobianPConstrState( t, u%rotors(iR), p%rotors(iR), p, x%rotors(iR), xd%rotors(iR), z%rotors(iR), OtherState%rotors(iR), y%rotors(iR), m%rotors(iR), m, iR, errStat, errMsg, dYdz, dXdz, dXddz, dZdz ) END SUBROUTINE AD_JacobianPConstrState !---------------------------------------------------------------------------------------------------------------------------------- !> 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 RotJacobianPConstrState( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, dYdz, dXdz, dXddz, dZdz ) +SUBROUTINE RotJacobianPConstrState( t, u, p, p_AD, x, xd, z, OtherState, y, m, m_AD, iRot, ErrStat, ErrMsg, dYdz, dXdz, dXddz, dZdz ) !.................................................................................................................................. REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point @@ -4386,6 +5749,8 @@ SUBROUTINE RotJacobianPConstrState( t, u, p, p_AD, x, xd, z, OtherState, y, m, E !! available here so that mesh parameter information (i.e., !! connectivity) does not have to be recalculated for dYdz. TYPE(RotMiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + TYPE(AD_MiscVarType), INTENT(INOUT) :: m_AD !< misc variables + INTEGER, INTENT(IN ) :: iRot !< Rotor index, needed for OLAF 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 @@ -4492,7 +5857,7 @@ SUBROUTINE RotJacobianPConstrState( t, u, p, p_AD, x, xd, z, OtherState, y, m, E z_perturb%BEMT%phi(j,k) = z%BEMT%phi(j,k) + delta_p ! compute y at z_op + delta_p z - call RotCalcOutput( t, u, p, p_AD, x, xd, z_perturb, OtherState, y_p, m, ErrStat2, ErrMsg2 ) + call RotCalcOutput( t, u, p, p_AD, x, xd, z_perturb, OtherState, y_p, m, m_AD, iRot, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ! we shouldn't have any errors about allocating memory here so I'm not going to return-on-error until later @@ -4500,12 +5865,12 @@ SUBROUTINE RotJacobianPConstrState( t, u, p, p_AD, x, xd, z, OtherState, y, m, E z_perturb%BEMT%phi(j,k) = z%BEMT%phi(j,k) - delta_m ! compute y at z_op - delta_m z - call RotCalcOutput( t, u, p, p_AD, x, xd, z_perturb, OtherState, y_m, m, ErrStat2, ErrMsg2 ) + call RotCalcOutput( t, u, p, p_AD, x, xd, z_perturb, OtherState, y_m, m, m_AD, iRot, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ! we shouldn't have any errors about allocating memory here so I'm not going to return-on-error until later ! get central difference: - call Compute_dY( p, y_p, y_m, delta_p, delta_m, dYdz(:,i) ) + call Compute_dY( p, p_AD, y_p, y_m, delta_p, delta_m, dYdz(:,i) ) ! put z_perturb back (for next iteration): @@ -4825,8 +6190,8 @@ SUBROUTINE RotGetOP( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, do j=1,p%NumBlades ! size(x%BEMT%DBEMT%element,2) do i=1,p%NumBlNds ! size(x%BEMT%DBEMT%element,1) - do k=1,size(x%BEMT%DBEMT%element(i,j)%vind_dot) - x_op(index) = x%BEMT%DBEMT%element(i,j)%vind_dot(k) + do k=1,size(x%BEMT%DBEMT%element(i,j)%vind_1) + x_op(index) = x%BEMT%DBEMT%element(i,j)%vind_1(k) index = index + 1 end do end do @@ -4835,14 +6200,23 @@ SUBROUTINE RotGetOP( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, end if if (p%BEMT%UA%lin_nx>0) then - do j=1,p%NumBlades ! size(x%BEMT%UA%element,2) - do i=1,p%NumBlNds ! size(x%BEMT%UA%element,1) - do k=1,4 !size(x%BEMT%UA%element(i,j)%x) !linearize only first 4 states (5th is vortex) - x_op(index) = x%BEMT%UA%element(i,j)%x(k) + if (p%BEMT%UA%UAMod==UA_OYE) then + do j=1,p%NumBlades ! size(x%BEMT%UA%element,2) + do i=1,p%NumBlNds ! size(x%BEMT%UA%element,1) + x_op(index) = x%BEMT%UA%element(i,j)%x(4) index = index + 1 end do end do - end do + else + do j=1,p%NumBlades ! size(x%BEMT%UA%element,2) + do i=1,p%NumBlNds ! size(x%BEMT%UA%element,1) + do k=1,4 !size(x%BEMT%UA%element(i,j)%x) !linearize only first 4 states (5th is vortex) + x_op(index) = x%BEMT%UA%element(i,j)%x(k) + index = index + 1 + end do + end do + end do + endif end if @@ -4878,8 +6252,8 @@ SUBROUTINE RotGetOP( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, do j=1,p%NumBlades ! size(dxdt%BEMT%DBEMT%element,2) do i=1,p%NumBlNds ! size(dxdt%BEMT%DBEMT%element,1) - do k=1,size(dxdt%BEMT%DBEMT%element(i,j)%vind_dot) - dx_op(index) = dxdt%BEMT%DBEMT%element(i,j)%vind_dot(k) + do k=1,size(dxdt%BEMT%DBEMT%element(i,j)%vind_1) + dx_op(index) = dxdt%BEMT%DBEMT%element(i,j)%vind_1(k) index = index + 1 end do end do @@ -4888,14 +6262,23 @@ SUBROUTINE RotGetOP( t, u, p, p_AD, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, end if if (p%BEMT%UA%lin_nx>0) then - do j=1,p%NumBlades ! size(dxdt%BEMT%UA%element,2) - do i=1,p%NumBlNds ! size(dxdt%BEMT%UA%element,1) - do k=1,4 !size(dxdt%BEMT%UA%element(i,j)%x) don't linearize 5th state - dx_op(index) = dxdt%BEMT%UA%element(i,j)%x(k) + if (p%BEMT%UA%UAMod==UA_OYE) then + do j=1,p%NumBlades ! size(dxdt%BEMT%UA%element,2) + do i=1,p%NumBlNds ! size(dxdt%BEMT%UA%element,1) + dx_op(index) = dxdt%BEMT%UA%element(i,j)%x(4) index = index + 1 end do end do - end do + else + do j=1,p%NumBlades ! size(dxdt%BEMT%UA%element,2) + do i=1,p%NumBlNds ! size(dxdt%BEMT%UA%element,1) + do k=1,4 !size(dxdt%BEMT%UA%element(i,j)%x) don't linearize 5th state + dx_op(index) = dxdt%BEMT%UA%element(i,j)%x(k) + index = index + 1 + end do + end do + end do + endif end if call AD_DestroyRotContinuousStateType( dxdt, ErrStat2, ErrMsg2) @@ -4990,12 +6373,12 @@ SUBROUTINE Init_Jacobian_y( p, y, InitOut, ErrStat, ErrMsg) AllOut( BAzimuth(k)) = .true. AllOut( BPitch (k)) = .true. - ! AllOut( BAeroFx( k)) = .true. - ! AllOut( BAeroFy( k)) = .true. - ! AllOut( BAeroFz( k)) = .true. - ! AllOut( BAeroMx( k)) = .true. - ! AllOut( BAeroMy( k)) = .true. - ! AllOut( BAeroMz( k)) = .true. + ! AllOut( BFldFx( k)) = .true. + ! AllOut( BFldFy( k)) = .true. + ! AllOut( BFldFz( k)) = .true. + ! AllOut( BFldMx( k)) = .true. + ! AllOut( BFldMy( k)) = .true. + ! AllOut( BFldMz( k)) = .true. do j=1,9 AllOut(BNVUndx(j,k)) = .true. @@ -5398,15 +6781,17 @@ SUBROUTINE Init_Jacobian_x( p, InitOut, ErrStat, ErrMsg) do j=1,p%NumBlades ! size(x%BEMT%DBEMT%element,2) do i=1,p%NumBlNds ! size(x%BEMT%DBEMT%element,1) NodeTxt = 'blade '//trim(num2lstr(j))//', node '//trim(num2lstr(i)) + if (p%BEMT%UA%UAMod/=UA_OYE) then - InitOut%LinNames_x(k) = 'x1 '//trim(NodeTxt)//', rad' - k = k + 1 + InitOut%LinNames_x(k) = 'x1 '//trim(NodeTxt)//', rad' + k = k + 1 - InitOut%LinNames_x(k) = 'x2 '//trim(NodeTxt)//', rad' - k = k + 1 - - InitOut%LinNames_x(k) = 'x3 '//trim(NodeTxt)//', -' - k = k + 1 + InitOut%LinNames_x(k) = 'x2 '//trim(NodeTxt)//', rad' + k = k + 1 + + InitOut%LinNames_x(k) = 'x3 '//trim(NodeTxt)//', -' + k = k + 1 + endif InitOut%LinNames_x(k) = 'x4 '//trim(NodeTxt)//', -' p%dx(k) = 0.001 ! x4 is a number between 0 and 1, so we need this to be small @@ -5575,17 +6960,23 @@ SUBROUTINE Perturb_x( p, n, perturb_sign, x, dx ) if (n <= p%BEMT%DBEMT%lin_nx) then - if (n <= p%BEMT%DBEMT%lin_nx/2) then ! x_p%BEMT%DBEMT%element(i,j)%vind, else x_p%BEMT%DBEMT%element(i,j)%vind_dot + if (n <= p%BEMT%DBEMT%lin_nx/2) then ! x_p%BEMT%DBEMT%element(i,j)%vind, else x_p%BEMT%DBEMT%element(i,j)%vind_1 call GetStateIndices( n, size(x%BEMT%DBEMT%element,2), size(x%BEMT%DBEMT%element,1), size(x%BEMT%DBEMT%element(1,1)%vind), Blade, BladeNode, StateIndex ) x%BEMT%DBEMT%element(BladeNode,Blade)%vind(StateIndex) = x%BEMT%DBEMT%element(BladeNode,Blade)%vind(StateIndex) + dx * perturb_sign else - call GetStateIndices( n - p%BEMT%DBEMT%lin_nx/2, size(x%BEMT%DBEMT%element,2), size(x%BEMT%DBEMT%element,1), size(x%BEMT%DBEMT%element(1,1)%vind_dot), Blade, BladeNode, StateIndex ) - x%BEMT%DBEMT%element(BladeNode,Blade)%vind_dot(StateIndex) = x%BEMT%DBEMT%element(BladeNode,Blade)%vind_dot(StateIndex) + dx * perturb_sign + call GetStateIndices( n - p%BEMT%DBEMT%lin_nx/2, size(x%BEMT%DBEMT%element,2), size(x%BEMT%DBEMT%element,1), size(x%BEMT%DBEMT%element(1,1)%vind_1), Blade, BladeNode, StateIndex ) + x%BEMT%DBEMT%element(BladeNode,Blade)%vind_1(StateIndex) = x%BEMT%DBEMT%element(BladeNode,Blade)%vind_1(StateIndex) + dx * perturb_sign endif else !call GetStateIndices( n - p%BEMT%DBEMT%lin_nx, size(x%BEMT%UA%element,2), size(x%BEMT%UA%element,1), size(x%BEMT%UA%element(1,1)%x), Blade, BladeNode, StateIndex ) - call GetStateIndices( n - p%BEMT%DBEMT%lin_nx, size(x%BEMT%UA%element,2), size(x%BEMT%UA%element,1), 4, Blade, BladeNode, StateIndex ) + + if (p%BEMT%UA%UAMod==UA_OYE) then + call GetStateIndices( n - p%BEMT%DBEMT%lin_nx, size(x%BEMT%UA%element,2), size(x%BEMT%UA%element,1), 1, Blade, BladeNode, StateIndex ) + StateIndex=4 ! Always the 4th one + else + call GetStateIndices( n - p%BEMT%DBEMT%lin_nx, size(x%BEMT%UA%element,2), size(x%BEMT%UA%element,1), 4, Blade, BladeNode, StateIndex ) + endif x%BEMT%UA%element(BladeNode,Blade)%x(StateIndex) = x%BEMT%UA%element(BladeNode,Blade)%x(StateIndex) + dx * perturb_sign end if @@ -5617,9 +7008,10 @@ END SUBROUTINE 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 aerodyn::init_jacobian is consistant with this routine! -SUBROUTINE Compute_dY(p, y_p, y_m, delta_p, delta_m, dY) +SUBROUTINE Compute_dY(p, p_AD, y_p, y_m, delta_p, delta_m, dY) TYPE(RotParameterType) , INTENT(IN ) :: p !< parameters + TYPE(AD_ParameterType) , INTENT(IN ) :: p_AD !< parameters TYPE(RotOutputType) , INTENT(IN ) :: y_p !< AD outputs at \f$ u + \Delta_p u \f$ or \f$ x + \Delta_p x \f$ (p=plus) TYPE(RotOutputType) , INTENT(IN ) :: y_m !< AD outputs at \f$ u - \Delta_m u \f$ or \f$ x - \Delta_m x \f$ (m=minus) REAL(R8Ki) , INTENT(IN ) :: delta_p !< difference in inputs or states \f$ delta_p = \Delta_p u \f$ or \f$ delta_p = \Delta_p x \f$ @@ -5679,8 +7071,8 @@ SUBROUTINE Compute_dX(p, x_p, x_m, delta_p, delta_m, dX) do j=1,size(x_p%BEMT%DBEMT%element,2) ! number of blades do i=1,size(x_p%BEMT%DBEMT%element,1) ! number of nodes per blade - dX(indx_first:indx_first+1) = x_p%BEMT%DBEMT%element(i,j)%vind_dot - x_m%BEMT%DBEMT%element(i,j)%vind_dot - indx_first = indx_first + size(x_p%BEMT%DBEMT%element(i,j)%vind_dot) !+=2 + dX(indx_first:indx_first+1) = x_p%BEMT%DBEMT%element(i,j)%vind_1 - x_m%BEMT%DBEMT%element(i,j)%vind_1 + indx_first = indx_first + size(x_p%BEMT%DBEMT%element(i,j)%vind_1) !+=2 end do end do @@ -5688,12 +7080,21 @@ SUBROUTINE Compute_dX(p, x_p, x_m, delta_p, delta_m, dX) if (p%BEMT%UA%lin_nx>0) then - do j=1,size(x_p%BEMT%UA%element,2) ! number of blades - do i=1,size(x_p%BEMT%UA%element,1) ! number of nodes per blade - dX(indx_first:indx_first+3) = x_p%BEMT%UA%element(i,j)%x(1:4) - x_m%BEMT%UA%element(i,j)%x(1:4) - indx_first = indx_first + 4 ! = index_first += 4 + if (p%BEMT%UA%UAMod==UA_OYE) then + do j=1,size(x_p%BEMT%UA%element,2) ! number of blades + do i=1,size(x_p%BEMT%UA%element,1) ! number of nodes per blade + dX(indx_first) = x_p%BEMT%UA%element(i,j)%x(4) - x_m%BEMT%UA%element(i,j)%x(4) + indx_first = indx_first + 1 ! = index_first += 4 + end do end do - end do + else + do j=1,size(x_p%BEMT%UA%element,2) ! number of blades + do i=1,size(x_p%BEMT%UA%element,1) ! number of nodes per blade + dX(indx_first:indx_first+3) = x_p%BEMT%UA%element(i,j)%x(1:4) - x_m%BEMT%UA%element(i,j)%x(1:4) + indx_first = indx_first + 4 ! = index_first += 4 + end do + end do + endif end if @@ -5701,4 +7102,167 @@ SUBROUTINE Compute_dX(p, x_p, x_m, delta_p, delta_m, dX) END SUBROUTINE Compute_dX !---------------------------------------------------------------------------------------------------------------------------------- +!> Count number of wind points required by AeroDyn. +!! Should respect the order of AD_GetExternalWind and AD_SetExternalWindPositions +integer(IntKi) function AD_NumWindPoints(u_AD, o_AD) result(n) + type(AD_InputType), intent(in ) :: u_AD ! AeroDyn data + type(AD_OtherStateType), intent(in ) :: o_AD ! AeroDyn data + ! locals + integer(IntKi) :: k + integer(IntKi) :: iWT + n = 0 + do iWT=1, size(u_AD%rotors) + ! Blades + do k=1,size(u_AD%rotors(iWT)%BladeMotion) + n = n + u_AD%rotors(iWT)%BladeMotion(k)%NNodes + end do + ! Tower + n = n + u_AD%rotors(iWT)%TowerMotion%NNodes + ! Nacelle + if (u_AD%rotors(iWT)%NacelleMotion%Committed) then + n = n + u_AD%rotors(iWT)%NacelleMotion%NNodes ! 1 point + endif + ! Hub Motion + if (u_AD%rotors(iWT)%HubMotion%Committed) then + n = n + u_AD%rotors(iWT)%HubMotion%NNodes ! 1 point + endif + ! TailFin + n = n + u_AD%rotors(iWT)%TFinMotion%NNodes ! 1 point + enddo + if (allocated(o_AD%WakeLocationPoints)) then + n = n + size(o_AD%WakeLocationPoints, dim=2) + end if +end function AD_NumWindPoints +!---------------------------------------------------------------------------------------------------------------------------------- +!> Start index of the OLAF wind points for this turbine +!! Should respect the order of AD_GetExternalWind and AD_SetExternalWindPositions +integer(IntKi) function AD_BoxExceedPointsIdx(u_AD, o_AD) result(n) + type(AD_InputType), intent(in ) :: u_AD ! AeroDyn data + type(AD_OtherStateType), intent(in ) :: o_AD ! AeroDyn data + ! locals + integer(IntKi) :: k + integer(IntKi) :: TotPts ! call AD_NumWindPts, then subtract + TotPts = AD_NumWindPoints(u_AD, o_AD) + if (allocated(o_AD%WakeLocationPoints)) then + n = TotPts - size(o_AD%WakeLocationPoints, dim=2) + 1 ! start index of the olaf points + else ! No OLAF, so return -1 to indicate not used + n = -1 + endif +end function AD_BoxExceedPointsIdx +!---------------------------------------------------------------------------------------------------------------------------------- +!> Sets the wind calculated by InflowWind into the AeroDyn arrays ("InputSolve_IfW") +!! Should respect the order of AD_NumWindPoints and AD_SetExternalWindPositions +subroutine AD_GetExternalWind(u_AD, VelUVW, node, errStat, errMsg) + ! Passed variables + type(AD_InputType), intent(inout) :: u_AD !< AeroDyn inputs + real(ReKi), dimension(:,:), intent(in ) :: VelUVW !< Velocity array 3 x n (as typically returned by InflowWind) + integer(IntKi), intent(inout) :: node !< Counter for dimension 2 of VelUVW. Initialized by caller and returned! + integer(IntKi) :: errStat!< Error status of the operation + character(*) :: errMsg !< Error message if errStat /= ErrID_None + ! Local variables: + integer(IntKi) :: j ! Loops through nodes / elements. + integer(IntKi) :: k ! Loops through blades. + integer(IntKi) :: nNodes + integer(IntKi) :: iWT + errStat = ErrID_None + errMsg = "" + + do iWT=1,size(u_AD%rotors) + nNodes = size(u_AD%rotors(iWT)%InflowOnBlade,2) + ! Blades + do k=1,size(u_AD%rotors(iWT)%InflowOnBlade,3) + do j=1,nNodes + u_AD%rotors(iWT)%InflowOnBlade(:,j,k) = VelUVW(:,node) + node = node + 1 + end do + end do + ! Tower + if ( allocated(u_AD%rotors(iWT)%InflowOnTower) ) then + do j=1,size(u_AD%rotors(iWT)%InflowOnTower,2) + u_AD%rotors(iWT)%InflowOnTower(:,j) = VelUVW(:,node) + node = node + 1 + end do + end if + ! Nacelle + if (u_AD%rotors(iWT)%NacelleMotion%Committed) then + u_AD%rotors(iWT)%InflowOnNacelle(:) = VelUVW(:,node) + node = node + 1 + else + u_AD%rotors(iWT)%InflowOnNacelle = 0.0_ReKi + end if + ! Hub + if (u_AD%rotors(iWT)%HubMotion%NNodes > 0) then + u_AD%rotors(iWT)%InflowOnHub(:) = VelUVW(:,node) + node = node + 1 + else + u_AD%rotors(iWT)%InflowOnHub = 0.0_ReKi + end if + ! TailFin + if (u_AD%rotors(iWT)%TFinMotion%NNodes > 0) then + u_AD%rotors(iWT)%InflowOnTailFin(:) = VelUVW(:,node) + node = node + 1 + else + u_AD%rotors(iWT)%InflowOnTailFin = 0.0_ReKi + end if + enddo ! rotors + ! OLAF points + if ( allocated(u_AD%InflowWakeVel) ) then + do j=1,size(u_AD%InflowWakeVel,DIM=2) + u_AD%InflowWakeVel(:,j) = VelUVW(:,node) + node = node + 1 + end do !j, wake points + end if +end subroutine AD_GetExternalWind +!---------------------------------------------------------------------------------------------------------------------------------- +!> Set inputs for inflow wind +!! Order should match AD_NumWindPoints and AD_GetExternalWind +subroutine AD_SetExternalWindPositions(u_AD, o_AD, PosXYZ, node, errStat, errMsg) + type(AD_InputType), intent(in ) :: u_AD !< AeroDyn inputs + type(AD_OtherStateType), intent(in ) :: o_AD !< AeroDyn other states + real(ReKi), dimension(:,:), intent(inout) :: PosXYZ !< Positions + integer(IntKi), intent(inout) :: node !< Counter for dimension 2 of PosXYZ. Initialized by caller and returned! + integer(IntKi) , intent(out ) :: errStat !< Status of error message + character(*) , intent(out ) :: errMsg !< Error message if errStat /= ErrID_None + integer :: k, j, iWT + errStat = ErrID_None + errMsg = '' + + do iWT=1,size(u_AD%rotors) + ! Blade + do k = 1,size(u_AD%rotors(iWT)%BladeMotion) + do j = 1,u_AD%rotors(iWT)%BladeMotion(k)%nNodes + node = node + 1 + PosXYZ(:,node) = u_AD%rotors(iWT)%BladeMotion(k)%TranslationDisp(:,j) + u_AD%rotors(iWT)%BladeMotion(k)%Position(:,j) + end do !J = 1,p%Bldnodes ! Loop through the blade nodes / elements + end do !K = 1,p%NumBl + ! Tower + do j = 1,u_AD%rotors(iWT)%TowerMotion%nNodes + node = node + 1 + PosXYZ(:,node) = u_AD%rotors(iWT)%TowerMotion%TranslationDisp(:,J) + u_AD%rotors(iWT)%TowerMotion%Position(:,J) + end do + ! Nacelle + if (u_AD%rotors(iWT)%NacelleMotion%Committed) then + node = node + 1 + PosXYZ(:,node) = u_AD%rotors(iWT)%NacelleMotion%TranslationDisp(:,1) + u_AD%rotors(iWT)%NacelleMotion%Position(:,1) + end if + ! Hub + if (u_AD%rotors(iWT)%HubMotion%Committed) then + node = node + 1 + PosXYZ(:,node) = u_AD%rotors(iWT)%HubMotion%TranslationDisp(:,1) + u_AD%rotors(iWT)%HubMotion%Position(:,1) + end if + ! TailFin + if (u_AD%rotors(iWT)%TFinMotion%Committed) then + node = node + 1 + PosXYZ(:,node) = u_AD%rotors(iWT)%TFinMotion%TranslationDisp(:,1) + u_AD%rotors(iWT)%TFinMotion%Position(:,1) + end if + enddo ! iWT + ! vortex points from FVW in AD15 + if (allocated(o_AD%WakeLocationPoints)) then + do j = 1,size(o_AD%WakeLocationPoints,dim=2) + node = node + 1 + PosXYZ(:,node) = o_AD%WakeLocationPoints(:,j) + enddo !j, wake points + end if +end subroutine AD_SetExternalWindPositions + END MODULE AeroDyn diff --git a/modules/aerodyn/src/AeroDyn_AllBldNdOuts_IO.f90 b/modules/aerodyn/src/AeroDyn_AllBldNdOuts_IO.f90 index 7110eeb83..72a199cce 100644 --- a/modules/aerodyn/src/AeroDyn_AllBldNdOuts_IO.f90 +++ b/modules/aerodyn/src/AeroDyn_AllBldNdOuts_IO.f90 @@ -19,7 +19,6 @@ MODULE AeroDyn_AllBldNdOuts_IO ! Parameters related to output length (number of characters allowed in the output data headers): - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 6 ! The NREL allowed channel name length is usually 20. We are making these of the form B#N##namesuffix ! =================================================================================================== @@ -27,9 +26,9 @@ MODULE AeroDyn_AllBldNdOuts_IO ! using the parameters listed in the "OutListParameters.xlsx" Excel file. Any changes to these ! lines should be modified in the Matlab script and/or Excel worksheet as necessary. ! =================================================================================================== -! This code was generated by Write_ChckOutLst.m at 02-Mar-2022 11:12:19. - +! This code was generated by "Write_ChckOutLst.m" at 07-Sep-2022 16:16:13. + ! Indices for computing output channels: ! NOTES: ! (1) These parameters are in the order stored in "OutListParameters.xlsx" @@ -98,12 +97,18 @@ MODULE AeroDyn_AllBldNdOuts_IO INTEGER(IntKi), PARAMETER :: BldNd_Uin = 60 INTEGER(IntKi), PARAMETER :: BldNd_Uit = 61 INTEGER(IntKi), PARAMETER :: BldNd_Uir = 62 + INTEGER(IntKi), PARAMETER :: BldNd_Fbn = 63 + INTEGER(IntKi), PARAMETER :: BldNd_Fbt = 64 + INTEGER(IntKi), PARAMETER :: BldNd_Fbs = 65 + INTEGER(IntKi), PARAMETER :: BldNd_Mbn = 66 + INTEGER(IntKi), PARAMETER :: BldNd_Mbt = 67 + INTEGER(IntKi), PARAMETER :: BldNd_Mbs = 68 ! The maximum number of output channels which can be output by the code. - INTEGER(IntKi), PARAMETER, PUBLIC :: BldNd_MaxOutPts = 62 + INTEGER(IntKi), PARAMETER, PUBLIC :: BldNd_MaxOutPts = 68 -!End of code generated by Matlab script +!End of code generated by Matlab script Write_ChckOutLst ! =================================================================================================== CONTAINS @@ -112,11 +117,10 @@ MODULE AeroDyn_AllBldNdOuts_IO !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine populates the headers with the blade node outputs. The iteration cycle is blade:node:channel (channel iterated !! fastest). If this iteration order is changed, it should be changed in the Calc_WriteAllBldNdOutput routine as well. -SUBROUTINE AllBldNdOuts_InitOut( InitOut, p, p_AD, InputFileData, ErrStat, ErrMsg ) +SUBROUTINE AllBldNdOuts_InitOut( InitOut, p, InputFileData, ErrStat, ErrMsg ) TYPE(RotInitOutputType), INTENT(INOUT) :: InitOut ! output data TYPE(RotParameterType), INTENT(IN ) :: p ! The rotor parameters - TYPE(AD_ParameterType), INTENT(IN ) :: p_AD ! The module parameters TYPE(RotInputFile), INTENT(IN ) :: InputFileData ! All the data in the AeroDyn input file (want Blade Span for channel name) INTEGER(IntKi), INTENT( OUT) :: ErrStat ! The error status code CHARACTER(*), INTENT( OUT) :: ErrMsg ! The error message, if an error occurred @@ -248,7 +252,7 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx CASE ( BldNd_VUndx ) DO IdxBlade=1,p%BldNd_BladesOut DO IdxNode=1,p%NumBlNds - y%WriteOutput( OutIdx ) = dot_product( m%WithoutSweepPitchTwist(1,:,IdxNode,IdxBlade), u%InflowOnBlade(:,IdxNode,IdxBlade) ) + y%WriteOutput( OutIdx ) = dot_product( m%orientationAnnulus(1,:,IdxNode,IdxBlade), u%InflowOnBlade(:,IdxNode,IdxBlade) ) OutIdx = OutIdx + 1 END DO END DO @@ -257,7 +261,7 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx CASE ( BldNd_VUndy ) DO IdxBlade=1,p%BldNd_BladesOut DO IdxNode=1,p%NumBlNds - y%WriteOutput( OutIdx ) = dot_product( m%WithoutSweepPitchTwist(2,:,IdxNode,IdxBlade), u%InflowOnBlade(:,IdxNode,IdxBlade) ) + y%WriteOutput( OutIdx ) = dot_product( m%orientationAnnulus(2,:,IdxNode,IdxBlade), u%InflowOnBlade(:,IdxNode,IdxBlade) ) OutIdx = OutIdx + 1 END DO END DO @@ -265,14 +269,14 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx CASE ( BldNd_VUndz ) DO IdxBlade=1,p%BldNd_BladesOut DO IdxNode=1,p%NumBlNds - y%WriteOutput( OutIdx ) = dot_product( m%WithoutSweepPitchTwist(3,:,IdxNode,IdxBlade), u%InflowOnBlade(:,IdxNode,IdxBlade) ) + y%WriteOutput( OutIdx ) = dot_product( m%orientationAnnulus(3,:,IdxNode,IdxBlade), u%InflowOnBlade(:,IdxNode,IdxBlade) ) OutIdx = OutIdx + 1 END DO END DO - ! ***** Disturbed wind velocity in local blade coord system ***** + ! ***** Undisturbed wind velocity in inertial/global coord system ***** CASE ( BldNd_VUndxi ) DO IdxBlade=1,p%BldNd_BladesOut DO IdxNode=1,p%NumBlNds @@ -304,7 +308,7 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx CASE ( BldNd_VDisx ) DO IdxBlade=1,p%BldNd_BladesOut DO IdxNode=1,p%NumBlNds - y%WriteOutput( OutIdx ) = dot_product( m%WithoutSweepPitchTwist(1,:,IdxNode,IdxBlade), m%DisturbedInflow(:,IdxNode,IdxBlade) ) + y%WriteOutput( OutIdx ) = dot_product( m%orientationAnnulus(1,:,IdxNode,IdxBlade), m%DisturbedInflow(:,IdxNode,IdxBlade) ) OutIdx = OutIdx + 1 END DO END DO @@ -312,7 +316,7 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx CASE ( BldNd_VDisy ) DO IdxBlade=1,p%BldNd_BladesOut DO IdxNode=1,p%NumBlNds - y%WriteOutput( OutIdx ) = dot_product( m%WithoutSweepPitchTwist(2,:,IdxNode,IdxBlade), m%DisturbedInflow(:,IdxNode,IdxBlade) ) + y%WriteOutput( OutIdx ) = dot_product( m%orientationAnnulus(2,:,IdxNode,IdxBlade), m%DisturbedInflow(:,IdxNode,IdxBlade) ) OutIdx = OutIdx + 1 END DO END DO @@ -320,7 +324,7 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx CASE ( BldNd_VDisz ) DO IdxBlade=1,p%BldNd_BladesOut DO IdxNode=1,p%NumBlNds - y%WriteOutput( OutIdx ) = dot_product( m%WithoutSweepPitchTwist(3,:,IdxNode,IdxBlade), m%DisturbedInflow(:,IdxNode,IdxBlade) ) + y%WriteOutput( OutIdx ) = dot_product( m%orientationAnnulus(3,:,IdxNode,IdxBlade), m%DisturbedInflow(:,IdxNode,IdxBlade) ) OutIdx = OutIdx + 1 END DO END DO @@ -330,7 +334,7 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx CASE ( BldNd_STVx ) DO IdxBlade=1,p%BldNd_BladesOut DO IdxNode=1,p%NumBlNds - y%WriteOutput( OutIdx ) = dot_product( m%WithoutSweepPitchTwist(1,:,IdxNode,IdxBlade), u%BladeMotion(IdxBlade)%TranslationVel(:,IdxNode) ) + y%WriteOutput( OutIdx ) = dot_product( m%orientationAnnulus(1,:,IdxNode,IdxBlade), u%BladeMotion(IdxBlade)%TranslationVel(:,IdxNode) ) OutIdx = OutIdx + 1 END DO END DO @@ -338,7 +342,7 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx CASE ( BldNd_STVy ) DO IdxBlade=1,p%BldNd_BladesOut DO IdxNode=1,p%NumBlNds - y%WriteOutput( OutIdx ) = dot_product( m%WithoutSweepPitchTwist(2,:,IdxNode,IdxBlade), u%BladeMotion(IdxBlade)%TranslationVel(:,IdxNode) ) + y%WriteOutput( OutIdx ) = dot_product( m%orientationAnnulus(2,:,IdxNode,IdxBlade), u%BladeMotion(IdxBlade)%TranslationVel(:,IdxNode) ) OutIdx = OutIdx + 1 END DO END DO @@ -346,7 +350,7 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx CASE ( BldNd_STVz ) DO IdxBlade=1,p%BldNd_BladesOut DO IdxNode=1,p%NumBlNds - y%WriteOutput( OutIdx ) = dot_product( m%WithoutSweepPitchTwist(3,:,IdxNode,IdxBlade), u%BladeMotion(IdxBlade)%TranslationVel(:,IdxNode) ) + y%WriteOutput( OutIdx ) = dot_product( m%orientationAnnulus(3,:,IdxNode,IdxBlade), u%BladeMotion(IdxBlade)%TranslationVel(:,IdxNode) ) OutIdx = OutIdx + 1 END DO END DO @@ -1046,8 +1050,7 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx DO IdxBlade=1,p%BldNd_BladesOut iW = p_AD%FVW%Bld2Wings(iRot, IdxBlade) DO IdxNode=1,u%BladeMotion(IdxBlade)%NNodes -!NOT available in FVW yet - y%WriteOutput( OutIdx ) = 0.0_ReKi + y%WriteOutput( OutIdx ) = m_AD%FVW%W(iW)%BN_Cpmin(IdxNode) OutIdx = OutIdx + 1 ENDDO ENDDO @@ -1162,7 +1165,7 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx DO IdxBlade=1,p%BldNd_BladesOut DO IdxNode=1,u%BladeMotion(IdxBlade)%NNodes Vind_s = (/ -m%BEMT_u(Indx)%Vx(IdxNode,IdxBlade)*m%BEMT_y%axInduction(IdxNode,IdxBlade), m%BEMT_u(Indx)%Vy(IdxNode,IdxBlade)*m%BEMT_y%tanInduction(IdxNode,IdxBlade), 0.0_ReKi /) - Vind_g = matmul(Vind_s, m%WithoutSweepPitchTwist(:,:,IdxNode,IdxBlade)) + Vind_g = matmul(Vind_s, m%orientationAnnulus(:,:,IdxNode,IdxBlade)) y%WriteOutput( OutIdx ) = dot_product(M_pg(1,1:3,IdxBlade), Vind_g(1:3) ) ! Uihn, hub normal OutIdx = OutIdx + 1 ENDDO @@ -1183,7 +1186,7 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx DO IdxBlade=1,p%BldNd_BladesOut DO IdxNode=1,u%BladeMotion(IdxBlade)%NNodes Vind_s = (/ -m%BEMT_u(Indx)%Vx(IdxNode,IdxBlade)*m%BEMT_y%axInduction(IdxNode,IdxBlade), m%BEMT_u(Indx)%Vy(IdxNode,IdxBlade)*m%BEMT_y%tanInduction(IdxNode,IdxBlade), 0.0_ReKi /) - Vind_g = matmul(Vind_s, m%WithoutSweepPitchTwist(:,:,IdxNode,IdxBlade)) + Vind_g = matmul(Vind_s, m%orientationAnnulus(:,:,IdxNode,IdxBlade)) y%WriteOutput( OutIdx ) = dot_product(M_pg(2,1:3,IdxBlade), Vind_g(1:3) ) ! Uiht, hub tangential OutIdx = OutIdx + 1 ENDDO @@ -1204,7 +1207,7 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx DO IdxBlade=1,p%BldNd_BladesOut DO IdxNode=1,u%BladeMotion(IdxBlade)%NNodes Vind_s = (/ -m%BEMT_u(Indx)%Vx(IdxNode,IdxBlade)*m%BEMT_y%axInduction(IdxNode,IdxBlade), m%BEMT_u(Indx)%Vy(IdxNode,IdxBlade)*m%BEMT_y%tanInduction(IdxNode,IdxBlade), 0.0_ReKi /) - Vind_g = matmul(Vind_s, m%WithoutSweepPitchTwist(:,:,IdxNode,IdxBlade)) + Vind_g = matmul(Vind_s, m%orientationAnnulus(:,:,IdxNode,IdxBlade)) y%WriteOutput( OutIdx ) = dot_product(M_pg(3,1:3,IdxBlade), Vind_g(1:3) ) ! Uihr, hub radial OutIdx = OutIdx + 1 ENDDO @@ -1218,7 +1221,56 @@ SUBROUTINE Calc_WriteAllBldNdOutput( p, p_AD, u, m, m_AD, x, y, OtherState, Indx ENDDO ENDDO endif - + + ! Normal buoyant force (to chord), tangential buoyant force (to chord), spanwise buoyant force + CASE ( BldNd_Fbn ) + DO IdxBlade=1,p%BldNd_BladesOut + DO IdxNode=1,p%NumBlNds + y%WriteOutput( OutIdx ) = dot_product( u%BladeMotion(IdxBlade)%Orientation(1,:,IdxNode), m%BlFB(IdxNode,IdxBlade,:) ) + OutIdx = OutIdx + 1 + END DO + END DO + + CASE ( BldNd_Fbt ) + DO IdxBlade=1,p%BldNd_BladesOut + DO IdxNode=1,p%NumBlNds + y%WriteOutput( OutIdx ) = dot_product( u%BladeMotion(IdxBlade)%Orientation(2,:,IdxNode), m%BlFB(IdxNode,IdxBlade,:) ) + OutIdx = OutIdx + 1 + END DO + END DO + + CASE ( BldNd_Fbs ) + DO IdxBlade=1,p%BldNd_BladesOut + DO IdxNode=1,p%NumBlNds + y%WriteOutput( OutIdx ) = dot_product( u%BladeMotion(IdxBlade)%Orientation(3,:,IdxNode), m%BlFB(IdxNode,IdxBlade,:) ) + OutIdx = OutIdx + 1 + END DO + END DO + + ! Normal buoyant moment (to chord), tangential buoyant moment (to chord), spanwise buoyant moment + CASE ( BldNd_Mbn ) + DO IdxBlade=1,p%BldNd_BladesOut + DO IdxNode=1,p%NumBlNds + y%WriteOutput( OutIdx ) = dot_product( u%BladeMotion(IdxBlade)%Orientation(1,:,IdxNode), m%BlMB(IdxNode,IdxBlade,:) ) + OutIdx = OutIdx + 1 + END DO + END DO + + CASE ( BldNd_Mbt ) + DO IdxBlade=1,p%BldNd_BladesOut + DO IdxNode=1,p%NumBlNds + y%WriteOutput( OutIdx ) = dot_product( u%BladeMotion(IdxBlade)%Orientation(2,:,IdxNode), m%BlMB(IdxNode,IdxBlade,:) ) + OutIdx = OutIdx + 1 + END DO + END DO + + CASE ( BldNd_Mbs ) + DO IdxBlade=1,p%BldNd_BladesOut + DO IdxNode=1,p%NumBlNds + y%WriteOutput( OutIdx ) = dot_product( u%BladeMotion(IdxBlade)%Orientation(3,:,IdxNode), m%BlMB(IdxNode,IdxBlade,:) ) + OutIdx = OutIdx + 1 + END DO + END DO END SELECT @@ -1251,10 +1303,10 @@ SUBROUTINE AllBldNdOuts_SetParameters( InputFileData, p, p_AD, ErrStat, ErrMsg ) ! Check if the requested blades exist - IF ( (InputFileData%BldNd_BladesOut < 0_IntKi) ) then + IF ( (InputFileData%BldNd_BladesOut < 0_IntKi) ) THEN p%BldNd_BladesOut = 0_IntKi ELSE IF ((InputFileData%BldNd_BladesOut > p%NumBlades) ) THEN - CALL SetErrStat( ErrID_Warn, " Number of blades to output data at all blade nodes (BldNd_BladesOut) must be less than "//TRIM(Num2LStr(p%NumBlades))//".", ErrStat, ErrMsg, RoutineName) + CALL SetErrStat( ErrID_Warn, " Number of blades to output data at all blade nodes (BldNd_BladesOut) must be no more than the total number of blades, "//TRIM(Num2LStr(p%NumBlades))//".", ErrStat, ErrMsg, RoutineName) p%BldNd_BladesOut = p%NumBlades ! NOTE: we are forgiving and plateau to numBlades ELSE p%BldNd_BladesOut = InputFileData%BldNd_BladesOut @@ -1317,11 +1369,11 @@ END SUBROUTINE AllBldNdOuts_SetParameters !---------------------------------------------------------------------------------------------------------------------------------- !> This routine checks to see if any requested output channel names (stored in the OutList(:)) are invalid. It returns a !! warning if any of the channels are not available outputs from the module. -!! It assigns the settings for OutParam(:) (i.e, the index, name, and units of the output channels, WriteOutput(:)). -!! the sign is set to 0 if the channel is invalid. +!! It assigns the settings for OutParam(:) (i.e, the index, name, and units of the output channels, WriteOutput(:)). +!! the sign is set to 0 if the channel is invalid. !! It sets assumes the value p%NumOuts has been set before this routine has been called, and it sets the values of p%OutParam here. !! -!! This routine was generated by Write_ChckOutLst.m using the parameters listed in OutListParameters.xlsx at 02-Mar-2022 11:12:19. +!! This routine was generated by Write_ChckOutLst.m using the parameters listed in OutListParameters.xlsx at 07-Sep-2022 16:16:13. SUBROUTINE BldNdOuts_SetOutParam(BldNd_OutList, p, p_AD, ErrStat, ErrMsg ) !.................................................................................................................................. @@ -1329,8 +1381,8 @@ SUBROUTINE BldNdOuts_SetOutParam(BldNd_OutList, p, p_AD, ErrStat, ErrMsg ) ! Passed variables - CHARACTER(ChanLen), INTENT(IN) :: BldNd_OutList(:) !< The list out user-requested outputs - TYPE(RotParameterType), INTENT(INOUT) :: p !< The rotor parameters + CHARACTER(ChanLen), INTENT(IN) :: BldNd_OutList(:) !< The list of user-requested outputs + TYPE(RotParameterType), INTENT(INOUT) :: p !< The module parameters TYPE(AD_ParameterType), INTENT(INOUT) :: p_AD !< The module parameters INTEGER(IntKi), INTENT(OUT) :: ErrStat !< The error status code CHARACTER(*), INTENT(OUT) :: ErrMsg !< The error message, if an error occurred @@ -1343,36 +1395,38 @@ SUBROUTINE BldNdOuts_SetOutParam(BldNd_OutList, p, p_AD, ErrStat, ErrMsg ) INTEGER :: INDX ! Index for valid arrays LOGICAL :: InvalidOutput(1:BldNd_MaxOutPts) ! This array determines if the output channel is valid for this configuration - CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I) CHARACTER(*), PARAMETER :: RoutineName = "BldNdOuts_SetOutParam" - CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(62) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(68) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically "ALPHA ","AXIND ","CD ","CD_STATIC","CHI ","CL ","CLRNC ","CL_STATIC", & "CM ","CM_STATIC","CN ","CPMIN ","CT ","CURVE ","CX ","CY ", & - "DEBUG1 ","DEBUG2 ","DEBUG3 ","DYNP ","FD ","FL ","FN ","FT ", & - "FX ","FY ","GAM ","GEOMPHI ","M ","MM ","PHI ","RE ", & - "SGCAV ","SIGCR ","STVX ","STVY ","STVZ ","THETA ","TNIND ","UA_FLAG ", & - "UA_X1 ","UA_X2 ","UA_X3 ","UA_X4 ","UA_X5 ","UIN ","UIR ","UIT ", & - "VDISX ","VDISY ","VDISZ ","VINDX ","VINDY ","VREL ","VUNDX ","VUNDXI ", & - "VUNDY ","VUNDYI ","VUNDZ ","VUNDZI ","VX ","VY "/) - INTEGER(IntKi), PARAMETER :: ParamIndxAry(62) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + "DEBUG1 ","DEBUG2 ","DEBUG3 ","DYNP ","FBN ","FBS ","FBT ","FD ", & + "FL ","FN ","FT ","FX ","FY ","GAM ","GEOMPHI ","M ", & + "MBN ","MBS ","MBT ","MM ","PHI ","RE ","SGCAV ","SIGCR ", & + "STVX ","STVY ","STVZ ","THETA ","TNIND ","UA_FLAG ","UA_X1 ","UA_X2 ", & + "UA_X3 ","UA_X4 ","UA_X5 ","UIN ","UIR ","UIT ","VDISX ","VDISY ", & + "VDISZ ","VINDX ","VINDY ","VREL ","VUNDX ","VUNDXI ","VUNDY ","VUNDYI ", & + "VUNDZ ","VUNDZI ","VX ","VY "/) + INTEGER(IntKi), PARAMETER :: ParamIndxAry(68) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) BldNd_Alpha , BldNd_AxInd , BldNd_Cd , BldNd_Cd_Static , BldNd_Chi , BldNd_Cl , BldNd_Clrnc , BldNd_Cl_Static , & BldNd_Cm , BldNd_Cm_Static , BldNd_Cn , BldNd_CpMin , BldNd_Ct , BldNd_Curve , BldNd_Cx , BldNd_Cy , & - BldNd_Debug1 , BldNd_Debug2 , BldNd_Debug3 , BldNd_DynP , BldNd_Fd , BldNd_Fl , BldNd_Fn , BldNd_Ft , & - BldNd_Fx , BldNd_Fy , BldNd_Gam , BldNd_GeomPhi , BldNd_M , BldNd_Mm , BldNd_Phi , BldNd_Re , & - BldNd_SgCav , BldNd_SigCr , BldNd_STVx , BldNd_STVy , BldNd_STVz , BldNd_Theta , BldNd_TnInd , BldNd_UA_Flag , & - BldNd_UA_x1 , BldNd_UA_x2 , BldNd_UA_x3 , BldNd_UA_x4 , BldNd_UA_x5 , BldNd_Uin , BldNd_Uir , BldNd_Uit , & - BldNd_VDisx , BldNd_VDisy , BldNd_VDisz , BldNd_Vindx , BldNd_Vindy , BldNd_VRel , BldNd_VUndx , BldNd_Vundxi , & - BldNd_VUndy , BldNd_Vundyi , BldNd_VUndz , BldNd_Vundzi , BldNd_Vx , BldNd_Vy /) - CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(62) = (/ & ! This lists the units corresponding to the allowed parameters + BldNd_Debug1 , BldNd_Debug2 , BldNd_Debug3 , BldNd_DynP , BldNd_Fbn , BldNd_Fbs , BldNd_Fbt , BldNd_Fd , & + BldNd_Fl , BldNd_Fn , BldNd_Ft , BldNd_Fx , BldNd_Fy , BldNd_Gam , BldNd_GeomPhi , BldNd_M , & + BldNd_Mbn , BldNd_Mbs , BldNd_Mbt , BldNd_Mm , BldNd_Phi , BldNd_Re , BldNd_SgCav , BldNd_SigCr , & + BldNd_STVx , BldNd_STVy , BldNd_STVz , BldNd_Theta , BldNd_TnInd , BldNd_UA_Flag , BldNd_UA_x1 , BldNd_UA_x2 , & + BldNd_UA_x3 , BldNd_UA_x4 , BldNd_UA_x5 , BldNd_Uin , BldNd_Uir , BldNd_Uit , BldNd_VDisx , BldNd_VDisy , & + BldNd_VDisz , BldNd_Vindx , BldNd_Vindy , BldNd_VRel , BldNd_VUndx , BldNd_Vundxi , BldNd_VUndy , BldNd_Vundyi , & + BldNd_VUndz , BldNd_Vundzi , BldNd_Vx , BldNd_Vy /) + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(68) = (/ & ! This lists the units corresponding to the allowed parameters "(deg) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(m) ","(-) ", & "(-) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & "(-) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(m^2/s)","(1/0) ","(-) ","(N-m/m)","(deg) ","(-) ", & - "(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(rad) ","(rad) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(1/0) ","(-) ", & + "(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(rad) ","(rad) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) "/) + "(m/s) ","(m/s) ","(m/s) ","(m/s) "/) ! Initialize values @@ -1383,6 +1437,15 @@ SUBROUTINE BldNdOuts_SetOutParam(BldNd_OutList, p, p_AD, ErrStat, ErrMsg ) ! ..... Developer must add checking for invalid inputs here: ..... + if (.not. p%Buoyancy) then + InvalidOutput( BldNd_Fbn ) = .true. + InvalidOutput( BldNd_Fbt ) = .true. + InvalidOutput( BldNd_Fbs ) = .true. + InvalidOutput( BldNd_Mbn ) = .true. + InvalidOutput( BldNd_Mbt ) = .true. + InvalidOutput( BldNd_Mbs ) = .true. + end if + ! The following are valid only for BEMT/DBEMT if (p_AD%WakeMod /= WakeMod_FVW) then InvalidOutput( BldNd_Cl_Static ) = .true. @@ -1392,7 +1455,6 @@ SUBROUTINE BldNdOuts_SetOutParam(BldNd_OutList, p, p_AD, ErrStat, ErrMsg ) ! The following are invalid for free vortex wake InvalidOutput( BldNd_Chi ) = .true. InvalidOutput( BldNd_Curve ) = .true. - InvalidOutput( BldNd_CpMin ) = .true. InvalidOutput( BldNd_GeomPhi ) = .true. ! applies only to BEM endif @@ -1404,7 +1466,7 @@ SUBROUTINE BldNdOuts_SetOutParam(BldNd_OutList, p, p_AD, ErrStat, ErrMsg ) InvalidOutput( BldNd_UA_x4 ) = .true. InvalidOutput( BldNd_UA_x5 ) = .true. end if - + ! ................. End of validity checking ................. @@ -1427,13 +1489,14 @@ SUBROUTINE BldNdOuts_SetOutParam(BldNd_OutList, p, p_AD, ErrStat, ErrMsg ) DO I = 1,p%BldNd_NumOuts p%BldNd_OutParam(I)%Name = BldNd_OutList(I) - OutListTmp = BldNd_OutList(I) - p%BldNd_OutParam(I)%SignM = 1 ! this won't be used - - CALL Conv2UC( OutListTmp ) ! Convert OutListTmp to upper case + Indx = FindValidChannelIndx(BldNd_OutList(I), ValidParamAry, p%BldNd_OutParam(I)%SignM) - Indx = IndexCharAry( OutListTmp(1:OutStrLenM1), ValidParamAry ) + if (p%BldNd_OutParam(I)%SignM /= 1) then ! this won't be used + CALL SetErrStat(ErrID_Severe, "Negative channels not allowed for nodal outputs. Resetting channel name.", ErrStat, ErrMsg, RoutineName) + p%BldNd_OutParam(I)%SignM = 1 + p%BldNd_OutParam(I)%Name = p%BldNd_OutParam(I)%Name(2:) ! remove the first character that makes this a negative value + end if IF ( Indx > 0 ) THEN ! we found the channel name IF ( InvalidOutput( ParamIndxAry(Indx) ) ) THEN ! but, it isn't valid for these settings diff --git a/modules/aerodyn/src/AeroDyn_Driver.f90 b/modules/aerodyn/src/AeroDyn_Driver.f90 index 42202c4d8..fdc343249 100644 --- a/modules/aerodyn/src/AeroDyn_Driver.f90 +++ b/modules/aerodyn/src/AeroDyn_Driver.f90 @@ -1,105 +1,107 @@ -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2015-2016 National Renewable Energy Laboratory -! -! This file is part of AeroDyn. -! -! 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. -! -!********************************************************************************************************************************** -program AeroDyn_Driver - use AeroDyn_Driver_Subs, only: dat, dvr_Init, dvr_InitCase, dvr_TimeStep, dvr_CleanUp, dvr_EndCase - use AeroDyn_Driver_Subs, only: idAnalysisRegular, idAnalysisTimeD, idAnalysisCombi - use NWTC_IO - use NWTC_Num, only: RunTimes, SimStatus, SimStatus_FirstTime - implicit none - ! Program variables - REAL(ReKi) :: PrevClockTime ! Clock time at start of simulation in seconds [(s)] - REAL(ReKi) :: UsrTime1 ! User CPU time for simulation initialization [(s)] - REAL(ReKi) :: UsrTime2 ! User CPU time for simulation (without intialization) [(s)] - INTEGER(IntKi) , DIMENSION(1:8) :: StrtTime ! Start time of simulation (including intialization) [-] - INTEGER(IntKi) , DIMENSION(1:8) :: SimStrtTime ! Start time of simulation (after initialization) [-] - REAL(DbKi) :: t_global ! global-loop time marker - REAL(DbKi) :: t_final ! global-loop time marker - REAL(DbKi) :: TiLstPrn ! The simulation time of the last print (to file) [(s)] - integer :: nt !< loop counter (for time step) - integer(IntKi) :: iCase ! loop counter (for driver case) - 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) - UsrTime1 = MAX( 0.0_ReKi, UsrTime1 ) ! CPU_TIME: If a meaningful time cannot be returned, a processor-dependent negative value is returned - - dat%initialized=.false. - call dvr_Init(dat%dvr, dat%AD, dat%IW, dat%errStat, dat%errMsg); call CheckError() - - do iCase= 1,dat%dvr%numCases - - ! Initial case - call dvr_InitCase(iCase, dat%dvr, dat%AD, dat%IW, dat%errStat, dat%errMsg); call CheckError() - dat%initialized=.true. - - ! Init of time estimator - t_global=0.0_DbKi - t_final=dat%dvr%numSteps*dat%dvr%dt - if (dat%dvr%analysisType/=idAnalysisCombi) then - call SimStatus_FirstTime( TiLstPrn, PrevClockTime, SimStrtTime, UsrTime2, t_global, t_final ) - endif - - ! One time loop - do nt = 1, dat%dvr%numSteps - call dvr_TimeStep(nt, dat%dvr, dat%AD, dat%IW, dat%errStat, dat%errMsg); call CheckError() - ! Time update to screen - t_global=nt*dat%dvr%dt - if (dat%dvr%analysisType/=idAnalysisCombi) then - if (mod( nt + 1, 10 )==0) call SimStatus(TiLstPrn, PrevClockTime, t_global, t_final) - endif - end do !nt=1,numSteps - - if (dat%dvr%analysisType/=idAnalysisCombi) then - ! display runtime to screen - call RunTimes(StrtTime, UsrTime1, SimStrtTime, UsrTime2, t_global) - endif - - call dvr_EndCase(dat%dvr, dat%AD, dat%IW, dat%initialized, dat%errStat, dat%errMsg); call CheckError() - - enddo ! Loop on cases - - call dvr_End() -contains -!................................ - subroutine CheckError() - if (dat%ErrStat /= ErrID_None) then - call WrScr(TRIM(dat%errMsg)) - if (dat%errStat >= AbortErrLev) then - call dvr_End() - end if - end if - end subroutine CheckError -!................................ - subroutine dvr_End() - integer(IntKi) :: errStat2 ! local status of error message - character(ErrMsgLen) :: errMsg2 ! local error message if ErrStat /= ErrID_None - - call dvr_CleanUp(dat%dvr, dat%AD, dat%IW, dat%initialized, errStat2, errMsg2) - CALL SetErrStat(errStat2, errMsg2, dat%errStat, dat%errMsg, 'dvr_End') - - if (dat%errStat >= AbortErrLev) then - call WrScr('') - CALL ProgAbort( 'AeroDyn Driver encountered simulation error level: '& - //TRIM(GetErrStr(dat%errStat)), TrapErrors=.FALSE., TimeWait=3._ReKi ) ! wait 3 seconds (in case they double-clicked and got an error) - else - call NormStop() - end if - end subroutine dvr_End -!................................ -end program AeroDyn_Driver - +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2015-2016 National Renewable Energy Laboratory +! +! This file is part of AeroDyn. +! +! 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. +! +!********************************************************************************************************************************** +program AeroDyn_Driver + use AeroDyn_Driver_Subs, only: dat, Dvr_Init, Dvr_InitCase, Dvr_TimeStep, Dvr_CleanUp, Dvr_EndCase + use AeroDyn_Driver_Subs, only: idAnalysisRegular, idAnalysisTimeD, idAnalysisCombi + use NWTC_IO + use NWTC_Num, only: RunTimes, SimStatus, SimStatus_FirstTime + implicit none + ! Program variables + REAL(ReKi) :: PrevClockTime ! Clock time at start of simulation in seconds [(s)] + REAL(ReKi) :: UsrTime1 ! User CPU time for simulation initialization [(s)] + REAL(ReKi) :: UsrTime2 ! User CPU time for simulation (without intialization) [(s)] + INTEGER(IntKi) , DIMENSION(1:8) :: StrtTime ! Start time of simulation (including intialization) [-] + INTEGER(IntKi) , DIMENSION(1:8) :: SimStrtTime ! Start time of simulation (after initialization) [-] + REAL(DbKi) :: t_global ! global-loop time marker + REAL(DbKi) :: t_final ! global-loop time marker + REAL(DbKi) :: TiLstPrn ! The simulation time of the last print (to file) [(s)] + integer :: nt !< loop counter (for time step) + integer(IntKi) :: iCase ! loop counter (for driver case) + + 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) + UsrTime1 = MAX( 0.0_ReKi, UsrTime1 ) ! CPU_TIME: If a meaningful time cannot be returned, a processor-dependent negative value is returned + + ! ----- + dat%initialized=.false. + call Dvr_Init(dat%dvr, dat%ADI, dat%FED, dat%errStat, dat%errMsg); call CheckError() + + do iCase= 1,dat%dvr%numCases + + ! Initial case + call Dvr_InitCase(iCase, dat%dvr, dat%ADI, dat%FED, dat%errStat, dat%errMsg); call CheckError() + dat%initialized=.true. + + ! Init of time estimator + t_global=0.0_DbKi + t_final=dat%dvr%numSteps*dat%dvr%dt + if (dat%dvr%analysisType/=idAnalysisCombi) then + call SimStatus_FirstTime( TiLstPrn, PrevClockTime, SimStrtTime, UsrTime2, t_global, t_final ) + endif + + ! One time loop + do nt = 1, dat%dvr%numSteps + call Dvr_TimeStep(nt, dat%dvr, dat%ADI, dat%FED, dat%errStat, dat%errMsg); call CheckError() + ! Time update to screen + t_global=nt*dat%dvr%dt + if (dat%dvr%analysisType/=idAnalysisCombi) then + if (mod( nt + 1, 10 )==0) call SimStatus(TiLstPrn, PrevClockTime, t_global, t_final) + endif + end do !nt=1,numSteps + + if (dat%dvr%analysisType/=idAnalysisCombi) then + ! display runtime to screen + call RunTimes(StrtTime, UsrTime1, SimStrtTime, UsrTime2, t_global) + endif + + call Dvr_EndCase(dat%dvr, dat%ADI, dat%initialized, dat%errStat, dat%errMsg); call CheckError() + + enddo ! Loop on cases + + call Dvr_End() +contains +!................................ + subroutine CheckError() + if (dat%ErrStat /= ErrID_None) then + call WrScr(TRIM(dat%errMsg)) + if (dat%errStat >= AbortErrLev) then + call Dvr_End() + end if + end if + end subroutine CheckError +!................................ + subroutine Dvr_End() + integer(IntKi) :: errStat2 ! local status of error message + character(ErrMsgLen) :: errMsg2 ! local error message if ErrStat /= ErrID_None + + call Dvr_CleanUp(dat%dvr, dat%ADI, dat%FED, dat%initialized, errStat2, errMsg2) + CALL SetErrStat(errStat2, errMsg2, dat%errStat, dat%errMsg, 'Dvr_End') + + if (dat%errStat >= AbortErrLev) then + call WrScr('') + CALL ProgAbort( 'AeroDyn Driver encountered simulation error level: '& + //TRIM(GetErrStr(dat%errStat)), TrapErrors=.FALSE., TimeWait=3._ReKi ) ! wait 3 seconds (in case they double-clicked and got an error) + else + call NormStop() + end if + end subroutine Dvr_End +!................................ +end program AeroDyn_Driver + diff --git a/modules/aerodyn/src/AeroDyn_Driver_Registry.txt b/modules/aerodyn/src/AeroDyn_Driver_Registry.txt index 5debd28f0..b216fc47f 100644 --- a/modules/aerodyn/src/AeroDyn_Driver_Registry.txt +++ b/modules/aerodyn/src/AeroDyn_Driver_Registry.txt @@ -12,7 +12,7 @@ # ...... Include files (definitions from NWTC Library) ............................................................................ include Registry_NWTC_Library.txt usefrom AeroDyn_Registry.txt -usefrom InflowWind.txt +usefrom AeroDyn_Inflow_Registry.txt # # ..... Table of combined cases to run ....................................................................................................... typedef AeroDyn_Driver/AD_Dvr Dvr_Case ReKi HWindSpeed - - - "Hub wind speed" "m/s" @@ -28,12 +28,12 @@ typedef ^ ^ ReKi amplitu typedef ^ ^ ReKi frequency - - - "Frequency for sinusoidal motion (when DOF>0)" "-" # ...... Data for VTK surface visualization ............................................................................ -typedef AeroDyn_Driver/AD_Dvr DvrVTK_BLSurfaceType SiKi AirfoilCoords {:}{:}{:} - - "x,y coordinates for airfoil around each blade node on a blade (relative to reference)" - +# typedef AeroDyn_Driver/AD_Dvr DvrVTK_BLSurfaceType SiKi AirfoilCoords {:}{:}{:} - - "x,y coordinates for airfoil around each blade node on a blade (relative to reference)" - typedef ^ DvrVTK_SurfaceType IntKi NumSectors - - - "number of sectors in which to split circles (higher number gives smoother surface)" - typedef ^ DvrVTK_SurfaceType SiKi NacelleBox {3}{8} - - "X-Y-Z locations of 8 points that define the nacelle box, relative to the nacelle position" m typedef ^ DvrVTK_SurfaceType SiKi BaseBox {3}{8} - - "X-Y-Z locations of 8 points that define the base box" m -typedef ^ DvrVTK_SurfaceType SiKi TowerRad {:} - - "radius of each ED tower node" m -typedef ^ DvrVTK_SurfaceType DvrVTK_BLSurfaceType BladeShape {:} - - "AirfoilCoords for each blade" m +# typedef ^ DvrVTK_SurfaceType SiKi TowerRad {:} - - "radius of each ED tower node" m +# typedef ^ DvrVTK_SurfaceType DvrVTK_BLSurfaceType BladeShape {:} - - "AirfoilCoords for each blade" m # ..... Data for driver output file ....................................................................................................... typedef AeroDyn_Driver/AD_Dvr Dvr_Outputs ProgDesc AD_ver - - - "AeroDyn version information" - @@ -45,7 +45,8 @@ typedef ^ ^ character(25) Fmt_a typedef ^ ^ character(1) delim - - - "column delimiter" "-" typedef ^ ^ character(20) outFmt - - - "Format specifier" "-" typedef ^ ^ IntKi fileFmt - - - "Output format 1=Text, 2=Binary, 3=Both" "-" -typedef ^ ^ IntKi wrVTK - - - "0= no vtk, 1=animation" "-" +typedef ^ ^ IntKi wrVTK - - - "0= no vtk, 1=init only, 2=animation" "-" +typedef ^ ^ IntKi WrVTK_Type - - - "Flag for VTK output type (1=surface, 2=line, 3=both)" - typedef ^ ^ character(1024) Root - - - "Output file rootname" "-" typedef ^ ^ character(1024) VTK_OutFileRoot - - - "Output file rootname for vtk" "-" typedef ^ ^ character(ChanLen) WriteOutputHdr {:} - - "Channel headers" "-" @@ -58,30 +59,10 @@ typedef ^ ^ INTEGER n_VTKTi typedef ^ ^ SiKi VTKHubRad - - - "Hub radius for visualization" m typedef ^ ^ ReKi VTKNacDim 6 - - "Nacelle dimensions for visualization" m typedef ^ ^ SiKi VTKRefPoint 3 - - "RefPoint for VTK outputs" +typedef ^ ^ DbKi DT_Outs - - - "Output time resolution" s +typedef ^ ^ IntKi n_DT_Out - - - "Number of time steps between writing a line in the time-marching output files" - -# ..... AeroDyn data ....................................................................................................... -param ^ - INTEGER numInp - 2 - "Determines order of interpolation for input-output extrap (2=linear;3=quadratic)" -typedef ^ AeroDyn_Data AD_ContinuousStateType x - - - "Continuous states" -typedef ^ ^ AD_DiscreteStateType xd - - - "Discrete states" -typedef ^ ^ AD_ConstraintStateType z - - - "Constraint states" -typedef ^ ^ AD_OtherStateType OtherState - - - "Other states" -typedef ^ ^ AD_MiscVarType m - - - "misc/optimization variables" -typedef ^ ^ AD_ParameterType p - - - "Parameters" -typedef ^ ^ AD_InputType u {numInp} - - "Array of system inputs" -typedef ^ ^ AD_OutputType y - - - "System outputs" -typedef ^ ^ DbKi InputTime {numInp} - - "Array of times associated with u array" -# ..... InflowWind data ....................................................................................................... -typedef ^ InflowWind_Data InflowWind_ContinuousStateType x - - - "Continuous states" -typedef ^ ^ InflowWind_DiscreteStateType xd - - - "Discrete states" -typedef ^ ^ InflowWind_ConstraintStateType z - - - "Constraint states" -typedef ^ ^ InflowWind_OtherStateType OtherSt - - - "Other states" -typedef ^ ^ InflowWind_ParameterType p - - - "Parameters" -typedef ^ ^ InflowWind_MiscVarType m - - - "Misc/optimization variables" -typedef ^ ^ InflowWind_InputType u {2} - - "Array of inputs associated with InputTimes" -typedef ^ ^ InflowWind_OutputType y - - - "System outputs" -typedef ^ ^ DbKi InputTimes {2} - - "Array of times associated with Input Array" - -# ..... Blade data ........................................................................................................... +# ..... Blade data for driver................................................................................................. typedef ^ BladeData ReKi pitch - - - "rad" - typedef ^ ^ ReKi pitchSpeed - - - "rad/s" - typedef ^ ^ ReKi pitchAcc - - - "rad/s/s" - @@ -93,11 +74,8 @@ typedef ^ ^ IntKi motionT typedef ^ ^ IntKi iMotion - - - "Stored index to optimize time interpolation" - typedef ^ ^ ReKi motion :: - - "" "-" typedef ^ ^ character(1024) motionFileName - - - "" - -typedef ^ ^ MeshType ptMesh - - - "Point mesh for origin motion" "-" -typedef ^ ^ MeshMapType ED_P_2_AD_P_R - - - "Mesh mapping from blade to AD hub motion" -typedef ^ ^ MeshMapType AD_P_2_AD_L_B - - - "Mesh mapping from AD blade root to AD line mesh" "-" -# ... Hub data .............................................................................................................. +# ... Hub data for driver.................................................................................................... typedef ^ HubData ReKi origin_n 3 - - "" - typedef ^ ^ ReKi orientation_n 3 - - "" - typedef ^ ^ IntKi motionType - - - "" - @@ -107,11 +85,8 @@ typedef ^ ^ ReKi rotSpee typedef ^ ^ ReKi rotAcc - - - "rotor acceleration" "rad/s/s" typedef ^ ^ character(1024) motionFileName - - - "" - typedef ^ ^ ReKi motion :: - - "" "-" -typedef ^ ^ MeshType ptMesh - - - "Point mesh for origin motion" "-" -typedef ^ ^ MeshMapType ED_P_2_AD_P_H - - - "Mesh mapping from hub to AD hub motion" -typedef ^ ^ MeshMapType map2BldPt : - - "Mesh mapping from hub to bld root motion" -# ... Nacelle data .......................................................................................................... +# ... Nacelle data for driver................................................................................................ typedef ^ NacData ReKi origin_t 3 - - "" - typedef ^ ^ IntKi motionType - - - "" - typedef ^ ^ IntKi iMotion - - - "Stored index to optimize time interpolation" - @@ -120,23 +95,17 @@ typedef ^ ^ ReKi yawSpee typedef ^ ^ ReKi yawAcc - - - "yawAcceleration" "rad/s^2" typedef ^ ^ character(1024) motionFileName - - - "" - typedef ^ ^ ReKi motion :: - - "" "-" -typedef ^ ^ MeshType ptMesh - - - "Point mesh for origin motion" "-" -typedef ^ ^ MeshMapType ED_P_2_AD_P_N - - - "Mesh mapping from nacelle to AD nacelle motion" -typedef ^ ^ MeshMapType map2hubPt - - - "Mesh mapping from Nacelle to hub" -# ... Tower data ............................................................................................................ +# ... Tower data for driver ................................................................................................. typedef ^ TwrData ReKi origin_t 3 - - "" - -typedef ^ ^ MeshType ptMesh - - - "Point mesh for origin motion" "-" -typedef ^ ^ MeshType ptMeshAD - - - "Point mesh for origin motion" "-" -typedef ^ ^ MeshMapType ED_P_2_AD_P_T - - - "Mesh mapping from tower base to AD tower base" -typedef ^ ^ MeshMapType AD_P_2_AD_L_T - - - "Mesh mapping from tower base to AD tower line" -# ..... Wind Turbine data ................................................................................................... +# ..... Wind Turbine data for driver ........................................................................................ typedef ^ WTData ReKi originInit 3 - - "" - typedef ^ ^ ReKi orientationInit 3 - - "" - -typedef ^ ^ MeshType ptMesh - - - "Point mesh for origin motion" "-" typedef ^ ^ MeshMapType map2twrPt - - - "Mesh mapping from base to tower" typedef ^ ^ MeshMapType map2nacPt - - - "Mesh mapping from base to nacelle" +typedef ^ ^ MeshMapType map2hubPt - - - "Mesh mapping from Nacelle to hub" +typedef ^ ^ MeshMapType map2BldPt : - - "Mesh mapping from hub to bld root motion" typedef ^ ^ BladeData bld : - - "" - typedef ^ ^ HubData hub - - - "" - typedef ^ ^ NacData nac - - - "" - @@ -144,6 +113,8 @@ typedef ^ ^ TwrData twr typedef ^ ^ IntKi numBlades - - - "" - typedef ^ ^ logical basicHAWTFormat - - - "If true simply input HubRad/Pitch/Overhang/Cone, otherwise all turbine inputs" - typedef ^ ^ logical hasTower - - - "" - +typedef ^ ^ IntKi projMod - - - "If true simply input HubRad/Pitch/Overhang/Cone, otherwise all turbine inputs" - +typedef ^ ^ IntKi BEM_Mod - - - "Switch for different BEM implementations" - typedef ^ ^ logical HAWTprojection - - - "" - typedef ^ ^ IntKi motionType - - - "" - typedef ^ ^ ReKi motion :: - - "" "-" @@ -153,10 +124,11 @@ typedef ^ ^ ReKi amplitu typedef ^ ^ ReKi frequency - - - "" - typedef ^ ^ character(1024) motionFileName - - - "" - typedef ^ ^ ReKi WriteOutput : - - "WriteOutputs of the driver only" +typedef ^ ^ ReKi userSwapArray : - - "Array to store user data for user-defined functions" "-" + # ..... Data for driver simulation ....................................................................................................... typedef ^ Dvr_SimData character(1024) AD_InputFile - - - "Name of AeroDyn input file" - -typedef ^ ^ character(1024) IW_InputFile - - - "Name of InfloWind input file" - typedef ^ ^ IntKi MHK - - - "MHK turbine type (switch) {0: not an MHK turbine, 1: fixed MHK turbine, 2: floating MHK turbine}" "-" typedef ^ ^ IntKi AnalysisType - - - "0=Steady Wind, 1=InflowWind" "-" typedef ^ ^ ReKi FldDens - - - "Density of working fluid" "kg/m^3" @@ -166,12 +138,8 @@ typedef ^ ^ ReKi Patm typedef ^ ^ ReKi Pvap - - - "Vapour pressure of working fluid" "Pa" typedef ^ ^ ReKi WtrDpth - - - "Water depth" "m" typedef ^ ^ ReKi MSL2SWL - - - "Offset between still-water level and mean sea level" "m" -typedef ^ ^ IntKi CompInflow - - - "0=Steady Wind, 1=InflowWind" "-" -typedef ^ ^ ReKi HWindSpeed - - - "RefHeight Wind speed" -typedef ^ ^ ReKi RefHt - - - "RefHeight" -typedef ^ ^ ReKi PLExp - - - "PLExp" typedef ^ ^ IntKi numTurbines - - - "number of blades on turbine" "-" -typedef ^ ^ WTData WT : - - "Wind turbine data" "-" +typedef ^ ^ WTData WT : - - "Wind turbine data for driver" "-" typedef ^ ^ DbKi dT - - - "time increment" "s" typedef ^ ^ DbKi tMax - - - "time increment" "s" typedef ^ ^ IntKi numSteps - - - "number of steps in this case" "-" @@ -182,12 +150,14 @@ typedef ^ ^ ReKi timeSer typedef ^ ^ IntKi iTimeSeries - - - "Stored index to optimize time interpolation" - typedef ^ ^ character(1024) root - - - "Output file rootname" "-" typedef ^ ^ Dvr_Outputs out - - - "data for driver output file" "-" +typedef ^ ^ ADI_IW_InputData IW_InitInp - - - "" - # ..... Data to wrap the driver .......................................................................................................... -typedef ^ AllData Dvr_SimData dvr - - - "" - -typedef ^ ^ AeroDyn_Data AD - - - "" - -typedef ^ ^ InflowWind_Data IW - - - "" - +typedef ^ AllData Dvr_SimData dvr - - - "Driver data" - +typedef ^ ^ ADI_Data ADI - - - "AeroDyn InflowWind Data" - +typedef ^ ^ FED_Data FED - - - "Elastic wind turbine data (Fake ElastoDyn)" "-" typedef ^ ^ IntKi errStat - - - "" - typedef ^ ^ character(ErrMsgLen) errMsg - - - "" - typedef ^ ^ logical initialized - - - "" - + diff --git a/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 b/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 index 1993dbcd6..2af1a7f72 100644 --- a/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 +++ b/modules/aerodyn/src/AeroDyn_Driver_Subs.f90 @@ -19,6 +19,12 @@ ! !********************************************************************************************************************************** module AeroDyn_Driver_Subs + use AeroDyn_Inflow_Types + use AeroDyn_Inflow, only: ADI_Init, ADI_ReInit, ADI_End, ADI_CalcOutput, ADI_UpdateStates + use AeroDyn_Inflow, only: concatOutputHeaders + use AeroDyn_Inflow, only: ADI_ADIW_Solve ! TODO remove me + use AeroDyn_Inflow, only: Init_MeshMap_For_ADI, Set_Inputs_For_ADI + use AeroDyn_IO, only: AD_WrVTK_Surfaces, AD_WrVTK_LinesPoints use AeroDyn_Driver_Types use AeroDyn @@ -39,9 +45,10 @@ module AeroDyn_Driver_Subs integer(IntKi), parameter, dimension(3) :: idBaseMotionVALID = (/idBaseMotionFixed, idBaseMotionSine, idBaseMotionGeneral /) integer(IntKi), parameter :: idHubMotionConstant = 0 - integer(IntKi), parameter :: idHubMotionVariable = 1 - integer(IntKi), parameter :: idHubMotionStateTS = 2 !<<< Used internally, with idAnalysisTimeD - integer(IntKi), parameter, dimension(2) :: idHubMotionVALID = (/idHubMotionConstant, idHubMotionVariable/) + integer(IntKi), parameter :: idHubMotionVariable = 1 ! Input file with prescribed motion + integer(IntKi), parameter :: idHubMotionUserFunction = 3 ! User-defined function + integer(IntKi), parameter :: idHubMotionStateTS = 200 !<<< Used internally, with idAnalysisTimeD + integer(IntKi), parameter, dimension(3) :: idHubMotionVALID = (/idHubMotionConstant, idHubMotionVariable, idHubMotionUserFunction/) integer(IntKi), parameter :: idBldMotionConstant = 0 integer(IntKi), parameter :: idBldMotionVariable = 1 @@ -62,25 +69,41 @@ module AeroDyn_Driver_Subs integer(IntKi), parameter :: idAnalysisCombi = 3 integer(IntKi), parameter, dimension(3) :: idAnalysisVALID = (/idAnalysisRegular, idAnalysisTimeD, idAnalysisCombi/) - real(ReKi), parameter :: myNaN = -99.9_ReKi + ! User Swap Array - TODO not clean + integer(IntKi), parameter :: iAzi = 1 !< index in swap array for azimuth + integer(IntKi), parameter :: iN_ = 4 !< index in swap array for time step + integer(IntKi), parameter :: igenTorque = 5 !< index in swap array for generator torque + integer(IntKi), parameter :: igenTorqueF = 6 !< index in swap array for filtered generator torque + integer(IntKi), parameter :: irotTorque = 7 !< index in swap array for rotor torque + integer(IntKi), parameter :: irotTorqueF = 8 !< index in swap array for filtered rotor torque + integer(IntKi), parameter :: iDeltaTorque = 9 !< index in swap array for delta torque + integer(IntKi), parameter :: iDeltaTorqueF = 10 !< index in swap array for delta torque + integer(IntKi), parameter :: irotSpeedI = 11 !< index in swap array for instantaneous rotor speed + integer(IntKi), parameter :: irotSpeedF = 12 !< index in swap array for filtered rotor speed + integer(IntKi), parameter :: iAlpha = 13 !< index in swap array for filter constant alpha + integer(IntKi), parameter :: iRegion = 14 !< Controller region + + integer(IntKi), parameter :: NumInp = 2 + contains !---------------------------------------------------------------------------------------------------------------------------------- !> -subroutine Dvr_Init(dvr, AD, IW, errStat,errMsg ) - type(Dvr_SimData), intent( out) :: dvr ! driver data - type(AeroDyn_Data), intent( out) :: AD ! AeroDyn data - type(InflowWind_Data), intent( out) :: IW ! AeroDyn data - integer(IntKi) , intent( out) :: errStat ! Status of error message - character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None +subroutine Dvr_Init(dvr, ADI, FED, errStat, errMsg ) + type(Dvr_SimData), intent( out) :: dvr !< driver data + type(ADI_Data), intent( out) :: ADI !< AeroDyn/InflowWind data + type(FED_Data), intent( out) :: FED !< Elastic wind turbine data (Fake ElastoDyn) + integer(IntKi) , intent( out) :: errStat !< Status of error message + character(*) , intent( out) :: errMsg !< Error message if errStat /= ErrID_None ! local variables integer(IntKi) :: errStat2 ! local status of error message - character(ErrMsgLen) :: errMsg2 ! local error message if ErrStat /= ErrID_None - CHARACTER(1000) :: inputFile ! String to hold the file name. - CHARACTER(200) :: git_commit ! String containing the current git commit hash - CHARACTER(20) :: FlagArg ! flag argument from command line + character(ErrMsgLen) :: errMsg2 ! local error message if errStat /= ErrID_None + character(1000) :: inputFile ! String to hold the file name. + character(200) :: git_commit ! String containing the current git commit hash + character(20) :: FlagArg ! flag argument from command line + integer :: iWT ! Index on wind turbines/rotors errStat = ErrID_None errMsg = "" @@ -98,6 +121,14 @@ subroutine Dvr_Init(dvr, AD, IW, errStat,errMsg ) ! Read the AeroDyn driver input file call Dvr_ReadInputFile(inputFile, dvr, errStat2, errMsg2 ); if(Failed()) return + ! --- Propagate to FED + allocate(FED%WT(dvr%numTurbines), stat=errStat2); errMsg2='Allocating FED%WT'; if(Failed()) return + do iWT=1,dvr%numTurbines + FED%WT(iWT)%hasTower = dvr%WT(iWT)%hasTower + FED%WT(iWT)%numBlades = dvr%WT(iWT)%numBlades + FED%WT(iWT)%rigidBlades = .True. ! Driver only uses rigid blades + enddo + contains logical function Failed() @@ -109,18 +140,17 @@ end subroutine Dvr_Init !---------------------------------------------------------------------------------------------------------------------------------- !> -subroutine Dvr_InitCase(iCase, dvr, AD, IW, errStat, errMsg ) +subroutine Dvr_InitCase(iCase, dvr, ADI, FED, errStat, errMsg ) integer(IntKi) , intent(in ) :: iCase - type(Dvr_SimData), intent(inout) :: dvr ! driver data - type(AeroDyn_Data), intent(inout) :: AD ! AeroDyn data - type(InflowWind_Data), intent(inout) :: IW ! InflowWind data + type(Dvr_SimData), intent(inout) :: dvr !< driver data + type(ADI_Data), intent(inout) :: ADI !< AeroDyn/InflowWind data + type(FED_Data), intent(inout) :: FED !< Elastic wind turbine data (Fake ElastoDyn) integer(IntKi) , intent( out) :: errStat ! Status of error message - character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + character(*) , intent( out) :: errMsg ! Error message if errStat /= ErrID_None ! local variables integer(IntKi) :: errStat2 ! local status of error message - character(ErrMsgLen) :: errMsg2 ! local error message if ErrStat /= ErrID_None + character(ErrMsgLen) :: errMsg2 ! local error message if errStat /= ErrID_None integer(IntKi) :: iWT, j !< - type(AD_InitOutputType) :: InitOutData_AD ! Output data from initialization errStat = ErrID_None errMsg = "" @@ -148,8 +178,10 @@ subroutine Dvr_InitCase(iCase, dvr, AD, IW, errStat, errMsg ) dvr%tMax = dvr%Cases(iCase)%tMax ! Set wind for this case - dvr%HWindSpeed = dvr%Cases(iCase)%HWindSpeed - dvr%PLexp = dvr%Cases(iCase)%PLExp + dvr%IW_InitInp%HWindSpeed = dvr%Cases(iCase)%HWindSpeed + dvr%IW_InitInp%PLexp = dvr%Cases(iCase)%PLExp + ADI%m%IW%HWindSpeed = dvr%Cases(iCase)%HWindSpeed ! We need to do it again since InFlow Wind is initialized only for iCase==1 + ADI%m%IW%PLexp = dvr%Cases(iCase)%PLExp ! Set motion for this case call setSimpleMotion(dvr%WT(1), dvr%Cases(iCase)%rotSpeed, dvr%Cases(iCase)%bldPitch, dvr%Cases(iCase)%nacYaw, dvr%Cases(iCase)%DOF, dvr%Cases(iCase)%amplitude, dvr%Cases(iCase)%frequency) @@ -163,7 +195,7 @@ subroutine Dvr_InitCase(iCase, dvr, AD, IW, errStat, errMsg ) else ! Should never happen endif - dvr%numSteps = ceiling(dvr%tMax/dvr%dt) + dvr%numSteps = ceiling(dvr%tMax/dvr%dt) ! TODO I believe we need a plus one here ! Validate the inputs call ValidateInputs(dvr, errStat2, errMsg2) ; if(Failed()) return @@ -174,138 +206,140 @@ subroutine Dvr_InitCase(iCase, dvr, AD, IW, errStat, errMsg ) ! --- Initialize meshes if (iCase==1) then - call Init_Meshes(dvr, errStat2, errMsg2); if(Failed()) return + call Init_Meshes(dvr, FED, errStat2, errMsg2); if(Failed()) return endif ! --- Initialize driver-only outputs if (allocated(dvr%out%storage)) deallocate(dvr%out%storage) if (iCase==1) then ! Initialize driver output channels, they are constant for all cases and all turbines! - call Dvr_InitializeDriverOutputs(dvr, errStat2, errMsg2); if(Failed()) return + call Dvr_InitializeDriverOutputs(dvr, ADI, errStat2, errMsg2); if(Failed()) return allocate(dvr%out%unOutFile(dvr%numTurbines)) endif dvr%out%unOutFile = -1 - ! --- Initialize aerodyn - call Init_AeroDyn(iCase, dvr, AD, dvr%dt, InitOutData_AD, errStat2, errMsg2); if(Failed()) return - - ! --- Initialize Inflow Wind - if (iCase==1) then - call Init_InflowWind(dvr, IW, AD%u(1), AD%OtherState, dvr%dt, errStat2, errMsg2); if(Failed()) return - endif + ! --- Initialize ADI + call Init_ADI_ForDriver(iCase, ADI, dvr, FED, dvr%dt, errStat2, errMsg2); if(Failed()) return ! --- Initialize meshes if (iCase==1) then - call Init_ADMeshMap(dvr, AD%u(1), errStat2, errMsg2); if(Failed()) return + call Init_MeshMap_For_ADI(FED, ADI%p, ADI%u(1)%AD, errStat2, errMsg2); if(Failed()) return endif ! Copy AD input here because tower is modified in ADMeshMap do j = 2, numInp - call AD_CopyInput (AD%u(1), AD%u(j), MESH_NEWCOPY, errStat2, errMsg2); if(Failed()) return + call AD_CopyInput (ADI%u(1)%AD, ADI%u(j)%AD, MESH_NEWCOPY, errStat2, errMsg2); if(Failed()) return end do - ! Compute driver outputs at t=0 - call Set_Mesh_Motion(0,dvr,errStat2,errMsg2); if(Failed()) return + call Set_Mesh_Motion(0, dvr, ADI, FED, errStat2, errMsg2); if(Failed()) return - ! --- Initial AD inputs - AD%inputTime = -999 + ! --- Initialze AD inputs DO j = 1-numInp, 0 - call Set_AD_Inputs(j,dvr,AD,IW,errStat2,errMsg2); if(Failed()) return + call Shift_ADI_Inputs(j,dvr, ADI, errStat2, errMsg2); if(Failed()) return + call Set_Inputs_For_ADI(ADI%u(1), FED, errStat2, errMsg2); if(Failed()) return + call ADI_ADIW_Solve(ADI%inputTimes(1), ADI%p, ADI%u(1)%AD, ADI%OtherState(1)%AD, ADI%m%IW%u, ADI%m%IW, .true., errStat2, errMsg2); if(Failed()) return ! TODO TODO TODO remove me END DO + ! --- AeroDyn + Inflow at T=0 + call ADI_CalcOutput(ADI%inputTimes(1), ADI%u(1), ADI%p, ADI%x(1), ADI%xd(1), ADI%z(1), ADI%OtherState(1), ADI%y, ADI%m, errStat2, errMsg2); if(Failed()) return ! --- Initialize outputs call Dvr_InitializeOutputs(dvr%numTurbines, dvr%out, dvr%numSteps, errStat2, errMsg2); if(Failed()) return - call Dvr_CalcOutputDriver(dvr, IW%y, errStat2, errMsg2); if(Failed()) return + call Dvr_CalcOutputDriver(dvr, ADI%y, FED, errStat2, errMsg2); if(Failed()) return ! --- Initialize VTK if (dvr%out%WrVTK>0) then dvr%out%n_VTKTime = 1 dvr%out%VTKRefPoint = (/0.0_SiKi, 0.0_SiKi, 0.0_SiKi /) - call SetVTKParameters(dvr%out, dvr, InitOutData_AD, AD, errStat2, errMsg2); if(Failed()) return + call SetVTKParameters(dvr%out, dvr, ADI, errStat2, errMsg2); if(Failed()) return endif call cleanUp() contains subroutine cleanUp() - call AD_DestroyInitOutput(InitOutData_AD, errStat2, errMsg2) end subroutine cleanUp logical function Failed() - CALL SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Dvr_InitCase') + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Dvr_InitCase') Failed = errStat >= AbortErrLev if(Failed) call cleanUp() end function Failed end subroutine Dvr_InitCase - - - +!---------------------------------------------------------------------------------------------------------------------------------- !> Perform one time step -subroutine Dvr_TimeStep(nt, dvr, AD, IW, errStat, errMsg) - integer(IntKi) , intent(in ) :: nt ! time step +subroutine Dvr_TimeStep(nt, dvr, ADI, FED, errStat, errMsg) + integer(IntKi) , intent(in ) :: nt ! next time step (current time is nt-1) type(Dvr_SimData), intent(inout) :: dvr ! driver data - type(AeroDyn_Data), intent(inout) :: AD ! AeroDyn data - type(InflowWind_Data), intent(inout) :: IW ! AeroDyn data + type(ADI_Data), intent(inout) :: ADI ! Input data for initialization (intent out for getting AD WriteOutput names/units) + type(FED_Data), intent(inout) :: FED ! Elastic wind turbine data (Fake ElastoDyn) integer(IntKi) , intent( out) :: errStat ! Status of error message - character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + character(*) , intent( out) :: errMsg ! Error message if errStat /= ErrID_None ! local variables integer(IntKi) :: errStat2 ! local status of error message - character(ErrMsgLen) :: errMsg2 ! local error message if ErrStat /= ErrID_None + character(ErrMsgLen) :: errMsg2 ! local error message if errStat /= ErrID_None real(DbKi) :: time !< Variable for storing time, in seconds errStat = ErrID_None errMsg = '' - ! Update motion of meshes - call Set_Mesh_Motion(nt,dvr,errStat,errMsg) + ! Update motion of meshes for nt + call Set_Mesh_Motion(nt, dvr, ADI, FED, errStat,errMsg) ! Set AD inputs for nt (and keep values at nt-1 as well) - ! u(1) is at nt, u(2) is at nt-1 - call Set_AD_Inputs(nt,dvr,AD,IW,errStat2,errMsg2); if(Failed()) return - time = AD%inputTime(2) + ! u(1) is at nt, u(2) is at nt-1. Set inputs for nt timestep + call Shift_ADI_Inputs(nt,dvr, ADI, errStat2, errMsg2); if(Failed()) return + call Set_Inputs_For_ADI(ADI%u(1), FED, errStat2, errMsg2); if(Failed()) return + call ADI_ADIW_Solve(ADI%inputTimes(1), ADI%p, ADI%u(1)%AD, ADI%OtherState(1)%AD, ADI%m%IW%u, ADI%m%IW, .true., errStat, errMsg) + + time = ADI%inputTimes(2) - ! Calculate outputs at nt - 1 - call AD_CalcOutput( time, AD%u(2), AD%p, AD%x, AD%xd, AD%z, AD%OtherState, AD%y, AD%m, errStat2, errMsg2 ); if(Failed()) return + ! Calculate outputs at nt - 1 (current time) + call ADI_CalcOutput(time, ADI%u(2), ADI%p, ADI%x(1), ADI%xd(1), ADI%z(1), ADI%OtherState(1), ADI%y, ADI%m, errStat2, errMsg2 ); if(Failed()) return ! Write outputs for all turbines at nt-1 - call Dvr_WriteOutputs(nt, time, dvr, dvr%out, AD%y, IW%y, errStat2, errMsg2); if(Failed()) return + call Dvr_WriteOutputs(nt, time, dvr, dvr%out, ADI%y, errStat2, errMsg2); if(Failed()) return ! We store the "driver-level" outputs only now, above, the old outputs are used - call Dvr_CalcOutputDriver(dvr, IW%y, errStat, errMsg) + call Dvr_CalcOutputDriver(dvr, ADI%y, FED, errStat, errMsg) ! VTK outputs - if (dvr%out%WrVTK==1 .and. nt==1) then + if ((dvr%out%WrVTK>=1 .and. nt==1) .or. (dvr%out%WrVTK==2)) then ! Init only - call WrVTK_Surfaces(time, dvr, dvr%out, nt-1, AD) - else if (dvr%out%WrVTK==2) then - ! Animation - call WrVTK_Surfaces(time, dvr, dvr%out, nt-1, AD) + select case (dvr%out%WrVTK_Type) + case (1) ! surfaces + call WrVTK_Surfaces(time, ADI, FED, dvr%out, nt-1) + case (2) ! lines + call WrVTK_Lines( time, ADI, FED, dvr%out, nt-1) + case (3) ! both + call WrVTK_Surfaces(time, ADI, FED, dvr%out, nt-1) + call WrVTK_Lines( time, ADI, FED, dvr%out, nt-1) + end select endif ! Get state variables at next step: INPUT at step nt - 1, OUTPUT at step nt - call AD_UpdateStates( time, nt-1, AD%u, AD%inputTime, AD%p, AD%x, AD%xd, AD%z, AD%OtherState, AD%m, errStat2, errMsg2); if(Failed()) return + call ADI_UpdateStates( time, nt-1, ADI%u(:), ADI%inputTimes, ADI%p, ADI%x(1), ADI%xd(1), ADI%z(1), ADI%OtherState(1), ADI%m, errStat2, errMsg2); if(Failed()) return contains logical function Failed() - CALL SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Dvr_TimeStep') + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Dvr_TimeStep') Failed = errStat >= AbortErrLev end function Failed end subroutine Dvr_TimeStep -subroutine Dvr_EndCase(dvr, AD, IW, initialized, errStat, errMsg) +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine Dvr_EndCase(dvr, ADI, initialized, errStat, errMsg) type(Dvr_SimData), intent(inout) :: dvr ! driver data - type(AeroDyn_Data), intent(inout) :: AD ! AeroDyn data - type(InflowWind_Data), intent(inout) :: IW ! AeroDyn data + type(ADI_Data), intent(inout) :: ADI ! Input data for initialization (intent out for getting AD WriteOutput names/units) logical, intent(inout) :: initialized ! integer(IntKi) , intent( out) :: errStat ! Status of error message - character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + character(*) , intent( out) :: errMsg ! Error message if errStat /= ErrID_None ! local variables - character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None + character(ErrMsgLen) :: errMsg2 ! temporary Error message if errStat /= ErrID_None integer(IntKi) :: errStat2 ! temporary Error status of the operation integer(IntKi) :: iWT character(*), parameter :: RoutineName = 'Dvr_EndCase' @@ -336,16 +370,17 @@ subroutine Dvr_EndCase(dvr, AD, IW, initialized, errStat, errMsg) end subroutine Dvr_EndCase +!---------------------------------------------------------------------------------------------------------------------------------- !> End current case if not already closed, and destroy data -subroutine Dvr_CleanUp(dvr, AD, IW, initialized, errStat, errMsg) - type(Dvr_SimData), intent(inout) :: dvr ! driver data - type(AeroDyn_Data), intent(inout) :: AD ! AeroDyn data - type(InflowWind_Data), intent(inout) :: IW ! AeroDyn data +subroutine Dvr_CleanUp(dvr, ADI, FED, initialized, errStat, errMsg) + type(Dvr_SimData), intent(inout) :: dvr !< driver data + type(ADI_Data), intent(inout) :: ADI !< AeroDyn/InflowWind data + type(FED_Data), intent(inout) :: FED !< Elastic wind turbine data (Fake ElastoDyn) logical, intent(inout) :: initialized ! integer(IntKi) , intent( out) :: errStat ! Status of error message - character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + character(*) , intent( out) :: errMsg ! Error message if errStat /= ErrID_None ! local variables - character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None + character(ErrMsgLen) :: errMsg2 ! temporary Error message if errStat /= ErrID_None integer(IntKi) :: errStat2 ! temporary Error status of the operation integer(IntKi) :: iWT character(*), parameter :: RoutineName = 'Dvr_CleanUp' @@ -353,258 +388,179 @@ subroutine Dvr_CleanUp(dvr, AD, IW, initialized, errStat, errMsg) errStat = ErrID_None errMsg = '' - call Dvr_EndCase(dvr, AD, IW, initialized, errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) + call Dvr_EndCase(dvr, ADI, initialized, errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) ! End modules - call AD_End( AD%u(1), AD%p, AD%x, AD%xd, AD%z, AD%OtherState, AD%y, AD%m, errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) - call InflowWind_End( IW%u(1), IW%p, IW%x, IW%xd, IW%z, IW%OtherSt, IW%y, IW%m, errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) - - call AD_Dvr_DestroyAeroDyn_Data (AD , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) - call AD_Dvr_DestroyInflowWind_Data(IW , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) + call ADI_End( ADI%u(:), ADI%p, ADI%x(1), ADI%xd(1), ADI%z(1), ADI%OtherState(1), ADI%y, ADI%m, errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName); call AD_Dvr_DestroyDvr_SimData (dvr , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) -end subroutine Dvr_CleanUp + call ADI_DestroyFED_Data (FED , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) +end subroutine Dvr_CleanUp !---------------------------------------------------------------------------------------------------------------------------------- -!> Initialize aerodyn module based on driver data -subroutine Init_AeroDyn(iCase, dvr, AD, dt, InitOutData, errStat, errMsg) +subroutine Init_ADI_ForDriver(iCase, ADI, dvr, FED, dt, errStat, errMsg) integer(IntKi) , intent(in ) :: iCase - type(Dvr_SimData), target, intent(inout) :: dvr ! Input data for initialization (intent out for getting AD WriteOutput names/units) - type(AeroDyn_Data), intent(inout) :: AD ! AeroDyn data + type(ADI_Data), intent(inout) :: ADI ! Input data for initialization (intent out for getting AD WriteOutput names/units) + type(Dvr_SimData), target, intent(inout) :: dvr ! Input data for initialization (intent out for getting AD WriteOutput names/units) + type(FED_Data), target, intent(inout) :: FED ! Elastic wind turbine data (Fake ElastoDyn) real(DbKi), intent(inout) :: dt ! interval - type(AD_InitOutputType), intent( out) :: InitOutData ! Output data for initialization - integer(IntKi) , intent( out) :: errStat ! Status of error message - character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + integer(IntKi) , intent(out) :: errStat ! Status of error message + character(*) , intent(out) :: errMsg ! Error message if errStat /= ErrID_None ! locals - real(reKi) :: theta(3) - integer(IntKi) :: j, k - integer(IntKi) :: iWT - integer(IntKi) :: errStat2 ! local status of error message - character(ErrMsgLen) :: errMsg2 ! local error message if ErrStat /= ErrID_None - type(AD_InitInputType) :: InitInData ! Input data for initialization - type(WTData), pointer :: wt ! Alias to shorten notation - logical :: needInit + real(reKi) :: theta(3) + integer(IntKi) :: j, k + integer(IntKi) :: iWT + integer(IntKi) :: errStat2 ! local status of error message + character(ErrMsgLen) :: errMsg2 ! local error message if errStat /= ErrID_None + type(WTData), pointer :: wt ! Alias to shorten notation + type(RotFED), pointer :: y_ED ! Alias to shorten notation + logical :: needInit + type(ADI_InitInputType) :: InitInp !< Input data for initialization routine (inout so we can use MOVE_ALLOC) + type(ADI_InitOutputType) :: InitOut !< Output for initialization routine errStat = ErrID_None errMsg = '' + ! allocate AeroDyn data storage if not done alread + if (.not. allocated(ADI%u )) then; allocate(ADI%u(2), STAT=errStat2); if (Failed0("ADI input" )) return; endif ! set to size two for linear + if (.not. allocated(ADI%x )) then; allocate(ADI%x(1), STAT=errStat2); if (Failed0("x" )) return; endif + if (.not. allocated(ADI%xd )) then; allocate(ADI%xd(1), STAT=errStat2); if (Failed0("xd" )) return; endif + if (.not. allocated(ADI%z )) then; allocate(ADI%z(1), STAT=errStat2); if (Failed0("z" )) return; endif + if (.not. allocated(ADI%OtherState)) then; allocate(ADI%OtherState(1), STAT=errStat2); if (Failed0("OtherState")) return; endif + if (.not. allocated(ADI%inputTimes)) then + call AllocAry( ADI%inputTimes, 2, "InputTimes", ErrStat2, ErrMsg2 ) + if (Failed()) return + ADI%inputTimes = -999 ! TODO use something better? + endif + + needInit=.False. if (iCase==1) then needInit=.True. else - ! UA does not like changes of dt - if ( .not. EqualRealNos(AD%p%DT, dt) ) then + ! UA does not like changes of dt between cases + if ( .not. EqualRealNos(ADI%p%AD%DT, dt) ) then call WrScr('Info: dt is changing between cases, AeroDyn will be re-initialized') - call AD_End( AD%u(1), AD%p, AD%x, AD%xd, AD%z, AD%OtherState, AD%y, AD%m, errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Init_AeroDyn'); if(Failed()) return + call ADI_End( ADI%u(1:1), ADI%p, ADI%x(1), ADI%xd(1), ADI%z(1), ADI%OtherState(1), ADI%y, ADI%m, errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Init_ADI_ForDriver'); if(Failed()) return !call AD_Dvr_DestroyAeroDyn_Data (AD , errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) needInit=.true. endif + if (ADI%p%AD%WakeMod == WakeMod_FVW) then + call WrScr('[INFO] OLAF is used, AeroDyn will be re-initialized') + needInit=.true. + endif + if (needInit) then + call ADI_End( ADI%u(1:1), ADI%p, ADI%x(1), ADI%xd(1), ADI%z(1), ADI%OtherState(1), ADI%y, ADI%m, errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Init_ADI_ForDriver'); if(Failed()) return + endif endif if (needInit) then - ! --- Set init data - allocate(InitInData%rotors(dvr%numTurbines), stat=errStat) + ! ADI + InitInp%storeHHVel = .true. + InitInp%WrVTK = dvr%out%WrVTK + InitInp%WrVTK_Type = dvr%out%WrVTK_Type + ! Inflow Wind + InitInp%IW_InitInp%InputFile = dvr%IW_InitInp%InputFile + InitInp%IW_InitInp%CompInflow = dvr%IW_InitInp%CompInflow + InitInp%IW_InitInp%HWindSpeed = dvr%IW_InitInp%HWindSpeed + InitInp%IW_InitInp%RefHt = dvr%IW_InitInp%RefHt + InitInp%IW_InitInp%PLExp = dvr%IW_InitInp%PLExp + InitInp%IW_InitInp%UseInputFile = .true. ! read input file instead of passed file data + InitInp%IW_InitInp%MHK = dvr%MHK + ! AeroDyn + InitInp%AD%Gravity = 9.80665_ReKi + InitInp%AD%RootName = dvr%out%Root ! 'C:/Work/XFlow/' + InitInp%AD%InputFile = dvr%AD_InputFile + InitInp%AD%MHK = dvr%MHK + InitInp%AD%defFldDens = dvr%FldDens + InitInp%AD%defKinVisc = dvr%KinVisc + InitInp%AD%defSpdSound = dvr%SpdSound + InitInp%AD%defPatm = dvr%Patm + InitInp%AD%defPvap = dvr%Pvap + InitInp%AD%WtrDpth = dvr%WtrDpth + InitInp%AD%MSL2SWL = dvr%MSL2SWL + ! Init data per rotor + allocate(InitInp%AD%rotors(dvr%numTurbines), stat=errStat) if (errStat/=0) then - call SetErrStat( ErrID_Fatal, 'Allocating rotors', errStat, errMsg, 'Init_AeroDyn' ) + call SetErrStat( ErrID_Fatal, 'Allocating rotors', errStat, errMsg, 'Init_ADI_ForDriver' ) call Cleanup() return end if - InitInData%InputFile = dvr%AD_InputFile - InitInData%RootName = dvr%out%Root - InitInData%Gravity = 9.80665_ReKi - InitInData%MHK = dvr%MHK - InitInData%defFldDens = dvr%FldDens - InitInData%defKinVisc = dvr%KinVisc - InitInData%defSpdSound = dvr%SpdSound - InitInData%defPatm = dvr%Patm - InitInData%defPvap = dvr%Pvap - InitInData%WtrDpth = dvr%WtrDpth - InitInData%MSL2SWL = dvr%MSL2SWL - ! Init data per rotor + ! --- TODO Make this block independent of driver do iWT=1,dvr%numTurbines wt => dvr%WT(iWT) - InitInData%rotors(iWT)%numBlades = wt%numBlades - call AllocAry(InitInData%rotors(iWT)%BladeRootPosition, 3, wt%numBlades, 'BladeRootPosition', errStat2, ErrMsg2 ); if (Failed()) return - call AllocAry(InitInData%rotors(iWT)%BladeRootOrientation, 3, 3, wt%numBlades, 'BladeRootOrientation', errStat2, ErrMsg2 ); if (Failed()) return - if (wt%HAWTprojection) then - InitInData%rotors(iWT)%AeroProjMod = 0 ! default, with WithoutSweepPitchTwist + y_ED => FED%WT(iWT) + InitInp%AD%rotors(iWT)%numBlades = wt%numBlades + call AllocAry(InitInp%AD%rotors(iWT)%BladeRootPosition, 3, wt%numBlades, 'BladeRootPosition', errStat2, errMsg2 ); if (Failed()) return + call AllocAry(InitInp%AD%rotors(iWT)%BladeRootOrientation, 3, 3, wt%numBlades, 'BladeRootOrientation', errStat2, errMsg2 ); if (Failed()) return + if (wt%projMod==-1)then + !call WrScr('>>> Using HAWTprojection to determine projMod') + if (wt%HAWTprojection) then + InitInp%AD%rotors(iWT)%AeroProjMod = APM_BEM_NoSweepPitchTwist ! default, with WithoutSweepPitchTwist + else + InitInp%AD%rotors(iWT)%AeroProjMod = APM_LiftingLine + endif else - InitInData%rotors(iWT)%AeroProjMod = 1 + InitInp%AD%rotors(iWT)%AeroProjMod = wt%projMod endif - InitInData%rotors(iWT)%HubPosition = wt%hub%ptMesh%Position(:,1) - InitInData%rotors(iWT)%HubOrientation = wt%hub%ptMesh%RefOrientation(:,:,1) - InitInData%rotors(iWT)%NacellePosition = wt%nac%ptMesh%Position(:,1) - InitInData%rotors(iWT)%NacelleOrientation = wt%nac%ptMesh%RefOrientation(:,:,1) + InitInp%AD%rotors(iWT)%AeroBEM_Mod = wt%BEM_Mod + !call WrScr(' Driver: projMod: '//trim(num2lstr(InitInp%AD%rotors(iWT)%AeroProjMod))//', BEM_Mod:'//trim(num2lstr(InitInp%AD%rotors(iWT)%AeroBEM_Mod))) + InitInp%AD%rotors(iWT)%HubPosition = y_ED%HubPtMotion%Position(:,1) + InitInp%AD%rotors(iWT)%HubOrientation = y_ED%HubPtMotion%RefOrientation(:,:,1) + InitInp%AD%rotors(iWT)%NacellePosition = y_ED%NacelleMotion%Position(:,1) + InitInp%AD%rotors(iWT)%NacelleOrientation = y_ED%NacelleMotion%RefOrientation(:,:,1) do k=1,wt%numBlades - InitInData%rotors(iWT)%BladeRootOrientation(:,:,k) = wt%bld(k)%ptMesh%RefOrientation(:,:,1) - InitInData%rotors(iWT)%BladeRootPosition(:,k) = wt%bld(k)%ptMesh%Position(:,1) + InitInp%AD%rotors(iWT)%BladeRootOrientation(:,:,k) = y_ED%BladeRootMotion(k)%RefOrientation(:,:,1) + InitInp%AD%rotors(iWT)%BladeRootPosition(:,k) = y_ED%BladeRootMotion(k)%Position(:,1) end do enddo - ! --- Call AD_init - call AD_Init(InitInData, AD%u(1), AD%p, AD%x, AD%xd, AD%z, AD%OtherState, AD%y, AD%m, dt, InitOutData, ErrStat2, ErrMsg2 ); if (Failed()) return + call ADI_Init(InitInp, ADI%u(1), ADI%p, ADI%x(1), ADI%xd(1), ADI%z(1), ADI%OtherState(1), ADI%y, ADI%m, dt, InitOut, errStat, errMsg) + + ! Set output headers if (iCase==1) then - ! Add writeoutput units and headers to driver, same for all cases and rotors! - call concatOutputHeaders(dvr, InitOutData%rotors(1)%WriteOutputHdr, InitOutData%rotors(1)%WriteOutputUnt, errStat2, errMsg2); if(Failed()) return + call concatOutputHeaders(dvr%out%WriteOutputHdr, dvr%out%WriteOutputUnt, InitOut%WriteOutputHdr, InitOut%WriteOutputUnt, errStat2, errMsg2); if(Failed()) return endif - - dvr%out%AD_ver = InitOutData%ver - else ! --- Reinit - call AD_ReInit(AD%p, AD%x, AD%xd, AD%z, AD%OtherState, AD%m, dt, errStat2, errMsg2); if(Failed()) return + ! TODO change rootname, but that's a parameter.. + call ADI_ReInit(ADI%p, ADI%x(1), ADI%xd(1), ADI%z(1), ADI%OtherState(1), ADI%m, dt, errStat2, errMsg2); if(Failed()) return endif + call cleanup() contains subroutine cleanup() - call AD_DestroyInitInput (InitInData, errStat2, errMsg2) + call ADI_DestroyInitInput (InitInp, errStat2, errMsg2) + call ADI_DestroyInitOutput(InitOut, errStat2, errMsg2) end subroutine cleanup logical function Failed() - CALL SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Init_AeroDyn') + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Init_ADI_ForDriver') Failed = errStat >= AbortErrLev - if (Failed) then - call cleanup() - endif + if (Failed) call cleanup() end function Failed -end subroutine Init_AeroDyn - - -!---------------------------------------------------------------------------------------------------------------------------------- -!> -subroutine Init_InflowWind(dvr, IW, u_AD, o_AD, dt, errStat, errMsg) - use InflowWind, only: InflowWind_Init - type(Dvr_SimData), target, intent(inout) :: dvr ! Input data for initialization (intent out for getting AD WriteOutput names/units) - type(InflowWind_Data), intent(inout) :: IW ! AeroDyn data - type(AD_InputType), intent(in ) :: u_AD ! AeroDyn data - type(AD_OtherStateType), intent(in ) :: o_AD ! AeroDyn data - real(DbKi), intent(inout) :: dt ! interval - integer(IntKi) , intent( out) :: errStat ! Status of error message - character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - ! locals - real(reKi) :: theta(3) - integer(IntKi) :: j, k, nOut_AD, nOut_IW, nOut_Dvr - integer(IntKi) :: iWT - integer(IntKi) :: errStat2 ! local status of error message - character(ErrMsgLen) :: errMsg2 ! local error message if ErrStat /= ErrID_None - type(InflowWind_InitInputType) :: InitInData ! Input data for initialization - type(InflowWind_InitOutputType) :: InitOutData ! Output data from initialization - type(WTData), pointer :: wt ! Alias to shorten notation - !character(ChanLen), allocatable :: WriteOutputHdr(:) - !character(ChanLen), allocatable :: WriteOutputUnt(:) - errStat = ErrID_None - errMsg = '' - - ! --- Count number of points (see FAST_Subs, before InflowWind_Init) - InitInData%NumWindPoints = 0 - ! Hub windspeed for each turbine - InitInData%NumWindPoints = InitInData%NumWindPoints + dvr%numTurbines - do iWT=1,dvr%numTurbines - wt => dvr%wt(iWT) - ! Blade - do k=1,wt%numBlades - InitInData%NumWindPoints = InitInData%NumWindPoints + u_AD%rotors(iWT)%BladeMotion(k)%NNodes - end do - ! Tower - InitInData%NumWindPoints = InitInData%NumWindPoints + u_AD%rotors(iWT)%TowerMotion%NNodes - ! Nacelle - if (u_AD%rotors(1)%NacelleMotion%Committed) then - InitInData%NumWindPoints = InitInData%NumWindPoints + u_AD%rotors(iWT)%NacelleMotion%NNodes ! 1 point + ! check for failed where /= 0 is fatal + logical function Failed0(txt) + character(*), intent(in) :: txt + if (errStat /= 0) then + ErrStat2 = ErrID_Fatal + ErrMsg2 = "Could not allocate "//trim(txt) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Dvr_InitCase') endif - ! Hub Motion - !InitInData%NumWindPoints = InitInData%NumWindPoints + u_AD%rotors(iWT)%HubPtMotion%NNodes ! 1 point - enddo - if (allocated(o_AD%WakeLocationPoints)) then - InitInData%NumWindPoints = InitInData%NumWindPoints + size(o_AD%WakeLocationPoints,DIM=2) - end if - - ! --- Init InflowWind - if (dvr%CompInflow==0) then - ! Fake "InflowWind" init - allocate(InitOutData%WriteOutputHdr(0)) - allocate(InitOutData%WriteOutputUnt(0)) - allocate(IW%y%WriteOutput(0)) - call AllocAry(IW%u(1)%PositionXYZ, 3, InitInData%NumWindPoints, 'PositionXYZ', errStat2, errMsg2); if (Failed()) return - call AllocAry(IW%y%VelocityUVW , 3, InitInData%NumWindPoints, 'VelocityUVW', errStat2, errMsg2); if (Failed()) return - IW%u(1)%PositionXYZ = myNaN - IW%y%VelocityUVW = myNaN - else - ! Module init - InitInData%InputFileName = dvr%IW_InputFile - InitInData%Linearize = .false. - InitInData%UseInputFile = .true. - InitInData%RootName = dvr%out%Root - CALL InflowWind_Init( InitInData, IW%u(1), IW%p, & - IW%x, IW%xd, IW%z, IW%OtherSt, & - IW%y, IW%m, dt, InitOutData, errStat2, errMsg2 ) - if(Failed()) return - - endif - - call InflowWind_CopyInput (IW%u(1), IW%u(2), MESH_NEWCOPY, errStat2, errMsg2); if(Failed()) return + Failed0 = errStat >= AbortErrLev + if(Failed0) call cleanUp() + end function Failed0 - ! --- Concatenate AD outputs to IW outputs - call concatOutputHeaders(dvr, InitOutData%WriteOutputHdr, InitOutData%WriteOutputUnt, errStat2, errMsg2); if(Failed()) return - - call cleanup() -contains - subroutine cleanup() - call InflowWind_DestroyInitInput( InitInData, ErrStat2, ErrMsg2 ) - call InflowWind_DestroyInitOutput( InitOutData, ErrStat2, ErrMsg2 ) - end subroutine cleanup - - logical function Failed() - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Init_AeroDyn' ) - Failed = ErrStat >= AbortErrLev - if (Failed) then - call cleanup() - endif - end function Failed -end subroutine Init_InflowWind - -!> Concatenate new output channels info to the extisting ones in the driver -subroutine concatOutputHeaders(dvr, WriteOutputHdr, WriteOutputUnt, errStat, errMsg) - type(Dvr_SimData), target, intent(inout) :: dvr !< Input data for initialization (intent out for getting AD WriteOutput names/units) - character(ChanLen), dimension(:), allocatable, intent(inout) :: WriteOutputHdr !< Channel headers - character(ChanLen), dimension(:), allocatable, intent(inout) :: WriteOutputUnt !< Channel units - integer(IntKi) , intent( out) :: errStat !< Status of error message - character(*) , intent( out) :: errMsg !< Error message if ErrStat /= ErrID_None - ! Locals - character(ChanLen), allocatable :: TmpHdr(:) - character(ChanLen), allocatable :: TmpUnt(:) - integer :: nOld, nAdd - errStat = ErrID_None - errMsg = '' - - - if (.not.allocated(dvr%out%WriteOutputHdr)) then - call move_alloc(WriteOutputHdr, dvr%out%WriteOutputHdr) - call move_alloc(WriteOutputUnt, dvr%out%WriteOutputUnt) - else - nOld = size(dvr%out%WriteOutputHdr) - nAdd = size(WriteOutputHdr) - - call move_alloc(dvr%out%WriteOutputHdr, TmpHdr) - call move_alloc(dvr%out%WriteOutputUnt, TmpUnt) - - allocate(dvr%out%WriteOutputHdr(nOld+nAdd)) - allocate(dvr%out%WriteOutputUnt(nOld+nAdd)) - dvr%out%WriteOutputHdr(1:nOld) = TmpHdr - dvr%out%WriteOutputUnt(1:nOld) = TmpUnt - dvr%out%WriteOutputHdr(nOld+1:nOld+nAdd) = WriteOutputHdr - dvr%out%WriteOutputUnt(nOld+1:nOld+nAdd) = WriteOutputUnt - deallocate(TmpHdr) - deallocate(TmpUnt) - endif -end subroutine concatOutputHeaders +end subroutine Init_ADI_ForDriver !---------------------------------------------------------------------------------------------------------------------------------- !> -subroutine Init_Meshes(dvr, errStat, errMsg) +subroutine Init_Meshes(dvr, FED, errStat, errMsg) type(Dvr_SimData), target, intent(inout) :: dvr ! Input data for initialization (intent out for getting AD WriteOutput names/units) + type(FED_Data), target, intent(inout) :: FED ! Elastic wind turbine data (Fake ElastoDyn) integer(IntKi) , intent( out) :: errStat ! Status of error message character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None ! locals @@ -617,14 +573,16 @@ subroutine Init_Meshes(dvr, errStat, errMsg) real(R8Ki) :: R_gl2wt(3,3) integer(IntKi) :: iWT, iB integer(IntKi) :: errStat2 ! local status of error message - character(ErrMsgLen) :: errMsg2 ! local error message if ErrStat /= ErrID_None + character(ErrMsgLen) :: errMsg2 ! local error message if errStat /= ErrID_None type(WTData), pointer :: wt ! Alias to shorten notation + type(RotFED), pointer :: y_ED ! Alias to shorten notation errStat = ErrID_None errMsg = '' ! --- Create motion meshes do iWT=1,dvr%numTurbines wt => dvr%WT(iWT) + y_ED => FED%WT(iWT) ! WT base pos = wt%originInit ! We initialize to indentity at first @@ -633,27 +591,26 @@ subroutine Init_Meshes(dvr, errStat, errMsg) orientation = R_gl2wt !bjj: Inspector consistently gives "Invalid Memory Access" errors here on the allocation of wt%ptMesh%RotationVel in MeshCreate. I haven't yet figured out why. - call CreatePointMesh(wt%ptMesh, pos, orientation, errStat2, errMsg2); if(Failed()) return + call CreatePointMesh(y_ED%PlatformPtMesh, pos, orientation, errStat2, errMsg2, hasMotion=.True., hasLoads=.False.); if(Failed()) return ! Tower if (wt%hasTower) then - pos = wt%ptMesh%Position(:,1) + matmul(transpose(R_gl2wt), wt%twr%origin_t) + pos = y_ED%PlatformPtMesh%Position(:,1) + matmul(transpose(R_gl2wt), wt%twr%origin_t) orientation = R_gl2wt - call CreatePointMesh(wt%twr%ptMesh, pos, orientation, errStat2, errMsg2); if(Failed()) return + call CreatePointMesh(y_ED%TwrPtMesh, pos, orientation, errStat2, errMsg2, hasMotion=.True., hasLoads=.False.); if(Failed()) return endif ! Nacelle - pos = wt%ptMesh%Position(:,1) + matmul(transpose(R_gl2wt), wt%nac%origin_t) + pos = y_ED%PlatformPtMesh%Position(:,1) + matmul(transpose(R_gl2wt), wt%nac%origin_t) orientation = R_gl2wt ! Yaw? - call CreatePointMesh(wt%nac%ptMesh, pos, orientation, errStat2, errMsg2); if(Failed()) return + call CreatePointMesh(y_ED%NacelleMotion, pos, orientation, errStat2, errMsg2, hasMotion=.True., hasLoads=.False.); if(Failed()) return ! Hub - R_nac2gl = transpose(wt%nac%ptMesh%RefOrientation(:,:,1)) + R_nac2gl = transpose(y_ED%NacelleMotion%RefOrientation(:,:,1)) R_nac2hub = EulerConstruct( wt%hub%orientation_n ) ! nacelle 2 hub (constant) - pos = wt%nac%ptMesh%Position(:,1) + matmul(R_nac2gl,wt%hub%origin_n) - orientation = matmul(R_nac2hub, wt%nac%ptMesh%RefOrientation(:,:,1)) ! Global 2 hub at t=0 - - call CreatePointMesh(wt%hub%ptMesh, pos, orientation, errStat2, errMsg2); if(Failed())return + pos = y_ED%NacelleMotion%Position(:,1) + matmul(R_nac2gl,wt%hub%origin_n) + orientation = matmul(R_nac2hub, y_ED%NacelleMotion%RefOrientation(:,:,1)) ! Global 2 hub at t=0 + call CreatePointMesh(y_ED%HubPtMotion, pos, orientation, errStat2, errMsg2, hasMotion=.True., hasLoads=.False.); if(Failed())return ! Blades ! wt%Rg2b0 = EulerConstruct( wt%orientationInit ) ! global 2 base at t = 0 (constant) @@ -661,39 +618,40 @@ subroutine Init_Meshes(dvr, errStat, errMsg) ! InitInData%HubPosition = wt%originInit + wt%nac%origin_t + matmul( transpose(wt%Rg2b0), wt%hub%origin_n) ! InitInData%HubOrientation = matmul(wt%Rb2h0, wt%Rg2b0) ! Global 2 hub = base2hub x global2base - R_hub2gl = transpose(wt%hub%ptMesh%RefOrientation(:,:,1)) + R_hub2gl = transpose(y_ED%HubPtMotion%RefOrientation(:,:,1)) + allocate(y_ED%BladeRootMotion(wt%numBlades)) do iB=1,wt%numBlades R_hub2bl = EulerConstruct( wt%bld(iB)%orientation_h ) ! Rotation matrix hub 2 blade (constant) - orientation = matmul(R_hub2bl, wt%hub%ptMesh%RefOrientation(:,:,1) ) ! Global 2 blade = hub2blade x global2hub - pos = wt%hub%ptMesh%Position(:,1) + matmul(R_hub2gl, wt%bld(iB)%origin_h) + wt%bld(iB)%hubRad_bl*orientation(3,:) - call CreatePointMesh(wt%bld(iB)%ptMesh, pos, orientation, errStat2, errMsg2); if(Failed())return + orientation = matmul(R_hub2bl, y_ED%HubPtMotion%RefOrientation(:,:,1) ) ! Global 2 blade = hub2blade x global2hub + pos = y_ED%HubPtMotion%Position(:,1) + matmul(R_hub2gl, wt%bld(iB)%origin_h) + wt%bld(iB)%hubRad_bl*orientation(3,:) + call CreatePointMesh(y_ED%BladeRootMotion(iB), pos, orientation, errStat2, errMsg2, hasMotion=.True., hasLoads=.False.); if(Failed())return end do ! --- Mapping ! Base 2 twr if (wt%hasTower) then - call MeshMapCreate(wt%ptMesh, wt%twr%ptMesh, wt%map2twrPt, errStat2, errMsg2); if(Failed())return + call MeshMapCreate(y_ED%PlatformPtMesh, y_ED%TwrPtMesh, wt%map2twrPt, errStat2, errMsg2); if(Failed())return endif ! Base 2 nac - call MeshMapCreate(wt%ptMesh, wt%nac%ptMesh, wt%map2nacPt, errStat2, errMsg2); if(Failed())return + call MeshMapCreate(y_ED%PlatformPtMesh, y_ED%NacelleMotion, wt%map2nacPt, errStat2, errMsg2); if(Failed())return ! nac 2 hub - call MeshMapCreate(wt%nac%ptMesh, wt%hub%ptMesh, wt%nac%map2hubPt, errStat2, errMsg2); if(Failed())return + call MeshMapCreate(y_ED%NacelleMotion, y_ED%HubPtMotion, wt%map2hubPt, errStat2, errMsg2); if(Failed())return ! hub 2 bld - allocate(wt%hub%map2bldPt(wt%numBlades)) + allocate(wt%map2bldPt(wt%numBlades)) do iB=1,wt%numBlades - call MeshMapCreate(wt%hub%ptMesh, wt%bld(iB)%ptMesh, wt%hub%map2bldPt(iB), errStat2, errMsg2); if(Failed())return + call MeshMapCreate(y_ED%HubPtMotion, y_ED%BladeRootMotion(iB), wt%map2bldPt(iB), errStat2, errMsg2); if(Failed())return enddo ! ! --- NOTE: KEEP ME, this information would go well in a summary file... print*,'Nodes positions for turbine '//trim(num2lstr(iWT))//', (at t=0, without base or RNA motion)' - print*,'Bse: ',wt%ptMesh%Position + wt%ptMesh%TranslationDisp + print*,'Bse: ',y_ED%PlatformPtMesh%Position + y_ED%PlatformPtMesh%TranslationDisp if (wt%hasTower) then - print*,'Twr: ',wt%twr%ptMesh%Position + wt%twr%ptMesh%TranslationDisp + print*,'Twr: ',y_ED%TwrPtMesh%Position + y_ED%TwrPtMesh%TranslationDisp endif - print*,'Nac: ',wt%nac%ptMesh%Position + wt%nac%ptMesh%TranslationDisp - print*,'Hub: ',wt%hub%ptMesh%Position + wt%hub%ptMesh%TranslationDisp + print*,'Nac: ',y_ED%NacelleMotion%Position + y_ED%NacelleMotion%TranslationDisp + print*,'Hub: ',y_ED%HubPtMotion%Position + y_ED%HubPtMotion%TranslationDisp do iB=1,wt%numBlades - print*,'Bld: ',wt%bld(iB)%ptMesh%Position + wt%bld(iB)%ptMesh%TranslationDisp + print*,'Bld: ',y_ED%BladeRootMotion(iB)%Position + y_ED%BladeRootMotion(iB)%TranslationDisp enddo enddo @@ -701,147 +659,27 @@ subroutine Init_Meshes(dvr, errStat, errMsg) logical function Failed() call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Init_Meshes') - Failed = ErrStat >= AbortErrLev + Failed = errStat >= AbortErrLev end function Failed end subroutine Init_Meshes -!> Initialize the mesh mappings between the structure and aerodyn -!! Also adjust the tower mesh so that is is aligned with the tower base and tower top -subroutine Init_ADMeshMap(dvr, uAD, errStat, errMsg) - type(Dvr_SimData), target, intent(inout) :: dvr ! Input data for initialization (intent out for getting AD WriteOutput names/units) - type(AD_InputType), intent(inout) :: uAD ! AeroDyn input data - integer(IntKi) , intent( out) :: errStat ! Status of error message - character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - ! locals - real(ReKi) :: pos(3), Pbase(3), Ptop(3), Pmid(3), DeltaP(3) - real(R8Ki) :: orientation(3,3) - real(ReKi) :: twrHeightAD , twrHeight - real(ReKi) :: zBar ! dimensionsless tower height - integer(IntKi) :: iWT, iB, i - integer(IntKi) :: errStat2 ! local status of error message - character(ErrMsgLen) :: errMsg2 ! local error message if ErrStat /= ErrID_None - type(WTData), pointer :: wt ! Alias to shorten notation - errStat = ErrID_None - errMsg = '' - - ! --- Create Mappings from structure to AeroDyn - do iWT=1,dvr%numTurbines - wt => dvr%WT(iWT) - ! hub 2 hubAD - call MeshMapCreate(wt%hub%ptMesh, uAD%rotors(iWT)%hubMotion, wt%hub%ED_P_2_AD_P_H, errStat2, errMsg2); if(Failed())return - - ! nac 2 nacAD - call MeshMapCreate(wt%nac%ptMesh, uAD%rotors(iWT)%nacelleMotion, wt%nac%ED_P_2_AD_P_N, errStat2, errMsg2); if(Failed())return - - ! bldroot 2 bldroot AD - do iB = 1, wt%numBlades - call MeshMapCreate(wt%bld(iB)%ptMesh, uAD%rotors(iWT)%BladeRootMotion(iB), wt%bld(iB)%ED_P_2_AD_P_R, errStat2, errMsg2); if(Failed())return - enddo - - ! AD bld root 2 AD blade line - do iB = 1, wt%numBlades - call MeshMapCreate(uAD%rotors(iWT)%BladeRootMotion(iB), uAD%rotors(iWT)%BladeMotion(iB), wt%bld(iB)%AD_P_2_AD_L_B, errStat2, errMsg2); if(Failed())return - enddo - - if (uAD%rotors(iWT)%TowerMotion%nNodes>0) then - if (wt%hasTower) then - twrHeightAD=uAD%rotors(iWT)%TowerMotion%Position(3,uAD%rotors(iWT)%TowerMotion%nNodes)-uAD%rotors(iWT)%TowerMotion%Position(3,1) - ! Check tower height - if (twrHeightAD<0) then - errStat=ErrID_Fatal - errMsg='First AeroDyn tower height should be smaller than last AD tower height' - endif - - twrHeightAD=uAD%rotors(iWT)%TowerMotion%Position(3,uAD%rotors(iWT)%TowerMotion%nNodes) ! NOTE: assuming start a z=0 - - twrHeight=TwoNorm(wt%nac%ptMesh%Position(:,1) - wt%twr%ptMesh%Position(:,1) ) - ! KEEP ME, in summary file - !print*,'Tower Height',twrHeight, twrHeightAD - if (abs(twrHeightAD-twrHeight)> twrHeight*0.1) then - errStat=ErrID_Fatal - errMsg='More than 10% difference between AeroDyn tower length ('//trim(num2lstr(twrHeightAD))//& - 'm), and the distance from tower base to nacelle ('//trim(num2lstr(twrHeight))//'m) for turbine '//trim(num2lstr(iWT)) - endif - - ! Adjust tower position (AeroDyn return values assuming (0,0,0) for tower base - Pbase = wt%twr%ptMesh%Position(:,1) - Ptop = wt%nac%ptMesh%Position(:,1) - DeltaP = Ptop-Pbase - do i = 1, uAD%rotors(iWT)%TowerMotion%nNodes - zBar = uAD%rotors(iWT)%TowerMotion%Position(3,i)/twrHeight - uAD%rotors(iWT)%TowerMotion%Position(:,i)= Pbase+ zBar * DeltaP - uAD%rotors(iWT)%TowerMotion%RefOrientation(:,:,i)= wt%twr%ptMesh%RefOrientation(:,:,1) - enddo - ! Create AD tower base point mesh - pos = wt%twr%ptMesh%Position(:,1) - orientation = wt%twr%ptMesh%RefOrientation(:,:,1) - call Eye(orientation, errStat2, errMsg2) - call CreatePointMesh(wt%twr%ptMeshAD, pos, orientation, errStat2, errMsg2); if(Failed())return - - ! TowerBase to AD tower base - call MeshMapCreate(wt%twr%ptMesh, wt%twr%ptMeshAD, wt%twr%ED_P_2_AD_P_T, errStat2, errMsg2); if(Failed()) return - - ! AD TowerBase to AD tower line - call MeshMapCreate(wt%twr%ptMeshAD, uAD%rotors(iWT)%TowerMotion, wt%twr%AD_P_2_AD_L_T, errStat2, errMsg2); if(Failed()) return - endif - else - print*,'>>> NO AD Tower' - ! TODO create a tower mesh for outputs - endif - - enddo - -contains - - logical function Failed() - call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Init_ADMeshMap') - Failed = ErrStat >= AbortErrLev - end function Failed -end subroutine Init_ADMeshMap - -!---------------------------------------------------------------------------------------------------------------------------------- -!> -subroutine CreatePointMesh(mesh, posInit, orientInit, errStat, errMsg) - type(MeshType), intent(inout) :: mesh - real(ReKi), intent(in ) :: PosInit(3) !< Xi,Yi,Zi, coordinates of node - real(R8Ki), intent(in ) :: orientInit(3,3) !< Orientation (direction cosine matrix) of node; identity by default - integer(IntKi) , intent(out) :: errStat ! Status of error message - character(*) , intent(out) :: errMsg ! Error message if ErrStat /= ErrID_None - integer(IntKi) :: errStat2 ! local status of error message - character(ErrMsgLen) :: errMsg2 ! local error message if ErrStat /= ErrID_None - errStat = ErrID_None - errMsg = '' - - call MeshCreate(mesh, COMPONENT_INPUT, 1, errStat2, errMsg2, Orientation=.true., TranslationDisp=.true., TranslationVel=.true., RotationVel=.true., TranslationAcc=.true., RotationAcc=.true.) - call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'CreatePointMesh') - if (ErrStat >= AbortErrLev) return - - call MeshPositionNode(mesh, 1, posInit, errStat2, errMsg2, orientInit); - call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'CreatePointMesh') - - call MeshConstructElement(mesh, ELEMENT_POINT, errStat2, errMsg2, p1=1); - call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'CreatePointMesh') - - call MeshCommit(mesh, errStat2, errMsg2); - call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'CreatePointMesh') -end subroutine CreatePointMesh - - !---------------------------------------------------------------------------------------------------------------------------------- !> Set the motion of the different structural meshes !! "ED_CalcOutput" -subroutine Set_Mesh_Motion(nt,dvr,errStat,errMsg) +subroutine Set_Mesh_Motion(nt, dvr, ADI, FED, errStat, errMsg) integer(IntKi) , intent(in ) :: nt !< time step number - type(Dvr_SimData), target, intent(inout) :: dvr !< Driver data + type(Dvr_SimData), target, intent(inout) :: dvr !< Driver data + type(ADI_Data), intent(inout) :: ADI !< AeroDyn/InflowWind Data + type(FED_Data), target, intent(inout) :: FED !< Elastic wind turbine data (Fake ElastoDyn) integer(IntKi) , intent( out) :: errStat !< Status of error message - character(*) , intent( out) :: errMsg !< Error message if ErrStat /= ErrID_None + character(*) , intent( out) :: errMsg !< Error message if errStat /= ErrID_None ! local variables integer(intKi) :: j ! loop counter for nodes integer(intKi) :: k ! loop counter for blades integer(intKi) :: iWT ! loop counter for rotors integer(intKi) :: iB ! loop counter for blades integer(IntKi) :: errStat2 ! local status of error message - character(ErrMsgLen) :: errMsg2 ! local error message if ErrStat /= ErrID_None + character(ErrMsgLen) :: errMsg2 ! local error message if errStat /= ErrID_None real(R8Ki) :: theta(3) real(ReKi) :: hubMotion(3) ! Azimuth, Speed, Acceleration real(ReKi) :: nacMotion(3) ! Yaw, yaw speed, yaw acc @@ -853,6 +691,7 @@ subroutine Set_Mesh_Motion(nt,dvr,errStat,errMsg) real(R8Ki) :: orientation_loc(3,3) real(DbKi) :: time, timePrev type(WTData), pointer :: wt ! Alias to shorten notation + type(RotFED), pointer :: y_ED ! Alias to shorten notation errStat = ErrID_None errMsg = "" @@ -864,8 +703,8 @@ subroutine Set_Mesh_Motion(nt,dvr,errStat,errMsg) ! timestate = HWindSpeed, PLExp, RotSpeed, Pitch, yaw call interpTimeValue(dvr%timeSeries, time, dvr%iTimeSeries, timeState) ! Set wind at this time - dvr%HWindSpeed = timeState(1) - dvr%PLexp = timeState(2) + ADI%m%IW%HWindSpeed = timeState(1) + ADI%m%IW%PLexp = timeState(2) !! Set motion at this time dvr%WT(1)%hub%rotSpeed = timeState(3) ! rad/s do j=1,size(dvr%WT(1)%bld) @@ -887,45 +726,46 @@ subroutine Set_Mesh_Motion(nt,dvr,errStat,errMsg) ! --- Update motion do iWT=1,dvr%numTurbines wt => dvr%WT(iWT) + y_ED => FED%WT(iWT) ! --- Base Motion orientation = EulerConstruct( wt%orientationInit ) ! global 2 base at t = 0 (constant) if (wt%motionType == idBaseMotionGeneral) then orientation_loc = EulerConstruct( theta ) call interpTimeValue(wt%motion, time, wt%iMotion, basMotion) - wt%ptMesh%TranslationDisp(1:3,1) = basMotion(1:3) - wt%ptMesh%TranslationVel (1:3,1) = basMotion(7:9) - wt%ptMesh%RotationVel (1:3,1) = basMotion(10:12) - wt%ptMesh%TranslationAcc (1:3,1) = basMotion(13:15) - wt%ptMesh%RotationAcc (1:3,1) = basMotion(16:18) + y_ED%PlatformPtMesh%TranslationDisp(1:3,1) = basMotion(1:3) + y_ED%PlatformPtMesh%TranslationVel (1:3,1) = basMotion(7:9) + y_ED%PlatformPtMesh%RotationVel (1:3,1) = basMotion(10:12) + y_ED%PlatformPtMesh%TranslationAcc (1:3,1) = basMotion(13:15) + y_ED%PlatformPtMesh%RotationAcc (1:3,1) = basMotion(16:18) theta = basMotion(4:6) orientation_loc = EulerConstruct( theta ) orientation = matmul(orientation_loc, orientation) elseif (wt%motionType == idBaseMotionSine) then if (any(wt%degreeOfFreedom==(/1,2,3/))) then - wt%ptMesh%TranslationDisp(wt%degreeofFreedom,1) = wt%amplitude * sin(time * wt%frequency) - wt%ptMesh%TranslationVel (wt%degreeofFreedom,1) = (wt%frequency) * wt%amplitude * cos(time * wt%frequency) - wt%ptMesh%TranslationAcc (wt%degreeofFreedom,1) = -(wt%frequency)**2 * wt%amplitude * sin(time * wt%frequency) + y_ED%PlatformPtMesh%TranslationDisp(wt%degreeofFreedom,1) = wt%amplitude * sin(time * wt%frequency) + y_ED%PlatformPtMesh%TranslationVel (wt%degreeofFreedom,1) = (wt%frequency) * wt%amplitude * cos(time * wt%frequency) + y_ED%PlatformPtMesh%TranslationAcc (wt%degreeofFreedom,1) = -(wt%frequency)**2 * wt%amplitude * sin(time * wt%frequency) elseif (any(wt%degreeOfFreedom==(/4,5,6/))) then theta(1:3) = 0.0_ReKi theta(wt%degreeofFreedom-3) = wt%amplitude * sin(time * wt%frequency) - wt%ptMesh%RotationVel (wt%degreeofFreedom-3,1) = (wt%frequency) * wt%amplitude * cos(time * wt%frequency) - wt%ptMesh%RotationAcc (wt%degreeofFreedom-3,1) = -(wt%frequency)**2 * wt%amplitude * sin(time * wt%frequency) + y_ED%PlatformPtMesh%RotationVel (wt%degreeofFreedom-3,1) = (wt%frequency) * wt%amplitude * cos(time * wt%frequency) + y_ED%PlatformPtMesh%RotationAcc (wt%degreeofFreedom-3,1) = -(wt%frequency)**2 * wt%amplitude * sin(time * wt%frequency) orientation_loc = EulerConstruct( theta ) orientation = matmul(orientation_loc, orientation) endif endif - wt%ptMesh%Orientation(:,:,1) = orientation + y_ED%PlatformPtMesh%Orientation(:,:,1) = orientation ! --- Tower motion (none) ! Base to Tower if (wt%hasTower) then - call Transfer_Point_to_Point(wt%ptMesh, wt%twr%ptMesh, wt%map2twrPt, errStat2, errMsg2); if(Failed()) return + call Transfer_Point_to_Point(y_ED%PlatformPtMesh, y_ED%TwrPtMesh, wt%map2twrPt, errStat2, errMsg2); if(Failed()) return endif ! --- Nacelle Motion ! Base to Nac - call Transfer_Point_to_Point(wt%ptMesh, wt%nac%ptMesh, wt%map2nacPt, errStat2, errMsg2); if(Failed()) return + call Transfer_Point_to_Point(y_ED%PlatformPtMesh, y_ED%NacelleMotion, wt%map2nacPt, errStat2, errMsg2); if(Failed()) return ! Nacelle yaw motion (along nac z) theta =0.0_ReKi if (wt%nac%motionType==idNacMotionConstant) then @@ -937,19 +777,19 @@ subroutine Set_Mesh_Motion(nt,dvr,errStat,errMsg) wt%nac%yawSpeed = nacMotion(2) wt%nac%yawAcc = nacMotion(3) else - ErrMsg2='Unknown nac motion type; should never happen.' - ErrStat2 = ErrID_FATAL + errMsg2='Unknown nac motion type; should never happen.' + errStat2 = ErrID_FATAL if(Failed()) return endif theta(3) = wt%nac%yaw orientation_loc = EulerConstruct(theta) - wt%nac%ptMesh%Orientation(:,:,1) = matmul(orientation_loc, wt%nac%ptMesh%Orientation(:,:,1)) - wt%nac%ptMesh%RotationVel( :,1) = wt%nac%ptMesh%RotationVel(:,1) + wt%nac%ptMesh%Orientation(3,:,1) * wt%nac%yawSpeed - wt%nac%ptMesh%RotationAcc( :,1) = wt%nac%ptMesh%RotationAcc(:,1) + wt%nac%ptMesh%Orientation(3,:,1) * wt%nac%yawAcc + y_ED%NacelleMotion%Orientation(:,:,1) = matmul(orientation_loc, y_ED%NacelleMotion%Orientation(:,:,1)) + y_ED%NacelleMotion%RotationVel( :,1) = y_ED%NacelleMotion%RotationVel(:,1) + y_ED%NacelleMotion%Orientation(3,:,1) * wt%nac%yawSpeed + y_ED%NacelleMotion%RotationAcc( :,1) = y_ED%NacelleMotion%RotationAcc(:,1) + y_ED%NacelleMotion%Orientation(3,:,1) * wt%nac%yawAcc ! --- Hub Motion ! Nac 2 hub (rigid body) - call Transfer_Point_to_Point(wt%nac%ptMesh, wt%hub%ptMesh, wt%nac%map2hubPt, errStat2, errMsg2); if(Failed()) return + call Transfer_Point_to_Point(y_ED%NacelleMotion, y_ED%HubPtMotion, wt%map2hubPt, errStat2, errMsg2); if(Failed()) return ! Hub rotation around x if (wt%hub%motionType == idHubMotionConstant) then ! save the azimuth at t (not t+dt) for output to file: @@ -968,6 +808,10 @@ subroutine Set_Mesh_Motion(nt,dvr,errStat,errMsg) wt%hub%rotSpeed = hubMotion(2) wt%hub%rotAcc = hubMotion(2) wt%hub%azimuth = MODULO(hubMotion(1)*R2D, 360.0_ReKi ) + else if (wt%hub%motionType == idHubMotionUserFunction) then + ! We call a user-defined function to determined the azimuth, speed (and potentially acceleration...) + call userHubMotion(nt, iWT, dvr, ADI, FED, wt%userSwapArray, wt%hub%azimuth, wt%hub%rotSpeed, wt%hub%rotAcc, errStat2, errMsg2) + if (Failed()) return else if (wt%hub%motionType == idHubMotionStateTS) then ! NOTE: match AeroDyndriver for backward compatibility @@ -988,14 +832,14 @@ subroutine Set_Mesh_Motion(nt,dvr,errStat,errMsg) theta(2) = 0.0_ReKi theta(3) = 0.0_ReKi orientation_loc = EulerConstruct( theta ) - wt%hub%ptMesh%Orientation(:,:,1) = matmul(orientation_loc, wt%hub%ptMesh%Orientation(:,:,1)) - wt%hub%ptMesh%RotationVel( :,1) = wt%hub%ptMesh%RotationVel(:,1) + wt%hub%ptMesh%Orientation(1,:,1) * wt%hub%rotSpeed - wt%hub%ptMesh%RotationAcc( :,1) = wt%hub%ptMesh%RotationAcc(:,1) + wt%hub%ptMesh%Orientation(1,:,1) * wt%hub%rotAcc + y_ED%HubPtMotion%Orientation(:,:,1) = matmul(orientation_loc, y_ED%HubPtMotion%Orientation(:,:,1)) + y_ED%HubPtMotion%RotationVel( :,1) = y_ED%HubPtMotion%RotationVel(:,1) + y_ED%HubPtMotion%Orientation(1,:,1) * wt%hub%rotSpeed + y_ED%HubPtMotion%RotationAcc( :,1) = y_ED%HubPtMotion%RotationAcc(:,1) + y_ED%HubPtMotion%Orientation(1,:,1) * wt%hub%rotAcc ! --- Blade motion ! Hub 2 blade root do iB = 1,wt%numBlades - call Transfer_Point_to_Point(wt%hub%ptMesh, wt%bld(iB)%ptMesh, wt%hub%map2bldPt(iB), errStat2, errMsg2); if(Failed()) return + call Transfer_Point_to_Point(y_ED%HubPtMotion, y_ED%BladeRootMotion(iB), wt%map2bldPt(iB), errStat2, errMsg2); if(Failed()) return ! Pitch motion aong z theta =0.0_ReKi if (wt%bld(iB)%motionType==idBldMotionConstant) then @@ -1003,240 +847,59 @@ subroutine Set_Mesh_Motion(nt,dvr,errStat,errMsg) elseif (wt%bld(iB)%motionType==idBldMotionVariable) then call interpTimeValue(wt%bld(iB)%motion, time, wt%bld(iB)%iMotion, bldMotion) wt%bld(iB)%pitch =bldMotion(1) - wt%bld(iB)%ptMesh%RotationVel(:,1) = wt%bld(iB)%ptMesh%RotationVel(:,1) + wt%bld(iB)%ptMesh%Orientation(3,:,1)* (-bldMotion(2)) - wt%bld(iB)%ptMesh%RotationAcc(:,1) = wt%bld(iB)%ptMesh%RotationAcc(:,1) + wt%bld(iB)%ptMesh%Orientation(3,:,1)* (-bldMotion(3)) + y_ED%BladeRootMotion(iB)%RotationVel(:,1) = y_ED%BladeRootMotion(iB)%RotationVel(:,1) + y_ED%BladeRootMotion(iB)%Orientation(3,:,1)* (-bldMotion(2)) + y_ED%BladeRootMotion(iB)%RotationAcc(:,1) = y_ED%BladeRootMotion(iB)%RotationAcc(:,1) + y_ED%BladeRootMotion(iB)%Orientation(3,:,1)* (-bldMotion(3)) else print*,'Unknown blade motion type, should never happen' STOP endif theta(3) = - wt%bld(iB)%pitch ! NOTE: sign, wind turbine convention ... orientation_loc = EulerConstruct(theta) - wt%bld(iB)%ptMesh%Orientation(:,:,1) = matmul(orientation_loc, wt%bld(iB)%ptMesh%Orientation(:,:,1)) + y_ED%BladeRootMotion(iB)%Orientation(:,:,1) = matmul(orientation_loc, y_ED%BladeRootMotion(iB)%Orientation(:,:,1)) enddo - !print*,'Bse: ',wt%ptMesh%Position + wt%ptMesh%TranslationDisp + !print*,'Bse: ',y_ED%PlatformPtMesh%Position + y_ED%PlatformPtMesh%TranslationDisp !if (wt%hasTower) then ! print*,'Twr: ',wt%twr%ptMesh%Position + wt%twr%ptMesh%TranslationDisp !endif !print*,'Nac: ',wt%nac%ptMesh%Position + wt%nac%ptMesh%TranslationDisp !print*,'Hub: ',wt%hub%ptMesh%Position + wt%hub%ptMesh%TranslationDisp !do iB=1,wt%numBlades - ! print*,'Bld: ',wt%bld(iB)%ptMesh%Position + wt%bld(iB)%ptMesh%TranslationDisp + ! print*,'Bld: ',y_ED%BladeRootMotion(iB)%Position + y_ED%BladeRootMotion(iB)%TranslationDisp !enddo enddo ! Loop on wind turbines contains logical function Failed() call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Set_Mesh_Motion') - Failed = ErrStat >= AbortErrLev + Failed = errStat >= AbortErrLev end function Failed end subroutine Set_Mesh_Motion !---------------------------------------------------------------------------------------------------------------------------------- -!> Set aerodyn inputs -! - cycle values in the input array AD%InputTime and AD%u. -! - set AD input meshes and inflow -subroutine Set_AD_Inputs(nt,dvr,AD,IW,errStat,errMsg) - integer(IntKi) , intent(in ) :: nt ! time step number - type(Dvr_SimData), target, intent(in ) :: dvr ! Driver data - type(AeroDyn_Data), target, intent(inout) :: AD ! AeroDyn data - type(InflowWind_Data), intent(inout) :: IW ! InflowWind data - integer(IntKi) , intent( out) :: errStat ! Status of error message - character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None +!> Shift current inputs to old inputs (done because time step constant in driver) +!! NOTE: might not be needed with new ADI module +!! cycle values in the input array AD%InputTime and AD%u. +subroutine Shift_ADI_Inputs(nt, dvr, ADI, errStat, errMsg) + integer(IntKi) , intent(in ) :: nt ! time step number + type(Dvr_SimData), intent(in ) :: dvr ! Driver data + type(ADI_Data), intent(inout) :: ADI !< AeroDyn/InflowWind Data + integer(IntKi) , intent( out) :: errStat !< Status of error message + character(*) , intent( out) :: errMsg !< Error message if errStat /= ErrID_None ! local variables integer(intKi) :: j ! loop index - integer(intKi) :: iWT ! loop counter for rotors - integer(intKi) :: iB ! loop counter for blades integer(IntKi) :: errStat2 ! local status of error message - character(ErrMsgLen) :: errMsg2 ! local error message if ErrStat /= ErrID_None - type(WTData), pointer :: wt ! Alias to shorten notation + character(ErrMsgLen) :: errMsg2 ! local error message if errStat /= ErrID_None real(ReKi) :: z errStat = ErrID_None errMsg = "" - - ! --- Shift previous calculations: do j = numInp-1,1,-1 - call AD_CopyInput (AD%u(j), AD%u(j+1), MESH_UPDATECOPY, ErrStat2, ErrMsg2); if (Failed()) return - AD%inputTime(j+1) = AD%inputTime(j) + call AD_CopyInput (ADI%u(j)%AD, ADI%u(j+1)%AD, MESH_UPDATECOPY, errStat2, ErrMsg2); + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Shift_ADI_Inputs') + ADI%inputTimes(j+1) = ADI%inputTimes(j) end do - AD%inputTime(1) = dvr%dT * nt ! time at "nt+1" - - ! --- Transfer motion from "ED" to AeroDyn - do iWT=1,dvr%numTurbines - wt => dvr%WT(iWT) - ! Hub 2 Hub AD - call Transfer_Point_to_Point(wt%hub%ptMesh, AD%u(1)%rotors(iWT)%hubMotion, wt%hub%ED_P_2_AD_P_H, errStat2, errMsg2); if(Failed()) return - - ! Nac 2 Nac AD - call Transfer_Point_to_Point(wt%nac%ptMesh, AD%u(1)%rotors(iWT)%nacelleMotion, wt%nac%ED_P_2_AD_P_N, errStat2, errMsg2); if(Failed()) return - - ! Blade root to blade root AD - do iB = 1,wt%numBlades - call Transfer_Point_to_Point(wt%bld(iB)%ptMesh, AD%u(1)%rotors(iWT)%BladeRootMotion(iB), wt%bld(iB)%ED_P_2_AD_P_R, errStat2, errMsg2); if(Failed()) return - enddo - - ! Blade root AD to blade line AD - do iB = 1,wt%numBlades - call Transfer_Point_to_Line2(AD%u(1)%rotors(iWT)%BladeRootMotion(iB), AD%u(1)%rotors(iWT)%BladeMotion(iB), wt%bld(iB)%AD_P_2_AD_L_B, errStat2, errMsg2); if(Failed()) return - enddo - - ! Tower motion - if (wt%hasTower) then - if (AD%u(1)%rotors(iWT)%TowerMotion%nNodes>0) then - call Transfer_Point_to_Point(wt%twr%ptMesh, wt%twr%ptMeshAD, wt%twr%ED_P_2_AD_P_T, errStat2, errMsg2); if(Failed()) return - call Transfer_Point_to_Line2(wt%twr%ptMeshAD, AD%u(1)%rotors(iWT)%TowerMotion, wt%twr%AD_P_2_AD_L_T, errStat2, errMsg2); if(Failed()) return - endif - endif - enddo ! iWT, rotors - - ! --- Inflow on points - call Set_IW_Inputs(nt, dvr, AD%u(1), AD%OtherState, IW%u(1), errStat2, errMsg2); if(Failed()) return - if (dvr%CompInflow==1) then - call InflowWind_CalcOutput(AD%inputTime(1), IW%u(1), IW%p, IW%x, IW%xd, IW%z, IW%OtherSt, IW%y, IW%m, errStat2, errMsg2); if (Failed()) return - else - do j=1,size(IW%u(1)%PositionXYZ,2) - z = IW%u(1)%PositionXYZ(3,j) - IW%y%VelocityUVW(1,j) = dvr%HWindSpeed*(z/dvr%RefHt)**dvr%PLExp - IW%y%VelocityUVW(2,j) = 0.0_ReKi !V - IW%y%VelocityUVW(3,j) = 0.0_ReKi !W - end do - endif - call AD_InputSolve_IfW(AD%u(1), IW%y, errStat2, errMsg2); if(Failed()) return - -contains - logical function Failed() - call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Set_AD_Inputs') - Failed = ErrStat >= AbortErrLev - end function Failed -end subroutine Set_AD_Inputs - -!> Set inputs for inflow wind -!! Similar to FAST_Solver, IfW_InputSolve -subroutine Set_IW_Inputs(nt,dvr,u_AD,o_AD,u_IfW,errStat,errMsg) - integer(IntKi) , intent(in ) :: nt ! time step number - type(Dvr_SimData), target, intent(in ) :: dvr ! Driver data - type(AD_InputType), intent(in ) :: u_AD ! AeroDyn data - type(AD_OtherStateType), intent(in ) :: o_AD ! AeroDyn data - type(InflowWind_InputType), intent(inout) :: u_IfW ! InflowWind data - integer(IntKi) , intent( out) :: errStat ! Status of error message - character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - integer :: k,j,node, iWT - ErrStat = ErrID_None - ErrMsg = '' - Node=0 - - - ! Order important! - - ! Hub Height point for each turbine - do iWT=1,dvr%numTurbines - Node = Node + 1 - u_IfW%PositionXYZ(:,Node) = dvr%wt(iWT)%hub%ptMesh%Position(:,1) + dvr%wt(iWT)%hub%ptMesh%TranslationDisp(:,1) - enddo - - do iWT=1,dvr%numTurbines - ! Blade - do K = 1,SIZE(u_AD%rotors(iWT)%BladeMotion) - do J = 1,u_AD%rotors(iWT)%BladeMotion(k)%Nnodes - Node = Node + 1 - u_IfW%PositionXYZ(:,Node) = u_AD%rotors(iWT)%BladeMotion(k)%TranslationDisp(:,j) + u_AD%rotors(iWT)%BladeMotion(k)%Position(:,j) - end do !J = 1,p%BldNodes ! Loop through the blade nodes / elements - end do !K = 1,p%NumBl - ! Tower - do J=1,u_AD%rotors(iWT)%TowerMotion%nnodes - Node = Node + 1 - u_IfW%PositionXYZ(:,Node) = u_AD%rotors(iWT)%TowerMotion%TranslationDisp(:,J) + u_AD%rotors(iWT)%TowerMotion%Position(:,J) - end do - ! Nacelle - if (u_AD%rotors(iWT)%NacelleMotion%Committed) then - Node = Node + 1 - u_IfW%PositionXYZ(:,Node) = u_AD%rotors(iWT)%NacelleMotion%TranslationDisp(:,1) + u_AD%rotors(iWT)%NacelleMotion%Position(:,1) - end if - ! Hub - - enddo ! iWT - ! vortex points from FVW in AD15 - if (allocated(o_AD%WakeLocationPoints)) then - do J=1,size(o_AD%WakeLocationPoints,DIM=2) - Node = Node + 1 - u_IfW%PositionXYZ(:,Node) = o_AD%WakeLocationPoints(:,J) - ! rewrite the history of this so that extrapolation doesn't make a mess of things -! do k=2,size(IW%u) -! if (allocated(IW%u(k)%PositionXYZ)) IW%u(k)%PositionXYZ(:,Node) = IW%u(1)%PositionXYZ(:,Node) -! end do - enddo !j, wake points - end if -end subroutine Set_IW_Inputs - -!> This routine sets the AeroDyn wind inflow inputs. -!! See similar routine in FAST_Solver -subroutine AD_InputSolve_IfW(u_AD, y_IfW, errStat, errMsg) - ! Passed variables - TYPE(AD_InputType), INTENT(INOUT) :: u_AD !< The inputs to AeroDyn - TYPE(InflowWind_OutputType), INTENT(IN) :: y_IfW !< The outputs from InflowWind - INTEGER(IntKi) :: errStat !< Error status of the operation - CHARACTER(*) :: errMsg !< Error message if ErrStat /= ErrID_None - ! Local variables: - INTEGER(IntKi) :: J ! Loops through nodes / elements. - INTEGER(IntKi) :: K ! Loops through blades. - INTEGER(IntKi) :: NumBl - INTEGER(IntKi) :: NNodes - INTEGER(IntKi) :: node - INTEGER(IntKi) :: iWT - errStat = ErrID_None - errMsg = "" - node = 1 - - ! Order important! - - do iWT=1,size(u_AD%rotors) - node = node + 1 ! Hub velocities for each rotor - enddo - - do iWT=1,size(u_AD%rotors) - NumBl = size(u_AD%rotors(iWT)%InflowOnBlade,3) - Nnodes = size(u_AD%rotors(iWT)%InflowOnBlade,2) - ! Blades - do k=1,NumBl - do j=1,Nnodes - u_AD%rotors(iWT)%InflowOnBlade(:,j,k) = y_IfW%VelocityUVW(:,node) - node = node + 1 - end do - end do - ! Tower - if ( allocated(u_AD%rotors(iWT)%InflowOnTower) ) then - Nnodes = size(u_AD%rotors(iWT)%InflowOnTower,2) - do j=1,Nnodes - u_AD%rotors(iWT)%InflowOnTower(:,j) = y_IfW%VelocityUVW(:,node) - node = node + 1 - end do - end if - ! Nacelle - if (u_AD%rotors(iWT)%NacelleMotion%NNodes > 0) then - u_AD%rotors(iWT)%InflowOnNacelle(:) = y_IfW%VelocityUVW(:,node) - node = node + 1 - else - u_AD%rotors(iWT)%InflowOnNacelle = 0.0_ReKi - end if - ! Hub -! if (u_AD%HubMotion%NNodes > 0) then -! u_AD%InflowOnHub(:) = y_IfW%VelocityUVW(:,node) -! node = node + 1 -! else -! u_AD%InflowOnHub = 0.0_ReKi -! end if - enddo ! rotors - ! OLAF points - if ( allocated(u_AD%InflowWakeVel) ) then - Nnodes = size(u_AD%InflowWakeVel,DIM=2) - do j=1,Nnodes - u_AD%InflowWakeVel(:,j) = y_IfW%VelocityUVW(:,node) - node = node + 1 - end do !j, wake points - end if -end subroutine AD_InputSolve_IfW - - + ADI%inputTimes(1) = dvr%dT * nt ! time at "nt+1" +end subroutine Shift_ADI_Inputs !---------------------------------------------------------------------------------------------------------------------------------- !> Read the driver input file @@ -1264,8 +927,8 @@ subroutine Dvr_ReadInputFile(fileName, dvr, errStat, errMsg ) ! Basic inputs real(ReKi) :: hubRad, hubHt, overhang, shftTilt, precone, twr2Shft ! Basic inputs when basicHAWTFormat is true real(ReKi) :: nacYaw, bldPitch, rotSpeed - ErrStat = ErrID_None - ErrMsg = '' + errStat = ErrID_None + errMsg = '' UnIn = -1 UnEc = -1 @@ -1307,30 +970,30 @@ subroutine Dvr_ReadInputFile(fileName, dvr, errStat, errMsg ) ! --- Inflow data call ParseCom(FileInfo_In, CurLine, Line, errStat2, errMsg2, unEc); if (Failed()) return - call ParseVar(FileInfo_In, CurLine, "compInflow", dvr%compInflow , errStat2, errMsg2, unEc); if (Failed()) return - call ParseVar(FileInfo_In, CurLine, "InflowFile", dvr%IW_InputFile, errStat2, errMsg2, unEc); if (Failed()) return - if (dvr%compInflow==0) then - call ParseVar(FileInfo_In, CurLine, "HWindSpeed", dvr%HWindSpeed , errStat2, errMsg2, unEc); if (Failed()) return - call ParseVar(FileInfo_In, CurLine, "RefHt" , dvr%RefHt , errStat2, errMsg2, unEc); if (Failed()) return - call ParseVar(FileInfo_In, CurLine, "PLExp" , dvr%PLExp , errStat2, errMsg2, unEc); if (Failed()) return + call ParseVar(FileInfo_In, CurLine, "compInflow", dvr%IW_InitInp%compInflow , errStat2, errMsg2, unEc); if (Failed()) return + call ParseVar(FileInfo_In, CurLine, "InflowFile", dvr%IW_InitInp%InputFile, errStat2, errMsg2, unEc); if (Failed()) return + if (dvr%IW_InitInp%compInflow==0) then + call ParseVar(FileInfo_In, CurLine, "HWindSpeed", dvr%IW_InitInp%HWindSpeed , errStat2, errMsg2, unEc); if (Failed()) return + call ParseVar(FileInfo_In, CurLine, "RefHt" , dvr%IW_InitInp%RefHt , errStat2, errMsg2, unEc); if (Failed()) return + call ParseVar(FileInfo_In, CurLine, "PLExp" , dvr%IW_InitInp%PLExp , errStat2, errMsg2, unEc); if (Failed()) return else call ParseCom(FileInfo_In, CurLine, Line, errStat2, errMsg2, unEc); if (Failed()) return call ParseCom(FileInfo_In, CurLine, Line, errStat2, errMsg2, unEc); if (Failed()) return call ParseCom(FileInfo_In, CurLine, Line, errStat2, errMsg2, unEc); if (Failed()) return - dvr%PLexp = myNaN - dvr%RefHt = myNaN - dvr%HWindSpeed = myNaN + dvr%IW_InitInp%PLexp = myNaN + dvr%IW_InitInp%RefHt = myNaN + dvr%IW_InitInp%HWindSpeed = myNaN endif if (PathIsRelative(dvr%AD_InputFile)) dvr%AD_InputFile = trim(PriPath)//trim(dvr%AD_InputFile) - if (PathIsRelative(dvr%IW_InputFile)) dvr%IW_InputFile = trim(PriPath)//trim(dvr%IW_InputFile) + if (PathIsRelative(dvr%IW_InitInp%InputFile)) dvr%IW_InitInp%InputFile = trim(PriPath)//trim(dvr%IW_InitInp%InputFile) ! --- Turbines call ParseCom(FileInfo_In, CurLine, Line, errStat2, errMsg2, unEc); if (Failed()) return call ParseVar(FileInfo_In, CurLine, "numTurbines", dvr%numTurbines, errStat2, errMsg2, unEc); if (Failed()) return - allocate(dvr%WT(dvr%numTurbines), stat=ErrStat2) - if (ErrStat2 /=0) then - ErrStat2=ErrID_Fatal + allocate(dvr%WT(dvr%numTurbines), stat=errStat2) + if (errStat2 /=0) then + errStat2=ErrID_Fatal ErrMsg2="Error allocating dvr%WT." if(Failed()) return end if @@ -1339,6 +1002,15 @@ subroutine Dvr_ReadInputFile(fileName, dvr, errStat, errMsg ) wt => dvr%WT(iWT) sWT = '('//trim(num2lstr(iWT))//')' call ParseCom(FileInfo_In, CurLine, Line, errStat2, errMsg2, unEc); if(Failed()) return + ! Temporary hack, look if ProjMod is present on the line + !call ParseVar(FileInfo_In, CurLine, 'ProjMod'//sWT , wt%projMod , errStat2, errMsg2, unEc); if(Failed()) return + call ParseVar(FileInfo_In, CurLine, 'ProjMod'//sWT , wt%projMod , errStat2, errMsg2, unEc); + if (errStat2==ErrID_Fatal) then + wt%projMod = -1 + wt%BEM_Mod = -1 + else + call ParseVar(FileInfo_In, CurLine, 'BEM_Mod'//sWT , wt%BEM_Mod , errStat2, errMsg2, unEc); if(Failed()) return + endif call ParseVar(FileInfo_In, CurLine, 'BasicHAWTFormat'//sWT , wt%basicHAWTFormat , errStat2, errMsg2, unEc); if(Failed()) return ! Basic init @@ -1349,6 +1021,9 @@ subroutine Dvr_ReadInputFile(fileName, dvr, errStat, errMsg ) if (wt%BasicHAWTFormat) then ! --- Basic Geometry call ParseAry(FileInfo_In, CurLine, 'baseOriginInit'//sWT , wt%originInit , 3 , errStat2, errMsg2 , unEc); if(Failed()) return + if ( dvr%MHK == 1 ) then + wt%originInit(3) = wt%originInit(3) - dvr%WtrDpth + end if call ParseVar(FileInfo_In, CurLine, 'numBlades'//sWT , wt%numBlades , errStat2, errMsg2 , unEc); if(Failed()) return call ParseVar(FileInfo_In, CurLine, 'hubRad'//sWT , hubRad , errStat2, errMsg2 , unEc); if(Failed()) return call ParseVar(FileInfo_In, CurLine, 'hubHt'//sWT , hubHt , errStat2, errMsg2 , unEc); if(Failed()) return @@ -1384,6 +1059,9 @@ subroutine Dvr_ReadInputFile(fileName, dvr, errStat, errMsg ) ! --- Advanced geometry ! Rotor origin and orientation call ParseAry(FileInfo_In, CurLine, 'baseOriginInit'//sWT , wt%originInit, 3 , errStat2, errMsg2, unEc); if(Failed()) return + if ( dvr%MHK == 1 ) then + wt%originInit(3) = wt%originInit(3) - dvr%WtrDpth + end if call ParseAry(FileInfo_In, CurLine, 'baseOrientationInit'//sWT, wt%orientationInit, 3 , errStat2, errMsg2, unEc); if(Failed()) return call ParseVar(FileInfo_In, CurLine, 'hasTower'//sWT , wt%hasTower , errStat2, errMsg2, unEc); if(Failed()) return call ParseVar(FileInfo_In, CurLine, 'HAWTprojection'//sWT , wt%HAWTprojection , errStat2, errMsg2, unEc); if(Failed()) return @@ -1391,15 +1069,15 @@ subroutine Dvr_ReadInputFile(fileName, dvr, errStat, errMsg ) call ParseAry(FileInfo_In, CurLine, 'nacOrigin_t'//sWT , wt%nac%origin_t, 3 , errStat2, errMsg2, unEc); if(Failed()) return call ParseAry(FileInfo_In, CurLine, 'hubOrigin_n'//sWT , wt%hub%origin_n, 3 , errStat2, errMsg2, unEc); if(Failed()) return call ParseAry(FileInfo_In, CurLine, 'hubOrientation_n'//sWT , wt%hub%orientation_n, 3 , errStat2, errMsg2, unEc); if(Failed()) return - wt%hub%orientation_n = wt%hub%orientation_n*Pi/180_ReKi - wt%orientationInit = wt%orientationInit*Pi/180_ReKi + wt%hub%orientation_n = wt%hub%orientation_n*D2R + wt%orientationInit = wt%orientationInit*D2R ! Blades call ParseCom(FileInfo_In, CurLine, Line, errStat2, errMsg2, unEc); if(Failed()) return call ParseVar(FileInfo_In, CurLine, 'numBlades'//sWT , wt%numBlades, errStat2, errMsg2, unEc); if(Failed()) return - allocate(wt%bld(wt%numBlades), stat=ErrStat2) + allocate(wt%bld(wt%numBlades), stat=errStat2) if (errStat2 /= 0) then - ErrStat2=ErrID_Fatal - ErrMsg2 = "Error allocating wt%bld" + errStat2=ErrID_Fatal + errMsg2 = "Error allocating wt%bld" if(Failed()) return end if @@ -1587,6 +1265,7 @@ subroutine Dvr_ReadInputFile(fileName, dvr, errStat, errMsg ) call ParseVar(FileInfo_In, CurLine, 'outFmt' , dvr%out%outFmt , errStat2, errMsg2, unEc); if(Failed()) return call ParseVar(FileInfo_In, CurLine, 'outFileFmt' , dvr%out%fileFmt , errStat2, errMsg2, unEc); if(Failed()) return call ParseVar(FileInfo_In, CurLine, 'WrVTK' , dvr%out%WrVTK , errStat2, errMsg2, unEc); if(Failed()) return + call ParseVar(FileInfo_In, CurLine, 'WrVTK_Type' , dvr%out%WrVTK_Type , errStat2, errMsg2, unEc); if(Failed()) return call ParseVar(FileInfo_In, CurLine, 'VTKHubRad' , hubRad_ReKi , errStat2, errMsg2, unEc); if(Failed()) return call ParseAry(FileInfo_In, CurLine, 'VTKNacDim' , dvr%out%VTKNacDim, 6, errStat2, errMsg2, unEc); if(Failed()) return dvr%out%VTKHubRad = real(hubRad_ReKi,SiKi) @@ -1602,14 +1281,14 @@ logical function Check(Condition, ErrMsg_in) character(len=*), intent(in) :: ErrMsg_in Check=Condition if (Check) then - call SetErrStat(ErrID_Fatal, trim(ErrMsg_in), ErrStat, ErrMsg, 'Dvr_ReadInputFile'); + call SetErrStat(ErrID_Fatal, trim(ErrMsg_in), errStat, errMsg, 'Dvr_ReadInputFile'); endif end function Check subroutine CleanUp() if (UnIn>0) close(UnIn) if (UnEc>0) close(UnEc) - CALL NWTC_Library_Destroyfileinfotype(FileInfo_In, ErrStat2, ErrMsg2) + CALL NWTC_Library_Destroyfileinfotype(FileInfo_In, errStat2, errMsg2) end subroutine cleanup logical function Failed() @@ -1620,7 +1299,8 @@ logical function Failed() endif end function Failed end subroutine Dvr_ReadInputFile - +!---------------------------------------------------------------------------------------------------------------------------------- +!> Set simple motion on this turbine subroutine setSimpleMotion(wt, rotSpeed, bldPitch, nacYaw, DOF, amplitude, frequency) type(WTData), intent(inout) :: wt real(ReKi), intent(in ) :: rotSpeed ! rpm @@ -1645,9 +1325,8 @@ subroutine setSimpleMotion(wt, rotSpeed, bldPitch, nacYaw, DOF, amplitude, frequ end do end if end subroutine setSimpleMotion - - !---------------------------------------------------------------------------------------------------------------------------------- +!> Validate inputs read from input file subroutine ValidateInputs(dvr, errStat, errMsg) type(Dvr_SimData), target, intent(inout) :: dvr ! intent(out) only so that we can save FmtWidth in dvr%out%ActualChanLen integer, intent( out) :: errStat ! returns a non-zero value when an error occurs @@ -1655,31 +1334,28 @@ subroutine ValidateInputs(dvr, errStat, errMsg) ! local variables: integer(intKi) :: i integer(intKi) :: FmtWidth ! number of characters in string produced by dvr%OutFmt - integer(intKi) :: ErrStat2 ! temporary Error status + integer(intKi) :: errStat2 ! temporary Error status character(ErrMsgLen) :: ErrMsg2 ! temporary Error message character(*), parameter :: RoutineName = 'ValidateInputs' integer :: iWT, iB type(WTData), pointer :: wt ! Alias to shorten notation - ErrStat = ErrID_None - ErrMsg = "" + errStat = ErrID_None + errMsg = "" ! Turbine Data: - !if ( dvr%numBlades < 1 ) call SetErrStat( ErrID_Fatal, "There must be at least 1 blade (numBlades).", ErrStat, ErrMsg, RoutineName) + !if ( dvr%numBlades < 1 ) call SetErrStat( ErrID_Fatal, "There must be at least 1 blade (numBlades).", errStat, ErrMsg, RoutineName) ! Combined-Case Analysis: - if (dvr%MHK /= 0 ) call SetErrStat(ErrID_Fatal, 'MHK switch must be 0. Functionality to model an MHK turbine has not yet been implemented.', ErrStat, ErrMsg, RoutineName) ! hkr (4/6/21) Remove after MHK functionality is implemented if (dvr%MHK /= 0 .and. dvr%MHK /= 1 .and. dvr%MHK /= 2) call SetErrStat(ErrID_Fatal, 'MHK switch must be 0, 1, or 2.', ErrStat, ErrMsg, RoutineName) - if (dvr%MHK == 2) call SetErrStat(ErrID_Fatal, 'Functionality to model a floating MHK turbine has not yet been implemented.', ErrStat, ErrMsg, RoutineName) - if (dvr%DT < epsilon(0.0_ReKi) ) call SetErrStat(ErrID_Fatal,'dT must be larger than 0.',ErrStat, ErrMsg,RoutineName) - if (Check(.not.(ANY((/0,1/) == dvr%compInflow) ), 'CompInflow needs to be 0 or 1')) return + if (dvr%DT < epsilon(0.0_ReKi) ) call SetErrStat(ErrID_Fatal,'dT must be larger than 0.',errStat, errMsg,RoutineName) + if (Check(.not.(ANY((/0,1/) == dvr%IW_InitInp%compInflow) ), 'CompInflow needs to be 0 or 1')) return if (Check(.not.(ANY(idAnalysisVALID == dvr%analysisType )), 'Analysis type not supported: '//trim(Num2LStr(dvr%analysisType)) )) return if (dvr%analysisType==idAnalysisTimeD .or. dvr%analysisType==idAnalysisCombi) then - if (Check( dvr%CompInflow/=0, 'CompInflow needs to be 0 when analysis type is '//trim(Num2LStr(dvr%analysisType)))) return + if (Check( dvr%IW_InitInp%CompInflow/=0, 'CompInflow needs to be 0 when analysis type is '//trim(Num2LStr(dvr%analysisType)))) return endif - if (dvr%WtrDpth < 0.0_ReKi) call SetErrStat(ErrID_Fatal, 'WtrDpth must not be negative.', ErrStat, ErrMsg, RoutineName) do iWT=1,dvr%numTurbines wt => dvr%WT(iWT) @@ -1698,10 +1374,16 @@ subroutine ValidateInputs(dvr, errStat, errMsg) ! --- I-O Settings: if (Check(.not.(ANY(idFmtVALID == dvr%out%fileFmt)), 'fileFmt not supported: '//trim(Num2LStr(dvr%out%fileFmt)) )) return - call ChkRealFmtStr( dvr%out%OutFmt, 'OutFmt', FmtWidth, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call ChkRealFmtStr( dvr%out%OutFmt, 'OutFmt', FmtWidth, errStat2, errMsg2 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) !if ( FmtWidth < MinChanLen ) call SetErrStat( ErrID_Warn, 'OutFmt produces a column less than '//trim(num2lstr(MinChanLen))//' characters wide ('// & - ! TRIM(Num2LStr(FmtWidth))//'), which may be too small.', ErrStat, ErrMsg, RoutineName ) + ! TRIM(Num2LStr(FmtWidth))//'), which may be too small.', errStat, errMsg, RoutineName ) + + if (Check((dvr%out%WrVTK<0 .or. dvr%out%WrVTK>2 ), 'WrVTK must be 0 (none), 1 (initialization only), 2 (animation), or 3 (mode shapes).')) then + return + else + if (Check((dvr%out%WrVTK_Type<1 .or. dvr%out%WrVTK_Type>3), 'VTK_type must be 1 (surfaces), 2 (lines/points), or 3 (both).')) return + endif contains @@ -1710,19 +1392,19 @@ logical function Check(Condition, ErrMsg_in) character(len=*), intent(in) :: ErrMsg_in Check=Condition if (Check) then - call SetErrStat(ErrID_Fatal, trim(ErrMsg_in), ErrStat, ErrMsg, 'ValidateInputs'); + call SetErrStat(ErrID_Fatal, trim(ErrMsg_in), errStat, errMsg, 'ValidateInputs'); endif end function Check end subroutine ValidateInputs - !---------------------------------------------------------------------------------------------------------------------------------- +!> Initialize outputs to file for driver subroutine Dvr_InitializeOutputs(nWT, out, numSteps, errStat, errMsg) integer(IntKi) , intent(in ) :: nWT ! Number of time steps - type(Dvr_Outputs), intent(inout) :: out + type(Dvr_Outputs), intent(inout) :: out integer(IntKi) , intent(in ) :: numSteps ! Number of time steps integer(IntKi) , intent( out) :: errStat ! Status of error message - character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + character(*) , intent( out) :: errMsg ! Error message if errStat /= ErrID_None ! locals integer(IntKi) :: i integer(IntKi) :: numSpaces @@ -1763,13 +1445,13 @@ subroutine Dvr_InitializeOutputs(nWT, out, numSteps, errStat, errMsg) else sWT = '' endif - call GetNewUnit(out%unOutFile(iWT), ErrStat, ErrMsg) - if ( ErrStat >= AbortErrLev ) then + call GetNewUnit(out%unOutFile(iWT), errStat, errMsg) + if ( errStat >= AbortErrLev ) then out%unOutFile(iWT) = -1 return end if - call OpenFOutFile ( out%unOutFile(iWT), trim(out%Root)//trim(sWT)//'.out', ErrStat, ErrMsg ) - if ( ErrStat >= AbortErrLev ) return + call OpenFOutFile ( out%unOutFile(iWT), trim(out%Root)//trim(sWT)//'.out', errStat, errMsg ) + if ( errStat >= AbortErrLev ) return write (out%unOutFile(iWT),'(/,A)') 'Predictions were generated on '//CurDate()//' at '//CurTime()//' using '//trim( version%Name ) write (out%unOutFile(iWT),'(1X,A)') trim(GetNVD(out%AD_ver)) write (out%unOutFile(iWT),'()' ) !print a blank line @@ -1800,11 +1482,17 @@ end subroutine Dvr_InitializeOutputs !---------------------------------------------------------------------------------------------------------------------------------- !> Initialize driver (not module-level) output channels !! Output channels are constant for all cases and all turbines for now! -subroutine Dvr_InitializeDriverOutputs(dvr, errStat, errMsg) - type(Dvr_SimData), intent(inout) :: dvr ! driver data - integer(IntKi) , intent( out) :: errStat ! Status of error message - character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - integer :: maxNumBlades, k, j, iWT +subroutine Dvr_InitializeDriverOutputs(dvr, ADI, errStat, errMsg) + type(Dvr_SimData), intent(inout) :: dvr ! driver data + type(ADI_Data), intent(inout) :: ADI ! Input data for initialization (intent out for getting AD WriteOutput names/units) + integer(IntKi) , intent( out) :: errStat ! Status of error message + character(*) , intent( out) :: errMsg ! Error message if errStat /= ErrID_None + character(len=ChanLen), dimension(:), allocatable :: userSwapHdr !< Array of headers for user Swap Array + character(len=ChanLen), dimension(:), allocatable :: userSwapUnt !< Array of units for user Swap Array + integer :: maxNumBlades, k, j, iWT + logical :: hasSwapArray ! small hack, if a swap array is present NOTE: we don't know the size of it... + integer(IntKi) :: errStat2 ! Status of error message + character(ErrMsgLen) :: errMsg2 ! Error message errStat = ErrID_None errMsg = '' @@ -1815,69 +1503,88 @@ subroutine Dvr_InitializeDriverOutputs(dvr, errStat, errMsg) ! --- Allocate driver-level outputs dvr%out%nDvrOutputs = 1+ 4 + 6 + 3 + 1*maxNumBlades ! - allocate(dvr%out%WriteOutputHdr(1+dvr%out%nDvrOutputs)) - allocate(dvr%out%WriteOutputUnt(1+dvr%out%nDvrOutputs)) + + ! Initialize swap arrays + hasSwapArray=.false. do iWT =1,dvr%numTurbines - allocate(dvr%WT(iWT)%WriteOutput(1+dvr%out%nDvrOutputs)) + ! NOTE: same swap array for all turbines (outputs are expected to the same for all turbines) + if (dvr%WT(iWT)%hub%motionType == idHubMotionUserFunction) then + hasSwapArray=.true. + if (allocated(userSwapHdr)) deallocate(userSwapHdr) + if (allocated(userSwapUnt)) deallocate(userSwapUnt) + call userHubMotion_Init(dvr%wt(iWT)%userSwapArray, userSwapHdr, userSwapUnt, errStat2, errMsg2); if(Failed()) return + endif enddo + if (hasSwapArray) then + dvr%out%nDvrOutputs = dvr%out%nDvrOutputs + size(userSwapHdr) + endif - j=1 - dvr%out%WriteOutputHdr(j) = 'Time' - dvr%out%WriteOutputUnt(j) = '(s)' ; j=j+1 - dvr%out%WriteOutputHdr(j) = 'Case' - dvr%out%WriteOutputUnt(j) = '(-)' ; j=j+1 - - dvr%out%WriteOutputHdr(j) = 'HWindSpeedX' - dvr%out%WriteOutputUnt(j) = '(m/s)'; j=j+1 - dvr%out%WriteOutputHdr(j) = 'HWindSpeedY' - dvr%out%WriteOutputUnt(j) = '(m/s)'; j=j+1 - dvr%out%WriteOutputHdr(j) = 'HWindSpeedZ' - dvr%out%WriteOutputUnt(j) = '(m/s)'; j=j+1 + call AllocAry(dvr%out%WriteOutputHdr, 1+dvr%out%nDvrOutputs, 'WriteOutputHdr', errStat2, errMsg2); if(Failed()) return + call AllocAry(dvr%out%WriteOutputUnt, 1+dvr%out%nDvrOutputs, 'WriteOutputUnt', errStat2, errMsg2); if(Failed()) return + do iWT =1,dvr%numTurbines + call AllocAry(dvr%WT(iWT)%WriteOutput, 1+dvr%out%nDvrOutputs, 'WriteOutputWT', errStat2, errMsg2);if(Failed()) return + enddo + + j=1 + dvr%out%WriteOutputHdr(j) = 'Time' ; dvr%out%WriteOutputUnt(j) = '(s)' ; j=j+1 + dvr%out%WriteOutputHdr(j) = 'Case' ; dvr%out%WriteOutputUnt(j) = '(-)' ; j=j+1 + dvr%out%WriteOutputHdr(j) = 'HWindSpeedX' ; dvr%out%WriteOutputUnt(j) = '(m/s)'; j=j+1 + dvr%out%WriteOutputHdr(j) = 'HWindSpeedY' ; dvr%out%WriteOutputUnt(j) = '(m/s)'; j=j+1 + dvr%out%WriteOutputHdr(j) = 'HWindSpeedZ' ; dvr%out%WriteOutputUnt(j) = '(m/s)'; j=j+1 dvr%out%WriteOutputHdr(j) = 'ShearExp' - if (dvr%CompInflow==1) then - dvr%out%WriteOutputUnt(j) = '(NVALID)'; j=j+1 + if (ADI%m%IW%CompInflow==1) then + dvr%out%WriteOutputUnt(j) = '(INVALID)'; j=j+1 else dvr%out%WriteOutputUnt(j) = '(-)'; j=j+1 endif - - dvr%out%WriteOutputHdr(j) = 'PtfmSurge' - dvr%out%WriteOutputUnt(j) = '(m)'; j=j+1 - dvr%out%WriteOutputHdr(j) = 'PtfmSway' - dvr%out%WriteOutputUnt(j) = '(m)'; j=j+1 - dvr%out%WriteOutputHdr(j) = 'PtfmHeave' - dvr%out%WriteOutputUnt(j) = '(m)'; j=j+1 - dvr%out%WriteOutputHdr(j) = 'PtfmRoll' - dvr%out%WriteOutputUnt(j) = '(deg)'; j=j+1 - dvr%out%WriteOutputHdr(j) = 'PtfmPitch' - dvr%out%WriteOutputUnt(j) = '(deg)'; j=j+1 - dvr%out%WriteOutputHdr(j) = 'PtfmYaw' - dvr%out%WriteOutputUnt(j) = '(deg)'; j=j+1 - - dvr%out%WriteOutputHdr(j) = 'Yaw' - dvr%out%WriteOutputUnt(j) = '(deg)'; j=j+1 - dvr%out%WriteOutputHdr(j) = 'Azimuth' - dvr%out%WriteOutputUnt(j) = '(deg)'; j=j+1 - dvr%out%WriteOutputHdr(j) = 'RotSpeed' - dvr%out%WriteOutputUnt(j) = '(rpm)'; j=j+1 + dvr%out%WriteOutputHdr(j) = 'PtfmSurge' ; dvr%out%WriteOutputUnt(j) = '(m)' ; j=j+1 + dvr%out%WriteOutputHdr(j) = 'PtfmSway' ; dvr%out%WriteOutputUnt(j) = '(m)' ; j=j+1 + dvr%out%WriteOutputHdr(j) = 'PtfmHeave' ; dvr%out%WriteOutputUnt(j) = '(m)' ; j=j+1 + dvr%out%WriteOutputHdr(j) = 'PtfmRoll' ; dvr%out%WriteOutputUnt(j) = '(deg)'; j=j+1 + dvr%out%WriteOutputHdr(j) = 'PtfmPitch' ; dvr%out%WriteOutputUnt(j) = '(deg)'; j=j+1 + dvr%out%WriteOutputHdr(j) = 'PtfmYaw' ; dvr%out%WriteOutputUnt(j) = '(deg)'; j=j+1 + dvr%out%WriteOutputHdr(j) = 'Yaw' ; dvr%out%WriteOutputUnt(j) = '(deg)'; j=j+1 + dvr%out%WriteOutputHdr(j) = 'Azimuth' ; dvr%out%WriteOutputUnt(j) = '(deg)'; j=j+1 + dvr%out%WriteOutputHdr(j) = 'RotSpeed' ; dvr%out%WriteOutputUnt(j) = '(rpm)'; j=j+1 do k =1,maxNumBlades dvr%out%WriteOutputHdr(j) = 'BldPitch'//trim(num2lstr(k)) dvr%out%WriteOutputUnt(j) = '(deg)'; j=j+1 enddo + if (hasSwapArray) then + do k =1,size(userSwapHdr) + dvr%out%WriteOutputHdr(j) = userSwapHdr(k) + dvr%out%WriteOutputUnt(j) = userSwapUnt(k) + j=j+1 + enddo + endif +contains + logical function Failed() + CALL SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Dvr_InitializeDriverOutputs' ) + Failed = errStat >= AbortErrLev + if (Failed) then + if (allocated(userSwapHdr)) deallocate(userSwapHdr) + if (allocated(userSwapUnt)) deallocate(userSwapUnt) + endif + end function Failed end subroutine Dvr_InitializeDriverOutputs !---------------------------------------------------------------------------------------------------------------------------------- !> Store driver data -subroutine Dvr_CalcOutputDriver(dvr, y_Ifw, errStat, errMsg) +subroutine Dvr_CalcOutputDriver(dvr, y_ADI, FED, errStat, errMsg) type(Dvr_SimData), target, intent(inout) :: dvr ! driver data - type(InflowWind_OutputType), intent(in ) :: y_Ifw ! driver data - integer(IntKi) , intent( out) :: errStat ! Status of error message - character(*) , intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + type(FED_Data), target, intent(in ) :: FED !< Elastic wind turbine data (Fake ElastoDyn) + type(ADI_OutputType), intent(in ) :: y_ADI ! ADI output data + integer(IntKi) , intent( out) :: errStat ! Status of error message + character(*) , intent( out) :: errMsg ! Error message if errStat /= ErrID_None integer :: maxNumBlades, k, j, iWT real(ReKi) :: rotations(3) integer(IntKi) :: errStat2 ! Status of error message character(ErrMsgLen) :: errMsg2 ! Error message - real(ReKi), pointer :: arr(:) + real(ReKi), pointer :: arr(:) + type(WTData), pointer :: wt ! Alias to shorten notation + type(RotFED), pointer :: y_ED ! Alias to shorten notation + errStat = ErrID_None errMsg = '' @@ -1885,53 +1592,63 @@ subroutine Dvr_CalcOutputDriver(dvr, y_Ifw, errStat, errMsg) do iWT=1,size(dvr%WT) maxNumBlades= max(maxNumBlades, dvr%WT(iWT)%numBlades) end do + + ! Determine if a swap array is present do iWT = 1, dvr%numTurbines + wt => dvr%wt(iWT) + y_ED => FED%wt(iWT) if (dvr%wt(iWT)%numBlades >0 ) then ! TODO, export for tower only arr => dvr%wt(iWT)%WriteOutput k=1 ! NOTE: to do this properly we would need to store at the previous time step and perform a rotation - arr(k) = dvr%iCase ; k=k+1 + arr(k) = dvr%iCase ; k=k+1 ! Environment - arr(k) = y_Ifw%VelocityUVW(1, iWT) ; k=k+1 ! NOTE: stored at beginning of array - arr(k) = y_Ifw%VelocityUVW(2, iWT) ; k=k+1 - arr(k) = y_Ifw%VelocityUVW(3, iWT) ; k=k+1 - arr(k) = dvr%PLExp ; k=k+1 ! shear exp, not set if CompInflow=1 + arr(k) = y_ADI%HHVel(1, iWT) ; k=k+1 ! NOTE: stored at beginning of array + arr(k) = y_ADI%HHVel(2, iWT) ; k=k+1 + arr(k) = y_ADI%HHVel(3, iWT) ; k=k+1 + arr(k) = y_ADI%PLExp ; k=k+1 ! shear exp, not set if CompInflow=1 ! 6 base DOF - rotations = EulerExtract(dvr%WT(iWT)%ptMesh%Orientation(:,:,1)); - arr(k) = dvr%WT(iWT)%ptMesh%TranslationDisp(1,1); k=k+1 ! surge - arr(k) = dvr%WT(iWT)%ptMesh%TranslationDisp(2,1); k=k+1 ! sway - arr(k) = dvr%WT(iWT)%ptMesh%TranslationDisp(3,1); k=k+1 ! heave - arr(k) = rotations(1) * R2D ; k=k+1 ! roll - arr(k) = rotations(2) * R2D ; k=k+1 ! pitch - arr(k) = rotations(3) * R2D ; k=k+1 ! yaw + rotations = EulerExtract(y_ED%PlatformPtMesh%Orientation(:,:,1)); + arr(k) = y_ED%PlatformPtMesh%TranslationDisp(1,1); k=k+1 ! surge + arr(k) = y_ED%PlatformPtMesh%TranslationDisp(2,1); k=k+1 ! sway + arr(k) = y_ED%PlatformPtMesh%TranslationDisp(3,1); k=k+1 ! heave + arr(k) = rotations(1) * R2D ; k=k+1 ! roll + arr(k) = rotations(2) * R2D ; k=k+1 ! pitch + arr(k) = rotations(3) * R2D ; k=k+1 ! yaw ! RNA motion - arr(k) = dvr%WT(iWT)%nac%yaw*R2D ; k=k+1 ! yaw [deg] - arr(k) = modulo(real(dvr%WT(iWT)%hub%azimuth+(dvr%dt * dvr%WT(iWT)%hub%rotSpeed)*R2D, ReKi), 360.0_ReKi); k=k+1 ! azimuth [deg], stored at nt-1 - arr(k) = dvr%WT(iWT)%hub%rotSpeed*RPS2RPM; k=k+1 ! rotspeed [rpm] + arr(k) = wt%nac%yaw*R2D ; k=k+1 ! yaw [deg] + arr(k) = modulo(real(wt%hub%azimuth+(dvr%dt * wt%hub%rotSpeed)*R2D, ReKi), 360.0_ReKi); k=k+1 ! azimuth [deg], stored at nt-1 + arr(k) = wt%hub%rotSpeed*RPS2RPM; k=k+1 ! rotspeed [rpm] do j=1,maxNumBlades - if (j<=dvr%WT(iWT)%numBlades) then - arr(k) = dvr%WT(iWT)%bld(j)%pitch*R2D ! pitch [deg] + if (j<= wt%numBlades) then + arr(k) = wt%bld(j)%pitch*R2D ! pitch [deg] else arr(k) = 0.0_ReKi ! myNaN endif k=k+1; enddo + ! Swap array + if (wt%hub%motionType == idHubMotionUserFunction) then + do j=1,size(wt%userSwapArray) + arr(k) = wt%userSwapArray(j); k=k+1; + enddo + endif + endif enddo end subroutine Dvr_CalcOutputDriver !---------------------------------------------------------------------------------------------------------------------------------- -subroutine Dvr_WriteOutputs(nt, t, dvr, out, yAD, yIW, errStat, errMsg) +subroutine Dvr_WriteOutputs(nt, t, dvr, out, yADI, errStat, errMsg) integer(IntKi) , intent(in ) :: nt ! simulation time step real(DbKi) , intent(in ) :: t ! simulation time (s) - type(Dvr_SimData), intent(inout) :: dvr ! driver data - type(Dvr_Outputs) , intent(inout) :: out ! driver uotput options - type(AD_OutputType) , intent(in ) :: yAD ! aerodyn outputs - type(InflowWind_OutputType),intent(in ) :: yIW ! inflowwind outputs + type(Dvr_SimData), intent(inout) :: dvr ! driver data + type(Dvr_Outputs) , intent(inout) :: out ! driver uotput options + type(ADI_OutputType) , intent(in ) :: yADI ! aerodyn outputs integer(IntKi) , intent(inout) :: errStat ! Status of error message - character(*) , intent(inout) :: errMsg ! Error message if ErrStat /= ErrID_None + character(*) , intent(inout) :: errMsg ! Error message if errStat /= ErrID_None ! Local variables. character(ChanLen) :: tmpStr ! temporary string to print the time output as text integer :: nDV , nAD, nIW, iWT, k, j @@ -1942,17 +1659,17 @@ subroutine Dvr_WriteOutputs(nt, t, dvr, out, yAD, yIW, errStat, errMsg) errMsg = '' ! Packing all outputs excpet time into one array - nAD = size(yAD%rotors(1)%WriteOutput) - nIW = size(yIW%WriteOutput) + nAD = size(yADI%AD%rotors(1)%WriteOutput) + nIW = size(yADI%IW_WriteOutput) nDV = out%nDvrOutputs do iWT = 1, dvr%numTurbines if (dvr%wt(iWT)%numBlades >0 ) then ! TODO, export for tower only - out%outLine(1:nDV) = dvr%wt(iWT)%WriteOutput(1:nDV) + out%outLine(1:nDV) = dvr%wt(iWT)%WriteOutput(1:nDV) ! Driver Write Outputs ! out%outLine(11) = dvr%WT(iWT)%hub%azimuth ! azimuth already stored a nt-1 - out%outLine(nDV+1:nDV+nAD) = yAD%rotors(iWT)%WriteOutput - out%outLine(nDV+nAD+1:) = yIW%WriteOutput + out%outLine(nDV+1:nDV+nAD) = yADI%AD%rotors(iWT)%WriteOutput ! AeroDyn WriteOutputs + out%outLine(nDV+nAD+1:) = yADI%IW_WriteOutput ! InflowWind WriteOutputs if (out%fileFmt==idFmtBoth .or. out%fileFmt == idFmtAscii) then ! ASCII @@ -1969,15 +1686,16 @@ subroutine Dvr_WriteOutputs(nt, t, dvr, out, yAD, yIW, errStat, errMsg) endif endif enddo - end subroutine Dvr_WriteOutputs + +!---------------------------------------------------------------------------------------------------------------------------------- !> Read a delimited file with one line of header subroutine ReadDelimFile(Filename, nCol, Array, errStat, errMsg, nHeaderLines, priPath) character(len=*), intent(in) :: Filename integer, intent(in) :: nCol real(ReKi), dimension(:,:), allocatable, intent(out) :: Array integer(IntKi) , intent(out) :: errStat ! Status of error message - character(*) , intent(out) :: errMsg ! Error message if ErrStat /= ErrID_None + character(*) , intent(out) :: errMsg ! Error message if errStat /= ErrID_None integer(IntKi), optional, intent(in ) :: nHeaderLines character(*) , optional, intent(in ) :: priPath ! Primary path, to use if filename is not absolute integer :: UnIn, i, j, nLine, nHead @@ -1985,15 +1703,14 @@ subroutine ReadDelimFile(Filename, nCol, Array, errStat, errMsg, nHeaderLines, p integer(IntKi) :: errStat2 ! local status of error message character(ErrMsgLen) :: errMsg2 ! temporary Error message character(len=2048) :: Filename_Loc ! filename local to this function - ErrStat = ErrID_None - ErrMsg = "" + errStat = ErrID_None + errMsg = "" Filename_Loc = Filename if (present(priPath)) then if (PathIsRelative(Filename_Loc)) Filename_Loc = trim(PriPath)//trim(Filename) endif - ! Open file call GetNewUnit(UnIn) call OpenFInpFile(UnIn, Filename_Loc, errStat2, errMsg2); if(Failed()) return @@ -2025,6 +1742,7 @@ logical function Failed() end function Failed end subroutine ReadDelimFile +!---------------------------------------------------------------------------------------------------------------------------------- !> Counts number of lines in a file integer function line_count(iunit) integer, intent(in) :: iunit @@ -2047,7 +1765,9 @@ integer function line_count(iunit) endif rewind(iunit) return - end function +end function + +!---------------------------------------------------------------------------------------------------------------------------------- !> Perform linear interpolation of an array, where first column is assumed to be ascending time values !! First value is used for times before, and last value is used for time beyond subroutine interpTimeValue(array, time, iLast, values) @@ -2083,35 +1803,45 @@ end subroutine interpTimeValue !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine sets up the information needed for plotting VTK surfaces. -SUBROUTINE SetVTKParameters(p_FAST, dvr, InitOutData_AD, AD, ErrStat, ErrMsg) - TYPE(Dvr_Outputs), INTENT(INOUT) :: p_FAST !< The parameters of the glue code +subroutine setVTKParameters(p_FAST, dvr, ADI, errStat, errMsg, dirname) + type(Dvr_Outputs), intent(inout) :: p_FAST !< The parameters of the glue code type(Dvr_SimData), target, intent(inout) :: dvr ! intent(out) only so that we can save FmtWidth in dvr%out%ActualChanLen - TYPE(AD_InitOutputType), INTENT(INOUT) :: InitOutData_AD !< The initialization output from AeroDyn - TYPE(AeroDyn_Data), target, INTENT(IN ) :: AD !< AeroDyn data - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - REAL(SiKi) :: RefPoint(3), RefLengths(2) - REAL(SiKi) :: x, y - REAL(SiKi) :: TwrDiam_top, TwrDiam_base, TwrRatio, TwrLength - INTEGER(IntKi) :: topNode, baseNode, cylNode, tipNode, rootNode - INTEGER(IntKi) :: NumBl, k, iRot, iBld, nNodes - CHARACTER(1024) :: vtkroot - INTEGER(IntKi) :: iWT - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SetVTKParameters' - real(SiKi) :: BladeLength, MaxBladeLength, MaxTwrLength, GroundRad + type(ADI_Data), target, intent(in ) :: ADI ! Input data for initialization (intent out for getting AD WriteOutput names/units) + integer(IntKi), intent( out) :: errStat !< Error status of the operation + character(*), intent( out) :: errMsg !< Error message if errStat /= ErrID_None + character(*), optional,intent(in ) :: dirname + real(SiKi) :: RefPoint(3), RefLengths(2) + real(SiKi) :: x, y + real(SiKi) :: TwrDiam_top, TwrDiam_base, TwrRatio, TwrLength + integer(IntKi) :: topNode, baseNode, cylNode, tipNode, rootNode + integer(IntKi) :: NumBl, k, iRot, iBld, nNodes + character(1024) :: vtkroot + integer(IntKi) :: iWT + integer(IntKi) :: errStat2 + character(ErrMsgLen) :: errMsg2 + character(*), parameter :: RoutineName = 'SetVTKParameters' + character(1024) :: dir + real(SiKi) :: BladeLength, MaxBladeLength, MaxTwrLength, GroundRad, MaxLength real(SiKi) :: WorldBoxMax(3), WorldBoxMin(3) ! Extent of the turbines real(SiKi) :: BaseBoxDim type(MeshType), pointer :: Mesh type(WTData), pointer :: wt ! Alias to shorten notation - ErrStat = ErrID_None - ErrMsg = "" + errStat = ErrID_None + errMsg = "" + if (present(dirname)) then + dir = trim(dirname) + else + dir = 'vtk' + endif + + ! --- Tower Blades (NOTE: done by ADI) + !call AD_SetVTKSurface(InitOut_AD, u%AD, m%VTK_Surfaces, errStat2, errMsg2); if(Failed()) return + ! get the name of the output directory for vtk files (in a subdirectory called "vtk" of the output directory), and ! create the VTK directory if it does not exist call GetPath ( p_FAST%root, p_FAST%VTK_OutFileRoot, vtkroot ) ! the returned p_FAST%VTK_OutFileRoot includes a file separator character at the end - p_FAST%VTK_OutFileRoot = trim(p_FAST%VTK_OutFileRoot) // 'vtk' + p_FAST%VTK_OutFileRoot = trim(p_FAST%VTK_OutFileRoot) // trim(dir) call MKDIR( trim(p_FAST%VTK_OutFileRoot) ) p_FAST%VTK_OutFileRoot = trim( p_FAST%VTK_OutFileRoot ) // PathSep // trim(vtkroot) ! calculate the number of digits in 'y_FAST%NOutSteps' (Maximum number of output steps to be written) @@ -2124,33 +1854,42 @@ SUBROUTINE SetVTKParameters(p_FAST, dvr, InitOutData_AD, AD, ErrStat, ErrMsg) allocate(p_FAST%VTK_Surface(dvr%numTurbines)) ! --- Find dimensions for all objects to determine "Ground" and typical dimensions - WorldBoxMax(2) =-HUGE(1.0_SiKi) - WorldBoxMin(2) = HUGE(1.0_SiKi) - MaxBladeLength=0 - MaxTwrLength=0 + MaxBladeLength = 0 + MaxTwrLength = 0 + MaxLength = 0 do iWT=1,dvr%numTurbines wt => dvr%wt(iWT) do iBld=1, wt%numBlades - nNodes = AD%u(1)%rotors(iWT)%BladeMotion(iBld)%nnodes - BladeLength = TwoNorm(AD%u(1)%rotors(iWT)%BladeMotion(iBld)%Position(:,nNodes)-AD%u(1)%rotors(iWT)%BladeMotion(iBld)%Position(:,1)) + nNodes = ADI%u(1)%AD%rotors(iWT)%BladeMotion(iBld)%nnodes + BladeLength = TwoNorm(ADI%u(1)%AD%rotors(iWT)%BladeMotion(iBld)%Position(:,nNodes)-ADI%u(1)%AD%rotors(iWT)%BladeMotion(iBld)%Position(:,1)) MaxBladeLength = max(MaxBladeLength, BladeLength) enddo if (wt%hasTower) then - Mesh=>AD%u(1)%rotors(iWT)%TowerMotion + Mesh=>ADI%u(1)%AD%rotors(iWT)%TowerMotion if (Mesh%NNodes>0) then TwrLength = TwoNorm( Mesh%position(:,1) - Mesh%position(:,Mesh%NNodes) ) MaxTwrLength = max(MaxTwrLength, TwrLength) endif endif + MaxLength = max(MaxLength, MaxTwrLength, MaxBladeLength) ! Determine extent of the objects RefPoint = wt%originInit - WorldBoxMax(1) = max(WorldBoxMax(1), RefPoint(1)) - WorldBoxMax(2) = max(WorldBoxMax(2), RefPoint(2)) - WorldBoxMax(3) = max(WorldBoxMax(3), RefPoint(3)) ! NOTE: not used - WorldBoxMin(1) = min(WorldBoxMin(1), RefPoint(1)) - WorldBoxMin(2) = min(WorldBoxMin(2), RefPoint(2)) - WorldBoxMin(3) = min(WorldBoxMin(3), RefPoint(3)) ! NOTE: not used + if (iWT==1) then + WorldBoxMax(1) = RefPoint(1)+MaxLength + WorldBoxMax(2) = RefPoint(2)+MaxLength + WorldBoxMax(3) = RefPoint(3)+MaxLength ! NOTE: not used + WorldBoxMin(1) = RefPoint(1)-MaxLength + WorldBoxMin(2) = RefPoint(2)-MaxLength + WorldBoxMin(3) = RefPoint(3)-MaxLength ! NOTE: not used + else + WorldBoxMax(1) = max(WorldBoxMax(1), RefPoint(1)+MaxLength) + WorldBoxMax(2) = max(WorldBoxMax(2), RefPoint(2)+MaxLength) + WorldBoxMax(3) = max(WorldBoxMax(3), RefPoint(3)+MaxLength) ! NOTE: not used + WorldBoxMin(1) = min(WorldBoxMin(1), RefPoint(1)-MaxLength) + WorldBoxMin(2) = min(WorldBoxMin(2), RefPoint(2)-MaxLength) + WorldBoxMin(3) = min(WorldBoxMin(3), RefPoint(3)-MaxLength) ! NOTE: not used + endif enddo ! Loop on turbine ! Get radius for ground (blade length + hub radius): @@ -2164,7 +1903,8 @@ SUBROUTINE SetVTKParameters(p_FAST, dvr, InitOutData_AD, AD, ErrStat, ErrMsg) RefPoint(3) = 0.0_ReKi RefLengths = GroundRad + sqrt((WorldBoxMax(1)-WorldBoxMin(1))**2 + (WorldBoxMax(2)-WorldBoxMin(2))**2) - call WrVTK_Ground (RefPoint, RefLengths, trim(p_FAST%VTK_OutFileRoot) // '.GroundSurface', ErrStat2, ErrMsg2 ) + call WrVTK_Ground (RefPoint, RefLengths, trim(p_FAST%VTK_OutFileRoot) // '.GroundSurface', errStat2, errMsg2 ) + ! --- Create surfaces for Nacelle, Base, Tower, Blades do iWT=1,dvr%numTurbines @@ -2181,36 +1921,11 @@ SUBROUTINE SetVTKParameters(p_FAST, dvr, InitOutData_AD, AD, ErrStat, ErrMsg) p_FAST%VTK_Surface(iWT)%NacelleBox(:,7) = (/ p_FAST%VTKNacDim(1)+p_FAST%VTKNacDim(4), p_FAST%VTKNacDim(2)+p_FAST%VTKNacDim(5), p_FAST%VTKNacDim(3)+p_FAST%VTKNacDim(6) /) p_FAST%VTK_Surface(iWT)%NacelleBox(:,8) = (/ p_FAST%VTKNacDim(1) , p_FAST%VTKNacDim(2)+p_FAST%VTKNacDim(5), p_FAST%VTKNacDim(3)+p_FAST%VTKNacDim(6) /) - !....................... - ! tapered tower - !....................... + ! Create base box (using towerbase or nacelle dime) BaseBoxDim = minval(p_FAST%VTKNacDim(4:6))/2 - if (wt%hasTower) then - Mesh=>AD%u(1)%rotors(iWT)%TowerMotion - if (Mesh%NNodes>0) then - CALL AllocAry(p_FAST%VTK_Surface(iWT)%TowerRad, Mesh%NNodes,'VTK_Surface(iWT)%TowerRad',ErrStat2,ErrMsg2) - topNode = Mesh%NNodes - 1 - !baseNode = Mesh%refNode - baseNode = 1 ! TODO TODO - TwrLength = TwoNorm( Mesh%position(:,topNode) - Mesh%position(:,baseNode) ) ! this is the assumed length of the tower - TwrRatio = TwrLength / 87.6_SiKi ! use ratio of the tower length to the length of the 5MW tower - TwrDiam_top = 3.87*TwrRatio - TwrDiam_base = 6.0*TwrRatio - - TwrRatio = 0.5 * (TwrDiam_top - TwrDiam_base) / TwrLength - do k=1,Mesh%NNodes - TwrLength = TwoNorm( Mesh%position(:,k) - Mesh%position(:,baseNode) ) - p_FAST%VTK_Surface(iWT)%TowerRad(k) = 0.5*TwrDiam_Base + TwrRatio*TwrLength - end do - BaseBoxDim = TwrDiam_Base/2 - else - print*,'>>>> TOWER HAS NO NODES' - !CALL AllocAry(p_FAST%VTK_Surface(iWT)%TowerRad, 2, 'VTK_Surface(iWT)%TowerRad',ErrStat2,ErrMsg2) - ! TODO create a fake tower - endif + if (size(ADI%m%VTK_Surfaces(iWT)%TowerRad)>0) then + BaseBoxDim = ADI%m%VTK_Surfaces(iWT)%TowerRad(1) endif - - ! Create base box (using towerbase or nacelle dime) p_FAST%VTK_Surface(iWT)%BaseBox(:,1) = (/ -BaseBoxDim , -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim /) p_FAST%VTK_Surface(iWT)%BaseBox(:,2) = (/ -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim /) p_FAST%VTK_Surface(iWT)%BaseBox(:,3) = (/ -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim , -BaseBoxDim /) @@ -2220,223 +1935,392 @@ SUBROUTINE SetVTKParameters(p_FAST, dvr, InitOutData_AD, AD, ErrStat, ErrMsg) p_FAST%VTK_Surface(iWT)%BaseBox(:,7) = (/ -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim+2*BaseBoxDim /) p_FAST%VTK_Surface(iWT)%BaseBox(:,8) = (/ -BaseBoxDim , -BaseBoxDim+2*BaseBoxDim, -BaseBoxDim+2*BaseBoxDim /) - !....................... - ! blade surfaces - !....................... - allocate(p_FAST%VTK_Surface(iWT)%BladeShape(wt%numBlades),stat=ErrStat2) - IF (ALLOCATED(InitOutData_AD%rotors(iWT)%BladeShape)) THEN - do k=1,wt%numBlades - call move_alloc( InitOutData_AD%rotors(iWT)%BladeShape(k)%AirfoilCoords, p_FAST%VTK_Surface(iWT)%BladeShape(k)%AirfoilCoords ) - end do - else - print*,'>>> Profile coordinates missing, using dummy coordinates' - rootNode = 1 - DO K=1,wt%numBlades - tipNode = AD%u(1)%rotors(iWT)%BladeMotion(K)%NNodes - cylNode = min(3,AD%u(1)%rotors(iWT)%BladeMotion(K)%Nnodes) - - call SetVTKDefaultBladeParams(AD%u(1)%rotors(iWT)%BladeMotion(K), p_FAST%VTK_Surface(iWT)%BladeShape(K), tipNode, rootNode, cylNode, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - END DO - endif enddo ! iWT, turbines -END SUBROUTINE SetVTKParameters +end subroutine SetVTKParameters !---------------------------------------------------------------------------------------------------------------------------------- !> This routine writes a minimal subset of meshes with surfaces to VTK-formatted files. It doesn't bother with !! returning an error code. -SUBROUTINE WrVTK_Surfaces(t_global, dvr, p_FAST, VTK_count, AD) +subroutine WrVTK_Surfaces(t_global, ADI, FED, p_FAST, VTK_count) use FVW_IO, only: WrVTK_FVW - - REAL(DbKi), INTENT(IN ) :: t_global !< Current global time - type(Dvr_SimData), target, intent(inout) :: dvr ! intent(out) only so that we can save FmtWidth in dvr%out%ActualChanLen - TYPE(Dvr_Outputs), INTENT(IN ) :: p_FAST !< Parameters for the glue code - INTEGER(IntKi) , INTENT(IN ) :: VTK_count - TYPE(AeroDyn_Data), INTENT(IN ) :: AD !< AeroDyn data - logical, parameter :: OutputFields = .FALSE. ! due to confusion about what fields mean on a surface, we are going to just output the basic meshes if people ask for fields - INTEGER(IntKi) :: k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMSg2 - CHARACTER(*), PARAMETER :: RoutineName = 'WrVTK_Surfaces' - integer(IntKi) :: iWT - type(WTData), pointer :: wt ! Alias to shorten notation - character(10) :: sWT - - ! Ground (written at initialization) - - do iWT = 1, size(dvr%WT) - sWT = '.T'//trim(num2lstr(iWT)) - wt=>dvr%WT(iWT) + real(DbKi), intent(in ) :: t_global !< Current global time + type(FED_Data), target, intent(in ) :: FED !< Elastic wind turbine data (Fake ElastoDyn) + type(ADI_Data), intent(in ) :: ADI !< Input data for initialization (intent out for getting AD WriteOutput names/units) + type(Dvr_Outputs), intent(in ) :: p_FAST !< Parameters for the glue code + integer(IntKi) , intent(in ) :: VTK_count + logical, parameter :: OutputFields = .FALSE. ! due to confusion about what fields mean on a surface, we are going to just output the basic meshes if people ask for fields + integer(IntKi) :: errStat2 + character(ErrMsgLen) :: errMSg2 + integer(IntKi) :: iWT + integer(IntKi) :: nWT + character(10) :: sWT + type(RotFED), pointer :: y_ED ! Alias to shorten notation + + ! AeroDyn surfaces (Blades, Hub, Tower) + call AD_WrVTK_Surfaces(ADI%u(2)%AD, ADI%y%AD, p_FAST%VTKRefPoint, ADI%m%VTK_Surfaces, VTK_count, p_FAST%VTK_OutFileRoot, p_FAST%VTK_tWidth, 25, p_FAST%VTKHubRad) + + ! Elastic info + nWT = size(FED%WT) + do iWT = 1, nWT + if (nWT==1) then + sWT = '' + else + sWT = '.T'//trim(num2lstr(iWT)) + endif + y_ED => FED%WT(iWT) ! Base - call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, wt%ptMesh, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.BaseSurface', & - VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , verts = p_FAST%VTK_Surface(iWT)%BaseBox) - - ! Tower motions - if (AD%u(2)%rotors(iWT)%TowerMotion%nNodes>0) then - call MeshWrVTK_Ln2Surface (p_FAST%VTKRefPoint, AD%u(2)%rotors(iWT)%TowerMotion, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.TowerSurface', & - VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, p_FAST%VTK_Surface(iWT)%NumSectors, p_FAST%VTK_Surface(iWT)%TowerRad ) - endif - - if (wt%numBlades>0) then + call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, y_ED%PlatformPtMesh, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.BaseSurface', & + VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth , verts = p_FAST%VTK_Surface(iWT)%BaseBox) + if (y_ED%numBlades>0) then ! Nacelle - call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, wt%nac%ptMesh, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.NacelleSurface', & - VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , verts = p_FAST%VTK_Surface(iWT)%NacelleBox) - - ! Hub - call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, AD%u(2)%rotors(iWT)%HubMotion, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.HubSurface', & - VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , & - NumSegments=p_FAST%VTK_Surface(iWT)%NumSectors, radius=p_FAST%VTKHubRad) + call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, y_ED%NacelleMotion, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.NacelleSurface', & + VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth , verts = p_FAST%VTK_Surface(iWT)%NacelleBox) endif - - ! Blades - do K=1,wt%numBlades - - call MeshWrVTK_Ln2Surface (p_FAST%VTKRefPoint, AD%u(2)%rotors(iWT)%BladeMotion(K), trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.Blade'//trim(num2lstr(k))//'Surface', & - VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , verts=p_FAST%VTK_Surface(iWT)%BladeShape(K)%AirfoilCoords & - ,Sib=AD%y%rotors(iWT)%BladeLoad(k) ) - end do - if (p_FAST%WrVTK>1) then - ! --- Debug outputs + ! --- animations ! Tower base - call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, wt%twr%ptMesh, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.TwrBaseSurface', & - VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , & + call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, y_ED%TwrPtMesh, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.TwrBaseSurface', & + VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth , & NumSegments=p_FAST%VTK_Surface(iWT)%NumSectors, radius=p_FAST%VTKHubRad) - if (AD%u(2)%rotors(iWT)%TowerMotion%nNodes>0) then - call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, wt%twr%ptMeshAD, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.TwrBaseSurfaceAD', & - VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , & + if (ADI%u(2)%AD%rotors(iWT)%TowerMotion%nNodes>0) then + call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, y_ED%TwrPtMeshAD, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.TwrBaseSurfaceAD', & + VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth , & NumSegments=p_FAST%VTK_Surface(iWT)%NumSectors, radius=p_FAST%VTKHubRad) endif - endif enddo - ! Free wake - if (allocated(AD%m%FVW_u)) then - if (allocated(AD%m%FVW_u(1)%WingsMesh)) then - call WrVTK_FVW(AD%p%FVW, AD%x%FVW, AD%z%FVW, AD%m%FVW, trim(p_FAST%VTK_OutFileRoot)//'.FVW', VTK_count, p_FAST%VTK_tWidth, bladeFrame=.FALSE.) ! bladeFrame==.FALSE. to output in global coords + if (allocated(ADI%m%AD%FVW_u)) then + if (allocated(ADI%m%AD%FVW_u(1)%WingsMesh)) then + call WrVTK_FVW(ADI%p%AD%FVW, ADI%x(1)%AD%FVW, ADI%z(1)%AD%FVW, ADI%m%AD%FVW, trim(p_FAST%VTK_OutFileRoot)//'.FVW', VTK_count, p_FAST%VTK_tWidth, bladeFrame=.FALSE.) ! bladeFrame==.FALSE. to output in global coords end if end if -END SUBROUTINE WrVTK_Surfaces +end subroutine WrVTK_Surfaces +!> This routine writes a minimal subset of meshes with surfaces to VTK-formatted files. It doesn't bother with +!! returning an error code. +subroutine WrVTK_Lines(t_global, ADI, FED, p_FAST, VTK_count) + use FVW_IO, only: WrVTK_FVW + REAL(DbKi), INTENT(IN ) :: t_global !< Current global time + type(ADI_Data), intent(in ) :: ADI !< Input data for initialization (intent out for getting AD WriteOutput names/units) + type(FED_Data), target, intent(in ) :: FED !< Elastic wind turbine data (Fake ElastoDyn) + TYPE(Dvr_Outputs), INTENT(IN ) :: p_FAST !< Parameters for the glue code + INTEGER(IntKi) , INTENT(IN ) :: VTK_count + logical, parameter :: OutputFields = .TRUE. + INTEGER(IntKi) :: k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMSg2 + integer(IntKi) :: iWT + integer(IntKi) :: nWT + character(10) :: sWT + type(RotFED), pointer :: y_ED ! Alias to shorten notation + + ! AeroDyn surfaces (Blades, Tower) + call AD_WrVTK_LinesPoints(ADI%u(2)%AD, ADI%y%AD, p_FAST%VTKRefPoint, VTK_count, p_FAST%VTK_OutFileRoot, p_FAST%VTK_tWidth) + + ! Elastic info + nWT = size(FED%WT) + do iWT = 1, nWT + if (nWT==1) then + sWT = '' + else + sWT = '.T'//trim(num2lstr(iWT)) + endif + y_ED => FED%WT(iWT) + + if (p_FAST%WrVTK_Type==2) then ! only if not doing surfaces + ! Base + call MeshWrVTK_PointSurface (p_FAST%VTKRefPoint, y_ED%PlatformPtMesh, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.BaseSurface', & + VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth , verts = p_FAST%VTK_Surface(iWT)%BaseBox) + endif + if (y_ED%numBlades>0) then + ! Nacelle + call MeshWrVTK( p_FAST%VTKRefPoint, y_ED%NacelleMotion, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.Nacelle', & + VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth ) + endif + + if (p_FAST%WrVTK>1) then + ! --- animations + ! Tower base + call MeshWrVTK(p_FAST%VTKRefPoint, y_ED%TwrPtMesh, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.TwrBase', & + VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth ) + + if (ADI%u(2)%AD%rotors(iWT)%TowerMotion%nNodes>0) then + call MeshWrVTK(p_FAST%VTKRefPoint, y_ED%TwrPtMeshAD, trim(p_FAST%VTK_OutFileRoot)//trim(sWT)//'.TwrBaseAD', & + VTK_count, OutputFields, errStat2, errMsg2, p_FAST%VTK_tWidth ) + endif + endif + enddo + + ! Free wake (only write this here if doing line meshes only -- FVW is written with surface outputs) + if (allocated(ADI%m%AD%FVW_u) .and. p_FAST%WrVTK_Type==2) then + if (allocated(ADI%m%AD%FVW_u(1)%WingsMesh)) then + call WrVTK_FVW(ADI%p%AD%FVW, ADI%x(1)%AD%FVW, ADI%z(1)%AD%FVW, ADI%m%AD%FVW, trim(p_FAST%VTK_OutFileRoot)//'.FVW', VTK_count, p_FAST%VTK_tWidth, bladeFrame=.FALSE.) ! bladeFrame==.FALSE. to output in global coords + end if + end if +end subroutine WrVTK_Lines !---------------------------------------------------------------------------------------------------------------------------------- !> This routine writes the ground or seabed reference surface information in VTK format. !! see VTK file information format for XML, here: http://www.vtk.org/wp-content/uploads/2015/04/file-formats.pdf -SUBROUTINE WrVTK_Ground ( RefPoint, HalfLengths, FileRootName, ErrStat, ErrMsg ) +subroutine WrVTK_Ground (RefPoint, HalfLengths, FileRootName, errStat, errMsg) REAL(SiKi), INTENT(IN) :: RefPoint(3) !< reference point (plane will be created around it) REAL(SiKi), INTENT(IN) :: HalfLengths(2) !< half of the X-Y lengths of plane surrounding RefPoint CHARACTER(*), INTENT(IN) :: FileRootName !< Name of the file to write the output in (excluding extension) - INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Indicates whether an error occurred (see NWTC_Library) - CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message associated with the ErrStat + INTEGER(IntKi), INTENT(OUT) :: errStat !< Indicates whether an error occurred (see NWTC_Library) + CHARACTER(*), INTENT(OUT) :: errMsg !< Error message associated with the errStat ! local variables - INTEGER(IntKi) :: Un ! fortran unit number - INTEGER(IntKi) :: ix ! loop counters - CHARACTER(1024) :: FileName - INTEGER(IntKi), parameter :: NumberOfPoints = 4 - INTEGER(IntKi), parameter :: NumberOfLines = 0 - INTEGER(IntKi), parameter :: NumberOfPolys = 1 - - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*),PARAMETER :: RoutineName = 'WrVTK_Ground' - ErrStat = ErrID_None - ErrMsg = "" - !................................................................. - ! write the data that potentially changes each time step: - !................................................................. - ! PolyData (.vtp) - Serial vtkPolyData (unstructured) file + INTEGER(IntKi) :: Un ! fortran unit number + INTEGER(IntKi) :: ix ! loop counters + CHARACTER(1024) :: FileName + INTEGER(IntKi), parameter :: NumberOfPoints = 4 + INTEGER(IntKi), parameter :: NumberOfLines = 0 + INTEGER(IntKi), parameter :: NumberOfPolys = 1 + INTEGER(IntKi) :: errStat2 + CHARACTER(ErrMsgLen) :: errMsg2 + errStat = ErrID_None + errMsg = "" FileName = TRIM(FileRootName)//'.vtp' - call WrVTK_header( FileName, NumberOfPoints, NumberOfLines, NumberOfPolys, Un, ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if (ErrStat >= AbortErrLev) return -! points (nodes, augmented with NumSegments): - WRITE(Un,'(A)') ' ' - WRITE(Un,'(A)') ' ' - WRITE(Un,VTK_AryFmt) RefPoint(1) + HalfLengths(1) , RefPoint(2) + HalfLengths(2), RefPoint(3) - WRITE(Un,VTK_AryFmt) RefPoint(1) + HalfLengths(1) , RefPoint(2) - HalfLengths(2), RefPoint(3) - WRITE(Un,VTK_AryFmt) RefPoint(1) - HalfLengths(1) , RefPoint(2) - HalfLengths(2), RefPoint(3) - WRITE(Un,VTK_AryFmt) RefPoint(1) - HalfLengths(1) , RefPoint(2) + HalfLengths(2), RefPoint(3) - WRITE(Un,'(A)') ' ' - WRITE(Un,'(A)') ' ' - WRITE(Un,'(A)') ' ' - WRITE(Un,'(A)') ' ' - WRITE(Un,'('//trim(num2lstr(NumberOfPoints))//'(i7))') (ix, ix=0,NumberOfPoints-1) - WRITE(Un,'(A)') ' ' - - WRITE(Un,'(A)') ' ' - WRITE(Un,'(i7)') NumberOfPoints - WRITE(Un,'(A)') ' ' - WRITE(Un,'(A)') ' ' - call WrVTK_footer( Un ) -END SUBROUTINE WrVTK_Ground + call WrVTK_header( FileName, NumberOfPoints, NumberOfLines, NumberOfPolys, Un, errStat2, errMsg2 ) + call SetErrStat(errStat2,errMsg2,errStat,errMsg,'WrVTK_Ground'); if (errStat >= AbortErrLev) return + WRITE(Un,'(A)') ' ' + WRITE(Un,'(A)') ' ' + WRITE(Un,VTK_AryFmt) RefPoint(1) + HalfLengths(1) , RefPoint(2) + HalfLengths(2), RefPoint(3) + WRITE(Un,VTK_AryFmt) RefPoint(1) + HalfLengths(1) , RefPoint(2) - HalfLengths(2), RefPoint(3) + WRITE(Un,VTK_AryFmt) RefPoint(1) - HalfLengths(1) , RefPoint(2) - HalfLengths(2), RefPoint(3) + WRITE(Un,VTK_AryFmt) RefPoint(1) - HalfLengths(1) , RefPoint(2) + HalfLengths(2), RefPoint(3) + WRITE(Un,'(A)') ' ' + WRITE(Un,'(A)') ' ' + WRITE(Un,'(A)') ' ' + WRITE(Un,'(A)') ' ' + WRITE(Un,'('//trim(num2lstr(NumberOfPoints))//'(i7))') (ix, ix=0,NumberOfPoints-1) + WRITE(Un,'(A)') ' ' + + WRITE(Un,'(A)') ' ' + WRITE(Un,'(i7)') NumberOfPoints + WRITE(Un,'(A)') ' ' + WRITE(Un,'(A)') ' ' + call WrVTK_footer( Un ) +end subroutine WrVTK_Ground +!---------------------------------------------------------------------------------------------------------------------------------- +!> User routine to initialize swap array for hub motion +subroutine userHubMotion_Init(userSwapAry, userSwapHdr, userSwapUnt, errStat, errMsg) + real(ReKi) , dimension(:), allocatable, intent(inout) :: userSwapAry !< user Swap Array + character(len=ChanLen) , dimension(:), allocatable, intent(inout) :: userSwapHdr !< Array of headers for user Swap Array + character(len=ChanLen) , dimension(:), allocatable, intent(inout) :: userSwapUnt !< Array of units for user Swap Array + integer(IntKi), intent(inout) :: errStat !< Status of error message + character(*), intent(inout) :: errMsg !< Error message if errStat /= ErrID_None + integer(IntKi) :: i ! loop index + integer(IntKi) :: errStat2 ! local status of error message + character(ErrMsgLen) :: errMsg2 ! local error message if errStat /= ErrID_None + integer, parameter :: SWAP_ARRAY_SIZE = 16 + errStat = ErrID_None + errMsg = '' + + call AllocAry(userSwapAry, SWAP_ARRAY_SIZE, 'userSwapAry', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'userHubMotion_Init') + call AllocAry(userSwapHdr, SWAP_ARRAY_SIZE, 'userSwapHdr', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'userHubMotion_Init') + call AllocAry(userSwapUnt, SWAP_ARRAY_SIZE, 'userSwapUnt', errStat2, errMsg2); call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'userHubMotion_Init') + if (errStat/=ErrID_None) return + ! + userSwapAry(:) = 0.0_ReKi + userSwapUnt(:) = "(-)" + do i = 1, size(userSwapAry); userSwapHdr(i) = 'Swap'//trim(num2lstr(i)); enddo; + i = iAzi ; userSwapHdr(i) = "SwapAzimuth "; userSwapUnt(i) = "(deg) " ! 1 + i = iAzi+1 ; userSwapHdr(i) = "SwapRotSpeed "; userSwapUnt(i) = "(rad/s) " ! 2 + i = iAzi+2 ; userSwapHdr(i) = "SwapRotAcc "; userSwapUnt(i) = "(rad/s^2)" ! 3 + i = iN_ ; userSwapHdr(i) = "SwapTimeStep "; userSwapUnt(i) = "(-) " ! 4 + i = igenTorque ; userSwapHdr(i) = "SwapGenTq "; userSwapUnt(i) = "(Nm) " ! 5 + i = igenTorqueF ; userSwapHdr(i) = "SwapGenTqF "; userSwapUnt(i) = "(Nm) " ! 6 + i = irotTorque ; userSwapHdr(i) = "SwapRotTq "; userSwapUnt(i) = "(Nm) " ! 7 + i = irotTorqueF ; userSwapHdr(i) = "SwapRotTqF "; userSwapUnt(i) = "(Nm) " ! 8 + i = iDeltaTorque ; userSwapHdr(i) = "SwapDeltaTq "; userSwapUnt(i) = "(Nm) " ! 9 + i = iDeltaTorqueF; userSwapHdr(i) = "SwapDeltaTqF "; userSwapUnt(i) = "(Nm) " ! 10 + i = irotSpeedI ; userSwapHdr(i) = "SwapRotSpeedI"; userSwapUnt(i) = "(rad/s) " ! 11 + i = irotSpeedF ; userSwapHdr(i) = "SwapRotSpeedF"; userSwapUnt(i) = "(rad/s) " ! 12 + i = iAlpha ; userSwapHdr(i) = "SwapAlpha "; userSwapUnt(i) = "(-) " ! 13 + i = iRegion ; userSwapHdr(i) = "SwapRegion "; userSwapUnt(i) = "(-) " ! 14 +end subroutine userHubMotion_Init !---------------------------------------------------------------------------------------------------------------------------------- -!> This subroutine comes up with some default airfoils for blade surfaces for a given blade mesh, M. -SUBROUTINE SetVTKDefaultBladeParams(M, BladeShape, tipNode, rootNode, cylNode, ErrStat, ErrMsg) - TYPE(MeshType), INTENT(IN ) :: M !< The Mesh the defaults should be calculated for - TYPE(DvrVTK_BLSurfaceType), INTENT(INOUT) :: BladeShape !< BladeShape to set to default values - INTEGER(IntKi), INTENT(IN ) :: rootNode !< Index of root node (innermost node) for this mesh - INTEGER(IntKi), INTENT(IN ) :: tipNode !< Index of tip node (outermost node) for this mesh - INTEGER(IntKi), INTENT(IN ) :: cylNode !< Index of last node to have a cylinder shape - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - REAL(SiKi) :: bladeLength, chord, pitchAxis - REAL(SiKi) :: bladeLengthFract, bladeLengthFract2, ratio, posLength ! temporary quantities - REAL(SiKi) :: cylinderLength, x, y, angle - INTEGER(IntKi) :: i, j - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'SetVTKDefaultBladeParams' - integer, parameter :: N = 66 - ! default airfoil shape coordinates; uses S809 values from http://wind.nrel.gov/airfoils/Shapes/S809_Shape.html: - real, parameter, dimension(N) :: xc=(/ 1.0,0.996203,0.98519,0.967844,0.945073,0.917488,0.885293,0.848455,0.80747,0.763042,0.715952,0.667064,0.617331,0.56783,0.519832,0.474243,0.428461,0.382612,0.33726,0.29297,0.250247,0.209576,0.171409,0.136174,0.104263,0.076035,0.051823,0.03191,0.01659,0.006026,0.000658,0.000204,0.0,0.000213,0.001045,0.001208,0.002398,0.009313,0.02323,0.04232,0.065877,0.093426,0.124111,0.157653,0.193738,0.231914,0.271438,0.311968,0.35337,0.395329,0.438273,0.48192,0.527928,0.576211,0.626092,0.676744,0.727211,0.776432,0.823285,0.86663,0.905365,0.938474,0.965086,0.984478,0.996141,1.0 /) - real, parameter, dimension(N) :: yc=(/ 0.0,0.000487,0.002373,0.00596,0.011024,0.017033,0.023458,0.03028,0.037766,0.045974,0.054872,0.064353,0.074214,0.084095,0.093268,0.099392,0.10176,0.10184,0.10007,0.096703,0.091908,0.085851,0.078687,0.07058,0.061697,0.052224,0.042352,0.032299,0.02229,0.012615,0.003723,0.001942,-0.00002,-0.001794,-0.003477,-0.003724,-0.005266,-0.011499,-0.020399,-0.030269,-0.040821,-0.051923,-0.063082,-0.07373,-0.083567,-0.092442,-0.099905,-0.105281,-0.108181,-0.108011,-0.104552,-0.097347,-0.086571,-0.073979,-0.060644,-0.047441,-0.0351,-0.024204,-0.015163,-0.008204,-0.003363,-0.000487,0.000743,0.000775,0.00029,0.0 /) - call AllocAry(BladeShape%AirfoilCoords, 2, N, M%NNodes, 'BladeShape%AirfoilCoords', ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - ! Chord length and pitch axis location are given by scaling law - bladeLength = TwoNorm( M%position(:,tipNode) - M%Position(:,rootNode) ) - cylinderLength = TwoNorm( M%Position(:,cylNode) - M%Position(:,rootNode) ) - bladeLengthFract = 0.22*bladeLength - bladeLengthFract2 = bladeLength-bladeLengthFract != 0.78*bladeLength - DO i=1,M%Nnodes - posLength = TwoNorm( M%Position(:,i) - M%Position(:,rootNode) ) - IF (posLength .LE. bladeLengthFract) THEN - ratio = posLength/bladeLengthFract - chord = (0.06 + 0.02*ratio)*bladeLength - pitchAxis = 0.25 + 0.125*ratio - ELSE - chord = (0.08 - 0.06*(posLength-bladeLengthFract)/bladeLengthFract2)*bladeLength - pitchAxis = 0.375 - END IF - IF (posLength .LE. cylinderLength) THEN - ! create a cylinder for this node - chord = chord/2.0_SiKi - DO j=1,N - ! normalized x,y coordinates for airfoil - x = yc(j) - y = xc(j) - 0.5 - angle = ATAN2( y, x) - ! x,y coordinates for cylinder - BladeShape%AirfoilCoords(1,j,i) = chord*COS(angle) ! x (note that "chord" is really representing chord/2 here) - BladeShape%AirfoilCoords(2,j,i) = chord*SIN(angle) ! y (note that "chord" is really representing chord/2 here) - END DO - ELSE - ! create an airfoil for this node - DO j=1,N - ! normalized x,y coordinates for airfoil, assuming an upwind turbine - x = yc(j) - y = xc(j) - pitchAxis - ! x,y coordinates for airfoil - BladeShape%AirfoilCoords(1,j,i) = chord*x - BladeShape%AirfoilCoords(2,j,i) = chord*y - END DO - END IF - END DO ! nodes on mesh - -END SUBROUTINE SetVTKDefaultBladeParams +!> User routine to set hub motion +subroutine userHubMotion(nt, iWT, dvr, ADI, FED, arr, azimuth, rotSpeed, rotAcc, errStat, errMsg) + use AeroDyn_IO, only: RtAeroMxh + integer(IntKi) , intent(in ) :: nt !< time step number + integer(IntKi) , intent(in ) :: iWT !< Wind turbine index + type(Dvr_SimData), intent(in ) :: dvr !< Driver arr + type(ADI_Data), intent(in ) :: ADI !< AeroDyn/InflowWind arr + type(FED_Data), intent(in ) :: FED !< Elastic wind turbine arr (Fake ElastoDyn) + real(ReKi), dimension(:), allocatable, intent(inout) :: arr !< Swap array that user can use to store arr + real(ReKi), intent( out) :: azimuth !< [deg] + real(ReKi), intent( out) :: rotSpeed !< [rad/s] + real(ReKi), intent( out) :: rotAcc !< [rad/s^2] + integer(IntKi), intent(inout) :: errStat !< Status of error message + character(*), intent(inout) :: errMsg !< Error message if errStat /= ErrID_None + ! Main parameters to be adjusted + real(ReKi), parameter :: cutInSpeed = 0.10 !< [rad/s] + real(ReKi), parameter :: ratedSpeed = 1.00 !< [rad/s] + real(ReKi), parameter :: maxSpeed = 10 !< [rad/s] + real(ReKi), parameter :: minSpeed = 0.0 !< [rad/s] + real(ReKi), parameter :: genTorque_rated = 10.0e6 !< [rad/s] + real(ReKi), parameter :: genTorqueRate_max = 8.0e6 !< [Nm/s] Maximum torque rate + real(ReKi), parameter :: k2 = 1.0e7 !< Proportionality constant + real(ReKi), parameter :: rotInertia = 5.0e6 !< [kg m^2] + real(ReKi), parameter :: CornerFreqTq = 3.5 !< Corner frequency (-3dB point) for the low-pass filter, rad/s. + real(ReKi), parameter :: CornerFreqSpeed = 1.0 !< Corner frequency (-3dB point) for the low-pass filter, rad/s. + ! Local + real(ReKi) :: azimuth_prev, rotSpeed_prev, rotAcc_prev, rotSpeed_int, rotSpeed_filt, rotSpeed_filt_prev + real(ReKi) :: rotTorque, rotTorque_prev, rotTorque_filt, rotTorque_filt_prev + real(ReKi) :: genTorque, genTorque_prev, genTorque_filt, genTorque_filt_prev + real(ReKi) :: deltaTorque, deltaTorque_filt, deltaTorque_prev, deltaTorque_filt_prev + real(ReKi) :: genTorqueRate + real(DbKi) :: time, time_prev + integer(IntKi) :: nt_prev + integer(IntKi) :: region + real(ReKi) :: alphaTq ! coefficient for the low-pass filter for the generator torque + real(ReKi) :: alphaSpeed ! coefficient for the low-pass filter for the rotor speed + errStat = ErrID_None + errMsg = '' + + ! First call, allocate memory + if (.not.allocated(arr)) then + errStat=ErrID_Fatal + errMsg='Swap array should have already been allocated' + return + endif + if (nt==0) then ! the first time this function is called + arr = 0.0_ReKi + arr(iN_) = real(nt, ReKi) + arr(iAzi+1) = rotSpeed ! setting to initial rotor speed, rotSpeed = rotSpeedInit + endif + + ! Retrieve previous time step values + azimuth_prev = arr(iAzi+0) + rotSpeed_prev = arr(iAzi+1) + rotAcc_prev = arr(iAzi+2) + rotSpeed_filt_prev = arr(irotSpeedF) + rotTorque_prev = arr(irotTorque) + genTorque_prev = arr(igenTorque) + rotTorque_filt_prev = arr(irotTorqueF) + genTorque_filt_prev = arr(igenTorqueF) + deltaTorque_prev = arr(iDeltaTorque) + deltaTorque_filt_prev = arr(iDeltaTorqueF) + ! Example, accessing even older values + !rotSpeed_prev_prev = arr(15) + !azimuth_prev_prev = arr(16) + + nt_prev = int(arr(iN_), IntKi) + time_prev = dvr%dt * nt_prev + time = dvr%dt * nt + ! Return if time step is the same as previous time step + if (nt==nt_prev) then + azimuth = azimuth_prev + rotSpeed = rotSpeed_prev + rotAcc = rotAcc_prev + return + endif + ! --- Filter constant. alpha=0: use current value(no filter), alpha=1 use previous value + alphaTq = exp( (time_prev - time)*CornerFreqTq ) + alphaSpeed = exp( (time_prev - time)*CornerFreqSpeed ) + alphaTq = min(max(alphaTq, 0._ReKi), 1.0_ReKi) ! Bounding value + + ! --- Rotor torque + rotTorque = ADI%m%AD%rotors(iWT)%AllOuts( RtAeroMxh ) + ! Optional filtering of input torque + rotTorque_filt = ( 1.0 - alphaTq )*rotTorque + alphaTq*rotTorque_filt_prev + + ! --- Generator torque + ! TODO insert better generator model here + if (rotSpeed_prev >= ratedSpeed) then + genTorque = genTorque_rated + region = 3 + elseif (rotSpeed_prev > cutInSpeed) then + genTorque = k2 * rotSpeed**2 + region = 2 + else + genTorque = 0 + region = 0 + endif + + ! Optional - saturate torque rate + if (genTorque>0) then + genTorqueRate = (genTorque - genTorque_prev)/dvr%dt + genTorqueRate = min( max( genTorqueRate, -genTorqueRate_max), genTorqueRate_max) + genTorque = genTorque_prev + genTorqueRate * dvr%dt + endif + + ! Optional filtering + genTorque_filt = ( 1.0 - alphaTq )*genTorque + alphaTq*genTorque_filt_prev + + + ! --- Delta torque + !deltaTorque = rotTorque_filt - genTorque_filt + !deltaTorque = rotTorque - genTorque + deltaTorque = rotTorque - genTorque + ! Optional filtering + deltaTorque_filt = ( 1.0 - alphaTq )*deltaTorque + alphaTq*deltaTorque_filt_prev + + ! --- Rotor Speed + rotSpeed_int = rotSpeed_prev + dvr%dt/rotInertia * (deltaTorque) + !rotSpeed_int = 6.0*2*PI/60 ! Constant speed hack + + ! Optional filtering of the rotor speed + rotSpeed_filt = ( 1.0 - alphaSpeed )*rotSpeed_int + alphaSpeed*rotSpeed_filt_prev ! filtered + + ! Chose rotational speed + !rotSpeed = rotSpeed_filt ! we return the filtered value + rotSpeed = rotSpeed_int ! we return the filtered value + + ! Bounding + rotSpeed = min(max(rotSpeed, minSpeed), maxSpeed) ! Bounding rotor speed + + ! --- Azimuth and acceleration + azimuth = azimuth_prev + (dvr%dt * rotSpeed)*180/PI ! [deg] + rotAcc = (rotSpeed-rotSpeed_prev) / dvr%dt ! Or set it to zero.. + !rotAcc = 0.0_ReKi + + ! --- Example, access other turbine information + ! NOTE: if the turbine index is higher than iWT, then the information is at "new time step" + ! if the turbine index is lower than iWT, then the information is at "old time step" + !if (iWT==2) then + ! ! OR use: + ! azimuth = dvr%WT(1)%hub%azimuth + ! rotSpeed = dvr%WT(1)%hub%rotSpeed + ! rotAcc = dvr%WT(1)%hub%rotAcc + ! ! -- If the turbine uses a swap array (user hub motion0, you can also access it here) + ! !azimuth = FED%WT(2)%userSwapArray(iAzi+0) + ! !rotSpeed = FED%WT(2)%userSwapArray(iAzi+1) + ! !rotAcc = FED%WT(2)%userSwapArray(iAzi+2) + !endif + + ! --- Example enforce initial velocity at few first time steps! + ! NOTE: first time step nt=1 + !if (nt<=30) then + ! rotSpeed = rotSpeed_prev + ! azimuth = modulo(REAL(dvr%dT*(nt-1)*rotSpeed, ReKi) * R2D, 360.0_ReKi ) + ! rotAcc = 0 + !endif + + + ! --- Store new values in swap array + arr(:) = myNaN + arr(iAzi+0) = azimuth + arr(iAzi+1) = rotSpeed + arr(iAzi+2) = rotAcc + arr(iN_) = nt + arr(igenTorque) = genTorque + arr(igenTorqueF) = genTorque_filt + arr(irotTorque) = rotTorque + arr(irotTorqueF) = rotTorque_filt + arr(iDeltaTorque) = deltaTorque + arr(iDeltaTorqueF) = deltaTorque_filt + arr(irotSpeedI ) = rotSpeed_int + arr(irotSpeedF ) = rotSpeed_filt + arr(iAlpha ) = alphaTq + arr(iRegion ) = region + ! --- Example store even older values + !arr(15) = rotSpeed_prev + !arr(16) = azimuth_prev +end subroutine userHubMotion end module AeroDyn_Driver_Subs diff --git a/modules/aerodyn/src/AeroDyn_Driver_Types.f90 b/modules/aerodyn/src/AeroDyn_Driver_Types.f90 index 61f020d76..cb59d0248 100644 --- a/modules/aerodyn/src/AeroDyn_Driver_Types.f90 +++ b/modules/aerodyn/src/AeroDyn_Driver_Types.f90 @@ -31,11 +31,9 @@ !! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. MODULE AeroDyn_Driver_Types !--------------------------------------------------------------------------------------------------------------------------------- -USE AeroDyn_Types -USE InflowWind_Types +USE AeroDyn_Inflow_Types USE NWTC_Library IMPLICIT NONE - INTEGER(IntKi), PUBLIC, PARAMETER :: numInp = 2 ! Determines order of interpolation for input-output extrap (2=linear;3=quadratic) [-] ! ========= Dvr_Case ======= TYPE, PUBLIC :: Dvr_Case REAL(ReKi) :: HWindSpeed !< Hub wind speed [m/s] @@ -51,18 +49,11 @@ MODULE AeroDyn_Driver_Types REAL(ReKi) :: frequency !< Frequency for sinusoidal motion (when DOF>0) [-] END TYPE Dvr_Case ! ======================= -! ========= DvrVTK_BLSurfaceType ======= - TYPE, PUBLIC :: DvrVTK_BLSurfaceType - REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: AirfoilCoords !< x,y coordinates for airfoil around each blade node on a blade (relative to reference) [-] - END TYPE DvrVTK_BLSurfaceType -! ======================= ! ========= DvrVTK_SurfaceType ======= TYPE, PUBLIC :: DvrVTK_SurfaceType INTEGER(IntKi) :: NumSectors !< number of sectors in which to split circles (higher number gives smoother surface) [-] REAL(SiKi) , DIMENSION(1:3,1:8) :: NacelleBox !< X-Y-Z locations of 8 points that define the nacelle box, relative to the nacelle position [m] REAL(SiKi) , DIMENSION(1:3,1:8) :: BaseBox !< X-Y-Z locations of 8 points that define the base box [m] - REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: TowerRad !< radius of each ED tower node [m] - TYPE(DvrVTK_BLSurfaceType) , DIMENSION(:), ALLOCATABLE :: BladeShape !< AirfoilCoords for each blade [m] END TYPE DvrVTK_SurfaceType ! ======================= ! ========= Dvr_Outputs ======= @@ -76,7 +67,8 @@ MODULE AeroDyn_Driver_Types character(1) :: delim !< column delimiter [-] character(20) :: outFmt !< Format specifier [-] INTEGER(IntKi) :: fileFmt !< Output format 1=Text, 2=Binary, 3=Both [-] - INTEGER(IntKi) :: wrVTK !< 0= no vtk, 1=animation [-] + INTEGER(IntKi) :: wrVTK !< 0= no vtk, 1=init only, 2=animation [-] + INTEGER(IntKi) :: WrVTK_Type !< Flag for VTK output type (1=surface, 2=line, 3=both) [-] character(1024) :: Root !< Output file rootname [-] character(1024) :: VTK_OutFileRoot !< Output file rootname for vtk [-] character(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< Channel headers [-] @@ -89,34 +81,10 @@ MODULE AeroDyn_Driver_Types REAL(SiKi) :: VTKHubRad !< Hub radius for visualization [m] REAL(ReKi) , DIMENSION(1:6) :: VTKNacDim !< Nacelle dimensions for visualization [m] REAL(SiKi) , DIMENSION(1:3) :: VTKRefPoint !< RefPoint for VTK outputs [-] + REAL(DbKi) :: DT_Outs !< Output time resolution [s] + INTEGER(IntKi) :: n_DT_Out !< Number of time steps between writing a line in the time-marching output files [-] END TYPE Dvr_Outputs ! ======================= -! ========= AeroDyn_Data ======= - TYPE, PUBLIC :: AeroDyn_Data - TYPE(AD_ContinuousStateType) :: x !< Continuous states [-] - TYPE(AD_DiscreteStateType) :: xd !< Discrete states [-] - TYPE(AD_ConstraintStateType) :: z !< Constraint states [-] - TYPE(AD_OtherStateType) :: OtherState !< Other states [-] - TYPE(AD_MiscVarType) :: m !< misc/optimization variables [-] - TYPE(AD_ParameterType) :: p !< Parameters [-] - TYPE(AD_InputType) , DIMENSION(numInp) :: u !< Array of system inputs [-] - TYPE(AD_OutputType) :: y !< System outputs [-] - REAL(DbKi) , DIMENSION(numInp) :: InputTime !< Array of times associated with u array [-] - END TYPE AeroDyn_Data -! ======================= -! ========= InflowWind_Data ======= - TYPE, PUBLIC :: InflowWind_Data - TYPE(InflowWind_ContinuousStateType) :: x !< Continuous states [-] - TYPE(InflowWind_DiscreteStateType) :: xd !< Discrete states [-] - TYPE(InflowWind_ConstraintStateType) :: z !< Constraint states [-] - TYPE(InflowWind_OtherStateType) :: OtherSt !< Other states [-] - TYPE(InflowWind_ParameterType) :: p !< Parameters [-] - TYPE(InflowWind_MiscVarType) :: m !< Misc/optimization variables [-] - TYPE(InflowWind_InputType) , DIMENSION(1:2) :: u !< Array of inputs associated with InputTimes [-] - TYPE(InflowWind_OutputType) :: y !< System outputs [-] - REAL(DbKi) , DIMENSION(1:2) :: InputTimes !< Array of times associated with Input Array [-] - END TYPE InflowWind_Data -! ======================= ! ========= BladeData ======= TYPE, PUBLIC :: BladeData REAL(ReKi) :: pitch !< rad [-] @@ -130,9 +98,6 @@ MODULE AeroDyn_Driver_Types INTEGER(IntKi) :: iMotion !< Stored index to optimize time interpolation [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: motion !< [-] character(1024) :: motionFileName !< [-] - TYPE(MeshType) :: ptMesh !< Point mesh for origin motion [-] - TYPE(MeshMapType) :: ED_P_2_AD_P_R !< Mesh mapping from blade to AD hub motion [-] - TYPE(MeshMapType) :: AD_P_2_AD_L_B !< Mesh mapping from AD blade root to AD line mesh [-] END TYPE BladeData ! ======================= ! ========= HubData ======= @@ -146,9 +111,6 @@ MODULE AeroDyn_Driver_Types REAL(ReKi) :: rotAcc !< rotor acceleration [rad/s/s] character(1024) :: motionFileName !< [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: motion !< [-] - TYPE(MeshType) :: ptMesh !< Point mesh for origin motion [-] - TYPE(MeshMapType) :: ED_P_2_AD_P_H !< Mesh mapping from hub to AD hub motion [-] - TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: map2BldPt !< Mesh mapping from hub to bld root motion [-] END TYPE HubData ! ======================= ! ========= NacData ======= @@ -161,27 +123,21 @@ MODULE AeroDyn_Driver_Types REAL(ReKi) :: yawAcc !< yawAcceleration [rad/s^2] character(1024) :: motionFileName !< [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: motion !< [-] - TYPE(MeshType) :: ptMesh !< Point mesh for origin motion [-] - TYPE(MeshMapType) :: ED_P_2_AD_P_N !< Mesh mapping from nacelle to AD nacelle motion [-] - TYPE(MeshMapType) :: map2hubPt !< Mesh mapping from Nacelle to hub [-] END TYPE NacData ! ======================= ! ========= TwrData ======= TYPE, PUBLIC :: TwrData REAL(ReKi) , DIMENSION(1:3) :: origin_t !< [-] - TYPE(MeshType) :: ptMesh !< Point mesh for origin motion [-] - TYPE(MeshType) :: ptMeshAD !< Point mesh for origin motion [-] - TYPE(MeshMapType) :: ED_P_2_AD_P_T !< Mesh mapping from tower base to AD tower base [-] - TYPE(MeshMapType) :: AD_P_2_AD_L_T !< Mesh mapping from tower base to AD tower line [-] END TYPE TwrData ! ======================= ! ========= WTData ======= TYPE, PUBLIC :: WTData REAL(ReKi) , DIMENSION(1:3) :: originInit !< [-] REAL(ReKi) , DIMENSION(1:3) :: orientationInit !< [-] - TYPE(MeshType) :: ptMesh !< Point mesh for origin motion [-] TYPE(MeshMapType) :: map2twrPt !< Mesh mapping from base to tower [-] TYPE(MeshMapType) :: map2nacPt !< Mesh mapping from base to nacelle [-] + TYPE(MeshMapType) :: map2hubPt !< Mesh mapping from Nacelle to hub [-] + TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: map2BldPt !< Mesh mapping from hub to bld root motion [-] TYPE(BladeData) , DIMENSION(:), ALLOCATABLE :: bld !< [-] TYPE(HubData) :: hub !< [-] TYPE(NacData) :: nac !< [-] @@ -189,6 +145,8 @@ MODULE AeroDyn_Driver_Types INTEGER(IntKi) :: numBlades !< [-] LOGICAL :: basicHAWTFormat !< If true simply input HubRad/Pitch/Overhang/Cone, otherwise all turbine inputs [-] LOGICAL :: hasTower !< [-] + INTEGER(IntKi) :: projMod !< If true simply input HubRad/Pitch/Overhang/Cone, otherwise all turbine inputs [-] + INTEGER(IntKi) :: BEM_Mod !< Switch for different BEM implementations [-] LOGICAL :: HAWTprojection !< [-] INTEGER(IntKi) :: motionType !< [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: motion !< [-] @@ -198,12 +156,12 @@ MODULE AeroDyn_Driver_Types REAL(ReKi) :: frequency !< [-] character(1024) :: motionFileName !< [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< WriteOutputs of the driver only [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: userSwapArray !< Array to store user data for user-defined functions [-] END TYPE WTData ! ======================= ! ========= Dvr_SimData ======= TYPE, PUBLIC :: Dvr_SimData character(1024) :: AD_InputFile !< Name of AeroDyn input file [-] - character(1024) :: IW_InputFile !< Name of InfloWind input file [-] INTEGER(IntKi) :: MHK !< MHK turbine type (switch) {0: not an MHK turbine, 1: fixed MHK turbine, 2: floating MHK turbine} [-] INTEGER(IntKi) :: AnalysisType !< 0=Steady Wind, 1=InflowWind [-] REAL(ReKi) :: FldDens !< Density of working fluid [kg/m^3] @@ -213,12 +171,8 @@ MODULE AeroDyn_Driver_Types REAL(ReKi) :: Pvap !< Vapour pressure of working fluid [Pa] REAL(ReKi) :: WtrDpth !< Water depth [m] REAL(ReKi) :: MSL2SWL !< Offset between still-water level and mean sea level [m] - INTEGER(IntKi) :: CompInflow !< 0=Steady Wind, 1=InflowWind [-] - REAL(ReKi) :: HWindSpeed !< RefHeight Wind speed [-] - REAL(ReKi) :: RefHt !< RefHeight [-] - REAL(ReKi) :: PLExp !< PLExp [-] INTEGER(IntKi) :: numTurbines !< number of blades on turbine [-] - TYPE(WTData) , DIMENSION(:), ALLOCATABLE :: WT !< Wind turbine data [-] + TYPE(WTData) , DIMENSION(:), ALLOCATABLE :: WT !< Wind turbine data for driver [-] REAL(DbKi) :: dT !< time increment [s] REAL(DbKi) :: tMax !< time increment [s] INTEGER(IntKi) :: numSteps !< number of steps in this case [-] @@ -229,13 +183,14 @@ MODULE AeroDyn_Driver_Types INTEGER(IntKi) :: iTimeSeries !< Stored index to optimize time interpolation [-] character(1024) :: root !< Output file rootname [-] TYPE(Dvr_Outputs) :: out !< data for driver output file [-] + TYPE(ADI_IW_InputData) :: IW_InitInp !< [-] END TYPE Dvr_SimData ! ======================= ! ========= AllData ======= TYPE, PUBLIC :: AllData - TYPE(Dvr_SimData) :: dvr !< [-] - TYPE(AeroDyn_Data) :: AD !< [-] - TYPE(InflowWind_Data) :: IW !< [-] + TYPE(Dvr_SimData) :: dvr !< Driver data [-] + TYPE(ADI_Data) :: ADI !< AeroDyn InflowWind Data [-] + TYPE(FED_Data) :: FED !< Elastic wind turbine data (Fake ElastoDyn) [-] INTEGER(IntKi) :: errStat !< [-] character(ErrMsgLen) :: errMsg !< [-] LOGICAL :: initialized !< [-] @@ -272,15 +227,27 @@ SUBROUTINE AD_Dvr_CopyDvr_Case( SrcDvr_CaseData, DstDvr_CaseData, CtrlCode, ErrS DstDvr_CaseData%frequency = SrcDvr_CaseData%frequency END SUBROUTINE AD_Dvr_CopyDvr_Case - SUBROUTINE AD_Dvr_DestroyDvr_Case( Dvr_CaseData, ErrStat, ErrMsg ) + SUBROUTINE AD_Dvr_DestroyDvr_Case( Dvr_CaseData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Dvr_Case), INTENT(INOUT) :: Dvr_CaseData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyDvr_Case' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyDvr_Case' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AD_Dvr_DestroyDvr_Case SUBROUTINE AD_Dvr_PackDvr_Case( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -433,9 +400,9 @@ SUBROUTINE AD_Dvr_UnPackDvr_Case( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = Re_Xferred + 1 END SUBROUTINE AD_Dvr_UnPackDvr_Case - SUBROUTINE AD_Dvr_CopyDvrVTK_BLSurfaceType( SrcDvrVTK_BLSurfaceTypeData, DstDvrVTK_BLSurfaceTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(DvrVTK_BLSurfaceType), INTENT(IN) :: SrcDvrVTK_BLSurfaceTypeData - TYPE(DvrVTK_BLSurfaceType), INTENT(INOUT) :: DstDvrVTK_BLSurfaceTypeData + SUBROUTINE AD_Dvr_CopyDvrVTK_SurfaceType( SrcDvrVTK_SurfaceTypeData, DstDvrVTK_SurfaceTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(DvrVTK_SurfaceType), INTENT(IN) :: SrcDvrVTK_SurfaceTypeData + TYPE(DvrVTK_SurfaceType), INTENT(INOUT) :: DstDvrVTK_SurfaceTypeData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -443,50 +410,45 @@ SUBROUTINE AD_Dvr_CopyDvrVTK_BLSurfaceType( SrcDvrVTK_BLSurfaceTypeData, DstDvrV 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 = 'AD_Dvr_CopyDvrVTK_BLSurfaceType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_CopyDvrVTK_SurfaceType' ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcDvrVTK_BLSurfaceTypeData%AirfoilCoords)) THEN - i1_l = LBOUND(SrcDvrVTK_BLSurfaceTypeData%AirfoilCoords,1) - i1_u = UBOUND(SrcDvrVTK_BLSurfaceTypeData%AirfoilCoords,1) - i2_l = LBOUND(SrcDvrVTK_BLSurfaceTypeData%AirfoilCoords,2) - i2_u = UBOUND(SrcDvrVTK_BLSurfaceTypeData%AirfoilCoords,2) - i3_l = LBOUND(SrcDvrVTK_BLSurfaceTypeData%AirfoilCoords,3) - i3_u = UBOUND(SrcDvrVTK_BLSurfaceTypeData%AirfoilCoords,3) - IF (.NOT. ALLOCATED(DstDvrVTK_BLSurfaceTypeData%AirfoilCoords)) THEN - ALLOCATE(DstDvrVTK_BLSurfaceTypeData%AirfoilCoords(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvrVTK_BLSurfaceTypeData%AirfoilCoords.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstDvrVTK_BLSurfaceTypeData%AirfoilCoords = SrcDvrVTK_BLSurfaceTypeData%AirfoilCoords -ENDIF - END SUBROUTINE AD_Dvr_CopyDvrVTK_BLSurfaceType + DstDvrVTK_SurfaceTypeData%NumSectors = SrcDvrVTK_SurfaceTypeData%NumSectors + DstDvrVTK_SurfaceTypeData%NacelleBox = SrcDvrVTK_SurfaceTypeData%NacelleBox + DstDvrVTK_SurfaceTypeData%BaseBox = SrcDvrVTK_SurfaceTypeData%BaseBox + END SUBROUTINE AD_Dvr_CopyDvrVTK_SurfaceType - SUBROUTINE AD_Dvr_DestroyDvrVTK_BLSurfaceType( DvrVTK_BLSurfaceTypeData, ErrStat, ErrMsg ) - TYPE(DvrVTK_BLSurfaceType), INTENT(INOUT) :: DvrVTK_BLSurfaceTypeData + SUBROUTINE AD_Dvr_DestroyDvrVTK_SurfaceType( DvrVTK_SurfaceTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(DvrVTK_SurfaceType), INTENT(INOUT) :: DvrVTK_SurfaceTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyDvrVTK_BLSurfaceType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyDvrVTK_SurfaceType' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(DvrVTK_BLSurfaceTypeData%AirfoilCoords)) THEN - DEALLOCATE(DvrVTK_BLSurfaceTypeData%AirfoilCoords) -ENDIF - END SUBROUTINE AD_Dvr_DestroyDvrVTK_BLSurfaceType - SUBROUTINE AD_Dvr_PackDvrVTK_BLSurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE AD_Dvr_DestroyDvrVTK_SurfaceType + + SUBROUTINE AD_Dvr_PackDvrVTK_SurfaceType( 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(DvrVTK_BLSurfaceType), INTENT(IN) :: InData + TYPE(DvrVTK_SurfaceType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -501,7 +463,7 @@ SUBROUTINE AD_Dvr_PackDvrVTK_BLSurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_PackDvrVTK_BLSurfaceType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_PackDvrVTK_SurfaceType' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -517,11 +479,9 @@ SUBROUTINE AD_Dvr_PackDvrVTK_BLSurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! AirfoilCoords allocated yes/no - IF ( ALLOCATED(InData%AirfoilCoords) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! AirfoilCoords upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%AirfoilCoords) ! AirfoilCoords - END IF + Int_BufSz = Int_BufSz + 1 ! NumSectors + Re_BufSz = Re_BufSz + SIZE(InData%NacelleBox) ! NacelleBox + Re_BufSz = Re_BufSz + SIZE(InData%BaseBox) ! BaseBox IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -549,38 +509,27 @@ SUBROUTINE AD_Dvr_PackDvrVTK_BLSurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Db_Xferred = 1 Int_Xferred = 1 - IF ( .NOT. ALLOCATED(InData%AirfoilCoords) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 + IntKiBuf(Int_Xferred) = InData%NumSectors Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AirfoilCoords,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AirfoilCoords,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AirfoilCoords,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AirfoilCoords,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AirfoilCoords,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AirfoilCoords,3) - Int_Xferred = Int_Xferred + 2 - - DO i3 = LBOUND(InData%AirfoilCoords,3), UBOUND(InData%AirfoilCoords,3) - DO i2 = LBOUND(InData%AirfoilCoords,2), UBOUND(InData%AirfoilCoords,2) - DO i1 = LBOUND(InData%AirfoilCoords,1), UBOUND(InData%AirfoilCoords,1) - ReKiBuf(Re_Xferred) = InData%AirfoilCoords(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i2 = LBOUND(InData%NacelleBox,2), UBOUND(InData%NacelleBox,2) + DO i1 = LBOUND(InData%NacelleBox,1), UBOUND(InData%NacelleBox,1) + ReKiBuf(Re_Xferred) = InData%NacelleBox(i1,i2) + Re_Xferred = Re_Xferred + 1 END DO - END IF - END SUBROUTINE AD_Dvr_PackDvrVTK_BLSurfaceType + END DO + DO i2 = LBOUND(InData%BaseBox,2), UBOUND(InData%BaseBox,2) + DO i1 = LBOUND(InData%BaseBox,1), UBOUND(InData%BaseBox,1) + ReKiBuf(Re_Xferred) = InData%BaseBox(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END SUBROUTINE AD_Dvr_PackDvrVTK_SurfaceType - SUBROUTINE AD_Dvr_UnPackDvrVTK_BLSurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_Dvr_UnPackDvrVTK_SurfaceType( 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(DvrVTK_BLSurfaceType), INTENT(INOUT) :: OutData + TYPE(DvrVTK_SurfaceType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -591,10 +540,9 @@ SUBROUTINE AD_Dvr_UnPackDvrVTK_BLSurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Outdat 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 = 'AD_Dvr_UnPackDvrVTK_BLSurfaceType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_UnPackDvrVTK_SurfaceType' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -605,39 +553,33 @@ SUBROUTINE AD_Dvr_UnPackDvrVTK_BLSurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Outdat Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AirfoilCoords not allocated - Int_Xferred = Int_Xferred + 1 - ELSE + OutData%NumSectors = 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%AirfoilCoords)) DEALLOCATE(OutData%AirfoilCoords) - ALLOCATE(OutData%AirfoilCoords(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%AirfoilCoords.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i3 = LBOUND(OutData%AirfoilCoords,3), UBOUND(OutData%AirfoilCoords,3) - DO i2 = LBOUND(OutData%AirfoilCoords,2), UBOUND(OutData%AirfoilCoords,2) - DO i1 = LBOUND(OutData%AirfoilCoords,1), UBOUND(OutData%AirfoilCoords,1) - OutData%AirfoilCoords(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + i1_l = LBOUND(OutData%NacelleBox,1) + i1_u = UBOUND(OutData%NacelleBox,1) + i2_l = LBOUND(OutData%NacelleBox,2) + i2_u = UBOUND(OutData%NacelleBox,2) + DO i2 = LBOUND(OutData%NacelleBox,2), UBOUND(OutData%NacelleBox,2) + DO i1 = LBOUND(OutData%NacelleBox,1), UBOUND(OutData%NacelleBox,1) + OutData%NacelleBox(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 END DO - END IF - END SUBROUTINE AD_Dvr_UnPackDvrVTK_BLSurfaceType + END DO + i1_l = LBOUND(OutData%BaseBox,1) + i1_u = UBOUND(OutData%BaseBox,1) + i2_l = LBOUND(OutData%BaseBox,2) + i2_u = UBOUND(OutData%BaseBox,2) + DO i2 = LBOUND(OutData%BaseBox,2), UBOUND(OutData%BaseBox,2) + DO i1 = LBOUND(OutData%BaseBox,1), UBOUND(OutData%BaseBox,1) + OutData%BaseBox(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END SUBROUTINE AD_Dvr_UnPackDvrVTK_SurfaceType - SUBROUTINE AD_Dvr_CopyDvrVTK_SurfaceType( SrcDvrVTK_SurfaceTypeData, DstDvrVTK_SurfaceTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(DvrVTK_SurfaceType), INTENT(IN) :: SrcDvrVTK_SurfaceTypeData - TYPE(DvrVTK_SurfaceType), INTENT(INOUT) :: DstDvrVTK_SurfaceTypeData + SUBROUTINE AD_Dvr_CopyDvr_Outputs( SrcDvr_OutputsData, DstDvr_OutputsData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Dvr_Outputs), INTENT(IN) :: SrcDvr_OutputsData + TYPE(Dvr_Outputs), INTENT(INOUT) :: DstDvr_OutputsData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -645,70 +587,168 @@ SUBROUTINE AD_Dvr_CopyDvrVTK_SurfaceType( SrcDvrVTK_SurfaceTypeData, DstDvrVTK_S 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 = 'AD_Dvr_CopyDvrVTK_SurfaceType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_CopyDvr_Outputs' ! ErrStat = ErrID_None ErrMsg = "" - DstDvrVTK_SurfaceTypeData%NumSectors = SrcDvrVTK_SurfaceTypeData%NumSectors - DstDvrVTK_SurfaceTypeData%NacelleBox = SrcDvrVTK_SurfaceTypeData%NacelleBox - DstDvrVTK_SurfaceTypeData%BaseBox = SrcDvrVTK_SurfaceTypeData%BaseBox -IF (ALLOCATED(SrcDvrVTK_SurfaceTypeData%TowerRad)) THEN - i1_l = LBOUND(SrcDvrVTK_SurfaceTypeData%TowerRad,1) - i1_u = UBOUND(SrcDvrVTK_SurfaceTypeData%TowerRad,1) - IF (.NOT. ALLOCATED(DstDvrVTK_SurfaceTypeData%TowerRad)) THEN - ALLOCATE(DstDvrVTK_SurfaceTypeData%TowerRad(i1_l:i1_u),STAT=ErrStat2) + CALL NWTC_Library_Copyprogdesc( SrcDvr_OutputsData%AD_ver, DstDvr_OutputsData%AD_ver, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcDvr_OutputsData%unOutFile)) THEN + i1_l = LBOUND(SrcDvr_OutputsData%unOutFile,1) + i1_u = UBOUND(SrcDvr_OutputsData%unOutFile,1) + IF (.NOT. ALLOCATED(DstDvr_OutputsData%unOutFile)) THEN + ALLOCATE(DstDvr_OutputsData%unOutFile(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvr_OutputsData%unOutFile.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstDvr_OutputsData%unOutFile = SrcDvr_OutputsData%unOutFile +ENDIF + DstDvr_OutputsData%ActualChanLen = SrcDvr_OutputsData%ActualChanLen + DstDvr_OutputsData%nDvrOutputs = SrcDvr_OutputsData%nDvrOutputs + DstDvr_OutputsData%Fmt_t = SrcDvr_OutputsData%Fmt_t + DstDvr_OutputsData%Fmt_a = SrcDvr_OutputsData%Fmt_a + DstDvr_OutputsData%delim = SrcDvr_OutputsData%delim + DstDvr_OutputsData%outFmt = SrcDvr_OutputsData%outFmt + DstDvr_OutputsData%fileFmt = SrcDvr_OutputsData%fileFmt + DstDvr_OutputsData%wrVTK = SrcDvr_OutputsData%wrVTK + DstDvr_OutputsData%WrVTK_Type = SrcDvr_OutputsData%WrVTK_Type + DstDvr_OutputsData%Root = SrcDvr_OutputsData%Root + DstDvr_OutputsData%VTK_OutFileRoot = SrcDvr_OutputsData%VTK_OutFileRoot +IF (ALLOCATED(SrcDvr_OutputsData%WriteOutputHdr)) THEN + i1_l = LBOUND(SrcDvr_OutputsData%WriteOutputHdr,1) + i1_u = UBOUND(SrcDvr_OutputsData%WriteOutputHdr,1) + IF (.NOT. ALLOCATED(DstDvr_OutputsData%WriteOutputHdr)) THEN + ALLOCATE(DstDvr_OutputsData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvr_OutputsData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstDvr_OutputsData%WriteOutputHdr = SrcDvr_OutputsData%WriteOutputHdr +ENDIF +IF (ALLOCATED(SrcDvr_OutputsData%WriteOutputUnt)) THEN + i1_l = LBOUND(SrcDvr_OutputsData%WriteOutputUnt,1) + i1_u = UBOUND(SrcDvr_OutputsData%WriteOutputUnt,1) + IF (.NOT. ALLOCATED(DstDvr_OutputsData%WriteOutputUnt)) THEN + ALLOCATE(DstDvr_OutputsData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvr_OutputsData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstDvr_OutputsData%WriteOutputUnt = SrcDvr_OutputsData%WriteOutputUnt +ENDIF +IF (ALLOCATED(SrcDvr_OutputsData%storage)) THEN + i1_l = LBOUND(SrcDvr_OutputsData%storage,1) + i1_u = UBOUND(SrcDvr_OutputsData%storage,1) + i2_l = LBOUND(SrcDvr_OutputsData%storage,2) + i2_u = UBOUND(SrcDvr_OutputsData%storage,2) + i3_l = LBOUND(SrcDvr_OutputsData%storage,3) + i3_u = UBOUND(SrcDvr_OutputsData%storage,3) + IF (.NOT. ALLOCATED(DstDvr_OutputsData%storage)) THEN + ALLOCATE(DstDvr_OutputsData%storage(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvr_OutputsData%storage.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstDvr_OutputsData%storage = SrcDvr_OutputsData%storage +ENDIF +IF (ALLOCATED(SrcDvr_OutputsData%outLine)) THEN + i1_l = LBOUND(SrcDvr_OutputsData%outLine,1) + i1_u = UBOUND(SrcDvr_OutputsData%outLine,1) + IF (.NOT. ALLOCATED(DstDvr_OutputsData%outLine)) THEN + ALLOCATE(DstDvr_OutputsData%outLine(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvrVTK_SurfaceTypeData%TowerRad.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvr_OutputsData%outLine.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstDvrVTK_SurfaceTypeData%TowerRad = SrcDvrVTK_SurfaceTypeData%TowerRad + DstDvr_OutputsData%outLine = SrcDvr_OutputsData%outLine ENDIF -IF (ALLOCATED(SrcDvrVTK_SurfaceTypeData%BladeShape)) THEN - i1_l = LBOUND(SrcDvrVTK_SurfaceTypeData%BladeShape,1) - i1_u = UBOUND(SrcDvrVTK_SurfaceTypeData%BladeShape,1) - IF (.NOT. ALLOCATED(DstDvrVTK_SurfaceTypeData%BladeShape)) THEN - ALLOCATE(DstDvrVTK_SurfaceTypeData%BladeShape(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcDvr_OutputsData%VTK_surface)) THEN + i1_l = LBOUND(SrcDvr_OutputsData%VTK_surface,1) + i1_u = UBOUND(SrcDvr_OutputsData%VTK_surface,1) + IF (.NOT. ALLOCATED(DstDvr_OutputsData%VTK_surface)) THEN + ALLOCATE(DstDvr_OutputsData%VTK_surface(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvrVTK_SurfaceTypeData%BladeShape.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvr_OutputsData%VTK_surface.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcDvrVTK_SurfaceTypeData%BladeShape,1), UBOUND(SrcDvrVTK_SurfaceTypeData%BladeShape,1) - CALL AD_Dvr_Copydvrvtk_blsurfacetype( SrcDvrVTK_SurfaceTypeData%BladeShape(i1), DstDvrVTK_SurfaceTypeData%BladeShape(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcDvr_OutputsData%VTK_surface,1), UBOUND(SrcDvr_OutputsData%VTK_surface,1) + CALL AD_Dvr_Copydvrvtk_surfacetype( SrcDvr_OutputsData%VTK_surface(i1), DstDvr_OutputsData%VTK_surface(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF - END SUBROUTINE AD_Dvr_CopyDvrVTK_SurfaceType + DstDvr_OutputsData%VTK_tWidth = SrcDvr_OutputsData%VTK_tWidth + DstDvr_OutputsData%n_VTKTime = SrcDvr_OutputsData%n_VTKTime + DstDvr_OutputsData%VTKHubRad = SrcDvr_OutputsData%VTKHubRad + DstDvr_OutputsData%VTKNacDim = SrcDvr_OutputsData%VTKNacDim + DstDvr_OutputsData%VTKRefPoint = SrcDvr_OutputsData%VTKRefPoint + DstDvr_OutputsData%DT_Outs = SrcDvr_OutputsData%DT_Outs + DstDvr_OutputsData%n_DT_Out = SrcDvr_OutputsData%n_DT_Out + END SUBROUTINE AD_Dvr_CopyDvr_Outputs - SUBROUTINE AD_Dvr_DestroyDvrVTK_SurfaceType( DvrVTK_SurfaceTypeData, ErrStat, ErrMsg ) - TYPE(DvrVTK_SurfaceType), INTENT(INOUT) :: DvrVTK_SurfaceTypeData + SUBROUTINE AD_Dvr_DestroyDvr_Outputs( Dvr_OutputsData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Dvr_Outputs), INTENT(INOUT) :: Dvr_OutputsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyDvrVTK_SurfaceType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyDvr_Outputs' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(DvrVTK_SurfaceTypeData%TowerRad)) THEN - DEALLOCATE(DvrVTK_SurfaceTypeData%TowerRad) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyprogdesc( Dvr_OutputsData%AD_ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(Dvr_OutputsData%unOutFile)) THEN + DEALLOCATE(Dvr_OutputsData%unOutFile) +ENDIF +IF (ALLOCATED(Dvr_OutputsData%WriteOutputHdr)) THEN + DEALLOCATE(Dvr_OutputsData%WriteOutputHdr) +ENDIF +IF (ALLOCATED(Dvr_OutputsData%WriteOutputUnt)) THEN + DEALLOCATE(Dvr_OutputsData%WriteOutputUnt) +ENDIF +IF (ALLOCATED(Dvr_OutputsData%storage)) THEN + DEALLOCATE(Dvr_OutputsData%storage) +ENDIF +IF (ALLOCATED(Dvr_OutputsData%outLine)) THEN + DEALLOCATE(Dvr_OutputsData%outLine) ENDIF -IF (ALLOCATED(DvrVTK_SurfaceTypeData%BladeShape)) THEN -DO i1 = LBOUND(DvrVTK_SurfaceTypeData%BladeShape,1), UBOUND(DvrVTK_SurfaceTypeData%BladeShape,1) - CALL AD_Dvr_Destroydvrvtk_blsurfacetype( DvrVTK_SurfaceTypeData%BladeShape(i1), ErrStat, ErrMsg ) +IF (ALLOCATED(Dvr_OutputsData%VTK_surface)) THEN +DO i1 = LBOUND(Dvr_OutputsData%VTK_surface,1), UBOUND(Dvr_OutputsData%VTK_surface,1) + CALL AD_Dvr_Destroydvrvtk_surfacetype( Dvr_OutputsData%VTK_surface(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(DvrVTK_SurfaceTypeData%BladeShape) + DEALLOCATE(Dvr_OutputsData%VTK_surface) ENDIF - END SUBROUTINE AD_Dvr_DestroyDvrVTK_SurfaceType + END SUBROUTINE AD_Dvr_DestroyDvr_Outputs - SUBROUTINE AD_Dvr_PackDvrVTK_SurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE AD_Dvr_PackDvr_Outputs( 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(DvrVTK_SurfaceType), INTENT(IN) :: InData + TYPE(Dvr_Outputs), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -723,7 +763,7 @@ SUBROUTINE AD_Dvr_PackDvrVTK_SurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_PackDvrVTK_SurfaceType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_PackDvr_Outputs' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -739,38 +779,90 @@ SUBROUTINE AD_Dvr_PackDvrVTK_SurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! NumSectors - Re_BufSz = Re_BufSz + SIZE(InData%NacelleBox) ! NacelleBox - Re_BufSz = Re_BufSz + SIZE(InData%BaseBox) ! BaseBox - Int_BufSz = Int_BufSz + 1 ! TowerRad allocated yes/no - IF ( ALLOCATED(InData%TowerRad) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! TowerRad upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TowerRad) ! TowerRad - END IF - Int_BufSz = Int_BufSz + 1 ! BladeShape allocated yes/no - IF ( ALLOCATED(InData%BladeShape) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! BladeShape upper/lower bounds for each dimension ! Allocate buffers for subtypes, if any (we'll get sizes from these) - DO i1 = LBOUND(InData%BladeShape,1), UBOUND(InData%BladeShape,1) - Int_BufSz = Int_BufSz + 3 ! BladeShape: size of buffers for each call to pack subtype - CALL AD_Dvr_Packdvrvtk_blsurfacetype( Re_Buf, Db_Buf, Int_Buf, InData%BladeShape(i1), ErrStat2, ErrMsg2, .TRUE. ) ! BladeShape - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + Int_BufSz = Int_BufSz + 3 ! AD_ver: size of buffers for each call to pack subtype + CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%AD_ver, ErrStat2, ErrMsg2, .TRUE. ) ! AD_ver + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD_ver + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD_ver + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD_ver + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! unOutFile allocated yes/no + IF ( ALLOCATED(InData%unOutFile) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! unOutFile upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%unOutFile) ! unOutFile + END IF + Int_BufSz = Int_BufSz + 1 ! ActualChanLen + Int_BufSz = Int_BufSz + 1 ! nDvrOutputs + Int_BufSz = Int_BufSz + 1*LEN(InData%Fmt_t) ! Fmt_t + Int_BufSz = Int_BufSz + 1*LEN(InData%Fmt_a) ! Fmt_a + Int_BufSz = Int_BufSz + 1*LEN(InData%delim) ! delim + Int_BufSz = Int_BufSz + 1*LEN(InData%outFmt) ! outFmt + Int_BufSz = Int_BufSz + 1 ! fileFmt + Int_BufSz = Int_BufSz + 1 ! wrVTK + Int_BufSz = Int_BufSz + 1 ! WrVTK_Type + Int_BufSz = Int_BufSz + 1*LEN(InData%Root) ! Root + Int_BufSz = Int_BufSz + 1*LEN(InData%VTK_OutFileRoot) ! VTK_OutFileRoot + 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 + Int_BufSz = Int_BufSz + 1 ! storage allocated yes/no + IF ( ALLOCATED(InData%storage) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! storage upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%storage) ! storage + END IF + Int_BufSz = Int_BufSz + 1 ! outLine allocated yes/no + IF ( ALLOCATED(InData%outLine) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! outLine upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%outLine) ! outLine + END IF + Int_BufSz = Int_BufSz + 1 ! VTK_surface allocated yes/no + IF ( ALLOCATED(InData%VTK_surface) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VTK_surface upper/lower bounds for each dimension + DO i1 = LBOUND(InData%VTK_surface,1), UBOUND(InData%VTK_surface,1) + Int_BufSz = Int_BufSz + 3 ! VTK_surface: size of buffers for each call to pack subtype + CALL AD_Dvr_Packdvrvtk_surfacetype( Re_Buf, Db_Buf, Int_Buf, InData%VTK_surface(i1), ErrStat2, ErrMsg2, .TRUE. ) ! VTK_surface + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! BladeShape + IF(ALLOCATED(Re_Buf)) THEN ! VTK_surface Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! BladeShape + IF(ALLOCATED(Db_Buf)) THEN ! VTK_surface Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! BladeShape + IF(ALLOCATED(Int_Buf)) THEN ! VTK_surface Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! VTK_tWidth + Int_BufSz = Int_BufSz + 1 ! n_VTKTime + Re_BufSz = Re_BufSz + 1 ! VTKHubRad + Re_BufSz = Re_BufSz + SIZE(InData%VTKNacDim) ! VTKNacDim + Re_BufSz = Re_BufSz + SIZE(InData%VTKRefPoint) ! VTKRefPoint + Db_BufSz = Db_BufSz + 1 ! DT_Outs + Int_BufSz = Int_BufSz + 1 ! n_DT_Out IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -798,47 +890,169 @@ SUBROUTINE AD_Dvr_PackDvrVTK_SurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = InData%NumSectors + CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%AD_ver, ErrStat2, ErrMsg2, OnlySize ) ! AD_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%unOutFile) ) THEN + IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 - DO i2 = LBOUND(InData%NacelleBox,2), UBOUND(InData%NacelleBox,2) - DO i1 = LBOUND(InData%NacelleBox,1), UBOUND(InData%NacelleBox,1) - ReKiBuf(Re_Xferred) = InData%NacelleBox(i1,i2) - Re_Xferred = Re_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%unOutFile,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%unOutFile,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%unOutFile,1), UBOUND(InData%unOutFile,1) + IntKiBuf(Int_Xferred) = InData%unOutFile(i1) + Int_Xferred = Int_Xferred + 1 END DO - END DO - DO i2 = LBOUND(InData%BaseBox,2), UBOUND(InData%BaseBox,2) - DO i1 = LBOUND(InData%BaseBox,1), UBOUND(InData%BaseBox,1) - ReKiBuf(Re_Xferred) = InData%BaseBox(i1,i2) - Re_Xferred = Re_Xferred + 1 + END IF + IntKiBuf(Int_Xferred) = InData%ActualChanLen + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nDvrOutputs + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(InData%Fmt_t) + IntKiBuf(Int_Xferred) = ICHAR(InData%Fmt_t(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(InData%Fmt_a) + IntKiBuf(Int_Xferred) = ICHAR(InData%Fmt_a(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + 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 + IntKiBuf(Int_Xferred) = InData%fileFmt + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%wrVTK + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%WrVTK_Type + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(InData%Root) + IntKiBuf(Int_Xferred) = ICHAR(InData%Root(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(InData%VTK_OutFileRoot) + IntKiBuf(Int_Xferred) = ICHAR(InData%VTK_OutFileRoot(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + 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 DO - IF ( .NOT. ALLOCATED(InData%TowerRad) ) THEN + 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 + IF ( .NOT. ALLOCATED(InData%storage) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%storage,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%storage,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%storage,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%storage,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%storage,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%storage,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%storage,3), UBOUND(InData%storage,3) + DO i2 = LBOUND(InData%storage,2), UBOUND(InData%storage,2) + DO i1 = LBOUND(InData%storage,1), UBOUND(InData%storage,1) + ReKiBuf(Re_Xferred) = InData%storage(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%outLine) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TowerRad,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TowerRad,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%outLine,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%outLine,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%TowerRad,1), UBOUND(InData%TowerRad,1) - ReKiBuf(Re_Xferred) = InData%TowerRad(i1) + DO i1 = LBOUND(InData%outLine,1), UBOUND(InData%outLine,1) + ReKiBuf(Re_Xferred) = InData%outLine(i1) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%BladeShape) ) THEN + IF ( .NOT. ALLOCATED(InData%VTK_surface) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeShape,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeShape,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%VTK_surface,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VTK_surface,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%BladeShape,1), UBOUND(InData%BladeShape,1) - CALL AD_Dvr_Packdvrvtk_blsurfacetype( Re_Buf, Db_Buf, Int_Buf, InData%BladeShape(i1), ErrStat2, ErrMsg2, OnlySize ) ! BladeShape + DO i1 = LBOUND(InData%VTK_surface,1), UBOUND(InData%VTK_surface,1) + CALL AD_Dvr_Packdvrvtk_surfacetype( Re_Buf, Db_Buf, Int_Buf, InData%VTK_surface(i1), ErrStat2, ErrMsg2, OnlySize ) ! VTK_surface CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -868,13 +1082,31 @@ SUBROUTINE AD_Dvr_PackDvrVTK_SurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er ENDIF END DO END IF - END SUBROUTINE AD_Dvr_PackDvrVTK_SurfaceType + IntKiBuf(Int_Xferred) = InData%VTK_tWidth + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%n_VTKTime + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VTKHubRad + Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%VTKNacDim,1), UBOUND(InData%VTKNacDim,1) + ReKiBuf(Re_Xferred) = InData%VTKNacDim(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%VTKRefPoint,1), UBOUND(InData%VTKRefPoint,1) + ReKiBuf(Re_Xferred) = InData%VTKRefPoint(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DbKiBuf(Db_Xferred) = InData%DT_Outs + Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%n_DT_Out + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE AD_Dvr_PackDvr_Outputs - SUBROUTINE AD_Dvr_UnPackDvrVTK_SurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_Dvr_UnPackDvr_Outputs( 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(DvrVTK_SurfaceType), INTENT(INOUT) :: OutData + TYPE(Dvr_Outputs), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -885,9 +1117,10 @@ SUBROUTINE AD_Dvr_UnPackDvrVTK_SurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, 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 = 'AD_Dvr_UnPackDvrVTK_SurfaceType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_UnPackDvr_Outputs' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -898,60 +1131,198 @@ SUBROUTINE AD_Dvr_UnPackDvrVTK_SurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%NumSectors = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%NacelleBox,1) - i1_u = UBOUND(OutData%NacelleBox,1) - i2_l = LBOUND(OutData%NacelleBox,2) - i2_u = UBOUND(OutData%NacelleBox,2) - DO i2 = LBOUND(OutData%NacelleBox,2), UBOUND(OutData%NacelleBox,2) - DO i1 = LBOUND(OutData%NacelleBox,1), UBOUND(OutData%NacelleBox,1) - OutData%NacelleBox(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - i1_l = LBOUND(OutData%BaseBox,1) - i1_u = UBOUND(OutData%BaseBox,1) - i2_l = LBOUND(OutData%BaseBox,2) - i2_u = UBOUND(OutData%BaseBox,2) - DO i2 = LBOUND(OutData%BaseBox,2), UBOUND(OutData%BaseBox,2) - DO i1 = LBOUND(OutData%BaseBox,1), UBOUND(OutData%BaseBox,1) - OutData%BaseBox(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%AD_ver, ErrStat2, ErrMsg2 ) ! AD_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 ! unOutFile not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%unOutFile)) DEALLOCATE(OutData%unOutFile) + ALLOCATE(OutData%unOutFile(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%unOutFile.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%unOutFile,1), UBOUND(OutData%unOutFile,1) + OutData%unOutFile(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 END DO - END DO - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TowerRad not allocated + END IF + OutData%ActualChanLen = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nDvrOutputs = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(OutData%Fmt_t) + OutData%Fmt_t(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(OutData%Fmt_a) + OutData%Fmt_a(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(OutData%delim) + OutData%delim(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(OutData%outFmt) + OutData%outFmt(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%fileFmt = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%wrVTK = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WrVTK_Type = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(OutData%Root) + OutData%Root(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(OutData%VTK_OutFileRoot) + OutData%VTK_OutFileRoot(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + 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 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! storage not allocated + Int_Xferred = Int_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%storage)) DEALLOCATE(OutData%storage) + ALLOCATE(OutData%storage(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%storage.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%storage,3), UBOUND(OutData%storage,3) + DO i2 = LBOUND(OutData%storage,2), UBOUND(OutData%storage,2) + DO i1 = LBOUND(OutData%storage,1), UBOUND(OutData%storage,1) + OutData%storage(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 ! outLine not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TowerRad)) DEALLOCATE(OutData%TowerRad) - ALLOCATE(OutData%TowerRad(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%outLine)) DEALLOCATE(OutData%outLine) + ALLOCATE(OutData%outLine(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TowerRad.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%outLine.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%TowerRad,1), UBOUND(OutData%TowerRad,1) - OutData%TowerRad(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) + DO i1 = LBOUND(OutData%outLine,1), UBOUND(OutData%outLine,1) + OutData%outLine(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeShape not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VTK_surface not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BladeShape)) DEALLOCATE(OutData%BladeShape) - ALLOCATE(OutData%BladeShape(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%VTK_surface)) DEALLOCATE(OutData%VTK_surface) + ALLOCATE(OutData%VTK_surface(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeShape.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VTK_surface.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%BladeShape,1), UBOUND(OutData%BladeShape,1) + DO i1 = LBOUND(OutData%VTK_surface,1), UBOUND(OutData%VTK_surface,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -985,7 +1356,7 @@ SUBROUTINE AD_Dvr_UnPackDvrVTK_SurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL AD_Dvr_Unpackdvrvtk_blsurfacetype( Re_Buf, Db_Buf, Int_Buf, OutData%BladeShape(i1), ErrStat2, ErrMsg2 ) ! BladeShape + CALL AD_Dvr_Unpackdvrvtk_surfacetype( Re_Buf, Db_Buf, Int_Buf, OutData%VTK_surface(i1), ErrStat2, ErrMsg2 ) ! VTK_surface CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -994,11 +1365,33 @@ SUBROUTINE AD_Dvr_UnPackDvrVTK_SurfaceType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - END SUBROUTINE AD_Dvr_UnPackDvrVTK_SurfaceType + OutData%VTK_tWidth = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%n_VTKTime = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%VTKHubRad = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%VTKNacDim,1) + i1_u = UBOUND(OutData%VTKNacDim,1) + DO i1 = LBOUND(OutData%VTKNacDim,1), UBOUND(OutData%VTKNacDim,1) + OutData%VTKNacDim(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%VTKRefPoint,1) + i1_u = UBOUND(OutData%VTKRefPoint,1) + DO i1 = LBOUND(OutData%VTKRefPoint,1), UBOUND(OutData%VTKRefPoint,1) + OutData%VTKRefPoint(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%DT_Outs = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%n_DT_Out = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE AD_Dvr_UnPackDvr_Outputs - SUBROUTINE AD_Dvr_CopyDvr_Outputs( SrcDvr_OutputsData, DstDvr_OutputsData, CtrlCode, ErrStat, ErrMsg ) - TYPE(Dvr_Outputs), INTENT(IN) :: SrcDvr_OutputsData - TYPE(Dvr_Outputs), INTENT(INOUT) :: DstDvr_OutputsData + SUBROUTINE AD_Dvr_CopyBladeData( SrcBladeDataData, DstBladeDataData, CtrlCode, ErrStat, ErrMsg ) + TYPE(BladeData), INTENT(IN) :: SrcBladeDataData + TYPE(BladeData), INTENT(INOUT) :: DstBladeDataData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -1006,151 +1399,69 @@ SUBROUTINE AD_Dvr_CopyDvr_Outputs( SrcDvr_OutputsData, DstDvr_OutputsData, CtrlC 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 = 'AD_Dvr_CopyDvr_Outputs' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_CopyBladeData' ! ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Copyprogdesc( SrcDvr_OutputsData%AD_ver, DstDvr_OutputsData%AD_ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN -IF (ALLOCATED(SrcDvr_OutputsData%unOutFile)) THEN - i1_l = LBOUND(SrcDvr_OutputsData%unOutFile,1) - i1_u = UBOUND(SrcDvr_OutputsData%unOutFile,1) - IF (.NOT. ALLOCATED(DstDvr_OutputsData%unOutFile)) THEN - ALLOCATE(DstDvr_OutputsData%unOutFile(i1_l:i1_u),STAT=ErrStat2) + DstBladeDataData%pitch = SrcBladeDataData%pitch + DstBladeDataData%pitchSpeed = SrcBladeDataData%pitchSpeed + DstBladeDataData%pitchAcc = SrcBladeDataData%pitchAcc + DstBladeDataData%origin_h = SrcBladeDataData%origin_h + DstBladeDataData%orientation_h = SrcBladeDataData%orientation_h + DstBladeDataData%hubRad_bl = SrcBladeDataData%hubRad_bl + DstBladeDataData%Rh2bl0 = SrcBladeDataData%Rh2bl0 + DstBladeDataData%motionType = SrcBladeDataData%motionType + DstBladeDataData%iMotion = SrcBladeDataData%iMotion +IF (ALLOCATED(SrcBladeDataData%motion)) THEN + i1_l = LBOUND(SrcBladeDataData%motion,1) + i1_u = UBOUND(SrcBladeDataData%motion,1) + i2_l = LBOUND(SrcBladeDataData%motion,2) + i2_u = UBOUND(SrcBladeDataData%motion,2) + IF (.NOT. ALLOCATED(DstBladeDataData%motion)) THEN + ALLOCATE(DstBladeDataData%motion(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvr_OutputsData%unOutFile.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeDataData%motion.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstDvr_OutputsData%unOutFile = SrcDvr_OutputsData%unOutFile + DstBladeDataData%motion = SrcBladeDataData%motion ENDIF - DstDvr_OutputsData%ActualChanLen = SrcDvr_OutputsData%ActualChanLen - DstDvr_OutputsData%nDvrOutputs = SrcDvr_OutputsData%nDvrOutputs - DstDvr_OutputsData%Fmt_t = SrcDvr_OutputsData%Fmt_t - DstDvr_OutputsData%Fmt_a = SrcDvr_OutputsData%Fmt_a - DstDvr_OutputsData%delim = SrcDvr_OutputsData%delim - DstDvr_OutputsData%outFmt = SrcDvr_OutputsData%outFmt - DstDvr_OutputsData%fileFmt = SrcDvr_OutputsData%fileFmt - DstDvr_OutputsData%wrVTK = SrcDvr_OutputsData%wrVTK - DstDvr_OutputsData%Root = SrcDvr_OutputsData%Root - DstDvr_OutputsData%VTK_OutFileRoot = SrcDvr_OutputsData%VTK_OutFileRoot -IF (ALLOCATED(SrcDvr_OutputsData%WriteOutputHdr)) THEN - i1_l = LBOUND(SrcDvr_OutputsData%WriteOutputHdr,1) - i1_u = UBOUND(SrcDvr_OutputsData%WriteOutputHdr,1) - IF (.NOT. ALLOCATED(DstDvr_OutputsData%WriteOutputHdr)) THEN - ALLOCATE(DstDvr_OutputsData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvr_OutputsData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstDvr_OutputsData%WriteOutputHdr = SrcDvr_OutputsData%WriteOutputHdr -ENDIF -IF (ALLOCATED(SrcDvr_OutputsData%WriteOutputUnt)) THEN - i1_l = LBOUND(SrcDvr_OutputsData%WriteOutputUnt,1) - i1_u = UBOUND(SrcDvr_OutputsData%WriteOutputUnt,1) - IF (.NOT. ALLOCATED(DstDvr_OutputsData%WriteOutputUnt)) THEN - ALLOCATE(DstDvr_OutputsData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvr_OutputsData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstDvr_OutputsData%WriteOutputUnt = SrcDvr_OutputsData%WriteOutputUnt -ENDIF -IF (ALLOCATED(SrcDvr_OutputsData%storage)) THEN - i1_l = LBOUND(SrcDvr_OutputsData%storage,1) - i1_u = UBOUND(SrcDvr_OutputsData%storage,1) - i2_l = LBOUND(SrcDvr_OutputsData%storage,2) - i2_u = UBOUND(SrcDvr_OutputsData%storage,2) - i3_l = LBOUND(SrcDvr_OutputsData%storage,3) - i3_u = UBOUND(SrcDvr_OutputsData%storage,3) - IF (.NOT. ALLOCATED(DstDvr_OutputsData%storage)) THEN - ALLOCATE(DstDvr_OutputsData%storage(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvr_OutputsData%storage.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstDvr_OutputsData%storage = SrcDvr_OutputsData%storage -ENDIF -IF (ALLOCATED(SrcDvr_OutputsData%outLine)) THEN - i1_l = LBOUND(SrcDvr_OutputsData%outLine,1) - i1_u = UBOUND(SrcDvr_OutputsData%outLine,1) - IF (.NOT. ALLOCATED(DstDvr_OutputsData%outLine)) THEN - ALLOCATE(DstDvr_OutputsData%outLine(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvr_OutputsData%outLine.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstDvr_OutputsData%outLine = SrcDvr_OutputsData%outLine -ENDIF -IF (ALLOCATED(SrcDvr_OutputsData%VTK_surface)) THEN - i1_l = LBOUND(SrcDvr_OutputsData%VTK_surface,1) - i1_u = UBOUND(SrcDvr_OutputsData%VTK_surface,1) - IF (.NOT. ALLOCATED(DstDvr_OutputsData%VTK_surface)) THEN - ALLOCATE(DstDvr_OutputsData%VTK_surface(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDvr_OutputsData%VTK_surface.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcDvr_OutputsData%VTK_surface,1), UBOUND(SrcDvr_OutputsData%VTK_surface,1) - CALL AD_Dvr_Copydvrvtk_surfacetype( SrcDvr_OutputsData%VTK_surface(i1), DstDvr_OutputsData%VTK_surface(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF - DstDvr_OutputsData%VTK_tWidth = SrcDvr_OutputsData%VTK_tWidth - DstDvr_OutputsData%n_VTKTime = SrcDvr_OutputsData%n_VTKTime - DstDvr_OutputsData%VTKHubRad = SrcDvr_OutputsData%VTKHubRad - DstDvr_OutputsData%VTKNacDim = SrcDvr_OutputsData%VTKNacDim - DstDvr_OutputsData%VTKRefPoint = SrcDvr_OutputsData%VTKRefPoint - END SUBROUTINE AD_Dvr_CopyDvr_Outputs + DstBladeDataData%motionFileName = SrcBladeDataData%motionFileName + END SUBROUTINE AD_Dvr_CopyBladeData - SUBROUTINE AD_Dvr_DestroyDvr_Outputs( Dvr_OutputsData, ErrStat, ErrMsg ) - TYPE(Dvr_Outputs), INTENT(INOUT) :: Dvr_OutputsData + SUBROUTINE AD_Dvr_DestroyBladeData( BladeDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(BladeData), INTENT(INOUT) :: BladeDataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyDvr_Outputs' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyBladeData' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( Dvr_OutputsData%AD_ver, ErrStat, ErrMsg ) -IF (ALLOCATED(Dvr_OutputsData%unOutFile)) THEN - DEALLOCATE(Dvr_OutputsData%unOutFile) -ENDIF -IF (ALLOCATED(Dvr_OutputsData%WriteOutputHdr)) THEN - DEALLOCATE(Dvr_OutputsData%WriteOutputHdr) -ENDIF -IF (ALLOCATED(Dvr_OutputsData%WriteOutputUnt)) THEN - DEALLOCATE(Dvr_OutputsData%WriteOutputUnt) -ENDIF -IF (ALLOCATED(Dvr_OutputsData%storage)) THEN - DEALLOCATE(Dvr_OutputsData%storage) -ENDIF -IF (ALLOCATED(Dvr_OutputsData%outLine)) THEN - DEALLOCATE(Dvr_OutputsData%outLine) -ENDIF -IF (ALLOCATED(Dvr_OutputsData%VTK_surface)) THEN -DO i1 = LBOUND(Dvr_OutputsData%VTK_surface,1), UBOUND(Dvr_OutputsData%VTK_surface,1) - CALL AD_Dvr_Destroydvrvtk_surfacetype( Dvr_OutputsData%VTK_surface(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(Dvr_OutputsData%VTK_surface) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(BladeDataData%motion)) THEN + DEALLOCATE(BladeDataData%motion) ENDIF - END SUBROUTINE AD_Dvr_DestroyDvr_Outputs + END SUBROUTINE AD_Dvr_DestroyBladeData - SUBROUTINE AD_Dvr_PackDvr_Outputs( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE AD_Dvr_PackBladeData( 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(Dvr_Outputs), INTENT(IN) :: InData + TYPE(BladeData), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -1165,7 +1476,7 @@ SUBROUTINE AD_Dvr_PackDvr_Outputs( 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 = 'AD_Dvr_PackDvr_Outputs' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_PackBladeData' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -1181,87 +1492,21 @@ SUBROUTINE AD_Dvr_PackDvr_Outputs( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, 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 ! AD_ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%AD_ver, ErrStat2, ErrMsg2, .TRUE. ) ! AD_ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! AD_ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! AD_ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! AD_ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 1 ! unOutFile allocated yes/no - IF ( ALLOCATED(InData%unOutFile) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! unOutFile upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%unOutFile) ! unOutFile - END IF - Int_BufSz = Int_BufSz + 1 ! ActualChanLen - Int_BufSz = Int_BufSz + 1 ! nDvrOutputs - Int_BufSz = Int_BufSz + 1*LEN(InData%Fmt_t) ! Fmt_t - Int_BufSz = Int_BufSz + 1*LEN(InData%Fmt_a) ! Fmt_a - Int_BufSz = Int_BufSz + 1*LEN(InData%delim) ! delim - Int_BufSz = Int_BufSz + 1*LEN(InData%outFmt) ! outFmt - Int_BufSz = Int_BufSz + 1 ! fileFmt - Int_BufSz = Int_BufSz + 1 ! wrVTK - Int_BufSz = Int_BufSz + 1*LEN(InData%Root) ! Root - Int_BufSz = Int_BufSz + 1*LEN(InData%VTK_OutFileRoot) ! VTK_OutFileRoot - 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 - Int_BufSz = Int_BufSz + 1 ! storage allocated yes/no - IF ( ALLOCATED(InData%storage) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! storage upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%storage) ! storage - END IF - Int_BufSz = Int_BufSz + 1 ! outLine allocated yes/no - IF ( ALLOCATED(InData%outLine) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! outLine upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%outLine) ! outLine - END IF - Int_BufSz = Int_BufSz + 1 ! VTK_surface allocated yes/no - IF ( ALLOCATED(InData%VTK_surface) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! VTK_surface upper/lower bounds for each dimension - DO i1 = LBOUND(InData%VTK_surface,1), UBOUND(InData%VTK_surface,1) - Int_BufSz = Int_BufSz + 3 ! VTK_surface: size of buffers for each call to pack subtype - CALL AD_Dvr_Packdvrvtk_surfacetype( Re_Buf, Db_Buf, Int_Buf, InData%VTK_surface(i1), ErrStat2, ErrMsg2, .TRUE. ) ! VTK_surface - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! VTK_surface - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! VTK_surface - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! VTK_surface - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO + Re_BufSz = Re_BufSz + 1 ! pitch + Re_BufSz = Re_BufSz + 1 ! pitchSpeed + Re_BufSz = Re_BufSz + 1 ! pitchAcc + Re_BufSz = Re_BufSz + SIZE(InData%origin_h) ! origin_h + Re_BufSz = Re_BufSz + SIZE(InData%orientation_h) ! orientation_h + Re_BufSz = Re_BufSz + 1 ! hubRad_bl + Db_BufSz = Db_BufSz + SIZE(InData%Rh2bl0) ! Rh2bl0 + Int_BufSz = Int_BufSz + 1 ! motionType + Int_BufSz = Int_BufSz + 1 ! iMotion + Int_BufSz = Int_BufSz + 1 ! motion allocated yes/no + IF ( ALLOCATED(InData%motion) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! motion upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%motion) ! motion END IF - Int_BufSz = Int_BufSz + 1 ! VTK_tWidth - Int_BufSz = Int_BufSz + 1 ! n_VTKTime - Re_BufSz = Re_BufSz + 1 ! VTKHubRad - Re_BufSz = Re_BufSz + SIZE(InData%VTKNacDim) ! VTKNacDim - Re_BufSz = Re_BufSz + SIZE(InData%VTKRefPoint) ! VTKRefPoint + Int_BufSz = Int_BufSz + 1*LEN(InData%motionFileName) ! motionFileName IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1289,217 +1534,63 @@ SUBROUTINE AD_Dvr_PackDvr_Outputs( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = 1 Int_Xferred = 1 - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%AD_ver, ErrStat2, ErrMsg2, OnlySize ) ! AD_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%unOutFile) ) THEN - IntKiBuf( Int_Xferred ) = 0 + ReKiBuf(Re_Xferred) = InData%pitch + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%pitchSpeed + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%pitchAcc + Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%origin_h,1), UBOUND(InData%origin_h,1) + ReKiBuf(Re_Xferred) = InData%origin_h(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%orientation_h,1), UBOUND(InData%orientation_h,1) + ReKiBuf(Re_Xferred) = InData%orientation_h(i1) + Re_Xferred = Re_Xferred + 1 + END DO + ReKiBuf(Re_Xferred) = InData%hubRad_bl + Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(InData%Rh2bl0,2), UBOUND(InData%Rh2bl0,2) + DO i1 = LBOUND(InData%Rh2bl0,1), UBOUND(InData%Rh2bl0,1) + DbKiBuf(Db_Xferred) = InData%Rh2bl0(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + IntKiBuf(Int_Xferred) = InData%motionType Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%unOutFile,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%unOutFile,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%unOutFile,1), UBOUND(InData%unOutFile,1) - IntKiBuf(Int_Xferred) = InData%unOutFile(i1) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - IntKiBuf(Int_Xferred) = InData%ActualChanLen - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%nDvrOutputs - Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(InData%Fmt_t) - IntKiBuf(Int_Xferred) = ICHAR(InData%Fmt_t(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - DO I = 1, LEN(InData%Fmt_a) - IntKiBuf(Int_Xferred) = ICHAR(InData%Fmt_a(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - 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 - IntKiBuf(Int_Xferred) = InData%fileFmt - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%wrVTK - Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(InData%Root) - IntKiBuf(Int_Xferred) = ICHAR(InData%Root(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - DO I = 1, LEN(InData%VTK_OutFileRoot) - IntKiBuf(Int_Xferred) = ICHAR(InData%VTK_OutFileRoot(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - 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 + IntKiBuf(Int_Xferred) = InData%iMotion 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 - IF ( .NOT. ALLOCATED(InData%storage) ) THEN + IF ( .NOT. ALLOCATED(InData%motion) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%storage,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%storage,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%storage,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%storage,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%motion,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%motion,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%storage,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%storage,3) + IntKiBuf( Int_Xferred ) = LBOUND(InData%motion,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%motion,2) Int_Xferred = Int_Xferred + 2 - DO i3 = LBOUND(InData%storage,3), UBOUND(InData%storage,3) - DO i2 = LBOUND(InData%storage,2), UBOUND(InData%storage,2) - DO i1 = LBOUND(InData%storage,1), UBOUND(InData%storage,1) - ReKiBuf(Re_Xferred) = InData%storage(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO + DO i2 = LBOUND(InData%motion,2), UBOUND(InData%motion,2) + DO i1 = LBOUND(InData%motion,1), UBOUND(InData%motion,1) + ReKiBuf(Re_Xferred) = InData%motion(i1,i2) + Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%outLine) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%outLine,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%outLine,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%outLine,1), UBOUND(InData%outLine,1) - ReKiBuf(Re_Xferred) = InData%outLine(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%VTK_surface) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%VTK_surface,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VTK_surface,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%VTK_surface,1), UBOUND(InData%VTK_surface,1) - CALL AD_Dvr_Packdvrvtk_surfacetype( Re_Buf, Db_Buf, Int_Buf, InData%VTK_surface(i1), ErrStat2, ErrMsg2, OnlySize ) ! VTK_surface - 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%VTK_tWidth - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%n_VTKTime - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VTKHubRad - Re_Xferred = Re_Xferred + 1 - DO i1 = LBOUND(InData%VTKNacDim,1), UBOUND(InData%VTKNacDim,1) - ReKiBuf(Re_Xferred) = InData%VTKNacDim(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%VTKRefPoint,1), UBOUND(InData%VTKRefPoint,1) - ReKiBuf(Re_Xferred) = InData%VTKRefPoint(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE AD_Dvr_PackDvr_Outputs + DO I = 1, LEN(InData%motionFileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%motionFileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END SUBROUTINE AD_Dvr_PackBladeData - SUBROUTINE AD_Dvr_UnPackDvr_Outputs( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_Dvr_UnPackBladeData( 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(Dvr_Outputs), INTENT(INOUT) :: OutData + TYPE(BladeData), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -1510,10 +1601,9 @@ SUBROUTINE AD_Dvr_UnPackDvr_Outputs( 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 = 'AD_Dvr_UnPackDvr_Outputs' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_UnPackBladeData' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -1524,137 +1614,41 @@ SUBROUTINE AD_Dvr_UnPackDvr_Outputs( 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 NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%AD_ver, ErrStat2, ErrMsg2 ) ! AD_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 ! unOutFile not allocated + OutData%pitch = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%pitchSpeed = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%pitchAcc = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%origin_h,1) + i1_u = UBOUND(OutData%origin_h,1) + DO i1 = LBOUND(OutData%origin_h,1), UBOUND(OutData%origin_h,1) + OutData%origin_h(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%orientation_h,1) + i1_u = UBOUND(OutData%orientation_h,1) + DO i1 = LBOUND(OutData%orientation_h,1), UBOUND(OutData%orientation_h,1) + OutData%orientation_h(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%hubRad_bl = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%Rh2bl0,1) + i1_u = UBOUND(OutData%Rh2bl0,1) + i2_l = LBOUND(OutData%Rh2bl0,2) + i2_u = UBOUND(OutData%Rh2bl0,2) + DO i2 = LBOUND(OutData%Rh2bl0,2), UBOUND(OutData%Rh2bl0,2) + DO i1 = LBOUND(OutData%Rh2bl0,1), UBOUND(OutData%Rh2bl0,1) + OutData%Rh2bl0(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + OutData%motionType = 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 - IF (ALLOCATED(OutData%unOutFile)) DEALLOCATE(OutData%unOutFile) - ALLOCATE(OutData%unOutFile(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%unOutFile.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%unOutFile,1), UBOUND(OutData%unOutFile,1) - OutData%unOutFile(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - OutData%ActualChanLen = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%nDvrOutputs = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(OutData%Fmt_t) - OutData%Fmt_t(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - DO I = 1, LEN(OutData%Fmt_a) - OutData%Fmt_a(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - DO I = 1, LEN(OutData%delim) - OutData%delim(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - DO I = 1, LEN(OutData%outFmt) - OutData%outFmt(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%fileFmt = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%wrVTK = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(OutData%Root) - OutData%Root(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - DO I = 1, LEN(OutData%VTK_OutFileRoot) - OutData%VTK_OutFileRoot(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - 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 + OutData%iMotion = IntKiBuf(Int_Xferred) 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 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! storage not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! motion not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -1664,188 +1658,96 @@ SUBROUTINE AD_Dvr_UnPackDvr_Outputs( 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 - IF (ALLOCATED(OutData%storage)) DEALLOCATE(OutData%storage) - ALLOCATE(OutData%storage(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%motion)) DEALLOCATE(OutData%motion) + ALLOCATE(OutData%motion(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%storage.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%motion.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i3 = LBOUND(OutData%storage,3), UBOUND(OutData%storage,3) - DO i2 = LBOUND(OutData%storage,2), UBOUND(OutData%storage,2) - DO i1 = LBOUND(OutData%storage,1), UBOUND(OutData%storage,1) - OutData%storage(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + DO i2 = LBOUND(OutData%motion,2), UBOUND(OutData%motion,2) + DO i1 = LBOUND(OutData%motion,1), UBOUND(OutData%motion,1) + OutData%motion(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! outLine not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%outLine)) DEALLOCATE(OutData%outLine) - ALLOCATE(OutData%outLine(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%outLine.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%outLine,1), UBOUND(OutData%outLine,1) - OutData%outLine(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VTK_surface not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%VTK_surface)) DEALLOCATE(OutData%VTK_surface) - ALLOCATE(OutData%VTK_surface(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VTK_surface.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%VTK_surface,1), UBOUND(OutData%VTK_surface,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 ) + DO I = 1, LEN(OutData%motionFileName) + OutData%motionFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AD_Dvr_Unpackdvrvtk_surfacetype( Re_Buf, Db_Buf, Int_Buf, OutData%VTK_surface(i1), ErrStat2, ErrMsg2 ) ! VTK_surface - 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%VTK_tWidth = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%n_VTKTime = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%VTKHubRad = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - i1_l = LBOUND(OutData%VTKNacDim,1) - i1_u = UBOUND(OutData%VTKNacDim,1) - DO i1 = LBOUND(OutData%VTKNacDim,1), UBOUND(OutData%VTKNacDim,1) - OutData%VTKNacDim(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%VTKRefPoint,1) - i1_u = UBOUND(OutData%VTKRefPoint,1) - DO i1 = LBOUND(OutData%VTKRefPoint,1), UBOUND(OutData%VTKRefPoint,1) - OutData%VTKRefPoint(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE AD_Dvr_UnPackDvr_Outputs + END DO ! I + END SUBROUTINE AD_Dvr_UnPackBladeData - SUBROUTINE AD_Dvr_CopyAeroDyn_Data( SrcAeroDyn_DataData, DstAeroDyn_DataData, CtrlCode, ErrStat, ErrMsg ) - TYPE(AeroDyn_Data), INTENT(INOUT) :: SrcAeroDyn_DataData - TYPE(AeroDyn_Data), INTENT(INOUT) :: DstAeroDyn_DataData + SUBROUTINE AD_Dvr_CopyHubData( SrcHubDataData, DstHubDataData, CtrlCode, ErrStat, ErrMsg ) + TYPE(HubData), INTENT(IN) :: SrcHubDataData + TYPE(HubData), INTENT(INOUT) :: DstHubDataData 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 = 'AD_Dvr_CopyAeroDyn_Data' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_CopyHubData' ! ErrStat = ErrID_None ErrMsg = "" - CALL AD_CopyContState( SrcAeroDyn_DataData%x, DstAeroDyn_DataData%x, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL AD_CopyDiscState( SrcAeroDyn_DataData%xd, DstAeroDyn_DataData%xd, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL AD_CopyConstrState( SrcAeroDyn_DataData%z, DstAeroDyn_DataData%z, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL AD_CopyOtherState( SrcAeroDyn_DataData%OtherState, DstAeroDyn_DataData%OtherState, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL AD_CopyMisc( SrcAeroDyn_DataData%m, DstAeroDyn_DataData%m, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL AD_CopyParam( SrcAeroDyn_DataData%p, DstAeroDyn_DataData%p, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - DO i1 = LBOUND(SrcAeroDyn_DataData%u,1), UBOUND(SrcAeroDyn_DataData%u,1) - CALL AD_CopyInput( SrcAeroDyn_DataData%u(i1), DstAeroDyn_DataData%u(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO - CALL AD_CopyOutput( SrcAeroDyn_DataData%y, DstAeroDyn_DataData%y, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - DstAeroDyn_DataData%InputTime = SrcAeroDyn_DataData%InputTime - END SUBROUTINE AD_Dvr_CopyAeroDyn_Data + DstHubDataData%origin_n = SrcHubDataData%origin_n + DstHubDataData%orientation_n = SrcHubDataData%orientation_n + DstHubDataData%motionType = SrcHubDataData%motionType + DstHubDataData%iMotion = SrcHubDataData%iMotion + DstHubDataData%azimuth = SrcHubDataData%azimuth + DstHubDataData%rotSpeed = SrcHubDataData%rotSpeed + DstHubDataData%rotAcc = SrcHubDataData%rotAcc + DstHubDataData%motionFileName = SrcHubDataData%motionFileName +IF (ALLOCATED(SrcHubDataData%motion)) THEN + i1_l = LBOUND(SrcHubDataData%motion,1) + i1_u = UBOUND(SrcHubDataData%motion,1) + i2_l = LBOUND(SrcHubDataData%motion,2) + i2_u = UBOUND(SrcHubDataData%motion,2) + IF (.NOT. ALLOCATED(DstHubDataData%motion)) THEN + ALLOCATE(DstHubDataData%motion(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstHubDataData%motion.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstHubDataData%motion = SrcHubDataData%motion +ENDIF + END SUBROUTINE AD_Dvr_CopyHubData - SUBROUTINE AD_Dvr_DestroyAeroDyn_Data( AeroDyn_DataData, ErrStat, ErrMsg ) - TYPE(AeroDyn_Data), INTENT(INOUT) :: AeroDyn_DataData + SUBROUTINE AD_Dvr_DestroyHubData( HubDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(HubData), INTENT(INOUT) :: HubDataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyAeroDyn_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyHubData' + ErrStat = ErrID_None ErrMsg = "" - CALL AD_DestroyContState( AeroDyn_DataData%x, ErrStat, ErrMsg ) - CALL AD_DestroyDiscState( AeroDyn_DataData%xd, ErrStat, ErrMsg ) - CALL AD_DestroyConstrState( AeroDyn_DataData%z, ErrStat, ErrMsg ) - CALL AD_DestroyOtherState( AeroDyn_DataData%OtherState, ErrStat, ErrMsg ) - CALL AD_DestroyMisc( AeroDyn_DataData%m, ErrStat, ErrMsg ) - CALL AD_DestroyParam( AeroDyn_DataData%p, ErrStat, ErrMsg ) -DO i1 = LBOUND(AeroDyn_DataData%u,1), UBOUND(AeroDyn_DataData%u,1) - CALL AD_DestroyInput( AeroDyn_DataData%u(i1), ErrStat, ErrMsg ) -ENDDO - CALL AD_DestroyOutput( AeroDyn_DataData%y, ErrStat, ErrMsg ) - END SUBROUTINE AD_Dvr_DestroyAeroDyn_Data - SUBROUTINE AD_Dvr_PackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(HubDataData%motion)) THEN + DEALLOCATE(HubDataData%motion) +ENDIF + END SUBROUTINE AD_Dvr_DestroyHubData + + SUBROUTINE AD_Dvr_PackHubData( 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(AeroDyn_Data), INTENT(IN) :: InData + TYPE(HubData), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -1860,7 +1762,7 @@ SUBROUTINE AD_Dvr_PackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_PackAeroDyn_Data' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_PackHubData' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -1876,146 +1778,19 @@ SUBROUTINE AD_Dvr_PackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, 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 ! x: size of buffers for each call to pack subtype - CALL AD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, .TRUE. ) ! x - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! x - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! x - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! x - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! xd: size of buffers for each call to pack subtype - CALL AD_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, .TRUE. ) ! xd - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! xd - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! xd - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! xd - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! z: size of buffers for each call to pack subtype - CALL AD_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, .TRUE. ) ! z - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! z - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! z - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! z - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! OtherState: size of buffers for each call to pack subtype - CALL AD_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherState, ErrStat2, ErrMsg2, .TRUE. ) ! OtherState - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! OtherState - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! OtherState - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! OtherState - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! m: size of buffers for each call to pack subtype - CALL AD_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! m - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! m - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! m - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! p: size of buffers for each call to pack subtype - CALL AD_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! p - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! p - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! p - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - DO i1 = LBOUND(InData%u,1), UBOUND(InData%u,1) - Int_BufSz = Int_BufSz + 3 ! u: size of buffers for each call to pack subtype - CALL AD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u(i1), ErrStat2, ErrMsg2, .TRUE. ) ! u - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! u - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! u - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! u - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - Int_BufSz = Int_BufSz + 3 ! y: size of buffers for each call to pack subtype - CALL AD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! y - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! y - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! y - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Db_BufSz = Db_BufSz + SIZE(InData%InputTime) ! InputTime + Re_BufSz = Re_BufSz + SIZE(InData%origin_n) ! origin_n + Re_BufSz = Re_BufSz + SIZE(InData%orientation_n) ! orientation_n + Int_BufSz = Int_BufSz + 1 ! motionType + Int_BufSz = Int_BufSz + 1 ! iMotion + Re_BufSz = Re_BufSz + 1 ! azimuth + Re_BufSz = Re_BufSz + 1 ! rotSpeed + Re_BufSz = Re_BufSz + 1 ! rotAcc + Int_BufSz = Int_BufSz + 1*LEN(InData%motionFileName) ! motionFileName + Int_BufSz = Int_BufSz + 1 ! motion allocated yes/no + IF ( ALLOCATED(InData%motion) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! motion upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%motion) ! motion + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -2043,2892 +1818,55 @@ SUBROUTINE AD_Dvr_PackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = 1 Int_Xferred = 1 - CALL AD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, OnlySize ) ! x - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL AD_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, OnlySize ) ! xd - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL AD_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, OnlySize ) ! z - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + DO i1 = LBOUND(InData%origin_n,1), UBOUND(InData%origin_n,1) + ReKiBuf(Re_Xferred) = InData%origin_n(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%orientation_n,1), UBOUND(InData%orientation_n,1) + ReKiBuf(Re_Xferred) = InData%orientation_n(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%motionType + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%iMotion + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%azimuth + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%rotSpeed + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%rotAcc + Re_Xferred = Re_Xferred + 1 + DO I = 1, LEN(InData%motionFileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%motionFileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IF ( .NOT. ALLOCATED(InData%motion) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%motion,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%motion,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%motion,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%motion,2) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL AD_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherState, ErrStat2, ErrMsg2, OnlySize ) ! OtherState - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + DO i2 = LBOUND(InData%motion,2), UBOUND(InData%motion,2) + DO i1 = LBOUND(InData%motion,1), UBOUND(InData%motion,1) + ReKiBuf(Re_Xferred) = InData%motion(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + END SUBROUTINE AD_Dvr_PackHubData - 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 AD_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL AD_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - DO i1 = LBOUND(InData%u,1), UBOUND(InData%u,1) - CALL AD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u(i1), ErrStat2, ErrMsg2, OnlySize ) ! u - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END DO - CALL AD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - DO i1 = LBOUND(InData%InputTime,1), UBOUND(InData%InputTime,1) - DbKiBuf(Db_Xferred) = InData%InputTime(i1) - Db_Xferred = Db_Xferred + 1 - END DO - END SUBROUTINE AD_Dvr_PackAeroDyn_Data - - SUBROUTINE AD_Dvr_UnPackAeroDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(AeroDyn_Data), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_UnPackAeroDyn_Data' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AD_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%x, ErrStat2, ErrMsg2 ) ! x - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AD_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%xd, ErrStat2, ErrMsg2 ) ! xd - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AD_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%z, ErrStat2, ErrMsg2 ) ! z - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AD_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%OtherState, ErrStat2, ErrMsg2 ) ! OtherState - 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 AD_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AD_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%p, ErrStat2, ErrMsg2 ) ! p - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - i1_l = LBOUND(OutData%u,1) - i1_u = UBOUND(OutData%u,1) - DO i1 = LBOUND(OutData%u,1), UBOUND(OutData%u,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u(i1), ErrStat2, ErrMsg2 ) ! u - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END DO - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AD_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - i1_l = LBOUND(OutData%InputTime,1) - i1_u = UBOUND(OutData%InputTime,1) - DO i1 = LBOUND(OutData%InputTime,1), UBOUND(OutData%InputTime,1) - OutData%InputTime(i1) = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 - END DO - END SUBROUTINE AD_Dvr_UnPackAeroDyn_Data - - SUBROUTINE AD_Dvr_CopyInflowWind_Data( SrcInflowWind_DataData, DstInflowWind_DataData, CtrlCode, ErrStat, ErrMsg ) - TYPE(InflowWind_Data), INTENT(IN) :: SrcInflowWind_DataData - TYPE(InflowWind_Data), INTENT(INOUT) :: DstInflowWind_DataData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_CopyInflowWind_Data' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL InflowWind_CopyContState( SrcInflowWind_DataData%x, DstInflowWind_DataData%x, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL InflowWind_CopyDiscState( SrcInflowWind_DataData%xd, DstInflowWind_DataData%xd, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL InflowWind_CopyConstrState( SrcInflowWind_DataData%z, DstInflowWind_DataData%z, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL InflowWind_CopyOtherState( SrcInflowWind_DataData%OtherSt, DstInflowWind_DataData%OtherSt, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL InflowWind_CopyParam( SrcInflowWind_DataData%p, DstInflowWind_DataData%p, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL InflowWind_CopyMisc( SrcInflowWind_DataData%m, DstInflowWind_DataData%m, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - DO i1 = LBOUND(SrcInflowWind_DataData%u,1), UBOUND(SrcInflowWind_DataData%u,1) - CALL InflowWind_CopyInput( SrcInflowWind_DataData%u(i1), DstInflowWind_DataData%u(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO - CALL InflowWind_CopyOutput( SrcInflowWind_DataData%y, DstInflowWind_DataData%y, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - DstInflowWind_DataData%InputTimes = SrcInflowWind_DataData%InputTimes - END SUBROUTINE AD_Dvr_CopyInflowWind_Data - - SUBROUTINE AD_Dvr_DestroyInflowWind_Data( InflowWind_DataData, ErrStat, ErrMsg ) - TYPE(InflowWind_Data), INTENT(INOUT) :: InflowWind_DataData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyInflowWind_Data' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL InflowWind_DestroyContState( InflowWind_DataData%x, ErrStat, ErrMsg ) - CALL InflowWind_DestroyDiscState( InflowWind_DataData%xd, ErrStat, ErrMsg ) - CALL InflowWind_DestroyConstrState( InflowWind_DataData%z, ErrStat, ErrMsg ) - CALL InflowWind_DestroyOtherState( InflowWind_DataData%OtherSt, ErrStat, ErrMsg ) - CALL InflowWind_DestroyParam( InflowWind_DataData%p, ErrStat, ErrMsg ) - CALL InflowWind_DestroyMisc( InflowWind_DataData%m, ErrStat, ErrMsg ) -DO i1 = LBOUND(InflowWind_DataData%u,1), UBOUND(InflowWind_DataData%u,1) - CALL InflowWind_DestroyInput( InflowWind_DataData%u(i1), ErrStat, ErrMsg ) -ENDDO - CALL InflowWind_DestroyOutput( InflowWind_DataData%y, ErrStat, ErrMsg ) - END SUBROUTINE AD_Dvr_DestroyInflowWind_Data - - SUBROUTINE AD_Dvr_PackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(InflowWind_Data), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_PackInflowWind_Data' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! x: size of buffers for each call to pack subtype - CALL InflowWind_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, .TRUE. ) ! x - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! x - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! x - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! x - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! xd: size of buffers for each call to pack subtype - CALL InflowWind_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, .TRUE. ) ! xd - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! xd - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! xd - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! xd - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! z: size of buffers for each call to pack subtype - CALL InflowWind_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, .TRUE. ) ! z - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! z - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! z - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! z - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! OtherSt: size of buffers for each call to pack subtype - CALL InflowWind_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, .TRUE. ) ! OtherSt - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! OtherSt - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! OtherSt - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! OtherSt - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! p: size of buffers for each call to pack subtype - CALL InflowWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! p - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! p - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! p - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! m: size of buffers for each call to pack subtype - CALL InflowWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! m - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! m - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! m - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - DO i1 = LBOUND(InData%u,1), UBOUND(InData%u,1) - Int_BufSz = Int_BufSz + 3 ! u: size of buffers for each call to pack subtype - CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u(i1), ErrStat2, ErrMsg2, .TRUE. ) ! u - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! u - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! u - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! u - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - Int_BufSz = Int_BufSz + 3 ! y: size of buffers for each call to pack subtype - CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! y - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! y - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! y - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Db_BufSz = Db_BufSz + SIZE(InData%InputTimes) ! InputTimes - 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 InflowWind_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, OnlySize ) ! x - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL InflowWind_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, OnlySize ) ! xd - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL InflowWind_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, OnlySize ) ! z - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL InflowWind_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, OnlySize ) ! OtherSt - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL InflowWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL InflowWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - DO i1 = LBOUND(InData%u,1), UBOUND(InData%u,1) - CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u(i1), ErrStat2, ErrMsg2, OnlySize ) ! u - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END DO - CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - DO i1 = LBOUND(InData%InputTimes,1), UBOUND(InData%InputTimes,1) - DbKiBuf(Db_Xferred) = InData%InputTimes(i1) - Db_Xferred = Db_Xferred + 1 - END DO - END SUBROUTINE AD_Dvr_PackInflowWind_Data - - SUBROUTINE AD_Dvr_UnPackInflowWind_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(InflowWind_Data), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_UnPackInflowWind_Data' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL InflowWind_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%x, ErrStat2, ErrMsg2 ) ! x - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL InflowWind_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%xd, ErrStat2, ErrMsg2 ) ! xd - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL InflowWind_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%z, ErrStat2, ErrMsg2 ) ! z - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL InflowWind_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%OtherSt, ErrStat2, ErrMsg2 ) ! OtherSt - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL InflowWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%p, ErrStat2, ErrMsg2 ) ! p - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL InflowWind_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - i1_l = LBOUND(OutData%u,1) - i1_u = UBOUND(OutData%u,1) - DO i1 = LBOUND(OutData%u,1), UBOUND(OutData%u,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL InflowWind_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u(i1), ErrStat2, ErrMsg2 ) ! u - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END DO - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL InflowWind_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - i1_l = LBOUND(OutData%InputTimes,1) - i1_u = UBOUND(OutData%InputTimes,1) - DO i1 = LBOUND(OutData%InputTimes,1), UBOUND(OutData%InputTimes,1) - OutData%InputTimes(i1) = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 - END DO - END SUBROUTINE AD_Dvr_UnPackInflowWind_Data - - SUBROUTINE AD_Dvr_CopyBladeData( SrcBladeDataData, DstBladeDataData, CtrlCode, ErrStat, ErrMsg ) - TYPE(BladeData), INTENT(INOUT) :: SrcBladeDataData - TYPE(BladeData), INTENT(INOUT) :: DstBladeDataData - 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 = 'AD_Dvr_CopyBladeData' -! - ErrStat = ErrID_None - ErrMsg = "" - DstBladeDataData%pitch = SrcBladeDataData%pitch - DstBladeDataData%pitchSpeed = SrcBladeDataData%pitchSpeed - DstBladeDataData%pitchAcc = SrcBladeDataData%pitchAcc - DstBladeDataData%origin_h = SrcBladeDataData%origin_h - DstBladeDataData%orientation_h = SrcBladeDataData%orientation_h - DstBladeDataData%hubRad_bl = SrcBladeDataData%hubRad_bl - DstBladeDataData%Rh2bl0 = SrcBladeDataData%Rh2bl0 - DstBladeDataData%motionType = SrcBladeDataData%motionType - DstBladeDataData%iMotion = SrcBladeDataData%iMotion -IF (ALLOCATED(SrcBladeDataData%motion)) THEN - i1_l = LBOUND(SrcBladeDataData%motion,1) - i1_u = UBOUND(SrcBladeDataData%motion,1) - i2_l = LBOUND(SrcBladeDataData%motion,2) - i2_u = UBOUND(SrcBladeDataData%motion,2) - IF (.NOT. ALLOCATED(DstBladeDataData%motion)) THEN - ALLOCATE(DstBladeDataData%motion(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeDataData%motion.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladeDataData%motion = SrcBladeDataData%motion -ENDIF - DstBladeDataData%motionFileName = SrcBladeDataData%motionFileName - CALL MeshCopy( SrcBladeDataData%ptMesh, DstBladeDataData%ptMesh, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcBladeDataData%ED_P_2_AD_P_R, DstBladeDataData%ED_P_2_AD_P_R, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcBladeDataData%AD_P_2_AD_L_B, DstBladeDataData%AD_P_2_AD_L_B, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE AD_Dvr_CopyBladeData - - SUBROUTINE AD_Dvr_DestroyBladeData( BladeDataData, ErrStat, ErrMsg ) - TYPE(BladeData), INTENT(INOUT) :: BladeDataData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyBladeData' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(BladeDataData%motion)) THEN - DEALLOCATE(BladeDataData%motion) -ENDIF - CALL MeshDestroy( BladeDataData%ptMesh, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( BladeDataData%ED_P_2_AD_P_R, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( BladeDataData%AD_P_2_AD_L_B, ErrStat, ErrMsg ) - END SUBROUTINE AD_Dvr_DestroyBladeData - - SUBROUTINE AD_Dvr_PackBladeData( 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(BladeData), 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 = 'AD_Dvr_PackBladeData' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! pitch - Re_BufSz = Re_BufSz + 1 ! pitchSpeed - Re_BufSz = Re_BufSz + 1 ! pitchAcc - Re_BufSz = Re_BufSz + SIZE(InData%origin_h) ! origin_h - Re_BufSz = Re_BufSz + SIZE(InData%orientation_h) ! orientation_h - Re_BufSz = Re_BufSz + 1 ! hubRad_bl - Db_BufSz = Db_BufSz + SIZE(InData%Rh2bl0) ! Rh2bl0 - Int_BufSz = Int_BufSz + 1 ! motionType - Int_BufSz = Int_BufSz + 1 ! iMotion - Int_BufSz = Int_BufSz + 1 ! motion allocated yes/no - IF ( ALLOCATED(InData%motion) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! motion upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%motion) ! motion - END IF - Int_BufSz = Int_BufSz + 1*LEN(InData%motionFileName) ! motionFileName - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! ptMesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! ptMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! ptMesh - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! ptMesh - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! ptMesh - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_R: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_R, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_R - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_R - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_R - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_R - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! AD_P_2_AD_L_B: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_AD_L_B, ErrStat2, ErrMsg2, .TRUE. ) ! AD_P_2_AD_L_B - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! AD_P_2_AD_L_B - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! AD_P_2_AD_L_B - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! AD_P_2_AD_L_B - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%pitch - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%pitchSpeed - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%pitchAcc - Re_Xferred = Re_Xferred + 1 - DO i1 = LBOUND(InData%origin_h,1), UBOUND(InData%origin_h,1) - ReKiBuf(Re_Xferred) = InData%origin_h(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%orientation_h,1), UBOUND(InData%orientation_h,1) - ReKiBuf(Re_Xferred) = InData%orientation_h(i1) - Re_Xferred = Re_Xferred + 1 - END DO - ReKiBuf(Re_Xferred) = InData%hubRad_bl - Re_Xferred = Re_Xferred + 1 - DO i2 = LBOUND(InData%Rh2bl0,2), UBOUND(InData%Rh2bl0,2) - DO i1 = LBOUND(InData%Rh2bl0,1), UBOUND(InData%Rh2bl0,1) - DbKiBuf(Db_Xferred) = InData%Rh2bl0(i1,i2) - Db_Xferred = Db_Xferred + 1 - END DO - END DO - IntKiBuf(Int_Xferred) = InData%motionType - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%iMotion - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%motion) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%motion,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%motion,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%motion,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%motion,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%motion,2), UBOUND(InData%motion,2) - DO i1 = LBOUND(InData%motion,1), UBOUND(InData%motion,1) - ReKiBuf(Re_Xferred) = InData%motion(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - DO I = 1, LEN(InData%motionFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%motionFileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - CALL MeshPack( InData%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! ptMesh - 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_AD_P_R, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_R - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_AD_L_B, ErrStat2, ErrMsg2, OnlySize ) ! AD_P_2_AD_L_B - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE AD_Dvr_PackBladeData - - SUBROUTINE AD_Dvr_UnPackBladeData( 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(BladeData), 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 = 'AD_Dvr_UnPackBladeData' - ! 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%pitch = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%pitchSpeed = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%pitchAcc = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - i1_l = LBOUND(OutData%origin_h,1) - i1_u = UBOUND(OutData%origin_h,1) - DO i1 = LBOUND(OutData%origin_h,1), UBOUND(OutData%origin_h,1) - OutData%origin_h(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%orientation_h,1) - i1_u = UBOUND(OutData%orientation_h,1) - DO i1 = LBOUND(OutData%orientation_h,1), UBOUND(OutData%orientation_h,1) - OutData%orientation_h(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%hubRad_bl = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - i1_l = LBOUND(OutData%Rh2bl0,1) - i1_u = UBOUND(OutData%Rh2bl0,1) - i2_l = LBOUND(OutData%Rh2bl0,2) - i2_u = UBOUND(OutData%Rh2bl0,2) - DO i2 = LBOUND(OutData%Rh2bl0,2), UBOUND(OutData%Rh2bl0,2) - DO i1 = LBOUND(OutData%Rh2bl0,1), UBOUND(OutData%Rh2bl0,1) - OutData%Rh2bl0(i1,i2) = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 - END DO - END DO - OutData%motionType = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%iMotion = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! motion not allocated - Int_Xferred = Int_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%motion)) DEALLOCATE(OutData%motion) - ALLOCATE(OutData%motion(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%motion.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%motion,2), UBOUND(OutData%motion,2) - DO i1 = LBOUND(OutData%motion,1), UBOUND(OutData%motion,1) - OutData%motion(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - DO I = 1, LEN(OutData%motionFileName) - OutData%motionFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - 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%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! ptMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_R, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_R - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_P_2_AD_L_B, ErrStat2, ErrMsg2 ) ! AD_P_2_AD_L_B - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE AD_Dvr_UnPackBladeData - - SUBROUTINE AD_Dvr_CopyHubData( SrcHubDataData, DstHubDataData, CtrlCode, ErrStat, ErrMsg ) - TYPE(HubData), INTENT(INOUT) :: SrcHubDataData - TYPE(HubData), INTENT(INOUT) :: DstHubDataData - 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 = 'AD_Dvr_CopyHubData' -! - ErrStat = ErrID_None - ErrMsg = "" - DstHubDataData%origin_n = SrcHubDataData%origin_n - DstHubDataData%orientation_n = SrcHubDataData%orientation_n - DstHubDataData%motionType = SrcHubDataData%motionType - DstHubDataData%iMotion = SrcHubDataData%iMotion - DstHubDataData%azimuth = SrcHubDataData%azimuth - DstHubDataData%rotSpeed = SrcHubDataData%rotSpeed - DstHubDataData%rotAcc = SrcHubDataData%rotAcc - DstHubDataData%motionFileName = SrcHubDataData%motionFileName -IF (ALLOCATED(SrcHubDataData%motion)) THEN - i1_l = LBOUND(SrcHubDataData%motion,1) - i1_u = UBOUND(SrcHubDataData%motion,1) - i2_l = LBOUND(SrcHubDataData%motion,2) - i2_u = UBOUND(SrcHubDataData%motion,2) - IF (.NOT. ALLOCATED(DstHubDataData%motion)) THEN - ALLOCATE(DstHubDataData%motion(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstHubDataData%motion.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstHubDataData%motion = SrcHubDataData%motion -ENDIF - CALL MeshCopy( SrcHubDataData%ptMesh, DstHubDataData%ptMesh, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcHubDataData%ED_P_2_AD_P_H, DstHubDataData%ED_P_2_AD_P_H, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN -IF (ALLOCATED(SrcHubDataData%map2BldPt)) THEN - i1_l = LBOUND(SrcHubDataData%map2BldPt,1) - i1_u = UBOUND(SrcHubDataData%map2BldPt,1) - IF (.NOT. ALLOCATED(DstHubDataData%map2BldPt)) THEN - ALLOCATE(DstHubDataData%map2BldPt(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstHubDataData%map2BldPt.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcHubDataData%map2BldPt,1), UBOUND(SrcHubDataData%map2BldPt,1) - CALL NWTC_Library_Copymeshmaptype( SrcHubDataData%map2BldPt(i1), DstHubDataData%map2BldPt(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF - END SUBROUTINE AD_Dvr_CopyHubData - - SUBROUTINE AD_Dvr_DestroyHubData( HubDataData, ErrStat, ErrMsg ) - TYPE(HubData), INTENT(INOUT) :: HubDataData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyHubData' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(HubDataData%motion)) THEN - DEALLOCATE(HubDataData%motion) -ENDIF - CALL MeshDestroy( HubDataData%ptMesh, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( HubDataData%ED_P_2_AD_P_H, ErrStat, ErrMsg ) -IF (ALLOCATED(HubDataData%map2BldPt)) THEN -DO i1 = LBOUND(HubDataData%map2BldPt,1), UBOUND(HubDataData%map2BldPt,1) - CALL NWTC_Library_Destroymeshmaptype( HubDataData%map2BldPt(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(HubDataData%map2BldPt) -ENDIF - END SUBROUTINE AD_Dvr_DestroyHubData - - SUBROUTINE AD_Dvr_PackHubData( 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(HubData), 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 = 'AD_Dvr_PackHubData' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + SIZE(InData%origin_n) ! origin_n - Re_BufSz = Re_BufSz + SIZE(InData%orientation_n) ! orientation_n - Int_BufSz = Int_BufSz + 1 ! motionType - Int_BufSz = Int_BufSz + 1 ! iMotion - Re_BufSz = Re_BufSz + 1 ! azimuth - Re_BufSz = Re_BufSz + 1 ! rotSpeed - Re_BufSz = Re_BufSz + 1 ! rotAcc - Int_BufSz = Int_BufSz + 1*LEN(InData%motionFileName) ! motionFileName - Int_BufSz = Int_BufSz + 1 ! motion allocated yes/no - IF ( ALLOCATED(InData%motion) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! motion upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%motion) ! motion - END IF - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! ptMesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! ptMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! ptMesh - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! ptMesh - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! ptMesh - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_H: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_H - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_H - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_H - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_H - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 1 ! map2BldPt allocated yes/no - IF ( ALLOCATED(InData%map2BldPt) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! map2BldPt upper/lower bounds for each dimension - DO i1 = LBOUND(InData%map2BldPt,1), UBOUND(InData%map2BldPt,1) - Int_BufSz = Int_BufSz + 3 ! map2BldPt: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2BldPt(i1), ErrStat2, ErrMsg2, .TRUE. ) ! map2BldPt - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! map2BldPt - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! map2BldPt - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! map2BldPt - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO i1 = LBOUND(InData%origin_n,1), UBOUND(InData%origin_n,1) - ReKiBuf(Re_Xferred) = InData%origin_n(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%orientation_n,1), UBOUND(InData%orientation_n,1) - ReKiBuf(Re_Xferred) = InData%orientation_n(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = InData%motionType - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%iMotion - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%azimuth - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%rotSpeed - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%rotAcc - Re_Xferred = Re_Xferred + 1 - DO I = 1, LEN(InData%motionFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%motionFileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IF ( .NOT. ALLOCATED(InData%motion) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%motion,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%motion,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%motion,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%motion,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%motion,2), UBOUND(InData%motion,2) - DO i1 = LBOUND(InData%motion,1), UBOUND(InData%motion,1) - ReKiBuf(Re_Xferred) = InData%motion(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - CALL MeshPack( InData%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! ptMesh - 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_AD_P_H, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_H - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF ( .NOT. ALLOCATED(InData%map2BldPt) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%map2BldPt,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%map2BldPt,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%map2BldPt,1), UBOUND(InData%map2BldPt,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2BldPt(i1), ErrStat2, ErrMsg2, OnlySize ) ! map2BldPt - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END DO - END IF - END SUBROUTINE AD_Dvr_PackHubData - - SUBROUTINE AD_Dvr_UnPackHubData( 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(HubData), 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 = 'AD_Dvr_UnPackHubData' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - i1_l = LBOUND(OutData%origin_n,1) - i1_u = UBOUND(OutData%origin_n,1) - DO i1 = LBOUND(OutData%origin_n,1), UBOUND(OutData%origin_n,1) - OutData%origin_n(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%orientation_n,1) - i1_u = UBOUND(OutData%orientation_n,1) - DO i1 = LBOUND(OutData%orientation_n,1), UBOUND(OutData%orientation_n,1) - OutData%orientation_n(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%motionType = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%iMotion = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%azimuth = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%rotSpeed = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%rotAcc = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - DO I = 1, LEN(OutData%motionFileName) - OutData%motionFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! motion not allocated - Int_Xferred = Int_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%motion)) DEALLOCATE(OutData%motion) - ALLOCATE(OutData%motion(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%motion.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%motion,2), UBOUND(OutData%motion,2) - DO i1 = LBOUND(OutData%motion,1), UBOUND(OutData%motion,1) - OutData%motion(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - 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%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! ptMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_H - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! map2BldPt not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%map2BldPt)) DEALLOCATE(OutData%map2BldPt) - ALLOCATE(OutData%map2BldPt(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%map2BldPt.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%map2BldPt,1), UBOUND(OutData%map2BldPt,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%map2BldPt(i1), ErrStat2, ErrMsg2 ) ! map2BldPt - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END DO - END IF - END SUBROUTINE AD_Dvr_UnPackHubData - - SUBROUTINE AD_Dvr_CopyNacData( SrcNacDataData, DstNacDataData, CtrlCode, ErrStat, ErrMsg ) - TYPE(NacData), INTENT(INOUT) :: SrcNacDataData - TYPE(NacData), INTENT(INOUT) :: DstNacDataData - 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 = 'AD_Dvr_CopyNacData' -! - ErrStat = ErrID_None - ErrMsg = "" - DstNacDataData%origin_t = SrcNacDataData%origin_t - DstNacDataData%motionType = SrcNacDataData%motionType - DstNacDataData%iMotion = SrcNacDataData%iMotion - DstNacDataData%yaw = SrcNacDataData%yaw - DstNacDataData%yawSpeed = SrcNacDataData%yawSpeed - DstNacDataData%yawAcc = SrcNacDataData%yawAcc - DstNacDataData%motionFileName = SrcNacDataData%motionFileName -IF (ALLOCATED(SrcNacDataData%motion)) THEN - i1_l = LBOUND(SrcNacDataData%motion,1) - i1_u = UBOUND(SrcNacDataData%motion,1) - i2_l = LBOUND(SrcNacDataData%motion,2) - i2_u = UBOUND(SrcNacDataData%motion,2) - IF (.NOT. ALLOCATED(DstNacDataData%motion)) THEN - ALLOCATE(DstNacDataData%motion(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstNacDataData%motion.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstNacDataData%motion = SrcNacDataData%motion -ENDIF - CALL MeshCopy( SrcNacDataData%ptMesh, DstNacDataData%ptMesh, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcNacDataData%ED_P_2_AD_P_N, DstNacDataData%ED_P_2_AD_P_N, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcNacDataData%map2hubPt, DstNacDataData%map2hubPt, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE AD_Dvr_CopyNacData - - SUBROUTINE AD_Dvr_DestroyNacData( NacDataData, ErrStat, ErrMsg ) - TYPE(NacData), INTENT(INOUT) :: NacDataData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyNacData' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(NacDataData%motion)) THEN - DEALLOCATE(NacDataData%motion) -ENDIF - CALL MeshDestroy( NacDataData%ptMesh, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( NacDataData%ED_P_2_AD_P_N, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( NacDataData%map2hubPt, ErrStat, ErrMsg ) - END SUBROUTINE AD_Dvr_DestroyNacData - - SUBROUTINE AD_Dvr_PackNacData( 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(NacData), 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 = 'AD_Dvr_PackNacData' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + SIZE(InData%origin_t) ! origin_t - Int_BufSz = Int_BufSz + 1 ! motionType - Int_BufSz = Int_BufSz + 1 ! iMotion - Re_BufSz = Re_BufSz + 1 ! yaw - Re_BufSz = Re_BufSz + 1 ! yawSpeed - Re_BufSz = Re_BufSz + 1 ! yawAcc - Int_BufSz = Int_BufSz + 1*LEN(InData%motionFileName) ! motionFileName - Int_BufSz = Int_BufSz + 1 ! motion allocated yes/no - IF ( ALLOCATED(InData%motion) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! motion upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%motion) ! motion - END IF - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! ptMesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! ptMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! ptMesh - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! ptMesh - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! ptMesh - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_N: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_N, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_N - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_N - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_N - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_N - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! map2hubPt: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2hubPt, ErrStat2, ErrMsg2, .TRUE. ) ! map2hubPt - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! map2hubPt - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! map2hubPt - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! map2hubPt - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO i1 = LBOUND(InData%origin_t,1), UBOUND(InData%origin_t,1) - ReKiBuf(Re_Xferred) = InData%origin_t(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = InData%motionType - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%iMotion - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%yaw - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%yawSpeed - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%yawAcc - Re_Xferred = Re_Xferred + 1 - DO I = 1, LEN(InData%motionFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%motionFileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IF ( .NOT. ALLOCATED(InData%motion) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%motion,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%motion,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%motion,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%motion,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%motion,2), UBOUND(InData%motion,2) - DO i1 = LBOUND(InData%motion,1), UBOUND(InData%motion,1) - ReKiBuf(Re_Xferred) = InData%motion(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - CALL MeshPack( InData%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! ptMesh - 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_AD_P_N, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_N - 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%map2hubPt, ErrStat2, ErrMsg2, OnlySize ) ! map2hubPt - 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_Dvr_PackNacData - - SUBROUTINE AD_Dvr_UnPackNacData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_Dvr_UnPackHubData( 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(NacData), INTENT(INOUT) :: OutData + TYPE(HubData), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -4941,7 +1879,7 @@ SUBROUTINE AD_Dvr_UnPackNacData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_UnPackNacData' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_UnPackHubData' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -4952,21 +1890,27 @@ SUBROUTINE AD_Dvr_UnPackNacData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - i1_l = LBOUND(OutData%origin_t,1) - i1_u = UBOUND(OutData%origin_t,1) - DO i1 = LBOUND(OutData%origin_t,1), UBOUND(OutData%origin_t,1) - OutData%origin_t(i1) = ReKiBuf(Re_Xferred) + i1_l = LBOUND(OutData%origin_n,1) + i1_u = UBOUND(OutData%origin_n,1) + DO i1 = LBOUND(OutData%origin_n,1), UBOUND(OutData%origin_n,1) + OutData%origin_n(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%orientation_n,1) + i1_u = UBOUND(OutData%orientation_n,1) + DO i1 = LBOUND(OutData%orientation_n,1), UBOUND(OutData%orientation_n,1) + OutData%orientation_n(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO OutData%motionType = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%iMotion = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%yaw = ReKiBuf(Re_Xferred) + OutData%azimuth = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%yawSpeed = ReKiBuf(Re_Xferred) + OutData%rotSpeed = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%yawAcc = ReKiBuf(Re_Xferred) + OutData%rotAcc = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 DO I = 1, LEN(OutData%motionFileName) OutData%motionFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) @@ -4995,130 +1939,262 @@ SUBROUTINE AD_Dvr_UnPackNacData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END DO END DO END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL MeshUnpack( OutData%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! ptMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + END SUBROUTINE AD_Dvr_UnPackHubData - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_N, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_N - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + SUBROUTINE AD_Dvr_CopyNacData( SrcNacDataData, DstNacDataData, CtrlCode, ErrStat, ErrMsg ) + TYPE(NacData), INTENT(IN) :: SrcNacDataData + TYPE(NacData), INTENT(INOUT) :: DstNacDataData + 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 = 'AD_Dvr_CopyNacData' +! + ErrStat = ErrID_None + ErrMsg = "" + DstNacDataData%origin_t = SrcNacDataData%origin_t + DstNacDataData%motionType = SrcNacDataData%motionType + DstNacDataData%iMotion = SrcNacDataData%iMotion + DstNacDataData%yaw = SrcNacDataData%yaw + DstNacDataData%yawSpeed = SrcNacDataData%yawSpeed + DstNacDataData%yawAcc = SrcNacDataData%yawAcc + DstNacDataData%motionFileName = SrcNacDataData%motionFileName +IF (ALLOCATED(SrcNacDataData%motion)) THEN + i1_l = LBOUND(SrcNacDataData%motion,1) + i1_u = UBOUND(SrcNacDataData%motion,1) + i2_l = LBOUND(SrcNacDataData%motion,2) + i2_u = UBOUND(SrcNacDataData%motion,2) + IF (.NOT. ALLOCATED(DstNacDataData%motion)) THEN + ALLOCATE(DstNacDataData%motion(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstNacDataData%motion.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstNacDataData%motion = SrcNacDataData%motion +ENDIF + END SUBROUTINE AD_Dvr_CopyNacData - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%map2hubPt, ErrStat2, ErrMsg2 ) ! map2hubPt - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + SUBROUTINE AD_Dvr_DestroyNacData( NacDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(NacData), INTENT(INOUT) :: NacDataData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyNacData' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(NacDataData%motion)) THEN + DEALLOCATE(NacDataData%motion) +ENDIF + END SUBROUTINE AD_Dvr_DestroyNacData + + SUBROUTINE AD_Dvr_PackNacData( 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(NacData), 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 = 'AD_Dvr_PackNacData' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + SIZE(InData%origin_t) ! origin_t + Int_BufSz = Int_BufSz + 1 ! motionType + Int_BufSz = Int_BufSz + 1 ! iMotion + Re_BufSz = Re_BufSz + 1 ! yaw + Re_BufSz = Re_BufSz + 1 ! yawSpeed + Re_BufSz = Re_BufSz + 1 ! yawAcc + Int_BufSz = Int_BufSz + 1*LEN(InData%motionFileName) ! motionFileName + Int_BufSz = Int_BufSz + 1 ! motion allocated yes/no + IF ( ALLOCATED(InData%motion) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! motion upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%motion) ! motion + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO i1 = LBOUND(InData%origin_t,1), UBOUND(InData%origin_t,1) + ReKiBuf(Re_Xferred) = InData%origin_t(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%motionType + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%iMotion + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%yaw + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%yawSpeed + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%yawAcc + Re_Xferred = Re_Xferred + 1 + DO I = 1, LEN(InData%motionFileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%motionFileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IF ( .NOT. ALLOCATED(InData%motion) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%motion,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%motion,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%motion,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%motion,2) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + DO i2 = LBOUND(InData%motion,2), UBOUND(InData%motion,2) + DO i1 = LBOUND(InData%motion,1), UBOUND(InData%motion,1) + ReKiBuf(Re_Xferred) = InData%motion(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + END SUBROUTINE AD_Dvr_PackNacData + + SUBROUTINE AD_Dvr_UnPackNacData( 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(NacData), 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 = 'AD_Dvr_UnPackNacData' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + i1_l = LBOUND(OutData%origin_t,1) + i1_u = UBOUND(OutData%origin_t,1) + DO i1 = LBOUND(OutData%origin_t,1), UBOUND(OutData%origin_t,1) + OutData%origin_t(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%motionType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%iMotion = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%yaw = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%yawSpeed = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%yawAcc = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + DO I = 1, LEN(OutData%motionFileName) + OutData%motionFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! motion not allocated + Int_Xferred = Int_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%motion)) DEALLOCATE(OutData%motion) + ALLOCATE(OutData%motion(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%motion.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%motion,2), UBOUND(OutData%motion,2) + DO i1 = LBOUND(OutData%motion,1), UBOUND(OutData%motion,1) + OutData%motion(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF END SUBROUTINE AD_Dvr_UnPackNacData SUBROUTINE AD_Dvr_CopyTwrData( SrcTwrDataData, DstTwrDataData, CtrlCode, ErrStat, ErrMsg ) - TYPE(TwrData), INTENT(INOUT) :: SrcTwrDataData + TYPE(TwrData), INTENT(IN) :: SrcTwrDataData TYPE(TwrData), INTENT(INOUT) :: DstTwrDataData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat @@ -5133,33 +2209,29 @@ SUBROUTINE AD_Dvr_CopyTwrData( SrcTwrDataData, DstTwrDataData, CtrlCode, ErrStat ErrStat = ErrID_None ErrMsg = "" DstTwrDataData%origin_t = SrcTwrDataData%origin_t - CALL MeshCopy( SrcTwrDataData%ptMesh, DstTwrDataData%ptMesh, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL MeshCopy( SrcTwrDataData%ptMeshAD, DstTwrDataData%ptMeshAD, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcTwrDataData%ED_P_2_AD_P_T, DstTwrDataData%ED_P_2_AD_P_T, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL NWTC_Library_Copymeshmaptype( SrcTwrDataData%AD_P_2_AD_L_T, DstTwrDataData%AD_P_2_AD_L_T, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AD_Dvr_CopyTwrData - SUBROUTINE AD_Dvr_DestroyTwrData( TwrDataData, ErrStat, ErrMsg ) + SUBROUTINE AD_Dvr_DestroyTwrData( TwrDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(TwrData), INTENT(INOUT) :: TwrDataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyTwrData' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyTwrData' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( TwrDataData%ptMesh, ErrStat, ErrMsg ) - CALL MeshDestroy( TwrDataData%ptMeshAD, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( TwrDataData%ED_P_2_AD_P_T, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( TwrDataData%AD_P_2_AD_L_T, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AD_Dvr_DestroyTwrData SUBROUTINE AD_Dvr_PackTwrData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -5198,75 +2270,6 @@ SUBROUTINE AD_Dvr_PackTwrData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Db_BufSz = 0 Int_BufSz = 0 Re_BufSz = Re_BufSz + SIZE(InData%origin_t) ! origin_t - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! ptMesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! ptMesh - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! ptMesh - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! ptMesh - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! ptMesh - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! ptMeshAD: size of buffers for each call to pack subtype - CALL MeshPack( InData%ptMeshAD, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! ptMeshAD - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! ptMeshAD - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! ptMeshAD - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! ptMeshAD - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_T: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_T, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_T - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_T - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_T - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_T - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! AD_P_2_AD_L_T: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_AD_L_T, ErrStat2, ErrMsg2, .TRUE. ) ! AD_P_2_AD_L_T - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! AD_P_2_AD_L_T - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! AD_P_2_AD_L_T - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! AD_P_2_AD_L_T - 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 @@ -5291,125 +2294,13 @@ SUBROUTINE AD_Dvr_PackTwrData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO i1 = LBOUND(InData%origin_t,1), UBOUND(InData%origin_t,1) - ReKiBuf(Re_Xferred) = InData%origin_t(i1) - Re_Xferred = Re_Xferred + 1 - END DO - CALL MeshPack( InData%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! ptMesh - 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%ptMeshAD, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! ptMeshAD - 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_AD_P_T, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_T - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_AD_L_T, ErrStat2, ErrMsg2, OnlySize ) ! AD_P_2_AD_L_T - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + Db_Xferred = 1 + Int_Xferred = 1 - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF + DO i1 = LBOUND(InData%origin_t,1), UBOUND(InData%origin_t,1) + ReKiBuf(Re_Xferred) = InData%origin_t(i1) + Re_Xferred = Re_Xferred + 1 + END DO END SUBROUTINE AD_Dvr_PackTwrData SUBROUTINE AD_Dvr_UnPackTwrData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -5445,166 +2336,6 @@ SUBROUTINE AD_Dvr_UnPackTwrData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E OutData%origin_t(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL MeshUnpack( OutData%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! ptMesh - 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%ptMeshAD, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! ptMeshAD - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_T, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_T - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_P_2_AD_L_T, ErrStat2, ErrMsg2 ) ! AD_P_2_AD_L_T - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END SUBROUTINE AD_Dvr_UnPackTwrData SUBROUTINE AD_Dvr_CopyWTData( SrcWTDataData, DstWTDataData, CtrlCode, ErrStat, ErrMsg ) @@ -5625,15 +2356,31 @@ SUBROUTINE AD_Dvr_CopyWTData( SrcWTDataData, DstWTDataData, CtrlCode, ErrStat, E ErrMsg = "" DstWTDataData%originInit = SrcWTDataData%originInit DstWTDataData%orientationInit = SrcWTDataData%orientationInit - CALL MeshCopy( SrcWTDataData%ptMesh, DstWTDataData%ptMesh, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN CALL NWTC_Library_Copymeshmaptype( SrcWTDataData%map2twrPt, DstWTDataData%map2twrPt, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN CALL NWTC_Library_Copymeshmaptype( SrcWTDataData%map2nacPt, DstWTDataData%map2nacPt, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + CALL NWTC_Library_Copymeshmaptype( SrcWTDataData%map2hubPt, DstWTDataData%map2hubPt, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcWTDataData%map2BldPt)) THEN + i1_l = LBOUND(SrcWTDataData%map2BldPt,1) + i1_u = UBOUND(SrcWTDataData%map2BldPt,1) + IF (.NOT. ALLOCATED(DstWTDataData%map2BldPt)) THEN + ALLOCATE(DstWTDataData%map2BldPt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstWTDataData%map2BldPt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcWTDataData%map2BldPt,1), UBOUND(SrcWTDataData%map2BldPt,1) + CALL NWTC_Library_Copymeshmaptype( SrcWTDataData%map2BldPt(i1), DstWTDataData%map2BldPt(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcWTDataData%bld)) THEN i1_l = LBOUND(SrcWTDataData%bld,1) i1_u = UBOUND(SrcWTDataData%bld,1) @@ -5662,6 +2409,8 @@ SUBROUTINE AD_Dvr_CopyWTData( SrcWTDataData, DstWTDataData, CtrlCode, ErrStat, E DstWTDataData%numBlades = SrcWTDataData%numBlades DstWTDataData%basicHAWTFormat = SrcWTDataData%basicHAWTFormat DstWTDataData%hasTower = SrcWTDataData%hasTower + DstWTDataData%projMod = SrcWTDataData%projMod + DstWTDataData%BEM_Mod = SrcWTDataData%BEM_Mod DstWTDataData%HAWTprojection = SrcWTDataData%HAWTprojection DstWTDataData%motionType = SrcWTDataData%motionType IF (ALLOCATED(SrcWTDataData%motion)) THEN @@ -5694,35 +2443,76 @@ SUBROUTINE AD_Dvr_CopyWTData( SrcWTDataData, DstWTDataData, CtrlCode, ErrStat, E END IF END IF DstWTDataData%WriteOutput = SrcWTDataData%WriteOutput +ENDIF +IF (ALLOCATED(SrcWTDataData%userSwapArray)) THEN + i1_l = LBOUND(SrcWTDataData%userSwapArray,1) + i1_u = UBOUND(SrcWTDataData%userSwapArray,1) + IF (.NOT. ALLOCATED(DstWTDataData%userSwapArray)) THEN + ALLOCATE(DstWTDataData%userSwapArray(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstWTDataData%userSwapArray.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstWTDataData%userSwapArray = SrcWTDataData%userSwapArray ENDIF END SUBROUTINE AD_Dvr_CopyWTData - SUBROUTINE AD_Dvr_DestroyWTData( WTDataData, ErrStat, ErrMsg ) + SUBROUTINE AD_Dvr_DestroyWTData( WTDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WTData), INTENT(INOUT) :: WTDataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyWTData' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyWTData' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( WTDataData%ptMesh, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( WTDataData%map2twrPt, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( WTDataData%map2nacPt, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroymeshmaptype( WTDataData%map2twrPt, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( WTDataData%map2nacPt, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( WTDataData%map2hubPt, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(WTDataData%map2BldPt)) THEN +DO i1 = LBOUND(WTDataData%map2BldPt,1), UBOUND(WTDataData%map2BldPt,1) + CALL NWTC_Library_Destroymeshmaptype( WTDataData%map2BldPt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(WTDataData%map2BldPt) +ENDIF IF (ALLOCATED(WTDataData%bld)) THEN DO i1 = LBOUND(WTDataData%bld,1), UBOUND(WTDataData%bld,1) - CALL AD_Dvr_Destroybladedata( WTDataData%bld(i1), ErrStat, ErrMsg ) + CALL AD_Dvr_Destroybladedata( WTDataData%bld(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(WTDataData%bld) ENDIF - CALL AD_Dvr_Destroyhubdata( WTDataData%hub, ErrStat, ErrMsg ) - CALL AD_Dvr_Destroynacdata( WTDataData%nac, ErrStat, ErrMsg ) - CALL AD_Dvr_Destroytwrdata( WTDataData%twr, ErrStat, ErrMsg ) + CALL AD_Dvr_Destroyhubdata( WTDataData%hub, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD_Dvr_Destroynacdata( WTDataData%nac, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD_Dvr_Destroytwrdata( WTDataData%twr, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(WTDataData%motion)) THEN DEALLOCATE(WTDataData%motion) ENDIF IF (ALLOCATED(WTDataData%WriteOutput)) THEN DEALLOCATE(WTDataData%WriteOutput) +ENDIF +IF (ALLOCATED(WTDataData%userSwapArray)) THEN + DEALLOCATE(WTDataData%userSwapArray) ENDIF END SUBROUTINE AD_Dvr_DestroyWTData @@ -5764,57 +2554,80 @@ SUBROUTINE AD_Dvr_PackWTData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Re_BufSz = Re_BufSz + SIZE(InData%originInit) ! originInit Re_BufSz = Re_BufSz + SIZE(InData%orientationInit) ! orientationInit ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! ptMesh: size of buffers for each call to pack subtype - CALL MeshPack( InData%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! ptMesh + Int_BufSz = Int_BufSz + 3 ! map2twrPt: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2twrPt, ErrStat2, ErrMsg2, .TRUE. ) ! map2twrPt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! ptMesh + IF(ALLOCATED(Re_Buf)) THEN ! map2twrPt Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! ptMesh + IF(ALLOCATED(Db_Buf)) THEN ! map2twrPt Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! ptMesh + IF(ALLOCATED(Int_Buf)) THEN ! map2twrPt Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! map2twrPt: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2twrPt, ErrStat2, ErrMsg2, .TRUE. ) ! map2twrPt + Int_BufSz = Int_BufSz + 3 ! map2nacPt: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2nacPt, ErrStat2, ErrMsg2, .TRUE. ) ! map2nacPt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! map2twrPt + IF(ALLOCATED(Re_Buf)) THEN ! map2nacPt Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! map2twrPt + IF(ALLOCATED(Db_Buf)) THEN ! map2nacPt Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! map2twrPt + IF(ALLOCATED(Int_Buf)) THEN ! map2nacPt Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! map2nacPt: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2nacPt, ErrStat2, ErrMsg2, .TRUE. ) ! map2nacPt + Int_BufSz = Int_BufSz + 3 ! map2hubPt: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2hubPt, ErrStat2, ErrMsg2, .TRUE. ) ! map2hubPt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! map2nacPt + IF(ALLOCATED(Re_Buf)) THEN ! map2hubPt + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! map2hubPt + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! map2hubPt + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! map2BldPt allocated yes/no + IF ( ALLOCATED(InData%map2BldPt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! map2BldPt upper/lower bounds for each dimension + DO i1 = LBOUND(InData%map2BldPt,1), UBOUND(InData%map2BldPt,1) + Int_BufSz = Int_BufSz + 3 ! map2BldPt: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2BldPt(i1), ErrStat2, ErrMsg2, .TRUE. ) ! map2BldPt + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! map2BldPt Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! map2nacPt + IF(ALLOCATED(Db_Buf)) THEN ! map2BldPt Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! map2nacPt + IF(ALLOCATED(Int_Buf)) THEN ! map2BldPt Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! bld allocated yes/no IF ( ALLOCATED(InData%bld) ) THEN Int_BufSz = Int_BufSz + 2*1 ! bld upper/lower bounds for each dimension @@ -5892,6 +2705,8 @@ SUBROUTINE AD_Dvr_PackWTData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + 1 ! numBlades Int_BufSz = Int_BufSz + 1 ! basicHAWTFormat Int_BufSz = Int_BufSz + 1 ! hasTower + Int_BufSz = Int_BufSz + 1 ! projMod + Int_BufSz = Int_BufSz + 1 ! BEM_Mod Int_BufSz = Int_BufSz + 1 ! HAWTprojection Int_BufSz = Int_BufSz + 1 ! motionType Int_BufSz = Int_BufSz + 1 ! motion allocated yes/no @@ -5909,6 +2724,11 @@ SUBROUTINE AD_Dvr_PackWTData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + 2*1 ! WriteOutput upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WriteOutput) ! WriteOutput END IF + Int_BufSz = Int_BufSz + 1 ! userSwapArray allocated yes/no + IF ( ALLOCATED(InData%userSwapArray) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! userSwapArray upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%userSwapArray) ! userSwapArray + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -5944,7 +2764,7 @@ SUBROUTINE AD_Dvr_PackWTData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ReKiBuf(Re_Xferred) = InData%orientationInit(i1) Re_Xferred = Re_Xferred + 1 END DO - CALL MeshPack( InData%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! ptMesh + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2twrPt, ErrStat2, ErrMsg2, OnlySize ) ! map2twrPt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5972,7 +2792,7 @@ SUBROUTINE AD_Dvr_PackWTData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2twrPt, ErrStat2, ErrMsg2, OnlySize ) ! map2twrPt + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2nacPt, ErrStat2, ErrMsg2, OnlySize ) ! map2nacPt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6000,7 +2820,46 @@ SUBROUTINE AD_Dvr_PackWTData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2nacPt, ErrStat2, ErrMsg2, OnlySize ) ! map2nacPt + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2hubPt, ErrStat2, ErrMsg2, OnlySize ) ! map2hubPt + 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%map2BldPt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%map2BldPt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%map2BldPt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%map2BldPt,1), UBOUND(InData%map2BldPt,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%map2BldPt(i1), ErrStat2, ErrMsg2, OnlySize ) ! map2BldPt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6028,6 +2887,8 @@ SUBROUTINE AD_Dvr_PackWTData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + END DO + END IF IF ( .NOT. ALLOCATED(InData%bld) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -6159,6 +3020,10 @@ SUBROUTINE AD_Dvr_PackWTData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%hasTower, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%projMod + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%BEM_Mod + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%HAWTprojection, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%motionType @@ -6210,6 +3075,21 @@ SUBROUTINE AD_Dvr_PackWTData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%userSwapArray) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%userSwapArray,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%userSwapArray,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%userSwapArray,1), UBOUND(InData%userSwapArray,1) + ReKiBuf(Re_Xferred) = InData%userSwapArray(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE AD_Dvr_PackWTData SUBROUTINE AD_Dvr_UnPackWTData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -6285,7 +3165,7 @@ SUBROUTINE AD_Dvr_UnPackWTData( 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%ptMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! ptMesh + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%map2twrPt, ErrStat2, ErrMsg2 ) ! map2twrPt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6325,7 +3205,7 @@ SUBROUTINE AD_Dvr_UnPackWTData( 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 NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%map2twrPt, ErrStat2, ErrMsg2 ) ! map2twrPt + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%map2nacPt, ErrStat2, ErrMsg2 ) ! map2nacPt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6365,13 +3245,69 @@ SUBROUTINE AD_Dvr_UnPackWTData( 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 NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%map2nacPt, ErrStat2, ErrMsg2 ) ! map2nacPt + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%map2hubPt, ErrStat2, ErrMsg2 ) ! map2hubPt + 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 ! map2BldPt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%map2BldPt)) DEALLOCATE(OutData%map2BldPt) + ALLOCATE(OutData%map2BldPt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%map2BldPt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%map2BldPt,1), UBOUND(OutData%map2BldPt,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%map2BldPt(i1), ErrStat2, ErrMsg2 ) ! map2BldPt 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 ! bld not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -6554,6 +3490,10 @@ SUBROUTINE AD_Dvr_UnPackWTData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Xferred = Int_Xferred + 1 OutData%hasTower = TRANSFER(IntKiBuf(Int_Xferred), OutData%hasTower) Int_Xferred = Int_Xferred + 1 + OutData%projMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%BEM_Mod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%HAWTprojection = TRANSFER(IntKiBuf(Int_Xferred), OutData%HAWTprojection) Int_Xferred = Int_Xferred + 1 OutData%motionType = IntKiBuf(Int_Xferred) @@ -6611,6 +3551,24 @@ SUBROUTINE AD_Dvr_UnPackWTData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! userSwapArray not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%userSwapArray)) DEALLOCATE(OutData%userSwapArray) + ALLOCATE(OutData%userSwapArray(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%userSwapArray.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%userSwapArray,1), UBOUND(OutData%userSwapArray,1) + OutData%userSwapArray(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE AD_Dvr_UnPackWTData SUBROUTINE AD_Dvr_CopyDvr_SimData( SrcDvr_SimDataData, DstDvr_SimDataData, CtrlCode, ErrStat, ErrMsg ) @@ -6630,7 +3588,6 @@ SUBROUTINE AD_Dvr_CopyDvr_SimData( SrcDvr_SimDataData, DstDvr_SimDataData, CtrlC ErrStat = ErrID_None ErrMsg = "" DstDvr_SimDataData%AD_InputFile = SrcDvr_SimDataData%AD_InputFile - DstDvr_SimDataData%IW_InputFile = SrcDvr_SimDataData%IW_InputFile DstDvr_SimDataData%MHK = SrcDvr_SimDataData%MHK DstDvr_SimDataData%AnalysisType = SrcDvr_SimDataData%AnalysisType DstDvr_SimDataData%FldDens = SrcDvr_SimDataData%FldDens @@ -6640,10 +3597,6 @@ SUBROUTINE AD_Dvr_CopyDvr_SimData( SrcDvr_SimDataData, DstDvr_SimDataData, CtrlC DstDvr_SimDataData%Pvap = SrcDvr_SimDataData%Pvap DstDvr_SimDataData%WtrDpth = SrcDvr_SimDataData%WtrDpth DstDvr_SimDataData%MSL2SWL = SrcDvr_SimDataData%MSL2SWL - DstDvr_SimDataData%CompInflow = SrcDvr_SimDataData%CompInflow - DstDvr_SimDataData%HWindSpeed = SrcDvr_SimDataData%HWindSpeed - DstDvr_SimDataData%RefHt = SrcDvr_SimDataData%RefHt - DstDvr_SimDataData%PLExp = SrcDvr_SimDataData%PLExp DstDvr_SimDataData%numTurbines = SrcDvr_SimDataData%numTurbines IF (ALLOCATED(SrcDvr_SimDataData%WT)) THEN i1_l = LBOUND(SrcDvr_SimDataData%WT,1) @@ -6701,33 +3654,53 @@ SUBROUTINE AD_Dvr_CopyDvr_SimData( SrcDvr_SimDataData, DstDvr_SimDataData, CtrlC CALL AD_Dvr_Copydvr_outputs( SrcDvr_SimDataData%out, DstDvr_SimDataData%out, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + CALL ADI_Copyiw_inputdata( SrcDvr_SimDataData%IW_InitInp, DstDvr_SimDataData%IW_InitInp, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AD_Dvr_CopyDvr_SimData - SUBROUTINE AD_Dvr_DestroyDvr_SimData( Dvr_SimDataData, ErrStat, ErrMsg ) + SUBROUTINE AD_Dvr_DestroyDvr_SimData( Dvr_SimDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Dvr_SimData), INTENT(INOUT) :: Dvr_SimDataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyDvr_SimData' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyDvr_SimData' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(Dvr_SimDataData%WT)) THEN DO i1 = LBOUND(Dvr_SimDataData%WT,1), UBOUND(Dvr_SimDataData%WT,1) - CALL AD_Dvr_Destroywtdata( Dvr_SimDataData%WT(i1), ErrStat, ErrMsg ) + CALL AD_Dvr_Destroywtdata( Dvr_SimDataData%WT(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(Dvr_SimDataData%WT) ENDIF IF (ALLOCATED(Dvr_SimDataData%Cases)) THEN DO i1 = LBOUND(Dvr_SimDataData%Cases,1), UBOUND(Dvr_SimDataData%Cases,1) - CALL AD_Dvr_Destroydvr_case( Dvr_SimDataData%Cases(i1), ErrStat, ErrMsg ) + CALL AD_Dvr_Destroydvr_case( Dvr_SimDataData%Cases(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(Dvr_SimDataData%Cases) ENDIF IF (ALLOCATED(Dvr_SimDataData%timeSeries)) THEN DEALLOCATE(Dvr_SimDataData%timeSeries) ENDIF - CALL AD_Dvr_Destroydvr_outputs( Dvr_SimDataData%out, ErrStat, ErrMsg ) + CALL AD_Dvr_Destroydvr_outputs( Dvr_SimDataData%out, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ADI_Destroyiw_inputdata( Dvr_SimDataData%IW_InitInp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD_Dvr_DestroyDvr_SimData SUBROUTINE AD_Dvr_PackDvr_SimData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -6766,7 +3739,6 @@ SUBROUTINE AD_Dvr_PackDvr_SimData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_BufSz = 0 Int_BufSz = 0 Int_BufSz = Int_BufSz + 1*LEN(InData%AD_InputFile) ! AD_InputFile - Int_BufSz = Int_BufSz + 1*LEN(InData%IW_InputFile) ! IW_InputFile Int_BufSz = Int_BufSz + 1 ! MHK Int_BufSz = Int_BufSz + 1 ! AnalysisType Re_BufSz = Re_BufSz + 1 ! FldDens @@ -6776,10 +3748,6 @@ SUBROUTINE AD_Dvr_PackDvr_SimData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_BufSz = Re_BufSz + 1 ! Pvap Re_BufSz = Re_BufSz + 1 ! WtrDpth Re_BufSz = Re_BufSz + 1 ! MSL2SWL - Int_BufSz = Int_BufSz + 1 ! CompInflow - Re_BufSz = Re_BufSz + 1 ! HWindSpeed - Re_BufSz = Re_BufSz + 1 ! RefHt - Re_BufSz = Re_BufSz + 1 ! PLExp Int_BufSz = Int_BufSz + 1 ! numTurbines Int_BufSz = Int_BufSz + 1 ! WT allocated yes/no IF ( ALLOCATED(InData%WT) ) THEN @@ -6857,6 +3825,23 @@ SUBROUTINE AD_Dvr_PackDvr_SimData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 3 ! IW_InitInp: size of buffers for each call to pack subtype + CALL ADI_Packiw_inputdata( Re_Buf, Db_Buf, Int_Buf, InData%IW_InitInp, ErrStat2, ErrMsg2, .TRUE. ) ! IW_InitInp + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! IW_InitInp + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! IW_InitInp + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! IW_InitInp + 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 @@ -6888,10 +3873,6 @@ SUBROUTINE AD_Dvr_PackDvr_SimData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, IntKiBuf(Int_Xferred) = ICHAR(InData%AD_InputFile(I:I), IntKi) Int_Xferred = Int_Xferred + 1 END DO ! I - DO I = 1, LEN(InData%IW_InputFile) - IntKiBuf(Int_Xferred) = ICHAR(InData%IW_InputFile(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I IntKiBuf(Int_Xferred) = InData%MHK Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%AnalysisType @@ -6910,14 +3891,6 @@ SUBROUTINE AD_Dvr_PackDvr_SimData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%MSL2SWL Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%CompInflow - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%HWindSpeed - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RefHt - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%PLExp - Re_Xferred = Re_Xferred + 1 IntKiBuf(Int_Xferred) = InData%numTurbines Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%WT) ) THEN @@ -7066,6 +4039,34 @@ SUBROUTINE AD_Dvr_PackDvr_SimData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + CALL ADI_Packiw_inputdata( Re_Buf, Db_Buf, Int_Buf, InData%IW_InitInp, ErrStat2, ErrMsg2, OnlySize ) ! IW_InitInp + 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_Dvr_PackDvr_SimData SUBROUTINE AD_Dvr_UnPackDvr_SimData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -7100,10 +4101,6 @@ SUBROUTINE AD_Dvr_UnPackDvr_SimData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta OutData%AD_InputFile(I:I) = CHAR(IntKiBuf(Int_Xferred)) Int_Xferred = Int_Xferred + 1 END DO ! I - DO I = 1, LEN(OutData%IW_InputFile) - OutData%IW_InputFile(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I OutData%MHK = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%AnalysisType = IntKiBuf(Int_Xferred) @@ -7122,14 +4119,6 @@ SUBROUTINE AD_Dvr_UnPackDvr_SimData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Re_Xferred = Re_Xferred + 1 OutData%MSL2SWL = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%CompInflow = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%HWindSpeed = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RefHt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%PLExp = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 OutData%numTurbines = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WT not allocated @@ -7323,6 +4312,46 @@ SUBROUTINE AD_Dvr_UnPackDvr_SimData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL ADI_Unpackiw_inputdata( Re_Buf, Db_Buf, Int_Buf, OutData%IW_InitInp, ErrStat2, ErrMsg2 ) ! IW_InitInp + 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_Dvr_UnPackDvr_SimData SUBROUTINE AD_Dvr_CopyAllData( SrcAllDataData, DstAllDataData, CtrlCode, ErrStat, ErrMsg ) @@ -7342,10 +4371,10 @@ SUBROUTINE AD_Dvr_CopyAllData( SrcAllDataData, DstAllDataData, CtrlCode, ErrStat CALL AD_Dvr_Copydvr_simdata( SrcAllDataData%dvr, DstAllDataData%dvr, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AD_Dvr_Copyaerodyn_data( SrcAllDataData%AD, DstAllDataData%AD, CtrlCode, ErrStat2, ErrMsg2 ) + CALL ADI_Copydata( SrcAllDataData%ADI, DstAllDataData%ADI, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AD_Dvr_Copyinflowwind_data( SrcAllDataData%IW, DstAllDataData%IW, CtrlCode, ErrStat2, ErrMsg2 ) + CALL ADI_Copyfed_data( SrcAllDataData%FED, DstAllDataData%FED, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN DstAllDataData%errStat = SrcAllDataData%errStat @@ -7353,18 +4382,33 @@ SUBROUTINE AD_Dvr_CopyAllData( SrcAllDataData, DstAllDataData, CtrlCode, ErrStat DstAllDataData%initialized = SrcAllDataData%initialized END SUBROUTINE AD_Dvr_CopyAllData - SUBROUTINE AD_Dvr_DestroyAllData( AllDataData, ErrStat, ErrMsg ) + SUBROUTINE AD_Dvr_DestroyAllData( AllDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AllData), INTENT(INOUT) :: AllDataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyAllData' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_Dvr_DestroyAllData' + ErrStat = ErrID_None ErrMsg = "" - CALL AD_Dvr_Destroydvr_simdata( AllDataData%dvr, ErrStat, ErrMsg ) - CALL AD_Dvr_Destroyaerodyn_data( AllDataData%AD, ErrStat, ErrMsg ) - CALL AD_Dvr_Destroyinflowwind_data( AllDataData%IW, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AD_Dvr_Destroydvr_simdata( AllDataData%dvr, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ADI_Destroydata( AllDataData%ADI, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ADI_Destroyfed_data( AllDataData%FED, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD_Dvr_DestroyAllData SUBROUTINE AD_Dvr_PackAllData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -7420,37 +4464,37 @@ SUBROUTINE AD_Dvr_PackAllData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! AD: size of buffers for each call to pack subtype - CALL AD_Dvr_Packaerodyn_data( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, .TRUE. ) ! AD + Int_BufSz = Int_BufSz + 3 ! ADI: size of buffers for each call to pack subtype + CALL ADI_Packdata( Re_Buf, Db_Buf, Int_Buf, InData%ADI, ErrStat2, ErrMsg2, .TRUE. ) ! ADI CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! AD + IF(ALLOCATED(Re_Buf)) THEN ! ADI Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! AD + IF(ALLOCATED(Db_Buf)) THEN ! ADI Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! AD + IF(ALLOCATED(Int_Buf)) THEN ! ADI Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! IW: size of buffers for each call to pack subtype - CALL AD_Dvr_Packinflowwind_data( Re_Buf, Db_Buf, Int_Buf, InData%IW, ErrStat2, ErrMsg2, .TRUE. ) ! IW + Int_BufSz = Int_BufSz + 3 ! FED: size of buffers for each call to pack subtype + CALL ADI_Packfed_data( Re_Buf, Db_Buf, Int_Buf, InData%FED, ErrStat2, ErrMsg2, .TRUE. ) ! FED CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! IW + IF(ALLOCATED(Re_Buf)) THEN ! FED Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! IW + IF(ALLOCATED(Db_Buf)) THEN ! FED Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! IW + IF(ALLOCATED(Int_Buf)) THEN ! FED Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -7512,7 +4556,7 @@ SUBROUTINE AD_Dvr_PackAllData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL AD_Dvr_Packaerodyn_data( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, OnlySize ) ! AD + CALL ADI_Packdata( Re_Buf, Db_Buf, Int_Buf, InData%ADI, ErrStat2, ErrMsg2, OnlySize ) ! ADI CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7540,7 +4584,7 @@ SUBROUTINE AD_Dvr_PackAllData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL AD_Dvr_Packinflowwind_data( Re_Buf, Db_Buf, Int_Buf, InData%IW, ErrStat2, ErrMsg2, OnlySize ) ! IW + CALL ADI_Packfed_data( Re_Buf, Db_Buf, Int_Buf, InData%FED, ErrStat2, ErrMsg2, OnlySize ) ! FED CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7677,7 +4721,7 @@ SUBROUTINE AD_Dvr_UnPackAllData( 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 AD_Dvr_Unpackaerodyn_data( Re_Buf, Db_Buf, Int_Buf, OutData%AD, ErrStat2, ErrMsg2 ) ! AD + CALL ADI_Unpackdata( Re_Buf, Db_Buf, Int_Buf, OutData%ADI, ErrStat2, ErrMsg2 ) ! ADI CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7717,7 +4761,7 @@ SUBROUTINE AD_Dvr_UnPackAllData( 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 AD_Dvr_Unpackinflowwind_data( Re_Buf, Db_Buf, Int_Buf, OutData%IW, ErrStat2, ErrMsg2 ) ! IW + CALL ADI_Unpackfed_data( Re_Buf, Db_Buf, Int_Buf, OutData%FED, ErrStat2, ErrMsg2 ) ! FED CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN diff --git a/modules/aerodyn/src/AeroDyn_IO.f90 b/modules/aerodyn/src/AeroDyn_IO.f90 index e32881ef7..b8ab0babd 100644 --- a/modules/aerodyn/src/AeroDyn_IO.f90 +++ b/modules/aerodyn/src/AeroDyn_IO.f90 @@ -21,8 +21,9 @@ MODULE AeroDyn_IO use NWTC_Library + use AeroDyn_IO_Params use AeroDyn_Types - use BEMTUncoupled, only : SkewMod_Orthogonal, SkewMod_Uncoupled, SkewMod_PittPeters, VelocityIsZero + use BEMTUncoupled, only : VelocityIsZero use FVW_Subs, only : FVW_AeroOuts USE AeroDyn_AllBldNdOuts_IO @@ -33,1579 +34,7 @@ MODULE AeroDyn_IO character(*), parameter :: AD_Nickname = 'AD' -! =================================================================================================== -! 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 01-Mar-2022 11:16:33. - - - ! Parameters related to output length (number of characters allowed in the output data headers): - - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 - - - ! 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 - - - ! Tower: - - INTEGER(IntKi), PARAMETER :: TwN1VUndx = 1 - INTEGER(IntKi), PARAMETER :: TwN1VUndy = 2 - INTEGER(IntKi), PARAMETER :: TwN1VUndz = 3 - INTEGER(IntKi), PARAMETER :: TwN2VUndx = 4 - INTEGER(IntKi), PARAMETER :: TwN2VUndy = 5 - INTEGER(IntKi), PARAMETER :: TwN2VUndz = 6 - INTEGER(IntKi), PARAMETER :: TwN3VUndx = 7 - INTEGER(IntKi), PARAMETER :: TwN3VUndy = 8 - INTEGER(IntKi), PARAMETER :: TwN3VUndz = 9 - INTEGER(IntKi), PARAMETER :: TwN4VUndx = 10 - INTEGER(IntKi), PARAMETER :: TwN4VUndy = 11 - INTEGER(IntKi), PARAMETER :: TwN4VUndz = 12 - INTEGER(IntKi), PARAMETER :: TwN5VUndx = 13 - INTEGER(IntKi), PARAMETER :: TwN5VUndy = 14 - INTEGER(IntKi), PARAMETER :: TwN5VUndz = 15 - INTEGER(IntKi), PARAMETER :: TwN6VUndx = 16 - INTEGER(IntKi), PARAMETER :: TwN6VUndy = 17 - INTEGER(IntKi), PARAMETER :: TwN6VUndz = 18 - INTEGER(IntKi), PARAMETER :: TwN7VUndx = 19 - INTEGER(IntKi), PARAMETER :: TwN7VUndy = 20 - INTEGER(IntKi), PARAMETER :: TwN7VUndz = 21 - INTEGER(IntKi), PARAMETER :: TwN8VUndx = 22 - INTEGER(IntKi), PARAMETER :: TwN8VUndy = 23 - INTEGER(IntKi), PARAMETER :: TwN8VUndz = 24 - INTEGER(IntKi), PARAMETER :: TwN9VUndx = 25 - INTEGER(IntKi), PARAMETER :: TwN9VUndy = 26 - INTEGER(IntKi), PARAMETER :: TwN9VUndz = 27 - INTEGER(IntKi), PARAMETER :: TwN1STVx = 28 - INTEGER(IntKi), PARAMETER :: TwN1STVy = 29 - INTEGER(IntKi), PARAMETER :: TwN1STVz = 30 - INTEGER(IntKi), PARAMETER :: TwN2STVx = 31 - INTEGER(IntKi), PARAMETER :: TwN2STVy = 32 - INTEGER(IntKi), PARAMETER :: TwN2STVz = 33 - INTEGER(IntKi), PARAMETER :: TwN3STVx = 34 - INTEGER(IntKi), PARAMETER :: TwN3STVy = 35 - INTEGER(IntKi), PARAMETER :: TwN3STVz = 36 - INTEGER(IntKi), PARAMETER :: TwN4STVx = 37 - INTEGER(IntKi), PARAMETER :: TwN4STVy = 38 - INTEGER(IntKi), PARAMETER :: TwN4STVz = 39 - INTEGER(IntKi), PARAMETER :: TwN5STVx = 40 - INTEGER(IntKi), PARAMETER :: TwN5STVy = 41 - INTEGER(IntKi), PARAMETER :: TwN5STVz = 42 - INTEGER(IntKi), PARAMETER :: TwN6STVx = 43 - INTEGER(IntKi), PARAMETER :: TwN6STVy = 44 - INTEGER(IntKi), PARAMETER :: TwN6STVz = 45 - INTEGER(IntKi), PARAMETER :: TwN7STVx = 46 - INTEGER(IntKi), PARAMETER :: TwN7STVy = 47 - INTEGER(IntKi), PARAMETER :: TwN7STVz = 48 - INTEGER(IntKi), PARAMETER :: TwN8STVx = 49 - INTEGER(IntKi), PARAMETER :: TwN8STVy = 50 - INTEGER(IntKi), PARAMETER :: TwN8STVz = 51 - INTEGER(IntKi), PARAMETER :: TwN9STVx = 52 - INTEGER(IntKi), PARAMETER :: TwN9STVy = 53 - INTEGER(IntKi), PARAMETER :: TwN9STVz = 54 - INTEGER(IntKi), PARAMETER :: TwN1Vrel = 55 - INTEGER(IntKi), PARAMETER :: TwN2Vrel = 56 - INTEGER(IntKi), PARAMETER :: TwN3Vrel = 57 - INTEGER(IntKi), PARAMETER :: TwN4Vrel = 58 - INTEGER(IntKi), PARAMETER :: TwN5Vrel = 59 - INTEGER(IntKi), PARAMETER :: TwN6Vrel = 60 - INTEGER(IntKi), PARAMETER :: TwN7Vrel = 61 - INTEGER(IntKi), PARAMETER :: TwN8Vrel = 62 - INTEGER(IntKi), PARAMETER :: TwN9Vrel = 63 - INTEGER(IntKi), PARAMETER :: TwN1DynP = 64 - INTEGER(IntKi), PARAMETER :: TwN2DynP = 65 - INTEGER(IntKi), PARAMETER :: TwN3DynP = 66 - INTEGER(IntKi), PARAMETER :: TwN4DynP = 67 - INTEGER(IntKi), PARAMETER :: TwN5DynP = 68 - INTEGER(IntKi), PARAMETER :: TwN6DynP = 69 - INTEGER(IntKi), PARAMETER :: TwN7DynP = 70 - INTEGER(IntKi), PARAMETER :: TwN8DynP = 71 - INTEGER(IntKi), PARAMETER :: TwN9DynP = 72 - INTEGER(IntKi), PARAMETER :: TwN1Re = 73 - INTEGER(IntKi), PARAMETER :: TwN2Re = 74 - INTEGER(IntKi), PARAMETER :: TwN3Re = 75 - INTEGER(IntKi), PARAMETER :: TwN4Re = 76 - INTEGER(IntKi), PARAMETER :: TwN5Re = 77 - INTEGER(IntKi), PARAMETER :: TwN6Re = 78 - INTEGER(IntKi), PARAMETER :: TwN7Re = 79 - INTEGER(IntKi), PARAMETER :: TwN8Re = 80 - INTEGER(IntKi), PARAMETER :: TwN9Re = 81 - INTEGER(IntKi), PARAMETER :: TwN1M = 82 - INTEGER(IntKi), PARAMETER :: TwN2M = 83 - INTEGER(IntKi), PARAMETER :: TwN3M = 84 - INTEGER(IntKi), PARAMETER :: TwN4M = 85 - INTEGER(IntKi), PARAMETER :: TwN5M = 86 - INTEGER(IntKi), PARAMETER :: TwN6M = 87 - INTEGER(IntKi), PARAMETER :: TwN7M = 88 - INTEGER(IntKi), PARAMETER :: TwN8M = 89 - INTEGER(IntKi), PARAMETER :: TwN9M = 90 - INTEGER(IntKi), PARAMETER :: TwN1Fdx = 91 - INTEGER(IntKi), PARAMETER :: TwN2Fdx = 92 - INTEGER(IntKi), PARAMETER :: TwN3Fdx = 93 - INTEGER(IntKi), PARAMETER :: TwN4Fdx = 94 - INTEGER(IntKi), PARAMETER :: TwN5Fdx = 95 - INTEGER(IntKi), PARAMETER :: TwN6Fdx = 96 - INTEGER(IntKi), PARAMETER :: TwN7Fdx = 97 - INTEGER(IntKi), PARAMETER :: TwN8Fdx = 98 - INTEGER(IntKi), PARAMETER :: TwN9Fdx = 99 - INTEGER(IntKi), PARAMETER :: TwN1Fdy = 100 - INTEGER(IntKi), PARAMETER :: TwN2Fdy = 101 - INTEGER(IntKi), PARAMETER :: TwN3Fdy = 102 - INTEGER(IntKi), PARAMETER :: TwN4Fdy = 103 - INTEGER(IntKi), PARAMETER :: TwN5Fdy = 104 - INTEGER(IntKi), PARAMETER :: TwN6Fdy = 105 - INTEGER(IntKi), PARAMETER :: TwN7Fdy = 106 - INTEGER(IntKi), PARAMETER :: TwN8Fdy = 107 - INTEGER(IntKi), PARAMETER :: TwN9Fdy = 108 - - - ! Blade: - - INTEGER(IntKi), PARAMETER :: B1Azimuth = 109 - INTEGER(IntKi), PARAMETER :: B2Azimuth = 110 - INTEGER(IntKi), PARAMETER :: B3Azimuth = 111 - INTEGER(IntKi), PARAMETER :: B1Pitch = 112 - INTEGER(IntKi), PARAMETER :: B2Pitch = 113 - INTEGER(IntKi), PARAMETER :: B3Pitch = 114 - INTEGER(IntKi), PARAMETER :: B1AeroFx = 115 - INTEGER(IntKi), PARAMETER :: B1AeroFy = 116 - INTEGER(IntKi), PARAMETER :: B1AeroFz = 117 - INTEGER(IntKi), PARAMETER :: B1AeroMx = 118 - INTEGER(IntKi), PARAMETER :: B1AeroMy = 119 - INTEGER(IntKi), PARAMETER :: B1AeroMz = 120 - INTEGER(IntKi), PARAMETER :: B1AeroPwr = 121 - INTEGER(IntKi), PARAMETER :: B2AeroFx = 122 - INTEGER(IntKi), PARAMETER :: B2AeroFy = 123 - INTEGER(IntKi), PARAMETER :: B2AeroFz = 124 - INTEGER(IntKi), PARAMETER :: B2AeroMx = 125 - INTEGER(IntKi), PARAMETER :: B2AeroMy = 126 - INTEGER(IntKi), PARAMETER :: B2AeroMz = 127 - INTEGER(IntKi), PARAMETER :: B2AeroPwr = 128 - INTEGER(IntKi), PARAMETER :: B3AeroFx = 129 - INTEGER(IntKi), PARAMETER :: B3AeroFy = 130 - INTEGER(IntKi), PARAMETER :: B3AeroFz = 131 - INTEGER(IntKi), PARAMETER :: B3AeroMx = 132 - INTEGER(IntKi), PARAMETER :: B3AeroMy = 133 - INTEGER(IntKi), PARAMETER :: B3AeroMz = 134 - INTEGER(IntKi), PARAMETER :: B3AeroPwr = 135 - INTEGER(IntKi), PARAMETER :: B4AeroFx = 136 - INTEGER(IntKi), PARAMETER :: B4AeroFy = 137 - INTEGER(IntKi), PARAMETER :: B4AeroFz = 138 - INTEGER(IntKi), PARAMETER :: B4AeroMx = 139 - INTEGER(IntKi), PARAMETER :: B4AeroMy = 140 - INTEGER(IntKi), PARAMETER :: B4AeroMz = 141 - INTEGER(IntKi), PARAMETER :: B4AeroPwr = 142 - INTEGER(IntKi), PARAMETER :: B1AeroFxg = 143 - INTEGER(IntKi), PARAMETER :: B1AeroFyg = 144 - INTEGER(IntKi), PARAMETER :: B1AeroFzg = 145 - INTEGER(IntKi), PARAMETER :: B1AeroMxg = 146 - INTEGER(IntKi), PARAMETER :: B1AeroMyg = 147 - INTEGER(IntKi), PARAMETER :: B1AeroMzg = 148 - INTEGER(IntKi), PARAMETER :: B2AeroFxg = 149 - INTEGER(IntKi), PARAMETER :: B2AeroFyg = 150 - INTEGER(IntKi), PARAMETER :: B2AeroFzg = 151 - INTEGER(IntKi), PARAMETER :: B2AeroMxg = 152 - INTEGER(IntKi), PARAMETER :: B2AeroMyg = 153 - INTEGER(IntKi), PARAMETER :: B2AeroMzg = 154 - INTEGER(IntKi), PARAMETER :: B3AeroFxg = 155 - INTEGER(IntKi), PARAMETER :: B3AeroFyg = 156 - INTEGER(IntKi), PARAMETER :: B3AeroFzg = 157 - INTEGER(IntKi), PARAMETER :: B3AeroMxg = 158 - INTEGER(IntKi), PARAMETER :: B3AeroMyg = 159 - INTEGER(IntKi), PARAMETER :: B3AeroMzg = 160 - INTEGER(IntKi), PARAMETER :: B4AeroFxg = 161 - INTEGER(IntKi), PARAMETER :: B4AeroFyg = 162 - INTEGER(IntKi), PARAMETER :: B4AeroFzg = 163 - INTEGER(IntKi), PARAMETER :: B4AeroMxg = 164 - INTEGER(IntKi), PARAMETER :: B4AeroMyg = 165 - INTEGER(IntKi), PARAMETER :: B4AeroMzg = 166 - - - ! Blade Nodal outputs: - - INTEGER(IntKi), PARAMETER :: B1N1VUndx = 167 - INTEGER(IntKi), PARAMETER :: B1N2VUndx = 168 - INTEGER(IntKi), PARAMETER :: B1N3VUndx = 169 - INTEGER(IntKi), PARAMETER :: B1N4VUndx = 170 - INTEGER(IntKi), PARAMETER :: B1N5VUndx = 171 - INTEGER(IntKi), PARAMETER :: B1N6VUndx = 172 - INTEGER(IntKi), PARAMETER :: B1N7VUndx = 173 - INTEGER(IntKi), PARAMETER :: B1N8VUndx = 174 - INTEGER(IntKi), PARAMETER :: B1N9VUndx = 175 - INTEGER(IntKi), PARAMETER :: B1N1VUndy = 176 - INTEGER(IntKi), PARAMETER :: B1N2VUndy = 177 - INTEGER(IntKi), PARAMETER :: B1N3VUndy = 178 - INTEGER(IntKi), PARAMETER :: B1N4VUndy = 179 - INTEGER(IntKi), PARAMETER :: B1N5VUndy = 180 - INTEGER(IntKi), PARAMETER :: B1N6VUndy = 181 - INTEGER(IntKi), PARAMETER :: B1N7VUndy = 182 - INTEGER(IntKi), PARAMETER :: B1N8VUndy = 183 - INTEGER(IntKi), PARAMETER :: B1N9VUndy = 184 - INTEGER(IntKi), PARAMETER :: B1N1VUndz = 185 - INTEGER(IntKi), PARAMETER :: B1N2VUndz = 186 - INTEGER(IntKi), PARAMETER :: B1N3VUndz = 187 - INTEGER(IntKi), PARAMETER :: B1N4VUndz = 188 - INTEGER(IntKi), PARAMETER :: B1N5VUndz = 189 - INTEGER(IntKi), PARAMETER :: B1N6VUndz = 190 - INTEGER(IntKi), PARAMETER :: B1N7VUndz = 191 - INTEGER(IntKi), PARAMETER :: B1N8VUndz = 192 - INTEGER(IntKi), PARAMETER :: B1N9VUndz = 193 - INTEGER(IntKi), PARAMETER :: B2N1VUndx = 194 - INTEGER(IntKi), PARAMETER :: B2N2VUndx = 195 - INTEGER(IntKi), PARAMETER :: B2N3VUndx = 196 - INTEGER(IntKi), PARAMETER :: B2N4VUndx = 197 - INTEGER(IntKi), PARAMETER :: B2N5VUndx = 198 - INTEGER(IntKi), PARAMETER :: B2N6VUndx = 199 - INTEGER(IntKi), PARAMETER :: B2N7VUndx = 200 - INTEGER(IntKi), PARAMETER :: B2N8VUndx = 201 - INTEGER(IntKi), PARAMETER :: B2N9VUndx = 202 - INTEGER(IntKi), PARAMETER :: B2N1VUndy = 203 - INTEGER(IntKi), PARAMETER :: B2N2VUndy = 204 - INTEGER(IntKi), PARAMETER :: B2N3VUndy = 205 - INTEGER(IntKi), PARAMETER :: B2N4VUndy = 206 - INTEGER(IntKi), PARAMETER :: B2N5VUndy = 207 - INTEGER(IntKi), PARAMETER :: B2N6VUndy = 208 - INTEGER(IntKi), PARAMETER :: B2N7VUndy = 209 - INTEGER(IntKi), PARAMETER :: B2N8VUndy = 210 - INTEGER(IntKi), PARAMETER :: B2N9VUndy = 211 - INTEGER(IntKi), PARAMETER :: B2N1VUndz = 212 - INTEGER(IntKi), PARAMETER :: B2N2VUndz = 213 - INTEGER(IntKi), PARAMETER :: B2N3VUndz = 214 - INTEGER(IntKi), PARAMETER :: B2N4VUndz = 215 - INTEGER(IntKi), PARAMETER :: B2N5VUndz = 216 - INTEGER(IntKi), PARAMETER :: B2N6VUndz = 217 - INTEGER(IntKi), PARAMETER :: B2N7VUndz = 218 - INTEGER(IntKi), PARAMETER :: B2N8VUndz = 219 - INTEGER(IntKi), PARAMETER :: B2N9VUndz = 220 - INTEGER(IntKi), PARAMETER :: B3N1VUndx = 221 - INTEGER(IntKi), PARAMETER :: B3N2VUndx = 222 - INTEGER(IntKi), PARAMETER :: B3N3VUndx = 223 - INTEGER(IntKi), PARAMETER :: B3N4VUndx = 224 - INTEGER(IntKi), PARAMETER :: B3N5VUndx = 225 - INTEGER(IntKi), PARAMETER :: B3N6VUndx = 226 - INTEGER(IntKi), PARAMETER :: B3N7VUndx = 227 - INTEGER(IntKi), PARAMETER :: B3N8VUndx = 228 - INTEGER(IntKi), PARAMETER :: B3N9VUndx = 229 - INTEGER(IntKi), PARAMETER :: B3N1VUndy = 230 - INTEGER(IntKi), PARAMETER :: B3N2VUndy = 231 - INTEGER(IntKi), PARAMETER :: B3N3VUndy = 232 - INTEGER(IntKi), PARAMETER :: B3N4VUndy = 233 - INTEGER(IntKi), PARAMETER :: B3N5VUndy = 234 - INTEGER(IntKi), PARAMETER :: B3N6VUndy = 235 - INTEGER(IntKi), PARAMETER :: B3N7VUndy = 236 - INTEGER(IntKi), PARAMETER :: B3N8VUndy = 237 - INTEGER(IntKi), PARAMETER :: B3N9VUndy = 238 - INTEGER(IntKi), PARAMETER :: B3N1VUndz = 239 - INTEGER(IntKi), PARAMETER :: B3N2VUndz = 240 - INTEGER(IntKi), PARAMETER :: B3N3VUndz = 241 - INTEGER(IntKi), PARAMETER :: B3N4VUndz = 242 - INTEGER(IntKi), PARAMETER :: B3N5VUndz = 243 - INTEGER(IntKi), PARAMETER :: B3N6VUndz = 244 - INTEGER(IntKi), PARAMETER :: B3N7VUndz = 245 - INTEGER(IntKi), PARAMETER :: B3N8VUndz = 246 - INTEGER(IntKi), PARAMETER :: B3N9VUndz = 247 - INTEGER(IntKi), PARAMETER :: B1N1VDisx = 248 - INTEGER(IntKi), PARAMETER :: B1N2VDisx = 249 - INTEGER(IntKi), PARAMETER :: B1N3VDisx = 250 - INTEGER(IntKi), PARAMETER :: B1N4VDisx = 251 - INTEGER(IntKi), PARAMETER :: B1N5VDisx = 252 - INTEGER(IntKi), PARAMETER :: B1N6VDisx = 253 - INTEGER(IntKi), PARAMETER :: B1N7VDisx = 254 - INTEGER(IntKi), PARAMETER :: B1N8VDisx = 255 - INTEGER(IntKi), PARAMETER :: B1N9VDisx = 256 - INTEGER(IntKi), PARAMETER :: B1N1VDisy = 257 - INTEGER(IntKi), PARAMETER :: B1N2VDisy = 258 - INTEGER(IntKi), PARAMETER :: B1N3VDisy = 259 - INTEGER(IntKi), PARAMETER :: B1N4VDisy = 260 - INTEGER(IntKi), PARAMETER :: B1N5VDisy = 261 - INTEGER(IntKi), PARAMETER :: B1N6VDisy = 262 - INTEGER(IntKi), PARAMETER :: B1N7VDisy = 263 - INTEGER(IntKi), PARAMETER :: B1N8VDisy = 264 - INTEGER(IntKi), PARAMETER :: B1N9VDisy = 265 - INTEGER(IntKi), PARAMETER :: B1N1VDisz = 266 - INTEGER(IntKi), PARAMETER :: B1N2VDisz = 267 - INTEGER(IntKi), PARAMETER :: B1N3VDisz = 268 - INTEGER(IntKi), PARAMETER :: B1N4VDisz = 269 - INTEGER(IntKi), PARAMETER :: B1N5VDisz = 270 - INTEGER(IntKi), PARAMETER :: B1N6VDisz = 271 - INTEGER(IntKi), PARAMETER :: B1N7VDisz = 272 - INTEGER(IntKi), PARAMETER :: B1N8VDisz = 273 - INTEGER(IntKi), PARAMETER :: B1N9VDisz = 274 - INTEGER(IntKi), PARAMETER :: B2N1VDisx = 275 - INTEGER(IntKi), PARAMETER :: B2N2VDisx = 276 - INTEGER(IntKi), PARAMETER :: B2N3VDisx = 277 - INTEGER(IntKi), PARAMETER :: B2N4VDisx = 278 - INTEGER(IntKi), PARAMETER :: B2N5VDisx = 279 - INTEGER(IntKi), PARAMETER :: B2N6VDisx = 280 - INTEGER(IntKi), PARAMETER :: B2N7VDisx = 281 - INTEGER(IntKi), PARAMETER :: B2N8VDisx = 282 - INTEGER(IntKi), PARAMETER :: B2N9VDisx = 283 - INTEGER(IntKi), PARAMETER :: B2N1VDisy = 284 - INTEGER(IntKi), PARAMETER :: B2N2VDisy = 285 - INTEGER(IntKi), PARAMETER :: B2N3VDisy = 286 - INTEGER(IntKi), PARAMETER :: B2N4VDisy = 287 - INTEGER(IntKi), PARAMETER :: B2N5VDisy = 288 - INTEGER(IntKi), PARAMETER :: B2N6VDisy = 289 - INTEGER(IntKi), PARAMETER :: B2N7VDisy = 290 - INTEGER(IntKi), PARAMETER :: B2N8VDisy = 291 - INTEGER(IntKi), PARAMETER :: B2N9VDisy = 292 - INTEGER(IntKi), PARAMETER :: B2N1VDisz = 293 - INTEGER(IntKi), PARAMETER :: B2N2VDisz = 294 - INTEGER(IntKi), PARAMETER :: B2N3VDisz = 295 - INTEGER(IntKi), PARAMETER :: B2N4VDisz = 296 - INTEGER(IntKi), PARAMETER :: B2N5VDisz = 297 - INTEGER(IntKi), PARAMETER :: B2N6VDisz = 298 - INTEGER(IntKi), PARAMETER :: B2N7VDisz = 299 - INTEGER(IntKi), PARAMETER :: B2N8VDisz = 300 - INTEGER(IntKi), PARAMETER :: B2N9VDisz = 301 - INTEGER(IntKi), PARAMETER :: B3N1VDisx = 302 - INTEGER(IntKi), PARAMETER :: B3N2VDisx = 303 - INTEGER(IntKi), PARAMETER :: B3N3VDisx = 304 - INTEGER(IntKi), PARAMETER :: B3N4VDisx = 305 - INTEGER(IntKi), PARAMETER :: B3N5VDisx = 306 - INTEGER(IntKi), PARAMETER :: B3N6VDisx = 307 - INTEGER(IntKi), PARAMETER :: B3N7VDisx = 308 - INTEGER(IntKi), PARAMETER :: B3N8VDisx = 309 - INTEGER(IntKi), PARAMETER :: B3N9VDisx = 310 - INTEGER(IntKi), PARAMETER :: B3N1VDisy = 311 - INTEGER(IntKi), PARAMETER :: B3N2VDisy = 312 - INTEGER(IntKi), PARAMETER :: B3N3VDisy = 313 - INTEGER(IntKi), PARAMETER :: B3N4VDisy = 314 - INTEGER(IntKi), PARAMETER :: B3N5VDisy = 315 - INTEGER(IntKi), PARAMETER :: B3N6VDisy = 316 - INTEGER(IntKi), PARAMETER :: B3N7VDisy = 317 - INTEGER(IntKi), PARAMETER :: B3N8VDisy = 318 - INTEGER(IntKi), PARAMETER :: B3N9VDisy = 319 - INTEGER(IntKi), PARAMETER :: B3N1VDisz = 320 - INTEGER(IntKi), PARAMETER :: B3N2VDisz = 321 - INTEGER(IntKi), PARAMETER :: B3N3VDisz = 322 - INTEGER(IntKi), PARAMETER :: B3N4VDisz = 323 - INTEGER(IntKi), PARAMETER :: B3N5VDisz = 324 - INTEGER(IntKi), PARAMETER :: B3N6VDisz = 325 - INTEGER(IntKi), PARAMETER :: B3N7VDisz = 326 - INTEGER(IntKi), PARAMETER :: B3N8VDisz = 327 - INTEGER(IntKi), PARAMETER :: B3N9VDisz = 328 - INTEGER(IntKi), PARAMETER :: B1N1STVx = 329 - INTEGER(IntKi), PARAMETER :: B1N2STVx = 330 - INTEGER(IntKi), PARAMETER :: B1N3STVx = 331 - INTEGER(IntKi), PARAMETER :: B1N4STVx = 332 - INTEGER(IntKi), PARAMETER :: B1N5STVx = 333 - INTEGER(IntKi), PARAMETER :: B1N6STVx = 334 - INTEGER(IntKi), PARAMETER :: B1N7STVx = 335 - INTEGER(IntKi), PARAMETER :: B1N8STVx = 336 - INTEGER(IntKi), PARAMETER :: B1N9STVx = 337 - INTEGER(IntKi), PARAMETER :: B1N1STVy = 338 - INTEGER(IntKi), PARAMETER :: B1N2STVy = 339 - INTEGER(IntKi), PARAMETER :: B1N3STVy = 340 - INTEGER(IntKi), PARAMETER :: B1N4STVy = 341 - INTEGER(IntKi), PARAMETER :: B1N5STVy = 342 - INTEGER(IntKi), PARAMETER :: B1N6STVy = 343 - INTEGER(IntKi), PARAMETER :: B1N7STVy = 344 - INTEGER(IntKi), PARAMETER :: B1N8STVy = 345 - INTEGER(IntKi), PARAMETER :: B1N9STVy = 346 - INTEGER(IntKi), PARAMETER :: B1N1STVz = 347 - INTEGER(IntKi), PARAMETER :: B1N2STVz = 348 - INTEGER(IntKi), PARAMETER :: B1N3STVz = 349 - INTEGER(IntKi), PARAMETER :: B1N4STVz = 350 - INTEGER(IntKi), PARAMETER :: B1N5STVz = 351 - INTEGER(IntKi), PARAMETER :: B1N6STVz = 352 - INTEGER(IntKi), PARAMETER :: B1N7STVz = 353 - INTEGER(IntKi), PARAMETER :: B1N8STVz = 354 - INTEGER(IntKi), PARAMETER :: B1N9STVz = 355 - INTEGER(IntKi), PARAMETER :: B2N1STVx = 356 - INTEGER(IntKi), PARAMETER :: B2N2STVx = 357 - INTEGER(IntKi), PARAMETER :: B2N3STVx = 358 - INTEGER(IntKi), PARAMETER :: B2N4STVx = 359 - INTEGER(IntKi), PARAMETER :: B2N5STVx = 360 - INTEGER(IntKi), PARAMETER :: B2N6STVx = 361 - INTEGER(IntKi), PARAMETER :: B2N7STVx = 362 - INTEGER(IntKi), PARAMETER :: B2N8STVx = 363 - INTEGER(IntKi), PARAMETER :: B2N9STVx = 364 - INTEGER(IntKi), PARAMETER :: B2N1STVy = 365 - INTEGER(IntKi), PARAMETER :: B2N2STVy = 366 - INTEGER(IntKi), PARAMETER :: B2N3STVy = 367 - INTEGER(IntKi), PARAMETER :: B2N4STVy = 368 - INTEGER(IntKi), PARAMETER :: B2N5STVy = 369 - INTEGER(IntKi), PARAMETER :: B2N6STVy = 370 - INTEGER(IntKi), PARAMETER :: B2N7STVy = 371 - INTEGER(IntKi), PARAMETER :: B2N8STVy = 372 - INTEGER(IntKi), PARAMETER :: B2N9STVy = 373 - INTEGER(IntKi), PARAMETER :: B2N1STVz = 374 - INTEGER(IntKi), PARAMETER :: B2N2STVz = 375 - INTEGER(IntKi), PARAMETER :: B2N3STVz = 376 - INTEGER(IntKi), PARAMETER :: B2N4STVz = 377 - INTEGER(IntKi), PARAMETER :: B2N5STVz = 378 - INTEGER(IntKi), PARAMETER :: B2N6STVz = 379 - INTEGER(IntKi), PARAMETER :: B2N7STVz = 380 - INTEGER(IntKi), PARAMETER :: B2N8STVz = 381 - INTEGER(IntKi), PARAMETER :: B2N9STVz = 382 - INTEGER(IntKi), PARAMETER :: B3N1STVx = 383 - INTEGER(IntKi), PARAMETER :: B3N2STVx = 384 - INTEGER(IntKi), PARAMETER :: B3N3STVx = 385 - INTEGER(IntKi), PARAMETER :: B3N4STVx = 386 - INTEGER(IntKi), PARAMETER :: B3N5STVx = 387 - INTEGER(IntKi), PARAMETER :: B3N6STVx = 388 - INTEGER(IntKi), PARAMETER :: B3N7STVx = 389 - INTEGER(IntKi), PARAMETER :: B3N8STVx = 390 - INTEGER(IntKi), PARAMETER :: B3N9STVx = 391 - INTEGER(IntKi), PARAMETER :: B3N1STVy = 392 - INTEGER(IntKi), PARAMETER :: B3N2STVy = 393 - INTEGER(IntKi), PARAMETER :: B3N3STVy = 394 - INTEGER(IntKi), PARAMETER :: B3N4STVy = 395 - INTEGER(IntKi), PARAMETER :: B3N5STVy = 396 - INTEGER(IntKi), PARAMETER :: B3N6STVy = 397 - INTEGER(IntKi), PARAMETER :: B3N7STVy = 398 - INTEGER(IntKi), PARAMETER :: B3N8STVy = 399 - INTEGER(IntKi), PARAMETER :: B3N9STVy = 400 - INTEGER(IntKi), PARAMETER :: B3N1STVz = 401 - INTEGER(IntKi), PARAMETER :: B3N2STVz = 402 - INTEGER(IntKi), PARAMETER :: B3N3STVz = 403 - INTEGER(IntKi), PARAMETER :: B3N4STVz = 404 - INTEGER(IntKi), PARAMETER :: B3N5STVz = 405 - INTEGER(IntKi), PARAMETER :: B3N6STVz = 406 - INTEGER(IntKi), PARAMETER :: B3N7STVz = 407 - INTEGER(IntKi), PARAMETER :: B3N8STVz = 408 - INTEGER(IntKi), PARAMETER :: B3N9STVz = 409 - INTEGER(IntKi), PARAMETER :: B1N1VRel = 410 - INTEGER(IntKi), PARAMETER :: B1N2VRel = 411 - INTEGER(IntKi), PARAMETER :: B1N3VRel = 412 - INTEGER(IntKi), PARAMETER :: B1N4VRel = 413 - INTEGER(IntKi), PARAMETER :: B1N5VRel = 414 - INTEGER(IntKi), PARAMETER :: B1N6VRel = 415 - INTEGER(IntKi), PARAMETER :: B1N7VRel = 416 - INTEGER(IntKi), PARAMETER :: B1N8VRel = 417 - INTEGER(IntKi), PARAMETER :: B1N9VRel = 418 - INTEGER(IntKi), PARAMETER :: B2N1VRel = 419 - INTEGER(IntKi), PARAMETER :: B2N2VRel = 420 - INTEGER(IntKi), PARAMETER :: B2N3VRel = 421 - INTEGER(IntKi), PARAMETER :: B2N4VRel = 422 - INTEGER(IntKi), PARAMETER :: B2N5VRel = 423 - INTEGER(IntKi), PARAMETER :: B2N6VRel = 424 - INTEGER(IntKi), PARAMETER :: B2N7VRel = 425 - INTEGER(IntKi), PARAMETER :: B2N8VRel = 426 - INTEGER(IntKi), PARAMETER :: B2N9VRel = 427 - INTEGER(IntKi), PARAMETER :: B3N1VRel = 428 - INTEGER(IntKi), PARAMETER :: B3N2VRel = 429 - INTEGER(IntKi), PARAMETER :: B3N3VRel = 430 - INTEGER(IntKi), PARAMETER :: B3N4VRel = 431 - INTEGER(IntKi), PARAMETER :: B3N5VRel = 432 - INTEGER(IntKi), PARAMETER :: B3N6VRel = 433 - INTEGER(IntKi), PARAMETER :: B3N7VRel = 434 - INTEGER(IntKi), PARAMETER :: B3N8VRel = 435 - INTEGER(IntKi), PARAMETER :: B3N9VRel = 436 - INTEGER(IntKi), PARAMETER :: B1N1DynP = 437 - INTEGER(IntKi), PARAMETER :: B1N2DynP = 438 - INTEGER(IntKi), PARAMETER :: B1N3DynP = 439 - INTEGER(IntKi), PARAMETER :: B1N4DynP = 440 - INTEGER(IntKi), PARAMETER :: B1N5DynP = 441 - INTEGER(IntKi), PARAMETER :: B1N6DynP = 442 - INTEGER(IntKi), PARAMETER :: B1N7DynP = 443 - INTEGER(IntKi), PARAMETER :: B1N8DynP = 444 - INTEGER(IntKi), PARAMETER :: B1N9DynP = 445 - INTEGER(IntKi), PARAMETER :: B2N1DynP = 446 - INTEGER(IntKi), PARAMETER :: B2N2DynP = 447 - INTEGER(IntKi), PARAMETER :: B2N3DynP = 448 - INTEGER(IntKi), PARAMETER :: B2N4DynP = 449 - INTEGER(IntKi), PARAMETER :: B2N5DynP = 450 - INTEGER(IntKi), PARAMETER :: B2N6DynP = 451 - INTEGER(IntKi), PARAMETER :: B2N7DynP = 452 - INTEGER(IntKi), PARAMETER :: B2N8DynP = 453 - INTEGER(IntKi), PARAMETER :: B2N9DynP = 454 - INTEGER(IntKi), PARAMETER :: B3N1DynP = 455 - INTEGER(IntKi), PARAMETER :: B3N2DynP = 456 - INTEGER(IntKi), PARAMETER :: B3N3DynP = 457 - INTEGER(IntKi), PARAMETER :: B3N4DynP = 458 - INTEGER(IntKi), PARAMETER :: B3N5DynP = 459 - INTEGER(IntKi), PARAMETER :: B3N6DynP = 460 - INTEGER(IntKi), PARAMETER :: B3N7DynP = 461 - INTEGER(IntKi), PARAMETER :: B3N8DynP = 462 - INTEGER(IntKi), PARAMETER :: B3N9DynP = 463 - INTEGER(IntKi), PARAMETER :: B1N1Re = 464 - INTEGER(IntKi), PARAMETER :: B1N2Re = 465 - INTEGER(IntKi), PARAMETER :: B1N3Re = 466 - INTEGER(IntKi), PARAMETER :: B1N4Re = 467 - INTEGER(IntKi), PARAMETER :: B1N5Re = 468 - INTEGER(IntKi), PARAMETER :: B1N6Re = 469 - INTEGER(IntKi), PARAMETER :: B1N7Re = 470 - INTEGER(IntKi), PARAMETER :: B1N8Re = 471 - INTEGER(IntKi), PARAMETER :: B1N9Re = 472 - INTEGER(IntKi), PARAMETER :: B2N1Re = 473 - INTEGER(IntKi), PARAMETER :: B2N2Re = 474 - INTEGER(IntKi), PARAMETER :: B2N3Re = 475 - INTEGER(IntKi), PARAMETER :: B2N4Re = 476 - INTEGER(IntKi), PARAMETER :: B2N5Re = 477 - INTEGER(IntKi), PARAMETER :: B2N6Re = 478 - INTEGER(IntKi), PARAMETER :: B2N7Re = 479 - INTEGER(IntKi), PARAMETER :: B2N8Re = 480 - INTEGER(IntKi), PARAMETER :: B2N9Re = 481 - INTEGER(IntKi), PARAMETER :: B3N1Re = 482 - INTEGER(IntKi), PARAMETER :: B3N2Re = 483 - INTEGER(IntKi), PARAMETER :: B3N3Re = 484 - INTEGER(IntKi), PARAMETER :: B3N4Re = 485 - INTEGER(IntKi), PARAMETER :: B3N5Re = 486 - INTEGER(IntKi), PARAMETER :: B3N6Re = 487 - INTEGER(IntKi), PARAMETER :: B3N7Re = 488 - INTEGER(IntKi), PARAMETER :: B3N8Re = 489 - INTEGER(IntKi), PARAMETER :: B3N9Re = 490 - INTEGER(IntKi), PARAMETER :: B1N1M = 491 - INTEGER(IntKi), PARAMETER :: B1N2M = 492 - INTEGER(IntKi), PARAMETER :: B1N3M = 493 - INTEGER(IntKi), PARAMETER :: B1N4M = 494 - INTEGER(IntKi), PARAMETER :: B1N5M = 495 - INTEGER(IntKi), PARAMETER :: B1N6M = 496 - INTEGER(IntKi), PARAMETER :: B1N7M = 497 - INTEGER(IntKi), PARAMETER :: B1N8M = 498 - INTEGER(IntKi), PARAMETER :: B1N9M = 499 - INTEGER(IntKi), PARAMETER :: B2N1M = 500 - INTEGER(IntKi), PARAMETER :: B2N2M = 501 - INTEGER(IntKi), PARAMETER :: B2N3M = 502 - INTEGER(IntKi), PARAMETER :: B2N4M = 503 - INTEGER(IntKi), PARAMETER :: B2N5M = 504 - INTEGER(IntKi), PARAMETER :: B2N6M = 505 - INTEGER(IntKi), PARAMETER :: B2N7M = 506 - INTEGER(IntKi), PARAMETER :: B2N8M = 507 - INTEGER(IntKi), PARAMETER :: B2N9M = 508 - INTEGER(IntKi), PARAMETER :: B3N1M = 509 - INTEGER(IntKi), PARAMETER :: B3N2M = 510 - INTEGER(IntKi), PARAMETER :: B3N3M = 511 - INTEGER(IntKi), PARAMETER :: B3N4M = 512 - INTEGER(IntKi), PARAMETER :: B3N5M = 513 - INTEGER(IntKi), PARAMETER :: B3N6M = 514 - INTEGER(IntKi), PARAMETER :: B3N7M = 515 - INTEGER(IntKi), PARAMETER :: B3N8M = 516 - INTEGER(IntKi), PARAMETER :: B3N9M = 517 - INTEGER(IntKi), PARAMETER :: B1N1Vindx = 518 - INTEGER(IntKi), PARAMETER :: B1N2Vindx = 519 - INTEGER(IntKi), PARAMETER :: B1N3Vindx = 520 - INTEGER(IntKi), PARAMETER :: B1N4Vindx = 521 - INTEGER(IntKi), PARAMETER :: B1N5Vindx = 522 - INTEGER(IntKi), PARAMETER :: B1N6Vindx = 523 - INTEGER(IntKi), PARAMETER :: B1N7Vindx = 524 - INTEGER(IntKi), PARAMETER :: B1N8Vindx = 525 - INTEGER(IntKi), PARAMETER :: B1N9Vindx = 526 - INTEGER(IntKi), PARAMETER :: B2N1Vindx = 527 - INTEGER(IntKi), PARAMETER :: B2N2Vindx = 528 - INTEGER(IntKi), PARAMETER :: B2N3Vindx = 529 - INTEGER(IntKi), PARAMETER :: B2N4Vindx = 530 - INTEGER(IntKi), PARAMETER :: B2N5Vindx = 531 - INTEGER(IntKi), PARAMETER :: B2N6Vindx = 532 - INTEGER(IntKi), PARAMETER :: B2N7Vindx = 533 - INTEGER(IntKi), PARAMETER :: B2N8Vindx = 534 - INTEGER(IntKi), PARAMETER :: B2N9Vindx = 535 - INTEGER(IntKi), PARAMETER :: B3N1Vindx = 536 - INTEGER(IntKi), PARAMETER :: B3N2Vindx = 537 - INTEGER(IntKi), PARAMETER :: B3N3Vindx = 538 - INTEGER(IntKi), PARAMETER :: B3N4Vindx = 539 - INTEGER(IntKi), PARAMETER :: B3N5Vindx = 540 - INTEGER(IntKi), PARAMETER :: B3N6Vindx = 541 - INTEGER(IntKi), PARAMETER :: B3N7Vindx = 542 - INTEGER(IntKi), PARAMETER :: B3N8Vindx = 543 - INTEGER(IntKi), PARAMETER :: B3N9Vindx = 544 - INTEGER(IntKi), PARAMETER :: B1N1Vindy = 545 - INTEGER(IntKi), PARAMETER :: B1N2Vindy = 546 - INTEGER(IntKi), PARAMETER :: B1N3Vindy = 547 - INTEGER(IntKi), PARAMETER :: B1N4Vindy = 548 - INTEGER(IntKi), PARAMETER :: B1N5Vindy = 549 - INTEGER(IntKi), PARAMETER :: B1N6Vindy = 550 - INTEGER(IntKi), PARAMETER :: B1N7Vindy = 551 - INTEGER(IntKi), PARAMETER :: B1N8Vindy = 552 - INTEGER(IntKi), PARAMETER :: B1N9Vindy = 553 - INTEGER(IntKi), PARAMETER :: B2N1Vindy = 554 - INTEGER(IntKi), PARAMETER :: B2N2Vindy = 555 - INTEGER(IntKi), PARAMETER :: B2N3Vindy = 556 - INTEGER(IntKi), PARAMETER :: B2N4Vindy = 557 - INTEGER(IntKi), PARAMETER :: B2N5Vindy = 558 - INTEGER(IntKi), PARAMETER :: B2N6Vindy = 559 - INTEGER(IntKi), PARAMETER :: B2N7Vindy = 560 - INTEGER(IntKi), PARAMETER :: B2N8Vindy = 561 - INTEGER(IntKi), PARAMETER :: B2N9Vindy = 562 - INTEGER(IntKi), PARAMETER :: B3N1Vindy = 563 - INTEGER(IntKi), PARAMETER :: B3N2Vindy = 564 - INTEGER(IntKi), PARAMETER :: B3N3Vindy = 565 - INTEGER(IntKi), PARAMETER :: B3N4Vindy = 566 - INTEGER(IntKi), PARAMETER :: B3N5Vindy = 567 - INTEGER(IntKi), PARAMETER :: B3N6Vindy = 568 - INTEGER(IntKi), PARAMETER :: B3N7Vindy = 569 - INTEGER(IntKi), PARAMETER :: B3N8Vindy = 570 - INTEGER(IntKi), PARAMETER :: B3N9Vindy = 571 - INTEGER(IntKi), PARAMETER :: B1N1AxInd = 572 - INTEGER(IntKi), PARAMETER :: B1N2AxInd = 573 - INTEGER(IntKi), PARAMETER :: B1N3AxInd = 574 - INTEGER(IntKi), PARAMETER :: B1N4AxInd = 575 - INTEGER(IntKi), PARAMETER :: B1N5AxInd = 576 - INTEGER(IntKi), PARAMETER :: B1N6AxInd = 577 - INTEGER(IntKi), PARAMETER :: B1N7AxInd = 578 - INTEGER(IntKi), PARAMETER :: B1N8AxInd = 579 - INTEGER(IntKi), PARAMETER :: B1N9AxInd = 580 - INTEGER(IntKi), PARAMETER :: B2N1AxInd = 581 - INTEGER(IntKi), PARAMETER :: B2N2AxInd = 582 - INTEGER(IntKi), PARAMETER :: B2N3AxInd = 583 - INTEGER(IntKi), PARAMETER :: B2N4AxInd = 584 - INTEGER(IntKi), PARAMETER :: B2N5AxInd = 585 - INTEGER(IntKi), PARAMETER :: B2N6AxInd = 586 - INTEGER(IntKi), PARAMETER :: B2N7AxInd = 587 - INTEGER(IntKi), PARAMETER :: B2N8AxInd = 588 - INTEGER(IntKi), PARAMETER :: B2N9AxInd = 589 - INTEGER(IntKi), PARAMETER :: B3N1AxInd = 590 - INTEGER(IntKi), PARAMETER :: B3N2AxInd = 591 - INTEGER(IntKi), PARAMETER :: B3N3AxInd = 592 - INTEGER(IntKi), PARAMETER :: B3N4AxInd = 593 - INTEGER(IntKi), PARAMETER :: B3N5AxInd = 594 - INTEGER(IntKi), PARAMETER :: B3N6AxInd = 595 - INTEGER(IntKi), PARAMETER :: B3N7AxInd = 596 - INTEGER(IntKi), PARAMETER :: B3N8AxInd = 597 - INTEGER(IntKi), PARAMETER :: B3N9AxInd = 598 - INTEGER(IntKi), PARAMETER :: B1N1TnInd = 599 - INTEGER(IntKi), PARAMETER :: B1N2TnInd = 600 - INTEGER(IntKi), PARAMETER :: B1N3TnInd = 601 - INTEGER(IntKi), PARAMETER :: B1N4TnInd = 602 - INTEGER(IntKi), PARAMETER :: B1N5TnInd = 603 - INTEGER(IntKi), PARAMETER :: B1N6TnInd = 604 - INTEGER(IntKi), PARAMETER :: B1N7TnInd = 605 - INTEGER(IntKi), PARAMETER :: B1N8TnInd = 606 - INTEGER(IntKi), PARAMETER :: B1N9TnInd = 607 - INTEGER(IntKi), PARAMETER :: B2N1TnInd = 608 - INTEGER(IntKi), PARAMETER :: B2N2TnInd = 609 - INTEGER(IntKi), PARAMETER :: B2N3TnInd = 610 - INTEGER(IntKi), PARAMETER :: B2N4TnInd = 611 - INTEGER(IntKi), PARAMETER :: B2N5TnInd = 612 - INTEGER(IntKi), PARAMETER :: B2N6TnInd = 613 - INTEGER(IntKi), PARAMETER :: B2N7TnInd = 614 - INTEGER(IntKi), PARAMETER :: B2N8TnInd = 615 - INTEGER(IntKi), PARAMETER :: B2N9TnInd = 616 - INTEGER(IntKi), PARAMETER :: B3N1TnInd = 617 - INTEGER(IntKi), PARAMETER :: B3N2TnInd = 618 - INTEGER(IntKi), PARAMETER :: B3N3TnInd = 619 - INTEGER(IntKi), PARAMETER :: B3N4TnInd = 620 - INTEGER(IntKi), PARAMETER :: B3N5TnInd = 621 - INTEGER(IntKi), PARAMETER :: B3N6TnInd = 622 - INTEGER(IntKi), PARAMETER :: B3N7TnInd = 623 - INTEGER(IntKi), PARAMETER :: B3N8TnInd = 624 - INTEGER(IntKi), PARAMETER :: B3N9TnInd = 625 - INTEGER(IntKi), PARAMETER :: B1N1Alpha = 626 - INTEGER(IntKi), PARAMETER :: B1N2Alpha = 627 - INTEGER(IntKi), PARAMETER :: B1N3Alpha = 628 - INTEGER(IntKi), PARAMETER :: B1N4Alpha = 629 - INTEGER(IntKi), PARAMETER :: B1N5Alpha = 630 - INTEGER(IntKi), PARAMETER :: B1N6Alpha = 631 - INTEGER(IntKi), PARAMETER :: B1N7Alpha = 632 - INTEGER(IntKi), PARAMETER :: B1N8Alpha = 633 - INTEGER(IntKi), PARAMETER :: B1N9Alpha = 634 - INTEGER(IntKi), PARAMETER :: B2N1Alpha = 635 - INTEGER(IntKi), PARAMETER :: B2N2Alpha = 636 - INTEGER(IntKi), PARAMETER :: B2N3Alpha = 637 - INTEGER(IntKi), PARAMETER :: B2N4Alpha = 638 - INTEGER(IntKi), PARAMETER :: B2N5Alpha = 639 - INTEGER(IntKi), PARAMETER :: B2N6Alpha = 640 - INTEGER(IntKi), PARAMETER :: B2N7Alpha = 641 - INTEGER(IntKi), PARAMETER :: B2N8Alpha = 642 - INTEGER(IntKi), PARAMETER :: B2N9Alpha = 643 - INTEGER(IntKi), PARAMETER :: B3N1Alpha = 644 - INTEGER(IntKi), PARAMETER :: B3N2Alpha = 645 - INTEGER(IntKi), PARAMETER :: B3N3Alpha = 646 - INTEGER(IntKi), PARAMETER :: B3N4Alpha = 647 - INTEGER(IntKi), PARAMETER :: B3N5Alpha = 648 - INTEGER(IntKi), PARAMETER :: B3N6Alpha = 649 - INTEGER(IntKi), PARAMETER :: B3N7Alpha = 650 - INTEGER(IntKi), PARAMETER :: B3N8Alpha = 651 - INTEGER(IntKi), PARAMETER :: B3N9Alpha = 652 - INTEGER(IntKi), PARAMETER :: B1N1Theta = 653 - INTEGER(IntKi), PARAMETER :: B1N2Theta = 654 - INTEGER(IntKi), PARAMETER :: B1N3Theta = 655 - INTEGER(IntKi), PARAMETER :: B1N4Theta = 656 - INTEGER(IntKi), PARAMETER :: B1N5Theta = 657 - INTEGER(IntKi), PARAMETER :: B1N6Theta = 658 - INTEGER(IntKi), PARAMETER :: B1N7Theta = 659 - INTEGER(IntKi), PARAMETER :: B1N8Theta = 660 - INTEGER(IntKi), PARAMETER :: B1N9Theta = 661 - INTEGER(IntKi), PARAMETER :: B2N1Theta = 662 - INTEGER(IntKi), PARAMETER :: B2N2Theta = 663 - INTEGER(IntKi), PARAMETER :: B2N3Theta = 664 - INTEGER(IntKi), PARAMETER :: B2N4Theta = 665 - INTEGER(IntKi), PARAMETER :: B2N5Theta = 666 - INTEGER(IntKi), PARAMETER :: B2N6Theta = 667 - INTEGER(IntKi), PARAMETER :: B2N7Theta = 668 - INTEGER(IntKi), PARAMETER :: B2N8Theta = 669 - INTEGER(IntKi), PARAMETER :: B2N9Theta = 670 - INTEGER(IntKi), PARAMETER :: B3N1Theta = 671 - INTEGER(IntKi), PARAMETER :: B3N2Theta = 672 - INTEGER(IntKi), PARAMETER :: B3N3Theta = 673 - INTEGER(IntKi), PARAMETER :: B3N4Theta = 674 - INTEGER(IntKi), PARAMETER :: B3N5Theta = 675 - INTEGER(IntKi), PARAMETER :: B3N6Theta = 676 - INTEGER(IntKi), PARAMETER :: B3N7Theta = 677 - INTEGER(IntKi), PARAMETER :: B3N8Theta = 678 - INTEGER(IntKi), PARAMETER :: B3N9Theta = 679 - INTEGER(IntKi), PARAMETER :: B1N1Phi = 680 - INTEGER(IntKi), PARAMETER :: B1N2Phi = 681 - INTEGER(IntKi), PARAMETER :: B1N3Phi = 682 - INTEGER(IntKi), PARAMETER :: B1N4Phi = 683 - INTEGER(IntKi), PARAMETER :: B1N5Phi = 684 - INTEGER(IntKi), PARAMETER :: B1N6Phi = 685 - INTEGER(IntKi), PARAMETER :: B1N7Phi = 686 - INTEGER(IntKi), PARAMETER :: B1N8Phi = 687 - INTEGER(IntKi), PARAMETER :: B1N9Phi = 688 - INTEGER(IntKi), PARAMETER :: B2N1Phi = 689 - INTEGER(IntKi), PARAMETER :: B2N2Phi = 690 - INTEGER(IntKi), PARAMETER :: B2N3Phi = 691 - INTEGER(IntKi), PARAMETER :: B2N4Phi = 692 - INTEGER(IntKi), PARAMETER :: B2N5Phi = 693 - INTEGER(IntKi), PARAMETER :: B2N6Phi = 694 - INTEGER(IntKi), PARAMETER :: B2N7Phi = 695 - INTEGER(IntKi), PARAMETER :: B2N8Phi = 696 - INTEGER(IntKi), PARAMETER :: B2N9Phi = 697 - INTEGER(IntKi), PARAMETER :: B3N1Phi = 698 - INTEGER(IntKi), PARAMETER :: B3N2Phi = 699 - INTEGER(IntKi), PARAMETER :: B3N3Phi = 700 - INTEGER(IntKi), PARAMETER :: B3N4Phi = 701 - INTEGER(IntKi), PARAMETER :: B3N5Phi = 702 - INTEGER(IntKi), PARAMETER :: B3N6Phi = 703 - INTEGER(IntKi), PARAMETER :: B3N7Phi = 704 - INTEGER(IntKi), PARAMETER :: B3N8Phi = 705 - INTEGER(IntKi), PARAMETER :: B3N9Phi = 706 - INTEGER(IntKi), PARAMETER :: B1N1Curve = 707 - INTEGER(IntKi), PARAMETER :: B1N2Curve = 708 - INTEGER(IntKi), PARAMETER :: B1N3Curve = 709 - INTEGER(IntKi), PARAMETER :: B1N4Curve = 710 - INTEGER(IntKi), PARAMETER :: B1N5Curve = 711 - INTEGER(IntKi), PARAMETER :: B1N6Curve = 712 - INTEGER(IntKi), PARAMETER :: B1N7Curve = 713 - INTEGER(IntKi), PARAMETER :: B1N8Curve = 714 - INTEGER(IntKi), PARAMETER :: B1N9Curve = 715 - INTEGER(IntKi), PARAMETER :: B2N1Curve = 716 - INTEGER(IntKi), PARAMETER :: B2N2Curve = 717 - INTEGER(IntKi), PARAMETER :: B2N3Curve = 718 - INTEGER(IntKi), PARAMETER :: B2N4Curve = 719 - INTEGER(IntKi), PARAMETER :: B2N5Curve = 720 - INTEGER(IntKi), PARAMETER :: B2N6Curve = 721 - INTEGER(IntKi), PARAMETER :: B2N7Curve = 722 - INTEGER(IntKi), PARAMETER :: B2N8Curve = 723 - INTEGER(IntKi), PARAMETER :: B2N9Curve = 724 - INTEGER(IntKi), PARAMETER :: B3N1Curve = 725 - INTEGER(IntKi), PARAMETER :: B3N2Curve = 726 - INTEGER(IntKi), PARAMETER :: B3N3Curve = 727 - INTEGER(IntKi), PARAMETER :: B3N4Curve = 728 - INTEGER(IntKi), PARAMETER :: B3N5Curve = 729 - INTEGER(IntKi), PARAMETER :: B3N6Curve = 730 - INTEGER(IntKi), PARAMETER :: B3N7Curve = 731 - INTEGER(IntKi), PARAMETER :: B3N8Curve = 732 - INTEGER(IntKi), PARAMETER :: B3N9Curve = 733 - INTEGER(IntKi), PARAMETER :: B1N1Cl = 734 - INTEGER(IntKi), PARAMETER :: B1N2Cl = 735 - INTEGER(IntKi), PARAMETER :: B1N3Cl = 736 - INTEGER(IntKi), PARAMETER :: B1N4Cl = 737 - INTEGER(IntKi), PARAMETER :: B1N5Cl = 738 - INTEGER(IntKi), PARAMETER :: B1N6Cl = 739 - INTEGER(IntKi), PARAMETER :: B1N7Cl = 740 - INTEGER(IntKi), PARAMETER :: B1N8Cl = 741 - INTEGER(IntKi), PARAMETER :: B1N9Cl = 742 - INTEGER(IntKi), PARAMETER :: B2N1Cl = 743 - INTEGER(IntKi), PARAMETER :: B2N2Cl = 744 - INTEGER(IntKi), PARAMETER :: B2N3Cl = 745 - INTEGER(IntKi), PARAMETER :: B2N4Cl = 746 - INTEGER(IntKi), PARAMETER :: B2N5Cl = 747 - INTEGER(IntKi), PARAMETER :: B2N6Cl = 748 - INTEGER(IntKi), PARAMETER :: B2N7Cl = 749 - INTEGER(IntKi), PARAMETER :: B2N8Cl = 750 - INTEGER(IntKi), PARAMETER :: B2N9Cl = 751 - INTEGER(IntKi), PARAMETER :: B3N1Cl = 752 - INTEGER(IntKi), PARAMETER :: B3N2Cl = 753 - INTEGER(IntKi), PARAMETER :: B3N3Cl = 754 - INTEGER(IntKi), PARAMETER :: B3N4Cl = 755 - INTEGER(IntKi), PARAMETER :: B3N5Cl = 756 - INTEGER(IntKi), PARAMETER :: B3N6Cl = 757 - INTEGER(IntKi), PARAMETER :: B3N7Cl = 758 - INTEGER(IntKi), PARAMETER :: B3N8Cl = 759 - INTEGER(IntKi), PARAMETER :: B3N9Cl = 760 - INTEGER(IntKi), PARAMETER :: B1N1Cd = 761 - INTEGER(IntKi), PARAMETER :: B1N2Cd = 762 - INTEGER(IntKi), PARAMETER :: B1N3Cd = 763 - INTEGER(IntKi), PARAMETER :: B1N4Cd = 764 - INTEGER(IntKi), PARAMETER :: B1N5Cd = 765 - INTEGER(IntKi), PARAMETER :: B1N6Cd = 766 - INTEGER(IntKi), PARAMETER :: B1N7Cd = 767 - INTEGER(IntKi), PARAMETER :: B1N8Cd = 768 - INTEGER(IntKi), PARAMETER :: B1N9Cd = 769 - INTEGER(IntKi), PARAMETER :: B2N1Cd = 770 - INTEGER(IntKi), PARAMETER :: B2N2Cd = 771 - INTEGER(IntKi), PARAMETER :: B2N3Cd = 772 - INTEGER(IntKi), PARAMETER :: B2N4Cd = 773 - INTEGER(IntKi), PARAMETER :: B2N5Cd = 774 - INTEGER(IntKi), PARAMETER :: B2N6Cd = 775 - INTEGER(IntKi), PARAMETER :: B2N7Cd = 776 - INTEGER(IntKi), PARAMETER :: B2N8Cd = 777 - INTEGER(IntKi), PARAMETER :: B2N9Cd = 778 - INTEGER(IntKi), PARAMETER :: B3N1Cd = 779 - INTEGER(IntKi), PARAMETER :: B3N2Cd = 780 - INTEGER(IntKi), PARAMETER :: B3N3Cd = 781 - INTEGER(IntKi), PARAMETER :: B3N4Cd = 782 - INTEGER(IntKi), PARAMETER :: B3N5Cd = 783 - INTEGER(IntKi), PARAMETER :: B3N6Cd = 784 - INTEGER(IntKi), PARAMETER :: B3N7Cd = 785 - INTEGER(IntKi), PARAMETER :: B3N8Cd = 786 - INTEGER(IntKi), PARAMETER :: B3N9Cd = 787 - INTEGER(IntKi), PARAMETER :: B1N1Cm = 788 - INTEGER(IntKi), PARAMETER :: B1N2Cm = 789 - INTEGER(IntKi), PARAMETER :: B1N3Cm = 790 - INTEGER(IntKi), PARAMETER :: B1N4Cm = 791 - INTEGER(IntKi), PARAMETER :: B1N5Cm = 792 - INTEGER(IntKi), PARAMETER :: B1N6Cm = 793 - INTEGER(IntKi), PARAMETER :: B1N7Cm = 794 - INTEGER(IntKi), PARAMETER :: B1N8Cm = 795 - INTEGER(IntKi), PARAMETER :: B1N9Cm = 796 - INTEGER(IntKi), PARAMETER :: B2N1Cm = 797 - INTEGER(IntKi), PARAMETER :: B2N2Cm = 798 - INTEGER(IntKi), PARAMETER :: B2N3Cm = 799 - INTEGER(IntKi), PARAMETER :: B2N4Cm = 800 - INTEGER(IntKi), PARAMETER :: B2N5Cm = 801 - INTEGER(IntKi), PARAMETER :: B2N6Cm = 802 - INTEGER(IntKi), PARAMETER :: B2N7Cm = 803 - INTEGER(IntKi), PARAMETER :: B2N8Cm = 804 - INTEGER(IntKi), PARAMETER :: B2N9Cm = 805 - INTEGER(IntKi), PARAMETER :: B3N1Cm = 806 - INTEGER(IntKi), PARAMETER :: B3N2Cm = 807 - INTEGER(IntKi), PARAMETER :: B3N3Cm = 808 - INTEGER(IntKi), PARAMETER :: B3N4Cm = 809 - INTEGER(IntKi), PARAMETER :: B3N5Cm = 810 - INTEGER(IntKi), PARAMETER :: B3N6Cm = 811 - INTEGER(IntKi), PARAMETER :: B3N7Cm = 812 - INTEGER(IntKi), PARAMETER :: B3N8Cm = 813 - INTEGER(IntKi), PARAMETER :: B3N9Cm = 814 - INTEGER(IntKi), PARAMETER :: B1N1Cx = 815 - INTEGER(IntKi), PARAMETER :: B1N2Cx = 816 - INTEGER(IntKi), PARAMETER :: B1N3Cx = 817 - INTEGER(IntKi), PARAMETER :: B1N4Cx = 818 - INTEGER(IntKi), PARAMETER :: B1N5Cx = 819 - INTEGER(IntKi), PARAMETER :: B1N6Cx = 820 - INTEGER(IntKi), PARAMETER :: B1N7Cx = 821 - INTEGER(IntKi), PARAMETER :: B1N8Cx = 822 - INTEGER(IntKi), PARAMETER :: B1N9Cx = 823 - INTEGER(IntKi), PARAMETER :: B2N1Cx = 824 - INTEGER(IntKi), PARAMETER :: B2N2Cx = 825 - INTEGER(IntKi), PARAMETER :: B2N3Cx = 826 - INTEGER(IntKi), PARAMETER :: B2N4Cx = 827 - INTEGER(IntKi), PARAMETER :: B2N5Cx = 828 - INTEGER(IntKi), PARAMETER :: B2N6Cx = 829 - INTEGER(IntKi), PARAMETER :: B2N7Cx = 830 - INTEGER(IntKi), PARAMETER :: B2N8Cx = 831 - INTEGER(IntKi), PARAMETER :: B2N9Cx = 832 - INTEGER(IntKi), PARAMETER :: B3N1Cx = 833 - INTEGER(IntKi), PARAMETER :: B3N2Cx = 834 - INTEGER(IntKi), PARAMETER :: B3N3Cx = 835 - INTEGER(IntKi), PARAMETER :: B3N4Cx = 836 - INTEGER(IntKi), PARAMETER :: B3N5Cx = 837 - INTEGER(IntKi), PARAMETER :: B3N6Cx = 838 - INTEGER(IntKi), PARAMETER :: B3N7Cx = 839 - INTEGER(IntKi), PARAMETER :: B3N8Cx = 840 - INTEGER(IntKi), PARAMETER :: B3N9Cx = 841 - INTEGER(IntKi), PARAMETER :: B1N1Cy = 842 - INTEGER(IntKi), PARAMETER :: B1N2Cy = 843 - INTEGER(IntKi), PARAMETER :: B1N3Cy = 844 - INTEGER(IntKi), PARAMETER :: B1N4Cy = 845 - INTEGER(IntKi), PARAMETER :: B1N5Cy = 846 - INTEGER(IntKi), PARAMETER :: B1N6Cy = 847 - INTEGER(IntKi), PARAMETER :: B1N7Cy = 848 - INTEGER(IntKi), PARAMETER :: B1N8Cy = 849 - INTEGER(IntKi), PARAMETER :: B1N9Cy = 850 - INTEGER(IntKi), PARAMETER :: B2N1Cy = 851 - INTEGER(IntKi), PARAMETER :: B2N2Cy = 852 - INTEGER(IntKi), PARAMETER :: B2N3Cy = 853 - INTEGER(IntKi), PARAMETER :: B2N4Cy = 854 - INTEGER(IntKi), PARAMETER :: B2N5Cy = 855 - INTEGER(IntKi), PARAMETER :: B2N6Cy = 856 - INTEGER(IntKi), PARAMETER :: B2N7Cy = 857 - INTEGER(IntKi), PARAMETER :: B2N8Cy = 858 - INTEGER(IntKi), PARAMETER :: B2N9Cy = 859 - INTEGER(IntKi), PARAMETER :: B3N1Cy = 860 - INTEGER(IntKi), PARAMETER :: B3N2Cy = 861 - INTEGER(IntKi), PARAMETER :: B3N3Cy = 862 - INTEGER(IntKi), PARAMETER :: B3N4Cy = 863 - INTEGER(IntKi), PARAMETER :: B3N5Cy = 864 - INTEGER(IntKi), PARAMETER :: B3N6Cy = 865 - INTEGER(IntKi), PARAMETER :: B3N7Cy = 866 - INTEGER(IntKi), PARAMETER :: B3N8Cy = 867 - INTEGER(IntKi), PARAMETER :: B3N9Cy = 868 - INTEGER(IntKi), PARAMETER :: B1N1Cn = 869 - INTEGER(IntKi), PARAMETER :: B1N2Cn = 870 - INTEGER(IntKi), PARAMETER :: B1N3Cn = 871 - INTEGER(IntKi), PARAMETER :: B1N4Cn = 872 - INTEGER(IntKi), PARAMETER :: B1N5Cn = 873 - INTEGER(IntKi), PARAMETER :: B1N6Cn = 874 - INTEGER(IntKi), PARAMETER :: B1N7Cn = 875 - INTEGER(IntKi), PARAMETER :: B1N8Cn = 876 - INTEGER(IntKi), PARAMETER :: B1N9Cn = 877 - INTEGER(IntKi), PARAMETER :: B2N1Cn = 878 - INTEGER(IntKi), PARAMETER :: B2N2Cn = 879 - INTEGER(IntKi), PARAMETER :: B2N3Cn = 880 - INTEGER(IntKi), PARAMETER :: B2N4Cn = 881 - INTEGER(IntKi), PARAMETER :: B2N5Cn = 882 - INTEGER(IntKi), PARAMETER :: B2N6Cn = 883 - INTEGER(IntKi), PARAMETER :: B2N7Cn = 884 - INTEGER(IntKi), PARAMETER :: B2N8Cn = 885 - INTEGER(IntKi), PARAMETER :: B2N9Cn = 886 - INTEGER(IntKi), PARAMETER :: B3N1Cn = 887 - INTEGER(IntKi), PARAMETER :: B3N2Cn = 888 - INTEGER(IntKi), PARAMETER :: B3N3Cn = 889 - INTEGER(IntKi), PARAMETER :: B3N4Cn = 890 - INTEGER(IntKi), PARAMETER :: B3N5Cn = 891 - INTEGER(IntKi), PARAMETER :: B3N6Cn = 892 - INTEGER(IntKi), PARAMETER :: B3N7Cn = 893 - INTEGER(IntKi), PARAMETER :: B3N8Cn = 894 - INTEGER(IntKi), PARAMETER :: B3N9Cn = 895 - INTEGER(IntKi), PARAMETER :: B1N1Ct = 896 - INTEGER(IntKi), PARAMETER :: B1N2Ct = 897 - INTEGER(IntKi), PARAMETER :: B1N3Ct = 898 - INTEGER(IntKi), PARAMETER :: B1N4Ct = 899 - INTEGER(IntKi), PARAMETER :: B1N5Ct = 900 - INTEGER(IntKi), PARAMETER :: B1N6Ct = 901 - INTEGER(IntKi), PARAMETER :: B1N7Ct = 902 - INTEGER(IntKi), PARAMETER :: B1N8Ct = 903 - INTEGER(IntKi), PARAMETER :: B1N9Ct = 904 - INTEGER(IntKi), PARAMETER :: B2N1Ct = 905 - INTEGER(IntKi), PARAMETER :: B2N2Ct = 906 - INTEGER(IntKi), PARAMETER :: B2N3Ct = 907 - INTEGER(IntKi), PARAMETER :: B2N4Ct = 908 - INTEGER(IntKi), PARAMETER :: B2N5Ct = 909 - INTEGER(IntKi), PARAMETER :: B2N6Ct = 910 - INTEGER(IntKi), PARAMETER :: B2N7Ct = 911 - INTEGER(IntKi), PARAMETER :: B2N8Ct = 912 - INTEGER(IntKi), PARAMETER :: B2N9Ct = 913 - INTEGER(IntKi), PARAMETER :: B3N1Ct = 914 - INTEGER(IntKi), PARAMETER :: B3N2Ct = 915 - INTEGER(IntKi), PARAMETER :: B3N3Ct = 916 - INTEGER(IntKi), PARAMETER :: B3N4Ct = 917 - INTEGER(IntKi), PARAMETER :: B3N5Ct = 918 - INTEGER(IntKi), PARAMETER :: B3N6Ct = 919 - INTEGER(IntKi), PARAMETER :: B3N7Ct = 920 - INTEGER(IntKi), PARAMETER :: B3N8Ct = 921 - INTEGER(IntKi), PARAMETER :: B3N9Ct = 922 - INTEGER(IntKi), PARAMETER :: B1N1Fl = 923 - INTEGER(IntKi), PARAMETER :: B1N2Fl = 924 - INTEGER(IntKi), PARAMETER :: B1N3Fl = 925 - INTEGER(IntKi), PARAMETER :: B1N4Fl = 926 - INTEGER(IntKi), PARAMETER :: B1N5Fl = 927 - INTEGER(IntKi), PARAMETER :: B1N6Fl = 928 - INTEGER(IntKi), PARAMETER :: B1N7Fl = 929 - INTEGER(IntKi), PARAMETER :: B1N8Fl = 930 - INTEGER(IntKi), PARAMETER :: B1N9Fl = 931 - INTEGER(IntKi), PARAMETER :: B2N1Fl = 932 - INTEGER(IntKi), PARAMETER :: B2N2Fl = 933 - INTEGER(IntKi), PARAMETER :: B2N3Fl = 934 - INTEGER(IntKi), PARAMETER :: B2N4Fl = 935 - INTEGER(IntKi), PARAMETER :: B2N5Fl = 936 - INTEGER(IntKi), PARAMETER :: B2N6Fl = 937 - INTEGER(IntKi), PARAMETER :: B2N7Fl = 938 - INTEGER(IntKi), PARAMETER :: B2N8Fl = 939 - INTEGER(IntKi), PARAMETER :: B2N9Fl = 940 - INTEGER(IntKi), PARAMETER :: B3N1Fl = 941 - INTEGER(IntKi), PARAMETER :: B3N2Fl = 942 - INTEGER(IntKi), PARAMETER :: B3N3Fl = 943 - INTEGER(IntKi), PARAMETER :: B3N4Fl = 944 - INTEGER(IntKi), PARAMETER :: B3N5Fl = 945 - INTEGER(IntKi), PARAMETER :: B3N6Fl = 946 - INTEGER(IntKi), PARAMETER :: B3N7Fl = 947 - INTEGER(IntKi), PARAMETER :: B3N8Fl = 948 - INTEGER(IntKi), PARAMETER :: B3N9Fl = 949 - INTEGER(IntKi), PARAMETER :: B1N1Fd = 950 - INTEGER(IntKi), PARAMETER :: B1N2Fd = 951 - INTEGER(IntKi), PARAMETER :: B1N3Fd = 952 - INTEGER(IntKi), PARAMETER :: B1N4Fd = 953 - INTEGER(IntKi), PARAMETER :: B1N5Fd = 954 - INTEGER(IntKi), PARAMETER :: B1N6Fd = 955 - INTEGER(IntKi), PARAMETER :: B1N7Fd = 956 - INTEGER(IntKi), PARAMETER :: B1N8Fd = 957 - INTEGER(IntKi), PARAMETER :: B1N9Fd = 958 - INTEGER(IntKi), PARAMETER :: B2N1Fd = 959 - INTEGER(IntKi), PARAMETER :: B2N2Fd = 960 - INTEGER(IntKi), PARAMETER :: B2N3Fd = 961 - INTEGER(IntKi), PARAMETER :: B2N4Fd = 962 - INTEGER(IntKi), PARAMETER :: B2N5Fd = 963 - INTEGER(IntKi), PARAMETER :: B2N6Fd = 964 - INTEGER(IntKi), PARAMETER :: B2N7Fd = 965 - INTEGER(IntKi), PARAMETER :: B2N8Fd = 966 - INTEGER(IntKi), PARAMETER :: B2N9Fd = 967 - INTEGER(IntKi), PARAMETER :: B3N1Fd = 968 - INTEGER(IntKi), PARAMETER :: B3N2Fd = 969 - INTEGER(IntKi), PARAMETER :: B3N3Fd = 970 - INTEGER(IntKi), PARAMETER :: B3N4Fd = 971 - INTEGER(IntKi), PARAMETER :: B3N5Fd = 972 - INTEGER(IntKi), PARAMETER :: B3N6Fd = 973 - INTEGER(IntKi), PARAMETER :: B3N7Fd = 974 - INTEGER(IntKi), PARAMETER :: B3N8Fd = 975 - INTEGER(IntKi), PARAMETER :: B3N9Fd = 976 - INTEGER(IntKi), PARAMETER :: B1N1Mm = 977 - INTEGER(IntKi), PARAMETER :: B1N2Mm = 978 - INTEGER(IntKi), PARAMETER :: B1N3Mm = 979 - INTEGER(IntKi), PARAMETER :: B1N4Mm = 980 - INTEGER(IntKi), PARAMETER :: B1N5Mm = 981 - INTEGER(IntKi), PARAMETER :: B1N6Mm = 982 - INTEGER(IntKi), PARAMETER :: B1N7Mm = 983 - INTEGER(IntKi), PARAMETER :: B1N8Mm = 984 - INTEGER(IntKi), PARAMETER :: B1N9Mm = 985 - INTEGER(IntKi), PARAMETER :: B2N1Mm = 986 - INTEGER(IntKi), PARAMETER :: B2N2Mm = 987 - INTEGER(IntKi), PARAMETER :: B2N3Mm = 988 - INTEGER(IntKi), PARAMETER :: B2N4Mm = 989 - INTEGER(IntKi), PARAMETER :: B2N5Mm = 990 - INTEGER(IntKi), PARAMETER :: B2N6Mm = 991 - INTEGER(IntKi), PARAMETER :: B2N7Mm = 992 - INTEGER(IntKi), PARAMETER :: B2N8Mm = 993 - INTEGER(IntKi), PARAMETER :: B2N9Mm = 994 - INTEGER(IntKi), PARAMETER :: B3N1Mm = 995 - INTEGER(IntKi), PARAMETER :: B3N2Mm = 996 - INTEGER(IntKi), PARAMETER :: B3N3Mm = 997 - INTEGER(IntKi), PARAMETER :: B3N4Mm = 998 - INTEGER(IntKi), PARAMETER :: B3N5Mm = 999 - INTEGER(IntKi), PARAMETER :: B3N6Mm = 1000 - INTEGER(IntKi), PARAMETER :: B3N7Mm = 1001 - INTEGER(IntKi), PARAMETER :: B3N8Mm = 1002 - INTEGER(IntKi), PARAMETER :: B3N9Mm = 1003 - INTEGER(IntKi), PARAMETER :: B1N1Fx = 1004 - INTEGER(IntKi), PARAMETER :: B1N2Fx = 1005 - INTEGER(IntKi), PARAMETER :: B1N3Fx = 1006 - INTEGER(IntKi), PARAMETER :: B1N4Fx = 1007 - INTEGER(IntKi), PARAMETER :: B1N5Fx = 1008 - INTEGER(IntKi), PARAMETER :: B1N6Fx = 1009 - INTEGER(IntKi), PARAMETER :: B1N7Fx = 1010 - INTEGER(IntKi), PARAMETER :: B1N8Fx = 1011 - INTEGER(IntKi), PARAMETER :: B1N9Fx = 1012 - INTEGER(IntKi), PARAMETER :: B2N1Fx = 1013 - INTEGER(IntKi), PARAMETER :: B2N2Fx = 1014 - INTEGER(IntKi), PARAMETER :: B2N3Fx = 1015 - INTEGER(IntKi), PARAMETER :: B2N4Fx = 1016 - INTEGER(IntKi), PARAMETER :: B2N5Fx = 1017 - INTEGER(IntKi), PARAMETER :: B2N6Fx = 1018 - INTEGER(IntKi), PARAMETER :: B2N7Fx = 1019 - INTEGER(IntKi), PARAMETER :: B2N8Fx = 1020 - INTEGER(IntKi), PARAMETER :: B2N9Fx = 1021 - INTEGER(IntKi), PARAMETER :: B3N1Fx = 1022 - INTEGER(IntKi), PARAMETER :: B3N2Fx = 1023 - INTEGER(IntKi), PARAMETER :: B3N3Fx = 1024 - INTEGER(IntKi), PARAMETER :: B3N4Fx = 1025 - INTEGER(IntKi), PARAMETER :: B3N5Fx = 1026 - INTEGER(IntKi), PARAMETER :: B3N6Fx = 1027 - INTEGER(IntKi), PARAMETER :: B3N7Fx = 1028 - INTEGER(IntKi), PARAMETER :: B3N8Fx = 1029 - INTEGER(IntKi), PARAMETER :: B3N9Fx = 1030 - INTEGER(IntKi), PARAMETER :: B1N1Fy = 1031 - INTEGER(IntKi), PARAMETER :: B1N2Fy = 1032 - INTEGER(IntKi), PARAMETER :: B1N3Fy = 1033 - INTEGER(IntKi), PARAMETER :: B1N4Fy = 1034 - INTEGER(IntKi), PARAMETER :: B1N5Fy = 1035 - INTEGER(IntKi), PARAMETER :: B1N6Fy = 1036 - INTEGER(IntKi), PARAMETER :: B1N7Fy = 1037 - INTEGER(IntKi), PARAMETER :: B1N8Fy = 1038 - INTEGER(IntKi), PARAMETER :: B1N9Fy = 1039 - INTEGER(IntKi), PARAMETER :: B2N1Fy = 1040 - INTEGER(IntKi), PARAMETER :: B2N2Fy = 1041 - INTEGER(IntKi), PARAMETER :: B2N3Fy = 1042 - INTEGER(IntKi), PARAMETER :: B2N4Fy = 1043 - INTEGER(IntKi), PARAMETER :: B2N5Fy = 1044 - INTEGER(IntKi), PARAMETER :: B2N6Fy = 1045 - INTEGER(IntKi), PARAMETER :: B2N7Fy = 1046 - INTEGER(IntKi), PARAMETER :: B2N8Fy = 1047 - INTEGER(IntKi), PARAMETER :: B2N9Fy = 1048 - INTEGER(IntKi), PARAMETER :: B3N1Fy = 1049 - INTEGER(IntKi), PARAMETER :: B3N2Fy = 1050 - INTEGER(IntKi), PARAMETER :: B3N3Fy = 1051 - INTEGER(IntKi), PARAMETER :: B3N4Fy = 1052 - INTEGER(IntKi), PARAMETER :: B3N5Fy = 1053 - INTEGER(IntKi), PARAMETER :: B3N6Fy = 1054 - INTEGER(IntKi), PARAMETER :: B3N7Fy = 1055 - INTEGER(IntKi), PARAMETER :: B3N8Fy = 1056 - INTEGER(IntKi), PARAMETER :: B3N9Fy = 1057 - INTEGER(IntKi), PARAMETER :: B1N1Fn = 1058 - INTEGER(IntKi), PARAMETER :: B1N2Fn = 1059 - INTEGER(IntKi), PARAMETER :: B1N3Fn = 1060 - INTEGER(IntKi), PARAMETER :: B1N4Fn = 1061 - INTEGER(IntKi), PARAMETER :: B1N5Fn = 1062 - INTEGER(IntKi), PARAMETER :: B1N6Fn = 1063 - INTEGER(IntKi), PARAMETER :: B1N7Fn = 1064 - INTEGER(IntKi), PARAMETER :: B1N8Fn = 1065 - INTEGER(IntKi), PARAMETER :: B1N9Fn = 1066 - INTEGER(IntKi), PARAMETER :: B2N1Fn = 1067 - INTEGER(IntKi), PARAMETER :: B2N2Fn = 1068 - INTEGER(IntKi), PARAMETER :: B2N3Fn = 1069 - INTEGER(IntKi), PARAMETER :: B2N4Fn = 1070 - INTEGER(IntKi), PARAMETER :: B2N5Fn = 1071 - INTEGER(IntKi), PARAMETER :: B2N6Fn = 1072 - INTEGER(IntKi), PARAMETER :: B2N7Fn = 1073 - INTEGER(IntKi), PARAMETER :: B2N8Fn = 1074 - INTEGER(IntKi), PARAMETER :: B2N9Fn = 1075 - INTEGER(IntKi), PARAMETER :: B3N1Fn = 1076 - INTEGER(IntKi), PARAMETER :: B3N2Fn = 1077 - INTEGER(IntKi), PARAMETER :: B3N3Fn = 1078 - INTEGER(IntKi), PARAMETER :: B3N4Fn = 1079 - INTEGER(IntKi), PARAMETER :: B3N5Fn = 1080 - INTEGER(IntKi), PARAMETER :: B3N6Fn = 1081 - INTEGER(IntKi), PARAMETER :: B3N7Fn = 1082 - INTEGER(IntKi), PARAMETER :: B3N8Fn = 1083 - INTEGER(IntKi), PARAMETER :: B3N9Fn = 1084 - INTEGER(IntKi), PARAMETER :: B1N1Ft = 1085 - INTEGER(IntKi), PARAMETER :: B1N2Ft = 1086 - INTEGER(IntKi), PARAMETER :: B1N3Ft = 1087 - INTEGER(IntKi), PARAMETER :: B1N4Ft = 1088 - INTEGER(IntKi), PARAMETER :: B1N5Ft = 1089 - INTEGER(IntKi), PARAMETER :: B1N6Ft = 1090 - INTEGER(IntKi), PARAMETER :: B1N7Ft = 1091 - INTEGER(IntKi), PARAMETER :: B1N8Ft = 1092 - INTEGER(IntKi), PARAMETER :: B1N9Ft = 1093 - INTEGER(IntKi), PARAMETER :: B2N1Ft = 1094 - INTEGER(IntKi), PARAMETER :: B2N2Ft = 1095 - INTEGER(IntKi), PARAMETER :: B2N3Ft = 1096 - INTEGER(IntKi), PARAMETER :: B2N4Ft = 1097 - INTEGER(IntKi), PARAMETER :: B2N5Ft = 1098 - INTEGER(IntKi), PARAMETER :: B2N6Ft = 1099 - INTEGER(IntKi), PARAMETER :: B2N7Ft = 1100 - INTEGER(IntKi), PARAMETER :: B2N8Ft = 1101 - INTEGER(IntKi), PARAMETER :: B2N9Ft = 1102 - INTEGER(IntKi), PARAMETER :: B3N1Ft = 1103 - INTEGER(IntKi), PARAMETER :: B3N2Ft = 1104 - INTEGER(IntKi), PARAMETER :: B3N3Ft = 1105 - INTEGER(IntKi), PARAMETER :: B3N4Ft = 1106 - INTEGER(IntKi), PARAMETER :: B3N5Ft = 1107 - INTEGER(IntKi), PARAMETER :: B3N6Ft = 1108 - INTEGER(IntKi), PARAMETER :: B3N7Ft = 1109 - INTEGER(IntKi), PARAMETER :: B3N8Ft = 1110 - INTEGER(IntKi), PARAMETER :: B3N9Ft = 1111 - INTEGER(IntKi), PARAMETER :: B1N1Clrnc = 1112 - INTEGER(IntKi), PARAMETER :: B1N2Clrnc = 1113 - INTEGER(IntKi), PARAMETER :: B1N3Clrnc = 1114 - INTEGER(IntKi), PARAMETER :: B1N4Clrnc = 1115 - INTEGER(IntKi), PARAMETER :: B1N5Clrnc = 1116 - INTEGER(IntKi), PARAMETER :: B1N6Clrnc = 1117 - INTEGER(IntKi), PARAMETER :: B1N7Clrnc = 1118 - INTEGER(IntKi), PARAMETER :: B1N8Clrnc = 1119 - INTEGER(IntKi), PARAMETER :: B1N9Clrnc = 1120 - INTEGER(IntKi), PARAMETER :: B2N1Clrnc = 1121 - INTEGER(IntKi), PARAMETER :: B2N2Clrnc = 1122 - INTEGER(IntKi), PARAMETER :: B2N3Clrnc = 1123 - INTEGER(IntKi), PARAMETER :: B2N4Clrnc = 1124 - INTEGER(IntKi), PARAMETER :: B2N5Clrnc = 1125 - INTEGER(IntKi), PARAMETER :: B2N6Clrnc = 1126 - INTEGER(IntKi), PARAMETER :: B2N7Clrnc = 1127 - INTEGER(IntKi), PARAMETER :: B2N8Clrnc = 1128 - INTEGER(IntKi), PARAMETER :: B2N9Clrnc = 1129 - INTEGER(IntKi), PARAMETER :: B3N1Clrnc = 1130 - INTEGER(IntKi), PARAMETER :: B3N2Clrnc = 1131 - INTEGER(IntKi), PARAMETER :: B3N3Clrnc = 1132 - INTEGER(IntKi), PARAMETER :: B3N4Clrnc = 1133 - INTEGER(IntKi), PARAMETER :: B3N5Clrnc = 1134 - INTEGER(IntKi), PARAMETER :: B3N6Clrnc = 1135 - INTEGER(IntKi), PARAMETER :: B3N7Clrnc = 1136 - INTEGER(IntKi), PARAMETER :: B3N8Clrnc = 1137 - INTEGER(IntKi), PARAMETER :: B3N9Clrnc = 1138 - INTEGER(IntKi), PARAMETER :: B1N1Cpmin = 1139 - INTEGER(IntKi), PARAMETER :: B1N2Cpmin = 1140 - INTEGER(IntKi), PARAMETER :: B1N3Cpmin = 1141 - INTEGER(IntKi), PARAMETER :: B1N4Cpmin = 1142 - INTEGER(IntKi), PARAMETER :: B1N5Cpmin = 1143 - INTEGER(IntKi), PARAMETER :: B1N6Cpmin = 1144 - INTEGER(IntKi), PARAMETER :: B1N7Cpmin = 1145 - INTEGER(IntKi), PARAMETER :: B1N8Cpmin = 1146 - INTEGER(IntKi), PARAMETER :: B1N9Cpmin = 1147 - INTEGER(IntKi), PARAMETER :: B2N1Cpmin = 1148 - INTEGER(IntKi), PARAMETER :: B2N2Cpmin = 1149 - INTEGER(IntKi), PARAMETER :: B2N3Cpmin = 1150 - INTEGER(IntKi), PARAMETER :: B2N4Cpmin = 1151 - INTEGER(IntKi), PARAMETER :: B2N5Cpmin = 1152 - INTEGER(IntKi), PARAMETER :: B2N6Cpmin = 1153 - INTEGER(IntKi), PARAMETER :: B2N7Cpmin = 1154 - INTEGER(IntKi), PARAMETER :: B2N8Cpmin = 1155 - INTEGER(IntKi), PARAMETER :: B2N9Cpmin = 1156 - INTEGER(IntKi), PARAMETER :: B3N1Cpmin = 1157 - INTEGER(IntKi), PARAMETER :: B3N2Cpmin = 1158 - INTEGER(IntKi), PARAMETER :: B3N3Cpmin = 1159 - INTEGER(IntKi), PARAMETER :: B3N4Cpmin = 1160 - INTEGER(IntKi), PARAMETER :: B3N5Cpmin = 1161 - INTEGER(IntKi), PARAMETER :: B3N6Cpmin = 1162 - INTEGER(IntKi), PARAMETER :: B3N7Cpmin = 1163 - INTEGER(IntKi), PARAMETER :: B3N8Cpmin = 1164 - INTEGER(IntKi), PARAMETER :: B3N9Cpmin = 1165 - INTEGER(IntKi), PARAMETER :: B1N1SigCr = 1166 - INTEGER(IntKi), PARAMETER :: B1N2SigCr = 1167 - INTEGER(IntKi), PARAMETER :: B1N3SigCr = 1168 - INTEGER(IntKi), PARAMETER :: B1N4SigCr = 1169 - INTEGER(IntKi), PARAMETER :: B1N5SigCr = 1170 - INTEGER(IntKi), PARAMETER :: B1N6SigCr = 1171 - INTEGER(IntKi), PARAMETER :: B1N7SigCr = 1172 - INTEGER(IntKi), PARAMETER :: B1N8SigCr = 1173 - INTEGER(IntKi), PARAMETER :: B1N9SigCr = 1174 - INTEGER(IntKi), PARAMETER :: B2N1SigCr = 1175 - INTEGER(IntKi), PARAMETER :: B2N2SigCr = 1176 - INTEGER(IntKi), PARAMETER :: B2N3SigCr = 1177 - INTEGER(IntKi), PARAMETER :: B2N4SigCr = 1178 - INTEGER(IntKi), PARAMETER :: B2N5SigCr = 1179 - INTEGER(IntKi), PARAMETER :: B2N6SigCr = 1180 - INTEGER(IntKi), PARAMETER :: B2N7SigCr = 1181 - INTEGER(IntKi), PARAMETER :: B2N8SigCr = 1182 - INTEGER(IntKi), PARAMETER :: B2N9SigCr = 1183 - INTEGER(IntKi), PARAMETER :: B3N1SigCr = 1184 - INTEGER(IntKi), PARAMETER :: B3N2SigCr = 1185 - INTEGER(IntKi), PARAMETER :: B3N3SigCr = 1186 - INTEGER(IntKi), PARAMETER :: B3N4SigCr = 1187 - INTEGER(IntKi), PARAMETER :: B3N5SigCr = 1188 - INTEGER(IntKi), PARAMETER :: B3N6SigCr = 1189 - INTEGER(IntKi), PARAMETER :: B3N7SigCr = 1190 - INTEGER(IntKi), PARAMETER :: B3N8SigCr = 1191 - INTEGER(IntKi), PARAMETER :: B3N9SigCr = 1192 - INTEGER(IntKi), PARAMETER :: B1N1SgCav = 1193 - INTEGER(IntKi), PARAMETER :: B1N2SgCav = 1194 - INTEGER(IntKi), PARAMETER :: B1N3SgCav = 1195 - INTEGER(IntKi), PARAMETER :: B1N4SgCav = 1196 - INTEGER(IntKi), PARAMETER :: B1N5SgCav = 1197 - INTEGER(IntKi), PARAMETER :: B1N6SgCav = 1198 - INTEGER(IntKi), PARAMETER :: B1N7SgCav = 1199 - INTEGER(IntKi), PARAMETER :: B1N8SgCav = 1200 - INTEGER(IntKi), PARAMETER :: B1N9SgCav = 1201 - INTEGER(IntKi), PARAMETER :: B2N1SgCav = 1202 - INTEGER(IntKi), PARAMETER :: B2N2SgCav = 1203 - INTEGER(IntKi), PARAMETER :: B2N3SgCav = 1204 - INTEGER(IntKi), PARAMETER :: B2N4SgCav = 1205 - INTEGER(IntKi), PARAMETER :: B2N5SgCav = 1206 - INTEGER(IntKi), PARAMETER :: B2N6SgCav = 1207 - INTEGER(IntKi), PARAMETER :: B2N7SgCav = 1208 - INTEGER(IntKi), PARAMETER :: B2N8SgCav = 1209 - INTEGER(IntKi), PARAMETER :: B2N9SgCav = 1210 - INTEGER(IntKi), PARAMETER :: B3N1SgCav = 1211 - INTEGER(IntKi), PARAMETER :: B3N2SgCav = 1212 - INTEGER(IntKi), PARAMETER :: B3N3SgCav = 1213 - INTEGER(IntKi), PARAMETER :: B3N4SgCav = 1214 - INTEGER(IntKi), PARAMETER :: B3N5SgCav = 1215 - INTEGER(IntKi), PARAMETER :: B3N6SgCav = 1216 - INTEGER(IntKi), PARAMETER :: B3N7SgCav = 1217 - INTEGER(IntKi), PARAMETER :: B3N8SgCav = 1218 - INTEGER(IntKi), PARAMETER :: B3N9SgCav = 1219 - INTEGER(IntKi), PARAMETER :: B1N1Gam = 1220 - INTEGER(IntKi), PARAMETER :: B1N2Gam = 1221 - INTEGER(IntKi), PARAMETER :: B1N3Gam = 1222 - INTEGER(IntKi), PARAMETER :: B1N4Gam = 1223 - INTEGER(IntKi), PARAMETER :: B1N5Gam = 1224 - INTEGER(IntKi), PARAMETER :: B1N6Gam = 1225 - INTEGER(IntKi), PARAMETER :: B1N7Gam = 1226 - INTEGER(IntKi), PARAMETER :: B1N8Gam = 1227 - INTEGER(IntKi), PARAMETER :: B1N9Gam = 1228 - INTEGER(IntKi), PARAMETER :: B2N1Gam = 1229 - INTEGER(IntKi), PARAMETER :: B2N2Gam = 1230 - INTEGER(IntKi), PARAMETER :: B2N3Gam = 1231 - INTEGER(IntKi), PARAMETER :: B2N4Gam = 1232 - INTEGER(IntKi), PARAMETER :: B2N5Gam = 1233 - INTEGER(IntKi), PARAMETER :: B2N6Gam = 1234 - INTEGER(IntKi), PARAMETER :: B2N7Gam = 1235 - INTEGER(IntKi), PARAMETER :: B2N8Gam = 1236 - INTEGER(IntKi), PARAMETER :: B2N9Gam = 1237 - INTEGER(IntKi), PARAMETER :: B3N1Gam = 1238 - INTEGER(IntKi), PARAMETER :: B3N2Gam = 1239 - INTEGER(IntKi), PARAMETER :: B3N3Gam = 1240 - INTEGER(IntKi), PARAMETER :: B3N4Gam = 1241 - INTEGER(IntKi), PARAMETER :: B3N5Gam = 1242 - INTEGER(IntKi), PARAMETER :: B3N6Gam = 1243 - INTEGER(IntKi), PARAMETER :: B3N7Gam = 1244 - INTEGER(IntKi), PARAMETER :: B3N8Gam = 1245 - INTEGER(IntKi), PARAMETER :: B3N9Gam = 1246 - - - ! Rotor: - - INTEGER(IntKi), PARAMETER :: RtSpeed = 1247 - INTEGER(IntKi), PARAMETER :: RtTSR = 1248 - INTEGER(IntKi), PARAMETER :: RtVAvgxh = 1249 - INTEGER(IntKi), PARAMETER :: RtVAvgyh = 1250 - INTEGER(IntKi), PARAMETER :: RtVAvgzh = 1251 - INTEGER(IntKi), PARAMETER :: RtSkew = 1252 - INTEGER(IntKi), PARAMETER :: RtAeroFxh = 1253 - INTEGER(IntKi), PARAMETER :: RtAeroFyh = 1254 - INTEGER(IntKi), PARAMETER :: RtAeroFzh = 1255 - INTEGER(IntKi), PARAMETER :: RtAeroMxh = 1256 - INTEGER(IntKi), PARAMETER :: RtAeroMyh = 1257 - INTEGER(IntKi), PARAMETER :: RtAeroMzh = 1258 - INTEGER(IntKi), PARAMETER :: RtAeroPwr = 1259 - INTEGER(IntKi), PARAMETER :: RtArea = 1260 - INTEGER(IntKi), PARAMETER :: RtAeroCp = 1261 - INTEGER(IntKi), PARAMETER :: RtAeroCq = 1262 - INTEGER(IntKi), PARAMETER :: RtAeroCt = 1263 - INTEGER(IntKi), PARAMETER :: DBEMTau1 = 1264 - INTEGER(IntKi), PARAMETER :: RtAeroFxg = 1265 - INTEGER(IntKi), PARAMETER :: RtAeroFyg = 1266 - INTEGER(IntKi), PARAMETER :: RtAeroFzg = 1267 - INTEGER(IntKi), PARAMETER :: RtAeroMxg = 1268 - INTEGER(IntKi), PARAMETER :: RtAeroMyg = 1269 - INTEGER(IntKi), PARAMETER :: RtAeroMzg = 1270 - - - ! The maximum number of output channels which can be output by the code. - INTEGER(IntKi), PARAMETER :: MaxOutPts = 1270 - -!End of code generated by Matlab script -! =================================================================================================== - - INTEGER, PARAMETER :: TwNVUnd(3, 9) = RESHAPE( (/ & ! Undisturbed wind velocity - TwN1VUndx,TwN1VUndy,TwN1VUndz, & - TwN2VUndx,TwN2VUndy,TwN2VUndz, & - TwN3VUndx,TwN3VUndy,TwN3VUndz, & - TwN4VUndx,TwN4VUndy,TwN4VUndz, & - TwN5VUndx,TwN5VUndy,TwN5VUndz, & - TwN6VUndx,TwN6VUndy,TwN6VUndz, & - TwN7VUndx,TwN7VUndy,TwN7VUndz, & - TwN8VUndx,TwN8VUndy,TwN8VUndz, & - TwN9VUndx,TwN9VUndy,TwN9VUndz & - /), (/3, 9/) ) - INTEGER, PARAMETER :: TwNSTV(3, 9) = RESHAPE( (/ & ! Structural translational velocity - TwN1STVx,TwN1STVy,TwN1STVz, & - TwN2STVx,TwN2STVy,TwN2STVz, & - TwN3STVx,TwN3STVy,TwN3STVz, & - TwN4STVx,TwN4STVy,TwN4STVz, & - TwN5STVx,TwN5STVy,TwN5STVz, & - TwN6STVx,TwN6STVy,TwN6STVz, & - TwN7STVx,TwN7STVy,TwN7STVz, & - TwN8STVx,TwN8STVy,TwN8STVz, & - TwN9STVx,TwN9STVy,TwN9STVz & - /), (/3, 9/) ) - INTEGER, PARAMETER :: TwNVRel(9) = (/TwN1VRel,TwN2VRel,TwN3VRel,TwN4VRel,TwN5VRel,TwN6VRel,TwN7VRel,TwN8VRel,TwN9VRel/) ! relative wind speed - INTEGER, PARAMETER :: TwNDynP(9) = (/TwN1DynP,TwN2DynP,TwN3DynP,TwN4DynP,TwN5DynP,TwN6DynP,TwN7DynP,TwN8DynP,TwN9DynP/) ! dynamic pressure - INTEGER, PARAMETER :: TwNRe(9) = (/TwN1Re,TwN2Re,TwN3Re,TwN4Re,TwN5Re,TwN6Re,TwN7Re,TwN8Re,TwN9Re/) ! Reynolds number - INTEGER, PARAMETER :: TwNM(9) = (/TwN1M,TwN2M,TwN3M,TwN4M,TwN5M,TwN6M,TwN7M,TwN8M,TwN9M/) ! Mach number - INTEGER, PARAMETER :: TwNFdx(9) = (/TwN1Fdx,TwN2Fdx,TwN3Fdx,TwN4Fdx,TwN5Fdx,TwN6Fdx,TwN7Fdx,TwN8Fdx,TwN9Fdx/) ! x-component drag force per unit length - INTEGER, PARAMETER :: TwNFdy(9) = (/TwN1Fdy,TwN2Fdy,TwN3Fdy,TwN4Fdy,TwN5Fdy,TwN6Fdy,TwN7Fdy,TwN8Fdy,TwN9Fdy/) ! y-component drag force per unit length - INTEGER, PARAMETER :: BAzimuth(3) = (/B1Azimuth,B2Azimuth,B3Azimuth/) ! azimuth angle - INTEGER, PARAMETER :: BPitch(3) = (/B1Pitch, B2Pitch, B3Pitch/) ! pitch - - INTEGER, PARAMETER :: BAeroFx(4) = (/B1AeroFx, B2AeroFx, B3AeroFx, B4AeroFx/) ! x-component of total blade root aero force - INTEGER, PARAMETER :: BAeroFy(4) = (/B1AeroFy, B2AeroFy, B3AeroFy, B4AeroFy/) ! y-component of total blade root aero force - INTEGER, PARAMETER :: BAeroFz(4) = (/B1AeroFz, B2AeroFz, B3AeroFz, B4AeroFz/) ! z-component of total blade root aero force - INTEGER, PARAMETER :: BAeroMx(4) = (/B1AeroMx, B2AeroMx, B3AeroMx, B4AeroMx/) ! x-component of total blade root aero moment - INTEGER, PARAMETER :: BAeroMy(4) = (/B1AeroMy, B2AeroMy, B3AeroMy, B4AeroMy/) ! y-component of total blade root aero moment - INTEGER, PARAMETER :: BAeroMz(4) = (/B1AeroMz, B2AeroMz, B3AeroMz, B4AeroMz/) ! z-component of total blade root aero moment - INTEGER, PARAMETER :: BAeroPwr(4) = (/B1AeroPwr, B2AeroPwr, B3AeroPwr, B4AeroPwr/) ! Blade contribution to power - INTEGER, PARAMETER :: BAeroFxg(4) = (/B1AeroFxg, B2AeroFxg, B3AeroFxg, B4AeroFxg/) ! x-component of total blade root aero force in global - INTEGER, PARAMETER :: BAeroFyg(4) = (/B1AeroFyg, B2AeroFyg, B3AeroFyg, B4AeroFyg/) ! y-component of total blade root aero force in global - INTEGER, PARAMETER :: BAeroFzg(4) = (/B1AeroFzg, B2AeroFzg, B3AeroFzg, B4AeroFzg/) ! z-component of total blade root aero force in global - INTEGER, PARAMETER :: BAeroMxg(4) = (/B1AeroMxg, B2AeroMxg, B3AeroMxg, B4AeroMxg/) ! x-component of total blade root aero moment wrt hub in global - INTEGER, PARAMETER :: BAeroMyg(4) = (/B1AeroMyg, B2AeroMyg, B3AeroMyg, B4AeroMyg/) ! y-component of total blade root aero moment wrt hub in global - INTEGER, PARAMETER :: BAeroMzg(4) = (/B1AeroMzg, B2AeroMzg, B3AeroMzg, B4AeroMzg/) ! z-component of total blade root aero moment wrt hub in global - - INTEGER, PARAMETER :: BNVUndx(9, 3) = RESHAPE( (/ & ! undisturbed wind velocity (x component) - B1N1VUndx,B1N2VUndx,B1N3VUndx,B1N4VUndx,B1N5VUndx,B1N6VUndx,B1N7VUndx,B1N8VUndx,B1N9VUndx, & - B2N1VUndx,B2N2VUndx,B2N3VUndx,B2N4VUndx,B2N5VUndx,B2N6VUndx,B2N7VUndx,B2N8VUndx,B2N9VUndx, & - B3N1VUndx,B3N2VUndx,B3N3VUndx,B3N4VUndx,B3N5VUndx,B3N6VUndx,B3N7VUndx,B3N8VUndx,B3N9VUndx & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNVUndy(9, 3) = RESHAPE( (/ & ! undisturbed wind velocity (y component) - B1N1VUndy,B1N2VUndy,B1N3VUndy,B1N4VUndy,B1N5VUndy,B1N6VUndy,B1N7VUndy,B1N8VUndy,B1N9VUndy, & - B2N1VUndy,B2N2VUndy,B2N3VUndy,B2N4VUndy,B2N5VUndy,B2N6VUndy,B2N7VUndy,B2N8VUndy,B2N9VUndy, & - B3N1VUndy,B3N2VUndy,B3N3VUndy,B3N4VUndy,B3N5VUndy,B3N6VUndy,B3N7VUndy,B3N8VUndy,B3N9VUndy & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNVUndz(9, 3) = RESHAPE( (/ & ! undisturbed wind velocity (z component) - B1N1VUndz,B1N2VUndz,B1N3VUndz,B1N4VUndz,B1N5VUndz,B1N6VUndz,B1N7VUndz,B1N8VUndz,B1N9VUndz, & - B2N1VUndz,B2N2VUndz,B2N3VUndz,B2N4VUndz,B2N5VUndz,B2N6VUndz,B2N7VUndz,B2N8VUndz,B2N9VUndz, & - B3N1VUndz,B3N2VUndz,B3N3VUndz,B3N4VUndz,B3N5VUndz,B3N6VUndz,B3N7VUndz,B3N8VUndz,B3N9VUndz & - /), (/9, 3/) ) - - INTEGER, PARAMETER :: BNVDisx(9, 3) = RESHAPE( (/ & ! disturbed wind velocity (x component) - B1N1VDisx,B1N2VDisx,B1N3VDisx,B1N4VDisx,B1N5VDisx,B1N6VDisx,B1N7VDisx,B1N8VDisx,B1N9VDisx, & - B2N1VDisx,B2N2VDisx,B2N3VDisx,B2N4VDisx,B2N5VDisx,B2N6VDisx,B2N7VDisx,B2N8VDisx,B2N9VDisx, & - B3N1VDisx,B3N2VDisx,B3N3VDisx,B3N4VDisx,B3N5VDisx,B3N6VDisx,B3N7VDisx,B3N8VDisx,B3N9VDisx & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNVDisy(9, 3) = RESHAPE( (/ & ! disturbed wind velocity (y component) - B1N1VDisy,B1N2VDisy,B1N3VDisy,B1N4VDisy,B1N5VDisy,B1N6VDisy,B1N7VDisy,B1N8VDisy,B1N9VDisy, & - B2N1VDisy,B2N2VDisy,B2N3VDisy,B2N4VDisy,B2N5VDisy,B2N6VDisy,B2N7VDisy,B2N8VDisy,B2N9VDisy, & - B3N1VDisy,B3N2VDisy,B3N3VDisy,B3N4VDisy,B3N5VDisy,B3N6VDisy,B3N7VDisy,B3N8VDisy,B3N9VDisy & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNVDisz(9, 3) = RESHAPE( (/ & ! disturbed wind velocity (z component) - B1N1VDisz,B1N2VDisz,B1N3VDisz,B1N4VDisz,B1N5VDisz,B1N6VDisz,B1N7VDisz,B1N8VDisz,B1N9VDisz, & - B2N1VDisz,B2N2VDisz,B2N3VDisz,B2N4VDisz,B2N5VDisz,B2N6VDisz,B2N7VDisz,B2N8VDisz,B2N9VDisz, & - B3N1VDisz,B3N2VDisz,B3N3VDisz,B3N4VDisz,B3N5VDisz,B3N6VDisz,B3N7VDisz,B3N8VDisz,B3N9VDisz & - /), (/9, 3/) ) - - INTEGER, PARAMETER :: BNSTVx(9, 3) = RESHAPE( (/ & ! structural translational velocity (x component) - B1N1STVx,B1N2STVx,B1N3STVx,B1N4STVx,B1N5STVx,B1N6STVx,B1N7STVx,B1N8STVx,B1N9STVx, & - B2N1STVx,B2N2STVx,B2N3STVx,B2N4STVx,B2N5STVx,B2N6STVx,B2N7STVx,B2N8STVx,B2N9STVx, & - B3N1STVx,B3N2STVx,B3N3STVx,B3N4STVx,B3N5STVx,B3N6STVx,B3N7STVx,B3N8STVx,B3N9STVx & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNSTVy(9, 3) = RESHAPE( (/ & ! structural translational velocity (y component) - B1N1STVy,B1N2STVy,B1N3STVy,B1N4STVy,B1N5STVy,B1N6STVy,B1N7STVy,B1N8STVy,B1N9STVy, & - B2N1STVy,B2N2STVy,B2N3STVy,B2N4STVy,B2N5STVy,B2N6STVy,B2N7STVy,B2N8STVy,B2N9STVy, & - B3N1STVy,B3N2STVy,B3N3STVy,B3N4STVy,B3N5STVy,B3N6STVy,B3N7STVy,B3N8STVy,B3N9STVy & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNSTVz(9, 3) = RESHAPE( (/ & ! structural translational velocity (z component) - B1N1STVz,B1N2STVz,B1N3STVz,B1N4STVz,B1N5STVz,B1N6STVz,B1N7STVz,B1N8STVz,B1N9STVz, & - B2N1STVz,B2N2STVz,B2N3STVz,B2N4STVz,B2N5STVz,B2N6STVz,B2N7STVz,B2N8STVz,B2N9STVz, & - B3N1STVz,B3N2STVz,B3N3STVz,B3N4STVz,B3N5STVz,B3N6STVz,B3N7STVz,B3N8STVz,B3N9STVz & - /), (/9, 3/) ) - - INTEGER, PARAMETER :: BNVRel(9, 3) = RESHAPE( (/ & ! relative wind speed - B1N1VRel,B1N2VRel,B1N3VRel,B1N4VRel,B1N5VRel,B1N6VRel,B1N7VRel,B1N8VRel,B1N9VRel, & - B2N1VRel,B2N2VRel,B2N3VRel,B2N4VRel,B2N5VRel,B2N6VRel,B2N7VRel,B2N8VRel,B2N9VRel, & - B3N1VRel,B3N2VRel,B3N3VRel,B3N4VRel,B3N5VRel,B3N6VRel,B3N7VRel,B3N8VRel,B3N9VRel & - /), (/9, 3/) ) - - INTEGER, PARAMETER :: BNDynP(9, 3) = RESHAPE( (/ & ! dynamic pressure - B1N1DynP,B1N2DynP,B1N3DynP,B1N4DynP,B1N5DynP,B1N6DynP,B1N7DynP,B1N8DynP,B1N9DynP, & - B2N1DynP,B2N2DynP,B2N3DynP,B2N4DynP,B2N5DynP,B2N6DynP,B2N7DynP,B2N8DynP,B2N9DynP, & - B3N1DynP,B3N2DynP,B3N3DynP,B3N4DynP,B3N5DynP,B3N6DynP,B3N7DynP,B3N8DynP,B3N9DynP & - /), (/9, 3/) ) - - INTEGER, PARAMETER :: BNRe(9, 3) = RESHAPE( (/ & ! Reynolds number - B1N1Re,B1N2Re,B1N3Re,B1N4Re,B1N5Re,B1N6Re,B1N7Re,B1N8Re,B1N9Re, & - B2N1Re,B2N2Re,B2N3Re,B2N4Re,B2N5Re,B2N6Re,B2N7Re,B2N8Re,B2N9Re, & - B3N1Re,B3N2Re,B3N3Re,B3N4Re,B3N5Re,B3N6Re,B3N7Re,B3N8Re,B3N9Re & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNM(9, 3) = RESHAPE( (/ & ! Mach number - B1N1M,B1N2M,B1N3M,B1N4M,B1N5M,B1N6M,B1N7M,B1N8M,B1N9M, & - B2N1M,B2N2M,B2N3M,B2N4M,B2N5M,B2N6M,B2N7M,B2N8M,B2N9M, & - B3N1M,B3N2M,B3N3M,B3N4M,B3N5M,B3N6M,B3N7M,B3N8M,B3N9M & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNVIndx(9, 3) = RESHAPE( (/ & ! axial induced wind velocity - B1N1VIndx,B1N2VIndx,B1N3VIndx,B1N4VIndx,B1N5VIndx,B1N6VIndx,B1N7VIndx,B1N8VIndx,B1N9VIndx, & - B2N1VIndx,B2N2VIndx,B2N3VIndx,B2N4VIndx,B2N5VIndx,B2N6VIndx,B2N7VIndx,B2N8VIndx,B2N9VIndx, & - B3N1VIndx,B3N2VIndx,B3N3VIndx,B3N4VIndx,B3N5VIndx,B3N6VIndx,B3N7VIndx,B3N8VIndx,B3N9VIndx & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNVIndy(9, 3) = RESHAPE( (/ & ! tangential induced wind velocity - B1N1VIndy,B1N2VIndy,B1N3VIndy,B1N4VIndy,B1N5VIndy,B1N6VIndy,B1N7VIndy,B1N8VIndy,B1N9VIndy, & - B2N1VIndy,B2N2VIndy,B2N3VIndy,B2N4VIndy,B2N5VIndy,B2N6VIndy,B2N7VIndy,B2N8VIndy,B2N9VIndy, & - B3N1VIndy,B3N2VIndy,B3N3VIndy,B3N4VIndy,B3N5VIndy,B3N6VIndy,B3N7VIndy,B3N8VIndy,B3N9VIndy & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNAxInd(9, 3) = RESHAPE( (/ & ! axial induction factor - B1N1AxInd,B1N2AxInd,B1N3AxInd,B1N4AxInd,B1N5AxInd,B1N6AxInd,B1N7AxInd,B1N8AxInd,B1N9AxInd, & - B2N1AxInd,B2N2AxInd,B2N3AxInd,B2N4AxInd,B2N5AxInd,B2N6AxInd,B2N7AxInd,B2N8AxInd,B2N9AxInd, & - B3N1AxInd,B3N2AxInd,B3N3AxInd,B3N4AxInd,B3N5AxInd,B3N6AxInd,B3N7AxInd,B3N8AxInd,B3N9AxInd & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNTnInd(9, 3) = RESHAPE( (/ & ! tangential induction factor - B1N1TnInd,B1N2TnInd,B1N3TnInd,B1N4TnInd,B1N5TnInd,B1N6TnInd,B1N7TnInd,B1N8TnInd,B1N9TnInd, & - B2N1TnInd,B2N2TnInd,B2N3TnInd,B2N4TnInd,B2N5TnInd,B2N6TnInd,B2N7TnInd,B2N8TnInd,B2N9TnInd, & - B3N1TnInd,B3N2TnInd,B3N3TnInd,B3N4TnInd,B3N5TnInd,B3N6TnInd,B3N7TnInd,B3N8TnInd,B3N9TnInd & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNAlpha(9, 3) = RESHAPE( (/ & ! angle of attach - B1N1Alpha,B1N2Alpha,B1N3Alpha,B1N4Alpha,B1N5Alpha,B1N6Alpha,B1N7Alpha,B1N8Alpha,B1N9Alpha, & - B2N1Alpha,B2N2Alpha,B2N3Alpha,B2N4Alpha,B2N5Alpha,B2N6Alpha,B2N7Alpha,B2N8Alpha,B2N9Alpha, & - B3N1Alpha,B3N2Alpha,B3N3Alpha,B3N4Alpha,B3N5Alpha,B3N6Alpha,B3N7Alpha,B3N8Alpha,B3N9Alpha & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNTheta(9, 3) = RESHAPE( (/ & ! pitch+twist angle - B1N1Theta,B1N2Theta,B1N3Theta,B1N4Theta,B1N5Theta,B1N6Theta,B1N7Theta,B1N8Theta,B1N9Theta, & - B2N1Theta,B2N2Theta,B2N3Theta,B2N4Theta,B2N5Theta,B2N6Theta,B2N7Theta,B2N8Theta,B2N9Theta, & - B3N1Theta,B3N2Theta,B3N3Theta,B3N4Theta,B3N5Theta,B3N6Theta,B3N7Theta,B3N8Theta,B3N9Theta & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNPhi(9, 3) = RESHAPE( (/ & ! inflow angle - B1N1Phi,B1N2Phi,B1N3Phi,B1N4Phi,B1N5Phi,B1N6Phi,B1N7Phi,B1N8Phi,B1N9Phi, & - B2N1Phi,B2N2Phi,B2N3Phi,B2N4Phi,B2N5Phi,B2N6Phi,B2N7Phi,B2N8Phi,B2N9Phi, & - B3N1Phi,B3N2Phi,B3N3Phi,B3N4Phi,B3N5Phi,B3N6Phi,B3N7Phi,B3N8Phi,B3N9Phi & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNCurve(9, 3) = RESHAPE( (/ & ! curvature angle - B1N1Curve,B1N2Curve,B1N3Curve,B1N4Curve,B1N5Curve,B1N6Curve,B1N7Curve,B1N8Curve,B1N9Curve, & - B2N1Curve,B2N2Curve,B2N3Curve,B2N4Curve,B2N5Curve,B2N6Curve,B2N7Curve,B2N8Curve,B2N9Curve, & - B3N1Curve,B3N2Curve,B3N3Curve,B3N4Curve,B3N5Curve,B3N6Curve,B3N7Curve,B3N8Curve,B3N9Curve & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNCl(9, 3) = RESHAPE( (/ & ! lift force coefficient - B1N1Cl,B1N2Cl,B1N3Cl,B1N4Cl,B1N5Cl,B1N6Cl,B1N7Cl,B1N8Cl,B1N9Cl, & - B2N1Cl,B2N2Cl,B2N3Cl,B2N4Cl,B2N5Cl,B2N6Cl,B2N7Cl,B2N8Cl,B2N9Cl, & - B3N1Cl,B3N2Cl,B3N3Cl,B3N4Cl,B3N5Cl,B3N6Cl,B3N7Cl,B3N8Cl,B3N9Cl & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNCd(9, 3) = RESHAPE( (/ & ! drag force coefficient - B1N1Cd,B1N2Cd,B1N3Cd,B1N4Cd,B1N5Cd,B1N6Cd,B1N7Cd,B1N8Cd,B1N9Cd, & - B2N1Cd,B2N2Cd,B2N3Cd,B2N4Cd,B2N5Cd,B2N6Cd,B2N7Cd,B2N8Cd,B2N9Cd, & - B3N1Cd,B3N2Cd,B3N3Cd,B3N4Cd,B3N5Cd,B3N6Cd,B3N7Cd,B3N8Cd,B3N9Cd & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNCm(9, 3) = RESHAPE( (/ & ! pitching moment coefficient - B1N1Cm,B1N2Cm,B1N3Cm,B1N4Cm,B1N5Cm,B1N6Cm,B1N7Cm,B1N8Cm,B1N9Cm, & - B2N1Cm,B2N2Cm,B2N3Cm,B2N4Cm,B2N5Cm,B2N6Cm,B2N7Cm,B2N8Cm,B2N9Cm, & - B3N1Cm,B3N2Cm,B3N3Cm,B3N4Cm,B3N5Cm,B3N6Cm,B3N7Cm,B3N8Cm,B3N9Cm & - /), (/9, 3/) ) - - INTEGER, PARAMETER :: BNCpmin(9, 3) = RESHAPE( (/ & ! pressure coefficient - B1N1Cpmin,B1N2Cpmin,B1N3Cpmin,B1N4Cpmin,B1N5Cpmin,B1N6Cpmin,B1N7Cpmin,B1N8Cpmin,B1N9Cpmin, & - B2N1Cpmin,B2N2Cpmin,B2N3Cpmin,B2N4Cpmin,B2N5Cpmin,B2N6Cpmin,B2N7Cpmin,B2N8Cpmin,B2N9Cpmin, & - B3N1Cpmin,B3N2Cpmin,B3N3Cpmin,B3N4Cpmin,B3N5Cpmin,B3N6Cpmin,B3N7Cpmin,B3N8Cpmin,B3N9Cpmin & - /), (/9, 3/) ) - - INTEGER, PARAMETER :: BNSigCr(9, 3) = RESHAPE( (/ & ! Critical cavitation number - B1N1SigCr,B1N2SigCr,B1N3SigCr,B1N4SigCr,B1N5SigCr,B1N6SigCr,B1N7SigCr,B1N8SigCr,B1N9SigCr, & - B2N1SigCr,B2N2SigCr,B2N3SigCr,B2N4SigCr,B2N5SigCr,B2N6SigCr,B2N7SigCr,B2N8SigCr,B2N9SigCr, & - B3N1SigCr,B3N2SigCr,B3N3SigCr,B3N4SigCr,B3N5SigCr,B3N6SigCr,B3N7SigCr,B3N8SigCr,B3N9SigCr & - /), (/9, 3/) ) - - INTEGER, PARAMETER :: BNSgCav(9, 3) = RESHAPE( (/ & ! Cavitation number - B1N1SgCav,B1N2SgCav,B1N3SgCav,B1N4SgCav,B1N5SgCav,B1N6SgCav,B1N7SgCav,B1N8SgCav,B1N9SgCav, & - B2N1SgCav,B2N2SgCav,B2N3SgCav,B2N4SgCav,B2N5SgCav,B2N6SgCav,B2N7SgCav,B2N8SgCav,B2N9SgCav, & - B3N1SgCav,B3N2SgCav,B3N3SgCav,B3N4SgCav,B3N5SgCav,B3N6SgCav,B3N7SgCav,B3N8SgCav,B3N9SgCav & - /), (/9, 3/) ) - - INTEGER, PARAMETER :: BNCx(9, 3) = RESHAPE( (/ & ! normal force (to plane) coefficient - B1N1Cx,B1N2Cx,B1N3Cx,B1N4Cx,B1N5Cx,B1N6Cx,B1N7Cx,B1N8Cx,B1N9Cx, & - B2N1Cx,B2N2Cx,B2N3Cx,B2N4Cx,B2N5Cx,B2N6Cx,B2N7Cx,B2N8Cx,B2N9Cx, & - B3N1Cx,B3N2Cx,B3N3Cx,B3N4Cx,B3N5Cx,B3N6Cx,B3N7Cx,B3N8Cx,B3N9Cx & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNCy(9, 3) = RESHAPE( (/ & ! tangential force (to plane) coefficient - B1N1Cy,B1N2Cy,B1N3Cy,B1N4Cy,B1N5Cy,B1N6Cy,B1N7Cy,B1N8Cy,B1N9Cy, & - B2N1Cy,B2N2Cy,B2N3Cy,B2N4Cy,B2N5Cy,B2N6Cy,B2N7Cy,B2N8Cy,B2N9Cy, & - B3N1Cy,B3N2Cy,B3N3Cy,B3N4Cy,B3N5Cy,B3N6Cy,B3N7Cy,B3N8Cy,B3N9Cy & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNCn(9, 3) = RESHAPE( (/ & ! normal force (to chord) coefficient - B1N1Cn,B1N2Cn,B1N3Cn,B1N4Cn,B1N5Cn,B1N6Cn,B1N7Cn,B1N8Cn,B1N9Cn, & - B2N1Cn,B2N2Cn,B2N3Cn,B2N4Cn,B2N5Cn,B2N6Cn,B2N7Cn,B2N8Cn,B2N9Cn, & - B3N1Cn,B3N2Cn,B3N3Cn,B3N4Cn,B3N5Cn,B3N6Cn,B3N7Cn,B3N8Cn,B3N9Cn & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNCt(9, 3) = RESHAPE( (/ & ! tangential force (to chord) coefficient - B1N1Ct,B1N2Ct,B1N3Ct,B1N4Ct,B1N5Ct,B1N6Ct,B1N7Ct,B1N8Ct,B1N9Ct, & - B2N1Ct,B2N2Ct,B2N3Ct,B2N4Ct,B2N5Ct,B2N6Ct,B2N7Ct,B2N8Ct,B2N9Ct, & - B3N1Ct,B3N2Ct,B3N3Ct,B3N4Ct,B3N5Ct,B3N6Ct,B3N7Ct,B3N8Ct,B3N9Ct & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNFl(9, 3) = RESHAPE( (/ & ! lift force per unit length - B1N1Fl,B1N2Fl,B1N3Fl,B1N4Fl,B1N5Fl,B1N6Fl,B1N7Fl,B1N8Fl,B1N9Fl, & - B2N1Fl,B2N2Fl,B2N3Fl,B2N4Fl,B2N5Fl,B2N6Fl,B2N7Fl,B2N8Fl,B2N9Fl, & - B3N1Fl,B3N2Fl,B3N3Fl,B3N4Fl,B3N5Fl,B3N6Fl,B3N7Fl,B3N8Fl,B3N9Fl & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNFd(9, 3) = RESHAPE( (/ & ! drag force per unit length - B1N1Fd,B1N2Fd,B1N3Fd,B1N4Fd,B1N5Fd,B1N6Fd,B1N7Fd,B1N8Fd,B1N9Fd, & - B2N1Fd,B2N2Fd,B2N3Fd,B2N4Fd,B2N5Fd,B2N6Fd,B2N7Fd,B2N8Fd,B2N9Fd, & - B3N1Fd,B3N2Fd,B3N3Fd,B3N4Fd,B3N5Fd,B3N6Fd,B3N7Fd,B3N8Fd,B3N9Fd & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNMm(9, 3) = RESHAPE( (/ & ! pitching moment per unit length - B1N1Mm,B1N2Mm,B1N3Mm,B1N4Mm,B1N5Mm,B1N6Mm,B1N7Mm,B1N8Mm,B1N9Mm, & - B2N1Mm,B2N2Mm,B2N3Mm,B2N4Mm,B2N5Mm,B2N6Mm,B2N7Mm,B2N8Mm,B2N9Mm, & - B3N1Mm,B3N2Mm,B3N3Mm,B3N4Mm,B3N5Mm,B3N6Mm,B3N7Mm,B3N8Mm,B3N9Mm & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNFx(9, 3) = RESHAPE( (/ & ! normal force (to plane) per unit length - B1N1Fx,B1N2Fx,B1N3Fx,B1N4Fx,B1N5Fx,B1N6Fx,B1N7Fx,B1N8Fx,B1N9Fx, & - B2N1Fx,B2N2Fx,B2N3Fx,B2N4Fx,B2N5Fx,B2N6Fx,B2N7Fx,B2N8Fx,B2N9Fx, & - B3N1Fx,B3N2Fx,B3N3Fx,B3N4Fx,B3N5Fx,B3N6Fx,B3N7Fx,B3N8Fx,B3N9Fx & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNFy(9, 3) = RESHAPE( (/ & ! tangential force (to plane) per unit length - B1N1Fy,B1N2Fy,B1N3Fy,B1N4Fy,B1N5Fy,B1N6Fy,B1N7Fy,B1N8Fy,B1N9Fy, & - B2N1Fy,B2N2Fy,B2N3Fy,B2N4Fy,B2N5Fy,B2N6Fy,B2N7Fy,B2N8Fy,B2N9Fy, & - B3N1Fy,B3N2Fy,B3N3Fy,B3N4Fy,B3N5Fy,B3N6Fy,B3N7Fy,B3N8Fy,B3N9Fy & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNFn(9, 3) = RESHAPE( (/ & ! normal force (to chord) per unit length - B1N1Fn,B1N2Fn,B1N3Fn,B1N4Fn,B1N5Fn,B1N6Fn,B1N7Fn,B1N8Fn,B1N9Fn, & - B2N1Fn,B2N2Fn,B2N3Fn,B2N4Fn,B2N5Fn,B2N6Fn,B2N7Fn,B2N8Fn,B2N9Fn, & - B3N1Fn,B3N2Fn,B3N3Fn,B3N4Fn,B3N5Fn,B3N6Fn,B3N7Fn,B3N8Fn,B3N9Fn & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNFt(9, 3) = RESHAPE( (/ & ! tangential force (to chord) per unit length - B1N1Ft,B1N2Ft,B1N3Ft,B1N4Ft,B1N5Ft,B1N6Ft,B1N7Ft,B1N8Ft,B1N9Ft, & - B2N1Ft,B2N2Ft,B2N3Ft,B2N4Ft,B2N5Ft,B2N6Ft,B2N7Ft,B2N8Ft,B2N9Ft, & - B3N1Ft,B3N2Ft,B3N3Ft,B3N4Ft,B3N5Ft,B3N6Ft,B3N7Ft,B3N8Ft,B3N9Ft & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNClrnc(9, 3) = RESHAPE( (/ & ! tower clearance - B1N1Clrnc,B1N2Clrnc,B1N3Clrnc,B1N4Clrnc,B1N5Clrnc,B1N6Clrnc,B1N7Clrnc,B1N8Clrnc,B1N9Clrnc, & - B2N1Clrnc,B2N2Clrnc,B2N3Clrnc,B2N4Clrnc,B2N5Clrnc,B2N6Clrnc,B2N7Clrnc,B2N8Clrnc,B2N9Clrnc, & - B3N1Clrnc,B3N2Clrnc,B3N3Clrnc,B3N4Clrnc,B3N5Clrnc,B3N6Clrnc,B3N7Clrnc,B3N8Clrnc,B3N9Clrnc & - /), (/9, 3/) ) - INTEGER, PARAMETER :: BNGam(9,3) = RESHAPE( (/ & ! Vorticity gamma - B1N1Gam,B1N2Gam,B1N3Gam,B1N4Gam,B1N5Gam,B1N6Gam,B1N7Gam,B1N8Gam,B1N9Gam, & - B2N1Gam,B2N2Gam,B2N3Gam,B2N4Gam,B2N5Gam,B2N6Gam,B2N7Gam,B2N8Gam,B2N9Gam, & - B3N1Gam,B3N2Gam,B3N3Gam,B3N4Gam,B3N5Gam,B3N6Gam,B3N7Gam,B3N8Gam,B3N9Gam & - /), (/9,3/) ) - - - INTEGER(IntKi), PARAMETER :: MaxBl = 3 ! Maximum number of blades allowed in simulation - + contains @@ -1654,11 +83,12 @@ END FUNCTION Calc_Chi0 !---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE Calc_WriteOutput( p, p_AD, u, m, m_AD, y, OtherState, xd, indx, iRot, ErrStat, ErrMsg ) +SUBROUTINE Calc_WriteOutput( p, p_AD, u, x, m, m_AD, y, OtherState, xd, indx, iRot, ErrStat, ErrMsg ) TYPE(RotParameterType), INTENT(IN ) :: p ! The rotor parameters TYPE(AD_ParameterType), INTENT(IN ) :: p_AD ! The module parameters TYPE(RotInputType), INTENT(IN ) :: u ! inputs + TYPE(RotContinuousStateType), INTENT(IN ) :: x !< Continuous states at t TYPE(RotMiscVarType), INTENT(INOUT) :: m ! misc variables TYPE(AD_MiscVarType), INTENT(INOUT) :: m_AD ! misc variables TYPE(RotOutputType), INTENT(IN ) :: y ! outputs @@ -1676,6 +106,8 @@ SUBROUTINE Calc_WriteOutput( p, p_AD, u, m, m_AD, y, OtherState, xd, indx, iRot, INTEGER(IntKi) :: j,k,beta REAL(ReKi) :: tmp(3) + REAL(ReKi) :: tmpHubFB(3) + REAL(ReKi) :: tmpHubMB(3) REAL(ReKi) :: force(3) REAL(ReKi) :: moment(3) REAL(ReKi) :: denom, rmax, omega @@ -1687,6 +119,8 @@ SUBROUTINE Calc_WriteOutput( p, p_AD, u, m, m_AD, y, OtherState, xd, indx, iRot, ErrStat = ErrID_None ErrMsg = "" + tmpHubFB = 0.0_ReKi + tmpHubMB = 0.0_ReKi ! Compute max radius and rotor speed if (p_AD%WakeMod /= WakeMod_FVW) then @@ -1713,6 +147,8 @@ SUBROUTINE Calc_WriteOutput( p, p_AD, u, m, m_AD, y, OtherState, xd, indx, iRot, call Calc_WriteOutput_FVW() endif + + ! set these for debugging ! m%AllOuts( Debug1 ) = 0.0_ReKi !TwoNorm( m%BEMT%u_SkewWake(1)%v_qsw ) ! m%AllOuts( Debug2 ) = 0.0_ReKi !TwoNorm( x%BEMT%v_w ) @@ -1739,25 +175,62 @@ subroutine Calc_WriteOutput_AD() m%AllOuts( TwNFdx( beta) ) = m%X_Twr(j) m%AllOuts( TwNFdy( beta) ) = m%Y_Twr(j) + if ( p%Buoyancy ) then + tmp = matmul( u%TowerMotion%Orientation(:,:,j) , m%TwrBuoyLoad%Force(:,j) ) + m%AllOuts( TwNFbx(beta) ) = tmp(1) + m%AllOuts( TwNFby(beta) ) = tmp(2) + m%AllOuts( TwNFbz(beta) ) = tmp(3) + + tmp = matmul( u%TowerMotion%Orientation(:,:,j) , m%TwrBuoyLoad%Moment(:,j) ) + m%AllOuts( TwNMbx(beta) ) = tmp(1) + m%AllOuts( TwNMby(beta) ) = tmp(2) + m%AllOuts( TwNMbz(beta) ) = tmp(3) + end if + end do ! out nodes - + + ! hub outputs + if ( p%Buoyancy ) then + tmpHubFB = matmul( u%HubMotion%Orientation(:,:,1) , m%HubFB ) + m%AllOuts( HbFbx ) = tmpHubFB(1) + m%AllOuts( HbFby ) = tmpHubFB(2) + m%AllOuts( HbFbz ) = tmpHubFB(3) + + tmpHubMB = matmul( u%HubMotion%Orientation(:,:,1) , m%HubMB ) + m%AllOuts( HbMbx ) = tmpHubMB(1) + m%AllOuts( HbMby ) = tmpHubMB(2) + m%AllOuts( HbMbz ) = tmpHubMB(3) + end if + + ! nacelle outputs + if ( p%Buoyancy ) then + tmp = matmul( u%NacelleMotion%Orientation(:,:,1) , m%NacFB ) + m%AllOuts( NcFbx ) = tmp(1) + m%AllOuts( NcFby ) = tmp(2) + m%AllOuts( NcFbz ) = tmp(3) + + tmp = matmul( u%NacelleMotion%Orientation(:,:,1) , m%NacMB ) + m%AllOuts( NcMbx ) = tmp(1) + m%AllOuts( NcMby ) = tmp(2) + m%AllOuts( NcMbz ) = tmp(3) + end if ! blade outputs - do k=1,min(p%numBlades,3) ! limit this + do k=1,min(p%numBlades,AD_MaxBl_Out) ! limit this do beta=1,p%NBlOuts j=p%BlOutNd(beta) - tmp = matmul( m%WithoutSweepPitchTwist(:,:,j,k), u%InflowOnBlade(:,j,k) ) + tmp = matmul( m%orientationAnnulus(:,:,j,k), u%InflowOnBlade(:,j,k) ) m%AllOuts( BNVUndx(beta,k) ) = tmp(1) m%AllOuts( BNVUndy(beta,k) ) = tmp(2) m%AllOuts( BNVUndz(beta,k) ) = tmp(3) - tmp = matmul( m%WithoutSweepPitchTwist(:,:,j,k), m%DisturbedInflow(:,j,k) ) + tmp = matmul( m%orientationAnnulus(:,:,j,k), m%DisturbedInflow(:,j,k) ) m%AllOuts( BNVDisx(beta,k) ) = tmp(1) m%AllOuts( BNVDisy(beta,k) ) = tmp(2) m%AllOuts( BNVDisz(beta,k) ) = tmp(3) - tmp = matmul( m%WithoutSweepPitchTwist(:,:,j,k), u%BladeMotion(k)%TranslationVel(:,j) ) + tmp = matmul( m%orientationAnnulus(:,:,j,k), u%BladeMotion(k)%TranslationVel(:,j) ) m%AllOuts( BNSTVx( beta,k) ) = tmp(1) m%AllOuts( BNSTVy( beta,k) ) = tmp(2) m%AllOuts( BNSTVz( beta,k) ) = tmp(3) @@ -1767,6 +240,18 @@ subroutine Calc_WriteOutput_AD() m%AllOuts( BNSigCr( beta,k) ) = m%SigmaCavitCrit(j,k) m%AllOuts( BNSgCav( beta,k) ) = m%SigmaCavit(j,k) + if ( p%Buoyancy ) then + tmp = matmul( u%BladeMotion(k)%Orientation(:,:,j), m%BladeBuoyLoad(k)%Force(:,j) ) + m%AllOuts( BNFbn(beta,k) ) = tmp(1) + m%AllOuts( BNFbt(beta,k) ) = tmp(2) + m%AllOuts( BNFbs(beta,k) ) = tmp(3) + + tmp = matmul( u%BladeMotion(k)%Orientation(:,:,j), m%BladeBuoyLoad(k)%Moment(:,j) ) + m%AllOuts( BNMbn(beta,k) ) = tmp(1) + m%AllOuts( BNMbt(beta,k) ) = tmp(2) + m%AllOuts( BNMbs(beta,k) ) = tmp(3) + end if + end do ! nodes end do ! blades @@ -1774,7 +259,7 @@ subroutine Calc_WriteOutput_AD() ! blade node tower clearance (requires tower influence calculation): if (p%TwrPotent /= TwrPotent_none .or. p%TwrShadow /= TwrShadow_none) then - do k=1,p%numBlades + do k=1,min(p%numBlades,AD_MaxBl_Out) do beta=1,p%NBlOuts j=p%BlOutNd(beta) m%AllOuts( BNClrnc( beta,k) ) = m%TwrClrnc(j,k) @@ -1796,8 +281,8 @@ subroutine Calc_WriteOutput_AD() ! integrate force/moments over blades by performing mesh transfer to hub point: - force = 0.0_ReKi - moment = 0.0_ReKi + force = tmpHubFB + moment = tmpHubMB do k=1,p%NumBlades call Transfer_Line2_to_Point( y%BladeLoad(k), m%HubLoad, m%B_L_2_H_P(k), ErrStat2, ErrMsg2, u%BladeMotion(k), u%HubMotion ) force = force + m%HubLoad%force( :,1) @@ -1858,7 +343,7 @@ subroutine Calc_WriteOutput_AD() end do ! k=blades ! rotor outputs - if ( EqualRealNos( m%V_dot_x, 0.0_ReKi ) ) then + if ( EqualRealNos( real(m%V_dot_x,SiKi), 0.0_SiKi ) ) then m%AllOuts( RtTSR ) = 0.0_ReKi m%AllOuts( RtAeroCp ) = 0.0_ReKi m%AllOuts( RtAeroCq ) = 0.0_ReKi @@ -1872,6 +357,21 @@ subroutine Calc_WriteOutput_AD() m%AllOuts( RtAeroCt ) = m%AllOuts( RtAeroFxh ) / denom end if + + ! TailFin + if (p%TFinAero) then + m%AllOuts( TFAlpha ) = m%TFinAlpha*R2D ! [deg] + m%AllOuts( TFRe ) = m%TFinRe + !m%AllOuts( TFM ) = m%TFinVrel/p%SpdSound + m%AllOuts( TFVrel ) = m%TFinVrel + m%AllOuts( TFVundxi:TFVundzi) = m%TFinVund_i + m%AllOuts( TFVindxi:TFVindzi ) = m%TFinVind_i + m%AllOuts( TFVrelxi:TFVrelzi ) = m%TFinVrel_i + m%AllOuts( TFSTVxi:TFSTVzi ) = m%TFinSTV_i + m%AllOuts( TFFxi:TFFzi ) = m%TFinF_i + m%AllOuts( TFMxi:TFMzi ) = m%TFinM_i + endif + end subroutine Calc_WriteOutput_AD !.......................................................................................... @@ -1887,7 +387,7 @@ subroutine Calc_WriteOutput_BEMT() ! blade outputs - do k=1,min(p%numBlades,size(BAzimuth) ) ! limit this + do k=1,min(p%numBlades,AD_MaxBl_Out) ! limit this m%AllOuts( BAzimuth(k) ) = MODULO( m%BEMT_u(indx)%psi(k)*R2D, 360.0_ReKi ) ! m%AllOuts( BPitch( k) ) = calculated in SetInputsForBEMT @@ -1985,7 +485,7 @@ subroutine Calc_WriteOutput_FVW m%AllOuts( BNPhi( beta,k) ) = m_AD%FVW%W(iW)%BN_phi(j)*R2D ! m%AllOuts( BNCurve(beta,k) ) = m%Curve(j,k)*R2D ! TODO -! m%AllOuts( BNCpmin( beta,k) ) = m%BEMT_y%Cpmin(jk) ! TODO + m%AllOuts( BNCpmin(beta,k) ) = m_AD%FVW%W(iW)%BN_Cpmin(j) m%AllOuts( BNCl( beta,k) ) = m_AD%FVW%W(iW)%BN_Cl(j) m%AllOuts( BNCd( beta,k) ) = m_AD%FVW%W(iW)%BN_Cd(j) m%AllOuts( BNCm( beta,k) ) = m_AD%FVW%W(iW)%BN_Cm(j) @@ -2021,7 +521,7 @@ end subroutine Calc_WriteOutput_FVW END SUBROUTINE Calc_WriteOutput !---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE ReadInputFiles( InputFileName, InputFileData, Default_DT, OutFileRoot, NumBlades, UnEcho, ErrStat, ErrMsg ) +SUBROUTINE ReadInputFiles( InputFileName, InputFileData, Default_DT, OutFileRoot, NumBlades, AeroProjMod, UnEcho, ErrStat, ErrMsg ) ! This subroutine reads the input file and stores all the data in the AD_InputFile structure. ! It does not perform data validation. !.................................................................................................................................. @@ -2036,6 +536,7 @@ SUBROUTINE ReadInputFiles( InputFileName, InputFileData, Default_DT, OutFileRoot INTEGER(IntKi), INTENT(INOUT) :: UnEcho ! Unit number for the echo file INTEGER(IntKi), INTENT(IN) :: NumBlades(:) ! Number of blades per rotor + INTEGER(IntKi), INTENT(IN) :: AeroProjMod(:) ! AeroProjMod per rotor INTEGER(IntKi), INTENT(OUT) :: ErrStat ! The error status code CHARACTER(*), INTENT(OUT) :: ErrMsg ! The error message, if an error occurred @@ -2070,7 +571,7 @@ SUBROUTINE ReadInputFiles( InputFileName, InputFileData, Default_DT, OutFileRoot !FIXME: add options for passing the blade files. This routine will need restructuring to handle that. DO I=1,NumBlades(iR) - CALL ReadBladeInputs ( InputFileData%ADBlFile(iBld), InputFileData%rotors(iR)%BladeProps(I), UnEcho, ErrStat2, ErrMsg2 ) + CALL ReadBladeInputs ( InputFileData%ADBlFile(iBld), InputFileData%rotors(iR)%BladeProps(I), AeroProjMod(iR), UnEcho, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName//TRIM(':Blade')//TRIM(Num2LStr(I))) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -2079,7 +580,19 @@ SUBROUTINE ReadInputFiles( InputFileName, InputFileData, Default_DT, OutFileRoot iBld = iBld+1 ! Increment blade counter END DO - ENDDO ! Loop on rotors + end do ! loop on rotors + + ! Read TailFin + do iR = 1, size(InputFileData%rotors) + if (InputFileData%rotors(iR)%TFinAero) then + call ReadTailFinInputs(InputFileData%rotors(iR)%TFinFile, InputFileData%rotors(iR)%TFin, UnEcho, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if ( ErrStat >= AbortErrLev ) then + call Cleanup() + return + end if + endif + enddo ! iR, rotors CALL Cleanup ( ) @@ -2122,7 +635,7 @@ SUBROUTINE ParsePrimaryFileInfo( PriPath, InitInp, InputFile, RootName, NumBlade 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 + real(ReKi) :: TmpRe5(5) !< temporary 8 number array for reading values in character(*), parameter :: RoutineName = 'ParsePrimaryFileInfo' @@ -2187,6 +700,9 @@ SUBROUTINE ParsePrimaryFileInfo( PriPath, InitInp, InputFile, RootName, NumBlade 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 + ! Buoyancy - Include buoyancy effects? (flag) + call ParseVar( FileInfo_In, CurLine, "Buoyancy", InputFileData%Buoyancy, 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 ) @@ -2277,11 +793,9 @@ SUBROUTINE ParsePrimaryFileInfo( PriPath, InitInp, InputFile, RootName, NumBlade ! 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 - ! UAStartRad - Starting radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2]: call ParseVar( FileInfo_In, CurLine, "UAStartRad", InputFileData%UAStartRad, ErrStat2, ErrMsg2, UnEc ) if (ErrStat2>= AbortErrLev) InputFileData%UAStartRad = 0.0_ReKi - ! UAEndRad - Ending radius for dynamic stall (fraction of rotor radius) [used only when AFAeroMod=2]: call ParseVar( FileInfo_In, CurLine, "UAEndRad", InputFileData%UAEndRad, ErrStat2, ErrMsg2, UnEc ) if (ErrStat2>= AbortErrLev) InputFileData%UAEndRad = 1.0_ReKi @@ -2339,22 +853,60 @@ SUBROUTINE ParsePrimaryFileInfo( PriPath, InitInp, InputFile, RootName, NumBlade 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] + !====== Hub Properties ============================================================================== [used only when Buoyancy=True] + do iR = 1,size(NumBlades) ! Loop on rotors + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + ! VolHub - Hub volume (m^3) + call ParseVar( FileInfo_In, CurLine, "VolHub", InputFileData%rotors(iR)%VolHub, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! HubCenBx - Hub center of buoyancy x direction offset (m) + call ParseVar( FileInfo_In, CurLine, "HubCenBx", InputFileData%rotors(iR)%HubCenBx, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + end do + + !====== Nacelle Properties ========================================================================== [used only when Buoyancy=True] + do iR = 1,size(NumBlades) ! Loop on rotors + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + ! VolNac - Nacelle volume (m^3) + call ParseVar( FileInfo_In, CurLine, "VolNac", InputFileData%rotors(iR)%VolNac, ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + ! NacCenB - Nacelle center of buoyancy x,y,z direction offsets (m) + call ParseAry( FileInfo_In, CurLine, 'NacCenB', InputFileData%rotors(iR)%NacCenB, 3 , ErrStat2, ErrMsg2, UnEc ) + if (Failed()) return + end do + + !====== Tail fin aerodynamics ======================================================================== + do iR = 1,size(NumBlades) ! Loop on rotors + if ( InputFileData%Echo ) WRITE(UnEc, '(A)') FileInfo_In%Lines(CurLine) ! Write section break to echo + CurLine = CurLine + 1 + ! NOTE: being nice with legacy input file. Uncomment in next release + call ParseVar(FileInfo_In, CurLine, "TFinAero", InputFileData%rotors(iR)%TFinAero, ErrStat2, ErrMsg2, UnEc); + if (ErrStat2==ErrID_None) then + call ParseVar(FileInfo_In, CurLine, "TFinFile", InputFileData%rotors(iR)%TFinFile, ErrStat2, ErrMsg2, UnEc); if (Failed()) return + InputFileData%rotors(iR)%TFinFile = trim(PriPath) // trim(InputFileData%rotors(iR)%TFinFile) + else + call LegacyWarning('Tail Fin section (TFinAero, TFinFile) is missing from input file.') + CurLine = CurLine - 1 + endif + enddo + !====== Tower Influence and Aerodynamics ============================================================ [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True] do iR = 1,size(NumBlades) ! Loop on rotors 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] + ! NumTwrNds - Number of tower nodes used in the analysis (-) [used only when TwrPotent/=0, TwrShadow/=0, TwrAero=True, or Buoyancy=True] call ParseVar( FileInfo_In, CurLine, "NumTwrNds", InputFileData%rotors(iR)%NumTwrNds, ErrStat2, ErrMsg2, UnEc ) if (Failed()) return - !TwrElev TwrDiam TwrCd + !TwrElev TwrDiam TwrCd TwrTI TwrCb if ( InputFileData%Echo ) WRITE(UnEc, '(A)') 'Tower Table Header: '//FileInfo_In%Lines(CurLine) ! Write section break to echo CurLine = CurLine + 1 - !(m) (m) (-) + !(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%rotors(iR)%TwrElev, InputFileData%rotors(iR)%NumTwrNds, 'TwrElev', ErrStat2, ErrMsg2) + CALL AllocAry( InputFileData%rotors(iR)%TwrElev, InputFileData%rotors(iR)%NumTwrNds, 'TwrElev', ErrStat2, ErrMsg2) if (Failed()) return CALL AllocAry( InputFileData%rotors(iR)%TwrDiam, InputFileData%rotors(iR)%NumTwrNds, 'TwrDiam', ErrStat2, ErrMsg2) if (Failed()) return @@ -2362,14 +914,16 @@ SUBROUTINE ParsePrimaryFileInfo( PriPath, InitInp, InputFile, RootName, NumBlade if (Failed()) return CALL AllocAry( InputFileData%rotors(iR)%TwrTI, InputFileData%rotors(iR)%NumTwrNds, 'TwrTI', ErrStat2, ErrMsg2) if (Failed()) return - + CALL AllocAry( InputFileData%rotors(iR)%TwrCb, InputFileData%rotors(iR)%NumTwrNds, 'TwrCb', ErrStat2, ErrMsg2) + if (Failed()) return do I=1,InputFileData%rotors(iR)%NumTwrNds - call ParseAry ( FileInfo_In, CurLine, 'Properties for tower node '//trim( Int2LStr( I ) )//'.', TmpRe4, 4, ErrStat2, ErrMsg2, UnEc ) + call ParseAry ( FileInfo_In, CurLine, 'Properties for tower node '//trim( Int2LStr( I ) )//'.', TmpRe5, 5, ErrStat2, ErrMsg2, UnEc ) if (Failed()) return; - InputFileData%rotors(iR)%TwrElev(I) = TmpRe4( 1) - InputFileData%rotors(iR)%TwrDiam(I) = TmpRe4( 2) - InputFileData%rotors(iR)%TwrCd(I) = TmpRe4( 3) - InputFileData%rotors(iR)%TwrTI(I) = TmpRe4( 4) + InputFileData%rotors(iR)%TwrElev(I) = TmpRe5( 1) + InputFileData%rotors(iR)%TwrDiam(I) = TmpRe5( 2) + InputFileData%rotors(iR)%TwrCd(I) = TmpRe5( 3) + InputFileData%rotors(iR)%TwrTI(I) = TmpRe5( 4) + InputFileData%rotors(iR)%TwrCb(I) = TmpRe5( 5) end do enddo @@ -2408,8 +962,7 @@ SUBROUTINE ParsePrimaryFileInfo( PriPath, InitInp, InputFile, RootName, NumBlade 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 ) + call ReadOutputListFromFileInfo( FileInfo_In, CurLine, InputFileData%OutList, InputFileData%NumOuts, ErrStat2, ErrMsg2, UnEc ) if (Failed()) return; !====== Nodal Outputs ============================================================================== @@ -2437,8 +990,7 @@ SUBROUTINE ParsePrimaryFileInfo( PriPath, InitInp, InputFile, RootName, NumBlade 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 ) + call ReadOutputListFromFileInfo( FileInfo_In, CurLine, InputFileData%BldNd_OutList, InputFileData%BldNd_NumOuts, ErrStat2, ErrMsg2, UnEc ) if (FailedNodal()) return; RETURN @@ -2459,10 +1011,18 @@ logical function FailedNodal() call wrscr( trim(ErrMsg_NoAllBldNdOuts) ) endif end function FailedNodal + subroutine LegacyWarning(Message) + character(len=*), intent(in) :: Message + call WrScr('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') + call WrScr('Warning: the AeroDyn 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 !------------------------------------------------------------------------------------------------- END SUBROUTINE ParsePrimaryFileInfo !---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE ReadBladeInputs ( ADBlFile, BladeKInputFileData, UnEc, ErrStat, ErrMsg ) +SUBROUTINE ReadBladeInputs ( ADBlFile, BladeKInputFileData, AeroProjMod, UnEc, ErrStat, ErrMsg ) ! This routine reads a blade input file. !.................................................................................................................................. @@ -2471,6 +1031,7 @@ SUBROUTINE ReadBladeInputs ( ADBlFile, BladeKInputFileData, UnEc, ErrStat, ErrMs TYPE(AD_BladePropsType), INTENT(INOUT) :: BladeKInputFileData ! Data for Blade K stored in the module's input file CHARACTER(*), INTENT(IN) :: ADBlFile ! Name of the blade input file data + INTEGER(IntKi), INTENT(IN) :: AeroProjMod ! AeroProjMod INTEGER(IntKi), INTENT(IN) :: UnEc ! I/O unit for echo file. If present and > 0, write to UnEc INTEGER(IntKi), INTENT(OUT) :: ErrStat ! Error status @@ -2484,6 +1045,10 @@ SUBROUTINE ReadBladeInputs ( ADBlFile, BladeKInputFileData, UnEc, ErrStat, ErrMs INTEGER(IntKi) :: ErrStat2 , IOS ! Temporary Error status CHARACTER(ErrMsgLen) :: ErrMsg2 ! Temporary Err msg CHARACTER(*), PARAMETER :: RoutineName = 'ReadBladeInputs' + CHARACTER(len=1024) :: Line + CHARACTER(len=50) :: HeaderCols(10) ! Header columns in file + LOGICAL :: hasBuoyancy ! Does file contain Buoyancy columns + ErrStat = ErrID_None ErrMsg = "" @@ -2522,8 +1087,18 @@ SUBROUTINE ReadBladeInputs ( ADBlFile, BladeKInputFileData, UnEc, ErrStat, ErrMs RETURN END IF - CALL ReadCom ( UnIn, ADBlFile, 'Table header: names', ErrStat2, ErrMsg2, UnEc ) + CALL ReadCom ( UnIn, ADBlFile, 'Table header: names', ErrStat2, ErrMsg2, UnEc, Comment=Line ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + ! Check if 10 columns are present + READ (Line,*, IOSTAT=ErrStat2) ( HeaderCols(I), I=1,10 ) + hasBuoyancy = .true. + IF ( ErrStat2 < 0 ) THEN ! end of line reached + hasBuoyancy = .false. + !call WrScr('Blade input file is missing buoyancy columns.') + ELSE IF ( ErrStat2 > 0 ) THEN + CALL SetErrStat(ErrID_Fatal, 'Unexpected error while trying to infer column headers in blade file.', ErrStat, ErrMsg, RoutineName) + endif + CALL ReadCom ( UnIn, ADBlFile, 'Table header: units', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -2549,6 +1124,18 @@ SUBROUTINE ReadBladeInputs ( ADBlFile, BladeKInputFileData, UnEc, ErrStat, ErrMs CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL AllocAry( BladeKInputFileData%BlAFID, BladeKInputFileData%NumBlNds, 'BlAFID', ErrStat2, ErrMsg2) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocAry( BladeKInputFileData%BlCb, BladeKInputFileData%NumBlNds, 'BlCb', ErrStat2, ErrMsg2) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocAry( BladeKInputFileData%BlCenBn, BladeKInputFileData%NumBlNds, 'BlCenBn', ErrStat2, ErrMsg2) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL AllocAry( BladeKInputFileData%BlCenBt, BladeKInputFileData%NumBlNds, 'BlCenBt', ErrStat2, ErrMsg2) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + IF (.not. hasBuoyancy) THEN + BladeKInputFileData%BlCb = 0.0_ReKi + BladeKInputFileData%BlCenBn = 0.0_ReKi + BladeKInputFileData%BlCenBt = 0.0_ReKi + ENDIF ! Return on error if we didn't allocate space for the next inputs IF ( ErrStat >= AbortErrLev ) THEN @@ -2557,9 +1144,15 @@ SUBROUTINE ReadBladeInputs ( ADBlFile, BladeKInputFileData, UnEc, ErrStat, ErrMs END IF DO I=1,BladeKInputFileData%NumBlNds - READ( UnIn, *, IOStat=IOS ) BladeKInputFileData%BlSpn(I), BladeKInputFileData%BlCrvAC(I), BladeKInputFileData%BlSwpAC(I), & - BladeKInputFileData%BlCrvAng(I), BladeKInputFileData%BlTwist(I), BladeKInputFileData%BlChord(I), & - BladeKInputFileData%BlAFID(I) + IF (hasBuoyancy) THEN + READ( UnIn, *, IOStat=IOS ) BladeKInputFileData%BlSpn(I), BladeKInputFileData%BlCrvAC(I), BladeKInputFileData%BlSwpAC(I), & + BladeKInputFileData%BlCrvAng(I), BladeKInputFileData%BlTwist(I), BladeKInputFileData%BlChord(I), & + BladeKInputFileData%BlAFID(I), BladeKInputFileData%BlCb(I), BladeKInputFileData%BlCenBn(I), BladeKInputFileData%BlCenBt(I) + ELSE + READ( UnIn, *, IOStat=IOS ) BladeKInputFileData%BlSpn(I), BladeKInputFileData%BlCrvAC(I), BladeKInputFileData%BlSwpAC(I), & + BladeKInputFileData%BlCrvAng(I), BladeKInputFileData%BlTwist(I), BladeKInputFileData%BlChord(I), & + BladeKInputFileData%BlAFID(I) + ENDIF CALL CheckIOS( IOS, ADBlFile, 'Blade properties row '//TRIM(Num2LStr(I)), NumType, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Return on error if we couldn't read this line @@ -2569,11 +1162,27 @@ SUBROUTINE ReadBladeInputs ( ADBlFile, BladeKInputFileData, UnEc, ErrStat, ErrMs END IF IF (UnEc > 0) THEN - WRITE( UnEc, "(6(F9.4,1x),I9)", IOStat=IOS) BladeKInputFileData%BlSpn(I), BladeKInputFileData%BlCrvAC(I), BladeKInputFileData%BlSwpAC(I), & + WRITE( UnEc, "(6(F9.4,1x),I9,4(F9.4,1x))", IOStat=IOS) BladeKInputFileData%BlSpn(I), BladeKInputFileData%BlCrvAC(I), BladeKInputFileData%BlSwpAC(I), & BladeKInputFileData%BlCrvAng(I), BladeKInputFileData%BlTwist(I), BladeKInputFileData%BlChord(I), & - BladeKInputFileData%BlAFID(I) + BladeKInputFileData%BlAFID(I), BladeKInputFileData%BlCb(I), BladeKInputFileData%BlCenBn(I), BladeKInputFileData%BlCenBt(I) END IF END DO + + + if (all(BladeKInputFileData%BlCrvAC.eq.0.0_ReKi)) then + BladeKInputFileData%BlCrvAng = 0.0_ReKi + else + if (AeroProjMod==APM_BEM_NoSweepPitchTwist .or. AeroProjMod==APM_LiftingLine) then + !call WrScr('>>> ReadBladeInputs: Not computing cant angle (BlCrvAng), AeroProjMod='//trim(num2lstr(AeroProjMod))) + else if (AeroProjMod==APM_BEM_Polar) then + call WrScr('>>> ReadBladeInputs: Computing cant angle (BlCrvAng), AeroProjMod='//trim(num2lstr(AeroProjMod))) + call calcCantAngle(BladeKInputFileData%BlCrvAC,BladeKInputFileData%BlSpn,3, size(BladeKInputFileData%BlSpn),BladeKInputFileData%BlCrvAng) + else + call SetErrStat(ErrID_Fatal, 'Unsupported AeroProjMod='//trim(num2lstr(AeroProjMod)), ErrStat, ErrMsg, RoutineName) + call Cleanup() + return + endif + endif BladeKInputFileData%BlCrvAng = BladeKInputFileData%BlCrvAng*D2R BladeKInputFileData%BlTwist = BladeKInputFileData%BlTwist*D2R @@ -2595,9 +1204,73 @@ END SUBROUTINE Cleanup END SUBROUTINE ReadBladeInputs !---------------------------------------------------------------------------------------------------------------------------------- +!> Read Tail Fin inputs +SUBROUTINE ReadTailFinInputs(FileName, TFData, UnEc, ErrStat, ErrMsg) + character(*), intent(in ) :: FileName !< Name of the file containing the Tail Fin aero data + type(TFinInputFileType), intent(inout) :: TFData !< All the data in the Tail Fin input file + integer(IntKi), intent(in ) :: UnEc !< Echo unit + integer(IntKi), intent( out) :: ErrStat !< Error status + character(ErrMsgLen), intent( out) :: ErrMsg !< Error message + ! Local + type(FileInfoType) :: FileInfo_In ! < The derived type for holding the file information. + integer(IntKi) :: iLine !< current entry in FileInfo_In%Lines array + integer(IntKi) :: ErrStat2 !< Temporary Error status + character(ErrMsgLen) :: ErrMsg2 !< Temporary Error message + character(len=1024 ) :: DummyLine + + ! --- Read Tail fin input file into array of strings + call ProcessComFile( FileName, FileInfo_In, ErrStat2, ErrMsg2) + + ! --- Parse the array of strings + ! Skip the first two lines as they are known to be header lines and separators + do iLine = 1,2 + if ( UnEc>0 ) WRITE(UnEc, '(A)') FileInfo_In%Lines(iLine) ! Write header to echo + enddo + iLine = 3 + !====== General inputs ============================================================ + call ParseCom(FileInfo_in, iLine, DummyLine , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_In, iLine, 'TFinMod' , TFData%TFinMod , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_In, iLine, 'TFinChord' , TFData%TFinChord , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_In, iLine, 'TFinArea' , TFData%TFinArea , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseAry(FileInfo_In, iLine, 'TFinRefP_n', TFData%TFinRefP_n, 3 , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseAry(FileInfo_In, iLine, 'TFinAngles', TFData%TFinAngles, 3 , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_In, iLine, 'TFinIndMod', TFData%TFinIndMod , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + !====== Polar-based model ================================ [used only when TFinMod=1] + call ParseCom(FileInfo_in, iLine, DummyLine , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_In, iLine, 'TFinAFID' , TFData%TFinAFID , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + !====== Unsteady slender body model ===================== [used only when TFinMod=2] + call ParseCom(FileInfo_in, iLine, DummyLine , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + ! TODO + + ! --- Triggers + TFData%TFinAngles = TFData%TFinAngles*D2R ! deg2rad + + ! --- Validation on the fly + !if (all((/TFinAero_none,TFinAero_polar, TFinAero_USB/) /= TFData%TFinMod)) then + if (all((/TFinAero_none,TFinAero_polar/) /= TFData%TFinMod)) then + call Fatal('TFinMod needs to be 0, or 1') + endif + !if (all((/TFinIndMod_none,TFinIndMod_rotavg/) /= TFData%TFinIndMod)) then + if (all((/TFinIndMod_none/) /= TFData%TFinIndMod)) then + call Fatal('TFinIndMod needs to be 0') + endif + +contains + logical function Failed() + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'ReadTailFinInputs' ) + Failed = ErrStat >= AbortErrLev + end function Failed + + subroutine Fatal(ErrMsg_in) + character(len=*), intent(in) :: ErrMsg_in + call SetErrStat(ErrID_Fatal, 'File:'//trim(FileName)//':'//trim(ErrMsg_in), ErrStat, ErrMsg, 'ReadTailFinInputs') + end subroutine Fatal + +END SUBROUTINE ReadTailFinInputs +!---------------------------------------------------------------------------------------------------------------------------------- SUBROUTINE AD_PrintSum( InputFileData, p, p_AD, u, y, ErrStat, ErrMsg ) ! This routine generates the summary file, which contains a summary of input file options. - + use YAML, only: yaml_write_var ! passed variables TYPE(AD_InputFile), INTENT(IN) :: InputFileData ! Input-file data TYPE(RotParameterType), INTENT(IN) :: p ! Parameters @@ -2613,12 +1286,16 @@ SUBROUTINE AD_PrintSum( InputFileData, p, p_AD, u, y, ErrStat, ErrMsg ) INTEGER(IntKi) :: I ! Index for the nodes. INTEGER(IntKi) :: UnSu ! I/O unit number for the summary output file - CHARACTER(*), PARAMETER :: FmtDat = '(A,T35,1(:,F13.3))' ! Format for outputting mass and modal data. + CHARACTER(*), PARAMETER :: FmtDat = '(A,T41,1(:,F13.3))' ! Format for outputting mass and modal data. CHARACTER(*), PARAMETER :: FmtDatT = '(A,T35,1(:,F13.8))' ! Format for outputting time steps. CHARACTER(30) :: OutPFmt ! Format to print list of selected output channels to summary file + CHARACTER(30) :: OutPFmtS ! Format to print list of selected output channels to summary file CHARACTER(100) :: Msg ! temporary string for writing appropriate text to summary file + CHARACTER(ChanLen),PARAMETER :: TitleStr(2) = (/ 'Parameter', 'Units ' /) + CHARACTER(ChanLen),PARAMETER :: TitleStrLines(2) = (/ '---------------', '---------------' /) + ! Open the summary file and give it a heading. CALL GetNewUnit( UnSu, ErrStat, ErrMsg ) @@ -2694,6 +1371,22 @@ SUBROUTINE AD_PrintSum( InputFileData, p, p_AD, u, y, ErrStat, ErrMsg ) end if WRITE (UnSu,Ec_LgFrmt) p%TwrAero, 'TwrAero', 'Calculate tower aerodynamic loads? '//TRIM(Msg) + ! CavitCheck + if (p%CavitCheck) then + Msg = 'Yes' + else + Msg = 'No' + end if + WRITE (UnSu,Ec_LgFrmt) p%CavitCheck, 'CavitCheck', 'Perform cavitation check? '//TRIM(Msg) + + ! Buoyancy + if (p%Buoyancy) then + Msg = 'Yes' + else + Msg = 'No' + end if + WRITE (UnSu,Ec_LgFrmt) p%Buoyancy, 'Buoyancy', 'Include buoyancy effects? '//TRIM(Msg) + if (p_AD%WakeMod/=WakeMod_none) then WRITE (UnSu,'(A)') '====== Blade-Element/Momentum Theory Options ======================================================' @@ -2803,7 +1496,7 @@ SUBROUTINE AD_PrintSum( InputFileData, p, p_AD, u, y, ErrStat, ErrMsg ) Msg = 'Stieg Oye dynamic stall model' case (UA_BV) Msg = 'Boeing-Vertol dynamic stall model (e.g. used in CACTUS)' - case default + case default Msg = 'unknown' end select WRITE (UnSu,Ec_IntFrmt) InputFileData%UAMod, 'UAMod', 'Unsteady Aero Model: '//TRIM(Msg) @@ -2845,11 +1538,12 @@ SUBROUTINE AD_PrintSum( InputFileData, p, p_AD, u, y, ErrStat, ErrMsg ) end if - OutPFmt = '( 15x, I4, 2X, A '//TRIM(Num2LStr(ChanLen))//',1 X, A'//TRIM(Num2LStr(ChanLen))//' )' + OutPFmt = '( 15x, I4, 3X,A '//TRIM(Num2LStr(ChanLen))//',1 X, A'//TRIM(Num2LStr(ChanLen))//' )' + OutPFmtS = '( 15x, A4, 3X,A '//TRIM(Num2LStr(ChanLen))//',1 X, A'//TRIM(Num2LStr(ChanLen))//' )' + WRITE (UnSu,'(15x,A)') WRITE (UnSu,'(15x,A)') 'Requested Output Channels:' - WRITE (UnSu,'(15x,A)') 'Col Parameter Units' - WRITE (UnSu,'(15x,A)') '---- -------------- -----' - + WRITE (UnSu,OutPFmtS ) "Col", TitleStr + WRITE (UnSu,OutPFmtS ) "---", TitleStrLines DO I = 0,p%NumOuts WRITE (UnSu,OutPFmt) I, p%OutParam(I)%Name, p%OutParam(I)%Units END DO @@ -2857,11 +1551,18 @@ SUBROUTINE AD_PrintSum( InputFileData, p, p_AD, u, y, ErrStat, ErrMsg ) WRITE (UnSu,'(15x,A)') WRITE (UnSu,'(15x,A)') WRITE (UnSu,'(15x,A)') 'Requested Output Channels at each blade station:' - WRITE (UnSu,'(15x,A)') 'Col Parameter Units' - WRITE (UnSu,'(15x,A)') '---- -------------- -----' + WRITE (UnSu,OutPFmtS ) "Col", TitleStr + WRITE (UnSu,OutPFmtS ) "---", TitleStrLines DO I = 1,p%BldNd_NumOuts WRITE (UnSu,OutPFmt) I, p%BldNd_OutParam(I)%Name, p%BldNd_OutParam(I)%Units - END DO + END DO + + ! Buoyancy parameters + WRITE (UnSu,'(//,A,/)') 'Buoyancy parameters:' + call yaml_write_var ( UnSu , 'Hub volume (m^3)' , p%VolHub , 'F15.3' , ErrStat , ErrMsg ) ! Buoyancy volume of the hub + call yaml_write_var ( UnSu , 'Nacelle volume (m^3)' , p%VolNac , 'F11.3' , ErrStat , ErrMsg ) ! Buoyancy volume of the nacelle + call yaml_write_var ( UnSu , 'Total blade volume (m^3)' , p%VolBl , 'F7.3' , ErrStat , ErrMsg ) ! Buoyancy volume of all blades + call yaml_write_var ( UnSu , 'Tower volume (m^3)' , p%VolTwr , 'F13.3' , ErrStat , ErrMsg ) ! Buoyancy volume of the tower CLOSE(UnSu) @@ -2881,513 +1582,29 @@ END SUBROUTINE AD_PrintSum !! the sign is set to 0 if the channel is invalid. !! It sets assumes the value p%NumOuts has been set before this routine has been called, and it sets the values of p%OutParam here. !! -!! This routine was generated by Write_ChckOutLst.m using the parameters listed in OutListParameters.xlsx at 01-Mar-2022 11:16:33. +!! This routine was generated by Write_ChckOutLst.m using the parameters listed in OutListParameters.xlsx at 07-Sep-2022 16:15:55. SUBROUTINE SetOutParam(OutList, p, p_AD, ErrStat, ErrMsg ) !.................................................................................................................................. - + IMPLICIT NONE - + ! Passed variables - - CHARACTER(ChanLen), INTENT(IN) :: OutList(:) !< The list out user-requested outputs + + CHARACTER(ChanLen), INTENT(IN) :: OutList(:) !< The list of user-requested outputs TYPE(RotParameterType), INTENT(INOUT) :: p !< The module parameters TYPE(AD_ParameterType), INTENT(INOUT) :: p_AD !< The module parameters INTEGER(IntKi), INTENT(OUT) :: ErrStat !< The error status code CHARACTER(*), INTENT(OUT) :: ErrMsg !< The error message, if an error occurred - + ! Local variables - + INTEGER :: ErrStat2 ! temporary (local) error status INTEGER :: I ! Generic loop-counting index INTEGER :: J ! Generic loop-counting index INTEGER :: INDX ! Index for valid arrays - - LOGICAL :: CheckOutListAgain ! Flag used to determine if output parameter starting with "M" is valid (or the negative of another parameter) LOGICAL :: InvalidOutput(0:MaxOutPts) ! This array determines if the output channel is valid for this configuration - CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I) CHARACTER(*), PARAMETER :: RoutineName = "SetOutParam" - - CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(1270) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically - "B1AEROFX ","B1AEROFXG","B1AEROFY ","B1AEROFYG","B1AEROFZ ","B1AEROFZG","B1AEROMX ","B1AEROMXG", & - "B1AEROMY ","B1AEROMYG","B1AEROMZ ","B1AEROMZG","B1AEROPWR","B1AZIMUTH","B1N1ALPHA","B1N1AXIND", & - "B1N1CD ","B1N1CL ","B1N1CLRNC","B1N1CM ","B1N1CN ","B1N1CPMIN","B1N1CT ","B1N1CURVE", & - "B1N1CX ","B1N1CY ","B1N1DYNP ","B1N1FD ","B1N1FL ","B1N1FN ","B1N1FT ","B1N1FX ", & - "B1N1FY ","B1N1GAM ","B1N1M ","B1N1MM ","B1N1PHI ","B1N1RE ","B1N1SGCAV","B1N1SIGCR", & - "B1N1STVX ","B1N1STVY ","B1N1STVZ ","B1N1THETA","B1N1TNIND","B1N1VDISX","B1N1VDISY","B1N1VDISZ", & - "B1N1VINDX","B1N1VINDY","B1N1VREL ","B1N1VUNDX","B1N1VUNDY","B1N1VUNDZ","B1N2ALPHA","B1N2AXIND", & - "B1N2CD ","B1N2CL ","B1N2CLRNC","B1N2CM ","B1N2CN ","B1N2CPMIN","B1N2CT ","B1N2CURVE", & - "B1N2CX ","B1N2CY ","B1N2DYNP ","B1N2FD ","B1N2FL ","B1N2FN ","B1N2FT ","B1N2FX ", & - "B1N2FY ","B1N2GAM ","B1N2M ","B1N2MM ","B1N2PHI ","B1N2RE ","B1N2SGCAV","B1N2SIGCR", & - "B1N2STVX ","B1N2STVY ","B1N2STVZ ","B1N2THETA","B1N2TNIND","B1N2VDISX","B1N2VDISY","B1N2VDISZ", & - "B1N2VINDX","B1N2VINDY","B1N2VREL ","B1N2VUNDX","B1N2VUNDY","B1N2VUNDZ","B1N3ALPHA","B1N3AXIND", & - "B1N3CD ","B1N3CL ","B1N3CLRNC","B1N3CM ","B1N3CN ","B1N3CPMIN","B1N3CT ","B1N3CURVE", & - "B1N3CX ","B1N3CY ","B1N3DYNP ","B1N3FD ","B1N3FL ","B1N3FN ","B1N3FT ","B1N3FX ", & - "B1N3FY ","B1N3GAM ","B1N3M ","B1N3MM ","B1N3PHI ","B1N3RE ","B1N3SGCAV","B1N3SIGCR", & - "B1N3STVX ","B1N3STVY ","B1N3STVZ ","B1N3THETA","B1N3TNIND","B1N3VDISX","B1N3VDISY","B1N3VDISZ", & - "B1N3VINDX","B1N3VINDY","B1N3VREL ","B1N3VUNDX","B1N3VUNDY","B1N3VUNDZ","B1N4ALPHA","B1N4AXIND", & - "B1N4CD ","B1N4CL ","B1N4CLRNC","B1N4CM ","B1N4CN ","B1N4CPMIN","B1N4CT ","B1N4CURVE", & - "B1N4CX ","B1N4CY ","B1N4DYNP ","B1N4FD ","B1N4FL ","B1N4FN ","B1N4FT ","B1N4FX ", & - "B1N4FY ","B1N4GAM ","B1N4M ","B1N4MM ","B1N4PHI ","B1N4RE ","B1N4SGCAV","B1N4SIGCR", & - "B1N4STVX ","B1N4STVY ","B1N4STVZ ","B1N4THETA","B1N4TNIND","B1N4VDISX","B1N4VDISY","B1N4VDISZ", & - "B1N4VINDX","B1N4VINDY","B1N4VREL ","B1N4VUNDX","B1N4VUNDY","B1N4VUNDZ","B1N5ALPHA","B1N5AXIND", & - "B1N5CD ","B1N5CL ","B1N5CLRNC","B1N5CM ","B1N5CN ","B1N5CPMIN","B1N5CT ","B1N5CURVE", & - "B1N5CX ","B1N5CY ","B1N5DYNP ","B1N5FD ","B1N5FL ","B1N5FN ","B1N5FT ","B1N5FX ", & - "B1N5FY ","B1N5GAM ","B1N5M ","B1N5MM ","B1N5PHI ","B1N5RE ","B1N5SGCAV","B1N5SIGCR", & - "B1N5STVX ","B1N5STVY ","B1N5STVZ ","B1N5THETA","B1N5TNIND","B1N5VDISX","B1N5VDISY","B1N5VDISZ", & - "B1N5VINDX","B1N5VINDY","B1N5VREL ","B1N5VUNDX","B1N5VUNDY","B1N5VUNDZ","B1N6ALPHA","B1N6AXIND", & - "B1N6CD ","B1N6CL ","B1N6CLRNC","B1N6CM ","B1N6CN ","B1N6CPMIN","B1N6CT ","B1N6CURVE", & - "B1N6CX ","B1N6CY ","B1N6DYNP ","B1N6FD ","B1N6FL ","B1N6FN ","B1N6FT ","B1N6FX ", & - "B1N6FY ","B1N6GAM ","B1N6M ","B1N6MM ","B1N6PHI ","B1N6RE ","B1N6SGCAV","B1N6SIGCR", & - "B1N6STVX ","B1N6STVY ","B1N6STVZ ","B1N6THETA","B1N6TNIND","B1N6VDISX","B1N6VDISY","B1N6VDISZ", & - "B1N6VINDX","B1N6VINDY","B1N6VREL ","B1N6VUNDX","B1N6VUNDY","B1N6VUNDZ","B1N7ALPHA","B1N7AXIND", & - "B1N7CD ","B1N7CL ","B1N7CLRNC","B1N7CM ","B1N7CN ","B1N7CPMIN","B1N7CT ","B1N7CURVE", & - "B1N7CX ","B1N7CY ","B1N7DYNP ","B1N7FD ","B1N7FL ","B1N7FN ","B1N7FT ","B1N7FX ", & - "B1N7FY ","B1N7GAM ","B1N7M ","B1N7MM ","B1N7PHI ","B1N7RE ","B1N7SGCAV","B1N7SIGCR", & - "B1N7STVX ","B1N7STVY ","B1N7STVZ ","B1N7THETA","B1N7TNIND","B1N7VDISX","B1N7VDISY","B1N7VDISZ", & - "B1N7VINDX","B1N7VINDY","B1N7VREL ","B1N7VUNDX","B1N7VUNDY","B1N7VUNDZ","B1N8ALPHA","B1N8AXIND", & - "B1N8CD ","B1N8CL ","B1N8CLRNC","B1N8CM ","B1N8CN ","B1N8CPMIN","B1N8CT ","B1N8CURVE", & - "B1N8CX ","B1N8CY ","B1N8DYNP ","B1N8FD ","B1N8FL ","B1N8FN ","B1N8FT ","B1N8FX ", & - "B1N8FY ","B1N8GAM ","B1N8M ","B1N8MM ","B1N8PHI ","B1N8RE ","B1N8SGCAV","B1N8SIGCR", & - "B1N8STVX ","B1N8STVY ","B1N8STVZ ","B1N8THETA","B1N8TNIND","B1N8VDISX","B1N8VDISY","B1N8VDISZ", & - "B1N8VINDX","B1N8VINDY","B1N8VREL ","B1N8VUNDX","B1N8VUNDY","B1N8VUNDZ","B1N9ALPHA","B1N9AXIND", & - "B1N9CD ","B1N9CL ","B1N9CLRNC","B1N9CM ","B1N9CN ","B1N9CPMIN","B1N9CT ","B1N9CURVE", & - "B1N9CX ","B1N9CY ","B1N9DYNP ","B1N9FD ","B1N9FL ","B1N9FN ","B1N9FT ","B1N9FX ", & - "B1N9FY ","B1N9GAM ","B1N9M ","B1N9MM ","B1N9PHI ","B1N9RE ","B1N9SGCAV","B1N9SIGCR", & - "B1N9STVX ","B1N9STVY ","B1N9STVZ ","B1N9THETA","B1N9TNIND","B1N9VDISX","B1N9VDISY","B1N9VDISZ", & - "B1N9VINDX","B1N9VINDY","B1N9VREL ","B1N9VUNDX","B1N9VUNDY","B1N9VUNDZ","B1PITCH ","B2AEROFX ", & - "B2AEROFXG","B2AEROFY ","B2AEROFYG","B2AEROFZ ","B2AEROFZG","B2AEROMX ","B2AEROMXG","B2AEROMY ", & - "B2AEROMYG","B2AEROMZ ","B2AEROMZG","B2AEROPWR","B2AZIMUTH","B2N1ALPHA","B2N1AXIND","B2N1CD ", & - "B2N1CL ","B2N1CLRNC","B2N1CM ","B2N1CN ","B2N1CPMIN","B2N1CT ","B2N1CURVE","B2N1CX ", & - "B2N1CY ","B2N1DYNP ","B2N1FD ","B2N1FL ","B2N1FN ","B2N1FT ","B2N1FX ","B2N1FY ", & - "B2N1GAM ","B2N1M ","B2N1MM ","B2N1PHI ","B2N1RE ","B2N1SGCAV","B2N1SIGCR","B2N1STVX ", & - "B2N1STVY ","B2N1STVZ ","B2N1THETA","B2N1TNIND","B2N1VDISX","B2N1VDISY","B2N1VDISZ","B2N1VINDX", & - "B2N1VINDY","B2N1VREL ","B2N1VUNDX","B2N1VUNDY","B2N1VUNDZ","B2N2ALPHA","B2N2AXIND","B2N2CD ", & - "B2N2CL ","B2N2CLRNC","B2N2CM ","B2N2CN ","B2N2CPMIN","B2N2CT ","B2N2CURVE","B2N2CX ", & - "B2N2CY ","B2N2DYNP ","B2N2FD ","B2N2FL ","B2N2FN ","B2N2FT ","B2N2FX ","B2N2FY ", & - "B2N2GAM ","B2N2M ","B2N2MM ","B2N2PHI ","B2N2RE ","B2N2SGCAV","B2N2SIGCR","B2N2STVX ", & - "B2N2STVY ","B2N2STVZ ","B2N2THETA","B2N2TNIND","B2N2VDISX","B2N2VDISY","B2N2VDISZ","B2N2VINDX", & - "B2N2VINDY","B2N2VREL ","B2N2VUNDX","B2N2VUNDY","B2N2VUNDZ","B2N3ALPHA","B2N3AXIND","B2N3CD ", & - "B2N3CL ","B2N3CLRNC","B2N3CM ","B2N3CN ","B2N3CPMIN","B2N3CT ","B2N3CURVE","B2N3CX ", & - "B2N3CY ","B2N3DYNP ","B2N3FD ","B2N3FL ","B2N3FN ","B2N3FT ","B2N3FX ","B2N3FY ", & - "B2N3GAM ","B2N3M ","B2N3MM ","B2N3PHI ","B2N3RE ","B2N3SGCAV","B2N3SIGCR","B2N3STVX ", & - "B2N3STVY ","B2N3STVZ ","B2N3THETA","B2N3TNIND","B2N3VDISX","B2N3VDISY","B2N3VDISZ","B2N3VINDX", & - "B2N3VINDY","B2N3VREL ","B2N3VUNDX","B2N3VUNDY","B2N3VUNDZ","B2N4ALPHA","B2N4AXIND","B2N4CD ", & - "B2N4CL ","B2N4CLRNC","B2N4CM ","B2N4CN ","B2N4CPMIN","B2N4CT ","B2N4CURVE","B2N4CX ", & - "B2N4CY ","B2N4DYNP ","B2N4FD ","B2N4FL ","B2N4FN ","B2N4FT ","B2N4FX ","B2N4FY ", & - "B2N4GAM ","B2N4M ","B2N4MM ","B2N4PHI ","B2N4RE ","B2N4SGCAV","B2N4SIGCR","B2N4STVX ", & - "B2N4STVY ","B2N4STVZ ","B2N4THETA","B2N4TNIND","B2N4VDISX","B2N4VDISY","B2N4VDISZ","B2N4VINDX", & - "B2N4VINDY","B2N4VREL ","B2N4VUNDX","B2N4VUNDY","B2N4VUNDZ","B2N5ALPHA","B2N5AXIND","B2N5CD ", & - "B2N5CL ","B2N5CLRNC","B2N5CM ","B2N5CN ","B2N5CPMIN","B2N5CT ","B2N5CURVE","B2N5CX ", & - "B2N5CY ","B2N5DYNP ","B2N5FD ","B2N5FL ","B2N5FN ","B2N5FT ","B2N5FX ","B2N5FY ", & - "B2N5GAM ","B2N5M ","B2N5MM ","B2N5PHI ","B2N5RE ","B2N5SGCAV","B2N5SIGCR","B2N5STVX ", & - "B2N5STVY ","B2N5STVZ ","B2N5THETA","B2N5TNIND","B2N5VDISX","B2N5VDISY","B2N5VDISZ","B2N5VINDX", & - "B2N5VINDY","B2N5VREL ","B2N5VUNDX","B2N5VUNDY","B2N5VUNDZ","B2N6ALPHA","B2N6AXIND","B2N6CD ", & - "B2N6CL ","B2N6CLRNC","B2N6CM ","B2N6CN ","B2N6CPMIN","B2N6CT ","B2N6CURVE","B2N6CX ", & - "B2N6CY ","B2N6DYNP ","B2N6FD ","B2N6FL ","B2N6FN ","B2N6FT ","B2N6FX ","B2N6FY ", & - "B2N6GAM ","B2N6M ","B2N6MM ","B2N6PHI ","B2N6RE ","B2N6SGCAV","B2N6SIGCR","B2N6STVX ", & - "B2N6STVY ","B2N6STVZ ","B2N6THETA","B2N6TNIND","B2N6VDISX","B2N6VDISY","B2N6VDISZ","B2N6VINDX", & - "B2N6VINDY","B2N6VREL ","B2N6VUNDX","B2N6VUNDY","B2N6VUNDZ","B2N7ALPHA","B2N7AXIND","B2N7CD ", & - "B2N7CL ","B2N7CLRNC","B2N7CM ","B2N7CN ","B2N7CPMIN","B2N7CT ","B2N7CURVE","B2N7CX ", & - "B2N7CY ","B2N7DYNP ","B2N7FD ","B2N7FL ","B2N7FN ","B2N7FT ","B2N7FX ","B2N7FY ", & - "B2N7GAM ","B2N7M ","B2N7MM ","B2N7PHI ","B2N7RE ","B2N7SGCAV","B2N7SIGCR","B2N7STVX ", & - "B2N7STVY ","B2N7STVZ ","B2N7THETA","B2N7TNIND","B2N7VDISX","B2N7VDISY","B2N7VDISZ","B2N7VINDX", & - "B2N7VINDY","B2N7VREL ","B2N7VUNDX","B2N7VUNDY","B2N7VUNDZ","B2N8ALPHA","B2N8AXIND","B2N8CD ", & - "B2N8CL ","B2N8CLRNC","B2N8CM ","B2N8CN ","B2N8CPMIN","B2N8CT ","B2N8CURVE","B2N8CX ", & - "B2N8CY ","B2N8DYNP ","B2N8FD ","B2N8FL ","B2N8FN ","B2N8FT ","B2N8FX ","B2N8FY ", & - "B2N8GAM ","B2N8M ","B2N8MM ","B2N8PHI ","B2N8RE ","B2N8SGCAV","B2N8SIGCR","B2N8STVX ", & - "B2N8STVY ","B2N8STVZ ","B2N8THETA","B2N8TNIND","B2N8VDISX","B2N8VDISY","B2N8VDISZ","B2N8VINDX", & - "B2N8VINDY","B2N8VREL ","B2N8VUNDX","B2N8VUNDY","B2N8VUNDZ","B2N9ALPHA","B2N9AXIND","B2N9CD ", & - "B2N9CL ","B2N9CLRNC","B2N9CM ","B2N9CN ","B2N9CPMIN","B2N9CT ","B2N9CURVE","B2N9CX ", & - "B2N9CY ","B2N9DYNP ","B2N9FD ","B2N9FL ","B2N9FN ","B2N9FT ","B2N9FX ","B2N9FY ", & - "B2N9GAM ","B2N9M ","B2N9MM ","B2N9PHI ","B2N9RE ","B2N9SGCAV","B2N9SIGCR","B2N9STVX ", & - "B2N9STVY ","B2N9STVZ ","B2N9THETA","B2N9TNIND","B2N9VDISX","B2N9VDISY","B2N9VDISZ","B2N9VINDX", & - "B2N9VINDY","B2N9VREL ","B2N9VUNDX","B2N9VUNDY","B2N9VUNDZ","B2PITCH ","B3AEROFX ","B3AEROFXG", & - "B3AEROFY ","B3AEROFYG","B3AEROFZ ","B3AEROFZG","B3AEROMX ","B3AEROMXG","B3AEROMY ","B3AEROMYG", & - "B3AEROMZ ","B3AEROMZG","B3AEROPWR","B3AZIMUTH","B3N1ALPHA","B3N1AXIND","B3N1CD ","B3N1CL ", & - "B3N1CLRNC","B3N1CM ","B3N1CN ","B3N1CPMIN","B3N1CT ","B3N1CURVE","B3N1CX ","B3N1CY ", & - "B3N1DYNP ","B3N1FD ","B3N1FL ","B3N1FN ","B3N1FT ","B3N1FX ","B3N1FY ","B3N1GAM ", & - "B3N1M ","B3N1MM ","B3N1PHI ","B3N1RE ","B3N1SGCAV","B3N1SIGCR","B3N1STVX ","B3N1STVY ", & - "B3N1STVZ ","B3N1THETA","B3N1TNIND","B3N1VDISX","B3N1VDISY","B3N1VDISZ","B3N1VINDX","B3N1VINDY", & - "B3N1VREL ","B3N1VUNDX","B3N1VUNDY","B3N1VUNDZ","B3N2ALPHA","B3N2AXIND","B3N2CD ","B3N2CL ", & - "B3N2CLRNC","B3N2CM ","B3N2CN ","B3N2CPMIN","B3N2CT ","B3N2CURVE","B3N2CX ","B3N2CY ", & - "B3N2DYNP ","B3N2FD ","B3N2FL ","B3N2FN ","B3N2FT ","B3N2FX ","B3N2FY ","B3N2GAM ", & - "B3N2M ","B3N2MM ","B3N2PHI ","B3N2RE ","B3N2SGCAV","B3N2SIGCR","B3N2STVX ","B3N2STVY ", & - "B3N2STVZ ","B3N2THETA","B3N2TNIND","B3N2VDISX","B3N2VDISY","B3N2VDISZ","B3N2VINDX","B3N2VINDY", & - "B3N2VREL ","B3N2VUNDX","B3N2VUNDY","B3N2VUNDZ","B3N3ALPHA","B3N3AXIND","B3N3CD ","B3N3CL ", & - "B3N3CLRNC","B3N3CM ","B3N3CN ","B3N3CPMIN","B3N3CT ","B3N3CURVE","B3N3CX ","B3N3CY ", & - "B3N3DYNP ","B3N3FD ","B3N3FL ","B3N3FN ","B3N3FT ","B3N3FX ","B3N3FY ","B3N3GAM ", & - "B3N3M ","B3N3MM ","B3N3PHI ","B3N3RE ","B3N3SGCAV","B3N3SIGCR","B3N3STVX ","B3N3STVY ", & - "B3N3STVZ ","B3N3THETA","B3N3TNIND","B3N3VDISX","B3N3VDISY","B3N3VDISZ","B3N3VINDX","B3N3VINDY", & - "B3N3VREL ","B3N3VUNDX","B3N3VUNDY","B3N3VUNDZ","B3N4ALPHA","B3N4AXIND","B3N4CD ","B3N4CL ", & - "B3N4CLRNC","B3N4CM ","B3N4CN ","B3N4CPMIN","B3N4CT ","B3N4CURVE","B3N4CX ","B3N4CY ", & - "B3N4DYNP ","B3N4FD ","B3N4FL ","B3N4FN ","B3N4FT ","B3N4FX ","B3N4FY ","B3N4GAM ", & - "B3N4M ","B3N4MM ","B3N4PHI ","B3N4RE ","B3N4SGCAV","B3N4SIGCR","B3N4STVX ","B3N4STVY ", & - "B3N4STVZ ","B3N4THETA","B3N4TNIND","B3N4VDISX","B3N4VDISY","B3N4VDISZ","B3N4VINDX","B3N4VINDY", & - "B3N4VREL ","B3N4VUNDX","B3N4VUNDY","B3N4VUNDZ","B3N5ALPHA","B3N5AXIND","B3N5CD ","B3N5CL ", & - "B3N5CLRNC","B3N5CM ","B3N5CN ","B3N5CPMIN","B3N5CT ","B3N5CURVE","B3N5CX ","B3N5CY ", & - "B3N5DYNP ","B3N5FD ","B3N5FL ","B3N5FN ","B3N5FT ","B3N5FX ","B3N5FY ","B3N5GAM ", & - "B3N5M ","B3N5MM ","B3N5PHI ","B3N5RE ","B3N5SGCAV","B3N5SIGCR","B3N5STVX ","B3N5STVY ", & - "B3N5STVZ ","B3N5THETA","B3N5TNIND","B3N5VDISX","B3N5VDISY","B3N5VDISZ","B3N5VINDX","B3N5VINDY", & - "B3N5VREL ","B3N5VUNDX","B3N5VUNDY","B3N5VUNDZ","B3N6ALPHA","B3N6AXIND","B3N6CD ","B3N6CL ", & - "B3N6CLRNC","B3N6CM ","B3N6CN ","B3N6CPMIN","B3N6CT ","B3N6CURVE","B3N6CX ","B3N6CY ", & - "B3N6DYNP ","B3N6FD ","B3N6FL ","B3N6FN ","B3N6FT ","B3N6FX ","B3N6FY ","B3N6GAM ", & - "B3N6M ","B3N6MM ","B3N6PHI ","B3N6RE ","B3N6SGCAV","B3N6SIGCR","B3N6STVX ","B3N6STVY ", & - "B3N6STVZ ","B3N6THETA","B3N6TNIND","B3N6VDISX","B3N6VDISY","B3N6VDISZ","B3N6VINDX","B3N6VINDY", & - "B3N6VREL ","B3N6VUNDX","B3N6VUNDY","B3N6VUNDZ","B3N7ALPHA","B3N7AXIND","B3N7CD ","B3N7CL ", & - "B3N7CLRNC","B3N7CM ","B3N7CN ","B3N7CPMIN","B3N7CT ","B3N7CURVE","B3N7CX ","B3N7CY ", & - "B3N7DYNP ","B3N7FD ","B3N7FL ","B3N7FN ","B3N7FT ","B3N7FX ","B3N7FY ","B3N7GAM ", & - "B3N7M ","B3N7MM ","B3N7PHI ","B3N7RE ","B3N7SGCAV","B3N7SIGCR","B3N7STVX ","B3N7STVY ", & - "B3N7STVZ ","B3N7THETA","B3N7TNIND","B3N7VDISX","B3N7VDISY","B3N7VDISZ","B3N7VINDX","B3N7VINDY", & - "B3N7VREL ","B3N7VUNDX","B3N7VUNDY","B3N7VUNDZ","B3N8ALPHA","B3N8AXIND","B3N8CD ","B3N8CL ", & - "B3N8CLRNC","B3N8CM ","B3N8CN ","B3N8CPMIN","B3N8CT ","B3N8CURVE","B3N8CX ","B3N8CY ", & - "B3N8DYNP ","B3N8FD ","B3N8FL ","B3N8FN ","B3N8FT ","B3N8FX ","B3N8FY ","B3N8GAM ", & - "B3N8M ","B3N8MM ","B3N8PHI ","B3N8RE ","B3N8SGCAV","B3N8SIGCR","B3N8STVX ","B3N8STVY ", & - "B3N8STVZ ","B3N8THETA","B3N8TNIND","B3N8VDISX","B3N8VDISY","B3N8VDISZ","B3N8VINDX","B3N8VINDY", & - "B3N8VREL ","B3N8VUNDX","B3N8VUNDY","B3N8VUNDZ","B3N9ALPHA","B3N9AXIND","B3N9CD ","B3N9CL ", & - "B3N9CLRNC","B3N9CM ","B3N9CN ","B3N9CPMIN","B3N9CT ","B3N9CURVE","B3N9CX ","B3N9CY ", & - "B3N9DYNP ","B3N9FD ","B3N9FL ","B3N9FN ","B3N9FT ","B3N9FX ","B3N9FY ","B3N9GAM ", & - "B3N9M ","B3N9MM ","B3N9PHI ","B3N9RE ","B3N9SGCAV","B3N9SIGCR","B3N9STVX ","B3N9STVY ", & - "B3N9STVZ ","B3N9THETA","B3N9TNIND","B3N9VDISX","B3N9VDISY","B3N9VDISZ","B3N9VINDX","B3N9VINDY", & - "B3N9VREL ","B3N9VUNDX","B3N9VUNDY","B3N9VUNDZ","B3PITCH ","B4AEROFX ","B4AEROFXG","B4AEROFY ", & - "B4AEROFYG","B4AEROFZ ","B4AEROFZG","B4AEROMX ","B4AEROMXG","B4AEROMY ","B4AEROMYG","B4AEROMZ ", & - "B4AEROMZG","B4AEROPWR","DBEMTAU1 ","RTAEROCP ","RTAEROCQ ","RTAEROCT ","RTAEROFXG","RTAEROFXH", & - "RTAEROFYG","RTAEROFYH","RTAEROFZG","RTAEROFZH","RTAEROMXG","RTAEROMXH","RTAEROMYG","RTAEROMYH", & - "RTAEROMZG","RTAEROMZH","RTAEROPWR","RTAREA ","RTSKEW ","RTSPEED ","RTTSR ","RTVAVGXH ", & - "RTVAVGYH ","RTVAVGZH ","TWN1DYNP ","TWN1FDX ","TWN1FDY ","TWN1M ","TWN1RE ","TWN1STVX ", & - "TWN1STVY ","TWN1STVZ ","TWN1VREL ","TWN1VUNDX","TWN1VUNDY","TWN1VUNDZ","TWN2DYNP ","TWN2FDX ", & - "TWN2FDY ","TWN2M ","TWN2RE ","TWN2STVX ","TWN2STVY ","TWN2STVZ ","TWN2VREL ","TWN2VUNDX", & - "TWN2VUNDY","TWN2VUNDZ","TWN3DYNP ","TWN3FDX ","TWN3FDY ","TWN3M ","TWN3RE ","TWN3STVX ", & - "TWN3STVY ","TWN3STVZ ","TWN3VREL ","TWN3VUNDX","TWN3VUNDY","TWN3VUNDZ","TWN4DYNP ","TWN4FDX ", & - "TWN4FDY ","TWN4M ","TWN4RE ","TWN4STVX ","TWN4STVY ","TWN4STVZ ","TWN4VREL ","TWN4VUNDX", & - "TWN4VUNDY","TWN4VUNDZ","TWN5DYNP ","TWN5FDX ","TWN5FDY ","TWN5M ","TWN5RE ","TWN5STVX ", & - "TWN5STVY ","TWN5STVZ ","TWN5VREL ","TWN5VUNDX","TWN5VUNDY","TWN5VUNDZ","TWN6DYNP ","TWN6FDX ", & - "TWN6FDY ","TWN6M ","TWN6RE ","TWN6STVX ","TWN6STVY ","TWN6STVZ ","TWN6VREL ","TWN6VUNDX", & - "TWN6VUNDY","TWN6VUNDZ","TWN7DYNP ","TWN7FDX ","TWN7FDY ","TWN7M ","TWN7RE ","TWN7STVX ", & - "TWN7STVY ","TWN7STVZ ","TWN7VREL ","TWN7VUNDX","TWN7VUNDY","TWN7VUNDZ","TWN8DYNP ","TWN8FDX ", & - "TWN8FDY ","TWN8M ","TWN8RE ","TWN8STVX ","TWN8STVY ","TWN8STVZ ","TWN8VREL ","TWN8VUNDX", & - "TWN8VUNDY","TWN8VUNDZ","TWN9DYNP ","TWN9FDX ","TWN9FDY ","TWN9M ","TWN9RE ","TWN9STVX ", & - "TWN9STVY ","TWN9STVZ ","TWN9VREL ","TWN9VUNDX","TWN9VUNDY","TWN9VUNDZ"/) - INTEGER(IntKi), PARAMETER :: ParamIndxAry(1270) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) - B1AeroFx , B1AeroFxg , B1AeroFy , B1AeroFyg , B1AeroFz , B1AeroFzg , B1AeroMx , B1AeroMxg , & - B1AeroMy , B1AeroMyg , B1AeroMz , B1AeroMzg , B1AeroPwr , B1Azimuth , B1N1Alpha , B1N1AxInd , & - B1N1Cd , B1N1Cl , B1N1Clrnc , B1N1Cm , B1N1Cn , B1N1Cpmin , B1N1Ct , B1N1Curve , & - B1N1Cx , B1N1Cy , B1N1DynP , B1N1Fd , B1N1Fl , B1N1Fn , B1N1Ft , B1N1Fx , & - B1N1Fy , B1N1Gam , B1N1M , B1N1Mm , B1N1Phi , B1N1Re , B1N1SgCav , B1N1SigCr , & - B1N1STVx , B1N1STVy , B1N1STVz , B1N1Theta , B1N1TnInd , B1N1VDisx , B1N1VDisy , B1N1VDisz , & - B1N1Vindx , B1N1Vindy , B1N1VRel , B1N1VUndx , B1N1VUndy , B1N1VUndz , B1N2Alpha , B1N2AxInd , & - B1N2Cd , B1N2Cl , B1N2Clrnc , B1N2Cm , B1N2Cn , B1N2Cpmin , B1N2Ct , B1N2Curve , & - B1N2Cx , B1N2Cy , B1N2DynP , B1N2Fd , B1N2Fl , B1N2Fn , B1N2Ft , B1N2Fx , & - B1N2Fy , B1N2Gam , B1N2M , B1N2Mm , B1N2Phi , B1N2Re , B1N2SgCav , B1N2SigCr , & - B1N2STVx , B1N2STVy , B1N2STVz , B1N2Theta , B1N2TnInd , B1N2VDisx , B1N2VDisy , B1N2VDisz , & - B1N2Vindx , B1N2Vindy , B1N2VRel , B1N2VUndx , B1N2VUndy , B1N2VUndz , B1N3Alpha , B1N3AxInd , & - B1N3Cd , B1N3Cl , B1N3Clrnc , B1N3Cm , B1N3Cn , B1N3Cpmin , B1N3Ct , B1N3Curve , & - B1N3Cx , B1N3Cy , B1N3DynP , B1N3Fd , B1N3Fl , B1N3Fn , B1N3Ft , B1N3Fx , & - B1N3Fy , B1N3Gam , B1N3M , B1N3Mm , B1N3Phi , B1N3Re , B1N3SgCav , B1N3SigCr , & - B1N3STVx , B1N3STVy , B1N3STVz , B1N3Theta , B1N3TnInd , B1N3VDisx , B1N3VDisy , B1N3VDisz , & - B1N3Vindx , B1N3Vindy , B1N3VRel , B1N3VUndx , B1N3VUndy , B1N3VUndz , B1N4Alpha , B1N4AxInd , & - B1N4Cd , B1N4Cl , B1N4Clrnc , B1N4Cm , B1N4Cn , B1N4Cpmin , B1N4Ct , B1N4Curve , & - B1N4Cx , B1N4Cy , B1N4DynP , B1N4Fd , B1N4Fl , B1N4Fn , B1N4Ft , B1N4Fx , & - B1N4Fy , B1N4Gam , B1N4M , B1N4Mm , B1N4Phi , B1N4Re , B1N4SgCav , B1N4SigCr , & - B1N4STVx , B1N4STVy , B1N4STVz , B1N4Theta , B1N4TnInd , B1N4VDisx , B1N4VDisy , B1N4VDisz , & - B1N4Vindx , B1N4Vindy , B1N4VRel , B1N4VUndx , B1N4VUndy , B1N4VUndz , B1N5Alpha , B1N5AxInd , & - B1N5Cd , B1N5Cl , B1N5Clrnc , B1N5Cm , B1N5Cn , B1N5Cpmin , B1N5Ct , B1N5Curve , & - B1N5Cx , B1N5Cy , B1N5DynP , B1N5Fd , B1N5Fl , B1N5Fn , B1N5Ft , B1N5Fx , & - B1N5Fy , B1N5Gam , B1N5M , B1N5Mm , B1N5Phi , B1N5Re , B1N5SgCav , B1N5SigCr , & - B1N5STVx , B1N5STVy , B1N5STVz , B1N5Theta , B1N5TnInd , B1N5VDisx , B1N5VDisy , B1N5VDisz , & - B1N5Vindx , B1N5Vindy , B1N5VRel , B1N5VUndx , B1N5VUndy , B1N5VUndz , B1N6Alpha , B1N6AxInd , & - B1N6Cd , B1N6Cl , B1N6Clrnc , B1N6Cm , B1N6Cn , B1N6Cpmin , B1N6Ct , B1N6Curve , & - B1N6Cx , B1N6Cy , B1N6DynP , B1N6Fd , B1N6Fl , B1N6Fn , B1N6Ft , B1N6Fx , & - B1N6Fy , B1N6Gam , B1N6M , B1N6Mm , B1N6Phi , B1N6Re , B1N6SgCav , B1N6SigCr , & - B1N6STVx , B1N6STVy , B1N6STVz , B1N6Theta , B1N6TnInd , B1N6VDisx , B1N6VDisy , B1N6VDisz , & - B1N6Vindx , B1N6Vindy , B1N6VRel , B1N6VUndx , B1N6VUndy , B1N6VUndz , B1N7Alpha , B1N7AxInd , & - B1N7Cd , B1N7Cl , B1N7Clrnc , B1N7Cm , B1N7Cn , B1N7Cpmin , B1N7Ct , B1N7Curve , & - B1N7Cx , B1N7Cy , B1N7DynP , B1N7Fd , B1N7Fl , B1N7Fn , B1N7Ft , B1N7Fx , & - B1N7Fy , B1N7Gam , B1N7M , B1N7Mm , B1N7Phi , B1N7Re , B1N7SgCav , B1N7SigCr , & - B1N7STVx , B1N7STVy , B1N7STVz , B1N7Theta , B1N7TnInd , B1N7VDisx , B1N7VDisy , B1N7VDisz , & - B1N7Vindx , B1N7Vindy , B1N7VRel , B1N7VUndx , B1N7VUndy , B1N7VUndz , B1N8Alpha , B1N8AxInd , & - B1N8Cd , B1N8Cl , B1N8Clrnc , B1N8Cm , B1N8Cn , B1N8Cpmin , B1N8Ct , B1N8Curve , & - B1N8Cx , B1N8Cy , B1N8DynP , B1N8Fd , B1N8Fl , B1N8Fn , B1N8Ft , B1N8Fx , & - B1N8Fy , B1N8Gam , B1N8M , B1N8Mm , B1N8Phi , B1N8Re , B1N8SgCav , B1N8SigCr , & - B1N8STVx , B1N8STVy , B1N8STVz , B1N8Theta , B1N8TnInd , B1N8VDisx , B1N8VDisy , B1N8VDisz , & - B1N8Vindx , B1N8Vindy , B1N8VRel , B1N8VUndx , B1N8VUndy , B1N8VUndz , B1N9Alpha , B1N9AxInd , & - B1N9Cd , B1N9Cl , B1N9Clrnc , B1N9Cm , B1N9Cn , B1N9Cpmin , B1N9Ct , B1N9Curve , & - B1N9Cx , B1N9Cy , B1N9DynP , B1N9Fd , B1N9Fl , B1N9Fn , B1N9Ft , B1N9Fx , & - B1N9Fy , B1N9Gam , B1N9M , B1N9Mm , B1N9Phi , B1N9Re , B1N9SgCav , B1N9SigCr , & - B1N9STVx , B1N9STVy , B1N9STVz , B1N9Theta , B1N9TnInd , B1N9VDisx , B1N9VDisy , B1N9VDisz , & - B1N9Vindx , B1N9Vindy , B1N9VRel , B1N9VUndx , B1N9VUndy , B1N9VUndz , B1Pitch , B2AeroFx , & - B2AeroFxg , B2AeroFy , B2AeroFyg , B2AeroFz , B2AeroFzg , B2AeroMx , B2AeroMxg , B2AeroMy , & - B2AeroMyg , B2AeroMz , B2AeroMzg , B2AeroPwr , B2Azimuth , B2N1Alpha , B2N1AxInd , B2N1Cd , & - B2N1Cl , B2N1Clrnc , B2N1Cm , B2N1Cn , B2N1Cpmin , B2N1Ct , B2N1Curve , B2N1Cx , & - B2N1Cy , B2N1DynP , B2N1Fd , B2N1Fl , B2N1Fn , B2N1Ft , B2N1Fx , B2N1Fy , & - B2N1Gam , B2N1M , B2N1Mm , B2N1Phi , B2N1Re , B2N1SgCav , B2N1SigCr , B2N1STVx , & - B2N1STVy , B2N1STVz , B2N1Theta , B2N1TnInd , B2N1VDisx , B2N1VDisy , B2N1VDisz , B2N1Vindx , & - B2N1Vindy , B2N1VRel , B2N1VUndx , B2N1VUndy , B2N1VUndz , B2N2Alpha , B2N2AxInd , B2N2Cd , & - B2N2Cl , B2N2Clrnc , B2N2Cm , B2N2Cn , B2N2Cpmin , B2N2Ct , B2N2Curve , B2N2Cx , & - B2N2Cy , B2N2DynP , B2N2Fd , B2N2Fl , B2N2Fn , B2N2Ft , B2N2Fx , B2N2Fy , & - B2N2Gam , B2N2M , B2N2Mm , B2N2Phi , B2N2Re , B2N2SgCav , B2N2SigCr , B2N2STVx , & - B2N2STVy , B2N2STVz , B2N2Theta , B2N2TnInd , B2N2VDisx , B2N2VDisy , B2N2VDisz , B2N2Vindx , & - B2N2Vindy , B2N2VRel , B2N2VUndx , B2N2VUndy , B2N2VUndz , B2N3Alpha , B2N3AxInd , B2N3Cd , & - B2N3Cl , B2N3Clrnc , B2N3Cm , B2N3Cn , B2N3Cpmin , B2N3Ct , B2N3Curve , B2N3Cx , & - B2N3Cy , B2N3DynP , B2N3Fd , B2N3Fl , B2N3Fn , B2N3Ft , B2N3Fx , B2N3Fy , & - B2N3Gam , B2N3M , B2N3Mm , B2N3Phi , B2N3Re , B2N3SgCav , B2N3SigCr , B2N3STVx , & - B2N3STVy , B2N3STVz , B2N3Theta , B2N3TnInd , B2N3VDisx , B2N3VDisy , B2N3VDisz , B2N3Vindx , & - B2N3Vindy , B2N3VRel , B2N3VUndx , B2N3VUndy , B2N3VUndz , B2N4Alpha , B2N4AxInd , B2N4Cd , & - B2N4Cl , B2N4Clrnc , B2N4Cm , B2N4Cn , B2N4Cpmin , B2N4Ct , B2N4Curve , B2N4Cx , & - B2N4Cy , B2N4DynP , B2N4Fd , B2N4Fl , B2N4Fn , B2N4Ft , B2N4Fx , B2N4Fy , & - B2N4Gam , B2N4M , B2N4Mm , B2N4Phi , B2N4Re , B2N4SgCav , B2N4SigCr , B2N4STVx , & - B2N4STVy , B2N4STVz , B2N4Theta , B2N4TnInd , B2N4VDisx , B2N4VDisy , B2N4VDisz , B2N4Vindx , & - B2N4Vindy , B2N4VRel , B2N4VUndx , B2N4VUndy , B2N4VUndz , B2N5Alpha , B2N5AxInd , B2N5Cd , & - B2N5Cl , B2N5Clrnc , B2N5Cm , B2N5Cn , B2N5Cpmin , B2N5Ct , B2N5Curve , B2N5Cx , & - B2N5Cy , B2N5DynP , B2N5Fd , B2N5Fl , B2N5Fn , B2N5Ft , B2N5Fx , B2N5Fy , & - B2N5Gam , B2N5M , B2N5Mm , B2N5Phi , B2N5Re , B2N5SgCav , B2N5SigCr , B2N5STVx , & - B2N5STVy , B2N5STVz , B2N5Theta , B2N5TnInd , B2N5VDisx , B2N5VDisy , B2N5VDisz , B2N5Vindx , & - B2N5Vindy , B2N5VRel , B2N5VUndx , B2N5VUndy , B2N5VUndz , B2N6Alpha , B2N6AxInd , B2N6Cd , & - B2N6Cl , B2N6Clrnc , B2N6Cm , B2N6Cn , B2N6Cpmin , B2N6Ct , B2N6Curve , B2N6Cx , & - B2N6Cy , B2N6DynP , B2N6Fd , B2N6Fl , B2N6Fn , B2N6Ft , B2N6Fx , B2N6Fy , & - B2N6Gam , B2N6M , B2N6Mm , B2N6Phi , B2N6Re , B2N6SgCav , B2N6SigCr , B2N6STVx , & - B2N6STVy , B2N6STVz , B2N6Theta , B2N6TnInd , B2N6VDisx , B2N6VDisy , B2N6VDisz , B2N6Vindx , & - B2N6Vindy , B2N6VRel , B2N6VUndx , B2N6VUndy , B2N6VUndz , B2N7Alpha , B2N7AxInd , B2N7Cd , & - B2N7Cl , B2N7Clrnc , B2N7Cm , B2N7Cn , B2N7Cpmin , B2N7Ct , B2N7Curve , B2N7Cx , & - B2N7Cy , B2N7DynP , B2N7Fd , B2N7Fl , B2N7Fn , B2N7Ft , B2N7Fx , B2N7Fy , & - B2N7Gam , B2N7M , B2N7Mm , B2N7Phi , B2N7Re , B2N7SgCav , B2N7SigCr , B2N7STVx , & - B2N7STVy , B2N7STVz , B2N7Theta , B2N7TnInd , B2N7VDisx , B2N7VDisy , B2N7VDisz , B2N7Vindx , & - B2N7Vindy , B2N7VRel , B2N7VUndx , B2N7VUndy , B2N7VUndz , B2N8Alpha , B2N8AxInd , B2N8Cd , & - B2N8Cl , B2N8Clrnc , B2N8Cm , B2N8Cn , B2N8Cpmin , B2N8Ct , B2N8Curve , B2N8Cx , & - B2N8Cy , B2N8DynP , B2N8Fd , B2N8Fl , B2N8Fn , B2N8Ft , B2N8Fx , B2N8Fy , & - B2N8Gam , B2N8M , B2N8Mm , B2N8Phi , B2N8Re , B2N8SgCav , B2N8SigCr , B2N8STVx , & - B2N8STVy , B2N8STVz , B2N8Theta , B2N8TnInd , B2N8VDisx , B2N8VDisy , B2N8VDisz , B2N8Vindx , & - B2N8Vindy , B2N8VRel , B2N8VUndx , B2N8VUndy , B2N8VUndz , B2N9Alpha , B2N9AxInd , B2N9Cd , & - B2N9Cl , B2N9Clrnc , B2N9Cm , B2N9Cn , B2N9Cpmin , B2N9Ct , B2N9Curve , B2N9Cx , & - B2N9Cy , B2N9DynP , B2N9Fd , B2N9Fl , B2N9Fn , B2N9Ft , B2N9Fx , B2N9Fy , & - B2N9Gam , B2N9M , B2N9Mm , B2N9Phi , B2N9Re , B2N9SgCav , B2N9SigCr , B2N9STVx , & - B2N9STVy , B2N9STVz , B2N9Theta , B2N9TnInd , B2N9VDisx , B2N9VDisy , B2N9VDisz , B2N9Vindx , & - B2N9Vindy , B2N9VRel , B2N9VUndx , B2N9VUndy , B2N9VUndz , B2Pitch , B3AeroFx , B3AeroFxg , & - B3AeroFy , B3AeroFyg , B3AeroFz , B3AeroFzg , B3AeroMx , B3AeroMxg , B3AeroMy , B3AeroMyg , & - B3AeroMz , B3AeroMzg , B3AeroPwr , B3Azimuth , B3N1Alpha , B3N1AxInd , B3N1Cd , B3N1Cl , & - B3N1Clrnc , B3N1Cm , B3N1Cn , B3N1Cpmin , B3N1Ct , B3N1Curve , B3N1Cx , B3N1Cy , & - B3N1DynP , B3N1Fd , B3N1Fl , B3N1Fn , B3N1Ft , B3N1Fx , B3N1Fy , B3N1Gam , & - B3N1M , B3N1Mm , B3N1Phi , B3N1Re , B3N1SgCav , B3N1SigCr , B3N1STVx , B3N1STVy , & - B3N1STVz , B3N1Theta , B3N1TnInd , B3N1VDisx , B3N1VDisy , B3N1VDisz , B3N1Vindx , B3N1Vindy , & - B3N1VRel , B3N1VUndx , B3N1VUndy , B3N1VUndz , B3N2Alpha , B3N2AxInd , B3N2Cd , B3N2Cl , & - B3N2Clrnc , B3N2Cm , B3N2Cn , B3N2Cpmin , B3N2Ct , B3N2Curve , B3N2Cx , B3N2Cy , & - B3N2DynP , B3N2Fd , B3N2Fl , B3N2Fn , B3N2Ft , B3N2Fx , B3N2Fy , B3N2Gam , & - B3N2M , B3N2Mm , B3N2Phi , B3N2Re , B3N2SgCav , B3N2SigCr , B3N2STVx , B3N2STVy , & - B3N2STVz , B3N2Theta , B3N2TnInd , B3N2VDisx , B3N2VDisy , B3N2VDisz , B3N2Vindx , B3N2Vindy , & - B3N2VRel , B3N2VUndx , B3N2VUndy , B3N2VUndz , B3N3Alpha , B3N3AxInd , B3N3Cd , B3N3Cl , & - B3N3Clrnc , B3N3Cm , B3N3Cn , B3N3Cpmin , B3N3Ct , B3N3Curve , B3N3Cx , B3N3Cy , & - B3N3DynP , B3N3Fd , B3N3Fl , B3N3Fn , B3N3Ft , B3N3Fx , B3N3Fy , B3N3Gam , & - B3N3M , B3N3Mm , B3N3Phi , B3N3Re , B3N3SgCav , B3N3SigCr , B3N3STVx , B3N3STVy , & - B3N3STVz , B3N3Theta , B3N3TnInd , B3N3VDisx , B3N3VDisy , B3N3VDisz , B3N3Vindx , B3N3Vindy , & - B3N3VRel , B3N3VUndx , B3N3VUndy , B3N3VUndz , B3N4Alpha , B3N4AxInd , B3N4Cd , B3N4Cl , & - B3N4Clrnc , B3N4Cm , B3N4Cn , B3N4Cpmin , B3N4Ct , B3N4Curve , B3N4Cx , B3N4Cy , & - B3N4DynP , B3N4Fd , B3N4Fl , B3N4Fn , B3N4Ft , B3N4Fx , B3N4Fy , B3N4Gam , & - B3N4M , B3N4Mm , B3N4Phi , B3N4Re , B3N4SgCav , B3N4SigCr , B3N4STVx , B3N4STVy , & - B3N4STVz , B3N4Theta , B3N4TnInd , B3N4VDisx , B3N4VDisy , B3N4VDisz , B3N4Vindx , B3N4Vindy , & - B3N4VRel , B3N4VUndx , B3N4VUndy , B3N4VUndz , B3N5Alpha , B3N5AxInd , B3N5Cd , B3N5Cl , & - B3N5Clrnc , B3N5Cm , B3N5Cn , B3N5Cpmin , B3N5Ct , B3N5Curve , B3N5Cx , B3N5Cy , & - B3N5DynP , B3N5Fd , B3N5Fl , B3N5Fn , B3N5Ft , B3N5Fx , B3N5Fy , B3N5Gam , & - B3N5M , B3N5Mm , B3N5Phi , B3N5Re , B3N5SgCav , B3N5SigCr , B3N5STVx , B3N5STVy , & - B3N5STVz , B3N5Theta , B3N5TnInd , B3N5VDisx , B3N5VDisy , B3N5VDisz , B3N5Vindx , B3N5Vindy , & - B3N5VRel , B3N5VUndx , B3N5VUndy , B3N5VUndz , B3N6Alpha , B3N6AxInd , B3N6Cd , B3N6Cl , & - B3N6Clrnc , B3N6Cm , B3N6Cn , B3N6Cpmin , B3N6Ct , B3N6Curve , B3N6Cx , B3N6Cy , & - B3N6DynP , B3N6Fd , B3N6Fl , B3N6Fn , B3N6Ft , B3N6Fx , B3N6Fy , B3N6Gam , & - B3N6M , B3N6Mm , B3N6Phi , B3N6Re , B3N6SgCav , B3N6SigCr , B3N6STVx , B3N6STVy , & - B3N6STVz , B3N6Theta , B3N6TnInd , B3N6VDisx , B3N6VDisy , B3N6VDisz , B3N6Vindx , B3N6Vindy , & - B3N6VRel , B3N6VUndx , B3N6VUndy , B3N6VUndz , B3N7Alpha , B3N7AxInd , B3N7Cd , B3N7Cl , & - B3N7Clrnc , B3N7Cm , B3N7Cn , B3N7Cpmin , B3N7Ct , B3N7Curve , B3N7Cx , B3N7Cy , & - B3N7DynP , B3N7Fd , B3N7Fl , B3N7Fn , B3N7Ft , B3N7Fx , B3N7Fy , B3N7Gam , & - B3N7M , B3N7Mm , B3N7Phi , B3N7Re , B3N7SgCav , B3N7SigCr , B3N7STVx , B3N7STVy , & - B3N7STVz , B3N7Theta , B3N7TnInd , B3N7VDisx , B3N7VDisy , B3N7VDisz , B3N7Vindx , B3N7Vindy , & - B3N7VRel , B3N7VUndx , B3N7VUndy , B3N7VUndz , B3N8Alpha , B3N8AxInd , B3N8Cd , B3N8Cl , & - B3N8Clrnc , B3N8Cm , B3N8Cn , B3N8Cpmin , B3N8Ct , B3N8Curve , B3N8Cx , B3N8Cy , & - B3N8DynP , B3N8Fd , B3N8Fl , B3N8Fn , B3N8Ft , B3N8Fx , B3N8Fy , B3N8Gam , & - B3N8M , B3N8Mm , B3N8Phi , B3N8Re , B3N8SgCav , B3N8SigCr , B3N8STVx , B3N8STVy , & - B3N8STVz , B3N8Theta , B3N8TnInd , B3N8VDisx , B3N8VDisy , B3N8VDisz , B3N8Vindx , B3N8Vindy , & - B3N8VRel , B3N8VUndx , B3N8VUndy , B3N8VUndz , B3N9Alpha , B3N9AxInd , B3N9Cd , B3N9Cl , & - B3N9Clrnc , B3N9Cm , B3N9Cn , B3N9Cpmin , B3N9Ct , B3N9Curve , B3N9Cx , B3N9Cy , & - B3N9DynP , B3N9Fd , B3N9Fl , B3N9Fn , B3N9Ft , B3N9Fx , B3N9Fy , B3N9Gam , & - B3N9M , B3N9Mm , B3N9Phi , B3N9Re , B3N9SgCav , B3N9SigCr , B3N9STVx , B3N9STVy , & - B3N9STVz , B3N9Theta , B3N9TnInd , B3N9VDisx , B3N9VDisy , B3N9VDisz , B3N9Vindx , B3N9Vindy , & - B3N9VRel , B3N9VUndx , B3N9VUndy , B3N9VUndz , B3Pitch , B4AeroFx , B4AeroFxg , B4AeroFy , & - B4AeroFyg , B4AeroFz , B4AeroFzg , B4AeroMx , B4AeroMxg , B4AeroMy , B4AeroMyg , B4AeroMz , & - B4AeroMzg , B4AeroPwr , DBEMTau1 , RtAeroCp , RtAeroCq , RtAeroCt , RtAeroFxg , RtAeroFxh , & - RtAeroFyg , RtAeroFyh , RtAeroFzg , RtAeroFzh , RtAeroMxg , RtAeroMxh , RtAeroMyg , RtAeroMyh , & - RtAeroMzg , RtAeroMzh , RtAeroPwr , RtArea , RtSkew , RtSpeed , RtTSR , RtVAvgxh , & - RtVAvgyh , RtVAvgzh , TwN1DynP , TwN1Fdx , TwN1Fdy , TwN1M , TwN1Re , TwN1STVx , & - TwN1STVy , TwN1STVz , TwN1Vrel , TwN1VUndx , TwN1VUndy , TwN1VUndz , TwN2DynP , TwN2Fdx , & - TwN2Fdy , TwN2M , TwN2Re , TwN2STVx , TwN2STVy , TwN2STVz , TwN2Vrel , TwN2VUndx , & - TwN2VUndy , TwN2VUndz , TwN3DynP , TwN3Fdx , TwN3Fdy , TwN3M , TwN3Re , TwN3STVx , & - TwN3STVy , TwN3STVz , TwN3Vrel , TwN3VUndx , TwN3VUndy , TwN3VUndz , TwN4DynP , TwN4Fdx , & - TwN4Fdy , TwN4M , TwN4Re , TwN4STVx , TwN4STVy , TwN4STVz , TwN4Vrel , TwN4VUndx , & - TwN4VUndy , TwN4VUndz , TwN5DynP , TwN5Fdx , TwN5Fdy , TwN5M , TwN5Re , TwN5STVx , & - TwN5STVy , TwN5STVz , TwN5Vrel , TwN5VUndx , TwN5VUndy , TwN5VUndz , TwN6DynP , TwN6Fdx , & - TwN6Fdy , TwN6M , TwN6Re , TwN6STVx , TwN6STVy , TwN6STVz , TwN6Vrel , TwN6VUndx , & - TwN6VUndy , TwN6VUndz , TwN7DynP , TwN7Fdx , TwN7Fdy , TwN7M , TwN7Re , TwN7STVx , & - TwN7STVy , TwN7STVz , TwN7Vrel , TwN7VUndx , TwN7VUndy , TwN7VUndz , TwN8DynP , TwN8Fdx , & - TwN8Fdy , TwN8M , TwN8Re , TwN8STVx , TwN8STVy , TwN8STVz , TwN8Vrel , TwN8VUndx , & - TwN8VUndy , TwN8VUndz , TwN9DynP , TwN9Fdx , TwN9Fdy , TwN9M , TwN9Re , TwN9STVx , & - TwN9STVy , TwN9STVz , TwN9Vrel , TwN9VUndx , TwN9VUndy , TwN9VUndz /) - CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(1270) = (/ & ! This lists the units corresponding to the allowed parameters - "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & - "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(W) ","(deg) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ", & - "(N-m) ","(N-m) ","(N-m) ","(W) ","(deg) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(m^2/s)","(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & - "(N-m) ","(N-m) ","(W) ","(deg) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & - "(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & - "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & - "(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & - "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & - "(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & - "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & - "(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & - "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & - "(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & - "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & - "(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & - "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & - "(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & - "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & - "(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & - "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & - "(-) ","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & - "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(N) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & - "(N-m) ","(W) ","(s) ","(-) ","(-) ","(-) ","(N) ","(N) ", & - "(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & - "(N-m) ","(N-m) ","(W) ","(m^2) ","(deg) ","(rpm) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ", & - "(N/m) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ", & - "(N/m) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ", & - "(N/m) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ", & - "(N/m) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) "/) - + ! Initialize values ErrStat = ErrID_None @@ -3403,7 +1620,7 @@ SUBROUTINE SetOutParam(OutList, p, p_AD, ErrStat, ErrMsg ) ! 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) - InvalidOutput( BNClrnc(:,i) ) = .true. + InvalidOutput( BNClrnc(:,i) ) = .true. end do end if @@ -3411,6 +1628,45 @@ SUBROUTINE SetOutParam(OutList, p, p_AD, ErrStat, ErrMsg ) if (p_AD%WakeMod /= WakeMod_DBEMT) then InvalidOutput( DBEMTau1 ) = .true. end if + + if (.not. p%Buoyancy) then ! Invalid buoyant loads + InvalidOutput( HbFbx ) = .true. + InvalidOutput( HbFby ) = .true. + InvalidOutput( HbFbz ) = .true. + InvalidOutput( HbMbx ) = .true. + InvalidOutput( HbMby ) = .true. + InvalidOutput( HbMbz ) = .true. + InvalidOutput( NcFbx ) = .true. + InvalidOutput( NcFby ) = .true. + InvalidOutput( NcFbz ) = .true. + InvalidOutput( NcMbx ) = .true. + InvalidOutput( NcMby ) = .true. + InvalidOutput( NcMbz ) = .true. + InvalidOutput( TwNFbx ) = .true. + InvalidOutput( TwNFby ) = .true. + InvalidOutput( TwNFbz ) = .true. + InvalidOutput( TwNMbx ) = .true. + InvalidOutput( TwNMby ) = .true. + InvalidOutput( TwNMbz ) = .true. + do i = 1,size(BNFbn,2) + InvalidOutput( BNFbn(:,i) ) = .true. + end do + do i = 1,size(BNFbt,2) + InvalidOutput( BNFbt(:,i) ) = .true. + end do + do i = 1,size(BNFbs,2) + InvalidOutput( BNFbs(:,i) ) = .true. + end do + do i = 1,size(BNMbn,2) + InvalidOutput( BNMbn(:,i) ) = .true. + end do + do i = 1,size(BNMbt,2) + InvalidOutput( BNMbt(:,i) ) = .true. + end do + do i = 1,size(BNMbs,2) + InvalidOutput( BNMbs(:,i) ) = .true. + end do + end if DO i = p%NTwOuts+1,9 ! Invalid tower nodes @@ -3422,6 +1678,12 @@ SUBROUTINE SetOutParam(OutList, p, p_AD, ErrStat, ErrMsg ) InvalidOutput( TwNM( i) ) = .true. InvalidOutput( TwNFdx( i) ) = .true. InvalidOutput( TwNFdy( i) ) = .true. + InvalidOutput( TwNFbx( i) ) = .true. + InvalidOutput( TwNFby( i) ) = .true. + InvalidOutput( TwNFbz( i) ) = .true. + InvalidOutput( TwNMbx( i) ) = .true. + InvalidOutput( TwNMby( i) ) = .true. + InvalidOutput( TwNMbz( i) ) = .true. END DO @@ -3475,6 +1737,12 @@ SUBROUTINE SetOutParam(OutList, p, p_AD, ErrStat, ErrMsg ) InvalidOutput( BAeroMx( i) ) = .true. InvalidOutput( BAeroMy( i) ) = .true. InvalidOutput( BAeroMz( i) ) = .true. + InvalidOutput( BNFbn( :,i) ) = .true. + InvalidOutput( BNFbt( :,i) ) = .true. + InvalidOutput( BNFbs( :,i) ) = .true. + InvalidOutput( BNMbn( :,i) ) = .true. + InvalidOutput( BNMbt( :,i) ) = .true. + InvalidOutput( BNMbs( :,i) ) = .true. END DO @@ -3520,9 +1788,15 @@ SUBROUTINE SetOutParam(OutList, p, p_AD, ErrStat, ErrMsg ) InvalidOutput( BNSgCav(i,:) ) = .true. InvalidOutput( BNSigCr(i,:) ) = .true. InvalidOutput( BNCpMin(i,:) ) = .true. + InvalidOutput( BNFbn( i,:) ) = .true. + InvalidOutput( BNFbt( i,:) ) = .true. + InvalidOutput( BNFbs( i,:) ) = .true. + InvalidOutput( BNMbn( i,:) ) = .true. + InvalidOutput( BNMbt( i,:) ) = .true. + InvalidOutput( BNMbs( i,:) ) = .true. - END DO - + END DO + ! ................. End of validity checking ................. @@ -3551,39 +1825,8 @@ SUBROUTINE SetOutParam(OutList, p, p_AD, ErrStat, ErrMsg ) 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:OutStrLenM1), ValidParamAry ) - - - ! If it started with an "M" (CheckOutListAgain) we didn't find the value in our list (Indx < 1) - - 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:OutStrLenM1), ValidParamAry ) - END IF + Indx = FindValidChannelIndx(OutList(I), ValidParamAry, p%OutParam(I)%SignM) IF ( Indx > 0 ) THEN ! we found the channel name IF ( InvalidOutput( ParamIndxAry(Indx) ) ) THEN ! but, it isn't valid for these settings @@ -3598,18 +1841,676 @@ SUBROUTINE SetOutParam(OutList, p, p_AD, ErrStat, ErrMsg ) p%OutParam(I)%Indx = 0 ! pick any valid channel (I just picked "Time=0" here because it's universal) p%OutParam(I)%Units = "INVALID" p%OutParam(I)%SignM = 0 ! multiply all results by zero - + CALL SetErrStat(ErrID_Fatal, TRIM(p%OutParam(I)%Name)//" is not an available output channel.",ErrStat,ErrMsg,RoutineName) END IF - + END DO - + RETURN END SUBROUTINE SetOutParam !---------------------------------------------------------------------------------------------------------------------------------- !End of code generated by Matlab script !********************************************************************************************************************************** +!---------------------------------------------------------------------------------------------------------------------------------- +!> This subroutine sets up the information needed for plotting VTK surfaces. +subroutine AD_SetVTKSurface(InitOutData_AD, u_AD, VTK_Surface, errStat, errMsg) + type(AD_InitOutputType), intent(inout) :: InitOutData_AD !< The initialization output from AeroDyn + type(AD_InputType), target, intent(in ) :: u_AD + type(AD_VTK_RotSurfaceType), allocatable, intent(inout) :: VTK_Surface(:) ! VTK_Surface for each rotor + integer(IntKi), intent( out) :: errStat !< Error status of the operation + character(*), intent( out) :: errMsg !< Error message if errStat /= ErrID_None + real(SiKi) :: TwrDiam_top, TwrDiam_base, TwrRatio, TwrLength + integer(IntKi) :: topNode, baseNode, cylNode, tipNode, rootNode + integer(IntKi) :: k + character(1024) :: vtkroot + integer(IntKi) :: iWT + integer(IntKi) :: errStat2 + character(ErrMsgLen) :: errMsg2 + type(MeshType), pointer :: Mesh + integer(IntKi) :: nBlades + integer(IntKi) :: nWT + errStat = ErrID_None + errMsg = "" + + if (allocated(VTK_Surface)) then + return ! The surfaces were already computed (for combined cases) + endif + + nWT = size(u_AD%rotors) + allocate(VTK_Surface(nWT),stat=errStat2); errMsg2='Allocating VTK_Surface'; if(Failed()) return + + ! --- Create surfaces for Nacelle, Base, Tower, Blades + do iWT=1,nWT + !....................... + ! tapered tower + !....................... + Mesh=>u_AD%rotors(iWT)%TowerMotion + if(associated(Mesh)) then + if (Mesh%NNodes>0) then + CALL AllocAry(VTK_Surface(iWT)%TowerRad, Mesh%NNodes,'VTK_Surface(iWT)%TowerRad',errStat2,errMsg2) + topNode = Mesh%NNodes - 1 + !baseNode = Mesh%refNode + baseNode = 1 ! TODO TODO + TwrLength = TwoNorm( Mesh%position(:,topNode) - Mesh%position(:,baseNode) ) ! this is the assumed length of the tower + TwrRatio = TwrLength / 87.6_SiKi ! use ratio of the tower length to the length of the 5MW tower + TwrDiam_top = 3.87*TwrRatio + TwrDiam_base = 6.0*TwrRatio + TwrRatio = 0.5 * (TwrDiam_top - TwrDiam_base) / TwrLength + do k=1,Mesh%NNodes + TwrLength = TwoNorm( Mesh%position(:,k) - Mesh%position(:,baseNode) ) + VTK_Surface(iWT)%TowerRad(k) = 0.5*TwrDiam_Base + TwrRatio*TwrLength + end do + else + !print*,'>>>> TOWER HAS NO NODES' + ! TODO create a fake tower + CALL AllocAry(VTK_Surface(iWT)%TowerRad, 0,'VTK_Surface(iWT)%TowerRad',errStat2,errMsg2) + endif + endif + + !....................... + ! blade surfaces + !....................... + nBlades = size(u_AD%rotors(iWT)%BladeMotion) + allocate(VTK_Surface(iWT)%BladeShape(nBlades),stat=errStat2); errMsg2='Allocating BladeShape'; if(Failed()) return + if (allocated(InitOutData_AD%rotors(iWT)%BladeShape)) THEN + do k=1, nBlades + call move_alloc( InitOutData_AD%rotors(iWT)%BladeShape(k)%AirfoilCoords, VTK_Surface(iWT)%BladeShape(k)%AirfoilCoords ) + end do + else + call WrScr('Profile coordinates missing, using dummy coordinates for blade surface VTK outputs') + rootNode = 1 + do K=1, nBlades + tipNode = u_AD%rotors(iWT)%BladeMotion(K)%NNodes + cylNode = min(3,u_AD%rotors(iWT)%BladeMotion(K)%Nnodes) + call AD_SetVTKDefaultBladeParams(u_AD%rotors(iWT)%BladeMotion(K), VTK_Surface(iWT)%BladeShape(K), tipNode, rootNode, cylNode, errStat2, errMsg2, BlChord=InitOutData_AD%rotors(iWT)%BladeProps(k)%BlChord); if (Failed()) return + end do + endif + enddo ! iWT, turbines + +contains + + logical function Failed() + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'AD_SetVTKSurface') + Failed = errStat >= AbortErrLev + end function Failed + +end subroutine AD_SetVTKSurface +!---------------------------------------------------------------------------------------------------------------------------------- +!> Writes AeroDyn VTK surfaces (tower, hub, blades) +subroutine AD_WrVTK_Surfaces(u_AD, y_AD, RefPoint, VTK_Surface, VTK_count, OutFileRoot, tWidth, numSectors, HubRad) + type(AD_InputType), intent(in ) :: u_AD + type(AD_OutputType), intent(in ) :: y_AD + type(AD_VTK_RotSurfaceType), intent(in ) :: VTK_Surface(:) ! VTK_Surface for each rotor + real(SiKi), intent(in ) :: RefPoint(3) + real(SiKi), intent(in ) :: HubRad + integer(IntKi) , intent(in ) :: VTK_count + character(len=*), intent(in ) :: OutFileRoot + integer, intent(in ) :: tWidth + integer, intent(in ) :: numSectors + logical, parameter :: OutputFields = .FALSE. ! due to confusion about what fields mean on a surface, we are going to just output the basic meshes if people ask for fields + integer(IntKi) :: k + integer(IntKi) :: errStat2 + character(ErrMsgLen) :: errMSg2 + integer(IntKi) :: iWT + integer(IntKi) :: nBlades + integer(IntKi) :: nWT + character(10) :: sWT + + nWT = size(u_AD%rotors) + do iWT = 1, nWT + if (nWT==1) then + sWT = '' + else + sWT = '.T'//trim(num2lstr(iWT)) + endif + + ! Tower motions + if (u_AD%rotors(iWT)%TowerMotion%nNodes>0) then + call MeshWrVTK_Ln2Surface (RefPoint, u_AD%rotors(iWT)%TowerMotion, trim(OutFileRoot)//trim(sWT)//'.TowerSurface', & + VTK_count, OutputFields, errStat2, errMsg2, tWidth, numSectors, VTK_Surface(iWT)%TowerRad ) + endif + + nBlades = size(u_AD%rotors(iWT)%BladeMotion) + + if (nBlades>0) then + ! Hub + call MeshWrVTK_PointSurface (RefPoint, u_AD%rotors(iWT)%HubMotion, trim(OutFileRoot)//trim(sWT)//'.HubSurface', & + VTK_count, OutputFields, errStat2, errMsg2, tWidth , & + NumSegments=numSectors, radius=HubRad) + endif + + ! Blades + do K=1,nBlades + call MeshWrVTK_Ln2Surface (RefPoint, u_AD%rotors(iWT)%BladeMotion(K), trim(OutFileRoot)//trim(sWT)//'.Blade'//trim(num2lstr(k))//'Surface', & + VTK_count, OutputFields, errStat2, errMsg2, tWidth , verts=VTK_Surface(iWT)%BladeShape(K)%AirfoilCoords & + ,Sib=y_AD%rotors(iWT)%BladeLoad(k) ) + end do + enddo + +end subroutine AD_WrVTK_Surfaces +!---------------------------------------------------------------------------------------------------------------------------------- +!> Writes AeroDyn VTK Lines and points (tower, hub, blades) +subroutine AD_WrVTK_LinesPoints(u_AD, y_AD, RefPoint, VTK_count, OutFileRoot, tWidth) + type(AD_InputType), intent(in ) :: u_AD + type(AD_OutputType), intent(in ) :: y_AD + real(SiKi), intent(in ) :: RefPoint(3) + integer(IntKi), intent(in ) :: VTK_count + character(len=*), intent(in ) :: OutFileRoot + integer, intent(in ) :: tWidth + logical, parameter :: OutputFields = .TRUE. + integer(IntKi) :: k + integer(IntKi) :: errStat2 + character(ErrMsgLen) :: errMSg2 + integer(IntKi) :: iWT + integer(IntKi) :: nBlades + integer(IntKi) :: nWT + character(10) :: sWT + + nWT = size(u_AD%rotors) + do iWT = 1, nWT + if (nWT==1) then + sWT = '' + else + sWT = '.T'//trim(num2lstr(iWT)) + endif + + ! Tower motions + if (u_AD%rotors(iWT)%TowerMotion%nNodes>0) then + call MeshWrVTK(RefPoint, u_AD%rotors(iWT)%TowerMotion, trim(OutFileRoot)//trim(sWT)//'.Tower', & + VTK_count, OutputFields, errStat2, errMsg2, tWidth ) + endif + + nBlades = size(u_AD%rotors(iWT)%BladeMotion) + + if (nBlades>0) then + ! Hub + call MeshWrVTK(RefPoint, u_AD%rotors(iWT)%HubMotion, trim(OutFileRoot)//trim(sWT)//'.Hub', & + VTK_count, OutputFields, errStat2, errMsg2, tWidth ) + endif + + ! Blades + do K=1,nBlades + call MeshWrVTK(RefPoint, u_AD%rotors(iWT)%BladeMotion(K), trim(OutFileRoot)//trim(sWT)//'.Blade'//trim(num2lstr(k)), & + VTK_count, OutputFields, errStat2, errMsg2, tWidth, Sib=y_AD%rotors(iWT)%BladeLoad(k) ) + end do + enddo + +end subroutine AD_WrVTK_LinesPoints +!---------------------------------------------------------------------------------------------------------------------------------- +!> This subroutine comes up with some default airfoils for blade surfaces for a given blade mesh, M. +SUBROUTINE AD_SetVTKDefaultBladeParams(M, BladeShape, tipNode, rootNode, cylNode, errStat, errMsg, BlChord) + TYPE(MeshType), INTENT(IN ) :: M !< The Mesh the defaults should be calculated for + TYPE(AD_VTK_BLSurfaceType), INTENT(INOUT) :: BladeShape !< BladeShape to set to default values + INTEGER(IntKi), INTENT(IN ) :: rootNode !< Index of root node (innermost node) for this mesh + INTEGER(IntKi), INTENT(IN ) :: tipNode !< Index of tip node (outermost node) for this mesh + INTEGER(IntKi), INTENT(IN ) :: cylNode !< Index of last node to have a cylinder shape + INTEGER(IntKi), INTENT( OUT) :: errStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: errMsg !< Error message if errStat /= ErrID_None + REAL(ReKi), OPTIONAL, INTENT(IN ) :: BlChord(:) + REAL(SiKi) :: bladeLength, chord, pitchAxis + REAL(SiKi) :: bladeLengthFract, bladeLengthFract2, ratio, posLength ! temporary quantities + REAL(SiKi) :: cylinderLength, x, y, angle + INTEGER(IntKi) :: i, j + INTEGER(IntKi) :: errStat2 + CHARACTER(ErrMsgLen) :: errMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SetVTKDefaultBladeParams' + integer, parameter :: N = 66 + ! default airfoil shape coordinates; uses S809 values from http://wind.nrel.gov/airfoils/Shapes/S809_Shape.html: + real, parameter, dimension(N) :: xc=(/ 1.0,0.996203,0.98519,0.967844,0.945073,0.917488,0.885293,0.848455,0.80747,0.763042,0.715952,0.667064,0.617331,0.56783,0.519832,0.474243,0.428461,0.382612,0.33726,0.29297,0.250247,0.209576,0.171409,0.136174,0.104263,0.076035,0.051823,0.03191,0.01659,0.006026,0.000658,0.000204,0.0,0.000213,0.001045,0.001208,0.002398,0.009313,0.02323,0.04232,0.065877,0.093426,0.124111,0.157653,0.193738,0.231914,0.271438,0.311968,0.35337,0.395329,0.438273,0.48192,0.527928,0.576211,0.626092,0.676744,0.727211,0.776432,0.823285,0.86663,0.905365,0.938474,0.965086,0.984478,0.996141,1.0 /) + real, parameter, dimension(N) :: yc=(/ 0.0,0.000487,0.002373,0.00596,0.011024,0.017033,0.023458,0.03028,0.037766,0.045974,0.054872,0.064353,0.074214,0.084095,0.093268,0.099392,0.10176,0.10184,0.10007,0.096703,0.091908,0.085851,0.078687,0.07058,0.061697,0.052224,0.042352,0.032299,0.02229,0.012615,0.003723,0.001942,-0.00002,-0.001794,-0.003477,-0.003724,-0.005266,-0.011499,-0.020399,-0.030269,-0.040821,-0.051923,-0.063082,-0.07373,-0.083567,-0.092442,-0.099905,-0.105281,-0.108181,-0.108011,-0.104552,-0.097347,-0.086571,-0.073979,-0.060644,-0.047441,-0.0351,-0.024204,-0.015163,-0.008204,-0.003363,-0.000487,0.000743,0.000775,0.00029,0.0 /) + call AllocAry(BladeShape%AirfoilCoords, 2, N, M%NNodes, 'BladeShape%AirfoilCoords', errStat2, errMsg2) + CALL SetErrStat(errStat2,errMsg2,errStat,errMsg,RoutineName) + IF (errStat >= AbortErrLev) RETURN + ! Chord length and pitch axis location are given by scaling law + bladeLength = TwoNorm( M%position(:,tipNode) - M%Position(:,rootNode) ) + cylinderLength = TwoNorm( M%Position(:,cylNode) - M%Position(:,rootNode) ) + bladeLengthFract = 0.22*bladeLength + bladeLengthFract2 = bladeLength-bladeLengthFract != 0.78*bladeLength + DO i=1,M%Nnodes + posLength = TwoNorm( M%Position(:,i) - M%Position(:,rootNode) ) + IF (posLength .LE. bladeLengthFract) THEN + ratio = posLength/bladeLengthFract + chord = (0.06 + 0.02*ratio)*bladeLength + pitchAxis = 0.25 + 0.125*ratio + ELSE + chord = (0.08 - 0.06*(posLength-bladeLengthFract)/bladeLengthFract2)*bladeLength + pitchAxis = 0.375 + END IF + if(present(BlChord)) then + chord = BlChord(i) + endif + IF (posLength .LE. cylinderLength) THEN + ! create a cylinder for this node + chord = chord/2.0_SiKi + DO j=1,N + ! normalized x,y coordinates for airfoil + x = yc(j) + y = xc(j) - 0.5 + angle = ATAN2( y, x) + ! x,y coordinates for cylinder + BladeShape%AirfoilCoords(1,j,i) = chord*COS(angle) ! x (note that "chord" is really representing chord/2 here) + BladeShape%AirfoilCoords(2,j,i) = chord*SIN(angle) ! y (note that "chord" is really representing chord/2 here) + END DO + ELSE + ! create an airfoil for this node + DO j=1,N + ! normalized x,y coordinates for airfoil, assuming an upwind turbine + x = yc(j) + y = xc(j) - pitchAxis + ! x,y coordinates for airfoil + BladeShape%AirfoilCoords(1,j,i) = chord*x + BladeShape%AirfoilCoords(2,j,i) = chord*y + END DO + END IF + END DO ! nodes on mesh + +END SUBROUTINE AD_SetVTKDefaultBladeParams + + +subroutine calcCantAngle(f, xi,stencilSize,n,cantAngle) +! This subroutine calculates implicit cant angle based on the blade reference line that includes prebend. + implicit none + integer(IntKi), intent(in) :: stencilSize, n + integer(IntKi) :: i, j + integer(IntKi) :: sortInd(n) + integer(IntKi) :: info + real(ReKi), intent(in) :: f(n), xi(n) + real(ReKi) :: cx(stencilSize), cf(stencilSize), xiIn(stencilSize) + real(ReKi) :: fIn(stencilSize), cPrime(n), fPrime(n), xiAbs(n) + real(ReKi), intent(inout) :: cantAngle(n) + + do i = 1,size(xi) + + xiAbs = abs(xi-xi(i)) + call hpsort_eps_epw (n, xiAbs, sortInd, 1e-6) + + if (i.eq.1) then + fIn = f(1:stencilSize) + xiIn = xi(1:stencilSize) + call differ_stencil ( xi(i), 1, 2, xiIn, cx, info ) + if (info /= 0) return ! use default cantAngle in this case + call differ_stencil ( xi(i), 1, 2, fIn, cf, info ) + if (info /= 0) return ! use default cantAngle in this case + elseif (i.eq.size(xi)) then + fIn = f(size(xi)-stencilSize +1:size(xi)) + xiIn = xi(size(xi)-stencilSize+1:size(xi)) + call differ_stencil ( xi(i), 1, 2, xiIn, cx, info ) + if (info /= 0) return ! use default cantAngle in this case + call differ_stencil ( xi(i), 1, 2, fIn, cf, info ) + if (info /= 0) return ! use default cantAngle in this case + else + fIn = f(i-1:i+1) + xiIn = xi(i-1:i+1) + call differ_stencil ( xi(i), 1, 2, xiIn, cx, info ) + if (info /= 0) return ! use default cantAngle in this case + call differ_stencil ( xi(i), 1, 2, fIn, cf, info ) + if (info /= 0) return ! use default cantAngle in this case + endif + + cPrime(i) = 0.0 + fPrime(i) = 0.0 + + do j = 1,size(cx) + cPrime(i) = cPrime(i) + cx(j)*xiIn(j) + fPrime(i) = fPrime(i) + cx(j)*fIn(j) + end do + cantAngle(i) = atan2(fPrime(i),cPrime(i))*180_ReKi/pi + end do + +end subroutine calcCantAngle + + + +subroutine differ_stencil ( x0, o, p, x, c, info ) + +!*****************************************************************************80 +! +!! DIFFER_STENCIL computes finite difference coefficients. +! +! Discussion: +! +! We determine coefficients C to approximate the derivative at X0 +! of order O and precision P, using finite differences, so that +! +! d^o f(x)/dx^o (x0) = sum ( 0 <= i <= o+p-1 ) c(i) f(x(i)) +! + O(h^(p)) +! +! where H is the maximum spacing between X0 and any X(I). +! +! Licensing: +! +! This code is distributed under the GNU LGPL license. +! +! Modified: +! +! 10 November 2013 +! +! Author: +! +! John Burkardt +! +! Parameters: +! +! Input, real ( kind = 8 ) X0, the point where the derivative is to +! be approximated. +! +! Input, integer ( kind = 4 ) O, the order of the derivative to be +! approximated. 1 <= O. +! +! Input, integer ( kind = 4 ) P, the order of the error, as a power of H. +! +! Input, real ( kind = 8 ) X(O+P), the evaluation points. +! +! Output, real ( kind = 8 ) C(O+P), the coefficients. +! + implicit none + + integer(IntKi), intent(in) :: o + integer(IntKi), intent(in) :: p + + real(ReKi) :: b(o+p) + real(ReKi), intent(out) :: c(o+p) + real(ReKi) :: dx(o+p) + integer(IntKi) :: i + integer(IntKi), intent(out) :: info + integer(IntKi) :: job + integer(IntKi) :: n + real(R8Ki) :: r8_factorial + real(ReKi), intent(in) :: x(o+p) + real(ReKi), intent(in) :: x0 + + n = o + p + + dx(1:n) = x(1:n) - x0 + + b(1:o+p) = 0.0D+00 + b(o+1) = 1.0D+00 + + job = 0 + call r8vm_sl ( n, dx, b, c, job, info ) + + if ( info /= 0 ) then + call WrScr('DIFFER_STENCIL: Vandermonde linear system is singular.') + return + end if + r8_factorial = 1.0D+00 + do i = 1,o + r8_factorial = r8_factorial*i + end do + c(1:n) = c(1:n) * r8_factorial + + return + +end subroutine differ_stencil + +subroutine r8vm_sl ( n, a, b, x, job, info ) + +!*****************************************************************************80 +! +!! R8VM_SL solves an R8VM linear system. +! +! Discussion: +! +! The R8VM storage format is used for an M by N Vandermonde matrix. +! An M by N Vandermonde matrix is defined by the values in its second +! row, which will be written here as X(1:N). The matrix has a first +! row of 1's, a second row equal to X(1:N), a third row whose entries +! are the squares of the X values, up to the M-th row whose entries +! are the (M-1)th powers of the X values. The matrix can be stored +! compactly by listing just the values X(1:N). +! +! Vandermonde systems are very close to singularity. The singularity +! gets worse as N increases, and as any pair of values defining +! the matrix get close. Even a system as small as N = 10 will +! involve the 9th power of the defining values. +! +! Licensing: +! +! This code is distributed under the GNU LGPL license. +! +! Modified: +! +! 29 September 2003 +! +! Author: +! +! John Burkardt. +! +! Reference: +! +! Gene Golub, Charles Van Loan, +! Matrix Computations, +! Third Edition, +! Johns Hopkins, 1996. +! +! Parameters: +! +! Input, integer ( kind = 4 ) N, the number of rows and columns of +! the matrix. +! +! Input, real ( kind = 8 ) A(N), the R8VM matrix. +! +! Input, real ( kind = 8 ) B(N), the right hand side. +! +! Output, real ( kind = 8 ) X(N), the solution of the linear system. +! +! Input, integer ( kind = 4 ) JOB, specifies the system to solve. +! 0, solve A * x = b. +! nonzero, solve A' * x = b. +! +! Output, integer ( kind = 4 ) INFO. +! 0, no error. +! nonzero, at least two of the values in A are equal. +! + implicit none + + integer (IntKi ), intent(in) :: n + + real(ReKi), intent(in) :: a(n) + real(ReKi), intent(in) :: b(n) + integer(IntKi) :: i + integer(IntKi), intent(out) :: info + integer(IntKi) :: j + integer(IntKi), intent(in) :: job + real(ReKi), intent(out) :: x(n) +! +! Check for explicit singularity. +! + info = 0 + + do j = 1, n - 1 + do i = j + 1, n + if ( a(i) == a(j) ) then + info = 1 + return + end if + end do + end do + + x(1:n) = b(1:n) + + if ( job == 0 ) then + + do j = 1, n - 1 + do i = n, j + 1, -1 + x(i) = x(i) - a(j) * x(i-1) + end do + end do + do j = n - 1, 1, -1 + + do i = j + 1, n + x(i) = x(i) / ( a(i) - a(i-j) ) + end do + + do i = j, n - 1 + x(i) = x(i) - x(i+1) + end do + end do + + else + + do j = 1, n - 1 + do i = n, j + 1, -1 + x(i) = ( x(i) - x(i-1) ) / ( a(i) - a(i-j) ) + end do + end do + + do j = n - 1, 1, -1 + do i = j, n - 1 + x(i) = x(i) - x(i+1) * a(j) + end do + end do + + end if + + return +end subroutine r8vm_sl + +! + ! Copyright (C) 2010-2016 Samuel Ponce', Roxana Margine, Carla Verdi, Feliciano Giustino + ! Copyright (C) 2007-2009 Jesse Noffsinger, Brad Malone, Feliciano Giustino + ! + ! This file is distributed under the terms of the GNU General Public + ! License. See the file `LICENSE' in the root directory of the + ! present distribution, or http://www.gnu.org/copyleft.gpl.txt . + ! + ! Adapted from flib/hpsort_eps + !--------------------------------------------------------------------- + subroutine hpsort_eps_epw (n, ra, ind, eps) + !--------------------------------------------------------------------- + ! sort an array ra(1:n) into ascending order using heapsort algorithm, + ! and considering two elements being equal if their values differ + ! for less than "eps". + ! n is input, ra is replaced on output by its sorted rearrangement. + ! create an index table (ind) by making an exchange in the index array + ! whenever an exchange is made on the sorted data array (ra). + ! in case of equal values in the data array (ra) the values in the + ! index array (ind) are used to order the entries. + ! if on input ind(1) = 0 then indices are initialized in the routine, + ! if on input ind(1) != 0 then indices are assumed to have been + ! initialized before entering the routine and these + ! indices are carried around during the sorting process + ! + ! no work space needed ! + ! free us from machine-dependent sorting-routines ! + ! + ! adapted from Numerical Recipes pg. 329 (new edition) + ! + !use kinds, ONLY : DP + implicit none + !-input/output variables + integer(IntKi), intent(in) :: n + real(ReKi), intent(in) :: eps + integer(IntKi) :: ind (n) + real(ReKi) :: ra (n) + !-local variables + integer(IntKi) :: i, ir, j, l, iind + real(ReKi) :: rra +! + ! initialize index array + IF (ind (1) .eq.0) then + DO i = 1, n + ind (i) = i + ENDDO + ENDIF + ! nothing to order + IF (n.lt.2) return + ! initialize indices for hiring and retirement-promotion phase + l = n / 2 + 1 + + ir = n + + sorting: do + + ! still in hiring phase + IF ( l .gt. 1 ) then + l = l - 1 + rra = ra (l) + iind = ind (l) + ! in retirement-promotion phase. + ELSE + ! clear a space at the end of the array + rra = ra (ir) + ! + iind = ind (ir) + ! retire the top of the heap into it + ra (ir) = ra (1) + ! + ind (ir) = ind (1) + ! decrease the size of the corporation + ir = ir - 1 + ! done with the last promotion + IF ( ir .eq. 1 ) then + ! the least competent worker at all ! + ra (1) = rra + ! + ind (1) = iind + exit sorting + ENDIF + ENDIF + ! wheter in hiring or promotion phase, we + i = l + ! set up to place rra in its proper level + j = l + l + ! + DO while ( j .le. ir ) + IF ( j .lt. ir ) then + ! compare to better underling + IF ( hslt( ra (j), ra (j + 1) ) ) then + j = j + 1 + !else if ( .not. hslt( ra (j+1), ra (j) ) ) then + ! this means ra(j) == ra(j+1) within tolerance + ! if (ind (j) .lt.ind (j + 1) ) j = j + 1 + ENDIF + ENDIF + ! demote rra + IF ( hslt( rra, ra (j) ) ) then + ra (i) = ra (j) + ind (i) = ind (j) + i = j + j = j + j + !else if ( .not. hslt ( ra(j) , rra ) ) then + !this means rra == ra(j) within tolerance + ! demote rra + ! if (iind.lt.ind (j) ) then + ! ra (i) = ra (j) + ! ind (i) = ind (j) + ! i = j + ! j = j + j + ! else + ! set j to terminate do-while loop + ! j = ir + 1 + ! endif + ! this is the right place for rra + ELSE + ! set j to terminate do-while loop + j = ir + 1 + ENDIF + ENDDO + ra (i) = rra + ind (i) = iind + + END DO sorting +contains + + ! internal function + ! compare two real number and return the result + + logical function hslt( a, b ) + REAL(ReKi) :: a, b + IF( abs(a-b) < eps ) then + hslt = .false. + ELSE + hslt = ( a < b ) + end if + end function hslt + + ! +end subroutine hpsort_eps_epw + +!---------------------------------------------------------------------------------------------------------------------------------- END MODULE AeroDyn_IO diff --git a/modules/aerodyn/src/AeroDyn_IO_Params.f90 b/modules/aerodyn/src/AeroDyn_IO_Params.f90 new file mode 100644 index 000000000..34ea81575 --- /dev/null +++ b/modules/aerodyn/src/AeroDyn_IO_Params.f90 @@ -0,0 +1,2479 @@ +module AeroDyn_IO_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 + + +! =================================================================================================== +! 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 31-Jan-2023 17:39:52. + + + ! 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 + + + ! Tower: + + INTEGER(IntKi), PARAMETER :: TwN1VUndx = 1 + INTEGER(IntKi), PARAMETER :: TwN1VUndy = 2 + INTEGER(IntKi), PARAMETER :: TwN1VUndz = 3 + INTEGER(IntKi), PARAMETER :: TwN2VUndx = 4 + INTEGER(IntKi), PARAMETER :: TwN2VUndy = 5 + INTEGER(IntKi), PARAMETER :: TwN2VUndz = 6 + INTEGER(IntKi), PARAMETER :: TwN3VUndx = 7 + INTEGER(IntKi), PARAMETER :: TwN3VUndy = 8 + INTEGER(IntKi), PARAMETER :: TwN3VUndz = 9 + INTEGER(IntKi), PARAMETER :: TwN4VUndx = 10 + INTEGER(IntKi), PARAMETER :: TwN4VUndy = 11 + INTEGER(IntKi), PARAMETER :: TwN4VUndz = 12 + INTEGER(IntKi), PARAMETER :: TwN5VUndx = 13 + INTEGER(IntKi), PARAMETER :: TwN5VUndy = 14 + INTEGER(IntKi), PARAMETER :: TwN5VUndz = 15 + INTEGER(IntKi), PARAMETER :: TwN6VUndx = 16 + INTEGER(IntKi), PARAMETER :: TwN6VUndy = 17 + INTEGER(IntKi), PARAMETER :: TwN6VUndz = 18 + INTEGER(IntKi), PARAMETER :: TwN7VUndx = 19 + INTEGER(IntKi), PARAMETER :: TwN7VUndy = 20 + INTEGER(IntKi), PARAMETER :: TwN7VUndz = 21 + INTEGER(IntKi), PARAMETER :: TwN8VUndx = 22 + INTEGER(IntKi), PARAMETER :: TwN8VUndy = 23 + INTEGER(IntKi), PARAMETER :: TwN8VUndz = 24 + INTEGER(IntKi), PARAMETER :: TwN9VUndx = 25 + INTEGER(IntKi), PARAMETER :: TwN9VUndy = 26 + INTEGER(IntKi), PARAMETER :: TwN9VUndz = 27 + INTEGER(IntKi), PARAMETER :: TwN1STVx = 28 + INTEGER(IntKi), PARAMETER :: TwN1STVy = 29 + INTEGER(IntKi), PARAMETER :: TwN1STVz = 30 + INTEGER(IntKi), PARAMETER :: TwN2STVx = 31 + INTEGER(IntKi), PARAMETER :: TwN2STVy = 32 + INTEGER(IntKi), PARAMETER :: TwN2STVz = 33 + INTEGER(IntKi), PARAMETER :: TwN3STVx = 34 + INTEGER(IntKi), PARAMETER :: TwN3STVy = 35 + INTEGER(IntKi), PARAMETER :: TwN3STVz = 36 + INTEGER(IntKi), PARAMETER :: TwN4STVx = 37 + INTEGER(IntKi), PARAMETER :: TwN4STVy = 38 + INTEGER(IntKi), PARAMETER :: TwN4STVz = 39 + INTEGER(IntKi), PARAMETER :: TwN5STVx = 40 + INTEGER(IntKi), PARAMETER :: TwN5STVy = 41 + INTEGER(IntKi), PARAMETER :: TwN5STVz = 42 + INTEGER(IntKi), PARAMETER :: TwN6STVx = 43 + INTEGER(IntKi), PARAMETER :: TwN6STVy = 44 + INTEGER(IntKi), PARAMETER :: TwN6STVz = 45 + INTEGER(IntKi), PARAMETER :: TwN7STVx = 46 + INTEGER(IntKi), PARAMETER :: TwN7STVy = 47 + INTEGER(IntKi), PARAMETER :: TwN7STVz = 48 + INTEGER(IntKi), PARAMETER :: TwN8STVx = 49 + INTEGER(IntKi), PARAMETER :: TwN8STVy = 50 + INTEGER(IntKi), PARAMETER :: TwN8STVz = 51 + INTEGER(IntKi), PARAMETER :: TwN9STVx = 52 + INTEGER(IntKi), PARAMETER :: TwN9STVy = 53 + INTEGER(IntKi), PARAMETER :: TwN9STVz = 54 + INTEGER(IntKi), PARAMETER :: TwN1Vrel = 55 + INTEGER(IntKi), PARAMETER :: TwN2Vrel = 56 + INTEGER(IntKi), PARAMETER :: TwN3Vrel = 57 + INTEGER(IntKi), PARAMETER :: TwN4Vrel = 58 + INTEGER(IntKi), PARAMETER :: TwN5Vrel = 59 + INTEGER(IntKi), PARAMETER :: TwN6Vrel = 60 + INTEGER(IntKi), PARAMETER :: TwN7Vrel = 61 + INTEGER(IntKi), PARAMETER :: TwN8Vrel = 62 + INTEGER(IntKi), PARAMETER :: TwN9Vrel = 63 + INTEGER(IntKi), PARAMETER :: TwN1DynP = 64 + INTEGER(IntKi), PARAMETER :: TwN2DynP = 65 + INTEGER(IntKi), PARAMETER :: TwN3DynP = 66 + INTEGER(IntKi), PARAMETER :: TwN4DynP = 67 + INTEGER(IntKi), PARAMETER :: TwN5DynP = 68 + INTEGER(IntKi), PARAMETER :: TwN6DynP = 69 + INTEGER(IntKi), PARAMETER :: TwN7DynP = 70 + INTEGER(IntKi), PARAMETER :: TwN8DynP = 71 + INTEGER(IntKi), PARAMETER :: TwN9DynP = 72 + INTEGER(IntKi), PARAMETER :: TwN1Re = 73 + INTEGER(IntKi), PARAMETER :: TwN2Re = 74 + INTEGER(IntKi), PARAMETER :: TwN3Re = 75 + INTEGER(IntKi), PARAMETER :: TwN4Re = 76 + INTEGER(IntKi), PARAMETER :: TwN5Re = 77 + INTEGER(IntKi), PARAMETER :: TwN6Re = 78 + INTEGER(IntKi), PARAMETER :: TwN7Re = 79 + INTEGER(IntKi), PARAMETER :: TwN8Re = 80 + INTEGER(IntKi), PARAMETER :: TwN9Re = 81 + INTEGER(IntKi), PARAMETER :: TwN1M = 82 + INTEGER(IntKi), PARAMETER :: TwN2M = 83 + INTEGER(IntKi), PARAMETER :: TwN3M = 84 + INTEGER(IntKi), PARAMETER :: TwN4M = 85 + INTEGER(IntKi), PARAMETER :: TwN5M = 86 + INTEGER(IntKi), PARAMETER :: TwN6M = 87 + INTEGER(IntKi), PARAMETER :: TwN7M = 88 + INTEGER(IntKi), PARAMETER :: TwN8M = 89 + INTEGER(IntKi), PARAMETER :: TwN9M = 90 + INTEGER(IntKi), PARAMETER :: TwN1Fdx = 91 + INTEGER(IntKi), PARAMETER :: TwN2Fdx = 92 + INTEGER(IntKi), PARAMETER :: TwN3Fdx = 93 + INTEGER(IntKi), PARAMETER :: TwN4Fdx = 94 + INTEGER(IntKi), PARAMETER :: TwN5Fdx = 95 + INTEGER(IntKi), PARAMETER :: TwN6Fdx = 96 + INTEGER(IntKi), PARAMETER :: TwN7Fdx = 97 + INTEGER(IntKi), PARAMETER :: TwN8Fdx = 98 + INTEGER(IntKi), PARAMETER :: TwN9Fdx = 99 + INTEGER(IntKi), PARAMETER :: TwN1Fdy = 100 + INTEGER(IntKi), PARAMETER :: TwN2Fdy = 101 + INTEGER(IntKi), PARAMETER :: TwN3Fdy = 102 + INTEGER(IntKi), PARAMETER :: TwN4Fdy = 103 + INTEGER(IntKi), PARAMETER :: TwN5Fdy = 104 + INTEGER(IntKi), PARAMETER :: TwN6Fdy = 105 + INTEGER(IntKi), PARAMETER :: TwN7Fdy = 106 + INTEGER(IntKi), PARAMETER :: TwN8Fdy = 107 + INTEGER(IntKi), PARAMETER :: TwN9Fdy = 108 + INTEGER(IntKi), PARAMETER :: TwN1Fbx = 109 + INTEGER(IntKi), PARAMETER :: TwN2Fbx = 110 + INTEGER(IntKi), PARAMETER :: TwN3Fbx = 111 + INTEGER(IntKi), PARAMETER :: TwN4Fbx = 112 + INTEGER(IntKi), PARAMETER :: TwN5Fbx = 113 + INTEGER(IntKi), PARAMETER :: TwN6Fbx = 114 + INTEGER(IntKi), PARAMETER :: TwN7Fbx = 115 + INTEGER(IntKi), PARAMETER :: TwN8Fbx = 116 + INTEGER(IntKi), PARAMETER :: TwN9Fbx = 117 + INTEGER(IntKi), PARAMETER :: TwN1Fby = 118 + INTEGER(IntKi), PARAMETER :: TwN2Fby = 119 + INTEGER(IntKi), PARAMETER :: TwN3Fby = 120 + INTEGER(IntKi), PARAMETER :: TwN4Fby = 121 + INTEGER(IntKi), PARAMETER :: TwN5Fby = 122 + INTEGER(IntKi), PARAMETER :: TwN6Fby = 123 + INTEGER(IntKi), PARAMETER :: TwN7Fby = 124 + INTEGER(IntKi), PARAMETER :: TwN8Fby = 125 + INTEGER(IntKi), PARAMETER :: TwN9Fby = 126 + INTEGER(IntKi), PARAMETER :: TwN1Fbz = 127 + INTEGER(IntKi), PARAMETER :: TwN2Fbz = 128 + INTEGER(IntKi), PARAMETER :: TwN3Fbz = 129 + INTEGER(IntKi), PARAMETER :: TwN4Fbz = 130 + INTEGER(IntKi), PARAMETER :: TwN5Fbz = 131 + INTEGER(IntKi), PARAMETER :: TwN6Fbz = 132 + INTEGER(IntKi), PARAMETER :: TwN7Fbz = 133 + INTEGER(IntKi), PARAMETER :: TwN8Fbz = 134 + INTEGER(IntKi), PARAMETER :: TwN9Fbz = 135 + INTEGER(IntKi), PARAMETER :: TwN1Mbx = 136 + INTEGER(IntKi), PARAMETER :: TwN2Mbx = 137 + INTEGER(IntKi), PARAMETER :: TwN3Mbx = 138 + INTEGER(IntKi), PARAMETER :: TwN4Mbx = 139 + INTEGER(IntKi), PARAMETER :: TwN5Mbx = 140 + INTEGER(IntKi), PARAMETER :: TwN6Mbx = 141 + INTEGER(IntKi), PARAMETER :: TwN7Mbx = 142 + INTEGER(IntKi), PARAMETER :: TwN8Mbx = 143 + INTEGER(IntKi), PARAMETER :: TwN9Mbx = 144 + INTEGER(IntKi), PARAMETER :: TwN1Mby = 145 + INTEGER(IntKi), PARAMETER :: TwN2Mby = 146 + INTEGER(IntKi), PARAMETER :: TwN3Mby = 147 + INTEGER(IntKi), PARAMETER :: TwN4Mby = 148 + INTEGER(IntKi), PARAMETER :: TwN5Mby = 149 + INTEGER(IntKi), PARAMETER :: TwN6Mby = 150 + INTEGER(IntKi), PARAMETER :: TwN7Mby = 151 + INTEGER(IntKi), PARAMETER :: TwN8Mby = 152 + INTEGER(IntKi), PARAMETER :: TwN9Mby = 153 + INTEGER(IntKi), PARAMETER :: TwN1Mbz = 154 + INTEGER(IntKi), PARAMETER :: TwN2Mbz = 155 + INTEGER(IntKi), PARAMETER :: TwN3Mbz = 156 + INTEGER(IntKi), PARAMETER :: TwN4Mbz = 157 + INTEGER(IntKi), PARAMETER :: TwN5Mbz = 158 + INTEGER(IntKi), PARAMETER :: TwN6Mbz = 159 + INTEGER(IntKi), PARAMETER :: TwN7Mbz = 160 + INTEGER(IntKi), PARAMETER :: TwN8Mbz = 161 + INTEGER(IntKi), PARAMETER :: TwN9Mbz = 162 + + + ! Blade: + + INTEGER(IntKi), PARAMETER :: B1Azimuth = 163 + INTEGER(IntKi), PARAMETER :: B2Azimuth = 164 + INTEGER(IntKi), PARAMETER :: B3Azimuth = 165 + INTEGER(IntKi), PARAMETER :: B1Pitch = 166 + INTEGER(IntKi), PARAMETER :: B2Pitch = 167 + INTEGER(IntKi), PARAMETER :: B3Pitch = 168 + INTEGER(IntKi), PARAMETER :: B1AeroFx = 169 + INTEGER(IntKi), PARAMETER :: B1AeroFy = 170 + INTEGER(IntKi), PARAMETER :: B1AeroFz = 171 + INTEGER(IntKi), PARAMETER :: B1AeroMx = 172 + INTEGER(IntKi), PARAMETER :: B1AeroMy = 173 + INTEGER(IntKi), PARAMETER :: B1AeroMz = 174 + INTEGER(IntKi), PARAMETER :: B1AeroPwr = 175 + INTEGER(IntKi), PARAMETER :: B2AeroFx = 176 + INTEGER(IntKi), PARAMETER :: B2AeroFy = 177 + INTEGER(IntKi), PARAMETER :: B2AeroFz = 178 + INTEGER(IntKi), PARAMETER :: B2AeroMx = 179 + INTEGER(IntKi), PARAMETER :: B2AeroMy = 180 + INTEGER(IntKi), PARAMETER :: B2AeroMz = 181 + INTEGER(IntKi), PARAMETER :: B2AeroPwr = 182 + INTEGER(IntKi), PARAMETER :: B3AeroFx = 183 + INTEGER(IntKi), PARAMETER :: B3AeroFy = 184 + INTEGER(IntKi), PARAMETER :: B3AeroFz = 185 + INTEGER(IntKi), PARAMETER :: B3AeroMx = 186 + INTEGER(IntKi), PARAMETER :: B3AeroMy = 187 + INTEGER(IntKi), PARAMETER :: B3AeroMz = 188 + INTEGER(IntKi), PARAMETER :: B3AeroPwr = 189 + INTEGER(IntKi), PARAMETER :: B4AeroFx = 190 + INTEGER(IntKi), PARAMETER :: B4AeroFy = 191 + INTEGER(IntKi), PARAMETER :: B4AeroFz = 192 + INTEGER(IntKi), PARAMETER :: B4AeroMx = 193 + INTEGER(IntKi), PARAMETER :: B4AeroMy = 194 + INTEGER(IntKi), PARAMETER :: B4AeroMz = 195 + INTEGER(IntKi), PARAMETER :: B4AeroPwr = 196 + INTEGER(IntKi), PARAMETER :: B1AeroFxg = 197 + INTEGER(IntKi), PARAMETER :: B1AeroFyg = 198 + INTEGER(IntKi), PARAMETER :: B1AeroFzg = 199 + INTEGER(IntKi), PARAMETER :: B1AeroMxg = 200 + INTEGER(IntKi), PARAMETER :: B1AeroMyg = 201 + INTEGER(IntKi), PARAMETER :: B1AeroMzg = 202 + INTEGER(IntKi), PARAMETER :: B2AeroFxg = 203 + INTEGER(IntKi), PARAMETER :: B2AeroFyg = 204 + INTEGER(IntKi), PARAMETER :: B2AeroFzg = 205 + INTEGER(IntKi), PARAMETER :: B2AeroMxg = 206 + INTEGER(IntKi), PARAMETER :: B2AeroMyg = 207 + INTEGER(IntKi), PARAMETER :: B2AeroMzg = 208 + INTEGER(IntKi), PARAMETER :: B3AeroFxg = 209 + INTEGER(IntKi), PARAMETER :: B3AeroFyg = 210 + INTEGER(IntKi), PARAMETER :: B3AeroFzg = 211 + INTEGER(IntKi), PARAMETER :: B3AeroMxg = 212 + INTEGER(IntKi), PARAMETER :: B3AeroMyg = 213 + INTEGER(IntKi), PARAMETER :: B3AeroMzg = 214 + INTEGER(IntKi), PARAMETER :: B4AeroFxg = 215 + INTEGER(IntKi), PARAMETER :: B4AeroFyg = 216 + INTEGER(IntKi), PARAMETER :: B4AeroFzg = 217 + INTEGER(IntKi), PARAMETER :: B4AeroMxg = 218 + INTEGER(IntKi), PARAMETER :: B4AeroMyg = 219 + INTEGER(IntKi), PARAMETER :: B4AeroMzg = 220 + + + ! Blade Nodal outputs: + + INTEGER(IntKi), PARAMETER :: B1N1VUndx = 221 + INTEGER(IntKi), PARAMETER :: B1N2VUndx = 222 + INTEGER(IntKi), PARAMETER :: B1N3VUndx = 223 + INTEGER(IntKi), PARAMETER :: B1N4VUndx = 224 + INTEGER(IntKi), PARAMETER :: B1N5VUndx = 225 + INTEGER(IntKi), PARAMETER :: B1N6VUndx = 226 + INTEGER(IntKi), PARAMETER :: B1N7VUndx = 227 + INTEGER(IntKi), PARAMETER :: B1N8VUndx = 228 + INTEGER(IntKi), PARAMETER :: B1N9VUndx = 229 + INTEGER(IntKi), PARAMETER :: B1N1VUndy = 230 + INTEGER(IntKi), PARAMETER :: B1N2VUndy = 231 + INTEGER(IntKi), PARAMETER :: B1N3VUndy = 232 + INTEGER(IntKi), PARAMETER :: B1N4VUndy = 233 + INTEGER(IntKi), PARAMETER :: B1N5VUndy = 234 + INTEGER(IntKi), PARAMETER :: B1N6VUndy = 235 + INTEGER(IntKi), PARAMETER :: B1N7VUndy = 236 + INTEGER(IntKi), PARAMETER :: B1N8VUndy = 237 + INTEGER(IntKi), PARAMETER :: B1N9VUndy = 238 + INTEGER(IntKi), PARAMETER :: B1N1VUndz = 239 + INTEGER(IntKi), PARAMETER :: B1N2VUndz = 240 + INTEGER(IntKi), PARAMETER :: B1N3VUndz = 241 + INTEGER(IntKi), PARAMETER :: B1N4VUndz = 242 + INTEGER(IntKi), PARAMETER :: B1N5VUndz = 243 + INTEGER(IntKi), PARAMETER :: B1N6VUndz = 244 + INTEGER(IntKi), PARAMETER :: B1N7VUndz = 245 + INTEGER(IntKi), PARAMETER :: B1N8VUndz = 246 + INTEGER(IntKi), PARAMETER :: B1N9VUndz = 247 + INTEGER(IntKi), PARAMETER :: B2N1VUndx = 248 + INTEGER(IntKi), PARAMETER :: B2N2VUndx = 249 + INTEGER(IntKi), PARAMETER :: B2N3VUndx = 250 + INTEGER(IntKi), PARAMETER :: B2N4VUndx = 251 + INTEGER(IntKi), PARAMETER :: B2N5VUndx = 252 + INTEGER(IntKi), PARAMETER :: B2N6VUndx = 253 + INTEGER(IntKi), PARAMETER :: B2N7VUndx = 254 + INTEGER(IntKi), PARAMETER :: B2N8VUndx = 255 + INTEGER(IntKi), PARAMETER :: B2N9VUndx = 256 + INTEGER(IntKi), PARAMETER :: B2N1VUndy = 257 + INTEGER(IntKi), PARAMETER :: B2N2VUndy = 258 + INTEGER(IntKi), PARAMETER :: B2N3VUndy = 259 + INTEGER(IntKi), PARAMETER :: B2N4VUndy = 260 + INTEGER(IntKi), PARAMETER :: B2N5VUndy = 261 + INTEGER(IntKi), PARAMETER :: B2N6VUndy = 262 + INTEGER(IntKi), PARAMETER :: B2N7VUndy = 263 + INTEGER(IntKi), PARAMETER :: B2N8VUndy = 264 + INTEGER(IntKi), PARAMETER :: B2N9VUndy = 265 + INTEGER(IntKi), PARAMETER :: B2N1VUndz = 266 + INTEGER(IntKi), PARAMETER :: B2N2VUndz = 267 + INTEGER(IntKi), PARAMETER :: B2N3VUndz = 268 + INTEGER(IntKi), PARAMETER :: B2N4VUndz = 269 + INTEGER(IntKi), PARAMETER :: B2N5VUndz = 270 + INTEGER(IntKi), PARAMETER :: B2N6VUndz = 271 + INTEGER(IntKi), PARAMETER :: B2N7VUndz = 272 + INTEGER(IntKi), PARAMETER :: B2N8VUndz = 273 + INTEGER(IntKi), PARAMETER :: B2N9VUndz = 274 + INTEGER(IntKi), PARAMETER :: B3N1VUndx = 275 + INTEGER(IntKi), PARAMETER :: B3N2VUndx = 276 + INTEGER(IntKi), PARAMETER :: B3N3VUndx = 277 + INTEGER(IntKi), PARAMETER :: B3N4VUndx = 278 + INTEGER(IntKi), PARAMETER :: B3N5VUndx = 279 + INTEGER(IntKi), PARAMETER :: B3N6VUndx = 280 + INTEGER(IntKi), PARAMETER :: B3N7VUndx = 281 + INTEGER(IntKi), PARAMETER :: B3N8VUndx = 282 + INTEGER(IntKi), PARAMETER :: B3N9VUndx = 283 + INTEGER(IntKi), PARAMETER :: B3N1VUndy = 284 + INTEGER(IntKi), PARAMETER :: B3N2VUndy = 285 + INTEGER(IntKi), PARAMETER :: B3N3VUndy = 286 + INTEGER(IntKi), PARAMETER :: B3N4VUndy = 287 + INTEGER(IntKi), PARAMETER :: B3N5VUndy = 288 + INTEGER(IntKi), PARAMETER :: B3N6VUndy = 289 + INTEGER(IntKi), PARAMETER :: B3N7VUndy = 290 + INTEGER(IntKi), PARAMETER :: B3N8VUndy = 291 + INTEGER(IntKi), PARAMETER :: B3N9VUndy = 292 + INTEGER(IntKi), PARAMETER :: B3N1VUndz = 293 + INTEGER(IntKi), PARAMETER :: B3N2VUndz = 294 + INTEGER(IntKi), PARAMETER :: B3N3VUndz = 295 + INTEGER(IntKi), PARAMETER :: B3N4VUndz = 296 + INTEGER(IntKi), PARAMETER :: B3N5VUndz = 297 + INTEGER(IntKi), PARAMETER :: B3N6VUndz = 298 + INTEGER(IntKi), PARAMETER :: B3N7VUndz = 299 + INTEGER(IntKi), PARAMETER :: B3N8VUndz = 300 + INTEGER(IntKi), PARAMETER :: B3N9VUndz = 301 + INTEGER(IntKi), PARAMETER :: B1N1VDisx = 302 + INTEGER(IntKi), PARAMETER :: B1N2VDisx = 303 + INTEGER(IntKi), PARAMETER :: B1N3VDisx = 304 + INTEGER(IntKi), PARAMETER :: B1N4VDisx = 305 + INTEGER(IntKi), PARAMETER :: B1N5VDisx = 306 + INTEGER(IntKi), PARAMETER :: B1N6VDisx = 307 + INTEGER(IntKi), PARAMETER :: B1N7VDisx = 308 + INTEGER(IntKi), PARAMETER :: B1N8VDisx = 309 + INTEGER(IntKi), PARAMETER :: B1N9VDisx = 310 + INTEGER(IntKi), PARAMETER :: B1N1VDisy = 311 + INTEGER(IntKi), PARAMETER :: B1N2VDisy = 312 + INTEGER(IntKi), PARAMETER :: B1N3VDisy = 313 + INTEGER(IntKi), PARAMETER :: B1N4VDisy = 314 + INTEGER(IntKi), PARAMETER :: B1N5VDisy = 315 + INTEGER(IntKi), PARAMETER :: B1N6VDisy = 316 + INTEGER(IntKi), PARAMETER :: B1N7VDisy = 317 + INTEGER(IntKi), PARAMETER :: B1N8VDisy = 318 + INTEGER(IntKi), PARAMETER :: B1N9VDisy = 319 + INTEGER(IntKi), PARAMETER :: B1N1VDisz = 320 + INTEGER(IntKi), PARAMETER :: B1N2VDisz = 321 + INTEGER(IntKi), PARAMETER :: B1N3VDisz = 322 + INTEGER(IntKi), PARAMETER :: B1N4VDisz = 323 + INTEGER(IntKi), PARAMETER :: B1N5VDisz = 324 + INTEGER(IntKi), PARAMETER :: B1N6VDisz = 325 + INTEGER(IntKi), PARAMETER :: B1N7VDisz = 326 + INTEGER(IntKi), PARAMETER :: B1N8VDisz = 327 + INTEGER(IntKi), PARAMETER :: B1N9VDisz = 328 + INTEGER(IntKi), PARAMETER :: B2N1VDisx = 329 + INTEGER(IntKi), PARAMETER :: B2N2VDisx = 330 + INTEGER(IntKi), PARAMETER :: B2N3VDisx = 331 + INTEGER(IntKi), PARAMETER :: B2N4VDisx = 332 + INTEGER(IntKi), PARAMETER :: B2N5VDisx = 333 + INTEGER(IntKi), PARAMETER :: B2N6VDisx = 334 + INTEGER(IntKi), PARAMETER :: B2N7VDisx = 335 + INTEGER(IntKi), PARAMETER :: B2N8VDisx = 336 + INTEGER(IntKi), PARAMETER :: B2N9VDisx = 337 + INTEGER(IntKi), PARAMETER :: B2N1VDisy = 338 + INTEGER(IntKi), PARAMETER :: B2N2VDisy = 339 + INTEGER(IntKi), PARAMETER :: B2N3VDisy = 340 + INTEGER(IntKi), PARAMETER :: B2N4VDisy = 341 + INTEGER(IntKi), PARAMETER :: B2N5VDisy = 342 + INTEGER(IntKi), PARAMETER :: B2N6VDisy = 343 + INTEGER(IntKi), PARAMETER :: B2N7VDisy = 344 + INTEGER(IntKi), PARAMETER :: B2N8VDisy = 345 + INTEGER(IntKi), PARAMETER :: B2N9VDisy = 346 + INTEGER(IntKi), PARAMETER :: B2N1VDisz = 347 + INTEGER(IntKi), PARAMETER :: B2N2VDisz = 348 + INTEGER(IntKi), PARAMETER :: B2N3VDisz = 349 + INTEGER(IntKi), PARAMETER :: B2N4VDisz = 350 + INTEGER(IntKi), PARAMETER :: B2N5VDisz = 351 + INTEGER(IntKi), PARAMETER :: B2N6VDisz = 352 + INTEGER(IntKi), PARAMETER :: B2N7VDisz = 353 + INTEGER(IntKi), PARAMETER :: B2N8VDisz = 354 + INTEGER(IntKi), PARAMETER :: B2N9VDisz = 355 + INTEGER(IntKi), PARAMETER :: B3N1VDisx = 356 + INTEGER(IntKi), PARAMETER :: B3N2VDisx = 357 + INTEGER(IntKi), PARAMETER :: B3N3VDisx = 358 + INTEGER(IntKi), PARAMETER :: B3N4VDisx = 359 + INTEGER(IntKi), PARAMETER :: B3N5VDisx = 360 + INTEGER(IntKi), PARAMETER :: B3N6VDisx = 361 + INTEGER(IntKi), PARAMETER :: B3N7VDisx = 362 + INTEGER(IntKi), PARAMETER :: B3N8VDisx = 363 + INTEGER(IntKi), PARAMETER :: B3N9VDisx = 364 + INTEGER(IntKi), PARAMETER :: B3N1VDisy = 365 + INTEGER(IntKi), PARAMETER :: B3N2VDisy = 366 + INTEGER(IntKi), PARAMETER :: B3N3VDisy = 367 + INTEGER(IntKi), PARAMETER :: B3N4VDisy = 368 + INTEGER(IntKi), PARAMETER :: B3N5VDisy = 369 + INTEGER(IntKi), PARAMETER :: B3N6VDisy = 370 + INTEGER(IntKi), PARAMETER :: B3N7VDisy = 371 + INTEGER(IntKi), PARAMETER :: B3N8VDisy = 372 + INTEGER(IntKi), PARAMETER :: B3N9VDisy = 373 + INTEGER(IntKi), PARAMETER :: B3N1VDisz = 374 + INTEGER(IntKi), PARAMETER :: B3N2VDisz = 375 + INTEGER(IntKi), PARAMETER :: B3N3VDisz = 376 + INTEGER(IntKi), PARAMETER :: B3N4VDisz = 377 + INTEGER(IntKi), PARAMETER :: B3N5VDisz = 378 + INTEGER(IntKi), PARAMETER :: B3N6VDisz = 379 + INTEGER(IntKi), PARAMETER :: B3N7VDisz = 380 + INTEGER(IntKi), PARAMETER :: B3N8VDisz = 381 + INTEGER(IntKi), PARAMETER :: B3N9VDisz = 382 + INTEGER(IntKi), PARAMETER :: B1N1STVx = 383 + INTEGER(IntKi), PARAMETER :: B1N2STVx = 384 + INTEGER(IntKi), PARAMETER :: B1N3STVx = 385 + INTEGER(IntKi), PARAMETER :: B1N4STVx = 386 + INTEGER(IntKi), PARAMETER :: B1N5STVx = 387 + INTEGER(IntKi), PARAMETER :: B1N6STVx = 388 + INTEGER(IntKi), PARAMETER :: B1N7STVx = 389 + INTEGER(IntKi), PARAMETER :: B1N8STVx = 390 + INTEGER(IntKi), PARAMETER :: B1N9STVx = 391 + INTEGER(IntKi), PARAMETER :: B1N1STVy = 392 + INTEGER(IntKi), PARAMETER :: B1N2STVy = 393 + INTEGER(IntKi), PARAMETER :: B1N3STVy = 394 + INTEGER(IntKi), PARAMETER :: B1N4STVy = 395 + INTEGER(IntKi), PARAMETER :: B1N5STVy = 396 + INTEGER(IntKi), PARAMETER :: B1N6STVy = 397 + INTEGER(IntKi), PARAMETER :: B1N7STVy = 398 + INTEGER(IntKi), PARAMETER :: B1N8STVy = 399 + INTEGER(IntKi), PARAMETER :: B1N9STVy = 400 + INTEGER(IntKi), PARAMETER :: B1N1STVz = 401 + INTEGER(IntKi), PARAMETER :: B1N2STVz = 402 + INTEGER(IntKi), PARAMETER :: B1N3STVz = 403 + INTEGER(IntKi), PARAMETER :: B1N4STVz = 404 + INTEGER(IntKi), PARAMETER :: B1N5STVz = 405 + INTEGER(IntKi), PARAMETER :: B1N6STVz = 406 + INTEGER(IntKi), PARAMETER :: B1N7STVz = 407 + INTEGER(IntKi), PARAMETER :: B1N8STVz = 408 + INTEGER(IntKi), PARAMETER :: B1N9STVz = 409 + INTEGER(IntKi), PARAMETER :: B2N1STVx = 410 + INTEGER(IntKi), PARAMETER :: B2N2STVx = 411 + INTEGER(IntKi), PARAMETER :: B2N3STVx = 412 + INTEGER(IntKi), PARAMETER :: B2N4STVx = 413 + INTEGER(IntKi), PARAMETER :: B2N5STVx = 414 + INTEGER(IntKi), PARAMETER :: B2N6STVx = 415 + INTEGER(IntKi), PARAMETER :: B2N7STVx = 416 + INTEGER(IntKi), PARAMETER :: B2N8STVx = 417 + INTEGER(IntKi), PARAMETER :: B2N9STVx = 418 + INTEGER(IntKi), PARAMETER :: B2N1STVy = 419 + INTEGER(IntKi), PARAMETER :: B2N2STVy = 420 + INTEGER(IntKi), PARAMETER :: B2N3STVy = 421 + INTEGER(IntKi), PARAMETER :: B2N4STVy = 422 + INTEGER(IntKi), PARAMETER :: B2N5STVy = 423 + INTEGER(IntKi), PARAMETER :: B2N6STVy = 424 + INTEGER(IntKi), PARAMETER :: B2N7STVy = 425 + INTEGER(IntKi), PARAMETER :: B2N8STVy = 426 + INTEGER(IntKi), PARAMETER :: B2N9STVy = 427 + INTEGER(IntKi), PARAMETER :: B2N1STVz = 428 + INTEGER(IntKi), PARAMETER :: B2N2STVz = 429 + INTEGER(IntKi), PARAMETER :: B2N3STVz = 430 + INTEGER(IntKi), PARAMETER :: B2N4STVz = 431 + INTEGER(IntKi), PARAMETER :: B2N5STVz = 432 + INTEGER(IntKi), PARAMETER :: B2N6STVz = 433 + INTEGER(IntKi), PARAMETER :: B2N7STVz = 434 + INTEGER(IntKi), PARAMETER :: B2N8STVz = 435 + INTEGER(IntKi), PARAMETER :: B2N9STVz = 436 + INTEGER(IntKi), PARAMETER :: B3N1STVx = 437 + INTEGER(IntKi), PARAMETER :: B3N2STVx = 438 + INTEGER(IntKi), PARAMETER :: B3N3STVx = 439 + INTEGER(IntKi), PARAMETER :: B3N4STVx = 440 + INTEGER(IntKi), PARAMETER :: B3N5STVx = 441 + INTEGER(IntKi), PARAMETER :: B3N6STVx = 442 + INTEGER(IntKi), PARAMETER :: B3N7STVx = 443 + INTEGER(IntKi), PARAMETER :: B3N8STVx = 444 + INTEGER(IntKi), PARAMETER :: B3N9STVx = 445 + INTEGER(IntKi), PARAMETER :: B3N1STVy = 446 + INTEGER(IntKi), PARAMETER :: B3N2STVy = 447 + INTEGER(IntKi), PARAMETER :: B3N3STVy = 448 + INTEGER(IntKi), PARAMETER :: B3N4STVy = 449 + INTEGER(IntKi), PARAMETER :: B3N5STVy = 450 + INTEGER(IntKi), PARAMETER :: B3N6STVy = 451 + INTEGER(IntKi), PARAMETER :: B3N7STVy = 452 + INTEGER(IntKi), PARAMETER :: B3N8STVy = 453 + INTEGER(IntKi), PARAMETER :: B3N9STVy = 454 + INTEGER(IntKi), PARAMETER :: B3N1STVz = 455 + INTEGER(IntKi), PARAMETER :: B3N2STVz = 456 + INTEGER(IntKi), PARAMETER :: B3N3STVz = 457 + INTEGER(IntKi), PARAMETER :: B3N4STVz = 458 + INTEGER(IntKi), PARAMETER :: B3N5STVz = 459 + INTEGER(IntKi), PARAMETER :: B3N6STVz = 460 + INTEGER(IntKi), PARAMETER :: B3N7STVz = 461 + INTEGER(IntKi), PARAMETER :: B3N8STVz = 462 + INTEGER(IntKi), PARAMETER :: B3N9STVz = 463 + INTEGER(IntKi), PARAMETER :: B1N1VRel = 464 + INTEGER(IntKi), PARAMETER :: B1N2VRel = 465 + INTEGER(IntKi), PARAMETER :: B1N3VRel = 466 + INTEGER(IntKi), PARAMETER :: B1N4VRel = 467 + INTEGER(IntKi), PARAMETER :: B1N5VRel = 468 + INTEGER(IntKi), PARAMETER :: B1N6VRel = 469 + INTEGER(IntKi), PARAMETER :: B1N7VRel = 470 + INTEGER(IntKi), PARAMETER :: B1N8VRel = 471 + INTEGER(IntKi), PARAMETER :: B1N9VRel = 472 + INTEGER(IntKi), PARAMETER :: B2N1VRel = 473 + INTEGER(IntKi), PARAMETER :: B2N2VRel = 474 + INTEGER(IntKi), PARAMETER :: B2N3VRel = 475 + INTEGER(IntKi), PARAMETER :: B2N4VRel = 476 + INTEGER(IntKi), PARAMETER :: B2N5VRel = 477 + INTEGER(IntKi), PARAMETER :: B2N6VRel = 478 + INTEGER(IntKi), PARAMETER :: B2N7VRel = 479 + INTEGER(IntKi), PARAMETER :: B2N8VRel = 480 + INTEGER(IntKi), PARAMETER :: B2N9VRel = 481 + INTEGER(IntKi), PARAMETER :: B3N1VRel = 482 + INTEGER(IntKi), PARAMETER :: B3N2VRel = 483 + INTEGER(IntKi), PARAMETER :: B3N3VRel = 484 + INTEGER(IntKi), PARAMETER :: B3N4VRel = 485 + INTEGER(IntKi), PARAMETER :: B3N5VRel = 486 + INTEGER(IntKi), PARAMETER :: B3N6VRel = 487 + INTEGER(IntKi), PARAMETER :: B3N7VRel = 488 + INTEGER(IntKi), PARAMETER :: B3N8VRel = 489 + INTEGER(IntKi), PARAMETER :: B3N9VRel = 490 + INTEGER(IntKi), PARAMETER :: B1N1DynP = 491 + INTEGER(IntKi), PARAMETER :: B1N2DynP = 492 + INTEGER(IntKi), PARAMETER :: B1N3DynP = 493 + INTEGER(IntKi), PARAMETER :: B1N4DynP = 494 + INTEGER(IntKi), PARAMETER :: B1N5DynP = 495 + INTEGER(IntKi), PARAMETER :: B1N6DynP = 496 + INTEGER(IntKi), PARAMETER :: B1N7DynP = 497 + INTEGER(IntKi), PARAMETER :: B1N8DynP = 498 + INTEGER(IntKi), PARAMETER :: B1N9DynP = 499 + INTEGER(IntKi), PARAMETER :: B2N1DynP = 500 + INTEGER(IntKi), PARAMETER :: B2N2DynP = 501 + INTEGER(IntKi), PARAMETER :: B2N3DynP = 502 + INTEGER(IntKi), PARAMETER :: B2N4DynP = 503 + INTEGER(IntKi), PARAMETER :: B2N5DynP = 504 + INTEGER(IntKi), PARAMETER :: B2N6DynP = 505 + INTEGER(IntKi), PARAMETER :: B2N7DynP = 506 + INTEGER(IntKi), PARAMETER :: B2N8DynP = 507 + INTEGER(IntKi), PARAMETER :: B2N9DynP = 508 + INTEGER(IntKi), PARAMETER :: B3N1DynP = 509 + INTEGER(IntKi), PARAMETER :: B3N2DynP = 510 + INTEGER(IntKi), PARAMETER :: B3N3DynP = 511 + INTEGER(IntKi), PARAMETER :: B3N4DynP = 512 + INTEGER(IntKi), PARAMETER :: B3N5DynP = 513 + INTEGER(IntKi), PARAMETER :: B3N6DynP = 514 + INTEGER(IntKi), PARAMETER :: B3N7DynP = 515 + INTEGER(IntKi), PARAMETER :: B3N8DynP = 516 + INTEGER(IntKi), PARAMETER :: B3N9DynP = 517 + INTEGER(IntKi), PARAMETER :: B1N1Re = 518 + INTEGER(IntKi), PARAMETER :: B1N2Re = 519 + INTEGER(IntKi), PARAMETER :: B1N3Re = 520 + INTEGER(IntKi), PARAMETER :: B1N4Re = 521 + INTEGER(IntKi), PARAMETER :: B1N5Re = 522 + INTEGER(IntKi), PARAMETER :: B1N6Re = 523 + INTEGER(IntKi), PARAMETER :: B1N7Re = 524 + INTEGER(IntKi), PARAMETER :: B1N8Re = 525 + INTEGER(IntKi), PARAMETER :: B1N9Re = 526 + INTEGER(IntKi), PARAMETER :: B2N1Re = 527 + INTEGER(IntKi), PARAMETER :: B2N2Re = 528 + INTEGER(IntKi), PARAMETER :: B2N3Re = 529 + INTEGER(IntKi), PARAMETER :: B2N4Re = 530 + INTEGER(IntKi), PARAMETER :: B2N5Re = 531 + INTEGER(IntKi), PARAMETER :: B2N6Re = 532 + INTEGER(IntKi), PARAMETER :: B2N7Re = 533 + INTEGER(IntKi), PARAMETER :: B2N8Re = 534 + INTEGER(IntKi), PARAMETER :: B2N9Re = 535 + INTEGER(IntKi), PARAMETER :: B3N1Re = 536 + INTEGER(IntKi), PARAMETER :: B3N2Re = 537 + INTEGER(IntKi), PARAMETER :: B3N3Re = 538 + INTEGER(IntKi), PARAMETER :: B3N4Re = 539 + INTEGER(IntKi), PARAMETER :: B3N5Re = 540 + INTEGER(IntKi), PARAMETER :: B3N6Re = 541 + INTEGER(IntKi), PARAMETER :: B3N7Re = 542 + INTEGER(IntKi), PARAMETER :: B3N8Re = 543 + INTEGER(IntKi), PARAMETER :: B3N9Re = 544 + INTEGER(IntKi), PARAMETER :: B1N1M = 545 + INTEGER(IntKi), PARAMETER :: B1N2M = 546 + INTEGER(IntKi), PARAMETER :: B1N3M = 547 + INTEGER(IntKi), PARAMETER :: B1N4M = 548 + INTEGER(IntKi), PARAMETER :: B1N5M = 549 + INTEGER(IntKi), PARAMETER :: B1N6M = 550 + INTEGER(IntKi), PARAMETER :: B1N7M = 551 + INTEGER(IntKi), PARAMETER :: B1N8M = 552 + INTEGER(IntKi), PARAMETER :: B1N9M = 553 + INTEGER(IntKi), PARAMETER :: B2N1M = 554 + INTEGER(IntKi), PARAMETER :: B2N2M = 555 + INTEGER(IntKi), PARAMETER :: B2N3M = 556 + INTEGER(IntKi), PARAMETER :: B2N4M = 557 + INTEGER(IntKi), PARAMETER :: B2N5M = 558 + INTEGER(IntKi), PARAMETER :: B2N6M = 559 + INTEGER(IntKi), PARAMETER :: B2N7M = 560 + INTEGER(IntKi), PARAMETER :: B2N8M = 561 + INTEGER(IntKi), PARAMETER :: B2N9M = 562 + INTEGER(IntKi), PARAMETER :: B3N1M = 563 + INTEGER(IntKi), PARAMETER :: B3N2M = 564 + INTEGER(IntKi), PARAMETER :: B3N3M = 565 + INTEGER(IntKi), PARAMETER :: B3N4M = 566 + INTEGER(IntKi), PARAMETER :: B3N5M = 567 + INTEGER(IntKi), PARAMETER :: B3N6M = 568 + INTEGER(IntKi), PARAMETER :: B3N7M = 569 + INTEGER(IntKi), PARAMETER :: B3N8M = 570 + INTEGER(IntKi), PARAMETER :: B3N9M = 571 + INTEGER(IntKi), PARAMETER :: B1N1Vindx = 572 + INTEGER(IntKi), PARAMETER :: B1N2Vindx = 573 + INTEGER(IntKi), PARAMETER :: B1N3Vindx = 574 + INTEGER(IntKi), PARAMETER :: B1N4Vindx = 575 + INTEGER(IntKi), PARAMETER :: B1N5Vindx = 576 + INTEGER(IntKi), PARAMETER :: B1N6Vindx = 577 + INTEGER(IntKi), PARAMETER :: B1N7Vindx = 578 + INTEGER(IntKi), PARAMETER :: B1N8Vindx = 579 + INTEGER(IntKi), PARAMETER :: B1N9Vindx = 580 + INTEGER(IntKi), PARAMETER :: B2N1Vindx = 581 + INTEGER(IntKi), PARAMETER :: B2N2Vindx = 582 + INTEGER(IntKi), PARAMETER :: B2N3Vindx = 583 + INTEGER(IntKi), PARAMETER :: B2N4Vindx = 584 + INTEGER(IntKi), PARAMETER :: B2N5Vindx = 585 + INTEGER(IntKi), PARAMETER :: B2N6Vindx = 586 + INTEGER(IntKi), PARAMETER :: B2N7Vindx = 587 + INTEGER(IntKi), PARAMETER :: B2N8Vindx = 588 + INTEGER(IntKi), PARAMETER :: B2N9Vindx = 589 + INTEGER(IntKi), PARAMETER :: B3N1Vindx = 590 + INTEGER(IntKi), PARAMETER :: B3N2Vindx = 591 + INTEGER(IntKi), PARAMETER :: B3N3Vindx = 592 + INTEGER(IntKi), PARAMETER :: B3N4Vindx = 593 + INTEGER(IntKi), PARAMETER :: B3N5Vindx = 594 + INTEGER(IntKi), PARAMETER :: B3N6Vindx = 595 + INTEGER(IntKi), PARAMETER :: B3N7Vindx = 596 + INTEGER(IntKi), PARAMETER :: B3N8Vindx = 597 + INTEGER(IntKi), PARAMETER :: B3N9Vindx = 598 + INTEGER(IntKi), PARAMETER :: B1N1Vindy = 599 + INTEGER(IntKi), PARAMETER :: B1N2Vindy = 600 + INTEGER(IntKi), PARAMETER :: B1N3Vindy = 601 + INTEGER(IntKi), PARAMETER :: B1N4Vindy = 602 + INTEGER(IntKi), PARAMETER :: B1N5Vindy = 603 + INTEGER(IntKi), PARAMETER :: B1N6Vindy = 604 + INTEGER(IntKi), PARAMETER :: B1N7Vindy = 605 + INTEGER(IntKi), PARAMETER :: B1N8Vindy = 606 + INTEGER(IntKi), PARAMETER :: B1N9Vindy = 607 + INTEGER(IntKi), PARAMETER :: B2N1Vindy = 608 + INTEGER(IntKi), PARAMETER :: B2N2Vindy = 609 + INTEGER(IntKi), PARAMETER :: B2N3Vindy = 610 + INTEGER(IntKi), PARAMETER :: B2N4Vindy = 611 + INTEGER(IntKi), PARAMETER :: B2N5Vindy = 612 + INTEGER(IntKi), PARAMETER :: B2N6Vindy = 613 + INTEGER(IntKi), PARAMETER :: B2N7Vindy = 614 + INTEGER(IntKi), PARAMETER :: B2N8Vindy = 615 + INTEGER(IntKi), PARAMETER :: B2N9Vindy = 616 + INTEGER(IntKi), PARAMETER :: B3N1Vindy = 617 + INTEGER(IntKi), PARAMETER :: B3N2Vindy = 618 + INTEGER(IntKi), PARAMETER :: B3N3Vindy = 619 + INTEGER(IntKi), PARAMETER :: B3N4Vindy = 620 + INTEGER(IntKi), PARAMETER :: B3N5Vindy = 621 + INTEGER(IntKi), PARAMETER :: B3N6Vindy = 622 + INTEGER(IntKi), PARAMETER :: B3N7Vindy = 623 + INTEGER(IntKi), PARAMETER :: B3N8Vindy = 624 + INTEGER(IntKi), PARAMETER :: B3N9Vindy = 625 + INTEGER(IntKi), PARAMETER :: B1N1AxInd = 626 + INTEGER(IntKi), PARAMETER :: B1N2AxInd = 627 + INTEGER(IntKi), PARAMETER :: B1N3AxInd = 628 + INTEGER(IntKi), PARAMETER :: B1N4AxInd = 629 + INTEGER(IntKi), PARAMETER :: B1N5AxInd = 630 + INTEGER(IntKi), PARAMETER :: B1N6AxInd = 631 + INTEGER(IntKi), PARAMETER :: B1N7AxInd = 632 + INTEGER(IntKi), PARAMETER :: B1N8AxInd = 633 + INTEGER(IntKi), PARAMETER :: B1N9AxInd = 634 + INTEGER(IntKi), PARAMETER :: B2N1AxInd = 635 + INTEGER(IntKi), PARAMETER :: B2N2AxInd = 636 + INTEGER(IntKi), PARAMETER :: B2N3AxInd = 637 + INTEGER(IntKi), PARAMETER :: B2N4AxInd = 638 + INTEGER(IntKi), PARAMETER :: B2N5AxInd = 639 + INTEGER(IntKi), PARAMETER :: B2N6AxInd = 640 + INTEGER(IntKi), PARAMETER :: B2N7AxInd = 641 + INTEGER(IntKi), PARAMETER :: B2N8AxInd = 642 + INTEGER(IntKi), PARAMETER :: B2N9AxInd = 643 + INTEGER(IntKi), PARAMETER :: B3N1AxInd = 644 + INTEGER(IntKi), PARAMETER :: B3N2AxInd = 645 + INTEGER(IntKi), PARAMETER :: B3N3AxInd = 646 + INTEGER(IntKi), PARAMETER :: B3N4AxInd = 647 + INTEGER(IntKi), PARAMETER :: B3N5AxInd = 648 + INTEGER(IntKi), PARAMETER :: B3N6AxInd = 649 + INTEGER(IntKi), PARAMETER :: B3N7AxInd = 650 + INTEGER(IntKi), PARAMETER :: B3N8AxInd = 651 + INTEGER(IntKi), PARAMETER :: B3N9AxInd = 652 + INTEGER(IntKi), PARAMETER :: B1N1TnInd = 653 + INTEGER(IntKi), PARAMETER :: B1N2TnInd = 654 + INTEGER(IntKi), PARAMETER :: B1N3TnInd = 655 + INTEGER(IntKi), PARAMETER :: B1N4TnInd = 656 + INTEGER(IntKi), PARAMETER :: B1N5TnInd = 657 + INTEGER(IntKi), PARAMETER :: B1N6TnInd = 658 + INTEGER(IntKi), PARAMETER :: B1N7TnInd = 659 + INTEGER(IntKi), PARAMETER :: B1N8TnInd = 660 + INTEGER(IntKi), PARAMETER :: B1N9TnInd = 661 + INTEGER(IntKi), PARAMETER :: B2N1TnInd = 662 + INTEGER(IntKi), PARAMETER :: B2N2TnInd = 663 + INTEGER(IntKi), PARAMETER :: B2N3TnInd = 664 + INTEGER(IntKi), PARAMETER :: B2N4TnInd = 665 + INTEGER(IntKi), PARAMETER :: B2N5TnInd = 666 + INTEGER(IntKi), PARAMETER :: B2N6TnInd = 667 + INTEGER(IntKi), PARAMETER :: B2N7TnInd = 668 + INTEGER(IntKi), PARAMETER :: B2N8TnInd = 669 + INTEGER(IntKi), PARAMETER :: B2N9TnInd = 670 + INTEGER(IntKi), PARAMETER :: B3N1TnInd = 671 + INTEGER(IntKi), PARAMETER :: B3N2TnInd = 672 + INTEGER(IntKi), PARAMETER :: B3N3TnInd = 673 + INTEGER(IntKi), PARAMETER :: B3N4TnInd = 674 + INTEGER(IntKi), PARAMETER :: B3N5TnInd = 675 + INTEGER(IntKi), PARAMETER :: B3N6TnInd = 676 + INTEGER(IntKi), PARAMETER :: B3N7TnInd = 677 + INTEGER(IntKi), PARAMETER :: B3N8TnInd = 678 + INTEGER(IntKi), PARAMETER :: B3N9TnInd = 679 + INTEGER(IntKi), PARAMETER :: B1N1Alpha = 680 + INTEGER(IntKi), PARAMETER :: B1N2Alpha = 681 + INTEGER(IntKi), PARAMETER :: B1N3Alpha = 682 + INTEGER(IntKi), PARAMETER :: B1N4Alpha = 683 + INTEGER(IntKi), PARAMETER :: B1N5Alpha = 684 + INTEGER(IntKi), PARAMETER :: B1N6Alpha = 685 + INTEGER(IntKi), PARAMETER :: B1N7Alpha = 686 + INTEGER(IntKi), PARAMETER :: B1N8Alpha = 687 + INTEGER(IntKi), PARAMETER :: B1N9Alpha = 688 + INTEGER(IntKi), PARAMETER :: B2N1Alpha = 689 + INTEGER(IntKi), PARAMETER :: B2N2Alpha = 690 + INTEGER(IntKi), PARAMETER :: B2N3Alpha = 691 + INTEGER(IntKi), PARAMETER :: B2N4Alpha = 692 + INTEGER(IntKi), PARAMETER :: B2N5Alpha = 693 + INTEGER(IntKi), PARAMETER :: B2N6Alpha = 694 + INTEGER(IntKi), PARAMETER :: B2N7Alpha = 695 + INTEGER(IntKi), PARAMETER :: B2N8Alpha = 696 + INTEGER(IntKi), PARAMETER :: B2N9Alpha = 697 + INTEGER(IntKi), PARAMETER :: B3N1Alpha = 698 + INTEGER(IntKi), PARAMETER :: B3N2Alpha = 699 + INTEGER(IntKi), PARAMETER :: B3N3Alpha = 700 + INTEGER(IntKi), PARAMETER :: B3N4Alpha = 701 + INTEGER(IntKi), PARAMETER :: B3N5Alpha = 702 + INTEGER(IntKi), PARAMETER :: B3N6Alpha = 703 + INTEGER(IntKi), PARAMETER :: B3N7Alpha = 704 + INTEGER(IntKi), PARAMETER :: B3N8Alpha = 705 + INTEGER(IntKi), PARAMETER :: B3N9Alpha = 706 + INTEGER(IntKi), PARAMETER :: B1N1Theta = 707 + INTEGER(IntKi), PARAMETER :: B1N2Theta = 708 + INTEGER(IntKi), PARAMETER :: B1N3Theta = 709 + INTEGER(IntKi), PARAMETER :: B1N4Theta = 710 + INTEGER(IntKi), PARAMETER :: B1N5Theta = 711 + INTEGER(IntKi), PARAMETER :: B1N6Theta = 712 + INTEGER(IntKi), PARAMETER :: B1N7Theta = 713 + INTEGER(IntKi), PARAMETER :: B1N8Theta = 714 + INTEGER(IntKi), PARAMETER :: B1N9Theta = 715 + INTEGER(IntKi), PARAMETER :: B2N1Theta = 716 + INTEGER(IntKi), PARAMETER :: B2N2Theta = 717 + INTEGER(IntKi), PARAMETER :: B2N3Theta = 718 + INTEGER(IntKi), PARAMETER :: B2N4Theta = 719 + INTEGER(IntKi), PARAMETER :: B2N5Theta = 720 + INTEGER(IntKi), PARAMETER :: B2N6Theta = 721 + INTEGER(IntKi), PARAMETER :: B2N7Theta = 722 + INTEGER(IntKi), PARAMETER :: B2N8Theta = 723 + INTEGER(IntKi), PARAMETER :: B2N9Theta = 724 + INTEGER(IntKi), PARAMETER :: B3N1Theta = 725 + INTEGER(IntKi), PARAMETER :: B3N2Theta = 726 + INTEGER(IntKi), PARAMETER :: B3N3Theta = 727 + INTEGER(IntKi), PARAMETER :: B3N4Theta = 728 + INTEGER(IntKi), PARAMETER :: B3N5Theta = 729 + INTEGER(IntKi), PARAMETER :: B3N6Theta = 730 + INTEGER(IntKi), PARAMETER :: B3N7Theta = 731 + INTEGER(IntKi), PARAMETER :: B3N8Theta = 732 + INTEGER(IntKi), PARAMETER :: B3N9Theta = 733 + INTEGER(IntKi), PARAMETER :: B1N1Phi = 734 + INTEGER(IntKi), PARAMETER :: B1N2Phi = 735 + INTEGER(IntKi), PARAMETER :: B1N3Phi = 736 + INTEGER(IntKi), PARAMETER :: B1N4Phi = 737 + INTEGER(IntKi), PARAMETER :: B1N5Phi = 738 + INTEGER(IntKi), PARAMETER :: B1N6Phi = 739 + INTEGER(IntKi), PARAMETER :: B1N7Phi = 740 + INTEGER(IntKi), PARAMETER :: B1N8Phi = 741 + INTEGER(IntKi), PARAMETER :: B1N9Phi = 742 + INTEGER(IntKi), PARAMETER :: B2N1Phi = 743 + INTEGER(IntKi), PARAMETER :: B2N2Phi = 744 + INTEGER(IntKi), PARAMETER :: B2N3Phi = 745 + INTEGER(IntKi), PARAMETER :: B2N4Phi = 746 + INTEGER(IntKi), PARAMETER :: B2N5Phi = 747 + INTEGER(IntKi), PARAMETER :: B2N6Phi = 748 + INTEGER(IntKi), PARAMETER :: B2N7Phi = 749 + INTEGER(IntKi), PARAMETER :: B2N8Phi = 750 + INTEGER(IntKi), PARAMETER :: B2N9Phi = 751 + INTEGER(IntKi), PARAMETER :: B3N1Phi = 752 + INTEGER(IntKi), PARAMETER :: B3N2Phi = 753 + INTEGER(IntKi), PARAMETER :: B3N3Phi = 754 + INTEGER(IntKi), PARAMETER :: B3N4Phi = 755 + INTEGER(IntKi), PARAMETER :: B3N5Phi = 756 + INTEGER(IntKi), PARAMETER :: B3N6Phi = 757 + INTEGER(IntKi), PARAMETER :: B3N7Phi = 758 + INTEGER(IntKi), PARAMETER :: B3N8Phi = 759 + INTEGER(IntKi), PARAMETER :: B3N9Phi = 760 + INTEGER(IntKi), PARAMETER :: B1N1Curve = 761 + INTEGER(IntKi), PARAMETER :: B1N2Curve = 762 + INTEGER(IntKi), PARAMETER :: B1N3Curve = 763 + INTEGER(IntKi), PARAMETER :: B1N4Curve = 764 + INTEGER(IntKi), PARAMETER :: B1N5Curve = 765 + INTEGER(IntKi), PARAMETER :: B1N6Curve = 766 + INTEGER(IntKi), PARAMETER :: B1N7Curve = 767 + INTEGER(IntKi), PARAMETER :: B1N8Curve = 768 + INTEGER(IntKi), PARAMETER :: B1N9Curve = 769 + INTEGER(IntKi), PARAMETER :: B2N1Curve = 770 + INTEGER(IntKi), PARAMETER :: B2N2Curve = 771 + INTEGER(IntKi), PARAMETER :: B2N3Curve = 772 + INTEGER(IntKi), PARAMETER :: B2N4Curve = 773 + INTEGER(IntKi), PARAMETER :: B2N5Curve = 774 + INTEGER(IntKi), PARAMETER :: B2N6Curve = 775 + INTEGER(IntKi), PARAMETER :: B2N7Curve = 776 + INTEGER(IntKi), PARAMETER :: B2N8Curve = 777 + INTEGER(IntKi), PARAMETER :: B2N9Curve = 778 + INTEGER(IntKi), PARAMETER :: B3N1Curve = 779 + INTEGER(IntKi), PARAMETER :: B3N2Curve = 780 + INTEGER(IntKi), PARAMETER :: B3N3Curve = 781 + INTEGER(IntKi), PARAMETER :: B3N4Curve = 782 + INTEGER(IntKi), PARAMETER :: B3N5Curve = 783 + INTEGER(IntKi), PARAMETER :: B3N6Curve = 784 + INTEGER(IntKi), PARAMETER :: B3N7Curve = 785 + INTEGER(IntKi), PARAMETER :: B3N8Curve = 786 + INTEGER(IntKi), PARAMETER :: B3N9Curve = 787 + INTEGER(IntKi), PARAMETER :: B1N1Cl = 788 + INTEGER(IntKi), PARAMETER :: B1N2Cl = 789 + INTEGER(IntKi), PARAMETER :: B1N3Cl = 790 + INTEGER(IntKi), PARAMETER :: B1N4Cl = 791 + INTEGER(IntKi), PARAMETER :: B1N5Cl = 792 + INTEGER(IntKi), PARAMETER :: B1N6Cl = 793 + INTEGER(IntKi), PARAMETER :: B1N7Cl = 794 + INTEGER(IntKi), PARAMETER :: B1N8Cl = 795 + INTEGER(IntKi), PARAMETER :: B1N9Cl = 796 + INTEGER(IntKi), PARAMETER :: B2N1Cl = 797 + INTEGER(IntKi), PARAMETER :: B2N2Cl = 798 + INTEGER(IntKi), PARAMETER :: B2N3Cl = 799 + INTEGER(IntKi), PARAMETER :: B2N4Cl = 800 + INTEGER(IntKi), PARAMETER :: B2N5Cl = 801 + INTEGER(IntKi), PARAMETER :: B2N6Cl = 802 + INTEGER(IntKi), PARAMETER :: B2N7Cl = 803 + INTEGER(IntKi), PARAMETER :: B2N8Cl = 804 + INTEGER(IntKi), PARAMETER :: B2N9Cl = 805 + INTEGER(IntKi), PARAMETER :: B3N1Cl = 806 + INTEGER(IntKi), PARAMETER :: B3N2Cl = 807 + INTEGER(IntKi), PARAMETER :: B3N3Cl = 808 + INTEGER(IntKi), PARAMETER :: B3N4Cl = 809 + INTEGER(IntKi), PARAMETER :: B3N5Cl = 810 + INTEGER(IntKi), PARAMETER :: B3N6Cl = 811 + INTEGER(IntKi), PARAMETER :: B3N7Cl = 812 + INTEGER(IntKi), PARAMETER :: B3N8Cl = 813 + INTEGER(IntKi), PARAMETER :: B3N9Cl = 814 + INTEGER(IntKi), PARAMETER :: B1N1Cd = 815 + INTEGER(IntKi), PARAMETER :: B1N2Cd = 816 + INTEGER(IntKi), PARAMETER :: B1N3Cd = 817 + INTEGER(IntKi), PARAMETER :: B1N4Cd = 818 + INTEGER(IntKi), PARAMETER :: B1N5Cd = 819 + INTEGER(IntKi), PARAMETER :: B1N6Cd = 820 + INTEGER(IntKi), PARAMETER :: B1N7Cd = 821 + INTEGER(IntKi), PARAMETER :: B1N8Cd = 822 + INTEGER(IntKi), PARAMETER :: B1N9Cd = 823 + INTEGER(IntKi), PARAMETER :: B2N1Cd = 824 + INTEGER(IntKi), PARAMETER :: B2N2Cd = 825 + INTEGER(IntKi), PARAMETER :: B2N3Cd = 826 + INTEGER(IntKi), PARAMETER :: B2N4Cd = 827 + INTEGER(IntKi), PARAMETER :: B2N5Cd = 828 + INTEGER(IntKi), PARAMETER :: B2N6Cd = 829 + INTEGER(IntKi), PARAMETER :: B2N7Cd = 830 + INTEGER(IntKi), PARAMETER :: B2N8Cd = 831 + INTEGER(IntKi), PARAMETER :: B2N9Cd = 832 + INTEGER(IntKi), PARAMETER :: B3N1Cd = 833 + INTEGER(IntKi), PARAMETER :: B3N2Cd = 834 + INTEGER(IntKi), PARAMETER :: B3N3Cd = 835 + INTEGER(IntKi), PARAMETER :: B3N4Cd = 836 + INTEGER(IntKi), PARAMETER :: B3N5Cd = 837 + INTEGER(IntKi), PARAMETER :: B3N6Cd = 838 + INTEGER(IntKi), PARAMETER :: B3N7Cd = 839 + INTEGER(IntKi), PARAMETER :: B3N8Cd = 840 + INTEGER(IntKi), PARAMETER :: B3N9Cd = 841 + INTEGER(IntKi), PARAMETER :: B1N1Cm = 842 + INTEGER(IntKi), PARAMETER :: B1N2Cm = 843 + INTEGER(IntKi), PARAMETER :: B1N3Cm = 844 + INTEGER(IntKi), PARAMETER :: B1N4Cm = 845 + INTEGER(IntKi), PARAMETER :: B1N5Cm = 846 + INTEGER(IntKi), PARAMETER :: B1N6Cm = 847 + INTEGER(IntKi), PARAMETER :: B1N7Cm = 848 + INTEGER(IntKi), PARAMETER :: B1N8Cm = 849 + INTEGER(IntKi), PARAMETER :: B1N9Cm = 850 + INTEGER(IntKi), PARAMETER :: B2N1Cm = 851 + INTEGER(IntKi), PARAMETER :: B2N2Cm = 852 + INTEGER(IntKi), PARAMETER :: B2N3Cm = 853 + INTEGER(IntKi), PARAMETER :: B2N4Cm = 854 + INTEGER(IntKi), PARAMETER :: B2N5Cm = 855 + INTEGER(IntKi), PARAMETER :: B2N6Cm = 856 + INTEGER(IntKi), PARAMETER :: B2N7Cm = 857 + INTEGER(IntKi), PARAMETER :: B2N8Cm = 858 + INTEGER(IntKi), PARAMETER :: B2N9Cm = 859 + INTEGER(IntKi), PARAMETER :: B3N1Cm = 860 + INTEGER(IntKi), PARAMETER :: B3N2Cm = 861 + INTEGER(IntKi), PARAMETER :: B3N3Cm = 862 + INTEGER(IntKi), PARAMETER :: B3N4Cm = 863 + INTEGER(IntKi), PARAMETER :: B3N5Cm = 864 + INTEGER(IntKi), PARAMETER :: B3N6Cm = 865 + INTEGER(IntKi), PARAMETER :: B3N7Cm = 866 + INTEGER(IntKi), PARAMETER :: B3N8Cm = 867 + INTEGER(IntKi), PARAMETER :: B3N9Cm = 868 + INTEGER(IntKi), PARAMETER :: B1N1Cx = 869 + INTEGER(IntKi), PARAMETER :: B1N2Cx = 870 + INTEGER(IntKi), PARAMETER :: B1N3Cx = 871 + INTEGER(IntKi), PARAMETER :: B1N4Cx = 872 + INTEGER(IntKi), PARAMETER :: B1N5Cx = 873 + INTEGER(IntKi), PARAMETER :: B1N6Cx = 874 + INTEGER(IntKi), PARAMETER :: B1N7Cx = 875 + INTEGER(IntKi), PARAMETER :: B1N8Cx = 876 + INTEGER(IntKi), PARAMETER :: B1N9Cx = 877 + INTEGER(IntKi), PARAMETER :: B2N1Cx = 878 + INTEGER(IntKi), PARAMETER :: B2N2Cx = 879 + INTEGER(IntKi), PARAMETER :: B2N3Cx = 880 + INTEGER(IntKi), PARAMETER :: B2N4Cx = 881 + INTEGER(IntKi), PARAMETER :: B2N5Cx = 882 + INTEGER(IntKi), PARAMETER :: B2N6Cx = 883 + INTEGER(IntKi), PARAMETER :: B2N7Cx = 884 + INTEGER(IntKi), PARAMETER :: B2N8Cx = 885 + INTEGER(IntKi), PARAMETER :: B2N9Cx = 886 + INTEGER(IntKi), PARAMETER :: B3N1Cx = 887 + INTEGER(IntKi), PARAMETER :: B3N2Cx = 888 + INTEGER(IntKi), PARAMETER :: B3N3Cx = 889 + INTEGER(IntKi), PARAMETER :: B3N4Cx = 890 + INTEGER(IntKi), PARAMETER :: B3N5Cx = 891 + INTEGER(IntKi), PARAMETER :: B3N6Cx = 892 + INTEGER(IntKi), PARAMETER :: B3N7Cx = 893 + INTEGER(IntKi), PARAMETER :: B3N8Cx = 894 + INTEGER(IntKi), PARAMETER :: B3N9Cx = 895 + INTEGER(IntKi), PARAMETER :: B1N1Cy = 896 + INTEGER(IntKi), PARAMETER :: B1N2Cy = 897 + INTEGER(IntKi), PARAMETER :: B1N3Cy = 898 + INTEGER(IntKi), PARAMETER :: B1N4Cy = 899 + INTEGER(IntKi), PARAMETER :: B1N5Cy = 900 + INTEGER(IntKi), PARAMETER :: B1N6Cy = 901 + INTEGER(IntKi), PARAMETER :: B1N7Cy = 902 + INTEGER(IntKi), PARAMETER :: B1N8Cy = 903 + INTEGER(IntKi), PARAMETER :: B1N9Cy = 904 + INTEGER(IntKi), PARAMETER :: B2N1Cy = 905 + INTEGER(IntKi), PARAMETER :: B2N2Cy = 906 + INTEGER(IntKi), PARAMETER :: B2N3Cy = 907 + INTEGER(IntKi), PARAMETER :: B2N4Cy = 908 + INTEGER(IntKi), PARAMETER :: B2N5Cy = 909 + INTEGER(IntKi), PARAMETER :: B2N6Cy = 910 + INTEGER(IntKi), PARAMETER :: B2N7Cy = 911 + INTEGER(IntKi), PARAMETER :: B2N8Cy = 912 + INTEGER(IntKi), PARAMETER :: B2N9Cy = 913 + INTEGER(IntKi), PARAMETER :: B3N1Cy = 914 + INTEGER(IntKi), PARAMETER :: B3N2Cy = 915 + INTEGER(IntKi), PARAMETER :: B3N3Cy = 916 + INTEGER(IntKi), PARAMETER :: B3N4Cy = 917 + INTEGER(IntKi), PARAMETER :: B3N5Cy = 918 + INTEGER(IntKi), PARAMETER :: B3N6Cy = 919 + INTEGER(IntKi), PARAMETER :: B3N7Cy = 920 + INTEGER(IntKi), PARAMETER :: B3N8Cy = 921 + INTEGER(IntKi), PARAMETER :: B3N9Cy = 922 + INTEGER(IntKi), PARAMETER :: B1N1Cn = 923 + INTEGER(IntKi), PARAMETER :: B1N2Cn = 924 + INTEGER(IntKi), PARAMETER :: B1N3Cn = 925 + INTEGER(IntKi), PARAMETER :: B1N4Cn = 926 + INTEGER(IntKi), PARAMETER :: B1N5Cn = 927 + INTEGER(IntKi), PARAMETER :: B1N6Cn = 928 + INTEGER(IntKi), PARAMETER :: B1N7Cn = 929 + INTEGER(IntKi), PARAMETER :: B1N8Cn = 930 + INTEGER(IntKi), PARAMETER :: B1N9Cn = 931 + INTEGER(IntKi), PARAMETER :: B2N1Cn = 932 + INTEGER(IntKi), PARAMETER :: B2N2Cn = 933 + INTEGER(IntKi), PARAMETER :: B2N3Cn = 934 + INTEGER(IntKi), PARAMETER :: B2N4Cn = 935 + INTEGER(IntKi), PARAMETER :: B2N5Cn = 936 + INTEGER(IntKi), PARAMETER :: B2N6Cn = 937 + INTEGER(IntKi), PARAMETER :: B2N7Cn = 938 + INTEGER(IntKi), PARAMETER :: B2N8Cn = 939 + INTEGER(IntKi), PARAMETER :: B2N9Cn = 940 + INTEGER(IntKi), PARAMETER :: B3N1Cn = 941 + INTEGER(IntKi), PARAMETER :: B3N2Cn = 942 + INTEGER(IntKi), PARAMETER :: B3N3Cn = 943 + INTEGER(IntKi), PARAMETER :: B3N4Cn = 944 + INTEGER(IntKi), PARAMETER :: B3N5Cn = 945 + INTEGER(IntKi), PARAMETER :: B3N6Cn = 946 + INTEGER(IntKi), PARAMETER :: B3N7Cn = 947 + INTEGER(IntKi), PARAMETER :: B3N8Cn = 948 + INTEGER(IntKi), PARAMETER :: B3N9Cn = 949 + INTEGER(IntKi), PARAMETER :: B1N1Ct = 950 + INTEGER(IntKi), PARAMETER :: B1N2Ct = 951 + INTEGER(IntKi), PARAMETER :: B1N3Ct = 952 + INTEGER(IntKi), PARAMETER :: B1N4Ct = 953 + INTEGER(IntKi), PARAMETER :: B1N5Ct = 954 + INTEGER(IntKi), PARAMETER :: B1N6Ct = 955 + INTEGER(IntKi), PARAMETER :: B1N7Ct = 956 + INTEGER(IntKi), PARAMETER :: B1N8Ct = 957 + INTEGER(IntKi), PARAMETER :: B1N9Ct = 958 + INTEGER(IntKi), PARAMETER :: B2N1Ct = 959 + INTEGER(IntKi), PARAMETER :: B2N2Ct = 960 + INTEGER(IntKi), PARAMETER :: B2N3Ct = 961 + INTEGER(IntKi), PARAMETER :: B2N4Ct = 962 + INTEGER(IntKi), PARAMETER :: B2N5Ct = 963 + INTEGER(IntKi), PARAMETER :: B2N6Ct = 964 + INTEGER(IntKi), PARAMETER :: B2N7Ct = 965 + INTEGER(IntKi), PARAMETER :: B2N8Ct = 966 + INTEGER(IntKi), PARAMETER :: B2N9Ct = 967 + INTEGER(IntKi), PARAMETER :: B3N1Ct = 968 + INTEGER(IntKi), PARAMETER :: B3N2Ct = 969 + INTEGER(IntKi), PARAMETER :: B3N3Ct = 970 + INTEGER(IntKi), PARAMETER :: B3N4Ct = 971 + INTEGER(IntKi), PARAMETER :: B3N5Ct = 972 + INTEGER(IntKi), PARAMETER :: B3N6Ct = 973 + INTEGER(IntKi), PARAMETER :: B3N7Ct = 974 + INTEGER(IntKi), PARAMETER :: B3N8Ct = 975 + INTEGER(IntKi), PARAMETER :: B3N9Ct = 976 + INTEGER(IntKi), PARAMETER :: B1N1Fl = 977 + INTEGER(IntKi), PARAMETER :: B1N2Fl = 978 + INTEGER(IntKi), PARAMETER :: B1N3Fl = 979 + INTEGER(IntKi), PARAMETER :: B1N4Fl = 980 + INTEGER(IntKi), PARAMETER :: B1N5Fl = 981 + INTEGER(IntKi), PARAMETER :: B1N6Fl = 982 + INTEGER(IntKi), PARAMETER :: B1N7Fl = 983 + INTEGER(IntKi), PARAMETER :: B1N8Fl = 984 + INTEGER(IntKi), PARAMETER :: B1N9Fl = 985 + INTEGER(IntKi), PARAMETER :: B2N1Fl = 986 + INTEGER(IntKi), PARAMETER :: B2N2Fl = 987 + INTEGER(IntKi), PARAMETER :: B2N3Fl = 988 + INTEGER(IntKi), PARAMETER :: B2N4Fl = 989 + INTEGER(IntKi), PARAMETER :: B2N5Fl = 990 + INTEGER(IntKi), PARAMETER :: B2N6Fl = 991 + INTEGER(IntKi), PARAMETER :: B2N7Fl = 992 + INTEGER(IntKi), PARAMETER :: B2N8Fl = 993 + INTEGER(IntKi), PARAMETER :: B2N9Fl = 994 + INTEGER(IntKi), PARAMETER :: B3N1Fl = 995 + INTEGER(IntKi), PARAMETER :: B3N2Fl = 996 + INTEGER(IntKi), PARAMETER :: B3N3Fl = 997 + INTEGER(IntKi), PARAMETER :: B3N4Fl = 998 + INTEGER(IntKi), PARAMETER :: B3N5Fl = 999 + INTEGER(IntKi), PARAMETER :: B3N6Fl = 1000 + INTEGER(IntKi), PARAMETER :: B3N7Fl = 1001 + INTEGER(IntKi), PARAMETER :: B3N8Fl = 1002 + INTEGER(IntKi), PARAMETER :: B3N9Fl = 1003 + INTEGER(IntKi), PARAMETER :: B1N1Fd = 1004 + INTEGER(IntKi), PARAMETER :: B1N2Fd = 1005 + INTEGER(IntKi), PARAMETER :: B1N3Fd = 1006 + INTEGER(IntKi), PARAMETER :: B1N4Fd = 1007 + INTEGER(IntKi), PARAMETER :: B1N5Fd = 1008 + INTEGER(IntKi), PARAMETER :: B1N6Fd = 1009 + INTEGER(IntKi), PARAMETER :: B1N7Fd = 1010 + INTEGER(IntKi), PARAMETER :: B1N8Fd = 1011 + INTEGER(IntKi), PARAMETER :: B1N9Fd = 1012 + INTEGER(IntKi), PARAMETER :: B2N1Fd = 1013 + INTEGER(IntKi), PARAMETER :: B2N2Fd = 1014 + INTEGER(IntKi), PARAMETER :: B2N3Fd = 1015 + INTEGER(IntKi), PARAMETER :: B2N4Fd = 1016 + INTEGER(IntKi), PARAMETER :: B2N5Fd = 1017 + INTEGER(IntKi), PARAMETER :: B2N6Fd = 1018 + INTEGER(IntKi), PARAMETER :: B2N7Fd = 1019 + INTEGER(IntKi), PARAMETER :: B2N8Fd = 1020 + INTEGER(IntKi), PARAMETER :: B2N9Fd = 1021 + INTEGER(IntKi), PARAMETER :: B3N1Fd = 1022 + INTEGER(IntKi), PARAMETER :: B3N2Fd = 1023 + INTEGER(IntKi), PARAMETER :: B3N3Fd = 1024 + INTEGER(IntKi), PARAMETER :: B3N4Fd = 1025 + INTEGER(IntKi), PARAMETER :: B3N5Fd = 1026 + INTEGER(IntKi), PARAMETER :: B3N6Fd = 1027 + INTEGER(IntKi), PARAMETER :: B3N7Fd = 1028 + INTEGER(IntKi), PARAMETER :: B3N8Fd = 1029 + INTEGER(IntKi), PARAMETER :: B3N9Fd = 1030 + INTEGER(IntKi), PARAMETER :: B1N1Mm = 1031 + INTEGER(IntKi), PARAMETER :: B1N2Mm = 1032 + INTEGER(IntKi), PARAMETER :: B1N3Mm = 1033 + INTEGER(IntKi), PARAMETER :: B1N4Mm = 1034 + INTEGER(IntKi), PARAMETER :: B1N5Mm = 1035 + INTEGER(IntKi), PARAMETER :: B1N6Mm = 1036 + INTEGER(IntKi), PARAMETER :: B1N7Mm = 1037 + INTEGER(IntKi), PARAMETER :: B1N8Mm = 1038 + INTEGER(IntKi), PARAMETER :: B1N9Mm = 1039 + INTEGER(IntKi), PARAMETER :: B2N1Mm = 1040 + INTEGER(IntKi), PARAMETER :: B2N2Mm = 1041 + INTEGER(IntKi), PARAMETER :: B2N3Mm = 1042 + INTEGER(IntKi), PARAMETER :: B2N4Mm = 1043 + INTEGER(IntKi), PARAMETER :: B2N5Mm = 1044 + INTEGER(IntKi), PARAMETER :: B2N6Mm = 1045 + INTEGER(IntKi), PARAMETER :: B2N7Mm = 1046 + INTEGER(IntKi), PARAMETER :: B2N8Mm = 1047 + INTEGER(IntKi), PARAMETER :: B2N9Mm = 1048 + INTEGER(IntKi), PARAMETER :: B3N1Mm = 1049 + INTEGER(IntKi), PARAMETER :: B3N2Mm = 1050 + INTEGER(IntKi), PARAMETER :: B3N3Mm = 1051 + INTEGER(IntKi), PARAMETER :: B3N4Mm = 1052 + INTEGER(IntKi), PARAMETER :: B3N5Mm = 1053 + INTEGER(IntKi), PARAMETER :: B3N6Mm = 1054 + INTEGER(IntKi), PARAMETER :: B3N7Mm = 1055 + INTEGER(IntKi), PARAMETER :: B3N8Mm = 1056 + INTEGER(IntKi), PARAMETER :: B3N9Mm = 1057 + INTEGER(IntKi), PARAMETER :: B1N1Fx = 1058 + INTEGER(IntKi), PARAMETER :: B1N2Fx = 1059 + INTEGER(IntKi), PARAMETER :: B1N3Fx = 1060 + INTEGER(IntKi), PARAMETER :: B1N4Fx = 1061 + INTEGER(IntKi), PARAMETER :: B1N5Fx = 1062 + INTEGER(IntKi), PARAMETER :: B1N6Fx = 1063 + INTEGER(IntKi), PARAMETER :: B1N7Fx = 1064 + INTEGER(IntKi), PARAMETER :: B1N8Fx = 1065 + INTEGER(IntKi), PARAMETER :: B1N9Fx = 1066 + INTEGER(IntKi), PARAMETER :: B2N1Fx = 1067 + INTEGER(IntKi), PARAMETER :: B2N2Fx = 1068 + INTEGER(IntKi), PARAMETER :: B2N3Fx = 1069 + INTEGER(IntKi), PARAMETER :: B2N4Fx = 1070 + INTEGER(IntKi), PARAMETER :: B2N5Fx = 1071 + INTEGER(IntKi), PARAMETER :: B2N6Fx = 1072 + INTEGER(IntKi), PARAMETER :: B2N7Fx = 1073 + INTEGER(IntKi), PARAMETER :: B2N8Fx = 1074 + INTEGER(IntKi), PARAMETER :: B2N9Fx = 1075 + INTEGER(IntKi), PARAMETER :: B3N1Fx = 1076 + INTEGER(IntKi), PARAMETER :: B3N2Fx = 1077 + INTEGER(IntKi), PARAMETER :: B3N3Fx = 1078 + INTEGER(IntKi), PARAMETER :: B3N4Fx = 1079 + INTEGER(IntKi), PARAMETER :: B3N5Fx = 1080 + INTEGER(IntKi), PARAMETER :: B3N6Fx = 1081 + INTEGER(IntKi), PARAMETER :: B3N7Fx = 1082 + INTEGER(IntKi), PARAMETER :: B3N8Fx = 1083 + INTEGER(IntKi), PARAMETER :: B3N9Fx = 1084 + INTEGER(IntKi), PARAMETER :: B1N1Fy = 1085 + INTEGER(IntKi), PARAMETER :: B1N2Fy = 1086 + INTEGER(IntKi), PARAMETER :: B1N3Fy = 1087 + INTEGER(IntKi), PARAMETER :: B1N4Fy = 1088 + INTEGER(IntKi), PARAMETER :: B1N5Fy = 1089 + INTEGER(IntKi), PARAMETER :: B1N6Fy = 1090 + INTEGER(IntKi), PARAMETER :: B1N7Fy = 1091 + INTEGER(IntKi), PARAMETER :: B1N8Fy = 1092 + INTEGER(IntKi), PARAMETER :: B1N9Fy = 1093 + INTEGER(IntKi), PARAMETER :: B2N1Fy = 1094 + INTEGER(IntKi), PARAMETER :: B2N2Fy = 1095 + INTEGER(IntKi), PARAMETER :: B2N3Fy = 1096 + INTEGER(IntKi), PARAMETER :: B2N4Fy = 1097 + INTEGER(IntKi), PARAMETER :: B2N5Fy = 1098 + INTEGER(IntKi), PARAMETER :: B2N6Fy = 1099 + INTEGER(IntKi), PARAMETER :: B2N7Fy = 1100 + INTEGER(IntKi), PARAMETER :: B2N8Fy = 1101 + INTEGER(IntKi), PARAMETER :: B2N9Fy = 1102 + INTEGER(IntKi), PARAMETER :: B3N1Fy = 1103 + INTEGER(IntKi), PARAMETER :: B3N2Fy = 1104 + INTEGER(IntKi), PARAMETER :: B3N3Fy = 1105 + INTEGER(IntKi), PARAMETER :: B3N4Fy = 1106 + INTEGER(IntKi), PARAMETER :: B3N5Fy = 1107 + INTEGER(IntKi), PARAMETER :: B3N6Fy = 1108 + INTEGER(IntKi), PARAMETER :: B3N7Fy = 1109 + INTEGER(IntKi), PARAMETER :: B3N8Fy = 1110 + INTEGER(IntKi), PARAMETER :: B3N9Fy = 1111 + INTEGER(IntKi), PARAMETER :: B1N1Fn = 1112 + INTEGER(IntKi), PARAMETER :: B1N2Fn = 1113 + INTEGER(IntKi), PARAMETER :: B1N3Fn = 1114 + INTEGER(IntKi), PARAMETER :: B1N4Fn = 1115 + INTEGER(IntKi), PARAMETER :: B1N5Fn = 1116 + INTEGER(IntKi), PARAMETER :: B1N6Fn = 1117 + INTEGER(IntKi), PARAMETER :: B1N7Fn = 1118 + INTEGER(IntKi), PARAMETER :: B1N8Fn = 1119 + INTEGER(IntKi), PARAMETER :: B1N9Fn = 1120 + INTEGER(IntKi), PARAMETER :: B2N1Fn = 1121 + INTEGER(IntKi), PARAMETER :: B2N2Fn = 1122 + INTEGER(IntKi), PARAMETER :: B2N3Fn = 1123 + INTEGER(IntKi), PARAMETER :: B2N4Fn = 1124 + INTEGER(IntKi), PARAMETER :: B2N5Fn = 1125 + INTEGER(IntKi), PARAMETER :: B2N6Fn = 1126 + INTEGER(IntKi), PARAMETER :: B2N7Fn = 1127 + INTEGER(IntKi), PARAMETER :: B2N8Fn = 1128 + INTEGER(IntKi), PARAMETER :: B2N9Fn = 1129 + INTEGER(IntKi), PARAMETER :: B3N1Fn = 1130 + INTEGER(IntKi), PARAMETER :: B3N2Fn = 1131 + INTEGER(IntKi), PARAMETER :: B3N3Fn = 1132 + INTEGER(IntKi), PARAMETER :: B3N4Fn = 1133 + INTEGER(IntKi), PARAMETER :: B3N5Fn = 1134 + INTEGER(IntKi), PARAMETER :: B3N6Fn = 1135 + INTEGER(IntKi), PARAMETER :: B3N7Fn = 1136 + INTEGER(IntKi), PARAMETER :: B3N8Fn = 1137 + INTEGER(IntKi), PARAMETER :: B3N9Fn = 1138 + INTEGER(IntKi), PARAMETER :: B1N1Ft = 1139 + INTEGER(IntKi), PARAMETER :: B1N2Ft = 1140 + INTEGER(IntKi), PARAMETER :: B1N3Ft = 1141 + INTEGER(IntKi), PARAMETER :: B1N4Ft = 1142 + INTEGER(IntKi), PARAMETER :: B1N5Ft = 1143 + INTEGER(IntKi), PARAMETER :: B1N6Ft = 1144 + INTEGER(IntKi), PARAMETER :: B1N7Ft = 1145 + INTEGER(IntKi), PARAMETER :: B1N8Ft = 1146 + INTEGER(IntKi), PARAMETER :: B1N9Ft = 1147 + INTEGER(IntKi), PARAMETER :: B2N1Ft = 1148 + INTEGER(IntKi), PARAMETER :: B2N2Ft = 1149 + INTEGER(IntKi), PARAMETER :: B2N3Ft = 1150 + INTEGER(IntKi), PARAMETER :: B2N4Ft = 1151 + INTEGER(IntKi), PARAMETER :: B2N5Ft = 1152 + INTEGER(IntKi), PARAMETER :: B2N6Ft = 1153 + INTEGER(IntKi), PARAMETER :: B2N7Ft = 1154 + INTEGER(IntKi), PARAMETER :: B2N8Ft = 1155 + INTEGER(IntKi), PARAMETER :: B2N9Ft = 1156 + INTEGER(IntKi), PARAMETER :: B3N1Ft = 1157 + INTEGER(IntKi), PARAMETER :: B3N2Ft = 1158 + INTEGER(IntKi), PARAMETER :: B3N3Ft = 1159 + INTEGER(IntKi), PARAMETER :: B3N4Ft = 1160 + INTEGER(IntKi), PARAMETER :: B3N5Ft = 1161 + INTEGER(IntKi), PARAMETER :: B3N6Ft = 1162 + INTEGER(IntKi), PARAMETER :: B3N7Ft = 1163 + INTEGER(IntKi), PARAMETER :: B3N8Ft = 1164 + INTEGER(IntKi), PARAMETER :: B3N9Ft = 1165 + INTEGER(IntKi), PARAMETER :: B1N1Clrnc = 1166 + INTEGER(IntKi), PARAMETER :: B1N2Clrnc = 1167 + INTEGER(IntKi), PARAMETER :: B1N3Clrnc = 1168 + INTEGER(IntKi), PARAMETER :: B1N4Clrnc = 1169 + INTEGER(IntKi), PARAMETER :: B1N5Clrnc = 1170 + INTEGER(IntKi), PARAMETER :: B1N6Clrnc = 1171 + INTEGER(IntKi), PARAMETER :: B1N7Clrnc = 1172 + INTEGER(IntKi), PARAMETER :: B1N8Clrnc = 1173 + INTEGER(IntKi), PARAMETER :: B1N9Clrnc = 1174 + INTEGER(IntKi), PARAMETER :: B2N1Clrnc = 1175 + INTEGER(IntKi), PARAMETER :: B2N2Clrnc = 1176 + INTEGER(IntKi), PARAMETER :: B2N3Clrnc = 1177 + INTEGER(IntKi), PARAMETER :: B2N4Clrnc = 1178 + INTEGER(IntKi), PARAMETER :: B2N5Clrnc = 1179 + INTEGER(IntKi), PARAMETER :: B2N6Clrnc = 1180 + INTEGER(IntKi), PARAMETER :: B2N7Clrnc = 1181 + INTEGER(IntKi), PARAMETER :: B2N8Clrnc = 1182 + INTEGER(IntKi), PARAMETER :: B2N9Clrnc = 1183 + INTEGER(IntKi), PARAMETER :: B3N1Clrnc = 1184 + INTEGER(IntKi), PARAMETER :: B3N2Clrnc = 1185 + INTEGER(IntKi), PARAMETER :: B3N3Clrnc = 1186 + INTEGER(IntKi), PARAMETER :: B3N4Clrnc = 1187 + INTEGER(IntKi), PARAMETER :: B3N5Clrnc = 1188 + INTEGER(IntKi), PARAMETER :: B3N6Clrnc = 1189 + INTEGER(IntKi), PARAMETER :: B3N7Clrnc = 1190 + INTEGER(IntKi), PARAMETER :: B3N8Clrnc = 1191 + INTEGER(IntKi), PARAMETER :: B3N9Clrnc = 1192 + INTEGER(IntKi), PARAMETER :: B1N1Cpmin = 1193 + INTEGER(IntKi), PARAMETER :: B1N2Cpmin = 1194 + INTEGER(IntKi), PARAMETER :: B1N3Cpmin = 1195 + INTEGER(IntKi), PARAMETER :: B1N4Cpmin = 1196 + INTEGER(IntKi), PARAMETER :: B1N5Cpmin = 1197 + INTEGER(IntKi), PARAMETER :: B1N6Cpmin = 1198 + INTEGER(IntKi), PARAMETER :: B1N7Cpmin = 1199 + INTEGER(IntKi), PARAMETER :: B1N8Cpmin = 1200 + INTEGER(IntKi), PARAMETER :: B1N9Cpmin = 1201 + INTEGER(IntKi), PARAMETER :: B2N1Cpmin = 1202 + INTEGER(IntKi), PARAMETER :: B2N2Cpmin = 1203 + INTEGER(IntKi), PARAMETER :: B2N3Cpmin = 1204 + INTEGER(IntKi), PARAMETER :: B2N4Cpmin = 1205 + INTEGER(IntKi), PARAMETER :: B2N5Cpmin = 1206 + INTEGER(IntKi), PARAMETER :: B2N6Cpmin = 1207 + INTEGER(IntKi), PARAMETER :: B2N7Cpmin = 1208 + INTEGER(IntKi), PARAMETER :: B2N8Cpmin = 1209 + INTEGER(IntKi), PARAMETER :: B2N9Cpmin = 1210 + INTEGER(IntKi), PARAMETER :: B3N1Cpmin = 1211 + INTEGER(IntKi), PARAMETER :: B3N2Cpmin = 1212 + INTEGER(IntKi), PARAMETER :: B3N3Cpmin = 1213 + INTEGER(IntKi), PARAMETER :: B3N4Cpmin = 1214 + INTEGER(IntKi), PARAMETER :: B3N5Cpmin = 1215 + INTEGER(IntKi), PARAMETER :: B3N6Cpmin = 1216 + INTEGER(IntKi), PARAMETER :: B3N7Cpmin = 1217 + INTEGER(IntKi), PARAMETER :: B3N8Cpmin = 1218 + INTEGER(IntKi), PARAMETER :: B3N9Cpmin = 1219 + INTEGER(IntKi), PARAMETER :: B1N1SigCr = 1220 + INTEGER(IntKi), PARAMETER :: B1N2SigCr = 1221 + INTEGER(IntKi), PARAMETER :: B1N3SigCr = 1222 + INTEGER(IntKi), PARAMETER :: B1N4SigCr = 1223 + INTEGER(IntKi), PARAMETER :: B1N5SigCr = 1224 + INTEGER(IntKi), PARAMETER :: B1N6SigCr = 1225 + INTEGER(IntKi), PARAMETER :: B1N7SigCr = 1226 + INTEGER(IntKi), PARAMETER :: B1N8SigCr = 1227 + INTEGER(IntKi), PARAMETER :: B1N9SigCr = 1228 + INTEGER(IntKi), PARAMETER :: B2N1SigCr = 1229 + INTEGER(IntKi), PARAMETER :: B2N2SigCr = 1230 + INTEGER(IntKi), PARAMETER :: B2N3SigCr = 1231 + INTEGER(IntKi), PARAMETER :: B2N4SigCr = 1232 + INTEGER(IntKi), PARAMETER :: B2N5SigCr = 1233 + INTEGER(IntKi), PARAMETER :: B2N6SigCr = 1234 + INTEGER(IntKi), PARAMETER :: B2N7SigCr = 1235 + INTEGER(IntKi), PARAMETER :: B2N8SigCr = 1236 + INTEGER(IntKi), PARAMETER :: B2N9SigCr = 1237 + INTEGER(IntKi), PARAMETER :: B3N1SigCr = 1238 + INTEGER(IntKi), PARAMETER :: B3N2SigCr = 1239 + INTEGER(IntKi), PARAMETER :: B3N3SigCr = 1240 + INTEGER(IntKi), PARAMETER :: B3N4SigCr = 1241 + INTEGER(IntKi), PARAMETER :: B3N5SigCr = 1242 + INTEGER(IntKi), PARAMETER :: B3N6SigCr = 1243 + INTEGER(IntKi), PARAMETER :: B3N7SigCr = 1244 + INTEGER(IntKi), PARAMETER :: B3N8SigCr = 1245 + INTEGER(IntKi), PARAMETER :: B3N9SigCr = 1246 + INTEGER(IntKi), PARAMETER :: B1N1SgCav = 1247 + INTEGER(IntKi), PARAMETER :: B1N2SgCav = 1248 + INTEGER(IntKi), PARAMETER :: B1N3SgCav = 1249 + INTEGER(IntKi), PARAMETER :: B1N4SgCav = 1250 + INTEGER(IntKi), PARAMETER :: B1N5SgCav = 1251 + INTEGER(IntKi), PARAMETER :: B1N6SgCav = 1252 + INTEGER(IntKi), PARAMETER :: B1N7SgCav = 1253 + INTEGER(IntKi), PARAMETER :: B1N8SgCav = 1254 + INTEGER(IntKi), PARAMETER :: B1N9SgCav = 1255 + INTEGER(IntKi), PARAMETER :: B2N1SgCav = 1256 + INTEGER(IntKi), PARAMETER :: B2N2SgCav = 1257 + INTEGER(IntKi), PARAMETER :: B2N3SgCav = 1258 + INTEGER(IntKi), PARAMETER :: B2N4SgCav = 1259 + INTEGER(IntKi), PARAMETER :: B2N5SgCav = 1260 + INTEGER(IntKi), PARAMETER :: B2N6SgCav = 1261 + INTEGER(IntKi), PARAMETER :: B2N7SgCav = 1262 + INTEGER(IntKi), PARAMETER :: B2N8SgCav = 1263 + INTEGER(IntKi), PARAMETER :: B2N9SgCav = 1264 + INTEGER(IntKi), PARAMETER :: B3N1SgCav = 1265 + INTEGER(IntKi), PARAMETER :: B3N2SgCav = 1266 + INTEGER(IntKi), PARAMETER :: B3N3SgCav = 1267 + INTEGER(IntKi), PARAMETER :: B3N4SgCav = 1268 + INTEGER(IntKi), PARAMETER :: B3N5SgCav = 1269 + INTEGER(IntKi), PARAMETER :: B3N6SgCav = 1270 + INTEGER(IntKi), PARAMETER :: B3N7SgCav = 1271 + INTEGER(IntKi), PARAMETER :: B3N8SgCav = 1272 + INTEGER(IntKi), PARAMETER :: B3N9SgCav = 1273 + INTEGER(IntKi), PARAMETER :: B1N1Gam = 1274 + INTEGER(IntKi), PARAMETER :: B1N2Gam = 1275 + INTEGER(IntKi), PARAMETER :: B1N3Gam = 1276 + INTEGER(IntKi), PARAMETER :: B1N4Gam = 1277 + INTEGER(IntKi), PARAMETER :: B1N5Gam = 1278 + INTEGER(IntKi), PARAMETER :: B1N6Gam = 1279 + INTEGER(IntKi), PARAMETER :: B1N7Gam = 1280 + INTEGER(IntKi), PARAMETER :: B1N8Gam = 1281 + INTEGER(IntKi), PARAMETER :: B1N9Gam = 1282 + INTEGER(IntKi), PARAMETER :: B2N1Gam = 1283 + INTEGER(IntKi), PARAMETER :: B2N2Gam = 1284 + INTEGER(IntKi), PARAMETER :: B2N3Gam = 1285 + INTEGER(IntKi), PARAMETER :: B2N4Gam = 1286 + INTEGER(IntKi), PARAMETER :: B2N5Gam = 1287 + INTEGER(IntKi), PARAMETER :: B2N6Gam = 1288 + INTEGER(IntKi), PARAMETER :: B2N7Gam = 1289 + INTEGER(IntKi), PARAMETER :: B2N8Gam = 1290 + INTEGER(IntKi), PARAMETER :: B2N9Gam = 1291 + INTEGER(IntKi), PARAMETER :: B3N1Gam = 1292 + INTEGER(IntKi), PARAMETER :: B3N2Gam = 1293 + INTEGER(IntKi), PARAMETER :: B3N3Gam = 1294 + INTEGER(IntKi), PARAMETER :: B3N4Gam = 1295 + INTEGER(IntKi), PARAMETER :: B3N5Gam = 1296 + INTEGER(IntKi), PARAMETER :: B3N6Gam = 1297 + INTEGER(IntKi), PARAMETER :: B3N7Gam = 1298 + INTEGER(IntKi), PARAMETER :: B3N8Gam = 1299 + INTEGER(IntKi), PARAMETER :: B3N9Gam = 1300 + INTEGER(IntKi), PARAMETER :: B1N1Fbn = 1301 + INTEGER(IntKi), PARAMETER :: B1N2Fbn = 1302 + INTEGER(IntKi), PARAMETER :: B1N3Fbn = 1303 + INTEGER(IntKi), PARAMETER :: B1N4Fbn = 1304 + INTEGER(IntKi), PARAMETER :: B1N5Fbn = 1305 + INTEGER(IntKi), PARAMETER :: B1N6Fbn = 1306 + INTEGER(IntKi), PARAMETER :: B1N7Fbn = 1307 + INTEGER(IntKi), PARAMETER :: B1N8Fbn = 1308 + INTEGER(IntKi), PARAMETER :: B1N9Fbn = 1309 + INTEGER(IntKi), PARAMETER :: B2N1Fbn = 1310 + INTEGER(IntKi), PARAMETER :: B2N2Fbn = 1311 + INTEGER(IntKi), PARAMETER :: B2N3Fbn = 1312 + INTEGER(IntKi), PARAMETER :: B2N4Fbn = 1313 + INTEGER(IntKi), PARAMETER :: B2N5Fbn = 1314 + INTEGER(IntKi), PARAMETER :: B2N6Fbn = 1315 + INTEGER(IntKi), PARAMETER :: B2N7Fbn = 1316 + INTEGER(IntKi), PARAMETER :: B2N8Fbn = 1317 + INTEGER(IntKi), PARAMETER :: B2N9Fbn = 1318 + INTEGER(IntKi), PARAMETER :: B3N1Fbn = 1319 + INTEGER(IntKi), PARAMETER :: B3N2Fbn = 1320 + INTEGER(IntKi), PARAMETER :: B3N3Fbn = 1321 + INTEGER(IntKi), PARAMETER :: B3N4Fbn = 1322 + INTEGER(IntKi), PARAMETER :: B3N5Fbn = 1323 + INTEGER(IntKi), PARAMETER :: B3N6Fbn = 1324 + INTEGER(IntKi), PARAMETER :: B3N7Fbn = 1325 + INTEGER(IntKi), PARAMETER :: B3N8Fbn = 1326 + INTEGER(IntKi), PARAMETER :: B3N9Fbn = 1327 + INTEGER(IntKi), PARAMETER :: B1N1Fbt = 1328 + INTEGER(IntKi), PARAMETER :: B1N2Fbt = 1329 + INTEGER(IntKi), PARAMETER :: B1N3Fbt = 1330 + INTEGER(IntKi), PARAMETER :: B1N4Fbt = 1331 + INTEGER(IntKi), PARAMETER :: B1N5Fbt = 1332 + INTEGER(IntKi), PARAMETER :: B1N6Fbt = 1333 + INTEGER(IntKi), PARAMETER :: B1N7Fbt = 1334 + INTEGER(IntKi), PARAMETER :: B1N8Fbt = 1335 + INTEGER(IntKi), PARAMETER :: B1N9Fbt = 1336 + INTEGER(IntKi), PARAMETER :: B2N1Fbt = 1337 + INTEGER(IntKi), PARAMETER :: B2N2Fbt = 1338 + INTEGER(IntKi), PARAMETER :: B2N3Fbt = 1339 + INTEGER(IntKi), PARAMETER :: B2N4Fbt = 1340 + INTEGER(IntKi), PARAMETER :: B2N5Fbt = 1341 + INTEGER(IntKi), PARAMETER :: B2N6Fbt = 1342 + INTEGER(IntKi), PARAMETER :: B2N7Fbt = 1343 + INTEGER(IntKi), PARAMETER :: B2N8Fbt = 1344 + INTEGER(IntKi), PARAMETER :: B2N9Fbt = 1345 + INTEGER(IntKi), PARAMETER :: B3N1Fbt = 1346 + INTEGER(IntKi), PARAMETER :: B3N2Fbt = 1347 + INTEGER(IntKi), PARAMETER :: B3N3Fbt = 1348 + INTEGER(IntKi), PARAMETER :: B3N4Fbt = 1349 + INTEGER(IntKi), PARAMETER :: B3N5Fbt = 1350 + INTEGER(IntKi), PARAMETER :: B3N6Fbt = 1351 + INTEGER(IntKi), PARAMETER :: B3N7Fbt = 1352 + INTEGER(IntKi), PARAMETER :: B3N8Fbt = 1353 + INTEGER(IntKi), PARAMETER :: B3N9Fbt = 1354 + INTEGER(IntKi), PARAMETER :: B1N1Fbs = 1355 + INTEGER(IntKi), PARAMETER :: B1N2Fbs = 1356 + INTEGER(IntKi), PARAMETER :: B1N3Fbs = 1357 + INTEGER(IntKi), PARAMETER :: B1N4Fbs = 1358 + INTEGER(IntKi), PARAMETER :: B1N5Fbs = 1359 + INTEGER(IntKi), PARAMETER :: B1N6Fbs = 1360 + INTEGER(IntKi), PARAMETER :: B1N7Fbs = 1361 + INTEGER(IntKi), PARAMETER :: B1N8Fbs = 1362 + INTEGER(IntKi), PARAMETER :: B1N9Fbs = 1363 + INTEGER(IntKi), PARAMETER :: B2N1Fbs = 1364 + INTEGER(IntKi), PARAMETER :: B2N2Fbs = 1365 + INTEGER(IntKi), PARAMETER :: B2N3Fbs = 1366 + INTEGER(IntKi), PARAMETER :: B2N4Fbs = 1367 + INTEGER(IntKi), PARAMETER :: B2N5Fbs = 1368 + INTEGER(IntKi), PARAMETER :: B2N6Fbs = 1369 + INTEGER(IntKi), PARAMETER :: B2N7Fbs = 1370 + INTEGER(IntKi), PARAMETER :: B2N8Fbs = 1371 + INTEGER(IntKi), PARAMETER :: B2N9Fbs = 1372 + INTEGER(IntKi), PARAMETER :: B3N1Fbs = 1373 + INTEGER(IntKi), PARAMETER :: B3N2Fbs = 1374 + INTEGER(IntKi), PARAMETER :: B3N3Fbs = 1375 + INTEGER(IntKi), PARAMETER :: B3N4Fbs = 1376 + INTEGER(IntKi), PARAMETER :: B3N5Fbs = 1377 + INTEGER(IntKi), PARAMETER :: B3N6Fbs = 1378 + INTEGER(IntKi), PARAMETER :: B3N7Fbs = 1379 + INTEGER(IntKi), PARAMETER :: B3N8Fbs = 1380 + INTEGER(IntKi), PARAMETER :: B3N9Fbs = 1381 + INTEGER(IntKi), PARAMETER :: B1N1Mbn = 1382 + INTEGER(IntKi), PARAMETER :: B1N2Mbn = 1383 + INTEGER(IntKi), PARAMETER :: B1N3Mbn = 1384 + INTEGER(IntKi), PARAMETER :: B1N4Mbn = 1385 + INTEGER(IntKi), PARAMETER :: B1N5Mbn = 1386 + INTEGER(IntKi), PARAMETER :: B1N6Mbn = 1387 + INTEGER(IntKi), PARAMETER :: B1N7Mbn = 1388 + INTEGER(IntKi), PARAMETER :: B1N8Mbn = 1389 + INTEGER(IntKi), PARAMETER :: B1N9Mbn = 1390 + INTEGER(IntKi), PARAMETER :: B2N1Mbn = 1391 + INTEGER(IntKi), PARAMETER :: B2N2Mbn = 1392 + INTEGER(IntKi), PARAMETER :: B2N3Mbn = 1393 + INTEGER(IntKi), PARAMETER :: B2N4Mbn = 1394 + INTEGER(IntKi), PARAMETER :: B2N5Mbn = 1395 + INTEGER(IntKi), PARAMETER :: B2N6Mbn = 1396 + INTEGER(IntKi), PARAMETER :: B2N7Mbn = 1397 + INTEGER(IntKi), PARAMETER :: B2N8Mbn = 1398 + INTEGER(IntKi), PARAMETER :: B2N9Mbn = 1399 + INTEGER(IntKi), PARAMETER :: B3N1Mbn = 1400 + INTEGER(IntKi), PARAMETER :: B3N2Mbn = 1401 + INTEGER(IntKi), PARAMETER :: B3N3Mbn = 1402 + INTEGER(IntKi), PARAMETER :: B3N4Mbn = 1403 + INTEGER(IntKi), PARAMETER :: B3N5Mbn = 1404 + INTEGER(IntKi), PARAMETER :: B3N6Mbn = 1405 + INTEGER(IntKi), PARAMETER :: B3N7Mbn = 1406 + INTEGER(IntKi), PARAMETER :: B3N8Mbn = 1407 + INTEGER(IntKi), PARAMETER :: B3N9Mbn = 1408 + INTEGER(IntKi), PARAMETER :: B1N1Mbt = 1409 + INTEGER(IntKi), PARAMETER :: B1N2Mbt = 1410 + INTEGER(IntKi), PARAMETER :: B1N3Mbt = 1411 + INTEGER(IntKi), PARAMETER :: B1N4Mbt = 1412 + INTEGER(IntKi), PARAMETER :: B1N5Mbt = 1413 + INTEGER(IntKi), PARAMETER :: B1N6Mbt = 1414 + INTEGER(IntKi), PARAMETER :: B1N7Mbt = 1415 + INTEGER(IntKi), PARAMETER :: B1N8Mbt = 1416 + INTEGER(IntKi), PARAMETER :: B1N9Mbt = 1417 + INTEGER(IntKi), PARAMETER :: B2N1Mbt = 1418 + INTEGER(IntKi), PARAMETER :: B2N2Mbt = 1419 + INTEGER(IntKi), PARAMETER :: B2N3Mbt = 1420 + INTEGER(IntKi), PARAMETER :: B2N4Mbt = 1421 + INTEGER(IntKi), PARAMETER :: B2N5Mbt = 1422 + INTEGER(IntKi), PARAMETER :: B2N6Mbt = 1423 + INTEGER(IntKi), PARAMETER :: B2N7Mbt = 1424 + INTEGER(IntKi), PARAMETER :: B2N8Mbt = 1425 + INTEGER(IntKi), PARAMETER :: B2N9Mbt = 1426 + INTEGER(IntKi), PARAMETER :: B3N1Mbt = 1427 + INTEGER(IntKi), PARAMETER :: B3N2Mbt = 1428 + INTEGER(IntKi), PARAMETER :: B3N3Mbt = 1429 + INTEGER(IntKi), PARAMETER :: B3N4Mbt = 1430 + INTEGER(IntKi), PARAMETER :: B3N5Mbt = 1431 + INTEGER(IntKi), PARAMETER :: B3N6Mbt = 1432 + INTEGER(IntKi), PARAMETER :: B3N7Mbt = 1433 + INTEGER(IntKi), PARAMETER :: B3N8Mbt = 1434 + INTEGER(IntKi), PARAMETER :: B3N9Mbt = 1435 + INTEGER(IntKi), PARAMETER :: B1N1Mbs = 1436 + INTEGER(IntKi), PARAMETER :: B1N2Mbs = 1437 + INTEGER(IntKi), PARAMETER :: B1N3Mbs = 1438 + INTEGER(IntKi), PARAMETER :: B1N4Mbs = 1439 + INTEGER(IntKi), PARAMETER :: B1N5Mbs = 1440 + INTEGER(IntKi), PARAMETER :: B1N6Mbs = 1441 + INTEGER(IntKi), PARAMETER :: B1N7Mbs = 1442 + INTEGER(IntKi), PARAMETER :: B1N8Mbs = 1443 + INTEGER(IntKi), PARAMETER :: B1N9Mbs = 1444 + INTEGER(IntKi), PARAMETER :: B2N1Mbs = 1445 + INTEGER(IntKi), PARAMETER :: B2N2Mbs = 1446 + INTEGER(IntKi), PARAMETER :: B2N3Mbs = 1447 + INTEGER(IntKi), PARAMETER :: B2N4Mbs = 1448 + INTEGER(IntKi), PARAMETER :: B2N5Mbs = 1449 + INTEGER(IntKi), PARAMETER :: B2N6Mbs = 1450 + INTEGER(IntKi), PARAMETER :: B2N7Mbs = 1451 + INTEGER(IntKi), PARAMETER :: B2N8Mbs = 1452 + INTEGER(IntKi), PARAMETER :: B2N9Mbs = 1453 + INTEGER(IntKi), PARAMETER :: B3N1Mbs = 1454 + INTEGER(IntKi), PARAMETER :: B3N2Mbs = 1455 + INTEGER(IntKi), PARAMETER :: B3N3Mbs = 1456 + INTEGER(IntKi), PARAMETER :: B3N4Mbs = 1457 + INTEGER(IntKi), PARAMETER :: B3N5Mbs = 1458 + INTEGER(IntKi), PARAMETER :: B3N6Mbs = 1459 + INTEGER(IntKi), PARAMETER :: B3N7Mbs = 1460 + INTEGER(IntKi), PARAMETER :: B3N8Mbs = 1461 + INTEGER(IntKi), PARAMETER :: B3N9Mbs = 1462 + + + ! Rotor: + + INTEGER(IntKi), PARAMETER :: RtSpeed = 1463 + INTEGER(IntKi), PARAMETER :: RtTSR = 1464 + INTEGER(IntKi), PARAMETER :: RtVAvgxh = 1465 + INTEGER(IntKi), PARAMETER :: RtVAvgyh = 1466 + INTEGER(IntKi), PARAMETER :: RtVAvgzh = 1467 + INTEGER(IntKi), PARAMETER :: RtSkew = 1468 + INTEGER(IntKi), PARAMETER :: RtAeroFxh = 1469 + INTEGER(IntKi), PARAMETER :: RtAeroFyh = 1470 + INTEGER(IntKi), PARAMETER :: RtAeroFzh = 1471 + INTEGER(IntKi), PARAMETER :: RtAeroMxh = 1472 + INTEGER(IntKi), PARAMETER :: RtAeroMyh = 1473 + INTEGER(IntKi), PARAMETER :: RtAeroMzh = 1474 + INTEGER(IntKi), PARAMETER :: RtAeroPwr = 1475 + INTEGER(IntKi), PARAMETER :: RtArea = 1476 + INTEGER(IntKi), PARAMETER :: RtAeroCp = 1477 + INTEGER(IntKi), PARAMETER :: RtAeroCq = 1478 + INTEGER(IntKi), PARAMETER :: RtAeroCt = 1479 + INTEGER(IntKi), PARAMETER :: DBEMTau1 = 1480 + INTEGER(IntKi), PARAMETER :: RtAeroFxg = 1481 + INTEGER(IntKi), PARAMETER :: RtAeroFyg = 1482 + INTEGER(IntKi), PARAMETER :: RtAeroFzg = 1483 + INTEGER(IntKi), PARAMETER :: RtAeroMxg = 1484 + INTEGER(IntKi), PARAMETER :: RtAeroMyg = 1485 + INTEGER(IntKi), PARAMETER :: RtAeroMzg = 1486 + + + ! Hub: + + INTEGER(IntKi), PARAMETER :: HbFbx = 1487 + INTEGER(IntKi), PARAMETER :: HbFby = 1488 + INTEGER(IntKi), PARAMETER :: HbFbz = 1489 + INTEGER(IntKi), PARAMETER :: HbMbx = 1490 + INTEGER(IntKi), PARAMETER :: HbMby = 1491 + INTEGER(IntKi), PARAMETER :: HbMbz = 1492 + + + ! Nacelle: + + INTEGER(IntKi), PARAMETER :: NcFbx = 1493 + INTEGER(IntKi), PARAMETER :: NcFby = 1494 + INTEGER(IntKi), PARAMETER :: NcFbz = 1495 + INTEGER(IntKi), PARAMETER :: NcMbx = 1496 + INTEGER(IntKi), PARAMETER :: NcMby = 1497 + INTEGER(IntKi), PARAMETER :: NcMbz = 1498 + + + ! TailFin: + + INTEGER(IntKi), PARAMETER :: TFAlpha = 1499 + INTEGER(IntKi), PARAMETER :: TFMach = 1500 + INTEGER(IntKi), PARAMETER :: TFRe = 1501 + INTEGER(IntKi), PARAMETER :: TFVrel = 1502 + INTEGER(IntKi), PARAMETER :: TFVundxi = 1503 + INTEGER(IntKi), PARAMETER :: TFVundyi = 1504 + INTEGER(IntKi), PARAMETER :: TFVundzi = 1505 + INTEGER(IntKi), PARAMETER :: TFVindxi = 1506 + INTEGER(IntKi), PARAMETER :: TFVindyi = 1507 + INTEGER(IntKi), PARAMETER :: TFVindzi = 1508 + INTEGER(IntKi), PARAMETER :: TFVrelxi = 1509 + INTEGER(IntKi), PARAMETER :: TFVrelyi = 1510 + INTEGER(IntKi), PARAMETER :: TFVrelzi = 1511 + INTEGER(IntKi), PARAMETER :: TFSTVxi = 1512 + INTEGER(IntKi), PARAMETER :: TFSTVyi = 1513 + INTEGER(IntKi), PARAMETER :: TFSTVzi = 1514 + INTEGER(IntKi), PARAMETER :: TFFxi = 1515 + INTEGER(IntKi), PARAMETER :: TFFyi = 1516 + INTEGER(IntKi), PARAMETER :: TFFzi = 1517 + INTEGER(IntKi), PARAMETER :: TFMxi = 1518 + INTEGER(IntKi), PARAMETER :: TFMyi = 1519 + INTEGER(IntKi), PARAMETER :: TFMzi = 1520 + + + ! The maximum number of output channels which can be output by the code. + INTEGER(IntKi), PARAMETER :: MaxOutPts = 1520 + +!End of code generated by Matlab script +! =================================================================================================== +!End of code generated by Matlab script +! =================================================================================================== + + INTEGER, PARAMETER :: TwNVUnd(3, 9) = RESHAPE( (/ & ! Undisturbed wind velocity + TwN1VUndx,TwN1VUndy,TwN1VUndz, & + TwN2VUndx,TwN2VUndy,TwN2VUndz, & + TwN3VUndx,TwN3VUndy,TwN3VUndz, & + TwN4VUndx,TwN4VUndy,TwN4VUndz, & + TwN5VUndx,TwN5VUndy,TwN5VUndz, & + TwN6VUndx,TwN6VUndy,TwN6VUndz, & + TwN7VUndx,TwN7VUndy,TwN7VUndz, & + TwN8VUndx,TwN8VUndy,TwN8VUndz, & + TwN9VUndx,TwN9VUndy,TwN9VUndz & + /), (/3, 9/) ) + INTEGER, PARAMETER :: TwNSTV(3, 9) = RESHAPE( (/ & ! Structural translational velocity + TwN1STVx,TwN1STVy,TwN1STVz, & + TwN2STVx,TwN2STVy,TwN2STVz, & + TwN3STVx,TwN3STVy,TwN3STVz, & + TwN4STVx,TwN4STVy,TwN4STVz, & + TwN5STVx,TwN5STVy,TwN5STVz, & + TwN6STVx,TwN6STVy,TwN6STVz, & + TwN7STVx,TwN7STVy,TwN7STVz, & + TwN8STVx,TwN8STVy,TwN8STVz, & + TwN9STVx,TwN9STVy,TwN9STVz & + /), (/3, 9/) ) + INTEGER, PARAMETER :: TwNVRel(9) = (/TwN1VRel,TwN2VRel,TwN3VRel,TwN4VRel,TwN5VRel,TwN6VRel,TwN7VRel,TwN8VRel,TwN9VRel/) ! relative wind speed + INTEGER, PARAMETER :: TwNDynP(9) = (/TwN1DynP,TwN2DynP,TwN3DynP,TwN4DynP,TwN5DynP,TwN6DynP,TwN7DynP,TwN8DynP,TwN9DynP/) ! dynamic pressure + INTEGER, PARAMETER :: TwNRe(9) = (/TwN1Re,TwN2Re,TwN3Re,TwN4Re,TwN5Re,TwN6Re,TwN7Re,TwN8Re,TwN9Re/) ! Reynolds number + INTEGER, PARAMETER :: TwNM(9) = (/TwN1M,TwN2M,TwN3M,TwN4M,TwN5M,TwN6M,TwN7M,TwN8M,TwN9M/) ! Mach number + INTEGER, PARAMETER :: TwNFdx(9) = (/TwN1Fdx,TwN2Fdx,TwN3Fdx,TwN4Fdx,TwN5Fdx,TwN6Fdx,TwN7Fdx,TwN8Fdx,TwN9Fdx/) ! x-component drag force per unit length + INTEGER, PARAMETER :: TwNFdy(9) = (/TwN1Fdy,TwN2Fdy,TwN3Fdy,TwN4Fdy,TwN5Fdy,TwN6Fdy,TwN7Fdy,TwN8Fdy,TwN9Fdy/) ! y-component drag force per unit length + INTEGER, PARAMETER :: TwNFbx(9) = (/TwN1Fbx,TwN2Fbx,TwN3Fbx,TwN4Fbx,TwN5Fbx,TwN6Fbx,TwN7Fbx,TwN8Fbx,TwN9Fbx/) ! x-component buoyant force per unit length + INTEGER, PARAMETER :: TwNFby(9) = (/TwN1Fby,TwN2Fby,TwN3Fby,TwN4Fby,TwN5Fby,TwN6Fby,TwN7Fby,TwN8Fby,TwN9Fby/) ! y-component buoyant force per unit length + INTEGER, PARAMETER :: TwNFbz(9) = (/TwN1Fbz,TwN2Fbz,TwN3Fbz,TwN4Fbz,TwN5Fbz,TwN6Fbz,TwN7Fbz,TwN8Fbz,TwN9Fbz/) ! z-component buoyant force per unit length + INTEGER, PARAMETER :: TwNMbx(9) = (/TwN1Mbx,TwN2Mbx,TwN3Mbx,TwN4Mbx,TwN5Mbx,TwN6Mbx,TwN7Mbx,TwN8Mbx,TwN9Mbx/) ! x-component buoyant moment per unit length + INTEGER, PARAMETER :: TwNMby(9) = (/TwN1Mby,TwN2Mby,TwN3Mby,TwN4Mby,TwN5Mby,TwN6Mby,TwN7Mby,TwN8Mby,TwN9Mby/) ! y-component buoyant moment per unit length + INTEGER, PARAMETER :: TwNMbz(9) = (/TwN1Mbz,TwN2Mbz,TwN3Mbz,TwN4Mbz,TwN5Mbz,TwN6Mbz,TwN7Mbz,TwN8Mbz,TwN9Mbz/) ! z-component buoyant moment per unit length + + INTEGER, PARAMETER :: BAzimuth(3) = (/B1Azimuth,B2Azimuth,B3Azimuth/) ! azimuth angle + INTEGER, PARAMETER :: BPitch(3) = (/B1Pitch, B2Pitch, B3Pitch/) ! pitch + INTEGER, PARAMETER :: BAeroFx(4) = (/B1AeroFx, B2AeroFx, B3AeroFx, B4AeroFx/) ! total blade aero/hydro load (force in x-direction) + INTEGER, PARAMETER :: BAeroFy(4) = (/B1AeroFy, B2AeroFy, B3AeroFy, B4AeroFy/) ! total blade aero/hydro load (force in y-direction) + INTEGER, PARAMETER :: BAeroFz(4) = (/B1AeroFz, B2AeroFz, B3AeroFz, B4AeroFz/) ! total blade aero/hydro load (force in z-direction) + INTEGER, PARAMETER :: BAeroMx(4) = (/B1AeroMx, B2AeroMx, B3AeroMx, B4AeroMx/) ! total blade aero/hydro load (moment in x-direction) + INTEGER, PARAMETER :: BAeroMy(4) = (/B1AeroMy, B2AeroMy, B3AeroMy, B4AeroMy/) ! total blade aero/hydro load (moment in y-direction) + INTEGER, PARAMETER :: BAeroMz(4) = (/B1AeroMz, B2AeroMz, B3AeroMz, B4AeroMz/) ! total blade aero/hydro load (moment in z-direction) + INTEGER, PARAMETER :: BAeroPwr(4) = (/B1AeroPwr, B2AeroPwr, B3AeroPwr, B4AeroPwr/) ! total blade aero/hydro power + INTEGER, PARAMETER :: BAeroFxg(4) = (/B1AeroFxg, B2AeroFxg, B3AeroFxg, B4AeroFxg/) ! total blade aero/hydro load (force in x-direction) in global + INTEGER, PARAMETER :: BAeroFyg(4) = (/B1AeroFyg, B2AeroFyg, B3AeroFyg, B4AeroFyg/) ! total blade aero/hydro load (force in y-direction) in global + INTEGER, PARAMETER :: BAeroFzg(4) = (/B1AeroFzg, B2AeroFzg, B3AeroFzg, B4AeroFzg/) ! total blade aero/hydro load (force in z-direction) in global + INTEGER, PARAMETER :: BAeroMxg(4) = (/B1AeroMxg, B2AeroMxg, B3AeroMxg, B4AeroMxg/) ! total blade aero/hydro load (moment in x-direction) in global + INTEGER, PARAMETER :: BAeroMyg(4) = (/B1AeroMyg, B2AeroMyg, B3AeroMyg, B4AeroMyg/) ! total blade aero/hydro load (moment in y-direction) in global + INTEGER, PARAMETER :: BAeroMzg(4) = (/B1AeroMzg, B2AeroMzg, B3AeroMzg, B4AeroMzg/) ! total blade aero/hydro load (moment in z-direction) in global + + INTEGER, PARAMETER :: BNVUndx(9, 3) = RESHAPE( (/ & ! undisturbed wind velocity (x component) + B1N1VUndx,B1N2VUndx,B1N3VUndx,B1N4VUndx,B1N5VUndx,B1N6VUndx,B1N7VUndx,B1N8VUndx,B1N9VUndx, & + B2N1VUndx,B2N2VUndx,B2N3VUndx,B2N4VUndx,B2N5VUndx,B2N6VUndx,B2N7VUndx,B2N8VUndx,B2N9VUndx, & + B3N1VUndx,B3N2VUndx,B3N3VUndx,B3N4VUndx,B3N5VUndx,B3N6VUndx,B3N7VUndx,B3N8VUndx,B3N9VUndx & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNVUndy(9, 3) = RESHAPE( (/ & ! undisturbed wind velocity (y component) + B1N1VUndy,B1N2VUndy,B1N3VUndy,B1N4VUndy,B1N5VUndy,B1N6VUndy,B1N7VUndy,B1N8VUndy,B1N9VUndy, & + B2N1VUndy,B2N2VUndy,B2N3VUndy,B2N4VUndy,B2N5VUndy,B2N6VUndy,B2N7VUndy,B2N8VUndy,B2N9VUndy, & + B3N1VUndy,B3N2VUndy,B3N3VUndy,B3N4VUndy,B3N5VUndy,B3N6VUndy,B3N7VUndy,B3N8VUndy,B3N9VUndy & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNVUndz(9, 3) = RESHAPE( (/ & ! undisturbed wind velocity (z component) + B1N1VUndz,B1N2VUndz,B1N3VUndz,B1N4VUndz,B1N5VUndz,B1N6VUndz,B1N7VUndz,B1N8VUndz,B1N9VUndz, & + B2N1VUndz,B2N2VUndz,B2N3VUndz,B2N4VUndz,B2N5VUndz,B2N6VUndz,B2N7VUndz,B2N8VUndz,B2N9VUndz, & + B3N1VUndz,B3N2VUndz,B3N3VUndz,B3N4VUndz,B3N5VUndz,B3N6VUndz,B3N7VUndz,B3N8VUndz,B3N9VUndz & + /), (/9, 3/) ) + + INTEGER, PARAMETER :: BNVDisx(9, 3) = RESHAPE( (/ & ! disturbed wind velocity (x component) + B1N1VDisx,B1N2VDisx,B1N3VDisx,B1N4VDisx,B1N5VDisx,B1N6VDisx,B1N7VDisx,B1N8VDisx,B1N9VDisx, & + B2N1VDisx,B2N2VDisx,B2N3VDisx,B2N4VDisx,B2N5VDisx,B2N6VDisx,B2N7VDisx,B2N8VDisx,B2N9VDisx, & + B3N1VDisx,B3N2VDisx,B3N3VDisx,B3N4VDisx,B3N5VDisx,B3N6VDisx,B3N7VDisx,B3N8VDisx,B3N9VDisx & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNVDisy(9, 3) = RESHAPE( (/ & ! disturbed wind velocity (y component) + B1N1VDisy,B1N2VDisy,B1N3VDisy,B1N4VDisy,B1N5VDisy,B1N6VDisy,B1N7VDisy,B1N8VDisy,B1N9VDisy, & + B2N1VDisy,B2N2VDisy,B2N3VDisy,B2N4VDisy,B2N5VDisy,B2N6VDisy,B2N7VDisy,B2N8VDisy,B2N9VDisy, & + B3N1VDisy,B3N2VDisy,B3N3VDisy,B3N4VDisy,B3N5VDisy,B3N6VDisy,B3N7VDisy,B3N8VDisy,B3N9VDisy & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNVDisz(9, 3) = RESHAPE( (/ & ! disturbed wind velocity (z component) + B1N1VDisz,B1N2VDisz,B1N3VDisz,B1N4VDisz,B1N5VDisz,B1N6VDisz,B1N7VDisz,B1N8VDisz,B1N9VDisz, & + B2N1VDisz,B2N2VDisz,B2N3VDisz,B2N4VDisz,B2N5VDisz,B2N6VDisz,B2N7VDisz,B2N8VDisz,B2N9VDisz, & + B3N1VDisz,B3N2VDisz,B3N3VDisz,B3N4VDisz,B3N5VDisz,B3N6VDisz,B3N7VDisz,B3N8VDisz,B3N9VDisz & + /), (/9, 3/) ) + + INTEGER, PARAMETER :: BNSTVx(9, 3) = RESHAPE( (/ & ! structural translational velocity (x component) + B1N1STVx,B1N2STVx,B1N3STVx,B1N4STVx,B1N5STVx,B1N6STVx,B1N7STVx,B1N8STVx,B1N9STVx, & + B2N1STVx,B2N2STVx,B2N3STVx,B2N4STVx,B2N5STVx,B2N6STVx,B2N7STVx,B2N8STVx,B2N9STVx, & + B3N1STVx,B3N2STVx,B3N3STVx,B3N4STVx,B3N5STVx,B3N6STVx,B3N7STVx,B3N8STVx,B3N9STVx & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNSTVy(9, 3) = RESHAPE( (/ & ! structural translational velocity (y component) + B1N1STVy,B1N2STVy,B1N3STVy,B1N4STVy,B1N5STVy,B1N6STVy,B1N7STVy,B1N8STVy,B1N9STVy, & + B2N1STVy,B2N2STVy,B2N3STVy,B2N4STVy,B2N5STVy,B2N6STVy,B2N7STVy,B2N8STVy,B2N9STVy, & + B3N1STVy,B3N2STVy,B3N3STVy,B3N4STVy,B3N5STVy,B3N6STVy,B3N7STVy,B3N8STVy,B3N9STVy & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNSTVz(9, 3) = RESHAPE( (/ & ! structural translational velocity (z component) + B1N1STVz,B1N2STVz,B1N3STVz,B1N4STVz,B1N5STVz,B1N6STVz,B1N7STVz,B1N8STVz,B1N9STVz, & + B2N1STVz,B2N2STVz,B2N3STVz,B2N4STVz,B2N5STVz,B2N6STVz,B2N7STVz,B2N8STVz,B2N9STVz, & + B3N1STVz,B3N2STVz,B3N3STVz,B3N4STVz,B3N5STVz,B3N6STVz,B3N7STVz,B3N8STVz,B3N9STVz & + /), (/9, 3/) ) + + INTEGER, PARAMETER :: BNVRel(9, 3) = RESHAPE( (/ & ! relative wind speed + B1N1VRel,B1N2VRel,B1N3VRel,B1N4VRel,B1N5VRel,B1N6VRel,B1N7VRel,B1N8VRel,B1N9VRel, & + B2N1VRel,B2N2VRel,B2N3VRel,B2N4VRel,B2N5VRel,B2N6VRel,B2N7VRel,B2N8VRel,B2N9VRel, & + B3N1VRel,B3N2VRel,B3N3VRel,B3N4VRel,B3N5VRel,B3N6VRel,B3N7VRel,B3N8VRel,B3N9VRel & + /), (/9, 3/) ) + + INTEGER, PARAMETER :: BNDynP(9, 3) = RESHAPE( (/ & ! dynamic pressure + B1N1DynP,B1N2DynP,B1N3DynP,B1N4DynP,B1N5DynP,B1N6DynP,B1N7DynP,B1N8DynP,B1N9DynP, & + B2N1DynP,B2N2DynP,B2N3DynP,B2N4DynP,B2N5DynP,B2N6DynP,B2N7DynP,B2N8DynP,B2N9DynP, & + B3N1DynP,B3N2DynP,B3N3DynP,B3N4DynP,B3N5DynP,B3N6DynP,B3N7DynP,B3N8DynP,B3N9DynP & + /), (/9, 3/) ) + + INTEGER, PARAMETER :: BNRe(9, 3) = RESHAPE( (/ & ! Reynolds number + B1N1Re,B1N2Re,B1N3Re,B1N4Re,B1N5Re,B1N6Re,B1N7Re,B1N8Re,B1N9Re, & + B2N1Re,B2N2Re,B2N3Re,B2N4Re,B2N5Re,B2N6Re,B2N7Re,B2N8Re,B2N9Re, & + B3N1Re,B3N2Re,B3N3Re,B3N4Re,B3N5Re,B3N6Re,B3N7Re,B3N8Re,B3N9Re & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNM(9, 3) = RESHAPE( (/ & ! Mach number + B1N1M,B1N2M,B1N3M,B1N4M,B1N5M,B1N6M,B1N7M,B1N8M,B1N9M, & + B2N1M,B2N2M,B2N3M,B2N4M,B2N5M,B2N6M,B2N7M,B2N8M,B2N9M, & + B3N1M,B3N2M,B3N3M,B3N4M,B3N5M,B3N6M,B3N7M,B3N8M,B3N9M & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNVIndx(9, 3) = RESHAPE( (/ & ! axial induced wind velocity + B1N1VIndx,B1N2VIndx,B1N3VIndx,B1N4VIndx,B1N5VIndx,B1N6VIndx,B1N7VIndx,B1N8VIndx,B1N9VIndx, & + B2N1VIndx,B2N2VIndx,B2N3VIndx,B2N4VIndx,B2N5VIndx,B2N6VIndx,B2N7VIndx,B2N8VIndx,B2N9VIndx, & + B3N1VIndx,B3N2VIndx,B3N3VIndx,B3N4VIndx,B3N5VIndx,B3N6VIndx,B3N7VIndx,B3N8VIndx,B3N9VIndx & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNVIndy(9, 3) = RESHAPE( (/ & ! tangential induced wind velocity + B1N1VIndy,B1N2VIndy,B1N3VIndy,B1N4VIndy,B1N5VIndy,B1N6VIndy,B1N7VIndy,B1N8VIndy,B1N9VIndy, & + B2N1VIndy,B2N2VIndy,B2N3VIndy,B2N4VIndy,B2N5VIndy,B2N6VIndy,B2N7VIndy,B2N8VIndy,B2N9VIndy, & + B3N1VIndy,B3N2VIndy,B3N3VIndy,B3N4VIndy,B3N5VIndy,B3N6VIndy,B3N7VIndy,B3N8VIndy,B3N9VIndy & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNAxInd(9, 3) = RESHAPE( (/ & ! axial induction factor + B1N1AxInd,B1N2AxInd,B1N3AxInd,B1N4AxInd,B1N5AxInd,B1N6AxInd,B1N7AxInd,B1N8AxInd,B1N9AxInd, & + B2N1AxInd,B2N2AxInd,B2N3AxInd,B2N4AxInd,B2N5AxInd,B2N6AxInd,B2N7AxInd,B2N8AxInd,B2N9AxInd, & + B3N1AxInd,B3N2AxInd,B3N3AxInd,B3N4AxInd,B3N5AxInd,B3N6AxInd,B3N7AxInd,B3N8AxInd,B3N9AxInd & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNTnInd(9, 3) = RESHAPE( (/ & ! tangential induction factor + B1N1TnInd,B1N2TnInd,B1N3TnInd,B1N4TnInd,B1N5TnInd,B1N6TnInd,B1N7TnInd,B1N8TnInd,B1N9TnInd, & + B2N1TnInd,B2N2TnInd,B2N3TnInd,B2N4TnInd,B2N5TnInd,B2N6TnInd,B2N7TnInd,B2N8TnInd,B2N9TnInd, & + B3N1TnInd,B3N2TnInd,B3N3TnInd,B3N4TnInd,B3N5TnInd,B3N6TnInd,B3N7TnInd,B3N8TnInd,B3N9TnInd & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNAlpha(9, 3) = RESHAPE( (/ & ! angle of attack + B1N1Alpha,B1N2Alpha,B1N3Alpha,B1N4Alpha,B1N5Alpha,B1N6Alpha,B1N7Alpha,B1N8Alpha,B1N9Alpha, & + B2N1Alpha,B2N2Alpha,B2N3Alpha,B2N4Alpha,B2N5Alpha,B2N6Alpha,B2N7Alpha,B2N8Alpha,B2N9Alpha, & + B3N1Alpha,B3N2Alpha,B3N3Alpha,B3N4Alpha,B3N5Alpha,B3N6Alpha,B3N7Alpha,B3N8Alpha,B3N9Alpha & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNTheta(9, 3) = RESHAPE( (/ & ! pitch+twist angle + B1N1Theta,B1N2Theta,B1N3Theta,B1N4Theta,B1N5Theta,B1N6Theta,B1N7Theta,B1N8Theta,B1N9Theta, & + B2N1Theta,B2N2Theta,B2N3Theta,B2N4Theta,B2N5Theta,B2N6Theta,B2N7Theta,B2N8Theta,B2N9Theta, & + B3N1Theta,B3N2Theta,B3N3Theta,B3N4Theta,B3N5Theta,B3N6Theta,B3N7Theta,B3N8Theta,B3N9Theta & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNPhi(9, 3) = RESHAPE( (/ & ! inflow angle + B1N1Phi,B1N2Phi,B1N3Phi,B1N4Phi,B1N5Phi,B1N6Phi,B1N7Phi,B1N8Phi,B1N9Phi, & + B2N1Phi,B2N2Phi,B2N3Phi,B2N4Phi,B2N5Phi,B2N6Phi,B2N7Phi,B2N8Phi,B2N9Phi, & + B3N1Phi,B3N2Phi,B3N3Phi,B3N4Phi,B3N5Phi,B3N6Phi,B3N7Phi,B3N8Phi,B3N9Phi & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCurve(9, 3) = RESHAPE( (/ & ! curvature angle + B1N1Curve,B1N2Curve,B1N3Curve,B1N4Curve,B1N5Curve,B1N6Curve,B1N7Curve,B1N8Curve,B1N9Curve, & + B2N1Curve,B2N2Curve,B2N3Curve,B2N4Curve,B2N5Curve,B2N6Curve,B2N7Curve,B2N8Curve,B2N9Curve, & + B3N1Curve,B3N2Curve,B3N3Curve,B3N4Curve,B3N5Curve,B3N6Curve,B3N7Curve,B3N8Curve,B3N9Curve & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCl(9, 3) = RESHAPE( (/ & ! lift force coefficient + B1N1Cl,B1N2Cl,B1N3Cl,B1N4Cl,B1N5Cl,B1N6Cl,B1N7Cl,B1N8Cl,B1N9Cl, & + B2N1Cl,B2N2Cl,B2N3Cl,B2N4Cl,B2N5Cl,B2N6Cl,B2N7Cl,B2N8Cl,B2N9Cl, & + B3N1Cl,B3N2Cl,B3N3Cl,B3N4Cl,B3N5Cl,B3N6Cl,B3N7Cl,B3N8Cl,B3N9Cl & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCd(9, 3) = RESHAPE( (/ & ! drag force coefficient + B1N1Cd,B1N2Cd,B1N3Cd,B1N4Cd,B1N5Cd,B1N6Cd,B1N7Cd,B1N8Cd,B1N9Cd, & + B2N1Cd,B2N2Cd,B2N3Cd,B2N4Cd,B2N5Cd,B2N6Cd,B2N7Cd,B2N8Cd,B2N9Cd, & + B3N1Cd,B3N2Cd,B3N3Cd,B3N4Cd,B3N5Cd,B3N6Cd,B3N7Cd,B3N8Cd,B3N9Cd & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCm(9, 3) = RESHAPE( (/ & ! pitching moment coefficient + B1N1Cm,B1N2Cm,B1N3Cm,B1N4Cm,B1N5Cm,B1N6Cm,B1N7Cm,B1N8Cm,B1N9Cm, & + B2N1Cm,B2N2Cm,B2N3Cm,B2N4Cm,B2N5Cm,B2N6Cm,B2N7Cm,B2N8Cm,B2N9Cm, & + B3N1Cm,B3N2Cm,B3N3Cm,B3N4Cm,B3N5Cm,B3N6Cm,B3N7Cm,B3N8Cm,B3N9Cm & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCx(9, 3) = RESHAPE( (/ & ! normal force (to plane) coefficient + B1N1Cx,B1N2Cx,B1N3Cx,B1N4Cx,B1N5Cx,B1N6Cx,B1N7Cx,B1N8Cx,B1N9Cx, & + B2N1Cx,B2N2Cx,B2N3Cx,B2N4Cx,B2N5Cx,B2N6Cx,B2N7Cx,B2N8Cx,B2N9Cx, & + B3N1Cx,B3N2Cx,B3N3Cx,B3N4Cx,B3N5Cx,B3N6Cx,B3N7Cx,B3N8Cx,B3N9Cx & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCy(9, 3) = RESHAPE( (/ & ! tangential force (to plane) coefficient + B1N1Cy,B1N2Cy,B1N3Cy,B1N4Cy,B1N5Cy,B1N6Cy,B1N7Cy,B1N8Cy,B1N9Cy, & + B2N1Cy,B2N2Cy,B2N3Cy,B2N4Cy,B2N5Cy,B2N6Cy,B2N7Cy,B2N8Cy,B2N9Cy, & + B3N1Cy,B3N2Cy,B3N3Cy,B3N4Cy,B3N5Cy,B3N6Cy,B3N7Cy,B3N8Cy,B3N9Cy & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCn(9, 3) = RESHAPE( (/ & ! normal force (to chord) coefficient + B1N1Cn,B1N2Cn,B1N3Cn,B1N4Cn,B1N5Cn,B1N6Cn,B1N7Cn,B1N8Cn,B1N9Cn, & + B2N1Cn,B2N2Cn,B2N3Cn,B2N4Cn,B2N5Cn,B2N6Cn,B2N7Cn,B2N8Cn,B2N9Cn, & + B3N1Cn,B3N2Cn,B3N3Cn,B3N4Cn,B3N5Cn,B3N6Cn,B3N7Cn,B3N8Cn,B3N9Cn & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCt(9, 3) = RESHAPE( (/ & ! tangential force (to chord) coefficient + B1N1Ct,B1N2Ct,B1N3Ct,B1N4Ct,B1N5Ct,B1N6Ct,B1N7Ct,B1N8Ct,B1N9Ct, & + B2N1Ct,B2N2Ct,B2N3Ct,B2N4Ct,B2N5Ct,B2N6Ct,B2N7Ct,B2N8Ct,B2N9Ct, & + B3N1Ct,B3N2Ct,B3N3Ct,B3N4Ct,B3N5Ct,B3N6Ct,B3N7Ct,B3N8Ct,B3N9Ct & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNFl(9, 3) = RESHAPE( (/ & ! lift force per unit length + B1N1Fl,B1N2Fl,B1N3Fl,B1N4Fl,B1N5Fl,B1N6Fl,B1N7Fl,B1N8Fl,B1N9Fl, & + B2N1Fl,B2N2Fl,B2N3Fl,B2N4Fl,B2N5Fl,B2N6Fl,B2N7Fl,B2N8Fl,B2N9Fl, & + B3N1Fl,B3N2Fl,B3N3Fl,B3N4Fl,B3N5Fl,B3N6Fl,B3N7Fl,B3N8Fl,B3N9Fl & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNFd(9, 3) = RESHAPE( (/ & ! drag force per unit length + B1N1Fd,B1N2Fd,B1N3Fd,B1N4Fd,B1N5Fd,B1N6Fd,B1N7Fd,B1N8Fd,B1N9Fd, & + B2N1Fd,B2N2Fd,B2N3Fd,B2N4Fd,B2N5Fd,B2N6Fd,B2N7Fd,B2N8Fd,B2N9Fd, & + B3N1Fd,B3N2Fd,B3N3Fd,B3N4Fd,B3N5Fd,B3N6Fd,B3N7Fd,B3N8Fd,B3N9Fd & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNMm(9, 3) = RESHAPE( (/ & ! pitching moment per unit length + B1N1Mm,B1N2Mm,B1N3Mm,B1N4Mm,B1N5Mm,B1N6Mm,B1N7Mm,B1N8Mm,B1N9Mm, & + B2N1Mm,B2N2Mm,B2N3Mm,B2N4Mm,B2N5Mm,B2N6Mm,B2N7Mm,B2N8Mm,B2N9Mm, & + B3N1Mm,B3N2Mm,B3N3Mm,B3N4Mm,B3N5Mm,B3N6Mm,B3N7Mm,B3N8Mm,B3N9Mm & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNFx(9, 3) = RESHAPE( (/ & ! normal force (to plane) per unit length + B1N1Fx,B1N2Fx,B1N3Fx,B1N4Fx,B1N5Fx,B1N6Fx,B1N7Fx,B1N8Fx,B1N9Fx, & + B2N1Fx,B2N2Fx,B2N3Fx,B2N4Fx,B2N5Fx,B2N6Fx,B2N7Fx,B2N8Fx,B2N9Fx, & + B3N1Fx,B3N2Fx,B3N3Fx,B3N4Fx,B3N5Fx,B3N6Fx,B3N7Fx,B3N8Fx,B3N9Fx & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNFy(9, 3) = RESHAPE( (/ & ! tangential force (to plane) per unit length + B1N1Fy,B1N2Fy,B1N3Fy,B1N4Fy,B1N5Fy,B1N6Fy,B1N7Fy,B1N8Fy,B1N9Fy, & + B2N1Fy,B2N2Fy,B2N3Fy,B2N4Fy,B2N5Fy,B2N6Fy,B2N7Fy,B2N8Fy,B2N9Fy, & + B3N1Fy,B3N2Fy,B3N3Fy,B3N4Fy,B3N5Fy,B3N6Fy,B3N7Fy,B3N8Fy,B3N9Fy & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNFn(9, 3) = RESHAPE( (/ & ! normal force (to chord) per unit length + B1N1Fn,B1N2Fn,B1N3Fn,B1N4Fn,B1N5Fn,B1N6Fn,B1N7Fn,B1N8Fn,B1N9Fn, & + B2N1Fn,B2N2Fn,B2N3Fn,B2N4Fn,B2N5Fn,B2N6Fn,B2N7Fn,B2N8Fn,B2N9Fn, & + B3N1Fn,B3N2Fn,B3N3Fn,B3N4Fn,B3N5Fn,B3N6Fn,B3N7Fn,B3N8Fn,B3N9Fn & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNFt(9, 3) = RESHAPE( (/ & ! tangential force (to chord) per unit length + B1N1Ft,B1N2Ft,B1N3Ft,B1N4Ft,B1N5Ft,B1N6Ft,B1N7Ft,B1N8Ft,B1N9Ft, & + B2N1Ft,B2N2Ft,B2N3Ft,B2N4Ft,B2N5Ft,B2N6Ft,B2N7Ft,B2N8Ft,B2N9Ft, & + B3N1Ft,B3N2Ft,B3N3Ft,B3N4Ft,B3N5Ft,B3N6Ft,B3N7Ft,B3N8Ft,B3N9Ft & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNClrnc(9, 3) = RESHAPE( (/ & ! tower clearance + B1N1Clrnc,B1N2Clrnc,B1N3Clrnc,B1N4Clrnc,B1N5Clrnc,B1N6Clrnc,B1N7Clrnc,B1N8Clrnc,B1N9Clrnc, & + B2N1Clrnc,B2N2Clrnc,B2N3Clrnc,B2N4Clrnc,B2N5Clrnc,B2N6Clrnc,B2N7Clrnc,B2N8Clrnc,B2N9Clrnc, & + B3N1Clrnc,B3N2Clrnc,B3N3Clrnc,B3N4Clrnc,B3N5Clrnc,B3N6Clrnc,B3N7Clrnc,B3N8Clrnc,B3N9Clrnc & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCpmin(9, 3) = RESHAPE( (/ & ! pressure coefficient + B1N1Cpmin,B1N2Cpmin,B1N3Cpmin,B1N4Cpmin,B1N5Cpmin,B1N6Cpmin,B1N7Cpmin,B1N8Cpmin,B1N9Cpmin, & + B2N1Cpmin,B2N2Cpmin,B2N3Cpmin,B2N4Cpmin,B2N5Cpmin,B2N6Cpmin,B2N7Cpmin,B2N8Cpmin,B2N9Cpmin, & + B3N1Cpmin,B3N2Cpmin,B3N3Cpmin,B3N4Cpmin,B3N5Cpmin,B3N6Cpmin,B3N7Cpmin,B3N8Cpmin,B3N9Cpmin & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNSigCr(9, 3) = RESHAPE( (/ & ! Critical cavitation number + B1N1SigCr,B1N2SigCr,B1N3SigCr,B1N4SigCr,B1N5SigCr,B1N6SigCr,B1N7SigCr,B1N8SigCr,B1N9SigCr, & + B2N1SigCr,B2N2SigCr,B2N3SigCr,B2N4SigCr,B2N5SigCr,B2N6SigCr,B2N7SigCr,B2N8SigCr,B2N9SigCr, & + B3N1SigCr,B3N2SigCr,B3N3SigCr,B3N4SigCr,B3N5SigCr,B3N6SigCr,B3N7SigCr,B3N8SigCr,B3N9SigCr & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNSgCav(9, 3) = RESHAPE( (/ & ! Cavitation number + B1N1SgCav,B1N2SgCav,B1N3SgCav,B1N4SgCav,B1N5SgCav,B1N6SgCav,B1N7SgCav,B1N8SgCav,B1N9SgCav, & + B2N1SgCav,B2N2SgCav,B2N3SgCav,B2N4SgCav,B2N5SgCav,B2N6SgCav,B2N7SgCav,B2N8SgCav,B2N9SgCav, & + B3N1SgCav,B3N2SgCav,B3N3SgCav,B3N4SgCav,B3N5SgCav,B3N6SgCav,B3N7SgCav,B3N8SgCav,B3N9SgCav & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNGam(9,3) = RESHAPE( (/ & ! Vorticity gamma + B1N1Gam,B1N2Gam,B1N3Gam,B1N4Gam,B1N5Gam,B1N6Gam,B1N7Gam,B1N8Gam,B1N9Gam, & + B2N1Gam,B2N2Gam,B2N3Gam,B2N4Gam,B2N5Gam,B2N6Gam,B2N7Gam,B2N8Gam,B2N9Gam, & + B3N1Gam,B3N2Gam,B3N3Gam,B3N4Gam,B3N5Gam,B3N6Gam,B3N7Gam,B3N8Gam,B3N9Gam & + /), (/9,3/) ) + INTEGER, PARAMETER :: BNFbn(9, 3) = RESHAPE( (/ & ! normal buoyant force (to chord) per unit length + B1N1Fbn,B1N2Fbn,B1N3Fbn,B1N4Fbn,B1N5Fbn,B1N6Fbn,B1N7Fbn,B1N8Fbn,B1N9Fbn, & + B2N1Fbn,B2N2Fbn,B2N3Fbn,B2N4Fbn,B2N5Fbn,B2N6Fbn,B2N7Fbn,B2N8Fbn,B2N9Fbn, & + B3N1Fbn,B3N2Fbn,B3N3Fbn,B3N4Fbn,B3N5Fbn,B3N6Fbn,B3N7Fbn,B3N8Fbn,B3N9Fbn & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNFbt(9, 3) = RESHAPE( (/ & ! tangential buoyant force (to chord) per unit length + B1N1Fbt,B1N2Fbt,B1N3Fbt,B1N4Fbt,B1N5Fbt,B1N6Fbt,B1N7Fbt,B1N8Fbt,B1N9Fbt, & + B2N1Fbt,B2N2Fbt,B2N3Fbt,B2N4Fbt,B2N5Fbt,B2N6Fbt,B2N7Fbt,B2N8Fbt,B2N9Fbt, & + B3N1Fbt,B3N2Fbt,B3N3Fbt,B3N4Fbt,B3N5Fbt,B3N6Fbt,B3N7Fbt,B3N8Fbt,B3N9Fbt & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNFbs(9, 3) = RESHAPE( (/ & ! spanwise buoyant force per unit length + B1N1Fbs,B1N2Fbs,B1N3Fbs,B1N4Fbs,B1N5Fbs,B1N6Fbs,B1N7Fbs,B1N8Fbs,B1N9Fbs, & + B2N1Fbs,B2N2Fbs,B2N3Fbs,B2N4Fbs,B2N5Fbs,B2N6Fbs,B2N7Fbs,B2N8Fbs,B2N9Fbs, & + B3N1Fbs,B3N2Fbs,B3N3Fbs,B3N4Fbs,B3N5Fbs,B3N6Fbs,B3N7Fbs,B3N8Fbs,B3N9Fbs & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNMbn(9, 3) = RESHAPE( (/ & ! normal buoyant moment (to chord) per unit length + B1N1Mbn,B1N2Mbn,B1N3Mbn,B1N4Mbn,B1N5Mbn,B1N6Mbn,B1N7Mbn,B1N8Mbn,B1N9Mbn, & + B2N1Mbn,B2N2Mbn,B2N3Mbn,B2N4Mbn,B2N5Mbn,B2N6Mbn,B2N7Mbn,B2N8Mbn,B2N9Mbn, & + B3N1Mbn,B3N2Mbn,B3N3Mbn,B3N4Mbn,B3N5Mbn,B3N6Mbn,B3N7Mbn,B3N8Mbn,B3N9Mbn & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNMbt(9, 3) = RESHAPE( (/ & ! tangential buoyant moment (to chord) per unit length + B1N1Mbt,B1N2Mbt,B1N3Mbt,B1N4Mbt,B1N5Mbt,B1N6Mbt,B1N7Mbt,B1N8Mbt,B1N9Mbt, & + B2N1Mbt,B2N2Mbt,B2N3Mbt,B2N4Mbt,B2N5Mbt,B2N6Mbt,B2N7Mbt,B2N8Mbt,B2N9Mbt, & + B3N1Mbt,B3N2Mbt,B3N3Mbt,B3N4Mbt,B3N5Mbt,B3N6Mbt,B3N7Mbt,B3N8Mbt,B3N9Mbt & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNMbs(9, 3) = RESHAPE( (/ & ! spanwise buoyant moment per unit length + B1N1Mbs,B1N2Mbs,B1N3Mbs,B1N4Mbs,B1N5Mbs,B1N6Mbs,B1N7Mbs,B1N8Mbs,B1N9Mbs, & + B2N1Mbs,B2N2Mbs,B2N3Mbs,B2N4Mbs,B2N5Mbs,B2N6Mbs,B2N7Mbs,B2N8Mbs,B2N9Mbs, & + B3N1Mbs,B3N2Mbs,B3N3Mbs,B3N4Mbs,B3N5Mbs,B3N6Mbs,B3N7Mbs,B3N8Mbs,B3N9Mbs & + /), (/9, 3/) ) + + + INTEGER(IntKi), PARAMETER :: MaxBl = 3 ! Maximum number of blades allowed in simulation + + + + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(1588) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "B1AEROFX ","B1AEROFXG","B1AEROFY ","B1AEROFYG","B1AEROFZ ","B1AEROFZG","B1AEROMX ","B1AEROMXG", & + "B1AEROMY ","B1AEROMYG","B1AEROMZ ","B1AEROMZG","B1AEROPWR","B1AZIMUTH","B1FLDFX ","B1FLDFXG ", & + "B1FLDFY ","B1FLDFYG ","B1FLDFZ ","B1FLDFZG ","B1FLDMX ","B1FLDMXG ","B1FLDMY ","B1FLDMYG ", & + "B1FLDMZ ","B1FLDMZG ","B1FLDPWR ","B1N1ALPHA","B1N1AXIND","B1N1CD ","B1N1CL ","B1N1CLRNC", & + "B1N1CM ","B1N1CN ","B1N1CPMIN","B1N1CT ","B1N1CURVE","B1N1CX ","B1N1CY ","B1N1DYNP ", & + "B1N1FBN ","B1N1FBS ","B1N1FBT ","B1N1FD ","B1N1FL ","B1N1FN ","B1N1FT ","B1N1FX ", & + "B1N1FY ","B1N1GAM ","B1N1M ","B1N1MBN ","B1N1MBS ","B1N1MBT ","B1N1MM ","B1N1PHI ", & + "B1N1RE ","B1N1SGCAV","B1N1SIGCR","B1N1STVX ","B1N1STVY ","B1N1STVZ ","B1N1THETA","B1N1TNIND", & + "B1N1VDISX","B1N1VDISY","B1N1VDISZ","B1N1VINDX","B1N1VINDY","B1N1VREL ","B1N1VUNDX","B1N1VUNDY", & + "B1N1VUNDZ","B1N2ALPHA","B1N2AXIND","B1N2CD ","B1N2CL ","B1N2CLRNC","B1N2CM ","B1N2CN ", & + "B1N2CPMIN","B1N2CT ","B1N2CURVE","B1N2CX ","B1N2CY ","B1N2DYNP ","B1N2FBN ","B1N2FBS ", & + "B1N2FBT ","B1N2FD ","B1N2FL ","B1N2FN ","B1N2FT ","B1N2FX ","B1N2FY ","B1N2GAM ", & + "B1N2M ","B1N2MBN ","B1N2MBS ","B1N2MBT ","B1N2MM ","B1N2PHI ","B1N2RE ","B1N2SGCAV", & + "B1N2SIGCR","B1N2STVX ","B1N2STVY ","B1N2STVZ ","B1N2THETA","B1N2TNIND","B1N2VDISX","B1N2VDISY", & + "B1N2VDISZ","B1N2VINDX","B1N2VINDY","B1N2VREL ","B1N2VUNDX","B1N2VUNDY","B1N2VUNDZ","B1N3ALPHA", & + "B1N3AXIND","B1N3CD ","B1N3CL ","B1N3CLRNC","B1N3CM ","B1N3CN ","B1N3CPMIN","B1N3CT ", & + "B1N3CURVE","B1N3CX ","B1N3CY ","B1N3DYNP ","B1N3FBN ","B1N3FBS ","B1N3FBT ","B1N3FD ", & + "B1N3FL ","B1N3FN ","B1N3FT ","B1N3FX ","B1N3FY ","B1N3GAM ","B1N3M ","B1N3MBN ", & + "B1N3MBS ","B1N3MBT ","B1N3MM ","B1N3PHI ","B1N3RE ","B1N3SGCAV","B1N3SIGCR","B1N3STVX ", & + "B1N3STVY ","B1N3STVZ ","B1N3THETA","B1N3TNIND","B1N3VDISX","B1N3VDISY","B1N3VDISZ","B1N3VINDX", & + "B1N3VINDY","B1N3VREL ","B1N3VUNDX","B1N3VUNDY","B1N3VUNDZ","B1N4ALPHA","B1N4AXIND","B1N4CD ", & + "B1N4CL ","B1N4CLRNC","B1N4CM ","B1N4CN ","B1N4CPMIN","B1N4CT ","B1N4CURVE","B1N4CX ", & + "B1N4CY ","B1N4DYNP ","B1N4FBN ","B1N4FBS ","B1N4FBT ","B1N4FD ","B1N4FL ","B1N4FN ", & + "B1N4FT ","B1N4FX ","B1N4FY ","B1N4GAM ","B1N4M ","B1N4MBN ","B1N4MBS ","B1N4MBT ", & + "B1N4MM ","B1N4PHI ","B1N4RE ","B1N4SGCAV","B1N4SIGCR","B1N4STVX ","B1N4STVY ","B1N4STVZ ", & + "B1N4THETA","B1N4TNIND","B1N4VDISX","B1N4VDISY","B1N4VDISZ","B1N4VINDX","B1N4VINDY","B1N4VREL ", & + "B1N4VUNDX","B1N4VUNDY","B1N4VUNDZ","B1N5ALPHA","B1N5AXIND","B1N5CD ","B1N5CL ","B1N5CLRNC", & + "B1N5CM ","B1N5CN ","B1N5CPMIN","B1N5CT ","B1N5CURVE","B1N5CX ","B1N5CY ","B1N5DYNP ", & + "B1N5FBN ","B1N5FBS ","B1N5FBT ","B1N5FD ","B1N5FL ","B1N5FN ","B1N5FT ","B1N5FX ", & + "B1N5FY ","B1N5GAM ","B1N5M ","B1N5MBN ","B1N5MBS ","B1N5MBT ","B1N5MM ","B1N5PHI ", & + "B1N5RE ","B1N5SGCAV","B1N5SIGCR","B1N5STVX ","B1N5STVY ","B1N5STVZ ","B1N5THETA","B1N5TNIND", & + "B1N5VDISX","B1N5VDISY","B1N5VDISZ","B1N5VINDX","B1N5VINDY","B1N5VREL ","B1N5VUNDX","B1N5VUNDY", & + "B1N5VUNDZ","B1N6ALPHA","B1N6AXIND","B1N6CD ","B1N6CL ","B1N6CLRNC","B1N6CM ","B1N6CN ", & + "B1N6CPMIN","B1N6CT ","B1N6CURVE","B1N6CX ","B1N6CY ","B1N6DYNP ","B1N6FBN ","B1N6FBS ", & + "B1N6FBT ","B1N6FD ","B1N6FL ","B1N6FN ","B1N6FT ","B1N6FX ","B1N6FY ","B1N6GAM ", & + "B1N6M ","B1N6MBN ","B1N6MBS ","B1N6MBT ","B1N6MM ","B1N6PHI ","B1N6RE ","B1N6SGCAV", & + "B1N6SIGCR","B1N6STVX ","B1N6STVY ","B1N6STVZ ","B1N6THETA","B1N6TNIND","B1N6VDISX","B1N6VDISY", & + "B1N6VDISZ","B1N6VINDX","B1N6VINDY","B1N6VREL ","B1N6VUNDX","B1N6VUNDY","B1N6VUNDZ","B1N7ALPHA", & + "B1N7AXIND","B1N7CD ","B1N7CL ","B1N7CLRNC","B1N7CM ","B1N7CN ","B1N7CPMIN","B1N7CT ", & + "B1N7CURVE","B1N7CX ","B1N7CY ","B1N7DYNP ","B1N7FBN ","B1N7FBS ","B1N7FBT ","B1N7FD ", & + "B1N7FL ","B1N7FN ","B1N7FT ","B1N7FX ","B1N7FY ","B1N7GAM ","B1N7M ","B1N7MBN ", & + "B1N7MBS ","B1N7MBT ","B1N7MM ","B1N7PHI ","B1N7RE ","B1N7SGCAV","B1N7SIGCR","B1N7STVX ", & + "B1N7STVY ","B1N7STVZ ","B1N7THETA","B1N7TNIND","B1N7VDISX","B1N7VDISY","B1N7VDISZ","B1N7VINDX", & + "B1N7VINDY","B1N7VREL ","B1N7VUNDX","B1N7VUNDY","B1N7VUNDZ","B1N8ALPHA","B1N8AXIND","B1N8CD ", & + "B1N8CL ","B1N8CLRNC","B1N8CM ","B1N8CN ","B1N8CPMIN","B1N8CT ","B1N8CURVE","B1N8CX ", & + "B1N8CY ","B1N8DYNP ","B1N8FBN ","B1N8FBS ","B1N8FBT ","B1N8FD ","B1N8FL ","B1N8FN ", & + "B1N8FT ","B1N8FX ","B1N8FY ","B1N8GAM ","B1N8M ","B1N8MBN ","B1N8MBS ","B1N8MBT ", & + "B1N8MM ","B1N8PHI ","B1N8RE ","B1N8SGCAV","B1N8SIGCR","B1N8STVX ","B1N8STVY ","B1N8STVZ ", & + "B1N8THETA","B1N8TNIND","B1N8VDISX","B1N8VDISY","B1N8VDISZ","B1N8VINDX","B1N8VINDY","B1N8VREL ", & + "B1N8VUNDX","B1N8VUNDY","B1N8VUNDZ","B1N9ALPHA","B1N9AXIND","B1N9CD ","B1N9CL ","B1N9CLRNC", & + "B1N9CM ","B1N9CN ","B1N9CPMIN","B1N9CT ","B1N9CURVE","B1N9CX ","B1N9CY ","B1N9DYNP ", & + "B1N9FBN ","B1N9FBS ","B1N9FBT ","B1N9FD ","B1N9FL ","B1N9FN ","B1N9FT ","B1N9FX ", & + "B1N9FY ","B1N9GAM ","B1N9M ","B1N9MBN ","B1N9MBS ","B1N9MBT ","B1N9MM ","B1N9PHI ", & + "B1N9RE ","B1N9SGCAV","B1N9SIGCR","B1N9STVX ","B1N9STVY ","B1N9STVZ ","B1N9THETA","B1N9TNIND", & + "B1N9VDISX","B1N9VDISY","B1N9VDISZ","B1N9VINDX","B1N9VINDY","B1N9VREL ","B1N9VUNDX","B1N9VUNDY", & + "B1N9VUNDZ","B1PITCH ","B2AEROFX ","B2AEROFXG","B2AEROFY ","B2AEROFYG","B2AEROFZ ","B2AEROFZG", & + "B2AEROMX ","B2AEROMXG","B2AEROMY ","B2AEROMYG","B2AEROMZ ","B2AEROMZG","B2AEROPWR","B2AZIMUTH", & + "B2FLDFX ","B2FLDFXG ","B2FLDFY ","B2FLDFYG ","B2FLDFZ ","B2FLDFZG ","B2FLDMX ","B2FLDMXG ", & + "B2FLDMY ","B2FLDMYG ","B2FLDMZ ","B2FLDMZG ","B2FLDPWR ","B2N1ALPHA","B2N1AXIND","B2N1CD ", & + "B2N1CL ","B2N1CLRNC","B2N1CM ","B2N1CN ","B2N1CPMIN","B2N1CT ","B2N1CURVE","B2N1CX ", & + "B2N1CY ","B2N1DYNP ","B2N1FBN ","B2N1FBS ","B2N1FBT ","B2N1FD ","B2N1FL ","B2N1FN ", & + "B2N1FT ","B2N1FX ","B2N1FY ","B2N1GAM ","B2N1M ","B2N1MBN ","B2N1MBS ","B2N1MBT ", & + "B2N1MM ","B2N1PHI ","B2N1RE ","B2N1SGCAV","B2N1SIGCR","B2N1STVX ","B2N1STVY ","B2N1STVZ ", & + "B2N1THETA","B2N1TNIND","B2N1VDISX","B2N1VDISY","B2N1VDISZ","B2N1VINDX","B2N1VINDY","B2N1VREL ", & + "B2N1VUNDX","B2N1VUNDY","B2N1VUNDZ","B2N2ALPHA","B2N2AXIND","B2N2CD ","B2N2CL ","B2N2CLRNC", & + "B2N2CM ","B2N2CN ","B2N2CPMIN","B2N2CT ","B2N2CURVE","B2N2CX ","B2N2CY ","B2N2DYNP ", & + "B2N2FBN ","B2N2FBS ","B2N2FBT ","B2N2FD ","B2N2FL ","B2N2FN ","B2N2FT ","B2N2FX ", & + "B2N2FY ","B2N2GAM ","B2N2M ","B2N2MBN ","B2N2MBS ","B2N2MBT ","B2N2MM ","B2N2PHI ", & + "B2N2RE ","B2N2SGCAV","B2N2SIGCR","B2N2STVX ","B2N2STVY ","B2N2STVZ ","B2N2THETA","B2N2TNIND", & + "B2N2VDISX","B2N2VDISY","B2N2VDISZ","B2N2VINDX","B2N2VINDY","B2N2VREL ","B2N2VUNDX","B2N2VUNDY", & + "B2N2VUNDZ","B2N3ALPHA","B2N3AXIND","B2N3CD ","B2N3CL ","B2N3CLRNC","B2N3CM ","B2N3CN ", & + "B2N3CPMIN","B2N3CT ","B2N3CURVE","B2N3CX ","B2N3CY ","B2N3DYNP ","B2N3FBN ","B2N3FBS ", & + "B2N3FBT ","B2N3FD ","B2N3FL ","B2N3FN ","B2N3FT ","B2N3FX ","B2N3FY ","B2N3GAM ", & + "B2N3M ","B2N3MBN ","B2N3MBS ","B2N3MBT ","B2N3MM ","B2N3PHI ","B2N3RE ","B2N3SGCAV", & + "B2N3SIGCR","B2N3STVX ","B2N3STVY ","B2N3STVZ ","B2N3THETA","B2N3TNIND","B2N3VDISX","B2N3VDISY", & + "B2N3VDISZ","B2N3VINDX","B2N3VINDY","B2N3VREL ","B2N3VUNDX","B2N3VUNDY","B2N3VUNDZ","B2N4ALPHA", & + "B2N4AXIND","B2N4CD ","B2N4CL ","B2N4CLRNC","B2N4CM ","B2N4CN ","B2N4CPMIN","B2N4CT ", & + "B2N4CURVE","B2N4CX ","B2N4CY ","B2N4DYNP ","B2N4FBN ","B2N4FBS ","B2N4FBT ","B2N4FD ", & + "B2N4FL ","B2N4FN ","B2N4FT ","B2N4FX ","B2N4FY ","B2N4GAM ","B2N4M ","B2N4MBN ", & + "B2N4MBS ","B2N4MBT ","B2N4MM ","B2N4PHI ","B2N4RE ","B2N4SGCAV","B2N4SIGCR","B2N4STVX ", & + "B2N4STVY ","B2N4STVZ ","B2N4THETA","B2N4TNIND","B2N4VDISX","B2N4VDISY","B2N4VDISZ","B2N4VINDX", & + "B2N4VINDY","B2N4VREL ","B2N4VUNDX","B2N4VUNDY","B2N4VUNDZ","B2N5ALPHA","B2N5AXIND","B2N5CD ", & + "B2N5CL ","B2N5CLRNC","B2N5CM ","B2N5CN ","B2N5CPMIN","B2N5CT ","B2N5CURVE","B2N5CX ", & + "B2N5CY ","B2N5DYNP ","B2N5FBN ","B2N5FBS ","B2N5FBT ","B2N5FD ","B2N5FL ","B2N5FN ", & + "B2N5FT ","B2N5FX ","B2N5FY ","B2N5GAM ","B2N5M ","B2N5MBN ","B2N5MBS ","B2N5MBT ", & + "B2N5MM ","B2N5PHI ","B2N5RE ","B2N5SGCAV","B2N5SIGCR","B2N5STVX ","B2N5STVY ","B2N5STVZ ", & + "B2N5THETA","B2N5TNIND","B2N5VDISX","B2N5VDISY","B2N5VDISZ","B2N5VINDX","B2N5VINDY","B2N5VREL ", & + "B2N5VUNDX","B2N5VUNDY","B2N5VUNDZ","B2N6ALPHA","B2N6AXIND","B2N6CD ","B2N6CL ","B2N6CLRNC", & + "B2N6CM ","B2N6CN ","B2N6CPMIN","B2N6CT ","B2N6CURVE","B2N6CX ","B2N6CY ","B2N6DYNP ", & + "B2N6FBN ","B2N6FBS ","B2N6FBT ","B2N6FD ","B2N6FL ","B2N6FN ","B2N6FT ","B2N6FX ", & + "B2N6FY ","B2N6GAM ","B2N6M ","B2N6MBN ","B2N6MBS ","B2N6MBT ","B2N6MM ","B2N6PHI ", & + "B2N6RE ","B2N6SGCAV","B2N6SIGCR","B2N6STVX ","B2N6STVY ","B2N6STVZ ","B2N6THETA","B2N6TNIND", & + "B2N6VDISX","B2N6VDISY","B2N6VDISZ","B2N6VINDX","B2N6VINDY","B2N6VREL ","B2N6VUNDX","B2N6VUNDY", & + "B2N6VUNDZ","B2N7ALPHA","B2N7AXIND","B2N7CD ","B2N7CL ","B2N7CLRNC","B2N7CM ","B2N7CN ", & + "B2N7CPMIN","B2N7CT ","B2N7CURVE","B2N7CX ","B2N7CY ","B2N7DYNP ","B2N7FBN ","B2N7FBS ", & + "B2N7FBT ","B2N7FD ","B2N7FL ","B2N7FN ","B2N7FT ","B2N7FX ","B2N7FY ","B2N7GAM ", & + "B2N7M ","B2N7MBN ","B2N7MBS ","B2N7MBT ","B2N7MM ","B2N7PHI ","B2N7RE ","B2N7SGCAV", & + "B2N7SIGCR","B2N7STVX ","B2N7STVY ","B2N7STVZ ","B2N7THETA","B2N7TNIND","B2N7VDISX","B2N7VDISY", & + "B2N7VDISZ","B2N7VINDX","B2N7VINDY","B2N7VREL ","B2N7VUNDX","B2N7VUNDY","B2N7VUNDZ","B2N8ALPHA", & + "B2N8AXIND","B2N8CD ","B2N8CL ","B2N8CLRNC","B2N8CM ","B2N8CN ","B2N8CPMIN","B2N8CT ", & + "B2N8CURVE","B2N8CX ","B2N8CY ","B2N8DYNP ","B2N8FBN ","B2N8FBS ","B2N8FBT ","B2N8FD ", & + "B2N8FL ","B2N8FN ","B2N8FT ","B2N8FX ","B2N8FY ","B2N8GAM ","B2N8M ","B2N8MBN ", & + "B2N8MBS ","B2N8MBT ","B2N8MM ","B2N8PHI ","B2N8RE ","B2N8SGCAV","B2N8SIGCR","B2N8STVX ", & + "B2N8STVY ","B2N8STVZ ","B2N8THETA","B2N8TNIND","B2N8VDISX","B2N8VDISY","B2N8VDISZ","B2N8VINDX", & + "B2N8VINDY","B2N8VREL ","B2N8VUNDX","B2N8VUNDY","B2N8VUNDZ","B2N9ALPHA","B2N9AXIND","B2N9CD ", & + "B2N9CL ","B2N9CLRNC","B2N9CM ","B2N9CN ","B2N9CPMIN","B2N9CT ","B2N9CURVE","B2N9CX ", & + "B2N9CY ","B2N9DYNP ","B2N9FBN ","B2N9FBS ","B2N9FBT ","B2N9FD ","B2N9FL ","B2N9FN ", & + "B2N9FT ","B2N9FX ","B2N9FY ","B2N9GAM ","B2N9M ","B2N9MBN ","B2N9MBS ","B2N9MBT ", & + "B2N9MM ","B2N9PHI ","B2N9RE ","B2N9SGCAV","B2N9SIGCR","B2N9STVX ","B2N9STVY ","B2N9STVZ ", & + "B2N9THETA","B2N9TNIND","B2N9VDISX","B2N9VDISY","B2N9VDISZ","B2N9VINDX","B2N9VINDY","B2N9VREL ", & + "B2N9VUNDX","B2N9VUNDY","B2N9VUNDZ","B2PITCH ","B3AEROFX ","B3AEROFXG","B3AEROFY ","B3AEROFYG", & + "B3AEROFZ ","B3AEROFZG","B3AEROMX ","B3AEROMXG","B3AEROMY ","B3AEROMYG","B3AEROMZ ","B3AEROMZG", & + "B3AEROPWR","B3AZIMUTH","B3FLDFX ","B3FLDFXG ","B3FLDFY ","B3FLDFYG ","B3FLDFZ ","B3FLDFZG ", & + "B3FLDMX ","B3FLDMXG ","B3FLDMY ","B3FLDMYG ","B3FLDMZ ","B3FLDMZG ","B3FLDPWR ","B3N1ALPHA", & + "B3N1AXIND","B3N1CD ","B3N1CL ","B3N1CLRNC","B3N1CM ","B3N1CN ","B3N1CPMIN","B3N1CT ", & + "B3N1CURVE","B3N1CX ","B3N1CY ","B3N1DYNP ","B3N1FBN ","B3N1FBS ","B3N1FBT ","B3N1FD ", & + "B3N1FL ","B3N1FN ","B3N1FT ","B3N1FX ","B3N1FY ","B3N1GAM ","B3N1M ","B3N1MBN ", & + "B3N1MBS ","B3N1MBT ","B3N1MM ","B3N1PHI ","B3N1RE ","B3N1SGCAV","B3N1SIGCR","B3N1STVX ", & + "B3N1STVY ","B3N1STVZ ","B3N1THETA","B3N1TNIND","B3N1VDISX","B3N1VDISY","B3N1VDISZ","B3N1VINDX", & + "B3N1VINDY","B3N1VREL ","B3N1VUNDX","B3N1VUNDY","B3N1VUNDZ","B3N2ALPHA","B3N2AXIND","B3N2CD ", & + "B3N2CL ","B3N2CLRNC","B3N2CM ","B3N2CN ","B3N2CPMIN","B3N2CT ","B3N2CURVE","B3N2CX ", & + "B3N2CY ","B3N2DYNP ","B3N2FBN ","B3N2FBS ","B3N2FBT ","B3N2FD ","B3N2FL ","B3N2FN ", & + "B3N2FT ","B3N2FX ","B3N2FY ","B3N2GAM ","B3N2M ","B3N2MBN ","B3N2MBS ","B3N2MBT ", & + "B3N2MM ","B3N2PHI ","B3N2RE ","B3N2SGCAV","B3N2SIGCR","B3N2STVX ","B3N2STVY ","B3N2STVZ ", & + "B3N2THETA","B3N2TNIND","B3N2VDISX","B3N2VDISY","B3N2VDISZ","B3N2VINDX","B3N2VINDY","B3N2VREL ", & + "B3N2VUNDX","B3N2VUNDY","B3N2VUNDZ","B3N3ALPHA","B3N3AXIND","B3N3CD ","B3N3CL ","B3N3CLRNC", & + "B3N3CM ","B3N3CN ","B3N3CPMIN","B3N3CT ","B3N3CURVE","B3N3CX ","B3N3CY ","B3N3DYNP ", & + "B3N3FBN ","B3N3FBS ","B3N3FBT ","B3N3FD ","B3N3FL ","B3N3FN ","B3N3FT ","B3N3FX ", & + "B3N3FY ","B3N3GAM ","B3N3M ","B3N3MBN ","B3N3MBS ","B3N3MBT ","B3N3MM ","B3N3PHI ", & + "B3N3RE ","B3N3SGCAV","B3N3SIGCR","B3N3STVX ","B3N3STVY ","B3N3STVZ ","B3N3THETA","B3N3TNIND", & + "B3N3VDISX","B3N3VDISY","B3N3VDISZ","B3N3VINDX","B3N3VINDY","B3N3VREL ","B3N3VUNDX","B3N3VUNDY", & + "B3N3VUNDZ","B3N4ALPHA","B3N4AXIND","B3N4CD ","B3N4CL ","B3N4CLRNC","B3N4CM ","B3N4CN ", & + "B3N4CPMIN","B3N4CT ","B3N4CURVE","B3N4CX ","B3N4CY ","B3N4DYNP ","B3N4FBN ","B3N4FBS ", & + "B3N4FBT ","B3N4FD ","B3N4FL ","B3N4FN ","B3N4FT ","B3N4FX ","B3N4FY ","B3N4GAM ", & + "B3N4M ","B3N4MBN ","B3N4MBS ","B3N4MBT ","B3N4MM ","B3N4PHI ","B3N4RE ","B3N4SGCAV", & + "B3N4SIGCR","B3N4STVX ","B3N4STVY ","B3N4STVZ ","B3N4THETA","B3N4TNIND","B3N4VDISX","B3N4VDISY", & + "B3N4VDISZ","B3N4VINDX","B3N4VINDY","B3N4VREL ","B3N4VUNDX","B3N4VUNDY","B3N4VUNDZ","B3N5ALPHA", & + "B3N5AXIND","B3N5CD ","B3N5CL ","B3N5CLRNC","B3N5CM ","B3N5CN ","B3N5CPMIN","B3N5CT ", & + "B3N5CURVE","B3N5CX ","B3N5CY ","B3N5DYNP ","B3N5FBN ","B3N5FBS ","B3N5FBT ","B3N5FD ", & + "B3N5FL ","B3N5FN ","B3N5FT ","B3N5FX ","B3N5FY ","B3N5GAM ","B3N5M ","B3N5MBN ", & + "B3N5MBS ","B3N5MBT ","B3N5MM ","B3N5PHI ","B3N5RE ","B3N5SGCAV","B3N5SIGCR","B3N5STVX ", & + "B3N5STVY ","B3N5STVZ ","B3N5THETA","B3N5TNIND","B3N5VDISX","B3N5VDISY","B3N5VDISZ","B3N5VINDX", & + "B3N5VINDY","B3N5VREL ","B3N5VUNDX","B3N5VUNDY","B3N5VUNDZ","B3N6ALPHA","B3N6AXIND","B3N6CD ", & + "B3N6CL ","B3N6CLRNC","B3N6CM ","B3N6CN ","B3N6CPMIN","B3N6CT ","B3N6CURVE","B3N6CX ", & + "B3N6CY ","B3N6DYNP ","B3N6FBN ","B3N6FBS ","B3N6FBT ","B3N6FD ","B3N6FL ","B3N6FN ", & + "B3N6FT ","B3N6FX ","B3N6FY ","B3N6GAM ","B3N6M ","B3N6MBN ","B3N6MBS ","B3N6MBT ", & + "B3N6MM ","B3N6PHI ","B3N6RE ","B3N6SGCAV","B3N6SIGCR","B3N6STVX ","B3N6STVY ","B3N6STVZ ", & + "B3N6THETA","B3N6TNIND","B3N6VDISX","B3N6VDISY","B3N6VDISZ","B3N6VINDX","B3N6VINDY","B3N6VREL ", & + "B3N6VUNDX","B3N6VUNDY","B3N6VUNDZ","B3N7ALPHA","B3N7AXIND","B3N7CD ","B3N7CL ","B3N7CLRNC", & + "B3N7CM ","B3N7CN ","B3N7CPMIN","B3N7CT ","B3N7CURVE","B3N7CX ","B3N7CY ","B3N7DYNP ", & + "B3N7FBN ","B3N7FBS ","B3N7FBT ","B3N7FD ","B3N7FL ","B3N7FN ","B3N7FT ","B3N7FX ", & + "B3N7FY ","B3N7GAM ","B3N7M ","B3N7MBN ","B3N7MBS ","B3N7MBT ","B3N7MM ","B3N7PHI ", & + "B3N7RE ","B3N7SGCAV","B3N7SIGCR","B3N7STVX ","B3N7STVY ","B3N7STVZ ","B3N7THETA","B3N7TNIND", & + "B3N7VDISX","B3N7VDISY","B3N7VDISZ","B3N7VINDX","B3N7VINDY","B3N7VREL ","B3N7VUNDX","B3N7VUNDY", & + "B3N7VUNDZ","B3N8ALPHA","B3N8AXIND","B3N8CD ","B3N8CL ","B3N8CLRNC","B3N8CM ","B3N8CN ", & + "B3N8CPMIN","B3N8CT ","B3N8CURVE","B3N8CX ","B3N8CY ","B3N8DYNP ","B3N8FBN ","B3N8FBS ", & + "B3N8FBT ","B3N8FD ","B3N8FL ","B3N8FN ","B3N8FT ","B3N8FX ","B3N8FY ","B3N8GAM ", & + "B3N8M ","B3N8MBN ","B3N8MBS ","B3N8MBT ","B3N8MM ","B3N8PHI ","B3N8RE ","B3N8SGCAV", & + "B3N8SIGCR","B3N8STVX ","B3N8STVY ","B3N8STVZ ","B3N8THETA","B3N8TNIND","B3N8VDISX","B3N8VDISY", & + "B3N8VDISZ","B3N8VINDX","B3N8VINDY","B3N8VREL ","B3N8VUNDX","B3N8VUNDY","B3N8VUNDZ","B3N9ALPHA", & + "B3N9AXIND","B3N9CD ","B3N9CL ","B3N9CLRNC","B3N9CM ","B3N9CN ","B3N9CPMIN","B3N9CT ", & + "B3N9CURVE","B3N9CX ","B3N9CY ","B3N9DYNP ","B3N9FBN ","B3N9FBS ","B3N9FBT ","B3N9FD ", & + "B3N9FL ","B3N9FN ","B3N9FT ","B3N9FX ","B3N9FY ","B3N9GAM ","B3N9M ","B3N9MBN ", & + "B3N9MBS ","B3N9MBT ","B3N9MM ","B3N9PHI ","B3N9RE ","B3N9SGCAV","B3N9SIGCR","B3N9STVX ", & + "B3N9STVY ","B3N9STVZ ","B3N9THETA","B3N9TNIND","B3N9VDISX","B3N9VDISY","B3N9VDISZ","B3N9VINDX", & + "B3N9VINDY","B3N9VREL ","B3N9VUNDX","B3N9VUNDY","B3N9VUNDZ","B3PITCH ","B4AEROFX ","B4AEROFXG", & + "B4AEROFY ","B4AEROFYG","B4AEROFZ ","B4AEROFZG","B4AEROMX ","B4AEROMXG","B4AEROMY ","B4AEROMYG", & + "B4AEROMZ ","B4AEROMZG","B4AEROPWR","B4FLDFX ","B4FLDFXG ","B4FLDFY ","B4FLDFYG ","B4FLDFZ ", & + "B4FLDFZG ","B4FLDMX ","B4FLDMXG ","B4FLDMY ","B4FLDMYG ","B4FLDMZ ","B4FLDMZG ","B4FLDPWR ", & + "DBEMTAU1 ","HBFBX ","HBFBY ","HBFBZ ","HBMBX ","HBMBY ","HBMBZ ","NCFBX ", & + "NCFBY ","NCFBZ ","NCMBX ","NCMBY ","NCMBZ ","RTAEROCP ","RTAEROCQ ","RTAEROCT ", & + "RTAEROFXG","RTAEROFXH","RTAEROFYG","RTAEROFYH","RTAEROFZG","RTAEROFZH","RTAEROMXG","RTAEROMXH", & + "RTAEROMYG","RTAEROMYH","RTAEROMZG","RTAEROMZH","RTAEROPWR","RTAREA ","RTFLDCP ","RTFLDCQ ", & + "RTFLDCT ","RTFLDFXG ","RTFLDFXH ","RTFLDFYG ","RTFLDFYH ","RTFLDFZG ","RTFLDFZH ","RTFLDMXG ", & + "RTFLDMXH ","RTFLDMYG ","RTFLDMYH ","RTFLDMZG ","RTFLDMZH ","RTFLDPWR ","RTSKEW ","RTSPEED ", & + "RTTSR ","RTVAVGXH ","RTVAVGYH ","RTVAVGZH ","TFALPHA ","TFFXI ","TFFYI ","TFFZI ", & + "TFMACH ","TFMXI ","TFMYI ","TFMZI ","TFRE ","TFSTVXI ","TFSTVYI ","TFSTVZI ", & + "TFVINDXI ","TFVINDYI ","TFVINDZI ","TFVREL ","TFVRELXI ","TFVRELYI ","TFVRELZI ","TFVUNDXI ", & + "TFVUNDYI ","TFVUNDZI ","TWN1DYNP ","TWN1FBX ","TWN1FBY ","TWN1FBZ ","TWN1FDX ","TWN1FDY ", & + "TWN1M ","TWN1MBX ","TWN1MBY ","TWN1MBZ ","TWN1RE ","TWN1STVX ","TWN1STVY ","TWN1STVZ ", & + "TWN1VREL ","TWN1VUNDX","TWN1VUNDY","TWN1VUNDZ","TWN2DYNP ","TWN2FBX ","TWN2FBY ","TWN2FBZ ", & + "TWN2FDX ","TWN2FDY ","TWN2M ","TWN2MBX ","TWN2MBY ","TWN2MBZ ","TWN2RE ","TWN2STVX ", & + "TWN2STVY ","TWN2STVZ ","TWN2VREL ","TWN2VUNDX","TWN2VUNDY","TWN2VUNDZ","TWN3DYNP ","TWN3FBX ", & + "TWN3FBY ","TWN3FBZ ","TWN3FDX ","TWN3FDY ","TWN3M ","TWN3MBX ","TWN3MBY ","TWN3MBZ ", & + "TWN3RE ","TWN3STVX ","TWN3STVY ","TWN3STVZ ","TWN3VREL ","TWN3VUNDX","TWN3VUNDY","TWN3VUNDZ", & + "TWN4DYNP ","TWN4FBX ","TWN4FBY ","TWN4FBZ ","TWN4FDX ","TWN4FDY ","TWN4M ","TWN4MBX ", & + "TWN4MBY ","TWN4MBZ ","TWN4RE ","TWN4STVX ","TWN4STVY ","TWN4STVZ ","TWN4VREL ","TWN4VUNDX", & + "TWN4VUNDY","TWN4VUNDZ","TWN5DYNP ","TWN5FBX ","TWN5FBY ","TWN5FBZ ","TWN5FDX ","TWN5FDY ", & + "TWN5M ","TWN5MBX ","TWN5MBY ","TWN5MBZ ","TWN5RE ","TWN5STVX ","TWN5STVY ","TWN5STVZ ", & + "TWN5VREL ","TWN5VUNDX","TWN5VUNDY","TWN5VUNDZ","TWN6DYNP ","TWN6FBX ","TWN6FBY ","TWN6FBZ ", & + "TWN6FDX ","TWN6FDY ","TWN6M ","TWN6MBX ","TWN6MBY ","TWN6MBZ ","TWN6RE ","TWN6STVX ", & + "TWN6STVY ","TWN6STVZ ","TWN6VREL ","TWN6VUNDX","TWN6VUNDY","TWN6VUNDZ","TWN7DYNP ","TWN7FBX ", & + "TWN7FBY ","TWN7FBZ ","TWN7FDX ","TWN7FDY ","TWN7M ","TWN7MBX ","TWN7MBY ","TWN7MBZ ", & + "TWN7RE ","TWN7STVX ","TWN7STVY ","TWN7STVZ ","TWN7VREL ","TWN7VUNDX","TWN7VUNDY","TWN7VUNDZ", & + "TWN8DYNP ","TWN8FBX ","TWN8FBY ","TWN8FBZ ","TWN8FDX ","TWN8FDY ","TWN8M ","TWN8MBX ", & + "TWN8MBY ","TWN8MBZ ","TWN8RE ","TWN8STVX ","TWN8STVY ","TWN8STVZ ","TWN8VREL ","TWN8VUNDX", & + "TWN8VUNDY","TWN8VUNDZ","TWN9DYNP ","TWN9FBX ","TWN9FBY ","TWN9FBZ ","TWN9FDX ","TWN9FDY ", & + "TWN9M ","TWN9MBX ","TWN9MBY ","TWN9MBZ ","TWN9RE ","TWN9STVX ","TWN9STVY ","TWN9STVZ ", & + "TWN9VREL ","TWN9VUNDX","TWN9VUNDY","TWN9VUNDZ"/) + INTEGER(IntKi), PARAMETER :: ParamIndxAry(1588) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + B1AeroFx , B1AeroFxg , B1AeroFy , B1AeroFyg , B1AeroFz , B1AeroFzg , B1AeroMx , B1AeroMxg , & + B1AeroMy , B1AeroMyg , B1AeroMz , B1AeroMzg , B1AeroPwr , B1Azimuth , B1AeroFx , B1AeroFxg , & + B1AeroFy , B1AeroFyg , B1AeroFz , B1AeroFzg , B1AeroMx , B1AeroMxg , B1AeroMy , B1AeroMyg , & + B1AeroMz , B1AeroMzg , B1AeroPwr , B1N1Alpha , B1N1AxInd , B1N1Cd , B1N1Cl , B1N1Clrnc , & + B1N1Cm , B1N1Cn , B1N1Cpmin , B1N1Ct , B1N1Curve , B1N1Cx , B1N1Cy , B1N1DynP , & + B1N1Fbn , B1N1Fbs , B1N1Fbt , B1N1Fd , B1N1Fl , B1N1Fn , B1N1Ft , B1N1Fx , & + B1N1Fy , B1N1Gam , B1N1M , B1N1Mbn , B1N1Mbs , B1N1Mbt , B1N1Mm , B1N1Phi , & + B1N1Re , B1N1SgCav , B1N1SigCr , B1N1STVx , B1N1STVy , B1N1STVz , B1N1Theta , B1N1TnInd , & + B1N1VDisx , B1N1VDisy , B1N1VDisz , B1N1Vindx , B1N1Vindy , B1N1VRel , B1N1VUndx , B1N1VUndy , & + B1N1VUndz , B1N2Alpha , B1N2AxInd , B1N2Cd , B1N2Cl , B1N2Clrnc , B1N2Cm , B1N2Cn , & + B1N2Cpmin , B1N2Ct , B1N2Curve , B1N2Cx , B1N2Cy , B1N2DynP , B1N2Fbn , B1N2Fbs , & + B1N2Fbt , B1N2Fd , B1N2Fl , B1N2Fn , B1N2Ft , B1N2Fx , B1N2Fy , B1N2Gam , & + B1N2M , B1N2Mbn , B1N2Mbs , B1N2Mbt , B1N2Mm , B1N2Phi , B1N2Re , B1N2SgCav , & + B1N2SigCr , B1N2STVx , B1N2STVy , B1N2STVz , B1N2Theta , B1N2TnInd , B1N2VDisx , B1N2VDisy , & + B1N2VDisz , B1N2Vindx , B1N2Vindy , B1N2VRel , B1N2VUndx , B1N2VUndy , B1N2VUndz , B1N3Alpha , & + B1N3AxInd , B1N3Cd , B1N3Cl , B1N3Clrnc , B1N3Cm , B1N3Cn , B1N3Cpmin , B1N3Ct , & + B1N3Curve , B1N3Cx , B1N3Cy , B1N3DynP , B1N3Fbn , B1N3Fbs , B1N3Fbt , B1N3Fd , & + B1N3Fl , B1N3Fn , B1N3Ft , B1N3Fx , B1N3Fy , B1N3Gam , B1N3M , B1N3Mbn , & + B1N3Mbs , B1N3Mbt , B1N3Mm , B1N3Phi , B1N3Re , B1N3SgCav , B1N3SigCr , B1N3STVx , & + B1N3STVy , B1N3STVz , B1N3Theta , B1N3TnInd , B1N3VDisx , B1N3VDisy , B1N3VDisz , B1N3Vindx , & + B1N3Vindy , B1N3VRel , B1N3VUndx , B1N3VUndy , B1N3VUndz , B1N4Alpha , B1N4AxInd , B1N4Cd , & + B1N4Cl , B1N4Clrnc , B1N4Cm , B1N4Cn , B1N4Cpmin , B1N4Ct , B1N4Curve , B1N4Cx , & + B1N4Cy , B1N4DynP , B1N4Fbn , B1N4Fbs , B1N4Fbt , B1N4Fd , B1N4Fl , B1N4Fn , & + B1N4Ft , B1N4Fx , B1N4Fy , B1N4Gam , B1N4M , B1N4Mbn , B1N4Mbs , B1N4Mbt , & + B1N4Mm , B1N4Phi , B1N4Re , B1N4SgCav , B1N4SigCr , B1N4STVx , B1N4STVy , B1N4STVz , & + B1N4Theta , B1N4TnInd , B1N4VDisx , B1N4VDisy , B1N4VDisz , B1N4Vindx , B1N4Vindy , B1N4VRel , & + B1N4VUndx , B1N4VUndy , B1N4VUndz , B1N5Alpha , B1N5AxInd , B1N5Cd , B1N5Cl , B1N5Clrnc , & + B1N5Cm , B1N5Cn , B1N5Cpmin , B1N5Ct , B1N5Curve , B1N5Cx , B1N5Cy , B1N5DynP , & + B1N5Fbn , B1N5Fbs , B1N5Fbt , B1N5Fd , B1N5Fl , B1N5Fn , B1N5Ft , B1N5Fx , & + B1N5Fy , B1N5Gam , B1N5M , B1N5Mbn , B1N5Mbs , B1N5Mbt , B1N5Mm , B1N5Phi , & + B1N5Re , B1N5SgCav , B1N5SigCr , B1N5STVx , B1N5STVy , B1N5STVz , B1N5Theta , B1N5TnInd , & + B1N5VDisx , B1N5VDisy , B1N5VDisz , B1N5Vindx , B1N5Vindy , B1N5VRel , B1N5VUndx , B1N5VUndy , & + B1N5VUndz , B1N6Alpha , B1N6AxInd , B1N6Cd , B1N6Cl , B1N6Clrnc , B1N6Cm , B1N6Cn , & + B1N6Cpmin , B1N6Ct , B1N6Curve , B1N6Cx , B1N6Cy , B1N6DynP , B1N6Fbn , B1N6Fbs , & + B1N6Fbt , B1N6Fd , B1N6Fl , B1N6Fn , B1N6Ft , B1N6Fx , B1N6Fy , B1N6Gam , & + B1N6M , B1N6Mbn , B1N6Mbs , B1N6Mbt , B1N6Mm , B1N6Phi , B1N6Re , B1N6SgCav , & + B1N6SigCr , B1N6STVx , B1N6STVy , B1N6STVz , B1N6Theta , B1N6TnInd , B1N6VDisx , B1N6VDisy , & + B1N6VDisz , B1N6Vindx , B1N6Vindy , B1N6VRel , B1N6VUndx , B1N6VUndy , B1N6VUndz , B1N7Alpha , & + B1N7AxInd , B1N7Cd , B1N7Cl , B1N7Clrnc , B1N7Cm , B1N7Cn , B1N7Cpmin , B1N7Ct , & + B1N7Curve , B1N7Cx , B1N7Cy , B1N7DynP , B1N7Fbn , B1N7Fbs , B1N7Fbt , B1N7Fd , & + B1N7Fl , B1N7Fn , B1N7Ft , B1N7Fx , B1N7Fy , B1N7Gam , B1N7M , B1N7Mbn , & + B1N7Mbs , B1N7Mbt , B1N7Mm , B1N7Phi , B1N7Re , B1N7SgCav , B1N7SigCr , B1N7STVx , & + B1N7STVy , B1N7STVz , B1N7Theta , B1N7TnInd , B1N7VDisx , B1N7VDisy , B1N7VDisz , B1N7Vindx , & + B1N7Vindy , B1N7VRel , B1N7VUndx , B1N7VUndy , B1N7VUndz , B1N8Alpha , B1N8AxInd , B1N8Cd , & + B1N8Cl , B1N8Clrnc , B1N8Cm , B1N8Cn , B1N8Cpmin , B1N8Ct , B1N8Curve , B1N8Cx , & + B1N8Cy , B1N8DynP , B1N8Fbn , B1N8Fbs , B1N8Fbt , B1N8Fd , B1N8Fl , B1N8Fn , & + B1N8Ft , B1N8Fx , B1N8Fy , B1N8Gam , B1N8M , B1N8Mbn , B1N8Mbs , B1N8Mbt , & + B1N8Mm , B1N8Phi , B1N8Re , B1N8SgCav , B1N8SigCr , B1N8STVx , B1N8STVy , B1N8STVz , & + B1N8Theta , B1N8TnInd , B1N8VDisx , B1N8VDisy , B1N8VDisz , B1N8Vindx , B1N8Vindy , B1N8VRel , & + B1N8VUndx , B1N8VUndy , B1N8VUndz , B1N9Alpha , B1N9AxInd , B1N9Cd , B1N9Cl , B1N9Clrnc , & + B1N9Cm , B1N9Cn , B1N9Cpmin , B1N9Ct , B1N9Curve , B1N9Cx , B1N9Cy , B1N9DynP , & + B1N9Fbn , B1N9Fbs , B1N9Fbt , B1N9Fd , B1N9Fl , B1N9Fn , B1N9Ft , B1N9Fx , & + B1N9Fy , B1N9Gam , B1N9M , B1N9Mbn , B1N9Mbs , B1N9Mbt , B1N9Mm , B1N9Phi , & + B1N9Re , B1N9SgCav , B1N9SigCr , B1N9STVx , B1N9STVy , B1N9STVz , B1N9Theta , B1N9TnInd , & + B1N9VDisx , B1N9VDisy , B1N9VDisz , B1N9Vindx , B1N9Vindy , B1N9VRel , B1N9VUndx , B1N9VUndy , & + B1N9VUndz , B1Pitch , B2AeroFx , B2AeroFxg , B2AeroFy , B2AeroFyg , B2AeroFz , B2AeroFzg , & + B2AeroMx , B2AeroMxg , B2AeroMy , B2AeroMyg , B2AeroMz , B2AeroMzg , B2AeroPwr , B2Azimuth , & + B2AeroFx , B2AeroFxg , B2AeroFy , B2AeroFyg , B2AeroFz , B2AeroFzg , B2AeroMx , B2AeroMxg , & + B2AeroMy , B2AeroMyg , B2AeroMz , B2AeroMzg , B2AeroPwr , B2N1Alpha , B2N1AxInd , B2N1Cd , & + B2N1Cl , B2N1Clrnc , B2N1Cm , B2N1Cn , B2N1Cpmin , B2N1Ct , B2N1Curve , B2N1Cx , & + B2N1Cy , B2N1DynP , B2N1Fbn , B2N1Fbs , B2N1Fbt , B2N1Fd , B2N1Fl , B2N1Fn , & + B2N1Ft , B2N1Fx , B2N1Fy , B2N1Gam , B2N1M , B2N1Mbn , B2N1Mbs , B2N1Mbt , & + B2N1Mm , B2N1Phi , B2N1Re , B2N1SgCav , B2N1SigCr , B2N1STVx , B2N1STVy , B2N1STVz , & + B2N1Theta , B2N1TnInd , B2N1VDisx , B2N1VDisy , B2N1VDisz , B2N1Vindx , B2N1Vindy , B2N1VRel , & + B2N1VUndx , B2N1VUndy , B2N1VUndz , B2N2Alpha , B2N2AxInd , B2N2Cd , B2N2Cl , B2N2Clrnc , & + B2N2Cm , B2N2Cn , B2N2Cpmin , B2N2Ct , B2N2Curve , B2N2Cx , B2N2Cy , B2N2DynP , & + B2N2Fbn , B2N2Fbs , B2N2Fbt , B2N2Fd , B2N2Fl , B2N2Fn , B2N2Ft , B2N2Fx , & + B2N2Fy , B2N2Gam , B2N2M , B2N2Mbn , B2N2Mbs , B2N2Mbt , B2N2Mm , B2N2Phi , & + B2N2Re , B2N2SgCav , B2N2SigCr , B2N2STVx , B2N2STVy , B2N2STVz , B2N2Theta , B2N2TnInd , & + B2N2VDisx , B2N2VDisy , B2N2VDisz , B2N2Vindx , B2N2Vindy , B2N2VRel , B2N2VUndx , B2N2VUndy , & + B2N2VUndz , B2N3Alpha , B2N3AxInd , B2N3Cd , B2N3Cl , B2N3Clrnc , B2N3Cm , B2N3Cn , & + B2N3Cpmin , B2N3Ct , B2N3Curve , B2N3Cx , B2N3Cy , B2N3DynP , B2N3Fbn , B2N3Fbs , & + B2N3Fbt , B2N3Fd , B2N3Fl , B2N3Fn , B2N3Ft , B2N3Fx , B2N3Fy , B2N3Gam , & + B2N3M , B2N3Mbn , B2N3Mbs , B2N3Mbt , B2N3Mm , B2N3Phi , B2N3Re , B2N3SgCav , & + B2N3SigCr , B2N3STVx , B2N3STVy , B2N3STVz , B2N3Theta , B2N3TnInd , B2N3VDisx , B2N3VDisy , & + B2N3VDisz , B2N3Vindx , B2N3Vindy , B2N3VRel , B2N3VUndx , B2N3VUndy , B2N3VUndz , B2N4Alpha , & + B2N4AxInd , B2N4Cd , B2N4Cl , B2N4Clrnc , B2N4Cm , B2N4Cn , B2N4Cpmin , B2N4Ct , & + B2N4Curve , B2N4Cx , B2N4Cy , B2N4DynP , B2N4Fbn , B2N4Fbs , B2N4Fbt , B2N4Fd , & + B2N4Fl , B2N4Fn , B2N4Ft , B2N4Fx , B2N4Fy , B2N4Gam , B2N4M , B2N4Mbn , & + B2N4Mbs , B2N4Mbt , B2N4Mm , B2N4Phi , B2N4Re , B2N4SgCav , B2N4SigCr , B2N4STVx , & + B2N4STVy , B2N4STVz , B2N4Theta , B2N4TnInd , B2N4VDisx , B2N4VDisy , B2N4VDisz , B2N4Vindx , & + B2N4Vindy , B2N4VRel , B2N4VUndx , B2N4VUndy , B2N4VUndz , B2N5Alpha , B2N5AxInd , B2N5Cd , & + B2N5Cl , B2N5Clrnc , B2N5Cm , B2N5Cn , B2N5Cpmin , B2N5Ct , B2N5Curve , B2N5Cx , & + B2N5Cy , B2N5DynP , B2N5Fbn , B2N5Fbs , B2N5Fbt , B2N5Fd , B2N5Fl , B2N5Fn , & + B2N5Ft , B2N5Fx , B2N5Fy , B2N5Gam , B2N5M , B2N5Mbn , B2N5Mbs , B2N5Mbt , & + B2N5Mm , B2N5Phi , B2N5Re , B2N5SgCav , B2N5SigCr , B2N5STVx , B2N5STVy , B2N5STVz , & + B2N5Theta , B2N5TnInd , B2N5VDisx , B2N5VDisy , B2N5VDisz , B2N5Vindx , B2N5Vindy , B2N5VRel , & + B2N5VUndx , B2N5VUndy , B2N5VUndz , B2N6Alpha , B2N6AxInd , B2N6Cd , B2N6Cl , B2N6Clrnc , & + B2N6Cm , B2N6Cn , B2N6Cpmin , B2N6Ct , B2N6Curve , B2N6Cx , B2N6Cy , B2N6DynP , & + B2N6Fbn , B2N6Fbs , B2N6Fbt , B2N6Fd , B2N6Fl , B2N6Fn , B2N6Ft , B2N6Fx , & + B2N6Fy , B2N6Gam , B2N6M , B2N6Mbn , B2N6Mbs , B2N6Mbt , B2N6Mm , B2N6Phi , & + B2N6Re , B2N6SgCav , B2N6SigCr , B2N6STVx , B2N6STVy , B2N6STVz , B2N6Theta , B2N6TnInd , & + B2N6VDisx , B2N6VDisy , B2N6VDisz , B2N6Vindx , B2N6Vindy , B2N6VRel , B2N6VUndx , B2N6VUndy , & + B2N6VUndz , B2N7Alpha , B2N7AxInd , B2N7Cd , B2N7Cl , B2N7Clrnc , B2N7Cm , B2N7Cn , & + B2N7Cpmin , B2N7Ct , B2N7Curve , B2N7Cx , B2N7Cy , B2N7DynP , B2N7Fbn , B2N7Fbs , & + B2N7Fbt , B2N7Fd , B2N7Fl , B2N7Fn , B2N7Ft , B2N7Fx , B2N7Fy , B2N7Gam , & + B2N7M , B2N7Mbn , B2N7Mbs , B2N7Mbt , B2N7Mm , B2N7Phi , B2N7Re , B2N7SgCav , & + B2N7SigCr , B2N7STVx , B2N7STVy , B2N7STVz , B2N7Theta , B2N7TnInd , B2N7VDisx , B2N7VDisy , & + B2N7VDisz , B2N7Vindx , B2N7Vindy , B2N7VRel , B2N7VUndx , B2N7VUndy , B2N7VUndz , B2N8Alpha , & + B2N8AxInd , B2N8Cd , B2N8Cl , B2N8Clrnc , B2N8Cm , B2N8Cn , B2N8Cpmin , B2N8Ct , & + B2N8Curve , B2N8Cx , B2N8Cy , B2N8DynP , B2N8Fbn , B2N8Fbs , B2N8Fbt , B2N8Fd , & + B2N8Fl , B2N8Fn , B2N8Ft , B2N8Fx , B2N8Fy , B2N8Gam , B2N8M , B2N8Mbn , & + B2N8Mbs , B2N8Mbt , B2N8Mm , B2N8Phi , B2N8Re , B2N8SgCav , B2N8SigCr , B2N8STVx , & + B2N8STVy , B2N8STVz , B2N8Theta , B2N8TnInd , B2N8VDisx , B2N8VDisy , B2N8VDisz , B2N8Vindx , & + B2N8Vindy , B2N8VRel , B2N8VUndx , B2N8VUndy , B2N8VUndz , B2N9Alpha , B2N9AxInd , B2N9Cd , & + B2N9Cl , B2N9Clrnc , B2N9Cm , B2N9Cn , B2N9Cpmin , B2N9Ct , B2N9Curve , B2N9Cx , & + B2N9Cy , B2N9DynP , B2N9Fbn , B2N9Fbs , B2N9Fbt , B2N9Fd , B2N9Fl , B2N9Fn , & + B2N9Ft , B2N9Fx , B2N9Fy , B2N9Gam , B2N9M , B2N9Mbn , B2N9Mbs , B2N9Mbt , & + B2N9Mm , B2N9Phi , B2N9Re , B2N9SgCav , B2N9SigCr , B2N9STVx , B2N9STVy , B2N9STVz , & + B2N9Theta , B2N9TnInd , B2N9VDisx , B2N9VDisy , B2N9VDisz , B2N9Vindx , B2N9Vindy , B2N9VRel , & + B2N9VUndx , B2N9VUndy , B2N9VUndz , B2Pitch , B3AeroFx , B3AeroFxg , B3AeroFy , B3AeroFyg , & + B3AeroFz , B3AeroFzg , B3AeroMx , B3AeroMxg , B3AeroMy , B3AeroMyg , B3AeroMz , B3AeroMzg , & + B3AeroPwr , B3Azimuth , B3AeroFx , B3AeroFxg , B3AeroFy , B3AeroFyg , B3AeroFz , B3AeroFzg , & + B3AeroMx , B3AeroMxg , B3AeroMy , B3AeroMyg , B3AeroMz , B3AeroMzg , B3AeroPwr , B3N1Alpha , & + B3N1AxInd , B3N1Cd , B3N1Cl , B3N1Clrnc , B3N1Cm , B3N1Cn , B3N1Cpmin , B3N1Ct , & + B3N1Curve , B3N1Cx , B3N1Cy , B3N1DynP , B3N1Fbn , B3N1Fbs , B3N1Fbt , B3N1Fd , & + B3N1Fl , B3N1Fn , B3N1Ft , B3N1Fx , B3N1Fy , B3N1Gam , B3N1M , B3N1Mbn , & + B3N1Mbs , B3N1Mbt , B3N1Mm , B3N1Phi , B3N1Re , B3N1SgCav , B3N1SigCr , B3N1STVx , & + B3N1STVy , B3N1STVz , B3N1Theta , B3N1TnInd , B3N1VDisx , B3N1VDisy , B3N1VDisz , B3N1Vindx , & + B3N1Vindy , B3N1VRel , B3N1VUndx , B3N1VUndy , B3N1VUndz , B3N2Alpha , B3N2AxInd , B3N2Cd , & + B3N2Cl , B3N2Clrnc , B3N2Cm , B3N2Cn , B3N2Cpmin , B3N2Ct , B3N2Curve , B3N2Cx , & + B3N2Cy , B3N2DynP , B3N2Fbn , B3N2Fbs , B3N2Fbt , B3N2Fd , B3N2Fl , B3N2Fn , & + B3N2Ft , B3N2Fx , B3N2Fy , B3N2Gam , B3N2M , B3N2Mbn , B3N2Mbs , B3N2Mbt , & + B3N2Mm , B3N2Phi , B3N2Re , B3N2SgCav , B3N2SigCr , B3N2STVx , B3N2STVy , B3N2STVz , & + B3N2Theta , B3N2TnInd , B3N2VDisx , B3N2VDisy , B3N2VDisz , B3N2Vindx , B3N2Vindy , B3N2VRel , & + B3N2VUndx , B3N2VUndy , B3N2VUndz , B3N3Alpha , B3N3AxInd , B3N3Cd , B3N3Cl , B3N3Clrnc , & + B3N3Cm , B3N3Cn , B3N3Cpmin , B3N3Ct , B3N3Curve , B3N3Cx , B3N3Cy , B3N3DynP , & + B3N3Fbn , B3N3Fbs , B3N3Fbt , B3N3Fd , B3N3Fl , B3N3Fn , B3N3Ft , B3N3Fx , & + B3N3Fy , B3N3Gam , B3N3M , B3N3Mbn , B3N3Mbs , B3N3Mbt , B3N3Mm , B3N3Phi , & + B3N3Re , B3N3SgCav , B3N3SigCr , B3N3STVx , B3N3STVy , B3N3STVz , B3N3Theta , B3N3TnInd , & + B3N3VDisx , B3N3VDisy , B3N3VDisz , B3N3Vindx , B3N3Vindy , B3N3VRel , B3N3VUndx , B3N3VUndy , & + B3N3VUndz , B3N4Alpha , B3N4AxInd , B3N4Cd , B3N4Cl , B3N4Clrnc , B3N4Cm , B3N4Cn , & + B3N4Cpmin , B3N4Ct , B3N4Curve , B3N4Cx , B3N4Cy , B3N4DynP , B3N4Fbn , B3N4Fbs , & + B3N4Fbt , B3N4Fd , B3N4Fl , B3N4Fn , B3N4Ft , B3N4Fx , B3N4Fy , B3N4Gam , & + B3N4M , B3N4Mbn , B3N4Mbs , B3N4Mbt , B3N4Mm , B3N4Phi , B3N4Re , B3N4SgCav , & + B3N4SigCr , B3N4STVx , B3N4STVy , B3N4STVz , B3N4Theta , B3N4TnInd , B3N4VDisx , B3N4VDisy , & + B3N4VDisz , B3N4Vindx , B3N4Vindy , B3N4VRel , B3N4VUndx , B3N4VUndy , B3N4VUndz , B3N5Alpha , & + B3N5AxInd , B3N5Cd , B3N5Cl , B3N5Clrnc , B3N5Cm , B3N5Cn , B3N5Cpmin , B3N5Ct , & + B3N5Curve , B3N5Cx , B3N5Cy , B3N5DynP , B3N5Fbn , B3N5Fbs , B3N5Fbt , B3N5Fd , & + B3N5Fl , B3N5Fn , B3N5Ft , B3N5Fx , B3N5Fy , B3N5Gam , B3N5M , B3N5Mbn , & + B3N5Mbs , B3N5Mbt , B3N5Mm , B3N5Phi , B3N5Re , B3N5SgCav , B3N5SigCr , B3N5STVx , & + B3N5STVy , B3N5STVz , B3N5Theta , B3N5TnInd , B3N5VDisx , B3N5VDisy , B3N5VDisz , B3N5Vindx , & + B3N5Vindy , B3N5VRel , B3N5VUndx , B3N5VUndy , B3N5VUndz , B3N6Alpha , B3N6AxInd , B3N6Cd , & + B3N6Cl , B3N6Clrnc , B3N6Cm , B3N6Cn , B3N6Cpmin , B3N6Ct , B3N6Curve , B3N6Cx , & + B3N6Cy , B3N6DynP , B3N6Fbn , B3N6Fbs , B3N6Fbt , B3N6Fd , B3N6Fl , B3N6Fn , & + B3N6Ft , B3N6Fx , B3N6Fy , B3N6Gam , B3N6M , B3N6Mbn , B3N6Mbs , B3N6Mbt , & + B3N6Mm , B3N6Phi , B3N6Re , B3N6SgCav , B3N6SigCr , B3N6STVx , B3N6STVy , B3N6STVz , & + B3N6Theta , B3N6TnInd , B3N6VDisx , B3N6VDisy , B3N6VDisz , B3N6Vindx , B3N6Vindy , B3N6VRel , & + B3N6VUndx , B3N6VUndy , B3N6VUndz , B3N7Alpha , B3N7AxInd , B3N7Cd , B3N7Cl , B3N7Clrnc , & + B3N7Cm , B3N7Cn , B3N7Cpmin , B3N7Ct , B3N7Curve , B3N7Cx , B3N7Cy , B3N7DynP , & + B3N7Fbn , B3N7Fbs , B3N7Fbt , B3N7Fd , B3N7Fl , B3N7Fn , B3N7Ft , B3N7Fx , & + B3N7Fy , B3N7Gam , B3N7M , B3N7Mbn , B3N7Mbs , B3N7Mbt , B3N7Mm , B3N7Phi , & + B3N7Re , B3N7SgCav , B3N7SigCr , B3N7STVx , B3N7STVy , B3N7STVz , B3N7Theta , B3N7TnInd , & + B3N7VDisx , B3N7VDisy , B3N7VDisz , B3N7Vindx , B3N7Vindy , B3N7VRel , B3N7VUndx , B3N7VUndy , & + B3N7VUndz , B3N8Alpha , B3N8AxInd , B3N8Cd , B3N8Cl , B3N8Clrnc , B3N8Cm , B3N8Cn , & + B3N8Cpmin , B3N8Ct , B3N8Curve , B3N8Cx , B3N8Cy , B3N8DynP , B3N8Fbn , B3N8Fbs , & + B3N8Fbt , B3N8Fd , B3N8Fl , B3N8Fn , B3N8Ft , B3N8Fx , B3N8Fy , B3N8Gam , & + B3N8M , B3N8Mbn , B3N8Mbs , B3N8Mbt , B3N8Mm , B3N8Phi , B3N8Re , B3N8SgCav , & + B3N8SigCr , B3N8STVx , B3N8STVy , B3N8STVz , B3N8Theta , B3N8TnInd , B3N8VDisx , B3N8VDisy , & + B3N8VDisz , B3N8Vindx , B3N8Vindy , B3N8VRel , B3N8VUndx , B3N8VUndy , B3N8VUndz , B3N9Alpha , & + B3N9AxInd , B3N9Cd , B3N9Cl , B3N9Clrnc , B3N9Cm , B3N9Cn , B3N9Cpmin , B3N9Ct , & + B3N9Curve , B3N9Cx , B3N9Cy , B3N9DynP , B3N9Fbn , B3N9Fbs , B3N9Fbt , B3N9Fd , & + B3N9Fl , B3N9Fn , B3N9Ft , B3N9Fx , B3N9Fy , B3N9Gam , B3N9M , B3N9Mbn , & + B3N9Mbs , B3N9Mbt , B3N9Mm , B3N9Phi , B3N9Re , B3N9SgCav , B3N9SigCr , B3N9STVx , & + B3N9STVy , B3N9STVz , B3N9Theta , B3N9TnInd , B3N9VDisx , B3N9VDisy , B3N9VDisz , B3N9Vindx , & + B3N9Vindy , B3N9VRel , B3N9VUndx , B3N9VUndy , B3N9VUndz , B3Pitch , B4AeroFx , B4AeroFxg , & + B4AeroFy , B4AeroFyg , B4AeroFz , B4AeroFzg , B4AeroMx , B4AeroMxg , B4AeroMy , B4AeroMyg , & + B4AeroMz , B4AeroMzg , B4AeroPwr , B4AeroFx , B4AeroFxg , B4AeroFy , B4AeroFyg , B4AeroFz , & + B4AeroFzg , B4AeroMx , B4AeroMxg , B4AeroMy , B4AeroMyg , B4AeroMz , B4AeroMzg , B4AeroPwr , & + DBEMTau1 , HbFbx , HbFby , HbFbz , HbMbx , HbMby , HbMbz , NcFbx , & + NcFby , NcFbz , NcMbx , NcMby , NcMbz , RtAeroCp , RtAeroCq , RtAeroCt , & + RtAeroFxg , RtAeroFxh , RtAeroFyg , RtAeroFyh , RtAeroFzg , RtAeroFzh , RtAeroMxg , RtAeroMxh , & + RtAeroMyg , RtAeroMyh , RtAeroMzg , RtAeroMzh , RtAeroPwr , RtArea , RtAeroCp , RtAeroCq , & + RtAeroCt , RtAeroFxg , RtAeroFxh , RtAeroFyg , RtAeroFyh , RtAeroFzg , RtAeroFzh , RtAeroMxg , & + RtAeroMxh , RtAeroMyg , RtAeroMyh , RtAeroMzg , RtAeroMzh , RtAeroPwr , RtSkew , RtSpeed , & + RtTSR , RtVAvgxh , RtVAvgyh , RtVAvgzh , TFAlpha , TFFxi , TFFyi , TFFzi , & + TFMach , TFMxi , TFMyi , TFMzi , TFRe , TFSTVxi , TFSTVyi , TFSTVzi , & + TFVindxi , TFVindyi , TFVindzi , TFVrel , TFVrelxi , TFVrelyi , TFVrelzi , TFVundxi , & + TFVundyi , TFVundzi , TwN1DynP , TwN1Fbx , TwN1Fby , TwN1Fbz , TwN1Fdx , TwN1Fdy , & + TwN1M , TwN1Mbx , TwN1Mby , TwN1Mbz , TwN1Re , TwN1STVx , TwN1STVy , TwN1STVz , & + TwN1Vrel , TwN1VUndx , TwN1VUndy , TwN1VUndz , TwN2DynP , TwN2Fbx , TwN2Fby , TwN2Fbz , & + TwN2Fdx , TwN2Fdy , TwN2M , TwN2Mbx , TwN2Mby , TwN2Mbz , TwN2Re , TwN2STVx , & + TwN2STVy , TwN2STVz , TwN2Vrel , TwN2VUndx , TwN2VUndy , TwN2VUndz , TwN3DynP , TwN3Fbx , & + TwN3Fby , TwN3Fbz , TwN3Fdx , TwN3Fdy , TwN3M , TwN3Mbx , TwN3Mby , TwN3Mbz , & + TwN3Re , TwN3STVx , TwN3STVy , TwN3STVz , TwN3Vrel , TwN3VUndx , TwN3VUndy , TwN3VUndz , & + TwN4DynP , TwN4Fbx , TwN4Fby , TwN4Fbz , TwN4Fdx , TwN4Fdy , TwN4M , TwN4Mbx , & + TwN4Mby , TwN4Mbz , TwN4Re , TwN4STVx , TwN4STVy , TwN4STVz , TwN4Vrel , TwN4VUndx , & + TwN4VUndy , TwN4VUndz , TwN5DynP , TwN5Fbx , TwN5Fby , TwN5Fbz , TwN5Fdx , TwN5Fdy , & + TwN5M , TwN5Mbx , TwN5Mby , TwN5Mbz , TwN5Re , TwN5STVx , TwN5STVy , TwN5STVz , & + TwN5Vrel , TwN5VUndx , TwN5VUndy , TwN5VUndz , TwN6DynP , TwN6Fbx , TwN6Fby , TwN6Fbz , & + TwN6Fdx , TwN6Fdy , TwN6M , TwN6Mbx , TwN6Mby , TwN6Mbz , TwN6Re , TwN6STVx , & + TwN6STVy , TwN6STVz , TwN6Vrel , TwN6VUndx , TwN6VUndy , TwN6VUndz , TwN7DynP , TwN7Fbx , & + TwN7Fby , TwN7Fbz , TwN7Fdx , TwN7Fdy , TwN7M , TwN7Mbx , TwN7Mby , TwN7Mbz , & + TwN7Re , TwN7STVx , TwN7STVy , TwN7STVz , TwN7Vrel , TwN7VUndx , TwN7VUndy , TwN7VUndz , & + TwN8DynP , TwN8Fbx , TwN8Fby , TwN8Fbz , TwN8Fdx , TwN8Fdy , TwN8M , TwN8Mbx , & + TwN8Mby , TwN8Mbz , TwN8Re , TwN8STVx , TwN8STVy , TwN8STVz , TwN8Vrel , TwN8VUndx , & + TwN8VUndy , TwN8VUndz , TwN9DynP , TwN9Fbx , TwN9Fby , TwN9Fbz , TwN9Fdx , TwN9Fdy , & + TwN9M , TwN9Mbx , TwN9Mby , TwN9Mbz , TwN9Re , TwN9STVx , TwN9STVy , TwN9STVz , & + TwN9Vrel , TwN9VUndx , TwN9VUndy , TwN9VUndz /) + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(1588) = (/ & ! This lists the units corresponding to the allowed parameters + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(W) ","(deg) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(W) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & + "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & + "(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & + "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)", & + "(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & + "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)", & + "(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & + "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & + "(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & + "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)", & + "(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & + "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)", & + "(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(W) ","(deg) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(W) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & + "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)", & + "(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & + "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & + "(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & + "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)", & + "(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & + "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)", & + "(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & + "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & + "(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & + "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)", & + "(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & + "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)", & + "(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(W) ","(deg) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(W) ","(deg) ", & + "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & + "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)", & + "(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & + "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)", & + "(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & + "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & + "(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & + "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)", & + "(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & + "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)", & + "(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(m^2/s)","(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & + "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)", & + "(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & + "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(m^2/s)","(-) ","(N-m/m)", & + "(N-m/m)","(N-m/m)","(N-m/m)","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(N) ","(N) ", & + "(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(W) ","(N) ","(N) ","(N) ","(N) ","(N) ", & + "(N) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(W) ", & + "(s) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(N) ", & + "(N) ","(N) ","(N-m) ","(N-m) ","(N-m) ","(-) ","(-) ","(-) ", & + "(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(W) ","(m^2) ","(-) ","(-) ", & + "(-) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N) ","(N-m) ", & + "(N-m) ","(N-m) ","(N-m) ","(N-m) ","(N-m) ","(W) ","(deg) ","(rpm) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(N) ","(N) ","(N) ", & + "(-) ","(N-m) ","(N-m) ","(N-m) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N-m/m)","(N-m/m)","(N-m/m)", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N-m/m)", & + "(N-m/m)","(N-m/m)","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N-m/m)","(N-m/m)","(N-m/m)", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N-m/m)", & + "(N-m/m)","(N-m/m)","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(-) ","(N-m/m)","(N-m/m)","(N-m/m)","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) "/) + + +end module AeroDyn_IO_Params diff --git a/modules/aerodyn/src/AeroDyn_Inflow.f90 b/modules/aerodyn/src/AeroDyn_Inflow.f90 new file mode 100644 index 000000000..e513c1085 --- /dev/null +++ b/modules/aerodyn/src/AeroDyn_Inflow.f90 @@ -0,0 +1,720 @@ +!> Module for the coupling of AeroDyn and InflowWind +!! Also contains routine to couple with a "Fake ElastoDyn" (minimalistic structural solver) +module AeroDyn_Inflow + use NWTC_Library + use AeroDyn_Inflow_Types + use AeroDyn_Types + use AeroDyn, only: AD_Init, AD_ReInit, AD_CalcOutput, AD_UpdateStates, AD_End + use AeroDyn, only: AD_NumWindPoints, AD_GetExternalWind, AD_SetExternalWindPositions + use AeroDyn_IO, only: AD_SetVTKSurface + use InflowWind, only: InflowWind_Init, InflowWind_CalcOutput, InflowWind_End + + implicit none + + private + + type(ProgDesc), parameter :: ADI_Ver = ProgDesc( 'ADI', '', '' ) + + public :: ADI_Init + public :: ADI_ReInit + public :: ADI_End + public :: ADI_CalcOutput + public :: ADI_UpdateStates + + ! Convenient routines for driver + public :: ADI_ADIW_Solve + public :: concatOutputHeaders + public :: Init_MeshMap_For_ADI + public :: Set_Inputs_For_ADI + + real(ReKi), parameter :: myNaN = -99.9_ReKi +contains + +!---------------------------------------------------------------------------------------------------------------------------------- +!> 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 ADI_Init(InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut, errStat, errMsg) + type(ADI_InitInputType), intent(inout) :: InitInp !< Input data for initialization routine (inout so we can use MOVE_ALLOC) + type(ADI_InputType), intent( out) :: u !< An initial guess for the input; input mesh must be defined + type(ADI_ParameterType), intent( out) :: p !< Parameters + type(ADI_ContinuousStateType), intent( out) :: x !< Initial continuous states + type(ADI_DiscreteStateType), intent( out) :: xd !< Initial discrete states + type(ADI_ConstraintStateType), intent( out) :: z !< Initial guess of the constraint states + type(ADI_OtherStateType), intent( out) :: OtherState !< Initial other states + type(ADI_OutputType), intent( out) :: y !< Initial system outputs (outputs are not calculated; + type(ADI_MiscVarType), intent( out) :: m !< Initial misc/optimization variables + real(DbKi), intent(inout) :: interval !< Coupling interval in seconds + type(ADI_InitOutputType), intent(inout) :: InitOut !< Output for initialization routine. NOTE: inout to allow for reinit? + integer(IntKi), intent( out) :: errStat !< Error status of the operation + character(*), intent( out) :: errMsg !< Error message if errStat /= ErrID_None + ! Local variables + type(InflowWind_InitOutputType) :: InitOut_IW ! Output data from initialization + type(AD_InitOutputType) :: InitOut_AD ! Output data from initialization + integer(IntKi) :: errStat2 ! temporary error status of the operation + character(errMsgLen) :: errMsg2 ! temporary error message + + ! Initialize variables for this routine + errStat = ErrID_None + errMsg = "" + + ! Initialize the NWTC Subroutine Library + call NWTC_Init( EchoLibVer=.FALSE. ) + + ! Display the module information + call DispNVD( ADI_Ver ) + + ! Set parameters + p%dt = interval + p%storeHHVel = InitInp%storeHHVel + p%WrVTK = InitInp%WrVTK + p%MHK = InitInp%AD%MHK + p%WtrDpth = InitInp%AD%WtrDpth + + ! --- Initialize AeroDyn + if (allocated(InitOut%WriteOutputHdr)) deallocate(InitOut%WriteOutputHdr) + if (allocated(InitOut%WriteOutputUnt)) deallocate(InitOut%WriteOutputUnt) + + call AD_Init(InitInp%AD, u%AD, p%AD, x%AD, xd%AD, z%AD, OtherState%AD, y%AD, m%AD, Interval, InitOut_AD, errStat2, errMsg2); if (Failed()) return + InitOut%Ver = InitOut_AD%ver + ! Add writeoutput units and headers to driver, same for all cases and rotors! + !TODO: this header is too short if we add more rotors. Should also add a rotor identifier + call concatOutputHeaders(InitOut%WriteOutputHdr, InitOut%WriteOutputUnt, InitOut_AD%rotors(1)%WriteOutputHdr, InitOut_AD%rotors(1)%WriteOutputUnt, errStat2, errMsg2); if(Failed()) return + + ! --- Initialize Inflow Wind + call ADI_InitInflowWind(InitInp%RootName, InitInp%IW_InitInp, u%AD, OtherState%AD, m%IW, Interval, InitOut_IW, errStat2, errMsg2); if (Failed()) return + ! Concatenate AD outputs to IW outputs + call concatOutputHeaders(InitOut%WriteOutputHdr, InitOut%WriteOutputUnt, InitOut_IW%WriteOutputHdr, InitOut_IW%WriteOutputUnt, errStat2, errMsg2); if(Failed()) return + + ! --- Initialize grouped outputs + !TODO: assumes one rotor + p%NumOuts = p%AD%rotors(1)%NumOuts + p%AD%rotors(1)%BldNd_TotNumOuts + m%IW%p%NumOuts + call AllocAry(y%WriteOutput, p%NumOuts, 'WriteOutput', errStat2, errMsg2); if (Failed()) return + + ! --- Initialize outputs + call AllocAry(y%IW_WriteOutput, size(m%IW%y%WriteOutput),'IW_WriteOutput', errStat2, errMsg2); if(Failed()) return + y%IW_WriteOutput = myNaN + if (p%storeHHVel) then + call AllocAry(y%HHVel, 3, size(InitInp%AD%rotors), 'HHVel', errStat2, errMsg2); if(Failed()) return + y%HHVel= myNaN + else + call AllocAry(y%HHVel, 0, 0 , 'HHVel', errStat2, errMsg2); if(Failed()) return + endif + + ! --- Initialize VTK + if (p%WrVTK>0) then + call AD_SetVTKSurface(InitOut_AD, u%AD, m%VTK_Surfaces, errStat2, errMsg2); if(Failed()) return + endif + + call cleanup() + +contains + + subroutine cleanup() + call AD_DestroyInitInput (InitInp%AD, errStat2, errMsg2) + call AD_DestroyInitOutput(InitOut_AD, errStat2, errMsg2) + call InflowWind_DestroyInitOutput(InitOut_IW, errStat2, errMsg2) + end subroutine cleanup + + logical function Failed() + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'ADI_Init') + Failed = errStat >= AbortErrLev + if (Failed) call cleanup() + end function Failed + +end subroutine ADI_Init +!---------------------------------------------------------------------------------------------------------------------------------- +!> ReInit +subroutine ADI_ReInit(p, x, xd, z, OtherState, m, Interval, errStat, errMsg) + type(ADI_ParameterType), intent(in ) :: p !< Parameters + type(ADI_ContinuousStateType), intent(inout) :: x !< Initial continuous states + type(ADI_DiscreteStateType), intent(inout) :: xd !< Initial discrete states + type(ADI_ConstraintStateType), intent(inout) :: z !< Initial guess of the constraint states + type(ADI_OtherStateType), intent(inout) :: OtherState !< Initial other states + type(ADI_MiscVarType), intent(inout) :: m !< Initial misc/optimization variables + real(DbKi), intent(inout) :: interval !< Coupling interval in seconds + integer(IntKi), intent( out) :: errStat !< Error status of the operation + character(*), intent( out) :: errMsg !< Error message if errStat /= ErrID_None + ! Local variables + integer(IntKi) :: errStat2 ! temporary error status of the operation + character(errMsgLen) :: errMsg2 ! temporary error message + errStat = ErrID_None + errMsg = "" + + ! Reinitialize AeroDyn without reopening input file + call AD_ReInit(p%AD, x%AD, xd%AD, z%AD, OtherState%AD, m%AD, Interval, errStat2, errMsg2); if(Failed()) return + ! Set parameters + !p%dt = interval ! dt shouldn't change +contains + + logical function Failed() + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'ADI_ReInit') + Failed = errStat >= AbortErrLev + end function Failed + +end subroutine ADI_ReInit +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine is called at the end of the simulation. +subroutine ADI_End( u, p, x, xd, z, OtherState, y, m, errStat, errMsg ) + type(ADI_InputType), intent(inout) :: u(:) !< System inputs NOTE: used to be allocatable + type(ADI_ParameterType), intent(inout) :: p !< Parameters + type(ADI_ContinuousStateType), intent(inout) :: x !< Continuous states + type(ADI_DiscreteStateType), intent(inout) :: xd !< Discrete states + type(ADI_ConstraintStateType), intent(inout) :: z !< Constraint states + type(ADI_OtherStateType), intent(inout) :: OtherState !< Other states + type(ADI_OutputType), intent(inout) :: y !< System outputs + type(ADI_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) :: i + errStat = ErrID_None + errMsg = "" + + ! End modules + call AD_End(u(1)%AD, p%AD, x%AD, xd%AD, z%AD, OtherState%AD, y%AD, m%AD, ErrStat, ErrMsg) + call InflowWind_End(m%IW%u, m%IW%p, m%IW%x, m%IW%xd, m%IW%z, m%IW%OtherSt, m%IW%y, m%IW%m, ErrStat, ErrMsg) + + ! Destroy the input data: + !if (allocated(u)) then + do i=1,size(u) + call ADI_DestroyInput( u(i), errStat, errMsg ) + enddo + !endif + + ! Destroy the parameter data: + call ADI_DestroyParam( p, errStat, errMsg ) + + ! Destroy the state data: + call ADI_DestroyContState( x, errStat, errMsg ) + call ADI_DestroyDiscState( xd, errStat, errMsg ) + call ADI_DestroyConstrState( z, errStat, errMsg ) + call ADI_DestroyOtherState( OtherState, errStat, errMsg ) + call ADI_DestroyMisc( m, errStat, errMsg ) + + ! Destroy the output data: + call ADI_DestroyOutput( y, errStat, errMsg ) + +end subroutine ADI_End +!---------------------------------------------------------------------------------------------------------------------------------- +!> Loose coupling routine for solving for constraint states, integrating continuous states, and updating discrete and other states. +!! Continuous, constraint, discrete, and other states are updated for t + Interval +subroutine ADI_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, m, errStat, errMsg) + real(DbKi), intent(in ) :: t !< Current simulation time in seconds + integer(IntKi), intent(in ) :: n !< Current simulation time step n = 0,1,... + type(ADI_InputType), intent(inout) :: u(:) !< Inputs at utimes (out only for mesh record-keeping in ExtrapInterp routine) + real(DbKi), intent(in ) :: utimes(:) !< Times associated with u(:), in seconds + type(ADI_ParameterType), intent(in ) :: p !< Parameters + type(ADI_ContinuousStateType), intent(inout) :: x !< Input: Continuous states at t; Output: at t+DTaero + type(ADI_DiscreteStateType), intent(inout) :: xd !< Input: Discrete states at t; Output: at t+DTaero + type(ADI_ConstraintStateType), intent(inout) :: z !< Input: Constraint states at t; Output: at t+DTaero + type(ADI_OtherStateType), intent(inout) :: OtherState !< Input: Other states at t; Output: at t+DTaero + type(ADI_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 :: it ! Index on times + type(AD_InputType) :: u_AD(size(utimes)) + integer(IntKi) :: errStat2 ! temporary Error status + character(errMsgLen) :: errMsg2 ! temporary Error message + !type(ADI_InputType) :: uInterp ! Interpolated/Extrapolated input + errStat = ErrID_None + errMsg = "" + + ! Compute InflowWind inputs for each time + do it=1,size(utimes) + call AD_CopyInput(u(it)%AD,u_AD(it),MESH_NEWCOPY,ErrStat2,ErrMsg2); if(Failed()) return + enddo + + ! Get state variables at next step: INPUT at step nt - 1, OUTPUT at step nt + call AD_UpdateStates(t, n, u_AD(:), utimes(:), p%AD, x%AD, xd%AD, z%AD, OtherState%AD, m%AD, errStat2, errMsg2); if(Failed()) return + +contains + + subroutine CleanUp() + !call ADI_DestroyConstrState(z_guess, errStat2, errMsg2); if(Failed()) return + end subroutine + + logical function Failed() + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'ADI_UpdateStates') + Failed = errStat >= AbortErrLev + if (Failed) call CleanUp() + end function Failed + +end subroutine ADI_UpdateStates +!---------------------------------------------------------------------------------------------------------------------------------- +!> Routine for computing outputs, used in both loose and tight coupling. +subroutine ADI_CalcOutput(t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg) + real(DbKi), intent(in ) :: t !< Current simulation time in seconds + type(ADI_InputType), intent(inout) :: u !< Inputs at Time t ! NOTE: set as in-out since "Inflow" needs to be set + type(ADI_ParameterType), intent(in ) :: p !< Parameters + type(ADI_ContinuousStateType), intent(in ) :: x !< Continuous states at t + type(ADI_DiscreteStateType), intent(in ) :: xd !< Discrete states at t + type(ADI_ConstraintStateType), intent(in ) :: z !< Constraint states at t + type(ADI_OtherStateType), intent(in ) :: OtherState !< Other states at t + type(ADI_OutputType), intent(inout) :: y !< Outputs computed at t (Input only so that mesh con- + !! nectivity information does not have to be recalculated) + type(ADI_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 + character(errMsgLen) :: errMsg2 + character(*), parameter :: RoutineName = 'ADI_CalcOutput' + integer :: iWT + errStat = ErrID_None + errMsg = "" + + ! --- CalcOutputs for IW (Sets u_AD%rotors(:)%InflowOnBlade, etc, and m%IW%y) + y%IW_WriteOutput(:) = m%IW%y%WriteOutput(:) + + + ! Calculate outputs at t + call AD_CalcOutput(t, u%AD, p%AD, x%AD, xd%AD, z%AD, OtherState%AD, y%AD, m%AD, errStat2, errMsg2); if(Failed()) return + + ! --- Outputs for driver + ! Hub Height velocity outputs + if (p%storeHHVel) then + do iWT = 1, size(p%AD%rotors) + y%HHVel(1, iWT) = m%IW%y%VelocityUVW(1, iWT) + y%HHVel(2, iWT) = m%IW%y%VelocityUVW(2, iWT) + y%HHVel(3, iWT) = m%IW%y%VelocityUVW(3, iWT) + enddo + endif + y%PLExp = m%IW%PLExp + + ! --- Set outputs +!TODO: this assumes one rotor!!! + y%WriteOutput(1:p%AD%rotors(1)%NumOuts+p%AD%rotors(1)%BldNd_TotNumOuts) = y%AD%rotors(1)%WriteOutput(1:p%AD%rotors(1)%NumOuts+p%AD%rotors(1)%BldNd_TotNumOuts) + y%WriteOutput(p%AD%rotors(1)%NumOuts+p%AD%rotors(1)%BldNd_TotNumOuts+1:p%NumOuts) = y%IW_WriteOutput(1:m%IW%p%NumOuts) + +contains + + subroutine CleanUp() + !call ADI_DestroyConstrState(z_guess, errStat2, errMsg2); if(Failed()) return + end subroutine + + logical function Failed() + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'ADI_CalcOutput') + Failed = errStat >= AbortErrLev + if (Failed) call CleanUp() + end function Failed +end subroutine ADI_CalcOutput +!---------------------------------------------------------------------------------------------------------------------------------- +!> +subroutine ADI_InitInflowWind(Root, i_IW, u_AD, o_AD, IW, dt, InitOutData, errStat, errMsg) + use InflowWind, only: InflowWind_Init + character(len=*), intent(in ) :: Root ! Rootname for input files + type(ADI_IW_InputData), intent(in ) :: i_IW ! Inflow Wind "pseudo init input" data + type(AD_InputType), intent(in ) :: u_AD ! AeroDyn data + type(AD_OtherStateType), intent(in ) :: o_AD ! AeroDyn data + type(ADI_InflowWindData), intent(inout) :: IW ! InflowWind data + real(DbKi), intent(inout) :: dt ! interval + type(InflowWind_InitOutputType), intent(out) :: InitOutData ! Output data from initialization + integer(IntKi) , intent( out) :: errStat ! Status of error message + character(*) , intent( out) :: errMsg ! Error message if errStat /= ErrID_None + ! locals + integer(IntKi) :: errStat2 ! local status of error message + character(errMsgLen) :: errMsg2 ! local error message if errStat /= ErrID_None + type(InflowWind_InitInputType) :: InitInData ! Input data for initialization + errStat = ErrID_None + errMsg = '' + + ! --- Count number of points required by AeroDyn + InitInData%NumWindPoints = AD_NumWindPoints(u_AD, o_AD) + ! Adding Hub windspeed for each turbine + InitInData%NumWindPoints = InitInData%NumWindPoints + size(u_AD%rotors) + + ! --- Init InflowWind + if (i_IW%CompInflow==0) then + ! Fake "InflowWind" init + allocate(InitOutData%WriteOutputHdr(0)) + allocate(InitOutData%WriteOutputUnt(0)) + allocate(IW%y%WriteOutput(0)) + call AllocAry(IW%u%PositionXYZ, 3, InitInData%NumWindPoints, 'PositionXYZ', errStat2, errMsg2); if (Failed()) return + call AllocAry(IW%y%VelocityUVW, 3, InitInData%NumWindPoints, 'VelocityUVW', errStat2, errMsg2); if (Failed()) return + IW%u%PositionXYZ = myNaN + IW%y%VelocityUVW = myNaN + else + ! Module init + InitInData%InputFileName = i_IW%InputFile + InitInData%Linearize = i_IW%Linearize + InitInData%UseInputFile = i_IW%UseInputFile + if (.not. i_IW%UseInputFile) then + call NWTC_Library_Copyfileinfotype( i_IW%PassedFileData, InitInData%PassedFileData, MESH_NEWCOPY, errStat2, errMsg2 ); if (Failed()) return + endif + InitInData%RootName = trim(Root)//'.IfW' + InitInData%MHK = i_IW%MHK + CALL InflowWind_Init( InitInData, IW%u, IW%p, & + IW%x, IW%xd, IW%z, IW%OtherSt, & + IW%y, IW%m, dt, InitOutData, errStat2, errMsg2 ) + if(Failed()) return + + endif + ! --- Store main init input data (data that don't use InfloWind directly) + IW%CompInflow = i_IW%CompInflow + IW%HWindSpeed = i_IW%HWindSpeed + IW%RefHt = i_IW%RefHt + IW%PLExp = i_IW%PLExp + + call cleanup() +contains + subroutine cleanup() + call InflowWind_DestroyInitInput( InitInData, errStat2, errMsg2 ) + end subroutine cleanup + + logical function Failed() + CALL SetErrStat( errStat2, errMsg2, errStat, errMsg, 'ADI_InitInflowWind' ) + Failed = errStat >= AbortErrLev + if (Failed) call cleanup() + end function Failed +end subroutine ADI_InitInflowWind +!---------------------------------------------------------------------------------------------------------------------------------- +!> Concatenate new output channels info to the extisting ones in the driver +subroutine concatOutputHeaders(WriteOutputHdr0, WriteOutputUnt0, WriteOutputHdr, WriteOutputUnt, errStat, errMsg) + character(ChanLen), dimension(:), allocatable, intent(inout) :: WriteOutputHdr0 !< Channel headers + character(ChanLen), dimension(:), allocatable, intent(inout) :: WriteOutputUnt0 !< Channel units + character(ChanLen), dimension(:), allocatable, intent(inout) :: WriteOutputHdr !< Channel headers + character(ChanLen), dimension(:), allocatable, intent(inout) :: WriteOutputUnt !< Channel units + integer(IntKi) , intent( out) :: errStat !< Status of error message + character(*) , intent( out) :: errMsg !< Error message if errStat /= ErrID_None + ! Locals + character(ChanLen), allocatable :: TmpHdr(:) + character(ChanLen), allocatable :: TmpUnt(:) + integer :: nOld, nAdd + errStat = ErrID_None + errMsg = '' + !print*,'>>> Concat',allocated(WriteOutputHdr0), allocated(WriteOutputUnt0), allocated(WriteOutputHdr), allocated(WriteOutputUnt) + if (.not.allocated(WriteOutputHdr)) return + if (.not.allocated(WriteOutputHdr0)) then + call move_alloc(WriteOutputHdr, WriteOutputHdr0) + call move_alloc(WriteOutputUnt, WriteOutputUnt0) + else + nOld = size(WriteOutputHdr0) + nAdd = size(WriteOutputHdr) + + call move_alloc(WriteOutputHdr0, TmpHdr) + call move_alloc(WriteOutputUnt0, TmpUnt) + + allocate(WriteOutputHdr0(nOld+nAdd)) + allocate(WriteOutputUnt0(nOld+nAdd)) + WriteOutputHdr0(1:nOld) = TmpHdr + WriteOutputUnt0(1:nOld) = TmpUnt + WriteOutputHdr0(nOld+1:nOld+nAdd) = WriteOutputHdr + WriteOutputUnt0(nOld+1:nOld+nAdd) = WriteOutputUnt + deallocate(TmpHdr) + deallocate(TmpUnt) + endif +end subroutine concatOutputHeaders +!---------------------------------------------------------------------------------------------------------------------------------- +!> Solve for the wind speed at the location necessary for AeroDyn +subroutine ADI_ADIW_Solve(t, p_AD, u_AD, o_AD, u_IfW, IW, hubHeightFirst, errStat, errMsg) + real(DbKi), intent(in ) :: t ! Time of evaluation + type(ADI_ParameterType), intent(in ) :: p_AD ! Parameters + type(AD_InputType), intent(inout) :: u_AD ! AeroDyn data + type(AD_OtherStateType), intent(in ) :: o_AD ! AeroDyn data + type(InflowWind_InputType), intent(inout) :: u_IfW ! InflowWind data + type(ADI_InflowWindData), intent(inout) :: IW ! InflowWind data + logical, intent(in ) :: hubHeightFirst ! Hub Height velocity is packed at beginning + integer(IntKi) , intent( out) :: errStat ! Status of error message + character(*) , intent( out) :: errMsg ! Error message if errStat /= ErrID_None + integer(IntKi) :: errStat2 ! Status of error message + character(errMsgLen) :: errMsg2 ! Error message if errStat /= ErrID_None + errStat = ErrID_None + errMsg = '' + + ! Set u_ifW%PositionXYZ + call ADI_Set_IW_Inputs(p_AD, u_AD, o_AD, u_IfW, hubHeightFirst, errStat2, errMsg2); if(Failed()) return + ! Compute IW%y%VelocityUVW + call ADI_CalcOutput_IW(t, u_IfW, IW, errStat2, errMsg2); if(Failed()) return + ! Set u_AD%..%InflowOnBlade, u_AD%..%InflowOnTower, etc + call ADI_AD_InputSolve_IfW(u_AD, IW%y, hubHeightFirst, errStat2, errMsg2); if(Failed()) return + +contains + logical function Failed() + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'ADI_ADIW_Solve') + Failed = errStat >= AbortErrLev + end function Failed +end subroutine ADI_ADIW_Solve +!---------------------------------------------------------------------------------------------------------------------------------- +!> Set inputs for inflow wind +subroutine ADI_Set_IW_Inputs(p_AD, u_AD, o_AD, u_IfW, hubHeightFirst, errStat, errMsg) + type(ADI_ParameterType), intent(in ) :: p_AD ! Parameters + type(AD_InputType), intent(in ) :: u_AD ! AeroDyn data + type(AD_OtherStateType), intent(in ) :: o_AD ! AeroDyn data + type(InflowWind_InputType), intent(inout) :: u_IfW ! InflowWind data + logical, intent(in ) :: hubHeightFirst ! Hub Height velocity is packed at beginning + integer(IntKi) , intent( out) :: errStat ! Status of error message + character(*) , intent( out) :: errMsg ! Error message if errStat /= ErrID_None + integer :: node, iWT + errStat = ErrID_None + errMsg = '' + node=0 + + if (hubHeightFirst) then + ! Hub Height point for each turbine + do iWT=1,size(u_AD%rotors) + node = node + 1 + u_IfW%PositionXYZ(:,node) = u_AD%rotors(iWT)%hubMotion%Position(:,1) + u_AD%rotors(iWT)%hubMotion%TranslationDisp(:,1) + enddo + endif + call AD_SetExternalWindPositions(u_AD, o_AD, u_IfW%PositionXYZ, node, errStat, errMsg) + if ( p_AD%MHK == 1 .or. p_AD%MHK == 2 ) then + u_IfW%PositionXYZ(3,:) = u_IfW%PositionXYZ(3,:) + p_AD%WtrDpth + endif +end subroutine ADI_Set_IW_Inputs +!---------------------------------------------------------------------------------------------------------------------------------- +!---------------------------------------------------------------------------------------------------------------------------------- +!> Calculate Wind at desired points +!! NOTE: order is important and should match AD_NumWindPoints +!! Similar to FAST_Solver, IfW_InputSolve +subroutine ADI_CalcOutput_IW(t, u_IfW, IW, errStat, errMsg) + real(DbKi), intent(in ) :: t ! Time of evaluation + type(InflowWind_InputType), intent(inout) :: u_IfW ! InflowWind data + type(ADI_InflowWindData), intent(inout) :: IW ! InflowWind data + integer(IntKi) , intent( out) :: errStat ! Status of error message + character(*) , intent( out) :: errMsg ! Error message if errStat /= ErrID_None + integer :: j + real(ReKi) :: z + integer(IntKi) :: errStat2 ! Status of error message + character(errMsgLen) :: errMsg2 ! Error message if errStat /= ErrID_None + errStat = ErrID_None + errMsg = '' + if (IW%CompInflow==1) then + call InflowWind_CalcOutput(t, u_IfW, IW%p, IW%x, IW%xd, IW%z, IW%OtherSt, IW%y, IW%m, errStat2, errMsg2) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'ADI_CalcOutput_IW') + else + !$OMP PARALLEL DEFAULT(SHARED) + !$OMP DO PRIVATE(j,z) schedule(runtime) + do j=1,size(u_IfW%PositionXYZ,2) + z = u_IfW%PositionXYZ(3,j) + IW%y%VelocityUVW(1,j) = IW%HWindSpeed*(z/IW%RefHt)**IW%PLExp + IW%y%VelocityUVW(2,j) = 0.0_ReKi !V + IW%y%VelocityUVW(3,j) = 0.0_ReKi !W + end do + !$OMP END DO + !$OMP END PARALLEL + endif +end subroutine ADI_CalcOutput_IW +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine sets the wind claculated by InflowWind to the AeroDyn arrays +!! See similar routine in FAST_Solver +!! TODO put this in AeroDyn +subroutine ADI_AD_InputSolve_IfW(u_AD, y_IfW, hubHeightFirst, errStat, errMsg) + ! Passed variables + TYPE(AD_InputType), INTENT(INOUT) :: u_AD !< The inputs to AeroDyn + TYPE(InflowWind_OutputType), INTENT(IN) :: y_IfW !< The outputs from InflowWind + logical, intent(in ) :: hubHeightFirst ! Hub Height velocity is packed at beginning + INTEGER(IntKi) :: errStat !< Error status of the operation + CHARACTER(*) :: errMsg !< Error message if errStat /= ErrID_None + ! Local variables: + INTEGER(IntKi) :: node + INTEGER(IntKi) :: iWT + errStat = ErrID_None + errMsg = "" + node = 1 + ! Order important! + if (hubHeightFirst) then + do iWT=1,size(u_AD%rotors) + node = node + 1 ! Hub velocities for each rotor + enddo + endif + call AD_GetExternalWind(u_AD, y_IfW%VelocityUVW, node, errStat, errMsg) + +end subroutine ADI_AD_InputSolve_IfW + + + +! --------------------------------------------------------------------------------} +! --- ROUTINES RELEVANT FOR COUPLING WITH "FED": Fake ElastoDyn +! --------------------------------------------------------------------------------{ +!> Initialize the mesh mappings between the structure and aerodyn +!! Also adjust the tower mesh so that is is aligned with the tower base and tower top +!! Similar to FAST_Solver.f90, InitModuleMappings +subroutine Init_MeshMap_For_ADI(FED, p, uAD, errStat, errMsg) + type(FED_Data), target, intent(inout) :: FED ! Elastic wind turbine data (Fake ElastoDyn) + type(ADI_ParameterType), intent( in) :: p ! Parameters + type(AD_InputType), intent(inout) :: uAD ! AeroDyn input data + integer(IntKi) , intent( out) :: errStat ! Status of error message + character(*) , intent( out) :: errMsg ! Error message if errStat /= ErrID_None + ! locals + real(ReKi) :: pos(3), Pbase(3), Ptop(3), DeltaP(3) + real(R8Ki) :: orientation(3,3) + real(ReKi) :: twrHeightAD , twrHeight + real(ReKi) :: zBar ! dimensionsless tower height + integer(IntKi) :: iWT, iB, i + integer(IntKi) :: errStat2 ! local status of error message + character(ErrMsgLen) :: errMsg2 ! local error message if errStat /= ErrID_None + type(RotFED), pointer :: y_ED ! Alias to shorten notation + errStat = ErrID_None + errMsg = '' + + ! --- Create Mappings from structure to AeroDyn + do iWT=1,size(FED%WT) + y_ED => FED%WT(iWT) + ! hub 2 hubAD + call MeshMapCreate(y_ED%HubPtMotion, uAD%rotors(iWT)%hubMotion, y_ED%ED_P_2_AD_P_H, errStat2, errMsg2); if(Failed())return + + ! nac 2 nacAD + call MeshMapCreate(y_ED%NacelleMotion, uAD%rotors(iWT)%nacelleMotion, y_ED%ED_P_2_AD_P_N, errStat2, errMsg2); if(Failed())return + + ! nac 2 tfinAD + if (uAD%rotors(iWT)%TFinMotion%Committed) then + call MeshMapCreate(y_ED%NacelleMotion, uAD%rotors(iWT)%TFinMotion, y_ED%ED_P_2_AD_P_TF, errStat2, errMsg2); if(Failed())return + endif + + ! bldroot 2 bldroot AD + allocate(y_ED%ED_P_2_AD_P_R(y_ED%numBlades)) + do iB = 1, y_ED%numBlades + call MeshMapCreate(y_ED%BladeRootMotion(iB), uAD%rotors(iWT)%BladeRootMotion(iB), y_ED%ED_P_2_AD_P_R(iB), errStat2, errMsg2); if(Failed())return + enddo + + if (y_ED%rigidBlades) then + ! TODO Only for Rigid + ! AD bld root 2 AD blade line + allocate(y_ED%AD_P_2_AD_L_B(y_ED%numBlades)) + do iB = 1, y_ED%numBlades + call MeshMapCreate(uAD%rotors(iWT)%BladeRootMotion(iB), uAD%rotors(iWT)%BladeMotion(iB), y_ED%AD_P_2_AD_L_B(iB), errStat2, errMsg2); if(Failed())return + enddo + else + print*,'>>> Init_MeshMap_For_ADI, TODO coupling with elastic blades' + STOP + endif + + if (uAD%rotors(iWT)%TowerMotion%nNodes>0) then + if (y_ED%hasTower) then + twrHeightAD=uAD%rotors(iWT)%TowerMotion%Position(3,uAD%rotors(iWT)%TowerMotion%nNodes)-uAD%rotors(iWT)%TowerMotion%Position(3,1) + ! Check tower height + if ( p%MHK==2 ) then + if (twrHeightAD>0) then + errStat=ErrID_Fatal + errMsg='First AeroDyn tower height should be larger than last AD tower height for a floating MHK turbine' + endif + else + if (twrHeightAD<0) then + errStat=ErrID_Fatal + errMsg='First AeroDyn tower height should be smaller than last AD tower height' + endif + endif + + twrHeightAD=uAD%rotors(iWT)%TowerMotion%Position(3,uAD%rotors(iWT)%TowerMotion%nNodes) ! NOTE: assuming start a z=0 + if ( p%MHK==1 ) then + twrHeightAD = twrHeightAD + p%WtrDpth + elseif ( p%MHK==2 ) then + twrHeightAD = abs(twrHeightAD) + endif + + twrHeight=TwoNorm(y_ED%NacelleMotion%Position(:,1) - y_ED%TwrPtMesh%Position(:,1) ) + ! KEEP ME, in summary file + !print*,'Tower Height',twrHeight, twrHeightAD + if (abs(twrHeightAD-twrHeight)> twrHeight*0.1) then + errStat=ErrID_Fatal + errMsg='More than 10% difference between AeroDyn tower length ('//trim(num2lstr(twrHeightAD))//& + 'm), and the distance from tower base to nacelle ('//trim(num2lstr(twrHeight))//'m) for turbine '//trim(num2lstr(iWT)) + endif + + ! Adjust tower position (AeroDyn return values assuming (0,0,0) for tower base + Pbase = y_ED%TwrPtMesh%Position(:,1) + Ptop = y_ED%NacelleMotion%Position(:,1) + if ( p%MHK==2 ) then + DeltaP = Pbase-Ptop + else + DeltaP = Ptop-Pbase + endif + do i = 1, uAD%rotors(iWT)%TowerMotion%nNodes + if ( p%MHK==1 ) then + zBar = (uAD%rotors(iWT)%TowerMotion%Position(3,i) + p%WtrDpth) / twrHeight + else + zBar = uAD%rotors(iWT)%TowerMotion%Position(3,i)/twrHeight + endif + uAD%rotors(iWT)%TowerMotion%Position(:,i)= Pbase+ zBar * DeltaP + uAD%rotors(iWT)%TowerMotion%RefOrientation(:,:,i)= y_ED%TwrPtMesh%RefOrientation(:,:,1) + enddo + ! Create AD tower base point mesh + pos = y_ED%TwrPtMesh%Position(:,1) + orientation = y_ED%TwrPtMesh%RefOrientation(:,:,1) + call Eye(orientation, errStat2, errMsg2) + call CreatePointMesh(y_ED%TwrPtMeshAD, pos, orientation, errStat2, errMsg2, hasMotion=.True., hasLoads=.False.); if(Failed())return + + ! TowerBase to AD tower base + call MeshMapCreate(y_ED%TwrPtMesh, y_ED%TwrPtMeshAD, y_ED%ED_P_2_AD_P_T, errStat2, errMsg2); if(Failed()) return + + ! AD TowerBase to AD tower line + call MeshMapCreate(y_ED%TwrPtMeshAD, uAD%rotors(iWT)%TowerMotion, y_ED%AD_P_2_AD_L_T, errStat2, errMsg2); if(Failed()) return + endif ! hasTower + else + ! Do Nothing for now + endif + + enddo ! Loop on WT/rotors + +contains + + logical function Failed() + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Init_MeshMap_For_ADI') + Failed = errStat >= AbortErrLev + end function Failed +end subroutine Init_MeshMap_For_ADI +!---------------------------------------------------------------------------------------------------------------------------------- +!> Set aerodyn inputs based on FED meshes +! - set AD input meshes and inflow +subroutine Set_Inputs_For_ADI(u_ADI, FED, errStat, errMsg) + type(ADI_InputType), intent(inout) :: u_ADI !< AeroDyn/InflowWind Data inputs + type(FED_Data), target, intent(inout) :: FED !< Elastic wind turbine data (Fake ElastoDyn) + integer(IntKi) , intent( out) :: errStat !< Status of error message + character(*) , intent( out) :: errMsg !< Error message if errStat /= ErrID_None + ! local variables + integer(intKi) :: iWT ! loop counter for rotors + integer(intKi) :: iB ! loop counter for blades + integer(IntKi) :: errStat2 ! local status of error message + character(ErrMsgLen) :: errMsg2 ! local error message if errStat /= ErrID_None + type(RotFED), pointer :: y_ED ! Alias to shorten notation + errStat = ErrID_None + errMsg = "" + + ! --- Transfer motion from "ED" to AeroDyn + do iWT=1,size(FED%WT) + y_ED => FED%WT(iWT) + ! Hub 2 Hub AD + call Transfer_Point_to_Point(y_ED%HubPtMotion, u_ADI%AD%rotors(iWT)%hubMotion, y_ED%ED_P_2_AD_P_H, errStat2, errMsg2); if(Failed()) return + + ! Nac 2 Nac AD + call Transfer_Point_to_Point(y_ED%NacelleMotion, u_ADI%AD%rotors(iWT)%nacelleMotion, y_ED%ED_P_2_AD_P_N, errStat2, errMsg2); if(Failed()) return + + ! Nac 2 TailFin AD (Transfer ElastoDyn CM motion (taken as Nacelle) to AeroDyn tailfin ref point motion + if (u_ADI%AD%rotors(iWT)%TFinMotion%Committed) then + call Transfer_Point_to_Point( y_ED%NacelleMotion, u_ADI%AD%rotors(IWT)%TFinMotion, y_ED%ED_P_2_AD_P_TF, errStat2, errMsg2 ); if(Failed()) return + end if + + ! Blade root to blade root AD + do iB = 1,y_ED%numBlades + call Transfer_Point_to_Point(y_ED%BladeRootMotion(iB), u_ADI%AD%rotors(iWT)%BladeRootMotion(iB), y_ED%ED_P_2_AD_P_R(iB), errStat2, errMsg2); if(Failed()) return + enddo + + ! Blade root AD to blade line AD + if (y_ED%rigidBlades) then + do iB = 1,y_ED%numBlades + call Transfer_Point_to_Line2(u_ADI%AD%rotors(iWT)%BladeRootMotion(iB), u_ADI%AD%rotors(iWT)%BladeMotion(iB), y_ED%AD_P_2_AD_L_B(iB), errStat2, errMsg2); if(Failed()) return + enddo + else + print*,'>>> Set_Inputs_For_ADI: TODO Elastic Blades' + STOP + endif + + ! Tower motion + if (y_ED%hasTower) then + if (u_ADI%AD%rotors(iWT)%TowerMotion%nNodes>0) then + call Transfer_Point_to_Point(y_ED%TwrPtMesh, y_ED%TwrPtMeshAD, y_ED%ED_P_2_AD_P_T, errStat2, errMsg2); if(Failed()) return + call Transfer_Point_to_Line2(y_ED%TwrPtMeshAD, u_ADI%AD%rotors(iWT)%TowerMotion, y_ED%AD_P_2_AD_L_T, errStat2, errMsg2); if(Failed()) return + endif + endif + enddo ! iWT, rotors + +contains + logical function Failed() + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'Set_Inputs_For_ADI') + Failed = errStat >= AbortErrLev + end function Failed +end subroutine Set_Inputs_For_ADI + + +end module AeroDyn_Inflow diff --git a/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 new file mode 100644 index 000000000..b311284cf --- /dev/null +++ b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 @@ -0,0 +1,1860 @@ +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2021 National Renewable Energy Lab +! +! This file is part of AeroDyn. +! +! 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 AeroDyn_Inflow_C_BINDING + + USE ISO_C_BINDING + USE AeroDyn_Inflow + USE AeroDyn_Inflow_Types + USE AeroDyn_Driver_Types, only: Dvr_SimData, Dvr_Outputs + USE AeroDyn_Driver_Subs, only: Dvr_InitializeOutputs, Dvr_WriteOutputs, SetVTKParameters !, WrVTK_Surfaces, WrVTK_Lines, WrVTK_Ground + USE NWTC_Library + USE VersionInfo + + + IMPLICIT NONE + + PUBLIC :: AeroDyn_Inflow_C_Init + !PUBLIC :: AeroDyn_Inflow_C_ReInit + PUBLIC :: AeroDyn_Inflow_C_CalcOutput + PUBLIC :: AeroDyn_Inflow_C_UpdateStates + PUBLIC :: AeroDyn_Inflow_C_End + + !------------------------------------------------------------------------------------ + ! Version info for display + type(ProgDesc), parameter :: version = ProgDesc( 'AeroDyn-Inflow library', '', '' ) + + + !------------------------------------------------------------------------------------ + ! Debugging: debugverbose + ! 0 - none + ! 1 - some summary info + ! 2 - above + all position/orientation info + ! 3 - above + input files (if direct passed) + ! 4 - above + meshes + integer(IntKi), parameter :: debugverbose = 0 + + !------------------------------------------------------------------------------------ + ! Error handling + ! This must exactly match the value in the python-lib. If ErrMsgLen changes at + ! some point in the nwtc-library, this should be updated, but the logic exists + ! to correctly handle different lengths of the strings + integer(IntKi), parameter :: ErrMsgLen_C = 1025 + integer(IntKi), parameter :: IntfStrLen = 1025 ! length of other strings through the C interface + + !------------------------------------------------------------------------------------ + ! Potential issues + ! - if MaxADIOutputs is sufficiently large, we may overrun the buffer on the Python + ! side (OutputChannelNames_C,OutputChannelUnits_C). Don't have a good method to + ! check this in code yet. Might be best to pass the max length over to Init and + ! do some checks here. May also want to convert this to C_NULL_CHAR delimiter + ! instead of fixed width. + ! - NOTE: AD: MaxOutputs = 1291 + ! IfW: MaxOutputs = 59 + integer(IntKi), parameter :: MaxADIOutputs = 8000 + + !------------------------------------------------------------------------------------ + ! Data storage + ! All AeroDyn data is stored within the following data structures inside this + ! module. No data is stored within AeroDyn itself, but is instead passed in + ! from this module. This data is not available to the calling code unless + ! explicitly passed through the interface (derived types such as these are + ! non-trivial to pass through the c-bindings). + !------------------------------ + ! Extrapolation and interpolation + ! For the solver in AD, previous timesteps input must be stored for extrapolation + ! to the t+dt timestep. This can be either linear (1) quadratic (2). The + ! InterpOrder variable tracks what this is and sets the size of the inputs `u` + ! passed into AD. Inputs `u` will be sized as follows: + ! linear interp u(2) with inputs at T,T-dt + ! quadratic interp u(3) with inputs at T,T-dt,T-2*dt + integer(IntKi) :: InterpOrder + !------------------------------ + ! Primary ADI data derived data types + type(ADI_Data) :: ADI + type(ADI_InitInputType) :: InitInp !< Initialization data + type(ADI_InitOutputType) :: InitOutData !< Initial output data -- Names, units, and version info. + !------------------------------ + ! Simulation data + type(Dvr_SimData) :: Sim !< data about the simulation + !------------------------------ + ! Outputs + type(Dvr_Outputs) :: WrOutputsData !< Data for writing outputs to file + integer(IntKi), parameter :: idFmtNone = 0 + integer(IntKi), parameter :: idFmtAscii = 1 + integer(IntKi), parameter :: idFmtBinary = 2 + integer(IntKi), parameter :: idFmtBoth = 3 + + !------------------------------ + ! Time tracking + ! When we are performing a correction step, time information of previous + ! calls is needed to decide how to apply correction logic or cycle the inputs + ! and resave the previous timestep states. + ! Correction steps + ! OpenFAST has the ability to perform correction steps. During a correction + ! step, new input values are passed in but the timestep remains the same. + ! When this occurs the new input data at time t is used with the state + ! information from the previous timestep (t) to calculate new state values + ! time t+dt in the UpdateStates routine. In OpenFAST this is all handled by + ! the glue code. However, here we do not pass state information through the + ! interface and therefore must store it here analogously to how it is handled + ! in the OpenFAST glue code. + integer(IntKi) :: n_Global ! global timestep + integer(IntKi) :: n_VTK ! VTK timestep + real(DbKi) :: InputTimePrev ! input time of last UpdateStates call + ! Note that we are including the previous state info here (not done in OF this way) + integer(IntKi), parameter :: STATE_LAST = 0 ! Index for previous state (not needed in OF, but necessary here) + integer(IntKi), parameter :: STATE_CURR = 1 ! Index for current state + integer(IntKi), parameter :: STATE_PRED = 2 ! Index for predicted state + ! Note the indexing is different on inputs (no clue why, but thats how OF handles it) + integer(IntKi), parameter :: INPUT_LAST = 3 ! Index for previous input at t-dt + integer(IntKi), parameter :: INPUT_CURR = 2 ! Index for current input at t + integer(IntKi), parameter :: INPUT_PRED = 1 ! Index for predicted input at t+dt + + !------------------------------------------------------------------------------------ + ! Meshes for motions and loads + ! Meshes are used within AD to handle all motions and loads. Rather than directly + ! map to those nodes, we will create a mapping to go between the array of node + ! positions passed into this module and what is used inside AD. This is done + ! through a pair of meshes for the motion and loads corresponding to the node + ! positions passed in. + !------------------------------ + ! Meshes for external nodes + ! These point meshes are merely used to simplify the mapping of motions/loads + ! to/from AD using the library mesh mapping routines. These meshes may contain + ! one or multiple points. + ! - 1 point -- rigid floating body assumption + ! - N points -- flexible structure (either floating or fixed bottom) + logical :: TransposeDCM !< Transpose DCMs as passed in -- test the vtk outputs to see if needed + integer(IntKi) :: NumMeshPts ! Number of mesh points we are interfacing motions/loads to/from AD + type(MeshType) :: BldPtMotionMesh ! mesh for motions of external nodes + type(MeshType) :: BldPtLoadMesh ! mesh for loads for external nodes + type(MeshType) :: BldPtLoadMesh_tmp ! mesh for loads for external nodes -- temporary +! type(MeshType) :: NacMotionMesh ! mesh for motion of nacelle -- TODO: add this mesh for nacelle load transfers +! type(MeshType) :: NacLoadMesh ! mesh for loads for nacelle loads -- TODO: add this mesh for nacelle load transfers + !------------------------------ + ! Mesh mapping: motions + ! The mapping of motions from the nodes passed in to the corresponding AD meshes + type(MeshMapType), allocatable :: Map_BldPtMotion_2_AD_Blade(:) ! Mesh mapping between input motion mesh for blade +! type(MeshMapType) :: Map_AD_Nac_2_NacPtLoad ! Mesh mapping between input motion mesh for nacelle + !------------------------------ + ! Mesh mapping: loads + ! The mapping of loads from the AD meshes to the corresponding external nodes + type(MeshMapType), allocatable :: Map_AD_BldLoad_P_2_BldPtLoad(:) ! Mesh mapping between AD output blade line2 load to BldPtLoad for return +! type(MeshMapType) :: Map_NacPtMotion_2_AD_Nac ! Mesh mapping between AD output nacelle pt load to NacLoad for return + ! Motions input (so we don't have to reallocate all the time + real(ReKi), allocatable :: tmpBldPtMeshPos(:,:) ! temp array. Probably don't need this, but makes conversion from C clearer. + real(ReKi), allocatable :: tmpBldPtMeshOri(:,:,:) ! temp array. Probably don't need this, but makes conversion from C clearer. + real(ReKi), allocatable :: tmpBldPtMeshVel(:,:) ! temp array. Probably don't need this, but makes conversion from C clearer. + real(ReKi), allocatable :: tmpBldPtMeshAcc(:,:) ! temp array. Probably don't need this, but makes conversion from C clearer. + real(ReKi), allocatable :: tmpBldPtMeshFrc(:,:) ! temp array. Probably don't need this, but makes conversion to C clearer. + !------------------------------------------------------------------------------------ + + + + +CONTAINS + +!> This routine sets the error status in C_CHAR for export to calling code. +!! Make absolutely certain that we do not overrun the end of ErrMsg_C. That is hard coded to 1025, +!! but ErrMsgLen is set in the nwtc_library, and could change without updates here. We don't want an +!! inadvertant buffer overrun -- that can lead to bad things. +subroutine SetErr(ErrStat, ErrMsg, ErrStat_C, ErrMsg_C) + integer, intent(in ) :: ErrStat !< aggregated error message (fortran type) + character(ErrMsgLen), intent(in ) :: ErrMsg !< aggregated error message (fortran type) + integer(c_int), intent( out) :: ErrStat_C + character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) + integer :: i + ErrStat_C = ErrStat ! We will send back the same error status that is used in OpenFAST + if (ErrMsgLen > ErrMsgLen_C-1) then ! If ErrMsgLen is > the space in ErrMsg_C, do not copy everything over + ErrMsg_C = TRANSFER( trim(ErrMsg(1:ErrMsgLen_C-1))//C_NULL_CHAR, ErrMsg_C ) + else + ErrMsg_C = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_C ) + endif +end subroutine SetErr + + +!=============================================================================================================== +!--------------------------------------------- AeroDyn Init---------------------------------------------------- +!=============================================================================================================== +SUBROUTINE AeroDyn_Inflow_C_Init( ADinputFilePassed, ADinputFileString_C, ADinputFileStringLength_C, & + IfWinputFilePassed, IfWinputFileString_C, IfWinputFileStringLength_C, OutRootName_C, & + gravity_C, defFldDens_C, defKinVisc_C, defSpdSound_C, & + defPatm_C, defPvap_C, WtrDpth_C, MSL2SWL_C, & + AeroProjMod_C, & + InterpOrder_C, DT_C, TMax_C, & + storeHHVel, TransposeDCM_in, & + WrVTK_in, WrVTK_inType, VTKNacDim_in, VTKHubRad_in, & + wrOuts_C, DT_Outs_C, & + HubPos_C, HubOri_C, & + NacPos_C, NacOri_C, & + NumBlades_C, BldRootPos_C, BldRootOri_C, & + NumMeshPts_C, InitMeshPos_C, InitMeshOri_C, & + NumChannels_C, OutputChannelNames_C, OutputChannelUnits_C, & + ErrStat_C, ErrMsg_C) BIND (C, NAME='AeroDyn_Inflow_C_Init') + implicit none +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: AeroDyn_Inflow_C_Init +!GCC$ ATTRIBUTES DLLEXPORT :: AeroDyn_Inflow_C_Init +#endif + ! Input file info + logical(c_bool), intent(in ) :: ADinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] + type(c_ptr), intent(in ) :: ADinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR + integer(c_int), intent(in ) :: ADinputFileStringLength_C !< lenght of the input file string + logical(c_bool), intent(in ) :: IfWinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] + type(c_ptr), intent(in ) :: IfWinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR + integer(c_int), intent(in ) :: IfWinputFileStringLength_C !< lenght of the input file string + character(kind=c_char), intent(in ) :: OutRootName_C(IntfStrLen) !< Root name to use for echo files and other + ! Environmental + real(c_float), intent(in ) :: gravity_C !< Gravitational acceleration (m/s^2) + real(c_float), intent(in ) :: defFldDens_C !< Air density (kg/m^3) + real(c_float), intent(in ) :: defKinVisc_C !< Kinematic viscosity of working fluid (m^2/s) + real(c_float), intent(in ) :: defSpdSound_C !< Speed of sound in working fluid (m/s) + real(c_float), intent(in ) :: defPatm_C !< Atmospheric pressure (Pa) [used only for an MHK turbine cavitation check] + real(c_float), intent(in ) :: defPvap_C !< Vapour pressure of working fluid (Pa) [used only for an MHK turbine cavitation check] + real(c_float), intent(in ) :: WtrDpth_C !< Water depth (m) + real(c_float), intent(in ) :: MSL2SWL_C !< Offset between still-water level and mean sea level (m) [positive upward] + ! Aero calculation method -- AeroProjMod + ! APM_BEM_NoSweepPitchTwist - 1 - "Original AeroDyn model where momentum balance is done in the WithoutSweepPitchTwist system" + ! APM_BEM_Polar - 2 - "Use staggered polar grid for momentum balance in each annulus" + ! APM_LiftingLine - 3 - "Use the blade lifting line (i.e. the structural) orientation (currently for OLAF with VAWT)" + integer(c_int), intent(in ) :: AeroProjMod_C !< Type of aerodynamic projection + ! Initial hub and blade root positions/orientations + real(c_float), intent(in ) :: HubPos_C( 3 ) !< Hub position + real(c_double), intent(in ) :: HubOri_C( 9 ) !< Hub orientation + real(c_float), intent(in ) :: NacPos_C( 3 ) !< Nacelle position + real(c_double), intent(in ) :: NacOri_C( 9 ) !< Nacelle orientation + integer(c_int), intent(in ) :: NumBlades_C !< Number of blades + real(c_float), intent(in ) :: BldRootPos_C( 3*NumBlades_C ) !< Blade root positions + real(c_double), intent(in ) :: BldRootOri_C( 9*NumBlades_C ) !< Blade root orientations + ! Initial nodes + integer(c_int), intent(in ) :: NumMeshPts_C !< Number of mesh points we are transfering motions to and output loads to + real(c_float), intent(in ) :: InitMeshPos_C( 3*NumMeshPts_C ) !< A 3xNumMeshPts_C array [x,y,z] + real(c_double), intent(in ) :: InitMeshOri_C( 9*NumMeshPts_C ) !< A 9xNumMeshPts_C array [r11,r12,r13,r21,r22,r23,r31,r32,r33] + ! Interpolation + integer(c_int), intent(in ) :: InterpOrder_C !< Interpolation order to use (must be 1 or 2) + ! Time + real(c_double), intent(in ) :: DT_C !< Timestep used with AD for stepping forward from t to t+dt. Must be constant. + real(c_double), intent(in ) :: TMax_C !< Maximum time for simulation + ! Flags + logical(c_bool), intent(in ) :: storeHHVel !< Store hub height time series from IfW + logical(c_bool), intent(in ) :: TransposeDCM_in !< Transpose DCMs as they are passed in + ! VTK + integer(c_int), intent(in ) :: WrVTK_in !< Write VTK outputs [0: none, 1: init only, 2: animation] + integer(c_int), intent(in ) :: WrVTK_inType !< Write VTK outputs as [1: surface, 2: lines, 3: both] + real(c_float), intent(in ) :: VTKNacDim_in(6) !< Nacelle dimension passed in for VTK surface rendering [0,y0,z0,Lx,Ly,Lz] (m) + real(c_float), intent(in ) :: VTKHubrad_in !< Hub radius for VTK surface rendering + integer(c_int), intent(in ) :: wrOuts_C !< Write ADI output file + real(c_double), intent(in ) :: DT_Outs_C !< Timestep to write output file from ADI + ! Output + integer(c_int), intent( out) :: NumChannels_C !< Number of output channels requested from the input file + character(kind=c_char), intent( out) :: OutputChannelNames_C(ChanLen*MaxADIOutputs+1) !< NOTE: if MaxADIOutputs is sufficiently large, we may overrun the buffer on the Python side. + character(kind=c_char), intent( out) :: OutputChannelUnits_C(ChanLen*MaxADIOutputs+1) + integer(c_int), intent( out) :: ErrStat_C !< Error status + character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) !< Error message (C_NULL_CHAR terminated) + + ! Local Variable4 + character(IntfStrLen) :: OutRootName !< Root name to use for echo files and other + character(IntfStrLen) :: TmpFileName !< Temporary file name if not passing AD or IfW input file contents directly + character(kind=C_char, len=ADinputFileStringLength_C), pointer :: ADinputFileString !< Input file as a single string with NULL chracter separating lines + character(kind=C_char, len=IfWinputFileStringLength_C), pointer:: IfWinputFileString !< Input file as a single string with NULL chracter separating lines + + integer(IntKi) :: ErrStat !< aggregated error message + character(ErrMsgLen) :: ErrMsg !< aggregated error message + integer(IntKi) :: ErrStat2 !< temporary error status from a call + character(ErrMsgLen) :: ErrMsg2 !< temporary error message from a call + integer(IntKi) :: i,j,k !< generic counters + character(*), parameter :: RoutineName = 'AeroDyn_Inflow_C_Init' !< for error handling + + ! Initialize error handling + ErrStat = ErrID_None + ErrMsg = "" + NumChannels_C = 0_c_int + OutputChannelNames_C(:) = '' + OutputChannelUnits_C(:) = '' + + CALL NWTC_Init( ProgNameIn=version%Name ) + CALL DispCopyrightLicense( version%Name ) + CALL DispCompileRuntimeInfo( version%Name ) + + + !-------------------------- + ! Input files + !-------------------------- + ! RootName -- for output of echo or other files + OutRootName = TRANSFER( OutRootName_C, OutRootName ) + i = INDEX(OutRootName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... + if ( i > 0 ) OutRootName = OutRootName(1:I) ! remove it + + + ! For debugging the interface: + if (debugverbose > 0) then + call ShowPassedData() + endif + + + ! Get fortran pointer to C_NULL_CHAR deliniated input files as a string + call C_F_pointer(ADinputFileString_C, ADinputFileString) + call C_F_pointer(IfWinputFileString_C, IfWinputFileString) + + ! Format AD input file contents + InitInp%AD%RootName = OutRootName + if (ADinputFilePassed) then + InitInp%AD%UsePrimaryInputFile = .FALSE. ! Don't try to read an input -- use passed data instead (blades and AF tables not passed) + InitInp%AD%InputFile = "passed_ad_file" ! not actually used + call InitFileInfo(ADinputFileString, InitInp%AD%PassedPrimaryInputData, ErrStat2, ErrMsg2); if (Failed()) return + else + InitInp%AD%UsePrimaryInputFile = .TRUE. ! Read input info from a primary input file + i = min(IntfStrLen,ADinputFileStringLength_C) + TmpFileName = '' + TmpFileName(1:i) = ADinputFileString(1:i) + i = INDEX(TmpFileName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... + if ( i > 0 ) TmpFileName = TmpFileName(1:I) ! remove it + InitInp%AD%InputFile = TmpFileName + endif + + ! Format IfW input file contents + ! RootName is set in ADI_Init using InitInp%RootName + InitInp%RootName = OutRootName + if (IfWinputFilePassed) then + InitInp%IW_InitInp%UseInputFile = .FALSE. ! Don't try to read an input -- use passed data instead (blades and AF tables not passed) + InitInp%IW_InitInp%InputFile = "passed_ifw_file" ! not actually used + call InitFileInfo(IfWinputFileString, InitInp%IW_InitInp%PassedFileData, ErrStat2, ErrMsg2); if (Failed()) return + else + InitInp%IW_InitINp%UseInputFile = .TRUE. ! Read input info from a primary input file + i = min(IntfStrLen,IfWinputFileStringLength_C) + TmpFileName = '' + TmpFileName(1:i) = IfWinputFileString(1:i) + i = INDEX(TmpFileName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... + if ( i > 0 ) TmpFileName = TmpFileName(1:I) ! remove it + InitInp%IW_InitInp%InputFile = TmpFileName + endif + + + ! For diagnostic purposes, the following can be used to display the contents + ! of the InFileInfo data structure. + ! CU is the screen -- system dependent. + if (debugverbose >= 3) then + if (ADinputFilePassed) call Print_FileInfo_Struct( CU, InitInp%AD%PassedPrimaryInputData ) + if (IfWinputFilePassed) call Print_FileInfo_Struct( CU, InitInp%IW_InitInp%PassedFileData ) + endif + + ! Store data about the simulation (NOTE: we are not fully populating the Sim data structure) + allocate (Sim%WT(1),stat=errStat2); if (Failed0('wind turbines')) return + Sim%dT = REAL(DT_C, DbKi) + Sim%TMax = REAL(TMax_C, DbKi) + Sim%numSteps = ceiling(Sim%tMax/Sim%dt) + Sim%NumTurbines = 1_IntKi ! only one turbine for now + Sim%WT(1)%NumBlades = int(NumBlades_C, IntKi) + Sim%root = trim(OutRootName) + Sim%WT(1)%OriginInit = (/ 0.0_SiKi, 0.0_SiKi, 0.0_SiKi /) !TODO: should this be an input? + ! Timekeeping + n_Global = 0_IntKi ! Assume we are on timestep 0 at start + n_VTK = -1_IntKi ! Set VTK output to T=0 at first call + ! Interpolation order + InterpOrder = int(InterpOrder_C, IntKi) + + ! VTK outputs + WrOutputsData%WrVTK = int(WrVTK_in, IntKi) + WrOutputsData%WrVTK_Type = int(WrVTK_inType, IntKi) + WrOutputsData%VTKNacDim = real(VTKNacDim_in, SiKi) + WrOutputsData%VTKHubrad = real(VTKHubrad_in, SiKi) + WrOutputsData%VTKRefPoint = (/ 0.0_ReKi, 0.0_ReKi, 0.0_ReKi /) !TODO: should this be an input? + WrOutputsData%root = trim(OutRootName) + WrOutputsData%n_VTKTime = 1 ! output every timestep + + ! Write outputs to file + WrOutputsData%fileFmt = int(wrOuts_C, IntKi) + WrOutputsData%DT_Outs = real(DT_Outs_C, DbKi) + + ! Validate and set some inputs (moved to subroutine to make cleaner to read + call ValidateSetInputs(ErrStat2,ErrMsg2); if(Failed()) return + + ! Flag to transpose DCMs as they are passed in + TransposeDCM = TransposeDCM_in + + ! Linearization + ! for now, set linearization to false. Pass this in later when interface supports it + InitInp%AD%Linearize = .FALSE. + !InitInp%IW_InitInp%Linearize = .FALSE. + + + !---------------------------------------------------- + ! Set AeroDyn initialization data + !---------------------------------------------------- + InitInp%AD%Gravity = REAL(gravity_C, ReKi) + InitInp%AD%defFldDens = REAL(defFldDens_C, ReKi) + InitInp%AD%defKinVisc = REAL(defKinVisc_C, ReKi) + InitInp%AD%defSpdSound = REAL(defSpdSound_C, ReKi) + InitInp%AD%defPatm = REAL(defPatm_C, ReKi) + InitInp%AD%defPvap = REAL(defPvap_C, ReKi) + InitInp%AD%WtrDpth = REAL(WtrDpth_C, ReKi) + InitInp%AD%MSL2SWL = REAL(MSL2SWL_C, ReKi) + InitInp%storeHHVel = storeHHVel + InitInp%WrVTK = WrOutputsData%WrVTK + InitInp%WrVTK_Type = WrOutputsData%WrVTK_Type + InitInp%IW_InitInp%CompInflow = 1 ! Use InflowWind + + ! setup rotors for AD -- interface only supports one rotor at present + allocate (InitInp%AD%rotors(1),stat=errStat2); if (Failed0('rotors')) return + InitInp%AD%rotors(1)%AeroProjMod = int(AeroProjMod_C, IntKi) + InitInp%AD%rotors(1)%numBlades = Sim%WT(1)%NumBlades + call AllocAry(InitInp%AD%rotors(1)%BladeRootPosition, 3, Sim%WT(1)%NumBlades, 'BldRootPos', errStat2, errMsg2 ); if (Failed()) return + call AllocAry(InitInp%AD%rotors(1)%BladeRootOrientation, 3, 3, Sim%WT(1)%NumBlades, 'BldRootOri', errStat2, errMsg2 ); if (Failed()) return + InitInp%AD%rotors(1)%HubPosition = real(HubPos_C(1:3),ReKi) + InitInp%AD%rotors(1)%HubOrientation = reshape( real(HubOri_C(1:9),R8Ki), (/3,3/) ) + InitInp%AD%rotors(1)%NacellePosition = real(NacPos_C(1:3),ReKi) + InitInp%AD%rotors(1)%NacelleOrientation = reshape( real(NacOri_C(1:9),R8Ki), (/3,3/) ) + InitInp%AD%rotors(1)%BladeRootPosition = reshape( real(BldRootPos_C(1:3*Sim%WT(1)%NumBlades),ReKi), (/ 3,Sim%WT(1)%NumBlades/) ) + InitInp%AD%rotors(1)%BladeRootOrientation = reshape( real(BldRootOri_C(1:9*Sim%WT(1)%NumBlades),R8Ki), (/3,3,Sim%WT(1)%NumBlades/) ) + if (TransposeDCM) then + InitInp%AD%rotors(1)%HubOrientation = transpose(InitInp%AD%rotors(1)%HubOrientation) + InitInp%AD%rotors(1)%NacelleOrientation = transpose(InitInp%AD%rotors(1)%NacelleOrientation) + do i=1,Sim%WT(1)%NumBlades + InitInp%AD%rotors(1)%BladeRootOrientation(1:3,1:3,i) = transpose(InitInp%AD%rotors(1)%BladeRootOrientation(1:3,1:3,i)) + enddo + endif + + ! Remap the orientation DCM just in case there is some issue with passed + call OrientRemap(InitInp%AD%rotors(1)%HubOrientation) + call OrientRemap(InitInp%AD%rotors(1)%NacelleOrientation) + do i=1,Sim%WT(1)%NumBlades + call OrientRemap(InitInp%AD%rotors(1)%BladeRootOrientation(1:3,1:3,i)) + enddo + + ! Number of blades and initial positions + ! - NumMeshPts is the number of interface Mesh points we are expecting on the python + ! side. Will validate this against what AD reads from the initialization info. + NumMeshPts = int(NumMeshPts_C, IntKi) + if (NumMeshPts < 1) then + ErrStat2 = ErrID_Fatal + ErrMsg2 = "At least one node point must be specified" + if (Failed()) return + endif + ! Allocate temporary arrays to simplify data conversions + call AllocAry( tmpBldPtMeshPos, 3, NumMeshPts, "tmpBldPtMeshPos", ErrStat2, ErrMsg2 ); if (Failed()) return + call AllocAry( tmpBldPtMeshOri, 3, 3, NumMeshPts, "tmpBldPtMeshOri", ErrStat2, ErrMsg2 ); if (Failed()) return + call AllocAry( tmpBldPtMeshVel, 6, NumMeshPts, "tmpBldPtMeshVel", ErrStat2, ErrMsg2 ); if (Failed()) return + call AllocAry( tmpBldPtMeshAcc, 6, NumMeshPts, "tmpBldPtMeshAcc", ErrStat2, ErrMsg2 ); if (Failed()) return + call AllocAry( tmpBldPtMeshFrc, 6, NumMeshPts, "tmpBldPtMeshFrc", ErrStat2, ErrMsg2 ); if (Failed()) return + tmpBldPtMeshPos( 1:3,1:NumMeshPts) = reshape( real(InitMeshPos_C(1:3*NumMeshPts),ReKi), (/ 3,NumMeshPts/) ) + tmpBldPtMeshOri(1:3,1:3,1:NumMeshPts) = reshape( real(InitMeshOri_C(1:9*NumMeshPts),ReKi), (/3,3,NumMeshPts/) ) + + + !---------------------------------------------------- + ! Allocate input array u and corresponding InputTimes + !---------------------------------------------------- + ! These inputs are used in the time stepping algorithm within AD_UpdateStates + ! For quadratic interpolation (InterpOrder==2), 3 timesteps are used. For + ! linear (InterOrder==1), 2 timesteps (the AD code can handle either). + ! u(1) inputs at t + ! u(2) inputs at t - dt + ! u(3) inputs at t - 2*dt ! quadratic only + allocate(ADI%u(InterpOrder+1), STAT=ErrStat2); if (Failed0("inputs" )) return + allocate(ADI%x(0:2), STAT=errStat2); if (Failed0("x" )) return + allocate(ADI%xd(0:2), STAT=errStat2); if (Failed0("xd" )) return + allocate(ADI%z(0:2), STAT=errStat2); if (Failed0("z" )) return + allocate(ADI%OtherState(0:2), STAT=errStat2); if (Failed0("OtherState")) return + call AllocAry( ADI%InputTimes, InterpOrder+1, "InputTimes", ErrStat2, ErrMsg2 ); if (Failed()) return + + ! Call the main subroutine AeroDyn_Inflow_Init + ! Sim%dT and InitInp are passed into AD_Init, all the rest are set by AD_Init + ! + ! NOTE: Pass u(1) only (this is empty and will be set inside Init). We will copy + ! this to u(2) and u(3) afterwards + call ADI_Init( InitInp, ADI%u(1), ADI%p, ADI%x(STATE_CURR), ADI%xd(STATE_CURR), ADI%z(STATE_CURR), ADI%OtherState(STATE_CURR), ADI%y, ADI%m, Sim%dT, InitOutData, ErrStat2, ErrMsg2 ) + if (Failed()) return + + + !------------------------------------------------------------- + ! Sanity checks + !------------------------------------------------------------- + call CheckNodes(ErrStat2,ErrMsg2); if (Failed()) return + + + !------------------------------------------------------------- + ! Set the interface meshes for motion inputs and loads output + !------------------------------------------------------------- + call SetMotionLoadsInterfaceMeshes(ErrStat2,ErrMsg2); if (Failed()) return + if (WrOutputsData%WrVTK > 0_IntKi) then + call setVTKParameters(WrOutputsData, Sim, ADI, errStat, errMsg, 'vtk-ADI') + if (Failed()) return + call WrVTK_refMeshes(ADI%u(1)%AD%rotors(:),WrOutputsData%VTKRefPoint,ErrStat2,ErrMsg2) + if (Failed()) return + endif + + !------------------------------------------------------------- + ! Setup other prior timesteps + ! We fill InputTimes with negative times, but the Input values are identical for each of those times; this allows + ! us to use, e.g., quadratic interpolation that effectively acts as a zeroth-order extrapolation and first-order extrapolation + ! for the first and second time steps. (The interpolation order in the ExtrapInput routines are determined as + ! order = SIZE(Input) + !------------------------------------------------------------- + do i=2,InterpOrder+1 + call ADI_CopyInput (ADI%u(1), ADI%u(i), MESH_NEWCOPY, Errstat2, ErrMsg2) + if (Failed()) return + enddo + do i = 1, InterpOrder + 1 + ADI%InputTimes(i) = 0.0_DbKi - (i - 1) * Sim%dT ! assume start at T=0 + enddo + InputTimePrev = ADI%InputTimes(1) - Sim%dT ! Initialize for UpdateStates + + + !------------------------------------------------------------- + ! Initial setup of other pieces of x,xd,z,OtherState + !------------------------------------------------------------- + CALL ADI_CopyContState ( ADI%x( STATE_CURR), ADI%x( STATE_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyDiscState ( ADI%xd( STATE_CURR), ADI%xd( STATE_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyConstrState( ADI%z( STATE_CURR), ADI%z( STATE_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyOtherState ( ADI%OtherState(STATE_CURR), ADI%OtherState(STATE_PRED), MESH_NEWCOPY, Errstat2, ErrMsg2); if (Failed()) return + + !------------------------------------------------------------- + ! Setup the previous timestep copies of states + !------------------------------------------------------------- + CALL ADI_CopyContState ( ADI%x( STATE_CURR), ADI%x( STATE_LAST), MESH_NEWCOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyDiscState ( ADI%xd( STATE_CURR), ADI%xd( STATE_LAST), MESH_NEWCOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyConstrState( ADI%z( STATE_CURR), ADI%z( STATE_LAST), MESH_NEWCOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyOtherState ( ADI%OtherState(STATE_CURR), ADI%OtherState(STATE_LAST), MESH_NEWCOPY, Errstat2, ErrMsg2); if (Failed()) return + + + !------------------------------------------------- + ! Set output channel information for driver code + !------------------------------------------------- + ! Number of channels + NumChannels_C = size(InitOutData%WriteOutputHdr) + + ! transfer the output channel names and units to c_char arrays for returning + ! Upgrade idea: use C_NULL_CHAR as delimiters. Requires rework of Python + ! side of code. + k=1 + do i=1,NumChannels_C + do j=1,ChanLen ! max length of channel name. Same for units + OutputChannelNames_C(k)=InitOutData%WriteOutputHdr(i)(j:j) + OutputChannelUnits_C(k)=InitOutData%WriteOutputUnt(i)(j:j) + k=k+1 + enddo + enddo + + ! null terminate the string + OutputChannelNames_C(k) = C_NULL_CHAR + OutputChannelUnits_C(k) = C_NULL_CHAR + + !------------------------------------------------- + ! Write output file if requested + !------------------------------------------------- + if (WrOutputsData%fileFmt > idFmtNone) then + call SetupFileOutputs() + endif + + call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) + + +CONTAINS + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + if (Failed) then + call FailCleanup() + call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) + endif + end function Failed + + ! check for failed where /= 0 is fatal + logical function Failed0(txt) + character(*), intent(in) :: txt + if (errStat /= 0) then + ErrStat2 = ErrID_Fatal + ErrMsg2 = "Could not allocate "//trim(txt) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + endif + Failed0 = ErrStat >= AbortErrLev + if(Failed0) call FailCleanup() + end function Failed0 + + subroutine FailCleanup() + if (allocated(tmpBldPtMeshPos)) deallocate(tmpBldPtMeshPos) + if (allocated(tmpBldPtMeshOri)) deallocate(tmpBldPtMeshOri) + if (allocated(tmpBldPtMeshVel)) deallocate(tmpBldPtMeshVel) + if (allocated(tmpBldPtMeshAcc)) deallocate(tmpBldPtMeshAcc) + if (allocated(tmpBldPtMeshFrc)) deallocate(tmpBldPtMeshFrc) + end subroutine FailCleanup + + + !> Validate and set some of the outputs (values must be stored before here as some might be changed) + subroutine ValidateSetInputs(ErrStat3,ErrMsg3) + integer(IntKi), intent( out) :: ErrStat3 !< temporary error status + character(ErrMsgLen), intent( out) :: ErrMsg3 !< temporary error message + ! Interporder + if ( InterpOrder < 1_IntKi .or. InterpOrder > 2_IntKi ) then + call SetErrStat(ErrID_Fatal,"InterpOrder passed into AeroDyn_Inflow_C_Init must be 1 (linear) or 2 (quadratic)",ErrStat3,ErrMsg3,RoutineName) + return + endif + + ! VTK outputs + if ( WrOutputsData%WrVTK < 0_IntKi .or. WrOutputsData%WrVTK > 2_IntKi ) then + call SetErrStat(ErrID_Fatal,"WrVTK option for writing VTK visualization files must be [0: none, 1: init only, 2: animation]",ErrStat3,ErrMsg3,RoutineName) + return + endif + if ( WrOutputsData%WrVTK_Type > 0_IntKi ) then + if ( WrOutputsData%WrVTK_Type < 1_IntKi .or. WrOutputsData%WrVTK_Type > 3_IntKi ) then + call SetErrStat(ErrID_Fatal,"WrVTK_Type option for writing VTK visualization files must be [1: surface, 2: lines, 3: both]",ErrStat3,ErrMsg3,RoutineName) + return + endif + if (WrOutputsData%VTKHubRad < 0.0_SiKi) then + call SetErrStat(ErrID_Warn,"VTKHubRad for surface visualization of hub less than zero. Setting to zero.",ErrStat3,ErrMsg3,RoutineName) + WrOutputsData%VTKHubRad = 0.0_SiKi + endif + endif + + ! check fileFmt + if ( WrOutputsData%fileFmt /= idFmtNone .and. WrOutputsData%fileFmt /= idFmtAscii .and. & + WrOutputsData%fileFmt /= idFmtBinary .and. WrOutputsData%fileFmt /= idFmtBoth) then + call SetErrStat(ErrID_Warn,"Invalid file output format requested. Turning off file output.",ErrStat3,ErrMsg3,RoutineName) + WrOutputsData%fileFmt = idFmtNone + endif + if (WrOutputsData%fileFmt > idFmtNone) then + ! If a smaller timestep between outputs is requested than the simulation runs at, change to DT + if (WrOutputsData%DT_Outs < Sim%dT) then + WrOutputsData%DT_Outs = Sim%dT + call SetErrStat(ErrID_Warn,"Requested DT_Outs is smaller than timestep DT. Setting DT_Outs to DT.",ErrStat3,ErrMsg3,RoutineName) + endif + ! If not an integer multiple of DT, adjust + WrOutputsData%n_DT_Out = NINT( WrOutputsData%DT_Outs / Sim%dT ) + if (.NOT. EqualRealNos( WrOutputsData%DT_outs, Sim%dT * WrOutputsData%n_DT_Out )) then + WrOutputsData%DT_Outs = real(WrOutputsData%n_DT_Out, DbKi) * Sim%dT + call SetErrStat(ErrID_Warn,"Requested DT_Outs is not an integer multiple of DT. Changing DT_Outs to "//trim(Num2LStr(WrOutputsData%DT_Outs))//".",ErrStat3,ErrMsg3,RoutineName) + endif + endif + end subroutine ValidateSetInputs + + !> allocate data storage for file outputs + subroutine SetupFileOutputs() + ! time channel (stored but not counted as an output) + allocate(WrOutputsData%WriteOutputHdr(1), STAT=ErrStat2); if(Failed0("WriteOutputHdr")) return; + allocate(WrOutputsData%WriteOutputUnt(1), STAT=ErrStat2); if(Failed0("WriteOutputUnt")) return; + allocate(Sim%wt(1)%WriteOutput(1), STAT=ErrStat2); if(Failed0("WriteOutput")) return; + WrOutputsData%WriteOutputHdr(1) = 'Time' + WrOutputsData%WriteOutputUnt(1) = '(s)' + WrOutputsData%nDvrOutputs = 0 + + ! assemble all headers + call concatOutputHeaders(WrOutputsData%WriteOutputHdr, WrOutputsData%WriteOutputUnt, InitOutData%WriteOutputHdr, InitOutData%WriteOutputUnt, errStat2, errMsg2); if(Failed()) return + + ! allocate output file handling and set formats + WrOutputsData%outFmt = "ES15.8E2" + WrOutputsData%delim = TAB + WrOutputsData%AD_ver = InitOutData%Ver + allocate(WrOutputsData%unOutFile(Sim%numTurbines), STAT=ErrStat2); if(Failed0("unOutFile")) return; + WrOutputsData%unOutFile = -1 +!FIXME: number of timesteps is incorrect! + call Dvr_InitializeOutputs(Sim%numTurbines, WrOutputsData, Sim%numSteps-1, ErrStat2, ErrMsg2); if(Failed()) return + call Dvr_WriteOutputs(n_Global+1, ADI%InputTimes(INPUT_CURR), Sim, WrOutputsData, ADI%y, errStat2, errMsg2); if(Failed()) return + end subroutine SetupFileOutputs + + + !> This subroutine prints out all the variables that are passed in. Use this only + !! for debugging the interface on the Fortran side. + subroutine ShowPassedData() + character(1) :: TmpFlag + integer :: i,j + call WrScr("Interface debugging: Variables passed in through interface") + call WrScr("-----------------------------------------------------------") + call WrScr(" FileInfo") + TmpFlag="F"; if (ADinputFilePassed) TmpFlag="T" + call WrScr(" ADinputFilePassed_C "//TmpFlag ) + call WrScr(" ADinputFileString_C (ptr addr) "//trim(Num2LStr(LOC(ADinputFileString_C))) ) + call WrScr(" ADinputFileStringLength_C "//trim(Num2LStr( ADinputFileStringLength_C )) ) + TmpFlag="F"; if (IfWinputFilePassed) TmpFlag="T" + call WrScr(" IfWinputFilePassed_C "//TmpFlag ) + call WrScr(" IfWinputFileString_C (ptr addr)"//trim(Num2LStr(LOC(IfWinputFileString_C))) ) + call WrScr(" IfWinputFileStringLength_C "//trim(Num2LStr( IfWinputFileStringLength_C )) ) + call WrScr(" OutRootName "//trim(OutRootName) ) + call WrScr(" Environment variables") + call WrScr(" gravity_C "//trim(Num2LStr( gravity_C )) ) + call WrScr(" defFldDens_C "//trim(Num2LStr( defFldDens_C )) ) + call WrScr(" defKinVisc_C "//trim(Num2LStr( defKinVisc_C )) ) + call WrScr(" defSpdSound_C "//trim(Num2LStr( defSpdSound_C )) ) + call WrScr(" defPatm_C "//trim(Num2LStr( defPatm_C )) ) + call WrScr(" defPvap_C "//trim(Num2LStr( defPvap_C )) ) + call WrScr(" WtrDpth_C "//trim(Num2LStr( WtrDpth_C )) ) + call WrScr(" MSL2SWL_C "//trim(Num2LStr( MSL2SWL_C )) ) + call WrScr(" Interpolation") + call WrScr(" InterpOrder_C "//trim(Num2LStr( InterpOrder_C )) ) + call WrScr(" Time variables") + call WrScr(" DT_C "//trim(Num2LStr( DT_C )) ) + call WrScr(" TMax_C "//trim(Num2LStr( TMax_C )) ) + call WrScr(" Output variables") + call WrScr(" wrOuts_C "//trim(Num2LStr( wrOuts_C )) ) + call WrScr(" DT_Outs_C "//trim(Num2LStr( DT_Outs_C )) ) + call WrScr(" Flags") + TmpFlag="F"; if (storeHHVel) TmpFlag="T" + call WrScr(" storeHHVel "//TmpFlag ) + call WrScr(" WrVTK_in "//trim(Num2LStr( WrVTK_in )) ) + call WrScr(" WrVTK_inType "//trim(Num2LStr( WrVTK_inType )) ) + TmpFlag="F"; if (TransposeDCM_in) TmpFlag="T" + call WrScr(" TransposeDCM_in "//TmpFlag ) + call WrScr(" Init Data") + call WrNR(" Hub Position ") + call WrMatrix(HubPos_C,CU,'(3(ES15.7e2))') + call WrNR(" Hub Orientation ") + call WrMatrix(HubOri_C,CU,'(9(ES23.15e2))') + call WrNR(" Nacelle Position ") + call WrMatrix(NacPos_C,CU,'(3(ES15.7e2))') + call WrNR(" Nacelle Orientation ") + call WrMatrix(NacOri_C,CU,'(9(ES23.15e2))') + call WrScr(" NumBlades_C "//trim(Num2LStr( NumBlades_C )) ) + if (debugverbose > 1) then + call WrScr(" Root Positions") + do i=1,NumBlades_C + j=3*(i-1) + call WrMatrix(BldRootPos_C(j+1:j+3),CU,'(3(ES15.7e2))') + enddo + call WrScr(" Root Orientations") + do i=1,NumBlades_C + j=9*(i-1) + call WrMatrix(BldRootOri_C(j+1:j+9),CU,'(9(ES23.15e2))') + enddo + endif + call WrScr(" NumMeshPts_C "//trim(Num2LStr( NumMeshPts_C )) ) + if (debugverbose > 1) then + call WrScr(" Mesh Positions") + do i=1,NumMeshPts_C + j=3*(i-1) + call WrMatrix(InitMeshPos_C(j+1:j+3),CU,'(3(ES15.7e2))') + enddo + call WrScr(" Mesh Orientations") + do i=1,NumMeshPts_C + j=9*(i-1) + call WrMatrix(InitMeshOri_C(j+1:j+9),CU,'(9(ES23.15e2))') + enddo + endif + call WrScr("-----------------------------------------------------------") + end subroutine ShowPassedData + + !> This subroutine sets the interface meshes to map to the input motions to the AD + !! meshes + subroutine SetMotionLoadsInterfaceMeshes(ErrStat3,ErrMsg3) + integer(IntKi), intent( out) :: ErrStat3 !< temporary error status + character(ErrMsgLen), intent( out) :: ErrMsg3 !< temporary error message + integer(IntKi) :: iNode + real(ReKi) :: InitPos(3) + real(R8Ki) :: Orient(3,3) + !------------------------------------------------------------- + ! Set the interface meshes for motion inputs and loads output + !------------------------------------------------------------- + ! Motion mesh for blades + call MeshCreate( BldPtMotionMesh , & + IOS = COMPONENT_INPUT , & + Nnodes = NumMeshPts , & + ErrStat = ErrStat3 , & + ErrMess = ErrMsg3 , & + TranslationDisp = .TRUE., Orientation = .TRUE., & + TranslationVel = .TRUE., RotationVel = .TRUE., & + TranslationAcc = .TRUE., RotationAcc = .FALSE. ) + if (ErrStat3 >= AbortErrLev) return + + do iNode=1,NumMeshPts + ! initial position and orientation of node + InitPos = tmpBldPtMeshPos(1:3,iNode) + if (TransposeDCM) then + Orient = transpose(tmpBldPtMeshOri(1:3,1:3,iNode)) + else + Orient = tmpBldPtMeshOri(1:3,1:3,iNode) + endif + call OrientRemap(Orient) + call MeshPositionNode( BldPtMotionMesh , & + iNode , & + InitPos , & ! position + ErrStat3, ErrMsg3 , & + Orient ) ! orientation + if (ErrStat3 >= AbortErrLev) return +!FIXME: if we need to switch to line2 instead of point, do that here. + call MeshConstructElement ( BldPtMotionMesh, ELEMENT_POINT, ErrStat3, ErrMsg3, iNode ) + if (ErrStat3 >= AbortErrLev) return + enddo + + call MeshCommit ( BldPtMotionMesh, ErrStat3, ErrMsg3 ) + if (ErrStat3 >= AbortErrLev) return + BldPtMotionMesh%RemapFlag = .TRUE. + + ! For checking the mesh, uncomment this. + ! note: CU is is output unit (platform dependent). + if (debugverbose >= 4) call MeshPrintInfo( CU, BldPtMotionMesh, MeshName='BldPtMotionMesh' ) + + +! !------------------------------------------------------------- +! ! Motion mesh for nacelle -- TODO: add this mesh for nacelle load transfers +! call MeshCreate( NacMotionMesh , & +! IOS = COMPONENT_INPUT , & +! Nnodes = 1 , & +! ErrStat = ErrStat3 , & +! ErrMess = ErrMsg3 , & +! TranslationDisp = .TRUE., Orientation = .TRUE., & +! TranslationVel = .TRUE., RotationVel = .TRUE., & +! TranslationAcc = .TRUE., RotationAcc = .FALSE. ) +! if (ErrStat3 >= AbortErrLev) return +! +! InitPos = real(NacPos_C( 1:3),ReKi) +! Orient = reshape( real(NacOri_C(1:9),ReKi), (/3,3/) ) +! call OrientRemap(Orient) +! call MeshPositionNode( NacMotionMesh , & +! 1 , & +! InitPos , & ! position +! ErrStat3, ErrMsg3 , & +! Orient ) ! orientation +! if (ErrStat3 >= AbortErrLev) return +! +! call MeshConstructElement ( NacMotionMesh, ELEMENT_POINT, ErrStat3, ErrMsg3, p1=1 ) +! if (ErrStat3 >= AbortErrLev) return +! +! call MeshCommit ( NacMotionMesh, ErrStat3, ErrMsg3 ) +! if (ErrStat3 >= AbortErrLev) return +! NacMotionMesh%RemapFlag = .TRUE. +! +! ! For checking the mesh, uncomment this. +! ! note: CU is is output unit (platform dependent). +! if (debugverbose >= 4) call MeshPrintInfo( CU, NacMotionMesh, MeshName='NacMotionMesh' ) +! +! + !------------------------------------------------------------- + ! Load mesh for blades + CALL MeshCopy( SrcMesh = BldPtMotionMesh ,& + DestMesh = BldPtLoadMesh ,& + CtrlCode = MESH_SIBLING ,& + IOS = COMPONENT_OUTPUT ,& + ErrStat = ErrStat3 ,& + ErrMess = ErrMsg3 ,& + Force = .TRUE. ,& + Moment = .TRUE. ) + if (ErrStat3 >= AbortErrLev) return + BldPtLoadMesh%RemapFlag = .TRUE. + + ! Temp mesh for load transfer + CALL MeshCopy( SrcMesh = BldPtLoadMesh ,& + DestMesh = BldPtLoadMesh_tmp ,& + CtrlCode = MESH_COUSIN ,& + IOS = COMPONENT_OUTPUT ,& + ErrStat = ErrStat3 ,& + ErrMess = ErrMsg3 ,& + Force = .TRUE. ,& + Moment = .TRUE. ) + if (ErrStat3 >= AbortErrLev) return + BldPtLoadMesh_tmp%RemapFlag = .TRUE. + + + ! For checking the mesh + ! note: CU is is output unit (platform dependent). + if (debugverbose >= 4) call MeshPrintInfo( CU, BldPtLoadMesh, MeshName='BldPtLoadMesh' ) + + +! !------------------------------------------------------------- +! ! Load mesh for nacelle -- TODO: add this mesh for nacelle load transfers +! CALL MeshCopy( SrcMesh = NacMotionMesh ,& +! DestMesh = NacLoadMesh ,& +! CtrlCode = MESH_SIBLING ,& +! IOS = COMPONENT_OUTPUT ,& +! ErrStat = ErrStat3 ,& +! ErrMess = ErrMsg3 ,& +! Force = .TRUE. ,& +! Moment = .TRUE. ) +! if (ErrStat3 >= AbortErrLev) return +! NacLoadMesh%RemapFlag = .TRUE. +! +! ! For checking the mesh, uncomment this. +! ! note: CU is is output unit (platform dependent). +! if (debugverbose >= 4) call MeshPrintInfo( CU, NacLoadMesh, MeshName='NacLoadMesh' ) + + + !------------------------------------------------------------- + ! Set the mapping meshes + ! blades + allocate(Map_BldPtMotion_2_AD_Blade(Sim%WT(1)%NumBlades),Map_AD_BldLoad_P_2_BldPtLoad(Sim%WT(1)%NumBlades),STAT=ErrStat3) + if (ErrStat3 /= 0) then + ErrStat3 = ErrID_Fatal + ErrMsg3 = "Could not allocate Map_BldPtMotion_2_AD_Blade" + return + endif + do i=1,Sim%WT(1)%NumBlades + call MeshMapCreate( BldPtMotionMesh, ADI%u(1)%AD%rotors(1)%BladeMotion(i), Map_BldPtMotion_2_AD_Blade(i), ErrStat3, ErrMsg3 ) + if (ErrStat3 >= AbortErrLev) return + call MeshMapCreate( ADI%y%AD%rotors(1)%BladeLoad(i), BldPtLoadMesh, Map_AD_BldLoad_P_2_BldPtLoad(i), ErrStat3, ErrMsg3 ) + if (ErrStat3 >= AbortErrLev) return + enddo + ! nacelle -- TODO: add this mesh for nacelle load transfers +! if ( y%AD%rotors(1)%NacelleLoad%Committed ) then +! call MeshMapCreate( NacMotionMesh, ADI%u(1)%AD%rotors(1)%NacelleMotion, Map_NacPtMotion_2_AD_Nac, ErrStat3, ErrMsg3 ) +! if (ErrStat3 >= AbortErrLev) return +! call MeshMapCreate( ADI%y%AD%rotors(1)%NacelleLoad, NacLoadMesh, Map_AD_Nac_2_NacPtLoad, ErrStat3, ErrMsg3 ) +! if (ErrStat3 >= AbortErrLev) return +! endif + + end subroutine SetMotionLoadsInterfaceMeshes + + + !------------------------------------------------------------- + !> Sanity check the nodes + !! If more than one input node was passed in, but only a single AD node + !! exists, then give error that too many + !! nodes passed. + subroutine CheckNodes(ErrStat3,ErrMsg3) + integer(IntKi), intent( out) :: ErrStat3 !< temporary error status + character(ErrMsgLen), intent( out) :: ErrMsg3 !< temporary error message + ErrStat3 = ErrID_None + ErrMsg3 = "" + ! FIXME: this is a placeholder in case we think of some sanity checks to perform. + ! - some check that nodes make some sense -- might be caught in meshmapping + ! - some checks on hub/nacelle being near middle of the rotor? Not sure if that matters + end subroutine CheckNodes + +END SUBROUTINE AeroDyn_Inflow_C_Init + + +!!=============================================================================================================== +!!--------------------------------------------- AeroDyn ReInit--------------------------------------------------- +!!=============================================================================================================== +!!TODO: finish this routine so it is usable if we need re-init capability for coupling +!SUBROUTINE AeroDyn_Inflow_C_ReInit( DT_C, TMax_C, & +! ErrStat_C, ErrMsg_C) BIND (C, NAME='AeroDyn_Inflow_C_ReInit') +! implicit none +!#ifndef IMPLICIT_DLLEXPORT +!!DEC$ ATTRIBUTES DLLEXPORT :: AeroDyn_Inflow_C_ReInit +!!GCC$ ATTRIBUTES DLLEXPORT :: AeroDyn_Inflow_C_ReInit +!#endif +! +! real(c_double), intent(in ) :: DT_C !< Timestep used with AD for stepping forward from t to t+dt. Must be constant. +! real(c_double), intent(in ) :: TMax_C !< Maximum time for simulation (used to set arrays for wave kinematics) +! integer(c_int), intent( out) :: ErrStat_C !< Error status +! character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) !< Error message (C_NULL_CHAR terminated) +! +! integer(IntKi) :: ErrStat !< aggregated error message +! character(ErrMsgLen) :: ErrMsg !< aggregated error message +! integer(IntKi) :: ErrStat2 !< temporary error status from a call +! character(ErrMsgLen) :: ErrMsg2 !< temporary error message from a call +! character(*), parameter :: RoutineName = 'AeroDyn_Inflow_C_ReInit' !< for error handling +! +! ! Initialize error handling +! ErrStat = ErrID_None +! ErrMsg = "" +! +!ErrStat = ErrID_Fatal +!ErrMsg = "AeroDyn_Inflo_C_ReInit is not currently functional. Aborting." +!call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) +! +! call ADI_ReInit(ADI%p, ADI%x(STATE_CURR), ADI%xd(STATE_CURR), ADI%z(STATE_CURR), ADI%OtherState(STATE_CURR), ADI%m, Sim%dT, errStat2, errMsg2) +! if (Failed()) return +! +! call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) +! +!CONTAINS +! logical function Failed() +! CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) +! Failed = ErrStat >= AbortErrLev +! if (Failed) then +! call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) +! endif +! end function Failed +!END SUBROUTINE AeroDyn_Inflow_C_ReInit + + +!=============================================================================================================== +!--------------------------------------------- AeroDyn CalcOutput --------------------------------------------- +!=============================================================================================================== + +SUBROUTINE AeroDyn_Inflow_C_CalcOutput(Time_C, & + HubPos_C, HubOri_C, HubVel_C, HubAcc_C, & + NacPos_C, NacOri_C, NacVel_C, NacAcc_C, & + BldRootPos_C, BldRootOri_C, BldRootVel_C, BldRootAcc_C, & + NumMeshPts_C, & + MeshPos_C, MeshOri_C, MeshVel_C, MeshAcc_C, & + MeshFrc_C, OutputChannelValues_C, ErrStat_C, ErrMsg_C) BIND (C, NAME='AeroDyn_Inflow_C_CalcOutput') + implicit none +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: AeroDyn_Inflow_C_CalcOutput +!GCC$ ATTRIBUTES DLLEXPORT :: AeroDyn_Inflow_C_CalcOutput +#endif + real(c_double), intent(in ) :: Time_C + real(c_float), intent(in ) :: HubPos_C( 3 ) !< Hub position + real(c_double), intent(in ) :: HubOri_C( 9 ) !< Hub orientation + real(c_float), intent(in ) :: HubVel_C( 6 ) !< Hub velocity + real(c_float), intent(in ) :: HubAcc_C( 6 ) !< Hub acceleration + real(c_float), intent(in ) :: NacPos_C( 3 ) !< Nacelle position + real(c_double), intent(in ) :: NacOri_C( 9 ) !< Nacelle orientation + real(c_float), intent(in ) :: NacVel_C( 6 ) !< Nacelle velocity + real(c_float), intent(in ) :: NacAcc_C( 6 ) !< Nacelle acceleration + real(c_float), intent(in ) :: BldRootPos_C( 3*Sim%WT(1)%NumBlades ) !< Blade root positions + real(c_double), intent(in ) :: BldRootOri_C( 9*Sim%WT(1)%NumBlades ) !< Blade root orientations + real(c_float), intent(in ) :: BldRootVel_C( 6*Sim%WT(1)%NumBlades ) !< Blade root velocities + real(c_float), intent(in ) :: BldRootAcc_C( 6*Sim%WT(1)%NumBlades ) !< Blade root accelerations + ! Blade mesh nodes + integer(c_int), intent(in ) :: NumMeshPts_C !< Number of mesh points we are transfering motions to and output loads to + real(c_float), intent(in ) :: MeshPos_C( 3*NumMeshPts_C ) !< A 3xNumMeshPts_C array [x,y,z] + real(c_double), intent(in ) :: MeshOri_C( 9*NumMeshPts_C ) !< A 9xNumMeshPts_C array [r11,r12,r13,r21,r22,r23,r31,r32,r33] + real(c_float), intent(in ) :: MeshVel_C( 6*NumMeshPts_C ) !< A 6xNumMeshPts_C array [x,y,z] + real(c_float), intent(in ) :: MeshAcc_C( 6*NumMeshPts_C ) !< A 6xNumMeshPts_C array [x,y,z] + real(c_float), intent( out) :: MeshFrc_C( 6*NumMeshPts_C ) !< A 6xNumMeshPts_C array [Fx,Fy,Fz,Mx,My,Mz] -- forces and moments (global) + real(c_float), intent( out) :: OutputChannelValues_C(ADI%p%NumOuts) + integer(c_int), intent( out) :: ErrStat_C + character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) + + ! Local variables + real(DbKi) :: Time + integer(IntKi) :: iNode + integer(IntKi) :: ErrStat !< aggregated error status + character(ErrMsgLen) :: ErrMsg !< aggregated error message + integer(IntKi) :: ErrStat2 !< temporary error status from a call + character(ErrMsgLen) :: ErrMsg2 !< temporary error message from a call + character(*), parameter :: RoutineName = 'AeroDyn_Inflow_C_CalcOutput' !< for error handling + + ! Initialize error handling + ErrStat = ErrID_None + ErrMsg = "" + + ! Sanity check -- number of node points cannot change + if ( NumMeshPts /= int(NumMeshPts_C, IntKi) ) then + ErrStat2 = ErrID_Fatal + ErrMsg2 = "Number of node points passed in changed. This must be constant throughout simulation" + if (Failed()) return + endif + + + ! Convert the inputs from C to Fortrn + Time = REAL(Time_C,DbKi) + + ! Reshape mesh position, orientation, velocity, acceleration + tmpBldPtMeshPos(1:3,1:NumMeshPts) = reshape( real(MeshPos_C(1:3*NumMeshPts),ReKi), (/3, NumMeshPts/) ) + tmpBldPtMeshOri(1:3,1:3,1:NumMeshPts) = reshape( real(MeshOri_C(1:9*NumMeshPts),R8Ki), (/3,3,NumMeshPts/) ) + tmpBldPtMeshVel(1:6,1:NumMeshPts) = reshape( real(MeshVel_C(1:6*NumMeshPts),ReKi), (/6, NumMeshPts/) ) + tmpBldPtMeshAcc(1:6,1:NumMeshPts) = reshape( real(MeshAcc_C(1:6*NumMeshPts),ReKi), (/6, NumMeshPts/) ) + + + ! Transfer motions to input meshes + call Set_MotionMesh( ErrStat2, ErrMsg2 ); if (Failed()) return + call AD_SetInputMotion( ADI%u(1), & + HubPos_C, HubOri_C, HubVel_C, HubAcc_C, & + NacPos_C, NacOri_C, NacVel_C, NacAcc_C, & + BldRootPos_C, BldRootOri_C, BldRootVel_C, BldRootAcc_C, & + ErrStat2, ErrMsg2 ) ! transfer input motion mesh to u(1) meshes + if (Failed()) return + + ! call IfW and set inputs for AD + call ADI_ADIW_Solve(Time, ADI%p, ADI%u(1)%AD, ADI%OtherState(STATE_CURR)%AD, ADI%m%IW%u, ADI%m%IW, .false., ErrStat2, ErrMsg2) + if (Failed()) return + + ! Call the main subroutine ADI_CalcOutput to get the resulting forces and moments at time T + CALL ADI_CalcOutput( Time, ADI%u(1), ADI%p, ADI%x(STATE_CURR), ADI%xd(STATE_CURR), ADI%z(STATE_CURR), ADI%OtherState(STATE_CURR), ADI%y, ADI%m, ErrStat2, ErrMsg2 ) + if (Failed()) return + + ! Transfer resulting load meshes to intermediate mesh + call AD_TransferLoads( ADI%u(1), ADI%y, ErrStat2, ErrMsg2 ) + if (Failed()) return + + ! Set output force/moment array + call Set_OutputLoadArray( ) + MeshFrc_C(1:6*NumMeshPts) = reshape( real(tmpBldPtMeshFrc(1:6,1:NumMeshPts), c_float), (/6*NumMeshPts/) ) + + ! Get the output channel info out of y + OutputChannelValues_C = REAL(ADI%y%WriteOutput, C_FLOAT) + + !------------------------------------------------------- + ! write outputs + !------------------------------------------------------- + ! Write VTK if requested (animation=2) + if (WrOutputsData%WrVTK > 1_IntKi) call WrVTK_Meshes(ADI%u(1)%AD%rotors(:),(/0.0_SiKi,0.0_SiKi,0.0_SiKi/),ErrStat2,ErrMsg2) + + if (WrOutputsData%fileFmt > idFmtNone) then +!FIXME: need some way to overwrite the correction timesteps (for text file)! + call Dvr_WriteOutputs(n_Global+1, ADI%InputTimes(INPUT_CURR), Sim, WrOutputsData, ADI%y, errStat2, errMsg2); if(Failed()) return + endif + + ! Set error status + call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) + +CONTAINS + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + if (Failed) call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) + end function Failed +END SUBROUTINE AeroDyn_Inflow_C_CalcOutput + +!=============================================================================================================== +!--------------------------------------------- AeroDyn UpdateStates ------------------------------------------- +!=============================================================================================================== +!> This routine updates the states from Time_C to TimeNext_C. It is assumed that the inputs are given for +!! TimeNext_C, but will be checked against the previous timestep values. +!! Since we don't really know if we are doing correction steps or not, we will track the previous state and +!! reset to those if we are repeating a timestep (normally this would be handled by the OF glue code, but since +!! the states are not passed across the interface, we must handle them here). +SUBROUTINE AeroDyn_Inflow_C_UpdateStates( Time_C, TimeNext_C, & + HubPos_C, HubOri_C, HubVel_C, HubAcc_C, & + NacPos_C, NacOri_C, NacVel_C, NacAcc_C, & + BldRootPos_C, BldRootOri_C, BldRootVel_C, BldRootAcc_C, & + NumMeshPts_C, & + MeshPos_C, MeshOri_C, MeshVel_C, MeshAcc_C, & + ErrStat_C, ErrMsg_C) BIND (C, NAME='AeroDyn_Inflow_C_UpdateStates') + implicit none +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: AeroDyn_Inflow_C_UpdateStates +!GCC$ ATTRIBUTES DLLEXPORT :: AeroDyn_Inflow_C_UpdateStates +#endif + real(c_double), intent(in ) :: Time_C + real(c_double), intent(in ) :: TimeNext_C + real(c_float), intent(in ) :: HubPos_C( 3 ) !< Hub position + real(c_double), intent(in ) :: HubOri_C( 9 ) !< Hub orientation + real(c_float), intent(in ) :: HubVel_C( 6 ) !< Hub velocity + real(c_float), intent(in ) :: HubAcc_C( 6 ) !< Hub acceleration + real(c_float), intent(in ) :: NacPos_C( 3 ) !< Nacelle position + real(c_double), intent(in ) :: NacOri_C( 9 ) !< Nacelle orientation + real(c_float), intent(in ) :: NacVel_C( 6 ) !< Nacelle velocity + real(c_float), intent(in ) :: NacAcc_C( 6 ) !< Nacelle acceleration + real(c_float), intent(in ) :: BldRootPos_C( 3*Sim%WT(1)%NumBlades ) !< Blade root positions + real(c_double), intent(in ) :: BldRootOri_C( 9*Sim%WT(1)%NumBlades ) !< Blade root orientations + real(c_float), intent(in ) :: BldRootVel_C( 6*Sim%WT(1)%NumBlades ) !< Blade root velocities + real(c_float), intent(in ) :: BldRootAcc_C( 6*Sim%WT(1)%NumBlades ) !< Blade root accelerations + ! Blade mesh nodes + integer(c_int), intent(in ) :: NumMeshPts_C !< Number of mesh points we are transfering motions to and output loads to + real(c_float), intent(in ) :: MeshPos_C( 3*NumMeshPts_C ) !< A 3xNumMeshPts_C array [x,y,z] + real(c_double), intent(in ) :: MeshOri_C( 9*NumMeshPts_C ) !< A 9xNumMeshPts_C array [r11,r12,r13,r21,r22,r23,r31,r32,r33] + real(c_float), intent(in ) :: MeshVel_C( 6*NumMeshPts_C ) !< A 6xNumMeshPts_C array [x,y,z] + real(c_float), intent(in ) :: MeshAcc_C( 6*NumMeshPts_C ) !< A 6xNumMeshPts_C array [x,y,z] + integer(c_int), intent( out) :: ErrStat_C + character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) + + ! Local variables + logical :: CorrectionStep ! if we are repeating a timestep in UpdateStates, don't update the inputs array + integer(IntKi) :: iNode + integer(IntKi) :: ErrStat !< aggregated error status + character(ErrMsgLen) :: ErrMsg !< aggregated error message + integer(IntKi) :: ErrStat2 !< temporary error status from a call + character(ErrMsgLen) :: ErrMsg2 !< temporary error message from a call + character(*), parameter :: RoutineName = 'AeroDyn_Inflow_C_UpdateStates' !< for error handling + + ! Initialize error handling + ErrStat = ErrID_None + ErrMsg = "" + CorrectionStep = .false. + + ! Sanity check -- number of node points cannot change + if ( NumMeshPts /= int(NumMeshPts_C, IntKi) ) then + ErrStat2 = ErrID_Fatal + ErrMsg2 = "Number of node points passed in changed. This must be constant throughout simulation" + if (Failed()) return + endif + + + !------------------------------------------------------- + ! Check the time for current timestep and next timestep + !------------------------------------------------------- + ! These inputs are used in the time stepping algorithm within AD_UpdateStates + ! For quadratic interpolation (InterpOrder==2), 3 timesteps are used. For + ! linear (InterOrder==1), 2 timesteps (the AD code can handle either). + ! u(1) inputs at t + dt ! Next timestep + ! u(2) inputs at t ! This timestep + ! u(3) inputs at t - dt ! previous timestep (quadratic only) + ! + ! NOTE: Within AD, the Radiation calculations can be done at an integer multiple of the + ! timestep. This is checked at each UpdateStates call. However, if we compile + ! in double precision, the values of Time_C and TimeNext_C are in double precison, + ! but InputTimes is in DbKi (which is promoted quad precision when compiling in + ! double precision) and the check may fail. So we are going to set the times we + ! we pass over to UpdateStates using the global timestep and the stored DbKi value + ! for the timestep rather than the lower precision (when compiled double) time + ! values passed in. It is a bit of a clumsy workaround for this precision loss, + ! but should not affect any results. + + ! Check if we are repeating an UpdateStates call (for example in a predictor/corrector loop) + if ( EqualRealNos( real(Time_C,DbKi), InputTimePrev ) ) then + CorrectionStep = .true. + else ! Setup time input times array + InputTimePrev = real(Time_C,DbKi) ! Store for check next time + if (InterpOrder>1) then ! quadratic, so keep the old time + ADI%InputTimes(INPUT_LAST) = ( n_Global - 1 ) * Sim%dT ! u(3) at T-dT + endif + ADI%InputTimes(INPUT_CURR) = n_Global * Sim%dT ! u(2) at T + ADI%InputTimes(INPUT_PRED) = ( n_Global + 1 ) * Sim%dT ! u(1) at T+dT + n_Global = n_Global + 1_IntKi ! increment counter to T+dT + endif + + + if (CorrectionStep) then + ! Step back to previous state because we are doing a correction step + ! -- repeating the T -> T+dt update with new inputs at T+dt + ! -- the STATE_CURR contains states at T+dt from the previous call, so revert those + CALL ADI_CopyContState (ADI%x( STATE_LAST), ADI%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyDiscState (ADI%xd( STATE_LAST), ADI%xd( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyConstrState (ADI%z( STATE_LAST), ADI%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyOtherState (ADI%OtherState(STATE_LAST), ADI%OtherState(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + else + ! Cycle inputs back one timestep since we are moving forward in time. + if (InterpOrder>1) then ! quadratic, so keep the old time + call ADI_CopyInput( ADI%u(INPUT_CURR), ADI%u(INPUT_LAST), MESH_UPDATECOPY, ErrStat2, ErrMsg2); if (Failed()) return + endif + ! Move inputs from previous t+dt (now t) to t + call ADI_CopyInput( ADI%u(INPUT_PRED), ADI%u(INPUT_CURR), MESH_UPDATECOPY, ErrStat2, ErrMsg2); if (Failed()) return + endif + + !------------------------------------------------------- + ! Set inputs for time T+dt -- u(INPUT_PRED) + !------------------------------------------------------- + ! Reshape mesh position, orientation, velocity, acceleration + tmpBldPtMeshPos(1:3,1:NumMeshPts) = reshape( real(MeshPos_C(1:3*NumMeshPts),ReKi), (/3, NumMeshPts/) ) + tmpBldPtMeshOri(1:3,1:3,1:NumMeshPts) = reshape( real(MeshOri_C(1:9*NumMeshPts),R8Ki), (/3,3,NumMeshPts/) ) + tmpBldPtMeshVel(1:6,1:NumMeshPts) = reshape( real(MeshVel_C(1:6*NumMeshPts),ReKi), (/6, NumMeshPts/) ) + tmpBldPtMeshAcc(1:6,1:NumMeshPts) = reshape( real(MeshAcc_C(1:6*NumMeshPts),ReKi), (/6, NumMeshPts/) ) + + ! Transfer motions to input meshes + call Set_MotionMesh( ErrStat2, ErrMsg2 ); if (Failed()) return + call AD_SetInputMotion( ADI%u(INPUT_PRED), & + HubPos_C, HubOri_C, HubVel_C, HubAcc_C, & + NacPos_C, NacOri_C, NacVel_C, NacAcc_C, & + BldRootPos_C, BldRootOri_C, BldRootVel_C, BldRootAcc_C, & + ErrStat2, ErrMsg2 ) ! transfer input motion mesh to u(1) meshes + if (Failed()) return + + + ! Set copy the current state over to the predicted state for sending to UpdateStates + ! -- The STATE_PREDicted will get updated in the call. + ! -- The UpdateStates routine expects this to contain states at T at the start of the call (history not passed in) + CALL ADI_CopyContState (ADI%x( STATE_CURR), ADI%x( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyDiscState (ADI%xd( STATE_CURR), ADI%xd( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyConstrState (ADI%z( STATE_CURR), ADI%z( STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyOtherState (ADI%OtherState(STATE_CURR), ADI%OtherState(STATE_PRED), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + + + ! Call the main subroutine ADI_UpdateStates to get the velocities + CALL ADI_UpdateStates( ADI%InputTimes(INPUT_CURR), n_Global, ADI%u, ADI%InputTimes, ADI%p, ADI%x(STATE_PRED), ADI%xd(STATE_PRED), ADI%z(STATE_PRED), ADI%OtherState(STATE_PRED), ADI%m, ErrStat2, ErrMsg2 ) + if (Failed()) return + + + !------------------------------------------------------- + ! cycle the states + !------------------------------------------------------- + ! move current state at T to previous state at T-dt + ! -- STATE_LAST now contains info at time T + ! -- this allows repeating the T --> T+dt update + CALL ADI_CopyContState (ADI%x( STATE_CURR), ADI%x( STATE_LAST), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyDiscState (ADI%xd( STATE_CURR), ADI%xd( STATE_LAST), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyConstrState (ADI%z( STATE_CURR), ADI%z( STATE_LAST), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyOtherState (ADI%OtherState(STATE_CURR), ADI%OtherState(STATE_LAST), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + ! Update the predicted state as the new current state + ! -- we have now advanced from T to T+dt. This allows calling with CalcOuput to get the outputs at T+dt + CALL ADI_CopyContState (ADI%x( STATE_PRED), ADI%x( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyDiscState (ADI%xd( STATE_PRED), ADI%xd( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyConstrState (ADI%z( STATE_PRED), ADI%z( STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + CALL ADI_CopyOtherState (ADI%OtherState(STATE_PRED), ADI%OtherState(STATE_CURR), MESH_UPDATECOPY, Errstat2, ErrMsg2); if (Failed()) return + + + call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) + +contains + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + if (Failed) call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) + end function Failed +END SUBROUTINE AeroDyn_Inflow_C_UpdateStates + +!=============================================================================================================== +!--------------------------------------------------- AeroDyn End----------------------------------------------- +!=============================================================================================================== +! NOTE: the error handling in this routine is slightly different than the other routines + +SUBROUTINE AeroDyn_Inflow_C_End(ErrStat_C,ErrMsg_C) BIND (C, NAME='AeroDyn_Inflow_C_End') + implicit none +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: AeroDyn_Inflow_C_End +!GCC$ ATTRIBUTES DLLEXPORT :: AeroDyn_Inflow_C_End +#endif + integer(c_int), intent( out) :: ErrStat_C + character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) + + ! Local variables + integer(IntKi) :: i !< generic loop counter + character(10) :: sWT !< string for turbine + integer(IntKi) :: iWT !< current wind turbine + integer :: ErrStat !< aggregated error status + character(ErrMsgLen) :: ErrMsg !< aggregated error message + integer :: ErrStat2 !< temporary error status from a call + character(ErrMsgLen) :: ErrMsg2 !< temporary error message from a call + character(*), parameter :: RoutineName = 'AeroDyn_Inflow_C_End' !< for error handling + + ! Initialize error handling + ErrStat = ErrID_None + ErrMsg = "" + + ! Finalize output file + if (WrOutputsData%fileFmt > idFmtNone .and. allocated(WrOutputsData%unOutFile)) then + ! Close the output file + if (WrOutputsData%fileFmt==idFmtBoth .or. WrOutputsData%fileFmt == idFmtAscii) then + do iWT=1,Sim%numTurbines + if (WrOutputsData%unOutFile(iWT) > 0) close(WrOutputsData%unOutFile(iWT)) + enddo + endif + if (WrOutputsData%fileFmt==idFmtBoth .or. WrOutputsData%fileFmt == idFmtBinary) then + do iWT=1,Sim%numTurbines + if (Sim%numTurbines >1) then + sWT = '.T'//trim(num2lstr(iWT)) + else + sWT = '' + endif + call WrBinFAST(trim(WrOutputsData%Root)//trim(sWT)//'.outb', FileFmtID_ChanLen_In, 'AeroDyn_Inflow_C_Library', WrOutputsData%WriteOutputHdr, WrOutputsData%WriteOutputUnt, (/0.0_DbKi, Sim%dT/), WrOutputsData%storage(:,:,iWT), errStat2, errMsg2) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) + enddo + endif + end if + + ! clear out any globably allocated helper arrays + if (allocated(tmpBldPtMeshPos)) deallocate(tmpBldPtMeshPos) + if (allocated(tmpBldPtMeshOri)) deallocate(tmpBldPtMeshOri) + if (allocated(tmpBldPtMeshVel)) deallocate(tmpBldPtMeshVel) + if (allocated(tmpBldPtMeshAcc)) deallocate(tmpBldPtMeshAcc) + if (allocated(tmpBldPtMeshFrc)) deallocate(tmpBldPtMeshFrc) + + + ! Call the main subroutine ADI_End + ! If u is not allocated, then we didn't get far at all in initialization, + ! or AD_C_End got called before Init. We don't want a segfault, so check + ! for allocation. + if (allocated(ADI%u)) then + call ADI_End( ADI%u(:), ADI%p, ADI%x(STATE_CURR), ADI%xd(STATE_CURR), ADI%z(STATE_CURR), ADI%OtherState(STATE_CURR), ADI%y, ADI%m, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + endif + + ! NOTE: ADI_End only takes 1 instance of u, not the array. So extra + ! logic is required here (this isn't necessary in the fortran driver + ! or in openfast, but may be when this code is called from C, Python, + ! or some other code using the c-bindings. + if (allocated(ADI%u)) then + do i=2,size(ADI%u) + call ADI_DestroyInput( ADI%u(i), ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + enddo + if (allocated(ADI%u)) deallocate(ADI%u) + endif + + ! Destroy any other copies of states (rerun on (STATE_CURR) is ok) + call ADI_DestroyContState( ADI%x( STATE_LAST), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call ADI_DestroyContState( ADI%x( STATE_CURR), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call ADI_DestroyContState( ADI%x( STATE_PRED), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call ADI_DestroyDiscState( ADI%xd( STATE_LAST), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call ADI_DestroyDiscState( ADI%xd( STATE_CURR), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call ADI_DestroyDiscState( ADI%xd( STATE_PRED), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call ADI_DestroyConstrState( ADI%z( STATE_LAST), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call ADI_DestroyConstrState( ADI%z( STATE_CURR), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call ADI_DestroyConstrState( ADI%z( STATE_PRED), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call ADI_DestroyOtherState( ADI%OtherState(STATE_LAST), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call ADI_DestroyOtherState( ADI%OtherState(STATE_CURR), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call ADI_DestroyOtherState( ADI%OtherState(STATE_PRED), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! if deallocate other items now + !if (allocated(InputTimes)) deallocate(InputTimes) + + ! Clear out mesh related data storage + call ClearMesh() + + call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) +CONTAINS + !> Don't leave junk in memory. So destroy meshes and mappings. + subroutine ClearMesh() + ! Blade + call MeshDestroy( BldPtMotionMesh, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MeshDestroy( BldPtLoadMesh, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! Destroy mesh mappings + if (allocated(Map_BldPtMotion_2_AD_Blade)) then + do i=1,Sim%WT(1)%NumBlades + call NWTC_Library_Destroymeshmaptype( Map_BldPtMotion_2_AD_Blade(i), ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + enddo + deallocate(Map_BldPtMotion_2_AD_Blade) + endif + if (allocated(Map_AD_BldLoad_P_2_BldPtLoad)) then + do i=1,Sim%WT(1)%NumBlades + call NWTC_Library_Destroymeshmaptype( Map_AD_BldLoad_P_2_BldPtLoad(i), ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + enddo + deallocate(Map_AD_BldLoad_P_2_BldPtLoad) + endif + ! Nacelle -- TODO: add this mesh for nacelle load transfers +! call MeshDestroy( NacMotionMesh, ErrStat2, ErrMsg2 ) +! call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) +! call MeshDestroy( NacLoadMesh, ErrStat2, ErrMsg2 ) +! call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) +! call NWTC_Library_Destroymeshmaptype( Map_AD_Nac_2_NacPtLoad , ErrStat2, ErrMsg2 ) +! call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) +! call NWTC_Library_Destroymeshmaptype( Map_NacPtMotion_2_AD_Nac , ErrStat2, ErrMsg2 ) +! call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + end subroutine ClearMesh +END SUBROUTINE AeroDyn_Inflow_C_End + + +!> This routine is operating on module level data. Error handling here in case checks added +subroutine Set_MotionMesh(ErrStat3, ErrMsg3) + integer(IntKi), intent( out) :: ErrStat3 + character(ErrMsgLen), intent( out) :: ErrMsg3 + integer(IntKi) :: iNode + ErrStat3 = 0_IntKi + ErrMsg3 = '' + ! Set mesh corresponding to input motions + do iNode=1,NumMeshPts + BldPtMotionMesh%TranslationDisp(1:3,iNode) = tmpBldPtMeshPos(1:3,iNode) - real(BldPtMotionMesh%Position(1:3,iNode), R8Ki) + BldPtMotionMesh%Orientation(1:3,1:3,iNode) = tmpBldPtMeshOri(1:3,1:3,iNode) + BldPtMotionMesh%TranslationVel( 1:3,iNode) = tmpBldPtMeshVel(1:3,iNode) + BldPtMotionMesh%RotationVel( 1:3,iNode) = tmpBldPtMeshVel(4:6,iNode) + BldPtMotionMesh%TranslationAcc( 1:3,iNode) = tmpBldPtMeshAcc(1:3,iNode) + !BldPtMotionMesh%RotationAcc( 1:3,iNode) = tmpBldPtMeshAcc(4:6,iNode) ! Rotational acc not included + call OrientRemap(BldPtMotionMesh%Orientation(1:3,1:3,iNode)) + if (TransposeDCM) then + BldPtMotionMesh%Orientation(1:3,1:3,iNode) = transpose(BldPtMotionMesh%Orientation(1:3,1:3,iNode)) + endif + enddo +end subroutine Set_MotionMesh + +!> Map the motion of the intermediate input mesh over to the input meshes +!! This routine is operating on module level data, hence few inputs +subroutine AD_SetInputMotion( u_local, & + HubPos_C, HubOri_C, HubVel_C, HubAcc_C, & + NacPos_C, NacOri_C, NacVel_C, NacAcc_C, & + BldRootPos_C, BldRootOri_C, BldRootVel_C, BldRootAcc_C, & + ErrStat, ErrMsg ) + type(ADI_InputType), intent(inout) :: u_local ! Only one input (probably at T) + real(c_float), intent(in ) :: HubPos_C( 3 ) !< Hub position + real(c_double), intent(in ) :: HubOri_C( 9 ) !< Hub orientation + real(c_float), intent(in ) :: HubVel_C( 6 ) !< Hub velocity + real(c_float), intent(in ) :: HubAcc_C( 6 ) !< Hub acceleration + real(c_float), intent(in ) :: NacPos_C( 3 ) !< Nacelle position + real(c_double), intent(in ) :: NacOri_C( 9 ) !< Nacelle orientation + real(c_float), intent(in ) :: NacVel_C( 6 ) !< Nacelle velocity + real(c_float), intent(in ) :: NacAcc_C( 6 ) !< Nacelle acceleration + real(c_float), intent(in ) :: BldRootPos_C( 3*Sim%WT(1)%NumBlades ) !< Blade root positions + real(c_double), intent(in ) :: BldRootOri_C( 9*Sim%WT(1)%NumBlades ) !< Blade root orientations + real(c_float), intent(in ) :: BldRootVel_C( 6*Sim%WT(1)%NumBlades ) !< Blade root velocities + real(c_float), intent(in ) :: BldRootAcc_C( 6*Sim%WT(1)%NumBlades ) !< Blade root accelerations + integer(IntKi), intent( out) :: ErrStat + character(ErrMsgLen), intent( out) :: ErrMsg + integer(IntKi) :: i + ErrStat = 0_IntKi + ErrMsg = '' + ! Hub -- NOTE: RotationalAcc not present in the mesh + if ( u_local%AD%rotors(1)%HubMotion%Committed ) then + u_local%AD%rotors(1)%HubMotion%TranslationDisp(1:3,1) = real(HubPos_C(1:3),R8Ki) - real(u_local%AD%rotors(1)%HubMotion%Position(1:3,1), R8Ki) + u_local%AD%rotors(1)%HubMotion%Orientation(1:3,1:3,1) = reshape( real(HubOri_C(1:9),R8Ki), (/3,3/) ) + u_local%AD%rotors(1)%HubMotion%TranslationVel(1:3,1) = real(HubVel_C(1:3), ReKi) + u_local%AD%rotors(1)%HubMotion%RotationVel(1:3,1) = real(HubVel_C(4:6), ReKi) + u_local%AD%rotors(1)%HubMotion%TranslationAcc(1:3,1) = real(HubAcc_C(1:3), ReKi) + call OrientRemap(u_local%AD%rotors(1)%HubMotion%Orientation(1:3,1:3,1)) + if (TransposeDCM) then + u_local%AD%rotors(1)%HubMotion%Orientation(1:3,1:3,1) = transpose(u_local%AD%rotors(1)%HubMotion%Orientation(1:3,1:3,1)) + endif + endif + ! Nacelle -- NOTE: RotationalVel and RotationalAcc not present in the mesh + if ( u_local%AD%rotors(1)%NacelleMotion%Committed ) then + u_local%AD%rotors(1)%NacelleMotion%TranslationDisp(1:3,1) = real(NacPos_C(1:3),R8Ki) - real(u_local%AD%rotors(1)%NacelleMotion%Position(1:3,1), R8Ki) + u_local%AD%rotors(1)%NacelleMotion%Orientation(1:3,1:3,1) = reshape( real(NacOri_C(1:9),R8Ki), (/3,3/) ) + u_local%AD%rotors(1)%NacelleMotion%TranslationVel(1:3,1) = real(NacVel_C(1:3), ReKi) + u_local%AD%rotors(1)%NacelleMotion%TranslationAcc(1:3,1) = real(NacAcc_C(1:3), ReKi) + call OrientRemap(u_local%AD%rotors(1)%NacelleMotion%Orientation(1:3,1:3,1)) + if (TransposeDCM) then + u_local%AD%rotors(1)%NacelleMotion%Orientation(1:3,1:3,1) = transpose(u_local%AD%rotors(1)%NacelleMotion%Orientation(1:3,1:3,1)) + endif + endif + ! Blade root + do i=0,Sim%WT(1)%numBlades-1 + if ( u_local%AD%rotors(1)%BladeRootMotion(i+1)%Committed ) then + u_local%AD%rotors(1)%BladeRootMotion(i+1)%TranslationDisp(1:3,1) = real(BldRootPos_C(3*i+1:3*i+3),R8Ki) - real(u_local%AD%rotors(1)%BladeRootMotion(i+1)%Position(1:3,1), R8Ki) + u_local%AD%rotors(1)%BladeRootMotion(i+1)%Orientation(1:3,1:3,1) = reshape( real(BldRootOri_C(9*i+1:9*i+9),R8Ki), (/3,3/) ) + u_local%AD%rotors(1)%BladeRootMotion(i+1)%TranslationVel(1:3,1) = real(BldRootVel_C(6*i+1:6*i+3), ReKi) + u_local%AD%rotors(1)%BladeRootMotion(i+1)%RotationVel(1:3,1) = real(BldRootVel_C(6*i+4:6*i+6), ReKi) + u_local%AD%rotors(1)%BladeRootMotion(i+1)%TranslationAcc(1:3,1) = real(BldRootAcc_C(6*i+1:6*i+3), ReKi) + u_local%AD%rotors(1)%BladeRootMotion(i+1)%RotationAcc(1:3,1) = real(BldRootAcc_C(6*i+4:6*i+6), ReKi) + call OrientRemap(u_local%AD%rotors(1)%BladeRootMotion(i+1)%Orientation(1:3,1:3,1)) + if (TransposeDCM) then + u_local%AD%rotors(1)%BladeRootMotion(i+1)%Orientation(1:3,1:3,1) = transpose(u_local%AD%rotors(1)%BladeRootMotion(i+1)%Orientation(1:3,1:3,1)) + endif + endif + enddo + + ! Blade mesh + do i=1,Sim%WT(1)%numBlades + if ( u_local%AD%rotors(1)%BladeMotion(i)%Committed ) then + call Transfer_Point_to_Line2( BldPtMotionMesh, u_local%AD%rotors(1)%BladeMotion(i), Map_BldPtMotion_2_AD_Blade(i), ErrStat, ErrMsg ) + if (ErrStat >= AbortErrLev) return + endif + enddo +end subroutine AD_SetInputMotion + +!> Map the loads of the output mesh to the intermediate output mesh. +!! This routine is operating on module level data, hence few inputs +subroutine AD_TransferLoads( u_local, y_local, ErrStat3, ErrMsg3 ) + type(ADI_InputType), intent(in ) :: u_local ! Only one input (probably at T) + type(ADI_OutputType), intent(in ) :: y_local ! Only one input (probably at T) + integer(IntKi), intent( out) :: ErrStat3 + character(ErrMsgLen), intent( out) :: ErrMsg3 + integer(IntKi) :: i + BldPtLoadMesh%Force = 0.0_ReKi + BldPtLoadMesh%Moment = 0.0_ReKi + do i=1,Sim%WT(1)%NumBlades + if ( y_local%AD%rotors(1)%BladeLoad(i)%Committed ) then + if (debugverbose > 4) call MeshPrintInfo( CU, y_local%AD%rotors(1)%BladeLoad(i), MeshName='AD%rotors('//trim(Num2LStr(1))//')%BladeLoad('//trim(Num2LStr(i))//')' ) + call Transfer_Line2_to_Point( ADI%y%AD%rotors(1)%BladeLoad(i), BldPtLoadMesh_tmp, Map_AD_BldLoad_P_2_BldPtLoad(i), & + ErrStat3, ErrMsg3, u_local%AD%rotors(1)%BladeMotion(i), BldPtMotionMesh ) + if (ErrStat3 >= AbortErrLev) return + BldPtLoadMesh%Force = BldPtLoadMesh%Force + BldPtLoadMesh_tmp%Force + BldPtLoadMesh%Moment = BldPtLoadMesh%Moment + BldPtLoadMesh_tmp%Moment + endif + enddo + if (debugverbose > 4) call MeshPrintInfo( CU, BldPtLoadMesh, MeshName='BldPtLoadMesh' ) +end subroutine AD_TransferLoads + +!> Transfer the loads from the load mesh to the temporary array for output +!! This routine is operating on module level data, hence few inputs +subroutine Set_OutputLoadArray() + integer(IntKi) :: iNode + ! Set mesh corresponding to input motions + do iNode=1,NumMeshPts + tmpBldPtMeshFrc(1:3,iNode) = BldPtLoadMesh%Force (1:3,iNode) + tmpBldPtMeshFrc(4:6,iNode) = BldPtLoadMesh%Moment(1:3,iNode) + enddo +end subroutine Set_OutputLoadArray + +!> take DCM passed in, do Euler angle extract, then Euler angle construct back to DCM. Idea here is we can account +!! for minor accuracy issues in the passed DCM +subroutine OrientRemap(DCM) + real(R8Ki), intent(inout) :: DCM(3,3) + real(R8Ki) :: theta(3) +! real(R8Ki) :: logMap(3) +! integer(IntKi) :: TmpErrStat ! DCM_logMapD requires this output, but doesn't use it at all +! character(ErrMsgLen) :: TmpErrMsg ! DCM_logMapD requires this output, but doesn't use it at all +!write(200,*) reshape(DCM,(/9/)) + theta = EulerExtract(DCM) + DCM = EulerConstruct(theta) +! call DCM_logMap(DCM,logMap,TmpErrStat,TmpErrMsg) +! DCM = DCM_Exp(logMap) +!write(201,*) reshape(DCM,(/9/)) +end subroutine OrientRemap + +!> Write VTK reference meshes and setup directory if needed. +!! NOTE: it is assumed that only an fatal error will be returned in the subroutines contained here +subroutine WrVTK_refMeshes(rot_u, RefPoint, ErrStat, ErrMsg) + type(RotInputType), intent(in ) :: rot_u(:) !< pointer to rotor input (for easier to read code) + real(SiKi), intent(in ) :: RefPoint(3) + integer(IntKi), intent( out) :: ErrStat !< error status + character(ErrMsgLen), intent( out) :: ErrMsg !< error message + integer(IntKi) :: nBlades + integer(IntKi) :: iWT, nWT, k + character(*), parameter :: RoutineName = 'WrVTK_refMeshes' !< for error handling + integer(IntKi) :: ErrStat2 !< temporary error status + character(ErrMsgLen) :: ErrMsg2 !< temporary error message + character(10) :: sWT + + ErrStat = 0_IntKi + ErrMsg = '' + + nWT = size(Sim%WT) + do iWT = 1, nWT + ! Turbine identifier + if (nWT==1) then + sWT = '' + else + sWT = '.T'//trim(num2lstr(iWT)) + endif + + select case (WrOutputsData%WrVTK_Type) + case (1) ! surfaces -- don't write any surface references + call WrVTK_PointsRef( ErrStat2,ErrMsg2); if (Failed()) return; + case (2) ! lines + call WrVTK_PointsRef( ErrStat2,ErrMsg2); if (Failed()) return; + call WrVTK_LinesRef( ErrStat2,ErrMsg2); if (Failed()) return; + case (3) ! both + call WrVTK_PointsRef( ErrStat2,ErrMsg2); if (Failed()) return; + call WrVTK_LinesRef( ErrStat2,ErrMsg2); if (Failed()) return; + end select + enddo +contains + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + end function Failed + + !> meshes rendered at all times (points, or lines for fvw) + subroutine WrVTK_PointsRef(ErrStat3,ErrMsg3) + integer(IntKi), intent( out) :: ErrStat3 !< error status + character(ErrMsgLen), intent( out) :: ErrMsg3 !< error message + ErrStat3 = 0_IntKi + ErrMsg3 = '' + + ! Blade point motion (structural mesh from driver) + call MeshWrVTKreference(RefPoint, BldPtMotionMesh, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.BldPtMotionMesh', ErrStat3, ErrMsg3) + if (ErrStat3 >= AbortErrLev) return + + ! Blade root motion (point only) + if (allocated(rot_u(iWT)%BladeRootMotion)) then + do k=1,Sim%WT(1)%NumBlades + if (rot_u(iWT)%BladeRootMotion(k)%Committed) then + call MeshWrVTKreference(RefPoint, rot_u(iWT)%BladeRootMotion(k), trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.BladeRootMotion'//trim(num2lstr(k)), ErrStat3, ErrMsg3 ) + if (ErrStat3 >= AbortErrLev) return + endif + enddo + endif + + ! Nacelle (structural point input + if ( rot_u(iWT)%NacelleMotion%Committed ) call MeshWrVTKreference(RefPoint, rot_u(iWT)%NacelleMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.NacelleMotion', ErrStat3, ErrMsg3) + if (ErrStat3 >= AbortErrLev) return + end subroutine WrVTK_PointsRef + + !> meshes rendered with lines only + subroutine WrVTK_LinesRef(ErrStat3,ErrMsg3) + integer(IntKi), intent( out) :: ErrStat3 !< error status + character(ErrMsgLen), intent( out) :: ErrMsg3 !< error message + ErrStat3 = 0_IntKi + ErrMsg3 = '' + + ! Tower + if (rot_u(iWT)%TowerMotion%Committed) call MeshWrVTKreference(RefPoint, rot_u(iWT)%TowerMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Tower', ErrStat3, ErrMsg3 ) + if (ErrStat3 >= AbortErrLev) return + + ! Nacelle meshes + if (rot_u(iWT)%NacelleMotion%Committed) call MeshWrVTKreference(RefPoint, rot_u(iWT)%NacelleMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Nacelle', ErrStat3, ErrMsg3 ) + if (ErrStat3 >= AbortErrLev) return + + ! Hub + if (rot_u(iWT)%HubMotion%Committed) call MeshWrVTKreference(RefPoint, rot_u(iWT)%HubMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Hub', ErrStat3, ErrMsg3 ) + if (ErrStat3 >= AbortErrLev) return + + ! Blades + if (allocated(rot_u(iWT)%BladeMotion)) then + do k=1,Sim%WT(1)%NumBlades + if (rot_u(iWT)%BladeMotion(k)%Committed) then + call MeshWrVTKreference(RefPoint, rot_u(iWT)%BladeMotion(k), trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Blade'//trim(num2lstr(k)), ErrStat3, ErrMsg3 ) + if (ErrStat3 >= AbortErrLev) return + endif + enddo + endif + end subroutine WrVTK_LinesRef +end subroutine WrVTK_refMeshes + +!> Write VTK meshes +!! NOTE: it is assumed that only an fatal error will be returned in the subroutines contained here +subroutine WrVTK_Meshes(rot_u, RefPoint, ErrStat, ErrMsg) + type(RotInputType), intent(in ) :: rot_u(:) !< pointer to rotor input (for easier to read code) + real(SiKi), intent(in ) :: RefPoint(3) !< turbine reference point + integer(IntKi), intent( out) :: ErrStat !< error status + character(ErrMsgLen), intent( out) :: ErrMsg !< error message + integer(IntKi) :: nBlades + integer(IntKi) :: iWT, nWT, k + character(IntfStrLen) :: TmpFileName + character(*), parameter :: RoutineName = 'WrVTK_Meshes' !< for error handling + integer(IntKi) :: ErrStat2 !< temporary error status + character(ErrMsgLen) :: ErrMsg2 !< temporary error message + character(10) :: sWT + + ErrStat = 0_IntKi + ErrMsg = '' + + nWT = size(Sim%WT) + do iWT = 1, nWT + ! Turbine identifier + if (nWT==1) then + sWT = '' + else + sWT = '.T'//trim(num2lstr(iWT)) + endif + + select case (WrOutputsData%WrVTK_Type) + case (1) ! surfaces + call WrVTK_Points( ErrStat2,ErrMsg2); if (Failed()) return; + call WrVTK_Surfaces(ErrStat2,ErrMsg2); if (Failed()) return; + case (2) ! lines + call WrVTK_Points( ErrStat2,ErrMsg2); if (Failed()) return; + call WrVTK_Lines( ErrStat2,ErrMsg2); if (Failed()) return; + case (3) ! both + call WrVTK_Points( ErrStat2,ErrMsg2); if (Failed()) return; + call WrVTK_Surfaces(ErrStat2,ErrMsg2); if (Failed()) return; + call WrVTK_Lines( ErrStat2,ErrMsg2); if (Failed()) return; + end select + enddo + +contains + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + end function Failed + + !> meshes rendered at all times (points, or lines for fvw) + subroutine WrVTK_Points(ErrStat3,ErrMsg3) + use FVW_IO, only: WrVTK_FVW + integer(IntKi), intent( out) :: ErrStat3 !< error status + character(ErrMsgLen), intent( out) :: ErrMsg3 !< error message + ErrStat3 = 0_IntKi + ErrMsg3 = '' + + ! Blade point motion (structural mesh from driver) + call MeshWrVTK(RefPoint, BldPtMotionMesh, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.BldPtMotionMesh', n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + if (ErrStat3 >= AbortErrLev) return + + ! Blade root motion (point only) + if (allocated(rot_u(iWT)%BladeRootMotion)) then + do k=1,Sim%WT(1)%NumBlades + if (rot_u(iWT)%BladeRootMotion(k)%Committed) then + call MeshWrVTK(RefPoint, rot_u(iWT)%BladeRootMotion(k), trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.BladeRootMotion'//trim(num2lstr(k)), n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + if (ErrStat3 >= AbortErrLev) return + endif + enddo + endif + + ! Nacelle (structural point input + if ( rot_u(iWT)%NacelleMotion%Committed ) call MeshWrVTK(RefPoint, rot_u(iWT)%NacelleMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.NacelleMotion', n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + if (ErrStat3 >= AbortErrLev) return + + ! Free wake + if (allocated(ADI%m%AD%FVW_u) .and. iWT==1) then + if (allocated(ADI%m%AD%FVW_u(1)%WingsMesh)) then + call WrVTK_FVW(ADI%p%AD%FVW, ADI%x(STATE_CURR)%AD%FVW, ADI%z(STATE_CURR)%AD%FVW, ADI%m%AD%FVW, trim(WrOutputsData%VTK_OutFileRoot)//'.FVW', n_Global, WrOutputsData%VTK_tWidth, bladeFrame=.FALSE.) ! bladeFrame==.FALSE. to output in global coords + endif + end if + end subroutine WrVTK_Points + + !> meshes rendered with a shape or size + subroutine WrVTK_Surfaces(ErrStat3,ErrMsg3) + integer(IntKi), intent( out) :: ErrStat3 !< error status + character(ErrMsgLen), intent( out) :: ErrMsg3 !< error message + logical, parameter :: OutputFields = .FALSE. ! due to confusion about what fields mean on a surface, we are going to just output the basic meshes if people ask for fields + integer(IntKi), parameter :: numSectors = 25 ! Number of sectors for surface utput + + ErrStat3 = 0_IntKi + ErrMsg3 = '' + +!TODO: use this routine when it is moved out of the driver and into ADI +! call AD_WrVTK_Surfaces(ADI%u(1)%AD, ADI%y%AD, RefPoint, ADI%m%VTK_Surfaces, n_Global, WrOutputsData%Root, WrOutputsData%VTK_tWidth, 25, WrOutputsData%VTKHubRad) + + ! Nacelle + if ( rot_u(iWT)%NacelleMotion%Committed ) then + call MeshWrVTK_PointSurface (RefPoint, rot_u(iWT)%NacelleMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.NacelleSurface', n_Global, & + OutputFields, errStat3, errMsg3, WrOutputsData%VTK_tWidth, verts=WrOutputsData%VTK_Surface(iWT)%NacelleBox) + if (ErrStat3 >= AbortErrLev) return + endif + + ! Tower + if (rot_u(iWT)%TowerMotion%Committed) then + call MeshWrVTK_Ln2Surface (RefPoint, rot_u(iWT)%TowerMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.TowerSurface', & + n_Global, OutputFields, errStat3, errMsg3, WrOutputsData%VTK_tWidth, numSectors, ADI%m%VTK_Surfaces(iWT)%TowerRad ) + if (ErrStat3 >= AbortErrLev) return + endif + + ! Hub + if (rot_u(iWT)%HubMotion%Committed) then + call MeshWrVTK_PointSurface (RefPoint, rot_u(iWT)%HubMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.HubSurface', & + n_Global, OutputFields, errStat3, errMsg3, WrOutputsData%VTK_tWidth, & + NumSegments=numSectors, radius=WrOutputsData%VTKHubRad) + if (ErrStat3 >= AbortErrLev) return + endif + + ! Blades + if (allocated(rot_u(iWT)%BladeMotion)) then + do k=1,Sim%WT(1)%NumBlades + if (rot_u(iWT)%BladeMotion(k)%Committed) then + call MeshWrVTK_Ln2Surface (RefPoint, rot_u(iWT)%BladeMotion(k), trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Blade'//trim(num2lstr(k))//'Surface', & + n_Global, OutputFields, errStat3, errMsg3, WrOutputsData%VTK_tWidth , verts=ADI%m%VTK_Surfaces(iWT)%BladeShape(k)%AirfoilCoords, & + Sib=ADI%y%AD%rotors(iWT)%BladeLoad(k) ) + if (ErrStat3 >= AbortErrLev) return + endif + enddo + endif + end subroutine WrVTK_Surfaces + + !> meshes rendered with lines only + subroutine WrVTK_Lines(ErrStat3,ErrMsg3) + integer(IntKi), intent( out) :: ErrStat3 !< error status + character(ErrMsgLen), intent( out) :: ErrMsg3 !< error message + ErrStat3 = 0_IntKi + ErrMsg3 = '' + + ! Tower + if (rot_u(iWT)%TowerMotion%Committed) call MeshWrVTK(RefPoint, rot_u(iWT)%TowerMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Tower', n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + if (ErrStat3 >= AbortErrLev) return + + ! Nacelle meshes + if (rot_u(iWT)%NacelleMotion%Committed) call MeshWrVTK(RefPoint, rot_u(iWT)%NacelleMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Nacelle', n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + if (ErrStat3 >= AbortErrLev) return + + ! Hub + if (rot_u(iWT)%HubMotion%Committed) call MeshWrVTK(RefPoint, rot_u(iWT)%HubMotion, trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Hub', n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + if (ErrStat3 >= AbortErrLev) return + + ! Blades + if (allocated(rot_u(iWT)%BladeMotion)) then + do k=1,Sim%WT(1)%NumBlades + if (rot_u(iWT)%BladeMotion(k)%Committed) then + call MeshWrVTK(RefPoint, rot_u(iWT)%BladeMotion(k), trim(WrOutputsData%VTK_OutFileRoot)//trim(sWT)//'.Blade'//trim(num2lstr(k)), n_Global, .true., ErrStat3, ErrMsg3, WrOutputsData%VTK_tWidth) + if (ErrStat3 >= AbortErrLev) return + endif + enddo + endif + end subroutine WrVTK_Lines +end subroutine WrVTK_Meshes + +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine writes the ground or seabed reference surface information in VTK format. +!! see VTK file information format for XML, here: http://www.vtk.org/wp-content/uploads/2015/04/file-formats.pdf +!! TODO: this is a duplicate of the AeroDyn_Driver_Subs.f90 routine!!!! +subroutine WrVTK_Ground (RefPoint, HalfLengths, FileRootName, errStat, errMsg) + REAL(SiKi), INTENT(IN) :: RefPoint(3) !< reference point (plane will be created around it) + REAL(SiKi), INTENT(IN) :: HalfLengths(2) !< half of the X-Y lengths of plane surrounding RefPoint + CHARACTER(*), INTENT(IN) :: FileRootName !< Name of the file to write the output in (excluding extension) + INTEGER(IntKi), INTENT(OUT) :: errStat !< Indicates whether an error occurred (see NWTC_Library) + CHARACTER(*), INTENT(OUT) :: errMsg !< Error message associated with the errStat + ! local variables + INTEGER(IntKi) :: Un ! fortran unit number + INTEGER(IntKi) :: ix ! loop counters + CHARACTER(1024) :: FileName + INTEGER(IntKi), parameter :: NumberOfPoints = 4 + INTEGER(IntKi), parameter :: NumberOfLines = 0 + INTEGER(IntKi), parameter :: NumberOfPolys = 1 + INTEGER(IntKi) :: errStat2 + CHARACTER(ErrMsgLen) :: errMsg2 + errStat = ErrID_None + errMsg = "" + FileName = TRIM(FileRootName)//'.vtp' + call WrVTK_header( FileName, NumberOfPoints, NumberOfLines, NumberOfPolys, Un, errStat2, errMsg2 ) + call SetErrStat(errStat2,errMsg2,errStat,errMsg,'WrVTK_Ground'); if (errStat >= AbortErrLev) return + WRITE(Un,'(A)') ' ' + WRITE(Un,'(A)') ' ' + WRITE(Un,VTK_AryFmt) RefPoint(1) + HalfLengths(1) , RefPoint(2) + HalfLengths(2), RefPoint(3) + WRITE(Un,VTK_AryFmt) RefPoint(1) + HalfLengths(1) , RefPoint(2) - HalfLengths(2), RefPoint(3) + WRITE(Un,VTK_AryFmt) RefPoint(1) - HalfLengths(1) , RefPoint(2) - HalfLengths(2), RefPoint(3) + WRITE(Un,VTK_AryFmt) RefPoint(1) - HalfLengths(1) , RefPoint(2) + HalfLengths(2), RefPoint(3) + WRITE(Un,'(A)') ' ' + WRITE(Un,'(A)') ' ' + WRITE(Un,'(A)') ' ' + WRITE(Un,'(A)') ' ' + WRITE(Un,'('//trim(num2lstr(NumberOfPoints))//'(i7))') (ix, ix=0,NumberOfPoints-1) + WRITE(Un,'(A)') ' ' + + WRITE(Un,'(A)') ' ' + WRITE(Un,'(i7)') NumberOfPoints + WRITE(Un,'(A)') ' ' + WRITE(Un,'(A)') ' ' + call WrVTK_footer( Un ) +end subroutine WrVTK_Ground + + + +END MODULE AeroDyn_Inflow_C_BINDING diff --git a/modules/aerodyn/src/AeroDyn_Inflow_Registry.txt b/modules/aerodyn/src/AeroDyn_Inflow_Registry.txt new file mode 100644 index 000000000..f47582f5f --- /dev/null +++ b/modules/aerodyn/src/AeroDyn_Inflow_Registry.txt @@ -0,0 +1,139 @@ +################################################################################################################################### +# Registry for AeroDyn with InflowWind +# This Registry file is used to create AeroDyn_Types which contains data used in the AeroDyn module. +# It also contains copy, destroy, pack, and unpack routines associated with each defined data types. +# See the NWTC Programmer's Handbook for further information on the format/contents of this file. +# +# Entries are of the form +# +# +# Use ^ as a shortcut for the value in the same column from the previous line. +################################################################################################################################### +# ...... Include files (definitions from NWTC Library) ............................................................................ +include Registry_NWTC_Library.txt +usefrom AeroDyn_Registry.txt +usefrom InflowWind.txt + +param AeroDyn_Inflow/ADI - IntKi ADI_Version - 1 - "" - + + +# ..... InflowWind data ..................................................................................................... +typedef ^ ADI_InflowWindData InflowWind_ContinuousStateType x - - - "Continuous states" +typedef ^ ^ InflowWind_DiscreteStateType xd - - - "Discrete states" +typedef ^ ^ InflowWind_ConstraintStateType z - - - "Constraint states" +typedef ^ ^ InflowWind_OtherStateType OtherSt - - - "Other states" +typedef ^ ^ InflowWind_ParameterType p - - - "Parameters" +typedef ^ ^ InflowWind_MiscVarType m - - - "Misc/optimization variables" +typedef ^ ^ InflowWind_InputType u - - - "Array of inputs associated with InputTimes" +typedef ^ ^ InflowWind_OutputType y - - - "System outputs" +typedef ^ ^ IntKi CompInflow - - - "0=Steady Wind, 1=InflowWind" "-" +typedef ^ ^ ReKi HWindSpeed - - - "RefHeight Wind speed" +typedef ^ ^ ReKi RefHt - - - "RefHeight" +typedef ^ ^ ReKi PLExp - - - "PLExp" +# ..... InflowWind Input data ..................................................................................................... +typedef ^ ADI_IW_InputData Character(1024) InputFile - - - "Name of InfloWind input file" - +typedef ^ ^ IntKi CompInflow - - - "0=Steady Wind, 1=InflowWind" "-" +typedef ^ ^ ReKi HWindSpeed - - - "RefHeight Wind speed" +typedef ^ ^ ReKi RefHt - - - "RefHeight" +typedef ^ ^ ReKi PLExp - - - "PLExp" +typedef ^ ^ IntKi MHK - - - "MHK turbine type switch" - +typedef ^ ^ LOGICAL UseInputFile - .TRUE. - "Should we read everthing from an input file, or is it passed in?" - +typedef ^ ^ FileInfoType PassedFileData - - - "If we don't use the input file, pass everything through this" - +typedef ^ ^ LOGICAL Linearize - .FALSE. - "Flag that tells this module if the glue code wants to linearize." - + + +# ..... InitIn .................................................................................................................... +typedef ^ InitInputType AD_InitInputType AD - - - "AD Init input types" +typedef ^ ^ ADI_IW_InputData IW_InitInp - - - "IW Init input types" +typedef ^ ^ Character(1024) RootName - - - "RootName for writing output files" - +typedef ^ ^ Logical storeHHVel - .false. - "If True, hub height velocity will be computed by infow wind" - +typedef ^ ^ IntKi WrVTK - 0 - "0= no vtk, 1=init only, 2=animation" "-" +typedef ^ ^ IntKi WrVTK_Type - 1 - "Flag for VTK output type (1=surface, 2=line, 3=both)" - +typedef ^ ^ ReKi WtrDpth - - - "Water depth" m + +# ..... InitOut ................................................................................................................... +typedef ^ InitOutputType ProgDesc Ver - - - "This module's name, version, and date" - +typedef ^ ^ character(ChanLen) WriteOutputHdr {:} - - "Channel headers" "-" +typedef ^ ^ character(ChanLen) WriteOutputUnt {:} - - "Channel units" "-" + +# ..... Continuous States ......................................................................................................... +typedef ^ ContinuousStateType AD_ContinuousStateType AD - - - "AD Continuous states" + +# ..... DiscreteStates ............................................................................................................ +typedef ^ DiscreteStateType AD_DiscreteStateType AD - - - "Discrete states" + +# ..... Constraints ............................................................................................................... +typedef ^ ConstraintStateType AD_ConstraintStateType AD - - - "Constraint states" + +# ..... OtherStates ............................................................................................................... +typedef ^ OtherStateType AD_OtherStateType AD - - - "Other states" + +# ..... Misc ...................................................................................................................... +typedef ^ MiscVarType AD_MiscVarType AD - - - "misc/optimization variables" +typedef ^ ^ ADI_InflowWindData IW - - - "All the necessary inflow wind data" +typedef ^ ^ AD_VTK_RotSurfaceType VTK_surfaces {:} - - "VTK outputs surfaces for each rotor" +# ..... Parameters ................................................................................................................ +typedef ^ ParameterType AD_ParameterType AD - - - "Parameters" +typedef ^ ^ DbKi dt - - - "time increment" "s" +typedef ^ ^ Logical storeHHVel - - - "If True, hub height velocity will be computed by infow wind" - +typedef ^ ^ IntKi wrVTK - - - "0= no vtk, 1=init only, 2=animation" "-" +typedef ^ ^ IntKi WrVTK_Type - - - "Flag for VTK output type (1=surface, 2=line, 3=both)" - +typedef ^ ^ IntKi NumOuts - 0 - "Total number of WriteOutput outputs" - +typedef ^ ^ IntKi MHK - - - "MHK turbine type switch" - +typedef ^ ^ ReKi WtrDpth - - - "Water depth" m + +# ..... Inputs .................................................................................................................... +typedef ^ InputType AD_InputType AD - - - "Array of system inputs" + +# ..... Outputs ................................................................................................................... +#typedef ^ ADI_RotOutputType ReKi WriteOutput {:} - - "WriteOutputs for a given rotor" - +typedef ^ OutputType AD_OutputType AD - - - "System outputs" +#typedef ^ ^ InflowWind_OutputType IW - - - "System outputs" +typedef ^ ^ ReKi HHVel {:}{:} - - "Hub Height velocities for each rotors" +typedef ^ ^ ReKi PLExp - - - "Power law exponents (for outputs only)" +typedef ^ ^ ReKi IW_WriteOutput {:} - - "WriteOutputs for inflow wind" - +#typedef ^ ^ ADI_RotOutputType rotors : - - "WriteOutputs of the driver only" +typedef ^ OutputType ReKi WriteOutput {:} - - "System outputs" + +# ..... AeroDyn_Inflow data ................................................................................................... +# NOTE: useful for driver/wrapper of this module +typedef ^ ADI_Data ADI_ContinuousStateType x : - - "Continuous states" +typedef ^ ^ ADI_DiscreteStateType xd : - - "Discrete states" +typedef ^ ^ ADI_ConstraintStateType z : - - "Constraint states" +typedef ^ ^ ADI_OtherStateType OtherState : - - "Other states" +typedef ^ ^ ADI_ParameterType p - - - "Parameters" +typedef ^ ^ ADI_MiscVarType m - - - "Misc/optimization variables" +typedef ^ ^ ADI_InputType u {:} - - "Array of inputs associated with InputTimes" +typedef ^ ^ ADI_OutputType y - - - "System outputs" +typedef ^ ^ DbKi inputTimes {:} - - "Array of times associated with u array" + +# ..... Rotor elastic data .................................................................................................. +# NOTE: useful for driver/wrapper of this module +typedef ^ RotFED MeshType PlatformPtMesh - - - "Platform reference point positions/orientations/velocities/accelerations" - +typedef ^ ^ MeshType TwrPtMesh - - - "(only if hasTower) Point mesh for tower base motion" "-" +typedef ^ ^ MeshType TwrPtMeshAD - - - "(only if hasTower) Point mesh for tower base for AD" "-" +#typedef ^ ^ MeshType TowerLn2Mesh - - - "Tower line2 mesh with positions/orientations/velocities/accelerations" - +typedef ^ ^ MeshType NacelleMotion - - - "Point mesh for nacelle point motion" "-" +typedef ^ ^ MeshType HubPtMotion - - - "Point mesh for hub point motion" "-" +typedef ^ ^ MeshType BladeRootMotion : - - "BladeRootMotion Point mesh for blade root motion" "-" +typedef ^ ^ MeshType BladeLn2Mesh : - - "(only if elastic blades) BladeLn2Mesh Line mesh along blade" "-" +typedef ^ ^ Logical hasTower - .true. - "True if a tower is present" "-" +typedef ^ ^ Logical rigidBlades - .true. - "True if blades are rigid (using BladeRootMotion) or not (Useing BldeLn2Mesh)" "-" +typedef ^ ^ IntKi numBlades - - - "Number of blades" - +typedef ^ ^ MeshMapType ED_P_2_AD_P_T - - - "(only if hasTower) Mesh mapping from tower base to AD tower base" +typedef ^ ^ MeshMapType AD_P_2_AD_L_T - - - "(only if hasTower) Mesh mapping from tower base to AD tower line" +typedef ^ ^ MeshMapType AD_P_2_AD_L_B : - - "(only for rigid blades) Mesh mapping from AD blade root to AD line mesh" "-" +typedef ^ ^ MeshMapType ED_P_2_AD_P_TF - - - "Map ElastoDyn TailFin CM point (taken as Nacelle) motion mesh to AeroDyn TailFin ref point motion mesh" +typedef ^ ^ MeshMapType ED_P_2_AD_P_R : - - "Map ElastoDyn BladeRootMotion point meshes to AeroDyn BladeRootMotion point meshes" +typedef ^ ^ MeshMapType ED_P_2_AD_P_H - - - "Map ElastoDyn HubPtMotion point mesh to AeroDyn HubMotion point mesh" +typedef ^ ^ MeshMapType ED_P_2_AD_P_N - - - "Map ElastoDyn Nacelle point motion mesh to AeroDyn Nacelle point motion mesh" +#typedef ^ ^ MeshMapType AD_P_2_ED_P_TF - - - "Map AeroDyn TailFin ref point load mesh to ElastoDyn TailFin CM point load mesh" +#typedef ^ ^ MeshMapType AD_P_2_ED_P_N - - - "Map AeroDyn Nacelle point load mesh to ElastoDyn nacelle point load mesh" +#typedef ^ ^ MeshMapType ED_L_2_AD_L_T - - - "Map ElastoDyn TowerLn2Mesh line2 mesh to AeroDyn14 Twr_InputMarkers or AeroDyn TowerMotion line2 mesh" +#typedef ^ ^ MeshMapType AD_L_2_ED_P_T - - - "Map AeroDyn14 Twr_InputMarkers or AeroDyn TowerLoad line2 mesh to ElastoDyn TowerPtLoads point mesh" + +# ..... Turbine elastic data ................................................................................................ +typedef ^ FED_Data RotFED WT : - - "Wind turbine/rotors elastic data" "-" + + + diff --git a/modules/aerodyn/src/AeroDyn_Inflow_Types.f90 b/modules/aerodyn/src/AeroDyn_Inflow_Types.f90 new file mode 100644 index 000000000..9151ebda8 --- /dev/null +++ b/modules/aerodyn/src/AeroDyn_Inflow_Types.f90 @@ -0,0 +1,7325 @@ +!STARTOFREGISTRYGENERATEDFILE 'AeroDyn_Inflow_Types.f90' +! +! WARNING This file is generated automatically by the FAST registry. +! Do not edit. Your changes to this file will be lost. +! +! FAST Registry +!********************************************************************************************************************************* +! AeroDyn_Inflow_Types +!................................................................................................................................. +! This file is part of AeroDyn_Inflow. +! +! Copyright (C) 2012-2016 National Renewable Energy Laboratory +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +! +! +! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. +! +!********************************************************************************************************************************* +!> This module contains the user-defined types needed in AeroDyn_Inflow. It also contains copy, destroy, pack, and +!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. +MODULE AeroDyn_Inflow_Types +!--------------------------------------------------------------------------------------------------------------------------------- +USE AeroDyn_Types +USE InflowWind_Types +USE NWTC_Library +IMPLICIT NONE + INTEGER(IntKi), PUBLIC, PARAMETER :: ADI_Version = 1 ! [-] +! ========= ADI_InflowWindData ======= + TYPE, PUBLIC :: ADI_InflowWindData + TYPE(InflowWind_ContinuousStateType) :: x !< Continuous states [-] + TYPE(InflowWind_DiscreteStateType) :: xd !< Discrete states [-] + TYPE(InflowWind_ConstraintStateType) :: z !< Constraint states [-] + TYPE(InflowWind_OtherStateType) :: OtherSt !< Other states [-] + TYPE(InflowWind_ParameterType) :: p !< Parameters [-] + TYPE(InflowWind_MiscVarType) :: m !< Misc/optimization variables [-] + TYPE(InflowWind_InputType) :: u !< Array of inputs associated with InputTimes [-] + TYPE(InflowWind_OutputType) :: y !< System outputs [-] + INTEGER(IntKi) :: CompInflow !< 0=Steady Wind, 1=InflowWind [-] + REAL(ReKi) :: HWindSpeed !< RefHeight Wind speed [-] + REAL(ReKi) :: RefHt !< RefHeight [-] + REAL(ReKi) :: PLExp !< PLExp [-] + END TYPE ADI_InflowWindData +! ======================= +! ========= ADI_IW_InputData ======= + TYPE, PUBLIC :: ADI_IW_InputData + Character(1024) :: InputFile !< Name of InfloWind input file [-] + INTEGER(IntKi) :: CompInflow !< 0=Steady Wind, 1=InflowWind [-] + REAL(ReKi) :: HWindSpeed !< RefHeight Wind speed [-] + REAL(ReKi) :: RefHt !< RefHeight [-] + REAL(ReKi) :: PLExp !< PLExp [-] + INTEGER(IntKi) :: MHK !< MHK turbine type switch [-] + LOGICAL :: UseInputFile = .TRUE. !< Should we read everthing from an input file, or is it passed in? [-] + TYPE(FileInfoType) :: PassedFileData !< If we don't use the input file, pass everything through this [-] + LOGICAL :: Linearize = .FALSE. !< Flag that tells this module if the glue code wants to linearize. [-] + END TYPE ADI_IW_InputData +! ======================= +! ========= ADI_InitInputType ======= + TYPE, PUBLIC :: ADI_InitInputType + TYPE(AD_InitInputType) :: AD !< AD Init input types [-] + TYPE(ADI_IW_InputData) :: IW_InitInp !< IW Init input types [-] + Character(1024) :: RootName !< RootName for writing output files [-] + LOGICAL :: storeHHVel = .false. !< If True, hub height velocity will be computed by infow wind [-] + INTEGER(IntKi) :: WrVTK = 0 !< 0= no vtk, 1=init only, 2=animation [-] + INTEGER(IntKi) :: WrVTK_Type = 1 !< Flag for VTK output type (1=surface, 2=line, 3=both) [-] + REAL(ReKi) :: WtrDpth !< Water depth [m] + END TYPE ADI_InitInputType +! ======================= +! ========= ADI_InitOutputType ======= + TYPE, PUBLIC :: ADI_InitOutputType + TYPE(ProgDesc) :: Ver !< This module's name, version, and date [-] + character(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< Channel headers [-] + character(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputUnt !< Channel units [-] + END TYPE ADI_InitOutputType +! ======================= +! ========= ADI_ContinuousStateType ======= + TYPE, PUBLIC :: ADI_ContinuousStateType + TYPE(AD_ContinuousStateType) :: AD !< AD Continuous states [-] + END TYPE ADI_ContinuousStateType +! ======================= +! ========= ADI_DiscreteStateType ======= + TYPE, PUBLIC :: ADI_DiscreteStateType + TYPE(AD_DiscreteStateType) :: AD !< Discrete states [-] + END TYPE ADI_DiscreteStateType +! ======================= +! ========= ADI_ConstraintStateType ======= + TYPE, PUBLIC :: ADI_ConstraintStateType + TYPE(AD_ConstraintStateType) :: AD !< Constraint states [-] + END TYPE ADI_ConstraintStateType +! ======================= +! ========= ADI_OtherStateType ======= + TYPE, PUBLIC :: ADI_OtherStateType + TYPE(AD_OtherStateType) :: AD !< Other states [-] + END TYPE ADI_OtherStateType +! ======================= +! ========= ADI_MiscVarType ======= + TYPE, PUBLIC :: ADI_MiscVarType + TYPE(AD_MiscVarType) :: AD !< misc/optimization variables [-] + TYPE(ADI_InflowWindData) :: IW !< All the necessary inflow wind data [-] + TYPE(AD_VTK_RotSurfaceType) , DIMENSION(:), ALLOCATABLE :: VTK_surfaces !< VTK outputs surfaces for each rotor [-] + END TYPE ADI_MiscVarType +! ======================= +! ========= ADI_ParameterType ======= + TYPE, PUBLIC :: ADI_ParameterType + TYPE(AD_ParameterType) :: AD !< Parameters [-] + REAL(DbKi) :: dt !< time increment [s] + LOGICAL :: storeHHVel !< If True, hub height velocity will be computed by infow wind [-] + INTEGER(IntKi) :: wrVTK !< 0= no vtk, 1=init only, 2=animation [-] + INTEGER(IntKi) :: WrVTK_Type !< Flag for VTK output type (1=surface, 2=line, 3=both) [-] + INTEGER(IntKi) :: NumOuts = 0 !< Total number of WriteOutput outputs [-] + INTEGER(IntKi) :: MHK !< MHK turbine type switch [-] + REAL(ReKi) :: WtrDpth !< Water depth [m] + END TYPE ADI_ParameterType +! ======================= +! ========= ADI_InputType ======= + TYPE, PUBLIC :: ADI_InputType + TYPE(AD_InputType) :: AD !< Array of system inputs [-] + END TYPE ADI_InputType +! ======================= +! ========= ADI_OutputType ======= + TYPE, PUBLIC :: ADI_OutputType + TYPE(AD_OutputType) :: AD !< System outputs [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: HHVel !< Hub Height velocities for each rotors [-] + REAL(ReKi) :: PLExp !< Power law exponents (for outputs only) [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: IW_WriteOutput !< WriteOutputs for inflow wind [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< System outputs [-] + END TYPE ADI_OutputType +! ======================= +! ========= ADI_Data ======= + TYPE, PUBLIC :: ADI_Data + TYPE(ADI_ContinuousStateType) , DIMENSION(:), ALLOCATABLE :: x !< Continuous states [-] + TYPE(ADI_DiscreteStateType) , DIMENSION(:), ALLOCATABLE :: xd !< Discrete states [-] + TYPE(ADI_ConstraintStateType) , DIMENSION(:), ALLOCATABLE :: z !< Constraint states [-] + TYPE(ADI_OtherStateType) , DIMENSION(:), ALLOCATABLE :: OtherState !< Other states [-] + TYPE(ADI_ParameterType) :: p !< Parameters [-] + TYPE(ADI_MiscVarType) :: m !< Misc/optimization variables [-] + TYPE(ADI_InputType) , DIMENSION(:), ALLOCATABLE :: u !< Array of inputs associated with InputTimes [-] + TYPE(ADI_OutputType) :: y !< System outputs [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: inputTimes !< Array of times associated with u array [-] + END TYPE ADI_Data +! ======================= +! ========= RotFED ======= + TYPE, PUBLIC :: RotFED + TYPE(MeshType) :: PlatformPtMesh !< Platform reference point positions/orientations/velocities/accelerations [-] + TYPE(MeshType) :: TwrPtMesh !< (only if hasTower) Point mesh for tower base motion [-] + TYPE(MeshType) :: TwrPtMeshAD !< (only if hasTower) Point mesh for tower base for AD [-] + TYPE(MeshType) :: NacelleMotion !< Point mesh for nacelle point motion [-] + TYPE(MeshType) :: HubPtMotion !< Point mesh for hub point motion [-] + TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: BladeRootMotion !< BladeRootMotion Point mesh for blade root motion [-] + TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: BladeLn2Mesh !< (only if elastic blades) BladeLn2Mesh Line mesh along blade [-] + LOGICAL :: hasTower = .true. !< True if a tower is present [-] + LOGICAL :: rigidBlades = .true. !< True if blades are rigid (using BladeRootMotion) or not (Useing BldeLn2Mesh) [-] + INTEGER(IntKi) :: numBlades !< Number of blades [-] + TYPE(MeshMapType) :: ED_P_2_AD_P_T !< (only if hasTower) Mesh mapping from tower base to AD tower base [-] + TYPE(MeshMapType) :: AD_P_2_AD_L_T !< (only if hasTower) Mesh mapping from tower base to AD tower line [-] + TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: AD_P_2_AD_L_B !< (only for rigid blades) Mesh mapping from AD blade root to AD line mesh [-] + TYPE(MeshMapType) :: ED_P_2_AD_P_TF !< Map ElastoDyn TailFin CM point (taken as Nacelle) motion mesh to AeroDyn TailFin ref point motion 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) :: ED_P_2_AD_P_N !< Map ElastoDyn Nacelle point motion mesh to AeroDyn Nacelle point motion mesh [-] + END TYPE RotFED +! ======================= +! ========= FED_Data ======= + TYPE, PUBLIC :: FED_Data + TYPE(RotFED) , DIMENSION(:), ALLOCATABLE :: WT !< Wind turbine/rotors elastic data [-] + END TYPE FED_Data +! ======================= +CONTAINS + SUBROUTINE ADI_CopyInflowWindData( SrcInflowWindDataData, DstInflowWindDataData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ADI_InflowWindData), INTENT(IN) :: SrcInflowWindDataData + TYPE(ADI_InflowWindData), INTENT(INOUT) :: DstInflowWindDataData + 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 = 'ADI_CopyInflowWindData' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL InflowWind_CopyContState( SrcInflowWindDataData%x, DstInflowWindDataData%x, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL InflowWind_CopyDiscState( SrcInflowWindDataData%xd, DstInflowWindDataData%xd, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL InflowWind_CopyConstrState( SrcInflowWindDataData%z, DstInflowWindDataData%z, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL InflowWind_CopyOtherState( SrcInflowWindDataData%OtherSt, DstInflowWindDataData%OtherSt, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL InflowWind_CopyParam( SrcInflowWindDataData%p, DstInflowWindDataData%p, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL InflowWind_CopyMisc( SrcInflowWindDataData%m, DstInflowWindDataData%m, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL InflowWind_CopyInput( SrcInflowWindDataData%u, DstInflowWindDataData%u, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL InflowWind_CopyOutput( SrcInflowWindDataData%y, DstInflowWindDataData%y, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstInflowWindDataData%CompInflow = SrcInflowWindDataData%CompInflow + DstInflowWindDataData%HWindSpeed = SrcInflowWindDataData%HWindSpeed + DstInflowWindDataData%RefHt = SrcInflowWindDataData%RefHt + DstInflowWindDataData%PLExp = SrcInflowWindDataData%PLExp + END SUBROUTINE ADI_CopyInflowWindData + + SUBROUTINE ADI_DestroyInflowWindData( InflowWindDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ADI_InflowWindData), INTENT(INOUT) :: InflowWindDataData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyInflowWindData' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL InflowWind_DestroyContState( InflowWindDataData%x, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyDiscState( InflowWindDataData%xd, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyConstrState( InflowWindDataData%z, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyOtherState( InflowWindDataData%OtherSt, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyParam( InflowWindDataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyMisc( InflowWindDataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyInput( InflowWindDataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyOutput( InflowWindDataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE ADI_DestroyInflowWindData + + SUBROUTINE ADI_PackInflowWindData( 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(ADI_InflowWindData), 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 = 'ADI_PackInflowWindData' + ! 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 ! x: size of buffers for each call to pack subtype + CALL InflowWind_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, .TRUE. ) ! x + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! x + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! x + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! x + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! xd: size of buffers for each call to pack subtype + CALL InflowWind_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, .TRUE. ) ! xd + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! xd + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! xd + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! xd + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! z: size of buffers for each call to pack subtype + CALL InflowWind_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, .TRUE. ) ! z + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! z + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! z + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! z + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! OtherSt: size of buffers for each call to pack subtype + CALL InflowWind_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, .TRUE. ) ! OtherSt + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! OtherSt + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! OtherSt + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! OtherSt + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! p: size of buffers for each call to pack subtype + CALL InflowWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! p + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! p + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! p + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! m: size of buffers for each call to pack subtype + CALL InflowWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! m + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! m + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! m + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! u: size of buffers for each call to pack subtype + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, .TRUE. ) ! u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! u + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! u + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! u + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! y: size of buffers for each call to pack subtype + CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! y + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! y + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! y + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! CompInflow + Re_BufSz = Re_BufSz + 1 ! HWindSpeed + Re_BufSz = Re_BufSz + 1 ! RefHt + Re_BufSz = Re_BufSz + 1 ! PLExp + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + CALL InflowWind_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x, ErrStat2, ErrMsg2, OnlySize ) ! x + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL InflowWind_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd, ErrStat2, ErrMsg2, OnlySize ) ! xd + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL InflowWind_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z, ErrStat2, ErrMsg2, OnlySize ) ! z + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL InflowWind_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherSt, ErrStat2, ErrMsg2, OnlySize ) ! OtherSt + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL InflowWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL InflowWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u, ErrStat2, ErrMsg2, OnlySize ) ! u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IntKiBuf(Int_Xferred) = InData%CompInflow + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%HWindSpeed + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefHt + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%PLExp + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ADI_PackInflowWindData + + SUBROUTINE ADI_UnPackInflowWindData( 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(ADI_InflowWindData), 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 = 'ADI_UnPackInflowWindData' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%x, ErrStat2, ErrMsg2 ) ! x + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%xd, ErrStat2, ErrMsg2 ) ! xd + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%z, ErrStat2, ErrMsg2 ) ! z + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%OtherSt, ErrStat2, ErrMsg2 ) ! OtherSt + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%p, ErrStat2, ErrMsg2 ) ! p + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u, ErrStat2, ErrMsg2 ) ! u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + OutData%CompInflow = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%HWindSpeed = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefHt = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%PLExp = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ADI_UnPackInflowWindData + + SUBROUTINE ADI_CopyIW_InputData( SrcIW_InputDataData, DstIW_InputDataData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ADI_IW_InputData), INTENT(IN) :: SrcIW_InputDataData + TYPE(ADI_IW_InputData), INTENT(INOUT) :: DstIW_InputDataData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_CopyIW_InputData' +! + ErrStat = ErrID_None + ErrMsg = "" + DstIW_InputDataData%InputFile = SrcIW_InputDataData%InputFile + DstIW_InputDataData%CompInflow = SrcIW_InputDataData%CompInflow + DstIW_InputDataData%HWindSpeed = SrcIW_InputDataData%HWindSpeed + DstIW_InputDataData%RefHt = SrcIW_InputDataData%RefHt + DstIW_InputDataData%PLExp = SrcIW_InputDataData%PLExp + DstIW_InputDataData%MHK = SrcIW_InputDataData%MHK + DstIW_InputDataData%UseInputFile = SrcIW_InputDataData%UseInputFile + CALL NWTC_Library_Copyfileinfotype( SrcIW_InputDataData%PassedFileData, DstIW_InputDataData%PassedFileData, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstIW_InputDataData%Linearize = SrcIW_InputDataData%Linearize + END SUBROUTINE ADI_CopyIW_InputData + + SUBROUTINE ADI_DestroyIW_InputData( IW_InputDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ADI_IW_InputData), INTENT(INOUT) :: IW_InputDataData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyIW_InputData' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyfileinfotype( IW_InputDataData%PassedFileData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE ADI_DestroyIW_InputData + + SUBROUTINE ADI_PackIW_InputData( 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(ADI_IW_InputData), 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 = 'ADI_PackIW_InputData' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1*LEN(InData%InputFile) ! InputFile + Int_BufSz = Int_BufSz + 1 ! CompInflow + Re_BufSz = Re_BufSz + 1 ! HWindSpeed + Re_BufSz = Re_BufSz + 1 ! RefHt + Re_BufSz = Re_BufSz + 1 ! PLExp + Int_BufSz = Int_BufSz + 1 ! MHK + Int_BufSz = Int_BufSz + 1 ! UseInputFile + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! PassedFileData: size of buffers for each call to pack subtype + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, .TRUE. ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! PassedFileData + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! PassedFileData + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! PassedFileData + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! Linearize + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO I = 1, LEN(InData%InputFile) + IntKiBuf(Int_Xferred) = ICHAR(InData%InputFile(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IntKiBuf(Int_Xferred) = InData%CompInflow + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%HWindSpeed + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefHt + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%PLExp + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%MHK + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%UseInputFile, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, OnlySize ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IntKiBuf(Int_Xferred) = TRANSFER(InData%Linearize, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE ADI_PackIW_InputData + + SUBROUTINE ADI_UnPackIW_InputData( 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(ADI_IW_InputData), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_UnPackIW_InputData' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + DO I = 1, LEN(OutData%InputFile) + OutData%InputFile(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%CompInflow = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%HWindSpeed = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefHt = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%PLExp = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MHK = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%UseInputFile = TRANSFER(IntKiBuf(Int_Xferred), OutData%UseInputFile) + Int_Xferred = Int_Xferred + 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackfileinfotype( Re_Buf, Db_Buf, Int_Buf, OutData%PassedFileData, ErrStat2, ErrMsg2 ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + OutData%Linearize = TRANSFER(IntKiBuf(Int_Xferred), OutData%Linearize) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE ADI_UnPackIW_InputData + + SUBROUTINE ADI_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ADI_InitInputType), INTENT(IN) :: SrcInitInputData + TYPE(ADI_InitInputType), INTENT(INOUT) :: DstInitInputData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_CopyInitInput' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL AD_CopyInitInput( SrcInitInputData%AD, DstInitInputData%AD, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL ADI_Copyiw_inputdata( SrcInitInputData%IW_InitInp, DstInitInputData%IW_InitInp, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstInitInputData%RootName = SrcInitInputData%RootName + DstInitInputData%storeHHVel = SrcInitInputData%storeHHVel + DstInitInputData%WrVTK = SrcInitInputData%WrVTK + DstInitInputData%WrVTK_Type = SrcInitInputData%WrVTK_Type + DstInitInputData%WtrDpth = SrcInitInputData%WtrDpth + END SUBROUTINE ADI_CopyInitInput + + SUBROUTINE ADI_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ADI_InitInputType), INTENT(INOUT) :: InitInputData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyInitInput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AD_DestroyInitInput( InitInputData%AD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ADI_Destroyiw_inputdata( InitInputData%IW_InitInp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE ADI_DestroyInitInput + + SUBROUTINE ADI_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(ADI_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_PackInitInput' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! AD: size of buffers for each call to pack subtype + CALL AD_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, .TRUE. ) ! AD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! IW_InitInp: size of buffers for each call to pack subtype + CALL ADI_Packiw_inputdata( Re_Buf, Db_Buf, Int_Buf, InData%IW_InitInp, ErrStat2, ErrMsg2, .TRUE. ) ! IW_InitInp + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! IW_InitInp + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! IW_InitInp + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! IW_InitInp + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName + Int_BufSz = Int_BufSz + 1 ! storeHHVel + Int_BufSz = Int_BufSz + 1 ! WrVTK + Int_BufSz = Int_BufSz + 1 ! WrVTK_Type + Re_BufSz = Re_BufSz + 1 ! WtrDpth + 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 AD_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, OnlySize ) ! AD + 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 ADI_Packiw_inputdata( Re_Buf, Db_Buf, Int_Buf, InData%IW_InitInp, ErrStat2, ErrMsg2, OnlySize ) ! IW_InitInp + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + DO I = 1, LEN(InData%RootName) + IntKiBuf(Int_Xferred) = ICHAR(InData%RootName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IntKiBuf(Int_Xferred) = TRANSFER(InData%storeHHVel, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%WrVTK + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%WrVTK_Type + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WtrDpth + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ADI_PackInitInput + + SUBROUTINE ADI_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(ADI_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_UnPackInitInput' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL AD_UnpackInitInput( Re_Buf, Db_Buf, Int_Buf, OutData%AD, ErrStat2, ErrMsg2 ) ! AD + 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 ADI_Unpackiw_inputdata( Re_Buf, Db_Buf, Int_Buf, OutData%IW_InitInp, ErrStat2, ErrMsg2 ) ! IW_InitInp + 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) + DO I = 1, LEN(OutData%RootName) + OutData%RootName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%storeHHVel = TRANSFER(IntKiBuf(Int_Xferred), OutData%storeHHVel) + Int_Xferred = Int_Xferred + 1 + OutData%WrVTK = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WrVTK_Type = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WtrDpth = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ADI_UnPackInitInput + + SUBROUTINE ADI_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ADI_InitOutputType), INTENT(IN) :: SrcInitOutputData + TYPE(ADI_InitOutputType), INTENT(INOUT) :: DstInitOutputData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_CopyInitOutput' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +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 ADI_CopyInitOutput + + SUBROUTINE ADI_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ADI_InitOutputType), INTENT(INOUT) :: InitOutputData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyInitOutput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN + DEALLOCATE(InitOutputData%WriteOutputHdr) +ENDIF +IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN + DEALLOCATE(InitOutputData%WriteOutputUnt) +ENDIF + END SUBROUTINE ADI_DestroyInitOutput + + SUBROUTINE ADI_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(ADI_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 = 'ADI_PackInitOutput' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype + CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Ver + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Ver + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Ver + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + 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 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%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 ADI_PackInitOutput + + SUBROUTINE ADI_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(ADI_InitOutputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_UnPackInitOutput' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + 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 ADI_UnPackInitOutput + + SUBROUTINE ADI_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ADI_ContinuousStateType), INTENT(IN) :: SrcContStateData + TYPE(ADI_ContinuousStateType), INTENT(INOUT) :: DstContStateData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_CopyContState' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL AD_CopyContState( SrcContStateData%AD, DstContStateData%AD, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE ADI_CopyContState + + SUBROUTINE ADI_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ADI_ContinuousStateType), INTENT(INOUT) :: ContStateData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyContState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AD_DestroyContState( ContStateData%AD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE ADI_DestroyContState + + SUBROUTINE ADI_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(ADI_ContinuousStateType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_PackContState' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! AD: size of buffers for each call to pack subtype + CALL AD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, .TRUE. ) ! AD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + CALL AD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, OnlySize ) ! AD + 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 ADI_PackContState + + SUBROUTINE ADI_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(ADI_ContinuousStateType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_UnPackContState' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL AD_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%AD, ErrStat2, ErrMsg2 ) ! AD + 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 ADI_UnPackContState + + SUBROUTINE ADI_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ADI_DiscreteStateType), INTENT(IN) :: SrcDiscStateData + TYPE(ADI_DiscreteStateType), INTENT(INOUT) :: DstDiscStateData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_CopyDiscState' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL AD_CopyDiscState( SrcDiscStateData%AD, DstDiscStateData%AD, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE ADI_CopyDiscState + + SUBROUTINE ADI_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ADI_DiscreteStateType), INTENT(INOUT) :: DiscStateData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyDiscState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AD_DestroyDiscState( DiscStateData%AD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE ADI_DestroyDiscState + + SUBROUTINE ADI_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(ADI_DiscreteStateType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_PackDiscState' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! AD: size of buffers for each call to pack subtype + CALL AD_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, .TRUE. ) ! AD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + CALL AD_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, OnlySize ) ! AD + 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 ADI_PackDiscState + + SUBROUTINE ADI_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(ADI_DiscreteStateType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_UnPackDiscState' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL AD_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%AD, ErrStat2, ErrMsg2 ) ! AD + 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 ADI_UnPackDiscState + + SUBROUTINE ADI_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ADI_ConstraintStateType), INTENT(IN) :: SrcConstrStateData + TYPE(ADI_ConstraintStateType), INTENT(INOUT) :: DstConstrStateData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_CopyConstrState' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL AD_CopyConstrState( SrcConstrStateData%AD, DstConstrStateData%AD, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE ADI_CopyConstrState + + SUBROUTINE ADI_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ADI_ConstraintStateType), INTENT(INOUT) :: ConstrStateData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyConstrState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AD_DestroyConstrState( ConstrStateData%AD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE ADI_DestroyConstrState + + SUBROUTINE ADI_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(ADI_ConstraintStateType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_PackConstrState' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! AD: size of buffers for each call to pack subtype + CALL AD_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, .TRUE. ) ! AD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + CALL AD_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, OnlySize ) ! AD + 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 ADI_PackConstrState + + SUBROUTINE ADI_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(ADI_ConstraintStateType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_UnPackConstrState' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL AD_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%AD, ErrStat2, ErrMsg2 ) ! AD + 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 ADI_UnPackConstrState + + SUBROUTINE ADI_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ADI_OtherStateType), INTENT(IN) :: SrcOtherStateData + TYPE(ADI_OtherStateType), INTENT(INOUT) :: DstOtherStateData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_CopyOtherState' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL AD_CopyOtherState( SrcOtherStateData%AD, DstOtherStateData%AD, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE ADI_CopyOtherState + + SUBROUTINE ADI_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ADI_OtherStateType), INTENT(INOUT) :: OtherStateData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyOtherState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AD_DestroyOtherState( OtherStateData%AD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE ADI_DestroyOtherState + + SUBROUTINE ADI_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(ADI_OtherStateType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_PackOtherState' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! AD: size of buffers for each call to pack subtype + CALL AD_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, .TRUE. ) ! AD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + CALL AD_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, OnlySize ) ! AD + 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 ADI_PackOtherState + + SUBROUTINE ADI_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(ADI_OtherStateType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_UnPackOtherState' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL AD_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%AD, ErrStat2, ErrMsg2 ) ! AD + 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 ADI_UnPackOtherState + + SUBROUTINE ADI_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ADI_MiscVarType), INTENT(INOUT) :: SrcMiscData + TYPE(ADI_MiscVarType), INTENT(INOUT) :: DstMiscData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_CopyMisc' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL AD_CopyMisc( SrcMiscData%AD, DstMiscData%AD, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL ADI_Copyinflowwinddata( SrcMiscData%IW, DstMiscData%IW, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcMiscData%VTK_surfaces)) THEN + i1_l = LBOUND(SrcMiscData%VTK_surfaces,1) + i1_u = UBOUND(SrcMiscData%VTK_surfaces,1) + IF (.NOT. ALLOCATED(DstMiscData%VTK_surfaces)) THEN + ALLOCATE(DstMiscData%VTK_surfaces(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%VTK_surfaces.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%VTK_surfaces,1), UBOUND(SrcMiscData%VTK_surfaces,1) + CALL AD_Copyvtk_rotsurfacetype( SrcMiscData%VTK_surfaces(i1), DstMiscData%VTK_surfaces(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + END SUBROUTINE ADI_CopyMisc + + SUBROUTINE ADI_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ADI_MiscVarType), INTENT(INOUT) :: MiscData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyMisc' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AD_DestroyMisc( MiscData%AD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ADI_Destroyinflowwinddata( MiscData%IW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(MiscData%VTK_surfaces)) THEN +DO i1 = LBOUND(MiscData%VTK_surfaces,1), UBOUND(MiscData%VTK_surfaces,1) + CALL AD_Destroyvtk_rotsurfacetype( MiscData%VTK_surfaces(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MiscData%VTK_surfaces) +ENDIF + END SUBROUTINE ADI_DestroyMisc + + SUBROUTINE ADI_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(ADI_MiscVarType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_PackMisc' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! AD: size of buffers for each call to pack subtype + CALL AD_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, .TRUE. ) ! AD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! IW: size of buffers for each call to pack subtype + CALL ADI_Packinflowwinddata( Re_Buf, Db_Buf, Int_Buf, InData%IW, ErrStat2, ErrMsg2, .TRUE. ) ! IW + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! IW + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! IW + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! IW + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! VTK_surfaces allocated yes/no + IF ( ALLOCATED(InData%VTK_surfaces) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VTK_surfaces upper/lower bounds for each dimension + DO i1 = LBOUND(InData%VTK_surfaces,1), UBOUND(InData%VTK_surfaces,1) + Int_BufSz = Int_BufSz + 3 ! VTK_surfaces: size of buffers for each call to pack subtype + CALL AD_Packvtk_rotsurfacetype( Re_Buf, Db_Buf, Int_Buf, InData%VTK_surfaces(i1), ErrStat2, ErrMsg2, .TRUE. ) ! VTK_surfaces + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! VTK_surfaces + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! VTK_surfaces + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! VTK_surfaces + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + CALL AD_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, OnlySize ) ! AD + 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 ADI_Packinflowwinddata( Re_Buf, Db_Buf, Int_Buf, InData%IW, ErrStat2, ErrMsg2, OnlySize ) ! IW + 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%VTK_surfaces) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VTK_surfaces,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VTK_surfaces,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%VTK_surfaces,1), UBOUND(InData%VTK_surfaces,1) + CALL AD_Packvtk_rotsurfacetype( Re_Buf, Db_Buf, Int_Buf, InData%VTK_surfaces(i1), ErrStat2, ErrMsg2, OnlySize ) ! VTK_surfaces + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF + END SUBROUTINE ADI_PackMisc + + SUBROUTINE ADI_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(ADI_MiscVarType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_UnPackMisc' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL AD_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%AD, ErrStat2, ErrMsg2 ) ! AD + 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 ADI_Unpackinflowwinddata( Re_Buf, Db_Buf, Int_Buf, OutData%IW, ErrStat2, ErrMsg2 ) ! IW + 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 ! VTK_surfaces not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VTK_surfaces)) DEALLOCATE(OutData%VTK_surfaces) + ALLOCATE(OutData%VTK_surfaces(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VTK_surfaces.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%VTK_surfaces,1), UBOUND(OutData%VTK_surfaces,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL AD_Unpackvtk_rotsurfacetype( Re_Buf, Db_Buf, Int_Buf, OutData%VTK_surfaces(i1), ErrStat2, ErrMsg2 ) ! VTK_surfaces + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + END SUBROUTINE ADI_UnPackMisc + + SUBROUTINE ADI_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ADI_ParameterType), INTENT(IN) :: SrcParamData + TYPE(ADI_ParameterType), INTENT(INOUT) :: DstParamData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_CopyParam' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL AD_CopyParam( SrcParamData%AD, DstParamData%AD, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstParamData%dt = SrcParamData%dt + DstParamData%storeHHVel = SrcParamData%storeHHVel + DstParamData%wrVTK = SrcParamData%wrVTK + DstParamData%WrVTK_Type = SrcParamData%WrVTK_Type + DstParamData%NumOuts = SrcParamData%NumOuts + DstParamData%MHK = SrcParamData%MHK + DstParamData%WtrDpth = SrcParamData%WtrDpth + END SUBROUTINE ADI_CopyParam + + SUBROUTINE ADI_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ADI_ParameterType), INTENT(INOUT) :: ParamData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyParam' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AD_DestroyParam( ParamData%AD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE ADI_DestroyParam + + SUBROUTINE ADI_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(ADI_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 = 'ADI_PackParam' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! AD: size of buffers for each call to pack subtype + CALL AD_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, .TRUE. ) ! AD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Db_BufSz = Db_BufSz + 1 ! dt + Int_BufSz = Int_BufSz + 1 ! storeHHVel + Int_BufSz = Int_BufSz + 1 ! wrVTK + Int_BufSz = Int_BufSz + 1 ! WrVTK_Type + Int_BufSz = Int_BufSz + 1 ! NumOuts + Int_BufSz = Int_BufSz + 1 ! MHK + Re_BufSz = Re_BufSz + 1 ! WtrDpth + 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 AD_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, OnlySize ) ! AD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + DbKiBuf(Db_Xferred) = InData%dt + Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%storeHHVel, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%wrVTK + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%WrVTK_Type + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumOuts + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%MHK + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WtrDpth + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ADI_PackParam + + SUBROUTINE ADI_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(ADI_ParameterType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_UnPackParam' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL AD_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%AD, ErrStat2, ErrMsg2 ) ! AD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + OutData%dt = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%storeHHVel = TRANSFER(IntKiBuf(Int_Xferred), OutData%storeHHVel) + Int_Xferred = Int_Xferred + 1 + OutData%wrVTK = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WrVTK_Type = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NumOuts = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%MHK = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WtrDpth = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE ADI_UnPackParam + + SUBROUTINE ADI_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ADI_InputType), INTENT(INOUT) :: SrcInputData + TYPE(ADI_InputType), INTENT(INOUT) :: DstInputData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_CopyInput' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL AD_CopyInput( SrcInputData%AD, DstInputData%AD, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE ADI_CopyInput + + SUBROUTINE ADI_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ADI_InputType), INTENT(INOUT) :: InputData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyInput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AD_DestroyInput( InputData%AD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE ADI_DestroyInput + + SUBROUTINE ADI_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(ADI_InputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_PackInput' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! AD: size of buffers for each call to pack subtype + CALL AD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, .TRUE. ) ! AD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + CALL AD_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, OnlySize ) ! AD + 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 ADI_PackInput + + SUBROUTINE ADI_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(ADI_InputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_UnPackInput' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL AD_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%AD, ErrStat2, ErrMsg2 ) ! AD + 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 ADI_UnPackInput + + SUBROUTINE ADI_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ADI_OutputType), INTENT(INOUT) :: SrcOutputData + TYPE(ADI_OutputType), INTENT(INOUT) :: DstOutputData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_CopyOutput' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL AD_CopyOutput( SrcOutputData%AD, DstOutputData%AD, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcOutputData%HHVel)) THEN + i1_l = LBOUND(SrcOutputData%HHVel,1) + i1_u = UBOUND(SrcOutputData%HHVel,1) + i2_l = LBOUND(SrcOutputData%HHVel,2) + i2_u = UBOUND(SrcOutputData%HHVel,2) + IF (.NOT. ALLOCATED(DstOutputData%HHVel)) THEN + ALLOCATE(DstOutputData%HHVel(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%HHVel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%HHVel = SrcOutputData%HHVel +ENDIF + DstOutputData%PLExp = SrcOutputData%PLExp +IF (ALLOCATED(SrcOutputData%IW_WriteOutput)) THEN + i1_l = LBOUND(SrcOutputData%IW_WriteOutput,1) + i1_u = UBOUND(SrcOutputData%IW_WriteOutput,1) + IF (.NOT. ALLOCATED(DstOutputData%IW_WriteOutput)) THEN + ALLOCATE(DstOutputData%IW_WriteOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%IW_WriteOutput.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%IW_WriteOutput = SrcOutputData%IW_WriteOutput +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 ADI_CopyOutput + + SUBROUTINE ADI_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ADI_OutputType), INTENT(INOUT) :: OutputData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyOutput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AD_DestroyOutput( OutputData%AD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(OutputData%HHVel)) THEN + DEALLOCATE(OutputData%HHVel) +ENDIF +IF (ALLOCATED(OutputData%IW_WriteOutput)) THEN + DEALLOCATE(OutputData%IW_WriteOutput) +ENDIF +IF (ALLOCATED(OutputData%WriteOutput)) THEN + DEALLOCATE(OutputData%WriteOutput) +ENDIF + END SUBROUTINE ADI_DestroyOutput + + SUBROUTINE ADI_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(ADI_OutputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_PackOutput' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! AD: size of buffers for each call to pack subtype + CALL AD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, .TRUE. ) ! AD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! HHVel allocated yes/no + IF ( ALLOCATED(InData%HHVel) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! HHVel upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%HHVel) ! HHVel + END IF + Re_BufSz = Re_BufSz + 1 ! PLExp + Int_BufSz = Int_BufSz + 1 ! IW_WriteOutput allocated yes/no + IF ( ALLOCATED(InData%IW_WriteOutput) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! IW_WriteOutput upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%IW_WriteOutput) ! IW_WriteOutput + 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 + 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 AD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%AD, ErrStat2, ErrMsg2, OnlySize ) ! AD + 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%HHVel) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%HHVel,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HHVel,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%HHVel,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HHVel,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%HHVel,2), UBOUND(InData%HHVel,2) + DO i1 = LBOUND(InData%HHVel,1), UBOUND(InData%HHVel,1) + ReKiBuf(Re_Xferred) = InData%HHVel(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + ReKiBuf(Re_Xferred) = InData%PLExp + Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%IW_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%IW_WriteOutput,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IW_WriteOutput,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%IW_WriteOutput,1), UBOUND(InData%IW_WriteOutput,1) + ReKiBuf(Re_Xferred) = InData%IW_WriteOutput(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 ADI_PackOutput + + SUBROUTINE ADI_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(ADI_OutputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_UnPackOutput' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL AD_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%AD, ErrStat2, ErrMsg2 ) ! AD + 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 ! HHVel not allocated + Int_Xferred = Int_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%HHVel)) DEALLOCATE(OutData%HHVel) + ALLOCATE(OutData%HHVel(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%HHVel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%HHVel,2), UBOUND(OutData%HHVel,2) + DO i1 = LBOUND(OutData%HHVel,1), UBOUND(OutData%HHVel,1) + OutData%HHVel(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + OutData%PLExp = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IW_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%IW_WriteOutput)) DEALLOCATE(OutData%IW_WriteOutput) + ALLOCATE(OutData%IW_WriteOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IW_WriteOutput.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%IW_WriteOutput,1), UBOUND(OutData%IW_WriteOutput,1) + OutData%IW_WriteOutput(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 ADI_UnPackOutput + + SUBROUTINE ADI_CopyData( SrcDataData, DstDataData, CtrlCode, ErrStat, ErrMsg ) + TYPE(ADI_Data), INTENT(INOUT) :: SrcDataData + TYPE(ADI_Data), INTENT(INOUT) :: DstDataData + 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 = 'ADI_CopyData' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcDataData%x)) THEN + i1_l = LBOUND(SrcDataData%x,1) + i1_u = UBOUND(SrcDataData%x,1) + IF (.NOT. ALLOCATED(DstDataData%x)) THEN + ALLOCATE(DstDataData%x(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDataData%x.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcDataData%x,1), UBOUND(SrcDataData%x,1) + CALL ADI_CopyContState( SrcDataData%x(i1), DstDataData%x(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcDataData%xd)) THEN + i1_l = LBOUND(SrcDataData%xd,1) + i1_u = UBOUND(SrcDataData%xd,1) + IF (.NOT. ALLOCATED(DstDataData%xd)) THEN + ALLOCATE(DstDataData%xd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDataData%xd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcDataData%xd,1), UBOUND(SrcDataData%xd,1) + CALL ADI_CopyDiscState( SrcDataData%xd(i1), DstDataData%xd(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcDataData%z)) THEN + i1_l = LBOUND(SrcDataData%z,1) + i1_u = UBOUND(SrcDataData%z,1) + IF (.NOT. ALLOCATED(DstDataData%z)) THEN + ALLOCATE(DstDataData%z(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDataData%z.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcDataData%z,1), UBOUND(SrcDataData%z,1) + CALL ADI_CopyConstrState( SrcDataData%z(i1), DstDataData%z(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcDataData%OtherState)) THEN + i1_l = LBOUND(SrcDataData%OtherState,1) + i1_u = UBOUND(SrcDataData%OtherState,1) + IF (.NOT. ALLOCATED(DstDataData%OtherState)) THEN + ALLOCATE(DstDataData%OtherState(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDataData%OtherState.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcDataData%OtherState,1), UBOUND(SrcDataData%OtherState,1) + CALL ADI_CopyOtherState( SrcDataData%OtherState(i1), DstDataData%OtherState(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL ADI_CopyParam( SrcDataData%p, DstDataData%p, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL ADI_CopyMisc( SrcDataData%m, DstDataData%m, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcDataData%u)) THEN + i1_l = LBOUND(SrcDataData%u,1) + i1_u = UBOUND(SrcDataData%u,1) + IF (.NOT. ALLOCATED(DstDataData%u)) THEN + ALLOCATE(DstDataData%u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDataData%u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcDataData%u,1), UBOUND(SrcDataData%u,1) + CALL ADI_CopyInput( SrcDataData%u(i1), DstDataData%u(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL ADI_CopyOutput( SrcDataData%y, DstDataData%y, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcDataData%inputTimes)) THEN + i1_l = LBOUND(SrcDataData%inputTimes,1) + i1_u = UBOUND(SrcDataData%inputTimes,1) + IF (.NOT. ALLOCATED(DstDataData%inputTimes)) THEN + ALLOCATE(DstDataData%inputTimes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDataData%inputTimes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstDataData%inputTimes = SrcDataData%inputTimes +ENDIF + END SUBROUTINE ADI_CopyData + + SUBROUTINE ADI_DestroyData( DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(ADI_Data), INTENT(INOUT) :: DataData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyData' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(DataData%x)) THEN +DO i1 = LBOUND(DataData%x,1), UBOUND(DataData%x,1) + CALL ADI_DestroyContState( DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(DataData%x) +ENDIF +IF (ALLOCATED(DataData%xd)) THEN +DO i1 = LBOUND(DataData%xd,1), UBOUND(DataData%xd,1) + CALL ADI_DestroyDiscState( DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(DataData%xd) +ENDIF +IF (ALLOCATED(DataData%z)) THEN +DO i1 = LBOUND(DataData%z,1), UBOUND(DataData%z,1) + CALL ADI_DestroyConstrState( DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(DataData%z) +ENDIF +IF (ALLOCATED(DataData%OtherState)) THEN +DO i1 = LBOUND(DataData%OtherState,1), UBOUND(DataData%OtherState,1) + CALL ADI_DestroyOtherState( DataData%OtherState(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(DataData%OtherState) +ENDIF + CALL ADI_DestroyParam( DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ADI_DestroyMisc( DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(DataData%u)) THEN +DO i1 = LBOUND(DataData%u,1), UBOUND(DataData%u,1) + CALL ADI_DestroyInput( DataData%u(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(DataData%u) +ENDIF + CALL ADI_DestroyOutput( DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(DataData%inputTimes)) THEN + DEALLOCATE(DataData%inputTimes) +ENDIF + END SUBROUTINE ADI_DestroyData + + SUBROUTINE ADI_PackData( 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(ADI_Data), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_PackData' + ! 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 ! x allocated yes/no + IF ( ALLOCATED(InData%x) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! x upper/lower bounds for each dimension + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%x,1), UBOUND(InData%x,1) + Int_BufSz = Int_BufSz + 3 ! x: size of buffers for each call to pack subtype + CALL ADI_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x(i1), ErrStat2, ErrMsg2, .TRUE. ) ! x + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! x + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! x + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! x + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! xd allocated yes/no + IF ( ALLOCATED(InData%xd) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! xd upper/lower bounds for each dimension + DO i1 = LBOUND(InData%xd,1), UBOUND(InData%xd,1) + Int_BufSz = Int_BufSz + 3 ! xd: size of buffers for each call to pack subtype + CALL ADI_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd(i1), ErrStat2, ErrMsg2, .TRUE. ) ! xd + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! xd + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! xd + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! xd + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! z allocated yes/no + IF ( ALLOCATED(InData%z) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! z upper/lower bounds for each dimension + DO i1 = LBOUND(InData%z,1), UBOUND(InData%z,1) + Int_BufSz = Int_BufSz + 3 ! z: size of buffers for each call to pack subtype + CALL ADI_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z(i1), ErrStat2, ErrMsg2, .TRUE. ) ! z + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! z + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! z + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! z + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! OtherState allocated yes/no + IF ( ALLOCATED(InData%OtherState) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! OtherState upper/lower bounds for each dimension + DO i1 = LBOUND(InData%OtherState,1), UBOUND(InData%OtherState,1) + Int_BufSz = Int_BufSz + 3 ! OtherState: size of buffers for each call to pack subtype + CALL ADI_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherState(i1), ErrStat2, ErrMsg2, .TRUE. ) ! OtherState + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! OtherState + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! OtherState + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! OtherState + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! p: size of buffers for each call to pack subtype + CALL ADI_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, .TRUE. ) ! p + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! p + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! p + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! p + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! m: size of buffers for each call to pack subtype + CALL ADI_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, .TRUE. ) ! m + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! m + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! m + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! m + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! u allocated yes/no + IF ( ALLOCATED(InData%u) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! u upper/lower bounds for each dimension + DO i1 = LBOUND(InData%u,1), UBOUND(InData%u,1) + Int_BufSz = Int_BufSz + 3 ! u: size of buffers for each call to pack subtype + CALL ADI_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u(i1), ErrStat2, ErrMsg2, .TRUE. ) ! u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! u + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! u + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! u + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! y: size of buffers for each call to pack subtype + CALL ADI_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, .TRUE. ) ! y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! y + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! y + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! y + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! inputTimes allocated yes/no + IF ( ALLOCATED(InData%inputTimes) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! inputTimes upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%inputTimes) ! inputTimes + END IF + 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%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%x,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%x,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%x,1), UBOUND(InData%x,1) + CALL ADI_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%x(i1), ErrStat2, ErrMsg2, OnlySize ) ! x + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF + IF ( .NOT. ALLOCATED(InData%xd) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%xd,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%xd,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%xd,1), UBOUND(InData%xd,1) + CALL ADI_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%xd(i1), ErrStat2, ErrMsg2, OnlySize ) ! xd + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF + IF ( .NOT. ALLOCATED(InData%z) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%z,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%z,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%z,1), UBOUND(InData%z,1) + CALL ADI_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%z(i1), ErrStat2, ErrMsg2, OnlySize ) ! z + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF + IF ( .NOT. ALLOCATED(InData%OtherState) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%OtherState,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%OtherState,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%OtherState,1), UBOUND(InData%OtherState,1) + CALL ADI_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%OtherState(i1), ErrStat2, ErrMsg2, OnlySize ) ! OtherState + 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 ADI_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%p, ErrStat2, ErrMsg2, OnlySize ) ! p + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL ADI_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%m, ErrStat2, ErrMsg2, OnlySize ) ! m + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF ( .NOT. ALLOCATED(InData%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%u,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%u,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%u,1), UBOUND(InData%u,1) + CALL ADI_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u(i1), ErrStat2, ErrMsg2, OnlySize ) ! u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF + CALL ADI_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y, ErrStat2, ErrMsg2, OnlySize ) ! y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF ( .NOT. ALLOCATED(InData%inputTimes) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%inputTimes,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%inputTimes,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%inputTimes,1), UBOUND(InData%inputTimes,1) + DbKiBuf(Db_Xferred) = InData%inputTimes(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE ADI_PackData + + SUBROUTINE ADI_UnPackData( 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(ADI_Data), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_UnPackData' + ! 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 ! 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%x)) DEALLOCATE(OutData%x) + ALLOCATE(OutData%x(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%x.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%x,1), UBOUND(OutData%x,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL ADI_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%x(i1), ErrStat2, ErrMsg2 ) ! x + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! xd not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%xd)) DEALLOCATE(OutData%xd) + ALLOCATE(OutData%xd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%xd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%xd,1), UBOUND(OutData%xd,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL ADI_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%xd(i1), ErrStat2, ErrMsg2 ) ! xd + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! z not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%z)) DEALLOCATE(OutData%z) + ALLOCATE(OutData%z(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%z.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%z,1), UBOUND(OutData%z,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL ADI_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%z(i1), ErrStat2, ErrMsg2 ) ! z + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OtherState not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%OtherState)) DEALLOCATE(OutData%OtherState) + ALLOCATE(OutData%OtherState(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OtherState.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%OtherState,1), UBOUND(OutData%OtherState,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 ADI_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%OtherState(i1), ErrStat2, ErrMsg2 ) ! OtherState + 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 ADI_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%p, ErrStat2, ErrMsg2 ) ! p + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL ADI_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%m, ErrStat2, ErrMsg2 ) ! m + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! 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%u)) DEALLOCATE(OutData%u) + ALLOCATE(OutData%u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%u,1), UBOUND(OutData%u,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 ADI_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u(i1), ErrStat2, ErrMsg2 ) ! u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + 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 ADI_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y, ErrStat2, ErrMsg2 ) ! y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! inputTimes not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%inputTimes)) DEALLOCATE(OutData%inputTimes) + ALLOCATE(OutData%inputTimes(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%inputTimes.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%inputTimes,1), UBOUND(OutData%inputTimes,1) + OutData%inputTimes(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE ADI_UnPackData + + SUBROUTINE ADI_CopyRotFED( SrcRotFEDData, DstRotFEDData, CtrlCode, ErrStat, ErrMsg ) + TYPE(RotFED), INTENT(INOUT) :: SrcRotFEDData + TYPE(RotFED), INTENT(INOUT) :: DstRotFEDData + 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 = 'ADI_CopyRotFED' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL MeshCopy( SrcRotFEDData%PlatformPtMesh, DstRotFEDData%PlatformPtMesh, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcRotFEDData%TwrPtMesh, DstRotFEDData%TwrPtMesh, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcRotFEDData%TwrPtMeshAD, DstRotFEDData%TwrPtMeshAD, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcRotFEDData%NacelleMotion, DstRotFEDData%NacelleMotion, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcRotFEDData%HubPtMotion, DstRotFEDData%HubPtMotion, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcRotFEDData%BladeRootMotion)) THEN + i1_l = LBOUND(SrcRotFEDData%BladeRootMotion,1) + i1_u = UBOUND(SrcRotFEDData%BladeRootMotion,1) + IF (.NOT. ALLOCATED(DstRotFEDData%BladeRootMotion)) THEN + ALLOCATE(DstRotFEDData%BladeRootMotion(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotFEDData%BladeRootMotion.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcRotFEDData%BladeRootMotion,1), UBOUND(SrcRotFEDData%BladeRootMotion,1) + CALL MeshCopy( SrcRotFEDData%BladeRootMotion(i1), DstRotFEDData%BladeRootMotion(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcRotFEDData%BladeLn2Mesh)) THEN + i1_l = LBOUND(SrcRotFEDData%BladeLn2Mesh,1) + i1_u = UBOUND(SrcRotFEDData%BladeLn2Mesh,1) + IF (.NOT. ALLOCATED(DstRotFEDData%BladeLn2Mesh)) THEN + ALLOCATE(DstRotFEDData%BladeLn2Mesh(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotFEDData%BladeLn2Mesh.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcRotFEDData%BladeLn2Mesh,1), UBOUND(SrcRotFEDData%BladeLn2Mesh,1) + CALL MeshCopy( SrcRotFEDData%BladeLn2Mesh(i1), DstRotFEDData%BladeLn2Mesh(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + DstRotFEDData%hasTower = SrcRotFEDData%hasTower + DstRotFEDData%rigidBlades = SrcRotFEDData%rigidBlades + DstRotFEDData%numBlades = SrcRotFEDData%numBlades + CALL NWTC_Library_Copymeshmaptype( SrcRotFEDData%ED_P_2_AD_P_T, DstRotFEDData%ED_P_2_AD_P_T, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL NWTC_Library_Copymeshmaptype( SrcRotFEDData%AD_P_2_AD_L_T, DstRotFEDData%AD_P_2_AD_L_T, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcRotFEDData%AD_P_2_AD_L_B)) THEN + i1_l = LBOUND(SrcRotFEDData%AD_P_2_AD_L_B,1) + i1_u = UBOUND(SrcRotFEDData%AD_P_2_AD_L_B,1) + IF (.NOT. ALLOCATED(DstRotFEDData%AD_P_2_AD_L_B)) THEN + ALLOCATE(DstRotFEDData%AD_P_2_AD_L_B(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotFEDData%AD_P_2_AD_L_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcRotFEDData%AD_P_2_AD_L_B,1), UBOUND(SrcRotFEDData%AD_P_2_AD_L_B,1) + CALL NWTC_Library_Copymeshmaptype( SrcRotFEDData%AD_P_2_AD_L_B(i1), DstRotFEDData%AD_P_2_AD_L_B(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL NWTC_Library_Copymeshmaptype( SrcRotFEDData%ED_P_2_AD_P_TF, DstRotFEDData%ED_P_2_AD_P_TF, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcRotFEDData%ED_P_2_AD_P_R)) THEN + i1_l = LBOUND(SrcRotFEDData%ED_P_2_AD_P_R,1) + i1_u = UBOUND(SrcRotFEDData%ED_P_2_AD_P_R,1) + IF (.NOT. ALLOCATED(DstRotFEDData%ED_P_2_AD_P_R)) THEN + ALLOCATE(DstRotFEDData%ED_P_2_AD_P_R(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotFEDData%ED_P_2_AD_P_R.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcRotFEDData%ED_P_2_AD_P_R,1), UBOUND(SrcRotFEDData%ED_P_2_AD_P_R,1) + CALL NWTC_Library_Copymeshmaptype( SrcRotFEDData%ED_P_2_AD_P_R(i1), DstRotFEDData%ED_P_2_AD_P_R(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL NWTC_Library_Copymeshmaptype( SrcRotFEDData%ED_P_2_AD_P_H, DstRotFEDData%ED_P_2_AD_P_H, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL NWTC_Library_Copymeshmaptype( SrcRotFEDData%ED_P_2_AD_P_N, DstRotFEDData%ED_P_2_AD_P_N, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE ADI_CopyRotFED + + SUBROUTINE ADI_DestroyRotFED( RotFEDData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(RotFED), INTENT(INOUT) :: RotFEDData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyRotFED' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( RotFEDData%PlatformPtMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( RotFEDData%TwrPtMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( RotFEDData%TwrPtMeshAD, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( RotFEDData%NacelleMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( RotFEDData%HubPtMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(RotFEDData%BladeRootMotion)) THEN +DO i1 = LBOUND(RotFEDData%BladeRootMotion,1), UBOUND(RotFEDData%BladeRootMotion,1) + CALL MeshDestroy( RotFEDData%BladeRootMotion(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(RotFEDData%BladeRootMotion) +ENDIF +IF (ALLOCATED(RotFEDData%BladeLn2Mesh)) THEN +DO i1 = LBOUND(RotFEDData%BladeLn2Mesh,1), UBOUND(RotFEDData%BladeLn2Mesh,1) + CALL MeshDestroy( RotFEDData%BladeLn2Mesh(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(RotFEDData%BladeLn2Mesh) +ENDIF + CALL NWTC_Library_Destroymeshmaptype( RotFEDData%ED_P_2_AD_P_T, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( RotFEDData%AD_P_2_AD_L_T, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(RotFEDData%AD_P_2_AD_L_B)) THEN +DO i1 = LBOUND(RotFEDData%AD_P_2_AD_L_B,1), UBOUND(RotFEDData%AD_P_2_AD_L_B,1) + CALL NWTC_Library_Destroymeshmaptype( RotFEDData%AD_P_2_AD_L_B(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(RotFEDData%AD_P_2_AD_L_B) +ENDIF + CALL NWTC_Library_Destroymeshmaptype( RotFEDData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(RotFEDData%ED_P_2_AD_P_R)) THEN +DO i1 = LBOUND(RotFEDData%ED_P_2_AD_P_R,1), UBOUND(RotFEDData%ED_P_2_AD_P_R,1) + CALL NWTC_Library_Destroymeshmaptype( RotFEDData%ED_P_2_AD_P_R(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(RotFEDData%ED_P_2_AD_P_R) +ENDIF + CALL NWTC_Library_Destroymeshmaptype( RotFEDData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( RotFEDData%ED_P_2_AD_P_N, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE ADI_DestroyRotFED + + SUBROUTINE ADI_PackRotFED( 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(RotFED), 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 = 'ADI_PackRotFED' + ! 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 ! PlatformPtMesh: size of buffers for each call to pack subtype + CALL MeshPack( InData%PlatformPtMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! PlatformPtMesh + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! PlatformPtMesh + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! PlatformPtMesh + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! PlatformPtMesh + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! TwrPtMesh: size of buffers for each call to pack subtype + CALL MeshPack( InData%TwrPtMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! TwrPtMesh + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! TwrPtMesh + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! TwrPtMesh + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! TwrPtMesh + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! TwrPtMeshAD: size of buffers for each call to pack subtype + CALL MeshPack( InData%TwrPtMeshAD, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! TwrPtMeshAD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! TwrPtMeshAD + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! TwrPtMeshAD + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! TwrPtMeshAD + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! NacelleMotion: size of buffers for each call to pack subtype + CALL MeshPack( InData%NacelleMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! NacelleMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! NacelleMotion + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! NacelleMotion + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! NacelleMotion + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! HubPtMotion: size of buffers for each call to pack subtype + CALL MeshPack( InData%HubPtMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! HubPtMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! HubPtMotion + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! HubPtMotion + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! HubPtMotion + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! BladeRootMotion allocated yes/no + IF ( ALLOCATED(InData%BladeRootMotion) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BladeRootMotion upper/lower bounds for each dimension + DO i1 = LBOUND(InData%BladeRootMotion,1), UBOUND(InData%BladeRootMotion,1) + Int_BufSz = Int_BufSz + 3 ! BladeRootMotion: size of buffers for each call to pack subtype + CALL MeshPack( InData%BladeRootMotion(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! BladeRootMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BladeRootMotion + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BladeRootMotion + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BladeRootMotion + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! BladeLn2Mesh allocated yes/no + IF ( ALLOCATED(InData%BladeLn2Mesh) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BladeLn2Mesh upper/lower bounds for each dimension + DO i1 = LBOUND(InData%BladeLn2Mesh,1), UBOUND(InData%BladeLn2Mesh,1) + Int_BufSz = Int_BufSz + 3 ! BladeLn2Mesh: size of buffers for each call to pack subtype + CALL MeshPack( InData%BladeLn2Mesh(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! BladeLn2Mesh + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BladeLn2Mesh + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BladeLn2Mesh + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BladeLn2Mesh + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! hasTower + Int_BufSz = Int_BufSz + 1 ! rigidBlades + Int_BufSz = Int_BufSz + 1 ! numBlades + Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_T: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_T, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_T + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_T + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_T + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_T + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! AD_P_2_AD_L_T: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_AD_L_T, ErrStat2, ErrMsg2, .TRUE. ) ! AD_P_2_AD_L_T + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD_P_2_AD_L_T + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD_P_2_AD_L_T + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD_P_2_AD_L_T + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! AD_P_2_AD_L_B allocated yes/no + IF ( ALLOCATED(InData%AD_P_2_AD_L_B) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AD_P_2_AD_L_B upper/lower bounds for each dimension + DO i1 = LBOUND(InData%AD_P_2_AD_L_B,1), UBOUND(InData%AD_P_2_AD_L_B,1) + Int_BufSz = Int_BufSz + 3 ! AD_P_2_AD_L_B: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_AD_L_B(i1), ErrStat2, ErrMsg2, .TRUE. ) ! AD_P_2_AD_L_B + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD_P_2_AD_L_B + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD_P_2_AD_L_B + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD_P_2_AD_L_B + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_TF: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_TF + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_TF + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_TF + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_TF + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! ED_P_2_AD_P_R allocated yes/no + IF ( ALLOCATED(InData%ED_P_2_AD_P_R) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ED_P_2_AD_P_R upper/lower bounds for each dimension + DO i1 = LBOUND(InData%ED_P_2_AD_P_R,1), UBOUND(InData%ED_P_2_AD_P_R,1) + Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_R: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_R(i1), ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_R + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_R + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_R + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_R + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_H: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_H + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_H + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_H + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_H + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! ED_P_2_AD_P_N: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_N, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_N + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_N + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_N + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_N + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + CALL MeshPack( InData%PlatformPtMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! PlatformPtMesh + 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%TwrPtMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! TwrPtMesh + 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%TwrPtMeshAD, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! TwrPtMeshAD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL MeshPack( InData%NacelleMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! NacelleMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL MeshPack( InData%HubPtMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! HubPtMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF ( .NOT. ALLOCATED(InData%BladeRootMotion) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeRootMotion,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootMotion,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BladeRootMotion,1), UBOUND(InData%BladeRootMotion,1) + CALL MeshPack( InData%BladeRootMotion(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! BladeRootMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BladeLn2Mesh) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeLn2Mesh,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeLn2Mesh,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BladeLn2Mesh,1), UBOUND(InData%BladeLn2Mesh,1) + CALL MeshPack( InData%BladeLn2Mesh(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! BladeLn2Mesh + 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) = TRANSFER(InData%hasTower, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%rigidBlades, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%numBlades + Int_Xferred = Int_Xferred + 1 + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_T, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_T + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_AD_L_T, ErrStat2, ErrMsg2, OnlySize ) ! AD_P_2_AD_L_T + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF ( .NOT. ALLOCATED(InData%AD_P_2_AD_L_B) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AD_P_2_AD_L_B,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AD_P_2_AD_L_B,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AD_P_2_AD_L_B,1), UBOUND(InData%AD_P_2_AD_L_B,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_AD_L_B(i1), ErrStat2, ErrMsg2, OnlySize ) ! AD_P_2_AD_L_B + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_TF + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF ( .NOT. ALLOCATED(InData%ED_P_2_AD_P_R) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ED_P_2_AD_P_R,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ED_P_2_AD_P_R,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ED_P_2_AD_P_R,1), UBOUND(InData%ED_P_2_AD_P_R,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_R(i1), ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_R + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_H + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_N, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_N + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + 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 ADI_PackRotFED + + SUBROUTINE ADI_UnPackRotFED( 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(RotFED), 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 = 'ADI_UnPackRotFED' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MeshUnpack( OutData%PlatformPtMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! PlatformPtMesh + 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%TwrPtMesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! TwrPtMesh + 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%TwrPtMeshAD, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! TwrPtMeshAD + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MeshUnpack( OutData%NacelleMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! NacelleMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + 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%HubPtMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! HubPtMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeRootMotion not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BladeRootMotion)) DEALLOCATE(OutData%BladeRootMotion) + ALLOCATE(OutData%BladeRootMotion(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeRootMotion.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BladeRootMotion,1), UBOUND(OutData%BladeRootMotion,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MeshUnpack( OutData%BladeRootMotion(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeRootMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeLn2Mesh not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BladeLn2Mesh)) DEALLOCATE(OutData%BladeLn2Mesh) + ALLOCATE(OutData%BladeLn2Mesh(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeLn2Mesh.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BladeLn2Mesh,1), UBOUND(OutData%BladeLn2Mesh,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%BladeLn2Mesh(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeLn2Mesh + 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%hasTower = TRANSFER(IntKiBuf(Int_Xferred), OutData%hasTower) + Int_Xferred = Int_Xferred + 1 + OutData%rigidBlades = TRANSFER(IntKiBuf(Int_Xferred), OutData%rigidBlades) + Int_Xferred = Int_Xferred + 1 + OutData%numBlades = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_T, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_T + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_P_2_AD_L_T, ErrStat2, ErrMsg2 ) ! AD_P_2_AD_L_T + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AD_P_2_AD_L_B not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AD_P_2_AD_L_B)) DEALLOCATE(OutData%AD_P_2_AD_L_B) + ALLOCATE(OutData%AD_P_2_AD_L_B(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AD_P_2_AD_L_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AD_P_2_AD_L_B,1), UBOUND(OutData%AD_P_2_AD_L_B,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_P_2_AD_L_B(i1), ErrStat2, ErrMsg2 ) ! AD_P_2_AD_L_B + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + 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_AD_P_TF, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_TF + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ED_P_2_AD_P_R not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ED_P_2_AD_P_R)) DEALLOCATE(OutData%ED_P_2_AD_P_R) + ALLOCATE(OutData%ED_P_2_AD_P_R(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ED_P_2_AD_P_R.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ED_P_2_AD_P_R,1), UBOUND(OutData%ED_P_2_AD_P_R,1) + 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_AD_P_R(i1), ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_R + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + 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_AD_P_H, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_H + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_N, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_N + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END SUBROUTINE ADI_UnPackRotFED + + SUBROUTINE ADI_CopyFED_Data( SrcFED_DataData, DstFED_DataData, CtrlCode, ErrStat, ErrMsg ) + TYPE(FED_Data), INTENT(INOUT) :: SrcFED_DataData + TYPE(FED_Data), INTENT(INOUT) :: DstFED_DataData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_CopyFED_Data' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcFED_DataData%WT)) THEN + i1_l = LBOUND(SrcFED_DataData%WT,1) + i1_u = UBOUND(SrcFED_DataData%WT,1) + IF (.NOT. ALLOCATED(DstFED_DataData%WT)) THEN + ALLOCATE(DstFED_DataData%WT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstFED_DataData%WT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcFED_DataData%WT,1), UBOUND(SrcFED_DataData%WT,1) + CALL ADI_Copyrotfed( SrcFED_DataData%WT(i1), DstFED_DataData%WT(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + END SUBROUTINE ADI_CopyFED_Data + + SUBROUTINE ADI_DestroyFED_Data( FED_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(FED_Data), INTENT(INOUT) :: FED_DataData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_DestroyFED_Data' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(FED_DataData%WT)) THEN +DO i1 = LBOUND(FED_DataData%WT,1), UBOUND(FED_DataData%WT,1) + CALL ADI_Destroyrotfed( FED_DataData%WT(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(FED_DataData%WT) +ENDIF + END SUBROUTINE ADI_DestroyFED_Data + + SUBROUTINE ADI_PackFED_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(FED_Data), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_PackFED_Data' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! WT allocated yes/no + IF ( ALLOCATED(InData%WT) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! WT upper/lower bounds for each dimension + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%WT,1), UBOUND(InData%WT,1) + Int_BufSz = Int_BufSz + 3 ! WT: size of buffers for each call to pack subtype + CALL ADI_Packrotfed( Re_Buf, Db_Buf, Int_Buf, InData%WT(i1), ErrStat2, ErrMsg2, .TRUE. ) ! WT + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! WT + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! WT + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! WT + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IF ( .NOT. ALLOCATED(InData%WT) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WT,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WT,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%WT,1), UBOUND(InData%WT,1) + CALL ADI_Packrotfed( Re_Buf, Db_Buf, Int_Buf, InData%WT(i1), ErrStat2, ErrMsg2, OnlySize ) ! WT + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + END IF + END SUBROUTINE ADI_PackFED_Data + + SUBROUTINE ADI_UnPackFED_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(FED_Data), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ADI_UnPackFED_Data' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WT not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WT)) DEALLOCATE(OutData%WT) + ALLOCATE(OutData%WT(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WT.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WT,1), UBOUND(OutData%WT,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 ADI_Unpackrotfed( Re_Buf, Db_Buf, Int_Buf, OutData%WT(i1), ErrStat2, ErrMsg2 ) ! WT + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + END SUBROUTINE ADI_UnPackFED_Data + +END MODULE AeroDyn_Inflow_Types +!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/aerodyn/src/AeroDyn_Registry.txt b/modules/aerodyn/src/AeroDyn_Registry.txt index 3b32ea94f..441e24f6a 100644 --- a/modules/aerodyn/src/AeroDyn_Registry.txt +++ b/modules/aerodyn/src/AeroDyn_Registry.txt @@ -34,6 +34,44 @@ param ^ - IntKi TwrShadow_none - 0 - "no tower s param ^ - IntKi TwrShadow_Powles - 1 - "Powles tower shadow model" - param ^ - IntKi TwrShadow_Eames - 2 - "Eames tower shadow model" - +param ^ - IntKi TFinAero_none - 0 - "no tail fin aero" - +param ^ - IntKi TFinAero_polar - 1 - "polar-based tail fin aerodynamics" - +param ^ - IntKi TFinAero_USB - 2 - "unsteady slender body tail fin aerodynamics model" - + +param ^ - IntKi TFinIndMod_none - 0 - "no induction" - +param ^ - IntKi TFinIndMod_rotavg - 1 - "rotor averaged induction" - +# AeroProjMod (APM) +param ^ - IntKi APM_BEM_NoSweepPitchTwist - 1 - "Original AeroDyn model where momentum balance is done in the WithoutSweepPitchTwist system" - +param ^ - IntKi APM_BEM_Polar - 2 - "Use staggered polar grid for momentum balance in each annulus" - +param ^ - IntKi APM_LiftingLine - 3 - "Use the blade lifting line (i.e. the structural) orientation (currently for OLAF with VAWT)" - +# if more than AD_MaxBl_Out blades are used in the simulation, not all channels will have output information for the "extra" blades. +# Also, the AD input file will require more lines for the additional blades. +param ^ - IntKi AD_MaxBl_Out - 3 - "Maximum number of blades for information output (or linearization)" - + +# Tail Fin parameters +typedef ^ TFinParameterType IntKi TFinMod - - 0 "Tail fin aerodynamics model {0=none, 1=polar-based, 2=USB-based}" (switch) +typedef ^ TFinParameterType ReKi TFinChord - - - "Tail fin chord [used only when TFinMod=1]" m +typedef ^ TFinParameterType ReKi TFinArea - - - "Tail fin planform area [used only when TFinMod=1]" m^2 +typedef ^ TFinParameterType IntKi TFinIndMod - - - "Model for induced velocity calculation {0=none, 1=rotor-average}" (switch) +typedef ^ TFinParameterType IntKi TFinAFID - - - "Index of Tail fin airfoil number [1 to NumAFfiles]" - + +# Tail Fin input file +typedef ^ TFinInputFileType IntKi TFinMod - - 0 "Tail fin aerodynamics model {0=none, 1=polar-based, 2=USB-based}" (switch) +typedef ^ TFinInputFileType ReKi TFinChord - - - "Tail fin chord [used only when TFinMod=1]" m +typedef ^ TFinInputFileType ReKi TFinArea - - - "Tail fin planform area [used only when TFinMod=1]" m^2 +typedef ^ TFinInputFileType ReKi TFinRefP_n 3 - - "Undeflected position of the tail fin reference point wrt the tower top" m +typedef ^ TFinInputFileType ReKi TFinAngles 3 - - "Tail fin chordline skew, tilt, and bank angles about the reference point" (deg) +typedef ^ TFinInputFileType IntKi TFinIndMod - - - "Model for induced velocity calculation {0=none, 1=rotor-average}" (switch) +typedef ^ TFinInputFileType IntKi TFinAFID - - - "Index of Tail fin airfoil number [1 to NumAFfiles]" - + + + +typedef ^ AD_VTK_BLSurfaceType SiKi AirfoilCoords {:}{:}{:} - - "x,y coordinates for airfoil around each blade node on a blade (relative to reference)" - + +typedef ^ AD_VTK_RotSurfaceType AD_VTK_BLSurfaceType BladeShape {:} - - "AirfoilCoords for each blade" - +typedef ^ ^ SiKi TowerRad {:} - - "radius of each ED tower node" m + + # ..... Initialization data ....................................................................................................... # Define inputs that the initialization routine may need here: @@ -44,7 +82,8 @@ typedef ^ RotInitInputType ReKi BladeRootPosition {:}{:} - - "X-Y-Z reference po typedef ^ RotInitInputType R8Ki BladeRootOrientation {:}{:}{:} - - "DCM reference orientation of blade roots (3x3 x NumBlades)" - typedef ^ RotInitInputType R8Ki NacellePosition {3} - - "X-Y-Z reference position of nacelle" m typedef ^ RotInitInputType R8Ki NacelleOrientation {3}{3} - - "DCM reference orientation of nacelle" - -typedef ^ RotInitInputType IntKi AeroProjMod - 0 - "Flag to switch between different projection models" - +typedef ^ RotInitInputType IntKi AeroProjMod - 1 - "Flag to switch between different projection models" - +typedef ^ RotInitInputType IntKi AeroBEM_Mod - -1 - "Flag to switch between different BEM Model" - typedef ^ InitInputType RotInitInputType rotors {:} - - "Init Input Types for rotors" - typedef ^ InitInputType CHARACTER(1024) InputFile - - - "Name of the input file" - @@ -62,7 +101,6 @@ typedef ^ InitInputType ReKi defPvap - - - "Default vapor press typedef ^ InitInputType ReKi WtrDpth - - - "Water depth" m typedef ^ InitInputType ReKi MSL2SWL - - - "Offset between still-water level and mean sea level" m - # This is data defined in the Input File for this module (or could otherwise be passed in) # ..... Blade Input file data ..................................................................................................... typedef ^ AD_BladePropsType IntKi NumBlNds - - - "Number of blade nodes used in the analysis" - @@ -73,6 +111,9 @@ typedef ^ AD_BladePropsType ReKi BlCrvAng {:} - - "Curve angle at blade node" ra typedef ^ AD_BladePropsType ReKi BlTwist {:} - - "Twist at blade node" radians typedef ^ AD_BladePropsType ReKi BlChord {:} - - "Chord at blade node" m typedef ^ AD_BladePropsType IntKi BlAFID {:} - - "ID of Airfoil at blade node" - +typedef ^ AD_BladePropsType ReKi BlCb {:} - - "Coefficient of buoyancy at blade node" - +typedef ^ AD_BladePropsType ReKi BlCenBn {:} - - "Center of buoyancy normal offset at blade node" m +typedef ^ AD_BladePropsType ReKi BlCenBt {:} - - "Center of buoyancy tangential offset at blade node" m # Define outputs from the initialization routine here: typedef ^ AD_BladeShape SiKi AirfoilCoords {:}{:}{:} - - "x-y coordinates for airfoils, relative to node" m @@ -106,6 +147,17 @@ typedef ^ RotInputFile ReKi TwrElev {:} - - "Elevation at tower node" m typedef ^ RotInputFile ReKi TwrDiam {:} - - "Diameter of tower at node" m typedef ^ RotInputFile ReKi TwrCd {:} - - "Coefficient of drag at tower node" - typedef ^ RotInputFile ReKi TwrTI {:} - - "Turbulence intensity for tower shadow at tower node" - +typedef ^ RotInputFile ReKi TwrCb {:} - - "Coefficient of buoyancy at tower node" - +# Hub +typedef ^ RotInputFile ReKi VolHub - - - "Hub volume" m^3 +typedef ^ RotInputFile ReKi HubCenBx - - - "Hub center of buoyancy x direction offset" m +# Nacelle +typedef ^ RotInputFile ReKi VolNac - - - "Nacelle volume" m^3 +typedef ^ RotInputFile ReKi NacCenB 3 - - "Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates" m +# TailFin +typedef ^ RotInputFile LOGICAL TFinAero - .FALSE. - "Calculate tail fin aerodynamics model (flag)" flag +typedef ^ RotInputFile CHARACTER(1024) TFinFile - - - "Input file for tail fin aerodynamics [used only when TFinAero=True]" - +typedef ^ RotInputFile TFinInputFileType TFin - - - "Input file data for tail fin" - typedef ^ AD_InputFile Logical Echo - - - "Echo input file to echo file" - typedef ^ AD_InputFile DbKi DTAero - - - "Time interval for aerodynamic calculations {or "default"}" s @@ -116,6 +168,7 @@ typedef ^ AD_InputFile IntKi TwrShadow - - - "Type of tower influence on wind ba 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 Buoyancy - - - "Include buoyancy effects?" flag 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" @@ -166,6 +219,8 @@ typedef ^ AD_InputFile ReKi UAEndRad - - - Ending radius fo typedef ^ AD_InputFile RotInputFile rotors {:} - - "Rotor (blades and tower) input file data" - + + # ..... States .................................................................................................................... # Define continuous (differentiable) states here: typedef ^ RotContinuousStateType BEMT_ContinuousStateType BEMT - - - "Continuous states from the BEMT module" - @@ -207,7 +262,7 @@ typedef ^ RotMiscVarType AA_OutputType AA_y - - - "Outputs from the AA module" - typedef ^ RotMiscVarType AA_InputType AA_u - - - "Inputs to the AA module" - typedef ^ RotMiscVarType ReKi DisturbedInflow {:}{:}{:} - - "InflowOnBlade values modified by tower influence" m/s -typedef ^ RotMiscVarType ReKi WithoutSweepPitchTwist {:}{:}{:}{:} - - "Coordinate system equivalent to BladeMotion Orientation, but without live sweep, blade-pitch, and twist angles" - +typedef ^ RotMiscVarType R8Ki orientationAnnulus {:}{:}{:}{:} - - "Coordinate system equivalent to BladeMotion Orientation, but without live sweep, blade-pitch, and twist angles" - typedef ^ RotMiscVarType ReKi AllOuts {:} - - "An array holding the value of all of the calculated (not only selected) output channels" - typedef ^ RotMiscVarType ReKi W_Twr {:} - - "relative wind speed normal to the tower at node j" m/s typedef ^ RotMiscVarType ReKi X_Twr {:} - - "local x-component of force per unit length of the jth node in the tower" m/s @@ -216,8 +271,14 @@ typedef ^ RotMiscVarType ReKi Curve {:}{:} - - "curvature angle, saved for possi typedef ^ RotMiscVarType ReKi TwrClrnc {:}{:} - - "Distance between tower (including tower radius) and blade node (not including blade width), saved for possible output to file" m typedef ^ RotMiscVarType ReKi X {:}{:} - - "normal force per unit length (normal to the plane, not chord) of the jth node in the kth blade" N/m typedef ^ RotMiscVarType ReKi Y {:}{:} - - "tangential force per unit length (tangential to the plane, not chord) of the jth node in the kth blade" N/m +typedef ^ RotMiscVarType ReKi Z {:}{:} - - "axial force per unit length (tangential to the plane, not chord) of the jth node in the kth blade" N/m typedef ^ RotMiscVarType ReKi M {:}{:} - - "pitching moment per unit length of the jth node in the kth blade" Nm/m +typedef ^ RotMiscVarType ReKi Mx {:}{:} - - "pitching moment per unit length of the jth node in the kth blade (in x direction)" Nm/m +typedef ^ RotMiscVarType ReKi My {:}{:} - - "pitching moment per unit length of the jth node in the kth blade (in y direction)" Nm/m +typedef ^ RotMiscVarType ReKi Mz {:}{:} - - "pitching moment per unit length of the jth node in the kth blade (in z direction)" Nm/m typedef ^ RotMiscVarType ReKi V_DiskAvg {3} - - "disk-average relative wind speed" m/s +typedef ^ RotMiscVarType ReKi yaw - - - "Yaw calculated in SetInputsForBEMT" rad +typedef ^ RotMiscVarType ReKi tilt - - - "tilt calculated in SetInputsForBEMT" rad typedef ^ RotMiscVarType ReKi hub_theta_x_root {:} - - "angles saved for FAST.Farm" rad typedef ^ RotMiscVarType ReKi V_dot_x - - - typedef ^ RotMiscVarType MeshType HubLoad - - - "mesh at hub; used to compute an integral for mapping the output blade loads to a single point (for writing to file only)" - @@ -225,8 +286,35 @@ typedef ^ RotMiscVarType MeshMapType B_L_2_H_P {:} - - "mapping data structure t typedef ^ RotMiscVarType ReKi SigmaCavitCrit {:}{:} - - "critical cavitation number- inception value (above which cavit will occur)" - typedef ^ RotMiscVarType ReKi SigmaCavit {:}{:} - - "cavitation number at node " - typedef ^ RotMiscVarType Logical CavitWarnSet {:}{:} - - "cavitation warning issued " - +typedef ^ RotMiscVarType ReKi BlFB {:}{:}{:} - - "buoyant force per unit length at blade node" N/m +typedef ^ RotMiscVarType ReKi BlMB {:}{:}{:} - - "buoyant moment per unit length at blade node" Nm/m +typedef ^ RotMiscVarType ReKi TwrFB {:}{:} - - "buoyant force per unit length at tower node" N/m +typedef ^ RotMiscVarType ReKi TwrMB {:}{:} - - "buoyant moment per unit length at tower node" Nm/m +typedef ^ RotMiscVarType ReKi HubFB {:} - - "buoyant force at hub node" N +typedef ^ RotMiscVarType ReKi HubMB {:} - - "buoyant moment at hub node" Nm +typedef ^ RotMiscVarType ReKi NacFB {:} - - "buoyant force at nacelle (tower top) node" N +typedef ^ RotMiscVarType ReKi NacMB {:} - - "buoyant moment at nacelle (tower top) node" Nm typedef ^ RotMiscVarType MeshType BladeRootLoad {:} - - "meshes at blade root; used to compute an integral for mapping the output blade loads to single points (for writing to file only)" - typedef ^ RotMiscVarType MeshMapType B_L_2_R_P {:} - - "mapping data structure to map each bladeLoad output mesh to corresponding MiscVar%BladeRootLoad mesh" +typedef ^ RotMiscVarType MeshType BladeBuoyLoadPoint {:} - - "point mesh for lumped buoyant blade loads" - +typedef ^ RotMiscVarType MeshType BladeBuoyLoad {:} - - "line mesh for per unit length buoyant blade loads" - +typedef ^ RotMiscVarType MeshMapType B_P_2_B_L {:} - - "mapping data structure to map buoyant blade point loads (m%BladeBuoyLoadPoint) to buoyant blade line loads (m%BladeBuoyLoad)" +typedef ^ RotMiscVarType MeshType TwrBuoyLoadPoint - - - "point mesh for lumped buoyant tower loads" - +typedef ^ RotMiscVarType MeshType TwrBuoyLoad - - - "line mesh for per unit length buoyant tower loads" - +typedef ^ RotMiscVarType MeshMapType T_P_2_T_L - - - "mapping data structure to map buoyant tower point loads (m%TwrBuoyLoadPoint) to buoyant tower line loads (m%TwrBuoyLoad)" +typedef ^ RotMiscVarType Logical FirstWarn_TowerStrike - - - "flag to avoid printing tower strike multiple times" - +typedef ^ RotMiscVarType ReKi AvgDiskVel {3} - - "disk-averaged U,V,W (undisturbed)" m/s +typedef ^ RotMiscVarType ReKi AvgDiskVelDist {3} - - "disk-averaged U,V,W (disturbed)" m/s +# TailFin +typedef ^ RotMiscVarType ReKi TFinAlpha - - - "Angle of attack for tailfin" +typedef ^ RotMiscVarType ReKi TFinRe - - - "Reynolds number for tailfin" +typedef ^ RotMiscVarType ReKi TFinVrel - - - "Orthogonal relative velocity nrom at the reference point" +typedef ^ RotMiscVarType ReKi TFinVund_i 3 - - "Undisturbed wind velocity at the reference point of the fin in the inertial system" +typedef ^ RotMiscVarType ReKi TFinVind_i 3 - - "Induced velocity at the reference point of the fin in the inertial system" +typedef ^ RotMiscVarType ReKi TFinVrel_i 3 - - "Relative velocity at the reference point of the fin in the inertial system" +typedef ^ RotMiscVarType ReKi TFinSTV_i 3 - - "Structural velocity at the reference point of the fin in the inertial system" +typedef ^ RotMiscVarType ReKi TFinF_i 3 - - "Forces at the reference point of the fin in the inertial system" +typedef ^ RotMiscVarType ReKi TFinM_i 3 - - "Moments at the reference point of the fin in the inertial system" typedef ^ MiscVarType RotMiscVarType rotors {:}- - - "MiscVars for each rotor" - typedef ^ MiscVarType FVW_InputType FVW_u : - - "Inputs to the FVW module" - @@ -235,6 +323,8 @@ typedef ^ MiscVarType FVW_MiscVarType FVW - - - "MiscVars from the FVW module" - # ..... Parameters ................................................................................................................ # Define parameters here: + + # Parameters for each rotor typedef ^ RotParameterType IntKi NumBlades - - - "Number of blades on the turbine" - typedef ^ RotParameterType IntKi NumBlNds - - - "Number of nodes on each blade" - @@ -242,17 +332,39 @@ typedef ^ RotParameterType IntKi NumTwrNds - - - "Number of nodes on the tower" typedef ^ RotParameterType ReKi TwrDiam {:} - - "Diameter of tower at node" m typedef ^ RotParameterType ReKi TwrCd {:} - - "Coefficient of drag at tower node" - typedef ^ RotParameterType ReKi TwrTI {:} - - "Turbulence intensity for tower shadow at tower node" - +typedef ^ ^ ReKi BlTwist {:}{:} - - "Twist at blade node" radians +typedef ^ RotParameterType ReKi TwrCb {:} - - "Coefficient of buoyancy at tower node" - +typedef ^ RotParameterType ReKi BlCenBn {:}{:} - - "Normal offset between aerodynamic center and center of buoyancy at blade node" m +typedef ^ RotParameterType ReKi BlCenBt {:}{:} - - "Tangential offset between aerodynamic center and center of buoyancy at blade node" m +typedef ^ RotParameterType ReKi VolHub - - - "Hub volume" m^3 +typedef ^ RotParameterType ReKi HubCenBx - - - "Hub center of buoyancy x direction offset" m +typedef ^ RotParameterType ReKi VolNac - - - "Nacelle volume" m^3 +typedef ^ RotParameterType ReKi NacCenB 3 - - "Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates" m +typedef ^ RotParameterType ReKi VolBl - - - "Buoyancy volume of all blades" m^3 +typedef ^ RotParameterType ReKi VolTwr - - - "Buoyancy volume of the tower" m^3 +typedef ^ RotParameterType ReKi BlRad {:}{:} - - "Matrix of equivalent blade radius at each node, used in buoyancy calculation" m +typedef ^ RotParameterType ReKi BlDL {:}{:} - - "Matrix of blade element length based on CB, used in buoyancy calculation" m +typedef ^ RotParameterType ReKi BlTaper {:}{:} - - "Matrix of blade element taper, used in buoyancy calculation" - +typedef ^ RotParameterType ReKi BlAxCent {:}{:} - - "Matrix of blade element axial centroid, used in buoyancy calculation" - +typedef ^ RotParameterType ReKi TwrRad {:} - - "Array of equivalent tower radius at each node, used in buoyancy calculation" m +typedef ^ RotParameterType ReKi TwrDL {:} - - "Array of tower element length, used in buoyancy calculation" m +typedef ^ RotParameterType ReKi TwrTaper {:} - - "Array of tower element taper, used in buoyancy calculation" - +typedef ^ RotParameterType ReKi TwrAxCent {:} - - "Array of tower element axial centroid, used in buoyancy calculation" - typedef ^ RotParameterType BEMT_ParameterType BEMT - - - "Parameters for BEMT module" typedef ^ RotParameterType AA_ParameterType AA - - - "Parameters for AA module" typedef ^ RotParameterType Integer Jac_u_indx {:}{:} - - "matrix to help fill/pack the u vector in computing the jacobian" - typedef ^ RotParameterType ReKi du {:} - - "vector that determines size of perturbation for u (inputs)" typedef ^ RotParameterType ReKi dx {:} - - "vector that determines size of perturbation for x (continuous states)" typedef ^ RotParameterType Integer Jac_ny - - - "number of outputs in jacobian matrix" - +typedef ^ RotParameterType Integer NumBl_Lin - - - "number of blades in the jacobian" - + typedef ^ RotParameterType IntKi TwrPotent - - - "Type of tower influence on wind based on potential flow around the tower {0=none, 1=baseline potential flow, 2=potential flow with Bak correction}" - typedef ^ RotParameterType IntKi TwrShadow - - - "Type of tower influence on wind based on downstream tower shadow {0=none, 1=Powles model, 2=Eames model}" - typedef ^ RotParameterType LOGICAL TwrAero - - - "Calculate tower aerodynamic loads?" flag typedef ^ RotParameterType Logical FrozenWake - - - "Flag that tells this module it should assume a frozen wake during linearization." - typedef ^ RotParameterType Logical CavitCheck - - - "Flag that tells us if we want to check for cavitation" - +typedef ^ RotParameterType Logical Buoyancy - - - "Include buoyancy effects?" flag +typedef ^ RotParameterType IntKi MHK - - - "MHK" flag typedef ^ RotParameterType Logical CompAA - - - "Compute AeroAcoustic noise" flag typedef ^ RotParameterType ReKi AirDens - - - "Air density" kg/m^3 typedef ^ RotParameterType ReKi KinVisc - - - "Kinematic air viscosity" m^2/s @@ -262,7 +374,8 @@ typedef ^ RotParameterType ReKi Patm - - - "Atmospheric pressu typedef ^ RotParameterType ReKi Pvap - - - "Vapour pressure" Pa typedef ^ RotParameterType ReKi WtrDpth - - - "Water depth" m typedef ^ RotParameterType ReKi MSL2SWL - - - "Offset between still-water level and mean sea level" m -typedef ^ RotParameterType IntKi AeroProjMod - 0 - "Flag to switch between different projection models" - +typedef ^ RotParameterType IntKi AeroProjMod - 1 - "Flag to switch between different projection models" - +typedef ^ RotParameterType IntKi AeroBEM_Mod - -1 - "Flag to switch between different BEM Model" - # parameters for output typedef ^ RotParameterType IntKi NumOuts - - - "Number of parameters in the output list (number of outputs requested)" - typedef ^ RotParameterType CHARACTER(1024) RootName - - - "RootName for writing output files" - @@ -277,6 +390,9 @@ typedef ^ RotParameterType IntKi BldNd_TotNumOuts - - - "Total number of request typedef ^ RotParameterType OutParmType BldNd_OutParam {:} - - "Names and units (and other characteristics) of all requested output parameters" - typedef ^ RotParameterType IntKi BldNd_BlOutNd {:} - - "The blade nodes to actually output (AD_AllBldNdOuts)" - typedef ^ RotParameterType IntKi BldNd_BladesOut - - - "The blades to output (AD_AllBldNdOuts)" - +# Tail fin parameters (per rotor) +typedef ^ RotParameterType LOGICAL TFinAero - .FALSE. - "Calculate tail fin aerodynamics model (flag)" flag +typedef ^ RotParameterType TFinParameterType TFin - - - "Parameters for tail fin of current rotor" - # parameters for all rotors: typedef ^ ParameterType RotParameterType rotors {:} - - "Parameter types for each rotor" - @@ -287,6 +403,7 @@ typedef ^ ParameterType AFI_ParameterType AFI {:} - - "AirfoilInfo parameters" typedef ^ ParameterType IntKi SkewMod - - - "Type of skewed-wake correction model {0=orthogonal, 1=uncoupled, 2=Pitt/Peters, 3=coupled} [unused when WakeMod=0]" - typedef ^ ParameterType IntKi WakeMod - - - "Type of wake/induction model {0=none, 1=BEMT, 2=DBEMT, 3=FVW}" - typedef ^ ParameterType FVW_ParameterType FVW - - - "Parameters for FVW module" +typedef ^ ParameterType LOGICAL CompAeroMaps - .FALSE. - "flag to determine if AeroDyn is computing aero maps (true) or running a normal simulation (false)" - typedef ^ ParameterType LOGICAL UA_Flag - - - "logical flag indicating whether to use UnsteadyAero" - @@ -297,12 +414,16 @@ typedef ^ RotInputType MeshType TowerMotion - - - "motion on the tower" - typedef ^ RotInputType MeshType HubMotion - - - "motion on the hub" - typedef ^ RotInputType MeshType BladeRootMotion {:} - - "motion on each blade root" - typedef ^ RotInputType MeshType BladeMotion {:} - - "motion on each blade" - +typedef ^ RotInputType MeshType TFinMotion - - - "motion of tail fin (at tail fin ref point)" - # Define inputs that are not on a mesh here: typedef ^ RotInputType ReKi InflowOnBlade {:}{:}{:} - - "U,V,W at nodes on each blade (note if we change the requirement that NumNodes is the same for each blade, this will need to change)" m/s typedef ^ RotInputType ReKi InflowOnTower {:}{:} - - "U,V,W at nodes on the tower" m/s +typedef ^ RotInputType ReKi InflowOnHub {3} - - "U,V,W at hub" m/s typedef ^ RotInputType ReKi InflowOnNacelle {3} - - "U,V,W at nacelle" m/s +typedef ^ RotInputType ReKi InflowOnTailFin {3} - - "U,V,W at tailfin" m/s typedef ^ RotInputType ReKi UserProp {:}{:} - - "Optional user property for interpolating airfoils (per element per blade)" - + typedef ^ InputType RotInputType rotors {:} - - "Inputs for each rotor" - typedef ^ InputType ReKi InflowWakeVel {:}{:} - - "U,V,W at wake points" m/s @@ -310,8 +431,10 @@ typedef ^ InputType ReKi InflowWakeVel {:}{:} - - "U,V,W at wake points" m/s # ..... Outputs ................................................................................................................... # Define outputs that are contained on a mesh here: typedef ^ RotOutputType MeshType NacelleLoad - - - "loads on the nacelle" - +typedef ^ RotOutputType MeshType HubLoad - - - "loads on the hub" - typedef ^ RotOutputType MeshType TowerLoad - - - "loads on the tower" - typedef ^ RotOutputType MeshType BladeLoad {:} - - "loads on each blade" - +typedef ^ RotOutputType MeshType TFinLoad - - - "loads on tail fin (at tail fin ref point)" - # Define outputs that are not on a mesh here: typedef ^ RotOutputType ReKi WriteOutput {:} - - "Data to be written to an output file: see WriteOutputHdr for names of each variable" "see WriteOutputUnt" diff --git a/modules/aerodyn/src/AeroDyn_Types.f90 b/modules/aerodyn/src/AeroDyn_Types.f90 index 677430d4c..77135b3b3 100644 --- a/modules/aerodyn/src/AeroDyn_Types.f90 +++ b/modules/aerodyn/src/AeroDyn_Types.f90 @@ -50,6 +50,46 @@ MODULE AeroDyn_Types 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 [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: TFinAero_none = 0 ! no tail fin aero [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: TFinAero_polar = 1 ! polar-based tail fin aerodynamics [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: TFinAero_USB = 2 ! unsteady slender body tail fin aerodynamics model [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: TFinIndMod_none = 0 ! no induction [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: TFinIndMod_rotavg = 1 ! rotor averaged induction [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: APM_BEM_NoSweepPitchTwist = 1 ! Original AeroDyn model where momentum balance is done in the WithoutSweepPitchTwist system [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: APM_BEM_Polar = 2 ! Use staggered polar grid for momentum balance in each annulus [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: APM_LiftingLine = 3 ! Use the blade lifting line (i.e. the structural) orientation (currently for OLAF with VAWT) [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: AD_MaxBl_Out = 3 ! Maximum number of blades for information output (or linearization) [-] +! ========= TFinParameterType ======= + TYPE, PUBLIC :: TFinParameterType + INTEGER(IntKi) :: TFinMod !< Tail fin aerodynamics model {0=none, 1=polar-based, 2=USB-based} [(switch)] + REAL(ReKi) :: TFinChord !< Tail fin chord [used only when TFinMod=1] [m] + REAL(ReKi) :: TFinArea !< Tail fin planform area [used only when TFinMod=1] [m^2] + INTEGER(IntKi) :: TFinIndMod !< Model for induced velocity calculation {0=none, 1=rotor-average} [(switch)] + INTEGER(IntKi) :: TFinAFID !< Index of Tail fin airfoil number [1 to NumAFfiles] [-] + END TYPE TFinParameterType +! ======================= +! ========= TFinInputFileType ======= + TYPE, PUBLIC :: TFinInputFileType + INTEGER(IntKi) :: TFinMod !< Tail fin aerodynamics model {0=none, 1=polar-based, 2=USB-based} [(switch)] + REAL(ReKi) :: TFinChord !< Tail fin chord [used only when TFinMod=1] [m] + REAL(ReKi) :: TFinArea !< Tail fin planform area [used only when TFinMod=1] [m^2] + REAL(ReKi) , DIMENSION(1:3) :: TFinRefP_n !< Undeflected position of the tail fin reference point wrt the tower top [m] + REAL(ReKi) , DIMENSION(1:3) :: TFinAngles !< Tail fin chordline skew, tilt, and bank angles about the reference point [(deg)] + INTEGER(IntKi) :: TFinIndMod !< Model for induced velocity calculation {0=none, 1=rotor-average} [(switch)] + INTEGER(IntKi) :: TFinAFID !< Index of Tail fin airfoil number [1 to NumAFfiles] [-] + END TYPE TFinInputFileType +! ======================= +! ========= AD_VTK_BLSurfaceType ======= + TYPE, PUBLIC :: AD_VTK_BLSurfaceType + REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: AirfoilCoords !< x,y coordinates for airfoil around each blade node on a blade (relative to reference) [-] + END TYPE AD_VTK_BLSurfaceType +! ======================= +! ========= AD_VTK_RotSurfaceType ======= + TYPE, PUBLIC :: AD_VTK_RotSurfaceType + TYPE(AD_VTK_BLSurfaceType) , DIMENSION(:), ALLOCATABLE :: BladeShape !< AirfoilCoords for each blade [-] + REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: TowerRad !< radius of each ED tower node [m] + END TYPE AD_VTK_RotSurfaceType +! ======================= ! ========= RotInitInputType ======= TYPE, PUBLIC :: RotInitInputType INTEGER(IntKi) :: NumBlades !< Number of blades on the turbine [-] @@ -59,7 +99,8 @@ MODULE AeroDyn_Types REAL(R8Ki) , DIMENSION(:,:,:), ALLOCATABLE :: BladeRootOrientation !< DCM reference orientation of blade roots (3x3 x NumBlades) [-] REAL(R8Ki) , DIMENSION(1:3) :: NacellePosition !< X-Y-Z reference position of nacelle [m] REAL(R8Ki) , DIMENSION(1:3,1:3) :: NacelleOrientation !< DCM reference orientation of nacelle [-] - INTEGER(IntKi) :: AeroProjMod = 0 !< Flag to switch between different projection models [-] + INTEGER(IntKi) :: AeroProjMod = 1 !< Flag to switch between different projection models [-] + INTEGER(IntKi) :: AeroBEM_Mod = -1 !< Flag to switch between different BEM Model [-] END TYPE RotInitInputType ! ======================= ! ========= AD_InitInputType ======= @@ -91,6 +132,9 @@ MODULE AeroDyn_Types REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BlTwist !< Twist at blade node [radians] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BlChord !< Chord at blade node [m] INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: BlAFID !< ID of Airfoil at blade node [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BlCb !< Coefficient of buoyancy at blade node [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BlCenBn !< Center of buoyancy normal offset at blade node [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BlCenBt !< Center of buoyancy tangential offset at blade node [m] END TYPE AD_BladePropsType ! ======================= ! ========= AD_BladeShape ======= @@ -131,6 +175,14 @@ MODULE AeroDyn_Types 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) , DIMENSION(:), ALLOCATABLE :: TwrCb !< Coefficient of buoyancy at tower node [-] + REAL(ReKi) :: VolHub !< Hub volume [m^3] + REAL(ReKi) :: HubCenBx !< Hub center of buoyancy x direction offset [m] + REAL(ReKi) :: VolNac !< Nacelle volume [m^3] + REAL(ReKi) , DIMENSION(1:3) :: NacCenB !< Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates [m] + LOGICAL :: TFinAero = .FALSE. !< Calculate tail fin aerodynamics model (flag) [flag] + CHARACTER(1024) :: TFinFile !< Input file for tail fin aerodynamics [used only when TFinAero=True] [-] + TYPE(TFinInputFileType) :: TFin !< Input file data for tail fin [-] END TYPE RotInputFile ! ======================= ! ========= AD_InputFile ======= @@ -144,6 +196,7 @@ MODULE AeroDyn_Types 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 :: Buoyancy !< Include buoyancy effects? [flag] 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] @@ -249,7 +302,7 @@ MODULE AeroDyn_Types TYPE(AA_OutputType) :: AA_y !< Outputs from the AA module [-] TYPE(AA_InputType) :: AA_u !< Inputs to the AA module [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: DisturbedInflow !< InflowOnBlade values modified by tower influence [m/s] - REAL(ReKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: WithoutSweepPitchTwist !< Coordinate system equivalent to BladeMotion Orientation, but without live sweep, blade-pitch, and twist angles [-] + REAL(R8Ki) , DIMENSION(:,:,:,:), ALLOCATABLE :: orientationAnnulus !< Coordinate system equivalent to BladeMotion Orientation, but without live sweep, blade-pitch, and twist angles [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AllOuts !< An array holding the value of all of the calculated (not only selected) output channels [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: W_Twr !< relative wind speed normal to the tower at node j [m/s] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: X_Twr !< local x-component of force per unit length of the jth node in the tower [m/s] @@ -258,8 +311,14 @@ MODULE AeroDyn_Types REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: TwrClrnc !< Distance between tower (including tower radius) and blade node (not including blade width), saved for possible output to file [m] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: X !< normal force per unit length (normal to the plane, not chord) of the jth node in the kth blade [N/m] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Y !< tangential force per unit length (tangential to the plane, not chord) of the jth node in the kth blade [N/m] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Z !< axial force per unit length (tangential to the plane, not chord) of the jth node in the kth blade [N/m] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: M !< pitching moment per unit length of the jth node in the kth blade [Nm/m] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Mx !< pitching moment per unit length of the jth node in the kth blade (in x direction) [Nm/m] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: My !< pitching moment per unit length of the jth node in the kth blade (in y direction) [Nm/m] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Mz !< pitching moment per unit length of the jth node in the kth blade (in z direction) [Nm/m] REAL(ReKi) , DIMENSION(1:3) :: V_DiskAvg !< disk-average relative wind speed [m/s] + REAL(ReKi) :: yaw !< Yaw calculated in SetInputsForBEMT [rad] + REAL(ReKi) :: tilt !< tilt calculated in SetInputsForBEMT [rad] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: hub_theta_x_root !< angles saved for FAST.Farm [rad] REAL(ReKi) :: V_dot_x TYPE(MeshType) :: HubLoad !< mesh at hub; used to compute an integral for mapping the output blade loads to a single point (for writing to file only) [-] @@ -267,8 +326,34 @@ MODULE AeroDyn_Types REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: SigmaCavitCrit !< critical cavitation number- inception value (above which cavit will occur) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: SigmaCavit !< cavitation number at node [-] LOGICAL , DIMENSION(:,:), ALLOCATABLE :: CavitWarnSet !< cavitation warning issued [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: BlFB !< buoyant force per unit length at blade node [N/m] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: BlMB !< buoyant moment per unit length at blade node [Nm/m] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: TwrFB !< buoyant force per unit length at tower node [N/m] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: TwrMB !< buoyant moment per unit length at tower node [Nm/m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: HubFB !< buoyant force at hub node [N] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: HubMB !< buoyant moment at hub node [Nm] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: NacFB !< buoyant force at nacelle (tower top) node [N] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: NacMB !< buoyant moment at nacelle (tower top) node [Nm] TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: BladeRootLoad !< meshes at blade root; used to compute an integral for mapping the output blade loads to single points (for writing to file only) [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: B_L_2_R_P !< mapping data structure to map each bladeLoad output mesh to corresponding MiscVar%BladeRootLoad mesh [-] + TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: BladeBuoyLoadPoint !< point mesh for lumped buoyant blade loads [-] + TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: BladeBuoyLoad !< line mesh for per unit length buoyant blade loads [-] + TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: B_P_2_B_L !< mapping data structure to map buoyant blade point loads (m%BladeBuoyLoadPoint) to buoyant blade line loads (m%BladeBuoyLoad) [-] + TYPE(MeshType) :: TwrBuoyLoadPoint !< point mesh for lumped buoyant tower loads [-] + TYPE(MeshType) :: TwrBuoyLoad !< line mesh for per unit length buoyant tower loads [-] + TYPE(MeshMapType) :: T_P_2_T_L !< mapping data structure to map buoyant tower point loads (m%TwrBuoyLoadPoint) to buoyant tower line loads (m%TwrBuoyLoad) [-] + LOGICAL :: FirstWarn_TowerStrike !< flag to avoid printing tower strike multiple times [-] + REAL(ReKi) , DIMENSION(1:3) :: AvgDiskVel !< disk-averaged U,V,W (undisturbed) [m/s] + REAL(ReKi) , DIMENSION(1:3) :: AvgDiskVelDist !< disk-averaged U,V,W (disturbed) [m/s] + REAL(ReKi) :: TFinAlpha !< Angle of attack for tailfin [-] + REAL(ReKi) :: TFinRe !< Reynolds number for tailfin [-] + REAL(ReKi) :: TFinVrel !< Orthogonal relative velocity nrom at the reference point [-] + REAL(ReKi) , DIMENSION(1:3) :: TFinVund_i !< Undisturbed wind velocity at the reference point of the fin in the inertial system [-] + REAL(ReKi) , DIMENSION(1:3) :: TFinVind_i !< Induced velocity at the reference point of the fin in the inertial system [-] + REAL(ReKi) , DIMENSION(1:3) :: TFinVrel_i !< Relative velocity at the reference point of the fin in the inertial system [-] + REAL(ReKi) , DIMENSION(1:3) :: TFinSTV_i !< Structural velocity at the reference point of the fin in the inertial system [-] + REAL(ReKi) , DIMENSION(1:3) :: TFinF_i !< Forces at the reference point of the fin in the inertial system [-] + REAL(ReKi) , DIMENSION(1:3) :: TFinM_i !< Moments at the reference point of the fin in the inertial system [-] END TYPE RotMiscVarType ! ======================= ! ========= AD_MiscVarType ======= @@ -287,17 +372,38 @@ MODULE AeroDyn_Types 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) , DIMENSION(:,:), ALLOCATABLE :: BlTwist !< Twist at blade node [radians] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrCb !< Coefficient of buoyancy at tower node [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BlCenBn !< Normal offset between aerodynamic center and center of buoyancy at blade node [m] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BlCenBt !< Tangential offset between aerodynamic center and center of buoyancy at blade node [m] + REAL(ReKi) :: VolHub !< Hub volume [m^3] + REAL(ReKi) :: HubCenBx !< Hub center of buoyancy x direction offset [m] + REAL(ReKi) :: VolNac !< Nacelle volume [m^3] + REAL(ReKi) , DIMENSION(1:3) :: NacCenB !< Position of nacelle center of buoyancy from yaw bearing in nacelle coordinates [m] + REAL(ReKi) :: VolBl !< Buoyancy volume of all blades [m^3] + REAL(ReKi) :: VolTwr !< Buoyancy volume of the tower [m^3] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BlRad !< Matrix of equivalent blade radius at each node, used in buoyancy calculation [m] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BlDL !< Matrix of blade element length based on CB, used in buoyancy calculation [m] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BlTaper !< Matrix of blade element taper, used in buoyancy calculation [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BlAxCent !< Matrix of blade element axial centroid, used in buoyancy calculation [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrRad !< Array of equivalent tower radius at each node, used in buoyancy calculation [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrDL !< Array of tower element length, used in buoyancy calculation [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrTaper !< Array of tower element taper, used in buoyancy calculation [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwrAxCent !< Array of tower element axial centroid, used in buoyancy calculation [-] TYPE(BEMT_ParameterType) :: BEMT !< Parameters for BEMT module [-] TYPE(AA_ParameterType) :: AA !< Parameters for AA module [-] INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Jac_u_indx !< matrix to help fill/pack the u vector in computing the jacobian [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: du !< vector that determines size of perturbation for u (inputs) [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: dx !< vector that determines size of perturbation for x (continuous states) [-] INTEGER(IntKi) :: Jac_ny !< number of outputs in jacobian matrix [-] + INTEGER(IntKi) :: NumBl_Lin !< number of blades in the jacobian [-] INTEGER(IntKi) :: TwrPotent !< Type of tower influence on wind based on potential flow around the tower {0=none, 1=baseline potential flow, 2=potential flow with Bak correction} [-] INTEGER(IntKi) :: TwrShadow !< Type of 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 :: Buoyancy !< Include buoyancy effects? [flag] + INTEGER(IntKi) :: MHK !< MHK [flag] LOGICAL :: CompAA !< Compute AeroAcoustic noise [flag] REAL(ReKi) :: AirDens !< Air density [kg/m^3] REAL(ReKi) :: KinVisc !< Kinematic air viscosity [m^2/s] @@ -307,7 +413,8 @@ MODULE AeroDyn_Types REAL(ReKi) :: Pvap !< Vapour pressure [Pa] REAL(ReKi) :: WtrDpth !< Water depth [m] REAL(ReKi) :: MSL2SWL !< Offset between still-water level and mean sea level [m] - INTEGER(IntKi) :: AeroProjMod = 0 !< Flag to switch between different projection models [-] + INTEGER(IntKi) :: AeroProjMod = 1 !< Flag to switch between different projection models [-] + INTEGER(IntKi) :: AeroBEM_Mod = -1 !< Flag to switch between different BEM Model [-] INTEGER(IntKi) :: NumOuts !< Number of parameters in the output list (number of outputs requested) [-] CHARACTER(1024) :: RootName !< RootName for writing output files [-] TYPE(OutParmType) , DIMENSION(:), ALLOCATABLE :: OutParam !< Names and units (and other characteristics) of all requested output parameters [-] @@ -320,6 +427,8 @@ MODULE AeroDyn_Types TYPE(OutParmType) , DIMENSION(:), ALLOCATABLE :: BldNd_OutParam !< Names and units (and other characteristics) of all requested output parameters [-] INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: BldNd_BlOutNd !< The blade nodes to actually output (AD_AllBldNdOuts) [-] INTEGER(IntKi) :: BldNd_BladesOut !< The blades to output (AD_AllBldNdOuts) [-] + LOGICAL :: TFinAero = .FALSE. !< Calculate tail fin aerodynamics model (flag) [flag] + TYPE(TFinParameterType) :: TFin !< Parameters for tail fin of current rotor [-] END TYPE RotParameterType ! ======================= ! ========= AD_ParameterType ======= @@ -331,6 +440,7 @@ MODULE AeroDyn_Types INTEGER(IntKi) :: SkewMod !< Type of skewed-wake correction model {0=orthogonal, 1=uncoupled, 2=Pitt/Peters, 3=coupled} [unused when WakeMod=0] [-] INTEGER(IntKi) :: WakeMod !< Type of wake/induction model {0=none, 1=BEMT, 2=DBEMT, 3=FVW} [-] TYPE(FVW_ParameterType) :: FVW !< Parameters for FVW module [-] + LOGICAL :: CompAeroMaps = .FALSE. !< flag to determine if AeroDyn is computing aero maps (true) or running a normal simulation (false) [-] LOGICAL :: UA_Flag !< logical flag indicating whether to use UnsteadyAero [-] END TYPE AD_ParameterType ! ======================= @@ -341,9 +451,12 @@ MODULE AeroDyn_Types TYPE(MeshType) :: HubMotion !< motion on the hub [-] TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: BladeRootMotion !< motion on each blade root [-] TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: BladeMotion !< motion on each blade [-] + TYPE(MeshType) :: TFinMotion !< motion of tail fin (at tail fin ref point) [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: InflowOnBlade !< U,V,W at nodes on each blade (note if we change the requirement that NumNodes is the same for each blade, this will need to change) [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: InflowOnTower !< U,V,W at nodes on the tower [m/s] + REAL(ReKi) , DIMENSION(1:3) :: InflowOnHub !< U,V,W at hub [m/s] REAL(ReKi) , DIMENSION(1:3) :: InflowOnNacelle !< U,V,W at nacelle [m/s] + REAL(ReKi) , DIMENSION(1:3) :: InflowOnTailFin !< U,V,W at tailfin [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: UserProp !< Optional user property for interpolating airfoils (per element per blade) [-] END TYPE RotInputType ! ======================= @@ -356,8 +469,10 @@ MODULE AeroDyn_Types ! ========= RotOutputType ======= TYPE, PUBLIC :: RotOutputType TYPE(MeshType) :: NacelleLoad !< loads on the nacelle [-] + TYPE(MeshType) :: HubLoad !< loads on the hub [-] TYPE(MeshType) :: TowerLoad !< loads on the tower [-] TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: BladeLoad !< loads on each blade [-] + TYPE(MeshType) :: TFinLoad !< loads on tail fin (at tail fin ref point) [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< Data to be written to an output file: see WriteOutputHdr for names of each variable [see WriteOutputUnt] END TYPE RotOutputType ! ======================= @@ -367,9 +482,9 @@ MODULE AeroDyn_Types END TYPE AD_OutputType ! ======================= CONTAINS - SUBROUTINE AD_CopyRotInitInputType( SrcRotInitInputTypeData, DstRotInitInputTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(RotInitInputType), INTENT(IN) :: SrcRotInitInputTypeData - TYPE(RotInitInputType), INTENT(INOUT) :: DstRotInitInputTypeData + SUBROUTINE AD_CopyTFinParameterType( SrcTFinParameterTypeData, DstTFinParameterTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(TFinParameterType), INTENT(IN) :: SrcTFinParameterTypeData + TYPE(TFinParameterType), INTENT(INOUT) :: DstTFinParameterTypeData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -381,70 +496,45 @@ SUBROUTINE AD_CopyRotInitInputType( SrcRotInitInputTypeData, DstRotInitInputType INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyRotInitInputType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyTFinParameterType' ! ErrStat = ErrID_None ErrMsg = "" - DstRotInitInputTypeData%NumBlades = SrcRotInitInputTypeData%NumBlades - DstRotInitInputTypeData%HubPosition = SrcRotInitInputTypeData%HubPosition - DstRotInitInputTypeData%HubOrientation = SrcRotInitInputTypeData%HubOrientation -IF (ALLOCATED(SrcRotInitInputTypeData%BladeRootPosition)) THEN - i1_l = LBOUND(SrcRotInitInputTypeData%BladeRootPosition,1) - i1_u = UBOUND(SrcRotInitInputTypeData%BladeRootPosition,1) - i2_l = LBOUND(SrcRotInitInputTypeData%BladeRootPosition,2) - i2_u = UBOUND(SrcRotInitInputTypeData%BladeRootPosition,2) - IF (.NOT. ALLOCATED(DstRotInitInputTypeData%BladeRootPosition)) THEN - ALLOCATE(DstRotInitInputTypeData%BladeRootPosition(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitInputTypeData%BladeRootPosition.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotInitInputTypeData%BladeRootPosition = SrcRotInitInputTypeData%BladeRootPosition -ENDIF -IF (ALLOCATED(SrcRotInitInputTypeData%BladeRootOrientation)) THEN - i1_l = LBOUND(SrcRotInitInputTypeData%BladeRootOrientation,1) - i1_u = UBOUND(SrcRotInitInputTypeData%BladeRootOrientation,1) - i2_l = LBOUND(SrcRotInitInputTypeData%BladeRootOrientation,2) - i2_u = UBOUND(SrcRotInitInputTypeData%BladeRootOrientation,2) - i3_l = LBOUND(SrcRotInitInputTypeData%BladeRootOrientation,3) - i3_u = UBOUND(SrcRotInitInputTypeData%BladeRootOrientation,3) - IF (.NOT. ALLOCATED(DstRotInitInputTypeData%BladeRootOrientation)) THEN - ALLOCATE(DstRotInitInputTypeData%BladeRootOrientation(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitInputTypeData%BladeRootOrientation.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotInitInputTypeData%BladeRootOrientation = SrcRotInitInputTypeData%BladeRootOrientation -ENDIF - DstRotInitInputTypeData%NacellePosition = SrcRotInitInputTypeData%NacellePosition - DstRotInitInputTypeData%NacelleOrientation = SrcRotInitInputTypeData%NacelleOrientation - DstRotInitInputTypeData%AeroProjMod = SrcRotInitInputTypeData%AeroProjMod - END SUBROUTINE AD_CopyRotInitInputType - - SUBROUTINE AD_DestroyRotInitInputType( RotInitInputTypeData, ErrStat, ErrMsg ) - TYPE(RotInitInputType), INTENT(INOUT) :: RotInitInputTypeData + DstTFinParameterTypeData%TFinMod = SrcTFinParameterTypeData%TFinMod + DstTFinParameterTypeData%TFinChord = SrcTFinParameterTypeData%TFinChord + DstTFinParameterTypeData%TFinArea = SrcTFinParameterTypeData%TFinArea + DstTFinParameterTypeData%TFinIndMod = SrcTFinParameterTypeData%TFinIndMod + DstTFinParameterTypeData%TFinAFID = SrcTFinParameterTypeData%TFinAFID + END SUBROUTINE AD_CopyTFinParameterType + + SUBROUTINE AD_DestroyTFinParameterType( TFinParameterTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(TFinParameterType), INTENT(INOUT) :: TFinParameterTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotInitInputType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyTFinParameterType' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(RotInitInputTypeData%BladeRootPosition)) THEN - DEALLOCATE(RotInitInputTypeData%BladeRootPosition) -ENDIF -IF (ALLOCATED(RotInitInputTypeData%BladeRootOrientation)) THEN - DEALLOCATE(RotInitInputTypeData%BladeRootOrientation) -ENDIF - END SUBROUTINE AD_DestroyRotInitInputType - SUBROUTINE AD_PackRotInitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE AD_DestroyTFinParameterType + + SUBROUTINE AD_PackTFinParameterType( 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(RotInitInputType), INTENT(IN) :: InData + TYPE(TFinParameterType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -459,7 +549,7 @@ SUBROUTINE AD_PackRotInitInputType( 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 = 'AD_PackRotInitInputType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackTFinParameterType' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -475,22 +565,11 @@ SUBROUTINE AD_PackRotInitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! NumBlades - Re_BufSz = Re_BufSz + SIZE(InData%HubPosition) ! HubPosition - Db_BufSz = Db_BufSz + SIZE(InData%HubOrientation) ! HubOrientation - Int_BufSz = Int_BufSz + 1 ! BladeRootPosition allocated yes/no - IF ( ALLOCATED(InData%BladeRootPosition) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! BladeRootPosition upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%BladeRootPosition) ! BladeRootPosition - END IF - Int_BufSz = Int_BufSz + 1 ! BladeRootOrientation allocated yes/no - IF ( ALLOCATED(InData%BladeRootOrientation) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! BladeRootOrientation upper/lower bounds for each dimension - Db_BufSz = Db_BufSz + SIZE(InData%BladeRootOrientation) ! BladeRootOrientation - END IF - Db_BufSz = Db_BufSz + SIZE(InData%NacellePosition) ! NacellePosition - Db_BufSz = Db_BufSz + SIZE(InData%NacelleOrientation) ! NacelleOrientation - Int_BufSz = Int_BufSz + 1 ! AeroProjMod + Int_BufSz = Int_BufSz + 1 ! TFinMod + Re_BufSz = Re_BufSz + 1 ! TFinChord + Re_BufSz = Re_BufSz + 1 ! TFinArea + Int_BufSz = Int_BufSz + 1 ! TFinIndMod + Int_BufSz = Int_BufSz + 1 ! TFinAFID IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -518,82 +597,23 @@ SUBROUTINE AD_PackRotInitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = InData%NumBlades - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%HubPosition,1), UBOUND(InData%HubPosition,1) - ReKiBuf(Re_Xferred) = InData%HubPosition(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i2 = LBOUND(InData%HubOrientation,2), UBOUND(InData%HubOrientation,2) - DO i1 = LBOUND(InData%HubOrientation,1), UBOUND(InData%HubOrientation,1) - DbKiBuf(Db_Xferred) = InData%HubOrientation(i1,i2) - Db_Xferred = Db_Xferred + 1 - END DO - END DO - IF ( .NOT. ALLOCATED(InData%BladeRootPosition) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeRootPosition,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootPosition,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeRootPosition,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootPosition,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%BladeRootPosition,2), UBOUND(InData%BladeRootPosition,2) - DO i1 = LBOUND(InData%BladeRootPosition,1), UBOUND(InData%BladeRootPosition,1) - ReKiBuf(Re_Xferred) = InData%BladeRootPosition(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%BladeRootOrientation) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IntKiBuf(Int_Xferred) = InData%TFinMod Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 + ReKiBuf(Re_Xferred) = InData%TFinChord + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%TFinArea + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%TFinIndMod Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeRootOrientation,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootOrientation,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeRootOrientation,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootOrientation,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeRootOrientation,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootOrientation,3) - Int_Xferred = Int_Xferred + 2 - - DO i3 = LBOUND(InData%BladeRootOrientation,3), UBOUND(InData%BladeRootOrientation,3) - DO i2 = LBOUND(InData%BladeRootOrientation,2), UBOUND(InData%BladeRootOrientation,2) - DO i1 = LBOUND(InData%BladeRootOrientation,1), UBOUND(InData%BladeRootOrientation,1) - DbKiBuf(Db_Xferred) = InData%BladeRootOrientation(i1,i2,i3) - Db_Xferred = Db_Xferred + 1 - END DO - END DO - END DO - END IF - DO i1 = LBOUND(InData%NacellePosition,1), UBOUND(InData%NacellePosition,1) - DbKiBuf(Db_Xferred) = InData%NacellePosition(i1) - Db_Xferred = Db_Xferred + 1 - END DO - DO i2 = LBOUND(InData%NacelleOrientation,2), UBOUND(InData%NacelleOrientation,2) - DO i1 = LBOUND(InData%NacelleOrientation,1), UBOUND(InData%NacelleOrientation,1) - DbKiBuf(Db_Xferred) = InData%NacelleOrientation(i1,i2) - Db_Xferred = Db_Xferred + 1 - END DO - END DO - IntKiBuf(Int_Xferred) = InData%AeroProjMod + IntKiBuf(Int_Xferred) = InData%TFinAFID Int_Xferred = Int_Xferred + 1 - END SUBROUTINE AD_PackRotInitInputType + END SUBROUTINE AD_PackTFinParameterType - SUBROUTINE AD_UnPackRotInitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_UnPackTFinParameterType( 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(RotInitInputType), INTENT(INOUT) :: OutData + TYPE(TFinParameterType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -608,7 +628,7 @@ SUBROUTINE AD_UnPackRotInitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, 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 = 'AD_UnPackRotInitInputType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackTFinParameterType' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -619,98 +639,21 @@ SUBROUTINE AD_UnPackRotInitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%NumBlades = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%HubPosition,1) - i1_u = UBOUND(OutData%HubPosition,1) - DO i1 = LBOUND(OutData%HubPosition,1), UBOUND(OutData%HubPosition,1) - OutData%HubPosition(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%HubOrientation,1) - i1_u = UBOUND(OutData%HubOrientation,1) - i2_l = LBOUND(OutData%HubOrientation,2) - i2_u = UBOUND(OutData%HubOrientation,2) - DO i2 = LBOUND(OutData%HubOrientation,2), UBOUND(OutData%HubOrientation,2) - DO i1 = LBOUND(OutData%HubOrientation,1), UBOUND(OutData%HubOrientation,1) - OutData%HubOrientation(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - END DO - END DO - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeRootPosition not allocated - Int_Xferred = Int_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%BladeRootPosition)) DEALLOCATE(OutData%BladeRootPosition) - ALLOCATE(OutData%BladeRootPosition(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeRootPosition.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%BladeRootPosition,2), UBOUND(OutData%BladeRootPosition,2) - DO i1 = LBOUND(OutData%BladeRootPosition,1), UBOUND(OutData%BladeRootPosition,1) - OutData%BladeRootPosition(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeRootOrientation not allocated + OutData%TFinMod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - ELSE + OutData%TFinChord = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%TFinArea = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%TFinIndMod = 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%BladeRootOrientation)) DEALLOCATE(OutData%BladeRootOrientation) - ALLOCATE(OutData%BladeRootOrientation(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%BladeRootOrientation.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i3 = LBOUND(OutData%BladeRootOrientation,3), UBOUND(OutData%BladeRootOrientation,3) - DO i2 = LBOUND(OutData%BladeRootOrientation,2), UBOUND(OutData%BladeRootOrientation,2) - DO i1 = LBOUND(OutData%BladeRootOrientation,1), UBOUND(OutData%BladeRootOrientation,1) - OutData%BladeRootOrientation(i1,i2,i3) = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - END DO - END DO - END DO - END IF - i1_l = LBOUND(OutData%NacellePosition,1) - i1_u = UBOUND(OutData%NacellePosition,1) - DO i1 = LBOUND(OutData%NacellePosition,1), UBOUND(OutData%NacellePosition,1) - OutData%NacellePosition(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - END DO - i1_l = LBOUND(OutData%NacelleOrientation,1) - i1_u = UBOUND(OutData%NacelleOrientation,1) - i2_l = LBOUND(OutData%NacelleOrientation,2) - i2_u = UBOUND(OutData%NacelleOrientation,2) - DO i2 = LBOUND(OutData%NacelleOrientation,2), UBOUND(OutData%NacelleOrientation,2) - DO i1 = LBOUND(OutData%NacelleOrientation,1), UBOUND(OutData%NacelleOrientation,1) - OutData%NacelleOrientation(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - END DO - END DO - OutData%AeroProjMod = IntKiBuf(Int_Xferred) + OutData%TFinAFID = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - END SUBROUTINE AD_UnPackRotInitInputType + END SUBROUTINE AD_UnPackTFinParameterType - SUBROUTINE AD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(AD_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(AD_InitInputType), INTENT(INOUT) :: DstInitInputData + SUBROUTINE AD_CopyTFinInputFileType( SrcTFinInputFileTypeData, DstTFinInputFileTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(TFinInputFileType), INTENT(IN) :: SrcTFinInputFileTypeData + TYPE(TFinInputFileType), INTENT(INOUT) :: DstTFinInputFileTypeData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -719,67 +662,47 @@ SUBROUTINE AD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrSt INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyInitInput' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyTFinInputFileType' ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcInitInputData%rotors)) THEN - i1_l = LBOUND(SrcInitInputData%rotors,1) - i1_u = UBOUND(SrcInitInputData%rotors,1) - IF (.NOT. ALLOCATED(DstInitInputData%rotors)) THEN - ALLOCATE(DstInitInputData%rotors(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%rotors.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcInitInputData%rotors,1), UBOUND(SrcInitInputData%rotors,1) - CALL AD_Copyrotinitinputtype( SrcInitInputData%rotors(i1), DstInitInputData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF - DstInitInputData%InputFile = SrcInitInputData%InputFile - DstInitInputData%RootName = SrcInitInputData%RootName - 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 - DstInitInputData%Linearize = SrcInitInputData%Linearize - DstInitInputData%Gravity = SrcInitInputData%Gravity - DstInitInputData%MHK = SrcInitInputData%MHK - DstInitInputData%defFldDens = SrcInitInputData%defFldDens - DstInitInputData%defKinVisc = SrcInitInputData%defKinVisc - DstInitInputData%defSpdSound = SrcInitInputData%defSpdSound - DstInitInputData%defPatm = SrcInitInputData%defPatm - DstInitInputData%defPvap = SrcInitInputData%defPvap - DstInitInputData%WtrDpth = SrcInitInputData%WtrDpth - DstInitInputData%MSL2SWL = SrcInitInputData%MSL2SWL - END SUBROUTINE AD_CopyInitInput - - SUBROUTINE AD_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) - TYPE(AD_InitInputType), INTENT(INOUT) :: InitInputData + DstTFinInputFileTypeData%TFinMod = SrcTFinInputFileTypeData%TFinMod + DstTFinInputFileTypeData%TFinChord = SrcTFinInputFileTypeData%TFinChord + DstTFinInputFileTypeData%TFinArea = SrcTFinInputFileTypeData%TFinArea + DstTFinInputFileTypeData%TFinRefP_n = SrcTFinInputFileTypeData%TFinRefP_n + DstTFinInputFileTypeData%TFinAngles = SrcTFinInputFileTypeData%TFinAngles + DstTFinInputFileTypeData%TFinIndMod = SrcTFinInputFileTypeData%TFinIndMod + DstTFinInputFileTypeData%TFinAFID = SrcTFinInputFileTypeData%TFinAFID + END SUBROUTINE AD_CopyTFinInputFileType + + SUBROUTINE AD_DestroyTFinInputFileType( TFinInputFileTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(TFinInputFileType), INTENT(INOUT) :: TFinInputFileTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyTFinInputFileType' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(InitInputData%rotors)) THEN -DO i1 = LBOUND(InitInputData%rotors,1), UBOUND(InitInputData%rotors,1) - CALL AD_Destroyrotinitinputtype( InitInputData%rotors(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(InitInputData%rotors) -ENDIF - CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedPrimaryInputData, ErrStat, ErrMsg ) - END SUBROUTINE AD_DestroyInitInput - SUBROUTINE AD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE AD_DestroyTFinInputFileType + + SUBROUTINE AD_PackTFinInputFileType( 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(AD_InitInputType), INTENT(IN) :: InData + TYPE(TFinInputFileType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -794,7 +717,7 @@ SUBROUTINE AD_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 = 'AD_PackInitInput' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackTFinInputFileType' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -810,60 +733,13 @@ SUBROUTINE AD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! rotors allocated yes/no - IF ( ALLOCATED(InData%rotors) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! rotors upper/lower bounds for each dimension - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) - Int_BufSz = Int_BufSz + 3 ! rotors: size of buffers for each call to pack subtype - CALL AD_Packrotinitinputtype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! rotors - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! rotors - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! rotors - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - END IF - Int_BufSz = Int_BufSz + 1*LEN(InData%InputFile) ! InputFile - Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName - Int_BufSz = Int_BufSz + 1 ! UsePrimaryInputFile - 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 - Int_BufSz = Int_BufSz + 1 ! Linearize - Re_BufSz = Re_BufSz + 1 ! Gravity - Int_BufSz = Int_BufSz + 1 ! MHK - Re_BufSz = Re_BufSz + 1 ! defFldDens - Re_BufSz = Re_BufSz + 1 ! defKinVisc - Re_BufSz = Re_BufSz + 1 ! defSpdSound - Re_BufSz = Re_BufSz + 1 ! defPatm - Re_BufSz = Re_BufSz + 1 ! defPvap - Re_BufSz = Re_BufSz + 1 ! WtrDpth - Re_BufSz = Re_BufSz + 1 ! MSL2SWL + Int_BufSz = Int_BufSz + 1 ! TFinMod + Re_BufSz = Re_BufSz + 1 ! TFinChord + Re_BufSz = Re_BufSz + 1 ! TFinArea + Re_BufSz = Re_BufSz + SIZE(InData%TFinRefP_n) ! TFinRefP_n + Re_BufSz = Re_BufSz + SIZE(InData%TFinAngles) ! TFinAngles + Int_BufSz = Int_BufSz + 1 ! TFinIndMod + Int_BufSz = Int_BufSz + 1 ! TFinAFID IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -891,112 +767,31 @@ SUBROUTINE AD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Db_Xferred = 1 Int_Xferred = 1 - IF ( .NOT. ALLOCATED(InData%rotors) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IntKiBuf(Int_Xferred) = InData%TFinMod Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%rotors,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%rotors,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) - CALL AD_Packrotinitinputtype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF + ReKiBuf(Re_Xferred) = InData%TFinChord + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%TFinArea + Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%TFinRefP_n,1), UBOUND(InData%TFinRefP_n,1) + ReKiBuf(Re_Xferred) = InData%TFinRefP_n(i1) + Re_Xferred = Re_Xferred + 1 END DO - END IF - DO I = 1, LEN(InData%InputFile) - IntKiBuf(Int_Xferred) = ICHAR(InData%InputFile(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 - 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 - IntKiBuf(Int_Xferred) = TRANSFER(InData%Linearize, IntKiBuf(1)) + DO i1 = LBOUND(InData%TFinAngles,1), UBOUND(InData%TFinAngles,1) + ReKiBuf(Re_Xferred) = InData%TFinAngles(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%TFinIndMod Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Gravity - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%MHK + IntKiBuf(Int_Xferred) = InData%TFinAFID Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%defFldDens - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%defKinVisc - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%defSpdSound - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%defPatm - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%defPvap - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%WtrDpth - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%MSL2SWL - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE AD_PackInitInput + END SUBROUTINE AD_PackTFinInputFileType - SUBROUTINE AD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_UnPackTFinInputFileType( 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(AD_InitInputType), INTENT(INOUT) :: OutData + TYPE(TFinInputFileType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -1008,7 +803,7 @@ SUBROUTINE AD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackInitInput' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackTFinInputFileType' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -1019,273 +814,96 @@ SUBROUTINE AD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! rotors not allocated + OutData%TFinMod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - ELSE + OutData%TFinChord = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%TFinArea = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%TFinRefP_n,1) + i1_u = UBOUND(OutData%TFinRefP_n,1) + DO i1 = LBOUND(OutData%TFinRefP_n,1), UBOUND(OutData%TFinRefP_n,1) + OutData%TFinRefP_n(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%TFinAngles,1) + i1_u = UBOUND(OutData%TFinAngles,1) + DO i1 = LBOUND(OutData%TFinAngles,1), UBOUND(OutData%TFinAngles,1) + OutData%TFinAngles(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%TFinIndMod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%rotors)) DEALLOCATE(OutData%rotors) - ALLOCATE(OutData%rotors(i1_l:i1_u),STAT=ErrStat2) + OutData%TFinAFID = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE AD_UnPackTFinInputFileType + + SUBROUTINE AD_CopyVTK_BLSurfaceType( SrcVTK_BLSurfaceTypeData, DstVTK_BLSurfaceTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(AD_VTK_BLSurfaceType), INTENT(IN) :: SrcVTK_BLSurfaceTypeData + TYPE(AD_VTK_BLSurfaceType), INTENT(INOUT) :: DstVTK_BLSurfaceTypeData + 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 = 'AD_CopyVTK_BLSurfaceType' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcVTK_BLSurfaceTypeData%AirfoilCoords)) THEN + i1_l = LBOUND(SrcVTK_BLSurfaceTypeData%AirfoilCoords,1) + i1_u = UBOUND(SrcVTK_BLSurfaceTypeData%AirfoilCoords,1) + i2_l = LBOUND(SrcVTK_BLSurfaceTypeData%AirfoilCoords,2) + i2_u = UBOUND(SrcVTK_BLSurfaceTypeData%AirfoilCoords,2) + i3_l = LBOUND(SrcVTK_BLSurfaceTypeData%AirfoilCoords,3) + i3_u = UBOUND(SrcVTK_BLSurfaceTypeData%AirfoilCoords,3) + IF (.NOT. ALLOCATED(DstVTK_BLSurfaceTypeData%AirfoilCoords)) THEN + ALLOCATE(DstVTK_BLSurfaceTypeData%AirfoilCoords(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%rotors.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%rotors,1), UBOUND(OutData%rotors,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AD_Unpackrotinitinputtype( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors - 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 - DO I = 1, LEN(OutData%InputFile) - OutData%InputFile(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%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) - OutData%Linearize = TRANSFER(IntKiBuf(Int_Xferred), OutData%Linearize) - Int_Xferred = Int_Xferred + 1 - OutData%Gravity = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%MHK = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%defFldDens = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%defKinVisc = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%defSpdSound = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%defPatm = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%defPvap = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%WtrDpth = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%MSL2SWL = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE AD_UnPackInitInput - - SUBROUTINE AD_CopyBladePropsType( SrcBladePropsTypeData, DstBladePropsTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(AD_BladePropsType), INTENT(IN) :: SrcBladePropsTypeData - TYPE(AD_BladePropsType), INTENT(INOUT) :: DstBladePropsTypeData - 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 = 'AD_CopyBladePropsType' -! - ErrStat = ErrID_None - ErrMsg = "" - DstBladePropsTypeData%NumBlNds = SrcBladePropsTypeData%NumBlNds -IF (ALLOCATED(SrcBladePropsTypeData%BlSpn)) THEN - i1_l = LBOUND(SrcBladePropsTypeData%BlSpn,1) - i1_u = UBOUND(SrcBladePropsTypeData%BlSpn,1) - IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlSpn)) THEN - ALLOCATE(DstBladePropsTypeData%BlSpn(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlSpn.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladePropsTypeData%BlSpn = SrcBladePropsTypeData%BlSpn -ENDIF -IF (ALLOCATED(SrcBladePropsTypeData%BlCrvAC)) THEN - i1_l = LBOUND(SrcBladePropsTypeData%BlCrvAC,1) - i1_u = UBOUND(SrcBladePropsTypeData%BlCrvAC,1) - IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlCrvAC)) THEN - ALLOCATE(DstBladePropsTypeData%BlCrvAC(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlCrvAC.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladePropsTypeData%BlCrvAC = SrcBladePropsTypeData%BlCrvAC -ENDIF -IF (ALLOCATED(SrcBladePropsTypeData%BlSwpAC)) THEN - i1_l = LBOUND(SrcBladePropsTypeData%BlSwpAC,1) - i1_u = UBOUND(SrcBladePropsTypeData%BlSwpAC,1) - IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlSwpAC)) THEN - ALLOCATE(DstBladePropsTypeData%BlSwpAC(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlSwpAC.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladePropsTypeData%BlSwpAC = SrcBladePropsTypeData%BlSwpAC -ENDIF -IF (ALLOCATED(SrcBladePropsTypeData%BlCrvAng)) THEN - i1_l = LBOUND(SrcBladePropsTypeData%BlCrvAng,1) - i1_u = UBOUND(SrcBladePropsTypeData%BlCrvAng,1) - IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlCrvAng)) THEN - ALLOCATE(DstBladePropsTypeData%BlCrvAng(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlCrvAng.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladePropsTypeData%BlCrvAng = SrcBladePropsTypeData%BlCrvAng -ENDIF -IF (ALLOCATED(SrcBladePropsTypeData%BlTwist)) THEN - i1_l = LBOUND(SrcBladePropsTypeData%BlTwist,1) - i1_u = UBOUND(SrcBladePropsTypeData%BlTwist,1) - IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlTwist)) THEN - ALLOCATE(DstBladePropsTypeData%BlTwist(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlTwist.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladePropsTypeData%BlTwist = SrcBladePropsTypeData%BlTwist -ENDIF -IF (ALLOCATED(SrcBladePropsTypeData%BlChord)) THEN - i1_l = LBOUND(SrcBladePropsTypeData%BlChord,1) - i1_u = UBOUND(SrcBladePropsTypeData%BlChord,1) - IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlChord)) THEN - ALLOCATE(DstBladePropsTypeData%BlChord(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlChord.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladePropsTypeData%BlChord = SrcBladePropsTypeData%BlChord -ENDIF -IF (ALLOCATED(SrcBladePropsTypeData%BlAFID)) THEN - i1_l = LBOUND(SrcBladePropsTypeData%BlAFID,1) - i1_u = UBOUND(SrcBladePropsTypeData%BlAFID,1) - IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlAFID)) THEN - ALLOCATE(DstBladePropsTypeData%BlAFID(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlAFID.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstVTK_BLSurfaceTypeData%AirfoilCoords.', ErrStat, ErrMsg,RoutineName) + RETURN END IF END IF - DstBladePropsTypeData%BlAFID = SrcBladePropsTypeData%BlAFID + DstVTK_BLSurfaceTypeData%AirfoilCoords = SrcVTK_BLSurfaceTypeData%AirfoilCoords ENDIF - END SUBROUTINE AD_CopyBladePropsType + END SUBROUTINE AD_CopyVTK_BLSurfaceType - SUBROUTINE AD_DestroyBladePropsType( BladePropsTypeData, ErrStat, ErrMsg ) - TYPE(AD_BladePropsType), INTENT(INOUT) :: BladePropsTypeData + SUBROUTINE AD_DestroyVTK_BLSurfaceType( VTK_BLSurfaceTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(AD_VTK_BLSurfaceType), INTENT(INOUT) :: VTK_BLSurfaceTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyBladePropsType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyVTK_BLSurfaceType' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(BladePropsTypeData%BlSpn)) THEN - DEALLOCATE(BladePropsTypeData%BlSpn) -ENDIF -IF (ALLOCATED(BladePropsTypeData%BlCrvAC)) THEN - DEALLOCATE(BladePropsTypeData%BlCrvAC) -ENDIF -IF (ALLOCATED(BladePropsTypeData%BlSwpAC)) THEN - DEALLOCATE(BladePropsTypeData%BlSwpAC) -ENDIF -IF (ALLOCATED(BladePropsTypeData%BlCrvAng)) THEN - DEALLOCATE(BladePropsTypeData%BlCrvAng) -ENDIF -IF (ALLOCATED(BladePropsTypeData%BlTwist)) THEN - DEALLOCATE(BladePropsTypeData%BlTwist) -ENDIF -IF (ALLOCATED(BladePropsTypeData%BlChord)) THEN - DEALLOCATE(BladePropsTypeData%BlChord) -ENDIF -IF (ALLOCATED(BladePropsTypeData%BlAFID)) THEN - DEALLOCATE(BladePropsTypeData%BlAFID) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(VTK_BLSurfaceTypeData%AirfoilCoords)) THEN + DEALLOCATE(VTK_BLSurfaceTypeData%AirfoilCoords) ENDIF - END SUBROUTINE AD_DestroyBladePropsType + END SUBROUTINE AD_DestroyVTK_BLSurfaceType - SUBROUTINE AD_PackBladePropsType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE AD_PackVTK_BLSurfaceType( 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(AD_BladePropsType), INTENT(IN) :: InData + TYPE(AD_VTK_BLSurfaceType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -1300,7 +918,7 @@ SUBROUTINE AD_PackBladePropsType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackBladePropsType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackVTK_BLSurfaceType' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -1316,55 +934,24 @@ SUBROUTINE AD_PackBladePropsType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! NumBlNds - Int_BufSz = Int_BufSz + 1 ! BlSpn allocated yes/no - IF ( ALLOCATED(InData%BlSpn) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! BlSpn upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%BlSpn) ! BlSpn - END IF - Int_BufSz = Int_BufSz + 1 ! BlCrvAC allocated yes/no - IF ( ALLOCATED(InData%BlCrvAC) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! BlCrvAC upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%BlCrvAC) ! BlCrvAC + Int_BufSz = Int_BufSz + 1 ! AirfoilCoords allocated yes/no + IF ( ALLOCATED(InData%AirfoilCoords) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! AirfoilCoords upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AirfoilCoords) ! AirfoilCoords END IF - Int_BufSz = Int_BufSz + 1 ! BlSwpAC allocated yes/no - IF ( ALLOCATED(InData%BlSwpAC) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! BlSwpAC upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%BlSwpAC) ! BlSwpAC + 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 - Int_BufSz = Int_BufSz + 1 ! BlCrvAng allocated yes/no - IF ( ALLOCATED(InData%BlCrvAng) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! BlCrvAng upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%BlCrvAng) ! BlCrvAng - END IF - Int_BufSz = Int_BufSz + 1 ! BlTwist allocated yes/no - IF ( ALLOCATED(InData%BlTwist) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! BlTwist upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%BlTwist) ! BlTwist - END IF - Int_BufSz = Int_BufSz + 1 ! BlChord allocated yes/no - IF ( ALLOCATED(InData%BlChord) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! BlChord upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%BlChord) ! BlChord - END IF - Int_BufSz = Int_BufSz + 1 ! BlAFID allocated yes/no - IF ( ALLOCATED(InData%BlAFID) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! BlAFID upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%BlAFID) ! BlAFID - 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 + 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 ) @@ -1379,120 +966,38 @@ SUBROUTINE AD_PackBladePropsType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = InData%NumBlNds - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%BlSpn) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BlSpn,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlSpn,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%BlSpn,1), UBOUND(InData%BlSpn,1) - ReKiBuf(Re_Xferred) = InData%BlSpn(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%BlCrvAC) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BlCrvAC,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlCrvAC,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%BlCrvAC,1), UBOUND(InData%BlCrvAC,1) - ReKiBuf(Re_Xferred) = InData%BlCrvAC(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%BlSwpAC) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BlSwpAC,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlSwpAC,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%BlSwpAC,1), UBOUND(InData%BlSwpAC,1) - ReKiBuf(Re_Xferred) = InData%BlSwpAC(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%BlCrvAng) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BlCrvAng,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlCrvAng,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%BlCrvAng,1), UBOUND(InData%BlCrvAng,1) - ReKiBuf(Re_Xferred) = InData%BlCrvAng(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%BlTwist) ) THEN + IF ( .NOT. ALLOCATED(InData%AirfoilCoords) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BlTwist,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlTwist,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AirfoilCoords,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AirfoilCoords,1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%BlTwist,1), UBOUND(InData%BlTwist,1) - ReKiBuf(Re_Xferred) = InData%BlTwist(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%BlChord) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BlChord,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlChord,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AirfoilCoords,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AirfoilCoords,2) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%BlChord,1), UBOUND(InData%BlChord,1) - ReKiBuf(Re_Xferred) = InData%BlChord(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%BlAFID) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BlAFID,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlAFID,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AirfoilCoords,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AirfoilCoords,3) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%BlAFID,1), UBOUND(InData%BlAFID,1) - IntKiBuf(Int_Xferred) = InData%BlAFID(i1) - Int_Xferred = Int_Xferred + 1 + DO i3 = LBOUND(InData%AirfoilCoords,3), UBOUND(InData%AirfoilCoords,3) + DO i2 = LBOUND(InData%AirfoilCoords,2), UBOUND(InData%AirfoilCoords,2) + DO i1 = LBOUND(InData%AirfoilCoords,1), UBOUND(InData%AirfoilCoords,1) + ReKiBuf(Re_Xferred) = InData%AirfoilCoords(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO END IF - END SUBROUTINE AD_PackBladePropsType + END SUBROUTINE AD_PackVTK_BLSurfaceType - SUBROUTINE AD_UnPackBladePropsType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_UnPackVTK_BLSurfaceType( 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(AD_BladePropsType), INTENT(INOUT) :: OutData + TYPE(AD_VTK_BLSurfaceType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -1502,9 +1007,11 @@ SUBROUTINE AD_UnPackBladePropsType( 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) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackBladePropsType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackVTK_BLSurfaceType' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -1515,190 +1022,119 @@ SUBROUTINE AD_UnPackBladePropsType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%NumBlNds = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlSpn not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AirfoilCoords not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BlSpn)) DEALLOCATE(OutData%BlSpn) - ALLOCATE(OutData%BlSpn(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlSpn.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%BlSpn,1), UBOUND(OutData%BlSpn,1) - OutData%BlSpn(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlCrvAC not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BlCrvAC)) DEALLOCATE(OutData%BlCrvAC) - ALLOCATE(OutData%BlCrvAC(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlCrvAC.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%BlCrvAC,1), UBOUND(OutData%BlCrvAC,1) - OutData%BlCrvAC(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlSwpAC not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BlSwpAC)) DEALLOCATE(OutData%BlSwpAC) - ALLOCATE(OutData%BlSwpAC(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%AirfoilCoords)) DEALLOCATE(OutData%AirfoilCoords) + ALLOCATE(OutData%AirfoilCoords(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%BlSwpAC.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AirfoilCoords.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%BlSwpAC,1), UBOUND(OutData%BlSwpAC,1) - OutData%BlSwpAC(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(OutData%AirfoilCoords,3), UBOUND(OutData%AirfoilCoords,3) + DO i2 = LBOUND(OutData%AirfoilCoords,2), UBOUND(OutData%AirfoilCoords,2) + DO i1 = LBOUND(OutData%AirfoilCoords,1), UBOUND(OutData%AirfoilCoords,1) + OutData%AirfoilCoords(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 ! BlCrvAng not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BlCrvAng)) DEALLOCATE(OutData%BlCrvAng) - ALLOCATE(OutData%BlCrvAng(i1_l:i1_u),STAT=ErrStat2) + END SUBROUTINE AD_UnPackVTK_BLSurfaceType + + SUBROUTINE AD_CopyVTK_RotSurfaceType( SrcVTK_RotSurfaceTypeData, DstVTK_RotSurfaceTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(AD_VTK_RotSurfaceType), INTENT(IN) :: SrcVTK_RotSurfaceTypeData + TYPE(AD_VTK_RotSurfaceType), INTENT(INOUT) :: DstVTK_RotSurfaceTypeData + 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 = 'AD_CopyVTK_RotSurfaceType' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcVTK_RotSurfaceTypeData%BladeShape)) THEN + i1_l = LBOUND(SrcVTK_RotSurfaceTypeData%BladeShape,1) + i1_u = UBOUND(SrcVTK_RotSurfaceTypeData%BladeShape,1) + IF (.NOT. ALLOCATED(DstVTK_RotSurfaceTypeData%BladeShape)) THEN + ALLOCATE(DstVTK_RotSurfaceTypeData%BladeShape(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlCrvAng.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstVTK_RotSurfaceTypeData%BladeShape.', ErrStat, ErrMsg,RoutineName) + RETURN END IF - DO i1 = LBOUND(OutData%BlCrvAng,1), UBOUND(OutData%BlCrvAng,1) - OutData%BlCrvAng(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlTwist not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BlTwist)) DEALLOCATE(OutData%BlTwist) - ALLOCATE(OutData%BlTwist(i1_l:i1_u),STAT=ErrStat2) + DO i1 = LBOUND(SrcVTK_RotSurfaceTypeData%BladeShape,1), UBOUND(SrcVTK_RotSurfaceTypeData%BladeShape,1) + CALL AD_Copyvtk_blsurfacetype( SrcVTK_RotSurfaceTypeData%BladeShape(i1), DstVTK_RotSurfaceTypeData%BladeShape(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcVTK_RotSurfaceTypeData%TowerRad)) THEN + i1_l = LBOUND(SrcVTK_RotSurfaceTypeData%TowerRad,1) + i1_u = UBOUND(SrcVTK_RotSurfaceTypeData%TowerRad,1) + IF (.NOT. ALLOCATED(DstVTK_RotSurfaceTypeData%TowerRad)) THEN + ALLOCATE(DstVTK_RotSurfaceTypeData%TowerRad(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlTwist.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstVTK_RotSurfaceTypeData%TowerRad.', ErrStat, ErrMsg,RoutineName) + RETURN END IF - DO i1 = LBOUND(OutData%BlTwist,1), UBOUND(OutData%BlTwist,1) - OutData%BlTwist(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlChord not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BlChord)) DEALLOCATE(OutData%BlChord) - ALLOCATE(OutData%BlChord(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlChord.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%BlChord,1), UBOUND(OutData%BlChord,1) - OutData%BlChord(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlAFID not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BlAFID)) DEALLOCATE(OutData%BlAFID) - ALLOCATE(OutData%BlAFID(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlAFID.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%BlAFID,1), UBOUND(OutData%BlAFID,1) - OutData%BlAFID(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - END SUBROUTINE AD_UnPackBladePropsType - - SUBROUTINE AD_CopyBladeShape( SrcBladeShapeData, DstBladeShapeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(AD_BladeShape), INTENT(IN) :: SrcBladeShapeData - TYPE(AD_BladeShape), INTENT(INOUT) :: DstBladeShapeData - 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 = 'AD_CopyBladeShape' -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(SrcBladeShapeData%AirfoilCoords)) THEN - i1_l = LBOUND(SrcBladeShapeData%AirfoilCoords,1) - i1_u = UBOUND(SrcBladeShapeData%AirfoilCoords,1) - i2_l = LBOUND(SrcBladeShapeData%AirfoilCoords,2) - i2_u = UBOUND(SrcBladeShapeData%AirfoilCoords,2) - i3_l = LBOUND(SrcBladeShapeData%AirfoilCoords,3) - i3_u = UBOUND(SrcBladeShapeData%AirfoilCoords,3) - IF (.NOT. ALLOCATED(DstBladeShapeData%AirfoilCoords)) THEN - ALLOCATE(DstBladeShapeData%AirfoilCoords(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeShapeData%AirfoilCoords.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladeShapeData%AirfoilCoords = SrcBladeShapeData%AirfoilCoords + DstVTK_RotSurfaceTypeData%TowerRad = SrcVTK_RotSurfaceTypeData%TowerRad ENDIF - END SUBROUTINE AD_CopyBladeShape + END SUBROUTINE AD_CopyVTK_RotSurfaceType - SUBROUTINE AD_DestroyBladeShape( BladeShapeData, ErrStat, ErrMsg ) - TYPE(AD_BladeShape), INTENT(INOUT) :: BladeShapeData + SUBROUTINE AD_DestroyVTK_RotSurfaceType( VTK_RotSurfaceTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(AD_VTK_RotSurfaceType), INTENT(INOUT) :: VTK_RotSurfaceTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyBladeShape' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyVTK_RotSurfaceType' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(BladeShapeData%AirfoilCoords)) THEN - DEALLOCATE(BladeShapeData%AirfoilCoords) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(VTK_RotSurfaceTypeData%BladeShape)) THEN +DO i1 = LBOUND(VTK_RotSurfaceTypeData%BladeShape,1), UBOUND(VTK_RotSurfaceTypeData%BladeShape,1) + CALL AD_Destroyvtk_blsurfacetype( VTK_RotSurfaceTypeData%BladeShape(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(VTK_RotSurfaceTypeData%BladeShape) ENDIF - END SUBROUTINE AD_DestroyBladeShape +IF (ALLOCATED(VTK_RotSurfaceTypeData%TowerRad)) THEN + DEALLOCATE(VTK_RotSurfaceTypeData%TowerRad) +ENDIF + END SUBROUTINE AD_DestroyVTK_RotSurfaceType - SUBROUTINE AD_PackBladeShape( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE AD_PackVTK_RotSurfaceType( 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(AD_BladeShape), INTENT(IN) :: InData + TYPE(AD_VTK_RotSurfaceType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -1713,7 +1149,7 @@ SUBROUTINE AD_PackBladeShape( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackBladeShape' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackVTK_RotSurfaceType' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -1729,10 +1165,34 @@ SUBROUTINE AD_PackBladeShape( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! AirfoilCoords allocated yes/no - IF ( ALLOCATED(InData%AirfoilCoords) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! AirfoilCoords upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%AirfoilCoords) ! AirfoilCoords + Int_BufSz = Int_BufSz + 1 ! BladeShape allocated yes/no + IF ( ALLOCATED(InData%BladeShape) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BladeShape upper/lower bounds for each dimension + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%BladeShape,1), UBOUND(InData%BladeShape,1) + Int_BufSz = Int_BufSz + 3 ! BladeShape: size of buffers for each call to pack subtype + CALL AD_Packvtk_blsurfacetype( Re_Buf, Db_Buf, Int_Buf, InData%BladeShape(i1), ErrStat2, ErrMsg2, .TRUE. ) ! BladeShape + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BladeShape + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BladeShape + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BladeShape + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! TowerRad allocated yes/no + IF ( ALLOCATED(InData%TowerRad) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TowerRad upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TowerRad) ! TowerRad END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -1761,38 +1221,69 @@ SUBROUTINE AD_PackBladeShape( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = 1 Int_Xferred = 1 - IF ( .NOT. ALLOCATED(InData%AirfoilCoords) ) THEN + IF ( .NOT. ALLOCATED(InData%BladeShape) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AirfoilCoords,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AirfoilCoords,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AirfoilCoords,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AirfoilCoords,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeShape,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeShape,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AirfoilCoords,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AirfoilCoords,3) + + DO i1 = LBOUND(InData%BladeShape,1), UBOUND(InData%BladeShape,1) + CALL AD_Packvtk_blsurfacetype( Re_Buf, Db_Buf, Int_Buf, InData%BladeShape(i1), ErrStat2, ErrMsg2, OnlySize ) ! BladeShape + 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%TowerRad) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TowerRad,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TowerRad,1) Int_Xferred = Int_Xferred + 2 - DO i3 = LBOUND(InData%AirfoilCoords,3), UBOUND(InData%AirfoilCoords,3) - DO i2 = LBOUND(InData%AirfoilCoords,2), UBOUND(InData%AirfoilCoords,2) - DO i1 = LBOUND(InData%AirfoilCoords,1), UBOUND(InData%AirfoilCoords,1) - ReKiBuf(Re_Xferred) = InData%AirfoilCoords(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i1 = LBOUND(InData%TowerRad,1), UBOUND(InData%TowerRad,1) + ReKiBuf(Re_Xferred) = InData%TowerRad(i1) + Re_Xferred = Re_Xferred + 1 END DO END IF - END SUBROUTINE AD_PackBladeShape + END SUBROUTINE AD_PackVTK_RotSurfaceType - SUBROUTINE AD_UnPackBladeShape( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_UnPackVTK_RotSurfaceType( 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(AD_BladeShape), INTENT(INOUT) :: OutData + TYPE(AD_VTK_RotSurfaceType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -1802,11 +1293,9 @@ SUBROUTINE AD_UnPackBladeShape( 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) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackBladeShape' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackVTK_RotSurfaceType' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -1817,294 +1306,172 @@ SUBROUTINE AD_UnPackBladeShape( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AirfoilCoords not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeShape not allocated Int_Xferred = Int_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) + IF (ALLOCATED(OutData%BladeShape)) DEALLOCATE(OutData%BladeShape) + ALLOCATE(OutData%BladeShape(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeShape.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BladeShape,1), UBOUND(OutData%BladeShape,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL AD_Unpackvtk_blsurfacetype( Re_Buf, Db_Buf, Int_Buf, OutData%BladeShape(i1), ErrStat2, ErrMsg2 ) ! BladeShape + 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 ! TowerRad not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%AirfoilCoords)) DEALLOCATE(OutData%AirfoilCoords) - ALLOCATE(OutData%AirfoilCoords(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%TowerRad)) DEALLOCATE(OutData%TowerRad) + ALLOCATE(OutData%TowerRad(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AirfoilCoords.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TowerRad.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i3 = LBOUND(OutData%AirfoilCoords,3), UBOUND(OutData%AirfoilCoords,3) - DO i2 = LBOUND(OutData%AirfoilCoords,2), UBOUND(OutData%AirfoilCoords,2) - DO i1 = LBOUND(OutData%AirfoilCoords,1), UBOUND(OutData%AirfoilCoords,1) - OutData%AirfoilCoords(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i1 = LBOUND(OutData%TowerRad,1), UBOUND(OutData%TowerRad,1) + OutData%TowerRad(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 END DO END IF - END SUBROUTINE AD_UnPackBladeShape + END SUBROUTINE AD_UnPackVTK_RotSurfaceType - SUBROUTINE AD_CopyRotInitOutputType( SrcRotInitOutputTypeData, DstRotInitOutputTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(RotInitOutputType), INTENT(IN) :: SrcRotInitOutputTypeData - TYPE(RotInitOutputType), INTENT(INOUT) :: DstRotInitOutputTypeData + SUBROUTINE AD_CopyRotInitInputType( SrcRotInitInputTypeData, DstRotInitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(RotInitInputType), INTENT(IN) :: SrcRotInitInputTypeData + TYPE(RotInitInputType), INTENT(INOUT) :: DstRotInitInputTypeData 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 = 'AD_CopyRotInitOutputType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyRotInitInputType' ! ErrStat = ErrID_None ErrMsg = "" - DstRotInitOutputTypeData%AirDens = SrcRotInitOutputTypeData%AirDens -IF (ALLOCATED(SrcRotInitOutputTypeData%WriteOutputHdr)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%WriteOutputHdr,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%WriteOutputHdr,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%WriteOutputHdr)) THEN - ALLOCATE(DstRotInitOutputTypeData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotInitOutputTypeData%WriteOutputHdr = SrcRotInitOutputTypeData%WriteOutputHdr -ENDIF -IF (ALLOCATED(SrcRotInitOutputTypeData%WriteOutputUnt)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%WriteOutputUnt,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%WriteOutputUnt,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%WriteOutputUnt)) THEN - ALLOCATE(DstRotInitOutputTypeData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotInitOutputTypeData%WriteOutputUnt = SrcRotInitOutputTypeData%WriteOutputUnt -ENDIF -IF (ALLOCATED(SrcRotInitOutputTypeData%BladeShape)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%BladeShape,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%BladeShape,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%BladeShape)) THEN - ALLOCATE(DstRotInitOutputTypeData%BladeShape(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%BladeShape.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcRotInitOutputTypeData%BladeShape,1), UBOUND(SrcRotInitOutputTypeData%BladeShape,1) - CALL AD_Copybladeshape( SrcRotInitOutputTypeData%BladeShape(i1), DstRotInitOutputTypeData%BladeShape(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF -IF (ALLOCATED(SrcRotInitOutputTypeData%LinNames_y)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%LinNames_y,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%LinNames_y,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%LinNames_y)) THEN - ALLOCATE(DstRotInitOutputTypeData%LinNames_y(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%LinNames_y.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotInitOutputTypeData%LinNames_y = SrcRotInitOutputTypeData%LinNames_y -ENDIF -IF (ALLOCATED(SrcRotInitOutputTypeData%LinNames_x)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%LinNames_x,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%LinNames_x,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%LinNames_x)) THEN - ALLOCATE(DstRotInitOutputTypeData%LinNames_x(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%LinNames_x.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotInitOutputTypeData%LinNames_x = SrcRotInitOutputTypeData%LinNames_x -ENDIF -IF (ALLOCATED(SrcRotInitOutputTypeData%LinNames_u)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%LinNames_u,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%LinNames_u,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%LinNames_u)) THEN - ALLOCATE(DstRotInitOutputTypeData%LinNames_u(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%LinNames_u.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotInitOutputTypeData%LinNames_u = SrcRotInitOutputTypeData%LinNames_u -ENDIF -IF (ALLOCATED(SrcRotInitOutputTypeData%RotFrame_y)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%RotFrame_y,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%RotFrame_y,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%RotFrame_y)) THEN - ALLOCATE(DstRotInitOutputTypeData%RotFrame_y(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%RotFrame_y.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotInitOutputTypeData%RotFrame_y = SrcRotInitOutputTypeData%RotFrame_y -ENDIF -IF (ALLOCATED(SrcRotInitOutputTypeData%RotFrame_x)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%RotFrame_x,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%RotFrame_x,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%RotFrame_x)) THEN - ALLOCATE(DstRotInitOutputTypeData%RotFrame_x(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%RotFrame_x.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotInitOutputTypeData%RotFrame_x = SrcRotInitOutputTypeData%RotFrame_x -ENDIF -IF (ALLOCATED(SrcRotInitOutputTypeData%RotFrame_u)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%RotFrame_u,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%RotFrame_u,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%RotFrame_u)) THEN - ALLOCATE(DstRotInitOutputTypeData%RotFrame_u(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%RotFrame_u.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotInitOutputTypeData%RotFrame_u = SrcRotInitOutputTypeData%RotFrame_u -ENDIF -IF (ALLOCATED(SrcRotInitOutputTypeData%IsLoad_u)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%IsLoad_u,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%IsLoad_u,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%IsLoad_u)) THEN - ALLOCATE(DstRotInitOutputTypeData%IsLoad_u(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%IsLoad_u.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotInitOutputTypeData%IsLoad_u = SrcRotInitOutputTypeData%IsLoad_u -ENDIF -IF (ALLOCATED(SrcRotInitOutputTypeData%BladeProps)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%BladeProps,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%BladeProps,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%BladeProps)) THEN - ALLOCATE(DstRotInitOutputTypeData%BladeProps(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%BladeProps.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcRotInitOutputTypeData%BladeProps,1), UBOUND(SrcRotInitOutputTypeData%BladeProps,1) - CALL AD_Copybladepropstype( SrcRotInitOutputTypeData%BladeProps(i1), DstRotInitOutputTypeData%BladeProps(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF -IF (ALLOCATED(SrcRotInitOutputTypeData%DerivOrder_x)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%DerivOrder_x,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%DerivOrder_x,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%DerivOrder_x)) THEN - ALLOCATE(DstRotInitOutputTypeData%DerivOrder_x(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%DerivOrder_x.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotInitOutputTypeData%DerivOrder_x = SrcRotInitOutputTypeData%DerivOrder_x -ENDIF -IF (ALLOCATED(SrcRotInitOutputTypeData%TwrElev)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%TwrElev,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%TwrElev,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%TwrElev)) THEN - ALLOCATE(DstRotInitOutputTypeData%TwrElev(i1_l:i1_u),STAT=ErrStat2) + DstRotInitInputTypeData%NumBlades = SrcRotInitInputTypeData%NumBlades + DstRotInitInputTypeData%HubPosition = SrcRotInitInputTypeData%HubPosition + DstRotInitInputTypeData%HubOrientation = SrcRotInitInputTypeData%HubOrientation +IF (ALLOCATED(SrcRotInitInputTypeData%BladeRootPosition)) THEN + i1_l = LBOUND(SrcRotInitInputTypeData%BladeRootPosition,1) + i1_u = UBOUND(SrcRotInitInputTypeData%BladeRootPosition,1) + i2_l = LBOUND(SrcRotInitInputTypeData%BladeRootPosition,2) + i2_u = UBOUND(SrcRotInitInputTypeData%BladeRootPosition,2) + IF (.NOT. ALLOCATED(DstRotInitInputTypeData%BladeRootPosition)) THEN + ALLOCATE(DstRotInitInputTypeData%BladeRootPosition(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%TwrElev.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitInputTypeData%BladeRootPosition.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstRotInitOutputTypeData%TwrElev = SrcRotInitOutputTypeData%TwrElev + DstRotInitInputTypeData%BladeRootPosition = SrcRotInitInputTypeData%BladeRootPosition ENDIF -IF (ALLOCATED(SrcRotInitOutputTypeData%TwrDiam)) THEN - i1_l = LBOUND(SrcRotInitOutputTypeData%TwrDiam,1) - i1_u = UBOUND(SrcRotInitOutputTypeData%TwrDiam,1) - IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%TwrDiam)) THEN - ALLOCATE(DstRotInitOutputTypeData%TwrDiam(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRotInitInputTypeData%BladeRootOrientation)) THEN + i1_l = LBOUND(SrcRotInitInputTypeData%BladeRootOrientation,1) + i1_u = UBOUND(SrcRotInitInputTypeData%BladeRootOrientation,1) + i2_l = LBOUND(SrcRotInitInputTypeData%BladeRootOrientation,2) + i2_u = UBOUND(SrcRotInitInputTypeData%BladeRootOrientation,2) + i3_l = LBOUND(SrcRotInitInputTypeData%BladeRootOrientation,3) + i3_u = UBOUND(SrcRotInitInputTypeData%BladeRootOrientation,3) + IF (.NOT. ALLOCATED(DstRotInitInputTypeData%BladeRootOrientation)) THEN + ALLOCATE(DstRotInitInputTypeData%BladeRootOrientation(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%TwrDiam.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitInputTypeData%BladeRootOrientation.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstRotInitOutputTypeData%TwrDiam = SrcRotInitOutputTypeData%TwrDiam + DstRotInitInputTypeData%BladeRootOrientation = SrcRotInitInputTypeData%BladeRootOrientation ENDIF - END SUBROUTINE AD_CopyRotInitOutputType + DstRotInitInputTypeData%NacellePosition = SrcRotInitInputTypeData%NacellePosition + DstRotInitInputTypeData%NacelleOrientation = SrcRotInitInputTypeData%NacelleOrientation + DstRotInitInputTypeData%AeroProjMod = SrcRotInitInputTypeData%AeroProjMod + DstRotInitInputTypeData%AeroBEM_Mod = SrcRotInitInputTypeData%AeroBEM_Mod + END SUBROUTINE AD_CopyRotInitInputType - SUBROUTINE AD_DestroyRotInitOutputType( RotInitOutputTypeData, ErrStat, ErrMsg ) - TYPE(RotInitOutputType), INTENT(INOUT) :: RotInitOutputTypeData + SUBROUTINE AD_DestroyRotInitInputType( RotInitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(RotInitInputType), INTENT(INOUT) :: RotInitInputTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotInitOutputType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotInitInputType' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(RotInitOutputTypeData%WriteOutputHdr)) THEN - DEALLOCATE(RotInitOutputTypeData%WriteOutputHdr) -ENDIF -IF (ALLOCATED(RotInitOutputTypeData%WriteOutputUnt)) THEN - DEALLOCATE(RotInitOutputTypeData%WriteOutputUnt) -ENDIF -IF (ALLOCATED(RotInitOutputTypeData%BladeShape)) THEN -DO i1 = LBOUND(RotInitOutputTypeData%BladeShape,1), UBOUND(RotInitOutputTypeData%BladeShape,1) - CALL AD_Destroybladeshape( RotInitOutputTypeData%BladeShape(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(RotInitOutputTypeData%BladeShape) -ENDIF -IF (ALLOCATED(RotInitOutputTypeData%LinNames_y)) THEN - DEALLOCATE(RotInitOutputTypeData%LinNames_y) -ENDIF -IF (ALLOCATED(RotInitOutputTypeData%LinNames_x)) THEN - DEALLOCATE(RotInitOutputTypeData%LinNames_x) -ENDIF -IF (ALLOCATED(RotInitOutputTypeData%LinNames_u)) THEN - DEALLOCATE(RotInitOutputTypeData%LinNames_u) -ENDIF -IF (ALLOCATED(RotInitOutputTypeData%RotFrame_y)) THEN - DEALLOCATE(RotInitOutputTypeData%RotFrame_y) -ENDIF -IF (ALLOCATED(RotInitOutputTypeData%RotFrame_x)) THEN - DEALLOCATE(RotInitOutputTypeData%RotFrame_x) -ENDIF -IF (ALLOCATED(RotInitOutputTypeData%RotFrame_u)) THEN - DEALLOCATE(RotInitOutputTypeData%RotFrame_u) -ENDIF -IF (ALLOCATED(RotInitOutputTypeData%IsLoad_u)) THEN - DEALLOCATE(RotInitOutputTypeData%IsLoad_u) -ENDIF -IF (ALLOCATED(RotInitOutputTypeData%BladeProps)) THEN -DO i1 = LBOUND(RotInitOutputTypeData%BladeProps,1), UBOUND(RotInitOutputTypeData%BladeProps,1) - CALL AD_Destroybladepropstype( RotInitOutputTypeData%BladeProps(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(RotInitOutputTypeData%BladeProps) -ENDIF -IF (ALLOCATED(RotInitOutputTypeData%DerivOrder_x)) THEN - DEALLOCATE(RotInitOutputTypeData%DerivOrder_x) -ENDIF -IF (ALLOCATED(RotInitOutputTypeData%TwrElev)) THEN - DEALLOCATE(RotInitOutputTypeData%TwrElev) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(RotInitInputTypeData%BladeRootPosition)) THEN + DEALLOCATE(RotInitInputTypeData%BladeRootPosition) ENDIF -IF (ALLOCATED(RotInitOutputTypeData%TwrDiam)) THEN - DEALLOCATE(RotInitOutputTypeData%TwrDiam) +IF (ALLOCATED(RotInitInputTypeData%BladeRootOrientation)) THEN + DEALLOCATE(RotInitInputTypeData%BladeRootOrientation) ENDIF - END SUBROUTINE AD_DestroyRotInitOutputType + END SUBROUTINE AD_DestroyRotInitInputType - SUBROUTINE AD_PackRotInitOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE AD_PackRotInitInputType( 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(RotInitOutputType), INTENT(IN) :: InData + TYPE(RotInitInputType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -2119,7 +1486,7 @@ SUBROUTINE AD_PackRotInitOutputType( 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 = 'AD_PackRotInitOutputType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackRotInitInputType' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -2135,114 +1502,23 @@ SUBROUTINE AD_PackRotInitOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! AirDens - 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 - Int_BufSz = Int_BufSz + 1 ! BladeShape allocated yes/no - IF ( ALLOCATED(InData%BladeShape) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! BladeShape upper/lower bounds for each dimension - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - DO i1 = LBOUND(InData%BladeShape,1), UBOUND(InData%BladeShape,1) - Int_BufSz = Int_BufSz + 3 ! BladeShape: size of buffers for each call to pack subtype - CALL AD_Packbladeshape( Re_Buf, Db_Buf, Int_Buf, InData%BladeShape(i1), ErrStat2, ErrMsg2, .TRUE. ) ! BladeShape - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! BladeShape - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! BladeShape - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! BladeShape - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - 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 ! BladeProps allocated yes/no - IF ( ALLOCATED(InData%BladeProps) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! BladeProps upper/lower bounds for each dimension - DO i1 = LBOUND(InData%BladeProps,1), UBOUND(InData%BladeProps,1) - Int_BufSz = Int_BufSz + 3 ! BladeProps: size of buffers for each call to pack subtype - CALL AD_Packbladepropstype( Re_Buf, Db_Buf, Int_Buf, InData%BladeProps(i1), ErrStat2, ErrMsg2, .TRUE. ) ! BladeProps - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! BladeProps - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! BladeProps - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! BladeProps - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - 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 - Int_BufSz = Int_BufSz + 1 ! TwrElev allocated yes/no - IF ( ALLOCATED(InData%TwrElev) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! TwrElev upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TwrElev) ! TwrElev + Int_BufSz = Int_BufSz + 1 ! NumBlades + Re_BufSz = Re_BufSz + SIZE(InData%HubPosition) ! HubPosition + Db_BufSz = Db_BufSz + SIZE(InData%HubOrientation) ! HubOrientation + Int_BufSz = Int_BufSz + 1 ! BladeRootPosition allocated yes/no + IF ( ALLOCATED(InData%BladeRootPosition) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! BladeRootPosition upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BladeRootPosition) ! BladeRootPosition END IF - Int_BufSz = Int_BufSz + 1 ! TwrDiam allocated yes/no - IF ( ALLOCATED(InData%TwrDiam) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! TwrDiam upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TwrDiam) ! TwrDiam + Int_BufSz = Int_BufSz + 1 ! BladeRootOrientation allocated yes/no + IF ( ALLOCATED(InData%BladeRootOrientation) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! BladeRootOrientation upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%BladeRootOrientation) ! BladeRootOrientation END IF + Db_BufSz = Db_BufSz + SIZE(InData%NacellePosition) ! NacellePosition + Db_BufSz = Db_BufSz + SIZE(InData%NacelleOrientation) ! NacelleOrientation + Int_BufSz = Int_BufSz + 1 ! AeroProjMod + Int_BufSz = Int_BufSz + 1 ! AeroBEM_Mod IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -2270,287 +1546,84 @@ SUBROUTINE AD_PackRotInitOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Db_Xferred = 1 Int_Xferred = 1 - ReKiBuf(Re_Xferred) = InData%AirDens - Re_Xferred = Re_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%WriteOutputHdr) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 + IntKiBuf(Int_Xferred) = InData%NumBlades 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 + DO i1 = LBOUND(InData%HubPosition,1), UBOUND(InData%HubPosition,1) + ReKiBuf(Re_Xferred) = InData%HubPosition(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i2 = LBOUND(InData%HubOrientation,2), UBOUND(InData%HubOrientation,2) + DO i1 = LBOUND(InData%HubOrientation,1), UBOUND(InData%HubOrientation,1) + DbKiBuf(Db_Xferred) = InData%HubOrientation(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO - END IF - IF ( .NOT. ALLOCATED(InData%WriteOutputUnt) ) THEN + END DO + IF ( .NOT. ALLOCATED(InData%BladeRootPosition) ) THEN 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%BladeRootPosition,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootPosition,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeRootPosition,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootPosition,2) 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 + DO i2 = LBOUND(InData%BladeRootPosition,2), UBOUND(InData%BladeRootPosition,2) + DO i1 = LBOUND(InData%BladeRootPosition,1), UBOUND(InData%BladeRootPosition,1) + ReKiBuf(Re_Xferred) = InData%BladeRootPosition(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%BladeShape) ) THEN + IF ( .NOT. ALLOCATED(InData%BladeRootOrientation) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeShape,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeShape,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeRootOrientation,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootOrientation,1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%BladeShape,1), UBOUND(InData%BladeShape,1) - CALL AD_Packbladeshape( Re_Buf, Db_Buf, Int_Buf, InData%BladeShape(i1), ErrStat2, ErrMsg2, OnlySize ) ! BladeShape - 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%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) + IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeRootOrientation,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootOrientation,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeRootOrientation,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootOrientation,3) 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 + DO i3 = LBOUND(InData%BladeRootOrientation,3), UBOUND(InData%BladeRootOrientation,3) + DO i2 = LBOUND(InData%BladeRootOrientation,2), UBOUND(InData%BladeRootOrientation,2) + DO i1 = LBOUND(InData%BladeRootOrientation,1), UBOUND(InData%BladeRootOrientation,1) + DbKiBuf(Db_Xferred) = InData%BladeRootOrientation(i1,i2,i3) + Db_Xferred = Db_Xferred + 1 + END DO + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%LinNames_x) ) THEN - IntKiBuf( Int_Xferred ) = 0 + DO i1 = LBOUND(InData%NacellePosition,1), UBOUND(InData%NacellePosition,1) + DbKiBuf(Db_Xferred) = InData%NacellePosition(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i2 = LBOUND(InData%NacelleOrientation,2), UBOUND(InData%NacelleOrientation,2) + DO i1 = LBOUND(InData%NacelleOrientation,1), UBOUND(InData%NacelleOrientation,1) + DbKiBuf(Db_Xferred) = InData%NacelleOrientation(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + IntKiBuf(Int_Xferred) = InData%AeroProjMod Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 + IntKiBuf(Int_Xferred) = InData%AeroBEM_Mod 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 + END SUBROUTINE AD_PackRotInitInputType - 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%BladeProps) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeProps,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeProps,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%BladeProps,1), UBOUND(InData%BladeProps,1) - CALL AD_Packbladepropstype( Re_Buf, Db_Buf, Int_Buf, InData%BladeProps(i1), ErrStat2, ErrMsg2, OnlySize ) ! BladeProps - 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%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 - IF ( .NOT. ALLOCATED(InData%TwrElev) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrElev,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrElev,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TwrElev,1), UBOUND(InData%TwrElev,1) - ReKiBuf(Re_Xferred) = InData%TwrElev(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%TwrDiam) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrDiam,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrDiam,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TwrDiam,1), UBOUND(InData%TwrDiam,1) - ReKiBuf(Re_Xferred) = InData%TwrDiam(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - END SUBROUTINE AD_PackRotInitOutputType - - SUBROUTINE AD_UnPackRotInitOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_UnPackRotInitInputType( 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(RotInitOutputType), INTENT(INOUT) :: OutData + TYPE(RotInitInputType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -2560,9 +1633,11 @@ SUBROUTINE AD_UnPackRotInitOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackRotInitOutputType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackRotInitInputType' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -2573,250 +1648,436 @@ SUBROUTINE AD_UnPackRotInitOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%AirDens = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputHdr not allocated - Int_Xferred = Int_Xferred + 1 - ELSE + OutData%NumBlades = IntKiBuf(Int_Xferred) 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 + i1_l = LBOUND(OutData%HubPosition,1) + i1_u = UBOUND(OutData%HubPosition,1) + DO i1 = LBOUND(OutData%HubPosition,1), UBOUND(OutData%HubPosition,1) + OutData%HubPosition(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%HubOrientation,1) + i1_u = UBOUND(OutData%HubOrientation,1) + i2_l = LBOUND(OutData%HubOrientation,2) + i2_u = UBOUND(OutData%HubOrientation,2) + DO i2 = LBOUND(OutData%HubOrientation,2), UBOUND(OutData%HubOrientation,2) + DO i1 = LBOUND(OutData%HubOrientation,1), UBOUND(OutData%HubOrientation,1) + OutData%HubOrientation(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutputUnt not allocated + END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeRootPosition not allocated Int_Xferred = Int_Xferred + 1 ELSE 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) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BladeRootPosition)) DEALLOCATE(OutData%BladeRootPosition) + ALLOCATE(OutData%BladeRootPosition(i1_l:i1_u,i2_l:i2_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%BladeRootPosition.', 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 i2 = LBOUND(OutData%BladeRootPosition,2), UBOUND(OutData%BladeRootPosition,2) + DO i1 = LBOUND(OutData%BladeRootPosition,1), UBOUND(OutData%BladeRootPosition,1) + OutData%BladeRootPosition(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeShape not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeRootOrientation not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BladeShape)) DEALLOCATE(OutData%BladeShape) - ALLOCATE(OutData%BladeShape(i1_l:i1_u),STAT=ErrStat2) + 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%BladeRootOrientation)) DEALLOCATE(OutData%BladeRootOrientation) + ALLOCATE(OutData%BladeRootOrientation(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%BladeShape.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeRootOrientation.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%BladeShape,1), UBOUND(OutData%BladeShape,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 + DO i3 = LBOUND(OutData%BladeRootOrientation,3), UBOUND(OutData%BladeRootOrientation,3) + DO i2 = LBOUND(OutData%BladeRootOrientation,2), UBOUND(OutData%BladeRootOrientation,2) + DO i1 = LBOUND(OutData%BladeRootOrientation,1), UBOUND(OutData%BladeRootOrientation,1) + OutData%BladeRootOrientation(i1,i2,i3) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END IF + i1_l = LBOUND(OutData%NacellePosition,1) + i1_u = UBOUND(OutData%NacellePosition,1) + DO i1 = LBOUND(OutData%NacellePosition,1), UBOUND(OutData%NacellePosition,1) + OutData%NacellePosition(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%NacelleOrientation,1) + i1_u = UBOUND(OutData%NacelleOrientation,1) + i2_l = LBOUND(OutData%NacelleOrientation,2) + i2_u = UBOUND(OutData%NacelleOrientation,2) + DO i2 = LBOUND(OutData%NacelleOrientation,2), UBOUND(OutData%NacelleOrientation,2) + DO i1 = LBOUND(OutData%NacelleOrientation,1), UBOUND(OutData%NacelleOrientation,1) + OutData%NacelleOrientation(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + OutData%AeroProjMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%AeroBEM_Mod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE AD_UnPackRotInitInputType + + SUBROUTINE AD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(AD_InitInputType), INTENT(IN) :: SrcInitInputData + TYPE(AD_InitInputType), INTENT(INOUT) :: DstInitInputData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyInitInput' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcInitInputData%rotors)) THEN + i1_l = LBOUND(SrcInitInputData%rotors,1) + i1_u = UBOUND(SrcInitInputData%rotors,1) + IF (.NOT. ALLOCATED(DstInitInputData%rotors)) THEN + ALLOCATE(DstInitInputData%rotors(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%rotors.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcInitInputData%rotors,1), UBOUND(SrcInitInputData%rotors,1) + CALL AD_Copyrotinitinputtype( SrcInitInputData%rotors(i1), DstInitInputData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + DstInitInputData%InputFile = SrcInitInputData%InputFile + DstInitInputData%RootName = SrcInitInputData%RootName + 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 + DstInitInputData%Linearize = SrcInitInputData%Linearize + DstInitInputData%Gravity = SrcInitInputData%Gravity + DstInitInputData%MHK = SrcInitInputData%MHK + DstInitInputData%defFldDens = SrcInitInputData%defFldDens + DstInitInputData%defKinVisc = SrcInitInputData%defKinVisc + DstInitInputData%defSpdSound = SrcInitInputData%defSpdSound + DstInitInputData%defPatm = SrcInitInputData%defPatm + DstInitInputData%defPvap = SrcInitInputData%defPvap + DstInitInputData%WtrDpth = SrcInitInputData%WtrDpth + DstInitInputData%MSL2SWL = SrcInitInputData%MSL2SWL + END SUBROUTINE AD_CopyInitInput + + SUBROUTINE AD_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(AD_InitInputType), INTENT(INOUT) :: InitInputData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyInitInput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(InitInputData%rotors)) THEN +DO i1 = LBOUND(InitInputData%rotors,1), UBOUND(InitInputData%rotors,1) + CALL AD_Destroyrotinitinputtype( InitInputData%rotors(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(InitInputData%rotors) +ENDIF + CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedPrimaryInputData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE AD_DestroyInitInput + + SUBROUTINE AD_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(AD_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackInitInput' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! rotors allocated yes/no + IF ( ALLOCATED(InData%rotors) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! rotors upper/lower bounds for each dimension + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) + Int_BufSz = Int_BufSz + 3 ! rotors: size of buffers for each call to pack subtype + CALL AD_Packrotinitinputtype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! rotors + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) 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 + IF(ALLOCATED(Db_Buf)) THEN ! rotors + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) END IF - CALL AD_Unpackbladeshape( Re_Buf, Db_Buf, Int_Buf, OutData%BladeShape(i1), ErrStat2, ErrMsg2 ) ! BladeShape + IF(ALLOCATED(Int_Buf)) THEN ! rotors + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1*LEN(InData%InputFile) ! InputFile + Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName + Int_BufSz = Int_BufSz + 1 ! UsePrimaryInputFile + 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 )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END DO + 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 + Int_BufSz = Int_BufSz + 1 ! Linearize + Re_BufSz = Re_BufSz + 1 ! Gravity + Int_BufSz = Int_BufSz + 1 ! MHK + Re_BufSz = Re_BufSz + 1 ! defFldDens + Re_BufSz = Re_BufSz + 1 ! defKinVisc + Re_BufSz = Re_BufSz + 1 ! defSpdSound + Re_BufSz = Re_BufSz + 1 ! defPatm + Re_BufSz = Re_BufSz + 1 ! defPvap + Re_BufSz = Re_BufSz + 1 ! WtrDpth + Re_BufSz = Re_BufSz + 1 ! MSL2SWL + 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 ( 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) + 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 - 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 END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LinNames_x not allocated + 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%rotors) ) THEN + IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE + IntKiBuf( Int_Xferred ) = 1 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) + IntKiBuf( Int_Xferred ) = LBOUND(InData%rotors,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%rotors,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 + + DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) + CALL AD_Packrotinitinputtype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors + 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 ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RotFrame_u not allocated - Int_Xferred = Int_Xferred + 1 - ELSE + DO I = 1, LEN(InData%InputFile) + IntKiBuf(Int_Xferred) = ICHAR(InData%InputFile(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 + IntKiBuf(Int_Xferred) = TRANSFER(InData%UsePrimaryInputFile, IntKiBuf(1)) 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 + 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 + IntKiBuf(Int_Xferred) = TRANSFER(InData%Linearize, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - ELSE + ReKiBuf(Re_Xferred) = InData%Gravity + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%MHK 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 ! BladeProps not allocated + ReKiBuf(Re_Xferred) = InData%defFldDens + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%defKinVisc + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%defSpdSound + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%defPatm + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%defPvap + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WtrDpth + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MSL2SWL + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE AD_PackInitInput + + SUBROUTINE AD_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(AD_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackInitInput' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! rotors not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BladeProps)) DEALLOCATE(OutData%BladeProps) - ALLOCATE(OutData%BladeProps(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%rotors)) DEALLOCATE(OutData%rotors) + ALLOCATE(OutData%rotors(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeProps.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%rotors.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%BladeProps,1), UBOUND(OutData%BladeProps,1) + DO i1 = LBOUND(OutData%rotors,1), UBOUND(OutData%rotors,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -2850,7 +2111,7 @@ SUBROUTINE AD_UnPackRotInitOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL AD_Unpackbladepropstype( Re_Buf, Db_Buf, Int_Buf, OutData%BladeProps(i1), ErrStat2, ErrMsg2 ) ! BladeProps + CALL AD_Unpackrotinitinputtype( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2859,65 +2120,81 @@ SUBROUTINE AD_UnPackRotInitOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! DerivOrder_x not allocated - Int_Xferred = Int_Xferred + 1 - ELSE + DO I = 1, LEN(OutData%InputFile) + OutData%InputFile(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%UsePrimaryInputFile = TRANSFER(IntKiBuf(Int_Xferred), OutData%UsePrimaryInputFile) 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 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrElev not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwrElev)) DEALLOCATE(OutData%TwrElev) - ALLOCATE(OutData%TwrElev(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrElev.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%TwrElev,1), UBOUND(OutData%TwrElev,1) - OutData%TwrElev(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrDiam not allocated + 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) + OutData%Linearize = TRANSFER(IntKiBuf(Int_Xferred), OutData%Linearize) Int_Xferred = Int_Xferred + 1 - ELSE + OutData%Gravity = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MHK = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwrDiam)) DEALLOCATE(OutData%TwrDiam) - ALLOCATE(OutData%TwrDiam(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrDiam.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%TwrDiam,1), UBOUND(OutData%TwrDiam,1) - OutData%TwrDiam(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - END SUBROUTINE AD_UnPackRotInitOutputType + OutData%defFldDens = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%defKinVisc = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%defSpdSound = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%defPatm = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%defPvap = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%WtrDpth = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MSL2SWL = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE AD_UnPackInitInput - SUBROUTINE AD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(AD_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(AD_InitOutputType), INTENT(INOUT) :: DstInitOutputData + SUBROUTINE AD_CopyBladePropsType( SrcBladePropsTypeData, DstBladePropsTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(AD_BladePropsType), INTENT(IN) :: SrcBladePropsTypeData + TYPE(AD_BladePropsType), INTENT(INOUT) :: DstBladePropsTypeData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -2926,54 +2203,191 @@ SUBROUTINE AD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, Er INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyInitOutput' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyBladePropsType' ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcInitOutputData%rotors)) THEN - i1_l = LBOUND(SrcInitOutputData%rotors,1) - i1_u = UBOUND(SrcInitOutputData%rotors,1) - IF (.NOT. ALLOCATED(DstInitOutputData%rotors)) THEN - ALLOCATE(DstInitOutputData%rotors(i1_l:i1_u),STAT=ErrStat2) + DstBladePropsTypeData%NumBlNds = SrcBladePropsTypeData%NumBlNds +IF (ALLOCATED(SrcBladePropsTypeData%BlSpn)) THEN + i1_l = LBOUND(SrcBladePropsTypeData%BlSpn,1) + i1_u = UBOUND(SrcBladePropsTypeData%BlSpn,1) + IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlSpn)) THEN + ALLOCATE(DstBladePropsTypeData%BlSpn(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%rotors.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlSpn.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcInitOutputData%rotors,1), UBOUND(SrcInitOutputData%rotors,1) - CALL AD_Copyrotinitoutputtype( SrcInitOutputData%rotors(i1), DstInitOutputData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO + DstBladePropsTypeData%BlSpn = SrcBladePropsTypeData%BlSpn 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 AD_CopyInitOutput +IF (ALLOCATED(SrcBladePropsTypeData%BlCrvAC)) THEN + i1_l = LBOUND(SrcBladePropsTypeData%BlCrvAC,1) + i1_u = UBOUND(SrcBladePropsTypeData%BlCrvAC,1) + IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlCrvAC)) THEN + ALLOCATE(DstBladePropsTypeData%BlCrvAC(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlCrvAC.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBladePropsTypeData%BlCrvAC = SrcBladePropsTypeData%BlCrvAC +ENDIF +IF (ALLOCATED(SrcBladePropsTypeData%BlSwpAC)) THEN + i1_l = LBOUND(SrcBladePropsTypeData%BlSwpAC,1) + i1_u = UBOUND(SrcBladePropsTypeData%BlSwpAC,1) + IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlSwpAC)) THEN + ALLOCATE(DstBladePropsTypeData%BlSwpAC(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlSwpAC.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBladePropsTypeData%BlSwpAC = SrcBladePropsTypeData%BlSwpAC +ENDIF +IF (ALLOCATED(SrcBladePropsTypeData%BlCrvAng)) THEN + i1_l = LBOUND(SrcBladePropsTypeData%BlCrvAng,1) + i1_u = UBOUND(SrcBladePropsTypeData%BlCrvAng,1) + IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlCrvAng)) THEN + ALLOCATE(DstBladePropsTypeData%BlCrvAng(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlCrvAng.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBladePropsTypeData%BlCrvAng = SrcBladePropsTypeData%BlCrvAng +ENDIF +IF (ALLOCATED(SrcBladePropsTypeData%BlTwist)) THEN + i1_l = LBOUND(SrcBladePropsTypeData%BlTwist,1) + i1_u = UBOUND(SrcBladePropsTypeData%BlTwist,1) + IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlTwist)) THEN + ALLOCATE(DstBladePropsTypeData%BlTwist(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlTwist.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBladePropsTypeData%BlTwist = SrcBladePropsTypeData%BlTwist +ENDIF +IF (ALLOCATED(SrcBladePropsTypeData%BlChord)) THEN + i1_l = LBOUND(SrcBladePropsTypeData%BlChord,1) + i1_u = UBOUND(SrcBladePropsTypeData%BlChord,1) + IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlChord)) THEN + ALLOCATE(DstBladePropsTypeData%BlChord(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlChord.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBladePropsTypeData%BlChord = SrcBladePropsTypeData%BlChord +ENDIF +IF (ALLOCATED(SrcBladePropsTypeData%BlAFID)) THEN + i1_l = LBOUND(SrcBladePropsTypeData%BlAFID,1) + i1_u = UBOUND(SrcBladePropsTypeData%BlAFID,1) + IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlAFID)) THEN + ALLOCATE(DstBladePropsTypeData%BlAFID(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlAFID.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBladePropsTypeData%BlAFID = SrcBladePropsTypeData%BlAFID +ENDIF +IF (ALLOCATED(SrcBladePropsTypeData%BlCb)) THEN + i1_l = LBOUND(SrcBladePropsTypeData%BlCb,1) + i1_u = UBOUND(SrcBladePropsTypeData%BlCb,1) + IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlCb)) THEN + ALLOCATE(DstBladePropsTypeData%BlCb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlCb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBladePropsTypeData%BlCb = SrcBladePropsTypeData%BlCb +ENDIF +IF (ALLOCATED(SrcBladePropsTypeData%BlCenBn)) THEN + i1_l = LBOUND(SrcBladePropsTypeData%BlCenBn,1) + i1_u = UBOUND(SrcBladePropsTypeData%BlCenBn,1) + IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlCenBn)) THEN + ALLOCATE(DstBladePropsTypeData%BlCenBn(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlCenBn.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBladePropsTypeData%BlCenBn = SrcBladePropsTypeData%BlCenBn +ENDIF +IF (ALLOCATED(SrcBladePropsTypeData%BlCenBt)) THEN + i1_l = LBOUND(SrcBladePropsTypeData%BlCenBt,1) + i1_u = UBOUND(SrcBladePropsTypeData%BlCenBt,1) + IF (.NOT. ALLOCATED(DstBladePropsTypeData%BlCenBt)) THEN + ALLOCATE(DstBladePropsTypeData%BlCenBt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladePropsTypeData%BlCenBt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBladePropsTypeData%BlCenBt = SrcBladePropsTypeData%BlCenBt +ENDIF + END SUBROUTINE AD_CopyBladePropsType - SUBROUTINE AD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) - TYPE(AD_InitOutputType), INTENT(INOUT) :: InitOutputData + SUBROUTINE AD_DestroyBladePropsType( BladePropsTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(AD_BladePropsType), INTENT(INOUT) :: BladePropsTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyBladePropsType' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(InitOutputData%rotors)) THEN -DO i1 = LBOUND(InitOutputData%rotors,1), UBOUND(InitOutputData%rotors,1) - CALL AD_Destroyrotinitoutputtype( InitOutputData%rotors(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(InitOutputData%rotors) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(BladePropsTypeData%BlSpn)) THEN + DEALLOCATE(BladePropsTypeData%BlSpn) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) - END SUBROUTINE AD_DestroyInitOutput +IF (ALLOCATED(BladePropsTypeData%BlCrvAC)) THEN + DEALLOCATE(BladePropsTypeData%BlCrvAC) +ENDIF +IF (ALLOCATED(BladePropsTypeData%BlSwpAC)) THEN + DEALLOCATE(BladePropsTypeData%BlSwpAC) +ENDIF +IF (ALLOCATED(BladePropsTypeData%BlCrvAng)) THEN + DEALLOCATE(BladePropsTypeData%BlCrvAng) +ENDIF +IF (ALLOCATED(BladePropsTypeData%BlTwist)) THEN + DEALLOCATE(BladePropsTypeData%BlTwist) +ENDIF +IF (ALLOCATED(BladePropsTypeData%BlChord)) THEN + DEALLOCATE(BladePropsTypeData%BlChord) +ENDIF +IF (ALLOCATED(BladePropsTypeData%BlAFID)) THEN + DEALLOCATE(BladePropsTypeData%BlAFID) +ENDIF +IF (ALLOCATED(BladePropsTypeData%BlCb)) THEN + DEALLOCATE(BladePropsTypeData%BlCb) +ENDIF +IF (ALLOCATED(BladePropsTypeData%BlCenBn)) THEN + DEALLOCATE(BladePropsTypeData%BlCenBn) +ENDIF +IF (ALLOCATED(BladePropsTypeData%BlCenBt)) THEN + DEALLOCATE(BladePropsTypeData%BlCenBt) +ENDIF + END SUBROUTINE AD_DestroyBladePropsType - SUBROUTINE AD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE AD_PackBladePropsType( 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(AD_InitOutputType), INTENT(IN) :: InData + TYPE(AD_BladePropsType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -2988,7 +2402,7 @@ SUBROUTINE AD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackInitOutput' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackBladePropsType' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -3004,47 +2418,57 @@ SUBROUTINE AD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! rotors allocated yes/no - IF ( ALLOCATED(InData%rotors) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! rotors upper/lower bounds for each dimension - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) - Int_BufSz = Int_BufSz + 3 ! rotors: size of buffers for each call to pack subtype - CALL AD_Packrotinitoutputtype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! rotors - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! rotors - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! rotors - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO + Int_BufSz = Int_BufSz + 1 ! NumBlNds + Int_BufSz = Int_BufSz + 1 ! BlSpn allocated yes/no + IF ( ALLOCATED(InData%BlSpn) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BlSpn upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlSpn) ! BlSpn + END IF + Int_BufSz = Int_BufSz + 1 ! BlCrvAC allocated yes/no + IF ( ALLOCATED(InData%BlCrvAC) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BlCrvAC upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlCrvAC) ! BlCrvAC + END IF + Int_BufSz = Int_BufSz + 1 ! BlSwpAC allocated yes/no + IF ( ALLOCATED(InData%BlSwpAC) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BlSwpAC upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlSwpAC) ! BlSwpAC + END IF + Int_BufSz = Int_BufSz + 1 ! BlCrvAng allocated yes/no + IF ( ALLOCATED(InData%BlCrvAng) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BlCrvAng upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlCrvAng) ! BlCrvAng + END IF + Int_BufSz = Int_BufSz + 1 ! BlTwist allocated yes/no + IF ( ALLOCATED(InData%BlTwist) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BlTwist upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlTwist) ! BlTwist + END IF + Int_BufSz = Int_BufSz + 1 ! BlChord allocated yes/no + IF ( ALLOCATED(InData%BlChord) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BlChord upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlChord) ! BlChord + END IF + Int_BufSz = Int_BufSz + 1 ! BlAFID allocated yes/no + IF ( ALLOCATED(InData%BlAFID) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BlAFID upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%BlAFID) ! BlAFID + END IF + Int_BufSz = Int_BufSz + 1 ! BlCb allocated yes/no + IF ( ALLOCATED(InData%BlCb) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BlCb upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlCb) ! BlCb + END IF + Int_BufSz = Int_BufSz + 1 ! BlCenBn allocated yes/no + IF ( ALLOCATED(InData%BlCenBn) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BlCenBn upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlCenBn) ! BlCenBn + END IF + Int_BufSz = Int_BufSz + 1 ! BlCenBt allocated yes/no + IF ( ALLOCATED(InData%BlCenBt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BlCenBt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlCenBt) ! BlCenBt END IF - 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 @@ -3072,848 +2496,437 @@ SUBROUTINE AD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = 1 Int_Xferred = 1 - IF ( .NOT. ALLOCATED(InData%rotors) ) THEN + IntKiBuf(Int_Xferred) = InData%NumBlNds + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%BlSpn) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%rotors,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%rotors,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlSpn,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlSpn,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) - CALL AD_Packrotinitoutputtype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END DO + DO i1 = LBOUND(InData%BlSpn,1), UBOUND(InData%BlSpn,1) + ReKiBuf(Re_Xferred) = InData%BlSpn(i1) + Re_Xferred = Re_Xferred + 1 + 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 - END SUBROUTINE AD_PackInitOutput + IF ( .NOT. ALLOCATED(InData%BlCrvAC) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlCrvAC,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlCrvAC,1) + Int_Xferred = Int_Xferred + 2 - SUBROUTINE AD_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(AD_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! rotors not allocated + DO i1 = LBOUND(InData%BlCrvAC,1), UBOUND(InData%BlCrvAC,1) + ReKiBuf(Re_Xferred) = InData%BlCrvAC(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BlSwpAC) ) THEN + IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE + IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlSwpAC,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlSwpAC,1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%rotors)) DEALLOCATE(OutData%rotors) - ALLOCATE(OutData%rotors(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%rotors.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%rotors,1), UBOUND(OutData%rotors,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AD_Unpackrotinitoutputtype( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors - 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 + DO i1 = LBOUND(InData%BlSwpAC,1), UBOUND(InData%BlSwpAC,1) + ReKiBuf(Re_Xferred) = InData%BlSwpAC(i1) + Re_Xferred = Re_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 ( .NOT. ALLOCATED(InData%BlCrvAng) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlCrvAng,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlCrvAng,1) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE AD_UnPackInitOutput + DO i1 = LBOUND(InData%BlCrvAng,1), UBOUND(InData%BlCrvAng,1) + ReKiBuf(Re_Xferred) = InData%BlCrvAng(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BlTwist) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlTwist,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlTwist,1) + Int_Xferred = Int_Xferred + 2 - SUBROUTINE AD_CopyRotInputFile( SrcRotInputFileData, DstRotInputFileData, CtrlCode, ErrStat, ErrMsg ) - TYPE(RotInputFile), INTENT(IN) :: SrcRotInputFileData - TYPE(RotInputFile), INTENT(INOUT) :: DstRotInputFileData - 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 = 'AD_CopyRotInputFile' -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(SrcRotInputFileData%BladeProps)) THEN - i1_l = LBOUND(SrcRotInputFileData%BladeProps,1) - i1_u = UBOUND(SrcRotInputFileData%BladeProps,1) - IF (.NOT. ALLOCATED(DstRotInputFileData%BladeProps)) THEN - ALLOCATE(DstRotInputFileData%BladeProps(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInputFileData%BladeProps.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + DO i1 = LBOUND(InData%BlTwist,1), UBOUND(InData%BlTwist,1) + ReKiBuf(Re_Xferred) = InData%BlTwist(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF - DO i1 = LBOUND(SrcRotInputFileData%BladeProps,1), UBOUND(SrcRotInputFileData%BladeProps,1) - CALL AD_Copybladepropstype( SrcRotInputFileData%BladeProps(i1), DstRotInputFileData%BladeProps(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF - DstRotInputFileData%NumTwrNds = SrcRotInputFileData%NumTwrNds -IF (ALLOCATED(SrcRotInputFileData%TwrElev)) THEN - i1_l = LBOUND(SrcRotInputFileData%TwrElev,1) - i1_u = UBOUND(SrcRotInputFileData%TwrElev,1) - IF (.NOT. ALLOCATED(DstRotInputFileData%TwrElev)) THEN - ALLOCATE(DstRotInputFileData%TwrElev(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInputFileData%TwrElev.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%BlChord) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlChord,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlChord,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BlChord,1), UBOUND(InData%BlChord,1) + ReKiBuf(Re_Xferred) = InData%BlChord(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF - DstRotInputFileData%TwrElev = SrcRotInputFileData%TwrElev -ENDIF -IF (ALLOCATED(SrcRotInputFileData%TwrDiam)) THEN - i1_l = LBOUND(SrcRotInputFileData%TwrDiam,1) - i1_u = UBOUND(SrcRotInputFileData%TwrDiam,1) - IF (.NOT. ALLOCATED(DstRotInputFileData%TwrDiam)) THEN - ALLOCATE(DstRotInputFileData%TwrDiam(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInputFileData%TwrDiam.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%BlAFID) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlAFID,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlAFID,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BlAFID,1), UBOUND(InData%BlAFID,1) + IntKiBuf(Int_Xferred) = InData%BlAFID(i1) + Int_Xferred = Int_Xferred + 1 + END DO END IF - DstRotInputFileData%TwrDiam = SrcRotInputFileData%TwrDiam -ENDIF -IF (ALLOCATED(SrcRotInputFileData%TwrCd)) THEN - i1_l = LBOUND(SrcRotInputFileData%TwrCd,1) - i1_u = UBOUND(SrcRotInputFileData%TwrCd,1) - IF (.NOT. ALLOCATED(DstRotInputFileData%TwrCd)) THEN - ALLOCATE(DstRotInputFileData%TwrCd(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInputFileData%TwrCd.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%BlCb) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlCb,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlCb,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BlCb,1), UBOUND(InData%BlCb,1) + ReKiBuf(Re_Xferred) = InData%BlCb(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF - DstRotInputFileData%TwrCd = SrcRotInputFileData%TwrCd -ENDIF -IF (ALLOCATED(SrcRotInputFileData%TwrTI)) THEN - i1_l = LBOUND(SrcRotInputFileData%TwrTI,1) - i1_u = UBOUND(SrcRotInputFileData%TwrTI,1) - IF (.NOT. ALLOCATED(DstRotInputFileData%TwrTI)) THEN - ALLOCATE(DstRotInputFileData%TwrTI(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInputFileData%TwrTI.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%BlCenBn) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlCenBn,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlCenBn,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BlCenBn,1), UBOUND(InData%BlCenBn,1) + ReKiBuf(Re_Xferred) = InData%BlCenBn(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF - DstRotInputFileData%TwrTI = SrcRotInputFileData%TwrTI -ENDIF - END SUBROUTINE AD_CopyRotInputFile + IF ( .NOT. ALLOCATED(InData%BlCenBt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlCenBt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlCenBt,1) + Int_Xferred = Int_Xferred + 2 - SUBROUTINE AD_DestroyRotInputFile( RotInputFileData, ErrStat, ErrMsg ) - TYPE(RotInputFile), INTENT(INOUT) :: RotInputFileData + DO i1 = LBOUND(InData%BlCenBt,1), UBOUND(InData%BlCenBt,1) + ReKiBuf(Re_Xferred) = InData%BlCenBt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + END SUBROUTINE AD_PackBladePropsType + + SUBROUTINE AD_UnPackBladePropsType( 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(AD_BladePropsType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotInputFile' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(RotInputFileData%BladeProps)) THEN -DO i1 = LBOUND(RotInputFileData%BladeProps,1), UBOUND(RotInputFileData%BladeProps,1) - CALL AD_Destroybladepropstype( RotInputFileData%BladeProps(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(RotInputFileData%BladeProps) -ENDIF -IF (ALLOCATED(RotInputFileData%TwrElev)) THEN - DEALLOCATE(RotInputFileData%TwrElev) -ENDIF -IF (ALLOCATED(RotInputFileData%TwrDiam)) THEN - DEALLOCATE(RotInputFileData%TwrDiam) -ENDIF -IF (ALLOCATED(RotInputFileData%TwrCd)) THEN - DEALLOCATE(RotInputFileData%TwrCd) -ENDIF -IF (ALLOCATED(RotInputFileData%TwrTI)) THEN - DEALLOCATE(RotInputFileData%TwrTI) -ENDIF - END SUBROUTINE AD_DestroyRotInputFile - - SUBROUTINE AD_PackRotInputFile( 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(RotInputFile), 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) :: Buf_size 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) :: 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 = 'AD_PackRotInputFile' - ! buffers to store subtypes, if any + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackBladePropsType' + ! buffers to store meshes, 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 ! BladeProps allocated yes/no - IF ( ALLOCATED(InData%BladeProps) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! BladeProps upper/lower bounds for each dimension - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - DO i1 = LBOUND(InData%BladeProps,1), UBOUND(InData%BladeProps,1) - Int_BufSz = Int_BufSz + 3 ! BladeProps: size of buffers for each call to pack subtype - CALL AD_Packbladepropstype( Re_Buf, Db_Buf, Int_Buf, InData%BladeProps(i1), ErrStat2, ErrMsg2, .TRUE. ) ! BladeProps - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! BladeProps - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! BladeProps - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! BladeProps - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - END IF - Int_BufSz = Int_BufSz + 1 ! NumTwrNds - Int_BufSz = Int_BufSz + 1 ! TwrElev allocated yes/no - IF ( ALLOCATED(InData%TwrElev) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! TwrElev upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TwrElev) ! TwrElev - END IF - Int_BufSz = Int_BufSz + 1 ! TwrDiam allocated yes/no - IF ( ALLOCATED(InData%TwrDiam) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! TwrDiam upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TwrDiam) ! TwrDiam - END IF - Int_BufSz = Int_BufSz + 1 ! TwrCd allocated yes/no - 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 - 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%BladeProps) ) THEN - IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = 1 + OutData%NumBlNds = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlSpn not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeProps,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeProps,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%BladeProps,1), UBOUND(InData%BladeProps,1) - CALL AD_Packbladepropstype( Re_Buf, Db_Buf, Int_Buf, InData%BladeProps(i1), ErrStat2, ErrMsg2, OnlySize ) ! BladeProps - 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 + IF (ALLOCATED(OutData%BlSpn)) DEALLOCATE(OutData%BlSpn) + ALLOCATE(OutData%BlSpn(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlSpn.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BlSpn,1), UBOUND(OutData%BlSpn,1) + OutData%BlSpn(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END IF - IntKiBuf(Int_Xferred) = InData%NumTwrNds + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlCrvAC not allocated Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%TwrElev) ) THEN - IntKiBuf( Int_Xferred ) = 0 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BlCrvAC)) DEALLOCATE(OutData%BlCrvAC) + ALLOCATE(OutData%BlCrvAC(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlCrvAC.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BlCrvAC,1), UBOUND(OutData%BlCrvAC,1) + OutData%BlCrvAC(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlSwpAC not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrElev,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrElev,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TwrElev,1), UBOUND(InData%TwrElev,1) - ReKiBuf(Re_Xferred) = InData%TwrElev(i1) + IF (ALLOCATED(OutData%BlSwpAC)) DEALLOCATE(OutData%BlSwpAC) + ALLOCATE(OutData%BlSwpAC(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlSwpAC.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BlSwpAC,1), UBOUND(OutData%BlSwpAC,1) + OutData%BlSwpAC(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%TwrDiam) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlCrvAng not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrDiam,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrDiam,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TwrDiam,1), UBOUND(InData%TwrDiam,1) - ReKiBuf(Re_Xferred) = InData%TwrDiam(i1) + IF (ALLOCATED(OutData%BlCrvAng)) DEALLOCATE(OutData%BlCrvAng) + ALLOCATE(OutData%BlCrvAng(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlCrvAng.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BlCrvAng,1), UBOUND(OutData%BlCrvAng,1) + OutData%BlCrvAng(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%TwrCd) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlTwist not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrCd,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrCd,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TwrCd,1), UBOUND(InData%TwrCd,1) - ReKiBuf(Re_Xferred) = InData%TwrCd(i1) + IF (ALLOCATED(OutData%BlTwist)) DEALLOCATE(OutData%BlTwist) + ALLOCATE(OutData%BlTwist(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlTwist.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BlTwist,1), UBOUND(OutData%BlTwist,1) + OutData%BlTwist(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%TwrTI) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlChord not allocated 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) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TwrTI,1), UBOUND(InData%TwrTI,1) - ReKiBuf(Re_Xferred) = InData%TwrTI(i1) + IF (ALLOCATED(OutData%BlChord)) DEALLOCATE(OutData%BlChord) + ALLOCATE(OutData%BlChord(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlChord.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BlChord,1), UBOUND(OutData%BlChord,1) + OutData%BlChord(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - END SUBROUTINE AD_PackRotInputFile - - SUBROUTINE AD_UnPackRotInputFile( 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(RotInputFile), 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 = 'AD_UnPackRotInputFile' - ! 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 ! BladeProps not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlAFID not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BladeProps)) DEALLOCATE(OutData%BladeProps) - ALLOCATE(OutData%BladeProps(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%BlAFID)) DEALLOCATE(OutData%BlAFID) + ALLOCATE(OutData%BlAFID(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeProps.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlAFID.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%BladeProps,1), UBOUND(OutData%BladeProps,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AD_Unpackbladepropstype( Re_Buf, Db_Buf, Int_Buf, OutData%BladeProps(i1), ErrStat2, ErrMsg2 ) ! BladeProps - 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%NumTwrNds = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrElev not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwrElev)) DEALLOCATE(OutData%TwrElev) - ALLOCATE(OutData%TwrElev(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrElev.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%TwrElev,1), UBOUND(OutData%TwrElev,1) - OutData%TwrElev(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(OutData%BlAFID,1), UBOUND(OutData%BlAFID,1) + OutData%BlAFID(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrDiam not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlCb not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwrDiam)) DEALLOCATE(OutData%TwrDiam) - ALLOCATE(OutData%TwrDiam(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%BlCb)) DEALLOCATE(OutData%BlCb) + ALLOCATE(OutData%BlCb(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrDiam.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlCb.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%TwrDiam,1), UBOUND(OutData%TwrDiam,1) - OutData%TwrDiam(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%BlCb,1), UBOUND(OutData%BlCb,1) + OutData%BlCb(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrCd not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlCenBn not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwrCd)) DEALLOCATE(OutData%TwrCd) - ALLOCATE(OutData%TwrCd(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%BlCenBn)) DEALLOCATE(OutData%BlCenBn) + ALLOCATE(OutData%BlCenBn(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrCd.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlCenBn.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%TwrCd,1), UBOUND(OutData%TwrCd,1) - OutData%TwrCd(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%BlCenBn,1), UBOUND(OutData%BlCenBn,1) + OutData%BlCenBn(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrTI not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlCenBt not allocated Int_Xferred = Int_Xferred + 1 ELSE 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 (ALLOCATED(OutData%BlCenBt)) DEALLOCATE(OutData%BlCenBt) + ALLOCATE(OutData%BlCenBt(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrTI.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlCenBt.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%TwrTI,1), UBOUND(OutData%TwrTI,1) - OutData%TwrTI(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%BlCenBt,1), UBOUND(OutData%BlCenBt,1) + OutData%BlCenBt(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - END SUBROUTINE AD_UnPackRotInputFile + END SUBROUTINE AD_UnPackBladePropsType - SUBROUTINE AD_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrStat, ErrMsg ) - TYPE(AD_InputFile), INTENT(IN) :: SrcInputFileData - TYPE(AD_InputFile), INTENT(INOUT) :: DstInputFileData + SUBROUTINE AD_CopyBladeShape( SrcBladeShapeData, DstBladeShapeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(AD_BladeShape), INTENT(IN) :: SrcBladeShapeData + TYPE(AD_BladeShape), INTENT(INOUT) :: DstBladeShapeData 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 = 'AD_CopyInputFile' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyBladeShape' ! ErrStat = ErrID_None ErrMsg = "" - DstInputFileData%Echo = SrcInputFileData%Echo - DstInputFileData%DTAero = SrcInputFileData%DTAero - DstInputFileData%WakeMod = SrcInputFileData%WakeMod - DstInputFileData%AFAeroMod = SrcInputFileData%AFAeroMod - DstInputFileData%TwrPotent = SrcInputFileData%TwrPotent - DstInputFileData%TwrShadow = SrcInputFileData%TwrShadow - DstInputFileData%TwrAero = SrcInputFileData%TwrAero - DstInputFileData%FrozenWake = SrcInputFileData%FrozenWake - 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 - DstInputFileData%Pvap = SrcInputFileData%Pvap - DstInputFileData%SpdSound = SrcInputFileData%SpdSound - DstInputFileData%SkewMod = SrcInputFileData%SkewMod - DstInputFileData%SkewModFactor = SrcInputFileData%SkewModFactor - DstInputFileData%TipLoss = SrcInputFileData%TipLoss - DstInputFileData%HubLoss = SrcInputFileData%HubLoss - DstInputFileData%TanInd = SrcInputFileData%TanInd - DstInputFileData%AIDrag = SrcInputFileData%AIDrag - DstInputFileData%TIDrag = SrcInputFileData%TIDrag - DstInputFileData%IndToler = SrcInputFileData%IndToler - DstInputFileData%MaxIter = SrcInputFileData%MaxIter - DstInputFileData%UAMod = SrcInputFileData%UAMod - DstInputFileData%FLookup = SrcInputFileData%FLookup - DstInputFileData%InCol_Alfa = SrcInputFileData%InCol_Alfa - DstInputFileData%InCol_Cl = SrcInputFileData%InCol_Cl - DstInputFileData%InCol_Cd = SrcInputFileData%InCol_Cd - DstInputFileData%InCol_Cm = SrcInputFileData%InCol_Cm - DstInputFileData%InCol_Cpmin = SrcInputFileData%InCol_Cpmin - DstInputFileData%AFTabMod = SrcInputFileData%AFTabMod - DstInputFileData%NumAFfiles = SrcInputFileData%NumAFfiles - DstInputFileData%FVWFileName = SrcInputFileData%FVWFileName -IF (ALLOCATED(SrcInputFileData%AFNames)) THEN - i1_l = LBOUND(SrcInputFileData%AFNames,1) - i1_u = UBOUND(SrcInputFileData%AFNames,1) - IF (.NOT. ALLOCATED(DstInputFileData%AFNames)) THEN - ALLOCATE(DstInputFileData%AFNames(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%AFNames.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputFileData%AFNames = SrcInputFileData%AFNames -ENDIF - DstInputFileData%UseBlCm = SrcInputFileData%UseBlCm - DstInputFileData%SumPrint = SrcInputFileData%SumPrint - DstInputFileData%NBlOuts = SrcInputFileData%NBlOuts - DstInputFileData%BlOutNd = SrcInputFileData%BlOutNd - DstInputFileData%NTwOuts = SrcInputFileData%NTwOuts - DstInputFileData%TwOutNd = SrcInputFileData%TwOutNd - DstInputFileData%NumOuts = SrcInputFileData%NumOuts -IF (ALLOCATED(SrcInputFileData%OutList)) THEN - i1_l = LBOUND(SrcInputFileData%OutList,1) - i1_u = UBOUND(SrcInputFileData%OutList,1) - IF (.NOT. ALLOCATED(DstInputFileData%OutList)) THEN - ALLOCATE(DstInputFileData%OutList(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%OutList.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputFileData%OutList = SrcInputFileData%OutList -ENDIF - DstInputFileData%tau1_const = SrcInputFileData%tau1_const - DstInputFileData%DBEMT_Mod = SrcInputFileData%DBEMT_Mod - DstInputFileData%BldNd_NumOuts = SrcInputFileData%BldNd_NumOuts -IF (ALLOCATED(SrcInputFileData%BldNd_OutList)) THEN - i1_l = LBOUND(SrcInputFileData%BldNd_OutList,1) - i1_u = UBOUND(SrcInputFileData%BldNd_OutList,1) - IF (.NOT. ALLOCATED(DstInputFileData%BldNd_OutList)) THEN - ALLOCATE(DstInputFileData%BldNd_OutList(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%BldNd_OutList.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputFileData%BldNd_OutList = SrcInputFileData%BldNd_OutList -ENDIF - DstInputFileData%BldNd_BlOutNd_Str = SrcInputFileData%BldNd_BlOutNd_Str - DstInputFileData%BldNd_BladesOut = SrcInputFileData%BldNd_BladesOut - DstInputFileData%UAStartRad = SrcInputFileData%UAStartRad - DstInputFileData%UAEndRad = SrcInputFileData%UAEndRad -IF (ALLOCATED(SrcInputFileData%rotors)) THEN - i1_l = LBOUND(SrcInputFileData%rotors,1) - i1_u = UBOUND(SrcInputFileData%rotors,1) - IF (.NOT. ALLOCATED(DstInputFileData%rotors)) THEN - ALLOCATE(DstInputFileData%rotors(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcBladeShapeData%AirfoilCoords)) THEN + i1_l = LBOUND(SrcBladeShapeData%AirfoilCoords,1) + i1_u = UBOUND(SrcBladeShapeData%AirfoilCoords,1) + i2_l = LBOUND(SrcBladeShapeData%AirfoilCoords,2) + i2_u = UBOUND(SrcBladeShapeData%AirfoilCoords,2) + i3_l = LBOUND(SrcBladeShapeData%AirfoilCoords,3) + i3_u = UBOUND(SrcBladeShapeData%AirfoilCoords,3) + IF (.NOT. ALLOCATED(DstBladeShapeData%AirfoilCoords)) THEN + ALLOCATE(DstBladeShapeData%AirfoilCoords(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%rotors.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeShapeData%AirfoilCoords.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcInputFileData%rotors,1), UBOUND(SrcInputFileData%rotors,1) - CALL AD_Copyrotinputfile( SrcInputFileData%rotors(i1), DstInputFileData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO + DstBladeShapeData%AirfoilCoords = SrcBladeShapeData%AirfoilCoords ENDIF - END SUBROUTINE AD_CopyInputFile + END SUBROUTINE AD_CopyBladeShape - SUBROUTINE AD_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) - TYPE(AD_InputFile), INTENT(INOUT) :: InputFileData + SUBROUTINE AD_DestroyBladeShape( BladeShapeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(AD_BladeShape), INTENT(INOUT) :: BladeShapeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyInputFile' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyBladeShape' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(InputFileData%ADBlFile)) THEN - DEALLOCATE(InputFileData%ADBlFile) -ENDIF -IF (ALLOCATED(InputFileData%AFNames)) THEN - DEALLOCATE(InputFileData%AFNames) -ENDIF -IF (ALLOCATED(InputFileData%OutList)) THEN - DEALLOCATE(InputFileData%OutList) -ENDIF -IF (ALLOCATED(InputFileData%BldNd_OutList)) THEN - DEALLOCATE(InputFileData%BldNd_OutList) -ENDIF -IF (ALLOCATED(InputFileData%rotors)) THEN -DO i1 = LBOUND(InputFileData%rotors,1), UBOUND(InputFileData%rotors,1) - CALL AD_Destroyrotinputfile( InputFileData%rotors(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(InputFileData%rotors) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(BladeShapeData%AirfoilCoords)) THEN + DEALLOCATE(BladeShapeData%AirfoilCoords) ENDIF - END SUBROUTINE AD_DestroyInputFile + END SUBROUTINE AD_DestroyBladeShape - SUBROUTINE AD_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE AD_PackBladeShape( 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(AD_InputFile), INTENT(IN) :: InData + TYPE(AD_BladeShape), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -3928,7 +2941,7 @@ SUBROUTINE AD_PackInputFile( 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 = 'AD_PackInputFile' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackBladeShape' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -3944,98 +2957,10 @@ 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 - Int_BufSz = Int_BufSz + 1 ! TwrPotent - Int_BufSz = Int_BufSz + 1 ! TwrShadow - Int_BufSz = Int_BufSz + 1 ! TwrAero - Int_BufSz = Int_BufSz + 1 ! FrozenWake - 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 - Re_BufSz = Re_BufSz + 1 ! Pvap - Re_BufSz = Re_BufSz + 1 ! SpdSound - Int_BufSz = Int_BufSz + 1 ! SkewMod - Re_BufSz = Re_BufSz + 1 ! SkewModFactor - Int_BufSz = Int_BufSz + 1 ! TipLoss - Int_BufSz = Int_BufSz + 1 ! HubLoss - Int_BufSz = Int_BufSz + 1 ! TanInd - Int_BufSz = Int_BufSz + 1 ! AIDrag - Int_BufSz = Int_BufSz + 1 ! TIDrag - Re_BufSz = Re_BufSz + 1 ! IndToler - Re_BufSz = Re_BufSz + 1 ! MaxIter - Int_BufSz = Int_BufSz + 1 ! UAMod - Int_BufSz = Int_BufSz + 1 ! FLookup - Re_BufSz = Re_BufSz + 1 ! InCol_Alfa - Re_BufSz = Re_BufSz + 1 ! InCol_Cl - Re_BufSz = Re_BufSz + 1 ! InCol_Cd - Re_BufSz = Re_BufSz + 1 ! InCol_Cm - Re_BufSz = Re_BufSz + 1 ! InCol_Cpmin - Int_BufSz = Int_BufSz + 1 ! AFTabMod - Int_BufSz = Int_BufSz + 1 ! NumAFfiles - Int_BufSz = Int_BufSz + 1*LEN(InData%FVWFileName) ! FVWFileName - Int_BufSz = Int_BufSz + 1 ! AFNames allocated yes/no - IF ( ALLOCATED(InData%AFNames) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! AFNames upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%AFNames)*LEN(InData%AFNames) ! AFNames - END IF - Int_BufSz = Int_BufSz + 1 ! UseBlCm - Int_BufSz = Int_BufSz + 1 ! SumPrint - Int_BufSz = Int_BufSz + 1 ! NBlOuts - Int_BufSz = Int_BufSz + SIZE(InData%BlOutNd) ! BlOutNd - Int_BufSz = Int_BufSz + 1 ! NTwOuts - Int_BufSz = Int_BufSz + SIZE(InData%TwOutNd) ! TwOutNd - 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 - Re_BufSz = Re_BufSz + 1 ! tau1_const - Int_BufSz = Int_BufSz + 1 ! DBEMT_Mod - Int_BufSz = Int_BufSz + 1 ! BldNd_NumOuts - Int_BufSz = Int_BufSz + 1 ! BldNd_OutList allocated yes/no - IF ( ALLOCATED(InData%BldNd_OutList) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! BldNd_OutList upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%BldNd_OutList)*LEN(InData%BldNd_OutList) ! BldNd_OutList - END IF - Int_BufSz = Int_BufSz + 1*LEN(InData%BldNd_BlOutNd_Str) ! BldNd_BlOutNd_Str - Int_BufSz = Int_BufSz + 1 ! BldNd_BladesOut - Re_BufSz = Re_BufSz + 1 ! UAStartRad - Re_BufSz = Re_BufSz + 1 ! UAEndRad - Int_BufSz = Int_BufSz + 1 ! rotors allocated yes/no - IF ( ALLOCATED(InData%rotors) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! rotors upper/lower bounds for each dimension - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) - Int_BufSz = Int_BufSz + 3 ! rotors: size of buffers for each call to pack subtype - CALL AD_Packrotinputfile( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! rotors - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! rotors - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! rotors - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO + Int_BufSz = Int_BufSz + 1 ! AirfoilCoords allocated yes/no + IF ( ALLOCATED(InData%AirfoilCoords) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! AirfoilCoords upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AirfoilCoords) ! AirfoilCoords END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -4064,542 +2989,364 @@ 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 - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%AFAeroMod - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%TwrPotent - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%TwrShadow - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%TwrAero, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%FrozenWake, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%CavitCheck, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%CompAA, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(InData%AA_InputFile) - IntKiBuf(Int_Xferred) = ICHAR(InData%AA_InputFile(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IF ( .NOT. ALLOCATED(InData%ADBlFile) ) THEN + IF ( .NOT. ALLOCATED(InData%AirfoilCoords) ) THEN 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) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AirfoilCoords,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AirfoilCoords,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AirfoilCoords,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AirfoilCoords,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AirfoilCoords,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AirfoilCoords,3) 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 + DO i3 = LBOUND(InData%AirfoilCoords,3), UBOUND(InData%AirfoilCoords,3) + DO i2 = LBOUND(InData%AirfoilCoords,2), UBOUND(InData%AirfoilCoords,2) + DO i1 = LBOUND(InData%AirfoilCoords,1), UBOUND(InData%AirfoilCoords,1) + ReKiBuf(Re_Xferred) = InData%AirfoilCoords(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO END IF - ReKiBuf(Re_Xferred) = InData%AirDens - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%KinVisc - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Patm - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Pvap - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%SpdSound - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%SkewMod - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%SkewModFactor - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%TipLoss, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%HubLoss, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%TanInd, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%AIDrag, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%TIDrag, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%IndToler - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%MaxIter - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%UAMod - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%FLookup, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InCol_Alfa - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InCol_Cl - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InCol_Cd - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InCol_Cm - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InCol_Cpmin - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%AFTabMod - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NumAFfiles - Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(InData%FVWFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%FVWFileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IF ( .NOT. ALLOCATED(InData%AFNames) ) THEN - IntKiBuf( Int_Xferred ) = 0 + END SUBROUTINE AD_PackBladeShape + + SUBROUTINE AD_UnPackBladeShape( 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(AD_BladeShape), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackBladeShape' + ! 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 ! AirfoilCoords not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AFNames,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AFNames,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%AFNames,1), UBOUND(InData%AFNames,1) - DO I = 1, LEN(InData%AFNames) - IntKiBuf(Int_Xferred) = ICHAR(InData%AFNames(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I + 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%AirfoilCoords)) DEALLOCATE(OutData%AirfoilCoords) + ALLOCATE(OutData%AirfoilCoords(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%AirfoilCoords.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%AirfoilCoords,3), UBOUND(OutData%AirfoilCoords,3) + DO i2 = LBOUND(OutData%AirfoilCoords,2), UBOUND(OutData%AirfoilCoords,2) + DO i1 = LBOUND(OutData%AirfoilCoords,1), UBOUND(OutData%AirfoilCoords,1) + OutData%AirfoilCoords(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO END IF - IntKiBuf(Int_Xferred) = TRANSFER(InData%UseBlCm, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%SumPrint, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NBlOuts - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%BlOutNd,1), UBOUND(InData%BlOutNd,1) - IntKiBuf(Int_Xferred) = InData%BlOutNd(i1) - Int_Xferred = Int_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = InData%NTwOuts - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%TwOutNd,1), UBOUND(InData%TwOutNd,1) - IntKiBuf(Int_Xferred) = InData%TwOutNd(i1) - Int_Xferred = Int_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = InData%NumOuts - Int_Xferred = Int_Xferred + 1 - 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 + END SUBROUTINE AD_UnPackBladeShape - 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 + SUBROUTINE AD_CopyRotInitOutputType( SrcRotInitOutputTypeData, DstRotInitOutputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(RotInitOutputType), INTENT(IN) :: SrcRotInitOutputTypeData + TYPE(RotInitOutputType), INTENT(INOUT) :: DstRotInitOutputTypeData + 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 = 'AD_CopyRotInitOutputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstRotInitOutputTypeData%AirDens = SrcRotInitOutputTypeData%AirDens +IF (ALLOCATED(SrcRotInitOutputTypeData%WriteOutputHdr)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%WriteOutputHdr,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%WriteOutputHdr,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%WriteOutputHdr)) THEN + ALLOCATE(DstRotInitOutputTypeData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF END IF - ReKiBuf(Re_Xferred) = InData%tau1_const - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%DBEMT_Mod - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%BldNd_NumOuts - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%BldNd_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%BldNd_OutList,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldNd_OutList,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%BldNd_OutList,1), UBOUND(InData%BldNd_OutList,1) - DO I = 1, LEN(InData%BldNd_OutList) - IntKiBuf(Int_Xferred) = ICHAR(InData%BldNd_OutList(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO + DstRotInitOutputTypeData%WriteOutputHdr = SrcRotInitOutputTypeData%WriteOutputHdr +ENDIF +IF (ALLOCATED(SrcRotInitOutputTypeData%WriteOutputUnt)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%WriteOutputUnt,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%WriteOutputUnt,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%WriteOutputUnt)) THEN + ALLOCATE(DstRotInitOutputTypeData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF END IF - DO I = 1, LEN(InData%BldNd_BlOutNd_Str) - IntKiBuf(Int_Xferred) = ICHAR(InData%BldNd_BlOutNd_Str(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = InData%BldNd_BladesOut - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%UAStartRad - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%UAEndRad - Re_Xferred = Re_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%rotors) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%rotors,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%rotors,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) - CALL AD_Packrotinputfile( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors - 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 + DstRotInitOutputTypeData%WriteOutputUnt = SrcRotInitOutputTypeData%WriteOutputUnt +ENDIF +IF (ALLOCATED(SrcRotInitOutputTypeData%BladeShape)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%BladeShape,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%BladeShape,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%BladeShape)) THEN + ALLOCATE(DstRotInitOutputTypeData%BladeShape(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%BladeShape.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF END IF - END SUBROUTINE AD_PackInputFile - - SUBROUTINE AD_UnPackInputFile( 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(AD_InputFile), 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 = 'AD_UnPackInputFile' - ! 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%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) - Int_Xferred = Int_Xferred + 1 - OutData%AFAeroMod = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%TwrPotent = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%TwrShadow = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%TwrAero = TRANSFER(IntKiBuf(Int_Xferred), OutData%TwrAero) - Int_Xferred = Int_Xferred + 1 - OutData%FrozenWake = TRANSFER(IntKiBuf(Int_Xferred), OutData%FrozenWake) - Int_Xferred = Int_Xferred + 1 - OutData%CavitCheck = TRANSFER(IntKiBuf(Int_Xferred), OutData%CavitCheck) - Int_Xferred = Int_Xferred + 1 - OutData%CompAA = TRANSFER(IntKiBuf(Int_Xferred), OutData%CompAA) - Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(OutData%AA_InputFile) - 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) + DO i1 = LBOUND(SrcRotInitOutputTypeData%BladeShape,1), UBOUND(SrcRotInitOutputTypeData%BladeShape,1) + CALL AD_Copybladeshape( SrcRotInitOutputTypeData%BladeShape(i1), DstRotInitOutputTypeData%BladeShape(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcRotInitOutputTypeData%LinNames_y)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%LinNames_y,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%LinNames_y,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%LinNames_y)) THEN + ALLOCATE(DstRotInitOutputTypeData%LinNames_y(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ADBlFile.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%LinNames_y.', 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) - Re_Xferred = Re_Xferred + 1 - OutData%Patm = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Pvap = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%SpdSound = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%SkewMod = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%SkewModFactor = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TipLoss = TRANSFER(IntKiBuf(Int_Xferred), OutData%TipLoss) - Int_Xferred = Int_Xferred + 1 - OutData%HubLoss = TRANSFER(IntKiBuf(Int_Xferred), OutData%HubLoss) - Int_Xferred = Int_Xferred + 1 - OutData%TanInd = TRANSFER(IntKiBuf(Int_Xferred), OutData%TanInd) - Int_Xferred = Int_Xferred + 1 - OutData%AIDrag = TRANSFER(IntKiBuf(Int_Xferred), OutData%AIDrag) - Int_Xferred = Int_Xferred + 1 - OutData%TIDrag = TRANSFER(IntKiBuf(Int_Xferred), OutData%TIDrag) - Int_Xferred = Int_Xferred + 1 - OutData%IndToler = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%MaxIter = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%UAMod = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%FLookup = TRANSFER(IntKiBuf(Int_Xferred), OutData%FLookup) - Int_Xferred = Int_Xferred + 1 - OutData%InCol_Alfa = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InCol_Cl = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InCol_Cd = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InCol_Cm = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InCol_Cpmin = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%AFTabMod = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NumAFfiles = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(OutData%FVWFileName) - OutData%FVWFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AFNames not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%AFNames)) DEALLOCATE(OutData%AFNames) - ALLOCATE(OutData%AFNames(i1_l:i1_u),STAT=ErrStat2) + DstRotInitOutputTypeData%LinNames_y = SrcRotInitOutputTypeData%LinNames_y +ENDIF +IF (ALLOCATED(SrcRotInitOutputTypeData%LinNames_x)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%LinNames_x,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%LinNames_x,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%LinNames_x)) THEN + ALLOCATE(DstRotInitOutputTypeData%LinNames_x(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AFNames.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%LinNames_x.', ErrStat, ErrMsg,RoutineName) + RETURN END IF - DO i1 = LBOUND(OutData%AFNames,1), UBOUND(OutData%AFNames,1) - DO I = 1, LEN(OutData%AFNames) - OutData%AFNames(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO END IF - OutData%UseBlCm = TRANSFER(IntKiBuf(Int_Xferred), OutData%UseBlCm) - Int_Xferred = Int_Xferred + 1 - OutData%SumPrint = TRANSFER(IntKiBuf(Int_Xferred), OutData%SumPrint) - Int_Xferred = Int_Xferred + 1 - OutData%NBlOuts = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%BlOutNd,1) - i1_u = UBOUND(OutData%BlOutNd,1) - DO i1 = LBOUND(OutData%BlOutNd,1), UBOUND(OutData%BlOutNd,1) - OutData%BlOutNd(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - OutData%NTwOuts = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%TwOutNd,1) - i1_u = UBOUND(OutData%TwOutNd,1) - DO i1 = LBOUND(OutData%TwOutNd,1), UBOUND(OutData%TwOutNd,1) - OutData%TwOutNd(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - OutData%NumOuts = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - 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) + DstRotInitOutputTypeData%LinNames_x = SrcRotInitOutputTypeData%LinNames_x +ENDIF +IF (ALLOCATED(SrcRotInitOutputTypeData%LinNames_u)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%LinNames_u,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%LinNames_u,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%LinNames_u)) THEN + ALLOCATE(DstRotInitOutputTypeData%LinNames_u(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutList.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%LinNames_u.', 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%tau1_const = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%DBEMT_Mod = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%BldNd_NumOuts = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldNd_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%BldNd_OutList)) DEALLOCATE(OutData%BldNd_OutList) - ALLOCATE(OutData%BldNd_OutList(i1_l:i1_u),STAT=ErrStat2) + DstRotInitOutputTypeData%LinNames_u = SrcRotInitOutputTypeData%LinNames_u +ENDIF +IF (ALLOCATED(SrcRotInitOutputTypeData%RotFrame_y)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%RotFrame_y,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%RotFrame_y,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%RotFrame_y)) THEN + ALLOCATE(DstRotInitOutputTypeData%RotFrame_y(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BldNd_OutList.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%RotFrame_y.', ErrStat, ErrMsg,RoutineName) + RETURN END IF - DO i1 = LBOUND(OutData%BldNd_OutList,1), UBOUND(OutData%BldNd_OutList,1) - DO I = 1, LEN(OutData%BldNd_OutList) - OutData%BldNd_OutList(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO END IF - DO I = 1, LEN(OutData%BldNd_BlOutNd_Str) - OutData%BldNd_BlOutNd_Str(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%BldNd_BladesOut = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%UAStartRad = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%UAEndRad = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! rotors not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%rotors)) DEALLOCATE(OutData%rotors) - ALLOCATE(OutData%rotors(i1_l:i1_u),STAT=ErrStat2) + DstRotInitOutputTypeData%RotFrame_y = SrcRotInitOutputTypeData%RotFrame_y +ENDIF +IF (ALLOCATED(SrcRotInitOutputTypeData%RotFrame_x)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%RotFrame_x,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%RotFrame_x,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%RotFrame_x)) THEN + ALLOCATE(DstRotInitOutputTypeData%RotFrame_x(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%rotors.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%RotFrame_x.', ErrStat, ErrMsg,RoutineName) + RETURN END IF - DO i1 = LBOUND(OutData%rotors,1), UBOUND(OutData%rotors,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AD_Unpackrotinputfile( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END DO END IF - END SUBROUTINE AD_UnPackInputFile - - SUBROUTINE AD_CopyRotContinuousStateType( SrcRotContinuousStateTypeData, DstRotContinuousStateTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(RotContinuousStateType), INTENT(IN) :: SrcRotContinuousStateTypeData - TYPE(RotContinuousStateType), INTENT(INOUT) :: DstRotContinuousStateTypeData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyRotContinuousStateType' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL BEMT_CopyContState( SrcRotContinuousStateTypeData%BEMT, DstRotContinuousStateTypeData%BEMT, CtrlCode, ErrStat2, ErrMsg2 ) + DstRotInitOutputTypeData%RotFrame_x = SrcRotInitOutputTypeData%RotFrame_x +ENDIF +IF (ALLOCATED(SrcRotInitOutputTypeData%RotFrame_u)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%RotFrame_u,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%RotFrame_u,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%RotFrame_u)) THEN + ALLOCATE(DstRotInitOutputTypeData%RotFrame_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%RotFrame_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotInitOutputTypeData%RotFrame_u = SrcRotInitOutputTypeData%RotFrame_u +ENDIF +IF (ALLOCATED(SrcRotInitOutputTypeData%IsLoad_u)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%IsLoad_u,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%IsLoad_u,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%IsLoad_u)) THEN + ALLOCATE(DstRotInitOutputTypeData%IsLoad_u(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%IsLoad_u.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotInitOutputTypeData%IsLoad_u = SrcRotInitOutputTypeData%IsLoad_u +ENDIF +IF (ALLOCATED(SrcRotInitOutputTypeData%BladeProps)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%BladeProps,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%BladeProps,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%BladeProps)) THEN + ALLOCATE(DstRotInitOutputTypeData%BladeProps(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%BladeProps.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcRotInitOutputTypeData%BladeProps,1), UBOUND(SrcRotInitOutputTypeData%BladeProps,1) + CALL AD_Copybladepropstype( SrcRotInitOutputTypeData%BladeProps(i1), DstRotInitOutputTypeData%BladeProps(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AA_CopyContState( SrcRotContinuousStateTypeData%AA, DstRotContinuousStateTypeData%AA, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE AD_CopyRotContinuousStateType + ENDDO +ENDIF +IF (ALLOCATED(SrcRotInitOutputTypeData%DerivOrder_x)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%DerivOrder_x,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%DerivOrder_x,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%DerivOrder_x)) THEN + ALLOCATE(DstRotInitOutputTypeData%DerivOrder_x(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%DerivOrder_x.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotInitOutputTypeData%DerivOrder_x = SrcRotInitOutputTypeData%DerivOrder_x +ENDIF +IF (ALLOCATED(SrcRotInitOutputTypeData%TwrElev)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%TwrElev,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%TwrElev,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%TwrElev)) THEN + ALLOCATE(DstRotInitOutputTypeData%TwrElev(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%TwrElev.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotInitOutputTypeData%TwrElev = SrcRotInitOutputTypeData%TwrElev +ENDIF +IF (ALLOCATED(SrcRotInitOutputTypeData%TwrDiam)) THEN + i1_l = LBOUND(SrcRotInitOutputTypeData%TwrDiam,1) + i1_u = UBOUND(SrcRotInitOutputTypeData%TwrDiam,1) + IF (.NOT. ALLOCATED(DstRotInitOutputTypeData%TwrDiam)) THEN + ALLOCATE(DstRotInitOutputTypeData%TwrDiam(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInitOutputTypeData%TwrDiam.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotInitOutputTypeData%TwrDiam = SrcRotInitOutputTypeData%TwrDiam +ENDIF + END SUBROUTINE AD_CopyRotInitOutputType - SUBROUTINE AD_DestroyRotContinuousStateType( RotContinuousStateTypeData, ErrStat, ErrMsg ) - TYPE(RotContinuousStateType), INTENT(INOUT) :: RotContinuousStateTypeData + SUBROUTINE AD_DestroyRotInitOutputType( RotInitOutputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(RotInitOutputType), INTENT(INOUT) :: RotInitOutputTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotContinuousStateType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotInitOutputType' + ErrStat = ErrID_None ErrMsg = "" - CALL BEMT_DestroyContState( RotContinuousStateTypeData%BEMT, ErrStat, ErrMsg ) - CALL AA_DestroyContState( RotContinuousStateTypeData%AA, ErrStat, ErrMsg ) - END SUBROUTINE AD_DestroyRotContinuousStateType - SUBROUTINE AD_PackRotContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(RotInitOutputTypeData%WriteOutputHdr)) THEN + DEALLOCATE(RotInitOutputTypeData%WriteOutputHdr) +ENDIF +IF (ALLOCATED(RotInitOutputTypeData%WriteOutputUnt)) THEN + DEALLOCATE(RotInitOutputTypeData%WriteOutputUnt) +ENDIF +IF (ALLOCATED(RotInitOutputTypeData%BladeShape)) THEN +DO i1 = LBOUND(RotInitOutputTypeData%BladeShape,1), UBOUND(RotInitOutputTypeData%BladeShape,1) + CALL AD_Destroybladeshape( RotInitOutputTypeData%BladeShape(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(RotInitOutputTypeData%BladeShape) +ENDIF +IF (ALLOCATED(RotInitOutputTypeData%LinNames_y)) THEN + DEALLOCATE(RotInitOutputTypeData%LinNames_y) +ENDIF +IF (ALLOCATED(RotInitOutputTypeData%LinNames_x)) THEN + DEALLOCATE(RotInitOutputTypeData%LinNames_x) +ENDIF +IF (ALLOCATED(RotInitOutputTypeData%LinNames_u)) THEN + DEALLOCATE(RotInitOutputTypeData%LinNames_u) +ENDIF +IF (ALLOCATED(RotInitOutputTypeData%RotFrame_y)) THEN + DEALLOCATE(RotInitOutputTypeData%RotFrame_y) +ENDIF +IF (ALLOCATED(RotInitOutputTypeData%RotFrame_x)) THEN + DEALLOCATE(RotInitOutputTypeData%RotFrame_x) +ENDIF +IF (ALLOCATED(RotInitOutputTypeData%RotFrame_u)) THEN + DEALLOCATE(RotInitOutputTypeData%RotFrame_u) +ENDIF +IF (ALLOCATED(RotInitOutputTypeData%IsLoad_u)) THEN + DEALLOCATE(RotInitOutputTypeData%IsLoad_u) +ENDIF +IF (ALLOCATED(RotInitOutputTypeData%BladeProps)) THEN +DO i1 = LBOUND(RotInitOutputTypeData%BladeProps,1), UBOUND(RotInitOutputTypeData%BladeProps,1) + CALL AD_Destroybladepropstype( RotInitOutputTypeData%BladeProps(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(RotInitOutputTypeData%BladeProps) +ENDIF +IF (ALLOCATED(RotInitOutputTypeData%DerivOrder_x)) THEN + DEALLOCATE(RotInitOutputTypeData%DerivOrder_x) +ENDIF +IF (ALLOCATED(RotInitOutputTypeData%TwrElev)) THEN + DEALLOCATE(RotInitOutputTypeData%TwrElev) +ENDIF +IF (ALLOCATED(RotInitOutputTypeData%TwrDiam)) THEN + DEALLOCATE(RotInitOutputTypeData%TwrDiam) +ENDIF + END SUBROUTINE AD_DestroyRotInitOutputType + + SUBROUTINE AD_PackRotInitOutputType( 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(RotContinuousStateType), INTENT(IN) :: InData + TYPE(RotInitOutputType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -4614,7 +3361,7 @@ SUBROUTINE AD_PackRotContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackRotContinuousStateType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackRotInitOutputType' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -4630,41 +3377,114 @@ SUBROUTINE AD_PackRotContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! AirDens + 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 + Int_BufSz = Int_BufSz + 1 ! BladeShape allocated yes/no + IF ( ALLOCATED(InData%BladeShape) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BladeShape upper/lower bounds for each dimension ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! BEMT: size of buffers for each call to pack subtype - CALL BEMT_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, .TRUE. ) ! BEMT + DO i1 = LBOUND(InData%BladeShape,1), UBOUND(InData%BladeShape,1) + Int_BufSz = Int_BufSz + 3 ! BladeShape: size of buffers for each call to pack subtype + CALL AD_Packbladeshape( Re_Buf, Db_Buf, Int_Buf, InData%BladeShape(i1), ErrStat2, ErrMsg2, .TRUE. ) ! BladeShape CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! BEMT + IF(ALLOCATED(Re_Buf)) THEN ! BladeShape Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! BEMT + IF(ALLOCATED(Db_Buf)) THEN ! BladeShape Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! BEMT + IF(ALLOCATED(Int_Buf)) THEN ! BladeShape Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! AA: size of buffers for each call to pack subtype - CALL AA_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, .TRUE. ) ! AA + END DO + 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 ! BladeProps allocated yes/no + IF ( ALLOCATED(InData%BladeProps) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BladeProps upper/lower bounds for each dimension + DO i1 = LBOUND(InData%BladeProps,1), UBOUND(InData%BladeProps,1) + Int_BufSz = Int_BufSz + 3 ! BladeProps: size of buffers for each call to pack subtype + CALL AD_Packbladepropstype( Re_Buf, Db_Buf, Int_Buf, InData%BladeProps(i1), ErrStat2, ErrMsg2, .TRUE. ) ! BladeProps CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! AA + IF(ALLOCATED(Re_Buf)) THEN ! BladeProps Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! AA + IF(ALLOCATED(Db_Buf)) THEN ! BladeProps Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! AA + IF(ALLOCATED(Int_Buf)) THEN ! BladeProps Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + 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 + Int_BufSz = Int_BufSz + 1 ! TwrElev allocated yes/no + IF ( ALLOCATED(InData%TwrElev) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrElev upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrElev) ! TwrElev + END IF + Int_BufSz = Int_BufSz + 1 ! TwrDiam allocated yes/no + IF ( ALLOCATED(InData%TwrDiam) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrDiam upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrDiam) ! TwrDiam + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -4692,7 +3512,54 @@ SUBROUTINE AD_PackRotContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er Db_Xferred = 1 Int_Xferred = 1 - CALL BEMT_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, OnlySize ) ! BEMT + ReKiBuf(Re_Xferred) = InData%AirDens + Re_Xferred = Re_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 + IF ( .NOT. ALLOCATED(InData%BladeShape) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeShape,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeShape,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BladeShape,1), UBOUND(InData%BladeShape,1) + CALL AD_Packbladeshape( Re_Buf, Db_Buf, Int_Buf, InData%BladeShape(i1), ErrStat2, ErrMsg2, OnlySize ) ! BladeShape CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4720,12 +3587,136 @@ SUBROUTINE AD_PackRotContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL AA_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, OnlySize ) ! AA - 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 + END DO + END IF + 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%BladeProps) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeProps,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeProps,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BladeProps,1), UBOUND(InData%BladeProps,1) + CALL AD_Packbladepropstype( Re_Buf, Db_Buf, Int_Buf, InData%BladeProps(i1), ErrStat2, ErrMsg2, OnlySize ) ! BladeProps + 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) @@ -4748,13 +3739,60 @@ SUBROUTINE AD_PackRotContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END SUBROUTINE AD_PackRotContinuousStateType + 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 - SUBROUTINE AD_UnPackRotContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + 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 + IF ( .NOT. ALLOCATED(InData%TwrElev) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrElev,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrElev,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrElev,1), UBOUND(InData%TwrElev,1) + ReKiBuf(Re_Xferred) = InData%TwrElev(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%TwrDiam) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrDiam,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrDiam,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrDiam,1), UBOUND(InData%TwrDiam,1) + ReKiBuf(Re_Xferred) = InData%TwrDiam(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + END SUBROUTINE AD_PackRotInitOutputType + + SUBROUTINE AD_UnPackRotInitOutputType( 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(RotContinuousStateType), INTENT(INOUT) :: OutData + TYPE(RotInitOutputType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -4763,9 +3801,10 @@ SUBROUTINE AD_UnPackRotContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, 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 = 'AD_UnPackRotContinuousStateType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackRotInitOutputType' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -4776,6 +3815,62 @@ SUBROUTINE AD_UnPackRotContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 + OutData%AirDens = ReKiBuf(Re_Xferred) + Re_Xferred = Re_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 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeShape not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BladeShape)) DEALLOCATE(OutData%BladeShape) + ALLOCATE(OutData%BladeShape(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeShape.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BladeShape,1), UBOUND(OutData%BladeShape,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -4809,25 +3904,173 @@ SUBROUTINE AD_UnPackRotContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL BEMT_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT, ErrStat2, ErrMsg2 ) ! BEMT + CALL AD_Unpackbladeshape( Re_Buf, Db_Buf, Int_Buf, OutData%BladeShape(i1), ErrStat2, ErrMsg2 ) ! BladeShape 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 ) + END DO + END IF + 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 ! BladeProps not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BladeProps)) DEALLOCATE(OutData%BladeProps) + ALLOCATE(OutData%BladeProps(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeProps.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BladeProps,1), UBOUND(OutData%BladeProps,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) @@ -4849,18 +4092,74 @@ SUBROUTINE AD_UnPackRotContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL AA_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%AA, ErrStat2, ErrMsg2 ) ! AA + CALL AD_Unpackbladepropstype( Re_Buf, Db_Buf, Int_Buf, OutData%BladeProps(i1), ErrStat2, ErrMsg2 ) ! BladeProps 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_UnPackRotContinuousStateType + 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 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrElev not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%TwrElev)) DEALLOCATE(OutData%TwrElev) + ALLOCATE(OutData%TwrElev(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrElev.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrElev,1), UBOUND(OutData%TwrElev,1) + OutData%TwrElev(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrDiam not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%TwrDiam)) DEALLOCATE(OutData%TwrDiam) + ALLOCATE(OutData%TwrDiam(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrDiam.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrDiam,1), UBOUND(OutData%TwrDiam,1) + OutData%TwrDiam(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + END SUBROUTINE AD_UnPackRotInitOutputType - SUBROUTINE AD_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(AD_ContinuousStateType), INTENT(IN) :: SrcContStateData - TYPE(AD_ContinuousStateType), INTENT(INOUT) :: DstContStateData + SUBROUTINE AD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(AD_InitOutputType), INTENT(IN) :: SrcInitOutputData + TYPE(AD_InitOutputType), INTENT(INOUT) :: DstInitOutputData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -4869,54 +4168,68 @@ SUBROUTINE AD_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrSt INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyContState' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyInitOutput' ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcContStateData%rotors)) THEN - i1_l = LBOUND(SrcContStateData%rotors,1) - i1_u = UBOUND(SrcContStateData%rotors,1) - IF (.NOT. ALLOCATED(DstContStateData%rotors)) THEN - ALLOCATE(DstContStateData%rotors(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcInitOutputData%rotors)) THEN + i1_l = LBOUND(SrcInitOutputData%rotors,1) + i1_u = UBOUND(SrcInitOutputData%rotors,1) + IF (.NOT. ALLOCATED(DstInitOutputData%rotors)) THEN + ALLOCATE(DstInitOutputData%rotors(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstContStateData%rotors.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%rotors.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcContStateData%rotors,1), UBOUND(SrcContStateData%rotors,1) - CALL AD_Copyrotcontinuousstatetype( SrcContStateData%rotors(i1), DstContStateData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcInitOutputData%rotors,1), UBOUND(SrcInitOutputData%rotors,1) + CALL AD_Copyrotinitoutputtype( SrcInitOutputData%rotors(i1), DstInitOutputData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF - CALL FVW_CopyContState( SrcContStateData%FVW, DstContStateData%FVW, CtrlCode, ErrStat2, ErrMsg2 ) + CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE AD_CopyContState + END SUBROUTINE AD_CopyInitOutput - SUBROUTINE AD_DestroyContState( ContStateData, ErrStat, ErrMsg ) - TYPE(AD_ContinuousStateType), INTENT(INOUT) :: ContStateData + SUBROUTINE AD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(AD_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(ContStateData%rotors)) THEN -DO i1 = LBOUND(ContStateData%rotors,1), UBOUND(ContStateData%rotors,1) - CALL AD_Destroyrotcontinuousstatetype( ContStateData%rotors(i1), ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(InitOutputData%rotors)) THEN +DO i1 = LBOUND(InitOutputData%rotors,1), UBOUND(InitOutputData%rotors,1) + CALL AD_Destroyrotinitoutputtype( InitOutputData%rotors(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(ContStateData%rotors) + DEALLOCATE(InitOutputData%rotors) ENDIF - CALL FVW_DestroyContState( ContStateData%FVW, ErrStat, ErrMsg ) - END SUBROUTINE AD_DestroyContState + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE AD_DestroyInitOutput - SUBROUTINE AD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE AD_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(AD_ContinuousStateType), INTENT(IN) :: InData + TYPE(AD_InitOutputType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -4931,7 +4244,7 @@ SUBROUTINE AD_PackContState( 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 = 'AD_PackContState' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackInitOutput' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -4953,7 +4266,7 @@ SUBROUTINE AD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ! Allocate buffers for subtypes, if any (we'll get sizes from these) DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) Int_BufSz = Int_BufSz + 3 ! rotors: size of buffers for each call to pack subtype - CALL AD_Packrotcontinuousstatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors + CALL AD_Packrotinitoutputtype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4971,20 +4284,20 @@ SUBROUTINE AD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg END IF END DO END IF - Int_BufSz = Int_BufSz + 3 ! FVW: size of buffers for each call to pack subtype - CALL FVW_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, .TRUE. ) ! FVW + 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 ! FVW + IF(ALLOCATED(Re_Buf)) THEN ! Ver Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! FVW + IF(ALLOCATED(Db_Buf)) THEN ! Ver Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! FVW + IF(ALLOCATED(Int_Buf)) THEN ! Ver Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -5026,7 +4339,7 @@ SUBROUTINE AD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 2 DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) - CALL AD_Packrotcontinuousstatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors + CALL AD_Packrotinitoutputtype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5056,7 +4369,7 @@ SUBROUTINE AD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ENDIF END DO END IF - CALL FVW_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, OnlySize ) ! FVW + 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 @@ -5084,13 +4397,13 @@ SUBROUTINE AD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END SUBROUTINE AD_PackContState + END SUBROUTINE AD_PackInitOutput - SUBROUTINE AD_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_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(AD_ContinuousStateType), INTENT(INOUT) :: OutData + TYPE(AD_InitOutputType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -5102,7 +4415,7 @@ SUBROUTINE AD_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackContState' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackInitOutput' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -5160,7 +4473,7 @@ SUBROUTINE AD_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL AD_Unpackrotcontinuousstatetype( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors + CALL AD_Unpackrotinitoutputtype( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5202,55 +4515,170 @@ SUBROUTINE AD_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL FVW_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%FVW, ErrStat2, ErrMsg2 ) ! FVW + 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 AD_UnPackContState + END SUBROUTINE AD_UnPackInitOutput - SUBROUTINE AD_CopyRotDiscreteStateType( SrcRotDiscreteStateTypeData, DstRotDiscreteStateTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(RotDiscreteStateType), INTENT(IN) :: SrcRotDiscreteStateTypeData - TYPE(RotDiscreteStateType), INTENT(INOUT) :: DstRotDiscreteStateTypeData + SUBROUTINE AD_CopyRotInputFile( SrcRotInputFileData, DstRotInputFileData, CtrlCode, ErrStat, ErrMsg ) + TYPE(RotInputFile), INTENT(IN) :: SrcRotInputFileData + TYPE(RotInputFile), INTENT(INOUT) :: DstRotInputFileData 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 = 'AD_CopyRotDiscreteStateType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyRotInputFile' ! ErrStat = ErrID_None ErrMsg = "" - CALL BEMT_CopyDiscState( SrcRotDiscreteStateTypeData%BEMT, DstRotDiscreteStateTypeData%BEMT, CtrlCode, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(SrcRotInputFileData%BladeProps)) THEN + i1_l = LBOUND(SrcRotInputFileData%BladeProps,1) + i1_u = UBOUND(SrcRotInputFileData%BladeProps,1) + IF (.NOT. ALLOCATED(DstRotInputFileData%BladeProps)) THEN + ALLOCATE(DstRotInputFileData%BladeProps(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInputFileData%BladeProps.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcRotInputFileData%BladeProps,1), UBOUND(SrcRotInputFileData%BladeProps,1) + CALL AD_Copybladepropstype( SrcRotInputFileData%BladeProps(i1), DstRotInputFileData%BladeProps(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AA_CopyDiscState( SrcRotDiscreteStateTypeData%AA, DstRotDiscreteStateTypeData%AA, CtrlCode, ErrStat2, ErrMsg2 ) + ENDDO +ENDIF + DstRotInputFileData%NumTwrNds = SrcRotInputFileData%NumTwrNds +IF (ALLOCATED(SrcRotInputFileData%TwrElev)) THEN + i1_l = LBOUND(SrcRotInputFileData%TwrElev,1) + i1_u = UBOUND(SrcRotInputFileData%TwrElev,1) + IF (.NOT. ALLOCATED(DstRotInputFileData%TwrElev)) THEN + ALLOCATE(DstRotInputFileData%TwrElev(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInputFileData%TwrElev.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotInputFileData%TwrElev = SrcRotInputFileData%TwrElev +ENDIF +IF (ALLOCATED(SrcRotInputFileData%TwrDiam)) THEN + i1_l = LBOUND(SrcRotInputFileData%TwrDiam,1) + i1_u = UBOUND(SrcRotInputFileData%TwrDiam,1) + IF (.NOT. ALLOCATED(DstRotInputFileData%TwrDiam)) THEN + ALLOCATE(DstRotInputFileData%TwrDiam(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInputFileData%TwrDiam.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotInputFileData%TwrDiam = SrcRotInputFileData%TwrDiam +ENDIF +IF (ALLOCATED(SrcRotInputFileData%TwrCd)) THEN + i1_l = LBOUND(SrcRotInputFileData%TwrCd,1) + i1_u = UBOUND(SrcRotInputFileData%TwrCd,1) + IF (.NOT. ALLOCATED(DstRotInputFileData%TwrCd)) THEN + ALLOCATE(DstRotInputFileData%TwrCd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInputFileData%TwrCd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotInputFileData%TwrCd = SrcRotInputFileData%TwrCd +ENDIF +IF (ALLOCATED(SrcRotInputFileData%TwrTI)) THEN + i1_l = LBOUND(SrcRotInputFileData%TwrTI,1) + i1_u = UBOUND(SrcRotInputFileData%TwrTI,1) + IF (.NOT. ALLOCATED(DstRotInputFileData%TwrTI)) THEN + ALLOCATE(DstRotInputFileData%TwrTI(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInputFileData%TwrTI.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotInputFileData%TwrTI = SrcRotInputFileData%TwrTI +ENDIF +IF (ALLOCATED(SrcRotInputFileData%TwrCb)) THEN + i1_l = LBOUND(SrcRotInputFileData%TwrCb,1) + i1_u = UBOUND(SrcRotInputFileData%TwrCb,1) + IF (.NOT. ALLOCATED(DstRotInputFileData%TwrCb)) THEN + ALLOCATE(DstRotInputFileData%TwrCb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotInputFileData%TwrCb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotInputFileData%TwrCb = SrcRotInputFileData%TwrCb +ENDIF + DstRotInputFileData%VolHub = SrcRotInputFileData%VolHub + DstRotInputFileData%HubCenBx = SrcRotInputFileData%HubCenBx + DstRotInputFileData%VolNac = SrcRotInputFileData%VolNac + DstRotInputFileData%NacCenB = SrcRotInputFileData%NacCenB + DstRotInputFileData%TFinAero = SrcRotInputFileData%TFinAero + DstRotInputFileData%TFinFile = SrcRotInputFileData%TFinFile + CALL AD_Copytfininputfiletype( SrcRotInputFileData%TFin, DstRotInputFileData%TFin, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE AD_CopyRotDiscreteStateType + END SUBROUTINE AD_CopyRotInputFile - SUBROUTINE AD_DestroyRotDiscreteStateType( RotDiscreteStateTypeData, ErrStat, ErrMsg ) - TYPE(RotDiscreteStateType), INTENT(INOUT) :: RotDiscreteStateTypeData + SUBROUTINE AD_DestroyRotInputFile( RotInputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(RotInputFile), INTENT(INOUT) :: RotInputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotDiscreteStateType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotInputFile' + ErrStat = ErrID_None ErrMsg = "" - CALL BEMT_DestroyDiscState( RotDiscreteStateTypeData%BEMT, ErrStat, ErrMsg ) - CALL AA_DestroyDiscState( RotDiscreteStateTypeData%AA, ErrStat, ErrMsg ) - END SUBROUTINE AD_DestroyRotDiscreteStateType - SUBROUTINE AD_PackRotDiscreteStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(RotInputFileData%BladeProps)) THEN +DO i1 = LBOUND(RotInputFileData%BladeProps,1), UBOUND(RotInputFileData%BladeProps,1) + CALL AD_Destroybladepropstype( RotInputFileData%BladeProps(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(RotInputFileData%BladeProps) +ENDIF +IF (ALLOCATED(RotInputFileData%TwrElev)) THEN + DEALLOCATE(RotInputFileData%TwrElev) +ENDIF +IF (ALLOCATED(RotInputFileData%TwrDiam)) THEN + DEALLOCATE(RotInputFileData%TwrDiam) +ENDIF +IF (ALLOCATED(RotInputFileData%TwrCd)) THEN + DEALLOCATE(RotInputFileData%TwrCd) +ENDIF +IF (ALLOCATED(RotInputFileData%TwrTI)) THEN + DEALLOCATE(RotInputFileData%TwrTI) +ENDIF +IF (ALLOCATED(RotInputFileData%TwrCb)) THEN + DEALLOCATE(RotInputFileData%TwrCb) +ENDIF + CALL AD_Destroytfininputfiletype( RotInputFileData%TFin, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE AD_DestroyRotInputFile + + SUBROUTINE AD_PackRotInputFile( 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(RotDiscreteStateType), INTENT(IN) :: InData + TYPE(RotInputFile), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -5265,7 +4693,7 @@ SUBROUTINE AD_PackRotDiscreteStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrS LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackRotDiscreteStateType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackRotInputFile' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -5281,38 +4709,76 @@ SUBROUTINE AD_PackRotDiscreteStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrS Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! BladeProps allocated yes/no + IF ( ALLOCATED(InData%BladeProps) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BladeProps upper/lower bounds for each dimension ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! BEMT: size of buffers for each call to pack subtype - CALL BEMT_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, .TRUE. ) ! BEMT + DO i1 = LBOUND(InData%BladeProps,1), UBOUND(InData%BladeProps,1) + Int_BufSz = Int_BufSz + 3 ! BladeProps: size of buffers for each call to pack subtype + CALL AD_Packbladepropstype( Re_Buf, Db_Buf, Int_Buf, InData%BladeProps(i1), ErrStat2, ErrMsg2, .TRUE. ) ! BladeProps CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! BEMT + IF(ALLOCATED(Re_Buf)) THEN ! BladeProps Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! BEMT + IF(ALLOCATED(Db_Buf)) THEN ! BladeProps Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! BEMT + IF(ALLOCATED(Int_Buf)) THEN ! BladeProps Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! AA: size of buffers for each call to pack subtype - CALL AA_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, .TRUE. ) ! AA + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! NumTwrNds + Int_BufSz = Int_BufSz + 1 ! TwrElev allocated yes/no + IF ( ALLOCATED(InData%TwrElev) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrElev upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrElev) ! TwrElev + END IF + Int_BufSz = Int_BufSz + 1 ! TwrDiam allocated yes/no + IF ( ALLOCATED(InData%TwrDiam) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrDiam upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrDiam) ! TwrDiam + END IF + Int_BufSz = Int_BufSz + 1 ! TwrCd allocated yes/no + 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 ! TwrCb allocated yes/no + IF ( ALLOCATED(InData%TwrCb) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrCb upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrCb) ! TwrCb + END IF + Re_BufSz = Re_BufSz + 1 ! VolHub + Re_BufSz = Re_BufSz + 1 ! HubCenBx + Re_BufSz = Re_BufSz + 1 ! VolNac + Re_BufSz = Re_BufSz + SIZE(InData%NacCenB) ! NacCenB + Int_BufSz = Int_BufSz + 1 ! TFinAero + Int_BufSz = Int_BufSz + 1*LEN(InData%TFinFile) ! TFinFile + Int_BufSz = Int_BufSz + 3 ! TFin: size of buffers for each call to pack subtype + CALL AD_Packtfininputfiletype( Re_Buf, Db_Buf, Int_Buf, InData%TFin, ErrStat2, ErrMsg2, .TRUE. ) ! TFin CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! AA + IF(ALLOCATED(Re_Buf)) THEN ! TFin Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! AA + IF(ALLOCATED(Db_Buf)) THEN ! TFin Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! AA + IF(ALLOCATED(Int_Buf)) THEN ! TFin Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF @@ -5343,35 +4809,18 @@ SUBROUTINE AD_PackRotDiscreteStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrS Db_Xferred = 1 Int_Xferred = 1 - CALL BEMT_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, OnlySize ) ! BEMT - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + IF ( .NOT. ALLOCATED(InData%BladeProps) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeProps,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeProps,1) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL AA_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, OnlySize ) ! AA + DO i1 = LBOUND(InData%BladeProps,1), UBOUND(InData%BladeProps,1) + CALL AD_Packbladepropstype( Re_Buf, Db_Buf, Int_Buf, InData%BladeProps(i1), ErrStat2, ErrMsg2, OnlySize ) ! BladeProps CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5399,24 +4848,148 @@ SUBROUTINE AD_PackRotDiscreteStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrS ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END SUBROUTINE AD_PackRotDiscreteStateType - - SUBROUTINE AD_UnPackRotDiscreteStateType( 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(RotDiscreteStateType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables + END DO + END IF + IntKiBuf(Int_Xferred) = InData%NumTwrNds + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%TwrElev) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrElev,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrElev,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrElev,1), UBOUND(InData%TwrElev,1) + ReKiBuf(Re_Xferred) = InData%TwrElev(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%TwrDiam) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrDiam,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrDiam,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrDiam,1), UBOUND(InData%TwrDiam,1) + ReKiBuf(Re_Xferred) = InData%TwrDiam(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%TwrCd) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrCd,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrCd,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrCd,1), UBOUND(InData%TwrCd,1) + 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 + IF ( .NOT. ALLOCATED(InData%TwrCb) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrCb,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrCb,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrCb,1), UBOUND(InData%TwrCb,1) + ReKiBuf(Re_Xferred) = InData%TwrCb(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + ReKiBuf(Re_Xferred) = InData%VolHub + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%HubCenBx + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VolNac + Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%NacCenB,1), UBOUND(InData%NacCenB,1) + ReKiBuf(Re_Xferred) = InData%NacCenB(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = TRANSFER(InData%TFinAero, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(InData%TFinFile) + IntKiBuf(Int_Xferred) = ICHAR(InData%TFinFile(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + CALL AD_Packtfininputfiletype( Re_Buf, Db_Buf, Int_Buf, InData%TFin, ErrStat2, ErrMsg2, OnlySize ) ! TFin + 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_PackRotInputFile + + SUBROUTINE AD_UnPackRotInputFile( 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(RotInputFile), 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 = 'AD_UnPackRotDiscreteStateType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackRotInputFile' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -5427,6 +5000,20 @@ SUBROUTINE AD_UnPackRotDiscreteStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, E Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeProps not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BladeProps)) DEALLOCATE(OutData%BladeProps) + ALLOCATE(OutData%BladeProps(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeProps.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BladeProps,1), UBOUND(OutData%BladeProps,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -5460,13 +5047,125 @@ SUBROUTINE AD_UnPackRotDiscreteStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, E Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL BEMT_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT, ErrStat2, ErrMsg2 ) ! BEMT + CALL AD_Unpackbladepropstype( Re_Buf, Db_Buf, Int_Buf, OutData%BladeProps(i1), ErrStat2, ErrMsg2 ) ! BladeProps 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%NumTwrNds = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrElev not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%TwrElev)) DEALLOCATE(OutData%TwrElev) + ALLOCATE(OutData%TwrElev(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrElev.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrElev,1), UBOUND(OutData%TwrElev,1) + OutData%TwrElev(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrDiam not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%TwrDiam)) DEALLOCATE(OutData%TwrDiam) + ALLOCATE(OutData%TwrDiam(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrDiam.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrDiam,1), UBOUND(OutData%TwrDiam,1) + OutData%TwrDiam(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrCd not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%TwrCd)) DEALLOCATE(OutData%TwrCd) + ALLOCATE(OutData%TwrCd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrCd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrCd,1), UBOUND(OutData%TwrCd,1) + 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 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrCb not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%TwrCb)) DEALLOCATE(OutData%TwrCb) + ALLOCATE(OutData%TwrCb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrCb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrCb,1), UBOUND(OutData%TwrCb,1) + OutData%TwrCb(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + OutData%VolHub = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%HubCenBx = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VolNac = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%NacCenB,1) + i1_u = UBOUND(OutData%NacCenB,1) + DO i1 = LBOUND(OutData%NacCenB,1), UBOUND(OutData%NacCenB,1) + OutData%NacCenB(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%TFinAero = TRANSFER(IntKiBuf(Int_Xferred), OutData%TFinAero) + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(OutData%TFinFile) + OutData%TFinFile(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -5500,18 +5199,18 @@ SUBROUTINE AD_UnPackRotDiscreteStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, E Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL AA_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%AA, ErrStat2, ErrMsg2 ) ! AA + CALL AD_Unpacktfininputfiletype( Re_Buf, Db_Buf, Int_Buf, OutData%TFin, ErrStat2, ErrMsg2 ) ! TFin 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_UnPackRotDiscreteStateType + END SUBROUTINE AD_UnPackRotInputFile - SUBROUTINE AD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(AD_DiscreteStateType), INTENT(IN) :: SrcDiscStateData - TYPE(AD_DiscreteStateType), INTENT(INOUT) :: DstDiscStateData + SUBROUTINE AD_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrStat, ErrMsg ) + TYPE(AD_InputFile), INTENT(IN) :: SrcInputFileData + TYPE(AD_InputFile), INTENT(INOUT) :: DstInputFileData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -5520,54 +5219,173 @@ SUBROUTINE AD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyDiscState' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyInputFile' ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcDiscStateData%rotors)) THEN - i1_l = LBOUND(SrcDiscStateData%rotors,1) - i1_u = UBOUND(SrcDiscStateData%rotors,1) - IF (.NOT. ALLOCATED(DstDiscStateData%rotors)) THEN - ALLOCATE(DstDiscStateData%rotors(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%rotors.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcDiscStateData%rotors,1), UBOUND(SrcDiscStateData%rotors,1) - CALL AD_Copyrotdiscretestatetype( SrcDiscStateData%rotors(i1), DstDiscStateData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DstInputFileData%Echo = SrcInputFileData%Echo + DstInputFileData%DTAero = SrcInputFileData%DTAero + DstInputFileData%WakeMod = SrcInputFileData%WakeMod + DstInputFileData%AFAeroMod = SrcInputFileData%AFAeroMod + DstInputFileData%TwrPotent = SrcInputFileData%TwrPotent + DstInputFileData%TwrShadow = SrcInputFileData%TwrShadow + DstInputFileData%TwrAero = SrcInputFileData%TwrAero + DstInputFileData%FrozenWake = SrcInputFileData%FrozenWake + DstInputFileData%CavitCheck = SrcInputFileData%CavitCheck + DstInputFileData%Buoyancy = SrcInputFileData%Buoyancy + 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 + DstInputFileData%Pvap = SrcInputFileData%Pvap + DstInputFileData%SpdSound = SrcInputFileData%SpdSound + DstInputFileData%SkewMod = SrcInputFileData%SkewMod + DstInputFileData%SkewModFactor = SrcInputFileData%SkewModFactor + DstInputFileData%TipLoss = SrcInputFileData%TipLoss + DstInputFileData%HubLoss = SrcInputFileData%HubLoss + DstInputFileData%TanInd = SrcInputFileData%TanInd + DstInputFileData%AIDrag = SrcInputFileData%AIDrag + DstInputFileData%TIDrag = SrcInputFileData%TIDrag + DstInputFileData%IndToler = SrcInputFileData%IndToler + DstInputFileData%MaxIter = SrcInputFileData%MaxIter + DstInputFileData%UAMod = SrcInputFileData%UAMod + DstInputFileData%FLookup = SrcInputFileData%FLookup + DstInputFileData%InCol_Alfa = SrcInputFileData%InCol_Alfa + DstInputFileData%InCol_Cl = SrcInputFileData%InCol_Cl + DstInputFileData%InCol_Cd = SrcInputFileData%InCol_Cd + DstInputFileData%InCol_Cm = SrcInputFileData%InCol_Cm + DstInputFileData%InCol_Cpmin = SrcInputFileData%InCol_Cpmin + DstInputFileData%AFTabMod = SrcInputFileData%AFTabMod + DstInputFileData%NumAFfiles = SrcInputFileData%NumAFfiles + DstInputFileData%FVWFileName = SrcInputFileData%FVWFileName +IF (ALLOCATED(SrcInputFileData%AFNames)) THEN + i1_l = LBOUND(SrcInputFileData%AFNames,1) + i1_u = UBOUND(SrcInputFileData%AFNames,1) + IF (.NOT. ALLOCATED(DstInputFileData%AFNames)) THEN + ALLOCATE(DstInputFileData%AFNames(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%AFNames.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputFileData%AFNames = SrcInputFileData%AFNames +ENDIF + DstInputFileData%UseBlCm = SrcInputFileData%UseBlCm + DstInputFileData%SumPrint = SrcInputFileData%SumPrint + DstInputFileData%NBlOuts = SrcInputFileData%NBlOuts + DstInputFileData%BlOutNd = SrcInputFileData%BlOutNd + DstInputFileData%NTwOuts = SrcInputFileData%NTwOuts + DstInputFileData%TwOutNd = SrcInputFileData%TwOutNd + DstInputFileData%NumOuts = SrcInputFileData%NumOuts +IF (ALLOCATED(SrcInputFileData%OutList)) THEN + i1_l = LBOUND(SrcInputFileData%OutList,1) + i1_u = UBOUND(SrcInputFileData%OutList,1) + IF (.NOT. ALLOCATED(DstInputFileData%OutList)) THEN + ALLOCATE(DstInputFileData%OutList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%OutList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputFileData%OutList = SrcInputFileData%OutList +ENDIF + DstInputFileData%tau1_const = SrcInputFileData%tau1_const + DstInputFileData%DBEMT_Mod = SrcInputFileData%DBEMT_Mod + DstInputFileData%BldNd_NumOuts = SrcInputFileData%BldNd_NumOuts +IF (ALLOCATED(SrcInputFileData%BldNd_OutList)) THEN + i1_l = LBOUND(SrcInputFileData%BldNd_OutList,1) + i1_u = UBOUND(SrcInputFileData%BldNd_OutList,1) + IF (.NOT. ALLOCATED(DstInputFileData%BldNd_OutList)) THEN + ALLOCATE(DstInputFileData%BldNd_OutList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%BldNd_OutList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputFileData%BldNd_OutList = SrcInputFileData%BldNd_OutList +ENDIF + DstInputFileData%BldNd_BlOutNd_Str = SrcInputFileData%BldNd_BlOutNd_Str + DstInputFileData%BldNd_BladesOut = SrcInputFileData%BldNd_BladesOut + DstInputFileData%UAStartRad = SrcInputFileData%UAStartRad + DstInputFileData%UAEndRad = SrcInputFileData%UAEndRad +IF (ALLOCATED(SrcInputFileData%rotors)) THEN + i1_l = LBOUND(SrcInputFileData%rotors,1) + i1_u = UBOUND(SrcInputFileData%rotors,1) + IF (.NOT. ALLOCATED(DstInputFileData%rotors)) THEN + ALLOCATE(DstInputFileData%rotors(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%rotors.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcInputFileData%rotors,1), UBOUND(SrcInputFileData%rotors,1) + CALL AD_Copyrotinputfile( SrcInputFileData%rotors(i1), DstInputFileData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF - CALL FVW_CopyDiscState( SrcDiscStateData%FVW, DstDiscStateData%FVW, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE AD_CopyDiscState + END SUBROUTINE AD_CopyInputFile - SUBROUTINE AD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) - TYPE(AD_DiscreteStateType), INTENT(INOUT) :: DiscStateData + SUBROUTINE AD_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(AD_InputFile), INTENT(INOUT) :: InputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyInputFile' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(DiscStateData%rotors)) THEN -DO i1 = LBOUND(DiscStateData%rotors,1), UBOUND(DiscStateData%rotors,1) - CALL AD_Destroyrotdiscretestatetype( DiscStateData%rotors(i1), ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(InputFileData%ADBlFile)) THEN + DEALLOCATE(InputFileData%ADBlFile) +ENDIF +IF (ALLOCATED(InputFileData%AFNames)) THEN + DEALLOCATE(InputFileData%AFNames) +ENDIF +IF (ALLOCATED(InputFileData%OutList)) THEN + DEALLOCATE(InputFileData%OutList) +ENDIF +IF (ALLOCATED(InputFileData%BldNd_OutList)) THEN + DEALLOCATE(InputFileData%BldNd_OutList) +ENDIF +IF (ALLOCATED(InputFileData%rotors)) THEN +DO i1 = LBOUND(InputFileData%rotors,1), UBOUND(InputFileData%rotors,1) + CALL AD_Destroyrotinputfile( InputFileData%rotors(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(DiscStateData%rotors) + DEALLOCATE(InputFileData%rotors) ENDIF - CALL FVW_DestroyDiscState( DiscStateData%FVW, ErrStat, ErrMsg ) - END SUBROUTINE AD_DestroyDiscState + END SUBROUTINE AD_DestroyInputFile - SUBROUTINE AD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE AD_PackInputFile( 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(AD_DiscreteStateType), INTENT(IN) :: InData + TYPE(AD_InputFile), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -5582,7 +5400,7 @@ SUBROUTINE AD_PackDiscState( 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 = 'AD_PackDiscState' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackInputFile' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -5598,13 +5416,83 @@ SUBROUTINE AD_PackDiscState( 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 + Int_BufSz = Int_BufSz + 1 ! TwrPotent + Int_BufSz = Int_BufSz + 1 ! TwrShadow + Int_BufSz = Int_BufSz + 1 ! TwrAero + Int_BufSz = Int_BufSz + 1 ! FrozenWake + Int_BufSz = Int_BufSz + 1 ! CavitCheck + Int_BufSz = Int_BufSz + 1 ! Buoyancy + 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 + Re_BufSz = Re_BufSz + 1 ! Pvap + Re_BufSz = Re_BufSz + 1 ! SpdSound + Int_BufSz = Int_BufSz + 1 ! SkewMod + Re_BufSz = Re_BufSz + 1 ! SkewModFactor + Int_BufSz = Int_BufSz + 1 ! TipLoss + Int_BufSz = Int_BufSz + 1 ! HubLoss + Int_BufSz = Int_BufSz + 1 ! TanInd + Int_BufSz = Int_BufSz + 1 ! AIDrag + Int_BufSz = Int_BufSz + 1 ! TIDrag + Re_BufSz = Re_BufSz + 1 ! IndToler + Re_BufSz = Re_BufSz + 1 ! MaxIter + Int_BufSz = Int_BufSz + 1 ! UAMod + Int_BufSz = Int_BufSz + 1 ! FLookup + Re_BufSz = Re_BufSz + 1 ! InCol_Alfa + Re_BufSz = Re_BufSz + 1 ! InCol_Cl + Re_BufSz = Re_BufSz + 1 ! InCol_Cd + Re_BufSz = Re_BufSz + 1 ! InCol_Cm + Re_BufSz = Re_BufSz + 1 ! InCol_Cpmin + Int_BufSz = Int_BufSz + 1 ! AFTabMod + Int_BufSz = Int_BufSz + 1 ! NumAFfiles + Int_BufSz = Int_BufSz + 1*LEN(InData%FVWFileName) ! FVWFileName + Int_BufSz = Int_BufSz + 1 ! AFNames allocated yes/no + IF ( ALLOCATED(InData%AFNames) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AFNames upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%AFNames)*LEN(InData%AFNames) ! AFNames + END IF + Int_BufSz = Int_BufSz + 1 ! UseBlCm + Int_BufSz = Int_BufSz + 1 ! SumPrint + Int_BufSz = Int_BufSz + 1 ! NBlOuts + Int_BufSz = Int_BufSz + SIZE(InData%BlOutNd) ! BlOutNd + Int_BufSz = Int_BufSz + 1 ! NTwOuts + Int_BufSz = Int_BufSz + SIZE(InData%TwOutNd) ! TwOutNd + 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 + Re_BufSz = Re_BufSz + 1 ! tau1_const + Int_BufSz = Int_BufSz + 1 ! DBEMT_Mod + Int_BufSz = Int_BufSz + 1 ! BldNd_NumOuts + Int_BufSz = Int_BufSz + 1 ! BldNd_OutList allocated yes/no + IF ( ALLOCATED(InData%BldNd_OutList) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BldNd_OutList upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%BldNd_OutList)*LEN(InData%BldNd_OutList) ! BldNd_OutList + END IF + Int_BufSz = Int_BufSz + 1*LEN(InData%BldNd_BlOutNd_Str) ! BldNd_BlOutNd_Str + Int_BufSz = Int_BufSz + 1 ! BldNd_BladesOut + Re_BufSz = Re_BufSz + 1 ! UAStartRad + Re_BufSz = Re_BufSz + 1 ! UAEndRad Int_BufSz = Int_BufSz + 1 ! rotors allocated yes/no IF ( ALLOCATED(InData%rotors) ) THEN Int_BufSz = Int_BufSz + 2*1 ! rotors upper/lower bounds for each dimension ! Allocate buffers for subtypes, if any (we'll get sizes from these) DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) Int_BufSz = Int_BufSz + 3 ! rotors: size of buffers for each call to pack subtype - CALL AD_Packrotdiscretestatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors + CALL AD_Packrotinputfile( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5622,23 +5510,6 @@ SUBROUTINE AD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg END IF END DO END IF - Int_BufSz = Int_BufSz + 3 ! FVW: size of buffers for each call to pack subtype - CALL FVW_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, .TRUE. ) ! FVW - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! FVW - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! FVW - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! FVW - 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 @@ -5666,48 +5537,196 @@ SUBROUTINE AD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Db_Xferred = 1 Int_Xferred = 1 - IF ( .NOT. ALLOCATED(InData%rotors) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IntKiBuf(Int_Xferred) = TRANSFER(InData%Echo, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 + DbKiBuf(Db_Xferred) = InData%DTAero + Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%WakeMod Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%rotors,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%rotors,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) - CALL AD_Packrotdiscretestatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + IntKiBuf(Int_Xferred) = InData%AFAeroMod + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%TwrPotent + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%TwrShadow + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%TwrAero, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%FrozenWake, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%CavitCheck, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%Buoyancy, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%CompAA, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(InData%AA_InputFile) + 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 - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF + DO i1 = LBOUND(InData%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 + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Patm + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Pvap + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%SpdSound + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%SkewMod + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%SkewModFactor + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%TipLoss, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%HubLoss, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%TanInd, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%AIDrag, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%TIDrag, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%IndToler + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MaxIter + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%UAMod + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%FLookup, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%InCol_Alfa + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%InCol_Cl + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%InCol_Cd + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%InCol_Cm + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%InCol_Cpmin + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%AFTabMod + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumAFfiles + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(InData%FVWFileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%FVWFileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IF ( .NOT. ALLOCATED(InData%AFNames) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AFNames,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AFNames,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AFNames,1), UBOUND(InData%AFNames,1) + DO I = 1, LEN(InData%AFNames) + IntKiBuf(Int_Xferred) = ICHAR(InData%AFNames(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IntKiBuf(Int_Xferred) = TRANSFER(InData%UseBlCm, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%SumPrint, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NBlOuts + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%BlOutNd,1), UBOUND(InData%BlOutNd,1) + IntKiBuf(Int_Xferred) = InData%BlOutNd(i1) + Int_Xferred = Int_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%NTwOuts + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%TwOutNd,1), UBOUND(InData%TwOutNd,1) + IntKiBuf(Int_Xferred) = InData%TwOutNd(i1) + Int_Xferred = Int_Xferred + 1 END DO + IntKiBuf(Int_Xferred) = InData%NumOuts + Int_Xferred = Int_Xferred + 1 + 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 - CALL FVW_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, OnlySize ) ! FVW + ReKiBuf(Re_Xferred) = InData%tau1_const + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%DBEMT_Mod + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%BldNd_NumOuts + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%BldNd_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%BldNd_OutList,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldNd_OutList,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BldNd_OutList,1), UBOUND(InData%BldNd_OutList,1) + DO I = 1, LEN(InData%BldNd_OutList) + IntKiBuf(Int_Xferred) = ICHAR(InData%BldNd_OutList(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + DO I = 1, LEN(InData%BldNd_BlOutNd_Str) + IntKiBuf(Int_Xferred) = ICHAR(InData%BldNd_BlOutNd_Str(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IntKiBuf(Int_Xferred) = InData%BldNd_BladesOut + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%UAStartRad + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%UAEndRad + Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%rotors) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%rotors,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%rotors,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) + CALL AD_Packrotinputfile( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5735,13 +5754,15 @@ SUBROUTINE AD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END SUBROUTINE AD_PackDiscState + END DO + END IF + END SUBROUTINE AD_PackInputFile - SUBROUTINE AD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_UnPackInputFile( 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(AD_DiscreteStateType), INTENT(INOUT) :: OutData + TYPE(AD_InputFile), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -5753,7 +5774,7 @@ SUBROUTINE AD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackDiscState' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackInputFile' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -5764,62 +5785,214 @@ SUBROUTINE AD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! rotors not allocated + 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) + Int_Xferred = Int_Xferred + 1 + OutData%AFAeroMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%TwrPotent = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%TwrShadow = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%TwrAero = TRANSFER(IntKiBuf(Int_Xferred), OutData%TwrAero) + Int_Xferred = Int_Xferred + 1 + OutData%FrozenWake = TRANSFER(IntKiBuf(Int_Xferred), OutData%FrozenWake) + Int_Xferred = Int_Xferred + 1 + OutData%CavitCheck = TRANSFER(IntKiBuf(Int_Xferred), OutData%CavitCheck) + Int_Xferred = Int_Xferred + 1 + OutData%Buoyancy = TRANSFER(IntKiBuf(Int_Xferred), OutData%Buoyancy) + Int_Xferred = Int_Xferred + 1 + OutData%CompAA = TRANSFER(IntKiBuf(Int_Xferred), OutData%CompAA) + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(OutData%AA_InputFile) + 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%rotors)) DEALLOCATE(OutData%rotors) - ALLOCATE(OutData%rotors(i1_l:i1_u),STAT=ErrStat2) + 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%rotors.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ADBlFile.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%rotors,1), UBOUND(OutData%rotors,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 ) + 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) + Re_Xferred = Re_Xferred + 1 + OutData%Patm = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Pvap = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%SpdSound = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%SkewMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%SkewModFactor = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%TipLoss = TRANSFER(IntKiBuf(Int_Xferred), OutData%TipLoss) + Int_Xferred = Int_Xferred + 1 + OutData%HubLoss = TRANSFER(IntKiBuf(Int_Xferred), OutData%HubLoss) + Int_Xferred = Int_Xferred + 1 + OutData%TanInd = TRANSFER(IntKiBuf(Int_Xferred), OutData%TanInd) + Int_Xferred = Int_Xferred + 1 + OutData%AIDrag = TRANSFER(IntKiBuf(Int_Xferred), OutData%AIDrag) + Int_Xferred = Int_Xferred + 1 + OutData%TIDrag = TRANSFER(IntKiBuf(Int_Xferred), OutData%TIDrag) + Int_Xferred = Int_Xferred + 1 + OutData%IndToler = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MaxIter = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%UAMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%FLookup = TRANSFER(IntKiBuf(Int_Xferred), OutData%FLookup) + Int_Xferred = Int_Xferred + 1 + OutData%InCol_Alfa = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%InCol_Cl = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%InCol_Cd = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%InCol_Cm = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%InCol_Cpmin = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%AFTabMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NumAFfiles = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(OutData%FVWFileName) + OutData%FVWFileName(I:I) = CHAR(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 ) + END DO ! I + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AFNames not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AFNames)) DEALLOCATE(OutData%AFNames) + ALLOCATE(OutData%AFNames(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AFNames.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AFNames,1), UBOUND(OutData%AFNames,1) + DO I = 1, LEN(OutData%AFNames) + OutData%AFNames(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + OutData%UseBlCm = TRANSFER(IntKiBuf(Int_Xferred), OutData%UseBlCm) + Int_Xferred = Int_Xferred + 1 + OutData%SumPrint = TRANSFER(IntKiBuf(Int_Xferred), OutData%SumPrint) + Int_Xferred = Int_Xferred + 1 + OutData%NBlOuts = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%BlOutNd,1) + i1_u = UBOUND(OutData%BlOutNd,1) + DO i1 = LBOUND(OutData%BlOutNd,1), UBOUND(OutData%BlOutNd,1) + OutData%BlOutNd(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + OutData%NTwOuts = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%TwOutNd,1) + i1_u = UBOUND(OutData%TwOutNd,1) + DO i1 = LBOUND(OutData%TwOutNd,1), UBOUND(OutData%TwOutNd,1) + OutData%TwOutNd(i1) = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AD_Unpackrotdiscretestatetype( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors - 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 + OutData%NumOuts = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + 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%tau1_const = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%DBEMT_Mod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%BldNd_NumOuts = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldNd_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%BldNd_OutList)) DEALLOCATE(OutData%BldNd_OutList) + ALLOCATE(OutData%BldNd_OutList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BldNd_OutList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BldNd_OutList,1), UBOUND(OutData%BldNd_OutList,1) + DO I = 1, LEN(OutData%BldNd_OutList) + OutData%BldNd_OutList(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO END IF + DO I = 1, LEN(OutData%BldNd_BlOutNd_Str) + OutData%BldNd_BlOutNd_Str(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%BldNd_BladesOut = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%UAStartRad = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%UAEndRad = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! rotors not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%rotors)) DEALLOCATE(OutData%rotors) + ALLOCATE(OutData%rotors(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%rotors.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%rotors,1), UBOUND(OutData%rotors,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -5853,18 +6026,20 @@ SUBROUTINE AD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL FVW_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%FVW, ErrStat2, ErrMsg2 ) ! FVW + CALL AD_Unpackrotinputfile( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors 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_UnPackDiscState + END DO + END IF + END SUBROUTINE AD_UnPackInputFile - SUBROUTINE AD_CopyRotConstraintStateType( SrcRotConstraintStateTypeData, DstRotConstraintStateTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(RotConstraintStateType), INTENT(IN) :: SrcRotConstraintStateTypeData - TYPE(RotConstraintStateType), INTENT(INOUT) :: DstRotConstraintStateTypeData + SUBROUTINE AD_CopyRotContinuousStateType( SrcRotContinuousStateTypeData, DstRotContinuousStateTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(RotContinuousStateType), INTENT(IN) :: SrcRotContinuousStateTypeData + TYPE(RotContinuousStateType), INTENT(INOUT) :: DstRotContinuousStateTypeData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -5872,36 +6047,50 @@ SUBROUTINE AD_CopyRotConstraintStateType( SrcRotConstraintStateTypeData, DstRotC INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyRotConstraintStateType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyRotContinuousStateType' ! ErrStat = ErrID_None ErrMsg = "" - CALL BEMT_CopyConstrState( SrcRotConstraintStateTypeData%BEMT, DstRotConstraintStateTypeData%BEMT, CtrlCode, ErrStat2, ErrMsg2 ) + CALL BEMT_CopyContState( SrcRotContinuousStateTypeData%BEMT, DstRotContinuousStateTypeData%BEMT, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AA_CopyConstrState( SrcRotConstraintStateTypeData%AA, DstRotConstraintStateTypeData%AA, CtrlCode, ErrStat2, ErrMsg2 ) + CALL AA_CopyContState( SrcRotContinuousStateTypeData%AA, DstRotContinuousStateTypeData%AA, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE AD_CopyRotConstraintStateType + END SUBROUTINE AD_CopyRotContinuousStateType - SUBROUTINE AD_DestroyRotConstraintStateType( RotConstraintStateTypeData, ErrStat, ErrMsg ) - TYPE(RotConstraintStateType), INTENT(INOUT) :: RotConstraintStateTypeData + SUBROUTINE AD_DestroyRotContinuousStateType( RotContinuousStateTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(RotContinuousStateType), INTENT(INOUT) :: RotContinuousStateTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotConstraintStateType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotContinuousStateType' + ErrStat = ErrID_None ErrMsg = "" - CALL BEMT_DestroyConstrState( RotConstraintStateTypeData%BEMT, ErrStat, ErrMsg ) - CALL AA_DestroyConstrState( RotConstraintStateTypeData%AA, ErrStat, ErrMsg ) - END SUBROUTINE AD_DestroyRotConstraintStateType - SUBROUTINE AD_PackRotConstraintStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL BEMT_DestroyContState( RotContinuousStateTypeData%BEMT, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AA_DestroyContState( RotContinuousStateTypeData%AA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE AD_DestroyRotContinuousStateType + + SUBROUTINE AD_PackRotContinuousStateType( 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(RotConstraintStateType), INTENT(IN) :: InData + TYPE(RotContinuousStateType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -5916,7 +6105,7 @@ SUBROUTINE AD_PackRotConstraintStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackRotConstraintStateType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackRotContinuousStateType' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -5934,7 +6123,7 @@ SUBROUTINE AD_PackRotConstraintStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er Int_BufSz = 0 ! Allocate buffers for subtypes, if any (we'll get sizes from these) Int_BufSz = Int_BufSz + 3 ! BEMT: size of buffers for each call to pack subtype - CALL BEMT_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, .TRUE. ) ! BEMT + CALL BEMT_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, .TRUE. ) ! BEMT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5951,7 +6140,7 @@ SUBROUTINE AD_PackRotConstraintStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! AA: size of buffers for each call to pack subtype - CALL AA_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, .TRUE. ) ! AA + CALL AA_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, .TRUE. ) ! AA CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5994,7 +6183,7 @@ SUBROUTINE AD_PackRotConstraintStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er Db_Xferred = 1 Int_Xferred = 1 - CALL BEMT_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, OnlySize ) ! BEMT + CALL BEMT_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, OnlySize ) ! BEMT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6022,7 +6211,7 @@ SUBROUTINE AD_PackRotConstraintStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL AA_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, OnlySize ) ! AA + CALL AA_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, OnlySize ) ! AA CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6050,13 +6239,13 @@ SUBROUTINE AD_PackRotConstraintStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, Er ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END SUBROUTINE AD_PackRotConstraintStateType + END SUBROUTINE AD_PackRotContinuousStateType - SUBROUTINE AD_UnPackRotConstraintStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_UnPackRotContinuousStateType( 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(RotConstraintStateType), INTENT(INOUT) :: OutData + TYPE(RotContinuousStateType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -6067,7 +6256,7 @@ SUBROUTINE AD_UnPackRotConstraintStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, INTEGER(IntKi) :: i INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackRotConstraintStateType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackRotContinuousStateType' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -6111,7 +6300,7 @@ SUBROUTINE AD_UnPackRotConstraintStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL BEMT_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT, ErrStat2, ErrMsg2 ) ! BEMT + CALL BEMT_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT, ErrStat2, ErrMsg2 ) ! BEMT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6151,18 +6340,18 @@ SUBROUTINE AD_UnPackRotConstraintStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL AA_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%AA, ErrStat2, ErrMsg2 ) ! AA + CALL AA_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%AA, ErrStat2, ErrMsg2 ) ! AA 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_UnPackRotConstraintStateType + END SUBROUTINE AD_UnPackRotContinuousStateType - SUBROUTINE AD_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(AD_ConstraintStateType), INTENT(IN) :: SrcConstrStateData - TYPE(AD_ConstraintStateType), INTENT(INOUT) :: DstConstrStateData + SUBROUTINE AD_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(AD_ContinuousStateType), INTENT(IN) :: SrcContStateData + TYPE(AD_ContinuousStateType), INTENT(INOUT) :: DstContStateData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -6171,54 +6360,68 @@ SUBROUTINE AD_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyConstrState' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyContState' ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcConstrStateData%rotors)) THEN - i1_l = LBOUND(SrcConstrStateData%rotors,1) - i1_u = UBOUND(SrcConstrStateData%rotors,1) - IF (.NOT. ALLOCATED(DstConstrStateData%rotors)) THEN - ALLOCATE(DstConstrStateData%rotors(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcContStateData%rotors)) THEN + i1_l = LBOUND(SrcContStateData%rotors,1) + i1_u = UBOUND(SrcContStateData%rotors,1) + IF (.NOT. ALLOCATED(DstContStateData%rotors)) THEN + ALLOCATE(DstContStateData%rotors(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstConstrStateData%rotors.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstContStateData%rotors.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcConstrStateData%rotors,1), UBOUND(SrcConstrStateData%rotors,1) - CALL AD_Copyrotconstraintstatetype( SrcConstrStateData%rotors(i1), DstConstrStateData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcContStateData%rotors,1), UBOUND(SrcContStateData%rotors,1) + CALL AD_Copyrotcontinuousstatetype( SrcContStateData%rotors(i1), DstContStateData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF - CALL FVW_CopyConstrState( SrcConstrStateData%FVW, DstConstrStateData%FVW, CtrlCode, ErrStat2, ErrMsg2 ) + CALL FVW_CopyContState( SrcContStateData%FVW, DstContStateData%FVW, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE AD_CopyConstrState + END SUBROUTINE AD_CopyContState - SUBROUTINE AD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) - TYPE(AD_ConstraintStateType), INTENT(INOUT) :: ConstrStateData + SUBROUTINE AD_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(AD_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(ConstrStateData%rotors)) THEN -DO i1 = LBOUND(ConstrStateData%rotors,1), UBOUND(ConstrStateData%rotors,1) - CALL AD_Destroyrotconstraintstatetype( ConstrStateData%rotors(i1), ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(ContStateData%rotors)) THEN +DO i1 = LBOUND(ContStateData%rotors,1), UBOUND(ContStateData%rotors,1) + CALL AD_Destroyrotcontinuousstatetype( ContStateData%rotors(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(ConstrStateData%rotors) + DEALLOCATE(ContStateData%rotors) ENDIF - CALL FVW_DestroyConstrState( ConstrStateData%FVW, ErrStat, ErrMsg ) - END SUBROUTINE AD_DestroyConstrState + CALL FVW_DestroyContState( ContStateData%FVW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE AD_DestroyContState - SUBROUTINE AD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE AD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(AD_ConstraintStateType), INTENT(IN) :: InData + TYPE(AD_ContinuousStateType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -6233,7 +6436,7 @@ SUBROUTINE AD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackConstrState' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackContState' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -6255,7 +6458,7 @@ SUBROUTINE AD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ! Allocate buffers for subtypes, if any (we'll get sizes from these) DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) Int_BufSz = Int_BufSz + 3 ! rotors: size of buffers for each call to pack subtype - CALL AD_Packrotconstraintstatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors + CALL AD_Packrotcontinuousstatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6274,7 +6477,7 @@ SUBROUTINE AD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM END DO END IF Int_BufSz = Int_BufSz + 3 ! FVW: size of buffers for each call to pack subtype - CALL FVW_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, .TRUE. ) ! FVW + CALL FVW_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, .TRUE. ) ! FVW CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6328,7 +6531,7 @@ SUBROUTINE AD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Int_Xferred = Int_Xferred + 2 DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) - CALL AD_Packrotconstraintstatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors + CALL AD_Packrotcontinuousstatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6358,7 +6561,7 @@ SUBROUTINE AD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ENDIF END DO END IF - CALL FVW_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, OnlySize ) ! FVW + CALL FVW_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, OnlySize ) ! FVW CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6386,13 +6589,13 @@ SUBROUTINE AD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END SUBROUTINE AD_PackConstrState + END SUBROUTINE AD_PackContState - SUBROUTINE AD_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(AD_ConstraintStateType), INTENT(INOUT) :: OutData + TYPE(AD_ContinuousStateType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -6404,7 +6607,7 @@ SUBROUTINE AD_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackConstrState' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackContState' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -6462,7 +6665,7 @@ SUBROUTINE AD_UnPackConstrState( 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 AD_Unpackrotconstraintstatetype( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors + CALL AD_Unpackrotcontinuousstatetype( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6504,18 +6707,18 @@ SUBROUTINE AD_UnPackConstrState( 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 FVW_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%FVW, ErrStat2, ErrMsg2 ) ! FVW + CALL FVW_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%FVW, ErrStat2, ErrMsg2 ) ! FVW 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_UnPackConstrState + END SUBROUTINE AD_UnPackContState - SUBROUTINE AD_CopyRotOtherStateType( SrcRotOtherStateTypeData, DstRotOtherStateTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(RotOtherStateType), INTENT(IN) :: SrcRotOtherStateTypeData - TYPE(RotOtherStateType), INTENT(INOUT) :: DstRotOtherStateTypeData + SUBROUTINE AD_CopyRotDiscreteStateType( SrcRotDiscreteStateTypeData, DstRotDiscreteStateTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(RotDiscreteStateType), INTENT(IN) :: SrcRotDiscreteStateTypeData + TYPE(RotDiscreteStateType), INTENT(INOUT) :: DstRotDiscreteStateTypeData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -6523,36 +6726,50 @@ SUBROUTINE AD_CopyRotOtherStateType( SrcRotOtherStateTypeData, DstRotOtherStateT INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyRotOtherStateType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyRotDiscreteStateType' ! ErrStat = ErrID_None ErrMsg = "" - CALL BEMT_CopyOtherState( SrcRotOtherStateTypeData%BEMT, DstRotOtherStateTypeData%BEMT, CtrlCode, ErrStat2, ErrMsg2 ) + CALL BEMT_CopyDiscState( SrcRotDiscreteStateTypeData%BEMT, DstRotDiscreteStateTypeData%BEMT, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AA_CopyOtherState( SrcRotOtherStateTypeData%AA, DstRotOtherStateTypeData%AA, CtrlCode, ErrStat2, ErrMsg2 ) + CALL AA_CopyDiscState( SrcRotDiscreteStateTypeData%AA, DstRotDiscreteStateTypeData%AA, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE AD_CopyRotOtherStateType + END SUBROUTINE AD_CopyRotDiscreteStateType - SUBROUTINE AD_DestroyRotOtherStateType( RotOtherStateTypeData, ErrStat, ErrMsg ) - TYPE(RotOtherStateType), INTENT(INOUT) :: RotOtherStateTypeData + SUBROUTINE AD_DestroyRotDiscreteStateType( RotDiscreteStateTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(RotDiscreteStateType), INTENT(INOUT) :: RotDiscreteStateTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotOtherStateType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotDiscreteStateType' + ErrStat = ErrID_None ErrMsg = "" - CALL BEMT_DestroyOtherState( RotOtherStateTypeData%BEMT, ErrStat, ErrMsg ) - CALL AA_DestroyOtherState( RotOtherStateTypeData%AA, ErrStat, ErrMsg ) - END SUBROUTINE AD_DestroyRotOtherStateType - SUBROUTINE AD_PackRotOtherStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL BEMT_DestroyDiscState( RotDiscreteStateTypeData%BEMT, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AA_DestroyDiscState( RotDiscreteStateTypeData%AA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE AD_DestroyRotDiscreteStateType + + SUBROUTINE AD_PackRotDiscreteStateType( 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(RotOtherStateType), INTENT(IN) :: InData + TYPE(RotDiscreteStateType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -6567,7 +6784,7 @@ SUBROUTINE AD_PackRotOtherStateType( 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 = 'AD_PackRotOtherStateType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackRotDiscreteStateType' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -6585,7 +6802,7 @@ SUBROUTINE AD_PackRotOtherStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_BufSz = 0 ! Allocate buffers for subtypes, if any (we'll get sizes from these) Int_BufSz = Int_BufSz + 3 ! BEMT: size of buffers for each call to pack subtype - CALL BEMT_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, .TRUE. ) ! BEMT + CALL BEMT_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, .TRUE. ) ! BEMT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6602,7 +6819,7 @@ SUBROUTINE AD_PackRotOtherStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! AA: size of buffers for each call to pack subtype - CALL AA_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, .TRUE. ) ! AA + CALL AA_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, .TRUE. ) ! AA CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6645,7 +6862,7 @@ SUBROUTINE AD_PackRotOtherStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Db_Xferred = 1 Int_Xferred = 1 - CALL BEMT_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, OnlySize ) ! BEMT + CALL BEMT_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, OnlySize ) ! BEMT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6673,7 +6890,7 @@ SUBROUTINE AD_PackRotOtherStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL AA_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, OnlySize ) ! AA + CALL AA_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, OnlySize ) ! AA CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6701,13 +6918,13 @@ SUBROUTINE AD_PackRotOtherStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - END SUBROUTINE AD_PackRotOtherStateType + END SUBROUTINE AD_PackRotDiscreteStateType - SUBROUTINE AD_UnPackRotOtherStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_UnPackRotDiscreteStateType( 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(RotOtherStateType), INTENT(INOUT) :: OutData + TYPE(RotDiscreteStateType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -6718,7 +6935,7 @@ SUBROUTINE AD_UnPackRotOtherStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS INTEGER(IntKi) :: i INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackRotOtherStateType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackRotDiscreteStateType' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -6762,7 +6979,7 @@ SUBROUTINE AD_UnPackRotOtherStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL BEMT_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT, ErrStat2, ErrMsg2 ) ! BEMT + CALL BEMT_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT, ErrStat2, ErrMsg2 ) ! BEMT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6802,92 +7019,88 @@ SUBROUTINE AD_UnPackRotOtherStateType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL AA_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%AA, ErrStat2, ErrMsg2 ) ! AA + CALL AA_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%AA, ErrStat2, ErrMsg2 ) ! AA 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_UnPackRotOtherStateType + END SUBROUTINE AD_UnPackRotDiscreteStateType - SUBROUTINE AD_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(AD_OtherStateType), INTENT(IN) :: SrcOtherStateData - TYPE(AD_OtherStateType), INTENT(INOUT) :: DstOtherStateData + SUBROUTINE AD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(AD_DiscreteStateType), INTENT(IN) :: SrcDiscStateData + TYPE(AD_DiscreteStateType), INTENT(INOUT) :: DstDiscStateData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: 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 = 'AD_CopyOtherState' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyDiscState' ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcOtherStateData%rotors)) THEN - i1_l = LBOUND(SrcOtherStateData%rotors,1) - i1_u = UBOUND(SrcOtherStateData%rotors,1) - IF (.NOT. ALLOCATED(DstOtherStateData%rotors)) THEN - ALLOCATE(DstOtherStateData%rotors(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcDiscStateData%rotors)) THEN + i1_l = LBOUND(SrcDiscStateData%rotors,1) + i1_u = UBOUND(SrcDiscStateData%rotors,1) + IF (.NOT. ALLOCATED(DstDiscStateData%rotors)) THEN + ALLOCATE(DstDiscStateData%rotors(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOtherStateData%rotors.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%rotors.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcOtherStateData%rotors,1), UBOUND(SrcOtherStateData%rotors,1) - CALL AD_Copyrototherstatetype( SrcOtherStateData%rotors(i1), DstOtherStateData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DO i1 = LBOUND(SrcDiscStateData%rotors,1), UBOUND(SrcDiscStateData%rotors,1) + CALL AD_Copyrotdiscretestatetype( SrcDiscStateData%rotors(i1), DstDiscStateData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF - CALL FVW_CopyOtherState( SrcOtherStateData%FVW, DstOtherStateData%FVW, CtrlCode, ErrStat2, ErrMsg2 ) + CALL FVW_CopyDiscState( SrcDiscStateData%FVW, DstDiscStateData%FVW, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN -IF (ALLOCATED(SrcOtherStateData%WakeLocationPoints)) THEN - i1_l = LBOUND(SrcOtherStateData%WakeLocationPoints,1) - i1_u = UBOUND(SrcOtherStateData%WakeLocationPoints,1) - i2_l = LBOUND(SrcOtherStateData%WakeLocationPoints,2) - i2_u = UBOUND(SrcOtherStateData%WakeLocationPoints,2) - IF (.NOT. ALLOCATED(DstOtherStateData%WakeLocationPoints)) THEN - ALLOCATE(DstOtherStateData%WakeLocationPoints(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOtherStateData%WakeLocationPoints.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstOtherStateData%WakeLocationPoints = SrcOtherStateData%WakeLocationPoints -ENDIF - END SUBROUTINE AD_CopyOtherState + END SUBROUTINE AD_CopyDiscState - SUBROUTINE AD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) - TYPE(AD_OtherStateType), INTENT(INOUT) :: OtherStateData + SUBROUTINE AD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(AD_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(OtherStateData%rotors)) THEN -DO i1 = LBOUND(OtherStateData%rotors,1), UBOUND(OtherStateData%rotors,1) - CALL AD_Destroyrototherstatetype( OtherStateData%rotors(i1), ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(DiscStateData%rotors)) THEN +DO i1 = LBOUND(DiscStateData%rotors,1), UBOUND(DiscStateData%rotors,1) + CALL AD_Destroyrotdiscretestatetype( DiscStateData%rotors(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(OtherStateData%rotors) -ENDIF - CALL FVW_DestroyOtherState( OtherStateData%FVW, ErrStat, ErrMsg ) -IF (ALLOCATED(OtherStateData%WakeLocationPoints)) THEN - DEALLOCATE(OtherStateData%WakeLocationPoints) + DEALLOCATE(DiscStateData%rotors) ENDIF - END SUBROUTINE AD_DestroyOtherState + CALL FVW_DestroyDiscState( DiscStateData%FVW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE AD_DestroyDiscState - SUBROUTINE AD_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE AD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(AD_OtherStateType), INTENT(IN) :: InData + TYPE(AD_DiscreteStateType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -6902,7 +7115,7 @@ SUBROUTINE AD_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackOtherState' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackDiscState' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -6924,7 +7137,7 @@ SUBROUTINE AD_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ! Allocate buffers for subtypes, if any (we'll get sizes from these) DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) Int_BufSz = Int_BufSz + 3 ! rotors: size of buffers for each call to pack subtype - CALL AD_Packrototherstatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors + CALL AD_Packrotdiscretestatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6943,7 +7156,7 @@ SUBROUTINE AD_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs END DO END IF Int_BufSz = Int_BufSz + 3 ! FVW: size of buffers for each call to pack subtype - CALL FVW_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, .TRUE. ) ! FVW + CALL FVW_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, .TRUE. ) ! FVW CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -6959,11 +7172,6 @@ SUBROUTINE AD_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 1 ! WakeLocationPoints allocated yes/no - IF ( ALLOCATED(InData%WakeLocationPoints) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! WakeLocationPoints upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%WakeLocationPoints) ! WakeLocationPoints - END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -7002,7 +7210,7 @@ SUBROUTINE AD_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_Xferred = Int_Xferred + 2 DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) - CALL AD_Packrototherstatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors + CALL AD_Packrotdiscretestatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7032,7 +7240,7 @@ SUBROUTINE AD_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ENDIF END DO END IF - CALL FVW_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, OnlySize ) ! FVW + CALL FVW_PackDiscState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, OnlySize ) ! FVW CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7060,33 +7268,13 @@ SUBROUTINE AD_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - IF ( .NOT. ALLOCATED(InData%WakeLocationPoints) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WakeLocationPoints,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WakeLocationPoints,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WakeLocationPoints,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WakeLocationPoints,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%WakeLocationPoints,2), UBOUND(InData%WakeLocationPoints,2) - DO i1 = LBOUND(InData%WakeLocationPoints,1), UBOUND(InData%WakeLocationPoints,1) - ReKiBuf(Re_Xferred) = InData%WakeLocationPoints(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - END SUBROUTINE AD_PackOtherState + END SUBROUTINE AD_PackDiscState - SUBROUTINE AD_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE AD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(AD_OtherStateType), INTENT(INOUT) :: OutData + TYPE(AD_DiscreteStateType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -7096,10 +7284,9 @@ SUBROUTINE AD_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackOtherState' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackDiscState' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -7157,7 +7344,7 @@ SUBROUTINE AD_UnPackOtherState( 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 AD_Unpackrototherstatetype( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors + CALL AD_Unpackrotdiscretestatetype( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7199,751 +7386,3697 @@ SUBROUTINE AD_UnPackOtherState( 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 FVW_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%FVW, ErrStat2, ErrMsg2 ) ! FVW + CALL FVW_UnpackDiscState( Re_Buf, Db_Buf, Int_Buf, OutData%FVW, ErrStat2, ErrMsg2 ) ! FVW 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 ! WakeLocationPoints not allocated - Int_Xferred = Int_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%WakeLocationPoints)) DEALLOCATE(OutData%WakeLocationPoints) - ALLOCATE(OutData%WakeLocationPoints(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WakeLocationPoints.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%WakeLocationPoints,2), UBOUND(OutData%WakeLocationPoints,2) - DO i1 = LBOUND(OutData%WakeLocationPoints,1), UBOUND(OutData%WakeLocationPoints,1) - OutData%WakeLocationPoints(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - END SUBROUTINE AD_UnPackOtherState + END SUBROUTINE AD_UnPackDiscState - SUBROUTINE AD_CopyRotMiscVarType( SrcRotMiscVarTypeData, DstRotMiscVarTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(RotMiscVarType), INTENT(INOUT) :: SrcRotMiscVarTypeData - TYPE(RotMiscVarType), INTENT(INOUT) :: DstRotMiscVarTypeData + SUBROUTINE AD_CopyRotConstraintStateType( SrcRotConstraintStateTypeData, DstRotConstraintStateTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(RotConstraintStateType), INTENT(IN) :: SrcRotConstraintStateTypeData + TYPE(RotConstraintStateType), INTENT(INOUT) :: DstRotConstraintStateTypeData 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 = 'AD_CopyRotMiscVarType' + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyRotConstraintStateType' ! ErrStat = ErrID_None ErrMsg = "" - CALL BEMT_CopyMisc( SrcRotMiscVarTypeData%BEMT, DstRotMiscVarTypeData%BEMT, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL BEMT_CopyOutput( SrcRotMiscVarTypeData%BEMT_y, DstRotMiscVarTypeData%BEMT_y, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - DO i1 = LBOUND(SrcRotMiscVarTypeData%BEMT_u,1), UBOUND(SrcRotMiscVarTypeData%BEMT_u,1) - CALL BEMT_CopyInput( SrcRotMiscVarTypeData%BEMT_u(i1), DstRotMiscVarTypeData%BEMT_u(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO - CALL AA_CopyMisc( SrcRotMiscVarTypeData%AA, DstRotMiscVarTypeData%AA, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL AA_CopyOutput( SrcRotMiscVarTypeData%AA_y, DstRotMiscVarTypeData%AA_y, CtrlCode, ErrStat2, ErrMsg2 ) + CALL BEMT_CopyConstrState( SrcRotConstraintStateTypeData%BEMT, DstRotConstraintStateTypeData%BEMT, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL AA_CopyInput( SrcRotMiscVarTypeData%AA_u, DstRotMiscVarTypeData%AA_u, CtrlCode, ErrStat2, ErrMsg2 ) + CALL AA_CopyConstrState( SrcRotConstraintStateTypeData%AA, DstRotConstraintStateTypeData%AA, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN -IF (ALLOCATED(SrcRotMiscVarTypeData%DisturbedInflow)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%DisturbedInflow,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%DisturbedInflow,1) - i2_l = LBOUND(SrcRotMiscVarTypeData%DisturbedInflow,2) - i2_u = UBOUND(SrcRotMiscVarTypeData%DisturbedInflow,2) - i3_l = LBOUND(SrcRotMiscVarTypeData%DisturbedInflow,3) - i3_u = UBOUND(SrcRotMiscVarTypeData%DisturbedInflow,3) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%DisturbedInflow)) THEN - ALLOCATE(DstRotMiscVarTypeData%DisturbedInflow(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%DisturbedInflow.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotMiscVarTypeData%DisturbedInflow = SrcRotMiscVarTypeData%DisturbedInflow -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%WithoutSweepPitchTwist)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%WithoutSweepPitchTwist,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%WithoutSweepPitchTwist,1) - i2_l = LBOUND(SrcRotMiscVarTypeData%WithoutSweepPitchTwist,2) - i2_u = UBOUND(SrcRotMiscVarTypeData%WithoutSweepPitchTwist,2) - i3_l = LBOUND(SrcRotMiscVarTypeData%WithoutSweepPitchTwist,3) - i3_u = UBOUND(SrcRotMiscVarTypeData%WithoutSweepPitchTwist,3) - i4_l = LBOUND(SrcRotMiscVarTypeData%WithoutSweepPitchTwist,4) - i4_u = UBOUND(SrcRotMiscVarTypeData%WithoutSweepPitchTwist,4) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%WithoutSweepPitchTwist)) THEN - ALLOCATE(DstRotMiscVarTypeData%WithoutSweepPitchTwist(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 DstRotMiscVarTypeData%WithoutSweepPitchTwist.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotMiscVarTypeData%WithoutSweepPitchTwist = SrcRotMiscVarTypeData%WithoutSweepPitchTwist -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%AllOuts)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%AllOuts,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%AllOuts,1) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%AllOuts)) THEN - ALLOCATE(DstRotMiscVarTypeData%AllOuts(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%AllOuts.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotMiscVarTypeData%AllOuts = SrcRotMiscVarTypeData%AllOuts -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%W_Twr)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%W_Twr,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%W_Twr,1) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%W_Twr)) THEN - ALLOCATE(DstRotMiscVarTypeData%W_Twr(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%W_Twr.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotMiscVarTypeData%W_Twr = SrcRotMiscVarTypeData%W_Twr -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%X_Twr)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%X_Twr,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%X_Twr,1) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%X_Twr)) THEN - ALLOCATE(DstRotMiscVarTypeData%X_Twr(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%X_Twr.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRotMiscVarTypeData%X_Twr = SrcRotMiscVarTypeData%X_Twr -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%Y_Twr)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%Y_Twr,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%Y_Twr,1) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%Y_Twr)) THEN - ALLOCATE(DstRotMiscVarTypeData%Y_Twr(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%Y_Twr.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + END SUBROUTINE AD_CopyRotConstraintStateType + + SUBROUTINE AD_DestroyRotConstraintStateType( RotConstraintStateTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(RotConstraintStateType), INTENT(INOUT) :: RotConstraintStateTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotConstraintStateType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. END IF - DstRotMiscVarTypeData%Y_Twr = SrcRotMiscVarTypeData%Y_Twr -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%Curve)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%Curve,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%Curve,1) - i2_l = LBOUND(SrcRotMiscVarTypeData%Curve,2) - i2_u = UBOUND(SrcRotMiscVarTypeData%Curve,2) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%Curve)) THEN - ALLOCATE(DstRotMiscVarTypeData%Curve(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%Curve.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + + CALL BEMT_DestroyConstrState( RotConstraintStateTypeData%BEMT, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AA_DestroyConstrState( RotConstraintStateTypeData%AA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE AD_DestroyRotConstraintStateType + + SUBROUTINE AD_PackRotConstraintStateType( 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(RotConstraintStateType), 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 = 'AD_PackRotConstraintStateType' + ! 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 ! BEMT: size of buffers for each call to pack subtype + CALL BEMT_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, .TRUE. ) ! BEMT + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BEMT + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BEMT + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BEMT + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! AA: size of buffers for each call to pack subtype + CALL AA_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, .TRUE. ) ! AA + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AA + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AA + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AA + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF END IF - DstRotMiscVarTypeData%Curve = SrcRotMiscVarTypeData%Curve -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%TwrClrnc)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%TwrClrnc,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%TwrClrnc,1) - i2_l = LBOUND(SrcRotMiscVarTypeData%TwrClrnc,2) - i2_u = UBOUND(SrcRotMiscVarTypeData%TwrClrnc,2) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%TwrClrnc)) THEN - ALLOCATE(DstRotMiscVarTypeData%TwrClrnc(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%TwrClrnc.', ErrStat, ErrMsg,RoutineName) - RETURN - 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 - DstRotMiscVarTypeData%TwrClrnc = SrcRotMiscVarTypeData%TwrClrnc -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%X)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%X,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%X,1) - i2_l = LBOUND(SrcRotMiscVarTypeData%X,2) - i2_u = UBOUND(SrcRotMiscVarTypeData%X,2) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%X)) THEN - ALLOCATE(DstRotMiscVarTypeData%X(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%X.', ErrStat, ErrMsg,RoutineName) - RETURN - 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 - DstRotMiscVarTypeData%X = SrcRotMiscVarTypeData%X -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%Y)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%Y,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%Y,1) - i2_l = LBOUND(SrcRotMiscVarTypeData%Y,2) - i2_u = UBOUND(SrcRotMiscVarTypeData%Y,2) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%Y)) THEN - ALLOCATE(DstRotMiscVarTypeData%Y(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + CALL BEMT_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, OnlySize ) ! BEMT + 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 AA_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, OnlySize ) ! AA + 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_PackRotConstraintStateType + + SUBROUTINE AD_UnPackRotConstraintStateType( 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(RotConstraintStateType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackRotConstraintStateType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL BEMT_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT, ErrStat2, ErrMsg2 ) ! BEMT + 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 AA_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%AA, ErrStat2, ErrMsg2 ) ! AA + 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_UnPackRotConstraintStateType + + SUBROUTINE AD_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(AD_ConstraintStateType), INTENT(IN) :: SrcConstrStateData + TYPE(AD_ConstraintStateType), INTENT(INOUT) :: DstConstrStateData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyConstrState' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcConstrStateData%rotors)) THEN + i1_l = LBOUND(SrcConstrStateData%rotors,1) + i1_u = UBOUND(SrcConstrStateData%rotors,1) + IF (.NOT. ALLOCATED(DstConstrStateData%rotors)) THEN + ALLOCATE(DstConstrStateData%rotors(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%Y.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstConstrStateData%rotors.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstRotMiscVarTypeData%Y = SrcRotMiscVarTypeData%Y + DO i1 = LBOUND(SrcConstrStateData%rotors,1), UBOUND(SrcConstrStateData%rotors,1) + CALL AD_Copyrotconstraintstatetype( SrcConstrStateData%rotors(i1), DstConstrStateData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%M)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%M,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%M,1) - i2_l = LBOUND(SrcRotMiscVarTypeData%M,2) - i2_u = UBOUND(SrcRotMiscVarTypeData%M,2) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%M)) THEN - ALLOCATE(DstRotMiscVarTypeData%M(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%M.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + CALL FVW_CopyConstrState( SrcConstrStateData%FVW, DstConstrStateData%FVW, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE AD_CopyConstrState + + SUBROUTINE AD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(AD_ConstraintStateType), INTENT(INOUT) :: ConstrStateData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyConstrState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(ConstrStateData%rotors)) THEN +DO i1 = LBOUND(ConstrStateData%rotors,1), UBOUND(ConstrStateData%rotors,1) + CALL AD_Destroyrotconstraintstatetype( ConstrStateData%rotors(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(ConstrStateData%rotors) +ENDIF + CALL FVW_DestroyConstrState( ConstrStateData%FVW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE AD_DestroyConstrState + + SUBROUTINE AD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(AD_ConstraintStateType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackConstrState' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! rotors allocated yes/no + IF ( ALLOCATED(InData%rotors) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! rotors upper/lower bounds for each dimension + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) + Int_BufSz = Int_BufSz + 3 ! rotors: size of buffers for each call to pack subtype + CALL AD_Packrotconstraintstatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! rotors + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! rotors + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! rotors + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! FVW: size of buffers for each call to pack subtype + CALL FVW_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, .TRUE. ) ! FVW + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! FVW + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! FVW + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! FVW + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IF ( .NOT. ALLOCATED(InData%rotors) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%rotors,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%rotors,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) + CALL AD_Packrotconstraintstatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors + 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 FVW_PackConstrState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, OnlySize ) ! FVW + 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_PackConstrState + + SUBROUTINE AD_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(AD_ConstraintStateType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackConstrState' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! rotors not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%rotors)) DEALLOCATE(OutData%rotors) + ALLOCATE(OutData%rotors(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%rotors.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%rotors,1), UBOUND(OutData%rotors,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL AD_Unpackrotconstraintstatetype( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors + 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 FVW_UnpackConstrState( Re_Buf, Db_Buf, Int_Buf, OutData%FVW, ErrStat2, ErrMsg2 ) ! FVW + 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_UnPackConstrState + + SUBROUTINE AD_CopyRotOtherStateType( SrcRotOtherStateTypeData, DstRotOtherStateTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(RotOtherStateType), INTENT(IN) :: SrcRotOtherStateTypeData + TYPE(RotOtherStateType), INTENT(INOUT) :: DstRotOtherStateTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_CopyRotOtherStateType' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL BEMT_CopyOtherState( SrcRotOtherStateTypeData%BEMT, DstRotOtherStateTypeData%BEMT, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL AA_CopyOtherState( SrcRotOtherStateTypeData%AA, DstRotOtherStateTypeData%AA, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE AD_CopyRotOtherStateType + + SUBROUTINE AD_DestroyRotOtherStateType( RotOtherStateTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(RotOtherStateType), INTENT(INOUT) :: RotOtherStateTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotOtherStateType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL BEMT_DestroyOtherState( RotOtherStateTypeData%BEMT, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AA_DestroyOtherState( RotOtherStateTypeData%AA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE AD_DestroyRotOtherStateType + + SUBROUTINE AD_PackRotOtherStateType( 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(RotOtherStateType), 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 = 'AD_PackRotOtherStateType' + ! 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 ! BEMT: size of buffers for each call to pack subtype + CALL BEMT_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, .TRUE. ) ! BEMT + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BEMT + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BEMT + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BEMT + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! AA: size of buffers for each call to pack subtype + CALL AA_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, .TRUE. ) ! AA + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AA + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AA + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AA + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + CALL BEMT_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, OnlySize ) ! BEMT + 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 AA_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, OnlySize ) ! AA + 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_PackRotOtherStateType + + SUBROUTINE AD_UnPackRotOtherStateType( 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(RotOtherStateType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackRotOtherStateType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL BEMT_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT, ErrStat2, ErrMsg2 ) ! BEMT + 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 AA_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%AA, ErrStat2, ErrMsg2 ) ! AA + 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_UnPackRotOtherStateType + + SUBROUTINE AD_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(AD_OtherStateType), INTENT(IN) :: SrcOtherStateData + TYPE(AD_OtherStateType), INTENT(INOUT) :: DstOtherStateData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: 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 = 'AD_CopyOtherState' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcOtherStateData%rotors)) THEN + i1_l = LBOUND(SrcOtherStateData%rotors,1) + i1_u = UBOUND(SrcOtherStateData%rotors,1) + IF (.NOT. ALLOCATED(DstOtherStateData%rotors)) THEN + ALLOCATE(DstOtherStateData%rotors(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOtherStateData%rotors.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcOtherStateData%rotors,1), UBOUND(SrcOtherStateData%rotors,1) + CALL AD_Copyrototherstatetype( SrcOtherStateData%rotors(i1), DstOtherStateData%rotors(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL FVW_CopyOtherState( SrcOtherStateData%FVW, DstOtherStateData%FVW, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcOtherStateData%WakeLocationPoints)) THEN + i1_l = LBOUND(SrcOtherStateData%WakeLocationPoints,1) + i1_u = UBOUND(SrcOtherStateData%WakeLocationPoints,1) + i2_l = LBOUND(SrcOtherStateData%WakeLocationPoints,2) + i2_u = UBOUND(SrcOtherStateData%WakeLocationPoints,2) + IF (.NOT. ALLOCATED(DstOtherStateData%WakeLocationPoints)) THEN + ALLOCATE(DstOtherStateData%WakeLocationPoints(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOtherStateData%WakeLocationPoints.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOtherStateData%WakeLocationPoints = SrcOtherStateData%WakeLocationPoints +ENDIF + END SUBROUTINE AD_CopyOtherState + + SUBROUTINE AD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(AD_OtherStateType), INTENT(INOUT) :: OtherStateData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyOtherState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(OtherStateData%rotors)) THEN +DO i1 = LBOUND(OtherStateData%rotors,1), UBOUND(OtherStateData%rotors,1) + CALL AD_Destroyrototherstatetype( OtherStateData%rotors(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(OtherStateData%rotors) +ENDIF + CALL FVW_DestroyOtherState( OtherStateData%FVW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(OtherStateData%WakeLocationPoints)) THEN + DEALLOCATE(OtherStateData%WakeLocationPoints) +ENDIF + END SUBROUTINE AD_DestroyOtherState + + SUBROUTINE AD_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(AD_OtherStateType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_PackOtherState' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! rotors allocated yes/no + IF ( ALLOCATED(InData%rotors) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! rotors upper/lower bounds for each dimension + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) + Int_BufSz = Int_BufSz + 3 ! rotors: size of buffers for each call to pack subtype + CALL AD_Packrototherstatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, .TRUE. ) ! rotors + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! rotors + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! rotors + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! rotors + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! FVW: size of buffers for each call to pack subtype + CALL FVW_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, .TRUE. ) ! FVW + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! FVW + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! FVW + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! FVW + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! WakeLocationPoints allocated yes/no + IF ( ALLOCATED(InData%WakeLocationPoints) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! WakeLocationPoints upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WakeLocationPoints) ! WakeLocationPoints + 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%rotors) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%rotors,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%rotors,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%rotors,1), UBOUND(InData%rotors,1) + CALL AD_Packrototherstatetype( Re_Buf, Db_Buf, Int_Buf, InData%rotors(i1), ErrStat2, ErrMsg2, OnlySize ) ! rotors + 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 FVW_PackOtherState( Re_Buf, Db_Buf, Int_Buf, InData%FVW, ErrStat2, ErrMsg2, OnlySize ) ! FVW + 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%WakeLocationPoints) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WakeLocationPoints,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WakeLocationPoints,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WakeLocationPoints,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WakeLocationPoints,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%WakeLocationPoints,2), UBOUND(InData%WakeLocationPoints,2) + DO i1 = LBOUND(InData%WakeLocationPoints,1), UBOUND(InData%WakeLocationPoints,1) + ReKiBuf(Re_Xferred) = InData%WakeLocationPoints(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + END SUBROUTINE AD_PackOtherState + + SUBROUTINE AD_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(AD_OtherStateType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: 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 = 'AD_UnPackOtherState' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! rotors not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%rotors)) DEALLOCATE(OutData%rotors) + ALLOCATE(OutData%rotors(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%rotors.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%rotors,1), UBOUND(OutData%rotors,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL AD_Unpackrototherstatetype( Re_Buf, Db_Buf, Int_Buf, OutData%rotors(i1), ErrStat2, ErrMsg2 ) ! rotors + 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 FVW_UnpackOtherState( Re_Buf, Db_Buf, Int_Buf, OutData%FVW, ErrStat2, ErrMsg2 ) ! FVW + 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 ! WakeLocationPoints not allocated + Int_Xferred = Int_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%WakeLocationPoints)) DEALLOCATE(OutData%WakeLocationPoints) + ALLOCATE(OutData%WakeLocationPoints(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WakeLocationPoints.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%WakeLocationPoints,2), UBOUND(OutData%WakeLocationPoints,2) + DO i1 = LBOUND(OutData%WakeLocationPoints,1), UBOUND(OutData%WakeLocationPoints,1) + OutData%WakeLocationPoints(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + END SUBROUTINE AD_UnPackOtherState + + SUBROUTINE AD_CopyRotMiscVarType( SrcRotMiscVarTypeData, DstRotMiscVarTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(RotMiscVarType), INTENT(INOUT) :: SrcRotMiscVarTypeData + TYPE(RotMiscVarType), INTENT(INOUT) :: DstRotMiscVarTypeData + 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 = 'AD_CopyRotMiscVarType' +! + ErrStat = ErrID_None + ErrMsg = "" + CALL BEMT_CopyMisc( SrcRotMiscVarTypeData%BEMT, DstRotMiscVarTypeData%BEMT, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL BEMT_CopyOutput( SrcRotMiscVarTypeData%BEMT_y, DstRotMiscVarTypeData%BEMT_y, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DO i1 = LBOUND(SrcRotMiscVarTypeData%BEMT_u,1), UBOUND(SrcRotMiscVarTypeData%BEMT_u,1) + CALL BEMT_CopyInput( SrcRotMiscVarTypeData%BEMT_u(i1), DstRotMiscVarTypeData%BEMT_u(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO + CALL AA_CopyMisc( SrcRotMiscVarTypeData%AA, DstRotMiscVarTypeData%AA, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL AA_CopyOutput( SrcRotMiscVarTypeData%AA_y, DstRotMiscVarTypeData%AA_y, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL AA_CopyInput( SrcRotMiscVarTypeData%AA_u, DstRotMiscVarTypeData%AA_u, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcRotMiscVarTypeData%DisturbedInflow)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%DisturbedInflow,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%DisturbedInflow,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%DisturbedInflow,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%DisturbedInflow,2) + i3_l = LBOUND(SrcRotMiscVarTypeData%DisturbedInflow,3) + i3_u = UBOUND(SrcRotMiscVarTypeData%DisturbedInflow,3) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%DisturbedInflow)) THEN + ALLOCATE(DstRotMiscVarTypeData%DisturbedInflow(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%DisturbedInflow.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%DisturbedInflow = SrcRotMiscVarTypeData%DisturbedInflow +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%orientationAnnulus)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%orientationAnnulus,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%orientationAnnulus,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%orientationAnnulus,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%orientationAnnulus,2) + i3_l = LBOUND(SrcRotMiscVarTypeData%orientationAnnulus,3) + i3_u = UBOUND(SrcRotMiscVarTypeData%orientationAnnulus,3) + i4_l = LBOUND(SrcRotMiscVarTypeData%orientationAnnulus,4) + i4_u = UBOUND(SrcRotMiscVarTypeData%orientationAnnulus,4) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%orientationAnnulus)) THEN + ALLOCATE(DstRotMiscVarTypeData%orientationAnnulus(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 DstRotMiscVarTypeData%orientationAnnulus.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%orientationAnnulus = SrcRotMiscVarTypeData%orientationAnnulus +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%AllOuts)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%AllOuts,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%AllOuts,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%AllOuts)) THEN + ALLOCATE(DstRotMiscVarTypeData%AllOuts(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%AllOuts.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%AllOuts = SrcRotMiscVarTypeData%AllOuts +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%W_Twr)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%W_Twr,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%W_Twr,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%W_Twr)) THEN + ALLOCATE(DstRotMiscVarTypeData%W_Twr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%W_Twr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%W_Twr = SrcRotMiscVarTypeData%W_Twr +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%X_Twr)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%X_Twr,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%X_Twr,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%X_Twr)) THEN + ALLOCATE(DstRotMiscVarTypeData%X_Twr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%X_Twr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%X_Twr = SrcRotMiscVarTypeData%X_Twr +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%Y_Twr)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%Y_Twr,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%Y_Twr,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%Y_Twr)) THEN + ALLOCATE(DstRotMiscVarTypeData%Y_Twr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%Y_Twr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%Y_Twr = SrcRotMiscVarTypeData%Y_Twr +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%Curve)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%Curve,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%Curve,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%Curve,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%Curve,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%Curve)) THEN + ALLOCATE(DstRotMiscVarTypeData%Curve(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%Curve.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%Curve = SrcRotMiscVarTypeData%Curve +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%TwrClrnc)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%TwrClrnc,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%TwrClrnc,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%TwrClrnc,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%TwrClrnc,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%TwrClrnc)) THEN + ALLOCATE(DstRotMiscVarTypeData%TwrClrnc(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%TwrClrnc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%TwrClrnc = SrcRotMiscVarTypeData%TwrClrnc +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%X)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%X,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%X,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%X,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%X,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%X)) THEN + ALLOCATE(DstRotMiscVarTypeData%X(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%X.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%X = SrcRotMiscVarTypeData%X +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%Y)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%Y,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%Y,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%Y,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%Y,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%Y)) THEN + ALLOCATE(DstRotMiscVarTypeData%Y(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%Y.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%Y = SrcRotMiscVarTypeData%Y +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%Z)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%Z,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%Z,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%Z,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%Z,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%Z)) THEN + ALLOCATE(DstRotMiscVarTypeData%Z(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%Z.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%Z = SrcRotMiscVarTypeData%Z +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%M)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%M,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%M,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%M,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%M,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%M)) THEN + ALLOCATE(DstRotMiscVarTypeData%M(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%M.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%M = SrcRotMiscVarTypeData%M +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%Mx)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%Mx,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%Mx,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%Mx,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%Mx,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%Mx)) THEN + ALLOCATE(DstRotMiscVarTypeData%Mx(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%Mx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%Mx = SrcRotMiscVarTypeData%Mx +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%My)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%My,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%My,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%My,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%My,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%My)) THEN + ALLOCATE(DstRotMiscVarTypeData%My(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%My.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%My = SrcRotMiscVarTypeData%My +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%Mz)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%Mz,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%Mz,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%Mz,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%Mz,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%Mz)) THEN + ALLOCATE(DstRotMiscVarTypeData%Mz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%Mz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%Mz = SrcRotMiscVarTypeData%Mz +ENDIF + DstRotMiscVarTypeData%V_DiskAvg = SrcRotMiscVarTypeData%V_DiskAvg + DstRotMiscVarTypeData%yaw = SrcRotMiscVarTypeData%yaw + DstRotMiscVarTypeData%tilt = SrcRotMiscVarTypeData%tilt +IF (ALLOCATED(SrcRotMiscVarTypeData%hub_theta_x_root)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%hub_theta_x_root,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%hub_theta_x_root,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%hub_theta_x_root)) THEN + ALLOCATE(DstRotMiscVarTypeData%hub_theta_x_root(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%hub_theta_x_root.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%hub_theta_x_root = SrcRotMiscVarTypeData%hub_theta_x_root +ENDIF + DstRotMiscVarTypeData%V_dot_x = SrcRotMiscVarTypeData%V_dot_x + CALL MeshCopy( SrcRotMiscVarTypeData%HubLoad, DstRotMiscVarTypeData%HubLoad, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcRotMiscVarTypeData%B_L_2_H_P)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%B_L_2_H_P,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%B_L_2_H_P,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%B_L_2_H_P)) THEN + ALLOCATE(DstRotMiscVarTypeData%B_L_2_H_P(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%B_L_2_H_P.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcRotMiscVarTypeData%B_L_2_H_P,1), UBOUND(SrcRotMiscVarTypeData%B_L_2_H_P,1) + CALL NWTC_Library_Copymeshmaptype( SrcRotMiscVarTypeData%B_L_2_H_P(i1), DstRotMiscVarTypeData%B_L_2_H_P(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%SigmaCavitCrit)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%SigmaCavitCrit,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%SigmaCavitCrit,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%SigmaCavitCrit,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%SigmaCavitCrit,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%SigmaCavitCrit)) THEN + ALLOCATE(DstRotMiscVarTypeData%SigmaCavitCrit(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%SigmaCavitCrit.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%SigmaCavitCrit = SrcRotMiscVarTypeData%SigmaCavitCrit +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%SigmaCavit)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%SigmaCavit,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%SigmaCavit,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%SigmaCavit,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%SigmaCavit,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%SigmaCavit)) THEN + ALLOCATE(DstRotMiscVarTypeData%SigmaCavit(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%SigmaCavit.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%SigmaCavit = SrcRotMiscVarTypeData%SigmaCavit +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%CavitWarnSet)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%CavitWarnSet,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%CavitWarnSet,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%CavitWarnSet,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%CavitWarnSet,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%CavitWarnSet)) THEN + ALLOCATE(DstRotMiscVarTypeData%CavitWarnSet(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%CavitWarnSet.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%CavitWarnSet = SrcRotMiscVarTypeData%CavitWarnSet +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%BlFB)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%BlFB,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%BlFB,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%BlFB,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%BlFB,2) + i3_l = LBOUND(SrcRotMiscVarTypeData%BlFB,3) + i3_u = UBOUND(SrcRotMiscVarTypeData%BlFB,3) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%BlFB)) THEN + ALLOCATE(DstRotMiscVarTypeData%BlFB(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%BlFB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%BlFB = SrcRotMiscVarTypeData%BlFB +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%BlMB)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%BlMB,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%BlMB,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%BlMB,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%BlMB,2) + i3_l = LBOUND(SrcRotMiscVarTypeData%BlMB,3) + i3_u = UBOUND(SrcRotMiscVarTypeData%BlMB,3) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%BlMB)) THEN + ALLOCATE(DstRotMiscVarTypeData%BlMB(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%BlMB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%BlMB = SrcRotMiscVarTypeData%BlMB +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%TwrFB)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%TwrFB,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%TwrFB,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%TwrFB,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%TwrFB,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%TwrFB)) THEN + ALLOCATE(DstRotMiscVarTypeData%TwrFB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%TwrFB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%TwrFB = SrcRotMiscVarTypeData%TwrFB +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%TwrMB)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%TwrMB,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%TwrMB,1) + i2_l = LBOUND(SrcRotMiscVarTypeData%TwrMB,2) + i2_u = UBOUND(SrcRotMiscVarTypeData%TwrMB,2) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%TwrMB)) THEN + ALLOCATE(DstRotMiscVarTypeData%TwrMB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%TwrMB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%TwrMB = SrcRotMiscVarTypeData%TwrMB +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%HubFB)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%HubFB,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%HubFB,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%HubFB)) THEN + ALLOCATE(DstRotMiscVarTypeData%HubFB(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%HubFB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%HubFB = SrcRotMiscVarTypeData%HubFB +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%HubMB)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%HubMB,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%HubMB,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%HubMB)) THEN + ALLOCATE(DstRotMiscVarTypeData%HubMB(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%HubMB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%HubMB = SrcRotMiscVarTypeData%HubMB +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%NacFB)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%NacFB,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%NacFB,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%NacFB)) THEN + ALLOCATE(DstRotMiscVarTypeData%NacFB(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%NacFB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%NacFB = SrcRotMiscVarTypeData%NacFB +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%NacMB)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%NacMB,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%NacMB,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%NacMB)) THEN + ALLOCATE(DstRotMiscVarTypeData%NacMB(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%NacMB.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotMiscVarTypeData%NacMB = SrcRotMiscVarTypeData%NacMB +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%BladeRootLoad)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%BladeRootLoad,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%BladeRootLoad,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%BladeRootLoad)) THEN + ALLOCATE(DstRotMiscVarTypeData%BladeRootLoad(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%BladeRootLoad.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcRotMiscVarTypeData%BladeRootLoad,1), UBOUND(SrcRotMiscVarTypeData%BladeRootLoad,1) + CALL MeshCopy( SrcRotMiscVarTypeData%BladeRootLoad(i1), DstRotMiscVarTypeData%BladeRootLoad(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%B_L_2_R_P)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%B_L_2_R_P,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%B_L_2_R_P,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%B_L_2_R_P)) THEN + ALLOCATE(DstRotMiscVarTypeData%B_L_2_R_P(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%B_L_2_R_P.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcRotMiscVarTypeData%B_L_2_R_P,1), UBOUND(SrcRotMiscVarTypeData%B_L_2_R_P,1) + CALL NWTC_Library_Copymeshmaptype( SrcRotMiscVarTypeData%B_L_2_R_P(i1), DstRotMiscVarTypeData%B_L_2_R_P(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%BladeBuoyLoadPoint)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%BladeBuoyLoadPoint,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%BladeBuoyLoadPoint,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%BladeBuoyLoadPoint)) THEN + ALLOCATE(DstRotMiscVarTypeData%BladeBuoyLoadPoint(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%BladeBuoyLoadPoint.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcRotMiscVarTypeData%BladeBuoyLoadPoint,1), UBOUND(SrcRotMiscVarTypeData%BladeBuoyLoadPoint,1) + CALL MeshCopy( SrcRotMiscVarTypeData%BladeBuoyLoadPoint(i1), DstRotMiscVarTypeData%BladeBuoyLoadPoint(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%BladeBuoyLoad)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%BladeBuoyLoad,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%BladeBuoyLoad,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%BladeBuoyLoad)) THEN + ALLOCATE(DstRotMiscVarTypeData%BladeBuoyLoad(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%BladeBuoyLoad.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcRotMiscVarTypeData%BladeBuoyLoad,1), UBOUND(SrcRotMiscVarTypeData%BladeBuoyLoad,1) + CALL MeshCopy( SrcRotMiscVarTypeData%BladeBuoyLoad(i1), DstRotMiscVarTypeData%BladeBuoyLoad(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcRotMiscVarTypeData%B_P_2_B_L)) THEN + i1_l = LBOUND(SrcRotMiscVarTypeData%B_P_2_B_L,1) + i1_u = UBOUND(SrcRotMiscVarTypeData%B_P_2_B_L,1) + IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%B_P_2_B_L)) THEN + ALLOCATE(DstRotMiscVarTypeData%B_P_2_B_L(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%B_P_2_B_L.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcRotMiscVarTypeData%B_P_2_B_L,1), UBOUND(SrcRotMiscVarTypeData%B_P_2_B_L,1) + CALL NWTC_Library_Copymeshmaptype( SrcRotMiscVarTypeData%B_P_2_B_L(i1), DstRotMiscVarTypeData%B_P_2_B_L(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL MeshCopy( SrcRotMiscVarTypeData%TwrBuoyLoadPoint, DstRotMiscVarTypeData%TwrBuoyLoadPoint, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcRotMiscVarTypeData%TwrBuoyLoad, DstRotMiscVarTypeData%TwrBuoyLoad, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL NWTC_Library_Copymeshmaptype( SrcRotMiscVarTypeData%T_P_2_T_L, DstRotMiscVarTypeData%T_P_2_T_L, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstRotMiscVarTypeData%FirstWarn_TowerStrike = SrcRotMiscVarTypeData%FirstWarn_TowerStrike + DstRotMiscVarTypeData%AvgDiskVel = SrcRotMiscVarTypeData%AvgDiskVel + DstRotMiscVarTypeData%AvgDiskVelDist = SrcRotMiscVarTypeData%AvgDiskVelDist + DstRotMiscVarTypeData%TFinAlpha = SrcRotMiscVarTypeData%TFinAlpha + DstRotMiscVarTypeData%TFinRe = SrcRotMiscVarTypeData%TFinRe + DstRotMiscVarTypeData%TFinVrel = SrcRotMiscVarTypeData%TFinVrel + DstRotMiscVarTypeData%TFinVund_i = SrcRotMiscVarTypeData%TFinVund_i + DstRotMiscVarTypeData%TFinVind_i = SrcRotMiscVarTypeData%TFinVind_i + DstRotMiscVarTypeData%TFinVrel_i = SrcRotMiscVarTypeData%TFinVrel_i + DstRotMiscVarTypeData%TFinSTV_i = SrcRotMiscVarTypeData%TFinSTV_i + DstRotMiscVarTypeData%TFinF_i = SrcRotMiscVarTypeData%TFinF_i + DstRotMiscVarTypeData%TFinM_i = SrcRotMiscVarTypeData%TFinM_i + END SUBROUTINE AD_CopyRotMiscVarType + + SUBROUTINE AD_DestroyRotMiscVarType( RotMiscVarTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(RotMiscVarType), INTENT(INOUT) :: RotMiscVarTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotMiscVarType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL BEMT_DestroyMisc( RotMiscVarTypeData%BEMT, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL BEMT_DestroyOutput( RotMiscVarTypeData%BEMT_y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +DO i1 = LBOUND(RotMiscVarTypeData%BEMT_u,1), UBOUND(RotMiscVarTypeData%BEMT_u,1) + CALL BEMT_DestroyInput( RotMiscVarTypeData%BEMT_u(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + CALL AA_DestroyMisc( RotMiscVarTypeData%AA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AA_DestroyOutput( RotMiscVarTypeData%AA_y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AA_DestroyInput( RotMiscVarTypeData%AA_u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(RotMiscVarTypeData%DisturbedInflow)) THEN + DEALLOCATE(RotMiscVarTypeData%DisturbedInflow) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%orientationAnnulus)) THEN + DEALLOCATE(RotMiscVarTypeData%orientationAnnulus) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%AllOuts)) THEN + DEALLOCATE(RotMiscVarTypeData%AllOuts) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%W_Twr)) THEN + DEALLOCATE(RotMiscVarTypeData%W_Twr) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%X_Twr)) THEN + DEALLOCATE(RotMiscVarTypeData%X_Twr) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%Y_Twr)) THEN + DEALLOCATE(RotMiscVarTypeData%Y_Twr) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%Curve)) THEN + DEALLOCATE(RotMiscVarTypeData%Curve) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%TwrClrnc)) THEN + DEALLOCATE(RotMiscVarTypeData%TwrClrnc) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%X)) THEN + DEALLOCATE(RotMiscVarTypeData%X) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%Y)) THEN + DEALLOCATE(RotMiscVarTypeData%Y) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%Z)) THEN + DEALLOCATE(RotMiscVarTypeData%Z) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%M)) THEN + DEALLOCATE(RotMiscVarTypeData%M) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%Mx)) THEN + DEALLOCATE(RotMiscVarTypeData%Mx) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%My)) THEN + DEALLOCATE(RotMiscVarTypeData%My) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%Mz)) THEN + DEALLOCATE(RotMiscVarTypeData%Mz) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%hub_theta_x_root)) THEN + DEALLOCATE(RotMiscVarTypeData%hub_theta_x_root) +ENDIF + CALL MeshDestroy( RotMiscVarTypeData%HubLoad, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(RotMiscVarTypeData%B_L_2_H_P)) THEN +DO i1 = LBOUND(RotMiscVarTypeData%B_L_2_H_P,1), UBOUND(RotMiscVarTypeData%B_L_2_H_P,1) + CALL NWTC_Library_Destroymeshmaptype( RotMiscVarTypeData%B_L_2_H_P(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(RotMiscVarTypeData%B_L_2_H_P) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%SigmaCavitCrit)) THEN + DEALLOCATE(RotMiscVarTypeData%SigmaCavitCrit) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%SigmaCavit)) THEN + DEALLOCATE(RotMiscVarTypeData%SigmaCavit) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%CavitWarnSet)) THEN + DEALLOCATE(RotMiscVarTypeData%CavitWarnSet) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%BlFB)) THEN + DEALLOCATE(RotMiscVarTypeData%BlFB) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%BlMB)) THEN + DEALLOCATE(RotMiscVarTypeData%BlMB) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%TwrFB)) THEN + DEALLOCATE(RotMiscVarTypeData%TwrFB) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%TwrMB)) THEN + DEALLOCATE(RotMiscVarTypeData%TwrMB) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%HubFB)) THEN + DEALLOCATE(RotMiscVarTypeData%HubFB) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%HubMB)) THEN + DEALLOCATE(RotMiscVarTypeData%HubMB) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%NacFB)) THEN + DEALLOCATE(RotMiscVarTypeData%NacFB) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%NacMB)) THEN + DEALLOCATE(RotMiscVarTypeData%NacMB) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%BladeRootLoad)) THEN +DO i1 = LBOUND(RotMiscVarTypeData%BladeRootLoad,1), UBOUND(RotMiscVarTypeData%BladeRootLoad,1) + CALL MeshDestroy( RotMiscVarTypeData%BladeRootLoad(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(RotMiscVarTypeData%BladeRootLoad) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%B_L_2_R_P)) THEN +DO i1 = LBOUND(RotMiscVarTypeData%B_L_2_R_P,1), UBOUND(RotMiscVarTypeData%B_L_2_R_P,1) + CALL NWTC_Library_Destroymeshmaptype( RotMiscVarTypeData%B_L_2_R_P(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(RotMiscVarTypeData%B_L_2_R_P) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%BladeBuoyLoadPoint)) THEN +DO i1 = LBOUND(RotMiscVarTypeData%BladeBuoyLoadPoint,1), UBOUND(RotMiscVarTypeData%BladeBuoyLoadPoint,1) + CALL MeshDestroy( RotMiscVarTypeData%BladeBuoyLoadPoint(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(RotMiscVarTypeData%BladeBuoyLoadPoint) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%BladeBuoyLoad)) THEN +DO i1 = LBOUND(RotMiscVarTypeData%BladeBuoyLoad,1), UBOUND(RotMiscVarTypeData%BladeBuoyLoad,1) + CALL MeshDestroy( RotMiscVarTypeData%BladeBuoyLoad(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(RotMiscVarTypeData%BladeBuoyLoad) +ENDIF +IF (ALLOCATED(RotMiscVarTypeData%B_P_2_B_L)) THEN +DO i1 = LBOUND(RotMiscVarTypeData%B_P_2_B_L,1), UBOUND(RotMiscVarTypeData%B_P_2_B_L,1) + CALL NWTC_Library_Destroymeshmaptype( RotMiscVarTypeData%B_P_2_B_L(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(RotMiscVarTypeData%B_P_2_B_L) +ENDIF + CALL MeshDestroy( RotMiscVarTypeData%TwrBuoyLoadPoint, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( RotMiscVarTypeData%TwrBuoyLoad, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( RotMiscVarTypeData%T_P_2_T_L, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE AD_DestroyRotMiscVarType + + SUBROUTINE AD_PackRotMiscVarType( 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(RotMiscVarType), 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 = 'AD_PackRotMiscVarType' + ! 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 ! BEMT: size of buffers for each call to pack subtype + CALL BEMT_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, .TRUE. ) ! BEMT + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BEMT + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BEMT + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BEMT + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! BEMT_y: size of buffers for each call to pack subtype + CALL BEMT_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%BEMT_y, ErrStat2, ErrMsg2, .TRUE. ) ! BEMT_y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BEMT_y + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BEMT_y + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BEMT_y + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + DO i1 = LBOUND(InData%BEMT_u,1), UBOUND(InData%BEMT_u,1) + Int_BufSz = Int_BufSz + 3 ! BEMT_u: size of buffers for each call to pack subtype + CALL BEMT_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%BEMT_u(i1), ErrStat2, ErrMsg2, .TRUE. ) ! BEMT_u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BEMT_u + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BEMT_u + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BEMT_u + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + Int_BufSz = Int_BufSz + 3 ! AA: size of buffers for each call to pack subtype + CALL AA_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, .TRUE. ) ! AA + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AA + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AA + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AA + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! AA_y: size of buffers for each call to pack subtype + CALL AA_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%AA_y, ErrStat2, ErrMsg2, .TRUE. ) ! AA_y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AA_y + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AA_y + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AA_y + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! AA_u: size of buffers for each call to pack subtype + CALL AA_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%AA_u, ErrStat2, ErrMsg2, .TRUE. ) ! AA_u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AA_u + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AA_u + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AA_u + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! DisturbedInflow allocated yes/no + IF ( ALLOCATED(InData%DisturbedInflow) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! DisturbedInflow upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%DisturbedInflow) ! DisturbedInflow + END IF + Int_BufSz = Int_BufSz + 1 ! orientationAnnulus allocated yes/no + IF ( ALLOCATED(InData%orientationAnnulus) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! orientationAnnulus upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%orientationAnnulus) ! orientationAnnulus + END IF + Int_BufSz = Int_BufSz + 1 ! AllOuts allocated yes/no + IF ( ALLOCATED(InData%AllOuts) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AllOuts upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AllOuts) ! AllOuts + END IF + Int_BufSz = Int_BufSz + 1 ! W_Twr allocated yes/no + IF ( ALLOCATED(InData%W_Twr) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! W_Twr upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%W_Twr) ! W_Twr + END IF + Int_BufSz = Int_BufSz + 1 ! X_Twr allocated yes/no + IF ( ALLOCATED(InData%X_Twr) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! X_Twr upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%X_Twr) ! X_Twr + END IF + Int_BufSz = Int_BufSz + 1 ! Y_Twr allocated yes/no + IF ( ALLOCATED(InData%Y_Twr) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Y_Twr upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Y_Twr) ! Y_Twr + END IF + Int_BufSz = Int_BufSz + 1 ! Curve allocated yes/no + IF ( ALLOCATED(InData%Curve) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Curve upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Curve) ! Curve + END IF + Int_BufSz = Int_BufSz + 1 ! TwrClrnc allocated yes/no + IF ( ALLOCATED(InData%TwrClrnc) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! TwrClrnc upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrClrnc) ! TwrClrnc + END IF + Int_BufSz = Int_BufSz + 1 ! X allocated yes/no + IF ( ALLOCATED(InData%X) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! X upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%X) ! X + END IF + Int_BufSz = Int_BufSz + 1 ! Y allocated yes/no + IF ( ALLOCATED(InData%Y) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Y upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Y) ! Y + END IF + Int_BufSz = Int_BufSz + 1 ! Z allocated yes/no + IF ( ALLOCATED(InData%Z) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Z upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Z) ! Z + 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 ! Mx allocated yes/no + IF ( ALLOCATED(InData%Mx) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Mx upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Mx) ! Mx + END IF + Int_BufSz = Int_BufSz + 1 ! My allocated yes/no + IF ( ALLOCATED(InData%My) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! My upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%My) ! My + END IF + Int_BufSz = Int_BufSz + 1 ! Mz allocated yes/no + IF ( ALLOCATED(InData%Mz) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Mz upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Mz) ! Mz + END IF + Re_BufSz = Re_BufSz + SIZE(InData%V_DiskAvg) ! V_DiskAvg + Re_BufSz = Re_BufSz + 1 ! yaw + Re_BufSz = Re_BufSz + 1 ! tilt + Int_BufSz = Int_BufSz + 1 ! hub_theta_x_root allocated yes/no + IF ( ALLOCATED(InData%hub_theta_x_root) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! hub_theta_x_root upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%hub_theta_x_root) ! hub_theta_x_root + END IF + Re_BufSz = Re_BufSz + 1 ! V_dot_x + Int_BufSz = Int_BufSz + 3 ! HubLoad: size of buffers for each call to pack subtype + CALL MeshPack( InData%HubLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! HubLoad + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! HubLoad + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! HubLoad + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! HubLoad + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! B_L_2_H_P allocated yes/no + IF ( ALLOCATED(InData%B_L_2_H_P) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! B_L_2_H_P upper/lower bounds for each dimension + DO i1 = LBOUND(InData%B_L_2_H_P,1), UBOUND(InData%B_L_2_H_P,1) + Int_BufSz = Int_BufSz + 3 ! B_L_2_H_P: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%B_L_2_H_P(i1), ErrStat2, ErrMsg2, .TRUE. ) ! B_L_2_H_P + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! B_L_2_H_P + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! B_L_2_H_P + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! B_L_2_H_P + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! SigmaCavitCrit allocated yes/no + IF ( ALLOCATED(InData%SigmaCavitCrit) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! SigmaCavitCrit upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%SigmaCavitCrit) ! SigmaCavitCrit + END IF + Int_BufSz = Int_BufSz + 1 ! SigmaCavit allocated yes/no + IF ( ALLOCATED(InData%SigmaCavit) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! SigmaCavit upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%SigmaCavit) ! SigmaCavit + END IF + Int_BufSz = Int_BufSz + 1 ! CavitWarnSet allocated yes/no + IF ( ALLOCATED(InData%CavitWarnSet) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! CavitWarnSet upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%CavitWarnSet) ! CavitWarnSet + END IF + Int_BufSz = Int_BufSz + 1 ! BlFB allocated yes/no + IF ( ALLOCATED(InData%BlFB) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! BlFB upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlFB) ! BlFB + END IF + Int_BufSz = Int_BufSz + 1 ! BlMB allocated yes/no + IF ( ALLOCATED(InData%BlMB) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! BlMB upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlMB) ! BlMB + END IF + Int_BufSz = Int_BufSz + 1 ! TwrFB allocated yes/no + IF ( ALLOCATED(InData%TwrFB) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! TwrFB upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrFB) ! TwrFB + END IF + Int_BufSz = Int_BufSz + 1 ! TwrMB allocated yes/no + IF ( ALLOCATED(InData%TwrMB) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! TwrMB upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrMB) ! TwrMB + END IF + Int_BufSz = Int_BufSz + 1 ! HubFB allocated yes/no + IF ( ALLOCATED(InData%HubFB) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! HubFB upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%HubFB) ! HubFB + END IF + Int_BufSz = Int_BufSz + 1 ! HubMB allocated yes/no + IF ( ALLOCATED(InData%HubMB) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! HubMB upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%HubMB) ! HubMB + END IF + Int_BufSz = Int_BufSz + 1 ! NacFB allocated yes/no + IF ( ALLOCATED(InData%NacFB) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! NacFB upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%NacFB) ! NacFB + END IF + Int_BufSz = Int_BufSz + 1 ! NacMB allocated yes/no + IF ( ALLOCATED(InData%NacMB) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! NacMB upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%NacMB) ! NacMB + END IF + Int_BufSz = Int_BufSz + 1 ! BladeRootLoad allocated yes/no + IF ( ALLOCATED(InData%BladeRootLoad) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BladeRootLoad upper/lower bounds for each dimension + DO i1 = LBOUND(InData%BladeRootLoad,1), UBOUND(InData%BladeRootLoad,1) + Int_BufSz = Int_BufSz + 3 ! BladeRootLoad: size of buffers for each call to pack subtype + CALL MeshPack( InData%BladeRootLoad(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! BladeRootLoad + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BladeRootLoad + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BladeRootLoad + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BladeRootLoad + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! B_L_2_R_P allocated yes/no + IF ( ALLOCATED(InData%B_L_2_R_P) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! B_L_2_R_P upper/lower bounds for each dimension + DO i1 = LBOUND(InData%B_L_2_R_P,1), UBOUND(InData%B_L_2_R_P,1) + Int_BufSz = Int_BufSz + 3 ! B_L_2_R_P: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%B_L_2_R_P(i1), ErrStat2, ErrMsg2, .TRUE. ) ! B_L_2_R_P + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! B_L_2_R_P + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! B_L_2_R_P + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! B_L_2_R_P + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! BladeBuoyLoadPoint allocated yes/no + IF ( ALLOCATED(InData%BladeBuoyLoadPoint) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BladeBuoyLoadPoint upper/lower bounds for each dimension + DO i1 = LBOUND(InData%BladeBuoyLoadPoint,1), UBOUND(InData%BladeBuoyLoadPoint,1) + Int_BufSz = Int_BufSz + 3 ! BladeBuoyLoadPoint: size of buffers for each call to pack subtype + CALL MeshPack( InData%BladeBuoyLoadPoint(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! BladeBuoyLoadPoint + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BladeBuoyLoadPoint + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BladeBuoyLoadPoint + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BladeBuoyLoadPoint + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! BladeBuoyLoad allocated yes/no + IF ( ALLOCATED(InData%BladeBuoyLoad) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BladeBuoyLoad upper/lower bounds for each dimension + DO i1 = LBOUND(InData%BladeBuoyLoad,1), UBOUND(InData%BladeBuoyLoad,1) + Int_BufSz = Int_BufSz + 3 ! BladeBuoyLoad: size of buffers for each call to pack subtype + CALL MeshPack( InData%BladeBuoyLoad(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! BladeBuoyLoad + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BladeBuoyLoad + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BladeBuoyLoad + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BladeBuoyLoad + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! B_P_2_B_L allocated yes/no + IF ( ALLOCATED(InData%B_P_2_B_L) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! B_P_2_B_L upper/lower bounds for each dimension + DO i1 = LBOUND(InData%B_P_2_B_L,1), UBOUND(InData%B_P_2_B_L,1) + Int_BufSz = Int_BufSz + 3 ! B_P_2_B_L: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%B_P_2_B_L(i1), ErrStat2, ErrMsg2, .TRUE. ) ! B_P_2_B_L + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! B_P_2_B_L + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! B_P_2_B_L + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! B_P_2_B_L + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! TwrBuoyLoadPoint: size of buffers for each call to pack subtype + CALL MeshPack( InData%TwrBuoyLoadPoint, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! TwrBuoyLoadPoint + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! TwrBuoyLoadPoint + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! TwrBuoyLoadPoint + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! TwrBuoyLoadPoint + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! TwrBuoyLoad: size of buffers for each call to pack subtype + CALL MeshPack( InData%TwrBuoyLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! TwrBuoyLoad + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! TwrBuoyLoad + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! TwrBuoyLoad + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! TwrBuoyLoad + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! T_P_2_T_L: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%T_P_2_T_L, ErrStat2, ErrMsg2, .TRUE. ) ! T_P_2_T_L + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! T_P_2_T_L + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! T_P_2_T_L + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! T_P_2_T_L + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! FirstWarn_TowerStrike + Re_BufSz = Re_BufSz + SIZE(InData%AvgDiskVel) ! AvgDiskVel + Re_BufSz = Re_BufSz + SIZE(InData%AvgDiskVelDist) ! AvgDiskVelDist + Re_BufSz = Re_BufSz + 1 ! TFinAlpha + Re_BufSz = Re_BufSz + 1 ! TFinRe + Re_BufSz = Re_BufSz + 1 ! TFinVrel + Re_BufSz = Re_BufSz + SIZE(InData%TFinVund_i) ! TFinVund_i + Re_BufSz = Re_BufSz + SIZE(InData%TFinVind_i) ! TFinVind_i + Re_BufSz = Re_BufSz + SIZE(InData%TFinVrel_i) ! TFinVrel_i + Re_BufSz = Re_BufSz + SIZE(InData%TFinSTV_i) ! TFinSTV_i + Re_BufSz = Re_BufSz + SIZE(InData%TFinF_i) ! TFinF_i + Re_BufSz = Re_BufSz + SIZE(InData%TFinM_i) ! TFinM_i + 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 BEMT_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, OnlySize ) ! BEMT + 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 BEMT_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%BEMT_y, ErrStat2, ErrMsg2, OnlySize ) ! BEMT_y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + DO i1 = LBOUND(InData%BEMT_u,1), UBOUND(InData%BEMT_u,1) + CALL BEMT_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%BEMT_u(i1), ErrStat2, ErrMsg2, OnlySize ) ! BEMT_u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END DO + CALL AA_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, OnlySize ) ! AA + 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 AA_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%AA_y, ErrStat2, ErrMsg2, OnlySize ) ! AA_y + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL AA_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%AA_u, ErrStat2, ErrMsg2, OnlySize ) ! AA_u + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF ( .NOT. ALLOCATED(InData%DisturbedInflow) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%DisturbedInflow,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DisturbedInflow,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%DisturbedInflow,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DisturbedInflow,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%DisturbedInflow,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DisturbedInflow,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%DisturbedInflow,3), UBOUND(InData%DisturbedInflow,3) + DO i2 = LBOUND(InData%DisturbedInflow,2), UBOUND(InData%DisturbedInflow,2) + DO i1 = LBOUND(InData%DisturbedInflow,1), UBOUND(InData%DisturbedInflow,1) + ReKiBuf(Re_Xferred) = InData%DisturbedInflow(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO END IF - DstRotMiscVarTypeData%M = SrcRotMiscVarTypeData%M -ENDIF - DstRotMiscVarTypeData%V_DiskAvg = SrcRotMiscVarTypeData%V_DiskAvg -IF (ALLOCATED(SrcRotMiscVarTypeData%hub_theta_x_root)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%hub_theta_x_root,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%hub_theta_x_root,1) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%hub_theta_x_root)) THEN - ALLOCATE(DstRotMiscVarTypeData%hub_theta_x_root(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%hub_theta_x_root.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%orientationAnnulus) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%orientationAnnulus,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%orientationAnnulus,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%orientationAnnulus,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%orientationAnnulus,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%orientationAnnulus,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%orientationAnnulus,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%orientationAnnulus,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%orientationAnnulus,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%orientationAnnulus,4), UBOUND(InData%orientationAnnulus,4) + DO i3 = LBOUND(InData%orientationAnnulus,3), UBOUND(InData%orientationAnnulus,3) + DO i2 = LBOUND(InData%orientationAnnulus,2), UBOUND(InData%orientationAnnulus,2) + DO i1 = LBOUND(InData%orientationAnnulus,1), UBOUND(InData%orientationAnnulus,1) + DbKiBuf(Db_Xferred) = InData%orientationAnnulus(i1,i2,i3,i4) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END DO END IF - DstRotMiscVarTypeData%hub_theta_x_root = SrcRotMiscVarTypeData%hub_theta_x_root -ENDIF - DstRotMiscVarTypeData%V_dot_x = SrcRotMiscVarTypeData%V_dot_x - CALL MeshCopy( SrcRotMiscVarTypeData%HubLoad, DstRotMiscVarTypeData%HubLoad, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN -IF (ALLOCATED(SrcRotMiscVarTypeData%B_L_2_H_P)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%B_L_2_H_P,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%B_L_2_H_P,1) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%B_L_2_H_P)) THEN - ALLOCATE(DstRotMiscVarTypeData%B_L_2_H_P(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%B_L_2_H_P.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%AllOuts) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AllOuts,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AllOuts,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AllOuts,1), UBOUND(InData%AllOuts,1) + ReKiBuf(Re_Xferred) = InData%AllOuts(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF - DO i1 = LBOUND(SrcRotMiscVarTypeData%B_L_2_H_P,1), UBOUND(SrcRotMiscVarTypeData%B_L_2_H_P,1) - CALL NWTC_Library_Copymeshmaptype( SrcRotMiscVarTypeData%B_L_2_H_P(i1), DstRotMiscVarTypeData%B_L_2_H_P(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%SigmaCavitCrit)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%SigmaCavitCrit,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%SigmaCavitCrit,1) - i2_l = LBOUND(SrcRotMiscVarTypeData%SigmaCavitCrit,2) - i2_u = UBOUND(SrcRotMiscVarTypeData%SigmaCavitCrit,2) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%SigmaCavitCrit)) THEN - ALLOCATE(DstRotMiscVarTypeData%SigmaCavitCrit(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%SigmaCavitCrit.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%W_Twr) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%W_Twr,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%W_Twr,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%W_Twr,1), UBOUND(InData%W_Twr,1) + ReKiBuf(Re_Xferred) = InData%W_Twr(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF - DstRotMiscVarTypeData%SigmaCavitCrit = SrcRotMiscVarTypeData%SigmaCavitCrit -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%SigmaCavit)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%SigmaCavit,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%SigmaCavit,1) - i2_l = LBOUND(SrcRotMiscVarTypeData%SigmaCavit,2) - i2_u = UBOUND(SrcRotMiscVarTypeData%SigmaCavit,2) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%SigmaCavit)) THEN - ALLOCATE(DstRotMiscVarTypeData%SigmaCavit(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%SigmaCavit.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%X_Twr) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%X_Twr,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%X_Twr,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%X_Twr,1), UBOUND(InData%X_Twr,1) + ReKiBuf(Re_Xferred) = InData%X_Twr(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF - DstRotMiscVarTypeData%SigmaCavit = SrcRotMiscVarTypeData%SigmaCavit -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%CavitWarnSet)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%CavitWarnSet,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%CavitWarnSet,1) - i2_l = LBOUND(SrcRotMiscVarTypeData%CavitWarnSet,2) - i2_u = UBOUND(SrcRotMiscVarTypeData%CavitWarnSet,2) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%CavitWarnSet)) THEN - ALLOCATE(DstRotMiscVarTypeData%CavitWarnSet(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%CavitWarnSet.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%Y_Twr) ) THEN + 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_Twr,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Y_Twr,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Y_Twr,1), UBOUND(InData%Y_Twr,1) + ReKiBuf(Re_Xferred) = InData%Y_Twr(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF - DstRotMiscVarTypeData%CavitWarnSet = SrcRotMiscVarTypeData%CavitWarnSet -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%BladeRootLoad)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%BladeRootLoad,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%BladeRootLoad,1) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%BladeRootLoad)) THEN - ALLOCATE(DstRotMiscVarTypeData%BladeRootLoad(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%BladeRootLoad.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%Curve) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Curve,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Curve,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Curve,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Curve,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Curve,2), UBOUND(InData%Curve,2) + DO i1 = LBOUND(InData%Curve,1), UBOUND(InData%Curve,1) + ReKiBuf(Re_Xferred) = InData%Curve(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - DO i1 = LBOUND(SrcRotMiscVarTypeData%BladeRootLoad,1), UBOUND(SrcRotMiscVarTypeData%BladeRootLoad,1) - CALL MeshCopy( SrcRotMiscVarTypeData%BladeRootLoad(i1), DstRotMiscVarTypeData%BladeRootLoad(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF -IF (ALLOCATED(SrcRotMiscVarTypeData%B_L_2_R_P)) THEN - i1_l = LBOUND(SrcRotMiscVarTypeData%B_L_2_R_P,1) - i1_u = UBOUND(SrcRotMiscVarTypeData%B_L_2_R_P,1) - IF (.NOT. ALLOCATED(DstRotMiscVarTypeData%B_L_2_R_P)) THEN - ALLOCATE(DstRotMiscVarTypeData%B_L_2_R_P(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotMiscVarTypeData%B_L_2_R_P.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + IF ( .NOT. ALLOCATED(InData%TwrClrnc) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrClrnc,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrClrnc,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrClrnc,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrClrnc,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%TwrClrnc,2), UBOUND(InData%TwrClrnc,2) + DO i1 = LBOUND(InData%TwrClrnc,1), UBOUND(InData%TwrClrnc,1) + ReKiBuf(Re_Xferred) = InData%TwrClrnc(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - DO i1 = LBOUND(SrcRotMiscVarTypeData%B_L_2_R_P,1), UBOUND(SrcRotMiscVarTypeData%B_L_2_R_P,1) - CALL NWTC_Library_Copymeshmaptype( SrcRotMiscVarTypeData%B_L_2_R_P(i1), DstRotMiscVarTypeData%B_L_2_R_P(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF - END SUBROUTINE AD_CopyRotMiscVarType + IF ( .NOT. ALLOCATED(InData%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%X,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%X,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%X,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%X,2) + Int_Xferred = Int_Xferred + 2 - SUBROUTINE AD_DestroyRotMiscVarType( RotMiscVarTypeData, ErrStat, ErrMsg ) - TYPE(RotMiscVarType), INTENT(INOUT) :: RotMiscVarTypeData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotMiscVarType' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL BEMT_DestroyMisc( RotMiscVarTypeData%BEMT, ErrStat, ErrMsg ) - CALL BEMT_DestroyOutput( RotMiscVarTypeData%BEMT_y, ErrStat, ErrMsg ) -DO i1 = LBOUND(RotMiscVarTypeData%BEMT_u,1), UBOUND(RotMiscVarTypeData%BEMT_u,1) - CALL BEMT_DestroyInput( RotMiscVarTypeData%BEMT_u(i1), ErrStat, ErrMsg ) -ENDDO - CALL AA_DestroyMisc( RotMiscVarTypeData%AA, ErrStat, ErrMsg ) - CALL AA_DestroyOutput( RotMiscVarTypeData%AA_y, ErrStat, ErrMsg ) - CALL AA_DestroyInput( RotMiscVarTypeData%AA_u, ErrStat, ErrMsg ) -IF (ALLOCATED(RotMiscVarTypeData%DisturbedInflow)) THEN - DEALLOCATE(RotMiscVarTypeData%DisturbedInflow) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%WithoutSweepPitchTwist)) THEN - DEALLOCATE(RotMiscVarTypeData%WithoutSweepPitchTwist) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%AllOuts)) THEN - DEALLOCATE(RotMiscVarTypeData%AllOuts) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%W_Twr)) THEN - DEALLOCATE(RotMiscVarTypeData%W_Twr) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%X_Twr)) THEN - DEALLOCATE(RotMiscVarTypeData%X_Twr) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%Y_Twr)) THEN - DEALLOCATE(RotMiscVarTypeData%Y_Twr) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%Curve)) THEN - DEALLOCATE(RotMiscVarTypeData%Curve) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%TwrClrnc)) THEN - DEALLOCATE(RotMiscVarTypeData%TwrClrnc) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%X)) THEN - DEALLOCATE(RotMiscVarTypeData%X) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%Y)) THEN - DEALLOCATE(RotMiscVarTypeData%Y) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%M)) THEN - DEALLOCATE(RotMiscVarTypeData%M) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%hub_theta_x_root)) THEN - DEALLOCATE(RotMiscVarTypeData%hub_theta_x_root) -ENDIF - CALL MeshDestroy( RotMiscVarTypeData%HubLoad, ErrStat, ErrMsg ) -IF (ALLOCATED(RotMiscVarTypeData%B_L_2_H_P)) THEN -DO i1 = LBOUND(RotMiscVarTypeData%B_L_2_H_P,1), UBOUND(RotMiscVarTypeData%B_L_2_H_P,1) - CALL NWTC_Library_Destroymeshmaptype( RotMiscVarTypeData%B_L_2_H_P(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(RotMiscVarTypeData%B_L_2_H_P) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%SigmaCavitCrit)) THEN - DEALLOCATE(RotMiscVarTypeData%SigmaCavitCrit) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%SigmaCavit)) THEN - DEALLOCATE(RotMiscVarTypeData%SigmaCavit) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%CavitWarnSet)) THEN - DEALLOCATE(RotMiscVarTypeData%CavitWarnSet) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%BladeRootLoad)) THEN -DO i1 = LBOUND(RotMiscVarTypeData%BladeRootLoad,1), UBOUND(RotMiscVarTypeData%BladeRootLoad,1) - CALL MeshDestroy( RotMiscVarTypeData%BladeRootLoad(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(RotMiscVarTypeData%BladeRootLoad) -ENDIF -IF (ALLOCATED(RotMiscVarTypeData%B_L_2_R_P)) THEN -DO i1 = LBOUND(RotMiscVarTypeData%B_L_2_R_P,1), UBOUND(RotMiscVarTypeData%B_L_2_R_P,1) - CALL NWTC_Library_Destroymeshmaptype( RotMiscVarTypeData%B_L_2_R_P(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(RotMiscVarTypeData%B_L_2_R_P) -ENDIF - END SUBROUTINE AD_DestroyRotMiscVarType + DO i2 = LBOUND(InData%X,2), UBOUND(InData%X,2) + DO i1 = LBOUND(InData%X,1), UBOUND(InData%X,1) + ReKiBuf(Re_Xferred) = InData%X(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + 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 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Y,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Y,2) + Int_Xferred = Int_Xferred + 2 - SUBROUTINE AD_PackRotMiscVarType( 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(RotMiscVarType), 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 = 'AD_PackRotMiscVarType' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + DO i2 = LBOUND(InData%Y,2), UBOUND(InData%Y,2) + DO i1 = LBOUND(InData%Y,1), UBOUND(InData%Y,1) + ReKiBuf(Re_Xferred) = InData%Y(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Z) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Z,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Z,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Z,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Z,2) + Int_Xferred = Int_Xferred + 2 - 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 ! BEMT: size of buffers for each call to pack subtype - CALL BEMT_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, .TRUE. ) ! BEMT - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + DO i2 = LBOUND(InData%Z,2), UBOUND(InData%Z,2) + DO i1 = LBOUND(InData%Z,1), UBOUND(InData%Z,1) + ReKiBuf(Re_Xferred) = InData%Z(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + 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%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 - IF(ALLOCATED(Re_Buf)) THEN ! BEMT - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! BEMT - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! BEMT - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! BEMT_y: size of buffers for each call to pack subtype - CALL BEMT_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%BEMT_y, ErrStat2, ErrMsg2, .TRUE. ) ! BEMT_y - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + 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) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Mx) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Mx,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Mx,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Mx,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Mx,2) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN ! BEMT_y - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! BEMT_y - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! BEMT_y - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - DO i1 = LBOUND(InData%BEMT_u,1), UBOUND(InData%BEMT_u,1) - Int_BufSz = Int_BufSz + 3 ! BEMT_u: size of buffers for each call to pack subtype - CALL BEMT_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%BEMT_u(i1), ErrStat2, ErrMsg2, .TRUE. ) ! BEMT_u - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + DO i2 = LBOUND(InData%Mx,2), UBOUND(InData%Mx,2) + DO i1 = LBOUND(InData%Mx,1), UBOUND(InData%Mx,1) + ReKiBuf(Re_Xferred) = InData%Mx(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%My) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%My,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%My,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%My,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%My,2) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN ! BEMT_u - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! BEMT_u - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! BEMT_u - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF + DO i2 = LBOUND(InData%My,2), UBOUND(InData%My,2) + DO i1 = LBOUND(InData%My,1), UBOUND(InData%My,1) + ReKiBuf(Re_Xferred) = InData%My(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Mz) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Mz,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Mz,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Mz,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Mz,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Mz,2), UBOUND(InData%Mz,2) + DO i1 = LBOUND(InData%Mz,1), UBOUND(InData%Mz,1) + ReKiBuf(Re_Xferred) = InData%Mz(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + DO i1 = LBOUND(InData%V_DiskAvg,1), UBOUND(InData%V_DiskAvg,1) + ReKiBuf(Re_Xferred) = InData%V_DiskAvg(i1) + Re_Xferred = Re_Xferred + 1 END DO - Int_BufSz = Int_BufSz + 3 ! AA: size of buffers for each call to pack subtype - CALL AA_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, .TRUE. ) ! AA - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + ReKiBuf(Re_Xferred) = InData%yaw + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%tilt + Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%hub_theta_x_root) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%hub_theta_x_root,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%hub_theta_x_root,1) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN ! AA - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! AA - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! AA - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! AA_y: size of buffers for each call to pack subtype - CALL AA_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%AA_y, ErrStat2, ErrMsg2, .TRUE. ) ! AA_y + DO i1 = LBOUND(InData%hub_theta_x_root,1), UBOUND(InData%hub_theta_x_root,1) + ReKiBuf(Re_Xferred) = InData%hub_theta_x_root(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + ReKiBuf(Re_Xferred) = InData%V_dot_x + Re_Xferred = Re_Xferred + 1 + CALL MeshPack( InData%HubLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! HubLoad CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! AA_y - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! AA_y - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! AA_y - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! AA_u: size of buffers for each call to pack subtype - CALL AA_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%AA_u, ErrStat2, ErrMsg2, .TRUE. ) ! AA_u + 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%B_L_2_H_P) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%B_L_2_H_P,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%B_L_2_H_P,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%B_L_2_H_P,1), UBOUND(InData%B_L_2_H_P,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%B_L_2_H_P(i1), ErrStat2, ErrMsg2, OnlySize ) ! B_L_2_H_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! AA_u - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! AA_u - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! AA_u - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 1 ! DisturbedInflow allocated yes/no - IF ( ALLOCATED(InData%DisturbedInflow) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! DisturbedInflow upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%DisturbedInflow) ! DisturbedInflow - END IF - Int_BufSz = Int_BufSz + 1 ! WithoutSweepPitchTwist allocated yes/no - IF ( ALLOCATED(InData%WithoutSweepPitchTwist) ) THEN - Int_BufSz = Int_BufSz + 2*4 ! WithoutSweepPitchTwist upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%WithoutSweepPitchTwist) ! WithoutSweepPitchTwist + 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 - Int_BufSz = Int_BufSz + 1 ! AllOuts allocated yes/no - IF ( ALLOCATED(InData%AllOuts) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! AllOuts upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%AllOuts) ! AllOuts + IF ( .NOT. ALLOCATED(InData%SigmaCavitCrit) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%SigmaCavitCrit,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SigmaCavitCrit,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%SigmaCavitCrit,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SigmaCavitCrit,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%SigmaCavitCrit,2), UBOUND(InData%SigmaCavitCrit,2) + DO i1 = LBOUND(InData%SigmaCavitCrit,1), UBOUND(InData%SigmaCavitCrit,1) + ReKiBuf(Re_Xferred) = InData%SigmaCavitCrit(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - Int_BufSz = Int_BufSz + 1 ! W_Twr allocated yes/no - IF ( ALLOCATED(InData%W_Twr) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! W_Twr upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%W_Twr) ! W_Twr + IF ( .NOT. ALLOCATED(InData%SigmaCavit) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%SigmaCavit,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SigmaCavit,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%SigmaCavit,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SigmaCavit,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%SigmaCavit,2), UBOUND(InData%SigmaCavit,2) + DO i1 = LBOUND(InData%SigmaCavit,1), UBOUND(InData%SigmaCavit,1) + ReKiBuf(Re_Xferred) = InData%SigmaCavit(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - Int_BufSz = Int_BufSz + 1 ! X_Twr allocated yes/no - IF ( ALLOCATED(InData%X_Twr) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! X_Twr upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%X_Twr) ! X_Twr + IF ( .NOT. ALLOCATED(InData%CavitWarnSet) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CavitWarnSet,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CavitWarnSet,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CavitWarnSet,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CavitWarnSet,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%CavitWarnSet,2), UBOUND(InData%CavitWarnSet,2) + DO i1 = LBOUND(InData%CavitWarnSet,1), UBOUND(InData%CavitWarnSet,1) + IntKiBuf(Int_Xferred) = TRANSFER(InData%CavitWarnSet(i1,i2), IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END DO + END DO END IF - Int_BufSz = Int_BufSz + 1 ! Y_Twr allocated yes/no - IF ( ALLOCATED(InData%Y_Twr) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Y_Twr upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Y_Twr) ! Y_Twr + IF ( .NOT. ALLOCATED(InData%BlFB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlFB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlFB,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlFB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlFB,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlFB,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlFB,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%BlFB,3), UBOUND(InData%BlFB,3) + DO i2 = LBOUND(InData%BlFB,2), UBOUND(InData%BlFB,2) + DO i1 = LBOUND(InData%BlFB,1), UBOUND(InData%BlFB,1) + ReKiBuf(Re_Xferred) = InData%BlFB(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO END IF - Int_BufSz = Int_BufSz + 1 ! Curve allocated yes/no - IF ( ALLOCATED(InData%Curve) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! Curve upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Curve) ! Curve + IF ( .NOT. ALLOCATED(InData%BlMB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlMB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlMB,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlMB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlMB,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlMB,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlMB,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%BlMB,3), UBOUND(InData%BlMB,3) + DO i2 = LBOUND(InData%BlMB,2), UBOUND(InData%BlMB,2) + DO i1 = LBOUND(InData%BlMB,1), UBOUND(InData%BlMB,1) + ReKiBuf(Re_Xferred) = InData%BlMB(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO END IF - Int_BufSz = Int_BufSz + 1 ! TwrClrnc allocated yes/no - IF ( ALLOCATED(InData%TwrClrnc) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! TwrClrnc upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TwrClrnc) ! TwrClrnc + IF ( .NOT. ALLOCATED(InData%TwrFB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrFB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrFB,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrFB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrFB,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%TwrFB,2), UBOUND(InData%TwrFB,2) + DO i1 = LBOUND(InData%TwrFB,1), UBOUND(InData%TwrFB,1) + ReKiBuf(Re_Xferred) = InData%TwrFB(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - Int_BufSz = Int_BufSz + 1 ! X allocated yes/no - IF ( ALLOCATED(InData%X) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! X upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%X) ! X + IF ( .NOT. ALLOCATED(InData%TwrMB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrMB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrMB,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrMB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrMB,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%TwrMB,2), UBOUND(InData%TwrMB,2) + DO i1 = LBOUND(InData%TwrMB,1), UBOUND(InData%TwrMB,1) + ReKiBuf(Re_Xferred) = InData%TwrMB(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - Int_BufSz = Int_BufSz + 1 ! Y allocated yes/no - IF ( ALLOCATED(InData%Y) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! Y upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Y) ! Y + IF ( .NOT. ALLOCATED(InData%HubFB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%HubFB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HubFB,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%HubFB,1), UBOUND(InData%HubFB,1) + ReKiBuf(Re_Xferred) = InData%HubFB(i1) + Re_Xferred = Re_Xferred + 1 + END DO 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 + IF ( .NOT. ALLOCATED(InData%HubMB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%HubMB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HubMB,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%HubMB,1), UBOUND(InData%HubMB,1) + ReKiBuf(Re_Xferred) = InData%HubMB(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF - Re_BufSz = Re_BufSz + SIZE(InData%V_DiskAvg) ! V_DiskAvg - Int_BufSz = Int_BufSz + 1 ! hub_theta_x_root allocated yes/no - IF ( ALLOCATED(InData%hub_theta_x_root) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! hub_theta_x_root upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%hub_theta_x_root) ! hub_theta_x_root + IF ( .NOT. ALLOCATED(InData%NacFB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%NacFB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NacFB,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%NacFB,1), UBOUND(InData%NacFB,1) + ReKiBuf(Re_Xferred) = InData%NacFB(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF - Re_BufSz = Re_BufSz + 1 ! V_dot_x - Int_BufSz = Int_BufSz + 3 ! HubLoad: size of buffers for each call to pack subtype - CALL MeshPack( InData%HubLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! HubLoad + IF ( .NOT. ALLOCATED(InData%NacMB) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%NacMB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%NacMB,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%NacMB,1), UBOUND(InData%NacMB,1) + ReKiBuf(Re_Xferred) = InData%NacMB(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BladeRootLoad) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeRootLoad,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootLoad,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BladeRootLoad,1), UBOUND(InData%BladeRootLoad,1) + CALL MeshPack( InData%BladeRootLoad(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! BladeRootLoad CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! HubLoad - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! HubLoad - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! HubLoad - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 1 ! B_L_2_H_P allocated yes/no - IF ( ALLOCATED(InData%B_L_2_H_P) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! B_L_2_H_P upper/lower bounds for each dimension - DO i1 = LBOUND(InData%B_L_2_H_P,1), UBOUND(InData%B_L_2_H_P,1) - Int_BufSz = Int_BufSz + 3 ! B_L_2_H_P: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%B_L_2_H_P(i1), ErrStat2, ErrMsg2, .TRUE. ) ! B_L_2_H_P + 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%B_L_2_R_P) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%B_L_2_R_P,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%B_L_2_R_P,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%B_L_2_R_P,1), UBOUND(InData%B_L_2_R_P,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%B_L_2_R_P(i1), ErrStat2, ErrMsg2, OnlySize ) ! B_L_2_R_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! B_L_2_H_P - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! B_L_2_H_P - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! B_L_2_H_P - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF + 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 - Int_BufSz = Int_BufSz + 1 ! SigmaCavitCrit allocated yes/no - IF ( ALLOCATED(InData%SigmaCavitCrit) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! SigmaCavitCrit upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%SigmaCavitCrit) ! SigmaCavitCrit - END IF - Int_BufSz = Int_BufSz + 1 ! SigmaCavit allocated yes/no - IF ( ALLOCATED(InData%SigmaCavit) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! SigmaCavit upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%SigmaCavit) ! SigmaCavit - END IF - Int_BufSz = Int_BufSz + 1 ! CavitWarnSet allocated yes/no - IF ( ALLOCATED(InData%CavitWarnSet) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! CavitWarnSet upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%CavitWarnSet) ! CavitWarnSet + IF ( .NOT. ALLOCATED(InData%BladeBuoyLoadPoint) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeBuoyLoadPoint,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeBuoyLoadPoint,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BladeBuoyLoadPoint,1), UBOUND(InData%BladeBuoyLoadPoint,1) + CALL MeshPack( InData%BladeBuoyLoadPoint(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! BladeBuoyLoadPoint + 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 - Int_BufSz = Int_BufSz + 1 ! BladeRootLoad allocated yes/no - IF ( ALLOCATED(InData%BladeRootLoad) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! BladeRootLoad upper/lower bounds for each dimension - DO i1 = LBOUND(InData%BladeRootLoad,1), UBOUND(InData%BladeRootLoad,1) - Int_BufSz = Int_BufSz + 3 ! BladeRootLoad: size of buffers for each call to pack subtype - CALL MeshPack( InData%BladeRootLoad(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! BladeRootLoad + IF ( .NOT. ALLOCATED(InData%BladeBuoyLoad) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeBuoyLoad,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeBuoyLoad,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BladeBuoyLoad,1), UBOUND(InData%BladeBuoyLoad,1) + CALL MeshPack( InData%BladeBuoyLoad(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! BladeBuoyLoad CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! BladeRootLoad - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! BladeRootLoad - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! BladeRootLoad - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF + 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 - Int_BufSz = Int_BufSz + 1 ! B_L_2_R_P allocated yes/no - IF ( ALLOCATED(InData%B_L_2_R_P) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! B_L_2_R_P upper/lower bounds for each dimension - DO i1 = LBOUND(InData%B_L_2_R_P,1), UBOUND(InData%B_L_2_R_P,1) - Int_BufSz = Int_BufSz + 3 ! B_L_2_R_P: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%B_L_2_R_P(i1), ErrStat2, ErrMsg2, .TRUE. ) ! B_L_2_R_P + IF ( .NOT. ALLOCATED(InData%B_P_2_B_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%B_P_2_B_L,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%B_P_2_B_L,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%B_P_2_B_L,1), UBOUND(InData%B_P_2_B_L,1) + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%B_P_2_B_L(i1), ErrStat2, ErrMsg2, OnlySize ) ! B_P_2_B_L CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! B_L_2_R_P - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! B_L_2_R_P - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! B_L_2_R_P - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF + 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 ( 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) + CALL MeshPack( InData%TwrBuoyLoadPoint, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! TwrBuoyLoadPoint + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 + 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%TwrBuoyLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! TwrBuoyLoad + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN - CALL BEMT_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%BEMT, ErrStat2, ErrMsg2, OnlySize ) ! BEMT + 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%T_P_2_T_L, ErrStat2, ErrMsg2, OnlySize ) ! T_P_2_T_L CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -7971,667 +11104,692 @@ SUBROUTINE AD_PackRotMiscVarType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL BEMT_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%BEMT_y, ErrStat2, ErrMsg2, OnlySize ) ! BEMT_y + IntKiBuf(Int_Xferred) = TRANSFER(InData%FirstWarn_TowerStrike, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%AvgDiskVel,1), UBOUND(InData%AvgDiskVel,1) + ReKiBuf(Re_Xferred) = InData%AvgDiskVel(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%AvgDiskVelDist,1), UBOUND(InData%AvgDiskVelDist,1) + ReKiBuf(Re_Xferred) = InData%AvgDiskVelDist(i1) + Re_Xferred = Re_Xferred + 1 + END DO + ReKiBuf(Re_Xferred) = InData%TFinAlpha + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%TFinRe + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%TFinVrel + Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%TFinVund_i,1), UBOUND(InData%TFinVund_i,1) + ReKiBuf(Re_Xferred) = InData%TFinVund_i(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%TFinVind_i,1), UBOUND(InData%TFinVind_i,1) + ReKiBuf(Re_Xferred) = InData%TFinVind_i(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%TFinVrel_i,1), UBOUND(InData%TFinVrel_i,1) + ReKiBuf(Re_Xferred) = InData%TFinVrel_i(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%TFinSTV_i,1), UBOUND(InData%TFinSTV_i,1) + ReKiBuf(Re_Xferred) = InData%TFinSTV_i(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%TFinF_i,1), UBOUND(InData%TFinF_i,1) + ReKiBuf(Re_Xferred) = InData%TFinF_i(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%TFinM_i,1), UBOUND(InData%TFinM_i,1) + ReKiBuf(Re_Xferred) = InData%TFinM_i(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END SUBROUTINE AD_PackRotMiscVarType + + SUBROUTINE AD_UnPackRotMiscVarType( 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(RotMiscVarType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackRotMiscVarType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL BEMT_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT, ErrStat2, ErrMsg2 ) ! BEMT + 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 BEMT_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT_y, ErrStat2, ErrMsg2 ) ! BEMT_y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - DO i1 = LBOUND(InData%BEMT_u,1), UBOUND(InData%BEMT_u,1) - CALL BEMT_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%BEMT_u(i1), ErrStat2, ErrMsg2, OnlySize ) ! BEMT_u + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + i1_l = LBOUND(OutData%BEMT_u,1) + i1_u = UBOUND(OutData%BEMT_u,1) + DO i1 = LBOUND(OutData%BEMT_u,1), UBOUND(OutData%BEMT_u,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 BEMT_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT_u(i1), ErrStat2, ErrMsg2 ) ! BEMT_u CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO - CALL AA_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%AA, ErrStat2, ErrMsg2, OnlySize ) ! AA + 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 AA_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%AA, ErrStat2, ErrMsg2 ) ! AA 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 AA_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%AA_y, ErrStat2, ErrMsg2, OnlySize ) ! AA_y + 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 AA_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%AA_y, ErrStat2, ErrMsg2 ) ! AA_y CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL AA_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%AA_u, ErrStat2, ErrMsg2, OnlySize ) ! AA_u + 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 AA_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%AA_u, ErrStat2, ErrMsg2 ) ! AA_u CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF ( .NOT. ALLOCATED(InData%DisturbedInflow) ) THEN - IntKiBuf( Int_Xferred ) = 0 + 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 ! DisturbedInflow not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%DisturbedInflow,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DisturbedInflow,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%DisturbedInflow,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DisturbedInflow,2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%DisturbedInflow,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DisturbedInflow,3) + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i3 = LBOUND(InData%DisturbedInflow,3), UBOUND(InData%DisturbedInflow,3) - DO i2 = LBOUND(InData%DisturbedInflow,2), UBOUND(InData%DisturbedInflow,2) - DO i1 = LBOUND(InData%DisturbedInflow,1), UBOUND(InData%DisturbedInflow,1) - ReKiBuf(Re_Xferred) = InData%DisturbedInflow(i1,i2,i3) + IF (ALLOCATED(OutData%DisturbedInflow)) DEALLOCATE(OutData%DisturbedInflow) + ALLOCATE(OutData%DisturbedInflow(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%DisturbedInflow.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%DisturbedInflow,3), UBOUND(OutData%DisturbedInflow,3) + DO i2 = LBOUND(OutData%DisturbedInflow,2), UBOUND(OutData%DisturbedInflow,2) + DO i1 = LBOUND(OutData%DisturbedInflow,1), UBOUND(OutData%DisturbedInflow,1) + OutData%DisturbedInflow(i1,i2,i3) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%WithoutSweepPitchTwist) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! orientationAnnulus not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WithoutSweepPitchTwist,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WithoutSweepPitchTwist,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WithoutSweepPitchTwist,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WithoutSweepPitchTwist,2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WithoutSweepPitchTwist,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WithoutSweepPitchTwist,3) + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WithoutSweepPitchTwist,4) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WithoutSweepPitchTwist,4) + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i4 = LBOUND(InData%WithoutSweepPitchTwist,4), UBOUND(InData%WithoutSweepPitchTwist,4) - DO i3 = LBOUND(InData%WithoutSweepPitchTwist,3), UBOUND(InData%WithoutSweepPitchTwist,3) - DO i2 = LBOUND(InData%WithoutSweepPitchTwist,2), UBOUND(InData%WithoutSweepPitchTwist,2) - DO i1 = LBOUND(InData%WithoutSweepPitchTwist,1), UBOUND(InData%WithoutSweepPitchTwist,1) - ReKiBuf(Re_Xferred) = InData%WithoutSweepPitchTwist(i1,i2,i3,i4) - Re_Xferred = Re_Xferred + 1 + IF (ALLOCATED(OutData%orientationAnnulus)) DEALLOCATE(OutData%orientationAnnulus) + ALLOCATE(OutData%orientationAnnulus(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%orientationAnnulus.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%orientationAnnulus,4), UBOUND(OutData%orientationAnnulus,4) + DO i3 = LBOUND(OutData%orientationAnnulus,3), UBOUND(OutData%orientationAnnulus,3) + DO i2 = LBOUND(OutData%orientationAnnulus,2), UBOUND(OutData%orientationAnnulus,2) + DO i1 = LBOUND(OutData%orientationAnnulus,1), UBOUND(OutData%orientationAnnulus,1) + OutData%orientationAnnulus(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 ( .NOT. ALLOCATED(InData%AllOuts) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AllOuts not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AllOuts,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AllOuts,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%AllOuts,1), UBOUND(InData%AllOuts,1) - ReKiBuf(Re_Xferred) = InData%AllOuts(i1) + IF (ALLOCATED(OutData%AllOuts)) DEALLOCATE(OutData%AllOuts) + ALLOCATE(OutData%AllOuts(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AllOuts.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AllOuts,1), UBOUND(OutData%AllOuts,1) + OutData%AllOuts(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%W_Twr) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! W_Twr not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%W_Twr,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%W_Twr,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%W_Twr,1), UBOUND(InData%W_Twr,1) - ReKiBuf(Re_Xferred) = InData%W_Twr(i1) + IF (ALLOCATED(OutData%W_Twr)) DEALLOCATE(OutData%W_Twr) + ALLOCATE(OutData%W_Twr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%W_Twr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%W_Twr,1), UBOUND(OutData%W_Twr,1) + OutData%W_Twr(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%X_Twr) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! X_Twr not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%X_Twr,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%X_Twr,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%X_Twr,1), UBOUND(InData%X_Twr,1) - ReKiBuf(Re_Xferred) = InData%X_Twr(i1) + IF (ALLOCATED(OutData%X_Twr)) DEALLOCATE(OutData%X_Twr) + ALLOCATE(OutData%X_Twr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%X_Twr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%X_Twr,1), UBOUND(OutData%X_Twr,1) + OutData%X_Twr(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%Y_Twr) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Y_Twr not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Y_Twr,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Y_Twr,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%Y_Twr,1), UBOUND(InData%Y_Twr,1) - ReKiBuf(Re_Xferred) = InData%Y_Twr(i1) + IF (ALLOCATED(OutData%Y_Twr)) DEALLOCATE(OutData%Y_Twr) + ALLOCATE(OutData%Y_Twr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Y_Twr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Y_Twr,1), UBOUND(OutData%Y_Twr,1) + OutData%Y_Twr(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%Curve) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Curve not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Curve,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Curve,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Curve,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Curve,2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%Curve,2), UBOUND(InData%Curve,2) - DO i1 = LBOUND(InData%Curve,1), UBOUND(InData%Curve,1) - ReKiBuf(Re_Xferred) = InData%Curve(i1,i2) + IF (ALLOCATED(OutData%Curve)) DEALLOCATE(OutData%Curve) + ALLOCATE(OutData%Curve(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Curve.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Curve,2), UBOUND(OutData%Curve,2) + DO i1 = LBOUND(OutData%Curve,1), UBOUND(OutData%Curve,1) + OutData%Curve(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%TwrClrnc) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrClrnc not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrClrnc,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrClrnc,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrClrnc,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrClrnc,2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%TwrClrnc,2), UBOUND(InData%TwrClrnc,2) - DO i1 = LBOUND(InData%TwrClrnc,1), UBOUND(InData%TwrClrnc,1) - ReKiBuf(Re_Xferred) = InData%TwrClrnc(i1,i2) + IF (ALLOCATED(OutData%TwrClrnc)) DEALLOCATE(OutData%TwrClrnc) + ALLOCATE(OutData%TwrClrnc(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrClrnc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%TwrClrnc,2), UBOUND(OutData%TwrClrnc,2) + DO i1 = LBOUND(OutData%TwrClrnc,1), UBOUND(OutData%TwrClrnc,1) + OutData%TwrClrnc(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%X) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! X not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%X,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%X,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%X,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%X,2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%X,2), UBOUND(InData%X,2) - DO i1 = LBOUND(InData%X,1), UBOUND(InData%X,1) - ReKiBuf(Re_Xferred) = InData%X(i1,i2) + IF (ALLOCATED(OutData%X)) DEALLOCATE(OutData%X) + ALLOCATE(OutData%X(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%X.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%X,2), UBOUND(OutData%X,2) + DO i1 = LBOUND(OutData%X,1), UBOUND(OutData%X,1) + OutData%X(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Y) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Y not allocated 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) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Y,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Y,2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%Y,2), UBOUND(InData%Y,2) - DO i1 = LBOUND(InData%Y,1), UBOUND(InData%Y,1) - ReKiBuf(Re_Xferred) = InData%Y(i1,i2) + IF (ALLOCATED(OutData%Y)) DEALLOCATE(OutData%Y) + ALLOCATE(OutData%Y(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Y.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Y,2), UBOUND(OutData%Y,2) + DO i1 = LBOUND(OutData%Y,1), UBOUND(OutData%Y,1) + OutData%Y(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%M) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Z not allocated 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) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%M,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%M,2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) 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) + IF (ALLOCATED(OutData%Z)) DEALLOCATE(OutData%Z) + ALLOCATE(OutData%Z(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Z.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Z,2), UBOUND(OutData%Z,2) + DO i1 = LBOUND(OutData%Z,1), UBOUND(OutData%Z,1) + OutData%Z(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - DO i1 = LBOUND(InData%V_DiskAvg,1), UBOUND(InData%V_DiskAvg,1) - ReKiBuf(Re_Xferred) = InData%V_DiskAvg(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IF ( .NOT. ALLOCATED(InData%hub_theta_x_root) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! M not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%hub_theta_x_root,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%hub_theta_x_root,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%hub_theta_x_root,1), UBOUND(InData%hub_theta_x_root,1) - ReKiBuf(Re_Xferred) = InData%hub_theta_x_root(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - ReKiBuf(Re_Xferred) = InData%V_dot_x - Re_Xferred = Re_Xferred + 1 - CALL MeshPack( InData%HubLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! HubLoad - 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%B_L_2_H_P) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%B_L_2_H_P,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%B_L_2_H_P,1) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%B_L_2_H_P,1), UBOUND(InData%B_L_2_H_P,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%B_L_2_H_P(i1), ErrStat2, ErrMsg2, OnlySize ) ! B_L_2_H_P - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END DO + 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%M.', 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) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - IF ( .NOT. ALLOCATED(InData%SigmaCavitCrit) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Mx not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%SigmaCavitCrit,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SigmaCavitCrit,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%SigmaCavitCrit,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SigmaCavitCrit,2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%SigmaCavitCrit,2), UBOUND(InData%SigmaCavitCrit,2) - DO i1 = LBOUND(InData%SigmaCavitCrit,1), UBOUND(InData%SigmaCavitCrit,1) - ReKiBuf(Re_Xferred) = InData%SigmaCavitCrit(i1,i2) + IF (ALLOCATED(OutData%Mx)) DEALLOCATE(OutData%Mx) + ALLOCATE(OutData%Mx(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Mx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Mx,2), UBOUND(OutData%Mx,2) + DO i1 = LBOUND(OutData%Mx,1), UBOUND(OutData%Mx,1) + OutData%Mx(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%SigmaCavit) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! My not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%SigmaCavit,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SigmaCavit,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%SigmaCavit,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%SigmaCavit,2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%SigmaCavit,2), UBOUND(InData%SigmaCavit,2) - DO i1 = LBOUND(InData%SigmaCavit,1), UBOUND(InData%SigmaCavit,1) - ReKiBuf(Re_Xferred) = InData%SigmaCavit(i1,i2) + IF (ALLOCATED(OutData%My)) DEALLOCATE(OutData%My) + ALLOCATE(OutData%My(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%My.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%My,2), UBOUND(OutData%My,2) + DO i1 = LBOUND(OutData%My,1), UBOUND(OutData%My,1) + OutData%My(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%CavitWarnSet) ) THEN - IntKiBuf( Int_Xferred ) = 0 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Mz not allocated Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%CavitWarnSet,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CavitWarnSet,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%CavitWarnSet,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CavitWarnSet,2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%CavitWarnSet,2), UBOUND(InData%CavitWarnSet,2) - DO i1 = LBOUND(InData%CavitWarnSet,1), UBOUND(InData%CavitWarnSet,1) - IntKiBuf(Int_Xferred) = TRANSFER(InData%CavitWarnSet(i1,i2), IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 + IF (ALLOCATED(OutData%Mz)) DEALLOCATE(OutData%Mz) + ALLOCATE(OutData%Mz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Mz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Mz,2), UBOUND(OutData%Mz,2) + DO i1 = LBOUND(OutData%Mz,1), UBOUND(OutData%Mz,1) + OutData%Mz(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%BladeRootLoad) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BladeRootLoad,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BladeRootLoad,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%BladeRootLoad,1), UBOUND(InData%BladeRootLoad,1) - CALL MeshPack( InData%BladeRootLoad(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! BladeRootLoad - 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%B_L_2_R_P) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%B_L_2_R_P,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%B_L_2_R_P,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%B_L_2_R_P,1), UBOUND(InData%B_L_2_R_P,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%B_L_2_R_P(i1), ErrStat2, ErrMsg2, OnlySize ) ! B_L_2_R_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 + i1_l = LBOUND(OutData%V_DiskAvg,1) + i1_u = UBOUND(OutData%V_DiskAvg,1) + DO i1 = LBOUND(OutData%V_DiskAvg,1), UBOUND(OutData%V_DiskAvg,1) + OutData%V_DiskAvg(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END DO + OutData%yaw = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%tilt = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! hub_theta_x_root not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%hub_theta_x_root)) DEALLOCATE(OutData%hub_theta_x_root) + ALLOCATE(OutData%hub_theta_x_root(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%hub_theta_x_root.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%hub_theta_x_root,1), UBOUND(OutData%hub_theta_x_root,1) + OutData%hub_theta_x_root(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END IF - END SUBROUTINE AD_PackRotMiscVarType - - SUBROUTINE AD_UnPackRotMiscVarType( 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(RotMiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'AD_UnPackRotMiscVarType' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL BEMT_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT, ErrStat2, ErrMsg2 ) ! BEMT - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + OutData%V_dot_x = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -8665,16 +11823,27 @@ SUBROUTINE AD_UnPackRotMiscVarType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL BEMT_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT_y, ErrStat2, ErrMsg2 ) ! BEMT_y + CALL MeshUnpack( OutData%HubLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! HubLoad CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - i1_l = LBOUND(OutData%BEMT_u,1) - i1_u = UBOUND(OutData%BEMT_u,1) - DO i1 = LBOUND(OutData%BEMT_u,1), UBOUND(OutData%BEMT_u,1) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! B_L_2_H_P not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%B_L_2_H_P)) DEALLOCATE(OutData%B_L_2_H_P) + ALLOCATE(OutData%B_L_2_H_P(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%B_L_2_H_P.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%B_L_2_H_P,1), UBOUND(OutData%B_L_2_H_P,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -8708,7 +11877,7 @@ SUBROUTINE AD_UnPackRotMiscVarType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL BEMT_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%BEMT_u(i1), ErrStat2, ErrMsg2 ) ! BEMT_u + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%B_L_2_H_P(i1), ErrStat2, ErrMsg2 ) ! B_L_2_H_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -8716,127 +11885,31 @@ SUBROUTINE AD_UnPackRotMiscVarType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AA_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%AA, ErrStat2, ErrMsg2 ) ! AA - 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 AA_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%AA_y, ErrStat2, ErrMsg2 ) ! AA_y - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL AA_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%AA_u, ErrStat2, ErrMsg2 ) ! AA_u - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! DisturbedInflow not allocated + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SigmaCavitCrit not allocated + Int_Xferred = Int_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%SigmaCavitCrit)) DEALLOCATE(OutData%SigmaCavitCrit) + ALLOCATE(OutData%SigmaCavitCrit(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SigmaCavitCrit.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%SigmaCavitCrit,2), UBOUND(OutData%SigmaCavitCrit,2) + DO i1 = LBOUND(OutData%SigmaCavitCrit,1), UBOUND(OutData%SigmaCavitCrit,1) + OutData%SigmaCavitCrit(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SigmaCavit not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -8846,25 +11919,43 @@ SUBROUTINE AD_UnPackRotMiscVarType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat 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) + IF (ALLOCATED(OutData%SigmaCavit)) DEALLOCATE(OutData%SigmaCavit) + ALLOCATE(OutData%SigmaCavit(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SigmaCavit.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%SigmaCavit,2), UBOUND(OutData%SigmaCavit,2) + DO i1 = LBOUND(OutData%SigmaCavit,1), UBOUND(OutData%SigmaCavit,1) + OutData%SigmaCavit(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CavitWarnSet not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%DisturbedInflow)) DEALLOCATE(OutData%DisturbedInflow) - ALLOCATE(OutData%DisturbedInflow(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%CavitWarnSet)) DEALLOCATE(OutData%CavitWarnSet) + ALLOCATE(OutData%CavitWarnSet(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%DisturbedInflow.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CavitWarnSet.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i3 = LBOUND(OutData%DisturbedInflow,3), UBOUND(OutData%DisturbedInflow,3) - DO i2 = LBOUND(OutData%DisturbedInflow,2), UBOUND(OutData%DisturbedInflow,2) - DO i1 = LBOUND(OutData%DisturbedInflow,1), UBOUND(OutData%DisturbedInflow,1) - OutData%DisturbedInflow(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + DO i2 = LBOUND(OutData%CavitWarnSet,2), UBOUND(OutData%CavitWarnSet,2) + DO i1 = LBOUND(OutData%CavitWarnSet,1), UBOUND(OutData%CavitWarnSet,1) + OutData%CavitWarnSet(i1,i2) = TRANSFER(IntKiBuf(Int_Xferred), OutData%CavitWarnSet(i1,i2)) + Int_Xferred = Int_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WithoutSweepPitchTwist not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlFB not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -8877,239 +11968,293 @@ SUBROUTINE AD_UnPackRotMiscVarType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat 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%WithoutSweepPitchTwist)) DEALLOCATE(OutData%WithoutSweepPitchTwist) - ALLOCATE(OutData%WithoutSweepPitchTwist(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%BlFB)) DEALLOCATE(OutData%BlFB) + ALLOCATE(OutData%BlFB(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%WithoutSweepPitchTwist.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlFB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i4 = LBOUND(OutData%WithoutSweepPitchTwist,4), UBOUND(OutData%WithoutSweepPitchTwist,4) - DO i3 = LBOUND(OutData%WithoutSweepPitchTwist,3), UBOUND(OutData%WithoutSweepPitchTwist,3) - DO i2 = LBOUND(OutData%WithoutSweepPitchTwist,2), UBOUND(OutData%WithoutSweepPitchTwist,2) - DO i1 = LBOUND(OutData%WithoutSweepPitchTwist,1), UBOUND(OutData%WithoutSweepPitchTwist,1) - OutData%WithoutSweepPitchTwist(i1,i2,i3,i4) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + DO i3 = LBOUND(OutData%BlFB,3), UBOUND(OutData%BlFB,3) + DO i2 = LBOUND(OutData%BlFB,2), UBOUND(OutData%BlFB,2) + DO i1 = LBOUND(OutData%BlFB,1), UBOUND(OutData%BlFB,1) + OutData%BlFB(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 ! AllOuts not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlMB not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%AllOuts)) DEALLOCATE(OutData%AllOuts) - ALLOCATE(OutData%AllOuts(i1_l:i1_u),STAT=ErrStat2) + 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%BlMB)) DEALLOCATE(OutData%BlMB) + ALLOCATE(OutData%BlMB(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%AllOuts.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlMB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%AllOuts,1), UBOUND(OutData%AllOuts,1) - OutData%AllOuts(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(OutData%BlMB,3), UBOUND(OutData%BlMB,3) + DO i2 = LBOUND(OutData%BlMB,2), UBOUND(OutData%BlMB,2) + DO i1 = LBOUND(OutData%BlMB,1), UBOUND(OutData%BlMB,1) + OutData%BlMB(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 ! W_Twr not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrFB not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%W_Twr)) DEALLOCATE(OutData%W_Twr) - ALLOCATE(OutData%W_Twr(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%TwrFB)) DEALLOCATE(OutData%TwrFB) + ALLOCATE(OutData%TwrFB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%W_Twr.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrFB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%W_Twr,1), UBOUND(OutData%W_Twr,1) - OutData%W_Twr(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(OutData%TwrFB,2), UBOUND(OutData%TwrFB,2) + DO i1 = LBOUND(OutData%TwrFB,1), UBOUND(OutData%TwrFB,1) + OutData%TwrFB(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! X_Twr not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrMB not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%X_Twr)) DEALLOCATE(OutData%X_Twr) - ALLOCATE(OutData%X_Twr(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%TwrMB)) DEALLOCATE(OutData%TwrMB) + ALLOCATE(OutData%TwrMB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%X_Twr.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrMB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%X_Twr,1), UBOUND(OutData%X_Twr,1) - OutData%X_Twr(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i2 = LBOUND(OutData%TwrMB,2), UBOUND(OutData%TwrMB,2) + DO i1 = LBOUND(OutData%TwrMB,1), UBOUND(OutData%TwrMB,1) + OutData%TwrMB(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Y_Twr not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! HubFB not allocated Int_Xferred = Int_Xferred + 1 ELSE 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_Twr)) DEALLOCATE(OutData%Y_Twr) - ALLOCATE(OutData%Y_Twr(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%HubFB)) DEALLOCATE(OutData%HubFB) + ALLOCATE(OutData%HubFB(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Y_Twr.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%HubFB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Y_Twr,1), UBOUND(OutData%Y_Twr,1) - OutData%Y_Twr(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%HubFB,1), UBOUND(OutData%HubFB,1) + OutData%HubFB(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Curve not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! HubMB not allocated Int_Xferred = Int_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%Curve)) DEALLOCATE(OutData%Curve) - ALLOCATE(OutData%Curve(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%HubMB)) DEALLOCATE(OutData%HubMB) + ALLOCATE(OutData%HubMB(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Curve.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%HubMB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%Curve,2), UBOUND(OutData%Curve,2) - DO i1 = LBOUND(OutData%Curve,1), UBOUND(OutData%Curve,1) - OutData%Curve(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(OutData%HubMB,1), UBOUND(OutData%HubMB,1) + OutData%HubMB(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrClrnc not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NacFB not allocated Int_Xferred = Int_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%TwrClrnc)) DEALLOCATE(OutData%TwrClrnc) - ALLOCATE(OutData%TwrClrnc(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%NacFB)) DEALLOCATE(OutData%NacFB) + ALLOCATE(OutData%NacFB(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrClrnc.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NacFB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%TwrClrnc,2), UBOUND(OutData%TwrClrnc,2) - DO i1 = LBOUND(OutData%TwrClrnc,1), UBOUND(OutData%TwrClrnc,1) - OutData%TwrClrnc(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(OutData%NacFB,1), UBOUND(OutData%NacFB,1) + OutData%NacFB(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! X not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! NacMB not allocated Int_Xferred = Int_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%X)) DEALLOCATE(OutData%X) - ALLOCATE(OutData%X(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%NacMB)) DEALLOCATE(OutData%NacMB) + ALLOCATE(OutData%NacMB(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%X.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%NacMB.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%X,2), UBOUND(OutData%X,2) - DO i1 = LBOUND(OutData%X,1), UBOUND(OutData%X,1) - OutData%X(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(OutData%NacMB,1), UBOUND(OutData%NacMB,1) + OutData%NacMB(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Y not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeRootLoad not allocated Int_Xferred = Int_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%Y)) DEALLOCATE(OutData%Y) - ALLOCATE(OutData%Y(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%BladeRootLoad)) DEALLOCATE(OutData%BladeRootLoad) + ALLOCATE(OutData%BladeRootLoad(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Y.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeRootLoad.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%Y,2), UBOUND(OutData%Y,2) - DO i1 = LBOUND(OutData%Y,1), UBOUND(OutData%Y,1) - OutData%Y(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO + DO i1 = LBOUND(OutData%BladeRootLoad,1), UBOUND(OutData%BladeRootLoad,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%BladeRootLoad(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeRootLoad + 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 ! M not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! B_L_2_R_P not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - 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%B_L_2_R_P)) DEALLOCATE(OutData%B_L_2_R_P) + ALLOCATE(OutData%B_L_2_R_P(i1_l:i1_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%B_L_2_R_P.', 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) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - i1_l = LBOUND(OutData%V_DiskAvg,1) - i1_u = UBOUND(OutData%V_DiskAvg,1) - DO i1 = LBOUND(OutData%V_DiskAvg,1), UBOUND(OutData%V_DiskAvg,1) - OutData%V_DiskAvg(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(OutData%B_L_2_R_P,1), UBOUND(OutData%B_L_2_R_P,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%B_L_2_R_P(i1), ErrStat2, ErrMsg2 ) ! B_L_2_R_P + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! hub_theta_x_root not allocated + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeBuoyLoadPoint not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%hub_theta_x_root)) DEALLOCATE(OutData%hub_theta_x_root) - ALLOCATE(OutData%hub_theta_x_root(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%BladeBuoyLoadPoint)) DEALLOCATE(OutData%BladeBuoyLoadPoint) + ALLOCATE(OutData%BladeBuoyLoadPoint(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%hub_theta_x_root.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeBuoyLoadPoint.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%hub_theta_x_root,1), UBOUND(OutData%hub_theta_x_root,1) - OutData%hub_theta_x_root(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - OutData%V_dot_x = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(OutData%BladeBuoyLoadPoint,1), UBOUND(OutData%BladeBuoyLoadPoint,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -9143,27 +12288,29 @@ SUBROUTINE AD_UnPackRotMiscVarType( 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%HubLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! HubLoad + CALL MeshUnpack( OutData%BladeBuoyLoadPoint(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeBuoyLoadPoint 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 ! B_L_2_H_P not allocated + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeBuoyLoad not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%B_L_2_H_P)) DEALLOCATE(OutData%B_L_2_H_P) - ALLOCATE(OutData%B_L_2_H_P(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%BladeBuoyLoad)) DEALLOCATE(OutData%BladeBuoyLoad) + ALLOCATE(OutData%BladeBuoyLoad(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%B_L_2_H_P.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeBuoyLoad.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%B_L_2_H_P,1), UBOUND(OutData%B_L_2_H_P,1) + DO i1 = LBOUND(OutData%BladeBuoyLoad,1), UBOUND(OutData%BladeBuoyLoad,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -9197,7 +12344,7 @@ SUBROUTINE AD_UnPackRotMiscVarType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat 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%B_L_2_H_P(i1), ErrStat2, ErrMsg2 ) ! B_L_2_H_P + CALL MeshUnpack( OutData%BladeBuoyLoad(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeBuoyLoad CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -9206,89 +12353,20 @@ SUBROUTINE AD_UnPackRotMiscVarType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SigmaCavitCrit not allocated - Int_Xferred = Int_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%SigmaCavitCrit)) DEALLOCATE(OutData%SigmaCavitCrit) - ALLOCATE(OutData%SigmaCavitCrit(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SigmaCavitCrit.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%SigmaCavitCrit,2), UBOUND(OutData%SigmaCavitCrit,2) - DO i1 = LBOUND(OutData%SigmaCavitCrit,1), UBOUND(OutData%SigmaCavitCrit,1) - OutData%SigmaCavitCrit(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SigmaCavit not allocated - Int_Xferred = Int_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%SigmaCavit)) DEALLOCATE(OutData%SigmaCavit) - ALLOCATE(OutData%SigmaCavit(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%SigmaCavit.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%SigmaCavit,2), UBOUND(OutData%SigmaCavit,2) - DO i1 = LBOUND(OutData%SigmaCavit,1), UBOUND(OutData%SigmaCavit,1) - OutData%SigmaCavit(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CavitWarnSet not allocated - Int_Xferred = Int_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%CavitWarnSet)) DEALLOCATE(OutData%CavitWarnSet) - ALLOCATE(OutData%CavitWarnSet(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CavitWarnSet.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%CavitWarnSet,2), UBOUND(OutData%CavitWarnSet,2) - DO i1 = LBOUND(OutData%CavitWarnSet,1), UBOUND(OutData%CavitWarnSet,1) - OutData%CavitWarnSet(i1,i2) = TRANSFER(IntKiBuf(Int_Xferred), OutData%CavitWarnSet(i1,i2)) - Int_Xferred = Int_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeRootLoad not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! B_P_2_B_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%BladeRootLoad)) DEALLOCATE(OutData%BladeRootLoad) - ALLOCATE(OutData%BladeRootLoad(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%B_P_2_B_L)) DEALLOCATE(OutData%B_P_2_B_L) + ALLOCATE(OutData%B_P_2_B_L(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeRootLoad.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%B_P_2_B_L.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%BladeRootLoad,1), UBOUND(OutData%BladeRootLoad,1) + DO i1 = LBOUND(OutData%B_P_2_B_L,1), UBOUND(OutData%B_P_2_B_L,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -9322,7 +12400,7 @@ SUBROUTINE AD_UnPackRotMiscVarType( 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%BladeRootLoad(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeRootLoad + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%B_P_2_B_L(i1), ErrStat2, ErrMsg2 ) ! B_P_2_B_L CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -9331,20 +12409,6 @@ SUBROUTINE AD_UnPackRotMiscVarType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! B_L_2_R_P not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%B_L_2_R_P)) DEALLOCATE(OutData%B_L_2_R_P) - ALLOCATE(OutData%B_L_2_R_P(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%B_L_2_R_P.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%B_L_2_R_P,1), UBOUND(OutData%B_L_2_R_P,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -9378,15 +12442,149 @@ SUBROUTINE AD_UnPackRotMiscVarType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat 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%B_L_2_R_P(i1), ErrStat2, ErrMsg2 ) ! B_L_2_R_P + CALL MeshUnpack( OutData%TwrBuoyLoadPoint, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! TwrBuoyLoadPoint + 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%TwrBuoyLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! TwrBuoyLoad + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%T_P_2_T_L, ErrStat2, ErrMsg2 ) ! T_P_2_T_L CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + OutData%FirstWarn_TowerStrike = TRANSFER(IntKiBuf(Int_Xferred), OutData%FirstWarn_TowerStrike) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%AvgDiskVel,1) + i1_u = UBOUND(OutData%AvgDiskVel,1) + DO i1 = LBOUND(OutData%AvgDiskVel,1), UBOUND(OutData%AvgDiskVel,1) + OutData%AvgDiskVel(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%AvgDiskVelDist,1) + i1_u = UBOUND(OutData%AvgDiskVelDist,1) + DO i1 = LBOUND(OutData%AvgDiskVelDist,1), UBOUND(OutData%AvgDiskVelDist,1) + OutData%AvgDiskVelDist(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%TFinAlpha = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%TFinRe = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%TFinVrel = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%TFinVund_i,1) + i1_u = UBOUND(OutData%TFinVund_i,1) + DO i1 = LBOUND(OutData%TFinVund_i,1), UBOUND(OutData%TFinVund_i,1) + OutData%TFinVund_i(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%TFinVind_i,1) + i1_u = UBOUND(OutData%TFinVind_i,1) + DO i1 = LBOUND(OutData%TFinVind_i,1), UBOUND(OutData%TFinVind_i,1) + OutData%TFinVind_i(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%TFinVrel_i,1) + i1_u = UBOUND(OutData%TFinVrel_i,1) + DO i1 = LBOUND(OutData%TFinVrel_i,1), UBOUND(OutData%TFinVrel_i,1) + OutData%TFinVrel_i(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%TFinSTV_i,1) + i1_u = UBOUND(OutData%TFinSTV_i,1) + DO i1 = LBOUND(OutData%TFinSTV_i,1), UBOUND(OutData%TFinSTV_i,1) + OutData%TFinSTV_i(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%TFinF_i,1) + i1_u = UBOUND(OutData%TFinF_i,1) + DO i1 = LBOUND(OutData%TFinF_i,1), UBOUND(OutData%TFinF_i,1) + OutData%TFinF_i(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%TFinM_i,1) + i1_u = UBOUND(OutData%TFinM_i,1) + DO i1 = LBOUND(OutData%TFinM_i,1), UBOUND(OutData%TFinM_i,1) + OutData%TFinM_i(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END DO - END IF END SUBROUTINE AD_UnPackRotMiscVarType SUBROUTINE AD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) @@ -9444,29 +12642,45 @@ SUBROUTINE AD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AD_CopyMisc - SUBROUTINE AD_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE AD_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%rotors)) THEN DO i1 = LBOUND(MiscData%rotors,1), UBOUND(MiscData%rotors,1) - CALL AD_Destroyrotmiscvartype( MiscData%rotors(i1), ErrStat, ErrMsg ) + CALL AD_Destroyrotmiscvartype( MiscData%rotors(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%rotors) ENDIF IF (ALLOCATED(MiscData%FVW_u)) THEN DO i1 = LBOUND(MiscData%FVW_u,1), UBOUND(MiscData%FVW_u,1) - CALL FVW_DestroyInput( MiscData%FVW_u(i1), ErrStat, ErrMsg ) + CALL FVW_DestroyInput( MiscData%FVW_u(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%FVW_u) ENDIF - CALL FVW_DestroyOutput( MiscData%FVW_y, ErrStat, ErrMsg ) - CALL FVW_DestroyMisc( MiscData%FVW, ErrStat, ErrMsg ) + CALL FVW_DestroyOutput( MiscData%FVW_y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FVW_DestroyMisc( MiscData%FVW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD_DestroyMisc SUBROUTINE AD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -9998,35 +13212,199 @@ SUBROUTINE AD_CopyRotParameterType( SrcRotParameterTypeData, DstRotParameterType IF (.NOT. ALLOCATED(DstRotParameterTypeData%TwrDiam)) THEN ALLOCATE(DstRotParameterTypeData%TwrDiam(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%TwrDiam.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%TwrDiam.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotParameterTypeData%TwrDiam = SrcRotParameterTypeData%TwrDiam +ENDIF +IF (ALLOCATED(SrcRotParameterTypeData%TwrCd)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%TwrCd,1) + i1_u = UBOUND(SrcRotParameterTypeData%TwrCd,1) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%TwrCd)) THEN + ALLOCATE(DstRotParameterTypeData%TwrCd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%TwrCd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotParameterTypeData%TwrCd = SrcRotParameterTypeData%TwrCd +ENDIF +IF (ALLOCATED(SrcRotParameterTypeData%TwrTI)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%TwrTI,1) + i1_u = UBOUND(SrcRotParameterTypeData%TwrTI,1) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%TwrTI)) THEN + ALLOCATE(DstRotParameterTypeData%TwrTI(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%TwrTI.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotParameterTypeData%TwrTI = SrcRotParameterTypeData%TwrTI +ENDIF +IF (ALLOCATED(SrcRotParameterTypeData%BlTwist)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%BlTwist,1) + i1_u = UBOUND(SrcRotParameterTypeData%BlTwist,1) + i2_l = LBOUND(SrcRotParameterTypeData%BlTwist,2) + i2_u = UBOUND(SrcRotParameterTypeData%BlTwist,2) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%BlTwist)) THEN + ALLOCATE(DstRotParameterTypeData%BlTwist(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%BlTwist.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotParameterTypeData%BlTwist = SrcRotParameterTypeData%BlTwist +ENDIF +IF (ALLOCATED(SrcRotParameterTypeData%TwrCb)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%TwrCb,1) + i1_u = UBOUND(SrcRotParameterTypeData%TwrCb,1) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%TwrCb)) THEN + ALLOCATE(DstRotParameterTypeData%TwrCb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%TwrCb.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstRotParameterTypeData%TwrDiam = SrcRotParameterTypeData%TwrDiam + DstRotParameterTypeData%TwrCb = SrcRotParameterTypeData%TwrCb ENDIF -IF (ALLOCATED(SrcRotParameterTypeData%TwrCd)) THEN - i1_l = LBOUND(SrcRotParameterTypeData%TwrCd,1) - i1_u = UBOUND(SrcRotParameterTypeData%TwrCd,1) - IF (.NOT. ALLOCATED(DstRotParameterTypeData%TwrCd)) THEN - ALLOCATE(DstRotParameterTypeData%TwrCd(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRotParameterTypeData%BlCenBn)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%BlCenBn,1) + i1_u = UBOUND(SrcRotParameterTypeData%BlCenBn,1) + i2_l = LBOUND(SrcRotParameterTypeData%BlCenBn,2) + i2_u = UBOUND(SrcRotParameterTypeData%BlCenBn,2) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%BlCenBn)) THEN + ALLOCATE(DstRotParameterTypeData%BlCenBn(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%TwrCd.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%BlCenBn.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstRotParameterTypeData%TwrCd = SrcRotParameterTypeData%TwrCd + DstRotParameterTypeData%BlCenBn = SrcRotParameterTypeData%BlCenBn ENDIF -IF (ALLOCATED(SrcRotParameterTypeData%TwrTI)) THEN - i1_l = LBOUND(SrcRotParameterTypeData%TwrTI,1) - i1_u = UBOUND(SrcRotParameterTypeData%TwrTI,1) - IF (.NOT. ALLOCATED(DstRotParameterTypeData%TwrTI)) THEN - ALLOCATE(DstRotParameterTypeData%TwrTI(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRotParameterTypeData%BlCenBt)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%BlCenBt,1) + i1_u = UBOUND(SrcRotParameterTypeData%BlCenBt,1) + i2_l = LBOUND(SrcRotParameterTypeData%BlCenBt,2) + i2_u = UBOUND(SrcRotParameterTypeData%BlCenBt,2) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%BlCenBt)) THEN + ALLOCATE(DstRotParameterTypeData%BlCenBt(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%TwrTI.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%BlCenBt.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstRotParameterTypeData%TwrTI = SrcRotParameterTypeData%TwrTI + DstRotParameterTypeData%BlCenBt = SrcRotParameterTypeData%BlCenBt +ENDIF + DstRotParameterTypeData%VolHub = SrcRotParameterTypeData%VolHub + DstRotParameterTypeData%HubCenBx = SrcRotParameterTypeData%HubCenBx + DstRotParameterTypeData%VolNac = SrcRotParameterTypeData%VolNac + DstRotParameterTypeData%NacCenB = SrcRotParameterTypeData%NacCenB + DstRotParameterTypeData%VolBl = SrcRotParameterTypeData%VolBl + DstRotParameterTypeData%VolTwr = SrcRotParameterTypeData%VolTwr +IF (ALLOCATED(SrcRotParameterTypeData%BlRad)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%BlRad,1) + i1_u = UBOUND(SrcRotParameterTypeData%BlRad,1) + i2_l = LBOUND(SrcRotParameterTypeData%BlRad,2) + i2_u = UBOUND(SrcRotParameterTypeData%BlRad,2) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%BlRad)) THEN + ALLOCATE(DstRotParameterTypeData%BlRad(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%BlRad.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotParameterTypeData%BlRad = SrcRotParameterTypeData%BlRad +ENDIF +IF (ALLOCATED(SrcRotParameterTypeData%BlDL)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%BlDL,1) + i1_u = UBOUND(SrcRotParameterTypeData%BlDL,1) + i2_l = LBOUND(SrcRotParameterTypeData%BlDL,2) + i2_u = UBOUND(SrcRotParameterTypeData%BlDL,2) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%BlDL)) THEN + ALLOCATE(DstRotParameterTypeData%BlDL(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%BlDL.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotParameterTypeData%BlDL = SrcRotParameterTypeData%BlDL +ENDIF +IF (ALLOCATED(SrcRotParameterTypeData%BlTaper)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%BlTaper,1) + i1_u = UBOUND(SrcRotParameterTypeData%BlTaper,1) + i2_l = LBOUND(SrcRotParameterTypeData%BlTaper,2) + i2_u = UBOUND(SrcRotParameterTypeData%BlTaper,2) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%BlTaper)) THEN + ALLOCATE(DstRotParameterTypeData%BlTaper(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%BlTaper.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotParameterTypeData%BlTaper = SrcRotParameterTypeData%BlTaper +ENDIF +IF (ALLOCATED(SrcRotParameterTypeData%BlAxCent)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%BlAxCent,1) + i1_u = UBOUND(SrcRotParameterTypeData%BlAxCent,1) + i2_l = LBOUND(SrcRotParameterTypeData%BlAxCent,2) + i2_u = UBOUND(SrcRotParameterTypeData%BlAxCent,2) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%BlAxCent)) THEN + ALLOCATE(DstRotParameterTypeData%BlAxCent(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%BlAxCent.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotParameterTypeData%BlAxCent = SrcRotParameterTypeData%BlAxCent +ENDIF +IF (ALLOCATED(SrcRotParameterTypeData%TwrRad)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%TwrRad,1) + i1_u = UBOUND(SrcRotParameterTypeData%TwrRad,1) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%TwrRad)) THEN + ALLOCATE(DstRotParameterTypeData%TwrRad(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%TwrRad.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotParameterTypeData%TwrRad = SrcRotParameterTypeData%TwrRad +ENDIF +IF (ALLOCATED(SrcRotParameterTypeData%TwrDL)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%TwrDL,1) + i1_u = UBOUND(SrcRotParameterTypeData%TwrDL,1) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%TwrDL)) THEN + ALLOCATE(DstRotParameterTypeData%TwrDL(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%TwrDL.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotParameterTypeData%TwrDL = SrcRotParameterTypeData%TwrDL +ENDIF +IF (ALLOCATED(SrcRotParameterTypeData%TwrTaper)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%TwrTaper,1) + i1_u = UBOUND(SrcRotParameterTypeData%TwrTaper,1) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%TwrTaper)) THEN + ALLOCATE(DstRotParameterTypeData%TwrTaper(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%TwrTaper.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotParameterTypeData%TwrTaper = SrcRotParameterTypeData%TwrTaper +ENDIF +IF (ALLOCATED(SrcRotParameterTypeData%TwrAxCent)) THEN + i1_l = LBOUND(SrcRotParameterTypeData%TwrAxCent,1) + i1_u = UBOUND(SrcRotParameterTypeData%TwrAxCent,1) + IF (.NOT. ALLOCATED(DstRotParameterTypeData%TwrAxCent)) THEN + ALLOCATE(DstRotParameterTypeData%TwrAxCent(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRotParameterTypeData%TwrAxCent.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRotParameterTypeData%TwrAxCent = SrcRotParameterTypeData%TwrAxCent ENDIF CALL BEMT_CopyParam( SrcRotParameterTypeData%BEMT, DstRotParameterTypeData%BEMT, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) @@ -10073,11 +13451,14 @@ SUBROUTINE AD_CopyRotParameterType( SrcRotParameterTypeData, DstRotParameterType DstRotParameterTypeData%dx = SrcRotParameterTypeData%dx ENDIF DstRotParameterTypeData%Jac_ny = SrcRotParameterTypeData%Jac_ny + DstRotParameterTypeData%NumBl_Lin = SrcRotParameterTypeData%NumBl_Lin DstRotParameterTypeData%TwrPotent = SrcRotParameterTypeData%TwrPotent DstRotParameterTypeData%TwrShadow = SrcRotParameterTypeData%TwrShadow DstRotParameterTypeData%TwrAero = SrcRotParameterTypeData%TwrAero DstRotParameterTypeData%FrozenWake = SrcRotParameterTypeData%FrozenWake DstRotParameterTypeData%CavitCheck = SrcRotParameterTypeData%CavitCheck + DstRotParameterTypeData%Buoyancy = SrcRotParameterTypeData%Buoyancy + DstRotParameterTypeData%MHK = SrcRotParameterTypeData%MHK DstRotParameterTypeData%CompAA = SrcRotParameterTypeData%CompAA DstRotParameterTypeData%AirDens = SrcRotParameterTypeData%AirDens DstRotParameterTypeData%KinVisc = SrcRotParameterTypeData%KinVisc @@ -10088,6 +13469,7 @@ SUBROUTINE AD_CopyRotParameterType( SrcRotParameterTypeData, DstRotParameterType DstRotParameterTypeData%WtrDpth = SrcRotParameterTypeData%WtrDpth DstRotParameterTypeData%MSL2SWL = SrcRotParameterTypeData%MSL2SWL DstRotParameterTypeData%AeroProjMod = SrcRotParameterTypeData%AeroProjMod + DstRotParameterTypeData%AeroBEM_Mod = SrcRotParameterTypeData%AeroBEM_Mod DstRotParameterTypeData%NumOuts = SrcRotParameterTypeData%NumOuts DstRotParameterTypeData%RootName = SrcRotParameterTypeData%RootName IF (ALLOCATED(SrcRotParameterTypeData%OutParam)) THEN @@ -10141,17 +13523,33 @@ SUBROUTINE AD_CopyRotParameterType( SrcRotParameterTypeData, DstRotParameterType DstRotParameterTypeData%BldNd_BlOutNd = SrcRotParameterTypeData%BldNd_BlOutNd ENDIF DstRotParameterTypeData%BldNd_BladesOut = SrcRotParameterTypeData%BldNd_BladesOut + DstRotParameterTypeData%TFinAero = SrcRotParameterTypeData%TFinAero + CALL AD_Copytfinparametertype( SrcRotParameterTypeData%TFin, DstRotParameterTypeData%TFin, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AD_CopyRotParameterType - SUBROUTINE AD_DestroyRotParameterType( RotParameterTypeData, ErrStat, ErrMsg ) + SUBROUTINE AD_DestroyRotParameterType( RotParameterTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(RotParameterType), INTENT(INOUT) :: RotParameterTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotParameterType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotParameterType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(RotParameterTypeData%TwrDiam)) THEN DEALLOCATE(RotParameterTypeData%TwrDiam) ENDIF @@ -10161,8 +13559,46 @@ SUBROUTINE AD_DestroyRotParameterType( RotParameterTypeData, ErrStat, ErrMsg ) IF (ALLOCATED(RotParameterTypeData%TwrTI)) THEN DEALLOCATE(RotParameterTypeData%TwrTI) ENDIF - CALL BEMT_DestroyParam( RotParameterTypeData%BEMT, ErrStat, ErrMsg ) - CALL AA_DestroyParam( RotParameterTypeData%AA, ErrStat, ErrMsg ) +IF (ALLOCATED(RotParameterTypeData%BlTwist)) THEN + DEALLOCATE(RotParameterTypeData%BlTwist) +ENDIF +IF (ALLOCATED(RotParameterTypeData%TwrCb)) THEN + DEALLOCATE(RotParameterTypeData%TwrCb) +ENDIF +IF (ALLOCATED(RotParameterTypeData%BlCenBn)) THEN + DEALLOCATE(RotParameterTypeData%BlCenBn) +ENDIF +IF (ALLOCATED(RotParameterTypeData%BlCenBt)) THEN + DEALLOCATE(RotParameterTypeData%BlCenBt) +ENDIF +IF (ALLOCATED(RotParameterTypeData%BlRad)) THEN + DEALLOCATE(RotParameterTypeData%BlRad) +ENDIF +IF (ALLOCATED(RotParameterTypeData%BlDL)) THEN + DEALLOCATE(RotParameterTypeData%BlDL) +ENDIF +IF (ALLOCATED(RotParameterTypeData%BlTaper)) THEN + DEALLOCATE(RotParameterTypeData%BlTaper) +ENDIF +IF (ALLOCATED(RotParameterTypeData%BlAxCent)) THEN + DEALLOCATE(RotParameterTypeData%BlAxCent) +ENDIF +IF (ALLOCATED(RotParameterTypeData%TwrRad)) THEN + DEALLOCATE(RotParameterTypeData%TwrRad) +ENDIF +IF (ALLOCATED(RotParameterTypeData%TwrDL)) THEN + DEALLOCATE(RotParameterTypeData%TwrDL) +ENDIF +IF (ALLOCATED(RotParameterTypeData%TwrTaper)) THEN + DEALLOCATE(RotParameterTypeData%TwrTaper) +ENDIF +IF (ALLOCATED(RotParameterTypeData%TwrAxCent)) THEN + DEALLOCATE(RotParameterTypeData%TwrAxCent) +ENDIF + CALL BEMT_DestroyParam( RotParameterTypeData%BEMT, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AA_DestroyParam( RotParameterTypeData%AA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(RotParameterTypeData%Jac_u_indx)) THEN DEALLOCATE(RotParameterTypeData%Jac_u_indx) ENDIF @@ -10174,19 +13610,23 @@ SUBROUTINE AD_DestroyRotParameterType( RotParameterTypeData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(RotParameterTypeData%OutParam)) THEN DO i1 = LBOUND(RotParameterTypeData%OutParam,1), UBOUND(RotParameterTypeData%OutParam,1) - CALL NWTC_Library_Destroyoutparmtype( RotParameterTypeData%OutParam(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyoutparmtype( RotParameterTypeData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(RotParameterTypeData%OutParam) ENDIF IF (ALLOCATED(RotParameterTypeData%BldNd_OutParam)) THEN DO i1 = LBOUND(RotParameterTypeData%BldNd_OutParam,1), UBOUND(RotParameterTypeData%BldNd_OutParam,1) - CALL NWTC_Library_Destroyoutparmtype( RotParameterTypeData%BldNd_OutParam(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyoutparmtype( RotParameterTypeData%BldNd_OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(RotParameterTypeData%BldNd_OutParam) ENDIF IF (ALLOCATED(RotParameterTypeData%BldNd_BlOutNd)) THEN DEALLOCATE(RotParameterTypeData%BldNd_BlOutNd) ENDIF + CALL AD_Destroytfinparametertype( RotParameterTypeData%TFin, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD_DestroyRotParameterType SUBROUTINE AD_PackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -10241,6 +13681,72 @@ SUBROUTINE AD_PackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, 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 ! BlTwist allocated yes/no + IF ( ALLOCATED(InData%BlTwist) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! BlTwist upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlTwist) ! BlTwist + END IF + Int_BufSz = Int_BufSz + 1 ! TwrCb allocated yes/no + IF ( ALLOCATED(InData%TwrCb) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrCb upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrCb) ! TwrCb + END IF + Int_BufSz = Int_BufSz + 1 ! BlCenBn allocated yes/no + IF ( ALLOCATED(InData%BlCenBn) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! BlCenBn upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlCenBn) ! BlCenBn + END IF + Int_BufSz = Int_BufSz + 1 ! BlCenBt allocated yes/no + IF ( ALLOCATED(InData%BlCenBt) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! BlCenBt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlCenBt) ! BlCenBt + END IF + Re_BufSz = Re_BufSz + 1 ! VolHub + Re_BufSz = Re_BufSz + 1 ! HubCenBx + Re_BufSz = Re_BufSz + 1 ! VolNac + Re_BufSz = Re_BufSz + SIZE(InData%NacCenB) ! NacCenB + Re_BufSz = Re_BufSz + 1 ! VolBl + Re_BufSz = Re_BufSz + 1 ! VolTwr + Int_BufSz = Int_BufSz + 1 ! BlRad allocated yes/no + IF ( ALLOCATED(InData%BlRad) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! BlRad upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlRad) ! BlRad + END IF + Int_BufSz = Int_BufSz + 1 ! BlDL allocated yes/no + IF ( ALLOCATED(InData%BlDL) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! BlDL upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlDL) ! BlDL + END IF + Int_BufSz = Int_BufSz + 1 ! BlTaper allocated yes/no + IF ( ALLOCATED(InData%BlTaper) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! BlTaper upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlTaper) ! BlTaper + END IF + Int_BufSz = Int_BufSz + 1 ! BlAxCent allocated yes/no + IF ( ALLOCATED(InData%BlAxCent) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! BlAxCent upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BlAxCent) ! BlAxCent + END IF + Int_BufSz = Int_BufSz + 1 ! TwrRad allocated yes/no + IF ( ALLOCATED(InData%TwrRad) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrRad upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrRad) ! TwrRad + END IF + Int_BufSz = Int_BufSz + 1 ! TwrDL allocated yes/no + IF ( ALLOCATED(InData%TwrDL) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrDL upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrDL) ! TwrDL + END IF + Int_BufSz = Int_BufSz + 1 ! TwrTaper allocated yes/no + IF ( ALLOCATED(InData%TwrTaper) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrTaper upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrTaper) ! TwrTaper + END IF + Int_BufSz = Int_BufSz + 1 ! TwrAxCent allocated yes/no + IF ( ALLOCATED(InData%TwrAxCent) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! TwrAxCent upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TwrAxCent) ! TwrAxCent END IF ! Allocate buffers for subtypes, if any (we'll get sizes from these) Int_BufSz = Int_BufSz + 3 ! BEMT: size of buffers for each call to pack subtype @@ -10293,11 +13799,14 @@ SUBROUTINE AD_PackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_BufSz = Re_BufSz + SIZE(InData%dx) ! dx END IF Int_BufSz = Int_BufSz + 1 ! Jac_ny + Int_BufSz = Int_BufSz + 1 ! NumBl_Lin Int_BufSz = Int_BufSz + 1 ! TwrPotent Int_BufSz = Int_BufSz + 1 ! TwrShadow Int_BufSz = Int_BufSz + 1 ! TwrAero Int_BufSz = Int_BufSz + 1 ! FrozenWake Int_BufSz = Int_BufSz + 1 ! CavitCheck + Int_BufSz = Int_BufSz + 1 ! Buoyancy + Int_BufSz = Int_BufSz + 1 ! MHK Int_BufSz = Int_BufSz + 1 ! CompAA Re_BufSz = Re_BufSz + 1 ! AirDens Re_BufSz = Re_BufSz + 1 ! KinVisc @@ -10308,6 +13817,7 @@ SUBROUTINE AD_PackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_BufSz = Re_BufSz + 1 ! WtrDpth Re_BufSz = Re_BufSz + 1 ! MSL2SWL Int_BufSz = Int_BufSz + 1 ! AeroProjMod + Int_BufSz = Int_BufSz + 1 ! AeroBEM_Mod Int_BufSz = Int_BufSz + 1 ! NumOuts Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName Int_BufSz = Int_BufSz + 1 ! OutParam allocated yes/no @@ -10368,6 +13878,24 @@ SUBROUTINE AD_PackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE(InData%BldNd_BlOutNd) ! BldNd_BlOutNd END IF Int_BufSz = Int_BufSz + 1 ! BldNd_BladesOut + Int_BufSz = Int_BufSz + 1 ! TFinAero + Int_BufSz = Int_BufSz + 3 ! TFin: size of buffers for each call to pack subtype + CALL AD_Packtfinparametertype( Re_Buf, Db_Buf, Int_Buf, InData%TFin, ErrStat2, ErrMsg2, .TRUE. ) ! TFin + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! TFin + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! TFin + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! TFin + 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 @@ -10407,42 +13935,271 @@ SUBROUTINE AD_PackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrDiam,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrDiam,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrDiam,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrDiam,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrDiam,1), UBOUND(InData%TwrDiam,1) + ReKiBuf(Re_Xferred) = InData%TwrDiam(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%TwrCd) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrCd,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrCd,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrCd,1), UBOUND(InData%TwrCd,1) + 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 + IF ( .NOT. ALLOCATED(InData%BlTwist) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlTwist,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlTwist,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlTwist,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlTwist,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BlTwist,2), UBOUND(InData%BlTwist,2) + DO i1 = LBOUND(InData%BlTwist,1), UBOUND(InData%BlTwist,1) + ReKiBuf(Re_Xferred) = InData%BlTwist(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%TwrCb) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrCb,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrCb,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrCb,1), UBOUND(InData%TwrCb,1) + ReKiBuf(Re_Xferred) = InData%TwrCb(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BlCenBn) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlCenBn,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlCenBn,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlCenBn,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlCenBn,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BlCenBn,2), UBOUND(InData%BlCenBn,2) + DO i1 = LBOUND(InData%BlCenBn,1), UBOUND(InData%BlCenBn,1) + ReKiBuf(Re_Xferred) = InData%BlCenBn(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BlCenBt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlCenBt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlCenBt,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlCenBt,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlCenBt,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BlCenBt,2), UBOUND(InData%BlCenBt,2) + DO i1 = LBOUND(InData%BlCenBt,1), UBOUND(InData%BlCenBt,1) + ReKiBuf(Re_Xferred) = InData%BlCenBt(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + ReKiBuf(Re_Xferred) = InData%VolHub + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%HubCenBx + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VolNac + Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%NacCenB,1), UBOUND(InData%NacCenB,1) + ReKiBuf(Re_Xferred) = InData%NacCenB(i1) + Re_Xferred = Re_Xferred + 1 + END DO + ReKiBuf(Re_Xferred) = InData%VolBl + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VolTwr + Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%BlRad) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlRad,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlRad,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlRad,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlRad,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BlRad,2), UBOUND(InData%BlRad,2) + DO i1 = LBOUND(InData%BlRad,1), UBOUND(InData%BlRad,1) + ReKiBuf(Re_Xferred) = InData%BlRad(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BlDL) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlDL,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlDL,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlDL,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlDL,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BlDL,2), UBOUND(InData%BlDL,2) + DO i1 = LBOUND(InData%BlDL,1), UBOUND(InData%BlDL,1) + ReKiBuf(Re_Xferred) = InData%BlDL(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BlTaper) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlTaper,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlTaper,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlTaper,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlTaper,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BlTaper,2), UBOUND(InData%BlTaper,2) + DO i1 = LBOUND(InData%BlTaper,1), UBOUND(InData%BlTaper,1) + ReKiBuf(Re_Xferred) = InData%BlTaper(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BlAxCent) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlAxCent,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlAxCent,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BlAxCent,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BlAxCent,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BlAxCent,2), UBOUND(InData%BlAxCent,2) + DO i1 = LBOUND(InData%BlAxCent,1), UBOUND(InData%BlAxCent,1) + ReKiBuf(Re_Xferred) = InData%BlAxCent(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%TwrRad) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrRad,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrRad,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%TwrRad,1), UBOUND(InData%TwrRad,1) + ReKiBuf(Re_Xferred) = InData%TwrRad(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%TwrDL) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrDL,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrDL,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%TwrDiam,1), UBOUND(InData%TwrDiam,1) - ReKiBuf(Re_Xferred) = InData%TwrDiam(i1) + DO i1 = LBOUND(InData%TwrDL,1), UBOUND(InData%TwrDL,1) + ReKiBuf(Re_Xferred) = InData%TwrDL(i1) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%TwrCd) ) THEN + IF ( .NOT. ALLOCATED(InData%TwrTaper) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrCd,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrCd,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrTaper,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrTaper,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%TwrCd,1), UBOUND(InData%TwrCd,1) - ReKiBuf(Re_Xferred) = InData%TwrCd(i1) + DO i1 = LBOUND(InData%TwrTaper,1), UBOUND(InData%TwrTaper,1) + ReKiBuf(Re_Xferred) = InData%TwrTaper(i1) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%TwrTI) ) THEN + IF ( .NOT. ALLOCATED(InData%TwrAxCent) ) THEN 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) + IntKiBuf( Int_Xferred ) = LBOUND(InData%TwrAxCent,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwrAxCent,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%TwrTI,1), UBOUND(InData%TwrTI,1) - ReKiBuf(Re_Xferred) = InData%TwrTI(i1) + DO i1 = LBOUND(InData%TwrAxCent,1), UBOUND(InData%TwrAxCent,1) + ReKiBuf(Re_Xferred) = InData%TwrAxCent(i1) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -10554,6 +14311,8 @@ SUBROUTINE AD_PackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END IF IntKiBuf(Int_Xferred) = InData%Jac_ny Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumBl_Lin + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%TwrPotent Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%TwrShadow @@ -10564,6 +14323,10 @@ SUBROUTINE AD_PackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%CavitCheck, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%Buoyancy, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%MHK + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%CompAA, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 ReKiBuf(Re_Xferred) = InData%AirDens @@ -10584,6 +14347,8 @@ SUBROUTINE AD_PackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_Xferred = Re_Xferred + 1 IntKiBuf(Int_Xferred) = InData%AeroProjMod Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%AeroBEM_Mod + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NumOuts Int_Xferred = Int_Xferred + 1 DO I = 1, LEN(InData%RootName) @@ -10692,106 +14457,403 @@ SUBROUTINE AD_PackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE - IntKiBuf( Int_Xferred ) = 1 + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BldNd_BlOutNd,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldNd_BlOutNd,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BldNd_BlOutNd,1), UBOUND(InData%BldNd_BlOutNd,1) + IntKiBuf(Int_Xferred) = InData%BldNd_BlOutNd(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IntKiBuf(Int_Xferred) = InData%BldNd_BladesOut + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%TFinAero, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + CALL AD_Packtfinparametertype( Re_Buf, Db_Buf, Int_Buf, InData%TFin, ErrStat2, ErrMsg2, OnlySize ) ! TFin + 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_PackRotParameterType + + SUBROUTINE AD_UnPackRotParameterType( 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(RotParameterType), 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 = 'AD_UnPackRotParameterType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%NumBlades = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NumBlNds = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NumTwrNds = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrDiam not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%TwrDiam)) DEALLOCATE(OutData%TwrDiam) + ALLOCATE(OutData%TwrDiam(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrDiam.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrDiam,1), UBOUND(OutData%TwrDiam,1) + OutData%TwrDiam(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrCd not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%TwrCd)) DEALLOCATE(OutData%TwrCd) + ALLOCATE(OutData%TwrCd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrCd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrCd,1), UBOUND(OutData%TwrCd,1) + 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 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlTwist not allocated + Int_Xferred = Int_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%BlTwist)) DEALLOCATE(OutData%BlTwist) + ALLOCATE(OutData%BlTwist(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlTwist.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%BlTwist,2), UBOUND(OutData%BlTwist,2) + DO i1 = LBOUND(OutData%BlTwist,1), UBOUND(OutData%BlTwist,1) + OutData%BlTwist(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrCb not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%TwrCb)) DEALLOCATE(OutData%TwrCb) + ALLOCATE(OutData%TwrCb(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrCb.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrCb,1), UBOUND(OutData%TwrCb,1) + OutData%TwrCb(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlCenBn not allocated + Int_Xferred = Int_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%BlCenBn)) DEALLOCATE(OutData%BlCenBn) + ALLOCATE(OutData%BlCenBn(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlCenBn.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%BlCenBn,2), UBOUND(OutData%BlCenBn,2) + DO i1 = LBOUND(OutData%BlCenBn,1), UBOUND(OutData%BlCenBn,1) + OutData%BlCenBn(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlCenBt not allocated + Int_Xferred = Int_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%BlCenBt)) DEALLOCATE(OutData%BlCenBt) + ALLOCATE(OutData%BlCenBt(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlCenBt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%BlCenBt,2), UBOUND(OutData%BlCenBt,2) + DO i1 = LBOUND(OutData%BlCenBt,1), UBOUND(OutData%BlCenBt,1) + OutData%BlCenBt(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + OutData%VolHub = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%HubCenBx = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VolNac = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%NacCenB,1) + i1_u = UBOUND(OutData%NacCenB,1) + DO i1 = LBOUND(OutData%NacCenB,1), UBOUND(OutData%NacCenB,1) + OutData%NacCenB(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%VolBl = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VolTwr = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlRad not allocated + Int_Xferred = Int_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%BlRad)) DEALLOCATE(OutData%BlRad) + ALLOCATE(OutData%BlRad(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlRad.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%BlRad,2), UBOUND(OutData%BlRad,2) + DO i1 = LBOUND(OutData%BlRad,1), UBOUND(OutData%BlRad,1) + OutData%BlRad(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlDL not allocated + Int_Xferred = Int_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%BlDL)) DEALLOCATE(OutData%BlDL) + ALLOCATE(OutData%BlDL(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlDL.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%BlDL,2), UBOUND(OutData%BlDL,2) + DO i1 = LBOUND(OutData%BlDL,1), UBOUND(OutData%BlDL,1) + OutData%BlDL(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlTaper not allocated + Int_Xferred = Int_Xferred + 1 + ELSE Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BldNd_BlOutNd,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BldNd_BlOutNd,1) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%BldNd_BlOutNd,1), UBOUND(InData%BldNd_BlOutNd,1) - IntKiBuf(Int_Xferred) = InData%BldNd_BlOutNd(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%BlTaper)) DEALLOCATE(OutData%BlTaper) + ALLOCATE(OutData%BlTaper(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlTaper.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%BlTaper,2), UBOUND(OutData%BlTaper,2) + DO i1 = LBOUND(OutData%BlTaper,1), UBOUND(OutData%BlTaper,1) + OutData%BlTaper(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END IF - IntKiBuf(Int_Xferred) = InData%BldNd_BladesOut + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BlAxCent not allocated Int_Xferred = Int_Xferred + 1 - END SUBROUTINE AD_PackRotParameterType - - SUBROUTINE AD_UnPackRotParameterType( 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(RotParameterType), 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 = 'AD_UnPackRotParameterType' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%NumBlades = IntKiBuf(Int_Xferred) + ELSE Int_Xferred = Int_Xferred + 1 - OutData%NumBlNds = 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%BlAxCent)) DEALLOCATE(OutData%BlAxCent) + ALLOCATE(OutData%BlAxCent(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BlAxCent.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%BlAxCent,2), UBOUND(OutData%BlAxCent,2) + DO i1 = LBOUND(OutData%BlAxCent,1), UBOUND(OutData%BlAxCent,1) + OutData%BlAxCent(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrRad not allocated Int_Xferred = Int_Xferred + 1 - OutData%NumTwrNds = IntKiBuf(Int_Xferred) + ELSE Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrDiam not allocated + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%TwrRad)) DEALLOCATE(OutData%TwrRad) + ALLOCATE(OutData%TwrRad(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrRad.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%TwrRad,1), UBOUND(OutData%TwrRad,1) + OutData%TwrRad(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrDL not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwrDiam)) DEALLOCATE(OutData%TwrDiam) - ALLOCATE(OutData%TwrDiam(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%TwrDL)) DEALLOCATE(OutData%TwrDL) + ALLOCATE(OutData%TwrDL(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrDiam.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrDL.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%TwrDiam,1), UBOUND(OutData%TwrDiam,1) - OutData%TwrDiam(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%TwrDL,1), UBOUND(OutData%TwrDL,1) + OutData%TwrDL(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrCd not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrTaper not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwrCd)) DEALLOCATE(OutData%TwrCd) - ALLOCATE(OutData%TwrCd(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%TwrTaper)) DEALLOCATE(OutData%TwrTaper) + ALLOCATE(OutData%TwrTaper(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrCd.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrTaper.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%TwrCd,1), UBOUND(OutData%TwrCd,1) - OutData%TwrCd(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%TwrTaper,1), UBOUND(OutData%TwrTaper,1) + OutData%TwrTaper(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrTI not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwrAxCent not allocated Int_Xferred = Int_Xferred + 1 ELSE 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 (ALLOCATED(OutData%TwrAxCent)) DEALLOCATE(OutData%TwrAxCent) + ALLOCATE(OutData%TwrAxCent(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrTI.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwrAxCent.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%TwrTI,1), UBOUND(OutData%TwrTI,1) - OutData%TwrTI(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%TwrAxCent,1), UBOUND(OutData%TwrAxCent,1) + OutData%TwrAxCent(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -10936,6 +14998,8 @@ SUBROUTINE AD_UnPackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt END IF OutData%Jac_ny = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + OutData%NumBl_Lin = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%TwrPotent = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%TwrShadow = IntKiBuf(Int_Xferred) @@ -10946,6 +15010,10 @@ SUBROUTINE AD_UnPackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Int_Xferred = Int_Xferred + 1 OutData%CavitCheck = TRANSFER(IntKiBuf(Int_Xferred), OutData%CavitCheck) Int_Xferred = Int_Xferred + 1 + OutData%Buoyancy = TRANSFER(IntKiBuf(Int_Xferred), OutData%Buoyancy) + Int_Xferred = Int_Xferred + 1 + OutData%MHK = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%CompAA = TRANSFER(IntKiBuf(Int_Xferred), OutData%CompAA) Int_Xferred = Int_Xferred + 1 OutData%AirDens = ReKiBuf(Re_Xferred) @@ -10966,6 +15034,8 @@ SUBROUTINE AD_UnPackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Re_Xferred = Re_Xferred + 1 OutData%AeroProjMod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + OutData%AeroBEM_Mod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%NumOuts = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 DO I = 1, LEN(OutData%RootName) @@ -11124,6 +15194,48 @@ SUBROUTINE AD_UnPackRotParameterType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt END IF OutData%BldNd_BladesOut = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + OutData%TFinAero = TRANSFER(IntKiBuf(Int_Xferred), OutData%TFinAero) + 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 AD_Unpacktfinparametertype( Re_Buf, Db_Buf, Int_Buf, OutData%TFin, ErrStat2, ErrMsg2 ) ! TFin + 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_UnPackRotParameterType SUBROUTINE AD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) @@ -11180,31 +15292,47 @@ SUBROUTINE AD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) CALL FVW_CopyParam( SrcParamData%FVW, DstParamData%FVW, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + DstParamData%CompAeroMaps = SrcParamData%CompAeroMaps DstParamData%UA_Flag = SrcParamData%UA_Flag END SUBROUTINE AD_CopyParam - SUBROUTINE AD_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE AD_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%rotors)) THEN DO i1 = LBOUND(ParamData%rotors,1), UBOUND(ParamData%rotors,1) - CALL AD_Destroyrotparametertype( ParamData%rotors(i1), ErrStat, ErrMsg ) + CALL AD_Destroyrotparametertype( ParamData%rotors(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%rotors) ENDIF IF (ALLOCATED(ParamData%AFI)) THEN DO i1 = LBOUND(ParamData%AFI,1), UBOUND(ParamData%AFI,1) - CALL AFI_DestroyParam( ParamData%AFI(i1), ErrStat, ErrMsg ) + CALL AFI_DestroyParam( ParamData%AFI(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%AFI) ENDIF - CALL FVW_DestroyParam( ParamData%FVW, ErrStat, ErrMsg ) + CALL FVW_DestroyParam( ParamData%FVW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD_DestroyParam SUBROUTINE AD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -11310,6 +15438,7 @@ SUBROUTINE AD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 1 ! CompAeroMaps Int_BufSz = Int_BufSz + 1 ! UA_Flag IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -11458,6 +15587,8 @@ SUBROUTINE AD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + IntKiBuf(Int_Xferred) = TRANSFER(InData%CompAeroMaps, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%UA_Flag, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 END SUBROUTINE AD_PackParam @@ -11651,6 +15782,8 @@ SUBROUTINE AD_UnPackParam( 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) + OutData%CompAeroMaps = TRANSFER(IntKiBuf(Int_Xferred), OutData%CompAeroMaps) + Int_Xferred = Int_Xferred + 1 OutData%UA_Flag = TRANSFER(IntKiBuf(Int_Xferred), OutData%UA_Flag) Int_Xferred = Int_Xferred + 1 END SUBROUTINE AD_UnPackParam @@ -11713,6 +15846,9 @@ SUBROUTINE AD_CopyRotInputType( SrcRotInputTypeData, DstRotInputTypeData, CtrlCo IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF + CALL MeshCopy( SrcRotInputTypeData%TFinMotion, DstRotInputTypeData%TFinMotion, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN IF (ALLOCATED(SrcRotInputTypeData%InflowOnBlade)) THEN i1_l = LBOUND(SrcRotInputTypeData%InflowOnBlade,1) i1_u = UBOUND(SrcRotInputTypeData%InflowOnBlade,1) @@ -11743,7 +15879,9 @@ SUBROUTINE AD_CopyRotInputType( SrcRotInputTypeData, DstRotInputTypeData, CtrlCo END IF DstRotInputTypeData%InflowOnTower = SrcRotInputTypeData%InflowOnTower ENDIF + DstRotInputTypeData%InflowOnHub = SrcRotInputTypeData%InflowOnHub DstRotInputTypeData%InflowOnNacelle = SrcRotInputTypeData%InflowOnNacelle + DstRotInputTypeData%InflowOnTailFin = SrcRotInputTypeData%InflowOnTailFin IF (ALLOCATED(SrcRotInputTypeData%UserProp)) THEN i1_l = LBOUND(SrcRotInputTypeData%UserProp,1) i1_u = UBOUND(SrcRotInputTypeData%UserProp,1) @@ -11760,30 +15898,49 @@ SUBROUTINE AD_CopyRotInputType( SrcRotInputTypeData, DstRotInputTypeData, CtrlCo ENDIF END SUBROUTINE AD_CopyRotInputType - SUBROUTINE AD_DestroyRotInputType( RotInputTypeData, ErrStat, ErrMsg ) + SUBROUTINE AD_DestroyRotInputType( RotInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(RotInputType), INTENT(INOUT) :: RotInputTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotInputType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotInputType' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( RotInputTypeData%NacelleMotion, ErrStat, ErrMsg ) - CALL MeshDestroy( RotInputTypeData%TowerMotion, ErrStat, ErrMsg ) - CALL MeshDestroy( RotInputTypeData%HubMotion, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( RotInputTypeData%NacelleMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( RotInputTypeData%TowerMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( RotInputTypeData%HubMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(RotInputTypeData%BladeRootMotion)) THEN DO i1 = LBOUND(RotInputTypeData%BladeRootMotion,1), UBOUND(RotInputTypeData%BladeRootMotion,1) - CALL MeshDestroy( RotInputTypeData%BladeRootMotion(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( RotInputTypeData%BladeRootMotion(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(RotInputTypeData%BladeRootMotion) ENDIF IF (ALLOCATED(RotInputTypeData%BladeMotion)) THEN DO i1 = LBOUND(RotInputTypeData%BladeMotion,1), UBOUND(RotInputTypeData%BladeMotion,1) - CALL MeshDestroy( RotInputTypeData%BladeMotion(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( RotInputTypeData%BladeMotion(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(RotInputTypeData%BladeMotion) ENDIF + CALL MeshDestroy( RotInputTypeData%TFinMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(RotInputTypeData%InflowOnBlade)) THEN DEALLOCATE(RotInputTypeData%InflowOnBlade) ENDIF @@ -11928,6 +16085,23 @@ SUBROUTINE AD_PackRotInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err END IF END DO END IF + Int_BufSz = Int_BufSz + 3 ! TFinMotion: size of buffers for each call to pack subtype + CALL MeshPack( InData%TFinMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! TFinMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! TFinMotion + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! TFinMotion + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! TFinMotion + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 1 ! InflowOnBlade allocated yes/no IF ( ALLOCATED(InData%InflowOnBlade) ) THEN Int_BufSz = Int_BufSz + 2*3 ! InflowOnBlade upper/lower bounds for each dimension @@ -11938,7 +16112,9 @@ SUBROUTINE AD_PackRotInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Int_BufSz = Int_BufSz + 2*2 ! InflowOnTower upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%InflowOnTower) ! InflowOnTower END IF + Re_BufSz = Re_BufSz + SIZE(InData%InflowOnHub) ! InflowOnHub Re_BufSz = Re_BufSz + SIZE(InData%InflowOnNacelle) ! InflowOnNacelle + Re_BufSz = Re_BufSz + SIZE(InData%InflowOnTailFin) ! InflowOnTailFin Int_BufSz = Int_BufSz + 1 ! UserProp allocated yes/no IF ( ALLOCATED(InData%UserProp) ) THEN Int_BufSz = Int_BufSz + 2*2 ! UserProp upper/lower bounds for each dimension @@ -12137,6 +16313,34 @@ SUBROUTINE AD_PackRotInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err ENDIF END DO END IF + CALL MeshPack( InData%TFinMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! TFinMotion + 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%InflowOnBlade) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -12182,10 +16386,18 @@ SUBROUTINE AD_PackRotInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err END DO END DO END IF + DO i1 = LBOUND(InData%InflowOnHub,1), UBOUND(InData%InflowOnHub,1) + ReKiBuf(Re_Xferred) = InData%InflowOnHub(i1) + Re_Xferred = Re_Xferred + 1 + END DO DO i1 = LBOUND(InData%InflowOnNacelle,1), UBOUND(InData%InflowOnNacelle,1) ReKiBuf(Re_Xferred) = InData%InflowOnNacelle(i1) Re_Xferred = Re_Xferred + 1 END DO + DO i1 = LBOUND(InData%InflowOnTailFin,1), UBOUND(InData%InflowOnTailFin,1) + ReKiBuf(Re_Xferred) = InData%InflowOnTailFin(i1) + Re_Xferred = Re_Xferred + 1 + END DO IF ( .NOT. ALLOCATED(InData%UserProp) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -12364,13 +16576,69 @@ SUBROUTINE AD_UnPackRotInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BladeRootMotion)) DEALLOCATE(OutData%BladeRootMotion) - ALLOCATE(OutData%BladeRootMotion(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%BladeRootMotion)) DEALLOCATE(OutData%BladeRootMotion) + ALLOCATE(OutData%BladeRootMotion(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeRootMotion.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BladeRootMotion,1), UBOUND(OutData%BladeRootMotion,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MeshUnpack( OutData%BladeRootMotion(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeRootMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeMotion not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BladeMotion)) DEALLOCATE(OutData%BladeMotion) + ALLOCATE(OutData%BladeMotion(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeRootMotion.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeMotion.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%BladeRootMotion,1), UBOUND(OutData%BladeRootMotion,1) + DO i1 = LBOUND(OutData%BladeMotion,1), UBOUND(OutData%BladeMotion,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -12404,7 +16672,7 @@ SUBROUTINE AD_UnPackRotInputType( 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%BladeRootMotion(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeRootMotion + CALL MeshUnpack( OutData%BladeMotion(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeMotion CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -12413,20 +16681,6 @@ SUBROUTINE AD_UnPackRotInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BladeMotion not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BladeMotion)) DEALLOCATE(OutData%BladeMotion) - ALLOCATE(OutData%BladeMotion(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BladeMotion.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%BladeMotion,1), UBOUND(OutData%BladeMotion,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -12460,15 +16714,13 @@ SUBROUTINE AD_UnPackRotInputType( 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%BladeMotion(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! BladeMotion + CALL MeshUnpack( OutData%TFinMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! TFinMotion 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 ! InflowOnBlade not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -12520,12 +16772,24 @@ SUBROUTINE AD_UnPackRotInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END DO END DO END IF + i1_l = LBOUND(OutData%InflowOnHub,1) + i1_u = UBOUND(OutData%InflowOnHub,1) + DO i1 = LBOUND(OutData%InflowOnHub,1), UBOUND(OutData%InflowOnHub,1) + OutData%InflowOnHub(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO i1_l = LBOUND(OutData%InflowOnNacelle,1) i1_u = UBOUND(OutData%InflowOnNacelle,1) DO i1 = LBOUND(OutData%InflowOnNacelle,1), UBOUND(OutData%InflowOnNacelle,1) OutData%InflowOnNacelle(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO + i1_l = LBOUND(OutData%InflowOnTailFin,1) + i1_u = UBOUND(OutData%InflowOnTailFin,1) + DO i1 = LBOUND(OutData%InflowOnTailFin,1), UBOUND(OutData%InflowOnTailFin,1) + OutData%InflowOnTailFin(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! UserProp not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -12599,18 +16863,31 @@ SUBROUTINE AD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) ENDIF END SUBROUTINE AD_CopyInput - SUBROUTINE AD_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE AD_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%rotors)) THEN DO i1 = LBOUND(InputData%rotors,1), UBOUND(InputData%rotors,1) - CALL AD_Destroyrotinputtype( InputData%rotors(i1), ErrStat, ErrMsg ) + CALL AD_Destroyrotinputtype( InputData%rotors(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InputData%rotors) ENDIF @@ -12900,6 +17177,9 @@ SUBROUTINE AD_CopyRotOutputType( SrcRotOutputTypeData, DstRotOutputTypeData, Ctr CALL MeshCopy( SrcRotOutputTypeData%NacelleLoad, DstRotOutputTypeData%NacelleLoad, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcRotOutputTypeData%HubLoad, DstRotOutputTypeData%HubLoad, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN CALL MeshCopy( SrcRotOutputTypeData%TowerLoad, DstRotOutputTypeData%TowerLoad, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -12919,6 +17199,9 @@ SUBROUTINE AD_CopyRotOutputType( SrcRotOutputTypeData, DstRotOutputTypeData, Ctr IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF + CALL MeshCopy( SrcRotOutputTypeData%TFinLoad, DstRotOutputTypeData%TFinLoad, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN IF (ALLOCATED(SrcRotOutputTypeData%WriteOutput)) THEN i1_l = LBOUND(SrcRotOutputTypeData%WriteOutput,1) i1_u = UBOUND(SrcRotOutputTypeData%WriteOutput,1) @@ -12933,23 +17216,42 @@ SUBROUTINE AD_CopyRotOutputType( SrcRotOutputTypeData, DstRotOutputTypeData, Ctr ENDIF END SUBROUTINE AD_CopyRotOutputType - SUBROUTINE AD_DestroyRotOutputType( RotOutputTypeData, ErrStat, ErrMsg ) + SUBROUTINE AD_DestroyRotOutputType( RotOutputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(RotOutputType), INTENT(INOUT) :: RotOutputTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotOutputType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyRotOutputType' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( RotOutputTypeData%NacelleLoad, ErrStat, ErrMsg ) - CALL MeshDestroy( RotOutputTypeData%TowerLoad, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( RotOutputTypeData%NacelleLoad, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( RotOutputTypeData%HubLoad, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( RotOutputTypeData%TowerLoad, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(RotOutputTypeData%BladeLoad)) THEN DO i1 = LBOUND(RotOutputTypeData%BladeLoad,1), UBOUND(RotOutputTypeData%BladeLoad,1) - CALL MeshDestroy( RotOutputTypeData%BladeLoad(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( RotOutputTypeData%BladeLoad(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(RotOutputTypeData%BladeLoad) ENDIF + CALL MeshDestroy( RotOutputTypeData%TFinLoad, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(RotOutputTypeData%WriteOutput)) THEN DEALLOCATE(RotOutputTypeData%WriteOutput) ENDIF @@ -13008,6 +17310,23 @@ SUBROUTINE AD_PackRotOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 3 ! HubLoad: size of buffers for each call to pack subtype + CALL MeshPack( InData%HubLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! HubLoad + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! HubLoad + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! HubLoad + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! HubLoad + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 3 ! TowerLoad: size of buffers for each call to pack subtype CALL MeshPack( InData%TowerLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! TowerLoad CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -13048,6 +17367,23 @@ SUBROUTINE AD_PackRotOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er END IF END DO END IF + Int_BufSz = Int_BufSz + 3 ! TFinLoad: size of buffers for each call to pack subtype + CALL MeshPack( InData%TFinLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! TFinLoad + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! TFinLoad + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! TFinLoad + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! TFinLoad + 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 @@ -13084,6 +17420,34 @@ SUBROUTINE AD_PackRotOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL MeshPack( InData%HubLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! HubLoad + 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 @@ -13177,6 +17541,34 @@ SUBROUTINE AD_PackRotOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er ENDIF END DO END IF + CALL MeshPack( InData%TFinLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! TFinLoad + 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%WriteOutput) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -13258,6 +17650,46 @@ SUBROUTINE AD_UnPackRotOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MeshUnpack( OutData%HubLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! HubLoad + 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) @@ -13357,6 +17789,46 @@ SUBROUTINE AD_UnPackRotOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MeshUnpack( OutData%TFinLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! TFinLoad + 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 ! WriteOutput not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -13410,18 +17882,31 @@ SUBROUTINE AD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs ENDIF END SUBROUTINE AD_CopyOutput - SUBROUTINE AD_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE AD_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%rotors)) THEN DO i1 = LBOUND(OutputData%rotors,1), UBOUND(OutputData%rotors,1) - CALL AD_Destroyrotoutputtype( OutputData%rotors(i1), ErrStat, ErrMsg ) + CALL AD_Destroyrotoutputtype( OutputData%rotors(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OutputData%rotors) ENDIF @@ -13769,6 +18254,10 @@ SUBROUTINE AD_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg ) ENDDO END IF ! check if allocated ENDDO + DO i01 = LBOUND(u_out%rotors,1),UBOUND(u_out%rotors,1) + CALL MeshExtrapInterp1(u1%rotors(i01)%TFinMotion, u2%rotors(i01)%TFinMotion, tin, u_out%rotors(i01)%TFinMotion, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO DO i01 = LBOUND(u_out%rotors,1),UBOUND(u_out%rotors,1) IF (ALLOCATED(u_out%rotors(i01)%InflowOnBlade) .AND. ALLOCATED(u1%rotors(i01)%InflowOnBlade)) THEN DO i3 = LBOUND(u_out%rotors(i01)%InflowOnBlade,3),UBOUND(u_out%rotors(i01)%InflowOnBlade,3) @@ -13790,6 +18279,12 @@ SUBROUTINE AD_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg ) END DO END DO END IF ! check if allocated + ENDDO + DO i01 = LBOUND(u_out%rotors,1),UBOUND(u_out%rotors,1) + DO i1 = LBOUND(u_out%rotors(i01)%InflowOnHub,1),UBOUND(u_out%rotors(i01)%InflowOnHub,1) + b = -(u1%rotors(i01)%InflowOnHub(i1) - u2%rotors(i01)%InflowOnHub(i1)) + u_out%rotors(i01)%InflowOnHub(i1) = u1%rotors(i01)%InflowOnHub(i1) + b * ScaleFactor + END DO ENDDO DO i01 = LBOUND(u_out%rotors,1),UBOUND(u_out%rotors,1) DO i1 = LBOUND(u_out%rotors(i01)%InflowOnNacelle,1),UBOUND(u_out%rotors(i01)%InflowOnNacelle,1) @@ -13798,6 +18293,12 @@ SUBROUTINE AD_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg ) END DO ENDDO DO i01 = LBOUND(u_out%rotors,1),UBOUND(u_out%rotors,1) + DO i1 = LBOUND(u_out%rotors(i01)%InflowOnTailFin,1),UBOUND(u_out%rotors(i01)%InflowOnTailFin,1) + b = -(u1%rotors(i01)%InflowOnTailFin(i1) - u2%rotors(i01)%InflowOnTailFin(i1)) + u_out%rotors(i01)%InflowOnTailFin(i1) = u1%rotors(i01)%InflowOnTailFin(i1) + b * ScaleFactor + END DO + ENDDO + DO i01 = LBOUND(u_out%rotors,1),UBOUND(u_out%rotors,1) IF (ALLOCATED(u_out%rotors(i01)%UserProp) .AND. ALLOCATED(u1%rotors(i01)%UserProp)) THEN DO i2 = LBOUND(u_out%rotors(i01)%UserProp,2),UBOUND(u_out%rotors(i01)%UserProp,2) DO i1 = LBOUND(u_out%rotors(i01)%UserProp,1),UBOUND(u_out%rotors(i01)%UserProp,1) @@ -13906,6 +18407,10 @@ SUBROUTINE AD_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, ErrM ENDDO END IF ! check if allocated ENDDO + DO i01 = LBOUND(u_out%rotors,1),UBOUND(u_out%rotors,1) + CALL MeshExtrapInterp2(u1%rotors(i01)%TFinMotion, u2%rotors(i01)%TFinMotion, u3%rotors(i01)%TFinMotion, tin, u_out%rotors(i01)%TFinMotion, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO DO i01 = LBOUND(u_out%rotors,1),UBOUND(u_out%rotors,1) IF (ALLOCATED(u_out%rotors(i01)%InflowOnBlade) .AND. ALLOCATED(u1%rotors(i01)%InflowOnBlade)) THEN DO i3 = LBOUND(u_out%rotors(i01)%InflowOnBlade,3),UBOUND(u_out%rotors(i01)%InflowOnBlade,3) @@ -13929,6 +18434,13 @@ SUBROUTINE AD_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, ErrM END DO END DO END IF ! check if allocated + ENDDO + DO i01 = LBOUND(u_out%rotors,1),UBOUND(u_out%rotors,1) + DO i1 = LBOUND(u_out%rotors(i01)%InflowOnHub,1),UBOUND(u_out%rotors(i01)%InflowOnHub,1) + b = (t(3)**2*(u1%rotors(i01)%InflowOnHub(i1) - u2%rotors(i01)%InflowOnHub(i1)) + t(2)**2*(-u1%rotors(i01)%InflowOnHub(i1) + u3%rotors(i01)%InflowOnHub(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%rotors(i01)%InflowOnHub(i1) + t(3)*u2%rotors(i01)%InflowOnHub(i1) - t(2)*u3%rotors(i01)%InflowOnHub(i1) ) * scaleFactor + u_out%rotors(i01)%InflowOnHub(i1) = u1%rotors(i01)%InflowOnHub(i1) + b + c * t_out + END DO ENDDO DO i01 = LBOUND(u_out%rotors,1),UBOUND(u_out%rotors,1) DO i1 = LBOUND(u_out%rotors(i01)%InflowOnNacelle,1),UBOUND(u_out%rotors(i01)%InflowOnNacelle,1) @@ -13938,6 +18450,13 @@ SUBROUTINE AD_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, ErrM END DO ENDDO DO i01 = LBOUND(u_out%rotors,1),UBOUND(u_out%rotors,1) + DO i1 = LBOUND(u_out%rotors(i01)%InflowOnTailFin,1),UBOUND(u_out%rotors(i01)%InflowOnTailFin,1) + b = (t(3)**2*(u1%rotors(i01)%InflowOnTailFin(i1) - u2%rotors(i01)%InflowOnTailFin(i1)) + t(2)**2*(-u1%rotors(i01)%InflowOnTailFin(i1) + u3%rotors(i01)%InflowOnTailFin(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%rotors(i01)%InflowOnTailFin(i1) + t(3)*u2%rotors(i01)%InflowOnTailFin(i1) - t(2)*u3%rotors(i01)%InflowOnTailFin(i1) ) * scaleFactor + u_out%rotors(i01)%InflowOnTailFin(i1) = u1%rotors(i01)%InflowOnTailFin(i1) + b + c * t_out + END DO + ENDDO + DO i01 = LBOUND(u_out%rotors,1),UBOUND(u_out%rotors,1) IF (ALLOCATED(u_out%rotors(i01)%UserProp) .AND. ALLOCATED(u1%rotors(i01)%UserProp)) THEN DO i2 = LBOUND(u_out%rotors(i01)%UserProp,2),UBOUND(u_out%rotors(i01)%UserProp,2) DO i1 = LBOUND(u_out%rotors(i01)%UserProp,1),UBOUND(u_out%rotors(i01)%UserProp,1) @@ -14060,6 +18579,10 @@ SUBROUTINE AD_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, ErrMsg CALL MeshExtrapInterp1(y1%rotors(i01)%NacelleLoad, y2%rotors(i01)%NacelleLoad, tin, y_out%rotors(i01)%NacelleLoad, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) ENDDO + DO i01 = LBOUND(y_out%rotors,1),UBOUND(y_out%rotors,1) + CALL MeshExtrapInterp1(y1%rotors(i01)%HubLoad, y2%rotors(i01)%HubLoad, tin, y_out%rotors(i01)%HubLoad, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO DO i01 = LBOUND(y_out%rotors,1),UBOUND(y_out%rotors,1) CALL MeshExtrapInterp1(y1%rotors(i01)%TowerLoad, y2%rotors(i01)%TowerLoad, tin, y_out%rotors(i01)%TowerLoad, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) @@ -14072,6 +18595,10 @@ SUBROUTINE AD_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, ErrMsg ENDDO END IF ! check if allocated ENDDO + DO i01 = LBOUND(y_out%rotors,1),UBOUND(y_out%rotors,1) + CALL MeshExtrapInterp1(y1%rotors(i01)%TFinLoad, y2%rotors(i01)%TFinLoad, tin, y_out%rotors(i01)%TFinLoad, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO DO i01 = LBOUND(y_out%rotors,1),UBOUND(y_out%rotors,1) IF (ALLOCATED(y_out%rotors(i01)%WriteOutput) .AND. ALLOCATED(y1%rotors(i01)%WriteOutput)) THEN DO i1 = LBOUND(y_out%rotors(i01)%WriteOutput,1),UBOUND(y_out%rotors(i01)%WriteOutput,1) @@ -14143,6 +18670,10 @@ SUBROUTINE AD_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, Err CALL MeshExtrapInterp2(y1%rotors(i01)%NacelleLoad, y2%rotors(i01)%NacelleLoad, y3%rotors(i01)%NacelleLoad, tin, y_out%rotors(i01)%NacelleLoad, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) ENDDO + DO i01 = LBOUND(y_out%rotors,1),UBOUND(y_out%rotors,1) + CALL MeshExtrapInterp2(y1%rotors(i01)%HubLoad, y2%rotors(i01)%HubLoad, y3%rotors(i01)%HubLoad, tin, y_out%rotors(i01)%HubLoad, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO DO i01 = LBOUND(y_out%rotors,1),UBOUND(y_out%rotors,1) CALL MeshExtrapInterp2(y1%rotors(i01)%TowerLoad, y2%rotors(i01)%TowerLoad, y3%rotors(i01)%TowerLoad, tin, y_out%rotors(i01)%TowerLoad, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) @@ -14155,6 +18686,10 @@ SUBROUTINE AD_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, Err ENDDO END IF ! check if allocated ENDDO + DO i01 = LBOUND(y_out%rotors,1),UBOUND(y_out%rotors,1) + CALL MeshExtrapInterp2(y1%rotors(i01)%TFinLoad, y2%rotors(i01)%TFinLoad, y3%rotors(i01)%TFinLoad, tin, y_out%rotors(i01)%TFinLoad, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO DO i01 = LBOUND(y_out%rotors,1),UBOUND(y_out%rotors,1) IF (ALLOCATED(y_out%rotors(i01)%WriteOutput) .AND. ALLOCATED(y1%rotors(i01)%WriteOutput)) THEN DO i1 = LBOUND(y_out%rotors(i01)%WriteOutput,1),UBOUND(y_out%rotors(i01)%WriteOutput,1) diff --git a/modules/aerodyn/src/AirfoilInfo_Types.f90 b/modules/aerodyn/src/AirfoilInfo_Types.f90 index 4eabaad1b..64e6a7d47 100644 --- a/modules/aerodyn/src/AirfoilInfo_Types.f90 +++ b/modules/aerodyn/src/AirfoilInfo_Types.f90 @@ -265,15 +265,27 @@ SUBROUTINE AFI_CopyUA_BL_Type( SrcUA_BL_TypeData, DstUA_BL_TypeData, CtrlCode, E DstUA_BL_TypeData%c_alphaUpperWrap = SrcUA_BL_TypeData%c_alphaUpperWrap END SUBROUTINE AFI_CopyUA_BL_Type - SUBROUTINE AFI_DestroyUA_BL_Type( UA_BL_TypeData, ErrStat, ErrMsg ) + SUBROUTINE AFI_DestroyUA_BL_Type( UA_BL_TypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AFI_UA_BL_Type), INTENT(INOUT) :: UA_BL_TypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyUA_BL_Type' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyUA_BL_Type' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AFI_DestroyUA_BL_Type SUBROUTINE AFI_PackUA_BL_Type( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -658,15 +670,27 @@ SUBROUTINE AFI_CopyUA_BL_Default_Type( SrcUA_BL_Default_TypeData, DstUA_BL_Defau DstUA_BL_Default_TypeData%alphaLower = SrcUA_BL_Default_TypeData%alphaLower END SUBROUTINE AFI_CopyUA_BL_Default_Type - SUBROUTINE AFI_DestroyUA_BL_Default_Type( UA_BL_Default_TypeData, ErrStat, ErrMsg ) + SUBROUTINE AFI_DestroyUA_BL_Default_Type( UA_BL_Default_TypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AFI_UA_BL_Default_Type), INTENT(INOUT) :: UA_BL_Default_TypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyUA_BL_Default_Type' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyUA_BL_Default_Type' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AFI_DestroyUA_BL_Default_Type SUBROUTINE AFI_PackUA_BL_Default_Type( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1010,15 +1034,27 @@ SUBROUTINE AFI_CopyTable_Type( SrcTable_TypeData, DstTable_TypeData, CtrlCode, E IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AFI_CopyTable_Type - SUBROUTINE AFI_DestroyTable_Type( Table_TypeData, ErrStat, ErrMsg ) + SUBROUTINE AFI_DestroyTable_Type( Table_TypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AFI_Table_Type), INTENT(INOUT) :: Table_TypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyTable_Type' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyTable_Type' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(Table_TypeData%Alpha)) THEN DEALLOCATE(Table_TypeData%Alpha) ENDIF @@ -1028,7 +1064,8 @@ SUBROUTINE AFI_DestroyTable_Type( Table_TypeData, ErrStat, ErrMsg ) IF (ALLOCATED(Table_TypeData%SplineCoefs)) THEN DEALLOCATE(Table_TypeData%SplineCoefs) ENDIF - CALL AFI_Destroyua_bl_type( Table_TypeData%UA_BL, ErrStat, ErrMsg ) + CALL AFI_Destroyua_bl_type( Table_TypeData%UA_BL, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AFI_DestroyTable_Type SUBROUTINE AFI_PackTable_Type( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1405,15 +1442,27 @@ SUBROUTINE AFI_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrS DstInitInputData%UA_f_cn = SrcInitInputData%UA_f_cn END SUBROUTINE AFI_CopyInitInput - SUBROUTINE AFI_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE AFI_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AFI_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AFI_DestroyInitInput SUBROUTINE AFI_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1571,16 +1620,29 @@ SUBROUTINE AFI_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, E IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AFI_CopyInitOutput - SUBROUTINE AFI_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE AFI_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AFI_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AFI_DestroyInitOutput SUBROUTINE AFI_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1843,15 +1905,27 @@ SUBROUTINE AFI_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%FileName = SrcParamData%FileName END SUBROUTINE AFI_CopyParam - SUBROUTINE AFI_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE AFI_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AFI_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%secondVals)) THEN DEALLOCATE(ParamData%secondVals) ENDIF @@ -1863,7 +1937,8 @@ SUBROUTINE AFI_DestroyParam( ParamData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(ParamData%Table)) THEN DO i1 = LBOUND(ParamData%Table,1), UBOUND(ParamData%Table,1) - CALL AFI_Destroytable_type( ParamData%Table(i1), ErrStat, ErrMsg ) + CALL AFI_Destroytable_type( ParamData%Table(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%Table) ENDIF @@ -2289,15 +2364,27 @@ SUBROUTINE AFI_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg DstInputData%Re = SrcInputData%Re END SUBROUTINE AFI_CopyInput - SUBROUTINE AFI_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE AFI_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AFI_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AFI_DestroyInput SUBROUTINE AFI_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2432,15 +2519,27 @@ SUBROUTINE AFI_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrM DstOutputData%FullyAttached = SrcOutputData%FullyAttached END SUBROUTINE AFI_CopyOutput - SUBROUTINE AFI_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE AFI_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AFI_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AFI_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AFI_DestroyOutput SUBROUTINE AFI_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) diff --git a/modules/aerodyn/src/BEMT.f90 b/modules/aerodyn/src/BEMT.f90 index be879948c..d62b855be 100644 --- a/modules/aerodyn/src/BEMT.f90 +++ b/modules/aerodyn/src/BEMT.f90 @@ -66,18 +66,19 @@ module BEMT !---------------------------------------------------------------------------------------------------------------------------------- -real(ReKi) function ComputePhiWithInduction( Vx, Vy, a, aprime ) +real(ReKi) function ComputePhiWithInduction( Vx, Vy, a, aprime, cantAngle, xVelCorr) ! This routine is used to compute the inflow angle, phi, from the local velocities and the induction factors. !.................................................................................................................................. real(ReKi), intent(in ) :: Vx ! Local velocity component along the thrust direction real(ReKi), intent(in ) :: Vy ! Local velocity component along the rotor plane-of-rotation direction real(ReKi), intent(in ) :: a ! Axial induction factor real(ReKi), intent(in ) :: aprime ! Tangential induction factor - + real(ReKi), intent(in ) :: cantAngle + real(ReKi), intent(in ) :: xVelCorr real(ReKi) :: x real(ReKi) :: y - x = Vx*(1.0_ReKi-a) + x = (Vx*cos(cantAngle)+xVelCorr)*(1.0_R8Ki-a) y = Vy*(1.0_ReKi + aprime) if ( EqualRealNos(y, 0.0_ReKi) .AND. EqualRealNos(x, 0.0_ReKi) ) then @@ -155,6 +156,12 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) character(*), parameter :: RoutineName = 'BEMT_SetParameters' integer(IntKi) :: i, j + real(ReKi), parameter :: FractionMax = 0.7 ! fraction of rotor disk where weighted average should be maximum + real(ReKi), parameter :: FractionRadius = 0.1 ! radius of smoothing (fraction of rotor disk around FractionMax) + ! constants for kernelType_TRIWEIGHT: + real(ReKi), parameter :: w = 35.0_ReKi/32.0_ReKi + real(ReKi), parameter :: Exp1 = 2 + real(ReKi), parameter :: Exp2 = 3 ! Initialize variables for this routine @@ -165,6 +172,14 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) p%numBlades = InitInp%numBlades p%UA_Flag = InitInp%UA_Flag p%DBEMT_Mod = InitInp%DBEMT_Mod + p%MomentumCorr = InitInp%MomentumCorr + p%BEM_Mod = InitInp%BEM_Mod + !call WrScr('>>>> BEM_Mod '//trim(num2lstr(p%BEM_Mod))) + if ((p%BEM_Mod/=BEMMod_2D .and. p%BEM_Mod/=BEMMod_3D )) then + call SetErrStat( ErrID_Fatal, 'BEM_Mod needs to be 0 or 2 for now', errStat, errMsg, RoutineName ) + return + endif + allocate ( p%chord(p%numBladeNodes, p%numBlades), STAT = errStat2 ) if ( errStat2 /= 0 ) then @@ -210,6 +225,7 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) do i=1,p%numBladeNodes p%chord(i,j) = InitInp%chord(i,j) p%tipLossConst(i,j) = p%numBlades*(InitInp%zTip (j) - InitInp%zLocal(i,j)) / (2.0*InitInp%zLocal(i,j)) + ! NOTE different conventions are possible for hub losses p%hubLossConst(i,j) = p%numBlades*(InitInp%zLocal(i,j) - InitInp%zHub (j)) / (2.0*InitInp%zHub (j)) end do end do @@ -238,6 +254,7 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) end do end do + p%rTipFixMax = maxval(InitInp%rTipFix) end subroutine BEMT_SetParameters !---------------------------------------------------------------------------------------------------------------------------------- @@ -352,22 +369,13 @@ subroutine BEMT_AllocInput( u, p, errStat, errMsg ) end if u%Vy = 0.0_ReKi - if (p%DBEMT_Mod==DBEMT_cont_tauConst) then - allocate ( u%Vx_elast_dot( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%Vx_dot.', errStat, errMsg, RoutineName ) - return - end if - u%Vx_elast_dot = 0.0_ReKi - - allocate ( u%Vy_elast_dot( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%Vy_dot.', errStat, errMsg, RoutineName ) - return - end if - u%Vy_elast_dot = 0.0_ReKi - end if - + allocate ( u%Vz( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%Vz.', errStat, errMsg, RoutineName ) + return + end if + u%Vz = 0.0_ReKi + allocate ( u%omega_z( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) if ( errStat2 /= 0 ) then call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%omega_z.', errStat, errMsg, RoutineName ) @@ -375,6 +383,13 @@ subroutine BEMT_AllocInput( u, p, errStat, errMsg ) end if u%omega_z = 0.0_ReKi + allocate ( u%xVelCorr( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%Vz.', errStat, errMsg, RoutineName ) + return + end if + u%xVelCorr = 0.0_ReKi + allocate ( u%rLocal( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) if ( errStat2 /= 0 ) then call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%rLocal.', errStat, errMsg, RoutineName ) @@ -392,6 +407,26 @@ subroutine BEMT_AllocInput( u, p, errStat, errMsg ) u%omega = 0.0_ReKi + allocate ( u%cantAngle( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%cantAngle.', errStat, errMsg, RoutineName ) + return + end if + u%cantAngle = 0.0_ReKi + + allocate ( u%drdz( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%drdz.', errStat, errMsg, RoutineName ) + return + end if + u%drdz = 0.0_ReKi + + allocate ( u%toeAngle( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%toeAngle.', errStat, errMsg, RoutineName ) + return + end if + u%toeAngle = 0.0_ReKi end subroutine BEMT_AllocInput @@ -427,6 +462,10 @@ subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) call allocAry( y%AOA, p%numBladeNodes, p%numBlades, 'y%AOA', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cx, p%numBladeNodes, p%numBlades, 'y%Cx', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cy, p%numBladeNodes, p%numBlades, 'y%Cy', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%Cz, p%numBladeNodes, p%numBlades, 'y%Cz', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%Cmx, p%numBladeNodes, p%numBlades, 'y%Cmx', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%Cmy, p%numBladeNodes, p%numBlades, 'y%Cmy', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%Cmz, p%numBladeNodes, p%numBlades, 'y%Cmz', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cm, p%numBladeNodes, p%numBlades, 'y%Cm', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cl, p%numBladeNodes, p%numBlades, 'y%Cl', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cd, p%numBladeNodes, p%numBlades, 'y%Cd', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -440,7 +479,10 @@ subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) y%phi = 0.0_ReKi y%Cx = 0.0_ReKi y%Cy = 0.0_ReKi - y%Cm = 0.0_ReKi + y%Cz = 0.0_ReKi + y%Cmx = 0.0_ReKi + y%Cmy = 0.0_ReKi + y%Cmz = 0.0_ReKi ! others: y%chi = 0.0_ReKi @@ -450,6 +492,7 @@ subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) y%AOA = 0.0_ReKi y%Cl = 0.0_ReKi y%Cd = 0.0_ReKi + y%Cm = 0.0_ReKi y%Cpmin = 0.0_ReKi end subroutine BEMT_AllocOutput @@ -534,12 +577,6 @@ subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Inte InitInp_DBEMT%numNodes = p%numBladeNodes InitInp_DBEMT%tau1_const = InitInp%tau1_const - allocate(misc%u_DBEMT(2),stat=errStat2) - if (errStat2 /= 0) then - call SetErrStat(ErrID_Fatal,"Error allocating u_DBEMT",errStat,errMsg,RoutineName) - return - end if - if (allocated(InitInp%rlocal)) then call MOVE_ALLOC( InitInp%rlocal, InitInp_DBEMT%rlocal ) else @@ -668,6 +705,7 @@ subroutine BEMT_ReInit(p,x,xd,z,OtherState,misc,ErrStat,ErrMsg) misc%BEM_weight = 0.0_ReKi OtherState%DBEMT%tau1 = 0.0_ReKi !we're going to output this value, so let's initialize it + OtherState%n = -1 if (p%UseInduction) then OtherState%ValidPhi = .true. @@ -745,7 +783,7 @@ END SUBROUTINE BEMT_End !---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, errStat, errMsg ) +subroutine BEMT_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, AFInfo, m, errStat, errMsg ) ! Loose coupling routine for solving for constraint states, integrating continuous states, and updating discrete states ! Continuous, constraint, discrete, and other states are updated for t + Interval ! @@ -754,8 +792,8 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, real(DbKi), intent(in ) :: t ! Current simulation time in seconds integer(IntKi), intent(in ) :: n ! Current simulation time step n = 0,1,... - type(BEMT_InputType), intent(in ) :: u1,u2 ! Input at t and t+ dt - !real(DbKi), intent(in ) :: utime ! Times associated with u(:), in seconds + type(BEMT_InputType), intent(in ) :: u(2) ! Input at t and t+ dt + real(DbKi), intent(in ) :: uTimes(2) ! Times associated with u(:), in seconds type(BEMT_ParameterType), intent(in ) :: p ! Parameters type(BEMT_ContinuousStateType), intent(inout) :: x ! Input: Continuous states at t; ! Output: Continuous states at t + Interval @@ -773,49 +811,46 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, integer(IntKi) :: i,j + integer(IntKi), parameter :: TimeIndex_t = 1 + integer(IntKi), parameter :: TimeIndex_t_plus_dt = 2 character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None integer(IntKi) :: errStat2 ! temporary Error status of the operation character(*), parameter :: RoutineName = 'BEMT_UpdateStates' - real(DbKi) :: uTimes(2) + ErrStat = ErrID_None ErrMsg = "" - uTimes(1) = t - uTimes(2) = t+p%dt - !............................................................................................................................... ! if we haven't initialized z%phi, we want to get a better guess as to what the actual values of phi at t are: !............................................................................................................................... - if (.not. OtherState%nodesInitialized) then - call UpdatePhi( u1, p, z%phi, AFInfo, m, OtherState%ValidPhi, errStat2, errMsg2 ) - OtherState%nodesInitialized = .true. ! otherState updated to t+dt (i.e., n+1) + call UpdatePhi( u(TimeIndex_t), p, z%phi, AFInfo, m, OtherState%ValidPhi, errStat2, errMsg2 ) end if !............................................................................................................................... - ! compute inputs to DBEMT at step n (also setting inductions--including DBEMT and skewed wake corrections--at time n) + ! compute inputs to DBEMT and SkewedWake at step n (also setting inductions--including DBEMT and skewed wake corrections--at time n) !............................................................................................................................... - call BEMT_CalcOutput_Inductions( 1, t, .true., .true., z%phi, u1, p, x, xd, z, OtherState, AFInfo, m%axInduction, m%tanInduction, m%chi, m, errStat2, errMsg2 ) + call BEMT_CalcOutput_Inductions( TimeIndex_t, t, .true., .true., z%phi, u(TimeIndex_t), p, x, xd, z, OtherState, AFInfo, m%axInduction, m%tanInduction, m%chi, m, errStat2, errMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat >= AbortErrLev) return #ifdef DEBUG_BEMT_RESIDUAL - if (p%useInduction) call WriteDEBUGValuesToFile(t, u1, p, x, xd, z, OtherState, m, AFInfo) + if (p%useInduction) call WriteDEBUGValuesToFile(t, u(TimeIndex_t), p, x, xd, z, OtherState, m, AFInfo) #endif !............................................................................................................................... ! compute inputs to UA at time n (also setting inductions--including DBEMT and skewed wake corrections--at time n) !............................................................................................................................... if (p%UA_Flag) then m%phi = z%phi - call SetInputs_for_UA_AllNodes(u1, p, m%phi, m%axInduction, m%tanInduction, m%u_UA(:,:,1)) + call SetInputs_for_UA_AllNodes(u(TimeIndex_t), p, m%phi, m%axInduction, m%tanInduction, m%u_UA(:,:,TimeIndex_t)) end if !............................................................................................................................... - ! update BEMT states to step n+1 + ! update BEMT constraint states to step n+1 !............................................................................................................................... - call UpdatePhi( u2, p, z%phi, AFInfo, m, OtherState%ValidPhi, errStat2, errMsg2 ) + call UpdatePhi( u(TimeIndex_t_plus_dt), p, z%phi, AFInfo, m, OtherState%ValidPhi, errStat2, errMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (errStat >= AbortErrLev) return @@ -823,7 +858,7 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, !............................................................................................................................... ! compute inputs to DBEMT at step n+1 (also setting inductions--WITHOUT DBEMT or skewed wake corrections--at step n+1) !............................................................................................................................... - call BEMT_CalcOutput_Inductions( 2, t, .true., .false., z%phi, u2, p, x, xd, z, OtherState, AFInfo, m%axInduction, m%tanInduction, m%chi, m, errStat2, errMsg2 ) + call BEMT_CalcOutput_Inductions( TimeIndex_t_plus_dt, t, .true., .false., z%phi, u(TimeIndex_t_plus_dt), p, x, xd, z, OtherState, AFInfo, m%axInduction, m%tanInduction, m%chi, m, errStat2, errMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat >= AbortErrLev) return @@ -858,20 +893,20 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, ! apply DBEMT correction to axInduction and tanInduction: !............................................ if (p%DBEMT_Mod /= DBEMT_none) then - call calculate_Inductions_from_DBEMT_AllNodes(2, uTimes(2), u2, p, x, OtherState, m, m%axInduction, m%tanInduction) + call calculate_Inductions_from_DBEMT_AllNodes(TimeIndex_t_plus_dt, uTimes(TimeIndex_t_plus_dt), u(TimeIndex_t_plus_dt), p, x, OtherState, m, m%axInduction, m%tanInduction) end if - call ApplySkewedWakeCorrection_AllNodes(p, u2, m, m%axInduction, m%chi) + call ApplySkewedWakeCorrection_AllNodes(p, u(TimeIndex_t_plus_dt), m, x, z%phi, OtherState, m%axInduction, m%chi) !............................................ ! If TSR is too low, (start to) turn off induction !............................................ - call check_turnOffBEMT(p, u2, m%BEM_weight, m%axInduction, m%tanInduction, m%FirstWarn_BEMoff) + call check_turnOffBEMT(p, u(TimeIndex_t_plus_dt), m%BEM_weight, m%axInduction, m%tanInduction, m%FirstWarn_BEMoff) end if m%phi = z%phi - call SetInputs_for_UA_AllNodes(u2, p, m%phi, m%axInduction, m%tanInduction, m%u_UA(:,:,2)) + call SetInputs_for_UA_AllNodes(u(TimeIndex_t_plus_dt), p, m%phi, m%axInduction, m%tanInduction, m%u_UA(:,:,TimeIndex_t_plus_dt)) !............................................................................................................................... ! compute UA states at t+dt @@ -892,6 +927,8 @@ subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, end if ! is UA used? + OtherState%nodesInitialized = .true. ! otherState updated to t+dt (i.e., n+1) + end subroutine BEMT_UpdateStates !.................................................................................................................................. subroutine SetInputs_For_DBEMT(u_DBEMT, u, p, axInduction, tanInduction, Rtip) @@ -906,26 +943,30 @@ subroutine SetInputs_For_DBEMT(u_DBEMT, u, p, axInduction, tanInduction, Rtip) integer :: i, j - ! Locate the maximum rlocal value for all blades. - u_DBEMT%R_disk = Rtip(1) - do j = 2,p%numBlades - u_DBEMT%R_disk = max( u_DBEMT%R_disk , Rtip(j) ) + !............................. + ! calculate rotor-level inputs + !............................. + u_DBEMT%R_disk = maxval( Rtip ) ! Locate the maximum rlocal value for all blades. + u_DBEMT%Un_disk = u%Un_disk + u_DBEMT%AxInd_disk = 0.0_ReKi + do j = 1,p%numBlades + do i = 1,p%numBladeNodes + u_DBEMT%AxInd_disk = u_DBEMT%AxInd_disk + axInduction(i,j) + end do end do - + u_DBEMT%AxInd_disk = u_DBEMT%AxInd_disk / (p%numBladeNodes*p%numBlades) + + !............................. + ! calculate element-level inputs + !............................. if (p%DBEMT_Mod == DBEMT_tauVaries ) then - ! We need to generate a disk-averaged axial induction for this timestep - u_DBEMT%AxInd_disk = 0.0_ReKi + ! Compute span Ratio do j = 1,p%numBlades do i = 1,p%numBladeNodes - u_DBEMT%AxInd_disk = u_DBEMT%AxInd_disk + axInduction(i,j) - u_DBEMT%element(i,j)%spanRatio = u%rlocal(i,j)/u_DBEMT%R_disk end do end do - u_DBEMT%AxInd_disk = u_DBEMT%AxInd_disk / (p%numBladeNodes*p%numBlades) - - u_DBEMT%Un_disk = u%Un_disk end if @@ -936,15 +977,6 @@ subroutine SetInputs_For_DBEMT(u_DBEMT, u, p, axInduction, tanInduction, Rtip) end do end do - if( allocated(u%Vx_elast_dot)) then ! only for DBEMT_Mod=DBEMT_cont_tauConst - do j = 1,p%numBlades - do i = 1,p%numBladeNodes - u_DBEMT%element(i,j)%vind_s_dot(1) = axInduction( i,j)*u%Vx_elast_dot(i,j) - u%omega_z(i,j)*tanInduction(i,j)*u%Vy(i,j) ! Eq. 41 - u_DBEMT%element(i,j)%vind_s_dot(2) = -tanInduction(i,j)*u%Vy_elast_dot(i,j) - u%omega_z(i,j)*axInduction( i,j)*u%Vx(i,j) ! Eq. 41 - end do - end do - end if - end subroutine SetInputs_For_DBEMT !.................................................................................................................................. @@ -994,7 +1026,7 @@ subroutine UpdatePhi( u, p, phi, AFInfo, m, ValidPhi, errStat, errMsg ) ! We'll simply compute a geometrical phi based on both induction factors being 0.0 do j = 1,p%numBlades ! Loop through all blades do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements - phi(i,j) = ComputePhiWithInduction(u%Vx(i,j), u%Vy(i,j), 0.0_ReKi, 0.0_ReKi) + phi(i,j) = ComputePhiWithInduction(u%Vx(i,j), u%Vy(i,j), 0.0_ReKi, 0.0_ReKi, u%cantAngle(i,j), u%xVelCorr(i,j) ) end do end do @@ -1139,9 +1171,9 @@ subroutine check_turnOffBEMT(p, u, Weight, axInduction, tanInduction, FirstWarn) integer(IntKi) :: i !< blade node counter integer(IntKi) :: j !< blade counter - if( u%TSR < BEMT_upperBoundTSR ) then + if( abs(u%TSR) < BEMT_upperBoundTSR ) then - Weight = BlendCosine( u%TSR, BEMT_lowerBoundTSR, BEMT_upperBoundTSR ) + Weight = BlendCosine( abs(u%TSR), BEMT_lowerBoundTSR, BEMT_upperBoundTSR ) if (FirstWarn) then if (Weight < 1.0_ReKi) then @@ -1183,8 +1215,6 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat ! nectivity information does not have to be recalculated) 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 ! Generic index @@ -1206,7 +1236,7 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat !!#endif y%phi = z%phi ! set this before possibly calling UpdatePhi() because phi is intent(inout) in the solve - m%ValidPhi = OtherState%ValidPhi ! set this so that we don't overwrite OtherSTate%ValidPhi + m%ValidPhi = OtherState%ValidPhi !............................................................................................................................... ! if we haven't initialized z%phi, we want to get a better guess as to what the actual values of phi are: @@ -1217,6 +1247,7 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat !............................................ ! calculate inductions using BEMT, applying the DBEMT, and/or skewed wake corrections as applicable: + ! NOTE that we don't use the DBEMT inputs when calling its CalcOutput routine, so we'll skip calculating them here !............................................ call BEMT_CalcOutput_Inductions( InputIndex, t, .false., .true., y%phi, u, p, x, xd, z, OtherState, AFInfo, y%axInduction, y%tanInduction, y%chi, m, errStat, errMsg ) @@ -1288,8 +1319,18 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat !............................................ do j = 1,p%numBlades ! Loop through all blades do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements - ! NOTE: For these calculations we force the useAIDrag and useTIDrag flags to .TRUE. - call Transform_ClCd_to_CxCy( y%phi(i,j), .TRUE., .TRUE., y%Cl(i,j), y%Cd(i,j),y%Cx(i,j), y%Cy(i,j) ) + ! Compute Cx, Cy given Cl, Cd and phi + ! NOTE: For these calculations we force the useAIDrag and useTIDrag flags to .TRUE. + if(p%BEM_Mod==BEMMod_2D) then + call Transform_ClCd_to_CxCy( y%phi(i,j), .TRUE., .TRUE., y%Cl(i,j), y%Cd(i,j),y%Cx(i,j), y%Cy(i,j) ) + y%Cz(i,j) = 0.0_ReKi + y%Cmx(i,j) = 0.0_ReKi + y%Cmy(i,j) = 0.0_ReKi + y%Cmz(i,j) = y%Cm(i,j) + else + call Transform_ClCdCm_to_CxCyCzCmxCmyCmz( y%phi(i,j), u%theta(i,j), u%cantAngle(i,j),u%toeAngle(i,j), .TRUE., .TRUE., & + y%AOA(i,j), y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), y%Cx(i,j), y%Cy(i,j), y%Cz(i,j), y%Cmx(i,j), y%Cmy(i,j), y%Cmz(i,j) ) + endif enddo ! I - Blade nodes / elements enddo ! J - All blades @@ -1436,7 +1477,7 @@ subroutine BEMT_CalcOutput_Inductions( InputIndex, t, CalculateDBEMTInputs, Appl !............................................ ! Apply skewed wake correction to the axial induction (axInduction) !............................................ - call ApplySkewedWakeCorrection_AllNodes(p, u, m, axInduction, chi) + call ApplySkewedWakeCorrection_AllNodes(p, u, m, x, phi, OtherState, axInduction, chi) !............................................ ! If TSR is too low, (start to) turn off induction @@ -1483,31 +1524,72 @@ subroutine calculate_Inductions_from_DBEMT_AllNodes(InputIndex, t, u, p, x, Othe end subroutine calculate_Inductions_from_DBEMT_AllNodes !---------------------------------------------------------------------------------------------------------------------------------- -subroutine ApplySkewedWakeCorrection_AllNodes(p, u, m, axInduction, chi) +subroutine ApplySkewedWakeCorrection_AllNodes(p, u, m, x, phi, OtherState, axInduction, chi) type(BEMT_InputType), intent(in ) :: u ! Inputs at Time t type(BEMT_ParameterType), intent(in ) :: p ! Parameters type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables + type(BEMT_ContinuousStateType), intent(in ) :: x ! continuous states (for filter on V_w) + REAL(ReKi), intent(in ) :: phi(:,:) ! phi at which this is getting applied (for calculation of tip/hub losses) + type(BEMT_OtherStateType), intent(in ) :: OtherState ! Other states at t REAL(ReKi), intent(inout) :: axInduction(:,:) REAL(ReKi), intent(inout) :: chi(:,:) ! value used in skewed wake correction - integer(IntKi) :: i ! Generic index - integer(IntKi) :: j ! Loops through nodes / elements + integer(IntKi) :: i ! Generic index + integer(IntKi) :: j ! Loops through nodes / elements + real(ReKi) :: F ! correction factor + real(ReKi) :: X_chi ! value for chi !............................................ ! Apply skewed wake correction to the axial induction (y%axInduction) !............................................ if ( p%skewWakeMod == SkewMod_PittPeters ) then + if (p%BEM_Mod==BEMMod_2D) then + ! do nothing + else + X_chi = CalculateChiAngle(p, u, m, x, OtherState, .false.) + chi = X_chi ! initialize in case of fixed inductions + endif + do j = 1,p%numBlades ! Loop through all blades do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements if ( .not. p%FixedInductions(i,j) ) then - call ApplySkewedWakeCorrection( p%yawCorrFactor, u%psi(j), u%chi0, u%rlocal(i,j)/m%Rtip(j), axInduction(i,j), chi(i,j), m%FirstWarn_Skew ) + F = getHubTipLossCorrection(p%BEM_Mod, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), phi(i,j), u%cantAngle(i,j) ) + call ApplySkewedWakeCorrection( p%BEM_Mod, p%skewWakeMod, p%yawCorrFactor, F, u%psi(j), u%psiSkewOffset, u%chi0, u%rlocal(i,j)/m%Rtip(j), axInduction(i,j), chi(i,j), m%FirstWarn_Skew ) end if ! .not. p%FixedInductions (special case for tip and/or hub loss) enddo ! I - Blade nodes / elements enddo ! J - All blades end if end subroutine ApplySkewedWakeCorrection_AllNodes +!---------------------------------------------------------------------------------------------------------------------------------- +function CalculateChiAngle(p, u, m, x, OtherState, UseV0) result(chi) + type(BEMT_InputType), intent(in ) :: u ! Inputs at Time t + type(BEMT_ParameterType), intent(in ) :: p ! Parameters + type(BEMT_MiscVarType), intent(in ) :: m ! Misc/optimization variables + type(BEMT_ContinuousStateType), intent(in ) :: x ! continuous states (for filter on V_w) + type(BEMT_OtherStateType), intent(in ) :: OtherState ! Other states at t + logical, intent(in ) :: UseV0 ! Whether to initialize with V0 or try to use a state + + real(ReKi) :: v_w(3) ! wake velocity + real(ReKi) :: denom ! denominator + real(ReKi) :: chi ! skew angle + if (UseV0) then + v_w = u%V0 + elseif (.not. OtherState%nodesInitialized) then + v_w = m%u_SkewWake(1)%v_qsw + else + v_w = x%v_w + end if + + denom= TwoNorm(v_w) + if (EqualRealNos(denom, 0.0_ReKi)) then + chi = 0.0_ReKi !technically would be acos( 0.0_ReKi ), but with no wind, we can pick a nicer angle to use later in tan(chi/2) + else + chi = acos( min(1.0_R8Ki, max(-1.0_R8Ki, dot_product(u%x_hat_disk, v_w) / denom)) ) + end if + +end function CalculateChiAngle !---------------------------------------------------------------------------------------------------------------------------------- subroutine BEMT_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, AFInfo, ErrStat, ErrMsg ) ! Tight coupling routine for computing derivatives of continuous states @@ -1551,7 +1633,7 @@ subroutine BEMT_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, AFIn call UpdatePhi( u, p, m%phi, AFInfo, m, m%ValidPhi, errStat2, errMsg2 ) !............................................................................................................................... - ! compute inputs to DBEMT (also setting inductions needed for UA inputs--including DBEMT and skewed wake corrections) + ! compute inputs to DBEMT and SkewedWake (also setting inductions needed for UA inputs--including DBEMT and skewed wake corrections) !............................................................................................................................... call BEMT_CalcOutput_Inductions( InputIndex, t, .true., .true., m%phi, u, p, x, xd, z, OtherState, AFInfo, m%axInduction, m%tanInduction, m%chi, m, errStat2, errMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -2152,7 +2234,7 @@ subroutine BEMT_UnCoupledSolve(p, u, iBladeNode, jBlade, phi, AFInfo, ValidPhi, if (.not. ValidPhi) then - phi = ComputePhiWithInduction(u%Vx(iBladeNode,jBlade), u%Vy(iBladeNode,jBlade), 0.0_ReKi, 0.0_ReKi) + phi = ComputePhiWithInduction(u%Vx(iBladeNode,jBlade), u%Vy(iBladeNode,jBlade), 0.0_ReKi, 0.0_ReKi, u%cantangle(iBladeNode,jBlade), u%xVelCorr(iBladeNode,jBlade)) if (abs(phi)>MsgLimit .and. abs(abs(phi)-PiBy2) > MsgLimit ) then if (FirstWarn) then @@ -2175,28 +2257,39 @@ function NodeText(i,j) NodeText = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' end function NodeText !---------------------------------------------------------------------------------------------------------------------------------- -subroutine SetInputs_for_UA(phi, theta, axInduction, tanInduction, Vx, Vy, omega, chord, kinVisc, UserProp, u_UA) +subroutine SetInputs_for_UA(BEM_Mod, phi, theta, cantAngle, toeAngle, axInduction, tanInduction, chord, Vx, Vy, Vz, omega, kinVisc, UserProp, xVelCorr, u_UA) + integer(IntKi), intent(in ) :: BEM_Mod real(ReKi), intent(in ) :: UserProp ! User property (for 2D Airfoil interp) real(ReKi), intent(in ) :: phi real(ReKi), intent(in ) :: theta + real(ReKi), intent(in ) :: cantAngle + real(ReKi), intent(in ) :: toeAngle real(ReKi), intent(in ) :: axInduction real(ReKi), intent(in ) :: tanInduction real(ReKi), intent(in ) :: Vx real(ReKi), intent(in ) :: Vy + real(ReKi), intent(in ) :: Vz real(ReKi), intent(in ) :: omega ! aka PitchRate real(ReKi), intent(in ) :: chord real(ReKi), intent(in ) :: kinVisc + real(ReKi), intent(in ) :: xVelCorr type(UA_InputType), intent( out) :: u_UA ! ....... compute inputs to UA ........... - u_UA%alpha = phi - theta ! angle of attack + call computeAirfoilOperatingAOA(BEM_Mod, phi, theta, cantAngle, toeAngle ,u_UA%alpha ) u_UA%UserProp = UserProp ! Need to compute relative velocity at the aerodynamic center, including both axial and tangential induction ! COMPUTE: u_UA%U, u_UA%Re, u_UA%v_ac - call GetRelativeVelocity( axInduction, tanInduction, Vx, Vy, u_UA%U, u_UA%v_ac ) - call GetReynoldsNumber( axInduction, tanInduction, Vx, Vy, chord, kinVisc, u_UA%Re) + if (BEM_Mod==BEMMod_2D) then + ! Setting Cant, Toe and xVelCorr to 0 + call GetRelativeVelocity( axInduction, tanInduction, Vx, Vy, 0.0_ReKi, 0.0_ReKi, u_UA%U, u_UA%v_ac ) + call GetReynoldsNumber(BEM_Mod, axInduction, tanInduction, Vx, Vy, Vz, chord, kinVisc, theta, phi, 0.0_ReKi, 0.0_ReKi, u_UA%Re) + else + call GetRelativeVelocity( axInduction, tanInduction, Vx, Vy, cantAngle, xVelCorr, u_UA%U, u_UA%v_ac ) + call GetReynoldsNumber(BEM_Mod, axInduction, tanInduction, Vx, Vy, Vz, chord, kinVisc, theta, phi, cantAngle, toeAngle, u_UA%Re) + endif u_UA%v_ac(1) = sin(u_UA%alpha)*u_UA%U u_UA%v_ac(2) = cos(u_UA%alpha)*u_UA%U @@ -2221,7 +2314,7 @@ subroutine SetInputs_for_UA_AllNodes(u, p, phi, axInduction, tanInduction, u_UA) !............................................ do j = 1,p%numBlades ! Loop through all blades do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements - phi(i,j) = ComputePhiWithInduction( u%Vx(i,j), u%Vy(i,j), axInduction(i,j), tanInduction(i,j) ) + phi(i,j) = ComputePhiWithInduction( u%Vx(i,j), u%Vy(i,j), axInduction(i,j), tanInduction(i,j), u%cantAngle(i,j), u%xVelCorr(i,j) ) enddo ! I - Blade nodes / elements enddo ! J - All blades end if @@ -2233,7 +2326,7 @@ subroutine SetInputs_for_UA_AllNodes(u, p, phi, axInduction, tanInduction, u_UA) do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements ! Compute AoA, Re, Vrel (inputs to UA) based on current values of axInduction, tanInduction: - call SetInputs_for_UA(phi(i,j), u%theta(i,j), axInduction(i,j), tanInduction(i,j), u%Vx(i,j), u%Vy(i,j), u%omega_z(i,j), p%chord(i,j), p%kinVisc, u%UserProp(i,j), u_UA(i,j)) + call SetInputs_for_UA(p%BEM_Mod, phi(i,j), u%theta(i,j), u%cantAngle(i,j), u%toeAngle(i,j), axInduction(i,j), tanInduction(i,j), p%chord(i,j), u%Vx(i,j), u%Vy(i,j), u%Vz(i,j), u%omega_z(i,j), p%kinVisc, u%UserProp(i,j), u%xVelCorr(i,j), u_UA(i,j)) end do end do @@ -2286,7 +2379,6 @@ subroutine WriteDEBUGValuesToFile(t, u, p, x, xd, z, OtherState, m, AFInfo) , "omega_z" & , "rLocal" , "UserProp" & , "AxInd", "TanInd" -! , "Vx_elast_dot" , "Vy_elast_dot" & end if @@ -2312,9 +2404,6 @@ subroutine WriteDEBUGValuesToFile(t, u, p, x, xd, z, OtherState, m, AFInfo) , u%UserProp( DEBUG_BLADENODE,DEBUG_BLADE) & , m%axInduction( DEBUG_BLADENODE,DEBUG_BLADE) & , m%tanInduction(DEBUG_BLADENODE,DEBUG_BLADE) -! these are not always allocated -! , u%Vx_elast_dot(DEBUG_BLADENODE,DEBUG_BLADE) & -! , u%Vy_elast_dot(DEBUG_BLADENODE,DEBUG_BLADE) & ! now write the residual function to a separate file: if ((DEBUG_nStep >= 0).AND.(DEBUG_nStep <= 450000).AND.(MOD(DEBUG_nStep,25) == 0)) then diff --git a/modules/aerodyn/src/BEMTUncoupled.f90 b/modules/aerodyn/src/BEMTUncoupled.f90 index 1107f48aa..5d4b9a34f 100644 --- a/modules/aerodyn/src/BEMTUncoupled.f90 +++ b/modules/aerodyn/src/BEMTUncoupled.f90 @@ -26,21 +26,19 @@ module BEMTUnCoupled use UnsteadyAero use UnsteadyAero_Types use BEMT_Types + use PolynomialRoots implicit none - integer(IntKi), public, parameter :: SkewMod_Orthogonal = 0 ! Inflow orthogonal to rotor [-] - integer(IntKi), public, parameter :: SkewMod_Uncoupled = 1 ! Uncoupled (no correction) [-] - integer(IntKi), public, parameter :: SkewMod_PittPeters = 2 ! Pitt/Peters [-] - integer(IntKi), public, parameter :: SkewMod_Coupled = 3 ! Coupled [-] - real(ReKi), public, parameter :: BEMT_MaxInduction(2) = (/1.5_ReKi, 1.0_ReKi /) ! largest magnitude of axial (1) and tangential (2) induction factors real(ReKi), public, parameter :: BEMT_MinInduction(2) = -1.0_ReKi real(ReKi), public, parameter :: BEMT_lowerBoundTSR = 1.0_ReKi real(ReKi), public, parameter :: BEMT_upperBoundTSR = 2.0_ReKi + real(R8Ki), parameter :: MaxTanChi0 = 100.0_R8Ki ! maximum absolute value allowed for tan(chi0), an arbitary large number + !1e-6 works for double precision, but not single precision real(ReKi), public, parameter :: BEMT_epsilon2 = 10.0_ReKi*sqrt(epsilon(1.0_ReKi)) !this is the tolerance in radians for values around singularities in phi (i.e., phi=0 and phi=pi/2); must be large enough so that EqualRealNos(BEMT_epsilon2, 0.0_ReKi) is false @@ -52,8 +50,13 @@ module BEMTUnCoupled public :: BEMTU_InductionWithResidual public :: ApplySkewedWakeCorrection public :: Transform_ClCd_to_CxCy + public :: getAirfoilOrientation + public :: getAirfoilOrientationMatrix + public :: computeAirfoilOperatingAOA + public :: Transform_ClCdCm_to_CxCyCzCmxCmyCmz public :: getHubTipLossCorrection public :: limitInductionFactors + public :: GetEulerAnglesFromOrientation public :: VelocityIsZero contains @@ -74,40 +77,163 @@ function VelocityIsZero ( v ) end function VelocityIsZero !.................................................................................................................................. - subroutine GetReynoldsNumber( axInduction, tanInduction, Vx, Vy, chord, nu, Re ) + subroutine GetReynoldsNumber(BEM_Mod, axInduction, tanInduction, Vx, Vy, Vz, chord, nu, theta, phi, cantAngle, toeAngle , Re ) + ! in - real(ReKi), intent(in) :: axInduction, tanInduction, Vx, Vy + integer(IntKi), intent(in) :: BEM_Mod + real(ReKi), intent(in) :: axInduction, tanInduction, Vx, Vy, Vz real(ReKi), intent(in) :: chord, nu - + real(ReKi), intent(in) :: cantAngle, theta, phi, toeAngle !note phi is unused + ! out real(ReKi), intent(out) :: Re ! Reynolds number - real(ReKi) :: W ! relative velocity + real(ReKi) :: Wxy ! relative velocity + real(ReKi) :: afAxialVec(3), afNormalVec(3), afRadialVec(3), inflowVec(3),inflowVecInAirfoilPlane(3) +!bjj: this doesn't seem consistent with computeAirfoilOperatingAOA, which uses phiN + inflowVec(1) = Vx*(1-axInduction) + inflowVec(2) = Vy*(1+tanInduction) + inflowVec(3) = Vz + + ! Project inflow vector onto airfoil plane + if(BEM_Mod==BEMMod_2D) then + ! TODO TODO TODO EB CHECK THAT THE SAME MIGHT BE OBTAINED IF cant=0, toe=0 + inflowVecInAirfoilPlane(1) = inflowVec(1) + inflowVecInAirfoilPlane(2) = inflowVec(2) + inflowVecInAirfoilPlane(3) = 0.0_ReKi + else + call getAirfoilOrientation( theta, cantAngle,toeAngle ,afAxialVec, afNormalVec, afRadialVec ) + inflowVecInAirfoilPlane = inflowVec - dot_product( inflowVec, afRadialVec ) * afRadialVec - W = sqrt((Vx*(1-axInduction))**2 + (Vy*(1+tanInduction))**2) + endif + + ! Wxy: resultant velocity in the xy airfoil plane. + Wxy = sqrt(inflowVecInAirfoilPlane(1)**2 + inflowVecInAirfoilPlane(2)**2) - Re = W * chord / nu - if ( EqualRealNos(Re, 0.0_ReKi) ) Re = 0.001 ! Do this to avoid a singularity when we take log(Re) in the airfoil lookup. + Re = Wxy * chord / nu + if ( Re <= 0.001 ) Re = 0.001 ! Do this to avoid a singularity when we take log(Re) in the airfoil lookup. end subroutine GetReynoldsNumber !.................................................................................................................................. - subroutine GetRelativeVelocity( axInduction, tanInduction, Vx, Vy, Vrel, v_ac ) + subroutine GetRelativeVelocity( axInduction, tanInduction, Vx, Vy, cantAngle, xVelCorr, Vrel, v_ac ) ! in - real(ReKi), intent(in) :: axInduction, tanInduction, Vx, Vy + real(ReKi), intent(in) :: axInduction, tanInduction, Vx, Vy, cantAngle, xVelCorr ! out real(ReKi), intent(out) :: Vrel ! relative velocity real(ReKi), intent(out) :: v_ac(2) ! components of relative velocity - v_ac(1) = Vx*(1-axInduction) - v_ac(2) = Vy*(1+tanInduction) +!bjj: check that the cantAngle modification works for UA!!!! + + v_ac(1) = (Vx*cos(cantAngle)+xVelCorr)*(1.0_ReKi - axInduction) + v_ac(2) = Vy*(1.0_ReKi + tanInduction) Vrel = TwoNorm(v_ac) + end subroutine GetRelativeVelocity !.................................................................................................................................. +!> getAirfoilOrientation = R_ap = transformation from from polar coordinate system of the section to the airfoil coordinate system + subroutine getAirfoilOrientation( theta, cantAngle, toeAngle, afAxialVec, afNormalVec, afRadialVec ) + ! Routine for creating the airfoil orientation vectors + + implicit none + + real(ReKi), intent(in ) :: theta + real(ReKi), intent(in ) :: cantAngle + real(ReKi), intent(in ) :: toeAngle + real(ReKi), intent( out) :: afAxialVec(3) + real(ReKi), intent( out) :: afNormalVec(3) + real(ReKi), intent( out) :: afRadialVec(3) + real(ReKi) :: orientation(3) + real(ReKi) :: rotMat(3,3) + + orientation(1) = toeAngle + orientation(2) = cantAngle + orientation(3) = -theta + rotMat = EulerConstruct( orientation ) ! = R_ap: from polar to airfoil + + ! unit vector normal to the chord line in the airfoil plane + afNormalVec = rotMat(1,:) + + ! unit vector tangent to the chord line in the airfoil plane + ! pointing from leading- to trailing-edge + afAxialVec = rotMat(2,:) + + ! Unit vector normal to airfoil plane + afRadialVec = rotMat(3,:) + + end subroutine getAirfoilOrientation +!.................................................................................................................................. +!> getAirfoilOrientation = R_ap = transformation from from polar coordinate system of the section to the airfoil coordinate system + subroutine getAirfoilOrientationMatrix( theta, cantAngle, toeAngle, rotMat) + ! Routine for creating the airfoil orientation vectors + + implicit none + + real(ReKi), intent(in ) :: theta + real(ReKi), intent(in ) :: cantAngle + real(ReKi), intent(in ) :: toeAngle + real(ReKi), intent(out ) :: rotMat(3,3) + real(ReKi) :: orientation(3) + + orientation(1) = toeAngle + orientation(2) = cantAngle + orientation(3) = -theta + rotMat = EulerConstruct( orientation ) ! = R_ap: from polar to airfoil + end subroutine getAirfoilOrientationMatrix +!.................................................................................................................................. + subroutine computeAirfoilOperatingAOA( BEM_Mod, phi, theta, cantAngle, toeAngle, AoA ) + ! Routine for computing local angle-of-attack in the airfoil reference frame + ! accounting for the current orientation of the airfoil relative to the inflow + ! defined by the phi angle. + + implicit none + + integer(IntKi), intent(in ) :: BEM_Mod + real(ReKi), intent(in ) :: phi + real(ReKi), intent(in ) :: theta + real(ReKi), intent(in ) :: cantAngle + real(ReKi), intent(in ) :: toeAngle + real(ReKi), intent( out) :: AoA + real(ReKi) :: afAxialVec(3) + real(ReKi) :: afNormalVec(3) + real(ReKi) :: afRadialVec(3) + real(ReKi) :: inflowVec(3) + real(ReKi) :: inflowVecInAirfoilPlane(3) + real(ReKi) :: signOfAngle + real(ReKi) :: numer, denom, ratio + real(ReKi) :: phiN + + if (BEM_Mod==BEMMod_2D) then + AoA = phi - theta ! angle of attack + else + ! get airfoil orientation vectors + call getAirfoilOrientation( theta, cantAngle, toeAngle ,afAxialVec, afNormalVec, afRadialVec ) + phiN = getNewPhi(phi,cantAngle) + + ! Create inflow vector + inflowVec(1) = sin( phiN) + inflowVec(2) = cos( phiN) + inflowVec(3) = 0.0_Reki + + ! Project inflow vector onto airfoil plane + inflowVecInAirfoilPlane = inflowVec - dot_product( inflowVec, afRadialVec ) * afRadialVec + + ! Determine angle of attack as angle between airfoil chordline (afAxialVec) and inflow (inflowVecInAirfoilPlane) + numer = dot_product( inflowVecInAirfoilPlane, afAxialVec ) + denom = TwoNorm( inflowVecInAirfoilPlane ) + ratio = numer / denom + AoA = acos( max( min( ratio, 1.0_ReKi ), -1.0_ReKi ) ) + signOfAngle = dot_product( cross_product( inflowVecInAirfoilPlane, afAxialVec ), afRadialVec ) + AoA = sign( AoA, signOfAngle ) + endif + + +end subroutine computeAirfoilOperatingAOA +!.................................................................................................................................. subroutine Transform_ClCd_to_CxCy( phi, useAIDrag, useTIDrag, Cl, Cd, Cx, Cy ) real(ReKi), intent(in ) :: phi logical, intent(in ) :: useAIDrag @@ -137,10 +263,59 @@ subroutine Transform_ClCd_to_CxCy( phi, useAIDrag, useTIDrag, Cl, Cd, Cx, Cy ) end subroutine Transform_ClCd_to_CxCy !---------------------------------------------------------------------------------------------------------------------------------- +subroutine Transform_ClCdCm_to_CxCyCzCmxCmyCmz( phi, theta, cant,toeAngle ,useAIDrag, useTIDrag, AOA, Cl, Cd, Cm, Cx, Cy, Cz, Cmx, Cmy, Cmz ) + implicit none + + real(ReKi), intent(in ) :: phi ! note that this is unused + real(ReKi), intent(in ) :: theta + real(ReKi), intent(in ) :: cant + real(ReKi), intent(in ) :: toeAngle + logical, intent(in ) :: useAIDrag + logical, intent(in ) :: useTIDrag + real(ReKi), intent(in ) :: AOA + real(ReKi), intent(in ) :: Cl + real(ReKi), intent(in ) :: Cd + real(ReKi), intent(in ) :: Cm + real(ReKi), intent( out) :: Cx, Cy, Cz + real(ReKi), intent( out) :: Cmx, Cmy, Cmz + real(ReKi) :: afAxialVec(3) + real(ReKi) :: afNormalVec(3) + real(ReKi) :: afRadialVec(3) + real(ReKi) :: coeffVec(3) + real(ReKi) :: Cn + real(ReKi) :: Ct + + ! get airfoil orientation vectors + call getAirfoilOrientation( theta, cant, toeAngle, afAxialVec, afNormalVec, afRadialVec ) + + ! transform force coefficients into airfoil frame + if ( useAIDrag ) then + Cn = Cl*cos(AOA) + Cd*sin(AOA) + else + Cn = Cl*cos(AOA) + end if + if ( useTIDrag ) then + Ct = -Cl*sin(AOA) + Cd*cos(AOA) + else + Ct = -Cl*sin(AOA) + end if + + ! Put force coefficients back into rotor plane reference frame + coeffVec = Cn*afNormalVec + Ct*afAxialVec + Cx = coeffVec(1) + Cy = -coeffVec(2) + Cz = coeffVec(3) + + ! Put moment coefficients into the rotor reference frame + coeffVec = Cm * afRadialVec + Cmx = coeffVec(1) + Cmy = coeffVec(2) + Cmz = coeffVec(3) +end subroutine Transform_ClCdCm_to_CxCyCzCmxCmyCmz !---------------------------------------------------------------------------------------------------------------------------------- !>This is the residual calculation for the uncoupled BEM solve -real(ReKi) function BEMTU_InductionWithResidual(p, u, i, j, phi, AFInfo, IsValidSolution, ErrStat, ErrMsg, a, ap ) result (ResidualVal) +real(ReKi) function BEMTU_InductionWithResidual(p, u, i, j, phi, AFInfo, IsValidSolution, ErrStat, ErrMsg, a, ap, k, kp, Cx_out, Cy_out ) result (ResidualVal) type(BEMT_ParameterType),intent(in ) :: p !< parameters @@ -155,6 +330,9 @@ real(ReKi) function BEMTU_InductionWithResidual(p, u, i, j, phi, AFInfo, IsValid character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None real(ReKi), optional, intent( out) :: a ! computed axial induction real(ReKi), optional, intent( out) :: ap ! computed tangential induction + real(ReKi), optional, intent( out) :: k ! k in the induction factors routine + real(ReKi), optional, intent( out) :: kp ! kp in the induction factors routine + ! Local variables @@ -166,18 +344,22 @@ real(ReKi) function BEMTU_InductionWithResidual(p, u, i, j, phi, AFInfo, IsValid real(ReKi) :: axInduction real(ReKi) :: tanInduction + real(ReKi) :: F ! tip/hub loss factor real(ReKi) :: Re - real(ReKi) :: Cx, Cy + real(ReKi) :: Cx, Cy, Cz + real(ReKi), optional, intent( out) :: Cx_out, Cy_out + real(ReKi) :: dumX,dumY,dumZ, k_out, kp_out TYPE(AFI_OutputType) :: AFI_interp - ErrStat = ErrID_None ErrMsg = "" ResidualVal = 0.0_ReKi IsValidSolution = .true. + k_out = 0 + kp_out = 0 + ! make these return values consistent with what is returned in inductionFactors routine: - ! Set the local version of the induction factors if ( p%FixedInductions(i,j) ) then ! We are simply going to bail if we are using tiploss and tipLossConst = 0 or using hubloss and hubLossConst=0, regardless of phi! [do this before checking if Vx or Vy is zero or you'll get jumps in the induction and loads] @@ -187,36 +369,64 @@ real(ReKi) function BEMTU_InductionWithResidual(p, u, i, j, phi, AFInfo, IsValid axInduction = 0.0_ReKi tanInduction = 0.0_ReKi else !if ( (.NOT. VelocityIsZero(Vx)) .AND. (.NOT. VelocityIsZero(Vy)) ) then + + ! Compute operating conditions in the airfoil reference frame + call computeAirfoilOperatingAOA(p%BEM_Mod, phi, u%theta(i,j), u%cantAngle(i,j), u%toeAngle(i,j), AOA ) - AOA = phi - u%theta(i,j) - ! FIX ME: Note that the Re used here is computed assuming axInduction and tanInduction are 0. Is that a problem for 2D Re interpolation on airfoils? or should update solve method to take this into account? - call GetReynoldsNumber( 0.0_ReKi, 0.0_ReKi, u%Vx(i,j), u%Vy(i,j), p%chord(i,j), p%kinVisc, Re) + call GetReynoldsNumber(p%BEM_Mod, 0.0_ReKi, 0.0_ReKi, u%Vx(i,j), u%Vy(i,j), u%Vz(i,j), p%chord(i,j), p%kinVisc, u%theta(i,j), phi, u%cantAngle(i,j), u%toeAngle(i,j), Re) + call AFI_ComputeAirfoilCoefs( AOA, Re, u%UserProp(i,j), AFInfo, AFI_interp, errStat2, errMsg2 ) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) if (ErrStat >= AbortErrLev) return ! Compute Cx, Cy given Cl, Cd and phi, we honor the useAIDrag and useTIDrag flag because Cx,Cy are only used for the solution of inductions - call Transform_ClCd_to_CxCy( phi, p%useAIDrag, p%useTIDrag, AFI_interp%Cl, AFI_interp%Cd, Cx, Cy ) + if(p%BEM_Mod==BEMMod_2D) then + call Transform_ClCd_to_CxCy( phi, p%useAIDrag, p%useTIDrag, AFI_interp%Cl, AFI_interp%Cd, Cx, Cy ) + else + call Transform_ClCdCm_to_CxCyCzCmxCmyCmz( phi, u%theta(i,j), u%cantAngle(i,j), u%toeAngle(i,j), p%useAIDrag, p%useTIDrag, & + AOA, AFI_interp%Cl, AFI_interp%Cd, AFI_interp%Cm, Cx, Cy, Cz, dumX, dumY, dumZ ) + endif + + + !..................................................... + ! Prandtl's tip and hub loss factor: + !..................................................... + ! Note: cantAngle is 0 for BEMMod_2D + F = getHubTipLossCorrection(p%BEM_Mod, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), phi, u%cantAngle(i,j) ) + F = max(F,0.0001_ReKi) ! Determine axInduction, tanInduction for the current Cl, Cd, phi - call inductionFactors( u%rlocal(i,j), p%chord(i,j), phi, Cx, Cy, p%numBlades, & - u%Vx(i,j), u%Vy(i,j), p%useTanInd, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & + if(p%BEM_Mod==BEMMod_2D) then + call inductionFactors0(p%numBlades, u%rlocal(i,j), p%chord(i,j), phi, Cx, Cy, u%Vx(i,j), u%Vy(i,j), F, p%useTanInd, & ResidualVal, axInduction, tanInduction, IsValidSolution) + else + call inductionFactors2(p%BEM_Mod, p%numBlades, u%rlocal(i,j), p%chord(i,j), phi, Cx, Cy, u%Vx(i,j), u%Vy(i,j), u%drdz(i,j), u%cantAngle(i,j), F, u%CHI0, p%useTanInd, & + ResidualVal, axInduction, tanInduction, p%MomentumCorr, u%xVelCorr(i,j), IsValidSolution, k_out, kp_out ) + + endif end if if (present(a )) a = axInduction if (present(ap)) ap = tanInduction + if (present(k )) k = k_out + if (present(kp)) kp = kp_out + if (present(Cx_out)) Cx_out = Cx + if (present(Cy_out)) Cy_out = Cy end function BEMTU_InductionWithResidual !----------------------------------------------------------------------------------------- -subroutine ApplySkewedWakeCorrection( yawCorrFactor, azimuth, chi0, tipRatio, a, chi, FirstWarn ) +subroutine ApplySkewedWakeCorrection(BEM_Mod, SkewMod, yawCorrFactor, F, azimuth, azimuthOffset, chi0, tipRatio, a, chi, FirstWarn ) + integer(IntKi), intent(in ) :: BEM_Mod + integer(IntKi), intent(in ) :: SkewMod real(ReKi), intent(in ) :: yawCorrFactor ! set to 15*pi/32 previously; now allowed to be input (to better match data) + real(ReKi), intent(in ) :: F ! tip/hub loss factor real(ReKi), intent(in ) :: azimuth + real(ReKi), intent(in ) :: azimuthOffset ! offset angle of most downwind blade position real(ReKi), intent(in ) :: chi0 real(ReKi), intent(in ) :: tipRatio ! r/Rtip real(ReKi), intent(inout) :: a @@ -229,8 +439,13 @@ subroutine ApplySkewedWakeCorrection( yawCorrFactor, azimuth, chi0, tipRatio, a, ! Skewed wake correction - - chi = (0.6_ReKi*a + 1.0_ReKi)*chi0 + IF (.true.) then + if(BEM_Mod==BEMMod_2D) then + chi = (0.6_ReKi*a + 1.0_ReKi)*chi0 + else + chi = (0.6_ReKi*a + 1.0_ReKi)*abs(chi0) + endif + END IF call MPi2Pi( chi ) ! make sure chi is in [-pi, pi] before testing if it's outside a valid range @@ -257,41 +472,39 @@ subroutine ApplySkewedWakeCorrection( yawCorrFactor, azimuth, chi0, tipRatio, a, end subroutine ApplySkewedWakeCorrection !----------------------------------------------------------------------------------------- !> This subroutine computes the induction factors (a) and (ap) along with the residual (fzero) -subroutine inductionFactors(r, chord, phi, cn, ct, B, Vx, Vy, wakerotation, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & - fzero, a, ap, IsValidSolution) +subroutine inductionFactors0(B, r, chord, phi, cn, ct, Vx, Vy, F, wakerotation, & + fzero, a_out, ap_out, IsValidSolution) implicit none ! in + integer, intent(in) :: B !< number of blades [p%numBlades] real(ReKi), intent(in) :: r !< local radial position [u%rlocal] real(ReKi), intent(in) :: chord !< chord [p%chord] real(ReKi), intent(in) :: phi !< angle between the plane of rotation and the direction of the local wind [y%phi]; must be in range [-pi,pi] real(ReKi), intent(in) :: cn !< normal force coefficient (normal to the plane, not chord) of the jth node in the kth blade; [y%cx] real(ReKi), intent(in) :: ct !< tangential force coefficient (tangential to the plane, not chord) of the jth node in the kth blade; [y%cy] - integer, intent(in) :: B !< number of blades [p%numBlades] real(ReKi), intent(in) :: Vx !< velocity component [u%Vx] real(ReKi), intent(in) :: Vy !< velocity component [u%Vy] - real(ReKi), intent(in) :: hubLossConst !< hub loss constant [p%hubLossConst] - real(ReKi), intent(in) :: tipLossConst !< tip loss constant [p%tipLossConst] - logical, intent(in) :: useHubLoss !< hub-loss flag [p%useHubLoss] - logical, intent(in) :: useTipLoss !< tip-loss flag [p%useTipLoss] + real(ReKi), intent(in) :: F !< hub/tip loss correction factor logical, intent(in) :: wakerotation !< Include tangential induction in BEMT calculations [flag] [p%useTanInd] ! out real(ReKi), intent(out) :: fzero !< residual of BEM equations - real(ReKi), intent(out) :: a !< axial induction [y%axInduction] - real(ReKi), intent(out) :: ap !< tangential induction, i.e., a-prime [y%tanInduction] + real(ReKi), intent(out) :: a_out !< axial induction [y%axInduction] + real(ReKi), intent(out) :: ap_out !< tangential induction, i.e., a-prime [y%tanInduction] logical, intent(out) :: IsValidSolution !< this is set to false if k<=1 in the propeller brake region or k<-1 in the momentum region, indicating an invalid solution ! local - real(ReKi) :: sigma_p ! local solidity (B*chord/(TwoPi*r)) - real(ReKi) :: sphi, cphi, lambda_r - real(ReKi) :: k, kp ! non-dimensional parameters - real(ReKi) :: F ! hub/tip loss correction factor + real(R8Ki) :: VxCorrected + real(R8Ki) :: sigma_p ! local solidity (B*chord/(TwoPi*r)) + real(R8Ki) :: sphi, cphi, lambda_r + real(R8Ki) :: k, kp ! non-dimensional parameters real(ReKi) :: g1, g2, g3 real(ReKi) :: temp ! temporary variable so we don't have to calculate 2.0_ReKi*F*k multiple times - real(ReKi), parameter :: InductionLimit = 1000000.0_ReKi + real(R8Ki) :: a, ap ! double precision versions of output variables of similar name + real(R8Ki), parameter :: InductionLimit = 1000000.0_R8Ki logical :: momentumRegion @@ -309,13 +522,7 @@ subroutine inductionFactors(r, chord, phi, cn, ct, B, Vx, Vy, wakerotation, useH cphi = cos(phi) - !..................................................... - ! Prandtl's tip and hub loss factor: - !..................................................... - F = getHubTipLossCorrection(sphi, useHubLoss, useTipLoss, hubLossConst, tipLossConst) ! Prandtl's tip and hub loss factor - - !..................................................... ! compute axial induction factor: !..................................................... @@ -330,13 +537,13 @@ subroutine inductionFactors(r, chord, phi, cn, ct, B, Vx, Vy, wakerotation, useH ! update axial induction factor if (k <= 2.0_ReKi/3.0_ReKi) then ! momentum state for a < 0.4 - if ( EqualRealNos(k,-1.0_ReKi) ) then - a = -sign(InductionLimit, 1.0_ReKi+k) + if ( EqualRealNos(k,-1.0_R8Ki) ) then + a = -sign(InductionLimit, 1.0_R8Ki+k) else - a = k/(1.0_ReKi+k) + a = k/(1.0_R8Ki+k) end if - if (k<-1.0_ReKi) then ! k < -1 cannot be a solution in momentum region (this is equivalent to a>1.0) + if (k<-1.0_R8Ki) then ! k < -1 cannot be a solution in momentum region (this is equivalent to a>1.0) IsValidSolution = .false. end if @@ -361,15 +568,15 @@ subroutine inductionFactors(r, chord, phi, cn, ct, B, Vx, Vy, wakerotation, useH else ! propeller brake - if ( EqualRealNos(k,1.0_ReKi) ) then + if ( EqualRealNos(k,1.0_R8Ki) ) then IsValidSolution = .false. a = InductionLimit else - a = k/(k-1.0_ReKi) + a = k/(k-1.0_R8Ki) end if - if (k<=1.0_ReKi) then ! k <= 1 cannot be a solution in propeller brake region (this is equivalent to a<1.0) + if (k<=1.0_R8Ki) then ! k <= 1 cannot be a solution in propeller brake region (this is equivalent to a<1.0) IsValidSolution = .false. end if @@ -380,35 +587,15 @@ subroutine inductionFactors(r, chord, phi, cn, ct, B, Vx, Vy, wakerotation, useH !..................................................... if (wakerotation) then - - ! compute tangential induction factor - if ( EqualRealNos(cphi,0.0_ReKi) ) then - - ap = -1.0_ReKi - kp = sign(InductionLimit, ct*sphi)*sign(1.0_ReKi,Vx) - - else - - kp = sigma_p*ct/4.0_ReKi/F/sphi/cphi - if (Vx < 0.0_ReKi) then - kp = -kp - end if - - - if ( EqualRealNos(kp,1.0_ReKi) ) then - ap = sign(InductionLimit, 1.0_ReKi-kp) - else - ap = kp/(1.0_ReKi-kp) - end if - - endif + VxCorrected = Vx + call getTangentialInduction(a, cphi, sphi, Vx, F, 1.0_R8Ki, sigma_p, ct, VxCorrected, 0.0_R8Ki, 1.0_R8Ki, .False., ap, kp) else ! we're not computing tangential induction: - ap = 0.0_ReKi - kp = 0.0_ReKi - + ap = 0.0_R8Ki + kp = 0.0_R8Ki +! end if @@ -418,7 +605,7 @@ subroutine inductionFactors(r, chord, phi, cn, ct, B, Vx, Vy, wakerotation, useH lambda_r = Vy/Vx if (momentumRegion) then ! momentum/empirical - if ( EqualRealNos(a, 1.0_ReKi) ) then + if ( EqualRealNos(a, 1.0_R8Ki) ) then fzero = - cphi/lambda_r*(1-kp) else fzero = sphi/(1-a) - cphi/lambda_r*(1-kp) @@ -428,8 +615,372 @@ subroutine inductionFactors(r, chord, phi, cn, ct, B, Vx, Vy, wakerotation, useH fzero = sphi*(1-k) - cphi/lambda_r*(1-kp) end if -end subroutine inductionFactors + + ! Convert from double to ReKi + a_out = real( a, ReKi ) + ap_out = real( ap, ReKi ) + +end subroutine inductionFactors0 +subroutine getTangentialInduction(a, cphi, sphi, Vx, F, kCorrectionFactor, sigma_p, ct, VxCorrected, effectiveYaw, H, MomentumCorr, ap, kp) + real(ReKi), intent(in) :: Vx !< velocity component [u%Vx] + real(ReKi), intent(in) :: F !< hub/tip loss correction factor + logical, intent(in) :: MomentumCorr !< Include tangential induction in BEMT calculations [flag] [p%useTanInd] + real(ReKi), intent(in) :: ct !< tangential force coefficient (tangential to the plane, not chord) of the jth node in the kth blade; [y%cy] + real(R8Ki), intent(in) :: sigma_p ! local solidity (B*chord/(TwoPi*r)) + real(R8Ki), intent(in) :: sphi, cphi ! sin(phi), cos(phi) + real(R8Ki), intent(in) :: VxCorrected, kCorrectionFactor + real(R8Ki), intent(in) :: effectiveYaw ! + real(R8Ki), intent(in) :: H ! scaling factor to gradually phase out tangential induction when axial induction is near 1.0 + real(R8Ki), intent(in) :: a ! double precision versions of output variables of similar name + real(R8Ki), intent(out) :: kp ! non-dimensional parameters + real(R8Ki), intent(out) :: ap ! double precision versions of output variables of similar name + real(R8Ki), parameter :: InductionLimit = 1000000.0_R8Ki + + ! compute tangential induction factor + if ( EqualRealNos(cphi,0.0_R8Ki) ) then + + ap = -1.0_R8Ki + kp = sign(InductionLimit, ct*sphi)*sign(1.0_R8Ki,real(Vx,R8Ki)) + + else + !H = smoothStep( real(a,ReKi), 0.8, 1.0, 1.0, 0.0 ) + smoothStep( real(a,ReKi), 1.0, 0.0, 1.2, 1.0 ) + !kp = sigma_p*( cl*sphi - H*cd*cphi )/( 4.0*F*sphi*cphi )*kCorrectionFactor + if (MomentumCorr) then + if (equalrealnos(a,1.0_R8Ki)) then + kp = 0.0_R8Ki !H*sigma_p*ct/( 4.0*F*sphi*cphi )*(kCorrectionFactor) + else + kp = H*sigma_p*ct/( 4.0*F*sphi*cphi )*(kCorrectionFactor)/sqrt(1+(tan(effectiveYaw)/(1.0_ReKi-a))**2) + endif + else + kp = H*sigma_p*ct/( 4.0*F*sphi*cphi )*kCorrectionFactor + endif + + if ( VxCorrected < 0.0_ReKi ) then + kp = -kp + endif + + if ( EqualRealNos(kp,1.0_R8Ki) ) then + ap = sign(InductionLimit, 1.0_R8Ki-kp) + else + ap = kp/(1.0_R8Ki-kp) + end if + + endif +end subroutine getTangentialInduction +!----------------------------------------------------------------------------------------- +!> This subroutine computes the induction factors (a) and (ap) along with the residual (fzero) +subroutine inductionFactors2( BEM_Mod, B, r, chord, phi, cn, ct, Vx, Vy, drdz,cantAngle, F, CHI0, wakerotation, & + fzero_out, a_out, ap_out, MomentumCorr, xVelCorr, IsValidSolution, k_out, kp_out ) + + implicit none + + ! in + integer, intent(in) :: BEM_Mod + integer, intent(in) :: B !< number of blades [p%numBlades] + real(ReKi), intent(in) :: r !< local radial position [u%rlocal] + real(ReKi), intent(in) :: chord !< chord [p%chord] + real(ReKi), intent(in) :: phi !< angle between the plane of rotation and the direction of the local wind [y%phi]; must be in range [-pi,pi] + real(ReKi), intent(in) :: cn !< normal force coefficient (normal to the plane, not chord) of the jth node in the kth blade; [y%cx] + real(ReKi), intent(in) :: ct !< tangential force coefficient (tangential to the plane, not chord) of the jth node in the kth blade; [y%cy] + real(ReKi), intent(in) :: Vx !< velocity component [u%Vx] + real(ReKi), intent(in) :: Vy !< velocity component [u%Vy] + real(ReKi), intent(in) :: drdz, cantAngle + real(ReKi), intent(in) :: F !< hub/tip loss correction factor + real(ReKi), intent(in) :: CHI0 !< Yaw + logical, intent(in) :: wakerotation !< Include tangential induction in BEMT calculations [flag] [p%useTanInd] + logical, intent(in) :: MomentumCorr !< Include tangential induction in BEMT calculations [flag] [p%useTanInd] + real(ReKi), intent(in) :: xVelCorr + ! out + real(ReKi), intent(out) :: fzero_out !< residual of BEM equations + real(ReKi), intent(out) :: a_out !< axial induction [y%axInduction] + real(ReKi), intent(out) :: ap_out !< tangential induction, i.e., a-prime [y%tanInduction] + logical, intent(out) :: IsValidSolution !< this is set to false if k<=1 in the propeller brake region or k<-1 in the momentum region, indicating an invalid solution + real(ReKi), intent(out) :: k_out + real(ReKi), intent(out) :: kp_out + + ! local variables + ! NOTE!!! Double precision is used here to help the numerics which become + ! poorly behaved in the vicinity of phi = 0.0 + + real(R8Ki) :: sigma_p ! local solidity (B*chord/(TwoPi*r)) + real(R8Ki) :: sphi, cphi ! sin(phi), cos(phi) + real(R8Ki) :: k, kp ! non-dimensional parameters + real(R8Ki) :: VxCorrected, kCorrectionFactor + real(R8Ki) :: effectiveYaw ! + + + real(R8Ki) :: k0 + real(R8Ki) :: H ! scaling factor to gradually phase out tangential induction when axial induction is near 1.0 + real(R8Ki) :: fzero, a, ap ! double precision versions of output variables of similar name + + real(R8Ki), parameter :: InductionLimit = 1000000.0_R8Ki + + IsValidSolution = .true. + + !..................................................... + ! Some special cases have already been taken care of in BEMTU_InductionWithResidual, the only routine that calls this function + !..................................................... + + !..................................................... + ! Temporary variables: + !..................................................... + effectiveYaw = abs( CHI0 ) + if (equalrealnos(cos(effectiveYaw),0.0_R8Ki)) then + effectiveYaw = effectiveYaw + sqrt(epsilon(effectiveYaw)) + endif + !effectiveYaw = min( 40.0_R8Ki*D2R, effectiveYaw ) + sphi = sin(real(phi,R8Ki)) + cphi = cos(real(phi,R8Ki)) + + !..................................................... + ! compute axial induction factor: + !..................................................... + sigma_p = B*chord/(TwoPi_R8*r) ! local solidity + k = sigma_p*cn/(4.0_R8Ki*F*sphi*sphi)*drdz + + ! "corrections" + VxCorrected = Vx*cos(cantAngle)+xVelCorr + kCorrectionFactor = 1.0_R8Ki + xVelCorr/(Vx*cos(real(cantAngle,R8Ki))) + k = k*kCorrectionFactor**2 + + !k = sign( k, real(phi,R8Ki) ) + k0 = a0(effectiveYaw) / (1.0-a0(effectiveYaw)) + if (.not.MomentumCorr) then + if (k <= k0 ) then + if (VxCorrected > 0.0) then + a = k/(k+1.0) + else + a = k/(k-1.0) + end if + H = 1.0_R8Ki + else + call axialInductionFromEmpiricalThrust( effectiveYaw, phi, k, F, a, H, MomentumCorr ) + endif + else + call axialInductionFromGlauertMomentum(effectiveYaw, phi, k, F, a, H, MomentumCorr) + a = sign(a,k) + endif + + + !..................................................... + ! compute tangential induction factor: + !..................................................... + if (wakerotation) then + call getTangentialInduction(a, cphi, sphi, Vx, F, kCorrectionFactor, sigma_p, ct, VxCorrected, effectiveYaw, H, MomentumCorr, ap, kp) + else + + ! we're not computing tangential induction: + ap = 0.0_R8Ki + kp = 0.0_R8Ki + + end if + + !..................................................... + ! error function (residual) + !..................................................... + if ( EqualRealNos(a,1.0_R8Ki)) then + fzero = - cphi/(Vy*(1.0_R8Ki+ap)) + elseif (EqualRealNos(ap,-1.0_R8Ki)) then + fzero = sphi/(1.0_R8Ki-a) + else + if (momentumCorr) then + fzero = sphi/(1.0_R8Ki-a) - VxCorrected/Vy*cphi/(1.0_R8Ki+ap)!sphi*Vy(1.0_R8Ki+ap) - cphi*(1.0_R8Ki-a)*VxCorrected !sphi*Vy*(1.0_R8Ki+ap) - cphi*VxCorrected*(1.0_R8Ki-a)!cphi/(1.0_R8Ki+ap)*(1.0_R8Ki-a)-sphi*Vy/VxCorrected + else + fzero = sphi/(1.0_R8Ki-a) - VxCorrected/Vy*cphi/(1.0_R8Ki+ap) + endif + + endif + + ! Convert from double to ReKi + fzero_out = real( fzero, ReKi ) + a_out = real( a, ReKi ) + ap_out = real( ap, ReKi ) + k_out = real( k, ReKi ) + kp_out = real( kp, ReKi ) + +end subroutine inductionFactors2 + +real(R8Ki) function a0(chi0) + implicit none + real(R8Ki), intent(in) :: chi0 + a0 = 0.5*cos(45.0*D2R)/cos(chi0) + a0 = min( a0, 0.5_R8Ki ) +end function a0 + !----------------------------------------------------------------------------------------- +subroutine axialInductionFromEmpiricalThrust( chi0, phi, k, F, axInd, H, momentumCorr ) + implicit none + real(R8Ki), intent(in) :: chi0 + real(ReKi), intent(in) :: phi + real(R8Ki), intent(in) :: k + real(ReKi), intent(in) :: F + logical, intent(in) :: momentumCorr + + real(R8Ki), intent(out) :: axInd + real(R8Ki), intent(out) :: H + + real(R8Ki) :: c2, c1, c0 ! Empirical CT = c2*a^2 + c1*a + c0 for a > a0 + real(R8Ki) :: A,y1,y2,y3, Asquare ! axial induction quadratic solve variables + real(R8Ki) :: coeffs(5) + complex(R8Ki) :: roots(4) + real(R8Ki) :: tan_chi0 + ! Get Coefficients for Empirical CT + call getEmpiricalCoefficients( chi0 ,F , c0, c1, c2,momentumCorr ) + + ! Solve for axial induction + A = 4.0*F*k + if (.NOT.momentumCorr) then + y1 = 2.0*A + c1 + y2 = 4.0*A*(c2+c1+c0) + c1*c1 - 4.0*c0*c2 + y3 = 2.0*(A-c2) + if ( EqualRealNos( y3, 0.0_R8Ki ) ) then + axInd = 1.0 - 1.0/(2.0*SQRT(y2)) + else + if (phi>=0.0) then + axInd = ( y1 - SQRT(y2) ) / y3 + else + axInd = ( y1 + SQRT(y2) ) / y3 + end if + end if + + if ((axInd>a0(chi0)).AND.(axInd<=1.0)) then + H = (4.0*axInd*(1.0-axInd)*F)/(c0+c1*axInd+c2*axInd*axInd) + elseif (axInd>1.0) then + H = (-4.0*axInd*(1.0-axInd)*F)/(c0+c1*axInd+c2*axInd*axInd) + else + H = 1.0 + endif + else + + Asquare = A**2 + coeffs(5) = Asquare - c2*c2 + coeffs(4) = -4*Asquare-2*c1*c2 + coeffs(3) = 6*Asquare -2*c0*c2 -c1*c1 + coeffs(2) = -4*Asquare - 2*c0*c1 + coeffs(1) = Asquare -c0*c0 + call QuarticRoots(coeffs,roots) + call sortRoots(roots) + + if (phi >= 0.0) then + if (real(roots(1))<0.0_R8Ki) then + axInd = real(roots(2)) + elseif (real(roots(2))<1.0_R8Ki) then + axInd = real(roots(2)) + else + axInd = real(roots(1)) + endif + else + axInd = real(roots(2)) + endif + + tan_chi0 = min(MaxTanChi0, max(-MaxTanChi0, tan(chi0))) + + if (equalrealnos(axInd,1.0_R8Ki)) then + H = 0 + elseif ((axInd>a0(chi0)).AND.(axInd<=1.0)) then + H = 4.0_R8Ki*axInd*(1.0_R8Ki-axInd)*F*sqrt(1 + (tan_chi0/(1.0_R8Ki-axInd)*F)**2)/sqrt((c0+c1*axInd+c2*axInd*axInd)**2 + (4.0_R8Ki*axInd*tan_chi0)**2) + ! Alternatively following implemention can be used but it keeps H from approaching zero as a -> 1 + !H = (4.0_R8Ki*axInd*sqrt(((1.0_R8Ki-axInd)*F)**2 + tan(chi0)**2))/sqrt((c0+c1*axInd+c2*axInd*axInd)**2 + (4.0_R8Ki*axInd*tan(chi0))**2) + elseif (axInd>1.0) then + H = -4.0_R8Ki*axInd*(1.0_R8Ki-axInd)*F*sqrt(1 + (tan_chi0/(1.0_R8Ki-axInd)*F)**2)/sqrt((c0+c1*axInd+c2*axInd*axInd)**2 + (4.0_R8Ki*axInd*tan_chi0)**2) + ! Alternatively following implemention can be used but it keeps H from approaching zero as a -> 1 + !H = -(4.0_R8Ki*axInd*sqrt(((1.0_R8Ki-axInd)*F)**2 + tan(chi0)**2))/sqrt((c0+c1*axInd+c2*axInd*axInd)**2 + (4.0_R8Ki*axInd*tan(chi0))**2) + else + H = 1.0 + endif + if (k<0.0) then + H = 1.0 + endif + endif + +end subroutine axialInductionFromEmpiricalThrust + +subroutine axialInductionFromGlauertMomentum(chi0, phi, k, F, axInd, H,momentumCorr) + ! axialInductionFromGlauertMomentum calculates axial induction using Glauert Momentum Theory + implicit none + real(R8Ki), intent(in) :: chi0 + real(R8Ki), intent(in) :: k + real(ReKi), intent(in) :: F + real(ReKi), intent(in) :: phi + logical, intent(in) :: momentumCorr + real(R8Ki), intent(out):: axInd + real(R8Ki), intent(out):: H + real(R8Ki) :: c11, c12, coeffs(5), previousRoot + complex(R8Ki) :: roots(4) + real(R8Ki) :: a0_local + real(R8Ki) :: c2, c1, c0 ! Empirical CT = c2*a^2 + c1*a + c0 for a > a0 + real(R8Ki) :: k0 + real(R8Ki) :: tan_chi0 + + ! Get Coefficients for Empirical CT + call getEmpiricalCoefficients( chi0, F, c0, c1, c2,momentumCorr) + + a0_local = a0(chi0) + k0 = a0_local / (1.0-a0_local) + + tan_chi0 = min(MaxTanChi0, max(-MaxTanChi0, tan(chi0))) + if (abs(k) <= k0*sqrt(1+(tan_chi0/(1-a0_local))**2)) then + c11 = tan_chi0**2 + c12 = k**2 + coeffs(5) = 1.0_R8Ki-c12 + coeffs(4) = 4.0_R8Ki*c12-2.0_R8Ki + coeffs(3) = 1.0_R8Ki+c11 -6.0_R8Ki*c12 + coeffs(2) = 4.0_R8Ki*c12 + coeffs(1) = -c12 + + call QuarticRoots(coeffs,roots) + call sortRoots(roots) + if (phi >= 0.0) then + if (real(roots(1))<0.0_R8Ki) then + axInd = real(roots(2)) + else + axInd = real(roots(1))!min(real(roots(1)),real(roots(2))) + endif + else + axInd = min(real(roots(1)),real(roots(2))) + endif + + previousRoot = axInd + H = 1.0_R8Ki + else !if (k > k0) then ! High induction/ empirical correction + call axialInductionFromEmpiricalThrust( chi0, phi, k, F, axInd, H, momentumCorr ) + endif +end subroutine axialInductionFromGlauertMomentum + +subroutine getEmpiricalCoefficients( chi0, F, c0, c1, c2, MomentumCorr ) + real(R8Ki), intent(in) :: chi0 + real(ReKi), intent(in) :: F + logical, intent(in) :: MomentumCorr + real(R8Ki), intent(inout) :: c0, c1, c2 ! Empirical CT = c2*a^2 + c1*a + c0 for a > a0 + real(R8Ki) :: a0_local + real(R8Ki) :: CTata1 + real(R8Ki) :: denom, temp1, temp2 + + ! Empirical CT = 4*a*(1-a)*F = c2*a^2 + c1*a + c0 for a > a0 + ! third Boundary condition (CT@a=1) is based on equations from Bladed. + a0_local = a0(chi0) + denom = (a0_local**2 - 2.0_R8Ki*a0_local + 1.0_R8Ki) + if (MomentumCorr) then + temp2 = (min(MaxTanChi0, max(-MaxTanChi0, tan(chi0))))**2 + temp1 = sqrt((a0_local-1)**2 +temp2) + + CTata1 = sqrt(((-0.64755/(cos(chi0)*cos(chi0)) - 0.8509/cos(chi0) + 3.4984)*F)**2 + 16*temp2) + CTata1 = max( 1.0_R8Ki, CTata1 ) + + c2 = (CTata1 - 4*F/temp1 + 16*F*a0_local/temp1 - 4*F*a0_local*temp1 - 4*temp2*F/temp1 - 20*F*(a0_local**2)/temp1 + 8*F*(a0_local**3)/temp1 + 4*temp2*F*a0_local/temp1 ) /denom + c1 = 2*( 2*F/temp1 - a0_local*CTata1 - 6*F*a0_local/temp1 + 2*temp2*F/temp1 + 2*F*(a0_local**2)/temp1 + 4*F*(a0_local**2)*temp1 + 6*F*(a0_local**3)/temp1 - 4*F*(a0_local**4)/temp1 - 2*temp2*F*(a0_local**2)/temp1 )/denom + c0 = a0_local*( a0_local*CTata1 - 4*F/temp1 + 4*F*temp1 + 16*F*a0_local/temp1 - 8*F*a0_local*temp1 - 4*temp2*F/temp1 - 20*F*(a0_local**2)/temp1 + 8*F*(a0_local**3)/temp1 + 4*temp2*F*a0_local/temp1 )/denom + + else + CTata1 = (-0.64755/(cos(chi0)*cos(chi0)) - 0.8509/cos(chi0) + 3.4984)*F + CTata1 = max( 1.0_R8Ki, CTata1 ) + c2 = (-4.0_R8Ki*F*a0_local**2 + 8.0_R8Ki*F*a0_local - 4.0_R8Ki*F + CTata1)/denom + c1 = 2.0_R8Ki*(2.0_R8Ki*F*a0_local**2 - CTata1*a0_local - 4.0_R8Ki*F*a0_local + 2.0_R8Ki*F)/denom + c0 = CTata1*(a0_local**2)/denom + endif + + +end subroutine getEmpiricalCoefficients subroutine limitInductionFactors(a,ap) real(ReKi), intent(inout) :: a ! axial induction real(ReKi), intent(inout), optional :: ap ! tangential induction @@ -445,18 +996,59 @@ subroutine limitInductionFactors(a,ap) end if end subroutine limitInductionFactors +!----------------------------------------------------------------------------------------- +subroutine sortRoots(a) +! Sort the roots + complex(R8Ki), intent(inout) :: a(4) + real(R8Ki) :: reala(4) + INTEGER :: j, ind(4) + INTEGER,DIMENSION(1):: k + + do j = 1,size(a) + if (equalrealnos(aimag(a(j)),0.0_R8Ki)) then + reala(j) = real(a(j)) + else + reala(j) = 10000_R8Ki + endif + ind(j) = j + enddo + + DO j=1,SIZE(a)-1 + k=(j-1)+MINLOC(reala(j:)) + IF (j /= k(1)) CALL SwapInt(ind(k(1)),ind(j)) + END DO + + a = a(ind) + + +end subroutine sortRoots + +subroutine SwapInt(a,b) + INTEGER,INTENT(IN OUT):: a,b + INTEGER :: t + + t=b + b=a + a=t + RETURN + +end subroutine SwapInt + + !----------------------------------------------------------------------------------------- !> This function computes \f$F\f$, the hub/tip loss correction -real(reKi) function getHubTipLossCorrection(sphi, useHubLoss, useTipLoss, hubLossConst, tipLossConst) result(F) +real(reKi) function getHubTipLossCorrection(BEM_Mod, useHubLoss, useTipLoss, hubLossConst, tipLossConst, phi, cantAngle) result(F) - real(ReKi), intent(in) :: sphi !< sine of local inflow angle, sin(phi) + integer(IntKi), intent(in) :: BEM_Mod !< BEM Model real(ReKi), intent(in) :: hubLossConst !< hub loss constant [p%hubLossConst] real(ReKi), intent(in) :: tipLossConst !< tip loss constant [p%tipLossConst] logical, intent(in) :: useHubLoss !< hub-loss flag [p%useHubLoss] logical, intent(in) :: useTipLoss !< tip-loss flag [p%useTipLoss] - + real(ReKi), intent(in) :: phi !< local inflow angle phi + real(ReKi), intent(in) :: cantAngle !< cant angle real(ReKi) :: factortip, Ftip, factorhub, Fhub + real(ReKi) :: phiN, sphiN !sinBeta !..................................................... ! Prandtl's tip and hub loss factor: @@ -465,23 +1057,79 @@ real(reKi) function getHubTipLossCorrection(sphi, useHubLoss, useTipLoss, hubLos Ftip = 1.0_ReKi ! default tip loss value Fhub = 1.0_ReKi ! default hub loss value - if (.not. EqualRealNos(sphi,0.0_ReKi)) then - if ( useTipLoss ) then - factortip = tipLossConst/abs(sphi) - Ftip = TwoByPi*acos(min(1.0_ReKi,exp(-factortip))) - ! else Ftip = 1.0_ReKi ! TwoByPi*Pi/2 + if (BEM_Mod==BEMMod_2D) then + sphiN = abs(sin(phi)) + + if (.not. EqualRealNos(sphiN,0.0_ReKi)) then + if ( useTipLoss ) then + factortip = tipLossConst/sphiN + Ftip = TwoByPi*acos(min(1.0_ReKi,exp(-factortip))) + ! else Ftip = 1.0_ReKi ! TwoByPi*Pi/2 + end if + + if ( useHubLoss ) then + factorhub = hubLossConst/sphiN + Fhub = TwoByPi*acos(min(1.0_ReKi,exp(-factorhub))) + ! else Ftip = 1.0_ReKi ! TwoByPi*Pi/2 + end if end if + + else + !sinBeta = sin(cantAngle) + !phiN = acos(sqrt(sinBeta**2 + ((cos(cantAngle)**2) * (cos(phi)**2)))) + phiN = getNewPhi(phi,cantAngle) + sphiN = sin(phiN) + + if (.not. EqualRealNos(sphiN,0.0_ReKi)) then + + if ( useTipLoss .AND. (phi > 0.0_ReKi) ) then + factortip = max(-1.0_ReKi, tipLossConst/sphiN) + Ftip = TwoByPi*acos(min(1.0_ReKi,exp(-factortip))) + ! else Ftip = 1.0_ReKi ! TwoByPi*Pi/2 + end if - if ( useHubLoss ) then - factorhub = hubLossConst/abs(sphi) - Fhub = TwoByPi*acos(min(1.0_ReKi,exp(-factorhub))) - ! else Ftip = 1.0_ReKi ! TwoByPi*Pi/2 + if ( useHubLoss .AND. (phi > 0.0_ReKi) ) then + factorhub = max(-1.0_ReKi, hubLossConst/sphiN) + Fhub = TwoByPi*acos(min(1.0_ReKi,exp(-factorhub))) + ! else Ftip = 1.0_ReKi ! TwoByPi*Pi/2 + end if end if - end if + endif ! BEM_Mod F = Ftip * Fhub end function getHubTipLossCorrection !----------------------------------------------------------------------------------------- +function getNewPhi(phi,CantAngle) result(phiN) + real(ReKi), intent(in ) :: phi + real(ReKi), intent(in ) :: cantAngle + real(ReKi) :: phiN + + real(ReKi) :: y + real(ReKi) :: x + + y = sin(phi) + x = cos(phi)*cos(cantAngle) + + if (y==0.0_ReKi .and. x==0.0_ReKi) then + phiN = 0.0_ReKi !atan2 is undefined when y=0 and x=0 + else + phiN = atan2(y, x) + end if + +end function getNewPhi +!---------------------------------------------------------------------------------------------------------------------------------- +FUNCTION GetEulerAnglesFromOrientation(EulerDCM,orientation) RESULT(theta) + LOGICAL , INTENT(IN ) :: EulerDCM + REAL(R8Ki), INTENT(IN ) :: orientation(3,3) + REAL(R8Ki) :: theta(3) + + if (EulerDCM) then + theta = EulerExtract( orientation ) + else + theta = -EulerExtract( transpose(orientation) ) + end if +end function +!----------------------------------------------------------------------------------------- end module BEMTUncoupled diff --git a/modules/aerodyn/src/BEMT_Registry.txt b/modules/aerodyn/src/BEMT_Registry.txt index 73b2d2cd4..cd98adc86 100644 --- a/modules/aerodyn/src/BEMT_Registry.txt +++ b/modules/aerodyn/src/BEMT_Registry.txt @@ -16,10 +16,14 @@ usefrom AirfoilInfo_Registry.txt usefrom UnsteadyAero_Registry.txt usefrom DBEMT_Registry.txt -#param BEMT/BEMT - INTEGER SkewMod_Uncoupled - 1 - "Uncoupled (no correction)" - -#param BEMT/BEMT - INTEGER SkewMod_PittPeters - 2 - "Pitt/Peters" - -#param BEMT/BEMT - INTEGER SkewMod_Coupled - 3 - "Coupled" - +param BEMT/BEMT - INTEGER SkewMod_Orthogonal - 0 - "Inflow orthogonal to rotor [-]" - +param BEMT/BEMT - INTEGER SkewMod_Uncoupled - 1 - "Uncoupled (no correction)" - +param BEMT/BEMT - INTEGER SkewMod_PittPeters - 2 - "Pitt/Peters" - +param BEMT/BEMT - INTEGER SkewMod_Coupled - 3 - "Coupled" - +param BEMT/BEMT - INTEGER SkewMod_PittPeters_Cont - 4 - "Pitt/Peters continuous formulation" - +param BEMT/BEMT - INTEGER BEMMod_2D - 0 - "2D BEM assuming Cx, Cy, phi, L, D are in the same plane" - +param BEMT/BEMT - INTEGER BEMMod_3D - 2 - "3D BEM assuming a momentum balance system, and an airfoil system" - # # @@ -39,6 +43,7 @@ typedef ^ ^ LOGICAL typedef ^ ^ LOGICAL useTanInd - - - "Include tangential induction in BEMT calculations [flag]" - typedef ^ ^ LOGICAL useAIDrag - - - "Include the drag term in the axial-induction calculation? [flag]" - typedef ^ ^ LOGICAL useTIDrag - - - "Include the drag term in the tangential-induction calculation? Ignored if TanInd is False. [flag]" - +typedef ^ ^ LOGICAL MomentumCorr - - - "Momentum Correction {0=Axial Theory, 1 = Glauert Momentum Theory}" - typedef ^ ^ INTEGER numBladeNodes - - - "Number of blade nodes used in the analysis" - typedef ^ ^ INTEGER numReIterations - - - "Number of iterations for finding the Reynolds number" - typedef ^ ^ INTEGER maxIndIterations - - - "Maximum number of iterations of induction factor solve" - @@ -47,6 +52,7 @@ typedef ^ ^ ReKi typedef ^ ^ ReKi zLocal {:}{:} - - "Distance to blade node, measured along the blade" m typedef ^ ^ ReKi zTip {:} - - "Distance to blade tip, measured along the blade" m typedef ^ ^ ReKi rLocal {:}{:} - - "Radial distance to blade node from the center of rotation, measured in the rotor plane, needed for DBEMT" m +typedef ^ ^ ReKi rTipFix {:} - - "Nominally the coned rotor diameter (without prebend), used to align with Bladed calculations" m typedef ^ ^ INTEGER UAMod - - - "Model for the dynamic stall equations [1 = Leishman/Beddoes, 2 = Gonzalez, 3 = Minnema]" - typedef ^ ^ LOGICAL UA_Flag - - - "logical flag indicating whether to use UnsteadyAero" - typedef ^ ^ LOGICAL Flookup - - - "Use table lookup for f' and f'' " - @@ -58,6 +64,7 @@ typedef ^ ^ INTEGER typedef ^ ^ INTEGER UAOff_outerNode {:} - - "First node on each blade where UA should be turned off based on span location from blade tip (>nNodesPerBlade if always on)" - typedef ^ ^ CHARACTER(1024) RootName - - - "RootName for writing output files" - typedef ^ ^ LOGICAL SumPrint - - - "logical flag indicating whether to use UnsteadyAero" - +typedef ^ ^ IntKi BEM_Mod - - - "BEM Model 0=OpenFAST 2=Envision " - # # # Define outputs from the initialization routine here: @@ -65,11 +72,20 @@ typedef ^ ^ LOGICAL typedef ^ InitOutputType ProgDesc Version - - - "" - # # + +# Define inputs to the Skewed-Wake filter here: +# +typedef ^ BEMT_SkewWake_InputType ReKi v_qsw {3} - - "quasi-steady instantaneous wake velocity (value to be filtered in Skewed Wake model)" m/s +typedef ^ BEMT_SkewWake_InputType ReKi V0 - - - "magnitude of disk-averaged velocity (for input to SkewWake)" m/s +typedef ^ BEMT_SkewWake_InputType ReKi R - - - "rotor radius (for input to SkewWake)" m + + # ..... States .................................................................................................................... # Define continuous (differentiable) states here: # typedef ^ ContinuousStateType UA_ContinuousStateType UA - - - "UA module continuous states" - typedef ^ ContinuousStateType DBEMT_ContinuousStateType DBEMT - - - "DBEMT module continuous states" - +typedef ^ ContinuousStateType R8Ki V_w {3} - - "continuous state for filtering wake velocity" # # # Define discrete (non-differentiable) states here: @@ -88,6 +104,8 @@ typedef ^ OtherStateType UA_OtherSta typedef ^ OtherStateType DBEMT_OtherStateType DBEMT - - - "other states for DBEMT" - typedef ^ ^ LOGICAL ValidPhi {:}{:} - - "set to indicate when there is no valid Phi for this node at this time (temporarially turn off induction when this is false)" - typedef ^ OtherStateType Logical nodesInitialized - - - "the node states have been initialized properly" - +typedef ^ OtherStateType BEMT_ContinuousStateType xdot 4 - - "history states for continuous state integration" - +typedef ^ OtherStateType Integer n - - - "time step # value used for continuous state integrator" - # ..... Misc/Optimization variables................................................................................................. # Define any data that are used only for efficiency purposes (these variables are not associated with time): @@ -99,7 +117,8 @@ typedef ^ MiscVarType UA_MiscVarT typedef ^ MiscVarType DBEMT_MiscVarType DBEMT - - - "misc vars for DBEMT" - typedef ^ MiscVarType UA_OutputType y_UA - - - "outputs from UnsteadyAero" - typedef ^ MiscVarType UA_InputType u_UA {:}{:}{:} - - "inputs to UnsteadyAero at t and t+dt" - -typedef ^ MiscVarType DBEMT_InputType u_DBEMT {:} - - "inputs to DBEMT" - +typedef ^ MiscVarType DBEMT_InputType u_DBEMT {2} - - "inputs to DBEMT at t and t+dt" - +typedef ^ MiscVarType BEMT_SkewWake_InputType u_SkewWake {2} - - "inputs to SkewedWake at t and t+dt" - typedef ^ MiscVarType ReKi TnInd_op {:}{:} - - "tangential induction at the operating point (for linearization with frozen wake assumption)" typedef ^ MiscVarType ReKi AxInd_op {:}{:} - - "axial induction at the operating point (for linearization) with frozen wake assumption" typedef ^ MiscVarType ReKi AxInduction {:}{:} - - "axial induction used for code run-time optimization" - @@ -141,6 +160,11 @@ typedef ^ ^ LOGICAL typedef ^ ^ IntKi DBEMT_Mod - - - "DBEMT Model. 0 = constant tau1, 1 = time dependent tau1" - typedef ^ ^ ReKi yawCorrFactor - - - "constant used in Pitt/Peters skewed wake model (default is 15*pi/32)" - typedef ^ ^ LOGICAL FixedInductions {:}{:} - - "flag to determine if BEM inductions should be fixed and not modified by dbemt or skewed wake" - +typedef ^ ^ LOGICAL MomentumCorr - - - "Momentum Correction {0=Axial Theory, 1 = Glauert Momentum Theory}" - +typedef ^ ^ ReKi rTipFixMax - - - "Nominally the coned rotor diameter (without prebend), used to align with Bladed calculations" m +typedef ^ ^ ReKi IntegrateWeight {:}{:} - - "A weighting factor for calculating rotor-averaged values (e.g., AxInd)" - +typedef ^ ParameterType IntKi lin_nx - 0 - "Number of continuous states for linearization" - +typedef ^ ^ IntKi BEM_Mod - - - "BEM Model 0=OpenFAST 2=Envision " - # # @@ -149,17 +173,23 @@ typedef ^ ^ LOGICAL # typedef ^ InputType ReKi theta {:}{:} - - "Twist angle (includes all sources of twist) [Array of size (NumBlNds,numBlades)]" rad typedef ^ ^ ReKi chi0 - - - "Angle between the vector normal to the rotor plane and the wind vector (e.g., the yaw angle in the case of no tilt)" rad +typedef ^ ^ ReKi psiSkewOffset - - - "Azimuth angle offset (relative to 90 deg) of the most downwind blade when chi0 is non-zero" rad typedef ^ ^ ReKi psi {:} - - "Azimuth angle" rad typedef ^ ^ ReKi omega - - - "Angular velocity of rotor" rad/s typedef ^ ^ ReKi TSR - - - "Tip-speed ratio (to check if BEM should be turned off)" - typedef ^ ^ ReKi Vx {:}{:} - - "Local axial velocity at node" m/s typedef ^ ^ ReKi Vy {:}{:} - - "Local tangential velocity at node" m/s -typedef ^ ^ ReKi Vx_elast_dot {:}{:} - - "Local relative axial acceleration at node (for CDBEMT)" "m/s^2" -typedef ^ ^ ReKi Vy_elast_dot {:}{:} - - "Local relative tangential acceleration at node (for CDBEMT)" "m/s^2" +typedef ^ ^ ReKi Vz {:}{:} - - "Local radial velocity at node" m/s typedef ^ ^ ReKi omega_z {:}{:} - - "rotation of no-sweep-pitch-twist coordinate system around z (for CDBEMT and CUA)" "rad/s" +typedef ^ ^ ReKi xVelCorr {:}{:} - - "projection of velocity when yawed + prebend" m/s typedef ^ ^ ReKi rLocal {:}{:} - - "Radial distance from center-of-rotation to node" m typedef ^ InputType ReKi Un_disk - - - "disk-averaged velocity normal to the rotor disk (for input to DBEMT)" m/s +typedef ^ InputType ReKi V0 {3} - - "disk-averaged velocity (for input to SkewWake)" m/s +typedef ^ InputType R8Ki x_hat_disk {3} - - "Hub Orientation vector: normal to rotor disk" - typedef ^ ^ ReKi UserProp {:}{:} - - "Optional user property for interpolating airfoils (per element per blade)" - +typedef ^ InputType ReKi CantAngle {:}{:} - - "Cant angle [Array of size (NumBlNds,numBlades)]" rad +typedef ^ ^ ReKi drdz {:}{:} - - "dr/dz geometric parameter" - +typedef ^ InputType ReKi toeAngle {:}{:} - - "Toe angle [Array of size (NumBlNds,numBlades)]" rad # # ..... Outputs ................................................................................................................... # Define outputs that are contained on the mesh here: @@ -171,6 +201,10 @@ typedef ^ ^ ReKi typedef ^ ^ ReKi AOA {:}{:} - - "angle of attack" rad typedef ^ ^ ReKi Cx {:}{:} - - "normal force coefficient (normal to the plane, not chord) of the jth node in the kth blade" - typedef ^ ^ ReKi Cy {:}{:} - - "tangential force coefficient (tangential to the plane, not chord) of the jth node in the kth blade" - +typedef ^ ^ ReKi Cz {:}{:} - - "axial force coefficient (tangential to the plane, not chord) of the jth node in the kth blade" - +typedef ^ ^ ReKi Cmx {:}{:} - - "pitching moment coefficient (x-component) of the jth node in the kth blade" - +typedef ^ ^ ReKi Cmy {:}{:} - - "pitching moment coefficient (y-component) of the jth node in the kth blade" - +typedef ^ ^ ReKi Cmz {:}{:} - - "pitching moment coefficient (z-component) of the jth node in the kth blade" - typedef ^ ^ ReKi Cm {:}{:} - - "pitching moment coefficient of the jth node in the kth blade" - typedef ^ ^ ReKi Cl {:}{:} - - "lift coefficient" - typedef ^ ^ ReKi Cd {:}{:} - - "drag coefficient" - diff --git a/modules/aerodyn/src/BEMT_Types.f90 b/modules/aerodyn/src/BEMT_Types.f90 index d7dd816ca..afc972c2b 100644 --- a/modules/aerodyn/src/BEMT_Types.f90 +++ b/modules/aerodyn/src/BEMT_Types.f90 @@ -35,6 +35,13 @@ MODULE BEMT_Types USE DBEMT_Types USE NWTC_Library IMPLICIT NONE + INTEGER(IntKi), PUBLIC, PARAMETER :: SkewMod_Orthogonal = 0 ! Inflow orthogonal to rotor [-] [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: SkewMod_Uncoupled = 1 ! Uncoupled (no correction) [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: SkewMod_PittPeters = 2 ! Pitt/Peters [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: SkewMod_Coupled = 3 ! Coupled [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: SkewMod_PittPeters_Cont = 4 ! Pitt/Peters continuous formulation [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: BEMMod_2D = 0 ! 2D BEM assuming Cx, Cy, phi, L, D are in the same plane [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: BEMMod_3D = 2 ! 3D BEM assuming a momentum balance system, and an airfoil system [-] ! ========= BEMT_InitInputType ======= TYPE, PUBLIC :: BEMT_InitInputType REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: chord !< Chord length at node [m] @@ -49,6 +56,7 @@ MODULE BEMT_Types LOGICAL :: useTanInd !< Include tangential induction in BEMT calculations [flag] [-] LOGICAL :: useAIDrag !< Include the drag term in the axial-induction calculation? [flag] [-] LOGICAL :: useTIDrag !< Include the drag term in the tangential-induction calculation? Ignored if TanInd is False. [flag] [-] + LOGICAL :: MomentumCorr !< Momentum Correction {0=Axial Theory, 1 = Glauert Momentum Theory} [-] INTEGER(IntKi) :: numBladeNodes !< Number of blade nodes used in the analysis [-] INTEGER(IntKi) :: numReIterations !< Number of iterations for finding the Reynolds number [-] INTEGER(IntKi) :: maxIndIterations !< Maximum number of iterations of induction factor solve [-] @@ -57,6 +65,7 @@ MODULE BEMT_Types REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: zLocal !< Distance to blade node, measured along the blade [m] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: zTip !< Distance to blade tip, measured along the blade [m] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: rLocal !< Radial distance to blade node from the center of rotation, measured in the rotor plane, needed for DBEMT [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: rTipFix !< Nominally the coned rotor diameter (without prebend), used to align with Bladed calculations [m] INTEGER(IntKi) :: UAMod !< Model for the dynamic stall equations [1 = Leishman/Beddoes, 2 = Gonzalez, 3 = Minnema] [-] LOGICAL :: UA_Flag !< logical flag indicating whether to use UnsteadyAero [-] LOGICAL :: Flookup !< Use table lookup for f' and f'' [-] @@ -68,6 +77,7 @@ MODULE BEMT_Types INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: UAOff_outerNode !< First node on each blade where UA should be turned off based on span location from blade tip (>nNodesPerBlade if always on) [-] CHARACTER(1024) :: RootName !< RootName for writing output files [-] LOGICAL :: SumPrint !< logical flag indicating whether to use UnsteadyAero [-] + INTEGER(IntKi) :: BEM_Mod !< BEM Model 0=OpenFAST 2=Envision [-] END TYPE BEMT_InitInputType ! ======================= ! ========= BEMT_InitOutputType ======= @@ -75,10 +85,18 @@ MODULE BEMT_Types TYPE(ProgDesc) :: Version !< [-] END TYPE BEMT_InitOutputType ! ======================= +! ========= BEMT_SkewWake_InputType ======= + TYPE, PUBLIC :: BEMT_SkewWake_InputType + REAL(ReKi) , DIMENSION(1:3) :: v_qsw !< quasi-steady instantaneous wake velocity (value to be filtered in Skewed Wake model) [m/s] + REAL(ReKi) :: V0 !< magnitude of disk-averaged velocity (for input to SkewWake) [m/s] + REAL(ReKi) :: R !< rotor radius (for input to SkewWake) [m] + END TYPE BEMT_SkewWake_InputType +! ======================= ! ========= BEMT_ContinuousStateType ======= TYPE, PUBLIC :: BEMT_ContinuousStateType TYPE(UA_ContinuousStateType) :: UA !< UA module continuous states [-] TYPE(DBEMT_ContinuousStateType) :: DBEMT !< DBEMT module continuous states [-] + REAL(R8Ki) , DIMENSION(1:3) :: V_w !< continuous state for filtering wake velocity [-] END TYPE BEMT_ContinuousStateType ! ======================= ! ========= BEMT_DiscreteStateType ======= @@ -97,6 +115,8 @@ MODULE BEMT_Types TYPE(DBEMT_OtherStateType) :: DBEMT !< other states for DBEMT [-] LOGICAL , DIMENSION(:,:), ALLOCATABLE :: ValidPhi !< set to indicate when there is no valid Phi for this node at this time (temporarially turn off induction when this is false) [-] LOGICAL :: nodesInitialized !< the node states have been initialized properly [-] + TYPE(BEMT_ContinuousStateType) , DIMENSION(1:4) :: xdot !< history states for continuous state integration [-] + INTEGER(IntKi) :: n !< time step value used for continuous state integrator [-] END TYPE BEMT_OtherStateType ! ======================= ! ========= BEMT_MiscVarType ======= @@ -108,7 +128,8 @@ MODULE BEMT_Types TYPE(DBEMT_MiscVarType) :: DBEMT !< misc vars for DBEMT [-] TYPE(UA_OutputType) :: y_UA !< outputs from UnsteadyAero [-] TYPE(UA_InputType) , DIMENSION(:,:,:), ALLOCATABLE :: u_UA !< inputs to UnsteadyAero at t and t+dt [-] - TYPE(DBEMT_InputType) , DIMENSION(:), ALLOCATABLE :: u_DBEMT !< inputs to DBEMT [-] + TYPE(DBEMT_InputType) , DIMENSION(1:2) :: u_DBEMT !< inputs to DBEMT at t and t+dt [-] + TYPE(BEMT_SkewWake_InputType) , DIMENSION(1:2) :: u_SkewWake !< inputs to SkewedWake at t and t+dt [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: TnInd_op !< tangential induction at the operating point (for linearization with frozen wake assumption) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: AxInd_op !< axial induction at the operating point (for linearization) with frozen wake assumption [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: AxInduction !< axial induction used for code run-time optimization [-] @@ -149,23 +170,34 @@ MODULE BEMT_Types INTEGER(IntKi) :: DBEMT_Mod !< DBEMT Model. 0 = constant tau1, 1 = time dependent tau1 [-] REAL(ReKi) :: yawCorrFactor !< constant used in Pitt/Peters skewed wake model (default is 15*pi/32) [-] LOGICAL , DIMENSION(:,:), ALLOCATABLE :: FixedInductions !< flag to determine if BEM inductions should be fixed and not modified by dbemt or skewed wake [-] + LOGICAL :: MomentumCorr !< Momentum Correction {0=Axial Theory, 1 = Glauert Momentum Theory} [-] + REAL(ReKi) :: rTipFixMax !< Nominally the coned rotor diameter (without prebend), used to align with Bladed calculations [m] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: IntegrateWeight !< A weighting factor for calculating rotor-averaged values (e.g., AxInd) [-] + INTEGER(IntKi) :: lin_nx = 0 !< Number of continuous states for linearization [-] + INTEGER(IntKi) :: BEM_Mod !< BEM Model 0=OpenFAST 2=Envision [-] END TYPE BEMT_ParameterType ! ======================= ! ========= BEMT_InputType ======= TYPE, PUBLIC :: BEMT_InputType REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: theta !< Twist angle (includes all sources of twist) [Array of size (NumBlNds,numBlades)] [rad] REAL(ReKi) :: chi0 !< Angle between the vector normal to the rotor plane and the wind vector (e.g., the yaw angle in the case of no tilt) [rad] + REAL(ReKi) :: psiSkewOffset !< Azimuth angle offset (relative to 90 deg) of the most downwind blade when chi0 is non-zero [rad] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: psi !< Azimuth angle [rad] REAL(ReKi) :: omega !< Angular velocity of rotor [rad/s] REAL(ReKi) :: TSR !< Tip-speed ratio (to check if BEM should be turned off) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vx !< Local axial velocity at node [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vy !< Local tangential velocity at node [m/s] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vx_elast_dot !< Local relative axial acceleration at node (for CDBEMT) [m/s^2] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vy_elast_dot !< Local relative tangential acceleration at node (for CDBEMT) [m/s^2] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vz !< Local radial velocity at node [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: omega_z !< rotation of no-sweep-pitch-twist coordinate system around z (for CDBEMT and CUA) [rad/s] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: xVelCorr !< projection of velocity when yawed + prebend [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: rLocal !< Radial distance from center-of-rotation to node [m] REAL(ReKi) :: Un_disk !< disk-averaged velocity normal to the rotor disk (for input to DBEMT) [m/s] + REAL(ReKi) , DIMENSION(1:3) :: V0 !< disk-averaged velocity (for input to SkewWake) [m/s] + REAL(R8Ki) , DIMENSION(1:3) :: x_hat_disk !< Hub Orientation vector: normal to rotor disk [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: UserProp !< Optional user property for interpolating airfoils (per element per blade) [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: CantAngle !< Cant angle [Array of size (NumBlNds,numBlades)] [rad] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: drdz !< dr/dz geometric parameter [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: toeAngle !< Toe angle [Array of size (NumBlNds,numBlades)] [rad] END TYPE BEMT_InputType ! ======================= ! ========= BEMT_OutputType ======= @@ -178,6 +210,10 @@ MODULE BEMT_Types REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: AOA !< angle of attack [rad] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Cx !< normal force coefficient (normal to the plane, not chord) of the jth node in the kth blade [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Cy !< tangential force coefficient (tangential to the plane, not chord) of the jth node in the kth blade [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Cz !< axial force coefficient (tangential to the plane, not chord) of the jth node in the kth blade [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Cmx !< pitching moment coefficient (x-component) of the jth node in the kth blade [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Cmy !< pitching moment coefficient (y-component) of the jth node in the kth blade [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Cmz !< pitching moment coefficient (z-component) of the jth node in the kth blade [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Cm !< pitching moment coefficient of the jth node in the kth blade [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Cl !< lift coefficient [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Cd !< drag coefficient [-] @@ -228,6 +264,7 @@ SUBROUTINE BEMT_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Err DstInitInputData%useTanInd = SrcInitInputData%useTanInd DstInitInputData%useAIDrag = SrcInitInputData%useAIDrag DstInitInputData%useTIDrag = SrcInitInputData%useTIDrag + DstInitInputData%MomentumCorr = SrcInitInputData%MomentumCorr DstInitInputData%numBladeNodes = SrcInitInputData%numBladeNodes DstInitInputData%numReIterations = SrcInitInputData%numReIterations DstInitInputData%maxIndIterations = SrcInitInputData%maxIndIterations @@ -296,6 +333,18 @@ SUBROUTINE BEMT_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Err END IF END IF DstInitInputData%rLocal = SrcInitInputData%rLocal +ENDIF +IF (ALLOCATED(SrcInitInputData%rTipFix)) THEN + i1_l = LBOUND(SrcInitInputData%rTipFix,1) + i1_u = UBOUND(SrcInitInputData%rTipFix,1) + IF (.NOT. ALLOCATED(DstInitInputData%rTipFix)) THEN + ALLOCATE(DstInitInputData%rTipFix(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%rTipFix.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%rTipFix = SrcInitInputData%rTipFix ENDIF DstInitInputData%UAMod = SrcInitInputData%UAMod DstInitInputData%UA_Flag = SrcInitInputData%UA_Flag @@ -330,17 +379,30 @@ SUBROUTINE BEMT_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Err ENDIF DstInitInputData%RootName = SrcInitInputData%RootName DstInitInputData%SumPrint = SrcInitInputData%SumPrint + DstInitInputData%BEM_Mod = SrcInitInputData%BEM_Mod END SUBROUTINE BEMT_CopyInitInput - SUBROUTINE BEMT_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE BEMT_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BEMT_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%chord)) THEN DEALLOCATE(InitInputData%chord) ENDIF @@ -359,6 +421,9 @@ SUBROUTINE BEMT_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) IF (ALLOCATED(InitInputData%rLocal)) THEN DEALLOCATE(InitInputData%rLocal) ENDIF +IF (ALLOCATED(InitInputData%rTipFix)) THEN + DEALLOCATE(InitInputData%rTipFix) +ENDIF IF (ALLOCATED(InitInputData%UAOff_innerNode)) THEN DEALLOCATE(InitInputData%UAOff_innerNode) ENDIF @@ -418,6 +483,7 @@ SUBROUTINE BEMT_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Int_BufSz = Int_BufSz + 1 ! useTanInd Int_BufSz = Int_BufSz + 1 ! useAIDrag Int_BufSz = Int_BufSz + 1 ! useTIDrag + Int_BufSz = Int_BufSz + 1 ! MomentumCorr Int_BufSz = Int_BufSz + 1 ! numBladeNodes Int_BufSz = Int_BufSz + 1 ! numReIterations Int_BufSz = Int_BufSz + 1 ! maxIndIterations @@ -445,6 +511,11 @@ SUBROUTINE BEMT_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM IF ( ALLOCATED(InData%rLocal) ) THEN Int_BufSz = Int_BufSz + 2*2 ! rLocal upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%rLocal) ! rLocal + END IF + Int_BufSz = Int_BufSz + 1 ! rTipFix allocated yes/no + IF ( ALLOCATED(InData%rTipFix) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! rTipFix upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%rTipFix) ! rTipFix END IF Int_BufSz = Int_BufSz + 1 ! UAMod Int_BufSz = Int_BufSz + 1 ! UA_Flag @@ -465,6 +536,7 @@ SUBROUTINE BEMT_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM END IF Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName Int_BufSz = Int_BufSz + 1 ! SumPrint + Int_BufSz = Int_BufSz + 1 ! BEM_Mod IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -534,6 +606,8 @@ SUBROUTINE BEMT_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%useTIDrag, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%MomentumCorr, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%numBladeNodes Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%numReIterations @@ -629,6 +703,21 @@ SUBROUTINE BEMT_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Re_Xferred = Re_Xferred + 1 END DO END DO + END IF + IF ( .NOT. ALLOCATED(InData%rTipFix) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%rTipFix,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%rTipFix,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%rTipFix,1), UBOUND(InData%rTipFix,1) + ReKiBuf(Re_Xferred) = InData%rTipFix(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF IntKiBuf(Int_Xferred) = InData%UAMod Int_Xferred = Int_Xferred + 1 @@ -680,6 +769,8 @@ SUBROUTINE BEMT_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM END DO ! I IntKiBuf(Int_Xferred) = TRANSFER(InData%SumPrint, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%BEM_Mod + Int_Xferred = Int_Xferred + 1 END SUBROUTINE BEMT_PackInitInput SUBROUTINE BEMT_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -756,6 +847,8 @@ SUBROUTINE BEMT_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E Int_Xferred = Int_Xferred + 1 OutData%useTIDrag = TRANSFER(IntKiBuf(Int_Xferred), OutData%useTIDrag) Int_Xferred = Int_Xferred + 1 + OutData%MomentumCorr = TRANSFER(IntKiBuf(Int_Xferred), OutData%MomentumCorr) + Int_Xferred = Int_Xferred + 1 OutData%numBladeNodes = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%numReIterations = IntKiBuf(Int_Xferred) @@ -866,6 +959,24 @@ SUBROUTINE BEMT_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E Re_Xferred = Re_Xferred + 1 END DO END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! rTipFix not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%rTipFix)) DEALLOCATE(OutData%rTipFix) + ALLOCATE(OutData%rTipFix(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%rTipFix.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%rTipFix,1), UBOUND(OutData%rTipFix,1) + OutData%rTipFix(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END IF OutData%UAMod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 @@ -923,6 +1034,8 @@ SUBROUTINE BEMT_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END DO ! I OutData%SumPrint = TRANSFER(IntKiBuf(Int_Xferred), OutData%SumPrint) Int_Xferred = Int_Xferred + 1 + OutData%BEM_Mod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE BEMT_UnPackInitInput SUBROUTINE BEMT_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -944,16 +1057,29 @@ SUBROUTINE BEMT_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE BEMT_CopyInitOutput - SUBROUTINE BEMT_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE BEMT_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BEMT_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Version, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Version, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE BEMT_DestroyInitOutput SUBROUTINE BEMT_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1134,6 +1260,163 @@ SUBROUTINE BEMT_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END SUBROUTINE BEMT_UnPackInitOutput + SUBROUTINE BEMT_CopySkewWake_InputType( SrcSkewWake_InputTypeData, DstSkewWake_InputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(BEMT_SkewWake_InputType), INTENT(IN) :: SrcSkewWake_InputTypeData + TYPE(BEMT_SkewWake_InputType), INTENT(INOUT) :: DstSkewWake_InputTypeData + 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 = 'BEMT_CopySkewWake_InputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstSkewWake_InputTypeData%v_qsw = SrcSkewWake_InputTypeData%v_qsw + DstSkewWake_InputTypeData%V0 = SrcSkewWake_InputTypeData%V0 + DstSkewWake_InputTypeData%R = SrcSkewWake_InputTypeData%R + END SUBROUTINE BEMT_CopySkewWake_InputType + + SUBROUTINE BEMT_DestroySkewWake_InputType( SkewWake_InputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(BEMT_SkewWake_InputType), INTENT(INOUT) :: SkewWake_InputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroySkewWake_InputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE BEMT_DestroySkewWake_InputType + + SUBROUTINE BEMT_PackSkewWake_InputType( 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(BEMT_SkewWake_InputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_PackSkewWake_InputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + SIZE(InData%v_qsw) ! v_qsw + Re_BufSz = Re_BufSz + 1 ! V0 + Re_BufSz = Re_BufSz + 1 ! R + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO i1 = LBOUND(InData%v_qsw,1), UBOUND(InData%v_qsw,1) + ReKiBuf(Re_Xferred) = InData%v_qsw(i1) + Re_Xferred = Re_Xferred + 1 + END DO + ReKiBuf(Re_Xferred) = InData%V0 + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%R + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE BEMT_PackSkewWake_InputType + + SUBROUTINE BEMT_UnPackSkewWake_InputType( 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(BEMT_SkewWake_InputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_UnPackSkewWake_InputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + i1_l = LBOUND(OutData%v_qsw,1) + i1_u = UBOUND(OutData%v_qsw,1) + DO i1 = LBOUND(OutData%v_qsw,1), UBOUND(OutData%v_qsw,1) + OutData%v_qsw(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%V0 = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%R = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE BEMT_UnPackSkewWake_InputType + SUBROUTINE BEMT_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) TYPE(BEMT_ContinuousStateType), INTENT(IN) :: SrcContStateData TYPE(BEMT_ContinuousStateType), INTENT(INOUT) :: DstContStateData @@ -1142,6 +1425,7 @@ SUBROUTINE BEMT_CopyContState( SrcContStateData, DstContStateData, CtrlCode, Err 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 = 'BEMT_CopyContState' @@ -1154,19 +1438,34 @@ SUBROUTINE BEMT_CopyContState( SrcContStateData, DstContStateData, CtrlCode, Err CALL DBEMT_CopyContState( SrcContStateData%DBEMT, DstContStateData%DBEMT, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + DstContStateData%V_w = SrcContStateData%V_w END SUBROUTINE BEMT_CopyContState - SUBROUTINE BEMT_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE BEMT_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BEMT_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" - CALL UA_DestroyContState( ContStateData%UA, ErrStat, ErrMsg ) - CALL DBEMT_DestroyContState( ContStateData%DBEMT, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL UA_DestroyContState( ContStateData%UA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DBEMT_DestroyContState( ContStateData%DBEMT, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE BEMT_DestroyContState SUBROUTINE BEMT_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1239,6 +1538,7 @@ SUBROUTINE BEMT_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Db_BufSz = Db_BufSz + SIZE(InData%V_w) ! V_w IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1322,6 +1622,10 @@ SUBROUTINE BEMT_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + DO i1 = LBOUND(InData%V_w,1), UBOUND(InData%V_w,1) + DbKiBuf(Db_Xferred) = InData%V_w(i1) + Db_Xferred = Db_Xferred + 1 + END DO END SUBROUTINE BEMT_PackContState SUBROUTINE BEMT_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1337,6 +1641,7 @@ SUBROUTINE BEMT_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E 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 = 'BEMT_UnPackContState' @@ -1430,6 +1735,12 @@ SUBROUTINE BEMT_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + i1_l = LBOUND(OutData%V_w,1) + i1_u = UBOUND(OutData%V_w,1) + DO i1 = LBOUND(OutData%V_w,1), UBOUND(OutData%V_w,1) + OutData%V_w(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO END SUBROUTINE BEMT_UnPackContState SUBROUTINE BEMT_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrStat, ErrMsg ) @@ -1451,16 +1762,29 @@ SUBROUTINE BEMT_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, Err IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE BEMT_CopyDiscState - SUBROUTINE BEMT_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE BEMT_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BEMT_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" - CALL UA_DestroyDiscState( DiscStateData%UA, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL UA_DestroyDiscState( DiscStateData%UA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE BEMT_DestroyDiscState SUBROUTINE BEMT_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1673,15 +1997,27 @@ SUBROUTINE BEMT_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCod ENDIF END SUBROUTINE BEMT_CopyConstrState - SUBROUTINE BEMT_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE BEMT_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BEMT_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ConstrStateData%phi)) THEN DEALLOCATE(ConstrStateData%phi) ENDIF @@ -1866,22 +2202,46 @@ SUBROUTINE BEMT_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, DstOtherStateData%ValidPhi = SrcOtherStateData%ValidPhi ENDIF DstOtherStateData%nodesInitialized = SrcOtherStateData%nodesInitialized + DO i1 = LBOUND(SrcOtherStateData%xdot,1), UBOUND(SrcOtherStateData%xdot,1) + CALL BEMT_CopyContState( SrcOtherStateData%xdot(i1), DstOtherStateData%xdot(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO + DstOtherStateData%n = SrcOtherStateData%n END SUBROUTINE BEMT_CopyOtherState - SUBROUTINE BEMT_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE BEMT_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BEMT_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" - CALL UA_DestroyOtherState( OtherStateData%UA, ErrStat, ErrMsg ) - CALL DBEMT_DestroyOtherState( OtherStateData%DBEMT, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL UA_DestroyOtherState( OtherStateData%UA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DBEMT_DestroyOtherState( OtherStateData%DBEMT, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(OtherStateData%ValidPhi)) THEN DEALLOCATE(OtherStateData%ValidPhi) ENDIF +DO i1 = LBOUND(OtherStateData%xdot,1), UBOUND(OtherStateData%xdot,1) + CALL BEMT_DestroyContState( OtherStateData%xdot(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO END SUBROUTINE BEMT_DestroyOtherState SUBROUTINE BEMT_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1960,6 +2320,26 @@ SUBROUTINE BEMT_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Int_BufSz = Int_BufSz + SIZE(InData%ValidPhi) ! ValidPhi END IF Int_BufSz = Int_BufSz + 1 ! nodesInitialized + DO i1 = LBOUND(InData%xdot,1), UBOUND(InData%xdot,1) + Int_BufSz = Int_BufSz + 3 ! xdot: size of buffers for each call to pack subtype + CALL BEMT_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%xdot(i1), ErrStat2, ErrMsg2, .TRUE. ) ! xdot + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! xdot + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! xdot + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! xdot + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + Int_BufSz = Int_BufSz + 1 ! n IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -2065,6 +2445,38 @@ SUBROUTINE BEMT_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err END IF IntKiBuf(Int_Xferred) = TRANSFER(InData%nodesInitialized, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%xdot,1), UBOUND(InData%xdot,1) + CALL BEMT_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%xdot(i1), ErrStat2, ErrMsg2, OnlySize ) ! xdot + 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 + IntKiBuf(Int_Xferred) = InData%n + Int_Xferred = Int_Xferred + 1 END SUBROUTINE BEMT_PackOtherState SUBROUTINE BEMT_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -2200,9 +2612,55 @@ SUBROUTINE BEMT_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END IF OutData%nodesInitialized = TRANSFER(IntKiBuf(Int_Xferred), OutData%nodesInitialized) Int_Xferred = Int_Xferred + 1 - END SUBROUTINE BEMT_UnPackOtherState - - SUBROUTINE BEMT_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) + i1_l = LBOUND(OutData%xdot,1) + i1_u = UBOUND(OutData%xdot,1) + DO i1 = LBOUND(OutData%xdot,1), UBOUND(OutData%xdot,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 BEMT_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%xdot(i1), ErrStat2, ErrMsg2 ) ! xdot + 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 + OutData%n = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE BEMT_UnPackOtherState + + SUBROUTINE BEMT_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) TYPE(BEMT_MiscVarType), INTENT(IN) :: SrcMiscData TYPE(BEMT_MiscVarType), INTENT(INOUT) :: DstMiscData INTEGER(IntKi), INTENT(IN ) :: CtrlCode @@ -2255,22 +2713,16 @@ SUBROUTINE BEMT_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) ENDDO ENDDO ENDIF -IF (ALLOCATED(SrcMiscData%u_DBEMT)) THEN - i1_l = LBOUND(SrcMiscData%u_DBEMT,1) - i1_u = UBOUND(SrcMiscData%u_DBEMT,1) - IF (.NOT. ALLOCATED(DstMiscData%u_DBEMT)) THEN - ALLOCATE(DstMiscData%u_DBEMT(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%u_DBEMT.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF DO i1 = LBOUND(SrcMiscData%u_DBEMT,1), UBOUND(SrcMiscData%u_DBEMT,1) CALL DBEMT_CopyInput( SrcMiscData%u_DBEMT(i1), DstMiscData%u_DBEMT(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO -ENDIF + DO i1 = LBOUND(SrcMiscData%u_SkewWake,1), UBOUND(SrcMiscData%u_SkewWake,1) + CALL BEMT_Copyskewwake_inputtype( SrcMiscData%u_SkewWake(i1), DstMiscData%u_SkewWake(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO IF (ALLOCATED(SrcMiscData%TnInd_op)) THEN i1_l = LBOUND(SrcMiscData%TnInd_op,1) i1_u = UBOUND(SrcMiscData%TnInd_op,1) @@ -2385,34 +2837,52 @@ SUBROUTINE BEMT_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%BEM_weight = SrcMiscData%BEM_weight END SUBROUTINE BEMT_CopyMisc - SUBROUTINE BEMT_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE BEMT_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BEMT_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" - CALL UA_DestroyMisc( MiscData%UA, ErrStat, ErrMsg ) - CALL DBEMT_DestroyMisc( MiscData%DBEMT, ErrStat, ErrMsg ) - CALL UA_DestroyOutput( MiscData%y_UA, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL UA_DestroyMisc( MiscData%UA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DBEMT_DestroyMisc( MiscData%DBEMT, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL UA_DestroyOutput( MiscData%y_UA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MiscData%u_UA)) THEN DO i3 = LBOUND(MiscData%u_UA,3), UBOUND(MiscData%u_UA,3) DO i2 = LBOUND(MiscData%u_UA,2), UBOUND(MiscData%u_UA,2) DO i1 = LBOUND(MiscData%u_UA,1), UBOUND(MiscData%u_UA,1) - CALL UA_DestroyInput( MiscData%u_UA(i1,i2,i3), ErrStat, ErrMsg ) + CALL UA_DestroyInput( MiscData%u_UA(i1,i2,i3), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO ENDDO DEALLOCATE(MiscData%u_UA) ENDIF -IF (ALLOCATED(MiscData%u_DBEMT)) THEN DO i1 = LBOUND(MiscData%u_DBEMT,1), UBOUND(MiscData%u_DBEMT,1) - CALL DBEMT_DestroyInput( MiscData%u_DBEMT(i1), ErrStat, ErrMsg ) + CALL DBEMT_DestroyInput( MiscData%u_DBEMT(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO +DO i1 = LBOUND(MiscData%u_SkewWake,1), UBOUND(MiscData%u_SkewWake,1) + CALL BEMT_Destroyskewwake_inputtype( MiscData%u_SkewWake(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(MiscData%u_DBEMT) -ENDIF IF (ALLOCATED(MiscData%TnInd_op)) THEN DEALLOCATE(MiscData%TnInd_op) ENDIF @@ -2556,9 +3026,6 @@ SUBROUTINE BEMT_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S END DO END DO END IF - Int_BufSz = Int_BufSz + 1 ! u_DBEMT allocated yes/no - IF ( ALLOCATED(InData%u_DBEMT) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! u_DBEMT upper/lower bounds for each dimension DO i1 = LBOUND(InData%u_DBEMT,1), UBOUND(InData%u_DBEMT,1) Int_BufSz = Int_BufSz + 3 ! u_DBEMT: size of buffers for each call to pack subtype CALL DBEMT_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_DBEMT(i1), ErrStat2, ErrMsg2, .TRUE. ) ! u_DBEMT @@ -2578,7 +3045,25 @@ SUBROUTINE BEMT_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S DEALLOCATE(Int_Buf) END IF END DO - END IF + DO i1 = LBOUND(InData%u_SkewWake,1), UBOUND(InData%u_SkewWake,1) + Int_BufSz = Int_BufSz + 3 ! u_SkewWake: size of buffers for each call to pack subtype + CALL BEMT_Packskewwake_inputtype( Re_Buf, Db_Buf, Int_Buf, InData%u_SkewWake(i1), ErrStat2, ErrMsg2, .TRUE. ) ! u_SkewWake + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! u_SkewWake + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! u_SkewWake + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! u_SkewWake + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO Int_BufSz = Int_BufSz + 1 ! TnInd_op allocated yes/no IF ( ALLOCATED(InData%TnInd_op) ) THEN Int_BufSz = Int_BufSz + 2*2 ! TnInd_op upper/lower bounds for each dimension @@ -2789,16 +3274,6 @@ SUBROUTINE BEMT_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%u_DBEMT) ) THEN - 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_DBEMT,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%u_DBEMT,1) - Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%u_DBEMT,1), UBOUND(InData%u_DBEMT,1) CALL DBEMT_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_DBEMT(i1), ErrStat2, ErrMsg2, OnlySize ) ! u_DBEMT CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -2829,7 +3304,36 @@ SUBROUTINE BEMT_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF END DO - END IF + DO i1 = LBOUND(InData%u_SkewWake,1), UBOUND(InData%u_SkewWake,1) + CALL BEMT_Packskewwake_inputtype( Re_Buf, Db_Buf, Int_Buf, InData%u_SkewWake(i1), ErrStat2, ErrMsg2, OnlySize ) ! u_SkewWake + 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 IF ( .NOT. ALLOCATED(InData%TnInd_op) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -3212,19 +3716,8 @@ SUBROUTINE BEMT_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! u_DBEMT not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - 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_DBEMT)) DEALLOCATE(OutData%u_DBEMT) - ALLOCATE(OutData%u_DBEMT(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%u_DBEMT.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + i1_l = LBOUND(OutData%u_DBEMT,1) + i1_u = UBOUND(OutData%u_DBEMT,1) DO i1 = LBOUND(OutData%u_DBEMT,1), UBOUND(OutData%u_DBEMT,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 @@ -3267,7 +3760,50 @@ SUBROUTINE BEMT_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO - END IF + i1_l = LBOUND(OutData%u_SkewWake,1) + i1_u = UBOUND(OutData%u_SkewWake,1) + DO i1 = LBOUND(OutData%u_SkewWake,1), UBOUND(OutData%u_SkewWake,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 BEMT_Unpackskewwake_inputtype( Re_Buf, Db_Buf, Int_Buf, OutData%u_SkewWake(i1), ErrStat2, ErrMsg2 ) ! u_SkewWake + 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 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TnInd_op not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -3575,17 +4111,47 @@ SUBROUTINE BEMT_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg END IF DstParamData%FixedInductions = SrcParamData%FixedInductions ENDIF + DstParamData%MomentumCorr = SrcParamData%MomentumCorr + DstParamData%rTipFixMax = SrcParamData%rTipFixMax +IF (ALLOCATED(SrcParamData%IntegrateWeight)) THEN + i1_l = LBOUND(SrcParamData%IntegrateWeight,1) + i1_u = UBOUND(SrcParamData%IntegrateWeight,1) + i2_l = LBOUND(SrcParamData%IntegrateWeight,2) + i2_u = UBOUND(SrcParamData%IntegrateWeight,2) + IF (.NOT. ALLOCATED(DstParamData%IntegrateWeight)) THEN + ALLOCATE(DstParamData%IntegrateWeight(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%IntegrateWeight.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%IntegrateWeight = SrcParamData%IntegrateWeight +ENDIF + DstParamData%lin_nx = SrcParamData%lin_nx + DstParamData%BEM_Mod = SrcParamData%BEM_Mod END SUBROUTINE BEMT_CopyParam - SUBROUTINE BEMT_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE BEMT_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BEMT_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%chord)) THEN DEALLOCATE(ParamData%chord) ENDIF @@ -3601,10 +4167,15 @@ SUBROUTINE BEMT_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%zHub)) THEN DEALLOCATE(ParamData%zHub) ENDIF - CALL UA_DestroyParam( ParamData%UA, ErrStat, ErrMsg ) - CALL DBEMT_DestroyParam( ParamData%DBEMT, ErrStat, ErrMsg ) + CALL UA_DestroyParam( ParamData%UA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DBEMT_DestroyParam( ParamData%DBEMT, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ParamData%FixedInductions)) THEN DEALLOCATE(ParamData%FixedInductions) +ENDIF +IF (ALLOCATED(ParamData%IntegrateWeight)) THEN + DEALLOCATE(ParamData%IntegrateWeight) ENDIF END SUBROUTINE BEMT_DestroyParam @@ -3726,6 +4297,15 @@ SUBROUTINE BEMT_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 2*2 ! FixedInductions upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%FixedInductions) ! FixedInductions END IF + Int_BufSz = Int_BufSz + 1 ! MomentumCorr + Re_BufSz = Re_BufSz + 1 ! rTipFixMax + Int_BufSz = Int_BufSz + 1 ! IntegrateWeight allocated yes/no + IF ( ALLOCATED(InData%IntegrateWeight) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! IntegrateWeight upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%IntegrateWeight) ! IntegrateWeight + END IF + Int_BufSz = Int_BufSz + 1 ! lin_nx + Int_BufSz = Int_BufSz + 1 ! BEM_Mod IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -3960,6 +4540,34 @@ SUBROUTINE BEMT_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END DO END DO END IF + IntKiBuf(Int_Xferred) = TRANSFER(InData%MomentumCorr, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%rTipFixMax + Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%IntegrateWeight) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%IntegrateWeight,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IntegrateWeight,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%IntegrateWeight,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%IntegrateWeight,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%IntegrateWeight,2), UBOUND(InData%IntegrateWeight,2) + DO i1 = LBOUND(InData%IntegrateWeight,1), UBOUND(InData%IntegrateWeight,1) + ReKiBuf(Re_Xferred) = InData%IntegrateWeight(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IntKiBuf(Int_Xferred) = InData%lin_nx + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%BEM_Mod + Int_Xferred = Int_Xferred + 1 END SUBROUTINE BEMT_PackParam SUBROUTINE BEMT_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -4239,6 +4847,37 @@ SUBROUTINE BEMT_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END DO END DO END IF + OutData%MomentumCorr = TRANSFER(IntKiBuf(Int_Xferred), OutData%MomentumCorr) + Int_Xferred = Int_Xferred + 1 + OutData%rTipFixMax = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IntegrateWeight not allocated + Int_Xferred = Int_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%IntegrateWeight)) DEALLOCATE(OutData%IntegrateWeight) + ALLOCATE(OutData%IntegrateWeight(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%IntegrateWeight.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%IntegrateWeight,2), UBOUND(OutData%IntegrateWeight,2) + DO i1 = LBOUND(OutData%IntegrateWeight,1), UBOUND(OutData%IntegrateWeight,1) + OutData%IntegrateWeight(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + OutData%lin_nx = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%BEM_Mod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE BEMT_UnPackParam SUBROUTINE BEMT_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) @@ -4272,6 +4911,7 @@ SUBROUTINE BEMT_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg DstInputData%theta = SrcInputData%theta ENDIF DstInputData%chi0 = SrcInputData%chi0 + DstInputData%psiSkewOffset = SrcInputData%psiSkewOffset IF (ALLOCATED(SrcInputData%psi)) THEN i1_l = LBOUND(SrcInputData%psi,1) i1_u = UBOUND(SrcInputData%psi,1) @@ -4314,33 +4954,19 @@ SUBROUTINE BEMT_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%Vy = SrcInputData%Vy ENDIF -IF (ALLOCATED(SrcInputData%Vx_elast_dot)) THEN - i1_l = LBOUND(SrcInputData%Vx_elast_dot,1) - i1_u = UBOUND(SrcInputData%Vx_elast_dot,1) - i2_l = LBOUND(SrcInputData%Vx_elast_dot,2) - i2_u = UBOUND(SrcInputData%Vx_elast_dot,2) - IF (.NOT. ALLOCATED(DstInputData%Vx_elast_dot)) THEN - ALLOCATE(DstInputData%Vx_elast_dot(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%Vx_elast_dot.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputData%Vx_elast_dot = SrcInputData%Vx_elast_dot -ENDIF -IF (ALLOCATED(SrcInputData%Vy_elast_dot)) THEN - i1_l = LBOUND(SrcInputData%Vy_elast_dot,1) - i1_u = UBOUND(SrcInputData%Vy_elast_dot,1) - i2_l = LBOUND(SrcInputData%Vy_elast_dot,2) - i2_u = UBOUND(SrcInputData%Vy_elast_dot,2) - IF (.NOT. ALLOCATED(DstInputData%Vy_elast_dot)) THEN - ALLOCATE(DstInputData%Vy_elast_dot(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcInputData%Vz)) THEN + i1_l = LBOUND(SrcInputData%Vz,1) + i1_u = UBOUND(SrcInputData%Vz,1) + i2_l = LBOUND(SrcInputData%Vz,2) + i2_u = UBOUND(SrcInputData%Vz,2) + IF (.NOT. ALLOCATED(DstInputData%Vz)) THEN + ALLOCATE(DstInputData%Vz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%Vy_elast_dot.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%Vz.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInputData%Vy_elast_dot = SrcInputData%Vy_elast_dot + DstInputData%Vz = SrcInputData%Vz ENDIF IF (ALLOCATED(SrcInputData%omega_z)) THEN i1_l = LBOUND(SrcInputData%omega_z,1) @@ -4356,6 +4982,20 @@ SUBROUTINE BEMT_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%omega_z = SrcInputData%omega_z ENDIF +IF (ALLOCATED(SrcInputData%xVelCorr)) THEN + i1_l = LBOUND(SrcInputData%xVelCorr,1) + i1_u = UBOUND(SrcInputData%xVelCorr,1) + i2_l = LBOUND(SrcInputData%xVelCorr,2) + i2_u = UBOUND(SrcInputData%xVelCorr,2) + IF (.NOT. ALLOCATED(DstInputData%xVelCorr)) THEN + ALLOCATE(DstInputData%xVelCorr(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%xVelCorr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%xVelCorr = SrcInputData%xVelCorr +ENDIF IF (ALLOCATED(SrcInputData%rLocal)) THEN i1_l = LBOUND(SrcInputData%rLocal,1) i1_u = UBOUND(SrcInputData%rLocal,1) @@ -4371,6 +5011,8 @@ SUBROUTINE BEMT_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg DstInputData%rLocal = SrcInputData%rLocal ENDIF DstInputData%Un_disk = SrcInputData%Un_disk + DstInputData%V0 = SrcInputData%V0 + DstInputData%x_hat_disk = SrcInputData%x_hat_disk IF (ALLOCATED(SrcInputData%UserProp)) THEN i1_l = LBOUND(SrcInputData%UserProp,1) i1_u = UBOUND(SrcInputData%UserProp,1) @@ -4384,18 +5026,72 @@ SUBROUTINE BEMT_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF END IF DstInputData%UserProp = SrcInputData%UserProp +ENDIF +IF (ALLOCATED(SrcInputData%CantAngle)) THEN + i1_l = LBOUND(SrcInputData%CantAngle,1) + i1_u = UBOUND(SrcInputData%CantAngle,1) + i2_l = LBOUND(SrcInputData%CantAngle,2) + i2_u = UBOUND(SrcInputData%CantAngle,2) + IF (.NOT. ALLOCATED(DstInputData%CantAngle)) THEN + ALLOCATE(DstInputData%CantAngle(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%CantAngle.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%CantAngle = SrcInputData%CantAngle +ENDIF +IF (ALLOCATED(SrcInputData%drdz)) THEN + i1_l = LBOUND(SrcInputData%drdz,1) + i1_u = UBOUND(SrcInputData%drdz,1) + i2_l = LBOUND(SrcInputData%drdz,2) + i2_u = UBOUND(SrcInputData%drdz,2) + IF (.NOT. ALLOCATED(DstInputData%drdz)) THEN + ALLOCATE(DstInputData%drdz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%drdz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%drdz = SrcInputData%drdz +ENDIF +IF (ALLOCATED(SrcInputData%toeAngle)) THEN + i1_l = LBOUND(SrcInputData%toeAngle,1) + i1_u = UBOUND(SrcInputData%toeAngle,1) + i2_l = LBOUND(SrcInputData%toeAngle,2) + i2_u = UBOUND(SrcInputData%toeAngle,2) + IF (.NOT. ALLOCATED(DstInputData%toeAngle)) THEN + ALLOCATE(DstInputData%toeAngle(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%toeAngle.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%toeAngle = SrcInputData%toeAngle ENDIF END SUBROUTINE BEMT_CopyInput - SUBROUTINE BEMT_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE BEMT_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BEMT_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%theta)) THEN DEALLOCATE(InputData%theta) ENDIF @@ -4408,20 +5104,29 @@ SUBROUTINE BEMT_DestroyInput( InputData, ErrStat, ErrMsg ) IF (ALLOCATED(InputData%Vy)) THEN DEALLOCATE(InputData%Vy) ENDIF -IF (ALLOCATED(InputData%Vx_elast_dot)) THEN - DEALLOCATE(InputData%Vx_elast_dot) -ENDIF -IF (ALLOCATED(InputData%Vy_elast_dot)) THEN - DEALLOCATE(InputData%Vy_elast_dot) +IF (ALLOCATED(InputData%Vz)) THEN + DEALLOCATE(InputData%Vz) ENDIF IF (ALLOCATED(InputData%omega_z)) THEN DEALLOCATE(InputData%omega_z) ENDIF +IF (ALLOCATED(InputData%xVelCorr)) THEN + DEALLOCATE(InputData%xVelCorr) +ENDIF IF (ALLOCATED(InputData%rLocal)) THEN DEALLOCATE(InputData%rLocal) ENDIF IF (ALLOCATED(InputData%UserProp)) THEN DEALLOCATE(InputData%UserProp) +ENDIF +IF (ALLOCATED(InputData%CantAngle)) THEN + DEALLOCATE(InputData%CantAngle) +ENDIF +IF (ALLOCATED(InputData%drdz)) THEN + DEALLOCATE(InputData%drdz) +ENDIF +IF (ALLOCATED(InputData%toeAngle)) THEN + DEALLOCATE(InputData%toeAngle) ENDIF END SUBROUTINE BEMT_DestroyInput @@ -4466,6 +5171,7 @@ SUBROUTINE BEMT_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Re_BufSz = Re_BufSz + SIZE(InData%theta) ! theta END IF Re_BufSz = Re_BufSz + 1 ! chi0 + Re_BufSz = Re_BufSz + 1 ! psiSkewOffset Int_BufSz = Int_BufSz + 1 ! psi allocated yes/no IF ( ALLOCATED(InData%psi) ) THEN Int_BufSz = Int_BufSz + 2*1 ! psi upper/lower bounds for each dimension @@ -4483,33 +5189,50 @@ SUBROUTINE BEMT_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 2*2 ! Vy upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Vy) ! Vy END IF - Int_BufSz = Int_BufSz + 1 ! Vx_elast_dot allocated yes/no - IF ( ALLOCATED(InData%Vx_elast_dot) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! Vx_elast_dot upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Vx_elast_dot) ! Vx_elast_dot - END IF - Int_BufSz = Int_BufSz + 1 ! Vy_elast_dot allocated yes/no - IF ( ALLOCATED(InData%Vy_elast_dot) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! Vy_elast_dot upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Vy_elast_dot) ! Vy_elast_dot + Int_BufSz = Int_BufSz + 1 ! Vz allocated yes/no + IF ( ALLOCATED(InData%Vz) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Vz upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vz) ! Vz END IF Int_BufSz = Int_BufSz + 1 ! omega_z allocated yes/no IF ( ALLOCATED(InData%omega_z) ) THEN Int_BufSz = Int_BufSz + 2*2 ! omega_z upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%omega_z) ! omega_z END IF + Int_BufSz = Int_BufSz + 1 ! xVelCorr allocated yes/no + IF ( ALLOCATED(InData%xVelCorr) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! xVelCorr upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%xVelCorr) ! xVelCorr + END IF Int_BufSz = Int_BufSz + 1 ! rLocal allocated yes/no IF ( ALLOCATED(InData%rLocal) ) THEN Int_BufSz = Int_BufSz + 2*2 ! rLocal upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%rLocal) ! rLocal END IF Re_BufSz = Re_BufSz + 1 ! Un_disk + Re_BufSz = Re_BufSz + SIZE(InData%V0) ! V0 + Db_BufSz = Db_BufSz + SIZE(InData%x_hat_disk) ! x_hat_disk Int_BufSz = Int_BufSz + 1 ! UserProp allocated yes/no IF ( ALLOCATED(InData%UserProp) ) THEN Int_BufSz = Int_BufSz + 2*2 ! UserProp upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%UserProp) ! UserProp END IF - IF ( Re_BufSz .GT. 0 ) THEN + Int_BufSz = Int_BufSz + 1 ! CantAngle allocated yes/no + IF ( ALLOCATED(InData%CantAngle) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! CantAngle upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%CantAngle) ! CantAngle + END IF + Int_BufSz = Int_BufSz + 1 ! drdz allocated yes/no + IF ( ALLOCATED(InData%drdz) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! drdz upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%drdz) ! drdz + END IF + Int_BufSz = Int_BufSz + 1 ! toeAngle allocated yes/no + IF ( ALLOCATED(InData%toeAngle) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! toeAngle upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%toeAngle) ! toeAngle + 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) @@ -4558,6 +5281,8 @@ SUBROUTINE BEMT_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END IF ReKiBuf(Re_Xferred) = InData%chi0 Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%psiSkewOffset + Re_Xferred = Re_Xferred + 1 IF ( .NOT. ALLOCATED(InData%psi) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -4617,62 +5342,62 @@ SUBROUTINE BEMT_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Vx_elast_dot) ) THEN + IF ( .NOT. ALLOCATED(InData%Vz) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_elast_dot,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_elast_dot,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_elast_dot,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_elast_dot,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%Vx_elast_dot,2), UBOUND(InData%Vx_elast_dot,2) - DO i1 = LBOUND(InData%Vx_elast_dot,1), UBOUND(InData%Vx_elast_dot,1) - ReKiBuf(Re_Xferred) = InData%Vx_elast_dot(i1,i2) + DO i2 = LBOUND(InData%Vz,2), UBOUND(InData%Vz,2) + DO i1 = LBOUND(InData%Vz,1), UBOUND(InData%Vz,1) + ReKiBuf(Re_Xferred) = InData%Vz(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Vy_elast_dot) ) THEN + IF ( .NOT. ALLOCATED(InData%omega_z) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_elast_dot,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_elast_dot,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%omega_z,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%omega_z,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_elast_dot,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_elast_dot,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%omega_z,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%omega_z,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%Vy_elast_dot,2), UBOUND(InData%Vy_elast_dot,2) - DO i1 = LBOUND(InData%Vy_elast_dot,1), UBOUND(InData%Vy_elast_dot,1) - ReKiBuf(Re_Xferred) = InData%Vy_elast_dot(i1,i2) + DO i2 = LBOUND(InData%omega_z,2), UBOUND(InData%omega_z,2) + DO i1 = LBOUND(InData%omega_z,1), UBOUND(InData%omega_z,1) + ReKiBuf(Re_Xferred) = InData%omega_z(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%omega_z) ) THEN + IF ( .NOT. ALLOCATED(InData%xVelCorr) ) THEN 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_z,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%omega_z,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%xVelCorr,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%xVelCorr,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%omega_z,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%omega_z,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%xVelCorr,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%xVelCorr,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%omega_z,2), UBOUND(InData%omega_z,2) - DO i1 = LBOUND(InData%omega_z,1), UBOUND(InData%omega_z,1) - ReKiBuf(Re_Xferred) = InData%omega_z(i1,i2) + DO i2 = LBOUND(InData%xVelCorr,2), UBOUND(InData%xVelCorr,2) + DO i1 = LBOUND(InData%xVelCorr,1), UBOUND(InData%xVelCorr,1) + ReKiBuf(Re_Xferred) = InData%xVelCorr(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO @@ -4699,6 +5424,14 @@ SUBROUTINE BEMT_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END IF ReKiBuf(Re_Xferred) = InData%Un_disk Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%V0,1), UBOUND(InData%V0,1) + ReKiBuf(Re_Xferred) = InData%V0(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%x_hat_disk,1), UBOUND(InData%x_hat_disk,1) + DbKiBuf(Db_Xferred) = InData%x_hat_disk(i1) + Db_Xferred = Db_Xferred + 1 + END DO IF ( .NOT. ALLOCATED(InData%UserProp) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -4719,6 +5452,66 @@ SUBROUTINE BEMT_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%CantAngle) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CantAngle,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CantAngle,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CantAngle,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CantAngle,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%CantAngle,2), UBOUND(InData%CantAngle,2) + DO i1 = LBOUND(InData%CantAngle,1), UBOUND(InData%CantAngle,1) + ReKiBuf(Re_Xferred) = InData%CantAngle(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%drdz) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%drdz,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%drdz,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%drdz,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%drdz,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%drdz,2), UBOUND(InData%drdz,2) + DO i1 = LBOUND(InData%drdz,1), UBOUND(InData%drdz,1) + ReKiBuf(Re_Xferred) = InData%drdz(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%toeAngle) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%toeAngle,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%toeAngle,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%toeAngle,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%toeAngle,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%toeAngle,2), UBOUND(InData%toeAngle,2) + DO i1 = LBOUND(InData%toeAngle,1), UBOUND(InData%toeAngle,1) + ReKiBuf(Re_Xferred) = InData%toeAngle(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF END SUBROUTINE BEMT_PackInput SUBROUTINE BEMT_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -4774,6 +5567,8 @@ SUBROUTINE BEMT_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%chi0 = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%psiSkewOffset = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! psi not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -4842,7 +5637,7 @@ SUBROUTINE BEMT_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vx_elast_dot not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vz not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -4852,20 +5647,20 @@ SUBROUTINE BEMT_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Vx_elast_dot)) DEALLOCATE(OutData%Vx_elast_dot) - ALLOCATE(OutData%Vx_elast_dot(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Vz)) DEALLOCATE(OutData%Vz) + ALLOCATE(OutData%Vz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vx_elast_dot.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vz.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%Vx_elast_dot,2), UBOUND(OutData%Vx_elast_dot,2) - DO i1 = LBOUND(OutData%Vx_elast_dot,1), UBOUND(OutData%Vx_elast_dot,1) - OutData%Vx_elast_dot(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%Vz,2), UBOUND(OutData%Vz,2) + DO i1 = LBOUND(OutData%Vz,1), UBOUND(OutData%Vz,1) + OutData%Vz(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vy_elast_dot not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! omega_z not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -4875,20 +5670,20 @@ SUBROUTINE BEMT_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Vy_elast_dot)) DEALLOCATE(OutData%Vy_elast_dot) - ALLOCATE(OutData%Vy_elast_dot(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%omega_z)) DEALLOCATE(OutData%omega_z) + ALLOCATE(OutData%omega_z(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vy_elast_dot.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%omega_z.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%Vy_elast_dot,2), UBOUND(OutData%Vy_elast_dot,2) - DO i1 = LBOUND(OutData%Vy_elast_dot,1), UBOUND(OutData%Vy_elast_dot,1) - OutData%Vy_elast_dot(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%omega_z,2), UBOUND(OutData%omega_z,2) + DO i1 = LBOUND(OutData%omega_z,1), UBOUND(OutData%omega_z,1) + OutData%omega_z(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! omega_z not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! xVelCorr not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -4898,15 +5693,15 @@ SUBROUTINE BEMT_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs i2_l = IntKiBuf( Int_Xferred ) i2_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%omega_z)) DEALLOCATE(OutData%omega_z) - ALLOCATE(OutData%omega_z(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%xVelCorr)) DEALLOCATE(OutData%xVelCorr) + ALLOCATE(OutData%xVelCorr(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%omega_z.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%xVelCorr.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%omega_z,2), UBOUND(OutData%omega_z,2) - DO i1 = LBOUND(OutData%omega_z,1), UBOUND(OutData%omega_z,1) - OutData%omega_z(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%xVelCorr,2), UBOUND(OutData%xVelCorr,2) + DO i1 = LBOUND(OutData%xVelCorr,1), UBOUND(OutData%xVelCorr,1) + OutData%xVelCorr(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO @@ -4936,6 +5731,18 @@ SUBROUTINE BEMT_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%Un_disk = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%V0,1) + i1_u = UBOUND(OutData%V0,1) + DO i1 = LBOUND(OutData%V0,1), UBOUND(OutData%V0,1) + OutData%V0(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%x_hat_disk,1) + i1_u = UBOUND(OutData%x_hat_disk,1) + DO i1 = LBOUND(OutData%x_hat_disk,1), UBOUND(OutData%x_hat_disk,1) + OutData%x_hat_disk(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! UserProp not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -4959,6 +5766,75 @@ SUBROUTINE BEMT_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CantAngle not allocated + Int_Xferred = Int_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%CantAngle)) DEALLOCATE(OutData%CantAngle) + ALLOCATE(OutData%CantAngle(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CantAngle.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%CantAngle,2), UBOUND(OutData%CantAngle,2) + DO i1 = LBOUND(OutData%CantAngle,1), UBOUND(OutData%CantAngle,1) + OutData%CantAngle(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! drdz not allocated + Int_Xferred = Int_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%drdz)) DEALLOCATE(OutData%drdz) + ALLOCATE(OutData%drdz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%drdz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%drdz,2), UBOUND(OutData%drdz,2) + DO i1 = LBOUND(OutData%drdz,1), UBOUND(OutData%drdz,1) + OutData%drdz(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! toeAngle not allocated + Int_Xferred = Int_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%toeAngle)) DEALLOCATE(OutData%toeAngle) + ALLOCATE(OutData%toeAngle(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%toeAngle.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%toeAngle,2), UBOUND(OutData%toeAngle,2) + DO i1 = LBOUND(OutData%toeAngle,1), UBOUND(OutData%toeAngle,1) + OutData%toeAngle(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF END SUBROUTINE BEMT_UnPackInput SUBROUTINE BEMT_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -5089,6 +5965,62 @@ SUBROUTINE BEMT_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Err END IF DstOutputData%Cy = SrcOutputData%Cy ENDIF +IF (ALLOCATED(SrcOutputData%Cz)) THEN + i1_l = LBOUND(SrcOutputData%Cz,1) + i1_u = UBOUND(SrcOutputData%Cz,1) + i2_l = LBOUND(SrcOutputData%Cz,2) + i2_u = UBOUND(SrcOutputData%Cz,2) + IF (.NOT. ALLOCATED(DstOutputData%Cz)) THEN + ALLOCATE(DstOutputData%Cz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%Cz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%Cz = SrcOutputData%Cz +ENDIF +IF (ALLOCATED(SrcOutputData%Cmx)) THEN + i1_l = LBOUND(SrcOutputData%Cmx,1) + i1_u = UBOUND(SrcOutputData%Cmx,1) + i2_l = LBOUND(SrcOutputData%Cmx,2) + i2_u = UBOUND(SrcOutputData%Cmx,2) + IF (.NOT. ALLOCATED(DstOutputData%Cmx)) THEN + ALLOCATE(DstOutputData%Cmx(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%Cmx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%Cmx = SrcOutputData%Cmx +ENDIF +IF (ALLOCATED(SrcOutputData%Cmy)) THEN + i1_l = LBOUND(SrcOutputData%Cmy,1) + i1_u = UBOUND(SrcOutputData%Cmy,1) + i2_l = LBOUND(SrcOutputData%Cmy,2) + i2_u = UBOUND(SrcOutputData%Cmy,2) + IF (.NOT. ALLOCATED(DstOutputData%Cmy)) THEN + ALLOCATE(DstOutputData%Cmy(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%Cmy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%Cmy = SrcOutputData%Cmy +ENDIF +IF (ALLOCATED(SrcOutputData%Cmz)) THEN + i1_l = LBOUND(SrcOutputData%Cmz,1) + i1_u = UBOUND(SrcOutputData%Cmz,1) + i2_l = LBOUND(SrcOutputData%Cmz,2) + i2_u = UBOUND(SrcOutputData%Cmz,2) + IF (.NOT. ALLOCATED(DstOutputData%Cmz)) THEN + ALLOCATE(DstOutputData%Cmz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%Cmz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%Cmz = SrcOutputData%Cmz +ENDIF IF (ALLOCATED(SrcOutputData%Cm)) THEN i1_l = LBOUND(SrcOutputData%Cm,1) i1_u = UBOUND(SrcOutputData%Cm,1) @@ -5161,15 +6093,27 @@ SUBROUTINE BEMT_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Err ENDIF END SUBROUTINE BEMT_CopyOutput - SUBROUTINE BEMT_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE BEMT_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BEMT_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BEMT_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%Vrel)) THEN DEALLOCATE(OutputData%Vrel) ENDIF @@ -5194,6 +6138,18 @@ SUBROUTINE BEMT_DestroyOutput( OutputData, ErrStat, ErrMsg ) IF (ALLOCATED(OutputData%Cy)) THEN DEALLOCATE(OutputData%Cy) ENDIF +IF (ALLOCATED(OutputData%Cz)) THEN + DEALLOCATE(OutputData%Cz) +ENDIF +IF (ALLOCATED(OutputData%Cmx)) THEN + DEALLOCATE(OutputData%Cmx) +ENDIF +IF (ALLOCATED(OutputData%Cmy)) THEN + DEALLOCATE(OutputData%Cmy) +ENDIF +IF (ALLOCATED(OutputData%Cmz)) THEN + DEALLOCATE(OutputData%Cmz) +ENDIF IF (ALLOCATED(OutputData%Cm)) THEN DEALLOCATE(OutputData%Cm) ENDIF @@ -5286,6 +6242,26 @@ SUBROUTINE BEMT_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 2*2 ! Cy upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Cy) ! Cy END IF + Int_BufSz = Int_BufSz + 1 ! Cz allocated yes/no + IF ( ALLOCATED(InData%Cz) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Cz upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Cz) ! Cz + END IF + Int_BufSz = Int_BufSz + 1 ! Cmx allocated yes/no + IF ( ALLOCATED(InData%Cmx) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Cmx upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Cmx) ! Cmx + END IF + Int_BufSz = Int_BufSz + 1 ! Cmy allocated yes/no + IF ( ALLOCATED(InData%Cmy) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Cmy upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Cmy) ! Cmy + END IF + Int_BufSz = Int_BufSz + 1 ! Cmz allocated yes/no + IF ( ALLOCATED(InData%Cmz) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Cmz upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Cmz) ! Cmz + END IF Int_BufSz = Int_BufSz + 1 ! Cm allocated yes/no IF ( ALLOCATED(InData%Cm) ) THEN Int_BufSz = Int_BufSz + 2*2 ! Cm upper/lower bounds for each dimension @@ -5498,6 +6474,86 @@ SUBROUTINE BEMT_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%Cz) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cz,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cz,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cz,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cz,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Cz,2), UBOUND(InData%Cz,2) + DO i1 = LBOUND(InData%Cz,1), UBOUND(InData%Cz,1) + ReKiBuf(Re_Xferred) = InData%Cz(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Cmx) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cmx,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cmx,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cmx,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cmx,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Cmx,2), UBOUND(InData%Cmx,2) + DO i1 = LBOUND(InData%Cmx,1), UBOUND(InData%Cmx,1) + ReKiBuf(Re_Xferred) = InData%Cmx(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Cmy) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cmy,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cmy,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cmy,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cmy,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Cmy,2), UBOUND(InData%Cmy,2) + DO i1 = LBOUND(InData%Cmy,1), UBOUND(InData%Cmy,1) + ReKiBuf(Re_Xferred) = InData%Cmy(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Cmz) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cmz,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cmz,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cmz,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cmz,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Cmz,2), UBOUND(InData%Cmz,2) + DO i1 = LBOUND(InData%Cmz,1), UBOUND(InData%Cmz,1) + ReKiBuf(Re_Xferred) = InData%Cmz(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF IF ( .NOT. ALLOCATED(InData%Cm) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -5812,6 +6868,98 @@ SUBROUTINE BEMT_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Cz not allocated + Int_Xferred = Int_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%Cz)) DEALLOCATE(OutData%Cz) + ALLOCATE(OutData%Cz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Cz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Cz,2), UBOUND(OutData%Cz,2) + DO i1 = LBOUND(OutData%Cz,1), UBOUND(OutData%Cz,1) + OutData%Cz(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Cmx not allocated + Int_Xferred = Int_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%Cmx)) DEALLOCATE(OutData%Cmx) + ALLOCATE(OutData%Cmx(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Cmx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Cmx,2), UBOUND(OutData%Cmx,2) + DO i1 = LBOUND(OutData%Cmx,1), UBOUND(OutData%Cmx,1) + OutData%Cmx(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Cmy not allocated + Int_Xferred = Int_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%Cmy)) DEALLOCATE(OutData%Cmy) + ALLOCATE(OutData%Cmy(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Cmy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Cmy,2), UBOUND(OutData%Cmy,2) + DO i1 = LBOUND(OutData%Cmy,1), UBOUND(OutData%Cmy,1) + OutData%Cmy(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Cmz not allocated + Int_Xferred = Int_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%Cmz)) DEALLOCATE(OutData%Cmz) + ALLOCATE(OutData%Cmz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Cmz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Cmz,2), UBOUND(OutData%Cmz,2) + DO i1 = LBOUND(OutData%Cmz,1), UBOUND(OutData%Cmz,1) + OutData%Cmz(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Cm not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -6036,6 +7184,8 @@ SUBROUTINE BEMT_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg END IF ! check if allocated b = -(u1%chi0 - u2%chi0) u_out%chi0 = u1%chi0 + b * ScaleFactor + b = -(u1%psiSkewOffset - u2%psiSkewOffset) + u_out%psiSkewOffset = u1%psiSkewOffset + b * ScaleFactor IF (ALLOCATED(u_out%psi) .AND. ALLOCATED(u1%psi)) THEN DO i1 = LBOUND(u_out%psi,1),UBOUND(u_out%psi,1) b = -(u1%psi(i1) - u2%psi(i1)) @@ -6062,19 +7212,11 @@ SUBROUTINE BEMT_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg END DO END DO END IF ! check if allocated -IF (ALLOCATED(u_out%Vx_elast_dot) .AND. ALLOCATED(u1%Vx_elast_dot)) THEN - DO i2 = LBOUND(u_out%Vx_elast_dot,2),UBOUND(u_out%Vx_elast_dot,2) - DO i1 = LBOUND(u_out%Vx_elast_dot,1),UBOUND(u_out%Vx_elast_dot,1) - b = -(u1%Vx_elast_dot(i1,i2) - u2%Vx_elast_dot(i1,i2)) - u_out%Vx_elast_dot(i1,i2) = u1%Vx_elast_dot(i1,i2) + b * ScaleFactor - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(u_out%Vy_elast_dot) .AND. ALLOCATED(u1%Vy_elast_dot)) THEN - DO i2 = LBOUND(u_out%Vy_elast_dot,2),UBOUND(u_out%Vy_elast_dot,2) - DO i1 = LBOUND(u_out%Vy_elast_dot,1),UBOUND(u_out%Vy_elast_dot,1) - b = -(u1%Vy_elast_dot(i1,i2) - u2%Vy_elast_dot(i1,i2)) - u_out%Vy_elast_dot(i1,i2) = u1%Vy_elast_dot(i1,i2) + b * ScaleFactor +IF (ALLOCATED(u_out%Vz) .AND. ALLOCATED(u1%Vz)) THEN + DO i2 = LBOUND(u_out%Vz,2),UBOUND(u_out%Vz,2) + DO i1 = LBOUND(u_out%Vz,1),UBOUND(u_out%Vz,1) + b = -(u1%Vz(i1,i2) - u2%Vz(i1,i2)) + u_out%Vz(i1,i2) = u1%Vz(i1,i2) + b * ScaleFactor END DO END DO END IF ! check if allocated @@ -6086,6 +7228,14 @@ SUBROUTINE BEMT_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg END DO END DO END IF ! check if allocated +IF (ALLOCATED(u_out%xVelCorr) .AND. ALLOCATED(u1%xVelCorr)) THEN + DO i2 = LBOUND(u_out%xVelCorr,2),UBOUND(u_out%xVelCorr,2) + DO i1 = LBOUND(u_out%xVelCorr,1),UBOUND(u_out%xVelCorr,1) + b = -(u1%xVelCorr(i1,i2) - u2%xVelCorr(i1,i2)) + u_out%xVelCorr(i1,i2) = u1%xVelCorr(i1,i2) + b * ScaleFactor + END DO + END DO +END IF ! check if allocated IF (ALLOCATED(u_out%rLocal) .AND. ALLOCATED(u1%rLocal)) THEN DO i2 = LBOUND(u_out%rLocal,2),UBOUND(u_out%rLocal,2) DO i1 = LBOUND(u_out%rLocal,1),UBOUND(u_out%rLocal,1) @@ -6096,6 +7246,14 @@ SUBROUTINE BEMT_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg END IF ! check if allocated b = -(u1%Un_disk - u2%Un_disk) u_out%Un_disk = u1%Un_disk + b * ScaleFactor + DO i1 = LBOUND(u_out%V0,1),UBOUND(u_out%V0,1) + b = -(u1%V0(i1) - u2%V0(i1)) + u_out%V0(i1) = u1%V0(i1) + b * ScaleFactor + END DO + DO i1 = LBOUND(u_out%x_hat_disk,1),UBOUND(u_out%x_hat_disk,1) + b = -(u1%x_hat_disk(i1) - u2%x_hat_disk(i1)) + u_out%x_hat_disk(i1) = u1%x_hat_disk(i1) + b * ScaleFactor + END DO IF (ALLOCATED(u_out%UserProp) .AND. ALLOCATED(u1%UserProp)) THEN DO i2 = LBOUND(u_out%UserProp,2),UBOUND(u_out%UserProp,2) DO i1 = LBOUND(u_out%UserProp,1),UBOUND(u_out%UserProp,1) @@ -6103,6 +7261,30 @@ SUBROUTINE BEMT_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg u_out%UserProp(i1,i2) = u1%UserProp(i1,i2) + b * ScaleFactor END DO END DO +END IF ! check if allocated +IF (ALLOCATED(u_out%CantAngle) .AND. ALLOCATED(u1%CantAngle)) THEN + DO i2 = LBOUND(u_out%CantAngle,2),UBOUND(u_out%CantAngle,2) + DO i1 = LBOUND(u_out%CantAngle,1),UBOUND(u_out%CantAngle,1) + b = -(u1%CantAngle(i1,i2) - u2%CantAngle(i1,i2)) + u_out%CantAngle(i1,i2) = u1%CantAngle(i1,i2) + b * ScaleFactor + END DO + END DO +END IF ! check if allocated +IF (ALLOCATED(u_out%drdz) .AND. ALLOCATED(u1%drdz)) THEN + DO i2 = LBOUND(u_out%drdz,2),UBOUND(u_out%drdz,2) + DO i1 = LBOUND(u_out%drdz,1),UBOUND(u_out%drdz,1) + b = -(u1%drdz(i1,i2) - u2%drdz(i1,i2)) + u_out%drdz(i1,i2) = u1%drdz(i1,i2) + b * ScaleFactor + END DO + END DO +END IF ! check if allocated +IF (ALLOCATED(u_out%toeAngle) .AND. ALLOCATED(u1%toeAngle)) THEN + DO i2 = LBOUND(u_out%toeAngle,2),UBOUND(u_out%toeAngle,2) + DO i1 = LBOUND(u_out%toeAngle,1),UBOUND(u_out%toeAngle,1) + b = -(u1%toeAngle(i1,i2) - u2%toeAngle(i1,i2)) + u_out%toeAngle(i1,i2) = u1%toeAngle(i1,i2) + b * ScaleFactor + END DO + END DO END IF ! check if allocated END SUBROUTINE BEMT_Input_ExtrapInterp1 @@ -6175,6 +7357,9 @@ SUBROUTINE BEMT_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, Er b = (t(3)**2*(u1%chi0 - u2%chi0) + t(2)**2*(-u1%chi0 + u3%chi0))* scaleFactor c = ( (t(2)-t(3))*u1%chi0 + t(3)*u2%chi0 - t(2)*u3%chi0 ) * scaleFactor u_out%chi0 = u1%chi0 + b + c * t_out + b = (t(3)**2*(u1%psiSkewOffset - u2%psiSkewOffset) + t(2)**2*(-u1%psiSkewOffset + u3%psiSkewOffset))* scaleFactor + c = ( (t(2)-t(3))*u1%psiSkewOffset + t(3)*u2%psiSkewOffset - t(2)*u3%psiSkewOffset ) * scaleFactor + u_out%psiSkewOffset = u1%psiSkewOffset + b + c * t_out IF (ALLOCATED(u_out%psi) .AND. ALLOCATED(u1%psi)) THEN DO i1 = LBOUND(u_out%psi,1),UBOUND(u_out%psi,1) b = (t(3)**2*(u1%psi(i1) - u2%psi(i1)) + t(2)**2*(-u1%psi(i1) + u3%psi(i1)))* scaleFactor @@ -6206,21 +7391,12 @@ SUBROUTINE BEMT_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, Er END DO END DO END IF ! check if allocated -IF (ALLOCATED(u_out%Vx_elast_dot) .AND. ALLOCATED(u1%Vx_elast_dot)) THEN - DO i2 = LBOUND(u_out%Vx_elast_dot,2),UBOUND(u_out%Vx_elast_dot,2) - DO i1 = LBOUND(u_out%Vx_elast_dot,1),UBOUND(u_out%Vx_elast_dot,1) - b = (t(3)**2*(u1%Vx_elast_dot(i1,i2) - u2%Vx_elast_dot(i1,i2)) + t(2)**2*(-u1%Vx_elast_dot(i1,i2) + u3%Vx_elast_dot(i1,i2)))* scaleFactor - c = ( (t(2)-t(3))*u1%Vx_elast_dot(i1,i2) + t(3)*u2%Vx_elast_dot(i1,i2) - t(2)*u3%Vx_elast_dot(i1,i2) ) * scaleFactor - u_out%Vx_elast_dot(i1,i2) = u1%Vx_elast_dot(i1,i2) + b + c * t_out - END DO - END DO -END IF ! check if allocated -IF (ALLOCATED(u_out%Vy_elast_dot) .AND. ALLOCATED(u1%Vy_elast_dot)) THEN - DO i2 = LBOUND(u_out%Vy_elast_dot,2),UBOUND(u_out%Vy_elast_dot,2) - DO i1 = LBOUND(u_out%Vy_elast_dot,1),UBOUND(u_out%Vy_elast_dot,1) - b = (t(3)**2*(u1%Vy_elast_dot(i1,i2) - u2%Vy_elast_dot(i1,i2)) + t(2)**2*(-u1%Vy_elast_dot(i1,i2) + u3%Vy_elast_dot(i1,i2)))* scaleFactor - c = ( (t(2)-t(3))*u1%Vy_elast_dot(i1,i2) + t(3)*u2%Vy_elast_dot(i1,i2) - t(2)*u3%Vy_elast_dot(i1,i2) ) * scaleFactor - u_out%Vy_elast_dot(i1,i2) = u1%Vy_elast_dot(i1,i2) + b + c * t_out +IF (ALLOCATED(u_out%Vz) .AND. ALLOCATED(u1%Vz)) THEN + DO i2 = LBOUND(u_out%Vz,2),UBOUND(u_out%Vz,2) + DO i1 = LBOUND(u_out%Vz,1),UBOUND(u_out%Vz,1) + b = (t(3)**2*(u1%Vz(i1,i2) - u2%Vz(i1,i2)) + t(2)**2*(-u1%Vz(i1,i2) + u3%Vz(i1,i2)))* scaleFactor + c = ( (t(2)-t(3))*u1%Vz(i1,i2) + t(3)*u2%Vz(i1,i2) - t(2)*u3%Vz(i1,i2) ) * scaleFactor + u_out%Vz(i1,i2) = u1%Vz(i1,i2) + b + c * t_out END DO END DO END IF ! check if allocated @@ -6233,6 +7409,15 @@ SUBROUTINE BEMT_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, Er END DO END DO END IF ! check if allocated +IF (ALLOCATED(u_out%xVelCorr) .AND. ALLOCATED(u1%xVelCorr)) THEN + DO i2 = LBOUND(u_out%xVelCorr,2),UBOUND(u_out%xVelCorr,2) + DO i1 = LBOUND(u_out%xVelCorr,1),UBOUND(u_out%xVelCorr,1) + b = (t(3)**2*(u1%xVelCorr(i1,i2) - u2%xVelCorr(i1,i2)) + t(2)**2*(-u1%xVelCorr(i1,i2) + u3%xVelCorr(i1,i2)))* scaleFactor + c = ( (t(2)-t(3))*u1%xVelCorr(i1,i2) + t(3)*u2%xVelCorr(i1,i2) - t(2)*u3%xVelCorr(i1,i2) ) * scaleFactor + u_out%xVelCorr(i1,i2) = u1%xVelCorr(i1,i2) + b + c * t_out + END DO + END DO +END IF ! check if allocated IF (ALLOCATED(u_out%rLocal) .AND. ALLOCATED(u1%rLocal)) THEN DO i2 = LBOUND(u_out%rLocal,2),UBOUND(u_out%rLocal,2) DO i1 = LBOUND(u_out%rLocal,1),UBOUND(u_out%rLocal,1) @@ -6245,6 +7430,16 @@ SUBROUTINE BEMT_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, Er b = (t(3)**2*(u1%Un_disk - u2%Un_disk) + t(2)**2*(-u1%Un_disk + u3%Un_disk))* scaleFactor c = ( (t(2)-t(3))*u1%Un_disk + t(3)*u2%Un_disk - t(2)*u3%Un_disk ) * scaleFactor u_out%Un_disk = u1%Un_disk + b + c * t_out + DO i1 = LBOUND(u_out%V0,1),UBOUND(u_out%V0,1) + b = (t(3)**2*(u1%V0(i1) - u2%V0(i1)) + t(2)**2*(-u1%V0(i1) + u3%V0(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%V0(i1) + t(3)*u2%V0(i1) - t(2)*u3%V0(i1) ) * scaleFactor + u_out%V0(i1) = u1%V0(i1) + b + c * t_out + END DO + DO i1 = LBOUND(u_out%x_hat_disk,1),UBOUND(u_out%x_hat_disk,1) + b = (t(3)**2*(u1%x_hat_disk(i1) - u2%x_hat_disk(i1)) + t(2)**2*(-u1%x_hat_disk(i1) + u3%x_hat_disk(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%x_hat_disk(i1) + t(3)*u2%x_hat_disk(i1) - t(2)*u3%x_hat_disk(i1) ) * scaleFactor + u_out%x_hat_disk(i1) = u1%x_hat_disk(i1) + b + c * t_out + END DO IF (ALLOCATED(u_out%UserProp) .AND. ALLOCATED(u1%UserProp)) THEN DO i2 = LBOUND(u_out%UserProp,2),UBOUND(u_out%UserProp,2) DO i1 = LBOUND(u_out%UserProp,1),UBOUND(u_out%UserProp,1) @@ -6253,6 +7448,33 @@ SUBROUTINE BEMT_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, Er u_out%UserProp(i1,i2) = u1%UserProp(i1,i2) + b + c * t_out END DO END DO +END IF ! check if allocated +IF (ALLOCATED(u_out%CantAngle) .AND. ALLOCATED(u1%CantAngle)) THEN + DO i2 = LBOUND(u_out%CantAngle,2),UBOUND(u_out%CantAngle,2) + DO i1 = LBOUND(u_out%CantAngle,1),UBOUND(u_out%CantAngle,1) + b = (t(3)**2*(u1%CantAngle(i1,i2) - u2%CantAngle(i1,i2)) + t(2)**2*(-u1%CantAngle(i1,i2) + u3%CantAngle(i1,i2)))* scaleFactor + c = ( (t(2)-t(3))*u1%CantAngle(i1,i2) + t(3)*u2%CantAngle(i1,i2) - t(2)*u3%CantAngle(i1,i2) ) * scaleFactor + u_out%CantAngle(i1,i2) = u1%CantAngle(i1,i2) + b + c * t_out + END DO + END DO +END IF ! check if allocated +IF (ALLOCATED(u_out%drdz) .AND. ALLOCATED(u1%drdz)) THEN + DO i2 = LBOUND(u_out%drdz,2),UBOUND(u_out%drdz,2) + DO i1 = LBOUND(u_out%drdz,1),UBOUND(u_out%drdz,1) + b = (t(3)**2*(u1%drdz(i1,i2) - u2%drdz(i1,i2)) + t(2)**2*(-u1%drdz(i1,i2) + u3%drdz(i1,i2)))* scaleFactor + c = ( (t(2)-t(3))*u1%drdz(i1,i2) + t(3)*u2%drdz(i1,i2) - t(2)*u3%drdz(i1,i2) ) * scaleFactor + u_out%drdz(i1,i2) = u1%drdz(i1,i2) + b + c * t_out + END DO + END DO +END IF ! check if allocated +IF (ALLOCATED(u_out%toeAngle) .AND. ALLOCATED(u1%toeAngle)) THEN + DO i2 = LBOUND(u_out%toeAngle,2),UBOUND(u_out%toeAngle,2) + DO i1 = LBOUND(u_out%toeAngle,1),UBOUND(u_out%toeAngle,1) + b = (t(3)**2*(u1%toeAngle(i1,i2) - u2%toeAngle(i1,i2)) + t(2)**2*(-u1%toeAngle(i1,i2) + u3%toeAngle(i1,i2)))* scaleFactor + c = ( (t(2)-t(3))*u1%toeAngle(i1,i2) + t(3)*u2%toeAngle(i1,i2) - t(2)*u3%toeAngle(i1,i2) ) * scaleFactor + u_out%toeAngle(i1,i2) = u1%toeAngle(i1,i2) + b + c * t_out + END DO + END DO END IF ! check if allocated END SUBROUTINE BEMT_Input_ExtrapInterp2 @@ -6417,6 +7639,38 @@ SUBROUTINE BEMT_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, ErrMs END DO END DO END IF ! check if allocated +IF (ALLOCATED(y_out%Cz) .AND. ALLOCATED(y1%Cz)) THEN + DO i2 = LBOUND(y_out%Cz,2),UBOUND(y_out%Cz,2) + DO i1 = LBOUND(y_out%Cz,1),UBOUND(y_out%Cz,1) + b = -(y1%Cz(i1,i2) - y2%Cz(i1,i2)) + y_out%Cz(i1,i2) = y1%Cz(i1,i2) + b * ScaleFactor + END DO + END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%Cmx) .AND. ALLOCATED(y1%Cmx)) THEN + DO i2 = LBOUND(y_out%Cmx,2),UBOUND(y_out%Cmx,2) + DO i1 = LBOUND(y_out%Cmx,1),UBOUND(y_out%Cmx,1) + b = -(y1%Cmx(i1,i2) - y2%Cmx(i1,i2)) + y_out%Cmx(i1,i2) = y1%Cmx(i1,i2) + b * ScaleFactor + END DO + END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%Cmy) .AND. ALLOCATED(y1%Cmy)) THEN + DO i2 = LBOUND(y_out%Cmy,2),UBOUND(y_out%Cmy,2) + DO i1 = LBOUND(y_out%Cmy,1),UBOUND(y_out%Cmy,1) + b = -(y1%Cmy(i1,i2) - y2%Cmy(i1,i2)) + y_out%Cmy(i1,i2) = y1%Cmy(i1,i2) + b * ScaleFactor + END DO + END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%Cmz) .AND. ALLOCATED(y1%Cmz)) THEN + DO i2 = LBOUND(y_out%Cmz,2),UBOUND(y_out%Cmz,2) + DO i1 = LBOUND(y_out%Cmz,1),UBOUND(y_out%Cmz,1) + b = -(y1%Cmz(i1,i2) - y2%Cmz(i1,i2)) + y_out%Cmz(i1,i2) = y1%Cmz(i1,i2) + b * ScaleFactor + END DO + END DO +END IF ! check if allocated IF (ALLOCATED(y_out%Cm) .AND. ALLOCATED(y1%Cm)) THEN DO i2 = LBOUND(y_out%Cm,2),UBOUND(y_out%Cm,2) DO i1 = LBOUND(y_out%Cm,1),UBOUND(y_out%Cm,1) @@ -6588,6 +7842,42 @@ SUBROUTINE BEMT_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, E END DO END DO END IF ! check if allocated +IF (ALLOCATED(y_out%Cz) .AND. ALLOCATED(y1%Cz)) THEN + DO i2 = LBOUND(y_out%Cz,2),UBOUND(y_out%Cz,2) + DO i1 = LBOUND(y_out%Cz,1),UBOUND(y_out%Cz,1) + b = (t(3)**2*(y1%Cz(i1,i2) - y2%Cz(i1,i2)) + t(2)**2*(-y1%Cz(i1,i2) + y3%Cz(i1,i2)))* scaleFactor + c = ( (t(2)-t(3))*y1%Cz(i1,i2) + t(3)*y2%Cz(i1,i2) - t(2)*y3%Cz(i1,i2) ) * scaleFactor + y_out%Cz(i1,i2) = y1%Cz(i1,i2) + b + c * t_out + END DO + END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%Cmx) .AND. ALLOCATED(y1%Cmx)) THEN + DO i2 = LBOUND(y_out%Cmx,2),UBOUND(y_out%Cmx,2) + DO i1 = LBOUND(y_out%Cmx,1),UBOUND(y_out%Cmx,1) + b = (t(3)**2*(y1%Cmx(i1,i2) - y2%Cmx(i1,i2)) + t(2)**2*(-y1%Cmx(i1,i2) + y3%Cmx(i1,i2)))* scaleFactor + c = ( (t(2)-t(3))*y1%Cmx(i1,i2) + t(3)*y2%Cmx(i1,i2) - t(2)*y3%Cmx(i1,i2) ) * scaleFactor + y_out%Cmx(i1,i2) = y1%Cmx(i1,i2) + b + c * t_out + END DO + END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%Cmy) .AND. ALLOCATED(y1%Cmy)) THEN + DO i2 = LBOUND(y_out%Cmy,2),UBOUND(y_out%Cmy,2) + DO i1 = LBOUND(y_out%Cmy,1),UBOUND(y_out%Cmy,1) + b = (t(3)**2*(y1%Cmy(i1,i2) - y2%Cmy(i1,i2)) + t(2)**2*(-y1%Cmy(i1,i2) + y3%Cmy(i1,i2)))* scaleFactor + c = ( (t(2)-t(3))*y1%Cmy(i1,i2) + t(3)*y2%Cmy(i1,i2) - t(2)*y3%Cmy(i1,i2) ) * scaleFactor + y_out%Cmy(i1,i2) = y1%Cmy(i1,i2) + b + c * t_out + END DO + END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%Cmz) .AND. ALLOCATED(y1%Cmz)) THEN + DO i2 = LBOUND(y_out%Cmz,2),UBOUND(y_out%Cmz,2) + DO i1 = LBOUND(y_out%Cmz,1),UBOUND(y_out%Cmz,1) + b = (t(3)**2*(y1%Cmz(i1,i2) - y2%Cmz(i1,i2)) + t(2)**2*(-y1%Cmz(i1,i2) + y3%Cmz(i1,i2)))* scaleFactor + c = ( (t(2)-t(3))*y1%Cmz(i1,i2) + t(3)*y2%Cmz(i1,i2) - t(2)*y3%Cmz(i1,i2) ) * scaleFactor + y_out%Cmz(i1,i2) = y1%Cmz(i1,i2) + b + c * t_out + END DO + END DO +END IF ! check if allocated IF (ALLOCATED(y_out%Cm) .AND. ALLOCATED(y1%Cm)) THEN DO i2 = LBOUND(y_out%Cm,2),UBOUND(y_out%Cm,2) DO i1 = LBOUND(y_out%Cm,1),UBOUND(y_out%Cm,1) diff --git a/modules/aerodyn/src/DBEMT.f90 b/modules/aerodyn/src/DBEMT.f90 index 4d3eae6a1..3c12e5c3b 100644 --- a/modules/aerodyn/src/DBEMT.f90 +++ b/modules/aerodyn/src/DBEMT.f90 @@ -17,6 +17,14 @@ ! See the License for the specific language governing permissions and ! limitations under the License. !********************************************************************************************************************************** +! +! References: +! [1] E. Branlard, B. Jonkman, G.R. Pirrung, K. Dixon, J. Jonkman (2022) +! Dynamic inflow and unsteady aerodynamics models for modal and stability analyses in OpenFAST, +! Journal of Physics: Conference Series, doi:10.1088/1742-6596/2265/3/032044 +! [2] R. Damiani, J.Jonkman +! DBEMT Theory Rev. 3 +! Unpublished module DBEMT use NWTC_Library @@ -208,7 +216,7 @@ subroutine DBEMT_Init( InitInp, u, p, x, OtherState, m, Interval, InitOut, ErrSt end if end do - p%lin_nx = p%numNodes*p%numBlades*4 ! vind and vind_dot + p%lin_nx = p%numNodes*p%numBlades*4 ! vind and vind_1 else p%lin_nx = 0 end if @@ -241,9 +249,8 @@ subroutine DBEMT_ReInit( p, x, OtherState, m ) do j=1,size(x%element,2) do i=1,size(x%element,1) - x%element(i,j)%vind = 0.0_ReKi - x%element(i,j)%vind_dot = 0.0_ReKi - x%element(i,j)%vind_1 = 0.0_ReKi + x%element(i,j)%vind = 0.0_ReKi ! Dynamic induced velocities + x%element(i,j)%vind_1 = 0.0_ReKi ! Reduced induced velocities end do end do @@ -306,10 +313,10 @@ subroutine DBEMT_InitStates( i, j, u, p, x, OtherState ) x%element(i,j)%vind(2) = u%element(i,j)%vind_s(2) if (p%DBEMT_Mod == DBEMT_cont_tauConst) then - x%element(i,j)%vind_dot(1) = u%element(i,j)%vind_s_dot(1) - x%element(i,j)%vind_dot(2) = u%element(i,j)%vind_s_dot(2) + x%element(i,j)%vind_1(1) = (1._ReKi - p%k_0ye)*u%element(i,j)%vind_s(1) ! Reduced velocity. Eq. (6) from [1] + x%element(i,j)%vind_1(2) = (1._ReKi - p%k_0ye)*u%element(i,j)%vind_s(2) else - x%element(i,j)%vind_1(1) = u%element(i,j)%vind_s(1) + x%element(i,j)%vind_1(1) = u%element(i,j)%vind_s(1) ! Intermediate velocity x%element(i,j)%vind_1(2) = u%element(i,j)%vind_s(2) end if @@ -455,7 +462,7 @@ subroutine ComputeTau1(u, p, m, tau1, errStat, errMsg) temp = (1.0-1.3*AxInd_disk)*Un_disk - tau1 = 1.1*u%R_disk/temp ! Eqn. 1.2 (note that we've eliminated possibility of temp being 0) + tau1 = 1.1*u%R_disk/temp ! Eq. (1) from [1] (note that we've eliminated possibility of temp being 0) tau1 = min(tau1, 100.0_ReKi) ! put a limit on this time constant so it isn't unrealistically long (particularly at initialization) end if @@ -484,8 +491,8 @@ subroutine ComputeTau2(i, j, u, p, tau1, tau2, k_tau_out) spanRatio = u%spanRatio end if - k_tau = 0.39 - 0.26*spanRatio**2 ! Eqn. 1.23b - tau2 = k_tau*tau1 ! Eqn. 1.7 or Eqn 1.23a + k_tau = 0.39 - 0.26*spanRatio**2 + tau2 = k_tau*tau1 ! Eq. (1) from [1] if (present(k_tau_out) ) k_tau_out = k_tau @@ -552,7 +559,8 @@ SUBROUTINE DBEMT_CalcContStateDeriv( i, j, t, u, p, x, OtherState, m, dxdt, ErrS ! LOCAL variables CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_CalcContStateDeriv' - REAL(ReKi) :: tauConst + REAL(ReKi) :: tau1inv + REAL(ReKi) :: tau2inv REAL(ReKi) :: tau1 REAL(ReKi) :: tau2 @@ -567,20 +575,15 @@ SUBROUTINE DBEMT_CalcContStateDeriv( i, j, t, u, p, x, OtherState, m, dxdt, ErrS call SetErrStat(ErrID_Fatal,"Continuous state derivatives cannot be calculated unless DBEMT_Mod is 3.",ErrStat,ErrMsg,RoutineName) return end if - tau1 = p%tau1_const - !call ComputeTau1( u, p, m, tau1, errStat, errMsg) call ComputeTau2(i, j, u, p, tau1, tau2) - - ! Implement Equation 37 from E.Branlard 16-Dec-2019 doc: + tau1inv = 1.0_ReKi/(tau1) + tau2inv = 1.0_ReKi/(tau2) - dxdt%vind = x%vind_dot - - tauConst = -1.0_ReKi/(tau1 * tau2) - - dxdt%vind_dot = tauConst * ( x%vind(:) + (tau1 + tau2)*x%vind_dot(:) & - - u%vind_s(:) - p%k_0ye*tau1*u%vind_s_dot(:) ) - + ! State derivatives, Eq. (7) from [1] + dxdt%vind_1 = -tau1inv * x%vind_1(:) + (1 - p%k_0ye) * tau1inv * u%vind_s(:) + dxdt%vind = tau2inv * x%vind_1(:) - tau2inv * x%vind(:) + p%k_0ye * tau2inv * u%vind_s(:) + END SUBROUTINE DBEMT_CalcContStateDeriv !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine implements the fourth-order Runge-Kutta Method (RK4) for numerically integrating ordinary differential equations: @@ -652,11 +655,11 @@ SUBROUTINE DBEMT_RK4( i, j, t, n, u, utimes, p, x, OtherState, m, ErrStat, ErrMs IF ( ErrStat >= AbortErrLev ) RETURN - k1%vind = p%dt * k1%vind - k1%vind_dot = p%dt * k1%vind_dot + k1%vind = p%dt * k1%vind + k1%vind_1 = p%dt * k1%vind_1 - x_tmp%vind = x%element(i,j)%vind + 0.5 * k1%vind - x_tmp%vind_dot = x%element(i,j)%vind_dot + 0.5 * k1%vind_dot + x_tmp%vind = x%element(i,j)%vind + 0.5 * k1%vind + x_tmp%vind_1 = x%element(i,j)%vind_1 + 0.5 * k1%vind_1 ! interpolate u to find u_interp = u(t + dt/2) TPlusHalfDt = t+0.5_DbKi*p%dt @@ -667,20 +670,20 @@ SUBROUTINE DBEMT_RK4( i, j, t, n, u, utimes, p, x, OtherState, m, ErrStat, ErrMs ! find xdot at t + dt/2 CALL DBEMT_CalcContStateDeriv( i, j, TPlusHalfDt, u_interp, p, x_tmp, OtherState, m, k2, ErrStat2, ErrMsg2 ) - k2%vind = p%dt * k2%vind - k2%vind_dot = p%dt * k2%vind_dot + k2%vind = p%dt * k2%vind + k2%vind_1 = p%dt * k2%vind_1 - x_tmp%vind = x%element(i,j)%vind + 0.5 * k2%vind - x_tmp%vind_dot = x%element(i,j)%vind_dot + 0.5 * k2%vind_dot + x_tmp%vind = x%element(i,j)%vind + 0.5 * k2%vind + x_tmp%vind_1 = x%element(i,j)%vind_1 + 0.5 * k2%vind_1 ! find xdot at t + dt/2 (note x_tmp has changed) CALL DBEMT_CalcContStateDeriv( i, j, TPlusHalfDt, u_interp, p, x_tmp, OtherState, m, k3, ErrStat2, ErrMsg2 ) - k3%vind = p%dt * k3%vind - k3%vind_dot = p%dt * k3%vind_dot + k3%vind = p%dt * k3%vind + k3%vind_1 = p%dt * k3%vind_1 - x_tmp%vind = x%element(i,j)%vind + k3%vind - x_tmp%vind_dot = x%element(i,j)%vind_dot + k3%vind_dot + x_tmp%vind = x%element(i,j)%vind + k3%vind + x_tmp%vind_1 = x%element(i,j)%vind_1 + k3%vind_1 ! interpolate u to find u_interp = u(t + dt) TPlusDt = t + p%dt @@ -691,11 +694,11 @@ SUBROUTINE DBEMT_RK4( i, j, t, n, u, utimes, p, x, OtherState, m, ErrStat, ErrMs ! find xdot at t + dt CALL DBEMT_CalcContStateDeriv( i, j, TPlusDt, u_interp, p, x_tmp, OtherState, m, k4, ErrStat2, ErrMsg2 ) - k4%vind = p%dt * k4%vind - k4%vind_dot = p%dt * k4%vind_dot + k4%vind = p%dt * k4%vind + k4%vind_1 = p%dt * k4%vind_1 - x%element(i,j)%vind = x%element(i,j)%vind + ( k1%vind + 2. * k2%vind + 2. * k3%vind + k4%vind ) / 6. - x%element(i,j)%vind_dot = x%element(i,j)%vind_dot + ( k1%vind_dot + 2. * k2%vind_dot + 2. * k3%vind_dot + k4%vind_dot ) / 6. + x%element(i,j)%vind = x%element(i,j)%vind + ( k1%vind + 2. * k2%vind + 2. * k3%vind + k4%vind ) / 6. + x%element(i,j)%vind_1 = x%element(i,j)%vind_1 + ( k1%vind_1 + 2. * k2%vind_1 + 2. * k3%vind_1 + k4%vind_1 ) / 6. END SUBROUTINE DBEMT_RK4 !---------------------------------------------------------------------------------------------------------------------------------- @@ -779,11 +782,11 @@ SUBROUTINE DBEMT_AB4( i, j, t, n, u, utimes, p, x, OtherState, m, ErrStat, ErrMs else - x%element(i,j)%vind = x%element(i,j)%vind + p%DT/24. * ( 55.*OtherState%xdot(1)%element(i,j)%vind - 59.*OtherState%xdot(2)%element(i,j)%vind & + x%element(i,j)%vind = x%element(i,j)%vind + p%DT/24. * ( 55.*OtherState%xdot(1)%element(i,j)%vind - 59.*OtherState%xdot(2)%element(i,j)%vind & + 37.*OtherState%xdot(3)%element(i,j)%vind - 9.*OtherState%xdot(4)%element(i,j)%vind ) - x%element(i,j)%vind_dot = x%element(i,j)%vind_dot + p%DT/24. * ( 55.*OtherState%xdot(1)%element(i,j)%vind_dot - 59.*OtherState%xdot(2)%element(i,j)%vind_dot & - + 37.*OtherState%xdot(3)%element(i,j)%vind_dot - 9.*OtherState%xdot(4)%element(i,j)%vind_dot ) + x%element(i,j)%vind_1 = x%element(i,j)%vind_1 + p%DT/24. * ( 55.*OtherState%xdot(1)%element(i,j)%vind_1 - 59.*OtherState%xdot(2)%element(i,j)%vind_1 & + + 37.*OtherState%xdot(3)%element(i,j)%vind_1 - 9.*OtherState%xdot(4)%element(i,j)%vind_1 ) endif @@ -861,13 +864,13 @@ SUBROUTINE DBEMT_ABM4( i, j, t, n, u, utimes, p, x, OtherState, m, ErrStat, ErrM IF ( ErrStat >= AbortErrLev ) RETURN - x%element(i,j)%vind = x_in%vind + p%DT/24. * ( 9. * xdot_pred%vind + 19. * OtherState%xdot(1)%element(i,j)%vind & + x%element(i,j)%vind = x_in%vind + p%DT/24. * ( 9. * xdot_pred%vind + 19. * OtherState%xdot(1)%element(i,j)%vind & - 5. * OtherState%xdot(2)%element(i,j)%vind & + 1. * OtherState%xdot(3)%element(i,j)%vind ) - x%element(i,j)%vind_dot = x_in%vind_dot + p%DT/24. * ( 9. * xdot_pred%vind_dot + 19. * OtherState%xdot(1)%element(i,j)%vind_dot & - - 5. * OtherState%xdot(2)%element(i,j)%vind_dot & - + 1. * OtherState%xdot(3)%element(i,j)%vind_dot ) + x%element(i,j)%vind_1 = x_in%vind_1 + p%DT/24. * ( 9. * xdot_pred%vind_1 + 19. * OtherState%xdot(1)%element(i,j)%vind_1 & + - 5. * OtherState%xdot(2)%element(i,j)%vind_1 & + + 1. * OtherState%xdot(3)%element(i,j)%vind_1 ) endif END SUBROUTINE DBEMT_ABM4 @@ -921,4 +924,4 @@ subroutine DBEMT_End( u, p, x, OtherState, m, ErrStat, ErrMsg ) END SUBROUTINE DBEMT_End -end module DBEMT \ No newline at end of file +end module DBEMT diff --git a/modules/aerodyn/src/DBEMT_Registry.txt b/modules/aerodyn/src/DBEMT_Registry.txt index c5fa20f52..21a726a06 100644 --- a/modules/aerodyn/src/DBEMT_Registry.txt +++ b/modules/aerodyn/src/DBEMT_Registry.txt @@ -29,8 +29,7 @@ typedef ^ ^ ReKi rLocal { typedef ^ InitOutputType ProgDesc Ver - - - "This module's name, version, and date" - typedef ^ DBEMT_ElementContinuousStateType R8Ki vind {2} - - "The filtered induced velocity, [1,i,j] is the axial induced velocity (-Vx*a) at node i on blade j and [2,i,j] is the tantential induced velocity (Vy*a')" m/s -typedef ^ DBEMT_ElementContinuousStateType R8Ki vind_dot {2} - - "Time derivative of the filtered induced velocity, x%vind in CCSD" "m/s^2" -typedef ^ DBEMT_ElementContinuousStateType R8Ki vind_1 {2} - - "The filtered intermediate induced velocity" "m/s" +typedef ^ DBEMT_ElementContinuousStateType R8Ki vind_1 {2} - - "The filtered reduced or intermediate induced velocity" "m/s" # ..... States .................................................................................................................... # Define continuous (differentiable) states here: @@ -73,7 +72,6 @@ typedef ^ ParameterType IntKi DBEMT_Mod # ..... Inputs .................................................................................................................... typedef ^ DBEMT_ElementInputType ReKi vind_s {2} - - "The unfiltered induced velocity, [1] is the axial induced velocity (-Vx*a) and [2] is the tangential induced velocity (Vy*a') at node i on blade j. Note that the inputs are used only operated on at a particular node and blade, so we don't store all elements" "m/s" -typedef ^ DBEMT_ElementInputType ReKi vind_s_dot {2} - - "The first time derivative of the unfiltered induced velocity, u%vind_s" "m/s^2" typedef ^ DBEMT_ElementInputType ReKi spanRatio - - - "Normalized span location of blade node" - # Define inputs that are contained on the mesh here: # diff --git a/modules/aerodyn/src/DBEMT_Types.f90 b/modules/aerodyn/src/DBEMT_Types.f90 index 04f0fb3af..423dd42b0 100644 --- a/modules/aerodyn/src/DBEMT_Types.f90 +++ b/modules/aerodyn/src/DBEMT_Types.f90 @@ -54,8 +54,7 @@ MODULE DBEMT_Types ! ========= DBEMT_ElementContinuousStateType ======= TYPE, PUBLIC :: DBEMT_ElementContinuousStateType REAL(R8Ki) , DIMENSION(1:2) :: vind !< The filtered induced velocity, [1,i,j] is the axial induced velocity (-Vx*a) at node i on blade j and [2,i,j] is the tantential induced velocity (Vy*a') [m/s] - REAL(R8Ki) , DIMENSION(1:2) :: vind_dot !< Time derivative of the filtered induced velocity, x%vind in CCSD [m/s^2] - REAL(R8Ki) , DIMENSION(1:2) :: vind_1 !< The filtered intermediate induced velocity [m/s] + REAL(R8Ki) , DIMENSION(1:2) :: vind_1 !< The filtered reduced or intermediate induced velocity [m/s] END TYPE DBEMT_ElementContinuousStateType ! ======================= ! ========= DBEMT_ContinuousStateType ======= @@ -102,7 +101,6 @@ MODULE DBEMT_Types ! ========= DBEMT_ElementInputType ======= TYPE, PUBLIC :: DBEMT_ElementInputType REAL(ReKi) , DIMENSION(1:2) :: vind_s !< The unfiltered induced velocity, [1] is the axial induced velocity (-Vx*a) and [2] is the tangential induced velocity (Vy*a') at node i on blade j. Note that the inputs are used only operated on at a particular node and blade, so we don't store all elements [m/s] - REAL(ReKi) , DIMENSION(1:2) :: vind_s_dot !< The first time derivative of the unfiltered induced velocity, u%vind_s [m/s^2] REAL(ReKi) :: spanRatio !< Normalized span location of blade node [-] END TYPE DBEMT_ElementInputType ! ======================= @@ -157,15 +155,27 @@ SUBROUTINE DBEMT_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Er ENDIF END SUBROUTINE DBEMT_CopyInitInput - SUBROUTINE DBEMT_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE DBEMT_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DBEMT_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%rLocal)) THEN DEALLOCATE(InitInputData%rLocal) ENDIF @@ -353,16 +363,29 @@ SUBROUTINE DBEMT_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE DBEMT_CopyInitOutput - SUBROUTINE DBEMT_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE DBEMT_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DBEMT_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE DBEMT_DestroyInitOutput SUBROUTINE DBEMT_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -559,19 +582,30 @@ SUBROUTINE DBEMT_CopyElementContinuousStateType( SrcElementContinuousStateTypeDa ErrStat = ErrID_None ErrMsg = "" DstElementContinuousStateTypeData%vind = SrcElementContinuousStateTypeData%vind - DstElementContinuousStateTypeData%vind_dot = SrcElementContinuousStateTypeData%vind_dot DstElementContinuousStateTypeData%vind_1 = SrcElementContinuousStateTypeData%vind_1 END SUBROUTINE DBEMT_CopyElementContinuousStateType - SUBROUTINE DBEMT_DestroyElementContinuousStateType( ElementContinuousStateTypeData, ErrStat, ErrMsg ) + SUBROUTINE DBEMT_DestroyElementContinuousStateType( ElementContinuousStateTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DBEMT_ElementContinuousStateType), INTENT(INOUT) :: ElementContinuousStateTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyElementContinuousStateType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyElementContinuousStateType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE DBEMT_DestroyElementContinuousStateType SUBROUTINE DBEMT_PackElementContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -610,7 +644,6 @@ SUBROUTINE DBEMT_PackElementContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Ind Db_BufSz = 0 Int_BufSz = 0 Db_BufSz = Db_BufSz + SIZE(InData%vind) ! vind - Db_BufSz = Db_BufSz + SIZE(InData%vind_dot) ! vind_dot Db_BufSz = Db_BufSz + SIZE(InData%vind_1) ! vind_1 IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -643,10 +676,6 @@ SUBROUTINE DBEMT_PackElementContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Ind DbKiBuf(Db_Xferred) = InData%vind(i1) Db_Xferred = Db_Xferred + 1 END DO - DO i1 = LBOUND(InData%vind_dot,1), UBOUND(InData%vind_dot,1) - DbKiBuf(Db_Xferred) = InData%vind_dot(i1) - Db_Xferred = Db_Xferred + 1 - END DO DO i1 = LBOUND(InData%vind_1,1), UBOUND(InData%vind_1,1) DbKiBuf(Db_Xferred) = InData%vind_1(i1) Db_Xferred = Db_Xferred + 1 @@ -686,12 +715,6 @@ SUBROUTINE DBEMT_UnPackElementContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, O OutData%vind(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) Db_Xferred = Db_Xferred + 1 END DO - i1_l = LBOUND(OutData%vind_dot,1) - i1_u = UBOUND(OutData%vind_dot,1) - DO i1 = LBOUND(OutData%vind_dot,1), UBOUND(OutData%vind_dot,1) - OutData%vind_dot(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - END DO i1_l = LBOUND(OutData%vind_1,1) i1_u = UBOUND(OutData%vind_1,1) DO i1 = LBOUND(OutData%vind_1,1), UBOUND(OutData%vind_1,1) @@ -738,19 +761,32 @@ SUBROUTINE DBEMT_CopyContState( SrcContStateData, DstContStateData, CtrlCode, Er ENDIF END SUBROUTINE DBEMT_CopyContState - SUBROUTINE DBEMT_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE DBEMT_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DBEMT_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%element)) THEN DO i2 = LBOUND(ContStateData%element,2), UBOUND(ContStateData%element,2) DO i1 = LBOUND(ContStateData%element,1), UBOUND(ContStateData%element,1) - CALL DBEMT_Destroyelementcontinuousstatetype( ContStateData%element(i1,i2), ErrStat, ErrMsg ) + CALL DBEMT_Destroyelementcontinuousstatetype( ContStateData%element(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(ContStateData%element) @@ -1001,15 +1037,27 @@ SUBROUTINE DBEMT_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, Er DstDiscStateData%DummyState = SrcDiscStateData%DummyState END SUBROUTINE DBEMT_CopyDiscState - SUBROUTINE DBEMT_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE DBEMT_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DBEMT_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE DBEMT_DestroyDiscState SUBROUTINE DBEMT_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1126,15 +1174,27 @@ SUBROUTINE DBEMT_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCo DstConstrStateData%DummyState = SrcConstrStateData%DummyState END SUBROUTINE DBEMT_CopyConstrState - SUBROUTINE DBEMT_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE DBEMT_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DBEMT_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE DBEMT_DestroyConstrState SUBROUTINE DBEMT_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1287,15 +1347,27 @@ SUBROUTINE DBEMT_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ENDDO END SUBROUTINE DBEMT_CopyOtherState - SUBROUTINE DBEMT_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE DBEMT_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DBEMT_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OtherStateData%areStatesInitialized)) THEN DEALLOCATE(OtherStateData%areStatesInitialized) ENDIF @@ -1303,7 +1375,8 @@ SUBROUTINE DBEMT_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) DEALLOCATE(OtherStateData%n) ENDIF DO i1 = LBOUND(OtherStateData%xdot,1), UBOUND(OtherStateData%xdot,1) - CALL DBEMT_DestroyContState( OtherStateData%xdot(i1), ErrStat, ErrMsg ) + CALL DBEMT_DestroyContState( OtherStateData%xdot(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO END SUBROUTINE DBEMT_DestroyOtherState @@ -1618,15 +1691,27 @@ SUBROUTINE DBEMT_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%FirstWarn_tau1 = SrcMiscData%FirstWarn_tau1 END SUBROUTINE DBEMT_CopyMisc - SUBROUTINE DBEMT_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE DBEMT_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DBEMT_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE DBEMT_DestroyMisc SUBROUTINE DBEMT_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1765,15 +1850,27 @@ SUBROUTINE DBEMT_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMs DstParamData%DBEMT_Mod = SrcParamData%DBEMT_Mod END SUBROUTINE DBEMT_CopyParam - SUBROUTINE DBEMT_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE DBEMT_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DBEMT_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%spanRatio)) THEN DEALLOCATE(ParamData%spanRatio) ENDIF @@ -1972,19 +2069,30 @@ SUBROUTINE DBEMT_CopyElementInputType( SrcElementInputTypeData, DstElementInputT ErrStat = ErrID_None ErrMsg = "" DstElementInputTypeData%vind_s = SrcElementInputTypeData%vind_s - DstElementInputTypeData%vind_s_dot = SrcElementInputTypeData%vind_s_dot DstElementInputTypeData%spanRatio = SrcElementInputTypeData%spanRatio END SUBROUTINE DBEMT_CopyElementInputType - SUBROUTINE DBEMT_DestroyElementInputType( ElementInputTypeData, ErrStat, ErrMsg ) + SUBROUTINE DBEMT_DestroyElementInputType( ElementInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DBEMT_ElementInputType), INTENT(INOUT) :: ElementInputTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyElementInputType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyElementInputType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE DBEMT_DestroyElementInputType SUBROUTINE DBEMT_PackElementInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2023,7 +2131,6 @@ SUBROUTINE DBEMT_PackElementInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt Db_BufSz = 0 Int_BufSz = 0 Re_BufSz = Re_BufSz + SIZE(InData%vind_s) ! vind_s - Re_BufSz = Re_BufSz + SIZE(InData%vind_s_dot) ! vind_s_dot Re_BufSz = Re_BufSz + 1 ! spanRatio IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -2056,10 +2163,6 @@ SUBROUTINE DBEMT_PackElementInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSt ReKiBuf(Re_Xferred) = InData%vind_s(i1) Re_Xferred = Re_Xferred + 1 END DO - DO i1 = LBOUND(InData%vind_s_dot,1), UBOUND(InData%vind_s_dot,1) - ReKiBuf(Re_Xferred) = InData%vind_s_dot(i1) - Re_Xferred = Re_Xferred + 1 - END DO ReKiBuf(Re_Xferred) = InData%spanRatio Re_Xferred = Re_Xferred + 1 END SUBROUTINE DBEMT_PackElementInputType @@ -2097,12 +2200,6 @@ SUBROUTINE DBEMT_UnPackElementInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Er OutData%vind_s(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO - i1_l = LBOUND(OutData%vind_s_dot,1) - i1_u = UBOUND(OutData%vind_s_dot,1) - DO i1 = LBOUND(OutData%vind_s_dot,1), UBOUND(OutData%vind_s_dot,1) - OutData%vind_s_dot(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO OutData%spanRatio = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END SUBROUTINE DBEMT_UnPackElementInputType @@ -2148,19 +2245,32 @@ SUBROUTINE DBEMT_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMs ENDIF END SUBROUTINE DBEMT_CopyInput - SUBROUTINE DBEMT_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE DBEMT_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DBEMT_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%element)) THEN DO i2 = LBOUND(InputData%element,2), UBOUND(InputData%element,2) DO i1 = LBOUND(InputData%element,1), UBOUND(InputData%element,1) - CALL DBEMT_Destroyelementinputtype( InputData%element(i1,i2), ErrStat, ErrMsg ) + CALL DBEMT_Destroyelementinputtype( InputData%element(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(InputData%element) @@ -2444,15 +2554,27 @@ SUBROUTINE DBEMT_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Er ENDIF END SUBROUTINE DBEMT_CopyOutput - SUBROUTINE DBEMT_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE DBEMT_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DBEMT_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DBEMT_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%vind)) THEN DEALLOCATE(OutputData%vind) ENDIF @@ -2710,10 +2832,6 @@ SUBROUTINE DBEMT_ElementInputType_ExtrapInterp1(u1, u2, tin, u_out, tin_out, Err b = -(u1%vind_s(i1) - u2%vind_s(i1)) u_out%vind_s(i1) = u1%vind_s(i1) + b * ScaleFactor END DO - DO i1 = LBOUND(u_out%vind_s_dot,1),UBOUND(u_out%vind_s_dot,1) - b = -(u1%vind_s_dot(i1) - u2%vind_s_dot(i1)) - u_out%vind_s_dot(i1) = u1%vind_s_dot(i1) + b * ScaleFactor - END DO b = -(u1%spanRatio - u2%spanRatio) u_out%spanRatio = u1%spanRatio + b * ScaleFactor END SUBROUTINE DBEMT_ElementInputType_ExtrapInterp1 @@ -2778,11 +2896,6 @@ SUBROUTINE DBEMT_ElementInputType_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, c = ( (t(2)-t(3))*u1%vind_s(i1) + t(3)*u2%vind_s(i1) - t(2)*u3%vind_s(i1) ) * scaleFactor u_out%vind_s(i1) = u1%vind_s(i1) + b + c * t_out END DO - DO i1 = LBOUND(u_out%vind_s_dot,1),UBOUND(u_out%vind_s_dot,1) - b = (t(3)**2*(u1%vind_s_dot(i1) - u2%vind_s_dot(i1)) + t(2)**2*(-u1%vind_s_dot(i1) + u3%vind_s_dot(i1)))* scaleFactor - c = ( (t(2)-t(3))*u1%vind_s_dot(i1) + t(3)*u2%vind_s_dot(i1) - t(2)*u3%vind_s_dot(i1) ) * scaleFactor - u_out%vind_s_dot(i1) = u1%vind_s_dot(i1) + b + c * t_out - END DO b = (t(3)**2*(u1%spanRatio - u2%spanRatio) + t(2)**2*(-u1%spanRatio + u3%spanRatio))* scaleFactor c = ( (t(2)-t(3))*u1%spanRatio + t(3)*u2%spanRatio - t(2)*u3%spanRatio ) * scaleFactor u_out%spanRatio = u1%spanRatio + b + c * t_out @@ -2902,14 +3015,6 @@ SUBROUTINE DBEMT_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMs ENDDO DO i02 = LBOUND(u_out%element,2),UBOUND(u_out%element,2) DO i01 = LBOUND(u_out%element,1),UBOUND(u_out%element,1) - DO i1 = LBOUND(u_out%element(i01,i02)%vind_s_dot,1),UBOUND(u_out%element(i01,i02)%vind_s_dot,1) - b = -(u1%element(i01,i02)%vind_s_dot(i1) - u2%element(i01,i02)%vind_s_dot(i1)) - u_out%element(i01,i02)%vind_s_dot(i1) = u1%element(i01,i02)%vind_s_dot(i1) + b * ScaleFactor - END DO - ENDDO - ENDDO - DO i02 = LBOUND(u_out%element,2),UBOUND(u_out%element,2) - DO i01 = LBOUND(u_out%element,1),UBOUND(u_out%element,1) b = -(u1%element(i01,i02)%spanRatio - u2%element(i01,i02)%spanRatio) u_out%element(i01,i02)%spanRatio = u1%element(i01,i02)%spanRatio + b * ScaleFactor ENDDO @@ -2995,15 +3100,6 @@ SUBROUTINE DBEMT_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, E ENDDO DO i02 = LBOUND(u_out%element,2),UBOUND(u_out%element,2) DO i01 = LBOUND(u_out%element,1),UBOUND(u_out%element,1) - DO i1 = LBOUND(u_out%element(i01,i02)%vind_s_dot,1),UBOUND(u_out%element(i01,i02)%vind_s_dot,1) - b = (t(3)**2*(u1%element(i01,i02)%vind_s_dot(i1) - u2%element(i01,i02)%vind_s_dot(i1)) + t(2)**2*(-u1%element(i01,i02)%vind_s_dot(i1) + u3%element(i01,i02)%vind_s_dot(i1)))* scaleFactor - c = ( (t(2)-t(3))*u1%element(i01,i02)%vind_s_dot(i1) + t(3)*u2%element(i01,i02)%vind_s_dot(i1) - t(2)*u3%element(i01,i02)%vind_s_dot(i1) ) * scaleFactor - u_out%element(i01,i02)%vind_s_dot(i1) = u1%element(i01,i02)%vind_s_dot(i1) + b + c * t_out - END DO - ENDDO - ENDDO - DO i02 = LBOUND(u_out%element,2),UBOUND(u_out%element,2) - DO i01 = LBOUND(u_out%element,1),UBOUND(u_out%element,1) b = (t(3)**2*(u1%element(i01,i02)%spanRatio - u2%element(i01,i02)%spanRatio) + t(2)**2*(-u1%element(i01,i02)%spanRatio + u3%element(i01,i02)%spanRatio))* scaleFactor c = ( (t(2)-t(3))*u1%element(i01,i02)%spanRatio + t(3)*u2%element(i01,i02)%spanRatio - t(2)*u3%element(i01,i02)%spanRatio ) * scaleFactor u_out%element(i01,i02)%spanRatio = u1%element(i01,i02)%spanRatio + b + c * t_out diff --git a/modules/aerodyn/src/FVW.f90 b/modules/aerodyn/src/FVW.f90 index 1e0b97173..616d96ffc 100644 --- a/modules/aerodyn/src/FVW.f90 +++ b/modules/aerodyn/src/FVW.f90 @@ -14,6 +14,7 @@ module FVW use FVW_IO use FVW_Wings use FVW_BiotSavart + use FVW_VortexTools, only: tic, toc use FVW_Tests use AirFoilInfo @@ -67,7 +68,6 @@ subroutine FVW_Init(AFInfo, InitInp, u, p, x, xd, z, OtherState, y, m, Interval, character(*), parameter :: RoutineName = 'FVW_Init' type(FVW_InputFile) :: InputFileData !< Data stored in the module's input file character(len=1054) :: DirName - integer :: iW ! Initialize variables for this routine ErrStat = ErrID_None @@ -83,16 +83,6 @@ subroutine FVW_Init(AFInfo, InitInp, u, p, x, xd, z, OtherState, y, m, Interval, call getcwd(DirName) call WrScr(' - Directory: '//trim(DirName)) call WrScr(' - RootName: '//trim(InitInp%RootName)) -#ifdef _OPENMP - call WrScr(' - Compiled with OpenMP') - !$OMP PARALLEL default(shared) - if (omp_get_thread_num()==0) then - call WrScr(' Number of threads: '//trim(Num2LStr(omp_get_num_threads()))//'/'//trim(Num2LStr(omp_get_max_threads()))) - endif - !$OMP END PARALLEL -#else - call WrScr(' - No OpenMP support') -#endif if (DEV_VERSION) then CALL FVW_RunTests(ErrStat2, ErrMsg2); if (Failed()) return endif @@ -106,6 +96,7 @@ subroutine FVW_Init(AFInfo, InitInp, u, p, x, xd, z, OtherState, y, m, Interval, ! Trigger required before allocations p%nNWMax = max(InputFileData%nNWPanels,0)+1 ! +1 since LL panel included in NW p%nFWMax = max(InputFileData%nFWPanels,0) + p%nNWFree = max(InputFileData%nNWPanelsFree,0)+1 ! +1 since LL panel included in NW p%nFWFree = max(InputFileData%nFWPanelsFree,0) p%DTfvw = InputFileData%DTfvw p%DTvtk = InputFileData%DTvtk @@ -122,10 +113,10 @@ subroutine FVW_Init(AFInfo, InitInp, u, p, x, xd, z, OtherState, y, m, Interval, CALL MOVE_ALLOC( InitInp%WingsMesh, u%WingsMesh ) ! Move from InitInp to u ! This mesh is passed in as a cousin of the BladeMotion mesh. - CALL Wings_Panelling_Init(u%WingsMesh, p, m, ErrStat2, ErrMsg2); if(Failed()) return + CALL Wings_Panelling_Init(u%WingsMesh, p, ErrStat2, ErrMsg2); if(Failed()) return ! Set parameters from InputFileData (need Misc allocated) - CALL FVW_SetParametersFromInputFile(InputFileData, p, m, ErrStat2, ErrMsg2); if(Failed()) return + CALL FVW_SetParametersFromInputFile(InputFileData, p, ErrStat2, ErrMsg2); if(Failed()) return ! Initialize Misc Vars (after input file params) CALL FVW_InitMiscVarsPostParam( p, m, ErrStat2, ErrMsg2 ); if(Failed()) return @@ -140,7 +131,6 @@ subroutine FVW_Init(AFInfo, InitInp, u, p, x, xd, z, OtherState, y, m, Interval, ! This mesh is now a cousin of the BladeMotion mesh from AD. CALL Wings_Panelling (u%WingsMesh, p, m, ErrStat2, ErrMsg2); if(Failed()) return CALL FVW_InitRegularization(x, p, m, ErrStat2, ErrMsg2); if(Failed()) return - CALL FVW_ToString(p, m) ! Print to screen ! Mapping NW and FW (purely for esthetics, and maybe wind) ! TODO, just points call Map_LL_NW(p, m, z, x, 1.0_ReKi, ErrStat2, ErrMsg2); if(Failed()) return @@ -159,9 +149,9 @@ subroutine FVW_Init(AFInfo, InitInp, u, p, x, xd, z, OtherState, y, m, Interval, call UA_Init_Wrapper(AFInfo, InitInp, interval, p, x, xd, OtherState, m, ErrStat2, ErrMsg2); if (Failed()) return ! Framework types unused - OtherState%NULL = 0 - xd%NULL = 0 - InitOut%NULL = 0 + OtherState%Dummy = 0 + xd%Dummy = 0 + InitOut%Dummy = 0 CONTAINS logical function Failed() @@ -192,7 +182,7 @@ subroutine FVW_InitMiscVars( p, m, ErrStat, ErrMsg ) m%nNW = p%iNWStart-1 ! Number of active nearwake panels m%nFW = 0 ! Number of active farwake panels m%iStep = 0 ! Current step number - m%VTKStep = -1 ! Counter of VTK outputs + m%VTKstep = -1 ! Counter of VTK outputs m%VTKlastTime = -HUGE(1.0_DbKi) m%OldWakeTime = -HUGE(1.0_DbKi) @@ -240,6 +230,7 @@ subroutine FVW_InitMiscVars( p, m, ErrStat, ErrMsg ) call AllocAry( m%W(iW)%BN_Cl_Static , p%W(iW)%nSpan+1 , 'Coefficient lift - no UA', ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName ); m%W(iW)%BN_Cl_Static = -999999_ReKi; call AllocAry( m%W(iW)%BN_Cd_Static , p%W(iW)%nSpan+1 , 'Coefficient drag - no UA', ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName ); m%W(iW)%BN_Cd_Static = -999999_ReKi; call AllocAry( m%W(iW)%BN_Cm_Static , p%W(iW)%nSpan+1 , 'Coefficient moment - no UA', ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName ); m%W(iW)%BN_Cm_Static = -999999_ReKi; + call AllocAry( m%W(iW)%BN_Cpmin , p%W(iW)%nSpan+1 , 'Coefficient minimum pressure - no UA', ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName ); m%W(iW)%BN_Cpmin = -999999_ReKi; call AllocAry( m%W(iW)%BN_Cl , p%W(iW)%nSpan+1 , 'Coefficient lift - with UA', ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName ); m%W(iW)%BN_Cl = -999999_ReKi; call AllocAry( m%W(iW)%BN_Cd , p%W(iW)%nSpan+1 , 'Coefficient drag - with UA', ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName ); m%W(iW)%BN_Cd = -999999_ReKi; call AllocAry( m%W(iW)%BN_Cm , p%W(iW)%nSpan+1 , 'Coefficient moment - with UA', ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName ); m%W(iW)%BN_Cm = -999999_ReKi; @@ -281,73 +272,6 @@ subroutine FVW_InitMiscVars( p, m, ErrStat, ErrMsg ) end subroutine FVW_InitMiscVars ! ============================================================================== -subroutine FVW_InitMiscVarsPostParam( p, m, ErrStat, ErrMsg ) - type(FVW_ParameterType), intent(in ) :: p !< Parameters - type(FVW_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 - integer(IntKi) :: ErrStat2 ! temporary error status of the operation - character(ErrMsgLen) :: ErrMsg2 ! temporary error message - character(*), parameter :: RoutineName = 'FVW_InitMiscVarsPostParam' - integer(IntKi) :: nSeg, nSegP, nSegNW !< Total number of segments after packing - integer(IntKi) :: nCPs !< Total number of control points - logical :: bMirror - ErrStat = ErrID_None - ErrMsg = "" - ! --- Counting maximum number of segments and Control Points expected for the whole simulation - call CountSegments(p, p%nNWMax, p%nFWMax, 1, nSeg, nSegP, nSegNW) - nCPs = CountCPs(p, p%nNWMax, p%nFWFree) - - bMirror = p%ShearModel==idShearMirror ! Whether or not we mirror the vorticity wrt ground - if (bMirror) then - nSeg = nSeg*2 - nSegP = nSegP*2 - endif - call AllocAry( m%Sgmt%Connct, 4, nSeg , 'SegConnct' , ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%Sgmt%Connct = -999; - call AllocAry( m%Sgmt%Points, 3, nSegP, 'SegPoints' , ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%Sgmt%Points = -999999_ReKi; - call AllocAry( m%Sgmt%Gamma , nSeg, 'SegGamma' , ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%Sgmt%Gamma = -999999_ReKi; - call AllocAry( m%Sgmt%Epsilon, nSeg, 'SegEpsilon', ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%Sgmt%Epsilon= -999999_ReKi; - m%Sgmt%nAct = -1 ! Active segments - m%Sgmt%nActP = -1 - m%Sgmt%RegFunction = p%RegFunction - - call AllocAry( m%CPs , 3, nCPs, 'CPs' , ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%CPs= -999999_ReKi; - call AllocAry( m%Uind , 3, nCPs, 'Uind' , ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%Uind= -999999_ReKi; - -end subroutine FVW_InitMiscVarsPostParam -! ============================================================================== -subroutine FVW_InitStates( x, p, ErrStat, ErrMsg ) - type(FVW_ContinuousStateType), intent( out) :: x !< States - type(FVW_ParameterType), intent(in ) :: p !< Parameters - integer(IntKi), intent( out) :: ErrStat !< Error status of the operation - character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None - integer(IntKi) :: ErrStat2 ! temporary error status of the operation - character(ErrMsgLen) :: ErrMsg2 ! temporary error message - character(*), parameter :: RoutineName = 'FVW_InitMiscVars' - integer :: iW - ! Initialize ErrStat - ErrStat = ErrID_None - ErrMsg = "" - - allocate(x%W(p%nWings)) - do iW=1,p%nWings - call AllocAry( x%W(iW)%Gamma_NW, p%W(iW)%nSpan , p%nNWMax , 'NW Panels Circulation', ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,'FVW_InitStates' ); - call AllocAry( x%W(iW)%Gamma_FW, FWnSpan , p%nFWMax , 'FW Panels Circulation', ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,'FVW_InitStates' ); - call AllocAry( x%W(iW)%Eps_NW , 3, p%W(iW)%nSpan , p%nNWMax , 'NW Panels Reg Param' , ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,'FVW_InitStates' ); - call AllocAry( x%W(iW)%Eps_FW , 3, FWnSpan , p%nFWMax , 'FW Panels Reg Param' , ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,'FVW_InitStates' ); - ! set x%W(iW)%r_NW and x%W(iW)%r_FW to (0,0,0) so that InflowWind can shortcut the calculations - call AllocAry( x%W(iW)%r_NW , 3, p%W(iW)%nSpan+1 , p%nNWMax+1, 'NW Panels Points' , ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,'FVW_InitStates' ); - call AllocAry( x%W(iW)%r_FW , 3, FWnSpan+1 , p%nFWMax+1, 'FW Panels Points' , ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,'FVW_InitStates' ); - if (ErrStat >= AbortErrLev) return - x%W(iW)%r_NW = 0.0_ReKi - x%W(iW)%r_FW = 0.0_ReKi - x%W(iW)%Gamma_NW = 0.0_ReKi ! First call of calcoutput, states might not be set - x%W(iW)%Gamma_FW = 0.0_ReKi ! NOTE, these values might be mapped from z%W(iW)%Gamma_LL at init - x%W(iW)%Eps_NW = 0.001_ReKi - x%W(iW)%Eps_FW = 0.001_ReKi - enddo -end subroutine FVW_InitStates -! ============================================================================== subroutine FVW_InitConstraint( z, p, m, ErrStat, ErrMsg ) type(FVW_ConstraintStateType), intent( out) :: z !< Constraints type(FVW_ParameterType), intent(in ) :: p !< Parameters @@ -381,7 +305,7 @@ subroutine FVW_Init_U_Y( p, u, y, m, ErrStat, ErrMsg ) type(FVW_OutputType), intent( out) :: y !< Constraints integer(IntKi), intent( out) :: ErrStat !< Error status of the operation character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None - integer(IntKi) :: nMax ! Total number of wind points possible + integer(IntKi) :: ErrStat2 ! temporary error status of the operation character(ErrMsgLen) :: ErrMsg2 ! temporary error message character(*), parameter :: RoutineName = 'FVW_Init_U_Y' @@ -410,14 +334,26 @@ subroutine FVW_Init_U_Y( p, u, y, m, ErrStat, ErrMsg ) end subroutine FVW_Init_U_Y ! ============================================================================== !> Setting parameters *and misc* from module inputs -SUBROUTINE FVW_SetParametersFromInputs( InitInp, p, ErrStat, ErrMsg ) +subroutine FVW_SetRootName(RootName, p) + character(*) , intent(in ) :: RootName !< Input data for initialization routine (inout so we can use MOVE_ALLOC) + type(FVW_ParameterType), intent(inout) :: p !< Parameters + ! Local variables + character(1024) :: rootDir, baseName ! Simulation root dir and basename + p%RootName = RootName ! Rootname for outputs + call GetPath( p%RootName, rootDir, baseName ) + p%VTK_OutFileRoot = trim(rootDir) // 'vtk_fvw' ! Directory for VTK outputs + p%VTK_OutFileBase = trim(rootDir) // 'vtk_fvw' // PathSep // trim(baseName) ! Basename for VTK files +end subroutine FVW_SetRootName +! ============================================================================== +!> Setting parameters *and misc* from module inputs +subroutine FVW_SetParametersFromInputs( InitInp, p, ErrStat, ErrMsg ) type(FVW_InitInputType), intent(inout) :: InitInp !< Input data for initialization routine (inout so we can use MOVE_ALLOC) type(FVW_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 character(1024) :: rootDir, baseName ! Simulation root dir and basename - integer(IntKi) :: iW, nRotors, nBldMax + integer(IntKi) :: iW, nBldMax integer(IntKi), allocatable :: nBldPerRot(:) integer(IntKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 @@ -428,10 +364,10 @@ SUBROUTINE FVW_SetParametersFromInputs( InitInp, p, ErrStat, ErrMsg ) p%nWings = size(InitInp%WingsMesh) p%DTaero = InitInp%DTaero ! AeroDyn Time step p%KinVisc = InitInp%KinVisc ! Kinematic air viscosity - p%RootName = InitInp%RootName ! Rootname for outputs - call GetPath( p%RootName, rootDir, baseName ) - p%VTK_OutFileRoot = trim(rootDir) // 'vtk_fvw' ! Directory for VTK outputs - p%VTK_OutFileBase = trim(rootDir) // 'vtk_fvw' // PathSep // trim(baseName) ! Basename for VTK files + p%MHK = InitInp%MHK ! MHK flag + p%WtrDpth = InitInp%WtrDpth ! Water depth + call FVW_SetRootName(InitInp%RootName, p) + ! Set indexing to AFI tables -- this is set from the AD15 calling code. ! Set the Chord values @@ -470,13 +406,14 @@ SUBROUTINE FVW_SetParametersFromInputs( InitInp, p, ErrStat, ErrMsg ) p%Bld2Wings(p%W(iW)%iRotor, nBldPerRot(p%W(iW)%iRotor)) = iW enddo + if (allocated(nBldPerRot)) deallocate(nBldPerRot) + end subroutine FVW_SetParametersFromInputs ! ============================================================================== !> -SUBROUTINE FVW_SetParametersFromInputFile( InputFileData, p, m, ErrStat, ErrMsg ) +SUBROUTINE FVW_SetParametersFromInputFile( InputFileData, p, ErrStat, ErrMsg ) type(FVW_InputFile), intent(in ) :: InputFileData !< Data stored in the module's input file type(FVW_ParameterType), intent(inout) :: p !< Parameters - type(FVW_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 @@ -488,13 +425,13 @@ SUBROUTINE FVW_SetParametersFromInputFile( InputFileData, p, m, ErrStat, ErrMsg ! Set parameters from input file p%IntMethod = InputFileData%IntMethod - p%CirculationMethod = InputFileData%CirculationMethod + p%CircSolvMethod = InputFileData%CircSolvMethod p%CircSolvConvCrit = InputFileData%CircSolvConvCrit p%CircSolvRelaxation = InputFileData%CircSolvRelaxation p%CircSolvMaxIter = InputFileData%CircSolvMaxIter p%FreeWakeStart = InputFileData%FreeWakeStart p%CircSolvPolar = InputFileData%CircSolvPolar - p%FullCirculationStart = InputFileData%FullCirculationStart + p%FullCircStart = InputFileData%FullCircStart p%FWShedVorticity = InputFileData%FWShedVorticity p%DiffusionMethod = InputFileData%DiffusionMethod p%RegFunction = InputFileData%RegFunction @@ -514,7 +451,7 @@ SUBROUTINE FVW_SetParametersFromInputFile( InputFileData, p, m, ErrStat, ErrMsg do iW=1,p%nWings if (allocated(p%W(iW)%PrescribedCirculation)) deallocate(p%W(iW)%PrescribedCirculation) - if (InputFileData%CirculationMethod==idCircPrescribed) then + if (InputFileData%CircSolvMethod==idCircPrescribed) then call AllocAry(p%W(iW)%PrescribedCirculation, p%W(iW)%nSpan, 'Prescribed Circulation', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,'FVW_SetParameters'); p%W(iW)%PrescribedCirculation = -999999_ReKi; if (.not. allocated(p%W(iW)%s_CP)) then @@ -528,18 +465,36 @@ SUBROUTINE FVW_SetParametersFromInputFile( InputFileData, p, m, ErrStat, ErrMsg enddo end subroutine FVW_SetParametersFromInputFile - -subroutine FVW_ToString(p,m) - type(FVW_ParameterType), intent(in) :: p !< Parameters - type(FVW_MiscVarType), intent(inout) :: m !< Misc - if (DEV_VERSION) then - print*,'-----------------------------------------------------------------------------------------' - if(.false.) print*,m%nNW ! unused var for now - endif -end subroutine FVW_ToString - !---------------------------------------------------------------------------------------------------------------------------------- !> This routine is called at the end of the simulation. +subroutine FVW_FinalWrite(u, p, x, z, m, ErrStat, ErrMsg) + type(FVW_InputType), intent(in ) :: u !< System inputs + type(FVW_ParameterType), intent(in ) :: p !< Parameters + type(FVW_ContinuousStateType), intent(in ) :: x !< Continuous states + type(FVW_ConstraintStateType), intent(in ) :: z !< Constraint states + type(FVW_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(DbKi) :: t + integer, parameter :: FINAL_STEP = 999999999 + ErrStat = ErrID_None + ErrMsg = "" + ! Place any last minute operations or calculations here: + if (p%WrVTK>0 .and. m%VTKstep>> FINAL WRITE' + t=-1.0_ReKi + if (p%WrVTK==1) then + if (m%VTKstep This routine is called at the end of the simulation. NOTE: we don't store errstat subroutine FVW_End( u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) type(FVW_InputType),allocatable, intent(inout) :: u(:) !< System inputs @@ -552,22 +507,11 @@ subroutine FVW_End( u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) type(FVW_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) :: i - real(DbKi) :: t - - ! Initialize ErrStat + integer :: i ErrStat = ErrID_None ErrMsg = "" - ! Place any last minute operations or calculations here: - if (p%WrVTK==2) then - call WrScr('Outputs of VTK before FVW_END') - t=-1.0_ReKi - m%VTKStep=999999999 ! not pretty, but we know we have twidth=9 - call WriteVTKOutputs(t, .true., u(1), p, x, z, y, m, ErrStat, ErrMsg) - endif - - ! Close files here: + ! Final trigger + call FVW_FinalWrite(u(1), p, x, z, m, ErrStat, ErrMsg) ! Destroy the input data: if (allocated(u)) then @@ -615,10 +559,11 @@ subroutine FVW_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, AFInfo, m integer(IntKi) :: ErrStat2 ! temporary Error status character(ErrMsgLen) :: ErrMsg2 ! temporary Error message type(FVW_ConstraintStateType) :: z_guess ! < - integer(IntKi) :: nP, nFWEff, iW + integer(IntKi) :: nP, nFWEff, nNWEff, iW real(ReKi) :: ShedScale !< Scaling factor for shed vorticity (for sub-cycling), 1 if no subcycling logical :: bReevaluation logical :: bOverCycling + if (OLAF_PROFILING) call tic('FVW_UpdateStates') ErrStat = ErrID_None ErrMsg = "" @@ -639,7 +584,7 @@ subroutine FVW_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, AFInfo, m m%ComputeWakeInduced = .FALSE. endif if (bReevaluation) then - print*,'[INFO] FVW: Update States: reevaluation at the same starting time' + call WrScr('[INFO] FVW: Update States: reevaluation at the same starting time') call RollBackPreviousTimeStep() ! Cancel wake emission done in previous call m%ComputeWakeInduced = .TRUE. endif @@ -648,9 +593,10 @@ subroutine FVW_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, AFInfo, m do iW=1,p%nWings nP = np + ( (p%W(iW)%nSpan+1)*(m%nNW-1+2) +(FWnSpan+1)*(m%nFW+1) ) enddo + nNWEff = min(m%nNW, p%nNWFree) nFWEff = min(m%nFW, p%nFWFree) ! --- Display some status to screen - if (DEV_VERSION) print'(A,F10.3,A,I0,A,I0,A,I0,A,I0,A,I0,A,I0,A,I0,A,I0,A,L1)','FVW status - t:',t,' n:',n,' nNW:',m%nNW-1,'/',p%nNWMax-1,' nFW:',nFWEff, '+',m%nFW-nFWEff,'=',m%nFW,'/',p%nFWMax,' nP:',nP, 's Comp:',m%ComputeWakeInduced + if (DEV_VERSION) print'(A,F10.3,A,I0,A,I0,A,I0,A,I0,A,I0,A,I0,A,I0,A,I0,A,I0,A,L1)','FVW status - t:',t,' n:',n,' nNW:',m%nNW-1,'-',nNWEff-1,'/',p%nNWMax-1,' nFW:',nFWEff, '+',m%nFW-nFWEff,'=',m%nFW,'/',p%nFWMax,' nP:',nP, 's Comp:',m%ComputeWakeInduced ! --- Evaluation at t ! Inputs at t @@ -662,7 +608,7 @@ subroutine FVW_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, AFInfo, m ! Compute UA inputs at t if (m%UA_Flag) then - call CalculateInputsAndOtherStatesForUA(1, uInterp, p, x, xd, z, OtherState, AFInfo, m, ErrStat2, ErrMsg2); if(Failed()) return + call CalculateInputsAndOtherStatesForUA(1, uInterp, p, x, xd, z, m, ErrStat2, ErrMsg2); if(Failed()) return end if ! --- Integration between t and t+DTfvw @@ -680,7 +626,7 @@ subroutine FVW_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, AFInfo, m if (p%IntMethod .eq. idEuler1) then call FVW_Euler1( t, uInterp, p, x, xd, z, OtherState, m, ErrStat2, ErrMsg2); if(Failed()) return elseif (p%IntMethod .eq. idRK4) then - call FVW_RK4( t, n, u, utimes, p, x, xd, z, OtherState, m, ErrStat2, ErrMsg2); if(Failed()) return + call FVW_RK4( t, u, utimes, p, x, xd, z, OtherState, m, ErrStat2, ErrMsg2); if(Failed()) return !elseif (p%IntMethod .eq. idAB4) then ! call FVW_AB4( t, n, u, utimes, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ) !elseif (p%IntMethod .eq. idABM4) then @@ -719,7 +665,7 @@ subroutine FVW_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, AFInfo, m !call FVW_CalcConstrStateResidual(t+p%DTfvw, uInterp, p, m%x2, xd, z_guess, OtherState, m, z, AFInfo, ErrStat2, ErrMsg2, 2); if(Failed()) return !! Compute UA inputs at t+DTfvw and integrate UA states between t and t+dtAero !if (m%UA_Flag) then - ! call CalculateInputsAndOtherStatesForUA(2, uInterp, p, m%x2, xd, z, OtherState, AFInfo, m, ErrStat2, ErrMsg2); if(Failed()) return + ! call CalculateInputsAndOtherStatesForUA(2, uInterp, p, m%x2, xd, z, OtherState, m, ErrStat2, ErrMsg2); if(Failed()) return ! call UA_UpdateState_Wrapper(AFInfo, t, n, (/t,t+p%DTfvw/), p, m%x2, xd, OtherState, m, ErrStat2, ErrMsg2); if(Failed()) return !end if !! Updating circulation of near wake panel (and position but irrelevant) @@ -731,7 +677,7 @@ subroutine FVW_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, AFInfo, m ! --- Integration between t and t+DTaero if DTaero/=DTfvw if (bOverCycling) then ! Linear interpolation of states between t and dtaero - call FVW_ContStates_Interp(t+p%DTaero, (/m%x1, m%x2/), (/m%t1, m%t2/), p, m, x, ErrStat2, ErrMsg2); if(Failed()) return + call FVW_ContStates_Interp(t+p%DTaero, (/m%x1, m%x2/), (/m%t1, m%t2/), p, x, ErrStat2, ErrMsg2); if(Failed()) return endif ! Inputs at t+DTaero (Wings Panelling updates CP, and VstW(iW)%r_LL) @@ -746,22 +692,24 @@ subroutine FVW_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, AFInfo, m !call print_x_NW_FW(p, m, x,'Map2') ! --- Solve for quasi steady circulation at t+p%DTaero + if (OLAF_PROFILING) call tic('Circulation Solving') ! Returns: z%W(iW)%Gamma_LL (at t+p%DTaero) allocate(z_guess%W(p%nWings)) do iW=1,p%nWings z_guess%W(iW)%Gamma_LL = z%W(iW)%Gamma_LL ! We use as guess the circulation from the previous time step (see above) enddo call FVW_CalcConstrStateResidual(t+p%DTaero, uInterp, p, x, xd, z_guess, OtherState, m, z, AFInfo, ErrStat2, ErrMsg2, 2); if(Failed()) return + if (OLAF_PROFILING) call toc() ! Updating circulation of near wake panel (need to be set for UA, Uind on LL) (and position but irrelevant) ! Changes: x only call Map_LL_NW(p, m, z, x, ShedScale, ErrStat2, ErrMsg2); if(Failed()) return call Map_NW_FW(p, m, z, x, ErrStat2, ErrMsg2); if(Failed()) return ! Compute UA inputs at t+DTaero and integrate UA states between t and t+dtAero if (m%UA_Flag) then - call CalculateInputsAndOtherStatesForUA(2, uInterp, p, x, xd, z, OtherState, AFInfo, m, ErrStat2, ErrMsg2); if(Failed()) return + call CalculateInputsAndOtherStatesForUA(2, uInterp, p, x, xd, z, m, ErrStat2, ErrMsg2); if(Failed()) return call UA_UpdateState_Wrapper(AFInfo, t, n, (/t,t+p%DTaero/), p, x, xd, OtherState, m, ErrStat2, ErrMsg2); if(Failed()) return ! Compute unsteady Gamma based on UA Cl - if (p%DStallOnWake .and. p%CirculationMethod/=idCircPrescribed) then + if (p%DStallOnWake .and. p%CircSolvMethod/=idCircPrescribed) then call UA_SetGammaDyn(t, uInterp, p, x, xd, OtherState, m, AFInfo, z, ErrStat, ErrMsg) ! Updating circulation of near wake panel again (and position but irrelevant) ! Changes: x only @@ -784,11 +732,12 @@ subroutine FVW_UpdateStates( t, n, u, utimes, p, x, xd, z, OtherState, AFInfo, m call CleanUp() if (DEV_VERSION) then - if(have_nan(p, m, x, u, 'End Update ')) then + if(have_nan(p, m, x, z, u, 'End Update ')) then STOP endif endif + if (OLAF_PROFILING) call toc() contains subroutine PrepareNextTimeStep() ! --- Increase wake length if maximum not reached @@ -838,10 +787,14 @@ subroutine FVW_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, ErrSt integer(IntKi) :: ErrStat2 ! temporary error status of the operation character(ErrMsgLen) :: ErrMsg2 ! temporary error message integer(IntKi) :: nFWEff ! Number of farwake panels that are free at current time step - integer(IntKi) :: i,j,k,iW,nP - real(ReKi) :: visc_fact, age ! Viscosity factor for diffusion of reg param - real(ReKi), dimension(3) :: VmeanFW, VmeanNW ! Mean velocity of the near wake and far wake - + integer(IntKi) :: nNWEff ! Number of nearwake panels that are free at current time step + integer(IntKi) :: nNWEffEnd ! End the number of free nearwake panels + integer(IntKi) :: j,k,iW,nP + real(ReKi) :: visc_fact ! Viscosity factor for diffusion of reg param + real(ReKi) :: UiScale ! Scale induced velocity from full to 0 in frozen wake + real(ReKi), dimension(3) :: VmeanFWFree, VmeanNW, VmeanNWFree ! Mean velocity of the near wake and far wake + real(ReKi), dimension(3) :: VmeanNWFixed + integer(IntKi), parameter :: nNWFreeAvg=20 ! Number of parameters used to compute velocity for frozen wake ErrStat = ErrID_None ErrMsg = "" @@ -863,7 +816,9 @@ subroutine FVW_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, ErrSt ! Only calculate freewake after start time and if on a timestep when it should be calculated. if ((t>= p%FreeWakeStart)) then + nNWEff = min(m%nNW, p%nNWFree) nFWEff = min(m%nFW, p%nFWFree) + nNWEffEnd = max(nNWEff-nNWFreeAvg, 2) ! start for frozen convection average ! --- Compute Induced velocities on the Near wake and far wake based on the marker postions: ! (expensive N^2 call) @@ -871,7 +826,31 @@ subroutine FVW_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, ErrSt ! Out: m%W(iW)%Vind_NW, m%Vind_FW call WakeInducedVelocities(p, x, m, ErrStat2, ErrMsg2); if(Failed()) return - ! --- Mean induced velocity over the near wake (NW) TODO, store per wing + ! --- Mean induced velocity over end of the free near wake (NW) + VmeanNWFree(1:3)=0 + if (nNWEff >0) then + nP=0; + do iW=1,size(m%W); do j=nNWEffEnd,nNWEff+1; do k=1,size(m%W(iW)%Vind_NW,2); + VmeanNWFree(1:3) = VmeanNWFree(1:3) + m%W(iW)%Vind_NW(1:3, k, j) + nP=nP+1; + enddo; enddo; enddo; + VmeanNWFree(1:3) = VmeanNWFree(1:3) / nP + endif + ! --- Convecting non-free NW based on an average (decaying) induced velocity (and free stream) + do iW=1,p%nWings + do j=p%nNWFree+2,p%nNWMax+1 + ! Scale so that induced velocity scale goes from s=kFrozenNWStart to e=kFrozenNWEnd in frozen Wake + ! Uiscale = [ (e-s)*j + b*s - a*e ]/(b-a) b=(p%nNWMax+1) , a=(p%nNWFree+2) + UiScale = ( (p%kFrozenNWEnd-p%kFrozenNWStart)*j + (p%nNWMax+1)*p%kFrozenNWStart - (p%nNWFree+2)*p%kFrozenNWEnd)/(p%nNWMax+1-(p%nNWFree+2)) + do k=1,size(m%W(iW)%Vind_NW,2); + m%W(iW)%Vind_NW(1, k, j) = VmeanNWFree(1)*UiScale ! + m%W(iW)%Vind_NW(2, k, j) = VmeanNWFree(2)*UiScale ! + m%W(iW)%Vind_NW(3, k, j) = VmeanNWFree(3)*UiScale ! + enddo + enddo + enddo + + ! --- Mean induced velocity over the full near wake (NW) TODO, store per wing VmeanNW(1:3)=0 if (m%nNW >1) then nP=0; @@ -881,39 +860,59 @@ subroutine FVW_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, ErrSt enddo; enddo; enddo; VmeanNW(1:3) = VmeanNW(1:3) / nP endif - ! --- Induced velocity over the free far wake (FWEff) - VmeanFW(1:3)=0 + + ! --- Mean induced velocity over the fixed near wake (NW) TODO REMOVE FOR DEBUG ONLY + VmeanNWFixed(1:3)=0 + nP=0; + do iW=1,size(m%W); do j=p%nNWFree+2,p%nNWMax+1; do k=1,size(m%W(iW)%Vind_NW,2); + VmeanNWFixed(1:3) = VmeanNWFixed(1:3) + m%W(iW)%Vind_NW(1:3, k, j) + nP=nP+1; + enddo; enddo; enddo; + VmeanNWFixed(1:3) = VmeanNWFixed(1:3) / nP + + ! --- Mean induced velocity over the free far wake (FWEff) + VmeanFWFree(1:3)=0 if (nFWEff >0) then nP=0 do iW=1,size(m%W); do j=1,nFWEff; do k=1,size(m%W(iW)%Vind_FW,2); - VmeanFW(1:3) = VmeanFW(1:3) + m%W(iW)%Vind_FW(1:3, k, j) + VmeanFWFree(1:3) = VmeanFWFree(1:3) + m%W(iW)%Vind_FW(1:3, k, j) nP=nP+1; enddo; enddo; enddo; - VmeanFW(1:3) = VmeanFW(1:3) / nP + VmeanFWFree(1:3) = VmeanFWFree(1:3) / nP else - VmeanFW=VmeanNW + if (p%nNWMax==p%nNWFree) then ! No frozen near wake + VmeanFWFree=VmeanNW + else ! a frozen near wake is present, frozen far wake we convect at same end velocity as end of frozen near wake + VmeanFWFree=VmeanNWFree*p%kFrozenNWEnd + endif ! Since we convect the first FW point, we need a reasonable velocity there ! NOTE: mostly needed for sub-cycling and when no FW do iW=1,p%nWings - m%W(iW)%Vind_FW(1, 1:FWnSpan+1, 1) = VmeanFW(1) - m%W(iW)%Vind_FW(2, 1:FWnSpan+1, 1) = VmeanFW(2) - m%W(iW)%Vind_FW(3, 1:FWnSpan+1, 1) = VmeanFW(3) + m%W(iW)%Vind_FW(1, 1:FWnSpan+1, 1) = VmeanFWFree(1) + m%W(iW)%Vind_FW(2, 1:FWnSpan+1, 1) = VmeanFWFree(2) + m%W(iW)%Vind_FW(3, 1:FWnSpan+1, 1) = VmeanFWFree(3) enddo endif ! --- Convecting non-free FW with a constant induced velocity (and free stream) do iW=1,p%nWings - m%W(iW)%Vind_FW(1, 1:FWnSpan+1, p%nFWFree+1:p%nFWMax+1) = VmeanFW(1) ! - m%W(iW)%Vind_FW(2, 1:FWnSpan+1, p%nFWFree+1:p%nFWMax+1) = VmeanFW(2) ! - m%W(iW)%Vind_FW(3, 1:FWnSpan+1, p%nFWFree+1:p%nFWMax+1) = VmeanFW(3) ! + m%W(iW)%Vind_FW(1, 1:FWnSpan+1, p%nFWFree+1:p%nFWMax+1) = VmeanFWFree(1) ! + m%W(iW)%Vind_FW(2, 1:FWnSpan+1, p%nFWFree+1:p%nFWMax+1) = VmeanFWFree(2) ! + m%W(iW)%Vind_FW(3, 1:FWnSpan+1, p%nFWFree+1:p%nFWMax+1) = VmeanFWFree(3) ! enddo if (DEV_VERSION) then - !call print_mean_4d( m%W(iW)%Vind_NW(:,:, 1:m%nNW+1,:), 'Mean induced vel. NW') - !if (nFWEff>0) then - ! call print_mean_4d( m%W(iW)%Vind_FW(:,:, 1:nFWEff ,:), 'Mean induced vel. FW') - !endif - !print'(A25,3F12.4)','MeanFW (non free)',VmeanFW + do iW=1,p%nWings + call print_mean_3d( m%W(iW)%Vind_NW(:,:, 1:m%nNW+1), 'Mean induced vel. NW') + if (nFWEff>0) then + call print_mean_3d( m%W(iW)%Vind_FW(:,:, 1:nFWEff), 'Mean induced vel. FW') + endif + enddo + print'(A25,3F12.4)','MeanNW (all) ',VmeanNW + print'(A25,3F12.4)','MeanNW (all2) ',(VmeanNWFree+VmeanNWFixed)/2 + print'(A25,3F12.4)','MeanNW (free) ',VmeanNWFree + print'(A25,3F12.4)','MeanNW (fixed) ',VmeanNWFixed + print'(A25,3F12.4)','MeanFW (non free)',VmeanFWFree !call print_mean_4d( m%Vwnd_NW(:,:, 1:m%nNW+1,:), 'Mean wind vel. NW') !call print_mean_4d( m%Vwnd_FW(:,:, 1:nFWEff+1,:), 'Mean wind vel. FWEff') !call print_mean_4d( m%Vwnd_FW(:,:, (p%nFWFree+1):m%nFW+1,:), 'Mean wind vel. FWNF') @@ -979,6 +978,10 @@ subroutine FVW_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, ErrSt dxdt%W(iW)%Eps_NW(1:3,:,1:p%iNWStart) = 0.0_ReKi ! Important! LL and First NW panel epsilon does not change enddo + if(.false.) print*,OtherState%Dummy ! unused var + if(.false.) print*,u%W(1)%omega_z(1) ! unused var + if(.false.) print*,xd%Dummy + if(.false.) print*,z%W(1)%Gamma_LL(1) contains logical function Failed() call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'FVW_CalcContStateDeriv') @@ -987,14 +990,14 @@ end function Failed end subroutine FVW_CalcContStateDeriv +!------------------------------------------------------------------------------------------------ !> Interpolate states to the current time !! For now: linear interpolation, two states, with t1 Routine for computing outputs, used in both loose and tight coupling. -subroutine FVW_CalcOutput(t, u, p, x, xd, z, OtherState, AFInfo, y, m, ErrStat, ErrMsg) - use FVW_VTK, only: set_vtk_coordinate_transform +subroutine FVW_CalcOutput(t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg) + use VTK, only: set_vtk_coordinate_transform use FVW_VortexTools, only: interpextrap_cp2node real(DbKi), intent(in ) :: t !< Current simulation time in seconds type(FVW_InputType), intent(in ) :: u !< Inputs at Time t @@ -1410,18 +1416,19 @@ subroutine FVW_CalcOutput(t, u, p, x, xd, z, OtherState, AFInfo, y, m, ErrStat, type(FVW_DiscreteStateType), intent(in ) :: xd !< Discrete states at t type(FVW_ConstraintStateType), intent(in ) :: z !< Constraint states at t type(FVW_OtherStateType), intent(in ) :: OtherState !< Other states at t - type(AFI_ParameterType), intent(in ) :: AFInfo(:) !< The airfoil parameter data type(FVW_OutputType), intent(inout) :: y !< Outputs computed at t (Input only so that mesh con- !! nectivity information does not have to be recalculated) type(FVW_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) :: nP integer(IntKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 character(*), parameter :: RoutineName = 'FVW_CalcOutput' logical :: bOverCycling - real(ReKi) :: fact + if (OLAF_PROFILING) call tic('FVW_CalcOutput') + ErrStat = ErrID_None ErrMsg = "" if (DEV_VERSION) then @@ -1432,29 +1439,51 @@ subroutine FVW_CalcOutput(t, u, p, x, xd, z, OtherState, AFInfo, y, m, ErrStat, bOverCycling = p%DTfvw > p%DTaero ! Compute induced velocity at AD nodes - call CalcOutputForAD(t,u,p,x,y,m,AFInfo, ErrStat2, ErrMsg2) + call CalcOutputForAD(u,p,x,y,m, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + ! Write some info to screen when major milestone achieved + if (m%iStep == p%nNWFree .and. p%nNWFree0 .and. m%iStep== p%nNWMax+p%nFWMax) then + nP = CountCPs(p, p%nNWMax, p%nFWMax) + call WrScr(NewLine//'[INFO] OLAF wake is at full extent - '//trim(num2lstr(t))//'s, '//trim(num2lstr(nP))//' points.') + endif ! Export to VTK - if (m%VTKStep==-1) then - m%VTKStep = 0 ! Has never been called, special handling for init + if (m%VTKstep==-1) then + ! Has never been called, special handling for init + call WriteVTKOutputs(t, .False., 0 , u, p, x, z, m, ErrStat2, ErrMsg2) else - m%VTKStep = m%iStep+1 ! We use glue code step number for outputs + call WriteVTKOutputs(t, .False., m%iStep+1, u, p, x, z, m, ErrStat2, ErrMsg2) endif - call WriteVTKOutputs(t, .False., u, p, x, z, y, m, ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (OLAF_PROFILING) call toc() + if(.false.) print*,OtherState%Dummy !unused var + if(.false.) print*,xd%Dummy end subroutine FVW_CalcOutput +!------------------------------------------------------------------------------------------------ !> Write to vtk_fvw folder at fps requested -subroutine WriteVTKOutputs(t, force, u, p, x, z, y, m, ErrStat, ErrMsg) +subroutine WriteVTKOutputs(t, force, VTKstep, u, p, x, z, m, ErrStat, ErrMsg) real(DbKi), intent(in ) :: t !< Current simulation time in seconds logical, intent(in ) :: force !< force the writing + integer, intent(in ) :: VTKstep !< step index used to write the filenames type(FVW_InputType), intent(in ) :: u !< Inputs at Time t type(FVW_ParameterType), intent(in ) :: p !< Parameters type(FVW_ContinuousStateType), intent(in ) :: x !< Continuous states at t type(FVW_ConstraintStateType), intent(in ) :: z !< Constraint states at t - type(FVW_OutputType), intent(in ) :: y !< Outputs computed at t (Input only so that mesh con- type(FVW_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 @@ -1489,13 +1518,14 @@ subroutine WriteVTKOutputs(t, force, u, p, x, z, y, m, ErrStat, ErrMsg) call SetErrStat(ErrID_Warn, ErrMsg2, ErrStat, ErrMsg, RoutineName) endif ! We ouput in first rotor frame - call WrVTK_FVW(p, x, z, m, trim(p%VTK_OutFileBase)//'FVW_Hub', m%VTKStep, 9, bladeFrame=.TRUE., & + call WrVTK_FVW(p, x, z, m, trim(p%VTK_OutFileBase)//'FVW_Hub', VTKstep, 9, bladeFrame=.TRUE., & HubOrientation=real(u%rotors(1)%HubOrientation,ReKi),HubPosition=real(u%rotors(1)%HubPosition,ReKi)) endif if ((p%VTKCoord==1).or.(p%VTKCoord==3)) then ! Global coordinate system, ALL VTK will be exported in global - call WrVTK_FVW(p, x, z, m, trim(p%VTK_OutFileBase)//'FVW_Glb', m%VTKStep, 9, bladeFrame=.FALSE.) + call WrVTK_FVW(p, x, z, m, trim(p%VTK_OutFileBase)//'FVW_Glb', VTKstep, 9, bladeFrame=.FALSE.) endif + m%VTKstep=VTKstep ! We save the step at which writing occured endif endif ! --- Write VTK grids @@ -1514,7 +1544,8 @@ subroutine WriteVTKOutputs(t, force, u, p, x, z, y, m, ErrStat, ErrMsg) call InducedVelocitiesAll_OnGrid(m%GridOutputs(iGrid), p, x, m, ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) m%GridOutputs(iGrid)%tLastOutput = t - call WrVTK_FVW_Grid(p, x, z, m, iGrid, trim(p%VTK_OutFileBase)//'FVW_Grid', m%VTKStep, 9) + call WrVTK_FVW_Grid(p, m, iGrid, trim(p%VTK_OutFileBase)//'FVW_Grid', VTKstep, 9) + m%VTKstep=VTKstep ! We save the step at which writing occured endif enddo endif @@ -1584,8 +1615,8 @@ subroutine UA_Init_Wrapper(AFInfo, InitInp, interval, p, x, xd, OtherState, m, E enddo ! --- FVW specific - if (p%CirculationMethod/=idCircPolarData) then - ErrMsg2='Unsteady aerodynamic (`AFAeroMod>1`) is only available with a circulation solving using profile data (`CircSolvingMethod=1`)'; ErrStat2=ErrID_Fatal; + if (p%CircSolvMethod/=idCircPolarData) then + ErrMsg2='Unsteady aerodynamic (`AFAeroMod>1`) is only available with a circulation solving using profile data (`CircSolvMethod=1`)'; ErrStat2=ErrID_Fatal; call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'UA_Init_Wrapper'); return endif endif @@ -1596,21 +1627,21 @@ logical function Failed() end function Failed end subroutine UA_Init_Wrapper +!------------------------------------------------------------------------------------------------ !> Compute necessary inputs for UA at a given time step, stored in m%u_UA !! Inputs are AoA, U, Re, !! See equivalent version in BEMT, and SetInputs_for_UA in BEMT -subroutine CalculateInputsAndOtherStatesForUA(InputIndex, u, p, x, xd, z, OtherState, AFInfo, m, ErrStat, ErrMsg) +subroutine CalculateInputsAndOtherStatesForUA(InputIndex, u, p, x, xd, z, m, ErrStat, ErrMsg) integer(IntKi), intent(in ) :: InputIndex ! InputIndex= 1 or 2, depending on time step we are calculating inputs for type(FVW_InputType), intent(in ) :: u ! Input type(FVW_ParameterType), intent(in ) :: p ! Parameters type(FVW_ContinuousStateType), intent(in ) :: x ! Continuous states at given time step type(FVW_DiscreteStateType), intent(in ) :: xd ! Discrete states at given time step type(FVW_ConstraintStateType), intent(in ) :: z ! Constraint states at given time step - type(FVW_OtherStateType), intent(inout) :: OtherState ! Other states at given time step + !type(FVW_OtherStateType), intent(inout) :: OtherState ! Other states at given time step type(FVW_MiscVarType), target, intent(inout) :: m ! Misc/optimization variables - type(AFI_ParameterType), intent(in ) :: AFInfo(:) ! The airfoil parameter data - 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 type(UA_InputType), pointer :: u_UA ! Alias to shorten notations integer(IntKi) :: i,iW @@ -1653,9 +1684,11 @@ subroutine CalculateInputsAndOtherStatesForUA(InputIndex, u, p, x, xd, z, OtherS u_UA%UserProp = 0 ! u1%UserProp(i,j) ! TODO end do ! i nSpan end do ! iW nWings + if(.false.) print*,xd%Dummy + if(.false.) print*,z%W(1)%Gamma_LL(1) end subroutine CalculateInputsAndOtherStatesForUA - +!------------------------------------------------------------------------------------------------ subroutine UA_UpdateState_Wrapper(AFInfo, t, n, uTimes, p, x, xd, OtherState, m, ErrStat, ErrMsg ) use FVW_VortexTools, only: interpextrap_cp2node use UnsteadyAero, only: UA_UpdateStates @@ -1701,7 +1734,7 @@ function NodeText(i,j) NodeText = '(nd:'//trim(num2lstr(i))//' bld:'//trim(num2lstr(j))//')' end function NodeText end subroutine UA_UpdateState_Wrapper - +!------------------------------------------------------------------------------------------------ !> Set dynamic gamma based on dynamic stall states !! NOTE: We use Vind_LL computed in CalculateInputsAndOtherStatesForUA subroutine UA_SetGammaDyn(t, u, p, x, xd, OtherState, m, AFInfo, z, ErrStat, ErrMsg) @@ -1717,7 +1750,6 @@ subroutine UA_SetGammaDyn(t, u, p, x, xd, OtherState, m, AFInfo, z, ErrStat, Err type(FVW_ConstraintStateType), intent(inout) :: z !< Constraint states integer(IntKi), intent( out) :: ErrStat !< Error status of the operation character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None - real(ReKi) :: Cl_dyn, Cl_dyn_prev, Cl_dyn_avg real(ReKi) :: Gamma_dyn, Gamma_dyn_prev, Gamma_dyn_avg type(UA_InputType), pointer :: u_UA ! Alias to shorten notations integer(IntKi), parameter :: InputIndex=2 ! we will always use values at t+dt in this routine @@ -1744,6 +1776,7 @@ subroutine UA_SetGammaDyn(t, u, p, x, xd, OtherState, m, AFInfo, z, ErrStat, Err z%W(iW)%Gamma_LL(j-1) = Gamma_dyn_avg enddo enddo ! iW, Loop on wings + if(.false.) print*,u%W(1)%omega_z(1) ! unused var end subroutine UA_SetGammaDyn end module FVW diff --git a/modules/aerodyn/src/FVW_BiotSavart.f90 b/modules/aerodyn/src/FVW_BiotSavart.f90 index ec5dcc24b..99dc7d0ac 100644 --- a/modules/aerodyn/src/FVW_BiotSavart.f90 +++ b/modules/aerodyn/src/FVW_BiotSavart.f90 @@ -88,6 +88,8 @@ subroutine ui_seg_11(DeltaPa, DeltaPb, SegGamma, RegFunction, RegParam1, Uind) Kv = 1.0_ReKi denominator=denominator+RegParam1**2*norm2_r0 case default + print*,'Unknown SgmtReg', RegFunction + STOP ! Will never happen Kv=1.0_ReKi !< Should be an error end select Kv=SegGamma*fourpi_inv*Kv*(norm_a+norm_b)/denominator @@ -103,7 +105,7 @@ end subroutine ui_seg_11 !! The function can compute the velocity on part of the segments and part of the control points. !! This feature is useful if some parallelization is used, while common storage vectors are used. subroutine ui_seg(iCPStart, iCPEnd, CPs, & - iSegStart, iSegEnd, nSegTot, nSegPTot, SegPoints, SegConnct, SegGamma, & + iSegStart, iSegEnd, SegPoints, SegConnct, SegGamma, & RegFunction, RegParam, Uind_out) real(ReKi), dimension(:,:), intent(in) :: CPs !< Control points (3 x nCPs++) integer(IntKi), intent(in) :: iCPStart !< Index where we start in Control points array @@ -113,8 +115,6 @@ subroutine ui_seg(iCPStart, iCPEnd, CPs, & real(ReKi), dimension(:), intent(in) :: SegGamma !< Segment circulation (nSegTot) integer(IntKi), intent(in) :: iSegStart !< Index in SegConnct, and SegGamma where we start integer(IntKi), intent(in) :: iSegEnd !< Index in SegConnct, and SegGamma where we end - integer(IntKi), intent(in) :: nSegTot !< Total number of segments - integer(IntKi), intent(in) :: nSegPTot !< Total number of segment points integer(IntKi), intent(in) :: RegFunction !< Regularization model real(ReKi), dimension(:), intent(in) :: RegParam !< Regularization parameter (nSegTot) real(ReKi), dimension(:,:) , intent(inout) :: Uind_out !< Induced velocity vector - Side effects!!! (3 x nCPs++) @@ -323,15 +323,15 @@ subroutine ui_seg(iCPStart, iCPEnd, CPs, & end subroutine ui_seg !> Induced velocity from `nPart` particles at `nCPs` control points. The velocity gradient is not computed -subroutine ui_part_nograd(CPs, Part, Alpha, RegFunction, RegParam, UIout, nCPs, nPart) - integer(IntKi), intent(in) :: nCPs - integer(IntKi), intent(in) :: nPart - real(ReKi), dimension(:,:), intent(in) :: CPs !< Control points (3 x nCPs) - real(ReKi), dimension(:,:), intent(inout) :: UIout !< Induced velocity, with side effects! (3 x nCPs) - real(ReKi), dimension(:,:), intent(in) :: Part !< Particle positions (3 x nPart) - real(ReKi), dimension(:,:), intent(in) :: Alpha !< Particle intensity [m^3/s] (3 x nPart) omega dV= alpha +subroutine ui_part_nograd(nCPS, CPs, nPart, Part, Alpha, RegFunction, RegParam, UIout) + integer(IntKi), intent(in) :: nCPs !< Number of control points to use (nCPs<=size(CPs,2)) + integer(IntKi), intent(in) :: nPart !< Number of particles to use (nPart<=size(Part,2)) + real(ReKi), dimension(:,:), intent(in) :: CPs !< Control points (3 x nCPs+) + real(ReKi), dimension(:,:), intent(inout) :: UIout !< Induced velocity, with side effects! (3 x nCPs+) + real(ReKi), dimension(:,:), intent(in) :: Part !< Particle positions (3 x nPart+) + real(ReKi), dimension(:,:), intent(in) :: Alpha !< Particle intensity [m^3/s] (3 x nPart+) omega dV= alpha integer(IntKi), intent(in) :: RegFunction !< Regularization function - real(ReKi), dimension(:), intent(in) :: RegParam !< Regularization parameter (nPart) + real(ReKi), dimension(:), intent(in) :: RegParam !< Regularization parameter (nPart+) real(ReKi), dimension(3) :: UItmp !< real(ReKi), dimension(3) :: DP !< integer :: icp,ip diff --git a/modules/aerodyn/src/FVW_IO.f90 b/modules/aerodyn/src/FVW_IO.f90 index c0a173ece..1efc58adf 100644 --- a/modules/aerodyn/src/FVW_IO.f90 +++ b/modules/aerodyn/src/FVW_IO.f90 @@ -18,7 +18,7 @@ SUBROUTINE FVW_ReadInputFile( FileName, p, m, Inp, ErrStat, ErrMsg ) character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None ! Local variables character(1024) :: PriPath ! the path to the primary input file - character(1024) :: sDummy, sLine, Key, Val ! string to temporarially hold value of read line + character(1024) :: sDummy, sLine ! string to temporarially hold value of read line integer(IntKi) :: UnIn, i integer(IntKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 @@ -37,20 +37,21 @@ SUBROUTINE FVW_ReadInputFile( FileName, p, m, Inp, ErrStat, ErrMsg ) CALL ReadVarWDefault(UnIn,FileName,Inp%IntMethod ,'Integration method' ,'', idEuler1 , ErrStat2,ErrMsg2); if(Failed())return CALL ReadVarWDefault(UnIn,FileName,Inp%DTfvw ,'DTfvw' ,'', p%DTaero , ErrStat2,ErrMsg2); if(Failed())return CALL ReadVarWDefault(UnIn,FileName,Inp%FreeWakeStart ,'FreeWakeStart' ,'', 0.0_ReKi , ErrStat2,ErrMsg2); if(Failed())return - CALL ReadVarWDefault(UnIn,FileName,Inp%FullCirculationStart,'FullCirculationStart','', real(20.0_ReKi*Inp%DTfvw,ReKi), ErrStat2,ErrMsg2); if(Failed())return + CALL ReadVarWDefault(UnIn,FileName,Inp%FullCircStart ,'FullCircStart' ,'', 0.0_ReKi , ErrStat2,ErrMsg2); if(Failed())return !------------------------ CIRCULATION SPECIFICATIONS ------------------------------------------- CALL ReadCom(UnIn,FileName, '--- Circulation specification header' , ErrStat2, ErrMsg2 ); if(Failed()) return - CALL ReadVarWDefault(UnIn,FileName,Inp%CirculationMethod ,'CirculationMethod' ,'', idCircPolarData, ErrStat2,ErrMsg2); if(Failed())return + CALL ReadVarWDefault(UnIn,FileName,Inp%CircSolvMethod ,'CircSolvMethod' ,'', idCircPolarData, ErrStat2,ErrMsg2); if(Failed())return CALL ReadVarWDefault(UnIn,FileName,Inp%CircSolvConvCrit ,'CircSolvConvCrit ' ,'', 0.001 , ErrStat2,ErrMsg2); if(Failed())return CALL ReadVarWDefault(UnIn,FileName,Inp%CircSolvRelaxation,'CircSolvRelaxation','', 0.1 , ErrStat2,ErrMsg2); if(Failed())return CALL ReadVarWDefault(UnIn,FileName,Inp%CircSolvMaxIter ,'CircSolvMaxIter' ,'', 30 , ErrStat2,ErrMsg2); if(Failed())return - CALL ReadVar(UnIn,FileName,Inp%CirculationFile ,'CirculationFile' ,'',ErrStat2,ErrMsg2); if(Failed())return + CALL ReadVar (UnIn,FileName,Inp%CirculationFile ,'CirculationFile' ,'' , ErrStat2,ErrMsg2); if(Failed())return !------------------------ WAKE OPTIONS ------------------------------------------- CALL ReadCom (UnIn,FileName, '=== Separator' , ErrStat2,ErrMsg2); if(Failed()) return CALL ReadCom (UnIn,FileName, '--- Wake options header' , ErrStat2,ErrMsg2); if(Failed()) return CALL ReadCom (UnIn,FileName, '--- Wake extent header' , ErrStat2,ErrMsg2); if(Failed()) return CALL ReadVar (UnIn,FileName,Inp%nNWPanels ,'nNWPanels' ,'' , ErrStat2,ErrMsg2); if(Failed())return - CALL ReadVar (UnIn,FileName,Inp%nFWPanels ,'nFWPanels' ,'' , ErrStat2,ErrMsg2); if(Failed())return + CALL ReadVarWDefault(UnIn,FileName,Inp%nNWPanelsFree ,'nNWPanelsFree' ,'', Inp%nNWPanels , ErrStat2,ErrMsg2); if(Failed())return + CALL ReadVarWDefault(UnIn,FileName,Inp%nFWPanels ,'nFWPanels' ,'', 0 , ErrStat2,ErrMsg2); if(Failed())return CALL ReadVarWDefault(UnIn,FileName,Inp%nFWPanelsFree ,'nFWPanelsFree' ,'', Inp%nFWPanels , ErrStat2,ErrMsg2); if(Failed())return CALL ReadVarWDefault(UnIn,FileName,Inp%FWShedVorticity ,'FWShedVorticity' ,'', .False. , ErrStat2,ErrMsg2); if(Failed())return @@ -58,7 +59,7 @@ SUBROUTINE FVW_ReadInputFile( FileName, p, m, Inp, ErrStat, ErrMsg ) CALL ReadVarWDefault(UnIn,FileName,Inp%DiffusionMethod ,'DiffusionMethod' ,'',idDiffusionNone , ErrStat2,ErrMsg2); if(Failed())return CALL ReadVarWDefault(UnIn,FileName,Inp%RegDeterMethod ,'RegDeterMethod' ,'',idRegDeterConstant, ErrStat2,ErrMsg2); if(Failed())return CALL ReadVarWDefault(UnIn,FileName,Inp%RegFunction ,'RegFunction' ,'',idRegVatistas , ErrStat2,ErrMsg2); if(Failed())return - CALL ReadVarWDefault(UnIn,FileName,Inp%WakeRegMethod ,'WakeRegMethod' ,'',idRegConstant , ErrStat2,ErrMsg2); if(Failed())return + CALL ReadVarWDefault(UnIn,FileName,Inp%WakeRegMethod ,'WakeRegMethod' ,'',idRegAge , ErrStat2,ErrMsg2); if(Failed())return CALL ReadVar (UnIn,FileName,Inp%WakeRegParam ,'WakeRegParam' ,'' , ErrStat2,ErrMsg2); if(Failed())return CALL ReadVar (UnIn,FileName,Inp%WingRegParam ,'WingRegParam' ,'' , ErrStat2,ErrMsg2); if(Failed())return CALL ReadVarWDefault(UnIn,FileName,Inp%CoreSpreadEddyVisc ,'CoreSpreadEddyVisc','',100.0_ReKi , ErrStat2,ErrMsg2); if(Failed())return @@ -68,21 +69,27 @@ SUBROUTINE FVW_ReadInputFile( FileName, p, m, Inp, ErrStat, ErrMsg ) CALL ReadVarWDefault(UnIn,FileName,Inp%ShearModel ,'ShearModel' ,'',idShearNone , ErrStat2,ErrMsg2); if(Failed())return CALL ReadCom (UnIn,FileName, '--- Speed up header ' , ErrStat2,ErrMsg2); if(Failed()) return - CALL ReadVarWDefault(UnIn,FileName,Inp%VelocityMethod ,'VelocityMethod' ,'',idVelocityBasic , ErrStat2,ErrMsg2); if(Failed())return - CALL ReadVarWDefault(UnIn,FileName,Inp%TreeBranchFactor ,'TreeBranchFactor' ,'',2.0_ReKi , ErrStat2,ErrMsg2); if(Failed())return - CALL ReadVarWDefault(UnIn,FileName,Inp%PartPerSegment ,'PartPerSegment' ,'', 1 , ErrStat2,ErrMsg2); if(Failed())return -! Inp%TwrShadowOnWake = .False. -! Inp%VelocityMethod = idVelocityBasic -! Inp%TreeBranchFactor = 3.0_ReKi -! Inp%PartPerSegment = 1 + CALL ReadVarWDefault(UnIn,FileName,Inp%VelocityMethod(1) ,'VelocityMethod' ,'',idVelocityTreePart, ErrStat2,ErrMsg2); if(Failed())return + CALL ReadVarWDefault(UnIn,FileName,Inp%TreeBranchFactor(1),'TreeBranchFactor' ,'',1.5_ReKi , ErrStat2,ErrMsg2); if(Failed())return + CALL ReadVarWDefault(UnIn,FileName,Inp%PartPerSegment(1) ,'PartPerSegment' ,'', 1 , ErrStat2,ErrMsg2); if(Failed())return + Inp%PartPerSegment(2) = 1 + Inp%TreeBranchFactor(2) = 2.0_ReKi + Inp%VelocityMethod(2) = idVelocityBasic + !CALL ReadVarWDefault(UnIn,FileName,Inp%VelocityMethod, 2,'VelocityMethod' ,'',(/idVelocityTreePart, idVelocityTreeSeg/) , ErrStat2,ErrMsg2); if(Failed())return + !CALL ReadVarWDefault(UnIn,FileName,Inp%TreeBranchFactor, 2,'TreeBranchFactor' ,'',(/1.5_ReKi, 5.0_ReKi/) , ErrStat2,ErrMsg2); if(Failed())return + !CALL ReadVarWDefault(UnIn,FileName,Inp%PartPerSegmentr , 2,'PartPerSegment' ,'',(/1, 2/) , ErrStat2,ErrMsg2); if(Failed())return !------------------------ OUTPUT OPTIONS ----------------------------------------- CALL ReadCom (UnIn,FileName, '=== Separator' ,ErrStat2,ErrMsg2); if(Failed()) return CALL ReadCom (UnIn,FileName, '--- Output options header' ,ErrStat2,ErrMsg2); if(Failed()) return CALL ReadVarWDefault(UnIn,FileName,Inp%WrVTK , 'WrVTK' ,'', 0 ,ErrStat2,ErrMsg2); if(Failed())return - CALL ReadVarWDefault(UnIn,FileName,Inp%VTKBlades , 'VTKBlades' ,'', 1 ,ErrStat2,ErrMsg2); if(Failed())return + CALL ReadVarWDefault(UnIn,FileName,Inp%VTKBlades , 'VTKBlades' ,'', 0 ,ErrStat2,ErrMsg2); if(Failed())return CALL ReadVarWDefault(UnIn,FileName,Inp%VTKCoord , 'VTKCoord' ,'', 1 ,ErrStat2,ErrMsg2); if(Failed())return CALL ReadVar (UnIn,FileName,sDummy , 'VTK_fps' ,'' ,ErrStat2,ErrMsg2); if(Failed())return - Inp%DTvtk = Get_DTvtk( sDummy, p%DTaero, Inp%DTfvw ) + if (Inp%WrVTK==2 .or. Inp%WrVTK==0) then + Inp%DTvtk = HUGE(1.0_DbKi) + else + Inp%DTvtk = Get_DTvtk( sDummy, p%DTaero, Inp%DTfvw ) + endif CALL ReadVarWDefault(UnIn,FileName,p%nGridOut , 'nGridOut' ,'', 0 ,ErrStat2,ErrMsg2); if (ErrStat2/=ErrID_None) then @@ -105,31 +112,42 @@ SUBROUTINE FVW_ReadInputFile( FileName, p, m, Inp, ErrStat, ErrMsg ) ! --- Advanced Options ! NOTE: no error handling since this is for debug ! Default options are typically "true" - p%InductionAtCP = .true. ! Compute the induced velocities at Control Points, otherwise, at nodes - p%WakeAtTE = .true. ! The wake starts at the trailing edge, otherwise, directly at the lifting line - p%Induction = .true. ! Compute induced velocities, otherwise 0 induced velocities on the lifting line! - p%DStallOnWake = .false. CALL ReadCom(UnIn,FileName, '=== Separator' ,ErrStat2,ErrMsg2); CALL ReadCom(UnIn,FileName, '--- Advanced options header' ,ErrStat2,ErrMsg2); if(ErrStat2==ErrID_None) then call WrScr(' - Reading advanced options for OLAF:') do while(ErrStat2==ErrID_None) - read(UnIn, '(A)',iostat=ErrStat2) sDummy + read(UnIn, '(A)', iostat=ErrStat2) sDummy + if (ErrStat2/=ErrID_None) exit call Conv2UC(sDummy) ! to uppercase - if (index(sDummy, 'INDUCTIONATCP')>1) then + if (index(sDummy, '!') == 1 .or. index(sDummy, '=') == 1 .or. index(sDummy, '#') == 1) then + ! pass comment lines + elseif (index(sDummy, 'INDUCTIONATCP')>1) then read(sDummy, '(L1)') p%InductionAtCP - print*,' >>> InductionAtCP',p%InductionAtCP + print*,' >>> InductionAtCP ',p%InductionAtCP elseif (index(sDummy, 'WAKEATTE')>1) then read(sDummy, '(L1)') p%WakeAtTE - print*,' >>> WakeAtTE ',p%WakeAtTE + print*,' >>> WakeAtTE ',p%WakeAtTE elseif (index(sDummy, 'DSTALLONWAKE')>1) then read(sDummy, '(L1)') p%DStallOnWake - print*,' >>> DStallOnWake ',p%DStallOnWake + print*,' >>> DStallOnWake ',p%DStallOnWake elseif (index(sDummy, 'INDUCTION')>1) then read(sDummy, '(L1)') p%Induction - print*,' >>> Induction ',p%Induction + print*,' >>> Induction ',p%Induction + elseif (index(sDummy, 'KFROZENNWEND')>1) then + read(sDummy, *) p%kFrozenNWEnd + print*,' >>> kFrozenNWEnd ',p%kFrozenNWEnd + elseif (index(sDummy, 'KFROZENNWSTART')>1) then + read(sDummy, *) p%kFrozenNWStart + print*,' >>> kFrozenNWStart ',p%kFrozenNWStart + elseif (index(sDummy, 'VELOCITYMETHODLL')>1) then + read(sDummy, *) Inp%VelocityMethod(2) + print*,' >>> VelocityMethod ',Inp%VelocityMethod + elseif (index(sDummy, 'TREEBRANCHFACTORLL')>1) then + read(sDummy, *) Inp%TreeBranchFactor(2) + print*,' >>> TreeBranchFactor ',Inp%TreeBranchFactor else - print*,' >>> Line ignored, starting with'//trim(sDummy) + print*,'[WARN] Line ignored: '//trim(sDummy) endif enddo endif @@ -138,21 +156,31 @@ SUBROUTINE FVW_ReadInputFile( FileName, p, m, Inp, ErrStat, ErrMsg ) ! --- Validation of inputs if (PathIsRelative(Inp%CirculationFile)) Inp%CirculationFile = TRIM(PriPath)//TRIM(Inp%CirculationFile) - if (Check(.not.(ANY(idCircVALID ==Inp%CirculationMethod)), 'Circulation method (CircSolvingMethod) not implemented: '//trim(Num2LStr(Inp%CirculationMethod)))) return + if (Check(.not.(ANY(idCircVALID ==Inp%CircSolvMethod)), 'Circulation method (CircSolvMethod) not implemented: '//trim(Num2LStr(Inp%CircSolvMethod)))) return if (Check(.not.(ANY(idIntMethodVALID==Inp%IntMethod )) , 'Time integration method (IntMethod) not yet implemented. Use Euler 1st order method for now.')) return if (Check(.not.(ANY(idDiffusionVALID==Inp%DiffusionMethod)) , 'Diffusion method (DiffusionMethod) not implemented: '//trim(Num2LStr(Inp%DiffusionMethod)))) return if (Check(.not.(ANY(idRegDeterVALID ==Inp%RegDeterMethod)) , 'Regularization determination method (RegDeterMethod) not yet implemented: '//trim(Num2LStr(Inp%RegDeterMethod)))) return if (Check(.not.(ANY(idRegVALID ==Inp%RegFunction )), 'Regularization function (RegFunction) not implemented: '//trim(Num2LStr(Inp%RegFunction)))) return if (Check(.not.(ANY(idRegMethodVALID==Inp%WakeRegMethod)), 'Wake regularization method (WakeRegMethod) not implemented: '//trim(Num2LStr(Inp%WakeRegMethod)))) return if (Check(.not.(ANY(idShearVALID ==Inp%ShearModel )), 'Shear model (ShearModel) not valid: '//trim(Num2LStr(Inp%ShearModel)))) return - if (Check(.not.(ANY(idVelocityVALID ==Inp%VelocityMethod )), 'Velocity method (VelocityMethod) not valid: '//trim(Num2LStr(Inp%VelocityMethod)))) return + if (Check(.not.(ANY(idVelocityVALID ==Inp%VelocityMethod(1))), 'Velocity method (VelocityMethod(1)) not valid: '//trim(Num2LStr(Inp%VelocityMethod(1))))) return + if (Check(.not.(ANY(idVelocityVALID ==Inp%VelocityMethod(2))), 'Velocity method (VelocityMethod(2)) not valid: '//trim(Num2LStr(Inp%VelocityMethod(2))))) return if (Check( Inp%DTfvw < p%DTaero, 'DTfvw must be >= DTaero from AD15.')) return - if (Inp%CirculationMethod == idCircPolarData) then - if (Check( Inp%nNWPanels<1 , 'Number of near wake panels (`nNWPanels`) must be >=1 when using circulation solving with polar data (`CircSolvingMethod=1`)')) return + if (Inp%CircSolvMethod == idCircPolarData) then + if (Check( Inp%nNWPanels<1 , 'Number of near wake panels (`nNWPanels`) must be >=1 when using circulation solving with polar data (`CircSolvMethod=1`)')) return endif if (Check( Inp%nNWPanels<0 , 'Number of near wake panels must be >=0')) return + if (Check( Inp%nNWPanelsFree<0 , 'Number of free near wake panels must be >=0')) return + if (Check( Inp%nNWPanelsFree>Inp%nNWPanels , 'Number of free near wake panels must be <=Number of near wake panels')) return + if (Inp%nNWPanels-Inp%nNWPanelsFree>0) then + call WrScr('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') + call WrScr('nNWPanelsFree < nNWPanels is a beta feature for simulation speed up.') + call WrScr('The frozen near-wake convection might slightly change in the future.') + call WrScr('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') + if (Check( Inp%nFWPanelsFree>0 , 'Number of free wake panels must be 0 when using a fixed NW')) return + endif if (Check( Inp%nFWPanels<0 , 'Number of far wake panels must be >=0')) return if (Check( Inp%nFWPanelsFree<0 , 'Number of free far wake panels must be >=0')) return if (Check( Inp%nFWPanelsFree>Inp%nFWPanels , 'Number of free far wake panels must be <=Number of far wake panels')) return @@ -166,6 +194,7 @@ SUBROUTINE FVW_ReadInputFile( FileName, p, m, Inp, ErrStat, ErrMsg ) ! Still we force the user to be responsible. if (Check((.not.(Inp%FWShedVorticity)) .and. Inp%nNWPanels<30, '`FWShedVorticity` should be true if `nNWPanels`<30. Alternatively, use a larger number of NWPanels ')) return + if (Check(p%kFrozenNWEnd>p%kFrozenNWStart , 'kFrozenNWEnd should be smaller than kFrozenNWStart')) return ! At least one NW panel if FW, this shoudln't be a problem since the LL is in NW, but safety for now !if (Check( (Inp%nNWPanels<=0).and.(Inp%nFWPanels>0) , 'At least one near wake panel is required if the number of far wake panel is >0')) return @@ -249,7 +278,7 @@ subroutine ReadGridOut(sLine, GridOut) GridOut%name =StrArray(1) ! Type if (.not. is_int (StrArray(2), GridOut%type ) ) then - ErrMsg2=trim(ErrMsg2)//achar(13)//achar(10)//'GridType needs to be an integer.' + ErrMsg2=trim(ErrMsg2)//NewLine//'GridType needs to be an integer.' return endif ! tStart @@ -258,7 +287,7 @@ subroutine ReadGridOut(sLine, GridOut) GridOut%tStart = 0.0_ReKi else if (.not. is_numeric(StrArray(3), GridOut%tStart) ) then - ErrMsg2=trim(ErrMsg2)//achar(13)//achar(10)//'TStart needs to be numeric or "default".' + ErrMsg2=trim(ErrMsg2)//NewLine//'TStart needs to be numeric or "default".' return endif endif @@ -268,7 +297,7 @@ subroutine ReadGridOut(sLine, GridOut) GridOut%tEnd = 99999.0_ReKi ! TODO else if (.not. is_numeric(StrArray(4), GridOut%tEnd) ) then - ErrMsg2=trim(ErrMsg2)//achar(13)//achar(10)//'TEnd needs to be numeric or "default".' + ErrMsg2=trim(ErrMsg2)//NewLine//'TEnd needs to be numeric or "default".' return endif endif @@ -280,7 +309,7 @@ subroutine ReadGridOut(sLine, GridOut) GridOut%DTout = p%DTaero else if (.not. is_numeric(StrArray(5), GridOut%DTout) ) then - ErrMsg2=trim(ErrMsg2)//achar(13)//achar(10)//'DTout needs to be numeric, "default" or "all".' + ErrMsg2=trim(ErrMsg2)//NewLine//'DTout needs to be numeric, "default" or "all".' return endif endif @@ -313,6 +342,12 @@ function is_numeric(string, x) character(len=12) :: fmt x = 0.0_reki n=len_trim(string) + + if (n==0) then ! blank lines shouldn't be valid numbers + is_numeric = .false. + return + end if + write(fmt,'("(F",I0,".0)")') n read(string,fmt,iostat=e) x is_numeric = e == 0 @@ -327,6 +362,12 @@ function is_int(string, x) character(len=12) :: fmt x = 0 n=len_trim(string) + + if (n==0) then ! blank lines shouldn't be valid integers + is_int = .false. + return + end if + write(fmt,'("(I",I0,")")') n read(string,fmt,iostat=e) x is_int = e == 0 @@ -337,7 +378,7 @@ end function is_int !> Export FVW variables to VTK !! NOTE: when entering this function nNW and nFW has been incremented by 1 subroutine WrVTK_FVW(p, x, z, m, FileRootName, VTKcount, Twidth, bladeFrame, HubOrientation, HubPosition) - use FVW_VTK ! for all the vtk_* functions + use VTK ! for all the vtk_* functions type(FVW_ParameterType), intent(in ) :: p !< Parameters type(FVW_ContinuousStateType), intent(in ) :: x !< States type(FVW_ConstraintStateType), intent(in ) :: z !< Constraints @@ -361,7 +402,7 @@ subroutine WrVTK_FVW(p, x, z, m, FileRootName, VTKcount, Twidth, bladeFrame, Hub real(Reki), dimension(:,:,:), allocatable :: Arr3D !< real(Reki), dimension(:,:), allocatable :: Arr2D !< - type(FVW_VTK_Misc) :: mvtk + type(VTK_Misc) :: mvtk call vtk_misc_init(mvtk) @@ -459,12 +500,10 @@ subroutine WrVTK_FVW(p, x, z, m, FileRootName, VTKcount, Twidth, bladeFrame, Hub end subroutine WrVTK_FVW !> Export Grid velocity field to VTK -subroutine WrVTK_FVW_Grid(p, x, z, m, iGrid, FileRootName, VTKcount, Twidth, HubOrientation, HubPosition) +subroutine WrVTK_FVW_Grid(p, m, iGrid, FileRootName, VTKcount, Twidth, HubOrientation, HubPosition) use FVW_VortexTools, only: curl_regular_grid - use FVW_VTK ! for all the vtk_* functions + use VTK ! for all the vtk_* functions type(FVW_ParameterType), intent(in ) :: p !< Parameters - type(FVW_ContinuousStateType), intent(in ) :: x !< States - type(FVW_ConstraintStateType), intent(in ) :: z !< Constraints type(FVW_MiscVarType), target, intent(in ) :: m !< MiscVars integer(IntKi), intent(in) :: iGrid !< Grid out index character(*), intent(in) :: FileRootName !< Name of the file to write the output in (excluding extension) @@ -478,7 +517,7 @@ subroutine WrVTK_FVW_Grid(p, x, z, m, iGrid, FileRootName, VTKcount, Twidth, Hub character(Twidth) :: Tstr ! string for current VTK write-out step (padded with zeros) real(ReKi), dimension(3) :: dx type(GridOutType), pointer :: g - type(FVW_VTK_Misc) :: mvtk + type(VTK_Misc) :: mvtk call vtk_misc_init(mvtk) call set_vtk_binary_format(.false.,mvtk) ! TODO binary fails @@ -506,15 +545,17 @@ subroutine WrVTK_FVW_Grid(p, x, z, m, iGrid, FileRootName, VTKcount, Twidth, Hub call vtk_close_file(mvtk) endif - if(.false.) print*,z%W(1)%Gamma_LL(1) ! unused var for now + if(.false.) print*,HubOrientation! unused var for now + if(.false.) print*,HubPosition ! unused var for now + if(.false.) print*,p%nNWMax ! unused var for now end subroutine WrVTK_FVW_Grid subroutine WrVTK_Segments(filename, mvtk, SegPoints, SegConnct, SegGamma, SegEpsilon, bladeFrame) - use FVW_VTK + use VTK character(len=*),intent(in) :: filename - type(FVW_VTK_Misc), intent(inout) :: mvtk !< miscvars for VTK output + type(VTK_Misc), intent(inout) :: mvtk !< miscvars for VTK output real(ReKi), dimension(:,:), intent(in) :: SegPoints !< integer(IntKi), dimension(:,:), intent(in) :: SegConnct !< real(ReKi), dimension(:) , intent(in) :: SegGamma !< @@ -533,9 +574,9 @@ subroutine WrVTK_Segments(filename, mvtk, SegPoints, SegConnct, SegGamma, SegEps end subroutine subroutine WrVTK_Lattice(filename, mvtk, LatticePoints, LatticeGamma, LatticeData3d, bladeFrame) - use FVW_VTK ! for all the vtk_* functions + use VTK ! for all the vtk_* functions character(len=*), intent(in) :: filename - type(FVW_VTK_Misc), intent(inout) :: mvtk !< miscvars for VTK output + type(VTK_Misc), intent(inout) :: mvtk !< miscvars for VTK output real(Reki), dimension(:,:,:), intent(in ) :: LatticePoints !< Array of points 3 x nSpan x nDepth real(Reki), dimension(:,:), intent(in ) :: LatticeGamma !< Array of nSpan x nDepth real(Reki), dimension(:,:,:), intent(in ), optional :: LatticeData3d !< Array of n x nSpan x nDepth KEEP ME diff --git a/modules/aerodyn/src/FVW_Registry.txt b/modules/aerodyn/src/FVW_Registry.txt index 4b820161e..698cbf063 100644 --- a/modules/aerodyn/src/FVW_Registry.txt +++ b/modules/aerodyn/src/FVW_Registry.txt @@ -37,7 +37,13 @@ typedef ^ ^ ReKi typedef ^ ^ IntKi RegFunction - - - "Type of regularizaion function (LambOseen, Vatistas, see FVW_BiotSavart)" - typedef ^ ^ IntKi nAct - - - "Number of active segments" - typedef ^ ^ IntKi nActP - - - "Number of active segment points" - -# TODO add tree, and part +# TODO add tree +##################### Particles ############### +typedef FVW/FVW T_Part ReKi P :: - - "Particle Points" - +typedef ^ ^ ReKi Alpha :: - - "Particle intensity 3 x nP" - +typedef ^ ^ ReKi RegParam : - - "Particle regularization parameter" - +typedef ^ ^ IntKi RegFunction - - - "Type of regularizaion function (FVW_BiotSavart)" - +typedef ^ ^ IntKi nAct - - - "Number of active particles <=nP" - ##################### Registry for FVW ############### # ..... PARAMETERS ............. @@ -60,13 +66,14 @@ typedef ^ ^ Wng_ParameterType typedef ^ ^ IntKi Bld2Wings :: - - "Index mapping from blades to wings" - typedef ^ ^ IntKi iNWStart - - - "Index where NW start in r_NW. (iNWStart=2, the first panel contains the lifting line panel, otherwise, start at 1)" - typedef ^ ^ IntKi nNWMax - - - "Maximum number of nw panels, per wing" - +typedef ^ ^ IntKi nNWFree - - - "Number of nw panels that are free, per wing" - typedef ^ ^ IntKi nFWMax - - - "Maximum number of fw panels, per wing" - typedef ^ ^ IntKi nFWFree - - - "Number of fw panels that are free, per wing" - typedef ^ ^ Logical FWShedVorticity - - - "Include shed vorticity in the far wake" - typedef ^ ^ IntKi IntMethod - - - "Integration Method (1=RK4, 2=AB4, 3=ABM4, 5=Euler1)" - typedef ^ ^ ReKi FreeWakeStart - - - "Time when wake starts convecting (rolling up)" s -typedef ^ ^ ReKi FullCirculationStart - - - "Time when the circulation is full" s -typedef ^ ^ IntKi CirculationMethod - - - "Method to determine the circulation" - +typedef ^ ^ ReKi FullCircStart - - - "Time when the circulation is full" s +typedef ^ ^ IntKi CircSolvMethod - - - "Method to determine the circulation" - typedef ^ ^ IntKi CircSolvMaxIter - - - "Maximum number of iterations for circulation solving" - typedef ^ ^ ReKi CircSolvConvCrit - - - "Convergence criterion for circulation solving" - typedef ^ ^ ReKi CircSolvRelaxation - - - "Relaxation factor for circulation solving" - @@ -80,12 +87,14 @@ typedef ^ ^ ReKi typedef ^ ^ ReKi WingRegParam - - - "Regularization parameter of the wing" typedef ^ ^ IntKi ShearModel - - - "Option for shear modelling" typedef ^ ^ Logical TwrShadowOnWake - - - "Include tower shadow effects on wake" -typedef ^ ^ IntKi VelocityMethod - - - "Velocity calculation method" -typedef ^ ^ ReKi TreeBranchFactor - - - "Factor used to determine if a point is far enough" -typedef ^ ^ IntKi PartPerSegment - - - "Number of particles per segment, e.g. for tree method" +typedef ^ ^ IntKi VelocityMethod 2 - - "Velocity calculation method for Full Wake and for LiftingLine" +typedef ^ ^ ReKi TreeBranchFactor 2 - - "Factor used to determine if a point is far enough, for full wake and lifting line" +typedef ^ ^ IntKi PartPerSegment 2 - - "Number of particles per segment, e.g. for tree method, for full wake and lifting line" typedef ^ ^ DbKi DTaero - - - "Time interval for calls calculations" s typedef ^ ^ DbKi DTfvw - - - "Time interval for calculating wake induced velocities" s typedef ^ ^ ReKi KinVisc - - - "Kinematic air viscosity" m^2/s +typedef ^ ^ IntKi MHK - - - "MHK flag" - +typedef ^ ^ ReKi WtrDpth - - - "Water depth" m # Parameters output options typedef ^ ^ IntKi WrVTK - - - "Outputs VTK at each calcoutput call, even if main fst doesnt do it" - typedef ^ ^ IntKi VTKBlades - - - "Outputs VTk for each blade 0=no blade, 1=Bld 1" - @@ -96,10 +105,12 @@ typedef ^ ^ CHARACTER(1024) typedef ^ ^ CHARACTER(1024) VTK_OutFileBase - - - "Basename for writing VTK files" - typedef ^ ^ IntKi nGridOut - - - "Number of VTK grid to output" - # Parameters advanced options -typedef ^ ^ Logical InductionAtCP - - - "Compute induced velocities at nodes or CP" -typedef ^ ^ Logical WakeAtTE - - - "Start the wake at the trailing edge, or at the LL" -typedef ^ ^ Logical DStallOnWake - - - "Dynamic stall has influence on wake" -typedef ^ ^ Logical Induction - - - "Compute induction" +typedef ^ ^ Logical InductionAtCP - .true. - "Compute induced velocities at nodes or CP" +typedef ^ ^ Logical WakeAtTE - .true. - "Start the wake at the trailing edge, or at the LL" +typedef ^ ^ Logical DStallOnWake - .false. - "Dynamic stall has influence on wake" +typedef ^ ^ Logical Induction - .true. - "Compute induction" +typedef ^ ^ ReKi kFrozenNWStart - 0.75 - "Fraction of wake induced velocity at start of frozen wake. 1 seems too strong." +typedef ^ ^ ReKi kFrozenNWEnd - 0.5 - "Fraction of wake induced velocity at end of frozen wake" #.......... ContinuousStateType ...... typedef FVW/FVW Wng_ContinuousStateType ReKi Gamma_NW :: - - "Circulation of the near wake panels ( nSpan x nNW )" - @@ -165,6 +176,7 @@ typedef ^ ^ ReKi typedef ^ ^ ReKi BN_Cl_Static : - - "Coefficient lift, excluding unsteady aero effects" - typedef ^ ^ ReKi BN_Cd_Static : - - "Coefficient drag. excluding unsteady aero effects" - typedef ^ ^ ReKi BN_Cm_Static : - - "Coefficient moment, excluding unsteady aero effects" - +typedef ^ ^ ReKi BN_Cpmin : - - "Coefficient minimum pressure, excluding unsteady aero effects" - typedef ^ ^ ReKi BN_Cl : - - "Coefficient lift, including unsteady aero effects" - typedef ^ ^ ReKi BN_Cd : - - "Coefficient drag, including unsteady aero effects" - typedef ^ ^ ReKi BN_Cm : - - "Coefficient moment, including unsteady aero effects" - @@ -189,8 +201,9 @@ typedef ^ ^ FVW_ContinuousStateType typedef ^ ^ DbKi t1 - - - "Time of x1 (for overcycling) " - typedef ^ ^ DbKi t2 - - - "Time of x2 t+DTFVW (for overcycling)" - typedef ^ ^ LOGICAL UA_Flag - - - "logical flag indicating whether to use UnsteadyAero" - -# Segment storage (buffer) +# Element storage (buffers) typedef ^ ^ T_Sgmt Sgmt - - - "Segments storage" - +typedef ^ ^ T_Part Part - - - "Particle storage" - # Wake rollup storage (buffer) typedef ^ ^ ReKi CPs :: - - "Control points used for wake rollup computation" - typedef ^ ^ ReKi Uind :: - - "Induced velocities obtained at control points" - @@ -214,7 +227,7 @@ typedef ^ ^ ReKi #.......... DiscreteStateType ...... # FVW_DiscreteStateType -typedef FVW/FVW DiscreteStateType ReKi NULL - - - "Empty to satisfy framework" - +typedef FVW/FVW DiscreteStateType ReKi Dummy - - - "Empty to satisfy framework" - typedef ^ ^ UA_DiscreteStateType UA : - - "states for UnsteadyAero for each Wing" - #.......... ConstraintStateType ...... @@ -226,7 +239,7 @@ typedef ^ ^ Reki # ....... OtherStateType ............ # FVW_OtherStateType -typedef FVW/FVW OtherStateType IntKi NULL - - - "Number of active near wake panels" - +typedef FVW/FVW OtherStateType IntKi Dummy - - - "Empty to satisfy framework" typedef ^ ^ UA_OtherStateType UA : - - "other states for UnsteadyAero for each wing" - @@ -247,6 +260,8 @@ typedef ^ ^ MeshType typedef ^ ^ IntKi numBladeNodes - - - "Number of nodes on each blade" - typedef ^ ^ DbKi DTaero - - - "Time interval for calls (from AD15)" s typedef ^ ^ ReKi KinVisc - - - "Kinematic air viscosity" m^2/s +typedef ^ ^ IntKi MHK - - - "MHK flag" - +typedef ^ ^ ReKi WtrDpth - - - "Water depth" m # TODO UA - Should be part of AeroDyn typedef ^ ^ IntKi UAMod - - - "Model for the dynamic stall equations [1 = Leishman/Beddoes, 2 = Gonzalez, 3 = Minnema]" - typedef ^ ^ LOGICAL UA_Flag - - - "logical flag indicating whether to use UnsteadyAero" - @@ -256,7 +271,7 @@ typedef ^ ^ LOGICAL #.......... InputFileType ...... # FVW_InputFile -typedef FVW/FVW FVW_InputFile IntKi CirculationMethod - - - "Method to determine the circulation" - +typedef FVW/FVW FVW_InputFile IntKi CircSolvMethod - - - "Method to determine the circulation" - typedef ^ ^ CHARACTER(1024) CirculationFile - - - "Prescribed circulation file" - typedef ^ ^ IntKi CircSolvMaxIter - - - "Maximum number of iterations for circulation solving" - typedef ^ ^ ReKi CircSolvConvCrit - - - "Convergence criterion for circulation solving" - @@ -265,10 +280,11 @@ typedef ^ ^ ReKi typedef ^ ^ IntKi IntMethod - - - "Integration Method (1=RK4, 2=AB4, 3=ABM4, 5=Euler1, 7=Corrector/Predictor)" - typedef ^ ^ LOGICAL FreeWake - - - "Disable roll up, wake convects with wind only (flag)" - typedef ^ ^ ReKi FreeWakeStart - - - "Time when wake starts convecting (rolling up)" s -typedef ^ ^ ReKi FullCirculationStart - - - "Time when the circulation is full" s +typedef ^ ^ ReKi FullCircStart - - - "Time when the circulation is full" s typedef ^ ^ DbKi DTfvw - - - "Time interval for calculating wake induced velocities" s typedef ^ ^ IntKi CircSolvPolar - - - "(0=Use AD polars, 1=2PiAlpha, 2=sin(2pialpha)" - typedef ^ ^ IntKi nNWPanels - - - "Number of nw panels" - +typedef ^ ^ IntKi nNWPanelsFree - - - "Number of nw panels" - typedef ^ ^ IntKi nFWPanels - - - "Number of fw panels" - typedef ^ ^ IntKi nFWPanelsFree - - - "Number of fw panels that are free" - typedef ^ ^ Logical FWShedVorticity - - - "Include shed vorticity in the far wake" - @@ -281,9 +297,9 @@ typedef ^ ^ ReKi typedef ^ ^ ReKi WingRegParam - - - "Factor used in the regularization " typedef ^ ^ IntKi ShearModel - - - "Option for shear modelling" typedef ^ ^ Logical TwrShadowOnWake - - - "Include tower shadow effects on wake" -typedef ^ ^ IntKi VelocityMethod - - - "Velocity calculation method" -typedef ^ ^ ReKi TreeBranchFactor - - - "Factor used to determine if a point is far enough" -typedef ^ ^ IntKi PartPerSegment - - - "Number of particles per segment, e.g. for tree method" +typedef ^ ^ IntKi VelocityMethod 2 - - "Velocity calculation method for Full Wake and for LiftingLine" +typedef ^ ^ ReKi TreeBranchFactor 2 - - "Factor used to determine if a point is far enough, for full wake and lifting line" +typedef ^ ^ IntKi PartPerSegment 2 - - "Number of particles per segment, e.g. for tree method, for full wake and lifting line" typedef ^ ^ IntKi WrVTK - - - "Outputs VTK at each calcoutput call, even if main fst doesnt do it" - typedef ^ ^ IntKi VTKBlades - - - "Outputs VTk for each blade 0=no blade, 1=Bld 1" - typedef ^ ^ DbKi DTvtk - - - "Requested timestep between VTK outputs (calculated from the VTK_fps read in)" s @@ -291,7 +307,7 @@ typedef ^ ^ IntKi #.......... InitOutputType ...... # FVW_InitOutputType -typedef FVW/FVW InitOutputType IntKi Null - - - "Empty parameter to satisfy framework" - +typedef FVW/FVW InitOutputType IntKi Dummy - - - "Empty parameter to satisfy framework" - diff --git a/modules/aerodyn/src/FVW_Subs.f90 b/modules/aerodyn/src/FVW_Subs.f90 index 676f5ee44..64dc8c6a2 100644 --- a/modules/aerodyn/src/FVW_Subs.f90 +++ b/modules/aerodyn/src/FVW_Subs.f90 @@ -32,7 +32,7 @@ module FVW_SUBS integer(IntKi), parameter, dimension(2) :: idRegMethodVALID = (/idRegConstant,idRegAge/) ! Regularization determination method integer(IntKi), parameter :: idRegDeterConstant = 0 - integer(IntKi), parameter :: idRegDeterAuto = 1 + integer(IntKi), parameter :: idRegDeterAuto = 1 integer(IntKi), parameter :: idRegDeterChord = 2 integer(IntKi), parameter :: idRegDeterSpan = 3 integer(IntKi), parameter, dimension(4) :: idRegDeterVALID = (/idRegDeterConstant, idRegDeterAuto, idRegDeterChord, idRegDeterSpan /) @@ -41,11 +41,11 @@ module FVW_SUBS integer(IntKi), parameter :: idShearMirror = 1 integer(IntKi), parameter, dimension(2) :: idShearVALID = (/idShearNone, idShearMirror /) ! Velocity calculation method - integer(IntKi), parameter :: idVelocityBasic = 1 - integer(IntKi), parameter :: idVelocityTree = 2 - integer(IntKi), parameter :: idVelocityPart = 3 + integer(IntKi), parameter :: idVelocityBasic = 1 + integer(IntKi), parameter :: idVelocityTreePart = 2 + integer(IntKi), parameter :: idVelocityPart = 3 integer(IntKi), parameter :: idVelocityTreeSeg = 4 - integer(IntKi), parameter, dimension(4) :: idVelocityVALID = (/idVelocityBasic, idVelocityTree, idVelocityPart,& + integer(IntKi), parameter, dimension(4) :: idVelocityVALID = (/idVelocityBasic, idVelocityTreePart, idVelocityPart,& idVelocityTreeSeg/) real(ReKi), parameter :: CoreSpreadAlpha = 1.25643 @@ -53,6 +53,7 @@ module FVW_SUBS ! Implementation integer(IntKi), parameter :: FWnSpan=1 !< Number of spanwise far wake panels ! TODO make it an input later logical , parameter :: DEV_VERSION=.False. + logical , parameter :: OLAF_PROFILING=.False. contains !========================================================================== @@ -276,14 +277,14 @@ subroutine Map_NW_FW(p, m, z, x, ErrStat, ErrMsg) type(FVW_ContinuousStateType), intent(inout) :: x !< Continuous states integer(IntKi), intent( out) :: ErrStat !< Error status of the operation character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None - integer(IntKi) :: iW, iRoot, iTip, iMax + integer(IntKi) :: iW, iRoot, iTip real(ReKi), dimension(p%nWings) :: FWGamma real(ReKi), dimension(:),allocatable :: Gamma_t real(ReKi), dimension(:),allocatable :: sCoord ! real(ReKi), dimension(p%W(iW)%nSpan+1) :: Gamma_t ! real(ReKi), dimension(p%W(iW)%nSpan) :: sCoord real(ReKi) :: FWEpsTip, FWEpsRoot - real(ReKi) :: ltip, rTip, Gamma_max + integer(IntKi), parameter :: iAgeFW=1 !< we update the first FW panel ErrStat = ErrID_None ErrMsg = "" @@ -296,7 +297,7 @@ subroutine Map_NW_FW(p, m, z, x, ErrStat, ErrMsg) do iW=1,p%nWings allocate(Gamma_t(p%W(iW)%nSpan+1)) ! TODO TODO TODO, store as misc allocate(sCoord(p%W(iW)%nSpan)) - if (p%FullCirculationStart>0 .and. m%nFW<3) then + if (p%FullCircStart>0 .and. m%nFW<3) then ! we might run into the issue that the circulation is 0 m%W(iW)%iTip =-1 m%W(iW)%iRoot=-1 @@ -452,49 +453,122 @@ subroutine print_x_NW_FW(p, m, x, label) endsubroutine !> Debug function to figure out if data have nan -logical function have_nan(p, m, x, u, label) +logical function have_nan(p, m, x, z, u, label) type(FVW_ParameterType), intent(in) :: p !< Parameters type(FVW_MiscVarType), intent(in) :: m !< Initial misc/optimization variables type(FVW_ContinuousStateType), intent(in) :: x !< Continuous states + type(FVW_ConstraintStateType), intent(in) :: z !< ConstrStates type(FVW_InputType), intent(in) :: u(:) !< Input states character(len=*), intent(in) :: label !< label for print integer :: iW have_nan=.False. do iW = 1,size(p%W) if (any(isnan(x%W(iW)%r_NW))) then - print*,trim(label),'NaN in W(iW)%r_NW' + print*,trim(label),'NaN in W(iW)%r_NW'//trim(num2lstr(iW)) have_nan=.True. endif if (any(isnan(x%W(iW)%r_FW))) then - print*,trim(label),'NaN in W(iW)%r_FW' + print*,trim(label),'NaN in W(iW)%r_FW'//trim(num2lstr(iW)) have_nan=.True. endif if (any(isnan(x%W(iW)%Gamma_NW))) then - print*,trim(label),'NaN in G_NW' + print*,trim(label),'NaN in G_NW'//trim(num2lstr(iW)) have_nan=.True. endif if (any(isnan(x%W(iW)%Gamma_FW))) then - print*,trim(label),'NaN in G_FW' + print*,trim(label),'NaN in G_FW'//trim(num2lstr(iW)) have_nan=.True. endif if (any(isnan(x%W(iW)%Eps_NW))) then - print*,trim(label),'NaN in G_FW' + print*,trim(label),'NaN in G_FW'//trim(num2lstr(iW)) have_nan=.True. endif if (any(isnan(x%W(iW)%Eps_FW))) then - print*,trim(label),'NaN in G_FW' + print*,trim(label),'NaN in G_FW'//trim(num2lstr(iW)) + have_nan=.True. + endif + if (any(isnan(z%W(iW)%Gamma_LL))) then + print*,trim(label),'NaN in G_LL'//trim(num2lstr(iW)) + have_nan=.True. + endif + enddo + do iW=1,size(u) + if (any(isnan(u(iW)%V_wind))) then + print*,trim(label),'NaN in Vwind'//trim(num2lstr(iW)) have_nan=.True. endif enddo - if (any(isnan(u(1)%V_wind))) then - print*,trim(label),'NaN in Vwind1' - have_nan=.True. + if(.false.)print*,m%iStep ! unused var +endfunction +subroutine find_nan_1D(array, varname) + real(ReKi), dimension(:), intent(in) :: array + character(len=*), intent(in) :: varname + logical :: found + integer :: i, n, tot + n = size(array) + found=.false. + tot=0 + do i =1, n + if (isnan(array(i))) then + if (tot<10) then + print*,'Position i',i + endif + found=.true. + tot=tot+1 + endif + enddo + if (found) then + print*,'>>>>>>>>>>>>> NAN ',trim(varname),tot,n + STOP endif - if (any(isnan(u(2)%V_wind))) then - print*,trim(label),'NaN in Vwind2' - have_nan=.True. +end subroutine +subroutine find_nan_2D(array, varname) + real(ReKi), dimension(:,:), intent(in) :: array + character(len=*), intent(in) :: varname + logical :: found + integer :: i, n, tot + n = size(array,2) + found=.false. + tot=0 + do i =1, n + if (any(isnan(array(:,i)))) then + if (tot<10) then + print*,'Position i',i + endif + found=.true. + tot=tot+1 + endif + enddo + if (found) then + print*,'>>>>>>>>>>>>> NAN ',trim(varname),tot,n + STOP endif -endfunction +end subroutine +subroutine find_nan_3D(array, varname) + real(ReKi), dimension(:,:,:), intent(in) :: array + character(len=*), intent(in) :: varname + logical :: found + integer :: i, j, n,m,tot + n = size(array,2) + m = size(array,3) + found=.false. + tot=0 + do i =1, n + do j =1, m + if (any(isnan(array(:,i,j)))) then + if (tot<10) then + print*,'Position i,j',i,j + endif + found=.true. + tot=tot+1 + endif + enddo + enddo + if (found) then + print*,'>>>>>>>>>>>>> NAN ',trim(varname), tot,n*m + STOP + endif +end subroutine ! -------------------------------------------------------------------------------- @@ -695,6 +769,90 @@ end subroutine DistributeRequestedWind_Grid +!> Init States +subroutine FVW_InitStates( x, p, ErrStat, ErrMsg ) + type(FVW_ContinuousStateType), intent( out) :: x !< States + type(FVW_ParameterType), intent(in ) :: p !< Parameters + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + integer(IntKi) :: ErrStat2 ! temporary error status of the operation + character(ErrMsgLen) :: ErrMsg2 ! temporary error message + character(*), parameter :: RoutineName = 'FVW_InitMiscVars' + integer :: iW + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + + allocate(x%W(p%nWings)) + do iW=1,p%nWings + call AllocAry( x%W(iW)%Gamma_NW, p%W(iW)%nSpan , p%nNWMax , 'NW Panels Circulation', ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,'FVW_InitStates' ); + call AllocAry( x%W(iW)%Gamma_FW, FWnSpan , p%nFWMax , 'FW Panels Circulation', ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,'FVW_InitStates' ); + call AllocAry( x%W(iW)%Eps_NW , 3, p%W(iW)%nSpan , p%nNWMax , 'NW Panels Reg Param' , ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,'FVW_InitStates' ); + call AllocAry( x%W(iW)%Eps_FW , 3, FWnSpan , p%nFWMax , 'FW Panels Reg Param' , ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,'FVW_InitStates' ); + ! set x%W(iW)%r_NW and x%W(iW)%r_FW to (0,0,0) so that InflowWind can shortcut the calculations + call AllocAry( x%W(iW)%r_NW , 3, p%W(iW)%nSpan+1 , p%nNWMax+1, 'NW Panels Points' , ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,'FVW_InitStates' ); + call AllocAry( x%W(iW)%r_FW , 3, FWnSpan+1 , p%nFWMax+1, 'FW Panels Points' , ErrStat2, ErrMsg2 );call SetErrStat ( ErrStat2, ErrMsg2, ErrStat,ErrMsg,'FVW_InitStates' ); + if (ErrStat >= AbortErrLev) return + x%W(iW)%r_NW = 0.0_ReKi + x%W(iW)%r_FW = 0.0_ReKi + x%W(iW)%Gamma_NW = 0.0_ReKi ! First call of calcoutput, states might not be set + x%W(iW)%Gamma_FW = 0.0_ReKi ! NOTE, these values might be mapped from z%W(iW)%Gamma_LL at init + x%W(iW)%Eps_NW = 0.001_ReKi + x%W(iW)%Eps_FW = 0.001_ReKi + enddo +end subroutine FVW_InitStates + +subroutine FVW_InitMiscVarsPostParam( p, m, ErrStat, ErrMsg ) + type(FVW_ParameterType), intent(in ) :: p !< Parameters + type(FVW_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 + integer(IntKi) :: ErrStat2 ! temporary error status of the operation + character(ErrMsgLen) :: ErrMsg2 ! temporary error message + character(*), parameter :: RoutineName = 'FVW_InitMiscVarsPostParam' + integer(IntKi) :: nSeg, nSegP, nSegNW !< Total number of segments after packing + integer(IntKi) :: nPart !< Total number of particles after packing + integer(IntKi) :: nCPs !< Total number of control points + logical :: bMirror + logical :: bLLNeedsPart, bWakeNeedsPart + ErrStat = ErrID_None + ErrMsg = "" + ! --- Counting maximum number of segments and Control Points expected for the whole simulation + call CountSegments(p, p%nNWMax, p%nFWMax, 1, nSeg, nSegP, nSegNW) + nCPs = CountCPs(p, p%nNWMax, p%nFWFree) + + bMirror = p%ShearModel==idShearMirror ! Whether or not we mirror the vorticity wrt ground + if (bMirror) then + nSeg = nSeg*2 + nSegP = nSegP*2 + endif + call AllocAry( m%Sgmt%Connct, 4, nSeg , 'SegConnct' , ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%Sgmt%Connct = -999; + call AllocAry( m%Sgmt%Points, 3, nSegP, 'SegPoints' , ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%Sgmt%Points = -999999_ReKi; + call AllocAry( m%Sgmt%Gamma , nSeg, 'SegGamma' , ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%Sgmt%Gamma = -999999_ReKi; + call AllocAry( m%Sgmt%Epsilon, nSeg, 'SegEpsilon', ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%Sgmt%Epsilon= -999999_ReKi; + m%Sgmt%nAct = -1 ! Active segments + m%Sgmt%nActP = -1 + m%Sgmt%RegFunction = p%RegFunction + + bWakeNeedsPart = p%VelocityMethod(1)==idVelocityPart .or.p%VelocityMethod(1)==idVelocityTreePart + bLLNeedsPart = p%VelocityMethod(2)==idVelocityPart .or. p%VelocityMethod(2)==idVelocityTreePart + if (bLLNeedsPart .or. bWakeNeedsPart) then + nPart = 0 + if (bWakeNeedsPart) nPart = max(nPart, nSeg * p%PartPerSegment(1)) + if (bLLNeedsPart) nPart = max(nPart, nSeg * p%PartPerSegment(2)) + call AllocAry( m%Part%P , 3, nPart, 'PartP' , ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%Part%P = -999999_ReKi; + call AllocAry( m%Part%Alpha , 3, nPart, 'PartAlpha' , ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%Part%Alpha = -999999_ReKi; + call AllocAry( m%Part%RegParam, nPart, 'PartEpsilon', ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%Part%RegParam= -999999_ReKi; + m%Part%nAct = -1 ! Active particles + m%Part%RegFunction = p%RegFunction + endif + + ! TODO Figure out Uind, CPs needed for grid + call AllocAry( m%CPs , 3, nCPs, 'CPs' , ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%CPs= -999999_ReKi; + call AllocAry( m%Uind , 3, nCPs, 'Uind' , ErrStat2, ErrMsg2 );call SetErrStat(ErrStat2, ErrMsg2, ErrStat,ErrMsg,RoutineName); m%Uind= -999999_ReKi; + +end subroutine FVW_InitMiscVarsPostParam + !> Count how many segments are needed to represent the Near wake and far wakes, starting at a given depth subroutine CountSegments(p, nNW, nFW, iDepthStart, nSeg, nSegP, nSegNW) type(FVW_ParameterType), intent(in ) :: p !< Parameters @@ -803,7 +961,7 @@ subroutine PackPanelsToSegments(p, x, iDepthStart, bMirror, nNW, nFW, SegConnct, print*,'PackPanelsToSegments: Number of segments wrongly estimated',nC, iHeadC-1 STOP ! Keep me. The check will be removed once the code is well established endif - if (any(SegPoints(3,:)<-99._ReKi)) then + if (any(SegPoints(3,:)<-999._ReKi)) then print*,'PackPanelsToSegments: some segments are NAN' STOP ! Keep me. The check will be removed once the code is well established endif @@ -829,6 +987,11 @@ subroutine PackPanelsToSegments(p, x, iDepthStart, bMirror, nNW, nFW, SegConnct, nSeg = nSeg*2 nSegP = nSegP*2 endif + + if (DEV_VERSION) then + call find_nan_2D(SegPoints(:,1:nSegP), 'PackPanelsToSegments SegPoints') + endif + else nSeg = 0 nSegP = 0 @@ -849,7 +1012,7 @@ subroutine FVW_InitRegularization(x, p, m, ErrStat, ErrMsg) real(ReKi) :: c_min, c_max, c_mean !< min,max and mean of chord real(ReKi) :: d_min, d_max, d_mean !< min,max and mean of panel diagonal real(ReKi) :: RegParam - real(ReKi) :: Span !< "Blade span" + real(ReKi) :: Span !< Wing "span"/length (taken as curvilinear coordinate) integer :: iW, iSpan ErrStat = ErrID_None ErrMsg = "" @@ -910,7 +1073,7 @@ subroutine FVW_InitRegularization(x, p, m, ErrStat, ErrMsg) write(*,'(A,I0)' ) 'WakeRegMethod : ', p%WakeRegMethod write(*,'(A,I0)' ) 'RegFunction : ', p%RegFunction write(*,'(A,1F8.4)') 'WakeRegParam : ', p%WakeRegParam - write(*,'(A,1F8.4)') 'BladeRegParam : ', p%WingRegParam + write(*,'(A,1F8.4)') 'WingRegParam : ', p%WingRegParam write(*,'(A,1F9.4)') 'CoreSpreadEddyVisc: ', p%CoreSpreadEddyVisc ! Set reg param on wing and first NW ! NOTE: setting the same in all three directions for now, TODO! @@ -944,7 +1107,7 @@ subroutine FVW_InitRegularization(x, p, m, ErrStat, ErrMsg) if (iW==1) then call WrScr(' - OLAF regularization parameters (for wing 1):') - write(*,'(A,2F8.4)') ' BladeReg (min/max): ', minval(x%W(iW)%Eps_NW(:, :, 1)), maxval(x%W(iW)%Eps_NW(:, :, 1)) + write(*,'(A,2F8.4)') ' WingReg (min/max) : ', minval(x%W(iW)%Eps_NW(:, :, 1)), maxval(x%W(iW)%Eps_NW(:, :, 1)) if (p%nNWMax>1) then write(*,'(A,2F8.4)') ' WakeReg (min/max) : ', minval(x%W(iW)%Eps_NW(:,:, 2)), maxval(x%W(iW)%Eps_NW(:,:, 2)) endif @@ -955,6 +1118,7 @@ subroutine FVW_InitRegularization(x, p, m, ErrStat, ErrMsg) end subroutine FVW_InitRegularization + !> Compute induced velocities from all vortex elements onto nPoints !! In : x, x%W(iW)%r_NW, x%W(iW)%r_FW, x%W(iW)%Gamma_NW, x%W(iW)%Gamma_FW !! Out: Vind @@ -971,7 +1135,6 @@ subroutine InducedVelocitiesAll_OnGrid(g, p, x, m, ErrStat, ErrMsg) real(ReKi) :: xP,yP,zP,dx,dy,dz ! TODO new options type(T_Tree) :: Tree - type(T_Part) :: Part real(ReKi), dimension(:,:), allocatable :: CPs ! TODO get rid of me with dedicated functions real(ReKi), dimension(:,:), allocatable :: Uind ! TODO get rid of me with dedicated functions ErrStat= ErrID_None @@ -1003,37 +1166,85 @@ subroutine InducedVelocitiesAll_OnGrid(g, p, x, m, ErrStat, ErrMsg) ! --- Compute induced velocity ! Convert Panels to segments, segments to particles, particles to tree - call InducedVelocitiesAll_Init(p, x, m, m%Sgmt, Part, Tree, ErrStat, ErrMsg) - call InducedVelocitiesAll_Calc(CPs, nCPs, Uind, p, m%Sgmt, Part, Tree, ErrStat, ErrMsg) - call InducedVelocitiesAll_End(p, m, Tree, Part, ErrStat, ErrMsg) + call InducedVelocitiesAll_Init(p, x, m, m%Sgmt, m%Part, Tree, ErrStat, ErrMsg, allocPart=.false.) + call InducedVelocitiesAll_Calc(CPs, nCPs, Uind, p, m%Sgmt, m%Part, Tree, ErrStat, ErrMsg) + call InducedVelocitiesAll_End(p, Tree, m%Part, ErrStat, ErrMsg, deallocPart=.false.) ! --- Unpacking induced velocity points iHeadP=1 call DeflateValues(Uind, g%uGrid, iHeadP) - deallocate(CPs , stat=ErrStat) - deallocate(Uind, stat=ErrStat) + if(allocated(CPs )) deallocate(CPs , stat=ErrStat) + if(allocated(Uind)) deallocate(Uind, stat=ErrStat) end subroutine InducedVelocitiesAll_OnGrid - +!> Wrapper to setup part from set of segments +subroutine SegmentsToPartWrap(Sgmt, nSeg, PartPerSegment, RegFunction, Part, allocPart) + type(T_Sgmt), intent(in ) :: Sgmt !< Segments + integer(IntKi), intent(in ) :: nSeg !< Number of segments to use (might not use all of them) + integer(IntKi), intent(in ) :: PartPerSegment !< Number of particles per segment + integer(IntKi), intent(in ) :: RegFunction !< Regularization function + type(T_Part), intent(inout) :: Part !< Particles + logical, intent(in ) :: allocPart !< allocate particles + integer(IntKi) :: iHeadP + integer(IntKi) :: nPart + logical, parameter :: alloc =.true. !< Should we allocate the particles? + iHeadP=1 + nPart = PartPerSegment * nSeg + ! --- Allocate + if (allocPart) then + if (allocated(Part%P)) deallocate(Part%P) + if (allocated(Part%Alpha)) deallocate(Part%Alpha) + if (allocated(Part%RegParam)) deallocate(Part%RegParam) + allocate(Part%P(3,nPart), Part%Alpha(3,nPart), Part%RegParam(nPart)) ! NOTE: remember to deallocate + else + ! check that we have enough space + if (.not. allocated(Part%P)) then + print*,'>>> PartP not allocated'; + STOP + endif + if (size(Part%P,2)>> PartP storage too small'; + STOP + endif + endif + Part%P(:,:) = -99999.99_ReKi + Part%Alpha(:,:) = -99999.99_ReKi + Part%RegParam(:) = -99999.99_ReKi + Part%nAct = nPart ! TODO add iHeadPart if particles already present + + call SegmentsToPart(Sgmt%Points, Sgmt%Connct, Sgmt%Gamma, Sgmt%Epsilon, 1, nSeg, PartPerSegment, Part%P, Part%Alpha, Part%RegParam, iHeadP) + if (RegFunction/=idRegNone) then + Part%RegFunction = idRegExp ! TODO need to find a good equivalence and potentially adapt Epsilon in SegmentsToPart + endif + if (DEV_VERSION) then + call find_nan_2D(Part%P , 'SegmentsToPartWrap Part%P') + call find_nan_2D(Part%Alpha, 'SegmentsToPartWrap Part%Alpha') + if (any(Part%RegParam(:)<-9999.99_ReKi)) then + print*,'Error in Segment to part conversion' + STOP + endif + endif +end subroutine SegmentsToPartWrap !> Perform initialization steps before requesting induced velocities from All vortex elements !! In : x%W(iW)%r_NW, x%W(iW)%r_FW, x%W(iW)%Gamma_NW, x%W(iW)%Gamma_FW !! Out: Tree, Part, m -subroutine InducedVelocitiesAll_Init(p, x, m, Sgmt, Part, Tree, ErrStat, ErrMsg) +subroutine InducedVelocitiesAll_Init(p, x, m, Sgmt, Part, Tree, ErrStat, ErrMsg, allocPart) type(FVW_ParameterType), intent(in ) :: p !< Parameters type(FVW_ContinuousStateType), intent(in ) :: x !< States type(FVW_MiscVarType), intent(in ) :: m !< Misc type(T_Sgmt), intent(inout) :: Sgmt !< Segments - type(T_Part), intent(out) :: Part !< Particle storage if needed + type(T_Part), intent(inout) :: Part !< Particle storage if needed type(T_Tree), intent(out) :: Tree !< Tree of particles if needed integer(IntKi), intent( out) :: ErrStat !< Error status of the operation character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + logical, intent(in ) :: allocPart !< allocate particles + integer, parameter :: iVel = 1 ! Local variables - integer(IntKi) :: iHeadP, nSeg, nSegP + integer(IntKi) :: nSeg, nSegP logical :: bMirror ! True if we mirror the vorticity wrt ground - integer(IntKi) :: nPart ErrStat= ErrID_None ErrMsg ='' @@ -1045,33 +1256,17 @@ subroutine InducedVelocitiesAll_Init(p, x, m, Sgmt, Part, Tree, ErrStat, ErrMsg Sgmt%nAct = nSeg Sgmt%nActP = nSegP - ! --- Converting to particles - if ((p%VelocityMethod==idVelocityTree) .or. (p%VelocityMethod==idVelocityPart)) then - iHeadP=1 - nPart = p%PartPerSegment * nSeg - allocate(Part%P(3,nPart), Part%Alpha(3,nPart), Part%RegParam(nPart)) - Part%Alpha(:,:) = -99999.99_ReKi - Part%P(:,:) = -99999.99_ReKi - Part%RegParam(:) = -99999.99_ReKi - call SegmentsToPart(Sgmt%Points, Sgmt%Connct, Sgmt%Gamma, Sgmt%Epsilon, 1, nSeg, p%PartPerSegment, Part%P, Part%Alpha, Part%RegParam, iHeadP) - if (p%RegFunction/=idRegNone) then - Part%RegFunction = idRegExp ! TODO need to find a good equivalence and potentially adapt Epsilon in SegmentsToPart - endif - if (DEV_VERSION) then - if (any(Part%RegParam(:)<-9999.99_ReKi)) then - print*,'Error in Segment to part conversion' - STOP - endif - endif + ! --- Convert to particles if needed + if ((p%VelocityMethod(iVel)==idVelocityTreePart) .or. (p%VelocityMethod(iVel)==idVelocityPart)) then + call SegmentsToPartWrap(Sgmt, nSeg, p%PartPerSegment(iVel), p%RegFunction, Part, allocPart=allocPart) endif - ! Grow tree if needed - if (p%VelocityMethod==idVelocityTree) then - Tree%DistanceDirect = 2*sum(Part%RegParam)/size(Part%RegParam) ! 2*mean(eps), below that distance eps has a strong effect - call grow_tree(Tree, Part%P, Part%Alpha, Part%RegFunction, Part%RegParam, 0) - elseif (p%VelocityMethod==idVelocityTreeSeg) then - Tree%DistanceDirect = 2*sum(Sgmt%Epsilon)/size(Sgmt%Epsilon) ! 2*mean(eps), below that distance eps has a strong effect - call grow_tree_segment(Tree, Sgmt%Points, Sgmt%Connct(:,1:nSeg),Sgmt%Gamma, p%RegFunction, Sgmt%Epsilon, 0) + ! --- Grow tree if needed + if (p%VelocityMethod(iVel)==idVelocityTreePart) then + call grow_tree_part(Tree, Part%nAct, Part%P, Part%Alpha, Part%RegFunction, Part%RegParam, 0) + + elseif (p%VelocityMethod(iVel)==idVelocityTreeSeg) then + call grow_tree_segment(Tree, nSeg, Sgmt%Points, Sgmt%Connct(:,1:nSeg), Sgmt%Gamma(1:nSeg), p%RegFunction, Sgmt%Epsilon(1:nSeg), 0) endif end subroutine InducedVelocitiesAll_Init @@ -1087,50 +1282,54 @@ subroutine InducedVelocitiesAll_Calc(CPs, nCPs, Uind, p, Sgmt, Part, Tree, ErrSt type(T_Tree), intent(inout) :: Tree !< Tree of particles if needed integer(IntKi), intent( out) :: ErrStat !< Error status of the operation character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + integer, parameter :: iVel = 1 ! Local variables ErrStat= ErrID_None ErrMsg ='' - if (p%VelocityMethod==idVelocityBasic) then - call ui_seg( 1, nCPs, CPs, 1, Sgmt%nAct, Sgmt%nAct, Sgmt%nActP, Sgmt%Points, Sgmt%Connct, Sgmt%Gamma, Sgmt%RegFunction, Sgmt%Epsilon, Uind) + if (p%VelocityMethod(iVel)==idVelocityBasic) then + call ui_seg( 1, nCPs, CPs, 1, Sgmt%nAct, Sgmt%Points, Sgmt%Connct, Sgmt%Gamma, Sgmt%RegFunction, Sgmt%Epsilon, Uind) - elseif (p%VelocityMethod==idVelocityTree) then + elseif (p%VelocityMethod(iVel)==idVelocityTreePart) then ! Tree has already been grown with InducedVelocitiesAll_Init !call print_tree(Tree) - call ui_tree(Tree, CPs, 0, 1, nCPs, p%TreeBranchFactor, Tree%DistanceDirect, Uind, ErrStat, ErrMsg) + call ui_tree_part(Tree, nCPs, CPs, p%TreeBranchFactor(iVel), Tree%DistanceDirect, Uind, ErrStat, ErrMsg) + + elseif (p%VelocityMethod(iVel)==idVelocityPart) then + call ui_part_nograd(nCPs, CPs, Part%nAct, Part%P, Part%Alpha, Part%RegFunction, Part%RegParam, Uind) - elseif (p%VelocityMethod==idVelocityPart) then - call ui_part_nograd(CPs ,Part%P, Part%Alpha, Part%RegFunction, Part%RegParam, Uind, nCPs, size(Part%P,2)) - elseif (p%VelocityMethod==idVelocityTreeSeg) then - call ui_tree_segment(Tree, CPs, 0, 1, nCPs, p%TreeBranchFactor, Tree%DistanceDirect, Uind, ErrStat, ErrMsg) + elseif (p%VelocityMethod(iVel)==idVelocityTreeSeg) then + call ui_tree_segment(Tree, CPs, nCPs, p%TreeBranchFactor(iVel), Tree%DistanceDirect, Uind, ErrStat, ErrMsg) endif end subroutine InducedVelocitiesAll_Calc !> Perform termination steps after velocity was requested from all vortex elements !! InOut: Tree, Part, m -subroutine InducedVelocitiesAll_End(p, m, Tree, Part, ErrStat, ErrMsg) +subroutine InducedVelocitiesAll_End(p, Tree, Part, ErrStat, ErrMsg, deallocPart) type(FVW_ParameterType), intent(in ) :: p !< Parameters - type(FVW_MiscVarType), intent(inout) :: m !< Initial misc/optimization variables type(T_Tree), intent(inout) :: Tree !< Tree of particles if needed type(T_Part), intent(inout) :: Part !< Particle storage if needed integer(IntKi), intent( out) :: ErrStat !< Error status of the operation character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + logical, intent(in ) :: deallocPart + integer, parameter :: iVel = 1 ! Local variables ErrStat= ErrID_None ErrMsg ='' - if (p%VelocityMethod==idVelocityBasic) then + if (p%VelocityMethod(iVel)==idVelocityBasic) then ! Nothing - elseif (p%VelocityMethod==idVelocityTree) then + elseif (p%VelocityMethod(iVel)==idVelocityTreePart) then + if (deallocPart) deallocate(Part%P, Part%Alpha, Part%RegParam) call cut_tree(Tree) - deallocate(Part%P, Part%Alpha, Part%RegParam) - elseif (p%VelocityMethod==idVelocityPart) then - deallocate(Part%P, Part%Alpha, Part%RegParam) - elseif (p%VelocityMethod==idVelocityTreeSeg) then - call cut_tree(Tree) + elseif (p%VelocityMethod(iVel)==idVelocityPart) then + if (deallocPart) deallocate(Part%P, Part%Alpha, Part%RegParam) + + elseif (p%VelocityMethod(iVel)==idVelocityTreeSeg) then + call cut_tree(Tree) ! We do not deallocate segment endif end subroutine InducedVelocitiesAll_End @@ -1149,13 +1348,15 @@ subroutine WakeInducedVelocities(p, x, m, ErrStat, ErrMsg) character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None ! Local variables integer(IntKi) :: iW, nCPs, iHeadP - integer(IntKi) :: nFWEff ! Number of farwake panels that are free at current tmie step + integer(IntKi) :: nFWEff ! Number of farwake panels that are free at current time step + integer(IntKi) :: nNWEff ! Number of nearwake panels that are free at current time step type(T_Tree) :: Tree - type(T_Part) :: Part + if (OLAF_PROFILING) call tic('WakeInduced Calc') ErrStat= ErrID_None ErrMsg ='' nFWEff = min(m%nFW, p%nFWFree) + nNWEff = min(m%nNW, p%nNWFree) ! --- Pack control points call PackConvectingPoints() ! m%CPs @@ -1163,24 +1364,26 @@ subroutine WakeInducedVelocities(p, x, m, ErrStat, ErrMsg) ! --- Compute induced velocity ! Convert Panels to segments, segments to particles, particles to tree m%Uind=0.0_ReKi ! very important due to side effects of ui_* methods - call InducedVelocitiesAll_Init(p, x, m, m%Sgmt, Part, Tree, ErrStat, ErrMsg) - call InducedVelocitiesAll_Calc(m%CPs, nCPs, m%Uind, p, m%Sgmt, Part, Tree, ErrStat, ErrMsg) - call InducedVelocitiesAll_End(p, m, Tree, Part, ErrStat, ErrMsg) + m%Uind(:,nCPs+1:)=1000.0_ReKi ! TODO For debugging only + call InducedVelocitiesAll_Init(p, x, m, m%Sgmt, m%Part, Tree, ErrStat, ErrMsg, allocPart=.false.) + call InducedVelocitiesAll_Calc(m%CPs, nCPs, m%Uind, p, m%Sgmt, m%Part, Tree, ErrStat, ErrMsg) + call InducedVelocitiesAll_End(p, Tree, m%Part, ErrStat, ErrMsg, deallocPart=.false.) call UnPackInducedVelocity() if (DEV_VERSION) then print'(A,I0,A,I0,A,I0)','Convection - nSeg:',m%Sgmt%nAct,' - nSegP:',m%Sgmt%nActP, ' - nCPs:',nCPs endif + if (OLAF_PROFILING) call toc() contains !> Pack all the points that convect subroutine PackConvectingPoints() ! Counting total number of control points that convects - nCPs = CountCPs(p, m%nNW, nFWEff) + nCPs = CountCPs(p, nNWEff, nFWEff) m%CPs=-999.9_ReKi ! Packing iHeadP=1 do iW=1,p%nWings - CALL LatticeToPoints(x%W(iW)%r_NW(1:3,:,1:m%nNW+1), 1, m%CPs, iHeadP) + CALL LatticeToPoints(x%W(iW)%r_NW(1:3,:,1:nNWEff+1), 1, m%CPs, iHeadP) enddo if (nFWEff>0) then do iW=1,p%nWings @@ -1193,11 +1396,15 @@ subroutine PackConvectingPoints() call print_x_NW_FW(p,m,x,'pack') ErrMsg='PackConvectingPoints: Problem in Control points'; ErrStat=ErrID_Fatal; return endif - if ((iHeadP-1)/=nCPs) then - print*,'PackConvectingPoints: Number of points wrongly estimated',nCPs, iHeadP-1 - STOP ! Keep me. The check will be removed once the code is well established - ErrMsg='PackConvectingPoints: Number of points wrongly estimated '; ErrStat=ErrID_Fatal; return + if (p%nNWMax==p%nNWFree) then + ! Number of CP should be number of SegP + if ((iHeadP-1)/=nCPs) then + print*,'PackConvectingPoints: Number of points wrongly estimated',nCPs, iHeadP-1 + STOP ! Keep me. The check will be removed once the code is well established + ErrMsg='PackConvectingPoints: Number of points wrongly estimated '; ErrStat=ErrID_Fatal; return + endif endif + call find_nan_2D(m%CPs(:,1:nCPs), 'WakeInducedVel CPs') endif end subroutine !> Distribute the induced velocity to the proper location @@ -1205,10 +1412,11 @@ subroutine UnPackInducedVelocity() do iW=1,p%nWings m%W(iW)%Vind_NW = -9999._ReKi !< Safety m%W(iW)%Vind_FW = -9999._ReKi !< Safety + m%W(iW)%Vind_NW(:,:,p%nNWFree+1:) = 2222._ReKi !< Safety enddo iHeadP=1 do iW=1,p%nWings - CALL VecToLattice(m%Uind, 1, m%W(iW)%Vind_NW(:,:,1:m%nNW+1), iHeadP) + CALL VecToLattice(m%Uind, 1, m%W(iW)%Vind_NW(:,:,1:nNWEff+1), iHeadP) enddo if (nFWEff>0) then do iW=1,p%nWings @@ -1223,11 +1431,15 @@ subroutine UnPackInducedVelocity() endif endif if (DEV_VERSION) then - if ((iHeadP-1)/=nCPs) then - print*,'UnPackInducedVelocity: Number of points wrongly estimated',nCPs, iHeadP-1 - STOP ! Keep me. The check will be removed once the code is well established - ErrMsg='UnPackInducedVelocity: Number of points wrongly estimated'; ErrStat=ErrID_Fatal; return + if (p%nNWMax==p%nNWFree) then + ! Number of CP should be number of SegP + if ((iHeadP-1)/=nCPs) then + print*,'UnPackInducedVelocity: Number of points wrongly estimated',nCPs, iHeadP-1 + STOP ! Keep me. The check will be removed once the code is well established + ErrMsg='UnPackInducedVelocity: Number of points wrongly estimated'; ErrStat=ErrID_Fatal; return + endif endif + call find_nan_2D(m%Uind(:,:), 'WakeInducedVel Uind') endif end subroutine @@ -1243,16 +1455,20 @@ subroutine LiftingLineInducedVelocities(p, x, InductionAtCP, iDepthStart, m, Err logical, intent(in ) :: InductionAtCP !< Compute induction at CP or on LL nodes integer(IntKi), intent(in ) :: iDepthStart !< Index where we start packing for NW panels type(FVW_MiscVarType), intent(inout) :: m !< Initial misc/optimization variables - !real(ReKi), dimension(:,:,:), intent( out) :: Vind_CP !< Control points where velocity is to be evaluated + integer(IntKi), intent( out) :: ErrStat !< Error status of the operation + character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None ! Local variables integer(IntKi) :: iW, nSeg, nSegP, nCPs, iHeadP + real(ReKi) :: MaxWingLength, DistanceDirect !< Maximum wing length, used to determined distance for direct evaluation of tree real(ReKi), dimension(:,:), allocatable :: CPs !< ControlPoints real(ReKi), dimension(:,:), allocatable :: Uind !< Induced velocity - integer(IntKi), intent( out) :: ErrStat !< Error status of the operation - character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None - logical :: bMirror + type(T_Tree) :: Tree !< Tree of particles/segment if needed + integer, parameter :: iVel = 2 + logical :: bMirror + if (OLAF_PROFILING) call tic('LiftingLine UI Calc') ErrStat = ErrID_None ErrMsg = "" + do iW=1,p%nWings m%W(iW)%Vind_CP = -9999._ReKi !< Safety m%W(iW)%Vind_LL = -9999._ReKi !< Safety @@ -1261,6 +1477,9 @@ subroutine LiftingLineInducedVelocities(p, x, InductionAtCP, iDepthStart, m, Err ! --- Packing all vortex elements into a list of segments call PackPanelsToSegments(p, x, iDepthStart, bMirror, m%nNW, m%nFW, m%Sgmt%Connct, m%Sgmt%Points, m%Sgmt%Gamma, m%Sgmt%Epsilon, nSeg, nSegP) + m%Sgmt%RegFunction=p%RegFunction + m%Sgmt%nAct = nSeg + m%Sgmt%nActP = nSegP ! --- Computing induced velocity if (nSegP==0) then @@ -1283,20 +1502,54 @@ subroutine LiftingLineInducedVelocities(p, x, InductionAtCP, iDepthStart, m, Err nCPs = nCPs + p%W(iW)%nSpan+1 enddo endif + allocate(CPs (1:3,1:nCPs)) ! NOTE: here we do allocate CPs and Uind insteadof using Misc allocate(Uind(1:3,1:nCPs)) ! The size is reasonably small, and m%Uind then stay filled with "rollup velocities" (for export) Uind=0.0_ReKi !< important due to side effects of ui_seg - ! --- + + ! --- Pack call PackLiftingLinePoints() if (DEV_VERSION) then print'(A,I0,A,I0,A,I0)','Induction - nSeg:',nSeg,' - nSegP:',nSegP, ' - nCPs:',nCPs endif - call ui_seg( 1, nCPs, CPs, 1, nSeg, nSeg, nSegP, m%Sgmt%Points, m%Sgmt%Connct, m%Sgmt%Gamma, m%Sgmt%RegFunction, m%Sgmt%Epsilon, Uind) + + ! --- Compute maximum wing length + MaxWingLength = 0.0_ReKi + do iW=1,p%nWings + MaxWingLength = max(MaxWingLength, p%W(iW)%s_LL(p%W(iW)%nSpan+1)-p%W(iW)%s_LL(1)) ! Using curvilinear variable for length... + enddo + DistanceDirect = MaxWingLength*2.2_ReKi ! Using ~2*R+margin so that an entire rotor will be part of a direct evaluation + + ! --- Compute velocity on LL + ! TreeSeg is faster but introduce some noise, so we keep this open for the user to choose + if (p%VelocityMethod(iVel) == idVelocityBasic) then + call ui_seg( 1, nCPs, CPs, 1, nSeg, m%Sgmt%Points, m%Sgmt%Connct, m%Sgmt%Gamma, m%Sgmt%RegFunction, m%Sgmt%Epsilon, Uind) + + else if (p%VelocityMethod(iVel) == idVelocityPart) then + call SegmentsToPartWrap(m%Sgmt, nSeg, p%PartPerSegment(iVel), p%RegFunction, m%Part, allocPart=.false.) + call ui_part_nograd(nCPs, CPs, m%Part%nAct, m%Part%P, m%Part%Alpha, m%Part%RegFunction, m%Part%RegParam, Uind) + !deallocate(Part%P, Part%Alpha, Part%RegParam) + + else if (p%VelocityMethod(iVel) == idVelocityTreeSeg) then + call grow_tree_segment(Tree, nSeg, m%Sgmt%Points, m%Sgmt%Connct(:,1:nSeg), m%Sgmt%Gamma(1:nSeg), m%Sgmt%RegFunction, m%Sgmt%Epsilon(1:nSeg), 0) + call ui_tree_segment(Tree, CPs, nCPs, p%TreeBranchFactor(iVel), DistanceDirect, Uind, ErrStat, ErrMsg) + call cut_tree(Tree) + + else if (p%VelocityMethod(iVel) == idVelocityTreePart) then + call SegmentsToPartWrap(m%Sgmt, nSeg, p%PartPerSegment(iVel), p%RegFunction, m%Part, allocPart=.false.) + call grow_tree_part(Tree, m%Part%nAct, m%Part%P, m%Part%Alpha, m%Part%RegFunction, m%Part%RegParam, 0) + call ui_tree_part(Tree, nCPs, CPs, p%TreeBranchFactor(iVel), DistanceDirect, Uind, ErrStat, ErrMsg) + !deallocate(Part%P, Part%Alpha, Part%RegParam) + call cut_tree(Tree) + endif + + ! --- Unpack call UnPackLiftingLineVelocities() deallocate(Uind) deallocate(CPs) endif + if (OLAF_PROFILING) call toc() contains !> Pack all the control points subroutine PackLiftingLinePoints() @@ -1315,6 +1568,7 @@ subroutine PackLiftingLinePoints() print*,'PackLLPoints: Number of points wrongly estimated',size(CPs,2), iHeadP-1 STOP ! Keep me. The check will be removed once the code is well established endif + call find_nan_2D(CPs, 'LiftingLineInducedVel CPs') endif nCPs=iHeadP-1 end subroutine @@ -1349,6 +1603,7 @@ subroutine UnPackLiftingLineVelocities() print*,'UnPackLiftingLineVelocities: Number of points wrongly estimated',size(Uind,2), iHeadP-1 STOP ! Keep me. The check will be removed once the code is well established endif + call find_nan_2D(Uind, 'LiftingLineInducedVel Uind') endif end subroutine end subroutine @@ -1365,11 +1620,19 @@ subroutine FakeGroundEffect(p, x, m, ErrStat, ErrMsg) character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None integer(IntKi) :: iAge, iW, iSpan integer(IntKi) :: nBelow - real(ReKi), parameter:: GROUND = 1.e-4_ReKi - real(ReKi), parameter:: ABOVE_GROUND = 0.1_ReKi + real(ReKi) :: GROUND + real(ReKi) :: ABOVE_GROUND ErrStat = ErrID_None ErrMsg = "" + if ( p%MHK == 1 .or. p%MHK == 2 ) then + GROUND = 1.e-4_ReKi - p%WtrDpth + ABOVE_GROUND = 0.1_ReKi - p%WtrDpth + else + GROUND = 1.e-4_ReKi + ABOVE_GROUND = 0.1_ReKi + endif + nBelow=0 do iW = 1,p%nWings do iAge = 1,m%nNW+1 @@ -1405,7 +1668,7 @@ end subroutine FakeGroundEffect !! - M_sg : from global to section (this is ill-defined), this coordinate is used to define the "axial" and "tangential" inductions subroutine FVW_AeroOuts( M_sg, M_ag, PitchAndTwist, Vstr_g, Vind_g, Vwnd_g, KinVisc, Chord, & AxInd, TanInd, Vrel_norm, phi, alpha, Re, Urel_s, ErrStat, ErrMsg ) - real(ReKi), intent(in ) :: M_sg(3,3) ! m%WithoutSweepPitchTwist global coord to "section" coord + real(R8Ki), intent(in ) :: M_sg(3,3) ! m%WithoutSweepPitchTwist global coord to "section" coord real(R8Ki), intent(in ) :: M_ag(3,3) ! u%BladeMotion(k)%Orientation(1:3,1:3,j) global coord to airfoil coord real(ReKi), intent(in ) :: PitchAndTwist ! Pitch and twist of section real(ReKi), intent(in ) :: Vstr_g(3) ! Structural velocity global coord diff --git a/modules/aerodyn/src/FVW_Tests.f90 b/modules/aerodyn/src/FVW_Tests.f90 index 450c23e9b..6de6f7dff 100644 --- a/modules/aerodyn/src/FVW_Tests.f90 +++ b/modules/aerodyn/src/FVW_Tests.f90 @@ -8,7 +8,7 @@ module FVW_Tests use FVW_Wings use FVW_IO use FVW_BiotSavart - use FVW_VTK, only : FVW_VTK_Misc + use VTK, only : VTK_Misc implicit none @@ -266,7 +266,7 @@ subroutine Test_BiotSavart_Sgmt(testname, ErrStat, ErrMsg) ! Method 1 Uind_out =0.0_ReKi call ui_seg(1, 1, CPs, & - 1, 1, nSegTot, nSegPTot, SegPoints, SegConnct, SegGamma, & + 1, 1, SegPoints, SegConnct, SegGamma, & RegFunction, RegParam, Uind_out) ! Method 2 call ui_seg_11(CP-P1, CP-P2, SegGamma1, RegFunction, RegParam1, U1) @@ -306,7 +306,7 @@ subroutine Test_BiotSavart_Sgmt(testname, ErrStat, ErrMsg) ! Method 1 Uind_out =0.0_ReKi call ui_seg(1, 1, CPs, & - 1, 2, nSegTot, nSegPTot, SegPoints, SegConnct, SegGamma, & + 1, 2, SegPoints, SegConnct, SegGamma, & RegFunction, RegParam, Uind_out) ! Method 2 call ui_seg_11(CP-P1, CP-P2, SegGamma1, RegFunction, RegParam1, U1) @@ -361,7 +361,7 @@ subroutine Test_BiotSavart_Part(testname, ErrStat, ErrMsg) RegFunction = idRegPartVALID(i1) ! Method 1 Uind_out =0.0_ReKi - call ui_part_nograd(CPs,PartPoints, PartAlpha, RegFunction, RegParam, Uind_out, nCPs, nPart) + call ui_part_nograd(nCPS, CPs, nPart, PartPoints, PartAlpha, RegFunction, RegParam, Uind_out) ! Method 2 call ui_part_nograd_11(CP-P1, PartAlpha1, RegFunction, RegParam1, U1) ! Test @@ -406,10 +406,10 @@ subroutine Test_BiotSavart_PartTree(testname, ErrStat, ErrMsg) Uind1 =0.0_ReKi Uind2 =0.0_ReKi U_ref =0.0_ReKi - call grow_tree(Tree, PartPoints, PartAlpha, RegFunction, RegParam, 0) + call grow_tree_part(Tree, nPart, PartPoints, PartAlpha, RegFunction, RegParam, 0) !call print_tree(Tree) - call ui_tree(Tree, CPs, 0, 1, nCPs, BranchFactor, BranchSmall, Uind2, ErrStat, ErrMsg) - call ui_part_nograd(CPs,PartPoints, PartAlpha, RegFunction, RegParam, Uind1, nCPs, nPart) + call ui_tree_part(Tree, nCPs, CPs, BranchFactor, BranchSmall, Uind2, ErrStat, ErrMsg) + call ui_part_nograd(nCPS, CPs, nPart, PartPoints, PartAlpha, RegFunction, RegParam, Uind1) ! Test call test_almost_equal(testname,'Uind tree 0 part', U_ref, Uind2(:,1), 1e-4_ReKi, .true.,.true.) call cut_tree(Tree) @@ -422,10 +422,10 @@ subroutine Test_BiotSavart_PartTree(testname, ErrStat, ErrMsg) CPs(:,1) = (/0.0,0.0,0.0/) PartPoints(1:3,1) = (/1.0,0.0,0.0/) U_ref =0.0_ReKi - call grow_tree(Tree, PartPoints, PartAlpha, RegFunction, RegParam, 0) + call grow_tree_part(Tree, nPart, PartPoints, PartAlpha, RegFunction, RegParam, 0) !call print_tree(Tree) - call ui_tree(Tree, CPs, 0, 1, nCPs, BranchFactor, BranchSmall, Uind2, ErrStat, ErrMsg) - call ui_part_nograd(CPs,PartPoints, PartAlpha, RegFunction, RegParam, Uind1, nCPs, nPart) + call ui_tree_part(Tree, nCPs, CPs, BranchFactor, BranchSmall, Uind2, ErrStat, ErrMsg) + call ui_part_nograd(nCPS, CPs, nPart, PartPoints, PartAlpha, RegFunction, RegParam, Uind1) ! Test call test_almost_equal(testname,'Uind tree 1 part', Uind1, Uind2, 1e-4_ReKi, .true.,.true.) call cut_tree(Tree) @@ -452,20 +452,20 @@ subroutine Test_BiotSavart_PartTree(testname, ErrStat, ErrMsg) CPs_test(:,4) = (/ 2.0, 2.0, 2.0 /) ! Starts to be far from most points CPs_test(:,5) = (/ 10., 10., 10.0 /) ! Far from all - call grow_tree(Tree, PartPoints, PartAlpha, RegFunction, RegParam, 0) + call grow_tree_part(Tree, nPart, PartPoints, PartAlpha, RegFunction, RegParam, 0) !call print_tree(Tree) do iCP=1,4 CPs(:,1) = CPs_test(:,icp) Uind2=0.0_ReKi; Uind1=0.0_ReKi - call ui_tree(Tree, CPs, 0, 1, nCPs, BranchFactor, BranchSmall, Uind2, ErrStat, ErrMsg) - call ui_part_nograd(CPs,PartPoints, PartAlpha, RegFunction, RegParam, Uind1, nCPs, nPart) + call ui_tree_part(Tree, nCPs, CPs, BranchFactor, BranchSmall, Uind2, ErrStat, ErrMsg) + call ui_part_nograd(nCPs, CPs, nPart, PartPoints, PartAlpha, RegFunction, RegParam, Uind1) !print*,'Uind',Uind1, Uind2 ! Test call test_almost_equal(testname,'Uind tree 81 part', Uind1, Uind2, 1e-2_ReKi, .true.,.true.) enddo call cut_tree(Tree) ! --- Test that tree ui cannot be called after tree has been cut - call ui_tree(Tree, CPs, 0, 1, nCPs, BranchFactor, BranchSmall, Uind2, ErrStat, ErrMsg) + call ui_tree_part(Tree, nCPs, CPs, BranchFactor, BranchSmall, Uind2, ErrStat, ErrMsg) call test_equal(testname,'Err. stat tree cut',ErrStat,ErrID_Fatal) call dealloc() @@ -542,8 +542,8 @@ subroutine Test_SegmentsToPart(testname, ErrStat, ErrMsg) call SegmentsToPart(SegPoints, SegConnct, SegGamma, SegEpsilon, 1, nSegTot, nPartPerSeg, PartPoints, PartAlpha, PartEpsilon, iHeadP) Uind1 =0.0_ReKi; Uind2 =0.0_ReKi; - call ui_seg(1, nCPsTot, CPs, 1, nSegTot, nSegTot, nSegPTot, SegPoints, SegConnct, SegGamma, RegFunctionSeg, SegEpsilon, Uind1) - call ui_part_nograd(CPs,PartPoints, PartAlpha, RegFunctionPart, PartEpsilon, Uind2, nCPsTot, nPart) + call ui_seg(1, nCPsTot, CPs, 1, nSegTot, SegPoints, SegConnct, SegGamma, RegFunctionSeg, SegEpsilon, Uind1) + call ui_part_nograd(nCPSTot, CPs, nPart, PartPoints, PartAlpha, RegFunctionPart, PartEpsilon, Uind2) call test_almost_equal(testname,'Uind 10 part/sgmt no reg', Uind1, Uind2, 1e-3_ReKi, .true.,.true.) call dealloc() @@ -558,8 +558,8 @@ subroutine Test_SegmentsToPart(testname, ErrStat, ErrMsg) call SegmentsToPart(SegPoints, SegConnct, SegGamma, SegEpsilon, 1, nSegTot, nPartPerSeg, PartPoints, PartAlpha, PartEpsilon, iHeadP) Uind1 =0.0_ReKi; Uind2 =0.0_ReKi; - call ui_seg(1, nCPsTot, CPs, 1, nSegTot, nSegTot, nSegPTot, SegPoints, SegConnct, SegGamma, RegFunctionSeg, SegEpsilon, Uind1) - call ui_part_nograd(CPs,PartPoints, PartAlpha, RegFunctionPart, PartEpsilon, Uind2, nCPsTot, nPart) + call ui_seg(1, nCPsTot, CPs, 1, nSegTot, SegPoints, SegConnct, SegGamma, RegFunctionSeg, SegEpsilon, Uind1) + call ui_part_nograd(nCPsTot, CPs, nPart, PartPoints, PartAlpha, RegFunctionPart, PartEpsilon, Uind2) call test_almost_equal(testname,'Uind 2 part/sgmt noreg', Uind1, Uind2, 3e-1_ReKi, .true.,.true.) call dealloc() @@ -576,8 +576,8 @@ subroutine Test_SegmentsToPart(testname, ErrStat, ErrMsg) call SegmentsToPart(SegPoints, SegConnct, SegGamma, SegEpsilon, 1, nSegTot, nPartPerSeg, PartPoints, PartAlpha, PartEpsilon, iHeadP) Uind1 =0.0_ReKi; Uind2 =0.0_ReKi; - call ui_seg(1, nCPsTot, CPs, 1, nSegTot, nSegTot, nSegPTot, SegPoints, SegConnct, SegGamma, RegFunctionSeg, SegEpsilon, Uind1) - call ui_part_nograd(CPs,PartPoints, PartAlpha, RegFunctionPart, PartEpsilon, Uind2, nCPsTot, nPart) + call ui_seg(1, nCPsTot, CPs, 1, nSegTot, SegPoints, SegConnct, SegGamma, RegFunctionSeg, SegEpsilon, Uind1) + call ui_part_nograd(nCPSTot, CPs, nPart, PartPoints, PartAlpha, RegFunctionPart, PartEpsilon, Uind2) !print'(A,10F7.3)','Uind1',Uind1(1,:) !print'(A,10F7.3)','Uind2',Uind2(1,:) !print'(A,10F7.3)','Uind1',Uind1(2,:) @@ -602,7 +602,7 @@ end subroutine Test_SegmentsToPart !> subroutine Test_LatticeToSegment(mvtk,iStat) - type(FVW_VTK_Misc),intent(inout) :: mvtk !< miscvars for VTK output + type(VTK_Misc),intent(inout) :: mvtk !< miscvars for VTK output integer(IntKi), intent( out) :: iStat !< Status for test ! Local integer(IntKi),dimension(:,:), allocatable :: SegConnct !< Segment connectivity @@ -681,7 +681,7 @@ subroutine Test_LatticeToSegment(mvtk,iStat) SegEpsilon=100.0_ReKi SmoothModel=0 ! No smooth CALL ui_seg(1, 1, CPs, & - 1, nC1, nC1, nP1, SegPoints, SegConnct, SegGamma, & + 1, nC1, SegPoints, SegConnct, SegGamma, & SmoothModel, SegEpsilon, Uind) !print*,'Uind',Uind @@ -745,6 +745,102 @@ subroutine MeshMe(M,offset) endsubroutine endsubroutine Test_LatticeToSegment + !> Test Wake Induced velocity calcualtion when using nNWMax or nNWFree + !! A dummy helical wake is created. The induced velocity is computed on + !! either the full wake, or just the "free" wake (which should be way faster) + subroutine FVW_Test_WakeInducedVelocities(ErrStat, ErrMsg) + integer(IntKi) , intent(out) :: ErrStat !< Error status of the operation + character(ErrMsgLen), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + type(FVW_ParameterType) :: p !< Parameters + type(FVW_ContinuousStateType) :: x !< States + type(FVW_MiscVarType) :: m !< Initial misc/optimization variables + !type(FVW_VTK_Misc) :: mvtk + integer :: iW, j, k, nSpan + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + character(*), parameter :: RoutineName = 'FVW_Test_CPUTime' + integer(ReKi), parameter :: nR = 20 + real(ReKi), parameter :: R = 100 + real(ReKi), parameter :: G = 100 + real(ReKi), allocatable, dimension(:,:) :: V1 + real(ReKi), allocatable, dimension(:,:) :: V2 + real(ReKi) :: t1,t2 + ErrStat = ErrID_None + ErrMsg = "" + + ! --- Create a helical wake TODO, put me into FVW_* + p%nWings = 3 + p%nNWMax = 1600 + nSpan = 50 + m%nNW = p%nNWMax + m%nFW = 0 + p%nFWMax = 0 + p%nFWFree = 0 + p%ShearModel = idShearNone + p%RegFunction = idRegVatistas + p%VelocityMethod = idVelocityTreePart + p%FWShedVorticity = .false. + p%TreeBranchFactor = 1.5_ReKi + p%PartPerSegment = 1 + allocate(p%W(p%nWings)) + p%W(:)%nSpan = nSpan + call FVW_InitStates( x, p, ErrStat, ErrMsg ) + do iW=1,size(x%W); + do j=1,size(x%W(iW)%r_NW,2); + do k=1,size(x%W(iW)%r_NW,3); + x%W(iW)%r_NW(1,j,k) = real(k, ReKi)/p%nNWMax*(nR*R) + x%W(iW)%r_NW(2,j,k) = real(j, ReKi)/nSpan*R*cos(iW*TwoPi/p%nWings + x%W(iW)%r_NW(1,j,k)/R*0.5) + x%W(iW)%r_NW(3,j,k) = real(j, ReKi)/nSpan*R*sin(iW*TwoPi/p%nWings + x%W(iW)%r_NW(1,j,k)/R*0.5) + 1.5*R + enddo + enddo + do j=1,size(x%W(iW)%r_NW,2)-1 + do k=1,size(x%W(iW)%r_NW,3)-1 + x%W(iW)%Gamma_NW(j,k) = G*4.0_ReKi*(real((j-1),ReKi)/nSpan -0.5)**2 + x%W(iW)%Eps_NW(:,j,k) = 0.03*R*(real(k,ReKi)/p%nNWMax) + enddo + enddo + enddo + allocate(m%W(p%nWings)) + do iW = 1,p%nWings + call AllocAry( m%W(iW)%Vind_NW , 3 , nSpan+1 ,p%nNWMax+1, 'Vind on NW ', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName); m%W(iW)%Vind_NW= -999_ReKi; + call AllocAry( m%W(iW)%Vind_FW , 3 , FWnSpan+1,p%nFWMax+1, 'Vind on FW ', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName); m%W(iW)%Vind_FW= -999_ReKi; + enddo + call FVW_InitMiscVarsPostParam( p, m, ErrStat2, ErrMsg2) ! Alloc Sgmt, CPs, Uind + + ! --- Compute induced velocity on full wake + allocate(V1(3,nSpan+1)) + p%nNWFree=p%nNWMax + call cpu_time(t1) + call WakeInducedVelocities(p, x, m, ErrStat2, ErrMsg2); + call cpu_time(t2) + print*,'Ellapsed time',t2-t1 + V1 = m%W(1)%Vind_NW(:,:,1) + + ! --- Compute induced velocity on free wake only + allocate(V2(3,nSpan+1)) + p%nNWFree=int(p%nNWMax/5) + call cpu_time(t1) + call WakeInducedVelocities(p, x, m, ErrStat2, ErrMsg2); + call cpu_time(t2) + print*,'Ellapsed time',t2-t1 + V2 = m%W(1)%Vind_NW(:,:,1) + !print*,'>>>Vx mean ',sum(abs((V1(1,:))))/nSpan + !print*,'>>>Vx mean ',sum(abs((V2(1,:))))/nSpan + !print*,'>>> Vx error',sum(abs(V1(1,:)-V2(1,:)))/nSpan + !print*,'>>> Vy error',sum(abs(V1(2,:)-V2(2,:)))/nSpan + !print*,'>>> Vz error',sum(abs(V1(3,:)-V2(3,:)))/nSpan + !call WrVTK_Segments('_TEST.vtk', mvtk, m%Sgmt%Points(:,:), m%Sgmt%Connct(:,:), m%Sgmt%Gamma(:), m%Sgmt%Epsilon(:), .false.) + + call test_almost_equal(RoutineName,'Uind nNW/nNWFree', V1, V2, 1e-6_ReKi, .true.,.true.) + + deallocate(V1) + deallocate(V2) + call FVW_DestroyParam(p, ErrStat2, ErrMsg2) + call FVW_DestroyContState(x, ErrStat2, ErrMsg2) + call FVW_DestroyMisc(m, ErrStat2, ErrMsg2) + + end subroutine FVW_Test_WakeInducedVelocities + !> Main test function subroutine FVW_RunTests(ErrStat,ErrMsg) integer(IntKi) , intent(out) :: ErrStat !< Error status of the operation @@ -760,6 +856,7 @@ subroutine FVW_RunTests(ErrStat,ErrMsg) call Test_BiotSavart_Part(testname, ErrStat2, ErrMsg2) call Test_BiotSavart_PartTree(testname, ErrStat2, ErrMsg2) call Test_SegmentsToPart(testname, ErrStat2, ErrMsg2) + call FVW_Test_WakeInducedVelocities(ErrStat2, ErrMsg2) end subroutine FVW_RunTests end module FVW_Tests diff --git a/modules/aerodyn/src/FVW_Types.f90 b/modules/aerodyn/src/FVW_Types.f90 index 72df451fa..40021d693 100644 --- a/modules/aerodyn/src/FVW_Types.f90 +++ b/modules/aerodyn/src/FVW_Types.f90 @@ -68,6 +68,15 @@ MODULE FVW_Types INTEGER(IntKi) :: nActP !< Number of active segment points [-] END TYPE T_Sgmt ! ======================= +! ========= T_Part ======= + TYPE, PUBLIC :: T_Part + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: P !< Particle Points [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Alpha !< Particle intensity 3 x nP [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: RegParam !< Particle regularization parameter [-] + INTEGER(IntKi) :: RegFunction !< Type of regularizaion function (FVW_BiotSavart) [-] + INTEGER(IntKi) :: nAct !< Number of active particles <=nP [-] + END TYPE T_Part +! ======================= ! ========= Wng_ParameterType ======= TYPE, PUBLIC :: Wng_ParameterType REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: chord_LL !< Chord of each blade element from input file [idx1=BladeNode, idx2=Blade number] [-] @@ -88,13 +97,14 @@ MODULE FVW_Types INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Bld2Wings !< Index mapping from blades to wings [-] INTEGER(IntKi) :: iNWStart !< Index where NW start in r_NW. (iNWStart=2, the first panel contains the lifting line panel, otherwise, start at 1) [-] INTEGER(IntKi) :: nNWMax !< Maximum number of nw panels, per wing [-] + INTEGER(IntKi) :: nNWFree !< Number of nw panels that are free, per wing [-] INTEGER(IntKi) :: nFWMax !< Maximum number of fw panels, per wing [-] INTEGER(IntKi) :: nFWFree !< Number of fw panels that are free, per wing [-] LOGICAL :: FWShedVorticity !< Include shed vorticity in the far wake [-] INTEGER(IntKi) :: IntMethod !< Integration Method (1=RK4, 2=AB4, 3=ABM4, 5=Euler1) [-] REAL(ReKi) :: FreeWakeStart !< Time when wake starts convecting (rolling up) [s] - REAL(ReKi) :: FullCirculationStart !< Time when the circulation is full [s] - INTEGER(IntKi) :: CirculationMethod !< Method to determine the circulation [-] + REAL(ReKi) :: FullCircStart !< Time when the circulation is full [s] + INTEGER(IntKi) :: CircSolvMethod !< Method to determine the circulation [-] INTEGER(IntKi) :: CircSolvMaxIter !< Maximum number of iterations for circulation solving [-] REAL(ReKi) :: CircSolvConvCrit !< Convergence criterion for circulation solving [-] REAL(ReKi) :: CircSolvRelaxation !< Relaxation factor for circulation solving [-] @@ -108,12 +118,14 @@ MODULE FVW_Types REAL(ReKi) :: WingRegParam !< Regularization parameter of the wing [-] INTEGER(IntKi) :: ShearModel !< Option for shear modelling [-] LOGICAL :: TwrShadowOnWake !< Include tower shadow effects on wake [-] - INTEGER(IntKi) :: VelocityMethod !< Velocity calculation method [-] - REAL(ReKi) :: TreeBranchFactor !< Factor used to determine if a point is far enough [-] - INTEGER(IntKi) :: PartPerSegment !< Number of particles per segment, e.g. for tree method [-] + INTEGER(IntKi) , DIMENSION(1:2) :: VelocityMethod !< Velocity calculation method for Full Wake and for LiftingLine [-] + REAL(ReKi) , DIMENSION(1:2) :: TreeBranchFactor !< Factor used to determine if a point is far enough, for full wake and lifting line [-] + INTEGER(IntKi) , DIMENSION(1:2) :: PartPerSegment !< Number of particles per segment, e.g. for tree method, for full wake and lifting line [-] REAL(DbKi) :: DTaero !< Time interval for calls calculations [s] REAL(DbKi) :: DTfvw !< Time interval for calculating wake induced velocities [s] REAL(ReKi) :: KinVisc !< Kinematic air viscosity [m^2/s] + INTEGER(IntKi) :: MHK !< MHK flag [-] + REAL(ReKi) :: WtrDpth !< Water depth [m] INTEGER(IntKi) :: WrVTK !< Outputs VTK at each calcoutput call, even if main fst doesnt do it [-] INTEGER(IntKi) :: VTKBlades !< Outputs VTk for each blade 0=no blade, 1=Bld 1 [-] REAL(DbKi) :: DTvtk !< DT between vtk writes [s] @@ -122,10 +134,12 @@ MODULE FVW_Types CHARACTER(1024) :: VTK_OutFileRoot !< Rootdirectory for writing VTK files [-] CHARACTER(1024) :: VTK_OutFileBase !< Basename for writing VTK files [-] INTEGER(IntKi) :: nGridOut !< Number of VTK grid to output [-] - LOGICAL :: InductionAtCP !< Compute induced velocities at nodes or CP [-] - LOGICAL :: WakeAtTE !< Start the wake at the trailing edge, or at the LL [-] - LOGICAL :: DStallOnWake !< Dynamic stall has influence on wake [-] - LOGICAL :: Induction !< Compute induction [-] + LOGICAL :: InductionAtCP = .true. !< Compute induced velocities at nodes or CP [-] + LOGICAL :: WakeAtTE = .true. !< Start the wake at the trailing edge, or at the LL [-] + LOGICAL :: DStallOnWake = .false. !< Dynamic stall has influence on wake [-] + LOGICAL :: Induction = .true. !< Compute induction [-] + REAL(ReKi) :: kFrozenNWStart = 0.75 !< Fraction of wake induced velocity at start of frozen wake. 1 seems too strong. [-] + REAL(ReKi) :: kFrozenNWEnd = 0.5 !< Fraction of wake induced velocity at end of frozen wake [-] END TYPE FVW_ParameterType ! ======================= ! ========= Wng_ContinuousStateType ======= @@ -194,6 +208,7 @@ MODULE FVW_Types REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BN_Cl_Static !< Coefficient lift, excluding unsteady aero effects [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BN_Cd_Static !< Coefficient drag. excluding unsteady aero effects [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BN_Cm_Static !< Coefficient moment, excluding unsteady aero effects [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BN_Cpmin !< Coefficient minimum pressure, excluding unsteady aero effects [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BN_Cl !< Coefficient lift, including unsteady aero effects [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BN_Cd !< Coefficient drag, including unsteady aero effects [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BN_Cm !< Coefficient moment, including unsteady aero effects [-] @@ -220,6 +235,7 @@ MODULE FVW_Types REAL(DbKi) :: t2 !< Time of x2 t+DTFVW (for overcycling) [-] LOGICAL :: UA_Flag !< logical flag indicating whether to use UnsteadyAero [-] TYPE(T_Sgmt) :: Sgmt !< Segments storage [-] + TYPE(T_Part) :: Part !< Particle storage [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: CPs !< Control points used for wake rollup computation [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Uind !< Induced velocities obtained at control points [-] TYPE(GridOutType) , DIMENSION(:), ALLOCATABLE :: GridOutputs !< Number of VTK grid to output [-] @@ -247,7 +263,7 @@ MODULE FVW_Types ! ======================= ! ========= FVW_DiscreteStateType ======= TYPE, PUBLIC :: FVW_DiscreteStateType - REAL(ReKi) :: NULL !< Empty to satisfy framework [-] + REAL(ReKi) :: Dummy !< Empty to satisfy framework [-] TYPE(UA_DiscreteStateType) , DIMENSION(:), ALLOCATABLE :: UA !< states for UnsteadyAero for each Wing [-] END TYPE FVW_DiscreteStateType ! ======================= @@ -264,7 +280,7 @@ MODULE FVW_Types ! ======================= ! ========= FVW_OtherStateType ======= TYPE, PUBLIC :: FVW_OtherStateType - INTEGER(IntKi) :: NULL !< Number of active near wake panels [-] + INTEGER(IntKi) :: Dummy !< Empty to satisfy framework [-] TYPE(UA_OtherStateType) , DIMENSION(:), ALLOCATABLE :: UA !< other states for UnsteadyAero for each wing [-] END TYPE FVW_OtherStateType ! ======================= @@ -287,6 +303,8 @@ MODULE FVW_Types INTEGER(IntKi) :: numBladeNodes !< Number of nodes on each blade [-] REAL(DbKi) :: DTaero !< Time interval for calls (from AD15) [s] REAL(ReKi) :: KinVisc !< Kinematic air viscosity [m^2/s] + INTEGER(IntKi) :: MHK !< MHK flag [-] + REAL(ReKi) :: WtrDpth !< Water depth [m] INTEGER(IntKi) :: UAMod !< Model for the dynamic stall equations [1 = Leishman/Beddoes, 2 = Gonzalez, 3 = Minnema] [-] LOGICAL :: UA_Flag !< logical flag indicating whether to use UnsteadyAero [-] LOGICAL :: Flookup !< Use table lookup for f' and f'' [-] @@ -296,7 +314,7 @@ MODULE FVW_Types ! ======================= ! ========= FVW_InputFile ======= TYPE, PUBLIC :: FVW_InputFile - INTEGER(IntKi) :: CirculationMethod !< Method to determine the circulation [-] + INTEGER(IntKi) :: CircSolvMethod !< Method to determine the circulation [-] CHARACTER(1024) :: CirculationFile !< Prescribed circulation file [-] INTEGER(IntKi) :: CircSolvMaxIter !< Maximum number of iterations for circulation solving [-] REAL(ReKi) :: CircSolvConvCrit !< Convergence criterion for circulation solving [-] @@ -304,10 +322,11 @@ MODULE FVW_Types INTEGER(IntKi) :: IntMethod !< Integration Method (1=RK4, 2=AB4, 3=ABM4, 5=Euler1, 7=Corrector/Predictor) [-] LOGICAL :: FreeWake !< Disable roll up, wake convects with wind only (flag) [-] REAL(ReKi) :: FreeWakeStart !< Time when wake starts convecting (rolling up) [s] - REAL(ReKi) :: FullCirculationStart !< Time when the circulation is full [s] + REAL(ReKi) :: FullCircStart !< Time when the circulation is full [s] REAL(DbKi) :: DTfvw !< Time interval for calculating wake induced velocities [s] INTEGER(IntKi) :: CircSolvPolar !< (0=Use AD polars, 1=2PiAlpha, 2=sin(2pialpha) [-] INTEGER(IntKi) :: nNWPanels !< Number of nw panels [-] + INTEGER(IntKi) :: nNWPanelsFree !< Number of nw panels [-] INTEGER(IntKi) :: nFWPanels !< Number of fw panels [-] INTEGER(IntKi) :: nFWPanelsFree !< Number of fw panels that are free [-] LOGICAL :: FWShedVorticity !< Include shed vorticity in the far wake [-] @@ -320,9 +339,9 @@ MODULE FVW_Types REAL(ReKi) :: WingRegParam !< Factor used in the regularization [-] INTEGER(IntKi) :: ShearModel !< Option for shear modelling [-] LOGICAL :: TwrShadowOnWake !< Include tower shadow effects on wake [-] - INTEGER(IntKi) :: VelocityMethod !< Velocity calculation method [-] - REAL(ReKi) :: TreeBranchFactor !< Factor used to determine if a point is far enough [-] - INTEGER(IntKi) :: PartPerSegment !< Number of particles per segment, e.g. for tree method [-] + INTEGER(IntKi) , DIMENSION(1:2) :: VelocityMethod !< Velocity calculation method for Full Wake and for LiftingLine [-] + REAL(ReKi) , DIMENSION(1:2) :: TreeBranchFactor !< Factor used to determine if a point is far enough, for full wake and lifting line [-] + INTEGER(IntKi) , DIMENSION(1:2) :: PartPerSegment !< Number of particles per segment, e.g. for tree method, for full wake and lifting line [-] INTEGER(IntKi) :: WrVTK !< Outputs VTK at each calcoutput call, even if main fst doesnt do it [-] INTEGER(IntKi) :: VTKBlades !< Outputs VTk for each blade 0=no blade, 1=Bld 1 [-] REAL(DbKi) :: DTvtk !< Requested timestep between VTK outputs (calculated from the VTK_fps read in) [s] @@ -331,7 +350,7 @@ MODULE FVW_Types ! ======================= ! ========= FVW_InitOutputType ======= TYPE, PUBLIC :: FVW_InitOutputType - INTEGER(IntKi) :: Null !< Empty parameter to satisfy framework [-] + INTEGER(IntKi) :: Dummy !< Empty parameter to satisfy framework [-] END TYPE FVW_InitOutputType ! ======================= CONTAINS @@ -406,15 +425,27 @@ SUBROUTINE FVW_CopyGridOutType( SrcGridOutTypeData, DstGridOutTypeData, CtrlCode DstGridOutTypeData%tLastOutput = SrcGridOutTypeData%tLastOutput END SUBROUTINE FVW_CopyGridOutType - SUBROUTINE FVW_DestroyGridOutType( GridOutTypeData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyGridOutType( GridOutTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(GridOutType), INTENT(INOUT) :: GridOutTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyGridOutType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyGridOutType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(GridOutTypeData%uGrid)) THEN DEALLOCATE(GridOutTypeData%uGrid) ENDIF @@ -807,15 +838,27 @@ SUBROUTINE FVW_CopyT_Sgmt( SrcT_SgmtData, DstT_SgmtData, CtrlCode, ErrStat, ErrM DstT_SgmtData%nActP = SrcT_SgmtData%nActP END SUBROUTINE FVW_CopyT_Sgmt - SUBROUTINE FVW_DestroyT_Sgmt( T_SgmtData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyT_Sgmt( T_SgmtData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(T_Sgmt), INTENT(INOUT) :: T_SgmtData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyT_Sgmt' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyT_Sgmt' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(T_SgmtData%Points)) THEN DEALLOCATE(T_SgmtData%Points) ENDIF @@ -1111,6 +1154,336 @@ SUBROUTINE FVW_UnPackT_Sgmt( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs Int_Xferred = Int_Xferred + 1 END SUBROUTINE FVW_UnPackT_Sgmt + SUBROUTINE FVW_CopyT_Part( SrcT_PartData, DstT_PartData, CtrlCode, ErrStat, ErrMsg ) + TYPE(T_Part), INTENT(IN) :: SrcT_PartData + TYPE(T_Part), INTENT(INOUT) :: DstT_PartData + 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 = 'FVW_CopyT_Part' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcT_PartData%P)) THEN + i1_l = LBOUND(SrcT_PartData%P,1) + i1_u = UBOUND(SrcT_PartData%P,1) + i2_l = LBOUND(SrcT_PartData%P,2) + i2_u = UBOUND(SrcT_PartData%P,2) + IF (.NOT. ALLOCATED(DstT_PartData%P)) THEN + ALLOCATE(DstT_PartData%P(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstT_PartData%P.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstT_PartData%P = SrcT_PartData%P +ENDIF +IF (ALLOCATED(SrcT_PartData%Alpha)) THEN + i1_l = LBOUND(SrcT_PartData%Alpha,1) + i1_u = UBOUND(SrcT_PartData%Alpha,1) + i2_l = LBOUND(SrcT_PartData%Alpha,2) + i2_u = UBOUND(SrcT_PartData%Alpha,2) + IF (.NOT. ALLOCATED(DstT_PartData%Alpha)) THEN + ALLOCATE(DstT_PartData%Alpha(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstT_PartData%Alpha.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstT_PartData%Alpha = SrcT_PartData%Alpha +ENDIF +IF (ALLOCATED(SrcT_PartData%RegParam)) THEN + i1_l = LBOUND(SrcT_PartData%RegParam,1) + i1_u = UBOUND(SrcT_PartData%RegParam,1) + IF (.NOT. ALLOCATED(DstT_PartData%RegParam)) THEN + ALLOCATE(DstT_PartData%RegParam(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstT_PartData%RegParam.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstT_PartData%RegParam = SrcT_PartData%RegParam +ENDIF + DstT_PartData%RegFunction = SrcT_PartData%RegFunction + DstT_PartData%nAct = SrcT_PartData%nAct + END SUBROUTINE FVW_CopyT_Part + + SUBROUTINE FVW_DestroyT_Part( T_PartData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(T_Part), INTENT(INOUT) :: T_PartData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyT_Part' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(T_PartData%P)) THEN + DEALLOCATE(T_PartData%P) +ENDIF +IF (ALLOCATED(T_PartData%Alpha)) THEN + DEALLOCATE(T_PartData%Alpha) +ENDIF +IF (ALLOCATED(T_PartData%RegParam)) THEN + DEALLOCATE(T_PartData%RegParam) +ENDIF + END SUBROUTINE FVW_DestroyT_Part + + SUBROUTINE FVW_PackT_Part( 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(T_Part), 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 = 'FVW_PackT_Part' + ! 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 ! P allocated yes/no + IF ( ALLOCATED(InData%P) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! P upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%P) ! P + END IF + Int_BufSz = Int_BufSz + 1 ! Alpha allocated yes/no + IF ( ALLOCATED(InData%Alpha) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Alpha upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Alpha) ! Alpha + END IF + Int_BufSz = Int_BufSz + 1 ! RegParam allocated yes/no + IF ( ALLOCATED(InData%RegParam) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! RegParam upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%RegParam) ! RegParam + END IF + Int_BufSz = Int_BufSz + 1 ! RegFunction + Int_BufSz = Int_BufSz + 1 ! nAct + 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%P) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%P,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%P,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%P,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%P,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%P,2), UBOUND(InData%P,2) + DO i1 = LBOUND(InData%P,1), UBOUND(InData%P,1) + ReKiBuf(Re_Xferred) = InData%P(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + 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 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Alpha,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Alpha,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Alpha,2), UBOUND(InData%Alpha,2) + DO i1 = LBOUND(InData%Alpha,1), UBOUND(InData%Alpha,1) + ReKiBuf(Re_Xferred) = InData%Alpha(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%RegParam) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%RegParam,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RegParam,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%RegParam,1), UBOUND(InData%RegParam,1) + ReKiBuf(Re_Xferred) = InData%RegParam(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IntKiBuf(Int_Xferred) = InData%RegFunction + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nAct + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE FVW_PackT_Part + + SUBROUTINE FVW_UnPackT_Part( 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(T_Part), 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 = 'FVW_UnPackT_Part' + ! 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 ! P not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%P)) DEALLOCATE(OutData%P) + ALLOCATE(OutData%P(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%P.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%P,2), UBOUND(OutData%P,2) + DO i1 = LBOUND(OutData%P,1), UBOUND(OutData%P,1) + OutData%P(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + 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 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Alpha)) DEALLOCATE(OutData%Alpha) + ALLOCATE(OutData%Alpha(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Alpha.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Alpha,2), UBOUND(OutData%Alpha,2) + DO i1 = LBOUND(OutData%Alpha,1), UBOUND(OutData%Alpha,1) + OutData%Alpha(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RegParam not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%RegParam)) DEALLOCATE(OutData%RegParam) + ALLOCATE(OutData%RegParam(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RegParam.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%RegParam,1), UBOUND(OutData%RegParam,1) + OutData%RegParam(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + OutData%RegFunction = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nAct = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE FVW_UnPackT_Part + SUBROUTINE FVW_CopyWng_ParameterType( SrcWng_ParameterTypeData, DstWng_ParameterTypeData, CtrlCode, ErrStat, ErrMsg ) TYPE(Wng_ParameterType), INTENT(IN) :: SrcWng_ParameterTypeData TYPE(Wng_ParameterType), INTENT(INOUT) :: DstWng_ParameterTypeData @@ -1205,15 +1578,27 @@ SUBROUTINE FVW_CopyWng_ParameterType( SrcWng_ParameterTypeData, DstWng_Parameter ENDIF END SUBROUTINE FVW_CopyWng_ParameterType - SUBROUTINE FVW_DestroyWng_ParameterType( Wng_ParameterTypeData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyWng_ParameterType( Wng_ParameterTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Wng_ParameterType), INTENT(INOUT) :: Wng_ParameterTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_ParameterType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_ParameterType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(Wng_ParameterTypeData%chord_LL)) THEN DEALLOCATE(Wng_ParameterTypeData%chord_LL) ENDIF @@ -1626,13 +2011,14 @@ SUBROUTINE FVW_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ENDIF DstParamData%iNWStart = SrcParamData%iNWStart DstParamData%nNWMax = SrcParamData%nNWMax + DstParamData%nNWFree = SrcParamData%nNWFree DstParamData%nFWMax = SrcParamData%nFWMax DstParamData%nFWFree = SrcParamData%nFWFree DstParamData%FWShedVorticity = SrcParamData%FWShedVorticity DstParamData%IntMethod = SrcParamData%IntMethod DstParamData%FreeWakeStart = SrcParamData%FreeWakeStart - DstParamData%FullCirculationStart = SrcParamData%FullCirculationStart - DstParamData%CirculationMethod = SrcParamData%CirculationMethod + DstParamData%FullCircStart = SrcParamData%FullCircStart + DstParamData%CircSolvMethod = SrcParamData%CircSolvMethod DstParamData%CircSolvMaxIter = SrcParamData%CircSolvMaxIter DstParamData%CircSolvConvCrit = SrcParamData%CircSolvConvCrit DstParamData%CircSolvRelaxation = SrcParamData%CircSolvRelaxation @@ -1652,6 +2038,8 @@ SUBROUTINE FVW_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%DTaero = SrcParamData%DTaero DstParamData%DTfvw = SrcParamData%DTfvw DstParamData%KinVisc = SrcParamData%KinVisc + DstParamData%MHK = SrcParamData%MHK + DstParamData%WtrDpth = SrcParamData%WtrDpth DstParamData%WrVTK = SrcParamData%WrVTK DstParamData%VTKBlades = SrcParamData%VTKBlades DstParamData%DTvtk = SrcParamData%DTvtk @@ -1664,20 +2052,35 @@ SUBROUTINE FVW_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%WakeAtTE = SrcParamData%WakeAtTE DstParamData%DStallOnWake = SrcParamData%DStallOnWake DstParamData%Induction = SrcParamData%Induction + DstParamData%kFrozenNWStart = SrcParamData%kFrozenNWStart + DstParamData%kFrozenNWEnd = SrcParamData%kFrozenNWEnd END SUBROUTINE FVW_CopyParam - SUBROUTINE FVW_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FVW_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%W)) THEN DO i1 = LBOUND(ParamData%W,1), UBOUND(ParamData%W,1) - CALL FVW_Destroywng_parametertype( ParamData%W(i1), ErrStat, ErrMsg ) + CALL FVW_Destroywng_parametertype( ParamData%W(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%W) ENDIF @@ -1754,13 +2157,14 @@ SUBROUTINE FVW_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S END IF Int_BufSz = Int_BufSz + 1 ! iNWStart Int_BufSz = Int_BufSz + 1 ! nNWMax + Int_BufSz = Int_BufSz + 1 ! nNWFree Int_BufSz = Int_BufSz + 1 ! nFWMax Int_BufSz = Int_BufSz + 1 ! nFWFree Int_BufSz = Int_BufSz + 1 ! FWShedVorticity Int_BufSz = Int_BufSz + 1 ! IntMethod Re_BufSz = Re_BufSz + 1 ! FreeWakeStart - Re_BufSz = Re_BufSz + 1 ! FullCirculationStart - Int_BufSz = Int_BufSz + 1 ! CirculationMethod + Re_BufSz = Re_BufSz + 1 ! FullCircStart + Int_BufSz = Int_BufSz + 1 ! CircSolvMethod Int_BufSz = Int_BufSz + 1 ! CircSolvMaxIter Re_BufSz = Re_BufSz + 1 ! CircSolvConvCrit Re_BufSz = Re_BufSz + 1 ! CircSolvRelaxation @@ -1774,12 +2178,14 @@ SUBROUTINE FVW_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Re_BufSz = Re_BufSz + 1 ! WingRegParam Int_BufSz = Int_BufSz + 1 ! ShearModel Int_BufSz = Int_BufSz + 1 ! TwrShadowOnWake - Int_BufSz = Int_BufSz + 1 ! VelocityMethod - Re_BufSz = Re_BufSz + 1 ! TreeBranchFactor - Int_BufSz = Int_BufSz + 1 ! PartPerSegment + Int_BufSz = Int_BufSz + SIZE(InData%VelocityMethod) ! VelocityMethod + Re_BufSz = Re_BufSz + SIZE(InData%TreeBranchFactor) ! TreeBranchFactor + Int_BufSz = Int_BufSz + SIZE(InData%PartPerSegment) ! PartPerSegment Db_BufSz = Db_BufSz + 1 ! DTaero Db_BufSz = Db_BufSz + 1 ! DTfvw Re_BufSz = Re_BufSz + 1 ! KinVisc + Int_BufSz = Int_BufSz + 1 ! MHK + Re_BufSz = Re_BufSz + 1 ! WtrDpth Int_BufSz = Int_BufSz + 1 ! WrVTK Int_BufSz = Int_BufSz + 1 ! VTKBlades Db_BufSz = Db_BufSz + 1 ! DTvtk @@ -1792,6 +2198,8 @@ SUBROUTINE FVW_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_BufSz = Int_BufSz + 1 ! WakeAtTE Int_BufSz = Int_BufSz + 1 ! DStallOnWake Int_BufSz = Int_BufSz + 1 ! Induction + Re_BufSz = Re_BufSz + 1 ! kFrozenNWStart + Re_BufSz = Re_BufSz + 1 ! kFrozenNWEnd IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1888,6 +2296,8 @@ SUBROUTINE FVW_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%nNWMax Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nNWFree + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%nFWMax Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%nFWFree @@ -1898,9 +2308,9 @@ SUBROUTINE FVW_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_Xferred = Int_Xferred + 1 ReKiBuf(Re_Xferred) = InData%FreeWakeStart Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%FullCirculationStart + ReKiBuf(Re_Xferred) = InData%FullCircStart Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%CirculationMethod + IntKiBuf(Int_Xferred) = InData%CircSolvMethod Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%CircSolvMaxIter Int_Xferred = Int_Xferred + 1 @@ -1928,18 +2338,28 @@ SUBROUTINE FVW_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%TwrShadowOnWake, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%VelocityMethod - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TreeBranchFactor - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%PartPerSegment - Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%VelocityMethod,1), UBOUND(InData%VelocityMethod,1) + IntKiBuf(Int_Xferred) = InData%VelocityMethod(i1) + Int_Xferred = Int_Xferred + 1 + END DO + DO i1 = LBOUND(InData%TreeBranchFactor,1), UBOUND(InData%TreeBranchFactor,1) + ReKiBuf(Re_Xferred) = InData%TreeBranchFactor(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%PartPerSegment,1), UBOUND(InData%PartPerSegment,1) + IntKiBuf(Int_Xferred) = InData%PartPerSegment(i1) + Int_Xferred = Int_Xferred + 1 + END DO DbKiBuf(Db_Xferred) = InData%DTaero Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%DTfvw Db_Xferred = Db_Xferred + 1 ReKiBuf(Re_Xferred) = InData%KinVisc Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%MHK + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WtrDpth + Re_Xferred = Re_Xferred + 1 IntKiBuf(Int_Xferred) = InData%WrVTK Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%VTKBlades @@ -1970,6 +2390,10 @@ SUBROUTINE FVW_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%Induction, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%kFrozenNWStart + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%kFrozenNWEnd + Re_Xferred = Re_Xferred + 1 END SUBROUTINE FVW_PackParam SUBROUTINE FVW_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -2087,6 +2511,8 @@ SUBROUTINE FVW_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 1 OutData%nNWMax = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + OutData%nNWFree = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%nFWMax = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%nFWFree = IntKiBuf(Int_Xferred) @@ -2097,9 +2523,9 @@ SUBROUTINE FVW_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 1 OutData%FreeWakeStart = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%FullCirculationStart = ReKiBuf(Re_Xferred) + OutData%FullCircStart = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%CirculationMethod = IntKiBuf(Int_Xferred) + OutData%CircSolvMethod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%CircSolvMaxIter = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 @@ -2127,18 +2553,34 @@ SUBROUTINE FVW_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 1 OutData%TwrShadowOnWake = TRANSFER(IntKiBuf(Int_Xferred), OutData%TwrShadowOnWake) Int_Xferred = Int_Xferred + 1 - OutData%VelocityMethod = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%TreeBranchFactor = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%PartPerSegment = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%VelocityMethod,1) + i1_u = UBOUND(OutData%VelocityMethod,1) + DO i1 = LBOUND(OutData%VelocityMethod,1), UBOUND(OutData%VelocityMethod,1) + OutData%VelocityMethod(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + i1_l = LBOUND(OutData%TreeBranchFactor,1) + i1_u = UBOUND(OutData%TreeBranchFactor,1) + DO i1 = LBOUND(OutData%TreeBranchFactor,1), UBOUND(OutData%TreeBranchFactor,1) + OutData%TreeBranchFactor(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%PartPerSegment,1) + i1_u = UBOUND(OutData%PartPerSegment,1) + DO i1 = LBOUND(OutData%PartPerSegment,1), UBOUND(OutData%PartPerSegment,1) + OutData%PartPerSegment(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO OutData%DTaero = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 OutData%DTfvw = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 OutData%KinVisc = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%MHK = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WtrDpth = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 OutData%WrVTK = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%VTKBlades = IntKiBuf(Int_Xferred) @@ -2169,6 +2611,10 @@ SUBROUTINE FVW_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 1 OutData%Induction = TRANSFER(IntKiBuf(Int_Xferred), OutData%Induction) Int_Xferred = Int_Xferred + 1 + OutData%kFrozenNWStart = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%kFrozenNWEnd = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE FVW_UnPackParam SUBROUTINE FVW_CopyWng_ContinuousStateType( SrcWng_ContinuousStateTypeData, DstWng_ContinuousStateTypeData, CtrlCode, ErrStat, ErrMsg ) @@ -2282,15 +2728,27 @@ SUBROUTINE FVW_CopyWng_ContinuousStateType( SrcWng_ContinuousStateTypeData, DstW ENDIF END SUBROUTINE FVW_CopyWng_ContinuousStateType - SUBROUTINE FVW_DestroyWng_ContinuousStateType( Wng_ContinuousStateTypeData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyWng_ContinuousStateType( Wng_ContinuousStateTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Wng_ContinuousStateType), INTENT(INOUT) :: Wng_ContinuousStateTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_ContinuousStateType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_ContinuousStateType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(Wng_ContinuousStateTypeData%Gamma_NW)) THEN DEALLOCATE(Wng_ContinuousStateTypeData%Gamma_NW) ENDIF @@ -2783,24 +3241,38 @@ SUBROUTINE FVW_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrS ENDIF END SUBROUTINE FVW_CopyContState - SUBROUTINE FVW_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FVW_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%W)) THEN DO i1 = LBOUND(ContStateData%W,1), UBOUND(ContStateData%W,1) - CALL FVW_Destroywng_continuousstatetype( ContStateData%W(i1), ErrStat, ErrMsg ) + CALL FVW_Destroywng_continuousstatetype( ContStateData%W(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ContStateData%W) ENDIF IF (ALLOCATED(ContStateData%UA)) THEN DO i1 = LBOUND(ContStateData%UA,1), UBOUND(ContStateData%UA,1) - CALL UA_DestroyContState( ContStateData%UA(i1), ErrStat, ErrMsg ) + CALL UA_DestroyContState( ContStateData%UA(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ContStateData%UA) ENDIF @@ -3172,15 +3644,27 @@ SUBROUTINE FVW_CopyWng_OutputType( SrcWng_OutputTypeData, DstWng_OutputTypeData, ENDIF END SUBROUTINE FVW_CopyWng_OutputType - SUBROUTINE FVW_DestroyWng_OutputType( Wng_OutputTypeData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyWng_OutputType( Wng_OutputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Wng_OutputType), INTENT(INOUT) :: Wng_OutputTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_OutputType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_OutputType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(Wng_OutputTypeData%Vind)) THEN DEALLOCATE(Wng_OutputTypeData%Vind) ENDIF @@ -3361,18 +3845,31 @@ SUBROUTINE FVW_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrM ENDIF END SUBROUTINE FVW_CopyOutput - SUBROUTINE FVW_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FVW_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%W)) THEN DO i1 = LBOUND(OutputData%W,1), UBOUND(OutputData%W,1) - CALL FVW_Destroywng_outputtype( OutputData%W(i1), ErrStat, ErrMsg ) + CALL FVW_Destroywng_outputtype( OutputData%W(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OutputData%W) ENDIF @@ -4070,6 +4567,18 @@ SUBROUTINE FVW_CopyWng_MiscVarType( SrcWng_MiscVarTypeData, DstWng_MiscVarTypeDa END IF DstWng_MiscVarTypeData%BN_Cm_Static = SrcWng_MiscVarTypeData%BN_Cm_Static ENDIF +IF (ALLOCATED(SrcWng_MiscVarTypeData%BN_Cpmin)) THEN + i1_l = LBOUND(SrcWng_MiscVarTypeData%BN_Cpmin,1) + i1_u = UBOUND(SrcWng_MiscVarTypeData%BN_Cpmin,1) + IF (.NOT. ALLOCATED(DstWng_MiscVarTypeData%BN_Cpmin)) THEN + ALLOCATE(DstWng_MiscVarTypeData%BN_Cpmin(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstWng_MiscVarTypeData%BN_Cpmin.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstWng_MiscVarTypeData%BN_Cpmin = SrcWng_MiscVarTypeData%BN_Cpmin +ENDIF IF (ALLOCATED(SrcWng_MiscVarTypeData%BN_Cl)) THEN i1_l = LBOUND(SrcWng_MiscVarTypeData%BN_Cl,1) i1_u = UBOUND(SrcWng_MiscVarTypeData%BN_Cl,1) @@ -4132,15 +4641,27 @@ SUBROUTINE FVW_CopyWng_MiscVarType( SrcWng_MiscVarTypeData, DstWng_MiscVarTypeDa ENDIF END SUBROUTINE FVW_CopyWng_MiscVarType - SUBROUTINE FVW_DestroyWng_MiscVarType( Wng_MiscVarTypeData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyWng_MiscVarType( Wng_MiscVarTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Wng_MiscVarType), INTENT(INOUT) :: Wng_MiscVarTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_MiscVarType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_MiscVarType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(Wng_MiscVarTypeData%LE)) THEN DEALLOCATE(Wng_MiscVarTypeData%LE) ENDIF @@ -4207,14 +4728,18 @@ SUBROUTINE FVW_DestroyWng_MiscVarType( Wng_MiscVarTypeData, ErrStat, ErrMsg ) IF (ALLOCATED(Wng_MiscVarTypeData%u_UA)) THEN DO i2 = LBOUND(Wng_MiscVarTypeData%u_UA,2), UBOUND(Wng_MiscVarTypeData%u_UA,2) DO i1 = LBOUND(Wng_MiscVarTypeData%u_UA,1), UBOUND(Wng_MiscVarTypeData%u_UA,1) - CALL UA_DestroyInput( Wng_MiscVarTypeData%u_UA(i1,i2), ErrStat, ErrMsg ) + CALL UA_DestroyInput( Wng_MiscVarTypeData%u_UA(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(Wng_MiscVarTypeData%u_UA) ENDIF - CALL UA_DestroyMisc( Wng_MiscVarTypeData%m_UA, ErrStat, ErrMsg ) - CALL UA_DestroyOutput( Wng_MiscVarTypeData%y_UA, ErrStat, ErrMsg ) - CALL UA_DestroyParam( Wng_MiscVarTypeData%p_UA, ErrStat, ErrMsg ) + CALL UA_DestroyMisc( Wng_MiscVarTypeData%m_UA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL UA_DestroyOutput( Wng_MiscVarTypeData%y_UA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL UA_DestroyParam( Wng_MiscVarTypeData%p_UA, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(Wng_MiscVarTypeData%Vind_LL)) THEN DEALLOCATE(Wng_MiscVarTypeData%Vind_LL) ENDIF @@ -4248,6 +4773,9 @@ SUBROUTINE FVW_DestroyWng_MiscVarType( Wng_MiscVarTypeData, ErrStat, ErrMsg ) IF (ALLOCATED(Wng_MiscVarTypeData%BN_Cm_Static)) THEN DEALLOCATE(Wng_MiscVarTypeData%BN_Cm_Static) ENDIF +IF (ALLOCATED(Wng_MiscVarTypeData%BN_Cpmin)) THEN + DEALLOCATE(Wng_MiscVarTypeData%BN_Cpmin) +ENDIF IF (ALLOCATED(Wng_MiscVarTypeData%BN_Cl)) THEN DEALLOCATE(Wng_MiscVarTypeData%BN_Cl) ENDIF @@ -4539,6 +5067,11 @@ SUBROUTINE FVW_PackWng_MiscVarType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 2*1 ! BN_Cm_Static upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%BN_Cm_Static) ! BN_Cm_Static END IF + Int_BufSz = Int_BufSz + 1 ! BN_Cpmin allocated yes/no + IF ( ALLOCATED(InData%BN_Cpmin) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BN_Cpmin upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%BN_Cpmin) ! BN_Cpmin + END IF Int_BufSz = Int_BufSz + 1 ! BN_Cl allocated yes/no IF ( ALLOCATED(InData%BN_Cl) ) THEN Int_BufSz = Int_BufSz + 2*1 ! BN_Cl upper/lower bounds for each dimension @@ -5320,6 +5853,21 @@ SUBROUTINE FVW_PackWng_MiscVarType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%BN_Cpmin) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BN_Cpmin,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BN_Cpmin,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BN_Cpmin,1), UBOUND(InData%BN_Cpmin,1) + ReKiBuf(Re_Xferred) = InData%BN_Cpmin(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF IF ( .NOT. ALLOCATED(InData%BN_Cl) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -6302,6 +6850,24 @@ SUBROUTINE FVW_UnPackWng_MiscVarType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BN_Cpmin not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BN_Cpmin)) DEALLOCATE(OutData%BN_Cpmin) + ALLOCATE(OutData%BN_Cpmin(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BN_Cpmin.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BN_Cpmin,1), UBOUND(OutData%BN_Cpmin,1) + OutData%BN_Cpmin(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BN_Cl not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -6463,6 +7029,9 @@ SUBROUTINE FVW_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) CALL FVW_Copyt_sgmt( SrcMiscData%Sgmt, DstMiscData%Sgmt, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + CALL FVW_Copyt_part( SrcMiscData%Part, DstMiscData%Part, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN IF (ALLOCATED(SrcMiscData%CPs)) THEN i1_l = LBOUND(SrcMiscData%CPs,1) i1_u = UBOUND(SrcMiscData%CPs,1) @@ -6509,28 +7078,47 @@ SUBROUTINE FVW_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) ENDIF END SUBROUTINE FVW_CopyMisc - SUBROUTINE FVW_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FVW_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%W)) THEN DO i1 = LBOUND(MiscData%W,1), UBOUND(MiscData%W,1) - CALL FVW_Destroywng_miscvartype( MiscData%W(i1), ErrStat, ErrMsg ) + CALL FVW_Destroywng_miscvartype( MiscData%W(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%W) ENDIF IF (ALLOCATED(MiscData%r_wind)) THEN DEALLOCATE(MiscData%r_wind) ENDIF - CALL FVW_DestroyContState( MiscData%dxdt, ErrStat, ErrMsg ) - CALL FVW_DestroyContState( MiscData%x1, ErrStat, ErrMsg ) - CALL FVW_DestroyContState( MiscData%x2, ErrStat, ErrMsg ) - CALL FVW_Destroyt_sgmt( MiscData%Sgmt, ErrStat, ErrMsg ) + CALL FVW_DestroyContState( MiscData%dxdt, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FVW_DestroyContState( MiscData%x1, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FVW_DestroyContState( MiscData%x2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FVW_Destroyt_sgmt( MiscData%Sgmt, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FVW_Destroyt_part( MiscData%Part, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MiscData%CPs)) THEN DEALLOCATE(MiscData%CPs) ENDIF @@ -6539,7 +7127,8 @@ SUBROUTINE FVW_DestroyMisc( MiscData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(MiscData%GridOutputs)) THEN DO i1 = LBOUND(MiscData%GridOutputs,1), UBOUND(MiscData%GridOutputs,1) - CALL FVW_Destroygridouttype( MiscData%GridOutputs(i1), ErrStat, ErrMsg ) + CALL FVW_Destroygridouttype( MiscData%GridOutputs(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%GridOutputs) ENDIF @@ -6688,6 +7277,23 @@ SUBROUTINE FVW_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 3 ! Part: size of buffers for each call to pack subtype + CALL FVW_Packt_part( Re_Buf, Db_Buf, Int_Buf, InData%Part, ErrStat2, ErrMsg2, .TRUE. ) ! Part + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Part + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Part + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Part + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 1 ! CPs allocated yes/no IF ( ALLOCATED(InData%CPs) ) THEN Int_BufSz = Int_BufSz + 2*2 ! CPs upper/lower bounds for each dimension @@ -6943,6 +7549,34 @@ SUBROUTINE FVW_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + CALL FVW_Packt_part( Re_Buf, Db_Buf, Int_Buf, InData%Part, ErrStat2, ErrMsg2, OnlySize ) ! Part + 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%CPs) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -7315,6 +7949,46 @@ SUBROUTINE FVW_UnPackMisc( 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) + 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 FVW_Unpackt_part( Re_Buf, Db_Buf, Int_Buf, OutData%Part, ErrStat2, ErrMsg2 ) ! Part + 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 ! CPs not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -7439,15 +8113,27 @@ SUBROUTINE FVW_CopyRot_InputType( SrcRot_InputTypeData, DstRot_InputTypeData, Ct DstRot_InputTypeData%HubPosition = SrcRot_InputTypeData%HubPosition END SUBROUTINE FVW_CopyRot_InputType - SUBROUTINE FVW_DestroyRot_InputType( Rot_InputTypeData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyRot_InputType( Rot_InputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Rot_InputType), INTENT(INOUT) :: Rot_InputTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyRot_InputType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyRot_InputType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE FVW_DestroyRot_InputType SUBROUTINE FVW_PackRot_InputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -7616,15 +8302,27 @@ SUBROUTINE FVW_CopyWng_InputType( SrcWng_InputTypeData, DstWng_InputTypeData, Ct ENDIF END SUBROUTINE FVW_CopyWng_InputType - SUBROUTINE FVW_DestroyWng_InputType( Wng_InputTypeData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyWng_InputType( Wng_InputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Wng_InputType), INTENT(INOUT) :: Wng_InputTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_InputType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_InputType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(Wng_InputTypeData%Vwnd_LL)) THEN DEALLOCATE(Wng_InputTypeData%Vwnd_LL) ENDIF @@ -7893,30 +8591,45 @@ SUBROUTINE FVW_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ENDIF END SUBROUTINE FVW_CopyInput - SUBROUTINE FVW_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FVW_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%rotors)) THEN DO i1 = LBOUND(InputData%rotors,1), UBOUND(InputData%rotors,1) - CALL FVW_Destroyrot_inputtype( InputData%rotors(i1), ErrStat, ErrMsg ) + CALL FVW_Destroyrot_inputtype( InputData%rotors(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InputData%rotors) ENDIF IF (ALLOCATED(InputData%W)) THEN DO i1 = LBOUND(InputData%W,1), UBOUND(InputData%W,1) - CALL FVW_Destroywng_inputtype( InputData%W(i1), ErrStat, ErrMsg ) + CALL FVW_Destroywng_inputtype( InputData%W(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InputData%W) ENDIF IF (ALLOCATED(InputData%WingsMesh)) THEN DO i1 = LBOUND(InputData%WingsMesh,1), UBOUND(InputData%WingsMesh,1) - CALL MeshDestroy( InputData%WingsMesh(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%WingsMesh(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InputData%WingsMesh) ENDIF @@ -8443,7 +9156,7 @@ SUBROUTINE FVW_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrS ! ErrStat = ErrID_None ErrMsg = "" - DstDiscStateData%NULL = SrcDiscStateData%NULL + DstDiscStateData%Dummy = SrcDiscStateData%Dummy IF (ALLOCATED(SrcDiscStateData%UA)) THEN i1_l = LBOUND(SrcDiscStateData%UA,1) i1_u = UBOUND(SrcDiscStateData%UA,1) @@ -8462,18 +9175,31 @@ SUBROUTINE FVW_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrS ENDIF END SUBROUTINE FVW_CopyDiscState - SUBROUTINE FVW_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FVW_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(DiscStateData%UA)) THEN DO i1 = LBOUND(DiscStateData%UA,1), UBOUND(DiscStateData%UA,1) - CALL UA_DestroyDiscState( DiscStateData%UA(i1), ErrStat, ErrMsg ) + CALL UA_DestroyDiscState( DiscStateData%UA(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(DiscStateData%UA) ENDIF @@ -8514,7 +9240,7 @@ SUBROUTINE FVW_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! NULL + Re_BufSz = Re_BufSz + 1 ! Dummy Int_BufSz = Int_BufSz + 1 ! UA allocated yes/no IF ( ALLOCATED(InData%UA) ) THEN Int_BufSz = Int_BufSz + 2*1 ! UA upper/lower bounds for each dimension @@ -8566,7 +9292,7 @@ SUBROUTINE FVW_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = 1 Int_Xferred = 1 - ReKiBuf(Re_Xferred) = InData%NULL + ReKiBuf(Re_Xferred) = InData%Dummy Re_Xferred = Re_Xferred + 1 IF ( .NOT. ALLOCATED(InData%UA) ) THEN IntKiBuf( Int_Xferred ) = 0 @@ -8638,7 +9364,7 @@ SUBROUTINE FVW_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%NULL = ReKiBuf(Re_Xferred) + OutData%Dummy = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! UA not allocated Int_Xferred = Int_Xferred + 1 @@ -8727,15 +9453,27 @@ SUBROUTINE FVW_CopyWng_ConstraintStateType( SrcWng_ConstraintStateTypeData, DstW ENDIF END SUBROUTINE FVW_CopyWng_ConstraintStateType - SUBROUTINE FVW_DestroyWng_ConstraintStateType( Wng_ConstraintStateTypeData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyWng_ConstraintStateType( Wng_ConstraintStateTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Wng_ConstraintStateType), INTENT(INOUT) :: Wng_ConstraintStateTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_ConstraintStateType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_ConstraintStateType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(Wng_ConstraintStateTypeData%Gamma_LL)) THEN DEALLOCATE(Wng_ConstraintStateTypeData%Gamma_LL) ENDIF @@ -8906,18 +9644,31 @@ SUBROUTINE FVW_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode DstConstrStateData%residual = SrcConstrStateData%residual END SUBROUTINE FVW_CopyConstrState - SUBROUTINE FVW_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FVW_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ConstrStateData%W)) THEN DO i1 = LBOUND(ConstrStateData%W,1), UBOUND(ConstrStateData%W,1) - CALL FVW_Destroywng_constraintstatetype( ConstrStateData%W(i1), ErrStat, ErrMsg ) + CALL FVW_Destroywng_constraintstatetype( ConstrStateData%W(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ConstrStateData%W) ENDIF @@ -9157,7 +9908,7 @@ SUBROUTINE FVW_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E ! ErrStat = ErrID_None ErrMsg = "" - DstOtherStateData%NULL = SrcOtherStateData%NULL + DstOtherStateData%Dummy = SrcOtherStateData%Dummy IF (ALLOCATED(SrcOtherStateData%UA)) THEN i1_l = LBOUND(SrcOtherStateData%UA,1) i1_u = UBOUND(SrcOtherStateData%UA,1) @@ -9176,18 +9927,31 @@ SUBROUTINE FVW_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E ENDIF END SUBROUTINE FVW_CopyOtherState - SUBROUTINE FVW_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FVW_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OtherStateData%UA)) THEN DO i1 = LBOUND(OtherStateData%UA,1), UBOUND(OtherStateData%UA,1) - CALL UA_DestroyOtherState( OtherStateData%UA(i1), ErrStat, ErrMsg ) + CALL UA_DestroyOtherState( OtherStateData%UA(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OtherStateData%UA) ENDIF @@ -9228,7 +9992,7 @@ SUBROUTINE FVW_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! NULL + Int_BufSz = Int_BufSz + 1 ! Dummy Int_BufSz = Int_BufSz + 1 ! UA allocated yes/no IF ( ALLOCATED(InData%UA) ) THEN Int_BufSz = Int_BufSz + 2*1 ! UA upper/lower bounds for each dimension @@ -9280,7 +10044,7 @@ SUBROUTINE FVW_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = InData%NULL + IntKiBuf(Int_Xferred) = InData%Dummy Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%UA) ) THEN IntKiBuf( Int_Xferred ) = 0 @@ -9352,7 +10116,7 @@ SUBROUTINE FVW_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%NULL = IntKiBuf(Int_Xferred) + OutData%Dummy = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! UA not allocated Int_Xferred = Int_Xferred + 1 @@ -9471,15 +10235,27 @@ SUBROUTINE FVW_CopyWng_InitInputType( SrcWng_InitInputTypeData, DstWng_InitInput DstWng_InitInputTypeData%UAOff_outerNode = SrcWng_InitInputTypeData%UAOff_outerNode END SUBROUTINE FVW_CopyWng_InitInputType - SUBROUTINE FVW_DestroyWng_InitInputType( Wng_InitInputTypeData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyWng_InitInputType( Wng_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Wng_InitInputType), INTENT(INOUT) :: Wng_InitInputTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_InitInputType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyWng_InitInputType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(Wng_InitInputTypeData%AFindx)) THEN DEALLOCATE(Wng_InitInputTypeData%AFindx) ENDIF @@ -9776,6 +10552,8 @@ SUBROUTINE FVW_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrS DstInitInputData%numBladeNodes = SrcInitInputData%numBladeNodes DstInitInputData%DTaero = SrcInitInputData%DTaero DstInitInputData%KinVisc = SrcInitInputData%KinVisc + DstInitInputData%MHK = SrcInitInputData%MHK + DstInitInputData%WtrDpth = SrcInitInputData%WtrDpth DstInitInputData%UAMod = SrcInitInputData%UAMod DstInitInputData%UA_Flag = SrcInitInputData%UA_Flag DstInitInputData%Flookup = SrcInitInputData%Flookup @@ -9783,24 +10561,38 @@ SUBROUTINE FVW_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrS DstInitInputData%SumPrint = SrcInitInputData%SumPrint END SUBROUTINE FVW_CopyInitInput - SUBROUTINE FVW_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FVW_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%W)) THEN DO i1 = LBOUND(InitInputData%W,1), UBOUND(InitInputData%W,1) - CALL FVW_Destroywng_initinputtype( InitInputData%W(i1), ErrStat, ErrMsg ) + CALL FVW_Destroywng_initinputtype( InitInputData%W(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%W) ENDIF IF (ALLOCATED(InitInputData%WingsMesh)) THEN DO i1 = LBOUND(InitInputData%WingsMesh,1), UBOUND(InitInputData%WingsMesh,1) - CALL MeshDestroy( InitInputData%WingsMesh(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( InitInputData%WingsMesh(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%WingsMesh) ENDIF @@ -9893,6 +10685,8 @@ SUBROUTINE FVW_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + 1 ! numBladeNodes Db_BufSz = Db_BufSz + 1 ! DTaero Re_BufSz = Re_BufSz + 1 ! KinVisc + Int_BufSz = Int_BufSz + 1 ! MHK + Re_BufSz = Re_BufSz + 1 ! WtrDpth Int_BufSz = Int_BufSz + 1 ! UAMod Int_BufSz = Int_BufSz + 1 ! UA_Flag Int_BufSz = Int_BufSz + 1 ! Flookup @@ -10021,6 +10815,10 @@ SUBROUTINE FVW_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = Db_Xferred + 1 ReKiBuf(Re_Xferred) = InData%KinVisc Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%MHK + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WtrDpth + Re_Xferred = Re_Xferred + 1 IntKiBuf(Int_Xferred) = InData%UAMod Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%UA_Flag, IntKiBuf(1)) @@ -10186,6 +10984,10 @@ SUBROUTINE FVW_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Db_Xferred = Db_Xferred + 1 OutData%KinVisc = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%MHK = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WtrDpth = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 OutData%UAMod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%UA_Flag = TRANSFER(IntKiBuf(Int_Xferred), OutData%UA_Flag) @@ -10206,13 +11008,14 @@ SUBROUTINE FVW_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrS 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 = 'FVW_CopyInputFile' ! ErrStat = ErrID_None ErrMsg = "" - DstInputFileData%CirculationMethod = SrcInputFileData%CirculationMethod + DstInputFileData%CircSolvMethod = SrcInputFileData%CircSolvMethod DstInputFileData%CirculationFile = SrcInputFileData%CirculationFile DstInputFileData%CircSolvMaxIter = SrcInputFileData%CircSolvMaxIter DstInputFileData%CircSolvConvCrit = SrcInputFileData%CircSolvConvCrit @@ -10220,10 +11023,11 @@ SUBROUTINE FVW_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrS DstInputFileData%IntMethod = SrcInputFileData%IntMethod DstInputFileData%FreeWake = SrcInputFileData%FreeWake DstInputFileData%FreeWakeStart = SrcInputFileData%FreeWakeStart - DstInputFileData%FullCirculationStart = SrcInputFileData%FullCirculationStart + DstInputFileData%FullCircStart = SrcInputFileData%FullCircStart DstInputFileData%DTfvw = SrcInputFileData%DTfvw DstInputFileData%CircSolvPolar = SrcInputFileData%CircSolvPolar DstInputFileData%nNWPanels = SrcInputFileData%nNWPanels + DstInputFileData%nNWPanelsFree = SrcInputFileData%nNWPanelsFree DstInputFileData%nFWPanels = SrcInputFileData%nFWPanels DstInputFileData%nFWPanelsFree = SrcInputFileData%nFWPanelsFree DstInputFileData%FWShedVorticity = SrcInputFileData%FWShedVorticity @@ -10245,15 +11049,27 @@ SUBROUTINE FVW_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrS DstInputFileData%VTKCoord = SrcInputFileData%VTKCoord END SUBROUTINE FVW_CopyInputFile - SUBROUTINE FVW_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FVW_InputFile), INTENT(INOUT) :: InputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyInputFile' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyInputFile' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE FVW_DestroyInputFile SUBROUTINE FVW_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -10291,7 +11107,7 @@ SUBROUTINE FVW_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! CirculationMethod + Int_BufSz = Int_BufSz + 1 ! CircSolvMethod Int_BufSz = Int_BufSz + 1*LEN(InData%CirculationFile) ! CirculationFile Int_BufSz = Int_BufSz + 1 ! CircSolvMaxIter Re_BufSz = Re_BufSz + 1 ! CircSolvConvCrit @@ -10299,10 +11115,11 @@ SUBROUTINE FVW_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_BufSz = Int_BufSz + 1 ! IntMethod Int_BufSz = Int_BufSz + 1 ! FreeWake Re_BufSz = Re_BufSz + 1 ! FreeWakeStart - Re_BufSz = Re_BufSz + 1 ! FullCirculationStart + Re_BufSz = Re_BufSz + 1 ! FullCircStart Db_BufSz = Db_BufSz + 1 ! DTfvw Int_BufSz = Int_BufSz + 1 ! CircSolvPolar Int_BufSz = Int_BufSz + 1 ! nNWPanels + Int_BufSz = Int_BufSz + 1 ! nNWPanelsFree Int_BufSz = Int_BufSz + 1 ! nFWPanels Int_BufSz = Int_BufSz + 1 ! nFWPanelsFree Int_BufSz = Int_BufSz + 1 ! FWShedVorticity @@ -10315,9 +11132,9 @@ SUBROUTINE FVW_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Re_BufSz = Re_BufSz + 1 ! WingRegParam Int_BufSz = Int_BufSz + 1 ! ShearModel Int_BufSz = Int_BufSz + 1 ! TwrShadowOnWake - Int_BufSz = Int_BufSz + 1 ! VelocityMethod - Re_BufSz = Re_BufSz + 1 ! TreeBranchFactor - Int_BufSz = Int_BufSz + 1 ! PartPerSegment + Int_BufSz = Int_BufSz + SIZE(InData%VelocityMethod) ! VelocityMethod + Re_BufSz = Re_BufSz + SIZE(InData%TreeBranchFactor) ! TreeBranchFactor + Int_BufSz = Int_BufSz + SIZE(InData%PartPerSegment) ! PartPerSegment Int_BufSz = Int_BufSz + 1 ! WrVTK Int_BufSz = Int_BufSz + 1 ! VTKBlades Db_BufSz = Db_BufSz + 1 ! DTvtk @@ -10349,7 +11166,7 @@ SUBROUTINE FVW_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = InData%CirculationMethod + IntKiBuf(Int_Xferred) = InData%CircSolvMethod Int_Xferred = Int_Xferred + 1 DO I = 1, LEN(InData%CirculationFile) IntKiBuf(Int_Xferred) = ICHAR(InData%CirculationFile(I:I), IntKi) @@ -10367,7 +11184,7 @@ SUBROUTINE FVW_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_Xferred = Int_Xferred + 1 ReKiBuf(Re_Xferred) = InData%FreeWakeStart Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%FullCirculationStart + ReKiBuf(Re_Xferred) = InData%FullCircStart Re_Xferred = Re_Xferred + 1 DbKiBuf(Db_Xferred) = InData%DTfvw Db_Xferred = Db_Xferred + 1 @@ -10375,6 +11192,8 @@ SUBROUTINE FVW_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%nNWPanels Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nNWPanelsFree + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%nFWPanels Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%nFWPanelsFree @@ -10399,12 +11218,18 @@ SUBROUTINE FVW_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMs Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%TwrShadowOnWake, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%VelocityMethod - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TreeBranchFactor - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%PartPerSegment - Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%VelocityMethod,1), UBOUND(InData%VelocityMethod,1) + IntKiBuf(Int_Xferred) = InData%VelocityMethod(i1) + Int_Xferred = Int_Xferred + 1 + END DO + DO i1 = LBOUND(InData%TreeBranchFactor,1), UBOUND(InData%TreeBranchFactor,1) + ReKiBuf(Re_Xferred) = InData%TreeBranchFactor(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%PartPerSegment,1), UBOUND(InData%PartPerSegment,1) + IntKiBuf(Int_Xferred) = InData%PartPerSegment(i1) + Int_Xferred = Int_Xferred + 1 + END DO IntKiBuf(Int_Xferred) = InData%WrVTK Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%VTKBlades @@ -10428,6 +11253,7 @@ SUBROUTINE FVW_UnPackInputFile( 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 = 'FVW_UnPackInputFile' @@ -10441,7 +11267,7 @@ SUBROUTINE FVW_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%CirculationMethod = IntKiBuf(Int_Xferred) + OutData%CircSolvMethod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 DO I = 1, LEN(OutData%CirculationFile) OutData%CirculationFile(I:I) = CHAR(IntKiBuf(Int_Xferred)) @@ -10459,7 +11285,7 @@ SUBROUTINE FVW_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Xferred = Int_Xferred + 1 OutData%FreeWakeStart = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%FullCirculationStart = ReKiBuf(Re_Xferred) + OutData%FullCircStart = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%DTfvw = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 @@ -10467,6 +11293,8 @@ SUBROUTINE FVW_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Xferred = Int_Xferred + 1 OutData%nNWPanels = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + OutData%nNWPanelsFree = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%nFWPanels = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%nFWPanelsFree = IntKiBuf(Int_Xferred) @@ -10491,12 +11319,24 @@ SUBROUTINE FVW_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Er Int_Xferred = Int_Xferred + 1 OutData%TwrShadowOnWake = TRANSFER(IntKiBuf(Int_Xferred), OutData%TwrShadowOnWake) Int_Xferred = Int_Xferred + 1 - OutData%VelocityMethod = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%TreeBranchFactor = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%PartPerSegment = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%VelocityMethod,1) + i1_u = UBOUND(OutData%VelocityMethod,1) + DO i1 = LBOUND(OutData%VelocityMethod,1), UBOUND(OutData%VelocityMethod,1) + OutData%VelocityMethod(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + i1_l = LBOUND(OutData%TreeBranchFactor,1) + i1_u = UBOUND(OutData%TreeBranchFactor,1) + DO i1 = LBOUND(OutData%TreeBranchFactor,1), UBOUND(OutData%TreeBranchFactor,1) + OutData%TreeBranchFactor(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%PartPerSegment,1) + i1_u = UBOUND(OutData%PartPerSegment,1) + DO i1 = LBOUND(OutData%PartPerSegment,1), UBOUND(OutData%PartPerSegment,1) + OutData%PartPerSegment(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO OutData%WrVTK = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%VTKBlades = IntKiBuf(Int_Xferred) @@ -10521,18 +11361,30 @@ SUBROUTINE FVW_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, E ! ErrStat = ErrID_None ErrMsg = "" - DstInitOutputData%Null = SrcInitOutputData%Null + DstInitOutputData%Dummy = SrcInitOutputData%Dummy END SUBROUTINE FVW_CopyInitOutput - SUBROUTINE FVW_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE FVW_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FVW_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FVW_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE FVW_DestroyInitOutput SUBROUTINE FVW_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -10570,7 +11422,7 @@ SUBROUTINE FVW_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! Null + Int_BufSz = Int_BufSz + 1 ! Dummy IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -10598,7 +11450,7 @@ SUBROUTINE FVW_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = InData%Null + IntKiBuf(Int_Xferred) = InData%Dummy Int_Xferred = Int_Xferred + 1 END SUBROUTINE FVW_PackInitOutput @@ -10628,7 +11480,7 @@ SUBROUTINE FVW_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%Null = IntKiBuf(Int_Xferred) + OutData%Dummy = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 END SUBROUTINE FVW_UnPackInitOutput diff --git a/modules/aerodyn/src/FVW_VTK.f90 b/modules/aerodyn/src/FVW_VTK.f90 deleted file mode 100644 index a69a5a451..000000000 --- a/modules/aerodyn/src/FVW_VTK.f90 +++ /dev/null @@ -1,592 +0,0 @@ -module FVW_VTK - !use PrecisionMod, only: ReKi - use NWTC_Library, only: ReKi, GetNewUnit - implicit none -! character(8), parameter :: RFMT='F14.5' - !character(8), parameter :: RFMT='E24.15E3' - character(8), parameter :: RFMT='E17.8E3' - character(8), parameter :: IFMT='I7' - - TYPE, PUBLIC :: FVW_VTK_Misc - integer :: vtk_unit - logical :: bFileOpen=.false. - - integer :: nData=0; - integer :: nPoints=0; - - logical :: bBinary = .false. - character(len=255) :: buffer - - ! Reference Frame - real(ReKi),dimension(3,3) :: T_g2b - real(ReKi),dimension(3) :: PO_g - END TYPE FVW_VTK_Misc - - character(1), parameter :: NL = char(10) ! New Line character - - interface vtk_dataset_structured_grid; module procedure & - vtk_dataset_structured_grid_flat, & - vtk_dataset_structured_grid_grid - end interface - - interface vtk_point_data_vector; module procedure & - vtk_point_data_vector_flat, & - vtk_point_data_vector_grid2D,& - vtk_point_data_vector_grid - end interface - interface vtk_point_data_scalar; module procedure & - vtk_point_data_scalar_flat, & - vtk_point_data_scalar_grid2D, & - vtk_point_data_scalar_grid - end interface - interface vtk_cell_data_scalar; module procedure & - vtk_cell_data_scalar_1d,& - vtk_cell_data_scalar_2d - end interface - - public - -contains - - subroutine vtk_misc_init(mvtk) - type(FVW_VTK_Misc),intent(inout) :: mvtk - mvtk%vtk_unit = -1 !< VTK output unit [-] - mvtk%bFileOpen = .false. !< binary file is open [-] - mvtk%bBinary = .false. !< write binary files [-] - mvtk%nData = 0 !< number of data lines [-] - mvtk%nPoints = 0 !< number of points [-] - end subroutine - - !> - subroutine set_vtk_binary_format(bBin,mvtk) - logical, intent(in)::bBin - type(FVW_VTK_Misc),intent(inout) :: mvtk - mvtk%bBinary=bBin - end subroutine - - - !> Save a coordinate transform - ! ALL VTK Will be exported in this coordinate system! - subroutine set_vtk_coordinate_transform(T_g2b_in,PO_g_in,mvtk) - real(ReKi),dimension(3,3), intent(in) :: T_g2b_in - real(ReKi),dimension(3) , intent(in) :: PO_g_in - type(FVW_VTK_Misc),intent(inout) :: mvtk - mvtk%T_g2b=T_g2b_in - mvtk%PO_g=PO_g_in - end subroutine - - logical function vtk_new_ascii_file(filename,label,mvtk) - !use MainIO, only: get_free_unit ,check_io - !use MainIOData, only: bSTOP_ALLOWED - !use FileSystem, only: file_exists - !use Logging, only: log_warning,log_error,log_info - ! - character(len=*),intent(in) :: filename - character(len=*),intent(in) :: label - type(FVW_VTK_Misc),intent(inout) :: mvtk - ! - integer :: iostatvar - logical :: b - - if (.not. mvtk%bFileOpen) then - CALL GetNewUnit( mvtk%vtk_unit ) - if (mvtk%bBinary) then - ! Fortran 2003 stream, otherwise intel fortran ! - !form='UNFORMATTED',access='SEQUENTIAL',action='WRITE',convert='BIG_ENDIAN',recordtype='STREAM',buffered='YES', - !print*,'Not available for this compiler' !COMPAQ-COMPILER - !STOP !COMPAQ-COMPILER -!bjj: CONVERT is non-standard, so maybe this should be part of Sys*.f90? Like OpenUnfInpBEFile()? - open(unit = mvtk%vtk_unit,file= trim(adjustl(filename)),form='UNFORMATTED',access = 'stream',& !OTHER-COMPILER - action = 'WRITE',convert= 'BIG_ENDIAN',iostat=iostatvar,status='replace') !OTHER-COMPILER - else - open(mvtk%vtk_unit,file=trim(adjustl(filename)),iostat=iostatvar,action="write",status='replace') - endif - if (iostatvar == 0) then - if (mvtk%bBinary) then - write(mvtk%vtk_unit)'# vtk DataFile Version 3.0'//NL - write(mvtk%vtk_unit)trim(label)//NL - write(mvtk%vtk_unit)'BINARY'//NL - else - write(mvtk%vtk_unit,'(a)') '# vtk DataFile Version 2.0' - write(mvtk%vtk_unit,'(a)') trim(label) - write(mvtk%vtk_unit,'(a)') 'ASCII' - write(mvtk%vtk_unit,'(a)') ' ' - endif - - mvtk%bFileOpen=.true. - mvtk%nData=-1; - endif - else - b=.false. - !call log_error('VTK: Cannot open two vtk files at the same time, call vtk_close first') - endif - if (iostatvar ==0) then - vtk_new_ascii_file=.true. - else - vtk_new_ascii_file=.false. - endif - end function - - subroutine vtk_close_file(mvtk) - type(FVW_VTK_Misc),intent(inout) :: mvtk - if ( mvtk%bFileOpen ) then - close(mvtk%vtk_unit) - mvtk%bFileOpen=.false. - endif - endsubroutine - - - ! ------------------------------------------------------------------------- - ! --- POLYDATA STUFF - ! ------------------------------------------------------------------------- - subroutine vtk_dataset_polydata(Points,mvtk,bladeFrame) - real(ReKi), dimension(:,:),intent(in) :: Points !< 3 x n - type(FVW_VTK_Misc),intent(inout) :: mvtk - logical, intent(in) :: bladeFrame - integer :: i - if ( mvtk%bFileOpen ) then - mvtk%nPoints=size(Points,2) - if (mvtk%bBinary) then - write(mvtk%vtk_unit)'DATASET POLYDATA'//NL - write(mvtk%buffer,'(A,I0,A)') 'POINTS ', mvtk%nPoints ,' double' - write(mvtk%vtk_unit)trim(mvtk%buffer)//NL - if (bladeFrame) then - do i=1,mvtk%nPoints - write(mvtk%vtk_unit)matmul(mvtk%T_g2b,Points(1:3,i)-mvtk%PO_g) - enddo - else - do i=1,mvtk%nPoints - write(mvtk%vtk_unit)Points(1:3,i) - enddo - endif - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,'(A)') 'DATASET POLYDATA' - write(mvtk%vtk_unit,'(A,I0,A)') 'POINTS ', mvtk%nPoints ,' double' - if (bladeFrame) then - do i=1,mvtk%nPoints - write(mvtk%vtk_unit,'(3'//RFMT//')') matmul(mvtk%T_g2b,Points(1:3,i)-mvtk%PO_g) - enddo - else - do i=1,mvtk%nPoints - write(mvtk%vtk_unit,'(3'//RFMT//')') Points(1:3,i) - enddo - endif - write(mvtk%vtk_unit,*) ' ' - endif - endif - end subroutine - - - subroutine vtk_lines(L,mvtk) - integer, dimension(:,:),intent(in) :: L !< 2 x n - type(FVW_VTK_Misc),intent(inout) :: mvtk - - integer :: i - - if ( mvtk%bFileOpen ) then - mvtk%nData=size(L,2) - if (mvtk%bBinary) then - write(mvtk%buffer,'(A,I0,A,I0)')'LINES ',mvtk%nData,' ',3*mvtk%nData - write(mvtk%vtk_unit)trim(mvtk%buffer)//NL - do i=1,mvtk%nData - write(mvtk%vtk_unit)2,L(1:2,i) - enddo - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,'(A,I0,A,I0)')'LINES ',mvtk%nData,' ',3*mvtk%nData - do i=1,mvtk%nData - write(mvtk%vtk_unit,'(3'//IFMT//')') 2, L(1:2,i) - enddo - write(mvtk%vtk_unit,*) ' ' - endif - endif - end subroutine - - subroutine vtk_quad(Q,mvtk) - integer, dimension(:,:),intent(in) :: Q !< 4 x n - type(FVW_VTK_Misc),intent(inout) :: mvtk - integer :: i - if ( mvtk%bFileOpen ) then - mvtk%nData=size(Q,2) - if (mvtk%bBinary) then - write(mvtk%buffer,'(A,I0,A,I0)')'POLYGONS ',mvtk%nData,' ',5*mvtk%nData - write(mvtk%vtk_unit)trim(mvtk%buffer)//NL - do i=1,mvtk%nData - write(mvtk%vtk_unit)4,Q(1:4,i) - enddo - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,'(A,I0,A,I0)') 'POLYGONS ', mvtk%nData,' ',5*mvtk%nData - do i=1,mvtk%nData - write(mvtk%vtk_unit,'(5'//IFMT//')') 4, Q(1:4,i) - enddo - write(mvtk%vtk_unit,*) ' ' - endif - endif - end subroutine - - ! ------------------------------------------------------------------------- - ! --- RECTILINEAR - ! ------------------------------------------------------------------------- - subroutine vtk_dataset_rectilinear(v1,v2,v3,mvtk) - real(ReKi), dimension(:),intent(in) :: v1,v2,v3 !< n - type(FVW_VTK_Misc),intent(inout) :: mvtk - - if ( mvtk%bFileOpen ) then - mvtk%nPoints=size(v1)*size(v2)*size(v3) - if (mvtk%bBinary) then - write(mvtk%vtk_unit) 'DATASET RECTILINEAR_GRID'//NL - write(mvtk%buffer,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', size(v1),' ',size(v2),' ',size(v3) - write(mvtk%vtk_unit) trim(mvtk%buffer)//NL - write(mvtk%buffer,'(A,I0,A)') 'X_COORDINATES ', size(v1), ' double' - write(mvtk%vtk_unit) trim(mvtk%buffer)//NL - write(mvtk%vtk_unit)v1 - write(mvtk%vtk_unit)NL - write(mvtk%buffer,'(A,I0,A)') 'Y_COORDINATES ', size(v2), ' double' - write(mvtk%vtk_unit) trim(mvtk%buffer)//NL - write(mvtk%vtk_unit)v2 - write(mvtk%vtk_unit)NL - write(mvtk%buffer,'(A,I0,A)') 'Z_COORDINATES ', size(v3), ' double' - write(mvtk%vtk_unit) trim(mvtk%buffer)//NL - write(mvtk%vtk_unit)v3 - !write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,'(A)') 'DATASET RECTILINEAR_GRID' - write(mvtk%vtk_unit,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', size(v1),' ',size(v2),' ',size(v3) - write(mvtk%vtk_unit,'(A,I0,A)') 'X_COORDINATES ', size(v1), ' double' - write(mvtk%vtk_unit,'('//RFMT//')') v1 - write(mvtk%vtk_unit,'(A,I0,A)') 'Y_COORDINATES ', size(v2), ' double' - write(mvtk%vtk_unit,'('//RFMT//')') v2 - write(mvtk%vtk_unit,'(A,I0,A)') 'Z_COORDINATES ', size(v3), ' double' - write(mvtk%vtk_unit,'('//RFMT//')') v3 - write(mvtk%vtk_unit,*) ' ' - endif - endif - end subroutine - - subroutine vtk_dataset_structured_points(x0,dx,n,mvtk) - real(ReKi), dimension(3), intent(in) :: x0 !< origin - real(ReKi), dimension(3), intent(in) :: dx !< spacing - integer, dimension(3), intent(in) :: n !< length - type(FVW_VTK_Misc),intent(inout) :: mvtk - - if ( mvtk%bFileOpen ) then - mvtk%nPoints=n(1)*n(2)*n(3) - if (mvtk%bBinary) then - write(mvtk%vtk_unit) 'DATASET STRUCTURED_POINTS'//NL - write(mvtk%buffer,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ',n(1),' ',n(2),' ',n(3) - write(mvtk%vtk_unit) trim(mvtk%buffer)//NL - write(mvtk%buffer,'(A,3F16.8)') 'ORIGIN ', x0 - write(mvtk%vtk_unit) trim(mvtk%buffer)//NL - write(mvtk%buffer,'(A,3F16.8)') 'SPACING ', dx - write(mvtk%vtk_unit) trim(mvtk%buffer)//NL - else - write(mvtk%vtk_unit,'(A)') 'DATASET STRUCTURED_POINTS' - write(mvtk%vtk_unit,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', n(1),' ',n(2),' ',n(3) - write(mvtk%vtk_unit,'(A,3F16.8,A)') 'ORIGIN ',x0 - write(mvtk%vtk_unit,'(A,3F16.8,A)') 'SPACING ',dx - endif - endif - end subroutine - - - ! ------------------------------------------------------------------------- - ! --- STRUCTURED GRID (Points dumped without for loop since memory is in proper order) - ! ------------------------------------------------------------------------- - !> Subroutine using flat data as input (not in natural order) - subroutine vtk_dataset_structured_grid_flat(D,n1,n2,n3,mvtk) - integer , intent(in) :: n1,n2,n3 - real(ReKi), dimension(:,:),intent(in)::D - type(FVW_VTK_Misc),intent(inout) :: mvtk - if ( mvtk%bFileOpen ) then - mvtk%nPoints=n1*n2*n3 - if (mvtk%bBinary) then - write(mvtk%vtk_unit) 'DATASET STRUCTURED_GRID'//NL - write(mvtk%buffer,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', n1,' ',n2,' ',n3 - write(mvtk%vtk_unit) trim(mvtk%buffer)//NL - write(mvtk%buffer,'(A,I0,A)') 'POINTS ', mvtk%nPoints, ' double' - write(mvtk%vtk_unit) trim(mvtk%buffer)//NL - write(mvtk%vtk_unit)D - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,'(A)') 'DATASET STRUCTURED_GRID' - write(mvtk%vtk_unit,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', n1,' ',n2,' ',n3 - write(mvtk%vtk_unit,'(A,I0,A)') 'POINTS ', mvtk%nPoints, ' double' - write(mvtk%vtk_unit,'(3'//RFMT//')')D - write(mvtk%vtk_unit,*) ' ' - endif - endif - end subroutine - - !> Using Grid data 4d as input - subroutine vtk_dataset_structured_grid_grid(D,n1,n2,n3,mvtk) - integer , intent(in) :: n1,n2,n3 - real(ReKi), dimension(:,:,:,:),intent(in)::D - type(FVW_VTK_Misc),intent(inout) :: mvtk - - if ( mvtk%bFileOpen ) then - mvtk%nPoints=n1*n2*n3 - if (mvtk%bBinary) then - write(mvtk%vtk_unit) 'DATASET STRUCTURED_GRID'//NL - write(mvtk%buffer,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', n1,' ',n2,' ',n3 - write(mvtk%vtk_unit) trim(mvtk%buffer)//NL - write(mvtk%buffer,'(A,I0,A)') 'POINTS ', mvtk%nPoints, ' double' - write(mvtk%vtk_unit) trim(mvtk%buffer)//NL - write(mvtk%vtk_unit)D - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,'(A)') 'DATASET STRUCTURED_GRID' - write(mvtk%vtk_unit,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', n1,' ',n2,' ',n3 - write(mvtk%vtk_unit,'(A,I0,A)') 'POINTS ', mvtk%nPoints, ' double' - write(mvtk%vtk_unit,'(3'//RFMT//')')D - write(mvtk%vtk_unit,*) ' ' - endif - endif - end subroutine - - - - ! ------------------------------------------------------------------------- - ! --- POINT DATA - ! ------------------------------------------------------------------------- - subroutine vtk_point_data_init(mvtk) - type(FVW_VTK_Misc),intent(inout) :: mvtk - if ( mvtk%bFileOpen ) then - if(mvtk%bBinary) then - write(mvtk%buffer,'(A,I0)')'POINT_DATA ',mvtk%nPoints - write(mvtk%vtk_unit)trim(mvtk%buffer)//NL - else - write(mvtk%vtk_unit,'(A,I0)') 'POINT_DATA ', mvtk%nPoints - endif - endif - end subroutine - - subroutine vtk_point_data_scalar_flat(D,sname,mvtk) - real(ReKi), dimension(:),intent(in)::D - character(len=*),intent(in) ::sname - type(FVW_VTK_Misc),intent(inout) :: mvtk - - if ( mvtk%bFileOpen ) then - if (mvtk%bBinary) then - write(mvtk%vtk_unit)'SCALARS '//trim(sname)//' double'//NL - write(mvtk%vtk_unit)'LOOKUP_TABLE default'//NL - write(mvtk%vtk_unit)D - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,'(A,A,A)') 'SCALARS ', sname, ' double' - write(mvtk%vtk_unit,'(A)') 'LOOKUP_TABLE default' - write(mvtk%vtk_unit,'(1'//RFMT//')')D - endif - endif - end subroutine - - subroutine vtk_point_data_scalar_grid(D,sname,mvtk) - real(ReKi), dimension(:,:,:,:),intent(in)::D - character(len=*),intent(in) ::sname - type(FVW_VTK_Misc),intent(inout) :: mvtk - - if ( mvtk%bFileOpen ) then - if (mvtk%bBinary) then - write(mvtk%vtk_unit)'SCALARS '//trim(sname)//' double'//NL - write(mvtk%vtk_unit)'LOOKUP_TABLE default'//NL - write(mvtk%vtk_unit)D - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,'(A,A,A)') 'SCALARS ', sname, ' double' - write(mvtk%vtk_unit,'(A)') 'LOOKUP_TABLE default' - write(mvtk%vtk_unit,'(1'//RFMT//')')D - endif - endif - end subroutine - - subroutine vtk_point_data_scalar_grid2D(D,sname,mvtk) - real(ReKi), dimension(:,:,:),intent(in)::D - character(len=*),intent(in) ::sname - type(FVW_VTK_Misc),intent(inout) :: mvtk - - if ( mvtk%bFileOpen ) then - if (mvtk%bBinary) then - write(mvtk%vtk_unit)'SCALARS '//trim(sname)//' double'//NL - write(mvtk%vtk_unit)'LOOKUP_TABLE default'//NL - write(mvtk%vtk_unit)D - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,'(A,A,A)') 'SCALARS ', sname, ' double' - write(mvtk%vtk_unit,'(A)') 'LOOKUP_TABLE default' - write(mvtk%vtk_unit,'(1'//RFMT//')')D - endif - endif - end subroutine - - !> - subroutine vtk_point_data_vector_flat(D,sname,mvtk) - real(ReKi), dimension(:,:),intent(in) :: D !< 3 x n - character(len=*),intent(in) ::sname - type(FVW_VTK_Misc),intent(inout) :: mvtk - if ( mvtk%bFileOpen ) then - if (mvtk%bBinary) then - write(mvtk%vtk_unit)'VECTORS '//trim(sname)//' double'//NL - write(mvtk%vtk_unit)D - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,'(A,A,A)') 'VECTORS ', sname, ' double' - write(mvtk%vtk_unit,'(3'//RFMT//')')D - endif - endif - end subroutine - !> - subroutine vtk_point_data_vector_grid(D,sname,mvtk) - real(ReKi), dimension(:,:,:,:),intent(in) :: D !< 3 x n - character(len=*),intent(in) ::sname - type(FVW_VTK_Misc),intent(inout) :: mvtk - if ( mvtk%bFileOpen ) then - if (mvtk%bBinary) then - write(mvtk%vtk_unit)'VECTORS '//trim(sname)//' double'//NL - write(mvtk%vtk_unit)D - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,'(A,A,A)') 'VECTORS ', sname, ' double' - write(mvtk%vtk_unit,'(3'//RFMT//')')D - endif - endif - end subroutine - !> - subroutine vtk_point_data_vector_grid2D(D,sname,mvtk) - real(ReKi), dimension(:,:,:),intent(in) :: D !< - character(len=*),intent(in) ::sname - type(FVW_VTK_Misc),intent(inout) :: mvtk - if ( mvtk%bFileOpen ) then - if (mvtk%bBinary) then - write(mvtk%vtk_unit)'VECTORS '//trim(sname)//' double'//NL - write(mvtk%vtk_unit)D - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,'(A,A,A)') 'VECTORS ', sname, ' double' - write(mvtk%vtk_unit,'(3'//RFMT//')')D - endif - endif - end subroutine - - - ! ------------------------------------------------------------------------- - ! --- CELL DATA - ! ------------------------------------------------------------------------- - subroutine vtk_cell_data_init(mvtk) - type(FVW_VTK_Misc),intent(inout) :: mvtk - if ( mvtk%bFileOpen ) then - if (mvtk%bBinary) then - write(mvtk%buffer,'(A,I0)')'CELL_DATA ',mvtk%nData - write(mvtk%vtk_unit)trim(mvtk%buffer)//NL - else - write(mvtk%vtk_unit,'(A,I0)') 'CELL_DATA ', mvtk%nData - endif - endif - end subroutine - - subroutine vtk_cell_data_scalar_1d(D,sname,mvtk) - real(ReKi), dimension(:),intent(in)::D - character(len=*),intent(in) ::sname - type(FVW_VTK_Misc),intent(inout) :: mvtk - - if ( mvtk%bFileOpen ) then - if (mvtk%bBinary) then - write(mvtk%vtk_unit)'SCALARS '//trim(sname)//' double 1'//NL - write(mvtk%vtk_unit)'LOOKUP_TABLE default'//NL - write(mvtk%vtk_unit)D - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,fmt='(A,A,A)') 'SCALARS ', sname, ' double' - write(mvtk%vtk_unit,'(A)') 'LOOKUP_TABLE default' - write(mvtk%vtk_unit,'(1'//RFMT//')')D - endif - endif - end subroutine - - subroutine vtk_cell_data_scalar_2d(D,sname,mvtk) - real(ReKi), dimension(:,:),intent(in)::D - character(len=*),intent(in) ::sname - type(FVW_VTK_Misc),intent(inout) :: mvtk - - if ( mvtk%bFileOpen ) then - if (mvtk%bBinary) then - write(mvtk%vtk_unit)'SCALARS '//trim(sname)//' double 1'//NL - write(mvtk%vtk_unit)'LOOKUP_TABLE default'//NL - write(mvtk%vtk_unit)D - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,fmt='(A,A,A)') 'SCALARS ', sname, ' double' - write(mvtk%vtk_unit,'(A)') 'LOOKUP_TABLE default' - write(mvtk%vtk_unit,'(1'//RFMT//')')D - endif - endif - end subroutine - - - subroutine vtk_cell_data_vector(D,sname,mvtk) - real(ReKi), dimension(:,:),intent(in) :: D !< 3 x n - character(len=*),intent(in) ::sname - type(FVW_VTK_Misc),intent(inout) :: mvtk - if ( mvtk%bFileOpen ) then - if (mvtk%bBinary) then - write(mvtk%vtk_unit)'VECTORS '//trim(sname)//' double'//NL - write(mvtk%vtk_unit)D - write(mvtk%vtk_unit)NL - else - write(mvtk%vtk_unit,'(A,A,A)') 'VECTORS ', sname, ' double' - write(mvtk%vtk_unit,'(3'//RFMT//')')D - endif - endif - end subroutine - - ! --------------------------------------------------------------------------------} - ! --- VTK Tools - ! --------------------------------------------------------------------------------{ - !> Exports a Plane From a mesh - subroutine export_plane_grid3d(fname,v1,v2,v3,Values,mvtk) - character(len=*),intent(in) :: fname - real(ReKi),dimension(:), intent(in) :: v1,v2,v3 - real(ReKi),dimension(:,:,:,:), intent(in) :: Values - type(FVW_VTK_Misc),intent(inout) :: mvtk - ! Variables - integer :: nD - - ! Writting - if ( vtk_new_ascii_file(trim(fname),'grid',mvtk)) then - nD=size(Values,1) - call vtk_dataset_rectilinear(v1,v2,v3,mvtk) - ! Output as a structured grid, No need to reorder - call vtk_point_data_init(mvtk) - ! Could be a function of nDim, be careful - if(nD==3) then - call vtk_point_data_vector(Values(1:3,:,:,:),'Velocity',mvtk) ! Label... - endif - - call vtk_close_file(mvtk) - endif ! file opening - end subroutine - - !> Exports a Plane From a mesh - subroutine export_plane_grid2d(fname,v1,v2,v3,Values,mvtk) - character(len=*),intent(in) :: fname - real(ReKi),dimension(:), intent(in) :: v1,v2,v3 - real(ReKi),dimension(:,:,:), intent(in) :: Values - type(FVW_VTK_Misc),intent(inout) :: mvtk - ! Variables - integer :: nD - - ! Writting - if ( vtk_new_ascii_file(trim(fname),'plane',mvtk) ) then - nD=size(Values,1) - call vtk_dataset_rectilinear(v1,v2,v3,mvtk) - ! Output as a structured grid, No need to reorder - call vtk_point_data_init(mvtk) - ! Could be a function of nDim, be careful - if(nD==3) then - call vtk_point_data_vector(Values(1:3,:,:),'Velocity',mvtk) ! Label... - endif - - call vtk_close_file(mvtk) - endif ! file opening - end subroutine -end module FVW_VTK diff --git a/modules/aerodyn/src/FVW_VortexTools.f90 b/modules/aerodyn/src/FVW_VortexTools.f90 index d07345127..7537b8e81 100644 --- a/modules/aerodyn/src/FVW_VortexTools.f90 +++ b/modules/aerodyn/src/FVW_VortexTools.f90 @@ -1,14 +1,35 @@ module FVW_VortexTools ! Contains Typical Tools for vortex methods - + ! ! Should be *independent* of the Framework and any derived type + ! apart from the types defined here: Tree, Seg and Part + ! + ! Only low-to-mid level functions! - ! Only low level functions ! - - use NWTC_LIBRARY + use NWTC_LIBRARY, only: ReKi, IntKi, num2lstr, ErrID_Fatal, ErrID_None, EqualRealNos !< Not desired + use NWTC_LIBRARY, only: InterpArray + use FVW_BiotSavart, only: fourpi_inv implicit none + logical,parameter :: DEV_VERSION_VT = .False. + + ! --- TIC TOC MODULE + ! Parameters + logical, parameter :: bSilentTicToc =.false. !< If set to true, will only show times bigger than SmartTicTocVal + logical, parameter :: bSmartTicToc =.true. !< If set to true, will only show times bigger than SmartTicTocVal + integer, parameter :: nmax_store=40 !< maximum number of storage in tic toc stack + integer, parameter :: nmax_label=46 !< maximum length of label + real(ReKi), parameter :: SmartTicTocVal=0.02_ReKi !< duration below this value will not be displayed (if bSmartTicToc is True) + ! Reals + real(ReKi), save :: start_time,finish_time + ! Tic toc stack arrays + integer, save :: npos = 0 ! < position on the stack + integer, dimension(8), save :: time_array + integer, dimension(nmax_store,8), save :: start_arrays = 0 + character(len=nmax_label), dimension(nmax_store), save :: labels + ! --- END TIC TOC MODULE + ! Tree parameters integer, parameter :: IK1 = selected_int_kind(1) ! to store particle branch number (from 1 to 8) integer,parameter :: M0 = 1, M1_1=2, M1_2=3, M1_3=4, M2_11=5, M2_21=6, M2_22=7, M2_31=8, M2_32=9, M2_33=10 ! For moment coefficients @@ -18,53 +39,45 @@ module FVW_VortexTools integer,parameter :: M1_001 = 4 !> - type T_Part + type T_VPart real(ReKi), dimension(:,:), pointer :: P =>null() real(ReKi), dimension(:,:), pointer :: Alpha =>null() real(ReKi), dimension(:), pointer :: RegParam =>null() integer(IntKi) :: RegFunction =-1 integer(IntKi) :: n =-1 - end type T_Part + end type T_VPart !> - type T_Seg + type T_VSgmt real(ReKi), dimension(:,:), pointer :: SP =>null() integer(IntKi), dimension(:,:), pointer :: SConnct =>null() real(ReKi), dimension(:), pointer :: SGamma =>null() real(ReKi), dimension(:), pointer :: RegParam =>null() integer(IntKi) :: RegFunction =-1 integer(IntKi) :: n =-1 - end type T_Seg + end type T_VSgmt !> The node type is recursive and is used to make a chained-list of nodes for the tree type T_Node real(ReKi) :: radius !< Typical dimension of a cell (max of x,y,z extent) - real(ReKi),dimension(3) :: center + real(ReKi),dimension(3) :: center !< Used to store first the geometric center, then the vorticity center real(ReKi),dimension(3,10) :: Moments integer,dimension(:),pointer :: iPart=>null() !< indexes of particles stored in this node integer,dimension(:),pointer :: leaves=>null() ! NOTE: leaves are introduced to save memory type(T_Node),dimension(:), pointer :: branches =>null() integer :: nPart = -1 ! Number of particles in branches and leaves of this node - integer(IntKi) :: idBranch ! Index of the branch end type T_Node !> The type tree contains some basic data, a chained-list of nodes, and a pointer to the Particle data that were used type T_Tree - type(T_Part) :: Part !< Storage for all particles - type(T_Seg) :: Seg !< Storage for all particles + type(T_VPart) :: Part !< Storage for all particles + type(T_VSgmt) :: Seg !< Storage for all segments integer :: iStep =-1 !< Time step at which the tree was built logical :: bGrown =.false. !< Is the tree build real(ReKi) :: DistanceDirect type(T_Node) :: Root !< Contains the chained-list of nodes end type T_Tree - type T_Tree_Seg - type(T_Seg) :: Seg !< Storage for all particles - integer :: iStep =-1 !< Time step at which the tree was built - logical :: bGrown =.false. !< Is the tree build - type(T_Node) :: Root !< Contains the chained-list of nodes - end type T_Tree_Seg - interface cut_tree module procedure cut_tree_parallel ; ! to switch between parallel and rec easily end interface @@ -250,7 +263,7 @@ subroutine LatticeToPoints2D(LatticePoints, Points, iHeadP) real(ReKi), dimension(:,:), intent(inout) :: Points !< integer(IntKi), intent(inout) :: iHeadP !< Index indicating where to start in Points ! Local - integer(IntKi) :: iSpan, iDepth + integer(IntKi) :: iSpan do iSpan = 1, size(LatticePoints,2) Points(1:3,iHeadP) = LatticePoints(1:3, iSpan) iHeadP=iHeadP+1 @@ -402,7 +415,18 @@ subroutine SegmentsToPart(SegPoints, SegConnct, SegGamma, SegEpsilon, iSegStart, P2 = SegPoints(1:3,SegConnct(2,iSeg)) DP = P2-P1 SegLen = sqrt(DP(1)**2 + DP(2)**2 + DP(3)**2) - SegDir = DP/SegLen ! Unit vector along segment direction + if (SegLen>0) then + SegDir = DP/SegLen ! Unit vector along segment direction + else + ! For now we set direction to zero. Part. Intensity will be zero. Multiple zero part may be created at P1 + ! In the future we should skip the creation of the particles all together + SegDir = 0 + if (DEV_VERSION_VT) then + ! This is prone to happening with turbulence and single precision + print*,'OLAF: encountered a segment of zero length' + STOP + endif + endif PartInt = DP*SegGamma(iSeg)/nPartPerSeg ! alpha = Gamma.L/n = omega.dV [m^3/s] PartEps = SegEpsilon(iSeg) ! TODO this might need tuning depending on RegFunction and n_new PartLen = SegLen/nPartPerSeg @@ -447,9 +471,50 @@ subroutine print_mean_3d(M, Label) enddo; enddo; U(1:3)=U(1:3)/ (size(M,3)*size(M,2)) endif - print'(A24,3F12.4)',trim(Label),U + print'(A25,3F12.4)',trim(Label),U end subroutine + subroutine find_equal_points(array, varname) + real(ReKi), dimension(:,:,:), intent(in) :: array ! 3*n*m + character(len=*), intent(in) :: varname + logical :: found + integer :: iSpan, jSpan, iDepth, jDepth, tot + real(ReKi), dimension(3) :: DP, P1, P2 + real(ReKi) ::s1 + ! Check if two points are the same + found=.false. + tot=0 + do iDepth = 1, size(array,3) + do iSpan = 1, size(array,2) + P1 = array(1:3, iSpan , iDepth) + do jDepth = iDepth, size(array,3) + do jSpan = iSpan, size(array,2) + if ((iDepth==jDepth) .and. (iSpan == jSpan)) then + ! pass + else + P2 = array(1:3, jSpan, jDepth) + DP = P2-P1; s1 = sqrt(DP(1)**2 + DP(2)**2 + DP(3)**2) + if (s1<=0) then + tot=tot+1; found=.true. + if (tot<5) then + print*,'Two points are the same on the lattice!' + print*,'P1', P1, 'i', iSpan, iDepth + print*,'P2', P2, 'j', jSpan, jDepth + endif + endif + + endif + enddo + enddo + enddo + enddo + if (found) then + print*,'>>>>>>>>>>>>> Points the same ',trim(varname), tot, size(array,2)*size(array,3) + print*,'>>>>>>>>>>>>> Lattice size ', size(array,2), size(array,3) + STOP + endif + end subroutine find_equal_points + !> Perform interpolation from control points to nodes assuming CP are between nodes subroutine interpextrap_cp2node(xin, yin, xnew, ynew) real(ReKi), intent(in ) :: xin(:) @@ -480,15 +545,16 @@ end subroutine interpextrap_cp2node ! --------------------------------------------------------------------------------} ! --- Tree -Grow ! --------------------------------------------------------------------------------{ - subroutine grow_tree(Tree, PartP, PartAlpha, PartRegFunction, PartRegParam, iStep) + subroutine grow_tree_part(Tree, nPart, PartP, PartAlpha, PartRegFunction, PartRegParam, iStep) type(T_Tree), intent(inout), target :: Tree !< + integer(IntKi), intent(in ) :: nPart !< real(ReKi), dimension(:,:), intent(in ), target :: PartP !< real(ReKi), dimension(:,:), intent(in ), target :: PartAlpha !< integer(IntKi), intent(in ) :: PartRegFunction !< real(ReKi), dimension(:), intent(in ), target :: PartRegParam !< integer(IntKi), intent(in ) :: iStep !< type(T_Node), pointer :: node !< Alias - type(T_Part), pointer :: Part !< Alias + type(T_VPart), pointer :: Part !< Alias real(ReKi) :: max_x,max_y,max_z !< for domain dimension real(ReKi) :: min_x,min_y,min_z !< for domain dimension integer(IntKi) :: i @@ -501,15 +567,16 @@ subroutine grow_tree(Tree, PartP, PartAlpha, PartRegFunction, PartRegParam, iSte nullify(Tree%Part%P) nullify(Tree%Part%Alpha) nullify(Tree%Part%RegParam) - Tree%Part%P => PartP - Tree%Part%Alpha => PartAlpha - Tree%Part%RegParam => PartRegParam + Tree%Part%P => PartP(:,1:nPart) + Tree%Part%Alpha => PartAlpha(:,1:nPart) + Tree%Part%RegParam => PartRegParam(1:nPart) Tree%Part%RegFunction = PartRegFunction - Tree%Part%n = size(PartP,2) + Tree%Part%n = nPart ! --- Handle special case for root node node => Tree%Root Part => Tree%Part + node%nPart = Part%n if (Part%n==0) then ! Do nothing node%radius = -9999.99_ReKi @@ -522,8 +589,7 @@ subroutine grow_tree(Tree, PartP, PartAlpha, PartRegFunction, PartRegParam, iSte nullify(node%iPart) nullify(node%branches) allocate(node%leaves(1:1)) - node%leaves(1) = Part%n !< index - node%nPart = 1 + node%leaves(1) = 1 !< index else ! Domain dimensions max_x=maxval(Part%P(1,1:Part%n)); max_y=maxval(Part%P(2,1:Part%n)); max_z=maxval(Part%P(3,1:Part%n)) @@ -532,48 +598,52 @@ subroutine grow_tree(Tree, PartP, PartAlpha, PartRegFunction, PartRegParam, iSte ! Init of trunc ! Radius taken slightly bigger than domain extent. This radius will be divided by 2 successively node%radius = max(abs(max_x-min_x),abs(max_y-min_y),abs(max_z-min_z))*1.001_ReKi - if(node%radius>1e6) then - print*,'[Error] Domain extent too large, particle points must be invalid'; - print*, min_x, max_x, min_y, max_y, min_z, max_z - STOP - endif node%center = (/ (max_x+min_x)/2._ReKi, (max_y+min_y)/2._ReKi, (max_z+min_z)/2._ReKi /) node%Moments=0.0_ReKi - if(associated(node%iPart)) then ; print*,'[Error] Node part allocated'; STOP; endif + if (DEV_VERSION_VT) then + if(node%radius>1e6) then + print*,'[Error] Domain extent too large, particle points must be invalid'; + print*, min_x, max_x, min_y, max_y, min_z, max_z + STOP + endif + if(associated(node%iPart)) then ; print*,'[Error] Node part allocated'; STOP; endif + endif allocate(node%iPart(1:Part%n)) do i=1,Part%n node%iPart(i) = i end do - if(associated(node%branches)) then; print*,'node branches allocated'; STOP; endif - if(associated(node%leaves)) then; print*,'node leaves allocated'; STOP; endif + if (DEV_VERSION_VT) then + if(associated(node%branches)) then; print*,'node branches allocated'; STOP; endif + if(associated(node%leaves)) then; print*,'node leaves allocated'; STOP; endif + endif node%branches=>null() node%leaves=>null() - node%nPart=Part%n ! --- Calling grow function on subbranches - call grow_tree_parallel(Tree%root, Tree%Part) + call grow_tree_part_parallel(Tree%root, Tree%Part) ! call grow_tree_rec(Tree%root, Tree%Part) endif Tree%iStep = iStep Tree%bGrown = .true. - end subroutine grow_tree + Tree%DistanceDirect = 2*sum(PartRegParam)/size(PartRegParam) ! 2*mean(eps), below that distance eps has a strong effect + end subroutine grow_tree_part !> Recursive function to grow/setup a tree. !! Note, needed preliminary calc are done by grow_tree before - recursive subroutine grow_tree_rec(node, Part) + recursive subroutine grow_tree_part_rec(node, Part) type(T_Node), target :: node !< - type(T_Part), intent(in) :: Part !< + type(T_VPart), intent(in) :: Part !< integer :: i ! Sub Step: ! - compute moments and center for the current node ! - allocate branches and leaves - call grow_tree_substep(node, Part) + call grow_tree_part_substep(node, Part) ! Call grow_tree on branches if(associated(node%branches)) then do i = 1,size(node%branches) - call grow_tree_rec(node%branches(i), Part) + call grow_tree_part_rec(node%branches(i), Part) end do endif - end subroutine grow_tree_rec + end subroutine grow_tree_part_rec !> Perform a substep of tree growth, growing sub branches from a given node/cell !! Parent has already setup node%iPart, indices of the particle in this cell @@ -582,35 +652,35 @@ end subroutine grow_tree_rec !! - Compute node moments !! - Distribute particles in each 8 octants. Branches are not created for empty octant !! - Allocate branches and leaves and distribute particles to them - subroutine grow_tree_substep(node, Part) + subroutine grow_tree_part_substep(node, Part) type(T_Node), intent(inout) :: node !< Current node we are growing from - type(T_Part), intent(in) :: Part !< All particles info + type(T_VPart), intent(in) :: Part !< All particles info integer(IK1) :: iPartOctant !< Index corresponding to which octant the particle falls into integer :: nLeaves, nBranches integer :: iLeaf, iOctant, iBranch - integer :: i1,i2,i3,i4,i5,i6,i7,i8 - integer :: i,j,k + integer :: nPerBranchAcc(8) !< Accumulated counter on number of particles per branch + integer :: i !,j,k real(ReKi) :: wTot, wLoc ! Total and local vorticity strength real(ReKi) :: halfSize ! TODO remove me real(ReKi),dimension(3) :: locCenter, DeltaP,PartPos,PartAlpha - real(ReKi),dimension(3) :: nodeGeomCenter !< Geometric center from division of the domain in powers of 2 - real(ReKi),dimension(3) :: nodeBaryCenter !< Vorticity weighted center + real(ReKi),dimension(3) :: GeomC !< Geometric center from division of the domain in powers of 2 + real(ReKi),dimension(3) :: VortC !< Vorticity weighted center integer(IK1),dimension(:),allocatable :: PartOctant !< Stores the octant (1-8) where each particle belongs integer,dimension(8) :: npart_per_octant !< Number of particle per octant integer,dimension(8) :: octant2branches !< Mapping between 8 octants, to index of non empty branch integer,dimension(8) :: octant2leaves !< Idem for singleton/leaves real(ReKi) :: max_x,max_y,max_z !< for domain dimension real(ReKi) :: min_x,min_y,min_z !< for domain dimension - nodeGeomCenter = node%center ! NOTE: we rely on the fact that our parent has set this to the Geometric value - nodeBaryCenter = 0.0_ReKi + GeomC = node%center ! NOTE: we rely on the fact that our parent has set this to the Geometric value + VortC = 0.0_ReKi wTot = 0.0_ReKi ! --- Barycenter of vorticity of the node do i = 1,node%nPart - PartPos = Part%P(:,node%iPart(i)) - PartAlpha = Part%Alpha(:,node%iPart(i)) - wLoc = (PartAlpha(1)**2 + PartAlpha(2)**2 + PartAlpha(3)**2)**0.5_ReKi ! Vorticity norm - nodeBaryCenter = nodeBaryCenter + wLoc*PartPos ! Sum coordinates weighted by vorticity - wTot = wTot + wLoc ! Total vorticity + PartPos = Part%P(:,node%iPart(i)) + PartAlpha = Part%Alpha(:,node%iPart(i)) + wLoc = (PartAlpha(1)**2 + PartAlpha(2)**2 + PartAlpha(3)**2)**0.5_ReKi ! Vorticity norm + VortC = VortC + wLoc*PartPos ! Sum coordinates weighted by vorticity + wTot = wTot + wLoc ! Total vorticity end do ! There is no vorticity, we make it a empty node and we exit if(EqualRealNos(abs(wTot),0.0_ReKi)) then @@ -618,14 +688,14 @@ subroutine grow_tree_substep(node, Part) if (associated(node%iPart)) deallocate(node%iPart) return ! NOTE: we exit endif - nodeBaryCenter = nodeBaryCenter/wTot ! barycenter of vorticity - node%center = nodeBaryCenter ! updating + VortC = VortC/wTot ! barycenter of vorticity + node%center = VortC ! updating center, it's now the vorticity center, geomCenter will be use to divide cell though - ! --- Calculation of moments about nodeBaryCenter + ! --- Calculation of moments about VortC do i = 1,node%nPart PartPos = Part%P (:,node%iPart(i)) PartAlpha = Part%Alpha(:,node%iPart(i)) - DeltaP = PartPos-nodeBaryCenter + DeltaP = PartPos-VortC ! Order 0 node%Moments(1:3,M0_000) = node%Moments(1:3,M0_000) + PartAlpha ! 1st order @@ -633,11 +703,18 @@ subroutine grow_tree_substep(node, Part) node%Moments(1:3,M1_010) = node%Moments(1:3,M1_010) + PartAlpha*DeltaP(2) ! 010 node%Moments(1:3,M1_001) = node%Moments(1:3,M1_001) + PartAlpha*DeltaP(3) ! 001 ! 2nd order - do j=1,3 - do k=1,j - node%Moments(1:3,3+j+k+j/3) = node%Moments(1:3,3+j+k+j/3) + PartAlpha*DeltaP(j)*DeltaP(k) - end do - end do + ! KEEP ME: + ! do j=1,3 + ! do k=1,j + ! node%Moments(1:3,3+j+k+j/3) = node%Moments(1:3,3+j+k+j/3) + PartAlpha*DeltaP(j)*DeltaP(k) + ! end do + ! end do + node%Moments(1:3, 5) = node%Moments(1:3, 5) + PartAlpha*DeltaP(1)*DeltaP(1) ! j=1,k=1 + node%Moments(1:3, 6) = node%Moments(1:3, 6) + PartAlpha*DeltaP(2)*DeltaP(1) ! j=2,k=1 + node%Moments(1:3, 7) = node%Moments(1:3, 7) + PartAlpha*DeltaP(2)*DeltaP(2) ! j=2,k=2 + node%Moments(1:3, 8) = node%Moments(1:3, 8) + PartAlpha*DeltaP(3)*DeltaP(1) ! j=3,k=1 + node%Moments(1:3, 9) = node%Moments(1:3, 9) + PartAlpha*DeltaP(3)*DeltaP(2) ! j=3,k=2 + node%Moments(1:3,10) = node%Moments(1:3,10) + PartAlpha*DeltaP(3)*DeltaP(3) ! j=3,k=3 end do ! --- Distributing particles to the 8 octants (based on the geometric center!) @@ -647,9 +724,9 @@ subroutine grow_tree_substep(node, Part) PartPos = Part%P(:,node%iPart(i)) ! index corresponding to which octant the particle falls into iPartOctant = int(1,IK1) - if (PartPos(1) > nodeGeomCenter(1)) iPartOctant = iPartOctant + int(1,IK1) - if (PartPos(2) > nodeGeomCenter(2)) iPartOctant = iPartOctant + int(2,IK1) - if (PartPos(3) > nodeGeomCenter(3)) iPartOctant = iPartOctant + int(4,IK1) + if (PartPos(1) > GeomC(1)) iPartOctant = iPartOctant + int(1,IK1) + if (PartPos(2) > GeomC(2)) iPartOctant = iPartOctant + int(2,IK1) + if (PartPos(3) > GeomC(3)) iPartOctant = iPartOctant + int(4,IK1) npart_per_octant(iPartOctant) = npart_per_octant(iPartOctant) + 1 ! Counter of particles per octant PartOctant(i)=iPartOctant ! Store in which octant particle i is end do @@ -687,14 +764,16 @@ subroutine grow_tree_substep(node, Part) octant2branches(iOctant) = nBranches endif enddo - if (associated(node%branches)) then - print*,'Tree build: error, branches associated' - STOP + if (DEV_VERSION_VT) then + if (associated(node%branches)) then + print*,'Tree build: error, branches associated' + STOP + endif + if (associated(node%leaves)) then + print*,'Tree build: error, leaves associated' + STOP + end if endif - if (associated(node%leaves)) then - print*,'Tree build: error, leaves associated' - STOP - end if if(nBranches>0) allocate (node%branches(1:nBranches)) if(nLeaves>0) allocate (node%leaves(1:nLeaves)) @@ -707,7 +786,7 @@ subroutine grow_tree_substep(node, Part) allocate(node%branches(iBranch)%iPart(1:npart_per_octant(iOctant))) node%branches(iBranch)%nPart=npart_per_octant(iOctant) ! NOTE: this is geometric center not barycenter - locCenter = nodeGeomCenter + 0.5*halfSize*(/ (-1)**(iOctant), (-1)**floor(0.5*real(iOctant-1)+1), (-1)**floor(0.25*real(iOctant-1)+1) /) + locCenter = GeomC + 0.5*halfSize*(/ (-1)**(iOctant), (-1)**floor(0.5*real(iOctant-1)+1), (-1)**floor(0.25*real(iOctant-1)+1) /) ! Init of branches node%branches(iBranch)%radius = halfSize ! node%branches(iBranch)%center = locCenter ! NOTE: this is the geometric center @@ -719,20 +798,11 @@ subroutine grow_tree_substep(node, Part) end do ! Store indices of the particles the sub-branch contains - i1=0; i2=0; i3=0; i4=0; i5=0; i6=0; i7=0; i8=0; + nPerBranchAcc(:) = 0 do i = 1,node%nPart iBranch = octant2branches(PartOctant(i)) if(iBranch>0) then - select case(iBranch) - case(1);i1=i1+1; node%branches(1)%iPart(i1) = node%iPart(i) - case(2);i2=i2+1; node%branches(2)%iPart(i2) = node%iPart(i) - case(3);i3=i3+1; node%branches(3)%iPart(i3) = node%iPart(i) - case(4);i4=i4+1; node%branches(4)%iPart(i4) = node%iPart(i) - case(5);i5=i5+1; node%branches(5)%iPart(i5) = node%iPart(i) - case(6);i6=i6+1; node%branches(6)%iPart(i6) = node%iPart(i) - case(7);i7=i7+1; node%branches(7)%iPart(i7) = node%iPart(i) - case(8);i8=i8+1; node%branches(8)%iPart(i8) = node%iPart(i) - end select + nPerBranchAcc(iBranch)=nPerBranchAcc(iBranch)+1; node%branches(iBranch)%iPart(nPerBranchAcc(iBranch)) = node%iPart(i) else iLeaf = octant2leaves(PartOctant(i)) if(iLeaf>0) then @@ -743,15 +813,23 @@ subroutine grow_tree_substep(node, Part) endif endif end do + if (DEV_VERSION_VT) then + do iBranch=1,nBranches + if (nPerBranchAcc(iBranch)/=node%branches(iBranch)%nPart) then + print*,'Grow tree: Problem in repartition of particles per branches' + STOP + endif + enddo + endif if (associated(node%iPart)) deallocate(node%iPart) ! Freeing memory if (allocated(PartOctant)) deallocate(PartOctant) - end subroutine grow_tree_substep + end subroutine grow_tree_part_substep !> Grow a tree in "parallel", since recursive calls cannot be parallized easily, we unroll the different layer calls !! Note, needed preliminary calc are done by grow_tree before! - subroutine grow_tree_parallel(Root, Part) + subroutine grow_tree_part_parallel(Root, Part) type(T_Node), intent(inout) :: Root - type(T_Part), intent(in) :: Part + type(T_VPart), intent(in) :: Part integer :: i, nBranches integer :: i1 integer :: i2 @@ -760,7 +838,7 @@ subroutine grow_tree_parallel(Root, Part) ! Sub Step: ! - compute moments and center for the current node ! - allocate branches and leaves - call grow_tree_substep(Root, Part) + call grow_tree_part_substep(Root, Part) if(.not. associated(Root%branches)) then nBranches=0 @@ -778,7 +856,7 @@ subroutine grow_tree_parallel(Root, Part) !$OMP do private(i) schedule(runtime) do i = 1,nBranches ! maximum 8 branches if(Root%branches(i)%nPart>1) then ! I dont think this test is needed - call grow_tree_substep(Root%branches(i), Part) + call grow_tree_part_substep(Root%branches(i), Part) endif end do !$OMP end do @@ -790,7 +868,7 @@ subroutine grow_tree_parallel(Root, Part) i2=mod(i-1,8)+1; if(associated(Root%branches(i1)%branches)) then if (i2<=size(Root%branches(i1)%branches)) then - call grow_tree_rec(Root%branches(i1)%branches(i2), Part) + call grow_tree_part_rec(Root%branches(i1)%branches(i2), Part) endif endif enddo @@ -799,12 +877,13 @@ subroutine grow_tree_parallel(Root, Part) !$OMP END PARALLEL endif endif - end subroutine grow_tree_parallel + end subroutine grow_tree_part_parallel ! --------------------------------------------------------------------------------} ! --- Tree -Grow for vortex lines ! --------------------------------------------------------------------------------{ - subroutine grow_tree_segment(Tree_Seg, SegPoints, SegConnct,SegGamma, SegRegFunction, SegRegParam, iStep) + subroutine grow_tree_segment(Tree_Seg, nSeg, SegPoints, SegConnct, SegGamma, SegRegFunction, SegRegParam, iStep) type(T_Tree), intent(inout), target :: Tree_Seg !< + integer(IntKi), intent(in ) :: nSeg !< real(ReKi), dimension(:,:), intent(in ), target :: SegPoints !< integer(IntKi), dimension(:,:), intent(in ), target :: SegConnct !< real(ReKi), dimension(:), intent(in ), target :: SegGamma !< @@ -812,7 +891,7 @@ subroutine grow_tree_segment(Tree_Seg, SegPoints, SegConnct,SegGamma, SegRegFunc real(ReKi), dimension(:), intent(in ), target :: SegRegParam !< integer(IntKi), intent(in ) :: iStep !< type(T_Node), pointer :: node !< Alias - type(T_Seg), pointer :: Seg !< Alias + type(T_VSgmt), pointer :: Seg !< Alias real(ReKi) :: max_x,max_y,max_z !< for domain dimension real(ReKi) :: min_x,min_y,min_z !< for domain dimension integer(IntKi) :: i @@ -827,12 +906,11 @@ subroutine grow_tree_segment(Tree_Seg, SegPoints, SegConnct,SegGamma, SegRegFunc nullify(Tree_Seg%Seg%SGamma) nullify(Tree_Seg%Seg%RegParam) Tree_Seg%Seg%SP => SegPoints - Tree_Seg%Seg%SConnct => SegConnct - Tree_Seg%Seg%SGamma => SegGamma - Tree_Seg%Seg%RegParam => SegRegParam + Tree_Seg%Seg%SConnct => SegConnct(:,1:nSeg) + Tree_Seg%Seg%SGamma => SegGamma(1:nSeg) + Tree_Seg%Seg%RegParam => SegRegParam(1:nSeg) Tree_Seg%Seg%RegFunction = SegRegFunction - Tree_Seg%Seg%n = size(SegConnct,2) - + Tree_Seg%Seg%n = nSeg ! --- Handle special case for root node node => Tree_Seg%Root @@ -852,10 +930,6 @@ subroutine grow_tree_segment(Tree_Seg, SegPoints, SegConnct,SegGamma, SegRegFunc node%leaves(1) = Seg%n !< index node%nPart = 1 else - if (any(Seg%SP(1,:)<-999.99_ReKi)) then - print*,'Error in segment transmission to grow tree segment' - STOP - endif ! Domain dimensions max_x=max(maxval(Seg%SP(1,Seg%SConnct(1,:))),maxval(Seg%SP(1,Seg%SConnct(2,:)))) max_y=max(maxval(Seg%SP(2,Seg%SConnct(1,:))),maxval(Seg%SP(2,Seg%SConnct(2,:)))) @@ -867,47 +941,53 @@ subroutine grow_tree_segment(Tree_Seg, SegPoints, SegConnct,SegGamma, SegRegFunc ! Init of trunc ! Radius taken slightly bigger than domain extent. This radius will be divided by 2 successively node%radius = max(abs(max_x-min_x),abs(max_y-min_y),abs(max_z-min_z))*1.001_ReKi - if(node%radius>1e6) then - print*,'[Error] Domain extent too large, segment points must be invalid'; - print*, min_x, max_x, min_y, max_y, min_z, max_z - STOP - endif node%center = (/ (max_x+min_x)/2._ReKi, (max_y+min_y)/2._ReKi, (max_z+min_z)/2._ReKi /) node%Moments=0.0_ReKi - if(associated(node%iPart)) then ; print*,'[Error] Node part allocated'; STOP; endif + if (DEV_VERSION_VT) then + if (any(Seg%SP(1,:)<-999.99_ReKi)) then + print*,'Error in segment transmission to grow tree segment' + STOP + endif + if(node%radius>1e6) then + print*,'[Error] Domain extent too large, segment points must be invalid'; + print*, min_x, max_x, min_y, max_y, min_z, max_z + STOP + endif + if(associated(node%iPart)) then ; print*,'[Error] Node part allocated'; STOP; endif + endif allocate(node%iPart(1:Seg%n)) do i=1,Seg%n node%iPart(i) = i end do - if(associated(node%branches)) then; print*,'node branches allocated'; STOP; endif - if(associated(node%leaves)) then; print*,'node leaves allocated'; STOP; endif + if (DEV_VERSION_VT) then + if(associated(node%branches)) then; print*,'node branches allocated'; STOP; endif + if(associated(node%leaves)) then; print*,'node leaves allocated'; STOP; endif + endif node%branches=>null() node%leaves=>null() node%nPart=Seg%n ! --- Calling grow function on subbranches call grow_tree_segment_parallel(Tree_Seg%root, Tree_Seg%Seg) -! call grow_tree_rec(Tree%root, Tree%Part) + !call grow_tree_segment_rec(Tree_Seg%root, Tree_Seg%Seg) endif Tree_Seg%iStep = iStep Tree_Seg%bGrown = .true. + Tree_Seg%DistanceDirect = 2*sum(SegRegParam)/size(SegRegParam) ! 2*mean(eps), below that distance eps has a strong effect ! TODO REMOVE end subroutine grow_tree_segment !> Recursive function to grow/setup a tree. !! Note, needed preliminary calc are done by grow_tree before recursive subroutine grow_tree_segment_rec(node, Seg) type(T_Node), target :: node !< - type(T_Seg), intent(in) :: Seg !< + type(T_VSgmt), intent(in) :: Seg !< integer :: i ! Sub Step: ! - compute moments and center for the current node ! - allocate branches and leaves - !write(*,*) 'Calling grow_tree_segment_substep in rec' - !write(*,*) 'node%nPart', node%nPart call grow_tree_segment_substep(node, Seg) ! Call grow_tree on branches if(associated(node%branches)) then do i = 1,size(node%branches) - !write(*,*) 'calling rec' call grow_tree_segment_rec(node%branches(i), Seg) end do endif @@ -922,36 +1002,34 @@ end subroutine grow_tree_segment_rec !! - Allocate branches and leaves and distribute particles to them subroutine grow_tree_segment_substep(node, Seg) type(T_Node), intent(inout) :: node !< Current node we are growing from - type(T_Seg), intent(in) :: Seg !< All particles info + type(T_VSgmt), intent(in) :: Seg !< All particles info integer(IK1) :: iPartOctant !< Index corresponding to which octant the particle falls into integer :: nLeaves, nBranches integer :: iLeaf, iOctant, iBranch - integer :: i1,i2,i3,i4,i5,i6,i7,i8 - integer :: i,j,k + integer :: nPerBranchAcc(8) !< Accumulated counter on number of particles per branch + integer :: i!,j,k real(ReKi) :: wTot ! Total vorticity strength - real(ReKi) :: SegLen ! Length of vortex segment real(ReKi) :: halfSize ! TODO remove me - real(ReKi),dimension(3) :: locCenter, DeltaP,SegCenter,DP, SegDir, SegGammaVec + real(ReKi),dimension(3) :: locCenter, SegCenter,DP, SegGammaVec real(ReKi),dimension(3) :: P1,P2 !< Segment extremities - real(ReKi),dimension(3) :: nodeGeomCenter !< Geometric center from division of the domain in powers of 2 - real(ReKi),dimension(3) :: nodeBaryCenter !< Vorticity weighted center + real(ReKi),dimension(3) :: GeomC !< Geometric center from division of the domain in powers of 2 + real(ReKi),dimension(3) :: VortC !< Vorticity weighted center integer(IK1),dimension(:),allocatable :: PartOctant !< Stores the octant (1-8) where each particle belongs integer,dimension(8) :: npart_per_octant !< Number of particle per octant integer,dimension(8) :: octant2branches !< Mapping between 8 octants, to index of non empty branch integer,dimension(8) :: octant2leaves !< Idem for singleton/leaves real(ReKi) :: max_x,max_y,max_z !< for domain dimension real(ReKi) :: min_x,min_y,min_z !< for domain dimension - nodeGeomCenter = node%center ! NOTE: we rely on the fact that our parent has set this to the Geometric value - nodeBaryCenter = 0.0_ReKi + GeomC = node%center ! NOTE: we rely on the fact that our parent has set this to the Geometric value + VortC = 0.0_ReKi wTot = 0.0_ReKi ! --- Barycenter of vorticity of the node - !write(*,*) Seg%SConnct do i = 1,node%nPart P1 = Seg%SP(1:3,Seg%SConnct(1,node%iPart(i))) P2 = Seg%SP(1:3,Seg%SConnct(2,node%iPart(i))) - SegCenter = 0.5_ReKi*(P1+P2) - nodeBaryCenter = nodeBaryCenter + abs(Seg%SGamma(node%iPart(i)))*SegCenter ! Sum coordinates weighted by vorticity - wTot = wTot + abs(Seg%SGamma(node%iPart(i))) ! Total vorticity + SegCenter = 0.5_ReKi*(P1+P2) + VortC = VortC + abs(Seg%SGamma(node%iPart(i)))*SegCenter ! Sum coordinates weighted by vorticity + wTot = wTot + abs(Seg%SGamma(node%iPart(i))) ! Total vorticity end do ! There is no vorticity, we make it a empty node and we exit if(EqualRealNos(abs(wTot),0.0_ReKi)) then @@ -959,44 +1037,41 @@ subroutine grow_tree_segment_substep(node, Seg) if (associated(node%iPart)) deallocate(node%iPart) return ! NOTE: we exit endif - nodeBaryCenter = nodeBaryCenter/wTot ! barycenter of vorticity - node%center = nodeBaryCenter ! updating + VortC = VortC/wTot ! barycenter of vorticity + node%center = VortC ! updating center, it's now the vorticity center, geomCenter will be use to divide cell though - ! --- Calculation of moments about nodeBaryCenter - !write(*,*) 'node%nPart', node%nPart + ! --- Calculation of moments about VortC do i = 1,node%nPart P1 = Seg%SP(1:3,Seg%SConnct(1,node%iPart(i))) P2 = Seg%SP(1:3,Seg%SConnct(2,node%iPart(i))) DP = P2-P1 - SegLen = sqrt(DP(1)**2 + DP(2)**2 + DP(3)**2) - SegDir = DP/SegLen ! Unit vector along segment direction SegGammaVec = Seg%SGamma(node%iPart(i))*DP !Vorticity vector ! Order 0 node%Moments(1:3,M0_000) = node%Moments(1:3,M0_000) + SegGammaVec - !write(*,*) 'M0_000', node%Moments(1:3,M0_000) ! 1st order - node%Moments(1:3,M1_100) = node%Moments(1:3,M1_100) + SegGammaVec*(0.5_ReKi*(P1(1)+P2(1))-nodeBaryCenter(1)) ! 100 - node%Moments(1:3,M1_010) = node%Moments(1:3,M1_010) + SegGammaVec*(0.5_ReKi*(P1(2)+P2(2))-nodeBaryCenter(2)) ! 010 - node%Moments(1:3,M1_001) = node%Moments(1:3,M1_001) + SegGammaVec*(0.5_ReKi*(P1(3)+P2(3))-nodeBaryCenter(3)) ! 001 - ! write(*,*) 'M1_100', node%Moments(1:3,M1_100) ! 1st order - ! write(*,*) 'M1_010', node%Moments(1:3,M1_010) ! 1st order - ! write(*,*) 'M1_001', node%Moments(1:3,M1_001) ! 1st order + node%Moments(1:3,M1_100) = node%Moments(1:3,M1_100) + SegGammaVec*(0.5_ReKi*(P1(1)+P2(1))-VortC(1)) ! 100 + node%Moments(1:3,M1_010) = node%Moments(1:3,M1_010) + SegGammaVec*(0.5_ReKi*(P1(2)+P2(2))-VortC(2)) ! 010 + node%Moments(1:3,M1_001) = node%Moments(1:3,M1_001) + SegGammaVec*(0.5_ReKi*(P1(3)+P2(3))-VortC(3)) ! 001 ! 2nd order - do j=1,3 - do k=1,j - if (j==k) then - node%Moments(1:3,3+j+k+j/3) = node%Moments(1:3,3+j+k+j/3) + SegGammaVec*1/3.0_ReKi*(3*nodeBaryCenter(j)**2 & - -3*nodeBaryCenter(j)*(P1(j)+P2(j))+P1(j)**2+P1(j)*P2(j)+P2(j)**2) - - else - node%Moments(1:3,3+j+k+j/3) = node%Moments(1:3,3+j+k+j/3) + SegGammaVec*1/6.0_ReKi*( & - 6*nodeBaryCenter(j)*nodeBaryCenter(k) & - -3*nodeBaryCenter(j)*(P1(k)+P2(k)) & - +P1(j)*(-3*nodeBaryCenter(k)+2*P1(k)+P2(k)) & - +P2(j)*(-3*nodeBaryCenter(k)+P1(k)+2*P2(k))) - end if - ! write(*,*) 'M2', (3+j+k+j/3), node%Moments(1:3,3+j+k+j/3) - end do - end do + ! KEEP ME + !do j=1,3 + ! do k=1,j + ! if (j==k) then + ! node%Moments(1:3,3+j+k+j/3) = node%Moments(1:3,3+j+k+j/3) + SegGammaVec*1/3.0_ReKi*(3*VortC(j)**2 -3*VortC(j)*(P1(j)+P2(j))+P1(j)**2+P1(j)*P2(j)+P2(j)**2) + + ! else + ! node%Moments(1:3,3+j+k+j/3) = node%Moments(1:3,3+j+k+j/3) + SegGammaVec*1/6.0_ReKi*( 6*VortC(j)*VortC(k) -3*VortC(j)*(P1(k)+P2(k)) +P1(j)*(-3*VortC(k)+2*P1(k)+P2(k)) +P2(j)*(-3*VortC(k)+P1(k)+2*P2(k))) + ! end if + ! end do + !end do + + !node%Moments(1:3,3+j+k+j/3) = node%Moments(1:3,3+j+k+j/3) + SegGammaVec*1/3.0_ReKi*(3*VortC(j)**2 -3*VortC(j)*(P1(j)+P2(j))+P1(j)**2+P1(j)*P2(j)+P2(j)**2) + node%Moments(1:3, 5 ) = node%Moments(1:3, 5 ) + SegGammaVec*1/3.0_ReKi*(3*VortC(1)**2 -3*VortC(1)*(P1(1)+P2(1))+P1(1)**2+P1(1)*P2(1)+P2(1)**2) !j=1,k=1 + node%Moments(1:3, 7 ) = node%Moments(1:3, 7 ) + SegGammaVec*1/3.0_ReKi*(3*VortC(2)**2 -3*VortC(2)*(P1(2)+P2(2))+P1(2)**2+P1(2)*P2(2)+P2(2)**2) !j=2,k=2 + node%Moments(1:3, 10 ) = node%Moments(1:3, 10 ) + SegGammaVec*1/3.0_ReKi*(3*VortC(3)**2 -3*VortC(3)*(P1(3)+P2(3))+P1(3)**2+P1(3)*P2(3)+P2(3)**2) !j=3,k=3 + !node%Moments(1:3,3+j+k+j/3) = node%Moments(1:3,3+j+k+j/3) + SegGammaVec*1/6.0_ReKi*( 6*VortC(j)*VortC(k) -3*VortC(j)*(P1(k)+P2(k)) +P1(j)*(-3*VortC(k)+2*P1(k)+P2(k)) +P2(j)*(-3*VortC(k)+P1(k)+2*P2(k))) + node%Moments(1:3, 6 ) = node%Moments(1:3, 6 ) + SegGammaVec*1/6.0_ReKi*( 6*VortC(2)*VortC(1) -3*VortC(2)*(P1(1)+P2(1)) +P1(2)*(-3*VortC(1)+2*P1(1)+P2(1)) +P2(2)*(-3*VortC(1)+P1(1)+2*P2(1))) !j=2, k=1 + node%Moments(1:3, 8 ) = node%Moments(1:3, 8 ) + SegGammaVec*1/6.0_ReKi*( 6*VortC(3)*VortC(1) -3*VortC(3)*(P1(1)+P2(1)) +P1(3)*(-3*VortC(1)+2*P1(1)+P2(1)) +P2(3)*(-3*VortC(1)+P1(1)+2*P2(1))) !j=3, k=1 + node%Moments(1:3, 9 ) = node%Moments(1:3, 9 ) + SegGammaVec*1/6.0_ReKi*( 6*VortC(3)*VortC(2) -3*VortC(3)*(P1(2)+P2(2)) +P1(3)*(-3*VortC(2)+2*P1(2)+P2(2)) +P2(3)*(-3*VortC(2)+P1(2)+2*P2(2))) !j=3, k=2 end do ! --- Distributing particles to the 8 octants (based on the geometric center!) @@ -1005,12 +1080,12 @@ subroutine grow_tree_segment_substep(node, Seg) do i = 1,node%nPart P1 = Seg%SP(1:3,Seg%SConnct(1,node%iPart(i))) P2 = Seg%SP(1:3,Seg%SConnct(2,node%iPart(i))) - SegCenter = 0.5_ReKi*(P1+P2) + SegCenter = 0.5_ReKi*(P1+P2) ! We use the segment center. We could consider looking at point 1 and 2 separately ! index corresponding to which octant the particle falls into iPartOctant = int(1,IK1) - if (SegCenter(1) > nodeGeomCenter(1)) iPartOctant = iPartOctant + int(1,IK1) - if (SegCenter(2) > nodeGeomCenter(2)) iPartOctant = iPartOctant + int(2,IK1) - if (SegCenter(3) > nodeGeomCenter(3)) iPartOctant = iPartOctant + int(4,IK1) + if (SegCenter(1) > GeomC(1)) iPartOctant = iPartOctant + int(1,IK1) + if (SegCenter(2) > GeomC(2)) iPartOctant = iPartOctant + int(2,IK1) + if (SegCenter(3) > GeomC(3)) iPartOctant = iPartOctant + int(4,IK1) npart_per_octant(iPartOctant) = npart_per_octant(iPartOctant) + 1 ! Counter of particles per octant PartOctant(i)=iPartOctant ! Store in which octant particle i is end do @@ -1052,14 +1127,16 @@ subroutine grow_tree_segment_substep(node, Seg) octant2branches(iOctant) = nBranches endif enddo - if (associated(node%branches)) then - print*,'Tree build: error, branches associated' - STOP + if (DEV_VERSION_VT) then + if (associated(node%branches)) then + print*,'Tree build: error, branches associated' + STOP + endif + if (associated(node%leaves)) then + print*,'Tree build: error, leaves associated' + STOP + end if endif - if (associated(node%leaves)) then - print*,'Tree build: error, leaves associated' - STOP - end if if(nBranches>0) allocate (node%branches(1:nBranches)) if(nLeaves>0) allocate (node%leaves(1:nLeaves)) @@ -1072,7 +1149,7 @@ subroutine grow_tree_segment_substep(node, Seg) allocate(node%branches(iBranch)%iPart(1:npart_per_octant(iOctant))) node%branches(iBranch)%nPart=npart_per_octant(iOctant) ! NOTE: this is geometric center not barycenter - locCenter = nodeGeomCenter + 0.5*halfSize*(/ (-1)**(iOctant), (-1)**floor(0.5*real(iOctant-1)+1), (-1)**floor(0.25*real(iOctant-1)+1) /) + locCenter = GeomC + 0.5*halfSize*(/ (-1)**(iOctant), (-1)**floor(0.5*real(iOctant-1)+1), (-1)**floor(0.25*real(iOctant-1)+1) /) ! Init of branches node%branches(iBranch)%radius = halfSize ! node%branches(iBranch)%center = locCenter ! NOTE: this is the geometric center @@ -1084,20 +1161,11 @@ subroutine grow_tree_segment_substep(node, Seg) end do ! Store indices of the particles the sub-branch contains - i1=0; i2=0; i3=0; i4=0; i5=0; i6=0; i7=0; i8=0; + nPerBranchAcc(:) = 0 do i = 1,node%nPart iBranch = octant2branches(PartOctant(i)) if(iBranch>0) then - select case(iBranch) - case(1);i1=i1+1; node%branches(1)%iPart(i1) = node%iPart(i) - case(2);i2=i2+1; node%branches(2)%iPart(i2) = node%iPart(i) - case(3);i3=i3+1; node%branches(3)%iPart(i3) = node%iPart(i) - case(4);i4=i4+1; node%branches(4)%iPart(i4) = node%iPart(i) - case(5);i5=i5+1; node%branches(5)%iPart(i5) = node%iPart(i) - case(6);i6=i6+1; node%branches(6)%iPart(i6) = node%iPart(i) - case(7);i7=i7+1; node%branches(7)%iPart(i7) = node%iPart(i) - case(8);i8=i8+1; node%branches(8)%iPart(i8) = node%iPart(i) - end select + nPerBranchAcc(iBranch)=nPerBranchAcc(iBranch)+1; node%branches(iBranch)%iPart(nPerBranchAcc(iBranch)) = node%iPart(i) else iLeaf = octant2leaves(PartOctant(i)) if(iLeaf>0) then @@ -1116,7 +1184,7 @@ end subroutine grow_tree_segment_substep !! Note, needed preliminary calc are done by grow_tree before! subroutine grow_tree_segment_parallel(Root, Seg) type(T_Node), intent(inout) :: Root - type(T_Seg), intent(in) :: Seg + type(T_VSgmt), intent(in) :: Seg integer :: i, nBranches integer :: i1 integer :: i2 @@ -1191,17 +1259,34 @@ subroutine cut_substep(node) if (associated(node%leaves)) then deallocate(node%leaves) end if - if (associated(node%iPart)) then - print*,'The tree particles were not properly cleaned' - STOP - deallocate(node%iPart) - end if + if (DEV_VERSION_VT) then + if (associated(node%iPart)) then + print*,'The tree particles were not properly cleaned' + STOP + deallocate(node%iPart) + end if + endif end subroutine cut_substep !> Cut a tree and all its sub-branches, unrolled to use parallelization for the first 3 levels - subroutine cut_tree_parallel(Tree) + subroutine cut_tree_parallel(Tree, deallocPart, deallocSgmt) type(T_Tree), intent(inout) :: Tree - integer :: i,i1,i2,nBranches + logical, optional, intent(in) :: deallocPart + logical, optional, intent(in) :: deallocSgmt + integer :: i,i1,i2,nBranches,istat + ! --- Deallocating data we are pointing to, only if user requests it + if (present(deallocPart)) then + if (deallocPart) then + deallocate(Tree%Part%P , stat=istat) + deallocate(Tree%Part%AlphA , stat=istat) + deallocate(Tree%Part%RegParam , stat=istat) + endif + endif + if (present(deallocSgmt)) then + if (deallocSgmt) then + deallocate(Tree%Seg%SP, Tree%Seg%SConnct, Tree%Seg%SGamma, Tree%Seg%RegParam, stat=istat) + endif + endif ! --- Unlinking particles nullify(Tree%Part%P) nullify(Tree%Part%Alpha) @@ -1250,9 +1335,11 @@ subroutine cut_tree_parallel(Tree) deallocate(Tree%root%branches) nullify(Tree%root%branches) endif - if (associated(Tree%root%branches)) then - print*,'Tree cut: branches are still allocated' - STOP + if (DEV_VERSION_VT) then + if (associated(Tree%root%branches)) then + print*,'Tree cut: branches are still allocated' + STOP + endif endif Tree%iStep=-1 Tree%root%nPart=-1 @@ -1274,12 +1361,12 @@ recursive subroutine print_tree_rec(node, preffix) integer :: i ! Test if there are enough particles on the node to build new branchess ! The case of only one particle should be handled upstream by allocating one leaf to the parent node - print'(A)' ,trim(preffix)//':nPart = '//Num2LStr(node%nPart) - print'(A,3F12.3)',trim(preffix)//':center =',node%center - print'(A,1F12.3)',trim(preffix)//':radius =',node%radius + print'(A, I0)' ,trim(preffix)//':nPart = ', node%nPart + print'(A,3F12.3)',trim(preffix)//':center =', node%center + print'(A,1F12.3)',trim(preffix)//':radius =', node%radius if(associated(node%leaves)) then do i = 1,size(node%leaves) - print'(A)',trim(preffix)//':leaf'//trim(Num2LStr(i))//'='//trim(Num2LStr(node%leaves(i))) + print'(A, I0, A, I0)',trim(preffix)//':leaf', i,'=', node%leaves(i) end do endif if(associated(node%branches)) then @@ -1341,9 +1428,11 @@ subroutine cut_tree_segment_parallel(Tree_Seg) deallocate(Tree_Seg%root%branches) nullify(Tree_Seg%root%branches) endif - if (associated(Tree_Seg%root%branches)) then - print*,'Tree cut: branches are still allocated' - STOP + if (DEV_VERSION_VT) then + if (associated(Tree_Seg%root%branches)) then + print*,'Tree cut: branches are still allocated' + STOP + endif endif Tree_Seg%iStep=-1 Tree_Seg%root%nPart=-1 @@ -1353,12 +1442,10 @@ end subroutine cut_tree_segment_parallel ! -------------------------------------------------------------------------------- ! --- Velocity computation ! -------------------------------------------------------------------------------- - subroutine ui_tree(Tree, CPs, ioff, icp_beg, icp_end, BranchFactor, DistanceDirect, Uind, ErrStat, ErrMsg) - use FVW_BiotSavart, only: fourpi_inv, ui_part_nograd_11 + subroutine ui_tree_part(Tree, icp_end, CPs, BranchFactor, DistanceDirect, Uind, ErrStat, ErrMsg) + use FVW_BiotSavart, only: ui_part_nograd_11 type(T_Tree), target, intent(inout) :: Tree !< - integer, intent(in ) :: ioff !< - integer, intent(in ) :: icp_beg !< - integer, intent(in ) :: icp_end !< + integer, intent(in ) :: icp_end !< Number of CPs to use Tree%Part if(.not. associated(Part%P)) then ErrMsg='Ui Part Tree called but tree particles not associated'; ErrStat=ErrID_Fatal; return endif !$OMP PARALLEL DEFAULT(SHARED) - !$OMP DO PRIVATE(icp,CP,Uind_tmp,nDirect,nQuad) schedule(runtime) - do icp=icp_beg,icp_end + !$OMP DO PRIVATE(icp,CP,Uind_tmp) schedule(runtime) + do icp=1,icp_end CP = CPs(1:3,icp) Uind_tmp(1:3) = 0.0_ReKi - nDirect =0 - nQuad =0 - call ui_tree_11(Tree%root, CP, Uind_tmp, nDirect, nQuad) !< SIDE EFFECTS - !print*,'Number of direct calls, and quad calls',nDirect, nQuad - Uind(1:3,ioff+icp-icp_beg+1) = Uind(1:3,ioff+icp-icp_beg+1) + Uind_tmp(1:3) + call ui_tree_part_11(Tree%root, CP, Uind_tmp) !< SIDE EFFECTS + Uind(1:3, icp) = Uind(1:3, icp) + Uind_tmp(1:3) enddo !$OMP END DO !$OMP END PARALLEL contains !> Velocity at one control point from the entire tree - recursive subroutine ui_tree_11(node, CP, Uind, nDirect, nQuad) - real(ReKi),dimension(3),intent(inout) :: CP, Uind !< Velocity at control point, with side effect - integer, intent(inout) :: nDirect,nQuad + recursive subroutine ui_tree_part_11(node, CP, Uind) + real(ReKi), dimension(3), intent(in ) :: CP + real(ReKi), dimension(3), intent(inout) :: Uind !< Velocity at control point, with side effect type(T_Node), intent(inout) :: node - real(ReKi) :: distDirect, coeff - real(ReKi),dimension(3) :: DeltaP, phi, Uloc - real(ReKi) :: x,y,z,mx,my,mz,r - integer :: i,j,ieqj + real(ReKi) :: distDirect + real(ReKi),dimension(3) :: DeltaP, Uloc + real(ReKi) :: r + real(ReKi) :: coeff, coeff3, coeff5, coeff7, coeff7ij + real(ReKi) :: x, y, z + real(ReKi),dimension(3) :: phi + real(ReKi) :: ieqj + integer :: i,j integer :: iPart if (node%nPart<=0) then ! We skip the dead leaf @@ -1406,7 +1496,6 @@ recursive subroutine ui_tree_11(node, CP, Uind, nDirect, nQuad) iPart=node%leaves(i) DeltaP = CP(1:3) - Part%P(1:3,iPart) call ui_part_nograd_11(DeltaP, Part%Alpha(1:3,iPart), Part%RegFunction, Part%RegParam(iPart), Uloc) - nDirect=nDirect+1 Uind(1:3) = Uind(1:3) + Uloc enddo endif @@ -1422,91 +1511,144 @@ recursive subroutine ui_tree_11(node, CP, Uind, nDirect, nQuad) iPart=node%leaves(i) DeltaP = CP(1:3) - Part%P(1:3,iPart) call ui_part_nograd_11(DeltaP, Part%Alpha(1:3,iPart), Part%RegFunction, Part%RegParam(iPart), Uloc) - nDirect=nDirect+1 Uind(1:3) = Uind(1:3) + Uloc enddo endif if(associated(node%branches)) then ! TODO: consider implementing a recursive method for that: direct call on all children do i =1,size(node%branches) - call ui_tree_11(node%branches(i), CP, Uind, nDirect, nQuad) + call ui_tree_part_11(node%branches(i), CP, Uind) end do endif else - ! We are far enough, use branch node quadrupole + ! We are far enough, use branch node quadrupole + !call ui_expansion_order2(r, DeltaP, node%node%Moments, Uloc) + !! NOTE all of this is common between particle and segment + coeff3 = fourpi_inv/r**3 x=DeltaP(1) y=DeltaP(2) z=DeltaP(3) - phi = node%Moments(1:3,M0)/r**3*fourpi_inv - ! Speed, order 0 + phi = node%Moments(1:3,M0)*coeff3 Uloc(1) = phi(2)*z - phi(3)*y Uloc(2) = phi(3)*x - phi(1)*z Uloc(3) = phi(1)*y - phi(2)*x - Uind = Uind+Uloc + Uind = Uind + Uloc ! Speed, order 1 Uloc=0.0_ReKi - coeff = 3.0_ReKi*x*fourpi_inv/r**5 + coeff5 = 3.0_ReKi*fourpi_inv/r**5 + coeff = coeff5*x Uloc(1) = Uloc(1)- coeff*(node%Moments(3,M1_1)*y-node%Moments(2,M1_1)*z) Uloc(2) = Uloc(2)- coeff*(node%Moments(1,M1_1)*z-node%Moments(3,M1_1)*x) Uloc(3) = Uloc(3)- coeff*(node%Moments(2,M1_1)*x-node%Moments(1,M1_1)*y) - coeff = 3.0_ReKi*y*fourpi_inv/r**5 + coeff = coeff5*y Uloc(1) = Uloc(1) - coeff*(node%Moments(3,M1_2)*y-node%Moments(2,M1_2)*z) Uloc(2) = Uloc(2) - coeff*(node%Moments(1,M1_2)*z-node%Moments(3,M1_2)*x) Uloc(3) = Uloc(3) - coeff*(node%Moments(2,M1_2)*x-node%Moments(1,M1_2)*y) - coeff = 3.0_ReKi*z*fourpi_inv/r**5 + coeff = coeff5*z Uloc(1) = Uloc(1) - coeff*(node%Moments(3,M1_3)*y-node%Moments(2,M1_3)*z) Uloc(2) = Uloc(2) - coeff*(node%Moments(1,M1_3)*z-node%Moments(3,M1_3)*x) Uloc(3) = Uloc(3) - coeff*(node%Moments(2,M1_3)*x-node%Moments(1,M1_3)*y) - coeff = fourpi_inv/r**3 - Uloc(1) = Uloc(1) + coeff*node%Moments(3,M1_2) - coeff*node%Moments(2,M1_3) - Uloc(2) = Uloc(2) + coeff*node%Moments(1,M1_3) - coeff*node%Moments(3,M1_1) - Uloc(3) = Uloc(3) + coeff*node%Moments(2,M1_1) - coeff*node%Moments(1,M1_2) + Uloc(1) = Uloc(1) + coeff3*node%Moments(3,M1_2) - coeff3*node%Moments(2,M1_3) + Uloc(2) = Uloc(2) + coeff3*node%Moments(1,M1_3) - coeff3*node%Moments(3,M1_1) + Uloc(3) = Uloc(3) + coeff3*node%Moments(2,M1_1) - coeff3*node%Moments(1,M1_2) Uind=Uind+Uloc + + ! Speed, order 2 Uloc =0.0_ReKi + coeff = coeff5*0.5_ReKi ! 3/2 * 1/(4 pi r**5) + coeff7= -7.5_ReKi*fourpi_inv/r**7 + ! TODO: BAR_OLAF test fails (very slightly) with unrolled version... + !! NOTE: KEEP ME do i =1,3 - coeff = 1.5_ReKi*fourpi_inv/r**5 - Uloc(1) = Uloc(1) + coeff * (y*node%Moments(3,5+2*(i/2)+3*(i/3)) - z*node%Moments(2,5+2*(i/2)+3*(i/3))) - Uloc(2) = Uloc(2) + coeff * (z*node%Moments(1,5+2*(i/2)+3*(i/3)) - x*node%Moments(3,5+2*(i/2)+3*(i/3))) - Uloc(3) = Uloc(3) + coeff * (x*node%Moments(2,5+2*(i/2)+3*(i/3)) - y*node%Moments(1,5+2*(i/2)+3*(i/3))) + Uloc(1) = Uloc(1) + coeff* (y*node%Moments(3,5+2*(i/2)+3*(i/3)) - z*node%Moments(2,5+2*(i/2)+3*(i/3))) + Uloc(2) = Uloc(2) + coeff* (z*node%Moments(1,5+2*(i/2)+3*(i/3)) - x*node%Moments(3,5+2*(i/2)+3*(i/3))) + Uloc(3) = Uloc(3) + coeff* (x*node%Moments(2,5+2*(i/2)+3*(i/3)) - y*node%Moments(1,5+2*(i/2)+3*(i/3))) do j=1,i if (i==j) then - ieqj = 1 + ieqj = 1.0_ReKi else - ieqj = 2 + ieqj = 2.0_ReKi end if - coeff = -7.5_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 - Uloc(1) = Uloc(1) + ieqj * coeff * ( y*node%Moments(3,3+i+j+i/3) - z*node%Moments(2,3+i+j+i/3)) - Uloc(2) = Uloc(2) + ieqj * coeff * ( z*node%Moments(1,3+i+j+i/3) - x*node%Moments(3,3+i+j+i/3)) - Uloc(3) = Uloc(3) + ieqj * coeff * ( x*node%Moments(2,3+i+j+i/3) - y*node%Moments(1,3+i+j+i/3)) + coeff7ij = DeltaP(i)*DeltaP(j)*coeff7 + Uloc(1) = Uloc(1) + ieqj * coeff7ij * ( y*node%Moments(3,3+i+j+i/3) - z*node%Moments(2,3+i+j+i/3)) + Uloc(2) = Uloc(2) + ieqj * coeff7ij * ( z*node%Moments(1,3+i+j+i/3) - x*node%Moments(3,3+i+j+i/3)) + Uloc(3) = Uloc(3) + ieqj * coeff7ij * ( x*node%Moments(2,3+i+j+i/3) - y*node%Moments(1,3+i+j+i/3)) end do end do - coeff = 3.0_ReKi*fourpi_inv/r**5 - Uloc(1) = Uloc(1) + coeff * ( y*node%Moments(3,M2_22) - z*node%Moments(2,M2_33) ) - Uloc(2) = Uloc(2) + coeff * ( z*node%Moments(1,M2_33) - x*node%Moments(3,M2_11) ) - Uloc(3) = Uloc(3) + coeff * ( x*node%Moments(2,M2_11) - y*node%Moments(1,M2_22) ) - - coeff = 3.0_ReKi*fourpi_inv/r**5 - Uloc(1) = Uloc(1) + coeff * (z*node%Moments(3,M2_32) + x*node%Moments(3,M2_21) - x*node%Moments(2,M2_31) - y*node%Moments(2,M2_32)) - Uloc(2) = Uloc(2) + coeff * (x*node%Moments(1,M2_31) + y*node%Moments(1,M2_32) - y*node%Moments(3,M2_21) - z*node%Moments(3,M2_31)) - Uloc(3) = Uloc(3) + coeff * (y*node%Moments(2,M2_21) + z*node%Moments(2,M2_31) - z*node%Moments(1,M2_32) - x*node%Moments(1,M2_21)) - Uind(1:3) = Uind(1:3) + Uloc - nQuad=nQuad+1 + !! r5 terms, unrolled version + !! Uloc(1) = Uloc(1) + coeff * (y*node%Moments(3,5+2*(i/2)+3*(i/3)) - z*node%Moments(2,5+2*(i/2)+3*(i/3))) + !! Uloc(2) = Uloc(2) + coeff * (z*node%Moments(1,5+2*(i/2)+3*(i/3)) - x*node%Moments(3,5+2*(i/2)+3*(i/3))) + !! Uloc(3) = Uloc(3) + coeff * (x*node%Moments(2,5+2*(i/2)+3*(i/3)) - y*node%Moments(1,5+2*(i/2)+3*(i/3))) + ! i=1 + !Uloc(1) = Uloc(1) + coeff * (y*node%Moments(3,5) - z*node%Moments(2,5)) + !Uloc(2) = Uloc(2) + coeff * (z*node%Moments(1,5) - x*node%Moments(3,5)) + !Uloc(3) = Uloc(3) + coeff * (x*node%Moments(2,5) - y*node%Moments(1,5)) + !! i=2 + !Uloc(1) = Uloc(1) + coeff * (y*node%Moments(3,7) - z*node%Moments(2,7)) + !Uloc(2) = Uloc(2) + coeff * (z*node%Moments(1,7) - x*node%Moments(3,7)) + !Uloc(3) = Uloc(3) + coeff * (x*node%Moments(2,7) - y*node%Moments(1,7)) + !! i=3 + !Uloc(1) = Uloc(1) + coeff * (y*node%Moments(3,8) - z*node%Moments(2,8)) + !Uloc(2) = Uloc(2) + coeff * (z*node%Moments(1,8) - x*node%Moments(3,8)) + !Uloc(3) = Uloc(3) + coeff * (x*node%Moments(2,8) - y*node%Moments(1,8)) + !! r7 terms, unrolled version + !! coeff7ij = DeltaP(i)*DeltaP(j)*coeff7 * (1 or 2 depdening if i=j) + !! Uloc(1) = Uloc(1) + ieqj * coeff7ij * ( y*node%Moments(3,3+i+j+i/3) - z*node%Moments(2,3+i+j+i/3)) + !! Uloc(2) = Uloc(2) + ieqj * coeff7ij * ( z*node%Moments(1,3+i+j+i/3) - x*node%Moments(3,3+i+j+i/3)) + !! Uloc(3) = Uloc(3) + ieqj * coeff7ij * ( x*node%Moments(2,3+i+j+i/3) - y*node%Moments(1,3+i+j+i/3)) + !! i=1, j=1 + !coeff7ij = DeltaP(1)*DeltaP(1)*coeff7 !=-7.5_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + !Uloc(1) = Uloc(1) + coeff7ij * (y*node%Moments(3,5) - z*node%Moments(2,5)) + !Uloc(2) = Uloc(2) + coeff7ij * (z*node%Moments(1,5) - x*node%Moments(3,5)) + !Uloc(3) = Uloc(3) + coeff7ij * (x*node%Moments(2,5) - y*node%Moments(1,5)) + !! i=2, j=1 + !coeff7ij = 2.0_ReKi* DeltaP(2)*DeltaP(1)*coeff7 !=-15_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + !Uloc(1) = Uloc(1) + coeff7ij * (y*node%Moments(3,6) - z*node%Moments(2,6)) + !Uloc(2) = Uloc(2) + coeff7ij * (z*node%Moments(1,6) - x*node%Moments(3,6)) + !Uloc(3) = Uloc(3) + coeff7ij * (x*node%Moments(2,6) - y*node%Moments(1,6)) + !! i=2, j=2 + !coeff7ij = DeltaP(2)*DeltaP(2)*coeff7 !=-7.5_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + !Uloc(1) = Uloc(1) + coeff7ij * (y*node%Moments(3,7) - z*node%Moments(2,7)) + !Uloc(2) = Uloc(2) + coeff7ij * (z*node%Moments(1,7) - x*node%Moments(3,7)) + !Uloc(3) = Uloc(3) + coeff7ij * (x*node%Moments(2,7) - y*node%Moments(1,7)) + !! i=3, j=1 + !coeff7ij = 2.0_ReKi*DeltaP(3)*DeltaP(1)*coeff7 !=-15_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + !Uloc(1) = Uloc(1) + coeff7ij * (y*node%Moments(3,8) - z*node%Moments(2,8)) + !Uloc(2) = Uloc(2) + coeff7ij * (z*node%Moments(1,8) - x*node%Moments(3,8)) + !Uloc(3) = Uloc(3) + coeff7ij * (x*node%Moments(2,8) - y*node%Moments(1,8)) + !! i=3, j=2 + !coeff7ij = 2.0_ReKi*DeltaP(3)*DeltaP(2)*coeff7 !=-15_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + !Uloc(1) = Uloc(1) + coeff7ij * (y*node%Moments(3,9) - z*node%Moments(2,9)) + !Uloc(2) = Uloc(2) + coeff7ij * (z*node%Moments(1,9) - x*node%Moments(3,9)) + !Uloc(3) = Uloc(3) + coeff7ij * (x*node%Moments(2,9) - y*node%Moments(1,9)) + !! i=3, j=3 + !coeff7ij = DeltaP(3)*DeltaP(3)*coeff7 !=-7.5_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + !Uloc(1) = Uloc(1) + coeff7ij * (y*node%Moments(3,10) - z*node%Moments(2,10)) + !Uloc(2) = Uloc(2) + coeff7ij * (z*node%Moments(1,10) - x*node%Moments(3,10)) + !Uloc(3) = Uloc(3) + coeff7ij * (x*node%Moments(2,10) - y*node%Moments(1,10)) + + ! r5 terms 2 + Uloc(1) = Uloc(1) + coeff5 * (y*node%Moments(3,M2_22) - z*node%Moments(2,M2_33)) + Uloc(2) = Uloc(2) + coeff5 * (z*node%Moments(1,M2_33) - x*node%Moments(3,M2_11)) + Uloc(3) = Uloc(3) + coeff5 * (x*node%Moments(2,M2_11) - y*node%Moments(1,M2_22)) + Uloc(1) = Uloc(1) + coeff5 * (z*node%Moments(3,M2_32) + x*node%Moments(3,M2_21) - x*node%Moments(2,M2_31) - y*node%Moments(2,M2_32)) + Uloc(2) = Uloc(2) + coeff5 * (x*node%Moments(1,M2_31) + y*node%Moments(1,M2_32) - y*node%Moments(3,M2_21) - z*node%Moments(3,M2_31)) + Uloc(3) = Uloc(3) + coeff5 * (y*node%Moments(2,M2_21) + z*node%Moments(2,M2_31) - z*node%Moments(1,M2_32) - x*node%Moments(1,M2_21)) + Uind = Uind + Uloc end if ! Far enough end if ! had more than 1 particles - end subroutine ui_tree_11 - end subroutine ui_tree + end subroutine ui_tree_part_11 + end subroutine ui_tree_part - subroutine ui_tree_segment(Tree, CPs, ioff, icp_beg, icp_end, BranchFactor, DistanceDirect, Uind, ErrStat, ErrMsg) - use FVW_BiotSavart, only: fourpi_inv, ui_seg_11 + subroutine ui_tree_segment(Tree, CPs, icp_end, BranchFactor, DistanceDirect, Uind, ErrStat, ErrMsg) + use FVW_BiotSavart, only: ui_seg_11 type(T_Tree), target, intent(inout) :: Tree !< - integer, intent(in ) :: ioff !< - integer, intent(in ) :: icp_beg !< integer, intent(in ) :: icp_end !< real(ReKi), intent(in ) :: BranchFactor !< real(ReKi), intent(in ) :: DistanceDirect !< Distance under which direct evaluation should be done no matter what the tree cell size is @@ -1516,35 +1658,36 @@ subroutine ui_tree_segment(Tree, CPs, ioff, icp_beg, icp_end, BranchFactor, Dist character(*), intent( out) :: ErrMsg !< Error message if ErrStat /= ErrID_None real(ReKi), dimension(3) :: Uind_tmp !< real(ReKi), dimension(3) :: CP !< Current CP - integer :: icp, nDirect, nQuad - type(T_Seg), pointer :: Seg ! Alias + integer :: icp + type(T_VSgmt), pointer :: Seg ! Alias Seg => Tree%Seg if(.not. associated(Seg%SP)) then - ErrMsg='Ui Part Tree called but tree segments not associated'; ErrStat=ErrID_Fatal; return + ErrMsg='Ui Sgmt Tree called but tree segments not associated'; ErrStat=ErrID_Fatal; return endif !$OMP PARALLEL DEFAULT(SHARED) - !$OMP DO PRIVATE(icp,CP,Uind_tmp,nDirect,nQuad) schedule(runtime) - do icp=icp_beg,icp_end + !$OMP DO PRIVATE(icp, CP, Uind_tmp) schedule(runtime) + do icp=1,icp_end CP = CPs(1:3,icp) Uind_tmp(1:3) = 0.0_ReKi - nDirect =0 - nQuad =0 - call ui_tree_segment_11(Tree%root, CP, Uind_tmp, nDirect, nQuad) !< SIDE EFFECTS - !print*,' Segment Number of direct calls, and quad calls',nDirect, nQuad - Uind(1:3,ioff+icp-icp_beg+1) = Uind(1:3,ioff+icp-icp_beg+1) + Uind_tmp(1:3) + call ui_tree_segment_11(Tree%root, CP, Uind_tmp) !< SIDE EFFECTS + Uind(1:3, icp) = Uind(1:3, icp) + Uind_tmp(1:3) enddo !$OMP END DO !$OMP END PARALLEL contains !> Velocity at one control point from the entire tree - recursive subroutine ui_tree_segment_11(node, CP, Uind, nDirect, nQuad) - real(ReKi),dimension(3),intent(inout) :: CP, Uind !< Velocity at control point, with side effect - integer, intent(inout) :: nDirect,nQuad + recursive subroutine ui_tree_segment_11(node, CP, Uind) + real(ReKi), dimension(3), intent(in ) :: CP + real(ReKi), dimension(3), intent(inout) :: Uind !< Velocity at control point, with side effect type(T_Node), intent(inout) :: node - real(ReKi) :: distDirect, coeff - real(ReKi),dimension(3) :: DeltaP, DeltaPa, DeltaPb, phi, Uloc - real(ReKi) :: x,y,z,mx,my,mz,r - integer :: i,j,ieqj + real(ReKi) :: distDirect + real(ReKi),dimension(3) :: DeltaP, DeltaPa, DeltaPb, Uloc + real(ReKi),dimension(3) :: Uquad + real(ReKi) :: r + real(ReKi) :: coeff, coeff3, coeff5, coeff7, coeff7ij + real(ReKi) :: x, y, z + real(ReKi),dimension(3) :: phi + integer :: i integer :: iPart if (node%nPart<=0) then ! We skip the dead leaf @@ -1556,7 +1699,6 @@ recursive subroutine ui_tree_segment_11(node, CP, Uind, nDirect, nQuad) DeltaPa = CP(1:3) - Seg%SP(1:3,Seg%SConnct(1,iPart)) DeltaPb = CP(1:3) - Seg%SP(1:3,Seg%SConnct(2,iPart)) call ui_seg_11(DeltaPa, DeltaPb, Seg%SGamma(iPart), Seg%RegFunction, Seg%RegParam(iPart), Uloc) - nDirect=nDirect+1 Uind(1:3) = Uind(1:3) + Uloc enddo endif @@ -1573,86 +1715,277 @@ recursive subroutine ui_tree_segment_11(node, CP, Uind, nDirect, nQuad) DeltaPa = CP(1:3) - Seg%SP(1:3,Seg%SConnct(1,iPart)) DeltaPb = CP(1:3) - Seg%SP(1:3,Seg%SConnct(2,iPart)) call ui_seg_11(DeltaPa, DeltaPb, Seg%SGamma(iPart), Seg%RegFunction, Seg%RegParam(iPart), Uloc) - nDirect=nDirect+1 Uind(1:3) = Uind(1:3) + Uloc enddo endif if(associated(node%branches)) then ! TODO: consider implementing a recursive method for that: direct call on all children do i =1,size(node%branches) - call ui_tree_segment_11(node%branches(i), CP, Uind, nDirect, nQuad) + call ui_tree_segment_11(node%branches(i), CP, Uind) end do endif else ! We are far enough, use branch node quadrupole + !call ui_expansion_order2(r, DeltaP, node%node%Moments, Uloc) + !! NOTE all of this is common between particle and segment + coeff3 = fourpi_inv/r**3 x=DeltaP(1) y=DeltaP(2) z=DeltaP(3) - phi = node%Moments(1:3,M0)/r**3*fourpi_inv - ! Speed, order 0 + phi = node%Moments(1:3,M0)*coeff3 Uloc(1) = phi(2)*z - phi(3)*y Uloc(2) = phi(3)*x - phi(1)*z Uloc(3) = phi(1)*y - phi(2)*x - Uind = Uind+Uloc + Uquad = Uloc ! Speed, order 1 Uloc=0.0_ReKi - coeff = 3.0_ReKi*x*fourpi_inv/r**5 + coeff5 = 3.0_ReKi*fourpi_inv/r**5 + coeff = coeff5*x Uloc(1) = Uloc(1)- coeff*(node%Moments(3,M1_1)*y-node%Moments(2,M1_1)*z) Uloc(2) = Uloc(2)- coeff*(node%Moments(1,M1_1)*z-node%Moments(3,M1_1)*x) Uloc(3) = Uloc(3)- coeff*(node%Moments(2,M1_1)*x-node%Moments(1,M1_1)*y) - coeff = 3.0_ReKi*y*fourpi_inv/r**5 + coeff = coeff5*y Uloc(1) = Uloc(1) - coeff*(node%Moments(3,M1_2)*y-node%Moments(2,M1_2)*z) Uloc(2) = Uloc(2) - coeff*(node%Moments(1,M1_2)*z-node%Moments(3,M1_2)*x) Uloc(3) = Uloc(3) - coeff*(node%Moments(2,M1_2)*x-node%Moments(1,M1_2)*y) - coeff = 3.0_ReKi*z*fourpi_inv/r**5 + coeff = coeff5*z Uloc(1) = Uloc(1) - coeff*(node%Moments(3,M1_3)*y-node%Moments(2,M1_3)*z) Uloc(2) = Uloc(2) - coeff*(node%Moments(1,M1_3)*z-node%Moments(3,M1_3)*x) Uloc(3) = Uloc(3) - coeff*(node%Moments(2,M1_3)*x-node%Moments(1,M1_3)*y) - coeff = fourpi_inv/r**3 - Uloc(1) = Uloc(1) + coeff*node%Moments(3,M1_2) - coeff*node%Moments(2,M1_3) - Uloc(2) = Uloc(2) + coeff*node%Moments(1,M1_3) - coeff*node%Moments(3,M1_1) - Uloc(3) = Uloc(3) + coeff*node%Moments(2,M1_1) - coeff*node%Moments(1,M1_2) - Uind=Uind+Uloc + Uloc(1) = Uloc(1) + coeff3*node%Moments(3,M1_2) - coeff3*node%Moments(2,M1_3) + Uloc(2) = Uloc(2) + coeff3*node%Moments(1,M1_3) - coeff3*node%Moments(3,M1_1) + Uloc(3) = Uloc(3) + coeff3*node%Moments(2,M1_1) - coeff3*node%Moments(1,M1_2) + Uquad = Uquad + Uloc + + ! Speed, order 2 Uloc =0.0_ReKi - do i =1,3 - coeff = 1.5_ReKi*fourpi_inv/r**5 - Uloc(1) = Uloc(1) + coeff * (y*node%Moments(3,5+2*(i/2)+3*(i/3)) - z*node%Moments(2,5+2*(i/2)+3*(i/3))) - Uloc(2) = Uloc(2) + coeff * (z*node%Moments(1,5+2*(i/2)+3*(i/3)) - x*node%Moments(3,5+2*(i/2)+3*(i/3))) - Uloc(3) = Uloc(3) + coeff * (x*node%Moments(2,5+2*(i/2)+3*(i/3)) - y*node%Moments(1,5+2*(i/2)+3*(i/3))) - do j=1,i - if (i==j) then - ieqj = 1 - else - ieqj = 2 - end if - coeff = -7.5_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 - Uloc(1) = Uloc(1) + ieqj * coeff * ( y*node%Moments(3,3+i+j+i/3) - z*node%Moments(2,3+i+j+i/3)) - Uloc(2) = Uloc(2) + ieqj * coeff * ( z*node%Moments(1,3+i+j+i/3) - x*node%Moments(3,3+i+j+i/3)) - Uloc(3) = Uloc(3) + ieqj * coeff * ( x*node%Moments(2,3+i+j+i/3) - y*node%Moments(1,3+i+j+i/3)) - end do - end do - coeff = 3.0_ReKi*fourpi_inv/r**5 - Uloc(1) = Uloc(1) + coeff * ( y*node%Moments(3,M2_22) - z*node%Moments(2,M2_33) ) - Uloc(2) = Uloc(2) + coeff * ( z*node%Moments(1,M2_33) - x*node%Moments(3,M2_11) ) - Uloc(3) = Uloc(3) + coeff * ( x*node%Moments(2,M2_11) - y*node%Moments(1,M2_22) ) - - coeff = 3.0_ReKi*fourpi_inv/r**5 - Uloc(1) = Uloc(1) + coeff * (z*node%Moments(3,M2_32) + x*node%Moments(3,M2_21) - x*node%Moments(2,M2_31) - y*node%Moments(2,M2_32)) - Uloc(2) = Uloc(2) + coeff * (x*node%Moments(1,M2_31) + y*node%Moments(1,M2_32) - y*node%Moments(3,M2_21) - z*node%Moments(3,M2_31)) - Uloc(3) = Uloc(3) + coeff * (y*node%Moments(2,M2_21) + z*node%Moments(2,M2_31) - z*node%Moments(1,M2_32) - x*node%Moments(1,M2_21)) - Uind(1:3) = Uind(1:3) + Uloc - nQuad=nQuad+1 + coeff = coeff5*0.5_ReKi ! 3/2 * 1/(4 pi r**5) + coeff7= -7.5_ReKi*fourpi_inv/r**7 + !! NOTE: KEEP ME + !do i =1,3 + ! Uloc(1) = Uloc(1) + coeff* (y*node%Moments(3,5+2*(i/2)+3*(i/3)) - z*node%Moments(2,5+2*(i/2)+3*(i/3))) + ! Uloc(2) = Uloc(2) + coeff* (z*node%Moments(1,5+2*(i/2)+3*(i/3)) - x*node%Moments(3,5+2*(i/2)+3*(i/3))) + ! Uloc(3) = Uloc(3) + coeff* (x*node%Moments(2,5+2*(i/2)+3*(i/3)) - y*node%Moments(1,5+2*(i/2)+3*(i/3))) + ! do j=1,i + ! if (i==j) then + ! ieqj = 1.0_ReKi + ! else + ! ieqj = 2.0_ReKi + ! end if + ! coeff7ij = DeltaP(i)*DeltaP(j)*coeff7 + ! Uloc(1) = Uloc(1) + ieqj * coeff7ij * ( y*node%Moments(3,3+i+j+i/3) - z*node%Moments(2,3+i+j+i/3)) + ! Uloc(2) = Uloc(2) + ieqj * coeff7ij * ( z*node%Moments(1,3+i+j+i/3) - x*node%Moments(3,3+i+j+i/3)) + ! Uloc(3) = Uloc(3) + ieqj * coeff7ij * ( x*node%Moments(2,3+i+j+i/3) - y*node%Moments(1,3+i+j+i/3)) + ! end do + !end do + !! r5 terms, unrolled version + !! Uloc(1) = Uloc(1) + coeff * (y*node%Moments(3,5+2*(i/2)+3*(i/3)) - z*node%Moments(2,5+2*(i/2)+3*(i/3))) + !! Uloc(2) = Uloc(2) + coeff * (z*node%Moments(1,5+2*(i/2)+3*(i/3)) - x*node%Moments(3,5+2*(i/2)+3*(i/3))) + !! Uloc(3) = Uloc(3) + coeff * (x*node%Moments(2,5+2*(i/2)+3*(i/3)) - y*node%Moments(1,5+2*(i/2)+3*(i/3))) + ! i=1 + Uloc(1) = Uloc(1) + coeff * (y*node%Moments(3,5) - z*node%Moments(2,5)) + Uloc(2) = Uloc(2) + coeff * (z*node%Moments(1,5) - x*node%Moments(3,5)) + Uloc(3) = Uloc(3) + coeff * (x*node%Moments(2,5) - y*node%Moments(1,5)) + ! i=2 + Uloc(1) = Uloc(1) + coeff * (y*node%Moments(3,7) - z*node%Moments(2,7)) + Uloc(2) = Uloc(2) + coeff * (z*node%Moments(1,7) - x*node%Moments(3,7)) + Uloc(3) = Uloc(3) + coeff * (x*node%Moments(2,7) - y*node%Moments(1,7)) + ! i=3 + Uloc(1) = Uloc(1) + coeff * (y*node%Moments(3,8) - z*node%Moments(2,8)) + Uloc(2) = Uloc(2) + coeff * (z*node%Moments(1,8) - x*node%Moments(3,8)) + Uloc(3) = Uloc(3) + coeff * (x*node%Moments(2,8) - y*node%Moments(1,8)) + ! r7 terms, unrolled version + ! coeff7ij = DeltaP(i)*DeltaP(j)*coeff7 * (1 or 2 depdening if i=j) + ! Uloc(1) = Uloc(1) + ieqj * coeff7ij * ( y*node%Moments(3,3+i+j+i/3) - z*node%Moments(2,3+i+j+i/3)) + ! Uloc(2) = Uloc(2) + ieqj * coeff7ij * ( z*node%Moments(1,3+i+j+i/3) - x*node%Moments(3,3+i+j+i/3)) + ! Uloc(3) = Uloc(3) + ieqj * coeff7ij * ( x*node%Moments(2,3+i+j+i/3) - y*node%Moments(1,3+i+j+i/3)) + ! i=1, j=1 + coeff7ij = DeltaP(1)*DeltaP(1)*coeff7 !=-7.5_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + Uloc(1) = Uloc(1) + coeff7ij * (y*node%Moments(3,5) - z*node%Moments(2,5)) + Uloc(2) = Uloc(2) + coeff7ij * (z*node%Moments(1,5) - x*node%Moments(3,5)) + Uloc(3) = Uloc(3) + coeff7ij * (x*node%Moments(2,5) - y*node%Moments(1,5)) + ! i=2, j=1 + coeff7ij = 2.0_ReKi* DeltaP(2)*DeltaP(1)*coeff7 !=-15_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + Uloc(1) = Uloc(1) + coeff7ij * (y*node%Moments(3,6) - z*node%Moments(2,6)) + Uloc(2) = Uloc(2) + coeff7ij * (z*node%Moments(1,6) - x*node%Moments(3,6)) + Uloc(3) = Uloc(3) + coeff7ij * (x*node%Moments(2,6) - y*node%Moments(1,6)) + ! i=2, j=2 + coeff7ij = DeltaP(2)*DeltaP(2)*coeff7 !=-7.5_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + Uloc(1) = Uloc(1) + coeff7ij * (y*node%Moments(3,7) - z*node%Moments(2,7)) + Uloc(2) = Uloc(2) + coeff7ij * (z*node%Moments(1,7) - x*node%Moments(3,7)) + Uloc(3) = Uloc(3) + coeff7ij * (x*node%Moments(2,7) - y*node%Moments(1,7)) + ! i=3, j=1 + coeff7ij = 2.0_ReKi*DeltaP(3)*DeltaP(1)*coeff7 !=-15_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + Uloc(1) = Uloc(1) + coeff7ij * (y*node%Moments(3,8) - z*node%Moments(2,8)) + Uloc(2) = Uloc(2) + coeff7ij * (z*node%Moments(1,8) - x*node%Moments(3,8)) + Uloc(3) = Uloc(3) + coeff7ij * (x*node%Moments(2,8) - y*node%Moments(1,8)) + ! i=3, j=2 + coeff7ij = 2.0_ReKi*DeltaP(3)*DeltaP(2)*coeff7 !=-15_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + Uloc(1) = Uloc(1) + coeff7ij * (y*node%Moments(3,9) - z*node%Moments(2,9)) + Uloc(2) = Uloc(2) + coeff7ij * (z*node%Moments(1,9) - x*node%Moments(3,9)) + Uloc(3) = Uloc(3) + coeff7ij * (x*node%Moments(2,9) - y*node%Moments(1,9)) + ! i=3, j=3 + coeff7ij = DeltaP(3)*DeltaP(3)*coeff7 !=-7.5_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + Uloc(1) = Uloc(1) + coeff7ij * (y*node%Moments(3,10) - z*node%Moments(2,10)) + Uloc(2) = Uloc(2) + coeff7ij * (z*node%Moments(1,10) - x*node%Moments(3,10)) + Uloc(3) = Uloc(3) + coeff7ij * (x*node%Moments(2,10) - y*node%Moments(1,10)) + + ! r5 terms 2 + Uloc(1) = Uloc(1) + coeff5 * (y*node%Moments(3,M2_22) - z*node%Moments(2,M2_33)) + Uloc(2) = Uloc(2) + coeff5 * (z*node%Moments(1,M2_33) - x*node%Moments(3,M2_11)) + Uloc(3) = Uloc(3) + coeff5 * (x*node%Moments(2,M2_11) - y*node%Moments(1,M2_22)) + Uloc(1) = Uloc(1) + coeff5 * (z*node%Moments(3,M2_32) + x*node%Moments(3,M2_21) - x*node%Moments(2,M2_31) - y*node%Moments(2,M2_32)) + Uloc(2) = Uloc(2) + coeff5 * (x*node%Moments(1,M2_31) + y*node%Moments(1,M2_32) - y*node%Moments(3,M2_21) - z*node%Moments(3,M2_31)) + Uloc(3) = Uloc(3) + coeff5 * (y*node%Moments(2,M2_21) + z*node%Moments(2,M2_31) - z*node%Moments(1,M2_32) - x*node%Moments(1,M2_21)) + Uquad = Uquad + Uloc + + Uind = Uind + Uquad end if ! Far enough end if ! had more than 1 particles end subroutine ui_tree_segment_11 end subroutine ui_tree_segment + + !> Compute second order expansion of velocity for a given point based on moment up to order 2 (quadrupole) + !! TODO: might be sensitive to numerics since r,x,y,z might be large + pure subroutine ui_expansion_order2(r, DeltaP, Moments, Uind) + real(ReKi), intent(in ) :: r !< Norm of DeltaP + real(ReKi), dimension(3), intent(in ) :: DeltaP !< ControlPoint - Vorticity Center + real(ReKi), dimension(3,10), intent(in ) :: Moments!< Moments from Taylor expansion + real(ReKi), dimension(3), intent( out) :: Uind !< Velocity + real(ReKi) :: coeff, coeff3, coeff5, coeff7, coeff7ij + real(ReKi) :: x, y, z + real(ReKi),dimension(3) :: phi + real(ReKi),dimension(3) :: Uloc + !integer :: i,j + !real(ReKi) :: ieqj + Uind=0.0_ReKi + + !! NOTE all of this is common between particle and segment + coeff3 = fourpi_inv/r**3 + x=DeltaP(1) + y=DeltaP(2) + z=DeltaP(3) + ! Speed, order 0 + phi = Moments(1:3,M0)*coeff3 + Uloc(1) = phi(2)*z - phi(3)*y + Uloc(2) = phi(3)*x - phi(1)*z + Uloc(3) = phi(1)*y - phi(2)*x + Uind = Uind + Uloc + + ! Speed, order 1 + Uloc=0.0_ReKi + coeff5 = 3.0_ReKi*fourpi_inv/r**5 + coeff = coeff5*x + Uloc(1) = Uloc(1)- coeff*(Moments(3,M1_1)*y-Moments(2,M1_1)*z) + Uloc(2) = Uloc(2)- coeff*(Moments(1,M1_1)*z-Moments(3,M1_1)*x) + Uloc(3) = Uloc(3)- coeff*(Moments(2,M1_1)*x-Moments(1,M1_1)*y) + + coeff = coeff5*y + Uloc(1) = Uloc(1) - coeff*(Moments(3,M1_2)*y-Moments(2,M1_2)*z) + Uloc(2) = Uloc(2) - coeff*(Moments(1,M1_2)*z-Moments(3,M1_2)*x) + Uloc(3) = Uloc(3) - coeff*(Moments(2,M1_2)*x-Moments(1,M1_2)*y) + + coeff = coeff5*z + Uloc(1) = Uloc(1) - coeff*(Moments(3,M1_3)*y-Moments(2,M1_3)*z) + Uloc(2) = Uloc(2) - coeff*(Moments(1,M1_3)*z-Moments(3,M1_3)*x) + Uloc(3) = Uloc(3) - coeff*(Moments(2,M1_3)*x-Moments(1,M1_3)*y) + + Uloc(1) = Uloc(1) + coeff3*Moments(3,M1_2) - coeff3*Moments(2,M1_3) + Uloc(2) = Uloc(2) + coeff3*Moments(1,M1_3) - coeff3*Moments(3,M1_1) + Uloc(3) = Uloc(3) + coeff3*Moments(2,M1_1) - coeff3*Moments(1,M1_2) + Uind=Uind+Uloc + + ! Speed, order 2 + Uloc =0.0_ReKi + coeff = coeff5*0.5_ReKi ! 3/2 * 1/(4 pi r**5) + coeff7= -7.5_ReKi*fourpi_inv/r**7 + !! NOTE: KEEP ME + !do i =1,3 + ! Uloc(1) = Uloc(1) + coeff* (y*Moments(3,5+2*(i/2)+3*(i/3)) - z*Moments(2,5+2*(i/2)+3*(i/3))) + ! Uloc(2) = Uloc(2) + coeff* (z*Moments(1,5+2*(i/2)+3*(i/3)) - x*Moments(3,5+2*(i/2)+3*(i/3))) + ! Uloc(3) = Uloc(3) + coeff* (x*Moments(2,5+2*(i/2)+3*(i/3)) - y*Moments(1,5+2*(i/2)+3*(i/3))) + ! do j=1,i + ! if (i==j) then + ! ieqj = 1.0_ReKi + ! else + ! ieqj = 2.0_ReKi + ! end if + ! coeff7ij = DeltaP(i)*DeltaP(j)*coeff7 + ! Uloc(1) = Uloc(1) + ieqj * coeff7ij * ( y*Moments(3,3+i+j+i/3) - z*Moments(2,3+i+j+i/3)) + ! Uloc(2) = Uloc(2) + ieqj * coeff7ij * ( z*Moments(1,3+i+j+i/3) - x*Moments(3,3+i+j+i/3)) + ! Uloc(3) = Uloc(3) + ieqj * coeff7ij * ( x*Moments(2,3+i+j+i/3) - y*Moments(1,3+i+j+i/3)) + ! end do + !end do + !! r5 terms, unrolled version + !! Uloc(1) = Uloc(1) + coeff * (y*Moments(3,5+2*(i/2)+3*(i/3)) - z*Moments(2,5+2*(i/2)+3*(i/3))) + !! Uloc(2) = Uloc(2) + coeff * (z*Moments(1,5+2*(i/2)+3*(i/3)) - x*Moments(3,5+2*(i/2)+3*(i/3))) + !! Uloc(3) = Uloc(3) + coeff * (x*Moments(2,5+2*(i/2)+3*(i/3)) - y*Moments(1,5+2*(i/2)+3*(i/3))) + ! i=1 + Uloc(1) = Uloc(1) + coeff * (y*Moments(3,5) - z*Moments(2,5)) + Uloc(2) = Uloc(2) + coeff * (z*Moments(1,5) - x*Moments(3,5)) + Uloc(3) = Uloc(3) + coeff * (x*Moments(2,5) - y*Moments(1,5)) + ! i=2 + Uloc(1) = Uloc(1) + coeff * (y*Moments(3,7) - z*Moments(2,7)) + Uloc(2) = Uloc(2) + coeff * (z*Moments(1,7) - x*Moments(3,7)) + Uloc(3) = Uloc(3) + coeff * (x*Moments(2,7) - y*Moments(1,7)) + ! i=3 + Uloc(1) = Uloc(1) + coeff * (y*Moments(3,8) - z*Moments(2,8)) + Uloc(2) = Uloc(2) + coeff * (z*Moments(1,8) - x*Moments(3,8)) + Uloc(3) = Uloc(3) + coeff * (x*Moments(2,8) - y*Moments(1,8)) + ! r7 terms, unrolled version + ! coeff7ij = DeltaP(i)*DeltaP(j)*coeff7 * (1 or 2 depdening if i=j) + ! Uloc(1) = Uloc(1) + ieqj * coeff7ij * ( y*Moments(3,3+i+j+i/3) - z*Moments(2,3+i+j+i/3)) + ! Uloc(2) = Uloc(2) + ieqj * coeff7ij * ( z*Moments(1,3+i+j+i/3) - x*Moments(3,3+i+j+i/3)) + ! Uloc(3) = Uloc(3) + ieqj * coeff7ij * ( x*Moments(2,3+i+j+i/3) - y*Moments(1,3+i+j+i/3)) + ! i=1, j=1 + coeff7ij = DeltaP(1)*DeltaP(1)*coeff7 !=-7.5_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + Uloc(1) = Uloc(1) + coeff7ij * (y*Moments(3,5) - z*Moments(2,5)) + Uloc(2) = Uloc(2) + coeff7ij * (z*Moments(1,5) - x*Moments(3,5)) + Uloc(3) = Uloc(3) + coeff7ij * (x*Moments(2,5) - y*Moments(1,5)) + ! i=2, j=1 + coeff7ij = 2.0_ReKi* DeltaP(2)*DeltaP(1)*coeff7 !=-15_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + Uloc(1) = Uloc(1) + coeff7ij * (y*Moments(3,6) - z*Moments(2,6)) + Uloc(2) = Uloc(2) + coeff7ij * (z*Moments(1,6) - x*Moments(3,6)) + Uloc(3) = Uloc(3) + coeff7ij * (x*Moments(2,6) - y*Moments(1,6)) + ! i=2, j=2 + coeff7ij = DeltaP(2)*DeltaP(2)*coeff7 !=-7.5_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + Uloc(1) = Uloc(1) + coeff7ij * (y*Moments(3,7) - z*Moments(2,7)) + Uloc(2) = Uloc(2) + coeff7ij * (z*Moments(1,7) - x*Moments(3,7)) + Uloc(3) = Uloc(3) + coeff7ij * (x*Moments(2,7) - y*Moments(1,7)) + ! i=3, j=1 + coeff7ij = 2.0_ReKi*DeltaP(3)*DeltaP(1)*coeff7 !=-15_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + Uloc(1) = Uloc(1) + coeff7ij * (y*Moments(3,8) - z*Moments(2,8)) + Uloc(2) = Uloc(2) + coeff7ij * (z*Moments(1,8) - x*Moments(3,8)) + Uloc(3) = Uloc(3) + coeff7ij * (x*Moments(2,8) - y*Moments(1,8)) + ! i=3, j=2 + coeff7ij = 2.0_ReKi*DeltaP(3)*DeltaP(2)*coeff7 !=-15_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + Uloc(1) = Uloc(1) + coeff7ij * (y*Moments(3,9) - z*Moments(2,9)) + Uloc(2) = Uloc(2) + coeff7ij * (z*Moments(1,9) - x*Moments(3,9)) + Uloc(3) = Uloc(3) + coeff7ij * (x*Moments(2,9) - y*Moments(1,9)) + ! i=3, j=3 + coeff7ij = DeltaP(3)*DeltaP(3)*coeff7 !=-7.5_ReKi*DeltaP(i)*DeltaP(j)*fourpi_inv/r**7 + Uloc(1) = Uloc(1) + coeff7ij * (y*Moments(3,10) - z*Moments(2,10)) + Uloc(2) = Uloc(2) + coeff7ij * (z*Moments(1,10) - x*Moments(3,10)) + Uloc(3) = Uloc(3) + coeff7ij * (x*Moments(2,10) - y*Moments(1,10)) + + ! r5 terms 2 + Uloc(1) = Uloc(1) + coeff5 * (y*Moments(3,M2_22) - z*Moments(2,M2_33)) + Uloc(2) = Uloc(2) + coeff5 * (z*Moments(1,M2_33) - x*Moments(3,M2_11)) + Uloc(3) = Uloc(3) + coeff5 * (x*Moments(2,M2_11) - y*Moments(1,M2_22)) + Uloc(1) = Uloc(1) + coeff5 * (z*Moments(3,M2_32) + x*Moments(3,M2_21) - x*Moments(2,M2_31) - y*Moments(2,M2_32)) + Uloc(2) = Uloc(2) + coeff5 * (x*Moments(1,M2_31) + y*Moments(1,M2_32) - y*Moments(3,M2_21) - z*Moments(3,M2_31)) + Uloc(3) = Uloc(3) + coeff5 * (y*Moments(2,M2_21) + z*Moments(2,M2_31) - z*Moments(1,M2_32) - x*Moments(1,M2_21)) + Uind = Uind + Uloc + end subroutine ui_expansion_order2 + + ! -------------------------------------------------------------------------------- ! --- Vector analysis tools ! -------------------------------------------------------------------------------- @@ -1814,4 +2147,99 @@ subroutine curl_regular_grid(f,rotf,ix,iy,iz,nx,ny,nz,dx,dy,dz) !endif end subroutine curl_regular_grid + + + ! --- TIC TOC MODULE + !> Simpler version of matlab tic + subroutine tic(label) + character(len=*),intent(in),optional ::label !< Optional label will be displayed when calling toc + character(len=nmax_label)::lbl + integer :: i + if (npos0) then + lbl(i:i)=label((i-npos):(i-npos)) + else + lbl(i:i)=' ' + endif + endif + enddo + else + lbl='' + endif + ! + npos=npos+1 + call date_and_time(values=time_array) + start_arrays(npos,1:8) = time_array(1:8) !< we store the whole array + labels(npos)=lbl + else + write(*,*) 'TicToc: stack full' + endif + + end subroutine tic + + !> Simpler version of matlab toc. Computes elapsed wallclock after a call to tic() + subroutine toc(delta_t_out) + real(ReKi), intent(out), optional :: delta_t_out + real(ReKi) :: delta_t + integer, dimension(8) :: v_dt + if (npos<=nmax_store.and.npos>0 ) then + call date_and_time(values=time_array) + v_dt=time_array-start_arrays(npos,1:8) + if (v_dt(4)<0. ) then + v_dt(6)=v_dt(6)+30 ! approximate month change + endif + delta_t= v_dt(4)*86400+v_dt(5)*3600+v_dt(6)*60 +v_dt(7)+0.001*v_dt(8) + if (.not. bSilentTicToc) then + if((bSmartTicToc .and. delta_t>SmartTicTocVal) .or.(.not.bSmartTicToc)) then + write (6, '(A,A,A,A)') 'Time: ',labels(npos),'- Time: ', pretty_time(delta_t) + endif + endif + npos=npos-1 + else + write(*,*) 'TicToc: stack error' + delta_t=0 + endif + if(present(delta_t_out)) then + delta_t_out=delta_t + endif + end subroutine toc + + function pretty_time(t) + character(len=6) :: pretty_time + real(ReKi), intent(in) :: t + integer :: d,m,h,s,c + if(t<0) then + write(pretty_time,'(A)') '------' + elseif(t<1) then + !c=int(t*1000) + !write(pretty_time,'(A,I3.3)') '00.',c + c=int(t*100) + write(pretty_time,'(A,I2.2,A)') ' 0.',c,'s' + elseif(t<60) then + s=int(t) + c=int((t-s)*100) + write(pretty_time,'(I2,A,I2.2,A)') s,'.',c,'s' + elseif(t<3600) then + m=int(t/60) + s=mod(int(t),60) + write(pretty_time,'(I2,A,I2.2,A)') m,'m',s,'s' + elseif(t<86400) then + h=int(t/3600); + m=int(mod(int(t),3600)/60); + write(pretty_time,'(I2,A,I2.2,A)') h,'h',m,'m' + elseif(t<8553600) then + d=int(t/86400); + h=int(mod(int(t),86400)/3600); + write(pretty_time,'(I2,A,I2.2,A)') d,'d',h,'h' + else + pretty_time='+3mon.' + endif + end function pretty_time + ! --- END TIC TOC MODULE + end module FVW_VortexTools diff --git a/modules/aerodyn/src/FVW_Wings.f90 b/modules/aerodyn/src/FVW_Wings.f90 index 47dda876d..443653caa 100644 --- a/modules/aerodyn/src/FVW_Wings.f90 +++ b/modules/aerodyn/src/FVW_Wings.f90 @@ -2,7 +2,11 @@ module FVW_Wings use NWTC_Library use FVW_Types - use FVW_Subs + use FVW_BiotSavart, only: ui_quad_n1 + use FVW_VortexTools, only: tic, toc + use FVW_Subs, only: DEV_VERSION, OLAF_PROFILING + use FVW_Subs, only: idCircPrescribed, idCircPolarData, idCircNoFlowThrough + use FVW_Subs, only: LiftingLineInducedVelocities use AirFoilInfo, only : AFI_ComputeAirfoilCoefs implicit none @@ -63,10 +67,10 @@ end subroutine Meshing !! - s_CP : Dimensionless spanwise coordinate of LL CP !! - chord_LL : chord on LL nodes !! - chord_CP : chord on LL control points (CP) - subroutine Wings_Panelling_Init(Meshes, p, m, ErrStat, ErrMsg ) + subroutine Wings_Panelling_Init(Meshes, p, ErrStat, ErrMsg ) type(MeshType), dimension(:), intent(in ) :: Meshes !< Wings mesh type(FVW_ParameterType), intent(inout) :: p !< Parameters - type(FVW_MiscVarType), intent(inout) :: m !< Initial misc/optimization variables + !type(FVW_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 ! Local @@ -234,15 +238,15 @@ end subroutine Wings_Panelling !---------------------------------------------------------------------------------------------------------------------------------- !> - subroutine Wings_ComputeCirculation(t, z, z_prev, u, p, x, m, AFInfo, ErrStat, ErrMsg, iLabel) + subroutine Wings_ComputeCirculation(t, z, z_prev, p, x, m, AFInfo, ErrStat, ErrMsg, iLabel) real(DbKi), intent(in ) :: t !< Current simulation time in seconds type(FVW_ConstraintStateType), intent(inout) :: z !< z%W%Gamma_LL type(FVW_ConstraintStateType), intent(in ) :: z_prev !< z_prev%W%Gamma_LL !real(ReKi), dimension(:,:), intent(inout) :: Gamma_LL !< Circulation on all the lifting lines !real(ReKi), dimension(:,:), intent(in ) :: Gamma_LL_prev !< Previous/Guessed circulation - type(FVW_InputType), intent(in ) :: u !< Parameters + !type(FVW_InputType), intent(in ) :: u !< Inputs type(FVW_ParameterType), intent(in ) :: p !< Parameters - type(FVW_ContinuousStateType), intent(in ) :: x !< Parameters + type(FVW_ContinuousStateType), intent(in ) :: x !< Continuous States type(FVW_MiscVarType), intent(inout) :: m !< Initial misc/optimization variables type(AFI_ParameterType), intent(in ) :: AFInfo(:) !< The airfoil parameter data integer(IntKi), intent( out) :: ErrStat !< Error status of the operation @@ -255,14 +259,14 @@ subroutine Wings_ComputeCirculation(t, z, z_prev, u, p, x, m, AFInfo, ErrStat, E ErrStat = ErrID_None ErrMsg = "" - if (t= 9) then + if (p%FullCircStart/p%DTfvw >= 9) then ! Smooth approximations of the Heavyside function ! Example 1: 1/2 (1+2/pi arctan(k x) ) x \in ]-infty,+infty [ ! Example 2: 1/(1+exp(k x) ) x \in ]-infty,+infty [ @@ -277,18 +281,18 @@ subroutine Wings_ComputeCirculation(t, z, z_prev, u, p, x, m, AFInfo, ErrStat, E GammaScale=1.0_ReKi endif - if (p%CirculationMethod==idCircPrescribed) then + if (p%CircSolvMethod==idCircPrescribed) then do iW = 1, p%nWings !Loop over lifting lines z%W(iW)%Gamma_LL(1:p%W(iW)%nSpan) = p%W(iW)%PrescribedCirculation(1:p%W(iW)%nSpan) m%W(iW)%Vind_CP=-9999._ReKi !< Safety m%W(iW)%Vtot_CP=-9999._ReKi !< Safety enddo - else if (p%CirculationMethod==idCircPolarData) then + else if (p%CircSolvMethod==idCircPolarData) then ! --- Solve for circulation using polar data CALL Wings_ComputeCirculationPolarData(z, z_prev, p, x, m, AFInfo, GammaScale, ErrStat, ErrMsg, iLabel) - else if (p%CirculationMethod==idCircNoFlowThrough) then + else if (p%CircSolvMethod==idCircNoFlowThrough) then ! --- Solve for circulation using the no-flow through condition ErrMsg='Circulation method nor implemented'; ErrStat=ErrID_Fatal; return ! should never happen else @@ -334,6 +338,7 @@ subroutine Wings_ComputeCirculationPolarData(z, z_prev, p, x, m, AFInfo, GammaSc integer(IntKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 + ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" @@ -380,7 +385,9 @@ subroutine Wings_ComputeCirculationPolarData(z, z_prev, p, x, m, AFInfo, GammaSc ! Set induced velocity from Known wake only (after iNWStart+1) ! if InductionAtCP : In: m%W%CP, Out:m%W%Vind_CP and m%W%Vind_LL (averaged) ! if not InductionAtCP : In: m%W%r_LL, Out:m%W%Vind_CP (interp/extrap) and m%W%Vind_LL + if (OLAF_PROFILING) call tic('LLUI') call LiftingLineInducedVelocities(p, x, p%InductionAtCP, p%iNWStart+1, m, ErrStat2, ErrMsg2); if(Failed()) return; + if (OLAF_PROFILING) call toc() kCP=0 do iW=1,p%nWings @@ -406,6 +413,7 @@ subroutine Wings_ComputeCirculationPolarData(z, z_prev, p, x, m, AFInfo, GammaSc endif ! --- Convergence loop until near wake gives induction coherent with circulation + if (OLAF_PROFILING) call tic('Convergence loop') bConverged=.false. iIter=0 do while (.not.(bConverged) .and. iIter= AbortErrLev) then + ! Temporarily allowing backward compatibility.. + call WrScr('') + call WrScr('[WARN] An error occured when reading the output section of the UA Driver input file.') + call WrScr(' Make sure it is at the latest version. See error message below:') + call WrScr(trim(ErrMsg)) + call WrScr('') + call WrScr('[INFO] Continuing using default output options.') + call WrScr('') + InitInp%SumPrint = .True. + InitInp%WrAFITables = .True. + ErrStat = ErrID_None + ErrMsg = '' + endif + 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() - ! 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 + ! Close this module's echo file if ( InitInp%Echo ) then close(UnEchoLocal) end if - close( UnIn ) - end subroutine Cleanup - - end subroutine ReadDriverInputFile subroutine ReadTimeSeriesData( inputsFile, nSimSteps, timeArr, AOAarr, Uarr, OmegaArr, ErrStat, ErrMsg ) @@ -519,17 +535,17 @@ subroutine Cleanup() end subroutine Cleanup end subroutine ReadTimeSeriesData !-------------------------------------------------------------------------------------------------------------- - subroutine Init_AFI(UAMod, NumAFfiles, afNames, UseCm, AFI_Params, ErrStat, ErrMsg) + subroutine Init_AFI(UAMod, NumAFfiles, afNames, UseCm, UA_f_cn, AFI_Params, ErrStat, ErrMsg) integer, intent(in ) :: UAMod integer, intent(in ) :: NumAFfiles CHARACTER(1024), intent(in ) :: afNames(NumAFfiles) logical, intent(in ) :: UseCm + logical, intent(in ) :: UA_f_cn type(AFI_ParameterType), intent( out) :: AFI_Params(NumAFfiles) integer(IntKi), intent( out) :: ErrStat ! Error status. character(*), intent( out) :: ErrMsg ! Error message. - type(AFI_InitInputType) :: AFI_InitInputs integer :: UnEc integer :: i @@ -561,8 +577,8 @@ subroutine Init_AFI(UAMod, NumAFfiles, afNames, UseCm, AFI_Params, ErrStat, ErrM end if AFI_InitInputs%InCol_Cpmin = 0 - AFI_InitInputs%AFTabMod = AFITable_1 ! 1D-interpolation (on AoA only) - AFI_InitInputs%UA_f_cn = UAMod /= UA_HGM ! HGM needs the separation function based on cl instead of cn + AFI_InitInputs%AFTabMod = AFITable_1 ! 1D-interpolation (on AoA only) + AFI_InitInputs%UA_f_cn = UA_f_cn do i=1,NumAFfiles AFI_InitInputs%FileName = afNames(i) !InitInp%AF_File(i) @@ -597,46 +613,108 @@ end subroutine Cleanup end subroutine Init_AFI - subroutine WriteAFITables(AFI_Params,OutRootName) + subroutine WriteAFITables(AFI_Params, OutRootName, UseCm, UA_f_cn) - type(AFI_ParameterType), intent(in) :: AFI_Params - character(ErrMsgLen) , intent(in) :: OutRootName + type(AFI_ParameterType), intent(in), target :: AFI_Params + character(len=*) , intent(in) :: OutRootName + logical , intent(in) :: UseCm + logical , intent(in) :: UA_f_cn integer(IntKi) :: unOutFile - integer(IntKi) :: row integer(IntKi) :: ErrStat character(ErrMsgLen) :: ErrMsg - Real(ReKi) :: cl_smooth(AFI_Params%Table(1)%NumAlf) - Real(ReKi) :: cn_smooth(AFI_Params%Table(1)%NumAlf) - Real(ReKi) :: cn(AFI_Params%Table(1)%NumAlf) + Real(ReKi), allocatable :: cl_smooth(:) + Real(ReKi), allocatable :: cn_smooth(:) + Real(ReKi), allocatable :: cn(:) + Real(ReKi), allocatable :: cl_lin(:) + Real(ReKi), allocatable :: cn_lin(:) + character(len=3) :: Prefix + character(len=11) :: sFullyAtt + character(len=8) :: sCm + integer :: iTab, iRow, iStartUA + type(AFI_Table_Type), pointer :: tab !< Alias + + if (UA_f_cn) then + Prefix='Cn_' + sFullyAtt='Cn_FullyAtt' + else + Prefix='Cl_' + sFullyAtt='Dummy' + endif + if (UseCm) then + sCm='Cm' + else + sCm='Cm_Dummy' + endif + + + ! Loop on tables, write a different file for each table. + do iTab = 1, size(AFI_Params%Table) + tab => AFI_Params%Table(iTab) + + ! Compute derived parameters from cl and cd, and UA_BL + if(allocated(cl_smooth)) deallocate(cl_smooth) + if(allocated(cn_smooth)) deallocate(cn_smooth) + if(allocated(cn )) deallocate(cn ) + if(allocated(cl_lin )) deallocate(cl_lin ) + if(allocated(cn_lin )) deallocate(cn_lin ) + allocate(cl_smooth(tab%NumAlf)) + allocate(cn_smooth(tab%NumAlf)) + allocate(cn (tab%NumAlf)) + allocate(cl_lin (tab%NumAlf)) + allocate(cn_lin (tab%NumAlf)) + + + cn = tab%Coefs(:,AFI_Params%ColCl) * cos(tab%alpha) + (tab%Coefs(:,AFI_Params%ColCd) - tab%UA_BL%Cd0) * sin(tab%alpha); + cn_lin = tab%UA_BL%C_nalpha * (tab%alpha - tab%UA_BL%alpha0) + cl_lin = tab%UA_BL%C_lalpha * (tab%alpha - tab%UA_BL%alpha0) + + do iRow = 1, tab%NumAlf + if ((tab%alpha(iRow)tab%UA_BL%alphaUpperWrap) then + cl_lin(iRow) =0.0_ReKi + cn_lin(iRow) =0.0_ReKi + endif + enddo + + ! Smoothing (used priot to compute slope in CalculateUACoeffs) + call kernelSmoothing(tab%alpha, cn , kernelType_TRIWEIGHT, 2.0_ReKi*D2R, cn_smooth) + call kernelSmoothing(tab%alpha, tab%Coefs(:,AFI_Params%ColCl), kernelType_TRIWEIGHT, 2.0_ReKi*D2R, cl_smooth) + + ! Write to file + + CALL GetNewUnit( unOutFile, ErrStat, ErrMsg ) + IF ( ErrStat /= ErrID_None ) RETURN + + CALL OpenFOutFile ( unOutFile, trim(OutRootName)//'.UA.Coefs.'//trim(num2lstr(iTab))//'.out', ErrStat, ErrMsg ) + if (ErrStat >= AbortErrLev) then + call WrScr(Trim(ErrMsg)) + return + end if - cn = AFI_Params%Table(1)%Coefs(:,AFI_Params%ColCl) * cos(AFI_Params%Table(1)%alpha) + (AFI_Params%Table(1)%Coefs(:,AFI_Params%ColCd) - AFI_Params%Table(1)%UA_BL%Cd0) * sin(AFI_Params%Table(1)%alpha); + WRITE (unOutFile,'(/,A/)') 'These predictions were generated by UnsteadyAero Driver on '//CurDate()//' at '//CurTime()//'.' + WRITE (unOutFile,'(/,A/)') ' ' - call kernelSmoothing(AFI_Params%Table(1)%alpha, cn, kernelType_TRIWEIGHT, 2.0_ReKi*D2R, cn_smooth) - call kernelSmoothing(AFI_Params%Table(1)%alpha, AFI_Params%Table(1)%Coefs(:,AFI_Params%ColCl), kernelType_TRIWEIGHT, 2.0_ReKi*D2R, cl_smooth) + WRITE(unOutFile, '(20(A20,1x))') 'Alpha', 'Cl', 'Cd', sCm, 'Cn', 'f_st', Prefix//'FullySep', sFullyAtt , 'Cl_lin','Cn_lin','Cl_smooth', 'Cn_smooth' + WRITE(unOutFile, '(20(A20,1x))') '(deg)', '(-)', '(-)', '(-)', '(-)', '(-)', '(-)' , '(-)' , '(-)' , '(-)' , '(-)' ,'(-)' - CALL GetNewUnit( unOutFile, ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - - CALL OpenFOutFile ( unOutFile, trim(OutRootName)//'.Coefs.out', ErrStat, ErrMsg ) - if (ErrStat >= AbortErrLev) then - call WrScr(Trim(ErrMsg)) - return - end if - - - WRITE (unOutFile,'(/,A/)') 'These predictions were generated by UnsteadyAero Driver on '//CurDate()//' at '//CurTime()//'.' - WRITE (unOutFile,'(/,A/)') ' ' - ! note that this header assumes we have Cm and unsteady aero coefficients - WRITE(unOutFile, '(20(A20,1x))') 'Alpha', 'Cl', 'Cd', 'Cm', 'f_st', 'FullySeparate', 'FullyAttached', 'smoothed_Cl', 'smoothed_Cn' - WRITE(unOutFile, '(20(A20,1x))') '(deg)', '(-)', '(-)', '(-)', '(-)', '(-)', '(-)', '(-)', '(-)' - - do row=1,size(AFI_Params%Table(1)%Alpha) - WRITE(unOutFile, '(20(F20.6,1x))') AFI_Params%Table(1)%Alpha(row)*R2D, AFI_Params%Table(1)%Coefs(row,:), cl_smooth(Row), cn_smooth(Row) - end do - - CLOSE(unOutFile) + ! TODO, we could do something with ColCpmim and ColUAf + if (UseCm) then + iStartUA = 4 + do iRow=1,size(tab%Alpha) + WRITE(unOutFile, '(20(F20.6,1x))') tab%Alpha(iRow)*R2D, tab%Coefs(iRow,AFI_Params%ColCl), tab%Coefs(iRow,AFI_Params%ColCd), tab%Coefs(iRow,AFI_Params%ColCm), & + cn(iRow), tab%Coefs(iRow,iStartUA:), cl_lin(iRow), cn_lin(iRow), cl_smooth(iRow), cn_smooth(iRow) + end do + else + iStartUA = 3 + do iRow=1,size(tab%Alpha) + WRITE(unOutFile, '(20(F20.6,1x))') tab%Alpha(iRow)*R2D, tab%Coefs(iRow,AFI_Params%ColCl), tab%Coefs(iRow,AFI_Params%ColCd), 0.0_ReKi, & + cn(iRow), tab%Coefs(iRow,iStartUA:), cl_lin(iRow), cn_lin(iRow), cl_smooth(iRow), cn_smooth(iRow) + end do + endif + + CLOSE(unOutFile) + enddo end subroutine WriteAFITables diff --git a/modules/aerodyn/src/UnsteadyAero.f90 b/modules/aerodyn/src/UnsteadyAero.f90 index 1c8421c14..84f0addf1 100644 --- a/modules/aerodyn/src/UnsteadyAero.f90 +++ b/modules/aerodyn/src/UnsteadyAero.f90 @@ -18,6 +18,23 @@ ! limitations under the License. ! !********************************************************************************************************************************** +! References: +! +! [40] E. Branlard, B. Jonkman, G.R. Pirrung, K. Dixon, J. Jonkman (2022) +! Dynamic inflow and unsteady aerodynamics models for modal and stability analyses in OpenFAST, +! Journal of Physics: Conference Series, doi:10.1088/1742-6596/2265/3/032044 +! +! [41] E. Branlard, J. Jonkman, B.Jonkman (2020) +! Development plan for the aerodynamic linearization in OpenFAST +! Unpublished +! +! [70] User Documentation / AeroDyn / Unsteady Aerodynamics / Boing-Vertol model +! https://openfast.readthedocs.io/ +! +! [other] R. Damiani and G. Hayman (2017) +! The Unsteady Aerodynamics Module for FAST 8 +! NOTE: equations for this reference are labeled as x.y [n] where n is the number of the equation when several equations are given. + module UnsteadyAero ! This module uses equations defined in the document "The Unsteady Aerodynamics Module for FAST 8" by Rick Damiani and Greg Hayman, 28-Feb-2017 @@ -728,8 +745,10 @@ subroutine UA_SetParameters( dt, InitInp, p, AFInfo, AFIndx, ErrStat, ErrMsg ) p%Flookup = InitInp%Flookup p%ShedEffect = InitInp%ShedEffect - if (p%UAMod==UA_HGM) then + if (p%UAMod==UA_HGM .or. p%UAMod==UA_HGMV) then p%lin_nx = p%numBlades*p%nNodesPerBlade*4 ! 4 continuous states per node per blade (5th state isn't currently linearizable) + else if (p%UAMod==UA_OYE) then + p%lin_nx = p%numBlades*p%nNodesPerBlade*1 ! continuous state per node per blade, but stored at position 4 else p%lin_nx = 0 end if @@ -1309,15 +1328,16 @@ subroutine UA_Init( InitInp, u, p, x, xd, OtherState, y, m, Interval, & p%Delim ='' if (p%NumOuts > 0) then - CALL GetNewUnit( p%unOutFile, ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN + CALL GetNewUnit( p%unOutFile, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return CALL OpenFOutFile ( p%unOutFile, trim(InitInp%OutRootName)//'.UA.out', ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return ! Heading: WRITE (p%unOutFile,'(/,A/)') 'These predictions were generated by UnsteadyAero on '//CurDate()//' at '//CurTime()//'.' - WRITE (p%unOutFile,'(/,A/)', IOSTAT=ErrStat) ' ' + WRITE (p%unOutFile,'(/,A/)', IOSTAT=ErrStat2) ' ' ! Write the names of the output parameters: WRITE (p%unOutFile,'('//p%OutSFmt//')', ADVANCE='no' ) 'Time' @@ -1358,7 +1378,7 @@ subroutine UA_ValidateInput(InitInp, ErrStat, ErrMsg) ErrMsg = "" if (InitInp%UAMod < UA_Gonzalez .or. InitInp%UAMod > UA_BV ) call SetErrStat( ErrID_Fatal, & - "In this version, UAMod must be 2 (Gonzalez's variant), 3 (Minnema/Pierce variant), 4 (continuous HGM model), 5 (HGM with vortex)& + "In this version, UAMod must be 2 (Gonzalez's variant), 3 (Minnema/Pierce variant), 4 (continuous HGM model), 5 (HGM with vortex), & &6 (Oye), 7 (Boing-Vertol)", ErrStat, ErrMsg, RoutineName ) ! NOTE: for later- 1 (baseline/original) if (.not. InitInp%FLookUp ) call SetErrStat( ErrID_Fatal, 'FLookUp must be TRUE for this version.', ErrStat, ErrMsg, RoutineName ) @@ -1369,15 +1389,16 @@ subroutine UA_ValidateInput(InitInp, ErrStat, ErrMsg) end subroutine UA_ValidateInput !============================================================================== subroutine UA_ValidateAFI(UAMod, AFInfo, ErrStat, ErrMsg) - integer(IntKi), intent(in ) :: UAMod ! which UA model we are using - type(AFI_ParameterType), intent(in ) :: AFInfo ! The airfoil parameter data - integer(IntKi), intent( out) :: ErrStat ! Error status of the operation - character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None + integer(IntKi), intent(in ) :: UAMod ! which UA model we are using + type(AFI_ParameterType), target, intent(in ) :: AFInfo ! The airfoil parameter data + integer(IntKi), intent( out) :: ErrStat ! Error status of the operation + character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None integer(IntKi) :: j integer(IntKi) :: indx - real(ReKi) :: cl_fs + real(ReKi) :: cl_fs, vmax character(*), parameter :: RoutineName = 'UA_ValidateAFI' + type(AFI_Table_Type), pointer :: tab !< Alias ErrStat = ErrID_None ErrMsg = "" @@ -1387,6 +1408,7 @@ subroutine UA_ValidateAFI(UAMod, AFInfo, ErrStat, ErrMsg) else do j=1, AFInfo%NumTabs + tab => AFInfo%Table(j) if ( AFInfo%Table(j)%InclUAdata ) then ! parameters used only for UAMod/=UA_HGM) @@ -1446,6 +1468,31 @@ subroutine UA_ValidateAFI(UAMod, AFInfo, ErrStat, ErrMsg) call SetErrStat(ErrID_Severe, 'UA cutout parameter should be at a value where the separation function is 0 in "'//trim(AFInfo%FileName)//'".'// & " Separation function is "//trim(num2lstr(cl_fs)), ErrStat, ErrMsg, RoutineName ) end if + ! C_alpha should have a reasonable value + if (abs(tab%UA_BL%C_lalpha)>9.11_ReKi) then ! 45% above 2*pi, arbitrary.. + call SetErrStat(ErrID_Severe, 'Large value of C_lalpha in "'//trim(AFInfo%FileName)//'".'// & + " C_lalpha="//trim(num2lstr(tab%UA_BL%C_lalpha))//& + ". We advise to check this value or provide it in the input file.", ErrStat, ErrMsg, RoutineName ) + endif + ! NOTE: check if C_nalpha is alwasy defined + ! C_lalpha and C_nalpha should be in the same ballpark + if (abs(tab%UA_BL%C_nalpha-tab%UA_BL%C_lalpha)>3.0_ReKi) then ! arbitrary criteria.. + call SetErrStat(ErrID_Severe, 'Large difference between C_lalpha and C_nalpha in "'//trim(AFInfo%FileName)//'".'// & + " C_lalpha="//trim(num2lstr(tab%UA_BL%C_lalpha))//& + " C_nalpha="//trim(num2lstr(tab%UA_BL%C_nalpha))//& + ". We advise to check these value or provide them in the input file.", ErrStat, ErrMsg, RoutineName ) + endif + vmax = maxval(tab%Coefs(:,AFInfo%ColUAf)) + if (vmax>1.00_ReKi) then + call SetErrStat(ErrID_Severe, 'The separation function f_st exceed 1 in "'//trim(AFInfo%FileName)//'".'// & + " max(f_st)="//trim(num2lstr(vmax))//& + ". Check the calculation or provide f_st in the input file.", ErrStat, ErrMsg, RoutineName ) + endif + if (vmax<0.70_ReKi) then + call SetErrStat(ErrID_Severe, 'The separation function f_st does not reach 1 in "'//trim(AFInfo%FileName)//'".'// & + " max(f_st)="//trim(num2lstr(vmax))//& + ". Check the calculation or provide f_st in the input file.", ErrStat, ErrMsg, RoutineName ) + endif end if if (UAMod == UA_BV) then @@ -1507,9 +1554,13 @@ subroutine UA_TurnOff_param(p, AFInfo, ErrStat, ErrMsg) ErrMsg = "" do j=1, AFInfo%NumTabs - if ( .not. AFInfo%Table(j)%InclUAdata ) then + if ( AFInfo%Table(j)%ConstData ) then ErrStat = ErrID_Fatal - ErrMsg = 'UA parameters are not included in airfoil (airfoil has likely has constant polars).' + ErrMsg = 'polar has constant data.' + return + else if ( .not. AFInfo%Table(j)%InclUAdata ) then + ErrStat = ErrID_Fatal + ErrMsg = 'UA parameters are not included in airfoil.' return end if end do @@ -1648,7 +1699,7 @@ end function Failed end subroutine UA_UpdateDiscOtherState_BV !============================================================================== -!> Calculate angle of attacks using Boeing-Vertol model +!> Calculate angle of attacks using Boeing-Vertol model, see [70] !! Drag effective angle of attack needs extra computation subroutine BV_getAlphas(i, j, u, p, xd, BL_p, tc, alpha_34, alphaE_L, alphaLag_D, adotnorm) integer, intent(in ) :: i !< node index within a blade @@ -1707,7 +1758,7 @@ subroutine BV_getAlphas(i, j, u, p, xd, BL_p, tc, alpha_34, alphaE_L, alphaLag_D alphaLag_D = alpha_34 - dalphaD*isgn ! NOTE: not effective alpha yet for drag end subroutine BV_getAlphas !============================================================================== -!> Calculate gamma for lift and drag based rel thickness. See CACTUS BV_DynStall.f95 +!> Calculate gamma for lift and drag based rel thickness. See CACTUS BV_DynStall.f95 subroutine BV_getGammas(tc, umach, gammaL, gammaD) real(ReKi), intent(in) :: tc !< Relative thickness of airfoil real(ReKi), intent(in) :: umach !< Mach number of Urel, = Urel*MinfMinf (freestrem Mach), 0 for incompressible @@ -1750,7 +1801,7 @@ real(ReKi) function BV_TransA(BL_p) BV_TransA = .5_ReKi*dalphaMax ! transition region for fairing lagged AOA in pure lag model end function BV_TransA !============================================================================== -!> Calculate deltas to negative and postivive stall angle +!> Calculate deltas to negative and postivive stall angle, see [70] subroutine BV_delNP(adotnorm, alpha, alphaLag_D, BL_p, activeD, delN, delP) real(ReKi), intent(in) :: adotnorm !< alphadot * Tu real(ReKi), intent(in) :: alpha !< alpha (3/4) @@ -1782,7 +1833,7 @@ subroutine BV_delNP(adotnorm, alpha, alphaLag_D, BL_p, activeD, delN, delP) end if end subroutine BV_delNP !============================================================================== -!> Calculate effective angle of attack for drag coefficient, based on lagged angle of attack +!> Calculate effective angle of attack for drag coefficient, based on lagged angle of attack, see [70] real(ReKi) function BV_alphaE_D(adotnorm, alpha, alphaLag_D, BL_p, activeD) real(ReKi), intent(in) :: adotnorm !< alphadot * Tu real(ReKi), intent(in) :: alpha !< alpha (3/4) @@ -1811,7 +1862,7 @@ real(ReKi) function BV_alphaE_D(adotnorm, alpha, alphaLag_D, BL_p, activeD) end if end function BV_alphaE_D !============================================================================== -!> Activate dynamic stall for lift or drag +!> Activate dynamic stall for lift or drag, see [70] subroutine BV_UpdateActiveStates(adotnorm, alpha, alphaLag_D, alphaE_L, BL_p, activeL, activeD) real(ReKi), intent(in) :: adotnorm !< alphadot * Tu real(ReKi), intent(in) :: alpha !< alpha (3/4) @@ -2414,7 +2465,7 @@ SUBROUTINE HGM_Steady( i, j, u, p, x, AFInfo, ErrStat, ErrMsg ) x%x(3) = AFI_interp%Cl ! Not used elseif (p%UAMod==UA_HGM) then - x%x(3) = BL_p%c_lalpha * (alphaE-BL_p%alpha0) + x%x(3) = BL_p%c_lalpha * (alphaE-BL_p%alpha0) ! Clp ! calculate x%x(4) = fs_aF = f_st(alphaF): !alphaF = x%x(3)/BL_p%c_lalpha + BL_p%alpha0 ! p. 13 @@ -2513,7 +2564,7 @@ subroutine UA_CalcContStateDeriv( i, j, t, u_in, p, x, OtherState, AFInfo, m, dx ! find alphaF where FullyAttached(alphaF) = x(3) if (p%UAMod == UA_HGM) then !note: BL_p%c_lalpha cannot be zero. UA is turned off at initialization if this occurs. - alphaF = x%x(3)/BL_p%c_lalpha + BL_p%alpha0 ! p. 13 + alphaF = x%x(3)/BL_p%c_lalpha + BL_p%alpha0 ! Eq. 15 [40] else if (p%UAMod == UA_OYE) then alphaF = alpha_34 @@ -2550,8 +2601,8 @@ subroutine UA_CalcContStateDeriv( i, j, t, u_in, p, x, OtherState, AFInfo, m, dx call AddOrSub2Pi(real(x%x(1),ReKi), alpha_34) ! make sure we use the same alpha_34 for both x1 and x2 equations. if (p%ShedEffect) then - dxdt%x(1) = -1.0_R8Ki / Tu * (BL_p%b1 + p%c(i,j) * U_dot/(2*u%u**2)) * x%x(1) + BL_p%b1 * BL_p%A1 / Tu * alpha_34 - dxdt%x(2) = -1.0_R8Ki / Tu * (BL_p%b2 + p%c(i,j) * U_dot/(2*u%u**2)) * x%x(2) + BL_p%b2 * BL_p%A2 / Tu * alpha_34 + dxdt%x(1) = -1.0_R8Ki / Tu * (BL_p%b1 + p%c(i,j) * U_dot/(2*u%u**2)) * x%x(1) + BL_p%b1 * BL_p%A1 / Tu * alpha_34 ! Eq. 8 [40] + dxdt%x(2) = -1.0_R8Ki / Tu * (BL_p%b2 + p%c(i,j) * U_dot/(2*u%u**2)) * x%x(2) + BL_p%b2 * BL_p%A2 / Tu * alpha_34 ! Eq. 9 [40] else dxdt%x(1) = 0.0_ReKi dxdt%x(2) = 0.0_ReKi @@ -2560,8 +2611,8 @@ subroutine UA_CalcContStateDeriv( i, j, t, u_in, p, x, OtherState, AFInfo, m, dx if (p%UAMod == UA_HGM) then call AddOrSub2Pi(BL_p%alpha0, alphaE) Clp = BL_p%c_lalpha * (alphaE - BL_p%alpha0) + pi * Tu * u%omega ! Eq. 13 - dxdt%x(3) = -1.0_R8Ki / BL_p%T_p * x%x(3) + 1.0_ReKi / BL_p%T_p * Clp - dxdt%x(4) = -1.0_R8Ki / BL_p%T_f0 * x4 + 1.0_ReKi / BL_p%T_f0 * AFI_AlphaF%f_st + dxdt%x(3) = -1.0_R8Ki / BL_p%T_p * x%x(3) + 1.0_ReKi / BL_p%T_p * Clp ! Eq. 10 [40] + dxdt%x(4) = -1.0_R8Ki / BL_p%T_f0 * x4 + 1.0_ReKi / BL_p%T_f0 * AFI_AlphaF%f_st ! Eq. 11 [40] dxdt%x(5) = 0.0_R8Ki elseif (p%UAMod == UA_OYE) then @@ -3008,6 +3059,7 @@ subroutine UA_CalcOutput( i, j, t, u_in, p, x, xd, OtherState, AFInfo, y, misc, real(ReKi) :: cn_circ, tau_vl, tV_ratio real(ReKi) :: delta_c_df_primeprime real(ReKi), parameter :: delta_c_mf_primeprime = 0.0_ReKi + real(ReKi) :: cl_circ, cd_tors TYPE(UA_ElementContinuousStateType) :: x_in ! Continuous states at t ! for BV real(ReKi) :: alphaE_L, alphaE_D ! effective angle of attack for lift and drag @@ -3138,18 +3190,20 @@ subroutine UA_CalcOutput( i, j, t, u_in, p, x, xd, OtherState, AFInfo, y, misc, call AddOrSub2Pi(BL_p%alpha0, alphaE) cl_fa = (alphaE - BL_p%alpha0) * BL_p%c_lalpha - delta_c_df_primeprime = 0.5_ReKi * (sqrt(fs_aE) - sqrt(x4)) - 0.25_ReKi * (fs_aE - x4) ! Eq. 81 + delta_c_df_primeprime = 0.5_ReKi * (sqrt(fs_aE) - sqrt(x4)) - 0.25_ReKi * (fs_aE - x4) ! Eq. 20 [40] ! bjj: do we need to check that u%alpha is between -pi and + pi? - y%Cl = x4 * cl_fa + (1.0_ReKi - x4) * cl_fs + pi * Tu * u%omega ! Eq. 78 + cl_circ = x4 * cl_fa + (1.0_ReKi - x4) * cl_fs ! Eq. 19 [40] + y%Cl = cl_circ + pi * Tu * u%omega ! Eq. 16 [40] call AddOrSub2Pi(u%alpha, alphaE) - y%Cd = AFI_interp%Cd + (u%alpha - alphaE) * y%Cl + (AFI_interp%Cd - BL_p%Cd0) * delta_c_df_primeprime ! Eq. 79 + cd_tors = cl_circ * Tu * u%omega + y%Cd = AFI_interp%Cd + (alpha_34 - alphaE) * cl_circ + (AFI_interp%Cd - BL_p%Cd0) * delta_c_df_primeprime + cd_tors ! Eq. 17 [40] if (AFInfo%ColCm == 0) then ! we don't have a cm column, so make everything 0 y%Cm = 0.0_ReKi else - y%Cm = AFI_interp%Cm + y%Cl * delta_c_mf_primeprime - piBy2 * Tu * u%omega ! Eq. 80 + y%Cm = AFI_interp%Cm + y%Cl * delta_c_mf_primeprime - piBy2 * Tu * u%omega ! Eq. 18 [40] end if y%Cn = y%Cl*cos(u%alpha) + y%Cd*sin(u%alpha) @@ -3170,10 +3224,10 @@ subroutine UA_CalcOutput( i, j, t, u_in, p, x, xd, OtherState, AFInfo, y, misc, tau_vl = tau_vl / Tu ! make this non-dimensional (to compare with T_VL) tV_ratio = min(1.5_ReKi, tau_vl/BL_p%T_VL) - delta_c_df_primeprime = 0.5_ReKi * (sqrt(fs_aE) - sqrt(x4)) - 0.25_ReKi * (fs_aE - x4) ! Eq. 81 + delta_c_df_primeprime = 0.5_ReKi * (sqrt(fs_aE) - sqrt(x4)) - 0.25_ReKi * (fs_aE - x4) ! Eq. 20 [40] call AddOrSub2Pi(u%alpha, alphaE) - y%Cd = AFI_interp%Cd + (u%alpha - alphaE) * y%Cn + (AFI_interp%Cd - BL_p%Cd0) * delta_c_df_primeprime ! Eq. 79 + y%Cd = AFI_interp%Cd + (u%alpha - alphaE) * y%Cn + (AFI_interp%Cd - BL_p%Cd0) * delta_c_df_primeprime ! Eq. 79 [41] if (AFInfo%ColCm == 0) then ! we don't have a cm column, so make everything 0 @@ -3453,7 +3507,7 @@ subroutine UA_CalcOutput( i, j, t, u_in, p, x, xd, OtherState, AFInfo, y, misc, contains !> Calc Outputs for Boieng-Vertol dynamic stall - !! See BV_DynStall.f95 of CACTUS, notations kept more or less consistent + !! See BV_DynStall.f95 of CACTUS, and [70], notations kept more or less consistent subroutine BV_CalcOutput() real(ReKi) :: alpha_50 real(ReKi) :: Cm25_stat diff --git a/modules/aerodyn/src/UnsteadyAero_Driver.f90 b/modules/aerodyn/src/UnsteadyAero_Driver.f90 index cd1591a12..1ffac3286 100644 --- a/modules/aerodyn/src/UnsteadyAero_Driver.f90 +++ b/modules/aerodyn/src/UnsteadyAero_Driver.f90 @@ -69,6 +69,7 @@ program UnsteadyAero_Driver real(ReKi), allocatable :: AOAarr(:) real(ReKi), allocatable :: Uarr(:) real(ReKi), allocatable :: OmegaArr(:) + logical :: UA_f_cn ! Should the separation function be computed using Cn or Cl CHARACTER(200) :: git_commit TYPE(ProgDesc), PARAMETER :: version = ProgDesc( 'UnsteadyAero Driver', '', '' ) ! The version number of this program. @@ -157,7 +158,7 @@ program UnsteadyAero_Driver end if InitInData%OutRootName = dvrInitInp%OutRootName - InitInData%WrSum = .true. ! write all the AFI data + InitInData%WrSum = dvrInitInp%SumPrint ! write all the AFI data if ( dvrInitInp%SimMod == 1 ) then @@ -179,13 +180,16 @@ program UnsteadyAero_Driver ! Initialize the Airfoil Info Params afNames(1) = dvrInitInp%AirFoil1 ! All nodes/blades are using the same 2D airfoil AFIndx(1,1) = 1 - call Init_AFI( InitInData%UAMod, NumAFfiles, afNames, dvrInitInp%UseCm, AFI_Params, errStat, errMsg ) + UA_f_cn = (InitInData%UAMod /= UA_HGM).and.(InitInData%UAMod /= UA_OYE) ! HGM and OYE use the separation function based on cl instead of cn + call Init_AFI( InitInData%UAMod, NumAFfiles, afNames, dvrInitInp%UseCm, UA_f_cn, AFI_Params, errStat, errMsg ) call checkError() -! call WriteAFITables(AFI_Params(1), dvrInitInp%OutRootName) + if (dvrInitInp%WrAFITables) then + call WriteAFITables(AFI_Params(1), dvrInitInp%OutRootName, dvrInitInp%UseCm, UA_f_cn) + endif - ! Initialize UnsteadyAero (after AFI) + ! Initialize UnsteadyAero (after AFI) call UA_Init( InitInData, u(1), p, x, xd, OtherState, y, m, dt, AFI_Params, AFIndx, InitOutData, errStat, errMsg ) call checkError() @@ -202,7 +206,8 @@ program UnsteadyAero_Driver !u(3) = time at n=-1 (t= -2dt) if NumInp > 2 DO iu = 1, NumInp-1 !u(NumInp) is overwritten in time-sim loop, so no need to init here - call setUAinputs(2-iu, u(iu), uTimes(iu), dt, dvrInitInp, timeArr, AOAarr, Uarr, OmegaArr) + call setUAinputs(2-iu, u(iu), uTimes(iu), dt, dvrInitInp, timeArr, AOAarr, Uarr, OmegaArr, errStat, errMsg) + call checkError() END DO ! Set inputs which do not vary with node or time @@ -220,8 +225,9 @@ program UnsteadyAero_Driver END DO ! first value of uTimes/u contain inputs at t+dt - call setUAinputs(n+1, u(1), uTimes(1), dt, dvrInitInp, timeArr, AOAarr, Uarr, OmegaArr) - + call setUAinputs(n+1, u(1), uTimes(1), dt, dvrInitInp, timeArr, AOAarr, Uarr, OmegaArr, errStat, errMsg) + call checkError() + t = uTimes(2) ! Use existing states to compute the outputs @@ -276,48 +282,91 @@ subroutine checkError() end subroutine checkError !---------------------------------------------------------------------------------------------------- - subroutine setUAinputs(n,u,t,dt,dvrInitInp,timeArr,AOAarr,Uarr,OmegaArr) - - integer, intent(in) :: n - type(UA_InputType), intent(inout) :: u ! System inputs - real(DbKi), intent( out) :: t - real(DbKi), intent(in) :: dt - TYPE(UA_Dvr_InitInput), intent(in) :: dvrInitInp ! Initialization data for the driver program - real(DbKi), intent(in) :: timeArr(:) - real(ReKi), intent(in) :: AOAarr(:) - real(ReKi), intent(in) :: Uarr(:) - real(ReKi), intent(in) :: OmegaArr(:) - integer :: indx - real(ReKi) :: phase + subroutine setUAinputs(n,u,t,dt,dvrInitInp,timeArr,AOAarr,Uarr,OmegaArr,errStat,errMsg) + + integer, intent(in) :: n + type(UA_InputType), intent(inout) :: u ! System inputs + real(DbKi), intent( out) :: t + real(DbKi), intent(in) :: dt + TYPE(UA_Dvr_InitInput), intent(in) :: dvrInitInp ! Initialization data for the driver program + real(DbKi), intent(in), allocatable :: timeArr(:) + real(ReKi), intent(in), allocatable :: AOAarr(:) + real(ReKi), intent(in), allocatable :: Uarr(:) + real(ReKi), intent(in), allocatable :: OmegaArr(:) + integer, intent(out) :: errStat + character(len=*), intent(out) :: errMsg + integer :: indx + real(ReKi) :: phase + real(ReKi) :: d_ref2AC + real(ReKi) :: alpha_ref + real(ReKi) :: U_ref + real(ReKi) :: v_ref(2) + real(ReKi) :: v_34(2) + logical, parameter :: OscillationAtMidChord=.true. ! for legacy, use false + logical, parameter :: VelocityAt34 =.true. ! for legacy, use false + + ! Initialize error handling variables + ErrMsg = '' + ErrStat = ErrID_None u%UserProp = 0 u%Re = dvrInitInp%Re if ( dvrInitInp%SimMod == 1 ) then + if (OscillationAtMidChord) then + d_ref2AC =-0.25_ReKi ! -0.25: oscillations at mid_chord + else + d_ref2AC = 0.0_ReKi ! 0: oscillations at AC + endif + U_ref = dvrInitInp%InflowVel ! m/s + t = (n-1)*dt phase = (n+dvrInitInp%Phase-1)*2*pi/dvrInitInp%StepsPerCycle - u%alpha = (dvrInitInp%Amplitude * sin(phase) + dvrInitInp%Mean)*D2R ! This needs to be in radians - ! u%omega = dvrInitInp%Amplitude * cos(phase) * dvrInitInp%Frequency * pi**2 / 90.0 ! This needs to be in radians derivative: d_alpha /d_t + alpha_ref = (dvrInitInp%Amplitude * sin(phase) + dvrInitInp%Mean)*D2R ! This needs to be in radians + v_ref(1) = sin(alpha_ref)*U_ref + v_ref(2) = cos(alpha_ref)*U_ref u%omega = dvrInitInp%Amplitude * cos(phase) * 2*pi/dvrInitInp%StepsPerCycle / dt * D2R ! This needs to be in radians derivative: d_alpha /d_t - - u%U = dvrInitInp%InflowVel ! m/s + + u%v_ac(1) = v_ref(1) + u%omega * d_ref2AC* dvrInitInp%Chord + u%v_ac(2) = v_ref(2) + + v_34(1) = u%v_ac(1) + u%omega * 0.5* dvrInitInp%Chord + v_34(2) = u%v_ac(2) + + + u%alpha = atan2(u%v_ac(1), u%v_ac(2) ) ! + if (VelocityAt34) then + u%U = sqrt(v_34(1)**2 + v_34(2)**2) ! Using U at 3/4 + else + u%U = sqrt(u%v_ac(1)**2 + u%v_ac(2)**2) ! Using U at 1/4 + endif + + else - indx = min(n,size(timeArr)) - indx = max(1, indx) ! use constant data at initialization + ! check optional variables and allocation status + if (all( (/ allocated(timeArr),allocated(AOAarr),allocated(OmegaArr),allocated(Uarr) /) )) then + + indx = min(n,size(timeArr)) + indx = max(1, indx) ! use constant data at initialization - ! Load timestep data from the time-series inputs which were previous read from input file - t = timeArr(indx) - u%alpha = AOAarr(indx)*pi/180.0 ! This needs to be in radians - u%omega = OmegaArr(indx) - u%U = Uarr(indx) - if (n> size(timeArr)) then - t = t + dt*(n - size(timeArr) ) ! update for NumInp>1; - elseif (n < 1) then - t = (n-1)*dt + ! Load timestep data from the time-series inputs which were previous read from input file + t = timeArr(indx) + u%alpha = AOAarr(indx)*pi/180.0 ! This needs to be in radians + u%omega = OmegaArr(indx) + u%U = Uarr(indx) + if (n> size(timeArr)) then + t = t + dt*(n - size(timeArr) ) ! update for NumInp>1; + elseif (n < 1) then + t = (n-1)*dt + end if + u%v_ac(1) = sin(u%alpha)*u%U + u%v_ac(2) = cos(u%alpha)*u%U + else + errStat = ErrID_Fatal + errMsg = 'mandatory input arrays are not allocated: timeArr,AOAarr,OmegaArr,Uarr' end if + end if - u%v_ac(1) = sin(u%alpha)*u%U - u%v_ac(2) = cos(u%alpha)*u%U end subroutine setUAinputs !---------------------------------------------------------------------------------------------------- diff --git a/modules/aerodyn/src/UnsteadyAero_Registry.txt b/modules/aerodyn/src/UnsteadyAero_Registry.txt index 733a4b46b..b71aef051 100644 --- a/modules/aerodyn/src/UnsteadyAero_Registry.txt +++ b/modules/aerodyn/src/UnsteadyAero_Registry.txt @@ -51,58 +51,58 @@ typedef ^ ^ CHARACTER(1 # Variables local to the Kelvin Chain: -typedef ^ UA_KelvinChainType ReKi Cn_prime - - - "" - -#typedef ^ UA_KelvinChainType ReKi Cn_prime_diff - - - "" - -typedef ^ UA_KelvinChainType ReKi C_nalpha_circ - - - "slope of the circulatory normal force coefficient vs alpha curve" - -typedef ^ UA_KelvinChainType ReKi Kalpha_f - - - "filtered backwards finite difference of alpha (xd%Kalpha_f_minus1)" - -typedef ^ UA_KelvinChainType ReKi Kq_f - - - "filtered backwards finite difference of q" - -typedef ^ UA_KelvinChainType ReKi alpha_filt_cur - - - "filtered angle of attack" - -typedef ^ UA_KelvinChainType ReKi alpha_e - - - "effective angle of attack at 3/4 chord TODO: verify 3/4 and not 1/4" - -typedef ^ UA_KelvinChainType ReKi dalpha0 - - - "" - -typedef ^ UA_KelvinChainType ReKi alpha_f - - - "" - -typedef ^ UA_KelvinChainType ReKi Kq - - - "" - -typedef ^ UA_KelvinChainType ReKi q_cur - - - "" - -typedef ^ UA_KelvinChainType ReKi q_f_cur - - - "" - -typedef ^ UA_KelvinChainType ReKi X1 - - - "" - -typedef ^ UA_KelvinChainType ReKi X2 - - - "" - -typedef ^ UA_KelvinChainType ReKi X3 - - - "" - -typedef ^ UA_KelvinChainType ReKi X4 - - - "" - -typedef ^ UA_KelvinChainType ReKi Kprime_alpha - - - "" - -typedef ^ UA_KelvinChainType ReKi Kprime_q - - - "" - -typedef ^ UA_KelvinChainType ReKi K3prime_q - - - "" - -typedef ^ UA_KelvinChainType ReKi Kprimeprime_q - - - "" - -typedef ^ UA_KelvinChainType ReKi Dp - - - "" - -typedef ^ UA_KelvinChainType ReKi Cn_pot - - - "" - -typedef ^ UA_KelvinChainType ReKi Cc_pot - - - "" - -typedef ^ UA_KelvinChainType ReKi Cn_alpha_q_circ - - - "" - -typedef ^ UA_KelvinChainType ReKi Cn_alpha_q_nc - - - "non-circulatory component of normal force coefficient response to step change in alpha and q" - -typedef ^ UA_KelvinChainType ReKi Cm_q_circ - - - "" - -typedef ^ UA_KelvinChainType ReKi Cn_alpha_nc - - - "non-circulatory component of the normal force coefficient response to step change in alpha" - -typedef ^ UA_KelvinChainType ReKi Cn_q_circ - - - "" - -typedef ^ UA_KelvinChainType ReKi Cn_q_nc - - - "" - -typedef ^ UA_KelvinChainType ReKi Cm_q_nc - - - "non-circulatory component of the moment coefficient response to step change in q" - -typedef ^ UA_KelvinChainType ReKi fprimeprime - - - "" - -typedef ^ UA_KelvinChainType ReKi Df - - - "" - -typedef ^ UA_KelvinChainType ReKi Df_c - - - "" - -typedef ^ UA_KelvinChainType ReKi Df_m - - - "" - -typedef ^ UA_KelvinChainType ReKi Dalphaf - - - "" - -typedef ^ UA_KelvinChainType ReKi fprime - - - "" - -typedef ^ UA_KelvinChainType ReKi fprime_c - - - "" - -typedef ^ UA_KelvinChainType ReKi fprimeprime_c - - - "" - -typedef ^ UA_KelvinChainType ReKi fprime_m - - - "" - -typedef ^ UA_KelvinChainType ReKi fprimeprime_m - - - "" - -typedef ^ UA_KelvinChainType ReKi Cn_v - - - "normal force coefficient due to the presence of LE vortex" - -typedef ^ UA_KelvinChainType ReKi C_V - - - "contribution to the normal force coefficient due to accumulated vorticity in the LE vortex" - -typedef ^ UA_KelvinChainType ReKi Cn_FS - - - "" - -typedef ^ UA_KelvinChainType ReKi T_f - - - "" - -typedef ^ UA_KelvinChainType ReKi T_fc - - - "" - -typedef ^ UA_KelvinChainType ReKi T_fm - - - "" - -typedef ^ UA_KelvinChainType ReKi T_V - - - "backwards finite difference of the non-dimensionalized distance parameter" - -typedef ^ UA_KelvinChainType ReKi k_alpha - - - "" - -typedef ^ UA_KelvinChainType ReKi k_q - - - "" - -typedef ^ UA_KelvinChainType ReKi T_alpha - - - "" - -typedef ^ UA_KelvinChainType ReKi T_q - - - "" - -typedef ^ UA_KelvinChainType ReKi ds - - - "non-dimensionalized distance parameter" - +typedef ^ UA_KelvinChainType ReKi Cn_prime - 0.0 - "" - +#typedef ^ UA_KelvinChainType ReKi Cn_prime_diff - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi C_nalpha_circ - 0.0 - "slope of the circulatory normal force coefficient vs alpha curve" - +typedef ^ UA_KelvinChainType ReKi Kalpha_f - 0.0 - "filtered backwards finite difference of alpha (xd%Kalpha_f_minus1)" - +typedef ^ UA_KelvinChainType ReKi Kq_f - 0.0 - "filtered backwards finite difference of q" - +typedef ^ UA_KelvinChainType ReKi alpha_filt_cur - 0.0 - "filtered angle of attack" - +typedef ^ UA_KelvinChainType ReKi alpha_e - 0.0 - "effective angle of attack at 3/4 chord TODO: verify 3/4 and not 1/4" - +typedef ^ UA_KelvinChainType ReKi dalpha0 - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi alpha_f - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Kq - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi q_cur - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi q_f_cur - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi X1 - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi X2 - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi X3 - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi X4 - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Kprime_alpha - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Kprime_q - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi K3prime_q - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Kprimeprime_q - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Dp - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Cn_pot - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Cc_pot - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Cn_alpha_q_circ - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Cn_alpha_q_nc - 0.0 - "non-circulatory component of normal force coefficient response to step change in alpha and q" - +typedef ^ UA_KelvinChainType ReKi Cm_q_circ - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Cn_alpha_nc - 0.0 - "non-circulatory component of the normal force coefficient response to step change in alpha" - +typedef ^ UA_KelvinChainType ReKi Cn_q_circ - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Cn_q_nc - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Cm_q_nc - 0.0 - "non-circulatory component of the moment coefficient response to step change in q" - +typedef ^ UA_KelvinChainType ReKi fprimeprime - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Df - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Df_c - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Df_m - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Dalphaf - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi fprime - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi fprime_c - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi fprimeprime_c - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi fprime_m - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi fprimeprime_m - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi Cn_v - 0.0 - "normal force coefficient due to the presence of LE vortex" - +typedef ^ UA_KelvinChainType ReKi C_V - 0.0 - "contribution to the normal force coefficient due to accumulated vorticity in the LE vortex" - +typedef ^ UA_KelvinChainType ReKi Cn_FS - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi T_f - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi T_fc - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi T_fm - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi T_V - 0.0 - "backwards finite difference of the non-dimensionalized distance parameter" - +typedef ^ UA_KelvinChainType ReKi k_alpha - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi k_q - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi T_alpha - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi T_q - 0.0 - "" - +typedef ^ UA_KelvinChainType ReKi ds - 0.0 - "non-dimensionalized distance parameter" - # ..... States .................................................................................................................... @@ -114,8 +114,8 @@ typedef ^ ContinuousStateType UA_ElementC # typedef ^ DiscreteStateType ReKi alpha_minus1 {:}{:} - - "angle of attack, previous time step" rad typedef ^ DiscreteStateType ReKi alpha_filt_minus1 {:}{:} - - "filtered angle of attack, previous time step" rad -typedef ^ DiscreteStateType ReKi alpha_dot {:}{:} - - "Rate of change of angle of attack (filtered)" rad/s -typedef ^ DiscreteStateType ReKi alpha_dot_minus1 {:}{:} - - "Rate of change of angle of attack (filtered)" rad/s +typedef ^ DiscreteStateType ReKi alpha_dot {:}{:} - - "Rate of change of angle of attack (filtered); BV model" rad/s +typedef ^ DiscreteStateType ReKi alpha_dot_minus1 {:}{:} - - "Rate of change of angle of attack (filtered); BV modeldata" rad/s typedef ^ DiscreteStateType ReKi q_minus1 {:}{:} - - "non-dimensional pitching rate, previous time step" - typedef ^ DiscreteStateType ReKi Kalpha_f_minus1 {:}{:} - - "filtered pitching rate, previous time step" - typedef ^ DiscreteStateType ReKi Kq_f_minus1 {:}{:} - - "filtered pitching acceleration, previous time step" - diff --git a/modules/aerodyn/src/UnsteadyAero_Types.f90 b/modules/aerodyn/src/UnsteadyAero_Types.f90 index 48c47a9ff..3a4234206 100644 --- a/modules/aerodyn/src/UnsteadyAero_Types.f90 +++ b/modules/aerodyn/src/UnsteadyAero_Types.f90 @@ -66,57 +66,57 @@ MODULE UnsteadyAero_Types ! ======================= ! ========= UA_KelvinChainType ======= TYPE, PUBLIC :: UA_KelvinChainType - REAL(ReKi) :: Cn_prime !< [-] - REAL(ReKi) :: C_nalpha_circ !< slope of the circulatory normal force coefficient vs alpha curve [-] - REAL(ReKi) :: Kalpha_f !< filtered backwards finite difference of alpha (xd%Kalpha_f_minus1) [-] - REAL(ReKi) :: Kq_f !< filtered backwards finite difference of q [-] - REAL(ReKi) :: alpha_filt_cur !< filtered angle of attack [-] - REAL(ReKi) :: alpha_e !< effective angle of attack at 3/4 chord TODO: verify 3/4 and not 1/4 [-] - REAL(ReKi) :: dalpha0 !< [-] - REAL(ReKi) :: alpha_f !< [-] - REAL(ReKi) :: Kq !< [-] - REAL(ReKi) :: q_cur !< [-] - REAL(ReKi) :: q_f_cur !< [-] - REAL(ReKi) :: X1 !< [-] - REAL(ReKi) :: X2 !< [-] - REAL(ReKi) :: X3 !< [-] - REAL(ReKi) :: X4 !< [-] - REAL(ReKi) :: Kprime_alpha !< [-] - REAL(ReKi) :: Kprime_q !< [-] - REAL(ReKi) :: K3prime_q !< [-] - REAL(ReKi) :: Kprimeprime_q !< [-] - REAL(ReKi) :: Dp !< [-] - REAL(ReKi) :: Cn_pot !< [-] - REAL(ReKi) :: Cc_pot !< [-] - REAL(ReKi) :: Cn_alpha_q_circ !< [-] - REAL(ReKi) :: Cn_alpha_q_nc !< non-circulatory component of normal force coefficient response to step change in alpha and q [-] - REAL(ReKi) :: Cm_q_circ !< [-] - REAL(ReKi) :: Cn_alpha_nc !< non-circulatory component of the normal force coefficient response to step change in alpha [-] - REAL(ReKi) :: Cn_q_circ !< [-] - REAL(ReKi) :: Cn_q_nc !< [-] - REAL(ReKi) :: Cm_q_nc !< non-circulatory component of the moment coefficient response to step change in q [-] - REAL(ReKi) :: fprimeprime !< [-] - REAL(ReKi) :: Df !< [-] - REAL(ReKi) :: Df_c !< [-] - REAL(ReKi) :: Df_m !< [-] - REAL(ReKi) :: Dalphaf !< [-] - REAL(ReKi) :: fprime !< [-] - REAL(ReKi) :: fprime_c !< [-] - REAL(ReKi) :: fprimeprime_c !< [-] - REAL(ReKi) :: fprime_m !< [-] - REAL(ReKi) :: fprimeprime_m !< [-] - REAL(ReKi) :: Cn_v !< normal force coefficient due to the presence of LE vortex [-] - REAL(ReKi) :: C_V !< contribution to the normal force coefficient due to accumulated vorticity in the LE vortex [-] - REAL(ReKi) :: Cn_FS !< [-] - REAL(ReKi) :: T_f !< [-] - REAL(ReKi) :: T_fc !< [-] - REAL(ReKi) :: T_fm !< [-] - REAL(ReKi) :: T_V !< backwards finite difference of the non-dimensionalized distance parameter [-] - REAL(ReKi) :: k_alpha !< [-] - REAL(ReKi) :: k_q !< [-] - REAL(ReKi) :: T_alpha !< [-] - REAL(ReKi) :: T_q !< [-] - REAL(ReKi) :: ds !< non-dimensionalized distance parameter [-] + REAL(ReKi) :: Cn_prime = 0.0 !< [-] + REAL(ReKi) :: C_nalpha_circ = 0.0 !< slope of the circulatory normal force coefficient vs alpha curve [-] + REAL(ReKi) :: Kalpha_f = 0.0 !< filtered backwards finite difference of alpha (xd%Kalpha_f_minus1) [-] + REAL(ReKi) :: Kq_f = 0.0 !< filtered backwards finite difference of q [-] + REAL(ReKi) :: alpha_filt_cur = 0.0 !< filtered angle of attack [-] + REAL(ReKi) :: alpha_e = 0.0 !< effective angle of attack at 3/4 chord TODO: verify 3/4 and not 1/4 [-] + REAL(ReKi) :: dalpha0 = 0.0 !< [-] + REAL(ReKi) :: alpha_f = 0.0 !< [-] + REAL(ReKi) :: Kq = 0.0 !< [-] + REAL(ReKi) :: q_cur = 0.0 !< [-] + REAL(ReKi) :: q_f_cur = 0.0 !< [-] + REAL(ReKi) :: X1 = 0.0 !< [-] + REAL(ReKi) :: X2 = 0.0 !< [-] + REAL(ReKi) :: X3 = 0.0 !< [-] + REAL(ReKi) :: X4 = 0.0 !< [-] + REAL(ReKi) :: Kprime_alpha = 0.0 !< [-] + REAL(ReKi) :: Kprime_q = 0.0 !< [-] + REAL(ReKi) :: K3prime_q = 0.0 !< [-] + REAL(ReKi) :: Kprimeprime_q = 0.0 !< [-] + REAL(ReKi) :: Dp = 0.0 !< [-] + REAL(ReKi) :: Cn_pot = 0.0 !< [-] + REAL(ReKi) :: Cc_pot = 0.0 !< [-] + REAL(ReKi) :: Cn_alpha_q_circ = 0.0 !< [-] + REAL(ReKi) :: Cn_alpha_q_nc = 0.0 !< non-circulatory component of normal force coefficient response to step change in alpha and q [-] + REAL(ReKi) :: Cm_q_circ = 0.0 !< [-] + REAL(ReKi) :: Cn_alpha_nc = 0.0 !< non-circulatory component of the normal force coefficient response to step change in alpha [-] + REAL(ReKi) :: Cn_q_circ = 0.0 !< [-] + REAL(ReKi) :: Cn_q_nc = 0.0 !< [-] + REAL(ReKi) :: Cm_q_nc = 0.0 !< non-circulatory component of the moment coefficient response to step change in q [-] + REAL(ReKi) :: fprimeprime = 0.0 !< [-] + REAL(ReKi) :: Df = 0.0 !< [-] + REAL(ReKi) :: Df_c = 0.0 !< [-] + REAL(ReKi) :: Df_m = 0.0 !< [-] + REAL(ReKi) :: Dalphaf = 0.0 !< [-] + REAL(ReKi) :: fprime = 0.0 !< [-] + REAL(ReKi) :: fprime_c = 0.0 !< [-] + REAL(ReKi) :: fprimeprime_c = 0.0 !< [-] + REAL(ReKi) :: fprime_m = 0.0 !< [-] + REAL(ReKi) :: fprimeprime_m = 0.0 !< [-] + REAL(ReKi) :: Cn_v = 0.0 !< normal force coefficient due to the presence of LE vortex [-] + REAL(ReKi) :: C_V = 0.0 !< contribution to the normal force coefficient due to accumulated vorticity in the LE vortex [-] + REAL(ReKi) :: Cn_FS = 0.0 !< [-] + REAL(ReKi) :: T_f = 0.0 !< [-] + REAL(ReKi) :: T_fc = 0.0 !< [-] + REAL(ReKi) :: T_fm = 0.0 !< [-] + REAL(ReKi) :: T_V = 0.0 !< backwards finite difference of the non-dimensionalized distance parameter [-] + REAL(ReKi) :: k_alpha = 0.0 !< [-] + REAL(ReKi) :: k_q = 0.0 !< [-] + REAL(ReKi) :: T_alpha = 0.0 !< [-] + REAL(ReKi) :: T_q = 0.0 !< [-] + REAL(ReKi) :: ds = 0.0 !< non-dimensionalized distance parameter [-] END TYPE UA_KelvinChainType ! ======================= ! ========= UA_ElementContinuousStateType ======= @@ -133,8 +133,8 @@ MODULE UnsteadyAero_Types TYPE, PUBLIC :: UA_DiscreteStateType REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: alpha_minus1 !< angle of attack, previous time step [rad] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: alpha_filt_minus1 !< filtered angle of attack, previous time step [rad] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: alpha_dot !< Rate of change of angle of attack (filtered) [rad/s] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: alpha_dot_minus1 !< Rate of change of angle of attack (filtered) [rad/s] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: alpha_dot !< Rate of change of angle of attack (filtered); BV model [rad/s] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: alpha_dot_minus1 !< Rate of change of angle of attack (filtered); BV modeldata [rad/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: q_minus1 !< non-dimensional pitching rate, previous time step [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Kalpha_f_minus1 !< filtered pitching rate, previous time step [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Kq_f_minus1 !< filtered pitching acceleration, previous time step [-] @@ -309,15 +309,27 @@ SUBROUTINE UA_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrSt ENDIF END SUBROUTINE UA_CopyInitInput - SUBROUTINE UA_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE UA_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(UA_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%c)) THEN DEALLOCATE(InitInputData%c) ENDIF @@ -640,16 +652,29 @@ SUBROUTINE UA_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, Er ENDIF END SUBROUTINE UA_CopyInitOutput - SUBROUTINE UA_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE UA_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(UA_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Version, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Version, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF @@ -988,15 +1013,27 @@ SUBROUTINE UA_CopyKelvinChainType( SrcKelvinChainTypeData, DstKelvinChainTypeDat DstKelvinChainTypeData%ds = SrcKelvinChainTypeData%ds END SUBROUTINE UA_CopyKelvinChainType - SUBROUTINE UA_DestroyKelvinChainType( KelvinChainTypeData, ErrStat, ErrMsg ) + SUBROUTINE UA_DestroyKelvinChainType( KelvinChainTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(UA_KelvinChainType), INTENT(INOUT) :: KelvinChainTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyKelvinChainType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyKelvinChainType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE UA_DestroyKelvinChainType SUBROUTINE UA_PackKelvinChainType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1364,15 +1401,27 @@ SUBROUTINE UA_CopyElementContinuousStateType( SrcElementContinuousStateTypeData, DstElementContinuousStateTypeData%x = SrcElementContinuousStateTypeData%x END SUBROUTINE UA_CopyElementContinuousStateType - SUBROUTINE UA_DestroyElementContinuousStateType( ElementContinuousStateTypeData, ErrStat, ErrMsg ) + SUBROUTINE UA_DestroyElementContinuousStateType( ElementContinuousStateTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(UA_ElementContinuousStateType), INTENT(INOUT) :: ElementContinuousStateTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyElementContinuousStateType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyElementContinuousStateType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE UA_DestroyElementContinuousStateType SUBROUTINE UA_PackElementContinuousStateType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1517,19 +1566,32 @@ SUBROUTINE UA_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrSt ENDIF END SUBROUTINE UA_CopyContState - SUBROUTINE UA_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE UA_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(UA_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%element)) THEN DO i2 = LBOUND(ContStateData%element,2), UBOUND(ContStateData%element,2) DO i1 = LBOUND(ContStateData%element,1), UBOUND(ContStateData%element,1) - CALL UA_Destroyelementcontinuousstatetype( ContStateData%element(i1,i2), ErrStat, ErrMsg ) + CALL UA_Destroyelementcontinuousstatetype( ContStateData%element(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(ContStateData%element) @@ -2257,15 +2319,27 @@ SUBROUTINE UA_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt ENDIF END SUBROUTINE UA_CopyDiscState - SUBROUTINE UA_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE UA_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(UA_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(DiscStateData%alpha_minus1)) THEN DEALLOCATE(DiscStateData%alpha_minus1) ENDIF @@ -4113,15 +4187,27 @@ SUBROUTINE UA_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, DstConstrStateData%DummyConstraintState = SrcConstrStateData%DummyConstraintState END SUBROUTINE UA_CopyConstrState - SUBROUTINE UA_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE UA_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(UA_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE UA_DestroyConstrState SUBROUTINE UA_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -4426,15 +4512,27 @@ SUBROUTINE UA_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, Er ENDIF END SUBROUTINE UA_CopyOtherState - SUBROUTINE UA_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE UA_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(UA_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OtherStateData%FirstPass)) THEN DEALLOCATE(OtherStateData%FirstPass) ENDIF @@ -4454,7 +4552,8 @@ SUBROUTINE UA_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) DEALLOCATE(OtherStateData%n) ENDIF DO i1 = LBOUND(OtherStateData%xdot,1), UBOUND(OtherStateData%xdot,1) - CALL UA_DestroyContState( OtherStateData%xdot(i1), ErrStat, ErrMsg ) + CALL UA_DestroyContState( OtherStateData%xdot(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO IF (ALLOCATED(OtherStateData%t_vortexBegin)) THEN DEALLOCATE(OtherStateData%t_vortexBegin) @@ -5396,15 +5495,27 @@ SUBROUTINE UA_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) ENDIF END SUBROUTINE UA_CopyMisc - SUBROUTINE UA_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE UA_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(UA_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%TESF)) THEN DEALLOCATE(MiscData%TESF) ENDIF @@ -5882,15 +5993,27 @@ SUBROUTINE UA_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) ENDIF END SUBROUTINE UA_CopyParam - SUBROUTINE UA_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE UA_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(UA_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%c)) THEN DEALLOCATE(ParamData%c) ENDIF @@ -6194,15 +6317,27 @@ SUBROUTINE UA_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) DstInputData%omega = SrcInputData%omega END SUBROUTINE UA_CopyInput - SUBROUTINE UA_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE UA_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(UA_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE UA_DestroyInput SUBROUTINE UA_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -6368,15 +6503,27 @@ SUBROUTINE UA_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs ENDIF END SUBROUTINE UA_CopyOutput - SUBROUTINE UA_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE UA_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(UA_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'UA_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF diff --git a/modules/aerodyn14/CMakeLists.txt b/modules/aerodyn14/CMakeLists.txt index 58741a928..5c67692e2 100644 --- a/modules/aerodyn14/CMakeLists.txt +++ b/modules/aerodyn14/CMakeLists.txt @@ -19,7 +19,7 @@ if (GENERATE_TYPES) generate_f90_types(src/Registry-DWM.txt ${CMAKE_CURRENT_LIST_DIR}/src/DWM_Types.f90) endif() -set(AD14_LIBS_SOURCES +add_library(aerodyn14lib src/AeroDyn14.f90 src/AeroSubs.f90 src/DWM.f90 @@ -28,26 +28,20 @@ set(AD14_LIBS_SOURCES src/AeroDyn14_Types.f90 src/DWM_Types.f90 ) - -add_library(aerodyn14lib ${AD14_LIBS_SOURCES}) target_link_libraries(aerodyn14lib ifwlib nwtclibs) +# set(DWM_SOURCES +# src/DWM_driver_wind_farm_mod.f90 +# src/DWM_driver_wind_farm_sub.f90 +# src/DWM_driver_wind_farm.f90 +# ) + +# add_executable(dwm_driver_wind_farm ${DWM_SOURCES}) +# target_link_libraries(dwm_driver_wind_farm aerodyn14lib versioninfolib) + install(TARGETS aerodyn14lib EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) - -set(DWM_SOURCES - src/DWM_driver_wind_farm_mod.f90 - src/DWM_driver_wind_farm_sub.f90 - src/DWM_driver_wind_farm.f90 + ARCHIVE DESTINATION lib ) - -add_executable(dwm_driver_wind_farm ${DWM_SOURCES}) -target_link_libraries(dwm_driver_wind_farm aerodyn14lib versioninfolib) - -install(TARGETS dwm_driver_wind_farm - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) diff --git a/modules/aerodyn14/src/AeroDyn14.f90 b/modules/aerodyn14/src/AeroDyn14.f90 index 93ec5ebbb..52eb44358 100644 --- a/modules/aerodyn14/src/AeroDyn14.f90 +++ b/modules/aerodyn14/src/AeroDyn14.f90 @@ -121,6 +121,15 @@ SUBROUTINE AD14_Init( InitInp, u, p, x, xd, z, O, y, m, Interval, InitOut, ErrSt p%DtAero = Interval ! set the default DT here; may be overwritten later, when we read the input file in AD14_GetInput() p%UseDWM = InitInp%UseDWM + ! 2022.09.06 -- ADP + ! Recent changes to how the disk average velocity is calculated in InflowWind will likely cause seg-faults in DWM. Therefore + ! changes will need to be made to DWM for this to work properly. Since AD14 and DWM will be removed in the very near future, + ! it is not a good use of time to fix this. Instead I'll leave this comment here for anyone who really wants to use DWM. + if (p%UseDWM) then + call SetErrStat(ErrID_Fatal, ' DWM is no longer supported and will be deprecated in the near future. We recommend using FAST.Farm instead.', ErrStat,ErrMess,RoutineName ) + return + endif + ! Define parameters here: p%WrOptFile = InitInp%WrSumFile diff --git a/modules/aerodyn14/src/AeroDyn14_Types.f90 b/modules/aerodyn14/src/AeroDyn14_Types.f90 index 242472313..51041bf08 100644 --- a/modules/aerodyn14/src/AeroDyn14_Types.f90 +++ b/modules/aerodyn14/src/AeroDyn14_Types.f90 @@ -493,15 +493,27 @@ SUBROUTINE AD14_CopyMarker( SrcMarkerData, DstMarkerData, CtrlCode, ErrStat, Err DstMarkerData%RotationVel = SrcMarkerData%RotationVel END SUBROUTINE AD14_CopyMarker - SUBROUTINE AD14_DestroyMarker( MarkerData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyMarker( MarkerData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Marker), INTENT(INOUT) :: MarkerData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyMarker' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyMarker' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AD14_DestroyMarker SUBROUTINE AD14_PackMarker( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -704,28 +716,48 @@ SUBROUTINE AD14_CopyAeroConfig( SrcAeroConfigData, DstAeroConfigData, CtrlCode, DstAeroConfigData%BladeLength = SrcAeroConfigData%BladeLength END SUBROUTINE AD14_CopyAeroConfig - SUBROUTINE AD14_DestroyAeroConfig( AeroConfigData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyAeroConfig( AeroConfigData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AeroConfig), INTENT(INOUT) :: AeroConfigData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyAeroConfig' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyAeroConfig' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(AeroConfigData%Blade)) THEN DO i1 = LBOUND(AeroConfigData%Blade,1), UBOUND(AeroConfigData%Blade,1) - CALL AD14_Destroymarker( AeroConfigData%Blade(i1), ErrStat, ErrMsg ) + CALL AD14_Destroymarker( AeroConfigData%Blade(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(AeroConfigData%Blade) ENDIF - CALL AD14_Destroymarker( AeroConfigData%Hub, ErrStat, ErrMsg ) - CALL AD14_Destroymarker( AeroConfigData%RotorFurl, ErrStat, ErrMsg ) - CALL AD14_Destroymarker( AeroConfigData%Nacelle, ErrStat, ErrMsg ) - CALL AD14_Destroymarker( AeroConfigData%TailFin, ErrStat, ErrMsg ) - CALL AD14_Destroymarker( AeroConfigData%Tower, ErrStat, ErrMsg ) - CALL AD14_Destroymarker( AeroConfigData%SubStructure, ErrStat, ErrMsg ) - CALL AD14_Destroymarker( AeroConfigData%Foundation, ErrStat, ErrMsg ) + CALL AD14_Destroymarker( AeroConfigData%Hub, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroymarker( AeroConfigData%RotorFurl, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroymarker( AeroConfigData%Nacelle, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroymarker( AeroConfigData%TailFin, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroymarker( AeroConfigData%Tower, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroymarker( AeroConfigData%SubStructure, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroymarker( AeroConfigData%Foundation, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD14_DestroyAeroConfig SUBROUTINE AD14_PackAeroConfig( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1625,15 +1657,27 @@ SUBROUTINE AD14_CopyAirFoil( SrcAirFoilData, DstAirFoilData, CtrlCode, ErrStat, DstAirFoilData%MulTabLoc = SrcAirFoilData%MulTabLoc END SUBROUTINE AD14_CopyAirFoil - SUBROUTINE AD14_DestroyAirFoil( AirFoilData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyAirFoil( AirFoilData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AirFoil), INTENT(INOUT) :: AirFoilData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyAirFoil' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyAirFoil' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(AirFoilData%AL)) THEN DEALLOCATE(AirFoilData%AL) ENDIF @@ -2058,15 +2102,27 @@ SUBROUTINE AD14_CopyAirFoilParms( SrcAirFoilParmsData, DstAirFoilParmsData, Ctrl ENDIF END SUBROUTINE AD14_CopyAirFoilParms - SUBROUTINE AD14_DestroyAirFoilParms( AirFoilParmsData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyAirFoilParms( AirFoilParmsData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AirFoilParms), INTENT(INOUT) :: AirFoilParmsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyAirFoilParms' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyAirFoilParms' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(AirFoilParmsData%NTables)) THEN DEALLOCATE(AirFoilParmsData%NTables) ENDIF @@ -3161,15 +3217,27 @@ SUBROUTINE AD14_CopyBeddoes( SrcBeddoesData, DstBeddoesData, CtrlCode, ErrStat, DstBeddoesData%VOR = SrcBeddoesData%VOR END SUBROUTINE AD14_CopyBeddoes - SUBROUTINE AD14_DestroyBeddoes( BeddoesData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyBeddoes( BeddoesData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Beddoes), INTENT(INOUT) :: BeddoesData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyBeddoes' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyBeddoes' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(BeddoesData%ADOT)) THEN DEALLOCATE(BeddoesData%ADOT) ENDIF @@ -6025,15 +6093,27 @@ SUBROUTINE AD14_CopyBeddoesParms( SrcBeddoesParmsData, DstBeddoesParmsData, Ctrl DstBeddoesParmsData%TVL = SrcBeddoesParmsData%TVL END SUBROUTINE AD14_CopyBeddoesParms - SUBROUTINE AD14_DestroyBeddoesParms( BeddoesParmsData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyBeddoesParms( BeddoesParmsData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BeddoesParms), INTENT(INOUT) :: BeddoesParmsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyBeddoesParms' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyBeddoesParms' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AD14_DestroyBeddoesParms SUBROUTINE AD14_PackBeddoesParms( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -6196,15 +6276,27 @@ SUBROUTINE AD14_CopyBladeParms( SrcBladeParmsData, DstBladeParmsData, CtrlCode, DstBladeParmsData%BladeLength = SrcBladeParmsData%BladeLength END SUBROUTINE AD14_CopyBladeParms - SUBROUTINE AD14_DestroyBladeParms( BladeParmsData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyBladeParms( BladeParmsData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BladeParms), INTENT(INOUT) :: BladeParmsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyBladeParms' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyBladeParms' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(BladeParmsData%C)) THEN DEALLOCATE(BladeParmsData%C) ENDIF @@ -6467,15 +6559,27 @@ SUBROUTINE AD14_CopyDynInflow( SrcDynInflowData, DstDynInflowData, CtrlCode, Err DstDynInflowData%GAMMA = SrcDynInflowData%GAMMA END SUBROUTINE AD14_CopyDynInflow - SUBROUTINE AD14_DestroyDynInflow( DynInflowData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyDynInflow( DynInflowData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DynInflow), INTENT(INOUT) :: DynInflowData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyDynInflow' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyDynInflow' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(DynInflowData%RMC_SAVE)) THEN DEALLOCATE(DynInflowData%RMC_SAVE) ENDIF @@ -6966,15 +7070,27 @@ SUBROUTINE AD14_CopyDynInflowParms( SrcDynInflowParmsData, DstDynInflowParmsData DstDynInflowParmsData%xMinv = SrcDynInflowParmsData%xMinv END SUBROUTINE AD14_CopyDynInflowParms - SUBROUTINE AD14_DestroyDynInflowParms( DynInflowParmsData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyDynInflowParms( DynInflowParmsData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DynInflowParms), INTENT(INOUT) :: DynInflowParmsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyDynInflowParms' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyDynInflowParms' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AD14_DestroyDynInflowParms SUBROUTINE AD14_PackDynInflowParms( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -7202,15 +7318,27 @@ SUBROUTINE AD14_CopyElement( SrcElementData, DstElementData, CtrlCode, ErrStat, ENDIF END SUBROUTINE AD14_CopyElement - SUBROUTINE AD14_DestroyElement( ElementData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyElement( ElementData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Element), INTENT(INOUT) :: ElementData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyElement' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyElement' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ElementData%A)) THEN DEALLOCATE(ElementData%A) ENDIF @@ -7730,15 +7858,27 @@ SUBROUTINE AD14_CopyElementParms( SrcElementParmsData, DstElementParmsData, Ctrl ENDIF END SUBROUTINE AD14_CopyElementParms - SUBROUTINE AD14_DestroyElementParms( ElementParmsData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyElementParms( ElementParmsData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ElementParms), INTENT(INOUT) :: ElementParmsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyElementParms' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyElementParms' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ElementParmsData%TWIST)) THEN DEALLOCATE(ElementParmsData%TWIST) ENDIF @@ -8296,15 +8436,27 @@ SUBROUTINE AD14_CopyElOutParms( SrcElOutParmsData, DstElOutParmsData, CtrlCode, DstElOutParmsData%NumElOut = SrcElOutParmsData%NumElOut END SUBROUTINE AD14_CopyElOutParms - SUBROUTINE AD14_DestroyElOutParms( ElOutParmsData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyElOutParms( ElOutParmsData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ElOutParms), INTENT(INOUT) :: ElOutParmsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyElOutParms' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyElOutParms' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ElOutParmsData%AAA)) THEN DEALLOCATE(ElOutParmsData%AAA) ENDIF @@ -9375,15 +9527,27 @@ SUBROUTINE AD14_CopyInducedVel( SrcInducedVelData, DstInducedVelData, CtrlCode, DstInducedVelData%SumInFl = SrcInducedVelData%SumInFl END SUBROUTINE AD14_CopyInducedVel - SUBROUTINE AD14_DestroyInducedVel( InducedVelData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyInducedVel( InducedVelData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(InducedVel), INTENT(INOUT) :: InducedVelData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyInducedVel' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyInducedVel' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AD14_DestroyInducedVel SUBROUTINE AD14_PackInducedVel( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -9506,15 +9670,27 @@ SUBROUTINE AD14_CopyInducedVelParms( SrcInducedVelParmsData, DstInducedVelParmsD DstInducedVelParmsData%HLoss = SrcInducedVelParmsData%HLoss END SUBROUTINE AD14_CopyInducedVelParms - SUBROUTINE AD14_DestroyInducedVelParms( InducedVelParmsData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyInducedVelParms( InducedVelParmsData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(InducedVelParms), INTENT(INOUT) :: InducedVelParmsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyInducedVelParms' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyInducedVelParms' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AD14_DestroyInducedVelParms SUBROUTINE AD14_PackInducedVelParms( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -9669,15 +9845,27 @@ SUBROUTINE AD14_CopyRotor( SrcRotorData, DstRotorData, CtrlCode, ErrStat, ErrMsg DstRotorData%YawVEL = SrcRotorData%YawVEL END SUBROUTINE AD14_CopyRotor - SUBROUTINE AD14_DestroyRotor( RotorData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyRotor( RotorData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Rotor), INTENT(INOUT) :: RotorData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyRotor' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyRotor' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AD14_DestroyRotor SUBROUTINE AD14_PackRotor( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -9834,15 +10022,27 @@ SUBROUTINE AD14_CopyRotorParms( SrcRotorParmsData, DstRotorParmsData, CtrlCode, DstRotorParmsData%HH = SrcRotorParmsData%HH END SUBROUTINE AD14_CopyRotorParms - SUBROUTINE AD14_DestroyRotorParms( RotorParmsData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyRotorParms( RotorParmsData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(RotorParms), INTENT(INOUT) :: RotorParmsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyRotorParms' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyRotorParms' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AD14_DestroyRotorParms SUBROUTINE AD14_PackRotorParms( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -10050,15 +10250,27 @@ SUBROUTINE AD14_CopyTwrPropsParms( SrcTwrPropsParmsData, DstTwrPropsParmsData, C ENDIF END SUBROUTINE AD14_CopyTwrPropsParms - SUBROUTINE AD14_DestroyTwrPropsParms( TwrPropsParmsData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyTwrPropsParms( TwrPropsParmsData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(TwrPropsParms), INTENT(INOUT) :: TwrPropsParmsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyTwrPropsParms' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyTwrPropsParms' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(TwrPropsParmsData%TwrHtFr)) THEN DEALLOCATE(TwrPropsParmsData%TwrHtFr) ENDIF @@ -10523,15 +10735,27 @@ SUBROUTINE AD14_CopyWind( SrcWindData, DstWindData, CtrlCode, ErrStat, ErrMsg ) DstWindData%SDEL = SrcWindData%SDEL END SUBROUTINE AD14_CopyWind - SUBROUTINE AD14_DestroyWind( WindData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyWind( WindData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Wind), INTENT(INOUT) :: WindData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyWind' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyWind' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AD14_DestroyWind SUBROUTINE AD14_PackWind( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -10674,15 +10898,27 @@ SUBROUTINE AD14_CopyWindParms( SrcWindParmsData, DstWindParmsData, CtrlCode, Err DstWindParmsData%KinVisc = SrcWindParmsData%KinVisc END SUBROUTINE AD14_CopyWindParms - SUBROUTINE AD14_DestroyWindParms( WindParmsData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyWindParms( WindParmsData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WindParms), INTENT(INOUT) :: WindParmsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyWindParms' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyWindParms' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AD14_DestroyWindParms SUBROUTINE AD14_PackWindParms( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -10805,15 +11041,27 @@ SUBROUTINE AD14_CopyPositionType( SrcPositionTypeData, DstPositionTypeData, Ctrl DstPositionTypeData%Pos = SrcPositionTypeData%Pos END SUBROUTINE AD14_CopyPositionType - SUBROUTINE AD14_DestroyPositionType( PositionTypeData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyPositionType( PositionTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(PositionType), INTENT(INOUT) :: PositionTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyPositionType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyPositionType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AD14_DestroyPositionType SUBROUTINE AD14_PackPositionType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -10939,15 +11187,27 @@ SUBROUTINE AD14_CopyOrientationType( SrcOrientationTypeData, DstOrientationTypeD DstOrientationTypeData%Orient = SrcOrientationTypeData%Orient END SUBROUTINE AD14_CopyOrientationType - SUBROUTINE AD14_DestroyOrientationType( OrientationTypeData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyOrientationType( OrientationTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(OrientationType), INTENT(INOUT) :: OrientationTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyOrientationType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyOrientationType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE AD14_DestroyOrientationType SUBROUTINE AD14_PackOrientationType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -11109,20 +11369,34 @@ SUBROUTINE AD14_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Err IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AD14_CopyInitInput - SUBROUTINE AD14_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD14_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" - CALL AD14_Destroyaeroconfig( InitInputData%TurbineComponents, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AD14_Destroyaeroconfig( InitInputData%TurbineComponents, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitInputData%TwrNodeLocs)) THEN DEALLOCATE(InitInputData%TwrNodeLocs) ENDIF - CALL DWM_DestroyInitInput( InitInputData%DWM, ErrStat, ErrMsg ) + CALL DWM_DestroyInitInput( InitInputData%DWM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD14_DestroyInitInput SUBROUTINE AD14_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -11523,17 +11797,31 @@ SUBROUTINE AD14_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, DstInitOutputData%AirDens = SrcInitOutputData%AirDens END SUBROUTINE AD14_CopyInitOutput - SUBROUTINE AD14_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD14_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) - CALL DWM_DestroyInitOutput( InitOutputData%DWM, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_DestroyInitOutput( InitOutputData%DWM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD14_DestroyInitOutput SUBROUTINE AD14_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -11823,16 +12111,29 @@ SUBROUTINE AD14_CopyContState( SrcContStateData, DstContStateData, CtrlCode, Err IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AD14_CopyContState - SUBROUTINE AD14_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD14_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" - CALL DWM_DestroyContState( ContStateData%DWM, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL DWM_DestroyContState( ContStateData%DWM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD14_DestroyContState SUBROUTINE AD14_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -12032,16 +12333,29 @@ SUBROUTINE AD14_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, Err IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AD14_CopyDiscState - SUBROUTINE AD14_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD14_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" - CALL DWM_DestroyDiscState( DiscStateData%DWM, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL DWM_DestroyDiscState( DiscStateData%DWM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD14_DestroyDiscState SUBROUTINE AD14_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -12241,16 +12555,29 @@ SUBROUTINE AD14_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCod IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AD14_CopyConstrState - SUBROUTINE AD14_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD14_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" - CALL DWM_DestroyConstrState( ConstrStateData%DWM, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL DWM_DestroyConstrState( ConstrStateData%DWM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD14_DestroyConstrState SUBROUTINE AD14_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -12450,16 +12777,29 @@ SUBROUTINE AD14_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AD14_CopyOtherState - SUBROUTINE AD14_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD14_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" - CALL DWM_DestroyOtherState( OtherStateData%DWM, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL DWM_DestroyOtherState( OtherStateData%DWM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD14_DestroyOtherState SUBROUTINE AD14_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -12752,29 +13092,52 @@ SUBROUTINE AD14_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) ENDIF END SUBROUTINE AD14_CopyMisc - SUBROUTINE AD14_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD14_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" - CALL DWM_DestroyMisc( MiscData%DWM, ErrStat, ErrMsg ) - CALL DWM_DestroyInput( MiscData%DWM_Inputs, ErrStat, ErrMsg ) - CALL DWM_DestroyOutput( MiscData%DWM_Outputs, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL DWM_DestroyMisc( MiscData%DWM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_DestroyInput( MiscData%DWM_Inputs, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_DestroyOutput( MiscData%DWM_Outputs, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MiscData%ElPrNum)) THEN DEALLOCATE(MiscData%ElPrNum) ENDIF - CALL AD14_Destroyairfoil( MiscData%AirFoil, ErrStat, ErrMsg ) - CALL AD14_Destroybeddoes( MiscData%Beddoes, ErrStat, ErrMsg ) - CALL AD14_Destroydyninflow( MiscData%DynInflow, ErrStat, ErrMsg ) - CALL AD14_Destroyelement( MiscData%Element, ErrStat, ErrMsg ) - CALL AD14_Destroyrotor( MiscData%Rotor, ErrStat, ErrMsg ) - CALL AD14_Destroywind( MiscData%Wind, ErrStat, ErrMsg ) - CALL AD14_Destroyinducedvel( MiscData%InducedVel, ErrStat, ErrMsg ) - CALL AD14_Destroyeloutparms( MiscData%ElOut, ErrStat, ErrMsg ) + CALL AD14_Destroyairfoil( MiscData%AirFoil, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroybeddoes( MiscData%Beddoes, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroydyninflow( MiscData%DynInflow, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroyelement( MiscData%Element, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroyrotor( MiscData%Rotor, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroywind( MiscData%Wind, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroyinducedvel( MiscData%InducedVel, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroyeloutparms( MiscData%ElOut, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MiscData%StoredForces)) THEN DEALLOCATE(MiscData%StoredForces) ENDIF @@ -14119,25 +14482,47 @@ SUBROUTINE AD14_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AD14_CopyParam - SUBROUTINE AD14_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD14_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" - CALL AD14_Destroyairfoilparms( ParamData%AirFoil, ErrStat, ErrMsg ) - CALL AD14_Destroybladeparms( ParamData%Blade, ErrStat, ErrMsg ) - CALL AD14_Destroybeddoesparms( ParamData%Beddoes, ErrStat, ErrMsg ) - CALL AD14_Destroydyninflowparms( ParamData%DynInflow, ErrStat, ErrMsg ) - CALL AD14_Destroyelementparms( ParamData%Element, ErrStat, ErrMsg ) - CALL AD14_Destroytwrpropsparms( ParamData%TwrProps, ErrStat, ErrMsg ) - CALL AD14_Destroyinducedvelparms( ParamData%InducedVel, ErrStat, ErrMsg ) - CALL AD14_Destroywindparms( ParamData%Wind, ErrStat, ErrMsg ) - CALL AD14_Destroyrotorparms( ParamData%Rotor, ErrStat, ErrMsg ) - CALL DWM_DestroyParam( ParamData%DWM, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AD14_Destroyairfoilparms( ParamData%AirFoil, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroybladeparms( ParamData%Blade, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroybeddoesparms( ParamData%Beddoes, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroydyninflowparms( ParamData%DynInflow, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroyelementparms( ParamData%Element, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroytwrpropsparms( ParamData%TwrProps, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroyinducedvelparms( ParamData%InducedVel, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroywindparms( ParamData%Wind, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroyrotorparms( ParamData%Rotor, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_DestroyParam( ParamData%DWM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD14_DestroyParam SUBROUTINE AD14_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -15281,23 +15666,38 @@ SUBROUTINE AD14_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg DstInputData%AvgInfVel = SrcInputData%AvgInfVel END SUBROUTINE AD14_CopyInput - SUBROUTINE AD14_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD14_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%InputMarkers)) THEN DO i1 = LBOUND(InputData%InputMarkers,1), UBOUND(InputData%InputMarkers,1) - CALL MeshDestroy( InputData%InputMarkers(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%InputMarkers(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InputData%InputMarkers) ENDIF - CALL MeshDestroy( InputData%Twr_InputMarkers, ErrStat, ErrMsg ) - CALL AD14_Destroyaeroconfig( InputData%TurbineComponents, ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%Twr_InputMarkers, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_Destroyaeroconfig( InputData%TurbineComponents, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InputData%MulTabLoc)) THEN DEALLOCATE(InputData%MulTabLoc) ENDIF @@ -15834,22 +16234,36 @@ SUBROUTINE AD14_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Err IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AD14_CopyOutput - SUBROUTINE AD14_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE AD14_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AD14_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AD14_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%OutputLoads)) THEN DO i1 = LBOUND(OutputData%OutputLoads,1), UBOUND(OutputData%OutputLoads,1) - CALL MeshDestroy( OutputData%OutputLoads(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%OutputLoads(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OutputData%OutputLoads) ENDIF - CALL MeshDestroy( OutputData%Twr_OutputLoads, ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%Twr_OutputLoads, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AD14_DestroyOutput SUBROUTINE AD14_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) diff --git a/modules/aerodyn14/src/AeroSubs.f90 b/modules/aerodyn14/src/AeroSubs.f90 index 3ca457193..d47f5137c 100644 --- a/modules/aerodyn14/src/AeroSubs.f90 +++ b/modules/aerodyn14/src/AeroSubs.f90 @@ -1264,13 +1264,13 @@ SUBROUTINE READFL(InitInp, P, x, xd, z, m, y, ErrStat, ErrMess ) IF ( p%PMOMENT ) THEN - READ( NUNIT,*,END=150 ) m%AirFoil%AL(NFOILID,I), & + READ( NUNIT,*,END=150,ERR=150 ) m%AirFoil%AL(NFOILID,I), & (m%AirFoil%CL(NFOILID,I,IPHI), m%AirFoil%CD(NFOILID,I,IPHI), & m%AirFoil%CM(NFOILID,I,IPHI), IPHI = 1, p%AirFoil%NTables(NFOILID)) ELSE - READ( NUNIT,*,END=150 ) m%AirFoil%AL(NFOILID,I), & + READ( NUNIT,*,END=150,ERR=150 ) m%AirFoil%AL(NFOILID,I), & (m%AirFoil%CL(NFOILID,I,IPHI), m%AirFoil%CD(NFOILID,I,IPHI), & IPHI = 1, p%AirFoil%NTables(NFOILID)) diff --git a/modules/aerodyn14/src/DWM_Types.f90 b/modules/aerodyn14/src/DWM_Types.f90 index a79aae342..9e6784c86 100644 --- a/modules/aerodyn14/src/DWM_Types.f90 +++ b/modules/aerodyn14/src/DWM_Types.f90 @@ -349,15 +349,27 @@ SUBROUTINE DWM_CopyCVSD( SrcCVSDData, DstCVSDData, CtrlCode, ErrStat, ErrMsg ) DstCVSDData%Numerator = SrcCVSDData%Numerator END SUBROUTINE DWM_CopyCVSD - SUBROUTINE DWM_DestroyCVSD( CVSDData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyCVSD( CVSDData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(CVSD), INTENT(INOUT) :: CVSDData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyCVSD' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyCVSD' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE DWM_DestroyCVSD SUBROUTINE DWM_PackCVSD( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -539,15 +551,27 @@ SUBROUTINE DWM_Copyturbine_average_velocity_data( Srcturbine_average_velocity_da Dstturbine_average_velocity_dataData%time_step_force = Srcturbine_average_velocity_dataData%time_step_force END SUBROUTINE DWM_Copyturbine_average_velocity_data - SUBROUTINE DWM_Destroyturbine_average_velocity_data( turbine_average_velocity_dataData, ErrStat, ErrMsg ) + SUBROUTINE DWM_Destroyturbine_average_velocity_data( turbine_average_velocity_dataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(turbine_average_velocity_data), INTENT(INOUT) :: turbine_average_velocity_dataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_Destroyturbine_average_velocity_data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_Destroyturbine_average_velocity_data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(turbine_average_velocity_dataData%average_velocity_array_temp)) THEN DEALLOCATE(turbine_average_velocity_dataData%average_velocity_array_temp) ENDIF @@ -859,15 +883,27 @@ SUBROUTINE DWM_CopyWake_Deficit_Data( SrcWake_Deficit_DataData, DstWake_Deficit_ DstWake_Deficit_DataData%ppR = SrcWake_Deficit_DataData%ppR END SUBROUTINE DWM_CopyWake_Deficit_Data - SUBROUTINE DWM_DestroyWake_Deficit_Data( Wake_Deficit_DataData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyWake_Deficit_Data( Wake_Deficit_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DWM_Wake_Deficit_Data), INTENT(INOUT) :: Wake_Deficit_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyWake_Deficit_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyWake_Deficit_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(Wake_Deficit_DataData%Turb_Stress_DWM)) THEN DEALLOCATE(Wake_Deficit_DataData%Turb_Stress_DWM) ENDIF @@ -1058,15 +1094,27 @@ SUBROUTINE DWM_CopyMeanderData( SrcMeanderDataData, DstMeanderDataData, CtrlCode DstMeanderDataData%moving_time = SrcMeanderDataData%moving_time END SUBROUTINE DWM_CopyMeanderData - SUBROUTINE DWM_DestroyMeanderData( MeanderDataData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyMeanderData( MeanderDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MeanderData), INTENT(INOUT) :: MeanderDataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyMeanderData' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyMeanderData' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE DWM_DestroyMeanderData SUBROUTINE DWM_PackMeanderData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1389,15 +1437,27 @@ SUBROUTINE DWM_Copyread_turbine_position_data( Srcread_turbine_position_dataData ENDIF END SUBROUTINE DWM_Copyread_turbine_position_data - SUBROUTINE DWM_Destroyread_turbine_position_data( read_turbine_position_dataData, ErrStat, ErrMsg ) + SUBROUTINE DWM_Destroyread_turbine_position_data( read_turbine_position_dataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(read_turbine_position_data), INTENT(INOUT) :: read_turbine_position_dataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_Destroyread_turbine_position_data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_Destroyread_turbine_position_data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(read_turbine_position_dataData%Turbine_sort_order)) THEN DEALLOCATE(read_turbine_position_dataData%Turbine_sort_order) ENDIF @@ -2220,15 +2280,27 @@ SUBROUTINE DWM_CopyWeiMethod( SrcWeiMethodData, DstWeiMethodData, CtrlCode, ErrS DstWeiMethodData%weighting_denominator = SrcWeiMethodData%weighting_denominator END SUBROUTINE DWM_CopyWeiMethod - SUBROUTINE DWM_DestroyWeiMethod( WeiMethodData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyWeiMethod( WeiMethodData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WeiMethod), INTENT(INOUT) :: WeiMethodData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyWeiMethod' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyWeiMethod' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(WeiMethodData%sweptarea)) THEN DEALLOCATE(WeiMethodData%sweptarea) ENDIF @@ -2431,15 +2503,27 @@ SUBROUTINE DWM_CopyTIDownstream( SrcTIDownstreamData, DstTIDownstreamData, CtrlC DstTIDownstreamData%temp3 = SrcTIDownstreamData%temp3 END SUBROUTINE DWM_CopyTIDownstream - SUBROUTINE DWM_DestroyTIDownstream( TIDownstreamData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyTIDownstream( TIDownstreamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(TIDownstream), INTENT(INOUT) :: TIDownstreamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyTIDownstream' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyTIDownstream' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(TIDownstreamData%TI_downstream_matrix)) THEN DEALLOCATE(TIDownstreamData%TI_downstream_matrix) ENDIF @@ -2755,15 +2839,27 @@ SUBROUTINE DWM_CopyTurbKaimal( SrcTurbKaimalData, DstTurbKaimalData, CtrlCode, E DstTurbKaimalData%STD = SrcTurbKaimalData%STD END SUBROUTINE DWM_CopyTurbKaimal - SUBROUTINE DWM_DestroyTurbKaimal( TurbKaimalData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyTurbKaimal( TurbKaimalData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(TurbKaimal), INTENT(INOUT) :: TurbKaimalData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyTurbKaimal' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyTurbKaimal' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE DWM_DestroyTurbKaimal SUBROUTINE DWM_PackTurbKaimal( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2978,15 +3074,27 @@ SUBROUTINE DWM_CopyShinozuka( SrcShinozukaData, DstShinozukaData, CtrlCode, ErrS DstShinozukaData%df = SrcShinozukaData%df END SUBROUTINE DWM_CopyShinozuka - SUBROUTINE DWM_DestroyShinozuka( ShinozukaData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyShinozuka( ShinozukaData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Shinozuka), INTENT(INOUT) :: ShinozukaData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyShinozuka' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyShinozuka' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ShinozukaData%f_syn)) THEN DEALLOCATE(ShinozukaData%f_syn) ENDIF @@ -3344,15 +3452,27 @@ SUBROUTINE DWM_Copysmooth_out_wake_data( Srcsmooth_out_wake_dataData, Dstsmooth_ Dstsmooth_out_wake_dataData%length_velocity_array = Srcsmooth_out_wake_dataData%length_velocity_array END SUBROUTINE DWM_Copysmooth_out_wake_data - SUBROUTINE DWM_Destroysmooth_out_wake_data( smooth_out_wake_dataData, ErrStat, ErrMsg ) + SUBROUTINE DWM_Destroysmooth_out_wake_data( smooth_out_wake_dataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(smooth_out_wake_data), INTENT(INOUT) :: smooth_out_wake_dataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_Destroysmooth_out_wake_data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_Destroysmooth_out_wake_data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE DWM_Destroysmooth_out_wake_data SUBROUTINE DWM_Packsmooth_out_wake_data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -3474,15 +3594,27 @@ SUBROUTINE DWM_CopySWSV( SrcSWSVData, DstSWSVData, CtrlCode, ErrStat, ErrMsg ) DstSWSVData%unit = SrcSWSVData%unit END SUBROUTINE DWM_CopySWSV - SUBROUTINE DWM_DestroySWSV( SWSVData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroySWSV( SWSVData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SWSV), INTENT(INOUT) :: SWSVData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroySWSV' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroySWSV' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE DWM_DestroySWSV SUBROUTINE DWM_PackSWSV( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -3775,15 +3907,27 @@ SUBROUTINE DWM_Copyread_upwind_result( Srcread_upwind_resultData, Dstread_upwind ENDIF END SUBROUTINE DWM_Copyread_upwind_result - SUBROUTINE DWM_Destroyread_upwind_result( read_upwind_resultData, ErrStat, ErrMsg ) + SUBROUTINE DWM_Destroyread_upwind_result( read_upwind_resultData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(read_upwind_result), INTENT(INOUT) :: read_upwind_resultData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_Destroyread_upwind_result' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_Destroyread_upwind_result' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(read_upwind_resultData%upwind_U)) THEN DEALLOCATE(read_upwind_resultData%upwind_U) ENDIF @@ -4442,15 +4586,27 @@ SUBROUTINE DWM_Copywake_meandered_center( Srcwake_meandered_centerData, Dstwake_ ENDIF END SUBROUTINE DWM_Copywake_meandered_center - SUBROUTINE DWM_Destroywake_meandered_center( wake_meandered_centerData, ErrStat, ErrMsg ) + SUBROUTINE DWM_Destroywake_meandered_center( wake_meandered_centerData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(wake_meandered_center), INTENT(INOUT) :: wake_meandered_centerData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_Destroywake_meandered_center' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_Destroywake_meandered_center' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(wake_meandered_centerData%wake_width)) THEN DEALLOCATE(wake_meandered_centerData%wake_width) ENDIF @@ -4606,15 +4762,27 @@ SUBROUTINE DWM_Copyturbine_blade( Srcturbine_bladeData, Dstturbine_bladeData, Ct Dstturbine_bladeData%Element_index = Srcturbine_bladeData%Element_index END SUBROUTINE DWM_Copyturbine_blade - SUBROUTINE DWM_Destroyturbine_blade( turbine_bladeData, ErrStat, ErrMsg ) + SUBROUTINE DWM_Destroyturbine_blade( turbine_bladeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DWM_turbine_blade), INTENT(INOUT) :: turbine_bladeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_Destroyturbine_blade' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_Destroyturbine_blade' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE DWM_Destroyturbine_blade SUBROUTINE DWM_Packturbine_blade( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -4822,15 +4990,27 @@ SUBROUTINE DWM_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE DWM_CopyParam - SUBROUTINE DWM_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DWM_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%velocityU)) THEN DEALLOCATE(ParamData%velocityU) ENDIF @@ -4843,8 +5023,10 @@ SUBROUTINE DWM_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%ElementRad)) THEN DEALLOCATE(ParamData%ElementRad) ENDIF - CALL DWM_Destroyread_turbine_position_data( ParamData%RTPD, ErrStat, ErrMsg ) - CALL InflowWind_DestroyParam( ParamData%IfW, ErrStat, ErrMsg ) + CALL DWM_Destroyread_turbine_position_data( ParamData%RTPD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyParam( ParamData%IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE DWM_DestroyParam SUBROUTINE DWM_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -5409,16 +5591,29 @@ SUBROUTINE DWM_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE DWM_CopyOtherState - SUBROUTINE DWM_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DWM_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" - CALL InflowWind_DestroyOtherState( OtherStateData%IfW, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL InflowWind_DestroyOtherState( OtherStateData%IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE DWM_DestroyOtherState SUBROUTINE DWM_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -5693,34 +5888,59 @@ SUBROUTINE DWM_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE DWM_CopyMisc - SUBROUTINE DWM_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DWM_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" - CALL InflowWind_DestroyMisc( MiscData%IfW, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL InflowWind_DestroyMisc( MiscData%IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MiscData%Nforce)) THEN DEALLOCATE(MiscData%Nforce) ENDIF IF (ALLOCATED(MiscData%blade_dr)) THEN DEALLOCATE(MiscData%blade_dr) ENDIF - CALL DWM_Destroyturbine_average_velocity_data( MiscData%TAVD, ErrStat, ErrMsg ) - CALL DWM_Destroycvsd( MiscData%CalVelScale_data, ErrStat, ErrMsg ) - CALL DWM_Destroymeanderdata( MiscData%meandering_data, ErrStat, ErrMsg ) - CALL DWM_Destroyweimethod( MiscData%weighting_method, ErrStat, ErrMsg ) - CALL DWM_Destroytidownstream( MiscData%TI_downstream_data, ErrStat, ErrMsg ) - CALL DWM_Destroyturbkaimal( MiscData%Turbulence_KS, ErrStat, ErrMsg ) - CALL DWM_Destroyshinozuka( MiscData%shinozuka_data, ErrStat, ErrMsg ) - CALL DWM_Destroysmooth_out_wake_data( MiscData%SmoothOut, ErrStat, ErrMsg ) - CALL DWM_Destroyswsv( MiscData%smooth_wake_shifted_velocity_data, ErrStat, ErrMsg ) - CALL DWM_Destroywake_deficit_data( MiscData%DWDD, ErrStat, ErrMsg ) - CALL DWM_Destroyturbine_blade( MiscData%DWM_tb, ErrStat, ErrMsg ) - CALL DWM_Destroywake_meandered_center( MiscData%WMC, ErrStat, ErrMsg ) + CALL DWM_Destroyturbine_average_velocity_data( MiscData%TAVD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_Destroycvsd( MiscData%CalVelScale_data, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_Destroymeanderdata( MiscData%meandering_data, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_Destroyweimethod( MiscData%weighting_method, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_Destroytidownstream( MiscData%TI_downstream_data, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_Destroyturbkaimal( MiscData%Turbulence_KS, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_Destroyshinozuka( MiscData%shinozuka_data, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_Destroysmooth_out_wake_data( MiscData%SmoothOut, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_Destroyswsv( MiscData%smooth_wake_shifted_velocity_data, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_Destroywake_deficit_data( MiscData%DWDD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_Destroyturbine_blade( MiscData%DWM_tb, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL DWM_Destroywake_meandered_center( MiscData%WMC, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE DWM_DestroyMisc SUBROUTINE DWM_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -7086,17 +7306,31 @@ SUBROUTINE DWM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE DWM_CopyInput - SUBROUTINE DWM_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DWM_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" - CALL DWM_Destroyread_upwind_result( InputData%Upwind_result, ErrStat, ErrMsg ) - CALL InflowWind_DestroyInput( InputData%IfW, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL DWM_Destroyread_upwind_result( InputData%Upwind_result, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyInput( InputData%IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE DWM_DestroyInput SUBROUTINE DWM_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -7496,15 +7730,27 @@ SUBROUTINE DWM_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrM IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE DWM_CopyOutput - SUBROUTINE DWM_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DWM_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%turbine_thrust_force)) THEN DEALLOCATE(OutputData%turbine_thrust_force) ENDIF @@ -7529,7 +7775,8 @@ SUBROUTINE DWM_DestroyOutput( OutputData, ErrStat, ErrMsg ) IF (ALLOCATED(OutputData%smoothed_velocity_array)) THEN DEALLOCATE(OutputData%smoothed_velocity_array) ENDIF - CALL InflowWind_DestroyOutput( OutputData%IfW, ErrStat, ErrMsg ) + CALL InflowWind_DestroyOutput( OutputData%IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE DWM_DestroyOutput SUBROUTINE DWM_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -8117,16 +8364,29 @@ SUBROUTINE DWM_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrS IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE DWM_CopyContState - SUBROUTINE DWM_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DWM_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" - CALL InflowWind_DestroyContState( ContStateData%IfW, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL InflowWind_DestroyContState( ContStateData%IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE DWM_DestroyContState SUBROUTINE DWM_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -8332,16 +8592,29 @@ SUBROUTINE DWM_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrS IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE DWM_CopyDiscState - SUBROUTINE DWM_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DWM_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" - CALL InflowWind_DestroyDiscState( DiscStateData%IfW, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL InflowWind_DestroyDiscState( DiscStateData%IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE DWM_DestroyDiscState SUBROUTINE DWM_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -8547,16 +8820,29 @@ SUBROUTINE DWM_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE DWM_CopyConstrState - SUBROUTINE DWM_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DWM_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" - CALL InflowWind_DestroyConstrState( ConstrStateData%IfW, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL InflowWind_DestroyConstrState( ConstrStateData%IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE DWM_DestroyConstrState SUBROUTINE DWM_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -8762,16 +9048,29 @@ SUBROUTINE DWM_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrS IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE DWM_CopyInitInput - SUBROUTINE DWM_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DWM_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" - CALL InflowWind_DestroyInitInput( InitInputData%IfW, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL InflowWind_DestroyInitInput( InitInputData%IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE DWM_DestroyInitInput SUBROUTINE DWM_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -8977,16 +9276,29 @@ SUBROUTINE DWM_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, E IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE DWM_CopyInitOutput - SUBROUTINE DWM_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE DWM_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(DWM_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'DWM_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL InflowWind_DestroyInitOutput( InitOutputData%IfW, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL InflowWind_DestroyInitOutput( InitOutputData%IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE DWM_DestroyInitOutput SUBROUTINE DWM_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) diff --git a/modules/awae/CMakeLists.txt b/modules/awae/CMakeLists.txt index 941c0c97d..ee236b36b 100644 --- a/modules/awae/CMakeLists.txt +++ b/modules/awae/CMakeLists.txt @@ -17,13 +17,11 @@ if (GENERATE_TYPES) generate_f90_types(src/AWAE_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/AWAE_Types.f90 -noextrap) endif() -set(AWAE_LIBS_SOURCES +add_library(awaelib src/AWAE.f90 src/AWAE_IO.f90 src/AWAE_Types.f90 - ) - -add_library(awaelib ${AWAE_LIBS_SOURCES}) +) target_link_libraries(awaelib ifwlib nwtclibs) install(TARGETS awaelib diff --git a/modules/awae/src/AWAE.f90 b/modules/awae/src/AWAE.f90 index d6137766f..b640d5039 100644 --- a/modules/awae/src/AWAE.f90 +++ b/modules/awae/src/AWAE.f90 @@ -53,6 +53,7 @@ module AWAE public :: AWAE_TEST_Init_BadData public :: AWAE_TEST_Init_GoodData public :: AWAE_TEST_CalcOutput + public :: AWAE_TEST_Interp2D contains @@ -123,7 +124,7 @@ subroutine ComputeLocals(n, u, p, y, m, errStat, errMsg) errStat = 0 errMsg = "" maxPln = min(n,p%NumPlanes-2) - rmax = p%r(p%NumRadii-1) + rmax = p%y(p%NumRadii-1) do nt = 1,p%NumTurbines do np = 0, maxPln cosTerm = dot_product(u%xhat_plane(:,np+1,nt),u%xhat_plane(:,np,nt)) @@ -169,8 +170,9 @@ real(ReKi) function jinc ( x ) end function jinc !---------------------------------------------------------------------------------------------------------------------------------- -!> This subroutine -!! +!> Loop over the entire grid of low resolution ambient wind data to compute: +!! 1) the disturbed flow at each point and 2) the averaged disturbed velocity of each wake plane +!! TODO explain algorithm subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) integer(IntKi), intent(in ) :: n !< Current simulation time increment (zero-based) type(AWAE_InputType), intent(in ) :: u !< Inputs at Time t @@ -184,11 +186,13 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) integer(IntKi) :: nx, ny, nz, nt, np, nw, nx_low, ny_low, nz_low, nr, npsi, wamb, iwsum !< loop counters integer(IntKi) :: nXYZ_low, n_wake, n_r_polar, n_psi_polar !< accumulating counters real(ReKi) :: xhatBar_plane(3) !< + real(ReKi) :: xHat_plane(3), yHat_plane(3), zHat_plane(3) real(ReKi) :: x_end_plane real(ReKi) :: x_start_plane real(ReKi) :: r_vec_plane(3) - real(ReKi) :: tmp_xhatBar_plane - real(ReKi) :: r_tmp_plane + real(ReKi) :: xhatBar_plane_norm + real(ReKi) :: y_tmp_plane + real(ReKi) :: z_tmp_plane real(ReKi) :: Vx_wake_tmp real(ReKi) :: Vr_wake_tmp(3) real(ReKi) :: Vr_term(3) @@ -202,22 +206,26 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) real(ReKi) :: tmp_x,tmp_y,tmp_z !, tm1, tm2 real(ReKi) :: xxplane(3), xyplane(3), yyplane(3), yxplane(3), psi_polar, r_polar, p_polar(3) real(ReKi) :: yzplane_Y(3), xyplane_norm - real(ReKi) :: xplane_sq, yplane_sq, xysq_Z(3), xzplane_X(3), tmp_yhat_plane(3), tmp_zhat_plane(3) - real(ReKi), ALLOCATABLE :: tmp_rhat_plane(:,:), tmp_xhat_plane(:,:) - real(ReKi), ALLOCATABLE :: tmp_Vx_wake(:), tmp_Vr_wake(:) - integer(IntKi) :: ILo - integer(IntKi) :: maxPln, tmpPln, maxN_wake - integer(IntKi) :: i,np1,errStat2 + real(ReKi) :: xplane_sq, yplane_sq, xysq_Z(3), xzplane_X(3) + integer(IntKi) :: tmpPln + real(ReKi), ALLOCATABLE :: tmp_xhat_plane(:,:), tmp_yhat_plane(:,:), tmp_zhat_plane(:,:) + real(ReKi), ALLOCATABLE :: tmp_Vx_wake(:), tmp_Vz_wake(:), tmp_Vy_wake(:) + integer(IntKi) :: np1 + integer(IntKi) :: i !< Flat counter on X,Y,Z low res grid + integer(IntKi) :: maxN_wake + integer(IntKi) :: maxPln + integer(IntKi) :: errStat2 character(*), parameter :: RoutineName = 'LowResGridCalcOutput' logical :: within + real(SiKi), dimension(3,3) :: C_rot + real(SiKi) :: C_rot_norm errStat = ErrID_None errMsg = "" maxPln = min(n,p%NumPlanes-2) tmpPln = min(p%NumPlanes-1, n+1) - - + !#ifdef _OPENMP ! tm1 = omp_get_wtime() @@ -225,33 +233,39 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) maxN_wake = p%NumTurbines*( p%NumPlanes-1 ) ! Temporary variables needed by OpenMP - allocate ( tmp_xhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_xhat_plane.', errStat, errMsg, RoutineName ) - allocate ( tmp_rhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_rhat_plane.', errStat, errMsg, RoutineName ) - allocate ( tmp_Vx_wake ( 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_Vx_wake.', errStat, errMsg, RoutineName ) - allocate ( tmp_Vr_wake ( 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_Vr_wake.', errStat, errMsg, RoutineName ) + allocate ( tmp_xhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_xhat_plane.', errStat, errMsg, RoutineName ) + allocate ( tmp_yhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_yhat_plane.', errStat, errMsg, RoutineName ) + allocate ( tmp_zhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_zhat_plane.', errStat, errMsg, RoutineName ) + allocate ( tmp_Vx_wake ( 1:maxN_wake ) , STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_Vx_wake.', errStat, errMsg, RoutineName ) + allocate ( tmp_Vy_wake ( 1:maxN_wake ) , STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_Vy_wake.', errStat, errMsg, RoutineName ) + allocate ( tmp_Vz_wake ( 1:maxN_wake ) , STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_Vz_wake.', errStat, errMsg, RoutineName ) if (ErrStat >= AbortErrLev) return ! Loop over the entire grid of low resolution ambient wind data to compute: ! 1) the disturbed flow at each point and 2) the averaged disturbed velocity of each wake plane - - !$OMP PARALLEL DO PRIVATE(nx_low,ny_low,nz_low, nXYZ_low, n_wake, xhatBar_plane, x_end_plane,nt,np,ILo,x_start_plane,delta,deltad,p_tmp_plane,tmp_vec,r_vec_plane,r_tmp_plane,tmp_xhatBar_plane, Vx_wake_tmp,Vr_wake_tmp,nw,Vr_term,Vx_term,tmp_x,tmp_y,tmp_z,tmp_xhat_plane,tmp_rhat_plane,tmp_Vx_wake,tmp_Vr_wake,i,np1,errStat2) SHARED(m,u,p,maxPln,errStat,errMsg) DEFAULT(NONE) - !do nz_low=0, p%nZ_low-1 - ! do ny_low=0, p%yZ_low-1 - ! do nx_low=0, p%nX_low-1 - ! nXYZ_low=0 + !$OMP PARALLEL DO & + !$OMP PRIVATE(i, nx_low, ny_low, nz_low, & + !$OMP& nXYZ_low, n_wake, xhatBar_plane, & + !$OMP& tmp_x,tmp_y,tmp_z,& + !$OMP& x_end_plane, nt, np, np1, & + !$OMP& x_start_plane, delta, deltad, p_tmp_plane, tmp_vec, r_vec_plane, & + !$OMP& xHat_plane, yHat_plane, zHat_plane, & + !$OMP& y_tmp_plane, z_tmp_plane, & + !$OMP& tmp_xhat_plane, tmp_yhat_plane, tmp_zhat_plane,& + !$OMP& tmp_Vx_wake, tmp_Vy_wake, tmp_Vz_wake, & + !$OMP& xhatBar_plane_norm, Vx_wake_tmp, Vr_wake_tmp, nw, Vr_term, Vx_term, & + !$OMP& C_rot, C_rot_norm) & + !$OMP SHARED(m, u, p, maxPln, errStat, errMsg) DEFAULT(NONE) do i = 0 , p%NumGrid_low - 1 - + ! From flat index iXYZ to grid indices nx, ny, nz nx_low = mod( i ,p%nX_low) ny_low = mod(int( i / (p%nX_low ) ),p%nY_low) nz_low = int( i / (p%nX_low*p%nY_low) ) ! set the disturbed flow equal to the ambient flow for this time step - m%Vdist_low(:,nx_low,ny_low,nz_low) = m%Vamb_low(:,nx_low,ny_low,nz_low) + m%Vdist_low (:,nx_low,ny_low,nz_low) = m%Vamb_low(:,nx_low,ny_low,nz_low) + m%Vdist_low_full(:,nx_low,ny_low,nz_low) = m%Vamb_low(:,nx_low,ny_low,nz_low) !nXYZ_low = nXYZ_low + 1 nXYZ_low = i + 1 @@ -268,90 +282,134 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) x_end_plane = tmp_x + tmp_y + tmp_z do np = 0, maxPln - ! Reset interpolation counter - ILo = 0 np1 = np + 1 - ! Construct the endcaps of the current wake plane volume + ! Construct the endcaps of the current wake plane volume x_start_plane = x_end_plane ! H Long: again, replace intrinsic dot_product !x_end_plane = dot_product(u%xhat_plane(:,np+1,nt), (p%Grid_Low(:,nXYZ_low) - u%p_plane(:,np+1,nt)) ) tmp_x = u%xhat_plane(1,np1,nt) * (p%Grid_Low(1,nXYZ_low) - u%p_plane(1,np1,nt)) tmp_y = u%xhat_plane(2,np1,nt) * (p%Grid_Low(2,nXYZ_low) - u%p_plane(2,np1,nt)) tmp_z = u%xhat_plane(3,np1,nt) * (p%Grid_Low(3,nXYZ_low) - u%p_plane(3,np1,nt)) - - x_end_plane = tmp_x + tmp_y + tmp_z - ! test if the point is within the endcaps of the wake volume - + ! test if the point is within the endcaps of the wake volume if ( ( ( x_start_plane >= 0.0_ReKi ) .and. ( x_end_plane < 0.0_ReKi ) ) .or. & ( ( x_start_plane <= 0.0_ReKi ) .and. ( x_end_plane > 0.0_ReKi ) ) ) then + ! Plane interpolation factor if ( EqualRealNos( x_start_plane, x_end_plane ) ) then delta = 0.5_ReKi else delta = x_start_plane / ( x_start_plane - x_end_plane ) end if deltad = (1.0_ReKi - delta) + + ! Interpolated plane position if ( m%parallelFlag(np,nt) ) then p_tmp_plane = delta*u%p_plane(:,np1,nt) + deltad*u%p_plane(:,np,nt) else - tmp_vec = delta*m%rhat_e(:,np,nt) + deltad*m%rhat_s(:,np,nt) + tmp_vec = delta*m%rhat_e(:,np,nt) + deltad*m%rhat_s(:,np,nt) p_tmp_plane = delta*m%pvec_ce(:,np,nt) + deltad*m%pvec_cs(:,np,nt) + ( delta*m%r_e(np,nt) + deltad*m%r_s(np,nt) )* tmp_vec / TwoNorm(tmp_vec) end if - - + ! Vector between current grid point and plane position r_vec_plane = p%Grid_Low(:,nXYZ_low) - p_tmp_plane - r_tmp_plane = TwoNorm( r_vec_plane ) - - ! test if the point is within radial finite-difference grid - if ( r_tmp_plane <= p%r(p%numRadii-1) ) then + ! Interpolate x_hat, plane normal at grid point + xHat_plane(1:3) = delta*u%xhat_plane(:,np1,nt) + deltad*u%xhat_plane(:,np,nt) + xHat_plane(1:3) = xHat_plane(:) / TwoNorm(xHat_plane(:)) + ! Construct y_hat, orthogonal to x_hat when its z component is neglected (in a projected horizontal plane) + yHat_plane(1:3) = (/ -xHat_plane(2), xHat_plane(1), 0.0_ReKi /) + yHat_plane(1:3) = yHat_plane / TwoNorm(yHat_plane) + ! Construct z_hat + zHat_plane(1) = -xHat_plane(1)*xHat_plane(3) + zHat_plane(2) = -xHat_plane(2)*xHat_plane(3) + zHat_plane(3) = xHat_plane(1)*xHat_plane(1) + xHat_plane(2)*xHat_plane(2) + zHat_plane(1:3) = zHat_plane / TwoNorm(zHat_plane) + + ! Point positions in plane, y = yhat . (p-p_plane), z = zhat . (p-p_plane) + y_tmp_plane = yHat_plane(1)*r_vec_plane(1) + yHat_plane(2)*r_vec_plane(2) + yHat_plane(3)*r_vec_plane(3) + z_tmp_plane = zHat_plane(1)*r_vec_plane(1) + zHat_plane(2)*r_vec_plane(2) + zHat_plane(3)*r_vec_plane(3) + + ! test if the point is within finite-difference grid + if ( (abs(y_tmp_plane) <= p%y(p%numRadii-1)).and.(abs(z_tmp_plane) <= p%z(p%numRadii-1)) ) then + ! Increment number of wakes contributing to current grid point n_wake = n_wake + 1 - - if ( EqualRealNos(r_tmp_plane, 0.0_ReKi) ) then - tmp_rhat_plane(:,n_wake) = 0.0_ReKi - else - tmp_rhat_plane(:,n_wake) = ( r_vec_plane ) / r_tmp_plane - end if - - - ! given r_tmp_plane and Vx_wake at p%dr increments, find value of m%Vx_wake(@r_tmp_plane) using interpolation - tmp_Vx_wake(n_wake) = delta*InterpBin( r_tmp_plane, p%r, u%Vx_wake(:,np1,nt), ILo, p%NumRadii ) + deltad*InterpBin( r_tmp_plane, p%r, u%Vx_wake(:,np,nt), ILo, p%NumRadii ) !( XVal, XAry, YAry, ILo, AryLen ) - tmp_Vr_wake(n_wake) = delta*InterpBin( r_tmp_plane, p%r, u%Vr_wake(:,np1,nt), ILo, p%NumRadii ) + deltad*InterpBin( r_tmp_plane, p%r, u%Vr_wake(:,np,nt), ILo, p%NumRadii ) !( XVal, XAry, YAry, ILo, AryLen ) - - - tmp_xhat_plane(:,n_wake) = delta*u%xhat_plane(:,np1,nt) + deltad*u%xhat_plane(:,np,nt) - tmp_xhat_plane(:,n_wake) = tmp_xhat_plane(:,n_wake) / TwoNorm(tmp_xhat_plane(:,n_wake)) + ! Store unit vectors for projection + tmp_xhat_plane(:,n_wake) = xHat_plane + tmp_yhat_plane(:,n_wake) = yHat_plane + tmp_zhat_plane(:,n_wake) = zHat_plane + + ! Velocity at point (y,z) by 2d interpolation in plane, and interpolations between planes (delta) + tmp_Vx_wake(n_wake) = delta *interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vx_wake(:,:,np1,nt)) & + + deltad*interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vx_wake(:,:,np, nt)) + tmp_Vy_wake(n_wake) = delta *interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vy_wake(:,:,np1,nt)) & + + deltad*interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vy_wake(:,:,np, nt)) + tmp_Vz_wake(n_wake) = delta *interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vz_wake(:,:,np1,nt)) & + + deltad*interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vz_wake(:,:,np, nt)) + ! Average xhat over overlapping wakes xhatBar_plane = xhatBar_plane + abs(tmp_Vx_wake(n_wake))*tmp_xhat_plane(:,n_wake) + end if ! if the point is within radial finite-difference grid end if end do ! do np = 0, p%NumPlanes-2 end do ! do nt = 1,p%NumTurbines if (n_wake > 0) then - tmp_xhatBar_plane = TwoNorm(xhatBar_plane) - if ( EqualRealNos(tmp_xhatBar_plane, 0.0_ReKi) ) then + ! Normalize xhatBar to unit vector + xhatBar_plane_norm = TwoNorm(xhatBar_plane) + if ( EqualRealNos(xhatBar_plane_norm, 0.0_ReKi) ) then xhatBar_plane = 0.0_ReKi else - xhatBar_plane = xhatBar_plane / tmp_xhatBar_plane + xhatBar_plane = xhatBar_plane / xhatBar_plane_norm end if - + ! Compute average contributions + ! - sqrt[ sum (e_x. V)^2 ] e_x ! Axial (sqrt-avg) + ! + sum [(I-e_x.e_x^T). V ] ! Radial (sum) Vx_wake_tmp = 0.0_ReKi Vr_wake_tmp = 0.0_ReKi do nw = 1,n_wake - Vr_term = tmp_Vx_wake(nw)*tmp_xhat_plane(:,nw) + tmp_Vr_wake(nw)*tmp_rhat_plane(:,nw) + Vr_term = tmp_Vx_wake(nw)*tmp_xhat_plane(:,nw) + tmp_Vy_wake(nw)*tmp_yhat_plane(:,nw) + tmp_Vz_wake(nw)*tmp_zhat_plane(:,nw) Vx_term = dot_product( xhatBar_plane, Vr_term ) Vx_wake_tmp = Vx_wake_tmp + Vx_term*Vx_term Vr_wake_tmp = Vr_wake_tmp + Vr_term end do - ! [I - XX']V = V - (V dot X)X + ! [I - XX']V = V - (V dot X)X Vr_wake_tmp = Vr_wake_tmp - dot_product(Vr_wake_tmp,xhatBar_plane)*xhatBar_plane - m%Vdist_low(:,nx_low,ny_low,nz_low) = m%Vdist_low(:,nx_low,ny_low,nz_low) + real(Vr_wake_tmp - xhatBar_plane*sqrt(Vx_wake_tmp),SiKi) + ! Compute C matrix and update Vdist_low + if(p%Mod_Projection==1) then + ! We keep the full field (including cross flow components), done for outputs and VTK outputs + m%Vdist_low (:,nx_low,ny_low,nz_low) = m%Vdist_low (:,nx_low,ny_low,nz_low) + real(Vr_wake_tmp - xhatBar_plane*sqrt(Vx_wake_tmp),SiKi) + m%Vdist_low_full(:,nx_low,ny_low,nz_low) = m%Vdist_low_full(:,nx_low,ny_low,nz_low) + real(Vr_wake_tmp - xhatBar_plane*sqrt(Vx_wake_tmp),SiKi) + + else if (p%Mod_Projection==2) then + ! We project against the normal of the plane to remove the cross flow components + C_rot(1,1) = m%Vamb_low(1,nx_low,ny_low,nz_low) * m%Vamb_low(1,nx_low,ny_low,nz_low) + C_rot(1,2) = m%Vamb_low(1,nx_low,ny_low,nz_low) * m%Vamb_low(2,nx_low,ny_low,nz_low) + C_rot(1,3) = m%Vamb_low(1,nx_low,ny_low,nz_low) * m%Vamb_low(3,nx_low,ny_low,nz_low) + + C_rot(2,1) = m%Vamb_low(2,nx_low,ny_low,nz_low) * m%Vamb_low(1,nx_low,ny_low,nz_low) + C_rot(2,2) = m%Vamb_low(2,nx_low,ny_low,nz_low) * m%Vamb_low(2,nx_low,ny_low,nz_low) + C_rot(2,3) = m%Vamb_low(2,nx_low,ny_low,nz_low) * m%Vamb_low(3,nx_low,ny_low,nz_low) + + C_rot(3,1) = m%Vamb_low(3,nx_low,ny_low,nz_low) * m%Vamb_low(1,nx_low,ny_low,nz_low) + C_rot(3,2) = m%Vamb_low(3,nx_low,ny_low,nz_low) * m%Vamb_low(2,nx_low,ny_low,nz_low) + C_rot(3,3) = m%Vamb_low(3,nx_low,ny_low,nz_low) * m%Vamb_low(3,nx_low,ny_low,nz_low) + + C_rot_norm = C_rot(1,1) + C_rot(2,2) + C_rot(3,3) + if (EqualRealNos( C_rot_norm, 0.0_SiKi) ) then + ! do nothing + else + C_rot = C_rot / C_rot_norm + ! Full field is for VTK outputs, contains the cross flow components + m%Vdist_low (:,nx_low,ny_low,nz_low) = m%Vdist_low (:,nx_low,ny_low,nz_low) + matmul(C_rot, real(Vr_wake_tmp - xhatBar_plane*sqrt(Vx_wake_tmp),SiKi)) + m%Vdist_low_full(:,nx_low,ny_low,nz_low) = m%Vdist_low_full(:,nx_low,ny_low,nz_low) + real(Vr_wake_tmp - xhatBar_plane*sqrt(Vx_wake_tmp),SiKi) + endif + endif + end if ! (n_wake > 0) - end do + end do ! i, loop NumGrid_low points ! end do ! do nx_low=0, p%nX_low-1 ! end do ! do ny_low=0, p%nY_low-1 !end do ! do nz_low=0, p%nZ_low-1 @@ -391,8 +449,8 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) xysq_Z = (/0.0_ReKi, 0.0_ReKi, xplane_sq+yplane_sq/) xzplane_X = (/u%xhat_plane(1,np,nt)*u%xhat_plane(3,np,nt), 0.0_ReKi, 0.0_ReKi/) yzplane_Y = (/0.0_ReKi, u%xhat_plane(2,np,nt)*u%xhat_plane(3,np,nt), 0.0_ReKi/) - tmp_yhat_plane = (xyplane-yxplane)/xyplane_norm - tmp_zhat_plane = (xysq_Z-xzplane_X-yzplane_Y)/xyplane_norm + yHat_plane = (xyplane-yxplane)/xyplane_norm + zHat_plane = (xysq_Z-xzplane_X-yzplane_Y)/xyplane_norm ! Calculate y%Vx_wind_disk and y%TI_amb at the rotor disk @@ -411,7 +469,7 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) do npsi = 0,n_psi_polar psi_polar = (TwoPi*REAL(npsi,ReKi))/(REAL(n_psi_polar+1,ReKi)) - p_polar = u%p_plane(:,np,nt) + r_polar*COS(psi_polar)*tmp_yhat_plane + r_polar*SIN(psi_polar)*tmp_zhat_plane + p_polar = u%p_plane(:,np,nt) + r_polar*COS(psi_polar)*yHat_plane + r_polar*SIN(psi_polar)*zHat_plane Vamb_lowpol_tmp = INTERP3D( p_polar, p%Grid_Low(:,1), p%dXYZ_Low, m%Vamb_low, within, p%nX_low, p%nY_low, p%nZ_low, Vbox=Vamb_low_tmp ) if ( within ) then Vsum_low = Vsum_low + Vamb_lowpol_tmp @@ -475,7 +533,7 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) do npsi = 0,n_psi_polar psi_polar = (TwoPi*REAL(npsi,ReKi))/(REAL(n_psi_polar+1,ReKi)) - p_polar = u%p_plane(:,np,nt) + r_polar*COS(psi_polar)*tmp_yhat_plane + r_polar*SIN(psi_polar)*tmp_zhat_plane + p_polar = u%p_plane(:,np,nt) + r_polar*COS(psi_polar)*yHat_plane + r_polar*SIN(psi_polar)*zHat_plane Vdist_lowpol_tmp = INTERP3D( p_polar, p%Grid_Low(:,1), p%dXYZ_Low, m%Vdist_low, within, p%nX_low, p%nY_low, p%nZ_low ) if ( within ) then y%V_plane(:,np,nt) = y%V_plane(:,np,nt) + w*Vdist_lowpol_tmp @@ -494,8 +552,8 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) end if - end do - end do + end do ! np, tmpPln + end do ! nt, turbines !#ifdef _OPENMP ! tm2 = omp_get_wtime() @@ -504,16 +562,19 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) !#endif if (allocated(tmp_xhat_plane)) deallocate(tmp_xhat_plane) - if (allocated(tmp_rhat_plane)) deallocate(tmp_rhat_plane) - if (allocated(tmp_Vx_wake)) deallocate(tmp_Vx_wake) - if (allocated(tmp_Vr_wake)) deallocate(tmp_Vr_wake) + if (allocated(tmp_yhat_plane)) deallocate(tmp_yhat_plane) + if (allocated(tmp_zhat_plane)) deallocate(tmp_zhat_plane) + if (allocated(tmp_Vx_wake)) deallocate(tmp_Vx_wake) + if (allocated(tmp_Vy_wake)) deallocate(tmp_Vy_wake) + if (allocated(tmp_Vz_wake)) deallocate(tmp_Vz_wake) end subroutine LowResGridCalcOutput !---------------------------------------------------------------------------------------------------------------------------------- -!> This subroutine -!! +!> Loop over each point of the high resolution ambient wind to compute: +!! 1) the disturbed flow at each point and 2) the averaged disturbed velocity of each wake plane +!! TODO explain algorithm subroutine HighResGridCalcOutput(n, u, p, y, m, errStat, errMsg) integer(IntKi), intent(in ) :: n !< Current high-res, simulation time increment (zero-based) type(AWAE_InputType), intent(in ) :: u !< Inputs at Time t @@ -527,11 +588,13 @@ subroutine HighResGridCalcOutput(n, u, p, y, m, errStat, errMsg) integer(IntKi) :: nx, ny, nz, nt, nt2, np, nw, nx_high, ny_high, nz_high, n_hl !< loop counters integer(IntKi) :: nXYZ_high, n_wake !< accumulating counters real(ReKi) :: xhatBar_plane(3) !< - real(ReKi) :: tmp_xhatBar_plane + real(ReKi) :: xHat_plane(3), yHat_plane(3), zHat_plane(3) + real(ReKi) :: xhatBar_plane_norm real(ReKi) :: x_end_plane real(ReKi) :: x_start_plane real(ReKi) :: r_vec_plane(3) - real(ReKi) :: r_tmp_plane + real(ReKi) :: y_tmp_plane + real(ReKi) :: z_tmp_plane real(ReKi) :: Vx_wake_tmp real(ReKi) :: Vr_wake_tmp(3) real(ReKi) :: Vr_term(3) @@ -540,14 +603,19 @@ subroutine HighResGridCalcOutput(n, u, p, y, m, errStat, errMsg) real(ReKi) :: p_tmp_plane(3) real(ReKi) :: tmp_vec(3) real(ReKi) :: delta, deltad - integer(IntKi) :: ILo + real(ReKi), ALLOCATABLE :: tmp_xhat_plane(:,:), tmp_yhat_plane(:,:), tmp_zhat_plane(:,:) + real(ReKi), ALLOCATABLE :: tmp_Vx_wake(:), tmp_Vz_wake(:), tmp_Vy_wake(:) + integer(IntKi) :: np1 + integer(IntKi) :: iXYZ !< Flat counter on X,Y,Z high res grid integer(IntKi) :: maxPln + integer(IntKi) :: maxN_wake + integer(IntKi) :: NumGrid_high !< number of points in high res grid grid integer(IntKi) :: n_high_low + integer(IntKi) :: errStat2 character(*), parameter :: RoutineName = 'HighResGridCalcOutput' errStat = ErrID_None errMsg = "" - maxPln = min(n,p%NumPlanes-2) ! We only need one high res file for that last simulation time @@ -558,21 +626,49 @@ subroutine HighResGridCalcOutput(n, u, p, y, m, errStat, errMsg) end if - ! Loop over the entire grid of low resolution ambient wind data to compute: + maxN_wake = p%NumTurbines*( p%NumPlanes-1 ) + ! Temporary variables needed by OpenMP + allocate ( tmp_xhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_xhat_plane.', errStat, errMsg, RoutineName ) + allocate ( tmp_yhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_yhat_plane.', errStat, errMsg, RoutineName ) + allocate ( tmp_zhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_zhat_plane.', errStat, errMsg, RoutineName ) + allocate ( tmp_Vx_wake ( 1:maxN_wake ) , STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_Vx_wake.', errStat, errMsg, RoutineName ) + allocate ( tmp_Vy_wake ( 1:maxN_wake ) , STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_Vy_wake.', errStat, errMsg, RoutineName ) + allocate ( tmp_Vz_wake ( 1:maxN_wake ) , STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_Vz_wake.', errStat, errMsg, RoutineName ) + if (ErrStat >= AbortErrLev) return + + ! Loop over the entire grid of high resolution ambient wind data to compute: ! 1) the disturbed flow at each point and 2) the averaged disturbed velocity of each wake plane + ! NOTE: loop here is different from low res grid, doing: turbines > grid > turbines(nt/=nt2) > planes + ! instead of grid > turbines > planes + ! TODO explain + NumGrid_high = p%nX_high*p%nY_high*p%nZ_high do nt = 1,p%NumTurbines - nXYZ_high = 0 ! set the disturbed flow equal to the ambient flow for this time step y%Vdist_high(nt)%data = m%Vamb_high(nt)%data - do nz_high=0, p%nZ_high-1 - do ny_high=0, p%nY_high-1 - do nx_high=0, p%nX_high-1 - - nXYZ_high = nXYZ_high + 1 + !$OMP PARALLEL DO DEFAULT(NONE) & + !$OMP PRIVATE (nx_high, ny_high, nz_high,& + !$OMP& nXYZ_high, n_wake, xhatBar_plane,& + !$OMP& nt2, x_end_plane, np, np1,& + !$OMP& x_start_plane, delta, deltad, p_tmp_plane, tmp_vec, r_vec_plane,& + !$OMP& xHat_plane, yHat_plane, zHat_plane,& + !$OMP& y_tmp_plane, z_tmp_plane,& + !$OMP& tmp_xhat_plane, tmp_yhat_plane, tmp_zhat_plane,& + !$OMP& tmp_Vx_wake, tmp_Vy_wake, tmp_Vz_wake,& + !$OMP& xhatBar_plane_norm, Vx_wake_tmp, Vr_wake_tmp, nw, Vr_term, Vx_term,& + !$OMP& n_hl)& + !$OMP SHARED(NumGrid_High, m, u, p, y, nt, maxPln, n_high_low, errStat, errMsg) + ! Loop over all points of the high resolution ambiend wind + do iXYZ=0, NumGrid_high-1 + ! From flat index iXYZ to grid indices nx, ny, nz + nx_high = mod( iXYZ ,p%nX_high) + ny_high = mod(int( iXYZ / (p%nX_high ) ),p%nY_high) + nz_high = int( iXYZ / (p%nX_high*p%nY_high) ) + + nXYZ_high = iXYZ + 1 n_wake = 0 xhatBar_plane = 0.0_ReKi @@ -582,55 +678,70 @@ subroutine HighResGridCalcOutput(n, u, p, y, m, errStat, errMsg) x_end_plane = dot_product(u%xhat_plane(:,0,nt2), (p%Grid_high(:,nXYZ_high,nt) - u%p_plane(:,0,nt2)) ) do np = 0, maxPln !p%NumPlanes-2 - - ! Reset interpolation counter - ILo = 0 - - ! Construct the endcaps of the current wake plane volume + np1 = np + 1 + ! Construct the endcaps of the current wake plane volume x_start_plane = x_end_plane x_end_plane = dot_product(u%xhat_plane(:,np+1,nt2), (p%Grid_high(:,nXYZ_high,nt) - u%p_plane(:,np+1,nt2)) ) - ! test if the point is within the endcaps of the wake volume + ! test if the point is within the endcaps of the wake volume if ( ( ( x_start_plane >= 0.0_ReKi ) .and. ( x_end_plane < 0.0_ReKi ) ) .or. & ( ( x_start_plane <= 0.0_ReKi ) .and. ( x_end_plane > 0.0_ReKi ) ) ) then + ! Plane interpolation factor if ( EqualRealNos( x_start_plane, x_end_plane ) ) then delta = 0.5_ReKi else delta = x_start_plane / ( x_start_plane - x_end_plane ) end if deltad = (1.0_ReKi - delta) + + ! Interpolate x_hat, plane normal at grid point if ( m%parallelFlag(np,nt2) ) then p_tmp_plane = delta*u%p_plane(:,np+1,nt2) + deltad*u%p_plane(:,np,nt2) else - tmp_vec = delta*m%rhat_e(:,np,nt2) + deltad*m%rhat_s(:,np,nt2) + tmp_vec = delta*m%rhat_e(:,np,nt2) + deltad*m%rhat_s(:,np,nt2) p_tmp_plane = delta*m%pvec_ce(:,np,nt2) + deltad*m%pvec_cs(:,np,nt2) + ( delta*m%r_e(np,nt2) + deltad*m%r_s(np,nt2) )* tmp_vec / TwoNorm(tmp_vec) end if + ! Vector between current grid and plane position r_vec_plane = p%Grid_high(:,nXYZ_high,nt) - p_tmp_plane - r_tmp_plane = TwoNorm( r_vec_plane ) - - ! test if the point is within radial finite-difference grid - if ( r_tmp_plane <= p%r(p%numRadii-1) ) then + ! Interpolate x_hat + xHat_plane(1:3) = delta*u%xhat_plane(:,np1,nt2) + deltad*u%xhat_plane(:,np,nt2) + xHat_plane(1:3) = xHat_plane(:) / TwoNorm(xHat_plane(:)) + ! Construct y_hat, orthogonal to x_hat when its z component is neglected (in a projected horizontal plane) + yHat_plane(1:3) = (/ -xHat_plane(2), xHat_plane(1), 0.0_ReKi /) + yHat_plane(1:3) = yHat_plane / TwoNorm(yHat_plane) + ! Construct z_hat + zHat_plane(1) = -xHat_plane(1)*xHat_plane(3) + zHat_plane(2) = -xHat_plane(2)*xHat_plane(3) + zHat_plane(3) = xHat_plane(1)*xHat_plane(1) + xHat_plane(2)*xHat_plane(2) + zHat_plane(1:3) = zHat_plane / TwoNorm(zHat_plane) + + ! Point positions in plane, y = yhat . (p-p_plane), z = zhat . (p-p_plane) + y_tmp_plane = yHat_plane(1)*r_vec_plane(1) + yHat_plane(2)*r_vec_plane(2) + yHat_plane(3)*r_vec_plane(3) + z_tmp_plane = zHat_plane(1)*r_vec_plane(1) + zHat_plane(2)*r_vec_plane(2) + zHat_plane(3)*r_vec_plane(3) + + ! test if the point is within finite-difference grid + if ( (abs(y_tmp_plane) <= p%y(p%numRadii-1)).and.(abs(z_tmp_plane) <= p%z(p%numRadii-1)) ) then + ! Increment number of wakes contributing to current grid point n_wake = n_wake + 1 + ! Store unit vectors for projection + tmp_xhat_plane(:,n_wake) = xHat_plane + tmp_yhat_plane(:,n_wake) = yHat_plane + tmp_zhat_plane(:,n_wake) = zHat_plane - if ( EqualRealNos(r_tmp_plane, 0.0_ReKi) ) then - m%rhat_plane(:,n_wake) = 0.0_ReKi - else - m%rhat_plane(:,n_wake) = ( r_vec_plane ) / r_tmp_plane - end if - + ! Velocity at point (y,z) by 2d interpolation in plane, and interpolations between planes (delta) + tmp_Vx_wake(n_wake) = delta *interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vx_wake(:,:,np1,nt2)) & + + deltad*interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vx_wake(:,:,np, nt2)) + tmp_Vy_wake(n_wake) = delta *interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vy_wake(:,:,np1,nt2)) & + + deltad*interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vy_wake(:,:,np, nt2)) + tmp_Vz_wake(n_wake) = delta *interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vz_wake(:,:,np1,nt2)) & + + deltad*interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vz_wake(:,:,np, nt2)) - - ! given r_tmp_plane and Vx_wake at p%dr increments, find value of m%Vx_wake(@r_tmp_plane) using interpolation - m%Vx_wake(n_wake) = delta*InterpBin( r_tmp_plane, p%r, u%Vx_wake(:,np+1,nt2), ILo, p%NumRadii ) + deltad*InterpBin( r_tmp_plane, p%r, u%Vx_wake(:,np,nt2), ILo, p%NumRadii ) !( XVal, XAry, YAry, ILo, AryLen ) - m%Vr_wake(n_wake) = delta*InterpBin( r_tmp_plane, p%r, u%Vr_wake(:,np+1,nt2), ILo, p%NumRadii ) + deltad*InterpBin( r_tmp_plane, p%r, u%Vr_wake(:,np,nt2), ILo, p%NumRadii )!( XVal, XAry, YAry, ILo, AryLen ) - - m%xhat_plane(:,n_wake) = delta*u%xhat_plane(:,np+1,nt2) + deltad*u%xhat_plane(:,np,nt2) - m%xhat_plane(:,n_wake) = m%xhat_plane(:,n_wake) / TwoNorm(m%xhat_plane(:,n_wake)) - xhatBar_plane = xhatBar_plane + abs(m%Vx_wake(n_wake))*m%xhat_plane(:,n_wake) + ! Average xhat over overlapping wakes + xhatBar_plane = xhatBar_plane + abs(tmp_Vx_wake(n_wake))*tmp_xhat_plane(:,n_wake) end if ! if the point is within radial finite-difference grid @@ -639,35 +750,41 @@ subroutine HighResGridCalcOutput(n, u, p, y, m, errStat, errMsg) end if ! nt /= nt2 end do ! nt2 = 1,p%NumTurbines if (n_wake > 0) then - - tmp_xhatBar_plane = TwoNorm(xhatBar_plane) - if ( EqualRealNos(tmp_xhatBar_plane, 0.0_ReKi) ) then + ! Normalize xhatBar to unit vector + xhatBar_plane_norm = TwoNorm(xhatBar_plane) + if ( EqualRealNos(xhatBar_plane_norm, 0.0_ReKi) ) then xhatBar_plane = 0.0_ReKi else - xhatBar_plane = xhatBar_plane / tmp_xhatBar_plane + xhatBar_plane = xhatBar_plane / xhatBar_plane_norm end if + ! Compute average contributions + ! - sqrt[ sum (e_x. V)^2 ] e_x ! Axial (sqrt-avg) + ! + sum [(I-e_x.e_x^T). V ] ! Radial (sum) Vx_wake_tmp = 0.0_ReKi Vr_wake_tmp = 0.0_ReKi do nw = 1,n_wake - Vr_term = m%Vx_wake(nw)*m%xhat_plane(:,nw) + m%Vr_wake(nw)*m%rhat_plane(:,nw) + Vr_term = tmp_Vx_wake(nw)*tmp_xhat_plane(:,nw) + tmp_Vy_wake(nw)*tmp_yhat_plane(:,nw) + tmp_Vz_wake(nw)*tmp_zhat_plane(:,nw) Vx_term = dot_product( xhatBar_plane, Vr_term ) Vx_wake_tmp = Vx_wake_tmp + Vx_term*Vx_term Vr_wake_tmp = Vr_wake_tmp + Vr_term end do - ! [I - XX']V = V - (V dot X)X + ! [I - XX']V = V - (V dot X)X Vr_wake_tmp = Vr_wake_tmp - dot_product(Vr_wake_tmp,xhatBar_plane)*xhatBar_plane do n_hl=0, n_high_low y%Vdist_high(nt)%data(:,nx_high,ny_high,nz_high,n_hl) = y%Vdist_high(nt)%data(:,nx_high,ny_high,nz_high,n_hl) + real(Vr_wake_tmp - xhatBar_plane*sqrt(Vx_wake_tmp),SiKi) end do - end if ! (n_wake > 0) - - end do ! nx_high=0, p%nX_high-1 - end do ! ny_high=0, p%nY_high-1 - end do ! nz_high=0, p%nZ_high-1 + end do ! iXYZ=0,NumGrid_high-1 + !$OMP END PARALLEL DO end do ! nt = 1,p%NumTurbines + if (allocated(tmp_xhat_plane)) deallocate(tmp_xhat_plane) + if (allocated(tmp_yhat_plane)) deallocate(tmp_yhat_plane) + if (allocated(tmp_zhat_plane)) deallocate(tmp_zhat_plane) + if (allocated(tmp_Vx_wake)) deallocate(tmp_Vx_wake) + if (allocated(tmp_Vy_wake)) deallocate(tmp_Vy_wake) + if (allocated(tmp_Vz_wake)) deallocate(tmp_Vz_wake) end subroutine HighResGridCalcOutput @@ -699,7 +816,6 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO ! Local variables character(1024) :: rootDir, baseName, OutFileVTKDir ! Simulation root dir, basename for outputs integer(IntKi) :: i,j,nt ! loop counter - integer(IntKi) :: maxN_wake real(ReKi) :: gridLoc ! Location of requested output slice in grid coordinates [0,sz-1] integer(IntKi) :: errStat2 ! temporary error status of the operation character(ErrMsgLen) :: errMsg2 ! temporary error message @@ -753,6 +869,10 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO p%WrDisSkp1 = nint(InitInp%InputFileData%WrDisDT / p%dt_low) p%Mod_Meander = InitInp%InputFileData%Mod_Meander p%C_Meander = InitInp%InputFileData%C_Meander + p%Mod_Projection = InitInp%InputFileData%Mod_Projection + ! Wake Added Turbulence (WAT) Parameters + !p%WAT = InitInp%InputFileData%WAT + !p%WAT_Basename = InitInp%InputFileData%WAT_Basename select case ( p%Mod_Meander ) case (MeanderMod_Uniform) @@ -796,14 +916,15 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO end if - allocate( p%r(0:p%NumRadii-1),stat=errStat2) - if (errStat2 /= 0) then - call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for p%r.', errStat, errMsg, RoutineName ) - return - end if - - do i = 0,p%NumRadii-1 - p%r(i) = InitInp%InputFileData%dr*i + ! Plane grids + allocate( p%y(-p%Numradii+1:p%NumRadii-1), stat=errStat2); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for p%y.', errStat, errMsg, RoutineName ) + allocate( p%z(-p%Numradii+1:p%NumRadii-1), stat=errStat2); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for p%z.', errStat, errMsg, RoutineName ) + if ( ErrStat >= AbortErrLev ) then + return + end if + do i = -p%NumRadii+1,p%NumRadii-1 + p%y(i) = InitInp%InputFileData%dr*i + p%z(i) = InitInp%InputFileData%dr*i end do allocate( p%WT_Position(3,p%NumTurbines),stat=errStat2) @@ -874,6 +995,7 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO ! Initialize InflowWind IfW_InitInp%FixedWindFileRootName = .false. IfW_InitInp%NumWindPoints = p%NumGrid_low + IfW_InitInp%RadAvg = 0.25 * p%nZ_low * p%dX_low ! arbitrary garbage, just must be bigger than zero, but not bigger than grid (IfW will complain if this isn't set when it tries to calculate disk average vel) call InflowWind_Init( IfW_InitInp, m%u_IfW_Low, p%IfW(0), x%IfW(0), xd%IfW(0), z%IfW(0), OtherState%IfW(0), m%y_IfW_Low, m%IfW(0), Interval, IfW_InitOut, ErrStat2, ErrMsg2 ) call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) @@ -944,6 +1066,9 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO ! Set the position inputs once for the low-resolution grid m%u_IfW_Low%PositionXYZ = p%Grid_low + ! Set the hub position and orientation to pass to IfW (IfW always calculates hub and disk avg vel) + m%u_IfW_Low%HubPosition = (/ p%X0_low + 0.5*p%nX_low*p%dX_low, p%Y0_low + 0.5*p%nY_low*p%dY_low, p%Z0_low + 0.5*p%nZ_low*p%dZ_low /) + call Eye(m%u_IfW_Low%HubOrientation,ErrStat2,ErrMsg2) ! Initialize the high-resolution grid inputs and outputs IF ( .NOT. ALLOCATED( m%u_IfW_High%PositionXYZ ) ) THEN @@ -953,6 +1078,25 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) call AllocAry(m%y_IfW_High%WriteOutput, size(m%y_IfW_Low%WriteOutput), 'm%y_IfW_High%WriteOutput', ErrStat2, ErrMsg2) call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) + if (allocated(m%y_IfW_Low%lidar%LidSpeed)) then + call AllocAry(m%y_IfW_High%lidar%LidSpeed, size(m%y_IfW_Low%lidar%LidSpeed ), 'm%y_IfW_High%lidar%LidSpeed', ErrStat2, ErrMsg2) + call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) + endif + if (allocated(m%y_IfW_High%lidar%MsrPositionsX)) then + call AllocAry(m%y_IfW_High%lidar%MsrPositionsX, size(m%y_IfW_High%lidar%MsrPositionsX), 'm%y_IfW_High%lidar%MsrPositionsX', ErrStat2, ErrMsg2) + call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) + endif + if (allocated(m%y_IfW_High%lidar%MsrPositionsY)) then + call AllocAry(m%y_IfW_High%lidar%MsrPositionsY, size(m%y_IfW_High%lidar%MsrPositionsY), 'm%y_IfW_High%lidar%MsrPositionsY', ErrStat2, ErrMsg2) + call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) + endif + if (allocated(m%y_IfW_High%lidar%MsrPositionsZ)) then + call AllocAry(m%y_IfW_High%lidar%MsrPositionsZ, size(m%y_IfW_High%lidar%MsrPositionsZ), 'm%y_IfW_High%lidar%MsrPositionsZ', ErrStat2, ErrMsg2) + call SetErrStat ( errStat2, errMsg2, errStat, errMsg, RoutineName ) + endif + + + END IF if (errStat2 >= AbortErrLev) then return @@ -996,18 +1140,19 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO ! Define and initialize inputs here !............................................................................................ - allocate ( u%xhat_plane(3,0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%xhat_plane.', errStat, errMsg, RoutineName ) - allocate ( u%p_plane (3,0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%p_plane.', errStat, errMsg, RoutineName ) - allocate ( u%Vx_wake (0:p%NumRadii-1,0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%Vx_wake.', errStat, errMsg, RoutineName ) - allocate ( u%Vr_wake (0:p%NumRadii-1,0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%Vr_wake.', errStat, errMsg, RoutineName ) - allocate ( u%D_wake (0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%D_wake.', errStat, errMsg, RoutineName ) + allocate ( u%xhat_plane(3,0:p%NumPlanes-1,1:p%NumTurbines) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%xhat_plane.', errStat, errMsg, RoutineName ) + allocate ( u%p_plane (3,0:p%NumPlanes-1,1:p%NumTurbines) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%p_plane.', errStat, errMsg, RoutineName ) + allocate ( u%Vx_wake (-p%NumRadii+1:p%NumRadii-1, -p%NumRadii+1:p%NumRadii-1, 0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%Vx_wake.', errStat, errMsg, RoutineName ) + allocate ( u%Vy_wake (-p%NumRadii+1:p%NumRadii-1, -p%NumRadii+1:p%NumRadii-1, 0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%Vy_wake.', errStat, errMsg, RoutineName ) + allocate ( u%Vz_wake (-p%NumRadii+1:p%NumRadii-1, -p%NumRadii+1:p%NumRadii-1, 0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%Vz_wake.', errStat, errMsg, RoutineName ) + allocate ( u%D_wake (0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%D_wake.', errStat, errMsg, RoutineName ) + allocate ( u%WAT_k_mt (0:p%NumRadii-1, 0:p%NumPlanes-1, 1:p%NumTurbines), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%k_mt.', errStat, errMsg, RoutineName ) if (errStat >= AbortErrLev) return + u%Vx_wake=0.0_ReKi + u%Vy_wake=0.0_ReKi + u%Vz_wake=0.0_ReKi + @@ -1079,6 +1224,8 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vamb_lowpol.', errStat, errMsg, RoutineName ) allocate ( m%Vdist_low ( 3, 0:p%nX_low-1 , 0:p%nY_low-1 , 0:p%nZ_low-1 ) , STAT=errStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vdist_low.', errStat, errMsg, RoutineName ) + allocate ( m%Vdist_low_full ( 3, 0:p%nX_low-1 , 0:p%nY_low-1 , 0:p%nZ_low-1 ) , STAT=errStat2 ) + if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vdist_low_full', errStat, errMsg, RoutineName ) allocate ( m%Vamb_high(1:p%NumTurbines), STAT=ErrStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vamb_high.', errStat, errMsg, RoutineName ) @@ -1086,15 +1233,6 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO allocate ( m%Vamb_high(i)%data(3,0:p%nX_high-1,0:p%nY_high-1,0:p%nZ_high-1,0:p%n_high_low), STAT=ErrStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vamb_high%data.', errStat, errMsg, RoutineName ) end do - maxN_wake = p%NumTurbines*( p%NumPlanes-1 ) - allocate ( m%xhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%xhat_plane.', errStat, errMsg, RoutineName ) - allocate ( m%rhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%rhat_plane.', errStat, errMsg, RoutineName ) - allocate ( m%Vx_wake ( 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vx_wake.', errStat, errMsg, RoutineName ) - allocate ( m%Vr_wake ( 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vr_wake.', errStat, errMsg, RoutineName ) allocate ( m%parallelFlag( 0:p%NumPlanes-2,1:p%NumTurbines ), STAT=errStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%parallelFlag.', errStat, errMsg, RoutineName ) @@ -1248,17 +1386,26 @@ subroutine AWAE_UpdateStates( t, n, u, p, x, xd, z, OtherState, m, errStat, errM ! write(*,*) ' AWAE_UpdateStates: Time spent reading Low Res data : '//trim(num2lstr(t2-t1))//' seconds' !#endif + !$OMP PARALLEL DO DEFAULT(Shared) PRIVATE(nt, n_hl, errStat2, errMsg2) !Private(nt,tm2,tm3) do nt = 1,p%NumTurbines do n_hl=0, n_high_low ! read from file the ambient flow for the current time step call ReadHighResWindFile(nt, (n+1)*p%n_high_low + n_hl, p, m%Vamb_high(nt)%data(:,:,:,:,n_hl), errStat2, errMsg2) - call SetErrStat( ErrStat2, ErrMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) return + if (ErrStat2 >= AbortErrLev) then + !$OMP CRITICAL ! Needed to avoid data race on ErrStat and ErrMsg + call SetErrStat( ErrStat2, ErrMsg2, errStat, errMsg, RoutineName ) + !$OMP END CRITICAL + endif end do end do + !$OMP END PARALLEL DO + if (errStat >= AbortErrLev) return else ! p%Mod_AmbWind == 2 .or. 3 + ! Set the hub position and orientation to pass to IfW (IfW always calculates hub and disk avg vel) + m%u_IfW_Low%HubPosition = (/ p%X0_low + 0.5*p%nX_low*p%dX_low, p%Y0_low + 0.5*p%nY_low*p%dY_low, p%Z0_low + 0.5*p%nZ_low*p%dZ_low /) + call Eye(m%u_IfW_Low%HubOrientation,ErrStat2,ErrMsg2) ! Set low-resolution inflow wind velocities call InflowWind_CalcOutput(t+p%dt_low, m%u_IfW_Low, p%IfW(0), x%IfW(0), xd%IfW(0), z%IfW(0), OtherState%IfW(0), m%y_IfW_Low, m%IfW(0), errStat2, errMsg2) call SetErrStat( ErrStat2, ErrMsg2, errStat, errMsg, RoutineName ) @@ -1276,6 +1423,9 @@ subroutine AWAE_UpdateStates( t, n, u, p, x, xd, z, OtherState, m, errStat, errM if ( p%Mod_AmbWind == 2 ) then do nt = 1,p%NumTurbines m%u_IfW_High%PositionXYZ = p%Grid_high(:,:,nt) + ! Set the hub position and orientation to pass to IfW (IfW always calculates hub and disk avg vel) + m%u_IfW_High%HubPosition = (/ p%X0_high(nt) + 0.5*p%nX_high*p%dX_high(nt), p%Y0_high(nt) + 0.5*p%nY_high*p%dY_high(nt), p%Z0_high(nt) + 0.5*p%nZ_high*p%dZ_high(nt) /) + call Eye(m%u_IfW_High%HubOrientation,ErrStat2,ErrMsg2) do n_hl=0, n_high_low call InflowWind_CalcOutput(t+p%dt_low+n_hl*p%DT_high, m%u_IfW_High, p%IfW(0), x%IfW(0), xd%IfW(0), z%IfW(0), OtherState%IfW(0), m%y_IfW_High, m%IfW(0), errStat2, errMsg2) call SetErrStat( ErrStat2, ErrMsg2, errStat, errMsg, RoutineName ) @@ -1304,6 +1454,9 @@ subroutine AWAE_UpdateStates( t, n, u, p, x, xd, z, OtherState, m, errStat, errM end do end do do n_hl=0, n_high_low + ! Set the hub position and orientation to pass to IfW (IfW always calculates hub and disk avg vel) + m%u_IfW_High%HubPosition = (/ p%X0_high(nt) + 0.5*p%nX_high*p%dX_high(nt), p%Y0_high(nt) + 0.5*p%nY_high*p%dY_high(nt), p%Z0_high(nt) + 0.5*p%nZ_high*p%dZ_high(nt) /) + call Eye(m%u_IfW_High%HubOrientation,ErrStat2,ErrMsg2) call InflowWind_CalcOutput(t+p%dt_low+n_hl*p%DT_high, m%u_IfW_High, p%IfW(nt), x%IfW(nt), xd%IfW(nt), z%IfW(nt), OtherState%IfW(nt), m%y_IfW_High, m%IfW(nt), errStat2, errMsg2) call SetErrStat( ErrStat2, ErrMsg2, errStat, errMsg, RoutineName ) if (errStat >= AbortErrLev) return @@ -1341,6 +1494,7 @@ subroutine AWAE_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ! placed in the y%WriteOutput(:) array. !.................................................................................................................................. + use VTK real(DbKi), intent(in ) :: t !< Current simulation time in seconds type(AWAE_InputType), intent(in ) :: u !< Inputs at Time t type(AWAE_ParameterType), intent(in ) :: p !< Parameters @@ -1362,6 +1516,7 @@ subroutine AWAE_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg character(ErrMsgLen) :: errMsg2 character(*), parameter :: RoutineName = 'AWAE_CalcOutput' integer(intKi) :: n, n_high + character(2) :: PlaneNumStr ! 2 digit number of the output plane CHARACTER(1024) :: FileName INTEGER(IntKi) :: Un ! unit number of opened file @@ -1399,10 +1554,10 @@ subroutine AWAE_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ! XY plane slices do k = 1,p%NOutDisWindXY - - call ExtractSlice( XYSlice, p%OutDisWindZ(k), p%Z0_low, p%nZ_low, p%nX_low, p%nY_low, p%dZ_low, m%Vdist_low, m%outVizXYPlane(:,:,:,1)) + write(PlaneNumStr, '(i2.2)') k + call ExtractSlice( XYSlice, p%OutDisWindZ(k), p%Z0_low, p%nZ_low, p%nX_low, p%nY_low, p%dZ_low, m%Vdist_low_full, m%outVizXYPlane(:,:,:,1)) ! Create the output vtk file with naming /Low/DisXY.t.vtk - FileName = trim(p%OutFileVTKRoot)//".Low.DisXY"//trim(num2lstr(k))//"."//trim(Tstr)//".vtk" + FileName = trim(p%OutFileVTKRoot)//".Low.DisXY"//PlaneNumStr//"."//trim(Tstr)//".vtk" call WrVTK_SP_header( FileName, "Low resolution, disturbed wind of XY Slice at time = "//trim(num2lstr(t))//" seconds.", Un, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return @@ -1411,12 +1566,12 @@ subroutine AWAE_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg if (ErrStat >= AbortErrLev) return end do - ! YZ plane slices do k = 1,p%NOutDisWindYZ - call ExtractSlice( YZSlice, p%OutDisWindX(k), p%X0_low, p%nX_low, p%nY_low, p%nZ_low, p%dX_low, m%Vdist_low, m%outVizYZPlane(:,:,:,1)) + write(PlaneNumStr, '(i2.2)') k + call ExtractSlice( YZSlice, p%OutDisWindX(k), p%X0_low, p%nX_low, p%nY_low, p%nZ_low, p%dX_low, m%Vdist_low_full, m%outVizYZPlane(:,:,:,1)) ! Create the output vtk file with naming /Low/DisYZ.t.vtk - FileName = trim(p%OutFileVTKRoot)//".Low.DisYZ"//trim(num2lstr(k))//"."//trim(Tstr)//".vtk" + FileName = trim(p%OutFileVTKRoot)//".Low.DisYZ"//PlaneNumStr//"."//trim(Tstr)//".vtk" call WrVTK_SP_header( FileName, "Low resolution, disturbed wind of YZ Slice at time = "//trim(num2lstr(t))//" seconds.", Un, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return @@ -1427,9 +1582,10 @@ subroutine AWAE_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ! XZ plane slices do k = 1,p%NOutDisWindXZ - call ExtractSlice( XZSlice, p%OutDisWindY(k), p%Y0_low, p%nY_low, p%nX_low, p%nZ_low, p%dY_low, m%Vdist_low, m%outVizXZPlane(:,:,:,1)) + write(PlaneNumStr, '(i2.2)') k + call ExtractSlice( XZSlice, p%OutDisWindY(k), p%Y0_low, p%nY_low, p%nX_low, p%nZ_low, p%dY_low, m%Vdist_low_full, m%outVizXZPlane(:,:,:,1)) ! Create the output vtk file with naming /Low/DisXZ.t.vtk - FileName = trim(p%OutFileVTKRoot)//".Low.DisXZ"//trim(num2lstr(k))//"."//trim(Tstr)//".vtk" + FileName = trim(p%OutFileVTKRoot)//".Low.DisXZ"//PlaneNumStr//"."//trim(Tstr)//".vtk" call WrVTK_SP_header( FileName, "Low resolution, disturbed wind of XZ Slice at time = "//trim(num2lstr(t))//" seconds.", Un, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) if (ErrStat >= AbortErrLev) return @@ -1648,7 +1804,7 @@ subroutine AWAE_TEST_CalcOutput(errStat, errMsg) type(AWAE_InitOutputType) :: initOut !< Input data for initialization routine - integer(IntKi) :: nt, nr, np + integer(IntKi) :: nt, ny, nz, np real(DbKi) :: t ! This example creates turbine 1 at the global coordinate [0,0,0] @@ -1690,9 +1846,12 @@ subroutine AWAE_TEST_CalcOutput(errStat, errMsg) ! Set up the inputs do nt = 1,p%NumTurbines do np = 0,p%NumPlanes-1 - do nr = 0,p%NumRadii-1 - u%Vx_wake(nr,np,nt) = -1.0_ReKi - u%Vr_wake(nr,np,nt) = 0.1_ReKi + do nz = -p%NumRadii+1,p%NumRadii-1 + do ny = -p%NumRadii+1,p%NumRadii-1 + u%Vx_wake(ny,nz,np,nt) = -1.0_ReKi + u%Vy_wake(ny,nz,np,nt) = 0.1_ReKi ! TODO initialize to radial + u%Vz_wake(ny,nz,np,nt) = 0.1_ReKi + end do end do end do end do @@ -1733,6 +1892,40 @@ subroutine AWAE_TEST_CalcOutput(errStat, errMsg) end subroutine AWAE_TEST_CalcOutput +! WAT TODO +!> Compute non-scaled turbulence at a given plane based on a Mann Box, current time, and convection velocity of the box +subroutine TurbPlane(Uconv, t, nr, u_p, v_p, w_p) + integer(IntKi), intent(in) :: nr !< Number of radius in wake plane + !real(ReKi), dimension(0:,0:,0:), pointer, intent(in) :: u_b !< TODO turbulence box + real(ReKi), intent(in) :: Uconv !< Convection velocity of the box + real(DbKi), intent(in) :: t !< Current time + real(ReKi), dimension(-nr+1:nr+1,-nr+1:nr+1), intent(out) :: u_p !< Plane to be filled with turbulence values, shape + real(ReKi), dimension(-nr+1:nr+1,-nr+1:nr+1), intent(out) :: v_p !< Plane to be filled with turbulence values, shape + real(ReKi), dimension(-nr+1:nr+1,-nr+1:nr+1), intent(out) :: w_p !< Plane to be filled with turbulence values, shape + integer(IntKi) :: iz, iy ! indices in plane coordinates + integer(IntKi) :: ix_b, iy_b, iz_b, ib0, nb ! Indices in box coordinates + + !nb = size(u_b, 1) + nb=2 ! TODO + ib0 = int(nb/2)-1 ! NOTE: nb is multiple of 2 + + ! Interpolate time + ! TODO use Uconv/t to find ix_b + + ! Loop through all plane points + do iz = -nr+1, nr-1 + iz_b = modulo(ib0 + iz, nb) ! NOTE: assumes that turbulene box has indexing starting from 0 + do iy = -nr+1, nr-1 + iy_b = modulo(ib0 + iz, nb) + u_p(iy,iz) = 0.0_ReKi + v_p(iy,iz) = 0.0_ReKi + w_p(iy,iz) = 0.0_ReKi + !u_b = u_b(iy_b, iz_b, ix_b) ! TODO + enddo + enddo + +end subroutine + FUNCTION INTERP3D(p,p0,del,V,within,nX,nY,nZ,Vbox) ! I/O variables Real(ReKi), INTENT( IN ) :: p(3) !< Position where the 3D velocity field will be interpreted (m) @@ -1807,6 +2000,158 @@ FUNCTION INTERP3D(p,p0,del,V,within,nX,nY,nZ,Vbox) ! Output the wind velocities at the 8 points in the 3D spatial domain surrounding the input position (if necessary) IF ( PRESENT( Vbox ) ) Vbox = REAL( Vtmp, ReKi ) -END FUNCTION +END FUNCTION INTERP3D + +! +!> 2D interpolation of a scalar field field defined on a 2D-rectilinear grid, using lambda 1 kernel +function interp2d(Point, v1, v2, mesh) result(PointVal) + ! Argument declarations + real(ReKi), dimension(2) , intent(in) :: Point !< Point where values are to be interpolated + real(ReKi), dimension(:), intent(in) :: v1,v2 !< Array of values along 1st and 2nd dimension + real(ReKi), dimension(:,:), intent(in) :: mesh !< Mesh values + real(ReKi) :: PointVal !< Output + ! Variable declarations + real(ReKi) :: ax1,ax2 !< + integer :: i1,i2 !< + real(ReKi) :: ay1,ay2 !< + integer :: j1,j2 !< + integer :: i + real(ReKi), dimension(2) :: dc !< + integer, dimension(2) :: ic !< + ! Indices (ic) and distances (dc) in grid index space (to nearest left grid point) + call coordRectilinearGrid(Point(1), v1, ic(1), dc(1)) + call coordRectilinearGrid(Point(2), v2, ic(2), dc(2)) + ! Getting the lambda 1 kernel coefficients + call interp_coeff_l1(ic(1),dc(1),size(v1),ax1,ax2,i1,i2) + call interp_coeff_l1(ic(2),dc(2),size(v2),ay1,ay2,j1,j2) + ! Interpolation + PointVal = ax1*ay1*mesh(i1,j1) + & + & ax2*ay1*mesh(i2,j1) + & + & ax1*ay2*mesh(i1,j2) + & + & ax2*ay2*mesh(i2,j2) +end function + +!> Returns index and distance of closest value in vx below x0 +subroutine coordRectilinearGrid(x0, vx, ic, dc) + ! Arguments declarations + real(ReKi), dimension(:), intent(in) :: vx !< Array of values + real(ReKi), intent(in) :: x0 !< Point looked for in array + real(ReKi), intent(out) :: dc !< distance to left grid point + integer, intent(out) :: ic !< index of left grid point + ! + dc=0 + ic=binary_search(vx,x0) ! ic can be -1 + if (ic/=-1 .and. ic Return interpolation coefficients for a lambda 1 kernel (linear interpolation) +subroutine interp_coeff_l1(i, dx, nx, ax1, ax2, i1, i2) + ! Arguments declarations + integer, intent(in) :: i !< Index of left node + real(ReKi), intent(in) :: dx !< Normalized distance to mid left node + integer, intent(in) :: nx !< Maximum number of values + real(ReKi), intent(out) :: ax1 !< Interpolation coefficients + real(ReKi), intent(out) :: ax2 !< + integer, intent(out) :: i1 !< Node indexes spreading over the stencil + integer, intent(out) :: i2 !< + ! --- Find index of other cells + i1 = i + i2 = i+1 + ! --- The Lambda 1 kernel coeffs + ax1 = 1._ReKi-dx + ax2 = dx + ! --- Safety if box exceeded + if (i1<0) then + i1=1; i2=1; ax1=1._ReKi; ax2=0; + elseif (i2>nx) then + i1=nx; i2=nx; ax1=1._ReKi; ax2=0; + end if + i1=max(i1,1) + i2=max(i2,1) + i1=min(i1,nx) + i2=min(i2,nx) +end subroutine interp_coeff_l1 + +!> Perform binary search in an array +integer function binary_search(x, x0) result(i_inf) + ! Arguments declarations + real(ReKi), dimension(:),intent(in) :: x ! < array + real(ReKi), intent(in) :: x0 ! < searched value + ! Variable declarations + integer :: i_sup !< + integer :: mid !< + ! x a sorted vector (typically a grid vector) + ! Performs binary search and return the largest index such that x(i) <= x0 + 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+11e-5) then + print*,'>>Error interp2d on points',i,j,Vi,Vi_th + STOP + endif + enddo + enddo + + ! --- Test at different points + do i = 1,size(y2) + do j = 1,size(z2) + Vi = interp2d((/y2(i), z2(j)/), y, z, Vx) + Vi_th = testf(y2(i),z2(j)) + if (abs(Vi-Vi_th)>1e-5) then + print*,'>>Error interp2d on misc points',i,j,Vi,Vi_th + STOP + endif + enddo + enddo + contains + real(ReKi) function testf(y,z) + real(ReKi) :: y, z + testf=3._ReKi*y +5._ReKi*z + 10.0_ReKi + end function +end subroutine + end module AWAE diff --git a/modules/awae/src/AWAE_IO.f90 b/modules/awae/src/AWAE_IO.f90 index 9722d9376..5d89f4097 100644 --- a/modules/awae/src/AWAE_IO.f90 +++ b/modules/awae/src/AWAE_IO.f90 @@ -24,6 +24,7 @@ MODULE AWAE_IO use NWTC_Library + use VTK use AWAE_Types @@ -283,7 +284,7 @@ subroutine AWAE_IO_InitGridInfo(InitInp, p, InitOut, errStat, errMsg) p%dXYZ_Low = gridSpacing p%dpol = (gridSpacing(1)+gridSpacing(2)+gridSpacing(3))/3.0_ReKi - p%n_rp_max = ceiling(pi*((p%C_Meander*(p%r(p%NumRadii-1)+p%dpol))/p%dpol)**2.0_ReKi) + p%n_rp_max = ceiling(pi*((p%C_Meander*((p%NumRadii-1)*InitInp%InputFileData%dr+p%dpol))/p%dpol)**2.0_ReKi) ! Grid runs from (X0_low, Y0_low, Z0_low) to (X0_low + (p%nX_Low-1)*dX_low, Y0_low+ (p%nY_Low-1)*dY_low, Z0_low+ (p%nZ_Low-1)*dZ_low) ! (0,0,0) to (180,180,180) diff --git a/modules/awae/src/AWAE_Registry.txt b/modules/awae/src/AWAE_Registry.txt index d8b236238..a5680f0dc 100644 --- a/modules/awae/src/AWAE_Registry.txt +++ b/modules/awae/src/AWAE_Registry.txt @@ -64,6 +64,9 @@ typedef ^ ^ ReKi X0_low - - - typedef ^ ^ ReKi Y0_low - - - "Y-component of the origin of the low-resolution spatial domain" m typedef ^ ^ ReKi Z0_low - - - "Z-component of the origin of the low-resolution spatial domain" m typedef ^ ^ ReKi WT_Position {:}{:} - - "X-Y-Z position of each wind turbine; index 1 = XYZ; index 2 = turbine number" meters +typedef ^ ^ IntKi Mod_Projection - - - "Switch to select how the wake plane velocity is projected in AWAE {1: keep all components, 2: project against plane normal} or DEFAULT [DEFAULT=1: if Mod_Wake is 1 or 3, or DEFAULT=2: if Mod_Wake is 2]" + + # ..... Initialization data ....................................................................................................... # Define inputs that the initialization routine may need here: @@ -116,9 +119,8 @@ typedef ^ OtherStateType InflowWind_OtherStateType IfW {:} - - "Dum typedef ^ MiscVarType SiKi Vamb_low {:}{:}{:}{:} - - "UVW components of ambient wind across the low-resolution domain throughout the farm" m/s typedef ^ MiscVarType ReKi Vamb_lowpol {:}{:} - - "UVW components of disturbed wind (ambient + wakes) at points in the polar grid for each wake plane for each turbine" m/s typedef ^ MiscVarType SiKi Vdist_low {:}{:}{:}{:} - - "UVW components of disturbed wind (ambient + deficits) across the low-resolution domain throughout the farm" m/s +typedef ^ MiscVarType SiKi Vdist_low_full {:}{:}{:}{:} - - "UVW components of disturbed wind (ambient + deficits) across the low-resolution domain throughout the farm, for outputs" m/s typedef ^ MiscVarType AWAE_HighWindGrid Vamb_High {:} - - "UVW components of ambient wind across each high-resolution domain around a turbine (one for each turbine) for each high-resolution time step within a low-resolution time step" m/s -typedef ^ MiscVarType ReKi xhat_plane {:}{:} - - "Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain" - -typedef ^ MiscVarType ReKi rhat_plane {:}{:} - - "" - typedef ^ MiscVarType Logical parallelFlag {:}{:} - - "" - typedef ^ MiscVarType ReKi r_s {:}{:} - - "" - typedef ^ MiscVarType ReKi r_e {:}{:} - - "" - @@ -126,8 +128,7 @@ typedef ^ MiscVarType ReKi rhat_s {:}{:}{:} - - "" - typedef ^ MiscVarType ReKi rhat_e {:}{:}{:} - - "" - typedef ^ MiscVarType ReKi pvec_cs {:}{:}{:} - - "" - typedef ^ MiscVarType ReKi pvec_ce {:}{:}{:} - - "" - -typedef ^ MiscVarType ReKi Vx_wake {:} - - "" m/s -typedef ^ MiscVarType ReKi Vr_wake {:} - - "" m/s +# typedef ^ MiscVarType SiKi outVizXYPlane {:}{:}{:}{:} -- "An array holding the output data for a 2D visualization slice" - typedef ^ MiscVarType SiKi outVizYZPlane {:}{:}{:}{:} -- "An array holding the output data for a 2D visualization slice" - typedef ^ MiscVarType SiKi outVizXZPlane {:}{:}{:}{:} -- "An array holding the output data for a 2D visualization slice" - @@ -144,7 +145,8 @@ typedef ^ ParameterType CHARACTER(1024) WindFilePath - - - "Path na typedef ^ ParameterType IntKi NumTurbines - - - "Number of wind turbines in the farm [>=1]" - typedef ^ ParameterType IntKi NumRadii - - - "Number of radii in the radial finite-difference grid [>=2]" - typedef ^ ParameterType IntKi NumPlanes - - - "Number of wake planes downwind of the rotor where the wake is propagated [>=2]" - -typedef ^ ParameterType ReKi r {:} - - "Discretization of radial finite-difference grid" m +typedef ^ ParameterType ReKi y {:} - - "Horizontal discretization of the wake planes" m +typedef ^ ParameterType ReKi z {:} - - "Vertical discretization of the wake planes" m typedef ^ ^ IntKi Mod_AmbWind - - - "Ambient wind model {1: high-fidelity precursor in VTK format, 2: InflowWind module}" - typedef ^ ParameterType IntKi nX_low - - - "Number of low-resolution spatial nodes in X direction" - typedef ^ ParameterType IntKi nY_low - - - "Number of low-resolution spatial nodes in Y direction" - @@ -178,6 +180,7 @@ typedef ^ ParameterType IntKi NumDT - - - "Number typedef ^ ParameterType IntKi Mod_Meander - - - "Spatial filter model for wake meandering" - typedef ^ ParameterType ReKi C_Meander - - - "Calibrated parameter for wake meandering" - typedef ^ ParameterType ReKi C_ScaleDiam - - - "Normalized wake volume radius for wake meandering (normalized by the wake diameter)" - +typedef ^ ParameterType IntKi Mod_Projection - - - "Switch to select how the wake plane velocity is projected in AWAE {1: keep all components, 2: project against plane normal} or DEFAULT [DEFAULT=1: if Mod_Wake is 1 or 3, or DEFAULT=2: if Mod_Wake is 2]" typedef ^ ParameterType InflowWind_ParameterType IfW {:} - - "InflowWind module parameters" - # parameters for output #typedef ^ ParameterType IntKi NumOuts - - - "Number of parameters in the output list (number of outputs requested)" - @@ -207,7 +210,9 @@ typedef ^ OutputType ReKi Vx_wind_disk {:} - # Define inputs that are contained on the mesh here: typedef ^ InputType ReKi xhat_plane {:}{:}{:} - - "Orientations of wake planes, normal to wake planes, for each turbine" - typedef ^ InputType ReKi p_plane {:}{:}{:} - - "Center positions of wake planes for each turbine" m -typedef ^ InputType ReKi Vx_wake {:}{:}{:} - - "Axial wake velocity deficit at wake planes, distributed radially, for each turbine" m/s -typedef ^ InputType ReKi Vr_wake {:}{:}{:} - - "Radial wake velocity deficit at wake planes, distributed radially, for each turbine" m/s +typedef ^ InputType ReKi Vx_wake {:}{:}{:}{:} - - "Axial wake velocity deficit at wake planes, distributed across the plane, for each turbine (ny,nz,np,nWT)" m/s +typedef ^ InputType ReKi Vy_wake {:}{:}{:}{:} - - "Transverse horizonal wake velocity deficit at wake planes, distributed across the plane, for each turbine (ny,nz,np,nWT)" m/s +typedef ^ InputType ReKi Vz_wake {:}{:}{:}{:} - - "Transverse nominally vertical wake velocity deficit at wake planes, distributed across the plane, for each turbine (ny,nz,np,nWT)" m/s typedef ^ InputType ReKi D_wake {:}{:} - - "Wake diameters at wake planes for each turbine" m - +# wake added turbulence (WAT) inputs +typedef ^ InputType ReKi WAT_k_mt {:}{:}{:} - - "Scaling factor k_mt(r,x) for wake-added turbulence" - diff --git a/modules/awae/src/AWAE_Types.f90 b/modules/awae/src/AWAE_Types.f90 index d6ade6de2..c18322333 100644 --- a/modules/awae/src/AWAE_Types.f90 +++ b/modules/awae/src/AWAE_Types.f90 @@ -86,6 +86,7 @@ MODULE AWAE_Types REAL(ReKi) :: Y0_low !< Y-component of the origin of the low-resolution spatial domain [m] REAL(ReKi) :: Z0_low !< Z-component of the origin of the low-resolution spatial domain [m] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WT_Position !< X-Y-Z position of each wind turbine; index 1 = XYZ; index 2 = turbine number [meters] + INTEGER(IntKi) :: Mod_Projection !< Switch to select how the wake plane velocity is projected in AWAE {1: keep all components, 2: project against plane normal} or DEFAULT [DEFAULT=1: if Mod_Wake is 1 or 3, or DEFAULT=2: if Mod_Wake is 2] [-] END TYPE AWAE_InputFileType ! ======================= ! ========= AWAE_InitInputType ======= @@ -144,9 +145,8 @@ MODULE AWAE_Types REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vamb_low !< UVW components of ambient wind across the low-resolution domain throughout the farm [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vamb_lowpol !< UVW components of disturbed wind (ambient + wakes) at points in the polar grid for each wake plane for each turbine [m/s] REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vdist_low !< UVW components of disturbed wind (ambient + deficits) across the low-resolution domain throughout the farm [m/s] + REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vdist_low_full !< UVW components of disturbed wind (ambient + deficits) across the low-resolution domain throughout the farm, for outputs [m/s] TYPE(AWAE_HighWindGrid) , DIMENSION(:), ALLOCATABLE :: Vamb_High !< UVW components of ambient wind across each high-resolution domain around a turbine (one for each turbine) for each high-resolution time step within a low-resolution time step [m/s] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: xhat_plane !< Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: rhat_plane !< [-] LOGICAL , DIMENSION(:,:), ALLOCATABLE :: parallelFlag !< [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: r_s !< [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: r_e !< [-] @@ -154,8 +154,6 @@ MODULE AWAE_Types REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: rhat_e !< [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: pvec_cs !< [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: pvec_ce !< [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Vx_wake !< [m/s] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Vr_wake !< [m/s] REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: outVizXYPlane REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: outVizYZPlane REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: outVizXZPlane @@ -172,7 +170,8 @@ MODULE AWAE_Types INTEGER(IntKi) :: NumTurbines !< Number of wind turbines in the farm [>=1] [-] INTEGER(IntKi) :: NumRadii !< Number of radii in the radial finite-difference grid [>=2] [-] INTEGER(IntKi) :: NumPlanes !< Number of wake planes downwind of the rotor where the wake is propagated [>=2] [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: r !< Discretization of radial finite-difference grid [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: y !< Horizontal discretization of the wake planes [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: z !< Vertical discretization of the wake planes [m] INTEGER(IntKi) :: Mod_AmbWind !< Ambient wind model {1: high-fidelity precursor in VTK format, 2: InflowWind module} [-] INTEGER(IntKi) :: nX_low !< Number of low-resolution spatial nodes in X direction [-] INTEGER(IntKi) :: nY_low !< Number of low-resolution spatial nodes in Y direction [-] @@ -206,6 +205,7 @@ MODULE AWAE_Types INTEGER(IntKi) :: Mod_Meander !< Spatial filter model for wake meandering [-] REAL(ReKi) :: C_Meander !< Calibrated parameter for wake meandering [-] REAL(ReKi) :: C_ScaleDiam !< Normalized wake volume radius for wake meandering (normalized by the wake diameter) [-] + INTEGER(IntKi) :: Mod_Projection !< Switch to select how the wake plane velocity is projected in AWAE {1: keep all components, 2: project against plane normal} or DEFAULT [DEFAULT=1: if Mod_Wake is 1 or 3, or DEFAULT=2: if Mod_Wake is 2] [-] TYPE(InflowWind_ParameterType) , DIMENSION(:), ALLOCATABLE :: IfW !< InflowWind module parameters [-] INTEGER(IntKi) :: WrDisSkp1 !< Number of time steps to skip plus one [-] LOGICAL :: WrDisWind !< Write disturbed wind data to /Low/Dis.t.vtk etc.? [-] @@ -232,9 +232,11 @@ MODULE AWAE_Types TYPE, PUBLIC :: AWAE_InputType REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: xhat_plane !< Orientations of wake planes, normal to wake planes, for each turbine [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: p_plane !< Center positions of wake planes for each turbine [m] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vx_wake !< Axial wake velocity deficit at wake planes, distributed radially, for each turbine [m/s] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vr_wake !< Radial wake velocity deficit at wake planes, distributed radially, for each turbine [m/s] + REAL(ReKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vx_wake !< Axial wake velocity deficit at wake planes, distributed across the plane, for each turbine (ny,nz,np,nWT) [m/s] + REAL(ReKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vy_wake !< Transverse horizonal wake velocity deficit at wake planes, distributed across the plane, for each turbine (ny,nz,np,nWT) [m/s] + REAL(ReKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vz_wake !< Transverse nominally vertical wake velocity deficit at wake planes, distributed across the plane, for each turbine (ny,nz,np,nWT) [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_wake !< Wake diameters at wake planes for each turbine [m] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: WAT_k_mt !< Scaling factor k_mt(r,x) for wake-added turbulence [-] END TYPE AWAE_InputType ! ======================= CONTAINS @@ -279,15 +281,27 @@ SUBROUTINE AWAE_CopyHighWindGrid( SrcHighWindGridData, DstHighWindGridData, Ctrl ENDIF END SUBROUTINE AWAE_CopyHighWindGrid - SUBROUTINE AWAE_DestroyHighWindGrid( HighWindGridData, ErrStat, ErrMsg ) + SUBROUTINE AWAE_DestroyHighWindGrid( HighWindGridData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AWAE_HighWindGrid), INTENT(INOUT) :: HighWindGridData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyHighWindGrid' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyHighWindGrid' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(HighWindGridData%data)) THEN DEALLOCATE(HighWindGridData%data) ENDIF @@ -635,17 +649,30 @@ SUBROUTINE AWAE_CopyInputFileType( SrcInputFileTypeData, DstInputFileTypeData, C END IF DstInputFileTypeData%WT_Position = SrcInputFileTypeData%WT_Position ENDIF + DstInputFileTypeData%Mod_Projection = SrcInputFileTypeData%Mod_Projection END SUBROUTINE AWAE_CopyInputFileType - SUBROUTINE AWAE_DestroyInputFileType( InputFileTypeData, ErrStat, ErrMsg ) + SUBROUTINE AWAE_DestroyInputFileType( InputFileTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AWAE_InputFileType), INTENT(INOUT) :: InputFileTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyInputFileType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyInputFileType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputFileTypeData%OutDisWindZ)) THEN DEALLOCATE(InputFileTypeData%OutDisWindZ) ENDIF @@ -792,6 +819,7 @@ SUBROUTINE AWAE_PackInputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 2*2 ! WT_Position upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WT_Position) ! WT_Position END IF + Int_BufSz = Int_BufSz + 1 ! Mod_Projection IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1036,6 +1064,8 @@ SUBROUTINE AWAE_PackInputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END DO END DO END IF + IntKiBuf(Int_Xferred) = InData%Mod_Projection + Int_Xferred = Int_Xferred + 1 END SUBROUTINE AWAE_PackInputFileType SUBROUTINE AWAE_UnPackInputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1313,6 +1343,8 @@ SUBROUTINE AWAE_UnPackInputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta END DO END DO END IF + OutData%Mod_Projection = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE AWAE_UnPackInputFileType SUBROUTINE AWAE_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) @@ -1337,16 +1369,29 @@ SUBROUTINE AWAE_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Err DstInitInputData%OutFileRoot = SrcInitInputData%OutFileRoot END SUBROUTINE AWAE_CopyInitInput - SUBROUTINE AWAE_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE AWAE_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AWAE_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" - CALL AWAE_Destroyinputfiletype( InitInputData%InputFileData, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL AWAE_Destroyinputfiletype( InitInputData%InputFileData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AWAE_DestroyInitInput SUBROUTINE AWAE_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1650,16 +1695,29 @@ SUBROUTINE AWAE_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, DstInitOutputData%Z0_low = SrcInitOutputData%Z0_low END SUBROUTINE AWAE_CopyInitOutput - SUBROUTINE AWAE_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE AWAE_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AWAE_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitOutputData%X0_high)) THEN DEALLOCATE(InitOutputData%X0_high) ENDIF @@ -2180,18 +2238,31 @@ SUBROUTINE AWAE_CopyContState( SrcContStateData, DstContStateData, CtrlCode, Err ENDIF END SUBROUTINE AWAE_CopyContState - SUBROUTINE AWAE_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE AWAE_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AWAE_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%IfW)) THEN DO i1 = LBOUND(ContStateData%IfW,1), UBOUND(ContStateData%IfW,1) - CALL InflowWind_DestroyContState( ContStateData%IfW(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyContState( ContStateData%IfW(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ContStateData%IfW) ENDIF @@ -2444,18 +2515,31 @@ SUBROUTINE AWAE_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, Err ENDIF END SUBROUTINE AWAE_CopyDiscState - SUBROUTINE AWAE_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE AWAE_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AWAE_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(DiscStateData%IfW)) THEN DO i1 = LBOUND(DiscStateData%IfW,1), UBOUND(DiscStateData%IfW,1) - CALL InflowWind_DestroyDiscState( DiscStateData%IfW(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyDiscState( DiscStateData%IfW(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(DiscStateData%IfW) ENDIF @@ -2708,18 +2792,31 @@ SUBROUTINE AWAE_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCod ENDIF END SUBROUTINE AWAE_CopyConstrState - SUBROUTINE AWAE_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE AWAE_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AWAE_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ConstrStateData%IfW)) THEN DO i1 = LBOUND(ConstrStateData%IfW,1), UBOUND(ConstrStateData%IfW,1) - CALL InflowWind_DestroyConstrState( ConstrStateData%IfW(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyConstrState( ConstrStateData%IfW(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ConstrStateData%IfW) ENDIF @@ -2972,18 +3069,31 @@ SUBROUTINE AWAE_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ENDIF END SUBROUTINE AWAE_CopyOtherState - SUBROUTINE AWAE_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE AWAE_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AWAE_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OtherStateData%IfW)) THEN DO i1 = LBOUND(OtherStateData%IfW,1), UBOUND(OtherStateData%IfW,1) - CALL InflowWind_DestroyOtherState( OtherStateData%IfW(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyOtherState( OtherStateData%IfW(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OtherStateData%IfW) ENDIF @@ -3271,6 +3381,24 @@ SUBROUTINE AWAE_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF DstMiscData%Vdist_low = SrcMiscData%Vdist_low ENDIF +IF (ALLOCATED(SrcMiscData%Vdist_low_full)) THEN + i1_l = LBOUND(SrcMiscData%Vdist_low_full,1) + i1_u = UBOUND(SrcMiscData%Vdist_low_full,1) + i2_l = LBOUND(SrcMiscData%Vdist_low_full,2) + i2_u = UBOUND(SrcMiscData%Vdist_low_full,2) + i3_l = LBOUND(SrcMiscData%Vdist_low_full,3) + i3_u = UBOUND(SrcMiscData%Vdist_low_full,3) + i4_l = LBOUND(SrcMiscData%Vdist_low_full,4) + i4_u = UBOUND(SrcMiscData%Vdist_low_full,4) + IF (.NOT. ALLOCATED(DstMiscData%Vdist_low_full)) THEN + ALLOCATE(DstMiscData%Vdist_low_full(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 DstMiscData%Vdist_low_full.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%Vdist_low_full = SrcMiscData%Vdist_low_full +ENDIF IF (ALLOCATED(SrcMiscData%Vamb_High)) THEN i1_l = LBOUND(SrcMiscData%Vamb_High,1) i1_u = UBOUND(SrcMiscData%Vamb_High,1) @@ -3287,34 +3415,6 @@ SUBROUTINE AWAE_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcMiscData%xhat_plane)) THEN - i1_l = LBOUND(SrcMiscData%xhat_plane,1) - i1_u = UBOUND(SrcMiscData%xhat_plane,1) - i2_l = LBOUND(SrcMiscData%xhat_plane,2) - i2_u = UBOUND(SrcMiscData%xhat_plane,2) - IF (.NOT. ALLOCATED(DstMiscData%xhat_plane)) THEN - ALLOCATE(DstMiscData%xhat_plane(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%xhat_plane.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstMiscData%xhat_plane = SrcMiscData%xhat_plane -ENDIF -IF (ALLOCATED(SrcMiscData%rhat_plane)) THEN - i1_l = LBOUND(SrcMiscData%rhat_plane,1) - i1_u = UBOUND(SrcMiscData%rhat_plane,1) - i2_l = LBOUND(SrcMiscData%rhat_plane,2) - i2_u = UBOUND(SrcMiscData%rhat_plane,2) - IF (.NOT. ALLOCATED(DstMiscData%rhat_plane)) THEN - ALLOCATE(DstMiscData%rhat_plane(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%rhat_plane.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstMiscData%rhat_plane = SrcMiscData%rhat_plane -ENDIF IF (ALLOCATED(SrcMiscData%parallelFlag)) THEN i1_l = LBOUND(SrcMiscData%parallelFlag,1) i1_u = UBOUND(SrcMiscData%parallelFlag,1) @@ -3421,30 +3521,6 @@ SUBROUTINE AWAE_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF DstMiscData%pvec_ce = SrcMiscData%pvec_ce ENDIF -IF (ALLOCATED(SrcMiscData%Vx_wake)) THEN - i1_l = LBOUND(SrcMiscData%Vx_wake,1) - i1_u = UBOUND(SrcMiscData%Vx_wake,1) - IF (.NOT. ALLOCATED(DstMiscData%Vx_wake)) THEN - ALLOCATE(DstMiscData%Vx_wake(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%Vx_wake.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstMiscData%Vx_wake = SrcMiscData%Vx_wake -ENDIF -IF (ALLOCATED(SrcMiscData%Vr_wake)) THEN - i1_l = LBOUND(SrcMiscData%Vr_wake,1) - i1_u = UBOUND(SrcMiscData%Vr_wake,1) - IF (.NOT. ALLOCATED(DstMiscData%Vr_wake)) THEN - ALLOCATE(DstMiscData%Vr_wake(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%Vr_wake.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstMiscData%Vr_wake = SrcMiscData%Vr_wake -ENDIF IF (ALLOCATED(SrcMiscData%outVizXYPlane)) THEN i1_l = LBOUND(SrcMiscData%outVizXYPlane,1) i1_u = UBOUND(SrcMiscData%outVizXYPlane,1) @@ -3529,15 +3605,27 @@ SUBROUTINE AWAE_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE AWAE_CopyMisc - SUBROUTINE AWAE_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE AWAE_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AWAE_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%Vamb_low)) THEN DEALLOCATE(MiscData%Vamb_low) ENDIF @@ -3547,18 +3635,16 @@ SUBROUTINE AWAE_DestroyMisc( MiscData, ErrStat, ErrMsg ) IF (ALLOCATED(MiscData%Vdist_low)) THEN DEALLOCATE(MiscData%Vdist_low) ENDIF +IF (ALLOCATED(MiscData%Vdist_low_full)) THEN + DEALLOCATE(MiscData%Vdist_low_full) +ENDIF IF (ALLOCATED(MiscData%Vamb_High)) THEN DO i1 = LBOUND(MiscData%Vamb_High,1), UBOUND(MiscData%Vamb_High,1) - CALL AWAE_Destroyhighwindgrid( MiscData%Vamb_High(i1), ErrStat, ErrMsg ) + CALL AWAE_Destroyhighwindgrid( MiscData%Vamb_High(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%Vamb_High) ENDIF -IF (ALLOCATED(MiscData%xhat_plane)) THEN - DEALLOCATE(MiscData%xhat_plane) -ENDIF -IF (ALLOCATED(MiscData%rhat_plane)) THEN - DEALLOCATE(MiscData%rhat_plane) -ENDIF IF (ALLOCATED(MiscData%parallelFlag)) THEN DEALLOCATE(MiscData%parallelFlag) ENDIF @@ -3580,12 +3666,6 @@ SUBROUTINE AWAE_DestroyMisc( MiscData, ErrStat, ErrMsg ) IF (ALLOCATED(MiscData%pvec_ce)) THEN DEALLOCATE(MiscData%pvec_ce) ENDIF -IF (ALLOCATED(MiscData%Vx_wake)) THEN - DEALLOCATE(MiscData%Vx_wake) -ENDIF -IF (ALLOCATED(MiscData%Vr_wake)) THEN - DEALLOCATE(MiscData%Vr_wake) -ENDIF IF (ALLOCATED(MiscData%outVizXYPlane)) THEN DEALLOCATE(MiscData%outVizXYPlane) ENDIF @@ -3597,14 +3677,19 @@ SUBROUTINE AWAE_DestroyMisc( MiscData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(MiscData%IfW)) THEN DO i1 = LBOUND(MiscData%IfW,1), UBOUND(MiscData%IfW,1) - CALL InflowWind_DestroyMisc( MiscData%IfW(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyMisc( MiscData%IfW(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%IfW) ENDIF - CALL InflowWind_DestroyInput( MiscData%u_IfW_Low, ErrStat, ErrMsg ) - CALL InflowWind_DestroyInput( MiscData%u_IfW_High, ErrStat, ErrMsg ) - CALL InflowWind_DestroyOutput( MiscData%y_IfW_Low, ErrStat, ErrMsg ) - CALL InflowWind_DestroyOutput( MiscData%y_IfW_High, ErrStat, ErrMsg ) + CALL InflowWind_DestroyInput( MiscData%u_IfW_Low, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyInput( MiscData%u_IfW_High, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyOutput( MiscData%y_IfW_Low, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyOutput( MiscData%y_IfW_High, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE AWAE_DestroyMisc SUBROUTINE AWAE_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -3657,6 +3742,11 @@ SUBROUTINE AWAE_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_BufSz = Int_BufSz + 2*4 ! Vdist_low upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Vdist_low) ! Vdist_low END IF + Int_BufSz = Int_BufSz + 1 ! Vdist_low_full allocated yes/no + IF ( ALLOCATED(InData%Vdist_low_full) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! Vdist_low_full upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vdist_low_full) ! Vdist_low_full + END IF Int_BufSz = Int_BufSz + 1 ! Vamb_High allocated yes/no IF ( ALLOCATED(InData%Vamb_High) ) THEN Int_BufSz = Int_BufSz + 2*1 ! Vamb_High upper/lower bounds for each dimension @@ -3681,16 +3771,6 @@ SUBROUTINE AWAE_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! xhat_plane allocated yes/no - IF ( ALLOCATED(InData%xhat_plane) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! xhat_plane upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%xhat_plane) ! xhat_plane - END IF - Int_BufSz = Int_BufSz + 1 ! rhat_plane allocated yes/no - IF ( ALLOCATED(InData%rhat_plane) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! rhat_plane upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%rhat_plane) ! rhat_plane - END IF Int_BufSz = Int_BufSz + 1 ! parallelFlag allocated yes/no IF ( ALLOCATED(InData%parallelFlag) ) THEN Int_BufSz = Int_BufSz + 2*2 ! parallelFlag upper/lower bounds for each dimension @@ -3726,16 +3806,6 @@ SUBROUTINE AWAE_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_BufSz = Int_BufSz + 2*3 ! pvec_ce upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%pvec_ce) ! pvec_ce END IF - Int_BufSz = Int_BufSz + 1 ! Vx_wake allocated yes/no - IF ( ALLOCATED(InData%Vx_wake) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Vx_wake upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Vx_wake) ! Vx_wake - END IF - Int_BufSz = Int_BufSz + 1 ! Vr_wake allocated yes/no - IF ( ALLOCATED(InData%Vr_wake) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Vr_wake upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Vr_wake) ! Vr_wake - END IF Int_BufSz = Int_BufSz + 1 ! outVizXYPlane allocated yes/no IF ( ALLOCATED(InData%outVizXYPlane) ) THEN Int_BufSz = Int_BufSz + 2*4 ! outVizXYPlane upper/lower bounds for each dimension @@ -3949,6 +4019,36 @@ SUBROUTINE AWAE_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%Vdist_low_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%Vdist_low_full,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vdist_low_full,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vdist_low_full,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vdist_low_full,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vdist_low_full,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vdist_low_full,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vdist_low_full,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vdist_low_full,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%Vdist_low_full,4), UBOUND(InData%Vdist_low_full,4) + DO i3 = LBOUND(InData%Vdist_low_full,3), UBOUND(InData%Vdist_low_full,3) + DO i2 = LBOUND(InData%Vdist_low_full,2), UBOUND(InData%Vdist_low_full,2) + DO i1 = LBOUND(InData%Vdist_low_full,1), UBOUND(InData%Vdist_low_full,1) + ReKiBuf(Re_Xferred) = InData%Vdist_low_full(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF IF ( .NOT. ALLOCATED(InData%Vamb_High) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -3990,46 +4090,6 @@ SUBROUTINE AWAE_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%xhat_plane) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%xhat_plane,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%xhat_plane,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%xhat_plane,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%xhat_plane,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%xhat_plane,2), UBOUND(InData%xhat_plane,2) - DO i1 = LBOUND(InData%xhat_plane,1), UBOUND(InData%xhat_plane,1) - ReKiBuf(Re_Xferred) = InData%xhat_plane(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%rhat_plane) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%rhat_plane,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%rhat_plane,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%rhat_plane,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%rhat_plane,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%rhat_plane,2), UBOUND(InData%rhat_plane,2) - DO i1 = LBOUND(InData%rhat_plane,1), UBOUND(InData%rhat_plane,1) - ReKiBuf(Re_Xferred) = InData%rhat_plane(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF IF ( .NOT. ALLOCATED(InData%parallelFlag) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -4190,36 +4250,6 @@ SUBROUTINE AWAE_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Vx_wake) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%Vx_wake,1), UBOUND(InData%Vx_wake,1) - ReKiBuf(Re_Xferred) = InData%Vx_wake(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%Vr_wake) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vr_wake,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vr_wake,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%Vr_wake,1), UBOUND(InData%Vr_wake,1) - ReKiBuf(Re_Xferred) = InData%Vr_wake(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF IF ( .NOT. ALLOCATED(InData%outVizXYPlane) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -4584,6 +4614,39 @@ SUBROUTINE AWAE_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vdist_low_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 + 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%Vdist_low_full)) DEALLOCATE(OutData%Vdist_low_full) + ALLOCATE(OutData%Vdist_low_full(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%Vdist_low_full.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%Vdist_low_full,4), UBOUND(OutData%Vdist_low_full,4) + DO i3 = LBOUND(OutData%Vdist_low_full,3), UBOUND(OutData%Vdist_low_full,3) + DO i2 = LBOUND(OutData%Vdist_low_full,2), UBOUND(OutData%Vdist_low_full,2) + DO i1 = LBOUND(OutData%Vdist_low_full,1), UBOUND(OutData%Vdist_low_full,1) + OutData%Vdist_low_full(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vamb_High not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -4640,52 +4703,6 @@ SUBROUTINE AWAE_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! xhat_plane not allocated - Int_Xferred = Int_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%xhat_plane)) DEALLOCATE(OutData%xhat_plane) - ALLOCATE(OutData%xhat_plane(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%xhat_plane.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%xhat_plane,2), UBOUND(OutData%xhat_plane,2) - DO i1 = LBOUND(OutData%xhat_plane,1), UBOUND(OutData%xhat_plane,1) - OutData%xhat_plane(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! rhat_plane not allocated - Int_Xferred = Int_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%rhat_plane)) DEALLOCATE(OutData%rhat_plane) - ALLOCATE(OutData%rhat_plane(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%rhat_plane.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%rhat_plane,2), UBOUND(OutData%rhat_plane,2) - DO i1 = LBOUND(OutData%rhat_plane,1), UBOUND(OutData%rhat_plane,1) - OutData%rhat_plane(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! parallelFlag not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -4867,42 +4884,6 @@ SUBROUTINE AWAE_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vx_wake not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Vx_wake)) DEALLOCATE(OutData%Vx_wake) - ALLOCATE(OutData%Vx_wake(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vx_wake.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%Vx_wake,1), UBOUND(OutData%Vx_wake,1) - OutData%Vx_wake(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vr_wake not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Vr_wake)) DEALLOCATE(OutData%Vr_wake) - ALLOCATE(OutData%Vr_wake(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vr_wake.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%Vr_wake,1), UBOUND(OutData%Vr_wake,1) - OutData%Vr_wake(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! outVizXYPlane not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -5241,17 +5222,29 @@ SUBROUTINE AWAE_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%NumTurbines = SrcParamData%NumTurbines DstParamData%NumRadii = SrcParamData%NumRadii DstParamData%NumPlanes = SrcParamData%NumPlanes -IF (ALLOCATED(SrcParamData%r)) THEN - i1_l = LBOUND(SrcParamData%r,1) - i1_u = UBOUND(SrcParamData%r,1) - IF (.NOT. ALLOCATED(DstParamData%r)) THEN - ALLOCATE(DstParamData%r(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%y)) THEN + i1_l = LBOUND(SrcParamData%y,1) + i1_u = UBOUND(SrcParamData%y,1) + IF (.NOT. ALLOCATED(DstParamData%y)) THEN + ALLOCATE(DstParamData%y(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%y.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%y = SrcParamData%y +ENDIF +IF (ALLOCATED(SrcParamData%z)) THEN + i1_l = LBOUND(SrcParamData%z,1) + i1_u = UBOUND(SrcParamData%z,1) + IF (.NOT. ALLOCATED(DstParamData%z)) THEN + ALLOCATE(DstParamData%z(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%r.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%z.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%r = SrcParamData%r + DstParamData%z = SrcParamData%z ENDIF DstParamData%Mod_AmbWind = SrcParamData%Mod_AmbWind DstParamData%nX_low = SrcParamData%nX_low @@ -5393,6 +5386,7 @@ SUBROUTINE AWAE_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%Mod_Meander = SrcParamData%Mod_Meander DstParamData%C_Meander = SrcParamData%C_Meander DstParamData%C_ScaleDiam = SrcParamData%C_ScaleDiam + DstParamData%Mod_Projection = SrcParamData%Mod_Projection IF (ALLOCATED(SrcParamData%IfW)) THEN i1_l = LBOUND(SrcParamData%IfW,1) i1_u = UBOUND(SrcParamData%IfW,1) @@ -5455,17 +5449,32 @@ SUBROUTINE AWAE_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%VTK_tWidth = SrcParamData%VTK_tWidth END SUBROUTINE AWAE_CopyParam - SUBROUTINE AWAE_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE AWAE_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AWAE_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(ParamData%r)) THEN - DEALLOCATE(ParamData%r) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(ParamData%y)) THEN + DEALLOCATE(ParamData%y) +ENDIF +IF (ALLOCATED(ParamData%z)) THEN + DEALLOCATE(ParamData%z) ENDIF IF (ALLOCATED(ParamData%X0_high)) THEN DEALLOCATE(ParamData%X0_high) @@ -5496,7 +5505,8 @@ SUBROUTINE AWAE_DestroyParam( ParamData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(ParamData%IfW)) THEN DO i1 = LBOUND(ParamData%IfW,1), UBOUND(ParamData%IfW,1) - CALL InflowWind_DestroyParam( ParamData%IfW(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyParam( ParamData%IfW(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%IfW) ENDIF @@ -5550,10 +5560,15 @@ SUBROUTINE AWAE_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 1 ! NumTurbines Int_BufSz = Int_BufSz + 1 ! NumRadii Int_BufSz = Int_BufSz + 1 ! NumPlanes - 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 + 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 ! z allocated yes/no + IF ( ALLOCATED(InData%z) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! z upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%z) ! z END IF Int_BufSz = Int_BufSz + 1 ! Mod_AmbWind Int_BufSz = Int_BufSz + 1 ! nX_low @@ -5624,6 +5639,7 @@ SUBROUTINE AWAE_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 1 ! Mod_Meander Re_BufSz = Re_BufSz + 1 ! C_Meander Re_BufSz = Re_BufSz + 1 ! C_ScaleDiam + Int_BufSz = Int_BufSz + 1 ! Mod_Projection Int_BufSz = Int_BufSz + 1 ! IfW allocated yes/no IF ( ALLOCATED(InData%IfW) ) THEN Int_BufSz = Int_BufSz + 2*1 ! IfW upper/lower bounds for each dimension @@ -5708,18 +5724,33 @@ SUBROUTINE AWAE_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NumPlanes Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%r) ) THEN + 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%z) ) THEN 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) + IntKiBuf( Int_Xferred ) = LBOUND(InData%z,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%z,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%r,1), UBOUND(InData%r,1) - ReKiBuf(Re_Xferred) = InData%r(i1) + DO i1 = LBOUND(InData%z,1), UBOUND(InData%z,1) + ReKiBuf(Re_Xferred) = InData%z(i1) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -5928,6 +5959,8 @@ SUBROUTINE AWAE_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%C_ScaleDiam Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%Mod_Projection + Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%IfW) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -6075,21 +6108,39 @@ SUBROUTINE AWAE_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs Int_Xferred = Int_Xferred + 1 OutData%NumPlanes = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! r not allocated + 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 ! z not allocated Int_Xferred = Int_Xferred + 1 ELSE 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 (ALLOCATED(OutData%z)) DEALLOCATE(OutData%z) + ALLOCATE(OutData%z(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%r.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%z.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%r,1), UBOUND(OutData%r,1) - OutData%r(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%z,1), UBOUND(OutData%z,1) + OutData%z(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -6327,6 +6378,8 @@ SUBROUTINE AWAE_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs Re_Xferred = Re_Xferred + 1 OutData%C_ScaleDiam = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%Mod_Projection = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! IfW not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -6534,18 +6587,31 @@ SUBROUTINE AWAE_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Err ENDIF END SUBROUTINE AWAE_CopyOutput - SUBROUTINE AWAE_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE AWAE_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AWAE_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%Vdist_High)) THEN DO i1 = LBOUND(OutputData%Vdist_High,1), UBOUND(OutputData%Vdist_High,1) - CALL AWAE_Destroyhighwindgrid( OutputData%Vdist_High(i1), ErrStat, ErrMsg ) + CALL AWAE_Destroyhighwindgrid( OutputData%Vdist_High(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OutputData%Vdist_High) ENDIF @@ -6921,6 +6987,7 @@ SUBROUTINE AWAE_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg 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 = 'AWAE_CopyInput' @@ -6966,8 +7033,10 @@ SUBROUTINE AWAE_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg i2_u = UBOUND(SrcInputData%Vx_wake,2) i3_l = LBOUND(SrcInputData%Vx_wake,3) i3_u = UBOUND(SrcInputData%Vx_wake,3) + i4_l = LBOUND(SrcInputData%Vx_wake,4) + i4_u = UBOUND(SrcInputData%Vx_wake,4) IF (.NOT. ALLOCATED(DstInputData%Vx_wake)) THEN - ALLOCATE(DstInputData%Vx_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + ALLOCATE(DstInputData%Vx_wake(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 DstInputData%Vx_wake.', ErrStat, ErrMsg,RoutineName) RETURN @@ -6975,21 +7044,41 @@ SUBROUTINE AWAE_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%Vx_wake = SrcInputData%Vx_wake ENDIF -IF (ALLOCATED(SrcInputData%Vr_wake)) THEN - i1_l = LBOUND(SrcInputData%Vr_wake,1) - i1_u = UBOUND(SrcInputData%Vr_wake,1) - i2_l = LBOUND(SrcInputData%Vr_wake,2) - i2_u = UBOUND(SrcInputData%Vr_wake,2) - i3_l = LBOUND(SrcInputData%Vr_wake,3) - i3_u = UBOUND(SrcInputData%Vr_wake,3) - IF (.NOT. ALLOCATED(DstInputData%Vr_wake)) THEN - ALLOCATE(DstInputData%Vr_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) +IF (ALLOCATED(SrcInputData%Vy_wake)) THEN + i1_l = LBOUND(SrcInputData%Vy_wake,1) + i1_u = UBOUND(SrcInputData%Vy_wake,1) + i2_l = LBOUND(SrcInputData%Vy_wake,2) + i2_u = UBOUND(SrcInputData%Vy_wake,2) + i3_l = LBOUND(SrcInputData%Vy_wake,3) + i3_u = UBOUND(SrcInputData%Vy_wake,3) + i4_l = LBOUND(SrcInputData%Vy_wake,4) + i4_u = UBOUND(SrcInputData%Vy_wake,4) + IF (.NOT. ALLOCATED(DstInputData%Vy_wake)) THEN + ALLOCATE(DstInputData%Vy_wake(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 DstInputData%Vr_wake.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%Vy_wake.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInputData%Vr_wake = SrcInputData%Vr_wake + DstInputData%Vy_wake = SrcInputData%Vy_wake +ENDIF +IF (ALLOCATED(SrcInputData%Vz_wake)) THEN + i1_l = LBOUND(SrcInputData%Vz_wake,1) + i1_u = UBOUND(SrcInputData%Vz_wake,1) + i2_l = LBOUND(SrcInputData%Vz_wake,2) + i2_u = UBOUND(SrcInputData%Vz_wake,2) + i3_l = LBOUND(SrcInputData%Vz_wake,3) + i3_u = UBOUND(SrcInputData%Vz_wake,3) + i4_l = LBOUND(SrcInputData%Vz_wake,4) + i4_u = UBOUND(SrcInputData%Vz_wake,4) + IF (.NOT. ALLOCATED(DstInputData%Vz_wake)) THEN + ALLOCATE(DstInputData%Vz_wake(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 DstInputData%Vz_wake.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%Vz_wake = SrcInputData%Vz_wake ENDIF IF (ALLOCATED(SrcInputData%D_wake)) THEN i1_l = LBOUND(SrcInputData%D_wake,1) @@ -7004,18 +7093,46 @@ SUBROUTINE AWAE_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF END IF DstInputData%D_wake = SrcInputData%D_wake +ENDIF +IF (ALLOCATED(SrcInputData%WAT_k_mt)) THEN + i1_l = LBOUND(SrcInputData%WAT_k_mt,1) + i1_u = UBOUND(SrcInputData%WAT_k_mt,1) + i2_l = LBOUND(SrcInputData%WAT_k_mt,2) + i2_u = UBOUND(SrcInputData%WAT_k_mt,2) + i3_l = LBOUND(SrcInputData%WAT_k_mt,3) + i3_u = UBOUND(SrcInputData%WAT_k_mt,3) + IF (.NOT. ALLOCATED(DstInputData%WAT_k_mt)) THEN + ALLOCATE(DstInputData%WAT_k_mt(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%WAT_k_mt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%WAT_k_mt = SrcInputData%WAT_k_mt ENDIF END SUBROUTINE AWAE_CopyInput - SUBROUTINE AWAE_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE AWAE_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AWAE_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%xhat_plane)) THEN DEALLOCATE(InputData%xhat_plane) ENDIF @@ -7025,11 +7142,17 @@ SUBROUTINE AWAE_DestroyInput( InputData, ErrStat, ErrMsg ) IF (ALLOCATED(InputData%Vx_wake)) THEN DEALLOCATE(InputData%Vx_wake) ENDIF -IF (ALLOCATED(InputData%Vr_wake)) THEN - DEALLOCATE(InputData%Vr_wake) +IF (ALLOCATED(InputData%Vy_wake)) THEN + DEALLOCATE(InputData%Vy_wake) +ENDIF +IF (ALLOCATED(InputData%Vz_wake)) THEN + DEALLOCATE(InputData%Vz_wake) ENDIF IF (ALLOCATED(InputData%D_wake)) THEN DEALLOCATE(InputData%D_wake) +ENDIF +IF (ALLOCATED(InputData%WAT_k_mt)) THEN + DEALLOCATE(InputData%WAT_k_mt) ENDIF END SUBROUTINE AWAE_DestroyInput @@ -7080,19 +7203,29 @@ SUBROUTINE AWAE_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END IF Int_BufSz = Int_BufSz + 1 ! Vx_wake allocated yes/no IF ( ALLOCATED(InData%Vx_wake) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! Vx_wake upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + 2*4 ! Vx_wake upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Vx_wake) ! Vx_wake END IF - Int_BufSz = Int_BufSz + 1 ! Vr_wake allocated yes/no - IF ( ALLOCATED(InData%Vr_wake) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! Vr_wake upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Vr_wake) ! Vr_wake + Int_BufSz = Int_BufSz + 1 ! Vy_wake allocated yes/no + IF ( ALLOCATED(InData%Vy_wake) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! Vy_wake upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vy_wake) ! Vy_wake + END IF + Int_BufSz = Int_BufSz + 1 ! Vz_wake allocated yes/no + IF ( ALLOCATED(InData%Vz_wake) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! Vz_wake upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vz_wake) ! Vz_wake END IF Int_BufSz = Int_BufSz + 1 ! D_wake allocated yes/no IF ( ALLOCATED(InData%D_wake) ) THEN Int_BufSz = Int_BufSz + 2*2 ! D_wake upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%D_wake) ! D_wake END IF + Int_BufSz = Int_BufSz + 1 ! WAT_k_mt allocated yes/no + IF ( ALLOCATED(InData%WAT_k_mt) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! WAT_k_mt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WAT_k_mt) ! WAT_k_mt + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -7184,38 +7317,78 @@ SUBROUTINE AWAE_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_Xferred = Int_Xferred + 2 IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake,3) IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake,4) Int_Xferred = Int_Xferred + 2 - DO i3 = LBOUND(InData%Vx_wake,3), UBOUND(InData%Vx_wake,3) - DO i2 = LBOUND(InData%Vx_wake,2), UBOUND(InData%Vx_wake,2) - DO i1 = LBOUND(InData%Vx_wake,1), UBOUND(InData%Vx_wake,1) - ReKiBuf(Re_Xferred) = InData%Vx_wake(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 + DO i4 = LBOUND(InData%Vx_wake,4), UBOUND(InData%Vx_wake,4) + DO i3 = LBOUND(InData%Vx_wake,3), UBOUND(InData%Vx_wake,3) + DO i2 = LBOUND(InData%Vx_wake,2), UBOUND(InData%Vx_wake,2) + DO i1 = LBOUND(InData%Vx_wake,1), UBOUND(InData%Vx_wake,1) + ReKiBuf(Re_Xferred) = InData%Vx_wake(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Vr_wake) ) THEN + IF ( .NOT. ALLOCATED(InData%Vy_wake) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vr_wake,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vr_wake,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake,2) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vr_wake,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vr_wake,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake,3) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vr_wake,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vr_wake,3) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake,4) Int_Xferred = Int_Xferred + 2 - DO i3 = LBOUND(InData%Vr_wake,3), UBOUND(InData%Vr_wake,3) - DO i2 = LBOUND(InData%Vr_wake,2), UBOUND(InData%Vr_wake,2) - DO i1 = LBOUND(InData%Vr_wake,1), UBOUND(InData%Vr_wake,1) - ReKiBuf(Re_Xferred) = InData%Vr_wake(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 + DO i4 = LBOUND(InData%Vy_wake,4), UBOUND(InData%Vy_wake,4) + DO i3 = LBOUND(InData%Vy_wake,3), UBOUND(InData%Vy_wake,3) + DO i2 = LBOUND(InData%Vy_wake,2), UBOUND(InData%Vy_wake,2) + DO i1 = LBOUND(InData%Vy_wake,1), UBOUND(InData%Vy_wake,1) + ReKiBuf(Re_Xferred) = InData%Vy_wake(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Vz_wake) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%Vz_wake,4), UBOUND(InData%Vz_wake,4) + DO i3 = LBOUND(InData%Vz_wake,3), UBOUND(InData%Vz_wake,3) + DO i2 = LBOUND(InData%Vz_wake,2), UBOUND(InData%Vz_wake,2) + DO i1 = LBOUND(InData%Vz_wake,1), UBOUND(InData%Vz_wake,1) + ReKiBuf(Re_Xferred) = InData%Vz_wake(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END DO @@ -7240,6 +7413,31 @@ SUBROUTINE AWAE_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%WAT_k_mt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAT_k_mt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAT_k_mt,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAT_k_mt,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAT_k_mt,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAT_k_mt,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAT_k_mt,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%WAT_k_mt,3), UBOUND(InData%WAT_k_mt,3) + DO i2 = LBOUND(InData%WAT_k_mt,2), UBOUND(InData%WAT_k_mt,2) + DO i1 = LBOUND(InData%WAT_k_mt,1), UBOUND(InData%WAT_k_mt,1) + ReKiBuf(Re_Xferred) = InData%WAT_k_mt(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF END SUBROUTINE AWAE_PackInput SUBROUTINE AWAE_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -7258,6 +7456,7 @@ SUBROUTINE AWAE_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs 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 = 'AWAE_UnPackInput' @@ -7340,22 +7539,27 @@ SUBROUTINE AWAE_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs 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%Vx_wake)) DEALLOCATE(OutData%Vx_wake) - ALLOCATE(OutData%Vx_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + ALLOCATE(OutData%Vx_wake(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%Vx_wake.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i3 = LBOUND(OutData%Vx_wake,3), UBOUND(OutData%Vx_wake,3) - DO i2 = LBOUND(OutData%Vx_wake,2), UBOUND(OutData%Vx_wake,2) - DO i1 = LBOUND(OutData%Vx_wake,1), UBOUND(OutData%Vx_wake,1) - OutData%Vx_wake(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i4 = LBOUND(OutData%Vx_wake,4), UBOUND(OutData%Vx_wake,4) + DO i3 = LBOUND(OutData%Vx_wake,3), UBOUND(OutData%Vx_wake,3) + DO i2 = LBOUND(OutData%Vx_wake,2), UBOUND(OutData%Vx_wake,2) + DO i1 = LBOUND(OutData%Vx_wake,1), UBOUND(OutData%Vx_wake,1) + OutData%Vx_wake(i1,i2,i3,i4) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vr_wake not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vy_wake not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7368,17 +7572,55 @@ SUBROUTINE AWAE_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs i3_l = IntKiBuf( Int_Xferred ) i3_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Vr_wake)) DEALLOCATE(OutData%Vr_wake) - ALLOCATE(OutData%Vr_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vy_wake)) DEALLOCATE(OutData%Vy_wake) + ALLOCATE(OutData%Vy_wake(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%Vr_wake.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vy_wake.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i3 = LBOUND(OutData%Vr_wake,3), UBOUND(OutData%Vr_wake,3) - DO i2 = LBOUND(OutData%Vr_wake,2), UBOUND(OutData%Vr_wake,2) - DO i1 = LBOUND(OutData%Vr_wake,1), UBOUND(OutData%Vr_wake,1) - OutData%Vr_wake(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i4 = LBOUND(OutData%Vy_wake,4), UBOUND(OutData%Vy_wake,4) + DO i3 = LBOUND(OutData%Vy_wake,3), UBOUND(OutData%Vy_wake,3) + DO i2 = LBOUND(OutData%Vy_wake,2), UBOUND(OutData%Vy_wake,2) + DO i1 = LBOUND(OutData%Vy_wake,1), UBOUND(OutData%Vy_wake,1) + OutData%Vy_wake(i1,i2,i3,i4) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vz_wake not allocated + Int_Xferred = Int_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%Vz_wake)) DEALLOCATE(OutData%Vz_wake) + ALLOCATE(OutData%Vz_wake(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%Vz_wake.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%Vz_wake,4), UBOUND(OutData%Vz_wake,4) + DO i3 = LBOUND(OutData%Vz_wake,3), UBOUND(OutData%Vz_wake,3) + DO i2 = LBOUND(OutData%Vz_wake,2), UBOUND(OutData%Vz_wake,2) + DO i1 = LBOUND(OutData%Vz_wake,1), UBOUND(OutData%Vz_wake,1) + OutData%Vz_wake(i1,i2,i3,i4) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END DO @@ -7406,6 +7648,34 @@ SUBROUTINE AWAE_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAT_k_mt not allocated + Int_Xferred = Int_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%WAT_k_mt)) DEALLOCATE(OutData%WAT_k_mt) + ALLOCATE(OutData%WAT_k_mt(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%WAT_k_mt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%WAT_k_mt,3), UBOUND(OutData%WAT_k_mt,3) + DO i2 = LBOUND(OutData%WAT_k_mt,2), UBOUND(OutData%WAT_k_mt,2) + DO i1 = LBOUND(OutData%WAT_k_mt,1), UBOUND(OutData%WAT_k_mt,1) + OutData%WAT_k_mt(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF END SUBROUTINE AWAE_UnPackInput END MODULE AWAE_Types diff --git a/modules/beamdyn/CMakeLists.txt b/modules/beamdyn/CMakeLists.txt index dae656b08..bf44a7168 100644 --- a/modules/beamdyn/CMakeLists.txt +++ b/modules/beamdyn/CMakeLists.txt @@ -18,31 +18,24 @@ if (GENERATE_TYPES) generate_f90_types(src/Registry_BeamDyn.txt ${CMAKE_CURRENT_LIST_DIR}/src/BeamDyn_Types.f90) endif() -set(BD_SOURCES +add_library(beamdynlib src/BeamDyn.f90 src/BeamDyn_IO.f90 src/BeamDyn_BldNdOuts_IO.f90 src/BeamDyn_Subs.f90 src/BeamDyn_Types.f90 - ) - -add_library(beamdynlib ${BD_SOURCES}) +) target_link_libraries(beamdynlib nwtclibs) -install(TARGETS beamdynlib - EXPORT "${CMAKE_PROJECT_NAME}Libraries" - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) - -set(BD_DRIVER_SOURCES +add_executable(beamdyn_driver src/Driver_Beam.f90 - src/Driver_Beam_Subs.f90) - -add_executable(beamdyn_driver ${BD_DRIVER_SOURCES}) -target_link_libraries(beamdyn_driver beamdynlib nwtclibs versioninfolib ${CMAKE_DL_LIBS}) + src/Driver_Beam_Subs.f90 +) +target_link_libraries(beamdyn_driver beamdynlib versioninfolib) -install(TARGETS beamdyn_driver +install(TARGETS beamdynlib beamdyn_driver + EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) + ARCHIVE DESTINATION lib +) \ No newline at end of file diff --git a/modules/beamdyn/src/BeamDyn.f90 b/modules/beamdyn/src/BeamDyn.f90 index 4eaddf4b3..d2354776e 100644 --- a/modules/beamdyn/src/BeamDyn.f90 +++ b/modules/beamdyn/src/BeamDyn.f90 @@ -5438,6 +5438,10 @@ SUBROUTINE BD_InitAcc( u, p, x, m, qdotdot, ErrStat, ErrMsg ) ! Calculate Quadrature point values needed CALL BD_QuadraturePointData( p, x, m ) ! Calculate QP values uuu, uup, RR0, kappa, E1 + ! Reset QP values + CALL BD_QPData_mEta_rho(p, m) + CALL BD_QPDataVelocity(p, x, m) + ! set misc vars, particularly m%RHS CALL BD_CalcForceAcc( u, p, m, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -6519,7 +6523,7 @@ SUBROUTINE BD_JacobianPConstrState( t, u, p, x, xd, z, OtherState, y, m, ErrStat END SUBROUTINE BD_JacobianPConstrState !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ !> Routine to pack the data structures representing the operating points into arrays for linearization. -SUBROUTINE BD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, y_op, x_op, dx_op, xd_op, z_op, NeedPackedOrient ) +SUBROUTINE BD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, y_op, x_op, dx_op, xd_op, z_op, NeedTrimOP ) REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point TYPE(BD_InputType), INTENT(INOUT) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) @@ -6538,7 +6542,7 @@ SUBROUTINE BD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, 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 - LOGICAL, OPTIONAL, INTENT(IN ) :: NeedPackedOrient !< whether a y_op values should contain 3-value representation instead of full orientation matrices + LOGICAL, OPTIONAL, INTENT(IN ) :: NeedTrimOP !< whether a y_op values should contain values for trim solution (3-value representation instead of full orientation matrices, no rotation acc) INTEGER(IntKi) :: index, i, dof INTEGER(IntKi) :: nu @@ -6547,7 +6551,7 @@ SUBROUTINE BD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'BD_GetOP' LOGICAL :: FieldMask(FIELDMASK_SIZE) - LOGICAL :: ReturnSmallAngle + LOGICAL :: ReturnTrimOP TYPE(BD_ContinuousStateType) :: dx ! derivative of continuous states at operating point @@ -6585,10 +6589,10 @@ SUBROUTINE BD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, IF ( PRESENT( y_op ) ) THEN ! Only the y operating points need to potentially return a smaller array than the "normal" call to this return. In the trim solution, we use a smaller array for y. - if (present(NeedPackedOrient)) then - ReturnSmallAngle = NeedPackedOrient + if (present(NeedTrimOP)) then + ReturnTrimOP = NeedTrimOP else - ReturnSmallAngle = .false. + ReturnTrimOP = .false. end if if (.not. allocated(y_op)) then @@ -6599,7 +6603,7 @@ SUBROUTINE BD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, if (ErrStat >= AbortErrLev) return end if - if (ReturnSmallAngle) y_op = 0.0_ReKi ! initialize in case we are returning packed orientations and don't fill the entire array + if (ReturnTrimOP) y_op = 0.0_ReKi ! initialize in case we are returning packed orientations and don't fill the entire array index = 1 call PackLoadMesh(y%ReactionForce, y_op, index) @@ -6611,7 +6615,7 @@ SUBROUTINE BD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, FieldMask(MASKID_RotationVel) = .true. FieldMask(MASKID_TranslationAcc) = .true. FieldMask(MASKID_RotationAcc) = .true. - call PackMotionMesh(y%BldMotion, y_op, index, FieldMask=FieldMask, UseSmlAngle=ReturnSmallAngle) + call PackMotionMesh(y%BldMotion, y_op, index, FieldMask=FieldMask, TrimOP=ReturnTrimOP) index = index - 1 do i=1,p%NumOuts + p%BldNd_TotNumOuts @@ -6711,6 +6715,7 @@ END SUBROUTINE BD_GetOP SUBROUTINE BD_WriteMassStiff( p, m, ErrStat, ErrMsg ) + use YAML, only: yaml_write_array TYPE(BD_ParameterType), INTENT(IN ) :: p !< Parameters TYPE(BD_MiscVarType), INTENT(INOUT) :: m !< misc/optimization variables ! intent(out) so that we can update the accelerations here... INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation @@ -6731,17 +6736,16 @@ SUBROUTINE BD_WriteMassStiff( p, m, ErrStat, ErrMsg ) ! Write out the mass and stiffness in the calculation frame WRITE(m%Un_Sum,'()') - CALL WrMatrix(RESHAPE(m%StifK, (/p%dof_total, p%dof_total/)), m%Un_Sum, p%OutFmt, 'Full stiffness matrix (BD calculation coordinate frame)') + call yaml_write_array(m%Un_Sum, 'K_BD', RESHAPE(m%StifK, (/p%dof_total, p%dof_total/)), p%OutFmt, ErrStat, ErrMsg, comment='Full stiffness matrix (BD calculation coordinate frame).') WRITE(m%Un_Sum,'()') - CALL WrMatrix(RESHAPE(m%MassM, (/p%dof_total, p%dof_total/)), m%Un_Sum, p%OutFmt, 'Full mass matrix (BD calculation coordinate frame)') - - RETURN + call yaml_write_array(m%Un_Sum, 'M_BD', RESHAPE(m%MassM, (/p%dof_total, p%dof_total/)), p%OutFmt, ErrStat, ErrMsg, comment='Full mass matrix (BD calculation coordinate frame)') END SUBROUTINE BD_WriteMassStiff !---------------------------------------------------------------------------------------------------------------------------------- SUBROUTINE BD_WriteMassStiffInFirstNodeFrame( p, x, m, ErrStat, ErrMsg ) + use YAML, only: yaml_write_array TYPE(BD_ParameterType), INTENT(IN ) :: p !< Parameters TYPE(BD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at t TYPE(BD_MiscVarType), INTENT(INOUT) :: m !< misc/optimization variables ! intent(out) so that we can update the accelerations here... @@ -6789,10 +6793,8 @@ SUBROUTINE BD_WriteMassStiffInFirstNodeFrame( p, x, m, ErrStat, ErrMsg ) enddo ! Write out the mass and stiffness in the first node frame - WRITE(m%Un_Sum,'()') - CALL WrMatrix(RESHAPE(TmpStifK, (/p%dof_total, p%dof_total/)), m%Un_Sum, p%OutFmt, 'Full stiffness matrix (IEC blade first node coordinate frame)') - WRITE(m%Un_Sum,'()') - CALL WrMatrix(RESHAPE(TmpMassM, (/p%dof_total, p%dof_total/)), m%Un_Sum, p%OutFmt, 'Full mass matrix (IEC blade first node coordinate frame)') + call yaml_write_array(m%Un_Sum, 'K_IEC', TmpStifK, p%OutFmt, ErrStat, ErrMsg, comment='Full stiffness matrix (IEC blade first node coordinate frame)') + call yaml_write_array(m%Un_Sum, 'M_IEC', TmpMassM, p%OutFmt, ErrStat, ErrMsg, comment='Full mass matrix (IEC blade first node coordinate frame)') diff --git a/modules/beamdyn/src/BeamDyn_BldNdOuts_IO.f90 b/modules/beamdyn/src/BeamDyn_BldNdOuts_IO.f90 index 9cc98cb5d..7cc98b7a0 100644 --- a/modules/beamdyn/src/BeamDyn_BldNdOuts_IO.f90 +++ b/modules/beamdyn/src/BeamDyn_BldNdOuts_IO.f90 @@ -27,7 +27,7 @@ MODULE BeamDyn_BldNdOuts_IO ! Parameters related to output length (number of characters allowed in the output data headers): - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen-6 ! We are making these of the form B1Z###quantity, but note that the glue code adds the "B1" (turbine component) part +! INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen-6 ! We are making these of the form B1Z###quantity, but note that the glue code adds the "B1" (turbine component) part ! =================================================================================================== ! NOTE: The following lines of code were generated by a Matlab script called "Write_ChckOutLst.m" diff --git a/modules/beamdyn/src/BeamDyn_IO.f90 b/modules/beamdyn/src/BeamDyn_IO.f90 index c497b3f19..af3548c49 100644 --- a/modules/beamdyn/src/BeamDyn_IO.f90 +++ b/modules/beamdyn/src/BeamDyn_IO.f90 @@ -44,11 +44,6 @@ MODULE BeamDyn_IO ! This code was generated by Write_ChckOutLst.m at 29-Sep-2015 10:23:41. - ! Parameters related to output length (number of characters allowed in the output data headers): - - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 - - ! Indices for computing output channels: ! NOTES: ! (1) These parameters are in the order stored in "OutListParameters.xlsx" @@ -1114,6 +1109,10 @@ SUBROUTINE BD_ReadBladeFile(BldFile,BladeInputFileData,UnEc,ErrStat,ErrMsg) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) DO i=1,BladeInputFileData%station_total + if (i > 1) then + CALL ReadCom(UnIn,BldFile,'blank line after mass matrix',ErrStat2,ErrMsg2,UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + end if CALL ReadVar(UnIn,BldFile,BladeInputFileData%station_eta(i),'station_eta','Station '//trim(num2lstr(i))//' Eta',ErrStat2,ErrMsg2,UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -1127,7 +1126,8 @@ SUBROUTINE BD_ReadBladeFile(BldFile,BladeInputFileData,UnEc,ErrStat,ErrMsg) return end if BladeInputFileData%stiff0(:,:,i) = temp66 - + CALL ReadCom(UnIn,BldFile,'blank line after stiffness matrix',ErrStat2,ErrMsg2,UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) DO j=1,6 CALL ReadAry(UnIn,BldFile,temp66(j,:),6,'mass_matrix','Blade C/S mass matrix',ErrStat2,ErrMsg2,UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -1916,7 +1916,7 @@ END SUBROUTINE Calc_WriteOutput !---------------------------------------------------------------------------------------------------------------------------------- !> This routine generates the summary file, which contains a regurgitation of the input data and interpolated flexible body data. SUBROUTINE BD_PrintSum( p, x, m, InitInp, ErrStat, ErrMsg ) - + use YAML, only: yaml_write_var, yaml_write_array, yaml_write_list ! passed variables TYPE(BD_ParameterType), INTENT(IN) :: p !< Parameters of the structural dynamics module type(BD_ContinuousStateType), intent(in) :: x !< Continuous states @@ -1935,193 +1935,113 @@ SUBROUTINE BD_PrintSum( p, x, m, InitInp, ErrStat, ErrMsg ) CHARACTER(*), PARAMETER :: FmtDat = '(A,T35,1(:,F13.3))' ! Format for outputting mass and modal data. CHARACTER(*), PARAMETER :: FmtDatT = '(A,T35,1(:,F13.8))' ! Format for outputting time steps. - CHARACTER(30) :: OutPFmt ! Format to print list of selected output channels to summary file + CHARACTER(80) :: OutPFmt ! Format to print list of selected output channels to summary file ! Open the summary file and give it a heading. CALL GetNewUnit( UnSu, ErrStat, ErrMsg ) - CALL OpenFOutFile ( UnSu, TRIM( InitInp%RootName )//'.sum', ErrStat, ErrMsg ) + CALL OpenFOutFile ( UnSu, TRIM( InitInp%RootName )//'.sum.yaml', ErrStat, ErrMsg ) IF ( ErrStat >= AbortErrLev ) RETURN ! Heading: - WRITE (UnSu,'(/,A)') 'This summary information was generated by '//TRIM( GetNVD(BeamDyn_Ver) )// & - ' on '//CurDate()//' at '//CurTime()//'.' - - WRITE (UnSu,'(A,F13.3)') 'Blade mass (kg) ', p%blade_mass - WRITE (UnSu,'(A,F13.3)' ) 'Blade length (m) ', p%blade_length - - WRITE (UnSu,'(A)') 'Blade center of mass (IEC coords): ' - WRITE (UnSu,'(3ES18.5)' ) p%blade_CG(:) - - WRITE (UnSu,'(A)') 'Blade mass moment of inertia: ' - DO i=1,3 - WRITE (UnSu,'(3ES18.5)' ) p%blade_IN(i,:) - ENDDO - - WRITE (UnSu,'(A)') 'Global position vector (IEC coords):' - WRITE (UnSu,'(3ES18.5)' ) p%GlbPos(:) - - WRITE (UnSu,'(A)') 'Global rotation tensor (IEC coords):' - DO i=1,3 - WRITE (UnSu,'(3ES18.5)' ) p%GlbRot(i,:) - ENDDO - - WRITE (UnSu,'(A)') 'Initial blade orientation tensor (relative to global rotation tensor):' - DO i=1,3 - WRITE (UnSu,'(3ES18.5)' ) InitInp%RootOri(i,:) - ENDDO - - WRITE (UnSu,'(A)') 'Global rotation WM parameters (IEC coords):' - WRITE (UnSu,'(3ES18.5)' ) p%Glb_crv(:) - - WRITE (UnSu,'(A)') 'Gravity vector (m/s^2) (IEC coords):' - WRITE (UnSu,'(3ES18.5)' ) p%gravity(:) + WRITE (UnSu,'(A)') '#This summary information was generated by '//TRIM( GetNVD(BeamDyn_Ver) ) + + WRITE (UnSu,'(/,A)') '# --- Main parameters' + call yaml_write_var (UnSu, 'Mass' , p%blade_mass , 'F13.3', ErrStat, ErrMsg, comment='(kg)') + call yaml_write_var (UnSu, 'Length' , p%blade_length , 'F13.3', ErrStat, ErrMsg, comment='(m)') + call yaml_write_list (UnSu, 'CG' , p%blade_CG , 'ES18.5', ErrStat, ErrMsg, comment='Blade center of mass (IEC coords) (m) from blade root') + call yaml_write_array(UnSu, 'JRoot' , p%blade_IN , 'ES18.5', ErrStat, ErrMsg, comment='Blade mass moment of inertia at blade root. NOTE: from mass distribution only, missing some important inertial contributions (see PR#1337)') + call yaml_write_list (UnSu, 'GlbPos' , p%GlbPos , 'ES18.5', ErrStat, ErrMsg, comment='Global position vector (IEC coords) of blade root') + call yaml_write_array(UnSu, 'GlbRot' , p%GlbRot , 'ES18.5', ErrStat, ErrMsg, comment='Global rotation tensor (IEC coords)') + call yaml_write_array(UnSu, 'RootOri' , InitInp%RootOri , 'ES18.5', ErrStat, ErrMsg, comment='Initial blade orientation tensor (relative to global rotation tensor)') + call yaml_write_list (UnSu, 'GlbCrv' , p%Glb_crv , 'ES18.5', ErrStat, ErrMsg, comment='Global rotation WM parameters (IEC coords)') + call yaml_write_list (UnSu, 'Gravity' , p%gravity , 'ES18.5', ErrStat, ErrMsg, comment='Gravity vector (m/s^2) (IEC coords)') !FIXME:analysis_type IF(p%analysis_type .EQ. BD_STATIC_ANALYSIS) THEN - WRITE (UnSu,'(A,T59,A15)') 'Analysis type:','STATIC' + WRITE (UnSu,'(A,T59,A15)') 'Analysis_type:','"STATIC"' ELSEIF(p%analysis_type .EQ. BD_DYNAMIC_ANALYSIS) THEN - WRITE (UnSu,'(A,T59,A15)') 'Analysis type:','DYNAMIC' + WRITE (UnSu,'(A,T59,A15)') 'Analysis_type:','"DYNAMIC"' ELSEIF(p%analysis_type .EQ. BD_DYN_SSS_ANALYSIS) THEN - WRITE (UnSu,'(A,T37,A)') 'Analysis type:','DYNAMIC with quasi-steady-state start' + WRITE (UnSu,'(A,T37,A)') 'Analysis_type:','"DYNAMIC with quasi-steady-state start"' ENDIF - WRITE (UnSu,'(A,T59,1ES15.5)') 'Numerical damping parameter:',p%rhoinf - - WRITE (UnSu,'(A,T59,1ES15.5)') 'Time increment:',p%dt - - WRITE (UnSu,'(A,T59,I15)' ) 'Maximum number of iterations in Newton-Raphson solution:', p%niter - WRITE (UnSu,'(A,T59,1ES15.5)' ) 'Convergence parameter:', p%tol - WRITE (UnSu,'(A,T59,I15)' ) 'Factorization frequency in Newton-Raphson solution:', p%n_fact + call yaml_write_var (UnSu, 'Rhoinf' , p%rhoinf , 'ES15.5', ErrStat, ErrMsg, comment='Numerical damping parameter') + call yaml_write_var (UnSu, 'dt' , p%dt , 'ES15.5', ErrStat, ErrMsg, comment='Time increment') + call yaml_write_var (UnSu, 'niter' , p%niter , 'I15' , ErrStat, ErrMsg, comment='Maximum number of iterations in Newton-Raphson solution') + call yaml_write_var (UnSu, 'tol' , p%tol , 'ES15.5' , ErrStat, ErrMsg, comment='Convergence parameter') + call yaml_write_var (UnSu, 'n_fact' , p%n_fact , 'I15' , ErrStat, ErrMsg, comment='Factorization frequency in Newton-Raphson solution') IF(p%quadrature .EQ. GAUSS_QUADRATURE) THEN - WRITE (UnSu,'(A,T59,A15)') 'Quadrature method: ', 'Gaussian' + WRITE (UnSu,'(A,T59,A15)') 'Quadrature_method: ', 'Gaussian' ELSEIF(p%quadrature .EQ. TRAP_QUADRATURE) THEN - WRITE (UnSu,'(A,T59,A15)') 'Quadrature method: ', 'Trapezoidal' - WRITE (UnSu,'(A,T59,I15)' ) 'FE mesh refinement factor:', p%refine + WRITE (UnSu,'(A,T59,A15)') 'Quadrature_method: ', 'Trapezoidal' + WRITE (UnSu,'(A,T59,I15)' ) 'FE_mesh_refinement_factor:', p%refine ENDIF - - WRITE (UnSu,'(A,T59,I15)' ) 'Number of elements: ', p%elem_total - - WRITE (UnSu,'(A,T59,I15)' ) 'Number of nodes: ', p%node_total - - WRITE (UnSu,'(/,A)') 'Initial position vectors (IEC coordinate system)' - k=1 - DO i=1,p%elem_total - WRITE (UnSu,'(2x,A,I4)') 'Element number: ',i - WRITE (UnSu, '(2x,A,1x,A,1x,3(1x,A))') 'Node', 'Global node',' X ',' Y ',' Z ' - WRITE (UnSu, '(2x,A,1x,A,1x,3(1x,A))') '----', '-----------','-----------------','-----------------','-----------------' - DO j = 1, p%nodes_per_elem - WRITE(UnSu,'(I6,1x,I9,2x,3ES18.5)') j,k,p%uuN0(1:3,j,i) - k=k+1 - ENDDO - k = k-1 - ENDDO - WRITE (UnSu,'(/,A)') 'Initial Weiner-Milenkovic rotation vectors (IEC coordinate system)' - k=1 + WRITE (UnSu,'(A,T59,I15)' ) 'Number_of_elements: ', p%elem_total + WRITE (UnSu,'(A,T59,I15)' ) 'Number_of_nodes: ', p%node_total + + WRITE (UnSu,'(/,A)') '# --- Initial values and conditions' + ! EB: NOTE: information about node and global node were lost here. Can be reintroduced by creating a matrix with indices and u in it. Or use "label" keyword in Yaml. + ! OK until we introduce more elements + WRITE (UnSu,'(A)') '# Initial position and Weiner-Milenkovic rotation vectors of nodes (IEC coordinate system)' + WRITE (UnSu, '("#", 6(2x,A))') ' X ',' Y ',' Z ',' WM_x ',' WM_y ',' WM_z ' + WRITE (UnSu, '("#", 6(2x,A))') ' -----------------','-----------------','-----------------','-----------------','-----------------','-----------------' DO i=1,p%elem_total - WRITE (UnSu,'(2x,A,I4)') 'Element number: ',i - WRITE (UnSu, '(2x,A,1x,A,1x,3(1x,A))') 'Node', 'Global node',' WM_x ',' WM_y ',' WM_z ' - WRITE (UnSu, '(2x,A,1x,A,1x,3(1x,A))') '----', '-----------','-----------------','-----------------','-----------------' - DO j = 1, p%nodes_per_elem - WRITE(UnSu,'(I6,1x,I9,2x,3ES18.5)') j,k,p%uuN0(4:6,j,i) - k=k+1 - ENDDO - k = k-1 + WRITE (UnSu, '("#", 1x,A,I4)') 'Element number: ',i + call yaml_write_array(UnSu, 'Init_Nodes_E'//num2lstr(i), transpose(p%uuN0(1:6,:,i)), 'DummyFmt', ErrStat, ErrMsg, AllFmt='5(ES18.5,","),ES18.5') ENDDO - WRITE (UnSu,'(/,A)') 'Quadrature point position vectors' - k=1 - DO i=1,p%elem_total - WRITE (UnSu,'(2x,A,I4)') 'Element number: ',i - WRITE (UnSu, '(2x,A,1x,A,1x,3(1x,A))') ' QP ', ' Global QP ',' X ',' Y ',' Z ' - WRITE (UnSu, '(2x,A,1x,A,1x,3(1x,A))') '----', '-----------','-----------------','-----------------','-----------------' - DO j = 1, p%nqp - WRITE(UnSu,'(I6,1x,I9,2x,3ES18.5)') j,k,p%uu0(1:3,j,i) - k=k+1 - ENDDO - k = k-1 - ENDDO - WRITE (UnSu,'(/,A)') 'Quadrature point rotation vectors' - k=1 + WRITE (UnSu,'(/,A)') '# Quadrature points position and rotation vectors' + WRITE (UnSu, '("#", 6(2x,A))') ' X ',' Y ',' Z ',' WM_x ',' WM_y ',' WM_z ' + WRITE (UnSu, '("#", 6(2x,A))') ' -----------------','-----------------','-----------------','-----------------','-----------------','-----------------' DO i=1,p%elem_total - WRITE (UnSu,'(2x,A,I4)') 'Element number: ',i - WRITE (UnSu, '(2x,A,1x,A,1x,3(1x,A))') ' QP ', ' Global QP ',' WM_x ',' WM_y ',' WM_z ' - WRITE (UnSu, '(2x,A,1x,A,1x,3(1x,A))') '----', '-----------','-----------------','-----------------','-----------------' - DO j = 1, p%nqp - WRITE(UnSu,'(I6,1x,I9,2x,3ES18.5)') j,k,p%uu0(4:6,j,i) - k=k+1 - ENDDO - k = k-1 + WRITE (UnSu, '("#", 1x,A,I4)') 'Element number: ',i + call yaml_write_array(UnSu, 'Init_QP_E'//num2lstr(i), transpose(p%uu0(1:6,:,i)), 'DummyFmt', ErrStat, ErrMsg, AllFmt='5(ES18.5,","),ES18.5') ENDDO - WRITE (UnSu,'(/,A)') 'Sectional stiffness and mass matrices at quadrature points (in IEC coordinates)' + WRITE (UnSu,'(/,A)') '# Sectional stiffness and mass matrices at quadrature points (in IEC coordinates)' DO i=1,size(p%Stif0_QP,3) - WRITE (UnSu,'(/,A,I4)') 'Quadrature point number: ',i - DO j=1,6 - WRITE(UnSu,'(6ES15.5)') p%Stif0_QP(j,1:6,i) - ENDDO - WRITE(UnSu,'(A)') - DO j=1,6 - WRITE(UnSu,'(6ES15.5)') p%Mass0_QP(j,1:6,i) - ENDDO - ENDDO - - WRITE (UnSu,'(/,A)') 'Initial displacement' - DO i=1,p%node_total - WRITE(UnSu,'(I4,3ES18.5)') i,x%q(1:3,i) - ENDDO - - WRITE (UnSu,'(/,A)') 'Initial rotation' - DO i=1,p%node_total - WRITE(UnSu,'(I4,3ES18.5)') i,x%q(4:6,i) - ENDDO - - WRITE (UnSu,'(/,A)') 'Initial velocity' - DO i=1,p%node_total - WRITE(UnSu,'(I4,3ES18.5)') i,x%dqdt(1:3,i) - ENDDO - - WRITE (UnSu,'(/,A)') 'Initial angular velocity' - DO i=1,p%node_total - WRITE(UnSu,'(I4,3ES18.5)') i,x%dqdt(4:6,i) + WRITE (UnSu,'(A,I4)') '# Quadrature point number: ',i + call yaml_write_array(UnSu, 'Init_K_QP'//num2lstr(i), p%Stif0_QP(:,1:6,i), 'ES15.5', ErrStat, ErrMsg) + call yaml_write_array(UnSu, 'Init_M_QP'//num2lstr(i), p%Mass0_QP(:,1:6,i), 'ES15.5', ErrStat, ErrMsg) ENDDO + call yaml_write_array(UnSu, 'Init_q' , transpose(x%q(1:6,:) ), 'ES18.5', ErrStat, ErrMsg, comment='Initial displacement and rotation') + call yaml_write_array(UnSu, 'Init_dqdt', transpose(x%dqdt(1:6,:)), 'ES18.5', ErrStat, ErrMsg, comment='Initial velocity and angular velocity') + WRITE (UnSu,'(/,A)') '# --- Outputs' select case (p%BldMotionNodeLoc) case (BD_MESH_FE) - WRITE (UnSu, '(/,A)') 'Output nodes located at finite element nodes.' + WRITE (UnSu, '(A)') 'Output_nodes_location: "finite element nodes"' case (BD_MESH_QP) - WRITE (UnSu, '(/,A)') 'Output nodes located at quadrature points.' + WRITE (UnSu, '(A)') 'Output_nodes_location: "quadrature points"' case (BD_MESH_STATIONS) - WRITE (UnSu, '(/,A)') 'Output nodes located at blade propery input station locations.' + WRITE (UnSu, '(A)') 'Output_nodes_location: "blade propery input station locations"' !bjj: need to write where these nodes are located... end select - ! output channels: - OutPFmt = '( I4, 3X,A '//TRIM(Num2LStr(ChanLen))//',1 X, A'//TRIM(Num2LStr(ChanLen))//' )' - WRITE (UnSu,'(//,A,/)') 'Requested Outputs:' - WRITE (UnSu,"( ' Col Parameter Units', /, ' --- -------------- ----------')") + ! Output channels: + OutPFmt = '("# - [", I4, ",", 3X, A'//TRIM(Num2LStr(ChanLen+2))//', "," , 1 X, A'//TRIM(Num2LStr(ChanLen+2))//', "]" )' + WRITE (UnSu, '(A)') "# OutList: # Requested Outputs (Index, Parameter, Unit)" DO I = 0,p%NumOuts - WRITE (UnSu,OutPFmt) I, p%OutParam(I)%Name, p%OutParam(I)%Units + WRITE (UnSu,OutPFmt) I, '"'//trim(p%OutParam(I)%Name)//'"', '"'//trim(p%OutParam(I)%Units)//'"' END DO - WRITE (UnSu,'(15x,A)') - WRITE (UnSu,'(15x,A)') - WRITE (UnSu,'(15x,A)') 'Requested Output Channels at each blade station:' - WRITE (UnSu,'(15x,A)') 'Col Parameter Units' - WRITE (UnSu,'(15x,A)') '---- --------- -----' + WRITE (UnSu,'("#", 15x,A)') + WRITE (UnSu, '(A)') "# OutList_BldNd: # Requested Outputs at each blade station (Index, Parameter, Unit)" DO I = 1,p%BldNd_NumOuts - WRITE (UnSu,OutPFmt) I, p%BldNd_OutParam(I)%Name, p%BldNd_OutParam(I)%Units + WRITE (UnSu,OutPFmt) I, '"'//trim(p%BldNd_OutParam(I)%Name)//'"', '"'//trim(p%BldNd_OutParam(I)%Units)//'"' END DO if ( p%analysis_type /= BD_STATIC_ANALYSIS ) then !dynamic analysis ! we'll add mass and stiffness matrices in the first call to UpdateStates m%Un_Sum = UnSu + WRITE (UnSu,'(/,A)') '# --- System matrices' else CLOSE(UnSu) end if diff --git a/modules/beamdyn/src/BeamDyn_Types.f90 b/modules/beamdyn/src/BeamDyn_Types.f90 index 196dfafaa..2e38e89c9 100644 --- a/modules/beamdyn/src/BeamDyn_Types.f90 +++ b/modules/beamdyn/src/BeamDyn_Types.f90 @@ -366,15 +366,27 @@ SUBROUTINE BD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrSt DstInitInputData%DynamicSolve = SrcInitInputData%DynamicSolve END SUBROUTINE BD_CopyInitInput - SUBROUTINE BD_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BD_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE BD_DestroyInitInput SUBROUTINE BD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -763,22 +775,35 @@ SUBROUTINE BD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, Er ENDIF END SUBROUTINE BD_CopyInitOutput - SUBROUTINE BD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BD_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN DEALLOCATE(InitOutputData%WriteOutputUnt) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitOutputData%kp_coordinate)) THEN DEALLOCATE(InitOutputData%kp_coordinate) ENDIF @@ -1508,15 +1533,27 @@ SUBROUTINE BD_CopyBladeInputData( SrcBladeInputDataData, DstBladeInputDataData, DstBladeInputDataData%damp_flag = SrcBladeInputDataData%damp_flag END SUBROUTINE BD_CopyBladeInputData - SUBROUTINE BD_DestroyBladeInputData( BladeInputDataData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyBladeInputData( BladeInputDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BladeInputData), INTENT(INOUT) :: BladeInputDataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyBladeInputData' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyBladeInputData' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(BladeInputDataData%station_eta)) THEN DEALLOCATE(BladeInputDataData%station_eta) ENDIF @@ -1917,19 +1954,32 @@ SUBROUTINE BD_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrSt DstInputFileData%BldNd_BlOutNd_Str = SrcInputFileData%BldNd_BlOutNd_Str END SUBROUTINE BD_CopyInputFile - SUBROUTINE BD_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BD_InputFile), INTENT(INOUT) :: InputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyInputFile' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyInputFile' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputFileData%kp_member)) THEN DEALLOCATE(InputFileData%kp_member) ENDIF - CALL BD_Destroybladeinputdata( InputFileData%InpBl, ErrStat, ErrMsg ) + CALL BD_Destroybladeinputdata( InputFileData%InpBl, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InputFileData%kp_coordinate)) THEN DEALLOCATE(InputFileData%kp_coordinate) ENDIF @@ -2551,15 +2601,27 @@ SUBROUTINE BD_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrSt ENDIF END SUBROUTINE BD_CopyContState - SUBROUTINE BD_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BD_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%q)) THEN DEALLOCATE(ContStateData%q) ENDIF @@ -2776,15 +2838,27 @@ SUBROUTINE BD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt DstDiscStateData%thetaPD = SrcDiscStateData%thetaPD END SUBROUTINE BD_CopyDiscState - SUBROUTINE BD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BD_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE BD_DestroyDiscState SUBROUTINE BD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2906,15 +2980,27 @@ SUBROUTINE BD_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE BD_CopyConstrState - SUBROUTINE BD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BD_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE BD_DestroyConstrState SUBROUTINE BD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -3062,15 +3148,27 @@ SUBROUTINE BD_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, Er DstOtherStateData%RunQuasiStaticInit = SrcOtherStateData%RunQuasiStaticInit END SUBROUTINE BD_CopyOtherState - SUBROUTINE BD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BD_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OtherStateData%acc)) THEN DEALLOCATE(OtherStateData%acc) ENDIF @@ -3328,15 +3426,27 @@ SUBROUTINE BD_CopyqpParam( SrcqpParamData, DstqpParamData, CtrlCode, ErrStat, Er ENDIF END SUBROUTINE BD_CopyqpParam - SUBROUTINE BD_DestroyqpParam( qpParamData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyqpParam( qpParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(qpParam), INTENT(INOUT) :: qpParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyqpParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyqpParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(qpParamData%mmm)) THEN DEALLOCATE(qpParamData%mmm) ENDIF @@ -4024,15 +4134,27 @@ SUBROUTINE BD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) DstParamData%RelStates = SrcParamData%RelStates END SUBROUTINE BD_CopyParam - SUBROUTINE BD_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BD_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%uuN0)) THEN DEALLOCATE(ParamData%uuN0) ENDIF @@ -4077,7 +4199,8 @@ SUBROUTINE BD_DestroyParam( ParamData, ErrStat, ErrMsg ) 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 ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF @@ -4090,10 +4213,12 @@ SUBROUTINE BD_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%OutNd2NdElem)) THEN DEALLOCATE(ParamData%OutNd2NdElem) ENDIF - CALL BD_Destroyqpparam( ParamData%qp, ErrStat, ErrMsg ) + CALL BD_Destroyqpparam( ParamData%qp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ParamData%BldNd_OutParam)) THEN DO i1 = LBOUND(ParamData%BldNd_OutParam,1), UBOUND(ParamData%BldNd_OutParam,1) - CALL NWTC_Library_Destroyoutparmtype( ParamData%BldNd_OutParam(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%BldNd_OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%BldNd_OutParam) ENDIF @@ -6207,19 +6332,35 @@ SUBROUTINE BD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE BD_CopyInput - SUBROUTINE BD_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BD_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( InputData%RootMotion, ErrStat, ErrMsg ) - CALL MeshDestroy( InputData%PointLoad, ErrStat, ErrMsg ) - CALL MeshDestroy( InputData%DistrLoad, ErrStat, ErrMsg ) - CALL MeshDestroy( InputData%HubMotion, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( InputData%RootMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%PointLoad, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%DistrLoad, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%HubMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE BD_DestroyInput SUBROUTINE BD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -6692,17 +6833,31 @@ SUBROUTINE BD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs ENDIF END SUBROUTINE BD_CopyOutput - SUBROUTINE BD_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BD_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( OutputData%ReactionForce, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%BldMotion, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( OutputData%ReactionForce, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( OutputData%BldMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF @@ -7570,15 +7725,27 @@ SUBROUTINE BD_CopyEqMotionQP( SrcEqMotionQPData, DstEqMotionQPData, CtrlCode, Er ENDIF END SUBROUTINE BD_CopyEqMotionQP - SUBROUTINE BD_DestroyEqMotionQP( EqMotionQPData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyEqMotionQP( EqMotionQPData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(EqMotionQP), INTENT(INOUT) :: EqMotionQPData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyEqMotionQP' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyEqMotionQP' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(EqMotionQPData%uuu)) THEN DEALLOCATE(EqMotionQPData%uuu) ENDIF @@ -10234,20 +10401,37 @@ SUBROUTINE BD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE BD_CopyMisc - SUBROUTINE BD_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE BD_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BD_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'BD_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( MiscData%u_DistrLoad_at_y, ErrStat, ErrMsg ) - CALL MeshDestroy( MiscData%y_BldMotion_at_u, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( MiscData%Map_u_DistrLoad_to_y, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( MiscData%Map_y_BldMotion_to_u, ErrStat, ErrMsg ) - CALL BD_Destroyeqmotionqp( MiscData%qp, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( MiscData%u_DistrLoad_at_y, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( MiscData%y_BldMotion_at_u, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( MiscData%Map_u_DistrLoad_to_y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( MiscData%Map_y_BldMotion_to_u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL BD_Destroyeqmotionqp( MiscData%qp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MiscData%lin_A)) THEN DEALLOCATE(MiscData%lin_A) ENDIF @@ -10338,8 +10522,10 @@ SUBROUTINE BD_DestroyMisc( MiscData, ErrStat, ErrMsg ) IF (ALLOCATED(MiscData%LP_indx)) THEN DEALLOCATE(MiscData%LP_indx) ENDIF - CALL BD_DestroyInput( MiscData%u, ErrStat, ErrMsg ) - CALL BD_DestroyInput( MiscData%u2, ErrStat, ErrMsg ) + CALL BD_DestroyInput( MiscData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL BD_DestroyInput( MiscData%u2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE BD_DestroyMisc SUBROUTINE BD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) diff --git a/modules/beamdyn/src/Driver_Beam.f90 b/modules/beamdyn/src/Driver_Beam.f90 index 18b1f87e6..eed92052d 100644 --- a/modules/beamdyn/src/Driver_Beam.f90 +++ b/modules/beamdyn/src/Driver_Beam.f90 @@ -33,6 +33,7 @@ PROGRAM BeamDyn_Driver_Program REAL(DbKi) :: t_global ! global-loop time marker INTEGER(IntKi) :: n_t_final ! total number of time steps INTEGER(IntKi) :: n_t_global ! global-loop time counter + INTEGER(IntKi) :: n_t_vtk ! global vtk step counter INTEGER(IntKi), parameter :: BD_interp_order = 1 ! order of interpolation/extrapolation ! Module1 Derived-types variables; see Registry_Module1.txt for details @@ -98,9 +99,10 @@ PROGRAM BeamDyn_Driver_Program ! initialize the BD_InitInput values not in the driver input file BD_InitInput%RootName = TRIM(BD_Initinput%InputFile) - BD_InitInput%RootDisp = 0.d0 + BD_InitInput%RootName = TRIM(RootName)//'.BD' + BD_InitInput%RootDisp = MATMUL(BD_InitInput%GlbPos(:),DvrData%RootRelInit) - BD_InitInput%GlbPos(:) BD_InitInput%DynamicSolve = DvrData%DynamicSolve ! QuasiStatic options handled within the BD code. - + t_global = DvrData%t_initial n_t_final = ((DvrData%t_final - DvrData%t_initial) / dt_global ) @@ -156,6 +158,21 @@ PROGRAM BeamDyn_Driver_Program CALL CheckError() END DO + ! Write VTK reference if requested (ref is (0,0,0) + if (DvrData%WrVTK > 0) then + call SetVTKvars() + call MeshWrVTKreference( (/0.0_SiKi, 0.0_SiKi, 0.0_SiKi /), BD_Output%BldMotion, trim(DvrData%VTK_OutFileRoot)//'_BldMotion', ErrStat, ErrMsg ); call CheckError() + call MeshWrVTKreference( (/0.0_SiKi, 0.0_SiKi, 0.0_SiKi /), BD_Input(1)%PointLoad, trim(DvrData%VTK_OutFileRoot)//'_PointLoad', ErrStat, ErrMsg ); call CheckError() + call MeshWrVTKreference( (/0.0_SiKi, 0.0_SiKi, 0.0_SiKi /), BD_Input(1)%DistrLoad, trim(DvrData%VTK_OutFileRoot)//'_DistrLoad', ErrStat, ErrMsg ); call CheckError() + endif + ! Write VTK reference if requested (ref is (0,0,0) + if (DvrData%WrVTK == 2) then + n_t_vtk = 0 + call MeshWrVTK( (/0.0_SiKi, 0.0_SiKi, 0.0_SiKi /), BD_Output%BldMotion, trim(DvrData%VTK_OutFileRoot)//'_BldMotion', n_t_vtk, .true., ErrStat, ErrMsg, DvrData%VTK_tWidth ) + call MeshWrVTK( (/0.0_SiKi, 0.0_SiKi, 0.0_SiKi /), BD_Input(1)%PointLoad, trim(DvrData%VTK_OutFileRoot)//'_PointLoad', n_t_vtk, .true., ErrStat, ErrMsg, DvrData%VTK_tWidth ) + call MeshWrVTK( (/0.0_SiKi, 0.0_SiKi, 0.0_SiKi /), BD_Input(1)%DistrLoad, trim(DvrData%VTK_OutFileRoot)//'_DistrLoad', n_t_vtk, .true., ErrStat, ErrMsg, DvrData%VTK_tWidth ) + call CheckError() + endif !......................... @@ -207,6 +224,18 @@ PROGRAM BeamDyn_Driver_Program CALL Dvr_WriteOutputLine(t_global,DvrOut,BD_Parameter%OutFmt,BD_Output) + ! Write VTK reference if requested (ref is (0,0,0) + if (DvrData%WrVTK == 2) then + if ( MOD( n_t_global, DvrData%n_VTKTime ) == 0 ) then + n_t_vtk = n_t_vtk + 1 + call MeshWrVTK( (/0.0_SiKi, 0.0_SiKi, 0.0_SiKi /), BD_Output%BldMotion, trim(DvrData%VTK_OutFileRoot)//'_BldMotion', n_t_vtk, .true., ErrStat, ErrMsg, DvrData%VTK_tWidth ) + call MeshWrVTK( (/0.0_SiKi, 0.0_SiKi, 0.0_SiKi /), BD_Input(1)%PointLoad, trim(DvrData%VTK_OutFileRoot)//'_PointLoad', n_t_vtk, .true., ErrStat, ErrMsg, DvrData%VTK_tWidth ) + call MeshWrVTK( (/0.0_SiKi, 0.0_SiKi, 0.0_SiKi /), BD_Input(1)%DistrLoad, trim(DvrData%VTK_OutFileRoot)//'_DistrLoad', n_t_vtk, .true., ErrStat, ErrMsg, DvrData%VTK_tWidth ) + call CheckError() + endif + endif + + if ( MOD( n_t_global + 1, 100 ) == 0 ) call SimStatus( TiLstPrn, PrevClockTime, t_global, DvrData%t_final ) ENDDO @@ -263,4 +292,38 @@ subroutine CheckError() end subroutine CheckError + subroutine SetVTKvars() + real(R8Ki) :: TmpTime + real(R8Ki) :: TmpRate + real(R8Ki) :: TotalTime + + DvrData%VTK_OutFileRoot = trim(BD_InitInput%RootName) + n_t_vtk = 0 ! first VTK output number + + ! convert frames-per-second to seconds per sample: + TotalTime = DvrData%t_final - DvrData%t_initial + if ( DvrData%VTK_fps == 0 ) then + TmpTime = TotalTime + dt_global + else + TmpTime = 1.0_R8Ki / DvrData%VTK_fps + endif + + ! now save the number of time steps between VTK file output: + if (TmpTime > TotalTime) then + DvrData%n_VTKTime = HUGE(DvrData%n_VTKTime) + else + DvrData%n_VTKTime = NINT( TmpTime / dt_global ) + ! I'll warn if p%n_VTKTime*p%DT is not TmpTime + IF (DvrData%WrVTK == 2) THEN + TmpRate = DvrData%n_VTKTime*dt_global + if (.not. EqualRealNos(TmpRate, TmpTime)) then + call WrScr('1/VTK_fps is not an integer multiple of DT. FAST will output VTK information at '//& + trim(num2lstr(1.0_DbKi/TmpRate))//' fps, the closest rate possible.') + end if + end if + end if + + DvrData%VTK_tWidth = CEILING( log10( real(n_t_final, ReKi) / DvrData%n_VTKTime ) ) + 1 + end subroutine SetVTKvars + END PROGRAM BeamDyn_Driver_Program diff --git a/modules/beamdyn/src/Driver_Beam_Subs.f90 b/modules/beamdyn/src/Driver_Beam_Subs.f90 index ca4ea3df4..7d8141b7c 100644 --- a/modules/beamdyn/src/Driver_Beam_Subs.f90 +++ b/modules/beamdyn/src/Driver_Beam_Subs.f90 @@ -47,7 +47,13 @@ module BeamDyn_driver_subs REAL(DbKi) :: RootRelInit(3,3) ! Initial root orientation relative to GlbRot REAL(DbKi) :: t_initial REAL(DbKi) :: t_final - REAL(R8Ki) :: w ! magnitude of rotational velocity vector + REAL(R8Ki) :: w ! magnitude of rotational velocity vector + + INTEGER(IntKi) :: WrVTK ! VTK visualization data output: (switch) {0=none; 1=init; 2=animation} + INTEGER(IntKi) :: VTK_fps ! Frame rate for VTK output (frames per second) {will use closest integer multiple of DT} [used only if WrVTK=2] + INTEGER(IntKi) :: n_VTKTime ! Number of time steps between writing VTK files + INTEGER(IntKi) :: VTK_tWidth ! number of digits in the time part of file name + character(1024) :: VTK_OutFileRoot ! rootname for the output file END TYPE @@ -95,187 +101,95 @@ SUBROUTINE BD_ReadDvrFile(DvrInputFile,dt,InitInputData,DvrData,& ErrMsg = "" UnEc = -1 - CALL GetNewUnit(UnIn,ErrStat2,ErrMsg2) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL OpenFInpFile(UnIn,DvrInputFile,ErrStat2,ErrMsg2) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + CALL GetNewUnit(UnIn,ErrStat2,ErrMsg2); if (Failed()) return; + CALL OpenFInpFile(UnIn,DvrInputFile,ErrStat2,ErrMsg2); if (Failed()) return; CALL GetPath( DvrInputFile, PriPath ) ! Input files will be relative to the path where the primary input file is located. !-------------------------- HEADER --------------------------------------------- - CALL ReadCom(UnIn,DvrInputFile,'File Header: Module Version (line 1)',ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ReadStr(UnIn,DvrInputFile,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 + CALL ReadCom(UnIn,DvrInputFile,'File Header: Module Version (line 1)',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadStr(UnIn,DvrInputFile,FTitle,'FTitle','File Header: File Description (line 2)',ErrStat2, ErrMsg2, UnEc); if (Failed()) return; !---------------------- SIMULATION CONTROL -------------------------------------- - CALL ReadCom(UnIn,DvrInputFile,'Section Header: Simulation Control',ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ReadVar(UnIn,DvrInputFile,DvrData%DynamicSolve,'DynamicSolve','Use Dynamic solve (false for static solve).',ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ReadVar(UnIn,DvrInputFile,DvrData%t_initial,'t_initial','Starting time of simulation',ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ReadVar(UnIn,DvrInputFile,DvrData%t_final,"t_final", "Ending time of simulation",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - + CALL ReadCom(UnIn,DvrInputFile,'Section Header: Simulation Control',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%DynamicSolve,'DynamicSolve','Use Dynamic solve (false for static solve).',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%t_initial,'t_initial','Starting time of simulation',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%t_final,"t_final", "Ending time of simulation",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; CALL ReadVar(UnIn,DvrInputFile,dt,"dt", "Time increment size",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) !---------------------- GRAVITY PARAMETER -------------------------------------- CALL ReadCom(UnIn,DvrInputFile,'Section Header: Gravity Parameter',ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) InitInputData%gravity(:) = 0.0_ReKi - CALL ReadVar(UnIn,DvrInputFile,InitInputData%gravity(1),"InitInputData%gravity(1)", "gravity vector X",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,InitInputData%gravity(2),"InitInputData%gravity(2)", "gravity vector Y",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,InitInputData%gravity(3),"InitInputData%gravity(3)", "gravity vector Z",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call cleanup() - return - end if + CALL ReadVar(UnIn,DvrInputFile,InitInputData%gravity(1),"InitInputData%gravity(1)", "gravity vector X",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,InitInputData%gravity(2),"InitInputData%gravity(2)", "gravity vector Y",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,InitInputData%gravity(3),"InitInputData%gravity(3)", "gravity vector Z",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + !---------------------- FRAME PARAMETER -------------------------------------- - CALL ReadCom(UnIn,DvrInputFile,'Section Header: Frame Parameter',ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ReadCom(UnIn,DvrInputFile,'Section Header: Frame Parameter',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; InitInputData%GlbPos(:) = 0.0_ReKi InitInputData%GlbRot(:,:) = 0.0_R8Ki InitInputData%RootOri(:,:) = 0.0_R8Ki - CALL ReadVar(UnIn,DvrInputFile,InitInputData%GlbPos(1),"InitInputData%GlbPos(1)", "position vector X",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,InitInputData%GlbPos(2),"InitInputData%GlbPos(2)", "position vector Y",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,InitInputData%GlbPos(3),"InitInputData%GlbPos(3)", "position vector Z",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ReadVar(UnIn,DvrInputFile,InitInputData%GlbPos(1),"InitInputData%GlbPos(1)", "position vector X",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,InitInputData%GlbPos(2),"InitInputData%GlbPos(2)", "position vector Y",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,InitInputData%GlbPos(3),"InitInputData%GlbPos(3)", "position vector Z",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; - CALL ReadCom(UnIn,DvrInputFile,'Comments on DCM',ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadCom(UnIn,DvrInputFile,'Comments on DCM',ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ReadCom(UnIn,DvrInputFile,'Comments on DCM',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadCom(UnIn,DvrInputFile,'Comments on DCM',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; DO i=1,3 CALL ReadAry(UnIn,DvrInputFile,InitInputData%RootOri(i,:),3,"InitInputData%RootOri",& - "Initial root orientation",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + "Initial root orientation",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; ENDDO - CALL ReadVar(UnIn,DvrInputFile,DvrData%GlbRotBladeT0,"DvrData%GlbRotBladeT0","Is the blade initial orientation also the GlbRot calculation frame",ErrStat2,ErrMSg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - if (ErrStat >= AbortErrLev) then - call cleanup() - return - end if + CALL ReadVar(UnIn,DvrInputFile,DvrData%GlbRotBladeT0,"DvrData%GlbRotBladeT0","Is the blade initial orientation also the GlbRot calculation frame",ErrStat2,ErrMSg2,UnEc); if (Failed()) return; ! Use the initial blade root orientation as the GlbRot reference orientation for all calculations? if ( DvrData%GlbRotBladeT0 ) then - ! Set the GlbRot matrix InitInputData%GlbRot = InitInputData%RootOri - CALL eye( DvrData%RootRelInit, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - + CALL eye( DvrData%RootRelInit, ErrStat2, ErrMsg2 ); if (Failed()) return; else - ! Initialize the GlbRot matrix as the identity. Relative rotation for root to GlbRot DvrData%RootRelInit = InitInputData%RootOri - CALL eye( InitInputData%GlbRot, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - end if - - if (ErrStat >= AbortErrLev) then - call cleanup() - return + CALL eye( InitInputData%GlbRot, ErrStat2, ErrMsg2 ); if (Failed()) return; end if !---------------------- INITIAL VELOCITY PARAMETER -------------------------------- - CALL ReadCom(UnIn,DvrInputFile,'Section Header: Initial Velocity Parameter',ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ReadVar(UnIn,DvrInputFile,InitInputData%RootVel(4),"InitInputData%IniRootVel(1)", "angular velocity vector X",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,InitInputData%RootVel(5),"InitInputData%IniRootVel(2)", "angular velocity vector Y",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,InitInputData%RootVel(6),"InitInputData%IniRootVel(3)", "angular velocity vector Z",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call cleanup() - return - end if - + CALL ReadCom(UnIn,DvrInputFile,'Section Header: Initial Velocity Parameter',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,InitInputData%RootVel(4),"InitInputData%IniRootVel(1)", "angular velocity vector X",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,InitInputData%RootVel(5),"InitInputData%IniRootVel(2)", "angular velocity vector Y",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,InitInputData%RootVel(6),"InitInputData%IniRootVel(3)", "angular velocity vector Z",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; InitInputData%RootVel(1:3) = cross_product(InitInputData%RootVel(4:6),InitInputData%GlbPos(:)) !---------------------- APPLIED FORCE -------------------------------- - CALL ReadCom(UnIn,DvrInputFile,'Section Header: Applied Force',ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ReadVar(UnIn,DvrInputFile,DvrData%DistrLoad(1),"InitInputData%DistrLoad(1)", "Distributed load vector X",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,DvrData%DistrLoad(2),"InitInputData%DistrLoad(2)", "Distributed load vector Y",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,DvrData%DistrLoad(3),"InitInputData%DistrLoad(3)", "Distributed load vector Z",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,DvrData%DistrLoad(4),"InitInputData%DistrLoad(4)", "Distributed load vector X",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,DvrData%DistrLoad(5),"InitInputData%DistrLoad(5)", "Distributed load vector Y",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,DvrData%DistrLoad(6),"InitInputData%DistrLoad(6)", "Distributed load vector Z",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,DvrData%TipLoad(1),"InitInputData%TipLoad(1)", "Tip load vector X",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,DvrData%TipLoad(2),"InitInputData%TipLoad(2)", "Tip load vector Y",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,DvrData%TipLoad(3),"InitInputData%TipLoad(3)", "Tip load vector Z",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,DvrData%TipLoad(4),"InitInputData%TipLoad(4)", "Tip load vector X",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,DvrData%TipLoad(5),"InitInputData%TipLoad(5)", "Tip load vector Y",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadVar(UnIn,DvrInputFile,DvrData%TipLoad(6),"InitInputData%TipLoad(6)", "Tip load vector Z",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call cleanup() - return - end if + CALL ReadCom(UnIn,DvrInputFile,'Section Header: Applied Force',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%DistrLoad(1),"InitInputData%DistrLoad(1)", "Distributed load vector X",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%DistrLoad(2),"InitInputData%DistrLoad(2)", "Distributed load vector Y",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%DistrLoad(3),"InitInputData%DistrLoad(3)", "Distributed load vector Z",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%DistrLoad(4),"InitInputData%DistrLoad(4)", "Distributed load vector X",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%DistrLoad(5),"InitInputData%DistrLoad(5)", "Distributed load vector Y",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%DistrLoad(6),"InitInputData%DistrLoad(6)", "Distributed load vector Z",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%TipLoad(1),"InitInputData%TipLoad(1)", "Tip load vector X",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%TipLoad(2),"InitInputData%TipLoad(2)", "Tip load vector Y",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%TipLoad(3),"InitInputData%TipLoad(3)", "Tip load vector Z",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%TipLoad(4),"InitInputData%TipLoad(4)", "Tip load vector X",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%TipLoad(5),"InitInputData%TipLoad(5)", "Tip load vector Y",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%TipLoad(6),"InitInputData%TipLoad(6)", "Tip load vector Z",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; !---------------------- MULTI-POINT LOAD INPUTS ---------------------------------------- !First read into temporary "line" variable so we can check if this is numeric or not (for backward compatibility) - CALL ReadVar(UnIn,DvrInputFile,line,"DvrData%NumPointLoads", "Number of Point Loads (primary input file section header)",ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call cleanup() - return - end if + CALL ReadVar(UnIn,DvrInputFile,line,"DvrData%NumPointLoads", "Number of Point Loads (primary input file section header)",ErrStat2,ErrMsg2,UnEc); if (Failed()) return; READ( Line, *, IOSTAT=IOS) DvrData%NumPointLoads if (IOS == 0) then !this is numeric, so we can go ahead with the multi-point loads - CALL ReadCom(UnIn,DvrInputFile,'Multiple Point Loads Table',ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL ReadCom(UnIn,DvrInputFile,'Multiple Point Loads Table Units',ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocAry(DvrData%MultiPointLoad,max(1,DvrData%NumPointLoads),7,'Point loads input array',ErrStat2,ErrMsg2) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call cleanup() - return - end if - + CALL ReadCom(UnIn,DvrInputFile,'Multiple Point Loads Table',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadCom(UnIn,DvrInputFile,'Multiple Point Loads Table Units',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL AllocAry(DvrData%MultiPointLoad,max(1,DvrData%NumPointLoads),7,'Point loads input array',ErrStat2,ErrMsg2); if (Failed()) return; DvrData%MultiPointLoad = 0.0_ReKi ! this must have at least one node, and it will be initialized to 0 DO i = 1,DvrData%NumPointLoads - CALL ReadAry( UnIn, DvrInputFile, TmpReAry, 7, 'PointLoad', 'Nodal point loads - Node No., DOF No., ', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ReadAry( UnIn, DvrInputFile, TmpReAry, 7, 'PointLoad', 'Nodal point loads - Node No., DOF No., ', ErrStat2, ErrMsg2, UnEc ); if (Failed()) return; DvrData%MultiPointLoad(i,1) = TmpReAry(1) DvrData%MultiPointLoad(i,2) = TmpReAry(2) DvrData%MultiPointLoad(i,3) = TmpReAry(3) @@ -284,37 +198,34 @@ SUBROUTINE BD_ReadDvrFile(DvrInputFile,dt,InitInputData,DvrData,& DvrData%MultiPointLoad(i,6) = TmpReAry(6) DvrData%MultiPointLoad(i,7) = TmpReAry(7) ENDDO - if (ErrStat >= AbortErrLev) then - call cleanup() - return - end if DvrData%NumPointLoads = max(1,DvrData%NumPointLoads) !---------------------- BEAM SECTIONAL PARAMETER ---------------------------------------- - CALL ReadCom(UnIn,DvrInputFile,'Section Header: Primary input file',ErrStat2,ErrMsg2,UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ReadCom(UnIn,DvrInputFile,'Section Header: Primary input file',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; else DvrData%NumPointLoads = 1 - CALL AllocAry(DvrData%MultiPointLoad,DvrData%NumPointLoads,7,'Point loads input array',ErrStat2,ErrMsg2) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (ErrStat >= AbortErrLev) then - call cleanup() - return - end if + CALL AllocAry(DvrData%MultiPointLoad,DvrData%NumPointLoads,7,'Point loads input array',ErrStat2,ErrMsg2); if (Failed()) return; DvrData%MultiPointLoad = 0.0_ReKi end if ! we read the header already !---------------------- BEAM SECTIONAL PARAMETER ---------------------------------------- - CALL ReadVar ( UnIn, DvrInputFile, InitInputData%InputFile, 'InputFile', 'Name of the primary input file', ErrStat2,ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL ReadVar ( UnIn, DvrInputFile, InitInputData%InputFile, 'InputFile', 'Name of the primary input file', ErrStat2,ErrMsg2, UnEc ); if (Failed()) return; IF ( PathIsRelative( InitInputData%InputFile ) ) InitInputData%InputFile = TRIM(PriPath)//TRIM(InitInputData%InputFile) - if (ErrStat >= AbortErrLev) then - call cleanup() - return - end if + !---------------------- Outputs --------------------------------------------------------- + CALL ReadCom(UnIn,DvrInputFile,'Section Header: Outputs',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%WrVTK,'WrVTK','WrVTK',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + CALL ReadVar(UnIn,DvrInputFile,DvrData%VTK_fps,'VTK_fps','VTK_fps',ErrStat2,ErrMsg2,UnEc); if (Failed()) return; + + ! FIXME: added error check here, but probably should be done with more comprehensive error checks on the input file + if (DvrData%WrVTK < 0 .or. DvrData%WrVTK > 2) then + ErrStat2 = ErrID_Fatal; ErrMsg2 = "WrVTK must be 0=none; 1=init; 2=animation"; + if (Failed()) return; + endif + + call cleanup() return @@ -323,7 +234,13 @@ SUBROUTINE BD_ReadDvrFile(DvrInputFile,dt,InitInputData,DvrData,& subroutine cleanup() close(UnIn) return - end subroutine cleanup + end subroutine cleanup + logical function Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'BD_ReadDvrFile') + Failed = ErrStat>=ErrID_Fatal + if (Failed) call cleanup() + return + end function Failed END SUBROUTINE BD_ReadDvrFile SUBROUTINE Dvr_InitializeOutputFile(OutUnit,IntOutput,RootName,ErrStat,ErrMsg) diff --git a/modules/elastodyn/CMakeLists.txt b/modules/elastodyn/CMakeLists.txt index 5610748e9..ce0f1e51b 100644 --- a/modules/elastodyn/CMakeLists.txt +++ b/modules/elastodyn/CMakeLists.txt @@ -18,16 +18,14 @@ if (GENERATE_TYPES) generate_f90_types(src/ElastoDyn_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/ElastoDyn_Types.f90) endif() -set(ED_SOURCES +add_library(elastodynlib src/ElastoDyn.f90 src/ElastoDyn_IO.f90 src/ElastoDyn_AllBldNdOuts_IO.f90 src/ED_UserSubs.f90 src/ElastoDyn_Types.f90 - ) - -add_library(elastodynlib ${ED_SOURCES}) -target_link_libraries(elastodynlib servodynlib nwtclibs) +) +target_link_libraries(elastodynlib nwtclibs) install(TARGETS elastodynlib EXPORT "${CMAKE_PROJECT_NAME}Libraries" diff --git a/modules/elastodyn/src/ED_UserSubs.f90 b/modules/elastodyn/src/ED_UserSubs.f90 index 5184e8159..de368c02e 100644 --- a/modules/elastodyn/src/ED_UserSubs.f90 +++ b/modules/elastodyn/src/ED_UserSubs.f90 @@ -32,9 +32,6 @@ SUBROUTINE UserRFrl ( RFrlDef, RFrlRate, ZTime, DirRoot, RFrlMom ) ! This technique is useful, for example, if the rotor-furl hinge has ! an electromagnetic latch that will unlock and relock the hinge under ! certain specified conditions. - ! Note that this technique WILL NOT work for user-defined routines - ! written for ADAMS datasets extracted using the FAST-to-ADAMS - ! preprocessor. USE Precision @@ -78,9 +75,6 @@ SUBROUTINE UserTeet ( TeetDef, TeetRate, ZTime, DirRoot, TeetMom ) ! This technique is useful, for example, if the teeter hinge has ! an electromagnetic latch that will unlock and relock the hinge under ! certain specified conditions. - ! Note that this technique WILL NOT work for user-defined routines - ! written for ADAMS datasets extracted using the FAST-to-ADAMS - ! preprocessor. USE Precision @@ -124,9 +118,6 @@ SUBROUTINE UserTFrl ( TFrlDef, TFrlRate, ZTime, DirRoot, TFrlMom ) ! This technique is useful, for example, if the tail-furl hinge has ! an electromagnetic latch that will unlock and relock the hinge under ! certain specified conditions. - ! Note that this technique WILL NOT work for user-defined routines - ! written for ADAMS datasets extracted using the FAST-to-ADAMS - ! preprocessor. USE Precision diff --git a/modules/elastodyn/src/ElastoDyn.f90 b/modules/elastodyn/src/ElastoDyn.f90 index ffb058a9f..2bcfb11fc 100644 --- a/modules/elastodyn/src/ElastoDyn.f90 +++ b/modules/elastodyn/src/ElastoDyn.f90 @@ -98,7 +98,6 @@ SUBROUTINE ED_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut TYPE(ED_InputFile) :: InputFileData ! Data stored in the module's input file INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation INTEGER(IntKi) :: i, K ! 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 @@ -127,7 +126,7 @@ SUBROUTINE ED_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut p%Gravity = InitInp%Gravity - CALL ED_ReadInput( InitInp%InputFile, InitInp%ADInputFile, InputFileData, GetAdamsVals, p%BD4Blades, Interval, p%RootName, ErrStat2, ErrMsg2 ) + CALL ED_ReadInput( InitInp%InputFile, InitInp%ADInputFile, InputFileData, p%BD4Blades, Interval, p%RootName, ErrStat2, ErrMsg2 ) CALL CheckError( ErrStat2, ErrMsg2 ) IF ( ErrStat >= AbortErrLev ) RETURN @@ -150,14 +149,14 @@ SUBROUTINE ED_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut END IF - CALL ED_ValidateInput( InputFileData, p%BD4Blades, InitInp%Linearize, ErrStat2, ErrMsg2 ) + CALL ED_ValidateInput( InputFileData, p%BD4Blades, InitInp%Linearize, InitInp%MHK, ErrStat2, ErrMsg2 ) CALL CheckError( ErrStat2, ErrMsg2 ) IF (ErrStat >= AbortErrLev) RETURN !............................................................................................ ! Define parameters here: !............................................................................................ - CALL ED_SetParameters( InputFileData, p, ErrStat2, ErrMsg2 ) + CALL ED_SetParameters( InitInp, InputFileData, p, ErrStat2, ErrMsg2 ) CALL CheckError( ErrStat2, ErrMsg2 ) IF (ErrStat >= AbortErrLev) RETURN @@ -304,7 +303,7 @@ SUBROUTINE ED_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut ! Print the summary file if requested: IF (InputFileData%SumPrint) THEN - CALL ED_PrintSum( p, OtherState, GetAdamsVals, ErrStat2, ErrMsg2 ) + CALL ED_PrintSum( p, OtherState, ErrStat2, ErrMsg2 ) CALL CheckError( ErrStat2, ErrMsg2 ) IF (ErrStat >= AbortErrLev) RETURN END IF @@ -761,10 +760,18 @@ SUBROUTINE ED_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) m%AllOuts( TipRDxb(K) ) = DOT_PRODUCT( m%RtHS%AngPosHM(:,K,p%TipNode), m%CoordSys%j1(K, :) )*R2D m%AllOuts( TipRDyb(K) ) = DOT_PRODUCT( m%RtHS%AngPosHM(:,K,p%TipNode), m%CoordSys%j2(K, :) )*R2D ! There is no sense computing AllOuts( TipRDzc(K) ) here since it is always zero for FAST simulation results. - IF ( rOSTipzn > 0.0 ) THEN ! Tip of blade K is above the yaw bearing. - m%AllOuts(TipClrnc(K) ) = SQRT( rOSTipxn*rOSTipxn + rOSTipyn*rOSTipyn + rOSTipzn*rOSTipzn ) ! Absolute distance from the tower top / yaw bearing to the tip of blade 1. - ELSE ! Tip of blade K is below the yaw bearing. - m%AllOuts(TipClrnc(K) ) = SQRT( rOSTipxn*rOSTipxn + rOSTipyn*rOSTipyn ) ! Perpendicular distance from the yaw axis / tower centerline to the tip of blade 1. + IF ( p%MHK == 2 ) THEN + IF ( rOSTipzn < 0.0 ) THEN ! Tip of blade K is above the yaw bearing. + m%AllOuts(TipClrnc(K) ) = SQRT( rOSTipxn*rOSTipxn + rOSTipyn*rOSTipyn + rOSTipzn*rOSTipzn ) ! Absolute distance from the tower top / yaw bearing to the tip of blade 1. + ELSE ! Tip of blade K is below the yaw bearing. + m%AllOuts(TipClrnc(K) ) = SQRT( rOSTipxn*rOSTipxn + rOSTipyn*rOSTipyn ) ! Perpendicular distance from the yaw axis / tower centerline to the tip of blade 1. + ENDIF + ELSE + IF ( rOSTipzn > 0.0 ) THEN ! Tip of blade K is above the yaw bearing. + m%AllOuts(TipClrnc(K) ) = SQRT( rOSTipxn*rOSTipxn + rOSTipyn*rOSTipyn + rOSTipzn*rOSTipzn ) ! Absolute distance from the tower top / yaw bearing to the tip of blade 1. + ELSE ! Tip of blade K is below the yaw bearing. + m%AllOuts(TipClrnc(K) ) = SQRT( rOSTipxn*rOSTipxn + rOSTipyn*rOSTipyn ) ! Perpendicular distance from the yaw axis / tower centerline to the tip of blade 1. + ENDIF ENDIF END IF @@ -1169,10 +1176,10 @@ SUBROUTINE ED_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) ! Integrate to find FrcFGagT and MomFGagT using all of the nodes / elements above the current strain gage location: DO J = ( p%TwrGagNd(I) + 1 ),p%TwrNodes ! Loop through tower nodes / elements above strain gage node TmpVec2 = FTTower(:,J) - p%MassT(J)*( p%Gravity*m%CoordSys%z2 + LinAccET(:,J) ) ! Portion of FrcFGagT associated with element J - FrcFGagT = FrcFGagT + TmpVec2*p%DHNodes(J) + FrcFGagT = FrcFGagT + TmpVec2*abs(p%DHNodes(J)) TmpVec = CROSS_PRODUCT( m%RtHS%rZT(:,J) - m%RtHS%rZT(:,p%TwrGagNd(I)), TmpVec2 ) ! Portion of MomFGagT associated with element J - MomFGagT = MomFGagT + ( TmpVec + MFHydro(:,J) )*p%DHNodes(J) + MomFGagT = MomFGagT + ( TmpVec + MFHydro(:,J) )*abs(p%DHNodes(J)) ENDDO ! J -Tower nodes / elements above strain gage node ! Add the effects of 1/2 the strain gage element: @@ -1182,12 +1189,12 @@ SUBROUTINE ED_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) TmpVec2 = FTTower(:,p%TwrGagNd(I)) - p%MassT(p%TwrGagNd(I))*( p%Gravity*m%CoordSys%z2 + LinAccET(:,p%TwrGagNd(I))) - FrcFGagT = FrcFGagT + TmpVec2 * 0.5 * p%DHNodes(p%TwrGagNd(I)) + FrcFGagT = FrcFGagT + TmpVec2 * 0.5 * abs(p%DHNodes(p%TwrGagNd(I))) FrcFGagT = 0.001*FrcFGagT ! Convert the local force to kN TmpVec = CROSS_PRODUCT( ( 0.25_R8Ki*p%DHNodes( p%TwrGagNd(I)) )*m%CoordSys%a2, TmpVec2 ) ! Portion of MomFGagT associated with 1/2 of the strain gage element TmpVec = TmpVec + MFHydro(:,p%TwrGagNd(I)) - MomFGagT = MomFGagT + TmpVec * 0.5 * p%DHNodes(p%TwrGagNd(I)) + MomFGagT = MomFGagT + TmpVec * 0.5 * abs(p%DHNodes(p%TwrGagNd(I))) MomFGagT = 0.001*MomFGagT ! Convert the local moment to kN-m m%AllOuts( TwHtFLxt(I) ) = DOT_PRODUCT( FrcFGagT, m%CoordSys%t1(p%TwrGagNd(I),:) ) @@ -1576,6 +1583,35 @@ SUBROUTINE ED_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) y%RotorFurlMotion14%RotationVel(1,1) = m%RtHS%AngVelER(1) y%RotorFurlMotion14%RotationVel(2,1) = -1.*m%RtHS%AngVelER(3) y%RotorFurlMotion14%RotationVel(3,1) = m%RtHS%AngVelER(2) + + !........... + ! TailFin : + !........... + ! Translation (absolute position - starting position): + y%TFinCMMotion%TranslationDisp(1,1) = m%RtHS%rJ(1) + y%TFinCMMotion%TranslationDisp(2,1) = -1.*m%RtHS%rJ(3) + y%TFinCMMotion%TranslationDisp(3,1) = m%RtHS%rJ(2) + p%PtfmRefzt + y%TFinCMMotion%TranslationDisp = y%TFinCMMotion%TranslationDisp - y%TFinCMMotion%Position + ! Orientation: + y%TFinCMMotion%Orientation(1,1,1) = m%CoordSys%tf1(1) + y%TFinCMMotion%Orientation(2,1,1) = m%CoordSys%tf2(1) + y%TFinCMMotion%Orientation(3,1,1) = m%CoordSys%tf3(1) + y%TFinCMMotion%Orientation(1,2,1) = -1.*m%CoordSys%tf1(3) + y%TFinCMMotion%Orientation(2,2,1) = -1.*m%CoordSys%tf2(3) + y%TFinCMMotion%Orientation(3,2,1) = -1.*m%CoordSys%tf3(3) + y%TFinCMMotion%Orientation(1,3,1) = m%CoordSys%tf1(2) + y%TFinCMMotion%Orientation(2,3,1) = m%CoordSys%tf2(2) + y%TFinCMMotion%Orientation(3,3,1) = m%CoordSys%tf3(2) + ! Rotational velocity: + y%TFinCMMotion%RotationVel(1,1) = m%RtHS%AngVelEA(1) + y%TFinCMMotion%RotationVel(2,1) = -1.*m%RtHS%AngVelEA(3) + y%TFinCMMotion%RotationVel(3,1) = m%RtHS%AngVelEA(2) + ! Linear velocity: + y%TFinCMMotion%TranslationVel(1,1) = m%RtHS%LinVelEJ(1) + y%TFinCMMotion%TranslationVel(2,1) = -1.*m%RtHS%LinVelEJ(3) + y%TFinCMMotion%TranslationVel(3,1) = m%RtHS%LinVelEJ(2) + + !........... ! Nacelle : @@ -2009,9 +2045,10 @@ END SUBROUTINE ED_CalcConstrStateResidual !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine sets the parameters, based on the data stored in InputFileData -SUBROUTINE ED_SetParameters( InputFileData, p, ErrStat, ErrMsg ) +SUBROUTINE ED_SetParameters( InitInp, InputFileData, p, ErrStat, ErrMsg ) !.................................................................................................................................. + TYPE(ED_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization routine TYPE(ED_InputFile), INTENT(IN) :: InputFileData !< Data stored in the module's input file TYPE(ED_ParameterType), INTENT(INOUT) :: p !< The module's parameter data INTEGER(IntKi), INTENT(OUT) :: ErrStat !< The error status code @@ -2030,7 +2067,7 @@ SUBROUTINE ED_SetParameters( InputFileData, p, ErrStat, ErrMsg ) ! Set parameters from primary input file - CALL SetPrimaryParameters( p, InputFileData, ErrStat2, ErrMsg2 ) + CALL SetPrimaryParameters( InitInp, p, InputFileData, ErrStat2, ErrMsg2 ) CALL CheckError( ErrStat2, ErrMsg2 ) IF ( ErrStat >= AbortErrLev ) RETURN @@ -2476,17 +2513,10 @@ SUBROUTINE SetBladeParameters( p, BladeInData, BladeMeshData, ErrStat, ErrMsg ) INTEGER(IntKi ) :: K ! Blade number INTEGER(IntKi ) :: J ! Index for the node arrays INTEGER(IntKi) :: InterpInd ! Index for the interpolation routine - LOGICAL :: SetAdmVals ! Logical to determine if Adams inputs should be set ! initialize variables ErrStat = ErrID_None ErrMsg = '' - - IF (p%BD4Blades) THEN - SetAdmVals = .FALSE. - ELSE - SetAdmVals = ALLOCATED( BladeInData(1)%GJStff ) - END IF ! .............................................................................................................................. @@ -2507,7 +2537,7 @@ SUBROUTINE SetBladeParameters( p, BladeInData, BladeMeshData, ErrStat, ErrMsg ) ! .......... Allocate arrays for the blade parameters being set in this routine ..........: - CALL Alloc_BladeParameters( p, SetAdmVals, ErrStat, ErrMsg ) + CALL Alloc_BladeParameters( p, ErrStat, ErrMsg ) IF ( ErrStat /= ErrID_None ) RETURN @@ -2568,17 +2598,6 @@ SUBROUTINE SetBladeParameters( p, BladeInData, BladeMeshData, ErrStat, ErrMsg ) ! BMassDen MassB Lineal mass density ! FlpStff StiffBF Flapwise stiffness ! EdgStff StiffBE Edgewise stiffness - ! GJStff StiffBGJ Blade torsional stiffness - ! EAStff StiffBEA Blade extensional stiffness - ! Alpha BAlpha Blade flap/twist coupling coefficient - ! FlpIner InerBFlp Blade flap (about local structural yb-axis) mass inertia per unit length - ! EdgIner InerBEdg Blade edge (about local structural xb-axis) mass inertia per unit length - ! PrecrvRef RefAxisxb Blade offset for defining the reference axis from the pitch axis for precurved blades (along xb-axis) - ! PreswpRef RefAxisyb Blade offset for defining the reference axis from the pitch axis for preswept blades (along yb-axis) - ! FlpcgOf cgOffBFlp Blade flap mass cg offset - ! EdgcgOf cgOffBEdg Blade edge mass cg offset - ! FlpEAOf EAOffBFlp Blade flap elastic axis offset - ! EdgEAOf EAOffBEdg Blade edge elastic axis offset ! Define RNodesNorm() which is common to all the blades: @@ -2620,30 +2639,8 @@ SUBROUTINE SetBladeParameters( p, BladeInData, BladeMeshData, ErrStat, ErrMsg ) p%StiffBF (K,J) = InterpAry( x, BladeInData(K)%FlpStff , InterpInd ) p%StiffBE (K,J) = InterpAry( x, BladeInData(K)%EdgStff , InterpInd ) - IF ( SetAdmVals ) THEN - p%StiffBGJ (K,J) = InterpAry( x, BladeInData(K)%GJStff , InterpInd ) - p%StiffBEA (K,J) = InterpAry( x, BladeInData(K)%EAStff , InterpInd ) - p%BAlpha (K,J) = InterpAry( x, BladeInData(K)%Alpha , InterpInd ) - p%InerBFlp (K,J) = InterpAry( x, BladeInData(K)%FlpIner , InterpInd ) - p%InerBEdg (K,J) = InterpAry( x, BladeInData(K)%EdgIner , InterpInd ) - p%RefAxisxb(K,J) = InterpAry( x, BladeInData(K)%PrecrvRef, InterpInd ) - p%RefAxisyb(K,J) = InterpAry( x, BladeInData(K)%PreswpRef, InterpInd ) - p%cgOffBFlp(K,J) = InterpAry( x, BladeInData(K)%FlpcgOf , InterpInd ) - p%cgOffBEdg(K,J) = InterpAry( x, BladeInData(K)%EdgcgOf , InterpInd ) - p%EAOffBFlp(K,J) = InterpAry( x, BladeInData(K)%FlpEAOf , InterpInd ) - p%EAOffBEdg(K,J) = InterpAry( x, BladeInData(K)%EdgEAOf , InterpInd ) - END IF - - - END DO ! J (Blade nodes) - IF ( SetAdmVals ) THEN - ! Set the valus for the tip node - p%RefAxisxb(K,p%TipNode) = BladeInData(K)%PrecrvRef( BladeInData(K)%NBlInpSt ) - p%RefAxisyb(K,p%TipNode) = BladeInData(K)%PreswpRef( BladeInData(K)%NBlInpSt ) - END IF - ! Set the blade damping and stiffness tuner p%BldFDamp(K,:) = BladeInData(K)%BldFlDmp @@ -2709,11 +2706,10 @@ END FUNCTION InterpAry END SUBROUTINE SetBladeParameters !---------------------------------------------------------------------------------------------------------------------------------- !> This routine allocates arrays for the blade parameters. -SUBROUTINE Alloc_BladeParameters( p, AllocAdams, ErrStat, ErrMsg ) +SUBROUTINE Alloc_BladeParameters( p, ErrStat, ErrMsg ) !.................................................................................................................................. TYPE(ED_ParameterType), INTENT(INOUT) :: p !< The parameters of the structural dynamics module - LOGICAL, INTENT(IN) :: AllocAdams !< Logical to determine if Adams inputs should be allocated INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status CHARACTER(*), INTENT(OUT) :: ErrMsg !< Err msg @@ -2745,31 +2741,6 @@ SUBROUTINE Alloc_BladeParameters( p, AllocAdams, ErrStat, ErrMsg ) CALL AllocAry ( p%StiffBE, p%NumBl, p%BldNodes, 'StiffBE' , ErrStat, ErrMsg ); IF ( ErrStat /= ErrID_None ) RETURN - IF ( AllocAdams ) THEN - CALL AllocAry ( p%StiffBGJ, p%NumBl, p%BldNodes, 'StiffBGJ' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%StiffBEA, p%NumBl, p%BldNodes, 'StiffBEA' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%BAlpha, p%NumBl, p%BldNodes, 'BAlpha' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%InerBFlp, p%NumBl, p%BldNodes, 'InerBFlp' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%InerBEdg, p%NumBl, p%BldNodes, 'InerBEdg' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%RefAxisxb, p%NumBl, p%TipNode, 'RefAxisxb' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%RefAxisyb, p%NumBl, p%TipNode, 'RefAxisyb' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%cgOffBFlp, p%NumBl, p%BldNodes, 'cgOffBFlp' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%cgOffBEdg, p%NumBl, p%BldNodes, 'cgOffBEdg' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%EAOffBFlp, p%NumBl, p%BldNodes, 'EAOffBFlp' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%EAOffBEdg, p%NumBl, p%BldNodes, 'EAOffBEdg' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - END IF - CALL AllocAry ( p%BldEDamp, p%NumBl, NumBE, 'BldEDamp' , ErrStat, ErrMsg ) IF ( ErrStat /= ErrID_None ) RETURN CALL AllocAry ( p%BldFDamp, p%NumBl, NumBF, 'BldFDamp' , ErrStat, ErrMsg ) @@ -2791,11 +2762,10 @@ SUBROUTINE Alloc_BladeParameters( p, AllocAdams, ErrStat, ErrMsg ) END SUBROUTINE Alloc_BladeParameters !---------------------------------------------------------------------------------------------------------------------------------- !> This routine allocates arrays for the tower parameters. -SUBROUTINE Alloc_TowerParameters( p, AllocAdams, ErrStat, ErrMsg ) +SUBROUTINE Alloc_TowerParameters( p, ErrStat, ErrMsg ) !.................................................................................................................................. TYPE(ED_ParameterType), INTENT(INOUT) :: p !< The parameters of the structural dynamics module - LOGICAL, INTENT(IN) :: AllocAdams !< Logical to determine if Adams inputs should be allocated INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status CHARACTER(*), INTENT(OUT) :: ErrMsg !< Err msg @@ -2816,20 +2786,6 @@ SUBROUTINE Alloc_TowerParameters( p, AllocAdams, ErrStat, ErrMsg ) CALL AllocAry ( p%StiffTSS, p%TwrNodes, 'StiffTSS' , ErrStat, ErrMsg ) IF ( ErrStat /= ErrID_None ) RETURN - IF ( AllocAdams ) THEN - CALL AllocAry ( p%StiffTGJ, p%TwrNodes, 'StiffTGJ' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%StiffTEA, p%TwrNodes, 'StiffTEA' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%InerTFA, p%TwrNodes, 'InerTFA' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%InerTSS, p%TwrNodes, 'InerTSS' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%cgOffTFA, p%TwrNodes, 'cgOffTFA' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( p%cgOffTSS, p%TwrNodes, 'cgOffTSS' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - END IF ! ! these are for HydroDyn? !CALL AllocAry ( p%DiamT, p%TwrNodes, 'DiamT' , ErrStat, ErrMsg ) @@ -3118,12 +3074,6 @@ SUBROUTINE Alloc_RtHS( RtHS, p, ErrStat, ErrMsg ) ErrMsg = ' Error allocating memory for the PLinVelEJ array.' RETURN ENDIF - ALLOCATE ( RtHS%PLinVelEK(p%NDOF,0:1,3) , STAT=ErrStat ) - IF ( ErrStat /= 0_IntKi ) THEN - ErrStat = ErrID_Fatal - ErrMsg = ' Error allocating memory for the PLinVelEK array.' - RETURN - ENDIF ALLOCATE ( RtHS%PLinVelEP(p%NDOF,0:1,3) , STAT=ErrStat ) IF ( ErrStat /= 0_IntKi ) THEN ErrStat = ErrID_Fatal @@ -3215,15 +3165,13 @@ SUBROUTINE SetTowerParameters( p, InputFileData, ErrStat, ErrMsg ) REAL(ReKi) :: x ! Fractional location between two points in linear interpolation INTEGER(IntKi ) :: J ! Index for the node arrays INTEGER(IntKi) :: InterpInd ! Index for the interpolation routine - LOGICAL :: SetAdmVals ! Logical to determine if Adams inputs should be set ! Initialize data ErrStat = ErrID_None ErrMsg = '' - SetAdmVals = ALLOCATED( InputFileData%TwGJStif ) - CALL Alloc_TowerParameters( p, SetAdmVals, ErrStat, ErrMsg ) + CALL Alloc_TowerParameters( p, ErrStat, ErrMsg ) IF ( ErrStat /= ErrID_None ) RETURN @@ -3256,12 +3204,6 @@ SUBROUTINE SetTowerParameters( p, InputFileData, ErrStat, ErrMsg ) ! TMassDen MassT Lineal mass density ! TwFAStif StiffTFA Tower fore-aft stiffness ! TwSSStif StiffTSS Tower side-to-side stiffness - ! TwGJStif StiffTGJ Tower torsional stiffness - ! TwEAStif StiffTEA Tower extensional stiffness - ! TwFAIner InerTFA Tower fore-aft (about yt-axis) mass inertia per unit length - ! TwSSIner InerTSS Tower side-to-side (about xt-axis) mass inertia per unit length - ! TwFAcgOf cgOffTFA Tower fore-aft mass cg offset - ! TwSScgOf cgOffTSS Tower side-to-side mass cg offset InterpInd = 1 @@ -3273,18 +3215,9 @@ SUBROUTINE SetTowerParameters( p, InputFileData, ErrStat, ErrMsg ) p%StiffTFA (J) = InterpStp( p%HNodesNorm(J), InputFileData%HtFract, InputFileData%TwFAStif, InterpInd, InputFileData%NTwInpSt ) p%StiffTSS (J) = InterpStp( p%HNodesNorm(J), InputFileData%HtFract, InputFileData%TwSSStif, InterpInd, InputFileData%NTwInpSt ) END DO ! J - - - IF ( SetAdmVals ) THEN ! An ADAMS model will be created; thus, read in all the cols. - DO J=1,p%TwrNodes - p%StiffTGJ (J) = InterpStp( p%HNodesNorm(J), InputFileData%HtFract, InputFileData%TwGJStif, InterpInd, InputFileData%NTwInpSt ) - p%StiffTEA (J) = InterpStp( p%HNodesNorm(J), InputFileData%HtFract, InputFileData%TwEAStif, InterpInd, InputFileData%NTwInpSt ) - p%InerTFA (J) = InterpStp( p%HNodesNorm(J), InputFileData%HtFract, InputFileData%TwFAIner, InterpInd, InputFileData%NTwInpSt ) - p%InerTSS (J) = InterpStp( p%HNodesNorm(J), InputFileData%HtFract, InputFileData%TwSSIner, InterpInd, InputFileData%NTwInpSt ) - p%cgOffTFA (J) = InterpStp( p%HNodesNorm(J), InputFileData%HtFract, InputFileData%TwFAcgOf, InterpInd, InputFileData%NTwInpSt ) - p%cgOffTSS (J) = InterpStp( p%HNodesNorm(J), InputFileData%HtFract, InputFileData%TwSScgOf, InterpInd, InputFileData%NTwInpSt ) - END DO ! J - END IF + p%MassT = abs(p%MassT) + p%StiffTFA = abs(p%StiffTFA) + p%StiffTSS = abs(p%StiffTSS) !............................................................................................................................... @@ -3356,7 +3289,6 @@ SUBROUTINE SetFurlParameters( p, InputFileData, ErrStat, ErrMsg ) p%RFrlSpr = InputFileData%RFrlSpr p%RFrlDmp = InputFileData%RFrlDmp - p%RFrlCDmp = InputFileData%RFrlCDmp p%RFrlUSSP = InputFileData%RFrlUSSP p%RFrlDSSP = InputFileData%RFrlDSSP p%RFrlDSSpr= InputFileData%RFrlDSSpr @@ -3368,7 +3300,6 @@ SUBROUTINE SetFurlParameters( p, InputFileData, ErrStat, ErrMsg ) p%TFrlSpr = InputFileData%TFrlSpr p%TFrlDmp = InputFileData%TFrlDmp - p%TFrlCDmp = InputFileData%TFrlCDmp p%TFrlUSSP = InputFileData%TFrlUSSP p%TFrlDSSP = InputFileData%TFrlDSSP p%TFrlUSSpr= InputFileData%TFrlUSSpr @@ -3378,13 +3309,9 @@ SUBROUTINE SetFurlParameters( p, InputFileData, ErrStat, ErrMsg ) p%TFrlUSDmp= InputFileData%TFrlUSDmp p%TFrlDSDmp= InputFileData%TFrlDSDmp - p%RFrlPntxn = InputFileData%RFrlPntxn - p%RFrlPntyn = InputFileData%RFrlPntyn - p%RFrlPntzn = InputFileData%RFrlPntzn + p%RFrlPnt_n = InputFileData%RFrlPnt_n - p%TFrlPntxn = InputFileData%TFrlPntxn - p%TFrlPntyn = InputFileData%TFrlPntyn - p%TFrlPntzn = InputFileData%TFrlPntzn + p%TFrlPnt_n = InputFileData%TFrlPnt_n ! Store sine/cosine values instead of some input angles: @@ -3392,13 +3319,6 @@ SUBROUTINE SetFurlParameters( p, InputFileData, ErrStat, ErrMsg ) p%CShftSkew = COS( REAL(InputFileData%ShftSkew,R8Ki) ) p%SShftSkew = SIN( REAL(InputFileData%ShftSkew,R8Ki) ) - p%CTFinSkew = COS( REAL(InputFileData%TFinSkew, R8Ki) ) - p%STFinSkew = SIN( REAL(InputFileData%TFinSkew, R8Ki) ) - p%CTFinTilt = COS( REAL(InputFileData%TFinTilt, R8Ki) ) - p%STFinTilt = SIN( REAL(InputFileData%TFinTilt, R8Ki) ) - p%CTFinBank = COS( REAL(InputFileData%TFinBank, R8Ki) ) - p%STFinBank = SIN( REAL(InputFileData%TFinBank, R8Ki) ) - p%CRFrlSkew = COS( REAL(InputFileData%RFrlSkew, R8Ki) ) p%SRFrlSkew = SIN( REAL(InputFileData%RFrlSkew, R8Ki) ) p%CRFrlTilt = COS( REAL(InputFileData%RFrlTilt, R8Ki) ) @@ -3429,41 +3349,38 @@ SUBROUTINE SetFurlParameters( p, InputFileData, ErrStat, ErrMsg ) ! Calculate some positions: - p%rWIxn = InputFileData%BoomCMxn - p%TFrlPntxn - p%rWIyn = InputFileData%BoomCMyn - p%TFrlPntyn - p%rWIzn = InputFileData%BoomCMzn - p%TFrlPntzn - - p%rWJxn = InputFileData%TFinCMxn - p%TFrlPntxn - p%rWJyn = InputFileData%TFinCMyn - p%TFrlPntyn - p%rWJzn = InputFileData%TFinCMzn - p%TFrlPntzn + p%rWIxn = InputFileData%BoomCM_n(1) - p%TFrlPnt_n(1) + p%rWIyn = InputFileData%BoomCM_n(2) - p%TFrlPnt_n(2) + p%rWIzn = InputFileData%BoomCM_n(3) - p%TFrlPnt_n(3) - p%rWKxn = InputFileData%TFinCPxn - p%TFrlPntxn - p%rWKyn = InputFileData%TFinCPyn - p%TFrlPntyn - p%rWKzn = InputFileData%TFinCPzn - p%TFrlPntzn + p%rWJxn = InputFileData%TFinCM_n(1) - p%TFrlPnt_n(1) + p%rWJyn = InputFileData%TFinCM_n(2) - p%TFrlPnt_n(2) + p%rWJzn = InputFileData%TFinCM_n(3) - p%TFrlPnt_n(3) - p%rVDxn = InputFileData%RFrlCMxn - p%RFrlPntxn - p%rVDyn = InputFileData%RFrlCMyn - p%RFrlPntyn - p%rVDzn = InputFileData%RFrlCMzn - p%RFrlPntzn + p%rVDxn = InputFileData%RFrlCM_n(1) - p%RFrlPnt_n(1) + p%rVDyn = InputFileData%RFrlCM_n(2) - p%RFrlPnt_n(2) + p%rVDzn = InputFileData%RFrlCM_n(3) - p%RFrlPnt_n(3) - p%rVPxn = 0.0_ReKi - p%RFrlPntxn - p%rVPyn = InputFileData%Yaw2Shft - p%RFrlPntyn + p%rVPxn = 0.0_ReKi - p%RFrlPnt_n(1) + p%rVPyn = InputFileData%Yaw2Shft - p%RFrlPnt_n(2) ! Note: These positions are also used for non-furling machines: - p%rVPzn = InputFileData%Twr2Shft - p%RFrlPntzn - p%rVIMUxn = InputFileData%NcIMUxn - p%RFrlPntxn - p%rVIMUyn = InputFileData%NcIMUyn - p%RFrlPntyn - p%rVIMUzn = InputFileData%NcIMUzn - p%RFrlPntzn + p%rVPzn = InputFileData%Twr2Shft - p%RFrlPnt_n(3) + p%rVIMUxn = InputFileData%NcIMUxn - p%RFrlPnt_n(1) + p%rVIMUyn = InputFileData%NcIMUyn - p%RFrlPnt_n(2) + p%rVIMUzn = InputFileData%NcIMUzn - p%RFrlPnt_n(3) END SUBROUTINE SetFurlParameters !---------------------------------------------------------------------------------------------------------------------------------- !> This takes the primary input file data and sets the corresponding parameters. -SUBROUTINE SetPrimaryParameters( p, InputFileData, ErrStat, ErrMsg ) +SUBROUTINE SetPrimaryParameters( InitInp, p, InputFileData, ErrStat, ErrMsg ) !.................................................................................................................................. ! Passed variables + TYPE(ED_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization routine TYPE(ED_ParameterType), INTENT(INOUT) :: p !< Parameters of the structural dynamics module TYPE(ED_InputFile), INTENT(IN) :: InputFileData !< Data stored in the module's input file INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status @@ -3488,6 +3405,7 @@ SUBROUTINE SetPrimaryParameters( p, InputFileData, ErrStat, ErrMsg ) p%HubRad = InputFileData%HubRad p%method = InputFileData%method p%TwrNodes = InputFileData%TwrNodes + p%MHK = InitInp%MHK p%PtfmCMxt = InputFileData%PtfmCMxt p%PtfmCMyt = InputFileData%PtfmCMyt @@ -3495,9 +3413,15 @@ SUBROUTINE SetPrimaryParameters( p, InputFileData, ErrStat, ErrMsg ) p%DT = InputFileData%DT p%OverHang = InputFileData%OverHang p%ShftGagL = InputFileData%ShftGagL - p%TowerHt = InputFileData%TowerHt - p%TowerBsHt = InputFileData%TowerBsHt - p%PtfmRefzt = InputFileData%PtfmRefzt + IF ( InitInp%MHK == 1 ) THEN + p%TowerHt = InputFileData%TowerHt - InitInp%WtrDpth + p%TowerBsHt = InputFileData%TowerBsHt - InitInp%WtrDpth + p%PtfmRefzt = InputFileData%PtfmRefzt - InitInp%WtrDpth + ELSE + p%TowerHt = InputFileData%TowerHt + p%TowerBsHt = InputFileData%TowerBsHt + p%PtfmRefzt = InputFileData%PtfmRefzt + END IF p%HubMass = InputFileData%HubMass p%GenIner = InputFileData%GenIner @@ -3578,7 +3502,11 @@ SUBROUTINE SetPrimaryParameters( p, InputFileData, ErrStat, ErrMsg ) p%BldFlexL = p%TipRad - p%HubRad ! Length of the flexible portion of the blade. if (p%BD4Blades) p%BldFlexL = 0.0_ReKi - p%rZYzt = InputFileData%PtfmCMzt - p%PtfmRefzt + IF ( InitInp%MHK == 1 ) THEN + p%rZYzt = InputFileData%PtfmCMzt - InitInp%WtrDpth - p%PtfmRefzt + ELSE + p%rZYzt = InputFileData%PtfmCMzt - p%PtfmRefzt + END IF !............................................................................................................................... ! set cosine and sine of Precone and Delta3 angles: @@ -5105,7 +5033,7 @@ SUBROUTINE Coeff(p,InputFileData, ErrStat, ErrMsg) ! Calculate the mass of the current element - p%TElmntMass(J) = p%MassT(J)*p%DHNodes(J) ! Mass of tower element J + p%TElmntMass(J) = p%MassT(J)*abs(p%DHNodes(J)) ! Mass of tower element J ! Integrate to find the tower mass which will be output in .fsm @@ -5179,8 +5107,8 @@ SUBROUTINE Coeff(p,InputFileData, ErrStat, ErrMsg) ! Integrate to find the generalized stiffness of the tower (not including gravitational ! effects). - ElStffFA = p%StiffTFA(J)*p%DHNodes(J) ! Fore-aft stiffness of tower element J - ElStffSS = p%StiffTSS(J)*p%DHNodes(J) ! Side-to-side stiffness of tower element J + ElStffFA = p%StiffTFA(J)*abs(p%DHNodes(J)) ! Fore-aft stiffness of tower element J + ElStffSS = p%StiffTSS(J)*abs(p%DHNodes(J)) ! Side-to-side stiffness of tower element J DO I = 1,2 ! Loop through all tower DOFs in one direction DO L = 1,2 ! Loop through all tower DOFs in one direction @@ -5194,7 +5122,7 @@ SUBROUTINE Coeff(p,InputFileData, ErrStat, ErrMsg) ! Ignore the cross-correlation terms of KTFAGrav (i.e. KTFAGrav(i,j) where i /= j) ! and KTSSGrav since these terms will never be used. - ElmntStff = -TMssAbvNd(J)*p%DHNodes(J)*p%Gravity ! Gravitational stiffness of tower element J + ElmntStff = -TMssAbvNd(J)*abs(p%DHNodes(J))*p%Gravity ! Gravitational stiffness of tower element J DO I = 1,2 ! Loop through all tower DOFs in one direction KTFAGrav(I,I) = KTFAGrav(I,I) + ElmntStff*p%TwrFASF(I,J,1)**2 @@ -6313,18 +6241,6 @@ SUBROUTINE SetCoordSy( t, CoordSys, RtHSdat, BlPitch, p, x, ErrStat, ErrMsg ) CoordSys%tfa = p%CTFrlSkew*p%CTFrlTilt*CoordSys%d1 + p%STFrlTilt*CoordSys%d2 - p%STFrlSkew*p%CTFrlTilt*CoordSys%d3 - ! Tail fin coordinate system: - - CoordSys%p1 = ( p%CTFinSkew*p%CTFinTilt )*CoordSys%tf1 & ! Vector / direction p1 (= tail fin x). - + ( p%STFinTilt )*CoordSys%tf2 & - + ( - p%STFinSkew*p%CTFinTilt )*CoordSys%tf3 - CoordSys%p2 = ( p%STFinSkew*p%STFinBank - p%CTFinSkew*p%STFinTilt*p%CTFinBank )*CoordSys%tf1 & ! Vector / direction p2 (= tail fin z). - + ( p%CTFinTilt*p%CTFinBank )*CoordSys%tf2 & - + ( p%CTFinSkew*p%STFinBank + p%STFinSkew*p%STFinTilt*p%CTFinBank )*CoordSys%tf3 - CoordSys%p3 = ( p%STFinSkew*p%CTFinBank + p%CTFinSkew*p%STFinTilt*p%STFinBank )*CoordSys%tf1 & ! Vector / direction p3 (= tail fin -y). - + ( - p%CTFinTilt*p%STFinBank )*CoordSys%tf2 & - + ( p%CTFinSkew*p%CTFinBank - p%STFinSkew*p%STFinTilt*p%STFinBank )*CoordSys%tf3 - RETURN CONTAINS !............................................................................................................................... @@ -6362,82 +6278,52 @@ END SUBROUTINE SetCoordSy !---------------------------------------------------------------------------------------------------------------------------------- !> This routine computes the rotor-furl moment due to rotor-furl deflection and rate. SUBROUTINE RFurling( t, p, RFrlDef, RFrlRate, RFrlMom ) -!.................................................................................................................................. - ! Passed Variables: REAL(DbKi), INTENT(IN) :: t !< simulation time TYPE(ED_ParameterType), INTENT(IN) :: p !< parameters from the structural dynamics module - REAL(R8Ki), INTENT(IN ) :: RFrlDef !< The rotor-furl deflection, x%QT(DOF_RFrl) REAL(ReKi), INTENT(OUT) :: RFrlMom !< The total moment supplied by the springs, and dampers REAL(R8Ki), INTENT(IN ) :: RFrlRate !< The rotor-furl rate, x%QDT(DOF_RFrl) - - ! Local variables: REAL(ReKi) :: RFrlDMom ! The moment supplied by the rotor-furl dampers REAL(ReKi) :: RFrlSMom ! The moment supplied by the rotor-furl springs - SELECT CASE ( p%RFrlMod ) ! Which rotor-furl model are we using? CASE ( 0_IntKi ) ! None! - RFrlMom = 0.0 - CASE ( 1_IntKi ) ! Standard (using inputs from the FAST furling input file). - ! Linear spring: - RFrlSMom = -p%RFrlSpr*RFrlDef - ! Add spring-stops: - IF ( RFrlDef > p%RFrlUSSP ) THEN ! Up-stop RFrlSMom = RFrlSMom - p%RFrlUSSpr*( RFrlDef - p%RFrlUSSP ) ELSEIF ( RFrlDef < p%RFrlDSSP ) THEN ! Down-stop RFrlSMom = RFrlSMom - p%RFrlDSSpr*( RFrlDef - p%RFrlDSSP ) ENDIF - ! Linear damper: - RFrlDMom = -p%RFrlDmp*RFrlRate - - ! Add coulomb friction: - - IF ( RFrlRate /= 0.0 ) THEN - RFrlDMom = RFrlDMom - SIGN( p%RFrlCDmp, real(RFrlRate,ReKi) ) - ENDIF - - ! Add damper-stops: - IF ( RFrlDef > p%RFrlUSDP ) THEN ! Up-stop RFrlDMom = RFrlDMom - p%RFrlUSDmp*RFrlRate ELSEIF ( RFrlDef < p%RFrlDSDP ) THEN ! Down-stop RFrlDMom = RFrlDMom - p%RFrlDSDmp*RFrlRate ENDIF - ! Total up all the moments. - RFrlMom = RFrlSMom + RFrlDMom - CASE ( 2_IntKi ) ! User-defined rotor-furl spring/damper model. - CALL UserRFrl ( RFrlDef, RFrlRate, t, p%RootName, RFrlMom ) - END SELECT - - RETURN END SUBROUTINE RFurling !---------------------------------------------------------------------------------------------------------------------------------- !> This routine computes the teeter moment due to teeter deflection and rate. @@ -6539,87 +6425,52 @@ END SUBROUTINE Teeter !---------------------------------------------------------------------------------------------------------------------------------- !> This routine computes the tail-furl moment due to tail-furl deflection and rate. SUBROUTINE TFurling( t, p, TFrlDef, TFrlRate, TFrlMom ) -!.................................................................................................................................. - - IMPLICIT NONE - ! Passed Variables: REAL(DbKi), INTENT(IN) :: t !< simulation time TYPE(ED_ParameterType), INTENT(IN) :: p !< parameters from the structural dynamics module - REAL(R8Ki), INTENT(IN ) :: TFrlDef !< The tail-furl deflection, QT(DOF_TFrl). REAL(ReKi), INTENT(OUT) :: TFrlMom !< The total moment supplied by the springs, and dampers. REAL(R8Ki), INTENT(IN ) :: TFrlRate !< The tail-furl rate, QDT(DOF_TFrl). - - ! Local variables: - REAL(ReKi) :: TFrlDMom ! The moment supplied by the tail-furl dampers. REAL(ReKi) :: TFrlSMom ! The moment supplied by the tail-furl springs. - - SELECT CASE ( p%TFrlMod ) ! Which tail-furl model are we using? CASE ( 0_IntKi ) ! None! - TFrlMom = 0.0 - CASE ( 1_IntKi ) ! Standard (using inputs from the FAST furling input file). - ! Linear spring: - TFrlSMom = -p%TFrlSpr*TFrlDef - ! Add spring-stops: - IF ( TFrlDef > p%TFrlUSSP ) THEN ! Up-stop TFrlSMom = TFrlSMom - p%TFrlUSSpr*( TFrlDef - p%TFrlUSSP ) ELSEIF ( TFrlDef < p%TFrlDSSP ) THEN ! Down-stop TFrlSMom = TFrlSMom - p%TFrlDSSpr*( TFrlDef - p%TFrlDSSP ) ENDIF - ! Linear damper: - TFrlDMom = -p%TFrlDmp*TFrlRate - - ! Add coulomb friction: - - IF ( .NOT. EqualRealNos( TFrlRate, 0.0_R8Ki) ) THEN - TFrlDMom = TFrlDMom - SIGN( p%TFrlCDmp, real(TFrlRate,reKi) ) - ENDIF - - ! Add damper-stops: - IF ( TFrlDef > p%TFrlUSDP ) THEN ! Up-stop TFrlDMom = TFrlDMom - p%TFrlUSDmp*TFrlRate ELSEIF ( TFrlDef < p%TFrlDSDP ) THEN ! Down-stop TFrlDMom = TFrlDMom - p%TFrlDSDmp*TFrlRate ENDIF - ! Total up all the moments. - TFrlMom = TFrlSMom + TFrlDMom - CASE ( 2 ) ! User-defined tail-furl spring/damper model. - CALL UserTFrl ( TFrlDef, TFrlRate, t, p%RootName, TFrlMom ) - END SELECT - - - RETURN END SUBROUTINE TFurling !---------------------------------------------------------------------------------------------------------------------------------- !> This function calculates the sign (+/-1) of the low-speed shaft torque for @@ -6666,7 +6517,6 @@ SUBROUTINE CalculatePositions( p, x, CoordSys, RtHSdat ) TYPE(ED_RtHndSide), INTENT(INOUT) :: RtHSdat !< data from the RtHndSid module (contains positions to be set) !Local variables - REAL(R8Ki) :: rK (3) ! Position vector from inertial frame origin to tail fin center of pressure (point K). !REAL(R8Ki) :: rQ (3) ! Position vector from inertial frame origin to apex of rotation (point Q). INTEGER(IntKi) :: J ! Counter for elements @@ -6691,16 +6541,15 @@ SUBROUTINE CalculatePositions( p, x, CoordSys, RtHSdat ) + 2.0*p%AxRedTSS(1,2,p%TTopNode)*x%QT(DOF_TSS1)*x%QT(DOF_TSS2) ) )*CoordSys%a2 & + ( x%QT(DOF_TSS1) + x%QT(DOF_TSS2) )*CoordSys%a3 RtHSdat%rOU = p%NacCMxn*CoordSys%d1 + p%NacCMzn *CoordSys%d2 - p%NacCMyn *CoordSys%d3 ! Position vector from tower-top / base plate (point O) to nacelle center of mass (point U). - RtHSdat%rOV = p%RFrlPntxn*CoordSys%d1 + p%RFrlPntzn*CoordSys%d2 - p%RFrlPntyn*CoordSys%d3 ! Position vector from tower-top / base plate (point O) to specified point on rotor-furl axis (point V). + RtHSdat%rOV = p%RFrlPnt_n(1)*CoordSys%d1 + p%RFrlPnt_n(3)*CoordSys%d2 - p%RFrlPnt_n(2)*CoordSys%d3 ! Position vector from tower-top / base plate (point O) to specified point on rotor-furl axis (point V). RtHSdat%rVIMU = p%rVIMUxn*CoordSys%rf1 + p%rVIMUzn *CoordSys%rf2 - p%rVIMUyn *CoordSys%rf3 ! Position vector from specified point on rotor-furl axis (point V) to nacelle IMU (point IMU). RtHSdat%rVD = p%rVDxn*CoordSys%rf1 + p%rVDzn *CoordSys%rf2 - p%rVDyn *CoordSys%rf3 ! Position vector from specified point on rotor-furl axis (point V) to center of mass of structure that furls with the rotor (not including rotor) (point D). RtHSdat%rVP = p%rVPxn*CoordSys%rf1 + p%rVPzn *CoordSys%rf2 - p%rVPyn *CoordSys%rf3 + p%OverHang*CoordSys%c1 ! Position vector from specified point on rotor-furl axis (point V) to teeter pin (point P). RtHSdat%rPQ = -p%UndSling*CoordSys%g1 ! Position vector from teeter pin (point P) to apex of rotation (point Q). RtHSdat%rQC = p%HubCM*CoordSys%g1 ! Position vector from apex of rotation (point Q) to hub center of mass (point C). - RtHSdat%rOW = p%TFrlPntxn*CoordSys%d1 + p%TFrlPntzn *CoordSys%d2 - p%TFrlPntyn*CoordSys%d3 ! Position vector from tower-top / base plate (point O) to specified point on tail-furl axis (point W). + RtHSdat%rOW = p%TFrlPnt_n(1)*CoordSys%d1 + p%TFrlPnt_n(3) *CoordSys%d2 - p%TFrlPnt_n(2)*CoordSys%d3 ! Position vector from tower-top / base plate (point O) to specified point on tail-furl axis (point W). RtHSdat%rWI = p%rWIxn*CoordSys%tf1 + p%rWIzn*CoordSys%tf2 - p%rWIyn*CoordSys%tf3 ! Position vector from specified point on tail-furl axis (point W) to tail boom center of mass (point I). RtHSdat%rWJ = p%rWJxn*CoordSys%tf1 + p%rWJzn*CoordSys%tf2 - p%rWJyn*CoordSys%tf3 ! Position vector from specified point on tail-furl axis (point W) to tail fin center of mass (point J). - RtHSdat%rWK = p%rWKxn*CoordSys%tf1 + p%rWKzn*CoordSys%tf2 - p%rWKyn*CoordSys%tf3 ! Position vector from specified point on tail-furl axis (point W) to tail fin center of pressure (point K). RtHSdat%rPC = RtHSdat%rPQ + RtHSdat%rQC ! Position vector from teeter pin (point P) to hub center of mass (point C). RtHSdat%rT0O = RtHSdat%rZO - RtHSdat%rZT0 ! Position vector from the tower base (point T(0)) to tower-top / base plate (point O). RtHSdat%rO = RtHSdat%rZ + RtHSdat%rZO ! Position vector from inertial frame origin to tower-top / base plate (point O). @@ -6708,7 +6557,7 @@ SUBROUTINE CalculatePositions( p, x, CoordSys, RtHSdat ) !RtHSdat%rP = RtHSdat%rO + RtHSdat%rOV + RtHSdat%rVP ! Position vector from inertial frame origin to teeter pin (point P). RtHSdat%rP = RtHSdat%rV + RtHSdat%rVP ! Position vector from inertial frame origin to teeter pin (point P). RtHSdat%rQ = RtHSdat%rP + RtHSdat%rPQ ! Position vector from inertial frame origin to apex of rotation (point Q). - rK = RtHSdat%rO + RtHSdat%rOW + RtHSdat%rWK ! Position vector from inertial frame origin to tail fin center of pressure (point K). + RtHSdat%rJ = RtHSdat%rO + RtHSdat%rOW + RtHSdat%rWJ ! Position vector from inertial frame origin to tail fin center of mass (point J). DO K = 1,p%NumBl ! Loop through all blades @@ -7031,19 +6880,16 @@ SUBROUTINE CalculateLinearVelPAcc( p, x, CoordSys, RtHSdat ) TYPE(ED_RtHndSide), INTENT(INOUT) :: RtHSdat !< data from the RtHndSid module (contains positions to be set) ! Local variables - REAL(ReKi) :: LinAccEKt (3) ! "Portion of the linear acceleration of the tail fin center of pressure (point K) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" REAL(ReKi) :: LinAccEPt (3) ! "Portion of the linear acceleration of the teeter pin (point P) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" REAL(ReKi) :: LinAccEQt (3) ! "Portion of the linear acceleration of the apex of rotation (point Q) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" REAL(ReKi) :: LinAccEVt (3) ! "Portion of the linear acceleration of the selected point on the rotor-furl axis (point V) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" REAL(ReKi) :: LinAccEWt (3) ! "Portion of the linear acceleration of the selected point on the tail-furl axis (point W) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" - REAL(ReKi) :: LinVelEK (3) ! "Linear velocity of tail fin center-of-pressure (point K) in the inertia frame" REAL(ReKi) :: LinVelHS (3) ! "Relative linear velocity of the current point on the current blade (point S) in the hub frame (body H)" REAL(ReKi) :: LinVelXO (3) ! "Relative linear velocity of the tower-top / base plate (point O) in the platform (body X)" REAL(ReKi) :: LinVelXT (3) ! "Relative linear velocity of the current point on the tower (point T) in the platform (body X)" REAL(ReKi) :: EwAXrWI (3) ! = AngVelEA X rWI REAL(ReKi) :: EwAXrWJ (3) ! = AngVelEA X rWJ - REAL(ReKi) :: EwAXrWK (3) ! = AngVelEA X rWK REAL(ReKi) :: EwHXrPQ (3) ! = AngVelEH X rPQ REAL(ReKi) :: EwHXrQC (3) ! = AngVelEH X rQC REAL(ReKi) :: EwHXrQS (3) ! = AngVelEH X rQS of the current blade point S. @@ -7075,7 +6921,6 @@ SUBROUTINE CalculateLinearVelPAcc( p, x, CoordSys, RtHSdat ) RtHSdat%LinAccEIMUt = 0.0 RtHSdat%LinAccEIt = 0.0 RtHSdat%LinAccEJt = 0.0 - LinAccEKt = 0.0 RtHSdat%LinAccEOt = 0.0 LinAccEPt = 0.0 LinAccEQt = 0.0 @@ -7112,7 +6957,6 @@ SUBROUTINE CalculateLinearVelPAcc( p, x, CoordSys, RtHSdat ) EwNXrOW = CROSS_PRODUCT( RtHSdat%AngVelEN, RtHSdat%rOW ) ! EwAXrWI = CROSS_PRODUCT( RtHSdat%AngVelEA, RtHSdat%rWI ) ! EwAXrWJ = CROSS_PRODUCT( RtHSdat%AngVelEA, RtHSdat%rWJ ) ! - EwAXrWK = CROSS_PRODUCT( RtHSdat%AngVelEA, RtHSdat%rWK ) ! RtHSdat%PLinVelEZ( :,:,:) = 0.0 @@ -7392,6 +7236,7 @@ SUBROUTINE CalculateLinearVelPAcc( p, x, CoordSys, RtHSdat ) ENDDO ! I - all DOFs associated with the angular motion of the nacelle (body N) + ! Velocities of point I (tail boom center of mass) RtHSdat%PLinVelEI( :,:,:) = RtHSdat%PLinVelEW(:,:,:) DO I = 1,NPA ! Loop through all DOFs associated with the angular motion of the tail (body A) @@ -7407,7 +7252,9 @@ SUBROUTINE CalculateLinearVelPAcc( p, x, CoordSys, RtHSdat ) ENDDO ! I - all DOFs associated with the angular motion of the tail (body A) + ! Velocities of point J (tail fin center of mass) RtHSdat%PLinVelEJ( :,:,:) = RtHSdat%PLinVelEW(:,:,:) + RtHSdat%LinVelEJ = RtHSdat%LinVelEZ DO I = 1,NPA ! Loop through all DOFs associated with the angular motion of the tail (body A) TmpVec0 = CROSS_PRODUCT( RtHSdat%PAngVelEA(PA(I) ,0,:), RtHSdat%rWJ ) @@ -7417,27 +7264,11 @@ SUBROUTINE CalculateLinearVelPAcc( p, x, CoordSys, RtHSdat ) RtHSdat%PLinVelEJ(PA(I),0,:) = TmpVec0 + RtHSdat%PLinVelEJ(PA(I) ,0,:) RtHSdat%PLinVelEJ(PA(I),1,:) = TmpVec1 + TmpVec2 + RtHSdat%PLinVelEJ(PA(I) ,1,:) + RtHSdat%LinVelEJ = RtHSdat%LinVelEJ + x%QDT(PA(I) )*RtHSdat%PLinVelEJ(PA(I) ,0,:) RtHSdat%LinAccEJt = RtHSdat%LinAccEJt + x%QDT(PA(I) )*RtHSdat%PLinVelEJ(PA(I) ,1,:) ENDDO ! I - all DOFs associated with the angular motion of the tail (body A) - RtHSdat%PLinVelEK( :,:,:) = RtHSdat%PLinVelEW(:,:,:) - LinVelEK = RtHSdat%LinVelEZ - DO I = 1,NPA ! Loop through all DOFs associated with the angular motion of the tail (body A) - - TmpVec0 = CROSS_PRODUCT( RtHSdat%PAngVelEA(PA(I) ,0,:), RtHSdat%rWK ) - TmpVec1 = CROSS_PRODUCT( RtHSdat%PAngVelEA(PA(I) ,0,:), EwAXrWK ) - TmpVec2 = CROSS_PRODUCT( RtHSdat%PAngVelEA(PA(I) ,1,:), RtHSdat%rWK ) - - RtHSdat%PLinVelEK(PA(I),0,:) = TmpVec0 + RtHSdat%PLinVelEK(PA(I) ,0,:) - RtHSdat%PLinVelEK(PA(I),1,:) = TmpVec1 + TmpVec2 + RtHSdat%PLinVelEK(PA(I) ,1,:) - - LinVelEK = LinVelEK + x%QDT(PA(I) )*RtHSdat%PLinVelEK(PA(I) ,0,:) - LinAccEKt = LinAccEKt + x%QDT(PA(I) )*RtHSdat%PLinVelEK(PA(I) ,1,:) - - ENDDO ! I - all DOFs associated with the angular motion of the tail (body A) - - DO J = 0,p%TwrNodes ! Loop through the tower nodes / elements @@ -7521,12 +7352,8 @@ SUBROUTINE CalculateForcesMoments( p, x, CoordSys, u, RtHSdat ) REAL(ReKi) :: TmpVec3 (3) ! A temporary vector used in various computations. REAL(ReKi) :: TmpVec4 (3) ! A temporary vector used in various computations. REAL(ReKi) :: TmpVec5 (3) ! A temporary vector used in various computations. - -!REAL(ReKi) :: rSAerCen (3) ! Position vector from a blade analysis node (point S) on the current blade to the aerodynamic center associated with the element. - REAL(ReKi), PARAMETER :: FKAero (3) = 0.0 ! The tail fin aerodynamic force acting at point K, the center-of-pressure of the tail fin. (bjj: should be an input) - REAL(ReKi), PARAMETER :: MAAero (3) = 0.0 ! The tail fin aerodynamic moment acting at point K, the center-of-pressure of the tail fin. (bjj: should be an input) - - + REAL(ReKi) :: Force(3) ! External force (e.g. from AeroDyn) + REAL(ReKi) :: Moment(3) ! External moment (e.g. from AeroDyn) INTEGER(IntKi) :: I ! Loops through some or all of the DOFs INTEGER(IntKi) :: J ! Counter for elements INTEGER(IntKi) :: K ! Counter for blades @@ -7806,9 +7633,11 @@ SUBROUTINE CalculateForcesMoments( p, x, CoordSys, u, RtHSdat ) ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the tail boom center of mass (point I) !..................................... -! FrcWTailt and MomNTailt -! (requires FKAero and MAAero) +! FrcWTailt and MomNTailt - Forces on the tailfin !..................................... + ! Aerodynamic loads on TailFin CM (point K), with change of coordinate system + Force(1:3) = (/ u%TFinCMLoads%Force (1,1), u%TFinCMLoads%Force (3,1), -u%TFinCMLoads%Force (2,1) /) + Moment(1:3) = (/ u%TFinCMLoads%Moment(1,1), u%TFinCMLoads%Moment(3,1), -u%TFinCMLoads%Moment(2,1) /) TmpVec1 = -p%BoomMass*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccEIt ) ! The portion of FrcWTailt associated with the BoomMass TmpVec2 = -p%TFinMass*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccEJt ) ! The portion of FrcWTailt associated with the TFinMass @@ -7817,9 +7646,9 @@ SUBROUTINE CalculateForcesMoments( p, x, CoordSys, u, RtHSdat ) TmpVec = p%AtfaIner*CoordSys%tfa*DOT_PRODUCT( CoordSys%tfa, RtHSdat%AngVelEA ) ! = ( A inertia dyadic ) dot ( angular velocity of the tail in the inertia frame ) TmpVec5 = CROSS_PRODUCT( -RtHSdat%AngVelEA, TmpVec ) ! = ( -angular velocity of the tail in the inertia frame ) cross ( TmpVec ) - RtHSdat%FrcWTailt = FKAero + TmpVec1 + TmpVec2 - RtHSdat%MomNTailt = MAAero + TmpVec3 + TmpVec4 + TmpVec5 & - + CROSS_PRODUCT( RtHSdat%rWK , FKAero ) & ! The portion of MomNTailt associated with FKAero + RtHSdat%FrcWTailt = Force + TmpVec1 + TmpVec2 + RtHSdat%MomNTailt = Moment + TmpVec3 + TmpVec4 + TmpVec5 & + + CROSS_PRODUCT( RtHSdat%rWJ , Force ) & ! The portion of MomNTailt associated with Force with lever arm WK - p%AtfaIner*CoordSys%tfa*DOT_PRODUCT( CoordSys%tfa, RtHSdat%AngAccEAt ) !..................................... @@ -7945,42 +7774,42 @@ SUBROUTINE CalculateForcesMoments( p, x, CoordSys, u, RtHSdat ) !..................................... DO J=1,p%TwrNodes - RtHSdat%FTHydrot(:,J) = CoordSys%z1*( u%TowerPtLoads%Force(DOF_Sg,J)/p%DHNodes(J) & + RtHSdat%FTHydrot(:,J) = CoordSys%z1*( u%TowerPtLoads%Force(DOF_Sg,J)/abs(p%DHNodes(J)) & - u%TwrAddedMass(DOF_Sg,DOF_Sg,J)*RtHSdat%LinAccETt(1,J) & + u%TwrAddedMass(DOF_Sg,DOF_Sw,J)*RtHSdat%LinAccETt(3,J) & - u%TwrAddedMass(DOF_Sg,DOF_Hv,J)*RtHSdat%LinAccETt(2,J) & - u%TwrAddedMass(DOF_Sg,DOF_R ,J)*RtHSdat%AngAccEFt(1,J) & + u%TwrAddedMass(DOF_Sg,DOF_P ,J)*RtHSdat%AngAccEFt(3,J) & - u%TwrAddedMass(DOF_Sg,DOF_Y ,J)*RtHSdat%AngAccEFt(2,J) ) & - - CoordSys%z3*( u%TowerPtLoads%Force(DOF_Sw,J)/p%DHNodes(J) & + - CoordSys%z3*( u%TowerPtLoads%Force(DOF_Sw,J)/abs(p%DHNodes(J)) & - u%TwrAddedMass(DOF_Sw,DOF_Sg,J)*RtHSdat%LinAccETt(1,J) & + u%TwrAddedMass(DOF_Sw,DOF_Sw,J)*RtHSdat%LinAccETt(3,J) & - u%TwrAddedMass(DOF_Sw,DOF_Hv,J)*RtHSdat%LinAccETt(2,J) & - u%TwrAddedMass(DOF_Sw,DOF_R ,J)*RtHSdat%AngAccEFt(1,J) & + u%TwrAddedMass(DOF_Sw,DOF_P ,J)*RtHSdat%AngAccEFt(3,J) & - u%TwrAddedMass(DOF_Sw,DOF_Y ,J)*RtHSdat%AngAccEFt(2,J) ) & - + CoordSys%z2*( u%TowerPtLoads%Force(DOF_Hv,J)/p%DHNodes(J) & + + CoordSys%z2*( u%TowerPtLoads%Force(DOF_Hv,J)/abs(p%DHNodes(J)) & - u%TwrAddedMass(DOF_Hv,DOF_Sg,J)*RtHSdat%LinAccETt(1,J) & + u%TwrAddedMass(DOF_Hv,DOF_Sw,J)*RtHSdat%LinAccETt(3,J) & - u%TwrAddedMass(DOF_Hv,DOF_Hv,J)*RtHSdat%LinAccETt(2,J) & - u%TwrAddedMass(DOF_Hv,DOF_R ,J)*RtHSdat%AngAccEFt(1,J) & + u%TwrAddedMass(DOF_Hv,DOF_P ,J)*RtHSdat%AngAccEFt(3,J) & - u%TwrAddedMass(DOF_Hv,DOF_Y ,J)*RtHSdat%AngAccEFt(2,J) ) - RtHSdat%MFHydrot(:,J) = CoordSys%z1*( u%TowerPtLoads%Moment(DOF_R-3,J)/p%DHNodes(J) & + RtHSdat%MFHydrot(:,J) = CoordSys%z1*( u%TowerPtLoads%Moment(DOF_R-3,J)/abs(p%DHNodes(J)) & - u%TwrAddedMass(DOF_R ,DOF_Sg,J)*RtHSdat%LinAccETt(1,J) & + u%TwrAddedMass(DOF_R ,DOF_Sw,J)*RtHSdat%LinAccETt(3,J) & - u%TwrAddedMass(DOF_R ,DOF_Hv,J)*RtHSdat%LinAccETt(2,J) & - u%TwrAddedMass(DOF_R ,DOF_R ,J)*RtHSdat%AngAccEFt(1,J) & + u%TwrAddedMass(DOF_R ,DOF_P ,J)*RtHSdat%AngAccEFt(3,J) & - u%TwrAddedMass(DOF_R ,DOF_Y ,J)*RtHSdat%AngAccEFt(2,J) ) & - - CoordSys%z3*( u%TowerPtLoads%Moment(DOF_P-3 ,J)/p%DHNodes(J) & + - CoordSys%z3*( u%TowerPtLoads%Moment(DOF_P-3 ,J)/abs(p%DHNodes(J)) & - u%TwrAddedMass(DOF_P ,DOF_Sg,J)*RtHSdat%LinAccETt(1,J) & + u%TwrAddedMass(DOF_P ,DOF_Sw,J)*RtHSdat%LinAccETt(3,J) & - u%TwrAddedMass(DOF_P ,DOF_Hv,J)*RtHSdat%LinAccETt(2,J) & - u%TwrAddedMass(DOF_P ,DOF_R ,J)*RtHSdat%AngAccEFt(1,J) & + u%TwrAddedMass(DOF_P ,DOF_P ,J)*RtHSdat%AngAccEFt(3,J) & - u%TwrAddedMass(DOF_P ,DOF_Y ,J)*RtHSdat%AngAccEFt(2,J) ) & - + CoordSys%z2*( u%TowerPtLoads%Moment(DOF_Y-3 ,J)/p%DHNodes(J) & + + CoordSys%z2*( u%TowerPtLoads%Moment(DOF_Y-3 ,J)/abs(p%DHNodes(J)) & - u%TwrAddedMass(DOF_Y ,DOF_Sg,J)*RtHSdat%LinAccETt(1,J) & + u%TwrAddedMass(DOF_Y ,DOF_Sw,J)*RtHSdat%LinAccETt(3,J) & - u%TwrAddedMass(DOF_Y ,DOF_Hv,J)*RtHSdat%LinAccETt(2,J) & @@ -8030,19 +7859,19 @@ SUBROUTINE CalculateForcesMoments( p, x, CoordSys, u, RtHSdat ) DO I = 1,p%DOFs%NPTE ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the tower - TmpVec1 = RtHSdat%PFTHydro(:,J,p%DOFs%PTE(I))*p%DHNodes(J) - p%TElmntMass(J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,:) ! The portion of PFrcT0Trb associated with tower element J + TmpVec1 = RtHSdat%PFTHydro(:,J,p%DOFs%PTE(I))*abs(p%DHNodes(J)) - p%TElmntMass(J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,:) ! The portion of PFrcT0Trb associated with tower element J TmpVec2 = CROSS_PRODUCT( RtHSdat%rT0T(:,J), TmpVec1 ) ! The portion of PMomX0Trb associated with tower element J - TmpVec3 = RtHSdat%PMFHydro(:,J,p%DOFs%PTE(I))*p%DHNodes(J) ! The added moment applied at tower element J + TmpVec3 = RtHSdat%PMFHydro(:,J,p%DOFs%PTE(I))*abs(p%DHNodes(J)) ! The added moment applied at tower element J RtHSdat%PFrcT0Trb(:,p%DOFs%PTE(I)) = RtHSdat%PFrcT0Trb(:,p%DOFs%PTE(I)) + TmpVec1 RtHSdat%PMomX0Trb(:,p%DOFs%PTE(I)) = RtHSdat%PMomX0Trb(:,p%DOFs%PTE(I)) + TmpVec2 + TmpVec3 ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the tower - TmpVec1 = ( RtHSdat%FTHydrot(:,J) )*p%DHNodes(J) & + TmpVec1 = ( RtHSdat%FTHydrot(:,J) )*abs(p%DHNodes(J)) & - p%TElmntMass(J)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccETt(:,J) ) ! The portion of FrcT0Trbt associated with tower element J TmpVec2 = CROSS_PRODUCT( RtHSdat%rT0T(:,J), TmpVec1 ) ! The portion of MomX0Trbt associated with tower element J - TmpVec3 = ( RtHSdat%MFHydrot(:,J) )*p%DHNodes(J) ! The external moment applied to tower element J + TmpVec3 = ( RtHSdat%MFHydrot(:,J) )*abs(p%DHNodes(J)) ! The external moment applied to tower element J RtHSdat%FrcT0Trbt = RtHSdat%FrcT0Trbt + TmpVec1 @@ -8310,16 +8139,16 @@ SUBROUTINE FillAugMat( p, x, CoordSys, u, HSSBrTrq, RtHSdat, AugMat ) AugMat(p%DOFs%PTTE(I),p%DOFs%PTTE(L)) = AugMat(p%DOFs%PTTE(I),p%DOFs%PTTE(L)) & + p%TElmntMass(J) *DOT_PRODUCT( RtHSdat%PLinVelET(J,p%DOFs%PTTE(I),0,:), & RtHSdat%PLinVelET(J,p%DOFs%PTTE(L),0,:) ) & ! [C(q,t)]T + [C(q,t)]HydroT - - p%DHNodes(J)*DOT_PRODUCT( RtHSdat%PLinVelET(J,p%DOFs%PTTE(I),0,:), & + - abs(p%DHNodes(J))*DOT_PRODUCT( RtHSdat%PLinVelET(J,p%DOFs%PTTE(I),0,:), & RtHSdat%PFTHydro (:,J,p%DOFs%PTTE(L) ) ) & - - p%DHNodes(J)*DOT_PRODUCT( RtHSdat%PAngVelEF(J,p%DOFs%PTTE(I),0,:), & + - abs(p%DHNodes(J))*DOT_PRODUCT( RtHSdat%PAngVelEF(J,p%DOFs%PTTE(I),0,:), & RtHSdat%PMFHydro (:,J,p%DOFs%PTTE(L) ) ) ENDDO ! I - All active (enabled) tower DOFs greater than or equal to L ENDDO ! L - All active (enabled) tower DOFs that contribute to the QD2T-related linear accelerations of the tower - TmpVec1 = ( RtHSdat%FTHydrot(:,J) )*p%DHNodes(J) & + TmpVec1 = ( RtHSdat%FTHydrot(:,J) )*abs(p%DHNodes(J)) & - p%TElmntMass(J)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccETt(:,J) ) ! The portion of FrcT0Trbt associated with tower element J - TmpVec3 = ( RtHSdat%MFHydrot(:,J) )*p%DHNodes(J) ! The external moment applied to tower element J + TmpVec3 = ( RtHSdat%MFHydrot(:,J) )*abs(p%DHNodes(J)) ! The external moment applied to tower element J DO I = 1,p%DOFs%NPTTE ! Loop through all active (enabled) tower DOFs that contribute to the QD2T-related linear accelerations of the tower AugMat(p%DOFs%PTTE(I), p%NAug) = AugMat(p%DOFs%PTTE(I), p%NAug) & ! {-f(qd,q,t)}T + {-f(qd,q,t)}GravT + {-f(qd,q,t)}AeroT + {-f(qd,q,t)}HydroT + DOT_PRODUCT( RtHSdat%PLinVelET(J,p%DOFs%PTTE(I),0,:), TmpVec1 ) & ! NOTE: TmpVec1 is still the portion of FrcT0Trbt associated with tower element J @@ -8974,6 +8803,22 @@ SUBROUTINE ED_AllocOutput( p, m, u, y, ErrStat, ErrMsg ) IF (ErrStat >= AbortErrLev) RETURN + ! -------------- Tailfin ----------------------------------- + call MeshCopy ( SrcMesh = u%TFinCMLoads & + , DestMesh = y%TFinCMMotion & + , CtrlCode = MESH_SIBLING & + , IOS = COMPONENT_OUTPUT & + , TranslationDisp = .TRUE. & + , Orientation = .TRUE. & + , TranslationVel = .TRUE. & + , RotationVel = .TRUE. & + , TranslationAcc = .TRUE. & + , RotationAcc = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + + call CheckError( ErrStat2, ErrMsg2 ) + if (ErrStat >= AbortErrLev) RETURN ! -------------- Tower Base----------------------------------- CALL MeshCreate( BlankMesh = y%TowerBaseMotion14 & @@ -9089,11 +8934,7 @@ SUBROUTINE Init_u( u, p, x, InputFileData, m, ErrStat, ErrMsg ) !....................................................... CALL AllocAry( u%BlPitchCom, p%NumBl, 'BlPitchCom', ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + if (Failed()) return ! will initialize u%BlPitchCom later, after getting undisplaced positions !....................................................... @@ -9102,11 +8943,7 @@ SUBROUTINE Init_u( u, p, x, InputFileData, m, ErrStat, ErrMsg ) ! want inputs and states initialized to 0 first. !....................................................... CALL ED_CopyContState( x, x_tmp, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + if (Failed()) return x_tmp%qt = 0.0_ReKi x_tmp%qdt = 0.0_ReKi x_tmp%QT (DOF_GeAz) = - p%AzimB1Up - REAL(Piby2_D, R8Ki) @@ -9152,11 +8989,7 @@ SUBROUTINE Init_u( u, p, x, InputFileData, m, ErrStat, ErrMsg ) ,Moment = .TRUE. & ,ErrStat = ErrStat2 & ,ErrMess = ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + if (Failed()) return if (p%UseAD14) then ! position the nodes on the blades: @@ -9234,11 +9067,7 @@ SUBROUTINE Init_u( u, p, x, InputFileData, m, ErrStat, ErrMsg ) ! that's our entire mesh: CALL MeshCommit ( u%BladePtLoads(K), ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + if (Failed()) return ! initialize it @@ -9250,23 +9079,9 @@ SUBROUTINE Init_u( u, p, x, InputFileData, m, ErrStat, ErrMsg ) END IF ! p%BD4Blades - !....................................................... - ! Create Point Mesh for loads input at hub point (from BeamDyn): - !....................................................... - - CALL MeshCreate( BlankMesh = u%HubPtLoad & - ,IOS = COMPONENT_INPUT & - ,NNodes = 1 & - ,Force = .TRUE. & - ,Moment = .TRUE. & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - + !....................................................... + ! Create Point Mesh for loads input at hub point (from BeamDyn): + !....................................................... ! place single node at hub; position affects mapping/coupling with other modules Position(1) = m%RtHS%rQ(1) Position(2) = -1.*m%RtHS%rQ(3) @@ -9281,147 +9096,52 @@ SUBROUTINE Init_u( u, p, x, InputFileData, m, ErrStat, ErrMsg ) Orientation(1,3) = m%CoordSys%g1(2) Orientation(2,3) = m%CoordSys%g2(2) Orientation(3,3) = m%CoordSys%g3(2) - - CALL MeshPositionNode ( u%HubPtLoad, 1, Position, ErrStat2, ErrMsg2, orient=Orientation ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! create an element from this point - CALL MeshConstructElement ( Mesh = u%HubPtLoad & - , Xelement = ELEMENT_POINT & - , P1 = 1 & ! node number - , ErrStat = ErrStat2 & - , ErrMess = ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! that's our entire mesh: - CALL MeshCommit ( u%HubPtLoad, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! initailize it - u%HubPtLoad%Moment = 0.0_ReKi - u%HubPtLoad%Force = 0.0_ReKi + call CreatePointMesh(u%HubPtLoad, Position, Orientation, errStat2, errMsg2, hasMotion=.False., hasLoads=.True.) + if (Failed()) return !....................................................... ! Create Point Mesh for loads input at Platform Reference Point: !....................................................... - - CALL MeshCreate( BlankMesh = u%PlatformPtMesh & - ,IOS = COMPONENT_INPUT & - ,NNodes = 1 & - ,Force = .TRUE. & - ,Moment = .TRUE. & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! place single node at platform reference point; position affects mapping/coupling with other modules - CALL MeshPositionNode ( u%PlatformPtMesh, 1, (/0.0_ReKi, 0.0_ReKi, p%PtfmRefzt /), ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! create an element from this point - CALL MeshConstructElement ( Mesh = u%PlatformPtMesh & - , Xelement = ELEMENT_POINT & - , P1 = 1 & ! node number - , ErrStat = ErrStat2 & - , ErrMess = ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! that's our entire mesh: - CALL MeshCommit ( u%PlatformPtMesh, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! initialize fields - u%PlatformPtMesh%Moment = 0.0_ReKi - u%PlatformPtMesh%Force = 0.0_ReKi + Position = (/0.0_ReKi, 0.0_ReKi, p%PtfmRefzt /) + call Eye(Orientation, ErrStat2, errMsg2) + call CreatePointMesh(u%PlatformPtMesh, Position, Orientation, errStat2, errMsg2, hasMotion=.False., hasLoads=.True.) + if (Failed()) return !....................................................... ! Create Point Mesh for loads input at nacelle: !....................................................... - - CALL MeshCreate( BlankMesh = u%NacelleLoads & - ,IOS = COMPONENT_OUTPUT & - ,NNodes = 1 & - ,Force = .TRUE. & - ,Moment = .TRUE. & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - CALL MeshPositionNode ( u%NacelleLoads, 1, (/0.0_ReKi, 0.0_ReKi, p%TowerHt /), ErrStat2, ErrMsg2 ) ! orientation is identity by default - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! create an element from this point - CALL MeshConstructElement ( Mesh = u%NacelleLoads & - , Xelement = ELEMENT_POINT & - , P1 = 1 & ! node number - , ErrStat = ErrStat2 & - , ErrMess = ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - - CALL MeshCommit ( u%NacelleLoads, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - ! initialize fields - u%NacelleLoads%Force = 0.0_ReKi - u%NacelleLoads%Moment = 0.0_ReKi + Position = (/0.0_ReKi, 0.0_ReKi, p%TowerHt /) + call Eye(Orientation, ErrStat2, errMsg2) + call CreatePointMesh(u%NacelleLoads, Position, Orientation, errStat2, errMsg2, hasMotion=.False., hasLoads=.True.) + if (Failed()) return + !....................................................... + ! Create Point Mesh for loads on Rotor tailfin: + !....................................................... + Position(1) = m%RtHS%rJ(1) ! undeflected position of the tailfin CM in the xi ( z1) direction + Position(2) = -1.*m%RtHS%rJ(3) ! undeflected position of the tailfin CM in the yi (-z3) direction + Position(3) = m%RtHS%rJ(2) + p%PtfmRefzt ! undeflected position of the tailfin CM in the zi ( z2) direction + Orientation(1,1) = m%CoordSys%tf1(1) + Orientation(2,1) = m%CoordSys%tf2(1) + Orientation(3,1) = m%CoordSys%tf3(1) + Orientation(1,2) = -1.*m%CoordSys%tf1(3) + Orientation(2,2) = -1.*m%CoordSys%tf2(3) + Orientation(3,2) = -1.*m%CoordSys%tf3(3) + Orientation(1,3) = m%CoordSys%tf1(2) + Orientation(2,3) = m%CoordSys%tf2(2) + Orientation(3,3) = m%CoordSys%tf3(2) + call CreatePointMesh(u%TFinCMLoads, Position, Orientation, errStat2, errMsg2, hasMotion=.False., hasLoads=.True.) + if (Failed()) return + + !....................................................... ! Create u%TwrAddedMass for loads input on tower: ! SHOULD REMOVE EVENTUALLY !....................................................... CALL AllocAry( u%TwrAddedMass, 6_IntKi, 6_IntKi, p%TwrNodes, 'TwrAddedMass', ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + if (Failed()) return ! initialize it u%TwrAddedMass = 0.0_ReKi @@ -9438,20 +9158,12 @@ SUBROUTINE Init_u( u, p, x, InputFileData, m, ErrStat, ErrMsg ) ,Moment = .TRUE. & ,ErrStat = ErrStat2 & ,ErrMess = ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + if (Failed()) return ! position the nodes on the tower: DO J = 1,p%TwrNodes CALL MeshPositionNode ( u%TowerPtLoads, J, (/0.0_ReKi, 0.0_ReKi, p%HNodes(J) + p%TowerBsHt /), ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + if (Failed()) return END DO ! create elements: @@ -9462,21 +9174,13 @@ SUBROUTINE Init_u( u, p, x, InputFileData, m, ErrStat, ErrMsg ) , ErrStat = ErrStat2 & , ErrMess = ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + if (Failed()) return END DO ! that's our entire mesh: CALL MeshCommit ( u%TowerPtLoads, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF + if (Failed()) return ! initialize fields u%TowerPtLoads%Moment = 0.0_ReKi @@ -9504,6 +9208,11 @@ SUBROUTINE Cleanup() CALL ED_DestroyContState( x_tmp, ErrStat2, ErrMsg2 ) END SUBROUTINE Cleanup + logical function Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + Failed = ErrStat >= AbortErrLev + if (Failed) call Cleanup() + end function Failed END SUBROUTINE Init_u !---------------------------------------------------------------------------------------------------------------------------------- @@ -10040,12 +9749,11 @@ END SUBROUTINE CheckError END SUBROUTINE ED_ABM4 !---------------------------------------------------------------------------------------------------------------------------------- !> This routine generates the summary file, which contains a regurgitation of the input data and interpolated flexible body data. -SUBROUTINE ED_PrintSum( p, OtherState, GenerateAdamsModel, ErrStat, ErrMsg ) +SUBROUTINE ED_PrintSum( p, OtherState, ErrStat, ErrMsg ) ! passed variables TYPE(ED_ParameterType), INTENT(IN ) :: p !< Parameters of the structural dynamics module TYPE(ED_OtherStateType), INTENT(IN ) :: OtherState !< Other states of the structural dynamics module - LOGICAL, INTENT(IN ) :: GenerateAdamsModel !< Logical to determine if Adams inputs were read/should be summarized INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None @@ -10185,30 +9893,14 @@ SUBROUTINE ED_PrintSum( p, OtherState, GenerateAdamsModel, ErrStat, ErrMsg ) ! Interpolated tower properties. WRITE (UnSu,"(//,'Interpolated tower properties:',/)") - IF ( GenerateAdamsModel ) THEN ! An ADAMS model will be created; thus, print out all the cols. - WRITE (UnSu,'(A)') 'Node TwFract HNodes DHNodes TMassDen FAStiff SSStiff'// & - ' GJStiff EAStiff FAIner SSIner FAcgOff SScgOff' - WRITE (UnSu,'(A)') ' (-) (-) (m) (m) (kg/m) (Nm^2) (Nm^2)'// & - ' (Nm^2) (N) (kg m) (kg m) (m) (m)' + WRITE (UnSu,'(A)') 'Node TwFract HNodes DHNodes TMassDen FAStiff SSStiff' + WRITE (UnSu,'(A)') ' (-) (-) (m) (m) (kg/m) (Nm^2) (Nm^2)' - DO I=1,p%TwrNodes - WRITE(UnSu,'(I4,3F9.3,F10.3,4ES11.3,2F10.3,2F9.3)') I, p%HNodesNorm(I), p%HNodes(I), p%DHNodes(I), p%MassT(I), & - p%StiffTFA(I), p%StiffTSS(I), p%StiffTGJ(I), p%StiffTEA(I), & - p%InerTFA(I), p%InerTSS(I), p%cgOffTFA(I), p%cgOffTSS(I) - ENDDO ! I - - ELSE ! Only FAST will be run; thus, only print out the necessary cols. - - WRITE (UnSu,'(A)') 'Node TwFract HNodes DHNodes TMassDen FAStiff SSStiff' - WRITE (UnSu,'(A)') ' (-) (-) (m) (m) (kg/m) (Nm^2) (Nm^2)' - - DO I=1,p%TwrNodes - WRITE(UnSu,'(I4,3F9.3,F10.3,2ES11.3)') I, p%HNodesNorm(I), p%HNodes(I), p%DHNodes(I), p%MassT(I), & - p%StiffTFA(I), p%StiffTSS(I) - ENDDO ! I - - ENDIF + DO I=1,p%TwrNodes + WRITE(UnSu,'(I4,3F9.3,F10.3,2ES11.3)') I, p%HNodesNorm(I), p%HNodes(I), p%DHNodes(I), p%MassT(I), & + p%StiffTFA(I), p%StiffTSS(I) + ENDDO ! I ! Interpolated blade properties. @@ -10217,39 +9909,15 @@ SUBROUTINE ED_PrintSum( p, OtherState, GenerateAdamsModel, ErrStat, ErrMsg ) DO K=1,p%NumBl WRITE (UnSu,'(//,A,I1,A,/)') 'Interpolated blade ', K, ' properties:' - IF ( GenerateAdamsModel ) THEN ! An ADAMS model will be created; thus, print out all the cols. - - WRITE (UnSu,'(A)') 'Node BlFract RNodes DRNodes PitchAxis StrcTwst BMassDen FlpStff EdgStff'// & - ' GJStff EAStff Alpha FlpIner EdgIner PrecrvRef PreswpRef FlpcgOf EdgcgOf'// & - ' FlpEAOf EdgEAOf' - WRITE (UnSu,'(A)') ' (-) (-) (m) (m) (-) (deg) (kg/m) (Nm^2) (Nm^2)'// & - ' (Nm^2) (Nm^2) (-) (kg m) (kg m) (m) (m) (m) (m)'// & - ' (m) (m)' - - DO I=1,p%BldNodes - - WRITE(UnSu,'(I4,3F9.3,3F10.3,4ES11.3,F9.3,4F10.3,4F9.3)') I, p%RNodesNorm(I), p%RNodes(I) + p%HubRad, p%DRNodes(I), & - p%PitchAxis(K,I), p%ThetaS(K,I)*R2D, p%MassB(K,I), & - p%StiffBF(K,I), p%StiffBE(K,I), & - p%StiffBGJ(K,I), p%StiffBEA(K,I), & - p%BAlpha(K,I), p%InerBFlp(K,I), p%InerBEdg(K,I), & - p%RefAxisxb(K,I), p%RefAxisyb(K,I), & - p%cgOffBFlp(K,I), p%cgOffBEdg(K,I), & - p%EAOffBFlp(K,I), p%EAOffBEdg(K,I) - ENDDO ! I - - ELSE ! Only FAST will be run; thus, only print out the necessary cols. - - WRITE (UnSu,'(A)') 'Node BlFract RNodes DRNodes PitchAxis StrcTwst BMassDen FlpStff EdgStff' - WRITE (UnSu,'(A)') ' (-) (-) (m) (m) (-) (deg) (kg/m) (Nm^2) (Nm^2)' - - DO I=1,p%BldNodes - WRITE(UnSu,'(I4,3F9.3,3F10.3,2ES11.3)') I, p%RNodesNorm(I), p%RNodes(I) + p%HubRad, p%DRNodes(I), & - p%PitchAxis(K,I),p%ThetaS(K,I)*R2D, p%MassB(K,I), & - p%StiffBF(K,I), p%StiffBE(K,I) - ENDDO ! I - ENDIF + WRITE (UnSu,'(A)') 'Node BlFract RNodes DRNodes PitchAxis StrcTwst BMassDen FlpStff EdgStff' + WRITE (UnSu,'(A)') ' (-) (-) (m) (m) (-) (deg) (kg/m) (Nm^2) (Nm^2)' + + DO I=1,p%BldNodes + WRITE(UnSu,'(I4,3F9.3,3F10.3,2ES11.3)') I, p%RNodesNorm(I), p%RNodes(I) + p%HubRad, p%DRNodes(I), & + p%PitchAxis(K,I),p%ThetaS(K,I)*R2D, p%MassB(K,I), & + p%StiffBF(K,I), p%StiffBE(K,I) + ENDDO ! I ENDDO ! K @@ -11668,7 +11336,7 @@ SUBROUTINE Compute_dY(p, y_p, y_m, delta, dY) END SUBROUTINE Compute_dY !---------------------------------------------------------------------------------------------------------------------------------- !> Routine to pack the data structures representing the operating points into arrays for linearization. -SUBROUTINE ED_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, y_op, x_op, dx_op, xd_op, z_op, NeedPackedOrient ) +SUBROUTINE ED_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, y_op, x_op, dx_op, xd_op, z_op, NeedTrimOP ) REAL(DbKi), INTENT(IN ) :: t !< Time in seconds at operating point TYPE(ED_InputType), INTENT(IN ) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) @@ -11687,7 +11355,7 @@ SUBROUTINE ED_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, 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 - LOGICAL, OPTIONAL, INTENT(IN ) :: NeedPackedOrient !< whether a y_op values should contain 3-value representation instead of full orientation matrices + LOGICAL, OPTIONAL, INTENT(IN ) :: NeedTrimOP !< whether a y_op values should contain values for trim solution (3-value representation instead of full orientation matrices, no rotation acc) @@ -11696,7 +11364,7 @@ SUBROUTINE ED_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'ED_GetOP' - LOGICAL :: ReturnLogMap + LOGICAL :: ReturnTrimOP TYPE(ED_ContinuousStateType) :: dx !< derivative of continuous states at operating point LOGICAL :: Mask(FIELDMASK_SIZE) !< flags to determine if this field is part of the packing @@ -11747,10 +11415,10 @@ SUBROUTINE ED_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, !.................................. IF ( PRESENT( y_op ) ) THEN - if (present(NeedPackedOrient)) then - ReturnLogMap = NeedPackedOrient + if (present(NeedTrimOP)) then + ReturnTrimOP = NeedTrimOP else - ReturnLogMap = .false. + ReturnTrimOP = .false. end if if (.not. allocated(y_op)) then @@ -11774,7 +11442,7 @@ SUBROUTINE ED_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, if (ErrStat>=AbortErrLev) return end if - if (ReturnLogMap) y_op = 0.0_ReKi ! initialize in case we are returning packed orientations and don't fill the entire array + if (ReturnTrimOP) y_op = 0.0_ReKi ! initialize in case we are returning packed orientations and don't fill the entire array Mask = .false. @@ -11785,16 +11453,17 @@ SUBROUTINE ED_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, index = 1 if (allocated(y%BladeLn2Mesh)) then do k=1,p%NumBl - call PackMotionMesh(y%BladeLn2Mesh(k), y_op, index, UseSmlAngle=ReturnLogMap) + call PackMotionMesh(y%BladeLn2Mesh(k), y_op, index, TrimOP=ReturnTrimOP) end do end if - call PackMotionMesh(y%PlatformPtMesh, y_op, index, UseSmlAngle=ReturnLogMap) - call PackMotionMesh(y%TowerLn2Mesh, y_op, index, UseSmlAngle=ReturnLogMap) - call PackMotionMesh(y%HubPtMotion, y_op, index, FieldMask=Mask, UseSmlAngle=ReturnLogMap) + call PackMotionMesh(y%PlatformPtMesh, y_op, index, TrimOP=ReturnTrimOP) + call PackMotionMesh(y%TowerLn2Mesh, y_op, index, TrimOP=ReturnTrimOP) + call PackMotionMesh(y%HubPtMotion, y_op, index, FieldMask=Mask, TrimOP=ReturnTrimOP) + do k=1,p%NumBl - call PackMotionMesh(y%BladeRootMotion(k), y_op, index, UseSmlAngle=ReturnLogMap) - end do - call PackMotionMesh(y%NacelleMotion, y_op, index, UseSmlAngle=ReturnLogMap) + call PackMotionMesh(y%BladeRootMotion(k), y_op, index, TrimOP=ReturnTrimOP) + end do + call PackMotionMesh(y%NacelleMotion, y_op, index, TrimOP=ReturnTrimOP) y_op(index) = y%Yaw ; index = index + 1 y_op(index) = y%YawRate ; index = index + 1 @@ -11802,7 +11471,7 @@ SUBROUTINE ED_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, do i=1,p%NumOuts + p%BldNd_TotNumOuts y_op(i+index) = y%WriteOutput(i) - end do + end do END IF diff --git a/modules/elastodyn/src/ElastoDyn_AllBldNdOuts_IO.f90 b/modules/elastodyn/src/ElastoDyn_AllBldNdOuts_IO.f90 index 91c2ed066..adbbd1320 100644 --- a/modules/elastodyn/src/ElastoDyn_AllBldNdOuts_IO.f90 +++ b/modules/elastodyn/src/ElastoDyn_AllBldNdOuts_IO.f90 @@ -20,7 +20,7 @@ MODULE ElastoDyn_AllBldNdOuts_IO ! Parameters related to output length (number of characters allowed in the output data headers): - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen-6 ! The NREL allowed channel name length is usually 20. We are making these of the form B#N###namesuffix +! INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen-6 ! The NREL allowed channel name length is usually 20. We are making these of the form B#N###namesuffix ! =================================================================================================== diff --git a/modules/elastodyn/src/ElastoDyn_IO.f90 b/modules/elastodyn/src/ElastoDyn_IO.f90 index 376792d54..c4e40d272 100644 --- a/modules/elastodyn/src/ElastoDyn_IO.f90 +++ b/modules/elastodyn/src/ElastoDyn_IO.f90 @@ -104,11 +104,6 @@ MODULE ElastoDyn_Parameters ! This code was generated by Write_ChckOutLst.m at 25-Jan-2021 13:23:51. - ! Parameters related to output length (number of characters allowed in the output data headers): - - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 - - ! Indices for computing output channels: ! NOTES: ! (1) These parameters are in the order stored in "OutListParameters.xlsx" @@ -1281,7 +1276,7 @@ MODULE ElastoDyn_IO !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine reads the input file and stores all the data in the ED_InputFile structure. !! It does not perform data validation. -SUBROUTINE ED_ReadInput( InputFileName, MeshFile, InputFileData, ReadAdmVals, BD4Blades, Default_DT, OutFileRoot, ErrStat, ErrMsg ) +SUBROUTINE ED_ReadInput( InputFileName, MeshFile, InputFileData, BD4Blades, Default_DT, OutFileRoot, ErrStat, ErrMsg ) !.................................................................................................................................. ! Passed variables @@ -1294,7 +1289,6 @@ SUBROUTINE ED_ReadInput( InputFileName, MeshFile, InputFileData, ReadAdmVals, BD TYPE(ED_InputFile), INTENT(OUT) :: InputFileData !< Data stored in the module's input file INTEGER(IntKi), INTENT(OUT) :: ErrStat !< The error status code - LOGICAL, INTENT(IN) :: ReadAdmVals !< Determines if we should read the Adams-only values LOGICAL, INTENT(IN) :: BD4Blades !< Determines if we should read the blade values (true=don't read this file; use BeamDyn for blades instead) CHARACTER(*), INTENT(OUT) :: ErrMsg !< The error message, if an error occurred @@ -1327,8 +1321,6 @@ SUBROUTINE ED_ReadInput( InputFileName, MeshFile, InputFileData, ReadAdmVals, BD end if ! get the furling input-file data - InputFileData%Furling = .FALSE. ! Furling is not supported in this version of ElastoDyn - IF ( InputFileData%Furling ) THEN CALL ReadFurlFile( FurlFile, InputFileData, UnEcho, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -1343,29 +1335,13 @@ SUBROUTINE ED_ReadInput( InputFileName, MeshFile, InputFileData, ReadAdmVals, BD InputFileData%TailFurl = 0.0_ReKi InputFileData%Yaw2Shft = 0.0 InputFileData%ShftSkew = 0.0 - InputFileData%RFrlCMxn = 0.0 - InputFileData%RFrlCMyn = 0.0 - InputFileData%RFrlCMzn = 0.0 - InputFileData%BoomCMxn = 0.0 - InputFileData%BoomCMyn = 0.0 - InputFileData%BoomCMzn = 0.0 - InputFileData%TFinCMxn = 0.0 - InputFileData%TFinCMyn = 0.0 - InputFileData%TFinCMzn = 0.0 - InputFileData%TFinCPxn = 0.0 - InputFileData%TFinCPyn = 0.0 - InputFileData%TFinCPzn = 0.0 - InputFileData%TFinSkew = 0.0 - InputFileData%TFinTilt = 0.0 - InputFileData%TFinBank = 0.0 - InputFileData%RFrlPntxn = 0.0 - InputFileData%RFrlPntyn = 0.0 - InputFileData%RFrlPntzn = 0.0 + InputFileData%RFrlCM_n = 0.0 + InputFileData%BoomCM_n = 0.0 + InputFileData%TFinCM_n = 0.0 + InputFileData%RFrlPnt_n = 0.0 InputFileData%RFrlSkew = 0.0 InputFileData%RFrlTilt = 0.0 - InputFileData%TFrlPntxn = 0.0 - InputFileData%TFrlPntyn = 0.0 - InputFileData%TFrlPntzn = 0.0 + InputFileData%TFrlPnt_n = 0.0 InputFileData%TFrlSkew = 0.0 InputFileData%TFrlTilt = 0.0 InputFileData%RFrlMass = 0.0 @@ -1376,7 +1352,6 @@ SUBROUTINE ED_ReadInput( InputFileName, MeshFile, InputFileData, ReadAdmVals, BD InputFileData%RFrlMod = 0 InputFileData%RFrlSpr = 0.0 InputFileData%RFrlDmp = 0.0 - InputFileData%RFrlCDmp = 0.0 InputFileData%RFrlUSSP = 0.0 InputFileData%RFrlDSSP = 0.0 InputFileData%RFrlUSSpr = 0.0 @@ -1388,7 +1363,6 @@ SUBROUTINE ED_ReadInput( InputFileName, MeshFile, InputFileData, ReadAdmVals, BD InputFileData%TFrlMod = 0 InputFileData%TFrlSpr = 0.0 InputFileData%TFrlDmp = 0.0 - InputFileData%TFrlCDmp = 0.0 InputFileData%TFrlUSSP = 0.0 InputFileData%TFrlDSSP = 0.0 InputFileData%TFrlUSSpr = 0.0 @@ -1402,7 +1376,7 @@ SUBROUTINE ED_ReadInput( InputFileName, MeshFile, InputFileData, ReadAdmVals, BD ! get the blade input-file data (from blade and mesh files) IF (.NOT. BD4Blades) THEN - CALL ReadBladeInputs ( BldFile, MeshFile, ReadAdmVals, InputFileData, UnEcho, ErrStat2, ErrMsg2 ) + CALL ReadBladeInputs ( BldFile, MeshFile, InputFileData, UnEcho, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if ( ErrStat >= AbortErrLev ) then call Cleanup() @@ -1412,7 +1386,7 @@ SUBROUTINE ED_ReadInput( InputFileName, MeshFile, InputFileData, ReadAdmVals, BD ! get the tower input-file data - CALL ReadTowerFile( TwrFile, InputFileData, ReadAdmVals, UnEcho, ErrStat2, ErrMsg2 ) + CALL ReadTowerFile( TwrFile, InputFileData, UnEcho, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if ( ErrStat >= AbortErrLev ) then call Cleanup() @@ -1435,12 +1409,13 @@ END SUBROUTINE Cleanup END SUBROUTINE ED_ReadInput !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine validates the input file data -SUBROUTINE ED_ValidateInput( InputFileData, BD4Blades, Linearize, ErrStat, ErrMsg ) +SUBROUTINE ED_ValidateInput( InputFileData, BD4Blades, Linearize, MHK, ErrStat, ErrMsg ) !.................................................................................................................................. TYPE(ED_InputFile), INTENT(IN) :: InputFileData !< Data stored in the module's input file LOGICAL, INTENT(IN) :: BD4Blades !< Determines if we should validate the blade values (true=don't validate; use BeamDyn for blades instead) LOGICAL, INTENT(IN) :: Linearize !< Flag indicating glue code wants to linearize this module + INTEGER(IntKi), INTENT(IN) :: MHK !< MHK turbine type switch INTEGER(IntKi), INTENT(OUT) :: ErrStat !< The error status code CHARACTER(*), INTENT(OUT) :: ErrMsg !< The error message, if an error occurred @@ -1456,7 +1431,7 @@ SUBROUTINE ED_ValidateInput( InputFileData, BD4Blades, Linearize, ErrStat, ErrMs ErrMsg = '' ! validate the primary input data - CALL ValidatePrimaryData( InputFileData, BD4Blades, Linearize, ErrStat2, ErrMsg2 ) + CALL ValidatePrimaryData( InputFileData, BD4Blades, Linearize, MHK, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -1488,7 +1463,7 @@ END SUBROUTINE ED_ValidateInput !---------------------------------------------------------------------------------------------------------------------------------- !> This routine reads the data from the blade and mesh inputs files. !! This routines assumes that InputFileData%NumBl has already been set. -SUBROUTINE ReadBladeInputs ( BldFile, MeshFile, ReadAdmVals, InputFileData, UnEc, ErrStat, ErrMsg ) +SUBROUTINE ReadBladeInputs ( BldFile, MeshFile, InputFileData, UnEc, ErrStat, ErrMsg ) !.................................................................................................................................. ! Passed variables: @@ -1500,7 +1475,6 @@ SUBROUTINE ReadBladeInputs ( BldFile, MeshFile, ReadAdmVals, InputFileData, UnEc INTEGER(IntKi), INTENT(OUT) :: ErrStat !< The error ID CHARACTER(*), INTENT(OUT) :: ErrMsg !< Message describing error - LOGICAL, INTENT(IN) :: ReadAdmVals !< Logical to determine if Adams inputs should be read from file ! Local variables: @@ -1552,7 +1526,7 @@ SUBROUTINE ReadBladeInputs ( BldFile, MeshFile, ReadAdmVals, InputFileData, UnEc WRITE (UnEc,'(//,A,/)') 'Blade '//TRIM( Num2LStr( K ) )//' input data from file "'//TRIM( BldFile(K) )//'":' END IF - CALL ReadBladeFile( BldFile(K), InputFileData%InpBl(K), ReadAdmVals, UnEc, ErrStat2, ErrMsg2 ) + CALL ReadBladeFile( BldFile(K), InputFileData%InpBl(K), UnEc, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) RETURN @@ -1576,14 +1550,13 @@ SUBROUTINE ReadBladeInputs ( BldFile, MeshFile, ReadAdmVals, InputFileData, UnEc END SUBROUTINE ReadBladeInputs !---------------------------------------------------------------------------------------------------------------------------------- !> This routine reads a blade input file. -SUBROUTINE ReadBladeFile ( BldFile, BladeKInputFileData, ReadAdmVals, UnEc, ErrStat, ErrMsg ) +SUBROUTINE ReadBladeFile ( BldFile, BladeKInputFileData, UnEc, ErrStat, ErrMsg ) !.................................................................................................................................. ! Passed variables: TYPE(BladeInputData), INTENT(INOUT) :: BladeKInputFileData !< Data for Blade K stored in the module's input file CHARACTER(*), INTENT(IN) :: BldFile !< Name of the blade input file data - LOGICAL, INTENT(IN) :: ReadAdmVals !< Logical to determine if Adams inputs should be read from file INTEGER(IntKi), INTENT(IN) :: UnEc !< I/O unit for echo file. If present and > 0, write to UnEc INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status @@ -1663,7 +1636,7 @@ SUBROUTINE ReadBladeFile ( BldFile, BladeKInputFileData, ReadAdmVals, UnEc, ErrS ! .......... Allocate the arrays based on this NBlInpSt input .......... - CALL Alloc_BladeInputProperties( BladeKInputFileData, ReadAdmVals, ErrStat2, ErrMsg2 ) + CALL Alloc_BladeInputProperties( BladeKInputFileData, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -1797,11 +1770,7 @@ SUBROUTINE ReadBladeFile ( BldFile, BladeKInputFileData, ReadAdmVals, UnEc, ErrS ! Read the table. - IF ( ReadAdmVals ) THEN - NInputCols = 17 - ELSE - NInputCols = 6 - END IF + NInputCols = 6 DO I=1,BladeKInputFileData%NBlInpSt @@ -1821,851 +1790,16 @@ SUBROUTINE ReadBladeFile ( BldFile, BladeKInputFileData, ReadAdmVals, UnEc, ErrS BladeKInputFileData%FlpStff( I) = TmpRAry(5)*AdjFlSt ! Apply the correction factors to the elemental data. BladeKInputFileData%EdgStff( I) = TmpRAry(6)*AdjEdSt ! Apply the correction factors to the elemental data. - IF ( NInputCols > 6 ) THEN - BladeKInputFileData%GJStff( I) = TmpRAry( 7) - BladeKInputFileData%EAStff( I) = TmpRAry( 8) - BladeKInputFileData%Alpha( I) = TmpRAry( 9) - BladeKInputFileData%FlpIner( I) = TmpRAry(10) - BladeKInputFileData%EdgIner( I) = TmpRAry(11) - BladeKInputFileData%PrecrvRef(I) = TmpRAry(12) - BladeKInputFileData%PreswpRef(I) = TmpRAry(13) - BladeKInputFileData%FlpcgOf( I) = TmpRAry(14) - BladeKInputFileData%EdgcgOf( I) = TmpRAry(15) - BladeKInputFileData%FlpEAOf( I) = TmpRAry(16) - BladeKInputFileData%EdgEAOf( I) = TmpRAry(17) - END IF ENDDO ! I - ! -------------- BLADE MODE SHAPES -------------------------------------------- - - - ! Skip the comment line. - - CALL ReadCom ( UnIn, BldFile, 'blade mode shapes', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! BldFl1Sh - Blade-flap mode-1 shape coefficients. - CALL ReadAryLines ( UnIn, BldFile, BladeKInputFileData%BldFl1Sh, SIZE(BladeKInputFileData%BldFl1Sh), 'BldFl1Sh', & - 'Blade-flap mode-1 shape coefficients', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! BldFl2Sh - Blade-flap mode-2 shape coefficients. - - CALL ReadAryLines ( UnIn, BldFile, BladeKInputFileData%BldFl2Sh, SIZE(BladeKInputFileData%BldFl2Sh), 'BldFl2Sh', & - 'Blade-flap mode-2 shape coefficients', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! BldEdgSh - Blade-edge mode shape coefficients. - - CALL ReadAryLines ( UnIn, BldFile, BladeKInputFileData%BldEdgSh, SIZE(BladeKInputFileData%BldEdgSh), 'BldEdgSh', & - 'Blade-edge mode shape coefficients', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - - ! -------------- END OF FILE -------------------------------------------- - - ! Close the blade file. - - call Cleanup() - RETURN - - -CONTAINS - - SUBROUTINE Cleanup() - IF (UnIn > 0) CLOSE( UnIn ) - END SUBROUTINE Cleanup - -END SUBROUTINE ReadBladeFile -!---------------------------------------------------------------------------------------------------------------------------------- -!> This routine reads in the AeroDyn v14.00.00 input file to get the -!! blade discretization used in the structural dynamics module. -SUBROUTINE ReadBladeMeshFileAD( BladeKInputFileMesh, MeshFile, UnEc, ErrStat, ErrMsg ) -!.................................................................................................................................. - - ! Passed variables - - TYPE(ED_BladeMeshInputData), INTENT(INOUT) :: BladeKInputFileMesh !< All the data in the ElastoDyn input file - CHARACTER(*), INTENT(IN) :: MeshFile !< Name of the AeroDyn input file data (for mesh) - - INTEGER(IntKi), INTENT(IN) :: UnEc !< I/O unit for echo file. If present and > 0, write to UnEc - INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status - CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message - - ! Local variables: - INTEGER(IntKi), PARAMETER :: NInputCols = 4 ! Number of input columns to be read from the file - REAL(ReKi) :: TmpRAry(NInputCols) ! Temporary variable to read table from file - INTEGER(IntKi) :: I ! loop counter - INTEGER(IntKi) :: NumLin2Skp ! number of lines to read - INTEGER(IntKi) :: NumFoil ! number of airfoil lines to skip in the AD input file. - INTEGER(IntKi) :: UnIn ! Unit number for reading file - - INTEGER(IntKi) :: ErrStat2 ! Temporary Error status - CHARACTER(ErrMsgLen) :: ErrMsg2 ! Temporary Err msg - CHARACTER(*), PARAMETER :: RoutineName = 'ReadBladeMeshFileAD' - CHARACTER(1024) :: Line ! Temporary string. -! CHARACTER(1024) :: TmpStr(1) ! Temporary string. - - - - ! Get an available unit number for the file. - - CALL GetNewUnit( UnIn, ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! Open the AeroDyn input file. - - CALL OpenFInpFile ( UnIn, MeshFile, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! Add a separator to the echo file if appropriate. - - IF ( UnEc > 0 ) WRITE (UnEc,'(//,A,/)') 'Mesh input data from (AeroDyn input) file "'//TRIM( MeshFile )//'":' - - - ! -------------- HEADER ------------------------------------------------------- - ! BJJ: This file is AeroDyn's input file. Until we decide on a format for the - ! structural dynamics input, we will get this information from AeroDyn like we - ! used to. - - DO I = 1,9 - CALL ReadCom ( UnIn, MeshFile, 'AeroDyn input (for structural dynamics mesh)', ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END DO - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - ! See if the next line is "NEWTOWER". If it is, read 7 more lines. If not, read 5 more lines. - - CALL ReadVar( UnIn, MeshFile, Line, VarName='NewTowerModel?', VarDescr='Check for tower influence model', ErrStat=ErrStat2, ErrMsg=ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - ! Check if this is the "special string" to indicate the new tower influence model - - CALL Conv2UC( Line ) - IF ( INDEX(Line, "NEWTOWER" ) > 0 ) THEN - NumLin2Skp = 7 - ELSE - NumLin2Skp = 5 - END IF - - DO I = 1,NumLin2Skp - CALL ReadCom ( UnIn, MeshFile, 'AeroDyn input (for structural dynamics mesh)', ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - END DO - - CALL ReadVar ( UnIn, MeshFile, NumFoil, 'NumFoil', & - 'Number of airfoil lines to skip in AeroDyn input (for structural dynamics mesh)', ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - DO I = 1,NumFoil - CALL ReadCom ( UnIn, MeshFile, 'AeroDyn input (for structural dynamics mesh)', ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - END DO - - - ! -------------- Blade Mesh Data -------------------------------------------------- - - ! Read in the number of blade elements - CALL ReadVar( UnIn, MeshFile, BladeKInputFileMesh%BldNodes, 'BldNodes', 'Number of blade elements', ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - ! Allocate the arrays to store input - CALL Alloc_BladeMeshInputProperties( BladeKInputFileMesh, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - ! Read comment line for the element table - CALL ReadCom( UnIn, MeshFile, 'Blade element table headers', ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - DO I = 1, BladeKInputFileMesh%BldNodes - - CALL ReadAry( UnIn, MeshFile, TmpRAry, NInputCols, 'Blade element line'//TRIM(Num2LStr(I)), 'Blade element input table', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - BladeKInputFileMesh%RNodes( I) = TmpRAry(1) - BladeKInputFileMesh%AeroTwst(I) = TmpRAry(2)*D2R !Convert input file data (degrees) to radians - BladeKInputFileMesh%Chord( I) = TmpRAry(4) - - END DO - - !bjj: move this to a validation routine if we plan to keep AD14 stuff in ElastoDyn: - IF ( ANY( BladeKInputFileMesh%Chord < 0.0_ReKi ) ) THEN - call SetErrStat( ErrID_Fatal, 'Chord length must be larger than 0 meters.', ErrStat, ErrMsg, RoutineName ) - RETURN - END IF - - - ! Close the input file: - - CALL cleanup() - RETURN - - -CONTAINS - SUBROUTINE Cleanup() - CLOSE( UnIn ) - END SUBROUTINE Cleanup -END SUBROUTINE ReadBladeMeshFileAD -!---------------------------------------------------------------------------------------------------------------------------------- -!> This routine reads the furling file input and converts units as appropriate. -SUBROUTINE ReadFurlFile( FurlFile, InputFileData, UnEc, ErrStat, ErrMsg ) -!.................................................................................................................................. - - IMPLICIT NONE - - ! Passed variables: - - TYPE(ED_InputFile), INTENT(INOUT) :: InputFileData !< All the data in the ElastoDyn input file - INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status - INTEGER(IntKi), INTENT(IN) :: UnEc !< I/O unit for echo file. If present and > 0, write to UnEc - CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message - CHARACTER(*), INTENT(IN) :: FurlFile !< Name of the furling input file data - - ! Local variables: - - INTEGER(IntKi) :: UnIn ! Unit number for reading file - INTEGER(IntKi) :: ErrStat2 ! Temporary Error status - CHARACTER(ErrMsgLen) :: ErrMsg2 ! Temporary Err msg - CHARACTER(*),PARAMETER :: RoutineName = 'ReadFurlFile' - - ! Get an available unit number for the file. - - CALL GetNewUnit( UnIn, ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! Open the furling input file. - - CALL OpenFInpFile ( UnIn, FurlFile, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! Add a separator to the echo file if appropriate. - - IF ( UnEc > 0 ) WRITE (UnEc,'(//,A,/)') 'Furling input data from file "'//TRIM( FurlFile )//'":' - - - ! -------------- FILE HEADER --------------------------------------------------- - - CALL ReadCom ( UnIn, FurlFile, 'unused tower furling header line 1', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - CALL ReadCom ( UnIn, FurlFile, 'unused tower furling header line 2', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - CALL ReadCom ( UnIn, FurlFile, 'unused tower furling header line 3', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! -------------- Furling FEATURE SWITCHES -------------------------------------- - - - ! Skip the comment line. - - CALL ReadCom ( UnIn, FurlFile, 'degree of freedom switches (cont)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - ! RFrlDOF - Rotor-furl DOF. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlDOF, 'RFrlDOF', 'Rotor-furl DOF (flag)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! TFrlDOF - Tail-furl DOF. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlDOF, 'TFrlDOF', 'Tail-furl DOF (flag)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! -------------- Furling INITIAL CONDITIONS ------------------------------------ - - - ! Skip the comment line. - - CALL ReadCom ( UnIn, FurlFile, 'initial conditions (cont)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! RotFurl - Initial or fixed rotor-furl angle (read in degrees, converted to radians here) - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RotFurl, 'RotFurl', 'Initial or fixed rotor-furl angle (deg)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - InputFileData%RotFurl = InputFileData%RotFurl*D2R - - - ! TailFurl - Initial or fixed tail-furl angle (read in degrees, converted to radians here) - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TailFurl, 'TailFurl', 'Initial or fixed tail-furl angle (deg)', & - ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - InputFileData%TailFurl = InputFileData%TailFurl*D2R - - - ! -------------- TURBINE CONFIGURATION (CONT) --------------------------------- - - - ! Skip the comment line. - - CALL ReadCom ( UnIn, FurlFile, 'turbine configuration (cont)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! Yaw2Shft - Lateral distance from yaw axis to rotor shaft. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%Yaw2Shft, 'Yaw2Shft', & - 'Lateral distance from yaw axis to rotor shaft (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! ShftSkew - Rotor shaft skew angle (read in degrees and converted to radians here). - - CALL ReadVar ( UnIn, FurlFile, InputFileData%ShftSkew, 'ShftSkew', 'Rotor shaft skew angle (deg)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - InputFileData%ShftSkew = InputFileData%ShftSkew *D2R - - - ! RFrlCMxn - Downwind distance from tower-top to CM of structure that furls with the rotor (not including rotor). - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlCMxn, 'RFrlCMxn', & - 'Downwind distance from tower-top to rotor-furl CM (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! RFrlCMyn - Lateral distance from tower-top to CM of structure that furls with the rotor (not including rotor). - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlCMyn, 'RFrlCMyn', & - 'Lateral distance from tower-top to rotor-furl CM (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! RFrlCMzn - Vertical distance from tower-top to CM of structure that furls with the rotor (not including rotor). - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlCMzn, 'RFrlCMzn', & - 'Vertical distance from tower-top to rotor-furl CM (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! BoomCMxn - Downwind distance from tower-top to tail boom CM. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%BoomCMxn, 'BoomCMxn', & - 'Downwind distance from tower-top to tail boom CM (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! BoomCMyn - Lateral distance from tower-top to tail boom CM. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%BoomCMyn, 'BoomCMyn', & - 'Lateral distance from tower-top to tail boom CM (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! BoomCMzn - Vertical distance from tower-top to tail boom CM. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%BoomCMzn, 'BoomCMzn', & - 'Vertical distance from tower-top to tail boom CM (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! TFinCMxn - Downwind distance from tower-top to tail fin CM. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFinCMxn, 'TFinCMxn', & - 'Downwind distance from tower-top to tail fin CM (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! TFinCMyn - Lateral distance from tower-top to tail fin CM. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFinCMyn, 'TFinCMyn', & - 'Lateral distance from tower-top to tail fin CM (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! TFinCMzn - Vertical distance from tower-top to tail fin CM. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFinCMzn, 'TFinCMzn', & - 'Vertical distance from tower-top to tail fin CM (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! TFinCPxn - Downwind distance from tower-top to tail fin CP. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFinCPxn, 'TFinCPxn', & - 'Downwind distance from tower-top to tail fin CP (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! TFinCPyn - Lateral distance from tower-top to tail fin CP. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFinCPyn, 'TFinCPyn', & - 'Lateral distance from tower-top to tail fin CP (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! TFinCPzn - Vertical distance from tower-top to tail fin CP. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFinCPzn, 'TFinCPzn', & - 'Vertical distance from tower-top to tail fin CP (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! TFinSkew - Tail fin chordline skew angle (read in degrees, converted to radians here) - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFinSkew, 'TFinSkew', 'Tail fin chordline skew angle (deg)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - InputFileData%TFinSkew = InputFileData%TFinSkew*D2R - - - ! TFinTilt - Tail fin chordline tilt angle (read in degrees, converted to radians here) - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFinTilt, 'TFinTilt', 'Tail fin chordline tilt angle (deg)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - InputFileData%TFinTilt = InputFileData%TFinTilt *D2R - - - ! TFinBank - Tail fin planform bank angle (read in degrees, converted to radians here) - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFinBank, 'TFinBank', 'Tail fin planform bank angle (deg)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - InputFileData%TFinBank = InputFileData%TFinBank *D2R - - - ! RFrlPntxn - Downwind distance from tower-top to arbitrary point on rotor-furl axis. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlPntxn, 'RFrlPntxn', & - 'Downwind distance from tower-top to arbitrary point on rotor-furl axis (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! RFrlPntyn - Lateral distance from tower-top to arbitrary point on rotor-furl axis. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlPntyn, 'RFrlPntyn', & - 'Lateral distance from tower-top to arbitrary point on rotor-furl axis (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! RFrlPntzn - Vertical distance from tower-top to arbitrary point on rotor-furl axis. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlPntzn, 'RFrlPntzn', & - 'Vertical distance from tower-top to arbitrary point on rotor-furl axis (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! RFrlSkew - Rotor-furl axis skew angle (read in degrees and converted to radians here) - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlSkew, 'RFrlSkew', 'Rotor-furl axis skew angle (deg)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - InputFileData%RFrlSkew = InputFileData%RFrlSkew*D2R - - - ! RFrlTilt - Rotor-furl axis tilt angle (read in degrees and converted to radians here) - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlTilt, 'RFrlTilt', 'Rotor-furl axis tilt angle (deg)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - InputFileData%RFrlTilt = InputFileData%RFrlTilt*D2R - - - ! TFrlPntxn - Downwind distance from tower-top to arbitrary point on tail-furl axis. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlPntxn, 'TFrlPntxn', & - 'Downwind distance from tower-top to arbitrary point on tail-furl axis (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! TFrlPntyn - Lateral distance from tower-top to arbitrary point on tail-furl axis. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlPntyn, 'TFrlPntyn', & - 'Lateral distance from tower-top to arbitrary point on tail-furl axis (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! TFrlPntzn - Vertical distance from tower-top to arbitrary point on tail-furl axis. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlPntzn, 'TFrlPntzn', & - 'Vertical distance from tower-top to arbitrary point on tail-furl axis (m)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! TFrlSkew - Tail-furl axis skew angle (read in degrees and converted to radians here) - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlSkew, 'TFrlSkew', 'Tail-furl axis skew angle (deg)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - InputFileData%TFrlSkew = InputFileData%TFrlSkew *D2R - - - ! TFrlTilt - Tail-furl axis tilt angle (read in degrees and converted to radians here) - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlTilt, 'TFrlTilt', 'Tail-furl axis tilt angle (deg)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - InputFileData%TFrlTilt = InputFileData%TFrlTilt *D2R - - - ! -------------- MASS AND INERTIA (CONT) -------------------------------------- - - ! Skip the comment line. - - CALL ReadCom ( UnIn, FurlFile, 'mass and inertia (cont)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - ! RFrlMass - Mass of structure that furls with the rotor (not including rotor). - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlMass, 'RFrlMass', 'Rotor-furl mass (kg)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - ! BoomMass - Tail boom mass. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%BoomMass, 'BoomMass', 'Tail boom mass (kg)',ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! TFinMass - Tail fin mass. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFinMass, 'TFinMass', 'Tail fin mass (kg)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! RFrlIner - Inertia of structure that furls with the rotor about the rotor-furl axis (not including rotor). - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlIner, 'RFrlIner', 'Rotor-furl inertia about rotor-furl axis (kg m^2)', & - ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! TFrlIner - Tail boom inertia about tail-furl axis. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlIner, 'TFrlIner', 'Tail boom inertia about tail-furl axis (kg m^2)', & - ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - ! -------------- ROTOR-FURL --------------------------------------------------- - - ! Skip the comment line. - - CALL ReadCom ( UnIn, FurlFile, 'Section heading: Rotor-Furl', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! RFrlMod - Rotor-furl spring/damper model switch. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlMod, 'RFrlMod', 'Rotor-furl spring/damper model switch', & - ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! RFrlSpr - Rotor-furl spring constant. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlSpr, 'RFrlSpr', 'Rotor-furl spring constant (N-m/rad)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! RFrlDmp - Rotor-furl damping constant. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlDmp, 'RFrlDmp', 'Rotor-furl damping constant (N-m/(rad/s))', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! RFrlCDmp - Rotor-furl rate-independent Coulomb-damping moment. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlCDmp, 'RFrlCDmp', 'Rotor-furl rate-independent Coulomb-damping moment (N-m)', & - ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - - ! RFrlUSSP - Rotor-furl up-stop spring position (read in degrees and converted to radians here) - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlUSSP, 'RFrlUSSP', 'Rotor-furl up-stop spring position (deg)', & - ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - InputFileData%RFrlUSSP = InputFileData%RFrlUSSP*D2R - - - ! RFrlDSSP - Rotor-furl down-stop spring position (read in degrees and converted to radians here) - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlDSSP, 'RFrlDSSP', 'Rotor-furl down-stop spring position (deg)', & - ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - - InputFileData%RFrlDSSP = InputFileData%RFrlDSSP*D2R + ! -------------- BLADE MODE SHAPES -------------------------------------------- - ! RFrlUSSpr - Rotor-furl up-stop spring constant. + ! Skip the comment line. - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlUSSpr, 'RFrlUSSpr', 'Rotor-furl up-stop spring constant (N-m/rad)', ErrStat2, ErrMsg2, UnEc ) + CALL ReadCom ( UnIn, BldFile, 'blade mode shapes', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -2673,9 +1807,9 @@ SUBROUTINE ReadFurlFile( FurlFile, InputFileData, UnEc, ErrStat, ErrMsg ) END IF - ! RFrlDSSpr - Rotor-furl down-stop spring constant. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlDSSpr, 'RFrlDSSpr', 'Rotor-furl down-stop spring constant (N-m/rad)', ErrStat2, ErrMsg2, UnEc ) + ! BldFl1Sh - Blade-flap mode-1 shape coefficients. + CALL ReadAryLines ( UnIn, BldFile, BladeKInputFileData%BldFl1Sh, SIZE(BladeKInputFileData%BldFl1Sh), 'BldFl1Sh', & + 'Blade-flap mode-1 shape coefficients', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -2683,85 +1817,84 @@ SUBROUTINE ReadFurlFile( FurlFile, InputFileData, UnEc, ErrStat, ErrMsg ) END IF - ! RFrlUSDP - Rotor-furl up-stop damper position (read in degrees and converted to radians here) + ! BldFl2Sh - Blade-flap mode-2 shape coefficients. - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlUSDP, 'RFrlUSDP', 'Rotor-furl up-stop damper position (deg)', ErrStat2, ErrMsg2, UnEc ) + CALL ReadAryLines ( UnIn, BldFile, BladeKInputFileData%BldFl2Sh, SIZE(BladeKInputFileData%BldFl2Sh), 'BldFl2Sh', & + 'Blade-flap mode-2 shape coefficients', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF - InputFileData%RFrlUSDP = InputFileData%RFrlUSDP*D2R - - ! RFrlDSDP - Rotor-furl down-stop damper position (read in degrees and converted to radians here) + ! BldEdgSh - Blade-edge mode shape coefficients. - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlDSDP, 'RFrlDSDP', 'Rotor-furl down-stop damper position (deg)', ErrStat2, ErrMsg2, UnEc ) + CALL ReadAryLines ( UnIn, BldFile, BladeKInputFileData%BldEdgSh, SIZE(BladeKInputFileData%BldEdgSh), 'BldEdgSh', & + 'Blade-edge mode shape coefficients', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF - InputFileData%RFrlDSDP = InputFileData%RFrlDSDP*D2R - ! RFrlUSDmp - Rotor-furl up-stop damping constant. + ! -------------- END OF FILE -------------------------------------------- - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlUSDmp, 'RFrlUSDmp', 'Rotor-furl up-stop damping constant (N-m/(rad/s))', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF + ! Close the blade file. + call Cleanup() + RETURN - ! RFrlDSDmp - Rotor-furl down-stop damping constant. - CALL ReadVar ( UnIn, FurlFile, InputFileData%RFrlDSDmp, 'RFrlDSDmp', 'Rotor-furl down-stop damping constant (N-m/(rad/s))', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF +CONTAINS + SUBROUTINE Cleanup() + IF (UnIn > 0) CLOSE( UnIn ) + END SUBROUTINE Cleanup + +END SUBROUTINE ReadBladeFile +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine reads in the AeroDyn v14.00.00 input file to get the +!! blade discretization used in the structural dynamics module. +SUBROUTINE ReadBladeMeshFileAD( BladeKInputFileMesh, MeshFile, UnEc, ErrStat, ErrMsg ) +!.................................................................................................................................. - ! -------------- TAIL-FURL ---------------------------------------------------- + ! Passed variables - ! Skip the comment line. + TYPE(ED_BladeMeshInputData), INTENT(INOUT) :: BladeKInputFileMesh !< All the data in the ElastoDyn input file + CHARACTER(*), INTENT(IN) :: MeshFile !< Name of the AeroDyn input file data (for mesh) - CALL ReadCom ( UnIn, FurlFile, 'tail-furl', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF + INTEGER(IntKi), INTENT(IN) :: UnEc !< I/O unit for echo file. If present and > 0, write to UnEc + INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status + CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message + ! Local variables: + INTEGER(IntKi), PARAMETER :: NInputCols = 4 ! Number of input columns to be read from the file + REAL(ReKi) :: TmpRAry(NInputCols) ! Temporary variable to read table from file + INTEGER(IntKi) :: I ! loop counter + INTEGER(IntKi) :: NumLin2Skp ! number of lines to read + INTEGER(IntKi) :: NumFoil ! number of airfoil lines to skip in the AD input file. + INTEGER(IntKi) :: UnIn ! Unit number for reading file - ! TFrlMod - Tail-furl spring/damper model switch. + INTEGER(IntKi) :: ErrStat2 ! Temporary Error status + CHARACTER(ErrMsgLen) :: ErrMsg2 ! Temporary Err msg + CHARACTER(*), PARAMETER :: RoutineName = 'ReadBladeMeshFileAD' + CHARACTER(1024) :: Line ! Temporary string. +! CHARACTER(1024) :: TmpStr(1) ! Temporary string. - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlMod, 'TFrlMod', 'Tail-furl spring/damper model switch', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - ! TFrlSpr - Tail-furl spring constant. + ! Get an available unit number for the file. - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlSpr, 'TFrlSpr', 'Tail-furl spring constant (N-m/rad)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF + CALL GetNewUnit( UnIn, ErrStat, ErrMsg ) + IF ( ErrStat >= AbortErrLev ) RETURN - ! TFrlDmp - Tail-furl damping constant. + ! Open the AeroDyn input file. - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlDmp, 'TFrlDmp', 'Tail-furl damping constant (N-m/(rad/s))', ErrStat2, ErrMsg2, UnEc ) + CALL OpenFInpFile ( UnIn, MeshFile, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -2769,117 +1902,250 @@ SUBROUTINE ReadFurlFile( FurlFile, InputFileData, UnEc, ErrStat, ErrMsg ) END IF - ! TFrlCDmp - Tail-furl rate-independent Coulomb-damping moment. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlCDmp, 'TFrlCDmp', 'Tail-furl rate-independent Coulomb-damping moment (N-m)', & - ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - + ! Add a separator to the echo file if appropriate. - ! TFrlUSSP - Tail-furl up-stop spring position (read as degrees and converted to radians here) + IF ( UnEc > 0 ) WRITE (UnEc,'(//,A,/)') 'Mesh input data from (AeroDyn input) file "'//TRIM( MeshFile )//'":' - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlUSSP, 'TFrlUSSP', 'Tail-furl up-stop spring position (deg)', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF - InputFileData%TFrlUSSP = InputFileData%TFrlUSSP*D2R + ! -------------- HEADER ------------------------------------------------------- + ! BJJ: This file is AeroDyn's input file. Until we decide on a format for the + ! structural dynamics input, we will get this information from AeroDyn like we + ! used to. + DO I = 1,9 + CALL ReadCom ( UnIn, MeshFile, 'AeroDyn input (for structural dynamics mesh)', ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + END IF - ! TFrlDSSP - Tail-furl down-stop spring position (read as degrees and converted to radians here) + ! See if the next line is "NEWTOWER". If it is, read 7 more lines. If not, read 5 more lines. - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlDSSP, 'TFrlDSSP', 'Tail-furl down-stop spring position (deg)', ErrStat2, ErrMsg2, UnEc ) + CALL ReadVar( UnIn, MeshFile, Line, VarName='NewTowerModel?', VarDescr='Check for tower influence model', ErrStat=ErrStat2, ErrMsg=ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF - InputFileData%TFrlDSSP = InputFileData%TFrlDSSP*D2R + ! Check if this is the "special string" to indicate the new tower influence model + CALL Conv2UC( Line ) + IF ( INDEX(Line, "NEWTOWER" ) > 0 ) THEN + NumLin2Skp = 7 + ELSE + NumLin2Skp = 5 + END IF - ! TFrlUSSpr - Tail-furl up-stop spring constant. + DO I = 1,NumLin2Skp + CALL ReadCom ( UnIn, MeshFile, 'AeroDyn input (for structural dynamics mesh)', ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + END IF + END DO - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlUSSpr, 'TFrlUSSpr', 'Tail-furl up-stop spring constant (N-m/rad)', ErrStat2, ErrMsg2, UnEc ) + CALL ReadVar ( UnIn, MeshFile, NumFoil, 'NumFoil', & + 'Number of airfoil lines to skip in AeroDyn input (for structural dynamics mesh)', ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF + DO I = 1,NumFoil + CALL ReadCom ( UnIn, MeshFile, 'AeroDyn input (for structural dynamics mesh)', ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + END IF + END DO - ! TFrlDSSpr - Tail-furl down-stop spring constant. - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlDSSpr, 'TFrlDSSpr', 'Tail-furl down-stop spring constant (N-m/rad)', ErrStat2, ErrMsg2, UnEc ) + ! -------------- Blade Mesh Data -------------------------------------------------- + + ! Read in the number of blade elements + CALL ReadVar( UnIn, MeshFile, BladeKInputFileMesh%BldNodes, 'BldNodes', 'Number of blade elements', ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF - - ! TFrlUSDP - Tail-furl up-stop damper position. - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlUSDP, 'TFrlUSDP', 'Tail-furl up-stop damper position (deg)', ErrStat2, ErrMsg2, UnEc ) + ! Allocate the arrays to store input + CALL Alloc_BladeMeshInputProperties( BladeKInputFileMesh, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF - InputFileData%TFrlUSDP = InputFileData%TFrlUSDP*D2R - - - ! TFrlDSDP - Tail-furl down-stop damper position (read as degrees and converted to radians here) - - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlDSDP, 'TFrlDSDP', 'Tail-furl down-stop damper position (deg)', ErrStat2, ErrMsg2, UnEc ) + ! Read comment line for the element table + CALL ReadCom( UnIn, MeshFile, 'Blade element table headers', ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF - InputFileData%TFrlDSDP = InputFileData%TFrlDSDP*D2R + DO I = 1, BladeKInputFileMesh%BldNodes + CALL ReadAry( UnIn, MeshFile, TmpRAry, NInputCols, 'Blade element line'//TRIM(Num2LStr(I)), 'Blade element input table', ErrStat2, ErrMsg2, UnEc ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + END IF - ! TFrlUSDmp - Tail-furl up-stop damping constant. + BladeKInputFileMesh%RNodes( I) = TmpRAry(1) + BladeKInputFileMesh%AeroTwst(I) = TmpRAry(2)*D2R !Convert input file data (degrees) to radians + BladeKInputFileMesh%Chord( I) = TmpRAry(4) - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlUSDmp, 'TFrlUSDmp', 'Tail-furl up-stop damping constant (N-m/(rad/s))', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF + END DO + !bjj: move this to a validation routine if we plan to keep AD14 stuff in ElastoDyn: + IF ( ANY( BladeKInputFileMesh%Chord < 0.0_ReKi ) ) THEN + call SetErrStat( ErrID_Fatal, 'Chord length must be larger than 0 meters.', ErrStat, ErrMsg, RoutineName ) + RETURN + END IF - ! TFrlDSDmp - Tail-furl down-stop damping constant. - CALL ReadVar ( UnIn, FurlFile, InputFileData%TFrlDSDmp, 'TFrlDSDmp', 'Tail-furl down-stop damping constant (N-m/(rad/s))', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - END IF + ! Close the input file: - ! Close the ElastoDyn furling file: + CALL cleanup() + RETURN - call Cleanup() - RETURN CONTAINS SUBROUTINE Cleanup() CLOSE( UnIn ) END SUBROUTINE Cleanup +END SUBROUTINE ReadBladeMeshFileAD +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine reads the furling file input and converts units as appropriate. +SUBROUTINE ReadFurlFile( FurlFile, InputFileData, UnEc, ErrStat, ErrMsg ) + TYPE(ED_InputFile), INTENT(INOUT) :: InputFileData !< All the data in the ElastoDyn input file + INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status + INTEGER(IntKi), INTENT(IN) :: UnEc !< I/O unit for echo file. If present and > 0, write to UnEc + CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message + CHARACTER(*), INTENT(IN) :: FurlFile !< Name of the furling input file data + ! Local variables: + type(FileInfoType) :: FileInfo_In ! < The derived type for holding the file information. + integer(IntKi) :: iLine !< current entry in FileInfo_In%Lines array + character(len=1024 ) :: DummyLine + integer(IntKi) :: ErrStat2 !< Temporary Error status + character(ErrMsgLen) :: ErrMsg2 !< Temporary Error message + + ! --- Read TailFurl input file into array of strings + call ProcessComFile( FurlFile, FileInfo_In, ErrStat2, ErrMsg2) + + ! --- Parse the array of strings + + ! Skip the first two lines as they are known to be header lines and separators + do iLine = 1,2 + if ( UnEc>0 ) WRITE(UnEc, '(A)') FileInfo_In%Lines(iLine) ! Write header to echo + enddo + iLine = 3 + !---------------------- FEATURE FLAGS ------------------------------------------- + call ParseCom(FileInfo_in, iLine, DummyLine , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlDOF' , InputFileData%RFrlDOF , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlDOF' , InputFileData%TFrlDOF , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + + ! ---------------------- INITIAL CONDITIONS -------------------------------------- + call ParseCom(FileInfo_in, iLine, DummyLine , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RotFurl' , InputFileData%RotFurl , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TailFurl' , InputFileData%TailFurl , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + + ! ---------------------- TURBINE CONFIGURATION ----------------------------------- + call ParseCom(FileInfo_in, iLine, DummyLine , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'Yaw2Shft' , InputFileData%Yaw2Shft , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'ShftSkew' , InputFileData%ShftSkew , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseAry(FileInfo_in, iLine, 'RFrlCM_n' , InputFileData%RFrlCM_n ,3,ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseAry(FileInfo_in, iLine, 'BoomCM_n' , InputFileData%BoomCM_n ,3,ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseAry(FileInfo_in, iLine, 'TFinCM_n' , InputFileData%TFinCM_n ,3,ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseAry(FileInfo_in, iLine, 'RFrlPnt_n', InputFileData%RFrlPnt_n,3,ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlSkew' , InputFileData%RFrlSkew , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlTilt' , InputFileData%RFrlTilt , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseAry(FileInfo_in, iLine, 'TFrlPnt_n', InputFileData%TFrlPnt_n,3,ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlSkew' , InputFileData%TFrlSkew , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlTilt' , InputFileData%TFrlTilt , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + + ! ---------------------- MASS AND INERTIA ---------------------------------------- + call ParseCom(FileInfo_in, iLine, DummyLine , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlMass' , InputFileData%RFrlMass , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'BoomMass' , InputFileData%BoomMass , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFinMass' , InputFileData%TFinMass , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlIner' , InputFileData%RFrlIner , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlIner' , InputFileData%TFrlIner , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + + ! ---------------------- ROTOR-FURL ---------------------------------------------- + call ParseCom(FileInfo_in, iLine, DummyLine , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlMod' , InputFileData%RFrlMod , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlSpr' , InputFileData%RFrlSpr , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlDmp' , InputFileData%RFrlDmp , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlUSSP' , InputFileData%RFrlUSSP , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlDSSP' , InputFileData%RFrlDSSP , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlUSSpr', InputFileData%RFrlUSSpr, ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlDSSpr', InputFileData%RFrlDSSpr, ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlUSDP' , InputFileData%RFrlUSDP , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlDSDP' , InputFileData%RFrlDSDP , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlUSDmp', InputFileData%RFrlUSDmp, ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'RFrlDSDmp', InputFileData%RFrlDSDmp, ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + + ! ---------------------- TAIL-FURL ----------------------------------------------- + call ParseCom(FileInfo_in, iLine, DummyLine , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlMod' , InputFileData%TFrlMod , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlSpr' , InputFileData%TFrlSpr , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlDmp' , InputFileData%TFrlDmp , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlUSSP' , InputFileData%TFrlUSSP , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlDSSP' , InputFileData%TFrlDSSP , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlUSSpr', InputFileData%TFrlUSSpr, ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlDSSpr', InputFileData%TFrlDSSpr, ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlUSDP' , InputFileData%TFrlUSDP , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlDSDP' , InputFileData%TFrlDSDP , ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlUSDmp', InputFileData%TFrlUSDmp, ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + call ParseVar(FileInfo_in, iLine, 'TFrlDSDmp', InputFileData%TFrlDSDmp, ErrStat2, ErrMsg2, UnEc); if (Failed()) return; + + + ! --- Triggers + InputFileData%RotFurl = InputFileData%RotFurl * D2R + InputFileData%TailFurl = InputFileData%TailFurl * D2R + InputFileData%ShftSkew = InputFileData%ShftSkew * D2R + InputFileData%RFrlSkew = InputFileData%RFrlSkew * D2R + InputFileData%RFrlTilt = InputFileData%RFrlTilt * D2R + InputFileData%TFrlSkew = InputFileData%TFrlSkew * D2R + InputFileData%TFrlTilt = InputFileData%TFrlTilt * D2R + InputFileData%RFrlUSSP = InputFileData%RFrlUSSP * D2R + InputFileData%RFrlDSSP = InputFileData%RFrlDSSP * D2R + InputFileData%RFrlUSDP = InputFileData%RFrlUSDP * D2R + InputFileData%RFrlDSDP = InputFileData%RFrlDSDP * D2R + InputFileData%TFrlUSSP = InputFileData%TFrlUSSP * D2R + InputFileData%TFrlDSSP = InputFileData%TFrlDSSP * D2R + InputFileData%TFrlUSDP = InputFileData%TFrlUSDP * D2R + InputFileData%TFrlDSDP = InputFileData%TFrlDSDP * D2R + + + + +contains + logical function Failed() + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'ReadFurlFile' ) + Failed = ErrStat >= AbortErrLev + end function Failed + + subroutine Fatal(ErrMsg_in) + character(len=*), intent(in) :: ErrMsg_in + call SetErrStat(ErrID_Fatal, 'File:'//trim(FurlFile)//':'//trim(ErrMsg_in), ErrStat, ErrMsg, 'ReadFurlFile') + end subroutine Fatal + END SUBROUTINE ReadFurlFile !---------------------------------------------------------------------------------------------------------------------------------- !> This routine reads the tower file input. -SUBROUTINE ReadTowerFile( TwrFile, InputFileData, ReadAdmVals, UnEc, ErrStat, ErrMsg ) +SUBROUTINE ReadTowerFile( TwrFile, InputFileData, UnEc, ErrStat, ErrMsg ) !.................................................................................................................................. IMPLICIT NONE @@ -2888,7 +2154,6 @@ SUBROUTINE ReadTowerFile( TwrFile, InputFileData, ReadAdmVals, UnEc, ErrStat, Er INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status INTEGER(IntKi), INTENT(IN) :: UnEc !< I/O unit for echo file. If present and > 0, write to UnEc - LOGICAL, INTENT(IN) :: ReadAdmVals !< Logical to determine if Adams inputs should be read from file CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message CHARACTER(*), INTENT(IN) :: TwrFile !< Name of the tower input file data TYPE(ED_InputFile), INTENT(INOUT) :: InputFileData !< All the data in the ElastoDyn input file @@ -2969,7 +2234,7 @@ SUBROUTINE ReadTowerFile( TwrFile, InputFileData, ReadAdmVals, UnEc, ErrStat, Er ! Allocate the input arrays based on this NTwInpSt input - CALL Alloc_TowerInputProperties( InputFileData, ReadAdmVals, ErrStat, ErrMsg ) + CALL Alloc_TowerInputProperties( InputFileData, ErrStat, ErrMsg ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -3117,12 +2382,8 @@ SUBROUTINE ReadTowerFile( TwrFile, InputFileData, ReadAdmVals, UnEc, ErrStat, Er ! Read the table. - - IF ( ReadAdmVals ) THEN - NInputCols = 10 - ELSE - NInputCols = 4 - END IF + + NInputCols = 4 DO I=1,InputFileData%NTwInpSt @@ -3140,15 +2401,6 @@ SUBROUTINE ReadTowerFile( TwrFile, InputFileData, ReadAdmVals, UnEc, ErrStat, Er InputFileData%TwFAStif(I) = TmpRAry(3)*AdjFASt ! Apply the correction factors to the elemental data. InputFileData%TwSSStif(I) = TmpRAry(4)*AdjSSSt ! Apply the correction factors to the elemental data. - IF ( NInputCols > 4 ) THEN - InputFileData%TwGJStif(I) = TmpRAry( 5) - InputFileData%TwEAStif(I) = TmpRAry( 6) - InputFileData%TwFAIner(I) = TmpRAry( 7) - InputFileData%TwSSIner(I) = TmpRAry( 8) - InputFileData%TwFAcgOf(I) = TmpRAry( 9) - InputFileData%TwSScgOf(I) = TmpRAry(10) - END IF - END DO ! I @@ -3851,48 +3103,48 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, BldFile, FurlFile, TwrFile RETURN END IF - ! TowerHt - Height of tower above ground level [onshore] or MSL [offshore] (meters): - CALL ReadVar( UnIn, InputFile, InputFileData%TowerHt, "TowerHt", "Height of tower above ground level [onshore] or MSL [offshore] (meters)", ErrStat2, ErrMsg2, UnEc) + ! TowerHt - Height of tower relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] (meters): + CALL ReadVar( UnIn, InputFile, InputFileData%TowerHt, "TowerHt", "Height of tower above ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] (meters)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF - ! TowerBsHt - Height of tower base above ground level [onshore] or MSL [offshore] (meters): - CALL ReadVar( UnIn, InputFile, InputFileData%TowerBsHt, "TowerBsHt", "Height of tower base above ground level [onshore] or MSL [offshore] (meters)", ErrStat2, ErrMsg2, UnEc) + ! TowerBsHt - Height of tower base relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] (meters): + CALL ReadVar( UnIn, InputFile, InputFileData%TowerBsHt, "TowerBsHt", "Height of tower base above ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] (meters)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF - ! PtfmCMxt - Downwind distance from the ground [onshore] or MSL [offshore] to the platform CM (meters): - CALL ReadVar( UnIn, InputFile, InputFileData%PtfmCMxt, "PtfmCMxt", "Downwind distance from the ground [onshore] or MSL [offshore] to the platform CM (meters)", ErrStat2, ErrMsg2, UnEc) + ! PtfmCMxt - Downwind distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM (meters): + CALL ReadVar( UnIn, InputFile, InputFileData%PtfmCMxt, "PtfmCMxt", "Downwind distance from the ground [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM (meters)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF - ! PtfmCMyt - Lateral distance from the ground [onshore] or MSL [offshore] to the platform CM (meters): - CALL ReadVar( UnIn, InputFile, InputFileData%PtfmCMyt, "PtfmCMzt", "Lateral distance from the ground [onshore] or MSL [offshore] to the platform CM (meters)", ErrStat2, ErrMsg2, UnEc) + ! PtfmCMyt - Lateral distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM (meters): + CALL ReadVar( UnIn, InputFile, InputFileData%PtfmCMyt, "PtfmCMyt", "Lateral distance from the ground [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM (meters)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF - ! PtfmCMzt - Vertical distance from the ground [onshore] or MSL [offshore] to the platform CM (meters): - CALL ReadVar( UnIn, InputFile, InputFileData%PtfmCMzt, "PtfmCMzt", "Vertical distance from the ground [onshore] or MSL [offshore] to the platform CM (meters)", ErrStat2, ErrMsg2, UnEc) + ! PtfmCMzt - Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM (meters): + CALL ReadVar( UnIn, InputFile, InputFileData%PtfmCMzt, "PtfmCMzt", "Vertical distance from the ground [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM (meters)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() RETURN END IF - ! PtfmRefzt - Vertical distance from the ground [onshore] or MSL [offshore] to the platform reference point (meters): - CALL ReadVar( UnIn, InputFile, InputFileData%PtfmRefzt, "PtfmRefzt", "Vertical distance from the ground [onshore] or MSL [offshore] to the platform reference point (meters)", ErrStat2, ErrMsg2, UnEc) + ! PtfmRefzt - Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform reference point (meters): + CALL ReadVar( UnIn, InputFile, InputFileData%PtfmRefzt, "PtfmRefzt", "Vertical distance from the ground [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform reference point (meters)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -4417,11 +3669,10 @@ SUBROUTINE Alloc_BladeMeshInputProperties( BladeKInputFileMesh, ErrStat, ErrMsg END SUBROUTINE Alloc_BladeMeshInputProperties !---------------------------------------------------------------------------------------------------------------------------------- !> This routine allocates arrays for the blade properties from the input file. -SUBROUTINE Alloc_BladeInputProperties( BladeKInputFileData, AllocAdams, ErrStat, ErrMsg ) +SUBROUTINE Alloc_BladeInputProperties( BladeKInputFileData, ErrStat, ErrMsg ) !.................................................................................................................................. TYPE(BladeInputData), INTENT(INOUT) :: BladeKInputFileData !< Data for Blade K stored in the module's input file - LOGICAL, INTENT(IN) :: AllocAdams !< Logical to determine if we should allocate the arrays only used for Adams INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status CHARACTER(*), INTENT(OUT) :: ErrMsg !< Err message @@ -4449,32 +3700,6 @@ SUBROUTINE Alloc_BladeInputProperties( BladeKInputFileData, AllocAdams, ErrStat, IF ( ErrStat /= ErrID_None ) RETURN - IF ( AllocAdams ) THEN - CALL AllocAry ( BladeKInputFileData%GJStff, BladeKInputFileData%NBlInpSt, 'GJStff' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( BladeKInputFileData%EAStff, BladeKInputFileData%NBlInpSt, 'EAStff' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( BladeKInputFileData%Alpha, BladeKInputFileData%NBlInpSt, 'Alpha' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( BladeKInputFileData%FlpIner, BladeKInputFileData%NBlInpSt, 'FlpIner' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( BladeKInputFileData%EdgIner, BladeKInputFileData%NBlInpSt, 'EdgIner' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( BladeKInputFileData%PrecrvRef,BladeKInputFileData%NBlInpSt, 'PrecrvRef', ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( BladeKInputFileData%PreswpRef,BladeKInputFileData%NBlInpSt, 'PreswpRef', ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( BladeKInputFileData%FlpcgOf, BladeKInputFileData%NBlInpSt, 'FlpcgOf' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( BladeKInputFileData%EdgcgOf, BladeKInputFileData%NBlInpSt, 'EdgcgOf' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( BladeKInputFileData%FlpEAOf, BladeKInputFileData%NBlInpSt, 'FlpEAOf' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( BladeKInputFileData%EdgEAOf, BladeKInputFileData%NBlInpSt, 'EdgEAOf' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - END IF - - ! BJJ: note that these used to be allocated 2:PolyOrd : CALL AllocAry ( BladeKInputFileData%BldFl1Sh, PolyOrd-1, 'BldFl1Sh' , ErrStat, ErrMsg ) @@ -4488,11 +3713,10 @@ SUBROUTINE Alloc_BladeInputProperties( BladeKInputFileData, AllocAdams, ErrStat, END SUBROUTINE Alloc_BladeInputProperties !---------------------------------------------------------------------------------------------------------------------------------- !> This routine allocates arrays for the tower properties from the input file. -SUBROUTINE Alloc_TowerInputProperties( InputFileData, AllocAdams, ErrStat, ErrMsg ) +SUBROUTINE Alloc_TowerInputProperties( InputFileData, ErrStat, ErrMsg ) !.................................................................................................................................. TYPE(ED_InputFile), INTENT(INOUT) :: InputFileData !< All the data in the ElastoDyn input file - LOGICAL, INTENT(IN) :: AllocAdams !< Determines if the columns for Adams data will be read INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message @@ -4515,21 +3739,6 @@ SUBROUTINE Alloc_TowerInputProperties( InputFileData, AllocAdams, ErrStat, ErrMs CALL AllocAry ( InputFileData%TwSSStif, InputFileData%NTwInpSt, 'TwSSStif' , ErrStat, ErrMsg ) IF ( ErrStat /= ErrID_None ) RETURN - IF ( AllocAdams ) THEN - CALL AllocAry ( InputFileData%TwGJStif, InputFileData%NTwInpSt, 'TwGJStif' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( InputFileData%TwEAStif, InputFileData%NTwInpSt, 'TwEAStif' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( InputFileData%TwFAIner, InputFileData%NTwInpSt, 'TwFAIner' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( InputFileData%TwSSIner, InputFileData%NTwInpSt, 'TwSSIner' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( InputFileData%TwFAcgOf, InputFileData%NTwInpSt, 'TwFAcgOf' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - CALL AllocAry ( InputFileData%TwSScgOf, InputFileData%NTwInpSt, 'TwSScgOf' , ErrStat, ErrMsg ) - IF ( ErrStat /= ErrID_None ) RETURN - END IF - ! BJJ: note that these used to be allocated 2:PolyOrd : CALL AllocAry ( InputFileData%TwFAM1Sh, PolyOrd-1, 'TwFAM1Sh' , ErrStat, ErrMsg ) @@ -4612,61 +3821,6 @@ SUBROUTINE ValidateBladeData ( BladeKInputFileData, ErrStat, ErrMsg ) END DO - ! Check values for Adams input - - IF ( ALLOCATED(BladeKInputFileData%GJStff) ) THEN ! We assume that if GJStff is allocated, we are using ADAMS inputs - - ! The reference axis must be coincident with the pitch axis at the blade root (I == 1): - IF ( .NOT. EqualRealNos( BladeKInputFileData%PrecrvRef(1), 0.0_ReKi ) .OR. & - .NOT. EqualRealNos( BladeKInputFileData%PreswpRef(1), 0.0_ReKi ) ) THEN - CALL SetErrStat( ErrID_Fatal,'Both PrecrvRef(1) and PreswpRef(1) must be zero '//& - '(the reference axis must be coincident with the pitch axis at the blade root).',ErrStat,ErrMsg,RoutineName) - END IF - - - DO I = 1,BladeKInputFileData%NBlInpSt - - ! Check that GJStff is contained in (0.0, inf): - IF ( BladeKInputFileData%GJStff(I) <= 0.0_ReKi ) THEN - CALL SetErrStat( ErrID_Fatal,'GJStff('//TRIM( Num2LStr( I ) )//') must be greater than zero.',ErrStat,ErrMsg,RoutineName) - END IF - - ! Check that EAStff is contained in (0.0, inf): - IF ( BladeKInputFileData%EAStff(I) <= 0.0_ReKi ) THEN - CALL SetErrStat( ErrID_Fatal,'EAStff('//TRIM( Num2LStr( I ) )//') must be greater than zero.',ErrStat,ErrMsg,RoutineName) - END IF - - ! Check that Alpha is contained in (-1.0, 1): - IF ( ( BladeKInputFileData%Alpha(I) <= -1.0_ReKi ) .OR. ( BladeKInputFileData%Alpha(I) >= 1.0_ReKi ) ) THEN - CALL SetErrStat( ErrID_Fatal,'Alpha('//TRIM( Num2LStr( I ) )//') (the blade flap/twist'// & - ' coupling coefficient) must be between -1 and 1 (exclusive).',ErrStat,ErrMsg,RoutineName) - END IF - - ! Check that FlpIner is contained in [0.0, inf): - IF ( BladeKInputFileData%FlpIner(I) < 0.0_ReKi ) THEN - CALL SetErrStat( ErrID_Fatal,'FlpIner('//TRIM( Num2LStr( I ) )//') must not be less than zero.',ErrStat,ErrMsg,RoutineName) - END IF - - ! Check that EdgIner is contained in [0.0, inf): - IF ( BladeKInputFileData%EdgIner(I) < 0.0_ReKi ) THEN - CALL SetErrStat( ErrID_Fatal,'EdgIner('//TRIM( Num2LStr( I ) )//') must not be less than zero.',ErrStat,ErrMsg,RoutineName) - END IF - - ! Check that PrecrvRef is 0.0 for Adams models: - IF ( .NOT. EqualRealNos( BladeKInputFileData%PrecrvRef(I), 0.0_ReKi) ) THEN - CALL SetErrStat( ErrID_Fatal,'PrecrvRef('//TRIM( Num2LStr( I ) )//') must be zero for Adams models.',ErrStat,ErrMsg,RoutineName) - END IF - - ! Check that GJStff is contained in (0.0, inf): - IF ( .NOT. EqualRealNos( BladeKInputFileData%PreswpRef(I), 0.0_ReKi) ) THEN - CALL SetErrStat( ErrID_Fatal,'PreswpRef('//TRIM( Num2LStr( I ) )//') must be zero for Adams models.',ErrStat,ErrMsg,RoutineName) - END IF - - END DO - - END IF ! check for Adams models - - ! Check that the blade damping is not negative: IF ( ANY( BladeKInputFileData%BldFlDmp < 0.0_ReKi ) ) CALL SetErrStat( ErrID_Fatal,'BldFlDmp must not be negative.',ErrStat,ErrMsg,RoutineName) @@ -4771,31 +3925,6 @@ SUBROUTINE ValidateTowerData ( InputFileData, ErrStat, ErrMsg ) END IF END DO - ! Check Adams inputs - - IF ( ALLOCATED( InputFileData%TwGJStif ) ) THEN ! Assume that all of the Adams tower data is allocated - - DO I = 1,InputFileData%NTwInpSt - IF ( InputFileData%TwGJStif(I) <= 0.0_ReKi ) THEN - CALL SetErrStat( ErrID_Fatal, 'TwGJStif('//TRIM(Num2LStr( I ))//') must be greater than zero.', ErrStat, ErrMsg, RoutineName) - END IF - - IF ( InputFileData%TwEAStif(I) <= 0.0_ReKi ) THEN - CALL SetErrStat( ErrID_Fatal, 'TwEAStif('//TRIM(Num2LStr( I ))//') must be greater than zero.', ErrStat, ErrMsg, RoutineName) - END IF - - IF ( InputFileData%TwFAIner(I) <= 0.0_ReKi ) THEN - CALL SetErrStat( ErrID_Fatal, 'TwFAIner('//TRIM(Num2LStr( I ))//') must be greater than zero.', ErrStat, ErrMsg, RoutineName) - END IF - - IF ( InputFileData%TwSSIner(I) <= 0.0_ReKi ) THEN - CALL SetErrStat( ErrID_Fatal, 'TwSSIner('//TRIM(Num2LStr( I ))//') must be greater than zero.', ErrStat, ErrMsg, RoutineName) - END IF - END DO - - END IF ! Check items for Adams - - ! Check that the tower damping (TwrFADmp) is contained in the range [0, 100]: @@ -4864,8 +3993,6 @@ SUBROUTINE ValidateFurlData( InputFileData, ErrStat, ErrMsg ) CALL CheckAngle180Range( InputFileData%RotFurl, 'RotFurl' ) CALL CheckAngle180Range( InputFileData%TailFurl, 'TailFurl' ) - CALL CheckAngle180Range( InputFileData%TFinSkew, 'TFinSkew' ) - CALL CheckAngle180Range( InputFileData%TFinBank, 'TFinBank' ) CALL CheckAngle180Range( InputFileData%RFrlSkew, 'RFrlSkew' ) CALL CheckAngle180Range( InputFileData%TFrlSkew, 'TFrlSkew' ) @@ -4896,10 +4023,6 @@ SUBROUTINE ValidateFurlData( InputFileData, ErrStat, ErrMsg ) ! Check that tilt angles are in the range [-pi/2, pi/2] radians (i.e., [-90, 90] degrees ): - - IF ( ABS( InputFileData%TFinTilt ) > PiBy2 ) THEN - CALL SetErrStat(ErrID_Fatal,'TFinTilt must be between -pi/2 and pi/2 radians (i.e., in the range [-90, 90] degrees).',ErrStat,ErrMsg,RoutineName) - END IF IF ( ABS( InputFileData%RFrlTilt ) > PiBy2 ) THEN CALL SetErrStat(ErrID_Fatal,'RFrlTilt must be between -pi/2 and pi/2 radians (i.e., in the range [-90, 90] degrees).',ErrStat,ErrMsg,RoutineName) END IF @@ -4921,19 +4044,14 @@ SUBROUTINE ValidateFurlData( InputFileData, ErrStat, ErrMsg ) ! Warn if tail is defined upwind of the tower: - IF ( InputFileData%BoomCMxn < 0.0_ReKi ) THEN ! Print out warning when tail boom CM defined upwind of the tower. - CALL SetErrStat( ErrID_Warn,'WARNING: Tail boom CM is defined upwind of the tower (BoomCMxn < 0).',ErrStat,ErrMsg,RoutineName) + IF ( InputFileData%BoomCM_n(1) < 0.0_ReKi ) THEN ! Print out warning when tail boom CM defined upwind of the tower. + CALL SetErrStat( ErrID_Warn,'WARNING: Tail boom CM is defined upwind of the tower (BoomCM_n(1) < 0).',ErrStat,ErrMsg,RoutineName) ENDIF - IF ( InputFileData%TFinCMxn < 0.0_ReKi ) THEN ! Print out warning when tail fin CM defined upwind of the tower. - CALL SetErrStat( ErrID_Warn,'WARNING: Tail fin CM is defined upwind of the tower (TFinCMxn < 0).',ErrStat,ErrMsg,RoutineName) + IF ( InputFileData%TFinCM_n(1) < 0.0_ReKi ) THEN ! Print out warning when tail fin CM defined upwind of the tower. + CALL SetErrStat( ErrID_Warn,'WARNING: Tail fin CM is defined upwind of the tower (TFinCM_n(1) < 0).',ErrStat,ErrMsg,RoutineName) ENDIF - IF ( InputFileData%TFinCPxn < 0.0_ReKi ) THEN ! Print out warning when tail fin CP defined upwind of the tower. - CALL SetErrStat( ErrID_Warn,'WARNING: Tail fin CP is defined upwind of the tower (TFinCPxn < 0).',ErrStat,ErrMsg,RoutineName) - ENDIF - - ! Check that mass, inertias, damping, etc. values aren't negative: IF (InputFileData%RFrlMass < 0.0_ReKi) call SetErrStat(ErrID_Fatal, 'RFrlMass must not be negative.',ErrStat,ErrMsg,RoutineName) @@ -4943,14 +4061,12 @@ SUBROUTINE ValidateFurlData( InputFileData, ErrStat, ErrMsg ) IF (InputFileData%TFrlIner < 0.0_ReKi) call SetErrStat(ErrID_Fatal, 'TFrlIner must not be negative.',ErrStat,ErrMsg,RoutineName) IF (InputFileData%RFrlSpr < 0.0_ReKi) call SetErrStat(ErrID_Fatal, 'RFrlSpr must not be negative.',ErrStat,ErrMsg,RoutineName) IF ( InputFileData%RFrlDmp < 0.0_ReKi) call SetErrStat(ErrID_Fatal, 'RFrlDmp must not be negative.',ErrStat,ErrMsg,RoutineName) - IF ( InputFileData%RFrlCDmp < 0.0_ReKi) call SetErrStat(ErrID_Fatal, 'RFrlCDmp must not be negative.',ErrStat,ErrMsg,RoutineName) IF ( InputFileData%RFrlUSSpr < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'RFrlUSSpr must not be negative.',ErrStat,ErrMsg,RoutineName) IF ( InputFileData%RFrlDSSpr < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'RFrlDSSpr must not be negative.',ErrStat,ErrMsg,RoutineName) IF ( InputFileData%RFrlUSDmp < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'RFrlUSDmp must not be negative.',ErrStat,ErrMsg,RoutineName) IF ( InputFileData%RFrlDSDmp < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'RFrlDSDmp must not be negative.',ErrStat,ErrMsg,RoutineName) IF ( InputFileData%TFrlSpr < 0.0_ReKi) call SetErrStat(ErrID_Fatal, 'TFrlSpr must not be negative.',ErrStat,ErrMsg,RoutineName) IF ( InputFileData%TFrlDmp < 0.0_ReKi) call SetErrStat(ErrID_Fatal, 'TFrlDmp must not be negative.',ErrStat,ErrMsg,RoutineName) - IF ( InputFileData%TFrlCDmp < 0.0_ReKi) call SetErrStat(ErrID_Fatal, 'TFrlCDmp must not be negative.',ErrStat,ErrMsg,RoutineName) IF ( InputFileData%TFrlUSSpr < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'TFrlUSSpr must not be negative.',ErrStat,ErrMsg,RoutineName) IF ( InputFileData%TFrlDSSpr < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'TFrlDSSpr must not be negative.',ErrStat,ErrMsg,RoutineName) IF ( InputFileData%TFrlUSDmp < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'TFrlUSDmp must not be negative.',ErrStat,ErrMsg,RoutineName) @@ -4999,7 +4115,7 @@ END SUBROUTINE ValidateFurlData !---------------------------------------------------------------------------------------------------------------------------------- !> This routine validates the inputs from the primary input file. !! note that all angles are assumed to be in radians in this routine: -SUBROUTINE ValidatePrimaryData( InputFileData, BD4Blades, Linearize, ErrStat, ErrMsg ) +SUBROUTINE ValidatePrimaryData( InputFileData, BD4Blades, Linearize, MHK, ErrStat, ErrMsg ) !.................................................................................................................................. ! Passed variables: @@ -5007,6 +4123,7 @@ SUBROUTINE ValidatePrimaryData( InputFileData, BD4Blades, Linearize, ErrStat, Er TYPE(ED_InputFile), INTENT(IN) :: InputFileData !< All the data in the ElastoDyn input file LOGICAL, INTENT(IN) :: BD4Blades !< Use BeamDyn for blades, thus ignore ElastoDyn blade info LOGICAL, INTENT(IN) :: Linearize !< Flag indicating glue code wants to linearize this module + INTEGER(IntKi), INTENT(IN) :: MHK !< MHK turbine type switch INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message @@ -5066,8 +4183,12 @@ SUBROUTINE ValidatePrimaryData( InputFileData, BD4Blades, Linearize, ErrStat, Er IF ( InputFileData%YawBrMass < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'YawBrMass must not be negative.',ErrStat,ErrMsg,RoutineName) IF ( InputFileData%NacMass < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'NacMass must not be negative.',ErrStat,ErrMsg,RoutineName) IF ( InputFileData%HubMass < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'HubMass must not be negative.',ErrStat,ErrMsg,RoutineName) - IF ( InputFileData%Twr2Shft < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'Twr2Shft must not be negative.',ErrStat,ErrMsg,RoutineName) - + IF ( MHK /= 2 ) THEN + IF ( InputFileData%Twr2Shft < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'Twr2Shft must not be negative.',ErrStat,ErrMsg,RoutineName) + ELSEIF ( MHK == 2 ) THEN + IF ( InputFileData%Twr2Shft > 0.0_ReKi) call SetErrStat(ErrID_Fatal,'Twr2Shft must not be positive for a floating MHK turbine.',ErrStat,ErrMsg,RoutineName) + ENDIF + DO K=1,InputFileData%NumBl IF ( InputFileData%TipMass(K) < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'TipMass('//TRIM( Num2LStr( K ) )//') must not be negative.',ErrStat,ErrMsg,RoutineName) ENDDO ! K @@ -5077,7 +4198,11 @@ SUBROUTINE ValidatePrimaryData( InputFileData, BD4Blades, Linearize, ErrStat, Er IF ( InputFileData%HubIner < 0.0_ReKi) call SetErrStat(ErrID_Fatal,'HubIner must not be negative.',ErrStat,ErrMsg,RoutineName) ! Check that TowerHt is in the range [0,inf): - IF ( InputFileData%TowerHt <= 0.0_ReKi ) CALL SetErrStat( ErrID_Fatal, 'TowerHt must be greater than zero.',ErrStat,ErrMsg,RoutineName ) + IF ( MHK /= 2 ) THEN + IF ( InputFileData%TowerHt <= 0.0_ReKi ) CALL SetErrStat( ErrID_Fatal, 'TowerHt must be greater than zero.',ErrStat,ErrMsg,RoutineName ) + ELSEIF ( MHK == 2 ) THEN + IF ( InputFileData%TowerHt >= 0.0_ReKi ) CALL SetErrStat( ErrID_Fatal, 'TowerHt must be less than zero for a floating MHK turbine.',ErrStat,ErrMsg,RoutineName ) + ENDIF ! Check that these integers are in appropriate ranges: IF ( InputFileData%TwrNodes < 1_IntKi ) CALL SetErrStat( ErrID_Fatal, 'TwrNodes must not be less than 1.',ErrStat,ErrMsg,RoutineName ) @@ -5116,22 +4241,37 @@ SUBROUTINE ValidatePrimaryData( InputFileData, BD4Blades, Linearize, ErrStat, Er END IF ENDIF - IF ( InputFileData%TowerBsHt >= InputFileData%TowerHt ) CALL SetErrStat( ErrID_Fatal, 'TowerBsHt must be less than TowerHt.',ErrStat,ErrMsg,RoutineName) + IF ( MHK /= 2 ) THEN + + IF ( InputFileData%TowerBsHt >= InputFileData%TowerHt ) CALL SetErrStat( ErrID_Fatal, 'TowerBsHt must be less than TowerHt.',ErrStat,ErrMsg,RoutineName) - IF ( InputFileData%PtfmCMzt > InputFileData%TowerBsHt ) & - CALL SetErrStat( ErrID_Fatal, 'PtfmCMzt must not be greater than TowerBsHt.',ErrStat,ErrMsg,RoutineName) + IF ( InputFileData%PtfmCMzt > InputFileData%TowerBsHt ) & + CALL SetErrStat( ErrID_Fatal, 'PtfmCMzt must not be greater than TowerBsHt.',ErrStat,ErrMsg,RoutineName) - IF ( InputFileData%PtfmRefzt > InputFileData%TowerBsHt ) & - CALL SetErrStat( ErrID_Fatal, 'PtfmRefzt must not be greater than TowerBsHt.',ErrStat,ErrMsg,RoutineName) + IF ( InputFileData%PtfmRefzt > InputFileData%TowerBsHt ) & + CALL SetErrStat( ErrID_Fatal, 'PtfmRefzt must not be greater than TowerBsHt.',ErrStat,ErrMsg,RoutineName) + + ELSEIF ( MHK == 2 ) THEN + + IF ( InputFileData%TowerBsHt <= InputFileData%TowerHt ) CALL SetErrStat( ErrID_Fatal, 'TowerBsHt must be greater than TowerHt for a floating MHK turbine.',ErrStat,ErrMsg,RoutineName) + + ENDIF IF (.NOT. BD4Blades ) THEN IF (InputFileData%HubRad >= InputFileData%TipRad ) & CALL SetErrStat( ErrID_Fatal, 'HubRad must be less than TipRad.',ErrStat,ErrMsg,RoutineName) - IF ( InputFileData%TowerHt + InputFileData%Twr2Shft + InputFileData%OverHang*SIN(InputFileData%ShftTilt) & - <= InputFileData%TipRad ) THEN - CALL SetErrStat( ErrID_Fatal, 'TowerHt + Twr2Shft + OverHang*SIN(ShftTilt) must be greater than TipRad.',ErrStat,ErrMsg,RoutineName) - END IF + IF ( MHK /= 2 ) THEN + IF ( InputFileData%TowerHt + InputFileData%Twr2Shft + InputFileData%OverHang*SIN(InputFileData%ShftTilt) & + <= InputFileData%TipRad ) THEN + CALL SetErrStat( ErrID_Fatal, 'TowerHt + Twr2Shft + OverHang*SIN(ShftTilt) must be greater than TipRad.',ErrStat,ErrMsg,RoutineName) + END IF + ELSEIF ( MHK == 2 ) THEN + IF ( -InputFileData%TowerHt - InputFileData%Twr2Shft - InputFileData%OverHang*SIN(InputFileData%ShftTilt) & + <= InputFileData%TipRad ) THEN + CALL SetErrStat( ErrID_Fatal, 'TowerHt + Twr2Shft + OverHang*SIN(ShftTilt) must be greater than TipRad.',ErrStat,ErrMsg,RoutineName) + END IF + ENDIF END IF diff --git a/modules/elastodyn/src/ElastoDyn_Registry.txt b/modules/elastodyn/src/ElastoDyn_Registry.txt index b6f348bba..d18ab670c 100644 --- a/modules/elastodyn/src/ElastoDyn_Registry.txt +++ b/modules/elastodyn/src/ElastoDyn_Registry.txt @@ -24,6 +24,8 @@ typedef ^ InitInputType CHARACTER(1024) ADInputFile - - - "Name of the AeroDyn i typedef ^ InitInputType LOGICAL CompElast - - - "flag to determine if ElastoDyn is computing blade loads (true) or BeamDyn is (false)" - typedef ^ InitInputType CHARACTER(1024) RootName - - - "RootName for writing output files" typedef ^ InitInputType ReKi Gravity - - - "Gravitational acceleration" m/s^2 +typedef ^ InitInputType IntKi MHK - - - "MHK turbine type switch" - +typedef ^ InitInputType ReKi WtrDpth - - - "Water depth" m # Define outputs from the initialization routine here: typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "Names of the output-to-file channels" - @@ -62,17 +64,6 @@ typedef ^ BladeInputData ReKi StrcTwst {:} - - "Structural twist for distributed typedef ^ BladeInputData ReKi BMassDen {:} - - "Blade mass density for distributed input data" typedef ^ BladeInputData ReKi FlpStff {:} - - "Blade flap stiffness for distributed input data" typedef ^ BladeInputData ReKi EdgStff {:} - - "Blade edge stiffness for distributed input data" -typedef ^ BladeInputData ReKi GJStff {:} - - "Blade torsional stiffness for a given input station" -typedef ^ BladeInputData ReKi EAStff {:} - - "Blade extensional stiffness for a given input station" -typedef ^ BladeInputData ReKi Alpha {:} - - "Blade coupling coefficient between flap and twist for a given input station" -typedef ^ BladeInputData ReKi FlpIner {:} - - "Blade flap (about local structural yb-axis) mass inertia per unit length for a given input station" -typedef ^ BladeInputData ReKi EdgIner {:} - - "Blade edge (about local structural xb-axis) mass inertia per unit length for a given input station" -typedef ^ BladeInputData ReKi PrecrvRef {:} - - "Offset for defining the reference axis from the pitch axis for precurved blades at a given input station" -typedef ^ BladeInputData ReKi PreswpRef {:} - - "Offset for defining the reference axis from the pitch axis for preswept blades at a given input station" -typedef ^ BladeInputData ReKi FlpcgOf {:} - - "Blade flap (along local aerodynamic xb-axis) mass cg offset for a given input station" -typedef ^ BladeInputData ReKi EdgcgOf {:} - - "Blade edge (along local aerodynamic yb-axis) mass cg offset for a given input station" -typedef ^ BladeInputData ReKi FlpEAOf {:} - - "Blade flap (along local aerodynamic xb-axis) elastic axis offset for a given input station" -typedef ^ BladeInputData ReKi EdgEAOf {:} - - "Blade edge (along local aerodynamic yb-axis) elastic axis offset for a given input station" typedef ^ BladeInputData ReKi BldFlDmp 2 - - "Blade structural damping ratios in flapwise direction" typedef ^ BladeInputData ReKi BldEdDmp 1 - - "Blade structural damping ratios in edgewise direction" typedef ^ BladeInputData ReKi FlStTunr 2 - - "Blade flapwise modal stiffness tuners (input)" @@ -142,12 +133,12 @@ typedef ^ ED_InputFile ReKi NcIMUxn - - - "Downwind distance from the tower-top typedef ^ ED_InputFile ReKi NcIMUyn - - - "Lateral distance from the tower-top to the nacelle IMU" meters typedef ^ ED_InputFile ReKi NcIMUzn - - - "Vertical distance from the tower-top to the nacelle IMU" meters typedef ^ ED_InputFile ReKi Twr2Shft - - - "Vertical distance from the tower-top to the rotor shaft" meters -typedef ^ ED_InputFile ReKi TowerHt - - - "Height of tower above ground level [onshore] or MSL [offshore]" meters -typedef ^ ED_InputFile ReKi TowerBsHt - - - "Height of tower base above ground level [onshore] or MSL [offshore]" meters -typedef ^ ED_InputFile ReKi PtfmCMxt - - - "Downwind distance from the ground [onshore] or MSL [offshore] to the platform CM" meters -typedef ^ ED_InputFile ReKi PtfmCMyt - - - "Lateral distance from the ground [onshore] or MSL [offshore] to the platform CM" meters -typedef ^ ED_InputFile ReKi PtfmCMzt - - - "Vertical distance from the ground [onshore] or MSL [offshore] to the platform CM" meters -typedef ^ ED_InputFile ReKi PtfmRefzt - - - "Vertical distance from the ground [onshore] or MSL [offshore] to the platform reference point" meters +typedef ^ ED_InputFile ReKi TowerHt - - - "Height of tower relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK]" meters +typedef ^ ED_InputFile ReKi TowerBsHt - - - "Height of tower base relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK]" meters +typedef ^ ED_InputFile ReKi PtfmCMxt - - - "Downwind distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM" meters +typedef ^ ED_InputFile ReKi PtfmCMyt - - - "Lateral distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM" meters +typedef ^ ED_InputFile ReKi PtfmCMzt - - - "Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM" meters +typedef ^ ED_InputFile ReKi PtfmRefzt - - - "Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform reference point" meters typedef ^ ED_InputFile ReKi TipMass {:} - - "Tip-brake masses" kg typedef ^ ED_InputFile ReKi HubMass - - - "Hub mass" kg typedef ^ ED_InputFile ReKi HubIner - - - "Hub inertia about teeter axis (2-blader) or rotor axis (3-blader)" "kg m^2" @@ -204,13 +195,6 @@ typedef ^ ED_InputFile ReKi TwFAM1Sh {:} - - "Tower fore-aft mode-1 shape coeffi typedef ^ ED_InputFile ReKi TwFAM2Sh {:} - - "Tower fore-aft mode-2 shape coefficients" - typedef ^ ED_InputFile ReKi TwSSM1Sh {:} - - "Tower side-to-side mode-1 shape coefficients" - typedef ^ ED_InputFile ReKi TwSSM2Sh {:} - - "Tower side-to-side mode-2 shape coefficients" - -# ..... Tower Input file data (ADAMS only) ........................................................................................................... -typedef ^ ED_InputFile ReKi TwGJStif {:} - - "Tower torsional stiffness for a given input station" Nm^2 -typedef ^ ED_InputFile ReKi TwEAStif {:} - - "Tower extensional stiffness for a given input station" N -typedef ^ ED_InputFile ReKi TwFAIner {:} - - "Tower fore-aft (about yt-axis) mass inertia per unit length for a given input station" "kg m" -typedef ^ ED_InputFile ReKi TwSSIner {:} - - "Tower side-to-side (about xt-axis) mass inertia per unit length for a given input station" "kg m" -typedef ^ ED_InputFile ReKi TwFAcgOf {:} - - "Tower fore-aft (along the xt-axis) mass cg offset for a given input station" meters -typedef ^ ED_InputFile ReKi TwSScgOf {:} - - "Tower fore-aft (along the yt-axis) mass cg offset for a given input station" meters # ..... Furling Input file data ........................................................................................................... typedef ^ ED_InputFile LOGICAL RFrlDOF - - - "Rotor-furl DOF" - typedef ^ ED_InputFile LOGICAL TFrlDOF - - - "Tail-furl DOF" - @@ -218,29 +202,13 @@ typedef ^ ED_InputFile ReKi RotFurl - - - "Initial or fixed rotor-furl angle" ra typedef ^ ED_InputFile ReKi TailFurl - - - "Initial or fixed tail-furl angle" radians typedef ^ ED_InputFile ReKi Yaw2Shft - - - "Lateral distance from the yaw axis to the rotor shaft" meters typedef ^ ED_InputFile ReKi ShftSkew - - - "Rotor shaft skew angle" radians -typedef ^ ED_InputFile ReKi RFrlCMxn - - - "Downwind distance from tower-top to rotor-furl CM" meters -typedef ^ ED_InputFile ReKi RFrlCMyn - - - "Lateral distance from tower-top to rotor-furl CM" meters -typedef ^ ED_InputFile ReKi RFrlCMzn - - - "Vertical distance from tower-top to rotor-furl CM" meters -typedef ^ ED_InputFile ReKi BoomCMxn - - - "Downwind distance from tower-top to tail boom CM" meters -typedef ^ ED_InputFile ReKi BoomCMyn - - - "Lateral distance from tower-top to tail boom CM" meters -typedef ^ ED_InputFile ReKi BoomCMzn - - - "Vertical distance from tower-top to tail boom CM" meters -typedef ^ ED_InputFile ReKi TFinCMxn - - - "Downwind distance from tower-top to tail fin CM" meters -typedef ^ ED_InputFile ReKi TFinCMyn - - - "Lateral distance from tower-top to tail fin CM" meters -typedef ^ ED_InputFile ReKi TFinCMzn - - - "Vertical distance from tower-top to tail fin CM" meters -typedef ^ ED_InputFile ReKi TFinCPxn - - - "Downwind distance from tower-top to tail fin CP" meters -typedef ^ ED_InputFile ReKi TFinCPyn - - - "Lateral distance from tower-top to tail fin CP" meters -typedef ^ ED_InputFile ReKi TFinCPzn - - - "Vertical distance from tower-top to tail fin CP" meters -typedef ^ ED_InputFile ReKi TFinSkew - - - "Tail fin chordline skew angle" radians -typedef ^ ED_InputFile ReKi TFinTilt - - - "Tail fin chordline tilt angle" radians -typedef ^ ED_InputFile ReKi TFinBank - - - "Tail fin planform bank angle" radians -typedef ^ ED_InputFile ReKi RFrlPntxn - - - "Downwind distance from tower-top to arbitrary point on rotor-furl axis" meters -typedef ^ ED_InputFile ReKi RFrlPntyn - - - "Lateral distance from tower-top to arbitrary point on rotor-furl axis" meters -typedef ^ ED_InputFile ReKi RFrlPntzn - - - "Vertical distance from tower-top to arbitrary point on rotor-furl axis" meters +typedef ^ ED_InputFile ReKi RFrlCM_n 3 - - "Vector from tower-top to rotor-furl CM" meters +typedef ^ ED_InputFile ReKi BoomCM_n 3 - - "Vector from tower-top to tail boom CM" meters +typedef ^ ED_InputFile ReKi TFinCM_n 3 - - "Vector from tower-top to tail fin CM" meters +typedef ^ ED_InputFile ReKi RFrlPnt_n 3 - - "Vector from tower-top to arbitrary point on rotor-furl axis" meters typedef ^ ED_InputFile ReKi RFrlSkew - - - "Rotor-furl axis skew angle" radians typedef ^ ED_InputFile ReKi RFrlTilt - - - "Rotor-furl axis tilt angle" radians -typedef ^ ED_InputFile ReKi TFrlPntxn - - - "Downwind distance from tower-top to arbitrary point on tail-furl axis" meters -typedef ^ ED_InputFile ReKi TFrlPntyn - - - "Lateral distance from tower-top to arbitrary point on tail-furl axis" meters -typedef ^ ED_InputFile ReKi TFrlPntzn - - - "Vertical distance from tower-top to arbitrary point on tail-furl axis" meters +typedef ^ ED_InputFile ReKi TFrlPnt_n 3 - - "Vector from tower-top to arbitrary point on tail-furl axis" meters typedef ^ ED_InputFile ReKi TFrlSkew - - - "Rotor-furl axis skew angle" radians typedef ^ ED_InputFile ReKi TFrlTilt - - - "Rotor-furl axis tilt angle" radians typedef ^ ED_InputFile ReKi RFrlMass - - - "Rotor-furl mass" kg @@ -251,7 +219,6 @@ typedef ^ ED_InputFile ReKi TFrlIner - - - "Tail boom inertia about tail-furl ax typedef ^ ED_InputFile IntKi RFrlMod - - - "Rotor-furl spring/damper model switch" - typedef ^ ED_InputFile ReKi RFrlSpr - - - "Rotor-furl spring constant" N-m/rad typedef ^ ED_InputFile ReKi RFrlDmp - - - "Rotor-furl damping constant" N-m/(rad/s) -typedef ^ ED_InputFile ReKi RFrlCDmp - - - "Rotor-furl rate-independent Coulomb-damping moment" N-m typedef ^ ED_InputFile ReKi RFrlUSSP - - - "Rotor-furl up-stop spring position" radians typedef ^ ED_InputFile ReKi RFrlDSSP - - - "Rotor-furl down-stop spring position" radians typedef ^ ED_InputFile ReKi RFrlUSSpr - - - "Rotor-furl up-stop spring constant" N-m/rad @@ -263,7 +230,6 @@ typedef ^ ED_InputFile ReKi RFrlDSDmp - - - "Rotor-furl down-stop damping consta typedef ^ ED_InputFile IntKi TFrlMod - - - "Tail-furl spring/damper model switch" - typedef ^ ED_InputFile ReKi TFrlSpr - - - "Tail-furl spring constant" N-m/rad typedef ^ ED_InputFile ReKi TFrlDmp - - - "Tail-furl damping constant" N-m/(rad/s) -typedef ^ ED_InputFile ReKi TFrlCDmp - - - "Tail-furl rate-independent Coulomb-damping moment" N-m typedef ^ ED_InputFile ReKi TFrlUSSP - - - "Tail-furl up-stop spring position" radians typedef ^ ED_InputFile ReKi TFrlDSSP - - - "Tail-furl down-stop spring position" radians typedef ^ ED_InputFile ReKi TFrlUSSpr - - - "Tail-furl up-stop spring constant" N-m/rad @@ -319,9 +285,6 @@ typedef ^ ED_CoordSys R8Ki m3 {:}{:}{:} - - "m3(K,J,:) = vector / direction m3 f typedef ^ ED_CoordSys R8Ki n1 {:}{:}{:} - - "n1(K,J,:) = vector / direction n1 for node J of blade K (= LxbK from the IEC coord. system)" - typedef ^ ED_CoordSys R8Ki n2 {:}{:}{:} - - "n2(K,J,:) = vector / direction n2 for node J of blade K (= LybK from the IEC coord. system)" - typedef ^ ED_CoordSys R8Ki n3 {:}{:}{:} - - "n3(K,J,:) = vector / direction n3 for node J of blade K (= LzbK from the IEC coord. system)" - -typedef ^ ED_CoordSys R8Ki p1 3 - - "Vector / direction p1 (used to calc. and return tail aerodynamic loads from AeroDyn)" - -typedef ^ ED_CoordSys R8Ki p2 3 - - "Vector / direction p2 (used to calc. and return tail aerodynamic loads from AeroDyn)" - -typedef ^ ED_CoordSys R8Ki p3 3 - - "Vector / direction p3 (used to calc. and return tail aerodynamic loads from AeroDyn)" - typedef ^ ED_CoordSys R8Ki rf1 3 - - "Vector / direction rf1 (rotor-furl coordinate system = d1 when rotor-furl angle = 0)" - typedef ^ ED_CoordSys R8Ki rf2 3 - - "Vector / direction rf2 (rotor-furl coordinate system = d2 when rotor-furl angle = 0)" - typedef ^ ED_CoordSys R8Ki rf3 3 - - "Vector / direction rf3 (rotor-furl coordinate system = d3 when rotor-furl angle = 0)" - @@ -382,6 +345,7 @@ typedef ^ ED_RtHndSide R8Ki rZT {:}{:} - - "Position vector from platform refere typedef ^ ED_RtHndSide R8Ki rPQ 3 - - "Position vector from teeter pin (point P) to apex of rotation (point Q)" m typedef ^ ED_RtHndSide R8Ki rP 3 - - "Position vector from inertial frame origin to teeter pin (point P)" m typedef ^ ED_RtHndSide R8Ki rV 3 - - "Position vector from inertial frame origin to specified point on rotor-furl axis (point V)" m +typedef ^ ED_RtHndSide R8Ki rJ 3 - - "Position vector from inertial frame origin to tail fin center of mass (point J)" m typedef ^ ED_RtHndSide R8Ki rZY 3 - - "Position vector from platform reference (point Z) to platform mass center (point Y)" m typedef ^ ED_RtHndSide R8Ki rOU 3 - - "Position vector from tower-top / base plate (point O) to nacelle center of mass (point U)." m typedef ^ ED_RtHndSide R8Ki rOV 3 - - "Position vector from tower-top / base plate (point O) to specified point on rotor-furl axis (point V)" m @@ -395,7 +359,6 @@ typedef ^ ED_RtHndSide R8Ki rVIMU 3 - - "Position vector from specified point on typedef ^ ED_RtHndSide R8Ki rVP 3 - - "Position vector from specified point on rotor-furl axis (point V) to teeter pin (point P)" m typedef ^ ED_RtHndSide R8Ki rWI 3 - - "Position vector from specified point on tail-furl axis (point W) to tail boom center of mass (point I)" m typedef ^ ED_RtHndSide R8Ki rWJ 3 - - "Position vector from specified point on tail-furl axis (point W) to tail fin center of mass (point J)" m -typedef ^ ED_RtHndSide R8Ki rWK 3 - - "Position vector from specified point on tail-furl axis (point W) to tail fin center of pressure (point K)" m typedef ^ ED_RtHndSide R8Ki rZT0 3 - - "Position vector from platform reference (point Z) to tower base (point T(0))" m # RtHS Angular positions typedef ^ ED_RtHndSide ReKi AngPosEF {:}{:} - - "Angular position of the current point on the tower (body F) in the inertial frame (body E for earth)" @@ -442,14 +405,12 @@ typedef ^ ED_RtHndSide ReKi LinAccECt 3 - - "Portion of the linear acceleration typedef ^ ED_RtHndSide ReKi LinAccEDt 3 - - "Portion of the linear acceleration of the center of mass of the structure that furls with the rotor (not including rotor) (point D) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" typedef ^ ED_RtHndSide ReKi LinAccEIt 3 - - "Portion of the linear acceleration of the tail boom center of mass (point I) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" typedef ^ ED_RtHndSide ReKi LinAccEJt 3 - - "Portion of the linear acceleration of the tail fin center of mass (point J) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" -#typedef ^ ED_RtHndSide ReKi LinAccEKt 3 - - "Portion of the linear acceleration of the tail fin center of pressure (point K) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" #typedef ^ ED_RtHndSide ReKi LinAccEPt 3 - - "Portion of the linear acceleration of the teeter pin (point P) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" #typedef ^ ED_RtHndSide ReKi LinAccEQt 3 - - "Portion of the linear acceleration of the apex of rotation (point Q) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" typedef ^ ED_RtHndSide ReKi LinAccEUt 3 - - "Portion of the linear acceleration of the nacelle center of mass (point U) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" #typedef ^ ED_RtHndSide ReKi LinAccEVt 3 - - "Portion of the linear acceleration of the selected point on the rotor-furl axis (point V) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" #typedef ^ ED_RtHndSide ReKi LinAccEWt 3 - - "Portion of the linear acceleration of the selected point on the tail-furl axis (point W) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" typedef ^ ED_RtHndSide ReKi LinAccEYt 3 - - "Portion of the linear acceleration of the platform center of mass (point Y) in the inertia frame (body E for earth) associated with everything but the QD2T()'s" -#typedef ^ ED_RtHndSide ReKi LinVelEK 3 - - "Linear velocity of tail fin center-of-pressure (point K) in the inertia frame" typedef ^ ED_RtHndSide ReKi LinVelES {:}{:}{:} - - "Linear velocity of current point on the current blade (point S) in the inertia frame" #typedef ^ ED_RtHndSide ReKi LinVelHS 3 - - "Relative linear velocity of the current point on the current blade (point S) in the hub frame (body H)" #typedef ^ ED_RtHndSide ReKi LinVelXO 3 - - "Relative linear velocity of the tower-top / base plate (point O) in the platform (body X)" @@ -466,7 +427,6 @@ typedef ^ ED_RtHndSide ReKi PLinVelEC {:}{:}{:} - - "Partial linear velocity (an typedef ^ ED_RtHndSide ReKi PLinVelED {:}{:}{:} - - "Partial linear velocity (and its 1st time derivative) of the center of mass of the structure that furls with the rotor (not including rotor) (point D) in the inertia frame (body E for earth)" typedef ^ ED_RtHndSide ReKi PLinVelEI {:}{:}{:} - - "Partial linear velocity (and its 1st time derivative) of the tail boom center of mass (point I) in the inertia frame (body E for earth)" typedef ^ ED_RtHndSide ReKi PLinVelEJ {:}{:}{:} - - "Partial linear velocity (and its 1st time derivative) of the tail fin center of mass (point J) in the inertia frame (body E for earth)" -typedef ^ ED_RtHndSide ReKi PLinVelEK {:}{:}{:} - - "Partial linear velocity (and its 1st time derivative) of the tail fin center of pressure(point K) in the inertia frame (body E for earth)" typedef ^ ED_RtHndSide ReKi PLinVelEP {:}{:}{:} - - "Partial linear velocity (and its 1st time derivative) of the teeter pin (point P) in the inertia frame (body E for earth)" typedef ^ ED_RtHndSide ReKi PLinVelEQ {:}{:}{:} - - "Partial linear velocity (and its 1st time derivative) of the apex of rotation (point Q) in the inertia frame (body E for earth)" typedef ^ ED_RtHndSide ReKi PLinVelEU {:}{:}{:} - - "Partial linear velocity (and its 1st time derivative) of the nacelle center of mass (point U) in the inertia frame (body E for earth)" @@ -481,6 +441,7 @@ typedef ^ ED_RtHndSide ReKi LinAccEZt 3 - - "Portion of the linear acceleration typedef ^ ED_RtHndSide ReKi LinVelEIMU 3 - - "Linear velocity of the nacelle IMU (point IMU) in the inertia frame" typedef ^ ED_RtHndSide ReKi LinVelEZ 3 - - "Linear velocity of platform reference (point Z) in the inertia frame" typedef ^ ED_RtHndSide ReKi LinVelEO 3 - - "Linear velocity of the base plate (point O) in the inertia frame (body E for earth)" +typedef ^ ED_RtHndSide ReKi LinVelEJ 3 - - "Linear velocity of the tail fin CM (point J) in the inertia frame (body E for earth)" # RtHS Forces and Moments typedef ^ ED_RtHndSide ReKi FrcONcRtt 3 - - "Portion of the force at yaw bearing (point O) due to the nacelle, generator, and rotor associated with everything but the QD2T()'s" typedef ^ ED_RtHndSide ReKi FrcPRott 3 - - "Portion of the force at the teeter pin (point P) due to the rotor associated with everything but the QD2T()'s" @@ -518,8 +479,6 @@ typedef ^ ED_RtHndSide R8Ki TeetAng - - - "Current teeter angle = QT(DOF_Teet) f typedef ^ ED_RtHndSide ReKi FrcVGnRtt 3 - - "Portion of the force at the rotor-furl axis (point V) due to the structure that furls with the rotor, generator, and rotor associated with everything but the QD2T()'s" typedef ^ ED_RtHndSide ReKi FrcWTailt 3 - - "Portion of the force at the tail-furl axis (point W) due to the tail associated with everything but the QD2T()'s" typedef ^ ED_RtHndSide ReKi FrcZAllt 3 - - "Portion of the force at platform reference (point Z) due to everything associated with everything but the QD2T()'s" -#typedef ^ ED_RtHndSide ReKi FKAero 3 - - "The tail fin aerodynamic force acting at point K, the center-of-pressure of the tail fin" -#typedef ^ ED_RtHndSide ReKi MAAero 3 - - "The tail fin aerodynamic moment acting at point K, the center-of-pressure of the tail fin" typedef ^ ED_RtHndSide ReKi MomXAllt 3 - - "Portion of the moment at the platform (body X) / platform reference (point Z) due to everything associated with everything but the QD2T()'s" typedef ^ ED_RtHndSide ReKi PFrcVGnRt {:}{:} - - "Partial force at the rotor-furl axis (point V) due to the structure that furls with the rotor, generator, and rotor" typedef ^ ED_RtHndSide ReKi PFrcWTail {:}{:} - - "Partial force at the tail-furl axis (point W) due to the tail" @@ -600,9 +559,6 @@ typedef ^ ParameterType R8Ki CSRFrlSkw - - - "Cosine*Sine of the rotor-furl axis typedef ^ ParameterType R8Ki CSRFrlTlt - - - "Cosine*Sine of the rotor-furl axis tilt angle" typedef ^ ParameterType R8Ki CSTFrlSkw - - - "Cosine*Sine of the tail-furl axis skew angle" typedef ^ ParameterType R8Ki CSTFrlTlt - - - "Cosine*Sine of the tail-furl axis tilt angle" -typedef ^ ParameterType R8Ki CTFinBank - - - "Cosine of the tail fin planform bank angle" -typedef ^ ParameterType R8Ki CTFinSkew - - - "Cosine of the tail fin chordline skew angle" -typedef ^ ParameterType R8Ki CTFinTilt - - - "Cosine of the tail fin chordline tilt angle" typedef ^ ParameterType R8Ki CTFrlSkew - - - "Cosine of the tail-furl axis skew angle" typedef ^ ParameterType R8Ki CTFrlSkw2 - - - "Cosine-squared of the tail-furl axis skew angle" typedef ^ ParameterType R8Ki CTFrlTilt - - - "Cosine of the tail-furl axis tilt angle" @@ -615,11 +571,9 @@ typedef ^ ParameterType ReKi NacCMyn - - - "Lateral distance from tower-top to n typedef ^ ParameterType ReKi NacCMzn - - - "Vertical distance from tower-top to nacelle CM" typedef ^ ParameterType ReKi OverHang - - - "Distance from yaw axis to rotor apex or teeter pin" typedef ^ ParameterType ReKi ProjArea - - - "Swept area of the rotor projected onto the rotor plane (the plane normal to the low-speed shaft)" -typedef ^ ParameterType ReKi PtfmRefzt - - - "Vertical distance from the ground [onshore] or MSL [offshore] to the platform reference point" +typedef ^ ParameterType ReKi PtfmRefzt - - - "Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform reference point" typedef ^ ParameterType ReKi RefTwrHt - - - "Vertical distance between FAST's undisplaced tower height (variable TowerHt) and FAST's inertia frame reference point (variable PtfmRef); that is, RefTwrHt = TowerHt - PtfmRefzt" -typedef ^ ParameterType ReKi RFrlPntxn - - - "Downwind distance from tower-top to arbitrary point on rotor-furl axis" -typedef ^ ParameterType ReKi RFrlPntyn - - - "Lateral distance from tower-top to arbitrary point on rotor-furl axis" -typedef ^ ParameterType ReKi RFrlPntzn - - - "Vertical distance from tower-top to arbitrary point on rotor-furl axis" +typedef ^ ParameterType ReKi RFrlPnt_n 3 - - "Vector from tower-top to arbitrary point on rotor-furl axis" typedef ^ ParameterType ReKi rVDxn - - - "xn-component of position vector Rvd" typedef ^ ParameterType ReKi rVDyn - - - "yn-component of position vector rVD" typedef ^ ParameterType ReKi rVDzn - - - "zn-component of position vector rVD" @@ -635,9 +589,6 @@ typedef ^ ParameterType ReKi rWIzn - - - "zn-component of position vector rWI" typedef ^ ParameterType ReKi rWJxn - - - "xn-component of position vector rWJ" typedef ^ ParameterType ReKi rWJyn - - - "yn-component of position vector rWJ" typedef ^ ParameterType ReKi rWJzn - - - "zn-component of position vector rWJ" -typedef ^ ParameterType ReKi rWKxn - - - "xn-component of position vector rWK" -typedef ^ ParameterType ReKi rWKyn - - - "yn-component of position vector rWK" -typedef ^ ParameterType ReKi rWKzn - - - "zn-component of position vector rWK" typedef ^ ParameterType ReKi rZT0zt - - - "zt-component of position vector rZT0" typedef ^ ParameterType ReKi rZYzt - - - "zt-component of position vector rZY" typedef ^ ParameterType R8Ki SinDel3 - - - "Sine of the Delta-3 angle for teetering rotors" @@ -648,19 +599,14 @@ typedef ^ ParameterType R8Ki SRFrlTilt - - - "Sine of the rotor-furl axis tilt a typedef ^ ParameterType R8Ki SRFrlTlt2 - - - "Sine-squared of the rotor-furl axis tilt angle" typedef ^ ParameterType R8Ki SShftSkew - - - "Sine of the shaft skew angle" typedef ^ ParameterType R8Ki SShftTilt - - - "Sine of the shaft tilt angle" -typedef ^ ParameterType R8Ki STFinBank - - - "Sine of the tail fin planform bank angle" -typedef ^ ParameterType R8Ki STFinSkew - - - "Sine of the tail fin chordline skew angle" -typedef ^ ParameterType R8Ki STFinTilt - - - "Sine of the tail fin chordline tilt angle" typedef ^ ParameterType R8Ki STFrlSkew - - - "Sine of the tail-furl axis skew angle" typedef ^ ParameterType R8Ki STFrlSkw2 - - - "Sine-squared of the tail-furl axis skew angle" typedef ^ ParameterType R8Ki STFrlTilt - - - "Sine of the tail-furl axis tilt angle" typedef ^ ParameterType R8Ki STFrlTlt2 - - - "Sine-squared of the tail-furl axis tilt angle" -typedef ^ ParameterType ReKi TFrlPntxn - - - "Downwind distance from tower-top to arbitrary point on tail-furl axis" -typedef ^ ParameterType ReKi TFrlPntyn - - - "Lateral distance from tower-top to arbitrary point on tail-furl axis" -typedef ^ ParameterType ReKi TFrlPntzn - - - "Vertical distance from tower-top to arbitrary point on tail-furl axis" +typedef ^ ParameterType ReKi TFrlPnt_n 3 - - "Vector from tower-top to arbitrary point on tail-furl axis" typedef ^ ParameterType ReKi TipRad - - - "Preconed blade-tip radius" -typedef ^ ParameterType ReKi TowerHt - - - "Height of tower above ground level" -typedef ^ ParameterType ReKi TowerBsHt - - - "Height of tower base above ground level [onshore] or MSL [offshore]" meters +typedef ^ ParameterType ReKi TowerHt - - - "Height of tower relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK]" meters +typedef ^ ParameterType ReKi TowerBsHt - - - "Height of tower base relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK]" meters typedef ^ ParameterType ReKi UndSling - - - "Undersling length" typedef ^ ParameterType IntKi NumBl - - - "Number of turbine blades" - typedef ^ ParameterType ReKi AxRedTFA {:}{:}{:} - - "The axial-reduction terms for the fore-aft tower mode shapes" @@ -679,13 +625,8 @@ typedef ^ ParameterType ReKi TwrFlexL - - - "Height / length of the flexible por typedef ^ ParameterType ReKi TwrSSSF {:}{:}{:} - - "Tower side-to-side shape functions" typedef ^ ParameterType IntKi TTopNode - - - "Index of the additional node located at the tower-top = TwrNodes + 1" typedef ^ ParameterType IntKi TwrNodes - - - "Number of tower nodes used in the analysis" -typedef ^ ParameterType ReKi InerTFA {:} - - "Interpolated tower fore-aft (about yt-axis) mass inertia per unit length" -typedef ^ ParameterType ReKi InerTSS {:} - - "Interpolated tower side-to-side (about xt-axis) mass inertia per unit length" -typedef ^ ParameterType ReKi StiffTGJ {:} - - "Interpolated tower torsional stiffness" -typedef ^ ParameterType ReKi StiffTEA {:} - - "Interpolated tower extensional stiffness" +typedef ^ ParameterType IntKi MHK - - - "MHK turbine type switch" - typedef ^ ParameterType ReKi StiffTFA {:} - - "Interpolated fore-aft tower stiffness" -typedef ^ ParameterType ReKi cgOffTFA {:} - - "Interpolated tower fore-aft mass cg offset" -typedef ^ ParameterType ReKi cgOffTSS {:} - - "Interpolated tower side-to-side mass cg offset" typedef ^ ParameterType ReKi AtfaIner - - - "Inertia of tail boom about the tail-furl axis whose origin is the tail boom center of mass" typedef ^ ParameterType ReKi BldCG {:} - - "Blade center of mass wrt the blade root" typedef ^ ParameterType ReKi BldMass {:} - - "Blade masses" @@ -718,37 +659,26 @@ typedef ^ ParameterType ReKi Gravity - - - "Gravitational acceleration" m/s^2 typedef ^ ParameterType ReKi PitchAxis {:}{:} - - "Pitch axis for analysis nodes" - typedef ^ ParameterType ReKi AeroTwst {:} - - "Aerodynamic twist of the blade at the analysis nodes" typedef ^ ParameterType ReKi AxRedBld {:}{:}{:}{:} - - "The axial-reduction terms of the blade shape function" -typedef ^ ParameterType ReKi BAlpha {:}{:} - - "Interpolated blade coupling coefficient between flap and twist" typedef ^ ParameterType ReKi BldEDamp {:}{:} - - "Blade edgewise damping coefficients" typedef ^ ParameterType ReKi BldFDamp {:}{:} - - "Blade flapwise damping coefficients" typedef ^ ParameterType ReKi BldFlexL - - - "Flexible blade length" typedef ^ ParameterType ReKi CAeroTwst {:} - - "Cosine of the aerodynamic twist of the blade at the analysis nodes" typedef ^ ParameterType ReKi CBE {:}{:}{:} - - "Generalized edgewise damping of the blades" typedef ^ ParameterType ReKi CBF {:}{:}{:} - - "Generalized flapwise damping of the blades" -typedef ^ ParameterType ReKi cgOffBEdg {:}{:} - - "Interpolated blade edge (along local aerodynamic yb-axis) mass cg offset" -typedef ^ ParameterType ReKi cgOffBFlp {:}{:} - - "Interpolated blade flap (along local aerodynamic xb-axis) mass cg offset" typedef ^ ParameterType ReKi Chord {:} - - "Chord of the blade at the analysis nodes" typedef ^ ParameterType R8Ki CThetaS {:}{:} - - "COS( ThetaS )" typedef ^ ParameterType ReKi DRNodes {:} - - "Length of variable-spaced blade elements" -typedef ^ ParameterType ReKi EAOffBEdg {:}{:} - - "Interpolated blade edge (along local aerodynamic yb-axis) elastic axis offset" -typedef ^ ParameterType ReKi EAOffBFlp {:}{:} - - "Interpolated blade flap (along local aerodynamic xb-axis) elastic axis offset" typedef ^ ParameterType ReKi FStTunr {:}{:} - - "Blade flapwise modal stiffness tuners (stored for all blades)" -typedef ^ ParameterType ReKi InerBEdg {:}{:} - - "Interpolated blade edge (about local structural xb-axis) mass inertia per unit length" -typedef ^ ParameterType ReKi InerBFlp {:}{:} - - "Interpolated blade flap (about local structural yb-axis) mass inertia per unit length" typedef ^ ParameterType ReKi KBE {:}{:}{:} - - "Generalized edgewise stiffness of the blades" typedef ^ ParameterType ReKi KBF {:}{:}{:} - - "Generalized flapwise stiffness of the blades" typedef ^ ParameterType ReKi MassB {:}{:} - - "Interpolated lineal blade mass density" -typedef ^ ParameterType ReKi RefAxisxb {:}{:} - - "Interpolated Offset for defining the reference axis from the pitch axis for precurved blades at a given input station (along xb-axis)" -typedef ^ ParameterType ReKi RefAxisyb {:}{:} - - "Interpolated Offset for defining the reference axis from the pitch axis for preswept blades at a given input station (along yb-axis)" typedef ^ ParameterType ReKi RNodes {:} - - "Radius to analysis nodes relative to hub ( 0 < RNodes(:) < BldFlexL )" typedef ^ ParameterType ReKi RNodesNorm {:} - - "Normalized radius to analysis nodes relative to hub ( 0 < RNodesNorm(:) < 1 )" typedef ^ ParameterType ReKi rSAerCenn1 {:}{:} - - "Distance from point S on a blade to the aerodynamic center in the n1 direction (m)" typedef ^ ParameterType ReKi rSAerCenn2 {:}{:} - - "Distance from point S on a blade to the aerodynamic center in the n2 direction (m)" typedef ^ ParameterType ReKi SAeroTwst {:} - - "Sine of the aerodynamic twist of the blade at the analysis nodes" typedef ^ ParameterType ReKi StiffBE {:}{:} - - "Interpolated edgewise blade stiffness" -typedef ^ ParameterType ReKi StiffBEA {:}{:} - - "Interpolated blade extensional stiffness" typedef ^ ParameterType ReKi StiffBF {:}{:} - - "Interpolated flapwise blade stiffness" -typedef ^ ParameterType ReKi StiffBGJ {:}{:} - - "Interpolated blade torsional stiffness" typedef ^ ParameterType R8Ki SThetaS {:}{:} - - "SIN( ThetaS )" typedef ^ ParameterType ReKi ThetaS {:}{:} - - "Structural twist for analysis nodes" radians typedef ^ ParameterType ReKi TwistedSF {:}{:}{:}{:}{:} - - "Interpolated lineal blade mass density" @@ -768,7 +698,6 @@ typedef ^ ParameterType ReKi TeetHStP - - - "Rotor-teeter hard-stop position" typedef ^ ParameterType ReKi TeetSSSp - - - "Rotor-teeter soft-stop linear-spring constant" typedef ^ ParameterType ReKi TeetSStP - - - "Rotor-teeter soft-stop position" typedef ^ ParameterType IntKi TeetMod - - - "Rotor-teeter spring/damper model switch" -typedef ^ ParameterType ReKi TFrlCDmp - - - "Tail-furl rate-independent Coulomb-damping moment" typedef ^ ParameterType ReKi TFrlDmp - - - "Tail-furl damping constant" typedef ^ ParameterType ReKi TFrlDSDmp - - - "Tail-furl down-stop damping constant" typedef ^ ParameterType ReKi TFrlDSDP - - - "Tail-furl down-stop damper position" @@ -780,7 +709,6 @@ typedef ^ ParameterType ReKi TFrlUSDP - - - "Tail-furl up-stop damper position" typedef ^ ParameterType ReKi TFrlUSSP - - - "Tail-furl up-stop spring position" typedef ^ ParameterType ReKi TFrlUSSpr - - - "Tail-furl up-stop spring constant" typedef ^ ParameterType IntKi TFrlMod - - - "Tail-furl spring/damper model switch" -typedef ^ ParameterType ReKi RFrlCDmp - - - "Rotor-furl rate-independent Coulomb-damping moment" typedef ^ ParameterType ReKi RFrlDmp - - - "Rotor-furl damping constant" typedef ^ ParameterType ReKi RFrlDSDmp - - - "Rotor-furl down-stop damping constant" typedef ^ ParameterType ReKi RFrlDSDP - - - "Rotor-furl down-stop damper position" @@ -805,8 +733,8 @@ typedef ^ ParameterType CHARACTER(1024) RootName - - - "RootName for writing out typedef ^ ParameterType ReKi BElmntMass {:}{:} - - "Mass of the blade elements" typedef ^ ParameterType ReKi TElmntMass {:} - - "Mass of the tower elements" typedef ^ ParameterType IntKi method - - - "Identifier for integration method (1 [RK4], 2 [AB4], or 3 [ABM4])" - -typedef ^ ParameterType ReKi PtfmCMxt - - - "Downwind distance from the ground [onshore] or MSL [offshore] to the platform CM" meters -typedef ^ ParameterType ReKi PtfmCMyt - - - "Lateral distance from the ground [onshore] or MSL [offshore] to the platform CM" meters +typedef ^ ParameterType ReKi PtfmCMxt - - - "Downwind distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM" meters +typedef ^ ParameterType ReKi PtfmCMyt - - - "Lateral distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM" meters typedef ^ ParameterType LOGICAL BD4Blades - - - "flag to determine if BeamDyn is computing blade loads (true) or ElastoDyn is (false)" - typedef ^ ParameterType LOGICAL UseAD14 - - - "flag to determine if AeroDyn14 is being used. Will remove this later when we've replaced AD14." - # .... ED_AllBlNds option ........................................................................................................ @@ -828,6 +756,7 @@ typedef ^ InputType MeshType PlatformPtMesh - - - "A mesh at the platform refere typedef ^ InputType MeshType TowerPtLoads - - - "Tower line2 mesh with forces: surge/xi (1), sway/yi (2), and heave/zi (3)-components of the portion of the tower force at the current tower node (point T); and moments: roll/xi (1), pitch/yi (2), and yaw/zi (3)-components of the portion of the tower moment acting at the current tower node" N/m typedef ^ InputType MeshType HubPtLoad - - - "A mesh at the teeter pin, containing forces: surge/xi (1), sway/yi (2), and heave/zi (3)-components; and moments: roll/xi (1), pitch/yi (2), and yaw/zi (3)-components acting at the hub. Passed from BeamDyn" typedef ^ InputType MeshType NacelleLoads - - - "From ServoDyn/TMD: loads on the nacelle." +typedef ^ InputType MeshType TFinCMLoads - - - "Aerodynamic forces and moments at the tail-fin center of mass point (point J)" # Define inputs that are not on a mesh here: typedef ^ InputType ReKi TwrAddedMass {:}{:}{:} - - "6-by-6 added mass matrix of the tower elements, per unit length-bjj: place on a mesh" "per unit length" typedef ^ InputType ReKi PtfmAddedMass {6}{6} - - "Platform added mass matrix" "kg, kg-m, kg-m^2" @@ -848,6 +777,7 @@ typedef ^ OutputType MeshType BladeRootMotion {:} - - "For AeroDyn/BeamDyn: moti typedef ^ OutputType MeshType RotorFurlMotion14 - - - "For AeroDyn14: motions of the rotor furl point." typedef ^ OutputType MeshType NacelleMotion - - - "For AeroDyn14 & ServoDyn/TMD: motions of the nacelle." typedef ^ OutputType MeshType TowerBaseMotion14 - - - "For AeroDyn 14: motions of the tower base" +typedef ^ OutputType MeshType TFinCMMotion - - - "For AeroDyn: motions of the tail find CM point (point J)" # Define outputs that are not on this mesh here: typedef ^ OutputType ReKi WriteOutput {:} - - "Data to be written to an output file: see WriteOutputHdr for names of each variable" "see WriteOutputUnt" diff --git a/modules/elastodyn/src/ElastoDyn_Types.f90 b/modules/elastodyn/src/ElastoDyn_Types.f90 index 03ba6296e..6f19f87bd 100644 --- a/modules/elastodyn/src/ElastoDyn_Types.f90 +++ b/modules/elastodyn/src/ElastoDyn_Types.f90 @@ -42,6 +42,8 @@ MODULE ElastoDyn_Types LOGICAL :: CompElast !< flag to determine if ElastoDyn is computing blade loads (true) or BeamDyn is (false) [-] CHARACTER(1024) :: RootName !< RootName for writing output files [-] REAL(ReKi) :: Gravity !< Gravitational acceleration [m/s^2] + INTEGER(IntKi) :: MHK !< MHK turbine type switch [-] + REAL(ReKi) :: WtrDpth !< Water depth [m] END TYPE ED_InitInputType ! ======================= ! ========= ED_InitOutputType ======= @@ -84,17 +86,6 @@ MODULE ElastoDyn_Types REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BMassDen !< Blade mass density for distributed input data [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FlpStff !< Blade flap stiffness for distributed input data [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: EdgStff !< Blade edge stiffness for distributed input data [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: GJStff !< Blade torsional stiffness for a given input station [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: EAStff !< Blade extensional stiffness for a given input station [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Alpha !< Blade coupling coefficient between flap and twist for a given input station [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FlpIner !< Blade flap (about local structural yb-axis) mass inertia per unit length for a given input station [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: EdgIner !< Blade edge (about local structural xb-axis) mass inertia per unit length for a given input station [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PrecrvRef !< Offset for defining the reference axis from the pitch axis for precurved blades at a given input station [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: PreswpRef !< Offset for defining the reference axis from the pitch axis for preswept blades at a given input station [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FlpcgOf !< Blade flap (along local aerodynamic xb-axis) mass cg offset for a given input station [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: EdgcgOf !< Blade edge (along local aerodynamic yb-axis) mass cg offset for a given input station [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FlpEAOf !< Blade flap (along local aerodynamic xb-axis) elastic axis offset for a given input station [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: EdgEAOf !< Blade edge (along local aerodynamic yb-axis) elastic axis offset for a given input station [-] REAL(ReKi) , DIMENSION(1:2) :: BldFlDmp !< Blade structural damping ratios in flapwise direction [-] REAL(ReKi) , DIMENSION(1:1) :: BldEdDmp !< Blade structural damping ratios in edgewise direction [-] REAL(ReKi) , DIMENSION(1:2) :: FlStTunr !< Blade flapwise modal stiffness tuners (input) [-] @@ -164,12 +155,12 @@ MODULE ElastoDyn_Types REAL(ReKi) :: NcIMUyn !< Lateral distance from the tower-top to the nacelle IMU [meters] REAL(ReKi) :: NcIMUzn !< Vertical distance from the tower-top to the nacelle IMU [meters] REAL(ReKi) :: Twr2Shft !< Vertical distance from the tower-top to the rotor shaft [meters] - REAL(ReKi) :: TowerHt !< Height of tower above ground level [onshore] or MSL [offshore] [meters] - REAL(ReKi) :: TowerBsHt !< Height of tower base above ground level [onshore] or MSL [offshore] [meters] - REAL(ReKi) :: PtfmCMxt !< Downwind distance from the ground [onshore] or MSL [offshore] to the platform CM [meters] - REAL(ReKi) :: PtfmCMyt !< Lateral distance from the ground [onshore] or MSL [offshore] to the platform CM [meters] - REAL(ReKi) :: PtfmCMzt !< Vertical distance from the ground [onshore] or MSL [offshore] to the platform CM [meters] - REAL(ReKi) :: PtfmRefzt !< Vertical distance from the ground [onshore] or MSL [offshore] to the platform reference point [meters] + REAL(ReKi) :: TowerHt !< Height of tower relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] [meters] + REAL(ReKi) :: TowerBsHt !< Height of tower base relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] [meters] + REAL(ReKi) :: PtfmCMxt !< Downwind distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM [meters] + REAL(ReKi) :: PtfmCMyt !< Lateral distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM [meters] + REAL(ReKi) :: PtfmCMzt !< Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM [meters] + REAL(ReKi) :: PtfmRefzt !< Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform reference point [meters] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TipMass !< Tip-brake masses [kg] REAL(ReKi) :: HubMass !< Hub mass [kg] REAL(ReKi) :: HubIner !< Hub inertia about teeter axis (2-blader) or rotor axis (3-blader) [kg m^2] @@ -223,41 +214,19 @@ MODULE ElastoDyn_Types REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwFAM2Sh !< Tower fore-aft mode-2 shape coefficients [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwSSM1Sh !< Tower side-to-side mode-1 shape coefficients [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwSSM2Sh !< Tower side-to-side mode-2 shape coefficients [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwGJStif !< Tower torsional stiffness for a given input station [Nm^2] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwEAStif !< Tower extensional stiffness for a given input station [N] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwFAIner !< Tower fore-aft (about yt-axis) mass inertia per unit length for a given input station [kg m] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwSSIner !< Tower side-to-side (about xt-axis) mass inertia per unit length for a given input station [kg m] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwFAcgOf !< Tower fore-aft (along the xt-axis) mass cg offset for a given input station [meters] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TwSScgOf !< Tower fore-aft (along the yt-axis) mass cg offset for a given input station [meters] LOGICAL :: RFrlDOF !< Rotor-furl DOF [-] LOGICAL :: TFrlDOF !< Tail-furl DOF [-] REAL(ReKi) :: RotFurl !< Initial or fixed rotor-furl angle [radians] REAL(ReKi) :: TailFurl !< Initial or fixed tail-furl angle [radians] REAL(ReKi) :: Yaw2Shft !< Lateral distance from the yaw axis to the rotor shaft [meters] REAL(ReKi) :: ShftSkew !< Rotor shaft skew angle [radians] - REAL(ReKi) :: RFrlCMxn !< Downwind distance from tower-top to rotor-furl CM [meters] - REAL(ReKi) :: RFrlCMyn !< Lateral distance from tower-top to rotor-furl CM [meters] - REAL(ReKi) :: RFrlCMzn !< Vertical distance from tower-top to rotor-furl CM [meters] - REAL(ReKi) :: BoomCMxn !< Downwind distance from tower-top to tail boom CM [meters] - REAL(ReKi) :: BoomCMyn !< Lateral distance from tower-top to tail boom CM [meters] - REAL(ReKi) :: BoomCMzn !< Vertical distance from tower-top to tail boom CM [meters] - REAL(ReKi) :: TFinCMxn !< Downwind distance from tower-top to tail fin CM [meters] - REAL(ReKi) :: TFinCMyn !< Lateral distance from tower-top to tail fin CM [meters] - REAL(ReKi) :: TFinCMzn !< Vertical distance from tower-top to tail fin CM [meters] - REAL(ReKi) :: TFinCPxn !< Downwind distance from tower-top to tail fin CP [meters] - REAL(ReKi) :: TFinCPyn !< Lateral distance from tower-top to tail fin CP [meters] - REAL(ReKi) :: TFinCPzn !< Vertical distance from tower-top to tail fin CP [meters] - REAL(ReKi) :: TFinSkew !< Tail fin chordline skew angle [radians] - REAL(ReKi) :: TFinTilt !< Tail fin chordline tilt angle [radians] - REAL(ReKi) :: TFinBank !< Tail fin planform bank angle [radians] - REAL(ReKi) :: RFrlPntxn !< Downwind distance from tower-top to arbitrary point on rotor-furl axis [meters] - REAL(ReKi) :: RFrlPntyn !< Lateral distance from tower-top to arbitrary point on rotor-furl axis [meters] - REAL(ReKi) :: RFrlPntzn !< Vertical distance from tower-top to arbitrary point on rotor-furl axis [meters] + REAL(ReKi) , DIMENSION(1:3) :: RFrlCM_n !< Vector from tower-top to rotor-furl CM [meters] + REAL(ReKi) , DIMENSION(1:3) :: BoomCM_n !< Vector from tower-top to tail boom CM [meters] + REAL(ReKi) , DIMENSION(1:3) :: TFinCM_n !< Vector from tower-top to tail fin CM [meters] + REAL(ReKi) , DIMENSION(1:3) :: RFrlPnt_n !< Vector from tower-top to arbitrary point on rotor-furl axis [meters] REAL(ReKi) :: RFrlSkew !< Rotor-furl axis skew angle [radians] REAL(ReKi) :: RFrlTilt !< Rotor-furl axis tilt angle [radians] - REAL(ReKi) :: TFrlPntxn !< Downwind distance from tower-top to arbitrary point on tail-furl axis [meters] - REAL(ReKi) :: TFrlPntyn !< Lateral distance from tower-top to arbitrary point on tail-furl axis [meters] - REAL(ReKi) :: TFrlPntzn !< Vertical distance from tower-top to arbitrary point on tail-furl axis [meters] + REAL(ReKi) , DIMENSION(1:3) :: TFrlPnt_n !< Vector from tower-top to arbitrary point on tail-furl axis [meters] REAL(ReKi) :: TFrlSkew !< Rotor-furl axis skew angle [radians] REAL(ReKi) :: TFrlTilt !< Rotor-furl axis tilt angle [radians] REAL(ReKi) :: RFrlMass !< Rotor-furl mass [kg] @@ -268,7 +237,6 @@ MODULE ElastoDyn_Types INTEGER(IntKi) :: RFrlMod !< Rotor-furl spring/damper model switch [-] REAL(ReKi) :: RFrlSpr !< Rotor-furl spring constant [N-m/rad] REAL(ReKi) :: RFrlDmp !< Rotor-furl damping constant [N-m/(rad/s)] - REAL(ReKi) :: RFrlCDmp !< Rotor-furl rate-independent Coulomb-damping moment [N-m] REAL(ReKi) :: RFrlUSSP !< Rotor-furl up-stop spring position [radians] REAL(ReKi) :: RFrlDSSP !< Rotor-furl down-stop spring position [radians] REAL(ReKi) :: RFrlUSSpr !< Rotor-furl up-stop spring constant [N-m/rad] @@ -280,7 +248,6 @@ MODULE ElastoDyn_Types INTEGER(IntKi) :: TFrlMod !< Tail-furl spring/damper model switch [-] REAL(ReKi) :: TFrlSpr !< Tail-furl spring constant [N-m/rad] REAL(ReKi) :: TFrlDmp !< Tail-furl damping constant [N-m/(rad/s)] - REAL(ReKi) :: TFrlCDmp !< Tail-furl rate-independent Coulomb-damping moment [N-m] REAL(ReKi) :: TFrlUSSP !< Tail-furl up-stop spring position [radians] REAL(ReKi) :: TFrlDSSP !< Tail-furl down-stop spring position [radians] REAL(ReKi) :: TFrlUSSpr !< Tail-furl up-stop spring constant [N-m/rad] @@ -331,9 +298,6 @@ MODULE ElastoDyn_Types REAL(R8Ki) , DIMENSION(:,:,:), ALLOCATABLE :: n1 !< n1(K,J,:) = vector / direction n1 for node J of blade K (= LxbK from the IEC coord. system) [-] REAL(R8Ki) , DIMENSION(:,:,:), ALLOCATABLE :: n2 !< n2(K,J,:) = vector / direction n2 for node J of blade K (= LybK from the IEC coord. system) [-] REAL(R8Ki) , DIMENSION(:,:,:), ALLOCATABLE :: n3 !< n3(K,J,:) = vector / direction n3 for node J of blade K (= LzbK from the IEC coord. system) [-] - REAL(R8Ki) , DIMENSION(1:3) :: p1 !< Vector / direction p1 (used to calc. and return tail aerodynamic loads from AeroDyn) [-] - REAL(R8Ki) , DIMENSION(1:3) :: p2 !< Vector / direction p2 (used to calc. and return tail aerodynamic loads from AeroDyn) [-] - REAL(R8Ki) , DIMENSION(1:3) :: p3 !< Vector / direction p3 (used to calc. and return tail aerodynamic loads from AeroDyn) [-] REAL(R8Ki) , DIMENSION(1:3) :: rf1 !< Vector / direction rf1 (rotor-furl coordinate system = d1 when rotor-furl angle = 0) [-] REAL(R8Ki) , DIMENSION(1:3) :: rf2 !< Vector / direction rf2 (rotor-furl coordinate system = d2 when rotor-furl angle = 0) [-] REAL(R8Ki) , DIMENSION(1:3) :: rf3 !< Vector / direction rf3 (rotor-furl coordinate system = d3 when rotor-furl angle = 0) [-] @@ -395,6 +359,7 @@ MODULE ElastoDyn_Types REAL(R8Ki) , DIMENSION(1:3) :: rPQ !< Position vector from teeter pin (point P) to apex of rotation (point Q) [m] REAL(R8Ki) , DIMENSION(1:3) :: rP !< Position vector from inertial frame origin to teeter pin (point P) [m] REAL(R8Ki) , DIMENSION(1:3) :: rV !< Position vector from inertial frame origin to specified point on rotor-furl axis (point V) [m] + REAL(R8Ki) , DIMENSION(1:3) :: rJ !< Position vector from inertial frame origin to tail fin center of mass (point J) [m] REAL(R8Ki) , DIMENSION(1:3) :: rZY !< Position vector from platform reference (point Z) to platform mass center (point Y) [m] REAL(R8Ki) , DIMENSION(1:3) :: rOU !< Position vector from tower-top / base plate (point O) to nacelle center of mass (point U). [m] REAL(R8Ki) , DIMENSION(1:3) :: rOV !< Position vector from tower-top / base plate (point O) to specified point on rotor-furl axis (point V) [m] @@ -408,7 +373,6 @@ MODULE ElastoDyn_Types REAL(R8Ki) , DIMENSION(1:3) :: rVP !< Position vector from specified point on rotor-furl axis (point V) to teeter pin (point P) [m] REAL(R8Ki) , DIMENSION(1:3) :: rWI !< Position vector from specified point on tail-furl axis (point W) to tail boom center of mass (point I) [m] REAL(R8Ki) , DIMENSION(1:3) :: rWJ !< Position vector from specified point on tail-furl axis (point W) to tail fin center of mass (point J) [m] - REAL(R8Ki) , DIMENSION(1:3) :: rWK !< Position vector from specified point on tail-furl axis (point W) to tail fin center of pressure (point K) [m] REAL(R8Ki) , DIMENSION(1:3) :: rZT0 !< Position vector from platform reference (point Z) to tower base (point T(0)) [m] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: AngPosEF !< Angular position of the current point on the tower (body F) in the inertial frame (body E for earth) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: AngPosXF !< Angular position of the current point on the tower (body F) in the platform (body X) [-] @@ -465,7 +429,6 @@ MODULE ElastoDyn_Types REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: PLinVelED !< Partial linear velocity (and its 1st time derivative) of the center of mass of the structure that furls with the rotor (not including rotor) (point D) in the inertia frame (body E for earth) [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: PLinVelEI !< Partial linear velocity (and its 1st time derivative) of the tail boom center of mass (point I) in the inertia frame (body E for earth) [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: PLinVelEJ !< Partial linear velocity (and its 1st time derivative) of the tail fin center of mass (point J) in the inertia frame (body E for earth) [-] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: PLinVelEK !< Partial linear velocity (and its 1st time derivative) of the tail fin center of pressure(point K) in the inertia frame (body E for earth) [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: PLinVelEP !< Partial linear velocity (and its 1st time derivative) of the teeter pin (point P) in the inertia frame (body E for earth) [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: PLinVelEQ !< Partial linear velocity (and its 1st time derivative) of the apex of rotation (point Q) in the inertia frame (body E for earth) [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: PLinVelEU !< Partial linear velocity (and its 1st time derivative) of the nacelle center of mass (point U) in the inertia frame (body E for earth) [-] @@ -480,6 +443,7 @@ MODULE ElastoDyn_Types REAL(ReKi) , DIMENSION(1:3) :: LinVelEIMU !< Linear velocity of the nacelle IMU (point IMU) in the inertia frame [-] REAL(ReKi) , DIMENSION(1:3) :: LinVelEZ !< Linear velocity of platform reference (point Z) in the inertia frame [-] REAL(ReKi) , DIMENSION(1:3) :: LinVelEO !< Linear velocity of the base plate (point O) in the inertia frame (body E for earth) [-] + REAL(ReKi) , DIMENSION(1:3) :: LinVelEJ !< Linear velocity of the tail fin CM (point J) in the inertia frame (body E for earth) [-] REAL(ReKi) , DIMENSION(1:3) :: FrcONcRtt !< Portion of the force at yaw bearing (point O) due to the nacelle, generator, and rotor associated with everything but the QD2T()'s [-] REAL(ReKi) , DIMENSION(1:3) :: FrcPRott !< Portion of the force at the teeter pin (point P) due to the rotor associated with everything but the QD2T()'s [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: FrcS0Bt !< Portion of the force at the blade root (point S(0)) due to the blade associated with everything but the QD2T()'s [-] @@ -604,9 +568,6 @@ MODULE ElastoDyn_Types REAL(R8Ki) :: CSRFrlTlt !< Cosine*Sine of the rotor-furl axis tilt angle [-] REAL(R8Ki) :: CSTFrlSkw !< Cosine*Sine of the tail-furl axis skew angle [-] REAL(R8Ki) :: CSTFrlTlt !< Cosine*Sine of the tail-furl axis tilt angle [-] - REAL(R8Ki) :: CTFinBank !< Cosine of the tail fin planform bank angle [-] - REAL(R8Ki) :: CTFinSkew !< Cosine of the tail fin chordline skew angle [-] - REAL(R8Ki) :: CTFinTilt !< Cosine of the tail fin chordline tilt angle [-] REAL(R8Ki) :: CTFrlSkew !< Cosine of the tail-furl axis skew angle [-] REAL(R8Ki) :: CTFrlSkw2 !< Cosine-squared of the tail-furl axis skew angle [-] REAL(R8Ki) :: CTFrlTilt !< Cosine of the tail-furl axis tilt angle [-] @@ -619,11 +580,9 @@ MODULE ElastoDyn_Types REAL(ReKi) :: NacCMzn !< Vertical distance from tower-top to nacelle CM [-] REAL(ReKi) :: OverHang !< Distance from yaw axis to rotor apex or teeter pin [-] REAL(ReKi) :: ProjArea !< Swept area of the rotor projected onto the rotor plane (the plane normal to the low-speed shaft) [-] - REAL(ReKi) :: PtfmRefzt !< Vertical distance from the ground [onshore] or MSL [offshore] to the platform reference point [-] + REAL(ReKi) :: PtfmRefzt !< Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform reference point [-] REAL(ReKi) :: RefTwrHt !< Vertical distance between FAST's undisplaced tower height (variable TowerHt) and FAST's inertia frame reference point (variable PtfmRef); that is, RefTwrHt = TowerHt - PtfmRefzt [-] - REAL(ReKi) :: RFrlPntxn !< Downwind distance from tower-top to arbitrary point on rotor-furl axis [-] - REAL(ReKi) :: RFrlPntyn !< Lateral distance from tower-top to arbitrary point on rotor-furl axis [-] - REAL(ReKi) :: RFrlPntzn !< Vertical distance from tower-top to arbitrary point on rotor-furl axis [-] + REAL(ReKi) , DIMENSION(1:3) :: RFrlPnt_n !< Vector from tower-top to arbitrary point on rotor-furl axis [-] REAL(ReKi) :: rVDxn !< xn-component of position vector Rvd [-] REAL(ReKi) :: rVDyn !< yn-component of position vector rVD [-] REAL(ReKi) :: rVDzn !< zn-component of position vector rVD [-] @@ -639,9 +598,6 @@ MODULE ElastoDyn_Types REAL(ReKi) :: rWJxn !< xn-component of position vector rWJ [-] REAL(ReKi) :: rWJyn !< yn-component of position vector rWJ [-] REAL(ReKi) :: rWJzn !< zn-component of position vector rWJ [-] - REAL(ReKi) :: rWKxn !< xn-component of position vector rWK [-] - REAL(ReKi) :: rWKyn !< yn-component of position vector rWK [-] - REAL(ReKi) :: rWKzn !< zn-component of position vector rWK [-] REAL(ReKi) :: rZT0zt !< zt-component of position vector rZT0 [-] REAL(ReKi) :: rZYzt !< zt-component of position vector rZY [-] REAL(R8Ki) :: SinDel3 !< Sine of the Delta-3 angle for teetering rotors [-] @@ -652,19 +608,14 @@ MODULE ElastoDyn_Types REAL(R8Ki) :: SRFrlTlt2 !< Sine-squared of the rotor-furl axis tilt angle [-] REAL(R8Ki) :: SShftSkew !< Sine of the shaft skew angle [-] REAL(R8Ki) :: SShftTilt !< Sine of the shaft tilt angle [-] - REAL(R8Ki) :: STFinBank !< Sine of the tail fin planform bank angle [-] - REAL(R8Ki) :: STFinSkew !< Sine of the tail fin chordline skew angle [-] - REAL(R8Ki) :: STFinTilt !< Sine of the tail fin chordline tilt angle [-] REAL(R8Ki) :: STFrlSkew !< Sine of the tail-furl axis skew angle [-] REAL(R8Ki) :: STFrlSkw2 !< Sine-squared of the tail-furl axis skew angle [-] REAL(R8Ki) :: STFrlTilt !< Sine of the tail-furl axis tilt angle [-] REAL(R8Ki) :: STFrlTlt2 !< Sine-squared of the tail-furl axis tilt angle [-] - REAL(ReKi) :: TFrlPntxn !< Downwind distance from tower-top to arbitrary point on tail-furl axis [-] - REAL(ReKi) :: TFrlPntyn !< Lateral distance from tower-top to arbitrary point on tail-furl axis [-] - REAL(ReKi) :: TFrlPntzn !< Vertical distance from tower-top to arbitrary point on tail-furl axis [-] + REAL(ReKi) , DIMENSION(1:3) :: TFrlPnt_n !< Vector from tower-top to arbitrary point on tail-furl axis [-] REAL(ReKi) :: TipRad !< Preconed blade-tip radius [-] - REAL(ReKi) :: TowerHt !< Height of tower above ground level [-] - REAL(ReKi) :: TowerBsHt !< Height of tower base above ground level [onshore] or MSL [offshore] [meters] + REAL(ReKi) :: TowerHt !< Height of tower relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] [meters] + REAL(ReKi) :: TowerBsHt !< Height of tower base relative to ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] [meters] REAL(ReKi) :: UndSling !< Undersling length [-] INTEGER(IntKi) :: NumBl !< Number of turbine blades [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: AxRedTFA !< The axial-reduction terms for the fore-aft tower mode shapes [-] @@ -683,13 +634,8 @@ MODULE ElastoDyn_Types REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: TwrSSSF !< Tower side-to-side shape functions [-] INTEGER(IntKi) :: TTopNode !< Index of the additional node located at the tower-top = TwrNodes + 1 [-] INTEGER(IntKi) :: TwrNodes !< Number of tower nodes used in the analysis [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: InerTFA !< Interpolated tower fore-aft (about yt-axis) mass inertia per unit length [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: InerTSS !< Interpolated tower side-to-side (about xt-axis) mass inertia per unit length [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: StiffTGJ !< Interpolated tower torsional stiffness [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: StiffTEA !< Interpolated tower extensional stiffness [-] + INTEGER(IntKi) :: MHK !< MHK turbine type switch [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: StiffTFA !< Interpolated fore-aft tower stiffness [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: cgOffTFA !< Interpolated tower fore-aft mass cg offset [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: cgOffTSS !< Interpolated tower side-to-side mass cg offset [-] REAL(ReKi) :: AtfaIner !< Inertia of tail boom about the tail-furl axis whose origin is the tail boom center of mass [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BldCG !< Blade center of mass wrt the blade root [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BldMass !< Blade masses [-] @@ -721,37 +667,26 @@ MODULE ElastoDyn_Types REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PitchAxis !< Pitch axis for analysis nodes [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AeroTwst !< Aerodynamic twist of the blade at the analysis nodes [-] REAL(ReKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: AxRedBld !< The axial-reduction terms of the blade shape function [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BAlpha !< Interpolated blade coupling coefficient between flap and twist [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BldEDamp !< Blade edgewise damping coefficients [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BldFDamp !< Blade flapwise damping coefficients [-] REAL(ReKi) :: BldFlexL !< Flexible blade length [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: CAeroTwst !< Cosine of the aerodynamic twist of the blade at the analysis nodes [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: CBE !< Generalized edgewise damping of the blades [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: CBF !< Generalized flapwise damping of the blades [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: cgOffBEdg !< Interpolated blade edge (along local aerodynamic yb-axis) mass cg offset [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: cgOffBFlp !< Interpolated blade flap (along local aerodynamic xb-axis) mass cg offset [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Chord !< Chord of the blade at the analysis nodes [-] REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: CThetaS !< COS( ThetaS ) [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: DRNodes !< Length of variable-spaced blade elements [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: EAOffBEdg !< Interpolated blade edge (along local aerodynamic yb-axis) elastic axis offset [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: EAOffBFlp !< Interpolated blade flap (along local aerodynamic xb-axis) elastic axis offset [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: FStTunr !< Blade flapwise modal stiffness tuners (stored for all blades) [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: InerBEdg !< Interpolated blade edge (about local structural xb-axis) mass inertia per unit length [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: InerBFlp !< Interpolated blade flap (about local structural yb-axis) mass inertia per unit length [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: KBE !< Generalized edgewise stiffness of the blades [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: KBF !< Generalized flapwise stiffness of the blades [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: MassB !< Interpolated lineal blade mass density [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: RefAxisxb !< Interpolated Offset for defining the reference axis from the pitch axis for precurved blades at a given input station (along xb-axis) [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: RefAxisyb !< Interpolated Offset for defining the reference axis from the pitch axis for preswept blades at a given input station (along yb-axis) [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: RNodes !< Radius to analysis nodes relative to hub ( 0 < RNodes(:) < BldFlexL ) [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: RNodesNorm !< Normalized radius to analysis nodes relative to hub ( 0 < RNodesNorm(:) < 1 ) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: rSAerCenn1 !< Distance from point S on a blade to the aerodynamic center in the n1 direction (m) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: rSAerCenn2 !< Distance from point S on a blade to the aerodynamic center in the n2 direction (m) [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: SAeroTwst !< Sine of the aerodynamic twist of the blade at the analysis nodes [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: StiffBE !< Interpolated edgewise blade stiffness [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: StiffBEA !< Interpolated blade extensional stiffness [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: StiffBF !< Interpolated flapwise blade stiffness [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: StiffBGJ !< Interpolated blade torsional stiffness [-] REAL(R8Ki) , DIMENSION(:,:), ALLOCATABLE :: SThetaS !< SIN( ThetaS ) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: ThetaS !< Structural twist for analysis nodes [radians] REAL(ReKi) , DIMENSION(:,:,:,:,:), ALLOCATABLE :: TwistedSF !< Interpolated lineal blade mass density [-] @@ -770,7 +705,6 @@ MODULE ElastoDyn_Types REAL(ReKi) :: TeetSSSp !< Rotor-teeter soft-stop linear-spring constant [-] REAL(ReKi) :: TeetSStP !< Rotor-teeter soft-stop position [-] INTEGER(IntKi) :: TeetMod !< Rotor-teeter spring/damper model switch [-] - REAL(ReKi) :: TFrlCDmp !< Tail-furl rate-independent Coulomb-damping moment [-] REAL(ReKi) :: TFrlDmp !< Tail-furl damping constant [-] REAL(ReKi) :: TFrlDSDmp !< Tail-furl down-stop damping constant [-] REAL(ReKi) :: TFrlDSDP !< Tail-furl down-stop damper position [-] @@ -782,7 +716,6 @@ MODULE ElastoDyn_Types REAL(ReKi) :: TFrlUSSP !< Tail-furl up-stop spring position [-] REAL(ReKi) :: TFrlUSSpr !< Tail-furl up-stop spring constant [-] INTEGER(IntKi) :: TFrlMod !< Tail-furl spring/damper model switch [-] - REAL(ReKi) :: RFrlCDmp !< Rotor-furl rate-independent Coulomb-damping moment [-] REAL(ReKi) :: RFrlDmp !< Rotor-furl damping constant [-] REAL(ReKi) :: RFrlDSDmp !< Rotor-furl down-stop damping constant [-] REAL(ReKi) :: RFrlDSDP !< Rotor-furl down-stop damper position [-] @@ -807,8 +740,8 @@ MODULE ElastoDyn_Types REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: BElmntMass !< Mass of the blade elements [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TElmntMass !< Mass of the tower elements [-] INTEGER(IntKi) :: method !< Identifier for integration method (1 [RK4], 2 [AB4], or 3 [ABM4]) [-] - REAL(ReKi) :: PtfmCMxt !< Downwind distance from the ground [onshore] or MSL [offshore] to the platform CM [meters] - REAL(ReKi) :: PtfmCMyt !< Lateral distance from the ground [onshore] or MSL [offshore] to the platform CM [meters] + REAL(ReKi) :: PtfmCMxt !< Downwind distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM [meters] + REAL(ReKi) :: PtfmCMyt !< Lateral distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform CM [meters] LOGICAL :: BD4Blades !< flag to determine if BeamDyn is computing blade loads (true) or ElastoDyn is (false) [-] LOGICAL :: UseAD14 !< flag to determine if AeroDyn14 is being used. Will remove this later when we've replaced AD14. [-] INTEGER(IntKi) :: BldNd_NumOuts !< Number of requested output channels per blade node (ED_AllBldNdOuts) [-] @@ -828,6 +761,7 @@ MODULE ElastoDyn_Types TYPE(MeshType) :: TowerPtLoads !< Tower line2 mesh with forces: surge/xi (1), sway/yi (2), and heave/zi (3)-components of the portion of the tower force at the current tower node (point T); and moments: roll/xi (1), pitch/yi (2), and yaw/zi (3)-components of the portion of the tower moment acting at the current tower node [N/m] TYPE(MeshType) :: HubPtLoad !< A mesh at the teeter pin, containing forces: surge/xi (1), sway/yi (2), and heave/zi (3)-components; and moments: roll/xi (1), pitch/yi (2), and yaw/zi (3)-components acting at the hub. Passed from BeamDyn [-] TYPE(MeshType) :: NacelleLoads !< From ServoDyn/TMD: loads on the nacelle. [-] + TYPE(MeshType) :: TFinCMLoads !< Aerodynamic forces and moments at the tail-fin center of mass point (point J) [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: TwrAddedMass !< 6-by-6 added mass matrix of the tower elements, per unit length-bjj: place on a mesh [per unit length] REAL(ReKi) , DIMENSION(1:6,1:6) :: PtfmAddedMass !< Platform added mass matrix [kg, kg-m, kg-m^2] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BlPitchCom !< Commanded blade pitch angles [radians] @@ -848,6 +782,7 @@ MODULE ElastoDyn_Types TYPE(MeshType) :: RotorFurlMotion14 !< For AeroDyn14: motions of the rotor furl point. [-] TYPE(MeshType) :: NacelleMotion !< For AeroDyn14 & ServoDyn/TMD: motions of the nacelle. [-] TYPE(MeshType) :: TowerBaseMotion14 !< For AeroDyn 14: motions of the tower base [-] + TYPE(MeshType) :: TFinCMMotion !< For AeroDyn: motions of the tail find CM point (point J) [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< Data to be written to an output file: see WriteOutputHdr for names of each variable [see WriteOutputUnt] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: BlPitch !< Current blade pitch angles [radians] REAL(ReKi) :: Yaw !< Current nacelle yaw [radians] @@ -904,17 +839,31 @@ SUBROUTINE ED_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrSt DstInitInputData%CompElast = SrcInitInputData%CompElast DstInitInputData%RootName = SrcInitInputData%RootName DstInitInputData%Gravity = SrcInitInputData%Gravity + DstInitInputData%MHK = SrcInitInputData%MHK + DstInitInputData%WtrDpth = SrcInitInputData%WtrDpth END SUBROUTINE ED_CopyInitInput - SUBROUTINE ED_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE ED_DestroyInitInput SUBROUTINE ED_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -958,6 +907,8 @@ SUBROUTINE ED_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 1 ! CompElast Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName Re_BufSz = Re_BufSz + 1 ! Gravity + Int_BufSz = Int_BufSz + 1 ! MHK + Re_BufSz = Re_BufSz + 1 ! WtrDpth IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1003,6 +954,10 @@ SUBROUTINE ED_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg END DO ! I ReKiBuf(Re_Xferred) = InData%Gravity Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%MHK + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WtrDpth + Re_Xferred = Re_Xferred + 1 END SUBROUTINE ED_PackInitInput SUBROUTINE ED_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1054,6 +1009,10 @@ SUBROUTINE ED_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END DO ! I OutData%Gravity = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%MHK = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WtrDpth = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE ED_UnPackInitInput SUBROUTINE ED_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -1246,22 +1205,35 @@ SUBROUTINE ED_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, Er ENDIF END SUBROUTINE ED_CopyInitOutput - SUBROUTINE ED_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN DEALLOCATE(InitOutputData%WriteOutputUnt) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitOutputData%BlPitch)) THEN DEALLOCATE(InitOutputData%BlPitch) ENDIF @@ -2185,138 +2157,6 @@ SUBROUTINE ED_CopyBladeInputData( SrcBladeInputDataData, DstBladeInputDataData, END IF END IF DstBladeInputDataData%EdgStff = SrcBladeInputDataData%EdgStff -ENDIF -IF (ALLOCATED(SrcBladeInputDataData%GJStff)) THEN - i1_l = LBOUND(SrcBladeInputDataData%GJStff,1) - i1_u = UBOUND(SrcBladeInputDataData%GJStff,1) - IF (.NOT. ALLOCATED(DstBladeInputDataData%GJStff)) THEN - ALLOCATE(DstBladeInputDataData%GJStff(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeInputDataData%GJStff.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladeInputDataData%GJStff = SrcBladeInputDataData%GJStff -ENDIF -IF (ALLOCATED(SrcBladeInputDataData%EAStff)) THEN - i1_l = LBOUND(SrcBladeInputDataData%EAStff,1) - i1_u = UBOUND(SrcBladeInputDataData%EAStff,1) - IF (.NOT. ALLOCATED(DstBladeInputDataData%EAStff)) THEN - ALLOCATE(DstBladeInputDataData%EAStff(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeInputDataData%EAStff.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladeInputDataData%EAStff = SrcBladeInputDataData%EAStff -ENDIF -IF (ALLOCATED(SrcBladeInputDataData%Alpha)) THEN - i1_l = LBOUND(SrcBladeInputDataData%Alpha,1) - i1_u = UBOUND(SrcBladeInputDataData%Alpha,1) - IF (.NOT. ALLOCATED(DstBladeInputDataData%Alpha)) THEN - ALLOCATE(DstBladeInputDataData%Alpha(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeInputDataData%Alpha.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladeInputDataData%Alpha = SrcBladeInputDataData%Alpha -ENDIF -IF (ALLOCATED(SrcBladeInputDataData%FlpIner)) THEN - i1_l = LBOUND(SrcBladeInputDataData%FlpIner,1) - i1_u = UBOUND(SrcBladeInputDataData%FlpIner,1) - IF (.NOT. ALLOCATED(DstBladeInputDataData%FlpIner)) THEN - ALLOCATE(DstBladeInputDataData%FlpIner(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeInputDataData%FlpIner.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladeInputDataData%FlpIner = SrcBladeInputDataData%FlpIner -ENDIF -IF (ALLOCATED(SrcBladeInputDataData%EdgIner)) THEN - i1_l = LBOUND(SrcBladeInputDataData%EdgIner,1) - i1_u = UBOUND(SrcBladeInputDataData%EdgIner,1) - IF (.NOT. ALLOCATED(DstBladeInputDataData%EdgIner)) THEN - ALLOCATE(DstBladeInputDataData%EdgIner(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeInputDataData%EdgIner.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladeInputDataData%EdgIner = SrcBladeInputDataData%EdgIner -ENDIF -IF (ALLOCATED(SrcBladeInputDataData%PrecrvRef)) THEN - i1_l = LBOUND(SrcBladeInputDataData%PrecrvRef,1) - i1_u = UBOUND(SrcBladeInputDataData%PrecrvRef,1) - IF (.NOT. ALLOCATED(DstBladeInputDataData%PrecrvRef)) THEN - ALLOCATE(DstBladeInputDataData%PrecrvRef(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeInputDataData%PrecrvRef.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladeInputDataData%PrecrvRef = SrcBladeInputDataData%PrecrvRef -ENDIF -IF (ALLOCATED(SrcBladeInputDataData%PreswpRef)) THEN - i1_l = LBOUND(SrcBladeInputDataData%PreswpRef,1) - i1_u = UBOUND(SrcBladeInputDataData%PreswpRef,1) - IF (.NOT. ALLOCATED(DstBladeInputDataData%PreswpRef)) THEN - ALLOCATE(DstBladeInputDataData%PreswpRef(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeInputDataData%PreswpRef.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladeInputDataData%PreswpRef = SrcBladeInputDataData%PreswpRef -ENDIF -IF (ALLOCATED(SrcBladeInputDataData%FlpcgOf)) THEN - i1_l = LBOUND(SrcBladeInputDataData%FlpcgOf,1) - i1_u = UBOUND(SrcBladeInputDataData%FlpcgOf,1) - IF (.NOT. ALLOCATED(DstBladeInputDataData%FlpcgOf)) THEN - ALLOCATE(DstBladeInputDataData%FlpcgOf(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeInputDataData%FlpcgOf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladeInputDataData%FlpcgOf = SrcBladeInputDataData%FlpcgOf -ENDIF -IF (ALLOCATED(SrcBladeInputDataData%EdgcgOf)) THEN - i1_l = LBOUND(SrcBladeInputDataData%EdgcgOf,1) - i1_u = UBOUND(SrcBladeInputDataData%EdgcgOf,1) - IF (.NOT. ALLOCATED(DstBladeInputDataData%EdgcgOf)) THEN - ALLOCATE(DstBladeInputDataData%EdgcgOf(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeInputDataData%EdgcgOf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladeInputDataData%EdgcgOf = SrcBladeInputDataData%EdgcgOf -ENDIF -IF (ALLOCATED(SrcBladeInputDataData%FlpEAOf)) THEN - i1_l = LBOUND(SrcBladeInputDataData%FlpEAOf,1) - i1_u = UBOUND(SrcBladeInputDataData%FlpEAOf,1) - IF (.NOT. ALLOCATED(DstBladeInputDataData%FlpEAOf)) THEN - ALLOCATE(DstBladeInputDataData%FlpEAOf(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeInputDataData%FlpEAOf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladeInputDataData%FlpEAOf = SrcBladeInputDataData%FlpEAOf -ENDIF -IF (ALLOCATED(SrcBladeInputDataData%EdgEAOf)) THEN - i1_l = LBOUND(SrcBladeInputDataData%EdgEAOf,1) - i1_u = UBOUND(SrcBladeInputDataData%EdgEAOf,1) - IF (.NOT. ALLOCATED(DstBladeInputDataData%EdgEAOf)) THEN - ALLOCATE(DstBladeInputDataData%EdgEAOf(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladeInputDataData%EdgEAOf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstBladeInputDataData%EdgEAOf = SrcBladeInputDataData%EdgEAOf ENDIF DstBladeInputDataData%BldFlDmp = SrcBladeInputDataData%BldFlDmp DstBladeInputDataData%BldEdDmp = SrcBladeInputDataData%BldEdDmp @@ -2359,15 +2199,27 @@ SUBROUTINE ED_CopyBladeInputData( SrcBladeInputDataData, DstBladeInputDataData, ENDIF END SUBROUTINE ED_CopyBladeInputData - SUBROUTINE ED_DestroyBladeInputData( BladeInputDataData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyBladeInputData( BladeInputDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BladeInputData), INTENT(INOUT) :: BladeInputDataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyBladeInputData' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyBladeInputData' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(BladeInputDataData%BlFract)) THEN DEALLOCATE(BladeInputDataData%BlFract) ENDIF @@ -2386,39 +2238,6 @@ SUBROUTINE ED_DestroyBladeInputData( BladeInputDataData, ErrStat, ErrMsg ) IF (ALLOCATED(BladeInputDataData%EdgStff)) THEN DEALLOCATE(BladeInputDataData%EdgStff) ENDIF -IF (ALLOCATED(BladeInputDataData%GJStff)) THEN - DEALLOCATE(BladeInputDataData%GJStff) -ENDIF -IF (ALLOCATED(BladeInputDataData%EAStff)) THEN - DEALLOCATE(BladeInputDataData%EAStff) -ENDIF -IF (ALLOCATED(BladeInputDataData%Alpha)) THEN - DEALLOCATE(BladeInputDataData%Alpha) -ENDIF -IF (ALLOCATED(BladeInputDataData%FlpIner)) THEN - DEALLOCATE(BladeInputDataData%FlpIner) -ENDIF -IF (ALLOCATED(BladeInputDataData%EdgIner)) THEN - DEALLOCATE(BladeInputDataData%EdgIner) -ENDIF -IF (ALLOCATED(BladeInputDataData%PrecrvRef)) THEN - DEALLOCATE(BladeInputDataData%PrecrvRef) -ENDIF -IF (ALLOCATED(BladeInputDataData%PreswpRef)) THEN - DEALLOCATE(BladeInputDataData%PreswpRef) -ENDIF -IF (ALLOCATED(BladeInputDataData%FlpcgOf)) THEN - DEALLOCATE(BladeInputDataData%FlpcgOf) -ENDIF -IF (ALLOCATED(BladeInputDataData%EdgcgOf)) THEN - DEALLOCATE(BladeInputDataData%EdgcgOf) -ENDIF -IF (ALLOCATED(BladeInputDataData%FlpEAOf)) THEN - DEALLOCATE(BladeInputDataData%FlpEAOf) -ENDIF -IF (ALLOCATED(BladeInputDataData%EdgEAOf)) THEN - DEALLOCATE(BladeInputDataData%EdgEAOf) -ENDIF IF (ALLOCATED(BladeInputDataData%BldFl1Sh)) THEN DEALLOCATE(BladeInputDataData%BldFl1Sh) ENDIF @@ -2495,61 +2314,6 @@ SUBROUTINE ED_PackBladeInputData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E IF ( ALLOCATED(InData%EdgStff) ) THEN Int_BufSz = Int_BufSz + 2*1 ! EdgStff upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%EdgStff) ! EdgStff - END IF - Int_BufSz = Int_BufSz + 1 ! GJStff allocated yes/no - IF ( ALLOCATED(InData%GJStff) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! GJStff upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%GJStff) ! GJStff - END IF - Int_BufSz = Int_BufSz + 1 ! EAStff allocated yes/no - IF ( ALLOCATED(InData%EAStff) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! EAStff upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%EAStff) ! EAStff - 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 ! FlpIner allocated yes/no - IF ( ALLOCATED(InData%FlpIner) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! FlpIner upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%FlpIner) ! FlpIner - END IF - Int_BufSz = Int_BufSz + 1 ! EdgIner allocated yes/no - IF ( ALLOCATED(InData%EdgIner) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! EdgIner upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%EdgIner) ! EdgIner - END IF - Int_BufSz = Int_BufSz + 1 ! PrecrvRef allocated yes/no - IF ( ALLOCATED(InData%PrecrvRef) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! PrecrvRef upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%PrecrvRef) ! PrecrvRef - END IF - Int_BufSz = Int_BufSz + 1 ! PreswpRef allocated yes/no - IF ( ALLOCATED(InData%PreswpRef) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! PreswpRef upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%PreswpRef) ! PreswpRef - END IF - Int_BufSz = Int_BufSz + 1 ! FlpcgOf allocated yes/no - IF ( ALLOCATED(InData%FlpcgOf) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! FlpcgOf upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%FlpcgOf) ! FlpcgOf - END IF - Int_BufSz = Int_BufSz + 1 ! EdgcgOf allocated yes/no - IF ( ALLOCATED(InData%EdgcgOf) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! EdgcgOf upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%EdgcgOf) ! EdgcgOf - END IF - Int_BufSz = Int_BufSz + 1 ! FlpEAOf allocated yes/no - IF ( ALLOCATED(InData%FlpEAOf) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! FlpEAOf upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%FlpEAOf) ! FlpEAOf - END IF - Int_BufSz = Int_BufSz + 1 ! EdgEAOf allocated yes/no - IF ( ALLOCATED(InData%EdgEAOf) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! EdgEAOf upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%EdgEAOf) ! EdgEAOf END IF Re_BufSz = Re_BufSz + SIZE(InData%BldFlDmp) ! BldFlDmp Re_BufSz = Re_BufSz + SIZE(InData%BldEdDmp) ! BldEdDmp @@ -2687,171 +2451,6 @@ SUBROUTINE ED_PackBladeInputData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E ReKiBuf(Re_Xferred) = InData%EdgStff(i1) Re_Xferred = Re_Xferred + 1 END DO - END IF - IF ( .NOT. ALLOCATED(InData%GJStff) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%GJStff,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%GJStff,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%GJStff,1), UBOUND(InData%GJStff,1) - ReKiBuf(Re_Xferred) = InData%GJStff(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%EAStff) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%EAStff,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%EAStff,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%EAStff,1), UBOUND(InData%EAStff,1) - ReKiBuf(Re_Xferred) = InData%EAStff(i1) - Re_Xferred = Re_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%FlpIner) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FlpIner,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FlpIner,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%FlpIner,1), UBOUND(InData%FlpIner,1) - ReKiBuf(Re_Xferred) = InData%FlpIner(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%EdgIner) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%EdgIner,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%EdgIner,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%EdgIner,1), UBOUND(InData%EdgIner,1) - ReKiBuf(Re_Xferred) = InData%EdgIner(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%PrecrvRef) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PrecrvRef,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PrecrvRef,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%PrecrvRef,1), UBOUND(InData%PrecrvRef,1) - ReKiBuf(Re_Xferred) = InData%PrecrvRef(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%PreswpRef) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PreswpRef,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PreswpRef,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%PreswpRef,1), UBOUND(InData%PreswpRef,1) - ReKiBuf(Re_Xferred) = InData%PreswpRef(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%FlpcgOf) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FlpcgOf,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FlpcgOf,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%FlpcgOf,1), UBOUND(InData%FlpcgOf,1) - ReKiBuf(Re_Xferred) = InData%FlpcgOf(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%EdgcgOf) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%EdgcgOf,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%EdgcgOf,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%EdgcgOf,1), UBOUND(InData%EdgcgOf,1) - ReKiBuf(Re_Xferred) = InData%EdgcgOf(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%FlpEAOf) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FlpEAOf,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FlpEAOf,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%FlpEAOf,1), UBOUND(InData%FlpEAOf,1) - ReKiBuf(Re_Xferred) = InData%FlpEAOf(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%EdgEAOf) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%EdgEAOf,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%EdgEAOf,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%EdgEAOf,1), UBOUND(InData%EdgEAOf,1) - ReKiBuf(Re_Xferred) = InData%EdgEAOf(i1) - Re_Xferred = Re_Xferred + 1 - END DO END IF DO i1 = LBOUND(InData%BldFlDmp,1), UBOUND(InData%BldFlDmp,1) ReKiBuf(Re_Xferred) = InData%BldFlDmp(i1) @@ -3049,273 +2648,75 @@ SUBROUTINE ED_UnPackBladeInputData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! GJStff not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%GJStff)) DEALLOCATE(OutData%GJStff) - ALLOCATE(OutData%GJStff(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%GJStff.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%GJStff,1), UBOUND(OutData%GJStff,1) - OutData%GJStff(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! EAStff not allocated + i1_l = LBOUND(OutData%BldFlDmp,1) + i1_u = UBOUND(OutData%BldFlDmp,1) + DO i1 = LBOUND(OutData%BldFlDmp,1), UBOUND(OutData%BldFlDmp,1) + OutData%BldFlDmp(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%BldEdDmp,1) + i1_u = UBOUND(OutData%BldEdDmp,1) + DO i1 = LBOUND(OutData%BldEdDmp,1), UBOUND(OutData%BldEdDmp,1) + OutData%BldEdDmp(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%FlStTunr,1) + i1_u = UBOUND(OutData%FlStTunr,1) + DO i1 = LBOUND(OutData%FlStTunr,1), UBOUND(OutData%FlStTunr,1) + OutData%FlStTunr(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldFl1Sh not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%EAStff)) DEALLOCATE(OutData%EAStff) - ALLOCATE(OutData%EAStff(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%BldFl1Sh)) DEALLOCATE(OutData%BldFl1Sh) + ALLOCATE(OutData%BldFl1Sh(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%EAStff.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BldFl1Sh.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%EAStff,1), UBOUND(OutData%EAStff,1) - OutData%EAStff(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%BldFl1Sh,1), UBOUND(OutData%BldFl1Sh,1) + OutData%BldFl1Sh(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Alpha not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldFl2Sh not allocated Int_Xferred = Int_Xferred + 1 ELSE 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 (ALLOCATED(OutData%BldFl2Sh)) DEALLOCATE(OutData%BldFl2Sh) + ALLOCATE(OutData%BldFl2Sh(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Alpha.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BldFl2Sh.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Alpha,1), UBOUND(OutData%Alpha,1) - OutData%Alpha(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%BldFl2Sh,1), UBOUND(OutData%BldFl2Sh,1) + OutData%BldFl2Sh(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FlpIner not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldEdgSh not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%FlpIner)) DEALLOCATE(OutData%FlpIner) - ALLOCATE(OutData%FlpIner(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%BldEdgSh)) DEALLOCATE(OutData%BldEdgSh) + ALLOCATE(OutData%BldEdgSh(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FlpIner.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BldEdgSh.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%FlpIner,1), UBOUND(OutData%FlpIner,1) - OutData%FlpIner(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! EdgIner not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%EdgIner)) DEALLOCATE(OutData%EdgIner) - ALLOCATE(OutData%EdgIner(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%EdgIner.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%EdgIner,1), UBOUND(OutData%EdgIner,1) - OutData%EdgIner(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PrecrvRef not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%PrecrvRef)) DEALLOCATE(OutData%PrecrvRef) - ALLOCATE(OutData%PrecrvRef(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PrecrvRef.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%PrecrvRef,1), UBOUND(OutData%PrecrvRef,1) - OutData%PrecrvRef(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PreswpRef not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%PreswpRef)) DEALLOCATE(OutData%PreswpRef) - ALLOCATE(OutData%PreswpRef(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PreswpRef.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%PreswpRef,1), UBOUND(OutData%PreswpRef,1) - OutData%PreswpRef(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FlpcgOf not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%FlpcgOf)) DEALLOCATE(OutData%FlpcgOf) - ALLOCATE(OutData%FlpcgOf(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FlpcgOf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%FlpcgOf,1), UBOUND(OutData%FlpcgOf,1) - OutData%FlpcgOf(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! EdgcgOf not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%EdgcgOf)) DEALLOCATE(OutData%EdgcgOf) - ALLOCATE(OutData%EdgcgOf(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%EdgcgOf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%EdgcgOf,1), UBOUND(OutData%EdgcgOf,1) - OutData%EdgcgOf(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FlpEAOf not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%FlpEAOf)) DEALLOCATE(OutData%FlpEAOf) - ALLOCATE(OutData%FlpEAOf(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FlpEAOf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%FlpEAOf,1), UBOUND(OutData%FlpEAOf,1) - OutData%FlpEAOf(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! EdgEAOf not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%EdgEAOf)) DEALLOCATE(OutData%EdgEAOf) - ALLOCATE(OutData%EdgEAOf(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%EdgEAOf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%EdgEAOf,1), UBOUND(OutData%EdgEAOf,1) - OutData%EdgEAOf(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - i1_l = LBOUND(OutData%BldFlDmp,1) - i1_u = UBOUND(OutData%BldFlDmp,1) - DO i1 = LBOUND(OutData%BldFlDmp,1), UBOUND(OutData%BldFlDmp,1) - OutData%BldFlDmp(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%BldEdDmp,1) - i1_u = UBOUND(OutData%BldEdDmp,1) - DO i1 = LBOUND(OutData%BldEdDmp,1), UBOUND(OutData%BldEdDmp,1) - OutData%BldEdDmp(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%FlStTunr,1) - i1_u = UBOUND(OutData%FlStTunr,1) - DO i1 = LBOUND(OutData%FlStTunr,1), UBOUND(OutData%FlStTunr,1) - OutData%FlStTunr(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldFl1Sh not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BldFl1Sh)) DEALLOCATE(OutData%BldFl1Sh) - ALLOCATE(OutData%BldFl1Sh(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BldFl1Sh.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%BldFl1Sh,1), UBOUND(OutData%BldFl1Sh,1) - OutData%BldFl1Sh(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldFl2Sh not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BldFl2Sh)) DEALLOCATE(OutData%BldFl2Sh) - ALLOCATE(OutData%BldFl2Sh(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BldFl2Sh.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%BldFl2Sh,1), UBOUND(OutData%BldFl2Sh,1) - OutData%BldFl2Sh(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldEdgSh not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BldEdgSh)) DEALLOCATE(OutData%BldEdgSh) - ALLOCATE(OutData%BldEdgSh(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BldEdgSh.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%BldEdgSh,1), UBOUND(OutData%BldEdgSh,1) - OutData%BldEdgSh(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%BldEdgSh,1), UBOUND(OutData%BldEdgSh,1) + OutData%BldEdgSh(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -3375,15 +2776,27 @@ SUBROUTINE ED_CopyBladeMeshInputData( SrcBladeMeshInputDataData, DstBladeMeshInp ENDIF END SUBROUTINE ED_CopyBladeMeshInputData - SUBROUTINE ED_DestroyBladeMeshInputData( BladeMeshInputDataData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyBladeMeshInputData( BladeMeshInputDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_BladeMeshInputData), INTENT(INOUT) :: BladeMeshInputDataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyBladeMeshInputData' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyBladeMeshInputData' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(BladeMeshInputDataData%RNodes)) THEN DEALLOCATE(BladeMeshInputDataData%RNodes) ENDIF @@ -3893,78 +3306,6 @@ SUBROUTINE ED_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrSt END IF END IF DstInputFileData%TwSSM2Sh = SrcInputFileData%TwSSM2Sh -ENDIF -IF (ALLOCATED(SrcInputFileData%TwGJStif)) THEN - i1_l = LBOUND(SrcInputFileData%TwGJStif,1) - i1_u = UBOUND(SrcInputFileData%TwGJStif,1) - IF (.NOT. ALLOCATED(DstInputFileData%TwGJStif)) THEN - ALLOCATE(DstInputFileData%TwGJStif(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%TwGJStif.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputFileData%TwGJStif = SrcInputFileData%TwGJStif -ENDIF -IF (ALLOCATED(SrcInputFileData%TwEAStif)) THEN - i1_l = LBOUND(SrcInputFileData%TwEAStif,1) - i1_u = UBOUND(SrcInputFileData%TwEAStif,1) - IF (.NOT. ALLOCATED(DstInputFileData%TwEAStif)) THEN - ALLOCATE(DstInputFileData%TwEAStif(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%TwEAStif.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputFileData%TwEAStif = SrcInputFileData%TwEAStif -ENDIF -IF (ALLOCATED(SrcInputFileData%TwFAIner)) THEN - i1_l = LBOUND(SrcInputFileData%TwFAIner,1) - i1_u = UBOUND(SrcInputFileData%TwFAIner,1) - IF (.NOT. ALLOCATED(DstInputFileData%TwFAIner)) THEN - ALLOCATE(DstInputFileData%TwFAIner(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%TwFAIner.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputFileData%TwFAIner = SrcInputFileData%TwFAIner -ENDIF -IF (ALLOCATED(SrcInputFileData%TwSSIner)) THEN - i1_l = LBOUND(SrcInputFileData%TwSSIner,1) - i1_u = UBOUND(SrcInputFileData%TwSSIner,1) - IF (.NOT. ALLOCATED(DstInputFileData%TwSSIner)) THEN - ALLOCATE(DstInputFileData%TwSSIner(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%TwSSIner.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputFileData%TwSSIner = SrcInputFileData%TwSSIner -ENDIF -IF (ALLOCATED(SrcInputFileData%TwFAcgOf)) THEN - i1_l = LBOUND(SrcInputFileData%TwFAcgOf,1) - i1_u = UBOUND(SrcInputFileData%TwFAcgOf,1) - IF (.NOT. ALLOCATED(DstInputFileData%TwFAcgOf)) THEN - ALLOCATE(DstInputFileData%TwFAcgOf(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%TwFAcgOf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputFileData%TwFAcgOf = SrcInputFileData%TwFAcgOf -ENDIF -IF (ALLOCATED(SrcInputFileData%TwSScgOf)) THEN - i1_l = LBOUND(SrcInputFileData%TwSScgOf,1) - i1_u = UBOUND(SrcInputFileData%TwSScgOf,1) - IF (.NOT. ALLOCATED(DstInputFileData%TwSScgOf)) THEN - ALLOCATE(DstInputFileData%TwSScgOf(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%TwSScgOf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputFileData%TwSScgOf = SrcInputFileData%TwSScgOf ENDIF DstInputFileData%RFrlDOF = SrcInputFileData%RFrlDOF DstInputFileData%TFrlDOF = SrcInputFileData%TFrlDOF @@ -3972,29 +3313,13 @@ SUBROUTINE ED_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrSt DstInputFileData%TailFurl = SrcInputFileData%TailFurl DstInputFileData%Yaw2Shft = SrcInputFileData%Yaw2Shft DstInputFileData%ShftSkew = SrcInputFileData%ShftSkew - DstInputFileData%RFrlCMxn = SrcInputFileData%RFrlCMxn - DstInputFileData%RFrlCMyn = SrcInputFileData%RFrlCMyn - DstInputFileData%RFrlCMzn = SrcInputFileData%RFrlCMzn - DstInputFileData%BoomCMxn = SrcInputFileData%BoomCMxn - DstInputFileData%BoomCMyn = SrcInputFileData%BoomCMyn - DstInputFileData%BoomCMzn = SrcInputFileData%BoomCMzn - DstInputFileData%TFinCMxn = SrcInputFileData%TFinCMxn - DstInputFileData%TFinCMyn = SrcInputFileData%TFinCMyn - DstInputFileData%TFinCMzn = SrcInputFileData%TFinCMzn - DstInputFileData%TFinCPxn = SrcInputFileData%TFinCPxn - DstInputFileData%TFinCPyn = SrcInputFileData%TFinCPyn - DstInputFileData%TFinCPzn = SrcInputFileData%TFinCPzn - DstInputFileData%TFinSkew = SrcInputFileData%TFinSkew - DstInputFileData%TFinTilt = SrcInputFileData%TFinTilt - DstInputFileData%TFinBank = SrcInputFileData%TFinBank - DstInputFileData%RFrlPntxn = SrcInputFileData%RFrlPntxn - DstInputFileData%RFrlPntyn = SrcInputFileData%RFrlPntyn - DstInputFileData%RFrlPntzn = SrcInputFileData%RFrlPntzn + DstInputFileData%RFrlCM_n = SrcInputFileData%RFrlCM_n + DstInputFileData%BoomCM_n = SrcInputFileData%BoomCM_n + DstInputFileData%TFinCM_n = SrcInputFileData%TFinCM_n + DstInputFileData%RFrlPnt_n = SrcInputFileData%RFrlPnt_n DstInputFileData%RFrlSkew = SrcInputFileData%RFrlSkew DstInputFileData%RFrlTilt = SrcInputFileData%RFrlTilt - DstInputFileData%TFrlPntxn = SrcInputFileData%TFrlPntxn - DstInputFileData%TFrlPntyn = SrcInputFileData%TFrlPntyn - DstInputFileData%TFrlPntzn = SrcInputFileData%TFrlPntzn + DstInputFileData%TFrlPnt_n = SrcInputFileData%TFrlPnt_n DstInputFileData%TFrlSkew = SrcInputFileData%TFrlSkew DstInputFileData%TFrlTilt = SrcInputFileData%TFrlTilt DstInputFileData%RFrlMass = SrcInputFileData%RFrlMass @@ -4005,7 +3330,6 @@ SUBROUTINE ED_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrSt DstInputFileData%RFrlMod = SrcInputFileData%RFrlMod DstInputFileData%RFrlSpr = SrcInputFileData%RFrlSpr DstInputFileData%RFrlDmp = SrcInputFileData%RFrlDmp - DstInputFileData%RFrlCDmp = SrcInputFileData%RFrlCDmp DstInputFileData%RFrlUSSP = SrcInputFileData%RFrlUSSP DstInputFileData%RFrlDSSP = SrcInputFileData%RFrlDSSP DstInputFileData%RFrlUSSpr = SrcInputFileData%RFrlUSSpr @@ -4017,7 +3341,6 @@ SUBROUTINE ED_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrSt DstInputFileData%TFrlMod = SrcInputFileData%TFrlMod DstInputFileData%TFrlSpr = SrcInputFileData%TFrlSpr DstInputFileData%TFrlDmp = SrcInputFileData%TFrlDmp - DstInputFileData%TFrlCDmp = SrcInputFileData%TFrlCDmp DstInputFileData%TFrlUSSP = SrcInputFileData%TFrlUSSP DstInputFileData%TFrlDSSP = SrcInputFileData%TFrlDSSP DstInputFileData%TFrlUSSpr = SrcInputFileData%TFrlUSSpr @@ -4044,15 +3367,27 @@ SUBROUTINE ED_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrSt DstInputFileData%BldNd_BladesOut = SrcInputFileData%BldNd_BladesOut END SUBROUTINE ED_CopyInputFile - SUBROUTINE ED_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_InputFile), INTENT(INOUT) :: InputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyInputFile' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyInputFile' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputFileData%BlPitch)) THEN DEALLOCATE(InputFileData%BlPitch) ENDIF @@ -4064,13 +3399,15 @@ SUBROUTINE ED_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(InputFileData%InpBlMesh)) THEN DO i1 = LBOUND(InputFileData%InpBlMesh,1), UBOUND(InputFileData%InpBlMesh,1) - CALL ED_Destroyblademeshinputdata( InputFileData%InpBlMesh(i1), ErrStat, ErrMsg ) + CALL ED_Destroyblademeshinputdata( InputFileData%InpBlMesh(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InputFileData%InpBlMesh) ENDIF IF (ALLOCATED(InputFileData%InpBl)) THEN DO i1 = LBOUND(InputFileData%InpBl,1), UBOUND(InputFileData%InpBl,1) - CALL ED_Destroybladeinputdata( InputFileData%InpBl(i1), ErrStat, ErrMsg ) + CALL ED_Destroybladeinputdata( InputFileData%InpBl(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InputFileData%InpBl) ENDIF @@ -4101,24 +3438,6 @@ SUBROUTINE ED_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) IF (ALLOCATED(InputFileData%TwSSM2Sh)) THEN DEALLOCATE(InputFileData%TwSSM2Sh) ENDIF -IF (ALLOCATED(InputFileData%TwGJStif)) THEN - DEALLOCATE(InputFileData%TwGJStif) -ENDIF -IF (ALLOCATED(InputFileData%TwEAStif)) THEN - DEALLOCATE(InputFileData%TwEAStif) -ENDIF -IF (ALLOCATED(InputFileData%TwFAIner)) THEN - DEALLOCATE(InputFileData%TwFAIner) -ENDIF -IF (ALLOCATED(InputFileData%TwSSIner)) THEN - DEALLOCATE(InputFileData%TwSSIner) -ENDIF -IF (ALLOCATED(InputFileData%TwFAcgOf)) THEN - DEALLOCATE(InputFileData%TwFAcgOf) -ENDIF -IF (ALLOCATED(InputFileData%TwSScgOf)) THEN - DEALLOCATE(InputFileData%TwSScgOf) -ENDIF IF (ALLOCATED(InputFileData%BldNd_OutList)) THEN DEALLOCATE(InputFileData%BldNd_OutList) ENDIF @@ -4361,36 +3680,6 @@ SUBROUTINE ED_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg IF ( ALLOCATED(InData%TwSSM2Sh) ) THEN Int_BufSz = Int_BufSz + 2*1 ! TwSSM2Sh upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%TwSSM2Sh) ! TwSSM2Sh - END IF - Int_BufSz = Int_BufSz + 1 ! TwGJStif allocated yes/no - IF ( ALLOCATED(InData%TwGJStif) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! TwGJStif upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TwGJStif) ! TwGJStif - END IF - Int_BufSz = Int_BufSz + 1 ! TwEAStif allocated yes/no - IF ( ALLOCATED(InData%TwEAStif) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! TwEAStif upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TwEAStif) ! TwEAStif - END IF - Int_BufSz = Int_BufSz + 1 ! TwFAIner allocated yes/no - IF ( ALLOCATED(InData%TwFAIner) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! TwFAIner upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TwFAIner) ! TwFAIner - END IF - Int_BufSz = Int_BufSz + 1 ! TwSSIner allocated yes/no - IF ( ALLOCATED(InData%TwSSIner) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! TwSSIner upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TwSSIner) ! TwSSIner - END IF - Int_BufSz = Int_BufSz + 1 ! TwFAcgOf allocated yes/no - IF ( ALLOCATED(InData%TwFAcgOf) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! TwFAcgOf upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TwFAcgOf) ! TwFAcgOf - END IF - Int_BufSz = Int_BufSz + 1 ! TwSScgOf allocated yes/no - IF ( ALLOCATED(InData%TwSScgOf) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! TwSScgOf upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TwSScgOf) ! TwSScgOf END IF Int_BufSz = Int_BufSz + 1 ! RFrlDOF Int_BufSz = Int_BufSz + 1 ! TFrlDOF @@ -4398,29 +3687,13 @@ SUBROUTINE ED_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_BufSz = Re_BufSz + 1 ! TailFurl Re_BufSz = Re_BufSz + 1 ! Yaw2Shft Re_BufSz = Re_BufSz + 1 ! ShftSkew - Re_BufSz = Re_BufSz + 1 ! RFrlCMxn - Re_BufSz = Re_BufSz + 1 ! RFrlCMyn - Re_BufSz = Re_BufSz + 1 ! RFrlCMzn - Re_BufSz = Re_BufSz + 1 ! BoomCMxn - Re_BufSz = Re_BufSz + 1 ! BoomCMyn - Re_BufSz = Re_BufSz + 1 ! BoomCMzn - Re_BufSz = Re_BufSz + 1 ! TFinCMxn - Re_BufSz = Re_BufSz + 1 ! TFinCMyn - Re_BufSz = Re_BufSz + 1 ! TFinCMzn - Re_BufSz = Re_BufSz + 1 ! TFinCPxn - Re_BufSz = Re_BufSz + 1 ! TFinCPyn - Re_BufSz = Re_BufSz + 1 ! TFinCPzn - Re_BufSz = Re_BufSz + 1 ! TFinSkew - Re_BufSz = Re_BufSz + 1 ! TFinTilt - Re_BufSz = Re_BufSz + 1 ! TFinBank - Re_BufSz = Re_BufSz + 1 ! RFrlPntxn - Re_BufSz = Re_BufSz + 1 ! RFrlPntyn - Re_BufSz = Re_BufSz + 1 ! RFrlPntzn + Re_BufSz = Re_BufSz + SIZE(InData%RFrlCM_n) ! RFrlCM_n + Re_BufSz = Re_BufSz + SIZE(InData%BoomCM_n) ! BoomCM_n + Re_BufSz = Re_BufSz + SIZE(InData%TFinCM_n) ! TFinCM_n + Re_BufSz = Re_BufSz + SIZE(InData%RFrlPnt_n) ! RFrlPnt_n Re_BufSz = Re_BufSz + 1 ! RFrlSkew Re_BufSz = Re_BufSz + 1 ! RFrlTilt - Re_BufSz = Re_BufSz + 1 ! TFrlPntxn - Re_BufSz = Re_BufSz + 1 ! TFrlPntyn - Re_BufSz = Re_BufSz + 1 ! TFrlPntzn + Re_BufSz = Re_BufSz + SIZE(InData%TFrlPnt_n) ! TFrlPnt_n Re_BufSz = Re_BufSz + 1 ! TFrlSkew Re_BufSz = Re_BufSz + 1 ! TFrlTilt Re_BufSz = Re_BufSz + 1 ! RFrlMass @@ -4431,7 +3704,6 @@ SUBROUTINE ED_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 1 ! RFrlMod Re_BufSz = Re_BufSz + 1 ! RFrlSpr Re_BufSz = Re_BufSz + 1 ! RFrlDmp - Re_BufSz = Re_BufSz + 1 ! RFrlCDmp Re_BufSz = Re_BufSz + 1 ! RFrlUSSP Re_BufSz = Re_BufSz + 1 ! RFrlDSSP Re_BufSz = Re_BufSz + 1 ! RFrlUSSpr @@ -4443,7 +3715,6 @@ SUBROUTINE ED_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 1 ! TFrlMod Re_BufSz = Re_BufSz + 1 ! TFrlSpr Re_BufSz = Re_BufSz + 1 ! TFrlDmp - Re_BufSz = Re_BufSz + 1 ! TFrlCDmp Re_BufSz = Re_BufSz + 1 ! TFrlUSSP Re_BufSz = Re_BufSz + 1 ! TFrlDSSP Re_BufSz = Re_BufSz + 1 ! TFrlUSSpr @@ -4957,96 +4228,6 @@ SUBROUTINE ED_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ReKiBuf(Re_Xferred) = InData%TwSSM2Sh(i1) Re_Xferred = Re_Xferred + 1 END DO - END IF - IF ( .NOT. ALLOCATED(InData%TwGJStif) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwGJStif,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwGJStif,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TwGJStif,1), UBOUND(InData%TwGJStif,1) - ReKiBuf(Re_Xferred) = InData%TwGJStif(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%TwEAStif) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwEAStif,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwEAStif,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TwEAStif,1), UBOUND(InData%TwEAStif,1) - ReKiBuf(Re_Xferred) = InData%TwEAStif(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%TwFAIner) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwFAIner,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwFAIner,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TwFAIner,1), UBOUND(InData%TwFAIner,1) - ReKiBuf(Re_Xferred) = InData%TwFAIner(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%TwSSIner) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwSSIner,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwSSIner,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TwSSIner,1), UBOUND(InData%TwSSIner,1) - ReKiBuf(Re_Xferred) = InData%TwSSIner(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%TwFAcgOf) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwFAcgOf,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwFAcgOf,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TwFAcgOf,1), UBOUND(InData%TwFAcgOf,1) - ReKiBuf(Re_Xferred) = InData%TwFAcgOf(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%TwSScgOf) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TwSScgOf,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TwSScgOf,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TwSScgOf,1), UBOUND(InData%TwSScgOf,1) - ReKiBuf(Re_Xferred) = InData%TwSScgOf(i1) - Re_Xferred = Re_Xferred + 1 - END DO END IF IntKiBuf(Int_Xferred) = TRANSFER(InData%RFrlDOF, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 @@ -5060,52 +4241,30 @@ SUBROUTINE ED_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%ShftSkew Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RFrlCMxn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RFrlCMyn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RFrlCMzn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%BoomCMxn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%BoomCMyn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%BoomCMzn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFinCMxn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFinCMyn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFinCMzn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFinCPxn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFinCPyn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFinCPzn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFinSkew - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFinTilt - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFinBank - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RFrlPntxn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RFrlPntyn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RFrlPntzn - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%RFrlCM_n,1), UBOUND(InData%RFrlCM_n,1) + ReKiBuf(Re_Xferred) = InData%RFrlCM_n(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%BoomCM_n,1), UBOUND(InData%BoomCM_n,1) + ReKiBuf(Re_Xferred) = InData%BoomCM_n(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%TFinCM_n,1), UBOUND(InData%TFinCM_n,1) + ReKiBuf(Re_Xferred) = InData%TFinCM_n(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%RFrlPnt_n,1), UBOUND(InData%RFrlPnt_n,1) + ReKiBuf(Re_Xferred) = InData%RFrlPnt_n(i1) + Re_Xferred = Re_Xferred + 1 + END DO ReKiBuf(Re_Xferred) = InData%RFrlSkew Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%RFrlTilt Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFrlPntxn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFrlPntyn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFrlPntzn - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%TFrlPnt_n,1), UBOUND(InData%TFrlPnt_n,1) + ReKiBuf(Re_Xferred) = InData%TFrlPnt_n(i1) + Re_Xferred = Re_Xferred + 1 + END DO ReKiBuf(Re_Xferred) = InData%TFrlSkew Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%TFrlTilt @@ -5126,8 +4285,6 @@ SUBROUTINE ED_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%RFrlDmp Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RFrlCDmp - Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%RFrlUSSP Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%RFrlDSSP @@ -5150,8 +4307,6 @@ SUBROUTINE ED_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%TFrlDmp Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFrlCDmp - Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%TFrlUSSP Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%TFrlDSSP @@ -5744,139 +4899,31 @@ SUBROUTINE ED_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 IF (ALLOCATED(OutData%TwSSM1Sh)) DEALLOCATE(OutData%TwSSM1Sh) - ALLOCATE(OutData%TwSSM1Sh(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwSSM1Sh.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%TwSSM1Sh,1), UBOUND(OutData%TwSSM1Sh,1) - OutData%TwSSM1Sh(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwSSM2Sh not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwSSM2Sh)) DEALLOCATE(OutData%TwSSM2Sh) - ALLOCATE(OutData%TwSSM2Sh(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwSSM2Sh.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%TwSSM2Sh,1), UBOUND(OutData%TwSSM2Sh,1) - OutData%TwSSM2Sh(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwGJStif not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwGJStif)) DEALLOCATE(OutData%TwGJStif) - ALLOCATE(OutData%TwGJStif(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwGJStif.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%TwGJStif,1), UBOUND(OutData%TwGJStif,1) - OutData%TwGJStif(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwEAStif not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwEAStif)) DEALLOCATE(OutData%TwEAStif) - ALLOCATE(OutData%TwEAStif(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwEAStif.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%TwEAStif,1), UBOUND(OutData%TwEAStif,1) - OutData%TwEAStif(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwFAIner not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwFAIner)) DEALLOCATE(OutData%TwFAIner) - ALLOCATE(OutData%TwFAIner(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwFAIner.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%TwFAIner,1), UBOUND(OutData%TwFAIner,1) - OutData%TwFAIner(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwSSIner not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwSSIner)) DEALLOCATE(OutData%TwSSIner) - ALLOCATE(OutData%TwSSIner(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwSSIner.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%TwSSIner,1), UBOUND(OutData%TwSSIner,1) - OutData%TwSSIner(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwFAcgOf not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwFAcgOf)) DEALLOCATE(OutData%TwFAcgOf) - ALLOCATE(OutData%TwFAcgOf(i1_l:i1_u),STAT=ErrStat2) + ALLOCATE(OutData%TwSSM1Sh(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwFAcgOf.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwSSM1Sh.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%TwFAcgOf,1), UBOUND(OutData%TwFAcgOf,1) - OutData%TwFAcgOf(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%TwSSM1Sh,1), UBOUND(OutData%TwSSM1Sh,1) + OutData%TwSSM1Sh(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwSScgOf not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TwSSM2Sh not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TwSScgOf)) DEALLOCATE(OutData%TwSScgOf) - ALLOCATE(OutData%TwSScgOf(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%TwSSM2Sh)) DEALLOCATE(OutData%TwSSM2Sh) + ALLOCATE(OutData%TwSSM2Sh(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwSScgOf.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TwSSM2Sh.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%TwSScgOf,1), UBOUND(OutData%TwSScgOf,1) - OutData%TwSScgOf(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%TwSSM2Sh,1), UBOUND(OutData%TwSSM2Sh,1) + OutData%TwSSM2Sh(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -5892,52 +4939,40 @@ SUBROUTINE ED_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = Re_Xferred + 1 OutData%ShftSkew = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%RFrlCMxn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RFrlCMyn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RFrlCMzn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%BoomCMxn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%BoomCMyn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%BoomCMzn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TFinCMxn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TFinCMyn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TFinCMzn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TFinCPxn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TFinCPyn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TFinCPzn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TFinSkew = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TFinTilt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TFinBank = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RFrlPntxn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RFrlPntyn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RFrlPntzn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%RFrlCM_n,1) + i1_u = UBOUND(OutData%RFrlCM_n,1) + DO i1 = LBOUND(OutData%RFrlCM_n,1), UBOUND(OutData%RFrlCM_n,1) + OutData%RFrlCM_n(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%BoomCM_n,1) + i1_u = UBOUND(OutData%BoomCM_n,1) + DO i1 = LBOUND(OutData%BoomCM_n,1), UBOUND(OutData%BoomCM_n,1) + OutData%BoomCM_n(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%TFinCM_n,1) + i1_u = UBOUND(OutData%TFinCM_n,1) + DO i1 = LBOUND(OutData%TFinCM_n,1), UBOUND(OutData%TFinCM_n,1) + OutData%TFinCM_n(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%RFrlPnt_n,1) + i1_u = UBOUND(OutData%RFrlPnt_n,1) + DO i1 = LBOUND(OutData%RFrlPnt_n,1), UBOUND(OutData%RFrlPnt_n,1) + OutData%RFrlPnt_n(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO OutData%RFrlSkew = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%RFrlTilt = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%TFrlPntxn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TFrlPntyn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TFrlPntzn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%TFrlPnt_n,1) + i1_u = UBOUND(OutData%TFrlPnt_n,1) + DO i1 = LBOUND(OutData%TFrlPnt_n,1), UBOUND(OutData%TFrlPnt_n,1) + OutData%TFrlPnt_n(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO OutData%TFrlSkew = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%TFrlTilt = ReKiBuf(Re_Xferred) @@ -5958,8 +4993,6 @@ SUBROUTINE ED_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = Re_Xferred + 1 OutData%RFrlDmp = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%RFrlCDmp = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 OutData%RFrlUSSP = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%RFrlDSSP = ReKiBuf(Re_Xferred) @@ -5982,8 +5015,6 @@ SUBROUTINE ED_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = Re_Xferred + 1 OutData%TFrlDmp = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%TFrlCDmp = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 OutData%TFrlUSSP = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%TFrlDSSP = ReKiBuf(Re_Xferred) @@ -6250,9 +5281,6 @@ SUBROUTINE ED_CopyCoordSys( SrcCoordSysData, DstCoordSysData, CtrlCode, ErrStat, END IF DstCoordSysData%n3 = SrcCoordSysData%n3 ENDIF - DstCoordSysData%p1 = SrcCoordSysData%p1 - DstCoordSysData%p2 = SrcCoordSysData%p2 - DstCoordSysData%p3 = SrcCoordSysData%p3 DstCoordSysData%rf1 = SrcCoordSysData%rf1 DstCoordSysData%rf2 = SrcCoordSysData%rf2 DstCoordSysData%rf3 = SrcCoordSysData%rf3 @@ -6356,15 +5384,27 @@ SUBROUTINE ED_CopyCoordSys( SrcCoordSysData, DstCoordSysData, CtrlCode, ErrStat, DstCoordSysData%z3 = SrcCoordSysData%z3 END SUBROUTINE ED_CopyCoordSys - SUBROUTINE ED_DestroyCoordSys( CoordSysData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyCoordSys( CoordSysData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_CoordSys), INTENT(INOUT) :: CoordSysData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyCoordSys' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyCoordSys' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(CoordSysData%i1)) THEN DEALLOCATE(CoordSysData%i1) ENDIF @@ -6537,9 +5577,6 @@ SUBROUTINE ED_PackCoordSys( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 2*3 ! n3 upper/lower bounds for each dimension Db_BufSz = Db_BufSz + SIZE(InData%n3) ! n3 END IF - Db_BufSz = Db_BufSz + SIZE(InData%p1) ! p1 - Db_BufSz = Db_BufSz + SIZE(InData%p2) ! p2 - Db_BufSz = Db_BufSz + SIZE(InData%p3) ! p3 Db_BufSz = Db_BufSz + SIZE(InData%rf1) ! rf1 Db_BufSz = Db_BufSz + SIZE(InData%rf2) ! rf2 Db_BufSz = Db_BufSz + SIZE(InData%rf3) ! rf3 @@ -6962,18 +5999,6 @@ SUBROUTINE ED_PackCoordSys( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END DO END DO END IF - DO i1 = LBOUND(InData%p1,1), UBOUND(InData%p1,1) - DbKiBuf(Db_Xferred) = InData%p1(i1) - Db_Xferred = Db_Xferred + 1 - END DO - DO i1 = LBOUND(InData%p2,1), UBOUND(InData%p2,1) - DbKiBuf(Db_Xferred) = InData%p2(i1) - Db_Xferred = Db_Xferred + 1 - END DO - DO i1 = LBOUND(InData%p3,1), UBOUND(InData%p3,1) - DbKiBuf(Db_Xferred) = InData%p3(i1) - Db_Xferred = Db_Xferred + 1 - END DO DO i1 = LBOUND(InData%rf1,1), UBOUND(InData%rf1,1) DbKiBuf(Db_Xferred) = InData%rf1(i1) Db_Xferred = Db_Xferred + 1 @@ -7616,24 +6641,6 @@ SUBROUTINE ED_UnPackCoordSys( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM END DO END DO END IF - i1_l = LBOUND(OutData%p1,1) - i1_u = UBOUND(OutData%p1,1) - DO i1 = LBOUND(OutData%p1,1), UBOUND(OutData%p1,1) - OutData%p1(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - END DO - i1_l = LBOUND(OutData%p2,1) - i1_u = UBOUND(OutData%p2,1) - DO i1 = LBOUND(OutData%p2,1), UBOUND(OutData%p2,1) - OutData%p2(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - END DO - i1_l = LBOUND(OutData%p3,1) - i1_u = UBOUND(OutData%p3,1) - DO i1 = LBOUND(OutData%p3,1), UBOUND(OutData%p3,1) - OutData%p3(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - END DO i1_l = LBOUND(OutData%rf1,1) i1_u = UBOUND(OutData%rf1,1) DO i1 = LBOUND(OutData%rf1,1), UBOUND(OutData%rf1,1) @@ -8065,15 +7072,27 @@ SUBROUTINE ED_CopyActiveDOFs( SrcActiveDOFsData, DstActiveDOFsData, CtrlCode, Er ENDIF END SUBROUTINE ED_CopyActiveDOFs - SUBROUTINE ED_DestroyActiveDOFs( ActiveDOFsData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyActiveDOFs( ActiveDOFsData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_ActiveDOFs), INTENT(INOUT) :: ActiveDOFsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyActiveDOFs' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyActiveDOFs' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ActiveDOFsData%NPSBE)) THEN DEALLOCATE(ActiveDOFsData%NPSBE) ENDIF @@ -8961,6 +7980,7 @@ SUBROUTINE ED_CopyRtHndSide( SrcRtHndSideData, DstRtHndSideData, CtrlCode, ErrSt DstRtHndSideData%rPQ = SrcRtHndSideData%rPQ DstRtHndSideData%rP = SrcRtHndSideData%rP DstRtHndSideData%rV = SrcRtHndSideData%rV + DstRtHndSideData%rJ = SrcRtHndSideData%rJ DstRtHndSideData%rZY = SrcRtHndSideData%rZY DstRtHndSideData%rOU = SrcRtHndSideData%rOU DstRtHndSideData%rOV = SrcRtHndSideData%rOV @@ -8987,7 +8007,6 @@ SUBROUTINE ED_CopyRtHndSide( SrcRtHndSideData, DstRtHndSideData, CtrlCode, ErrSt DstRtHndSideData%rVP = SrcRtHndSideData%rVP DstRtHndSideData%rWI = SrcRtHndSideData%rWI DstRtHndSideData%rWJ = SrcRtHndSideData%rWJ - DstRtHndSideData%rWK = SrcRtHndSideData%rWK DstRtHndSideData%rZT0 = SrcRtHndSideData%rZT0 IF (ALLOCATED(SrcRtHndSideData%AngPosEF)) THEN i1_l = LBOUND(SrcRtHndSideData%AngPosEF,1) @@ -9492,22 +8511,6 @@ SUBROUTINE ED_CopyRtHndSide( SrcRtHndSideData, DstRtHndSideData, CtrlCode, ErrSt END IF DstRtHndSideData%PLinVelEJ = SrcRtHndSideData%PLinVelEJ ENDIF -IF (ALLOCATED(SrcRtHndSideData%PLinVelEK)) THEN - i1_l = LBOUND(SrcRtHndSideData%PLinVelEK,1) - i1_u = UBOUND(SrcRtHndSideData%PLinVelEK,1) - i2_l = LBOUND(SrcRtHndSideData%PLinVelEK,2) - i2_u = UBOUND(SrcRtHndSideData%PLinVelEK,2) - i3_l = LBOUND(SrcRtHndSideData%PLinVelEK,3) - i3_u = UBOUND(SrcRtHndSideData%PLinVelEK,3) - IF (.NOT. ALLOCATED(DstRtHndSideData%PLinVelEK)) THEN - ALLOCATE(DstRtHndSideData%PLinVelEK(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRtHndSideData%PLinVelEK.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstRtHndSideData%PLinVelEK = SrcRtHndSideData%PLinVelEK -ENDIF IF (ALLOCATED(SrcRtHndSideData%PLinVelEP)) THEN i1_l = LBOUND(SrcRtHndSideData%PLinVelEP,1) i1_u = UBOUND(SrcRtHndSideData%PLinVelEP,1) @@ -9640,6 +8643,7 @@ SUBROUTINE ED_CopyRtHndSide( SrcRtHndSideData, DstRtHndSideData, CtrlCode, ErrSt DstRtHndSideData%LinVelEIMU = SrcRtHndSideData%LinVelEIMU DstRtHndSideData%LinVelEZ = SrcRtHndSideData%LinVelEZ DstRtHndSideData%LinVelEO = SrcRtHndSideData%LinVelEO + DstRtHndSideData%LinVelEJ = SrcRtHndSideData%LinVelEJ DstRtHndSideData%FrcONcRtt = SrcRtHndSideData%FrcONcRtt DstRtHndSideData%FrcPRott = SrcRtHndSideData%FrcPRott IF (ALLOCATED(SrcRtHndSideData%FrcS0Bt)) THEN @@ -10013,15 +9017,27 @@ SUBROUTINE ED_CopyRtHndSide( SrcRtHndSideData, DstRtHndSideData, CtrlCode, ErrSt ENDIF END SUBROUTINE ED_CopyRtHndSide - SUBROUTINE ED_DestroyRtHndSide( RtHndSideData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyRtHndSide( RtHndSideData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_RtHndSide), INTENT(INOUT) :: RtHndSideData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyRtHndSide' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyRtHndSide' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(RtHndSideData%rQS)) THEN DEALLOCATE(RtHndSideData%rQS) ENDIF @@ -10133,9 +9149,6 @@ SUBROUTINE ED_DestroyRtHndSide( RtHndSideData, ErrStat, ErrMsg ) IF (ALLOCATED(RtHndSideData%PLinVelEJ)) THEN DEALLOCATE(RtHndSideData%PLinVelEJ) ENDIF -IF (ALLOCATED(RtHndSideData%PLinVelEK)) THEN - DEALLOCATE(RtHndSideData%PLinVelEK) -ENDIF IF (ALLOCATED(RtHndSideData%PLinVelEP)) THEN DEALLOCATE(RtHndSideData%PLinVelEP) ENDIF @@ -10306,6 +9319,7 @@ SUBROUTINE ED_PackRtHndSide( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Db_BufSz = Db_BufSz + SIZE(InData%rPQ) ! rPQ Db_BufSz = Db_BufSz + SIZE(InData%rP) ! rP Db_BufSz = Db_BufSz + SIZE(InData%rV) ! rV + Db_BufSz = Db_BufSz + SIZE(InData%rJ) ! rJ Db_BufSz = Db_BufSz + SIZE(InData%rZY) ! rZY Db_BufSz = Db_BufSz + SIZE(InData%rOU) ! rOU Db_BufSz = Db_BufSz + SIZE(InData%rOV) ! rOV @@ -10323,7 +9337,6 @@ SUBROUTINE ED_PackRtHndSide( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Db_BufSz = Db_BufSz + SIZE(InData%rVP) ! rVP Db_BufSz = Db_BufSz + SIZE(InData%rWI) ! rWI Db_BufSz = Db_BufSz + SIZE(InData%rWJ) ! rWJ - Db_BufSz = Db_BufSz + SIZE(InData%rWK) ! rWK Db_BufSz = Db_BufSz + SIZE(InData%rZT0) ! rZT0 Int_BufSz = Int_BufSz + 1 ! AngPosEF allocated yes/no IF ( ALLOCATED(InData%AngPosEF) ) THEN @@ -10500,11 +9513,6 @@ SUBROUTINE ED_PackRtHndSide( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 2*3 ! PLinVelEJ upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%PLinVelEJ) ! PLinVelEJ END IF - Int_BufSz = Int_BufSz + 1 ! PLinVelEK allocated yes/no - IF ( ALLOCATED(InData%PLinVelEK) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! PLinVelEK upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%PLinVelEK) ! PLinVelEK - END IF Int_BufSz = Int_BufSz + 1 ! PLinVelEP allocated yes/no IF ( ALLOCATED(InData%PLinVelEP) ) THEN Int_BufSz = Int_BufSz + 2*3 ! PLinVelEP upper/lower bounds for each dimension @@ -10551,6 +9559,7 @@ SUBROUTINE ED_PackRtHndSide( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_BufSz = Re_BufSz + SIZE(InData%LinVelEIMU) ! LinVelEIMU Re_BufSz = Re_BufSz + SIZE(InData%LinVelEZ) ! LinVelEZ Re_BufSz = Re_BufSz + SIZE(InData%LinVelEO) ! LinVelEO + Re_BufSz = Re_BufSz + SIZE(InData%LinVelEJ) ! LinVelEJ Re_BufSz = Re_BufSz + SIZE(InData%FrcONcRtt) ! FrcONcRtt Re_BufSz = Re_BufSz + SIZE(InData%FrcPRott) ! FrcPRott Int_BufSz = Int_BufSz + 1 ! FrcS0Bt allocated yes/no @@ -10882,6 +9891,10 @@ SUBROUTINE ED_PackRtHndSide( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg DbKiBuf(Db_Xferred) = InData%rV(i1) Db_Xferred = Db_Xferred + 1 END DO + DO i1 = LBOUND(InData%rJ,1), UBOUND(InData%rJ,1) + DbKiBuf(Db_Xferred) = InData%rJ(i1) + Db_Xferred = Db_Xferred + 1 + END DO DO i1 = LBOUND(InData%rZY,1), UBOUND(InData%rZY,1) DbKiBuf(Db_Xferred) = InData%rZY(i1) Db_Xferred = Db_Xferred + 1 @@ -10950,10 +9963,6 @@ SUBROUTINE ED_PackRtHndSide( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg DbKiBuf(Db_Xferred) = InData%rWJ(i1) Db_Xferred = Db_Xferred + 1 END DO - DO i1 = LBOUND(InData%rWK,1), UBOUND(InData%rWK,1) - DbKiBuf(Db_Xferred) = InData%rWK(i1) - Db_Xferred = Db_Xferred + 1 - END DO DO i1 = LBOUND(InData%rZT0,1), UBOUND(InData%rZT0,1) DbKiBuf(Db_Xferred) = InData%rZT0(i1) Db_Xferred = Db_Xferred + 1 @@ -11801,31 +10810,6 @@ SUBROUTINE ED_PackRtHndSide( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%PLinVelEK) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PLinVelEK,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PLinVelEK,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PLinVelEK,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PLinVelEK,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PLinVelEK,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PLinVelEK,3) - Int_Xferred = Int_Xferred + 2 - - DO i3 = LBOUND(InData%PLinVelEK,3), UBOUND(InData%PLinVelEK,3) - DO i2 = LBOUND(InData%PLinVelEK,2), UBOUND(InData%PLinVelEK,2) - DO i1 = LBOUND(InData%PLinVelEK,1), UBOUND(InData%PLinVelEK,1) - ReKiBuf(Re_Xferred) = InData%PLinVelEK(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF IF ( .NOT. ALLOCATED(InData%PLinVelEP) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -12045,6 +11029,10 @@ SUBROUTINE ED_PackRtHndSide( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ReKiBuf(Re_Xferred) = InData%LinVelEO(i1) Re_Xferred = Re_Xferred + 1 END DO + DO i1 = LBOUND(InData%LinVelEJ,1), UBOUND(InData%LinVelEJ,1) + ReKiBuf(Re_Xferred) = InData%LinVelEJ(i1) + Re_Xferred = Re_Xferred + 1 + END DO DO i1 = LBOUND(InData%FrcONcRtt,1), UBOUND(InData%FrcONcRtt,1) ReKiBuf(Re_Xferred) = InData%FrcONcRtt(i1) Re_Xferred = Re_Xferred + 1 @@ -12866,6 +11854,12 @@ SUBROUTINE ED_UnPackRtHndSide( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err OutData%rV(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) Db_Xferred = Db_Xferred + 1 END DO + i1_l = LBOUND(OutData%rJ,1) + i1_u = UBOUND(OutData%rJ,1) + DO i1 = LBOUND(OutData%rJ,1), UBOUND(OutData%rJ,1) + OutData%rJ(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 + END DO i1_l = LBOUND(OutData%rZY,1) i1_u = UBOUND(OutData%rZY,1) DO i1 = LBOUND(OutData%rZY,1), UBOUND(OutData%rZY,1) @@ -12961,12 +11955,6 @@ SUBROUTINE ED_UnPackRtHndSide( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err OutData%rWJ(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) Db_Xferred = Db_Xferred + 1 END DO - i1_l = LBOUND(OutData%rWK,1) - i1_u = UBOUND(OutData%rWK,1) - DO i1 = LBOUND(OutData%rWK,1), UBOUND(OutData%rWK,1) - OutData%rWK(i1) = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - END DO i1_l = LBOUND(OutData%rZT0,1) i1_u = UBOUND(OutData%rZT0,1) DO i1 = LBOUND(OutData%rZT0,1), UBOUND(OutData%rZT0,1) @@ -13954,34 +12942,6 @@ SUBROUTINE ED_UnPackRtHndSide( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PLinVelEK not allocated - Int_Xferred = Int_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%PLinVelEK)) DEALLOCATE(OutData%PLinVelEK) - ALLOCATE(OutData%PLinVelEK(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%PLinVelEK.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i3 = LBOUND(OutData%PLinVelEK,3), UBOUND(OutData%PLinVelEK,3) - DO i2 = LBOUND(OutData%PLinVelEK,2), UBOUND(OutData%PLinVelEK,2) - DO i1 = LBOUND(OutData%PLinVelEK,1), UBOUND(OutData%PLinVelEK,1) - OutData%PLinVelEK(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 ! PLinVelEP not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -14237,6 +13197,12 @@ SUBROUTINE ED_UnPackRtHndSide( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err OutData%LinVelEO(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO + i1_l = LBOUND(OutData%LinVelEJ,1) + i1_u = UBOUND(OutData%LinVelEJ,1) + DO i1 = LBOUND(OutData%LinVelEJ,1), UBOUND(OutData%LinVelEJ,1) + OutData%LinVelEJ(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO i1_l = LBOUND(OutData%FrcONcRtt,1) i1_u = UBOUND(OutData%FrcONcRtt,1) DO i1 = LBOUND(OutData%FrcONcRtt,1), UBOUND(OutData%FrcONcRtt,1) @@ -14981,15 +13947,27 @@ SUBROUTINE ED_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrSt ENDIF END SUBROUTINE ED_CopyContState - SUBROUTINE ED_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%QT)) THEN DEALLOCATE(ContStateData%QT) ENDIF @@ -15184,15 +14162,27 @@ SUBROUTINE ED_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE ED_CopyDiscState - SUBROUTINE ED_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE ED_DestroyDiscState SUBROUTINE ED_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -15309,15 +14299,27 @@ SUBROUTINE ED_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE ED_CopyConstrState - SUBROUTINE ED_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE ED_DestroyConstrState SUBROUTINE ED_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -15456,17 +14458,30 @@ SUBROUTINE ED_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, Er DstOtherStateData%SgnLSTQ = SrcOtherStateData%SgnLSTQ END SUBROUTINE ED_CopyOtherState - SUBROUTINE ED_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(OtherStateData%xdot,1), UBOUND(OtherStateData%xdot,1) - CALL ED_DestroyContState( OtherStateData%xdot(i1), ErrStat, ErrMsg ) + CALL ED_DestroyContState( OtherStateData%xdot(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO IF (ALLOCATED(OtherStateData%IC)) THEN DEALLOCATE(OtherStateData%IC) @@ -15842,17 +14857,31 @@ SUBROUTINE ED_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%IgnoreMod = SrcMiscData%IgnoreMod END SUBROUTINE ED_CopyMisc - SUBROUTINE ED_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" - CALL ED_Destroycoordsys( MiscData%CoordSys, ErrStat, ErrMsg ) - CALL ED_Destroyrthndside( MiscData%RtHS, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL ED_Destroycoordsys( MiscData%CoordSys, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ED_Destroyrthndside( MiscData%RtHS, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MiscData%AllOuts)) THEN DEALLOCATE(MiscData%AllOuts) ENDIF @@ -16559,9 +15588,6 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) DstParamData%CSRFrlTlt = SrcParamData%CSRFrlTlt DstParamData%CSTFrlSkw = SrcParamData%CSTFrlSkw DstParamData%CSTFrlTlt = SrcParamData%CSTFrlTlt - DstParamData%CTFinBank = SrcParamData%CTFinBank - DstParamData%CTFinSkew = SrcParamData%CTFinSkew - DstParamData%CTFinTilt = SrcParamData%CTFinTilt DstParamData%CTFrlSkew = SrcParamData%CTFrlSkew DstParamData%CTFrlSkw2 = SrcParamData%CTFrlSkw2 DstParamData%CTFrlTilt = SrcParamData%CTFrlTilt @@ -16576,9 +15602,7 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) DstParamData%ProjArea = SrcParamData%ProjArea DstParamData%PtfmRefzt = SrcParamData%PtfmRefzt DstParamData%RefTwrHt = SrcParamData%RefTwrHt - DstParamData%RFrlPntxn = SrcParamData%RFrlPntxn - DstParamData%RFrlPntyn = SrcParamData%RFrlPntyn - DstParamData%RFrlPntzn = SrcParamData%RFrlPntzn + DstParamData%RFrlPnt_n = SrcParamData%RFrlPnt_n DstParamData%rVDxn = SrcParamData%rVDxn DstParamData%rVDyn = SrcParamData%rVDyn DstParamData%rVDzn = SrcParamData%rVDzn @@ -16594,9 +15618,6 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) DstParamData%rWJxn = SrcParamData%rWJxn DstParamData%rWJyn = SrcParamData%rWJyn DstParamData%rWJzn = SrcParamData%rWJzn - DstParamData%rWKxn = SrcParamData%rWKxn - DstParamData%rWKyn = SrcParamData%rWKyn - DstParamData%rWKzn = SrcParamData%rWKzn DstParamData%rZT0zt = SrcParamData%rZT0zt DstParamData%rZYzt = SrcParamData%rZYzt DstParamData%SinDel3 = SrcParamData%SinDel3 @@ -16618,16 +15639,11 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) DstParamData%SRFrlTlt2 = SrcParamData%SRFrlTlt2 DstParamData%SShftSkew = SrcParamData%SShftSkew DstParamData%SShftTilt = SrcParamData%SShftTilt - DstParamData%STFinBank = SrcParamData%STFinBank - DstParamData%STFinSkew = SrcParamData%STFinSkew - DstParamData%STFinTilt = SrcParamData%STFinTilt DstParamData%STFrlSkew = SrcParamData%STFrlSkew DstParamData%STFrlSkw2 = SrcParamData%STFrlSkw2 DstParamData%STFrlTilt = SrcParamData%STFrlTilt DstParamData%STFrlTlt2 = SrcParamData%STFrlTlt2 - DstParamData%TFrlPntxn = SrcParamData%TFrlPntxn - DstParamData%TFrlPntyn = SrcParamData%TFrlPntyn - DstParamData%TFrlPntzn = SrcParamData%TFrlPntzn + DstParamData%TFrlPnt_n = SrcParamData%TFrlPnt_n DstParamData%TipRad = SrcParamData%TipRad DstParamData%TowerHt = SrcParamData%TowerHt DstParamData%TowerBsHt = SrcParamData%TowerBsHt @@ -16764,54 +15780,7 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) ENDIF DstParamData%TTopNode = SrcParamData%TTopNode DstParamData%TwrNodes = SrcParamData%TwrNodes -IF (ALLOCATED(SrcParamData%InerTFA)) THEN - i1_l = LBOUND(SrcParamData%InerTFA,1) - i1_u = UBOUND(SrcParamData%InerTFA,1) - IF (.NOT. ALLOCATED(DstParamData%InerTFA)) THEN - ALLOCATE(DstParamData%InerTFA(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%InerTFA.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%InerTFA = SrcParamData%InerTFA -ENDIF -IF (ALLOCATED(SrcParamData%InerTSS)) THEN - i1_l = LBOUND(SrcParamData%InerTSS,1) - i1_u = UBOUND(SrcParamData%InerTSS,1) - IF (.NOT. ALLOCATED(DstParamData%InerTSS)) THEN - ALLOCATE(DstParamData%InerTSS(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%InerTSS.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%InerTSS = SrcParamData%InerTSS -ENDIF -IF (ALLOCATED(SrcParamData%StiffTGJ)) THEN - i1_l = LBOUND(SrcParamData%StiffTGJ,1) - i1_u = UBOUND(SrcParamData%StiffTGJ,1) - IF (.NOT. ALLOCATED(DstParamData%StiffTGJ)) THEN - ALLOCATE(DstParamData%StiffTGJ(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%StiffTGJ.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%StiffTGJ = SrcParamData%StiffTGJ -ENDIF -IF (ALLOCATED(SrcParamData%StiffTEA)) THEN - i1_l = LBOUND(SrcParamData%StiffTEA,1) - i1_u = UBOUND(SrcParamData%StiffTEA,1) - IF (.NOT. ALLOCATED(DstParamData%StiffTEA)) THEN - ALLOCATE(DstParamData%StiffTEA(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%StiffTEA.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%StiffTEA = SrcParamData%StiffTEA -ENDIF + DstParamData%MHK = SrcParamData%MHK IF (ALLOCATED(SrcParamData%StiffTFA)) THEN i1_l = LBOUND(SrcParamData%StiffTFA,1) i1_u = UBOUND(SrcParamData%StiffTFA,1) @@ -16823,30 +15792,6 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF END IF DstParamData%StiffTFA = SrcParamData%StiffTFA -ENDIF -IF (ALLOCATED(SrcParamData%cgOffTFA)) THEN - i1_l = LBOUND(SrcParamData%cgOffTFA,1) - i1_u = UBOUND(SrcParamData%cgOffTFA,1) - IF (.NOT. ALLOCATED(DstParamData%cgOffTFA)) THEN - ALLOCATE(DstParamData%cgOffTFA(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%cgOffTFA.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%cgOffTFA = SrcParamData%cgOffTFA -ENDIF -IF (ALLOCATED(SrcParamData%cgOffTSS)) THEN - i1_l = LBOUND(SrcParamData%cgOffTSS,1) - i1_u = UBOUND(SrcParamData%cgOffTSS,1) - IF (.NOT. ALLOCATED(DstParamData%cgOffTSS)) THEN - ALLOCATE(DstParamData%cgOffTSS(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%cgOffTSS.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%cgOffTSS = SrcParamData%cgOffTSS ENDIF DstParamData%AtfaIner = SrcParamData%AtfaIner IF (ALLOCATED(SrcParamData%BldCG)) THEN @@ -16975,20 +15920,6 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%AxRedBld = SrcParamData%AxRedBld ENDIF -IF (ALLOCATED(SrcParamData%BAlpha)) THEN - i1_l = LBOUND(SrcParamData%BAlpha,1) - i1_u = UBOUND(SrcParamData%BAlpha,1) - i2_l = LBOUND(SrcParamData%BAlpha,2) - i2_u = UBOUND(SrcParamData%BAlpha,2) - IF (.NOT. ALLOCATED(DstParamData%BAlpha)) THEN - ALLOCATE(DstParamData%BAlpha(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%BAlpha.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%BAlpha = SrcParamData%BAlpha -ENDIF IF (ALLOCATED(SrcParamData%BldEDamp)) THEN i1_l = LBOUND(SrcParamData%BldEDamp,1) i1_u = UBOUND(SrcParamData%BldEDamp,1) @@ -17062,34 +15993,6 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%CBF = SrcParamData%CBF ENDIF -IF (ALLOCATED(SrcParamData%cgOffBEdg)) THEN - i1_l = LBOUND(SrcParamData%cgOffBEdg,1) - i1_u = UBOUND(SrcParamData%cgOffBEdg,1) - i2_l = LBOUND(SrcParamData%cgOffBEdg,2) - i2_u = UBOUND(SrcParamData%cgOffBEdg,2) - IF (.NOT. ALLOCATED(DstParamData%cgOffBEdg)) THEN - ALLOCATE(DstParamData%cgOffBEdg(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%cgOffBEdg.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%cgOffBEdg = SrcParamData%cgOffBEdg -ENDIF -IF (ALLOCATED(SrcParamData%cgOffBFlp)) THEN - i1_l = LBOUND(SrcParamData%cgOffBFlp,1) - i1_u = UBOUND(SrcParamData%cgOffBFlp,1) - i2_l = LBOUND(SrcParamData%cgOffBFlp,2) - i2_u = UBOUND(SrcParamData%cgOffBFlp,2) - IF (.NOT. ALLOCATED(DstParamData%cgOffBFlp)) THEN - ALLOCATE(DstParamData%cgOffBFlp(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%cgOffBFlp.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%cgOffBFlp = SrcParamData%cgOffBFlp -ENDIF IF (ALLOCATED(SrcParamData%Chord)) THEN i1_l = LBOUND(SrcParamData%Chord,1) i1_u = UBOUND(SrcParamData%Chord,1) @@ -17128,34 +16031,6 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%DRNodes = SrcParamData%DRNodes ENDIF -IF (ALLOCATED(SrcParamData%EAOffBEdg)) THEN - i1_l = LBOUND(SrcParamData%EAOffBEdg,1) - i1_u = UBOUND(SrcParamData%EAOffBEdg,1) - i2_l = LBOUND(SrcParamData%EAOffBEdg,2) - i2_u = UBOUND(SrcParamData%EAOffBEdg,2) - IF (.NOT. ALLOCATED(DstParamData%EAOffBEdg)) THEN - ALLOCATE(DstParamData%EAOffBEdg(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%EAOffBEdg.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%EAOffBEdg = SrcParamData%EAOffBEdg -ENDIF -IF (ALLOCATED(SrcParamData%EAOffBFlp)) THEN - i1_l = LBOUND(SrcParamData%EAOffBFlp,1) - i1_u = UBOUND(SrcParamData%EAOffBFlp,1) - i2_l = LBOUND(SrcParamData%EAOffBFlp,2) - i2_u = UBOUND(SrcParamData%EAOffBFlp,2) - IF (.NOT. ALLOCATED(DstParamData%EAOffBFlp)) THEN - ALLOCATE(DstParamData%EAOffBFlp(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%EAOffBFlp.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%EAOffBFlp = SrcParamData%EAOffBFlp -ENDIF IF (ALLOCATED(SrcParamData%FStTunr)) THEN i1_l = LBOUND(SrcParamData%FStTunr,1) i1_u = UBOUND(SrcParamData%FStTunr,1) @@ -17170,34 +16045,6 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%FStTunr = SrcParamData%FStTunr ENDIF -IF (ALLOCATED(SrcParamData%InerBEdg)) THEN - i1_l = LBOUND(SrcParamData%InerBEdg,1) - i1_u = UBOUND(SrcParamData%InerBEdg,1) - i2_l = LBOUND(SrcParamData%InerBEdg,2) - i2_u = UBOUND(SrcParamData%InerBEdg,2) - IF (.NOT. ALLOCATED(DstParamData%InerBEdg)) THEN - ALLOCATE(DstParamData%InerBEdg(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%InerBEdg.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%InerBEdg = SrcParamData%InerBEdg -ENDIF -IF (ALLOCATED(SrcParamData%InerBFlp)) THEN - i1_l = LBOUND(SrcParamData%InerBFlp,1) - i1_u = UBOUND(SrcParamData%InerBFlp,1) - i2_l = LBOUND(SrcParamData%InerBFlp,2) - i2_u = UBOUND(SrcParamData%InerBFlp,2) - IF (.NOT. ALLOCATED(DstParamData%InerBFlp)) THEN - ALLOCATE(DstParamData%InerBFlp(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%InerBFlp.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%InerBFlp = SrcParamData%InerBFlp -ENDIF IF (ALLOCATED(SrcParamData%KBE)) THEN i1_l = LBOUND(SrcParamData%KBE,1) i1_u = UBOUND(SrcParamData%KBE,1) @@ -17238,39 +16085,11 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) IF (.NOT. ALLOCATED(DstParamData%MassB)) THEN ALLOCATE(DstParamData%MassB(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%MassB.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%MassB = SrcParamData%MassB -ENDIF -IF (ALLOCATED(SrcParamData%RefAxisxb)) THEN - i1_l = LBOUND(SrcParamData%RefAxisxb,1) - i1_u = UBOUND(SrcParamData%RefAxisxb,1) - i2_l = LBOUND(SrcParamData%RefAxisxb,2) - i2_u = UBOUND(SrcParamData%RefAxisxb,2) - IF (.NOT. ALLOCATED(DstParamData%RefAxisxb)) THEN - ALLOCATE(DstParamData%RefAxisxb(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%RefAxisxb.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%RefAxisxb = SrcParamData%RefAxisxb -ENDIF -IF (ALLOCATED(SrcParamData%RefAxisyb)) THEN - i1_l = LBOUND(SrcParamData%RefAxisyb,1) - i1_u = UBOUND(SrcParamData%RefAxisyb,1) - i2_l = LBOUND(SrcParamData%RefAxisyb,2) - i2_u = UBOUND(SrcParamData%RefAxisyb,2) - IF (.NOT. ALLOCATED(DstParamData%RefAxisyb)) THEN - ALLOCATE(DstParamData%RefAxisyb(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%RefAxisyb.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%MassB.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%RefAxisyb = SrcParamData%RefAxisyb + DstParamData%MassB = SrcParamData%MassB ENDIF IF (ALLOCATED(SrcParamData%RNodes)) THEN i1_l = LBOUND(SrcParamData%RNodes,1) @@ -17350,20 +16169,6 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%StiffBE = SrcParamData%StiffBE ENDIF -IF (ALLOCATED(SrcParamData%StiffBEA)) THEN - i1_l = LBOUND(SrcParamData%StiffBEA,1) - i1_u = UBOUND(SrcParamData%StiffBEA,1) - i2_l = LBOUND(SrcParamData%StiffBEA,2) - i2_u = UBOUND(SrcParamData%StiffBEA,2) - IF (.NOT. ALLOCATED(DstParamData%StiffBEA)) THEN - ALLOCATE(DstParamData%StiffBEA(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%StiffBEA.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%StiffBEA = SrcParamData%StiffBEA -ENDIF IF (ALLOCATED(SrcParamData%StiffBF)) THEN i1_l = LBOUND(SrcParamData%StiffBF,1) i1_u = UBOUND(SrcParamData%StiffBF,1) @@ -17378,20 +16183,6 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%StiffBF = SrcParamData%StiffBF ENDIF -IF (ALLOCATED(SrcParamData%StiffBGJ)) THEN - i1_l = LBOUND(SrcParamData%StiffBGJ,1) - i1_u = UBOUND(SrcParamData%StiffBGJ,1) - i2_l = LBOUND(SrcParamData%StiffBGJ,2) - i2_u = UBOUND(SrcParamData%StiffBGJ,2) - IF (.NOT. ALLOCATED(DstParamData%StiffBGJ)) THEN - ALLOCATE(DstParamData%StiffBGJ(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%StiffBGJ.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%StiffBGJ = SrcParamData%StiffBGJ -ENDIF IF (ALLOCATED(SrcParamData%SThetaS)) THEN i1_l = LBOUND(SrcParamData%SThetaS,1) i1_u = UBOUND(SrcParamData%SThetaS,1) @@ -17524,7 +16315,6 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) DstParamData%TeetSSSp = SrcParamData%TeetSSSp DstParamData%TeetSStP = SrcParamData%TeetSStP DstParamData%TeetMod = SrcParamData%TeetMod - DstParamData%TFrlCDmp = SrcParamData%TFrlCDmp DstParamData%TFrlDmp = SrcParamData%TFrlDmp DstParamData%TFrlDSDmp = SrcParamData%TFrlDSDmp DstParamData%TFrlDSDP = SrcParamData%TFrlDSDP @@ -17536,7 +16326,6 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) DstParamData%TFrlUSSP = SrcParamData%TFrlUSSP DstParamData%TFrlUSSpr = SrcParamData%TFrlUSSpr DstParamData%TFrlMod = SrcParamData%TFrlMod - DstParamData%RFrlCDmp = SrcParamData%RFrlCDmp DstParamData%RFrlDmp = SrcParamData%RFrlDmp DstParamData%RFrlDSDmp = SrcParamData%RFrlDSDmp DstParamData%RFrlDSDP = SrcParamData%RFrlDSDP @@ -17649,15 +16438,27 @@ SUBROUTINE ED_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) DstParamData%Jac_ny = SrcParamData%Jac_ny END SUBROUTINE ED_CopyParam - SUBROUTINE ED_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%PH)) THEN DEALLOCATE(ParamData%PH) ENDIF @@ -17670,10 +16471,12 @@ SUBROUTINE ED_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%DOF_Desc)) THEN DEALLOCATE(ParamData%DOF_Desc) ENDIF - CALL ED_Destroyactivedofs( ParamData%DOFs, ErrStat, ErrMsg ) + CALL ED_Destroyactivedofs( ParamData%DOFs, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ParamData%OutParam)) THEN DO i1 = LBOUND(ParamData%OutParam,1), UBOUND(ParamData%OutParam,1) - CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF @@ -17710,27 +16513,9 @@ SUBROUTINE ED_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%TwrSSSF)) THEN DEALLOCATE(ParamData%TwrSSSF) ENDIF -IF (ALLOCATED(ParamData%InerTFA)) THEN - DEALLOCATE(ParamData%InerTFA) -ENDIF -IF (ALLOCATED(ParamData%InerTSS)) THEN - DEALLOCATE(ParamData%InerTSS) -ENDIF -IF (ALLOCATED(ParamData%StiffTGJ)) THEN - DEALLOCATE(ParamData%StiffTGJ) -ENDIF -IF (ALLOCATED(ParamData%StiffTEA)) THEN - DEALLOCATE(ParamData%StiffTEA) -ENDIF IF (ALLOCATED(ParamData%StiffTFA)) THEN DEALLOCATE(ParamData%StiffTFA) ENDIF -IF (ALLOCATED(ParamData%cgOffTFA)) THEN - DEALLOCATE(ParamData%cgOffTFA) -ENDIF -IF (ALLOCATED(ParamData%cgOffTSS)) THEN - DEALLOCATE(ParamData%cgOffTSS) -ENDIF IF (ALLOCATED(ParamData%BldCG)) THEN DEALLOCATE(ParamData%BldCG) ENDIF @@ -17755,9 +16540,6 @@ SUBROUTINE ED_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%AxRedBld)) THEN DEALLOCATE(ParamData%AxRedBld) ENDIF -IF (ALLOCATED(ParamData%BAlpha)) THEN - DEALLOCATE(ParamData%BAlpha) -ENDIF IF (ALLOCATED(ParamData%BldEDamp)) THEN DEALLOCATE(ParamData%BldEDamp) ENDIF @@ -17773,12 +16555,6 @@ SUBROUTINE ED_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%CBF)) THEN DEALLOCATE(ParamData%CBF) ENDIF -IF (ALLOCATED(ParamData%cgOffBEdg)) THEN - DEALLOCATE(ParamData%cgOffBEdg) -ENDIF -IF (ALLOCATED(ParamData%cgOffBFlp)) THEN - DEALLOCATE(ParamData%cgOffBFlp) -ENDIF IF (ALLOCATED(ParamData%Chord)) THEN DEALLOCATE(ParamData%Chord) ENDIF @@ -17788,21 +16564,9 @@ SUBROUTINE ED_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%DRNodes)) THEN DEALLOCATE(ParamData%DRNodes) ENDIF -IF (ALLOCATED(ParamData%EAOffBEdg)) THEN - DEALLOCATE(ParamData%EAOffBEdg) -ENDIF -IF (ALLOCATED(ParamData%EAOffBFlp)) THEN - DEALLOCATE(ParamData%EAOffBFlp) -ENDIF IF (ALLOCATED(ParamData%FStTunr)) THEN DEALLOCATE(ParamData%FStTunr) ENDIF -IF (ALLOCATED(ParamData%InerBEdg)) THEN - DEALLOCATE(ParamData%InerBEdg) -ENDIF -IF (ALLOCATED(ParamData%InerBFlp)) THEN - DEALLOCATE(ParamData%InerBFlp) -ENDIF IF (ALLOCATED(ParamData%KBE)) THEN DEALLOCATE(ParamData%KBE) ENDIF @@ -17812,12 +16576,6 @@ SUBROUTINE ED_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%MassB)) THEN DEALLOCATE(ParamData%MassB) ENDIF -IF (ALLOCATED(ParamData%RefAxisxb)) THEN - DEALLOCATE(ParamData%RefAxisxb) -ENDIF -IF (ALLOCATED(ParamData%RefAxisyb)) THEN - DEALLOCATE(ParamData%RefAxisyb) -ENDIF IF (ALLOCATED(ParamData%RNodes)) THEN DEALLOCATE(ParamData%RNodes) ENDIF @@ -17836,15 +16594,9 @@ SUBROUTINE ED_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%StiffBE)) THEN DEALLOCATE(ParamData%StiffBE) ENDIF -IF (ALLOCATED(ParamData%StiffBEA)) THEN - DEALLOCATE(ParamData%StiffBEA) -ENDIF IF (ALLOCATED(ParamData%StiffBF)) THEN DEALLOCATE(ParamData%StiffBF) ENDIF -IF (ALLOCATED(ParamData%StiffBGJ)) THEN - DEALLOCATE(ParamData%StiffBGJ) -ENDIF IF (ALLOCATED(ParamData%SThetaS)) THEN DEALLOCATE(ParamData%SThetaS) ENDIF @@ -17877,7 +16629,8 @@ SUBROUTINE ED_DestroyParam( ParamData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(ParamData%BldNd_OutParam)) THEN DO i1 = LBOUND(ParamData%BldNd_OutParam,1), UBOUND(ParamData%BldNd_OutParam,1) - CALL NWTC_Library_Destroyoutparmtype( ParamData%BldNd_OutParam(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%BldNd_OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%BldNd_OutParam) ENDIF @@ -18020,9 +16773,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Db_BufSz = Db_BufSz + 1 ! CSRFrlTlt Db_BufSz = Db_BufSz + 1 ! CSTFrlSkw Db_BufSz = Db_BufSz + 1 ! CSTFrlTlt - Db_BufSz = Db_BufSz + 1 ! CTFinBank - Db_BufSz = Db_BufSz + 1 ! CTFinSkew - Db_BufSz = Db_BufSz + 1 ! CTFinTilt Db_BufSz = Db_BufSz + 1 ! CTFrlSkew Db_BufSz = Db_BufSz + 1 ! CTFrlSkw2 Db_BufSz = Db_BufSz + 1 ! CTFrlTilt @@ -18037,9 +16787,7 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Re_BufSz = Re_BufSz + 1 ! ProjArea Re_BufSz = Re_BufSz + 1 ! PtfmRefzt Re_BufSz = Re_BufSz + 1 ! RefTwrHt - Re_BufSz = Re_BufSz + 1 ! RFrlPntxn - Re_BufSz = Re_BufSz + 1 ! RFrlPntyn - Re_BufSz = Re_BufSz + 1 ! RFrlPntzn + Re_BufSz = Re_BufSz + SIZE(InData%RFrlPnt_n) ! RFrlPnt_n Re_BufSz = Re_BufSz + 1 ! rVDxn Re_BufSz = Re_BufSz + 1 ! rVDyn Re_BufSz = Re_BufSz + 1 ! rVDzn @@ -18055,9 +16803,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Re_BufSz = Re_BufSz + 1 ! rWJxn Re_BufSz = Re_BufSz + 1 ! rWJyn Re_BufSz = Re_BufSz + 1 ! rWJzn - Re_BufSz = Re_BufSz + 1 ! rWKxn - Re_BufSz = Re_BufSz + 1 ! rWKyn - Re_BufSz = Re_BufSz + 1 ! rWKzn Re_BufSz = Re_BufSz + 1 ! rZT0zt Re_BufSz = Re_BufSz + 1 ! rZYzt Db_BufSz = Db_BufSz + 1 ! SinDel3 @@ -18072,16 +16817,11 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Db_BufSz = Db_BufSz + 1 ! SRFrlTlt2 Db_BufSz = Db_BufSz + 1 ! SShftSkew Db_BufSz = Db_BufSz + 1 ! SShftTilt - Db_BufSz = Db_BufSz + 1 ! STFinBank - Db_BufSz = Db_BufSz + 1 ! STFinSkew - Db_BufSz = Db_BufSz + 1 ! STFinTilt Db_BufSz = Db_BufSz + 1 ! STFrlSkew Db_BufSz = Db_BufSz + 1 ! STFrlSkw2 Db_BufSz = Db_BufSz + 1 ! STFrlTilt Db_BufSz = Db_BufSz + 1 ! STFrlTlt2 - Re_BufSz = Re_BufSz + 1 ! TFrlPntxn - Re_BufSz = Re_BufSz + 1 ! TFrlPntyn - Re_BufSz = Re_BufSz + 1 ! TFrlPntzn + Re_BufSz = Re_BufSz + SIZE(InData%TFrlPnt_n) ! TFrlPnt_n Re_BufSz = Re_BufSz + 1 ! TipRad Re_BufSz = Re_BufSz + 1 ! TowerHt Re_BufSz = Re_BufSz + 1 ! TowerBsHt @@ -18139,40 +16879,11 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si END IF Int_BufSz = Int_BufSz + 1 ! TTopNode Int_BufSz = Int_BufSz + 1 ! TwrNodes - Int_BufSz = Int_BufSz + 1 ! InerTFA allocated yes/no - IF ( ALLOCATED(InData%InerTFA) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InerTFA upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%InerTFA) ! InerTFA - END IF - Int_BufSz = Int_BufSz + 1 ! InerTSS allocated yes/no - IF ( ALLOCATED(InData%InerTSS) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! InerTSS upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%InerTSS) ! InerTSS - END IF - Int_BufSz = Int_BufSz + 1 ! StiffTGJ allocated yes/no - IF ( ALLOCATED(InData%StiffTGJ) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! StiffTGJ upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%StiffTGJ) ! StiffTGJ - END IF - Int_BufSz = Int_BufSz + 1 ! StiffTEA allocated yes/no - IF ( ALLOCATED(InData%StiffTEA) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! StiffTEA upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%StiffTEA) ! StiffTEA - END IF + Int_BufSz = Int_BufSz + 1 ! MHK Int_BufSz = Int_BufSz + 1 ! StiffTFA allocated yes/no IF ( ALLOCATED(InData%StiffTFA) ) THEN Int_BufSz = Int_BufSz + 2*1 ! StiffTFA upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%StiffTFA) ! StiffTFA - END IF - Int_BufSz = Int_BufSz + 1 ! cgOffTFA allocated yes/no - IF ( ALLOCATED(InData%cgOffTFA) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! cgOffTFA upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%cgOffTFA) ! cgOffTFA - END IF - Int_BufSz = Int_BufSz + 1 ! cgOffTSS allocated yes/no - IF ( ALLOCATED(InData%cgOffTSS) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! cgOffTSS upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%cgOffTSS) ! cgOffTSS END IF Re_BufSz = Re_BufSz + 1 ! AtfaIner Int_BufSz = Int_BufSz + 1 ! BldCG allocated yes/no @@ -18237,11 +16948,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + 2*4 ! AxRedBld upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%AxRedBld) ! AxRedBld END IF - Int_BufSz = Int_BufSz + 1 ! BAlpha allocated yes/no - IF ( ALLOCATED(InData%BAlpha) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! BAlpha upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%BAlpha) ! BAlpha - END IF Int_BufSz = Int_BufSz + 1 ! BldEDamp allocated yes/no IF ( ALLOCATED(InData%BldEDamp) ) THEN Int_BufSz = Int_BufSz + 2*2 ! BldEDamp upper/lower bounds for each dimension @@ -18268,16 +16974,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + 2*3 ! CBF upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%CBF) ! CBF END IF - Int_BufSz = Int_BufSz + 1 ! cgOffBEdg allocated yes/no - IF ( ALLOCATED(InData%cgOffBEdg) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! cgOffBEdg upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%cgOffBEdg) ! cgOffBEdg - END IF - Int_BufSz = Int_BufSz + 1 ! cgOffBFlp allocated yes/no - IF ( ALLOCATED(InData%cgOffBFlp) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! cgOffBFlp upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%cgOffBFlp) ! cgOffBFlp - END IF Int_BufSz = Int_BufSz + 1 ! Chord allocated yes/no IF ( ALLOCATED(InData%Chord) ) THEN Int_BufSz = Int_BufSz + 2*1 ! Chord upper/lower bounds for each dimension @@ -18293,31 +16989,11 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + 2*1 ! DRNodes upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%DRNodes) ! DRNodes END IF - Int_BufSz = Int_BufSz + 1 ! EAOffBEdg allocated yes/no - IF ( ALLOCATED(InData%EAOffBEdg) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! EAOffBEdg upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%EAOffBEdg) ! EAOffBEdg - END IF - Int_BufSz = Int_BufSz + 1 ! EAOffBFlp allocated yes/no - IF ( ALLOCATED(InData%EAOffBFlp) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! EAOffBFlp upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%EAOffBFlp) ! EAOffBFlp - END IF Int_BufSz = Int_BufSz + 1 ! FStTunr allocated yes/no IF ( ALLOCATED(InData%FStTunr) ) THEN Int_BufSz = Int_BufSz + 2*2 ! FStTunr upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%FStTunr) ! FStTunr END IF - Int_BufSz = Int_BufSz + 1 ! InerBEdg allocated yes/no - IF ( ALLOCATED(InData%InerBEdg) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! InerBEdg upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%InerBEdg) ! InerBEdg - END IF - Int_BufSz = Int_BufSz + 1 ! InerBFlp allocated yes/no - IF ( ALLOCATED(InData%InerBFlp) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! InerBFlp upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%InerBFlp) ! InerBFlp - END IF Int_BufSz = Int_BufSz + 1 ! KBE allocated yes/no IF ( ALLOCATED(InData%KBE) ) THEN Int_BufSz = Int_BufSz + 2*3 ! KBE upper/lower bounds for each dimension @@ -18333,16 +17009,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + 2*2 ! MassB upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%MassB) ! MassB END IF - Int_BufSz = Int_BufSz + 1 ! RefAxisxb allocated yes/no - IF ( ALLOCATED(InData%RefAxisxb) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! RefAxisxb upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%RefAxisxb) ! RefAxisxb - END IF - Int_BufSz = Int_BufSz + 1 ! RefAxisyb allocated yes/no - IF ( ALLOCATED(InData%RefAxisyb) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! RefAxisyb upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%RefAxisyb) ! RefAxisyb - END IF Int_BufSz = Int_BufSz + 1 ! RNodes allocated yes/no IF ( ALLOCATED(InData%RNodes) ) THEN Int_BufSz = Int_BufSz + 2*1 ! RNodes upper/lower bounds for each dimension @@ -18373,21 +17039,11 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + 2*2 ! StiffBE upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%StiffBE) ! StiffBE END IF - Int_BufSz = Int_BufSz + 1 ! StiffBEA allocated yes/no - IF ( ALLOCATED(InData%StiffBEA) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! StiffBEA upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%StiffBEA) ! StiffBEA - END IF Int_BufSz = Int_BufSz + 1 ! StiffBF allocated yes/no IF ( ALLOCATED(InData%StiffBF) ) THEN Int_BufSz = Int_BufSz + 2*2 ! StiffBF upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%StiffBF) ! StiffBF END IF - Int_BufSz = Int_BufSz + 1 ! StiffBGJ allocated yes/no - IF ( ALLOCATED(InData%StiffBGJ) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! StiffBGJ upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%StiffBGJ) ! StiffBGJ - END IF Int_BufSz = Int_BufSz + 1 ! SThetaS allocated yes/no IF ( ALLOCATED(InData%SThetaS) ) THEN Int_BufSz = Int_BufSz + 2*2 ! SThetaS upper/lower bounds for each dimension @@ -18438,7 +17094,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Re_BufSz = Re_BufSz + 1 ! TeetSSSp Re_BufSz = Re_BufSz + 1 ! TeetSStP Int_BufSz = Int_BufSz + 1 ! TeetMod - Re_BufSz = Re_BufSz + 1 ! TFrlCDmp Re_BufSz = Re_BufSz + 1 ! TFrlDmp Re_BufSz = Re_BufSz + 1 ! TFrlDSDmp Re_BufSz = Re_BufSz + 1 ! TFrlDSDP @@ -18450,7 +17105,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Re_BufSz = Re_BufSz + 1 ! TFrlUSSP Re_BufSz = Re_BufSz + 1 ! TFrlUSSpr Int_BufSz = Int_BufSz + 1 ! TFrlMod - Re_BufSz = Re_BufSz + 1 ! RFrlCDmp Re_BufSz = Re_BufSz + 1 ! RFrlDmp Re_BufSz = Re_BufSz + 1 ! RFrlDSDmp Re_BufSz = Re_BufSz + 1 ! RFrlDSDP @@ -18765,12 +17419,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%CSTFrlTlt Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%CTFinBank - Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%CTFinSkew - Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%CTFinTilt - Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%CTFrlSkew Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%CTFrlSkw2 @@ -18799,12 +17447,10 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%RefTwrHt Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RFrlPntxn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RFrlPntyn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RFrlPntzn - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%RFrlPnt_n,1), UBOUND(InData%RFrlPnt_n,1) + ReKiBuf(Re_Xferred) = InData%RFrlPnt_n(i1) + Re_Xferred = Re_Xferred + 1 + END DO ReKiBuf(Re_Xferred) = InData%rVDxn Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%rVDyn @@ -18835,12 +17481,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%rWJzn Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%rWKxn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%rWKyn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%rWKzn - Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%rZT0zt Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%rZYzt @@ -18874,12 +17514,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%SShftTilt Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%STFinBank - Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%STFinSkew - Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%STFinTilt - Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%STFrlSkew Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%STFrlSkw2 @@ -18888,12 +17522,10 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%STFrlTlt2 Db_Xferred = Db_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFrlPntxn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFrlPntyn - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFrlPntzn - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%TFrlPnt_n,1), UBOUND(InData%TFrlPnt_n,1) + ReKiBuf(Re_Xferred) = InData%TFrlPnt_n(i1) + Re_Xferred = Re_Xferred + 1 + END DO ReKiBuf(Re_Xferred) = InData%TipRad Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%TowerHt @@ -19109,66 +17741,8 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%TwrNodes Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%InerTFA) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%InerTFA,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InerTFA,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%InerTFA,1), UBOUND(InData%InerTFA,1) - ReKiBuf(Re_Xferred) = InData%InerTFA(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%InerTSS) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%InerTSS,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InerTSS,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%InerTSS,1), UBOUND(InData%InerTSS,1) - ReKiBuf(Re_Xferred) = InData%InerTSS(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%StiffTGJ) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%StiffTGJ,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%StiffTGJ,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%StiffTGJ,1), UBOUND(InData%StiffTGJ,1) - ReKiBuf(Re_Xferred) = InData%StiffTGJ(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%StiffTEA) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 + IntKiBuf(Int_Xferred) = InData%MHK Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%StiffTEA,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%StiffTEA,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%StiffTEA,1), UBOUND(InData%StiffTEA,1) - ReKiBuf(Re_Xferred) = InData%StiffTEA(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF IF ( .NOT. ALLOCATED(InData%StiffTFA) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -19183,36 +17757,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si ReKiBuf(Re_Xferred) = InData%StiffTFA(i1) Re_Xferred = Re_Xferred + 1 END DO - END IF - IF ( .NOT. ALLOCATED(InData%cgOffTFA) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%cgOffTFA,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%cgOffTFA,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%cgOffTFA,1), UBOUND(InData%cgOffTFA,1) - ReKiBuf(Re_Xferred) = InData%cgOffTFA(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%cgOffTSS) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%cgOffTSS,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%cgOffTSS,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%cgOffTSS,1), UBOUND(InData%cgOffTSS,1) - ReKiBuf(Re_Xferred) = InData%cgOffTSS(i1) - Re_Xferred = Re_Xferred + 1 - END DO END IF ReKiBuf(Re_Xferred) = InData%AtfaIner Re_Xferred = Re_Xferred + 1 @@ -19400,26 +17944,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%BAlpha) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BAlpha,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BAlpha,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%BAlpha,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BAlpha,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%BAlpha,2), UBOUND(InData%BAlpha,2) - DO i1 = LBOUND(InData%BAlpha,1), UBOUND(InData%BAlpha,1) - ReKiBuf(Re_Xferred) = InData%BAlpha(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF IF ( .NOT. ALLOCATED(InData%BldEDamp) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -19527,46 +18051,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%cgOffBEdg) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%cgOffBEdg,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%cgOffBEdg,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%cgOffBEdg,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%cgOffBEdg,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%cgOffBEdg,2), UBOUND(InData%cgOffBEdg,2) - DO i1 = LBOUND(InData%cgOffBEdg,1), UBOUND(InData%cgOffBEdg,1) - ReKiBuf(Re_Xferred) = InData%cgOffBEdg(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%cgOffBFlp) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%cgOffBFlp,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%cgOffBFlp,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%cgOffBFlp,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%cgOffBFlp,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%cgOffBFlp,2), UBOUND(InData%cgOffBFlp,2) - DO i1 = LBOUND(InData%cgOffBFlp,1), UBOUND(InData%cgOffBFlp,1) - ReKiBuf(Re_Xferred) = InData%cgOffBFlp(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF IF ( .NOT. ALLOCATED(InData%Chord) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -19617,46 +18101,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%EAOffBEdg) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%EAOffBEdg,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%EAOffBEdg,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%EAOffBEdg,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%EAOffBEdg,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%EAOffBEdg,2), UBOUND(InData%EAOffBEdg,2) - DO i1 = LBOUND(InData%EAOffBEdg,1), UBOUND(InData%EAOffBEdg,1) - ReKiBuf(Re_Xferred) = InData%EAOffBEdg(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%EAOffBFlp) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%EAOffBFlp,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%EAOffBFlp,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%EAOffBFlp,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%EAOffBFlp,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%EAOffBFlp,2), UBOUND(InData%EAOffBFlp,2) - DO i1 = LBOUND(InData%EAOffBFlp,1), UBOUND(InData%EAOffBFlp,1) - ReKiBuf(Re_Xferred) = InData%EAOffBFlp(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF IF ( .NOT. ALLOCATED(InData%FStTunr) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -19677,46 +18121,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%InerBEdg) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%InerBEdg,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InerBEdg,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%InerBEdg,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InerBEdg,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%InerBEdg,2), UBOUND(InData%InerBEdg,2) - DO i1 = LBOUND(InData%InerBEdg,1), UBOUND(InData%InerBEdg,1) - ReKiBuf(Re_Xferred) = InData%InerBEdg(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%InerBFlp) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%InerBFlp,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InerBFlp,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%InerBFlp,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%InerBFlp,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%InerBFlp,2), UBOUND(InData%InerBFlp,2) - DO i1 = LBOUND(InData%InerBFlp,1), UBOUND(InData%InerBFlp,1) - ReKiBuf(Re_Xferred) = InData%InerBFlp(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF IF ( .NOT. ALLOCATED(InData%KBE) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -19751,78 +18155,38 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si IntKiBuf( Int_Xferred ) = LBOUND(InData%KBF,1) IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KBF,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%KBF,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KBF,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%KBF,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KBF,3) - Int_Xferred = Int_Xferred + 2 - - DO i3 = LBOUND(InData%KBF,3), UBOUND(InData%KBF,3) - DO i2 = LBOUND(InData%KBF,2), UBOUND(InData%KBF,2) - DO i1 = LBOUND(InData%KBF,1), UBOUND(InData%KBF,1) - ReKiBuf(Re_Xferred) = InData%KBF(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%MassB) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MassB,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MassB,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MassB,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MassB,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%MassB,2), UBOUND(InData%MassB,2) - DO i1 = LBOUND(InData%MassB,1), UBOUND(InData%MassB,1) - ReKiBuf(Re_Xferred) = InData%MassB(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%RefAxisxb) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%RefAxisxb,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RefAxisxb,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%RefAxisxb,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RefAxisxb,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%KBF,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KBF,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%KBF,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%KBF,3) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%RefAxisxb,2), UBOUND(InData%RefAxisxb,2) - DO i1 = LBOUND(InData%RefAxisxb,1), UBOUND(InData%RefAxisxb,1) - ReKiBuf(Re_Xferred) = InData%RefAxisxb(i1,i2) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(InData%KBF,3), UBOUND(InData%KBF,3) + DO i2 = LBOUND(InData%KBF,2), UBOUND(InData%KBF,2) + DO i1 = LBOUND(InData%KBF,1), UBOUND(InData%KBF,1) + ReKiBuf(Re_Xferred) = InData%KBF(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%RefAxisyb) ) THEN + IF ( .NOT. ALLOCATED(InData%MassB) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%RefAxisyb,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RefAxisyb,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%MassB,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MassB,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%RefAxisyb,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RefAxisyb,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%MassB,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MassB,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%RefAxisyb,2), UBOUND(InData%RefAxisyb,2) - DO i1 = LBOUND(InData%RefAxisyb,1), UBOUND(InData%RefAxisyb,1) - ReKiBuf(Re_Xferred) = InData%RefAxisyb(i1,i2) + DO i2 = LBOUND(InData%MassB,2), UBOUND(InData%MassB,2) + DO i1 = LBOUND(InData%MassB,1), UBOUND(InData%MassB,1) + ReKiBuf(Re_Xferred) = InData%MassB(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO @@ -19932,26 +18296,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%StiffBEA) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%StiffBEA,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%StiffBEA,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%StiffBEA,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%StiffBEA,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%StiffBEA,2), UBOUND(InData%StiffBEA,2) - DO i1 = LBOUND(InData%StiffBEA,1), UBOUND(InData%StiffBEA,1) - ReKiBuf(Re_Xferred) = InData%StiffBEA(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF IF ( .NOT. ALLOCATED(InData%StiffBF) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -19972,26 +18316,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%StiffBGJ) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%StiffBGJ,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%StiffBGJ,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%StiffBGJ,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%StiffBGJ,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%StiffBGJ,2), UBOUND(InData%StiffBGJ,2) - DO i1 = LBOUND(InData%StiffBGJ,1), UBOUND(InData%StiffBGJ,1) - ReKiBuf(Re_Xferred) = InData%StiffBGJ(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF IF ( .NOT. ALLOCATED(InData%SThetaS) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -20205,8 +18529,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Re_Xferred = Re_Xferred + 1 IntKiBuf(Int_Xferred) = InData%TeetMod Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TFrlCDmp - Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%TFrlDmp Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%TFrlDSDmp @@ -20229,8 +18551,6 @@ SUBROUTINE ED_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Re_Xferred = Re_Xferred + 1 IntKiBuf(Int_Xferred) = InData%TFrlMod Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RFrlCDmp - Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%RFrlDmp Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%RFrlDSDmp @@ -20707,12 +19027,6 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Db_Xferred = Db_Xferred + 1 OutData%CSTFrlTlt = REAL(DbKiBuf(Db_Xferred), R8Ki) Db_Xferred = Db_Xferred + 1 - OutData%CTFinBank = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - OutData%CTFinSkew = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - OutData%CTFinTilt = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 OutData%CTFrlSkew = REAL(DbKiBuf(Db_Xferred), R8Ki) Db_Xferred = Db_Xferred + 1 OutData%CTFrlSkw2 = REAL(DbKiBuf(Db_Xferred), R8Ki) @@ -20741,12 +19055,12 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 OutData%RefTwrHt = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%RFrlPntxn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RFrlPntyn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RFrlPntzn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%RFrlPnt_n,1) + i1_u = UBOUND(OutData%RFrlPnt_n,1) + DO i1 = LBOUND(OutData%RFrlPnt_n,1), UBOUND(OutData%RFrlPnt_n,1) + OutData%RFrlPnt_n(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO OutData%rVDxn = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%rVDyn = ReKiBuf(Re_Xferred) @@ -20777,12 +19091,6 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 OutData%rWJzn = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - OutData%rWKxn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%rWKyn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%rWKzn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 OutData%rZT0zt = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%rZYzt = ReKiBuf(Re_Xferred) @@ -20819,12 +19127,6 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Db_Xferred = Db_Xferred + 1 OutData%SShftTilt = REAL(DbKiBuf(Db_Xferred), R8Ki) Db_Xferred = Db_Xferred + 1 - OutData%STFinBank = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - OutData%STFinSkew = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 - OutData%STFinTilt = REAL(DbKiBuf(Db_Xferred), R8Ki) - Db_Xferred = Db_Xferred + 1 OutData%STFrlSkew = REAL(DbKiBuf(Db_Xferred), R8Ki) Db_Xferred = Db_Xferred + 1 OutData%STFrlSkw2 = REAL(DbKiBuf(Db_Xferred), R8Ki) @@ -20833,12 +19135,12 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Db_Xferred = Db_Xferred + 1 OutData%STFrlTlt2 = REAL(DbKiBuf(Db_Xferred), R8Ki) Db_Xferred = Db_Xferred + 1 - OutData%TFrlPntxn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TFrlPntyn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TFrlPntzn = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%TFrlPnt_n,1) + i1_u = UBOUND(OutData%TFrlPnt_n,1) + DO i1 = LBOUND(OutData%TFrlPnt_n,1), UBOUND(OutData%TFrlPnt_n,1) + OutData%TFrlPnt_n(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO OutData%TipRad = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%TowerHt = ReKiBuf(Re_Xferred) @@ -21097,78 +19399,8 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 1 OutData%TwrNodes = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InerTFA not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%InerTFA)) DEALLOCATE(OutData%InerTFA) - ALLOCATE(OutData%InerTFA(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InerTFA.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%InerTFA,1), UBOUND(OutData%InerTFA,1) - OutData%InerTFA(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InerTSS not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%InerTSS)) DEALLOCATE(OutData%InerTSS) - ALLOCATE(OutData%InerTSS(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InerTSS.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%InerTSS,1), UBOUND(OutData%InerTSS,1) - OutData%InerTSS(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! StiffTGJ not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%StiffTGJ)) DEALLOCATE(OutData%StiffTGJ) - ALLOCATE(OutData%StiffTGJ(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%StiffTGJ.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%StiffTGJ,1), UBOUND(OutData%StiffTGJ,1) - OutData%StiffTGJ(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! StiffTEA not allocated - Int_Xferred = Int_Xferred + 1 - ELSE + OutData%MHK = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%StiffTEA)) DEALLOCATE(OutData%StiffTEA) - ALLOCATE(OutData%StiffTEA(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%StiffTEA.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%StiffTEA,1), UBOUND(OutData%StiffTEA,1) - OutData%StiffTEA(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! StiffTFA not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -21186,42 +19418,6 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg OutData%StiffTFA(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! cgOffTFA not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%cgOffTFA)) DEALLOCATE(OutData%cgOffTFA) - ALLOCATE(OutData%cgOffTFA(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%cgOffTFA.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%cgOffTFA,1), UBOUND(OutData%cgOffTFA,1) - OutData%cgOffTFA(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! cgOffTSS not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%cgOffTSS)) DEALLOCATE(OutData%cgOffTSS) - ALLOCATE(OutData%cgOffTSS(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%cgOffTSS.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%cgOffTSS,1), UBOUND(OutData%cgOffTSS,1) - OutData%cgOffTSS(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO END IF OutData%AtfaIner = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 @@ -21433,29 +19629,6 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BAlpha not allocated - Int_Xferred = Int_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%BAlpha)) DEALLOCATE(OutData%BAlpha) - ALLOCATE(OutData%BAlpha(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BAlpha.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%BAlpha,2), UBOUND(OutData%BAlpha,2) - DO i1 = LBOUND(OutData%BAlpha,1), UBOUND(OutData%BAlpha,1) - OutData%BAlpha(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BldEDamp not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -21578,52 +19751,6 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! cgOffBEdg not allocated - Int_Xferred = Int_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%cgOffBEdg)) DEALLOCATE(OutData%cgOffBEdg) - ALLOCATE(OutData%cgOffBEdg(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%cgOffBEdg.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%cgOffBEdg,2), UBOUND(OutData%cgOffBEdg,2) - DO i1 = LBOUND(OutData%cgOffBEdg,1), UBOUND(OutData%cgOffBEdg,1) - OutData%cgOffBEdg(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! cgOffBFlp not allocated - Int_Xferred = Int_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%cgOffBFlp)) DEALLOCATE(OutData%cgOffBFlp) - ALLOCATE(OutData%cgOffBFlp(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%cgOffBFlp.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%cgOffBFlp,2), UBOUND(OutData%cgOffBFlp,2) - DO i1 = LBOUND(OutData%cgOffBFlp,1), UBOUND(OutData%cgOffBFlp,1) - OutData%cgOffBFlp(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Chord not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -21680,102 +19807,10 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END IF DO i1 = LBOUND(OutData%DRNodes,1), UBOUND(OutData%DRNodes,1) OutData%DRNodes(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! EAOffBEdg not allocated - Int_Xferred = Int_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%EAOffBEdg)) DEALLOCATE(OutData%EAOffBEdg) - ALLOCATE(OutData%EAOffBEdg(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%EAOffBEdg.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%EAOffBEdg,2), UBOUND(OutData%EAOffBEdg,2) - DO i1 = LBOUND(OutData%EAOffBEdg,1), UBOUND(OutData%EAOffBEdg,1) - OutData%EAOffBEdg(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! EAOffBFlp not allocated - Int_Xferred = Int_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%EAOffBFlp)) DEALLOCATE(OutData%EAOffBFlp) - ALLOCATE(OutData%EAOffBFlp(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%EAOffBFlp.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%EAOffBFlp,2), UBOUND(OutData%EAOffBFlp,2) - DO i1 = LBOUND(OutData%EAOffBFlp,1), UBOUND(OutData%EAOffBFlp,1) - OutData%EAOffBFlp(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FStTunr not allocated - Int_Xferred = Int_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%FStTunr)) DEALLOCATE(OutData%FStTunr) - ALLOCATE(OutData%FStTunr(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FStTunr.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%FStTunr,2), UBOUND(OutData%FStTunr,2) - DO i1 = LBOUND(OutData%FStTunr,1), UBOUND(OutData%FStTunr,1) - OutData%FStTunr(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InerBEdg not allocated - Int_Xferred = Int_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%InerBEdg)) DEALLOCATE(OutData%InerBEdg) - ALLOCATE(OutData%InerBEdg(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InerBEdg.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%InerBEdg,2), UBOUND(OutData%InerBEdg,2) - DO i1 = LBOUND(OutData%InerBEdg,1), UBOUND(OutData%InerBEdg,1) - OutData%InerBEdg(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! InerBFlp not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FStTunr not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -21785,15 +19820,15 @@ SUBROUTINE ED_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%InerBFlp)) DEALLOCATE(OutData%InerBFlp) - ALLOCATE(OutData%InerBFlp(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%FStTunr)) DEALLOCATE(OutData%FStTunr) + ALLOCATE(OutData%FStTunr(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%InerBFlp.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FStTunr.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%InerBFlp,2), UBOUND(OutData%InerBFlp,2) - DO i1 = LBOUND(OutData%InerBFlp,1), UBOUND(OutData%InerBFlp,1) - OutData%InerBFlp(i1,i2) = ReKiBuf(Re_Xferred) + DO i2 = LBOUND(OutData%FStTunr,2), UBOUND(OutData%FStTunr,2) + DO i1 = LBOUND(OutData%FStTunr,1), UBOUND(OutData%FStTunr,1) + OutData%FStTunr(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END DO @@ -21877,52 +19912,6 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RefAxisxb not allocated - Int_Xferred = Int_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%RefAxisxb)) DEALLOCATE(OutData%RefAxisxb) - ALLOCATE(OutData%RefAxisxb(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RefAxisxb.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%RefAxisxb,2), UBOUND(OutData%RefAxisxb,2) - DO i1 = LBOUND(OutData%RefAxisxb,1), UBOUND(OutData%RefAxisxb,1) - OutData%RefAxisxb(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RefAxisyb not allocated - Int_Xferred = Int_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%RefAxisyb)) DEALLOCATE(OutData%RefAxisyb) - ALLOCATE(OutData%RefAxisyb(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RefAxisyb.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%RefAxisyb,2), UBOUND(OutData%RefAxisyb,2) - DO i1 = LBOUND(OutData%RefAxisyb,1), UBOUND(OutData%RefAxisyb,1) - OutData%RefAxisyb(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RNodes not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -22046,29 +20035,6 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! StiffBEA not allocated - Int_Xferred = Int_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%StiffBEA)) DEALLOCATE(OutData%StiffBEA) - ALLOCATE(OutData%StiffBEA(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%StiffBEA.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%StiffBEA,2), UBOUND(OutData%StiffBEA,2) - DO i1 = LBOUND(OutData%StiffBEA,1), UBOUND(OutData%StiffBEA,1) - OutData%StiffBEA(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! StiffBF not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -22092,29 +20058,6 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! StiffBGJ not allocated - Int_Xferred = Int_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%StiffBGJ)) DEALLOCATE(OutData%StiffBGJ) - ALLOCATE(OutData%StiffBGJ(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%StiffBGJ.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%StiffBGJ,2), UBOUND(OutData%StiffBGJ,2) - DO i1 = LBOUND(OutData%StiffBGJ,1), UBOUND(OutData%StiffBGJ,1) - OutData%StiffBGJ(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! SThetaS not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -22360,8 +20303,6 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 OutData%TeetMod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%TFrlCDmp = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 OutData%TFrlDmp = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%TFrlDSDmp = ReKiBuf(Re_Xferred) @@ -22384,8 +20325,6 @@ SUBROUTINE ED_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 OutData%TFrlMod = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%RFrlCDmp = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 OutData%RFrlDmp = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%RFrlDSDmp = ReKiBuf(Re_Xferred) @@ -22659,6 +20598,9 @@ SUBROUTINE ED_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) CALL MeshCopy( SrcInputData%NacelleLoads, DstInputData%NacelleLoads, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcInputData%TFinCMLoads, DstInputData%TFinCMLoads, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN IF (ALLOCATED(SrcInputData%TwrAddedMass)) THEN i1_l = LBOUND(SrcInputData%TwrAddedMass,1) i1_u = UBOUND(SrcInputData%TwrAddedMass,1) @@ -22693,25 +20635,44 @@ SUBROUTINE ED_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) DstInputData%HSSBrTrqC = SrcInputData%HSSBrTrqC END SUBROUTINE ED_CopyInput - SUBROUTINE ED_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%BladePtLoads)) THEN DO i1 = LBOUND(InputData%BladePtLoads,1), UBOUND(InputData%BladePtLoads,1) - CALL MeshDestroy( InputData%BladePtLoads(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%BladePtLoads(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InputData%BladePtLoads) ENDIF - CALL MeshDestroy( InputData%PlatformPtMesh, ErrStat, ErrMsg ) - CALL MeshDestroy( InputData%TowerPtLoads, ErrStat, ErrMsg ) - CALL MeshDestroy( InputData%HubPtLoad, ErrStat, ErrMsg ) - CALL MeshDestroy( InputData%NacelleLoads, ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%PlatformPtMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%TowerPtLoads, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%HubPtLoad, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%NacelleLoads, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%TFinCMLoads, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InputData%TwrAddedMass)) THEN DEALLOCATE(InputData%TwrAddedMass) ENDIF @@ -22847,6 +20808,23 @@ SUBROUTINE ED_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 3 ! TFinCMLoads: size of buffers for each call to pack subtype + CALL MeshPack( InData%TFinCMLoads, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! TFinCMLoads + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! TFinCMLoads + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! TFinCMLoads + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! TFinCMLoads + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 1 ! TwrAddedMass allocated yes/no IF ( ALLOCATED(InData%TwrAddedMass) ) THEN Int_BufSz = Int_BufSz + 2*3 ! TwrAddedMass upper/lower bounds for each dimension @@ -23041,6 +21019,34 @@ SUBROUTINE ED_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + CALL MeshPack( InData%TFinCMLoads, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! TFinCMLoads + 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%TwrAddedMass) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -23340,6 +21346,46 @@ SUBROUTINE ED_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) + 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%TFinCMLoads, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! TFinCMLoads + 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 ! TwrAddedMass not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -23475,6 +21521,9 @@ SUBROUTINE ED_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs CALL MeshCopy( SrcOutputData%TowerBaseMotion14, DstOutputData%TowerBaseMotion14, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcOutputData%TFinCMMotion, DstOutputData%TFinCMMotion, 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) @@ -23527,35 +21576,59 @@ SUBROUTINE ED_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs DstOutputData%LSShftFzs = SrcOutputData%LSShftFzs END SUBROUTINE ED_CopyOutput - SUBROUTINE ED_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE ED_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ED_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ED_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%BladeLn2Mesh)) THEN DO i1 = LBOUND(OutputData%BladeLn2Mesh,1), UBOUND(OutputData%BladeLn2Mesh,1) - CALL MeshDestroy( OutputData%BladeLn2Mesh(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%BladeLn2Mesh(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OutputData%BladeLn2Mesh) ENDIF - CALL MeshDestroy( OutputData%PlatformPtMesh, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%TowerLn2Mesh, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%HubPtMotion14, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%HubPtMotion, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%BladeRootMotion14, ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%PlatformPtMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( OutputData%TowerLn2Mesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( OutputData%HubPtMotion14, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( OutputData%HubPtMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( OutputData%BladeRootMotion14, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(OutputData%BladeRootMotion)) THEN DO i1 = LBOUND(OutputData%BladeRootMotion,1), UBOUND(OutputData%BladeRootMotion,1) - CALL MeshDestroy( OutputData%BladeRootMotion(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%BladeRootMotion(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OutputData%BladeRootMotion) ENDIF - CALL MeshDestroy( OutputData%RotorFurlMotion14, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%NacelleMotion, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%TowerBaseMotion14, ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%RotorFurlMotion14, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( OutputData%NacelleMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( OutputData%TowerBaseMotion14, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( OutputData%TFinCMMotion, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF @@ -23782,6 +21855,23 @@ SUBROUTINE ED_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 3 ! TFinCMMotion: size of buffers for each call to pack subtype + CALL MeshPack( InData%TFinCMMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! TFinCMMotion + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! TFinCMMotion + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! TFinCMMotion + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! TFinCMMotion + 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 @@ -24151,6 +22241,34 @@ SUBROUTINE ED_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + CALL MeshPack( InData%TFinCMMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! TFinCMMotion + 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%WriteOutput) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -24698,6 +22816,46 @@ SUBROUTINE ED_UnPackOutput( 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) + 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%TFinCMMotion, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! TFinCMMotion + 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 ! WriteOutput not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -24909,6 +23067,8 @@ SUBROUTINE ED_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) CALL MeshExtrapInterp1(u1%NacelleLoads, u2%NacelleLoads, tin, u_out%NacelleLoads, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + CALL MeshExtrapInterp1(u1%TFinCMLoads, u2%TFinCMLoads, tin, u_out%TFinCMLoads, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ALLOCATED(u_out%TwrAddedMass) .AND. ALLOCATED(u1%TwrAddedMass)) THEN DO i3 = LBOUND(u_out%TwrAddedMass,3),UBOUND(u_out%TwrAddedMass,3) DO i2 = LBOUND(u_out%TwrAddedMass,2),UBOUND(u_out%TwrAddedMass,2) @@ -25011,6 +23171,8 @@ SUBROUTINE ED_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, ErrM CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) CALL MeshExtrapInterp2(u1%NacelleLoads, u2%NacelleLoads, u3%NacelleLoads, tin, u_out%NacelleLoads, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + CALL MeshExtrapInterp2(u1%TFinCMLoads, u2%TFinCMLoads, u3%TFinCMLoads, tin, u_out%TFinCMLoads, tin_out, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ALLOCATED(u_out%TwrAddedMass) .AND. ALLOCATED(u1%TwrAddedMass)) THEN DO i3 = LBOUND(u_out%TwrAddedMass,3),UBOUND(u_out%TwrAddedMass,3) DO i2 = LBOUND(u_out%TwrAddedMass,2),UBOUND(u_out%TwrAddedMass,2) @@ -25168,6 +23330,8 @@ SUBROUTINE ED_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, ErrMsg CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) CALL MeshExtrapInterp1(y1%TowerBaseMotion14, y2%TowerBaseMotion14, tin, y_out%TowerBaseMotion14, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + CALL MeshExtrapInterp1(y1%TFinCMMotion, y2%TFinCMMotion, tin, y_out%TFinCMMotion, 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)) @@ -25317,6 +23481,8 @@ SUBROUTINE ED_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, Err CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) CALL MeshExtrapInterp2(y1%TowerBaseMotion14, y2%TowerBaseMotion14, y3%TowerBaseMotion14, tin, y_out%TowerBaseMotion14, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + CALL MeshExtrapInterp2(y1%TFinCMMotion, y2%TFinCMMotion, y3%TFinCMMotion, tin, y_out%TFinCMMotion, 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 diff --git a/modules/extptfm/CMakeLists.txt b/modules/extptfm/CMakeLists.txt index 384212ab1..4eb338ffb 100644 --- a/modules/extptfm/CMakeLists.txt +++ b/modules/extptfm/CMakeLists.txt @@ -18,16 +18,16 @@ if (GENERATE_TYPES) generate_f90_types(src/ExtPtfm_MCKF_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/ExtPtfm_MCKF_Types.f90) endif() -add_library(extptfm_mckflib +add_library(extptfm_mckflib src/ExtPtfm_MCKF.f90 src/ExtPtfm_MCKF_IO.f90 src/ExtPtfm_MCKF_Types.f90 ) - target_link_libraries(extptfm_mckflib nwtclibs) install(TARGETS extptfm_mckflib EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) + ARCHIVE DESTINATION lib +) diff --git a/modules/extptfm/src/ExtPtfm_MCKF_IO.f90 b/modules/extptfm/src/ExtPtfm_MCKF_IO.f90 index d0e2868d1..4fefde8a4 100644 --- a/modules/extptfm/src/ExtPtfm_MCKF_IO.f90 +++ b/modules/extptfm/src/ExtPtfm_MCKF_IO.f90 @@ -40,7 +40,6 @@ MODULE ExtPtfm_MCKF_Parameters ! Variables for output channels INTEGER(IntKi), PARAMETER :: MaxOutChs = 9 + 3*200 ! Maximum number of output channels ! Harcoded to outputs of 200 CB modes - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 INTEGER(IntKi), PARAMETER :: ID_Time = 0 INTEGER(IntKi), PARAMETER :: ID_PtfFx = 1 INTEGER(IntKi), PARAMETER :: ID_PtfFy = 2 @@ -298,7 +297,7 @@ subroutine setInvalidChannel() ! If a selected output channel is not available by this module set ErrStat = ErrID_Warn. p%OutParam(I)%Units = "INVALID" p%OutParam(I)%Indx = 0 - WarnMsg=trim(WarnMsg)//TRIM(p%OutParam(I)%Name)//" is not an available output channel."//CHAR(10) + WarnMsg=trim(WarnMsg)//TRIM(p%OutParam(I)%Name)//" is not an available output channel."//NewLine ! call SetErrStat(ErrID_Warn, TRIM(p%OutParam(I)%Name)//" is not an available output channel.",ErrStat,ErrMsg,'ExtPtfm_SetOutParam') ! write(*,*)TRIM(p%OutParam(I)%Name)//" is not an available output channel." end subroutine diff --git a/modules/extptfm/src/ExtPtfm_MCKF_Registry.txt b/modules/extptfm/src/ExtPtfm_MCKF_Registry.txt index c75fee857..4297d50b3 100644 --- a/modules/extptfm/src/ExtPtfm_MCKF_Registry.txt +++ b/modules/extptfm/src/ExtPtfm_MCKF_Registry.txt @@ -19,7 +19,7 @@ include Registry_NWTC_Library.txt # e.g., the name of the input file, the file root name, etc. typedef ExtPtfm_MCKF/ExtPtfm InitInputType CHARACTER(1024) InputFile - - - "Name of the input file; remove if there is no file" - typedef ^ ^ LOGICAL Linearize - .FALSE. - "Flag that tells this module if the glue code wants to linearize." - -typedef ^ ^ ReKi PtfmRefzt - - - "Vertical distance from the ground [onshore] or MSL [offshore] to the platform reference point" meters +typedef ^ ^ ReKi PtfmRefzt - - - "Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform reference point" meters typedef ^ ^ CHARACTER(1024) RootName - - - "RootName for writing output files" # ..... Input file data ........................................................................................................... diff --git a/modules/extptfm/src/ExtPtfm_MCKF_Types.f90 b/modules/extptfm/src/ExtPtfm_MCKF_Types.f90 index aac3e92fb..68f463e0f 100644 --- a/modules/extptfm/src/ExtPtfm_MCKF_Types.f90 +++ b/modules/extptfm/src/ExtPtfm_MCKF_Types.f90 @@ -37,7 +37,7 @@ MODULE ExtPtfm_MCKF_Types TYPE, PUBLIC :: ExtPtfm_InitInputType CHARACTER(1024) :: InputFile !< Name of the input file; remove if there is no file [-] LOGICAL :: Linearize = .FALSE. !< Flag that tells this module if the glue code wants to linearize. [-] - REAL(ReKi) :: PtfmRefzt !< Vertical distance from the ground [onshore] or MSL [offshore] to the platform reference point [meters] + REAL(ReKi) :: PtfmRefzt !< Vertical distance from the ground level [onshore], MSL [offshore wind or floating MHK], or seabed [fixed MHK] to the platform reference point [meters] CHARACTER(1024) :: RootName !< RootName for writing output files [-] END TYPE ExtPtfm_InitInputType ! ======================= @@ -177,15 +177,27 @@ SUBROUTINE ExtPtfm_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, DstInitInputData%RootName = SrcInitInputData%RootName END SUBROUTINE ExtPtfm_CopyInitInput - SUBROUTINE ExtPtfm_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE ExtPtfm_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ExtPtfm_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE ExtPtfm_DestroyInitInput SUBROUTINE ExtPtfm_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -387,15 +399,27 @@ SUBROUTINE ExtPtfm_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ENDIF END SUBROUTINE ExtPtfm_CopyInputFile - SUBROUTINE ExtPtfm_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) + SUBROUTINE ExtPtfm_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ExtPtfm_InputFile), INTENT(INOUT) :: InputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyInputFile' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyInputFile' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputFileData%ActiveCBDOF)) THEN DEALLOCATE(InputFileData%ActiveCBDOF) ENDIF @@ -871,16 +895,29 @@ SUBROUTINE ExtPtfm_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCod ENDIF END SUBROUTINE ExtPtfm_CopyInitOutput - SUBROUTINE ExtPtfm_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE ExtPtfm_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ExtPtfm_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF @@ -1533,15 +1570,27 @@ SUBROUTINE ExtPtfm_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ENDIF END SUBROUTINE ExtPtfm_CopyContState - SUBROUTINE ExtPtfm_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE ExtPtfm_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ExtPtfm_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%qm)) THEN DEALLOCATE(ContStateData%qm) ENDIF @@ -1736,15 +1785,27 @@ SUBROUTINE ExtPtfm_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE ExtPtfm_CopyDiscState - SUBROUTINE ExtPtfm_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE ExtPtfm_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ExtPtfm_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE ExtPtfm_DestroyDiscState SUBROUTINE ExtPtfm_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1861,15 +1922,27 @@ SUBROUTINE ExtPtfm_CopyConstrState( SrcConstrStateData, DstConstrStateData, Ctrl DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE ExtPtfm_CopyConstrState - SUBROUTINE ExtPtfm_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE ExtPtfm_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ExtPtfm_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE ExtPtfm_DestroyConstrState SUBROUTINE ExtPtfm_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2003,18 +2076,31 @@ SUBROUTINE ExtPtfm_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCod DstOtherStateData%n = SrcOtherStateData%n END SUBROUTINE ExtPtfm_CopyOtherState - SUBROUTINE ExtPtfm_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE ExtPtfm_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ExtPtfm_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OtherStateData%xdot)) THEN DO i1 = LBOUND(OtherStateData%xdot,1), UBOUND(OtherStateData%xdot,1) - CALL ExtPtfm_DestroyContState( OtherStateData%xdot(i1), ErrStat, ErrMsg ) + CALL ExtPtfm_DestroyContState( OtherStateData%xdot(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OtherStateData%xdot) ENDIF @@ -2295,15 +2381,27 @@ SUBROUTINE ExtPtfm_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ENDIF END SUBROUTINE ExtPtfm_CopyMisc - SUBROUTINE ExtPtfm_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE ExtPtfm_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ExtPtfm_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%xFlat)) THEN DEALLOCATE(MiscData%xFlat) ENDIF @@ -2898,15 +2996,27 @@ SUBROUTINE ExtPtfm_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, Err ENDIF END SUBROUTINE ExtPtfm_CopyParam - SUBROUTINE ExtPtfm_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE ExtPtfm_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ExtPtfm_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%Mass)) THEN DEALLOCATE(ParamData%Mass) ENDIF @@ -2975,7 +3085,8 @@ SUBROUTINE ExtPtfm_DestroyParam( ParamData, ErrStat, ErrMsg ) 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 ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF @@ -4317,16 +4428,29 @@ SUBROUTINE ExtPtfm_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, Err IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE ExtPtfm_CopyInput - SUBROUTINE ExtPtfm_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE ExtPtfm_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ExtPtfm_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( InputData%PtfmMesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( InputData%PtfmMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE ExtPtfm_DestroyInput SUBROUTINE ExtPtfm_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -4539,16 +4663,29 @@ SUBROUTINE ExtPtfm_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ENDIF END SUBROUTINE ExtPtfm_CopyOutput - SUBROUTINE ExtPtfm_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE ExtPtfm_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ExtPtfm_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'ExtPtfm_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( OutputData%PtfmMesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( OutputData%PtfmMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF diff --git a/modules/feamooring/CMakeLists.txt b/modules/feamooring/CMakeLists.txt index 42411802d..20a01aca8 100644 --- a/modules/feamooring/CMakeLists.txt +++ b/modules/feamooring/CMakeLists.txt @@ -18,25 +18,20 @@ if (GENERATE_TYPES) generate_f90_types(src/FEAM_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/FEAMooring_Types.f90) endif() -set(FEAM_LIBS_SOURCES +add_library(feamlib src/FEAM.f90 src/FEAMooring_Types.f90 ) - -add_library(feamlib ${FEAM_LIBS_SOURCES}) target_link_libraries(feamlib nwtclibs) -install(TARGETS feamlib - EXPORT "${CMAKE_PROJECT_NAME}Libraries" - RUNTIME DESTINATION lib - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) - -add_executable(feam_driver src/FEAM_Driver.f90) -target_link_libraries(feam_driver feamlib versioninfolib) +add_executable(feam_driver + src/FEAM_Driver.f90 +) +target_link_libraries(feam_driver feamlib) -install(TARGETS feam_driver +install(TARGETS feamlib feam_driver EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) + LIBRARY DESTINATION lib +) diff --git a/modules/feamooring/src/FEAM.f90 b/modules/feamooring/src/FEAM.f90 index f1e541e6e..a97aeee76 100644 --- a/modules/feamooring/src/FEAM.f90 +++ b/modules/feamooring/src/FEAM.f90 @@ -35,11 +35,6 @@ MODULE FEAMooring ! This code was generated by Write_ChckOutLst.m at 09-Dec-2014 14:03:37. - ! Parameters related to output length (number of characters allowed in the output data headers): - - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 - - ! Indices for computing output channels: ! NOTES: ! (1) These parameters are in the order stored in "OutListParameters.xlsx" diff --git a/modules/feamooring/src/FEAMooring_Types.f90 b/modules/feamooring/src/FEAMooring_Types.f90 index ffed53236..46cb3bec1 100644 --- a/modules/feamooring/src/FEAMooring_Types.f90 +++ b/modules/feamooring/src/FEAMooring_Types.f90 @@ -483,15 +483,27 @@ SUBROUTINE FEAM_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, Err ENDIF END SUBROUTINE FEAM_CopyInputFile - SUBROUTINE FEAM_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) + SUBROUTINE FEAM_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FEAM_InputFile), INTENT(INOUT) :: InputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyInputFile' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyInputFile' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputFileData%LineCI)) THEN DEALLOCATE(InputFileData%LineCI) ENDIF @@ -1520,15 +1532,27 @@ SUBROUTINE FEAM_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Err DstInitInputData%WtrDens = SrcInitInputData%WtrDens END SUBROUTINE FEAM_CopyInitInput - SUBROUTINE FEAM_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE FEAM_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FEAM_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%WaveAcc0)) THEN DEALLOCATE(InitInputData%WaveAcc0) ENDIF @@ -1949,22 +1973,35 @@ SUBROUTINE FEAM_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ENDIF END SUBROUTINE FEAM_CopyInitOutput - SUBROUTINE FEAM_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE FEAM_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FEAM_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN DEALLOCATE(InitOutputData%WriteOutputUnt) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitOutputData%LAnchxi)) THEN DEALLOCATE(InitOutputData%LAnchxi) ENDIF @@ -2522,15 +2559,27 @@ SUBROUTINE FEAM_CopyContState( SrcContStateData, DstContStateData, CtrlCode, Err ENDIF END SUBROUTINE FEAM_CopyContState - SUBROUTINE FEAM_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE FEAM_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FEAM_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%GLU)) THEN DEALLOCATE(ContStateData%GLU) ENDIF @@ -2746,15 +2795,27 @@ SUBROUTINE FEAM_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, Err DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE FEAM_CopyDiscState - SUBROUTINE FEAM_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE FEAM_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FEAM_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE FEAM_DestroyDiscState SUBROUTINE FEAM_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2873,15 +2934,27 @@ SUBROUTINE FEAM_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCod DstConstrStateData%TZER = SrcConstrStateData%TZER END SUBROUTINE FEAM_CopyConstrState - SUBROUTINE FEAM_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE FEAM_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FEAM_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE FEAM_DestroyConstrState SUBROUTINE FEAM_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -3114,15 +3187,27 @@ SUBROUTINE FEAM_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, DstOtherStateData%EMAS0 = SrcOtherStateData%EMAS0 END SUBROUTINE FEAM_CopyOtherState - SUBROUTINE FEAM_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE FEAM_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FEAM_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OtherStateData%GLU0)) THEN DEALLOCATE(OtherStateData%GLU0) ENDIF @@ -3781,15 +3866,27 @@ SUBROUTINE FEAM_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%LastIndWave = SrcMiscData%LastIndWave END SUBROUTINE FEAM_CopyMisc - SUBROUTINE FEAM_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE FEAM_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FEAM_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%GLF)) THEN DEALLOCATE(MiscData%GLF) ENDIF @@ -4893,15 +4990,27 @@ SUBROUTINE FEAM_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ENDIF END SUBROUTINE FEAM_CopyParam - SUBROUTINE FEAM_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE FEAM_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FEAM_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%NEQ)) THEN DEALLOCATE(ParamData%NEQ) ENDIF @@ -4949,7 +5058,8 @@ SUBROUTINE FEAM_DestroyParam( ParamData, ErrStat, ErrMsg ) 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 ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF @@ -6320,17 +6430,31 @@ SUBROUTINE FEAM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE FEAM_CopyInput - SUBROUTINE FEAM_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE FEAM_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FEAM_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( InputData%HydroForceLineMesh, ErrStat, ErrMsg ) - CALL MeshDestroy( InputData%PtFairleadDisplacement, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( InputData%HydroForceLineMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%PtFairleadDisplacement, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE FEAM_DestroyInput SUBROUTINE FEAM_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -6631,20 +6755,34 @@ SUBROUTINE FEAM_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Err IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE FEAM_CopyOutput - SUBROUTINE FEAM_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE FEAM_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FEAM_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FEAM_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF - CALL MeshDestroy( OutputData%PtFairleadLoad, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%LineMeshPosition, ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%PtFairleadLoad, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( OutputData%LineMeshPosition, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE FEAM_DestroyOutput SUBROUTINE FEAM_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) diff --git a/modules/hydrodyn/CMakeLists.txt b/modules/hydrodyn/CMakeLists.txt index ccf0a80ca..07e0319ec 100644 --- a/modules/hydrodyn/CMakeLists.txt +++ b/modules/hydrodyn/CMakeLists.txt @@ -27,7 +27,7 @@ if (GENERATE_TYPES) generate_f90_types(src/Waves2.txt ${CMAKE_CURRENT_LIST_DIR}/src/Waves2_Types.f90) endif() -set(HYDRODYN_SOURCES +add_library(hydrodynlib src/Conv_Radiation.f90 src/Current.f90 src/HydroDyn.f90 @@ -55,20 +55,23 @@ set(HYDRODYN_SOURCES src/Waves_Types.f90 src/Waves2_Types.f90 ) - -add_library(hydrodynlib ${HYDRODYN_SOURCES}) target_link_libraries(hydrodynlib nwtclibs) -# c-bindings interface library -add_library(hydrodyn_c_binding SHARED src/HydroDyn_C_Binding.f90) -target_link_libraries(hydrodyn_c_binding hydrodynlib) +# Driver +add_executable(hydrodyn_driver + src/HydroDyn_DriverCode.f90 +) +target_link_libraries(hydrodyn_driver hydrodynlib versioninfolib) + +# C-bindings interface library +add_library(hydrodyn_c_binding SHARED + src/HydroDyn_C_Binding.f90 +) +target_link_libraries(hydrodyn_c_binding hydrodynlib versioninfolib) if(APPLE OR UNIX) - target_compile_definitions(hydrodyn_c_binding PUBLIC -DIMPLICIT_DLLEXPORT) + target_compile_definitions(hydrodyn_c_binding PRIVATE IMPLICIT_DLLEXPORT) endif() -add_executable(hydrodyn_driver src/HydroDyn_DriverCode.f90) -target_link_libraries(hydrodyn_driver hydrodynlib nwtclibs versioninfolib) - #add_executable(ss_radiation # src/SS_Radiation_DriverCode.f90) #target_link_libraries(ss_radiation hydrodynlib nwtclibs) @@ -77,4 +80,5 @@ install(TARGETS hydrodynlib hydrodyn_driver hydrodyn_c_binding EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) + ARCHIVE DESTINATION lib +) diff --git a/modules/hydrodyn/python-lib/hydrodyn_library.py b/modules/hydrodyn/python-lib/hydrodyn_library.py index b52e2eb74..f9abfff7b 100644 --- a/modules/hydrodyn/python-lib/hydrodyn_library.py +++ b/modules/hydrodyn/python-lib/hydrodyn_library.py @@ -421,6 +421,7 @@ def check_error(self): def check_input_motions(self,nodePos,nodeVel,nodeAcc): # make sure number of nodes didn't change for some reason if self._initNumNodePts != self.numNodePts: + # @ANDY TODO: `time` is not available here so this would be a runtime error print(f"At time {time}, the number of node points changed from initial value of {self._initNumNodePts}. This is not permitted during the simulation.") self.hydrodyn_end() raise Exception("\nError in calling HydroDyn library.") @@ -594,7 +595,7 @@ def __init__(self,filename,chan_names,chan_units): # write file header t_string=datetime.datetime.now() dt_string=datetime.date.today() - self.OutFile.write(f"## This file was generated by InflowWind_Driver on {dt_string.strftime('%b-%d-%Y')} at {t_string.strftime('%H:%M:%S')}\n") + self.OutFile.write(f"## This file was generated by HydroDyn_Driver on {dt_string.strftime('%b-%d-%Y')} at {t_string.strftime('%H:%M:%S')}\n") self.OutFile.write(f"## This file contains output channels requested from the OutList section of the input file") self.OutFile.write(f"{filename}\n") self.OutFile.write("#\n") diff --git a/modules/hydrodyn/src/Conv_Radiation_Types.f90 b/modules/hydrodyn/src/Conv_Radiation_Types.f90 index d9188b01d..4c69b4d10 100644 --- a/modules/hydrodyn/src/Conv_Radiation_Types.f90 +++ b/modules/hydrodyn/src/Conv_Radiation_Types.f90 @@ -171,15 +171,27 @@ SUBROUTINE Conv_Rdtn_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode DstInitInputData%UnSum = SrcInitInputData%UnSum END SUBROUTINE Conv_Rdtn_CopyInitInput - SUBROUTINE Conv_Rdtn_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE Conv_Rdtn_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Conv_Rdtn_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%HdroAddMs)) THEN DEALLOCATE(InitInputData%HdroAddMs) ENDIF @@ -505,15 +517,27 @@ SUBROUTINE Conv_Rdtn_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlC DstInitOutputData%DummyInitOut = SrcInitOutputData%DummyInitOut END SUBROUTINE Conv_Rdtn_CopyInitOutput - SUBROUTINE Conv_Rdtn_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE Conv_Rdtn_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Conv_Rdtn_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Conv_Rdtn_DestroyInitOutput SUBROUTINE Conv_Rdtn_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -630,15 +654,27 @@ SUBROUTINE Conv_Rdtn_CopyContState( SrcContStateData, DstContStateData, CtrlCode DstContStateData%DummyContState = SrcContStateData%DummyContState END SUBROUTINE Conv_Rdtn_CopyContState - SUBROUTINE Conv_Rdtn_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE Conv_Rdtn_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Conv_Rdtn_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Conv_Rdtn_DestroyContState SUBROUTINE Conv_Rdtn_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -771,15 +807,27 @@ SUBROUTINE Conv_Rdtn_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode DstDiscStateData%LastTime = SrcDiscStateData%LastTime END SUBROUTINE Conv_Rdtn_CopyDiscState - SUBROUTINE Conv_Rdtn_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE Conv_Rdtn_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Conv_Rdtn_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(DiscStateData%XDHistory)) THEN DEALLOCATE(DiscStateData%XDHistory) ENDIF @@ -949,15 +997,27 @@ SUBROUTINE Conv_Rdtn_CopyConstrState( SrcConstrStateData, DstConstrStateData, Ct DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE Conv_Rdtn_CopyConstrState - SUBROUTINE Conv_Rdtn_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE Conv_Rdtn_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Conv_Rdtn_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Conv_Rdtn_DestroyConstrState SUBROUTINE Conv_Rdtn_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1074,15 +1134,27 @@ SUBROUTINE Conv_Rdtn_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlC DstOtherStateData%IndRdtn = SrcOtherStateData%IndRdtn END SUBROUTINE Conv_Rdtn_CopyOtherState - SUBROUTINE Conv_Rdtn_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE Conv_Rdtn_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Conv_Rdtn_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Conv_Rdtn_DestroyOtherState SUBROUTINE Conv_Rdtn_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1199,15 +1271,27 @@ SUBROUTINE Conv_Rdtn_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrM DstMiscData%LastIndRdtn = SrcMiscData%LastIndRdtn END SUBROUTINE Conv_Rdtn_CopyMisc - SUBROUTINE Conv_Rdtn_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE Conv_Rdtn_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Conv_Rdtn_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Conv_Rdtn_DestroyMisc SUBROUTINE Conv_Rdtn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1347,15 +1431,27 @@ SUBROUTINE Conv_Rdtn_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, E DstParamData%NStepRdtn1 = SrcParamData%NStepRdtn1 END SUBROUTINE Conv_Rdtn_CopyParam - SUBROUTINE Conv_Rdtn_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE Conv_Rdtn_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Conv_Rdtn_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%RdtnKrnl)) THEN DEALLOCATE(ParamData%RdtnKrnl) ENDIF @@ -1568,15 +1664,27 @@ SUBROUTINE Conv_Rdtn_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, E ENDIF END SUBROUTINE Conv_Rdtn_CopyInput - SUBROUTINE Conv_Rdtn_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE Conv_Rdtn_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Conv_Rdtn_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%Velocity)) THEN DEALLOCATE(InputData%Velocity) ENDIF @@ -1742,15 +1850,27 @@ SUBROUTINE Conv_Rdtn_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat ENDIF END SUBROUTINE Conv_Rdtn_CopyOutput - SUBROUTINE Conv_Rdtn_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE Conv_Rdtn_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Conv_Rdtn_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Conv_Rdtn_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%F_Rdtn)) THEN DEALLOCATE(OutputData%F_Rdtn) ENDIF diff --git a/modules/hydrodyn/src/Current_Types.f90 b/modules/hydrodyn/src/Current_Types.f90 index f262434bc..a768b5d0b 100644 --- a/modules/hydrodyn/src/Current_Types.f90 +++ b/modules/hydrodyn/src/Current_Types.f90 @@ -140,15 +140,27 @@ SUBROUTINE Current_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, DstInitInputData%DirRoot = SrcInitInputData%DirRoot END SUBROUTINE Current_CopyInitInput - SUBROUTINE Current_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE Current_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Current_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%MorisonNodezi)) THEN DEALLOCATE(InitInputData%MorisonNodezi) ENDIF @@ -396,15 +408,27 @@ SUBROUTINE Current_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCod DstInitOutputData%PCurrVyiPz0 = SrcInitOutputData%PCurrVyiPz0 END SUBROUTINE Current_CopyInitOutput - SUBROUTINE Current_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE Current_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Current_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%CurrVxi)) THEN DEALLOCATE(InitOutputData%CurrVxi) ENDIF @@ -609,15 +633,27 @@ SUBROUTINE Current_CopyContState( SrcContStateData, DstContStateData, CtrlCode, DstContStateData%DummyContState = SrcContStateData%DummyContState END SUBROUTINE Current_CopyContState - SUBROUTINE Current_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE Current_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Current_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Current_DestroyContState SUBROUTINE Current_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -734,15 +770,27 @@ SUBROUTINE Current_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE Current_CopyDiscState - SUBROUTINE Current_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE Current_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Current_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Current_DestroyDiscState SUBROUTINE Current_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -859,15 +907,27 @@ SUBROUTINE Current_CopyConstrState( SrcConstrStateData, DstConstrStateData, Ctrl DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE Current_CopyConstrState - SUBROUTINE Current_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE Current_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Current_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Current_DestroyConstrState SUBROUTINE Current_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -984,15 +1044,27 @@ SUBROUTINE Current_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCod DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState END SUBROUTINE Current_CopyOtherState - SUBROUTINE Current_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE Current_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Current_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Current_DestroyOtherState SUBROUTINE Current_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1109,15 +1181,27 @@ SUBROUTINE Current_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg DstMiscData%DummyMiscVar = SrcMiscData%DummyMiscVar END SUBROUTINE Current_CopyMisc - SUBROUTINE Current_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE Current_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Current_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Current_DestroyMisc SUBROUTINE Current_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1234,15 +1318,27 @@ SUBROUTINE Current_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, Err DstParamData%DT = SrcParamData%DT END SUBROUTINE Current_CopyParam - SUBROUTINE Current_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE Current_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Current_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Current_DestroyParam SUBROUTINE Current_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1359,15 +1455,27 @@ SUBROUTINE Current_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, Err DstInputData%DummyInput = SrcInputData%DummyInput END SUBROUTINE Current_CopyInput - SUBROUTINE Current_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE Current_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Current_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Current_DestroyInput SUBROUTINE Current_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1484,15 +1592,27 @@ SUBROUTINE Current_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, DstOutputData%DummyOutput = SrcOutputData%DummyOutput END SUBROUTINE Current_CopyOutput - SUBROUTINE Current_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE Current_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Current_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Current_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Current_DestroyOutput SUBROUTINE Current_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) diff --git a/modules/hydrodyn/src/HydroDyn.f90 b/modules/hydrodyn/src/HydroDyn.f90 index 1f8cedf0e..2c05caa18 100644 --- a/modules/hydrodyn/src/HydroDyn.f90 +++ b/modules/hydrodyn/src/HydroDyn.f90 @@ -442,11 +442,14 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I ! Set summary unit number in Waves, Radiation, and Morison initialization input data - InputFileData%Waves%UnSum = InputFileData%UnSum InputFileData%WAMIT%Conv_Rdtn%UnSum = InputFileData%UnSum InputFileData%Morison%UnSum = InputFileData%UnSum + ! distribute wave field and turbine location variables as needed to submodule initInputs + InputFileData%Waves%WaveFieldMod = InitInp%WaveFieldMod + InputFileData%Waves%PtfmLocationX = InitInp%PtfmLocationX + InputFileData%Waves%PtfmLocationY = InitInp%PtfmLocationY ! Now call each sub-module's *_Init subroutine ! to fully initialize each sub-module based on the necessary initialization data @@ -1355,10 +1358,7 @@ SUBROUTINE HydroDyn_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, I ErrStat, ErrMsg ) END IF - - - - + ! Check the output switch to see if Morison is needing to send outputs back to HydroDyn via the WriteOutput array IF ( InputFileData%OutSwtch > 0 ) THEN diff --git a/modules/hydrodyn/src/HydroDyn.txt b/modules/hydrodyn/src/HydroDyn.txt index 038fc676a..541a6dbcc 100644 --- a/modules/hydrodyn/src/HydroDyn.txt +++ b/modules/hydrodyn/src/HydroDyn.txt @@ -84,6 +84,7 @@ typedef ^ ^ ReKi typedef ^ ^ DbKi TMax - - - "Supplied by Driver: The total simulation time" "(sec)" typedef ^ ^ LOGICAL HasIce - - - "Supplied by Driver: Whether this simulation has ice loading (flag)" - 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 ^ ^ INTEGER WaveFieldMod - - - "Wave field handling (-) (switch) 0: use individual HydroDyn inputs without adjustment, 1: adjust wave phases based on turbine offsets from farm origin" - 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" # @@ -107,6 +108,12 @@ typedef ^ ^ CHARACTER(L typedef ^ InitOutputType INTEGER DerivOrder_x {:} - - "Integer that tells FAST/MBC3 the maximum derivative order of continuous states used in linearization" - typedef ^ ^ LOGICAL IsLoad_u {:} - - "Flag that tells FAST if the inputs used in linearization are loads (for preconditioning matrix)" - +typedef ^ ^ ReKi WaveVel {:}{:}{:} - - "output for now just to pass to MoorDyn" - +typedef ^ ^ ReKi WaveAcc {:}{:}{:} - - "output for now just to pass to MoorDyn" - +typedef ^ ^ ReKi WaveDynP {:}{:} - - "output for now just to pass to MoorDyn" - +typedef ^ ^ ReKi WaveElev {:}{:} - - "output for now just to pass to MoorDyn" - +typedef ^ ^ ReKi WaveTime {:} - - "output for now just to pass to MoorDyn" - + # ..... HD_ModuleMapType .................................................................................................................... typedef ^ HD_ModuleMapType MeshMapType uW_P_2_PRP_P - - - "Mesh mapping data: WAMIT body kinematics to PRP node at (0,0,0)" - diff --git a/modules/hydrodyn/src/HydroDyn_C_Binding.f90 b/modules/hydrodyn/src/HydroDyn_C_Binding.f90 index d4cda7163..532b7fc44 100644 --- a/modules/hydrodyn/src/HydroDyn_C_Binding.f90 +++ b/modules/hydrodyn/src/HydroDyn_C_Binding.f90 @@ -19,10 +19,11 @@ !********************************************************************************************************************************** MODULE HydroDyn_C_BINDING - USE ISO_C_BINDING - USE HydroDyn - USE HydroDyn_Types - USE NWTC_Library + USE ISO_C_BINDING + USE HydroDyn + USE HydroDyn_Types + USE NWTC_Library + USE VersionInfo IMPLICIT NONE @@ -39,6 +40,10 @@ MODULE HydroDyn_C_BINDING integer(IntKi), parameter :: ErrMsgLen_C = 1025 integer(IntKi), parameter :: IntfStrLen = 1025 ! length of other strings through the C interface + !------------------------------------------------------------------------------------ + ! Version info for display + type(ProgDesc), parameter :: version = ProgDesc( 'HydroDyn library', '', '' ) + !------------------------------------------------------------------------------------ ! Potential issues ! - if MaxHDOutputs is sufficiently large, we may overrun the buffer on the Python @@ -223,6 +228,10 @@ SUBROUTINE HydroDyn_C_Init( OutRootName_C, InputFileString_C, InputFileStringLen ErrStat = ErrID_None ErrMsg = "" + CALL NWTC_Init( ProgNameIn=version%Name ) + CALL DispCopyrightLicense( version%Name ) + CALL DispCompileRuntimeInfo( version%Name ) + ! Sanity checks on values passed InterpOrder = int(InterpOrder_C, IntKi) if ( InterpOrder < 1_IntKi .or. InterpOrder > 2_IntKi ) then diff --git a/modules/hydrodyn/src/HydroDyn_DriverCode.f90 b/modules/hydrodyn/src/HydroDyn_DriverCode.f90 index 6312fb010..926e58e35 100644 --- a/modules/hydrodyn/src/HydroDyn_DriverCode.f90 +++ b/modules/hydrodyn/src/HydroDyn_DriverCode.f90 @@ -103,7 +103,7 @@ PROGRAM HydroDynDriver INTEGER(IntKi) :: n ! Loop counter (for time step) 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, (-). + REAL(ReKi) :: 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 diff --git a/modules/hydrodyn/src/HydroDyn_Input.f90 b/modules/hydrodyn/src/HydroDyn_Input.f90 index 3dadca82b..fcbac6fa6 100644 --- a/modules/hydrodyn/src/HydroDyn_Input.f90 +++ b/modules/hydrodyn/src/HydroDyn_Input.f90 @@ -1262,8 +1262,7 @@ SUBROUTINE HydroDyn_ParseInput( InputFileName, OutRootName, defWtrDens, defWtrDp call AllocAry( InputFileData%UserOutputs, MaxUserOutputs, 'InputFileData%UserOutputs', ErrStat2, ErrMsg2 ) ! MaxUserOutputs is set in registry if (Failed()) return; - call ReadOutputListFromFileInfo( FileInfo_In, CurLine, InputFileData%UserOutputs, & - InputFileData%NUserOutputs, 'OutList', "List of user-requested output channels", ErrStat2, ErrMsg2, UnEc ) + call ReadOutputListFromFileInfo( FileInfo_In, CurLine, InputFileData%UserOutputs, InputFileData%NUserOutputs, ErrStat2, ErrMsg2, UnEc ) if (Failed()) return; @@ -1313,6 +1312,7 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, Interval, InputFileData, ErrS INTEGER :: I ! Generic loop counter index INTEGER :: J ! Generic loop counter index INTEGER :: K ! Generic loop counter index + INTEGER :: Itemp ! @mhall: additional temporary index CHARACTER(1024) :: TmpPath ! Temporary storage for relative path name LOGICAL :: FoundID ! Boolean flag indicating whether an ID from one tables is found in one of the other input table REAL(ReKi) :: MinDepth ! The minimum depth entry in the Depth-based Hydrodynamic coefficents table @@ -1483,7 +1483,7 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, Interval, InputFileData, ErrS ! WaveTMax - Analysis time for incident wave calculations. - IF ( InputFileData%Waves%WaveMod == 0 ) THEN ! .TRUE if we have incident waves. + IF ( InputFileData%Waves%WaveMod == 0 ) THEN ! .TRUE if we DO NOT HAVE have incident waves. ! TODO: Issue warning if WaveTMax was not already 0.0 in this case. IF ( .NOT. EqualRealNos(InputFileData%Waves%WaveTMax, 0.0_DbKi) ) THEN @@ -3223,7 +3223,6 @@ SUBROUTINE HydroDynInput_ProcessInitData( InitInp, Interval, InputFileData, ErrS InputFileData%Current%MorisonNodezi(I) = InputFileData%Waves%WaveKinzi(I) END DO - ! If we are using the Waves module, the node information must be copied over. InputFileData%Waves2%NWaveKin = InputFileData%Waves%NWaveKin ! Number of points where the incident wave kinematics will be computed (-) IF ( InputFileData%Waves2%WvDiffQTFF .OR. InputFileData%Waves2%WvSumQTFF ) THEN diff --git a/modules/hydrodyn/src/HydroDyn_Output.f90 b/modules/hydrodyn/src/HydroDyn_Output.f90 index fc1c73e6b..44668a17c 100644 --- a/modules/hydrodyn/src/HydroDyn_Output.f90 +++ b/modules/hydrodyn/src/HydroDyn_Output.f90 @@ -34,13 +34,7 @@ MODULE HydroDyn_Output ! 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 - +! This code was generated by "Write_ChckOutLst.m" at 07-Sep-2022 15:24:58. ! Indices for computing output channels: ! NOTES: @@ -612,8 +606,8 @@ MODULE HydroDyn_Output ! 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 -! =================================================================================================== +!End of code generated by Matlab script Write_ChckOutLst +! =================================================================================================== REAL(ReKi) :: AllOuts(MaxHDOutputs) ! Array of all possible outputs @@ -1232,7 +1226,7 @@ SUBROUTINE HDOut_WriteOutputs( Time, y, p, Decimate, ErrStat, ErrMsg ) INTEGER :: I ! Generic loop counter CHARACTER(200) :: Frmt ! a string to hold a format statement integer(IntKi) :: ErrStat2 - character(ErrMsgLen) :: ErrMsg2 +! character(ErrMsgLen) :: ErrMsg2 IF (p%UnOutFile < 0 ) RETURN @@ -1343,7 +1337,7 @@ SUBROUTINE HDOUT_Init( HydroDyn_ProgDesc, OutRootName, InputFileData, y, p, m, CALL HDOUT_ChkOutLst( InputFileData%OutList(1:p%NumOuts), y, p, ErrStat, ErrMsg ) - IF ( ErrStat /= 0 ) RETURN + IF ( ErrStat >= AbortErrLev ) RETURN ! Aggregate the sub-module initialization outputs for the glue code @@ -1597,13 +1591,13 @@ FUNCTION HDOut_GetChannels ( NUserOutputs, UserOutputs, OutList, foundMask, CALL Conv2UC( OutListTmp ) ! Convert OutListTmp to upper case - Indx = IndexCharAry( OutListTmp(1:9), ValidParamAry ) + Indx = IndexCharAry( OutListTmp(1:OutStrLenM1), 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 ) + Indx = IndexCharAry( OutListTmp(1:OutStrLenM1), ValidParamAry ) END IF IF ( Indx > 0 ) THEN diff --git a/modules/hydrodyn/src/HydroDyn_Types.f90 b/modules/hydrodyn/src/HydroDyn_Types.f90 index 3397982a0..4777387fd 100644 --- a/modules/hydrodyn/src/HydroDyn_Types.f90 +++ b/modules/hydrodyn/src/HydroDyn_Types.f90 @@ -95,6 +95,7 @@ MODULE HydroDyn_Types REAL(DbKi) :: TMax !< Supplied by Driver: The total simulation time [(sec)] LOGICAL :: HasIce !< Supplied by Driver: Whether this simulation has ice loading (flag) [-] 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,-] + INTEGER(IntKi) :: WaveFieldMod !< Wave field handling (-) (switch) 0: use individual HydroDyn inputs without adjustment, 1: adjust wave phases based on turbine offsets from farm origin [-] 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] END TYPE HydroDyn_InitInputType @@ -117,6 +118,11 @@ MODULE HydroDyn_Types CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_u !< Names of the inputs used in linearization [-] INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: DerivOrder_x !< Integer that tells FAST/MBC3 the maximum derivative order of continuous states used in linearization [-] LOGICAL , DIMENSION(:), ALLOCATABLE :: IsLoad_u !< Flag that tells FAST if the inputs used in linearization are loads (for preconditioning matrix) [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: WaveVel !< output for now just to pass to MoorDyn [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: WaveAcc !< output for now just to pass to MoorDyn [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WaveDynP !< output for now just to pass to MoorDyn [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WaveElev !< output for now just to pass to MoorDyn [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WaveTime !< output for now just to pass to MoorDyn [-] END TYPE HydroDyn_InitOutputType ! ======================= ! ========= HD_ModuleMapType ======= @@ -485,15 +491,27 @@ SUBROUTINE HydroDyn_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, DstInputFileData%OutSFmt = SrcInputFileData%OutSFmt END SUBROUTINE HydroDyn_CopyInputFile - SUBROUTINE HydroDyn_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) + SUBROUTINE HydroDyn_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(HydroDyn_InputFile), INTENT(INOUT) :: InputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyInputFile' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyInputFile' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputFileData%AddF0)) THEN DEALLOCATE(InputFileData%AddF0) ENDIF @@ -506,9 +524,12 @@ SUBROUTINE HydroDyn_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) IF (ALLOCATED(InputFileData%AddBQuad)) THEN DEALLOCATE(InputFileData%AddBQuad) ENDIF - CALL Waves_DestroyInitInput( InputFileData%Waves, ErrStat, ErrMsg ) - CALL Waves2_DestroyInitInput( InputFileData%Waves2, ErrStat, ErrMsg ) - CALL Current_DestroyInitInput( InputFileData%Current, ErrStat, ErrMsg ) + CALL Waves_DestroyInitInput( InputFileData%Waves, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Waves2_DestroyInitInput( InputFileData%Waves2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Current_DestroyInitInput( InputFileData%Current, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InputFileData%PotFile)) THEN DEALLOCATE(InputFileData%PotFile) ENDIF @@ -536,9 +557,12 @@ SUBROUTINE HydroDyn_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) IF (ALLOCATED(InputFileData%PtfmCOByt)) THEN DEALLOCATE(InputFileData%PtfmCOByt) ENDIF - CALL WAMIT_DestroyInitInput( InputFileData%WAMIT, ErrStat, ErrMsg ) - CALL WAMIT2_DestroyInitInput( InputFileData%WAMIT2, ErrStat, ErrMsg ) - CALL Morison_DestroyInitInput( InputFileData%Morison, ErrStat, ErrMsg ) + CALL WAMIT_DestroyInitInput( InputFileData%WAMIT, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL WAMIT2_DestroyInitInput( InputFileData%WAMIT2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Morison_DestroyInitInput( InputFileData%Morison, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InputFileData%UserOutputs)) THEN DEALLOCATE(InputFileData%UserOutputs) ENDIF @@ -1936,20 +1960,34 @@ SUBROUTINE HydroDyn_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, END IF DstInitInputData%WaveElevXY = SrcInitInputData%WaveElevXY ENDIF + DstInitInputData%WaveFieldMod = SrcInitInputData%WaveFieldMod DstInitInputData%PtfmLocationX = SrcInitInputData%PtfmLocationX DstInitInputData%PtfmLocationY = SrcInitInputData%PtfmLocationY END SUBROUTINE HydroDyn_CopyInitInput - SUBROUTINE HydroDyn_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE HydroDyn_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(HydroDyn_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedFileData, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedFileData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitInputData%WaveElevXY)) THEN DEALLOCATE(InitInputData%WaveElevXY) ENDIF @@ -2023,6 +2061,7 @@ SUBROUTINE HydroDyn_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 2*2 ! WaveElevXY upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WaveElevXY) ! WaveElevXY END IF + Int_BufSz = Int_BufSz + 1 ! WaveFieldMod Re_BufSz = Re_BufSz + 1 ! PtfmLocationX Re_BufSz = Re_BufSz + 1 ! PtfmLocationY IF ( Re_BufSz .GT. 0 ) THEN @@ -2124,6 +2163,8 @@ SUBROUTINE HydroDyn_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, END DO END DO END IF + IntKiBuf(Int_Xferred) = InData%WaveFieldMod + Int_Xferred = Int_Xferred + 1 ReKiBuf(Re_Xferred) = InData%PtfmLocationX Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%PtfmLocationY @@ -2245,6 +2286,8 @@ SUBROUTINE HydroDyn_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta END DO END DO END IF + OutData%WaveFieldMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%PtfmLocationX = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%PtfmLocationY = ReKiBuf(Re_Xferred) @@ -2261,6 +2304,7 @@ SUBROUTINE HydroDyn_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCo 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_CopyInitOutput' @@ -2408,32 +2452,120 @@ SUBROUTINE HydroDyn_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCo END IF END IF DstInitOutputData%IsLoad_u = SrcInitOutputData%IsLoad_u +ENDIF +IF (ALLOCATED(SrcInitOutputData%WaveVel)) THEN + i1_l = LBOUND(SrcInitOutputData%WaveVel,1) + i1_u = UBOUND(SrcInitOutputData%WaveVel,1) + i2_l = LBOUND(SrcInitOutputData%WaveVel,2) + i2_u = UBOUND(SrcInitOutputData%WaveVel,2) + i3_l = LBOUND(SrcInitOutputData%WaveVel,3) + i3_u = UBOUND(SrcInitOutputData%WaveVel,3) + IF (.NOT. ALLOCATED(DstInitOutputData%WaveVel)) THEN + ALLOCATE(DstInitOutputData%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 DstInitOutputData%WaveVel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%WaveVel = SrcInitOutputData%WaveVel +ENDIF +IF (ALLOCATED(SrcInitOutputData%WaveAcc)) THEN + i1_l = LBOUND(SrcInitOutputData%WaveAcc,1) + i1_u = UBOUND(SrcInitOutputData%WaveAcc,1) + i2_l = LBOUND(SrcInitOutputData%WaveAcc,2) + i2_u = UBOUND(SrcInitOutputData%WaveAcc,2) + i3_l = LBOUND(SrcInitOutputData%WaveAcc,3) + i3_u = UBOUND(SrcInitOutputData%WaveAcc,3) + IF (.NOT. ALLOCATED(DstInitOutputData%WaveAcc)) THEN + ALLOCATE(DstInitOutputData%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 DstInitOutputData%WaveAcc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%WaveAcc = SrcInitOutputData%WaveAcc +ENDIF +IF (ALLOCATED(SrcInitOutputData%WaveDynP)) THEN + i1_l = LBOUND(SrcInitOutputData%WaveDynP,1) + i1_u = UBOUND(SrcInitOutputData%WaveDynP,1) + i2_l = LBOUND(SrcInitOutputData%WaveDynP,2) + i2_u = UBOUND(SrcInitOutputData%WaveDynP,2) + IF (.NOT. ALLOCATED(DstInitOutputData%WaveDynP)) THEN + ALLOCATE(DstInitOutputData%WaveDynP(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WaveDynP.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%WaveDynP = SrcInitOutputData%WaveDynP +ENDIF +IF (ALLOCATED(SrcInitOutputData%WaveElev)) THEN + i1_l = LBOUND(SrcInitOutputData%WaveElev,1) + i1_u = UBOUND(SrcInitOutputData%WaveElev,1) + i2_l = LBOUND(SrcInitOutputData%WaveElev,2) + i2_u = UBOUND(SrcInitOutputData%WaveElev,2) + IF (.NOT. ALLOCATED(DstInitOutputData%WaveElev)) THEN + ALLOCATE(DstInitOutputData%WaveElev(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WaveElev.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%WaveElev = SrcInitOutputData%WaveElev +ENDIF +IF (ALLOCATED(SrcInitOutputData%WaveTime)) THEN + i1_l = LBOUND(SrcInitOutputData%WaveTime,1) + i1_u = UBOUND(SrcInitOutputData%WaveTime,1) + IF (.NOT. ALLOCATED(DstInitOutputData%WaveTime)) THEN + ALLOCATE(DstInitOutputData%WaveTime(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WaveTime.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%WaveTime = SrcInitOutputData%WaveTime ENDIF END SUBROUTINE HydroDyn_CopyInitOutput - SUBROUTINE HydroDyn_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE HydroDyn_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(HydroDyn_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WAMIT)) THEN DO i1 = LBOUND(InitOutputData%WAMIT,1), UBOUND(InitOutputData%WAMIT,1) - CALL WAMIT_DestroyInitOutput( InitOutputData%WAMIT(i1), ErrStat, ErrMsg ) + CALL WAMIT_DestroyInitOutput( InitOutputData%WAMIT(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) 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 ) + CALL WAMIT2_DestroyInitOutput( InitOutputData%WAMIT2(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitOutputData%WAMIT2) ENDIF - CALL Waves2_DestroyInitOutput( InitOutputData%Waves2, ErrStat, ErrMsg ) - CALL Morison_DestroyInitOutput( InitOutputData%Morison, ErrStat, ErrMsg ) + CALL Waves2_DestroyInitOutput( InitOutputData%Waves2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Morison_DestroyInitOutput( InitOutputData%Morison, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF @@ -2443,7 +2575,8 @@ SUBROUTINE HydroDyn_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) IF (ALLOCATED(InitOutputData%WaveElevSeries)) THEN DEALLOCATE(InitOutputData%WaveElevSeries) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitOutputData%LinNames_y)) THEN DEALLOCATE(InitOutputData%LinNames_y) ENDIF @@ -2458,6 +2591,21 @@ SUBROUTINE HydroDyn_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(InitOutputData%IsLoad_u)) THEN DEALLOCATE(InitOutputData%IsLoad_u) +ENDIF +IF (ALLOCATED(InitOutputData%WaveVel)) THEN + DEALLOCATE(InitOutputData%WaveVel) +ENDIF +IF (ALLOCATED(InitOutputData%WaveAcc)) THEN + DEALLOCATE(InitOutputData%WaveAcc) +ENDIF +IF (ALLOCATED(InitOutputData%WaveDynP)) THEN + DEALLOCATE(InitOutputData%WaveDynP) +ENDIF +IF (ALLOCATED(InitOutputData%WaveElev)) THEN + DEALLOCATE(InitOutputData%WaveElev) +ENDIF +IF (ALLOCATED(InitOutputData%WaveTime)) THEN + DEALLOCATE(InitOutputData%WaveTime) ENDIF END SUBROUTINE HydroDyn_DestroyInitOutput @@ -2637,6 +2785,31 @@ SUBROUTINE HydroDyn_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 ! WaveVel allocated yes/no + IF ( ALLOCATED(InData%WaveVel) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! WaveVel upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WaveVel) ! WaveVel + END IF + Int_BufSz = Int_BufSz + 1 ! WaveAcc allocated yes/no + IF ( ALLOCATED(InData%WaveAcc) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! WaveAcc upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WaveAcc) ! WaveAcc + END IF + Int_BufSz = Int_BufSz + 1 ! WaveDynP allocated yes/no + IF ( ALLOCATED(InData%WaveDynP) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! WaveDynP upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WaveDynP) ! WaveDynP + END IF + Int_BufSz = Int_BufSz + 1 ! WaveElev allocated yes/no + IF ( ALLOCATED(InData%WaveElev) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! WaveElev upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WaveElev) ! WaveElev + END IF + 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 IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -2971,6 +3144,111 @@ SUBROUTINE HydroDyn_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_Xferred = Int_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%WaveVel) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveVel,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveVel,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveVel,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveVel,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveVel,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveVel,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%WaveVel,3), UBOUND(InData%WaveVel,3) + DO i2 = LBOUND(InData%WaveVel,2), UBOUND(InData%WaveVel,2) + DO i1 = LBOUND(InData%WaveVel,1), UBOUND(InData%WaveVel,1) + ReKiBuf(Re_Xferred) = InData%WaveVel(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WaveAcc) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveAcc,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveAcc,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveAcc,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveAcc,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveAcc,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveAcc,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%WaveAcc,3), UBOUND(InData%WaveAcc,3) + DO i2 = LBOUND(InData%WaveAcc,2), UBOUND(InData%WaveAcc,2) + DO i1 = LBOUND(InData%WaveAcc,1), UBOUND(InData%WaveAcc,1) + ReKiBuf(Re_Xferred) = InData%WaveAcc(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WaveDynP) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveDynP,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveDynP,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveDynP,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveDynP,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%WaveDynP,2), UBOUND(InData%WaveDynP,2) + DO i1 = LBOUND(InData%WaveDynP,1), UBOUND(InData%WaveDynP,1) + ReKiBuf(Re_Xferred) = InData%WaveDynP(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WaveElev) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveElev,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveElev,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveElev,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveElev,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%WaveElev,2), UBOUND(InData%WaveElev,2) + DO i1 = LBOUND(InData%WaveElev,1), UBOUND(InData%WaveElev,1) + ReKiBuf(Re_Xferred) = InData%WaveElev(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + 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 END SUBROUTINE HydroDyn_PackInitOutput SUBROUTINE HydroDyn_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -2988,6 +3266,7 @@ SUBROUTINE HydroDyn_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt 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_UnPackInitOutput' @@ -3398,6 +3677,126 @@ SUBROUTINE HydroDyn_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Int_Xferred = Int_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveVel not allocated + Int_Xferred = Int_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%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) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveAcc not allocated + Int_Xferred = Int_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%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%WaveAcc.', 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) = 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 + Int_Xferred = Int_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%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%WaveDynP.', 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) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveElev not allocated + Int_Xferred = Int_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%WaveElev)) DEALLOCATE(OutData%WaveElev) + ALLOCATE(OutData%WaveElev(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveElev.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%WaveElev,2), UBOUND(OutData%WaveElev,2) + DO i1 = LBOUND(OutData%WaveElev,1), UBOUND(OutData%WaveElev,1) + OutData%WaveElev(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 + Int_Xferred = Int_Xferred + 1 + ELSE + 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 (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveTime.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WaveTime,1), UBOUND(OutData%WaveTime,1) + OutData%WaveTime(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE HydroDyn_UnPackInitOutput SUBROUTINE HydroDyn_CopyHD_ModuleMapType( SrcHD_ModuleMapTypeData, DstHD_ModuleMapTypeData, CtrlCode, ErrStat, ErrMsg ) @@ -3425,18 +3824,33 @@ SUBROUTINE HydroDyn_CopyHD_ModuleMapType( SrcHD_ModuleMapTypeData, DstHD_ModuleM IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE HydroDyn_CopyHD_ModuleMapType - SUBROUTINE HydroDyn_DestroyHD_ModuleMapType( HD_ModuleMapTypeData, ErrStat, ErrMsg ) + SUBROUTINE HydroDyn_DestroyHD_ModuleMapType( HD_ModuleMapTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(HD_ModuleMapType), INTENT(INOUT) :: HD_ModuleMapTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyHD_ModuleMapType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyHD_ModuleMapType' + ErrStat = ErrID_None 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 ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroymeshmaptype( HD_ModuleMapTypeData%uW_P_2_PRP_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( HD_ModuleMapTypeData%W_P_2_PRP_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( HD_ModuleMapTypeData%M_P_2_PRP_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE HydroDyn_DestroyHD_ModuleMapType SUBROUTINE HydroDyn_PackHD_ModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -3842,29 +4256,45 @@ SUBROUTINE HydroDyn_CopyContState( SrcContStateData, DstContStateData, CtrlCode, IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE HydroDyn_CopyContState - SUBROUTINE HydroDyn_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE HydroDyn_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(HydroDyn_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%WAMIT)) THEN DO i1 = LBOUND(ContStateData%WAMIT,1), UBOUND(ContStateData%WAMIT,1) - CALL WAMIT_DestroyContState( ContStateData%WAMIT(i1), ErrStat, ErrMsg ) + CALL WAMIT_DestroyContState( ContStateData%WAMIT(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) 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 ) + CALL WAMIT2_DestroyContState( ContStateData%WAMIT2(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ContStateData%WAMIT2) ENDIF - CALL Waves2_DestroyContState( ContStateData%Waves2, ErrStat, ErrMsg ) - CALL Morison_DestroyContState( ContStateData%Morison, ErrStat, ErrMsg ) + CALL Waves2_DestroyContState( ContStateData%Waves2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Morison_DestroyContState( ContStateData%Morison, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE HydroDyn_DestroyContState SUBROUTINE HydroDyn_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -4426,29 +4856,45 @@ SUBROUTINE HydroDyn_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE HydroDyn_CopyDiscState - SUBROUTINE HydroDyn_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE HydroDyn_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(HydroDyn_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(DiscStateData%WAMIT)) THEN DO i1 = LBOUND(DiscStateData%WAMIT,1), UBOUND(DiscStateData%WAMIT,1) - CALL WAMIT_DestroyDiscState( DiscStateData%WAMIT(i1), ErrStat, ErrMsg ) + CALL WAMIT_DestroyDiscState( DiscStateData%WAMIT(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) 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 ) + CALL WAMIT2_DestroyDiscState( DiscStateData%WAMIT2(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(DiscStateData%WAMIT2) ENDIF - CALL Waves2_DestroyDiscState( DiscStateData%Waves2, ErrStat, ErrMsg ) - CALL Morison_DestroyDiscState( DiscStateData%Morison, ErrStat, ErrMsg ) + CALL Waves2_DestroyDiscState( DiscStateData%Waves2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Morison_DestroyDiscState( DiscStateData%Morison, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE HydroDyn_DestroyDiscState SUBROUTINE HydroDyn_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -4983,19 +5429,35 @@ SUBROUTINE HydroDyn_CopyConstrState( SrcConstrStateData, DstConstrStateData, Ctr IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE HydroDyn_CopyConstrState - SUBROUTINE HydroDyn_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE HydroDyn_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(HydroDyn_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" - CALL WAMIT_DestroyConstrState( ConstrStateData%WAMIT, ErrStat, ErrMsg ) - CALL WAMIT2_DestroyConstrState( ConstrStateData%WAMIT2, ErrStat, ErrMsg ) - CALL Waves2_DestroyConstrState( ConstrStateData%Waves2, ErrStat, ErrMsg ) - CALL Morison_DestroyConstrState( ConstrStateData%Morison, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL WAMIT_DestroyConstrState( ConstrStateData%WAMIT, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL WAMIT2_DestroyConstrState( ConstrStateData%WAMIT2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Waves2_DestroyConstrState( ConstrStateData%Waves2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Morison_DestroyConstrState( ConstrStateData%Morison, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE HydroDyn_DestroyConstrState SUBROUTINE HydroDyn_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -5486,29 +5948,45 @@ SUBROUTINE HydroDyn_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCo IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE HydroDyn_CopyOtherState - SUBROUTINE HydroDyn_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE HydroDyn_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(HydroDyn_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OtherStateData%WAMIT)) THEN DO i1 = LBOUND(OtherStateData%WAMIT,1), UBOUND(OtherStateData%WAMIT,1) - CALL WAMIT_DestroyOtherState( OtherStateData%WAMIT(i1), ErrStat, ErrMsg ) + CALL WAMIT_DestroyOtherState( OtherStateData%WAMIT(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) 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 ) + CALL WAMIT2_DestroyOtherState( OtherStateData%WAMIT2(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OtherStateData%WAMIT2) ENDIF - CALL Waves2_DestroyOtherState( OtherStateData%Waves2, ErrStat, ErrMsg ) - CALL Morison_DestroyOtherState( OtherStateData%Morison, ErrStat, ErrMsg ) + CALL Waves2_DestroyOtherState( OtherStateData%Waves2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Morison_DestroyOtherState( OtherStateData%Morison, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE HydroDyn_DestroyOtherState SUBROUTINE HydroDyn_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -6142,18 +6620,33 @@ SUBROUTINE HydroDyn_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMs IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE HydroDyn_CopyMisc - SUBROUTINE HydroDyn_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE HydroDyn_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(HydroDyn_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( MiscData%AllHdroOrigin, ErrStat, ErrMsg ) - CALL MeshDestroy( MiscData%MrsnMesh_position, ErrStat, ErrMsg ) - CALL HydroDyn_Destroyhd_modulemaptype( MiscData%HD_MeshMap, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( MiscData%AllHdroOrigin, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( MiscData%MrsnMesh_position, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL HydroDyn_Destroyhd_modulemaptype( MiscData%HD_MeshMap, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MiscData%F_PtfmAdd)) THEN DEALLOCATE(MiscData%F_PtfmAdd) ENDIF @@ -6162,31 +6655,38 @@ SUBROUTINE HydroDyn_DestroyMisc( MiscData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(MiscData%WAMIT)) THEN DO i1 = LBOUND(MiscData%WAMIT,1), UBOUND(MiscData%WAMIT,1) - CALL WAMIT_DestroyMisc( MiscData%WAMIT(i1), ErrStat, ErrMsg ) + CALL WAMIT_DestroyMisc( MiscData%WAMIT(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) 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 ) + CALL WAMIT2_DestroyMisc( MiscData%WAMIT2(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%WAMIT2) ENDIF - CALL Waves2_DestroyMisc( MiscData%Waves2, ErrStat, ErrMsg ) - CALL Morison_DestroyMisc( MiscData%Morison, ErrStat, ErrMsg ) + CALL Waves2_DestroyMisc( MiscData%Waves2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Morison_DestroyMisc( MiscData%Morison, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) 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 ) + CALL WAMIT_DestroyInput( MiscData%u_WAMIT(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) 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 ) + CALL WAMIT2_DestroyInput( MiscData%u_WAMIT2(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%u_WAMIT2) ENDIF - CALL Waves2_DestroyInput( MiscData%u_Waves2, ErrStat, ErrMsg ) + CALL Waves2_DestroyInput( MiscData%u_Waves2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE HydroDyn_DestroyMisc SUBROUTINE HydroDyn_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -7624,29 +8124,45 @@ SUBROUTINE HydroDyn_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, Er DstParamData%Jac_ny = SrcParamData%Jac_ny END SUBROUTINE HydroDyn_CopyParam - SUBROUTINE HydroDyn_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE HydroDyn_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(HydroDyn_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%WAMIT)) THEN DO i1 = LBOUND(ParamData%WAMIT,1), UBOUND(ParamData%WAMIT,1) - CALL WAMIT_DestroyParam( ParamData%WAMIT(i1), ErrStat, ErrMsg ) + CALL WAMIT_DestroyParam( ParamData%WAMIT(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) 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 ) + CALL WAMIT2_DestroyParam( ParamData%WAMIT2(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%WAMIT2) ENDIF - CALL Waves2_DestroyParam( ParamData%Waves2, ErrStat, ErrMsg ) - CALL Morison_DestroyParam( ParamData%Morison, ErrStat, ErrMsg ) + CALL Waves2_DestroyParam( ParamData%Waves2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Morison_DestroyParam( ParamData%Morison, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ParamData%WaveTime)) THEN DEALLOCATE(ParamData%WaveTime) ENDIF @@ -7673,7 +8189,8 @@ SUBROUTINE HydroDyn_DestroyParam( ParamData, ErrStat, ErrMsg ) 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 ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF @@ -8989,18 +9506,33 @@ SUBROUTINE HydroDyn_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, Er IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE HydroDyn_CopyInput - SUBROUTINE HydroDyn_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE HydroDyn_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(HydroDyn_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" - CALL Morison_DestroyInput( InputData%Morison, ErrStat, ErrMsg ) - CALL MeshDestroy( InputData%WAMITMesh, ErrStat, ErrMsg ) - CALL MeshDestroy( InputData%PRPMesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL Morison_DestroyInput( InputData%Morison, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%WAMITMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%PRPMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE HydroDyn_DestroyInput SUBROUTINE HydroDyn_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -9421,30 +9953,47 @@ SUBROUTINE HydroDyn_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ENDIF END SUBROUTINE HydroDyn_CopyOutput - SUBROUTINE HydroDyn_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE HydroDyn_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(HydroDyn_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'HydroDyn_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%WAMIT)) THEN DO i1 = LBOUND(OutputData%WAMIT,1), UBOUND(OutputData%WAMIT,1) - CALL WAMIT_DestroyOutput( OutputData%WAMIT(i1), ErrStat, ErrMsg ) + CALL WAMIT_DestroyOutput( OutputData%WAMIT(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) 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 ) + CALL WAMIT2_DestroyOutput( OutputData%WAMIT2(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OutputData%WAMIT2) ENDIF - CALL Waves2_DestroyOutput( OutputData%Waves2, ErrStat, ErrMsg ) - CALL Morison_DestroyOutput( OutputData%Morison, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%WAMITMesh, ErrStat, ErrMsg ) + CALL Waves2_DestroyOutput( OutputData%Waves2, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Morison_DestroyOutput( OutputData%Morison, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( OutputData%WAMITMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF diff --git a/modules/hydrodyn/src/Morison.f90 b/modules/hydrodyn/src/Morison.f90 index 36419d3ee..0d834adfa 100644 --- a/modules/hydrodyn/src/Morison.f90 +++ b/modules/hydrodyn/src/Morison.f90 @@ -2110,6 +2110,8 @@ SUBROUTINE Morison_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, In END IF END DO !J = 1, InitInp%InpJoints(I)%NConnections + + Vn = Vn*TwoPi/3.0_ReKi ! Semisphere volume is Vn = 2/3 pi \sum (r_MG^3 k) p%An_End(:,i) = An_drag Amag_drag = Dot_Product(An_drag ,An_drag) @@ -2127,7 +2129,7 @@ SUBROUTINE Morison_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, In ! 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) + p%AM_End(:,:,i) = (InitInp%Nodes(I)%JAxCa*InitInp%WtrDens/ Vmag)*matmul(v2D, transpose(v2D)) end if ! Constant part of the external hydrodynamic dynamic pressure force @@ -2245,9 +2247,11 @@ FUNCTION GetAlpha(R1,R2) 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) - + if ( EqualRealNos(R1, 0.0_ReKi) .AND. EqualRealNos(R2, 0.0_ReKi) ) then ! if undefined, return 0 + GetAlpha = 0.0_ReKi + else + GetAlpha = (R1*R1 + 2.0*R1*R2 + 3.0*R2*R2)/4.0/(R1*R1 + R1*R2 + R2*R2) + end if END FUNCTION GetAlpha diff --git a/modules/hydrodyn/src/Morison_Output.f90 b/modules/hydrodyn/src/Morison_Output.f90 index 8c8a2b2ca..4ec1db451 100644 --- a/modules/hydrodyn/src/Morison_Output.f90 +++ b/modules/hydrodyn/src/Morison_Output.f90 @@ -36,12 +36,6 @@ MODULE Morison_Output ! (2) Array AllOuts() must be dimensioned to the value of the largest output parameter ! This code was generated by Write_ChckOutLst.m at 04-Jan-2014 12:13:30. - - ! Parameters related to output length (number of characters allowed in the output data headers): - - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 - - ! Indices for computing output channels: ! NOTES: ! (1) These parameters are in the order stored in "OutListParameters.xlsx" @@ -9016,36 +9010,9 @@ FUNCTION GetMorisonChannels ( NUserOutputs, UserOutputs, OutList, foundMask 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 + Indx = FindValidChannelIndx(UserOutputs(I), ValidParamAry) + + IF ( Indx > 0 ) THEN newFoundMask(I) = .TRUE. foundMask(I) = .TRUE. GetMorisonChannels = GetMorisonChannels + 1 diff --git a/modules/hydrodyn/src/Morison_Types.f90 b/modules/hydrodyn/src/Morison_Types.f90 index 09060ae3f..8f1ca39fd 100644 --- a/modules/hydrodyn/src/Morison_Types.f90 +++ b/modules/hydrodyn/src/Morison_Types.f90 @@ -440,15 +440,27 @@ SUBROUTINE Morison_CopyJointType( SrcJointTypeData, DstJointTypeData, CtrlCode, DstJointTypeData%ConnectionList = SrcJointTypeData%ConnectionList END SUBROUTINE Morison_CopyJointType - SUBROUTINE Morison_DestroyJointType( JointTypeData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyJointType( JointTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_JointType), INTENT(INOUT) :: JointTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyJointType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyJointType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Morison_DestroyJointType SUBROUTINE Morison_PackJointType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -612,15 +624,27 @@ SUBROUTINE Morison_CopyMemberPropType( SrcMemberPropTypeData, DstMemberPropTypeD DstMemberPropTypeData%PropThck = SrcMemberPropTypeData%PropThck END SUBROUTINE Morison_CopyMemberPropType - SUBROUTINE Morison_DestroyMemberPropType( MemberPropTypeData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyMemberPropType( MemberPropTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_MemberPropType), INTENT(INOUT) :: MemberPropTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMemberPropType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMemberPropType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Morison_DestroyMemberPropType SUBROUTINE Morison_PackMemberPropType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -763,15 +787,27 @@ SUBROUTINE Morison_CopyFilledGroupType( SrcFilledGroupTypeData, DstFilledGroupTy DstFilledGroupTypeData%FillDens = SrcFilledGroupTypeData%FillDens END SUBROUTINE Morison_CopyFilledGroupType - SUBROUTINE Morison_DestroyFilledGroupType( FilledGroupTypeData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyFilledGroupType( FilledGroupTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_FilledGroupType), INTENT(INOUT) :: FilledGroupTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyFilledGroupType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyFilledGroupType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(FilledGroupTypeData%FillMList)) THEN DEALLOCATE(FilledGroupTypeData%FillMList) ENDIF @@ -961,15 +997,27 @@ SUBROUTINE Morison_CopyCoefDpths( SrcCoefDpthsData, DstCoefDpthsData, CtrlCode, DstCoefDpthsData%DpthAxCpMG = SrcCoefDpthsData%DpthAxCpMG END SUBROUTINE Morison_CopyCoefDpths - SUBROUTINE Morison_DestroyCoefDpths( CoefDpthsData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyCoefDpths( CoefDpthsData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_CoefDpths), INTENT(INOUT) :: CoefDpthsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyCoefDpths' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyCoefDpths' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Morison_DestroyCoefDpths SUBROUTINE Morison_PackCoefDpths( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1149,15 +1197,27 @@ SUBROUTINE Morison_CopyAxialCoefType( SrcAxialCoefTypeData, DstAxialCoefTypeData DstAxialCoefTypeData%AxCp = SrcAxialCoefTypeData%AxCp END SUBROUTINE Morison_CopyAxialCoefType - SUBROUTINE Morison_DestroyAxialCoefType( AxialCoefTypeData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyAxialCoefType( AxialCoefTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_AxialCoefType), INTENT(INOUT) :: AxialCoefTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyAxialCoefType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyAxialCoefType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Morison_DestroyAxialCoefType SUBROUTINE Morison_PackAxialCoefType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1318,15 +1378,27 @@ SUBROUTINE Morison_CopyMemberInputType( SrcMemberInputTypeData, DstMemberInputTy DstMemberInputTypeData%dl = SrcMemberInputTypeData%dl END SUBROUTINE Morison_CopyMemberInputType - SUBROUTINE Morison_DestroyMemberInputType( MemberInputTypeData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyMemberInputType( MemberInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_MemberInputType), INTENT(INOUT) :: MemberInputTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMemberInputType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMemberInputType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MemberInputTypeData%NodeIndx)) THEN DEALLOCATE(MemberInputTypeData%NodeIndx) ENDIF @@ -1577,15 +1649,27 @@ SUBROUTINE Morison_CopyNodeType( SrcNodeTypeData, DstNodeTypeData, CtrlCode, Err DstNodeTypeData%MGdensity = SrcNodeTypeData%MGdensity END SUBROUTINE Morison_CopyNodeType - SUBROUTINE Morison_DestroyNodeType( NodeTypeData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyNodeType( NodeTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_NodeType), INTENT(INOUT) :: NodeTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyNodeType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyNodeType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Morison_DestroyNodeType SUBROUTINE Morison_PackNodeType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2243,15 +2327,27 @@ SUBROUTINE Morison_CopyMemberType( SrcMemberTypeData, DstMemberTypeData, CtrlCod DstMemberTypeData%Flipped = SrcMemberTypeData%Flipped END SUBROUTINE Morison_CopyMemberType - SUBROUTINE Morison_DestroyMemberType( MemberTypeData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyMemberType( MemberTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_MemberType), INTENT(INOUT) :: MemberTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMemberType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMemberType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MemberTypeData%NodeIndx)) THEN DEALLOCATE(MemberTypeData%NodeIndx) ENDIF @@ -4207,15 +4303,27 @@ SUBROUTINE Morison_CopyMemberLoads( SrcMemberLoadsData, DstMemberLoadsData, Ctrl ENDIF END SUBROUTINE Morison_CopyMemberLoads - SUBROUTINE Morison_DestroyMemberLoads( MemberLoadsData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyMemberLoads( MemberLoadsData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_MemberLoads), INTENT(INOUT) :: MemberLoadsData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMemberLoads' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMemberLoads' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MemberLoadsData%F_D)) THEN DEALLOCATE(MemberLoadsData%F_D) ENDIF @@ -4914,15 +5022,27 @@ SUBROUTINE Morison_CopyCoefMembers( SrcCoefMembersData, DstCoefMembersData, Ctrl DstCoefMembersData%MemberAxCpMG2 = SrcCoefMembersData%MemberAxCpMG2 END SUBROUTINE Morison_CopyCoefMembers - SUBROUTINE Morison_DestroyCoefMembers( CoefMembersData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyCoefMembers( CoefMembersData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_CoefMembers), INTENT(INOUT) :: CoefMembersData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyCoefMembers' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyCoefMembers' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Morison_DestroyCoefMembers SUBROUTINE Morison_PackCoefMembers( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -5161,15 +5281,27 @@ SUBROUTINE Morison_CopyMGDepthsType( SrcMGDepthsTypeData, DstMGDepthsTypeData, C DstMGDepthsTypeData%MGDens = SrcMGDepthsTypeData%MGDens END SUBROUTINE Morison_CopyMGDepthsType - SUBROUTINE Morison_DestroyMGDepthsType( MGDepthsTypeData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyMGDepthsType( MGDepthsTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_MGDepthsType), INTENT(INOUT) :: MGDepthsTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMGDepthsType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMGDepthsType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Morison_DestroyMGDepthsType SUBROUTINE Morison_PackMGDepthsType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -5371,15 +5503,27 @@ SUBROUTINE Morison_CopyMOutput( SrcMOutputData, DstMOutputData, CtrlCode, ErrSta ENDIF END SUBROUTINE Morison_CopyMOutput - SUBROUTINE Morison_DestroyMOutput( MOutputData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyMOutput( MOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_MOutput), INTENT(INOUT) :: MOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MOutputData%NodeLocs)) THEN DEALLOCATE(MOutputData%NodeLocs) ENDIF @@ -5754,15 +5898,27 @@ SUBROUTINE Morison_CopyJOutput( SrcJOutputData, DstJOutputData, CtrlCode, ErrSta DstJOutputData%JointIDIndx = SrcJOutputData%JointIDIndx END SUBROUTINE Morison_CopyJOutput - SUBROUTINE Morison_DestroyJOutput( JOutputData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyJOutput( JOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_JOutput), INTENT(INOUT) :: JOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyJOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyJOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Morison_DestroyJOutput SUBROUTINE Morison_PackJOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -6183,78 +6339,101 @@ SUBROUTINE Morison_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ENDIF END SUBROUTINE Morison_CopyInitInput - SUBROUTINE Morison_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%InpJoints)) THEN DO i1 = LBOUND(InitInputData%InpJoints,1), UBOUND(InitInputData%InpJoints,1) - CALL Morison_Destroyjointtype( InitInputData%InpJoints(i1), ErrStat, ErrMsg ) + CALL Morison_Destroyjointtype( InitInputData%InpJoints(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%InpJoints) ENDIF IF (ALLOCATED(InitInputData%Nodes)) THEN DO i1 = LBOUND(InitInputData%Nodes,1), UBOUND(InitInputData%Nodes,1) - CALL Morison_Destroynodetype( InitInputData%Nodes(i1), ErrStat, ErrMsg ) + CALL Morison_Destroynodetype( InitInputData%Nodes(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%Nodes) ENDIF IF (ALLOCATED(InitInputData%AxialCoefs)) THEN DO i1 = LBOUND(InitInputData%AxialCoefs,1), UBOUND(InitInputData%AxialCoefs,1) - CALL Morison_Destroyaxialcoeftype( InitInputData%AxialCoefs(i1), ErrStat, ErrMsg ) + CALL Morison_Destroyaxialcoeftype( InitInputData%AxialCoefs(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%AxialCoefs) ENDIF IF (ALLOCATED(InitInputData%MPropSets)) THEN DO i1 = LBOUND(InitInputData%MPropSets,1), UBOUND(InitInputData%MPropSets,1) - CALL Morison_Destroymemberproptype( InitInputData%MPropSets(i1), ErrStat, ErrMsg ) + CALL Morison_Destroymemberproptype( InitInputData%MPropSets(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%MPropSets) ENDIF IF (ALLOCATED(InitInputData%CoefDpths)) THEN DO i1 = LBOUND(InitInputData%CoefDpths,1), UBOUND(InitInputData%CoefDpths,1) - CALL Morison_Destroycoefdpths( InitInputData%CoefDpths(i1), ErrStat, ErrMsg ) + CALL Morison_Destroycoefdpths( InitInputData%CoefDpths(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%CoefDpths) ENDIF IF (ALLOCATED(InitInputData%CoefMembers)) THEN DO i1 = LBOUND(InitInputData%CoefMembers,1), UBOUND(InitInputData%CoefMembers,1) - CALL Morison_Destroycoefmembers( InitInputData%CoefMembers(i1), ErrStat, ErrMsg ) + CALL Morison_Destroycoefmembers( InitInputData%CoefMembers(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%CoefMembers) ENDIF IF (ALLOCATED(InitInputData%InpMembers)) THEN DO i1 = LBOUND(InitInputData%InpMembers,1), UBOUND(InitInputData%InpMembers,1) - CALL Morison_Destroymemberinputtype( InitInputData%InpMembers(i1), ErrStat, ErrMsg ) + CALL Morison_Destroymemberinputtype( InitInputData%InpMembers(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%InpMembers) ENDIF IF (ALLOCATED(InitInputData%FilledGroups)) THEN DO i1 = LBOUND(InitInputData%FilledGroups,1), UBOUND(InitInputData%FilledGroups,1) - CALL Morison_Destroyfilledgrouptype( InitInputData%FilledGroups(i1), ErrStat, ErrMsg ) + CALL Morison_Destroyfilledgrouptype( InitInputData%FilledGroups(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%FilledGroups) ENDIF IF (ALLOCATED(InitInputData%MGDepths)) THEN DO i1 = LBOUND(InitInputData%MGDepths,1), UBOUND(InitInputData%MGDepths,1) - CALL Morison_Destroymgdepthstype( InitInputData%MGDepths(i1), ErrStat, ErrMsg ) + CALL Morison_Destroymgdepthstype( InitInputData%MGDepths(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%MGDepths) ENDIF IF (ALLOCATED(InitInputData%MOutLst)) THEN DO i1 = LBOUND(InitInputData%MOutLst,1), UBOUND(InitInputData%MOutLst,1) - CALL Morison_Destroymoutput( InitInputData%MOutLst(i1), ErrStat, ErrMsg ) + CALL Morison_Destroymoutput( InitInputData%MOutLst(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%MOutLst) ENDIF IF (ALLOCATED(InitInputData%JOutLst)) THEN DO i1 = LBOUND(InitInputData%JOutLst,1), UBOUND(InitInputData%JOutLst,1) - CALL Morison_Destroyjoutput( InitInputData%JOutLst(i1), ErrStat, ErrMsg ) + CALL Morison_Destroyjoutput( InitInputData%JOutLst(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitInputData%JOutLst) ENDIF @@ -8222,15 +8401,27 @@ SUBROUTINE Morison_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCod ENDIF END SUBROUTINE Morison_CopyInitOutput - SUBROUTINE Morison_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF @@ -8433,15 +8624,27 @@ SUBROUTINE Morison_CopyContState( SrcContStateData, DstContStateData, CtrlCode, DstContStateData%DummyContState = SrcContStateData%DummyContState END SUBROUTINE Morison_CopyContState - SUBROUTINE Morison_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Morison_DestroyContState SUBROUTINE Morison_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -8558,15 +8761,27 @@ SUBROUTINE Morison_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE Morison_CopyDiscState - SUBROUTINE Morison_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Morison_DestroyDiscState SUBROUTINE Morison_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -8683,15 +8898,27 @@ SUBROUTINE Morison_CopyConstrState( SrcConstrStateData, DstConstrStateData, Ctrl DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE Morison_CopyConstrState - SUBROUTINE Morison_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Morison_DestroyConstrState SUBROUTINE Morison_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -8808,15 +9035,27 @@ SUBROUTINE Morison_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCod DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState END SUBROUTINE Morison_CopyOtherState - SUBROUTINE Morison_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Morison_DestroyOtherState SUBROUTINE Morison_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -9101,15 +9340,27 @@ SUBROUTINE Morison_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg DstMiscData%LastIndWave = SrcMiscData%LastIndWave END SUBROUTINE Morison_CopyMisc - SUBROUTINE Morison_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%FV)) THEN DEALLOCATE(MiscData%FV) ENDIF @@ -9127,7 +9378,8 @@ SUBROUTINE Morison_DestroyMisc( MiscData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(MiscData%memberLoads)) THEN DO i1 = LBOUND(MiscData%memberLoads,1), UBOUND(MiscData%memberLoads,1) - CALL Morison_Destroymemberloads( MiscData%memberLoads(i1), ErrStat, ErrMsg ) + CALL Morison_Destroymemberloads( MiscData%memberLoads(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%memberLoads) ENDIF @@ -10150,18 +10402,31 @@ SUBROUTINE Morison_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, Err DstParamData%Delim = SrcParamData%Delim END SUBROUTINE Morison_CopyParam - SUBROUTINE Morison_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%Members)) THEN DO i1 = LBOUND(ParamData%Members,1), UBOUND(ParamData%Members,1) - CALL Morison_Destroymembertype( ParamData%Members(i1), ErrStat, ErrMsg ) + CALL Morison_Destroymembertype( ParamData%Members(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%Members) ENDIF @@ -10203,19 +10468,22 @@ SUBROUTINE Morison_DestroyParam( ParamData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(ParamData%MOutLst)) THEN DO i1 = LBOUND(ParamData%MOutLst,1), UBOUND(ParamData%MOutLst,1) - CALL Morison_Destroymoutput( ParamData%MOutLst(i1), ErrStat, ErrMsg ) + CALL Morison_Destroymoutput( ParamData%MOutLst(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%MOutLst) ENDIF IF (ALLOCATED(ParamData%JOutLst)) THEN DO i1 = LBOUND(ParamData%JOutLst,1), UBOUND(ParamData%JOutLst,1) - CALL Morison_Destroyjoutput( ParamData%JOutLst(i1), ErrStat, ErrMsg ) + CALL Morison_Destroyjoutput( ParamData%JOutLst(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%JOutLst) 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 ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF @@ -11504,16 +11772,29 @@ SUBROUTINE Morison_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, Err IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE Morison_CopyInput - SUBROUTINE Morison_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( InputData%Mesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( InputData%Mesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE Morison_DestroyInput SUBROUTINE Morison_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -11726,16 +12007,29 @@ SUBROUTINE Morison_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ENDIF END SUBROUTINE Morison_CopyOutput - SUBROUTINE Morison_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE Morison_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Morison_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Morison_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( OutputData%Mesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( OutputData%Mesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF diff --git a/modules/hydrodyn/src/SS_Excitation_Types.f90 b/modules/hydrodyn/src/SS_Excitation_Types.f90 index 1dbef8c91..df75e5077 100644 --- a/modules/hydrodyn/src/SS_Excitation_Types.f90 +++ b/modules/hydrodyn/src/SS_Excitation_Types.f90 @@ -161,15 +161,27 @@ SUBROUTINE SS_Exc_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, E ENDIF END SUBROUTINE SS_Exc_CopyInitInput - SUBROUTINE SS_Exc_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE SS_Exc_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Exc_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%PtfmRefztRot)) THEN DEALLOCATE(InitInputData%PtfmRefztRot) ENDIF @@ -454,15 +466,27 @@ SUBROUTINE SS_Exc_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode ENDIF END SUBROUTINE SS_Exc_CopyInitOutput - SUBROUTINE SS_Exc_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE SS_Exc_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Exc_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF @@ -677,15 +701,27 @@ SUBROUTINE SS_Exc_CopyContState( SrcContStateData, DstContStateData, CtrlCode, E ENDIF END SUBROUTINE SS_Exc_CopyContState - SUBROUTINE SS_Exc_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE SS_Exc_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Exc_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%x)) THEN DEALLOCATE(ContStateData%x) ENDIF @@ -839,15 +875,27 @@ SUBROUTINE SS_Exc_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, E DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE SS_Exc_CopyDiscState - SUBROUTINE SS_Exc_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE SS_Exc_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Exc_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SS_Exc_DestroyDiscState SUBROUTINE SS_Exc_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -964,15 +1012,27 @@ SUBROUTINE SS_Exc_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlC DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE SS_Exc_CopyConstrState - SUBROUTINE SS_Exc_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE SS_Exc_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Exc_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SS_Exc_DestroyConstrState SUBROUTINE SS_Exc_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1095,17 +1155,30 @@ SUBROUTINE SS_Exc_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode ENDDO END SUBROUTINE SS_Exc_CopyOtherState - SUBROUTINE SS_Exc_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE SS_Exc_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Exc_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(OtherStateData%xdot,1), UBOUND(OtherStateData%xdot,1) - CALL SS_Exc_DestroyContState( OtherStateData%xdot(i1), ErrStat, ErrMsg ) + CALL SS_Exc_DestroyContState( OtherStateData%xdot(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO END SUBROUTINE SS_Exc_DestroyOtherState @@ -1318,15 +1391,27 @@ SUBROUTINE SS_Exc_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg DstMiscData%LastIndWave = SrcMiscData%LastIndWave END SUBROUTINE SS_Exc_CopyMisc - SUBROUTINE SS_Exc_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE SS_Exc_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Exc_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SS_Exc_DestroyMisc SUBROUTINE SS_Exc_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1514,15 +1599,27 @@ SUBROUTINE SS_Exc_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrM ENDIF END SUBROUTINE SS_Exc_CopyParam - SUBROUTINE SS_Exc_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE SS_Exc_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Exc_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%A)) THEN DEALLOCATE(ParamData%A) ENDIF @@ -1897,15 +1994,27 @@ SUBROUTINE SS_Exc_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrM DstInputData%DummyInput = SrcInputData%DummyInput END SUBROUTINE SS_Exc_CopyInput - SUBROUTINE SS_Exc_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE SS_Exc_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Exc_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SS_Exc_DestroyInput SUBROUTINE SS_Exc_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2046,15 +2155,27 @@ SUBROUTINE SS_Exc_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, E ENDIF END SUBROUTINE SS_Exc_CopyOutput - SUBROUTINE SS_Exc_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE SS_Exc_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Exc_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Exc_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%y)) THEN DEALLOCATE(OutputData%y) ENDIF diff --git a/modules/hydrodyn/src/SS_Radiation_Types.f90 b/modules/hydrodyn/src/SS_Radiation_Types.f90 index 9b26c59a7..dcea3022a 100644 --- a/modules/hydrodyn/src/SS_Radiation_Types.f90 +++ b/modules/hydrodyn/src/SS_Radiation_Types.f90 @@ -140,15 +140,27 @@ SUBROUTINE SS_Rad_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, E ENDIF END SUBROUTINE SS_Rad_CopyInitInput - SUBROUTINE SS_Rad_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE SS_Rad_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Rad_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%enabledDOFs)) THEN DEALLOCATE(InitInputData%enabledDOFs) ENDIF @@ -382,15 +394,27 @@ SUBROUTINE SS_Rad_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode ENDIF END SUBROUTINE SS_Rad_CopyInitOutput - SUBROUTINE SS_Rad_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE SS_Rad_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Rad_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF @@ -605,15 +629,27 @@ SUBROUTINE SS_Rad_CopyContState( SrcContStateData, DstContStateData, CtrlCode, E ENDIF END SUBROUTINE SS_Rad_CopyContState - SUBROUTINE SS_Rad_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE SS_Rad_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Rad_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%x)) THEN DEALLOCATE(ContStateData%x) ENDIF @@ -767,15 +803,27 @@ SUBROUTINE SS_Rad_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, E DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE SS_Rad_CopyDiscState - SUBROUTINE SS_Rad_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE SS_Rad_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Rad_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SS_Rad_DestroyDiscState SUBROUTINE SS_Rad_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -892,15 +940,27 @@ SUBROUTINE SS_Rad_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlC DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE SS_Rad_CopyConstrState - SUBROUTINE SS_Rad_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE SS_Rad_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Rad_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SS_Rad_DestroyConstrState SUBROUTINE SS_Rad_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1023,17 +1083,30 @@ SUBROUTINE SS_Rad_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode ENDDO END SUBROUTINE SS_Rad_CopyOtherState - SUBROUTINE SS_Rad_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE SS_Rad_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Rad_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(OtherStateData%xdot,1), UBOUND(OtherStateData%xdot,1) - CALL SS_Rad_DestroyContState( OtherStateData%xdot(i1), ErrStat, ErrMsg ) + CALL SS_Rad_DestroyContState( OtherStateData%xdot(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO END SUBROUTINE SS_Rad_DestroyOtherState @@ -1246,15 +1319,27 @@ SUBROUTINE SS_Rad_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg DstMiscData%DummyMiscVar = SrcMiscData%DummyMiscVar END SUBROUTINE SS_Rad_CopyMisc - SUBROUTINE SS_Rad_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE SS_Rad_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Rad_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SS_Rad_DestroyMisc SUBROUTINE SS_Rad_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1429,15 +1514,27 @@ SUBROUTINE SS_Rad_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrM DstParamData%NBody = SrcParamData%NBody END SUBROUTINE SS_Rad_CopyParam - SUBROUTINE SS_Rad_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE SS_Rad_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Rad_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%A)) THEN DEALLOCATE(ParamData%A) ENDIF @@ -1772,15 +1869,27 @@ SUBROUTINE SS_Rad_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrM ENDIF END SUBROUTINE SS_Rad_CopyInput - SUBROUTINE SS_Rad_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE SS_Rad_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Rad_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%dq)) THEN DEALLOCATE(InputData%dq) ENDIF @@ -1958,15 +2067,27 @@ SUBROUTINE SS_Rad_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, E ENDIF END SUBROUTINE SS_Rad_CopyOutput - SUBROUTINE SS_Rad_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE SS_Rad_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SS_Rad_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SS_Rad_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%y)) THEN DEALLOCATE(OutputData%y) ENDIF diff --git a/modules/hydrodyn/src/UserWaves.f90 b/modules/hydrodyn/src/UserWaves.f90 index a979b5df9..4689ba243 100644 --- a/modules/hydrodyn/src/UserWaves.f90 +++ b/modules/hydrodyn/src/UserWaves.f90 @@ -944,7 +944,7 @@ FUNCTION ExtractFields(FU, s, n) result(OK) CHARACTER(*), INTENT(OUT) :: s(n) !< Fields LOGICAL :: OK ! Local var - CHARACTER(2048) :: TextLine !< One line of text read from the file + CHARACTER(65536) :: TextLine !< One line of text read from the file OK=.TRUE. ! Read line diff --git a/modules/hydrodyn/src/WAMIT2.f90 b/modules/hydrodyn/src/WAMIT2.f90 index fad0873ce..47653312a 100644 --- a/modules/hydrodyn/src/WAMIT2.f90 +++ b/modules/hydrodyn/src/WAMIT2.f90 @@ -729,7 +729,7 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini !---------------------------------------------------------------------- !> 6. Set zero values for unused outputs. This is mostly so that the - !! compiler does not complain. + !! compiler does not complain. Also set misc vars !---------------------------------------------------------------------- x%DummyContState = 0.0_SiKi xd%DummyDiscState = 0.0_SiKi @@ -737,6 +737,8 @@ SUBROUTINE WAMIT2_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Ini CALL AllocAry( m%LastIndWave, p%NBody, 'm%LastIndWave', ErrStatTmp, ErrMsgTmp) CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) m%LastIndWave = 1_IntKi + call AllocAry(m%F_Waves2, 6*p%NBody, 'm%F_Waves2', ErrStatTmp, ErrMsgTmp) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, RoutineName) OtherState%DummyOtherState = 0 @@ -816,14 +818,14 @@ SUBROUTINE MnDrift_InitCalc( InitInp, p, MnDriftData, MnDriftForce, ErrMsg, ErrS ! Local Variables CHARACTER(2048) :: ErrMsgTmp !< Temporary error message for calls INTEGER(IntKi) :: ErrStatTmp !< Temporary error status for calls - REAL(SiKi) :: TmpReal1 !< Temporary real - REAL(SiKi) :: TmpReal2 !< Temporary real +! REAL(SiKi) :: TmpReal1 !< Temporary real +! REAL(SiKi) :: TmpReal2 !< Temporary real LOGICAL :: TmpFlag !< Temporary logical flag 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 +! INTEGER(IntKi) :: K !< Generic counter CHARACTER(*), PARAMETER :: RoutineName = 'MnDrift_InitCalc' @@ -1337,13 +1339,13 @@ SUBROUTINE NewmanApp_InitCalc( InitInp, p, NewmanAppData, NewmanAppForce, ErrMsg CHARACTER(2048) :: ErrMsgTmp !< Temporary error message for calls INTEGER(IntKi) :: ErrStatTmp !< Temporary error status for calls REAL(SiKi) :: TmpReal1 !< Temporary real - REAL(SiKi) :: TmpReal2 !< Temporary real +! REAL(SiKi) :: TmpReal2 !< Temporary real LOGICAL :: TmpFlag !< Temporary logical flag 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 +! INTEGER(IntKi) :: K !< Generic counter TYPE(FFT_DataType) :: FFT_Data !< Temporary array for the FFT module we're using CHARACTER(*), PARAMETER :: RoutineName = 'NewmanApp_InitCalc' @@ -3091,7 +3093,7 @@ SUBROUTINE CheckInitInput( InitInp, Interval, InitOut, p, MnDriftData, NewmanApp ! Temporary Error Variables INTEGER(IntKi) :: ErrStatTmp !< Temporary variable for the local error status - CHARACTER(2048) :: ErrMsgTmp !< Temporary error message variable +! CHARACTER(2048) :: ErrMsgTmp !< Temporary error message variable CHARACTER(*), PARAMETER :: RoutineName = 'CheckInitInput' !> ## Subroutine contents @@ -4024,7 +4026,7 @@ SUBROUTINE Read_DataFile3D( InitInp, Filename3D, Data3D, ErrStat, Errmsg ) ! Now that we know how many frequencies and wave directions there are, we can allocate the array ! for saving the sorted data. - ALLOCATE( Data3D%DataSet( Data3D%NumWvFreq1, Data3D%NumWvDir1, Data3D%NumWvDir2, 6 ), STAT=ErrStatTmp ) + ALLOCATE( Data3D%DataSet( Data3D%NumWvFreq1, Data3D%NumWvDir1, Data3D%NumWvDir2, 6*Data3D%NumBodies ), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,'Cannot allocate array Data3D%DataSet to store '// & 'the sorted 3D 2nd order WAMIT data.', ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN @@ -4038,7 +4040,7 @@ SUBROUTINE Read_DataFile3D( InitInp, Filename3D, Data3D, ErrStat, Errmsg ) ENDIF ! Allocate the logical array for storing the mask for which points are valid. Set to .FALSE. - ALLOCATE( Data3D%DataMask( Data3D%NumWvFreq1, Data3D%NumWvDir1, Data3D%NumWvDir2, 6 ), STAT=ErrStatTmp ) + ALLOCATE( Data3D%DataMask( Data3D%NumWvFreq1, Data3D%NumWvDir1, Data3D%NumWvDir2, 6*Data3D%NumBodies ), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,'Cannot allocate array Data3D%DataMask to store '// & 'the sorted 3D 2nd order WAMIT data.', ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN @@ -4130,6 +4132,21 @@ SUBROUTINE Read_DataFile3D( InitInp, Filename3D, Data3D, ErrStat, Errmsg ) ! Find which force component this belongs to TmpCoord(4) = NINT(RawData3D(I,4)) + ! Check that it is a valid force component + if (TmpCoord(4) < 1 .or. TmpCoord(4) > 6*Data3D%NumBodies) then + CALL SetErrStat( ErrID_Fatal, ' Line '//TRIM(Num2Lstr(NumHeaderLines+I))//' of '//TRIM(Filename3D)// & + ' contains force component '//TRIM(Num2LStr(TmpCoord(4)))//' which is outside the expected force '// & + ' range of 1 to '//TRIM(Num2Lstr(6*Data3D%NumBodies))//' for a '//TRIM(Num2LStr(Data3D%NumBodies))// & + ' body system.', ErrStat, ErrMsg, RoutineName) + IF (ALLOCATED(RawData3D)) DEALLOCATE(RawData3D,STAT=ErrStatTmp) + IF (ALLOCATED(RawData3DTmp)) DEALLOCATE(RawData3DTmp,STAT=ErrStatTmp) + IF (ALLOCATED(TmpRealArr)) DEALLOCATE(TmpRealArr,STAT=ErrStatTmp) + IF (ALLOCATED(TmpDataRow)) DEALLOCATE(TmpDataRow,STAT=ErrStatTmp) + IF (ALLOCATED(TmpWvFreq1)) DEALLOCATE(TmpWvFreq1,STAT=ErrStatTmp) + CALL CleanUp + RETURN + endif + !> The data from the WAMIT file is non-dimensional, so we need to dimensionalize it here. This @@ -4164,7 +4181,8 @@ SUBROUTINE Read_DataFile3D( InitInp, Filename3D, Data3D, ErrStat, Errmsg ) REAL(InitInp%RhoXg * InitInp%WAMITULEN**K * RawData3D(I,8) ,SiKi)) ) THEN CALL SetErrStat( ErrID_Fatal, ' Line '//TRIM(Num2Lstr(NumHeaderLines+I))//' of '//TRIM(Filename3D)// & ' contains different values for the real and imaginary part (columns 7 and 8) than was '// & - 'given earlier in the file for the same values of wave frequency and wave direction.', & + 'given earlier in the file for the same values of wave frequency and wave direction '// & + '(force dimension = '//TRIM(Num2LStr(TmpCoord(4)))//').', & ErrStat, ErrMsg, RoutineName ) IF (ALLOCATED(TmpRealArr)) DEALLOCATE(TmpRealArr,STAT=ErrStatTmp) IF (ALLOCATED(RawData3D)) DEALLOCATE(RawData3D,STAT=ErrStatTmp) @@ -4860,7 +4878,7 @@ SUBROUTINE Read_DataFile4D( InitInp, Filename4D, Data4D, ErrStat, Errmsg ) ! Now that we know how many frequencies and wave directions there are, we can allocate the array ! for saving the sorted data. - ALLOCATE( Data4D%DataSet( Data4D%NumWvFreq1, Data4D%NumWvFreq2, Data4D%NumWvDir1, Data4D%NumWvDir2, 6 ), STAT=ErrStatTmp ) + ALLOCATE( Data4D%DataSet( Data4D%NumWvFreq1, Data4D%NumWvFreq2, Data4D%NumWvDir1, Data4D%NumWvDir2, 6*Data4D%NumBodies ), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,'Cannot allocate array Data4D%DataSet to store '// & 'the sorted 4D 2nd order WAMIT data.', ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN @@ -4875,7 +4893,7 @@ SUBROUTINE Read_DataFile4D( InitInp, Filename4D, Data4D, ErrStat, Errmsg ) ENDIF ! Allocate the logical array for storing the mask for which points are valid. Set to .FALSE. - ALLOCATE( Data4D%DataMask( Data4D%NumWvFreq1, Data4D%NumWvFreq2, Data4D%NumWvDir1, Data4D%NumWvDir2, 6 ), STAT=ErrStatTmp ) + ALLOCATE( Data4D%DataMask( Data4D%NumWvFreq1, Data4D%NumWvFreq2, Data4D%NumWvDir1, Data4D%NumWvDir2, 6*Data4D%NumBodies ), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,'Cannot allocate array Data4D%DataMask to store '// & 'the sorted 4D 2nd order WAMIT data.', ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN @@ -4988,6 +5006,21 @@ SUBROUTINE Read_DataFile4D( InitInp, Filename4D, Data4D, ErrStat, Errmsg ) ! Find which force component this belongs to TmpCoord(5) = NINT(RawData4D(I,5)) + ! Check that it is a valid force component + if (TmpCoord(5) < 1 .or. TmpCoord(5) > 6*Data4D%NumBodies) then + CALL SetErrStat( ErrID_Fatal, ' Line '//TRIM(Num2Lstr(NumHeaderLines+I))//' of '//TRIM(Filename4D)// & + ' contains force component '//TRIM(Num2LStr(TmpCoord(5)))//' which is outside the expected force '// & + ' range of 1 to '//TRIM(Num2Lstr(6*Data4D%NumBodies))//' for a '//TRIM(Num2LStr(Data4D%NumBodies))// & + ' body system.', ErrStat, ErrMsg, RoutineName) + 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 !> The data from the WAMIT file is non-dimensional, so we need to dimensionalize it here. This @@ -5022,7 +5055,8 @@ SUBROUTINE Read_DataFile4D( InitInp, Filename4D, Data4D, ErrStat, Errmsg ) REAL(InitInp%RhoXg * InitInp%WAMITULEN**K * RawData4D(I,9) ,SiKi))) THEN CALL SetErrStat( ErrID_Fatal, ' Line '//TRIM(Num2Lstr(NumHeaderLines+I))//' of '//TRIM(Filename4D)// & ' contains different values for the real and imaginary part (columns 8 and 9) than was '// & - 'given earlier in the file for the same values of wave frequency and wave direction.', & + 'given earlier in the file for the same values of wave frequency and wave direction '// & + '(force dimension = '//TRIM(Num2LStr(TmpCoord(5)))//').', & ErrStat, ErrMsg, RoutineName ) IF (ALLOCATED(RawData4D)) DEALLOCATE(RawData4D,STAT=ErrStatTmp) IF (ALLOCATED(RawData4DTmp)) DEALLOCATE(RawData4DTmp,STAT=ErrStatTmp) @@ -5266,7 +5300,7 @@ SUBROUTINE UniqueRealValues( DataArrayIn, DataArrayOut, NumUnique, ErrStat, ErrM CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about the error ! Local variables - REAL(SiKi) :: TmpReal !< Temporary real value +! REAL(SiKi) :: TmpReal !< Temporary real value INTEGER(IntKi) :: I !< Generic counter INTEGER(IntKi) :: J !< Generic counter REAL(SiKi), ALLOCATABLE :: TmpRealArray(:) !< Temporary real array @@ -5406,7 +5440,7 @@ SUBROUTINE GetFileLength(UnitDataFile, Filename, NumDataColumns, NumDataLines, N CHARACTER(1024) :: StrRead !< String containing the first word read in REAL(SiKi) :: RealRead !< Returns value of the number (if there was one), or NaN (as set by NWTC_Num) if there wasn't CHARACTER(1024) :: VarName !< Name of the variable we are trying to read from the file - CHARACTER(24) :: Words(20) !< Array of words we extract from a line. We shouldn't have more than 20. + CHARACTER(NWTC_SizeOfNumWord) :: Words(20) !< Array of words we extract from a line. We shouldn't have more than 20. INTEGER(IntKi) :: i,j,k !< simple integer counters INTEGER(IntKi) :: LineNumber !< the line I am on LOGICAL :: LineHasText !< Flag indicating if the line I just read has text. If so, it is a header line. @@ -5462,13 +5496,7 @@ SUBROUTINE GetFileLength(UnitDataFile, Filename, NumDataColumns, NumDataLines, N !> Read all the words on the line into the array called 'Words'. Only the first words will be encountered !! will be stored. The others are empty (i.e. only three words on the line, so the remaining 17 are empty). - CALL GetWords( TextLine, Words, 20 ) - - !> Cycle through and count how many are not empty. Once an empty value is encountered, all the rest should - !! be empty if GetWords worked correctly. The index of the last non-empty value is stored. - DO i=1,20 - IF (TRIM(Words(i)) .ne. '') NumWords=i - ENDDO + CALL GetWords( TextLine, Words, size(Words), NumWords ) !> Now cycle through the first 'NumWords' of non-empty values stored in 'Words'. Words should contain @@ -6020,10 +6048,10 @@ SUBROUTINE Copy_InitData4Dto3D( Data4D, Data3D, ErrStat, ErrMsg ) ! Now allocate the storage arrays - ALLOCATE( Data3D%DataSet( Data3D%NumWvFreq1, Data3D%NumWvDir1, Data3D%NumWvDir2, 6 ), STAT=ErrStatTmp ) + ALLOCATE( Data3D%DataSet( Data3D%NumWvFreq1, Data3D%NumWvDir1, Data3D%NumWvDir2, 6*Data3D%NumBodies ), STAT=ErrStatTmp ) IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,'Cannot allocate array Data3D%DataSet to store '// & 'the 3D 2nd order WAMIT data.', ErrStat,ErrMsg,RoutineName) - ALLOCATE( Data3D%DataMask( Data3D%NumWvFreq1, Data3D%NumWvDir1, Data3D%NumWvDir2, 6 ), STAT=ErrStatTmp ) + ALLOCATE( Data3D%DataMask( Data3D%NumWvFreq1, Data3D%NumWvDir1, Data3D%NumWvDir2, 6*Data3D%NumBodies ), 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,RoutineName) CALL AllocAry( Data3D%WvFreq1, Data3D%NumWvFreq1, 'Data3D WvFreq array', ErrStatTmp, ErrMsgTmp ) diff --git a/modules/hydrodyn/src/WAMIT2.txt b/modules/hydrodyn/src/WAMIT2.txt index 9a500b34a..992093a69 100644 --- a/modules/hydrodyn/src/WAMIT2.txt +++ b/modules/hydrodyn/src/WAMIT2.txt @@ -89,7 +89,7 @@ typedef ^ OtherStateType IntKi DummyOtherS # 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 ^ ^ ReKi F_Waves2 {6} - - "2nd order force from this timestep" - +typedef ^ ^ ReKi F_Waves2 {:} - - "2nd order force from this timestep" - diff --git a/modules/hydrodyn/src/WAMIT2_Types.f90 b/modules/hydrodyn/src/WAMIT2_Types.f90 index 27627976a..d09382e26 100644 --- a/modules/hydrodyn/src/WAMIT2_Types.f90 +++ b/modules/hydrodyn/src/WAMIT2_Types.f90 @@ -105,7 +105,7 @@ MODULE WAMIT2_Types ! ========= WAMIT2_MiscVarType ======= TYPE, PUBLIC :: WAMIT2_MiscVarType 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 [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: F_Waves2 !< 2nd order force from this timestep [-] END TYPE WAMIT2_MiscVarType ! ======================= ! ========= WAMIT2_ParameterType ======= @@ -280,15 +280,27 @@ SUBROUTINE WAMIT2_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, E DstInitInputData%WvHiCOffS = SrcInitInputData%WvHiCOffS END SUBROUTINE WAMIT2_CopyInitInput - SUBROUTINE WAMIT2_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT2_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT2_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%PtfmRefxt)) THEN DEALLOCATE(InitInputData%PtfmRefxt) ENDIF @@ -863,15 +875,27 @@ SUBROUTINE WAMIT2_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode DstInitOutputData%NULLVAL = SrcInitOutputData%NULLVAL END SUBROUTINE WAMIT2_CopyInitOutput - SUBROUTINE WAMIT2_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT2_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT2_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE WAMIT2_DestroyInitOutput SUBROUTINE WAMIT2_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -988,15 +1012,27 @@ SUBROUTINE WAMIT2_CopyContState( SrcContStateData, DstContStateData, CtrlCode, E DstContStateData%DummyContState = SrcContStateData%DummyContState END SUBROUTINE WAMIT2_CopyContState - SUBROUTINE WAMIT2_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT2_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT2_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE WAMIT2_DestroyContState SUBROUTINE WAMIT2_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1113,15 +1149,27 @@ SUBROUTINE WAMIT2_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, E DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE WAMIT2_CopyDiscState - SUBROUTINE WAMIT2_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT2_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT2_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE WAMIT2_DestroyDiscState SUBROUTINE WAMIT2_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1238,15 +1286,27 @@ SUBROUTINE WAMIT2_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlC DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE WAMIT2_CopyConstrState - SUBROUTINE WAMIT2_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT2_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT2_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE WAMIT2_DestroyConstrState SUBROUTINE WAMIT2_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1363,15 +1423,27 @@ SUBROUTINE WAMIT2_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState END SUBROUTINE WAMIT2_CopyOtherState - SUBROUTINE WAMIT2_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT2_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT2_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE WAMIT2_DestroyOtherState SUBROUTINE WAMIT2_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1498,20 +1570,46 @@ SUBROUTINE WAMIT2_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg END IF DstMiscData%LastIndWave = SrcMiscData%LastIndWave ENDIF +IF (ALLOCATED(SrcMiscData%F_Waves2)) THEN + i1_l = LBOUND(SrcMiscData%F_Waves2,1) + i1_u = UBOUND(SrcMiscData%F_Waves2,1) + IF (.NOT. ALLOCATED(DstMiscData%F_Waves2)) THEN + ALLOCATE(DstMiscData%F_Waves2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_Waves2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstMiscData%F_Waves2 = SrcMiscData%F_Waves2 +ENDIF END SUBROUTINE WAMIT2_CopyMisc - SUBROUTINE WAMIT2_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT2_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT2_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%LastIndWave)) THEN DEALLOCATE(MiscData%LastIndWave) +ENDIF +IF (ALLOCATED(MiscData%F_Waves2)) THEN + DEALLOCATE(MiscData%F_Waves2) ENDIF END SUBROUTINE WAMIT2_DestroyMisc @@ -1555,7 +1653,11 @@ SUBROUTINE WAMIT2_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 2*1 ! LastIndWave upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%LastIndWave) ! LastIndWave END IF + Int_BufSz = Int_BufSz + 1 ! F_Waves2 allocated yes/no + IF ( ALLOCATED(InData%F_Waves2) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! F_Waves2 upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%F_Waves2) ! F_Waves2 + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1598,10 +1700,21 @@ SUBROUTINE WAMIT2_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, 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 - END DO + IF ( .NOT. ALLOCATED(InData%F_Waves2) ) THEN + 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_Waves2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_Waves2,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%F_Waves2,1), UBOUND(InData%F_Waves2,1) + ReKiBuf(Re_Xferred) = InData%F_Waves2(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE WAMIT2_PackMisc SUBROUTINE WAMIT2_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1649,12 +1762,24 @@ SUBROUTINE WAMIT2_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM 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) - OutData%F_Waves2(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_Waves2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + 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_Waves2)) DEALLOCATE(OutData%F_Waves2) + ALLOCATE(OutData%F_Waves2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_Waves2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%F_Waves2,1), UBOUND(OutData%F_Waves2,1) + OutData%F_Waves2(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE WAMIT2_UnPackMisc SUBROUTINE WAMIT2_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) @@ -1735,15 +1860,27 @@ SUBROUTINE WAMIT2_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrM DstParamData%UnOutFile = SrcParamData%UnOutFile END SUBROUTINE WAMIT2_CopyParam - SUBROUTINE WAMIT2_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT2_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT2_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%WaveTime)) THEN DEALLOCATE(ParamData%WaveTime) ENDIF @@ -1752,7 +1889,8 @@ SUBROUTINE WAMIT2_DestroyParam( ParamData, ErrStat, ErrMsg ) 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 ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF @@ -2204,16 +2342,29 @@ SUBROUTINE WAMIT2_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrM IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE WAMIT2_CopyInput - SUBROUTINE WAMIT2_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT2_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT2_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( InputData%Mesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( InputData%Mesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE WAMIT2_DestroyInput SUBROUTINE WAMIT2_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2413,16 +2564,29 @@ SUBROUTINE WAMIT2_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, E IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE WAMIT2_CopyOutput - SUBROUTINE WAMIT2_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT2_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT2_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT2_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( OutputData%Mesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( OutputData%Mesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE WAMIT2_DestroyOutput SUBROUTINE WAMIT2_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) diff --git a/modules/hydrodyn/src/WAMIT_Types.f90 b/modules/hydrodyn/src/WAMIT_Types.f90 index d5f86e17d..4cdcbb6a8 100644 --- a/modules/hydrodyn/src/WAMIT_Types.f90 +++ b/modules/hydrodyn/src/WAMIT_Types.f90 @@ -339,15 +339,27 @@ SUBROUTINE WAMIT_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Er DstInitInputData%NumOuts = SrcInitInputData%NumOuts END SUBROUTINE WAMIT_CopyInitInput - SUBROUTINE WAMIT_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%PtfmVol0)) THEN DEALLOCATE(InitInputData%PtfmVol0) ENDIF @@ -369,7 +381,8 @@ SUBROUTINE WAMIT_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) IF (ALLOCATED(InitInputData%PtfmCOByt)) THEN DEALLOCATE(InitInputData%PtfmCOByt) ENDIF - CALL Conv_Rdtn_DestroyInitInput( InitInputData%Conv_Rdtn, ErrStat, ErrMsg ) + CALL Conv_Rdtn_DestroyInitInput( InitInputData%Conv_Rdtn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitInputData%WaveElev0)) THEN DEALLOCATE(InitInputData%WaveElev0) ENDIF @@ -1133,15 +1146,27 @@ SUBROUTINE WAMIT_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, DstInitOutputData%NULLVAL = SrcInitOutputData%NULLVAL END SUBROUTINE WAMIT_CopyInitOutput - SUBROUTINE WAMIT_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE WAMIT_DestroyInitOutput SUBROUTINE WAMIT_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1266,18 +1291,33 @@ SUBROUTINE WAMIT_CopyContState( SrcContStateData, DstContStateData, CtrlCode, Er IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE WAMIT_CopyContState - SUBROUTINE WAMIT_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" - CALL SS_Rad_DestroyContState( ContStateData%SS_Rdtn, ErrStat, ErrMsg ) - CALL SS_Exc_DestroyContState( ContStateData%SS_Exctn, ErrStat, ErrMsg ) - CALL Conv_Rdtn_DestroyContState( ContStateData%Conv_Rdtn, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL SS_Rad_DestroyContState( ContStateData%SS_Rdtn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SS_Exc_DestroyContState( ContStateData%SS_Exctn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Conv_Rdtn_DestroyContState( ContStateData%Conv_Rdtn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE WAMIT_DestroyContState SUBROUTINE WAMIT_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1653,18 +1693,33 @@ SUBROUTINE WAMIT_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, Er IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE WAMIT_CopyDiscState - SUBROUTINE WAMIT_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" - CALL Conv_Rdtn_DestroyDiscState( DiscStateData%Conv_Rdtn, ErrStat, ErrMsg ) - CALL SS_Rad_DestroyDiscState( DiscStateData%SS_Rdtn, ErrStat, ErrMsg ) - CALL SS_Exc_DestroyDiscState( DiscStateData%SS_Exctn, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL Conv_Rdtn_DestroyDiscState( DiscStateData%Conv_Rdtn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SS_Rad_DestroyDiscState( DiscStateData%SS_Rdtn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SS_Exc_DestroyDiscState( DiscStateData%SS_Exctn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE WAMIT_DestroyDiscState SUBROUTINE WAMIT_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2040,18 +2095,33 @@ SUBROUTINE WAMIT_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCo IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE WAMIT_CopyConstrState - SUBROUTINE WAMIT_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" - CALL Conv_Rdtn_DestroyConstrState( ConstrStateData%Conv_Rdtn, ErrStat, ErrMsg ) - CALL SS_Rad_DestroyConstrState( ConstrStateData%SS_Rdtn, ErrStat, ErrMsg ) - CALL SS_Exc_DestroyConstrState( ConstrStateData%SS_Exctn, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL Conv_Rdtn_DestroyConstrState( ConstrStateData%Conv_Rdtn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SS_Rad_DestroyConstrState( ConstrStateData%SS_Rdtn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SS_Exc_DestroyConstrState( ConstrStateData%SS_Exctn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE WAMIT_DestroyConstrState SUBROUTINE WAMIT_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2427,18 +2497,33 @@ SUBROUTINE WAMIT_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE WAMIT_CopyOtherState - SUBROUTINE WAMIT_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" - CALL SS_Rad_DestroyOtherState( OtherStateData%SS_Rdtn, ErrStat, ErrMsg ) - CALL SS_Exc_DestroyOtherState( OtherStateData%SS_Exctn, ErrStat, ErrMsg ) - CALL Conv_Rdtn_DestroyOtherState( OtherStateData%Conv_Rdtn, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL SS_Rad_DestroyOtherState( OtherStateData%SS_Rdtn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SS_Exc_DestroyOtherState( OtherStateData%SS_Exctn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Conv_Rdtn_DestroyOtherState( OtherStateData%Conv_Rdtn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE WAMIT_DestroyOtherState SUBROUTINE WAMIT_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2882,15 +2967,27 @@ SUBROUTINE WAMIT_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE WAMIT_CopyMisc - SUBROUTINE WAMIT_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%F_HS)) THEN DEALLOCATE(MiscData%F_HS) ENDIF @@ -2903,15 +3000,24 @@ SUBROUTINE WAMIT_DestroyMisc( MiscData, ErrStat, ErrMsg ) 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 ) - CALL SS_Exc_DestroyMisc( MiscData%SS_Exctn, ErrStat, ErrMsg ) - CALL SS_Exc_DestroyInput( MiscData%SS_Exctn_u, ErrStat, ErrMsg ) - CALL SS_Exc_DestroyOutput( MiscData%SS_Exctn_y, ErrStat, ErrMsg ) - CALL Conv_Rdtn_DestroyMisc( MiscData%Conv_Rdtn, ErrStat, ErrMsg ) - CALL Conv_Rdtn_DestroyInput( MiscData%Conv_Rdtn_u, ErrStat, ErrMsg ) - CALL Conv_Rdtn_DestroyOutput( MiscData%Conv_Rdtn_y, ErrStat, ErrMsg ) + CALL SS_Rad_DestroyMisc( MiscData%SS_Rdtn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SS_Rad_DestroyInput( MiscData%SS_Rdtn_u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SS_Rad_DestroyOutput( MiscData%SS_Rdtn_y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SS_Exc_DestroyMisc( MiscData%SS_Exctn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SS_Exc_DestroyInput( MiscData%SS_Exctn_u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SS_Exc_DestroyOutput( MiscData%SS_Exctn_y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Conv_Rdtn_DestroyMisc( MiscData%Conv_Rdtn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Conv_Rdtn_DestroyInput( MiscData%Conv_Rdtn_u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Conv_Rdtn_DestroyOutput( MiscData%Conv_Rdtn_y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE WAMIT_DestroyMisc SUBROUTINE WAMIT_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -4041,15 +4147,27 @@ SUBROUTINE WAMIT_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMs DstParamData%UnOutFile = SrcParamData%UnOutFile END SUBROUTINE WAMIT_CopyParam - SUBROUTINE WAMIT_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%F_HS_Moment_Offset)) THEN DEALLOCATE(ParamData%F_HS_Moment_Offset) ENDIF @@ -4062,12 +4180,16 @@ SUBROUTINE WAMIT_DestroyParam( ParamData, ErrStat, ErrMsg ) IF (ALLOCATED(ParamData%WaveExctn)) THEN DEALLOCATE(ParamData%WaveExctn) ENDIF - CALL Conv_Rdtn_DestroyParam( ParamData%Conv_Rdtn, ErrStat, ErrMsg ) - CALL SS_Rad_DestroyParam( ParamData%SS_Rdtn, ErrStat, ErrMsg ) - CALL SS_Exc_DestroyParam( ParamData%SS_Exctn, ErrStat, ErrMsg ) + CALL Conv_Rdtn_DestroyParam( ParamData%Conv_Rdtn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SS_Rad_DestroyParam( ParamData%SS_Rdtn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SS_Exc_DestroyParam( ParamData%SS_Exctn, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ParamData%OutParam)) THEN DO i1 = LBOUND(ParamData%OutParam,1), UBOUND(ParamData%OutParam,1) - CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF @@ -4826,16 +4948,29 @@ SUBROUTINE WAMIT_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMs IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE WAMIT_CopyInput - SUBROUTINE WAMIT_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( InputData%Mesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( InputData%Mesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE WAMIT_DestroyInput SUBROUTINE WAMIT_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -5035,16 +5170,29 @@ SUBROUTINE WAMIT_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Er IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE WAMIT_CopyOutput - SUBROUTINE WAMIT_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE WAMIT_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WAMIT_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WAMIT_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( OutputData%Mesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( OutputData%Mesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE WAMIT_DestroyOutput SUBROUTINE WAMIT_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) diff --git a/modules/hydrodyn/src/Waves.f90 b/modules/hydrodyn/src/Waves.f90 index 5358c49a4..8934278e1 100644 --- a/modules/hydrodyn/src/Waves.f90 +++ b/modules/hydrodyn/src/Waves.f90 @@ -34,6 +34,21 @@ MODULE Waves TYPE(ProgDesc), PARAMETER :: Waves_ProgDesc = ProgDesc( 'Waves', '', '' ) + + ! ..... @mhall: Public variables for hard-coded wave kinematics grid (temporary solution) ........................... + + INTEGER, PUBLIC :: WaveGrid_n = 0 !150 Number of wave kinematics grid points = nx*ny*nz + ! + !REAL(SiKi), PUBLIC :: WaveGrid_x0 = -35.0 ! first grid point in x direction + !REAL(SiKi), PUBLIC :: WaveGrid_dx = 10.0 ! step size in x direction + !INTEGER, PUBLIC :: WaveGrid_nx = 10 ! Number of wave kinematics grid points in x + ! + !REAL(SiKi), PUBLIC :: WaveGrid_y0 = -35.0 ! same for y + !REAL(SiKi), PUBLIC :: WaveGrid_dy = 35.0 + !INTEGER, PUBLIC :: WaveGrid_ny = 3 + ! + !INTEGER, PUBLIC :: WaveGrid_nz = 5 ! Number of wave kinematics grid points in z (locations decided by 1.0 - 2.0**(WaveGrid_nz-I)) + ! ..... Public Subroutines ................................................................................................... PUBLIC :: WavePkShpDefault ! Return the default value of the peak shape parameter of the incident wave spectrum @@ -1670,6 +1685,35 @@ SUBROUTINE VariousWaves_Init ( InitInp, InitOut, ErrStat, ErrMsg ) SinWaveDir=SIN(D2R*InitOut%WaveDirArr) + !-------------------------------------------------------------------------------- + !> ## Phase shift the discrete Fourier transform of wave elevations at the WRP + !> This changes the phasing of all wave kinematics and loads to reflect the turbine's + !! location in the larger farm, in the case of FAST.Farm simulations, based on + !! specified PtfmLocationX and PtfmLocationY. + + IF (InitInp%WaveFieldMod == 2) THEN ! case 2: adjust wave phases based on turbine offsets from farm origin + + CALL WrScr ( ' Adjusting incident wave kinematics for turbine offset from array origin.' ) + + DO I = 0,InitOut%NStepWave2 + + tmpComplex = CMPLX( InitOut%WaveElevC0(1,I), InitOut%WaveElevC0(2,I)) + + ! some redundant calculations with later, but insignificant + Omega = I*InitOut%WaveDOmega + WaveNmbr = WaveNumber ( Omega, InitInp%Gravity, InitInp%WtrDpth ) + + ! apply the phase shift + tmpComplex = tmpComplex * EXP( -ImagNmbr*WaveNmbr*( InitInp%PtfmLocationX*CosWaveDir(I) + InitInp%PtfmLocationY*SinWaveDir(I) )) + + ! put shifted complex amplitudes back into the array for use in the remainder of this module and other modules (Waves2, WAMIT, WAMIT2) + InitOut%WaveElevC0 (1,I) = REAL( tmpComplex) + InitOut%WaveElevC0 (2,I) = AIMAG(tmpComplex) + + END DO + END IF + + !-------------------------------------------------------------------------------- !> ## Compute IFFTs !> Compute the discrete Fourier transform of the instantaneous elevation of @@ -1781,6 +1825,28 @@ SUBROUTINE VariousWaves_Init ( InitInp, InitOut, ErrStat, ErrMsg ) END IF END DO ! J - All points where the incident wave elevations can be output + ! :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + !@mhall: hard-coding some additional wave elevation time series output for now + + !ALLOCATE ( InitOut%WaveElevMD (0:InitOut%NStepWave, WaveGrid_nx*WaveGrid_ny), STAT=ErrStatTmp ) + !IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,'Cannot allocate array InitOut%WaveElevMD.', ErrStat,ErrMsg,'VariousWaves_Init') + ! + !DO J = 1,WaveGrid_ny !y = -60.0 + 20.0*J + ! DO K = 1,WaveGrid_nx !x = -60.0 + 20.0*K + ! + ! I = (J-1)*WaveGrid_nx + K ! index of actual node + ! + ! CALL WaveElevTimeSeriesAtXY( WaveGrid_x0 + WaveGrid_dx*(K-1), WaveGrid_y0 + WaveGrid_dy*(J-1), InitOut%WaveElevMD(:,I), ErrStatTmp, ErrMsgTmp ) + ! CALL SetErrStat(ErrStatTmp,'Error occured while applying the FFT to InitOut%WaveElevMD.',ErrStat,ErrMsg,'VariousWaves_Init') + ! IF ( ErrStat >= AbortErrLev ) THEN + ! CALL CleanUp() + ! RETURN + ! END IF + ! END DO + !END DO + + ! :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + ! For creating animations of the sea surface, the WaveElevXY array is passed in with a series of x,y coordinates ! (index 1). The second index corresponds to the number of points passed in. A two dimensional time series @@ -2182,8 +2248,13 @@ SUBROUTINE Waves_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init CALL StillWaterWaves_Init( InitInp, InitOut, ErrStatTmp, ErrMsgTmp ) CALL SetErrStat(ErrStatTmp,ErrMsgTmp,ErrStat,ErrMsg,'Waves_Init') + + !@mhall: :::: ensure all arrays needed for the wave grid to MoorDyn are allocated in the WaveMod=0 case too :::: + !ALLOCATE ( InitOut%WaveElevMD (0:InitOut%NStepWave, WaveGrid_nx*WaveGrid_ny), STAT=ErrStatTmp ) + !InitOut%WaveElevMD = 0.0_DbKi ! zero it + ! ::::: end ::::: + IF ( ErrStat >= AbortErrLev ) RETURN - CASE ( 1, 2, 3, 4, 10 ) ! 1, 10: Plane progressive (regular) wave, 2: JONSWAP/Pierson-Moskowitz spectrum (irregular) wave, 3: white-noise, or 4: user-defined spectrum (irregular) wave. diff --git a/modules/hydrodyn/src/Waves.txt b/modules/hydrodyn/src/Waves.txt index 366067469..5469e8b88 100644 --- a/modules/hydrodyn/src/Waves.txt +++ b/modules/hydrodyn/src/Waves.txt @@ -51,6 +51,9 @@ typedef ^ ^ INTEGER NWaveElev typedef ^ ^ SiKi WaveElevxi {:} - - "xi-coordinates for points where the incident wave elevations can be output" (meters) typedef ^ ^ SiKi WaveElevyi {:} - - "yi-coordinates for points where the incident wave elevations can be output" (meters) typedef ^ ^ SiKi WaveElevXY {:}{:} - - "Supplied by Driver: X-Y locations for WaveElevation output (for visualization). Index 1 corresponds to X or Y coordinate. Index 2 corresponds to point number." - +typedef ^ ^ ReKi PtfmLocationX - - - "Copy of X coordinate of platform location in the wave field, used to offset/phase-shift all wave kinematics to account for location in the farm" "m" +typedef ^ ^ ReKi PtfmLocationY - - - "Copy of Y coordinate of platform location in the wave field, used to offset/phase-shift all wave kinematics to account for location in the farm" "m" +typedef ^ ^ INTEGER WaveFieldMod - - - "Wave field handling (-) (switch) 0: use individual HydroDyn inputs without adjustment, 1: adjust wave phases based on turbine offsets from farm origin" - typedef ^ ^ INTEGER NWaveKin - - - "Number of points where the incident wave kinematics will be computed" - typedef ^ ^ SiKi WaveKinxi {:} - - "xi-coordinates for points where the incident wave kinematics will be computed; these are relative to the mean sea level" (meters) typedef ^ ^ SiKi WaveKinyi {:} - - "yi-coordinates for points where the incident wave kinematics will be computed; these are relative to the mean sea level" (meters) @@ -82,6 +85,8 @@ typedef ^ ^ SiKi PWaveVel0 typedef ^ ^ SiKi WaveElev {:}{:} - - "Instantaneous elevation time-series of incident waves at each of the NWaveElev points where the incident wave elevations can be output" (meters) typedef ^ ^ SiKi WaveElev0 {:} - - "Instantaneous elevation time-series of incident waves at the platform reference point" (meters) +typedef ^ ^ SiKi WaveElevMD {:}{:} - - "Instantaneous elevation time-series of incident waves at hard coded grid for temporary use in MoorDyn" (m) + typedef ^ ^ SiKi WaveElevSeries {:}{:} - - "Instantaneous elevation time-series at each of the points given by WaveElevXY. Used for making movies of the waves. First index is the timestep. Second index is XY point number corresponding to second index of WaveElevXY." (m) typedef ^ ^ SiKi WaveTime {:} - - "Simulation times at which the instantaneous elevation of, velocity of, acceleration of, and loads associated with the incident waves are determined" (sec) diff --git a/modules/hydrodyn/src/Waves2_Output.f90 b/modules/hydrodyn/src/Waves2_Output.f90 index 817ebc727..0faee486e 100644 --- a/modules/hydrodyn/src/Waves2_Output.f90 +++ b/modules/hydrodyn/src/Waves2_Output.f90 @@ -34,7 +34,6 @@ MODULE Waves2_Output ! (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 ! Waves2 Body Forces: diff --git a/modules/hydrodyn/src/Waves2_Types.f90 b/modules/hydrodyn/src/Waves2_Types.f90 index affe3fdc4..c5c1afd7d 100644 --- a/modules/hydrodyn/src/Waves2_Types.f90 +++ b/modules/hydrodyn/src/Waves2_Types.f90 @@ -294,15 +294,27 @@ SUBROUTINE Waves2_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, E DstInitInputData%NumOutAll = SrcInitInputData%NumOutAll END SUBROUTINE Waves2_CopyInitInput - SUBROUTINE Waves2_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE Waves2_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves2_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%WaveDirArr)) THEN DEALLOCATE(InitInputData%WaveDirArr) ENDIF @@ -1145,15 +1157,27 @@ SUBROUTINE Waves2_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode ENDIF END SUBROUTINE Waves2_CopyInitOutput - SUBROUTINE Waves2_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE Waves2_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves2_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF @@ -2101,15 +2125,27 @@ SUBROUTINE Waves2_CopyContState( SrcContStateData, DstContStateData, CtrlCode, E DstContStateData%DummyContState = SrcContStateData%DummyContState END SUBROUTINE Waves2_CopyContState - SUBROUTINE Waves2_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE Waves2_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves2_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves2_DestroyContState SUBROUTINE Waves2_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2226,15 +2262,27 @@ SUBROUTINE Waves2_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, E DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE Waves2_CopyDiscState - SUBROUTINE Waves2_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE Waves2_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves2_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves2_DestroyDiscState SUBROUTINE Waves2_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2351,15 +2399,27 @@ SUBROUTINE Waves2_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlC DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE Waves2_CopyConstrState - SUBROUTINE Waves2_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE Waves2_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves2_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves2_DestroyConstrState SUBROUTINE Waves2_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2476,15 +2536,27 @@ SUBROUTINE Waves2_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState END SUBROUTINE Waves2_CopyOtherState - SUBROUTINE Waves2_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE Waves2_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves2_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves2_DestroyOtherState SUBROUTINE Waves2_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2601,15 +2673,27 @@ SUBROUTINE Waves2_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg DstMiscData%LastIndWave = SrcMiscData%LastIndWave END SUBROUTINE Waves2_CopyMisc - SUBROUTINE Waves2_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE Waves2_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves2_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves2_DestroyMisc SUBROUTINE Waves2_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2781,15 +2865,27 @@ SUBROUTINE Waves2_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrM DstParamData%UnOutFile = SrcParamData%UnOutFile END SUBROUTINE Waves2_CopyParam - SUBROUTINE Waves2_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE Waves2_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves2_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%WaveTime)) THEN DEALLOCATE(ParamData%WaveTime) ENDIF @@ -2798,7 +2894,8 @@ SUBROUTINE Waves2_DestroyParam( ParamData, ErrStat, ErrMsg ) 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 ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF @@ -3194,15 +3291,27 @@ SUBROUTINE Waves2_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrM DstInputData%DummyInput = SrcInputData%DummyInput END SUBROUTINE Waves2_CopyInput - SUBROUTINE Waves2_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE Waves2_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves2_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves2_DestroyInput SUBROUTINE Waves2_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -3331,15 +3440,27 @@ SUBROUTINE Waves2_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, E ENDIF END SUBROUTINE Waves2_CopyOutput - SUBROUTINE Waves2_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE Waves2_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves2_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves2_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF diff --git a/modules/hydrodyn/src/Waves_Types.f90 b/modules/hydrodyn/src/Waves_Types.f90 index 9b98fdc94..3c3a277d0 100644 --- a/modules/hydrodyn/src/Waves_Types.f90 +++ b/modules/hydrodyn/src/Waves_Types.f90 @@ -68,6 +68,9 @@ MODULE Waves_Types REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveElevxi !< xi-coordinates for points where the incident wave elevations can be output [(meters)] REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveElevyi !< yi-coordinates for points where the incident wave elevations can be output [(meters)] REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: WaveElevXY !< Supplied by Driver: X-Y locations for WaveElevation output (for visualization). Index 1 corresponds to X or Y coordinate. Index 2 corresponds to point number. [-] + REAL(ReKi) :: PtfmLocationX !< Copy of X coordinate of platform location in the wave field, used to offset/phase-shift all wave kinematics to account for location in the farm [m] + REAL(ReKi) :: PtfmLocationY !< Copy of Y coordinate of platform location in the wave field, used to offset/phase-shift all wave kinematics to account for location in the farm [m] + INTEGER(IntKi) :: WaveFieldMod !< Wave field handling (-) (switch) 0: use individual HydroDyn inputs without adjustment, 1: adjust wave phases based on turbine offsets from farm origin [-] INTEGER(IntKi) :: NWaveKin !< Number of points where the incident wave kinematics will be computed [-] REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveKinxi !< xi-coordinates for points where the incident wave kinematics will be computed; these are relative to the mean sea level [(meters)] REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveKinyi !< yi-coordinates for points where the incident wave kinematics will be computed; these are relative to the mean sea level [(meters)] @@ -98,6 +101,7 @@ MODULE Waves_Types REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: PWaveVel0 !< Instantaneous velocity of incident waves in the xi- (1), yi- (2), and zi- (3) directions, respectively, at the location (xi,yi,0), at each of the NWaveKin points where the incident wave kinematics will be computed (The values include both the velocity of incident waves and the velocity of current.) [(m/s)] REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: WaveElev !< Instantaneous elevation time-series of incident waves at each of the NWaveElev points where the incident wave elevations can be output [(meters)] REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveElev0 !< Instantaneous elevation time-series of incident waves at the platform reference point [(meters)] + REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: WaveElevMD !< Instantaneous elevation time-series of incident waves at hard coded grid for temporary use in MoorDyn [(m)] REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE :: WaveElevSeries !< Instantaneous elevation time-series at each of the points given by WaveElevXY. Used for making movies of the waves. First index is the timestep. Second index is XY point number corresponding to second index of WaveElevXY. [(m)] REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: WaveTime !< Simulation times at which the instantaneous elevation of, velocity of, acceleration of, and loads associated with the incident waves are determined [(sec)] REAL(DbKi) :: WaveTMax !< Analysis time for incident wave calculations; the actual analysis time may be larger than this value in order for the maintain an effecient FFT [(sec)] @@ -237,6 +241,9 @@ SUBROUTINE Waves_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Er END IF DstInitInputData%WaveElevXY = SrcInitInputData%WaveElevXY ENDIF + DstInitInputData%PtfmLocationX = SrcInitInputData%PtfmLocationX + DstInitInputData%PtfmLocationY = SrcInitInputData%PtfmLocationY + DstInitInputData%WaveFieldMod = SrcInitInputData%WaveFieldMod DstInitInputData%NWaveKin = SrcInitInputData%NWaveKin IF (ALLOCATED(SrcInitInputData%WaveKinxi)) THEN i1_l = LBOUND(SrcInitInputData%WaveKinxi,1) @@ -305,15 +312,27 @@ SUBROUTINE Waves_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Er IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE Waves_CopyInitInput - SUBROUTINE Waves_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE Waves_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%WaveElevxi)) THEN DEALLOCATE(InitInputData%WaveElevxi) ENDIF @@ -338,7 +357,8 @@ SUBROUTINE Waves_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) IF (ALLOCATED(InitInputData%CurrVyi)) THEN DEALLOCATE(InitInputData%CurrVyi) ENDIF - CALL NWTC_Library_Destroynwtc_randomnumber_parametertype( InitInputData%RNG, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroynwtc_randomnumber_parametertype( InitInputData%RNG, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE Waves_DestroyInitInput SUBROUTINE Waves_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -421,6 +441,9 @@ SUBROUTINE Waves_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Int_BufSz = Int_BufSz + 2*2 ! WaveElevXY upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WaveElevXY) ! WaveElevXY END IF + Re_BufSz = Re_BufSz + 1 ! PtfmLocationX + Re_BufSz = Re_BufSz + 1 ! PtfmLocationY + Int_BufSz = Int_BufSz + 1 ! WaveFieldMod Int_BufSz = Int_BufSz + 1 ! NWaveKin Int_BufSz = Int_BufSz + 1 ! WaveKinxi allocated yes/no IF ( ALLOCATED(InData%WaveKinxi) ) THEN @@ -616,6 +639,12 @@ SUBROUTINE Waves_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err END DO END DO END IF + ReKiBuf(Re_Xferred) = InData%PtfmLocationX + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%PtfmLocationY + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%WaveFieldMod + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NWaveKin Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%WaveKinxi) ) THEN @@ -889,6 +918,12 @@ SUBROUTINE Waves_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END DO END DO END IF + OutData%PtfmLocationX = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%PtfmLocationY = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%WaveFieldMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%NWaveKin = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveKinxi not allocated @@ -1206,6 +1241,20 @@ SUBROUTINE Waves_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, END IF DstInitOutputData%WaveElev0 = SrcInitOutputData%WaveElev0 ENDIF +IF (ALLOCATED(SrcInitOutputData%WaveElevMD)) THEN + i1_l = LBOUND(SrcInitOutputData%WaveElevMD,1) + i1_u = UBOUND(SrcInitOutputData%WaveElevMD,1) + i2_l = LBOUND(SrcInitOutputData%WaveElevMD,2) + i2_u = UBOUND(SrcInitOutputData%WaveElevMD,2) + IF (.NOT. ALLOCATED(DstInitOutputData%WaveElevMD)) THEN + ALLOCATE(DstInitOutputData%WaveElevMD(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WaveElevMD.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%WaveElevMD = SrcInitOutputData%WaveElevMD +ENDIF IF (ALLOCATED(SrcInitOutputData%WaveElevSeries)) THEN i1_l = LBOUND(SrcInitOutputData%WaveElevSeries,1) i1_u = UBOUND(SrcInitOutputData%WaveElevSeries,1) @@ -1252,15 +1301,27 @@ SUBROUTINE Waves_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, DstInitOutputData%NStepWave2 = SrcInitOutputData%NStepWave2 END SUBROUTINE Waves_CopyInitOutput - SUBROUTINE Waves_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE Waves_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WaveElevC0)) THEN DEALLOCATE(InitOutputData%WaveElevC0) ENDIF @@ -1294,6 +1355,9 @@ SUBROUTINE Waves_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) IF (ALLOCATED(InitOutputData%WaveElev0)) THEN DEALLOCATE(InitOutputData%WaveElev0) ENDIF +IF (ALLOCATED(InitOutputData%WaveElevMD)) THEN + DEALLOCATE(InitOutputData%WaveElevMD) +ENDIF IF (ALLOCATED(InitOutputData%WaveElevSeries)) THEN DEALLOCATE(InitOutputData%WaveElevSeries) ENDIF @@ -1401,6 +1465,11 @@ SUBROUTINE Waves_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Int_BufSz = Int_BufSz + 2*1 ! WaveElev0 upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WaveElev0) ! WaveElev0 END IF + Int_BufSz = Int_BufSz + 1 ! WaveElevMD allocated yes/no + IF ( ALLOCATED(InData%WaveElevMD) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! WaveElevMD upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WaveElevMD) ! WaveElevMD + END IF Int_BufSz = Int_BufSz + 1 ! WaveElevSeries allocated yes/no IF ( ALLOCATED(InData%WaveElevSeries) ) THEN Int_BufSz = Int_BufSz + 2*2 ! WaveElevSeries upper/lower bounds for each dimension @@ -1684,6 +1753,26 @@ SUBROUTINE Waves_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%WaveElevMD) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveElevMD,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveElevMD,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveElevMD,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveElevMD,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%WaveElevMD,2), UBOUND(InData%WaveElevMD,2) + DO i1 = LBOUND(InData%WaveElevMD,1), UBOUND(InData%WaveElevMD,1) + ReKiBuf(Re_Xferred) = InData%WaveElevMD(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF IF ( .NOT. ALLOCATED(InData%WaveElevSeries) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -2048,6 +2137,29 @@ SUBROUTINE Waves_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveElevMD not allocated + Int_Xferred = Int_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%WaveElevMD)) DEALLOCATE(OutData%WaveElevMD) + ALLOCATE(OutData%WaveElevMD(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveElevMD.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%WaveElevMD,2), UBOUND(OutData%WaveElevMD,2) + DO i1 = LBOUND(OutData%WaveElevMD,1), UBOUND(OutData%WaveElevMD,1) + OutData%WaveElevMD(i1,i2) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveElevSeries not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -2139,15 +2251,27 @@ SUBROUTINE Waves_CopyContState( SrcContStateData, DstContStateData, CtrlCode, Er DstContStateData%DummyContState = SrcContStateData%DummyContState END SUBROUTINE Waves_CopyContState - SUBROUTINE Waves_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE Waves_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves_DestroyContState SUBROUTINE Waves_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2264,15 +2388,27 @@ SUBROUTINE Waves_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, Er DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE Waves_CopyDiscState - SUBROUTINE Waves_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE Waves_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves_DestroyDiscState SUBROUTINE Waves_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2389,15 +2525,27 @@ SUBROUTINE Waves_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCo DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE Waves_CopyConstrState - SUBROUTINE Waves_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE Waves_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves_DestroyConstrState SUBROUTINE Waves_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2514,15 +2662,27 @@ SUBROUTINE Waves_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState END SUBROUTINE Waves_CopyOtherState - SUBROUTINE Waves_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE Waves_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves_DestroyOtherState SUBROUTINE Waves_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2639,15 +2799,27 @@ SUBROUTINE Waves_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%DummyMiscVar = SrcMiscData%DummyMiscVar END SUBROUTINE Waves_CopyMisc - SUBROUTINE Waves_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE Waves_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves_DestroyMisc SUBROUTINE Waves_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2768,15 +2940,27 @@ SUBROUTINE Waves_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMs DstParamData%WaveMultiDir = SrcParamData%WaveMultiDir END SUBROUTINE Waves_CopyParam - SUBROUTINE Waves_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE Waves_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves_DestroyParam SUBROUTINE Waves_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2913,15 +3097,27 @@ SUBROUTINE Waves_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMs DstInputData%DummyInput = SrcInputData%DummyInput END SUBROUTINE Waves_CopyInput - SUBROUTINE Waves_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE Waves_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves_DestroyInput SUBROUTINE Waves_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -3038,15 +3234,27 @@ SUBROUTINE Waves_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Er DstOutputData%DummyOutput = SrcOutputData%DummyOutput END SUBROUTINE Waves_CopyOutput - SUBROUTINE Waves_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE Waves_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Waves_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Waves_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Waves_DestroyOutput SUBROUTINE Waves_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) diff --git a/modules/icedyn/CMakeLists.txt b/modules/icedyn/CMakeLists.txt index af328a1a2..77f4d4294 100644 --- a/modules/icedyn/CMakeLists.txt +++ b/modules/icedyn/CMakeLists.txt @@ -18,11 +18,10 @@ if (GENERATE_TYPES) generate_f90_types(src/Registry_IceDyn.txt ${CMAKE_CURRENT_LIST_DIR}/src/IceDyn_Types.f90) endif() -add_library(icedynlib +add_library(icedynlib src/IceDyn.f90 src/IceDyn_Types.f90 ) - target_link_libraries(icedynlib nwtclibs) install(TARGETS icedynlib diff --git a/modules/icedyn/src/IceDyn.f90 b/modules/icedyn/src/IceDyn.f90 index 454777b03..9abd548d9 100644 --- a/modules/icedyn/src/IceDyn.f90 +++ b/modules/icedyn/src/IceDyn.f90 @@ -267,7 +267,7 @@ SUBROUTINE IceD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO ! ! Print the summary file if requested: ! IF (InputFileData%SumPrint) THEN - ! CALL IceD_PrintSum( p, OtherState, GetAdamsVals, ErrStat2, ErrMsg2 ) + ! CALL IceD_PrintSum( p, OtherState, ErrStat2, ErrMsg2 ) ! CALL CheckError( ErrStat2, ErrMsg2 ) ! IF (ErrStat >= AbortErrLev) RETURN ! END IF diff --git a/modules/icedyn/src/IceDyn_Types.f90 b/modules/icedyn/src/IceDyn_Types.f90 index 5a676fa8b..f3c98e47c 100644 --- a/modules/icedyn/src/IceDyn_Types.f90 +++ b/modules/icedyn/src/IceDyn_Types.f90 @@ -335,15 +335,27 @@ SUBROUTINE IceD_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, Err DstInputFileData%FspN = SrcInputFileData%FspN END SUBROUTINE IceD_CopyInputFile - SUBROUTINE IceD_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) + SUBROUTINE IceD_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceD_InputFile), INTENT(INOUT) :: InputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyInputFile' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyInputFile' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputFileData%LegPosX)) THEN DEALLOCATE(InputFileData%LegPosX) ENDIF @@ -870,15 +882,27 @@ SUBROUTINE IceD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Err DstInitInputData%TMax = SrcInitInputData%TMax END SUBROUTINE IceD_CopyInitInput - SUBROUTINE IceD_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE IceD_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceD_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE IceD_DestroyInitInput SUBROUTINE IceD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1061,22 +1085,35 @@ SUBROUTINE IceD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE IceD_CopyInitOutput - SUBROUTINE IceD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE IceD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceD_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN DEALLOCATE(InitOutputData%WriteOutputUnt) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE IceD_DestroyInitOutput SUBROUTINE IceD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1365,15 +1402,27 @@ SUBROUTINE IceD_CopyContState( SrcContStateData, DstContStateData, CtrlCode, Err DstContStateData%dqdt = SrcContStateData%dqdt END SUBROUTINE IceD_CopyContState - SUBROUTINE IceD_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE IceD_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceD_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE IceD_DestroyContState SUBROUTINE IceD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1495,15 +1544,27 @@ SUBROUTINE IceD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, Err DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE IceD_CopyDiscState - SUBROUTINE IceD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE IceD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceD_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE IceD_DestroyDiscState SUBROUTINE IceD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1620,15 +1681,27 @@ SUBROUTINE IceD_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCod DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE IceD_CopyConstrState - SUBROUTINE IceD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE IceD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceD_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE IceD_DestroyConstrState SUBROUTINE IceD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1803,15 +1876,27 @@ SUBROUTINE IceD_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, DstOtherStateData%n = SrcOtherStateData%n END SUBROUTINE IceD_CopyOtherState - SUBROUTINE IceD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE IceD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceD_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OtherStateData%Nc)) THEN DEALLOCATE(OtherStateData%Nc) ENDIF @@ -1823,7 +1908,8 @@ SUBROUTINE IceD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(OtherStateData%xdot)) THEN DO i1 = LBOUND(OtherStateData%xdot,1), UBOUND(OtherStateData%xdot,1) - CALL IceD_DestroyContState( OtherStateData%xdot(i1), ErrStat, ErrMsg ) + CALL IceD_DestroyContState( OtherStateData%xdot(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OtherStateData%xdot) ENDIF @@ -2204,15 +2290,27 @@ SUBROUTINE IceD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%DummyMiscVar = SrcMiscData%DummyMiscVar END SUBROUTINE IceD_CopyMisc - SUBROUTINE IceD_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE IceD_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceD_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE IceD_DestroyMisc SUBROUTINE IceD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2497,15 +2595,27 @@ SUBROUTINE IceD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%Fsp = SrcParamData%Fsp END SUBROUTINE IceD_CopyParam - SUBROUTINE IceD_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE IceD_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceD_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%OutName)) THEN DEALLOCATE(ParamData%OutName) ENDIF @@ -3282,16 +3392,29 @@ SUBROUTINE IceD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE IceD_CopyInput - SUBROUTINE IceD_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE IceD_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceD_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( InputData%PointMesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( InputData%PointMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE IceD_DestroyInput SUBROUTINE IceD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -3504,16 +3627,29 @@ SUBROUTINE IceD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Err ENDIF END SUBROUTINE IceD_CopyOutput - SUBROUTINE IceD_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE IceD_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceD_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceD_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( OutputData%PointMesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( OutputData%PointMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF diff --git a/modules/icefloe/CMakeLists.txt b/modules/icefloe/CMakeLists.txt index 12fc293ac..8bba15450 100644 --- a/modules/icefloe/CMakeLists.txt +++ b/modules/icefloe/CMakeLists.txt @@ -18,7 +18,7 @@ if (GENERATE_TYPES) generate_f90_types(src/interfaces/FAST/IceFloe_FASTRegistry.inp ${CMAKE_CURRENT_LIST_DIR}/src/icefloe/IceFloe_Types.f90) endif() -set(ICEFLOE_LIBS_SOURCES +add_library(icefloelib src/icefloe/IceFlexBase.F90 src/icefloe/IceFlexIEC.f90 src/icefloe/IceFlexISO.f90 @@ -31,17 +31,14 @@ set(ICEFLOE_LIBS_SOURCES src/icefloe/intermittentCrushing.F90 src/icefloe/lockInISO.F90 src/icefloe/randomCrushing.F90 - src/interfaces/FAST/IceFloe.f90 - src/icefloe/IceFloe_Types.f90 ) - -add_library(icefloelib ${ICEFLOE_LIBS_SOURCES}) -target_link_libraries(icefloelib nwtclibs versioninfolib) +target_link_libraries(icefloelib nwtclibs) install(TARGETS icefloelib EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION lib ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) + LIBRARY DESTINATION lib +) diff --git a/modules/icefloe/src/icefloe/IceFloe_Types.f90 b/modules/icefloe/src/icefloe/IceFloe_Types.f90 index 630cf872c..1fea1d538 100644 --- a/modules/icefloe/src/icefloe/IceFloe_Types.f90 +++ b/modules/icefloe/src/icefloe/IceFloe_Types.f90 @@ -132,15 +132,27 @@ SUBROUTINE IceFloe_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, DstInitInputData%RootName = SrcInitInputData%RootName END SUBROUTINE IceFloe_CopyInitInput - SUBROUTINE IceFloe_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE IceFloe_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceFloe_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE IceFloe_DestroyInitInput SUBROUTINE IceFloe_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -314,22 +326,35 @@ SUBROUTINE IceFloe_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCod IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE IceFloe_CopyInitOutput - SUBROUTINE IceFloe_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE IceFloe_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceFloe_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN DEALLOCATE(InitOutputData%WriteOutputUnt) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE IceFloe_DestroyInitOutput SUBROUTINE IceFloe_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -612,15 +637,27 @@ SUBROUTINE IceFloe_CopyContState( SrcContStateData, DstContStateData, CtrlCode, DstContStateData%DummyContStateVar = SrcContStateData%DummyContStateVar END SUBROUTINE IceFloe_CopyContState - SUBROUTINE IceFloe_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE IceFloe_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceFloe_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE IceFloe_DestroyContState SUBROUTINE IceFloe_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -737,15 +774,27 @@ SUBROUTINE IceFloe_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, DstDiscStateData%DummyDiscStateVar = SrcDiscStateData%DummyDiscStateVar END SUBROUTINE IceFloe_CopyDiscState - SUBROUTINE IceFloe_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE IceFloe_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceFloe_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE IceFloe_DestroyDiscState SUBROUTINE IceFloe_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -862,15 +911,27 @@ SUBROUTINE IceFloe_CopyConstrState( SrcConstrStateData, DstConstrStateData, Ctrl DstConstrStateData%DummyConstrStateVar = SrcConstrStateData%DummyConstrStateVar END SUBROUTINE IceFloe_CopyConstrState - SUBROUTINE IceFloe_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE IceFloe_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceFloe_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE IceFloe_DestroyConstrState SUBROUTINE IceFloe_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -987,15 +1048,27 @@ SUBROUTINE IceFloe_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCod DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState END SUBROUTINE IceFloe_CopyOtherState - SUBROUTINE IceFloe_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE IceFloe_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceFloe_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE IceFloe_DestroyOtherState SUBROUTINE IceFloe_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1112,15 +1185,27 @@ SUBROUTINE IceFloe_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg DstMiscData%DummyMiscVar = SrcMiscData%DummyMiscVar END SUBROUTINE IceFloe_CopyMisc - SUBROUTINE IceFloe_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE IceFloe_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceFloe_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE IceFloe_DestroyMisc SUBROUTINE IceFloe_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1303,15 +1388,27 @@ SUBROUTINE IceFloe_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, Err DstParamData%initFlag = SrcParamData%initFlag END SUBROUTINE IceFloe_CopyParam - SUBROUTINE IceFloe_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE IceFloe_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceFloe_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%loadSeries)) THEN DEALLOCATE(ParamData%loadSeries) ENDIF @@ -1676,16 +1773,29 @@ SUBROUTINE IceFloe_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, Err IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE IceFloe_CopyInput - SUBROUTINE IceFloe_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE IceFloe_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceFloe_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( InputData%iceMesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( InputData%iceMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE IceFloe_DestroyInput SUBROUTINE IceFloe_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1898,16 +2008,29 @@ SUBROUTINE IceFloe_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ENDIF END SUBROUTINE IceFloe_CopyOutput - SUBROUTINE IceFloe_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE IceFloe_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceFloe_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IceFloe_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( OutputData%iceMesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( OutputData%iceMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF diff --git a/modules/icefloe/src/interfaces/ADAMS/IceADAMS_VFOSUB.f90 b/modules/icefloe/src/interfaces/ADAMS/IceADAMS_VFOSUB.f90 deleted file mode 100644 index 74ef79182..000000000 --- a/modules/icefloe/src/interfaces/ADAMS/IceADAMS_VFOSUB.f90 +++ /dev/null @@ -1,264 +0,0 @@ -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2014 DNV KEMA Renewables, Inc. -! -! This file is part of the IceFloe suite of subroutines -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -!************************************************************************ - -!********************************************************************************************************************************** -! File last committed: $Date: 2014-01-31 09:14:28 -0800 (Fri, 31 Jan 2014) $ -! (File) Revision #: $Rev: 131 $ -! URL: $HeadURL: http://sel1004.verit.dnv.com:8080/svn/LoadSimCtl_SurfaceIce/trunk/IceDyn_IntelFortran/HAWC2_DLL/HAWC2_DLL.f90 $ -!********************************************************************************************************************************** - -module IceADAMS - - use IceLog - use IceInputParams - use iceFloeBase - use IceCrushingISO - use IceCrushingIEC - use IceIntermittentCrushing - use IceFlexISO - use IceFlexIEC - use IceLockInCrushingISO - use randomCrushing - use IceCpldCrushing - use NWTC_IO, only : DispNVD, progdesc, curdate, curtime - - type(iceFloe_ParameterType), save :: icep ! Parameters, including precalculated time series - type(iceFloe_LoggingType), save :: theIceLog ! structure with message and error logging variables - -contains -!------------------------------------------------------------------------------------ - subroutine icefloe_init() - - implicit none - - ! locals - Real(ReKi) :: duration - INTEGER(IntKi) :: nSteps - INTEGER(IntKi) :: Err ! Error status of the operation - LOGICAL, SAVE :: bInit = .FALSE. ! Initialization flag - TYPE(ProgDesc), PARAMETER :: IceFloe_Ver = ProgDesc( 'IceFloe', 'v1.00.00', 'May-2014' ) - - ! More IceFloe types - type(iceInputType) :: iceInput ! hold list of input names and values from file - character(132) :: logFile ! File name for message logging - - ! Set up error logging - theIceLog%warnFlag = .false. - theIceLog%ErrID = ErrID_None - theIceLog%ErrMsg = "" - - ! Display the module information - - CALL DispNVD( IceFloe_Ver ) - - call openIceLog(theIceLog, 'IceFloe.log') - call logMessage(theIceLog, ' Running: '//trim(IceFloe_Ver%Name)//trim(IceFloe_Ver%Ver)//trim(IceFloe_Ver%Date)) - call logMessage(theIceLog, ' This run started on: '//curdate()//' at '//curtime()//newLine) - - call countIceInputs('testIce.inp', theIceLog, iceInput) - call readIceInputs(theIceLog, iceInput) - call logMessage(theIceLog, ' Input file read complete.'//newLine) - - ! call IceFloe initialization routine and get parameters back - ! not all parameters used by all ice floe types - call getIceInput(iceInput, 'iceType',icep%iceType, theIceLog, lowTypeLimit, hiTypeLimit) - if (theIceLog%ErrID >= AbortErrLev) then - return - endif - - ! Set the time step as the minimum of the suggested p%dt and the time step from the ice input file - call getIceInput(iceInput, 'timeStep',icep%dt, theIceLog, 0.0) - if (theIceLog%ErrID >= AbortErrLev) then - return - endif - - ! get the duration of the simulation - call getIceInput(iceInput, 'duration', duration, theIceLog, 0.0) - call logMessage(theIceLog, ' Load time series duration = '//TRIM(Num2LStr(duration))//' sec') - - ! get the number of legs on the support structure - call getIceInput(iceInput, 'numLegs', icep%numLegs, theIceLog, 1, 4) - if (theIceLog%ErrID >= AbortErrLev) then - return - endif - - ! allocate storage for load series - nSteps = ceiling(duration/icep%dt) + 1 ! + 1 for zero point - allocate(icep%loadSeries(nSteps, icep%numLegs), stat=err) - if (err /= 0) then - call iceErrorHndlr (theIceLog, ErrID_Fatal, 'Error in time series array allocation in IceFloe_init', 1) - return - endif - ! point internal iceFloe array to the saved load series - ! icep%loadSeries => loadseries - - ! allocate storage for the leg positions - allocate (icep%legX(icep%numLegs), stat=err) - allocate (icep%legY(icep%numLegs), stat=err) - allocate (icep%ks(icep%numLegs), stat=err) - if (err /= 0) then - call iceErrorHndlr (theIceLog, ErrID_Fatal, 'Error in allocation of leg data in parameters', 1) - return ! error in array allocation - endif - - iceType: select case (icep%iceType) - case (randomCrush) - call initRandomCrushing(iceInput, icep, theIceLog) - if (theIceLog%ErrID <= ErrID_Warn) & - call logMessage(theIceLog, newLine//' Random continuous ice crushing via ISO/Karna initialized'//newLine) - case (interCrush) - call initInterCrushing(iceInput, icep, theIceLog) - if (theIceLog%ErrID <= ErrID_Warn) & - call logMessage(theIceLog, newLine//' Intermittent ice crushing loads initialized'//newLine) - case (crushIEC) - call initCrushingIEC(iceInput, icep, theIceLog) - if (theIceLog%ErrID <= ErrID_Warn) & - call logMessage(theIceLog, newLine//' Ice crushing loads IEC/Korzhavin initialized'//newLine) - case (flexFailISO) - call initFlexISO(iceInput, icep, theIceLog) - if (theIceLog%ErrID <= ErrID_Warn) & - call logMessage(theIceLog, newLine//' ISO/Croasdale ice flexural failure loads initialized'//newLine) - case (flexFailIEC) - call initFlexIEC(iceInput, icep, theIceLog) - if (theIceLog%ErrID <= ErrID_Warn) & - call logMessage(theIceLog, newLine//' IEC/Ralston ice flexural failure loads initialized'//newLine) - case (lockInISO) - call initLockInCrushingISO(iceInput, icep, theIceLog) - if (theIceLog%ErrID <= ErrID_Warn) & - call logMessage(theIceLog, newLine//' Frequency lock-in ice crushing loads via ISO initialized'//newLine) - case (cpldCrush) - call initCpldCrushing(iceInput, icep, theIceLog) - if (theIceLog%ErrID <= ErrID_Warn) & - call logMessage(theIceLog, newLine//' Coupled crushing ice loads (Maattanen) initialized'//newLine) - case default - call iceErrorHndlr (theIceLog, ErrID_Fatal, 'Invalid ice floe type, ' & - //TRIM(Num2LStr(icep%IceType))//' is not a valid selection', 1) - end select iceType - - end subroutine icefloe_init - -!********************************************************************************************************************************** - SUBROUTINE icefloe_update(Time, Vels, Forces) - - implicit none - ! input - real(DbKi), intent(IN) :: Time - real(ReKi), intent(IN) :: Vels(3) - ! output - real(ReKi), intent(OUT) :: Forces(3) - - real(ReKi) :: loadVect(6,icep%numLegs) - real(ReKi) :: inVels(2,icep%numLegs) - integer(IntKi) :: nL - - ! reset up error logging - theIceLog%warnFlag = .false. - theIceLog%ErrID = ErrID_None - theIceLog%ErrMsg = "" - - ! Assign support structure velocities to local variables - ! CURRENTLY only monopile supported so NL should = 1 - inVels = 0.0 - do nL = 1, icep%numLegs - inVels(1,nL) = Vels(1) - inVels(2,nL) = Vels(2) - enddo - - ! get loads from IceFloe - iceType: select case (icep%iceType) - case (randomCrush) - loadVect = outputRandomCrushLoad(icep, theIceLog, time) - case (crushIEC) - loadVect = outputCrushLoadIEC(icep, theIceLog, time) - case (interCrush) - loadVect = outputInterCrushLoad(icep, theIceLog, time) - case (flexFailISO) - loadVect = outputFlexLoadISO(icep, theIceLog, time) - case (flexFailIEC) - loadVect = outputFlexLoadIEC(icep, theIceLog, time) - case (lockInISO) - loadVect = outputLockInLoadISO(icep, theIceLog, time) - case (cpldCrush) - loadVect = outputCpldCrushLoad(icep, theIceLog, inVels, time) - case default - call logFatal (theIceLog, 'Invalid Ice Floe Type Selection', 1) - end select iceType - - !Apply ramp for first 10 seconds - do nL = 1, icep%numLegs - Forces(1) = loadVect(1,nL)*min(1.0, 0.1*time) - Forces(2) = loadVect(2,nL)*min(1.0, 0.1*time) - Forces(3) = 0.0 - enddo - - end SUBROUTINE icefloe_update - -end module IceADAMS - -!********************************************************************************************************************************** - -SUBROUTINE VFOSUB ( ID, ATIME, PAR, NPAR, DFLAG, IFLAG, Forces ) - -! This routine is used to calculate the functional values for a VFORCE statement. -! Specifically to call the IceFloe routines for use in ADAMS - - use IceADAMS - - IMPLICIT NONE - -! Passed variables: - - INTEGER(4), INTENT(IN ) :: ID ! ID of the REQUEST statement calling this routine. - INTEGER(4), INTENT(IN ) :: NPAR ! Number of PARameters passed through PAR. - - REAL(8), INTENT(IN ) :: ATIME ! The current simimulation time. - REAL(8), INTENT(IN ) :: PAR(NPAR) ! The passeed PARameters. - REAL(8), INTENT(OUT) :: Forces(3) ! Values returned to ADAMS. - - LOGICAL, INTENT(IN) :: DFLAG ! Partial Derivative flag. - LOGICAL, INTENT(IN) :: IFLAG ! Initialization pass flag. - -! Local variables - LOGICAL, save :: initFlag = .true. - logical :: errFlg - integer(4) :: IPar3(3), NStates - REAL(4) :: IceForces(3) - REAL(8) :: States(3) - -! get the local velocity at the marker specified in PAR - IPar3(1) = int(PAR(1)) - IPar3(2) = 1 ! ground marker - IPar3(3) = 1 ! ground marker - call SYSARY('TVEL', IPar3, 3, States, NStates, errFlg ) - - IceForces = 0.0 - if (IFLAG .and. initFlag) then - call icefloe_init - initFlag = .false. - endif - - if (.not. initFlag) then -! Get the ice loads - call icefloe_update(atime, real(States, 4), IceForces) - endif - - Forces = real(IceForces, 8)/1000.0 - -END SUBROUTINE VFOSUB - diff --git a/modules/icefloe/src/interfaces/Console/SysIVF_reduced.f90 b/modules/icefloe/src/interfaces/Console/SysIVF_reduced.f90 index 0c31950cc..db1d0814c 100644 --- a/modules/icefloe/src/interfaces/Console/SysIVF_reduced.f90 +++ b/modules/icefloe/src/interfaces/Console/SysIVF_reduced.f90 @@ -56,7 +56,7 @@ MODULE SysSubs INTEGER, PARAMETER :: ConRecL = 120 ! The record length for console output. - INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. Unit 6 causes ADAMS to crash. + INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. INTEGER, PARAMETER :: MaxWrScrLen = 98 ! The maximum number of characters allowed to be written to a line in WrScr INTEGER, PARAMETER :: NL_Len = 2 ! The number of characters used for a new line. @@ -128,8 +128,6 @@ SUBROUTINE FlushOut ( Unit ) CALL FLUSH ( INT(Unit, B4Ki) ) -!bjj: ADAMS does not compile well with this, so I'll put it back to the subroutine form: -! FLUSH ( Unit ) RETURN diff --git a/modules/inflowwind/CMakeLists.txt b/modules/inflowwind/CMakeLists.txt index 1dea2c8db..7e7005d9b 100644 --- a/modules/inflowwind/CMakeLists.txt +++ b/modules/inflowwind/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2016 National Renewable Energy Laboratory +# Copyright 2023 National Renewable Energy Laboratory # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,59 +15,44 @@ # if (GENERATE_TYPES) - generate_f90_types(src/InflowWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/InflowWind_Types.f90) + generate_f90_types(src/IfW_FlowField.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_FlowField_Types.f90 -noextrap) + generate_f90_types(src/InflowWind_IO.txt ${CMAKE_CURRENT_LIST_DIR}/src/InflowWind_IO_Types.f90 -noextrap) generate_f90_types(src/Lidar.txt ${CMAKE_CURRENT_LIST_DIR}/src/Lidar_Types.f90) - generate_f90_types(src/IfW_BladedFFWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_BladedFFWind_Types.f90 -noextrap) - generate_f90_types(src/IfW_4Dext.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_4Dext_Types.f90 -noextrap) - generate_f90_types(src/IfW_HAWCWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_HAWCWind_Types.f90 -noextrap) - generate_f90_types(src/IfW_TSFFWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_TSFFWind_Types.f90 -noextrap) - generate_f90_types(src/IfW_UniformWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_UniformWind_Types.f90 -noextrap) - generate_f90_types(src/IfW_UserWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_UserWind_Types.f90 -noextrap) - generate_f90_types(src/IfW_FFWind_Base.txt ${CMAKE_CURRENT_LIST_DIR}/src/IfW_FFWind_Base_Types.f90 -noextrap) + generate_f90_types(src/InflowWind.txt ${CMAKE_CURRENT_LIST_DIR}/src/InflowWind_Types.f90) endif() -set(IFW_SOURCES - src/IfW_BladedFFWind.f90 - src/IfW_4Dext.f90 - src/IfW_HAWCWind.f90 - src/IfW_TSFFWind.f90 - src/IfW_UserWind.f90 - src/IfW_UniformWind.f90 +# InflowWind object library +add_library(ifwlib + src/IfW_FlowField_Types.f90 + src/IfW_FlowField.f90 + src/InflowWind_IO_Types.f90 + src/InflowWind_IO.f90 src/InflowWind_Subs.f90 - src/InflowWind.f90 - src/Lidar.f90 - src/IfW_FFWind_Base.f90 - src/IfW_FFWind_Base_Types.f90 - src/IfW_BladedFFWind_Types.f90 - src/IfW_4Dext_Types.f90 - src/IfW_HAWCWind_Types.f90 - src/IfW_TSFFWind_Types.f90 - src/IfW_UserWind_Types.f90 - src/IfW_UniformWind_Types.f90 src/InflowWind_Types.f90 + src/InflowWind.f90 src/Lidar_Types.f90 + src/Lidar.f90 ) - -add_library(ifwlib ${IFW_SOURCES}) target_link_libraries(ifwlib nwtclibs) -# C-bound interface library -add_library(ifw_c_binding SHARED src/IfW_C_Binding.f90) +# InflowWind C-Interface Library +add_library(ifw_c_binding SHARED + src/IfW_C_Binding.f90 +) target_link_libraries(ifw_c_binding ifwlib versioninfolib) if(APPLE OR UNIX) - target_compile_definitions(ifw_c_binding PUBLIC -DIMPLICIT_DLLEXPORT) + target_compile_definitions(ifw_c_binding PRIVATE IMPLICIT_DLLEXPORT) endif() -set(IFW_DRIVER_SOURCES - src/InflowWind_Driver_Types.f90 +# InflowWind Driver executable +add_executable(inflowwind_driver + src/InflowWind_Driver_Types.f90 src/InflowWind_Driver_Subs.f90 src/InflowWind_Driver.f90 ) +target_link_libraries(inflowwind_driver ifwlib versioninfolib) -add_executable(inflowwind_driver ${IFW_DRIVER_SOURCES}) -target_link_libraries(inflowwind_driver ifwlib versioninfolib ${CMAKE_DL_LIBS}) - -install(TARGETS inflowwind_driver ifwlib ifw_c_binding +install(TARGETS ifwlib inflowwind_driver ifw_c_binding EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin LIBRARY DESTINATION lib diff --git a/modules/inflowwind/python-lib/inflowwind_library.py b/modules/inflowwind/python-lib/inflowwind_library.py index 2a2d7e74e..26e6eb599 100644 --- a/modules/inflowwind/python-lib/inflowwind_library.py +++ b/modules/inflowwind/python-lib/inflowwind_library.py @@ -255,17 +255,19 @@ def __init__(self, filename, numWindPts): t_string=datetime.datetime.now() dt_string=datetime.date.today() self.debug_file.write(f"## This file was generated by InflowWind_Driver on {dt_string.strftime('%b-%d-%Y')} at {t_string.strftime('%H:%M:%S')}{os.linesep}") - self.debug_file.write(f"## This file contains the wind velocity at the {numWindPts} points specified in the file ") - self.debug_file.write(f"{filename}{os.linesep}") - self.debug_file.write(f"#{os.linesep}") - self.debug_file.write(f"# T X Y Z U V W{os.linesep}") - self.debug_file.write(f"# (s) (m) (m) (m) (m/s) (m/s) (m/s){os.linesep}") + self.debug_file.write(f"## This file contains the wind velocity at the {numWindPts} points specified in the file {filename}{os.linesep}") + self.debug_file.write(f"# {os.linesep}") + self.debug_file.write(f"# {os.linesep}") + self.debug_file.write(f"# {os.linesep}") + self.debug_file.write(f"# {os.linesep}") + self.debug_file.write(f" T X Y Z U V W{os.linesep}") + self.debug_file.write(f" (s) (m) (m) (m) (m/s) (m/s) (m/s){os.linesep}") self.opened = True def write(self,t,positions,velocities): for p, v in zip(positions,velocities): # TODO: does \n work as expected on Windows? - self.debug_file.write(' %14.7f %14.7f %14.7f %14.7f %14.7f %14.7f %14.7f\n' % (t,p[0],p[1],p[2],v[0],v[1],v[2])) + self.debug_file.write(' %16.8f %16.8f %16.8f %16.8f %16.8f %16.8f %16.8f\n' % (t,p[0],p[1],p[2],v[0],v[1],v[2])) def end(self): if self.opened: diff --git a/modules/inflowwind/src/CTWind.f90 b/modules/inflowwind/src/CTWind.f90 deleted file mode 100644 index b0adc411c..000000000 --- a/modules/inflowwind/src/CTWind.f90 +++ /dev/null @@ -1,1345 +0,0 @@ -MODULE CTWind -! This module uses reads coherent turbulence parameter (CTP) files and processes the data in them -! to get coherent turbulence which is later superimposed on a background wind field (the super- -! positioning occurs elsewhere). The turbulence in this module is part of the KH billow, which -! can be read using FDWind. As a result, the scaling here should be similiar to FDWind. -! -! This module assumes that the origin, (0,0,0), is located at the tower centerline at ground level, -! and that all units are specified in the metric system (using meters and seconds). -! Data is shifted by half the grid width when used with FFWind. -! -! Created 25-Sept-2009 by B. Jonkman, National Renewable Energy Laboratory -! using subroutines and modules from AeroDyn v12.58 -! -! Modified Jan-2013 by A. Platt, National Renewable Energy Laboratory -! to fit the modularization framework used by FAST -! -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2013 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** -! File last committed: $Date: 2014-07-29 13:30:04 -0600 (Tue, 29 Jul 2014) $ -! (File) Revision #: $Rev: 125 $ -! URL: $HeadURL$ -!********************************************************************************************************************************** - - USE NWTC_Library - USE SharedInflowDefs - USE InflowWind_Module_Types - - IMPLICIT NONE - PRIVATE - - -!fixme: this invokes SAVE - INTEGER, PARAMETER :: NumComps = 3 ! number of components - - ! CT_Wind - REAL(ReKi) :: DelYCTgrid ! The nondimensional distance between grid points in the y direction. - REAL(ReKi) :: DelZCTgrid ! The nondimensional distance between grid points in the z direction. - REAL(ReKi) :: CTDistSc ! Disturbance scale (ratio of wave height to rotor diameter). - REAL(ReKi) :: CTOffset (NumComps) ! Offsets to convert integer data to actual wind speeds. - REAL(ReKi) :: CTScale (NumComps) ! Scaling factors to convert integer data to actual wind speeds. - - - REAL(ReKi), ALLOCATABLE :: CTvelU (:,:,:) ! The y-z grid velocity data (U components) for the lower- and upper-bound time slices - REAL(ReKi), ALLOCATABLE :: CTvelV (:,:,:) ! The y-z grid velocity data (V components) for the lower- and upper-bound time slices - REAL(ReKi), ALLOCATABLE :: CTvelW (:,:,:) ! The y-z grid velocity data (W components) for the lower- and upper-bound time slices - REAL(ReKi) :: CTLy ! Fractional location of tower centerline from right (looking downwind) to left side of the dataset. - REAL(ReKi) :: CTLz ! Fractional location of hub height from bottom to top of dataset. - REAL(ReKi) :: CTScaleVel ! Scaling velocity, U0. 2*U0 is the difference in wind speed between the top and bottom of the wave. - REAL(ReKi), ALLOCATABLE :: Tdata (:) ! The list of times for the CT-wind input files. - - REAL(ReKi) :: CT_Zref ! The reference height for the CT file (the bottom of the billow) - REAL(ReKi) :: CTYHWid ! The half the width of the background dataset, used to compute the CTwind time offset - REAL(ReKi) :: CTYmax ! The dimensional lateral width of the dataset. - REAL(ReKi) :: CTYt ! Distance of the tower from the right side of the dataset (looking downwind). - REAL(ReKi) :: CTZmax ! The dimensional vertical height of the dataset. - REAL(ReKi) :: InvMCTWS ! The multiplicative inverse of the mean hub height wind speed for the CT wind data - - INTEGER :: CT_DF_Y ! The decimation factor for the CT wind data in the y direction. - INTEGER :: CT_DF_Z ! The decimation factor for the CT wind data in the z direction. - INTEGER :: CTvel_files(2) ! Times for the CT wind files stored in CTvel arrays. - - INTEGER :: IndCT_hi ! An index into the 3rd dimension of the CTvel arrays, indicating the upper time slice (allows us to avoid copying array) - INTEGER :: IndCT_lo ! An index into the 3rd dimension of the CTvel arrays, indicating the lower time slice (allows us to avoid copying array) - - INTEGER :: NumCTt ! The number of CT wind grids, no more than one grid per time step. - INTEGER :: NumCTy ! The number of CT wind grid points in the y direction. - INTEGER :: NumCTyD ! The decimated number of CT wind grid points in the y direction. - INTEGER :: NumCTyD1 ! The decimated number of CT wind grid points in the y direction minus 1. - INTEGER :: NumCTz ! The number of CT wind grid points in the z direction. - INTEGER :: NumCTzD ! The decimated number of CT wind grid points in the z direction. - INTEGER :: NumCTzD1 ! The decimated number of CT wind grid points in the z direction minus 1. -!FIXME: move to otherstate - INTEGER, SAVE :: TimeIndx = 0 ! Index into the time array - INTEGER, ALLOCATABLE :: TimeStpCT (:) ! The list of time steps from the original LE simulation, associated with the CT-wind times. - - INTEGER :: CTWindUnit ! unit number used to read the wind files at each call to CT_GetWindSpeed() - - LOGICAL :: CTVertShft ! Flag to indicate whether or not to shift the z values for the w component. - - CHARACTER(3) :: CText ! The extension used for coherent turbulence data files. (usually "les" or "dns") - CHARACTER(1024) :: CTSpath ! The path to the CT wind files. - -!FIXME: move this to types -- parameters! - TYPE :: CTWindFiles - CHARACTER(1024) :: CTfile ! The name of the file containing the time-step history of the wind files. - CHARACTER(1024) :: CTbackgr ! The name of the background wind data - END TYPE CTWindFiles - -!FIXME: this should be moved to parameters. - TYPE, PUBLIC :: CT_Backgr -! TYPE :: CT_Backgr - CHARACTER(1024) :: WindFile ! The name of the background wind file - INTEGER :: WindFileType ! The type of background wind file (currently only FF) - LOGICAL :: CoherentStr ! If the coherent time step file is blank or doesn't exist, this is FALSE (use the background only) - END TYPE CT_Backgr - - - PUBLIC :: CT_Init - PUBLIC :: CT_GetWindSpeed - PUBLIC :: CT_SetRefVal - PUBLIC :: CT_Terminate - -CONTAINS -!==================================================================================================== -SUBROUTINE CT_Init(UnWind, WindFile, BackGrndValues, ErrStat, ErrMsg) -! This subroutine is called at the beginning of a simulation. It reads the CTP file to obtain -! the name of the CTS file, the path locating the binary KH files, and decimation factors. -! It returns the background wind file and type; it also returns a flag that determines if CT wind -! files are ACTUALLY to be used (e.g., if the CTS file is blank or there is one line of zero in the -! CTS time array). -!---------------------------------------------------------------------------------------------------- - - ! Passed Variables: - - INTEGER, INTENT(IN) :: UnWind ! unit number for reading wind files - CHARACTER(*), INTENT(IN) :: WindFile ! Name of the CTP (.ctp) wind file - TYPE(CT_Backgr), INTENT(OUT) :: BackGrndValues ! output background values - INTEGER, INTENT(OUT) :: ErrStat ! return ErrID_None if no errors - CHARACTER(*), INTENT(OUT) :: ErrMsg ! message if there was an error - - ! Local Variables: - - TYPE(CTWindFiles) :: CTP_files - CHARACTER(3) :: CT_SC_ext ! extension of the scaling file - LOGICAL :: EmptyFileStat ! temporary variable indicating the CT file was empty / non-existent - - ! Temporary error handling Variables - - INTEGER :: TmpErrStat ! Temporary Error Status - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg ! Temporary error message returned - - - - !------------------------------------------------------------------------------------------------- - ! Initialize temporary variables - !------------------------------------------------------------------------------------------------- - - TmpErrStat = ErrID_None - TmpErrMsg = '' - - !------------------------------------------------------------------------------------------------- - ! Check that the module hasn't already been initialized. - !------------------------------------------------------------------------------------------------- - - IF ( TimeIndx /= 0 ) THEN - ErrMsg = ' CTWind has already been initialized.' - ErrStat = ErrID_Fatal - RETURN - ELSE - ErrMsg = '' - ErrStat = ErrID_None - END IF - - - !------------------------------------------------------------------------------------------------- - ! Read the CTP file and set the background data info to be returned later - !------------------------------------------------------------------------------------------------- - - CALL ReadCTP( UnWind, WindFile, CTP_files, TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - BackGrndValues%WindFile = CTP_files%CTbackgr - BackGrndValues%WindFileType = FF_Wind !bjj: perhaps we should check the wind type here - - - !------------------------------------------------------------------------------------------------- - ! Read the CT file to get the time step and file number arrays - !------------------------------------------------------------------------------------------------- - - CALL ReadCT( UnWind, CTP_files%CTfile, CT_SC_ext, EmptyFileStat, TmpErrStat, TmpErrMsg ) - - ! Errors check - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! If the CTP_files%CTfile was empty or non-existent, we continue on without it. - - IF ( EmptyFileStat ) THEN - - ! The file is missing, blank (or possibly incomplete), or has only 1 time step line (which - ! is zero); Go on without the CT file, using just the background - - ErrMsg = TRIM(ErrMsg)//' '//'Coherent turbulence wind file will be turned off.' - - BackGrndValues%CoherentStr = .FALSE. - CALL CT_Terminate( TmpErrStat, TmpErrMsg ) - - ! Error check - ErrStat = MAX( ErrStat, TmpErrStat ) - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - IF ( ErrStat >= AbortErrLev ) RETURN - - - RETURN - - ELSEIF ( (ErrStat < AbortErrLev) .AND. NumCTt > 1) THEN - BackGrndValues%CoherentStr = .TRUE. - - !------------------------------------------------------------------------------------------------- - ! Read file containing scaling for the binary large-eddy files - !------------------------------------------------------------------------------------------------- - CALL ReadCTScales( UnWind, TRIM( CTSpath )//'\Scales.'//TRIM( CT_SC_ext ), TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CTScale(:) = CTScaleVel*CTScale(:) - CTOffset(:) = CTScaleVel*CTOffset(:) - - END IF - - - !------------------------------------------------------------------------------------------------- - ! Set some values that don't change during the run - !------------------------------------------------------------------------------------------------- - - CTYHWid = 0.0 ! This value is used to perform a time shift (the equivalent distance of FFYHWid [approx. rotor radius]) - CT_Zref = -1.0 ! This value needs to be set after the corresponding background turbulence has been read (or the CTS file should be changed) - - NumCTyD = ( NumCTy + CT_DF_Y - 1 )/CT_DF_Y ! The decimated number of CT wind grid points in the y direction. - NumCTzD = ( NumCTz + CT_DF_Z - 1 )/CT_DF_Z ! The decimated number of CT wind grid points in the z direction. - NumCTyD1 = NumCTyD - 1 ! The decimated number of CT wind grid points in the y direction minus 1. - NumCTzD1 = NumCTzD - 1 ! The decimated number of CT wind grid points in the z direction minus 1. - - CTYt = CTYmax*CTLy ! Distance of the tower from the right side of the dataset (looking downwind). -! CTZt = CTZmax*CTLz ! Distance of the hub from the bottom of the dataset. - DelYCTgrid = 1.0/NumCTyD1 ! The nondimensional distance between grid points in the y direction. - DelZCTgrid = 1.0/NumCTzD1 ! The nondimensional distance between grid points in the z direction. - - - - !------------------------------------------------------------------------------------------------- - ! Allocate the wind array and initialize it - !------------------------------------------------------------------------------------------------- - - IF (.NOT. ALLOCATED(CTvelU) ) THEN - ALLOCATE ( CTvelU(NumCTyD,NumCTzD,2), STAT=TmpErrStat ) - - IF ( TmpErrStat /= 0 ) THEN - ErrMsg = TRIM(ErrMsg)//' Error allocating memory for the CTvelU array.' - ErrStat = ErrID_Fatal - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED(CTvelV) ) THEN -! CALL AllocAry( CTvelV, NumCTyD, NumCTzD, 2, 'CTvelV', ErrStat ) !AllRAry3 AllocAry - ALLOCATE ( CTvelV(NumCTyD,NumCTzD,2), STAT=TmpErrStat ) - - IF ( TmpErrStat /= 0 ) THEN - ErrMsg = TRIM(ErrMsg)//' Error allocating memory for the CTvelV array.' - ErrStat = ErrID_Fatal - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED(CTvelW) ) THEN -! CALL AllocAry( CTvelW, NumCTyD, NumCTzD, 2, 'CTvelW', ErrStat ) !AllRAry3 AllocAry - ALLOCATE ( CTvelW(NumCTyD,NumCTzD,2), STAT=TmpErrStat ) - - IF ( TmpErrStat /= 0 ) THEN - ErrMsg = TRIM(ErrMsg)//' Error allocating memory for the CTvelW array.' - ErrStat = ErrID_Fatal - RETURN - END IF - END IF - - CTvelU(:,:,:) = 0.0 ! the original velocity data - CTvelV(:,:,:) = 0.0 ! the original velocity data - CTvelW(:,:,:) = 0.0 ! the original velocity data - - !------------------------------------------------------------------------------------------------- - ! Initialize the arrays and set the initialization flag - !------------------------------------------------------------------------------------------------- - CTvel_files(:) = 0 ! the name of the files currently in the CTvel array - CTWindUnit = UnWind ! This unit is needed to open the binary files at each step - TimeIndx = 1 - - RETURN - -END SUBROUTINE CT_Init -!==================================================================================================== -SUBROUTINE CT_SetRefVal(Height, HWidth, ErrStat, ErrMsg) - - REAL(ReKi), INTENT(IN) :: Height ! a reference height (should be hub height) - REAL(ReKi), INTENT(IN), OPTIONAL :: HWidth ! a reference offset (should be half grid width [~rotor radius]) - INTEGER, INTENT(OUT) :: ErrStat ! returns ErrID_None if no errors, nonzero otherwise - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Message to return about the error - - - !------------------------------------------------------------------------------------------------- - ! Check that we've initialized everything first - !------------------------------------------------------------------------------------------------- - - IF ( TimeIndx == 0 ) THEN - ErrMsg = ' Initialialize the CTWind module before calling its subroutines.' - ErrStat = ErrID_Fatal - RETURN - ELSE IF ( CT_Zref >= 0 ) THEN - ErrMsg = ' Cannot reset the CTWind reference height in the middle of a simulation.' - ErrStat = ErrID_Fatal - RETURN - ELSE - ErrStat = ErrID_None - END IF - - - !------------------------------------------------------------------------------------------------- - ! Set the grid shift using the half-width - !------------------------------------------------------------------------------------------------- - IF ( PRESENT( HWidth ) ) THEN - CTYHWid = HWidth - - IF ( CTYHWid < 0 ) THEN - ErrMsg = TRIM(ErrMsg)//' Reference width in CTWind cannot be negative.' - CTYHWid = 0 - ErrStat = ErrID_Fatal - END IF - END IF - - - !------------------------------------------------------------------------------------------------- - ! Set the reference height (bottom of the KH billow) using the input hub-height - !------------------------------------------------------------------------------------------------- - ! CTZt = CTZmax*CTLz ! the distance between the hub and the bottom of the dataset - - CT_Zref = Height - CTZmax*CTLz ! the height of the bottom of the KH billow - - IF ( CT_Zref < 0 ) THEN - ErrMsg = TRIM(ErrMsg)//' Reference height in CTWind cannot be negative.' - CT_Zref = 0 - ErrStat = ErrID_Fatal - END IF - - -END SUBROUTINE CT_SetRefVal -!==================================================================================================== -FUNCTION CT_GetWindSpeed(Time, InputPosition, ErrStat, ErrMsg) -! This function receives time and position (in InputInfo) where (undisturbed) velocities are are -! requested. It returns the velocities at the specified time and space that are superimposed on -! a background wind flow. This function interpolates into the full-field CT wind arrays, performing -! a time shift based on the average windspeed. The modified time is used to decide which pair of time -! slices to interpolate within and between. After finding the two time slices, it decides which four -! grid points bound the (Y,Z) pair. It does a bilinear interpolation for (Y,Z) on each bounding time -! slice, then linearly interpolates between the 2 time slices. This routine assumes that X is downwind, -! Y is to the left when looking downwind and Z is up. In the time (X) and Z directions, steady winds -! are used when extrapolation is required. The dataset is assumed to be periodic in the Y direction. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables: - - REAL(DbKi), INTENT(IN) :: Time ! the time - REAL(ReKi), INTENT(IN) :: InputPosition(3) ! the position (X,Y,Z) - INTEGER, INTENT(OUT):: ErrStat ! returns ErrID_None if no error; non-zero otherwise - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Message about the error - REAL(ReKi) :: CT_GetWindSpeed ! the resultant wind speed - - - ! Local Variables: - - REAL(ReKi) :: Iyz_th ! Temporary interpolated value. (time hi, all y, all z) - REAL(ReKi) :: Iyz_tl ! Temporary interpolated value. (time lo, all y, all z) - REAL(ReKi) :: Iyhz ! Temporary interpolated value. (y hi, all z) - REAL(ReKi) :: Iylz ! Temporary interpolated value. (y lo, all z) - REAL(ReKi) :: TimeShifted ! Shifted time (necessary because we're keeping x constant) - REAL(ReKi) :: Tgrid ! Fractional distance between time grids. - REAL(ReKi) :: Ygrid ! Fractional distance between grids in the y direction. - REAL(ReKi) :: Ynorm ! Nondimensional lateral distance of the analysis point from right side of dataset (looking downwind). - REAL(ReKi) :: Zgrid(3) ! Fractional distance between grids in the z direction. - REAL(ReKi) :: Znorm ! Nondimensional vertical distance of the analysis point from bottom of dataset. - - INTEGER :: I - INTEGER :: IYHi - INTEGER :: IYLo - INTEGER :: IZHi(3) - INTEGER :: IZLo(3) - - ! Temporary error handling - INTEGER :: TmpErrStat - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg - - - !------------------------------------------------------------------------------------------------- - ! Check that we've initialized everything first - !------------------------------------------------------------------------------------------------- - - IF ( TimeIndx == 0 ) THEN - ErrMsg = ' Initialialize the CTWind module before calling its subroutines.' - ErrStat = ErrID_Fatal - RETURN - ELSE IF ( CT_Zref < 0 ) THEN - ErrMsg = ' Set the reference height in the CTWind module before calling CT_GetWindSpeed.' - ErrStat = ErrID_Fatal - RETURN - ELSE - ErrStat = ErrID_None - END IF - - - !------------------------------------------------------------------------------------------------- - ! Perform the time shift. At time=0, a point half the grid width downstream will index into the zero - ! time slice. CTYHWid is used to shift the CT wind the same as FF wind is shifted. - ! This assumes that the coherent turbulence events are moving at MCTWS - !------------------------------------------------------------------------------------------------- - - TimeShifted = TIME + ( CTYHWid - InputPosition(1) )*InvMCTWS - - - !------------------------------------------------------------------------------------------------- - ! Find the bounding time slices: - ! Linearly interpolate in time (or set to 0 before and/or after) - ! (compare with NWTC_Num.f90\InterpStpReal) - !------------------------------------------------------------------------------------------------- - - ! Let's check the limits first. - - IF ( TimeShifted <= Tdata(1) ) THEN - - TimeIndx = 1 - Tgrid = 0.0 - -! CT_GetWindSpeed%Velocity(:) = 0.0 -! RETURN - - ELSE IF ( TimeShifted >= Tdata(NumCTt) ) THEN - - TimeIndx = NumCTt - 1 - Tgrid = 1.0 - -! CT_GetWindSpeed%Velocity(:) = 0.0 -! RETURN - - ELSE - - ! Let's interpolate! - - TimeIndx = MAX( MIN( TimeIndx, NumCTt-1 ), 1 ) - - - DO - - IF ( TimeShifted < Tdata(TimeIndx) ) THEN - - TimeIndx = TimeIndx - 1 - - ELSE IF ( TimeShifted >= Tdata(TimeIndx+1) ) THEN - - TimeIndx = TimeIndx + 1 - - ELSE - - Tgrid = MIN( MAX( ( TimeShifted - Tdata(TimeIndx) )/( Tdata(TimeIndx+1) - Tdata(TimeIndx) ), 0.0 ), 1.0 ) - EXIT - - END IF - - END DO - - END IF - - - !------------------------------------------------------------------------------------------------- - ! Read the data at the two time steps, if necessary - !------------------------------------------------------------------------------------------------- - - IF ( TimeStpCT(TimeIndx) == CTvel_files(2) ) THEN - IndCT_lo = 2 - IndCT_hi = 1 - - ELSE - IndCT_lo = 1 - IndCT_hi = 2 - - IF ( TimeStpCT(TimeIndx) /= CTvel_files(IndCT_lo) ) THEN - CTvel_files(IndCT_lo) = TimeStpCT(TimeIndx) - CALL ReadCTData ( CTWindUnit, CTvel_files(IndCT_lo), IndCT_lo, TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - END IF - - - IF ( CTvel_files(IndCT_hi) /= TimeStpCT(TimeIndx+1) ) THEN - - CTvel_files(IndCT_hi) = TimeStpCT(TimeIndx+1) - CALL ReadCTData ( CTWindUnit, CTvel_files(IndCT_hi), IndCT_hi, TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - - !------------------------------------------------------------------------------------------------- - ! Calculate the y values; The lower-right corner is (1,1) when looking downwind. - ! note that the KH data is periodic in this direction - !------------------------------------------------------------------------------------------------- - - Ynorm = ( CTYt + InputPosition(2) )/CTYmax - - ! Ensure Ynorm is not negative. The wave is periodic in y. - - IF ( Ynorm < 0.0 ) THEN - Ynorm = 1.0 + MOD(Ynorm, 1.0) - ENDIF - - Ygrid = MIN( MAX( MOD( Ynorm, DelYCTgrid ), 0.0 ), 1.0 ) - IYLo = MAX( MOD( INT( Ynorm*NumCTyD1 ) + 1, NumCTyD1 ), 1 ) - IYHi = MOD( IYLo, NumCTyD ) + 1 - - - !------------------------------------------------------------------------------------------------- - ! Calculate the z values The lower-right corner is (1,1) when looking downwind. - ! Note: the equivalent Znorm for the w-component may be shifted vertically by half the original - ! grid spacing. (the K-H data staggers w differently than u & v). We store IZLo, IZHi, and - ! Zgrid in an array to account for this difference. - !------------------------------------------------------------------------------------------------- - - Znorm = MIN( MAX( ( InputPosition(3) - CT_Zref )/CTZmax, 0.0 ), 1.0 ) ! non-dimensional height (CT_Zref is the bottom of the billow) - - ! Find out fractionally how far we are between grids in time and between grid points in each direction. - ! Limit values to avoid extrapolation. We need this for interpolation later on. - - Zgrid(1:2) = MIN( MAX( MOD( Znorm, DelZCTgrid ), 0.0 ), 1.0 ) - IZLo(1:2) = MAX( INT( Znorm*NumCTzD1 ) + 1, 1 ) ! Make sure the lowest possible value is 1. - - ! If we are located at the upper end of the z dimension, decrement the index by one and set the grid coordinate to 1. - - IF ( IZLo(1) == NumCTzD ) THEN - IZLo(1:2) = NumCTzD1 - Zgrid(1:2) = 1.0 - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Find the equivalent Znorm for the w-component, which may be shifted vertically by half - ! the original grid spacing. (This is necessary due to the fact that the K-H data staggers w - ! differently than u & v). LES and DNS scale differently. - !------------------------------------------------------------------------------------------------- - - IF ( CTVertShft ) THEN - Znorm = MAX( Znorm - 0.5*DelZCTgrid/CT_DF_Z, 0.0 ) - - Zgrid(3) = MIN( MAX( MOD( Znorm, DelZCTgrid ), 0.0 ), 1.0 ) - IZLo(3) = MAX( INT( Znorm*NumCTzD1 ) + 1, 1 ) ! Make sure the lowest possible value is 1. - - - ! If we are located at the upper end of the z dimension, decrement the index by one and set the grid coordinate to 1. - - IF ( IZLo(3) == NumCTzD ) THEN - IZLo(3) = NumCTzD1 - Zgrid(3) = 1.0 - ENDIF - - ELSE - IZLo(3) = IZLo(1) - Zgrid(3)= Zgrid(1) - ENDIF - - IZHi(:) = IZLo(:) + 1 - -!bjj: old versions used Zgrid(3) = Zgrid(1) without regard to CTVertShft. It seemed wrong to me so I changed it. - - !------------------------------------------------------------------------------------------------- - ! Interpolate for U component of wind within the grid. - !------------------------------------------------------------------------------------------------- - - I = 1 - ! linearaly interpolate in the lower time slice - Iylz = ( CTvelU(IYLo,IZHi(I),IndCT_lo) - CTvelU(IYLo,IZLo(I),IndCT_lo) )*Zgrid(I) + CTvelU(IYLo,IZLo(I),IndCT_lo) - Iyhz = ( CTvelU(IYHi,IZHi(I),IndCT_lo) - CTvelU(IYHi,IZLo(I),IndCT_lo) )*Zgrid(I) + CTvelU(IYHi,IZLo(I),IndCT_lo) - Iyz_tl = ( Iyhz - Iylz )*Ygrid + Iylz - - ! linearaly interpolate in the upper time slice - Iylz = ( CTvelU(IYLo,IZHi(I),IndCT_hi) - CTvelU(IYLo,IZLo(I),IndCT_hi) )*Zgrid(I) + CTvelU(IYLo,IZLo(I),IndCT_hi) - Iyhz = ( CTvelU(IYHi,IZHi(I),IndCT_hi) - CTvelU(IYHi,IZLo(I),IndCT_hi) )*Zgrid(I) + CTvelU(IYHi,IZLo(I),IndCT_hi) - Iyz_th = ( Iyhz - Iylz )*Ygrid + Iylz - - CT_GetWindSpeed = ( Iyz_th - Iyz_tl )*Tgrid + Iyz_tl - - - !------------------------------------------------------------------------------------------------- - ! Interpolate for V component of wind within the grid. - !------------------------------------------------------------------------------------------------- - - I = 2 - - ! linearaly interpolate in the lower time slice - Iylz = ( CTvelV(IYLo,IZHi(I),IndCT_lo) - CTvelV(IYLo,IZLo(I),IndCT_lo) )*Zgrid(I) + CTvelV(IYLo,IZLo(I),IndCT_lo) - Iyhz = ( CTvelV(IYHi,IZHi(I),IndCT_lo) - CTvelV(IYHi,IZLo(I),IndCT_lo) )*Zgrid(I) + CTvelV(IYHi,IZLo(I),IndCT_lo) - Iyz_tl = ( Iyhz - Iylz )*Ygrid + Iylz - - ! linearaly interpolate in the upper time slice - Iylz = ( CTvelV(IYLo,IZHi(I),IndCT_hi) - CTvelV(IYLo,IZLo(I),IndCT_hi) )*Zgrid(I) + CTvelV(IYLo,IZLo(I),IndCT_hi) - Iyhz = ( CTvelV(IYHi,IZHi(I),IndCT_hi) - CTvelV(IYHi,IZLo(I),IndCT_hi) )*Zgrid(I) + CTvelV(IYHi,IZLo(I),IndCT_hi) - Iyz_th = ( Iyhz - Iylz )*Ygrid + Iylz - - CT_GetWindSpeed = ( Iyz_th - Iyz_tl )*Tgrid + Iyz_tl - - - !------------------------------------------------------------------------------------------------- - ! Interpolate for W component of wind within the grid. - !------------------------------------------------------------------------------------------------- - - I = 3 - - ! linearaly interpolate in the lower time slice - Iylz = ( CTvelW(IYLo,IZHi(I),IndCT_lo) - CTvelW(IYLo,IZLo(I),IndCT_lo) )*Zgrid(I) + CTvelW(IYLo,IZLo(I),IndCT_lo) - Iyhz = ( CTvelW(IYHi,IZHi(I),IndCT_lo) - CTvelW(IYHi,IZLo(I),IndCT_lo) )*Zgrid(I) + CTvelW(IYHi,IZLo(I),IndCT_lo) - Iyz_tl = ( Iyhz - Iylz )*Ygrid + Iylz - - ! linearaly interpolate in the upper time slice - Iylz = ( CTvelW(IYLo,IZHi(I),IndCT_hi) - CTvelW(IYLo,IZLo(I),IndCT_hi) )*Zgrid(I) + CTvelW(IYLo,IZLo(I),IndCT_hi) - Iyhz = ( CTvelW(IYHi,IZHi(I),IndCT_hi) - CTvelW(IYHi,IZLo(I),IndCT_hi) )*Zgrid(I) + CTvelW(IYHi,IZLo(I),IndCT_hi) - Iyz_th = ( Iyhz - Iylz )*Ygrid + Iylz - - CT_GetWindSpeed = ( Iyz_th - Iyz_tl )*Tgrid + Iyz_tl - - - RETURN - -END FUNCTION CT_GetWindSpeed -!==================================================================================================== -SUBROUTINE ReadCTData ( UnWind, CTFileNo, Itime, ErrStat, ErrMsg ) -! This subroutine is used to read one time-step's worth of large-eddy -! zero-mean wind data for each wind component from a file. -!---------------------------------------------------------------------------------------------------- - - - ! Passed variables. - - INTEGER, INTENT(IN) :: UnWind ! The I/O unit of the input file - INTEGER, INTENT(IN) :: CTFileNo ! The number of the file to read - INTEGER, INTENT(IN) :: Itime ! The index of the time slice - INTEGER, INTENT(OUT) :: ErrStat ! returns ErrID_None if no error; non-zero otherwise - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Message to return about the error - - ! Local variables. - -! CHARACTER(1),PARAMETER :: Comp(NumComps) = (/'u', 'v', 'w' /) ! the wind components - CHARACTER(5) :: CTnum ! string equivalent of input variable CTFileNo - CHARACTER(1024) :: FileName ! The name of the input data file - - ! Temporary error handling Variables - - INTEGER :: TmpErrStat ! Temporary Error Status - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg ! Temporary error message returned - - - !------------------------------------------------------------------------ - ! Initialize the error handling - !------------------------------------------------------------------------ - ErrStat = ErrID_None - ErrMsg = '' - - - IF ( CTFileNo == 0 ) THEN - - CTvelU(:,:,Itime) = 0.0 - CTvelV(:,:,Itime) = 0.0 - CTvelW(:,:,Itime) = 0.0 - - ELSE - ! Loop through the components - - WRITE( CTnum, '(I5.5)' ) CTFileNo - - - FileName = TRIM( CTSpath )//'\u\u_16i_'//CTnum//'.'//TRIM( CText ) - CALL LoadCTData( UnWind, TRIM(FileName), Itime, 1, CTvelU, TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - FileName = TRIM( CTSpath )//'\v\v_16i_'//CTnum//'.'//TRIM( CText ) - CALL LoadCTData( UnWind, TRIM(FileName), Itime, 2, CTvelV, TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - FileName = TRIM( CTSpath )//'\w\w_16i_'//CTnum//'.'//TRIM( CText ) - CALL LoadCTData( UnWind, TRIM(FileName), Itime, 3, CTvelW, TmpErrStat, TmpErrMsg ) - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - END IF - - RETURN - -END SUBROUTINE ReadCTData -!==================================================================================================== -SUBROUTINE LoadCTData( UnWind, FileName, ITime, IComp, Vel, ErrStat, ErrMsg ) -! This function is used to read the input parameters for the coherent turbulence events, -! based on the large-eddy simulation. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables. - - INTEGER, INTENT(IN) :: UnWind ! The I/O unit of the input file - CHARACTER(*), INTENT(IN) :: FileName ! The name of the file to open - INTEGER, INTENT(IN) :: Itime ! The index of the time slice - INTEGER, INTENT(IN) :: IComp ! The index of the component - REAL(ReKi), INTENT(INOUT) :: Vel (NumCTyD,NumCTzD,2) ! returns the velocity array (don't use INTENT OUT!) - INTEGER, INTENT(OUT) :: ErrStat ! returns ErrID_None if no error; non-zero otherwise - CHARACTER(*), INTENT(OUT) :: ErrMsg ! A message abouth the error - - - ! Local Variables - - INTEGER(B2Ki) :: Com (NumCTy) ! Temporary array to hold component's integer values for a given Z. - INTEGER :: IY ! A DO index for indexing the arrays in the y direction. - INTEGER :: IYK ! An index for the decimated arrays in the y direction. - INTEGER :: IZ ! A DO index for indexing the arrays in the z direction. - INTEGER :: IZK ! An index for the decimated arrays in the z direction. - - ! Temporary error handling - INTEGER :: TmpErrStat - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg - - - !------------------------------------------------------------------------------------------------- - ! Set temporary Error info - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' -!FIXME: remove with add ErrMsg - TmpErrMsg = '' - - - !------------------------------------------------------------------------------------------------- - ! Open the input file - !------------------------------------------------------------------------------------------------- - - CALL OpenUInBEFile( UnWind, TRIM(FileName), 2*NumCTy, TmpErrStat ) ! add ErrMsg - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - RETURN - ELSE - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Read the data and fill the arrays - !------------------------------------------------------------------------------------------------- - - IZK = 0 ! the Z index into the array (necessary b/c of decimation factor) - DO IZ=1,NumCTz,CT_DF_Z - - READ (UnWind,REC=IZ,IOSTAT=TmpErrStat) Com - - IF ( TmpErrStat /= 0 ) THEN - - ErrMsg = TRIM(ErrMsg)//' Error reading record '//TRIM( Num2LStr( IZ ) )//' of the binary CT wind file, "' & - //TRIM( FileName )//'."' - ErrStat=ErrID_Fatal - RETURN - - ENDIF - - IZK = IZK + 1 - IYK = 0 ! the Y index into the array (necessary b/c of decimation factor) - - DO IY=1,NumCTy,CT_DF_Y - IYK = IYK + 1 - Vel(IYK,IZK,ITime) = CTScale(IComp)*Com(IY) + CTOffset(IComp) - ENDDO ! IY - - ENDDO ! IZ - - - !------------------------------------------------------------------------------------------------- - ! Close the file - !------------------------------------------------------------------------------------------------- - CLOSE ( UnWind ) - - RETURN - - -END SUBROUTINE LoadCTData -!==================================================================================================== -SUBROUTINE ReadCTP( UnWind, FileName, CTPscaling, ErrStat, ErrMsg ) -! This function is used to read the input parameters for the coherent turbulence events, -! based on the large-eddy simulation. -!---------------------------------------------------------------------------------------------------- - - - ! Passed variables. - - INTEGER, INTENT(IN) :: UnWind ! The I/O unit of the input file - CHARACTER(*), INTENT(IN) :: FileName ! The name of the input data file - TYPE(CTWindFiles), INTENT(OUT) :: CTPscaling ! The file names contained in the CTP file - INTEGER, INTENT(OUT) :: ErrStat ! returns 0 if no error; non-zero otherwise' - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message to return - - - ! Local variables. - - CHARACTER(1024) :: HeaderLine ! The header text in the file - CHARACTER(1024) :: TmpPath - - ! Temporary error handling Variables - - INTEGER :: TmpErrStat ! Temporary Error Status - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg ! Temporary error message returned - - !------------------------------------------------------------------------------------------------- - ! Set temporary Error info - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - - !------------------------------------------------------------------------------------------------- - ! Open the CTP input file - !------------------------------------------------------------------------------------------------- - - CALL OpenFInpFile ( UnWind, TRIM( FileName ), TmpErrStat ) ! add ErrMsg - - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Read the CTP input file - !------------------------------------------------------------------------------------------------- - CALL ReadStr( UnWind, TRIM( FileName ), HeaderLine, 'Header line', 'The header line in the CTP file', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat > AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading header line of '//TRIM(FileName)//'.' - RETURN - ENDIF - CALL WrScr ( ' Heading of the CT-wind-parameter file: "'//TRIM(HeaderLine)//'"' ) - - - CALL ReadCom( UnWind, TRIM( FileName ), 'parameter header line', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading parameter header line of '//TRIM(FileName)//'.' - RETURN - ENDIF - - - CALL ReadVar( UnWind, TRIM( FileName ), CTSpath, 'CTSpath', & - 'Location (path) of the binary coherent turbulence dataset', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading location (path) of the binary coherent turbulence dataset '//TRIM(FileName)//'.' - RETURN - ENDIF - - - CALL ReadVar( UnWind, TRIM( FileName ), CTPscaling%CTfile, 'CTfile', & - 'File containing the time steps for the coherent turbulence events (.cts)', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading name of file containing time steps for the coherent turbulent events from ' & - //TRIM(FileName)//'.' - RETURN - ENDIF - - - IF ( PathIsRelative( CTPscaling%CTfile ) ) THEN - CALL GetPath( FileName, TmpPath ) - CTPscaling%CTfile = TRIM(TmpPath)//TRIM(CTPscaling%CTfile) - END IF - - - CALL ReadVar( UnWind, TRIM( FileName ), CTPscaling%CTbackgr, 'CTbackgr', 'File containing the background wind', TmpErrStat ) ! add ErrMsig - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading name of file containing the background wind from '//TRIM(FileName)//'.' - RETURN - ENDIF - - IF ( PathIsRelative( CTPscaling%CTbackgr ) ) THEN - CALL GetPath( FileName, TmpPath ) - CTPscaling%CTbackgr = TRIM(TmpPath)//TRIM(CTPscaling%CTbackgr) - END IF - - - CALL ReadVar( UnWind, TRIM( FileName ), CT_DF_Y, 'CT_DF_Y', 'Decimation factor for wind data in the Y direction', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading the decimation factor for wind data in the Y direction from ' & - //TRIM(FileName)//'.' - RETURN - ENDIF - - - CALL ReadVar( UnWind, TRIM( FileName ), CT_DF_Z, 'CT_DF_Z', 'Decimation factor for wind data in the Z direction', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) THEN - ErrMsg = TRIM(ErrMsg)//' Error reading the decimation factor for wind data in the Z direction from ' & - //TRIM(FileName)//'.' - RETURN - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Close the CTP input file - !------------------------------------------------------------------------------------------------- - - CLOSE( UnWind ) - - -END SUBROUTINE ReadCTP -!==================================================================================================== -SUBROUTINE ReadCT ( UnWind, FileName, CT_SC_ext, EmptyFileStat, ErrStat, ErrMsg ) -! This subroutine is used to read the input parameters calculated in TurbSim for the scaling of -! coherent turbulence events. It reads the .cts file and saves the time step and file number arrays. -!---------------------------------------------------------------------------------------------------- - -! EmptyFileStat: The CT file may not be exist or may be empty. TurbSim will do this in certain conditions. -! This is not a problem for program execution and used to be handled by Errstat<0. Set a -! warning in this case. - - - ! Passed variables. - - INTEGER, INTENT(IN) :: UnWind ! The I/O unit of the input file - CHARACTER(*), INTENT(IN) :: FileName ! The name of the input data file - CHARACTER(3), INTENT(OUT) :: CT_SC_ext ! The extension used for coherent turbulence scale files.(usually "les", "dns", or "dat") - LOGICAL, INTENT(OUT) :: EmptyFileStat ! Special case for this file type. see note above - INTEGER, INTENT(OUT) :: ErrStat ! returns ErrID_Warn if can't open the file - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Message about what happened - - ! Local variables - - INTEGER :: IT ! Loop counter - - ! Temporary error handling variables - - INTEGER :: TmpErrStat ! temporary ErrStat - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg ! temporary returned error message - - !------------------------------------------------------------------------------------------------- - ! Initialize variables - !------------------------------------------------------------------------------------------------- - - NumCTt = 0 - ErrMsg = '' - - !------------------------------------------------------------------------------------------------- - ! Open the CTS input file -- can proceed if we can't open this file. - !------------------------------------------------------------------------------------------------- - - CALL OpenFInpFile ( UnWind, TRIM( FileName ), TmpErrStat ) ! add ErrMsg when available - IF (TmpErrStat /= 0) THEN - EmptyFileStat = .TRUE. - ErrMsg = ' Error opening '//TRIM(FileName)//', ignoring it.' - ErrStat = ErrID_Warn - RETURN - ELSE - EmptyFileStat = .FALSE. - ENDIF - - !------------------------------------------------------------------------------------------------- - ! Read the header of the CTS input file - !------------------------------------------------------------------------------------------------- - - ! Check to see if the first value is numeric (old) or the file type (new) and start again - - READ ( UnWind, *, IOSTAT=TmpErrStat ) CTScaleVel - REWIND( UnWind ) - - IF ( TmpErrStat /= 0 ) THEN ! try again - - CALL ReadVar( UnWind, TRIM( FileName ), CText, 'CText', 'FileType ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? Can proceeed if the file is empty. - IF ( TmpErrStat < 0 ) THEN ! end of record / end of file condition - ErrMsg = TRIM(ErrMsg)//' File '//TRIM(FileName)//' is empty; ignoring it' - ErrStat = ErrID_Warn - EmptyFileStat = .TRUE. - RETURN - ELSE ! positive, so something bad happened. - ErrMsg = TRIM(ErrMsg)//' Error reading from file '//TRIM(TmpErrMsg) - ErrStat = ErrID_Fatal - ENDIF - IF ( ErrStat >= AbortErrLev ) RETURN - - CT_SC_ext = CText - - CALL ReadVar( UnWind, TRIM( FileName ), CTScaleVel, 'CTScaleVel', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - ELSE ! assume LES files - - CALL ReadVar( UnWind, TRIM( FileName ), CTScaleVel, 'CTScaleVel', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - CText = 'les' - CT_SC_ext = 'dat' - END IF - - CALL ReadVar( UnWind, TRIM( FileName ), InvMCTWS, 'MeanCTWS', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - InvMCTWS = 1.0 / InvMCTWS - - - CALL ReadVar( UnWind, TRIM( FileName ), CTYmax, 'CTYmax', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CTZmax, 'CTZmax', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CTDistSc, 'CTDistSc', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CTLy, 'CTLy', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CTLz, 'CTLz', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), NumCTt, 'NumCTt', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX( ErrStat, TmpErrStat ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Allocate space for the arrays - !------------------------------------------------------------------------------------------------- - - IF (.NOT. ALLOCATED(Tdata) ) THEN - ALLOCATE ( Tdata(NumCTt) , STAT=TmpErrStat ) - - ! Errors occured? - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' Error allocating memory for the Tdata array.' - ErrStat = ErrID_Fatal - RETURN - ENDIF - - END IF - - IF (.NOT. ALLOCATED(TimeStpCT) ) THEN - ALLOCATE ( TimeStpCT(NumCTt) , STAT=TmpErrStat ) - - ! Errors occured? - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' Error allocating memory for the TimeStpCT array.' - ErrStat = ErrID_Fatal - RETURN - ENDIF - - END IF - - - !------------------------------------------------------------------------------------------------- - ! Read the arrays from the CTS input file - !------------------------------------------------------------------------------------------------- - - DO IT=1,NumCTt - - READ (UnWind,*,IOSTAT=TmpErrStat) Tdata(IT), TimeStpCT(IT) - - ! Errors occured? - IF ( TmpErrStat /=0 ) THEN - ErrStat=ErrID_Fatal - ErrMsg = TRIM(ErrMsg)//' Error reading record '//TRIM( Num2LStr( IT ) )//' of the CT-wind time-steps file, "' & - //TRIM( FileName )//'."' - - NumCTt = IT - 1 - RETURN - ENDIF - - ENDDO ! IT - - - !------------------------------------------------------------------------------------------------- - ! Close the CTS input file - !------------------------------------------------------------------------------------------------- - CLOSE( UnWind ) - - - RETURN - -END SUBROUTINE ReadCT -!==================================================================================================== -SUBROUTINE ReadCTScales ( UnWind, FileName, ErrStat, ErrMsg ) -! This subroutine is used to read the input parameters for the coherent turbulence events, based -! on the large-eddy simulation. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - - INTEGER, INTENT(IN) :: UnWind ! The I/O unit of the input file - CHARACTER(*), INTENT(IN) :: FileName ! The name of the input data file - INTEGER, INTENT(OUT) :: ErrStat ! returns ErrID_None if no error; non-zero otherwise - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Message about the error - - - ! Local variables - - INTEGER :: I ! Array counter - - - ! Temporary error handling Variables - - INTEGER :: TmpErrStat ! Temporary Error Status - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg ! Temporary error message returned - - !------------------------------------------------------------------------------------------------- - ! Open the file with the scales (les or dns) - !------------------------------------------------------------------------------------------------- - - CALL OpenFInpFile ( UnWind, TRIM( FileName ), ErrStat) ! add ErrMsg - IF (ErrStat /= 0) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Read the file with the scales (les or dns) - !------------------------------------------------------------------------------------------------- - - CALL ReadCom( UnWind, TRIM( FileName ), 'First line', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CTVertShft, 'CTVertShft', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - DO I = 1,3 - CALL ReadVar( UnWind, TRIM( FileName ), CTScale(I), 'CTScale('//TRIM(Num2LStr(I))//')', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CTOffset(I), 'CTOffset('//TRIM(Num2LStr(I))//')', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - END DO !I - - - CALL ReadVar( UnWind, TRIM( FileName ), NumCTy, 'NumCTy', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), NumCTz, 'NumCTz', ' ', TmpErrStat ) ! add ErrMsg - - ! Errors occured? - ErrMsg = TRIM(ErrMsg)//' '//TRIM(TmpErrMsg) - ErrStat = MAX(ErrStat, TmpErrStat) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Close the file with the scales (les or dns) - !------------------------------------------------------------------------------------------------- - - CLOSE( UnWind ) - - - RETURN - -END SUBROUTINE ReadCTScales -!==================================================================================================== -SUBROUTINE CT_Terminate( ErrStat, ErrMsg ) -! This subroutine closes files, deallocates memory, and un-sets the initialization flag -!---------------------------------------------------------------------------------------------------- - - INTEGER, INTENT(OUT) :: ErrStat ! return ErrID_None if no errors, ErrID level otherwise. - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Message about the error that occurred. - - - ! Temporary error handling Variables - - INTEGER :: TmpErrStat ! Temporary Error Status - CHARACTER(LEN(ErrMsg)) :: TmpErrMsg ! Temporary Error Message - - - ! Initialize variables - ErrStat = ErrID_None - ErrMsg = '' - TmpErrMsg = '' - TmpErrStat = 0 - - - CLOSE( CTWindUnit ) - - IF ( ALLOCATED( CTvelU ) ) DEALLOCATE( CTvelU, STAT=TmpErrStat, ERRMSG=TmpErrMsg ) - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' InflowWind:CTWind: Error occured during de-allocation of CTvelU.'//TmpErrMsg - ErrStat = ErrID_Fatal - ENDIF - - IF ( ALLOCATED( CTvelV ) ) DEALLOCATE( CTvelV, STAT=TmpErrStat, ERRMSG=TmpErrMsg ) - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' InflowWind:CTWind: Error occured during de-allocation of CTvelV.'//TmpErrMsg - ErrStat = ErrID_Fatal - ENDIF - - IF ( ALLOCATED( CTvelW ) ) DEALLOCATE( CTvelW, STAT=TmpErrStat, ERRMSG=TmpErrMsg ) - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' InflowWind:CTWind: Error occured during de-allocation of CTvelW.'//TmpErrMsg - ErrStat = ErrID_Fatal - ENDIF - - IF ( ALLOCATED( Tdata ) ) DEALLOCATE( Tdata, STAT=TmpErrStat, ERRMSG=TmpErrMsg ) - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' InflowWind:CTWind: Error occured during de-allocation of Tdata.'//TmpErrMsg - ErrStat = ErrID_Fatal - ENDIF - - IF ( ALLOCATED( TimeStpCT ) ) DEALLOCATE( TimeStpCT, STAT=TmpErrStat, ERRMSG=TmpErrMsg ) - IF (TmpErrStat /= 0) THEN - ErrMsg = TRIM(ErrMsg)//' InflowWind:CTWind: Error occured during de-allocation of TimeStpCT.'//TmpErrMsg - ErrStat = ErrID_Fatal - ENDIF - - TimeIndx = 0 - -END SUBROUTINE CT_Terminate -!==================================================================================================== -END MODULE CTWind diff --git a/modules/inflowwind/src/FDWind.f90 b/modules/inflowwind/src/FDWind.f90 deleted file mode 100644 index c8accae52..000000000 --- a/modules/inflowwind/src/FDWind.f90 +++ /dev/null @@ -1,1300 +0,0 @@ -MODULE FDWind -! This module reads and processes 4-dimensional wind fields. -! The subroutines were originally created by Marshall Buhl to read LES data provided by researchers -! at NCAR. It was later updated by Bonnie Jonkman to read DNS data provided by researchers at CoRA. -! -! Data are assumed to be in units of meters and seconds. -! -! 7 Oct 2009 B. Jonkman, NREL/NWTC using subroutines from AeroDyn 12.57 -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2013 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** -! File last committed: $Date: 2014-07-29 13:30:04 -0600 (Tue, 29 Jul 2014) $ -! (File) Revision #: $Rev: 125 $ -! URL: $HeadURL$ -!********************************************************************************************************************************** - - USE NWTC_Library - USE SharedInflowDefs - USE InflowWind_Module_Types - - IMPLICIT NONE - PRIVATE - - ! FD_Wind - - REAL(ReKi) :: DelXgrid ! The nondimensional distance between grid points in the x direction. - REAL(ReKi) :: DelYgrid ! The nondimensional distance between grid points in the y direction. - REAL(ReKi) :: DelZgrid ! The nondimensional distance between grid points in the z direction. - REAL(ReKi) :: FDper ! Total time in dataset. - REAL(ReKi) :: FDTime (2) ! Times for the 4D wind files. - REAL(ReKi), ALLOCATABLE :: FDu (:,:,:,:) ! The u-component array of 4D wind data. - REAL(ReKi), ALLOCATABLE :: FDv (:,:,:,:) ! The v-component array of 4D wind data. - REAL(ReKi), ALLOCATABLE :: FDw (:,:,:,:) ! The w-component array of 4D wind data. - REAL(ReKi), ALLOCATABLE :: FDuData (:,:,:,:) ! The u-component array of all 4D wind data when used with advection. - REAL(ReKi), ALLOCATABLE :: FDvData (:,:,:,:) ! The v-component array of all 4D wind data when used with advection. - REAL(ReKi), ALLOCATABLE :: FDwData (:,:,:,:) ! The w-component array of all 4D wind data when used with advection. - REAL(ReKi) :: Lx ! Fractional location of tower centerline from upwind end to downwind end of the dataset. - REAL(ReKi) :: Ly ! Fractional location of tower centerline from right (looking downwind) to left side of the dataset. - REAL(ReKi) :: Lz ! Fractional location of hub height from bottom to top of dataset. - REAL(ReKi) :: Offsets (3) ! Offsets to convert integer data to actual wind speeds. -!FIXME: move to otherstates - REAL(ReKi), SAVE :: PrevTime ! The previous time this was called -- so we can go back in time if necessary - REAL(ReKi) :: RotDiam ! Rotor diameter. - REAL(ReKi) :: ScalFact (3) ! Scaling factors to convert integer data to actual wind speeds. - REAL(ReKi) :: ScaleVel ! Scaling velocity, U0. 2*U0 is the difference in wind speed between the top and bottom of the wave. - REAL(ReKi), ALLOCATABLE :: Times4D (:) ! The list of times for the 4D-wind input files. - REAL(ReKi) :: Tm_max ! The total nondimensional time of the dataset. - REAL(ReKi) :: TSclFact ! Scale factor for time (h/U0). - REAL(ReKi) :: T_4D_En ! Time at which the wave event ends. - REAL(ReKi) :: T_4D_St ! Time at which the wave event starts. - REAL(ReKi) :: Xmax ! The dimensional downwind length of the dataset. - REAL(ReKi) :: Xt ! Distance of the tower from the upwind end of the dataset. - REAL(ReKi) :: Ymax ! The dimensional lateral width of the dataset. - REAL(ReKi) :: Yt ! Distance of the tower from the right side of the dataset (looking downwind). - REAL(ReKi) :: Zmax ! The dimensional vertical height of the dataset. - REAL(ReKi) :: Zt ! Distance of the hub from the bottom of the dataset. - REAL(ReKi) :: Zref ! The reference height (hub height) - - INTEGER :: FD_DF_X ! The decimation factor for the 4D wind data in the x direction. - INTEGER :: FD_DF_Y ! The decimation factor for the 4D wind data in the y direction. - INTEGER :: FD_DF_Z ! The decimation factor for the 4D wind data in the z direction. - INTEGER :: FDFileNo ! The 4D wind file number. - INTEGER :: FDRecL ! The length, in bytes, of the LE binary records. - INTEGER :: Ind4DAdv ! Index of the file to be used in advection - INTEGER :: Ind4Dnew ! Index of the newest 4D wind file. - INTEGER :: Ind4Dold ! Index of the older 4D wind file. - INTEGER :: Num4Dt ! The number of 4D wind grids, one grid per time step. - INTEGER, PARAMETER :: Num4DtD = 2 ! The number of 4D wind grids stored in memory, normally 2 - INTEGER :: Num4Dx ! The number of 4D wind grid points in the x direction. - INTEGER :: Num4DxD ! The decimated number of 4D wind grid points in the x direction. - INTEGER :: Num4DxD1 ! The decimated number of 4D wind grid points in the x direction minus 1. - INTEGER :: Num4Dy ! The number of 4D wind grid points in the y direction. - INTEGER :: Num4DyD ! The decimated number of 4D wind grid points in the y direction. - INTEGER :: Num4DyD1 ! The decimated number of 4D wind grid points in the y direction minus 1. - INTEGER :: Num4Dz ! The number of 4D wind grid points in the z direction. - INTEGER :: Num4DzD ! The decimated number of 4D wind grid points in the z direction. - INTEGER :: Num4DzD1 ! The decimated number of 4D wind grid points in the z direction minus 1. - INTEGER :: NumAdvect ! Number of frozen timesteps to advect past the turbine - INTEGER :: Shft4Dnew ! Number of times the x-data needs to be shifted for advection - INTEGER, ALLOCATABLE :: Times4DIx (:) ! Index number of the 4D time files (used for advection) - - INTEGER :: FDUnit ! Unit number for reading wind files - - LOGICAL :: Advect ! Flag to indicate whether or not to advect a given data set or to just use the time step files - LOGICAL :: VertShft ! Flag to indicate whether or not to shift the z values for the w component. - -!FIXME: move to parameters or otherstates - LOGICAL, SAVE :: Initialized = .FALSE. - - CHARACTER(5), ALLOCATABLE :: AdvFiles (:) - CHARACTER(1024) :: FDSpath ! The path to the 4D wind files. - - - PUBLIC :: FD_Init - PUBLIC :: FD_GetWindSpeed - PUBLIC :: FD_Terminate - PUBLIC :: FD_GetValue - - -CONTAINS -!==================================================================================================== -SUBROUTINE FD_Init(UnWind, WindFile, RefHt, ErrStat) -! This subroutine is called at the beginning of a simulation to initialize the module. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - - INTEGER, INTENT(IN) :: UnWind ! unit number for reading wind files - CHARACTER(*), INTENT(IN) :: WindFile ! Name of the 4D wind parameter file (.fdp) - REAL(ReKi), INTENT(IN) :: RefHt ! The reference height for the billow (should be hub height) - INTEGER, INTENT(OUT) :: ErrStat ! return 0 if no errors; non-zero otherwise - - ! Local variables - - CHARACTER(1024) :: FDTSfile ! name of the 4D time step file - REAL(ReKi) :: FDTimStp ! Average time step for 4D wind data. - INTEGER :: IT - - !------------------------------------------------------------------------------------------------- - ! Check that the module hasn't already been initialized. - !------------------------------------------------------------------------------------------------- - - IF ( Initialized ) THEN - CALL WrScr( ' FDWind has already been initialized.' ) - ErrStat = 1 - RETURN - ELSE - ErrStat = 0 -! CALL NWTC_Init() ! Initialized in IfW_Init - END IF - - - !------------------------------------------------------------------------------------------------- - ! Set the reference height for the wind file (this takes the place of HH that was used earlier) - !------------------------------------------------------------------------------------------------- - - ZRef = RefHt - - !------------------------------------------------------------------------------------------------- - ! Read the main 4D input file - !------------------------------------------------------------------------------------------------- - - CALL ReadFDP( UnWind, WindFile, FDTSfile, ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - !------------------------------------------------------------------------------------------------- - ! Get the times array, which must be scaled and shifted later using TSclFact and T_4D_St - !------------------------------------------------------------------------------------------------- - - CALL Read4Dtimes ( UnWind, FDTSfile, ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Calculate some values that don't change during the run. - !------------------------------------------------------------------------------------------------- - - FDRecL = 2*Num4Dx*Num4Dy ! The length, in bytes, of the 4D binary records. - Num4DxD = ( Num4Dx + FD_DF_X - 1 )/FD_DF_X ! The decimated number of 4D wind grid points in the x direction. - Num4DyD = ( Num4Dy + FD_DF_Y - 1 )/FD_DF_Y ! The decimated number of 4D wind grid points in the y direction. - Num4DzD = ( Num4Dz + FD_DF_Z - 1 )/FD_DF_Z ! The decimated number of 4D wind grid points in the z direction. - Num4DxD1 = Num4DxD - 1 ! The decimated number of 4D wind grid points in the x direction minus 1. - Num4DyD1 = Num4DyD - 1 ! The decimated number of 4D wind grid points in the y direction minus 1. - Num4DzD1 = Num4DzD - 1 ! The decimated number of 4D wind grid points in the z direction minus 1. - - Tm_max = Times4D(Num4Dt) ! Time of end of dataset. - IF ( ADVECT ) THEN - FDTimStp = Xmax / ( ( Num4Dx - 1 )*( ScaleVel )*Num4Dt ) ! The timestep is calculated by the approximation dx/dt ~= U0 (divide by num4dt to get delta for a full timestep). - FDper = FDTimStp * Num4Dt ! Total time in dataset. (We have periodic time, so multiply by number of time steps, without subtracting 1) - TSclFact = FDper / Tm_max ! Equivalent scale factor for time. - ELSE - FDper = TSclFact*Tm_max ! Total time in dataset. - FDTimStp = FDper/( Num4Dt - 1 ) ! Average time step. - ENDIF - - T_4D_En = T_4D_St + FDper ! Time for the end of the dataset. - Xt = Xmax*Lx ! Distance of the tower from the upwind end of the dataset. - Yt = Ymax*Ly ! Distance of the tower from the right side of the dataset (looking downwind). - Zt = Zmax*Lz ! Distance of the hub from the bottom of the dataset. - DelXgrid = 1.0/Num4DxD1 ! The nondimensional distance between grid points in the x direction. - DelYgrid = 1.0/Num4DyD1 ! The nondimensional distance between grid points in the y direction. - DelZgrid = 1.0/Num4DzD1 ! The nondimensional distance between grid points in the z direction. - - - !------------------------------------------------------------------------------------------------- - ! Scale and shift the times array using TSclFact and T_4D_St - !------------------------------------------------------------------------------------------------- - - DO IT=1,Num4Dt - - Times4D(IT) = TSclFact*Times4D(IT) + T_4D_St - - ENDDO ! IT - - - !------------------------------------------------------------------------------------------------- - ! Allocate velocity arrays and fill Data arrays for advection (DNS files) - !------------------------------------------------------------------------------------------------- - - IF (.NOT. ALLOCATED(FDu) ) THEN -! CALL AllocAry ( FDu, Num4DxD, Num4DyD, Num4DzD, 2, 'U-component velocity array (FDu)', ErrStat) - ALLOCATE ( FDu(Num4DxD,Num4DyD,Num4DzD,2), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the U-component velocity array (FDu) array.' ) - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED(FDv) ) THEN -! CALL AllocAry ( FDv, Num4DxD, Num4DyD, Num4DzD, 2, 'V-component velocity array (FDv)', ErrStat) - ALLOCATE ( FDv(Num4DxD,Num4DyD,Num4DzD,2), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the V-component velocity array (FDv) array.' ) - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED(FDw) ) THEN -! CALL AllocAry ( FDw, Num4DxD, Num4DyD, Num4DzD, 2, 'W-component velocity array (FDw)', ErrStat) - ALLOCATE ( FDw(Num4DxD,Num4DyD,Num4DzD,2), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the W-component velocity array (FDw) array.' ) - RETURN - END IF - END IF - - IF ( ADVECT ) THEN - - IF (.NOT. ALLOCATED(FDuData) ) THEN -! CALL AllocAry ( FDuData, Num4DxD, Num4DyD, Num4DzD, Num4Dt, 'U-component velocity array (FDuData)', ErrStat) - ALLOCATE ( FDuData(Num4DxD,Num4DyD,Num4DzD,Num4Dt), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the U-component velocity array (FDuData) array.' ) - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED(FDvData) ) THEN -! CALL AllocAry ( FDvData, Num4DxD, Num4DyD, Num4DzD, Num4Dt, 'V-component velocity array (FDvData)', ErrStat) - ALLOCATE ( FDvData(Num4DxD,Num4DyD,Num4DzD,Num4Dt), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the V-component velocity array (FDvData) array.' ) - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED(FDwData) ) THEN -! CALL AllocAry ( FDwData, Num4DxD, Num4DyD, Num4DzD, Num4Dt, 'W-component velocity array (FDwData)', ErrStat) - ALLOCATE ( FDwData(Num4DxD,Num4DyD,Num4DzD,Num4Dt), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the W-component velocity array (FDwData) array.' ) - RETURN - END IF - END IF - - CALL ReadAll4DData(UnWind, ErrStat) !This needs AdvFiles(:), which was is read in ReadFDP() - IF ( ErrStat /= 0 ) RETURN - - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Determine the first file needed for this simulation. - !------------------------------------------------------------------------------------------------- - Ind4Dold = 1 ! Put the old stuff in the first part of the array. - Ind4Dnew = 2 ! Put the new stuff in the second part of the array. - - Shft4Dnew = 0 - - - IF ( T_4D_St >= 0.0 ) THEN - FDFileNo = 1 - ELSE - FDFileNo = Num4Dt - DO IT=1,Num4Dt - IF ( Times4D(IT) > 0.0 ) THEN - FDFileNo = IT - 1 - EXIT - END IF - END DO ! IT - END IF - - !------------------------------------------------------------------------------------------------- - ! Open, read, and close the first set of files. - !------------------------------------------------------------------------------------------------- - FDTime(Ind4Dold) = Times4D(FDFileNo) ! Set the time for this file. - - IF ( ADVECT ) THEN - CALL Load4DData(Ind4Dold) ! load data stored in FDuData, FDvData, and FDwData arrays - ELSE - CALL LoadLESData( UnWind, FDFileNo, Ind4Dold, ErrStat ) - END IF - - - !------------------------------------------------------------------------------------------------- - ! Open, read, and close the second set of files. - !------------------------------------------------------------------------------------------------- - FDFileNo = FDFileNo + 1 - - - IF ( ADVECT ) THEN - FDFileNo = MOD(FDFileNo-1,Num4Dt) + 1 - - IF (FDFileNo == 1) THEN - Shft4Dnew = Shft4Dnew + 1 - - IF (Ind4DAdv <= NumAdvect) THEN ! Ind4DAdv was set in ReadFDP - IF ( MOD( Shft4Dnew, Num4Dx ) == 0 ) THEN - CALL ReadAll4DData(UnWind, ErrStat) - IF ( ErrStat /= 0 ) RETURN - END IF - END IF - - ENDIF - - FDTime(Ind4Dnew) = Times4D(FDFileNo) + Shft4Dnew*FDPer ! Set the time for this file. - - CALL Load4DData( Ind4Dnew ) ! shift the data - - ELSE - FDTime(Ind4Dnew) = Times4D(FDFileNo) ! Set the time for this file. - - CALL LoadLESData( UnWind, FDFileNo, Ind4Dnew, ErrStat ) - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Set the initialization flag - !------------------------------------------------------------------------------------------------- - FDUnit = UnWind - PrevTime = 0.0 - - Initialized = .TRUE. - - RETURN - -END SUBROUTINE FD_Init -!==================================================================================================== -SUBROUTINE ReadFDP ( UnWind, FileName, FDTSfile, ErrStat ) -! This subroutine is used to read the input parameters for the large-eddy simulation. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - - INTEGER, INTENT(IN) :: UnWind ! unit number for reading wind files - CHARACTER(*), INTENT(IN) :: FileName ! Then name of the LE data file. - CHARACTER(*), INTENT(OUT) :: FDTSfile ! The name of the file containing the time-step history of the wind files. - INTEGER, INTENT(OUT) :: ErrStat ! return 0 if no errors encountered; non-zero otherwise - - - ! Local variables - - CHARACTER(1024) :: HeaderLine -!FIXME: this invokes SAVE - CHARACTER(1),PARAMETER :: Comp(3) = (/'U', 'V', 'W' /) ! the wind components - - REAL(ReKi) :: CoefTE ! Coefficient of thermal expansion. - REAL(ReKi) :: DistScal ! Disturbance scale (ratio of wave height to rotor diameter) from input file. - REAL(ReKi) :: Grav ! Gravitational acceleration. - REAL(ReKi) :: LenScale ! Length scale (h). - REAL(ReKi) :: Ri ! Richardson number. - REAL(ReKi) :: Ubot ! Steady u-component wind speed at the bottom of the wave. - REAL(ReKi) :: Zm_maxo ! The nondimensional vertical height of the untrimmed dataset. - - REAL(ReKi) :: Xm_max ! The nondimensional downwind length of the dataset. - REAL(ReKi) :: Ym_max ! The nondimensional lateral width of the dataset. - REAL(ReKi) :: Zm_max ! The nondimensional vertical height of the dataset. - - INTEGER :: I - - !------------------------------------------------------------------------------------------------- - ! Open the 4D parameter file for reading - !------------------------------------------------------------------------------------------------- - CALL OpenFInpFile ( UnWind, TRIM( FileName ), ErrStat) - IF (ErrStat /= 0) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Read the 4D parameter input file - !------------------------------------------------------------------------------------------------- - - !.............................................................................................. - ! Read the 4D wind parameters specific to this turbine simulation. - !.............................................................................................. - - CALL ReadStr( UnWind, TRIM( FileName ), HeaderLine, 'Header line', 'The header line in the FTP file', ErrStat ) - IF (ErrStat /= 0) RETURN - CALL WrScr ( ' Heading of the 4D-wind-parameter file: "'//TRIM(HeaderLine)//'"' ) - - - CALL ReadCom( UnWind, TRIM( FileName ), 'Header line', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), FDSpath, 'FDSpath', 'Location (path) of the binary dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), FDTSfile, 'FDTSfile', & - 'Name of the file containing the time-step history of the wind files', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Ubot, 'Ubot', 'Steady u-component wind speed at the bottom of the wave', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), DistScal, 'DistScal', 'Disturbance scale', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Lx, 'Lx', & - 'Fractional location of tower centerline from upwind end to downwind end of the dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Ly, 'Ly', & - 'Fractional location of tower centerline from right (looking downwind) to left side of the dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Lz, 'Lz', & - 'Fractional location of hub height from bottom to top of dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), T_4D_St, 'T_4D_St', 'Time at which the wave event starts', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), ScaleVel, 'ScaleVel', & - 'Scaling velocity, U0: half the difference in wind speed between the top and bottom of the billow.', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), RotDiam, 'RotDiam', 'Rotor diameter', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), FD_DF_X, 'FD_DF_X', 'Decimation factor in X direction', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), FD_DF_Y, 'FD_DF_Y', 'Decimation factor in Y direction', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), FD_DF_Z, 'FD_DF_Z', 'Decimation factor in Z direction', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadCom( UnWind, TRIM( FileName ), 'blank line', ErrStat ) - IF (ErrStat /= 0) RETURN - - !.............................................................................................. - ! Read the 4D wind parameters specific to the K-H billow simulation being used. - !.............................................................................................. - - CALL ReadCom( UnWind, TRIM( FileName ), 'LES parameters specific to the K-H billow simulation being used', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), VertShft, 'VertShft', & - 'Flag to indicate whether or not to shift the z values for the w component', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Xm_max, 'Xm_max', & - 'Maximum nondimensional downwind distance from center of dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Ym_max, 'Ym_max', & - 'Maximum nondimensional lateral distance from center of dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Zm_max, 'Zm_max', & - 'Maximum nondimensional vertical distance from center of dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Zm_maxo, 'Zm_maxo', & - 'Maximum nondimensional vertical distance from center of untrimmed dataset', ErrStat ) - IF (ErrStat /= 0) RETURN - - - DO I = 1,3 - - CALL ReadVar( UnWind, TRIM( FileName ), ScalFact(I), Comp(I)//'Scl', & - Comp(I)//'-component scale factor for converting from integers to reals', ErrStat ) - IF (ErrStat /= 0) RETURN - ScalFact(I) = ScalFact(I) * ScaleVel - - - CALL ReadVar( UnWind, TRIM( FileName ), Offsets(I), Comp(I)//'Off', & - Comp(I)//'-component offset for converting from integers to reals', ErrStat ) - IF (ErrStat /= 0) RETURN - Offsets(I) = Offsets(I) * ScaleVel - - END DO - Offsets (1) = Offsets (1) + ScaleVel + Ubot ! u-component offset to convert integer data to actual wind speeds. - - - CALL ReadVar( UnWind, TRIM( FileName ), Num4Dt, 'Num4Dt', 'The number of LE grids, one grid per time step', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Num4Dx, 'Num4Dx', 'The number of LE grid points in the x direction', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Num4Dy, 'Num4Dy', 'The number of LE grid points in the y direction', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Num4Dz, 'Num4Dz', 'The number of LE grid points in the z direction', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Ri, 'Ri', 'Richardson number', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), CoefTE, 'CoefTE', 'Coefficient of thermal expansion', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Grav, 'Grav', 'Gravitational acceleration', ErrStat ) - IF (ErrStat /= 0) RETURN - - - CALL ReadVar( UnWind, TRIM( FileName ), Advect, 'Advect', 'Advection flag', ErrStat ) - - IF (ErrStat /= 0) THEN - - Advect = .FALSE. - Ind4DAdv = 0 - ErrStat = 0 - CALL WrScr( ' Advection will not be used.') - - ELSE - - IF (Advect) THEN - IF ( FD_DF_X /= 1 ) THEN - CALL WrScr( ' FD_DF_X must be 1 when using advection. ' ) - FD_DF_X = 1 - ENDIF - - CALL ReadVar( UnWind, TRIM( FileName ), NumAdvect, 'NumAdvect', 'Number of 4D files for advection', ErrStat ) - IF (ErrStat /= 0) RETURN - - - IF ( NumAdvect < 1 ) THEN - CALL WrScr( ' NumAdvect in 4D-wind-parameter file, "'//TRIM( FileName )//'," must be at least 1.' ) - ErrStat = 1 - RETURN - ENDIF - - IF ( .NOT. ALLOCATED( AdvFiles ) ) THEN -! CALL AllocAry( AdvFiles, NumAdvect, 'AdvFiles array', ErrStat ) - ALLOCATE ( AdvFiles(NumAdvect), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the AdvFiles array.' ) - RETURN - END IF - ENDIF - - CALL ReadAryLines( UnWind, TRIM( FileName ), AdvFiles, NumAdvect, 'AdvFiles', 'Advection file names', ErrStat ) - IF (ErrStat /= 0) RETURN - Ind4DAdv = 1 - - ELSE - Ind4DAdv = 0 - ENDIF !Advect == .TRUE. - - END IF - - !------------------------------------------------------------------------------------------------- - ! Close the 4D parameter input file - !------------------------------------------------------------------------------------------------- - CLOSE ( UnWind ) - - !------------------------------------------------------------------------------------------------- - ! Close the 4D parameter input file - !------------------------------------------------------------------------------------------------- - - LenScale = RotDiam*DistScal/Zm_max ! Length scale (h). - Xmax = Xm_max*LenScale ! The dimensional length of the dataset. - Ymax = Ym_max*LenScale ! The dimensional width of the dataset - Zmax = Zm_max*LenScale ! The dimensional vertical height of the dataset. - TSclFact = LenScale/ScaleVel ! Scale factor for time (h/U0). - - - - RETURN - -END SUBROUTINE ReadFDP -!==================================================================================================== -SUBROUTINE Read4Dtimes ( UnWind, FileName, ErrStat ) -! This subroutine is used to read the time array for the 4D data. The times in the file are -! non-dimensional and non-uniformly spaced. They are scaled using TSclFact to obtain units of seconds -! and T_4D_St is added to allow the billow to start at non-zero time. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - - INTEGER, INTENT(IN) :: UnWind ! unit number for reading wind files - CHARACTER(*), INTENT(IN) :: FileName ! Then name of the LE data file. - INTEGER, INTENT(OUT) :: ErrStat ! return 0 if no errors encountered; non-zero otherwise - - - ! Local variables - - INTEGER :: I ! Loop counter - - !------------------------------------------------------------------------------------------------- - ! Allocate arrays to store the data in - !------------------------------------------------------------------------------------------------- - - IF (.NOT. ALLOCATED( Times4D) ) THEN -! CALL AllocAry( Times4D, Num4Dt, '4D time array', ErrStat) - ALLOCATE ( Times4D(Num4Dt), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the Times4D array.' ) - RETURN - END IF - END IF - - IF (.NOT. ALLOCATED( Times4DIx) ) THEN -! CALL AllocAry( Times4DIx, Num4Dt, '4D time array', ErrStat) - ALLOCATE ( Times4DIx(Num4Dt), STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - CALL WrScr ( ' Error allocating memory for the Times4DIx array.' ) - RETURN - END IF - END IF - - - !------------------------------------------------------------------------------------------------- - ! Open the 4D times file - !------------------------------------------------------------------------------------------------- - CALL OpenFInpFile ( UnWind, TRIM( FileName ), ErrStat) - IF ( ErrStat /= 0 ) RETURN - - !------------------------------------------------------------------------------------------------- - ! Read the 4D times file - !------------------------------------------------------------------------------------------------- - CALL ReadCom( UnWind, TRIM( FileName ), 'first line', ErrStat) - IF ( ErrStat /= 0 ) RETURN - - DO I=1,Num4Dt - - READ (UnWind,*,IOSTAT=ErrStat) Times4DIx(I), Times4D(I) - - IF ( ErrStat /= 0 ) THEN - - CALL WrScr( ' Error reading line '//TRIM( Num2LStr( I+1 ) )// & - ' of the 4D-wind time-steps file, "'//TRIM( FileName )//'."') - RETURN - - ENDIF - - ENDDO ! I - - - !------------------------------------------------------------------------------------------------- - ! Close the 4D times file - !------------------------------------------------------------------------------------------------- - - CLOSE ( UnWind ) - - RETURN - -END SUBROUTINE Read4Dtimes -!==================================================================================================== -SUBROUTINE ReadAll4DData(UnWind, ErrStat) -! This subroutine reads the data into one array to be accessed later when ADVECT=.TRUE. Since there -! are just a few time steps, we'll load them into memory to (hopefully) save I/O time. -!---------------------------------------------------------------------------------------------------- - - INTEGER, INTENT(IN) :: UnWind - INTEGER, INTENT(OUT) :: ErrStat ! - INTEGER :: IT - - CHARACTER(1) :: FDNum - CHARACTER(20) :: DNSFileName ! String containing part of the current file name. - - - DO IT = 1,Num4Dt - - WRITE(FDNum,'(I1.1)') Times4DIx(IT) - DNSFileName = TRIM(AdvFiles(Ind4DAdv))//'_'//TRIM(FDNum)//'.dns' - - CALL Read4DData ( UnWind, TRIM( FDSpath )//'\u\u_16i_'//TRIM(DNSFileName), FDuData, IT, ScalFact(1), Offsets(1), ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - CALL Read4DData ( UnWind, TRIM( FDSpath )//'\v\v_16i_'//TRIM(DNSFileName), FDvData, IT, ScalFact(2), Offsets(2), ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - CALL Read4DData ( UnWind, TRIM( FDSpath )//'\w\w_16i_'//TRIM(DNSFileName), FDwData, IT, ScalFact(3), Offsets(3), ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - ENDDO ! IT - - Ind4DAdv = Ind4DAdv + 1 - - RETURN - -END SUBROUTINE ReadAll4DData -!==================================================================================================== -SUBROUTINE LoadLESData( UnWind, FileNo, Indx, ErrStat ) -! This subroutine reads binary data from the U, V, and W files and stores them in the arrays FDu, -! FDv, and FDw (by calling Read4DData). -!---------------------------------------------------------------------------------------------------- - ! Passed variables - - INTEGER, INTENT(IN) :: UnWind ! unit number for reading wind files - INTEGER, INTENT(IN) :: FileNo ! current file number to read - INTEGER, INTENT(IN) :: Indx ! index into the data arrays - INTEGER, INTENT(OUT) :: ErrStat ! return 0 if no errors encountered; non-zero otherwise - - ! local variables - CHARACTER(5) :: FDNum - CHARACTER(20) :: LESFileName ! String containing part of the current file name. - - - ! get the file name for the file number - - WRITE(FDNum,'(I5.5)', IOStat=ErrStat) FileNo - IF ( ErrStat /= 0 ) RETURN - - LESFileName = TRIM(FDNum)//'.les' - - - ! set the paths and read the data for each component - - CALL Read4DData ( UnWind, TRIM( FDSpath )//'\u\u_16i_'//TRIM(LESFileName), FDu, Indx, ScalFact(1), Offsets(1), ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - CALL Read4DData ( UnWind, TRIM( FDSpath )//'\v\v_16i_'//TRIM(LESFileName), FDv, Indx, ScalFact(2), Offsets(2), ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - CALL Read4DData ( UnWind, TRIM( FDSpath )//'\w\w_16i_'//TRIM(LESFileName), FDw, Indx, ScalFact(3), Offsets(3), ErrStat ) - - -END SUBROUTINE LoadLESData -!==================================================================================================== -SUBROUTINE Read4DData ( UnWind, FileName, Comp, Indx4, Scale, Offset, ErrStat) -! This subroutine is used to read one time-step's worth of large-eddy wind data for one component -! from a file. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables - - INTEGER, INTENT(IN) :: UnWind ! The I/O unit of the LE file. - CHARACTER(*),INTENT(IN) :: FileName ! Then name of the LE data file. - - REAL(ReKi), INTENT(INOUT) :: Comp (:,:,:,:) ! The velocity array [do NOT make this INTENT(OUT): other parts of the array may become undefined] - INTEGER, INTENT(IN) :: Indx4 ! The index of the 4th dimension of Comp, which is to be read. - REAL(ReKi), INTENT(IN) :: Scale ! The scale factor for converting from intergers to non-normalized reals. - REAL(ReKi), INTENT(IN) :: Offset ! The offset for converting from intergers to non-normalized reals. - - INTEGER, INTENT(OUT) :: ErrStat ! The returned status of a READ. - - ! Local variables - - INTEGER :: IX ! A DO index for indexing the arrays in the x direction. - INTEGER :: IXK ! An index for the decimated arrays in the x direction. - INTEGER :: IY ! A DO index for indexing the arrays in the y direction. - INTEGER :: IYK ! An index for the decimated arrays in the y direction. - INTEGER :: IZ ! A DO index for indexing the arrays in the z direction. - INTEGER :: IZK ! An index for the decimated arrays in the z direction. - - INTEGER(B2Ki) :: Com (Num4Dx,Num4Dy) ! Temporary array to hold component's integer values for a given Z. - - - !------------------------------------------------------------------------------------------------- - ! Open the binary input file - !------------------------------------------------------------------------------------------------- - CALL OpenUInBEFile( UnWind, TRIM( FileName ), FDRecL, ErrStat ) - IF ( ErrStat /= 0 ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Read the input file - !------------------------------------------------------------------------------------------------- - - IZK = 0 - DO IZ=1,Num4Dz,FD_DF_Z - - READ (UnWind,REC=IZ,IOSTAT=ErrStat) Com - - IF ( ErrStat /= 0 ) THEN - - CALL WrScr( ' Error reading record '//TRIM( Num2LStr( IZ ) )// & - ' of the binary 4D wind file, "'//TRIM( FileName )//'".') - RETURN - - ENDIF - - IZK = IZK + 1 ! IZK = ( IZ - 1 + FD_DF_Z )/FD_DF_Z - IYK = 0 - - DO IY=1,Num4Dy,FD_DF_Y - - IYK = IYK + 1 ! IYK = ( IY - 1 + FD_DF_Y )/FD_DF_Y - - DO IX=1,Num4Dx,FD_DF_X - - ! shift the x-index, if necessary, to perform Advection - - !IXK = ( IX + FD_DF_X - 1 )/FD_DF_X - IXK = ( MOD(IX+Shft4Dnew-1,Num4Dx) + FD_DF_X )/FD_DF_X - - Comp(IXK,IYK,IZK,Indx4) = Scale*Com(IX,IY) + Offset - - ENDDO ! IX - - ENDDO ! IY - - ENDDO ! IZ - - - !------------------------------------------------------------------------------------------------- - ! Close the file - !------------------------------------------------------------------------------------------------- - CLOSE ( UnWind ) - - RETURN - -END SUBROUTINE Read4DData -!==================================================================================================== -SUBROUTINE Load4DData( InpIndx ) -! This subroutine takes the data from the storage array (used when ADVECT=.TRUE., shifts it if necessary, -! and loads it into the array for the time slice indexed by InpIndx. -!---------------------------------------------------------------------------------------------------- - - INTEGER, INTENT(IN) :: InpIndx - - INTEGER :: IX - INTEGER :: IXK - - - DO IX=1,Num4Dx,FD_DF_X - - ! shift the x-index, if necessary, to perform Advection - IXK = ( MOD(IX+Shft4Dnew-1,Num4Dx) + FD_DF_X )/FD_DF_X - - FDu(IXK,:,:,InpIndx) = FDuData(IX,:,:,FDFileNo) - FDv(IXK,:,:,InpIndx) = FDvData(IX,:,:,FDFileNo) - FDw(IXK,:,:,InpIndx) = FDwData(IX,:,:,FDFileNo) - - ENDDO ! IX - - - RETURN - -END SUBROUTINE Load4DData -!==================================================================================================== -FUNCTION FD_GetValue(RVarName, ErrStat) -! This function returns a real scalar value whose name is listed in the RVarName input argument. -! If the name is not recognized, an error is returned in ErrStat. -!---------------------------------------------------------------------------------------------------- - - CHARACTER(*), INTENT(IN) :: RVarName - INTEGER, INTENT(OUT) :: ErrStat - REAL(ReKi) :: FD_GetValue - - - CHARACTER(20) :: VarNameUC - - - !------------------------------------------------------------------------------------------------- - ! Check that the module has been initialized. - !------------------------------------------------------------------------------------------------- - - IF ( .NOT. Initialized ) THEN - CALL WrScr( ' Initialialize the FDWind module before calling its subroutines.' ) - ErrStat = 1 - RETURN - ELSE - ErrStat = 0 - END IF - - - !------------------------------------------------------------------------------------------------- - ! Return the requested values. - !------------------------------------------------------------------------------------------------- - - VarNameUC = RVarName - CALL Conv2UC( VarNameUC ) - - SELECT CASE ( TRIM(VarNameUC) ) - - CASE ('ROTDIAM' ) - FD_GetValue = RotDiam - - CASE DEFAULT - CALL WrScr( ' Invalid variable name in FD_GetRValue().' ) - ErrStat = 1 - - END SELECT - -END FUNCTION FD_GetValue -!==================================================================================================== -FUNCTION FD_GetWindSpeed(Time, InputPosition, ErrStat) -! This function is used to interpolate into the 4D wind arrays. It receives X, Y, Z and TIME from the -! calling routine. The time since the start of the 4D data is used to decide which pair of time slices -! to interpolate within and between. After finding the two time slices, it decides which eight grid -! points bound the (X,Y,Z) pair. It does a trilinear interpolation for each time slice. Linear -! interpolation is then used to interpolate between time slices. This routine assumes that X is -! downwind, Y is to the left when looking downwind and Z is up. It also assumes that no -! extrapolation will be needed except in time and the Z direction. In those cases, the appropriate -! steady winds are used. -!---------------------------------------------------------------------------------------------------- - - ! Passed variables: - - REAL(DbKi), INTENT(IN) :: Time ! the time - REAL(ReKi), INTENT(IN) :: InputPosition(3) ! structure that contains the position - INTEGER, INTENT(OUT):: ErrStat ! returns 0 if no error; non-zero otherwise -!FIXME:delete -! TYPE(InflIntrpOut) :: FD_GetWindSpeed ! the resultant wind speed - REAL(ReKi) :: FD_GetWindSpeed(3) ! the resultant wind speed - - - ! Local Variables: - - REAL(ReKi) :: Ixhyz ! Temporary interpolated value. - REAL(ReKi) :: Ixlyz ! Temporary interpolated value. - REAL(ReKi) :: Ixyzo ! Temporary interpolated value. - REAL(ReKi) :: Iyhz ! Temporary interpolated value. - REAL(ReKi) :: Iylz ! Temporary interpolated value. - REAL(ReKi) :: Ixyzn ! Temporary interpolated value. - REAL(ReKi) :: Tgrid ! Fractional distance between time grids. - REAL(ReKi) :: Xgrid ! Fractional distance between grids in the x direction. - REAL(ReKi) :: Xnorm ! Nondimensional downwind distance of the analysis point from upwind end of dataset. - REAL(ReKi) :: Ygrid ! Fractional distance between grids in the y direction. - REAL(ReKi) :: Ynorm ! Nondimensional lateral distance of the analysis point from right side of dataset (looking downwind). - REAL(ReKi) :: Zgrid ! Fractional distance between grids in the z direction. - REAL(ReKi) :: Zgrid_w ! Fractional distance between grids in the z direction for the w component. - REAL(ReKi) :: Znorm ! Nondimensional vertical distance of the analysis point from bottom of dataset. - REAL(ReKi) :: Znorm_w ! Nondimensional vertical distance of the analysis point from bottom of dataset for the w component. - - INTEGER :: IT ! Index for do loop - INTEGER :: IXHI ! Index for the more-positive x value. - INTEGER :: IXLO ! Index for the more-negative x value. - INTEGER :: IYHI ! Index for the more-positive y value. - INTEGER :: IYLO ! Index for the more-negative y value. - INTEGER :: IZHI ! Index for the more-positive z value. - INTEGER :: IZHI_w ! Index for the more-positive z value for the w component. - INTEGER :: IZLO ! Index for the more-negative z value. - INTEGER :: IZLO_w ! Index for the more-negative z value for the w component. - - REAL(ReKi) :: TempWindSpeed(3) ! Temporary variable to hold the windspeed before returning - - !------------------------------------------------------------------------------------------------- - ! Check that we've initialized everything first - !------------------------------------------------------------------------------------------------- - - IF ( .NOT. Initialized ) THEN - CALL WrScr( ' Initialialize the FDWind module before calling its subroutines.' ) - ErrStat = 1 - RETURN - ELSE - ErrStat = 0 - END IF - - !------------------------------------------------------------------------------------------------- - ! If the TIME is greater than the time for the last file read, read another set of files until we straddle the current time. - ! Stick with the last file if we've exhausted the data. - ! We're assuming here that the simulation time step is smaller than the wind-file time step. - !------------------------------------------------------------------------------------------------- - - IF ( Time < PrevTime .AND. Time < FDTime(Ind4Dold) ) THEN ! bjj: GET THE CORRECT TIME if we're going backward! - - !---------------------------------------------------------------------------------------------- - ! Determine the first file needed for this simulation. - !---------------------------------------------------------------------------------------------- - Ind4Dold = 1 ! Put the old stuff in the first part of the array. - Ind4Dnew = 2 ! Put the new stuff in the second part of the array. - - FDFileNo = Num4Dt - DO IT=1,Num4Dt - IF ( Times4D(IT) > Time ) THEN - FDFileNo = IT - 1 - EXIT - END IF - END DO ! IT - - !---------------------------------------------------------------------------------------------- - ! Open, read, and close the first set of files. - !---------------------------------------------------------------------------------------------- - FDTime(Ind4Dold) = Times4D(FDFileNo) ! Set the time for this file. - - IF ( ADVECT ) THEN - CALL Load4DData(Ind4Dold) ! load data stored in FDuData, FDvData, and FDwData arrays - ELSE - CALL LoadLESData( FDUnit, FDFileNo, Ind4Dold, ErrStat ) - END IF - - !---------------------------------------------------------------------------------------------- - ! Open, read, and close the second set of files. - !---------------------------------------------------------------------------------------------- - FDFileNo = MIN(FDFileNo + 1, Num4Dt) - Shft4Dnew = 0 - - IF ( ADVECT ) THEN - FDFileNo = MOD(FDFileNo-1,Num4Dt) + 1 - - IF (FDFileNo == 1) THEN - Shft4Dnew = Shft4Dnew + 1 - - IF (Ind4DAdv <= NumAdvect) THEN ! Ind4DAdv was set in ReadFDP - IF ( MOD( Shft4Dnew, Num4Dx ) == 0 ) THEN - CALL ReadAll4DData(FDUnit, ErrStat) - IF ( ErrStat /= 0 ) RETURN - END IF - END IF - - ENDIF - - FDTime(Ind4Dnew) = Times4D(FDFileNo) + Shft4Dnew*FDPer ! Set the time for this file. - - CALL Load4DData( Ind4Dnew ) ! shift the data - - ELSE - FDTime(Ind4Dnew) = Times4D(FDFileNo) ! Set the time for this file. -! - CALL LoadLESData( FDUnit, FDFileNo, Ind4Dnew, ErrStat ) - ENDIF - - END IF - - !------------------------------------------------------------------------------------------------- - ! Move forward in time - !------------------------------------------------------------------------------------------------- - - DO WHILE ( Time > FDTime(Ind4Dnew) .AND. ( Time < T_4D_En .OR. ADVECT ) ) - - Ind4Dnew = Ind4Dold ! Reverse array indices (1 or 2). - Ind4Dold = 3 - Ind4Dnew - FDFileNo = FDFileNo + 1 ! Increment file number. - - - IF ( ADVECT ) THEN - FDFileNo = MOD(FDFileNo-1,Num4Dt) + 1 - - IF (FDFileNo == 1) THEN - Shft4Dnew = Shft4Dnew + 1 - - IF (Ind4DAdv <= NumAdvect) THEN - IF ( MOD( Shft4Dnew, Num4Dx ) == 0 ) THEN - CALL ReadAll4DData(FDUnit, ErrStat) - IF ( ErrStat /= 0 ) RETURN - END IF - ENDIF - - ENDIF - - FDTime(Ind4Dnew) = Times4D(FDFileNo) + Shft4Dnew*FDPer - - CALL Load4DData( Ind4Dnew ) ! shift the data - ELSE - FDTime(Ind4Dnew) = Times4D(FDFileNo) - - CALL LoadLESData( FDUnit, FDFileNo, Ind4Dnew, ErrStat ) - ENDIF - - ENDDO - - - !................................................................................................. - ! Find the bounding rows, columns, and planes for the X,Y,Z position. The near, lower-right - ! corner is (1,1,1) when looking downwind. Make sure the lowest possible value is 1. - !................................................................................................. - - - !------------------------------------------------------------------------------------------------- - ! get values of Time for interpolation. Linear interpolation; Nearest-neighbor extrapolation. - !------------------------------------------------------------------------------------------------- - - ! Find out fractionally how far we are between grids in time and between grid points in each direction. - ! Limit values to avoid extrapolation. We need this for interpolation later on. - - Tgrid = MIN( MAX( ( Time - FDTime(Ind4Dold) )/( FDTime(Ind4Dnew) - FDTime(Ind4Dold) ), 0.0 ), 1.0 ) - - - !------------------------------------------------------------------------------------------------- - ! get values of X for interpolation. Grid is periodic in X. - !------------------------------------------------------------------------------------------------- - Xnorm = ( Xt + InputPosition(1) )/Xmax - - DO WHILE ( Xnorm < 0.0 ) ! Ensure Xnorm is not negative. The wave is periodic in x. - Xnorm = Xnorm + 1.0 - ENDDO - - Xgrid = MIN( MAX( MOD( Xnorm, DelXgrid ), 0.0 ), 1.0 ) - IXLo = MAX( MOD( INT( Xnorm*Num4DxD1 ) + 1, Num4DxD1 ), 1 ) - IXHi = MOD( IXLo, Num4DxD ) + 1 - - !------------------------------------------------------------------------------------------------- - ! get values of Y for interpolation. Grid is periodic in Y. - !------------------------------------------------------------------------------------------------- - Ynorm = ( Yt + InputPosition(2) )/Ymax - - DO WHILE ( Ynorm < 0.0 ) ! Ensure Ynorm is not negative. The wave is periodic in y. - Ynorm = Ynorm + 1.0 - ENDDO - - Ygrid = MIN( MAX( MOD( Ynorm, DelYgrid ), 0.0 ), 1.0 ) - IYLo = MAX( MOD( INT( Ynorm*Num4DyD1 ) + 1, Num4DyD1 ), 1 ) - IYHi = MOD( IYLo, Num4DyD ) + 1 - - !------------------------------------------------------------------------------------------------- - ! get values of Z for interpolation. Linear interpolation; Nearest-neighbor extrapolation. - !------------------------------------------------------------------------------------------------- - Znorm = MIN( MAX( ( Zt + InputPosition(3) - ZRef )/Zmax, 0.0 ), 1.0 ) !bjj: define ZRef - - Zgrid = MIN( MAX( MOD( Znorm, DelZgrid ), 0.0 ), 1.0 ) - IZLo = MAX( INT( Znorm*Num4DzD1 ) + 1, 1 ) - - ! If we are located at the upper end of the z dimension, decrement the index by one and set the grid coordinate to 1. - - IF ( IZLo == Num4DzD ) THEN - IZLo = Num4DzD1 - Zgrid = 1.0 - ENDIF - IZHi = IZLo + 1 - - !.............................................................................................. - ! Find the equivalent Znorm (Znorm_w) for the w-component, which may be shifted vertically - ! by half the original grid spacing. - !.............................................................................................. - - IF ( VertShft ) THEN - Znorm_w = MAX( Znorm - 0.5*DelZgrid/FD_DF_Z, 0.0 ) - ELSE - Znorm_w = Znorm - ENDIF - - Zgrid_w = MIN( MAX( MOD( Znorm_w, DelZgrid ), 0.0 ), 1.0 ) - IZLo_w = MAX( INT( Znorm_w*Num4DzD1 ) + 1, 1 ) - - IF ( IZLo_w == Num4DzD ) THEN - IZLo_w = Num4DzD1 - Zgrid_w = 1.0 - ENDIF - - IZHi_w = IZLo_w + 1 - - - !------------------------------------------------------------------------------------------------- - ! Interpolate for u component of wind within the grid. - !------------------------------------------------------------------------------------------------- - - Iylz = ( FDu(IXLo,IYLo,IZHi,Ind4Dold) - FDu(IXLo,IYLo,IZLo,Ind4Dold) )*Zgrid + FDu(IXLo,IYLo,IZLo,Ind4Dold) - Iyhz = ( FDu(IXLo,IYHi,IZHi,Ind4Dold) - FDu(IXLo,IYHi,IZLo,Ind4Dold) )*Zgrid + FDu(IXLo,IYHi,IZLo,Ind4Dold) - Ixlyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Iylz = ( FDu(IXHi,IYLo,IZHi,Ind4Dold) - FDu(IXHi,IYLo,IZLo,Ind4Dold) )*Zgrid + FDu(IXHi,IYLo,IZLo,Ind4Dold) - Iyhz = ( FDu(IXHi,IYHi,IZHi,Ind4Dold) - FDu(IXHi,IYHi,IZLo,Ind4Dold) )*Zgrid + FDu(IXHi,IYHi,IZLo,Ind4Dold) - Ixhyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Ixyzo = ( Ixhyz - Ixlyz )*Xgrid + Ixlyz - - Iylz = ( FDu(IXLo,IYLo,IZHi,Ind4Dnew) - FDu(IXLo,IYLo,IZLo,Ind4Dnew) )*Zgrid + FDu(IXLo,IYLo,IZLo,Ind4Dnew) - Iyhz = ( FDu(IXLo,IYHi,IZHi,Ind4Dnew) - FDu(IXLo,IYHi,IZLo,Ind4Dnew) )*Zgrid + FDu(IXLo,IYHi,IZLo,Ind4Dnew) - Ixlyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Iylz = ( FDu(IXHi,IYLo,IZHi,Ind4Dnew) - FDu(IXHi,IYLo,IZLo,Ind4Dnew) )*Zgrid + FDu(IXHi,IYLo,IZLo,Ind4Dnew) - Iyhz = ( FDu(IXHi,IYHi,IZHi,Ind4Dnew) - FDu(IXHi,IYHi,IZLo,Ind4Dnew) )*Zgrid + FDu(IXHi,IYHi,IZLo,Ind4Dnew) - Ixhyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Ixyzn = ( Ixhyz - Ixlyz )*Xgrid + Ixlyz - -! FD_GetWindSpeed%Velocity(1) = ( Ixyzn - Ixyzo )*Tgrid + Ixyzo - TempWindSpeed(1) = ( Ixyzn - Ixyzo )*Tgrid + Ixyzo - - !------------------------------------------------------------------------------------------------- - ! Interpolate for v component of wind within the grid. - !------------------------------------------------------------------------------------------------- - - Iylz = ( FDv(IXLo,IYLo,IZHi,Ind4Dold) - FDv(IXLo,IYLo,IZLo,Ind4Dold) )*Zgrid + FDv(IXLo,IYLo,IZLo,Ind4Dold) - Iyhz = ( FDv(IXLo,IYHi,IZHi,Ind4Dold) - FDv(IXLo,IYHi,IZLo,Ind4Dold) )*Zgrid + FDv(IXLo,IYHi,IZLo,Ind4Dold) - Ixlyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Iylz = ( FDv(IXHi,IYLo,IZHi,Ind4Dold) - FDv(IXHi,IYLo,IZLo,Ind4Dold) )*Zgrid + FDv(IXHi,IYLo,IZLo,Ind4Dold) - Iyhz = ( FDv(IXHi,IYHi,IZHi,Ind4Dold) - FDv(IXHi,IYHi,IZLo,Ind4Dold) )*Zgrid + FDv(IXHi,IYHi,IZLo,Ind4Dold) - Ixhyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Ixyzo = ( Ixhyz - Ixlyz )*Xgrid + Ixlyz - - Iylz = ( FDv(IXLo,IYLo,IZHi,Ind4Dnew) - FDv(IXLo,IYLo,IZLo,Ind4Dnew) )*Zgrid + FDv(IXLo,IYLo,IZLo,Ind4Dnew) - Iyhz = ( FDv(IXLo,IYHi,IZHi,Ind4Dnew) - FDv(IXLo,IYHi,IZLo,Ind4Dnew) )*Zgrid + FDv(IXLo,IYHi,IZLo,Ind4Dnew) - Ixlyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Iylz = ( FDv(IXHi,IYLo,IZHi,Ind4Dnew) - FDv(IXHi,IYLo,IZLo,Ind4Dnew) )*Zgrid + FDv(IXHi,IYLo,IZLo,Ind4Dnew) - Iyhz = ( FDv(IXHi,IYHi,IZHi,Ind4Dnew) - FDv(IXHi,IYHi,IZLo,Ind4Dnew) )*Zgrid + FDv(IXHi,IYHi,IZLo,Ind4Dnew) - Ixhyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Ixyzn = ( Ixhyz - Ixlyz )*Xgrid + Ixlyz - -!FIXME:delete -! FD_GetWindSpeed%Velocity(2) = ( Ixyzn - Ixyzo )*Tgrid + Ixyzo - TempWindSpeed(2) = ( Ixyzn - Ixyzo )*Tgrid + Ixyzo - - !------------------------------------------------------------------------------------------------- - ! Interpolate for w component of wind within the grid. - !------------------------------------------------------------------------------------------------- - !bjj: should Zgrid actually be Zgrid_w here? I changed it so that it's consistent - - Iylz = ( FDw(IXLo,IYLo,IZHi_w,Ind4Dold) - FDw(IXLo,IYLo,IZLo_w,Ind4Dold) )*Zgrid_w + FDw(IXLo,IYLo,IZLo_w,Ind4Dold) - Iyhz = ( FDw(IXLo,IYHi,IZHi_w,Ind4Dold) - FDw(IXLo,IYHi,IZLo_w,Ind4Dold) )*Zgrid_w + FDw(IXLo,IYHi,IZLo_w,Ind4Dold) - Ixlyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Iylz = ( FDw(IXHi,IYLo,IZHi_w,Ind4Dold) - FDw(IXHi,IYLo,IZLo_w,Ind4Dold) )*Zgrid_w + FDw(IXHi,IYLo,IZLo_w,Ind4Dold) - Iyhz = ( FDw(IXHi,IYHi,IZHi_w,Ind4Dold) - FDw(IXHi,IYHi,IZLo_w,Ind4Dold) )*Zgrid_w + FDw(IXHi,IYHi,IZLo_w,Ind4Dold) - Ixhyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Ixyzo = ( Ixhyz - Ixlyz )*Xgrid + Ixlyz - - Iylz = ( FDw(IXLo,IYLo,IZHi_w,Ind4Dnew) - FDw(IXLo,IYLo,IZLo_w,Ind4Dnew) )*Zgrid_w + FDw(IXLo,IYLo,IZLo_w,Ind4Dnew) - Iyhz = ( FDw(IXLo,IYHi,IZHi_w,Ind4Dnew) - FDw(IXLo,IYHi,IZLo_w,Ind4Dnew) )*Zgrid_w + FDw(IXLo,IYHi,IZLo_w,Ind4Dnew) - Ixlyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Iylz = ( FDw(IXHi,IYLo,IZHi_w,Ind4Dnew) - FDw(IXHi,IYLo,IZLo_w,Ind4Dnew) )*Zgrid_w + FDw(IXHi,IYLo,IZLo_w,Ind4Dnew) - Iyhz = ( FDw(IXHi,IYHi,IZHi_w,Ind4Dnew) - FDw(IXHi,IYHi,IZLo_w,Ind4Dnew) )*Zgrid_w + FDw(IXHi,IYHi,IZLo_w,Ind4Dnew) - Ixhyz = ( Iyhz - Iylz )*Ygrid + Iylz - - Ixyzn = ( Ixhyz - Ixlyz )*Xgrid + Ixlyz - -!FIXME:delete -! FD_GetWindSpeed%Velocity(3) = ( Ixyzn - Ixyzo )*Tgrid + Ixyzo - TempWindSpeed(3) = ( Ixyzn - Ixyzo )*Tgrid + Ixyzo - - ! Copy the windspeed info to the output - FD_GetWindSpeed = TempWindSpeed - - !------------------------------------------------------------------------------------------------- - ! Set the previous time here to compare with later... - !------------------------------------------------------------------------------------------------- - PrevTime = Time - - RETURN - -END FUNCTION FD_GetWindSpeed -!==================================================================================================== -SUBROUTINE FD_Terminate( ErrStat ) -! This subroutine deallocates arrays, closes files, and un-sets the initialization flag. -!---------------------------------------------------------------------------------------------------- - - INTEGER, INTENT(OUT) :: ErrStat ! return 0 if no errors; non-zero otherwise - - - CLOSE( FDunit ) - - ErrStat = 0 - - IF ( ALLOCATED( FDu ) ) DEALLOCATE( FDu, STAT=ErrStat ) - IF ( ALLOCATED( FDv ) ) DEALLOCATE( FDv, STAT=ErrStat ) - IF ( ALLOCATED( FDw ) ) DEALLOCATE( FDw, STAT=ErrStat ) - IF ( ALLOCATED( FDuData ) ) DEALLOCATE( FDuData, STAT=ErrStat ) - IF ( ALLOCATED( FDvData ) ) DEALLOCATE( FDvData, STAT=ErrStat ) - IF ( ALLOCATED( FDwData ) ) DEALLOCATE( FDwData, STAT=ErrStat ) - IF ( ALLOCATED( Times4D ) ) DEALLOCATE( Times4D, STAT=ErrStat ) - IF ( ALLOCATED( Times4DIx ) ) DEALLOCATE( Times4DIx, STAT=ErrStat ) - IF ( ALLOCATED( AdvFiles ) ) DEALLOCATE( AdvFiles, STAT=ErrStat ) - - Initialized = .FALSE. - -END SUBROUTINE FD_Terminate -!==================================================================================================== -END MODULE FDWind diff --git a/modules/inflowwind/src/IfW_4Dext.f90 b/modules/inflowwind/src/IfW_4Dext.f90 deleted file mode 100644 index dea5bd8e4..000000000 --- a/modules/inflowwind/src/IfW_4Dext.f90 +++ /dev/null @@ -1,369 +0,0 @@ -!> This module is a placeholder for any user defined wind types. The end user can use this as a template for their code. -!! @note This module does not need to exactly conform to the FAST Modularization Framework standards. Three routines are required -!! though: -!! -- IfW_4Dext_Init -- Load or create any wind data. Only called at the start of FAST. -!! -- IfW_4Dext_CalcOutput -- This will be called at each timestep with a series of data points to give wind velocities at. -!! -- IfW_4Dext_End -- clear out any stored stuff. Only called at the end of FAST. -MODULE IfW_4Dext -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - - USE NWTC_Library - USE IfW_4Dext_Types - - IMPLICIT NONE - PRIVATE - - TYPE(ProgDesc), PARAMETER :: IfW_4Dext_Ver = ProgDesc( 'IfW_4Dext', '', '' ) - - PUBLIC :: IfW_4Dext_Init - PUBLIC :: IfW_4Dext_End - PUBLIC :: IfW_4Dext_CalcOutput - -CONTAINS - -!==================================================================================================== - -!---------------------------------------------------------------------------------------------------- -!> A subroutine to initialize the UserWind module. This routine will initialize the module. -!---------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_4Dext_Init(InitInp, p, m, Interval, InitOut, ErrStat, ErrMsg) - - - IMPLICIT NONE - - ! Passed Variables - - TYPE(IfW_4Dext_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization - TYPE(IfW_4Dext_ParameterType), INTENT( OUT) :: p !< Parameters - TYPE(IfW_4Dext_MiscVarType), INTENT( OUT) :: m !< Misc variables for optimization (not copied in glue code) - TYPE(IfW_4Dext_InitOutputType), INTENT( OUT) :: InitOut !< Initial output - - REAL(DbKi), INTENT(IN ) :: Interval !< Do not change this!! - - - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< A message about the error. See NWTC_Library info for ErrID_* levels. - - ! local variables - ! Put local variables used during initializing your wind here. DO NOT USE GLOBAL VARIABLES EVER! - INTEGER(IntKi) :: UnitWind ! Use this unit number if you need to read in a file. - - ! Temporary variables for error handling - INTEGER(IntKi) :: ErrStat2 ! Temp variable for the error status - CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary error message - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_Init' - - !------------------------------------------------------------------------------------------------- - ! Set the Error handling variables - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = "" - - - !------------------------------------------------------------------------------------------------- - ! Copy things from the InitData to the ParamData. - !------------------------------------------------------------------------------------------------- - p%n = InitInp%n ! number of points on the evenly-spaced grid (in each direction) - p%delta = InitInp%delta ! distance between consecutive grid points in each direction - p%pZero = InitInp%pZero ! fixed location of first XYZ grid point (i.e., XYZ coordinates of m%V(:,1,1,1,:)) - - - !------------------------------------------------------------------------------------------------- - ! Set the MiscVars: - ! Note that these could be considered inputs, but that would mean many extra copies of potentially - ! large arrays. I am using misc vars to avoid unnecessary duplication. The external code must - ! set values for m%TgridStart and m%V. - !------------------------------------------------------------------------------------------------- - m%TgridStart = 0.0_ReKi ! (time) location of first time grid point (i.e., XYZ coordinates of m%V(:,:,:,:,1)) - should be set with m%V - - call AllocAry( m%V, 3, p%n(1), p%n(2), p%n(3), p%n(4), 'V', ErrStat2, ErrMsg2 ) !uvw at x,y,z,t coordinate - call SetErrStat(ErrStat, ErrMsg, ErrStat2, ErrMsg2, RoutineName) - if (ErrStat >= AbortErrLev) return - m%V = 0.0_SiKi - - !------------------------------------------------------------------------------------------------- - ! Set the InitOutput information. Set any outputs here. - !------------------------------------------------------------------------------------------------- - - InitOut%Ver = IfW_4Dext_Ver - - RETURN - -END SUBROUTINE IfW_4Dext_Init - -!==================================================================================================== - -!------------------------------------------------------------------------------------------------- -!> This routine and its subroutines calculate the wind velocity at a set of points given in -!! PositionXYZ. The UVW velocities are returned in OutData%Velocity -!------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_4Dext_CalcOutput(Time, PositionXYZ, p, Velocity, m, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_4Dext_CalcOutput" - - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_4Dext_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - TYPE(IfW_4Dext_MiscVarType), INTENT(IN ) :: m !< Misc variables for optimization (not copied in glue code) - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - - ! local counters - INTEGER(IntKi) :: PointNum ! a loop counter for the current point - - ! local variables - INTEGER(IntKi) :: NumPoints ! Number of points passed in - - ! temporary variables - INTEGER(IntKi) :: ErrStat2 ! temporary error status - CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary error message - - - - !------------------------------------------------------------------------------------------------- - ! Initialize some things - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = "" - - - ! The array is transposed so that the number of points is the second index, x/y/z is the first. - ! This is just in case we only have a single point, the SIZE command returns the correct number of points. - NumPoints = SIZE(PositionXYZ,DIM=2) - - - ! Step through all the positions and get the velocities - DO PointNum = 1, NumPoints - - - ! Calculate the velocity for the position - Velocity(:,PointNum) = Interp4D(Time, PositionXYZ(:,PointNum), p, m, ErrStat2, ErrMsg2 ) - - - ! Error handling - IF (ErrStat2 /= ErrID_None) THEN ! adding this so we don't have to convert numbers to strings every time - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//" [position=("// & - TRIM(Num2LStr(PositionXYZ(1,PointNum)))//", "// & - TRIM(Num2LStr(PositionXYZ(2,PointNum)))//", "// & - TRIM(Num2LStr(PositionXYZ(3,PointNum)))//") in wind-file coordinates]" ) - IF (ErrStat >= AbortErrLev) RETURN - END IF - - - ENDDO - - RETURN - -END SUBROUTINE IfW_4Dext_CalcOutput - -!==================================================================================================== -!> This routine interpolates a 4-d dataset. -!! This method is described here: http://rjwagner49.com/Mathematics/Interpolation.pdf -FUNCTION Interp4D( Time, Position, p, m, ErrStat, ErrMsg ) - - ! I/O variables - - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: Position(3) !< Array of XYZ coordinates, 3 - TYPE(IfW_4Dext_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(IfW_4Dext_MiscVarType), INTENT(IN ) :: m !< Misc variables for optimization (not copied in glue code) - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - REAL(SiKi) :: Interp4D(3) !< The interpolated UVW from m%V - - CHARACTER(*), PARAMETER :: RoutineName = 'Interp4D' - - ! Local variables - - INTEGER(IntKi) :: i ! loop counter - INTEGER(IntKi) :: ic ! wind-component counter - - INTEGER(IntKi) :: Indx_Lo(4) ! index associated with lower bound of dimension 1-4 where val(Indx_lo(i)) <= InCoord(i) <= val(Indx_hi(i)) - INTEGER(IntKi) :: Indx_Hi(4) ! index associated with upper bound of dimension 1-4 where val(Indx_lo(i)) <= InCoord(i) <= val(Indx_hi(i)) - - REAL(SiKi) :: isopc(4) ! isoparametric coordinates - REAL(SiKi) :: N(16) ! size 2^n - REAL(SiKi) :: u(16) ! size 2^n - REAL(ReKi) :: Tmp ! temporary fraction of distance between two grid points - - - Interp4D = 0.0_ReKi - ErrStat = ErrID_None - ErrMsg = "" - - - - !------------------------------------------------------------------------------------------------- - ! Find the bounding indices for XYZ position - !------------------------------------------------------------------------------------------------- - do i=1,3 - Tmp = (Position(i) - p%pZero(i)) / p%delta(i) - Indx_Lo(i) = INT( Tmp ) + 1 ! convert REAL to INTEGER, then add one since our grid indices start at 1, not 0 - isopc(i) = 2.0_ReKi * (Tmp - REAL(Indx_Lo(i) - 1_IntKi, ReKi)) - 1.0_ReKi ! convert to value between -1 and 1 - enddo - - !------------------------------------------------------------------------------------------------- - ! Find the bounding indices for time - !------------------------------------------------------------------------------------------------- - i=4 - Tmp = (Time - m%TgridStart) / p%delta(i) - Indx_Lo(i) = INT( Tmp ) + 1 ! convert REAL to INTEGER, then add one since our grid indices start at 1, not 0 - isopc(i) = 2.0_ReKi * (Tmp - REAL(Indx_Lo(i) - 1_IntKi, ReKi)) - 1.0_ReKi ! convert to value between -1 and 1 - IF ( ( Indx_Lo(i) == p%n(i) ) ) then - if ( abs(isopc(i) + 1.0_SiKi) < 0.001_SiKi ) THEN ! Allow for the special case where Time = TgridStart + deltat*( n_high_low - 1 ) - Indx_Lo(i) = Indx_Lo(i) - 1 - isopc(i) = 1.0_SiKi - end if - END IF - - !------------------------------------------------------------------------------------------------- - ! to verify that we don't extrapolate, make sure isopc is bound between -1 and 1 (effectively nearest neighbor) - !------------------------------------------------------------------------------------------------- - DO i=1,size(isopc) - isopc(i) = min( 1.0_SiKi, isopc(i) ) - isopc(i) = max(-1.0_SiKi, isopc(i) ) - END DO - - !------------------------------------------------------------------------------------------------- - ! also make sure we're not outside the bounds - !------------------------------------------------------------------------------------------------- - DO i=1,size(p%n) - IF (Indx_Lo(i) <= 0) THEN - Indx_Lo(i) = 1 - CALL SetErrStat(ErrID_Fatal,'Outside the grid bounds.',ErrStat,ErrMsg,RoutineName) !error out if x,y,z, or time is outside the lower bounds - RETURN - ELSEIF (Indx_Lo(i) >= p%n(i) ) THEN - Indx_Lo(i) = max( p%n(i) - 1, 1 ) ! make sure it's a valid index - CALL SetErrStat(ErrID_Fatal,'Outside the grid bounds.',ErrStat,ErrMsg,RoutineName) !error out if x,y,z, or time is outside the upper bounds - RETURN - END IF - Indx_Hi(i) = min( Indx_Lo(i) + 1, p%n(i) ) ! make sure it's a valid index - END DO - - !------------------------------------------------------------------------------------------------- - ! compute weighting factors - !------------------------------------------------------------------------------------------------- - - N( 1) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N( 2) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N( 3) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N( 4) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N( 5) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N( 6) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N( 7) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N( 8) = ( 1.0_SiKi - isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N( 9) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N(10) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N(11) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N(12) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi - isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N(13) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N(14) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi - isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N(15) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi - isopc(4) ) - N(16) = ( 1.0_SiKi + isopc(1) ) * ( 1.0_SiKi + isopc(2) ) * ( 1.0_SiKi + isopc(3) ) * ( 1.0_SiKi + isopc(4) ) - N = N / REAL( SIZE(N), SiKi ) ! normalize - - !------------------------------------------------------------------------------------------------- - ! interpolate - !------------------------------------------------------------------------------------------------- - - do ic=1,3 - - u( 1) = m%V( ic, Indx_Lo(1), Indx_Lo(2), Indx_Lo(3), Indx_Lo(4) ) - u( 2) = m%V( ic, Indx_Lo(1), Indx_Lo(2), Indx_Lo(3), Indx_Hi(4) ) - u( 3) = m%V( ic, Indx_Lo(1), Indx_Lo(2), Indx_Hi(3), Indx_Lo(4) ) - u( 4) = m%V( ic, Indx_Lo(1), Indx_Lo(2), Indx_Hi(3), Indx_Hi(4) ) - u( 5) = m%V( ic, Indx_Lo(1), Indx_Hi(2), Indx_Lo(3), Indx_Lo(4) ) - u( 6) = m%V( ic, Indx_Lo(1), Indx_Hi(2), Indx_Lo(3), Indx_Hi(4) ) - u( 7) = m%V( ic, Indx_Lo(1), Indx_Hi(2), Indx_Hi(3), Indx_Lo(4) ) - u( 8) = m%V( ic, Indx_Lo(1), Indx_Hi(2), Indx_Hi(3), Indx_Hi(4) ) - u( 9) = m%V( ic, Indx_Hi(1), Indx_Lo(2), Indx_Lo(3), Indx_Lo(4) ) - u(10) = m%V( ic, Indx_Hi(1), Indx_Lo(2), Indx_Lo(3), Indx_Hi(4) ) - u(11) = m%V( ic, Indx_Hi(1), Indx_Lo(2), Indx_Hi(3), Indx_Lo(4) ) - u(12) = m%V( ic, Indx_Hi(1), Indx_Lo(2), Indx_Hi(3), Indx_Hi(4) ) - u(13) = m%V( ic, Indx_Hi(1), Indx_Hi(2), Indx_Lo(3), Indx_Lo(4) ) - u(14) = m%V( ic, Indx_Hi(1), Indx_Hi(2), Indx_Lo(3), Indx_Hi(4) ) - u(15) = m%V( ic, Indx_Hi(1), Indx_Hi(2), Indx_Hi(3), Indx_Lo(4) ) - u(16) = m%V( ic, Indx_Hi(1), Indx_Hi(2), Indx_Hi(3), Indx_Hi(4) ) - - Interp4D(ic) = SUM ( N * u ) - - end do - -END FUNCTION Interp4D - -!---------------------------------------------------------------------------------------------------- -!> This routine deallocates any memory in the FDext module. -SUBROUTINE IfW_4Dext_End( ParamData, MiscVars, ErrStat, ErrMsg) - - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_4Dext_End" - - - ! Passed Variables - TYPE(IfW_4Dext_ParameterType), INTENT(INOUT) :: ParamData !< Parameters - TYPE(IfW_4Dext_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Local Variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - ErrMsg = '' - ErrStat = ErrID_None - - - - ! Destroy parameter data - - CALL IfW_4Dext_DestroyParam( ParamData, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - ! Destroy the misc data - - CALL IfW_4Dext_DestroyMisc( MiscVars, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - -END SUBROUTINE IfW_4Dext_End -!==================================================================================================== -END MODULE IfW_4Dext diff --git a/modules/inflowwind/src/IfW_4Dext.txt b/modules/inflowwind/src/IfW_4Dext.txt deleted file mode 100644 index 5a4543981..000000000 --- a/modules/inflowwind/src/IfW_4Dext.txt +++ /dev/null @@ -1,39 +0,0 @@ -################################################################################################################################### -# Registry for IfW_UserWind, creates MODULE IfW_UserWind_Types -# Module IfW_UserWind_Types contains all of the user-defined types needed in IfW_UserWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - -include Registry_NWTC_Library.txt - - -######################### - -typedef IfW_4Dext/IfW_4Dext InitInputType IntKi n 4 - - "number of grid points in the x, y, z, and t directions" - -typedef ^ InitInputType ReKi delta 4 - - "size between 2 consecutive grid points in each grid direction" "m,m,m,s" -typedef ^ InitInputType ReKi pZero 3 - - "fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:))" "m" - - -# Init Output -typedef ^ InitOutputType ProgDesc Ver - - - "Version information of this submodule" - - - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType SiKi V ::::: - - "this is the 4-d velocity field for each wind component [{uvw},nx,ny,nz,nt]; it is stored as a miscVar instead of an input so that we don't have 4 copies of a very large field" - -typedef ^ MiscVarType ReKi TgridStart - - - "this is the time where the first time grid in m%V starts (i.e, the time associated with m%V(:,:,:,:,1))" s - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType IntKi n 4 - - "number of evenly-spaced grid points in the x, y, z, and t directions" - -typedef ^ ParameterType ReKi delta 4 - - "size between 2 consecutive grid points in each grid direction" "m,m,m,s" -typedef ^ ParameterType ReKi pZero 3 - - "fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:))" "m" - - - - diff --git a/modules/inflowwind/src/IfW_4Dext_Types.f90 b/modules/inflowwind/src/IfW_4Dext_Types.f90 deleted file mode 100644 index b87a4e1fe..000000000 --- a/modules/inflowwind/src/IfW_4Dext_Types.f90 +++ /dev/null @@ -1,830 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_4Dext_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_4Dext_Types -!................................................................................................................................. -! This file is part of IfW_4Dext. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_4Dext. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_4Dext_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_4Dext_InitInputType ======= - TYPE, PUBLIC :: IfW_4Dext_InitInputType - INTEGER(IntKi) , DIMENSION(1:4) :: n !< number of grid points in the x, y, z, and t directions [-] - REAL(ReKi) , DIMENSION(1:4) :: delta !< size between 2 consecutive grid points in each grid direction [m,m,m,s] - REAL(ReKi) , DIMENSION(1:3) :: pZero !< fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:)) [m] - END TYPE IfW_4Dext_InitInputType -! ======================= -! ========= IfW_4Dext_InitOutputType ======= - TYPE, PUBLIC :: IfW_4Dext_InitOutputType - TYPE(ProgDesc) :: Ver !< Version information of this submodule [-] - END TYPE IfW_4Dext_InitOutputType -! ======================= -! ========= IfW_4Dext_MiscVarType ======= - TYPE, PUBLIC :: IfW_4Dext_MiscVarType - REAL(SiKi) , DIMENSION(:,:,:,:,:), ALLOCATABLE :: V !< this is the 4-d velocity field for each wind component [{uvw},nx,ny,nz,nt]; it is stored as a miscVar instead of an input so that we don't have 4 copies of a very large field [-] - REAL(ReKi) :: TgridStart !< this is the time where the first time grid in m%V starts (i.e, the time associated with m%V(:,:,:,:,1)) [s] - END TYPE IfW_4Dext_MiscVarType -! ======================= -! ========= IfW_4Dext_ParameterType ======= - TYPE, PUBLIC :: IfW_4Dext_ParameterType - INTEGER(IntKi) , DIMENSION(1:4) :: n !< number of evenly-spaced grid points in the x, y, z, and t directions [-] - REAL(ReKi) , DIMENSION(1:4) :: delta !< size between 2 consecutive grid points in each grid direction [m,m,m,s] - REAL(ReKi) , DIMENSION(1:3) :: pZero !< fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:)) [m] - END TYPE IfW_4Dext_ParameterType -! ======================= -CONTAINS - SUBROUTINE IfW_4Dext_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_4Dext_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_4Dext_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%n = SrcInitInputData%n - DstInitInputData%delta = SrcInitInputData%delta - DstInitInputData%pZero = SrcInitInputData%pZero - END SUBROUTINE IfW_4Dext_CopyInitInput - - SUBROUTINE IfW_4Dext_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) - TYPE(IfW_4Dext_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_DestroyInitInput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_4Dext_DestroyInitInput - - SUBROUTINE IfW_4Dext_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_4Dext_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + SIZE(InData%n) ! n - Re_BufSz = Re_BufSz + SIZE(InData%delta) ! delta - Re_BufSz = Re_BufSz + SIZE(InData%pZero) ! pZero - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO i1 = LBOUND(InData%n,1), UBOUND(InData%n,1) - IntKiBuf(Int_Xferred) = InData%n(i1) - Int_Xferred = Int_Xferred + 1 - END DO - DO i1 = LBOUND(InData%delta,1), UBOUND(InData%delta,1) - ReKiBuf(Re_Xferred) = InData%delta(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%pZero,1), UBOUND(InData%pZero,1) - ReKiBuf(Re_Xferred) = InData%pZero(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE IfW_4Dext_PackInitInput - - SUBROUTINE IfW_4Dext_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_4Dext_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - i1_l = LBOUND(OutData%n,1) - i1_u = UBOUND(OutData%n,1) - DO i1 = LBOUND(OutData%n,1), UBOUND(OutData%n,1) - OutData%n(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - i1_l = LBOUND(OutData%delta,1) - i1_u = UBOUND(OutData%delta,1) - DO i1 = LBOUND(OutData%delta,1), UBOUND(OutData%delta,1) - OutData%delta(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%pZero,1) - i1_u = UBOUND(OutData%pZero,1) - DO i1 = LBOUND(OutData%pZero,1), UBOUND(OutData%pZero,1) - OutData%pZero(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE IfW_4Dext_UnPackInitInput - - SUBROUTINE IfW_4Dext_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_4Dext_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(IfW_4Dext_InitOutputType), INTENT(INOUT) :: DstInitOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_CopyInitOutput' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_4Dext_CopyInitOutput - - SUBROUTINE IfW_4Dext_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) - TYPE(IfW_4Dext_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_DestroyInitOutput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) - END SUBROUTINE IfW_4Dext_DestroyInitOutput - - SUBROUTINE IfW_4Dext_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_4Dext_InitOutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_4Dext_PackInitOutput - - SUBROUTINE IfW_4Dext_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_4Dext_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_4Dext_UnPackInitOutput - - SUBROUTINE IfW_4Dext_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_4Dext_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(IfW_4Dext_MiscVarType), INTENT(INOUT) :: DstMiscData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_CopyMisc' -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(SrcMiscData%V)) THEN - i1_l = LBOUND(SrcMiscData%V,1) - i1_u = UBOUND(SrcMiscData%V,1) - i2_l = LBOUND(SrcMiscData%V,2) - i2_u = UBOUND(SrcMiscData%V,2) - i3_l = LBOUND(SrcMiscData%V,3) - i3_u = UBOUND(SrcMiscData%V,3) - i4_l = LBOUND(SrcMiscData%V,4) - i4_u = UBOUND(SrcMiscData%V,4) - i5_l = LBOUND(SrcMiscData%V,5) - i5_u = UBOUND(SrcMiscData%V,5) - IF (.NOT. ALLOCATED(DstMiscData%V)) THEN - ALLOCATE(DstMiscData%V(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u,i5_l:i5_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%V.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstMiscData%V = SrcMiscData%V -ENDIF - DstMiscData%TgridStart = SrcMiscData%TgridStart - END SUBROUTINE IfW_4Dext_CopyMisc - - SUBROUTINE IfW_4Dext_DestroyMisc( MiscData, ErrStat, ErrMsg ) - TYPE(IfW_4Dext_MiscVarType), INTENT(INOUT) :: MiscData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_DestroyMisc' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(MiscData%V)) THEN - DEALLOCATE(MiscData%V) -ENDIF - END SUBROUTINE IfW_4Dext_DestroyMisc - - SUBROUTINE IfW_4Dext_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_4Dext_MiscVarType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_PackMisc' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! V allocated yes/no - IF ( ALLOCATED(InData%V) ) THEN - Int_BufSz = Int_BufSz + 2*5 ! V upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%V) ! V - END IF - Re_BufSz = Re_BufSz + 1 ! TgridStart - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IF ( .NOT. ALLOCATED(InData%V) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,3) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V,4) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,4) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V,5) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,5) - Int_Xferred = Int_Xferred + 2 - - DO i5 = LBOUND(InData%V,5), UBOUND(InData%V,5) - DO i4 = LBOUND(InData%V,4), UBOUND(InData%V,4) - DO i3 = LBOUND(InData%V,3), UBOUND(InData%V,3) - DO i2 = LBOUND(InData%V,2), UBOUND(InData%V,2) - DO i1 = LBOUND(InData%V,1), UBOUND(InData%V,1) - ReKiBuf(Re_Xferred) = InData%V(i1,i2,i3,i4,i5) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END DO - END DO - END IF - ReKiBuf(Re_Xferred) = InData%TgridStart - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_4Dext_PackMisc - - SUBROUTINE IfW_4Dext_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_4Dext_MiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_UnPackMisc' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! V not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i4_l = IntKiBuf( Int_Xferred ) - i4_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i5_l = IntKiBuf( Int_Xferred ) - i5_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%V)) DEALLOCATE(OutData%V) - ALLOCATE(OutData%V(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u,i5_l:i5_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%V.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i5 = LBOUND(OutData%V,5), UBOUND(OutData%V,5) - DO i4 = LBOUND(OutData%V,4), UBOUND(OutData%V,4) - DO i3 = LBOUND(OutData%V,3), UBOUND(OutData%V,3) - DO i2 = LBOUND(OutData%V,2), UBOUND(OutData%V,2) - DO i1 = LBOUND(OutData%V,1), UBOUND(OutData%V,1) - OutData%V(i1,i2,i3,i4,i5) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END DO - END DO - END IF - OutData%TgridStart = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_4Dext_UnPackMisc - - SUBROUTINE IfW_4Dext_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_4Dext_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_4Dext_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - DstParamData%n = SrcParamData%n - DstParamData%delta = SrcParamData%delta - DstParamData%pZero = SrcParamData%pZero - END SUBROUTINE IfW_4Dext_CopyParam - - SUBROUTINE IfW_4Dext_DestroyParam( ParamData, ErrStat, ErrMsg ) - TYPE(IfW_4Dext_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_DestroyParam' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_4Dext_DestroyParam - - SUBROUTINE IfW_4Dext_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_4Dext_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + SIZE(InData%n) ! n - Re_BufSz = Re_BufSz + SIZE(InData%delta) ! delta - Re_BufSz = Re_BufSz + SIZE(InData%pZero) ! pZero - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO i1 = LBOUND(InData%n,1), UBOUND(InData%n,1) - IntKiBuf(Int_Xferred) = InData%n(i1) - Int_Xferred = Int_Xferred + 1 - END DO - DO i1 = LBOUND(InData%delta,1), UBOUND(InData%delta,1) - ReKiBuf(Re_Xferred) = InData%delta(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%pZero,1), UBOUND(InData%pZero,1) - ReKiBuf(Re_Xferred) = InData%pZero(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE IfW_4Dext_PackParam - - SUBROUTINE IfW_4Dext_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_4Dext_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_4Dext_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - i1_l = LBOUND(OutData%n,1) - i1_u = UBOUND(OutData%n,1) - DO i1 = LBOUND(OutData%n,1), UBOUND(OutData%n,1) - OutData%n(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - i1_l = LBOUND(OutData%delta,1) - i1_u = UBOUND(OutData%delta,1) - DO i1 = LBOUND(OutData%delta,1), UBOUND(OutData%delta,1) - OutData%delta(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%pZero,1) - i1_u = UBOUND(OutData%pZero,1) - DO i1 = LBOUND(OutData%pZero,1), UBOUND(OutData%pZero,1) - OutData%pZero(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE IfW_4Dext_UnPackParam - -END MODULE IfW_4Dext_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_BladedFFWind.f90 b/modules/inflowwind/src/IfW_BladedFFWind.f90 deleted file mode 100644 index 47f17c792..000000000 --- a/modules/inflowwind/src/IfW_BladedFFWind.f90 +++ /dev/null @@ -1,1896 +0,0 @@ -!> This module uses full-field binary wind files to determine the wind inflow. -!! This module assumes that the origin, (0,0,0), is located at the tower centerline at ground level, -!! and that all units are specified in the metric system (using meters and seconds). -!! Data is shifted by half the grid width to account for turbine yaw (so that data in the X -!! direction actually starts at -1*ParamData%FFYHWid meters). -MODULE IfW_BladedFFWind -!! -!! Created 25-Sep-2009 by B. Jonkman, National Renewable Energy Laboratory -!! using subroutines and modules from AeroDyn v12.58 -!! -!!---------------------------------------------------------------------------------------------------- -!! Feb 2013 v2.00.00 A. Platt -!! -- updated to the new framework -!! -- Modified to use NWTC_Library v. 2.0 -!! -- Note: Jacobians are not included in this version. -!! -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2015-2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - - USE NWTC_Library - USE IfW_BladedFFWind_Types - USE IfW_FFWind_Base - - IMPLICIT NONE - PRIVATE - - TYPE(ProgDesc), PARAMETER :: IfW_BladedFFWind_Ver = ProgDesc( 'IfW_BladedFFWind', '', '' ) - - PUBLIC :: IfW_BladedFFWind_Init - PUBLIC :: IfW_BladedFFWind_End - PUBLIC :: IfW_BladedFFWind_CalcOutput - - - - -CONTAINS -!==================================================================================================== -!> This routine is used read the full-field turbulence data. -!! 09/25/1997 - Created by M. Buhl from GETFILES in ViewWind. -!! 09/23/2009 - modified by B. Jonkman: this subroutine was split into several subroutines (was ReadFF) -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE IfW_BladedFFWind_Init(InitInp, ParamData, MiscVars, InitOutData, ErrStat, ErrMsg) - - CHARACTER(*), PARAMETER :: RoutineName="IfW_BladedFFWind_Init" - - ! Passed Variables - TYPE(IfW_BladedFFWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization data passed to the module - TYPE(IfW_BladedFFWind_ParameterType), INTENT( OUT) :: ParamData !< Parameters - TYPE(IfW_BladedFFWind_MiscVarType), INTENT( OUT) :: MiscVars !< misc/optimization data (storage for the main data) - TYPE(IfW_BladedFFWind_InitOutputType), INTENT( OUT) :: InitOutData !< Initial output - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Temporary variables for error handling - REAL(ReKi) :: TI(3) - REAL(ReKi) :: ScaleFactors(3) - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - TYPE(IfW_FFWind_InitInputType) :: FF_InitInp ! Initialization input data for FF scaling - - - - ErrMsg = '' - ErrStat = ErrID_None - - - CALL ReadFiles(InitInp, FF_InitInp, InitOutData, ParamData, TI, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - !------------------------------------------------------------------------------------------------- - ! If the wind file has zero-mean and unit standard deviation (native Bladed format), scale the data: - !------------------------------------------------------------------------------------------------- - ParamData%FF%AddMeanAfterInterp = .false. - ParamData%FF%WindProfileType = FF_InitInp%WindProfileType - ParamData%FF%Z0 = FF_InitInp%Z0 - ParamData%FF%PLExp = FF_InitInp%PLExp - - if (InitInp%NativeBladedFmt) then - ParamData%FF%InterpTower = .true. - ParamData%FF%AddMeanAfterInterp = .true. - - ! Validate scaling data if we've got native-Bladed format - CALL FFWind_ValidateInput(FF_InitInp, ParamData%FF%NFFComp, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - ! scale to requested TI (or use requested scale factors) - call ScaleTurbulence(FF_InitInp, ParamData%FF%FFData(:,:,:,1:ParamData%FF%NFFSteps), ScaleFactors, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - ! Add the mean wind speed to the u component. - if (.not. ParamData%FF%AddMeanAfterInterp) call AddMeanVelocity(FF_InitInp, ParamData%FF%GridBase, 1.0_ReKi/ParamData%FF%InvFFZD, ParamData%FF%FFData) - else - ParamData%FF%InterpTower = .false. - end if - - - IF (ParamData%FF%Periodic) THEN - ParamData%FF%InitXPosition = 0 ! start at the hub - ParamData%FF%TotalTime = ParamData%FF%NFFSteps*ParamData%FF%FFDTime - ELSE - ParamData%FF%InitXPosition = ParamData%FF%FFYHWid ! start half the grid width ahead of the turbine - ParamData%FF%TotalTime = (ParamData%FF%NFFSteps-1)*ParamData%FF%FFDTime - ENDIF - - ! overwrite the offset - IF (InitInp%NativeBladedFmt) THEN - ParamData%FF%InitXPosition = FF_InitInp%XOffset - END IF - - - !------------------------------------------------------------------------------------------------- - ! Set the InitOutput information - !------------------------------------------------------------------------------------------------- - - InitOutdata%Ver = IfW_BladedFFWind_Ver - InitOutdata%TI = TI - - - - !------------------------------------------------------------------------------------------------- - ! Write to the summary file - !------------------------------------------------------------------------------------------------- - - IF ( InitInp%SumFileUnit > 0 ) THEN - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) 'Bladed-style wind type. Read by InflowWind sub-module '// & - TRIM(IfW_BladedFFWind_Ver%Name)//' '//TRIM(IfW_BladedFFWind_Ver%Ver) - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) TRIM(TmpErrMsg) - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' FileName: '//TRIM(InitInp%WindFileName) - WRITE(InitInp%SumFileUnit,'(A34,I3)', IOSTAT=TmpErrStat) ' Binary file format id: ',ParamData%FF%WindFileFormat - WRITE(InitInp%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Reference height (m): ',ParamData%FF%RefHt - WRITE(InitInp%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Timestep (s): ',ParamData%FF%FFDTime - WRITE(InitInp%SumFileUnit,'(A34,I12)', IOSTAT=TmpErrStat) ' Number of timesteps: ',ParamData%FF%NFFSteps - WRITE(InitInp%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Mean windspeed (m/s): ',ParamData%FF%MeanFFWS - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Characteristic TI: [ '// & - TRIM(Num2LStr(TI(1)))//', '//TRIM(Num2LStr(TI(2)))//', '//TRIM(Num2LStr(TI(3)))//' ] ' - WRITE(InitInp%SumFileUnit,'(A34,L1)', IOSTAT=TmpErrStat) ' Windfile is periodic: ',ParamData%FF%Periodic - WRITE(InitInp%SumFileUnit,'(A34,L1)', IOSTAT=TmpErrStat) ' Windfile includes tower: ',ParamData%FF%NTGrids > 0 - - IF ( ParamData%FF%Periodic ) THEN - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Time range (s): [ '// & - TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(ParamData%FF%TotalTime))//' ]' - ELSE ! Shift the time range to compensate for the shifting of the wind grid - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Time range (s): [ '// & - TRIM(Num2LStr(-ParamData%FF%InitXPosition*ParamData%FF%InvMFFWS))//' : '// & - TRIM(Num2LStr(ParamData%FF%TotalTime-ParamData%FF%InitXPosition*ParamData%FF%InvMFFWS))//' ]' - ENDIF - - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Y range (m): [ '// & - TRIM(Num2LStr(-ParamData%FF%FFYHWid))//' : '//TRIM(Num2LStr(ParamData%FF%FFYHWid))//' ]' - - IF ( ParamData%FF%NTGrids > 0 ) THEN - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Z range (m): [ '// & - TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(ParamData%FF%RefHt + ParamData%FF%FFZHWid))//' ]' - ELSE - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Z range (m): [ '// & - TRIM(Num2LStr(ParamData%FF%RefHt - ParamData%FF%FFZHWid))//' : '//TRIM(Num2LStr(ParamData%FF%RefHt + ParamData%FF%FFZHWid))//' ]' - ENDIF - - - ! We are assuming that if the last line was written ok, then all of them were. - IF (TmpErrStat /= 0_IntKi) THEN - CALL SetErrStat(ErrID_Fatal,'Error writing to summary file.',ErrStat,ErrMsg,RoutineName) - RETURN - ENDIF - ENDIF - - - - - RETURN - -END SUBROUTINE IfW_BladedFFWind_Init -!======================================================================================================== -SUBROUTINE ReadFiles(InitInp, FF_InitInp, InitOut, ParamData, TI, ErrStat, ErrMsg) - - CHARACTER(*), PARAMETER :: RoutineName="ReadFiles" - - ! Passed Variables - TYPE(IfW_BladedFFWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization data passed to the module - TYPE(IfW_FFWind_InitInputType), INTENT( OUT) :: FF_InitInp !< Initialization data for scaling - TYPE(IfW_BladedFFWind_InitOutputType), INTENT(INOUT) :: InitOut !< Initial output - TYPE(IfW_BladedFFWind_ParameterType), INTENT( OUT) :: ParamData !< Parameters - REAL(ReKi) , INTENT( OUT) :: TI (3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - ! Local Variables: - - REAL(ReKi) :: BinTI (3) ! turbulence intensities of the wind components as defined in the FF binary file, not necessarially the actual TI - REAL(ReKi) :: NatTI (3) ! turbulence intensities of the wind components as defined in the native FF summary file - REAL(ReKi) :: UBar - REAL(ReKi) :: ZCenter - - INTEGER(IntKi) :: UnitWind ! Unit number for the InflowWind input file - INTEGER(B2Ki) :: Dum_Int2 - INTEGER(IntKi) :: I - LOGICAL :: CWise - LOGICAL :: LHR ! Left-hand rule for Bladed files (is the v component aligned along *negative* Y?) - - LOGICAL :: Exists - CHARACTER( 1028 ) :: SumFile ! length is LEN(ParamData%WindFileName) + the 4-character extension. - CHARACTER( 1028 ) :: TwrFile ! length is LEN(ParamData%WindFileName) + the 4-character extension. - - CHARACTER(1024) :: BinFileName - CHARACTER(1024) :: PriPath - - - ErrMsg = '' - ErrStat = ErrID_None - - - if (InitInp%NativeBladedFmt) then - call Read_NativeBladedSummary(InitInp%WindFileName, FF_InitInp%PLExp, NatTI, ParamData%FF%MeanFFWS, ParamData%FF%RefHt, InitOut%PropagationDir, InitOut%VFlowAngle, BinFileName, FF_InitInp%XOffset, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - - if (pathIsRelative(BinFileName)) then - CALL GetPath( InitInp%WindFileName, PriPath ) ! Binary file will be relative to the path where the primary input file is located. - BinFileName = TRIM(PriPath)//TRIM(BinFileName) - end if - - IF ( InitInp%FixedWindFileRootName ) THEN ! .TRUE. when FAST.Farm uses multiple instances of InflowWind for ambient wind data - IF ( InitInp%TurbineID == 0 ) THEN ! .TRUE. for the FAST.Farm low-resolution domain - BinFileName = TRIM(BinFileName)//TRIM(PathSep)//'Low' - ELSE ! FAST.Farm high-resolution domain(s) - BinFileName = TRIM(BinFileName)//TRIM(PathSep)//'HighT'//TRIM(Num2Lstr(InitInp%TurbineID)) - ENDIF - ENDIF - - ! default values for Bladed Format - CWise = .false. - ZCenter = ParamData%FF%RefHt - ParamData%FF%Periodic = .true. - - FF_InitInp%ScaleMethod = ScaleMethod_StdDev - FF_InitInp%SigmaF = NatTI * ParamData%FF%MeanFFWS - FF_InitInp%sf = FF_InitInp%SigmaF -! FF_InitInp%ScaleMethod = ScaleMethod_Direct ! Bladed files should have std of 1, so we'll just multiply (closer to what Bladed does) - - FF_InitInp%RefHt = ParamData%FF%RefHt - FF_InitInp%URef = ParamData%FF%MeanFFWS - FF_InitInp%WindProfileType = WindProfileType_PL ! it could also have logarithmic, but I'm going to leave that off for now - - TI = 100.0_ReKi - UBar = 0.0_ReKi - LHR = .true. - - else - InitOut%PropagationDir = 0.0_ReKi - InitOut%VFlowAngle = 0.0_ReKi - BinFileName = InitInp%WindFileName - end if - - - ! Get a unit number to use - - CALL GetNewUnit(UnitWind, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !---------------------------------------------------------------------------------------------- - ! Open the binary file, read its "header" (first 2-byte integer) to determine what format - ! binary file it is, and close it. - !---------------------------------------------------------------------------------------------- - - CALL OpenBInpFile (UnitWind, TRIM(BinFileName), TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - ! Read the first binary integer from the file to get info on the type. - ! Cannot use library read routines since this is a 2-byte integer. - READ ( UnitWind, IOSTAT=TmpErrStat ) Dum_Int2 - CLOSE( UnitWind ) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat(ErrID_Fatal,' Error reading first binary integer from file "'//TRIM(BinFileName)//'."', & - ErrStat,ErrMsg,RoutineName) - RETURN - ENDIF - - - !---------------------------------------------------------------------------------------------- - ! Read the files to get the required FF data. - !---------------------------------------------------------------------------------------------- - - ! Store the binary format information so the InflowWind code can use it. - ! Also changes to IntKi from INT(2) to compare in the SELECT below - ParamData%FF%WindFileFormat = Dum_Int2 - - - SELECT CASE (ParamData%FF%WindFileFormat) - - CASE ( -1, -2, -3, -99 ) ! Bladed-style binary format - - IF (.not. InitInp%NativeBladedFmt) THEN - - !........................................................................................... - ! Create full-field summary file name from binary file root name. Also get tower file - ! name. - !........................................................................................... - - CALL GetRoot(BinFileName, SumFile) - - TwrFile = TRIM(SumFile)//'.twr' - SumFile = TRIM(SumFile)//'.sum' - - - !........................................................................................... - ! Read the summary file to get necessary scaling information - !........................................................................................... - - CALL Read_Summary_FF (UnitWind, TRIM(SumFile), CWise, ZCenter, TI, UBar, ParamData%FF%RefHt, ParamData%FF%Periodic, LHR, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE ( UnitWind ) - RETURN - END IF - - END IF - - - !........................................................................................... - ! Open the binary file and read its header - !........................................................................................... - - CALL OpenBInpFile (UnitWind, TRIM(BinFileName), TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE ( UnitWind ) - RETURN - END IF - - IF ( Dum_Int2 == -99 ) THEN ! Newer-style BLADED format - CALL Read_Bladed_FF_Header1 (UnitWind, BinTI, ParamData%FF, InitInp%NativeBladedFmt, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE ( UnitWind ) - RETURN - END IF - - ! If the TIs are also in the binary file (BinTI > 0), - ! use those numbers instead of ones from the summary file - - if (.not. InitInp%NativeBladedFmt) then - DO I =1,ParamData%FF%NFFComp - IF ( BinTI(I) > 0 ) TI(I) = BinTI(I) - ENDDO - end if - - - ELSE - CALL Read_Bladed_FF_Header0 (UnitWind, ParamData%FF, InitInp%NativeBladedFmt, TmpErrStat, TmpErrMsg) ! Older-style BLADED format - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE ( UnitWind ) - RETURN - END IF - - ENDIF - - - - !........................................................................................... - ! Let's see if the summary and binary FF wind files go together before continuing. - !........................................................................................... - - IF (.not. InitInp%NativeBladedFmt) THEN - IF ( ABS( UBar - ParamData%FF%MeanFFWS ) > 0.1 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error: Incompatible mean hub-height wind speeds in FF wind files. '//& - '(Check that the .sum and .wnd files were generated together.)', ErrStat, ErrMsg, RoutineName ) - CLOSE ( UnitWind ) - RETURN - ENDIF - - END IF - - !........................................................................................... - ! Calculate the height of the bottom of the grid - !........................................................................................... - - ParamData%FF%GridBase = ZCenter - ParamData%FF%FFZHWid ! the location, in meters, of the bottom of the grid - IF ( ParamData%FF%GridBase < 0.0_ReKi ) THEN - call SetErrStat( ErrID_Severe, 'WARNING: The bottom of the grid is located at a height of '//& - TRIM( Num2LStr(ParamData%FF%GridBase) )//' meters, which is below the ground.'//& - ' Winds below the ground will be set to 0.', ErrStat,ErrMsg, RoutineName) - END IF - - !........................................................................................... - ! Read the binary grids (converted to m/s) and close the file - !........................................................................................... - - CALL Read_Bladed_Grids( UnitWind, InitInp%NativeBladedFmt, CWise, LHR, TI, ParamData%FF, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - CLOSE ( UnitWind ) - if (InitInp%NativeBladedFmt) TI = NatTI*100.0_ReKi ! report these TI for the native Bladed format in percent - - IF ( ErrStat >= AbortErrLev ) RETURN - - !........................................................................................... - ! Read the tower points file - !........................................................................................... - - IF ( InitInp%TowerFileExist .AND. .NOT. InitInp%NativeBladedFmt) THEN ! If we specified a tower file - INQUIRE ( FILE=TRIM(TwrFile) , EXIST=Exists ) - - ! Double check that the tower file exists and read it. If it was requested but doesn't exist, - ! throw fatal error and exit. - IF ( Exists ) THEN - CALL Read_FF_Tower( UnitWind, ParamData%FF, TwrFile, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE ( UnitWind ) - RETURN - END IF - ELSE - CALL SetErrStat( ErrID_Fatal, ' Tower file '//TRIM(TwrFile)//' specified for Bladed full-field '// & - 'wind files does not exist.', ErrStat, ErrMsg, RoutineName) - CLOSE ( UnitWind ) - RETURN - ENDIF - ELSE - ParamData%FF%NTGrids = 0_IntKi - ENDIF - - - CASE DEFAULT - CALL SetErrStat( ErrID_Fatal, ' This is not a bladed-style binary wind file (binary format identifier: '// & - TRIM(Num2LStr(ParamData%FF%WindFileFormat))//'. This might be a TurbSim binary wind file.', & - ErrStat, ErrMsg, RoutineName ) - RETURN - - END SELECT - -END SUBROUTINE ReadFiles - - !==================================================================================================== - !> This subroutine reads the text summary file to get normalizing parameters, the location of the - !! grid, and the direction the grid was written to the binary file - !! - !! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 - SUBROUTINE Read_Summary_FF ( UnitWind, FileName, CWise, ZCenter, TI, UBar, RefHt, Periodic, LHR, ErrStat, ErrMsg ) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="Read_Summary_FF" - - - ! Passed variables - INTEGER(IntKi), INTENT(IN ) :: UnitWind !< unit number for the file to open - CHARACTER(*), INTENT(IN ) :: FileName !< name of the summary file - LOGICAL, INTENT( OUT) :: CWise !< rotation (for reading the order of the binary data) - REAL(ReKi), INTENT( OUT) :: ZCenter !< the height at the center of the grid - REAL(ReKi), INTENT( OUT) :: TI (3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI - REAL(ReKi), INTENT( OUT) :: UBar !< mean (advection) wind speed - REAL(ReKi), INTENT( OUT) :: RefHt !< Reference height - LOGICAL, INTENT( OUT) :: Periodic !< rotation (for reading the order of the binary data) - LOGICAL, INTENT( OUT) :: LHR !< Left-hand rule for Bladed files (is the v component aligned along *negative* Y?) - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< returns 0 if no error encountered in the subroutine - CHARACTER(*), INTENT( OUT) :: ErrMsg !< holds the error messages - - ! Local variables - REAL(ReKi) :: ZGOffset ! The vertical offset of the turbine on rectangular grid (allows turbulence not centered on turbine hub) - - INTEGER, PARAMETER :: NumStrings = 7 ! number of strings to be looking for in the file - - INTEGER(IntKi) :: FirstIndx ! The first character of a line where data is located - INTEGER(IntKi) :: I ! A loop counter - INTEGER(IntKi) :: LastIndx ! The last character of a line where data is located - INTEGER(IntKi) :: LineCount ! Number of lines that have been read in the file - - LOGICAL :: StrNeeded(NumStrings) ! if the string has been found - - CHARACTER(1024) :: LINE ! temporary storage for reading a line from the file - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - !---------------------------------------------------------------------------------------------- - ! Initialize some variables - !---------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - LineCount = 0 - StrNeeded(:) = .TRUE. - ZGOffset = 0.0 - RefHt = 0.0 - Periodic = .FALSE. - LHR = .FALSE. - CWise = .FALSE. ! default value, in case it is not in this file - - !---------------------------------------------------------------------------------------------- - ! Open summary file. - !---------------------------------------------------------------------------------------------- - - CALL OpenFInpFile ( UnitWind, TRIM( FileName ), TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !---------------------------------------------------------------------------------------------- - ! Read the summary file. - !---------------------------------------------------------------------------------------------- - - ! Here are the strings we're looking for, in this order: - ! 1) 'CLOCKWISE' (optional) - ! 2) 'HUB HEIGHT' - ! 3) (unused; decided we didn't need to read data also stored in the binary file) - ! 4) 'UBAR' - ! 5) 'HEIGHT OFFSET' (optional) - ! 6) 'PERIODIC' (optional) - ! 7) 'BLADED LEFT-HAND RULE' (optional) - - - DO WHILE ( ( ErrStat == ErrID_None ) .AND. StrNeeded(NumStrings) ) - - LineCount = LineCount + 1 - - READ ( UnitWind, '(A)', IOSTAT=TmpErrStat ) LINE - IF ( TmpErrStat /= 0 ) THEN - - ! the "HEIGHT OFFSET", "PERIODIC", and "BLADED LEFT-HAND RULE" parameters are not necessary. We'll assume they are zero/false if we didn't find it. - ! We will also assume "CLOCKWISE" is false if we didn't find it. - IF ( StrNeeded(2) .OR. StrNeeded(4) ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading line #'//TRIM(Num2LStr(LineCount))//' of the summary file, "'// & - TRIM(FileName)//'". Could not find all of the required parameters.', ErrStat, ErrMsg, RoutineName ) - RETURN - ELSE - EXIT - ENDIF - - ENDIF - - CALL Conv2UC ( LINE ) - - - IF ( StrNeeded(2) ) THEN ! if "CLOCKWISE" (StrNeeded(1)) is in the file, we would have already read it. If not, it's not in this file. - - IF ( StrNeeded(1) ) THEN - - !------------------------------------------------------------------------------------------- - ! #1: Get the rotation direction, using the string "CLOCKWISE" - !------------------------------------------------------------------------------------------- - - IF ( INDEX( LINE, 'CLOCKWISE' ) > 0 ) THEN - - READ (LINE, *, IOSTAT = TmpErrStat) CWise ! Look for True/False values - - IF ( TmpErrStat /= 0 ) THEN ! Look for Yes/No values instead - - LINE = ADJUSTL ( LINE ) ! Remove leading spaces from input line - - SELECT CASE (LINE(1:1) ) - CASE ('Y') - CWise = .TRUE. - CASE ('N') - CWise = .FALSE. - CASE DEFAULT - CALL SetErrStat( ErrID_Fatal, ' Error reading rotation direction (CLOCKWISE) from FF summary file.', ErrStat, ErrMsg, RoutineName ) - RETURN - END SELECT - CYCLE - - ENDIF ! TmpErrStat /= 0 - StrNeeded(1) = .FALSE. - - ENDIF ! INDEX for "CLOCKWISE" - - END IF - - !------------------------------------------------------------------------------------------- - ! #2: Get the hub height, using the strings "HUB HEIGHT" or "ZHUB" - !------------------------------------------------------------------------------------------- - - IF ( INDEX( LINE, 'HUB HEIGHT' ) > 0 .OR. INDEX( LINE, 'ZHUB' ) > 0 ) THEN - - READ (LINE, *, IOSTAT = TmpErrStat) RefHt - - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading hub height from FF summary file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - StrNeeded(2) = .FALSE. - - ENDIF !INDEX for "HUB HEIGHT" or "ZHUB" - - ! ELSEIF ( StrNeeded(3) ) THEN - ! - ! !------------------------------------------------------------------------------------------- - ! ! #3: Get the grid width (& height, if available), using the strings "GRID WIDTH" or "RDIAM" - ! ! If GRID HEIGHT is specified, use it, too. -- THIS IS UNNECESSARY AS IT'S STORED IN THE BINARY FILE - ! !------------------------------------------------------------------------------------------- - - ELSEIF ( StrNeeded(4) ) THEN - - !------------------------------------------------------------------------------------------- - ! #4: Get the mean wind speed "UBAR" and turbulence intensities from following lines for - ! scaling Bladed-style FF binary files - !------------------------------------------------------------------------------------------- - - IF ( INDEX( LINE, 'UBAR') > 0 ) THEN - - FirstIndx = INDEX( LINE, '=' ) + 1 ! Look for the equal siqn to find the number we're looking for - - READ ( LINE( FirstIndx:LEN(LINE) ), *, IOSTAT=TmpErrStat ) UBar - - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading UBar binary data normalizing parameter from FF summary file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - DO I = 1,3 - - LineCount = LineCount + 1 - - READ ( UnitWind, '(A)', IOSTAT=TmpErrStat ) LINE - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading line #'//TRIM(Num2LStr(LineCount))//' of the summary file, "'//TRIM(FileName)//& - '". Could not find all of the required parameters.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - FirstIndx = INDEX( LINE, '=' ) + 1 ! Read the number between the = and % signs - LastIndx = INDEX( LINE, '%' ) - 1 - - IF ( LastIndx <= FirstIndx ) LastIndx = LEN( LINE ) ! If there's no % sign, read to the end of the line - - READ ( LINE( FirstIndx:LastIndx ), *, IOSTAT=TmpErrStat ) TI(I) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading TI('//TRIM(Num2LStr(I))// & - ') binary data normalizing parameter from FF summary file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ENDDO !I - - StrNeeded(4) = .FALSE. - - ENDIF - - ELSEIF ( StrNeeded(5) ) THEN - - !------------------------------------------------------------------------------------------- - ! #5: Get the grid "HEIGHT OFFSET", if it exists (in TurbSim). Otherwise, assume it's zero - ! ZGOffset = HH - GridBase - ParamData%FF%FFZHWid - !------------------------------------------------------------------------------------------- - IF ( INDEX( LINE, 'HEIGHT OFFSET' ) > 0 ) THEN - - FirstIndx = INDEX ( LINE, '=' ) + 1 - - READ ( LINE( FirstIndx:LEN(LINE) ), *, IOSTAT=TmpErrStat ) ZGOffset - - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading height offset from FF summary file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - StrNeeded(5) = .FALSE. - - ENDIF !INDEX for "HEIGHT OFFSET" - - ELSE - - IF ( StrNeeded(6) ) THEN - - !------------------------------------------------------------------------------------------- - ! #6: Get the grid "PERIODIC", if it exists (in TurbSim). Otherwise, assume it's - ! not a periodic file (would only show up if the HEIGHT OFFSET is in the file) - !------------------------------------------------------------------------------------------- - IF ( INDEX( LINE, 'PERIODIC' ) > 0 ) THEN - - Periodic = .TRUE. - StrNeeded(6) = .FALSE. - CYCLE - ENDIF !INDEX for "PERIODIC" - END IF - - IF ( StrNeeded(7) ) THEN - - IF ( INDEX( LINE, 'BLADED LEFT-HAND RULE') > 0 ) THEN - LHR = .TRUE. - StrNeeded(7) = .FALSE. - END IF ! INDEX for "BLADED LEFT-HAND RULE" - - END IF - - ENDIF ! StrNeeded - - ENDDO !WHILE - - !------------------------------------------------------------------------------------------------- - ! Close the summary file - !------------------------------------------------------------------------------------------------- - - CLOSE ( UnitWind ) - - - !------------------------------------------------------------------------------------------------- - ! Calculate the height of the grid center - !------------------------------------------------------------------------------------------------- - - ZCenter = RefHt - ZGOffset - - - END SUBROUTINE Read_Summary_FF - - !==================================================================================================== - !> Reads the binary headers from the turbulence files of the old Bladed variety. Note that - !! because of the normalization, neither ParamData%FF%NZGrids or ParamData%FF%NYGrids are larger than 32 points. - !! 21-Sep-2009 - B. Jonkman, NREL/NWTC. - !! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 - SUBROUTINE Read_Bladed_FF_Header0 (UnitWind, p, NativeBladedFmt, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="Read_Bladed_FF_Header0" - - ! Passed Variables: - - INTEGER(IntKi), INTENT(IN ) :: UnitWind !< unit number of already-opened wind file - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: p !< Parameters - LOGICAL, INTENT(IN ) :: NativeBladedFmt !< Whether this should ignore the advection speed in the binary file - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message - - - ! Local Variables: - REAL(ReKi) :: FFXDelt - REAL(ReKi) :: FFYDelt - REAL(ReKi) :: FFZDelt - - INTEGER(B2Ki) :: Dum_Int2 - INTEGER(IntKi) :: I - - - ! Temporary Error Handling - INTEGER(IntKi) :: TmpErrStat ! for checking the IOSTAT from a READ or Open statement - - - !------------------------------------------------------------------------------------------------- - ! Initializations - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - - !------------------------------------------------------------------------------------------------- - ! Read the header (file has just been opened) - !------------------------------------------------------------------------------------------------- - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! -NFFC (file ID) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading number of wind components from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NFFComp = -1*Dum_Int2 - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! delta z (mm) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dz from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - FFZDelt = 0.001*Dum_Int2 - p%InvFFZD = 1.0/FFZDelt - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! delta y (mm) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dy from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - FFYDelt = 0.001*Dum_Int2 - p%InvFFYD = 1.0/FFYDelt - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! delta x (mm) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dx from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - FFXDelt = 0.001*Dum_Int2 - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! half the number of time steps - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading number of time steps from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NFFSteps = 2*Dum_Int2 - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! 10 times the mean full-field wind speed - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading mean full-field wind speed from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - if (.not. NativeBladedFmt) p%MeanFFWS = 0.1*Dum_Int2 - p%InvMFFWS = 1.0/p%MeanFFWS - p%FFDTime = FFXDelt/p%MeanFFWS - p%FFRate = 1.0/p%FFDTime - - - DO I = 1,5 - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! unused variables: zLu, yLu, xLu, dummy, random seed - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 2-byte integers from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - END DO - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! 1000*nz - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading nz from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NZGrids = Dum_Int2/1000 - p%FFZHWid = 0.5*FFZDelt*( p%NZGrids - 1 ) ! half the vertical size of the grid - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! 1000*ny - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading ny from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NYGrids = Dum_Int2/1000 - p%FFYHWid = 0.5*FFYDelt*( p%NYGrids - 1 ) - - - IF (p%NFFComp == 3) THEN - - DO I=1,6 - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! unused variables: zLv, yLv, xLv, zLw, yLw, xLw - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 2-byte length scales from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - ENDIF !NFFComp - - - RETURN - - END SUBROUTINE Read_Bladed_FF_Header0 - !==================================================================================================== - !> Reads the binary headers from the turbulence files of the new Bladed variety. - !! 16-May-2002 - Windward Engineering. - !! 21-Sep-2009 - B. Jonkman, NREL. updated to trap errors and add extra parameters for MANN model - !! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 - SUBROUTINE Read_Bladed_FF_Header1 (UnitWind, TI, p, NativeBladedFmt, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="Read_Bladed_FF_Header1" - - - ! Passed Variables: - - INTEGER(IntKi), INTENT(IN ) :: UnitWind !< unit number of already-opened wind file - REAL(ReKi), INTENT( OUT) :: TI(3) !< turbulence intensity contained in file header - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: p !< Parameters - LOGICAL, INTENT(IN ) :: NativeBladedFmt !< Whether this should ignore the advection speed in the binary file - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message - - - ! Local Variables: - - REAL(ReKi) :: FFXDelt - REAL(ReKi) :: FFYDelt - REAL(ReKi) :: FFZDelt - - REAL(SiKi) :: Dum_Real4 - INTEGER(B2Ki) :: Dum_Int2 - INTEGER(B4Ki) :: Dum_Int4 - - INTEGER(IntKi) :: I - INTEGER(IntKi) :: TurbType - - - ! Temporary Error Handling - INTEGER(IntKi) :: TmpErrStat - - - !------------------------------------------------------------------------------------------------- - ! Initializations - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - TI(:) = -1 !Initialize to -1 (not all models contain TI) - - !------------------------------------------------------------------------------------------------- - ! File reading - !------------------------------------------------------------------------------------------------- - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! -99 (file ID) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading integer from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! turbulence type - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading turbulence type from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - TurbType = Dum_Int2 - - - SELECT CASE (TurbType) - CASE(1, 2) - !---------------------------------------- - !1-component Von Karman (1) or Kaimal (2) - !---------------------------------------- - p%NFFComp = 1 - - CASE(3, 5) - !---------------------------------------- - !3-component Von Karman (3) or IEC-2 - ! Kaimal (5) - !---------------------------------------- - p%NFFComp = 3 - - CASE(4) - !---------------------------------------- - !improved Von Karman - !---------------------------------------- - - ! Read 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! number of components (should be 3) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading number of components from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NFFComp = Dum_Int4 - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! Latitude (deg) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading latitude from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! Roughness length (m) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading roughness length from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! Reference height (m) = Z(1) + GridHeight / 2.0 - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading reference height from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - - DO I = 1,3 - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! TI(u, v, w) (%) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading TI('//'TRIM(Num2LStr(I))'//') from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - TI(I) = Dum_Real4 ! This overwrites the TI read in the summary file - - END DO !I - - - CASE (7, 8) - !---------------------------------------- - ! General Kaimal (7) or Mann model (8) - !---------------------------------------- - - ! Read 4-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! number of bytes in header - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading number of header records from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ! Read 4-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! number of components - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading number of data from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NFFComp = Dum_Int4 - - - CASE DEFAULT - - CALL SetErrStat( ErrID_Warn, ' InflowWind does not recognize the full-field turbulence file type ='// & - TRIM(Num2LStr(TurbType))//'.', ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - END SELECT !TurbType - - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! delta z (m) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dz from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - FFZDelt = Dum_Real4 - p%InvFFZD = 1.0/FFZDelt - - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! delta y (m) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dy from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - FFYDelt = Dum_Real4 - p%InvFFYD = 1.0/FFYDelt - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! delta x (m) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dx from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - FFXDelt = Dum_Real4 - - - ! Read 4-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! half the number of time steps - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading number of time steps from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NFFSteps = 2*Dum_Int4 - - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! mean full-field wind speed - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading mean full-field wind speed from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - if (.not. NativeBladedFmt) p%MeanFFWS = Dum_Real4 - p%InvMFFWS = 1.0/p%MeanFFWS - p%FFDTime = FFXDelt/p%MeanFFWS - p%FFRate = 1.0/p%FFDTime - - - DO I = 1,3 - - ! Read 4-byte real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables: zLu, yLu, xLu - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte length scales from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - END DO - - - DO I = 1,2 - - ! Read 4-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! unused variables: dummy, random seed - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte integers from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - END DO - - - ! Read 4-integer real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! nz - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading nz from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NZGrids = Dum_Int4 - p%FFZHWid = 0.5*FFZDelt*( p%NZGrids - 1 ) ! half the vertical size of the grid - - - ! Read 4-integer real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! ny - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading ny from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - p%NYGrids = Dum_Int4 - p%FFYHWid = 0.5*FFYDelt*( p%NYGrids - 1 ) - - - IF (p%NFFComp == 3) THEN - - DO I=1,6 - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables: zLv, yLv, xLv, zLw, yLw, xLw - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte length scales from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - ENDIF !NFFComp - - - - IF ( TurbType == 7 ) THEN ! General Kaimal model - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variable: coherence decay constant - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading coherence decay constant from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables: coherence scale parameter in m - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading coherence scale parameter from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ELSE IF ( TurbType == 8 ) THEN ! Mann model - - DO I=1,2 - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables: shear parameter (gamma), scale length - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte parameters from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - DO I=1,4 - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte parameters from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - DO I=1,3 - - ! Read 4-integer real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! unused variables - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte parameters from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - DO I=1,2 - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte parameters from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - DO I=1,3 - - ! Read 4-integer real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! unused variables - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte parameters from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - DO I=1,2 - - ! Read 4-real real. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! unused variables - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading 4-byte parameters from binary FF file.', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - - ENDDO !I - - - ENDIF !TurbType - - - RETURN - - END SUBROUTINE Read_Bladed_FF_Header1 - !==================================================================================================== - !> This subroutine continues reading UnitWind, starting after the headers have been read. - !! It reads the Grids and converts the data to un-normalized wind speeds in m/s. - !! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 - SUBROUTINE Read_Bladed_Grids ( UnitWind, NativeBladedFmt, CWise, LHR, TI, p, ErrStat, ErrMsg ) - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="Read_Bladed_Grids" - - ! Passed variables - - INTEGER(IntKi), INTENT(IN ) :: UnitWind !< unit number of already-opened wind file - LOGICAL, INTENT(IN ) :: NativeBladedFmt !< whether this data is in native Bladed format (scale to zero mean and unit standard deviation) - LOGICAL, INTENT(IN ) :: CWise !< clockwise flag (determines if y is increasing or decreasing in file) - LOGICAL, INTENT(IN ) :: LHR !< Left-hand rule for Bladed files (is the v component aligned along *negative* Y?) - REAL(ReKi), INTENT(IN ) :: TI (3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: p !< Parameters - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message - - REAL(ReKi) :: FF_Scale(3) !< used for "un-normalizing" the data - REAL(ReKi) :: FF_Offset(3) !< used for "un-normalizing" the data - - INTEGER(IntKi) :: CFirst - INTEGER(IntKi) :: CLast - INTEGER(IntKi) :: CStep - INTEGER(B2Ki) :: Dum_Int2 - INTEGER(IntKi) :: I - INTEGER(IntKi) :: IC - INTEGER(IntKi) :: IR - INTEGER(IntKi) :: IT - - INTEGER(IntKi) :: TmpNumSteps - - ! Temporary variables for error handling - - INTEGER(IntKi) :: TmpErrStat ! for checking the result of IOSTAT on READ or Open statements - CHARACTER(ErrMsgLen) :: TmpErrMsg - - IF (NativeBladedFmt) THEN - FF_Scale = 0.001_ReKi - FF_Offset = 0.0_ReKi - ELSE - FF_Scale = 0.001_ReKi*p%MeanFFWS*TI/100.0_ReKi - FF_Offset= (/ p%MeanFFWS, 0.0_ReKi, 0.0_ReKi /) ! used for "un-normalizing" the data - END IF - - ! Bladed convention has positive V pointed along negative Y - IF (LHR) THEN ! left-hand rule - FF_Scale(2) = -FF_Scale(2) - END IF - - - !------------------------------------------------------------------------------------------------- - ! Generate an informative message. Initialize the ErrStat. - !------------------------------------------------------------------------------------------------- - ! This could take a while, so we'll write a message to tell users what's going on: - - CALL WrScr( NewLine//' Reading a '//TRIM( Num2LStr(p%NYGrids) )//'x'//TRIM( Num2LStr(p%NZGrids) )// & - ' grid ('//TRIM( Num2LStr(p%FFYHWid*2) )//' m wide, '// & - TRIM( Num2LStr(p%GridBase) )//' m to '// & - TRIM( Num2LStr(p%GridBase+p%FFZHWid*2) )//& - ' m above ground) with a characteristic wind speed of '//TRIM( Num2LStr(p%MeanFFWS) )//' m/s. ' ) - ErrMsg = "" - ErrStat = ErrID_None - - - !------------------------------------------------------------------------------------------------- - ! Allocate space for the FF array - !------------------------------------------------------------------------------------------------- - - TmpNumSteps = p%NFFSteps + 1 ! add another step, just in case there is an odd number of steps. - - !bjj: should we reorganize this FFData array so we access the data faster? - - IF ( .NOT. ALLOCATED( p%FFData ) ) THEN - CALL AllocAry( p%FFData, p%NZGrids,p%NYGrids,p%NFFComp,TmpNumSteps, & - 'Full-field wind data array.', TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - ELSE - IF (SIZE(p%FFData,1) /= p%NZGrids .OR. SIZE(p%FFData,2) /= p%NYGrids .OR. & - SIZE(p%FFData,3) /= p%NFFComp .OR. SIZE(p%FFData,3) /= TmpNumSteps ) THEN - - ! Let's make the array the correct size (we should never get here, but you never know) - - DEALLOCATE( p%FFData ) - - CALL AllocAry( p%FFData, p%NZGrids,p%NYGrids,p%NFFComp,TmpNumSteps, & - 'Full-field wind data array.', TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - ENDIF !Incorrect size - ENDIF ! allocated - - !------------------------------------------------------------------------------------------------- - ! Initialize the data and set column indexing to account for direction of turbine rotation (CWise) - !------------------------------------------------------------------------------------------------- - - p%FFData(:,:,:,:) = 0.0 ! we may have only one component - - IF ( CWise ) THEN - CFirst = p%NYGrids - CLast = 1 - CStep = -1 - ELSE - CFirst = 1 - CLast = p%NYGrids - CStep = 1 - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Loop through all the time steps, reading the data and converting to m/s - !------------------------------------------------------------------------------------------------- - !bjj: should we reorganize this FFData array so we access the data faster? - - p%NFFSteps = TmpNumSteps - - TIME_LOOP: DO IT=1,TmpNumSteps ! time (add 1 to see if there is an odd number of grids) - - DO IR=1,p%NZGrids ! the rows (vertical) - - DO IC=CFirst,CLast,CStep ! the columns (lateral) - - DO I=1,p%NFFComp ! wind components (U, V, W) - - ! Get the next integer from the file. - ! This is a 2-byte integer, so we can't use the library read routines. - READ (UnitWind,IOStat=TmpErrStat) Dum_Int2 - IF (TmpErrStat /= 0) THEN - IF ( IT == TmpNumSteps ) THEN ! There really were an even number of steps - p%NFFSteps = TmpNumSteps - 1 - ErrStat = 0 - EXIT TIME_LOOP - ELSE - CALL SetErrStat( ErrID_Fatal, ' Error reading binary data file. '// & - 'ic = '//TRIM(Num2LStr(ic))// & - ', ir = '//TRIM(Num2LStr(ir))// & - ', it = '//TRIM(Num2LStr(it))// & - ', nffsteps = '//TRIM(Num2LStr(p%NFFSteps)), ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - ELSE - p%FFData(IR,IC,I,IT) = FF_Offset(I)+FF_Scale(I)*Dum_Int2 - ENDIF - - END DO !I - - END DO !IC - - END DO !IR - - END DO TIME_LOOP !IT - - IF ( p%Periodic ) THEN - TmpErrMsg = ' Processed '//TRIM( Num2LStr( p%NFFSteps ) )//' time steps of '// & - TRIM( Num2LStr ( p%FFRate ) )//'-Hz full-field data (period of '// & - TRIM( Num2LStr( p%FFDTime*p%NFFSteps ) )//' seconds).' - - ELSE - TmpErrMsg= ' Processed '//TRIM( Num2LStr( p%NFFSteps ) )//' time steps of '// & - TRIM( Num2LStr ( p%FFRate ) )//'-Hz full-field data ('// & - TRIM( Num2LStr( p%FFDTime*( p%NFFSteps - 1 ) ) )//' seconds).' - ENDIF - CALL WrScr( NewLine//TRIM(TmpErrMsg) ) - !CALL SetErrStat( ErrID_Info, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - - END SUBROUTINE Read_Bladed_Grids - !==================================================================================================== - !> This subroutine reads the binary tower file that corresponds with the Bladed-style FF binary file. - !! The FF grid must be read before this subroutine is called! (many checks are made to ensure the - !! files belong together) - !! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 - SUBROUTINE Read_FF_Tower( UnitWind, p, TwrFileName, ErrStat, ErrMsg ) - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="Read_FF_Tower" - - - ! Passed Variables: - INTEGER(IntKi) :: UnitWind !< unit number of wind file to be opened - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: p !< Parameters - CHARACTER(*), INTENT(IN ) :: TwrFileName - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status return value (0=no error; non-zero is error) - CHARACTER(*), INTENT( OUT) :: ErrMsg !< a message for errors that occur - - ! Local Variables: - - REAL(SiKi) :: Dum_Real4 ! dummy 4-byte real number - INTEGER(B2Ki) :: Dum_Int2 ! dummy 2-byte integer - INTEGER(B4Ki) :: Dum_Int4 ! dummy 4-byte integer - - INTEGER(IntKi) :: IC ! loop counter for wind components - INTEGER(IntKi) :: IT ! loop counter for time - INTEGER(IntKi) :: IZ ! loop counter for z - - REAL(ReKi), PARAMETER :: TOL = 1E-4 ! tolerence for wind file comparisons - - REAL(ReKi), PARAMETER :: FF_Offset(3) = (/ 1.0, 0.0, 0.0 /) ! used for "un-normalizing" the data - REAL(SiKi) :: TI (3) ! scaling values for "un-normalizing the data" [approx. turbulence intensities of the wind components] - - - ! Temporary Error Handling - - INTEGER(IntKi) :: TmpErrStat ! IOSTAT value. - CHARACTER(ErrMsgLen) :: TmpErrMsg - - !------------------------------------------------------------------------------------------------- - ! Initialization - !------------------------------------------------------------------------------------------------- - - ErrMsg = '' - ErrStat = ErrID_None - - p%NTGrids = 0 - - IF ( p%NFFComp /= 3 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error: Tower binary files require 3 wind components.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - !------------------------------------------------------------------------------------------------- - ! Open the file - !------------------------------------------------------------------------------------------------- - - CALL OpenBInpFile (UnitWind, TRIM(TwrFileName), TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN - - !------------------------------------------------------------------------------------------------- - ! Read the header information and check that it's compatible with the FF Bladed-style binary - ! parameters already read. - !------------------------------------------------------------------------------------------------- - ! This is a 4-byte real, so we can't use the library read routines. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! dz, in meters [4-byte REAL] - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dz in the binary tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - IF ( ABS(Dum_Real4*p%InvFFZD-1) > TOL ) THEN - CALL SetErrStat( ErrID_Fatal, ' Resolution in the FF binary file does not match the tower file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - - ! This is a 4-byte real, so we can't use the library read routines. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! dx, in meters [4-byte REAL] - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dx in the binary tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - IF ( ABS(Dum_Real4*p%InvMFFWS/p%FFDTime-1) > TOL ) THEN - CALL SetErrStat( ErrID_Fatal, ' Time resolution in the FF binary file does not match the tower file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - - ! This is a 4-byte real, so we can't use the library read routines. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! Zmax, in meters [4-byte REAL] - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading Zmax in the binary tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - IF ( ABS(Dum_Real4/p%GridBase-1) > TOL ) THEN - CALL SetErrStat( ErrID_Fatal, ' Height in the FF binary file does not match the tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - - ! This is a 4-byte integer, so we can't use the library read routines. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! NumOutSteps [4-byte INTEGER] - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading NumOutSteps in the binary tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - IF ( Dum_Int4 /= p%NFFSteps ) THEN - CALL SetErrStat( ErrID_Fatal, ' Number of time steps in the FF binary file does not match the tower file.', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - - ! This is a 4-byte integer, so we can't use the library read routines. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! NumZ [4-byte INTEGER] - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading NumZ in the binary tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - p%NTGrids = Dum_Int4 - - - ! This is a 4-byte real, so we can't use the library read routines. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! UHub [4-byte REAL] - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading UHub in the binary tower file "'//TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - IF ( ABS(Dum_Real4*p%InvMFFWS - 1) > TOL ) THEN - CALL SetErrStat( ErrID_Fatal, ' Mean wind speed in the FF binary file does not match the tower file.', ErrStat, ErrMsg, RoutineName ) - p%NTGrids = 0 - RETURN - ENDIF - - - DO IC=1,3 - ! Read the TI values fromthe tower file: 4-byte reals. - - !bjj: not sure you can call this routine to read from a binary file... - !CALL ReadVar( UnitWind, TRIM(InitInp%WindFileName), TI(IC), 'TI('//TRIM(Num2LStr(IC))//')', 'TI value for u,v, or w', TmpErrStat, TmpErrMsg ) - !IF (TmpErrStat /= ErrID_None) THEN - ! p%NTGrids = 0 - ! CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - ! IF (ErrStat >= AbortErrLev) RETURN - !ENDIF - ! - READ (UnitWind, IOSTAT=TmpErrStat) TI(IC) ! TI(u), TI(v), TI(w) [4-byte REAL] - - IF (TmpErrStat /= 0) THEN - p%NTGrids = 0 - CALL SetErrStat( ErrID_Fatal, ' Error reading TI('//TRIM(Num2LStr(IC))//') in the binary tower file "' & - //TRIM( TwrFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - END DO - - !---------------------------------------------------------------------------------------------- - ! Allocate arrays for the tower points - !---------------------------------------------------------------------------------------------- - - IF ( p%NTGrids > 0 ) THEN - - IF ( .NOT. ALLOCATED( p%FFTower ) ) THEN - CALL AllocAry( p%FFTower, p%NFFComp, p%NTGrids, p%NFFSteps, & - 'Tower wind data array.', TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN - - ELSE - ! Check sizes here! - ENDIF - - ENDIF - - !------------------------------------------------------------------------------------------------- - ! Read the 16-bit time-series data and scale it to 32-bit reals - !------------------------------------------------------------------------------------------------- - - ! Loop through time. - - DO IT=1,p%NFFSteps - - DO IZ=1,p%NTGrids ! If NTGrids<1, there are no tower points & FFTower is not allocated - - ! Ytower = 0 ! Lateral location of the tower data point, in m relative to tower centerline - ! Ztower(IZ) = Z1 - (IZ-1)*dz ! Vertical location of tower data point, in m relative to ground - - DO IC=1,p%NFFComp ! number of wind components - - ! Read in the 2-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! normalized wind-component, INT(2) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading binary tower data file. it = '//TRIM(Num2LStr(it))// & - ', nffsteps = '//TRIM(Num2LStr(p%NFFSteps)), ErrStat, ErrMsg, RoutineName ) - p%NTGrids = 0 - RETURN - ENDIF - - p%FFTower(IC,IZ,IT) = p%MeanFFWS*(FF_Offset(IC)+0.00001*TI(IC)*Dum_Int2) ! wind-component scaled to m/s - - ENDDO !IC - - ENDDO ! IZ - - - ENDDO ! IT - - !------------------------------------------------------------------------------------------------- - ! Close the file - !------------------------------------------------------------------------------------------------- - CLOSE ( UnitWind ) - - TmpErrMsg = ' Processed '//TRIM( Num2LStr(p%NFFSteps) )//' time steps of '// & - TRIM( Num2LStr(p%NTGrids) )//'x1 tower data grids.' - - !CALL SetErrStat( ErrID_Info, ErrMsgLcl, ErrStat, ErrMsg, RoutineName ) - CALL WrScr( NewLine//TRIM(TmpErrMsg) ) - - RETURN - - END SUBROUTINE Read_FF_Tower -!==================================================================================================== -!> This subroutine reads the text summary file to get normalizing parameters, the location of the -!! grid, and the direction the grid was written to the binary file -SUBROUTINE Read_NativeBladedSummary ( FileName, PLExp, TI, UBar, RefHt, PropagationDir, VFlowAngle, BinFileName, XOffset, ErrStat, ErrMsg ) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="Read_NativeBladedSummary" - - - ! Passed variables - CHARACTER(*), INTENT(IN ) :: FileName !< name of the summary file - REAL(ReKi), INTENT( OUT) :: PLExp !< the power-law exponent for vertical wind shear - REAL(ReKi), INTENT( OUT) :: TI (3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI - REAL(ReKi), INTENT( OUT) :: UBar !< mean (advection) wind speed - REAL(ReKi), INTENT( OUT) :: RefHt !< Reference height - REAL(ReKi), INTENT( OUT) :: PropagationDir !< propagation direction - REAL(ReKi), INTENT( OUT) :: VFlowAngle !< vertical flow angle - CHARACTER(*), INTENT( OUT) :: BinFileName !< name of the binary file containing wind data - REAL(ReKi), INTENT( OUT) :: XOffset !< distance offset for start of wind files - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< returns 0 if no error encountered in the subroutine - CHARACTER(*), INTENT( OUT) :: ErrMsg !< holds the error messages - - ! Local variables - INTEGER(IntKi), PARAMETER :: UnEc= -1 ! echo file unit number (set to something else > 0 for debugging) - INTEGER(IntKi) :: CurLine ! Current line to parse in FileInfo data structure - INTEGER(IntKi) :: ErrStat2 ! temporary error status - CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary error message - - TYPE (FileInfoType) :: FileInfo ! The derived type for holding the file information. - - - !---------------------------------------------------------------------------------------------- - ! Initialize some variables - !---------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - !---------------------------------------------------------------------------------------------- - ! Open and read the summary file; store data in FileInfo structure. - !---------------------------------------------------------------------------------------------- - - CALL ProcessComFile ( FileName, FileInfo, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - !------------------------------------------------------------------------------------------------- - ! Process the lines stored in FileInfo - !------------------------------------------------------------------------------------------------- - - CurLine = 1 - - CALL ParseVar ( FileInfo, CurLine, 'UBAR', UBar, ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ParseVar ( FileInfo, CurLine, 'REFHT', RefHt, ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ParseVar ( FileInfo, CurLine, 'TI', TI(1), ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ParseVar ( FileInfo, CurLine, 'TI_V', TI(2), ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ParseVar ( FileInfo, CurLine, 'TI_W', TI(3), ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ParseVar ( FileInfo, CurLine, 'WDIR', PropagationDir, ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - PropagationDir = R2D*PropagationDir - - CALL ParseVar ( FileInfo, CurLine, 'FLINC', VFlowAngle, ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - VFlowAngle = R2D*VFlowAngle ! convert to degrees - - CALL ParseVar ( FileInfo, CurLine, 'WINDF', BinFileName, ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ParseVar ( FileInfo, CurLine, 'WSHEAR', PLExp, ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - END IF - - CALL ParseVar ( FileInfo, CurLine, 'XOffset', XOffset, ErrStat2, ErrMsg2, UnEc ) - if (ErrStat2/=ErrID_None) then - XOffset = 0.0_ReKi ! this will be the default if offset is not in the file - end if - - - !------------------------------------------------------------------------------------------------- - ! Get rid of the FileInfo data structure (including pointers and allocatable array): - !------------------------------------------------------------------------------------------------- - - call Cleanup ( ) - - -CONTAINS - - SUBROUTINE Cleanup () - CALL NWTC_Library_DestroyFileInfoType (FileInfo, ErrStat2, ErrMsg2) - END SUBROUTINE Cleanup - -END SUBROUTINE Read_NativeBladedSummary -!==================================================================================================== - - -!==================================================================================================== -!> This routine acts as a wrapper for the GetWindSpeed routine. It steps through the array of input -!! positions and calls the GetWindSpeed routine to calculate the velocities at each point. -!! -!! There are inefficiencies in how this set of routines is coded, but that is a problem for another -!! day. For now, it merely needs to be functional. It can be fixed up and made all pretty later. -!! -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE IfW_BladedFFWind_CalcOutput(Time, PositionXYZ, ParamData, Velocity, DiskVel, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_BladedFFWind_CalcOutput" - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_BladedFFWind_ParameterType), INTENT(IN ) :: ParamData !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - REAL(ReKi), INTENT( OUT) :: DiskVel(3) !< HACK for AD14: disk velocity output at Time - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(INOUT) :: MiscVars !< misc/optimization data (storage for the main data) - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - - - CALL IfW_FFWind_CalcOutput(Time, PositionXYZ, ParamData%FF, Velocity, DiskVel, ErrStat, ErrMsg) - - - RETURN - -END SUBROUTINE IfW_BladedFFWind_CalcOutput - -!==================================================================================================== -!! This subroutine cleans up any data that is still allocated. The (possibly) open files are -!! closed in InflowWindMod. -!! -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE IfW_BladedFFWind_End( ParamData, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_BladedFFWind_End" - ! Passed Variables - TYPE(IfW_BladedFFWind_ParameterType), INTENT(INOUT) :: ParamData !< Parameters - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(INOUT) :: MiscVars !< misc/optimization data (storage for the main data) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Local Variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !-=- Initialize the routine -=- - - ErrMsg = '' - ErrStat = ErrID_None - - - - ! Destroy parameter data - - CALL IfW_BladedFFWind_DestroyParam( ParamData, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - ! Destroy the state data - - CALL IfW_BladedFFWind_DestroyMisc( MiscVars, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - -END SUBROUTINE IfW_BladedFFWind_End - -!==================================================================================================== -END MODULE IfW_BladedFFWind diff --git a/modules/inflowwind/src/IfW_BladedFFWind.txt b/modules/inflowwind/src/IfW_BladedFFWind.txt deleted file mode 100644 index 76a57b1b5..000000000 --- a/modules/inflowwind/src/IfW_BladedFFWind.txt +++ /dev/null @@ -1,41 +0,0 @@ -################################################################################################################################### -# Registry for IfW_BladedFFWind, creates MODULE IfW_BladedFFWind_Types -# Module IfW_BladedFFWind_Types contains all of the user-defined types needed in IfW_BladedFFWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - -include Registry_NWTC_Library.txt -usefrom IfW_FFWind_Base.txt - - -######################### - -typedef IfW_BladedFFWind/IfW_BladedFFWind InitInputType CHARACTER(1024) WindFileName - - - "Name of the wind file to use" - -typedef ^ ^ Logical TowerFileExist - - - "Tower file exists" - -typedef ^ ^ IntKi SumFileUnit - - - "Unit number for the summary file (-1 for none). Provided by IfW." - -typedef ^ ^ Logical NativeBladedFmt - - - "Whether this is native Bladed (needs wind profile and TI scaling) or not" - -typedef ^ ^ IntKi TurbineID - 0 - "Wind turbine ID number in the fixed (DEFAULT) file name when FixedWindFileRootName = .TRUE. (used by FAST.Farm)" - -typedef ^ ^ LOGICAL FixedWindFileRootName - .FALSE. - "Do the wind data files have a fixed (DEFAULT) file name? (used by FAST.Farm)" - -#typedef ^ ^ IfW_FFWind_InitInputType FF - - - "scaling data (provided for native Bladed format)" - - - -# Init Output -typedef ^ InitOutputType ProgDesc Ver - - - "Version information off FFWind submodule" - -typedef ^ ^ ReKi TI {3} - - "Turbulence intensity given in the file" - -typedef ^ InitOutputType ReKi PropagationDir - - - "Propogation direction from native Bladed format" degrees -typedef ^ InitOutputType ReKi VFlowAngle - - - "Vertical flow angle from native Bladed format" degrees - - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType IntKi dummy - 0 - "An Index into the TData array" - - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType IfW_FFWind_ParameterType FF - - - "Parameters used in all full-field wind types" - - diff --git a/modules/inflowwind/src/IfW_BladedFFWind_Types.f90 b/modules/inflowwind/src/IfW_BladedFFWind_Types.f90 deleted file mode 100644 index 2b6c032c8..000000000 --- a/modules/inflowwind/src/IfW_BladedFFWind_Types.f90 +++ /dev/null @@ -1,797 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_BladedFFWind_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_BladedFFWind_Types -!................................................................................................................................. -! This file is part of IfW_BladedFFWind. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_BladedFFWind. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_BladedFFWind_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE IfW_FFWind_Base_Types -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_BladedFFWind_InitInputType ======= - TYPE, PUBLIC :: IfW_BladedFFWind_InitInputType - CHARACTER(1024) :: WindFileName !< Name of the wind file to use [-] - LOGICAL :: TowerFileExist !< Tower file exists [-] - INTEGER(IntKi) :: SumFileUnit !< Unit number for the summary file (-1 for none). Provided by IfW. [-] - LOGICAL :: NativeBladedFmt !< Whether this is native Bladed (needs wind profile and TI scaling) or not [-] - INTEGER(IntKi) :: TurbineID = 0 !< Wind turbine ID number in the fixed (DEFAULT) file name when FixedWindFileRootName = .TRUE. (used by FAST.Farm) [-] - LOGICAL :: FixedWindFileRootName = .FALSE. !< Do the wind data files have a fixed (DEFAULT) file name? (used by FAST.Farm) [-] - END TYPE IfW_BladedFFWind_InitInputType -! ======================= -! ========= IfW_BladedFFWind_InitOutputType ======= - TYPE, PUBLIC :: IfW_BladedFFWind_InitOutputType - TYPE(ProgDesc) :: Ver !< Version information off FFWind submodule [-] - REAL(ReKi) , DIMENSION(1:3) :: TI !< Turbulence intensity given in the file [-] - REAL(ReKi) :: PropagationDir !< Propogation direction from native Bladed format [degrees] - REAL(ReKi) :: VFlowAngle !< Vertical flow angle from native Bladed format [degrees] - END TYPE IfW_BladedFFWind_InitOutputType -! ======================= -! ========= IfW_BladedFFWind_MiscVarType ======= - TYPE, PUBLIC :: IfW_BladedFFWind_MiscVarType - INTEGER(IntKi) :: dummy = 0 !< An Index into the TData array [-] - END TYPE IfW_BladedFFWind_MiscVarType -! ======================= -! ========= IfW_BladedFFWind_ParameterType ======= - TYPE, PUBLIC :: IfW_BladedFFWind_ParameterType - TYPE(IfW_FFWind_ParameterType) :: FF !< Parameters used in all full-field wind types [-] - END TYPE IfW_BladedFFWind_ParameterType -! ======================= -CONTAINS - SUBROUTINE IfW_BladedFFWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_BladedFFWind_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_BladedFFWind_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%WindFileName = SrcInitInputData%WindFileName - DstInitInputData%TowerFileExist = SrcInitInputData%TowerFileExist - DstInitInputData%SumFileUnit = SrcInitInputData%SumFileUnit - DstInitInputData%NativeBladedFmt = SrcInitInputData%NativeBladedFmt - DstInitInputData%TurbineID = SrcInitInputData%TurbineID - DstInitInputData%FixedWindFileRootName = SrcInitInputData%FixedWindFileRootName - END SUBROUTINE IfW_BladedFFWind_CopyInitInput - - SUBROUTINE IfW_BladedFFWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) - TYPE(IfW_BladedFFWind_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_DestroyInitInput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_BladedFFWind_DestroyInitInput - - SUBROUTINE IfW_BladedFFWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName - Int_BufSz = Int_BufSz + 1 ! TowerFileExist - Int_BufSz = Int_BufSz + 1 ! SumFileUnit - Int_BufSz = Int_BufSz + 1 ! NativeBladedFmt - Int_BufSz = Int_BufSz + 1 ! TurbineID - Int_BufSz = Int_BufSz + 1 ! FixedWindFileRootName - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO I = 1, LEN(InData%WindFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = TRANSFER(InData%TowerFileExist, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%SumFileUnit - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%NativeBladedFmt, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%TurbineID - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%FixedWindFileRootName, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_BladedFFWind_PackInitInput - - SUBROUTINE IfW_BladedFFWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - DO I = 1, LEN(OutData%WindFileName) - OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%TowerFileExist = TRANSFER(IntKiBuf(Int_Xferred), OutData%TowerFileExist) - Int_Xferred = Int_Xferred + 1 - OutData%SumFileUnit = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NativeBladedFmt = TRANSFER(IntKiBuf(Int_Xferred), OutData%NativeBladedFmt) - Int_Xferred = Int_Xferred + 1 - OutData%TurbineID = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%FixedWindFileRootName = TRANSFER(IntKiBuf(Int_Xferred), OutData%FixedWindFileRootName) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_BladedFFWind_UnPackInitInput - - SUBROUTINE IfW_BladedFFWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_BladedFFWind_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(IfW_BladedFFWind_InitOutputType), INTENT(INOUT) :: DstInitOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_CopyInitOutput' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - DstInitOutputData%TI = SrcInitOutputData%TI - DstInitOutputData%PropagationDir = SrcInitOutputData%PropagationDir - DstInitOutputData%VFlowAngle = SrcInitOutputData%VFlowAngle - END SUBROUTINE IfW_BladedFFWind_CopyInitOutput - - SUBROUTINE IfW_BladedFFWind_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) - TYPE(IfW_BladedFFWind_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_DestroyInitOutput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) - END SUBROUTINE IfW_BladedFFWind_DestroyInitOutput - - SUBROUTINE IfW_BladedFFWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_InitOutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Re_BufSz = Re_BufSz + SIZE(InData%TI) ! TI - Re_BufSz = Re_BufSz + 1 ! PropagationDir - Re_BufSz = Re_BufSz + 1 ! VFlowAngle - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - DO i1 = LBOUND(InData%TI,1), UBOUND(InData%TI,1) - ReKiBuf(Re_Xferred) = InData%TI(i1) - Re_Xferred = Re_Xferred + 1 - END DO - ReKiBuf(Re_Xferred) = InData%PropagationDir - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VFlowAngle - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_BladedFFWind_PackInitOutput - - SUBROUTINE IfW_BladedFFWind_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - i1_l = LBOUND(OutData%TI,1) - i1_u = UBOUND(OutData%TI,1) - DO i1 = LBOUND(OutData%TI,1), UBOUND(OutData%TI,1) - OutData%TI(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%PropagationDir = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VFlowAngle = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_BladedFFWind_UnPackInitOutput - - SUBROUTINE IfW_BladedFFWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(INOUT) :: DstMiscData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_CopyMisc' -! - ErrStat = ErrID_None - ErrMsg = "" - DstMiscData%dummy = SrcMiscData%dummy - END SUBROUTINE IfW_BladedFFWind_CopyMisc - - SUBROUTINE IfW_BladedFFWind_DestroyMisc( MiscData, ErrStat, ErrMsg ) - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(INOUT) :: MiscData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_DestroyMisc' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_BladedFFWind_DestroyMisc - - SUBROUTINE IfW_BladedFFWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_PackMisc' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! dummy - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IntKiBuf(Int_Xferred) = InData%dummy - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_BladedFFWind_PackMisc - - SUBROUTINE IfW_BladedFFWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_MiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_UnPackMisc' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%dummy = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_BladedFFWind_UnPackMisc - - SUBROUTINE IfW_BladedFFWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_BladedFFWind_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_BladedFFWind_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL IfW_FFWind_CopyParam( SrcParamData%FF, DstParamData%FF, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_BladedFFWind_CopyParam - - SUBROUTINE IfW_BladedFFWind_DestroyParam( ParamData, ErrStat, ErrMsg ) - TYPE(IfW_BladedFFWind_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_DestroyParam' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL IfW_FFWind_DestroyParam( ParamData%FF, ErrStat, ErrMsg ) - END SUBROUTINE IfW_BladedFFWind_DestroyParam - - SUBROUTINE IfW_BladedFFWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! FF: size of buffers for each call to pack subtype - CALL IfW_FFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, .TRUE. ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! FF - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! FF - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! FF - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL IfW_FFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, OnlySize ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_BladedFFWind_PackParam - - SUBROUTINE IfW_BladedFFWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_BladedFFWind_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_BladedFFWind_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_FFWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%FF, ErrStat2, ErrMsg2 ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_BladedFFWind_UnPackParam - -END MODULE IfW_BladedFFWind_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_C_Binding.f90 b/modules/inflowwind/src/IfW_C_Binding.f90 index 6df338953..fe02e36f4 100644 --- a/modules/inflowwind/src/IfW_C_Binding.f90 +++ b/modules/inflowwind/src/IfW_C_Binding.f90 @@ -19,11 +19,12 @@ !********************************************************************************************************************************** MODULE InflowWind_C_BINDING - USE ISO_C_BINDING - USE InflowWind - USE InflowWind_Subs, only: MaxOutPts - USE InflowWind_Types - USE NWTC_Library + USE ISO_C_BINDING + USE InflowWind + USE InflowWind_Subs, only: MaxOutPts + USE InflowWind_Types + USE NWTC_Library + USE VersionInfo IMPLICIT NONE @@ -31,17 +32,20 @@ MODULE InflowWind_C_BINDING PUBLIC :: IfW_C_CalcOutput PUBLIC :: IfW_C_End + ! Version info for display + type(ProgDesc), parameter :: version = ProgDesc( 'InflowWind library', '', '' ) + ! Accessible to all routines inside module - TYPE(InflowWind_InputType) :: InputData !< Inputs to InflowWind - TYPE(InflowWind_InitInputType) :: InitInp - TYPE(InflowWind_InitOutputType) :: InitOutData !< Initial output data -- Names, units, and version info. - TYPE(InflowWind_ParameterType) :: p !< Parameters - TYPE(InflowWind_ContinuousStateType) :: ContStates !< Initial continuous states - TYPE(InflowWind_DiscreteStateType) :: DiscStates !< Initial discrete states - TYPE(InflowWind_ConstraintStateType) :: ConstrStates !< Constraint states at Time - TYPE(InflowWind_OtherStateType) :: OtherStates !< Initial other/optimization states - TYPE(InflowWind_OutputType) :: y !< Initial output (outputs are not calculated; only the output mesh is initialized) - TYPE(InflowWind_MiscVarType) :: m !< Misc variables for optimization (not copied in glue code) + TYPE(InflowWind_InputType) , SAVE :: InputData !< Inputs to InflowWind + TYPE(InflowWind_InitInputType) , SAVE :: InitInp + TYPE(InflowWind_InitOutputType) , SAVE :: InitOutData !< Initial output data -- Names, units, and version info. + TYPE(InflowWind_ParameterType) , SAVE :: p !< Parameters + TYPE(InflowWind_ContinuousStateType) , SAVE :: ContStates !< Initial continuous states + TYPE(InflowWind_DiscreteStateType) , SAVE :: DiscStates !< Initial discrete states + TYPE(InflowWind_ConstraintStateType) , SAVE :: ConstrStates !< Constraint states at Time + TYPE(InflowWind_OtherStateType) , SAVE :: OtherStates !< Initial other/optimization states + TYPE(InflowWind_OutputType) , SAVE :: y !< Initial output (outputs are not calculated; only the output mesh is initialized) + TYPE(InflowWind_MiscVarType) , SAVE :: m !< Misc variables for optimization (not copied in glue code) ! This must exactly match the value in the Python interface. We are not using the variable 'ErrMsgLen' ! so that we avoid issues if ErrMsgLen changes in the NWTC Library. If the value of ErrMsgLen does change @@ -49,6 +53,8 @@ MODULE InflowWind_C_BINDING ! to be equivalent to ErrMsgLen + 1, but the logic exists to correctly handle different lengths of the strings integer(IntKi), parameter :: ErrMsgLen_C=1025 ! Numerical equivalent of ErrMsgLen + 1 + + CONTAINS !> This routine sets the error status in C_CHAR for export to calling code. @@ -106,6 +112,10 @@ SUBROUTINE IfW_C_Init(InputFileString_C, InputFileStringLength_C, InputUniformSt ErrStat = ErrID_None ErrMsg = "" + CALL NWTC_Init( ProgNameIn=version%Name ) + CALL DispCopyrightLicense( version%Name ) + CALL DispCompileRuntimeInfo( version%Name ) + ! Get fortran pointer to C_NULL_CHAR deliniated input file as a string CALL C_F_pointer(InputFileString_C, InputFileString) CALL C_F_pointer(InputUniformString_C, UniformFileString) diff --git a/modules/inflowwind/src/IfW_FFWind_Base.f90 b/modules/inflowwind/src/IfW_FFWind_Base.f90 deleted file mode 100644 index f3c3f4180..000000000 --- a/modules/inflowwind/src/IfW_FFWind_Base.f90 +++ /dev/null @@ -1,1172 +0,0 @@ -!> This module uses full-field binary wind files to determine the wind inflow. -!! This module assumes that the origin, (0,0,0), is located at the tower centerline at ground level, -!! and that all units are specified in the metric system (using meters and seconds). -!! Data is shifted by half the grid width to account for turbine yaw (so that data in the X -!! direction actually starts at -1*p%FFYHWid meters). -MODULE IfW_FFWind_Base -!! -!! Created 25-Sep-2009 by B. Jonkman, National Renewable Energy Laboratory -!! using subroutines and modules from AeroDyn v12.58 -!! -!!---------------------------------------------------------------------------------------------------- -!! Feb 2013 v2.00.00 A. Platt -!! -- updated to the new framework -!! -- Modified to use NWTC_Library v. 2.0 -!! -- Note: Jacobians are not included in this version. -!! -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2015-2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - - USE NWTC_Library - USE IfW_FFWind_Base_Types - - IMPLICIT NONE - - - INTEGER(IntKi), PARAMETER :: WindProfileType_None = -1 !< don't add wind profile; already included in input - INTEGER(IntKi), PARAMETER :: WindProfileType_Constant = 0 !< constant wind - INTEGER(IntKi), PARAMETER :: WindProfileType_Log = 1 !< logarithmic - INTEGER(IntKi), PARAMETER :: WindProfileType_PL = 2 !< power law - - INTEGER(IntKi), PARAMETER :: ScaleMethod_None = 0 !< no scaling - INTEGER(IntKi), PARAMETER :: ScaleMethod_Direct = 1 !< direct scaling factors - INTEGER(IntKi), PARAMETER :: ScaleMethod_StdDev = 2 !< requested standard deviation - - -CONTAINS -!==================================================================================================== - -!==================================================================================================== -!> This routine acts as a wrapper for the GetWindSpeed routine. It steps through the array of input -!! positions and calls the GetWindSpeed routine to calculate the velocities at each point. -SUBROUTINE IfW_FFWind_CalcOutput(Time, PositionXYZ, p, Velocity, DiskVel, ErrStat, ErrMsg) - - IMPLICIT NONE - - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - REAL(ReKi), INTENT( OUT) :: DiskVel(3) !< HACK for AD14: disk velocity output at Time - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - ! local variables - INTEGER(IntKi) :: NumPoints ! Number of points specified by the PositionXYZ array - - ! local counters - INTEGER(IntKi) :: PointNum ! a loop counter for the current point - - ! temporary variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_CalcOutput' - - - !------------------------------------------------------------------------------------------------- - ! Check that the module has been initialized. - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - !------------------------------------------------------------------------------------------------- - ! Initialize some things - !------------------------------------------------------------------------------------------------- - - - ! The array is transposed so that the number of points is the second index, x/y/z is the first. - ! This is just in case we only have a single point, the SIZE command returns the correct number of points. - NumPoints = SIZE(PositionXYZ,2) - - - ! Step through all the positions and get the velocities - !$OMP PARALLEL default(shared) if(PointNum>1000) - !$OMP do private(PointNum, TmpErrStat, TmpErrMsg ) schedule(runtime) - DO PointNum = 1, NumPoints - - ! Calculate the velocity for the position - Velocity(:,PointNum) = FFWind_Interp(Time,PositionXYZ(:,PointNum),p,TmpErrStat,TmpErrMsg) - - ! Error handling - IF (TmpErrStat /= ErrID_None) THEN ! adding this so we don't have to convert numbers to strings every time - !$OMP CRITICAL ! Needed to avoid data race on ErrStat and ErrMsg - ErrStat = ErrID_None - ErrMsg = "" - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName//" [position=("// & - TRIM(Num2LStr(PositionXYZ(1,PointNum)))//", "// & - TRIM(Num2LStr(PositionXYZ(2,PointNum)))//", "// & - TRIM(Num2LStr(PositionXYZ(3,PointNum)))//") in wind-file coordinates]" ) - !$OMP END CRITICAL - END IF - - ENDDO - !$OMP END DO - !$OMP END PARALLEL - IF (ErrStat >= AbortErrLev) RETURN ! Return cannot be in parallel loop - - IF (p%AddMeanAfterInterp) THEN - DO PointNum = 1, NumPoints - Velocity(1,PointNum) = Velocity(1,PointNum) + CalculateMeanVelocity(p,PositionXYZ(3,PointNum)) - ENDDO - END IF - - - !REMOVE THIS for AeroDyn 15 - ! Return the average disk velocity values needed by AeroDyn 14. This is the WindInf_ADhack_diskVel routine. - DiskVel(1) = p%MeanFFWS - DiskVel(2:3) = 0.0_ReKi - - - RETURN - -END SUBROUTINE IfW_FFWind_CalcOutput -!+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -!> This function is used to interpolate into the full-field wind array or tower array if it has -!! been defined and is necessary for the given inputs. It receives X, Y, Z and -!! TIME from the calling routine. It then computes a time shift due to a nonzero X based upon -!! the average windspeed. The modified time is used to decide which pair of time slices to interpolate -!! within and between. After finding the two time slices, it decides which four grid points bound the -!! (Y,Z) pair. It does a bilinear interpolation for each time slice. Linear interpolation is then used -!! to interpolate between time slices. This routine assumes that X is downwind, Y is to the left when -!! looking downwind and Z is up. It also assumes that no extrapolation will be needed. -!! -!! If tower points are used, it assumes the velocity at the ground is 0. It interpolates between -!! heights and between time slices, but ignores the Y input. -!! -!! 11/07/1994 - Created by M. Buhl from the original TURBINT. -!! 09/25/1997 - Modified by M. Buhl to use f90 constructs and new variable names. Renamed to FF_Interp. -!! 09/23/2009 - Modified by B. Jonkman to use arguments instead of modules to determine time and position. -!! Height is now relative to the ground -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -FUNCTION FFWind_Interp(Time, Position, p, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="FFWind_Interp" - - REAL(DbKi), INTENT(IN ) :: Time !< time (s) - REAL(ReKi), INTENT(IN ) :: Position(3) !< takes the place of XGrnd, YGrnd, ZGrnd - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi) :: FFWind_Interp(3) !< The U, V, W velocities - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message - - ! Local Variables: - - REAL(ReKi) :: TimeShifted - REAL(ReKi),PARAMETER :: Tol = 1.0E-3 ! a tolerance for determining if two reals are the same (for extrapolation) - REAL(ReKi) :: T - REAL(ReKi) :: TGRID - REAL(ReKi) :: Y - REAL(ReKi) :: YGRID - REAL(ReKi) :: Z - REAL(ReKi) :: ZGRID - REAL(ReKi) :: N(8) ! array for holding scaling factors for the interpolation algorithm - REAL(ReKi) :: u(8) ! array for holding the corner values for the interpolation algorithm across a cubic volume - REAL(ReKi) :: M(4) ! array for holding scaling factors for the interpolation algorithm - REAL(ReKi) :: v(4) ! array for holding the corner values for the interpolation algorithm across an area - - INTEGER(IntKi) :: IDIM - INTEGER(IntKi) :: ITHI - INTEGER(IntKi) :: ITLO - INTEGER(IntKi) :: IYHI - INTEGER(IntKi) :: IYLO - INTEGER(IntKi) :: IZHI - INTEGER(IntKi) :: IZLO - - LOGICAL :: OnGrid - - !------------------------------------------------------------------------------------------------- - ! Initialize variables - !------------------------------------------------------------------------------------------------- - - FFWind_Interp(:) = 0.0_ReKi ! the output velocities (in case p%NFFComp /= 3) - - ErrStat = ErrID_None - ErrMsg = "" - - - !------------------------------------------------------------------------------------------------- - ! By definition, wind below the ground is always zero (no turbulence, either). - !------------------------------------------------------------------------------------------------- - IF ( Position(3) <= 0.0_ReKi ) THEN - FFWind_Interp = 0.0_ReKi - RETURN - END IF - - - !------------------------------------------------------------------------------------------------- - ! Find the bounding time slices. - !------------------------------------------------------------------------------------------------- - - ! Perform the time shift. At time=0, a point half the grid width downstream (p%FFYHWid) will index into the zero time slice. - ! If we did not do this, any point downstream of the tower at the beginning of the run would index outside of the array. - ! This all assumes the grid width is at least as large as the rotor. If it isn't, then the interpolation will not work. - - - TimeShifted = TIME + ( p%InitXPosition - Position(1) )*p%InvMFFWS ! in distance, X: InputInfo%Position(1) - p%InitXPosition - TIME*p%MeanFFWS - - - IF ( p%Periodic ) THEN ! translate TimeShifted to ( 0 <= TimeShifted < p%TotalTime ) - - TimeShifted = MODULO( TimeShifted, p%TotalTime ) - ! If TimeShifted is a very small negative number, modulo returns the incorrect value due to internal rounding errors. - ! See bug report #471 - IF (TimeShifted == p%TotalTime) TimeShifted = 0.0_ReKi - - TGRID = TimeShifted*p%FFRate - ITLO = INT( TGRID ) ! convert REAL to INTEGER (add 1 later because our grids start at 1, not 0) - T = 2.0_ReKi * ( TGRID - REAL(ITLO, ReKi) ) - 1.0_ReKi ! a value between -1 and 1 that indicates a relative position between ITLO and ITHI - - ITLO = ITLO + 1 - IF ( ITLO == p%NFFSteps ) THEN - ITHI = 1 - ELSE - IF (ITLO > p%NFFSteps) ITLO = 1 - ITHI = ITLO + 1 - ENDIF - - - ELSE - - TGRID = TimeShifted*p%FFRate - ITLO = INT( TGRID ) ! convert REAL to INTEGER (add 1 later because our grids start at 1, not 0) - T = 2.0_ReKi * ( TGRID - REAL(ITLO, ReKi) ) - 1.0_ReKi ! a value between -1 and 1 that indicates a relative position between ITLO and ITHI - - ITLO = ITLO + 1 ! add one since our grids start at 1, not 0 - ITHI = ITLO + 1 - - IF ( ITLO >= p%NFFSteps .OR. ITLO < 1 ) THEN - IF ( ITLO == p%NFFSteps ) THEN - ITHI = ITLO - IF ( T <= TOL ) THEN ! we're on the last point - T = -1.0_ReKi - ELSE ! We'll extrapolate one dt past the last value in the file - ITLO = ITHI - 1 - ENDIF - ELSE - ErrMsg = ' Error: FF wind array was exhausted at '//TRIM( Num2LStr( REAL( TIME, ReKi ) ) )// & - ' seconds (trying to access data at '//TRIM( Num2LStr( REAL( TimeShifted, ReKi ) ) )//' seconds).' - ErrStat = ErrID_Fatal - RETURN - ENDIF - ENDIF - - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Find the bounding rows for the Z position. [The lower-left corner is (1,1) when looking upwind.] - !------------------------------------------------------------------------------------------------- - - ZGRID = ( Position(3) - p%GridBase )*p%InvFFZD - - IF (ZGRID > -1*TOL) THEN - OnGrid = .TRUE. - - ! Index for start and end slices - IZLO = INT( ZGRID ) + 1 ! convert REAL to INTEGER, then add one since our grids start at 1, not 0 - IZHI = IZLO + 1 - - ! Set Z as a value between -1 and 1 for the relative location between IZLO and IZHI. - ! Subtract 1_IntKi from Z since the indices are starting at 1, not 0 - Z = 2.0_ReKi * (ZGRID - REAL(IZLO - 1_IntKi, ReKi)) - 1.0_ReKi - - IF ( IZLO < 1 ) THEN - IF ( IZLO == 0 .AND. Z >= 1.0-TOL ) THEN - Z = -1.0_ReKi - IZLO = 1 - ELSE - ErrMsg = ' FF wind array boundaries violated. Grid too small in Z direction (Z='//& - TRIM(Num2LStr(Position(3)))//' m is below the grid).' - ErrStat = ErrID_Fatal - RETURN - ENDIF - ELSEIF ( IZLO >= p%NZGrids ) THEN - IF ( IZLO == p%NZGrids .AND. Z <= TOL ) THEN - Z = -1.0_ReKi - IZHI = IZLO ! We're right on the last point, which is still okay - ELSE - ErrMsg = ' FF wind array boundaries violated. Grid too small in Z direction (Z='//& - TRIM(Num2LStr(Position(3)))//' m is above the grid).' - ErrStat = ErrID_Fatal - RETURN - ENDIF - ENDIF - - ELSE - - OnGrid = .FALSE. ! this is on the tower - - IF (p%InterpTower) then - - ! get Z between ground and bottom of grid - ZGRID = Position(3)/p%GridBase - Z = 2.0_ReKi * ZGRID - 1.0_ReKi - IZHI = 1 - IZLO = 0 - - IF ( ZGRID < 0.0_ReKi ) THEN - ErrMsg = ' FF wind array boundaries violated. Grid too small in Z direction '// & - '(height (Z='//TRIM(Num2LStr(Position(3)))//' m) is below the ground).' - ErrStat = ErrID_Fatal - RETURN - ENDIF - - ELSE - - IF ( p%NTGrids < 1) THEN - ErrMsg = ' FF wind array boundaries violated. Grid too small in Z direction '// & - '(height (Z='//TRIM(Num2LStr(Position(3)))//' m) is below the grid and no tower points are defined).' - ErrStat = ErrID_Fatal - RETURN - ENDIF - - IZLO = INT( -1.0*ZGRID ) + 1 ! convert REAL to INTEGER, then add one since our grids start at 1, not 0 - - - IF ( IZLO >= p%NTGrids ) THEN !our dz is the difference between the bottom tower point and the ground - IZLO = p%NTGrids - - ! Check that this isn't zero. Value between -1 and 1 corresponding to the relative position. - Z = 1.0_ReKi - 2.0_ReKi * (Position(3) / (p%GridBase - REAL(IZLO - 1_IntKi, ReKi)/p%InvFFZD)) - - ELSE - - ! Set Z as a value between -1 and 1 for the relative location between IZLO and IZHI. Used in the interpolation. - Z = 2.0_ReKi * (ABS(ZGRID) - REAL(IZLO - 1_IntKi, ReKi)) - 1.0_ReKi - - ENDIF - IZHI = IZLO + 1 - - ENDIF - - END IF - - IF ( OnGrid ) THEN ! The tower points don't use this - - CALL GetInterpValues(); if (ErrStat/=ErrID_None) return - - !------------------------------------------------------------------------------------------------- - ! Interpolate on the grid - !------------------------------------------------------------------------------------------------- - - DO IDIM=1,p%NFFComp ! all the components - - u(1) = p%FFData( IZHI, IYLO, IDIM, ITLO ) - u(2) = p%FFData( IZHI, IYHI, IDIM, ITLO ) - u(3) = p%FFData( IZLO, IYHI, IDIM, ITLO ) - u(4) = p%FFData( IZLO, IYLO, IDIM, ITLO ) - u(5) = p%FFData( IZHI, IYLO, IDIM, ITHI ) - u(6) = p%FFData( IZHI, IYHI, IDIM, ITHI ) - u(7) = p%FFData( IZLO, IYHI, IDIM, ITHI ) - u(8) = p%FFData( IZLO, IYLO, IDIM, ITHI ) - - FFWind_Interp(IDIM) = SUM ( N * u ) - - END DO !IDIM - - ELSE - - IF (p%InterpTower) THEN - - CALL GetInterpValues(); if (ErrStat >= AbortErrLev) return - - !------------------------------------------------------------------------------------------------- - ! Interpolate on the bottom of the grid to the ground - !------------------------------------------------------------------------------------------------- - - DO IDIM=1,p%NFFComp ! all the components - - u(1) = p%FFData( IZHI, IYLO, IDIM, ITLO ) - u(2) = p%FFData( IZHI, IYHI, IDIM, ITLO ) - u(3) = 0.0_ReKi !p%FFData( IZLO, IYHI, IDIM, ITLO ) - u(4) = 0.0_ReKi !p%FFData( IZLO, IYLO, IDIM, ITLO ) - u(5) = p%FFData( IZHI, IYLO, IDIM, ITHI ) - u(6) = p%FFData( IZHI, IYHI, IDIM, ITHI ) - u(7) = 0.0_ReKi !p%FFData( IZLO, IYHI, IDIM, ITHI ) - u(8) = 0.0_ReKi !p%FFData( IZLO, IYLO, IDIM, ITHI ) - - FFWind_Interp(IDIM) = SUM ( N * u ) - - END DO !IDIM - - ELSE - - !------------------------------------------------------------------------------------------------- - ! Interpolate on the tower array - !------------------------------------------------------------------------------------------------- - ! Setup the scaling factors. Set the unused portion of the array to zero - M(1) = ( 1.0_ReKi + Z )*( 1.0_ReKi - T ) - M(2) = ( 1.0_ReKi + Z )*( 1.0_ReKi + T ) - M(3) = ( 1.0_ReKi - Z )*( 1.0_ReKi - T ) - M(4) = ( 1.0_ReKi - Z )*( 1.0_ReKi + T ) - M = M / 4.0_ReKi ! normalize - - - DO IDIM=1,p%NFFComp ! all the components - - !---------------------------------------------------------------------------------------------- - ! Interpolate between the two times using an area interpolation. - !---------------------------------------------------------------------------------------------- - - IF (IZHI > p%NTGrids) THEN - v(1) = 0.0_ReKi ! on the ground - v(2) = 0.0_ReKi ! on the ground - ELSE - v(1) = p%FFTower( IDIM, IZHI, ITLO ) - v(2) = p%FFTower( IDIM, IZHI, ITHI ) - END IF - - v(3) = p%FFTower( IDIM, IZLO, ITLO ) - v(4) = p%FFTower( IDIM, IZLO, ITHI ) - - FFWind_Interp(IDIM) = SUM ( M * v ) - - - END DO !IDIM - - END IF ! Interpolate below the grid - - ENDIF ! OnGrid - RETURN - -CONTAINS - SUBROUTINE GetInterpValues() - - !------------------------------------------------------------------------------------------------- - ! Find the bounding columns for the Y position. [The lower-left corner is (1,1) when looking upwind.] - !------------------------------------------------------------------------------------------------- - - YGRID = ( Position(2) + p%FFYHWid )*p%InvFFYD ! really, it's (Position(2) - -1.0*p%FFYHWid) - - IYLO = INT( YGRID ) + 1 ! convert REAL to INTEGER, then add one since our grids start at 1, not 0 - IYHI = IYLO + 1 - - ! Set Y as a value between -1 and 1 for the relative location between IYLO and IYHI. Used in the interpolation. - ! Subtract 1_IntKi from IYLO since grids start at index 1, not 0 - Y = 2.0_ReKi * (YGRID - REAL(IYLO - 1_IntKi, ReKi)) - 1.0_ReKi - - IF ( IYLO >= p%NYGrids .OR. IYLO < 1 ) THEN - IF ( IYLO == 0 .AND. Y >= 1.0-TOL ) THEN - Y = -1.0_ReKi - IYLO = 1 - ELSE IF ( IYLO == p%NYGrids .AND. Y <= TOL ) THEN - Y = -1.0_ReKi - IYHI = IYLO ! We're right on the last point, which is still okay - ELSE - ErrMsg = ' FF wind array boundaries violated: Grid too small in Y direction. Y='// & - TRIM(Num2LStr(Position(2)))//'; Y boundaries = ['//TRIM(Num2LStr(-1.0*p%FFYHWid))// & - ', '//TRIM(Num2LStr(p%FFYHWid))//']' - ErrStat = ErrID_Fatal ! we don't return anything - RETURN - ENDIF - ENDIF - - !------------------------------------------------------------------------------------------------- - ! Get normalization values for 3d-linear interpolation on the grid - !------------------------------------------------------------------------------------------------- - -!New Algorithm here - N(1) = ( 1.0_ReKi + Z )*( 1.0_ReKi - Y )*( 1.0_ReKi - T ) - N(2) = ( 1.0_ReKi + Z )*( 1.0_ReKi + Y )*( 1.0_ReKi - T ) - N(3) = ( 1.0_ReKi - Z )*( 1.0_ReKi + Y )*( 1.0_ReKi - T ) - N(4) = ( 1.0_ReKi - Z )*( 1.0_ReKi - Y )*( 1.0_ReKi - T ) - N(5) = ( 1.0_ReKi + Z )*( 1.0_ReKi - Y )*( 1.0_ReKi + T ) - N(6) = ( 1.0_ReKi + Z )*( 1.0_ReKi + Y )*( 1.0_ReKi + T ) - N(7) = ( 1.0_ReKi - Z )*( 1.0_ReKi + Y )*( 1.0_ReKi + T ) - N(8) = ( 1.0_ReKi - Z )*( 1.0_ReKi - Y )*( 1.0_ReKi + T ) - N = N / REAL( SIZE(N), ReKi ) ! normalize - - END SUBROUTINE GetInterpValues -END FUNCTION FFWind_Interp -!==================================================================================================== -!> This routine is used read scale the full-field turbulence data stored in HAWC format. -SUBROUTINE ScaleTurbulence(InitInp, FFData, ScaleFactors, ErrStat, ErrMsg) - - ! Passed Variables - TYPE(IfW_FFWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization input data passed to the module - REAL(SiKi), INTENT(INOUT) :: FFData(:,:,:,:) !< full-field wind inflow data - REAL(ReKi), INTENT( OUT) :: ScaleFactors(3) !< scaling factors that were used - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - ! Local Variables: - ! note that the variables used to compute statistics use double precision: - REAL(DbKi) :: v(3) ! instanteanous wind speed at target position - REAL(DbKi) :: vMean(3) ! average wind speeds over time at target position - REAL(DbKi) :: vSum(3) ! sum over time of wind speeds at target position - REAL(DbKi) :: vSum2(3) ! sum of wind speeds squared - REAL(ReKi) :: ActualSigma(3) ! computed standard deviation - - INTEGER :: ic ! Loop counter for wind component - INTEGER :: ix ! Loop counter for x or t - INTEGER :: iy ! Loop counter for y - INTEGER :: iz ! Loop counter for z - - INTEGER :: nc ! number of FF wind components - INTEGER :: nx ! size of x (or t) dimension of turbulence box - INTEGER :: ny ! size of y dimension of turbulence box - INTEGER :: nz ! size of z dimension of turbulence box - - CHARACTER(*), PARAMETER :: RoutineName = 'ScaleTurbulence' - - - - ErrStat = ErrID_None - ErrMsg = "" - - nz = size(FFData,1) - ny = size(FFData,2) - nc = size(FFData,3) - nx = size(FFData,4) - - if ( InitInp%ScaleMethod == ScaleMethod_None ) then - - ! don't scale FFWind: - ScaleFactors = 1.0_ReKi - - else ! ScaleMethod_Direct or ScaleMethod_StdDev - - !.............................. - ! determine the scaling factors: - !.............................. - - if ( InitInp%ScaleMethod == ScaleMethod_Direct ) then - ! Use the scaling factors specified in the input file: - ScaleFactors = InitInp%sf - - else !if ( InitInp%ScaleMethod == ScaleMethod_StdDev ) then - ! compute the scale factor to get requested sigma: - - ! find the center point of the grid (if we don't have an odd number of grid points, we'll pick the point closest to the center) - iz = (nz + 1) / 2 ! integer division - iy = (ny + 1) / 2 ! integer division - - ! compute the actual sigma at the point specified by (iy,iz). (This sigma should be close to 1.) - v = 0.0_ReKi - vSum = 0.0_ReKi - vSum2 = 0.0_ReKi - DO ix=1,nx - v(1:nc) = FFData(iz,iy,:,ix) - - vSum = vSum + v - vSum2 = vSum2 + v**2 - ENDDO ! IX - - vMean = vSum/nx - ActualSigma = SQRT( ABS( (vSum2/nx) - vMean**2 ) ) - - ! check that the ActualSigma isn't 0 - !InitOut%sf = InitInp%SigmaF / ActualSigma ! factor = Target / actual - do ic=1,nc - if ( EqualRealNos( ActualSigma(ic), 0.0_ReKi ) ) then - ScaleFactors(ic) = 0.0_ReKi - if ( .not. EqualRealNos( InitInp%SigmaF(ic), 0.0_ReKi ) ) then - call SetErrStat( ErrID_Fatal,"Computed standard deviation is zero; cannot scale to achieve target non-zero standard deviation.", ErrStat, ErrMsg, RoutineName ) - end if - else - ScaleFactors(ic) = InitInp%SigmaF(ic) / ActualSigma(ic) - end if - end do - - end if - - !.............................. - ! scale the data using our scaling factors: - !.............................. - - do ix=1,nx - do ic = 1,nc - FFData( :, :, ic, ix ) = ScaleFactors(ic) * FFData( :, :, ic, ix ) - end do !IC - end do - - end if - -END SUBROUTINE ScaleTurbulence -!==================================================================================================== -!> This routine is used to add a mean wind profile to the HAWC format turbulence data. -SUBROUTINE AddMeanVelocity(InitInp, GridBase, dz, FFData) - - ! Passed Variables - TYPE(IfW_FFWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization input data passed to the module - REAL(ReKi), INTENT(IN ) :: GridBase !< height of the lowest point on the grid - REAL(ReKi), INTENT(IN ) :: dz !< distance between two zertically consectutive grid points - REAL(SiKi), INTENT(INOUT) :: FFData(:,:,:,:) !< FF wind-inflow data - - ! Local Variables: - REAL(ReKi) :: Z ! height - REAL(ReKi) :: U ! mean wind speed - INTEGER(IntKi) :: iz ! loop counter - INTEGER(IntKi) :: nz ! number of points in the z direction - - - nz = size(FFData,1) - - DO iz = 1,nz - - Z = GridBase + ( iz - 1 )*dz - if (Z <= 0.0_ReKi) cycle - - SELECT CASE ( InitInp%WindProfileType ) - - CASE ( WindProfileType_PL ) - - U = InitInp%URef*( Z / InitInp%RefHt )**InitInp%PLExp ! [IEC 61400-1 6.3.1.2 (10)] - - CASE ( WindProfileType_Log ) - - IF ( .not. EqualRealNos( InitInp%RefHt, InitInp%Z0 ) .and. Z > 0.0_ReKi ) THEN - U = InitInp%URef*( LOG( Z / InitInp%Z0 ) )/( LOG( InitInp%RefHt / InitInp%Z0 ) ) - ELSE - U = 0.0_ReKi - ENDIF - - CASE ( WindProfileType_Constant ) - - U = InitInp%URef - - CASE DEFAULT ! WindProfileType_None - - U = 0.0_ReKi - - END SELECT - - FFData( iz, :, 1, : ) = FFData( iz, :, 1, : ) + U - - END DO ! iz - - -END SUBROUTINE AddMeanVelocity -!==================================================================================================== -FUNCTION CalculateMeanVelocity(p,z) RESULT(u) - - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi) , INTENT(IN ) :: Z ! height - REAL(ReKi) :: u ! mean wind speed at height z - - SELECT CASE ( p%WindProfileType ) - - CASE ( WindProfileType_PL ) - - U = p%MeanFFWS*( Z / p%RefHt )**p%PLExp ! [IEC 61400-1 6.3.1.2 (10)] - - CASE ( WindProfileType_Log ) - - IF ( .not. EqualRealNos( p%RefHt, p%Z0 ) .and. Z > 0.0_ReKi ) THEN - U = p%MeanFFWS*( LOG( Z / p%Z0 ) )/( LOG( p%RefHt / p%Z0 ) ) - ELSE - U = 0.0_ReKi - ENDIF - - CASE ( WindProfileType_Constant ) - - U = p%MeanFFWS - - CASE DEFAULT - - U = 0.0_ReKi - - END SELECT - -END FUNCTION CalculateMeanVelocity -!==================================================================================================== -!> This routine is used to add a subtract the mean wind speed from turbulence data (so that the added mean can be added later). -!! Note that this does NOT scale using the length of the wind simulation, so there may be differences with the HAWC implementation. -SUBROUTINE SubtractMeanVelocity(FFData) - - ! Passed Variables - REAL(SiKi), INTENT(INOUT) :: FFData(:,:,:,:) !< FF wind-inflow data - - ! Local Variables: - REAL(ReKi) :: MeanVal ! computed mean wind speed - INTEGER(IntKi) :: ic ! loop counter - INTEGER(IntKi) :: iy ! loop counter - INTEGER(IntKi) :: iz ! loop counter - INTEGER(IntKi) :: nt ! number of points in the x (time) direction - - - nt = size(FFData,4) - - DO ic = 1,1 !size(FFData,3) - DO iy = 1,size(FFData,2) - DO iz = 1,size(FFData,1) - meanVal = sum(FFData(iz,iy,ic,:)) / nt - - FFData( iz,iy,ic,: ) = FFData( iz,iy,ic,: ) - meanVal - END DO ! iz - END DO ! iy - END DO ! ic - - -END SUBROUTINE SubtractMeanVelocity -!==================================================================================================== -!> This routine is used to make sure the initInp data is valid. -SUBROUTINE FFWind_ValidateInput(InitInp, nffc, ErrStat, ErrMsg) - - ! Passed Variables - TYPE(IfW_FFWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization input data passed to the module - INTEGER(IntKi), INTENT(IN ) :: nffc !< number of full-field wind components (normally 3) - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - character(*), parameter :: RoutineName = 'FFWind_ValidateInput' - - integer(intki) :: ic ! loop counter - - ErrStat = ErrID_None - ErrMsg = "" - - IF ( InitInp%RefHt < 0.0_ReKi .or. EqualRealNos( InitInp%RefHt, 0.0_ReKi ) ) call SetErrStat( ErrID_Fatal, 'The grid reference height must be larger than 0.', ErrStat, ErrMsg, RoutineName ) - - if ( InitInp%ScaleMethod == ScaleMethod_Direct) then - do ic=1,nffc - if ( InitInp%sf(ic) < 0.0_ReKi ) CALL SetErrStat( ErrID_Fatal, 'Turbulence scaling factors must not be negative.', ErrStat, ErrMsg, RoutineName ) - end do - elseif ( InitInp%ScaleMethod == ScaleMethod_StdDev ) then - do ic=1,nffc - if ( InitInp%sigmaf(ic) < 0.0_ReKi ) CALL SetErrStat( ErrID_Fatal, 'Turbulence standard deviations must not be negative.', ErrStat, ErrMsg, RoutineName ) - end do -#ifdef UNUSED_INPUTFILE_LINES - if ( InitInp%TStart < 0.0_ReKi ) CALL SetErrStat( ErrID_Fatal, 'TStart for turbulence standard deviation calculations must not be negative.', ErrStat, ErrMsg, RoutineName ) - if ( InitInp%TEnd <= InitInp%TStart ) CALL SetErrStat( ErrID_Fatal, 'TEnd for turbulence standard deviation calculations must be after TStart.', ErrStat, ErrMsg, RoutineName ) -#endif - elseif ( InitInp%ScaleMethod /= ScaleMethod_None ) then - CALL SetErrStat( ErrID_Fatal, 'Turbulence scaling method must be 0 (none), 1 (direct scaling factors), or 2 (target standard deviation).', ErrStat, ErrMsg, RoutineName ) - end if - - - if (InitInp%WindProfileType == WindProfileType_Log) then - if ( InitInp%z0 < 0.0_ReKi .or. EqualRealNos( InitInp%z0, 0.0_ReKi ) ) & - call SetErrStat( ErrID_Fatal, 'The surface roughness length, Z0, must be greater than zero', ErrStat, ErrMsg, RoutineName ) - elseif ( InitInp%WindProfileType < WindProfileType_None .or. InitInp%WindProfileType > WindProfileType_PL) then - call SetErrStat( ErrID_Fatal, 'The WindProfile type must be 0 (constant), 1 (logarithmic) or 2 (power law).', ErrStat, ErrMsg, RoutineName ) - end if - - IF ( InitInp%URef < 0.0_ReKi ) call SetErrStat( ErrID_Fatal, 'The reference wind speed must not be negative.', ErrStat, ErrMsg, RoutineName ) - - -END SUBROUTINE FFWind_ValidateInput -!==================================================================================================== -SUBROUTINE ConvertFFWind_to_HAWC2(FileRootName, p, ErrStat, ErrMsg) - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: p !< Parameters - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Local variables - REAL(SiKi) :: delta(3) - - delta(1) = p%MeanFFWS * p%FFDTime - delta(2) = 1.0_SiKi / p%InvFFYD - delta(3) = 1.0_SiKi / p%InvFFZD - - CALL WrBinHAWC(FileRootName, p%FFData(:,:,:,1:p%NFFSteps), delta, ErrStat, ErrMsg) - - IF (.NOT. p%Periodic) THEN - call SetErrStat( ErrID_Severe, 'File converted to HAWC format is not periodic. Jumps may occur in resulting simulation.', & - ErrStat, ErrMsg, 'ConvertFFWind_to_HAWC2') - END IF - -END SUBROUTINE ConvertFFWind_to_HAWC2 -!==================================================================================================== -SUBROUTINE ConvertFFWind_to_Bladed(FileRootName, p, ErrStat, ErrMsg) - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: p !< Parameters - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Local variables - REAL(SiKi) :: delta(3) - - delta(1) = p%MeanFFWS * p%FFDTime - delta(2) = 1.0_SiKi / p%InvFFYD - delta(3) = 1.0_SiKi / p%InvFFZD - - CALL WrBinBladed(FileRootName, p%FFData(:,:,:,1:p%NFFSteps), delta, p%MeanFFWS, p%RefHt, p%GridBase, p%Periodic, p%AddMeanAfterInterp, ErrStat, ErrMsg) - -END SUBROUTINE ConvertFFWind_to_Bladed -!================================================================================================================================== - SUBROUTINE WrBinHAWC(FileRootName, FFWind, delta, ErrStat, ErrMsg) - CHARACTER(*), INTENT(IN) :: FileRootName !< Name of the file to write the output in - REAL(SiKi), INTENT(IN) :: FFWind(:,:,:,:) !< 4D wind speeds: index 1=z (height), 2=y (lateral), 3=dimension(u,v,w), 4=time or x - REAL(SiKi), INTENT(IN) :: delta(3) !< array containing dx, dy, dz in meters - INTEGER(IntKi), INTENT(OUT):: ErrStat !< Indicates whether an error occurred (see NWTC_Library) - CHARACTER(*), INTENT(OUT):: ErrMsg !< Error message associated with the ErrStat - - ! local variables - CHARACTER(*), PARAMETER :: Comp(3) = (/'u','v','w'/) - INTEGER(IntKi), PARAMETER :: AryDim(3) = (/4, 2, 1/) ! x,y,z dimensions of FFWind array - INTEGER(IntKi) :: nc - INTEGER(IntKi) :: IC, IX, IY, IZ - INTEGER(IntKi) :: UnWind - !REAL(SiKi) :: MeanVal(size(FFWind,1),size(FFWind,2)) - REAL(SiKi) :: MeanVal(size(FFWind,1)) - - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'WrBinHAWC' - CHARACTER(1024) :: RootWithoutPathName - - ErrStat = ErrID_None - ErrMsg = "" - - CALL GetNewUnit( UnWind, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - nc = size(FFWind,3) ! check that nc == 3 ???? - - ! need to remove time-average value from DIM=1 - MeanVal = 0.0_SiKi - DO IX = 1,size(FFWind,4) - MeanVal = MeanVal + FFWind(:,1,1,ix) - END DO - MeanVal = MeanVal / size(FFWind,4) - - - ! write the summary file - CALL OpenFOutFile ( UnWind, trim(FileRootName)//'-HAWC.sum', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - WRITE( UnWind, '(A)' ) '; Wind file converted to HAWC format on '//CurDate()//' at '//CurTime() - - WRITE( UnWind, '()' ) - DO IZ = size(FFWind,AryDim(3)),1,-1 - WRITE( UnWind, '(A,I3,A,F15.5)' ) '; mean removed at z(', iz, ') = ', MeanVal(iz) - END DO - - WRITE( UnWind, '(A)' ) 'turb_format 1 ;' -! WRITE( UnWind, '(A)' ) 'center_pos0 0.0 0.0 '//trim(num2lstr( ';' - - WRITE( UnWind, '()' ) - WRITE( UnWind, '(A)' ) 'begin mann;' - - ic = INDEX( FileRootName, '\', BACK=.TRUE. ) - ic = MAX( ic, INDEX( FileRootName, '/', BACK=.TRUE. ) ) - RootWithoutPathName = FileRootName((ic+1):) - - - DO IC = 1,nc - WRITE( UnWind, '(2x,A, T30, A, " ;")' ) 'filename_'//Comp(IC), trim(RootWithoutPathName)//'-HAWC-'//Comp(IC)//'.bin' - END DO - DO IC = 1,nc - WRITE( UnWind, '(2x,A, T30, I8, 1x, F15.5, " ;")' ) 'box_dim_'//Comp(IC), size( FFWind, AryDim(ic) ), delta(ic) - END DO - WRITE( UnWind, '(2x,A)' ) 'dont_scale 1; converter did not rescale turbulence to unit standard deviation' - WRITE( UnWind, '(A)' ) 'end mann;' - CLOSE ( UnWind ) - - - ! write the binary files for each component - - DO IC = 1,nc - - CALL OpenBOutFile ( UnWind, trim(FileRootName)//'-HAWC-'//Comp(ic)//'.bin', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - DO IX = 1,size(FFWind,AryDim(1)) - DO IY = size(FFWind,AryDim(2)),1,-1 - WRITE( UnWind, IOSTAT=ErrStat2 ) FFWind(:,iy,ic,ix) - MeanVal(:) ! note that FFWind is SiKi (4-byte reals, not default kinds) - END DO - END DO - - CLOSE ( UnWind ) - - MeanVal = 0.0_SiKi - - END DO - - END SUBROUTINE WrBinHAWC -!================================================================================================================================== - SUBROUTINE WrBinBladed(FileRootName, FFWind, delta, MeanFFWS, HubHt, GridBase, Periodic, AddMeanAfterInterp, ErrStat, ErrMsg) - CHARACTER(*), INTENT(IN) :: FileRootName !< Name of the file to write the output in - REAL(SiKi), INTENT(IN) :: FFWind(:,:,:,:) !< 4D wind speeds: index 1=z (height), 2=y (lateral), 3=dimension(u,v,w), 4=time or x - REAL(SiKi), INTENT(IN) :: delta(3) !< array containing dx, dy, dz in meters - REAL(ReKi), INTENT(IN) :: MeanFFWS !< advection speed (mean wind speed at hub) - REAL(ReKi), INTENT(IN) :: HubHt !< hub height - REAL(ReKi), INTENT(IN) :: GridBase !< height of lowest grid point - LOGICAL, INTENT(IN) :: Periodic !< whether this wind file is periodic - LOGICAL, INTENT(IN) :: AddMeanAfterInterp !< whether this wind file contains a mean longditudinal wind speed - INTEGER(IntKi), INTENT(OUT):: ErrStat !< Indicates whether an error occurred (see NWTC_Library) - CHARACTER(*), INTENT(OUT):: ErrMsg !< Error message associated with the ErrStat - - ! local variables - INTEGER(IntKi), PARAMETER :: AryDim(3) = (/4, 2, 1/) ! x,y,z dimensions of FFWind array - INTEGER(IntKi) :: ic, it, iy, iz - INTEGER(IntKi) :: UnWind - REAL(SiKi) :: MeanVal(size(FFWind,1),size(FFWind,2)) - REAL(SiKi) :: SigmaGrid( size(FFWind,1),size(FFWind,2)) - REAL(SiKi) :: TI(3) !< array containing turbulence intensity (for scaling factors) - REAL(SiKi) :: Sigma(3) !< array containing standard deviations (for scaling factors) - REAL(SiKi) :: Scl(3) !< array containing scaling factors - REAL(SiKi) :: Off(3) !< array containing offsets - REAL(SiKi) :: Tmp - REAL(ReKi) :: MeanFFWS_nonZero !< advection speed (mean wind speed at hub) - - - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'WrBinBladed' - - REAL(SiKi), PARAMETER :: Tolerance = 0.0001 ! The largest difference between two numbers that are assumed to be equal - - - ErrStat = ErrID_None - ErrMsg = "" - - !----------------------------------------------------- - ! Calculate the stats - !----------------------------------------------------- - - do ic=3,1,-1 - - ! mean values: - MeanVal = 0.0_SiKi - DO it = 1,size(FFWind,AryDim(1)) - MeanVal = MeanVal + FFWind(:,:,ic,it) - END DO - MeanVal = MeanVal / real( size(FFWind,AryDim(1)), SiKi) - - ! standard deviations (with 1/N scaling factor): - SigmaGrid = 0.0_SiKi - DO it = 1,size(FFWind,4) - SigmaGrid = SigmaGrid + FFWind(:,:,ic,it)**2 - END DO - SigmaGrid = SigmaGrid / size(FFWind,AryDim(1)) - SigmaGrid = SQRT( MAX( SigmaGrid - MeanVal**2, 0.0_SiKi ) ) - - ! now get the average standard deviation for each component: - Sigma(ic) = sum(SigmaGrid)/size(SigmaGrid) ! get the average sigma over the grid - Sigma(ic) = MAX(100.0_SiKi*Tolerance, Sigma(ic)) ! make sure this scaling isn't too small - - end do - - ! We need to take into account the shear across the grid in the sigma calculations for scaling the data, - ! and ensure that 32.767*sigma_u >= |V-UHub| so that we don't get values out of the range of our scaling values - ! in this BLADED-style binary output. Tmp is |V-UHub| - Tmp = MAX( ABS(MAXVAL(FFWind(:,:,1,:))-MeanFFWS), ABS(MINVAL(FFWind(:,:,1,:))-MeanFFWS) ) !Get the range of wind speed values for scaling in BLADED-format .wnd files - Sigma(1) = MAX(Sigma(1),0.05_SiKi*Tmp) - do ic=2,3 - Sigma(ic) = MAX( Sigma(ic), 0.05_SiKi*ABS(MAXVAL(FFWind(:,:,ic,:))), 0.05_SiKi*ABS(MINVAL(FFWind(:,:,ic,:))) ) ! put the abs() after the maxval() and minval() to avoid stack-overflow issues with large wind files - end do - - ! Put normalizing factors into the summary file. The user can use them to - ! tell a simulation program how to rescale the data. - - if ( abs(MeanFFWS) < 0.1_ReKi ) then - MeanFFWS_nonZero = sign( 0.1, MeanFFWS ) - else - MeanFFWS_nonZero = MeanFFWS - end if - - TI = Sigma / MeanFFWS_nonZero - - !----------------------------------------------------- - ! The summary file - !----------------------------------------------------- - CALL GetNewUnit( UnWind, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - CALL OpenFOutFile ( UnWind, trim(FileRootName)//'-Bladed.sum', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - !The string "TurbSim" needs to be in the 2nd line of the summary file if AeroDyn will read this. - WRITE( UnWind,"( / 'TurbSim - This summary file was generated by ', A, ' on ' , A , ' at ' , A , '.' / )") "NWTC_Library", CurDate(), CurTime() - WRITE( UnWind, '(/)' ) - WRITE( UnWind, '(/)' ) - WRITE( UnWind, '( L10, 2X, "Clockwise rotation when looking downwind?")' ) .FALSE. - WRITE( UnWind, '( F10.3, 2X, "Hub height [m]")' ) HubHt - WRITE( UnWind, '( F10.3, 2X, "Grid height [m]")' ) delta(3)*(size(FFWind,AryDim(3)) - 1) - WRITE( UnWind, '( F10.3, 2X, "Grid width [m]")' ) delta(2)*(size(FFWind,AryDim(2)) - 1) - WRITE( UnWind, '(/"BLADED-style binary scaling parameters:"/)' ) - WRITE( UnWind, '( 2X, "UBar = ", F9.4, " m/s")' ) MeanFFWS_nonZero - WRITE( UnWind, '( 2X, "TI(u) = ", F9.4, " %")' ) 100.0*TI(1) - WRITE( UnWind, '( 2X, "TI(v) = ", F9.4, " %")' ) 100.0*TI(2) - WRITE( UnWind, '( 2X, "TI(w) = ", F9.4, " %")' ) 100.0*TI(3) - WRITE( UnWind, '(/)' ) - WRITE( UnWind, '( 2X, "Height offset = ", F9.4, " m" )' ) HubHt - 0.5*delta(3)*(size(FFWind,AryDim(3)) - 1) - GridBase ! This will be zero for square grids - ! ZGOffset = ( HubHt - delta(3)*(size(FFWind,1) - 1) / 2.0 - Zbottom ) - WRITE( UnWind, '( 2X, "Grid Base = ", F9.4, " m" )' ) GridBase - if (Periodic) then - WRITE (UnWind,'()' ) - WRITE (UnWind,'( A)' ) 'Creating a PERIODIC output file.' - end if - WRITE (UnWind,'( A)' ) 'Creating a BLADED LEFT-HAND RULE output file.' - - - CLOSE (UnWind) - - !----------------------------------------------------- - ! The BINARY file - !----------------------------------------------------- - CALL OpenBOutFile ( UnWind, TRIM(FileRootName)//'-Bladed.wnd', ErrStat, ErrMsg ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - WRITE (UnWind) INT( -99 , B2Ki ) ! -99 = New Bladed format - WRITE (UnWind) INT( 4 , B2Ki ) ! 4 = improved von karman (not used, but needed for next 7 inputs) - WRITE (UnWind) INT( size(FFWind,3) , B4Ki ) ! size(FFWind,3) = 3 = number of wind components - WRITE (UnWind) REAL( 45.0_SiKi , SiKi ) ! Latitude (degrees) (informational, not used in FAST) - WRITE (UnWind) REAL( 0.03_SiKi , SiKi ) ! Roughness length (m) (informational, not used in FAST) - WRITE (UnWind) REAL( HubHt , SiKi ) ! Reference Height (m) (informational, not used in FAST) - WRITE (UnWind) REAL( 100.0*TI(1) , SiKi ) ! Longitudinal turbulence intensity (%) - WRITE (UnWind) REAL( 100.0*TI(2) , SiKi ) ! Lateral turbulence intensity (%) - WRITE (UnWind) REAL( 100.0*TI(3) , SiKi ) ! Vertical turbulence intensity (%) - - WRITE (UnWind) REAL( delta(3) , SiKi ) ! grid spacing in vertical direction, in m - WRITE (UnWind) REAL( delta(2) , SiKi ) ! grid spacing in lateral direction, in m - WRITE (UnWind) REAL( delta(1) , SiKi ) ! grid spacing in longitudinal direciton, in m - WRITE (UnWind) INT( size(FFWind,AryDim(1))/2 , B4Ki ) ! half the number of points in alongwind direction - WRITE (UnWind) REAL( MeanFFWS_nonZero , SiKi ) ! the mean wind speed in m/s - WRITE (UnWind) REAL( 0 , SiKi ) ! the vertical length scale of the longitudinal component in m - WRITE (UnWind) REAL( 0 , SiKi ) ! the lateral length scale of the longitudinal component in m - WRITE (UnWind) REAL( 0 , SiKi ) ! the longitudinal length scale of the longitudinal component in m - WRITE (UnWind) INT( 0 , B4Ki ) ! an unused integer - WRITE (UnWind) INT( 0 , B4Ki ) ! the random number seed - WRITE (UnWind) INT( size(FFWind,AryDim(3)) , B4Ki ) ! the number of grid points vertically - WRITE (UnWind) INT( size(FFWind,AryDim(2)) , B4Ki ) ! the number of grid points laterally - WRITE (UnWind) INT( 0 , B4Ki ) ! the vertical length scale of the lateral component, not used - WRITE (UnWind) INT( 0 , B4Ki ) ! the lateral length scale of the lateral component, not used - WRITE (UnWind) INT( 0 , B4Ki ) ! the longitudinal length scale of the lateral component, not used - WRITE (UnWind) INT( 0 , B4Ki ) ! the vertical length scale of the vertical component, not used - WRITE (UnWind) INT( 0 , B4Ki ) ! the lateral length scale of the vertical component, not used - WRITE (UnWind) INT( 0 , B4Ki ) ! the longitudinal length scale of the vertical component, not used - - ! Scaling value to convert wind speeds to 16-bit integers - do ic = 1,3 - if (.not. EqualRealNos( Sigma(ic), 0.0_SiKi ) ) then - Scl(ic) = 1000.0/( Sigma(ic) ) - else - Scl(ic) = 1.0_SiKi - end if - end do - Scl(2) = -Scl(2) ! Bladed convention is positive V is pointed along negative Y (IEC turbine coordinate) - - ! Offset value to convert wind speeds to 16-bit integers - IF (AddMeanAfterInterp) THEN ! Note that this will not take into account any shear!!! - Off(1) = 0.0 - ELSE - Off(1) = MeanFFWS * Scl(1) - END IF - Off(2) = 0.0 - Off(3) = 0.0 - - DO it=1,size(FFWind,AryDim(1)) - DO iz=1,size(FFWind,AryDim(3)) ! 1=bottom of grid - DO iy=1,size(FFWind,AryDim(2)) ! 1=left of grid, i.e. y(1) = -GridWidth/2 - - ! Scale velocity for 16-bit integers: - WRITE ( UnWind ) NINT( FFWind(iz,iy,:,it) * Scl - Off , B2Ki ) ! scale to int16 - - ENDDO !IY - ENDDO !IZ - ENDDO !IT - - CLOSE( UnWind ) - - - END SUBROUTINE WrBinBladed -!==================================================================================================== -SUBROUTINE ConvertFFWind_toVTK(FileRootName, p, ErrStat, ErrMsg) - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: p !< Parameters - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Local variables - CHARACTER(1024) :: RootPathName - CHARACTER(1024) :: FileName - INTEGER :: UnWind - INTEGER :: i - INTEGER :: iy - INTEGER :: iz - - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'ConvertFFWind_toVTK' - - - CALL GetPath ( FileRootName, RootPathName ) - CALL GetNewUnit( UnWind, ErrStat, ErrMsg ) - - do i = 1,p%NFFSteps - - ! Create the output vtk file with naming /vtk/DisYZ.t.vtk - - RootPathName = trim(RootPathName)//PathSep//"vtk" - call MkDir( trim(RootPathName) ) ! make this directory if it doesn't already exist - - !FileName = trim(RootPathName)//PathSep//"vtk"//PathSep//"DisYZ.t"//trim(num2lstr(i))//".vtp" - FileName = trim(RootPathName)//PathSep//"DisYZ.t"//trim(num2lstr(i))//".vtp" - - ! see WrVTK_SP_header - CALL OpenFOutFile ( UnWind, TRIM(FileName), ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if (ErrStat >= AbortErrLev) return - - WRITE(UnWind,'(A)') '# vtk DataFile Version 3.0' - WRITE(UnWind,'(A)') "InflowWind YZ Slice at T= "//trim(num2lstr((i-1)*p%FFDTime))//" s" - WRITE(UnWind,'(A)') 'ASCII' - WRITE(UnWind,'(A)') 'DATASET STRUCTURED_POINTS' - - ! Note: gridVals must be stored such that the left-most dimension is X and the right-most dimension is Z - ! see WrVTK_SP_vectors3D() - WRITE(UnWind,'(A,3(i5,1X))') 'DIMENSIONS ', 1, p%NYGrids, p%NZGrids - WRITE(UnWind,'(A,3(f10.2,1X))') 'ORIGIN ' , p%InitXPosition, -p%FFYHWid, p%GridBase - WRITE(UnWind,'(A,3(f10.2,1X))') 'SPACING ' , 0.0_ReKi, 1.0_SiKi / p%InvFFYD, 1.0_SiKi / p%InvFFZD - WRITE(UnWind,'(A,i5)') 'POINT_DATA ', p%NYGrids*p%NZGrids - WRITE(UnWind,'(A)') 'VECTORS DisYZ float' - - DO iz=1,p%NZGrids - DO iy=1,p%NYGrids - WRITE(UnWind,'(3(f10.2,1X))') p%FFData(iz,iy,:,i) - END DO - END DO - - CLOSE(UnWind) - - end do - - -END SUBROUTINE ConvertFFWind_toVTK - - -!==================================================================================================== - -END MODULE IfW_FFWind_Base diff --git a/modules/inflowwind/src/IfW_FFWind_Base.txt b/modules/inflowwind/src/IfW_FFWind_Base.txt deleted file mode 100644 index a1f78d123..000000000 --- a/modules/inflowwind/src/IfW_FFWind_Base.txt +++ /dev/null @@ -1,53 +0,0 @@ -################################################################################################################################### -# Registry for IfW_BladedFFWind, creates MODULE IfW_BladedFFWind_Types -# Module IfW_BladedFFWind_Types contains all of the user-defined types needed in IfW_BladedFFWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - - -typedef IfW_FFWind_Base/IfW_FFWind InitInputType IntKi ScaleMethod - 0 - "Turbulence scaling method [0=none, 1=direct scaling, 2= calculate scaling factor based on a desired standard deviation]" - -typedef ^ ^ ReKi SF 3 0 - "Turbulence scaling factor for each direction [ScaleMethod=1]" - -typedef ^ ^ ReKi SigmaF 3 0 - "Turbulence standard deviation to calculate scaling from in each direction [ScaleMethod=2]" - -#typedef ^ ^ ReKi TStart - 0 - "" - -#typedef ^ ^ ReKi TEnd - 0 - "" - -typedef ^ ^ IntKi WindProfileType - -1 - "Wind profile type (0=constant;1=logarithmic;2=power law)" - -typedef ^ ^ ReKi RefHt - 0 - "Reference (hub) height of the grid" meters -typedef ^ ^ ReKi URef - 0 - "Mean u-component wind speed at the reference height" meters -typedef ^ ^ ReKi PLExp - 0 - "Power law exponent (used for PL wind profile type only)" - -typedef ^ ^ ReKi Z0 - 0 - "Surface roughness length (used for LOG wind profile type only)" - -typedef ^ ^ ReKi XOffset - 0 - "distance offset for FF wind files" m - - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType Logical Periodic - .FALSE. - "Flag to indicate if the wind file is periodic" - -typedef ^ ParameterType Logical InterpTower - .FALSE. - "Flag to indicate if we should interpolate wind speeds below the tower" - -typedef ^ ^ SiKi FFData :::: - - "Array of FF data" - -typedef ^ ^ SiKi FFTower ::: - - "Array of data along tower, below FF array" - -typedef ^ ^ ReKi FFDTime - 0 - "Delta time" seconds -typedef ^ ^ ReKi FFRate - 0 - "Data rate (1/FFDTime)" Hertz -typedef ^ ^ ReKi FFYHWid - 0 - "Half the grid width" meters -typedef ^ ^ ReKi FFZHWid - 0 - "Half the grid height" meters -typedef ^ ^ ReKi RefHt - 0 - "Reference (hub) height of the grid" meters -typedef ^ ^ ReKi GridBase - 0 - "the height of the bottom of the grid" meters -typedef ^ ^ ReKi InitXPosition - 0 - "the initial x position of grid (distance in FF is offset)" meters -typedef ^ ^ ReKi InvFFYD - 0 - "reciprocal of delta y" 1/meters -typedef ^ ^ ReKi InvFFZD - 0 - "reciprocal of delta z" 1/meters -typedef ^ ^ ReKi InvMFFWS - 0 - "reciprocal of mean wind speed (MeanFFWS)" seconds/meter -typedef ^ ^ ReKi MeanFFWS - 0 - "Mean wind speed (as defined in FF file), not necessarily of the portion used" meters/second -typedef ^ ^ ReKi TotalTime - 0 - "The total time of the simulation" seconds -typedef ^ ^ IntKi NFFComp - 3 - "Number of wind components" - -typedef ^ ^ IntKi NFFSteps - 0 - "Number of time steps in the FF array" - -typedef ^ ^ IntKi NYGrids - 0 - "Number of points in the lateral (y) direction of the grids" - -typedef ^ ^ IntKi NZGrids - 0 - "Number of points in the vertical (z) direction of the grids" - -typedef ^ ^ IntKi NTGrids - 0 - "Number of points in the vertical (z) direction on the tower (below the grids)" - -typedef ^ ^ IntKi WindFileFormat - - - "Binary file format description number" - -typedef ^ ^ Logical AddMeanAfterInterp - .FALSE. - "Add the mean wind speed after interpolating at a given height?" - -typedef ^ ^ IntKi WindProfileType - -1 - "Wind profile type (0=constant;1=logarithmic;2=power law)" - -typedef ^ ^ ReKi PLExp - 0 - "Power law exponent (used for PL wind profile type only)" - -typedef ^ ^ ReKi Z0 - 0 - "Surface roughness length (used for LOG wind profile type only)" - - diff --git a/modules/inflowwind/src/IfW_FFWind_Base_Types.f90 b/modules/inflowwind/src/IfW_FFWind_Base_Types.f90 deleted file mode 100644 index ffc3ddafd..000000000 --- a/modules/inflowwind/src/IfW_FFWind_Base_Types.f90 +++ /dev/null @@ -1,711 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_FFWind_Base_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_FFWind_Base_Types -!................................................................................................................................. -! This file is part of IfW_FFWind_Base. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_FFWind_Base. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_FFWind_Base_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_FFWind_InitInputType ======= - TYPE, PUBLIC :: IfW_FFWind_InitInputType - INTEGER(IntKi) :: ScaleMethod = 0 !< Turbulence scaling method [0=none, 1=direct scaling, 2= calculate scaling factor based on a desired standard deviation] [-] - REAL(ReKi) , DIMENSION(1:3) :: SF !< Turbulence scaling factor for each direction [ScaleMethod=1] [-] - REAL(ReKi) , DIMENSION(1:3) :: SigmaF !< Turbulence standard deviation to calculate scaling from in each direction [ScaleMethod=2] [-] - INTEGER(IntKi) :: WindProfileType = -1 !< Wind profile type (0=constant;1=logarithmic;2=power law) [-] - REAL(ReKi) :: RefHt = 0 !< Reference (hub) height of the grid [meters] - REAL(ReKi) :: URef = 0 !< Mean u-component wind speed at the reference height [meters] - REAL(ReKi) :: PLExp = 0 !< Power law exponent (used for PL wind profile type only) [-] - REAL(ReKi) :: Z0 = 0 !< Surface roughness length (used for LOG wind profile type only) [-] - REAL(ReKi) :: XOffset = 0 !< distance offset for FF wind files [m] - END TYPE IfW_FFWind_InitInputType -! ======================= -! ========= IfW_FFWind_ParameterType ======= - TYPE, PUBLIC :: IfW_FFWind_ParameterType - LOGICAL :: Periodic = .FALSE. !< Flag to indicate if the wind file is periodic [-] - LOGICAL :: InterpTower = .FALSE. !< Flag to indicate if we should interpolate wind speeds below the tower [-] - REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: FFData !< Array of FF data [-] - REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: FFTower !< Array of data along tower, below FF array [-] - REAL(ReKi) :: FFDTime = 0 !< Delta time [seconds] - REAL(ReKi) :: FFRate = 0 !< Data rate (1/FFDTime) [Hertz] - REAL(ReKi) :: FFYHWid = 0 !< Half the grid width [meters] - REAL(ReKi) :: FFZHWid = 0 !< Half the grid height [meters] - REAL(ReKi) :: RefHt = 0 !< Reference (hub) height of the grid [meters] - REAL(ReKi) :: GridBase = 0 !< the height of the bottom of the grid [meters] - REAL(ReKi) :: InitXPosition = 0 !< the initial x position of grid (distance in FF is offset) [meters] - REAL(ReKi) :: InvFFYD = 0 !< reciprocal of delta y [1/meters] - REAL(ReKi) :: InvFFZD = 0 !< reciprocal of delta z [1/meters] - REAL(ReKi) :: InvMFFWS = 0 !< reciprocal of mean wind speed (MeanFFWS) [seconds/meter] - REAL(ReKi) :: MeanFFWS = 0 !< Mean wind speed (as defined in FF file), not necessarily of the portion used [meters/second] - REAL(ReKi) :: TotalTime = 0 !< The total time of the simulation [seconds] - INTEGER(IntKi) :: NFFComp = 3 !< Number of wind components [-] - INTEGER(IntKi) :: NFFSteps = 0 !< Number of time steps in the FF array [-] - INTEGER(IntKi) :: NYGrids = 0 !< Number of points in the lateral (y) direction of the grids [-] - INTEGER(IntKi) :: NZGrids = 0 !< Number of points in the vertical (z) direction of the grids [-] - INTEGER(IntKi) :: NTGrids = 0 !< Number of points in the vertical (z) direction on the tower (below the grids) [-] - INTEGER(IntKi) :: WindFileFormat !< Binary file format description number [-] - LOGICAL :: AddMeanAfterInterp = .FALSE. !< Add the mean wind speed after interpolating at a given height? [-] - INTEGER(IntKi) :: WindProfileType = -1 !< Wind profile type (0=constant;1=logarithmic;2=power law) [-] - REAL(ReKi) :: PLExp = 0 !< Power law exponent (used for PL wind profile type only) [-] - REAL(ReKi) :: Z0 = 0 !< Surface roughness length (used for LOG wind profile type only) [-] - END TYPE IfW_FFWind_ParameterType -! ======================= -CONTAINS - SUBROUTINE IfW_FFWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_FFWind_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_FFWind_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%ScaleMethod = SrcInitInputData%ScaleMethod - DstInitInputData%SF = SrcInitInputData%SF - DstInitInputData%SigmaF = SrcInitInputData%SigmaF - DstInitInputData%WindProfileType = SrcInitInputData%WindProfileType - DstInitInputData%RefHt = SrcInitInputData%RefHt - DstInitInputData%URef = SrcInitInputData%URef - DstInitInputData%PLExp = SrcInitInputData%PLExp - DstInitInputData%Z0 = SrcInitInputData%Z0 - DstInitInputData%XOffset = SrcInitInputData%XOffset - END SUBROUTINE IfW_FFWind_CopyInitInput - - SUBROUTINE IfW_FFWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) - TYPE(IfW_FFWind_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_DestroyInitInput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_FFWind_DestroyInitInput - - SUBROUTINE IfW_FFWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_FFWind_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! ScaleMethod - Re_BufSz = Re_BufSz + SIZE(InData%SF) ! SF - Re_BufSz = Re_BufSz + SIZE(InData%SigmaF) ! SigmaF - Int_BufSz = Int_BufSz + 1 ! WindProfileType - Re_BufSz = Re_BufSz + 1 ! RefHt - Re_BufSz = Re_BufSz + 1 ! URef - Re_BufSz = Re_BufSz + 1 ! PLExp - Re_BufSz = Re_BufSz + 1 ! Z0 - Re_BufSz = Re_BufSz + 1 ! XOffset - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IntKiBuf(Int_Xferred) = InData%ScaleMethod - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%SF,1), UBOUND(InData%SF,1) - ReKiBuf(Re_Xferred) = InData%SF(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%SigmaF,1), UBOUND(InData%SigmaF,1) - ReKiBuf(Re_Xferred) = InData%SigmaF(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = InData%WindProfileType - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RefHt - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%URef - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%PLExp - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Z0 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%XOffset - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_FFWind_PackInitInput - - SUBROUTINE IfW_FFWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_FFWind_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%ScaleMethod = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%SF,1) - i1_u = UBOUND(OutData%SF,1) - DO i1 = LBOUND(OutData%SF,1), UBOUND(OutData%SF,1) - OutData%SF(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%SigmaF,1) - i1_u = UBOUND(OutData%SigmaF,1) - DO i1 = LBOUND(OutData%SigmaF,1), UBOUND(OutData%SigmaF,1) - OutData%SigmaF(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%WindProfileType = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%RefHt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%URef = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%PLExp = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Z0 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%XOffset = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_FFWind_UnPackInitInput - - SUBROUTINE IfW_FFWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_FFWind_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - DstParamData%Periodic = SrcParamData%Periodic - DstParamData%InterpTower = SrcParamData%InterpTower -IF (ALLOCATED(SrcParamData%FFData)) THEN - i1_l = LBOUND(SrcParamData%FFData,1) - i1_u = UBOUND(SrcParamData%FFData,1) - i2_l = LBOUND(SrcParamData%FFData,2) - i2_u = UBOUND(SrcParamData%FFData,2) - i3_l = LBOUND(SrcParamData%FFData,3) - i3_u = UBOUND(SrcParamData%FFData,3) - i4_l = LBOUND(SrcParamData%FFData,4) - i4_u = UBOUND(SrcParamData%FFData,4) - IF (.NOT. ALLOCATED(DstParamData%FFData)) THEN - ALLOCATE(DstParamData%FFData(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%FFData.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%FFData = SrcParamData%FFData -ENDIF -IF (ALLOCATED(SrcParamData%FFTower)) THEN - i1_l = LBOUND(SrcParamData%FFTower,1) - i1_u = UBOUND(SrcParamData%FFTower,1) - i2_l = LBOUND(SrcParamData%FFTower,2) - i2_u = UBOUND(SrcParamData%FFTower,2) - i3_l = LBOUND(SrcParamData%FFTower,3) - i3_u = UBOUND(SrcParamData%FFTower,3) - IF (.NOT. ALLOCATED(DstParamData%FFTower)) THEN - ALLOCATE(DstParamData%FFTower(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%FFTower.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%FFTower = SrcParamData%FFTower -ENDIF - DstParamData%FFDTime = SrcParamData%FFDTime - DstParamData%FFRate = SrcParamData%FFRate - DstParamData%FFYHWid = SrcParamData%FFYHWid - DstParamData%FFZHWid = SrcParamData%FFZHWid - DstParamData%RefHt = SrcParamData%RefHt - DstParamData%GridBase = SrcParamData%GridBase - DstParamData%InitXPosition = SrcParamData%InitXPosition - DstParamData%InvFFYD = SrcParamData%InvFFYD - DstParamData%InvFFZD = SrcParamData%InvFFZD - DstParamData%InvMFFWS = SrcParamData%InvMFFWS - DstParamData%MeanFFWS = SrcParamData%MeanFFWS - DstParamData%TotalTime = SrcParamData%TotalTime - DstParamData%NFFComp = SrcParamData%NFFComp - DstParamData%NFFSteps = SrcParamData%NFFSteps - DstParamData%NYGrids = SrcParamData%NYGrids - DstParamData%NZGrids = SrcParamData%NZGrids - DstParamData%NTGrids = SrcParamData%NTGrids - DstParamData%WindFileFormat = SrcParamData%WindFileFormat - DstParamData%AddMeanAfterInterp = SrcParamData%AddMeanAfterInterp - DstParamData%WindProfileType = SrcParamData%WindProfileType - DstParamData%PLExp = SrcParamData%PLExp - DstParamData%Z0 = SrcParamData%Z0 - END SUBROUTINE IfW_FFWind_CopyParam - - SUBROUTINE IfW_FFWind_DestroyParam( ParamData, ErrStat, ErrMsg ) - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_DestroyParam' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(ParamData%FFData)) THEN - DEALLOCATE(ParamData%FFData) -ENDIF -IF (ALLOCATED(ParamData%FFTower)) THEN - DEALLOCATE(ParamData%FFTower) -ENDIF - END SUBROUTINE IfW_FFWind_DestroyParam - - SUBROUTINE IfW_FFWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_FFWind_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! Periodic - Int_BufSz = Int_BufSz + 1 ! InterpTower - Int_BufSz = Int_BufSz + 1 ! FFData allocated yes/no - IF ( ALLOCATED(InData%FFData) ) THEN - Int_BufSz = Int_BufSz + 2*4 ! FFData upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%FFData) ! FFData - END IF - Int_BufSz = Int_BufSz + 1 ! FFTower allocated yes/no - IF ( ALLOCATED(InData%FFTower) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! FFTower upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%FFTower) ! FFTower - END IF - Re_BufSz = Re_BufSz + 1 ! FFDTime - Re_BufSz = Re_BufSz + 1 ! FFRate - Re_BufSz = Re_BufSz + 1 ! FFYHWid - Re_BufSz = Re_BufSz + 1 ! FFZHWid - Re_BufSz = Re_BufSz + 1 ! RefHt - Re_BufSz = Re_BufSz + 1 ! GridBase - Re_BufSz = Re_BufSz + 1 ! InitXPosition - Re_BufSz = Re_BufSz + 1 ! InvFFYD - Re_BufSz = Re_BufSz + 1 ! InvFFZD - Re_BufSz = Re_BufSz + 1 ! InvMFFWS - Re_BufSz = Re_BufSz + 1 ! MeanFFWS - Re_BufSz = Re_BufSz + 1 ! TotalTime - Int_BufSz = Int_BufSz + 1 ! NFFComp - Int_BufSz = Int_BufSz + 1 ! NFFSteps - Int_BufSz = Int_BufSz + 1 ! NYGrids - Int_BufSz = Int_BufSz + 1 ! NZGrids - Int_BufSz = Int_BufSz + 1 ! NTGrids - Int_BufSz = Int_BufSz + 1 ! WindFileFormat - Int_BufSz = Int_BufSz + 1 ! AddMeanAfterInterp - Int_BufSz = Int_BufSz + 1 ! WindProfileType - Re_BufSz = Re_BufSz + 1 ! PLExp - Re_BufSz = Re_BufSz + 1 ! Z0 - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IntKiBuf(Int_Xferred) = TRANSFER(InData%Periodic, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%InterpTower, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%FFData) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFData,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFData,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFData,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFData,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFData,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFData,3) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFData,4) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFData,4) - Int_Xferred = Int_Xferred + 2 - - DO i4 = LBOUND(InData%FFData,4), UBOUND(InData%FFData,4) - DO i3 = LBOUND(InData%FFData,3), UBOUND(InData%FFData,3) - DO i2 = LBOUND(InData%FFData,2), UBOUND(InData%FFData,2) - DO i1 = LBOUND(InData%FFData,1), UBOUND(InData%FFData,1) - ReKiBuf(Re_Xferred) = InData%FFData(i1,i2,i3,i4) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END DO - END IF - IF ( .NOT. ALLOCATED(InData%FFTower) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFTower,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFTower,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFTower,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFTower,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%FFTower,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FFTower,3) - Int_Xferred = Int_Xferred + 2 - - DO i3 = LBOUND(InData%FFTower,3), UBOUND(InData%FFTower,3) - DO i2 = LBOUND(InData%FFTower,2), UBOUND(InData%FFTower,2) - DO i1 = LBOUND(InData%FFTower,1), UBOUND(InData%FFTower,1) - ReKiBuf(Re_Xferred) = InData%FFTower(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF - ReKiBuf(Re_Xferred) = InData%FFDTime - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%FFRate - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%FFYHWid - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%FFZHWid - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RefHt - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%GridBase - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InitXPosition - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InvFFYD - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InvFFZD - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%InvMFFWS - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%MeanFFWS - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TotalTime - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NFFComp - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NFFSteps - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NYGrids - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NZGrids - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NTGrids - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%WindFileFormat - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%AddMeanAfterInterp, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%WindProfileType - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%PLExp - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Z0 - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_FFWind_PackParam - - SUBROUTINE IfW_FFWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_FFWind_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 - INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FFWind_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%Periodic = TRANSFER(IntKiBuf(Int_Xferred), OutData%Periodic) - Int_Xferred = Int_Xferred + 1 - OutData%InterpTower = TRANSFER(IntKiBuf(Int_Xferred), OutData%InterpTower) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FFData not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i4_l = IntKiBuf( Int_Xferred ) - i4_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%FFData)) DEALLOCATE(OutData%FFData) - ALLOCATE(OutData%FFData(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FFData.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i4 = LBOUND(OutData%FFData,4), UBOUND(OutData%FFData,4) - DO i3 = LBOUND(OutData%FFData,3), UBOUND(OutData%FFData,3) - DO i2 = LBOUND(OutData%FFData,2), UBOUND(OutData%FFData,2) - DO i1 = LBOUND(OutData%FFData,1), UBOUND(OutData%FFData,1) - OutData%FFData(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FFTower not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i3_l = IntKiBuf( Int_Xferred ) - i3_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%FFTower)) DEALLOCATE(OutData%FFTower) - ALLOCATE(OutData%FFTower(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FFTower.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i3 = LBOUND(OutData%FFTower,3), UBOUND(OutData%FFTower,3) - DO i2 = LBOUND(OutData%FFTower,2), UBOUND(OutData%FFTower,2) - DO i1 = LBOUND(OutData%FFTower,1), UBOUND(OutData%FFTower,1) - OutData%FFTower(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END DO - END IF - OutData%FFDTime = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%FFRate = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%FFYHWid = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%FFZHWid = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RefHt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%GridBase = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InitXPosition = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InvFFYD = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InvFFZD = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%InvMFFWS = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%MeanFFWS = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TotalTime = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%NFFComp = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NFFSteps = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NYGrids = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NZGrids = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NTGrids = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%WindFileFormat = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%AddMeanAfterInterp = TRANSFER(IntKiBuf(Int_Xferred), OutData%AddMeanAfterInterp) - Int_Xferred = Int_Xferred + 1 - OutData%WindProfileType = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%PLExp = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Z0 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_FFWind_UnPackParam - -END MODULE IfW_FFWind_Base_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_FlowField.f90 b/modules/inflowwind/src/IfW_FlowField.f90 new file mode 100644 index 000000000..0d07e55f5 --- /dev/null +++ b/modules/inflowwind/src/IfW_FlowField.f90 @@ -0,0 +1,2050 @@ +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2022 National Renewable Energy Laboratory +! +! This file is part of the NWTC Subroutine Library. +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +!********************************************************************************************************************************** + +module IfW_FlowField + +use NWTC_Library +use IfW_FlowField_Types + +implicit none + +public IfW_FlowField_GetVelAcc +public IfW_UniformField_CalcAccel, IfW_Grid3DField_CalcAccel +public IfW_UniformWind_GetOP +public Grid3D_to_Uniform, Uniform_to_Grid3D + +integer(IntKi), parameter :: WindProfileType_None = -1 !< don't add wind profile; already included in input +integer(IntKi), parameter :: WindProfileType_Constant = 0 !< constant wind +integer(IntKi), parameter :: WindProfileType_Log = 1 !< logarithmic +integer(IntKi), parameter :: WindProfileType_PL = 2 !< power law + +real(ReKi), parameter :: GridTol = 1.0E-3 ! Tolerance for determining if position is within grid + +contains + +!> IfW_FlowField_GetVelAcc gets the velocities (and accelerations) at the given point positions. +!! Accelerations are only calculated if the AccelUVW array is allocated. +subroutine IfW_FlowField_GetVelAcc(FF, IStart, Time, PositionXYZ, VelocityUVW, AccelUVW, ErrStat, ErrMsg) + + type(FlowFieldType), intent(in) :: FF !< FlowField data structure + integer(IntKi), intent(in) :: IStart !< Start index for returning velocities for external field + real(DbKi), intent(in) :: Time !< Time to evaluate velocities/accelerations + real(ReKi), intent(in) :: PositionXYZ(:, :) !< Array of positions to evaluate velocites/accelerations + real(ReKi), intent(inout) :: VelocityUVW(:, :) !< Array of velocity outputs + real(ReKi), allocatable, intent(inout) :: AccelUVW(:, :) !< Array of acceleration outputs + integer(IntKi), intent(out) :: ErrStat !< Error status + character(*), intent(out) :: ErrMsg !< Error message + + character(*), parameter :: RoutineName = "IfW_FlowField_GetVelAcc" + integer(IntKi) :: i + integer(IntKi) :: NumPoints + logical :: OutputAccel, AddMeanAfterInterp + real(ReKi), allocatable :: Position(:, :) + integer(IntKi) :: Grid3D_AccelInterp + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + + ! Uniform Field + type(UniformField_Interp) :: UFopVel, UFopAcc + + ! Grid3D Field + real(ReKi) :: Xi(3) + real(ReKi) :: VelCell(8, 3), AccCell(8, 3) + logical :: Is3D + logical :: GridExceedAllow ! is this point allowed to exceed bounds of wind grid + + ErrStat = ErrID_None + ErrMsg = "" + + ! Get number of points to evaluate + NumPoints = size(PositionXYZ, dim=2) + + ! Determine if acceleration should be calculated and returned + OutputAccel = allocated(AccelUVW) + if (OutputAccel .and. .not. FF%AccFieldValid) then + call SetErrStat(ErrID_Fatal, "Accel output requested, but accel field is not valid", & + ErrStat, ErrMsg, RoutineName) + return + end if + + ! Allocate position array + call AllocAry(Position, 3, NumPoints, "Rotated position data", TmpErrStat, TmpErrMsg) + if (TmpErrStat >= AbortErrLev) then + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + return + end if + + !---------------------------------------------------------------------------- + ! Wind speed coordinate transforms from Wind file coordinates to global + !---------------------------------------------------------------------------- + + ! The VelocityUVW array data that has been returned from the sub-modules is + ! in the wind file (X'Y'Z') coordinates. These must be rotated to the global + ! XYZ coordinates if PropagationDir or UpflowAngle is nonzero. Apply the + ! coordinate transformation to the VelocityUVW(prime) coordinates + ! (in wind X'Y'Z' coordinate frame) returned from the submodules to the XYZ + ! coordinate frame, if PropagationDir is not zero. This is only a rotation + ! of the returned wind field, so UVW contains the direction components of + ! the wind at XYZ after translation from the U'V'W' wind velocity components + ! in the X'Y'Z' (wind file) coordinate frame. + ! NOTE: rotations are about the hub at [ 0 0 H ]. + + ! Copy positions or transform based on wind box rotation + if (FF%RotateWindBox) then + do i = 1, NumPoints + Position(:, i) = GetPrimePosition(PositionXYZ(:, i)) + end do + else + Position = PositionXYZ + end if + + !---------------------------------------------------------------------------- + ! Get velocities/accelerations based on flow field type + !---------------------------------------------------------------------------- + + ! Switch based on flow type + select case (FF%FieldType) + case (Uniform_FieldType) + + !------------------------------------------------------------------------- + ! Uniform Flow Field + !------------------------------------------------------------------------- + + ! If cubic velocity interp requested, calculate operating point using + ! cubic interpolation. Otherwise, use linear interpolation + if (FF%VelInterpCubic) then + UFopVel = UniformField_InterpCubic(FF%Uniform, Time) + else + UFopVel = UniformField_InterpLinear(FF%Uniform, Time) + end if + + ! If velocity and acceleration output is requested + if (OutputAccel) then + + ! If cubic interpolation was used for the velocity, use same for accel + ! otherwise, calculate operating point via cubic interpolation + if (FF%VelInterpCubic) then + UFopAcc = UFopVel + else + UFopAcc = UniformField_InterpCubic(FF%Uniform, Time) + end if + + ! Loop throuh points and calcualate velocity and acceleration + do i = 1, NumPoints + if (Position(3, i) > 0.0_ReKi) then + VelocityUVW(:, i) = UniformField_GetVel(FF%Uniform, UFopVel, Position(:, i)) + AccelUVW(:, i) = UniformField_GetAcc(FF%Uniform, UFopAcc, Position(:, i)) + else + VelocityUVW(:, i) = 0.0_ReKi + AccelUVW(:, i) = 0.0_ReKi + end if + end do + + else ! Otherwise, only velocity requested + + ! Loop throuh points and calcualate velocity + do i = 1, NumPoints + if (Position(3, i) > 0.0_ReKi) then + VelocityUVW(:, i) = UniformField_GetVel(FF%Uniform, UFopVel, Position(:, i)) + else + VelocityUVW(:, i) = 0.0_ReKi + end if + end do + end if + + case (Grid3D_FieldType) + + !------------------------------------------------------------------------- + ! Grid3D Flow Field + !------------------------------------------------------------------------- + + ! Determine select case value for calculating acceleration and + ! interpolation so it doesn't have to be done in the loop (optimization) + if (OutputAccel) then + if (FF%VelInterpCubic) then + Grid3D_AccelInterp = 1 ! Output accel, cubic interp + else + Grid3D_AccelInterp = 2 ! Output accel, linear interp + end if + else + if (FF%VelInterpCubic) then + Grid3D_AccelInterp = 3 ! No accel, cubic interp + else + Grid3D_AccelInterp = 4 ! No accel, linear interp + end if + end if + + ! Store flag value since it doesn't change during loop + AddMeanAfterInterp = FF%Grid3D%AddMeanAfterInterp + + ! Loop through points + do i = 1, NumPoints + + ! If height < zero, set velocity/acceleration to zero, continue + if (Position(3, i) <= 0.0_ReKi) then + VelocityUVW(:, i) = 0.0_ReKi + if (OutputAccel) AccelUVW(:, i) = 0.0_ReKi + cycle + end if + + ! Is this point allowed beyond the bounds of the wind box? + GridExceedAllow = FF%Grid3D%BoxExceedAllowF .and. (i >= FF%Grid3D%BoxExceedAllowIdx) + + ! Calculate grid cells for interpolation, returns velocity and acceleration + ! components at corners of grid cell containing time and position. Also + ! returns interpolation values Xi. + call Grid3DField_GetCell(FF%Grid3D, Time, Position(:, i), OutputAccel, GridExceedAllow, & + VelCell, AccCell, Xi, Is3D, TmpErrStat, TmpErrMsg) + if (TmpErrStat >= AbortErrLev) then + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + return + end if + + ! Switch based on if acceleration is output and velocity interpolation is cubic + select case(Grid3D_AccelInterp) + case (1) ! Cubic velocity and cubic acceleration + call Grid3DField_GetVelAccCubic(FF%Grid3D%DTime, VelCell, AccCell, Xi, Is3D, & + Velocity=VelocityUVW(:, i), Accel=AccelUVW(:, i)) + case (2) ! Linear velocity and cubic acceleration + VelocityUVW(:, i) = Grid3DField_GetVelLinear(VelCell, Xi, Is3D) + call Grid3DField_GetVelAccCubic(FF%Grid3D%DTime, VelCell, AccCell, Xi, Is3D, & + Accel=AccelUVW(:, i)) + case (3) ! Cubic velocity and no acceleration + call Grid3DField_GetVelAccCubic(FF%Grid3D%DTime, VelCell, AccCell, Xi, Is3D, & + Velocity=VelocityUVW(:, i)) + case (4) ! Linear velocity and no acceleration + VelocityUVW(:, i) = Grid3DField_GetVelLinear(VelCell, Xi, Is3D) + end select + + ! Add mean wind speed after interpolation if flag is set + if (AddMeanAfterInterp) then + VelocityUVW(1, i) = VelocityUVW(1, i) + & + CalculateMeanVelocity(FF%Grid3D, Position(3, i), Position(2, i)) + end if + + end do + + case (Grid4D_FieldType) + + !------------------------------------------------------------------------- + ! Grid4D Flow Field + !------------------------------------------------------------------------- + + ! If field is not allocated, return error + if (.not. allocated(FF%Grid4D%Vel)) then + call SetErrStat(ErrID_Fatal, "Grid4D Field not allocated", ErrStat, ErrMsg, RoutineName) + return + end if + + ! Loop through points + do i = 1, NumPoints + + ! If height less than or equal to zero, set velocity to zero + if (Position(3, i) <= 0.0_ReKi) then + VelocityUVW(:, i) = 0.0_ReKi + cycle + end if + + call Grid4DField_GetVel(FF%Grid4D, Time, Position(:, i), VelocityUVW(:, i), TmpErrStat, TmpErrMsg) + if (TmpErrStat >= AbortErrLev) then + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + return + end if + end do + + case (Point_FieldType) + + !------------------------------------------------------------------------- + ! Point Flow Field + !------------------------------------------------------------------------- + + ! If points field is not allocated, return error + if (.not. allocated(FF%Points%Vel)) then + call SetErrStat(ErrID_Fatal, "Points Point Field not allocated", ErrStat, ErrMsg, RoutineName) + return + end if + + ! Set velocities directly from velocity array + VelocityUVW = FF%Points%Vel(:, IStart:IStart + NumPoints - 1) + + case (User_FieldType) + + !------------------------------------------------------------------------- + ! User Flow Field + !------------------------------------------------------------------------- + + call SetErrStat(ErrID_Fatal, "User Field not to be implemented", ErrStat, ErrMsg, RoutineName) + return + + case default + call SetErrStat(ErrID_Fatal, "Invalid FieldType "//trim(num2lstr(FF%FieldType)), ErrStat, ErrMsg, RoutineName) + return + end select + + !---------------------------------------------------------------------------- + ! If wind box was rotated, apply rotation to velocity/acceleration + !---------------------------------------------------------------------------- + + if (FF%RotateWindBox) then + if (.not. OutputAccel) then + do i = 1, NumPoints + VelocityUVW(:, i) = matmul(FF%RotFromWind, VelocityUVW(:, i)) + end do + else + do i = 1, NumPoints + VelocityUVW(:, i) = matmul(FF%RotFromWind, VelocityUVW(:, i)) + AccelUVW(:, i) = matmul(FF%RotFromWind, AccelUVW(:, i)) + end do + end if + end if + +contains + + pure function GetPrimePosition(Pos) result(PrimePos) + real(ReKi), dimension(3), intent(in) :: Pos + real(ReKi), dimension(3) :: PrimePos + PrimePos = matmul(FF%RotToWind, (Pos - FF%RefPosition)) + FF%RefPosition + end function + +end subroutine + +pure function UniformField_GetVel(UF, op, Position) result(Velocity) + use, intrinsic :: ieee_arithmetic + + type(UniformFieldType), intent(in) :: UF + type(UniformField_Interp), intent(in) :: op + real(ReKi), dimension(3), intent(in) :: Position + real(ReKi), dimension(3) :: Velocity + + character(*), parameter :: RoutineName = "UniformField_GetVel" + real(ReKi) :: V1 + real(ReKi) :: V1_rotate, VZ_rotate + + ! Calculate horizontal velocity if position is above ground + V1 = op%VelH*((Position(3)/UF%RefHeight)**op%ShrV & ! power-law wind shear + + (op%ShrH*(Position(2)*op%CosAngleH + Position(1)*op%SinAngleH) & ! horizontal linear shear + + op%LinShrV*(Position(3) - UF%RefHeight))/UF%RefLength) & ! vertical linear shear + + op%VelGust ! gust speed + + ! Apply upflow angle + V1_rotate = op%CosAngleV*V1 - op%SinAngleV*op%VelV + VZ_rotate = op%SinAngleV*V1 + op%CosAngleV*op%VelV + + ! Apply wind direction + Velocity = [V1_rotate*op%CosAngleH, -V1_rotate*op%SinAngleH, VZ_rotate] + +end function + +function UniformField_GetAcc(UF, op, Position) result(Accel) + type(UniformFieldType), intent(in) :: UF + type(UniformField_Interp), intent(in) :: op + real(ReKi), dimension(3), intent(in) :: Position + real(ReKi), dimension(3) :: Accel + + character(*), parameter :: RoutineName = "UniformField_GetAcc" + real(ReKi) :: C1, C2, C3, C4, C5 + + C1 = (Position(3)/UF%RefHeight)**op%ShrV + & + (op%LinShrV*(Position(3) - UF%RefHeight) + & + op%ShrH*(Position(1)*op%SinAngleH + & + Position(2)*op%CosAngleH))/UF%RefLength + + C2 = op%CosAngleV*(op%VelGust + op%VelH*(C1)) + + C3 = op%AngleVDot*op%SinAngleV*(op%VelGust + op%VelH*(C1)) + + C4 = op%LinShrVDot*(Position(3) - UF%RefHeight) + & + op%ShrHDot*(Position(1)*op%SinAngleH + Position(2)*op%CosAngleH) + & + op%ShrH*(Position(1)*op%AngleHDot*op%CosAngleH - & + Position(2)*op%AngleHDot*op%SinAngleH) + + C5 = op%VelGustDot + op%VelHDot*C1 + & + op%VelH*(op%ShrVDot*(Position(3)/UF%RefHeight)**op%ShrV* & + log(Position(3)/UF%RefHeight) + C4/UF%RefLength) + + Accel(1) = -op%AngleHDot*op%SinAngleH*(C2 - op%SinAngleV*op%VelV) + & + op%CosAngleH*(-op%AngleVDot*op%CosAngleV*op%VelV - C3 - & + op%VelVDot*op%SinAngleV + op%CosAngleV*C5) + + Accel(2) = op%AngleHDot*op%CosAngleH*(-C2 + op%SinAngleV*op%VelV) + & + op%SinAngleH*(op%AngleVDot*op%CosAngleV*op%VelV + C3 + & + op%VelVDot*op%SinAngleV - op%CosAngleV*C5) + + Accel(3) = op%AngleVDot*C2 - op%AngleVDot*op%SinAngleV*op%VelV + & + op%VelVDot*op%CosAngleV + op%SinAngleV*C5 + +end function + +pure function UniformField_InterpLinear(UF, Time) result(op) + + type(UniformFieldType), intent(in) :: UF + real(DbKi), intent(in) :: Time + type(UniformField_Interp) :: op + integer(IntKi) :: i + real(ReKi) :: dt, alpha, OMalpha + + ! If only one data point or time is at or below first time, use first sample + if (UF%DataSize == 1 .or. Time < UF%Time(1)) then + + op%VelH = UF%VelH(1) + op%AngleH = UF%AngleH(1) + op%AngleV = UF%AngleV(1) + op%VelV = UF%VelV(1) + op%ShrH = UF%ShrH(1) + op%ShrV = UF%ShrV(1) + op%LinShrV = UF%LinShrV(1) + op%VelGust = UF%VelGust(1) + + ! If time is after end time, use last data point + else if (Time >= UF%Time(UF%DataSize)) then + + op%VelH = UF%VelH(UF%DataSize) + op%AngleH = UF%AngleH(UF%DataSize) + op%AngleV = UF%AngleV(UF%DataSize) + op%VelV = UF%VelV(UF%DataSize) + op%ShrH = UF%ShrH(UF%DataSize) + op%ShrV = UF%ShrV(UF%DataSize) + op%LinShrV = UF%LinShrV(UF%DataSize) + op%VelGust = UF%VelGust(UF%DataSize) + + else + + ! Find first index where current time is less than Time(i) + do i = 2, UF%DataSize + if (Time < UF%Time(i)) exit + end do + + ! Calculate interval delta time + dt = UF%Time(i) - UF%Time(i - 1) + + ! Calculate interpolation coefficient [0,1] + alpha = real((Time - UF%Time(i - 1))/dt, ReKi) + OMalpha = 1.0_ReKi - alpha + + ! Blend states before and after time based on alpha + op%VelH = UF%VelH(i - 1)*OMalpha + UF%VelH(i)*alpha + op%AngleH = UF%AngleH(i - 1)*OMalpha + UF%AngleH(i)*alpha + op%AngleV = UF%AngleV(i - 1)*OMalpha + UF%AngleV(i)*alpha + op%VelV = UF%VelV(i - 1)*OMalpha + UF%VelV(i)*alpha + op%ShrH = UF%ShrH(i - 1)*OMalpha + UF%ShrH(i)*alpha + op%ShrV = UF%ShrV(i - 1)*OMalpha + UF%ShrV(i)*alpha + op%LinShrV = UF%LinShrV(i - 1)*OMalpha + UF%LinShrV(i)*alpha + op%VelGust = UF%VelGust(i - 1)*OMalpha + UF%VelGust(i)*alpha + + end if + + op%CosAngleH = cos(op%AngleH) + op%SinAngleH = sin(op%AngleH) + op%CosAngleV = cos(op%AngleV) + op%SinAngleV = sin(op%AngleV) + +end function + +pure function UniformField_InterpCubic(UF, Time) result(op) + + type(UniformFieldType), intent(in) :: UF + real(DbKi), intent(in) :: Time + type(UniformField_Interp) :: op + + integer(IntKi) :: i + real(ReKi) :: C1, C2, C3, C4, h, t + + ! Initialize data index + i = 0 + + ! If time is outside of array + if (UF%DataSize == 1 .or. Time < UF%Time(1)) then + ! One data point or time is at or below first time, use first sample + i = 1 + else if (Time >= UF%Time(UF%DataSize)) then + ! Time is after end time, use last data point + i = UF%DataSize + end if + + ! If time was inside data array + if (i == 0) then + + ! Find first index where current time is less than Time(i) + do i = 2, UF%DataSize + if (Time < UF%Time(i)) exit + end do + + h = UF%Time(i) - UF%Time(i - 1) + t = real((Time - UF%Time(i - 1))/h, ReKi) + + C1 = 2.0_ReKi*t*t*t - 3.0_ReKi*t*t + 1.0_ReKi + C2 = (t*t*t - 2.0_ReKi*t*t + t)*h + C3 = -2.0_ReKi*t*t*t + 3.0_ReKi*t*t + C4 = (t*t*t - t*t)*h + + op%VelH = C1*UF%VelH(i - 1) + C2*UF%VelHDot(i - 1) + C3*UF%VelH(i) + C4*UF%VelHDot(i) + op%AngleH = C1*UF%AngleH(i - 1) + C2*UF%AngleHDot(i - 1) + C3*UF%AngleH(i) + C4*UF%AngleHDot(i) + op%AngleV = C1*UF%AngleV(i - 1) + C2*UF%AngleVDot(i - 1) + C3*UF%AngleV(i) + C4*UF%AngleVDot(i) + op%VelV = C1*UF%VelV(i - 1) + C2*UF%VelVDot(i - 1) + C3*UF%VelV(i) + C4*UF%VelVDot(i) + op%ShrH = C1*UF%ShrH(i - 1) + C2*UF%ShrHDot(i - 1) + C3*UF%ShrH(i) + C4*UF%ShrHDot(i) + op%ShrV = C1*UF%ShrV(i - 1) + C2*UF%ShrVDot(i - 1) + C3*UF%ShrV(i) + C4*UF%ShrVDot(i) + op%LinShrV = C1*UF%LinShrV(i - 1) + C2*UF%LinShrVDot(i - 1) + C3*UF%LinShrV(i) + C4*UF%LinShrVDot(i) + op%VelGust = C1*UF%VelGust(i - 1) + C2*UF%VelGustDot(i - 1) + C3*UF%VelGust(i) + C4*UF%VelGustDot(i) + + C1 = (6.0_ReKi*t*t - 6.0_ReKi*t)/h + C2 = (3.0_ReKi*t*t - 4.0_ReKi*t + 1.0_ReKi) + C3 = -C1 + C4 = (3.0_ReKi*t*t - 2.0_ReKi*t) + + op%VelHDot = C1*UF%VelH(i - 1) + C2*UF%VelHDot(i - 1) + C3*UF%VelH(i) + C4*UF%VelHDot(i) + op%AngleHDot = C1*UF%AngleH(i - 1) + C2*UF%AngleHDot(i - 1) + C3*UF%AngleH(i) + C4*UF%AngleHDot(i) + op%AngleVDot = C1*UF%AngleV(i - 1) + C2*UF%AngleVDot(i - 1) + C3*UF%AngleV(i) + C4*UF%AngleVDot(i) + op%VelVDot = C1*UF%VelV(i - 1) + C2*UF%VelVDot(i - 1) + C3*UF%VelV(i) + C4*UF%VelVDot(i) + op%ShrHDot = C1*UF%ShrH(i - 1) + C2*UF%ShrHDot(i - 1) + C3*UF%ShrH(i) + C4*UF%ShrHDot(i) + op%ShrVDot = C1*UF%ShrV(i - 1) + C2*UF%ShrVDot(i - 1) + C3*UF%ShrV(i) + C4*UF%ShrVDot(i) + op%LinShrVDot = C1*UF%LinShrV(i - 1) + C2*UF%LinShrVDot(i - 1) + C3*UF%LinShrV(i) + C4*UF%LinShrVDot(i) + op%VelGustDot = C1*UF%VelGust(i - 1) + C2*UF%VelGustDot(i - 1) + C3*UF%VelGust(i) + C4*UF%VelGustDot(i) + + else + + ! Set values based on first/last index + op%VelH = UF%VelH(i) + op%AngleH = UF%AngleH(i) + op%AngleV = UF%AngleV(i) + op%VelV = UF%VelV(i) + op%ShrH = UF%ShrH(i) + op%ShrV = UF%ShrV(i) + op%LinShrV = UF%LinShrV(i) + op%VelGust = UF%VelGust(i) + + op%VelHDot = 0.0_ReKi + op%AngleHDot = 0.0_ReKi + op%AngleVDot = 0.0_ReKi + op%VelVDot = 0.0_ReKi + op%ShrHDot = 0.0_ReKi + op%ShrVDot = 0.0_ReKi + op%LinShrVDot = 0.0_ReKi + op%VelGustDot = 0.0_ReKi + + end if + + op%CosAngleH = cos(op%AngleH) + op%SinAngleH = sin(op%AngleH) + op%CosAngleV = cos(op%AngleV) + op%SinAngleV = sin(op%AngleV) + +end function + +subroutine IfW_UniformField_CalcAccel(UF, ErrStat, ErrMsg) + type(UniformFieldType), intent(inout) :: UF + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "Uniform_CalcAccel" + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + real(ReKi), allocatable :: b(:), u(:), dy2(:) + + ErrStat = ErrID_None + ErrMsg = "" + + !---------------------------------------------------------------------------- + ! Storage for spline fit arrays + !---------------------------------------------------------------------------- + + call AllocAry(B, UF%DataSize, "storage for B", TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + call AllocAry(U, UF%DataSize, "storage for U", TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + call AllocAry(dy2, UF%DataSize, "storage for dy2", TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Storage for derivative arrays + !---------------------------------------------------------------------------- + + call AllocAry(UF%VelHDot, UF%DataSize, 'Uniform wind horizontal wind speed derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%AngleHDot, UF%DataSize, 'Uniform wind direction derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%AngleVDot, UF%DataSize, 'Uniform wind upflow angle derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%VelVDot, UF%DataSize, 'Uniform vertical wind speed derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%ShrHDot, UF%DataSize, 'Uniform horizontal linear shear derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%ShrVDot, UF%DataSize, 'Uniform vertical power-law shear exponent derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%LinShrVDot, UF%DataSize, 'Uniform vertical linear shear derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + call AllocAry(UF%VelGustDot, UF%DataSize, 'Uniform gust velocity derivative', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Calculate derivatives + !---------------------------------------------------------------------------- + + call CalcCubicSplineDeriv(UF%Time, UF%VelH, UF%VelHDot) + call CalcCubicSplineDeriv(UF%Time, UF%AngleH, UF%AngleHDot) + call CalcCubicSplineDeriv(UF%Time, UF%AngleV, UF%AngleVDot) + call CalcCubicSplineDeriv(UF%Time, UF%VelV, UF%VelVDot) + call CalcCubicSplineDeriv(UF%Time, UF%ShrH, UF%ShrHDot) + call CalcCubicSplineDeriv(UF%Time, UF%ShrV, UF%ShrVDot) + call CalcCubicSplineDeriv(UF%Time, UF%LinShrV, UF%LinShrVDot) + call CalcCubicSplineDeriv(UF%Time, UF%VelGust, UF%VelGustDot) + +contains + + !> CalcCubicSplineDeriv fits a cubic spline through the y array with points + !! at x locations. It then calculates the corresponding derivative of y + !! with respect to x at the same x values and returns it in the dy array. + subroutine CalcCubicSplineDeriv(x, y, dy) + real(ReKi), intent(in) :: x(:) + real(ReKi), intent(in) :: y(:) + real(ReKi), intent(out) :: dy(:) + + integer(IntKi) :: i, n + real(ReKi) :: p, sig, un + + ! Get size of arrays + n = size(x) + + ! If 1 or 2 points, set derivatives to zero and return + if (n < 3) then + do i = 1, n + dy(i) = 0.0_ReKi + end do + return + end if + + ! Natural lower and upper boundaries (second derivative = 0) + ! u(1) = 0.0_ReKi + ! dy2(1) = 0.0_ReKi + ! dy2(n) = 0.0_ReKi + + ! First derivative is zero at lower boundary condition + dy2(1) = -0.5_ReKi + u(1) = 3.0_ReKi*(y(2) - y(1))/(x(2) - x(1))**2 + + ! Calculate slopes + do i = 1, n - 1 + b(i) = (y(i + 1) - y(i))/(x(i + 1) - x(i)) + end do + + ! Decomposition + do i = 2, n - 1 + sig = (x(i) - x(i - 1))/(x(i + 1) - x(i - 1)) + p = sig*dy2(i - 1) + 2.0_ReKi + dy2(i) = (sig - 1.0_ReKi)/p + u(i) = (6.*((y(i + 1) - y(i))/(x(i + 1) - x(i)) - (y(i) - y(i - 1))/(x(i) - x(i - 1)))/ & + (x(i + 1) - x(i - 1)) - sig*u(i - 1))/p + end do + + ! First derviative is zero at upper boundary condition + un = -3.0_ReKi*(y(n) - y(n - 1))/(x(n) - x(n - 1))**2 + dy2(n) = (un - 0.5_ReKi*u(n - 1))/(0.5_ReKi*dy2(n - 1) + 1.0_ReKi) + + ! Back substitution and derivative calculation + do i = n - 1, 1, -1 + dy2(i) = dy2(i)*dy2(i + 1) + u(i) + dy(i) = real(b(i) - (x(i + 1) - x(i))*(dy2(i)/3.0_ReKi + dy2(i + 1)/6.0_ReKi), SiKi) + end do + dy(n) = 0.0_ReKi + + end subroutine + +end subroutine + +!> Routine to compute the Jacobians of the output (Y) function with respect to the inputs (u). The partial +!! derivative dY/du is returned. This submodule does not follow the modularization framework. +subroutine IfW_UniformWind_GetOP(UF, t, InterpCubic, OP_out) + type(UniformFieldType), intent(IN) :: UF !< Parameters + real(DbKi), intent(IN) :: t !< Current simulation time in seconds + logical, intent(in) :: InterpCubic !< flag for using cubic interpolation + real(ReKi), intent(OUT) :: OP_out(2) !< operating point (HWindSpeed and PLexp + + type(UniformField_Interp) :: op ! interpolated values of InterpParams + + ! Linearly interpolate parameters in time at operating point (or use nearest-neighbor to extrapolate) + if (InterpCubic) then + op = UniformField_InterpCubic(UF, t) + else + op = UniformField_InterpLinear(UF, t) + end if + + OP_out(1) = op%VelH + OP_out(2) = op%ShrV + +end subroutine + +subroutine Grid3DField_GetCell(G3D, Time, Position, CalcAccel, AllowExtrap, & + VelCell, AccCell, Xi, Is3D, ErrStat, ErrMsg) + + type(Grid3DFieldType), intent(in) :: G3D !< 3D Grid-Field data + real(DbKi), intent(in) :: Time !< time (s) + real(ReKi), intent(in) :: Position(3) !< position X,Y,Z to get value + logical, intent(in) :: CalcAccel !< flag to populat AccCell + logical, intent(in) :: AllowExtrap !< is this point allowed to exceed bounds of wind grid + real(ReKi), intent(out) :: VelCell(8, 3) !< Velocity components at corners of grid cell + real(ReKi), intent(out) :: AccCell(8, 3) !< Acceleration components at corners of grid cell + real(ReKi), intent(out) :: Xi(3) !< isoparametric coord of position in cell (y,z,t) [-1, +1] + logical, intent(out) :: Is3D !< flag indicating if interpolation is 3D or 2D + integer(IntKi), intent(out) :: ErrStat !< error status + character(*), intent(out) :: ErrMsg !< error message + + character(*), parameter :: RoutineName = "Grid3DField_GetCell" + integer(IntKi), parameter :: ExtrapNone = 0 + integer(IntKi), parameter :: ExtrapYmin = 1 + integer(IntKi), parameter :: ExtrapYmax = 2 + integer(IntKi), parameter :: ExtrapZmin = 4 + integer(IntKi), parameter :: ExtrapZmax = 8 + integer(IntKi) :: AllExtrap + integer(IntKi) :: IY_Lo, IY_Hi + integer(IntKi) :: IZ_Lo, IZ_Hi + integer(IntKi) :: IT_Lo, IT_Hi + logical :: InGrid + + ErrStat = ErrID_None + ErrMsg = "" + + ! Initialize to no extrapolation (modified in bounds routines) + AllExtrap = ExtrapNone + + !---------------------------------------------------------------------------- + ! Find grid bounds in Time and Z + !---------------------------------------------------------------------------- + + ! Get grid time bounds + call GetBoundsT(Position(1), Xi(3)) + if (ErrStat >= AbortErrLev) return + + ! Get grid Z bounds + call GetBoundsZ(Position(3), Xi(2)) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Extract interpolation cells from grids based on poisiont + !---------------------------------------------------------------------------- + + ! If position is inside grid + if (InGrid) then + + ! Set flag to use 3D interpolation + Is3D = .true. + + ! Get grid Y bounds + call GetBoundsY(Position(2), Xi(1)) + if (ErrStat >= AbortErrLev) return + + ! Interpolate within grid (or top, left, right if extrapolation enabled) + call GetCellInGrid(VelCell, G3D%Vel, G3D%VelAvg) + + ! If acceleration requested, get cell values + if (CalcAccel) then + call GetCellInGrid(AccCell, G3D%Acc, G3D%AccAvg) + end if + + else if (G3D%NTGrids > 0) then + + ! Interpolation is 2D + Is3D = .false. + + ! Tower grids present and position is below main grid + call GetCellInTower(VelCell, G3D%Vel, G3D%VelAvg, G3D%VelTower) + + ! If acceleration requested, get cell values + if (CalcAccel) then + call GetCellInTower(AccCell, G3D%Acc, G3D%AccAvg, G3D%AccTower) + end if + + else + + ! Set flag to use 3D interpolation + Is3D = .true. + + ! Get grid Y bounds + call GetBoundsY(Position(2), Xi(1)) + if (ErrStat >= AbortErrLev) return + + ! Tower interpolation without tower grids + call GetCellBelowGrid(VelCell, G3D%Vel) + + ! If acceleration requested, get cell values + if (CalcAccel) then + call GetCellBelowGrid(AccCell, G3D%Acc) + end if + + end if + +contains + + subroutine GetCellInGrid(cell, gridVal, gridAvg) + + real(ReKi), intent(out) :: cell(8, 3) + real(SiKi), intent(in) :: gridVal(:, :, :, :) + real(SiKi), intent(in), allocatable :: gridAvg(:, :, :) + + ! Select based on extrapolation flags + select case (AllExtrap) + + case (ExtrapNone) ! No extrapolation + + cell(1, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Lo) + cell(2, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Lo) + cell(3, :) = gridVal(:, IY_Lo, IZ_Hi, IT_Lo) + cell(4, :) = gridVal(:, IY_Hi, IZ_Hi, IT_Lo) + cell(5, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Hi) + cell(6, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Hi) + cell(7, :) = gridVal(:, IY_Lo, IZ_Hi, IT_Hi) + cell(8, :) = gridVal(:, IY_Hi, IZ_Hi, IT_Hi) + + case (ior(ExtrapZmax, ExtrapYmax)) ! Extrapolate top right corner + + cell(1, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Lo) + cell(2, :) = gridAvg(:, IZ_Lo, IT_Lo) + cell(3, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(4, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(5, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Hi) + cell(6, :) = gridAvg(:, IZ_Lo, IT_Hi) + cell(7, :) = gridAvg(:, IZ_Hi, IT_Hi) + cell(8, :) = gridAvg(:, IZ_Hi, IT_Hi) + + case (ior(ExtrapZmax, ExtrapYmin))! Extrapolate top left corner + + cell(1, :) = gridAvg(:, IZ_Lo, IT_Lo) + cell(2, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Lo) + cell(3, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(4, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(5, :) = gridAvg(:, IZ_Lo, IT_Hi) + cell(6, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Hi) + cell(7, :) = gridAvg(:, IZ_Hi, IT_Hi) + cell(8, :) = gridAvg(:, IZ_Hi, IT_Hi) + + case (ExtrapZmax) ! Extrapolate above grid only + + cell(1, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Lo) + cell(2, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Lo) + cell(3, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(4, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(5, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Hi) + cell(6, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Hi) + cell(7, :) = gridAvg(:, IZ_Hi, IT_Hi) + cell(8, :) = gridAvg(:, IZ_Hi, IT_Hi) + + case (ExtrapYmax) ! Extrapolate to the right of grid only + + cell(1, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Lo) + cell(2, :) = gridAvg(:, IZ_Lo, IT_Lo) + cell(3, :) = gridVal(:, IY_Lo, IZ_Hi, IT_Lo) + cell(4, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(5, :) = gridVal(:, IY_Lo, IZ_Lo, IT_Hi) + cell(6, :) = gridAvg(:, IZ_Lo, IT_Hi) + cell(7, :) = gridVal(:, IY_Lo, IZ_Hi, IT_Hi) + cell(8, :) = gridAvg(:, IZ_Hi, IT_Hi) + + case (ExtrapYmin) ! Extrapolate to the left of grid only + + cell(1, :) = gridAvg(:, IZ_Lo, IT_Lo) + cell(2, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Lo) + cell(3, :) = gridAvg(:, IZ_Hi, IT_Lo) + cell(4, :) = gridVal(:, IY_Hi, IZ_Hi, IT_Lo) + cell(5, :) = gridAvg(:, IZ_Lo, IT_Hi) + cell(6, :) = gridVal(:, IY_Hi, IZ_Lo, IT_Hi) + cell(7, :) = gridAvg(:, IZ_Hi, IT_Hi) + cell(8, :) = gridVal(:, IY_Hi, IZ_Hi, IT_Hi) + + case (ExtrapZmin) ! Extrapolate below grid + + cell(1, :) = 0.0_ReKi ! Ground + cell(2, :) = 0.0_ReKi ! Ground + cell(3, :) = gridVal(:, IY_Lo, 1, IT_Lo) + cell(4, :) = gridVal(:, IY_Hi, 1, IT_Lo) + cell(5, :) = 0.0_ReKi ! Ground + cell(6, :) = 0.0_ReKi ! Ground + cell(7, :) = gridVal(:, IY_Lo, 1, IT_Hi) + cell(8, :) = gridVal(:, IY_Hi, 1, IT_Hi) + + case (ior(ExtrapZmin, ExtrapYmin)) ! Extrapolate lower left of grid + + cell(1, :) = 0.0_ReKi ! Ground + cell(2, :) = 0.0_ReKi ! Ground + cell(3, :) = gridAvg(:, 1, IT_Lo) ! Average + cell(4, :) = gridVal(:, 1, 1, IT_Lo) + cell(5, :) = 0.0_ReKi ! Ground + cell(6, :) = 0.0_ReKi ! Ground + cell(7, :) = gridAvg(:, 1, IT_Hi) ! Average + cell(8, :) = gridVal(:, 1, 1, IT_Hi) + + case (ior(ExtrapZmin, ExtrapYmax)) ! Extrapolate lower right of grid + + cell(1, :) = 0.0_ReKi ! Ground + cell(2, :) = 0.0_ReKi ! Ground + cell(3, :) = gridVal(:, G3D%NYGrids, 1, IT_Lo) + cell(4, :) = gridAvg(:, 1, IT_Lo) ! Average + cell(5, :) = 0.0_ReKi ! Ground + cell(6, :) = 0.0_ReKi ! Ground + cell(7, :) = gridVal(:, G3D%NYGrids, 1, IT_Hi) + cell(8, :) = gridAvg(:, 1, IT_Hi) ! Average + + end select + + end subroutine + + !> GetCellBelowGrid interpolates between bottom of grid and ground. This + !! is only called if G3D%InterpTower == .true. + subroutine GetCellBelowGrid(cell, gridVal) + + real(ReKi), intent(out) :: cell(8, 3) + real(SiKi), intent(in) :: gridVal(:, :, :, :) + + cell(1, :) = 0.0_ReKi ! Ground + cell(2, :) = 0.0_ReKi ! Ground + cell(3, :) = gridVal(:, IY_Lo, IZ_Hi, IT_Lo) + cell(4, :) = gridVal(:, IY_Hi, IZ_Hi, IT_Lo) + cell(5, :) = 0.0_ReKi ! Ground + cell(6, :) = 0.0_ReKi ! Ground + cell(7, :) = gridVal(:, IY_Lo, IZ_Hi, IT_Hi) + cell(8, :) = gridVal(:, IY_Hi, IZ_Hi, IT_Hi) + + end subroutine + + subroutine GetCellInTower(cell, gridVal, gridAvg, towerVal) + + real(ReKi), intent(out) :: cell(8, 3) + real(SiKi), intent(in) :: gridVal(:, :, :, :) + real(SiKi), intent(in), allocatable :: gridAvg(:, :, :) + real(SiKi), intent(in), allocatable :: towerVal(:, :, :) + + real(ReKi), dimension(2) :: P, P1, P2, P3, V0, V1, V2 + real(ReKi) :: d00, d01, d11, d20, d21 + real(ReKi) :: V(3, 3, 2), W(3) + real(ReKi) :: alpha, omalpha, denom + integer(IntKi) :: ic + + !------------------------------------------------------------------------- + ! If extrapolation is not allowed or Y is nearly zero, only interpolate + ! along the tower + !------------------------------------------------------------------------- + + if (.not. AllowExtrap) then + if (IZ_HI <= G3D%NTGrids) then ! In tower grid + cell(1, :) = towerVal(:, IZ_LO, IT_LO) + cell(2, :) = towerVal(:, IZ_HI, IT_LO) + cell(3, :) = towerVal(:, IZ_LO, IT_HI) + cell(4, :) = towerVal(:, IZ_HI, IT_HI) + else ! Between tower grid and ground + cell(1, :) = towerVal(:, IZ_LO, IT_LO) + cell(2, :) = 0.0_ReKi + cell(3, :) = towerVal(:, IZ_LO, IT_HI) + cell(4, :) = 0.0_ReKi + end if + return + end if + + !------------------------------------------------------------------------- + ! If Y is beyond grid width from the tower (clamped), + ! interp between ground and bottom of grid average + !------------------------------------------------------------------------- + + if (abs(Position(2)) >= 2.0_ReKi*G3D%YHWid) then + Xi(2) = 2.0_ReKi*Position(3)/G3D%GridBase - 1.0_ReKi + cell(1, :) = 0.0_ReKi + cell(2, :) = gridAvg(:, 1, IT_LO) + cell(3, :) = 0.0_ReKi + cell(4, :) = gridAvg(:, 1, IT_HI) + return + end if + + !------------------------------------------------------------------------- + ! Otherwise, position is below grid and within +- 2*GridWidth from tower + ! This section uses Barycentric interpolation of a triangle to get + ! the wind components at the desired Position. The components on the + ! bottom of the grid and on the tower are interpolated to get the first + ! two points. The third point is on the ground at the GridWidth away + ! from the tower. + !------------------------------------------------------------------------- + + ! Get grid Y bounds + call GetBoundsY(Position(2), Xi(1)) + if (ErrStat >= AbortErrLev) return + + ! Get interpolation point + P = [abs(Position(2)), Position(3)] + + ! Point 1 (grid bottom point) + P1 = [abs(Position(2)), G3D%GridBase] + select case (AllExtrap) + case (ExtrapNone) + ! Interpolate between grid points + alpha = (Xi(1) + 1.0_ReKi)/2.0_ReKi + omalpha = 1.0_ReKi - alpha + V(:, 1, 1) = omalpha*gridVal(:, IY_Lo, 1, IT_Lo) + & + alpha*gridVal(:, IY_Hi, 1, IT_Lo) + V(:, 1, 2) = omalpha*gridVal(:, IY_Lo, 1, IT_Hi) + & + alpha*gridVal(:, IY_Hi, 1, IT_Hi) + case (ExtrapYmin, ExtrapYmax) + ! Interpolate between edge of grid and grid average + alpha = abs(Position(2))/G3D%YHWid - 1.0_ReKi + omalpha = 1.0_ReKi - alpha + V(:, 1, 1) = omalpha*gridVal(:, IY_Lo, 1, IT_Lo) + & + alpha*gridAvg(:, 1, IT_Lo) + V(:, 1, 2) = omalpha*gridVal(:, IY_Lo, 1, IT_Hi) + & + alpha*gridAvg(:, 1, IT_Hi) + end select + + ! Point 2 (tower point) + P2 = [0.0_ReKi, Position(3)] + alpha = (Xi(2) + 1.0_ReKi)/2.0_ReKi + omalpha = 1.0_ReKi - alpha + if (IZ_HI <= G3D%NTGrids) then ! Lower point above ground + V(:, 2, 1) = omalpha*towerVal(:, IZ_Lo, IT_Lo) + & + alpha*towerVal(:, IZ_Hi, IT_Lo) + V(:, 2, 2) = omalpha*towerVal(:, IZ_Lo, IT_Hi) + & + alpha*towerVal(:, IZ_Hi, IT_Hi) + else ! Lower point on ground + V(:, 2, 1) = omalpha*towerVal(:, IZ_Lo, IT_Lo) + V(:, 2, 2) = omalpha*towerVal(:, IZ_Lo, IT_Hi) + end if + + ! Point 3 (ground @ grid width away from tower) + P3 = [2.0_ReKi*G3D%YHWid, 0.0_Reki] + ! V(:, 3, :) = 0.0_ReKi ! Not used + + ! Calculate Barycentric weights for triangle + V0 = P1 - P3 + V1 = P2 - P3 + V2 = P - P3 + d00 = dot_product(v0, v0) + d01 = dot_product(v0, v1) + d11 = dot_product(v1, v1) + d20 = dot_product(v2, v0) + d21 = dot_product(v2, v1) + denom = d00*d11 - d01*d01 + W(1) = (d11*d20 - d01*d21)/denom + W(2) = (d00*d21 - d01*d20)/denom + ! W(3) = 1.0_ReKi - W(1) - W(2) ! Not used + + ! Interpolate wind components based on weights + do ic = 1, 3 + cell(1, ic) = V(ic, 1, 1) * W(1) + V(ic, 2, 1) * W(2) + cell(3, ic) = V(ic, 1, 2) * W(1) + V(ic, 2, 2) * W(2) + end do + cell(2, :) = cell(1, :) + cell(4, :) = cell(3, :) + + end subroutine + + !> GetBoundsY populates IY_Lo, IY_Hi, and the interpolant [-1,1]. It also + !! adds ExtrapYmin or ExtrapYmax to AllExtrap if applicable. + subroutine GetBoundsY(PosY, DY) + + real(ReKi), intent(in) :: PosY + real(ReKi), intent(out) :: DY + + real(ReKi) :: Y_Grid + + ! Calculate position on Y grid + Y_Grid = (PosY + G3D%YHWid)*G3D%InvDY + 1 + + ! Calculate bounding grid indices + IY_LO = floor(Y_Grid, IntKi) + IY_HI = IY_LO + 1 + + ! Position location within interval [0,1] + DY = Y_Grid - aint(Y_Grid) + + if (IY_LO >= 1 .and. IY_HI <= G3D%NYGrids) then + DY = 2.0_ReKi*DY - 1.0_ReKi + else if (IY_LO == 0 .and. DY >= 1.0_ReKi - GridTol) then + IY_LO = 1 + IY_HI = 2 + DY = -1.0_ReKi + else if (IY_LO == G3D%NYGrids .and. DY <= GridTol) then + IY_LO = G3D%NYGrids - 1 + IY_HI = G3D%NYGrids + DY = 1.0_ReKi + else if (AllowExtrap) then + if (IY_LO <= 0) then + ! Clamp value at grid width below the low side of grid + DY = 2.0_ReKi*max(PosY/G3D%YHWid + 2.0_ReKi, 0.0_Reki) - 1.0_ReKi + IY_LO = 1 + IY_HI = 1 + AllExtrap = ior(AllExtrap, ExtrapYmin) + else if (IY_LO >= G3D%NYGrids) then + ! Clamp value at grid width above the high side of grid + DY = 2.0_ReKi*min(PosY/G3D%YHWid - 1.0_ReKi, 1.0_Reki) - 1.0_ReKi + IY_LO = G3D%NYGrids + IY_HI = G3D%NYGrids + AllExtrap = ior(AllExtrap, ExtrapYmax) + end if + else + ! Position outside + call SetErrStat(ErrID_Fatal, ' GF wind array boundaries violated: Grid too small in Y direction. Y='// & + TRIM(Num2LStr(PosY))//'; Y boundaries = ['//TRIM(Num2LStr(-1.0*G3D%YHWid))// & + ', '//TRIM(Num2LStr(G3D%YHWid))//']', & + ErrStat, ErrMsg, RoutineName) + end if + + end subroutine + + !> GetBoundsZ populates IZ_Lo, IZ_Hi, and the interpolant [-1,1]. It also + !! adds ExtrapZmin or ExtrapZmax to AllExtrap if applicable. + subroutine GetBoundsZ(PosZ, DZ) + + real(ReKi), intent(in) :: PosZ + real(ReKi), intent(out) :: DZ + + real(ReKi) :: Z_GRID + + ! Calculate position on Z grid + Z_GRID = (PosZ - G3D%GridBase)*G3D%InvDZ + 1 + + ! Calculate bounding grid indices + IZ_LO = floor(Z_GRID, IntKi) + IZ_HI = IZ_LO + 1 + + ! Position location within interval [-1,1] + DZ = Z_GRID - aint(Z_GRID) + + ! If indices are within grid, set in grid to true + if (IZ_LO >= 1 .and. IZ_HI <= G3D%NZGrids) then + InGrid = .true. + DZ = 2.0_ReKi*DZ - 1.0_ReKi + return + end if + + ! If below grid + if (IZ_LO < 1) then + if (IZ_LO == 0 .and. DZ >= 1.0_ReKi - GridTol) then + InGrid = .true. + IZ_LO = 1 + IZ_HI = 2 + DZ = -1.0_ReKi + else if (G3D%InterpTower) then + ! Interp from bottom of grid to ground (zero velocity) + InGrid = .false. + IZ_LO = 0 + IZ_HI = 1 + DZ = 2.0_ReKi*(PosZ/G3D%GridBase) - 1.0_ReKi + else if (G3D%NTGrids > 0) then + ! Interpolate with tower grid + InGrid = .false. + ! Tower grid is reversed (lowest index is top of tower) + IZ_LO = int(-(Z_GRID - 1)) + 1 + if (IZ_LO >= G3D%NTGrids) then + ! Between end of tower grid and ground (zero velocity) + IZ_LO = G3D%NTGrids + DZ = 1.0_ReKi - 2.0_ReKi*(PosZ/(G3D%GridBase - real(IZ_LO - 1, ReKi)/G3D%InvDZ)) + else + ! Within tower grid + DZ = 2.0_ReKi*(real(2 - IZ_LO, ReKi) - Z_GRID) - 1.0_ReKi + end if + IZ_HI = IZ_LO + 1 + else if (AllowExtrap) then + InGrid = .true. + IZ_LO = 1 + IZ_HI = 1 + DZ = 2.0_ReKi*max(PosZ/G3D%GridBase, 0.0_Reki) - 1.0_ReKi + AllExtrap = ior(AllExtrap, ExtrapZmin) + else + ! Position below grid + call SetErrStat(ErrID_Fatal, ' G3D wind array boundaries violated. '// & + 'Grid too small in Z direction '// & + '(height (Z='//TRIM(Num2LStr(Position(3)))// & + ' m) is below the grid and no tower points are defined).', & + ErrStat, ErrMsg, RoutineName) + end if + return + end if + + ! If above grid + if (IZ_HI > G3D%NZGrids) then + if (IZ_HI == G3D%NZGrids + 1 .and. DZ <= GridTol) then + InGrid = .true. + IZ_LO = G3D%NZGrids - 1 + IZ_HI = G3D%NZGrids + DZ = 1.0_ReKi + else if (AllowExtrap) then + InGrid = .true. + IZ_LO = G3D%NZGrids + IZ_HI = G3D%NZGrids + ! Calculate interpolation, limit to value at grid width above top of grid + DZ = 2.0_ReKi*min((Position(3) - (G3D%GridBase + 2*G3D%ZHWid))/G3D%ZHWid, 1.0_ReKi) - 1.0_ReKi + AllExtrap = ior(AllExtrap, ExtrapZmax) + else + ! Position above grid + call SetErrStat(ErrID_Fatal, ' G3D wind array boundaries violated. '// & + 'Grid too small in Z direction '// & + '(Z='//TRIM(Num2LStr(Position(3)))//' m is above grid.)', & + ErrStat, ErrMsg, RoutineName) + end if + return + end if + + end subroutine + + !> GetBoundsT populates IT_Lo, IT_Hi, and the interpolant [-1,1]. + subroutine GetBoundsT(PosX, DT) + + real(ReKi), intent(in) :: PosX + real(ReKi), intent(out) :: DT + + real(ReKi) :: TimeShifted + real(ReKi) :: T_GRID + + ! Perform the time shift. At time=0, a point half the grid width downstream + ! (p%YHWid) will index into the zero time slice. If we did not do this, + ! any point downstream of the tower at the beginning of the run would + ! index outside of the array. This all assumes the grid width is at least as + ! large as the rotor. If it isn't, then the interpolation will not work. + + ! In distance, X: InputInfo%PosX - p%InitXPosition - TIME*p%MeanWS + TimeShifted = real(Time, ReKi) + (G3D%InitXPosition - PosX)*G3D%InvMWS + + ! If field is periodic + if (G3D%Periodic) then + TimeShifted = MODULO(TimeShifted, G3D%TotalTime) + ! If TimeShifted is a very small negative number, + ! modulo returns the incorrect value due to internal rounding errors. + ! See bug report #471 + if (TimeShifted == G3D%TotalTime) TimeShifted = 0.0_ReKi + end if + + ! Get position on T grid + T_GRID = TimeShifted*G3D%Rate + 1 + + ! Calculate bounding grid indices + IT_LO = floor(T_GRID, IntKi) + IT_HI = ceiling(T_GRID, IntKi) + + ! Position location within interval [0,1] + DT = T_GRID - aint(T_GRID) + + ! Adjust indices and interpolant + if (IT_LO >= 1 .and. IT_HI <= G3D%NSteps) then + ! Point is within grid + DT = 2.0_ReKi*DT - 1.0_ReKi + else if (IT_LO == G3D%NSteps) then + if (G3D%Periodic) then + ! Time wraps back to beginning + IT_HI = 1 + DT = 2.0_ReKi*DT - 1.0_ReKi + else if (DT <= GridTol) then + ! Within tolerance of last time + IT_HI = IT_LO + DT = -1.0_Reki + else + ! Extrapolate + IT_LO = G3D%NSteps - 1 + IT_HI = G3D%NSteps + DT = DT + 1.0_ReKi + end if + else + ! Time exceeds array bounds + call SetErrStat(ErrID_Fatal, ' Error: GF wind array was exhausted at '// & + TRIM(Num2LStr(TIME))//' seconds (trying to access data at '// & + TRIM(Num2LStr(TimeShifted))//' seconds).', & + ErrStat, ErrMsg, RoutineName) + end if + + end subroutine + +end subroutine + +pure function Grid3DField_GetVelLinear(VelCell, Xi, Is3D) result(Velocity) + + real(ReKi), intent(in) :: VelCell(8, 3) !< velocities at corners of grid cell + real(ReKi), intent(in) :: Xi(3) !< isoparametric coordinates in cell (dy, dz, dt) [-1, +1] + logical, intent(in) :: Is3D !< flag for 3D or 2D grid + real(ReKi) :: Velocity(3) !< The U, V, W velocities + + real(ReKi) :: N(8) ! Shape function values + integer(IntKi) :: IC + + if (Is3D) then + + ! Get 3D interpolation weights + N(1) = (1.0_ReKi - Xi(1))*(1.0_ReKi - Xi(2)) + N(2) = (1.0_ReKi + Xi(1))*(1.0_ReKi - Xi(2)) + N(3) = (1.0_ReKi - Xi(1))*(1.0_ReKi + Xi(2)) + N(4) = (1.0_ReKi + Xi(1))*(1.0_ReKi + Xi(2)) + N(5) = (1.0_ReKi - Xi(1))*(1.0_ReKi - Xi(2)) + N(6) = (1.0_ReKi + Xi(1))*(1.0_ReKi - Xi(2)) + N(7) = (1.0_ReKi - Xi(1))*(1.0_ReKi + Xi(2)) + N(8) = (1.0_ReKi + Xi(1))*(1.0_ReKi + Xi(2)) + N(1:4) = N(1:4)*(1.0_ReKi - Xi(3))/8.0_ReKi + N(5:8) = N(5:8)*(1.0_ReKi + Xi(3))/8.0_ReKi + + ! Calculate velocity + do ic = 1, 3 + Velocity(ic) = dot_product(VelCell(:, ic), N) + end do + + else + + ! Get 2D interpolation weights + N(1) = (1.0_ReKi - Xi(2))*(1.0_ReKi - Xi(3))/4.0_ReKi + N(2) = (1.0_ReKi + Xi(2))*(1.0_ReKi - Xi(3))/4.0_ReKi + N(3) = (1.0_ReKi - Xi(2))*(1.0_ReKi + Xi(3))/4.0_ReKi + N(4) = (1.0_ReKi + Xi(2))*(1.0_ReKi + Xi(3))/4.0_ReKi + + ! Calculate velocity + do ic = 1, 3 + Velocity(ic) = dot_product(VelCell(1:4, ic), N(1:4)) + end do + + end if + +end function + +subroutine Grid3DField_GetVelAccCubic(DTime, VelCell, AccCell, Xi, Is3D, Velocity, Accel) + + real(ReKi), intent(in) :: DTime !< cell delta time + real(ReKi), intent(in) :: VelCell(8, 3) !< + real(ReKi), intent(in) :: AccCell(8, 3) !< + real(ReKi), intent(in) :: Xi(3) !< cell distance (dy, dz, dt) [-1, +1] + logical, intent(in) :: Is3D !< + real(ReKi), intent(out), optional :: Velocity(3) !< + real(ReKi), intent(out), optional :: Accel(3) !< + + character(*), parameter :: RoutineName = "Grid3DField_GetVelAccCubic" + integer(IntKi) :: IC + real(ReKi) :: N(4) + real(ReKi) :: P(3, 2), PP(3, 2) + real(ReKi) :: t, C1, C2, C3, C4 + + ! If 3D interpolation + if (Is3D) then + + ! Get interpolation weights + N(1) = (1.0_ReKi - Xi(1))*(1.0_ReKi - Xi(2))/4.0_ReKi + N(2) = (1.0_ReKi + Xi(1))*(1.0_ReKi - Xi(2))/4.0_ReKi + N(3) = (1.0_ReKi - Xi(1))*(1.0_ReKi + Xi(2))/4.0_ReKi + N(4) = (1.0_ReKi + Xi(1))*(1.0_ReKi + Xi(2))/4.0_ReKi + + ! Calculate velocity and acceleration at lo and hi time + do IC = 1, 3 + P(IC, 1) = dot_product(VelCell(1:4, IC), N) ! lo time + P(IC, 2) = dot_product(VelCell(5:8, IC), N) ! hi time + PP(IC, 1) = dot_product(AccCell(1:4, IC), N) ! lo time + PP(IC, 2) = dot_product(AccCell(5:8, IC), N) ! hi time + end do + + else ! 2D (Tower) + + ! Get interpolation weights + N(1) = (1.0_ReKi - Xi(2))/2.0_ReKi + N(2) = (1.0_ReKi + Xi(2))/2.0_ReKi + + ! Calculate velocity and acceleration at lo and hi time + do IC = 1, 3 + P(IC, 1) = dot_product(VelCell(1:2, IC), N(1:2)) ! lo time + P(IC, 2) = dot_product(VelCell(3:4, IC), N(1:2)) ! hi time + PP(IC, 1) = dot_product(AccCell(1:2, IC), N(1:2)) ! lo time + PP(IC, 2) = dot_product(AccCell(3:4, IC), N(1:2)) ! hi time + end do + + end if + + ! Calculate interval percent + t = (Xi(3) + 1)/2.0_ReKi + + ! If velocity requested + if (present(Velocity)) then + C1 = 2.0_ReKi*t*t*t - 3.0_ReKi*t*t + 1.0_ReKi + C2 = (t*t*t - 2.0_ReKi*t*t + t)*DTime + C3 = -2.0_ReKi*t*t*t + 3.0_ReKi*t*t + C4 = (t*t*t - t*t)*DTime + Velocity = C1*P(:, 1) + C2*PP(:, 1) + C3*P(:, 2) + C4*PP(:, 2) + end if + + ! If acceleration requested + if (present(Accel)) then + C1 = (6.0_ReKi*t*t - 6.0_ReKi*t)/DTime + C2 = 3.0_ReKi*t*t - 4.0_ReKi*t + 1.0_ReKi + C3 = -C1 + C4 = 3.0_ReKi*t*t - 2.0_ReKi*t + Accel = C1*P(:, 1) + C2*PP(:, 1) + C3*P(:, 2) + C4*PP(:, 2) + end if + +end subroutine + +subroutine IfW_Grid3DField_CalcAccel(G3D, ErrStat, ErrMsg) + type(Grid3DFieldType), intent(inout) :: G3D + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "Grid3DField_CalcAccel" + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + integer(IntKi) :: ic, iy, iz + real(ReKi), allocatable :: u(:), dy2(:) + + ErrStat = ErrID_None + ErrMsg = "" + + ! Allocate storage for acceleration grid + call AllocAry(G3D%Acc, size(G3D%Vel, dim=1), size(G3D%Vel, dim=2), & + size(G3D%Vel, dim=3), size(G3D%Vel, dim=4), & + 'grid-field velocity data', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! If number of time grids is 1 or 2, set all accelerations to zero, return + if (G3D%NTGrids < 3) then + G3D%Acc = 0.0_SiKi + return + end if + + ! Allocate storage for U used in cubic spline derivative calc + call AllocAry(U, G3D%NSteps, "storage for U", TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Allocate storage for V used in cubic spline derivative calc + call AllocAry(dy2, G3D%NSteps, "storage for V", TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Loop through grid points and calculate derivative using spline + do iz = 1, G3D%NZGrids + do iy = 1, G3D%NYGrids + do ic = 1, G3D%NComp + call CalcCubicSplineDeriv(G3D%NSteps, G3D%DTime, G3D%Vel(ic, iy, iz, :), G3D%Acc(ic, iy, iz, :)) + end do + end do + end do + + ! If grid field does not include tower grids, return + if (G3D%NTGrids == 0) return + + ! Allocate storage for tower acceleration + call AllocAry(G3D%AccTower, size(G3D%VelTower, dim=1), & + size(G3D%VelTower, dim=2), size(G3D%VelTower, dim=3), & + 'tower wind acceleration data.', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! If number of time grids is 1 or 2, set all accelerations to zero + if (G3D%NTGrids < 3) then + G3D%Acc = 0.0_SiKi + else ! Otherwise, calculate acceleration at each grid point + do iz = 1, G3D%NTGrids + do ic = 1, G3D%NComp + call CalcCubicSplineDeriv(G3D%NSteps, G3D%DTime, G3D%VelTower(ic, iz, :), G3D%AccTower(ic, iz, :)) + end do + end do + end if + +contains + + !> CalcCubicSplineDeriv fits a cubic spline through the y array with points + !! spaced a constant 'h' apart. It then calculates the corresponding + !! derivative of y with respect to x at the same x values and returns it + !! in the dy array. + subroutine CalcCubicSplineDeriv(n, h, y, dy) + integer(IntKi), intent(in) :: n ! number of points + real(ReKi), intent(in) :: h ! delta time + real(SiKi), intent(in) :: y(:) ! value at each time + real(SiKi), intent(out) :: dy(:) ! value derivative at each time + + integer(IntKi) :: i + real(ReKi) :: p, un + + ! If periodic function, set beginning and end to have same slope + if (G3D%Periodic) then + dy(1) = real((y(2) - y(n - 1))/(2.0_ReKi*h), SiKi) + dy(n) = dy(1) + else + dy(1) = 0.0_ReKi + dy(n) = 0.0_ReKi + end if + + ! Apply first derivative at lower boundary condition + dy2(1) = -0.5_ReKi + u(1) = 3.0_ReKi*((y(2) - y(1))/h - dy(1))/h + + ! Decomposition + do i = 2, n - 1 + p = 0.5_ReKi*dy2(i - 1) + 2.0_ReKi + dy2(i) = -0.5_ReKi/p + u(i) = (6.*((y(i + 1) - 2.0_ReKi*y(i) + y(i - 1))/h)/(2.0_ReKi*h) - 0.5_ReKi*u(i - 1))/p + end do + + ! Apply first derviative at upper boundary condition + un = 3.0_ReKi*(dy(n) - (y(n) - y(n - 1))/h)/h + dy2(n) = (un - 0.5_ReKi*u(n - 1))/(0.5_ReKi*dy2(n - 1) + 1.0_ReKi) + + ! Back substitution and derivative calculation + do i = n - 1, 1, -1 + dy2(i) = dy2(i)*dy2(i + 1) + u(i) + dy(i) = real((y(i + 1) - y(i))/h - h*(dy2(i)/3.0_ReKi + dy2(i + 1)/6.0_ReKi), SiKi) + end do + + end subroutine + +end subroutine + +!> This subroutine generates the mean wind vector timeseries for each height above the ground. This +!! is essentially compressing the Y dimension of the wind box leaving a Z-T plane of vectors. The +!! resulting dimensions will be (NZGrids, NYGrids, NFFComp, NFFSteps) +subroutine IfW_Grid3DField_CalcVelAvgProfile(G3D, CalcAccel, ErrStat, ErrMsg) + + type(Grid3DFieldType), intent(inout) :: G3D !< Parameters + logical, intent(inout) :: CalcAccel !< Flag to calculate acceleration + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = 'IfW_Grid3DField_CalcVelAvgProfile' + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + ! Allocate velocity array + if (.not. allocated(G3D%VelAvg)) then + call AllocAry(G3D%VelAvg, G3D%NComp, G3D%NZGrids, G3D%NSteps, & + 'Full-field average wind velocity timeseries data array.', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + G3D%VelAvg = 0.0_SiKi + end if + + ! Calculate average velocity for each component across grid (Y) + G3D%VelAvg = sum(G3D%Vel, dim=2)/G3D%NYGrids + + ! If acceleration calculation not requested, return + if (.not. CalcAccel) return + + ! Allocate acceleration array + if (.not. allocated(G3D%AccAvg)) then + call AllocAry(G3D%AccAvg, G3D%NComp, G3D%NZGrids, G3D%NSteps, & + 'Full-field average wind acceleration timeseries data array.', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + G3D%AccAvg = 0.0_SiKi + end if + + ! Calculate average acceleration for each component across grid (Y) + G3D%AccAvg = sum(G3D%Acc, dim=2)/G3D%NYGrids + +end subroutine + +subroutine Grid4DField_GetVel(G4D, Time, Position, Velocity, ErrStat, ErrMsg) + + type(Grid4DFieldType), intent(in) :: G4D !< 4D grid-field data + real(DbKi), intent(in) :: Time !< time to get value + real(ReKi), intent(in) :: Position(3) !< position X,Y,Z to get value + real(ReKi), intent(out) :: Velocity(3) !< The U, V, W velocities + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "Grid4DField_GetVel" + + integer(IntKi) :: Indx_Lo(4) ! index associated with lower bound of dimension 1-4 where val(Indx_lo(i)) <= InCoord(i) <= val(Indx_hi(i)) + integer(IntKi) :: Indx_Hi(4) ! index associated with upper bound of dimension 1-4 where val(Indx_lo(i)) <= InCoord(i) <= val(Indx_hi(i)) + real(ReKi) :: xi(4) ! isoparametric coordinates + real(ReKi) :: N(16, 1) ! Shape function + real(ReKi) :: P(3, 16) ! Point values + real(ReKi) :: tmp + integer(IntKi) :: i + + ErrStat = ErrID_None + ErrMsg = "" + + !---------------------------------------------------------------------------- + ! Find the bounding indices for XYZ position + !---------------------------------------------------------------------------- + + do i = 1, 3 + tmp = (Position(i) - G4D%pZero(i))/G4D%delta(i) + Indx_Lo(i) = INT(tmp) + 1 ! convert REAL to INTEGER, then add one since our grid indices start at 1, not 0 + xi(i) = 2.0_ReKi*(tmp - aint(tmp)) - 1.0_ReKi ! convert to value between -1 and 1 + end do + + !---------------------------------------------------------------------------- + ! Find the bounding indices for time + !---------------------------------------------------------------------------- + + i = 4 + tmp = real((Time - G4D%TimeStart)/G4D%delta(i), ReKi) + Indx_Lo(i) = INT(tmp) + 1 ! convert REAL to INTEGER, then add one since our grid indices start at 1, not 0 + xi(i) = 2.0_ReKi*(tmp - aint(tmp)) - 1.0_ReKi ! convert to value between -1 and 1 + if ((Indx_Lo(i) == G4D%n(i))) then + if (abs(xi(i) + 1.0_SiKi) < 0.001_SiKi) then ! Allow for the special case where Time = TgridStart + deltat*( n_high_low - 1 ) + Indx_Lo(i) = Indx_Lo(i) - 1 + xi(i) = 1.0_SiKi + end if + end if + + !---------------------------------------------------------------------------- + ! Return error if outside bounds + !---------------------------------------------------------------------------- + + do i = 1, 4 + if (Indx_Lo(i) <= 0) then + Indx_Lo(i) = 1 + call SetErrStat(ErrID_Fatal, 'Outside the grid bounds.', ErrStat, ErrMsg, RoutineName) + return + elseif (Indx_Lo(i) >= G4D%n(i)) then + Indx_Lo(i) = max(G4D%n(i) - 1, 1) ! make sure it's a valid index + call SetErrStat(ErrID_Fatal, 'Outside the grid bounds.', ErrStat, ErrMsg, RoutineName) + return + end if + Indx_Hi(i) = min(Indx_Lo(i) + 1, G4D%n(i)) ! make sure it's a valid index + end do + + !---------------------------------------------------------------------------- + ! Clamp isopc to [-1, 1] so we don't extrapolate (effectively nearest neighbor) + !---------------------------------------------------------------------------- + + xi = min(+1.0_ReKi, max(-1.0_ReKi, xi)) + + !---------------------------------------------------------------------------- + ! compute weighting factors + !---------------------------------------------------------------------------- + + N(1, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi - xi(4)) + N(2, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi - xi(4)) + N(3, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi - xi(4)) + N(4, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi - xi(4)) + N(5, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi - xi(4)) + N(6, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi - xi(4)) + N(7, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi - xi(4)) + N(8, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi - xi(4)) + N(9, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi + xi(4)) + N(10, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi + xi(4)) + N(11, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi + xi(4)) + N(12, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi - xi(3))*(1.0_ReKi + xi(4)) + N(13, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi + xi(4)) + N(14, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi - xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi + xi(4)) + N(15, 1) = (1.0_ReKi - xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi + xi(4)) + N(16, 1) = (1.0_ReKi + xi(1))*(1.0_ReKi + xi(2))*(1.0_ReKi + xi(3))*(1.0_ReKi + xi(4)) + N = N/16.0_ReKi + + !---------------------------------------------------------------------------- + ! Get point values + !---------------------------------------------------------------------------- + + P(:, 1) = G4D%Vel(:, Indx_Lo(1), Indx_Lo(2), Indx_Lo(3), Indx_Lo(4)) + P(:, 2) = G4D%Vel(:, Indx_Hi(1), Indx_Lo(2), Indx_Lo(3), Indx_Lo(4)) + P(:, 3) = G4D%Vel(:, Indx_Lo(1), Indx_Hi(2), Indx_Lo(3), Indx_Lo(4)) + P(:, 4) = G4D%Vel(:, Indx_Hi(1), Indx_Hi(2), Indx_Lo(3), Indx_Lo(4)) + P(:, 5) = G4D%Vel(:, Indx_Lo(1), Indx_Lo(2), Indx_Hi(3), Indx_Lo(4)) + P(:, 6) = G4D%Vel(:, Indx_Hi(1), Indx_Lo(2), Indx_Hi(3), Indx_Lo(4)) + P(:, 7) = G4D%Vel(:, Indx_Lo(1), Indx_Hi(2), Indx_Hi(3), Indx_Lo(4)) + P(:, 8) = G4D%Vel(:, Indx_Hi(1), Indx_Hi(2), Indx_Hi(3), Indx_Lo(4)) + P(:, 9) = G4D%Vel(:, Indx_Lo(1), Indx_Lo(2), Indx_Lo(3), Indx_Hi(4)) + P(:, 10) = G4D%Vel(:, Indx_Hi(1), Indx_Lo(2), Indx_Lo(3), Indx_Hi(4)) + P(:, 11) = G4D%Vel(:, Indx_Lo(1), Indx_Hi(2), Indx_Lo(3), Indx_Hi(4)) + P(:, 12) = G4D%Vel(:, Indx_Hi(1), Indx_Hi(2), Indx_Lo(3), Indx_Hi(4)) + P(:, 13) = G4D%Vel(:, Indx_Lo(1), Indx_Lo(2), Indx_Hi(3), Indx_Hi(4)) + P(:, 14) = G4D%Vel(:, Indx_Hi(1), Indx_Lo(2), Indx_Hi(3), Indx_Hi(4)) + P(:, 15) = G4D%Vel(:, Indx_Lo(1), Indx_Hi(2), Indx_Hi(3), Indx_Hi(4)) + P(:, 16) = G4D%Vel(:, Indx_Hi(1), Indx_Hi(2), Indx_Hi(3), Indx_Hi(4)) + + !---------------------------------------------------------------------------- + ! Interpolate + !---------------------------------------------------------------------------- + + Velocity = pack(matmul(P, N), .true.) + +end subroutine + +subroutine UserField_GetVel(UF, Time, Position, Velocity, ErrStat, ErrMsg) + + type(UserFieldType), intent(in) :: UF !< user-field data + real(DbKi), intent(in) :: Time !< time to get value + real(ReKi), intent(in) :: Position(3) !< position X,Y,Z to get value + real(ReKi), intent(out) :: Velocity(3) !< The U, V, W velocities + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "UserField_GetVel" + + ErrStat = ErrID_None + ErrMsg = "" + + Velocity = 0.0_ReKi + call SetErrStat(ErrID_Fatal, "UserField_GetVel not implemented", ErrStat, ErrMsg, RoutineName) + +end subroutine + +function CalculateMeanVelocity(G3D, z, y) result(u) + + type(Grid3DFieldType), intent(IN) :: G3D !< Parameters + real(ReKi), intent(IN) :: Z ! height + real(ReKi), intent(IN) :: y ! lateral location + real(ReKi) :: u ! mean wind speed at position (y,z) + + if (Z <= 0.0_ReKi) then + U = 0.0_ReKi + return + end if + + select case (G3D%WindProfileType) + + case (WindProfileType_PL) + + U = G3D%MeanWS*(Z/G3D%RefHeight)**G3D%PLExp ! [IEC 61400-1 6.3.1.2 (10)] + + case (WindProfileType_Log) + + if (.not. EqualRealNos(G3D%RefHeight, G3D%Z0) .and. Z > 0.0_ReKi) then + U = G3D%MeanWS*(LOG(Z/G3D%Z0))/(LOG(G3D%RefHeight/G3D%Z0)) + else + U = 0.0_ReKi + end if + + case (WindProfileType_Constant) + + U = G3D%MeanWS + + case DEFAULT + + U = 0.0_ReKi + + end select + + if (G3D%VLinShr .ne. 0.0_ReKi) then ! Add vertical linear shear, if has + U = U + G3D%MeanWS*G3D%VLinShr*(Z - G3D%RefHeight)/G3D%RefLength + end if + + if (G3D%HLinShr .ne. 0.0_ReKi) then ! Add horizontal linear shear, if has + U = U + G3D%MeanWS*G3D%HLinShr*y/G3D%RefLength + end if + +end function CalculateMeanVelocity + +subroutine Uniform_to_Grid3D(UF, InterpCubic, G3D, ErrStat, ErrMsg) + + type(UniformFieldType), intent(IN) :: UF !< UniformWind Parameters + logical, intent(in) :: InterpCubic !< Flag to use cubic interpolation + type(Grid3DFieldType), intent(OUT) :: G3D !< FF Parameters + integer(IntKi), intent(OUT) :: ErrStat !< error status + character(*), intent(OUT) :: ErrMsg !< error message + + character(*), parameter :: RoutineName = 'Uniform_to_FFWind' + integer(ReKi), parameter :: dz = 5.0 + integer(ReKi), parameter :: dy = 5.0 + real(DbKi) :: Time + real(ReKi) :: PositionXYZ(3) + type(UniformField_Interp) :: op + integer(IntKi) :: n, i, it, iy, iz + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + G3D%WindFileFormat = -1 ! Binary file format description number + G3D%NComp = 3 ! Number of wind components + G3D%Periodic = .false. + G3D%InterpTower = .true. + G3D%RefHeight = UF%RefHeight + G3D%NTGrids = 0 + G3D%InvDY = 1.0_ReKi/dy ! reciprocal of delta y (1/meters) + G3D%InvDZ = 1.0_ReKi/dz ! reciprocal of delta z (1/meters) + + ! Number of points in the lateral (y) direction of the grids + n = nint(UF%RefLength*1.1_ReKi*0.5_ReKi/dy) + G3D%NYGrids = n*2 + 1 + + ! Number of points in the vertical (z) direction of the grids + n = nint(UF%RefLength*1.1_ReKi*0.5_ReKi/dz) + G3D%NZGrids = nint(G3D%RefHeight/dy) + n + 1 + + ! Half the grid width (meters) + G3D%YHWid = 0.5_ReKi*dy*(G3D%NYGrids - 1) + + ! Half the grid height (meters) + G3D%ZHWid = 0.5_ReKi*dz*(G3D%NZGrids - 1) + + ! Height of the bottom of the grid (meters) + G3D%GridBase = G3D%RefHeight + n*dz - G3D%ZHWid*2.0_ReKi + + ! Initial x position of grid (distance in FF is offset) meters) + G3D%InitXPosition = 0.0_ReKi + + ! time will be the smallest delta t in this Uniform wind file + if (UF%DataSize < 2) then + G3D%DTime = 600.0_ReKi ! doesn't matter what the time step is + G3D%NSteps = 2 ! "Number of time steps in the FF array + else + G3D%DTime = minval(UF%Time(2:) - UF%Time(:size(UF%Time) - 1)) ! Delta time (seconds) + if (G3D%DTime < 0.0001) then + call SetErrStat(ErrID_Fatal, "Smallest time step in uniform wind file is less that 0.0001 seconds. "// & + "Increase the time step to convert to a FF file.", ErrStat, ErrMsg, RoutineName) + return + end if + G3D%NSteps = NINT(UF%Time(UF%DataSize)/G3D%DTime) + 1 + end if + + G3D%Rate = 1.0_ReKi/G3D%DTime ! Data rate (1/DTime) + G3D%AddMeanAfterInterp = .false. ! Add the mean wind speed after interpolating at a given height? + G3D%WindProfileType = WindProfileType_PL ! Wind profile type (0=constant;1=logarithmic;2=power law) + G3D%PLExp = GetAverageVal(UF%ShrV) ! Power law exponent (used for PL wind profile type only) + G3D%Z0 = 0.0_ReKi ! Surface roughness length (used for LOG wind profile type only) + G3D%TotalTime = (G3D%NSteps - 1)*G3D%DTime ! The total time of the simulation (seconds) + + ! Allocate velocity array + call AllocAry(G3D%Vel, G3D%NComp, G3D%NYGrids, G3D%NZGrids, G3D%NSteps, 'G3D%Vel', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Initialize position + PositionXYZ = 0.0_ReKi + + ! Loop through time steps + do it = 1, G3D%NSteps + + ! Calculate time + Time = (it - 1)*G3D%DTime + + ! Get operating point + if (InterpCubic) then + op = UniformField_InterpCubic(UF, Time) + else + op = UniformField_InterpLinear(UF, Time) + end if + + ! Loop through y grid + do iy = 1, G3D%NYGrids + + ! Calculate Y position + PositionXYZ(2) = (iy - 1)*dy - G3D%YHWid + + ! Loop through z grid + do iz = 1, G3D%NZGrids + + ! Calculate Z position + PositionXYZ(3) = (iz - 1)*dz + G3D%GridBase + + ! If Z is zero or less + if (PositionXYZ(3) <= 0.0_Reki) then + ! Set wind velocity to zero + G3D%Vel(:, iy, iz, it) = 0.0_SiKi + else + ! Calculate velocity at operating point and position, store in grid + G3D%Vel(:, iy, iz, it) = real(UniformField_GetVel(UF, op, PositionXYZ), SiKi) + end if + end do ! iz + end do ! iy + end do ! it + + ! compute some averages for this simulation + G3D%MeanWS = GetAverageVal(UF%VelH) ! Mean wind speed (advection speed) + G3D%InvMWS = 1.0_ReKi/G3D%MeanWS + +contains + + function GetAverageVal(Ary) result(Avg) + real(ReKi), intent(in) :: Ary(:) + real(ReKi) :: Avg + + ! If array has one element, average is first value + if (UF%DataSize < 2) then + Avg = Ary(1) + return + end if + + Avg = UF%Time(1)*Ary(1) ! in case tData(1) /= 0 + do i = 2, UF%DataSize + Avg = Avg + (UF%Time(i) - UF%Time(i - 1))*(Ary(i) + Ary(i - 1)) + end do + Avg = Avg/(UF%Time(UF%DataSize) - UF%Time(1))/2.0_ReKi + + end function GetAverageVal + +end subroutine Uniform_to_Grid3D + +subroutine Grid3D_to_Uniform(G3D, UF, ErrStat, ErrMsg, SmoothingRadius) + + type(Grid3DFieldType), intent(IN) :: G3D !< FF Parameters + type(UniformFieldType), intent(OUT) :: UF !< UniformWind Parameters + integer(IntKi), intent(OUT) :: ErrStat !< error status + character(*), intent(OUT) :: ErrMsg !< error message + real(ReKi), optional, intent(IN) :: SmoothingRadius !< length of time used for smoothing data, seconds (if omitted, no smoothing will occur) + + character(*), parameter :: RoutineName = 'FFWind_to_Uniform' + integer(IntKi) :: i + integer(IntKi) :: iy_ref, iz_ref, iz_p1 + integer(IntKi) :: iy, iz, ic + real(ReKi) :: meanVel(3) + real(ReKi) :: meanWindDir + real(ReKi) :: u_p1, z_p1 + real(ReKi), parameter :: HubPositionX = 0.0_ReKi + real(ReKi) :: radius ! length of time to use for smoothing uniform wind data, seconds + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + real(SiKi), allocatable :: Vel(:, :, :, :) + real(ReKi), allocatable :: tmp(:) + real(R8Ki) :: transformMat(3, 3) + + ErrStat = ErrID_None + ErrMsg = "" + + if (G3D%RefLength > epsilon(0.0_ReKi)) then + UF%RefLength = G3D%VLinShr + else + UF%RefLength = (G3D%nYGrids - 1)/G3D%InvDY ! width of the FF wind field + end if + + UF%DataSize = G3D%NSteps + + call AllocAry(UF%Time, UF%DataSize, 'time', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%VelH, UF%DataSize, 'horizontal wind speed', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%AngleH, UF%DataSize, 'direction', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%AngleV, UF%DataSize, 'upflow', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%VelV, UF%DataSize, 'vertical wind speed', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%ShrH, UF%DataSize, 'horizontal linear shear', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%ShrV, UF%DataSize, 'vertical power-law shear exponent', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%LinShrV, UF%DataSize, 'vertical linear shear', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(UF%VelGust, UF%DataSize, 'gust velocity', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call AllocAry(Vel, G3D%NZGrids, G3D%NYGrids, G3D%NComp, G3D%NSteps, 'FFData', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + call AllocAry(tmp, G3D%NSteps, 'tmp', ErrStat2, ErrMsg2); call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + if (ErrStat >= AbortErrLev .or. UF%DataSize < 1) then + if (allocated(Vel)) deallocate (Vel) + if (allocated(tmp)) deallocate (tmp) + return + end if + + ! we'll assume these are 0, for simplicity + UF%ShrH = G3D%HLinShr + UF%LinShrV = G3D%VLinShr + UF%VelGust = 0.0_ReKi + + ! fill time array with time at hub position + do i = 1, UF%DataSize + UF%Time(i) = (G3D%InitXPosition - HubPositionX)*G3D%InvMWS + (i - 1)*G3D%DTime + end do + + ! calculate mean velocity at grid point nearest lateral center of grid at reference height: + iy_ref = nint(G3D%nYGrids/2.0_ReKi) + iz_ref = nint((G3D%RefHeight - G3D%GridBase)*G3D%InvDZ) + 1 + UF%RefHeight = G3D%GridBase + (iz_ref - 1)/G3D%InvDZ ! make sure RefHt is on the grid + + ! Calculate mean value for each component through + meanVel = sum(G3D%Vel(:, iy_ref, iz_ref, :), dim=2)/UF%DataSize + + ! calculate the average upflow angle + UF%AngleV = atan2(meanVel(3), TwoNorm(meanVel(1:2))) + meanWindDir = atan2(meanVel(2), meanVel(1)) + + ! rotate the FF wind to remove the mean upflow and direction + transformMat(1, 1) = cos(meanWindDir)*cos(UF%AngleV(1)) + transformMat(2, 1) = -sin(meanWindDir) + transformMat(3, 1) = -cos(meanWindDir)*sin(UF%AngleV(1)) + + transformMat(1, 2) = sin(meanWindDir)*cos(UF%AngleV(1)) + transformMat(2, 2) = cos(meanWindDir) + transformMat(3, 2) = -sin(meanWindDir)*sin(UF%AngleV(1)) + + transformMat(1, 3) = sin(UF%AngleV(1)) + transformMat(2, 3) = 0.0_R8Ki + transformMat(3, 3) = cos(UF%AngleV(1)) + + do ic = 1, size(Vel, 4) + do iy = 1, size(Vel, 2) + do iz = 1, size(Vel, 1) + Vel(iz, iy, :, ic) = real(matmul(transformMat, G3D%Vel(:, iy, iz, i)), SiKi) + end do + end do + end do + + ! make sure we have the correct mean, or the direction will also be off here + if (G3D%AddMeanAfterInterp) then + Vel(iz_ref, iy_ref, 1, :) = Vel(iz_ref, iy_ref, 1, :) + & + real(CalculateMeanVelocity(G3D, UF%RefHeight, 0.0_ReKi), SiKi) + end if + + meanVel = 0.0_ReKi + do i = 1, UF%DataSize + meanVel = meanVel + Vel(iz_ref, iy_ref, :, i) + end do + meanVel = meanVel/UF%DataSize + + ! Fill velocity arrays for uniform wind + do i = 1, UF%DataSize + UF%VelH(i) = TwoNorm(Vel(iz_ref, iy_ref, 1:2, i)) + end do + UF%VelV = Vel(iz_ref, iy_ref, 3, :) + + ! Fill wind direction array + do i = 1, UF%DataSize + UF%AngleH(i) = -(meanWindDir + atan2(Vel(iz_ref, iy_ref, 2, i), Vel(iz_ref, iy_ref, 1, i))) + end do + + ! Now, time average values, if desired: + if (present(SmoothingRadius)) then + radius = SmoothingRadius + else + radius = 0.0_ReKi + end if + + tmp = UF%VelH; call kernelSmoothing(UF%Time, tmp, kernelType_TRIWEIGHT, radius, UF%VelH) + tmp = UF%VelV; call kernelSmoothing(UF%Time, tmp, kernelType_TRIWEIGHT, radius, UF%VelV) + tmp = UF%AngleH; call kernelSmoothing(UF%Time, tmp, kernelType_TRIWEIGHT, radius, UF%AngleH) + + ! Calculate averaged power law coefficient: + if (G3D%WindProfileType == WindProfileType_PL) then + UF%ShrV = G3D%PLExp + else + iz_p1 = G3D%nZGrids ! pick a point to compute the power law exponent (least squares would be better than a single point) + z_p1 = G3D%GridBase + (iz_p1 - 1)/G3D%InvDZ + + if (G3D%AddMeanAfterInterp) then + u_p1 = CalculateMeanVelocity(G3D, z_p1, 0.0_ReKi) + else + u_p1 = 0.0_ReKi + do i = 1, UF%DataSize + u_p1 = u_p1 + Vel(iz_p1, iy_ref, 1, i) + end do + u_p1 = u_p1/UF%DataSize + end if + + if (EqualRealNos(meanVel(1), u_p1) .or. EqualRealNos(u_p1, 0.0_ReKi) .or. EqualRealNos(meanVel(1), 0.0_ReKi)) then + UF%ShrV = 0.0_ReKi + else + UF%ShrV = log(u_p1/meanVel(1))/log(z_p1/UF%RefHeight) + end if + end if + +end subroutine Grid3D_to_Uniform + +end module diff --git a/modules/inflowwind/src/IfW_FlowField.txt b/modules/inflowwind/src/IfW_FlowField.txt new file mode 100644 index 000000000..cb890684f --- /dev/null +++ b/modules/inflowwind/src/IfW_FlowField.txt @@ -0,0 +1,124 @@ +#---------------------------------------------------------------------------------------------------------------------------------- +# Data structures for representing flow fields. +#---------------------------------------------------------------------------------------------------------------------------------- +# +#---------------------------------------------------------------------------------------------------------------------------------- + +param IfW_FlowField - IntKi Undef_FieldType - 0 - "This is the code for an undefined FieldType" - +param ^ - IntKi Uniform_FieldType - 1 - "Uniform FieldType from SteadyWind or Uniform Wind" - +param ^ - IntKi Grid3D_FieldType - 2 - "3D Grid FieldType from TurbSim, Bladed, HAWC" - +param ^ - IntKi Grid4D_FieldType - 3 - "4D Grid FieldType from FAST.Farm" - +param ^ - IntKi Point_FieldType - 4 - "Points FieldType from ExtInflow" - +param ^ - IntKi User_FieldType - 5 - "User FieldType configured by the user" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ UniformFieldType ReKi RefHeight - - - "reference height; used to center the wind" meters +typedef ^ ^ ReKi RefLength - - - "reference length used to scale the linear shear" meters +typedef ^ ^ IntKi DataSize - - - "size of data in HH file" +typedef ^ ^ ReKi Time : - - "HH time array" seconds +typedef ^ ^ ReKi VelH : - - "HH horizontal wind speed" meters/sec +typedef ^ ^ ReKi VelHDot : - - "Derivative of HH horizontal wind speed wrt time" meters/sec +typedef ^ ^ ReKi VelV : - - "HH vertical wind speed, including tower shadow" meters/sec +typedef ^ ^ ReKi VelVDot : - - "Derivative of HH vertical wind speed wrt time" meters/sec +typedef ^ ^ ReKi VelGust : - - "HH wind gust speed" - +typedef ^ ^ ReKi VelGustDot : - - "Derivative of HH wind gust speed wrt time" - +typedef ^ ^ ReKi AngleH : - - "HH wind direction angle" degrees +typedef ^ ^ ReKi AngleHDot : - - "Derivative of HH wind direction angle wrt time" degrees +typedef ^ ^ ReKi AngleV : - - "HH upflow angle" degrees +typedef ^ ^ ReKi AngleVDot : - - "Derivative of HH upflow angle wrt time" degrees +typedef ^ ^ ReKi ShrH : - - "HH horizontal linear shear" - +typedef ^ ^ ReKi ShrHDot : - - "Derivative of HH horizontal linear shear wrt time" - +typedef ^ ^ ReKi ShrV : - - "HH vertical shear exponent" - +typedef ^ ^ ReKi ShrVDot : - - "Derivative of HH vertical shear exponent wrt time" - +typedef ^ ^ ReKi LinShrV : - - "HH vertical linear shear" seconds +typedef ^ ^ ReKi LinShrVDot : - - "Derivative of HH vertical linear shear wrt time" seconds + +typedef ^ UniformField_Interp ReKi VelH - - - "HH horizontal wind speed" meters/sec +typedef ^ ^ ReKi VelHDot - - - "derivative of HH horizontal wind speed wrt Time" meters/sec +typedef ^ ^ ReKi VelV - - - "HH vertical wind speed, including tower shadow" meters/sec +typedef ^ ^ ReKi VelVDot - - - "derivative of HH vertical wind speed wrt Time" meters/sec +typedef ^ ^ ReKi VelGust - - - "HH wind gust speed" - +typedef ^ ^ ReKi VelGustDot - - - "derivative of HH wind gust speed wrt Time" - +typedef ^ ^ ReKi AngleH - - - "HH wind direction angle" degrees +typedef ^ ^ ReKi AngleHDot - - - "derivative of HH wind direction angle wrt Time" degrees +typedef ^ ^ ReKi AngleV - - - "HH upflow angle" degrees +typedef ^ ^ ReKi AngleVDot - - - "derivative of HH upflow angle wrt Time" degrees +typedef ^ ^ ReKi ShrH - - - "HH horizontal linear shear" - +typedef ^ ^ ReKi ShrHDot - - - "derivative of HH horizontal linear shear wrt Time" - +typedef ^ ^ ReKi ShrV - - - "HH vertical shear exponent" - +typedef ^ ^ ReKi ShrVDot - - - "derivative of HH vertical shear exponent wrt Time" - +typedef ^ ^ ReKi LinShrV - - - "HH vertical linear shear" seconds +typedef ^ ^ ReKi LinShrVDot - - - "derivative of HH vertical linear shear wrt Time" seconds +typedef ^ ^ ReKi CosAngleH - - - "Horizontal angle components" - +typedef ^ ^ ReKi SinAngleH - - - "Horizontal angle components" - +typedef ^ ^ ReKi CosAngleV - - - "Vertical angle components" - +typedef ^ ^ ReKi SinAngleV - - - "Vertical angle components" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Grid3DFieldType IntKi WindFileFormat - - - "Binary file format description number" - +typedef ^ ^ IntKi WindProfileType - -1 - "Wind profile type (0=constant;1=logarithmic;2=power law)" - +typedef ^ ^ Logical Periodic - .false. - "Flag to indicate if the wind file is periodic" - +typedef ^ ^ Logical InterpTower - .false. - "Flag to indicate if we should interpolate wind speeds below the tower" - +typedef ^ ^ Logical AddMeanAfterInterp - .false. - "Add the mean wind speed after interpolating at a given height?" - +typedef ^ ^ ReKi RefHeight - 0 - "Reference (hub) height of the grid" meters +typedef ^ ^ ReKi RefLength - 1.0_ReKi - "Reference (rotor) length of the grid (used for horizontal wind profile type only)" - +typedef ^ ^ SiKi Vel :::: - - "Array of field velocities" - +typedef ^ ^ SiKi Acc :::: - - "Array of field accelerations" - +typedef ^ ^ SiKi VelTower ::: - - "Array of tower velocities" - +typedef ^ ^ SiKi AccTower ::: - - "Array of tower accelerations" - +typedef ^ ^ SiKi VelAvg ::: - - "Average velocity profile by Z and time" - +typedef ^ ^ SiKi AccAvg ::: - - "Average acceleration profile by Z and time" - +typedef ^ ^ ReKi DTime - 0 - "Delta time" seconds +typedef ^ ^ ReKi Rate - 0 - "Data rate (1/FFDTime)" Hertz +typedef ^ ^ ReKi YHWid - 0 - "Half the grid width" meters +typedef ^ ^ ReKi ZHWid - 0 - "Half the grid height" meters +typedef ^ ^ ReKi GridBase - 0 - "the height of the bottom of the grid" meters +typedef ^ ^ ReKi InitXPosition - 0 - "the initial x position of grid (distance in FF is offset)" meters +typedef ^ ^ ReKi InvDY - 0 - "reciprocal of delta y" 1/meters +typedef ^ ^ ReKi InvDZ - 0 - "reciprocal of delta z" 1/meters +typedef ^ ^ ReKi MeanWS - 0 - "Mean wind speed (as defined in FF file), not necessarily of the portion used" meters/second +typedef ^ ^ ReKi InvMWS - 0 - "reciprocal of mean wind speed (MeanFFWS)" seconds/meter +typedef ^ ^ ReKi TotalTime - 0 - "The total time of the simulation" seconds +typedef ^ ^ IntKi NComp - 3 - "Number of wind components" - +typedef ^ ^ IntKi NYGrids - 0 - "Number of points in the lateral (y) direction of the grids" - +typedef ^ ^ IntKi NZGrids - 0 - "Number of points in the vertical (z) direction of the grids" - +typedef ^ ^ IntKi NTGrids - 0 - "Number of points in the vertical (z) direction on the tower (below the grids)" - +typedef ^ ^ IntKi NSteps - 0 - "Number of time steps in the FF array" - +typedef ^ ^ ReKi PLExp - 0 - "Power law exponent (used for PL wind profile type only)" - +typedef ^ ^ ReKi Z0 - 0 - "Surface roughness length (used for LOG wind profile type only)" - +typedef ^ ^ ReKi VLinShr - 0 - "Vertical linear wind shear coefficient (used for vertical linear wind profile type only)" - +typedef ^ ^ ReKi HLinShr - 0 - "Horizontal linear wind shear coefficient (used for horizontal wind profile type only)" - +typedef ^ ^ LOGICAL BoxExceedAllowF - .FALSE. - "Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim)" - +typedef ^ ^ IntKi BoxExceedAllowIdx - -1 - "Extrapolate winds outside box starting at this index (for OLAF wakes and LidarSim)" - +typedef ^ ^ LOGICAL BoxExceedWarned - .FALSE. - "Has a warning been issued for points extrapolated beyond FFWind grid" - + + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Grid4DFieldType IntKi n 4 - - "number of evenly-spaced grid points in the x, y, z, and t directions" - +typedef ^ ^ ReKi delta 4 - - "size between 2 consecutive grid points in each grid direction" "m,m,m,s" +typedef ^ ^ ReKi pZero 3 - - "fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:))" "m" +typedef ^ ^ SiKi Vel ::::: - - "this is the 4-d velocity field for each wind component [{uvw},nx,ny,nz,nt]" - +typedef ^ ^ ReKi TimeStart - - - "this is the time where the first time grid in m%V starts (i.e, the time associated with m%V(:,:,:,:,1))" s +typedef ^ ^ ReKi RefHeight - - - "reference height; used to center the wind" meters + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ PointsFieldType ReKi Vel :: - - "Point velocities populated by external driver [uvw,point]" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ UserFieldType ReKi RefHeight - - - "reference height; used to center the wind" meters + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ FlowFieldType IntKi FieldType - 0 - "Switch for flow field type {1=Uniform, 2=Grid, 3=User, 4=External}" - +typedef ^ ^ ReKi RefPosition 3 0.0_ReKi - "Reference position (point where box is rotated)" meters +typedef ^ ^ ReKi PropagationDir - - - "Direction of wind propagation" radians +typedef ^ ^ ReKi VFlowAngle - - - "Vertical (upflow) angle" radians +typedef ^ ^ logical VelInterpCubic - .false. - "Velocity interpolation order in time (1=linear; 3=cubic) [Used with WindType=2,3,4,5,7]" - +typedef ^ ^ logical RotateWindBox - .false. - "flag indicating if the wind will be rotated" - +typedef ^ ^ logical AccFieldValid - .false. - "flag indicating that acceleration field has been calculated" - +typedef ^ ^ ReKi RotToWind {3}{3} - - "Rotation matrix for rotating from the global XYZ coordinate system to the wind coordinate system (wind along X')" - +typedef ^ ^ ReKi RotFromWind {3}{3} - - "Rotation matrix for rotating from the wind coordinate system (wind along X') back to the global XYZ coordinate system. Equal to TRANSPOSE(RotToWind)" - +typedef ^ ^ UniformFieldType Uniform - - - "Uniform Flow Data" +typedef ^ ^ Grid3DFieldType Grid3D - - - "Grid Field Wind Data" +typedef ^ ^ Grid4DFieldType Grid4D - - - "External Grid Flow Data" +typedef ^ ^ PointsFieldType Points - - - "External Point Flow Data" +typedef ^ ^ UserFieldType User - - - "User Field Wind Data" diff --git a/modules/inflowwind/src/IfW_FlowField_Types.f90 b/modules/inflowwind/src/IfW_FlowField_Types.f90 new file mode 100644 index 000000000..c8a805578 --- /dev/null +++ b/modules/inflowwind/src/IfW_FlowField_Types.f90 @@ -0,0 +1,3583 @@ +!STARTOFREGISTRYGENERATEDFILE 'IfW_FlowField_Types.f90' +! +! WARNING This file is generated automatically by the FAST registry. +! Do not edit. Your changes to this file will be lost. +! +! FAST Registry +!********************************************************************************************************************************* +! IfW_FlowField_Types +!................................................................................................................................. +! This file is part of IfW_FlowField. +! +! Copyright (C) 2012-2016 National Renewable Energy Laboratory +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +! +! +! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. +! +!********************************************************************************************************************************* +!> This module contains the user-defined types needed in IfW_FlowField. It also contains copy, destroy, pack, and +!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. +MODULE IfW_FlowField_Types +!--------------------------------------------------------------------------------------------------------------------------------- +USE NWTC_Library +IMPLICIT NONE + INTEGER(IntKi), PUBLIC, PARAMETER :: Undef_FieldType = 0 ! This is the code for an undefined FieldType [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Uniform_FieldType = 1 ! Uniform FieldType from SteadyWind or Uniform Wind [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Grid3D_FieldType = 2 ! 3D Grid FieldType from TurbSim, Bladed, HAWC [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Grid4D_FieldType = 3 ! 4D Grid FieldType from FAST.Farm [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Point_FieldType = 4 ! Points FieldType from ExtInflow [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: User_FieldType = 5 ! User FieldType configured by the user [-] +! ========= UniformFieldType ======= + TYPE, PUBLIC :: UniformFieldType + REAL(ReKi) :: RefHeight !< reference height; used to center the wind [meters] + REAL(ReKi) :: RefLength !< reference length used to scale the linear shear [meters] + INTEGER(IntKi) :: DataSize !< size of data in HH file [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Time !< HH time array [seconds] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VelH !< HH horizontal wind speed [meters/sec] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VelHDot !< Derivative of HH horizontal wind speed wrt time [meters/sec] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VelV !< HH vertical wind speed, including tower shadow [meters/sec] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VelVDot !< Derivative of HH vertical wind speed wrt time [meters/sec] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VelGust !< HH wind gust speed [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VelGustDot !< Derivative of HH wind gust speed wrt time [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AngleH !< HH wind direction angle [degrees] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AngleHDot !< Derivative of HH wind direction angle wrt time [degrees] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AngleV !< HH upflow angle [degrees] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AngleVDot !< Derivative of HH upflow angle wrt time [degrees] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: ShrH !< HH horizontal linear shear [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: ShrHDot !< Derivative of HH horizontal linear shear wrt time [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: ShrV !< HH vertical shear exponent [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: ShrVDot !< Derivative of HH vertical shear exponent wrt time [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: LinShrV !< HH vertical linear shear [seconds] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: LinShrVDot !< Derivative of HH vertical linear shear wrt time [seconds] + END TYPE UniformFieldType +! ======================= +! ========= UniformField_Interp ======= + TYPE, PUBLIC :: UniformField_Interp + REAL(ReKi) :: VelH !< HH horizontal wind speed [meters/sec] + REAL(ReKi) :: VelHDot !< derivative of HH horizontal wind speed wrt Time [meters/sec] + REAL(ReKi) :: VelV !< HH vertical wind speed, including tower shadow [meters/sec] + REAL(ReKi) :: VelVDot !< derivative of HH vertical wind speed wrt Time [meters/sec] + REAL(ReKi) :: VelGust !< HH wind gust speed [-] + REAL(ReKi) :: VelGustDot !< derivative of HH wind gust speed wrt Time [-] + REAL(ReKi) :: AngleH !< HH wind direction angle [degrees] + REAL(ReKi) :: AngleHDot !< derivative of HH wind direction angle wrt Time [degrees] + REAL(ReKi) :: AngleV !< HH upflow angle [degrees] + REAL(ReKi) :: AngleVDot !< derivative of HH upflow angle wrt Time [degrees] + REAL(ReKi) :: ShrH !< HH horizontal linear shear [-] + REAL(ReKi) :: ShrHDot !< derivative of HH horizontal linear shear wrt Time [-] + REAL(ReKi) :: ShrV !< HH vertical shear exponent [-] + REAL(ReKi) :: ShrVDot !< derivative of HH vertical shear exponent wrt Time [-] + REAL(ReKi) :: LinShrV !< HH vertical linear shear [seconds] + REAL(ReKi) :: LinShrVDot !< derivative of HH vertical linear shear wrt Time [seconds] + REAL(ReKi) :: CosAngleH !< Horizontal angle components [-] + REAL(ReKi) :: SinAngleH !< Horizontal angle components [-] + REAL(ReKi) :: CosAngleV !< Vertical angle components [-] + REAL(ReKi) :: SinAngleV !< Vertical angle components [-] + END TYPE UniformField_Interp +! ======================= +! ========= Grid3DFieldType ======= + TYPE, PUBLIC :: Grid3DFieldType + INTEGER(IntKi) :: WindFileFormat !< Binary file format description number [-] + INTEGER(IntKi) :: WindProfileType = -1 !< Wind profile type (0=constant;1=logarithmic;2=power law) [-] + LOGICAL :: Periodic = .false. !< Flag to indicate if the wind file is periodic [-] + LOGICAL :: InterpTower = .false. !< Flag to indicate if we should interpolate wind speeds below the tower [-] + LOGICAL :: AddMeanAfterInterp = .false. !< Add the mean wind speed after interpolating at a given height? [-] + REAL(ReKi) :: RefHeight = 0 !< Reference (hub) height of the grid [meters] + REAL(ReKi) :: RefLength = 1.0_ReKi !< Reference (rotor) length of the grid (used for horizontal wind profile type only) [-] + REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vel !< Array of field velocities [-] + REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Acc !< Array of field accelerations [-] + REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: VelTower !< Array of tower velocities [-] + REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: AccTower !< Array of tower accelerations [-] + REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: VelAvg !< Average velocity profile by Z and time [-] + REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: AccAvg !< Average acceleration profile by Z and time [-] + REAL(ReKi) :: DTime = 0 !< Delta time [seconds] + REAL(ReKi) :: Rate = 0 !< Data rate (1/FFDTime) [Hertz] + REAL(ReKi) :: YHWid = 0 !< Half the grid width [meters] + REAL(ReKi) :: ZHWid = 0 !< Half the grid height [meters] + REAL(ReKi) :: GridBase = 0 !< the height of the bottom of the grid [meters] + REAL(ReKi) :: InitXPosition = 0 !< the initial x position of grid (distance in FF is offset) [meters] + REAL(ReKi) :: InvDY = 0 !< reciprocal of delta y [1/meters] + REAL(ReKi) :: InvDZ = 0 !< reciprocal of delta z [1/meters] + REAL(ReKi) :: MeanWS = 0 !< Mean wind speed (as defined in FF file), not necessarily of the portion used [meters/second] + REAL(ReKi) :: InvMWS = 0 !< reciprocal of mean wind speed (MeanFFWS) [seconds/meter] + REAL(ReKi) :: TotalTime = 0 !< The total time of the simulation [seconds] + INTEGER(IntKi) :: NComp = 3 !< Number of wind components [-] + INTEGER(IntKi) :: NYGrids = 0 !< Number of points in the lateral (y) direction of the grids [-] + INTEGER(IntKi) :: NZGrids = 0 !< Number of points in the vertical (z) direction of the grids [-] + INTEGER(IntKi) :: NTGrids = 0 !< Number of points in the vertical (z) direction on the tower (below the grids) [-] + INTEGER(IntKi) :: NSteps = 0 !< Number of time steps in the FF array [-] + REAL(ReKi) :: PLExp = 0 !< Power law exponent (used for PL wind profile type only) [-] + REAL(ReKi) :: Z0 = 0 !< Surface roughness length (used for LOG wind profile type only) [-] + REAL(ReKi) :: VLinShr = 0 !< Vertical linear wind shear coefficient (used for vertical linear wind profile type only) [-] + REAL(ReKi) :: HLinShr = 0 !< Horizontal linear wind shear coefficient (used for horizontal wind profile type only) [-] + LOGICAL :: BoxExceedAllowF = .FALSE. !< Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim) [-] + INTEGER(IntKi) :: BoxExceedAllowIdx = -1 !< Extrapolate winds outside box starting at this index (for OLAF wakes and LidarSim) [-] + LOGICAL :: BoxExceedWarned = .FALSE. !< Has a warning been issued for points extrapolated beyond FFWind grid [-] + END TYPE Grid3DFieldType +! ======================= +! ========= Grid4DFieldType ======= + TYPE, PUBLIC :: Grid4DFieldType + INTEGER(IntKi) , DIMENSION(1:4) :: n !< number of evenly-spaced grid points in the x, y, z, and t directions [-] + REAL(ReKi) , DIMENSION(1:4) :: delta !< size between 2 consecutive grid points in each grid direction [m,m,m,s] + REAL(ReKi) , DIMENSION(1:3) :: pZero !< fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:)) [m] + REAL(SiKi) , DIMENSION(:,:,:,:,:), ALLOCATABLE :: Vel !< this is the 4-d velocity field for each wind component [{uvw},nx,ny,nz,nt] [-] + REAL(ReKi) :: TimeStart !< this is the time where the first time grid in m%V starts (i.e, the time associated with m%V(:,:,:,:,1)) [s] + REAL(ReKi) :: RefHeight !< reference height; used to center the wind [meters] + END TYPE Grid4DFieldType +! ======================= +! ========= PointsFieldType ======= + TYPE, PUBLIC :: PointsFieldType + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vel !< Point velocities populated by external driver [uvw,point] [-] + END TYPE PointsFieldType +! ======================= +! ========= UserFieldType ======= + TYPE, PUBLIC :: UserFieldType + REAL(ReKi) :: RefHeight !< reference height; used to center the wind [meters] + END TYPE UserFieldType +! ======================= +! ========= FlowFieldType ======= + TYPE, PUBLIC :: FlowFieldType + INTEGER(IntKi) :: FieldType = 0 !< Switch for flow field type {1=Uniform, 2=Grid, 3=User, 4=External} [-] + REAL(ReKi) , DIMENSION(1:3) :: RefPosition !< Reference position (point where box is rotated) [meters] + REAL(ReKi) :: PropagationDir !< Direction of wind propagation [radians] + REAL(ReKi) :: VFlowAngle !< Vertical (upflow) angle [radians] + LOGICAL :: VelInterpCubic = .false. !< Velocity interpolation order in time (1=linear; 3=cubic) [Used with WindType=2,3,4,5,7] [-] + LOGICAL :: RotateWindBox = .false. !< flag indicating if the wind will be rotated [-] + LOGICAL :: AccFieldValid = .false. !< flag indicating that acceleration field has been calculated [-] + REAL(ReKi) , DIMENSION(1:3,1:3) :: RotToWind !< Rotation matrix for rotating from the global XYZ coordinate system to the wind coordinate system (wind along X') [-] + REAL(ReKi) , DIMENSION(1:3,1:3) :: RotFromWind !< Rotation matrix for rotating from the wind coordinate system (wind along X') back to the global XYZ coordinate system. Equal to TRANSPOSE(RotToWind) [-] + TYPE(UniformFieldType) :: Uniform !< Uniform Flow Data [-] + TYPE(Grid3DFieldType) :: Grid3D !< Grid Field Wind Data [-] + TYPE(Grid4DFieldType) :: Grid4D !< External Grid Flow Data [-] + TYPE(PointsFieldType) :: Points !< External Point Flow Data [-] + TYPE(UserFieldType) :: User !< User Field Wind Data [-] + END TYPE FlowFieldType +! ======================= +CONTAINS + SUBROUTINE IfW_FlowField_CopyUniformFieldType( SrcUniformFieldTypeData, DstUniformFieldTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(UniformFieldType), INTENT(IN) :: SrcUniformFieldTypeData + TYPE(UniformFieldType), INTENT(INOUT) :: DstUniformFieldTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyUniformFieldType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstUniformFieldTypeData%RefHeight = SrcUniformFieldTypeData%RefHeight + DstUniformFieldTypeData%RefLength = SrcUniformFieldTypeData%RefLength + DstUniformFieldTypeData%DataSize = SrcUniformFieldTypeData%DataSize +IF (ALLOCATED(SrcUniformFieldTypeData%Time)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%Time,1) + i1_u = UBOUND(SrcUniformFieldTypeData%Time,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%Time)) THEN + ALLOCATE(DstUniformFieldTypeData%Time(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%Time.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%Time = SrcUniformFieldTypeData%Time +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%VelH)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%VelH,1) + i1_u = UBOUND(SrcUniformFieldTypeData%VelH,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%VelH)) THEN + ALLOCATE(DstUniformFieldTypeData%VelH(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%VelH.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%VelH = SrcUniformFieldTypeData%VelH +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%VelHDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%VelHDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%VelHDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%VelHDot)) THEN + ALLOCATE(DstUniformFieldTypeData%VelHDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%VelHDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%VelHDot = SrcUniformFieldTypeData%VelHDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%VelV)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%VelV,1) + i1_u = UBOUND(SrcUniformFieldTypeData%VelV,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%VelV)) THEN + ALLOCATE(DstUniformFieldTypeData%VelV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%VelV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%VelV = SrcUniformFieldTypeData%VelV +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%VelVDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%VelVDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%VelVDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%VelVDot)) THEN + ALLOCATE(DstUniformFieldTypeData%VelVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%VelVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%VelVDot = SrcUniformFieldTypeData%VelVDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%VelGust)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%VelGust,1) + i1_u = UBOUND(SrcUniformFieldTypeData%VelGust,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%VelGust)) THEN + ALLOCATE(DstUniformFieldTypeData%VelGust(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%VelGust.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%VelGust = SrcUniformFieldTypeData%VelGust +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%VelGustDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%VelGustDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%VelGustDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%VelGustDot)) THEN + ALLOCATE(DstUniformFieldTypeData%VelGustDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%VelGustDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%VelGustDot = SrcUniformFieldTypeData%VelGustDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%AngleH)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%AngleH,1) + i1_u = UBOUND(SrcUniformFieldTypeData%AngleH,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%AngleH)) THEN + ALLOCATE(DstUniformFieldTypeData%AngleH(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%AngleH.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%AngleH = SrcUniformFieldTypeData%AngleH +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%AngleHDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%AngleHDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%AngleHDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%AngleHDot)) THEN + ALLOCATE(DstUniformFieldTypeData%AngleHDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%AngleHDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%AngleHDot = SrcUniformFieldTypeData%AngleHDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%AngleV)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%AngleV,1) + i1_u = UBOUND(SrcUniformFieldTypeData%AngleV,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%AngleV)) THEN + ALLOCATE(DstUniformFieldTypeData%AngleV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%AngleV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%AngleV = SrcUniformFieldTypeData%AngleV +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%AngleVDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%AngleVDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%AngleVDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%AngleVDot)) THEN + ALLOCATE(DstUniformFieldTypeData%AngleVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%AngleVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%AngleVDot = SrcUniformFieldTypeData%AngleVDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%ShrH)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%ShrH,1) + i1_u = UBOUND(SrcUniformFieldTypeData%ShrH,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%ShrH)) THEN + ALLOCATE(DstUniformFieldTypeData%ShrH(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%ShrH.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%ShrH = SrcUniformFieldTypeData%ShrH +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%ShrHDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%ShrHDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%ShrHDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%ShrHDot)) THEN + ALLOCATE(DstUniformFieldTypeData%ShrHDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%ShrHDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%ShrHDot = SrcUniformFieldTypeData%ShrHDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%ShrV)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%ShrV,1) + i1_u = UBOUND(SrcUniformFieldTypeData%ShrV,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%ShrV)) THEN + ALLOCATE(DstUniformFieldTypeData%ShrV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%ShrV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%ShrV = SrcUniformFieldTypeData%ShrV +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%ShrVDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%ShrVDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%ShrVDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%ShrVDot)) THEN + ALLOCATE(DstUniformFieldTypeData%ShrVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%ShrVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%ShrVDot = SrcUniformFieldTypeData%ShrVDot +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%LinShrV)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%LinShrV,1) + i1_u = UBOUND(SrcUniformFieldTypeData%LinShrV,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%LinShrV)) THEN + ALLOCATE(DstUniformFieldTypeData%LinShrV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%LinShrV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%LinShrV = SrcUniformFieldTypeData%LinShrV +ENDIF +IF (ALLOCATED(SrcUniformFieldTypeData%LinShrVDot)) THEN + i1_l = LBOUND(SrcUniformFieldTypeData%LinShrVDot,1) + i1_u = UBOUND(SrcUniformFieldTypeData%LinShrVDot,1) + IF (.NOT. ALLOCATED(DstUniformFieldTypeData%LinShrVDot)) THEN + ALLOCATE(DstUniformFieldTypeData%LinShrVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstUniformFieldTypeData%LinShrVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstUniformFieldTypeData%LinShrVDot = SrcUniformFieldTypeData%LinShrVDot +ENDIF + END SUBROUTINE IfW_FlowField_CopyUniformFieldType + + SUBROUTINE IfW_FlowField_DestroyUniformFieldType( UniformFieldTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(UniformFieldType), INTENT(INOUT) :: UniformFieldTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyUniformFieldType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(UniformFieldTypeData%Time)) THEN + DEALLOCATE(UniformFieldTypeData%Time) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%VelH)) THEN + DEALLOCATE(UniformFieldTypeData%VelH) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%VelHDot)) THEN + DEALLOCATE(UniformFieldTypeData%VelHDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%VelV)) THEN + DEALLOCATE(UniformFieldTypeData%VelV) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%VelVDot)) THEN + DEALLOCATE(UniformFieldTypeData%VelVDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%VelGust)) THEN + DEALLOCATE(UniformFieldTypeData%VelGust) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%VelGustDot)) THEN + DEALLOCATE(UniformFieldTypeData%VelGustDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%AngleH)) THEN + DEALLOCATE(UniformFieldTypeData%AngleH) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%AngleHDot)) THEN + DEALLOCATE(UniformFieldTypeData%AngleHDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%AngleV)) THEN + DEALLOCATE(UniformFieldTypeData%AngleV) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%AngleVDot)) THEN + DEALLOCATE(UniformFieldTypeData%AngleVDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%ShrH)) THEN + DEALLOCATE(UniformFieldTypeData%ShrH) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%ShrHDot)) THEN + DEALLOCATE(UniformFieldTypeData%ShrHDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%ShrV)) THEN + DEALLOCATE(UniformFieldTypeData%ShrV) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%ShrVDot)) THEN + DEALLOCATE(UniformFieldTypeData%ShrVDot) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%LinShrV)) THEN + DEALLOCATE(UniformFieldTypeData%LinShrV) +ENDIF +IF (ALLOCATED(UniformFieldTypeData%LinShrVDot)) THEN + DEALLOCATE(UniformFieldTypeData%LinShrVDot) +ENDIF + END SUBROUTINE IfW_FlowField_DestroyUniformFieldType + + SUBROUTINE IfW_FlowField_PackUniformFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(UniformFieldType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackUniformFieldType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! RefHeight + Re_BufSz = Re_BufSz + 1 ! RefLength + Int_BufSz = Int_BufSz + 1 ! DataSize + Int_BufSz = Int_BufSz + 1 ! Time allocated yes/no + IF ( ALLOCATED(InData%Time) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Time upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Time) ! Time + END IF + Int_BufSz = Int_BufSz + 1 ! VelH allocated yes/no + IF ( ALLOCATED(InData%VelH) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VelH upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelH) ! VelH + END IF + Int_BufSz = Int_BufSz + 1 ! VelHDot allocated yes/no + IF ( ALLOCATED(InData%VelHDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VelHDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelHDot) ! VelHDot + END IF + Int_BufSz = Int_BufSz + 1 ! VelV allocated yes/no + IF ( ALLOCATED(InData%VelV) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VelV upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelV) ! VelV + END IF + Int_BufSz = Int_BufSz + 1 ! VelVDot allocated yes/no + IF ( ALLOCATED(InData%VelVDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VelVDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelVDot) ! VelVDot + END IF + Int_BufSz = Int_BufSz + 1 ! VelGust allocated yes/no + IF ( ALLOCATED(InData%VelGust) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VelGust upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelGust) ! VelGust + END IF + Int_BufSz = Int_BufSz + 1 ! VelGustDot allocated yes/no + IF ( ALLOCATED(InData%VelGustDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! VelGustDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelGustDot) ! VelGustDot + END IF + Int_BufSz = Int_BufSz + 1 ! AngleH allocated yes/no + IF ( ALLOCATED(InData%AngleH) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AngleH upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AngleH) ! AngleH + END IF + Int_BufSz = Int_BufSz + 1 ! AngleHDot allocated yes/no + IF ( ALLOCATED(InData%AngleHDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AngleHDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AngleHDot) ! AngleHDot + END IF + Int_BufSz = Int_BufSz + 1 ! AngleV allocated yes/no + IF ( ALLOCATED(InData%AngleV) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AngleV upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AngleV) ! AngleV + END IF + Int_BufSz = Int_BufSz + 1 ! AngleVDot allocated yes/no + IF ( ALLOCATED(InData%AngleVDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AngleVDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AngleVDot) ! AngleVDot + END IF + Int_BufSz = Int_BufSz + 1 ! ShrH allocated yes/no + IF ( ALLOCATED(InData%ShrH) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ShrH upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%ShrH) ! ShrH + END IF + Int_BufSz = Int_BufSz + 1 ! ShrHDot allocated yes/no + IF ( ALLOCATED(InData%ShrHDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ShrHDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%ShrHDot) ! ShrHDot + END IF + Int_BufSz = Int_BufSz + 1 ! ShrV allocated yes/no + IF ( ALLOCATED(InData%ShrV) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ShrV upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%ShrV) ! ShrV + END IF + Int_BufSz = Int_BufSz + 1 ! ShrVDot allocated yes/no + IF ( ALLOCATED(InData%ShrVDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ShrVDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%ShrVDot) ! ShrVDot + END IF + Int_BufSz = Int_BufSz + 1 ! LinShrV allocated yes/no + IF ( ALLOCATED(InData%LinShrV) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LinShrV upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%LinShrV) ! LinShrV + END IF + Int_BufSz = Int_BufSz + 1 ! LinShrVDot allocated yes/no + IF ( ALLOCATED(InData%LinShrVDot) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LinShrVDot upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%LinShrVDot) ! LinShrVDot + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%RefHeight + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefLength + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%DataSize + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%Time) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Time,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Time,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Time,1), UBOUND(InData%Time,1) + ReKiBuf(Re_Xferred) = InData%Time(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelH) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelH,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelH,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%VelH,1), UBOUND(InData%VelH,1) + ReKiBuf(Re_Xferred) = InData%VelH(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelHDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelHDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelHDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%VelHDot,1), UBOUND(InData%VelHDot,1) + ReKiBuf(Re_Xferred) = InData%VelHDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelV) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelV,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelV,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%VelV,1), UBOUND(InData%VelV,1) + ReKiBuf(Re_Xferred) = InData%VelV(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelVDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelVDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelVDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%VelVDot,1), UBOUND(InData%VelVDot,1) + ReKiBuf(Re_Xferred) = InData%VelVDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelGust) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelGust,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelGust,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%VelGust,1), UBOUND(InData%VelGust,1) + ReKiBuf(Re_Xferred) = InData%VelGust(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelGustDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelGustDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelGustDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%VelGustDot,1), UBOUND(InData%VelGustDot,1) + ReKiBuf(Re_Xferred) = InData%VelGustDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AngleH) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AngleH,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AngleH,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AngleH,1), UBOUND(InData%AngleH,1) + ReKiBuf(Re_Xferred) = InData%AngleH(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AngleHDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AngleHDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AngleHDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AngleHDot,1), UBOUND(InData%AngleHDot,1) + ReKiBuf(Re_Xferred) = InData%AngleHDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AngleV) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AngleV,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AngleV,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AngleV,1), UBOUND(InData%AngleV,1) + ReKiBuf(Re_Xferred) = InData%AngleV(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AngleVDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AngleVDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AngleVDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AngleVDot,1), UBOUND(InData%AngleVDot,1) + ReKiBuf(Re_Xferred) = InData%AngleVDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ShrH) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ShrH,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ShrH,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ShrH,1), UBOUND(InData%ShrH,1) + ReKiBuf(Re_Xferred) = InData%ShrH(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ShrHDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ShrHDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ShrHDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ShrHDot,1), UBOUND(InData%ShrHDot,1) + ReKiBuf(Re_Xferred) = InData%ShrHDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ShrV) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ShrV,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ShrV,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ShrV,1), UBOUND(InData%ShrV,1) + ReKiBuf(Re_Xferred) = InData%ShrV(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ShrVDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ShrVDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ShrVDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ShrVDot,1), UBOUND(InData%ShrVDot,1) + ReKiBuf(Re_Xferred) = InData%ShrVDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%LinShrV) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LinShrV,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LinShrV,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LinShrV,1), UBOUND(InData%LinShrV,1) + ReKiBuf(Re_Xferred) = InData%LinShrV(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%LinShrVDot) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LinShrVDot,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LinShrVDot,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LinShrVDot,1), UBOUND(InData%LinShrVDot,1) + ReKiBuf(Re_Xferred) = InData%LinShrVDot(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + END SUBROUTINE IfW_FlowField_PackUniformFieldType + + SUBROUTINE IfW_FlowField_UnPackUniformFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(UniformFieldType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackUniformFieldType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%RefHeight = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefLength = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%DataSize = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Time not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Time)) DEALLOCATE(OutData%Time) + ALLOCATE(OutData%Time(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Time.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Time,1), UBOUND(OutData%Time,1) + OutData%Time(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelH not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelH)) DEALLOCATE(OutData%VelH) + ALLOCATE(OutData%VelH(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelH.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%VelH,1), UBOUND(OutData%VelH,1) + OutData%VelH(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelHDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelHDot)) DEALLOCATE(OutData%VelHDot) + ALLOCATE(OutData%VelHDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelHDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%VelHDot,1), UBOUND(OutData%VelHDot,1) + OutData%VelHDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelV not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelV)) DEALLOCATE(OutData%VelV) + ALLOCATE(OutData%VelV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%VelV,1), UBOUND(OutData%VelV,1) + OutData%VelV(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelVDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelVDot)) DEALLOCATE(OutData%VelVDot) + ALLOCATE(OutData%VelVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%VelVDot,1), UBOUND(OutData%VelVDot,1) + OutData%VelVDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelGust not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelGust)) DEALLOCATE(OutData%VelGust) + ALLOCATE(OutData%VelGust(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelGust.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%VelGust,1), UBOUND(OutData%VelGust,1) + OutData%VelGust(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelGustDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelGustDot)) DEALLOCATE(OutData%VelGustDot) + ALLOCATE(OutData%VelGustDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelGustDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%VelGustDot,1), UBOUND(OutData%VelGustDot,1) + OutData%VelGustDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AngleH not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AngleH)) DEALLOCATE(OutData%AngleH) + ALLOCATE(OutData%AngleH(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AngleH.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AngleH,1), UBOUND(OutData%AngleH,1) + OutData%AngleH(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AngleHDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AngleHDot)) DEALLOCATE(OutData%AngleHDot) + ALLOCATE(OutData%AngleHDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AngleHDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AngleHDot,1), UBOUND(OutData%AngleHDot,1) + OutData%AngleHDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AngleV not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AngleV)) DEALLOCATE(OutData%AngleV) + ALLOCATE(OutData%AngleV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AngleV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AngleV,1), UBOUND(OutData%AngleV,1) + OutData%AngleV(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AngleVDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AngleVDot)) DEALLOCATE(OutData%AngleVDot) + ALLOCATE(OutData%AngleVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AngleVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AngleVDot,1), UBOUND(OutData%AngleVDot,1) + OutData%AngleVDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ShrH not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ShrH)) DEALLOCATE(OutData%ShrH) + ALLOCATE(OutData%ShrH(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ShrH.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ShrH,1), UBOUND(OutData%ShrH,1) + OutData%ShrH(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ShrHDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ShrHDot)) DEALLOCATE(OutData%ShrHDot) + ALLOCATE(OutData%ShrHDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ShrHDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ShrHDot,1), UBOUND(OutData%ShrHDot,1) + OutData%ShrHDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ShrV not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ShrV)) DEALLOCATE(OutData%ShrV) + ALLOCATE(OutData%ShrV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ShrV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ShrV,1), UBOUND(OutData%ShrV,1) + OutData%ShrV(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ShrVDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ShrVDot)) DEALLOCATE(OutData%ShrVDot) + ALLOCATE(OutData%ShrVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ShrVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ShrVDot,1), UBOUND(OutData%ShrVDot,1) + OutData%ShrVDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LinShrV not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LinShrV)) DEALLOCATE(OutData%LinShrV) + ALLOCATE(OutData%LinShrV(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LinShrV.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LinShrV,1), UBOUND(OutData%LinShrV,1) + OutData%LinShrV(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LinShrVDot not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LinShrVDot)) DEALLOCATE(OutData%LinShrVDot) + ALLOCATE(OutData%LinShrVDot(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LinShrVDot.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LinShrVDot,1), UBOUND(OutData%LinShrVDot,1) + OutData%LinShrVDot(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + END SUBROUTINE IfW_FlowField_UnPackUniformFieldType + + SUBROUTINE IfW_FlowField_CopyUniformField_Interp( SrcUniformField_InterpData, DstUniformField_InterpData, CtrlCode, ErrStat, ErrMsg ) + TYPE(UniformField_Interp), INTENT(IN) :: SrcUniformField_InterpData + TYPE(UniformField_Interp), INTENT(INOUT) :: DstUniformField_InterpData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyUniformField_Interp' +! + ErrStat = ErrID_None + ErrMsg = "" + DstUniformField_InterpData%VelH = SrcUniformField_InterpData%VelH + DstUniformField_InterpData%VelHDot = SrcUniformField_InterpData%VelHDot + DstUniformField_InterpData%VelV = SrcUniformField_InterpData%VelV + DstUniformField_InterpData%VelVDot = SrcUniformField_InterpData%VelVDot + DstUniformField_InterpData%VelGust = SrcUniformField_InterpData%VelGust + DstUniformField_InterpData%VelGustDot = SrcUniformField_InterpData%VelGustDot + DstUniformField_InterpData%AngleH = SrcUniformField_InterpData%AngleH + DstUniformField_InterpData%AngleHDot = SrcUniformField_InterpData%AngleHDot + DstUniformField_InterpData%AngleV = SrcUniformField_InterpData%AngleV + DstUniformField_InterpData%AngleVDot = SrcUniformField_InterpData%AngleVDot + DstUniformField_InterpData%ShrH = SrcUniformField_InterpData%ShrH + DstUniformField_InterpData%ShrHDot = SrcUniformField_InterpData%ShrHDot + DstUniformField_InterpData%ShrV = SrcUniformField_InterpData%ShrV + DstUniformField_InterpData%ShrVDot = SrcUniformField_InterpData%ShrVDot + DstUniformField_InterpData%LinShrV = SrcUniformField_InterpData%LinShrV + DstUniformField_InterpData%LinShrVDot = SrcUniformField_InterpData%LinShrVDot + DstUniformField_InterpData%CosAngleH = SrcUniformField_InterpData%CosAngleH + DstUniformField_InterpData%SinAngleH = SrcUniformField_InterpData%SinAngleH + DstUniformField_InterpData%CosAngleV = SrcUniformField_InterpData%CosAngleV + DstUniformField_InterpData%SinAngleV = SrcUniformField_InterpData%SinAngleV + END SUBROUTINE IfW_FlowField_CopyUniformField_Interp + + SUBROUTINE IfW_FlowField_DestroyUniformField_Interp( UniformField_InterpData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(UniformField_Interp), INTENT(INOUT) :: UniformField_InterpData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyUniformField_Interp' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE IfW_FlowField_DestroyUniformField_Interp + + SUBROUTINE IfW_FlowField_PackUniformField_Interp( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(UniformField_Interp), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackUniformField_Interp' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! VelH + Re_BufSz = Re_BufSz + 1 ! VelHDot + Re_BufSz = Re_BufSz + 1 ! VelV + Re_BufSz = Re_BufSz + 1 ! VelVDot + Re_BufSz = Re_BufSz + 1 ! VelGust + Re_BufSz = Re_BufSz + 1 ! VelGustDot + Re_BufSz = Re_BufSz + 1 ! AngleH + Re_BufSz = Re_BufSz + 1 ! AngleHDot + Re_BufSz = Re_BufSz + 1 ! AngleV + Re_BufSz = Re_BufSz + 1 ! AngleVDot + Re_BufSz = Re_BufSz + 1 ! ShrH + Re_BufSz = Re_BufSz + 1 ! ShrHDot + Re_BufSz = Re_BufSz + 1 ! ShrV + Re_BufSz = Re_BufSz + 1 ! ShrVDot + Re_BufSz = Re_BufSz + 1 ! LinShrV + Re_BufSz = Re_BufSz + 1 ! LinShrVDot + Re_BufSz = Re_BufSz + 1 ! CosAngleH + Re_BufSz = Re_BufSz + 1 ! SinAngleH + Re_BufSz = Re_BufSz + 1 ! CosAngleV + Re_BufSz = Re_BufSz + 1 ! SinAngleV + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%VelH + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VelHDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VelV + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VelVDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VelGust + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VelGustDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%AngleH + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%AngleHDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%AngleV + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%AngleVDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%ShrH + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%ShrHDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%ShrV + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%ShrVDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%LinShrV + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%LinShrVDot + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%CosAngleH + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%SinAngleH + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%CosAngleV + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%SinAngleV + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE IfW_FlowField_PackUniformField_Interp + + SUBROUTINE IfW_FlowField_UnPackUniformField_Interp( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(UniformField_Interp), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackUniformField_Interp' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%VelH = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VelHDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VelV = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VelVDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VelGust = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VelGustDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%AngleH = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%AngleHDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%AngleV = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%AngleVDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%ShrH = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%ShrHDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%ShrV = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%ShrVDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%LinShrV = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%LinShrVDot = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%CosAngleH = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%SinAngleH = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%CosAngleV = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%SinAngleV = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE IfW_FlowField_UnPackUniformField_Interp + + SUBROUTINE IfW_FlowField_CopyGrid3DFieldType( SrcGrid3DFieldTypeData, DstGrid3DFieldTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Grid3DFieldType), INTENT(IN) :: SrcGrid3DFieldTypeData + TYPE(Grid3DFieldType), INTENT(INOUT) :: DstGrid3DFieldTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyGrid3DFieldType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstGrid3DFieldTypeData%WindFileFormat = SrcGrid3DFieldTypeData%WindFileFormat + DstGrid3DFieldTypeData%WindProfileType = SrcGrid3DFieldTypeData%WindProfileType + DstGrid3DFieldTypeData%Periodic = SrcGrid3DFieldTypeData%Periodic + DstGrid3DFieldTypeData%InterpTower = SrcGrid3DFieldTypeData%InterpTower + DstGrid3DFieldTypeData%AddMeanAfterInterp = SrcGrid3DFieldTypeData%AddMeanAfterInterp + DstGrid3DFieldTypeData%RefHeight = SrcGrid3DFieldTypeData%RefHeight + DstGrid3DFieldTypeData%RefLength = SrcGrid3DFieldTypeData%RefLength +IF (ALLOCATED(SrcGrid3DFieldTypeData%Vel)) THEN + i1_l = LBOUND(SrcGrid3DFieldTypeData%Vel,1) + i1_u = UBOUND(SrcGrid3DFieldTypeData%Vel,1) + i2_l = LBOUND(SrcGrid3DFieldTypeData%Vel,2) + i2_u = UBOUND(SrcGrid3DFieldTypeData%Vel,2) + i3_l = LBOUND(SrcGrid3DFieldTypeData%Vel,3) + i3_u = UBOUND(SrcGrid3DFieldTypeData%Vel,3) + i4_l = LBOUND(SrcGrid3DFieldTypeData%Vel,4) + i4_u = UBOUND(SrcGrid3DFieldTypeData%Vel,4) + IF (.NOT. ALLOCATED(DstGrid3DFieldTypeData%Vel)) THEN + ALLOCATE(DstGrid3DFieldTypeData%Vel(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid3DFieldTypeData%Vel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid3DFieldTypeData%Vel = SrcGrid3DFieldTypeData%Vel +ENDIF +IF (ALLOCATED(SrcGrid3DFieldTypeData%Acc)) THEN + i1_l = LBOUND(SrcGrid3DFieldTypeData%Acc,1) + i1_u = UBOUND(SrcGrid3DFieldTypeData%Acc,1) + i2_l = LBOUND(SrcGrid3DFieldTypeData%Acc,2) + i2_u = UBOUND(SrcGrid3DFieldTypeData%Acc,2) + i3_l = LBOUND(SrcGrid3DFieldTypeData%Acc,3) + i3_u = UBOUND(SrcGrid3DFieldTypeData%Acc,3) + i4_l = LBOUND(SrcGrid3DFieldTypeData%Acc,4) + i4_u = UBOUND(SrcGrid3DFieldTypeData%Acc,4) + IF (.NOT. ALLOCATED(DstGrid3DFieldTypeData%Acc)) THEN + ALLOCATE(DstGrid3DFieldTypeData%Acc(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid3DFieldTypeData%Acc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid3DFieldTypeData%Acc = SrcGrid3DFieldTypeData%Acc +ENDIF +IF (ALLOCATED(SrcGrid3DFieldTypeData%VelTower)) THEN + i1_l = LBOUND(SrcGrid3DFieldTypeData%VelTower,1) + i1_u = UBOUND(SrcGrid3DFieldTypeData%VelTower,1) + i2_l = LBOUND(SrcGrid3DFieldTypeData%VelTower,2) + i2_u = UBOUND(SrcGrid3DFieldTypeData%VelTower,2) + i3_l = LBOUND(SrcGrid3DFieldTypeData%VelTower,3) + i3_u = UBOUND(SrcGrid3DFieldTypeData%VelTower,3) + IF (.NOT. ALLOCATED(DstGrid3DFieldTypeData%VelTower)) THEN + ALLOCATE(DstGrid3DFieldTypeData%VelTower(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid3DFieldTypeData%VelTower.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid3DFieldTypeData%VelTower = SrcGrid3DFieldTypeData%VelTower +ENDIF +IF (ALLOCATED(SrcGrid3DFieldTypeData%AccTower)) THEN + i1_l = LBOUND(SrcGrid3DFieldTypeData%AccTower,1) + i1_u = UBOUND(SrcGrid3DFieldTypeData%AccTower,1) + i2_l = LBOUND(SrcGrid3DFieldTypeData%AccTower,2) + i2_u = UBOUND(SrcGrid3DFieldTypeData%AccTower,2) + i3_l = LBOUND(SrcGrid3DFieldTypeData%AccTower,3) + i3_u = UBOUND(SrcGrid3DFieldTypeData%AccTower,3) + IF (.NOT. ALLOCATED(DstGrid3DFieldTypeData%AccTower)) THEN + ALLOCATE(DstGrid3DFieldTypeData%AccTower(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid3DFieldTypeData%AccTower.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid3DFieldTypeData%AccTower = SrcGrid3DFieldTypeData%AccTower +ENDIF +IF (ALLOCATED(SrcGrid3DFieldTypeData%VelAvg)) THEN + i1_l = LBOUND(SrcGrid3DFieldTypeData%VelAvg,1) + i1_u = UBOUND(SrcGrid3DFieldTypeData%VelAvg,1) + i2_l = LBOUND(SrcGrid3DFieldTypeData%VelAvg,2) + i2_u = UBOUND(SrcGrid3DFieldTypeData%VelAvg,2) + i3_l = LBOUND(SrcGrid3DFieldTypeData%VelAvg,3) + i3_u = UBOUND(SrcGrid3DFieldTypeData%VelAvg,3) + IF (.NOT. ALLOCATED(DstGrid3DFieldTypeData%VelAvg)) THEN + ALLOCATE(DstGrid3DFieldTypeData%VelAvg(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid3DFieldTypeData%VelAvg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid3DFieldTypeData%VelAvg = SrcGrid3DFieldTypeData%VelAvg +ENDIF +IF (ALLOCATED(SrcGrid3DFieldTypeData%AccAvg)) THEN + i1_l = LBOUND(SrcGrid3DFieldTypeData%AccAvg,1) + i1_u = UBOUND(SrcGrid3DFieldTypeData%AccAvg,1) + i2_l = LBOUND(SrcGrid3DFieldTypeData%AccAvg,2) + i2_u = UBOUND(SrcGrid3DFieldTypeData%AccAvg,2) + i3_l = LBOUND(SrcGrid3DFieldTypeData%AccAvg,3) + i3_u = UBOUND(SrcGrid3DFieldTypeData%AccAvg,3) + IF (.NOT. ALLOCATED(DstGrid3DFieldTypeData%AccAvg)) THEN + ALLOCATE(DstGrid3DFieldTypeData%AccAvg(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid3DFieldTypeData%AccAvg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid3DFieldTypeData%AccAvg = SrcGrid3DFieldTypeData%AccAvg +ENDIF + DstGrid3DFieldTypeData%DTime = SrcGrid3DFieldTypeData%DTime + DstGrid3DFieldTypeData%Rate = SrcGrid3DFieldTypeData%Rate + DstGrid3DFieldTypeData%YHWid = SrcGrid3DFieldTypeData%YHWid + DstGrid3DFieldTypeData%ZHWid = SrcGrid3DFieldTypeData%ZHWid + DstGrid3DFieldTypeData%GridBase = SrcGrid3DFieldTypeData%GridBase + DstGrid3DFieldTypeData%InitXPosition = SrcGrid3DFieldTypeData%InitXPosition + DstGrid3DFieldTypeData%InvDY = SrcGrid3DFieldTypeData%InvDY + DstGrid3DFieldTypeData%InvDZ = SrcGrid3DFieldTypeData%InvDZ + DstGrid3DFieldTypeData%MeanWS = SrcGrid3DFieldTypeData%MeanWS + DstGrid3DFieldTypeData%InvMWS = SrcGrid3DFieldTypeData%InvMWS + DstGrid3DFieldTypeData%TotalTime = SrcGrid3DFieldTypeData%TotalTime + DstGrid3DFieldTypeData%NComp = SrcGrid3DFieldTypeData%NComp + DstGrid3DFieldTypeData%NYGrids = SrcGrid3DFieldTypeData%NYGrids + DstGrid3DFieldTypeData%NZGrids = SrcGrid3DFieldTypeData%NZGrids + DstGrid3DFieldTypeData%NTGrids = SrcGrid3DFieldTypeData%NTGrids + DstGrid3DFieldTypeData%NSteps = SrcGrid3DFieldTypeData%NSteps + DstGrid3DFieldTypeData%PLExp = SrcGrid3DFieldTypeData%PLExp + DstGrid3DFieldTypeData%Z0 = SrcGrid3DFieldTypeData%Z0 + DstGrid3DFieldTypeData%VLinShr = SrcGrid3DFieldTypeData%VLinShr + DstGrid3DFieldTypeData%HLinShr = SrcGrid3DFieldTypeData%HLinShr + DstGrid3DFieldTypeData%BoxExceedAllowF = SrcGrid3DFieldTypeData%BoxExceedAllowF + DstGrid3DFieldTypeData%BoxExceedAllowIdx = SrcGrid3DFieldTypeData%BoxExceedAllowIdx + DstGrid3DFieldTypeData%BoxExceedWarned = SrcGrid3DFieldTypeData%BoxExceedWarned + END SUBROUTINE IfW_FlowField_CopyGrid3DFieldType + + SUBROUTINE IfW_FlowField_DestroyGrid3DFieldType( Grid3DFieldTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Grid3DFieldType), INTENT(INOUT) :: Grid3DFieldTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyGrid3DFieldType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(Grid3DFieldTypeData%Vel)) THEN + DEALLOCATE(Grid3DFieldTypeData%Vel) +ENDIF +IF (ALLOCATED(Grid3DFieldTypeData%Acc)) THEN + DEALLOCATE(Grid3DFieldTypeData%Acc) +ENDIF +IF (ALLOCATED(Grid3DFieldTypeData%VelTower)) THEN + DEALLOCATE(Grid3DFieldTypeData%VelTower) +ENDIF +IF (ALLOCATED(Grid3DFieldTypeData%AccTower)) THEN + DEALLOCATE(Grid3DFieldTypeData%AccTower) +ENDIF +IF (ALLOCATED(Grid3DFieldTypeData%VelAvg)) THEN + DEALLOCATE(Grid3DFieldTypeData%VelAvg) +ENDIF +IF (ALLOCATED(Grid3DFieldTypeData%AccAvg)) THEN + DEALLOCATE(Grid3DFieldTypeData%AccAvg) +ENDIF + END SUBROUTINE IfW_FlowField_DestroyGrid3DFieldType + + SUBROUTINE IfW_FlowField_PackGrid3DFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Grid3DFieldType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackGrid3DFieldType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! WindFileFormat + Int_BufSz = Int_BufSz + 1 ! WindProfileType + Int_BufSz = Int_BufSz + 1 ! Periodic + Int_BufSz = Int_BufSz + 1 ! InterpTower + Int_BufSz = Int_BufSz + 1 ! AddMeanAfterInterp + Re_BufSz = Re_BufSz + 1 ! RefHeight + Re_BufSz = Re_BufSz + 1 ! RefLength + Int_BufSz = Int_BufSz + 1 ! Vel allocated yes/no + IF ( ALLOCATED(InData%Vel) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! Vel upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vel) ! Vel + END IF + Int_BufSz = Int_BufSz + 1 ! Acc allocated yes/no + IF ( ALLOCATED(InData%Acc) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! Acc upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Acc) ! Acc + END IF + Int_BufSz = Int_BufSz + 1 ! VelTower allocated yes/no + IF ( ALLOCATED(InData%VelTower) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! VelTower upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelTower) ! VelTower + END IF + Int_BufSz = Int_BufSz + 1 ! AccTower allocated yes/no + IF ( ALLOCATED(InData%AccTower) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! AccTower upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AccTower) ! AccTower + END IF + Int_BufSz = Int_BufSz + 1 ! VelAvg allocated yes/no + IF ( ALLOCATED(InData%VelAvg) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! VelAvg upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelAvg) ! VelAvg + END IF + Int_BufSz = Int_BufSz + 1 ! AccAvg allocated yes/no + IF ( ALLOCATED(InData%AccAvg) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! AccAvg upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AccAvg) ! AccAvg + END IF + Re_BufSz = Re_BufSz + 1 ! DTime + Re_BufSz = Re_BufSz + 1 ! Rate + Re_BufSz = Re_BufSz + 1 ! YHWid + Re_BufSz = Re_BufSz + 1 ! ZHWid + Re_BufSz = Re_BufSz + 1 ! GridBase + Re_BufSz = Re_BufSz + 1 ! InitXPosition + Re_BufSz = Re_BufSz + 1 ! InvDY + Re_BufSz = Re_BufSz + 1 ! InvDZ + Re_BufSz = Re_BufSz + 1 ! MeanWS + Re_BufSz = Re_BufSz + 1 ! InvMWS + Re_BufSz = Re_BufSz + 1 ! TotalTime + Int_BufSz = Int_BufSz + 1 ! NComp + Int_BufSz = Int_BufSz + 1 ! NYGrids + Int_BufSz = Int_BufSz + 1 ! NZGrids + Int_BufSz = Int_BufSz + 1 ! NTGrids + Int_BufSz = Int_BufSz + 1 ! NSteps + Re_BufSz = Re_BufSz + 1 ! PLExp + Re_BufSz = Re_BufSz + 1 ! Z0 + Re_BufSz = Re_BufSz + 1 ! VLinShr + Re_BufSz = Re_BufSz + 1 ! HLinShr + Int_BufSz = Int_BufSz + 1 ! BoxExceedAllowF + Int_BufSz = Int_BufSz + 1 ! BoxExceedAllowIdx + Int_BufSz = Int_BufSz + 1 ! BoxExceedWarned + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IntKiBuf(Int_Xferred) = InData%WindFileFormat + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%WindProfileType + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%Periodic, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%InterpTower, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%AddMeanAfterInterp, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefHeight + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefLength + Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%Vel) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%Vel,4), UBOUND(InData%Vel,4) + DO i3 = LBOUND(InData%Vel,3), UBOUND(InData%Vel,3) + DO i2 = LBOUND(InData%Vel,2), UBOUND(InData%Vel,2) + DO i1 = LBOUND(InData%Vel,1), UBOUND(InData%Vel,1) + ReKiBuf(Re_Xferred) = InData%Vel(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Acc) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Acc,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Acc,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Acc,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Acc,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Acc,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Acc,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Acc,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Acc,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%Acc,4), UBOUND(InData%Acc,4) + DO i3 = LBOUND(InData%Acc,3), UBOUND(InData%Acc,3) + DO i2 = LBOUND(InData%Acc,2), UBOUND(InData%Acc,2) + DO i1 = LBOUND(InData%Acc,1), UBOUND(InData%Acc,1) + ReKiBuf(Re_Xferred) = InData%Acc(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelTower) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelTower,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelTower,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelTower,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelTower,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelTower,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelTower,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%VelTower,3), UBOUND(InData%VelTower,3) + DO i2 = LBOUND(InData%VelTower,2), UBOUND(InData%VelTower,2) + DO i1 = LBOUND(InData%VelTower,1), UBOUND(InData%VelTower,1) + ReKiBuf(Re_Xferred) = InData%VelTower(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AccTower) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccTower,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccTower,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccTower,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccTower,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccTower,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccTower,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%AccTower,3), UBOUND(InData%AccTower,3) + DO i2 = LBOUND(InData%AccTower,2), UBOUND(InData%AccTower,2) + DO i1 = LBOUND(InData%AccTower,1), UBOUND(InData%AccTower,1) + ReKiBuf(Re_Xferred) = InData%AccTower(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%VelAvg) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelAvg,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelAvg,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelAvg,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelAvg,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelAvg,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelAvg,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%VelAvg,3), UBOUND(InData%VelAvg,3) + DO i2 = LBOUND(InData%VelAvg,2), UBOUND(InData%VelAvg,2) + DO i1 = LBOUND(InData%VelAvg,1), UBOUND(InData%VelAvg,1) + ReKiBuf(Re_Xferred) = InData%VelAvg(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%AccAvg) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccAvg,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccAvg,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccAvg,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccAvg,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccAvg,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccAvg,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%AccAvg,3), UBOUND(InData%AccAvg,3) + DO i2 = LBOUND(InData%AccAvg,2), UBOUND(InData%AccAvg,2) + DO i1 = LBOUND(InData%AccAvg,1), UBOUND(InData%AccAvg,1) + ReKiBuf(Re_Xferred) = InData%AccAvg(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + ReKiBuf(Re_Xferred) = InData%DTime + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Rate + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%YHWid + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%ZHWid + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%GridBase + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%InitXPosition + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%InvDY + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%InvDZ + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MeanWS + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%InvMWS + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%TotalTime + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NComp + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NYGrids + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NZGrids + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NTGrids + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NSteps + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%PLExp + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Z0 + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VLinShr + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%HLinShr + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%BoxExceedAllowF, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%BoxExceedAllowIdx + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%BoxExceedWarned, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE IfW_FlowField_PackGrid3DFieldType + + SUBROUTINE IfW_FlowField_UnPackGrid3DFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Grid3DFieldType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackGrid3DFieldType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%WindFileFormat = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WindProfileType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%Periodic = TRANSFER(IntKiBuf(Int_Xferred), OutData%Periodic) + Int_Xferred = Int_Xferred + 1 + OutData%InterpTower = TRANSFER(IntKiBuf(Int_Xferred), OutData%InterpTower) + Int_Xferred = Int_Xferred + 1 + OutData%AddMeanAfterInterp = TRANSFER(IntKiBuf(Int_Xferred), OutData%AddMeanAfterInterp) + Int_Xferred = Int_Xferred + 1 + OutData%RefHeight = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefLength = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vel not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vel)) DEALLOCATE(OutData%Vel) + ALLOCATE(OutData%Vel(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%Vel,4), UBOUND(OutData%Vel,4) + DO i3 = LBOUND(OutData%Vel,3), UBOUND(OutData%Vel,3) + DO i2 = LBOUND(OutData%Vel,2), UBOUND(OutData%Vel,2) + DO i1 = LBOUND(OutData%Vel,1), UBOUND(OutData%Vel,1) + OutData%Vel(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Acc not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Acc)) DEALLOCATE(OutData%Acc) + ALLOCATE(OutData%Acc(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Acc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%Acc,4), UBOUND(OutData%Acc,4) + DO i3 = LBOUND(OutData%Acc,3), UBOUND(OutData%Acc,3) + DO i2 = LBOUND(OutData%Acc,2), UBOUND(OutData%Acc,2) + DO i1 = LBOUND(OutData%Acc,1), UBOUND(OutData%Acc,1) + OutData%Acc(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelTower not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelTower)) DEALLOCATE(OutData%VelTower) + ALLOCATE(OutData%VelTower(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelTower.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%VelTower,3), UBOUND(OutData%VelTower,3) + DO i2 = LBOUND(OutData%VelTower,2), UBOUND(OutData%VelTower,2) + DO i1 = LBOUND(OutData%VelTower,1), UBOUND(OutData%VelTower,1) + OutData%VelTower(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AccTower not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AccTower)) DEALLOCATE(OutData%AccTower) + ALLOCATE(OutData%AccTower(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AccTower.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%AccTower,3), UBOUND(OutData%AccTower,3) + DO i2 = LBOUND(OutData%AccTower,2), UBOUND(OutData%AccTower,2) + DO i1 = LBOUND(OutData%AccTower,1), UBOUND(OutData%AccTower,1) + OutData%AccTower(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VelAvg not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%VelAvg)) DEALLOCATE(OutData%VelAvg) + ALLOCATE(OutData%VelAvg(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VelAvg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%VelAvg,3), UBOUND(OutData%VelAvg,3) + DO i2 = LBOUND(OutData%VelAvg,2), UBOUND(OutData%VelAvg,2) + DO i1 = LBOUND(OutData%VelAvg,1), UBOUND(OutData%VelAvg,1) + OutData%VelAvg(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AccAvg not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AccAvg)) DEALLOCATE(OutData%AccAvg) + ALLOCATE(OutData%AccAvg(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AccAvg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%AccAvg,3), UBOUND(OutData%AccAvg,3) + DO i2 = LBOUND(OutData%AccAvg,2), UBOUND(OutData%AccAvg,2) + DO i1 = LBOUND(OutData%AccAvg,1), UBOUND(OutData%AccAvg,1) + OutData%AccAvg(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + OutData%DTime = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Rate = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%YHWid = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%ZHWid = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%GridBase = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%InitXPosition = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%InvDY = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%InvDZ = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MeanWS = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%InvMWS = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%TotalTime = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%NComp = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NYGrids = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NZGrids = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NTGrids = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NSteps = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%PLExp = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Z0 = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VLinShr = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%HLinShr = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%BoxExceedAllowF = TRANSFER(IntKiBuf(Int_Xferred), OutData%BoxExceedAllowF) + Int_Xferred = Int_Xferred + 1 + OutData%BoxExceedAllowIdx = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%BoxExceedWarned = TRANSFER(IntKiBuf(Int_Xferred), OutData%BoxExceedWarned) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE IfW_FlowField_UnPackGrid3DFieldType + + SUBROUTINE IfW_FlowField_CopyGrid4DFieldType( SrcGrid4DFieldTypeData, DstGrid4DFieldTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Grid4DFieldType), INTENT(IN) :: SrcGrid4DFieldTypeData + TYPE(Grid4DFieldType), INTENT(INOUT) :: DstGrid4DFieldTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyGrid4DFieldType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstGrid4DFieldTypeData%n = SrcGrid4DFieldTypeData%n + DstGrid4DFieldTypeData%delta = SrcGrid4DFieldTypeData%delta + DstGrid4DFieldTypeData%pZero = SrcGrid4DFieldTypeData%pZero +IF (ALLOCATED(SrcGrid4DFieldTypeData%Vel)) THEN + i1_l = LBOUND(SrcGrid4DFieldTypeData%Vel,1) + i1_u = UBOUND(SrcGrid4DFieldTypeData%Vel,1) + i2_l = LBOUND(SrcGrid4DFieldTypeData%Vel,2) + i2_u = UBOUND(SrcGrid4DFieldTypeData%Vel,2) + i3_l = LBOUND(SrcGrid4DFieldTypeData%Vel,3) + i3_u = UBOUND(SrcGrid4DFieldTypeData%Vel,3) + i4_l = LBOUND(SrcGrid4DFieldTypeData%Vel,4) + i4_u = UBOUND(SrcGrid4DFieldTypeData%Vel,4) + i5_l = LBOUND(SrcGrid4DFieldTypeData%Vel,5) + i5_u = UBOUND(SrcGrid4DFieldTypeData%Vel,5) + IF (.NOT. ALLOCATED(DstGrid4DFieldTypeData%Vel)) THEN + ALLOCATE(DstGrid4DFieldTypeData%Vel(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u,i5_l:i5_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstGrid4DFieldTypeData%Vel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstGrid4DFieldTypeData%Vel = SrcGrid4DFieldTypeData%Vel +ENDIF + DstGrid4DFieldTypeData%TimeStart = SrcGrid4DFieldTypeData%TimeStart + DstGrid4DFieldTypeData%RefHeight = SrcGrid4DFieldTypeData%RefHeight + END SUBROUTINE IfW_FlowField_CopyGrid4DFieldType + + SUBROUTINE IfW_FlowField_DestroyGrid4DFieldType( Grid4DFieldTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Grid4DFieldType), INTENT(INOUT) :: Grid4DFieldTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyGrid4DFieldType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(Grid4DFieldTypeData%Vel)) THEN + DEALLOCATE(Grid4DFieldTypeData%Vel) +ENDIF + END SUBROUTINE IfW_FlowField_DestroyGrid4DFieldType + + SUBROUTINE IfW_FlowField_PackGrid4DFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Grid4DFieldType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackGrid4DFieldType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + SIZE(InData%n) ! n + Re_BufSz = Re_BufSz + SIZE(InData%delta) ! delta + Re_BufSz = Re_BufSz + SIZE(InData%pZero) ! pZero + Int_BufSz = Int_BufSz + 1 ! Vel allocated yes/no + IF ( ALLOCATED(InData%Vel) ) THEN + Int_BufSz = Int_BufSz + 2*5 ! Vel upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vel) ! Vel + END IF + Re_BufSz = Re_BufSz + 1 ! TimeStart + Re_BufSz = Re_BufSz + 1 ! RefHeight + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO i1 = LBOUND(InData%n,1), UBOUND(InData%n,1) + IntKiBuf(Int_Xferred) = InData%n(i1) + Int_Xferred = Int_Xferred + 1 + END DO + DO i1 = LBOUND(InData%delta,1), UBOUND(InData%delta,1) + ReKiBuf(Re_Xferred) = InData%delta(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%pZero,1), UBOUND(InData%pZero,1) + ReKiBuf(Re_Xferred) = InData%pZero(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IF ( .NOT. ALLOCATED(InData%Vel) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,4) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,5) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,5) + Int_Xferred = Int_Xferred + 2 + + DO i5 = LBOUND(InData%Vel,5), UBOUND(InData%Vel,5) + DO i4 = LBOUND(InData%Vel,4), UBOUND(InData%Vel,4) + DO i3 = LBOUND(InData%Vel,3), UBOUND(InData%Vel,3) + DO i2 = LBOUND(InData%Vel,2), UBOUND(InData%Vel,2) + DO i1 = LBOUND(InData%Vel,1), UBOUND(InData%Vel,1) + ReKiBuf(Re_Xferred) = InData%Vel(i1,i2,i3,i4,i5) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END DO + END IF + ReKiBuf(Re_Xferred) = InData%TimeStart + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefHeight + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE IfW_FlowField_PackGrid4DFieldType + + SUBROUTINE IfW_FlowField_UnPackGrid4DFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Grid4DFieldType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: i5, i5_l, i5_u ! bounds (upper/lower) for an array dimension 5 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackGrid4DFieldType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + i1_l = LBOUND(OutData%n,1) + i1_u = UBOUND(OutData%n,1) + DO i1 = LBOUND(OutData%n,1), UBOUND(OutData%n,1) + OutData%n(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + i1_l = LBOUND(OutData%delta,1) + i1_u = UBOUND(OutData%delta,1) + DO i1 = LBOUND(OutData%delta,1), UBOUND(OutData%delta,1) + OutData%delta(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%pZero,1) + i1_u = UBOUND(OutData%pZero,1) + DO i1 = LBOUND(OutData%pZero,1), UBOUND(OutData%pZero,1) + OutData%pZero(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vel not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i5_l = IntKiBuf( Int_Xferred ) + i5_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vel)) DEALLOCATE(OutData%Vel) + ALLOCATE(OutData%Vel(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u,i5_l:i5_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i5 = LBOUND(OutData%Vel,5), UBOUND(OutData%Vel,5) + DO i4 = LBOUND(OutData%Vel,4), UBOUND(OutData%Vel,4) + DO i3 = LBOUND(OutData%Vel,3), UBOUND(OutData%Vel,3) + DO i2 = LBOUND(OutData%Vel,2), UBOUND(OutData%Vel,2) + DO i1 = LBOUND(OutData%Vel,1), UBOUND(OutData%Vel,1) + OutData%Vel(i1,i2,i3,i4,i5) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END DO + END IF + OutData%TimeStart = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefHeight = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE IfW_FlowField_UnPackGrid4DFieldType + + SUBROUTINE IfW_FlowField_CopyPointsFieldType( SrcPointsFieldTypeData, DstPointsFieldTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(PointsFieldType), INTENT(IN) :: SrcPointsFieldTypeData + TYPE(PointsFieldType), INTENT(INOUT) :: DstPointsFieldTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyPointsFieldType' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcPointsFieldTypeData%Vel)) THEN + i1_l = LBOUND(SrcPointsFieldTypeData%Vel,1) + i1_u = UBOUND(SrcPointsFieldTypeData%Vel,1) + i2_l = LBOUND(SrcPointsFieldTypeData%Vel,2) + i2_u = UBOUND(SrcPointsFieldTypeData%Vel,2) + IF (.NOT. ALLOCATED(DstPointsFieldTypeData%Vel)) THEN + ALLOCATE(DstPointsFieldTypeData%Vel(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstPointsFieldTypeData%Vel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstPointsFieldTypeData%Vel = SrcPointsFieldTypeData%Vel +ENDIF + END SUBROUTINE IfW_FlowField_CopyPointsFieldType + + SUBROUTINE IfW_FlowField_DestroyPointsFieldType( PointsFieldTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(PointsFieldType), INTENT(INOUT) :: PointsFieldTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyPointsFieldType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(PointsFieldTypeData%Vel)) THEN + DEALLOCATE(PointsFieldTypeData%Vel) +ENDIF + END SUBROUTINE IfW_FlowField_DestroyPointsFieldType + + SUBROUTINE IfW_FlowField_PackPointsFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(PointsFieldType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackPointsFieldType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! Vel allocated yes/no + IF ( ALLOCATED(InData%Vel) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Vel upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vel) ! Vel + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IF ( .NOT. ALLOCATED(InData%Vel) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vel,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vel,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Vel,2), UBOUND(InData%Vel,2) + DO i1 = LBOUND(InData%Vel,1), UBOUND(InData%Vel,1) + ReKiBuf(Re_Xferred) = InData%Vel(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + END SUBROUTINE IfW_FlowField_PackPointsFieldType + + SUBROUTINE IfW_FlowField_UnPackPointsFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(PointsFieldType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackPointsFieldType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vel not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vel)) DEALLOCATE(OutData%Vel) + ALLOCATE(OutData%Vel(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Vel,2), UBOUND(OutData%Vel,2) + DO i1 = LBOUND(OutData%Vel,1), UBOUND(OutData%Vel,1) + OutData%Vel(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + END SUBROUTINE IfW_FlowField_UnPackPointsFieldType + + SUBROUTINE IfW_FlowField_CopyUserFieldType( SrcUserFieldTypeData, DstUserFieldTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(UserFieldType), INTENT(IN) :: SrcUserFieldTypeData + TYPE(UserFieldType), INTENT(INOUT) :: DstUserFieldTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyUserFieldType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstUserFieldTypeData%RefHeight = SrcUserFieldTypeData%RefHeight + END SUBROUTINE IfW_FlowField_CopyUserFieldType + + SUBROUTINE IfW_FlowField_DestroyUserFieldType( UserFieldTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(UserFieldType), INTENT(INOUT) :: UserFieldTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyUserFieldType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE IfW_FlowField_DestroyUserFieldType + + SUBROUTINE IfW_FlowField_PackUserFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(UserFieldType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackUserFieldType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! RefHeight + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%RefHeight + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE IfW_FlowField_PackUserFieldType + + SUBROUTINE IfW_FlowField_UnPackUserFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(UserFieldType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackUserFieldType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%RefHeight = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE IfW_FlowField_UnPackUserFieldType + + SUBROUTINE IfW_FlowField_CopyFlowFieldType( SrcFlowFieldTypeData, DstFlowFieldTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(FlowFieldType), INTENT(IN) :: SrcFlowFieldTypeData + TYPE(FlowFieldType), INTENT(INOUT) :: DstFlowFieldTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_CopyFlowFieldType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstFlowFieldTypeData%FieldType = SrcFlowFieldTypeData%FieldType + DstFlowFieldTypeData%RefPosition = SrcFlowFieldTypeData%RefPosition + DstFlowFieldTypeData%PropagationDir = SrcFlowFieldTypeData%PropagationDir + DstFlowFieldTypeData%VFlowAngle = SrcFlowFieldTypeData%VFlowAngle + DstFlowFieldTypeData%VelInterpCubic = SrcFlowFieldTypeData%VelInterpCubic + DstFlowFieldTypeData%RotateWindBox = SrcFlowFieldTypeData%RotateWindBox + DstFlowFieldTypeData%AccFieldValid = SrcFlowFieldTypeData%AccFieldValid + DstFlowFieldTypeData%RotToWind = SrcFlowFieldTypeData%RotToWind + DstFlowFieldTypeData%RotFromWind = SrcFlowFieldTypeData%RotFromWind + CALL IfW_FlowField_Copyuniformfieldtype( SrcFlowFieldTypeData%Uniform, DstFlowFieldTypeData%Uniform, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL IfW_FlowField_Copygrid3dfieldtype( SrcFlowFieldTypeData%Grid3D, DstFlowFieldTypeData%Grid3D, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL IfW_FlowField_Copygrid4dfieldtype( SrcFlowFieldTypeData%Grid4D, DstFlowFieldTypeData%Grid4D, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL IfW_FlowField_Copypointsfieldtype( SrcFlowFieldTypeData%Points, DstFlowFieldTypeData%Points, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL IfW_FlowField_Copyuserfieldtype( SrcFlowFieldTypeData%User, DstFlowFieldTypeData%User, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE IfW_FlowField_CopyFlowFieldType + + SUBROUTINE IfW_FlowField_DestroyFlowFieldType( FlowFieldTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(FlowFieldType), INTENT(INOUT) :: FlowFieldTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_DestroyFlowFieldType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL IfW_FlowField_Destroyuniformfieldtype( FlowFieldTypeData%Uniform, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IfW_FlowField_Destroygrid3dfieldtype( FlowFieldTypeData%Grid3D, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IfW_FlowField_Destroygrid4dfieldtype( FlowFieldTypeData%Grid4D, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IfW_FlowField_Destroypointsfieldtype( FlowFieldTypeData%Points, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IfW_FlowField_Destroyuserfieldtype( FlowFieldTypeData%User, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE IfW_FlowField_DestroyFlowFieldType + + SUBROUTINE IfW_FlowField_PackFlowFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(FlowFieldType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_PackFlowFieldType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! FieldType + Re_BufSz = Re_BufSz + SIZE(InData%RefPosition) ! RefPosition + Re_BufSz = Re_BufSz + 1 ! PropagationDir + Re_BufSz = Re_BufSz + 1 ! VFlowAngle + Int_BufSz = Int_BufSz + 1 ! VelInterpCubic + Int_BufSz = Int_BufSz + 1 ! RotateWindBox + Int_BufSz = Int_BufSz + 1 ! AccFieldValid + Re_BufSz = Re_BufSz + SIZE(InData%RotToWind) ! RotToWind + Re_BufSz = Re_BufSz + SIZE(InData%RotFromWind) ! RotFromWind + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! Uniform: size of buffers for each call to pack subtype + CALL IfW_FlowField_Packuniformfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Uniform, ErrStat2, ErrMsg2, .TRUE. ) ! Uniform + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Uniform + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Uniform + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Uniform + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! Grid3D: size of buffers for each call to pack subtype + CALL IfW_FlowField_Packgrid3dfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Grid3D, ErrStat2, ErrMsg2, .TRUE. ) ! Grid3D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Grid3D + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Grid3D + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Grid3D + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! Grid4D: size of buffers for each call to pack subtype + CALL IfW_FlowField_Packgrid4dfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Grid4D, ErrStat2, ErrMsg2, .TRUE. ) ! Grid4D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Grid4D + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Grid4D + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Grid4D + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! Points: size of buffers for each call to pack subtype + CALL IfW_FlowField_Packpointsfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Points, ErrStat2, ErrMsg2, .TRUE. ) ! Points + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Points + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Points + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Points + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! User: size of buffers for each call to pack subtype + CALL IfW_FlowField_Packuserfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%User, ErrStat2, ErrMsg2, .TRUE. ) ! User + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! User + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! User + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! User + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IntKiBuf(Int_Xferred) = InData%FieldType + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%RefPosition,1), UBOUND(InData%RefPosition,1) + ReKiBuf(Re_Xferred) = InData%RefPosition(i1) + Re_Xferred = Re_Xferred + 1 + END DO + ReKiBuf(Re_Xferred) = InData%PropagationDir + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VFlowAngle + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%VelInterpCubic, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%RotateWindBox, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%AccFieldValid, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO i2 = LBOUND(InData%RotToWind,2), UBOUND(InData%RotToWind,2) + DO i1 = LBOUND(InData%RotToWind,1), UBOUND(InData%RotToWind,1) + ReKiBuf(Re_Xferred) = InData%RotToWind(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + DO i2 = LBOUND(InData%RotFromWind,2), UBOUND(InData%RotFromWind,2) + DO i1 = LBOUND(InData%RotFromWind,1), UBOUND(InData%RotFromWind,1) + ReKiBuf(Re_Xferred) = InData%RotFromWind(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + CALL IfW_FlowField_Packuniformfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Uniform, ErrStat2, ErrMsg2, OnlySize ) ! Uniform + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL IfW_FlowField_Packgrid3dfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Grid3D, ErrStat2, ErrMsg2, OnlySize ) ! Grid3D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL IfW_FlowField_Packgrid4dfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Grid4D, ErrStat2, ErrMsg2, OnlySize ) ! Grid4D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL IfW_FlowField_Packpointsfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%Points, ErrStat2, ErrMsg2, OnlySize ) ! Points + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL IfW_FlowField_Packuserfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%User, ErrStat2, ErrMsg2, OnlySize ) ! User + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END SUBROUTINE IfW_FlowField_PackFlowFieldType + + SUBROUTINE IfW_FlowField_UnPackFlowFieldType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(FlowFieldType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'IfW_FlowField_UnPackFlowFieldType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%FieldType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%RefPosition,1) + i1_u = UBOUND(OutData%RefPosition,1) + DO i1 = LBOUND(OutData%RefPosition,1), UBOUND(OutData%RefPosition,1) + OutData%RefPosition(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%PropagationDir = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VFlowAngle = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VelInterpCubic = TRANSFER(IntKiBuf(Int_Xferred), OutData%VelInterpCubic) + Int_Xferred = Int_Xferred + 1 + OutData%RotateWindBox = TRANSFER(IntKiBuf(Int_Xferred), OutData%RotateWindBox) + Int_Xferred = Int_Xferred + 1 + OutData%AccFieldValid = TRANSFER(IntKiBuf(Int_Xferred), OutData%AccFieldValid) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%RotToWind,1) + i1_u = UBOUND(OutData%RotToWind,1) + i2_l = LBOUND(OutData%RotToWind,2) + i2_u = UBOUND(OutData%RotToWind,2) + DO i2 = LBOUND(OutData%RotToWind,2), UBOUND(OutData%RotToWind,2) + DO i1 = LBOUND(OutData%RotToWind,1), UBOUND(OutData%RotToWind,1) + OutData%RotToWind(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + i1_l = LBOUND(OutData%RotFromWind,1) + i1_u = UBOUND(OutData%RotFromWind,1) + i2_l = LBOUND(OutData%RotFromWind,2) + i2_u = UBOUND(OutData%RotFromWind,2) + DO i2 = LBOUND(OutData%RotFromWind,2), UBOUND(OutData%RotFromWind,2) + DO i1 = LBOUND(OutData%RotFromWind,1), UBOUND(OutData%RotFromWind,1) + OutData%RotFromWind(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL IfW_FlowField_Unpackuniformfieldtype( Re_Buf, Db_Buf, Int_Buf, OutData%Uniform, ErrStat2, ErrMsg2 ) ! Uniform + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL IfW_FlowField_Unpackgrid3dfieldtype( Re_Buf, Db_Buf, Int_Buf, OutData%Grid3D, ErrStat2, ErrMsg2 ) ! Grid3D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL IfW_FlowField_Unpackgrid4dfieldtype( Re_Buf, Db_Buf, Int_Buf, OutData%Grid4D, ErrStat2, ErrMsg2 ) ! Grid4D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL IfW_FlowField_Unpackpointsfieldtype( Re_Buf, Db_Buf, Int_Buf, OutData%Points, ErrStat2, ErrMsg2 ) ! Points + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL IfW_FlowField_Unpackuserfieldtype( Re_Buf, Db_Buf, Int_Buf, OutData%User, ErrStat2, ErrMsg2 ) ! User + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END SUBROUTINE IfW_FlowField_UnPackFlowFieldType + +END MODULE IfW_FlowField_Types +!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_HAWCWind.f90 b/modules/inflowwind/src/IfW_HAWCWind.f90 deleted file mode 100644 index 2ebbcc2b0..000000000 --- a/modules/inflowwind/src/IfW_HAWCWind.f90 +++ /dev/null @@ -1,387 +0,0 @@ -!> This module uses full-field binary wind files to determine the wind inflow. -!! This module assumes that the origin, (0,0,0), is located at the tower centerline at ground level, -!! and that all units are specified in the metric system (using meters and seconds). -!! Data is assumed periodic in the X direction (and thus not shifted like FFWind files are). -MODULE IfW_HAWCWind -!! -!! Created 25-June-2010 by B. Jonkman, National Renewable Energy Laboratory -!! using subroutines and modules from AeroDyn v12.58 -!! -!!---------------------------------------------------------------------------------------------------- -!! Updated 8-Aug-2015 for InflowWind v3.0 in the FAST v8 Framework -! -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2015-2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - USE NWTC_Library - USE IfW_HAWCWind_Types - USE IfW_FFWind_Base - - IMPLICIT NONE - PRIVATE - - TYPE(ProgDesc), PARAMETER :: IfW_HAWCWind_Ver = ProgDesc( 'IfW_HAWCWind', '', '' ) - - PUBLIC :: IfW_HAWCWind_Init - PUBLIC :: IfW_HAWCWind_End - PUBLIC :: IfW_HAWCWind_CalcOutput - - INTEGER(IntKi), PARAMETER :: nc = 3 !< number of wind components - -CONTAINS -!==================================================================================================== -!> This routine is used to initialize the parameters for using HAWC wind format files. -SUBROUTINE IfW_HAWCWind_Init(InitInp, p, MiscVars, Interval, InitOut, ErrStat, ErrMsg) - - ! Passed Variables - TYPE(IfW_HAWCWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization data passed to the module - TYPE(IfW_HAWCWind_ParameterType), INTENT( OUT) :: p !< Parameters - TYPE(IfW_HAWCWind_MiscVarType), INTENT( OUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - TYPE(IfW_HAWCWind_InitOutputType), INTENT( OUT) :: InitOut !< Initialization output - - REAL(DbKi), INTENT(IN ) :: Interval !< Time Interval to use (passed through here) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_Init' - - ! Local Variables: - - - - ErrStat = ErrID_None - ErrMsg = "" - - ! validate init input data: - call ValidateInput(InitInp, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Set some internal module parameters based on input file values - !------------------------------------------------------------------------------------------------- - p%FF%WindFileFormat = 0 - p%FF%Periodic = .true. - p%FF%InterpTower = .true. - - p%FF%NFFComp = 3 - p%FF%NFFSteps = InitInp%nx - p%FF%NYGrids = InitInp%ny - p%FF%NZGrids = InitInp%nz - p%FF%NTGrids = 0 - - p%FF%MeanFFWS = InitInp%FF%URef - p%FF%FFDTime = InitInp%dx / InitInp%FF%URef - p%FF%FFRate = 1.0 / p%FF%FFDTime - p%FF%InvFFYD = 1.0 / InitInp%dy - p%FF%InvFFZD = 1.0 / InitInp%dz - p%FF%InvMFFWS = 1.0 / p%FF%MeanFFWS - - p%FF%TotalTime = InitInp%nx * InitInp%dx / InitInp%FF%URef - p%FF%FFYHWid = 0.5 * InitInp%dy * (InitInp%ny-1) - p%FF%FFZHWid = 0.5 * InitInp%dz * (InitInp%nz-1) - p%FF%GridBase = InitInp%FF%RefHt - p%FF%FFZHWid - p%FF%RefHt = InitInp%FF%RefHt - - p%FF%WindProfileType = InitInp%FF%WindProfileType - p%FF%Z0 = InitInp%FF%Z0 - p%FF%PLExp = InitInp%FF%PLExp - p%FF%AddMeanAfterInterp = .true. - - - p%FF%InitXPosition = InitInp%FF%XOffset - - IF ( p%FF%GridBase < 0.0_ReKi ) THEN - call SetErrStat( ErrID_Severe, 'WARNING: The bottom of the grid is located at a height of '//& - TRIM( Num2LStr(p%FF%GridBase) )//' meters, which is below the ground.'//& - ' Winds below the ground will be set to 0.', ErrStat,ErrMsg, RoutineName) - END IF - - !------------------------------------------------------------------------------------------------- - ! Read data files: - !------------------------------------------------------------------------------------------------- - call ReadTurbulenceData( p, InitInp, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - !------------------------------------------------------------------------------------------------- - ! scale to requested TI (or use requested scale factors) - !------------------------------------------------------------------------------------------------- - call ScaleTurbulence(InitInp%FF, p%FF%FFData, InitOut%sf, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Add the mean wind speed to the u component. - !------------------------------------------------------------------------------------------------- - if (InitInp%FF%ScaleMethod /= ScaleMethod_None) call SubtractMeanVelocity(p%FF%FFData) - if (.not. p%FF%AddMeanAfterInterp) call AddMeanVelocity(InitInp%FF, p%FF%GridBase, 1.0_ReKi/p%FF%InvFFZD, p%FF%FFData) - - !------------------------------------------------------------------------------------------------- - ! write info to summary file, if necessary - !------------------------------------------------------------------------------------------------- - - IF ( InitInp%SumFileUnit > 0 ) THEN - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) 'HAWC wind type. Read by InflowWind sub-module '//TRIM(GetNVD(IfW_HAWCWind_Ver)) - - WRITE(InitInp%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Reference height (m): ',InitInp%FF%RefHt - WRITE(InitInp%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Timestep (s): ',p%FF%FFDTime - WRITE(InitInp%SumFileUnit,'(A34,I12)', IOSTAT=TmpErrStat) ' Number of timesteps: ',p%FF%NFFSteps - WRITE(InitInp%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Mean windspeed (m/s): ',p%FF%MeanFFWS - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Time range (s): [ '// & - TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr( p%FF%TotalTime ))//' ]' - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' X range (m): [ '// & - TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr( p%FF%TotalTime * p%FF%MeanFFWS ))//' ]' - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Y range (m): [ '// & - TRIM(Num2LStr(-p%FF%FFYHWid))//' : '//TRIM(Num2LStr(p%FF%FFYHWid))//' ]' - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Z range (m): [ '// & - TRIM(Num2LStr(p%FF%GridBase))//' : '//TRIM(Num2LStr(p%FF%GridBase + p%FF%FFZHWid*2.0))//' ]' - - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) 'Scaling factors used:' - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' u v w ' - WRITE(InitInp%SumFileUnit,'(A)', IOSTAT=TmpErrStat) '---------- ---------- ----------' - WRITE(InitInp%SumFileUnit,'(F10.3,2x,F10.3,2x,F10.3)',IOSTAT=TmpErrStat) InitOut%sf - ENDIF - - MiscVars%DummyMiscVar = 0 - - RETURN - -END SUBROUTINE IfW_HAWCWind_Init -!==================================================================================================== -!> This routine is used to make sure the initInp data is valid. -SUBROUTINE ValidateInput(InitInp, ErrStat, ErrMsg) - - ! Passed Variables - TYPE(IfW_HAWCWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization input data passed to the module - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - character(*), parameter :: RoutineName = 'ValidateInput' - - - ErrStat = ErrID_None - ErrMsg = "" - - ! validate the inputs for scaling turbulence: - CALL FFWind_ValidateInput(InitInp%FF, nc, ErrStat, ErrMsg) - - IF ( InitInp%nx < 1 ) CALL SetErrStat( ErrID_Fatal, 'Number of grid points in the X direction must be at least 1.', ErrStat, ErrMsg, RoutineName ) - IF ( InitInp%ny < 1 ) CALL SetErrStat( ErrID_Fatal, 'Number of grid points in the Y direction must be at least 1.', ErrStat, ErrMsg, RoutineName ) - IF ( InitInp%nz < 1 ) CALL SetErrStat( ErrID_Fatal, 'Number of grid points in the Z direction must be at least 1.', ErrStat, ErrMsg, RoutineName ) - - IF ( InitInp%dx < 0.0_ReKi .or. EqualRealNos( InitInp%dx, 0.0_ReKi ) ) CALL SetErrStat( ErrID_Fatal, 'The grid spacing in the X direction must be larger than 0.', ErrStat, ErrMsg, RoutineName ) - IF ( InitInp%dy < 0.0_ReKi .or. EqualRealNos( InitInp%dy, 0.0_ReKi ) ) CALL SetErrStat( ErrID_Fatal, 'The grid spacing in the Y direction must be larger than 0.', ErrStat, ErrMsg, RoutineName ) - IF ( InitInp%dz < 0.0_ReKi .or. EqualRealNos( InitInp%dz, 0.0_ReKi ) ) CALL SetErrStat( ErrID_Fatal, 'The grid spacing in the Z direction must be larger than 0.', ErrStat, ErrMsg, RoutineName ) - - -END SUBROUTINE ValidateInput -!==================================================================================================== -!> This routine is used read the full-field turbulence data stored in HAWC format. -SUBROUTINE ReadTurbulenceData(p, InitInp, ErrStat, ErrMsg) - - ! Passed Variables - TYPE(IfW_HAWCWind_ParameterType), INTENT(INOUT) :: p !< Parameters - TYPE(IfW_HAWCWind_InitInputType), INTENT(IN ) :: InitInp !< Initialization input data passed to the module - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - ! Local Variables: - INTEGER :: IC ! Loop counter for the number of wind components - INTEGER :: IX ! Loop counter for the number of grid points in the X direction - INTEGER :: IY ! Loop counter for the number of grid points in the Y direction - INTEGER :: unWind ! unit number for reading binary files - - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - CHARACTER(*), PARAMETER :: RoutineName = 'ReadTurbulenceData' - - - ErrStat = ErrID_None - ErrMsg = "" - - - !------------------------------------------------------------------------------------------------- - ! Allocate space for the wind array. - !------------------------------------------------------------------------------------------------- - - CALL AllocAry( p%FF%FFData, p%FF%NZGrids,p%FF%NYGrids,p%FF%NFFComp, p%FF%NFFSteps, 'p%FF%FFData', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - !------------------------------------------------------------------------------------------------- - ! Read the 3 files containg the turbulent wind speeds. - !------------------------------------------------------------------------------------------------- -!bjj: check these indices... they do not seem to be very consistant between the WAsP IEC Turbulence -! simulator and documentation of OC3 file formats... the current implementation is from the -! OC3/Kenneth Thompson documentation. - - - ! this could take a while, so we'll write a message indicating what's going on: - - CALL WrScr( NewLine//' Reading HAWC wind files with grids of '//& - TRIM( Num2LStr(p%FF%NFFSteps) )//' x '//TRIM( Num2LStr(p%FF%NYGrids) )//' x '//TRIM( Num2LStr(p%FF%NZGrids) )//' points'// & - ' ('//TRIM( Num2LStr(p%FF%FFYHWid*2) )//' m wide, '// TRIM( Num2LStr(p%FF%GridBase) )//' m to '// & - TRIM( Num2LStr(p%FF%GridBase+p%FF%FFZHWid*2) )//& - ' m above ground) with a characteristic wind speed of '//TRIM( Num2LStr(p%FF%MeanFFWS) )//' m/s. ' ) - - - CALL GetNewUnit( UnWind, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - ! The array must be filled so that x(i) < x(i+1), y(i) < y(i+1), and z(i) < z(i+1) - ! Also, note that the time axis is the negative x axis. - - DO IC = 1,NC - - CALL OpenBInpFile ( UnWind, InitInp%WindFileName(IC), TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - DO IX = 1,p%FF%NFFSteps - DO IY = p%FF%NYGrids,1,-1 - !DO IZ = 1,p%FF%NZGrids - - READ( UnWind, IOSTAT=TmpErrStat ) p%FF%FFData(:,iy,ic,ix) ! note that FFData is SiKi (4-byte reals, not default kinds) - - IF (TmpErrStat /= 0) THEN - TmpErrMsg = ' Error reading binary data from "'//TRIM(InitInp%WindFileName(IC))//'". I/O error ' & - //TRIM(Num2LStr(TmpErrStat))//' occurred at IY='//TRIM(Num2LStr(IY))//', IX='//TRIM(Num2LStr(IX))//'.' - CLOSE ( UnWind ) - CALL SetErrStat(ErrID_Fatal, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - RETURN - END IF - - !END DO - END DO - END DO - - CLOSE ( UnWind ) - - END DO - - -END SUBROUTINE ReadTurbulenceData -!==================================================================================================== -!> This routine acts as a wrapper for the GetWindSpeed routine. It steps through the array of input -!! positions and calls the GetWindSpeed routine to calculate the velocities at each point. -!! -!! There are inefficiencies in how this set of routines is coded, but that is a problem for another -!! day. For now, it merely needs to be functional. It can be fixed up and made all pretty later. -!! -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE IfW_HAWCWind_CalcOutput(Time, PositionXYZ, p, Velocity, DiskVel, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_HAWCWind_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - REAL(ReKi), INTENT( OUT) :: DiskVel(3) !< HACK for AD14: disk velocity output at Time - TYPE(IfW_HAWCWind_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - - ! temporary variables - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CalcOutput' - - - !------------------------------------------------------------------------------------------------- - ! Check that the module has been initialized. - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = '' - - !------------------------------------------------------------------------------------------------- - ! Initialize some things - !------------------------------------------------------------------------------------------------- - - CALL IfW_FFWind_CalcOutput(Time, PositionXYZ, p%FF, Velocity, DiskVel, ErrStat, ErrMsg) - RETURN - -END SUBROUTINE IfW_HAWCWind_CalcOutput -!==================================================================================================== -!> This subroutine cleans up any data that is still allocated. The (possibly) open files are -!! closed in InflowWindMod. -SUBROUTINE IfW_HAWCWind_End( p, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_HAWCWind_End" - - - - ! Passed Variables - TYPE(IfW_HAWCWind_ParameterType), INTENT(INOUT) :: p !< Parameters - TYPE(IfW_HAWCWind_MiscVarType), INTENT( OUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Local Variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !-=- Initialize the routine -=- - - ErrMsg = '' - ErrStat = ErrID_None - - - - - ! Destroy parameter data - - CALL IfW_HAWCWind_DestroyParam( p, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - - - ! Destroy the state data - - CALL IfW_HAWCWind_DestroyMisc( MiscVars, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - - - -END SUBROUTINE IfW_HAWCWind_End - -!==================================================================================================== -END MODULE IfW_HAWCWind diff --git a/modules/inflowwind/src/IfW_HAWCWind.txt b/modules/inflowwind/src/IfW_HAWCWind.txt deleted file mode 100644 index 1d4529181..000000000 --- a/modules/inflowwind/src/IfW_HAWCWind.txt +++ /dev/null @@ -1,52 +0,0 @@ -################################################################################################################################### -# Registry for IfW_HAWCWind, creates MODULE IfW_HAWCWind_Types -# Module IfW_HAWCWind_Types contains all of the user-defined types needed in IfW_HAWCWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - -include Registry_NWTC_Library.txt -usefrom IfW_FFWind_Base.txt - - -######################### - -# Init Input -typedef IfW_HAWCWind/IfW_HAWCWind InitInputType CHARACTER(1024) WindFileName {3} - - "Name of the wind file to use" - -typedef ^ ^ IntKi SumFileUnit - - - "Unit number for the summary file (-1 for none). Provided by IfW." - -typedef ^ ^ IntKi nx - 0 - "Number of grids in the x direction (in the 3 files above)" - -typedef ^ ^ IntKi ny - 0 - "Number of grids in the y direction (in the 3 files above)" - -typedef ^ ^ IntKi nz - 0 - "Number of grids in the z direction (in the 3 files above)" - -typedef ^ ^ ReKi dx - 0 - "size of grids in the x direction (in the 3 files above)" - -typedef ^ ^ ReKi dy - 0 - "size of grids in the y direction (in the 3 files above)" - -typedef ^ ^ ReKi dz - 0 - "size of grids in the z direction (in the 3 files above)" - -typedef ^ ^ IfW_FFWind_InitInputType FF - - - "scaling data" - - - -# Init Output -typedef ^ InitOutputType ProgDesc Ver - - - "Version information of HAWCWind submodule" - -typedef ^ ^ ReKi SF 3 0 - "Turbulence scaling factor for each direction direction" - - - -# ..... States not used by this module ................................................................................................................... -typedef ^ ContinuousStateType ReKi DummyContState - - - "Remove this variable if you have continuous states" - -typedef ^ DiscreteStateType ReKi DummyDiscState - - - "Remove this variable if you have discrete states" - -typedef ^ ConstraintStateType ReKi DummyConstrState - - - "Remove this variable if you have constraint states" - -typedef ^ OtherStateType ReKi DummyOtherState - - - "Remove this variable if you have other states" - - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType ReKi DummyMiscVar - - - "Remove this variable if you have misc variables" - - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType IfW_FFWind_ParameterType FF - - - "Parameters used in all full-field wind types" - - -# ..... Inputs .................................................................................................................... -# Define inputs that are not on this mesh here: -typedef ^ InputType ReKi Position :: - - "Array holding the input positions at a given timestep" meters - diff --git a/modules/inflowwind/src/IfW_HAWCWind_Types.f90 b/modules/inflowwind/src/IfW_HAWCWind_Types.f90 deleted file mode 100644 index 8fce841f5..000000000 --- a/modules/inflowwind/src/IfW_HAWCWind_Types.f90 +++ /dev/null @@ -1,1609 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_HAWCWind_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_HAWCWind_Types -!................................................................................................................................. -! This file is part of IfW_HAWCWind. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_HAWCWind. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_HAWCWind_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE IfW_FFWind_Base_Types -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_HAWCWind_InitInputType ======= - TYPE, PUBLIC :: IfW_HAWCWind_InitInputType - CHARACTER(1024) , DIMENSION(1:3) :: WindFileName !< Name of the wind file to use [-] - INTEGER(IntKi) :: SumFileUnit !< Unit number for the summary file (-1 for none). Provided by IfW. [-] - INTEGER(IntKi) :: nx = 0 !< Number of grids in the x direction (in the 3 files above) [-] - INTEGER(IntKi) :: ny = 0 !< Number of grids in the y direction (in the 3 files above) [-] - INTEGER(IntKi) :: nz = 0 !< Number of grids in the z direction (in the 3 files above) [-] - REAL(ReKi) :: dx = 0 !< size of grids in the x direction (in the 3 files above) [-] - REAL(ReKi) :: dy = 0 !< size of grids in the y direction (in the 3 files above) [-] - REAL(ReKi) :: dz = 0 !< size of grids in the z direction (in the 3 files above) [-] - TYPE(IfW_FFWind_InitInputType) :: FF !< scaling data [-] - END TYPE IfW_HAWCWind_InitInputType -! ======================= -! ========= IfW_HAWCWind_InitOutputType ======= - TYPE, PUBLIC :: IfW_HAWCWind_InitOutputType - TYPE(ProgDesc) :: Ver !< Version information of HAWCWind submodule [-] - REAL(ReKi) , DIMENSION(1:3) :: SF !< Turbulence scaling factor for each direction direction [-] - END TYPE IfW_HAWCWind_InitOutputType -! ======================= -! ========= IfW_HAWCWind_ContinuousStateType ======= - TYPE, PUBLIC :: IfW_HAWCWind_ContinuousStateType - REAL(ReKi) :: DummyContState !< Remove this variable if you have continuous states [-] - END TYPE IfW_HAWCWind_ContinuousStateType -! ======================= -! ========= IfW_HAWCWind_DiscreteStateType ======= - TYPE, PUBLIC :: IfW_HAWCWind_DiscreteStateType - REAL(ReKi) :: DummyDiscState !< Remove this variable if you have discrete states [-] - END TYPE IfW_HAWCWind_DiscreteStateType -! ======================= -! ========= IfW_HAWCWind_ConstraintStateType ======= - TYPE, PUBLIC :: IfW_HAWCWind_ConstraintStateType - REAL(ReKi) :: DummyConstrState !< Remove this variable if you have constraint states [-] - END TYPE IfW_HAWCWind_ConstraintStateType -! ======================= -! ========= IfW_HAWCWind_OtherStateType ======= - TYPE, PUBLIC :: IfW_HAWCWind_OtherStateType - REAL(ReKi) :: DummyOtherState !< Remove this variable if you have other states [-] - END TYPE IfW_HAWCWind_OtherStateType -! ======================= -! ========= IfW_HAWCWind_MiscVarType ======= - TYPE, PUBLIC :: IfW_HAWCWind_MiscVarType - REAL(ReKi) :: DummyMiscVar !< Remove this variable if you have misc variables [-] - END TYPE IfW_HAWCWind_MiscVarType -! ======================= -! ========= IfW_HAWCWind_ParameterType ======= - TYPE, PUBLIC :: IfW_HAWCWind_ParameterType - TYPE(IfW_FFWind_ParameterType) :: FF !< Parameters used in all full-field wind types [-] - END TYPE IfW_HAWCWind_ParameterType -! ======================= -! ========= IfW_HAWCWind_InputType ======= - TYPE, PUBLIC :: IfW_HAWCWind_InputType - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Position !< Array holding the input positions at a given timestep [meters] - END TYPE IfW_HAWCWind_InputType -! ======================= -CONTAINS - SUBROUTINE IfW_HAWCWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_HAWCWind_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%WindFileName = SrcInitInputData%WindFileName - DstInitInputData%SumFileUnit = SrcInitInputData%SumFileUnit - DstInitInputData%nx = SrcInitInputData%nx - DstInitInputData%ny = SrcInitInputData%ny - DstInitInputData%nz = SrcInitInputData%nz - DstInitInputData%dx = SrcInitInputData%dx - DstInitInputData%dy = SrcInitInputData%dy - DstInitInputData%dz = SrcInitInputData%dz - CALL IfW_FFWind_CopyInitInput( SrcInitInputData%FF, DstInitInputData%FF, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_HAWCWind_CopyInitInput - - SUBROUTINE IfW_HAWCWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyInitInput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL IfW_FFWind_DestroyInitInput( InitInputData%FF, ErrStat, ErrMsg ) - END SUBROUTINE IfW_HAWCWind_DestroyInitInput - - SUBROUTINE IfW_HAWCWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + SIZE(InData%WindFileName)*LEN(InData%WindFileName) ! WindFileName - Int_BufSz = Int_BufSz + 1 ! SumFileUnit - Int_BufSz = Int_BufSz + 1 ! nx - Int_BufSz = Int_BufSz + 1 ! ny - Int_BufSz = Int_BufSz + 1 ! nz - Re_BufSz = Re_BufSz + 1 ! dx - Re_BufSz = Re_BufSz + 1 ! dy - Re_BufSz = Re_BufSz + 1 ! dz - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! FF: size of buffers for each call to pack subtype - CALL IfW_FFWind_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, .TRUE. ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! FF - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! FF - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! FF - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO i1 = LBOUND(InData%WindFileName,1), UBOUND(InData%WindFileName,1) - DO I = 1, LEN(InData%WindFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - IntKiBuf(Int_Xferred) = InData%SumFileUnit - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%nx - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%ny - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%nz - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%dx - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%dy - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%dz - Re_Xferred = Re_Xferred + 1 - CALL IfW_FFWind_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, OnlySize ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_HAWCWind_PackInitInput - - SUBROUTINE IfW_HAWCWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - i1_l = LBOUND(OutData%WindFileName,1) - i1_u = UBOUND(OutData%WindFileName,1) - DO i1 = LBOUND(OutData%WindFileName,1), UBOUND(OutData%WindFileName,1) - DO I = 1, LEN(OutData%WindFileName) - OutData%WindFileName(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO - OutData%SumFileUnit = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%nx = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%ny = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%nz = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%dx = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%dy = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%dz = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_FFWind_UnpackInitInput( Re_Buf, Db_Buf, Int_Buf, OutData%FF, ErrStat2, ErrMsg2 ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_HAWCWind_UnPackInitInput - - SUBROUTINE IfW_HAWCWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(IfW_HAWCWind_InitOutputType), INTENT(INOUT) :: DstInitOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyInitOutput' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - DstInitOutputData%SF = SrcInitOutputData%SF - END SUBROUTINE IfW_HAWCWind_CopyInitOutput - - SUBROUTINE IfW_HAWCWind_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyInitOutput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) - END SUBROUTINE IfW_HAWCWind_DestroyInitOutput - - SUBROUTINE IfW_HAWCWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_InitOutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Re_BufSz = Re_BufSz + SIZE(InData%SF) ! SF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - DO i1 = LBOUND(InData%SF,1), UBOUND(InData%SF,1) - ReKiBuf(Re_Xferred) = InData%SF(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE IfW_HAWCWind_PackInitOutput - - SUBROUTINE IfW_HAWCWind_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - i1_l = LBOUND(OutData%SF,1) - i1_u = UBOUND(OutData%SF,1) - DO i1 = LBOUND(OutData%SF,1), UBOUND(OutData%SF,1) - OutData%SF(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END SUBROUTINE IfW_HAWCWind_UnPackInitOutput - - SUBROUTINE IfW_HAWCWind_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_ContinuousStateType), INTENT(IN) :: SrcContStateData - TYPE(IfW_HAWCWind_ContinuousStateType), INTENT(INOUT) :: DstContStateData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyContState' -! - ErrStat = ErrID_None - ErrMsg = "" - DstContStateData%DummyContState = SrcContStateData%DummyContState - END SUBROUTINE IfW_HAWCWind_CopyContState - - SUBROUTINE IfW_HAWCWind_DestroyContState( ContStateData, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_ContinuousStateType), INTENT(INOUT) :: ContStateData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyContState' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_HAWCWind_DestroyContState - - SUBROUTINE IfW_HAWCWind_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_ContinuousStateType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackContState' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DummyContState - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DummyContState - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_PackContState - - SUBROUTINE IfW_HAWCWind_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_ContinuousStateType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackContState' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DummyContState = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_UnPackContState - - SUBROUTINE IfW_HAWCWind_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_DiscreteStateType), INTENT(IN) :: SrcDiscStateData - TYPE(IfW_HAWCWind_DiscreteStateType), INTENT(INOUT) :: DstDiscStateData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyDiscState' -! - ErrStat = ErrID_None - ErrMsg = "" - DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState - END SUBROUTINE IfW_HAWCWind_CopyDiscState - - SUBROUTINE IfW_HAWCWind_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_DiscreteStateType), INTENT(INOUT) :: DiscStateData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyDiscState' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_HAWCWind_DestroyDiscState - - SUBROUTINE IfW_HAWCWind_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_DiscreteStateType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackDiscState' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DummyDiscState - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DummyDiscState - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_PackDiscState - - SUBROUTINE IfW_HAWCWind_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_DiscreteStateType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackDiscState' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DummyDiscState = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_UnPackDiscState - - SUBROUTINE IfW_HAWCWind_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_ConstraintStateType), INTENT(IN) :: SrcConstrStateData - TYPE(IfW_HAWCWind_ConstraintStateType), INTENT(INOUT) :: DstConstrStateData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyConstrState' -! - ErrStat = ErrID_None - ErrMsg = "" - DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState - END SUBROUTINE IfW_HAWCWind_CopyConstrState - - SUBROUTINE IfW_HAWCWind_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_ConstraintStateType), INTENT(INOUT) :: ConstrStateData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyConstrState' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_HAWCWind_DestroyConstrState - - SUBROUTINE IfW_HAWCWind_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_ConstraintStateType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackConstrState' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DummyConstrState - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DummyConstrState - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_PackConstrState - - SUBROUTINE IfW_HAWCWind_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_ConstraintStateType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackConstrState' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DummyConstrState = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_UnPackConstrState - - SUBROUTINE IfW_HAWCWind_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_OtherStateType), INTENT(IN) :: SrcOtherStateData - TYPE(IfW_HAWCWind_OtherStateType), INTENT(INOUT) :: DstOtherStateData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyOtherState' -! - ErrStat = ErrID_None - ErrMsg = "" - DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState - END SUBROUTINE IfW_HAWCWind_CopyOtherState - - SUBROUTINE IfW_HAWCWind_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_OtherStateType), INTENT(INOUT) :: OtherStateData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyOtherState' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_HAWCWind_DestroyOtherState - - SUBROUTINE IfW_HAWCWind_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_OtherStateType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackOtherState' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DummyOtherState - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DummyOtherState - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_PackOtherState - - SUBROUTINE IfW_HAWCWind_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_OtherStateType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackOtherState' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DummyOtherState = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_UnPackOtherState - - SUBROUTINE IfW_HAWCWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(IfW_HAWCWind_MiscVarType), INTENT(INOUT) :: DstMiscData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyMisc' -! - ErrStat = ErrID_None - ErrMsg = "" - DstMiscData%DummyMiscVar = SrcMiscData%DummyMiscVar - END SUBROUTINE IfW_HAWCWind_CopyMisc - - SUBROUTINE IfW_HAWCWind_DestroyMisc( MiscData, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_MiscVarType), INTENT(INOUT) :: MiscData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyMisc' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_HAWCWind_DestroyMisc - - SUBROUTINE IfW_HAWCWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_MiscVarType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackMisc' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DummyMiscVar - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DummyMiscVar - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_PackMisc - - SUBROUTINE IfW_HAWCWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_MiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackMisc' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DummyMiscVar = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_HAWCWind_UnPackMisc - - SUBROUTINE IfW_HAWCWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_HAWCWind_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL IfW_FFWind_CopyParam( SrcParamData%FF, DstParamData%FF, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_HAWCWind_CopyParam - - SUBROUTINE IfW_HAWCWind_DestroyParam( ParamData, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyParam' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL IfW_FFWind_DestroyParam( ParamData%FF, ErrStat, ErrMsg ) - END SUBROUTINE IfW_HAWCWind_DestroyParam - - SUBROUTINE IfW_HAWCWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! FF: size of buffers for each call to pack subtype - CALL IfW_FFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, .TRUE. ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! FF - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! FF - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! FF - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL IfW_FFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, OnlySize ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_HAWCWind_PackParam - - SUBROUTINE IfW_HAWCWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_FFWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%FF, ErrStat2, ErrMsg2 ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_HAWCWind_UnPackParam - - SUBROUTINE IfW_HAWCWind_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_InputType), INTENT(IN) :: SrcInputData - TYPE(IfW_HAWCWind_InputType), INTENT(INOUT) :: DstInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_CopyInput' -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(SrcInputData%Position)) THEN - i1_l = LBOUND(SrcInputData%Position,1) - i1_u = UBOUND(SrcInputData%Position,1) - i2_l = LBOUND(SrcInputData%Position,2) - i2_u = UBOUND(SrcInputData%Position,2) - IF (.NOT. ALLOCATED(DstInputData%Position)) THEN - ALLOCATE(DstInputData%Position(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%Position.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputData%Position = SrcInputData%Position -ENDIF - END SUBROUTINE IfW_HAWCWind_CopyInput - - SUBROUTINE IfW_HAWCWind_DestroyInput( InputData, ErrStat, ErrMsg ) - TYPE(IfW_HAWCWind_InputType), INTENT(INOUT) :: InputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_DestroyInput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(InputData%Position)) THEN - DEALLOCATE(InputData%Position) -ENDIF - END SUBROUTINE IfW_HAWCWind_DestroyInput - - SUBROUTINE IfW_HAWCWind_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_InputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_PackInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! Position allocated yes/no - IF ( ALLOCATED(InData%Position) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! Position upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Position) ! Position - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IF ( .NOT. ALLOCATED(InData%Position) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Position,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Position,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Position,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Position,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%Position,2), UBOUND(InData%Position,2) - DO i1 = LBOUND(InData%Position,1), UBOUND(InData%Position,1) - ReKiBuf(Re_Xferred) = InData%Position(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - END SUBROUTINE IfW_HAWCWind_PackInput - - SUBROUTINE IfW_HAWCWind_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_HAWCWind_InputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_HAWCWind_UnPackInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Position not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Position)) DEALLOCATE(OutData%Position) - ALLOCATE(OutData%Position(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Position.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%Position,2), UBOUND(OutData%Position,2) - DO i1 = LBOUND(OutData%Position,1), UBOUND(OutData%Position,1) - OutData%Position(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - END SUBROUTINE IfW_HAWCWind_UnPackInput - -END MODULE IfW_HAWCWind_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_TSFFWind.f90 b/modules/inflowwind/src/IfW_TSFFWind.f90 deleted file mode 100644 index 6e400323d..000000000 --- a/modules/inflowwind/src/IfW_TSFFWind.f90 +++ /dev/null @@ -1,659 +0,0 @@ -!> This module uses full-field binary wind files to determine the wind inflow. -!! This module assumes that the origin, (0,0,0), is located at the tower centerline at ground level, -!! and that all units are specified in the metric system (using meters and seconds). -!! Data is shifted by half the grid width to account for turbine yaw (so that data in the X -!! direction actually starts at -1*ParamData%FF%FFYHWid meters). -MODULE IfW_TSFFWind -!! -!! Created 25-Sep-2009 by B. Jonkman, National Renewable Energy Laboratory -!! using subroutines and modules from AeroDyn v12.58 -!! -!!---------------------------------------------------------------------------------------------------- -!! Feb 2013 v2.00.00 A. Platt -!! -- updated to the new framework -!! -- Modified to use NWTC_Library v. 2.0 -!! -- Note: Jacobians are not included in this version. -!! -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2015-2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - - USE NWTC_Library - USE IfW_TSFFWind_Types - USE IfW_FFWind_Base - - IMPLICIT NONE - PRIVATE - - TYPE(ProgDesc), PARAMETER :: IfW_TSFFWind_Ver = ProgDesc( 'IfW_TSFFWind', '', '' ) - - PUBLIC :: IfW_TSFFWind_Init - PUBLIC :: IfW_TSFFWind_End - PUBLIC :: IfW_TSFFWind_CalcOutput - - - - -CONTAINS -!==================================================================================================== -!> This routine is used read the full-field turbulence data. -!! 09/25/1997 - Created by M. Buhl from GETFILES in ViewWind. -!! 09/23/2009 - modified by B. Jonkman: this subroutine was split into several subroutines (was ReadFF) -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE IfW_TSFFWind_Init(InitData, ParamData, MiscVars, InitOutData, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_TSFFWind_Init" - - - ! Passed Variables - TYPE(IfW_TSFFWind_InitInputType), INTENT(IN ) :: InitData !< Initialization data passed to the module - TYPE(IfW_TSFFWind_ParameterType), INTENT( OUT) :: ParamData !< Parameters - TYPE(IfW_TSFFWind_MiscVarType), INTENT( OUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - TYPE(IfW_TSFFWind_InitOutputType), INTENT( OUT) :: InitOutData !< Initial output - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - ! Local Variables: - - INTEGER(IntKi) :: UnitWind ! Unit number for the InflowWind input file - INTEGER(B2Ki) :: Dum_Int2 - - !------------------------------------------------------------------------------------------------- - ! Initialize temporary variables - !------------------------------------------------------------------------------------------------- - - ErrMsg = '' - ErrStat = ErrID_None - - ParamData%FF%InterpTower = .false. - ParamData%FF%AddMeanAfterInterp = .false. - - - ! Get a unit number to use - - CALL GetNewUnit(UnitWind, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Copy things from the InitData to the ParamData - !------------------------------------------------------------------------------------------------- - - !---------------------------------------------------------------------------------------------- - ! Open the binary file, read its "header" (first 2-byte integer) to determine what format - ! binary file it is, and close it. - !---------------------------------------------------------------------------------------------- - - CALL OpenBInpFile (UnitWind, TRIM(InitData%WindFileName), TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - ! Read the first binary integer from the file to get info on the type. - ! Cannot use library read routines since this is a 2-byte integer. - READ ( UnitWind, IOSTAT=TmpErrStat ) Dum_Int2 - CLOSE( UnitWind ) - - IF (TmpErrStat /= 0) THEN - CALL SetErrStat(ErrID_Fatal,' Error reading first binary integer from file "'//TRIM(InitData%WindFileName)//'."', & - ErrStat,ErrMsg,RoutineName) - RETURN - ENDIF - - - !---------------------------------------------------------------------------------------------- - ! Read the files to get the required FF data. - !---------------------------------------------------------------------------------------------- - - ! Store the binary format information so the InflowWind code can use it. - ! Also changes to IntKi from INT(2) to compare in the SELECT below - ParamData%FF%WindFileFormat = Dum_Int2 - - SELECT CASE (ParamData%FF%WindFileFormat) - - CASE ( 7, 8 ) ! TurbSim binary format - - CALL Read_TurbSim_FF(UnitWind, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CLOSE ( UnitWind ) - RETURN - END IF - - - CASE DEFAULT - CALL SetErrStat( ErrID_Fatal, ' Error: This is not a TurbSim binary wind file type (binary format identifier: '// & - TRIM(Num2LStr(ParamData%FF%WindFileFormat))//'. This might be a Bladed style binary wind file.', & - ErrStat, ErrMsg, RoutineName ) - RETURN - - END SELECT - - - IF (ParamData%FF%Periodic) THEN - ParamData%FF%InitXPosition = 0 ! start at the hub - ParamData%FF%TotalTime = ParamData%FF%NFFSteps*ParamData%FF%FFDTime - ELSE - ParamData%FF%InitXPosition = ParamData%FF%FFYHWid ! start half the grid width ahead of the turbine - ParamData%FF%TotalTime = (ParamData%FF%NFFSteps-1)*ParamData%FF%FFDTime - ENDIF - - - !------------------------------------------------------------------------------------------------- - ! Set the InitOutput information - !------------------------------------------------------------------------------------------------- - - InitOutdata%Ver = IfW_TSFFWind_Ver - - - - RETURN - - - CONTAINS - - !==================================================================================================== - !> This subroutine reads the binary TurbSim-format FF file (.bts). It fills the FFData array with - !! velocity data for the grids and fills the FFTower array with velocities at points on the tower - !! (if data exists). - !! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 - SUBROUTINE Read_TurbSim_FF(UnitWind, ErrStat, ErrMsg) - !---------------------------------------------------------------------------------------------------- - - CHARACTER(*), PARAMETER :: RoutineName="READ_TurbSim_FF" - - - ! Passed Variables: - - INTEGER(IntKi), INTENT(IN ) :: UnitWind !< unit number for the wind file - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status return value (0=no error; non-zero is error) - CHARACTER(*), INTENT( OUT) :: ErrMsg !< message about the error encountered - - ! Local Variables: - - REAL(SiKi) :: Dum_Real4 ! dummy 4-byte real number - INTEGER(B1Ki) :: Dum_Int1 ! dummy 1-byte integer - INTEGER(B2Ki) :: Dum_Int2 ! dummy 2-byte integer - INTEGER(B4Ki) :: Dum_Int4 ! dummy 4-byte integer - - INTEGER(IntKi) :: IC ! loop counter for wind components - INTEGER(IntKi) :: IT ! loop counter for time - INTEGER(IntKi) :: IY ! loop counter for y - INTEGER(IntKi) :: IZ ! loop counter for z - INTEGER(IntKi) :: NChar ! number of characters in the description string - - REAL(SiKi) :: Vslope(3) ! slope for "un-normalizing" data - REAL(SiKi) :: Voffset(3) ! offset for "un-normalizing" data - - LOGICAL :: FirstWarn ! we don't need to print warning for each character that exceeds the - CHARACTER(1024) :: DescStr ! description string contained in the file - - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - ParamData%FF%NFFComp = 3 ! this file contains 3 wind components - ErrStat = ErrID_None - ErrMsg = "" - - !------------------------------------------------------------------------------------------------- - ! Open the file - !------------------------------------------------------------------------------------------------- - - CALL OpenBInpFile (UnitWind, TRIM(InitData%WindFileName), TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - !------------------------------------------------------------------------------------------------- - ! Read the header information - !------------------------------------------------------------------------------------------------- - ! Read in the 2-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! the file identifier, INT(2) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading the file identifier in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%Periodic = Dum_Int2 == INT( 8, B2Ki) ! the number 7 is used for non-periodic wind files; 8 is periodic wind - - - ! Read in the 4-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! the number of grid points vertically, INT(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading the number of z grid points in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%NZGrids = Dum_Int4 - - - ! Read in the 4-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! the number of grid points laterally, INT(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading the number of y grid points in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%NYGrids = Dum_Int4 - - - ! Read in the 4-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! the number of tower points, INT(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading the number of tower points in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%NTGrids = Dum_Int4 - - - ! Read in the 4-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! the number of time steps, INT(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading the number of time steps in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%NFFSteps = Dum_Int4 - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! grid spacing in vertical direction (dz), REAL(4), in m - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dz in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%InvFFZD = 1.0/Dum_Real4 ! 1/dz - ParamData%FF%FFZHWid = 0.5*(ParamData%FF%NZGrids-1)*Dum_Real4 ! half the grid height - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! grid spacing in lateral direction (dy), REAL(4), in m - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dy in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%InvFFYD = 1.0 / Dum_Real4 ! 1/dy - ParamData%FF%FFYHWid = 0.5*(ParamData%FF%NYGrids-1)*Dum_Real4 ! half grid grid width - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! grid spacing in time (dt), REAL(4), in m/s - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading dt in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%FFDTime = Dum_Real4 - ParamData%FF%FFRate = 1.0/ParamData%FF%FFDTime - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! the mean wind speed at hub height, REAL(4), in m/s - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading mean wind speed in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%MeanFFWS = Dum_Real4 - ParamData%FF%InvMFFWS = 1.0 / ParamData%FF%MeanFFWS - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! height of the hub, REAL(4), in m - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading zHub in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%RefHt = Dum_Real4 - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Real4 ! height of the bottom of the grid, REAL(4), in m - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading GridBase in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ParamData%FF%GridBase = Dum_Real4 - - ! ZGOffset = ParamData%FF%RefHt - ParamData%FF%GridBase - ParamData%FF%FFZHWid - - - !---------------------------------------------------------------------------------------------- - ! Read the binary scaling factors - !---------------------------------------------------------------------------------------------- - - DO IC = 1,ParamData%FF%NFFComp - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Vslope(IC) ! the IC-component slope for scaling, REAL(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading Vslope('//Num2LStr(IC)//') in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - - ! Read in the 4-byte real. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Voffset(IC) ! the IC-component offset for scaling, REAL(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading Voffset('//Num2LStr(IC)//') in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ENDDO !IC - - - !---------------------------------------------------------------------------------------------- - ! Read the description string: "Generated by TurbSim (vx.xx, dd-mmm-yyyy) on dd-mmm-yyyy at hh:mm:ss." - !---------------------------------------------------------------------------------------------- - - ! Read in the 4-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int4 ! the number of characters in the description string, max 200, INT(4) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading NCHAR in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - nchar = Dum_Int4 - - DescStr = '' ! Initialize the description string - FirstWarn = .true. - - DO IC=1,nchar - - ! Read in the 1-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int1 ! the ASCII integer representation of the character, INT(1) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading description line in the FF binary file "'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - IF ( LEN(DescStr) >= IC ) THEN - DescStr(IC:IC) = ACHAR( Dum_Int1 ) ! converted ASCII characters - ELSEIF ( FirstWarn ) THEN - FirstWarn = .FALSE. - CALL SetErrStat( ErrID_Info, ' Description string was too long for variable.'//TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - ENDIF - - ENDDO !IC - - - !------------------------------------------------------------------------------------------------- - ! Get the grid and tower velocities - !------------------------------------------------------------------------------------------------- - - ! this could take a while, so we'll write a message indicating what's going on: - - CALL WrScr( NewLine//' Reading a '//TRIM( Num2LStr(ParamData%FF%NYGrids) )//'x'//TRIM( Num2LStr(ParamData%FF%NZGrids) )// & - ' grid ('//TRIM( Num2LStr(ParamData%FF%FFYHWid*2) )//' m wide, '// & - TRIM( Num2LStr(ParamData%FF%GridBase) )//' m to '// & - TRIM( Num2LStr(ParamData%FF%GridBase+ParamData%FF%FFZHWid*2) )//& - ' m above ground) with a characteristic wind speed of '// & - TRIM( Num2LStr(ParamData%FF%MeanFFWS) )//' m/s. '//TRIM(DescStr) ) - - - !---------------------------------------------------------------------------------------------- - ! Allocate arrays for the FF grid as well as the tower points, if they exist - !---------------------------------------------------------------------------------------------- - - IF ( .NOT. ALLOCATED( ParamData%FF%FFData ) ) THEN - CALL AllocAry( ParamData%FF%FFData, ParamData%FF%NZGrids, ParamData%FF%NYGrids, ParamData%FF%NFFComp, ParamData%FF%NFFSteps, & - 'Full-field wind data array.', TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - ENDIF - - - IF ( ParamData%FF%NTGrids > 0 ) THEN - - IF ( .NOT. ALLOCATED( ParamData%FF%FFTower ) ) THEN - CALL AllocAry( ParamData%FF%FFTower, ParamData%FF%NFFComp, ParamData%FF%NTGrids, ParamData%FF%NFFSteps, & - 'Tower wind file data array.', TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - ENDIF - - ENDIF - - !------------------------------------------------------------------------------------------------- - ! Read the 16-bit data and scale it to 32-bit reals - !------------------------------------------------------------------------------------------------- - - ! Loop through time. - - DO IT=1,ParamData%FF%NFFSteps - - !........................................................................................... - ! Read grid data at this time step. - !........................................................................................... - - DO IZ=1,ParamData%FF%NZGrids - ! Zgrid(IZ) = Z1 + (IZ-1)*dz ! Vertical location of grid data point, in m relative to ground - - DO IY=1,ParamData%FF%NYGrids - ! Ygrid(IY) = -0.5*(ny-1)*dy + (IY-1)*dy ! Horizontal location of grid data point, in m relative to tower centerline - - DO IC=1,ParamData%FF%NFFComp ! number of wind components (U, V, W) - - ! Read in the 2-byte integer. Can't use library read routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! normalized wind-component, INT(2) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading grid wind components in the FF binary file "'// & - TRIM( InitData%WindFileName )//'."', ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ParamData%FF%FFData(IZ,IY,IC,IT) = ( Dum_Int2 - Voffset(IC) ) / VSlope(IC) - - ENDDO !IC - - ENDDO !IY - - ENDDO ! IZ - - - !........................................................................................... - ! Read the tower data at this time step. - !........................................................................................... - - DO IZ=1,ParamData%FF%NTGrids ! If NTGrids<1, there are no tower points & FFTower is not allocated - - ! Ytower = 0 ! Lateral location of the tower data point, in m relative to tower centerline - ! Ztower(IZ) = Z1 - (IZ-1)*dz ! Vertical location of tower data point, in m relative to ground - - DO IC=1,ParamData%FF%NFFComp ! number of wind components - - ! Read in a 2-byte integer. Can't use library routines for this. - READ (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 ! normalized wind-component, INT(2) - IF ( TmpErrStat /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, ' Error reading tower wind components in the FF binary file "'//TRIM(InitData%WindFileName)//'."'& - , ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ParamData%FF%FFTower(IC,IZ,IT) = ( Dum_Int2 - Voffset(IC) ) / VSlope(IC) ! wind-component scaled to m/s - - ENDDO !IC - - ENDDO ! IZ - - - ENDDO ! IT - - !------------------------------------------------------------------------------------------------- - ! close the file and return - !------------------------------------------------------------------------------------------------- - - CLOSE ( UnitWind ) - - IF ( ParamData%FF%Periodic ) THEN - TmpErrMsg = ' Processed '//TRIM( Num2LStr( ParamData%FF%NFFSteps ) )//' time steps of '// & - TRIM( Num2LStr ( ParamData%FF%FFRate ) )//'-Hz full-field data (period of '// & - TRIM( Num2LStr( ParamData%FF%FFDTime*( ParamData%FF%NFFSteps ) ) )//' seconds).' - ELSE - TmpErrMsg = ' Processed '//TRIM( Num2LStr( ParamData%FF%NFFSteps ) )//' time steps of '// & - TRIM( Num2LStr ( ParamData%FF%FFRate ) )//'-Hz full-field data ('// & - TRIM( Num2LStr( ParamData%FF%FFDTime*( ParamData%FF%NFFSteps - 1 ) ) )//' seconds).' - ENDIF - - CALL WrScr( NewLine//TRIM(TmpErrMsg) ) ! Note: the TmpErrMsg gets used below for the summary file - - - - !------------------------------------------------------------------------------------------------- - ! Write to the summary file - !------------------------------------------------------------------------------------------------- - - IF ( InitData%SumFileUnit > 0 ) THEN - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) 'TurbSim wind type. Read by InflowWind sub-module '//TRIM(IfW_TSFFWind_Ver%Name)// & - ' '//TRIM(IfW_TSFFWind_Ver%Ver) - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) TRIM(TmpErrMsg) - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' FileName: '//TRIM(InitData%WindFileName) - WRITE(InitData%SumFileUnit,'(A34,I3)', IOSTAT=TmpErrStat) ' Binary file format id: ',ParamData%FF%WindFileFormat - WRITE(InitData%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Reference height (m): ',ParamData%FF%RefHt - WRITE(InitData%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Timestep (s): ',ParamData%FF%FFDTime - WRITE(InitData%SumFileUnit,'(A34,I12)', IOSTAT=TmpErrStat) ' Number of timesteps: ',ParamData%FF%NFFSteps - WRITE(InitData%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Mean windspeed (m/s): ',ParamData%FF%MeanFFWS - WRITE(InitData%SumFileUnit,'(A34,L1)', IOSTAT=TmpErrStat) ' Windfile is periodic: ',ParamData%FF%Periodic - WRITE(InitData%SumFileUnit,'(A34,L1)', IOSTAT=TmpErrStat) ' Windfile includes tower: ',ParamData%FF%NTGrids > 0 - - IF ( ParamData%FF%Periodic ) THEN - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Time range (s): [ '// & - TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(ParamData%FF%TotalTime))//' ]' - ELSE ! Shift the time range to compensate for the shifting of the wind grid - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Time range (s): [ '// & - TRIM(Num2LStr(-ParamData%FF%InitXPosition*ParamData%FF%InvMFFWS))//' : '// & - TRIM(Num2LStr(ParamData%FF%TotalTime-ParamData%FF%InitXPosition*ParamData%FF%InvMFFWS))//' ]' - ENDIF - - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Y range (m): [ '// & - TRIM(Num2LStr(-ParamData%FF%FFYHWid))//' : '//TRIM(Num2LStr(ParamData%FF%FFYHWid))//' ]' - - IF ( ParamData%FF%NTGrids > 0 ) THEN - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Z range (m): [ '// & - TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(ParamData%FF%RefHt + ParamData%FF%FFZHWid))//' ]' - ELSE - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Z range (m): [ '// & - TRIM(Num2LStr(ParamData%FF%RefHt - ParamData%FF%FFZHWid))//' : '//TRIM(Num2LStr(ParamData%FF%RefHt + ParamData%FF%FFZHWid))//' ]' - ENDIF - - - ! We are assuming that if the last line was written ok, then all of them were. - IF (TmpErrStat /= 0_IntKi) THEN - CALL SetErrStat(ErrID_Fatal,'Error writing to summary file.',ErrStat,ErrMsg,RoutineName) - RETURN - ENDIF - ENDIF - - - RETURN - - END SUBROUTINE READ_TurbSim_FF - - END SUBROUTINE IfW_TSFFWind_Init -!==================================================================================================== - - -!==================================================================================================== -!> This routine computes the wind speed at each of the PositionXYZ points. -SUBROUTINE IfW_TSFFWind_CalcOutput(Time, PositionXYZ, p, Velocity, DiskVel, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - - CHARACTER(*), PARAMETER :: RoutineName="IfW_TSFFWind_CalcOutput" - - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_TSFFWind_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - REAL(ReKi), INTENT( OUT) :: DiskVel(3) !< HACK for AD14: disk velocity output at Time - TYPE(IfW_TSFFWind_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - - - CALL IfW_FFWind_CalcOutput(Time, PositionXYZ, p%FF, Velocity, DiskVel, ErrStat, ErrMsg) - - - RETURN - -END SUBROUTINE IfW_TSFFWind_CalcOutput -!==================================================================================================== -!> This subroutine cleans up any data that is still allocated. The (possibly) open files are -!! closed in InflowWindMod. -!! -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE IfW_TSFFWind_End( p, m, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_TSFFWind_End" - - - - ! Passed Variables - TYPE(IfW_TSFFWind_ParameterType), INTENT(INOUT) :: p !< Parameters - TYPE(IfW_TSFFWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Local Variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !-=- Initialize the routine -=- - - ErrMsg = '' - ErrStat = ErrID_None - - - - ! Destroy parameter data - - CALL IfW_TSFFWind_DestroyParam( p, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - - - ! Destroy the misc data - - CALL IfW_TSFFWind_DestroyMisc( m, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - - - -END SUBROUTINE IfW_TSFFWind_End - -!==================================================================================================== -END MODULE IfW_TSFFWind diff --git a/modules/inflowwind/src/IfW_TSFFWind.txt b/modules/inflowwind/src/IfW_TSFFWind.txt deleted file mode 100644 index 71b9e9c75..000000000 --- a/modules/inflowwind/src/IfW_TSFFWind.txt +++ /dev/null @@ -1,33 +0,0 @@ -################################################################################################################################### -# Registry for IfW_TSFFWind, creates MODULE IfW_TSFFWind_Types -# Module IfW_TSFFWind_Types contains all of the user-defined types needed in IfW_TSFFWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - -include Registry_NWTC_Library.txt -usefrom IfW_FFWind_Base.txt - - -######################### - -typedef IfW_TSFFWind/IfW_TSFFWind InitInputType CHARACTER(1024) WindFileName - - - "Name of the wind file to use" - -typedef ^ ^ IntKi SumFileUnit - - - "Unit number for the summary file (-1 for none). Provided by IfW." - - - -# Init Output -typedef ^ InitOutputType ProgDesc Ver - - - "Version information off FFWind submodule" - - - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType IntKi dummy - 0 - "An Index into the TData array" - - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType IfW_FFWind_ParameterType FF - - - "Parameters used in all full-field wind types" - - diff --git a/modules/inflowwind/src/IfW_TSFFWind_Types.f90 b/modules/inflowwind/src/IfW_TSFFWind_Types.f90 deleted file mode 100644 index e3fe8d918..000000000 --- a/modules/inflowwind/src/IfW_TSFFWind_Types.f90 +++ /dev/null @@ -1,738 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_TSFFWind_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_TSFFWind_Types -!................................................................................................................................. -! This file is part of IfW_TSFFWind. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_TSFFWind. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_TSFFWind_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE IfW_FFWind_Base_Types -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_TSFFWind_InitInputType ======= - TYPE, PUBLIC :: IfW_TSFFWind_InitInputType - CHARACTER(1024) :: WindFileName !< Name of the wind file to use [-] - INTEGER(IntKi) :: SumFileUnit !< Unit number for the summary file (-1 for none). Provided by IfW. [-] - END TYPE IfW_TSFFWind_InitInputType -! ======================= -! ========= IfW_TSFFWind_InitOutputType ======= - TYPE, PUBLIC :: IfW_TSFFWind_InitOutputType - TYPE(ProgDesc) :: Ver !< Version information off FFWind submodule [-] - END TYPE IfW_TSFFWind_InitOutputType -! ======================= -! ========= IfW_TSFFWind_MiscVarType ======= - TYPE, PUBLIC :: IfW_TSFFWind_MiscVarType - INTEGER(IntKi) :: dummy = 0 !< An Index into the TData array [-] - END TYPE IfW_TSFFWind_MiscVarType -! ======================= -! ========= IfW_TSFFWind_ParameterType ======= - TYPE, PUBLIC :: IfW_TSFFWind_ParameterType - TYPE(IfW_FFWind_ParameterType) :: FF !< Parameters used in all full-field wind types [-] - END TYPE IfW_TSFFWind_ParameterType -! ======================= -CONTAINS - SUBROUTINE IfW_TSFFWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_TSFFWind_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_TSFFWind_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%WindFileName = SrcInitInputData%WindFileName - DstInitInputData%SumFileUnit = SrcInitInputData%SumFileUnit - END SUBROUTINE IfW_TSFFWind_CopyInitInput - - SUBROUTINE IfW_TSFFWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) - TYPE(IfW_TSFFWind_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_DestroyInitInput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_TSFFWind_DestroyInitInput - - SUBROUTINE IfW_TSFFWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName - Int_BufSz = Int_BufSz + 1 ! SumFileUnit - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO I = 1, LEN(InData%WindFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = InData%SumFileUnit - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_TSFFWind_PackInitInput - - SUBROUTINE IfW_TSFFWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - DO I = 1, LEN(OutData%WindFileName) - OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%SumFileUnit = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_TSFFWind_UnPackInitInput - - SUBROUTINE IfW_TSFFWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_TSFFWind_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(IfW_TSFFWind_InitOutputType), INTENT(INOUT) :: DstInitOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_CopyInitOutput' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_TSFFWind_CopyInitOutput - - SUBROUTINE IfW_TSFFWind_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) - TYPE(IfW_TSFFWind_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_DestroyInitOutput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) - END SUBROUTINE IfW_TSFFWind_DestroyInitOutput - - SUBROUTINE IfW_TSFFWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_InitOutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_TSFFWind_PackInitOutput - - SUBROUTINE IfW_TSFFWind_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_TSFFWind_UnPackInitOutput - - SUBROUTINE IfW_TSFFWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_TSFFWind_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(IfW_TSFFWind_MiscVarType), INTENT(INOUT) :: DstMiscData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_CopyMisc' -! - ErrStat = ErrID_None - ErrMsg = "" - DstMiscData%dummy = SrcMiscData%dummy - END SUBROUTINE IfW_TSFFWind_CopyMisc - - SUBROUTINE IfW_TSFFWind_DestroyMisc( MiscData, ErrStat, ErrMsg ) - TYPE(IfW_TSFFWind_MiscVarType), INTENT(INOUT) :: MiscData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_DestroyMisc' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_TSFFWind_DestroyMisc - - SUBROUTINE IfW_TSFFWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_MiscVarType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_PackMisc' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! dummy - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IntKiBuf(Int_Xferred) = InData%dummy - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_TSFFWind_PackMisc - - SUBROUTINE IfW_TSFFWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_MiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_UnPackMisc' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%dummy = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_TSFFWind_UnPackMisc - - SUBROUTINE IfW_TSFFWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_TSFFWind_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_TSFFWind_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL IfW_FFWind_CopyParam( SrcParamData%FF, DstParamData%FF, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_TSFFWind_CopyParam - - SUBROUTINE IfW_TSFFWind_DestroyParam( ParamData, ErrStat, ErrMsg ) - TYPE(IfW_TSFFWind_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_DestroyParam' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL IfW_FFWind_DestroyParam( ParamData%FF, ErrStat, ErrMsg ) - END SUBROUTINE IfW_TSFFWind_DestroyParam - - SUBROUTINE IfW_TSFFWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! FF: size of buffers for each call to pack subtype - CALL IfW_FFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, .TRUE. ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! FF - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! FF - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! FF - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL IfW_FFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, OnlySize ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_TSFFWind_PackParam - - SUBROUTINE IfW_TSFFWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_TSFFWind_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_TSFFWind_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_FFWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%FF, ErrStat2, ErrMsg2 ) ! FF - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_TSFFWind_UnPackParam - -END MODULE IfW_TSFFWind_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_UniformWind.f90 b/modules/inflowwind/src/IfW_UniformWind.f90 deleted file mode 100644 index 1bcc76d27..000000000 --- a/modules/inflowwind/src/IfW_UniformWind.f90 +++ /dev/null @@ -1,1121 +0,0 @@ -!> This module contains all the data and procedures that define uniform wind files (formerly known as -!! hub-height files). This could more accurately be called a point wind file since the wind speed at -!! any point is calculated by shear applied to the point where wind is defined. It is basically uniform -!! wind over the rotor disk. The entire file is read on initialization, then the columns that make up -!! the wind file are interpolated to the time requested, and wind is calculated based on the location -!! in space. -!! -!! the file contains header information (rows that contain "!"), followed by numeric data stored in -!! 9 columns (if only 8 are listed, Upflow is assumed to be 0): -!! |Column | Description | Variable Name | Units| -!! |-------|-----------------------------|---------------|------| -!! | 1 | Time | Time | [s] | -!! | 2 | Horizontal wind speed | V | [m/s]| -!! | 3 | Wind direction | Delta | [deg]| -!! | 4 | Vertical wind speed | VZ | [m/s]| -!! | 5 | Horizontal linear shear | HLinShr | [-] | -!! | 6 | Vertical power-law shear | VShr | [-] | -!! | 7 | Vertical linear shear | VLinShr | [-] | -!! | 8 | Gust (horizontal) velocity | VGust | [m/s]| -!! | 9 | Upflow angle | Upflow | [deg]| -!! -!! The horizontal wind speed at (X, Y, Z) is then calculated using the interpolated columns by \n -!! \f{eqnarray}{ V_h & = & V \, \left( \frac{Z}{Z_{Ref}} \right) ^ {VShr} & \mbox{power-law wind shear} \\ -!! & + & V \, \frac{H_{LinShr}}{RefWid} \, \left( Y \cos(Delta) + X \sin(Delta) \right) & \mbox{horizontal linear shear} \\ -!! & + & V \, \frac{V_{LinShr}}{RefWid} \, \left( Z-Z_{Ref} \right) & \mbox{vertical linear shear} \\ -!! & + & V_{Gust} & \mbox{gust speed} -!! \f} -MODULE IfW_UniformWind -!---------------------------------------------------------------------------------------------------- -!! Feb 2013 v2.00.00 A. Platt -!! -- updated to the new framework -!! -- Note: Jacobians are not included in this version. -!! -!! Feb 2015 v2.01.00 A. Platt -!! -- Further updates to the new framework -!! -- name change from 'hub-height wind files' to 'Uniform wind files'. -!! -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2015-2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - - USE NWTC_Library - USE IfW_UniformWind_Types - - IMPLICIT NONE - PRIVATE - - TYPE(ProgDesc), PARAMETER :: IfW_UniformWind_Ver = ProgDesc( 'IfW_UniformWind', '', '' ) - - PUBLIC :: IfW_UniformWind_Init - PUBLIC :: IfW_UniformWind_End - PUBLIC :: IfW_UniformWind_CalcOutput - PUBLIC :: IfW_UniformWind_JacobianPInput - PUBLIC :: IfW_UniformWind_GetOP - - PUBLIC :: Uniform_to_FF - -CONTAINS - -!==================================================================================================== - -!---------------------------------------------------------------------------------------------------- -!> A subroutine to initialize the UniformWind module. It reads the uniform wind file and stores the data in an -!! array to use later. It requires an initial reference height (hub height) and width (rotor diameter), -!! both in meters, which are used to define the volume where wind velocities will be calculated. This -!! information is necessary because of the way the shears are defined. -!! -!! @note This routine does not conform to the framework. The InputType has been replaced with just -!! the PositionXYZ array. -!! @date 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -!---------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_UniformWind_Init(InitData, ParamData, MiscVars, InitOutData, ErrStat, ErrMsg) - - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_UniformWind_Init" - - - ! Passed Variables - TYPE(IfW_UniformWind_InitInputType), INTENT(IN ) :: InitData !< Input data for initialization - TYPE(IfW_UniformWind_ParameterType), INTENT( OUT) :: ParamData !< Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - TYPE(IfW_UniformWind_InitOutputType), INTENT( OUT) :: InitOutData !< Initial output - - - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< A message about the error - - ! local variables - - INTEGER(IntKi), PARAMETER :: MaxNumCols = 9 ! maximum number of columns in the Uniform file - INTEGER(IntKi) :: NumCols ! Number of columns in the Uniform file - REAL(ReKi) :: TmpData(MaxNumCols) ! Temp variable for reading all columns from a line - INTEGER(IntKi) :: LineNo - REAL(ReKi) :: DelDiff ! Temp variable for storing the direction difference - - INTEGER(IntKi) :: I - INTEGER(IntKi) :: ILine ! Counts the line number in the file - INTEGER(IntKi), PARAMETER :: MaxTries = 100 - TYPE(FileInfoType) :: InFileInfo !< The derived type for holding the full input file for parsing -- we may pass this in the future - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! Temp variable for the error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !------------------------------------------------------------------------------------------------- - ! Set the Error handling variables - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = "" - - !------------------------------------------------------------------------------------------------- - ! Check that it's not already initialized - !------------------------------------------------------------------------------------------------- - - IF ( MiscVars%TimeIndex /= 0 ) THEN - CALL SetErrStat(ErrID_Warn,' UniformWind has already been initialized.',ErrStat,ErrMsg,RoutineName) - RETURN - END IF - - !------------------------------------------------------------------------------------------------- - ! Copy things from the InitData to the ParamData - !------------------------------------------------------------------------------------------------- - - ParamData%RefHt = InitData%ReferenceHeight - ParamData%RefLength = InitData%RefLength - - ! Read in the data from a file, or copy from the passed InFileInfo. After this, the InFileInfo - ! should contain only a table -- all comments and empty lines have been stripped out - IF ( InitData%UseInputFile ) THEN - CALL ProcessComFile( InitData%WindFileName, InFileInfo, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - ELSE - CALL NWTC_Library_CopyFileInfoType( InitData%PassedFileData, InFileInfo, MESH_NEWCOPY, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - ENDIF - - ! For diagnostic purposes, the following can be used to display the contents - ! of the InFileInfo data structure. - ! call Print_FileInfo_Struct( CU, InFileInfo ) ! CU is the screen -- different number on different systems. - - - !------------------------------------------------------------------------------------------------- - ! Allocate the data arrays - !------------------------------------------------------------------------------------------------- - - ParamData%NumDataLines = InFileInfo%NumLines - CALL Alloc_ParamDataArrays( ParamData, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Store the data arrays - !------------------------------------------------------------------------------------------------- - - ! Check if 9 columns - NumCols = MaxNumCols - LineNo = 1 ! Start at begining - CALL ParseAry( InFileInfo, LineNo, "Wind type 2 line", TmpData(1:NumCols), NumCols, TmpErrStat, TmpErrMsg ) - if (TmpErrStat /= 0) then - ! assume the upflow is 0 and try reading the rest of the files - CALL SetErrStat(ErrID_Info,' Could not read upflow column in uniform wind files. Assuming upflow is 0.', ErrStat, ErrMsg, RoutineName) - NumCols = NumCols - 1 - end if - - - ! Parse the data and store it - LineNo = 1 - DO I=1,ParamData%NumDataLines - CALL ParseAry( InFileInfo, LineNo, "Wind type 2 file line", TmpData(1:NumCols), NumCols, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - - ParamData%Tdata( I) = TmpData(1) - ParamData%V( I) = TmpData(2) - ParamData%Delta( I) = TmpData(3)*D2R - ParamData%VZ( I) = TmpData(4) - ParamData%HShr( I) = TmpData(5) - ParamData%VShr( I) = TmpData(6) - ParamData%VLinShr(I) = TmpData(7) - ParamData%VGust( I) = TmpData(8) - - if (NumCols > 8) ParamData%Upflow( I) = TmpData(9)*D2R - END DO !I - - - - !------------------------------------------------------------------------------------------------- - ! Make sure the wind direction isn't jumping more than 180 degrees between any 2 consecutive - ! input times. (Avoids interpolation errors with modular arithemetic.) - !------------------------------------------------------------------------------------------------- - - DO I=2,ParamData%NumDataLines - - ILine = 1 - - DO WHILE ( ILine < MaxTries ) - - DelDiff = ( ParamData%Delta(I) - ParamData%Delta(I-1) ) - - IF ( ABS( DelDiff ) < Pi ) EXIT ! exit inner loop - - ParamData%Delta(I) = ParamData%Delta(I) - SIGN( TwoPi, DelDiff ) - - ILine = ILine + 1 - - END DO - - IF ( ILine >= MaxTries ) THEN - TmpErrMsg= ' Error calculating wind direction from uniform wind file. ParamData%Delta(' & - // TRIM(Num2LStr(I )) // ') = ' // TRIM(Num2LStr(ParamData%Delta(I))) // '; ParamData%Delta(' & - // TRIM(Num2LStr(I+1)) // ') = ' // TRIM(Num2LStr(ParamData%Delta(I+1))) - CALL SetErrStat(ErrID_Fatal,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - END IF - - - END DO !I - - !------------------------------------------------------------------------------------------------- - ! Find out information on the timesteps and range - !------------------------------------------------------------------------------------------------- - - ! Uniform timesteps - IF ( ParamData%NumDataLines > 3 ) THEN - - InitOutData%WindFileConstantDT = .TRUE. - InitOutData%WindFileDT = ParamData%Tdata(2) - ParamData%Tdata(1) - - DO I=3,ParamData%NumDataLines - - IF ( .NOT. EqualRealNos( (ParamData%Tdata(I ) - ParamData%Tdata(I-1) ), REAL(InitOutData%WindFileDT,ReKi )) ) THEN - InitOutData%WindFileConstantDT = .FALSE. - EXIT - END IF - - END DO !I - - ELSE - - ! There aren't enough points to check, so report that the timesteps are not uniform - InitOutData%WindFileConstantDT = .FALSE. - InitOutData%WindFileDT = 0.0_ReKi - - END IF - - - ! Time range - InitOutData%WindFileTRange(1) = ParamData%Tdata(1) - InitOutData%WindFileTRange(2) = ParamData%Tdata(ParamData%NumDataLines) - - ! Number of timesteps - InitOutData%WindFileNumTSteps = ParamData%NumDataLines - - !------------------------------------------------------------------------------------------------- - ! Print warnings and messages - !------------------------------------------------------------------------------------------------- - ! CALL WrScr( ' Processed '//TRIM( Num2LStr( ParamData%NumDataLines ) )//' records of uniform wind data from '''// & - ! TRIM(ADJUSTL(InitData%WindFileName))//'''') - - - IF ( ParamData%Tdata(1) > 0.0 ) THEN - TmpErrMsg= 'The uniform wind file : "'//TRIM(ADJUSTL(InitData%WindFileName))// & - '" starts at a time '//'greater than zero. Interpolation errors may result.' - CALL SetErrStat(ErrID_Warn,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - ENDIF - - IF ( ParamData%NumDataLines == 1 ) THEN - TmpErrMsg= ' Only 1 line in uniform wind file. Steady, horizontal wind speed at the hub height is '// & - TRIM(Num2LStr(ParamData%V(1)))//' m/s.' - CALL SetErrStat(ErrID_Info,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - END IF - - - - !------------------------------------------------------------------------------------------------- - ! Write to the summary file - !------------------------------------------------------------------------------------------------- - - IF ( InitData%SumFileUnit > 0 ) THEN - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) 'Uniform wind. Module '//TRIM(IfW_UniformWind_Ver%Name)// & - ' '//TRIM(IfW_UniformWind_Ver%Ver) - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' FileName: '//TRIM(InitData%WindFileName) - WRITE(InitData%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Reference height (m): ',ParamData%RefHt - WRITE(InitData%SumFileUnit,'(A34,G12.4)',IOSTAT=TmpErrStat) ' Reference length (m): ',ParamData%RefLength - WRITE(InitData%SumFileUnit,'(A32,I8)', IOSTAT=TmpErrStat) ' Number of data lines: ',ParamData%NumDataLines - WRITE(InitData%SumFileUnit,'(A)', IOSTAT=TmpErrStat) ' Time range (s): [ '// & - TRIM(Num2LStr(InitOutData%WindFileTRange(1)))//' : '//TRIM(Num2LStr(InitOutData%WindFileTRange(2)))//' ]' - - ! We are assuming that if the last line was written ok, then all of them were. - IF (TmpErrStat /= 0_IntKi) THEN - CALL SetErrStat(ErrID_Fatal,'Error writing to summary file.',ErrStat,ErrMsg,RoutineName) - RETURN - ENDIF - ENDIF - - - - !------------------------------------------------------------------------------------------------- - ! Set the initial index into the time array (it indicates that we've initialized the module, too) - ! and initialize the spatial scaling for the wind calculations - !------------------------------------------------------------------------------------------------- - - MiscVars%TimeIndex = 1 - - - !------------------------------------------------------------------------------------------------- - ! Set the InitOutput information - !------------------------------------------------------------------------------------------------- - - InitOutdata%Ver = IfW_UniformWind_Ver - - - RETURN - -END SUBROUTINE IfW_UniformWind_Init - -SUBROUTINE Alloc_ParamDataArrays( ParamData, ErrStat, ErrMsg ) - - IMPLICIT NONE - CHARACTER(*), PARAMETER :: RoutineName="Alloc_ParamDataArrays" - - TYPE(IfW_UniformWind_ParameterType), INTENT(INOUT) :: ParamData !< Parameters - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< A message about the error - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! Temp variable for the error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! Temporary error message - - ErrStat = ErrID_None - ErrMsg = "" - - !------------------------------------------------------------------------------------------------- - ! Allocate arrays for the uniform wind data - !------------------------------------------------------------------------------------------------- - ! BJJ note: If the subroutine AllocAry() is called, the CVF compiler with A2AD does not work - ! properly. The arrays are not properly read even though they've been allocated. - ! ADP note: the above note may or may not apply after conversion to the modular framework in 2013 - !------------------------------------------------------------------------------------------------- - - IF (.NOT. ALLOCATED(ParamData%Tdata) ) THEN - CALL AllocAry( ParamData%Tdata, ParamData%NumDataLines, 'Uniform wind time', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%V) ) THEN - CALL AllocAry( ParamData%V, ParamData%NumDataLines, 'Uniform wind horizontal wind speed', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%Delta) ) THEN - CALL AllocAry( ParamData%Delta, ParamData%NumDataLines, 'Uniform wind direction', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%VZ) ) THEN - CALL AllocAry( ParamData%VZ, ParamData%NumDataLines, 'Uniform vertical wind speed', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%HShr) ) THEN - CALL AllocAry( ParamData%HShr, ParamData%NumDataLines, 'Uniform horizontal linear shear', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%VShr) ) THEN - CALL AllocAry( ParamData%VShr, ParamData%NumDataLines, 'Uniform vertical power-law shear exponent', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%VLinShr) ) THEN - CALL AllocAry( ParamData%VLinShr, ParamData%NumDataLines, 'Uniform vertical linear shear', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%VGust) ) THEN - CALL AllocAry( ParamData%VGust, ParamData%NumDataLines, 'Uniform gust velocity', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - - IF (.NOT. ALLOCATED(ParamData%Upflow) ) THEN - CALL AllocAry( ParamData%Upflow, ParamData%NumDataLines, 'Uniform wind upflow', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) RETURN - END IF - ParamData%Upflow = 0.0_ReKi - -END SUBROUTINE Alloc_ParamDataArrays - -!==================================================================================================== - -!------------------------------------------------------------------------------------------------- -!> This routine and its subroutines calculate the wind velocity at a set of points given in -!! PositionXYZ. The UVW velocities are returned in Velocity -!! -!! @note This routine does not satisfy the Modular framework. -!! @date 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -!------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_UniformWind_CalcOutput(Time, PositionXYZ, p, Velocity, DiskVel, m, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_UniformWind_CalcOutput" - - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - REAL(ReKi), INTENT( OUT) :: DiskVel(3) !< HACK for AD14: disk velocity output at Time - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - - ! local variables - INTEGER(IntKi) :: NumPoints ! Number of points specified by the PositionXYZ array - TYPE(IfW_UniformWind_Intrp) :: op ! interpolated values of InterpParams - INTEGER(IntKi) :: PointNum ! a loop counter for the current point - - ! temporary variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - - !------------------------------------------------------------------------------------------------- - ! Initialize some things - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = "" - - ! The array is transposed so that the number of points is the second index, x/y/z is the first. - ! This is just in case we only have a single point, the SIZE command returns the correct number of points. - NumPoints = SIZE(PositionXYZ,DIM=2) - - - !------------------------------------------------------------------------------------------------- - !> 1. Linearly interpolate parameters in time (or use nearest-neighbor to extrapolate) - !! (compare with nwtc_num::interpstpreal) - !------------------------------------------------------------------------------------------------- - CALL InterpParams(Time, p, m, op) - - ! Step through all the positions and get the velocities - !$OMP PARALLEL default(shared) if(NumPoints>1000) - !$OMP do private(PointNum, TmpErrStat, TmpErrMsg ) schedule(runtime) - DO PointNum = 1, NumPoints - - ! Calculate the velocity for the position - call GetWindSpeed(PositionXYZ(:,PointNum), p, op, Velocity(:,PointNum), TmpErrStat, TmpErrMsg) - - ! Error handling - !CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF (TmpErrStat >= AbortErrLev) THEN - TmpErrMsg= trim(TmpErrMsg)//" Error calculating the wind speed at position ("// & - TRIM(Num2LStr(PositionXYZ(1,PointNum)))//", "// & - TRIM(Num2LStr(PositionXYZ(2,PointNum)))//", "// & - TRIM(Num2LStr(PositionXYZ(3,PointNum)))//") in the wind-file coordinates" - !$OMP CRITICAL ! Needed to avoid data race on ErrStat and ErrMsg - ErrStat = ErrID_None - ErrMsg = "" - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - !$OMP END CRITICAL - ENDIF - - ENDDO - !$OMP END DO - !$OMP END PARALLEL - - IF (ErrStat >= AbortErrLev) RETURN ! Return cannot be in parallel loop - - ! DiskVel term -- this represents the average across the disk -- sort of. This changes for AeroDyn 15 - DiskVel = WindInf_ADhack_diskVel(Time, p, m, TmpErrStat, TmpErrMsg) - - RETURN - -END SUBROUTINE IfW_UniformWind_CalcOutput -!+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -!> This subroutine linearly interpolates the parameters that are used to compute uniform -!! wind. -SUBROUTINE InterpParams(Time, p, m, op) - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables (index) - - TYPE(IfW_UniformWind_Intrp) , INTENT( OUT) :: op !< interpolated V values at input TIME - - - ! Local Variables - REAL(ReKi) :: slope ! temporary storage for slope (in time) used in linear interpolation - - - !------------------------------------------------------------------------------------------------- - ! Linearly interpolate in time (or used nearest-neighbor to extrapolate) - ! (compare with NWTC_Num.f90\InterpStpReal) - !------------------------------------------------------------------------------------------------- - - ! Let's check the limits. - IF ( Time <= p%Tdata(1) .OR. p%NumDataLines == 1 ) THEN - - m%TimeIndex = 1 - op%V = p%V (1) - op%Delta = p%Delta (1) - op%Upflow = p%Upflow (1) - op%VZ = p%VZ (1) - op%HShr = p%HShr (1) - op%VShr = p%VShr (1) - op%VLinShr = p%VLinShr(1) - op%VGust = p%VGust (1) - - ELSE IF ( Time >= p%Tdata(p%NumDataLines) ) THEN - - m%TimeIndex = p%NumDataLines - 1 - op%V = p%V (p%NumDataLines) - op%Delta = p%Delta (p%NumDataLines) - op%Upflow = p%Upflow (p%NumDataLines) - op%VZ = p%VZ (p%NumDataLines) - op%HShr = p%HShr (p%NumDataLines) - op%VShr = p%VShr (p%NumDataLines) - op%VLinShr = p%VLinShr(p%NumDataLines) - op%VGust = p%VGust (p%NumDataLines) - - ELSE - - ! Let's interpolate! Linear interpolation. - m%TimeIndex = MAX( MIN( m%TimeIndex, p%NumDataLines-1 ), 1 ) - - DO - - IF ( Time < p%Tdata(m%TimeIndex) ) THEN - - m%TimeIndex = m%TimeIndex - 1 - - ELSE IF ( Time >= p%Tdata(m%TimeIndex+1) ) THEN - - m%TimeIndex = m%TimeIndex + 1 - - ELSE - slope = ( Time - p%Tdata(m%TimeIndex) )/( p%Tdata(m%TimeIndex+1) - p%Tdata(m%TimeIndex) ) - - op%V = ( p%V( m%TimeIndex+1) - p%V( m%TimeIndex) )*slope + p%V( m%TimeIndex) - op%Delta = ( p%Delta( m%TimeIndex+1) - p%Delta( m%TimeIndex) )*slope + p%Delta( m%TimeIndex) - op%Upflow = ( p%Upflow( m%TimeIndex+1) - p%Upflow( m%TimeIndex) )*slope + p%Upflow( m%TimeIndex) - op%VZ = ( p%VZ( m%TimeIndex+1) - p%VZ( m%TimeIndex) )*slope + p%VZ( m%TimeIndex) - op%HShr = ( p%HShr( m%TimeIndex+1) - p%HShr( m%TimeIndex) )*slope + p%HShr( m%TimeIndex) - op%VShr = ( p%VShr( m%TimeIndex+1) - p%VShr( m%TimeIndex) )*slope + p%VShr( m%TimeIndex) - op%VLinShr = ( p%VLinShr(m%TimeIndex+1) - p%VLinShr(m%TimeIndex) )*slope + p%VLinShr(m%TimeIndex) - op%VGust = ( p%VGust( m%TimeIndex+1) - p%VGust( m%TimeIndex) )*slope + p%VGust( m%TimeIndex) - EXIT - - END IF - - END DO - - END IF -END SUBROUTINE InterpParams - -!+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -!> This subroutine linearly interpolates the columns in the uniform input file to get the values for -!! the requested time, then uses the interpolated values to calclate the wind speed at a point -!! in space represented by InputPosition. -!! -!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -SUBROUTINE GetWindSpeed(InputPosition, p, op, WindSpeed, ErrStat, ErrMsg) - - ! Passed Variables - REAL(ReKi), INTENT(IN ) :: InputPosition(3) !< input information: positions X,Y,Z - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(IfW_UniformWind_Intrp), INTENT(IN ) :: op !< operating point values; interpolated UniformWind parameters for this time (for glue-code linearization operating point) - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - ! Returned variables - REAL(ReKi), INTENT( OUT) :: WindSpeed(3) !< return velocities (U,V,W) - - ! Local Variables - REAL(ReKi) :: CosDelta ! cosine of y%Delta - REAL(ReKi) :: SinDelta ! sine of y%Delta - REAL(ReKi) :: V1 ! temporary storage for horizontal velocity - REAL(ReKi) :: V1_rotate ! temporary storage for rotated horizontal velocity - REAL(ReKi) :: VZ_rotate ! temporary storage for rotated vertical velocity - - REAL(ReKi) :: CosUpflow ! cosine of y%Upflow - REAL(ReKi) :: SinUpflow ! sine of y%Upflow - - ErrStat = ErrID_None - ErrMsg = "" - - - - !------------------------------------------------------------------------------------------------- - !> 2. Calculate the wind speed at this time (if z<0, return an error): - !------------------------------------------------------------------------------------------------- - - if ( InputPosition(3) <= 0.0_ReKi ) then - if (.not. EqualRealNos(InputPosition(3), 0.0_ReKi) ) call SetErrStat(ErrID_Severe,'Height must not be negative.',ErrStat,ErrMsg,'GetWindSpeed') - WindSpeed = 0.0 - return - end if - - !> Let \f{eqnarray}{ V_h & = & V \, \left( \frac{Z}{Z_{ref}} \right) ^ {V_{shr}} & \mbox{power-law wind shear} \\ - !! & + & V \, \frac{H_{LinShr}}{RefWid} \, \left( Y \cos(Delta) + X \sin(Delta) \right) & \mbox{horizontal linear shear} \\ - !! & + & V \, \frac{V_{LinShr}}{RefWid} \, \left( Z - Z_{ref} \right) & \mbox{vertical linear shear} \\ - !! & + & V_{Gust} & \mbox{gust speed} - !! \f} Then the returned wind speed, \f$Vt\f$, is \n - !! \f$Vt_u = V_h \, \cos(Delta) \f$ \n - !! \f$Vt_v = -V_h \, \sin(Delta) \f$ \n - !! \f$Vt_w = V_z \f$ \n using input positions \f$X,Y,Z\f$ and interpolated values for time-dependent input-file parameters - !! \f$V, Delta, V_z, H_{LinShr}, V_{Shr}, V_{LinShr}, V_{Gust}\f$. - - CosDelta = COS( op%Delta ) - SinDelta = SIN( op%Delta ) - V1 = op%V * ( ( InputPosition(3)/p%RefHt ) ** op%VShr & ! power-law wind shear - + ( op%HShr * ( InputPosition(2) * CosDelta + InputPosition(1) * SinDelta ) & ! horizontal linear shear - + op%VLinShr * ( InputPosition(3) - p%RefHt ) )/p%RefLength ) & ! vertical linear shear - + op%VGust ! gust speed - - ! convert global to local: Global wind = R(op%Delta) * R(op%Upflow) * [local wind] = R(op%Delta) * R(op%Upflow) * [V1, 0, op%VZ] - - ! apply upflow angle: - CosUpflow = COS( op%Upflow ) - SinUpflow = SIN( op%Upflow ) - V1_rotate = CosUpflow*V1 - SinUpflow*op%VZ - VZ_rotate = SinUpflow*V1 + CosUpflow*op%VZ - - ! apply wind direction: - WindSpeed(1) = V1_rotate * CosDelta - WindSpeed(2) = -V1_rotate * SinDelta - WindSpeed(3) = VZ_rotate - - - RETURN - -END SUBROUTINE GetWindSpeed - -FUNCTION RotateWindSpeed(Vh, Vz, Delta, Upflow) - REAL(ReKi) :: Vh ! horizontal wind speed - REAL(ReKi) :: Vz ! vertical wind speed - REAL(ReKi) :: Delta ! wind direction - REAL(ReKi) :: Upflow ! upflow angle - - REAL(R8Ki) :: CosDelta ! cosine of y%Delta - REAL(R8Ki) :: SinDelta ! sine of y%Delta - REAL(R8Ki) :: V1_rotate ! temporary storage for rotated horizontal velocity - REAL(R8Ki) :: VZ_rotate ! temporary storage for rotated vertical velocity - - REAL(R8Ki) :: CosUpflow ! cosine of y%Upflow - REAL(R8Ki) :: SinUpflow ! sine of y%Upflow - - - REAL(R8Ki) :: RotateWindSpeed(3) - - - ! apply upflow angle: - CosUpflow = COS( REAL(Upflow,R8Ki) ) - SinUpflow = SIN( REAL(Upflow,R8Ki) ) - - V1_rotate = CosUpflow*Vh - SinUpflow*Vz - Vz_rotate = SinUpflow*Vh + CosUpflow*Vz - - - ! apply wind direction: - CosDelta = COS( REAL(Delta,R8Ki) ) - SinDelta = SIN( REAL(Delta,R8Ki) ) - - RotateWindSpeed(1) = V1_rotate * CosDelta - RotateWindSpeed(2) = -V1_rotate * SinDelta - RotateWindSpeed(3) = Vz_rotate - -END FUNCTION RotateWindSpeed - - -!> This function should be deleted ASAP. Its purpose is to reproduce results of AeroDyn 12.57; -!! when a consensus on the definition of "average velocity" is determined, this function will be -!! removed. -FUNCTION WindInf_ADhack_diskVel( t, p, m,ErrStat, ErrMsg ) - - ! Passed variables - - REAL(DbKi), INTENT(IN ) :: t !< Time - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: m !< misc/optimization data (storage for efficiency index) - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status from this function - CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message from this function - - ! Function definition - REAL(ReKi) :: WindInf_ADhack_diskVel(3) - - ! Local variables - TYPE(IfW_UniformWind_Intrp) :: op ! interpolated values of InterpParams - - - ErrStat = ErrID_None - ErrMsg = "" - - !------------------------------------------------------------------------------------------------- - ! Linearly interpolate in time (or use nearest-neighbor to extrapolate) - ! (compare with NWTC_Num.f90\InterpStpReal) - !------------------------------------------------------------------------------------------------- - - call InterpParams(t, p, m, op) - - !------------------------------------------------------------------------------------------------- - ! calculate the wind speed at this time (note that it is not the full uniform wind equation!) - !------------------------------------------------------------------------------------------------- - WindInf_ADhack_diskVel = RotateWindSpeed(op%V, op%VZ, op%Delta, op%Upflow) - - RETURN - -END FUNCTION WindInf_ADhack_diskVel - - -!==================================================================================================== -!> This routine closes any open files and clears all data stored in UniformWind derived Types -!! -!! @note This routine does not satisfy the Modular framework. The InputType is not used, rather -!! an array of points is passed in. -!! @date: 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -!---------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_UniformWind_End( ParamData, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_UniformWind_End" - - - ! Passed Variables - TYPE(IfW_UniformWind_ParameterType), INTENT(INOUT) :: ParamData !< Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Local Variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !-=- Initialize the routine -=- - - ErrMsg = '' - ErrStat = ErrID_None - - - - ! Destroy parameter data - - CALL IfW_UniformWind_DestroyParam( ParamData, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - ! Destroy the state data - - CALL IfW_UniformWind_DestroyMisc( MiscVars, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - ! reset time index so we know the module is no longer initialized - - MiscVars%TimeIndex = 0 - -END SUBROUTINE IfW_UniformWind_End -!.................................................................................................................................. -!> Routine to compute the Jacobians of the output (Y) function with respect to the inputs (u). The partial -!! derivative dY/du is returned. This submodule does not follow the modularization framework. -SUBROUTINE IfW_UniformWind_JacobianPInput( t, Position, CosPropDir, SinPropDir, p, m, dYdu ) - - REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds - REAL(ReKi), INTENT(IN ) :: Position(3) !< XYZ Position at which to find velocity (operating point) - REAL(ReKi), INTENT(IN ) :: CosPropDir !< cosine of InflowWind propagation direction - REAL(ReKi), INTENT(IN ) :: SinPropDir !< sine of InflowWind propagation direction - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - REAL(R8Ki), INTENT(INOUT) :: dYdu(3,6) !< Partial derivatives of output functions - !! (Y) with respect to the inputs (u) - - ! local variables: - !INTEGER(IntKi) :: ErrStat2 - !CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary error message - !CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_JacobianPInput' - - ! Local Variables - TYPE(IfW_UniformWind_Intrp) :: op ! interpolated values of InterpParams - REAL(R8Ki) :: CosDelta ! cosine of Delta_tmp - REAL(R8Ki) :: SinDelta ! sine of Delta_tmp - REAL(R8Ki) :: RotatePosition(3) !< rotated position - - REAL(R8Ki) :: dVhdx ! temporary value to hold partial v_h partial X - REAL(R8Ki) :: dVhdy ! temporary value to hold partial v_h partial Y - REAL(R8Ki) :: dVhdz ! temporary value to hold partial v_h partial Z - REAL(R8Ki) :: tmp_du ! temporary value to hold calculations that are part of multiple components - REAL(R8Ki) :: tmp_dv ! temporary value to hold calculations that are part of multiple components - REAL(R8Ki) :: dVhdPD ! temporary value to hold partial v_h partial propagation direction - REAL(R8Ki) :: dVhdV ! temporary value to hold partial v_h partial V - REAL(R8Ki) :: Vh ! temporary value to hold v_h - REAL(R8Ki) :: dVhdVShr ! temporary value to hold partial v_h partial VShr - REAL(R8Ki) :: zr - - - - - if ( Position(3) < 0.0_ReKi .or. EqualRealNos(Position(3), 0.0_ReKi)) then - dYdu = 0.0_R8Ki - RETURN - end if - - !------------------------------------------------------------------------------------------------- - !> 1. Linearly interpolate parameters in time at operating point (or use nearest-neighbor to extrapolate) - !! (compare with nwtc_num::interpstpreal) - !------------------------------------------------------------------------------------------------- - CALL InterpParams(t, p, m, op) - - CosDelta = COS( real(op%Delta,R8Ki) ) - SinDelta = SIN( real(op%Delta,R8Ki) ) - - RotatePosition(1) = Position(1)*cosPropDir - Position(2)*sinPropDir - RotatePosition(2) = Position(1)*sinPropDir + Position(2)*cosPropDir - RotatePosition(3) = Position(3) - - - !------------------------------------------------------------------------------------------------- - !> 2. Calculate \f$ \frac{\partial Y_{Output \, Equations}}{\partial u_{inputs}} = \begin{bmatrix} - !! \frac{\partial Vt_u}{\partial X} & \frac{\partial Vt_u}{\partial Y} & \frac{\partial Vt_u}{\partial Z} \\ - !! \frac{\partial Vt_v}{\partial X} & \frac{\partial Vt_v}{\partial Y} & \frac{\partial Vt_v}{\partial Z} \\ - !! \frac{\partial Vt_w}{\partial X} & \frac{\partial Vt_w}{\partial Y} & \frac{\partial Vt_w}{\partial Z} \\ - !! \end{bmatrix} \f$ - !------------------------------------------------------------------------------------------------- - zr = RotatePosition(3)/p%RefHt - tmp_du = op%V * op%HShr /p%RefLength * CosPropDir - dVhdx = tmp_du * SinDelta - dVhdy = tmp_du * CosDelta - dVhdz = op%V * ( op%VShr / p%RefHt * zr**(op%VShr-1.0_R8Ki) + op%VLinShr/p%RefLength) - - dVhdV = ( ( RotatePosition(3)/p%RefHt ) ** op%VShr & ! power-law wind shear - + ( op%HShr * ( RotatePosition(2) * CosDelta + RotatePosition(1) * SinDelta ) & ! horizontal linear shear - + op%VLinShr * ( RotatePosition(3) - p%RefHt ) )/p%RefLength ) ! vertical linear shear - Vh = op%V * dVhdV + op%Vgust - - dVhdVShr = op%V * zr**op%VShr * log(zr) - dVhdPD = op%V * op%HShr / p%RefLength * ( RotatePosition(1) * CosDelta - RotatePosition(2) * SinDelta ) - - tmp_du = CosPropDir*CosDelta - SinPropDir*SinDelta - tmp_dv = -SinPropDir*CosDelta - CosPropDir*SinDelta - - - !> \f$ \frac{\partial Vt_u}{\partial X} = \left[\cos(PropagationDir)\cos(Delta) - \sin(PropagationDir)\sin(Delta) \right] - !! V \, \frac{H_{LinShr}}{RefWid} \, \sin(Delta) \cos(PropagationDir) \f$ - dYdu(1,1) = tmp_du*dVhdx - - !> \f$ \frac{\partial Vt_v}{\partial X} = \left[-\sin(PropagationDir)\cos(Delta) - \cos(PropagationDir)\sin(Delta) \right] - !! V \, \frac{H_{LinShr}}{RefWid} \, \sin(Delta) \cos(PropagationDir) \f$ - dYdu(2,1) = tmp_dv*dVhdx - - !> \f$ \frac{\partial Vt_w}{\partial X} = 0 \f$ - dYdu(3,1) = 0.0_R8Ki - - - !> \f$ \frac{\partial Vt_u}{\partial Y} = \left[\cos(PropagationDir)\cos(Delta) - \sin(PropagationDir)\sin(Delta) \right] - !! V \, \frac{H_{LinShr}}{RefWid} \, \cos(Delta) \cos(PropagationDir) \f$ - dYdu(1,2) = tmp_du*dVhdy - - !> \f$ \frac{\partial Vt_v}{\partial Y} = \left[-\sin(PropagationDir)\cos(Delta) - \cos(PropagationDir)\sin(Delta) \right] - !! V \, \frac{H_{LinShr}}{RefWid} \, \cos(Delta) \cos(PropagationDir) \f$ - dYdu(2,2) = tmp_dv*dVhdy - - !> \f$ \frac{\partial Vt_w}{\partial Y} = 0 \f$ - dYdu(3,2) = 0.0_R8Ki - - - !> \f$ \frac{\partial Vt_u}{\partial Z} = \left[\cos(PropagationDir)\cos(Delta) - \sin(PropagationDir)\sin(Delta) \right] - !! V \, \left[ \frac{V_{shr}}{Z_{ref}} \left( \frac{Z}{Z_{ref}} \right) ^ {V_{shr}-1} + \frac{V_{LinShr}}{RefWid} \right] \f$ - dYdu(1,3) = tmp_du*dVhdz - - !> \f$ \frac{\partial Vt_v}{\partial Z} = \left[-\sin(PropagationDir)\cos(Delta) - \cos(PropagationDir)\sin(Delta) \right] - !! V \, \left[ \frac{V_{shr}}{Z_{ref}} \left( \frac{Z}{Z_{ref}} \right) ^ {V_{shr}-1} + \frac{V_{LinShr}}{RefWid} \right] \f$ - dYdu(2,3) = tmp_dv*dVhdz - - !> \f$ \frac{\partial Vt_w}{\partial Z} = 0 \f$ - dYdu(3,3) = 0.0_R8Ki - - - - ! \f$ \frac{\partial Vt_u}{\partial V} = \f$ - dYdu(1,4) = tmp_du*dVhdV - ! \f$ \frac{\partial Vt_v}{\partial V} = \f$ - dYdu(2,4) = tmp_dv*dVhdV - !> \f$ \frac{\partial Vt_w}{\partial V} = 0 \f$ - dYdu(3,4) = 0.0_R8Ki - - - ! \f$ \frac{\partial Vt_u}{\partial VShr} = \f$ - dYdu(1,5) = tmp_du*dVhdVShr - ! \f$ \frac{\partial Vt_v}{\partial VShr} = \f$ - dYdu(2,5) = tmp_dv*dVhdVShr - !> \f$ \frac{\partial Vt_w}{\partial VShr} = 0 \f$ - dYdu(3,5) = 0.0_R8Ki - - ! \f$ \frac{\partial Vt_u}{\partial PropDir} = \f$ - dYdu(1,6) = tmp_dv*Vh + tmp_du*dVhdPD - ! \f$ \frac{\partial Vt_v}{\partial PropDir} = \f$ - dYdu(2,6) = -tmp_du*Vh + tmp_dv*dVhdPD - !> \f$ \frac{\partial Vt_w}{\partial PropDir} = 0 \f$ - dYdu(3,6) = 0.0_R8Ki - - RETURN - -END SUBROUTINE IfW_UniformWind_JacobianPInput -!.................................................................................................................................. -!> Routine to compute the Jacobians of the output (Y) function with respect to the inputs (u). The partial -!! derivative dY/du is returned. This submodule does not follow the modularization framework. -SUBROUTINE IfW_UniformWind_GetOP( t, p, m, OP_out ) - - REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds - REAL(ReKi), INTENT( OUT) :: OP_out(2) !< operating point (HWindSpeed and PLexp - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - - ! Local Variables - TYPE(IfW_UniformWind_Intrp) :: op ! interpolated values of InterpParams - - - !------------------------------------------------------------------------------------------------- - !> 1. Linearly interpolate parameters in time at operating point (or use nearest-neighbor to extrapolate) - !! (compare with nwtc_num::interpstpreal) - !------------------------------------------------------------------------------------------------- - CALL InterpParams(t, p, m, op) - - OP_out(1) = op%V - OP_out(2) = op%VSHR - - RETURN - -END SUBROUTINE IfW_UniformWind_GetOP - - -!==================================================================================================== -SUBROUTINE Uniform_to_FF(p, m, p_ff, ErrStat, ErrMsg) - - USE IfW_FFWind_Base - - TYPE(IfW_UniformWind_ParameterType), INTENT(IN ) :: p !< UniformWind Parameters - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) - TYPE(IfW_FFWind_ParameterType), INTENT( OUT) :: p_ff !< FF Parameters - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message - - ! local variables - REAL(DbKi) :: Time !< time from the start of the simulation - REAL(ReKi) :: PositionXYZ(3,1) !< Array of XYZ coordinates, 3xN - REAL(ReKi) :: Velocity(3,1) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - REAL(ReKi) :: DiskVel(3) !< HACK for AD14: disk velocity output at Time - REAL(ReKi) :: n - - INTEGER(ReKi) , parameter :: dz = 5.0 - INTEGER(ReKi) , parameter :: dy = 5.0 - INTEGER(ReKi) :: i - INTEGER(ReKi) :: it - INTEGER(ReKi) :: iy - INTEGER(ReKi) :: iz - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), parameter :: RoutineName = 'Uniform_to_FF' - - ErrStat = ErrID_None - ErrMsg = "" - - p_ff%WindFileFormat = -1 ! "Binary file format description number" - - p_ff%NFFComp = 3 ! "Number of wind components" - - p_ff%Periodic = .false. - p_ff%InterpTower = .true. - p_ff%RefHt = p%RefHt - p_ff%NTGrids = 0 - p_ff%InvFFYD = 1.0_ReKi / dy ! "reciprocal of delta y" 1/meters - p_ff%InvFFZD = 1.0_ReKi / dz ! "reciprocal of delta z" 1/meters - - ! add roughly 10% to the width - n = NINT( p%RefLength*1.1_ReKi*0.5_ReKi / dy ) - p_ff%NYGrids = n*2+1 ! "Number of points in the lateral (y) direction of the grids" - - p_ff%FFYHWid = 0.5_ReKi * dy * (p_ff%NYGrids-1) ! "Half the grid width" meters - - n = NINT( p%RefLength*1.1_ReKi*0.5_ReKi / dz ) - p_ff%NZGrids = INT( p_ff%RefHt / dy ) + n + 1 ! "Number of points in the vertical (z) direction of the grids" - - - p_ff%FFZHWid = 0.5_ReKi * dz * (p_ff%NZGrids -1) ! "Half the grid height" meters - p_ff%GridBase = p_ff%RefHt + n*dz - p_ff%FFZHWid*2.0_ReKi ! "the height of the bottom of the grid" meters - - p_ff%InitXPosition = 0.0_ReKi ! "the initial x position of grid (distance in FF is offset)" meters - - - ! time will be the smallest delta t in this Uniform wind file - if (p%NumDataLines < 2) then - p_ff%FFDTime = 600.0_ReKi ! doesn't matter what the time step is - else - p_ff%FFDTime = HUGE(p_ff%FFDTime) ! "Delta time" seconds - do i=2,p%NumDataLines - p_ff%FFDTime = min(p_ff%FFDTime, p%TData(i) - p%TData(i-1)) - end do - - if (p_ff%FFDTime < 0.0001) then - call SetErrStat( ErrID_Fatal, "Smallest time step in uniform wind file is less that 0.0001 seconds. Increase the time step "//& - " to convert to a FF file.", ErrStat, ErrMsg, RoutineName ) - return - end if - - end if - - p_ff%FFRate = 1.0_ReKi / p_ff%FFDTime ! "Data rate (1/FFDTime)" Hertz - - - p_ff%AddMeanAfterInterp = .FALSE. ! "Add the mean wind speed after interpolating at a given height?" - - p_ff%WindProfileType = WindProfileType_PL ! "Wind profile type (0=constant;1=logarithmic;2=power law)" - - p_ff%PLExp = GetAverageVal(p%VSHR) ! "Power law exponent (used for PL wind profile type only)" - - p_ff%Z0 = 0.0_ReKi ! "Surface roughness length (used for LOG wind profile type only)" - - - if (p%NumDataLines < 2) then - p_ff%NFFSteps = 2 ! "Number of time steps in the FF array" - - else - p_ff%NFFSteps = NINT(p%TData(p%NumDataLines) / p_ff%FFDTime) + 1 - end if - - p_ff%TotalTime = (p_ff%NFFSteps-1) * p_ff%FFDTime ! "The total time of the simulation" seconds - - - call AllocAry( p_ff%FFData, p_ff%NZGrids,p_ff%NYGrids,p_ff%NFFComp, p_ff%NFFSteps, 'p%FF%FFData', ErrStat2, ErrMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if (ErrStat >= AbortErrLev) return - - PositionXYZ = 0.0_ReKi - do it = 1,p_ff%NFFSteps - Time = (it-1)*p_ff%FFDTime - - do iy = 1,p_ff%NYGrids - PositionXYZ(2,1) = (iy-1)*dy - p_ff%FFYHWid - - do iz=1,p_ff%NZGrids - PositionXYZ(3,1) = (iz-1)*dz + p_ff%GridBase - - call IfW_UniformWind_CalcOutput(Time, PositionXYZ, p, Velocity, DiskVel, m, ErrStat2, ErrMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - p_ff%FFData(iz,iy,:,it) = Velocity(:,1) - - end do ! iz - end do ! iy - end do ! it - - ! compute some averages for this simulation - p_ff%MeanFFWS = GetAverageVal(p%V) ! "Mean wind speed (advection speed)" - p_ff%InvMFFWS = 1.0_ReKi / p_ff%MeanFFWS - - RETURN - -CONTAINS - - FUNCTION GetAverageVal(Ary) RESULT(Avg) - REAL(ReKi), intent(in) :: Ary(:) - REAL(ReKi) :: Avg - - if (p%NumDataLines < 2) then - Avg = Ary(1) - else - Avg = p%TData(1) * Ary(1) ! in case tData(1)/=0 - do i=2,p%NumDataLines - Avg = Avg + (p%TData(i)-p%TData(i-1)) * (Ary(i)+Ary(i-1))/2.0_ReKi - end do - Avg = Avg / (p%TData(p%NumDataLines)-p%TData(1)) - end if - - END FUNCTION GetAverageVal - -END SUBROUTINE Uniform_to_FF -!==================================================================================================== - -!==================================================================================================== -END MODULE IfW_UniformWind diff --git a/modules/inflowwind/src/IfW_UniformWind.txt b/modules/inflowwind/src/IfW_UniformWind.txt deleted file mode 100644 index df99ddd79..000000000 --- a/modules/inflowwind/src/IfW_UniformWind.txt +++ /dev/null @@ -1,67 +0,0 @@ -################################################################################################################################### -# Registry for IfW_UniformWind, creates MODULE IfW_UniformWind_Types -# Module IfW_UniformWind_Types contains all of the user-defined types needed in IfW_UniformWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - -include Registry_NWTC_Library.txt - - -######################### - -typedef IfW_UniformWind/IfW_UniformWind InitInputType CHARACTER(1024) WindFileName - - - "Name of the wind file to use" - -typedef ^ ^ ReKi ReferenceHeight - - - "Hub height of the turbine" meters -typedef ^ ^ ReKi RefLength - - - "RefLength of the wind field to use" meters -typedef ^ ^ IntKi SumFileUnit - - - "Unit number for the summary file (-1 for none). Provided by IfW." - -typedef ^ ^ LOGICAL UseInputFile - .TRUE. - "Flag for toggling file based IO in wind type 2." - -typedef ^ ^ FileInfoType PassedFileData - - - "Optional slot for wind type 2 data if file IO is not used." - - - - -# Init Output -typedef ^ InitOutputType ProgDesc Ver - - - "Version information off HHWind submodule" - -typedef ^ ^ DbKi WindFileDT - - - "TimeStep of the wind file -- zero value for none" seconds -typedef ^ ^ ReKi WindFileTRange {2} - - "Time range of the wind file" seconds -typedef ^ ^ IntKi WindFileNumTSteps - - - "Number of timesteps in the time range of wind file" - -typedef ^ ^ LOGICAL WindFileConstantDT - - - "Timesteps are the same throughout file" - - - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType IntKi TimeIndex - 0 - "An Index into the TData array" - - - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType ReKi TData : - - "Time array from the HH file" seconds -typedef ^ ^ ReKi DELTA : - - "HH Wind direction (angle)" degrees -typedef ^ ^ ReKi Upflow : - - "HH upflow angle" degrees -typedef ^ ^ ReKi V : - - "HH horizontal wind speed" meters/sec -typedef ^ ^ ReKi VZ : - - "wind, including tower shadow, along the Z axis" meters/sec -typedef ^ ^ ReKi HSHR : - - "HH Horizontal linear shear" - -typedef ^ ^ ReKi VSHR : - - "HH vertical shear exponent" - -typedef ^ ^ ReKi VLINSHR : - - "HH vertical linear shear" - -typedef ^ ^ ReKi VGUST : - - "HH wind gust" - -typedef ^ ^ ReKi RefHt - - - "reference height; was HH (hub height); used to center the wind" meters -typedef ^ ^ ReKi RefLength - - - "reference length used to scale the linear shear" meters -typedef ^ ^ IntKi NumDataLines - - - "" - - -# ..... Input (dummy type for extrap/interp routine) ................................................................................................................ -#typedef ^ InputType SiKi dummy - - - "dummy type because we need extrap/interp routine if we put the below outputs in the InflowWind type" - -# ..... Output (for extended AD inputs in linearization) ................................................................................................................ -typedef ^ IfW_UniformWind_Intrp ReKi DELTA - - - "HH Wind direction (angle)" degrees -typedef ^ ^ ReKi Upflow - - - "HH upflow angle" degrees -typedef ^ ^ ReKi V - - - "HH horizontal wind speed" meters/sec -typedef ^ ^ ReKi VZ - - - "wind, including tower shadow, along the Z axis" meters/sec -typedef ^ ^ ReKi HSHR - - - "HH Horizontal linear shear" - -typedef ^ ^ ReKi VSHR - - - "HH vertical shear exponent" - -typedef ^ ^ ReKi VLINSHR - - - "HH vertical linear shear" - -typedef ^ ^ ReKi VGUST - - - "HH wind gust" - - - diff --git a/modules/inflowwind/src/IfW_UniformWind_Types.f90 b/modules/inflowwind/src/IfW_UniformWind_Types.f90 deleted file mode 100644 index 8c344bd7c..000000000 --- a/modules/inflowwind/src/IfW_UniformWind_Types.f90 +++ /dev/null @@ -1,1484 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_UniformWind_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_UniformWind_Types -!................................................................................................................................. -! This file is part of IfW_UniformWind. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_UniformWind. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_UniformWind_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_UniformWind_InitInputType ======= - TYPE, PUBLIC :: IfW_UniformWind_InitInputType - CHARACTER(1024) :: WindFileName !< Name of the wind file to use [-] - REAL(ReKi) :: ReferenceHeight !< Hub height of the turbine [meters] - REAL(ReKi) :: RefLength !< RefLength of the wind field to use [meters] - INTEGER(IntKi) :: SumFileUnit !< Unit number for the summary file (-1 for none). Provided by IfW. [-] - LOGICAL :: UseInputFile = .TRUE. !< Flag for toggling file based IO in wind type 2. [-] - TYPE(FileInfoType) :: PassedFileData !< Optional slot for wind type 2 data if file IO is not used. [-] - END TYPE IfW_UniformWind_InitInputType -! ======================= -! ========= IfW_UniformWind_InitOutputType ======= - TYPE, PUBLIC :: IfW_UniformWind_InitOutputType - TYPE(ProgDesc) :: Ver !< Version information off HHWind submodule [-] - REAL(DbKi) :: WindFileDT !< TimeStep of the wind file -- zero value for none [seconds] - REAL(ReKi) , DIMENSION(1:2) :: WindFileTRange !< Time range of the wind file [seconds] - INTEGER(IntKi) :: WindFileNumTSteps !< Number of timesteps in the time range of wind file [-] - LOGICAL :: WindFileConstantDT !< Timesteps are the same throughout file [-] - END TYPE IfW_UniformWind_InitOutputType -! ======================= -! ========= IfW_UniformWind_MiscVarType ======= - TYPE, PUBLIC :: IfW_UniformWind_MiscVarType - INTEGER(IntKi) :: TimeIndex = 0 !< An Index into the TData array [-] - END TYPE IfW_UniformWind_MiscVarType -! ======================= -! ========= IfW_UniformWind_ParameterType ======= - TYPE, PUBLIC :: IfW_UniformWind_ParameterType - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TData !< Time array from the HH file [seconds] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: DELTA !< HH Wind direction (angle) [degrees] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Upflow !< HH upflow angle [degrees] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: V !< HH horizontal wind speed [meters/sec] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VZ !< wind, including tower shadow, along the Z axis [meters/sec] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: HSHR !< HH Horizontal linear shear [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VSHR !< HH vertical shear exponent [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VLINSHR !< HH vertical linear shear [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: VGUST !< HH wind gust [-] - REAL(ReKi) :: RefHt !< reference height; was HH (hub height); used to center the wind [meters] - REAL(ReKi) :: RefLength !< reference length used to scale the linear shear [meters] - INTEGER(IntKi) :: NumDataLines !< [-] - END TYPE IfW_UniformWind_ParameterType -! ======================= -! ========= IfW_UniformWind_Intrp ======= - TYPE, PUBLIC :: IfW_UniformWind_Intrp - REAL(ReKi) :: DELTA !< HH Wind direction (angle) [degrees] - REAL(ReKi) :: Upflow !< HH upflow angle [degrees] - REAL(ReKi) :: V !< HH horizontal wind speed [meters/sec] - REAL(ReKi) :: VZ !< wind, including tower shadow, along the Z axis [meters/sec] - REAL(ReKi) :: HSHR !< HH Horizontal linear shear [-] - REAL(ReKi) :: VSHR !< HH vertical shear exponent [-] - REAL(ReKi) :: VLINSHR !< HH vertical linear shear [-] - REAL(ReKi) :: VGUST !< HH wind gust [-] - END TYPE IfW_UniformWind_Intrp -! ======================= -CONTAINS - SUBROUTINE IfW_UniformWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_UniformWind_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%WindFileName = SrcInitInputData%WindFileName - DstInitInputData%ReferenceHeight = SrcInitInputData%ReferenceHeight - DstInitInputData%RefLength = SrcInitInputData%RefLength - DstInitInputData%SumFileUnit = SrcInitInputData%SumFileUnit - DstInitInputData%UseInputFile = SrcInitInputData%UseInputFile - CALL NWTC_Library_Copyfileinfotype( SrcInitInputData%PassedFileData, DstInitInputData%PassedFileData, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_UniformWind_CopyInitInput - - SUBROUTINE IfW_UniformWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_DestroyInitInput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedFileData, ErrStat, ErrMsg ) - END SUBROUTINE IfW_UniformWind_DestroyInitInput - - SUBROUTINE IfW_UniformWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UniformWind_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName - Re_BufSz = Re_BufSz + 1 ! ReferenceHeight - Re_BufSz = Re_BufSz + 1 ! RefLength - Int_BufSz = Int_BufSz + 1 ! SumFileUnit - Int_BufSz = Int_BufSz + 1 ! UseInputFile - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! PassedFileData: size of buffers for each call to pack subtype - CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, .TRUE. ) ! PassedFileData - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! PassedFileData - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! PassedFileData - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! PassedFileData - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO I = 1, LEN(InData%WindFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - ReKiBuf(Re_Xferred) = InData%ReferenceHeight - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RefLength - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%SumFileUnit - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%UseInputFile, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, OnlySize ) ! PassedFileData - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_UniformWind_PackInitInput - - SUBROUTINE IfW_UniformWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UniformWind_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - DO I = 1, LEN(OutData%WindFileName) - OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%ReferenceHeight = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RefLength = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%SumFileUnit = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%UseInputFile = TRANSFER(IntKiBuf(Int_Xferred), OutData%UseInputFile) - Int_Xferred = Int_Xferred + 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackfileinfotype( Re_Buf, Db_Buf, Int_Buf, OutData%PassedFileData, ErrStat2, ErrMsg2 ) ! PassedFileData - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_UniformWind_UnPackInitInput - - SUBROUTINE IfW_UniformWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(IfW_UniformWind_InitOutputType), INTENT(INOUT) :: DstInitOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_CopyInitOutput' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - DstInitOutputData%WindFileDT = SrcInitOutputData%WindFileDT - DstInitOutputData%WindFileTRange = SrcInitOutputData%WindFileTRange - DstInitOutputData%WindFileNumTSteps = SrcInitOutputData%WindFileNumTSteps - DstInitOutputData%WindFileConstantDT = SrcInitOutputData%WindFileConstantDT - END SUBROUTINE IfW_UniformWind_CopyInitOutput - - SUBROUTINE IfW_UniformWind_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_DestroyInitOutput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) - END SUBROUTINE IfW_UniformWind_DestroyInitOutput - - SUBROUTINE IfW_UniformWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UniformWind_InitOutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Db_BufSz = Db_BufSz + 1 ! WindFileDT - Re_BufSz = Re_BufSz + SIZE(InData%WindFileTRange) ! WindFileTRange - Int_BufSz = Int_BufSz + 1 ! WindFileNumTSteps - Int_BufSz = Int_BufSz + 1 ! WindFileConstantDT - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - DbKiBuf(Db_Xferred) = InData%WindFileDT - Db_Xferred = Db_Xferred + 1 - DO i1 = LBOUND(InData%WindFileTRange,1), UBOUND(InData%WindFileTRange,1) - ReKiBuf(Re_Xferred) = InData%WindFileTRange(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = InData%WindFileNumTSteps - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%WindFileConstantDT, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_UniformWind_PackInitOutput - - SUBROUTINE IfW_UniformWind_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UniformWind_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - OutData%WindFileDT = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 - i1_l = LBOUND(OutData%WindFileTRange,1) - i1_u = UBOUND(OutData%WindFileTRange,1) - DO i1 = LBOUND(OutData%WindFileTRange,1), UBOUND(OutData%WindFileTRange,1) - OutData%WindFileTRange(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%WindFileNumTSteps = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%WindFileConstantDT = TRANSFER(IntKiBuf(Int_Xferred), OutData%WindFileConstantDT) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_UniformWind_UnPackInitOutput - - SUBROUTINE IfW_UniformWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: DstMiscData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_CopyMisc' -! - ErrStat = ErrID_None - ErrMsg = "" - DstMiscData%TimeIndex = SrcMiscData%TimeIndex - END SUBROUTINE IfW_UniformWind_CopyMisc - - SUBROUTINE IfW_UniformWind_DestroyMisc( MiscData, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: MiscData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_DestroyMisc' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_UniformWind_DestroyMisc - - SUBROUTINE IfW_UniformWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UniformWind_MiscVarType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_PackMisc' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! TimeIndex - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IntKiBuf(Int_Xferred) = InData%TimeIndex - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_UniformWind_PackMisc - - SUBROUTINE IfW_UniformWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UniformWind_MiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_UnPackMisc' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%TimeIndex = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_UniformWind_UnPackMisc - - SUBROUTINE IfW_UniformWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_UniformWind_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(SrcParamData%TData)) THEN - i1_l = LBOUND(SrcParamData%TData,1) - i1_u = UBOUND(SrcParamData%TData,1) - IF (.NOT. ALLOCATED(DstParamData%TData)) THEN - ALLOCATE(DstParamData%TData(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%TData.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%TData = SrcParamData%TData -ENDIF -IF (ALLOCATED(SrcParamData%DELTA)) THEN - i1_l = LBOUND(SrcParamData%DELTA,1) - i1_u = UBOUND(SrcParamData%DELTA,1) - IF (.NOT. ALLOCATED(DstParamData%DELTA)) THEN - ALLOCATE(DstParamData%DELTA(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%DELTA.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%DELTA = SrcParamData%DELTA -ENDIF -IF (ALLOCATED(SrcParamData%Upflow)) THEN - i1_l = LBOUND(SrcParamData%Upflow,1) - i1_u = UBOUND(SrcParamData%Upflow,1) - IF (.NOT. ALLOCATED(DstParamData%Upflow)) THEN - ALLOCATE(DstParamData%Upflow(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%Upflow.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%Upflow = SrcParamData%Upflow -ENDIF -IF (ALLOCATED(SrcParamData%V)) THEN - i1_l = LBOUND(SrcParamData%V,1) - i1_u = UBOUND(SrcParamData%V,1) - IF (.NOT. ALLOCATED(DstParamData%V)) THEN - ALLOCATE(DstParamData%V(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%V.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%V = SrcParamData%V -ENDIF -IF (ALLOCATED(SrcParamData%VZ)) THEN - i1_l = LBOUND(SrcParamData%VZ,1) - i1_u = UBOUND(SrcParamData%VZ,1) - IF (.NOT. ALLOCATED(DstParamData%VZ)) THEN - ALLOCATE(DstParamData%VZ(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%VZ.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%VZ = SrcParamData%VZ -ENDIF -IF (ALLOCATED(SrcParamData%HSHR)) THEN - i1_l = LBOUND(SrcParamData%HSHR,1) - i1_u = UBOUND(SrcParamData%HSHR,1) - IF (.NOT. ALLOCATED(DstParamData%HSHR)) THEN - ALLOCATE(DstParamData%HSHR(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%HSHR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%HSHR = SrcParamData%HSHR -ENDIF -IF (ALLOCATED(SrcParamData%VSHR)) THEN - i1_l = LBOUND(SrcParamData%VSHR,1) - i1_u = UBOUND(SrcParamData%VSHR,1) - IF (.NOT. ALLOCATED(DstParamData%VSHR)) THEN - ALLOCATE(DstParamData%VSHR(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%VSHR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%VSHR = SrcParamData%VSHR -ENDIF -IF (ALLOCATED(SrcParamData%VLINSHR)) THEN - i1_l = LBOUND(SrcParamData%VLINSHR,1) - i1_u = UBOUND(SrcParamData%VLINSHR,1) - IF (.NOT. ALLOCATED(DstParamData%VLINSHR)) THEN - ALLOCATE(DstParamData%VLINSHR(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%VLINSHR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%VLINSHR = SrcParamData%VLINSHR -ENDIF -IF (ALLOCATED(SrcParamData%VGUST)) THEN - i1_l = LBOUND(SrcParamData%VGUST,1) - i1_u = UBOUND(SrcParamData%VGUST,1) - IF (.NOT. ALLOCATED(DstParamData%VGUST)) THEN - ALLOCATE(DstParamData%VGUST(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%VGUST.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstParamData%VGUST = SrcParamData%VGUST -ENDIF - DstParamData%RefHt = SrcParamData%RefHt - DstParamData%RefLength = SrcParamData%RefLength - DstParamData%NumDataLines = SrcParamData%NumDataLines - END SUBROUTINE IfW_UniformWind_CopyParam - - SUBROUTINE IfW_UniformWind_DestroyParam( ParamData, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_DestroyParam' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(ParamData%TData)) THEN - DEALLOCATE(ParamData%TData) -ENDIF -IF (ALLOCATED(ParamData%DELTA)) THEN - DEALLOCATE(ParamData%DELTA) -ENDIF -IF (ALLOCATED(ParamData%Upflow)) THEN - DEALLOCATE(ParamData%Upflow) -ENDIF -IF (ALLOCATED(ParamData%V)) THEN - DEALLOCATE(ParamData%V) -ENDIF -IF (ALLOCATED(ParamData%VZ)) THEN - DEALLOCATE(ParamData%VZ) -ENDIF -IF (ALLOCATED(ParamData%HSHR)) THEN - DEALLOCATE(ParamData%HSHR) -ENDIF -IF (ALLOCATED(ParamData%VSHR)) THEN - DEALLOCATE(ParamData%VSHR) -ENDIF -IF (ALLOCATED(ParamData%VLINSHR)) THEN - DEALLOCATE(ParamData%VLINSHR) -ENDIF -IF (ALLOCATED(ParamData%VGUST)) THEN - DEALLOCATE(ParamData%VGUST) -ENDIF - END SUBROUTINE IfW_UniformWind_DestroyParam - - SUBROUTINE IfW_UniformWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UniformWind_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! TData allocated yes/no - IF ( ALLOCATED(InData%TData) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! TData upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%TData) ! TData - END IF - Int_BufSz = Int_BufSz + 1 ! DELTA allocated yes/no - IF ( ALLOCATED(InData%DELTA) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! DELTA upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%DELTA) ! DELTA - END IF - Int_BufSz = Int_BufSz + 1 ! Upflow allocated yes/no - IF ( ALLOCATED(InData%Upflow) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Upflow upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Upflow) ! Upflow - END IF - Int_BufSz = Int_BufSz + 1 ! V allocated yes/no - IF ( ALLOCATED(InData%V) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! V upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%V) ! V - END IF - Int_BufSz = Int_BufSz + 1 ! VZ allocated yes/no - IF ( ALLOCATED(InData%VZ) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! VZ upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%VZ) ! VZ - END IF - Int_BufSz = Int_BufSz + 1 ! HSHR allocated yes/no - IF ( ALLOCATED(InData%HSHR) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! HSHR upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%HSHR) ! HSHR - END IF - Int_BufSz = Int_BufSz + 1 ! VSHR allocated yes/no - IF ( ALLOCATED(InData%VSHR) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! VSHR upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%VSHR) ! VSHR - END IF - Int_BufSz = Int_BufSz + 1 ! VLINSHR allocated yes/no - IF ( ALLOCATED(InData%VLINSHR) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! VLINSHR upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%VLINSHR) ! VLINSHR - END IF - Int_BufSz = Int_BufSz + 1 ! VGUST allocated yes/no - IF ( ALLOCATED(InData%VGUST) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! VGUST upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%VGUST) ! VGUST - END IF - Re_BufSz = Re_BufSz + 1 ! RefHt - Re_BufSz = Re_BufSz + 1 ! RefLength - Int_BufSz = Int_BufSz + 1 ! NumDataLines - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IF ( .NOT. ALLOCATED(InData%TData) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%TData,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TData,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%TData,1), UBOUND(InData%TData,1) - ReKiBuf(Re_Xferred) = InData%TData(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%DELTA) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%DELTA,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%DELTA,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%DELTA,1), UBOUND(InData%DELTA,1) - ReKiBuf(Re_Xferred) = InData%DELTA(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%Upflow) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Upflow,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Upflow,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%Upflow,1), UBOUND(InData%Upflow,1) - ReKiBuf(Re_Xferred) = InData%Upflow(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%V) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%V,1), UBOUND(InData%V,1) - ReKiBuf(Re_Xferred) = InData%V(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%VZ) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%VZ,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VZ,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%VZ,1), UBOUND(InData%VZ,1) - ReKiBuf(Re_Xferred) = InData%VZ(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%HSHR) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%HSHR,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%HSHR,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%HSHR,1), UBOUND(InData%HSHR,1) - ReKiBuf(Re_Xferred) = InData%HSHR(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%VSHR) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%VSHR,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VSHR,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%VSHR,1), UBOUND(InData%VSHR,1) - ReKiBuf(Re_Xferred) = InData%VSHR(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%VLINSHR) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%VLINSHR,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VLINSHR,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%VLINSHR,1), UBOUND(InData%VLINSHR,1) - ReKiBuf(Re_Xferred) = InData%VLINSHR(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%VGUST) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%VGUST,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VGUST,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%VGUST,1), UBOUND(InData%VGUST,1) - ReKiBuf(Re_Xferred) = InData%VGUST(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - ReKiBuf(Re_Xferred) = InData%RefHt - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RefLength - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NumDataLines - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_UniformWind_PackParam - - SUBROUTINE IfW_UniformWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UniformWind_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TData not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%TData)) DEALLOCATE(OutData%TData) - ALLOCATE(OutData%TData(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TData.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%TData,1), UBOUND(OutData%TData,1) - OutData%TData(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! DELTA not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%DELTA)) DEALLOCATE(OutData%DELTA) - ALLOCATE(OutData%DELTA(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%DELTA.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%DELTA,1), UBOUND(OutData%DELTA,1) - OutData%DELTA(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Upflow not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Upflow)) DEALLOCATE(OutData%Upflow) - ALLOCATE(OutData%Upflow(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Upflow.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%Upflow,1), UBOUND(OutData%Upflow,1) - OutData%Upflow(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! V not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%V)) DEALLOCATE(OutData%V) - ALLOCATE(OutData%V(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%V.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%V,1), UBOUND(OutData%V,1) - OutData%V(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VZ not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%VZ)) DEALLOCATE(OutData%VZ) - ALLOCATE(OutData%VZ(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VZ.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%VZ,1), UBOUND(OutData%VZ,1) - OutData%VZ(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! HSHR not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%HSHR)) DEALLOCATE(OutData%HSHR) - ALLOCATE(OutData%HSHR(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%HSHR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%HSHR,1), UBOUND(OutData%HSHR,1) - OutData%HSHR(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VSHR not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%VSHR)) DEALLOCATE(OutData%VSHR) - ALLOCATE(OutData%VSHR(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VSHR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%VSHR,1), UBOUND(OutData%VSHR,1) - OutData%VSHR(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VLINSHR not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%VLINSHR)) DEALLOCATE(OutData%VLINSHR) - ALLOCATE(OutData%VLINSHR(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VLINSHR.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%VLINSHR,1), UBOUND(OutData%VLINSHR,1) - OutData%VLINSHR(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! VGUST not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%VGUST)) DEALLOCATE(OutData%VGUST) - ALLOCATE(OutData%VGUST(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%VGUST.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%VGUST,1), UBOUND(OutData%VGUST,1) - OutData%VGUST(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - OutData%RefHt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RefLength = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%NumDataLines = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE IfW_UniformWind_UnPackParam - - SUBROUTINE IfW_UniformWind_CopyIntrp( SrcIntrpData, DstIntrpData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_Intrp), INTENT(IN) :: SrcIntrpData - TYPE(IfW_UniformWind_Intrp), INTENT(INOUT) :: DstIntrpData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_CopyIntrp' -! - ErrStat = ErrID_None - ErrMsg = "" - DstIntrpData%DELTA = SrcIntrpData%DELTA - DstIntrpData%Upflow = SrcIntrpData%Upflow - DstIntrpData%V = SrcIntrpData%V - DstIntrpData%VZ = SrcIntrpData%VZ - DstIntrpData%HSHR = SrcIntrpData%HSHR - DstIntrpData%VSHR = SrcIntrpData%VSHR - DstIntrpData%VLINSHR = SrcIntrpData%VLINSHR - DstIntrpData%VGUST = SrcIntrpData%VGUST - END SUBROUTINE IfW_UniformWind_CopyIntrp - - SUBROUTINE IfW_UniformWind_DestroyIntrp( IntrpData, ErrStat, ErrMsg ) - TYPE(IfW_UniformWind_Intrp), INTENT(INOUT) :: IntrpData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_DestroyIntrp' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_UniformWind_DestroyIntrp - - SUBROUTINE IfW_UniformWind_PackIntrp( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UniformWind_Intrp), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_PackIntrp' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DELTA - Re_BufSz = Re_BufSz + 1 ! Upflow - Re_BufSz = Re_BufSz + 1 ! V - Re_BufSz = Re_BufSz + 1 ! VZ - Re_BufSz = Re_BufSz + 1 ! HSHR - Re_BufSz = Re_BufSz + 1 ! VSHR - Re_BufSz = Re_BufSz + 1 ! VLINSHR - Re_BufSz = Re_BufSz + 1 ! VGUST - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DELTA - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Upflow - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%V - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VZ - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%HSHR - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VSHR - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VLINSHR - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VGUST - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_UniformWind_PackIntrp - - SUBROUTINE IfW_UniformWind_UnPackIntrp( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UniformWind_Intrp), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UniformWind_UnPackIntrp' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DELTA = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%Upflow = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%V = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VZ = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%HSHR = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VSHR = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VLINSHR = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VGUST = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_UniformWind_UnPackIntrp - -END MODULE IfW_UniformWind_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/IfW_UserWind.f90 b/modules/inflowwind/src/IfW_UserWind.f90 deleted file mode 100644 index cf52a3386..000000000 --- a/modules/inflowwind/src/IfW_UserWind.f90 +++ /dev/null @@ -1,286 +0,0 @@ -!> This module is a placeholder for any user defined wind types. The end user can use this as a template for their code. -!! @note This module does not need to exactly conform to the FAST Modularization Framework standards. Three routines are required -!! though: -!! -- IfW_UserWind_Init -- Load or create any wind data. Only called at the start of FAST. -!! -- IfW_UserWind_CalcOutput -- This will be called at each timestep with a series of data points to give wind velocities at. -!! -- IfW_UserWind_End -- clear out any stored stuff. Only called at the end of FAST. -MODULE IfW_UserWind -!********************************************************************************************************************************** -! LICENSING -! Copyright (C) 2015-2016 National Renewable Energy Laboratory -! -! This file is part of InflowWind. -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -!********************************************************************************************************************************** - - USE NWTC_Library - USE IfW_UserWind_Types - - IMPLICIT NONE - PRIVATE - - TYPE(ProgDesc), PARAMETER :: IfW_UserWind_Ver = ProgDesc( 'IfW_UserWind', '', '' ) - - PUBLIC :: IfW_UserWind_Init - PUBLIC :: IfW_UserWind_End - PUBLIC :: IfW_UserWind_CalcOutput - -CONTAINS - -!==================================================================================================== - -!---------------------------------------------------------------------------------------------------- -!> A subroutine to initialize the UserWind module. This routine will initialize the module. -!---------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_UserWind_Init(InitData, ParamData, MiscVars, Interval, InitOutData, ErrStat, ErrMsg) - - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_UserWind_Init" - - - ! Passed Variables - - ! Anything this code needs to be able to generate or read its data in should be passed into here through InitData. - TYPE(IfW_UserWind_InitInputType), INTENT(IN ) :: InitData !< Input data for initialization. - - ! Store all data that does not change during the simulation in here (including the wind data field). This cannot be changed later. - TYPE(IfW_UserWind_ParameterType), INTENT( OUT) :: ParamData !< Parameters. - - ! Store things that change during the simulation (indices to arrays for quicker searching etc). - TYPE(IfW_UserWind_MiscVarType), INTENT( OUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - ! Anything that should be passed back to the InflowWind or higher modules regarding initialization. - TYPE(IfW_UserWind_InitOutputType), INTENT( OUT) :: InitOutData !< Initial output. - - REAL(DbKi), INTENT(IN ) :: Interval !< Do not change this!! - - - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< A message about the error. See NWTC_Library info for ErrID_* levels. - - ! local variables - ! Put local variables used during initializing your wind here. DO NOT USE GLOBAL VARIABLES EVER! - INTEGER(IntKi) :: UnitWind ! Use this unit number if you need to read in a file. - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat ! Temp variable for the error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !------------------------------------------------------------------------------------------------- - ! Set the Error handling variables - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = "" - - - ! Get a unit number to use - - CALL GetNewUnit(UnitWind, TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Copy things from the InitData to the ParamData. If you need to store it for later calculations, - ! copy it over now. - !------------------------------------------------------------------------------------------------- - ParamData%dummy = 0 -! ParamData%RefHt = InitData%ReferenceHeight -! ParamData%RefLength = InitData%RefLength - - !------------------------------------------------------------------------------------------------- - ! Open the file for reading. Proceed with file parsing etc. Populate your wind field here. - !------------------------------------------------------------------------------------------------- - -! CALL OpenFInpFile (UnitWind, TRIM(InitData%WindFileName), TmpErrStat, TmpErrMsg) -! CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) -! IF ( ErrStat >= AbortErrLev ) RETURN - - - !------------------------------------------------------------------------------------------------- - ! Set the MiscVars: - !------------------------------------------------------------------------------------------------- - - MiscVars%DummyMiscVar = 0 - - - !------------------------------------------------------------------------------------------------- - ! Set the InitOutput information. Set Any outputs here. - !------------------------------------------------------------------------------------------------- - - InitOutdata%Ver = IfW_UserWind_Ver - - - - ! REMOVE THIS MESSAGE IF YOU WRITE CODE IN THIS MODULE - CALL SetErrStat(ErrID_Fatal,' This module has not been written yet.',ErrStat,ErrMsg,RoutineName) - - RETURN - -END SUBROUTINE IfW_UserWind_Init - -!==================================================================================================== - -!------------------------------------------------------------------------------------------------- -!> This routine and its subroutines calculate the wind velocity at a set of points given in -!! PositionXYZ. The UVW velocities are returned in OutData%Velocity -!! -!! @note This routine may be called multiple times in a single timestep!!! -!! -!! @note The PositionXYZ coordinates have been rotated into the wind coordinate system where the -!! primary wind flow is along the X-axis. The rotations to PropagationDir are taken care of -!! in the InflowWind_CalcOutput subroutine which calls this routine. -!------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_UserWind_CalcOutput(Time, PositionXYZ, ParamData, Velocity, DiskVel, MiscVars, ErrStat, ErrMsg) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_UserWind_CalcOutput" - - - ! Passed Variables - REAL(DbKi), INTENT(IN ) :: Time !< time from the start of the simulation - REAL(ReKi), INTENT(IN ) :: PositionXYZ(:,:) !< Array of XYZ coordinates, 3xN - TYPE(IfW_UserWind_ParameterType), INTENT(IN ) :: ParamData !< Parameters - REAL(ReKi), INTENT(INOUT) :: Velocity(:,:) !< Velocity output at Time (Set to INOUT so that array does not get deallocated) - REAL(ReKi), INTENT( OUT) :: DiskVel(3) !< HACK for AD14: disk velocity output at Time - TYPE(IfW_UserWind_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - ! Error handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< error status - CHARACTER(*), INTENT( OUT) :: ErrMsg !< The error message - - - ! local counters - INTEGER(IntKi) :: PointNum ! a loop counter for the current point - - ! local variables - INTEGER(IntKi) :: NumPoints ! Number of points passed in - - ! temporary variables - !INTEGER(IntKi) :: TmpErrStat ! temporary error status - !CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - - !------------------------------------------------------------------------------------------------- - ! Initialize some things - !------------------------------------------------------------------------------------------------- - - ErrStat = ErrID_None - ErrMsg = "" - - - ! The array is transposed so that the number of points is the second index, x/y/z is the first. - ! This is just in case we only have a single point, the SIZE command returns the correct number of points. - NumPoints = SIZE(PositionXYZ,DIM=2) - - - ! Step through all the positions and get the velocities - DO PointNum = 1, NumPoints - -! Place code to retrieve the windspeed at a given point here. - - - ! Some generic error handling if you want it when a calculation fails for some reason: - ! - ! ! Error handling - !CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - !IF (ErrStat >= AbortErrLev) THEN - ! TmpErrMsg= " Error calculating the wind speed at position ("// & - ! TRIM(Num2LStr(PositionXYZ(1,PointNum)))//", "// & - ! TRIM(Num2LStr(PositionXYZ(2,PointNum)))//", "// & - ! TRIM(Num2LStr(PositionXYZ(3,PointNum)))//") in the wind-file coordinates" - ! CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - ! RETURN - !ENDIF - - ENDDO - - ! an average wind speed, required for AD14 - DiskVel = 0.0_ReKi - - ! REMOVE THIS MESSAGE IF YOU WRITE CODE IN THIS MODULE - CALL SetErrStat(ErrID_Fatal,' This module has not been written yet.',ErrStat,ErrMsg,RoutineName) - - - RETURN - -END SUBROUTINE IfW_UserWind_CalcOutput - -!==================================================================================================== - -!---------------------------------------------------------------------------------------------------- -!> This routine closes any open files and clears all data stored in UserWind derived Types -!! -!! @note This routine does not satisfy the Modular framework. The InputType is not used, rather -!! an array of points is passed in. -!! @date: 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 -!---------------------------------------------------------------------------------------------------- -SUBROUTINE IfW_UserWind_End( ParamData, MiscVars, ErrStat, ErrMsg) - - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="IfW_UserWind_End" - - - ! Passed Variables - TYPE(IfW_UserWind_ParameterType), INTENT(INOUT) :: ParamData !< Parameters - TYPE(IfW_UserWind_MiscVarType), INTENT(INOUT) :: MiscVars !< Misc variables for optimization (not copied in glue code) - - - ! Error Handling - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< determines if an error has been encountered - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Message about errors - - - ! Local Variables - INTEGER(IntKi) :: TmpErrStat ! temporary error status - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - !-=- Initialize the routine -=- - - ErrMsg = '' - ErrStat = ErrID_None - - - - ! Destroy parameter data - - CALL IfW_UserWind_DestroyParam( ParamData, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - - ! Destroy the misc data - - CALL IfW_UserWind_DestroyMisc( MiscVars, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - - -END SUBROUTINE IfW_UserWind_End - - -!==================================================================================================== -!==================================================================================================== -!==================================================================================================== -END MODULE IfW_UserWind diff --git a/modules/inflowwind/src/IfW_UserWind.txt b/modules/inflowwind/src/IfW_UserWind.txt deleted file mode 100644 index 62fa3e3b2..000000000 --- a/modules/inflowwind/src/IfW_UserWind.txt +++ /dev/null @@ -1,36 +0,0 @@ -################################################################################################################################### -# Registry for IfW_UserWind, creates MODULE IfW_UserWind_Types -# Module IfW_UserWind_Types contains all of the user-defined types needed in IfW_UserWind. It also contains copy, destroy, pack, and -# unpack routines associated with each defined data types. -################################################################################################################################### -# Entries are of the form -# keyword -################################################################################################################################### - -include Registry_NWTC_Library.txt - - -######################### - -typedef IfW_UserWind/IfW_UserWind InitInputType CHARACTER(1024) WindFileName - - - "Name of the wind file to use" - - - - -# Init Output -typedef ^ InitOutputType ProgDesc Ver - - - "Version information off HHWind submodule" - - - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType ReKi DummyMiscVar - - - "Remove this variable if you have misc variables" - - - -# ..... Parameters ................................................................................................................ -# Define parameters here: -# Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: -typedef ^ ParameterType SiKi dummy - - - "remove if you have parameters" - - - - - diff --git a/modules/inflowwind/src/IfW_UserWind_Types.f90 b/modules/inflowwind/src/IfW_UserWind_Types.f90 deleted file mode 100644 index 1fa5c484a..000000000 --- a/modules/inflowwind/src/IfW_UserWind_Types.f90 +++ /dev/null @@ -1,646 +0,0 @@ -!STARTOFREGISTRYGENERATEDFILE 'IfW_UserWind_Types.f90' -! -! WARNING This file is generated automatically by the FAST registry. -! Do not edit. Your changes to this file will be lost. -! -! FAST Registry -!********************************************************************************************************************************* -! IfW_UserWind_Types -!................................................................................................................................. -! This file is part of IfW_UserWind. -! -! Copyright (C) 2012-2016 National Renewable Energy Laboratory -! -! Licensed under the Apache License, Version 2.0 (the "License"); -! you may not use this file except in compliance with the License. -! You may obtain a copy of the License at -! -! http://www.apache.org/licenses/LICENSE-2.0 -! -! Unless required by applicable law or agreed to in writing, software -! distributed under the License is distributed on an "AS IS" BASIS, -! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -! See the License for the specific language governing permissions and -! limitations under the License. -! -! -! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. -! -!********************************************************************************************************************************* -!> This module contains the user-defined types needed in IfW_UserWind. It also contains copy, destroy, pack, and -!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. -MODULE IfW_UserWind_Types -!--------------------------------------------------------------------------------------------------------------------------------- -USE NWTC_Library -IMPLICIT NONE -! ========= IfW_UserWind_InitInputType ======= - TYPE, PUBLIC :: IfW_UserWind_InitInputType - CHARACTER(1024) :: WindFileName !< Name of the wind file to use [-] - END TYPE IfW_UserWind_InitInputType -! ======================= -! ========= IfW_UserWind_InitOutputType ======= - TYPE, PUBLIC :: IfW_UserWind_InitOutputType - TYPE(ProgDesc) :: Ver !< Version information off HHWind submodule [-] - END TYPE IfW_UserWind_InitOutputType -! ======================= -! ========= IfW_UserWind_MiscVarType ======= - TYPE, PUBLIC :: IfW_UserWind_MiscVarType - REAL(ReKi) :: DummyMiscVar !< Remove this variable if you have misc variables [-] - END TYPE IfW_UserWind_MiscVarType -! ======================= -! ========= IfW_UserWind_ParameterType ======= - TYPE, PUBLIC :: IfW_UserWind_ParameterType - REAL(SiKi) :: dummy !< remove if you have parameters [-] - END TYPE IfW_UserWind_ParameterType -! ======================= -CONTAINS - SUBROUTINE IfW_UserWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UserWind_InitInputType), INTENT(IN) :: SrcInitInputData - TYPE(IfW_UserWind_InitInputType), INTENT(INOUT) :: DstInitInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_CopyInitInput' -! - ErrStat = ErrID_None - ErrMsg = "" - DstInitInputData%WindFileName = SrcInitInputData%WindFileName - END SUBROUTINE IfW_UserWind_CopyInitInput - - SUBROUTINE IfW_UserWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) - TYPE(IfW_UserWind_InitInputType), INTENT(INOUT) :: InitInputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_DestroyInitInput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_UserWind_DestroyInitInput - - SUBROUTINE IfW_UserWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UserWind_InitInputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_PackInitInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO I = 1, LEN(InData%WindFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END SUBROUTINE IfW_UserWind_PackInitInput - - SUBROUTINE IfW_UserWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UserWind_InitInputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_UnPackInitInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - DO I = 1, LEN(OutData%WindFileName) - OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END SUBROUTINE IfW_UserWind_UnPackInitInput - - SUBROUTINE IfW_UserWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UserWind_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(IfW_UserWind_InitOutputType), INTENT(INOUT) :: DstInitOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_CopyInitOutput' -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE IfW_UserWind_CopyInitOutput - - SUBROUTINE IfW_UserWind_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) - TYPE(IfW_UserWind_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_DestroyInitOutput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) - END SUBROUTINE IfW_UserWind_DestroyInitOutput - - SUBROUTINE IfW_UserWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UserWind_InitOutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE IfW_UserWind_PackInitOutput - - SUBROUTINE IfW_UserWind_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UserWind_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE IfW_UserWind_UnPackInitOutput - - SUBROUTINE IfW_UserWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UserWind_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(IfW_UserWind_MiscVarType), INTENT(INOUT) :: DstMiscData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_CopyMisc' -! - ErrStat = ErrID_None - ErrMsg = "" - DstMiscData%DummyMiscVar = SrcMiscData%DummyMiscVar - END SUBROUTINE IfW_UserWind_CopyMisc - - SUBROUTINE IfW_UserWind_DestroyMisc( MiscData, ErrStat, ErrMsg ) - TYPE(IfW_UserWind_MiscVarType), INTENT(INOUT) :: MiscData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_DestroyMisc' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_UserWind_DestroyMisc - - SUBROUTINE IfW_UserWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UserWind_MiscVarType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_PackMisc' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DummyMiscVar - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%DummyMiscVar - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_UserWind_PackMisc - - SUBROUTINE IfW_UserWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UserWind_MiscVarType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_UnPackMisc' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%DummyMiscVar = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_UserWind_UnPackMisc - - SUBROUTINE IfW_UserWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(IfW_UserWind_ParameterType), INTENT(IN) :: SrcParamData - TYPE(IfW_UserWind_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - DstParamData%dummy = SrcParamData%dummy - END SUBROUTINE IfW_UserWind_CopyParam - - SUBROUTINE IfW_UserWind_DestroyParam( ParamData, ErrStat, ErrMsg ) - TYPE(IfW_UserWind_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_DestroyParam' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE IfW_UserWind_DestroyParam - - SUBROUTINE IfW_UserWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(IfW_UserWind_ParameterType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! dummy - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%dummy - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_UserWind_PackParam - - SUBROUTINE IfW_UserWind_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(IfW_UserWind_ParameterType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'IfW_UserWind_UnPackParam' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%dummy = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE IfW_UserWind_UnPackParam - -END MODULE IfW_UserWind_Types -!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/InflowWind.f90 b/modules/inflowwind/src/InflowWind.f90 index a84d02b84..46bf3325d 100644 --- a/modules/inflowwind/src/InflowWind.f90 +++ b/modules/inflowwind/src/InflowWind.f90 @@ -41,9 +41,12 @@ MODULE InflowWind - USE InflowWind_Types USE NWTC_Library + USE InflowWind_Types USE InflowWind_Subs + USE InflowWind_IO_Types + USE InflowWind_IO + USE IfW_FlowField USE Lidar ! module for obtaining sensor data @@ -51,6 +54,7 @@ MODULE InflowWind PRIVATE TYPE(ProgDesc), PARAMETER :: IfW_Ver = ProgDesc( 'InflowWind', '', '' ) + integer, parameter :: NumExtendedInputs = 3 !: V, VShr, PropDir @@ -61,11 +65,6 @@ MODULE InflowWind PUBLIC :: InflowWind_CalcOutput !< Calculate the wind velocities PUBLIC :: InflowWind_End !< Ending routine (includes clean up) - PUBLIC :: InflowWind_Convert2HAWC !< An extension of the FAST framework, this routine converts an InflowWind data structure to HAWC format wind files - PUBLIC :: InflowWind_Convert2Bladed !< An extension of the FAST framework, this routine converts an InflowWind data structure to Bladed format wind files (with shear already included) - PUBLIC :: InflowWind_Convert2VTK !< An extension of the FAST framework, this routine converts an InflowWind data structure to VTK format wind files - - ! These routines satisfy the framework, but do nothing at present. PUBLIC :: InflowWind_UpdateStates !< Loose coupling routine for solving for constraint states, integrating continuous states, and updating discrete states PUBLIC :: InflowWind_CalcConstrStateResidual !< Tight coupling routine for returning the constraint state residual @@ -97,660 +96,563 @@ MODULE InflowWind !! Since this module acts as an interface to other modules, on some things are set before initiating !! calls to the lower modules. !---------------------------------------------------------------------------------------------------- -SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, ConstrStateGuess, OtherStates, & - y, m, TimeInterval, InitOutData, ErrStat, ErrMsg ) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_Init" - - ! Initialization data and guesses - - TYPE(InflowWind_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization - TYPE(InflowWind_InputType), INTENT( OUT) :: InputGuess !< An initial guess for the input; the input mesh must be defined - TYPE(InflowWind_ParameterType), INTENT( OUT) :: p !< Parameters - TYPE(InflowWind_ContinuousStateType), INTENT( OUT) :: ContStates !< Initial continuous states - TYPE(InflowWind_DiscreteStateType), INTENT( OUT) :: DiscStates !< Initial discrete states - TYPE(InflowWind_ConstraintStateType), INTENT( OUT) :: ConstrStateGuess !< Initial guess of the constraint states - TYPE(InflowWind_OtherStateType), INTENT( OUT) :: OtherStates !< Initial other/optimization states - TYPE(InflowWind_OutputType), INTENT( OUT) :: y !< Initial output (outputs are not calculated; only the output mesh is initialized) - TYPE(InflowWind_MiscVarType), INTENT( OUT) :: m !< Misc variables for optimization (not copied in glue code) - REAL(DbKi), INTENT(IN ) :: TimeInterval !< Coupling time interval in seconds: InflowWind does not change this. - TYPE(InflowWind_InitOutputType), INTENT( OUT) :: InitOutData !< Initial output data -- Names, units, and version info. - - - ! Error Handling - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Local variables - - TYPE(InflowWind_InputFile) :: InputFileData !< Data from input file - - TYPE(IfW_UniformWind_InitInputType) :: Uniform_InitData !< initialization info - TYPE(IfW_UniformWind_InitOutputType) :: Uniform_InitOutData !< initialization output info - - TYPE(IfW_TSFFWind_InitInputType) :: TSFF_InitData !< initialization info - TYPE(IfW_TSFFWind_InitOutputType) :: TSFF_InitOutData !< initialization output info - - TYPE(IfW_HAWCWind_InitInputType) :: HAWC_InitData !< initialization info - TYPE(IfW_HAWCWind_InitOutputType) :: HAWC_InitOutData !< initialization output info - - TYPE(IfW_BladedFFWind_InitInputType) :: BladedFF_InitData !< initialization info - TYPE(IfW_BladedFFWind_InitOutputType) :: BladedFF_InitOutData !< initialization output info - - TYPE(IfW_UserWind_InitInputType) :: User_InitData !< initialization info - TYPE(IfW_UserWind_InitOutputType) :: User_InitOutData !< initialization info - - TYPE(IfW_4Dext_InitOutputType) :: FDext_InitOutData !< initialization info +SUBROUTINE InflowWind_Init( InitInp, InputGuess, p, ContStates, DiscStates, ConstrStateGuess, OtherStates, & + y, m, TimeInterval, InitOutData, ErrStat, ErrMsg ) + + ! Initialization data and guesses + TYPE(InflowWind_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization + TYPE(InflowWind_InputType), INTENT( OUT) :: InputGuess !< An initial guess for the input; the input mesh must be defined + TYPE(InflowWind_ParameterType), INTENT( OUT) :: p !< Parameters + TYPE(InflowWind_ContinuousStateType), INTENT( OUT) :: ContStates !< Initial continuous states + TYPE(InflowWind_DiscreteStateType), INTENT( OUT) :: DiscStates !< Initial discrete states + TYPE(InflowWind_ConstraintStateType), INTENT( OUT) :: ConstrStateGuess !< Initial guess of the constraint states + TYPE(InflowWind_OtherStateType), INTENT( OUT) :: OtherStates !< Initial other/optimization states + TYPE(InflowWind_OutputType), INTENT( OUT) :: y !< Initial output (outputs are not calculated; only the output mesh is initialized) + TYPE(InflowWind_MiscVarType), INTENT( OUT) :: m !< Misc variables for optimization (not copied in glue code) + REAL(DbKi), INTENT(IN ) :: TimeInterval !< Coupling time interval in seconds: InflowWind does not change this. + TYPE(InflowWind_InitOutputType), INTENT( OUT) :: InitOutData !< Initial output data -- Names, units, and version info. + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! Local variables + CHARACTER(*), PARAMETER :: RoutineName="InflowWind_Init" + + TYPE(InflowWind_InputFile) :: InputFileData !< Data from input file + + Type(Steady_InitInputType) :: Steady_InitInput + Type(Uniform_InitInputType) :: Uniform_InitInput + Type(TurbSim_InitInputType) :: TurbSim_InitInput + Type(Bladed_InitInputType) :: Bladed_InitInput + Type(Bladed_InitOutputType) :: Bladed_InitOutput + Type(HAWC_InitInputType) :: HAWC_InitInput + Type(User_InitInputType) :: User_InitInput + Type(Grid4D_InitInputType) :: Grid4D_InitInput + Type(Points_InitInputType) :: Points_InitInput + + Type(WindFileDat) :: FileDat + - TYPE(FileInfoType) :: InFileInfo !< The derived type for holding the full input file for parsing -- we may pass this in the future -!!! TYPE(CTBladed_Backgr) :: BackGrndValues + ! TYPE(InflowWind_IO_InitInputType) :: FlowField_InitData !< initialization info + ! TYPE(InflowWind_IO_InitOutputType) :: FlowField_InitOutData !< initialization output info + TYPE(FileInfoType) :: InFileInfo !< The derived type for holding the full input file for parsing -- we may pass this in the future + CHARACTER(1024) :: PriPath - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat - CHARACTER(ErrMsgLen) :: TmpErrMsg !< temporary error message - CHARACTER(1024) :: PriPath + INTEGER(IntKi) :: I, j !< Generic counter + INTEGER(IntKi) :: Lin_indx !< Generic counter + INTEGER(IntKi) :: SumFileUnit !< Unit number for the summary file + CHARACTER(256) :: SumFileName !< Name of the summary file + CHARACTER(256) :: EchoFileName !< Name of the summary file + CHARACTER(1), PARAMETER :: UVW(3) = (/'U','V','W'/) + CHARACTER(1), PARAMETER :: XYZ(3) = (/'X','Y','Z'/) + INTEGER(IntKi) :: TmpErrStat + CHARACTER(ErrMsgLen) :: TmpErrMsg !< temporary error message - ! Local Variables - INTEGER(IntKi) :: I, j !< Generic counter - INTEGER(IntKi) :: SumFileUnit !< Unit number for the summary file - CHARACTER(256) :: SumFileName !< Name of the summary file - CHARACTER(256) :: EchoFileName !< Name of the summary file - CHARACTER(1), PARAMETER :: UVW(3) = (/'U','V','W'/) - CHARACTER(1), PARAMETER :: XYZ(3) = (/'X','Y','Z'/) + !---------------------------------------------------------------------------------------------- + ! Initialize variables and check to see if this module has been initialized before. + !---------------------------------------------------------------------------------------------- - !---------------------------------------------------------------------------------------------- - ! Initialize variables and check to see if this module has been initialized before. - !---------------------------------------------------------------------------------------------- + ErrStat = ErrID_None + ErrMsg = "" + SumFileUnit = -1_IntKi ! set at beginning in case of error - ErrStat = ErrID_None - ErrMsg = "" - SumFileUnit = -1_IntKi ! set at beginning in case of error + ! Set a few variables. - ! Set a few variables. + p%DT = TimeInterval ! InflowWind does not require a specific time interval, so this is never changed. + CALL NWTC_Init() + CALL DispNVD( IfW_Ver ) - p%DT = TimeInterval ! InflowWind does not require a specific time interval, so this is never changed. - CALL NWTC_Init() - CALL DispNVD( IfW_Ver ) + !---------------------------------------------------------------------------------------------- + ! Read the input file + !---------------------------------------------------------------------------------------------- + ! Set the names of the files based on the inputfilename + p%RootFileName = InitInp%RootName + IF (LEN_TRIM(p%RootFileName) == 0) CALL GetRoot( InitInp%InputFileName, p%RootFileName ) + EchoFileName = TRIM(p%RootFileName)//".ech" + SumFileName = TRIM(p%RootFileName)//".sum" - !---------------------------------------------------------------------------------------------- - ! Read the input file - !---------------------------------------------------------------------------------------------- - ! Set the names of the files based on the inputfilename - p%RootFileName = InitInp%RootName - IF (LEN_TRIM(p%RootFileName) == 0) CALL GetRoot( InitInp%InputFileName, p%RootFileName ) - EchoFileName = TRIM(p%RootFileName)//".ech" - SumFileName = TRIM(p%RootFileName)//".sum" - ! these values (and others hard-coded in lidar_init) should be set in the input file, too - InputFileData%SensorType = InitInp%lidar%SensorType - InputFileData%NumPulseGate = InitInp%lidar%NumPulseGate - InputFileData%RotorApexOffsetPos = InitInp%lidar%RotorApexOffsetPos - InputFileData%LidRadialVel = InitInp%lidar%LidRadialVel - ! Parse all the InflowWind related input files and populate the *_InitDataType derived types - CALL GetPath( InitInp%InputFileName, PriPath ) - IF ( InitInp%UseInputFile ) THEN - CALL ProcessComFile( InitInp%InputFileName, InFileInfo, TmpErrStat, TmpErrMsg ) - ! For diagnostic purposes, the following can be used to display the contents - ! of the InFileInfo data structure. - ! call Print_FileInfo_Struct( CU, InFileInfo ) ! CU is the screen -- different number on different systems. - - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - ENDIF - - ELSE - CALL NWTC_Library_CopyFileInfoType( InitInp%PassedFileData, InFileInfo, MESH_NEWCOPY, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat >= AbortErrLev ) THEN - CALL Cleanup() - RETURN - ENDIF - - ENDIF - - CALL InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, InitInp%InputFileName, EchoFileName, InitInp%FixedWindFileRootName, InitInp%TurbineID, TmpErrStat, TmpErrMsg ) + ! Parse all the InflowWind related input files and populate the *_InitDataType derived types + CALL GetPath( InitInp%InputFileName, PriPath ) + IF ( InitInp%UseInputFile ) THEN + CALL ProcessComFile( InitInp%InputFileName, InFileInfo, TmpErrStat, TmpErrMsg ) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() - CALL InflowWind_DestroyInputFile( InputFileData, TmpErrStat, TmpErrMsg ) RETURN - ENDIF - ! let's tell InflowWind if an external module (e.g., FAST.Farm) is going to set the velocity grids. - - IF ( InitInp%Use4Dext) then - InputFileData%WindType = FDext_WindNumber - InputFileData%PropagationDir = 0.0_ReKi ! wind is in XYZ coordinates (already rotated if necessary), so don't rotate it again - END IF - - ! initialize sensor data: - CALL Lidar_Init( InitInp, InputGuess, p, ContStates, DiscStates, ConstrStateGuess, OtherStates, & - y, m, TimeInterval, InitOutData, TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - + ENDIF + ELSE + CALL NWTC_Library_CopyFileInfoType( InitInp%PassedFileData, InFileInfo, MESH_NEWCOPY, TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF + ENDIF - ! Validate the InflowWind input file information. + CALL InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, InitInp%InputFileName, EchoFileName, & + InitInp%FixedWindFileRootName, InitInp%TurbineID, TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF - CALL InflowWind_ValidateInput( InitInp, InputFileData, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + ! If wind is Grid4D from FAST.Farm, set input file values + IF (InitInp%Use4Dext) then + InputFileData%WindType = FDext_WindNumber + InputFileData%PropagationDir = 0.0_ReKi ! wind is in XYZ coordinates (already rotated if necessary), so don't rotate it again + InputFileData%VFlowAngle = 0.0_ReKi + InputFileData%VelInterpCubic = .false. + END IF + + ! initialize sensor data: + p%lidar%NumBeam = InputFileData%NumBeam + p%lidar%RotorApexOffsetPos = InputFileData%RotorApexOffsetPos + p%lidar%SensorType = InputFileData%SensorType + p%lidar%LidRadialVel = InputFileData%LidRadialVel + p%lidar%NumPulseGate = InputFileData%NumPulseGate + p%lidar%FocalDistanceX = InputFileData%FocalDistanceX + p%lidar%FocalDistanceY = InputFileData%FocalDistanceY + p%lidar%FocalDistanceZ = InputFileData%FocalDistanceZ + p%lidar%MeasurementInterval = InputFileData%MeasurementInterval + p%lidar%PulseSpacing = InputFileData%PulseSpacing + p%lidar%URefLid = InputFileData%URefLid + p%lidar%ConsiderHubMotion = InputFileData%ConsiderHubMotion - IF ( ErrStat>= AbortErrLev ) THEN - CALL Cleanup() - RETURN - ENDIF + + CALL Lidar_Init( InitInp, InputGuess, p, ContStates, DiscStates, ConstrStateGuess, OtherStates, & + y, m, TimeInterval, InitOutData, TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + + ! Validate the InflowWind input file information. + CALL InflowWind_ValidateInput( InitInp, InputFileData, TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - ! If a summary file was requested, open it. - IF ( InputFileData%SumPrint ) THEN - - ! Open the summary file and write some preliminary info to it - CALL InflowWind_OpenSumFile( SumFileUnit, SumFileName, IfW_Ver, InputFileData%WindType, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - ELSE - SumFileUnit = -1_IntKi ! So that we don't try to write to something. Used as indicator in submodules. - ENDIF + IF ( ErrStat>= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF - ! Allocate the arrays for passing points in and velocities out - CALL AllocAry( InputGuess%PositionXYZ, 3, InitInp%NumWindPoints, & - "Array of positions at which to find wind velocities", TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( y%VelocityUVW, 3, InitInp%NumWindPoints, & - "Array of wind velocities returned by InflowWind", TmpErrStat, TmpErrMsg ) + + ! If a summary file was requested, open it. + IF ( InputFileData%SumPrint ) THEN + + ! Open the summary file and write some preliminary info to it + CALL InflowWind_OpenSumFile( SumFileUnit, SumFileName, IfW_Ver, InputFileData%WindType, TmpErrStat, TmpErrMsg ) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat>= AbortErrLev ) THEN + IF (ErrStat >= AbortErrLev) THEN CALL Cleanup() RETURN ENDIF - InputGuess%PositionXYZ = 0.0_ReKi - y%VelocityUVW = 0.0_ReKi - - - !----------------------------------------------------------------- - ! Initialize the submodules based on the WindType - !----------------------------------------------------------------- + ELSE + SumFileUnit = -1_IntKi ! So that we don't try to write to something. Used as indicator in submodules. + ENDIF - - InitOutData%WindFileInfo%MWS = HUGE(InitOutData%WindFileInfo%MWS) + ! Allocate the array for passing points + CALL AllocAry( InputGuess%PositionXYZ, 3, InitInp%NumWindPoints, "Array of positions at which to find wind velocities", TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + InputGuess%PositionXYZ = 0.0_ReKi + InputGuess%HubPosition = 0.0_ReKi + CALL Eye(InputGuess%HubOrientation,TmpErrStat,TmpErrMsg) + + ! Allocate the array for passing velocities out + CALL AllocAry( y%VelocityUVW, 3, InitInp%NumWindPoints, "Array of wind velocities returned by InflowWind", TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF (ErrStat>= AbortErrLev) THEN + CALL Cleanup() + RETURN + ENDIF + y%VelocityUVW = 0.0_ReKi - SELECT CASE ( InputFileData%WindType ) + ! If requested, allocate the array for passing accelerations out + IF ( InitInp%OutputAccel ) THEN + CALL AllocAry( y%AccelUVW, 3, InitInp%NumWindPoints, "Array of wind accelerations returned by InflowWind", TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF (ErrStat>= AbortErrLev) THEN + CALL Cleanup() + RETURN + ENDIF + y%AccelUVW = 0.0_ReKi + ENDIF + !---------------------------------------------------------------------------- + ! Set flow field input data based on wind type + !---------------------------------------------------------------------------- - CASE ( Steady_WindNumber ) + InitOutData%WindFileInfo%MWS = HUGE(InitOutData%WindFileInfo%MWS) - ! This is a simplified case of the Uniform wind. For this, we set the OtherStates data manually and don't - ! call UniformWind_Init. We do however call it for the calculations. + select case(InputFileData%WindType) + case (Steady_WindNumber) - ! Set InitInp information -- It isn't necessary to do this since that information is only used in the Uniform_Init routine, which is not called. + Steady_InitInput%HWindSpeed = InputFileData%Steady_HWindSpeed + Steady_InitInput%RefHt = InputFileData%Steady_RefHt + Steady_InitInput%PLExp = InputFileData%Steady_PLexp - ! Set the Otherstates information - p%UniformWind%NumDataLines = 1_IntKi - p%UniformWind%RefHt = InputFileData%Steady_RefHt - p%UniformWind%RefLength = 1.0_ReKi ! This is not used since no shear gusts are used. Set to 1.0 so calculations don't bomb. - m%UniformWind%TimeIndex = 1 ! Used in UniformWind as a check if initialization was done. + p%FlowField%FieldType = Uniform_FieldType + call IfW_SteadyWind_Init(Steady_InitInput, SumFileUnit, p%FlowField%Uniform, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + ! Set reference position for wind rotation + p%FlowField%RefPosition = [0.0_ReKi, 0.0_ReKi, p%FlowField%Uniform%RefHeight] - CALL AllocAry( p%UniformWind%Tdata, p%UniformWind%NumDataLines, 'Uniform wind time', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%V, p%UniformWind%NumDataLines, 'Uniform wind horizontal wind speed', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%Delta, p%UniformWind%NumDataLines, 'Uniform wind direction', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%Upflow, p%UniformWind%NumDataLines, 'Uniform wind upflow angle', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%VZ, p%UniformWind%NumDataLines, 'Uniform vertical wind speed', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%HShr, p%UniformWind%NumDataLines, 'Uniform horizontal linear shear', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%VShr, p%UniformWind%NumDataLines, 'Uniform vertical power-law shear exponent', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%VLinShr, p%UniformWind%NumDataLines, 'Uniform vertical linear shear', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - - CALL AllocAry( p%UniformWind%VGust, p%UniformWind%NumDataLines, 'Uniform gust velocity', TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - ! Set the array information - - p%UniformWind%Tdata( :) = 0.0_ReKi - p%UniformWind%V( :) = InputFileData%Steady_HWindSpeed - p%UniformWind%Delta( :) = 0.0_ReKi - p%UniformWind%Upflow( :) = 0.0_ReKi - p%UniformWind%VZ( :) = 0.0_ReKi - p%UniformWind%HShr( :) = 0.0_ReKi - p%UniformWind%VShr( :) = InputFileData%Steady_PLexp - p%UniformWind%VLinShr(:) = 0.0_ReKi - p%UniformWind%VGust( :) = 0.0_ReKi + case (Uniform_WindNumber) + Uniform_InitInput%WindFileName = InputFileData%Uniform_FileName + Uniform_InitInput%RefHt = InputFileData%Uniform_RefHt + Uniform_InitInput%RefLength = InputFileData%Uniform_RefLength + Uniform_InitInput%PropagationDir = InputFileData%PropagationDir + Uniform_InitInput%UseInputFile = InitInp%WindType2UseInputFile + Uniform_InitInput%PassedFileData = InitInp%WindType2Data + p%FlowField%FieldType = Uniform_FieldType + call IfW_UniformWind_Init(Uniform_InitInput, SumFileUnit, p%FlowField%Uniform, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif - ! Now we have in effect initialized the IfW_UniformWind module, so set the parameters - p%UniformWind%RefLength = 1.0_ReKi ! This is done so that 0.0*(some stuff)/RefLength doesn't blow up. - p%UniformWind%RefHt = InputFileData%Steady_RefHt - m%UniformWind%TimeIndex = 1_IntKi + ! Set reference position for wind rotation + p%FlowField%RefPosition = [0.0_ReKi, 0.0_ReKi, p%FlowField%Uniform%RefHeight] - p%ReferenceHeight = p%UniformWind%RefHt - - ! Store wind file metadata - InitOutData%WindFileInfo%FileName = "" - InitOutData%WindFileInfo%WindType = Steady_WindNumber - InitOutData%WindFileInfo%RefHt = InputFileData%Steady_RefHt - InitOutData%WindFileInfo%RefHt_Set = .FALSE. ! The wind file does not set this - InitOutData%WindFileInfo%DT = 0.0_ReKi - InitOutData%WindFileInfo%NumTSteps = 1_IntKi - InitOutData%WindFileInfo%ConstantDT = .FALSE. - InitOutData%WindFileInfo%TRange = (/ 0.0_ReKi, 0.0_ReKi /) - InitOutData%WindFileInfo%TRange_Limited = .FALSE. ! This is constant - InitOutData%WindFileInfo%YRange = (/ 0.0_ReKi, 0.0_ReKi /) - InitOutData%WindFileInfo%YRange_Limited = .FALSE. ! Hard boundaries not enforced in y-direction - InitOutData%WindFileInfo%ZRange = (/ 0.0_ReKi, 0.0_ReKi /) - InitOutData%WindFileInfo%ZRange_Limited = .FALSE. ! Hard boundaries not enforced in z-direction - InitOutData%WindFileInfo%BinaryFormat = 0_IntKi - InitOutData%WindFileInfo%IsBinary = .FALSE. - InitOutData%WindFileInfo%TI = 0.0_ReKi - InitOutData%WindFileInfo%TI_listed = .FALSE. - InitOutData%WindFileInfo%MWS = InputFileData%Steady_HWindSpeed - - ! Write summary file information - IF ( SumFileUnit > 0 ) THEN - WRITE(SumFileUnit,'(A)',IOSTAT=TmpErrStat) - WRITE(SumFileUnit,'(A80)',IOSTAT=TmpErrStat) 'Steady wind -- Constant wind profile for entire simulation. No windfile read in.' - WRITE(SumFileUnit,'(A40,G12.4)',IOSTAT=TmpErrStat) ' Reference height: ',p%UniformWind%RefHt - WRITE(SumFileUnit,'(A40,G12.4)',IOSTAT=TmpErrStat) ' Horizontal velocity: ',p%UniformWind%V - WRITE(SumFileUnit,'(A40,G12.4)',IOSTAT=TmpErrStat) ' Vertical sheer power law exponent: ',p%UniformWind%VShr - - ! We are assuming that if the last line was written ok, then all of them were. - IF (TmpErrStat /= 0_IntKi) THEN - CALL SetErrStat(ErrID_Fatal,'Error writing to summary file.',ErrStat,ErrMsg,RoutineName) - CALL Cleanup - RETURN - ENDIF - ENDIF - - - CASE ( Uniform_WindNumber ) - - ! Set InitInp information - Uniform_InitData%ReferenceHeight = InputFileData%Uniform_RefHt - Uniform_InitData%RefLength = InputFileData%Uniform_RefLength - Uniform_InitData%WindFileName = InputFileData%Uniform_FileName - Uniform_InitData%SumFileUnit = SumFileUnit - - Uniform_InitData%UseInputFile = InitInp%WindType2UseInputFile - Uniform_InitData%PassedFileData = InitInp%WindType2Data - - ! Initialize the UniformWind module - CALL IfW_UniformWind_Init(Uniform_InitData, p%UniformWind, & - m%UniformWind, Uniform_InitOutData, TmpErrStat, TmpErrMsg) - - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, ' IfW_Init' ) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - if (InitInp%Linearize) then - ! we'd have to redo the math to get this correct, so for now we are disabling upflow for linearization: - if (any(p%UniformWind%upflow /= 0.0_ReKi) ) then - call SetErrStat(ErrID_Fatal, 'Upflow in uniform wind files must be 0 for linearization analysis in InflowWind.', ErrStat, ErrMsg, RoutineName) - CALL Cleanup() - return - end if - end if + case (TSFF_WindNumber) + TurbSim_InitInput%WindFileName = InputFileData%TSFF_FileName - p%ReferenceHeight = p%UniformWind%RefHt - - ! Store wind file metadata - InitOutData%WindFileInfo%FileName = InputFileData%Uniform_FileName - InitOutData%WindFileInfo%WindType = Uniform_WindNumber - InitOutData%WindFileInfo%RefHt = p%UniformWind%RefHt - InitOutData%WindFileInfo%RefHt_Set = .FALSE. ! The wind file does not set this - InitOutData%WindFileInfo%DT = Uniform_InitOutData%WindFileDT - InitOutData%WindFileInfo%NumTSteps = Uniform_InitOutData%WindFileNumTSteps - InitOutData%WindFileInfo%ConstantDT = Uniform_InitOutData%WindFileConstantDT - InitOutData%WindFileInfo%TRange = Uniform_InitOutData%WindFileTRange - InitOutData%WindFileInfo%TRange_Limited = .FALSE. ! UniformWind sets to limit of file if outside time bounds - InitOutData%WindFileInfo%YRange = (/ 0.0_ReKi, 0.0_ReKi /) - InitOutData%WindFileInfo%YRange_Limited = .FALSE. ! Hard boundaries not enforced in y-direction - InitOutData%WindFileInfo%ZRange = (/ 0.0_ReKi, 0.0_ReKi /) - InitOutData%WindFileInfo%ZRange_Limited = .FALSE. ! Hard boundaries not enforced in z-direction - InitOutData%WindFileInfo%BinaryFormat = 0_IntKi - InitOutData%WindFileInfo%IsBinary = .FALSE. - InitOutData%WindFileInfo%TI = 0.0_ReKi - InitOutData%WindFileInfo%TI_listed = .FALSE. - - if (p%UniformWind%NumDataLines == 1) then - InitOutData%WindFileInfo%MWS = p%UniformWind%V(1) - else - InitOutData%WindFileInfo%MWS = 0.0_ReKi - do i=2,p%UniformWind%NumDataLines - InitOutData%WindFileInfo%MWS = InitOutData%WindFileInfo%MWS + & - 0.5_ReKi*(p%UniformWind%V(i)+p%UniformWind%V(i-1))*& - (p%UniformWind%Tdata(i)-p%UniformWind%Tdata(i-1)) - end do - InitOutData%WindFileInfo%MWS = InitOutData%WindFileInfo%MWS / & - ( p%UniformWind%Tdata(p%UniformWind%NumDataLines) - p%UniformWind%Tdata(1) ) - end if - - - ! Check if the fist data point from the file is not along the X-axis while applying the windfield rotation - IF ( ( .NOT. EqualRealNos (p%UniformWind%Delta(1), 0.0_ReKi) ) .AND. & - ( .NOT. EqualRealNos (p%PropagationDir, 0.0_ReKi) ) ) THEN - CALL SetErrStat( ErrID_Warn,' Possible double rotation of wind field! Uniform wind file starts with a wind direction of '// & - TRIM(Num2LStr(p%UniformWind%Delta(1)*R2D))// & - ' degrees and the InflowWind input file specifies a PropagationDir of '// & - TRIM(Num2LStr(p%PropagationDir*R2D))//' degrees.', & - ErrStat,ErrMsg,RoutineName ) - ENDIF - - - - CASE ( TSFF_WindNumber ) - - ! Set InitInp information - TSFF_InitData%WindFileName = InputFileData%TSFF_FileName - TSFF_InitData%SumFileUnit = SumFileUnit - - ! Initialize the TSFFWind module - CALL IfW_TSFFWind_Init(TSFF_InitData, p%TSFFWind, & - m%TSFFWind, TSFF_InitOutData, TmpErrStat, TmpErrMsg) - CALL SetErrSTat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - ! Store wind file metadata - InitOutData%WindFileInfo%FileName = InputFileData%TSFF_FileName - - CALL SetFFInitOutData(p%TSFFWind%FF) - p%ReferenceHeight = InitOutData%WindFileInfo%RefHt + p%FlowField%FieldType = Grid3D_FieldType + call IfW_TurbSim_Init(TurbSim_InitInput, SumFileUnit, p%FlowField%Grid3D, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + ! Set reference position for wind rotation + p%FlowField%RefPosition = [0.0_ReKi, 0.0_ReKi, p%FlowField%Grid3D%RefHeight] - CASE ( BladedFF_WindNumber, BladedFF_Shr_WindNumber ) - - ! Set InitInp information - BladedFF_InitData%SumFileUnit = SumFileUnit - BladedFF_InitData%FixedWindFileRootName = InitInp%FixedWindFileRootName - BladedFF_InitData%TurbineID = InitInp%TurbineID - - if (InputFileData%WindType /= BladedFF_Shr_WindNumber) then - IF ( InitInp%FixedWindFileRootName ) THEN ! .TRUE. when FAST.Farm uses multiple instances of InflowWind for ambient wind data - IF ( InitInp%TurbineID == 0 ) THEN ! .TRUE. for the FAST.Farm low-resolution domain - InputFileData%BladedFF_FileName = TRIM(InputFileData%BladedFF_FileName)//TRIM(PathSep)//'Low' - ELSE ! FAST.Farm high-resolution domain(s) - InputFileData%BladedFF_FileName = TRIM(InputFileData%BladedFF_FileName)//TRIM(PathSep)//'HighT'//TRIM(Num2Lstr(InitInp%TurbineID)) - ENDIF - ENDIF - - BladedFF_InitData%WindFileName = TRIM(InputFileData%BladedFF_FileName)//'.wnd' - BladedFF_InitData%TowerFileExist = InputFileData%BladedFF_TowerFile - BladedFF_InitData%NativeBladedFmt = .false. - else - BladedFF_InitData%WindFileName = InputFileData%BladedFF_FileName - BladedFF_InitData%TowerFileExist = .false. - BladedFF_InitData%NativeBladedFmt = .true. - !call IfW_FFWind_CopyInitInput( InputFileData%FF, BladedFF_InitData%FF, MESH_NEWCOPY, TmpErrStat, TmpErrMsg) - end if - - ! Initialize the BladedFFWind module - CALL IfW_BladedFFWind_Init(BladedFF_InitData, p%BladedFFWind, m%BladedFFWind, & - BladedFF_InitOutData, TmpErrStat, TmpErrMsg) - CALL SetErrSTat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - ! Store wind file metadata - InitOutData%WindFileInfo%FileName = InputFileData%BladedFF_FileName - - CALL SetFFInitOutData(p%BladedFFWind%FF) - - InitOutData%WindFileInfo%TI = BladedFF_InitOutData%TI - InitOutData%WindFileInfo%TI_listed = .TRUE. ! This must be listed in the file someplace - - if (InputFileData%WindType == BladedFF_Shr_WindNumber) then - InputFileData%WindType = BladedFF_WindNumber - ! this overwrites the values of PropagationDir and VFlowAngle with values from the native Bladed file - InputFileData%PropagationDir = BladedFF_InitOutData%PropagationDir - InputFileData%VFlowAngle = BladedFF_InitOutData%VFlowAngle - end if - p%ReferenceHeight = InitOutData%WindFileInfo%RefHt - - - CASE ( HAWC_WindNumber ) - - ! Set InitInp information - HAWC_InitData%WindFileName(1) = InputFileData%HAWC_FileName_u - HAWC_InitData%WindFileName(2) = InputFileData%HAWC_FileName_v - HAWC_InitData%WindFileName(3) = InputFileData%HAWC_FileName_w - HAWC_InitData%SumFileUnit = SumFileUnit - HAWC_InitData%nx = InputFileData%HAWC_nx - HAWC_InitData%ny = InputFileData%HAWC_ny - HAWC_InitData%nz = InputFileData%HAWC_nz - - HAWC_InitData%dx = InputFileData%HAWC_dx - HAWC_InitData%dy = InputFileData%HAWC_dy - HAWC_InitData%dz = InputFileData%HAWC_dz - - call IfW_FFWind_CopyInitInput( InputFileData%FF, HAWC_InitData%FF, MESH_NEWCOPY, TmpErrStat, TmpErrMsg) - - - ! Initialize the HAWCWind module - CALL IfW_HAWCWind_Init(HAWC_InitData, p%HAWCWind, m%HAWCWind, & - TimeInterval, HAWC_InitOutData, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - - ! Store wind file metadata - CALL SetFFInitOutData(p%HAWCWind%FF) - InitOutData%WindFileInfo%FileName = InputFileData%HAWC_FileName_u - p%ReferenceHeight = InitOutData%WindFileInfo%RefHt - - - CASE (User_WindNumber) - - ! Initialize the UserWind module - CALL IfW_UserWind_Init(User_InitData, p%UserWind, m%UserWind, & - TimeInterval, User_InitOutData, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - p%ReferenceHeight = InputFileData%Steady_RefHt ! FIXME!!!! - - CASE ( FDext_WindNumber ) - - ! Initialize the UserWind module - CALL IfW_4Dext_Init(InitInp%FDext, p%FDext, m%FDext, TimeInterval, FDext_InitOutData, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - p%ReferenceHeight = p%FDext%pZero(3) + (p%FDext%n(3)/2) * p%FDext%delta(3) ! should be middle of grid, right???? FIXME - - CASE DEFAULT ! keep this check to make sure that all new wind types have been accounted for - CALL SetErrStat(ErrID_Fatal,' Undefined wind type.',ErrStat,ErrMsg,'InflowWind_Init()') - + case (BladedFF_WindNumber) + Bladed_InitInput%TurbineID = InitInp%TurbineID + IF ( InitInp%FixedWindFileRootName ) THEN ! .TRUE. when FAST.Farm uses multiple instances of InflowWind for ambient wind data + IF ( InitInp%TurbineID == 0 ) THEN ! .TRUE. for the FAST.Farm low-resolution domain + InputFileData%BladedFF_FileName = TRIM(InputFileData%BladedFF_FileName)//TRIM(PathSep)//'Low' + ELSE ! FAST.Farm high-resolution domain(s) + InputFileData%BladedFF_FileName = TRIM(InputFileData%BladedFF_FileName)//TRIM(PathSep)//'HighT'//TRIM(Num2Lstr(InitInp%TurbineID)) + ENDIF + ENDIF + Bladed_InitInput%WindType = BladedFF_WindNumber + Bladed_InitInput%WindFileName = TRIM(InputFileData%BladedFF_FileName)//'.wnd' + Bladed_InitInput%TowerFileExist = InputFileData%BladedFF_TowerFile + Bladed_InitInput%NativeBladedFmt = .false. + + p%FlowField%FieldType = Grid3D_FieldType + call IfW_Bladed_Init(Bladed_InitInput, SumFileUnit, Bladed_InitOutput, p%FlowField%Grid3D, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + ! Set reference position for wind rotation + p%FlowField%RefPosition = [0.0_ReKi, 0.0_ReKi, p%FlowField%Grid3D%RefHeight] + + case (BladedFF_Shr_WindNumber) + + Bladed_InitInput%WindType = BladedFF_Shr_WindNumber + Bladed_InitInput%TurbineID = InitInp%TurbineID + Bladed_InitInput%WindFileName = InputFileData%BladedFF_FileName + Bladed_InitInput%TowerFileExist = .false. + Bladed_InitInput%NativeBladedFmt = .true. + + p%FlowField%FieldType = Grid3D_FieldType + call IfW_Bladed_Init(Bladed_InitInput, SumFileUnit, Bladed_InitOutput, p%FlowField%Grid3D, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + ! Overwrite the values of PropagationDir and VFlowAngle with values from the native Bladed file + InputFileData%PropagationDir = Bladed_InitOutput%PropagationDir + InputFileData%VFlowAngle = Bladed_InitOutput%VFlowAngle + + ! Set reference position for wind rotation + p%FlowField%RefPosition = [0.0_ReKi, 0.0_ReKi, p%FlowField%Grid3D%RefHeight] + + case (HAWC_WindNumber) + + HAWC_InitInput%WindFileName(1) = InputFileData%HAWC_FileName_u + HAWC_InitInput%WindFileName(2) = InputFileData%HAWC_FileName_v + HAWC_InitInput%WindFileName(3) = InputFileData%HAWC_FileName_w + HAWC_InitInput%nx = InputFileData%HAWC_nx + HAWC_InitInput%ny = InputFileData%HAWC_ny + HAWC_InitInput%nz = InputFileData%HAWC_nz + HAWC_InitInput%dx = InputFileData%HAWC_dx + HAWC_InitInput%dy = InputFileData%HAWC_dy + HAWC_InitInput%dz = InputFileData%HAWC_dz + HAWC_InitInput%G3D%RefHt = InputFileData%FF%RefHt + HAWC_InitInput%G3D%ScaleMethod = InputFileData%FF%ScaleMethod + HAWC_InitInput%G3D%SF = InputFileData%FF%SF + HAWC_InitInput%G3D%SigmaF = InputFileData%FF%SigmaF + HAWC_InitInput%G3D%URef = InputFileData%FF%URef + HAWC_InitInput%G3D%WindProfileType = InputFileData%FF%WindProfileType + HAWC_InitInput%G3D%PLExp = InputFileData%FF%PLExp + HAWC_InitInput%G3D%Z0 = InputFileData%FF%Z0 + HAWC_InitInput%G3D%XOffset = InputFileData%FF%XOffset + + p%FlowField%FieldType = Grid3D_FieldType + call IfW_HAWC_Init(HAWC_InitInput, SumFileUnit, p%FlowField%Grid3D, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + ! Set reference position for wind rotation + p%FlowField%RefPosition = [0.0_ReKi, 0.0_ReKi, p%FlowField%Grid3D%RefHeight] + + case (User_WindNumber) + + p%FlowField%FieldType = User_FieldType + call IfW_User_Init(User_InitInput, SumFileUnit, p%FlowField%User, FileDat, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + ! Set reference position for wind rotation + p%FlowField%RefPosition = [0.0_ReKi, 0.0_ReKi, p%FlowField%User%RefHeight] + + case (FDext_WindNumber) + + p%FlowField%FieldType = Grid4D_FieldType + call IfW_Grid4D_Init(InitInp%FDext, p%FlowField%Grid4D, TmpErrStat, TmpErrMsg) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + ! Set reference position for wind rotation + p%FlowField%RefPosition = [0.0_ReKi, 0.0_ReKi, p%FlowField%Grid4D%RefHeight] + + case (Point_WindNumber) + + p%FlowField%FieldType = Point_FieldType + Points_InitInput%NumWindPoints = InitInp%NumWindPoints + call IfW_Points_Init(Points_InitInput, p%FlowField%Points, TmpErrStat, TmpErrMsg) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + endif + + ! Set reference position for wind rotation + p%FlowField%RefPosition = 0.0_ReKi + + case default + call SetErrStat(ErrID_Fatal, ' Undefined wind type.', ErrStat, ErrMsg, RoutineName) + return + end select + + !---------------------------------------------------------------------------- + ! Initialization by Field Type + !---------------------------------------------------------------------------- + + ! Reset flag indicating that acceleration field is valid + p%FlowField%AccFieldValid = .false. + + ! Copy flag for enabling cubic velocity interpolation + p%FlowField%VelInterpCubic = InputFileData%VelInterpCubic + + ! If cubic velocity interpolation requested and linearization is performed, + ! display message that cubic interpolation is incompatible with linearization + ! and will be disabled + if (p%FlowField%VelInterpCubic .and. InitInp%Linearize) then + call WrScr("InflowWind: Cubic interpolation of wind velocity is disabled for linearization") + p%FlowField%VelInterpCubic = .false. + end if + + ! Set box exceed flag and index + p%FlowField%Grid3D%BoxExceedAllowF = InitInp%BoxExceedAllowF + p%FlowField%Grid3D%BoxExceedAllowIdx = huge(1_IntKi) + if (InitInp%BoxExceedAllowF .and. (InitInp%BoxExceedAllowIdx <= InitInp%NumWindPoints)) then + p%FlowField%Grid3D%BoxExceedAllowIdx = InitInp%BoxExceedAllowIdx + end if + + ! Select based on field type + select case (p%FlowField%FieldType) + + case (Uniform_FieldType) + + if (InitInp%OutputAccel .or. p%FlowField%VelInterpCubic) then + call IfW_UniformField_CalcAccel(p%FlowField%Uniform, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + p%FlowField%AccFieldValid = .true. + end if + case (Grid3D_FieldType) - END SELECT - + ! Calculate acceleration + if (InitInp%OutputAccel .or. p%FlowField%VelInterpCubic) then + call IfW_Grid3DField_CalcAccel(p%FlowField%Grid3D, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + p%FlowField%AccFieldValid = .true. + end if - !IF ( InputFileData%CTTS_Flag ) THEN - ! ! Initialize the CTTS_Wind module - !ENDIF + ! Calculate field average if box is allowed to be exceeded + if (p%FlowField%Grid3D%BoxExceedAllowF .and. p%FlowField%Grid3D%BoxExceedAllowIdx > 0) then + call IfW_Grid3DField_CalcVelAvgProfile(p%FlowField%Grid3D, p%FlowField%AccFieldValid, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + end if + case default - !............................................ - ! Set the p and OtherStates for InflowWind using the input file information. - ! (set this after initializing modules so that we can use propagationDir and VFlowAng from native-Bladed files - !............................................ + if (InitInp%OutputAccel) then + call SetErrStat(ErrID_Fatal, "Acceleration not implemented for field type "// & + num2LStr(p%FlowField%FieldType), ErrStat, ErrMsg, RoutineName) + return + end if + if (p%FlowField%VelInterpCubic) then + call WrScr(' Cubic velocity interpolation not implemented for WindType '// & + num2LStr(InputFileData%WindType)) + p%FlowField%VelInterpCubic = .false. + end if - CALL InflowWind_SetParameters( InitInp, InputFileData, p, m, TmpErrStat, TmpErrMsg ) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat>= AbortErrLev ) THEN - CALL Cleanup() - RETURN - ENDIF + end select - + !---------------------------------------------------------------------------- + ! Set the p and OtherStates for InflowWind using the input file information. + ! (set this after initializing modules so that we can use PropagationDir + ! and VFlowAng from native-Bladed files + !---------------------------------------------------------------------------- -!!! !---------------------------------------------------------------------------------------------- -!!! ! Check for coherent turbulence file (KH superimposed on a background wind file) -!!! ! Initialize the CTWind module and initialize the module of the other wind type. -!!! !---------------------------------------------------------------------------------------------- -!!! -!!! IF ( p%WindType == CTP_WindNumber ) THEN -!!! -!!!!FIXME: remove this error message when we add CTP_Wind in -!!! CALL SetErrStat( ErrID_Fatal, ' InflowWind cannot currently handle the CTP_Wind type.', ErrStat, ErrMsg, ' IfW_Init' ) -!!! RETURN -!!! -!!! CALL CTTS_Init(UnWind, p%WindFileName, BackGrndValues, ErrStat, ErrMsg) -!!! IF (ErrStat /= 0) THEN -!!! p%WindType = Undef_Wind -!!! ErrStat = ErrID_Fatal -!!! RETURN -!!! END IF -!!! -!!! !FIXME: check this -!!! p%WindFileName = BackGrndValues%WindFile -!!! p%WindType = BackGrndValues%WindType -!!! ! CTTS_Flag = BackGrndValues%CoherentStr -!!! p%CTTS_Flag = BackGrndValues%CoherentStr ! This might be wrong -!!! -!!! ELSE -!!! -!!! p%CTTS_Flag = .FALSE. -!!! -!!! END IF -!!! + CALL InflowWind_SetParameters( InitInp, InputFileData, p, m, TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat>= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF + + ! Allocate arrays for the WriteOutput + CALL AllocAry( y%WriteOutput, p%NumOuts, 'WriteOutput', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat>= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF + y%WriteOutput = 0.0_ReKi + + CALL AllocAry( InitOutData%WriteOutputHdr, p%NumOuts, 'WriteOutputHdr', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat>= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF + CALL AllocAry( InitOutData%WriteOutputUnt, p%NumOuts, 'WriteOutputUnt', TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat>= AbortErrLev ) THEN + CALL Cleanup() + RETURN + ENDIF + InitOutData%WriteOutputHdr = p%OutParam(1:p%NumOuts)%Name + InitOutData%WriteOutputUnt = p%OutParam(1:p%NumOuts)%Units + !---------------------------------------------------------------------------- + ! Linearization + !---------------------------------------------------------------------------- - ! Allocate arrays for the WriteOutput + ! allocate and fill variables for linearization + if (InitInp%Linearize) then + + ! If field is uniform and there is any nonzero upflow, return error + ! Math needs work before this can be implemented + if (p%FlowField%FieldType == Uniform_FieldType) then + if (any(p%FlowField%Uniform%AngleV /= 0.0_ReKi)) then + call SetErrStat(ErrID_Fatal, 'Upflow in uniform wind files must be 0 for linearization analysis in InflowWind.', ErrStat, ErrMsg, RoutineName) + call Cleanup() + return + end if + end if - CALL AllocAry( y%WriteOutput, p%NumOuts, 'WriteOutput', TmpErrStat, TmpErrMsg ) + ! also need to add InputGuess%HubOrientation to the u%Linear items + CALL AllocAry(InitOutData%LinNames_u, InitInp%NumWindPoints*3 + size(InputGuess%HubPosition) + 3 + NumExtendedInputs, 'LinNames_u', TmpErrStat, TmpErrMsg) ! add hub position, orientation(3) + extended inputs CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat>= AbortErrLev ) THEN - CALL Cleanup() - RETURN - ENDIF - y%WriteOutput = 0.0_ReKi - - CALL AllocAry( InitOutData%WriteOutputHdr, p%NumOuts, 'WriteOutputHdr', TmpErrStat, TmpErrMsg ) + CALL AllocAry(InitOutData%RotFrame_u, InitInp%NumWindPoints*3 + size(InputGuess%HubPosition) + 3 + NumExtendedInputs, 'RotFrame_u', TmpErrStat, TmpErrMsg) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( InitOutData%WriteOutputUnt, p%NumOuts, 'WriteOutputUnt', TmpErrStat, TmpErrMsg ) + CALL AllocAry(InitOutData%IsLoad_u, InitInp%NumWindPoints*3 + size(InputGuess%HubPosition) + 3 + NumExtendedInputs, 'IsLoad_u', TmpErrStat, TmpErrMsg) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF ( ErrStat>= AbortErrLev ) THEN - CALL Cleanup() - RETURN - ENDIF - - InitOutData%WriteOutputHdr = p%OutParam(1:p%NumOuts)%Name - InitOutData%WriteOutputUnt = p%OutParam(1:p%NumOuts)%Units - - - ! allocate and fill variables for linearization: - if (InitInp%Linearize) then - - CALL AllocAry(InitOutData%LinNames_u, InitInp%NumWindPoints*3 + 3, 'LinNames_u', TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CALL AllocAry(InitOutData%RotFrame_u, InitInp%NumWindPoints*3 + 3, 'RotFrame_u', TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CALL AllocAry(InitOutData%IsLoad_u, InitInp%NumWindPoints*3 + 3, 'IsLoad_u', TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CALL AllocAry(InitOutData%LinNames_y, InitInp%NumWindPoints*3+p%NumOuts, 'LinNames_y', TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - CALL AllocAry(InitOutData%RotFrame_y, InitInp%NumWindPoints*3+p%NumOuts, 'RotFrame_y', TmpErrStat, TmpErrMsg) - CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) - IF (ErrStat >= AbortErrLev) THEN - CALL Cleanup() - RETURN - ENDIF - - do i=1,InitInp%NumWindPoints - do j=1,3 - InitOutData%LinNames_y((i-1)*3+j) = UVW(j)//'-component inflow velocity at node '//trim(num2lstr(i))//', m/s' - InitOutData%LinNames_u((i-1)*3+j) = XYZ(j)//'-component position of node '//trim(num2lstr(i))//', m' - end do - end do - - InitOutData%LinNames_u(InitInp%NumWindPoints*3 + 1) = 'Extended input: horizontal wind speed (steady/uniform wind), m/s' - InitOutData%LinNames_u(InitInp%NumWindPoints*3 + 2) = 'Extended input: vertical power-law shear exponent, -' - InitOutData%LinNames_u(InitInp%NumWindPoints*3 + 3) = 'Extended input: propagation direction, rad' - - do i=1,p%NumOuts - InitOutData%LinNames_y(i+3*InitInp%NumWindPoints) = trim(p%OutParam(i)%Name)//', '//p%OutParam(i)%Units + CALL AllocAry(InitOutData%LinNames_y, InitInp%NumWindPoints*3 + size(y%DiskVel) + p%NumOuts, 'LinNames_y', TmpErrStat, TmpErrMsg) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + CALL AllocAry(InitOutData%RotFrame_y, InitInp%NumWindPoints*3 + size(y%DiskVel) + p%NumOuts, 'RotFrame_y', TmpErrStat, TmpErrMsg) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF (ErrStat >= AbortErrLev) THEN + CALL Cleanup() + RETURN + ENDIF + + do i=1,InitInp%NumWindPoints + do j=1,3 + InitOutData%LinNames_y((i-1)*3+j) = UVW(j)//'-component inflow velocity at node '//trim(num2lstr(i))//', m/s' + InitOutData%LinNames_u((i-1)*3+j) = XYZ(j)//'-component position of node '//trim(num2lstr(i))//', m' end do + end do - ! IfW inputs and outputs are in the global, not rotating frame - InitOutData%RotFrame_u = .false. - InitOutData%RotFrame_y = .false. - - InitOutData%IsLoad_u = .false. ! IfW inputs for linearization are not loads - - !InitOutData%PropagationDir = -p%PropagationDir - !InitOutData%RefHt = p%UniformWind%RefHt - !InitOutData%RefLength = p%UniformWind%RefLength - - end if - - - ! Set the version information in InitOutData - InitOutData%Ver = IfW_Ver - - - CALL CleanUp() + ! hub position + Lin_Indx = InitInp%NumWindPoints*3 + do j=1,3 + InitOutData%LinNames_y(Lin_Indx+j) = 'average '//UVW(j)//'-component rotor-disk velocity, m/s' + InitOutData%LinNames_u(Lin_Indx+j) = XYZ(j)//'-component position of moving hub, m' + end do + Lin_Indx = Lin_Indx + 3 + + ! hub orientation angles + do j=1,3 + InitOutData%LinNames_u(Lin_Indx+j) = XYZ(j)//' orientation of moving hub, rad' + end do + Lin_Indx = Lin_Indx + 3 + + InitOutData%LinNames_u(Lin_Indx + 1) = 'Extended input: horizontal wind speed (steady/uniform wind), m/s' + InitOutData%LinNames_u(Lin_Indx + 2) = 'Extended input: vertical power-law shear exponent, -' + InitOutData%LinNames_u(Lin_Indx + 3) = 'Extended input: propagation direction, rad' + + do i=1,p%NumOuts + InitOutData%LinNames_y(i+3*InitInp%NumWindPoints+size(y%DiskVel)) = trim(p%OutParam(i)%Name)//', '//p%OutParam(i)%Units + end do + ! IfW inputs and outputs are in the global, not rotating frame + InitOutData%RotFrame_u = .false. + InitOutData%RotFrame_y = .false. - RETURN + InitOutData%IsLoad_u = .false. ! IfW inputs for linearization are not loads + + end if + + ! Set the version information in InitOutData + InitOutData%Ver = IfW_Ver + CALL CleanUp() - !---------------------------------------------------------------------------------------------------- CONTAINS SUBROUTINE CleanUp() @@ -761,6 +663,7 @@ SUBROUTINE CleanUp() ! Ignore error messages from InFileInfo destruction call NWTC_Library_DestroyFileInfoType( InFileInfo, TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) ! Close the summary file if we were writing one IF ( SumFileUnit > 0 ) THEN @@ -768,45 +671,7 @@ SUBROUTINE CleanUp() CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) ENDIF - END SUBROUTINE CleanUp - - - SUBROUTINE SetFFInitOutData(FFp) - - TYPE(IfW_FFWind_ParameterType), INTENT(IN ) :: FFp !< Parameters - - - InitOutData%WindFileInfo%WindType = p%WindType - InitOutData%WindFileInfo%RefHt = FFp%RefHt - InitOutData%WindFileInfo%RefHt_Set = .TRUE. - InitOutData%WindFileInfo%DT = FFp%FFDTime - InitOutData%WindFileInfo%NumTSteps = FFp%NFFSteps - InitOutData%WindFileInfo%ConstantDT = .TRUE. - IF ( FFp%Periodic ) THEN - InitOutData%WindFileInfo%TRange = (/ 0.0_ReKi, FFp%TotalTime /) - InitOutData%WindFileInfo%TRange_Limited = .FALSE. - ELSE ! Shift the time range to compensate for the shifting of the wind grid - InitOutData%WindFileInfo%TRange = (/ 0.0_ReKi, FFp%TotalTime /) - FFp%InitXPosition*FFp%InvMFFWS - InitOutData%WindFileInfo%TRange_Limited = .TRUE. - ENDIF - InitOutData%WindFileInfo%YRange = (/ -FFp%FFYHWid, FFp%FFYHWid /) - InitOutData%WindFileInfo%YRange_Limited = .TRUE. ! Hard boundaries enforced in y-direction - IF ( p%TSFFWind%FF%NTGrids > 0 ) THEN ! have tower data - InitOutData%WindFileInfo%ZRange = (/ 0.0_Reki, FFp%RefHt + FFp%FFZHWid /) - ELSE - InitOutData%WindFileInfo%ZRange = (/ FFp%GridBase, & - FFp%GridBase + FFp%FFZHWid*2.0 /) - ENDIF - InitOutData%WindFileInfo%ZRange_Limited = .TRUE. - InitOutData%WindFileInfo%BinaryFormat = FFp%WindFileFormat - InitOutData%WindFileInfo%IsBinary = .TRUE. - InitOutData%WindFileInfo%MWS = FFp%MeanFFWS - - InitOutData%WindFileInfo%TI = 0.0_ReKi - InitOutData%WindFileInfo%TI_listed = .FALSE. - - END SUBROUTINE SetFFInitOutData END SUBROUTINE InflowWind_Init @@ -830,14 +695,8 @@ SUBROUTINE InflowWind_CalcOutput( Time, InputData, p, & ContStates, DiscStates, ConstrStates, & ! Framework required states -- empty in this case. OtherStates, OutputData, m, ErrStat, ErrMsg ) - - IMPLICIT NONE - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_CalcOutput" - - ! Inputs / Outputs - REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds TYPE(InflowWind_InputType), INTENT(IN ) :: InputData !< Inputs at Time TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters @@ -847,24 +706,18 @@ SUBROUTINE InflowWind_CalcOutput( Time, InputData, p, & TYPE(InflowWind_OtherStateType), INTENT(IN ) :: OtherStates !< Other/optimization states at Time TYPE(InflowWind_OutputType), INTENT(INOUT) :: OutputData !< Outputs computed at Time (IN for mesh reasons and data allocation) TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - ! Local variables INTEGER(IntKi) :: i ! Temporary variables for error handling INTEGER(IntKi) :: TmpErrStat CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" - ! Allocate the velocity array to get out IF ( .NOT. ALLOCATED(OutputData%VelocityUVW) ) THEN CALL AllocAry( OutputData%VelocityUVW, 3, SIZE(InputData%PositionXYZ,DIM=2), & @@ -877,15 +730,26 @@ SUBROUTINE InflowWind_CalcOutput( Time, InputData, p, & ENDIF !----------------------------- - ! Outputs: OutputData%VelocityUVW and OutputData%DiskVel + ! Outputs: OutputData%VelocityUVW !----------------------------- - - - CALL CalculateOutput( Time, InputData, p, & - ContStates, DiscStates, ConstrStates, & + CALL CalculateOutput( Time, InputData, p, ContStates, DiscStates, ConstrStates, & OtherStates, OutputData, m, .TRUE., TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + !----------------------------- + ! Output: OutputData%DiskVel + !----------------------------- + CALL InflowWind_GetSpatialAverage( Time, InputData, p, ContStates, DiscStates, ConstrStates, & + OtherStates, m, OutputData%DiskVel, TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + + !----------------------------- + ! Output: OutputData%HubVel + !----------------------------- + CALL InflowWind_GetHubValues( Time, InputData, p, ContStates, DiscStates, ConstrStates, & + OtherStates, m, OutputData%HubVel, TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + !----------------------------- ! Outputs: OutputData%lidar%LidSpeed and OutputData%lidar%WtTrunc !----------------------------- @@ -922,81 +786,36 @@ END SUBROUTINE InflowWind_CalcOutput !> Clean up the allocated variables and close all open files. Reset the initialization flag so !! that we have to reinitialize before calling the routines again. SUBROUTINE InflowWind_End( InputData, p, ContStates, DiscStates, ConstrStateGuess, OtherStates, & - y, m, ErrStat, ErrMsg ) - - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_End" - - ! Initialization data and guesses + y, m, ErrStat, ErrMsg ) TYPE(InflowWind_InputType), INTENT(INOUT) :: InputData !< Input data for initialization - TYPE(InflowWind_ParameterType), INTENT(INOUT) :: p !< Parameters + TYPE(InflowWind_ParameterType), INTENT(INOUT) :: p !< Parameters TYPE(InflowWind_ContinuousStateType), INTENT(INOUT) :: ContStates !< Continuous states TYPE(InflowWind_DiscreteStateType), INTENT(INOUT) :: DiscStates !< Discrete states TYPE(InflowWind_ConstraintStateType), INTENT(INOUT) :: ConstrStateGuess !< Guess of the constraint states TYPE(InflowWind_OtherStateType), INTENT(INOUT) :: OtherStates !< Other/optimization states - TYPE(InflowWind_OutputType), INTENT(INOUT) :: y !< Output data - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) - - - ! Error Handling - + TYPE(InflowWind_OutputType), INTENT(INOUT) :: y !< Output data + TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc variables for optimization (not copied in glue code) INTEGER( IntKi ), INTENT( OUT) :: ErrStat !< error status CHARACTER(*), INTENT( OUT) :: ErrMsg !< error message + CHARACTER(*), PARAMETER :: RoutineName="InflowWind_End" ErrStat = ErrID_None ErrMsg = "" - ! End the sub-modules (deallocates their arrays and closes their files): - - SELECT CASE ( p%WindType ) - - CASE (Steady_WindNumber, Uniform_WindNumber) ! The Steady wind is a simple wrapper for the UniformWind module. - CALL IfW_UniformWind_End( p%UniformWind, m%UniformWind, ErrStat, ErrMsg ) - - CASE (TSFF_WindNumber) - CALL IfW_TSFFWind_End( p%TSFFWind, m%TSFFWind, ErrStat, ErrMsg ) - - CASE (BladedFF_WindNumber) - CALL IfW_BladedFFWind_End( p%BladedFFWind, m%BladedFFWind, ErrStat, ErrMsg ) - - CASE (HAWC_WindNumber) - CALL IfW_HAWCWind_End( p%HAWCWind, m%HAWCWind, ErrStat, ErrMsg ) - - CASE (User_WindNumber) - CALL IfW_UserWind_End( p%UserWind, m%UserWind, ErrStat, ErrMsg ) - - CASE (FDext_WindNumber) - CALL IfW_4Dext_End( p%FDext, m%FDext, ErrStat, ErrMsg ) - - CASE ( Undef_WindNumber ) - ! Do nothing - - CASE DEFAULT ! keep this check to make sure that all new wind types have been accounted for - CALL SetErrStat(ErrID_Fatal,' Undefined wind type.',ErrStat,ErrMsg,RoutineName) - - END SELECT - -!!! ! IF (CTTS_Flag) CALL CTTS_Terminate( ErrStat ) !FIXME: should it be this line or the next? -!!! CALL CTTS_Terminate( ErrStat, ErrMsg ) - + ! Reset the wind type so that the initialization routine must be called + p%WindType = Undef_WindNumber + ! Destroy all inflow wind derived types CALL InflowWind_DestroyInput( InputData, ErrStat, ErrMsg ) - CALL InflowWind_DestroyParam( p, ErrStat, ErrMsg ) + CALL InflowWind_DestroyParam( p, ErrStat, ErrMsg, DeallocatePointers=.true. ) CALL InflowWind_DestroyContState( ContStates, ErrStat, ErrMsg ) CALL InflowWind_DestroyDiscState( DiscStates, ErrStat, ErrMsg ) CALL InflowWind_DestroyConstrState( ConstrStateGuess, ErrStat, ErrMsg ) CALL InflowWind_DestroyOtherState( OtherStates, ErrStat, ErrMsg ) CALL InflowWind_DestroyOutput( y, ErrStat, ErrMsg ) CALL InflowWind_DestroyMisc( m, ErrStat, ErrMsg ) - - - ! Reset the wind type so that the initialization routine must be called - p%WindType = Undef_WindNumber - p%CTTS_Flag = .FALSE. - END SUBROUTINE InflowWind_End @@ -1167,10 +986,15 @@ SUBROUTINE InflowWind_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrSt CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary error message CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_JacobianPInput' - REAL(R8Ki) :: local_dYdu(3,6) + + REAL(R8Ki) :: local_dYdu(3,3+NumExtendedInputs) integer :: i, n integer :: i_start, i_end ! indices for input/output start and end integer :: node, comp + integer :: n_inputs + integer :: n_outputs + integer :: i_ExtendedInput_start + integer :: i_WriteOutput ! Initialize ErrStat @@ -1181,12 +1005,17 @@ SUBROUTINE InflowWind_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrSt IF ( PRESENT( dYdu ) ) THEN + n_outputs = SIZE(u%PositionXYZ)+p%NumOuts + size(y%DiskVel) + n_inputs = SIZE(u%PositionXYZ)+size(u%HubPosition) + 3 + NumExtendedInputs ! need to add 3 for u%HubOrientation + i_ExtendedInput_start = n_inputs - NumExtendedInputs + 1 ! index for extended inputs starts 2 from end (encompasses 3 values: V, VShr, PropDir) + i_WriteOutput = n_outputs - p%NumOuts ! index for where write outputs begin is i_WriteOutput + 1 + ! Calculate the partial derivative of the output functions (Y) with respect to the inputs (u) here: ! outputs are all velocities at all positions plus the WriteOutput values ! if (.not. ALLOCATED(dYdu)) then - CALL AllocAry( dYdu, SIZE(u%PositionXYZ)+p%NumOuts, SIZE(u%PositionXYZ)+3, 'dYdu', ErrStat2, ErrMsg2 ) + CALL AllocAry( dYdu, n_outputs, n_inputs, 'dYdu', ErrStat2, ErrMsg2 ) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) end if @@ -1202,39 +1031,66 @@ SUBROUTINE InflowWind_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrSt n = SIZE(u%PositionXYZ,2) ! these are the positions used in the module coupling do i=1,n - ! note that p%RotToWind(1,1) = cos(p%PropagationDir) and p%RotToWind(2,1) = sin(p%PropagationDir), which are the + ! note that p%FlowField%RotToWind(1,1) = cos(p%PropagationDir) and p%FlowField%RotToWind(2,1) = sin(p%PropagationDir), which are the ! values we need to compute the jacobian. !!!FIX ME with the propagation values!!!! - call IfW_UniformWind_JacobianPInput( t, u%PositionXYZ(:,i), p%RotToWind(1,1), p%RotToWind(2,1), p%UniformWind, m%UniformWind, local_dYdu ) + call IfW_UniformWind_JacobianPInput( p%FlowField%Uniform, t, u%PositionXYZ(:,i), p%FlowField%RotToWind(1,1), p%FlowField%RotToWind(2,1), local_dYdu ) i_end = 3*i i_start= i_end - 2 dYdu(i_start:i_end,i_start:i_end) = local_dYdu(:,1:3) - dYdu(i_start:i_end,n*3+1:) = local_dYdu(:,4:6) ! extended inputs + dYdu(i_start:i_end, i_ExtendedInput_start:) = local_dYdu(:,4:6) ! extended inputs - end do + end do + + + ! see InflowWind_GetSpatialAverage(): + + ! location of y%DiskAvg + i_start = 3*n + 1 + i_end = i_start + 2 + + dYdu(i_start:i_end,:) = 0.0_R8Ki ! initialize because we're going to create averages + + do i=1,IfW_NumPtsAvg + m%u_Avg%PositionXYZ(:,i) = matmul(u%HubOrientation,p%PositionAvg(:,i)) + u%HubPosition +!!!FIX ME with the propagation values!!!! + call IfW_UniformWind_JacobianPInput( p%FlowField%Uniform, t, m%u_Avg%PositionXYZ(:,i), p%FlowField%RotToWind(1,1), p%FlowField%RotToWind(2,1), local_dYdu ) + + ! y%DiskAvg has the same index as u%HubPosition + ! Also note that partial_(m%u_Avg%PositionXYZ) / partial_(u%HubPosition) is identity, so we can skip that part of the chain rule for these derivatives: + dYdu(i_start:i_end,i_start:i_end) = dYdu(i_start:i_end, i_start:i_end) + local_dYdu(:,1:3) + dYdu(i_start:i_end, i_ExtendedInput_start:) = dYdu(i_start:i_end, i_ExtendedInput_start:) + local_dYdu(:,4:6) ! extended inputs + end do + dYdu(i_start:i_end,i_start:i_end) = dYdu(i_start:i_end, i_start:i_end) / REAL(IfW_NumPtsAvg,R8Ki) + dYdu(i_start:i_end,i_ExtendedInput_start:) = dYdu(i_start:i_end, i_ExtendedInput_start:) / REAL(IfW_NumPtsAvg,R8Ki) +!FIX ME: + ! need to calculate dXYZdHubOrient = partial_(m%u_Avg%PositionXYZ) / partial_(u%HubOrientation) + !dYdu(i_start:i_end,(i_start+3):(i_end+3)) = matmul( dYdu(i_start:i_end,i_start:i_end), dXYZdHubOrient ) + ! these are the InflowWind WriteOutput velocities (and note that we may not have all of the components of each point) ! they do not depend on the inputs, so the derivatives w.r.t. X, Y, Z are all zero - do i=1, p%NumOuts + do i=1, p%NumOuts node = p%OutParamLinIndx(1,i) ! output node comp = p%OutParamLinIndx(2,i) ! component of output node if (node > 0) then !!!FIX ME with the propagation values!!!! - call IfW_UniformWind_JacobianPInput( t, p%WindViXYZ(:,node), p%RotToWind(1,1), p%RotToWind(2,1), p%UniformWind, m%UniformWind, local_dYdu ) + call IfW_UniformWind_JacobianPInput( p%FlowField%Uniform, t, p%WindViXYZ(:,node), p%FlowField%RotToWind(1,1), p%FlowField%RotToWind(2,1), local_dYdu ) else local_dYdu = 0.0_R8Ki - end if + comp = 1 + end if - dYdu(3*n+i, 3*n+1:) = p%OutParam(i)%SignM * local_dYdu( comp , 4:6) - end do + dYdu(i_WriteOutput+i, i_ExtendedInput_start:) = p%OutParam(i)%SignM * local_dYdu( comp , 4:6) + end do CASE DEFAULT - END SELECT + END SELECT END IF @@ -1252,6 +1108,121 @@ SUBROUTINE InflowWind_JacobianPInput( t, u, p, x, xd, z, OtherState, y, m, ErrSt END SUBROUTINE InflowWind_JacobianPInput +!.................................................................................................................................. +!> Routine to compute the Jacobians of the output (Y) function with respect to the inputs (u). The partial +!! derivative dY/du is returned. This submodule does not follow the modularization framework. +SUBROUTINE IfW_UniformWind_JacobianPInput(UF, t, Position, CosPropDir, SinPropDir, dYdu) + USE IfW_FlowField, only : UniformField_InterpLinear, UniformField_InterpCubic + + TYPE(UniformFieldType), INTENT(IN ) :: UF !< Uniform field derived type + REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds + REAL(ReKi), INTENT(IN ) :: Position(3) !< XYZ Position at which to find velocity (operating point) + REAL(ReKi), INTENT(IN ) :: CosPropDir !< cosine of InflowWind propagation direction + REAL(ReKi), INTENT(IN ) :: SinPropDir !< sine of InflowWind propagation direction + REAL(R8Ki), INTENT(INOUT) :: dYdu(3,6) !< Partial derivatives of output functions (Y) with respect to the inputs (u) + + TYPE(UniformField_Interp) :: op ! interpolated values of InterpParams + REAL(R8Ki) :: RotatePosition(3) !< rotated position + REAL(R8Ki) :: dVhdx ! temporary value to hold partial v_h partial X + REAL(R8Ki) :: dVhdy ! temporary value to hold partial v_h partial Y + REAL(R8Ki) :: dVhdz ! temporary value to hold partial v_h partial Z + REAL(R8Ki) :: tmp_du ! temporary value to hold calculations that are part of multiple components + REAL(R8Ki) :: tmp_dv ! temporary value to hold calculations that are part of multiple components + REAL(R8Ki) :: dVhdPD ! temporary value to hold partial v_h partial propagation direction + REAL(R8Ki) :: dVhdV ! temporary value to hold partial v_h partial V + REAL(R8Ki) :: Vh ! temporary value to hold v_h + REAL(R8Ki) :: dVhdVShr ! temporary value to hold partial v_h partial VShr + REAL(R8Ki) :: zr + + if ( Position(3) < 0.0_ReKi .or. EqualRealNos(Position(3), 0.0_ReKi)) then + dYdu = 0.0_R8Ki + return + end if + + !------------------------------------------------------------------------------------------------- + !> 1. Interpolate uniform field to get values at operating point + !------------------------------------------------------------------------------------------------- + + op = UniformField_InterpLinear(UF, t) + + RotatePosition(1) = Position(1)*cosPropDir - Position(2)*sinPropDir + RotatePosition(2) = Position(1)*sinPropDir + Position(2)*cosPropDir + RotatePosition(3) = Position(3) + + !------------------------------------------------------------------------------------------------- + !> 2. Calculate \f$ \frac{\partial Y_{Output \, Equations}}{\partial u_{inputs}} = \begin{bmatrix} + !! \frac{\partial Vt_u}{\partial X} & \frac{\partial Vt_u}{\partial Y} & \frac{\partial Vt_u}{\partial Z} \\ + !! \frac{\partial Vt_v}{\partial X} & \frac{\partial Vt_v}{\partial Y} & \frac{\partial Vt_v}{\partial Z} \\ + !! \frac{\partial Vt_w}{\partial X} & \frac{\partial Vt_w}{\partial Y} & \frac{\partial Vt_w}{\partial Z} \\ + !! \end{bmatrix} \f$ + !------------------------------------------------------------------------------------------------- + + zr = RotatePosition(3)/UF%RefHeight + tmp_du = op%VelH * op%ShrH / UF%RefLength * CosPropDir + dVhdx = tmp_du * op%SinAngleH + dVhdy = tmp_du * op%CosAngleH + dVhdz = op%VelH * ( op%ShrV / UF%RefHeight * zr**(op%ShrV-1.0_R8Ki) + op%LinShrV/UF%RefLength) + + dVhdV = ( ( RotatePosition(3)/UF%RefHeight ) ** op%ShrV & ! power-law wind shear + + ( op%ShrH * ( RotatePosition(2) * op%CosAngleH + RotatePosition(1) * op%SinAngleH ) & ! horizontal linear shear + + op%LinShrV * ( RotatePosition(3) - UF%RefHeight ) )/UF%RefLength ) ! vertical linear shear + Vh = op%VelH * dVhdV + op%VelGust + + dVhdVShr = op%VelH * zr**op%ShrV * log(zr) + dVhdPD = op%VelH * op%ShrH / UF%RefLength * ( RotatePosition(1) * op%CosAngleH - RotatePosition(2) * op%SinAngleH ) + + tmp_du = CosPropDir*op%CosAngleH - SinPropDir*op%SinAngleH + tmp_dv = -SinPropDir*op%CosAngleH - CosPropDir*op%SinAngleH + + !> \f$ \frac{\partial Vt_u}{\partial X} = \left[\cos(PropagationDir)\cos(Delta) - \sin(PropagationDir)\sin(Delta) \right] + !! V \, \frac{H_{LinShr}}{RefWid} \, \sin(Delta) \cos(PropagationDir) \f$ + dYdu(1,1) = tmp_du*dVhdx + !> \f$ \frac{\partial Vt_v}{\partial X} = \left[-\sin(PropagationDir)\cos(Delta) - \cos(PropagationDir)\sin(Delta) \right] + !! V \, \frac{H_{LinShr}}{RefWid} \, \sin(Delta) \cos(PropagationDir) \f$ + dYdu(2,1) = tmp_dv*dVhdx + !> \f$ \frac{\partial Vt_w}{\partial X} = 0 \f$ + dYdu(3,1) = 0.0_R8Ki + + !> \f$ \frac{\partial Vt_u}{\partial Y} = \left[\cos(PropagationDir)\cos(Delta) - \sin(PropagationDir)\sin(Delta) \right] + !! V \, \frac{H_{LinShr}}{RefWid} \, \cos(Delta) \cos(PropagationDir) \f$ + dYdu(1,2) = tmp_du*dVhdy + !> \f$ \frac{\partial Vt_v}{\partial Y} = \left[-\sin(PropagationDir)\cos(Delta) - \cos(PropagationDir)\sin(Delta) \right] + !! V \, \frac{H_{LinShr}}{RefWid} \, \cos(Delta) \cos(PropagationDir) \f$ + dYdu(2,2) = tmp_dv*dVhdy + !> \f$ \frac{\partial Vt_w}{\partial Y} = 0 \f$ + dYdu(3,2) = 0.0_R8Ki + + !> \f$ \frac{\partial Vt_u}{\partial Z} = \left[\cos(PropagationDir)\cos(Delta) - \sin(PropagationDir)\sin(Delta) \right] + !! V \, \left[ \frac{V_{shr}}{Z_{ref}} \left( \frac{Z}{Z_{ref}} \right) ^ {V_{shr}-1} + \frac{V_{LinShr}}{RefWid} \right] \f$ + dYdu(1,3) = tmp_du*dVhdz + !> \f$ \frac{\partial Vt_v}{\partial Z} = \left[-\sin(PropagationDir)\cos(Delta) - \cos(PropagationDir)\sin(Delta) \right] + !! V \, \left[ \frac{V_{shr}}{Z_{ref}} \left( \frac{Z}{Z_{ref}} \right) ^ {V_{shr}-1} + \frac{V_{LinShr}}{RefWid} \right] \f$ + dYdu(2,3) = tmp_dv*dVhdz + !> \f$ \frac{\partial Vt_w}{\partial Z} = 0 \f$ + dYdu(3,3) = 0.0_R8Ki + + ! \f$ \frac{\partial Vt_u}{\partial V} = \f$ + dYdu(1,4) = tmp_du*dVhdV + ! \f$ \frac{\partial Vt_v}{\partial V} = \f$ + dYdu(2,4) = tmp_dv*dVhdV + !> \f$ \frac{\partial Vt_w}{\partial V} = 0 \f$ + dYdu(3,4) = 0.0_R8Ki + + ! \f$ \frac{\partial Vt_u}{\partial VShr} = \f$ + dYdu(1,5) = tmp_du*dVhdVShr + ! \f$ \frac{\partial Vt_v}{\partial VShr} = \f$ + dYdu(2,5) = tmp_dv*dVhdVShr + !> \f$ \frac{\partial Vt_w}{\partial VShr} = 0 \f$ + dYdu(3,5) = 0.0_R8Ki + + ! \f$ \frac{\partial Vt_u}{\partial PropDir} = \f$ + dYdu(1,6) = tmp_dv*Vh + tmp_du*dVhdPD + ! \f$ \frac{\partial Vt_v}{\partial PropDir} = \f$ + dYdu(2,6) = -tmp_du*Vh + tmp_dv*dVhdPD + !> \f$ \frac{\partial Vt_w}{\partial PropDir} = 0 \f$ + dYdu(3,6) = 0.0_R8Ki + +END SUBROUTINE IfW_UniformWind_JacobianPInput !---------------------------------------------------------------------------------------------------------------------------------- !> Routine to compute the Jacobians of the output (Y), continuous- (X), discrete- (Xd), and constraint-state (Z) functions !! with respect to the continuous states (x). The partial derivatives dY/dx, dX/dx, dXd/dx, and dZ/dx are returned. @@ -1511,7 +1482,7 @@ SUBROUTINE InflowWind_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs IF ( PRESENT( u_op ) ) THEN if (.not. allocated(u_op)) then - call AllocAry(u_op, size(u%PositionXYZ)+3, 'u_op', ErrStat2, ErrMsg2) + call AllocAry(u_op, size(u%PositionXYZ) + size(u%HubPosition) + 3 + NumExtendedInputs, 'u_op', ErrStat2, ErrMsg2) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat >= AbortErrLev) return end if @@ -1525,14 +1496,22 @@ SUBROUTINE InflowWind_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs end do end do - call IfW_UniformWind_GetOP( t, p%UniformWind, m%UniformWind, u_op(index+1:index+2) ) - u_op(index + 3) = p%PropagationDir + do i=1,3 + index = index + 1 + u_op(index) = u%HubPosition(i) + end do + + u_op((index+1):(index+3)) = EulerExtract(u%HubOrientation) + index = index + 3 + + call IfW_UniformWind_GetOP( p%FlowField%Uniform, t, p%FlowField%VelInterpCubic, u_op(index+1:index+2) ) + u_op(index + 3) = p%FlowField%PropagationDir END IF IF ( PRESENT( y_op ) ) THEN if (.not. allocated(y_op)) then - call AllocAry(y_op, size(u%PositionXYZ)+p%NumOuts, 'y_op', ErrStat2, ErrMsg2) + call AllocAry(y_op, size(u%PositionXYZ)+p%NumOuts+3, 'y_op', ErrStat2, ErrMsg2) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat >= AbortErrLev) return end if @@ -1542,12 +1521,17 @@ SUBROUTINE InflowWind_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs do j=1,size(u%PositionXYZ,1) index = index + 1 !(i-1)*size(u%PositionXYZ,1)+j y_op(index) = y%VelocityUVW(j,i) - end do + end do end do - do i=1,p%NumOuts + do j=1,size(y%DiskVel) + index = index + 1 + y_op(index) = y%DiskVel(j) + end do + + do i=1,p%NumOuts y_op(i+index) = y%WriteOutput( i ) - end do + end do END IF @@ -1568,193 +1552,5 @@ SUBROUTINE InflowWind_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs END IF END SUBROUTINE InflowWind_GetOP -!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - -!==================================================================================================== -SUBROUTINE InflowWind_Convert2HAWC( FileRootName, p, m, ErrStat, ErrMsg ) - USE IfW_FFWind_Base - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_Convert2HAWC" - - ! Subroutine arguments - - TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Local variables - TYPE(IfW_FFWind_ParameterType) :: p_ff !< FF Parameters - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - - - ! Compute the wind velocities by stepping through all the data points and calling the appropriate GetWindSpeed routine - SELECT CASE ( p%WindType ) - - CASE (Steady_WindNumber, Uniform_WindNumber) - - CALL Uniform_to_FF(p%UniformWind, m%UniformWind, p_ff, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - IF (ErrStat < AbortErrLev) THEN - CALL ConvertFFWind_to_HAWC2(FileRootName, p_ff, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - END IF - - CALL IfW_FFWind_DestroyParam(p_ff,ErrStat2,ErrMsg2) - - CASE (TSFF_WindNumber) - - CALL ConvertFFWind_to_HAWC2(FileRootName, p%TSFFWind%FF, ErrStat, ErrMsg) - - CASE (BladedFF_WindNumber) - - CALL ConvertFFWind_to_HAWC2(FileRootName, p%BladedFFWind%FF, ErrStat, ErrMsg) - - CASE ( HAWC_WindNumber ) - - CALL ConvertFFWind_to_HAWC2(FileRootName, p%HAWCWind%FF, ErrStat, ErrMsg) - - CASE DEFAULT ! User_WindNumber - - ErrStat = ErrID_Warn - ErrMsg = 'Wind type '//TRIM(Num2LStr(p%WindType))//' cannot be converted to HAWC format.' - - END SELECT - -END SUBROUTINE InflowWind_Convert2HAWC - -!==================================================================================================== -SUBROUTINE InflowWind_Convert2Bladed( FileRootName, p, m, ErrStat, ErrMsg ) - - USE IfW_FFWind_Base - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_Convert2Bladed" - - ! Subroutine arguments - - TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - ! Local variables - TYPE(IfW_FFWind_ParameterType) :: p_ff !< FF Parameters - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - - ErrStat = ErrID_None - ErrMsg = "" - - ! Local variables - - ! Compute the wind velocities by stepping through all the data points and calling the appropriate GetWindSpeed routine - SELECT CASE ( p%WindType ) - - CASE (Steady_WindNumber, Uniform_WindNumber) - - CALL Uniform_to_FF(p%UniformWind, m%UniformWind, p_ff, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - IF (ErrStat < AbortErrLev) THEN - CALL ConvertFFWind_to_Bladed(FileRootName, p_ff, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - END IF - - CALL IfW_FFWind_DestroyParam(p_ff,ErrStat2,ErrMsg2) - - CASE (TSFF_WindNumber) - - CALL ConvertFFWind_to_Bladed(FileRootName, p%TSFFWind%FF, ErrStat, ErrMsg) - - CASE (BladedFF_WindNumber) - - CALL ConvertFFWind_to_Bladed(FileRootName, p%BladedFFWind%FF, ErrStat, ErrMsg) - - CASE ( HAWC_WindNumber ) - - CALL ConvertFFWind_to_Bladed(FileRootName, p%HAWCWind%FF, ErrStat, ErrMsg) - - CASE DEFAULT ! User_WindNumber - - ErrStat = ErrID_Warn - ErrMsg = 'Wind type '//TRIM(Num2LStr(p%WindType))//' cannot be converted to Bladed format.' - - END SELECT - -END SUBROUTINE InflowWind_Convert2Bladed - -!==================================================================================================== -SUBROUTINE InflowWind_Convert2VTK( FileRootName, p, m, ErrStat, ErrMsg ) - - USE IfW_FFWind_Base - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="InflowWind_Convert2VTK" - - ! Subroutine arguments - - TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables - CHARACTER(*), INTENT(IN ) :: FileRootName !< RootName for output files - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - ! Local variables - TYPE(IfW_FFWind_ParameterType) :: p_ff !< FF Parameters - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - - ErrStat = ErrID_None - ErrMsg = "" - - ! Local variables - - ! Compute the wind velocities by stepping through all the data points and calling the appropriate GetWindSpeed routine - SELECT CASE ( p%WindType ) - - CASE (Steady_WindNumber, Uniform_WindNumber) - - CALL Uniform_to_FF(p%UniformWind, m%UniformWind, p_ff, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - IF (ErrStat < AbortErrLev) THEN - CALL ConvertFFWind_toVTK(FileRootName, p_ff, ErrStat2, ErrMsg2) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - END IF - - CALL IfW_FFWind_DestroyParam(p_ff,ErrStat2,ErrMsg2) - - CASE (TSFF_WindNumber) - - CALL ConvertFFWind_toVTK(FileRootName, p%TSFFWind%FF, ErrStat, ErrMsg) - - CASE (BladedFF_WindNumber) - - CALL ConvertFFWind_toVTK(FileRootName, p%BladedFFWind%FF, ErrStat, ErrMsg) - - CASE ( HAWC_WindNumber ) - - CALL ConvertFFWind_toVTK(FileRootName, p%HAWCWind%FF, ErrStat, ErrMsg) - - CASE DEFAULT ! User_WindNumber - - ErrStat = ErrID_Warn - ErrMsg = 'Wind type '//TRIM(Num2LStr(p%WindType))//' cannot be converted to VTK format.' - - END SELECT - -END SUBROUTINE InflowWind_Convert2VTK -!==================================================================================================== END MODULE InflowWind diff --git a/modules/inflowwind/src/InflowWind.txt b/modules/inflowwind/src/InflowWind.txt index d00380ea4..3ab094098 100644 --- a/modules/inflowwind/src/InflowWind.txt +++ b/modules/inflowwind/src/InflowWind.txt @@ -7,13 +7,8 @@ # keyword ################################################################################################################################### -usefrom IfW_UniformWind.txt -usefrom IfW_TSFFWind.txt -usefrom IfW_FFWind_Base.txt -usefrom IfW_BladedFFWind.txt -usefrom IfW_HAWCWind.txt -usefrom IfW_UserWind.txt -usefrom IfW_4Dext.txt +usefrom IfW_FlowField.txt +usefrom InflowWind_IO.txt usefrom Lidar.txt include Registry_NWTC_Library.txt @@ -28,32 +23,10 @@ param ^ - IntKi HAWC_WindNu param ^ - IntKi User_WindNumber - 6 - "User defined wind." - param ^ - IntKi BladedFF_Shr_WindNumber - 7 - "Native Bladed binary full-field file." - param ^ - IntKi FDext_WindNumber - 8 - "4D wind from external souce (i.e., FAST.Farm)." - -param ^ - IntKi Highest_WindNumber - 8 - "Highest wind number supported." - - - -######################### -# ..... WindFile metadata ........................................................................................................ -# This is metadata about the windfile that is retrieved when InflowWind is initialized -# ................................................................................................................................ -typedef InflowWind/InflowWind WindFileMetaData CHARACTER(1024) FileName - - - "Name of the windfile retrieved" - -typedef ^ ^ IntKi WindType - 0 - "Type of the windfile" - -typedef ^ ^ ReKi RefHt - - - "Reference height given in file" meters -typedef ^ ^ Logical RefHt_Set - - - "Reference height was given in file" - -typedef ^ ^ DbKi DT - - - "TimeStep of the wind file -- zero value for none" seconds -typedef ^ ^ IntKi NumTSteps - - - "Number of timesteps in the time range of wind file" - -typedef ^ ^ Logical ConstantDT - - - "Timesteps are the same throughout file" - -typedef ^ ^ ReKi TRange {2} - - "Time range of the wind file" seconds -typedef ^ ^ Logical TRange_Limited - - - "TRange limits strictly enforced" - -typedef ^ ^ ReKi YRange {2} - - "Range in y direction" meters -typedef ^ ^ Logical YRange_Limited - - - "YRange limits strictly enforced" - -typedef ^ ^ ReKi ZRange {2} - - "Range in z direction" meters -typedef ^ ^ Logical ZRange_Limited - - - "ZRange limits strictly enforced" - -typedef ^ ^ IntKi BinaryFormat - - - "Binary format identifier" - -typedef ^ ^ Logical IsBinary - - - "Windfile is a binary file" - -typedef ^ ^ ReKi TI {3} - - "Turbulence intensity (U,V,W)" - -typedef ^ ^ Logical TI_listed - - - "Turbulence intesity given in file" - -typedef ^ ^ ReKi MWS - - - "Approximate mean wind speed" - +param ^ - IntKi Point_WindNumber - 9 - "1D wind components from ExtInflow" - +param ^ - IntKi Highest_WindNumber - 9 - "Highest wind number supported." - +param ^ - IntKi IfW_NumPtsAvg - 144 - "Number of points averaged for rotor-average wind speed" - ######################### # ..... Input file data ........................................................................................................... @@ -63,6 +36,7 @@ typedef InflowWind/InflowWind InflowWind_InputFile LOGICAL EchoFlag typedef ^ ^ IntKi WindType - 0 - "Type of windfile" - typedef ^ ^ ReKi PropagationDir - - - "Direction of wind propagation (meteorological direction)" (degrees) typedef ^ ^ ReKi VFlowAngle - - - "Vertical (upflow) angle" degrees +typedef ^ ^ LOGICAL VelInterpCubic - .FALSE. - "Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7]" - typedef ^ ^ IntKi NWindVel - - - "Number of points to output the wind velocity (0 to 9)" typedef ^ ^ ReKi WindVxiList : - - "List of X coordinates for wind velocity measurements" meters typedef ^ ^ ReKi WindVyiList : - - "List of Y coordinates for wind velocity measurements" meters @@ -90,12 +64,20 @@ typedef ^ ^ ReKi HAWC_dy typedef ^ ^ ReKi HAWC_dz - - - "HAWC -- distance between points in z direction" meters typedef ^ ^ LOGICAL SumPrint - - - "Write summary info to a file .IfW.Sum" - typedef ^ ^ IntKi NumOuts - - - "Number of parameters in the output list (number of outputs requested)" - -typedef ^ ^ CHARACTER(ChanLen) OutList : - - "List of user-requested output channels" - -typedef ^ ^ IntKi SensorType - SensorType_None - "Sensor type (for lidar/sensor module)" - -typedef ^ ^ IntKi NumPulseGate - - - "the number of range gates to return wind speeds at" - -typedef ^ ^ ReKi RotorApexOffsetPos 3 - - "position of the lidar unit relative to the rotor apex of rotation" m -typedef ^ ^ LOGICAL LidRadialVel - - - "TRUE => return radial component, FALSE => return 'x' direction estimate" - -typedef ^ ^ IfW_FFWind_InitInputType FF - - - "scaling data" - +typedef ^ ^ CHARACTER(ChanLen) OutList : - - "List of user-requested output channels" - +typedef ^ ^ IntKi SensorType - - - "Sensor type (for lidar/sensor module)" - +typedef ^ ^ IntKi NumBeam - - - "Number of lidar beams" - +typedef ^ ^ IntKi NumPulseGate - - - "The number of range gates to return wind speeds at" - +typedef ^ ^ ReKi RotorApexOffsetPos {3} - - "Position of the lidar unit relative to the rotor apex of rotation" m +typedef ^ ^ ReKi FocalDistanceX : - - "LIDAR LOS focal distance co-ordinates in the x direction" m +typedef ^ ^ ReKi FocalDistanceY : - - "LIDAR LOS focal distance co-ordinates in the y direction" m +typedef ^ ^ ReKi FocalDistanceZ : - - "LIDAR LOS focal distance co-ordinates in the z direction" m +typedef ^ ^ ReKi PulseSpacing - - - "Distance between range gates" m +typedef ^ ^ ReKi MeasurementInterval - - - "Time between each measurement" s +typedef ^ ^ ReKi URefLid - - - "Reference average wind speed for the lidar" m/s +typedef ^ ^ LOGICAL LidRadialVel - - - "TRUE => return radial component, FALSE => return 'x' direction estimate" - +typedef ^ ^ IntKi ConsiderHubMotion - - - "Flag whether or not the hub motion's impact on the Lidar measurement will be considered [0 for no, 1 for yes]" - +typedef ^ ^ Grid3D_InitInputType FF - - - "scaling data" - @@ -106,19 +88,26 @@ typedef ^ ^ IntKi NumWindPoin typedef ^ ^ IntKi TurbineID - 0 - "Wind turbine ID number in the fixed (DEFAULT) file name when FixedWindFileRootName = .TRUE. (used by FAST.Farm)" - typedef ^ ^ LOGICAL FixedWindFileRootName - .FALSE. - "Do the wind data files have a fixed (DEFAULT) file name? (used by FAST.Farm)" - typedef ^ ^ LOGICAL UseInputFile - .TRUE. - "Should we read everthing from an input file, or do we get it some other way" - -typedef ^ ^ CHARACTER(1024) RootName - - - "RootName for writing output files" +typedef ^ ^ CHARACTER(1024) RootName - - - "RootName for writing output files" typedef ^ ^ FileInfoType PassedFileData - - - "If we don't use the input file, pass everything through this" - -typedef ^ ^ LOGICAL WindType2UseInputFile - .TRUE. - "Flag for toggling file based IO in wind type 2." - -typedef ^ ^ FileInfoType WindType2Data - - - "Optional slot for wind type 2 data if file IO is not used." - -typedef ^ ^ Lidar_InitInputType lidar - - - "InitInput for lidar data" - -typedef ^ ^ IfW_4Dext_InitInputType FDext - - - "InitInput for lidar data" - +typedef ^ ^ LOGICAL WindType2UseInputFile - .TRUE. - "Flag for toggling file based IO in wind type 2." - +typedef ^ ^ FileInfoType WindType2Data - - - "Optional slot for wind type 2 data if file IO is not used." - +typedef ^ ^ LOGICAL OutputAccel - .FALSE. - "Flag to output wind acceleration" - +typedef ^ ^ Lidar_InitInputType lidar - - - "InitInput for lidar data" - +typedef ^ ^ Grid4D_InitInputType FDext - - - "InitInput for 4D external wind data" - +typedef ^ ^ ReKi RadAvg - - - "Radius (from hub) used for averaging wind speed" - +typedef ^ ^ IntKi MHK - - - "MHK turbine type switch" - +typedef ^ ^ ReKi WtrDpth - - - "Water depth" m +typedef ^ ^ ReKi MSL2SWL - - - "Mean sea level to still water level" m +typedef ^ ^ IntKi BoxExceedAllowIdx - -1 - "Extrapolate winds outside box starting at this index (for OLAF wakes and LidarSim)" - +typedef ^ ^ LOGICAL BoxExceedAllowF - .FALSE. - "Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim)" - # Init Output typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr : - - "Names of output-to-file channels" - typedef ^ ^ CHARACTER(ChanLen) WriteOutputUnt : - - "Units of output-to-file channels" - typedef ^ ^ ProgDesc Ver - - - "Version information of InflowWind module" - -typedef ^ ^ WindFileMetaData WindFileInfo - - - "Meta data from the wind file" - +typedef ^ ^ WindFileDat WindFileInfo - - - "Meta data from the wind file" - typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_y {:} - - "Names of the outputs used in linearization" - typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_u {:} - - "Names of the inputs used in linearization" - typedef ^ InitOutputType LOGICAL RotFrame_y {:} - - "Flag that tells FAST/MBC3 if the outputs used in linearization are in the rotating frame" - @@ -126,68 +115,56 @@ typedef ^ InitOutputType LOGICAL RotFra typedef ^ InitOutputType LOGICAL IsLoad_u {:} - - "Flag that tells FAST if the inputs used in linearization are loads (for preconditioning matrix)" - -# ..... Misc/Optimization variables................................................................................................. -# Define any data that are used only for efficiency purposes (these variables are not associated with time): -# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType IntKi TimeIndex - 0 - "An Index into the TData array" - -typedef ^ ^ IfW_UniformWind_MiscVarType UniformWind - - - "MiscVars from UniformWind" - -typedef ^ ^ IfW_TSFFWind_MiscVarType TSFFWind - - - "MiscVars from TSFFWind" - -typedef ^ ^ IfW_HAWCWind_MiscVarType HAWCWind - - - "MiscVars from HAWCWind" - -typedef ^ ^ IfW_BladedFFWind_MiscVarType BladedFFWind - - - "MiscVars from BladedFFWind" - -typedef ^ ^ IfW_UserWind_MiscVarType UserWind - - - "MiscVars from UserWind" - -typedef ^ ^ IfW_4Dext_MiscVarType FDext - - - "MiscVars from FDext" - -typedef ^ ^ ReKi AllOuts : - - "An array holding the value of all of the calculated (not only selected) output channels" "see OutListParameters.xlsx spreadsheet" -typedef ^ ^ ReKi WindViUVW :: - - "List of UVW velocities for wind velocity measurements, 3xNWindVel. corresponds to ParamData%WindViXYZ" meters/second - # ..... 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 CHARACTER(1024) RootFileName - - - "Root of the InflowWind input filename" - -typedef ^ ^ LOGICAL CTTS_Flag - .FALSE. - "determines if coherent turbulence is used" - -typedef ^ ^ LOGICAL RotateWindBox - .FALSE. - "determines if wind will be rotated" - +typedef ^ ^ IntKi WindType - 0 - "Type of wind -- set to Undef_Wind initially" - typedef ^ ^ DbKi DT - - - "Time step for cont. state integration & disc. state update" seconds -typedef ^ ^ ReKi PropagationDir - - - "Direction of wind propagation" radians -typedef ^ ^ ReKi VFlowAngle - - - "Vertical (upflow) angle" radians - -typedef ^ ^ ReKi RotToWind {3}{3} - - "Rotation matrix for rotating from the global XYZ coordinate system to the wind coordinate system (wind along X')" - -typedef ^ ^ ReKi RotFromWind {3}{3} - - "Rotation matrix for rotating from the wind coordinate system (wind along X') back to the global XYZ coordinate system. Equal to TRANSPOSE(RotToWind)" - typedef ^ ^ ReKi WindViXYZprime :: - - "List of XYZ coordinates for velocity measurements, translated to the wind coordinate system (prime coordinates). This equals MATMUL( RotToWind, ParamData%WindViXYZ )" meters - -typedef ^ ^ IntKi WindType - 0 - "Type of wind -- set to Undef_Wind initially" - -typedef ^ ^ ReKi ReferenceHeight - - - "Height of the wind turbine" meters -typedef ^ ^ ReKi RefPosition 3 - - "Reference position (point where box is rotated)" meters -typedef ^ ^ IntKi NWindVel - - - "Number of points in the wind velocity list" - typedef ^ ^ ReKi WindViXYZ :: - - "List of XYZ coordinates for wind velocity measurements, 3xNWindVel" meters -typedef ^ ^ IfW_UniformWind_ParameterType UniformWind - - - "Parameters from UniformWind" - -typedef ^ ^ IfW_TSFFWind_ParameterType TSFFWind - - - "Parameters from TSFFWind -- TurbSim full-field format" - -typedef ^ ^ IfW_BladedFFWind_ParameterType BladedFFWind - - - "Parameters from BladedFFWind -- Bladed-style full-field format" - -typedef ^ ^ IfW_HAWCWind_ParameterType HAWCWind - - - "Parameters from HAWCWind" - -typedef ^ ^ IfW_UserWind_ParameterType UserWind - - - "Parameters from UserWind" - -typedef ^ ^ IfW_4Dext_ParameterType FDext - - - "Parameters from FDext" - -#typedef ^ ^ IfW_CTWind_ParameterType CTWind - - - "Parameters from CTWind" - +typedef ^ ^ FlowFieldType FlowField - - - "Parameters from Full-Field" - +typedef ^ ^ ReKi PositionAvg :: - - "(non-rotated) positions of points used for averaging wind speed" meters +typedef ^ ^ IntKi NWindVel - - - "Number of points in the wind velocity list" - typedef ^ ^ IntKi NumOuts - 0 - "Number of parameters in the output list (number of outputs requested)" - typedef ^ ^ OutParmType OutParam {:} - - "Names and units (and other characteristics) of all requested output parameters" - typedef ^ ^ IntKi OutParamLinIndx {:}{:} - - "Index into WriteOutput for WindViXYZ in linearization analysis" - -typedef ^ ^ lidar_ParameterType lidar - - - "Lidar parameter data" - +typedef ^ ^ lidar_ParameterType lidar - - - "Lidar parameter data" - +typedef ^ ^ LOGICAL OutputAccel - .FALSE. - "Flag to output wind acceleration" - # ..... Inputs .................................................................................................................... # Define inputs that are not on this mesh here: typedef ^ InputType ReKi PositionXYZ :: - - "Array holding the input positions at a given timestep" meters typedef ^ ^ lidar_InputType lidar - - - "Lidar data" - +typedef ^ ^ ReKi HubPosition {3} - - "position of the hub (inertial frame)" m +typedef ^ ^ ReKi HubOrientation {3}{3} - - "orientation of the hub (direction cosine matrix)" - # ..... Outputs ................................................................................................................... # Define outputs that are contained on the mesh here: typedef ^ OutputType ReKi VelocityUVW :: - - "Array holding the U,V,W velocity for a given timestep" meters/sec +typedef ^ OutputType ReKi AccelUVW :: - - "Array holding the U,V,W acceleration for a given timestep" meters/sec typedef ^ OutputType ReKi WriteOutput : - - "Array with values to output to file" - typedef ^ ^ ReKi DiskVel {3} - - "Vector holding the U,V,W average velocity of the disk" meters/sec +typedef ^ ^ ReKi HubVel {3} - - "Vector holding the U,V,W velocity at the hub" meters/sec typedef ^ ^ lidar_OutputType lidar - - - "Lidar data" - -#typedef ^ ^ IfW_UniformWind_OutputType UniformWind - - - "uniform/steady wind operating point" # ..... States not used by this module ................................................................................................................... typedef ^ ContinuousStateType ReKi DummyContState - - - "Remove this variable if you have continuous states" - typedef ^ DiscreteStateType ReKi DummyDiscState - - - "Remove this variable if you have discrete states" - typedef ^ ConstraintStateType ReKi DummyConstrState - - - "Remove this variable if you have constraint states" - typedef ^ OtherStateType ReKi DummyOtherState - - - "Remove this variable if you have other states" - + + +# ..... Misc/Optimization variables................................................................................................. +# Define any data that are used only for efficiency purposes (these variables are not associated with time): +# e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. +typedef ^ MiscVarType ReKi AllOuts : - - "An array holding the value of all of the calculated (not only selected) output channels" "see OutListParameters.xlsx spreadsheet" +typedef ^ ^ ReKi WindViUVW :: - - "List of UVW velocities for wind velocity measurements, 3xNWindVel. corresponds to ParamData%WindViXYZ" meters/second +typedef ^ ^ ReKi WindAiUVW :: - - "List of UVW accelerations for wind acceleration measurements, 3xNWindVel. corresponds to ParamData%WindViXYZ" m/s^2 +typedef ^ ^ InflowWind_InputType u_Avg - - - "inputs for computing rotor-averaged values" - +typedef ^ ^ InflowWind_OutputType y_Avg - - - "outputs for computing rotor-averaged values" - +typedef ^ ^ InflowWind_InputType u_Hub - - - "inputs for computing hub values" - +typedef ^ ^ InflowWind_OutputType y_Hub - - - "outputs for computing hub values" - diff --git a/modules/inflowwind/src/InflowWind_Driver.f90 b/modules/inflowwind/src/InflowWind_Driver.f90 index fedb40334..77beb83a5 100644 --- a/modules/inflowwind/src/InflowWind_Driver.f90 +++ b/modules/inflowwind/src/InflowWind_Driver.f90 @@ -30,6 +30,8 @@ PROGRAM InflowWind_Driver USE InflowWind_Types USE InflowWind_Driver_Types ! Contains types and routines for handling the input arguments USE InflowWind_Driver_Subs ! Contains subroutines for the driver program + USE IfW_FlowField + USE InflowWind_Subs, only: CalculateOutput IMPLICIT NONE @@ -61,19 +63,16 @@ PROGRAM InflowWind_Driver TYPE(IfWDriver_Settings) :: Settings ! Driver settings REAL(DbKi) :: Timer(1:2) ! Keep track of how long this takes to run REAL(DbKi) :: TimeNow ! The current time - INTEGER(IntKi) :: NumTotalPoints ! Number of points for this iteration LOGICAL :: TempFileExist ! Flag for inquiring file existence - CHARACTER(11) :: TmpNumString ! Temporary string for holding a number INTEGER(IntKi) :: ITime ! Generic counter for keeping track of the timestep index - !FIXME: may want to borrow some of the type storage concepts from WAMIT2 !FIXME: look at Waves.f90 for ideas on other things needed for this ! Local variables for the FFT calculations - REAL(ReKi), ALLOCATABLE :: FFTDataSetVel(:,:) ! Velocity dataset for FFT calcs. Indices of (NumTimeSteps,3). Index 2 gives dimension U,V,W - COMPLEX(ReKi), ALLOCATABLE :: FFTDataSetFrq(:,:) ! Complex frequency information for the FFT (NumFreqs,3). Index 2 gives dimension X,Y,Z - REAL(ReKi), ALLOCATABLE :: TimeArray(:) ! Time array information. (NumTimeSteps) - REAL(ReKi), ALLOCATABLE :: FreqArray(:) ! Frequency array information (NumFreqs) + ! REAL(ReKi), ALLOCATABLE :: FFTDataSetVel(:,:) ! Velocity dataset for FFT calcs. Indices of (NumTimeSteps,3). Index 2 gives dimension U,V,W + ! COMPLEX(ReKi), ALLOCATABLE :: FFTDataSetFrq(:,:) ! Complex frequency information for the FFT (NumFreqs,3). Index 2 gives dimension X,Y,Z + ! REAL(ReKi), ALLOCATABLE :: TimeArray(:) ! Time array information. (NumTimeSteps) + ! REAL(ReKi), ALLOCATABLE :: FreqArray(:) ! Frequency array information (NumFreqs) @@ -109,10 +108,6 @@ PROGRAM InflowWind_Driver CALL NWTC_Init CALL DispNVD(ProgInfo) -! Beep = .FALSE. - - - !-------------------------------------------------------------------------------------------------------------------------------- !-=-=- Setup the program -=-=- !-------------------------------------------------------------------------------------------------------------------------------- @@ -120,61 +115,9 @@ PROGRAM InflowWind_Driver ! Start the timer CALL CPU_TIME( Timer(1) ) - ! Set some CLSettings to null/default values - CLSettings%DvrIptFileName = "" ! No input name name until set - CLSettings%IfWIptFileName = "" ! No IfW input file name until set - CLSettings%SummaryFileName = "" ! No summary file name until set - CLSettings%NumTimeSteps = 0_IntKi - CLSettings%DT = 0.0_DbKi - CLSettings%TStart = 0.0_ReKi - CLSettings%FFTcoord = 0.0_ReKi ! Set to origin - CLSettings%GridDelta = 0.0_ReKi ! No stepsize - CLSettings%GridN = 1_IntKi ! No grid points to calculate -- center of grid only - CLSettings%XRange = 0.0_ReKi ! No xrange points - CLSettings%YRange = 0.0_ReKi ! No Yrange points - CLSettings%ZRange = 0.0_ReKi ! No Zrange points - CLSettings%PointsFileName = "" ! No points file name until set - CLSettings%PointsOutputName = "" ! No points file name until set - CLSettings%FFTOutputName = "" ! No FFT output file name until set - CLSettings%WindGridOutputName = "" ! No WindGrid output file name until set - CLSettings%WindGridOutputUnit = -1_IntKi ! No WindGrid output unit set - CLSettings%FFTOutputUnit = -1_IntKi ! No FFT output unit set - CLSettings%PointsOutputUnit = -1_IntKi ! No Points file output unit set - CLSettings%ProgInfo = ProgInfo ! Driver info - - ! Set some CLSettingsFlags to null/default values - CLSettingsFlags%DvrIptFile = .FALSE. ! Driver input filename given as command line argument - CLSettingsFlags%IfWIptFile = .FALSE. ! InflowWind input filename given as command line argument - CLSettingsFlags%Summary = .FALSE. ! create a summary at command line? (data extents in the wind file) - CLSettingsFlags%SummaryFile = .FALSE. ! create a summary file of the output? - CLSettingsFlags%TStart = .FALSE. ! specified time to start at - CLSettingsFlags%NumTimeSteps = .FALSE. ! specified a number of timesteps - CLSettingsFlags%NumTimeStepsDefault = .FALSE. ! specified 'DEFAULT' for number of timesteps - CLSettingsFlags%DT = .FALSE. ! specified a resolution in time - CLSettingsFlags%DTDefault = .FALSE. ! specified 'DEFAULT' for resolution in time - CLSettingsFlags%FFTcalc = .FALSE. ! do an FFT - CLSettingsFlags%WindGrid = .FALSE. ! Requested output of wind data on a grid -- input file option only - CLSettingsFlags%XRange = .FALSE. ! specified a range of x -- command line option only -- stored as GridCtrCoord and GridDelta - CLSettingsFlags%YRange = .FALSE. ! specified a range of y -- command line option only -- stored as GridCtrCoord and GridDelta - CLSettingsFlags%ZRange = .FALSE. ! specified a range of z -- command line option only -- stored as GridCtrCoord and GridDelta - CLSettingsFlags%Dx = .FALSE. ! specified a resolution in x -- command line option only, 0.0 otherwise - CLSettingsFlags%Dy = .FALSE. ! speficied a resolution in y - CLSettingsFlags%Dz = .FALSE. ! specified a resolution in z - CLSettingsFlags%PointsFile = .FALSE. ! points filename to read in -- command line option only - CLSettingsFlags%WindGridOutputInit = .FALSE. ! Wind Grid output file not started - CLSettingsFlags%FFTOutputInit = .FALSE. ! FFT output file not started - CLSettingsFlags%PointsOutputInit = .FALSE. ! Points output file not started - CLSettingsFlags%Verbose = .FALSE. ! Turn on verbose error reporting? - CLSettingsFlags%VVerbose = .FALSE. ! Turn on very verbose error reporting? - CLSettingsFlags%WrHAWC = .FALSE. ! don't convert to HAWC format - CLSettingsFlags%WrBladed = .FALSE. ! don't convert to Bladed format - CLSettingsFlags%WrVTK = .FALSE. ! don't convert to VTK format - - ! Initialize the driver settings to their default values (same as the CL -- command line -- values) - Settings = CLSettings - SettingsFlags = CLSettingsFlags - + CLSettings%ProgInfo = ProgInfo + Settings%ProgInfo = ProgInfo !-------------------------------------------------------------------------------------------------------------------------------- !-=-=- Parse the command line inputs -=-=- @@ -278,6 +221,7 @@ PROGRAM InflowWind_Driver SettingsFlags%WrHAWC = .FALSE. SettingsFlags%WrBladed = .FALSE. SettingsFlags%WrVTK = .FALSE. + SettingsFlags%WrUniform = .FALSE. ! VVerbose error reporting IF ( IfWDriver_Verbose >= 10_IntKi ) CALL WrScr('No driver input file used. Updating driver settings with command line arguments') @@ -305,13 +249,14 @@ PROGRAM InflowWind_Driver - ! Sanity check: if an input points file is specified, make sure it actually exists. Open it if specified - + ! If output based a points file was requested IF ( SettingsFlags%PointsFile ) THEN + + ! Check if the points file exists, abort if not found INQUIRE( file=TRIM(Settings%PointsFileName), exist=TempFileExist ) IF ( TempFileExist .eqv. .FALSE. ) CALL ProgAbort( "Cannot find the points file "//TRIM(Settings%PointsFileName)) - ! Now read the file in and save the points + ! Now read the file in and save the points CALL ReadPointsFile( Settings%PointsFileName, PointsXYZ, ErrStat,ErrMsg ) IF ( ErrStat >= AbortErrLev ) THEN CALL ProgAbort( ErrMsg ) @@ -320,16 +265,16 @@ PROGRAM InflowWind_Driver ErrStat = ErrID_None ENDIF - ! Make name for output - CALL GetRoot( Settings%PointsFileName, Settings%PointsOutputName ) - Settings%PointsOutputName = TRIM(Settings%PointsOutputName)//'.Velocity.dat' - - CALL WrScr(NewLine//"Read "//TRIM(Num2LStr(SIZE(PointsXYZ,DIM=2)))//" points from '"//TRIM(Settings%PointsFileName)// & - "'. Results output to '"//TRIM(Settings%PointsOutputName)//"'.") + ! Display number of points read from file + CALL WrScr(NewLine//"Read "//TRIM(Num2LStr(SIZE(PointsXYZ,DIM=2)))//" points from '"//TRIM(Settings%PointsFileName)//"'.") - ! If the output file already exists, warn that it will be overwritten - INQUIRE( file=TRIM(Settings%PointsOutputName), exist=TempFileExist ) - IF ( TempFileExist .eqv. .TRUE. ) CALL ProgWarn( "Overwriting file "//TRIM(Settings%PointsOutputName)) + ! Create velocity output file name from points input file name + ! Display that file will be created, output message if it will be overwritten + CALL GetRoot( Settings%PointsFileName, Settings%PointsVelOutput%Name ) + Settings%PointsVelOutput%Name = TRIM(Settings%PointsVelOutput%Name)//'.Velocity.dat' + CALL WrScr(NewLine//"Results output to '"//TRIM(Settings%PointsVelOutput%Name)//"'.") + INQUIRE( file=TRIM(Settings%PointsVelOutput%Name), exist=TempFileExist ) + IF ( TempFileExist .eqv. .TRUE. ) CALL ProgWarn( "Overwriting file "//TRIM(Settings%PointsVelOutput%Name)) ENDIF @@ -338,24 +283,24 @@ PROGRAM InflowWind_Driver IF ( SettingsFlags%FFTcalc ) THEN ! Make name for output IF ( SettingsFlags%DvrIptFile ) THEN - CALL GetRoot( Settings%DvrIptFileName, Settings%FFTOutputName ) + CALL GetRoot( Settings%DvrIptFileName, Settings%FFTOutput%Name ) ELSE - CALL GetRoot( Settings%IfWIptFileName, Settings%FFTOutputName ) + CALL GetRoot( Settings%IfWIptFileName, Settings%FFTOutput%Name ) ENDIF - Settings%FFTOutputName = TRIM(Settings%FFTOutputName)//'_'// & + Settings%FFTOutput%Name = TRIM(Settings%FFTOutput%Name)//'_'// & TRIM(Num2LStr(Settings%FFTcoord(1)))//'x_'// & TRIM(Num2LStr(Settings%FFTcoord(2)))//'y_'// & TRIM(Num2LStr(Settings%FFTcoord(3)))//'z'//'.FFT' - CALL WrScr(NewLine//"Writing FFT results to '"//TRIM(Settings%FFTOutputName)//"' for coordinate ( "// & + CALL WrScr(NewLine//"Writing FFT results to '"//TRIM(Settings%FFTOutput%Name)//"' for coordinate ( "// & TRIM(Num2LStr(Settings%FFTcoord(1)))//", "// & TRIM(Num2LStr(Settings%FFTcoord(2)))//", "// & TRIM(Num2LStr(Settings%FFTcoord(3)))//" ).") ! If the output file already exists, warn that it will be overwritten - INQUIRE( file=TRIM(Settings%FFTOutputName), exist=TempFileExist ) - IF ( TempFileExist .eqv. .TRUE. ) CALL ProgWarn( "Overwriting file "//TRIM(Settings%FFTOutputName)) + INQUIRE( file=TRIM(Settings%FFTOutput%Name), exist=TempFileExist ) + IF ( TempFileExist .eqv. .TRUE. ) CALL ProgWarn( "Overwriting file "//TRIM(Settings%FFTOutput%Name)) ENDIF @@ -366,12 +311,12 @@ PROGRAM InflowWind_Driver ! Create WindGrid output name IF ( SettingsFlags%DvrIptFile ) THEN - CALL GetRoot( Settings%DvrIptFileName, Settings%WindGridOutputName ) + CALL GetRoot( Settings%DvrIptFileName, Settings%WindGridOutput%Name ) ELSE - CALL GetRoot( Settings%IfWIptFileName, Settings%WindGridOutputName ) + CALL GetRoot( Settings%IfWIptFileName, Settings%WindGridOutput%Name ) ENDIF - Settings%WindGridOutputName = TRIM(Settings%WindGridOutputName)//'.WindGrid.out' + Settings%WindGridOutput%Name = TRIM(Settings%WindGridOutput%Name)//'.WindGrid.out' ! Output message if some verbosity. IF ( IfWDriver_Verbose >= 5_IntKi ) THEN @@ -458,9 +403,14 @@ PROGRAM InflowWind_Driver !InflowWind_InitInp%RootName = "" END IF InflowWind_InitInp%RootName = trim(InflowWind_InitInp%RootName)//'.IfW' + InflowWind_InitInp%RadAvg = -1.0_ReKi ! let the IfW code guess what to use + InflowWind_InitInp%BoxExceedAllowF = SettingsFlags%BoxExceedAllowF ! Set flag for allowing points outside the wind box (alternate interpolation method for FF) + if (InflowWind_InitInp%BoxExceedAllowF) InflowWind_InitInp%BoxExceedAllowIdx = 1_IntKi IF ( IfWDriver_Verbose >= 5_IntKi ) CALL WrScr('Calling InflowWind_Init...') + ! Set flag to calculate accelerations if requested + InflowWind_InitInp%OutputAccel = SettingsFlags%OutputAccel CALL InflowWind_Init( InflowWind_InitInp, InflowWind_u1, InflowWind_p, & InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & @@ -471,11 +421,15 @@ PROGRAM InflowWind_Driver IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) - ELSEIF ( ( ErrStat /= ErrID_None ) .AND. ( IfWDriver_Verbose >= 7_IntKi ) ) THEN - CALL WrScr(NewLine//' InflowWind_Init returned: ErrStat: '//TRIM(Num2LStr(ErrStat))// & - NewLine//' ErrMsg: '//TRIM(ErrMsg)//NewLine) - ELSEIF ( ( ErrStat /= ErrID_None ) .AND. ( IfWDriver_Verbose < 7_IntKi ) ) THEN - CALL ProgWarn( ErrMsg ) + ELSEIF ( ErrStat /= ErrID_None ) THEN + IF ( IfWDriver_Verbose >= 7_IntKi ) THEN + CALL WrScr(NewLine//' InflowWind_Init returned: ErrStat: '//TRIM(Num2LStr(ErrStat))// & + NewLine//' ErrMsg: '//TRIM(ErrMsg)//NewLine) + ELSEIF ( ErrStat >= ErrID_Warn ) THEN + CALL ProgWarn( ErrMsg ) + ELSE + CALL WrScr(TRIM(ErrMsg)) + ENDIF ENDIF @@ -486,28 +440,24 @@ PROGRAM InflowWind_Driver ! Convert InflowWind file to HAWC format IF (SettingsFlags%WrHAWC) THEN - - CALL InflowWind_Convert2HAWC( InflowWind_InitInp%RootName, InflowWind_p, InflowWind_MiscVars, ErrStat, ErrMsg ) - + CALL IfW_WriteHAWC( InflowWind_p%FlowField, InflowWind_InitInp%RootName, ErrStat, ErrMsg ) IF (ErrStat > ErrID_None) THEN CALL WrScr( TRIM(ErrMsg) ) IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN - CALL WrScr(NewLine//' InflowWind_Convert2HAWC returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) + CALL WrScr(NewLine//' IfW_WriteHAWC returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) END IF - ELSE - IF ( IfWDriver_Verbose >= 5_IntKi ) CALL WrScr(NewLine//'InflowWind_Convert2HAWC CALL returned without errors.'//NewLine) + ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN + CALL WrScr(NewLine//'IfW_WriteHAWC CALL returned without errors.'//NewLine) END IF - - END IF ! Write HAWC2 files + END IF ! Convert InflowWind file to Native Bladed format IF (SettingsFlags%WrBladed) THEN - CALL InflowWind_Convert2Bladed( InflowWind_InitInp%RootName, InflowWind_p, InflowWind_MiscVars, ErrStat, ErrMsg ) - + CALL IfW_WriteBladed( InflowWind_p%FlowField, InflowWind_InitInp%RootName, ErrStat, ErrMsg ) IF (ErrStat > ErrID_None) THEN CALL WrScr( TRIM(ErrMsg) ) IF ( ErrStat >= AbortErrLev ) THEN @@ -516,29 +466,43 @@ PROGRAM InflowWind_Driver ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN CALL WrScr(NewLine//' InflowWind_Convert2Bladed returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) END IF - ELSE - IF ( IfWDriver_Verbose >= 5_IntKi ) CALL WrScr(NewLine//'InflowWind_Convert2Bladed CALL returned without errors.'//NewLine) + ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN + CALL WrScr(NewLine//'InflowWind_Convert2Bladed CALL returned without errors.'//NewLine) END IF END IF IF (SettingsFlags%WrVTK) THEN - CALL InflowWind_Convert2VTK( InflowWind_InitInp%RootName, InflowWind_p, InflowWind_MiscVars, ErrStat, ErrMsg ) - + CALL IfW_WriteVTK( InflowWind_p%FlowField, InflowWind_InitInp%RootName, ErrStat, ErrMsg ) IF (ErrStat > ErrID_None) THEN CALL WrScr( TRIM(ErrMsg) ) IF ( ErrStat >= AbortErrLev ) THEN CALL DriverCleanup() CALL ProgAbort( ErrMsg ) ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN - CALL WrScr(NewLine//' InflowWind_Convert2VTK returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) + CALL WrScr(NewLine//' IfW_WriteVTK returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) END IF - ELSE - IF ( IfWDriver_Verbose >= 5_IntKi ) CALL WrScr(NewLine//'InflowWind_Convert2VTK CALL returned without errors.'//NewLine) + ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN + CALL WrScr(NewLine//'IfW_WriteVTK CALL returned without errors.'//NewLine) END IF END IF - + + IF (SettingsFlags%WrUniform) THEN + CALL IfW_WriteUniform( InflowWind_p%FlowField, InflowWind_InitInp%RootName, ErrStat, ErrMsg ) + IF (ErrStat > ErrID_None) THEN + CALL WrScr( TRIM(ErrMsg) ) + IF ( ErrStat >= AbortErrLev ) THEN + CALL DriverCleanup() + CALL ProgAbort( ErrMsg ) + ELSEIF ( IfWDriver_Verbose >= 7_IntKi ) THEN + CALL WrScr(NewLine//' IfW_WriteUniform returned: ErrStat: '//TRIM(Num2LStr(ErrStat))) + END IF + ELSE IF ( IfWDriver_Verbose >= 5_IntKi ) THEN + CALL WrScr(NewLine//'IfW_WriteUniform CALL returned without errors.'//NewLine) + END IF + END IF + !-------------------------------------------------------------------------------------------------------------------------------- !-=-=- Other Setup -=-=- !-------------------------------------------------------------------------------------------------------------------------------- @@ -606,9 +570,8 @@ PROGRAM InflowWind_Driver IF ( SettingsFlags%WindGrid ) THEN ! Write the header for the WindGrid output file - CALL WindGridVel_OutputWrite( Settings%WindGridOutputUnit, Settings%WindGridOutputName, SettingsFlags%WindGridOutputInit, & - Settings, InflowWind_u1%PositionXYZ, InflowWind_y1%VelocityUVW, & - TimeNow, ErrStat, ErrMsg ) + CALL WindGridVel_OutputWrite( Settings%WindGridOutput, Settings, InflowWind_u1%PositionXYZ, & + InflowWind_y1%VelocityUVW, TimeNow, ErrStat, ErrMsg ) ! Setup the actual grid points -- scan order, Y,Z,X @@ -624,6 +587,9 @@ PROGRAM InflowWind_Driver ENDDO ENDDO + Counter = MAX(1, NINT(Counter/2.0)) + InflowWind_u1%HubPosition = InflowWind_u1%PositionXYZ(:,Counter) + ELSE ! We are going to set the WindGrid with only a single point at the RefHt so that we can calculate something @@ -631,15 +597,19 @@ PROGRAM InflowWind_Driver InflowWind_u1%PositionXYZ(2,1) = 0.0_ReKi ! Y InflowWind_u1%PositionXYZ(3,1) = InflowWind_InitOut%WindFileInfo%RefHt ! Z + InflowWind_u1%HubPosition = InflowWind_u1%PositionXYZ(:,1) ENDIF - + call Eye(InflowWind_u1%HubOrientation, ErrStat, ErrMsg) + call Eye(InflowWind_u2%HubOrientation, ErrStat, ErrMsg) ! If we read in a list of points from the Points input file, setup the arrays for it. IF ( SettingsFlags%PointsFile ) THEN ! Move the points list CALL MOVE_ALLOC( PointsXYZ, InflowWind_u2%PositionXYZ ) + Counter = MAX(1, NINT(size(InflowWind_u2%PositionXYZ,2)/2.0)) + InflowWind_u2%HubPosition = InflowWind_u2%PositionXYZ(:,Counter) ! Allocate the array for the velocity results -- 3 x Npoints CALL AllocAry( InflowWind_y2%VelocityUVW, 3, SIZE(InflowWind_u2%PositionXYZ, DIM=2 ), & @@ -649,6 +619,16 @@ PROGRAM InflowWind_Driver CALL ProgAbort( ErrMsg ) ENDIF + ! Allocate the array for the acceleration results -- 3 x Npoints + IF ( SettingsFlags%OutputAccel ) THEN + CALL AllocAry( InflowWind_y2%AccelUVW, 3, SIZE(InflowWind_u2%PositionXYZ, DIM=2 ), & + "Array of accelerations corresponding to Points file", ErrStat, ErrMsg ) + IF ( ErrStat /= ErrID_None ) THEN + CALL DriverCleanup() + CALL ProgAbort( ErrMsg ) + ENDIF + ENDIF + ! WriteOutput info IF ( ALLOCATED(InflowWind_y1%WriteOutput) ) THEN ALLOCATE( InflowWind_y2%WriteOutput(SIZE(InflowWind_y1%WriteOutput)), STAT=ErrStat ) @@ -659,19 +639,19 @@ PROGRAM InflowWind_Driver InflowWind_y2%WriteOutput = InflowWind_y1%WriteOutput ENDIF - ! Now create the output file. Write header information - CALL PointsVel_OutputWrite( Settings%PointsOutputUnit, Settings%PointsOutputName, SettingsFlags%PointsOutputInit, & - Settings, InflowWind_u2%PositionXYZ, InflowWind_y2%VelocityUVW, & - TimeNow, ErrStat, ErrMsg ) + ! Now create the velocity output file. Write header information + CALL PointData_OutputWrite( Settings%PointsVelOutput, Settings, & + InflowWind_u2%PositionXYZ, & + InflowWind_y2%VelocityUVW, & + InflowWind_y2%AccelUVW, & + TimeNow, .true., ErrStat, ErrMsg ) + IF ( ErrStat /= ErrID_None ) THEN + CALL DriverCleanup() + CALL ProgAbort( 'Error creating point data velocity output file: '//trim(Settings%PointsVelOutput%Name) ) + ENDIF ENDIF - - - - - - ! FFT setup IF ( SettingsFlags%FFTcalc ) THEN @@ -713,23 +693,25 @@ PROGRAM InflowWind_Driver ! Report the rotation of the coordinates. - IF ( IfWDriver_Verbose >= 10_IntKi .AND. InflowWind_p%NWindVel > 0_IntKi ) THEN + IF ( IfWDriver_Verbose >= 10_IntKi .and. InflowWind_p%NumOuts > 0 ) THEN CALL WrScr(NewLine//NewLine//' Rotation of coordinates to prime (wind file) coordinates by rotating '// & - TRIM(Num2LStr(R2D*InflowWind_p%PropagationDir))// & + TRIM(Num2LStr(R2D*InflowWind_p%FlowField%PropagationDir))// & ' degrees (meteorological wind direction change) ...'//NewLine) - CALL WrScr(' ------ WindViXYZ --------- ----- WindViXYZprime -----') - - DO I = 1,InflowWind_p%NWindVel - ErrMsgTmp = '' - ErrMsgTmp = ' '//TRIM(Num2LStr(I))//' ' - ErrMsgTmp = TRIM(ErrMsgTmp)//' ('//TRIM(Num2LStr(InflowWind_p%WindViXYZ(1,I)))// & - ', '//TRIM(Num2LStr(InflowWind_p%WindViXYZ(2,I)))//', '// & - TRIM(Num2LStr(InflowWind_p%WindViXYZ(3,I)))//')' - ErrMsgTmp = ErrMsgTmp(1:40)//'('//TRIM(Num2LStr(InflowWind_p%WindViXYZprime(1,I)))// & - ', '//TRIM(Num2LStr(InflowWind_p%WindViXYZprime(2,I)))//', '// & - TRIM(Num2LStr(InflowWind_p%WindViXYZprime(3,I)))//')' - CALL WrScr(TRIM(ErrMsgTmp)) - ENDDO + if (InflowWind_p%NWindVel > 0_IntKi) then + CALL WrScr(' ------ WindViXYZ --------- ----- WindViXYZprime -----') + + DO I = 1,InflowWind_p%NWindVel + ErrMsgTmp = '' + ErrMsgTmp = ' '//TRIM(Num2LStr(I))//' ' + ErrMsgTmp = TRIM(ErrMsgTmp)//' ('//TRIM(Num2LStr(InflowWind_p%WindViXYZ(1,I)))// & + ', '//TRIM(Num2LStr(InflowWind_p%WindViXYZ(2,I)))//', '// & + TRIM(Num2LStr(InflowWind_p%WindViXYZ(3,I)))//')' + ErrMsgTmp = ErrMsgTmp(1:40)//'('//TRIM(Num2LStr(InflowWind_p%WindViXYZprime(1,I)))// & + ', '//TRIM(Num2LStr(InflowWind_p%WindViXYZprime(2,I)))//', '// & + TRIM(Num2LStr(InflowWind_p%WindViXYZprime(3,I)))//')' + CALL WrScr(TRIM(ErrMsgTmp)) + ENDDO + end if CALL WrScr(NewLine) ENDIF @@ -756,69 +738,72 @@ PROGRAM InflowWind_Driver TimeNow = Settings%TStart + Settings%DT*(ITime) - ! Get results for WindGrid data from IfW -- WindGrid may contain only a single point at the hub if the WindGrid flag isn't set. - CALL InflowWind_CalcOutput( TimeNow, InflowWind_u1, InflowWind_p, & - InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & - InflowWind_y1, InflowWind_MiscVars, ErrStat, ErrMsg) - - + IF ( SettingsFlags%WindGrid ) THEN - ! Make sure no errors occured that give us reason to terminate now. - IF ( ErrStat >= AbortErrLev ) THEN - CALL DriverCleanup() - CALL ProgAbort( ErrMsg ) - ELSEIF ( ( ErrStat /= ErrID_None ) .AND. ( IfWDriver_Verbose >= 10_IntKi ) ) THEN - CALL WrScr(NewLine//' Timestep '//TRIM(Num2LStr(ITime))// & - ' InflowWind_Calc returned: ErrStat: '//TRIM(Num2LStr(ErrStat))// & - NewLine//' ErrMsg: '//TRIM(ErrMsg)//NewLine) - ENDIF + ! Get results for WindGrid data from IfW -- WindGrid may contain only a single point at the hub if the WindGrid flag isn't set. + CALL InflowWind_CalcOutput( TimeNow, InflowWind_u1, InflowWind_p, & + InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & + InflowWind_y1, InflowWind_MiscVars, ErrStat, ErrMsg) + ! Make sure no errors occured that give us reason to terminate now. + IF ( ErrStat >= AbortErrLev ) THEN + CALL DriverCleanup() + CALL ProgAbort( ErrMsg ) + ELSEIF ( ( ErrStat /= ErrID_None ) .AND. ( IfWDriver_Verbose >= 10_IntKi ) ) THEN + CALL WrScr(NewLine//' Timestep '//TRIM(Num2LStr(ITime))// & + ' InflowWind_Calc returned: ErrStat: '//TRIM(Num2LStr(ErrStat))//NewLine// & + ' ErrMsg: '//TRIM(ErrMsg)//NewLine) + ENDIF ! Write the WindGrid results to a file for this timestep - IF ( SettingsFlags%WindGrid ) THEN - - CALL WindGridVel_OutputWrite( Settings%WindGridOutputUnit, Settings%WindGridOutputName, SettingsFlags%WindGridOutputInit, & - Settings, InflowWind_u1%PositionXYZ, InflowWind_y1%VelocityUVW, & + CALL WindGridVel_OutputWrite( Settings%WindGridOutput, Settings, & + InflowWind_u1%PositionXYZ, InflowWind_y1%VelocityUVW, & TimeNow, ErrStat, ErrMsg ) - ENDIF - - - ! Calculate results for the Points and export them for this timestep + ! If point results were requested IF ( SettingsFlags%PointsFile ) THEN - - ! Get results for Points data from IfW - CALL InflowWind_CalcOutput( TimeNow, InflowWind_u2, InflowWind_p, & - InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & - InflowWind_y2, InflowWind_MiscVars, ErrStat, ErrMsg) - - ! Output the Points results for this timestep - CALL PointsVel_OutputWrite( Settings%PointsOutputUnit, Settings%PointsOutputName, SettingsFlags%PointsOutputInit, & - Settings, InflowWind_u2%PositionXYZ, InflowWind_y2%VelocityUVW, & - TimeNow, ErrStat, ErrMsg ) - - ENDIF - - + + ! Calculate velocity/acceleration at points + CALL InflowWind_CalcOutput( TimeNow, InflowWind_u2, InflowWind_p, & + InflowWind_x, InflowWind_xd, InflowWind_z, InflowWind_OtherState, & + InflowWind_y2, InflowWind_MiscVars, ErrStat, ErrMsg) + IF ( ErrStat >= AbortErrLev ) THEN + CALL DriverCleanup() + CALL ProgAbort( ErrMsg ) + ELSEIF ( ( ErrStat /= ErrID_None ) .AND. ( IfWDriver_Verbose >= 10_IntKi ) ) THEN + CALL WrScr(NewLine//' Timestep '//TRIM(Num2LStr(ITime))// & + ' InflowWind_Calc returned: ErrStat: '//TRIM(Num2LStr(ErrStat))//NewLine// & + ' ErrMsg: '//TRIM(ErrMsg)//NewLine) + ENDIF + + ! Output the Points results for this timestep + CALL PointData_OutputWrite( Settings%PointsVelOutput, Settings, & + InflowWind_u2%PositionXYZ, & + InflowWind_y2%VelocityUVW, & + InflowWind_y2%AccelUVW, & + TimeNow, .true., ErrStat, ErrMsg ) + IF ( ErrStat >= AbortErrLev ) THEN + CALL DriverCleanup() + CALL ProgAbort( ErrMsg ) + END IF + + END IF ! Calculate results for FFT if we are performing one IF ( SettingsFlags%FFTcalc ) THEN - ! Get the results from IfW + ! Get the results from IfW ! CALL InflowWind_CalcOutput() - ! Copy results over to the array for storage + ! Copy results over to the array for storage ! FFTdata(ITime,:) = - - + ENDIF - ENDDO ! ITime loop - ! output table of results for the outlist comparison and check if very verbose -- print statements are ! used because we don't want linewrapping. IF ( IfWDriver_Verbose >= 10_IntKi ) THEN @@ -948,11 +933,10 @@ PROGRAM InflowWind_Driver SUBROUTINE DriverCleanup() - - if (Settings%WindGridOutputUnit > -1_IntKi ) CLOSE( Settings%WindGridOutputUnit ) - if (Settings%PointsOutputUnit > -1_IntKi ) CLOSE( Settings%PointsOutputUnit ) - if (Settings%FFTOutputUnit > -1_IntKi ) CLOSE( Settings%FFTOutputUnit ) - + ! Close output files that may have been opened + if (Settings%WindGridOutput%Unit > -1_IntKi ) CLOSE( Settings%WindGridOutput%Unit ) + if (Settings%PointsVelOutput%Unit > -1_IntKi ) CLOSE( Settings%PointsVelOutput%Unit ) + if (Settings%FFTOutput%Unit > -1_IntKi ) CLOSE( Settings%FFTOutput%Unit ) ! Find out how long this actually took CALL CPU_TIME( Timer(2) ) diff --git a/modules/inflowwind/src/InflowWind_Driver_Subs.f90 b/modules/inflowwind/src/InflowWind_Driver_Subs.f90 index c10193ae6..d7033445b 100644 --- a/modules/inflowwind/src/InflowWind_Driver_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Driver_Subs.f90 @@ -27,6 +27,8 @@ MODULE InflowWind_Driver_Subs USE NWTC_Library USE InflowWind_Driver_Types + USE InflowWind_IO + USE IfW_FlowField IMPLICIT NONE @@ -59,25 +61,27 @@ SUBROUTINE DispHelpText( ErrStat, ErrMsg ) CALL WrScr(" (no driver input file)") CALL WrScr("") CALL WrScr(" The following options will overwrite values in the driver input file:") - CALL WrScr(" "//SwChar//"DT[#] -- timestep ") - CALL WrScr(" "//SwChar//"TStart[#] -- start time ") - CALL WrScr(" "//SwChar//"TSteps[#] -- number of timesteps ") - CALL WrScr(" "//SwChar//"xrange[#:#] -- range of x (#'s are reals) ") - CALL WrScr(" "//SwChar//"yrange[#:#] -- range of y ") - CALL WrScr(" "//SwChar//"zrange[#:#] -- range in z (ground = 0.0) ") - CALL WrScr(" "//SwChar//"Dx[#] -- spacing in x ") - CALL WrScr(" "//SwChar//"Dy[#] -- spacing in y ") - CALL WrScr(" "//SwChar//"Dz[#] -- spacing in z ") -! CALL WrScr(" "//SwChar//"sum -- summarize wind file info [N/A]") -! CALL WrScr(" "//SwChar//"FFT[X,Y,Z] -- an fft over all t using specified DT at X,Y,Z [N/A]") - CALL WrScr(" "//SwChar//"points[FILE] -- calculates at x,y,z coordinates specified in a ") + CALL WrScr(" "//SwChar//"DT[#] -- timestep ") + CALL WrScr(" "//SwChar//"TStart[#] -- start time ") + CALL WrScr(" "//SwChar//"TSteps[#] -- number of timesteps ") + CALL WrScr(" "//SwChar//"xrange[#:#] -- range of x (#'s are reals) ") + CALL WrScr(" "//SwChar//"yrange[#:#] -- range of y ") + CALL WrScr(" "//SwChar//"zrange[#:#] -- range in z (ground = 0.0) ") + CALL WrScr(" "//SwChar//"Dx[#] -- spacing in x ") + CALL WrScr(" "//SwChar//"Dy[#] -- spacing in y ") + CALL WrScr(" "//SwChar//"Dz[#] -- spacing in z ") +! CALL WrScr(" "//SwChar//"sum -- summarize wind file info [N/A]") +! CALL WrScr(" "//SwChar//"FFT[X,Y,Z] -- an fft over all t using specified DT at X,Y,Z [N/A]") + CALL WrScr(" "//SwChar//"points[FILE] -- calculates at x,y,z coordinates specified in a ") CALL WrScr(" white space delimited FILE") - CALL WrScr(" "//SwChar//"v -- verbose output ") - CALL WrScr(" "//SwChar//"vv -- very verbose output ") - CALL WrScr(" "//SwChar//"HAWC -- convert contents of to HAWC format ") - CALL WrScr(" "//SwChar//"Bladed -- convert contents of to Bladed format ") - CALL WrScr(" "//SwChar//"vtk -- convert contents of to vtk format ") - CALL WrScr(" "//SwChar//"help -- print this help menu and exit") + CALL WrScr(" "//SwChar//"v -- verbose output ") + CALL WrScr(" "//SwChar//"vv -- very verbose output ") + CALL WrScr(" "//SwChar//"HAWC -- convert contents of to HAWC format ") + CALL WrScr(" "//SwChar//"Bladed -- convert contents of to Bladed format ") + CALL WrScr(" "//SwChar//"vtk -- convert contents of to vtk format ") + CALL WrScr(" "//SwChar//"accel -- calculate wind acceleration in addition to velocity") + CALL WrScr(" "//SwChar//"BoxExceedAllow -- set flag to allow FF points outside wind box") + CALL WrScr(" "//SwChar//"help -- print this help menu and exit") CALL WrScr("") CALL WrScr(" Notes:") CALL WrScr(" -- Unspecified ranges and resolutions default to what is in the file.") @@ -324,6 +328,15 @@ SUBROUTINE ParseArg( CLSettings, CLFlags, ThisArgUC, ThisArg, ifwFlagSet, ErrSta ELSEIF ( TRIM(ThisArgUC) == "VTK" ) THEN CLFlags%WrVTK = .TRUE. RETURN + ELSEIF ( TRIM(ThisArgUC) == "UNIFORM" ) THEN + CLFlags%WrUniform = .TRUE. + RETURN + ELSEIF ( TRIM(ThisArgUC) == "BOXEXCEEDALLOW" ) THEN + CLFlags%BoxExceedAllowF = .TRUE. + RETURN + ELSEIF ( TRIM(ThisArgUC) == "ACCEL" ) THEN + CLFlags%OutputAccel = .TRUE. + RETURN ELSE CALL SetErrStat( ErrID_Warn," Unrecognized option '"//SwChar//TRIM(ThisArg)//"'. Ignoring. Use option "//SwChar//"help for list of options.", & ErrStat,ErrMsg,'ParseArg') @@ -867,6 +880,10 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat CALL ReadVar( UnIn, FileName, DvrFlags%WrVTK, 'WrVTK', 'Convert wind data to VTK format?', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) CALL SetErrStat(ErrStatTmp, ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + ! WrUniform + CALL ReadVar( UnIn, FileName, DvrFlags%WrUniform, 'WrUniform', 'Convert wind data to Uniform Wind format?', ErrStatTmp, ErrMsgTmp, UnEchoLocal ) + CALL SetErrStat(ErrStatTmp, ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat >= AbortErrLev ) THEN CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) CLOSE( UnIn ) @@ -977,7 +994,15 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat ! DvrFlags%SummaryFile = .TRUE. ENDIF - + ! Flag to allow sampling outside grid + CALL ReadVar( UnIn, FileName,DvrFlags%BoxExceedAllowF,'BoxExceedAllow',' Allow point sampling outside grid', & + ErrStatTmp,ErrMsgTmp, UnEchoLocal ) + IF ( ErrStatTmp /= ErrID_None ) THEN + CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) + CLOSE( UnIn ) + RETURN + ENDIF #ifdef UNUSED_INPUTFILE_LINES !------------------------------------------------------------------------------------------------- @@ -1066,7 +1091,15 @@ SUBROUTINE ReadDvrIptFile( DvrFileName, DvrFlags, DvrSettings, ProgInfo, ErrStat IF ( PathIsRelative( DvrSettings%PointsFileName ) ) DvrSettings%PointsFileName = TRIM(PriPath)//TRIM(DvrSettings%PointsFileName) - + ! CalcAccel - calculate wind acceleration (unused if .not. DvrFlags%PointsFile) + CALL ReadVar( UnIn, FileName,DvrFlags%OutputAccel, 'CalcAccel', ' Calc and output wind acceleration', & + ErrStatTmp,ErrMsgTmp, UnEchoLocal ) + IF ( ErrStatTmp /= ErrID_None ) THEN + CALL SetErrStat(ErrID_Fatal,ErrMsgTmp,ErrStat,ErrMsg,RoutineName) + CALL CleanupEchoFile( EchoFileContents, UnEchoLocal ) + CLOSE( UnIn ) + RETURN + ENDIF !------------------------------------------------------------------------------------------------- ! gridded data output @@ -1329,9 +1362,12 @@ SUBROUTINE UpdateSettingsWithCL( DvrFlags, DvrSettings, CLFlags, CLSettings, DVR ErrMsgTmp = '' - DvrFlags%WrHAWC = DvrFlags%WrHAWC .or. CLFlags%WrHAWC ! create file if specified in either place - DvrFlags%WrBladed = DvrFlags%WrBladed .or. CLFlags%WrBladed ! create file if specified in either place - DvrFlags%WrVTK = DvrFlags%WrVTK .or. CLFlags%WrVTK ! create file if specified in either place + DvrFlags%WrHAWC = DvrFlags%WrHAWC .or. CLFlags%WrHAWC ! create file if specified in either place + DvrFlags%WrBladed = DvrFlags%WrBladed .or. CLFlags%WrBladed ! create file if specified in either place + DvrFlags%WrVTK = DvrFlags%WrVTK .or. CLFlags%WrVTK ! create file if specified in either place + DvrFlags%WrUniform = DvrFlags%WrUniform .or. CLFlags%WrUniform ! create file if specified in either place + DvrFlags%BoxExceedAllowF = DvrFlags%BoxExceedAllowF .or. CLFlags%BoxExceedAllowF ! flag to allow points beyond box for FF + DvrFlags%OutputAccel = DvrFlags%OutputAccel .or. CLFlags%OutputAccel ! calculate acceleration if specified in either place ! ! Due to the complexity, we are handling overwriting driver input file settings with ! ! command line settings and the instance where no driver input file is read separately. @@ -2145,7 +2181,7 @@ SUBROUTINE WindGridMessage( Settings, ToFile, Msg, MsgLen ) IF ( ToFile ) THEN Msg='# ' ELSE - Msg="Requested wind grid data will be written to "//TRIM(Settings%WindGridOutputName)//'.' + Msg="Requested wind grid data will be written to "//TRIM(Settings%WindGridOutput%Name)//'.' ENDIF Msg = TRIM(Msg)//" Requested data:"//NewLine @@ -2254,11 +2290,8 @@ SUBROUTINE WindGridMessage( Settings, ToFile, Msg, MsgLen ) !> This subroutine outputs the results of the WindGrid calculations information at each timestep. -SUBROUTINE WindGridVel_OutputWrite (FileUnit, FileName, Initialized, Settings, GridXYZ, GridVel, TIME, ErrStat, ErrMsg) - - INTEGER(IntKi), INTENT(INOUT) :: FileUnit !< Unit number for the output file - CHARACTER(*), INTENT(IN ) :: FileName !< Name of the current unit number - LOGICAL, INTENT(INOUT) :: Initialized !< Was this file started before? +SUBROUTINE WindGridVel_OutputWrite (OutFile, Settings, GridXYZ, GridVel, TIME, ErrStat, ErrMsg) + TYPE(OutputFile), INTENT(INOUT) :: OutFile TYPE(IfWDriver_Settings), INTENT(IN ) :: Settings !< Settings for IfW driver REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: GridXYZ(:,:) !< The position grid passed in REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: GridVel(:,:) !< The velocity grid passed in @@ -2275,7 +2308,7 @@ SUBROUTINE WindGridVel_OutputWrite (FileUnit, FileName, Initialized, Settings, G INTEGER(IntKi) :: I !< generic counter - WindVelFmt = "(3(F14.7,3x),3(F10.3,3x))" + WindVelFmt = "(3(F14.7,3x),3(F14.7,3x))" ErrMsg = '' ErrStat = ErrID_None @@ -2284,39 +2317,39 @@ SUBROUTINE WindGridVel_OutputWrite (FileUnit, FileName, Initialized, Settings, G ! If it hasn't been initially written to, do this then exit. Otherwise set a few things and continue. - IF ( .NOT. Initialized ) THEN + IF ( .NOT. OutFile%Initialized ) THEN - CALL GetNewUnit( FileUnit ) - CALL OpenFOutFile( FileUnit, TRIM(FileName), ErrStatTmp, ErrMsgTmp ) + CALL GetNewUnit( OutFile%Unit ) + CALL OpenFOutFile( OutFile%Unit, TRIM(OutFile%Name), ErrStatTmp, ErrMsgTmp ) CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'WindGridVel_OutputWrite' ) IF ( ErrStat >= AbortErrLev ) RETURN - Initialized = .TRUE. + OutFile%Initialized = .TRUE. ! Write header section - WRITE( FileUnit,'(A)', IOSTAT=ErrStatTmp ) '## This file was generated by '//TRIM(GetNVD(Settings%ProgInfo))// & + WRITE( OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## This file was generated by '//TRIM(GetNVD(Settings%ProgInfo))// & ' on '//CurDate()//' at '//CurTime()//'.' - WRITE( FileUnit,'(A)', IOSTAT=ErrStatTmp ) '## This file contains the wind velocity at a grid of points at each '// & + WRITE( OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## This file contains the wind velocity at a grid of points at each '// & 'requested timestep' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '## It is arranged as blocks of X,Y,Z,U,V,W at each timestep' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '## Each block is separated by two blank lines for use in gnuplot' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# ' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## It is arranged as blocks of X,Y,Z,U,V,W at each timestep' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## Each block is separated by two blank lines for use in gnuplot' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' CALL WindGridMessage( Settings, .TRUE., ErrMsgTmp, LenErrMsgTmp ) - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) ErrMsgTmp(1:LenErrMsgTmp) - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# ' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# ' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# X Y Z '// & + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) ErrMsgTmp(1:LenErrMsgTmp) + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# X Y Z '// & ' U V W' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# (m) (m) (m) '// & + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# (m) (m) (m) '// & ' (m/s) (m/s) (m/s)' ELSE - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) NewLine//NewLine - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# Time: '//TRIM(Num2LStr(TIME)) + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) NewLine//NewLine + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# Time: '//TRIM(Num2LStr(TIME)) DO I = 1,SIZE(GridXYZ,DIM=2) - WRITE (FileUnit,WindVelFmt, IOSTAT=ErrStatTmp ) GridXYZ(1,I),GridXYZ(2,I),GridXYZ(3,I),GridVel(1,I),GridVel(2,I),GridVel(3,I) + WRITE (OutFile%Unit,WindVelFmt, IOSTAT=ErrStatTmp ) GridXYZ(1,I),GridXYZ(2,I),GridXYZ(3,I),GridVel(1,I),GridVel(2,I),GridVel(3,I) ENDDO @@ -2325,28 +2358,27 @@ SUBROUTINE WindGridVel_OutputWrite (FileUnit, FileName, Initialized, Settings, G END SUBROUTINE WindGridVel_OutputWrite -SUBROUTINE PointsVel_OutputWrite (FileUnit, FileName, Initialized, Settings, GridXYZ, GridVel, TIME, ErrStat, ErrMsg) +SUBROUTINE PointData_OutputWrite (OutFile, Settings, GridXYZ, GridVel, GridAcc, TIME, IsVel, ErrStat, ErrMsg) - INTEGER(IntKi), INTENT(INOUT) :: FileUnit !< Unit number for the output file - CHARACTER(*), INTENT(IN ) :: FileName !< Name of the current unit number - LOGICAL, INTENT(INOUT) :: Initialized !< Was this file started before? + TYPE(OutputFile), INTENT(INOUT) :: OutFile TYPE(IfWDriver_Settings), INTENT(IN ) :: Settings !< Settings for IfW driver REAL(ReKi), INTENT(IN ) :: GridXYZ(:,:) !< The position grid passed in REAL(ReKi), INTENT(IN ) :: GridVel(:,:) !< The velocity grid passed in + REAL(ReKi), allocatable, INTENT(IN ) :: GridAcc(:,:) !< The acceleration grid passed in REAL(DbKi), INTENT(IN ) :: TIME !< The current time + LOGICAL, INTENT(IN ) :: IsVel !< Is this velocity output INTEGER(IntKi), INTENT( OUT) :: ErrStat !< returns a non-zero value when an error occurs CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - ! Temporary local variables INTEGER(IntKi) :: ErrStatTmp !< Temporary variable for the status of error message CHARACTER(2048) :: ErrMsgTmp !< Temporary variable for the error message - INTEGER(IntKi) :: LenErrMsgTmp !< Length of ErrMsgTmp (for getting WindGrid info) - INTEGER(IntKi) :: I !< Generic counter + INTEGER(IntKi) :: I, J !< Generic counter - CHARACTER(61) :: PointsVelFmt !< Format specifier for the output file for wave elevation series + CHARACTER(61) :: NameUnitFmt !< Format specifier for the output file for channel names and units + CHARACTER(61) :: PointsVelFmt !< Format specifier for the output file for wind point location and velocity - - PointsVelFmt = "(F14.7,3x,F14.7,3x,F14.7,3x,F14.7,3x,F14.7,3x,F14.7,3x,F14.7)" + NameUnitFmt = "( *(A16,3X) )" + PointsVelFmt = "( *(F16.8,3X) )" ErrMsg = '' ErrStat = ErrID_None @@ -2355,39 +2387,240 @@ SUBROUTINE PointsVel_OutputWrite (FileUnit, FileName, Initialized, Settings, Gri ! If it hasn't been initially written to, do this then exit. Otherwise set a few things and continue. - IF ( .NOT. Initialized ) THEN + IF ( .NOT. OutFile%Initialized ) THEN - CALL GetNewUnit( FileUnit ) - CALL OpenFOutFile( FileUnit, TRIM(FileName), ErrStatTmp, ErrMsgTmp ) - CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'PointsVel_OutputWrite' ) + CALL GetNewUnit( OutFile%Unit ) + CALL OpenFOutFile( OutFile%Unit, TRIM(OutFile%Name), ErrStatTmp, ErrMsgTmp ) + CALL SetErrStat( ErrStatTmp, ErrMsgTmp, ErrStat, ErrMsg, 'PointData_OutputWrite' ) IF ( ErrStat >= AbortErrLev ) RETURN - Initialized = .TRUE. + OutFile%Initialized = .TRUE. ! Write header section - WRITE( FileUnit,'(A)', IOSTAT=ErrStatTmp ) '## This file was generated by '//TRIM(GetNVD(Settings%ProgInfo))// & + WRITE( OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## This file was generated by '//TRIM(GetNVD(Settings%ProgInfo))// & ' on '//CurDate()//' at '//CurTime()//'.' - WRITE( FileUnit,'(A)', IOSTAT=ErrStatTmp ) '## This file contains the wind velocity at the '// & - TRIM(Num2LStr(SIZE(GridXYZ,DIM=2)))//' points specified in the '// & - 'file '//TRIM(Settings%PointsFileName)//'.' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# ' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# T X Y Z '// & - ' U V W' - WRITE (FileUnit,'(A)', IOSTAT=ErrStatTmp ) '# (s) (m) (m) (m) '// & - ' (m/s) (m/s) (m/s)' + if (allocated(GridAcc)) then + WRITE( OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## This file contains the wind velocity and acceleration at the '// & + TRIM(Num2LStr(SIZE(GridXYZ,DIM=2)))//' points specified in the '// & + 'file '//TRIM(Settings%PointsFileName)//'.' + else + WRITE( OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '## This file contains the wind velocity at the '// & + TRIM(Num2LStr(SIZE(GridXYZ,DIM=2)))//' points specified in the '// & + 'file '//TRIM(Settings%PointsFileName)//'.' + end if + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' + WRITE (OutFile%Unit,'(A)', IOSTAT=ErrStatTmp ) '# ' + if (allocated(GridAcc)) then + WRITE (OutFile%Unit, NameUnitFmt, IOSTAT=ErrStatTmp ) 'T', 'X', 'Y', 'Z', 'U', 'V', 'W', 'UA', 'VA', 'WA' + WRITE (OutFile%Unit, NameUnitFmt, IOSTAT=ErrStatTmp ) '(s)', '(m)', '(m)', '(m)', '(m/s)', '(m/s)', '(m/s)', '(m/s/s)', '(m/s/s)', '(m/s/s)' + else + WRITE (OutFile%Unit, NameUnitFmt, IOSTAT=ErrStatTmp ) 'T', 'X', 'Y', 'Z', 'U', 'V', 'W' + WRITE (OutFile%Unit, NameUnitFmt, IOSTAT=ErrStatTmp ) '(s)', '(m)', '(m)', '(m)', '(m/s)', '(m/s)', '(m/s)' + end if ELSE - DO I = 1,SIZE(GridXYZ,DIM=2) + if (allocated(GridAcc)) then + DO I = 1,SIZE(GridXYZ,DIM=2) + WRITE (OutFile%Unit, PointsVelFmt, IOSTAT=ErrStatTmp) TIME, (GridXYZ(J,I),j=1,3), (GridVel(J,I),j=1,3), (GridAcc(J,I),j=1,3) + ENDDO + else + DO I = 1,SIZE(GridXYZ,DIM=2) + WRITE (OutFile%Unit, PointsVelFmt, IOSTAT=ErrStatTmp) TIME, (GridXYZ(J,I),j=1,3), (GridVel(J,I),j=1,3) + ENDDO + end if + + ENDIF - WRITE (FileUnit,PointsVelFmt, IOSTAT=ErrStatTmp ) TIME,GridXYZ(1,I),GridXYZ(2,I),GridXYZ(3,I),GridVel(1,I),GridVel(2,I),GridVel(3,I) +END SUBROUTINE PointData_OutputWrite - ENDDO - ENDIF +subroutine IfW_WriteUniform(FF, FileRootName, ErrStat, ErrMsg) + + type(FlowFieldType), intent(in) :: FF !< Parameters + character(*), intent(in) :: FileRootName !< RootName for output files + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = "IfW_WriteUniform" + type(UniformFieldType) :: UF + integer(IntKi) :: unit + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + ! Get new unit for writing file + call GetNewUnit(unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Switch based on field type + select case (FF%FieldType) + + case (Uniform_FieldType) + + call Uniform_WriteHH(FF%Uniform, FileRootName, unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + case (Grid3D_FieldType) -END SUBROUTINE PointsVel_OutputWrite + call Grid3D_to_Uniform(FF%Grid3D, UF, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat < AbortErrLev) then + call Uniform_WriteHH(UF, FileRootName, unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if + case default + ErrStat = ErrID_Warn + ErrMsg = RoutineName//': Field type '//TRIM(Num2LStr(FF%FieldType))// & + ' cannot be converted to UniformWind format.' + end select + +end subroutine IfW_WriteUniform + +subroutine IfW_WriteHAWC(FF, FileRootName, ErrStat, ErrMsg) + + type(FlowFieldType), intent(in) :: FF !< Parameters + character(*), intent(in) :: FileRootName !< RootName for output files + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = "IfW_Convert2HAWC" + type(Grid3DFieldType) :: G3D + integer(IntKi) :: unit + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ! Get new unit for writing file + call GetNewUnit(unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Switch based on field type + select case (FF%FieldType) + + case (Uniform_FieldType) + + call Uniform_to_Grid3D(FF%Uniform, FF%VelInterpCubic, G3D, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat < AbortErrLev) then + call Grid3D_WriteHAWC(G3D, FileRootName, unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if + + case (Grid3D_FieldType) + + call Grid3D_WriteHAWC(FF%Grid3D, FileRootName, unit, ErrStat, ErrMsg) + + case default + + ErrStat = ErrID_Warn + ErrMsg = RoutineName//': Field Type '//TRIM(Num2LStr(FF%FieldType))// & + ' cannot be converted to HAWC format.' + + end select + +end subroutine + +subroutine IfW_WriteBladed(FF, FileRootName, ErrStat, ErrMsg) + + type(FlowFieldType), intent(in) :: FF !< Parameters + character(*), intent(in) :: FileRootName !< RootName for output files + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = "IfW_WriteBladed" + type(Grid3DFieldType) :: G3D + integer(IntKi) :: unit + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + ! Get new unit for writing file + call GetNewUnit(unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Switch based on field type + select case (FF%FieldType) + + case (Uniform_FieldType) + + call Uniform_to_Grid3D(FF%Uniform, FF%VelInterpCubic, G3D, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat < AbortErrLev) then + call Grid3D_WriteBladed(G3D, FileRootName, unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if + + case (Grid3D_FieldType) + + call Grid3D_WriteBladed(FF%Grid3D, FileRootName, unit, ErrStat, ErrMsg) + + case default + + ErrStat = ErrID_Warn + ErrMsg = RoutineName//': Field type '//TRIM(Num2LStr(FF%FieldType))// & + ' cannot be converted to Bladed format.' + + end select + +end subroutine + + +subroutine IfW_WriteVTK(FF, FileRootName, ErrStat, ErrMsg) + + type(FlowFieldType), intent(in) :: FF !< Parameters + character(*), intent(in) :: FileRootName !< RootName for output files + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = "IfW_WriteVTK" + type(Grid3DFieldType) :: G3D + integer(IntKi) :: unit + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + ! Get new unit for writing file + call GetNewUnit(unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Switch based on field type + select case (FF%FieldType) + + case (Uniform_FieldType) + + call Uniform_to_Grid3D(FF%Uniform, FF%VelInterpCubic, G3D, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat < AbortErrLev) then + call Grid3D_WriteVTK(G3D, FileRootName, unit, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + end if + + case (Grid3D_FieldType) + + call Grid3D_WriteVTK(FF%Grid3D, FileRootName, unit, ErrStat, ErrMsg) + + case default + + ErrStat = ErrID_Warn + ErrMsg = RoutineName//': Field type '//TRIM(Num2LStr(FF%FieldType))// & + ' cannot be converted to VTK format.' + + end select + +end subroutine IfW_WriteVTK !> This routine exists only to support the development of the module. It will not be needed after the module is complete. @@ -2395,13 +2628,14 @@ SUBROUTINE printSettings( DvrFlags, DvrSettings ) ! The arguments TYPE( IfWDriver_Flags ), INTENT(IN ) :: DvrFlags !< Flags indicating which settings were set TYPE( IfWDriver_Settings ), INTENT(IN ) :: DvrSettings !< Stored settings + integer(IntKi) :: i CALL WrsCr(TRIM(GetNVD(DvrSettings%ProgInfo))) CALL WrScr(' DvrIptFile: '//FLAG(DvrFlags%DvrIptFile)// ' '//TRIM(DvrSettings%DvrIptFileName)) CALL WrScr(' IfWIptFile: '//FLAG(DvrFlags%IfWIptFile)// ' '//TRIM(DvrSettings%IfWIptFileName)) CALL WrScr(' PointsFile: '//FLAG(DvrFlags%PointsFile)// ' '//TRIM(DvrSettings%PointsFileName)) - CALL WrScr(' FFTOutputName: '//FLAG(DvrFlags%FFTcalc)// ' '//TRIM(DvrSettings%FFTOutputName)) - CALL WrScr(' WindGridOutName: '//FLAG(DvrFlags%WindGrid)// ' '//TRIM(DvrSettings%WindGridOutputName)) + CALL WrScr(' FFTOutputName: '//FLAG(DvrFlags%FFTcalc)// ' '//TRIM(DvrSettings%FFTOutput%Name)) + CALL WrScr(' WindGridOutName: '//FLAG(DvrFlags%WindGrid)// ' '//TRIM(DvrSettings%WindGridOutput%Name)) CALL WrScr(' Summary: '//FLAG(DvrFlags%Summary)) CALL WrScr(' SummaryFile: '//FLAG(DvrFlags%SummaryFile)// ' '//TRIM(DvrSettings%SummaryFileName)) CALL WrScr(' TStart: '//FLAG(DvrFlags%TStart)// ' '//TRIM(Num2LStr(DvrSettings%TStart))) @@ -2432,11 +2666,11 @@ SUBROUTINE printSettings( DvrFlags, DvrSettings ) CALL WrScr(' Dx: '//FLAG(DvrFlags%Dx)// ' '//TRIM(Num2LStr(DvrSettings%GridDelta(1)))) CALL WrScr(' Dy: '//FLAG(DvrFlags%Dy)// ' '//TRIM(Num2LStr(DvrSettings%GridDelta(2)))) CALL WrScr(' Dz: '//FLAG(DvrFlags%Dz)// ' '//TRIM(Num2LStr(DvrSettings%GridDelta(3)))) - CALL WrScr(' WindGridOutputInit: '//FLAG(DvrFlags%WindGridOutputInit)//' Unit #: '//TRIM(Num2LStr(DvrSettings%WindGridOutputUnit))) + CALL WrScr(' WindGridOutputInit: '//FLAG(DvrSettings%WindGridOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%WindGridOutput%Unit))) end if - CALL WrScr(' FFTOutputInit: '//FLAG(DvrFlags%FFTOutputInit)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%FFTOutputUnit))) - CALL WrScr(' PointsOutputInit: '//FLAG(DvrFlags%PointsOutputInit)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%PointsOutputUnit))) - RETURN + CALL WrScr(' FFTOutputInit: '//FLAG(DvrSettings%FFTOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%FFTOutput%Unit))) + CALL WrScr(' PointsVelOutputInit: '//FLAG(DvrSettings%PointsVelOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%PointsVelOutput%Unit))) + CALL WrScr(' PointsAccOutputInit: '//FLAG(DvrSettings%PointsVelOutput%Initialized)// ' Unit #: '//TRIM(Num2LStr(DvrSettings%PointsVelOutput%Unit))) END SUBROUTINE printSettings diff --git a/modules/inflowwind/src/InflowWind_Driver_Types.f90 b/modules/inflowwind/src/InflowWind_Driver_Types.f90 index 26bad3c3d..669303cf6 100644 --- a/modules/inflowwind/src/InflowWind_Driver_Types.f90 +++ b/modules/inflowwind/src/InflowWind_Driver_Types.f90 @@ -31,6 +31,12 @@ MODULE InflowWind_Driver_Types IMPLICIT NONE + TYPE OutputFile + LOGICAL :: Initialized = .FALSE. !< Flag indicating that file has been initialized + CHARACTER(1024) :: Name = "" !< Filename for output from points read in from points file + INTEGER(IntKi) :: Unit = -1 !< Unit number for the output file for the Points file output + END TYPE + !> This contains flags to note if the settings were made. This same data structure is !! used both during the driver input file and the command line options. !! @@ -38,7 +44,7 @@ MODULE InflowWind_Driver_Types !! it is handled internally by InflowWInd. !! !! NOTE: The wind direction is specified by the InflowWind input file. - TYPE :: IfWDriver_Flags + TYPE :: IfWDriver_Flags LOGICAL :: DvrIptFile = .FALSE. !< Was an input file name given on the command line? LOGICAL :: IfWIptFile = .FALSE. !< Was an InflowWind input file requested? LOGICAL :: Summary = .FALSE. !< create a summary at command line? (data extents in the wind file) @@ -59,53 +65,47 @@ MODULE InflowWind_Driver_Types LOGICAL :: Dy = .FALSE. !< speficied a resolution in y LOGICAL :: Dz = .FALSE. !< specified a resolution in z - LOGICAL :: PointsFile = .FALSE. !< points filename to read in -- command line option only + LOGICAL :: PointsFile = .FALSE. !< points filename to read in + LOGICAL :: OutputAccel = .FALSE. !< flag to calculate and output wind acceleration in addition to velocity - LOGICAL :: WindGridOutputInit = .FALSE. !< Is the WindGridOut file initialized - LOGICAL :: PointsOutputInit = .FALSE. !< Is the Points output file initialized - LOGICAL :: FFTOutputInit = .FALSE. !< Is the FFT output file initialized LOGICAL :: Verbose = .FALSE. !< Verbose error reporting LOGICAL :: VVerbose = .FALSE. !< Very Verbose error reporting + LOGICAL :: BoxExceedAllowF = .FALSE. !< set flag to allow exceeding wind box boundaries for FF files (for diagnostic purposes) LOGICAL :: WrHAWC = .FALSE. !< Requested file conversion to HAWC2 format? LOGICAL :: WrBladed = .FALSE. !< Requested file conversion to Bladed format? LOGICAL :: WrVTK = .FALSE. !< Requested file output as VTK? - END TYPE IfWDriver_Flags + LOGICAL :: WrUniform = .FALSE. !< Requested file output as Uniform wind format? + END TYPE IfWDriver_Flags ! This contains all the settings (possible passed in arguments). - TYPE :: IfWDriver_Settings - CHARACTER(1024) :: DvrIptFileName !< Driver input file name - CHARACTER(1024) :: IfWIptFileName !< Filename of InflowWind input file to read (if no driver input file) - CHARACTER(1024) :: SummaryFileName !< Filename for the summary information output - - CHARACTER(1024) :: PointsFileName !< Filename of points file to read in - CHARACTER(1024) :: PointsOutputName !< Filename for output from points read in from points file - CHARACTER(1024) :: FFTOutputName !< Filename for output from points read in from points file - CHARACTER(1024) :: WindGridOutputName !< Filename for output from points read in from points file - - INTEGER(IntKi) :: WindGridOutputUnit !< Unit number for the output file for the wind grid data - INTEGER(IntKi) :: PointsOutputUnit !< Unit number for the output file for the Points file output - INTEGER(IntKi) :: FFTOutputUnit !< Unit number for the output file for the FFT results - - INTEGER(IntKi) :: NumTimeSteps !< Number of timesteps - REAL(DbKi) :: DT !< resolution of time - REAL(DbKi) :: TStart !< range of time -- end time converted from TRange (command line option only) + TYPE :: IfWDriver_Settings + CHARACTER(1024) :: DvrIptFileName = "" !< Driver input file name + CHARACTER(1024) :: IfWIptFileName = "" !< Filename of InflowWind input file to read (if no driver input file) + CHARACTER(1024) :: SummaryFileName = "" !< Filename for the summary information output + CHARACTER(1024) :: PointsFileName = "" !< Filename of points file to read in + + INTEGER(IntKi) :: NumTimeSteps = 0 !< Number of timesteps + REAL(DbKi) :: DT = 0.0_DbKi !< resolution of time + REAL(DbKi) :: TStart = 0.0_DbKi !< range of time -- end time converted from TRange (command line option only) - REAL(ReKi) :: FFTcoord(1:3) !< (x,y,z) coordinate to do an FFT at + REAL(ReKi) :: FFTcoord(1:3) = 0.0_ReKi !< (x,y,z) coordinate to do an FFT at - REAL(ReKi) :: GridDelta(1:3) !< (GridDx,GridDy,GridDz) -- grid point spacing - INTEGER(IntKi) :: GridN(1:3) !< (GridNx,GridNy,GridNz) -- number of grid points + REAL(ReKi) :: GridDelta(1:3) = 0.0_ReKi !< (GridDx,GridDy,GridDz) -- grid point spacing + INTEGER(IntKi) :: GridN(1:3) = 1_IntKi !< (GridNx,GridNy,GridNz) -- number of grid points - REAL(ReKi) :: XRange(1:2) !< Range in the x-direction for the gridded data - REAL(ReKi) :: YRange(1:2) !< Range in the y-direction for the gridded data - REAL(ReKi) :: ZRange(1:2) !< Range in the z-direction for the gridded data + REAL(ReKi) :: XRange(1:2) = 0.0_ReKi !< Range in the x-direction for the gridded data + REAL(ReKi) :: YRange(1:2) = 0.0_ReKi !< Range in the y-direction for the gridded data + REAL(ReKi) :: ZRange(1:2) = 0.0_ReKi !< Range in the z-direction for the gridded data - TYPE(ProgDesc) :: ProgInfo !< Program info - TYPE(ProgDesc) :: IfWProgInfo !< Program info for InflowWind + TYPE(ProgDesc) :: ProgInfo !< Program info + TYPE(OutputFile) :: WindGridOutput + TYPE(OutputFile) :: FFTOutput + TYPE(OutputFile) :: PointsVelOutput - END TYPE IfWDriver_Settings + END TYPE IfWDriver_Settings END MODULE InflowWind_Driver_Types diff --git a/modules/inflowwind/src/InflowWind_IO.f90 b/modules/inflowwind/src/InflowWind_IO.f90 new file mode 100644 index 000000000..122d8a5ce --- /dev/null +++ b/modules/inflowwind/src/InflowWind_IO.f90 @@ -0,0 +1,2937 @@ +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2022 National Renewable Energy Laboratory +! +! This file is part of InflowWind. +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +! +!********************************************************************************************************************************** + +module InflowWind_IO + +use NWTC_Library +use InflowWind_IO_Types +use IfW_FlowField + +implicit none +private + +public :: IfW_SteadyWind_Init, & + IfW_UniformWind_Init, & + IfW_TurbSim_Init, & + IfW_Bladed_Init, & + IfW_HAWC_Init, & + IfW_User_Init, & + IfW_Grid4D_Init, & + IfW_Points_Init + +public :: Uniform_WriteHH, & + Grid3D_WriteBladed, & + Grid3D_WriteHAWC, & + Grid3D_WriteVTK + +type(ProgDesc), parameter :: InflowWind_IO_Ver = ProgDesc('InflowWind_IO', '', '') + +integer(IntKi), parameter :: ScaleMethod_None = 0, & !< no scaling + ScaleMethod_Direct = 1, & !< direct scaling factors + ScaleMethod_StdDev = 2 !< requested standard deviation + +contains + +subroutine IfW_Points_Init(InitInp, PF, ErrStat, ErrMsg) + type(Points_InitInputType), intent(in) :: InitInp + type(PointsFieldType), intent(out) :: PF + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = 'IfW_Points_Init' + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + + ErrStat = ErrID_None + ErrMsg = "" + + ! UVW components at points + call AllocAry(PF%Vel, 3, InitInp%NumWindPoints, & + 'Point Velocity Array', TmpErrStat, TmpErrMsg) + call SetErrStat(ErrStat, ErrMsg, TmpErrStat, TmpErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + +end subroutine + +!> IfW_SteadyWind_Init initializes a Uniform field with with one set of values. +subroutine IfW_SteadyWind_Init(InitInp, SumFileUnit, UF, FileDat, ErrStat, ErrMsg) + type(Steady_InitInputType), intent(in) :: InitInp + integer(IntKi), intent(in) :: SumFileUnit + type(UniformFieldType), intent(out) :: UF + type(WindFileDat), intent(out) :: FileDat + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = 'IfW_SteadyWind_Init' + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + + ErrStat = ErrID_None + ErrMsg = "" + + ! Set parameters from inititialization input + UF%DataSize = 1 + UF%RefHeight = InitInp%RefHt + UF%RefLength = 1.0_ReKi + + ! Allocate uniform wind data arrays + call UniformWind_AllocArrays(UF, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Set data values + UF%Time = 0.0_ReKi + UF%VelH = InitInp%HWindSpeed + UF%VelV = 0.0_ReKi + UF%VelGust = 0.0_ReKi + UF%AngleH = 0.0_ReKi + UF%AngleV = 0.0_ReKi + UF%ShrH = 0.0_ReKi + UF%ShrV = InitInp%PLExp + UF%LinShrV = 0.0_ReKi + + !---------------------------------------------------------------------------- + ! Set wind file data + !---------------------------------------------------------------------------- + + FileDat%FileName = "" + FileDat%WindType = 1 + FileDat%RefHt = UF%RefHeight + FileDat%RefHt_Set = .false. + FileDat%DT = 0.0_ReKi + FileDat%NumTSteps = UF%DataSize + FileDat%ConstantDT = .false. + FileDat%TRange = 0.0_ReKi + FileDat%TRange_Limited = .false. + FileDat%YRange = 0.0_ReKi + FileDat%YRange_Limited = .false. + FileDat%ZRange = 0.0_ReKi + FileDat%ZRange_Limited = .false. + FileDat%BinaryFormat = 0_IntKi + FileDat%IsBinary = .false. + FileDat%TI = 0.0_ReKi + FileDat%TI_listed = .false. + FileDat%MWS = InitInp%HWindSpeed + + !---------------------------------------------------------------------------- + ! Write summary file if applicable + !---------------------------------------------------------------------------- + + if (SumFileUnit > 0) then + write (SumFileUnit, '(A)') + write (SumFileUnit, '(A80)') 'Steady wind -- Constant wind profile for entire simulation. No windfile read in.' + write (SumFileUnit, '(A40,G12.4)') ' Reference height: ', UF%RefHeight + write (SumFileUnit, '(A40,G12.4)') ' Horizontal velocity: ', UF%VelH(1) + write (SumFileUnit, '(A40,G12.4)') ' Vertical sheer power law exponent: ', UF%ShrV(1) + + ! Get IO status for unit + inquire (SumFileUnit, iostat=TmpErrStat) + if (TmpErrStat /= 0_IntKi) then + call SetErrStat(ErrID_Fatal, 'Error writing to summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + end if + +end subroutine + +!> IfW_UniformWind_Init initializes a Uniform field from file. +subroutine IfW_UniformWind_Init(InitInp, SumFileUnit, UF, FileDat, ErrStat, ErrMsg) + type(Uniform_InitInputType), intent(in) :: InitInp + integer(IntKi), intent(in) :: SumFileUnit + type(UniformFieldType), intent(out) :: UF + type(WindFileDat), intent(out) :: FileDat + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = 'IfW_UniformWind_Init' + integer(IntKi), parameter :: MaxNumCols = 9 + integer(IntKi), parameter :: MaxTries = 100 + integer(IntKi) :: NumCols + integer(IntKi) :: LineNo, ILine + integer(IntKi) :: i + type(FileInfoType) :: WindFileInfo + logical :: WindFileConstantDT + real(DbKi) :: WindFileDT + real(ReKi) :: DirDiff + real(ReKi) :: TmpData(MaxNumCols) ! Temp variable for storing wind file data + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + + ErrStat = ErrID_None + ErrMsg = "" + + ! Set parameters from inititialization input + UF%RefHeight = InitInp%RefHt + UF%RefLength = InitInp%RefLength + + ! Read wind data from file or init input data + if (InitInp%UseInputFile) then + call ProcessComFile(InitInp%WindFileName, WindFileInfo, TmpErrStat, TmpErrMsg) + else + call NWTC_Library_CopyFileInfoType(InitInp%PassedFileData, WindFileInfo, MESH_NEWCOPY, TmpErrStat, TmpErrMsg) + end if + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Get number of data lines in file + UF%DataSize = WindFileInfo%NumLines + + ! Allocate uniform wind data arrays + call UniformWind_AllocArrays(UF, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Parse wind file data + !---------------------------------------------------------------------------- + + ! Initialize reading variables + NumCols = MaxNumCols + LineNo = 1 + + ! Attempt to read 9 columns from line; if error, upflow column is not in file + ! so set upflow=0 and reduce number of columns to read remaning data + call ParseAry(WindFileInfo, LineNo, "HH file line", TmpData(1:NumCols), NumCols, TmpErrStat, TmpErrMsg) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Info, ' Could not read upflow column in uniform wind files. Assuming upflow is 0.', & + ErrStat, ErrMsg, RoutineName) + UF%AngleV = 0 + NumCols = MaxNumCols - 1 + end if + + ! Parse the data and store it + LineNo = 1 + do i = 1, UF%DataSize + call ParseAry(WindFileInfo, LineNo, "HH file line", TmpData(1:NumCols), NumCols, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + UF%Time(i) = TmpData(1) + UF%VelH(i) = TmpData(2) + UF%AngleH(i) = TmpData(3)*D2R + UF%VelV(i) = TmpData(4) + UF%ShrH(i) = TmpData(5) + UF%ShrV(i) = TmpData(6) + UF%LinShrV(i) = TmpData(7) + UF%VelGust(i) = TmpData(8) + if (NumCols > 8) UF%AngleV(i) = TmpData(9)*D2R + end do + + !---------------------------------------------------------------------------- + ! Ensure the wind direction isn't jumping more than 180 degrees between + ! any 2 consecutive input times. + ! (Avoids interpolation errors with modular arithemetic.) + !---------------------------------------------------------------------------- + + do i = 2, UF%DataSize + ILine = 1 + do while (ILine < MaxTries) + DirDiff = (UF%AngleH(i) - UF%AngleH(i - 1)) + if (abs(DirDiff) < Pi) exit + UF%AngleH(i) = UF%AngleH(i) - SIGN(TwoPi, DirDiff) + ILine = ILine + 1 + end do + + if (ILine >= MaxTries) then + TmpErrMsg = ' Error calculating wind direction from uniform wind file. p%AngleH(' & + //TRIM(Num2LStr(i))//') = '//TRIM(Num2LStr(UF%AngleH(i)))//'; p%AngleH(' & + //TRIM(Num2LStr(i + 1))//') = '//TRIM(Num2LStr(UF%AngleH(i + 1))) + call SetErrStat(ErrID_Fatal, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + end if + end do + + !---------------------------------------------------------------------------- + ! Find out information on the timesteps and range + !---------------------------------------------------------------------------- + + ! Uniform timesteps + if (UF%DataSize > 3) then + WindFileConstantDT = .true. + WindFileDT = UF%Time(2) - UF%Time(1) + do I = 3, UF%DataSize + if (.not. EqualRealNos((UF%Time(i) - UF%Time(i - 1)), real(WindFileDT, ReKi))) then + WindFileConstantDT = .false. + exit + end if + end do + else + ! Insufficient points to check, report that the timesteps are not uniform + WindFileConstantDT = .false. + WindFileDT = 0.0_ReKi + end if + + !---------------------------------------------------------------------------- + ! Store wind file metadata + !---------------------------------------------------------------------------- + + FileDat%FileName = InitInp%WindFileName + FileDat%WindType = 2 + FileDat%RefHt = UF%RefHeight + FileDat%RefHt_Set = .false. + FileDat%DT = WindFileDT + FileDat%NumTSteps = UF%DataSize + FileDat%ConstantDT = WindFileConstantDT + FileDat%TRange = [UF%Time(1), UF%Time(UF%DataSize)] + FileDat%TRange_Limited = .false. + FileDat%YRange = (/0.0_ReKi, 0.0_ReKi/) + FileDat%YRange_Limited = .false. + FileDat%ZRange = (/0.0_ReKi, 0.0_ReKi/) + FileDat%ZRange_Limited = .false. + FileDat%BinaryFormat = 0_IntKi + FileDat%IsBinary = .false. + FileDat%TI = 0.0_ReKi + FileDat%TI_listed = .false. + + if (UF%DataSize == 1) then + FileDat%MWS = UF%VelH(1) + else + FileDat%MWS = 0.0_ReKi + do i = 2, UF%DataSize + FileDat%MWS = FileDat%MWS + 0.5_ReKi*(UF%VelH(i) + UF%VelH(i - 1))* & + (UF%Time(i) - UF%Time(i - 1)) + end do + FileDat%MWS = FileDat%MWS/(UF%Time(UF%DataSize) - UF%Time(1)) + end if + + ! Check if the fist data point from the file is not along the X-axis while + ! applying the windfield rotation + if ((.not. EqualRealNos(UF%AngleH(1), 0.0_ReKi)) .and. & + (.not. EqualRealNos(InitInp%PropagationDir, 0.0_ReKi))) then + call SetErrStat(ErrID_Warn, ' Possible double rotation of wind field! Uniform wind file starts with a wind direction of '// & + TRIM(Num2LStr(UF%AngleH(1)*R2D))// & + ' degrees and the InflowWind input file specifies a PropagationDir of '// & + TRIM(Num2LStr(InitInp%PropagationDir*R2D))//' degrees.', & + ErrStat, ErrMsg, RoutineName) + end if + + !---------------------------------------------------------------------------- + ! Print warnings and messages + !---------------------------------------------------------------------------- + + if (UF%Time(1) > 0.0) then + TmpErrMsg = 'The uniform wind file : "'//TRIM(ADJUSTL(InitInp%WindFileName))// & + '" starts at a time '//'greater than zero. Interpolation errors may result.' + call SetErrStat(ErrID_Warn, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + end if + + if (UF%DataSize == 1) then + TmpErrMsg = ' Only 1 line in uniform wind file. Steady, horizontal wind speed at the hub height is '// & + TRIM(Num2LStr(UF%VelH(1)))//' m/s.' + call SetErrStat(ErrID_Info, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + end if + + !---------------------------------------------------------------------------- + ! Write to the summary file + !---------------------------------------------------------------------------- + + if (SumFileUnit > 0) then + write (SumFileUnit, '(A)') + write (SumFileUnit, '(A)') 'Uniform wind. Module '//TRIM(InflowWind_IO_Ver%Name)//' '//TRIM(InflowWind_IO_Ver%Ver) + write (SumFileUnit, '(A)') ' FileName: '//TRIM(InitInp%WindFileName) + write (SumFileUnit, '(A34,G12.4)') ' Reference height (m): ', UF%RefHeight + write (SumFileUnit, '(A34,G12.4)') ' Reference length (m): ', UF%RefLength + write (SumFileUnit, '(A32,I8)') ' Number of data lines: ', UF%DataSize + write (SumFileUnit, '(A)') ' Time range (s): [ '// & + TRIM(Num2LStr(UF%Time(1)))//' : '//TRIM(Num2LStr(UF%Time(UF%DataSize)))//' ]' + + ! Get IO status for unit + inquire (SumFileUnit, iostat=TmpErrStat) + if (TmpErrStat /= 0_IntKi) then + call SetErrStat(ErrID_Fatal, 'Error writing to summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + end if + +end subroutine + +!> UniformWind_AllocArrays allocates the data arrays in the Uniform field. +subroutine UniformWind_AllocArrays(UF, ErrStat, ErrMsg) + type(UniformFieldType), intent(inout) :: UF + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = 'UniformWind_AllocArrays' + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + + ErrStat = ErrID_None + ErrMsg = "" + + if (.not. allocated(UF%Time)) then + call AllocAry(UF%Time, UF%DataSize, 'Uniform wind time', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%VelH)) then + call AllocAry(UF%VelH, UF%DataSize, 'Uniform wind horizontal wind speed', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%AngleH)) then + call AllocAry(UF%AngleH, UF%DataSize, 'Uniform wind direction', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%AngleV)) then + call AllocAry(UF%AngleV, UF%DataSize, 'Uniform wind upflow angle', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%VelV)) then + call AllocAry(UF%VelV, UF%DataSize, 'Uniform vertical wind speed', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%ShrH)) then + call AllocAry(UF%ShrH, UF%DataSize, 'Uniform horizontal linear shear', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%ShrV)) then + call AllocAry(UF%ShrV, UF%DataSize, 'Uniform vertical power-law shear exponent', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%LinShrV)) then + call AllocAry(UF%LinShrV, UF%DataSize, 'Uniform vertical linear shear', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + + if (.not. allocated(UF%VelGust)) then + call AllocAry(UF%VelGust, UF%DataSize, 'Uniform gust velocity', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat > AbortErrLev) return + end if + +end subroutine + +!> Uniform_WriteHH writes a Uniform field hub-height wind file. +subroutine Uniform_WriteHH(UF, FileRootName, unit, ErrStat, ErrMsg) + + type(UniformFieldType), intent(in) :: UF !< Parameter + character(*), intent(in) :: FileRootName !< RootName for output files + integer(IntKi), intent(in) :: Unit !< Indicates whether an error occurred (see NWTC_Library) + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = 'Uniform_WriteHH' + integer(IntKi) :: i + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + call OpenFOutFile(unit, trim(FileRootName)//'.UniformWind.dat', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + write (unit, "(A)") "#" + write (unit, "(A)") '# Uniform Wind (deterministic) file for ENFAST generated by InflowWind' + write (unit, "(A)") "#" + write (unit, "(A)") "! Time Wind Wind Vertical Horiz. Pwr.Law Lin.Vert. Gust Upflow" + write (unit, "(A)") "! Speed Dir Speed Shear Vert.Shr Shear Speed Angle" + write (unit, "(A)") "! (sec) (m/s) (Deg) (m/s) (m/s) (deg)" + + do i = 1, UF%DataSize + write (unit, "(F15.5,8(1x,F11.4))") UF%Time(i), UF%VelH(i), UF%AngleH(i)*R2D, UF%VelV(i), & + UF%ShrH(i), UF%ShrV(i), UF%LinShrV(i), UF%VelGust(i), UF%AngleV(i)*R2D + end do + + close (unit) + +end subroutine Uniform_WriteHH + +!> Read_TurbSim reads the binary TurbSim-format FF file (.bts). It fills the FFData array with +!! velocity data for the grids and fills the Tower array with velocities at points on the tower +!! (if data exists). +subroutine IfW_TurbSim_Init(InitInp, SumFileUnit, G3D, FileDat, ErrStat, ErrMsg) + + type(TurbSim_InitInputType), intent(in) :: InitInp + integer(IntKi), intent(in) :: SumFileUnit + type(Grid3DFieldType), intent(out) :: G3D + type(WindFileDat), intent(out) :: FileDat + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "IfW_TurbSim_Init" + integer(IntKi) :: WindFileUnit + integer(B2Ki), allocatable :: VelRaw(:, :, :) ! raw grid-field velocity data at one time step + integer(B2Ki), allocatable :: TwrRaw(:, :) ! raw towrer velocity data at one time step + character(:), allocatable :: DescStr ! description string contained in the file + integer(IntKi) :: IC ! loop counter for wind components + integer(IntKi) :: IT ! loop counter for time + integer(IntKi) :: NChar ! number of characters in the description string + real(SiKi) :: Vslope(3) ! slope for "un-normalizing" data + real(SiKi) :: Voffset(3) ! offset for "un-normalizing" data + integer(IntKi) :: TmpErrStat ! temporary error status + character(ErrMsgLen) :: TmpErrMsg ! temporary error message + + type :: TurbSimHeaderType + sequence + integer(B2Ki) :: FileID + integer(B4Ki) :: NZGrids, NYGrids, NTGrids, NSteps + real(SiKi) :: dz, dy, dt + real(SiKi) :: mws, ref_height, grid_base_height + real(SiKi) :: VslopeX, VoffsetX + real(SiKi) :: VslopeY, VoffsetY + real(SiKi) :: VslopeZ, VoffsetZ + integer(B4Ki) :: DescLen + end type + + type(TurbSimHeaderType) :: header + + !---------------------------------------------------------------------------- + ! Initialize error variables + !---------------------------------------------------------------------------- + + ErrStat = ErrID_None + ErrMsg = "" + + !---------------------------------------------------------------------------- + ! Open the binary wind file and read header + !---------------------------------------------------------------------------- + + ! Get a unit number to use for the wind file + call GetNewUnit(WindFileUnit, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Open binary file + call OpenBInpFile(WindFileUnit, TRIM(InitInp%WindFileName), TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Read header from file + read (WindFileUnit, IOSTAT=TmpErrStat) header + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading header of the FF binary file "' & + //TRIM(InitInp%WindFileName)//'."', ErrStat, ErrMsg, RoutineName) + return + end if + + !---------------------------------------------------------------------------- + ! Populate parameter data from header + !---------------------------------------------------------------------------- + + G3D%WindFileFormat = header%FileID ! file format identifier + G3D%Periodic = header%FileID == 8 ! 7 is used for non-periodic wind files; 8 is periodic wind + G3D%InterpTower = .false. ! wind should not be interpolated at tower + G3D%AddMeanAfterInterp = .false. ! do not add mean wind speed after interpolation + + G3D%DTime = real(header%dt, ReKi) ! grid spacing in time (dt), m/s + G3D%Rate = 1.0_ReKi/G3D%DTime ! Data rate (1/DTime), Hertz + + G3D%NComp = 3 ! TurbSim file file contains 3 wind components + G3D%NYGrids = header%NYGrids ! the number of grid points laterally + G3D%NZGrids = header%NZGrids ! the number of grid points vertically + G3D%NTGrids = header%NTGrids ! the number of tower points + G3D%NSteps = header%NSteps ! the number of time steps + + G3D%InvDY = 1.0_ReKi/real(header%dy, ReKi) ! 1/dy + G3D%YHWid = 0.5_ReKi*(G3D%NYGrids - 1)/G3D%InvDY ! half the grid width (m) + + G3D%InvDZ = 1.0_ReKi/real(header%dz, ReKi) ! 1/dz + G3D%ZHWid = 0.5_ReKi*(G3D%NZGrids - 1)/G3D%InvDZ ! half the grid height (m) + + G3D%MeanWS = real(header%mws, ReKi) ! the mean wind speed at hub height (m/s) + G3D%InvMWS = 1.0_ReKi/G3D%MeanWS ! inverse of mean wind speed + + G3D%RefHeight = real(header%ref_height, ReKi) ! height of the hub (m) + G3D%GridBase = real(header%grid_base_height, ReKi) ! height of the bottom of the grid (m) + + if (G3D%Periodic) then + G3D%InitXPosition = 0 ! start at the hub + G3D%TotalTime = G3D%NSteps*G3D%DTime + else + G3D%InitXPosition = G3D%YHWid ! start half the grid width ahead of the turbine + G3D%TotalTime = (G3D%NSteps - 1)*G3D%DTime + end if + + G3D%WindProfileType = WindProfileType_None ! unused for turbsim + G3D%PLExp = 0 ! unused for turbsim + G3D%Z0 = 0 ! unused for turbsim + + !---------------------------------------------------------------------------- + ! Binary scaling factors from header + !---------------------------------------------------------------------------- + + ! Wind component slope for scaling, REAL(4) + Vslope = [header%VslopeX, header%VslopeY, header%VslopeZ] + + ! Wind component offset for scaling, REAL(4) + Voffset = [header%VoffsetX, header%VoffsetY, header%VoffsetZ] + + !---------------------------------------------------------------------------------------------- + ! Read the description string: "Generated by TurbSim (vx.xx, dd-mmm-yyyy) on dd-mmm-yyyy at hh:mm:ss." + !---------------------------------------------------------------------------------------------- + + ! The number of characters in the description string, max 200, INT(4) + NChar = header%DescLen + + ! Read description bytes, INT(1) + allocate (character(NChar)::DescStr) + read (WindFileUnit, IOSTAT=TmpErrStat) DescStr + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading description line in the FF binary file "' & + //TRIM(InitInp%WindFileName)//'."', ErrStat, ErrMsg, RoutineName) + return + end if + + !---------------------------------------------------------------------------- + ! Allocate arrays for the grid-field grid and tower if applicable + !---------------------------------------------------------------------------- + + ! Allocate storage for grid-field velocity data + call AllocAry(G3D%Vel, G3D%NComp, G3D%NYGrids, G3D%NZGrids, G3D%NSteps, & + 'grid-field velocity data', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Allocate storage for raw grid-field velocity for each time step + allocate (VelRaw(G3D%NComp, G3D%NYGrids, G3D%NZGrids), stat=TmpErrStat) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, "error allocating grid-field time step velocity data", & + ErrStat, ErrMsg, RoutineName) + end if + if (ErrStat >= AbortErrLev) return + + ! If tower grids specified + if (G3D%NTGrids > 0) then + + ! Allocate storage for tower velocity data + call AllocAry(G3D%VelTower, G3D%NComp, G3D%NTGrids, G3D%NSteps, & + 'tower wind velocity data.', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Allocate storage for raw tower data for each timestep + allocate (TwrRaw(G3D%NComp, G3D%NTGrids), stat=TmpErrStat) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, "error allocating tower time step velocity data", & + ErrStat, ErrMsg, RoutineName) + end if + if (ErrStat >= AbortErrLev) return + end if + + !---------------------------------------------------------------------------- + ! Read the 16-bit raw velocity data and scale it to 32-bit real + !---------------------------------------------------------------------------- + + ! This could take a while, so we'll write a message indicating what's going on: + call WrScr(NewLine//' Reading a ' & + //TRIM(Num2LStr(G3D%NYGrids))//'x' & + //TRIM(Num2LStr(G3D%NZGrids))// & + ' grid ('//TRIM(Num2LStr(G3D%YHWid*2))//' m wide, '// & + TRIM(Num2LStr(G3D%GridBase))//' m to '// & + TRIM(Num2LStr(G3D%GridBase + G3D%ZHWid*2))// & + ' m above ground) with a characteristic wind speed of '// & + TRIM(Num2LStr(G3D%MeanWS))//' m/s. '//TRIM(DescStr)) + + ! Loop through time steps + do IT = 1, G3D%NSteps + + ! Read grid-field raw wind data (normalized) comprised of 2-byte integers, INT(2) + ! Indices are Velocity components, Y coordinates, Z coordinates + read (WindFileUnit, IOSTAT=TmpErrStat) VelRaw + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading grid wind components in the FF binary file "'// & + TRIM(InitInp%WindFileName)//'."', ErrStat, ErrMsg, RoutineName) + return + end if + + ! Loop through wind components (U, V, W), calculate de-normalized velocity (m/s) + do IC = 1, 3 + G3D%Vel(IC, :, :, IT) = (real(VelRaw(IC, :, :), SiKi) - Voffset(IC))/VSlope(IC) + end do !IC + + ! Read tower raw wind data (normalized) comprised of 2-byte integers, INT(2) + ! Indices are Velocity components, Z coordinates + if (G3D%NTGrids > 0) then + read (WindFileUnit, IOSTAT=TmpErrStat) TwrRaw + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading tower wind components in the FF binary file "'// & + TRIM(InitInp%WindFileName)//'."', ErrStat, ErrMsg, RoutineName) + return + end if + + ! Loop through wind components (U, V, W), calculate de-normalized velocity (m/s) + do IC = 1, 3 + G3D%VelTower(IC, :, IT) = (real(TwrRaw(IC, :), SiKi) - Voffset(IC))/VSlope(IC) + end do + end if + end do + + !---------------------------------------------------------------------------- + ! Close the file + !---------------------------------------------------------------------------- + + close (WindFileUnit) + + if (G3D%Periodic) then + call WrScr(NewLine//' Processed '//TRIM(Num2LStr(G3D%NSteps))//' time steps of '// & + TRIM(Num2LStr(G3D%Rate))//'-Hz grid-field data (period of '// & + TRIM(Num2LStr(G3D%DTime*(G3D%NSteps)))//' seconds).') + else + call WrScr(NewLine//' Processed '//TRIM(Num2LStr(G3D%NSteps))//' time steps of '// & + TRIM(Num2LStr(G3D%Rate))//'-Hz grid-field data ('// & + TRIM(Num2LStr(G3D%DTime*(G3D%NSteps - 1)))//' seconds).') + end if + + !---------------------------------------------------------------------------- + ! Store wind file metadata + !---------------------------------------------------------------------------- + + call Grid3D_PopulateWindFileDat(G3D, InitInp%WindFileName, 3, G3D%NTGrids > 0, FileDat) + + !---------------------------------------------------------------------------- + ! Write the summary file + !---------------------------------------------------------------------------- + + if (SumFileUnit > 0) then + write (SumFileUnit, '(A)') + write (SumFileUnit, '(A)') 'TurbSim wind type. Read by InflowWind sub-module ' & + //TRIM(InflowWind_IO_Ver%Name)//' '//TRIM(InflowWind_IO_Ver%Ver) + write (SumFileUnit, '(A)') TRIM(TmpErrMsg) + write (SumFileUnit, '(5x,A)') 'FileName: '//TRIM(InitInp%WindFileName) + write (SumFileUnit, '(5x,A29,I3)') 'Binary file format id: ', G3D%WindFileFormat + write (SumFileUnit, '(5x,A29,G12.4)') 'Reference height (m): ', G3D%RefHeight + write (SumFileUnit, '(5x,A29,G12.4)') 'Timestep (s): ', G3D%DTime + write (SumFileUnit, '(5x,A29,I12)') 'Number of timesteps: ', G3D%NSteps + write (SumFileUnit, '(5x,A29,G12.4)') 'Mean windspeed (m/s): ', G3D%MeanWS + write (SumFileUnit, '(5x,A29,L1)') 'Windfile is periodic: ', G3D%Periodic + write (SumFileUnit, '(5x,A29,L1)') 'Windfile includes tower: ', G3D%NTGrids > 0 + + if (G3D%Periodic) then + write (SumFileUnit, '(5x,A)') 'Time range (s): [ '// & + TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(G3D%TotalTime))//' ]' + else ! Shift the time range to compensate for the shifting of the wind grid + write (SumFileUnit, '(5x,A)') 'Time range (s): [ '// & + TRIM(Num2LStr(-G3D%InitXPosition*G3D%InvMWS))//' : '// & + TRIM(Num2LStr(G3D%TotalTime - G3D%InitXPosition*G3D%InvMWS))//' ]' + end if + + write (SumFileUnit, '(5x,A)') 'Y range (m): [ '// & + TRIM(Num2LStr(-G3D%YHWid))//' : '//TRIM(Num2LStr(G3D%YHWid))//' ]' + + if (G3D%NTGrids > 0) then + write (SumFileUnit, '(5x,A)') 'Z range (m): [ '// & + TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(G3D%RefHeight + G3D%ZHWid))//' ]' + else + write (SumFileUnit, '(5x,A)') 'Z range (m): [ '// & + TRIM(Num2LStr(G3D%RefHeight - G3D%ZHWid))//' : '//TRIM(Num2LStr(G3D%RefHeight + G3D%ZHWid))//' ]' + end if + + if (G3D%BoxExceedAllowF) then + write (SumFileUnit, '(A)') ' Wind grid exceedence allowed: '// & + 'True -- Only for points requested by OLAF free vortex wake, or LidarSim module' + write (SumFileUnit, '(A)') ' '// & + ' Out of bounds values are linearly interpolated to mean at Z loction for' + write (SumFileUnit, '(A)') ' '// & + ' given timestep and X,T value. Values above grid are held to top of wind' + write (SumFileUnit, '(A)') ' '// & + ' grid value' + else + write (SumFileUnit, '(A)') ' Wind grid exceedence allowed: False' + end if + + ! Get IO status for unit + inquire (SumFileUnit, iostat=TmpErrStat) + if (TmpErrStat /= 0_IntKi) then + call SetErrStat(ErrID_Fatal, 'Error writing to summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + end if + +end subroutine + +subroutine IfW_HAWC_Init(InitInp, SumFileUnit, G3D, FileDat, ErrStat, ErrMsg) + + type(HAWC_InitInputType), intent(in) :: InitInp + integer(IntKi), intent(in) :: SumFileUnit + type(Grid3DFieldType), intent(out) :: G3D + type(WindFileDat), intent(out) :: FileDat + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "IfW_HAWC_Init" + integer(IntKi) :: WindFileUnit + real(SiKi), allocatable :: VelRaw(:, :) ! grid-field data for one timestep + integer :: IC ! Loop counter for the number of wind components + integer :: IX, IY, IZ ! Loop counters for the number of grid points in the X,Y,Z directions + real(DbKi) :: vMean ! average wind speeds over time at target position + real(ReKi) :: ScaleFactors(3) ! scale factors + integer(IntKi) :: TmpErrStat ! temporary error status + character(ErrMsgLen) :: TmpErrMsg + + !---------------------------------------------------------------------------- + ! Initialize variables + !---------------------------------------------------------------------------- + + ErrStat = ErrID_None + ErrMsg = "" + + G3D%WindFileFormat = 0 + G3D%Periodic = .true. + G3D%InterpTower = .true. + G3D%AddMeanAfterInterp = .true. + + G3D%DTime = InitInp%dx/InitInp%G3D%URef + G3D%Rate = 1.0_ReKi/G3D%DTime + + G3D%NComp = 3 + G3D%NYGrids = InitInp%ny + G3D%NZGrids = InitInp%nz + G3D%NTGrids = 0 + G3D%NSteps = InitInp%nx + + G3D%YHWid = 0.5_ReKi*InitInp%dy*(G3D%NYGrids - 1) + G3D%InvDY = 1.0/InitInp%dy + + G3D%ZHWid = 0.5_ReKi*InitInp%dz*(G3D%NZGrids - 1) + G3D%InvDZ = 1.0_ReKi/InitInp%dz + + G3D%MeanWS = InitInp%G3D%URef + G3D%InvMWS = 1.0_ReKi/G3D%MeanWS + + G3D%RefHeight = InitInp%G3D%RefHt + G3D%GridBase = G3D%RefHeight - G3D%ZHWid + + G3D%InitXPosition = InitInp%G3D%XOffset + G3D%TotalTime = G3D%NSteps*InitInp%dx/G3D%MeanWS + + G3D%WindProfileType = InitInp%G3D%WindProfileType + G3D%Z0 = InitInp%G3D%Z0 + G3D%PLExp = InitInp%G3D%PLExp + + ScaleFactors = 0.0_ReKi + + !---------------------------------------------------------------------------- + ! Validate initialization iput + !---------------------------------------------------------------------------- + + call Grid3D_ValidateInput(InitInp%G3D, 3, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + if (InitInp%nx < 1) then + call SetErrStat(ErrID_Fatal, 'Number of grid points in the X direction must be at least 1.', ErrStat, ErrMsg, RoutineName) + else if (InitInp%ny < 1) then + call SetErrStat(ErrID_Fatal, 'Number of grid points in the Y direction must be at least 1.', ErrStat, ErrMsg, RoutineName) + else if (InitInp%nz < 1) then + call SetErrStat(ErrID_Fatal, 'Number of grid points in the Z direction must be at least 1.', ErrStat, ErrMsg, RoutineName) + else if (InitInp%dx < 0.0_ReKi .or. EqualRealNos(InitInp%dx, 0.0_ReKi)) then + call SetErrStat(ErrID_Fatal, 'The grid spacing in the X direction must be larger than 0.', ErrStat, ErrMsg, RoutineName) + else if (InitInp%dy < 0.0_ReKi .or. EqualRealNos(InitInp%dy, 0.0_ReKi)) then + call SetErrStat(ErrID_Fatal, 'The grid spacing in the Y direction must be larger than 0.', ErrStat, ErrMsg, RoutineName) + else if (InitInp%dz < 0.0_ReKi .or. EqualRealNos(InitInp%dz, 0.0_ReKi)) then + call SetErrStat(ErrID_Fatal, 'The grid spacing in the Z direction must be larger than 0.', ErrStat, ErrMsg, RoutineName) + end if + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Allocate storage for grid-field velocity data + !---------------------------------------------------------------------------- + + ! Allocate storage for grid-field velocity data + call AllocAry(G3D%Vel, G3D%NComp, G3D%NYGrids, G3D%NZGrids, G3D%NSteps, & + 'grid-field velocity data', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Allocate storage for raw grid-field velocity for each time step + allocate (VelRaw(G3D%NZGrids, G3D%NYGrids), stat=TmpErrStat) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, "error allocating grid-field time step velocity data", & + ErrStat, ErrMsg, RoutineName) + end if + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Loop through files and read data + !---------------------------------------------------------------------------- + + ! Display message indicating that file is being read + call WrScr(NewLine//' Reading HAWC wind files with grids of '// & + TRIM(Num2LStr(G3D%NSteps))//' x '//TRIM(Num2LStr(G3D%NYGrids))//' x '//TRIM(Num2LStr(G3D%NZGrids))//' points'// & + ' ('//TRIM(Num2LStr(G3D%YHWid*2))//' m wide, '//TRIM(Num2LStr(G3D%GridBase))//' m to '// & + TRIM(Num2LStr(G3D%GridBase + G3D%ZHWid*2))// & + ' m above ground) with a characteristic wind speed of '//TRIM(Num2LStr(G3D%MeanWS))//' m/s. ') + + ! Get a unit number to use for the wind file + call GetNewUnit(WindFileUnit, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Loop through wind components (X, Y, Z) + do IC = 1, G3D%NComp + + ! Open wind file for this component + call OpenBInpFile(WindFileUnit, InitInp%WindFileName(IC), TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Loop through time steps + do IX = 1, G3D%NSteps + + ! Read file data for this timestep (Z(1:N),Y(N:1),C(1:3)) + read (WindFileUnit, IOSTAT=TmpErrStat) VelRaw + if (TmpErrStat /= 0) then + TmpErrMsg = ' Error reading binary data from "'//TRIM(InitInp%WindFileName(IC)) & + //'". I/O error '//TRIM(Num2LStr(TmpErrStat)) & + //' occurred at IX='//TRIM(Num2LStr(IX))//'.' + close (WindFileUnit) + call SetErrStat(ErrID_Fatal, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + return + end if + + ! Reorganize raw data into grid-field array (reverse Y indices) + do IZ = 1, G3D%NZGrids + G3D%Vel(IC, :, IZ, IX) = VelRaw(IZ, G3D%NYGrids:1:-1) + end do + end do + + ! Close file + close (WindFileUnit) + + end do + + !---------------------------------------------------------------------------- + ! Scale turbulence to requested intensity + !---------------------------------------------------------------------------- + + call Grid3D_ScaleTurbulence(InitInp%G3D, G3D%Vel, ScaleFactors, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Remove the U component mean wind speed + !---------------------------------------------------------------------------- + + ! If scaling method is not none, remove mean value of X component at each grid point + if (InitInp%G3D%ScaleMethod /= ScaleMethod_None) then + do iz = 1, G3D%NZGrids + do iy = 1, G3D%NYGrids + vMean = sum(G3D%Vel(1, iy, iz, :))/G3D%NSteps + G3D%Vel(1, iy, iz, :) = real(G3D%Vel(1, iy, iz, :) - vMean, SiKi) + end do + end do + end if + + !---------------------------------------------------------------------------- + ! Store wind file metadata + !---------------------------------------------------------------------------- + + call Grid3D_PopulateWindFileDat(G3D, InitInp%WindFileName(1), 5, .false., FileDat) + + !---------------------------------------------------------------------------- + ! Write the summary file + !---------------------------------------------------------------------------- + + if (SumFileUnit > 0) then + write (SumFileUnit, '(A)') + write (SumFileUnit, '(A)') 'HAWC wind type. Read by InflowWind sub-module InflowWind_IO' + + write (SumFileUnit, '(A34,G12.4)') ' Reference height (m): ', G3D%RefHeight + write (SumFileUnit, '(A34,G12.4)') ' Timestep (s): ', G3D%DTime + write (SumFileUnit, '(A34,I12)') ' Number of timesteps: ', G3D%NSteps + write (SumFileUnit, '(A34,G12.4)') ' Mean windspeed (m/s): ', G3D%MeanWS + write (SumFileUnit, '(A)') ' Time range (s): [ '// & + TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(G3D%TotalTime))//' ]' + write (SumFileUnit, '(A)') ' X range (m): [ '// & + TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(G3D%TotalTime*G3D%MeanWS))//' ]' + write (SumFileUnit, '(A)') ' Y range (m): [ '// & + TRIM(Num2LStr(-G3D%YHWid))//' : '//TRIM(Num2LStr(G3D%YHWid))//' ]' + write (SumFileUnit, '(A)') ' Z range (m): [ '// & + TRIM(Num2LStr(G3D%GridBase))//' : '//TRIM(Num2LStr(G3D%GridBase + G3D%ZHWid*2.0))//' ]' + + if (G3D%BoxExceedAllowF) then + write (SumFileUnit, '(A)') ' Wind grid exceedence allowed: '// & + 'True -- Only for points requested by OLAF free vortex wake, or LidarSim module' + write (SumFileUnit, '(A)') ' '// & + ' Out of bounds values are linearly interpolated to mean at Z loction for' + write (SumFileUnit, '(A)') ' '// & + ' given timestep and X,T value. Values above grid are held to top of wind' + write (SumFileUnit, '(A)') ' '// & + ' grid value' + else + write (SumFileUnit, '(A)') ' Wind grid exceedence allowed: False' + end if + + write (SumFileUnit, '(A)') 'Scaling factors used:' + write (SumFileUnit, '(A)') ' u v w ' + write (SumFileUnit, '(A)') '---------- ---------- ----------' + write (SumFileUnit, '(F10.3,2x,F10.3,2x,F10.3)') ScaleFactors + end if + +end subroutine + +!> User_Init initializes a user defined wind field. +subroutine IfW_User_Init(InitInp, SumFileUnit, UF, FileDat, ErrStat, ErrMsg) + + type(User_InitInputType), intent(in) :: InitInp + integer(IntKi), intent(in) :: SumFileUnit + type(UserFieldType), intent(out) :: UF + type(WindFileDat), intent(out) :: FileDat + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "IfW_User_Init" + + ErrStat = ErrID_None + ErrMsg = "" + + UF%RefHeight = 0.0_Reki + + if (SumFileUnit > 0) then + write (SumFileUnit, '(A)') UF%RefHeight + end if + +end subroutine + +!> IfW_Grid4D_Init initializes a wind field defined by a 4D grid. +subroutine IfW_Grid4D_Init(InitInp, G4D, ErrStat, ErrMsg) + + type(Grid4D_InitInputType), intent(in) :: InitInp + type(Grid4DFieldType), intent(out) :: G4D + integer(IntKi), intent(out) :: ErrStat + character(*), intent(out) :: ErrMsg + + character(*), parameter :: RoutineName = "IfW_Grid4D_Init" + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + + ErrStat = ErrID_None + ErrMsg = "" + + ! Initialize field from inputs + G4D%n = InitInp%n + G4D%delta = InitInp%delta + G4D%pZero = InitInp%pZero + G4D%TimeStart = 0.0_ReKi + G4D%RefHeight = InitInp%pZero(3) + (InitInp%n(3)/2) * InitInp%delta(3) + + ! uvw velocity components at x,y,z,t coordinates + call AllocAry(G4D%Vel, 3, G4D%n(1), G4D%n(2), G4D%n(3), G4D%n(4), & + 'External Grid Velocity', TmpErrStat, TmpErrMsg) + call SetErrStat(ErrStat, ErrMsg, TmpErrStat, TmpErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Initialize velocities to zero + G4D%Vel = 0.0_SiKi + +end subroutine + +subroutine IfW_Bladed_Init(InitInp, SumFileUnit, InitOut, G3D, FileDat, ErrStat, ErrMsg) + + type(Bladed_InitInputType), intent(in) :: InitInp !< Initialization data passed to the module + integer(IntKi), intent(in) :: SumFileUnit + type(Bladed_InitOutputType), intent(out) :: InitOut !< Initial output + type(Grid3DFieldType), intent(out) :: G3D !< Parameters + type(WindFileDat), intent(out) :: FileDat + integer(IntKi), intent(out) :: ErrStat !< determines if an error has been encountered + character(*), intent(out) :: ErrMsg !< Message about errors + + character(*), parameter :: RoutineName = "IfW_Bladed_Init" + real(ReKi) :: TI(3) ! turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI + type(Grid3D_InitInputType) :: G3D_InitInp ! initialization input for grid 3d field + real(ReKi) :: BinTI(3) ! turbulence intensities of the wind components as defined in the FF binary file, not necessarially the actual TI + real(ReKi) :: NatTI(3) ! turbulence intensities of the wind components as defined in the native FF summary file + real(ReKi) :: UBar + real(ReKi) :: ZCenter + real(ReKi) :: ScaleFactors(3) ! turbulence scaling factors + integer(IntKi) :: UnitWind ! Unit number for the InflowWind input file + integer(B2Ki) :: Dum_Int2 + integer(IntKi) :: I + logical :: CWise + logical :: LHR ! Left-hand rule for Bladed files (is the v component aligned along *negative* Y?) + logical :: Exists + character(1028) :: SumFile ! length is LEN(ParamData%WindFileName) + the 4-character extension. + character(1028) :: TwrFile ! length is LEN(ParamData%WindFileName) + the 4-character extension. + character(1024) :: BinFileName + character(1024) :: PriPath + character(ErrMsgLen) :: TmpErrMsg ! temporary error message + integer(IntKi) :: TmpErrStat ! temporary error status + + ErrMsg = '' + ErrStat = ErrID_None + + if (InitInp%NativeBladedFmt) then + + call Bladed_ReadNativeSummary(InitInp%WindFileName, G3D_InitInp%PLExp, G3D_InitInp%VLinShr, & + G3D_InitInp%HLinShr, G3D_InitInp%RefLength, NatTI, G3D%MeanWS, & + G3D%RefHeight, InitOut%PropagationDir, InitOut%VFlowAngle, & + BinFileName, G3D_InitInp%XOffset, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + if (pathIsRelative(BinFileName)) then + call GetPath(InitInp%WindFileName, PriPath) ! Binary file will be relative to the path where the primary input file is located. + BinFileName = TRIM(PriPath)//TRIM(BinFileName) + end if + + if (InitInp%FixedWindFileRootName) then ! .TRUE. when FAST.Farm uses multiple instances of InflowWind for ambient wind data + if (InitInp%TurbineID == 0) then ! .TRUE. for the FAST.Farm low-resolution domain + BinFileName = TRIM(BinFileName)//TRIM(PathSep)//'Low' + else ! FAST.Farm high-resolution domain(s) + BinFileName = TRIM(BinFileName)//TRIM(PathSep)//'HighT'//TRIM(Num2Lstr(InitInp%TurbineID)) + end if + end if + + ! default values for Bladed Format + CWise = .false. + ZCenter = G3D%RefHeight + G3D%Periodic = .true. + + G3D_InitInp%ScaleMethod = ScaleMethod_StdDev + G3D_InitInp%SigmaF = NatTI*G3D%MeanWS + G3D_InitInp%SF = G3D_InitInp%SigmaF + + ! it could also have logarithmic, but I'm going to leave that off for now + G3D_InitInp%RefHt = G3D%RefHeight + G3D_InitInp%URef = G3D%MeanWS + G3D_InitInp%WindProfileType = WindProfileType_PL ! it could also have logarithmic, but I'm going to leave that off for now + + TI = 100.0_ReKi + UBar = 0.0_ReKi + LHR = .true. + + else + InitOut%PropagationDir = 0.0_ReKi + InitOut%VFlowAngle = 0.0_ReKi + G3D%VLinShr = 0.0_ReKi + G3D%HLinShr = 0.0_ReKi + G3D%RefLength = 1.0_ReKi + + BinFileName = InitInp%WindFileName + end if + + ! Get a unit number to use + call GetNewUnit(UnitWind, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Open the binary file, read its "header" (first 2-byte integer) to + ! determine what format binary file it is, and close it. + !---------------------------------------------------------------------------- + + call OpenBInpFile(UnitWind, TRIM(BinFileName), TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Read the first binary integer from the file to get info on the type. + ! Cannot use library read routines since this is a 2-byte integer. + read (UnitWind, IOSTAT=TmpErrStat) Dum_Int2 + close (UnitWind) + + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading first binary integer from file "' & + //TRIM(BinFileName)//'."', ErrStat, ErrMsg, RoutineName) + return + end if + + !---------------------------------------------------------------------------- + ! Read the files to get the required FF data. + !---------------------------------------------------------------------------- + + ! Store the binary format information so the InflowWind code can use it. + ! Also changes to IntKi from INT(2) to compare in the SELECT below + G3D%WindFileFormat = Dum_Int2 + + select case (G3D%WindFileFormat) + + case (-1, -2, -3, -99) ! Bladed-style binary format + + if (.not. InitInp%NativeBladedFmt) then + + !---------------------------------------------------------------------- + ! Create full-field summary file name from binary file root name. + ! Also get tower file name. + !---------------------------------------------------------------------- + + call GetRoot(BinFileName, SumFile) + + TwrFile = TRIM(SumFile)//'.twr' + SumFile = TRIM(SumFile)//'.sum' + + !---------------------------------------------------------------------- + ! Read the summary file to get necessary scaling information + !---------------------------------------------------------------------- + + call Bladed_ReadTurbSimSummary(UnitWind, TRIM(SumFile), CWise, ZCenter, TI, & + UBar, G3D%RefHeight, G3D%Periodic, LHR, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + close (UnitWind) + return + end if + + end if + + !------------------------------------------------------------------------- + ! Open the binary file and read its header + !------------------------------------------------------------------------- + + call OpenBInpFile(UnitWind, TRIM(BinFileName), TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + close (UnitWind) + return + end if + + if (Dum_Int2 == -99) then ! Newer-style BLADED format + call Bladed_ReadHeader1(UnitWind, BinTI, G3D, InitInp%NativeBladedFmt, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + close (UnitWind) + return + end if + + ! If the TIs are also in the binary file (BinTI > 0), + ! use those numbers instead of ones from the summary file + + if (.not. InitInp%NativeBladedFmt) then + do I = 1, G3D%NComp + if (BinTI(I) > 0) TI(I) = BinTI(I) + end do + end if + + else + call Bladed_ReadHeader0(UnitWind, G3D, InitInp%NativeBladedFmt, TmpErrStat, TmpErrMsg) ! Older-style BLADED format + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + close (UnitWind) + return + end if + + end if + + !------------------------------------------------------------------------- + ! Let's see if the summary and binary FF wind files go together before continuing. + !------------------------------------------------------------------------- + + if (.not. InitInp%NativeBladedFmt) then + if (ABS(UBar - G3D%MeanWS) > 0.1) then + call SetErrStat(ErrID_Fatal, ' Error: Incompatible mean hub-height wind speeds in FF wind files. '// & + '(Check that the .sum and .wnd files were generated together.)', ErrStat, ErrMsg, RoutineName) + close (UnitWind) + return + end if + + end if + + !------------------------------------------------------------------------- + ! Calculate the height of the bottom of the grid + !------------------------------------------------------------------------- + + G3D%GridBase = ZCenter - G3D%ZHWid ! the location, in meters, of the bottom of the grid + if (G3D%GridBase < 0.0_ReKi) then + call SetErrStat(ErrID_Severe, 'WARNING: The bottom of the grid is located at a height of '// & + TRIM(Num2LStr(G3D%GridBase))//' meters, which is below the ground.'// & + ' Winds below the ground will be set to 0.', ErrStat, ErrMsg, RoutineName) + end if + + !------------------------------------------------------------------------- + ! Read the binary grids (converted tƒo m/s) and close the file + !------------------------------------------------------------------------- + + call Bladed_ReadGrids(UnitWind, InitInp%NativeBladedFmt, CWise, LHR, TI, G3D, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + + close (UnitWind) + if (InitInp%NativeBladedFmt) TI = NatTI*100.0_ReKi ! report these TI for the native Bladed format in percent + + if (ErrStat >= AbortErrLev) return + + !------------------------------------------------------------------------- + ! Read the tower points file + !------------------------------------------------------------------------- + + if (InitInp%TowerFileExist .and. .not. InitInp%NativeBladedFmt) then ! If we specified a tower file + inquire (FILE=TRIM(TwrFile), EXIST=Exists) + + ! Double check that the tower file exists and read it. If it was requested but doesn't exist, + ! throw fatal error and exit. + if (Exists) then + call Bladed_ReadTower(UnitWind, G3D, TwrFile, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + close (UnitWind) + return + end if + else + call SetErrStat(ErrID_Fatal, ' Tower file '//TRIM(TwrFile)//' specified for Bladed full-field '// & + 'wind files does not exist.', ErrStat, ErrMsg, RoutineName) + close (UnitWind) + return + end if + else + G3D%NTGrids = 0_IntKi + end if + + case DEFAULT + call SetErrStat(ErrID_Fatal, ' This is not a bladed-style binary wind file (binary format identifier: '// & + TRIM(Num2LStr(G3D%WindFileFormat))//'. This might be a TurbSim binary wind file.', & + ErrStat, ErrMsg, RoutineName) + return + + end select + + !---------------------------------------------------------------------------- + ! Post reading + !---------------------------------------------------------------------------- + + !---------------------------------------------------------------------------- + ! If the wind file has zero-mean and unit standard deviation (native Bladed format), scale the data: + !---------------------------------------------------------------------------- + + G3D%AddMeanAfterInterp = .false. + G3D%Z0 = G3D_InitInp%Z0 + G3D%PLExp = G3D_InitInp%PLExp + G3D%VLinShr = G3D_InitInp%VLinShr + G3D%HLinShr = G3D_InitInp%HLinShr + G3D%RefLength = G3D_InitInp%RefLength + + if (InitInp%NativeBladedFmt) then + + G3D%InterpTower = .true. + G3D%AddMeanAfterInterp = .true. + G3D%WindProfileType = G3D_InitInp%WindProfileType + + ! Validate scaling data if we've got native-Bladed format + call Grid3D_ValidateInput(G3D_InitInp, G3D%NComp, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! scale to requested TI (or use requested scale factors) + call Grid3D_ScaleTurbulence(G3D_InitInp, G3D%Vel(:, :, :, 1:G3D%NSteps), ScaleFactors, TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + else + G3D%InterpTower = .false. + G3D%WindProfileType = WindProfileType_None + end if + + if (G3D%Periodic) then + G3D%InitXPosition = 0 ! start at the hub + G3D%TotalTime = G3D%NSteps*G3D%DTime + else + G3D%InitXPosition = G3D%YHWid ! start half the grid width ahead of the turbine + G3D%TotalTime = (G3D%NSteps - 1)*G3D%DTime + end if + + if (InitInp%NativeBladedFmt) then + G3D%InitXPosition = G3D_InitInp%XOffset + end if + + !---------------------------------------------------------------------------- + ! Store wind file metadata + !---------------------------------------------------------------------------- + + call Grid3D_PopulateWindFileDat(G3D, InitInp%WindFileName, InitInp%WindType, G3D%NTGrids > 0, FileDat) + + FileDat%TI = TI + FileDat%TI_listed = .true. + + !---------------------------------------------------------------------------- + ! Write to the summary file + !---------------------------------------------------------------------------- + + if (SumFileUnit > 0) then + write (SumFileUnit, '(A)') + write (SumFileUnit, '(A)') 'Bladed-style wind type. Read by InflowWind sub-module '// & + TRIM(InflowWind_IO_Ver%Name)//' '//TRIM(InflowWind_IO_Ver%Ver) + write (SumFileUnit, '(A)') TRIM(TmpErrMsg) + write (SumFileUnit, '(A)') ' FileName: '//TRIM(InitInp%WindFileName) + write (SumFileUnit, '(A34,I3)') ' Binary file format id: ', G3D%WindFileFormat + write (SumFileUnit, '(A34,G12.4)') ' Reference height (m): ', G3D%RefHeight + write (SumFileUnit, '(A34,G12.4)') ' Timestep (s): ', G3D%DTime + write (SumFileUnit, '(A34,I12)') ' Number of timesteps: ', G3D%NSteps + write (SumFileUnit, '(A34,G12.4)') ' Mean windspeed (m/s): ', G3D%MeanWS + write (SumFileUnit, '(A)') ' Characteristic TI: [ '// & + TRIM(Num2LStr(TI(1)))//', '//TRIM(Num2LStr(TI(2)))//', '//TRIM(Num2LStr(TI(3)))//' ] ' + write (SumFileUnit, '(A34,L1)') ' Windfile is periodic: ', G3D%Periodic + write (SumFileUnit, '(A34,L1)') ' Windfile includes tower: ', G3D%NTGrids > 0 + + if (G3D%Periodic) then + write (SumFileUnit, '(A)') ' Time range (s): [ '// & + TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(G3D%TotalTime))//' ]' + else ! Shift the time range to compensate for the shifting of the wind grid + write (SumFileUnit, '(A)') ' Time range (s): [ '// & + TRIM(Num2LStr(-G3D%InitXPosition*G3D%InvMWS))//' : '// & + TRIM(Num2LStr(G3D%TotalTime - G3D%InitXPosition*G3D%InvMWS))//' ]' + end if + + write (SumFileUnit, '(A)') ' Y range (m): [ '// & + TRIM(Num2LStr(-G3D%YHWid))//' : '//TRIM(Num2LStr(G3D%YHWid))//' ]' + + if (G3D%NTGrids > 0) then + write (SumFileUnit, '(A)') ' Z range (m): [ '// & + TRIM(Num2LStr(0.0_ReKi))//' : '//TRIM(Num2LStr(G3D%RefHeight + G3D%ZHWid))//' ]' + else + write (SumFileUnit, '(A)') ' Z range (m): [ '// & + TRIM(Num2LStr(G3D%RefHeight - G3D%ZHWid))//' : '//TRIM(Num2LStr(G3D%RefHeight + G3D%ZHWid))//' ]' + end if + + if (G3D%BoxExceedAllowF) then + write (SumFileUnit, '(A)') ' Wind grid exceedence allowed: '// & + 'True -- Only for points requested by OLAF free vortex wake, or LidarSim module' + write (SumFileUnit, '(A)') ' '// & + ' Out of bounds values are linearly interpolated to mean at Z loction for' + write (SumFileUnit, '(A)') ' '// & + ' given timestep and X,T value. Values above grid are held to top of wind' + write (SumFileUnit, '(A)') ' '// & + ' grid value' + else + write (SumFileUnit, '(A)') ' Wind grid exceedence allowed: '// & + 'False' + end if + + ! We are assuming that if the last line was written ok, then all of them were. + if (TmpErrStat /= 0_IntKi) then + call SetErrStat(ErrID_Fatal, 'Error writing to summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + end if + +end subroutine IfW_Bladed_Init + +subroutine Bladed_ReadTurbSimSummary(UnitWind, FileName, CWise, ZCenter, TI, UBar, RefHt, Periodic, LHR, ErrStat, ErrMsg) + + integer(IntKi), intent(in) :: UnitWind !< unit number for the file to open + character(*), intent(in) :: FileName !< name of the summary file + logical, intent(out) :: CWise !< rotation (for reading the order of the binary data) + real(ReKi), intent(out) :: ZCenter !< the height at the center of the grid + real(ReKi), intent(out) :: TI(3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI + real(ReKi), intent(out) :: UBar !< mean (advection) wind speed + real(ReKi), intent(out) :: RefHt !< Reference height + logical, intent(out) :: Periodic !< rotation (for reading the order of the binary data) + logical, intent(out) :: LHR !< Left-hand rule for Bladed files (is the v component aligned along *negative* Y?) + integer(IntKi), intent(out) :: ErrStat !< returns 0 if no error encountered in the subroutine + character(*), intent(out) :: ErrMsg !< holds the error messages + + character(*), parameter :: RoutineName = "Bladed_ReadTurbSimSummary" + integer(IntKi) :: TmpErrStat ! temporary error status + character(ErrMsgLen) :: TmpErrMsg ! temporary error message + real(ReKi) :: ZGOffset ! The vertical offset of the turbine on rectangular grid (allows turbulence not centered on turbine hub) + integer, parameter :: NumStrings = 7 ! number of strings to be looking for in the file + integer(IntKi) :: FirstIndx ! The first character of a line where data is located + integer(IntKi) :: I ! A loop counter + integer(IntKi) :: LastIndx ! The last character of a line where data is located + integer(IntKi) :: LineCount ! Number of lines that have been read in the file + logical :: StrNeeded(NumStrings) ! if the string has been found + character(1024) :: LINE ! temporary storage for reading a line from the file + + !---------------------------------------------------------------------------------------------- + ! Initialize some variables + !---------------------------------------------------------------------------------------------- + + ErrStat = ErrID_None + ErrMsg = '' + + LineCount = 0 + StrNeeded(:) = .true. + ZGOffset = 0.0 + RefHt = 0.0 + Periodic = .false. + LHR = .false. + CWise = .false. ! default value, in case it is not in this file + + !---------------------------------------------------------------------------------------------- + ! Open summary file. + !---------------------------------------------------------------------------------------------- + + call OpenFInpFile(UnitWind, TRIM(FileName), TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------------------------- + ! Read the summary file. + !---------------------------------------------------------------------------------------------- + + ! Here are the strings we're looking for, in this order: + ! 1) 'CLOCKWISE' (optional) + ! 2) 'HUB HEIGHT' + ! 3) (unused; decided we didn't need to read data also stored in the binary file) + ! 4) 'UBAR' + ! 5) 'HEIGHT OFFSET' (optional) + ! 6) 'PERIODIC' (optional) + ! 7) 'BLADED LEFT-HAND RULE' (optional) + + do while ((ErrStat == ErrID_None) .and. StrNeeded(NumStrings)) + + LineCount = LineCount + 1 + + read (UnitWind, '(A)', IOSTAT=TmpErrStat) LINE + if (TmpErrStat /= 0) then + + ! the "HEIGHT OFFSET", "PERIODIC", and "BLADED LEFT-HAND RULE" parameters are not necessary. We'll assume they are zero/false if we didn't find it. + ! We will also assume "CLOCKWISE" is false if we didn't find it. + if (StrNeeded(2) .or. StrNeeded(4)) then + call SetErrStat(ErrID_Fatal, ' Error reading line #'//TRIM(Num2LStr(LineCount))//' of the summary file, "'// & + TRIM(FileName)//'". Could not find all of the required parameters.', ErrStat, ErrMsg, RoutineName) + return + else + exit + end if + + end if + + call Conv2UC(LINE) + + if (StrNeeded(2)) then ! if "CLOCKWISE" (StrNeeded(1)) is in the file, we would have already read it. If not, it's not in this file. + + if (StrNeeded(1)) then + + !------------------------------------------------------------------------------------------- + ! #1: Get the rotation direction, using the string "CLOCKWISE" + !------------------------------------------------------------------------------------------- + + if (INDEX(LINE, 'CLOCKWISE') > 0) then + + read (LINE, *, IOSTAT=TmpErrStat) CWise ! Look for True/False values + + if (TmpErrStat /= 0) then ! Look for Yes/No values instead + + LINE = ADJUSTL(LINE) ! Remove leading spaces from input line + + select case (LINE(1:1)) + case ('Y') + CWise = .true. + case ('N') + CWise = .false. + case DEFAULT + call SetErrStat(ErrID_Fatal, ' Error reading rotation direction (CLOCKWISE) from FF summary file.', ErrStat, ErrMsg, RoutineName) + return + end select + cycle + + end if ! TmpErrStat /= 0 + StrNeeded(1) = .false. + + end if ! INDEX for "CLOCKWISE" + + end if + + !------------------------------------------------------------------------------------------- + ! #2: Get the hub height, using the strings "HUB HEIGHT" or "ZHUB" + !------------------------------------------------------------------------------------------- + + if (INDEX(LINE, 'HUB HEIGHT') > 0 .or. INDEX(LINE, 'ZHUB') > 0) then + + read (LINE, *, IOSTAT=TmpErrStat) RefHt + + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading hub height from FF summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + StrNeeded(2) = .false. + + end if !INDEX for "HUB HEIGHT" or "ZHUB" + + ! ELSEIF ( StrNeeded(3) ) THEN + ! + ! !------------------------------------------------------------------------------------------- + ! ! #3: Get the grid width (& height, if available), using the strings "GRID WIDTH" or "RDIAM" + ! ! If GRID HEIGHT is specified, use it, too. -- THIS IS UNNECESSARY AS IT'S STORED IN THE BINARY FILE + ! !------------------------------------------------------------------------------------------- + + elseif (StrNeeded(4)) then + + !------------------------------------------------------------------------------------------- + ! #4: Get the mean wind speed "UBAR" and turbulence intensities from following lines for + ! scaling Bladed-style FF binary files + !------------------------------------------------------------------------------------------- + + if (INDEX(LINE, 'UBAR') > 0) then + + FirstIndx = INDEX(LINE, '=') + 1 ! Look for the equal siqn to find the number we're looking for + + read (LINE(FirstIndx:LEN(LINE)), *, IOSTAT=TmpErrStat) UBar + + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading UBar binary data normalizing parameter from FF summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + + do I = 1, 3 + + LineCount = LineCount + 1 + + read (UnitWind, '(A)', IOSTAT=TmpErrStat) LINE + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading line #'//TRIM(Num2LStr(LineCount))//' of the summary file, "'//TRIM(FileName)// & + '". Could not find all of the required parameters.', ErrStat, ErrMsg, RoutineName) + return + end if + + FirstIndx = INDEX(LINE, '=') + 1 ! Read the number between the = and % signs + LastIndx = INDEX(LINE, '%') - 1 + + if (LastIndx <= FirstIndx) LastIndx = LEN(LINE) ! If there's no % sign, read to the end of the line + + read (LINE(FirstIndx:LastIndx), *, IOSTAT=TmpErrStat) TI(I) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading TI('//TRIM(Num2LStr(I))// & + ') binary data normalizing parameter from FF summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + + end do !I + + StrNeeded(4) = .false. + + end if + + elseif (StrNeeded(5)) then + + !------------------------------------------------------------------------------------------- + ! #5: Get the grid "HEIGHT OFFSET", if it exists (in TurbSim). Otherwise, assume it's zero + ! ZGOffset = HH - GridBase - ParamData%FF%ZHWid + !------------------------------------------------------------------------------------------- + if (INDEX(LINE, 'HEIGHT OFFSET') > 0) then + + FirstIndx = INDEX(LINE, '=') + 1 + + read (LINE(FirstIndx:LEN(LINE)), *, IOSTAT=TmpErrStat) ZGOffset + + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading height offset from FF summary file.', ErrStat, ErrMsg, RoutineName) + return + end if + + StrNeeded(5) = .false. + + end if !INDEX for "HEIGHT OFFSET" + + else + + if (StrNeeded(6)) then + + !------------------------------------------------------------------------------------------- + ! #6: Get the grid "PERIODIC", if it exists (in TurbSim). Otherwise, assume it's + ! not a periodic file (would only show up if the HEIGHT OFFSET is in the file) + !------------------------------------------------------------------------------------------- + if (INDEX(LINE, 'PERIODIC') > 0) then + + Periodic = .true. + StrNeeded(6) = .false. + cycle + end if !INDEX for "PERIODIC" + end if + + if (StrNeeded(7)) then + + if (INDEX(LINE, 'BLADED LEFT-HAND RULE') > 0) then + LHR = .true. + StrNeeded(7) = .false. + end if ! INDEX for "BLADED LEFT-HAND RULE" + + end if + + end if ! StrNeeded + + end do !WHILE + + !---------------------------------------------------------------------------- + ! Close the summary file + !---------------------------------------------------------------------------- + + close (UnitWind) + + !---------------------------------------------------------------------------- + ! Calculate the height of the grid center + !---------------------------------------------------------------------------- + + ZCenter = RefHt - ZGOffset + +end subroutine Bladed_ReadTurbSimSummary + +subroutine Bladed_ReadNativeSummary(FileName, PLExp, VLinShr, HLinShr, RefLength, TI, & + UBar, RefHt, PropagationDir, VFlowAngle, BinFileName, & + XOffset, ErrStat, ErrMsg) + + character(*), intent(in) :: FileName !< name of the summary file + real(ReKi), intent(out) :: PLExp !< the power-law exponent for vertical wind shear + real(ReKi), intent(out) :: VLinShr !< the linear shape for vertical wind shear + real(ReKi), intent(out) :: HLinShr !< the linear shape for horizontal wind shear + real(ReKi), intent(out) :: RefLength !< Reference (rotor) diameter + real(ReKi), intent(out) :: TI(3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI + real(ReKi), intent(out) :: UBar !< mean (advection) wind speed + real(ReKi), intent(out) :: RefHt !< Reference height + real(ReKi), intent(out) :: PropagationDir !< propagation direction + real(ReKi), intent(out) :: VFlowAngle !< vertical flow angle + character(*), intent(out) :: BinFileName !< name of the binary file containing wind data + real(ReKi), intent(out) :: XOffset !< distance offset for start of wind files + integer(IntKi), intent(out) :: ErrStat !< returns 0 if no error encountered in the subroutine + character(*), intent(out) :: ErrMsg !< holds the error messages + + character(*), parameter :: RoutineName = "Bladed_ReadNativeSummary" + integer(IntKi) :: ErrStat2 ! temporary error status + character(ErrMsgLen) :: ErrMsg2 ! temporary error message + integer(IntKi), parameter :: UnEc = -1 ! echo file unit number (set to something else > 0 for debugging) + integer(IntKi) :: CurLine ! Current line to parse in FileInfo data structure + + type(FileInfoType) :: FileInfo ! The derived type for holding the file information. + + ErrStat = ErrID_None + ErrMsg = '' + + !---------------------------------------------------------------------------- + ! Open and read the summary file; store data in FileInfo structure. + !---------------------------------------------------------------------------- + + call ProcessComFile(FileName, FileInfo, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + end if + + !---------------------------------------------------------------------------- + ! Process the lines stored in FileInfo + !---------------------------------------------------------------------------- + + CurLine = 1 + + call ParseVar(FileInfo, CurLine, 'UBAR', UBar, ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call ParseVar(FileInfo, CurLine, 'REFHT', RefHt, ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call ParseVar(FileInfo, CurLine, 'TI', TI(1), ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call ParseVar(FileInfo, CurLine, 'TI_V', TI(2), ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call ParseVar(FileInfo, CurLine, 'TI_W', TI(3), ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call ParseVar(FileInfo, CurLine, 'WDIR', PropagationDir, ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + PropagationDir = R2D*PropagationDir + + call ParseVar(FileInfo, CurLine, 'FLINC', VFlowAngle, ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + VFlowAngle = R2D*VFlowAngle ! convert to degrees + + call ParseVar(FileInfo, CurLine, 'WINDF', BinFileName, ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + call ParseVar(FileInfo, CurLine, 'WSHEAR', PLExp, ErrStat2, ErrMsg2, UnEc) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + if (ErrStat >= AbortErrLev) then + call Cleanup() + return + end if + + call ParseVar(FileInfo, CurLine, 'VLINSHEAR', VLinShr, ErrStat2, ErrMsg2, UnEc) + if (ErrStat2 /= ErrID_None) then + VLinShr = 0.0_ReKi ! this will be the default if VLINSHEAR is not in the file + end if + + call ParseVar(FileInfo, CurLine, 'HLINSHEAR', HLinShr, ErrStat2, ErrMsg2, UnEc) + if (ErrStat2 /= ErrID_None) then + HLinShr = 0.0_ReKi ! this will be the default if HLINSHEAR is not in the file + end if + + call ParseVar(FileInfo, CurLine, 'REFLENGTH', RefLength, ErrStat2, ErrMsg2, UnEc) + if (ErrStat2 /= ErrID_None) then + RefLength = 0.0_ReKi ! this will be the default if RefLength is not in the file; it will cause an error if either of the linear shears are non-zero + end if + + call ParseVar(FileInfo, CurLine, 'XOffset', XOffset, ErrStat2, ErrMsg2, UnEc) + if (ErrStat2 /= ErrID_None) then + XOffset = 0.0_ReKi ! this will be the default if offset is not in the file + end if + + !---------------------------------------------------------------------------- + ! Clean FileInfo data structure (including pointers and allocatable arrays) + !---------------------------------------------------------------------------- + + call Cleanup() + +contains + + subroutine Cleanup() + call NWTC_Library_DestroyFileInfoType(FileInfo, ErrStat2, ErrMsg2) + end subroutine Cleanup + +end subroutine Bladed_ReadNativeSummary + +!> Reads the binary headers from the turbulence files of the old Bladed variety. Note that +!! because of the normalization, neither ParamData%FF%NZGrids or ParamData%FF%NYGrids are larger than 32 points. +!! 21-Sep-2009 - B. Jonkman, NREL/NWTC. +!! 16-Apr-2013 - A. Platt, NREL. Converted to modular framework. Modified for NWTC_Library 2.0 +subroutine Bladed_ReadHeader0(WindFileUnit, G3D, NativeBladedFmt, ErrStat, ErrMsg) + + integer(IntKi), intent(in) :: WindFileUnit !< unit number of already-opened wind file + type(Grid3DFieldType), intent(inout) :: G3D !< Parameters + logical, intent(in) :: NativeBladedFmt !< Whether this should ignore the advection speed in the binary file + integer(IntKi), intent(out) :: ErrStat !< error status + character(*), intent(out) :: ErrMsg !< error message + + type :: HeaderType + sequence + integer(B2Ki) :: NComp + integer(B2Ki) :: DeltaZ, DeltaY, DeltaX + integer(B2Ki) :: NStepsHalf, MWS10 + integer(B2Ki) :: zLu, yLu, xLu, dummy, rnd + integer(B2Ki) :: NZ1000, NY1000 + end type + + character(*), parameter :: RoutineName = "Bladed_ReadHeader0" + real(ReKi) :: FFXDelt + real(ReKi) :: FFYDelt + real(ReKi) :: FFZDelt + + type(HeaderType) :: header + integer(B2Ki) :: dummy(6) + integer(IntKi) :: iostat ! for checking the IOSTAT from a READ or Open statement + + ErrStat = ErrID_None + ErrMsg = '' + + !---------------------------------------------------------------------------- + ! Read the header (file has just been opened) + !---------------------------------------------------------------------------- + + ! Read header + read (WindFileUnit, IOSTAT=iostat) header + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading header 0 from binary FF file.', & + ErrStat, ErrMsg, RoutineName) + return + end if + + G3D%NComp = -1*header%NComp + + FFZDelt = 0.001*header%DeltaZ + G3D%InvDZ = 1.0/FFZDelt + + FFYDelt = 0.001*header%DeltaY + G3D%InvDY = 1.0/FFYDelt + + FFXDelt = 0.001*header%DeltaX + G3D%NSteps = 2*header%NStepsHalf + + if (.not. NativeBladedFmt) G3D%MeanWS = 0.1*header%MWS10 + G3D%InvMWS = 1.0/G3D%MeanWS + G3D%DTime = FFXDelt/G3D%MeanWS + G3D%Rate = 1.0/G3D%DTime + + G3D%NZGrids = header%NZ1000/1000 + G3D%ZHWid = 0.5*FFZDelt*(G3D%NZGrids - 1) + + G3D%NYGrids = header%NY1000/1000 + G3D%YHWid = 0.5*FFYDelt*(G3D%NYGrids - 1) + + if (G3D%NComp == 3) then + read (WindFileUnit, IOSTAT=iostat) dummy + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading header 0 from binary FF file.', & + ErrStat, ErrMsg, RoutineName) + return + end if + end if + +end subroutine Bladed_ReadHeader0 + +subroutine Bladed_ReadHeader1(UnitWind, TI, G3D, NativeBladedFmt, ErrStat, ErrMsg) + + integer(IntKi), intent(in) :: UnitWind !< unit number of already-opened wind file + real(ReKi), intent(out) :: TI(3) !< turbulence intensity contained in file header + type(Grid3DFieldType), intent(inout) :: G3D !< Parameters + logical, intent(in) :: NativeBladedFmt !< Whether this should ignore the advection speed in the binary file + integer(IntKi), intent(out) :: ErrStat !< error status + character(*), intent(out) :: ErrMsg !< error message + + type :: Turb4Type + sequence + integer(B4Ki) :: NComp + real(SiKi) :: Latitude, RoughLen, RefHeight, TurbInt(3) + end type + + type :: Turb78Type + sequence + integer(B4Ki) :: HeaderSize, NComp + end type + + type :: Turb7Type + sequence + real(SiKi) :: CoherenceDecay, CoherenceScale + end type + + type :: Turb8Type + sequence + real(SiKi) :: dummy1(6) + integer(B4Ki) :: dummy2(3) + real(SiKi) :: dummy3(2) + integer(B4Ki) :: dummy4(3) + real(SiKi) :: dummy5(2) + end type + + type :: Sub1Type + sequence + real(SiKi) :: DeltaZ, DeltaY, DeltaX + integer(B4Ki) :: NStepsHalf + real(SiKi) :: MeanWS, zLu, yLu, xLu + integer(B4Ki) :: dummy, rnd, NZ, NY + end type + + type :: Sub2Type + sequence + real(SiKi) :: zLv, yLv, xLv, zLw, yLw, xLw + end type + + character(*), parameter :: RoutineName = "Bladed_ReadHeader1" + + type(Turb4Type) :: Turb4 + type(Turb78Type) :: Turb78 + type(Sub1Type) :: Sub1 + type(Sub2Type) :: Sub2 + type(Turb7Type) :: Turb7 + type(Turb8Type) :: Turb8 + + real(ReKi) :: FFXDelt + real(ReKi) :: FFYDelt + real(ReKi) :: FFZDelt + integer(B2Ki) :: Dum_Int2 + integer(B2Ki) :: TurbType + integer(IntKi) :: iostat + + ErrStat = ErrID_None + ErrMsg = '' + + ! Initialize turbulence intensities + TI(:) = -1 !Initialize to -1 (not all models contain TI) + + !---------------------------------------------------------------------------- + ! File reading + !---------------------------------------------------------------------------- + + ! Read 2-byte integer. Can't use library routines for this. + read (UnitWind, IOSTAT=iostat) Dum_Int2 ! -99 (file ID) + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading integer from binary FF file.', ErrStat, ErrMsg, RoutineName) + return + end if + + ! Read 2-byte integer. Can't use library routines for this. + read (UnitWind, IOSTAT=iostat) TurbType ! turbulence type + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading turbulence type from binary FF file.', ErrStat, ErrMsg, RoutineName) + return + end if + + select case (TurbType) + + case (1, 2) ! 1-component Von Karman (1) or Kaimal (2) + G3D%NComp = 1 + + case (3, 5) ! 3-component Von Karman (3) or IEC-2 Kaimal (5) + G3D%NComp = 3 + + case (4) ! improved Von Karman + + read (UnitWind, IOSTAT=iostat) Turb4 + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading number of components from binary FF file.', & + ErrStat, ErrMsg, RoutineName) + return + end if + + G3D%NComp = Turb4%NComp + TI = Turb4%TurbInt + + case (7, 8) ! General Kaimal (7) or Mann model (8) + + read (UnitWind, IOSTAT=iostat) Turb78 + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading number of header records from binary FF file.', & + ErrStat, ErrMsg, RoutineName) + return + end if + + G3D%NComp = Turb78%NComp + + case DEFAULT + + call SetErrStat(ErrID_Warn, ' InflowWind does not recognize the full-field turbulence file type ='// & + TRIM(Num2LStr(int(TurbType)))//'.', ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + end select + + read (UnitWind, IOSTAT=iostat) Sub1 + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading header Sub1 from binary FF file.', ErrStat, ErrMsg, RoutineName) + return + end if + + FFZDelt = Sub1%DeltaZ + G3D%InvDZ = 1.0/FFZDelt + + FFYDelt = Sub1%DeltaY + G3D%InvDY = 1.0/FFYDelt + + FFXDelt = Sub1%DeltaX + + G3D%NSteps = 2*Sub1%NStepsHalf + + if (.not. NativeBladedFmt) G3D%MeanWS = Sub1%MeanWS + G3D%InvMWS = 1.0/G3D%MeanWS + G3D%DTime = FFXDelt/G3D%MeanWS + G3D%Rate = 1.0/G3D%DTime + + G3D%NZGrids = Sub1%NZ + G3D%ZHWid = 0.5*FFZDelt*(G3D%NZGrids - 1) ! half the vertical size of the grid + + G3D%NYGrids = Sub1%NY + G3D%YHWid = 0.5*FFYDelt*(G3D%NYGrids - 1) + + ! unused variables: zLv, yLv, xLv, zLw, yLw, xLw + if (G3D%NComp == 3) then + read (UnitWind, IOSTAT=iostat) Sub2 + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading 4-byte length scales from binary FF file.', ErrStat, ErrMsg, RoutineName) + return + end if + end if + + select case (TurbType) + case (7) ! General Kaimal model + + ! Unused variables: coherence decay constant and coherence scale parameter in m + read (UnitWind, IOSTAT=iostat) Turb7 + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading header for Turb7 from binary FF file.', & + ErrStat, ErrMsg, RoutineName) + return + end if + + case (8) ! Mann model + + ! Unused variables + read (UnitWind, IOSTAT=iostat) Turb8 + if (iostat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading header for Turb8 from binary FF file.', & + ErrStat, ErrMsg, RoutineName) + return + end if + + end select !TurbType + +end subroutine Bladed_ReadHeader1 + +subroutine Bladed_ReadGrids(UnitWind, NativeBladedFmt, CWise, LHR, TI, G3D, ErrStat, ErrMsg) + + integer(IntKi), intent(in) :: UnitWind !< unit number of already-opened wind file + logical, intent(in) :: NativeBladedFmt !< whether this data is in native Bladed format (scale to zero mean and unit standard deviation) + logical, intent(in) :: CWise !< clockwise flag (determines if y is increasing or decreasing in file) + logical, intent(in) :: LHR !< Left-hand rule for Bladed files (is the v component aligned along *negative* Y?) + real(ReKi), intent(in) :: TI(3) !< turbulence intensities of the wind components as defined in the FF file, not necessarially the actual TI + type(Grid3DFieldType), intent(inout) :: G3D !< Parameters + integer(IntKi), intent(out) :: ErrStat !< error status + character(*), intent(out) :: ErrMsg !< error message + + character(*), parameter :: RoutineName = "Bladed_ReadGrids" + integer(IntKi) :: TmpErrStat + character(ErrMsgLen) :: TmpErrMsg + real(ReKi) :: FF_Scale(3) !< used for "un-normalizing" the data + real(ReKi) :: FF_Offset(3) !< used for "un-normalizing" the data + integer(B2Ki), allocatable :: raw_ff(:, :, :) + integer(IntKi) :: CFirst, CLast, CStep + integer(IntKi) :: IC, IR, IT + + ErrMsg = "" + ErrStat = ErrID_None + + if (NativeBladedFmt) then + FF_Scale = 0.001_ReKi + FF_Offset = 0.0_ReKi + else + FF_Scale = 0.001_ReKi*G3D%MeanWS*TI/100.0_ReKi + FF_Offset = (/G3D%MeanWS, 0.0_ReKi, 0.0_ReKi/) ! used for "un-normalizing" the data + end if + + ! Bladed convention has positive V pointed along negative Y + if (LHR) then ! left-hand rule + FF_Scale(2) = -FF_Scale(2) + end if + + !---------------------------------------------------------------------------- + ! Generate an informative message + !---------------------------------------------------------------------------- + ! This could take a while, so we'll write a message to tell users what's going on: + + call WrScr(NewLine//' Reading a '//TRIM(Num2LStr(G3D%NYGrids))//'x'// & + TRIM(Num2LStr(G3D%NZGrids))// & + ' grid ('//TRIM(Num2LStr(G3D%YHWid*2))//' m wide, '// & + TRIM(Num2LStr(G3D%GridBase))//' m to '// & + TRIM(Num2LStr(G3D%GridBase + G3D%ZHWid*2))// & + ' m above ground) with a characteristic wind speed of '// & + TRIM(Num2LStr(G3D%MeanWS))//' m/s. ') + + !---------------------------------------------------------------------------- + ! Allocate space for the data array + !---------------------------------------------------------------------------- + + ! Add another step, just in case there is an odd number of steps. + G3D%NSteps = G3D%NSteps + 1 + + ! If velocity array is allocated and the size is wrong, deallocate + if (allocated(G3D%Vel)) then + if (SIZE(G3D%Vel, 1) /= G3D%NZGrids .or. & + SIZE(G3D%Vel, 2) /= G3D%NYGrids .or. & + SIZE(G3D%Vel, 3) /= G3D%NComp .or. & + SIZE(G3D%Vel, 3) /= G3D%NSteps) then + deallocate (G3D%Vel) + end if + end if + + ! If velocity array isn't allocated, allocate it with proper size + if (.not. ALLOCATED(G3D%Vel)) then + call AllocAry(G3D%Vel, G3D%NComp, G3D%NYGrids, G3D%NZGrids, G3D%NSteps, & + 'Full-field wind data array.', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + end if + + ! Allocate space to read all data for a given time slice + allocate (raw_ff(G3D%NComp, G3D%NYGrids, G3D%NZGrids), STAT=TmpErrStat) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, 'Error allocating memory for '// & + TRIM(Num2LStr(G3D%NComp*G3D%NYGrids*G3D%NZGrids))// & + ' B2Ki in the raw data array.', ErrStat, ErrMsg, RoutineName) + return + end if + + !---------------------------------------------------------------------------- + ! Initialize the data and set column indexing to account for + ! direction of turbine rotation (CWise) + !---------------------------------------------------------------------------- + + ! Initialize velocity components not in file to zero + do IC = G3D%NComp + 1, 3 + G3D%Vel(IC, :, :, :) = 0.0_SiKi + end do + + if (CWise) then + CFirst = G3D%NYGrids + CLast = 1 + CStep = -1 + else + CFirst = 1 + CLast = G3D%NYGrids + CStep = 1 + end if + + !---------------------------------------------------------------------------- + ! Loop through all the time steps, reading the data and converting to m/s + !---------------------------------------------------------------------------- + + ! Loop through time steps + do IT = 1, G3D%NSteps + + ! Read raw data (NComp,NYGrids,NZGrids) + read (UnitWind, IOStat=TmpErrStat) raw_ff + + ! If data was read successfully, transfer into velocity array, continue + if (TmpErrStat == 0) then + do IC = 1, G3D%NComp + G3D%Vel(IC, :, :, IT) = real(FF_Offset(IC) + FF_Scale(IC)*raw_ff(IC, CFirst:CLast:CStep, :), SiKi) + end do + cycle + end if + + ! If time iterator equals number of steps, then the number of steps were even + ! so fix the number of steps and exit loop + if (IT == G3D%NSteps) then + G3D%NSteps = G3D%NSteps - 1 + ErrStat = ErrID_None + exit + end if + + ! Otherwise, an error occurred reading the file, return + call SetErrStat(ErrID_Fatal, ' Error reading binary data file. '// & + 'ic = '//TRIM(Num2LStr(ic))// & + ', ir = '//TRIM(Num2LStr(ir))// & + ', it = '//TRIM(Num2LStr(it))// & + ', nsteps = '//TRIM(Num2LStr(G3D%NSteps)), ErrStat, ErrMsg, RoutineName) + return + end do + + if (G3D%Periodic) then + call WrScr(NewLine//' Processed '//TRIM(Num2LStr(G3D%NSteps))//' time steps of '// & + TRIM(Num2LStr(G3D%Rate))//'-Hz full-field data (period of '// & + TRIM(Num2LStr(G3D%DTime*G3D%NSteps))//' seconds).') + + else + call WrScr(NewLine//' Processed '//TRIM(Num2LStr(G3D%NSteps))//' time steps of '// & + TRIM(Num2LStr(G3D%Rate))//'-Hz full-field data ('// & + TRIM(Num2LStr(G3D%DTime*(G3D%NSteps - 1)))//' seconds).') + end if + +end subroutine Bladed_ReadGrids + +subroutine Bladed_ReadTower(UnitWind, G3D, TwrFileName, ErrStat, ErrMsg) + + integer(IntKi) :: UnitWind !< unit number of wind file to be opened + type(Grid3DFieldType), intent(inout) :: G3D !< Parameters + character(*), intent(in) :: TwrFileName + integer(IntKi), intent(out) :: ErrStat !< error status return value (0=no error; non-zero is error) + character(*), intent(out) :: ErrMsg !< a message for errors that occur + + type :: HeaderType + sequence + real(SiKi) :: DZ, DX, Zmax + integer(B4Ki) :: NumOutSteps, NumZ + real(SiKi) :: UHub, TI(3) + end type + + character(*), parameter :: RoutineName = "Bladed_ReadTower" + integer(IntKi) :: TmpErrStat ! IOSTAT value. + character(ErrMsgLen) :: TmpErrMsg + real(ReKi), parameter :: FF_Offset(3) = (/1.0, 0.0, 0.0/) ! used for "un-normalizing" the data + real(ReKi), parameter :: TOL = 1E-4 ! tolerence for wind file comparisons + integer(IntKi) :: IC, IT ! loop counters + real(SiKi) :: TI(3) ! scaling values for "un-normalizing the data" [approx. turbulence intensities of the wind components] + integer(B2Ki), allocatable :: raw_twr(:, :) ! holds tower velocity for one timestep + type(HeaderType) :: header + + ErrMsg = '' + ErrStat = ErrID_None + + !---------------------------------------------------------------------------- + ! Initialization + !---------------------------------------------------------------------------- + + ! If number of wind components is not three, return with error + if (G3D%NComp /= 3) then + call SetErrStat(ErrID_Fatal, ' Error: Tower binary files require 3 wind components.', & + ErrStat, ErrMsg, RoutineName) + return + end if + + ! Initialize the number of tower grids to zero + G3D%NTGrids = 0 + + !---------------------------------------------------------------------------- + ! Open the file + !---------------------------------------------------------------------------- + + call OpenBInpFile(UnitWind, TRIM(TwrFileName), TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + !---------------------------------------------------------------------------- + ! Read the header information and check that it's compatible with the + ! FF Bladed-style binary parameters already read. + !---------------------------------------------------------------------------- + + read (UnitWind, IOSTAT=TmpErrStat) header + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, & + ' Error reading header of the binary tower file "' & + //TRIM(TwrFileName)//'."', ErrStat, ErrMsg, RoutineName) + return + end if + + ! If delta Z in file doesn't match tower file + if (ABS(header%DZ*G3D%InvDZ - 1) > TOL) then + call SetErrStat(ErrID_Fatal, ' Z resolution in the FF binary file does not match the tower file.', & + ErrStat, ErrMsg, RoutineName) + end if + + ! If X resolution doesn't match the tower file + if (ABS(header%DX*G3D%InvMWS/G3D%DTime - 1) > TOL) then + call SetErrStat(ErrID_Fatal, ' Time resolution in the FF binary file does not match the tower file.', & + ErrStat, ErrMsg, RoutineName) + end if + + ! If the height doesn't match the tower file + if (ABS(header%Zmax/G3D%GridBase - 1) > TOL) then + call SetErrStat(ErrID_Fatal, ' Height in the FF binary file does not match the tower file "'//TRIM(TwrFileName)//'."', & + ErrStat, ErrMsg, RoutineName) + end if + + ! Number of time steps doesn't match the tower file + if (header%NumOutSteps /= G3D%NSteps) then + call SetErrStat(ErrID_Fatal, ' Number of time steps in the FF binary file does not match the tower file.', & + ErrStat, ErrMsg, RoutineName) + end if + + ! If mean wind speed doesn't match tower file + if (ABS(header%UHub*G3D%InvMWS - 1) > TOL) then + call SetErrStat(ErrID_Fatal, ' Mean wind speed in the FF binary file does not match the tower file.', & + ErrStat, ErrMsg, RoutineName) + end if + + ! If any of the previous checks failed, or the number of tower grids is zero, + ! close the wind file and return + if (ErrStat >= AbortErrLev .or. header%NumZ == 0) then + close (UnitWind) + return + end if + + ! Set number of tower grids from header + G3D%NTGrids = header%NumZ + + ! Set turbulence intensity from header + TI = header%TI + + !---------------------------------------------------------------------------- + ! Allocate arrays for the tower points + !---------------------------------------------------------------------------- + + ! If tower array is allocated and the wrong size, deallocate + if (allocated(G3D%VelTower)) then + if (size(G3D%VelTower, 1) /= G3D%NComp .or. & + size(G3D%VelTower, 1) /= G3D%NTGrids .or. & + size(G3D%VelTower, 1) /= G3D%NSteps) then + deallocate (G3D%VelTower) + end if + end if + + ! If the tower array isn't allocated, allocate it + if (.not. ALLOCATED(G3D%VelTower)) then + call AllocAry(G3D%VelTower, G3D%NComp, G3D%NTGrids, G3D%NSteps, & + 'Tower wind data array.', TmpErrStat, TmpErrMsg) + call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + end if + + ! Allocate space to read all data for a given time slice + allocate (raw_twr(G3D%NComp, G3D%NTGrids), STAT=TmpErrStat) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, 'Error allocating memory for '// & + TRIM(Num2LStr(G3D%NComp*G3D%NYGrids*G3D%NZGrids))// & + ' B2Ki in the raw data array.', ErrStat, ErrMsg, RoutineName) + return + end if + + !---------------------------------------------------------------------------- + ! Read the 16-bit time-series data and scale it to 32-bit reals + !---------------------------------------------------------------------------- + + ! Loop through time. + do IT = 1, G3D%NSteps + + ! Read wind compnents for this time slice. Can't use library read routines for this. + read (UnitWind, IOSTAT=TmpErrStat) raw_twr ! normalized wind-component, INT(2) + if (TmpErrStat /= 0) then + call SetErrStat(ErrID_Fatal, ' Error reading binary tower data file. it = '//TRIM(Num2LStr(it))// & + ', nsteps = '//TRIM(Num2LStr(G3D%NSteps)), ErrStat, ErrMsg, RoutineName) + G3D%NTGrids = 0 + return + end if + + ! Loop through wind components and populate array after scaling to m/s + do IC = 1, G3D%NComp + G3D%VelTower(IC, :, IT) = real(G3D%MeanWS*(FF_Offset(IC) + 0.00001*TI(IC)*raw_twr(IC, :)), SiKi) + end do + end do + + !---------------------------------------------------------------------------- + ! Close the file + !---------------------------------------------------------------------------- + + close (UnitWind) + + call WrScr(NewLine//' Processed '//TRIM(Num2LStr(G3D%NSteps))//' time steps of '// & + TRIM(Num2LStr(G3D%NTGrids))//'x1 tower data grids.') + +end subroutine Bladed_ReadTower + +subroutine Grid3D_PopulateWindFileDat(Grid3DField, FileName, WindType, HasTower, FileDat) + + type(Grid3DFieldType), intent(in) :: Grid3DField + character(*), intent(in) :: FileName + integer(IntKi), intent(in) :: WindType + logical, intent(in) :: HasTower + type(WindFileDat), intent(out) :: FileDat + + FileDat%FileName = FileName + FileDat%WindType = WindType + FileDat%RefHt = Grid3DField%RefHeight + FileDat%RefHt_Set = .true. + FileDat%DT = Grid3DField%DTime + FileDat%NumTSteps = Grid3DField%NSteps + FileDat%ConstantDT = .true. + + if (Grid3DField%Periodic) then + FileDat%TRange = [0.0_ReKi, Grid3DField%TotalTime] + FileDat%TRange_Limited = .false. + else + ! Shift the time range to compensate for the shifting of the wind grid + FileDat%TRange = [0.0_ReKi, Grid3DField%TotalTime] - Grid3DField%InitXPosition*Grid3DField%InvMWS + FileDat%TRange_Limited = .true. + end if + + FileDat%YRange = [-Grid3DField%YHWid, Grid3DField%YHWid] + FileDat%YRange_Limited = .true. ! Hard boundaries enforced in y-direction + + ! If has tower data + if (HasTower) then + FileDat%ZRange = [0.0_Reki, Grid3DField%RefHeight + Grid3DField%ZHWid] + else + FileDat%ZRange = [Grid3DField%GridBase, Grid3DField%GridBase + Grid3DField%ZHWid*2.0] + end if + + FileDat%ZRange_Limited = .true. + FileDat%BinaryFormat = Grid3DField%WindFileFormat + FileDat%IsBinary = .true. + FileDat%MWS = Grid3DField%MeanWS + + FileDat%TI = 0.0_ReKi + FileDat%TI_listed = .false. + +end subroutine + +subroutine Grid3D_AddMeanVelocity(InitInp, G3D) + + type(Grid3D_InitInputType), intent(in) :: InitInp !< Initialization input data passed to the module + type(Grid3DFieldType), intent(inout) :: G3D !< Initialization input data passed to the module + + real(ReKi) :: Z ! height + real(ReKi) :: Y ! distance from centre in horizontal direction + real(ReKi) :: U ! mean wind speed + integer(IntKi) :: iz, iy ! loop counter + integer(IntKi) :: centre_y ! index of centre in y direction + integer(IntKi) :: first_positive_iz ! index of first height that is above ground + + ! Loop through grid elevations + first_positive_iz = 1 + do iz = 1, G3D%NZGrids + + ! calculate height + Z = G3D%GridBase + (iz - 1)/G3D%InvDZ + if (Z <= 0.0_ReKi) then + first_positive_iz = iz + 1 + cycle + end if + + ! Calculate wind speed to add based on profile + select case (G3D%WindProfileType) + + case (WindProfileType_PL) + U = G3D%MeanWS*(Z/G3D%RefHeight)**G3D%PLExp ! [IEC 61400-1 6.3.1.2 (10)] + + case (WindProfileType_Log) + if (.not. EqualRealNos(G3D%RefHeight, G3D%Z0) .and. Z > 0.0_ReKi) then + U = G3D%MeanWS*(LOG(Z/G3D%Z0))/(LOG(G3D%RefHeight/G3D%Z0)) + else + U = 0.0_ReKi + end if + + case (WindProfileType_Constant) + U = G3D%MeanWS + + case DEFAULT + U = 0.0_ReKi + + end select + + ! Add vertical linear shear, if nonzero + if (InitInp%VLinShr /= 0.0_ReKi) then + U = U + G3D%MeanWS*InitInp%VLinShr*(Z - G3D%RefHeight)/G3D%RefLength + end if + + ! Add velocity + G3D%Vel(1, :, iz, :) = real(G3D%Vel(1, :, iz, :) + U, SiKi) + + end do + + ! Add horizontal linear shear, if nonzero (only to the points above the ground) + if (InitInp%HLinShr /= 0.0_ReKi .and. first_positive_iz <= G3D%NZGrids) then + + ! find the center point of the grid (if we don't have an odd number of grid points, we'll pick the point closest to the center) + centre_y = (G3D%NYGrids + 1)/2 ! integer division + + ! Loop through grid Y coordinates + do iy = 1, G3D%NYGrids + Y = (iy - centre_y)/G3D%InvDY + U = G3D%MeanWS*InitInp%HLinShr*Y/G3D%RefLength + G3D%Vel(1, iy, first_positive_iz:, :) = real(G3D%Vel(1, iy, first_positive_iz:, :) + U, SiKi) + end do + end if + +end subroutine Grid3D_AddMeanVelocity + +subroutine Grid3D_ScaleTurbulence(InitInp, Vel, ScaleFactors, ErrStat, ErrMsg) + + type(Grid3D_InitInputType), intent(in) :: InitInp !< Initialization input data passed to the module + real(SiKi), intent(INOUT) :: Vel(:, :, :, :) !< full-field wind inflow data + real(ReKi), intent(out) :: ScaleFactors(3) !< scaling factors that were used + integer(IntKi), intent(out) :: ErrStat !< determines if an error has been encountered + character(*), intent(out) :: ErrMsg !< Message about errors + + character(*), parameter :: RoutineName = 'Grid3D_ScaleTurbulence' + real(DbKi) :: vMean(3) ! average wind speeds over time at target position + real(DbKi) :: vSum(3) ! sum over time of wind speeds at target position + real(DbKi) :: vSum2(3) ! sum of wind speeds squared + real(ReKi) :: ActualSigma(3) ! computed standard deviation + + integer :: ic ! Loop counter for wind component + integer :: iy ! Loop counter for y + integer :: iz ! Loop counter for z + + integer :: nc ! number of FF wind components + integer :: nt ! size of x (or t) dimension of turbulence box + integer :: ny ! size of y dimension of turbulence box + integer :: nz ! size of z dimension of turbulence box + + ErrStat = ErrID_None + ErrMsg = "" + + nc = size(Vel, 1) + ny = size(Vel, 2) + nz = size(Vel, 3) + nt = size(Vel, 4) + + ! If scaling method is none, set factors to 1 and return (no scaling) + if (InitInp%ScaleMethod == ScaleMethod_None) then + ScaleFactors = 1.0_ReKi + return + end if + + !---------------------------------------------------------------------------- + ! Determine the scaling factors: + !---------------------------------------------------------------------------- + + ! Use the scaling factors specified in the input file + if (InitInp%ScaleMethod == ScaleMethod_Direct) then + ScaleFactors = InitInp%sf + + else ! compute the scaling factors to get requested sigma: + + ! find the center point of the grid (if we don't have an odd number of grid points, we'll pick the point closest to the center) + iz = (nz + 1)/2 ! integer division + iy = (ny + 1)/2 ! integer division + + ! compute the actual sigma at the point specified by (iy,iz). (This sigma should be close to 1.) + vSum = sum(Vel(:, iy, iz, :), dim=2) + vSum2 = sum(Vel(:, iy, iz, :)**2, dim=2) + vMean = vSum/nt + ActualSigma = real(SQRT(ABS((vSum2/nt) - vMean**2)), ReKi) + + ! check that the ActualSigma isn't 0 + ! InitOut%sf = InitInp%SigmaF / ActualSigma ! factor = Target / actual + do ic = 1, nc + if (EqualRealNos(ActualSigma(ic), 0.0_ReKi)) then + ScaleFactors(ic) = 0.0_ReKi + if (.not. EqualRealNos(InitInp%SigmaF(ic), 0.0_ReKi)) then + call SetErrStat(ErrID_Fatal, "Computed standard deviation is zero; cannot scale to achieve target non-zero standard deviation.", & + ErrStat, ErrMsg, RoutineName) + end if + else + ScaleFactors(ic) = InitInp%SigmaF(ic)/ActualSigma(ic) + end if + end do + + end if + + !---------------------------------------------------------------------------- + ! scale the data using our scaling factors: + !---------------------------------------------------------------------------- + + do ic = 1, nc + Vel(ic, :, :, :) = real(ScaleFactors(ic)*Vel(ic, :, :, :), SiKi) + end do + +end subroutine Grid3D_ScaleTurbulence + +subroutine Grid3D_ValidateInput(InitInp, NComp, ErrStat, ErrMsg) + + type(Grid3D_InitInputType), intent(in) :: InitInp !< Initialization input data passed to the module + integer(IntKi), intent(in) :: NComp !< number of full-field wind components (normally 3) + + character(*), parameter :: RoutineName = 'Grid3D_ValidateInput' + integer(IntKi), intent(out) :: ErrStat !< determines if an error has been encountered + character(*), intent(out) :: ErrMsg !< Message about errors + + ErrStat = ErrID_None + ErrMsg = "" + + if (InitInp%RefHt < 0.0_ReKi .or. EqualRealNos(InitInp%RefHt, 0.0_ReKi)) call SetErrStat(ErrID_Fatal, 'The grid reference height must be larger than 0.', ErrStat, ErrMsg, RoutineName) + + if (InitInp%ScaleMethod == ScaleMethod_Direct) then + if (any(InitInp%sf < 0.0_ReKi)) call SetErrStat(ErrID_Fatal, 'Turbulence scaling factors must not be negative.', ErrStat, ErrMsg, RoutineName) + elseif (InitInp%ScaleMethod == ScaleMethod_StdDev) then + if (any(InitInp%sigmaf < 0.0_ReKi)) call SetErrStat(ErrID_Fatal, 'Turbulence standard deviations must not be negative.', ErrStat, ErrMsg, RoutineName) + elseif (InitInp%ScaleMethod /= ScaleMethod_None) then + call SetErrStat(ErrID_Fatal, 'Turbulence scaling method must be 0 (none), 1 (direct scaling factors), or 2 (target standard deviation).', ErrStat, ErrMsg, RoutineName) + end if + + if (InitInp%WindProfileType == WindProfileType_Log) then + if (InitInp%z0 < 0.0_ReKi .or. EqualRealNos(InitInp%z0, 0.0_ReKi)) & + call SetErrStat(ErrID_Fatal, 'The surface roughness length, Z0, must be greater than zero', ErrStat, ErrMsg, RoutineName) + elseif (InitInp%WindProfileType < WindProfileType_Constant .or. InitInp%WindProfileType > WindProfileType_PL) then + call SetErrStat(ErrID_Fatal, 'The WindProfile type must be 0 (constant), 1 (logarithmic) or 2 (power law).', ErrStat, ErrMsg, RoutineName) + end if + + if (InitInp%URef < 0.0_ReKi) call SetErrStat(ErrID_Fatal, 'The reference wind speed must not be negative.', ErrStat, ErrMsg, RoutineName) + + if (EqualRealNos(InitInp%RefLength, 0.0_ReKi) .or. InitInp%RefLength < 0.0_ReKi) then + if (InitInp%VLinShr /= 0.0_ReKi .or. InitInp%HLinShr /= 0.0_ReKi) then + call SetErrStat(ErrID_Fatal, 'The reference length must be a positive number when vertical or horizontal linear shear is used.', ErrStat, ErrMsg, RoutineName) + end if + end if + +end subroutine + +subroutine Grid3D_WriteBladed(G3D, FileRootName, unit, ErrStat, ErrMsg) + + type(Grid3DFieldType), intent(in) :: G3D !< Parameters + character(*), intent(in) :: FileRootName !< Name of the file to write the output in + integer(IntKi), intent(in) :: Unit !< Indicates whether an error occurred (see NWTC_Library) + integer(IntKi), intent(out) :: ErrStat !< Indicates whether an error occurred (see NWTC_Library) + character(*), intent(out) :: ErrMsg !< Error message associated with the ErrStat + + character(*), parameter :: RoutineName = 'Grid3D_WriteBladed' + real(SiKi), parameter :: Tolerance = 0.0001 ! The largest difference between two numbers that are assumed to be equal + integer(IntKi) :: ic, it, iy, iz + real(SiKi), allocatable :: MeanVal(:, :) + real(SiKi), allocatable :: SigmaGrid(:, :) + real(SiKi) :: TI(3) !< array containing turbulence intensity (for scaling factors) + real(SiKi) :: Sigma(3) !< array containing standard deviations (for scaling factors) + real(SiKi) :: Scl(3) !< array containing scaling factors + real(SiKi) :: Off(3) !< array containing offsets + real(SiKi) :: Tmp + real(ReKi) :: MeanWS_nonZero !< advection speed (mean wind speed at hub) + real(ReKi) :: delta(3) + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + delta = [G3D%MeanWS*G3D%DTime, 1.0_ReKi/G3D%InvDY, 1.0_ReKi/G3D%InvDZ] + + call AllocAry(MeanVal, G3D%NYGrids, G3D%NZGrids, "MeanVal", ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + call AllocAry(SigmaGrid, G3D%NYGrids, G3D%NZGrids, "SigmaGrid", ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Loop through components + do ic = 3, 1, -1 + + ! mean values: + MeanVal = sum(G3D%Vel(ic, :, :, :), dim=3)/G3D%NSteps + + ! standard deviations (with 1/N scaling factor): + SigmaGrid = sum(G3D%Vel(ic, :, :, :)**2, dim=3)/G3D%NSteps + SigmaGrid = sqrt(max(SigmaGrid - MeanVal**2, 0.0_SiKi)) + + ! now get the average standard deviation for each component: + Sigma(ic) = sum(SigmaGrid)/size(SigmaGrid) ! get the average sigma over the grid + Sigma(ic) = max(100.0_SiKi*Tolerance, Sigma(ic)) ! make sure this scaling isn't too small + + end do + + ! We need to take into account the shear across the grid in the sigma calculations for scaling the data, + ! and ensure that 32.767*sigma_u >= |V-UHub| so that we don't get values out of the range of our scaling values + ! in this BLADED-style binary output. Tmp is |V-UHub| + ! Get the range of wind speed values for scaling in BLADED-format .wnd files + Tmp = real(max(abs(maxval(G3D%Vel(:, :, 1, :)) - G3D%MeanWS), abs(minval(G3D%Vel(1, :, :, :)) - G3D%MeanWS)), SiKi) + Sigma(1) = max(Sigma(1), 0.05_SiKi*Tmp) + do ic = 2, 3 + ! put the abs() after the maxval() and minval() to avoid stack-overflow issues with large wind files + Sigma(ic) = max(Sigma(ic), 0.05_SiKi*abs(maxVAL(G3D%Vel(ic, :, :, :))), 0.05_SiKi*abs(minval(G3D%Vel(ic, :, :, :)))) + end do + + ! Put normalizing factors into the summary file. The user can use them to + ! tell a simulation program how to rescale the data. + if (abs(G3D%MeanWS) < 0.1_ReKi) then + MeanWS_nonZero = sign(0.1_ReKi, G3D%MeanWS) + else + MeanWS_nonZero = G3D%MeanWS + end if + + TI = real(Sigma/MeanWS_nonZero, SiKi) + + !---------------------------------------------------------------------------- + ! The summary file + !---------------------------------------------------------------------------- + + call OpenFOutFile(unit, trim(FileRootName)//'-Bladed.sum', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! The string "TurbSim" needs to be in the 2nd line of the summary file if AeroDyn will read this. + write (unit, "( / 'TurbSim - This summary file was generated by ', A, ' on ' , A , ' at ' , A , '.' / )") "NWTC_Library", CurDate(), CurTime() + write (unit, '(/)') + write (unit, '(/)') + write (unit, '( L10, 2X, "Clockwise rotation when looking downwind?")') .false. + write (unit, '( F10.3, 2X, "Hub height [m]")') G3D%RefHeight + write (unit, '( F10.3, 2X, "Grid height [m]")') delta(3)*(G3D%NZGrids - 1) + write (unit, '( F10.3, 2X, "Grid width [m]")') delta(2)*(G3D%NYGrids - 1) + write (unit, '(/"BLADED-style binary scaling parameters:"/)') + write (unit, '( 2X, "UBar = ", F9.4, " m/s")') MeanWS_nonZero + write (unit, '( 2X, "TI(u) = ", F9.4, " %")') 100.0*TI(1) + write (unit, '( 2X, "TI(v) = ", F9.4, " %")') 100.0*TI(2) + write (unit, '( 2X, "TI(w) = ", F9.4, " %")') 100.0*TI(3) + write (unit, '(/)') + write (unit, '( 2X, "Height offset = ", F9.4, " m" )') G3D%RefHeight - 0.5*delta(3)*(G3D%NZGrids - 1) - G3D%GridBase + write (unit, '( 2X, "Grid Base = ", F9.4, " m" )') G3D%GridBase + if (G3D%Periodic) then + write (unit, '()') + write (unit, '( A)') 'Creating a PERIODIC output file.' + end if + write (unit, '( A)') 'Creating a BLADED LEFT-HAND RULE output file.' + + close (unit) + + !---------------------------------------------------------------------------- + ! The BINARY file + !---------------------------------------------------------------------------- + + call OpenBOutFile(unit, TRIM(FileRootName)//'-Bladed.wnd', ErrStat, ErrMsg) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + write (unit) int(-99, B2Ki) ! -99 = New Bladed format + write (unit) int(4, B2Ki) ! 4 = improved von karman (not used, but needed for next 7 inputs) + write (unit) int(size(G3D%Vel, 3), B4Ki) ! size(FFWind,3) = 3 = number of wind components + write (unit) real(45.0_SiKi, SiKi) ! Latitude (degrees) (informational, not used in FAST) + write (unit) real(0.03_SiKi, SiKi) ! Roughness length (m) (informational, not used in FAST) + write (unit) real(G3D%RefHeight, SiKi) ! Reference Height (m) (informational, not used in FAST) + write (unit) real(100.0*TI(1), SiKi) ! Longitudinal turbulence intensity (%) + write (unit) real(100.0*TI(2), SiKi) ! Lateral turbulence intensity (%) + write (unit) real(100.0*TI(3), SiKi) ! Vertical turbulence intensity (%) + + write (unit) real(delta(3), SiKi) ! grid spacing in vertical direction, in m + write (unit) real(delta(2), SiKi) ! grid spacing in lateral direction, in m + write (unit) real(delta(1), SiKi) ! grid spacing in longitudinal direciton, in m + write (unit) int(G3D%NSteps/2, B4Ki) ! half the number of points in alongwind direction + write (unit) real(MeanWS_nonZero, SiKi) ! the mean wind speed in m/s + write (unit) real(0, SiKi) ! the vertical length scale of the longitudinal component in m + write (unit) real(0, SiKi) ! the lateral length scale of the longitudinal component in m + write (unit) real(0, SiKi) ! the longitudinal length scale of the longitudinal component in m + write (unit) int(0, B4Ki) ! an unused integer + write (unit) int(0, B4Ki) ! the random number seed + write (unit) int(G3D%NZGrids, B4Ki) ! the number of grid points vertically + write (unit) int(G3D%NYGrids, B4Ki) ! the number of grid points laterally + write (unit) int(0, B4Ki) ! the vertical length scale of the lateral component, not used + write (unit) int(0, B4Ki) ! the lateral length scale of the lateral component, not used + write (unit) int(0, B4Ki) ! the longitudinal length scale of the lateral component, not used + write (unit) int(0, B4Ki) ! the vertical length scale of the vertical component, not used + write (unit) int(0, B4Ki) ! the lateral length scale of the vertical component, not used + write (unit) int(0, B4Ki) ! the longitudinal length scale of the vertical component, not used + + ! Scaling value to convert wind speeds to 16-bit integers + do ic = 1, 3 + if (.not. EqualRealNos(Sigma(ic), 0.0_SiKi)) then + Scl(ic) = 1000.0/(Sigma(ic)) + else + Scl(ic) = 1.0_SiKi + end if + end do + + ! Bladed convention is positive V is pointed along negative Y (IEC turbine coordinate) + Scl(2) = -Scl(2) + + ! Offset value to convert wind speeds to 16-bit integers + if (G3D%AddMeanAfterInterp) then ! Note that this will not take into account any shear!!! + Off(1) = 0.0 + else + Off(1) = real(G3D%MeanWS*Scl(1), SiKi) + end if + Off(2) = 0.0 + Off(3) = 0.0 + + ! Scale velocity for 16-bit integers and write to file + do it = 1, G3D%NSteps + do iz = 1, G3D%NZGrids + do iy = 1, G3D%NYGrids + write (unit) NINT(G3D%Vel(:, iy, iz, it)*Scl - Off, B2Ki) ! scale to int16 + end do !IY + end do !IZ + end do !IT + + close (unit) + +end subroutine Grid3D_WriteBladed + +subroutine Grid3D_WriteVTK(G3D, FileRootName, unit, ErrStat, ErrMsg) + + type(Grid3DFieldType), intent(in) :: G3D !< Parameters + character(*), intent(in) :: FileRootName !< RootName for output files + integer(IntKi), intent(in) :: unit !< Error status of the operation + integer(IntKi), intent(out) :: ErrStat !< Error status of the operation + character(*), intent(out) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + character(*), parameter :: RoutineName = 'ConvertField_toVTK' + character(1024) :: RootPathName + character(1024) :: FileName + integer :: i + integer :: iy + integer :: iz + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + + call GetPath(FileRootName, RootPathName) + RootPathName = trim(RootPathName)//PathSep//"vtk" + call MkDir(trim(RootPathName)) ! make this directory if it doesn't already exist + + ! Loop through time steps + do i = 1, G3D%NSteps + + ! Create the output vtk file with naming /vtk/DisYZ.t.vtk + FileName = trim(RootPathName)//PathSep//"DisYZ.t"//trim(num2lstr(i))//".vtp" + + ! see WrVTK_SP_header + call OpenFOutFile(unit, TRIM(FileName), ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + write (unit, '(A)') '# vtk DataFile Version 3.0' + write (unit, '(A)') "InflowWind YZ Slice at T= "//trim(num2lstr((i - 1)*G3D%DTime))//" s" + write (unit, '(A)') 'ASCII' + write (unit, '(A)') 'DATASET STRUCTURED_POINTS' + + ! Note: gridVals must be stored such that the left-most dimension is X + ! and the right-most dimension is Z (see WrVTK_SP_vectors3D) + write (unit, '(A,3(i5,1X))') 'DIMENSIONS ', 1, G3D%NYGrids, G3D%NZGrids + write (unit, '(A,3(f10.2,1X))') 'ORIGIN ', G3D%InitXPosition, -G3D%YHWid, G3D%GridBase + write (unit, '(A,3(f10.2,1X))') 'SPACING ', 0.0_ReKi, 1.0_ReKi/G3D%InvDY, 1.0_ReKi/G3D%InvDZ + write (unit, '(A,i5)') 'POINT_DATA ', G3D%NYGrids*G3D%NZGrids + write (unit, '(A)') 'VECTORS DisYZ float' + + do iz = 1, G3D%NZGrids + do iy = 1, G3D%NYGrids + write (unit, '(3(f10.2,1X))') G3D%Vel(:, iy, iz, i) + end do + end do + + close (unit) + + end do + +end subroutine Grid3D_WriteVTK + +subroutine Grid3D_WriteHAWC(G3D, FileRootName, unit, ErrStat, ErrMsg) + + character(*), intent(in) :: FileRootName !< Name of the file to write the output in + type(Grid3DFieldType), intent(in) :: G3D !< Parameters + integer(IntKi), intent(in) :: unit !< Error status of the operation + integer(IntKi), intent(out) :: ErrStat !< Indicates whether an error occurred (see NWTC_Library) + character(*), intent(out) :: ErrMsg !< Error message associated with the ErrStat + + character(*), parameter :: RoutineName = 'Grid3D_WriteHAWC' + character(*), parameter :: Comp(3) = (/'u', 'v', 'w'/) + real(ReKi) :: delta(3) + integer(IntKi) :: IC, IX, IY, IZ + real(SiKi), allocatable :: MeanVal(:) + integer(IntKi) :: ErrStat2 + character(ErrMsgLen) :: ErrMsg2 + character(1024) :: RootWithoutPathName + + ErrStat = ErrID_None + ErrMsg = "" + + ! Array containing dx, dy, dz in meters + delta = [G3D%MeanWS*G3D%DTime, 1.0_ReKi/G3D%InvDY, 1.0_ReKi/G3D%InvDZ] + + ! Allocate array to hold mean value by Z location + call AllocAry(MeanVal, G3D%NZGrids, "MeanVal", ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + ! Calculate mean value at each Z location + MeanVal = sum(G3D%Vel(1, 1, :, :), dim=2)/G3D%NSteps + + !---------------------------------------------------------------------------- + ! Write summary file + !---------------------------------------------------------------------------- + + call OpenFOutFile(unit, trim(FileRootName)//'-HAWC.sum', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + write (unit, '(A)') '; Wind file converted to HAWC format on '//CurDate()//' at '//CurTime() + + write (unit, '()') + do IZ = G3D%NZGrids, 1, -1 + write (unit, '(A,I3,A,F15.5)') '; mean removed at z(', iz, ') = ', MeanVal(iz) + end do + + write (unit, '(A)') 'turb_format 1 ;' + + write (unit, '()') + write (unit, '(A)') 'begin mann;' + + ic = INDEX(FileRootName, '\', BACK=.true.) + ic = MAX(ic, INDEX(FileRootName, '/', BACK=.true.)) + RootWithoutPathName = FileRootName((ic + 1):) + + write (unit, '(2x,A, T30, A, " ;")') 'filename_u', trim(RootWithoutPathName)//'-HAWC-u.bin' + write (unit, '(2x,A, T30, A, " ;")') 'filename_v', trim(RootWithoutPathName)//'-HAWC-v.bin' + write (unit, '(2x,A, T30, A, " ;")') 'filename_w', trim(RootWithoutPathName)//'-HAWC-w.bin' + + write (unit, '(2x,A, T30, I8, 1x, F15.5, " ;")') 'box_dim_u', G3D%NSteps, delta(1) + write (unit, '(2x,A, T30, I8, 1x, F15.5, " ;")') 'box_dim_v', G3D%NYGrids, delta(2) + write (unit, '(2x,A, T30, I8, 1x, F15.5, " ;")') 'box_dim_w', G3D%NZGrids, delta(3) + + write (unit, '(2x,A)') 'dont_scale 1; converter did not rescale turbulence to unit standard deviation' + write (unit, '(A)') 'end mann;' + close (unit) + + !---------------------------------------------------------------------------- + ! Write the binary files for each component + !---------------------------------------------------------------------------- + + do IC = 1, G3D%NComp + + call OpenBOutFile(unit, trim(FileRootName)//'-HAWC-'//Comp(ic)//'.bin', ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return + + do IX = 1, G3D%NSteps + do IY = G3D%NYGrids, 1, -1 + write (unit, IOSTAT=ErrStat2) real(G3D%Vel(ic, iy, :, ix) - MeanVal, SiKi) + end do + end do + + close (unit) + + MeanVal = 0.0_SiKi + + end do + +end subroutine Grid3D_WriteHAWC + +end module InflowWind_IO diff --git a/modules/inflowwind/src/InflowWind_IO.txt b/modules/inflowwind/src/InflowWind_IO.txt new file mode 100644 index 000000000..5d6c60e59 --- /dev/null +++ b/modules/inflowwind/src/InflowWind_IO.txt @@ -0,0 +1,92 @@ +#---------------------------------------------------------------------------------------------------------------------------------- +# Registry for IfW_Interp, creates MODULE IfW_Interp_Types +# Module IfW_Interp_Types contains all of the user-defined types needed in IfW_FF. It also contains copy, destroy, pack, and +# unpack routines associated with each defined data types. +#---------------------------------------------------------------------------------------------------------------------------------- +# keyword +#---------------------------------------------------------------------------------------------------------------------------------- + +include Registry_NWTC_Library.txt +usefrom IfW_FlowField.txt + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef InflowWind_IO WindFileDat character(1024) FileName - - - "Name of the windfile retrieved" - +typedef ^ ^ IntKi WindType - 0 - "Type of the windfile" - +typedef ^ ^ ReKi RefHt - - - "Reference height given in file" meters +typedef ^ ^ Logical RefHt_Set - - - "Reference height was given in file" - +typedef ^ ^ DbKi DT - - - "TimeStep of the wind file -- zero value for none" seconds +typedef ^ ^ IntKi NumTSteps - - - "Number of timesteps in the time range of wind file" - +typedef ^ ^ Logical ConstantDT - - - "Timesteps are the same throughout file" - +typedef ^ ^ ReKi TRange {2} - - "Time range of the wind file" seconds +typedef ^ ^ Logical TRange_Limited - - - "TRange limits strictly enforced" - +typedef ^ ^ ReKi YRange {2} - - "Range in y direction" meters +typedef ^ ^ Logical YRange_Limited - - - "YRange limits strictly enforced" - +typedef ^ ^ ReKi ZRange {2} - - "Range in z direction" meters +typedef ^ ^ Logical ZRange_Limited - - - "ZRange limits strictly enforced" - +typedef ^ ^ IntKi BinaryFormat - - - "Binary format identifier" - +typedef ^ ^ Logical IsBinary - - - "Windfile is a binary file" - +typedef ^ ^ ReKi TI {3} - - "Turbulence intensity (U,V,W)" - +typedef ^ ^ Logical TI_listed - - - "Turbulence intesity given in file" - +typedef ^ ^ ReKi MWS - - - "Approximate mean wind speed" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Steady_InitInputType ReKi HWindSpeed - - - "Horizontal wind speed" m/s +typedef ^ ^ ReKi RefHt - - - "Reference height for horizontal wind speed" meters +typedef ^ ^ ReKi PLExp - - - "Power law exponent" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Uniform_InitInputType character(1024) WindFileName - - - "Name of the wind file to use" - +typedef ^ ^ ReKi RefHt - - - "Reference height for horizontal wind speed" meters +typedef ^ ^ ReKi RefLength - - - "Reference length for linear horizontal and vertical sheer" - +typedef ^ ^ ReKi PropagationDir - - - "Direction of wind propagation" radians +typedef ^ ^ logical UseInputFile - .true. - "Flag for toggling file based IO in wind type 2." - +typedef ^ ^ FileInfoType PassedFileData - - - "Optional slot for wind type 2 data if file IO is not used." - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Grid3D_InitInputType IntKi ScaleMethod - 0 - "Turbulence scaling method [0=none, 1=direct scaling, 2= calculate scaling factor based on a desired standard deviation]" - +typedef ^ ^ ReKi SF 3 0 - "Turbulence scaling factor for each direction [ScaleMethod=1]" - +typedef ^ ^ ReKi SigmaF 3 0 - "Turbulence standard deviation to calculate scaling from in each direction [ScaleMethod=2]" - +typedef ^ ^ IntKi WindProfileType - -1 - "Wind profile type (0=constant;1=logarithmic;2=power law)" - +typedef ^ ^ ReKi RefHt - 0 - "Reference (hub) height of the grid" meters +typedef ^ ^ ReKi URef - 0 - "Mean u-component wind speed at the reference height" meters +typedef ^ ^ ReKi PLExp - 0 - "Power law exponent (used for PL wind profile type only)" - +typedef ^ ^ ReKi VLinShr - 0 - "Vertical linear wind shear coefficient (used for vertical linear wind profile type only)" - +typedef ^ ^ ReKi HLinShr - 0 - "Horizontal linear wind shear coefficient (used for horizontal wind profile type only)" - +typedef ^ ^ ReKi RefLength - 1 - "Reference (rotor) length of the grid (used for horizontal wind profile type only)" - +typedef ^ ^ ReKi Z0 - 0 - "Surface roughness length (used for LOG wind profile type only)" - +typedef ^ ^ ReKi XOffset - 0 - "distance offset for FF wind files" m + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ TurbSim_InitInputType character(1024) WindFileName - - - "Name of the wind file to use" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Bladed_InitInputType character(1024) WindFileName - - - "Root filename" - +typedef ^ ^ IntKi WindType - - - "Whether this is native Bladed (needs wind profile and TI scaling) or not" - +typedef ^ ^ logical NativeBladedFmt - - - "Whether this is native Bladed (needs wind profile and TI scaling) or not" - +typedef ^ ^ logical TowerFileExist - - - "Tower file exists" - +typedef ^ ^ IntKi TurbineID - 0 - "Wind turbine ID number in the fixed (DEFAULT) file name when FixedWindFileRootName = .TRUE. (used by FAST.Farm)" - +typedef ^ ^ logical FixedWindFileRootName - .false. - "Do the wind data files have a fixed (DEFAULT) file name? (used by FAST.Farm)" - + +typedef ^ Bladed_InitOutputType ReKi PropagationDir - - - "Propogation direction from native Bladed format" degrees +typedef ^ ^ ReKi VFlowAngle - - - "Vertical flow angle from native Bladed format" degrees + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ HAWC_InitInputType character(1024) WindFileName {3} - - "Name of the wind file to use" - +typedef ^ ^ IntKi nx - 0 - "Number of grids in the x direction (in the 3 files above)" - +typedef ^ ^ IntKi ny - 0 - "Number of grids in the y direction (in the 3 files above)" - +typedef ^ ^ IntKi nz - 0 - "Number of grids in the z direction (in the 3 files above)" - +typedef ^ ^ ReKi dx - 0 - "size of grids in the x direction (in the 3 files above)" - +typedef ^ ^ ReKi dy - 0 - "size of grids in the y direction (in the 3 files above)" - +typedef ^ ^ ReKi dz - 0 - "size of grids in the z direction (in the 3 files above)" - +typedef ^ ^ Grid3D_InitInputType G3D - - - "Grid3D initialization input" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ User_InitInputType SiKi Dummy - - - "User field initialization input dummy value" - + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Grid4D_InitInputType IntKi n 4 - - "number of grid points in the x, y, z, and t directions" - +typedef ^ ^ ReKi delta 4 - - "size between 2 consecutive grid points in each grid direction" "m,m,m,s" +typedef ^ ^ ReKi pZero 3 - - "fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:))" "m" + +#---------------------------------------------------------------------------------------------------------------------------------- +typedef ^ Points_InitInputType IntKi NumWindPoints - - - "Number of points where wind components will be provided" - diff --git a/modules/inflowwind/src/InflowWind_IO_Types.f90 b/modules/inflowwind/src/InflowWind_IO_Types.f90 new file mode 100644 index 000000000..4409b9804 --- /dev/null +++ b/modules/inflowwind/src/InflowWind_IO_Types.f90 @@ -0,0 +1,2209 @@ +!STARTOFREGISTRYGENERATEDFILE 'InflowWind_IO_Types.f90' +! +! WARNING This file is generated automatically by the FAST registry. +! Do not edit. Your changes to this file will be lost. +! +! FAST Registry +!********************************************************************************************************************************* +! InflowWind_IO_Types +!................................................................................................................................. +! This file is part of InflowWind_IO. +! +! Copyright (C) 2012-2016 National Renewable Energy Laboratory +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +! +! +! W A R N I N G : This file was automatically generated from the FAST registry. Changes made to this file may be lost. +! +!********************************************************************************************************************************* +!> This module contains the user-defined types needed in InflowWind_IO. It also contains copy, destroy, pack, and +!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. +MODULE InflowWind_IO_Types +!--------------------------------------------------------------------------------------------------------------------------------- +USE IfW_FlowField_Types +USE NWTC_Library +IMPLICIT NONE +! ========= WindFileDat ======= + TYPE, PUBLIC :: WindFileDat + character(1024) :: FileName !< Name of the windfile retrieved [-] + INTEGER(IntKi) :: WindType = 0 !< Type of the windfile [-] + REAL(ReKi) :: RefHt !< Reference height given in file [meters] + LOGICAL :: RefHt_Set !< Reference height was given in file [-] + REAL(DbKi) :: DT !< TimeStep of the wind file -- zero value for none [seconds] + INTEGER(IntKi) :: NumTSteps !< Number of timesteps in the time range of wind file [-] + LOGICAL :: ConstantDT !< Timesteps are the same throughout file [-] + REAL(ReKi) , DIMENSION(1:2) :: TRange !< Time range of the wind file [seconds] + LOGICAL :: TRange_Limited !< TRange limits strictly enforced [-] + REAL(ReKi) , DIMENSION(1:2) :: YRange !< Range in y direction [meters] + LOGICAL :: YRange_Limited !< YRange limits strictly enforced [-] + REAL(ReKi) , DIMENSION(1:2) :: ZRange !< Range in z direction [meters] + LOGICAL :: ZRange_Limited !< ZRange limits strictly enforced [-] + INTEGER(IntKi) :: BinaryFormat !< Binary format identifier [-] + LOGICAL :: IsBinary !< Windfile is a binary file [-] + REAL(ReKi) , DIMENSION(1:3) :: TI !< Turbulence intensity (U,V,W) [-] + LOGICAL :: TI_listed !< Turbulence intesity given in file [-] + REAL(ReKi) :: MWS !< Approximate mean wind speed [-] + END TYPE WindFileDat +! ======================= +! ========= Steady_InitInputType ======= + TYPE, PUBLIC :: Steady_InitInputType + REAL(ReKi) :: HWindSpeed !< Horizontal wind speed [m/s] + REAL(ReKi) :: RefHt !< Reference height for horizontal wind speed [meters] + REAL(ReKi) :: PLExp !< Power law exponent [-] + END TYPE Steady_InitInputType +! ======================= +! ========= Uniform_InitInputType ======= + TYPE, PUBLIC :: Uniform_InitInputType + character(1024) :: WindFileName !< Name of the wind file to use [-] + REAL(ReKi) :: RefHt !< Reference height for horizontal wind speed [meters] + REAL(ReKi) :: RefLength !< Reference length for linear horizontal and vertical sheer [-] + REAL(ReKi) :: PropagationDir !< Direction of wind propagation [radians] + LOGICAL :: UseInputFile = .true. !< Flag for toggling file based IO in wind type 2. [-] + TYPE(FileInfoType) :: PassedFileData !< Optional slot for wind type 2 data if file IO is not used. [-] + END TYPE Uniform_InitInputType +! ======================= +! ========= Grid3D_InitInputType ======= + TYPE, PUBLIC :: Grid3D_InitInputType + INTEGER(IntKi) :: ScaleMethod = 0 !< Turbulence scaling method [0=none, 1=direct scaling, 2= calculate scaling factor based on a desired standard deviation] [-] + REAL(ReKi) , DIMENSION(1:3) :: SF !< Turbulence scaling factor for each direction [ScaleMethod=1] [-] + REAL(ReKi) , DIMENSION(1:3) :: SigmaF !< Turbulence standard deviation to calculate scaling from in each direction [ScaleMethod=2] [-] + INTEGER(IntKi) :: WindProfileType = -1 !< Wind profile type (0=constant;1=logarithmic;2=power law) [-] + REAL(ReKi) :: RefHt = 0 !< Reference (hub) height of the grid [meters] + REAL(ReKi) :: URef = 0 !< Mean u-component wind speed at the reference height [meters] + REAL(ReKi) :: PLExp = 0 !< Power law exponent (used for PL wind profile type only) [-] + REAL(ReKi) :: VLinShr = 0 !< Vertical linear wind shear coefficient (used for vertical linear wind profile type only) [-] + REAL(ReKi) :: HLinShr = 0 !< Horizontal linear wind shear coefficient (used for horizontal wind profile type only) [-] + REAL(ReKi) :: RefLength = 1 !< Reference (rotor) length of the grid (used for horizontal wind profile type only) [-] + REAL(ReKi) :: Z0 = 0 !< Surface roughness length (used for LOG wind profile type only) [-] + REAL(ReKi) :: XOffset = 0 !< distance offset for FF wind files [m] + END TYPE Grid3D_InitInputType +! ======================= +! ========= TurbSim_InitInputType ======= + TYPE, PUBLIC :: TurbSim_InitInputType + character(1024) :: WindFileName !< Name of the wind file to use [-] + END TYPE TurbSim_InitInputType +! ======================= +! ========= Bladed_InitInputType ======= + TYPE, PUBLIC :: Bladed_InitInputType + character(1024) :: WindFileName !< Root filename [-] + INTEGER(IntKi) :: WindType !< Whether this is native Bladed (needs wind profile and TI scaling) or not [-] + LOGICAL :: NativeBladedFmt !< Whether this is native Bladed (needs wind profile and TI scaling) or not [-] + LOGICAL :: TowerFileExist !< Tower file exists [-] + INTEGER(IntKi) :: TurbineID = 0 !< Wind turbine ID number in the fixed (DEFAULT) file name when FixedWindFileRootName = .TRUE. (used by FAST.Farm) [-] + LOGICAL :: FixedWindFileRootName = .false. !< Do the wind data files have a fixed (DEFAULT) file name? (used by FAST.Farm) [-] + END TYPE Bladed_InitInputType +! ======================= +! ========= Bladed_InitOutputType ======= + TYPE, PUBLIC :: Bladed_InitOutputType + REAL(ReKi) :: PropagationDir !< Propogation direction from native Bladed format [degrees] + REAL(ReKi) :: VFlowAngle !< Vertical flow angle from native Bladed format [degrees] + END TYPE Bladed_InitOutputType +! ======================= +! ========= HAWC_InitInputType ======= + TYPE, PUBLIC :: HAWC_InitInputType + character(1024) , DIMENSION(1:3) :: WindFileName !< Name of the wind file to use [-] + INTEGER(IntKi) :: nx = 0 !< Number of grids in the x direction (in the 3 files above) [-] + INTEGER(IntKi) :: ny = 0 !< Number of grids in the y direction (in the 3 files above) [-] + INTEGER(IntKi) :: nz = 0 !< Number of grids in the z direction (in the 3 files above) [-] + REAL(ReKi) :: dx = 0 !< size of grids in the x direction (in the 3 files above) [-] + REAL(ReKi) :: dy = 0 !< size of grids in the y direction (in the 3 files above) [-] + REAL(ReKi) :: dz = 0 !< size of grids in the z direction (in the 3 files above) [-] + TYPE(Grid3D_InitInputType) :: G3D !< Grid3D initialization input [-] + END TYPE HAWC_InitInputType +! ======================= +! ========= User_InitInputType ======= + TYPE, PUBLIC :: User_InitInputType + REAL(SiKi) :: Dummy !< User field initialization input dummy value [-] + END TYPE User_InitInputType +! ======================= +! ========= Grid4D_InitInputType ======= + TYPE, PUBLIC :: Grid4D_InitInputType + INTEGER(IntKi) , DIMENSION(1:4) :: n !< number of grid points in the x, y, z, and t directions [-] + REAL(ReKi) , DIMENSION(1:4) :: delta !< size between 2 consecutive grid points in each grid direction [m,m,m,s] + REAL(ReKi) , DIMENSION(1:3) :: pZero !< fixed position of the XYZ grid (i.e., XYZ coordinates of m%V(:,1,1,1,:)) [m] + END TYPE Grid4D_InitInputType +! ======================= +! ========= Points_InitInputType ======= + TYPE, PUBLIC :: Points_InitInputType + INTEGER(IntKi) :: NumWindPoints !< Number of points where wind components will be provided [-] + END TYPE Points_InitInputType +! ======================= +CONTAINS + SUBROUTINE InflowWind_IO_CopyWindFileDat( SrcWindFileDatData, DstWindFileDatData, CtrlCode, ErrStat, ErrMsg ) + TYPE(WindFileDat), INTENT(IN) :: SrcWindFileDatData + TYPE(WindFileDat), INTENT(INOUT) :: DstWindFileDatData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyWindFileDat' +! + ErrStat = ErrID_None + ErrMsg = "" + DstWindFileDatData%FileName = SrcWindFileDatData%FileName + DstWindFileDatData%WindType = SrcWindFileDatData%WindType + DstWindFileDatData%RefHt = SrcWindFileDatData%RefHt + DstWindFileDatData%RefHt_Set = SrcWindFileDatData%RefHt_Set + DstWindFileDatData%DT = SrcWindFileDatData%DT + DstWindFileDatData%NumTSteps = SrcWindFileDatData%NumTSteps + DstWindFileDatData%ConstantDT = SrcWindFileDatData%ConstantDT + DstWindFileDatData%TRange = SrcWindFileDatData%TRange + DstWindFileDatData%TRange_Limited = SrcWindFileDatData%TRange_Limited + DstWindFileDatData%YRange = SrcWindFileDatData%YRange + DstWindFileDatData%YRange_Limited = SrcWindFileDatData%YRange_Limited + DstWindFileDatData%ZRange = SrcWindFileDatData%ZRange + DstWindFileDatData%ZRange_Limited = SrcWindFileDatData%ZRange_Limited + DstWindFileDatData%BinaryFormat = SrcWindFileDatData%BinaryFormat + DstWindFileDatData%IsBinary = SrcWindFileDatData%IsBinary + DstWindFileDatData%TI = SrcWindFileDatData%TI + DstWindFileDatData%TI_listed = SrcWindFileDatData%TI_listed + DstWindFileDatData%MWS = SrcWindFileDatData%MWS + END SUBROUTINE InflowWind_IO_CopyWindFileDat + + SUBROUTINE InflowWind_IO_DestroyWindFileDat( WindFileDatData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(WindFileDat), INTENT(INOUT) :: WindFileDatData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyWindFileDat' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyWindFileDat + + SUBROUTINE InflowWind_IO_PackWindFileDat( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(WindFileDat), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackWindFileDat' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1*LEN(InData%FileName) ! FileName + Int_BufSz = Int_BufSz + 1 ! WindType + Re_BufSz = Re_BufSz + 1 ! RefHt + Int_BufSz = Int_BufSz + 1 ! RefHt_Set + Db_BufSz = Db_BufSz + 1 ! DT + Int_BufSz = Int_BufSz + 1 ! NumTSteps + Int_BufSz = Int_BufSz + 1 ! ConstantDT + Re_BufSz = Re_BufSz + SIZE(InData%TRange) ! TRange + Int_BufSz = Int_BufSz + 1 ! TRange_Limited + Re_BufSz = Re_BufSz + SIZE(InData%YRange) ! YRange + Int_BufSz = Int_BufSz + 1 ! YRange_Limited + Re_BufSz = Re_BufSz + SIZE(InData%ZRange) ! ZRange + Int_BufSz = Int_BufSz + 1 ! ZRange_Limited + Int_BufSz = Int_BufSz + 1 ! BinaryFormat + Int_BufSz = Int_BufSz + 1 ! IsBinary + Re_BufSz = Re_BufSz + SIZE(InData%TI) ! TI + Int_BufSz = Int_BufSz + 1 ! TI_listed + Re_BufSz = Re_BufSz + 1 ! MWS + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO I = 1, LEN(InData%FileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%FileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IntKiBuf(Int_Xferred) = InData%WindType + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefHt + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%RefHt_Set, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%DT + Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumTSteps + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%ConstantDT, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%TRange,1), UBOUND(InData%TRange,1) + ReKiBuf(Re_Xferred) = InData%TRange(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = TRANSFER(InData%TRange_Limited, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%YRange,1), UBOUND(InData%YRange,1) + ReKiBuf(Re_Xferred) = InData%YRange(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = TRANSFER(InData%YRange_Limited, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%ZRange,1), UBOUND(InData%ZRange,1) + ReKiBuf(Re_Xferred) = InData%ZRange(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = TRANSFER(InData%ZRange_Limited, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%BinaryFormat + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%IsBinary, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%TI,1), UBOUND(InData%TI,1) + ReKiBuf(Re_Xferred) = InData%TI(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = TRANSFER(InData%TI_listed, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MWS + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackWindFileDat + + SUBROUTINE InflowWind_IO_UnPackWindFileDat( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(WindFileDat), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackWindFileDat' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + DO I = 1, LEN(OutData%FileName) + OutData%FileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%WindType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%RefHt = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefHt_Set = TRANSFER(IntKiBuf(Int_Xferred), OutData%RefHt_Set) + Int_Xferred = Int_Xferred + 1 + OutData%DT = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%NumTSteps = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%ConstantDT = TRANSFER(IntKiBuf(Int_Xferred), OutData%ConstantDT) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%TRange,1) + i1_u = UBOUND(OutData%TRange,1) + DO i1 = LBOUND(OutData%TRange,1), UBOUND(OutData%TRange,1) + OutData%TRange(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%TRange_Limited = TRANSFER(IntKiBuf(Int_Xferred), OutData%TRange_Limited) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%YRange,1) + i1_u = UBOUND(OutData%YRange,1) + DO i1 = LBOUND(OutData%YRange,1), UBOUND(OutData%YRange,1) + OutData%YRange(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%YRange_Limited = TRANSFER(IntKiBuf(Int_Xferred), OutData%YRange_Limited) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%ZRange,1) + i1_u = UBOUND(OutData%ZRange,1) + DO i1 = LBOUND(OutData%ZRange,1), UBOUND(OutData%ZRange,1) + OutData%ZRange(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%ZRange_Limited = TRANSFER(IntKiBuf(Int_Xferred), OutData%ZRange_Limited) + Int_Xferred = Int_Xferred + 1 + OutData%BinaryFormat = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%IsBinary = TRANSFER(IntKiBuf(Int_Xferred), OutData%IsBinary) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%TI,1) + i1_u = UBOUND(OutData%TI,1) + DO i1 = LBOUND(OutData%TI,1), UBOUND(OutData%TI,1) + OutData%TI(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%TI_listed = TRANSFER(IntKiBuf(Int_Xferred), OutData%TI_listed) + Int_Xferred = Int_Xferred + 1 + OutData%MWS = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackWindFileDat + + SUBROUTINE InflowWind_IO_CopySteady_InitInputType( SrcSteady_InitInputTypeData, DstSteady_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Steady_InitInputType), INTENT(IN) :: SrcSteady_InitInputTypeData + TYPE(Steady_InitInputType), INTENT(INOUT) :: DstSteady_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopySteady_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstSteady_InitInputTypeData%HWindSpeed = SrcSteady_InitInputTypeData%HWindSpeed + DstSteady_InitInputTypeData%RefHt = SrcSteady_InitInputTypeData%RefHt + DstSteady_InitInputTypeData%PLExp = SrcSteady_InitInputTypeData%PLExp + END SUBROUTINE InflowWind_IO_CopySteady_InitInputType + + SUBROUTINE InflowWind_IO_DestroySteady_InitInputType( Steady_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Steady_InitInputType), INTENT(INOUT) :: Steady_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroySteady_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroySteady_InitInputType + + SUBROUTINE InflowWind_IO_PackSteady_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Steady_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackSteady_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! HWindSpeed + Re_BufSz = Re_BufSz + 1 ! RefHt + Re_BufSz = Re_BufSz + 1 ! PLExp + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%HWindSpeed + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefHt + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%PLExp + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackSteady_InitInputType + + SUBROUTINE InflowWind_IO_UnPackSteady_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Steady_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackSteady_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%HWindSpeed = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefHt = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%PLExp = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackSteady_InitInputType + + SUBROUTINE InflowWind_IO_CopyUniform_InitInputType( SrcUniform_InitInputTypeData, DstUniform_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Uniform_InitInputType), INTENT(IN) :: SrcUniform_InitInputTypeData + TYPE(Uniform_InitInputType), INTENT(INOUT) :: DstUniform_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyUniform_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstUniform_InitInputTypeData%WindFileName = SrcUniform_InitInputTypeData%WindFileName + DstUniform_InitInputTypeData%RefHt = SrcUniform_InitInputTypeData%RefHt + DstUniform_InitInputTypeData%RefLength = SrcUniform_InitInputTypeData%RefLength + DstUniform_InitInputTypeData%PropagationDir = SrcUniform_InitInputTypeData%PropagationDir + DstUniform_InitInputTypeData%UseInputFile = SrcUniform_InitInputTypeData%UseInputFile + CALL NWTC_Library_Copyfileinfotype( SrcUniform_InitInputTypeData%PassedFileData, DstUniform_InitInputTypeData%PassedFileData, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE InflowWind_IO_CopyUniform_InitInputType + + SUBROUTINE InflowWind_IO_DestroyUniform_InitInputType( Uniform_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Uniform_InitInputType), INTENT(INOUT) :: Uniform_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyUniform_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyfileinfotype( Uniform_InitInputTypeData%PassedFileData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE InflowWind_IO_DestroyUniform_InitInputType + + SUBROUTINE InflowWind_IO_PackUniform_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Uniform_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackUniform_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName + Re_BufSz = Re_BufSz + 1 ! RefHt + Re_BufSz = Re_BufSz + 1 ! RefLength + Re_BufSz = Re_BufSz + 1 ! PropagationDir + Int_BufSz = Int_BufSz + 1 ! UseInputFile + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! PassedFileData: size of buffers for each call to pack subtype + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, .TRUE. ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! PassedFileData + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! PassedFileData + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! PassedFileData + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO I = 1, LEN(InData%WindFileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + ReKiBuf(Re_Xferred) = InData%RefHt + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefLength + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%PropagationDir + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%UseInputFile, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + CALL NWTC_Library_Packfileinfotype( Re_Buf, Db_Buf, Int_Buf, InData%PassedFileData, ErrStat2, ErrMsg2, OnlySize ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END SUBROUTINE InflowWind_IO_PackUniform_InitInputType + + SUBROUTINE InflowWind_IO_UnPackUniform_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Uniform_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackUniform_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + DO I = 1, LEN(OutData%WindFileName) + OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%RefHt = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefLength = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%PropagationDir = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%UseInputFile = TRANSFER(IntKiBuf(Int_Xferred), OutData%UseInputFile) + Int_Xferred = Int_Xferred + 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackfileinfotype( Re_Buf, Db_Buf, Int_Buf, OutData%PassedFileData, ErrStat2, ErrMsg2 ) ! PassedFileData + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END SUBROUTINE InflowWind_IO_UnPackUniform_InitInputType + + SUBROUTINE InflowWind_IO_CopyGrid3D_InitInputType( SrcGrid3D_InitInputTypeData, DstGrid3D_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Grid3D_InitInputType), INTENT(IN) :: SrcGrid3D_InitInputTypeData + TYPE(Grid3D_InitInputType), INTENT(INOUT) :: DstGrid3D_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyGrid3D_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstGrid3D_InitInputTypeData%ScaleMethod = SrcGrid3D_InitInputTypeData%ScaleMethod + DstGrid3D_InitInputTypeData%SF = SrcGrid3D_InitInputTypeData%SF + DstGrid3D_InitInputTypeData%SigmaF = SrcGrid3D_InitInputTypeData%SigmaF + DstGrid3D_InitInputTypeData%WindProfileType = SrcGrid3D_InitInputTypeData%WindProfileType + DstGrid3D_InitInputTypeData%RefHt = SrcGrid3D_InitInputTypeData%RefHt + DstGrid3D_InitInputTypeData%URef = SrcGrid3D_InitInputTypeData%URef + DstGrid3D_InitInputTypeData%PLExp = SrcGrid3D_InitInputTypeData%PLExp + DstGrid3D_InitInputTypeData%VLinShr = SrcGrid3D_InitInputTypeData%VLinShr + DstGrid3D_InitInputTypeData%HLinShr = SrcGrid3D_InitInputTypeData%HLinShr + DstGrid3D_InitInputTypeData%RefLength = SrcGrid3D_InitInputTypeData%RefLength + DstGrid3D_InitInputTypeData%Z0 = SrcGrid3D_InitInputTypeData%Z0 + DstGrid3D_InitInputTypeData%XOffset = SrcGrid3D_InitInputTypeData%XOffset + END SUBROUTINE InflowWind_IO_CopyGrid3D_InitInputType + + SUBROUTINE InflowWind_IO_DestroyGrid3D_InitInputType( Grid3D_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Grid3D_InitInputType), INTENT(INOUT) :: Grid3D_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyGrid3D_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyGrid3D_InitInputType + + SUBROUTINE InflowWind_IO_PackGrid3D_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Grid3D_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackGrid3D_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! ScaleMethod + Re_BufSz = Re_BufSz + SIZE(InData%SF) ! SF + Re_BufSz = Re_BufSz + SIZE(InData%SigmaF) ! SigmaF + Int_BufSz = Int_BufSz + 1 ! WindProfileType + Re_BufSz = Re_BufSz + 1 ! RefHt + Re_BufSz = Re_BufSz + 1 ! URef + Re_BufSz = Re_BufSz + 1 ! PLExp + Re_BufSz = Re_BufSz + 1 ! VLinShr + Re_BufSz = Re_BufSz + 1 ! HLinShr + Re_BufSz = Re_BufSz + 1 ! RefLength + Re_BufSz = Re_BufSz + 1 ! Z0 + Re_BufSz = Re_BufSz + 1 ! XOffset + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IntKiBuf(Int_Xferred) = InData%ScaleMethod + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%SF,1), UBOUND(InData%SF,1) + ReKiBuf(Re_Xferred) = InData%SF(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%SigmaF,1), UBOUND(InData%SigmaF,1) + ReKiBuf(Re_Xferred) = InData%SigmaF(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%WindProfileType + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefHt + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%URef + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%PLExp + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VLinShr + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%HLinShr + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%RefLength + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Z0 + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%XOffset + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackGrid3D_InitInputType + + SUBROUTINE InflowWind_IO_UnPackGrid3D_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Grid3D_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackGrid3D_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%ScaleMethod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%SF,1) + i1_u = UBOUND(OutData%SF,1) + DO i1 = LBOUND(OutData%SF,1), UBOUND(OutData%SF,1) + OutData%SF(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%SigmaF,1) + i1_u = UBOUND(OutData%SigmaF,1) + DO i1 = LBOUND(OutData%SigmaF,1), UBOUND(OutData%SigmaF,1) + OutData%SigmaF(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + OutData%WindProfileType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%RefHt = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%URef = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%PLExp = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VLinShr = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%HLinShr = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%RefLength = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Z0 = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%XOffset = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackGrid3D_InitInputType + + SUBROUTINE InflowWind_IO_CopyTurbSim_InitInputType( SrcTurbSim_InitInputTypeData, DstTurbSim_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(TurbSim_InitInputType), INTENT(IN) :: SrcTurbSim_InitInputTypeData + TYPE(TurbSim_InitInputType), INTENT(INOUT) :: DstTurbSim_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyTurbSim_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstTurbSim_InitInputTypeData%WindFileName = SrcTurbSim_InitInputTypeData%WindFileName + END SUBROUTINE InflowWind_IO_CopyTurbSim_InitInputType + + SUBROUTINE InflowWind_IO_DestroyTurbSim_InitInputType( TurbSim_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(TurbSim_InitInputType), INTENT(INOUT) :: TurbSim_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyTurbSim_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyTurbSim_InitInputType + + SUBROUTINE InflowWind_IO_PackTurbSim_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(TurbSim_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackTurbSim_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO I = 1, LEN(InData%WindFileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END SUBROUTINE InflowWind_IO_PackTurbSim_InitInputType + + SUBROUTINE InflowWind_IO_UnPackTurbSim_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(TurbSim_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackTurbSim_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + DO I = 1, LEN(OutData%WindFileName) + OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END SUBROUTINE InflowWind_IO_UnPackTurbSim_InitInputType + + SUBROUTINE InflowWind_IO_CopyBladed_InitInputType( SrcBladed_InitInputTypeData, DstBladed_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Bladed_InitInputType), INTENT(IN) :: SrcBladed_InitInputTypeData + TYPE(Bladed_InitInputType), INTENT(INOUT) :: DstBladed_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyBladed_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstBladed_InitInputTypeData%WindFileName = SrcBladed_InitInputTypeData%WindFileName + DstBladed_InitInputTypeData%WindType = SrcBladed_InitInputTypeData%WindType + DstBladed_InitInputTypeData%NativeBladedFmt = SrcBladed_InitInputTypeData%NativeBladedFmt + DstBladed_InitInputTypeData%TowerFileExist = SrcBladed_InitInputTypeData%TowerFileExist + DstBladed_InitInputTypeData%TurbineID = SrcBladed_InitInputTypeData%TurbineID + DstBladed_InitInputTypeData%FixedWindFileRootName = SrcBladed_InitInputTypeData%FixedWindFileRootName + END SUBROUTINE InflowWind_IO_CopyBladed_InitInputType + + SUBROUTINE InflowWind_IO_DestroyBladed_InitInputType( Bladed_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Bladed_InitInputType), INTENT(INOUT) :: Bladed_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyBladed_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyBladed_InitInputType + + SUBROUTINE InflowWind_IO_PackBladed_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Bladed_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackBladed_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1*LEN(InData%WindFileName) ! WindFileName + Int_BufSz = Int_BufSz + 1 ! WindType + Int_BufSz = Int_BufSz + 1 ! NativeBladedFmt + Int_BufSz = Int_BufSz + 1 ! TowerFileExist + Int_BufSz = Int_BufSz + 1 ! TurbineID + Int_BufSz = Int_BufSz + 1 ! FixedWindFileRootName + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO I = 1, LEN(InData%WindFileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IntKiBuf(Int_Xferred) = InData%WindType + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%NativeBladedFmt, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%TowerFileExist, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%TurbineID + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%FixedWindFileRootName, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackBladed_InitInputType + + SUBROUTINE InflowWind_IO_UnPackBladed_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Bladed_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackBladed_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + DO I = 1, LEN(OutData%WindFileName) + OutData%WindFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%WindType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NativeBladedFmt = TRANSFER(IntKiBuf(Int_Xferred), OutData%NativeBladedFmt) + Int_Xferred = Int_Xferred + 1 + OutData%TowerFileExist = TRANSFER(IntKiBuf(Int_Xferred), OutData%TowerFileExist) + Int_Xferred = Int_Xferred + 1 + OutData%TurbineID = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%FixedWindFileRootName = TRANSFER(IntKiBuf(Int_Xferred), OutData%FixedWindFileRootName) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackBladed_InitInputType + + SUBROUTINE InflowWind_IO_CopyBladed_InitOutputType( SrcBladed_InitOutputTypeData, DstBladed_InitOutputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Bladed_InitOutputType), INTENT(IN) :: SrcBladed_InitOutputTypeData + TYPE(Bladed_InitOutputType), INTENT(INOUT) :: DstBladed_InitOutputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyBladed_InitOutputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstBladed_InitOutputTypeData%PropagationDir = SrcBladed_InitOutputTypeData%PropagationDir + DstBladed_InitOutputTypeData%VFlowAngle = SrcBladed_InitOutputTypeData%VFlowAngle + END SUBROUTINE InflowWind_IO_CopyBladed_InitOutputType + + SUBROUTINE InflowWind_IO_DestroyBladed_InitOutputType( Bladed_InitOutputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Bladed_InitOutputType), INTENT(INOUT) :: Bladed_InitOutputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyBladed_InitOutputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyBladed_InitOutputType + + SUBROUTINE InflowWind_IO_PackBladed_InitOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Bladed_InitOutputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackBladed_InitOutputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! PropagationDir + Re_BufSz = Re_BufSz + 1 ! VFlowAngle + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%PropagationDir + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%VFlowAngle + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackBladed_InitOutputType + + SUBROUTINE InflowWind_IO_UnPackBladed_InitOutputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Bladed_InitOutputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackBladed_InitOutputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%PropagationDir = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%VFlowAngle = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackBladed_InitOutputType + + SUBROUTINE InflowWind_IO_CopyHAWC_InitInputType( SrcHAWC_InitInputTypeData, DstHAWC_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(HAWC_InitInputType), INTENT(IN) :: SrcHAWC_InitInputTypeData + TYPE(HAWC_InitInputType), INTENT(INOUT) :: DstHAWC_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyHAWC_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstHAWC_InitInputTypeData%WindFileName = SrcHAWC_InitInputTypeData%WindFileName + DstHAWC_InitInputTypeData%nx = SrcHAWC_InitInputTypeData%nx + DstHAWC_InitInputTypeData%ny = SrcHAWC_InitInputTypeData%ny + DstHAWC_InitInputTypeData%nz = SrcHAWC_InitInputTypeData%nz + DstHAWC_InitInputTypeData%dx = SrcHAWC_InitInputTypeData%dx + DstHAWC_InitInputTypeData%dy = SrcHAWC_InitInputTypeData%dy + DstHAWC_InitInputTypeData%dz = SrcHAWC_InitInputTypeData%dz + CALL InflowWind_IO_Copygrid3d_initinputtype( SrcHAWC_InitInputTypeData%G3D, DstHAWC_InitInputTypeData%G3D, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE InflowWind_IO_CopyHAWC_InitInputType + + SUBROUTINE InflowWind_IO_DestroyHAWC_InitInputType( HAWC_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(HAWC_InitInputType), INTENT(INOUT) :: HAWC_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyHAWC_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL InflowWind_IO_Destroygrid3d_initinputtype( HAWC_InitInputTypeData%G3D, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE InflowWind_IO_DestroyHAWC_InitInputType + + SUBROUTINE InflowWind_IO_PackHAWC_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(HAWC_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackHAWC_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + SIZE(InData%WindFileName)*LEN(InData%WindFileName) ! WindFileName + Int_BufSz = Int_BufSz + 1 ! nx + Int_BufSz = Int_BufSz + 1 ! ny + Int_BufSz = Int_BufSz + 1 ! nz + Re_BufSz = Re_BufSz + 1 ! dx + Re_BufSz = Re_BufSz + 1 ! dy + Re_BufSz = Re_BufSz + 1 ! dz + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! G3D: size of buffers for each call to pack subtype + CALL InflowWind_IO_Packgrid3d_initinputtype( Re_Buf, Db_Buf, Int_Buf, InData%G3D, ErrStat2, ErrMsg2, .TRUE. ) ! G3D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! G3D + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! G3D + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! G3D + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO i1 = LBOUND(InData%WindFileName,1), UBOUND(InData%WindFileName,1) + DO I = 1, LEN(InData%WindFileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%WindFileName(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + IntKiBuf(Int_Xferred) = InData%nx + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%ny + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nz + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%dx + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%dy + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%dz + Re_Xferred = Re_Xferred + 1 + CALL InflowWind_IO_Packgrid3d_initinputtype( Re_Buf, Db_Buf, Int_Buf, InData%G3D, ErrStat2, ErrMsg2, OnlySize ) ! G3D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END SUBROUTINE InflowWind_IO_PackHAWC_InitInputType + + SUBROUTINE InflowWind_IO_UnPackHAWC_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(HAWC_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackHAWC_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + i1_l = LBOUND(OutData%WindFileName,1) + i1_u = UBOUND(OutData%WindFileName,1) + DO i1 = LBOUND(OutData%WindFileName,1), UBOUND(OutData%WindFileName,1) + DO I = 1, LEN(OutData%WindFileName) + OutData%WindFileName(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + OutData%nx = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%ny = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nz = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%dx = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%dy = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%dz = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_IO_Unpackgrid3d_initinputtype( Re_Buf, Db_Buf, Int_Buf, OutData%G3D, ErrStat2, ErrMsg2 ) ! G3D + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END SUBROUTINE InflowWind_IO_UnPackHAWC_InitInputType + + SUBROUTINE InflowWind_IO_CopyUser_InitInputType( SrcUser_InitInputTypeData, DstUser_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(User_InitInputType), INTENT(IN) :: SrcUser_InitInputTypeData + TYPE(User_InitInputType), INTENT(INOUT) :: DstUser_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyUser_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstUser_InitInputTypeData%Dummy = SrcUser_InitInputTypeData%Dummy + END SUBROUTINE InflowWind_IO_CopyUser_InitInputType + + SUBROUTINE InflowWind_IO_DestroyUser_InitInputType( User_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(User_InitInputType), INTENT(INOUT) :: User_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyUser_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyUser_InitInputType + + SUBROUTINE InflowWind_IO_PackUser_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(User_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackUser_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! Dummy + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%Dummy + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackUser_InitInputType + + SUBROUTINE InflowWind_IO_UnPackUser_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(User_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackUser_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%Dummy = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackUser_InitInputType + + SUBROUTINE InflowWind_IO_CopyGrid4D_InitInputType( SrcGrid4D_InitInputTypeData, DstGrid4D_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Grid4D_InitInputType), INTENT(IN) :: SrcGrid4D_InitInputTypeData + TYPE(Grid4D_InitInputType), INTENT(INOUT) :: DstGrid4D_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyGrid4D_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstGrid4D_InitInputTypeData%n = SrcGrid4D_InitInputTypeData%n + DstGrid4D_InitInputTypeData%delta = SrcGrid4D_InitInputTypeData%delta + DstGrid4D_InitInputTypeData%pZero = SrcGrid4D_InitInputTypeData%pZero + END SUBROUTINE InflowWind_IO_CopyGrid4D_InitInputType + + SUBROUTINE InflowWind_IO_DestroyGrid4D_InitInputType( Grid4D_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Grid4D_InitInputType), INTENT(INOUT) :: Grid4D_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyGrid4D_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyGrid4D_InitInputType + + SUBROUTINE InflowWind_IO_PackGrid4D_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Grid4D_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackGrid4D_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + SIZE(InData%n) ! n + Re_BufSz = Re_BufSz + SIZE(InData%delta) ! delta + Re_BufSz = Re_BufSz + SIZE(InData%pZero) ! pZero + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO i1 = LBOUND(InData%n,1), UBOUND(InData%n,1) + IntKiBuf(Int_Xferred) = InData%n(i1) + Int_Xferred = Int_Xferred + 1 + END DO + DO i1 = LBOUND(InData%delta,1), UBOUND(InData%delta,1) + ReKiBuf(Re_Xferred) = InData%delta(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%pZero,1), UBOUND(InData%pZero,1) + ReKiBuf(Re_Xferred) = InData%pZero(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END SUBROUTINE InflowWind_IO_PackGrid4D_InitInputType + + SUBROUTINE InflowWind_IO_UnPackGrid4D_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Grid4D_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackGrid4D_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + i1_l = LBOUND(OutData%n,1) + i1_u = UBOUND(OutData%n,1) + DO i1 = LBOUND(OutData%n,1), UBOUND(OutData%n,1) + OutData%n(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + i1_l = LBOUND(OutData%delta,1) + i1_u = UBOUND(OutData%delta,1) + DO i1 = LBOUND(OutData%delta,1), UBOUND(OutData%delta,1) + OutData%delta(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%pZero,1) + i1_u = UBOUND(OutData%pZero,1) + DO i1 = LBOUND(OutData%pZero,1), UBOUND(OutData%pZero,1) + OutData%pZero(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END SUBROUTINE InflowWind_IO_UnPackGrid4D_InitInputType + + SUBROUTINE InflowWind_IO_CopyPoints_InitInputType( SrcPoints_InitInputTypeData, DstPoints_InitInputTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(Points_InitInputType), INTENT(IN) :: SrcPoints_InitInputTypeData + TYPE(Points_InitInputType), INTENT(INOUT) :: DstPoints_InitInputTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_CopyPoints_InitInputType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstPoints_InitInputTypeData%NumWindPoints = SrcPoints_InitInputTypeData%NumWindPoints + END SUBROUTINE InflowWind_IO_CopyPoints_InitInputType + + SUBROUTINE InflowWind_IO_DestroyPoints_InitInputType( Points_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(Points_InitInputType), INTENT(INOUT) :: Points_InitInputTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_DestroyPoints_InitInputType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_IO_DestroyPoints_InitInputType + + SUBROUTINE InflowWind_IO_PackPoints_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(Points_InitInputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_PackPoints_InitInputType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! NumWindPoints + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IntKiBuf(Int_Xferred) = InData%NumWindPoints + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE InflowWind_IO_PackPoints_InitInputType + + SUBROUTINE InflowWind_IO_UnPackPoints_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(Points_InitInputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_IO_UnPackPoints_InitInputType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%NumWindPoints = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE InflowWind_IO_UnPackPoints_InitInputType + +END MODULE InflowWind_IO_Types +!ENDOFREGISTRYGENERATEDFILE diff --git a/modules/inflowwind/src/InflowWind_Subs.f90 b/modules/inflowwind/src/InflowWind_Subs.f90 index 2499deb11..ed6908263 100644 --- a/modules/inflowwind/src/InflowWind_Subs.f90 +++ b/modules/inflowwind/src/InflowWind_Subs.f90 @@ -19,22 +19,9 @@ !********************************************************************************************************************************** MODULE InflowWind_Subs - USE InflowWind_Types - USE NWTC_Library - - !------------------------------------------------------------------------------------------------- - ! The included wind modules (TYPES modules are inherited from InflowWind_Types, so not specified here again.) - !------------------------------------------------------------------------------------------------- - USE IfW_UniformWind ! uniform wind files (text files) - USE IfW_TSFFWind ! TurbSim style full-field binary wind files - USE IfW_BladedFFWind ! Bladed style full-field binary wind files - USE IfW_UserWind ! User-defined wind module - USE IfW_HAWCWind ! full-field binary wind files in HAWC format - USE IfW_4Dext ! 4D wind field from external source (e.g., FAST.Farm) - -!!! USE FDWind ! 4-D binary wind files -!!! USE CTWind ! coherent turbulence from KH billow - binary file superimposed on another wind type - + USE InflowWind_Types + USE NWTC_Library + USE IfW_FlowField, only: IfW_FlowField_GetVelAcc IMPLICIT NONE @@ -45,12 +32,7 @@ MODULE InflowWind_Subs ! using the parameters listed in the "OutListParameters.xlsx" Excel file. Any changes to these ! lines should be modified in the Matlab script and/or Excel worksheet as necessary. ! =================================================================================================== -! This code was generated by Write_ChckOutLst.m at 26-Oct-2020 15:42:27. - - - ! Parameters related to output length (number of characters allowed in the output data headers): - - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 +! This code was generated by "Write_ChckOutLst.m" at 05-Apr-2023. ! Indices for computing output channels: @@ -60,95 +42,144 @@ MODULE InflowWind_Subs ! Time: - INTEGER(IntKi), PARAMETER :: Time = 0 + INTEGER(IntKi), PARAMETER :: Time = 0 ! Wind Motions: - INTEGER(IntKi), PARAMETER :: Wind1VelX = 1 - INTEGER(IntKi), PARAMETER :: Wind1VelY = 2 - INTEGER(IntKi), PARAMETER :: Wind1VelZ = 3 - INTEGER(IntKi), PARAMETER :: Wind2VelX = 4 - INTEGER(IntKi), PARAMETER :: Wind2VelY = 5 - INTEGER(IntKi), PARAMETER :: Wind2VelZ = 6 - INTEGER(IntKi), PARAMETER :: Wind3VelX = 7 - INTEGER(IntKi), PARAMETER :: Wind3VelY = 8 - INTEGER(IntKi), PARAMETER :: Wind3VelZ = 9 - INTEGER(IntKi), PARAMETER :: Wind4VelX = 10 - INTEGER(IntKi), PARAMETER :: Wind4VelY = 11 - INTEGER(IntKi), PARAMETER :: Wind4VelZ = 12 - INTEGER(IntKi), PARAMETER :: Wind5VelX = 13 - INTEGER(IntKi), PARAMETER :: Wind5VelY = 14 - INTEGER(IntKi), PARAMETER :: Wind5VelZ = 15 - INTEGER(IntKi), PARAMETER :: Wind6VelX = 16 - INTEGER(IntKi), PARAMETER :: Wind6VelY = 17 - INTEGER(IntKi), PARAMETER :: Wind6VelZ = 18 - INTEGER(IntKi), PARAMETER :: Wind7VelX = 19 - INTEGER(IntKi), PARAMETER :: Wind7VelY = 20 - INTEGER(IntKi), PARAMETER :: Wind7VelZ = 21 - INTEGER(IntKi), PARAMETER :: Wind8VelX = 22 - INTEGER(IntKi), PARAMETER :: Wind8VelY = 23 - INTEGER(IntKi), PARAMETER :: Wind8VelZ = 24 - INTEGER(IntKi), PARAMETER :: Wind9VelX = 25 - INTEGER(IntKi), PARAMETER :: Wind9VelY = 26 - INTEGER(IntKi), PARAMETER :: Wind9VelZ = 27 + INTEGER(IntKi), PARAMETER :: Wind1VelX = 1 + INTEGER(IntKi), PARAMETER :: Wind1VelY = 2 + INTEGER(IntKi), PARAMETER :: Wind1VelZ = 3 + INTEGER(IntKi), PARAMETER :: Wind2VelX = 4 + INTEGER(IntKi), PARAMETER :: Wind2VelY = 5 + INTEGER(IntKi), PARAMETER :: Wind2VelZ = 6 + INTEGER(IntKi), PARAMETER :: Wind3VelX = 7 + INTEGER(IntKi), PARAMETER :: Wind3VelY = 8 + INTEGER(IntKi), PARAMETER :: Wind3VelZ = 9 + INTEGER(IntKi), PARAMETER :: Wind4VelX = 10 + INTEGER(IntKi), PARAMETER :: Wind4VelY = 11 + INTEGER(IntKi), PARAMETER :: Wind4VelZ = 12 + INTEGER(IntKi), PARAMETER :: Wind5VelX = 13 + INTEGER(IntKi), PARAMETER :: Wind5VelY = 14 + INTEGER(IntKi), PARAMETER :: Wind5VelZ = 15 + INTEGER(IntKi), PARAMETER :: Wind6VelX = 16 + INTEGER(IntKi), PARAMETER :: Wind6VelY = 17 + INTEGER(IntKi), PARAMETER :: Wind6VelZ = 18 + INTEGER(IntKi), PARAMETER :: Wind7VelX = 19 + INTEGER(IntKi), PARAMETER :: Wind7VelY = 20 + INTEGER(IntKi), PARAMETER :: Wind7VelZ = 21 + INTEGER(IntKi), PARAMETER :: Wind8VelX = 22 + INTEGER(IntKi), PARAMETER :: Wind8VelY = 23 + INTEGER(IntKi), PARAMETER :: Wind8VelZ = 24 + INTEGER(IntKi), PARAMETER :: Wind9VelX = 25 + INTEGER(IntKi), PARAMETER :: Wind9VelY = 26 + INTEGER(IntKi), PARAMETER :: Wind9VelZ = 27 + INTEGER(IntKi), PARAMETER :: WindHubVelX = 28 + INTEGER(IntKi), PARAMETER :: WindHubVelY = 29 + INTEGER(IntKi), PARAMETER :: WindHubVelZ = 30 + INTEGER(IntKi), PARAMETER :: WindDiskVelX = 31 + INTEGER(IntKi), PARAMETER :: WindDiskVelY = 32 + INTEGER(IntKi), PARAMETER :: WindDiskVelZ = 33 + + + ! Wind Accelerations: + + INTEGER(IntKi), PARAMETER :: Wind1AccX = 34 + INTEGER(IntKi), PARAMETER :: Wind1AccY = 35 + INTEGER(IntKi), PARAMETER :: Wind1AccZ = 36 + INTEGER(IntKi), PARAMETER :: Wind2AccX = 37 + INTEGER(IntKi), PARAMETER :: Wind2AccY = 38 + INTEGER(IntKi), PARAMETER :: Wind2AccZ = 39 + INTEGER(IntKi), PARAMETER :: Wind3AccX = 40 + INTEGER(IntKi), PARAMETER :: Wind3AccY = 41 + INTEGER(IntKi), PARAMETER :: Wind3AccZ = 42 + INTEGER(IntKi), PARAMETER :: Wind4AccX = 43 + INTEGER(IntKi), PARAMETER :: Wind4AccY = 44 + INTEGER(IntKi), PARAMETER :: Wind4AccZ = 45 + INTEGER(IntKi), PARAMETER :: Wind5AccX = 46 + INTEGER(IntKi), PARAMETER :: Wind5AccY = 47 + INTEGER(IntKi), PARAMETER :: Wind5AccZ = 48 + INTEGER(IntKi), PARAMETER :: Wind6AccX = 49 + INTEGER(IntKi), PARAMETER :: Wind6AccY = 50 + INTEGER(IntKi), PARAMETER :: Wind6AccZ = 51 + INTEGER(IntKi), PARAMETER :: Wind7AccX = 52 + INTEGER(IntKi), PARAMETER :: Wind7AccY = 53 + INTEGER(IntKi), PARAMETER :: Wind7AccZ = 54 + INTEGER(IntKi), PARAMETER :: Wind8AccX = 55 + INTEGER(IntKi), PARAMETER :: Wind8AccY = 56 + INTEGER(IntKi), PARAMETER :: Wind8AccZ = 57 + INTEGER(IntKi), PARAMETER :: Wind9AccX = 58 + INTEGER(IntKi), PARAMETER :: Wind9AccY = 59 + INTEGER(IntKi), PARAMETER :: Wind9AccZ = 60 ! Wind Magnitude and Direction: - INTEGER(IntKi), PARAMETER :: Wind1VelXY = 28 - INTEGER(IntKi), PARAMETER :: Wind2VelXY = 29 - INTEGER(IntKi), PARAMETER :: Wind3VelXY = 30 - INTEGER(IntKi), PARAMETER :: Wind4VelXY = 31 - INTEGER(IntKi), PARAMETER :: Wind5VelXY = 32 - INTEGER(IntKi), PARAMETER :: Wind6VelXY = 33 - INTEGER(IntKi), PARAMETER :: Wind7VelXY = 34 - INTEGER(IntKi), PARAMETER :: Wind8VelXY = 35 - INTEGER(IntKi), PARAMETER :: Wind9VelXY = 36 - INTEGER(IntKi), PARAMETER :: Wind1VelMag = 37 - INTEGER(IntKi), PARAMETER :: Wind2VelMag = 38 - INTEGER(IntKi), PARAMETER :: Wind3VelMag = 39 - INTEGER(IntKi), PARAMETER :: Wind4VelMag = 40 - INTEGER(IntKi), PARAMETER :: Wind5VelMag = 41 - INTEGER(IntKi), PARAMETER :: Wind6VelMag = 42 - INTEGER(IntKi), PARAMETER :: Wind7VelMag = 43 - INTEGER(IntKi), PARAMETER :: Wind8VelMag = 44 - INTEGER(IntKi), PARAMETER :: Wind9VelMag = 45 - INTEGER(IntKi), PARAMETER :: Wind1AngXY = 46 - INTEGER(IntKi), PARAMETER :: Wind2AngXY = 47 - INTEGER(IntKi), PARAMETER :: Wind3AngXY = 48 - INTEGER(IntKi), PARAMETER :: Wind4AngXY = 49 - INTEGER(IntKi), PARAMETER :: Wind5AngXY = 50 - INTEGER(IntKi), PARAMETER :: Wind6AngXY = 51 - INTEGER(IntKi), PARAMETER :: Wind7AngXY = 52 - INTEGER(IntKi), PARAMETER :: Wind8AngXY = 53 - INTEGER(IntKi), PARAMETER :: Wind9AngXY = 54 + INTEGER(IntKi), PARAMETER :: Wind1VelXY = 61 + INTEGER(IntKi), PARAMETER :: Wind2VelXY = 62 + INTEGER(IntKi), PARAMETER :: Wind3VelXY = 63 + INTEGER(IntKi), PARAMETER :: Wind4VelXY = 64 + INTEGER(IntKi), PARAMETER :: Wind5VelXY = 65 + INTEGER(IntKi), PARAMETER :: Wind6VelXY = 66 + INTEGER(IntKi), PARAMETER :: Wind7VelXY = 67 + INTEGER(IntKi), PARAMETER :: Wind8VelXY = 68 + INTEGER(IntKi), PARAMETER :: Wind9VelXY = 69 + INTEGER(IntKi), PARAMETER :: WindHubVelXY = 70 + INTEGER(IntKi), PARAMETER :: WindDiskVelXY = 71 + INTEGER(IntKi), PARAMETER :: Wind1VelMag = 72 + INTEGER(IntKi), PARAMETER :: Wind2VelMag = 73 + INTEGER(IntKi), PARAMETER :: Wind3VelMag = 74 + INTEGER(IntKi), PARAMETER :: Wind4VelMag = 75 + INTEGER(IntKi), PARAMETER :: Wind5VelMag = 76 + INTEGER(IntKi), PARAMETER :: Wind6VelMag = 77 + INTEGER(IntKi), PARAMETER :: Wind7VelMag = 78 + INTEGER(IntKi), PARAMETER :: Wind8VelMag = 79 + INTEGER(IntKi), PARAMETER :: Wind9VelMag = 80 + INTEGER(IntKi), PARAMETER :: WindHubVelMag = 81 + INTEGER(IntKi), PARAMETER :: WindDiskVelMag = 82 + INTEGER(IntKi), PARAMETER :: Wind1AngXY = 83 + INTEGER(IntKi), PARAMETER :: Wind2AngXY = 84 + INTEGER(IntKi), PARAMETER :: Wind3AngXY = 85 + INTEGER(IntKi), PARAMETER :: Wind4AngXY = 86 + INTEGER(IntKi), PARAMETER :: Wind5AngXY = 87 + INTEGER(IntKi), PARAMETER :: Wind6AngXY = 88 + INTEGER(IntKi), PARAMETER :: Wind7AngXY = 89 + INTEGER(IntKi), PARAMETER :: Wind8AngXY = 90 + INTEGER(IntKi), PARAMETER :: Wind9AngXY = 91 + INTEGER(IntKi), PARAMETER :: WindHubAngXY = 92 + INTEGER(IntKi), PARAMETER :: WindDiskAngXY = 93 ! Wind Sensor Measurements: - INTEGER(IntKi), PARAMETER :: WindMeas1 = 55 - INTEGER(IntKi), PARAMETER :: WindMeas2 = 56 - INTEGER(IntKi), PARAMETER :: WindMeas3 = 57 - INTEGER(IntKi), PARAMETER :: WindMeas4 = 58 - INTEGER(IntKi), PARAMETER :: WindMeas5 = 59 + INTEGER(IntKi), PARAMETER :: WindMeas1 = 94 + INTEGER(IntKi), PARAMETER :: WindMeas2 = 95 + INTEGER(IntKi), PARAMETER :: WindMeas3 = 96 + INTEGER(IntKi), PARAMETER :: WindMeas4 = 97 + INTEGER(IntKi), PARAMETER :: WindMeas5 = 98 ! The maximum number of output channels which can be output by the code. - INTEGER(IntKi), PARAMETER :: MaxOutPts = 59 + INTEGER(IntKi), PARAMETER :: MaxOutPts = 98 -!End of code generated by Matlab script +!End of code generated by Matlab script Write_ChckOutLst ! =================================================================================================== INTEGER(IntKi), PARAMETER :: WindMeas(5) = (/ WindMeas1, WindMeas2, WindMeas3, WindMeas4, WindMeas5 /) ! Array of output constants + INTEGER(IntKi), PARAMETER :: WindVelX(9) = (/ Wind1VelX, Wind2VelX, Wind3VelX, Wind4VelX, Wind5VelX, Wind6VelX, Wind7VelX, Wind8VelX, Wind9VelX /) ! Array of output constants INTEGER(IntKi), PARAMETER :: WindVelY(9) = (/ Wind1VelY, Wind2VelY, Wind3VelY, Wind4VelY, Wind5VelY, Wind6VelY, Wind7VelY, Wind8VelY, Wind9VelY /) ! Array of output constants INTEGER(IntKi), PARAMETER :: WindVelZ(9) = (/ Wind1VelZ, Wind2VelZ, Wind3VelZ, Wind4VelZ, Wind5VelZ, Wind6VelZ, Wind7VelZ, Wind8VelZ, Wind9VelZ /) ! Array of output constants - INTEGER(IntKi), PARAMETER :: WindVelXY(9) = (/ Wind1VelXY, Wind2VelXY, Wind3VelXY, Wind4VelXY, Wind5VelXY, Wind6VelXY, Wind7VelXY, Wind8VelXY, Wind9VelXY /) ! Array of output constants + INTEGER(IntKi), PARAMETER :: WindAccX(9) = (/ Wind1AccX, Wind2AccX, Wind3AccX, Wind4AccX, Wind5AccX, Wind6AccX, Wind7AccX, Wind8AccX, Wind9AccX /) ! Array of output constants + INTEGER(IntKi), PARAMETER :: WindAccY(9) = (/ Wind1AccY, Wind2AccY, Wind3AccY, Wind4AccY, Wind5AccY, Wind6AccY, Wind7AccY, Wind8AccY, Wind9AccY /) ! Array of output constants + INTEGER(IntKi), PARAMETER :: WindAccZ(9) = (/ Wind1AccZ, Wind2AccZ, Wind3AccZ, Wind4AccZ, Wind5AccZ, Wind6AccZ, Wind7AccZ, Wind8AccZ, Wind9AccZ /) ! Array of output constants + + + INTEGER(IntKi), PARAMETER :: WindVelXY( 9) = (/ Wind1VelXY, Wind2VelXY, Wind3VelXY, Wind4VelXY, Wind5VelXY, Wind6VelXY, Wind7VelXY, Wind8VelXY, Wind9VelXY /) ! Array of output constants INTEGER(IntKi), PARAMETER :: WindVelMag(9) = (/ Wind1VelMag, Wind2VelMag, Wind3VelMag, Wind4VelMag, Wind5VelMag, Wind6VelMag, Wind7VelMag, Wind8VelMag, Wind9VelMag/) ! Array of output constants - INTEGER(IntKi), PARAMETER :: WindAngXY(9) = (/ Wind1AngXY, Wind2AngXY, Wind3AngXY, Wind4AngXY, Wind5AngXY, Wind6AngXY, Wind7AngXY, Wind8AngXY, Wind9AngXY /) ! Array of output constants + INTEGER(IntKi), PARAMETER :: WindAngXY( 9) = (/ Wind1AngXY, Wind2AngXY, Wind3AngXY, Wind4AngXY, Wind5AngXY, Wind6AngXY, Wind7AngXY, Wind8AngXY, Wind9AngXY /) ! Array of output constants ! =================================================================================================== @@ -183,6 +214,8 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, In CHARACTER(ErrMsgLen) :: TmpErrMsg ! Initialization + InputFileData%VFlowAngle = 0.0 ! default vertical flow angle + ErrStat = ErrID_None ErrMsg = "" InputFileData%EchoFlag = .FALSE. ! initialize for error handling (cleanup() routine) @@ -215,6 +248,10 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, In endif + !------------------------------------------------------------------------------------------------- + !> Read general section with wind type, direction, and output point list (applies to all wind types) + !------------------------------------------------------------------------------------------------- + ! 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, UnEc ) if (Failed()) return @@ -225,6 +262,10 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, In ! VFlowAngle: Upflow angle (deg) CALL ParseVarWDefault( InFileInfo, CurLine, "VFlowAng", InputFileData%VFlowAngle, 0.0_ReKi, TmpErrStat, TmpErrMsg, UnEc ) + if (Failed()) return + + ! VelInterpCubic: Velocity interpolation order in time (1=linear; 3=cubic) [Used with WindType=2,3,4,5,7] + CALL ParseVar( InFileInfo, CurLine, "VelInterpCubic", InputFileData%VelInterpCubic, TmpErrStat, TmpErrMsg, UnEc ) if (Failed()) return ! NWindVel: Number of points to output the wind velocity (0 to 9) @@ -235,6 +276,7 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, In IF ( InputFileData%NWindVel < 0 .OR. InputFileData%NwindVel > 9 ) THEN CALL SetErrStat( ErrID_Fatal, 'NWindVel must be greater than or equal to zero and less than 10.', & ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() RETURN ELSE @@ -438,8 +480,91 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, In if (Failed()) return CALL ParseVarWDefault( InFileInfo, CurLine, "XOffset", InputFileData%FF%XOffset, 0.0_ReKi, TmpErrStat, TmpErrMsg, UnEc ) + if (Failed()) return + + !------------------------------------------------------------------------------------------------- + !> Read the _Parameters for LIDAR section + !------------------------------------------------------------------------------------------------- + + CurLine = CurLine + 1 ! Skip section break + + ! LIDAR Sensor Type + CALL ParseVar( InFileInfo, CurLine, "SensorType", InputFileData%SensorType, TmpErrStat, TmpErrMsg, UnEc ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (Failed()) RETURN + + ! Number of Range Gates + CALL ParseVar( InFileInfo, CurLine, "NumPulseGate", InputFileData%NumPulseGate, TmpErrStat, TmpErrMsg, UnEc ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (Failed()) RETURN + + ! Pulse Gate Spacing + CALL ParseVar( InFileInfo, CurLine, "PulseSpacing", InputFileData%PulseSpacing, TmpErrStat, TmpErrMsg, UnEc ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (Failed()) RETURN + + ! NumBeam: Number of points to output the lidar measured wind velocity (1 to 5) + CALL ParseVar( InFileInfo, CurLine, "NumBeam", InputFileData%NumBeam, TmpErrStat, TmpErrMsg, UnEc ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) if (Failed()) return + ! Before proceeding, make sure that NumBeam makes sense + IF ((InputFileData%SensorType == 1) .and. (InputFileData%NumBeam < 1 .OR. InputFileData%NumBeam > 5)) THEN + CALL SetErrStat( ErrID_Fatal, 'NumBeam must be greater than or equal to one and less than 6.', & + ErrStat, ErrMsg, RoutineName ) + RETURN + ELSE + ! Allocate space for the output location arrays: + CALL AllocAry( InputFileData%FocalDistanceX, InputFileData%NumBeam, 'NumBeam', TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + CALL AllocAry( InputFileData%FocalDistanceY, InputFileData%NumBeam, 'NumBeam', TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + CALL AllocAry( InputFileData%FocalDistanceZ, InputFileData%NumBeam, 'NumBeam', TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return + ENDIF + + ! Focal Distance X + CALL ParseAry( InFileInfo, CurLine, 'FocalDistanceX', InputFileData%FocalDistanceX, InputFileData%NumBeam, TmpErrStat, TmpErrMsg, UnEc ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return + + ! Focal Distance Y + CALL ParseAry( InFileInfo, CurLine, 'FocalDistanceY', InputFileData%FocalDistanceY, InputFileData%NumBeam, TmpErrStat, TmpErrMsg, UnEc ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return + + ! Focal Distance Z + CALL ParseAry( InFileInfo, CurLine, 'FocalDistanceZ', InputFileData%FocalDistanceZ, InputFileData%NumBeam, TmpErrStat, TmpErrMsg, UnEc ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + if (Failed()) return + + ! Rotor Apex Offset Position + CALL ParseAry( InFileInfo, CurLine, "RotorApexOffsetPos", InputFileData%RotorApexOffsetPos, 1, TmpErrStat, TmpErrMsg, UnEc ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (Failed()) RETURN + + ! URefIni + CALL ParseVar( InFileInfo, CurLine, "URefLid", InputFileData%URefLid, TmpErrStat, TmpErrMsg, UnEc ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (Failed()) RETURN + + ! Measurement Interval + CALL ParseVar( InFileInfo, CurLine, "MeasurementInterval", InputFileData%MeasurementInterval, TmpErrStat, TmpErrMsg, UnEc ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (Failed()) RETURN + + ! Lidar Radial Vel + CALL ParseLoVar( InFileInfo, CurLine, "LidRadialVel", InputFileData%LidRadialVel, TmpErrStat, TmpErrMsg, UnEc ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (Failed()) RETURN + + ! Consider Hub Motion + CALL ParseVar( InFileInfo, CurLine, "ConsiderHubMotion", InputFileData%ConsiderHubMotion, TmpErrStat, TmpErrMsg, UnEc ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF (Failed()) RETURN + + !---------------------------------------------------------------------------------------------- !> Read the _OUTPUT_ subsection !---------------------------------------------------------------------------------------------- @@ -449,25 +574,31 @@ SUBROUTINE InflowWind_ParseInputFileInfo( InputFileData, InFileInfo, PriPath, In !---------------------- OUTLIST -------------------------------------------- CurLine = CurLine + 1 ! Skip comment line - CALL ReadOutputListFromFileInfo( InFileInfo, CurLine, InputFileData%OutList, & - InputFileData%NumOuts, "OutList", "List of user-requested output channels", TmpErrStat, TmpErrMsg, UnEc ) + CALL ReadOutputListFromFileInfo( InFileInfo, CurLine, InputFileData%OutList, InputFileData%NumOuts, TmpErrStat, TmpErrMsg, UnEc ) if (Failed()) return !------------------------------------------------------------------------------------------------- ! This is the end of the input file !------------------------------------------------------------------------------------------------- + CALL Cleanup() + 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 + if (Failed) CALL Cleanup() end function Failed - END SUBROUTINE InflowWind_ParseInputFileInfo + + !.............................. + SUBROUTINE Cleanup() + if (UnEc > -1_IntKi) CLOSE( UnEc ) + END SUBROUTINE Cleanup + +END SUBROUTINE InflowWind_ParseInputFileInfo + !==================================================================================================== !> This private subroutine verifies the input required for InflowWind is correctly specified. This @@ -548,12 +679,25 @@ SUBROUTINE InflowWind_ValidateInput( InitInp, InputFileData, ErrStat, ErrMsg ) ! make sure that all values for WindVzi are above ground. Set to 0 otherwise. + IF ( InitInp%MHK == 1 .or. InitInp%MHK == 2 ) THEN + DO I = 1, InputFileData%NWindVel + IF ( InputFileData%WindVziList(I) >= InitInp%WtrDpth + InitInp%MSL2SWL ) THEN + CALL SetErrStat( ErrID_Warn, ' Requested wind velocity at point ( '// & + TRIM(Num2LStr(InputFileData%WindVxiList(I)))//', '// & + TRIM(Num2LStr(InputFileData%WindVyiList(I)))//', '// & + TRIM(Num2LStr(InputFileData%WindVziList(I)))//') is above MSL. Ignoring this point.', & + ErrStat, ErrMsg, RoutineName) + InputFileData%WindVziList(I) = 0.0_ReKi + ENDIF + ENDDO + ENDIF + DO I = 1, InputFileData%NWindVel IF ( InputFileData%WindVziList(I) <= 0.0_ReKi ) THEN CALL SetErrStat( ErrID_Warn, ' Requested wind velocity at point ( '// & TRIM(Num2LStr(InputFileData%WindVxiList(I)))//', '// & TRIM(Num2LStr(InputFileData%WindVyiList(I)))//', '// & - TRIM(Num2LStr(InputFileData%WindVziList(I)))//') is below ground. Ignoring this point.', & + TRIM(Num2LStr(InputFileData%WindVziList(I)))//') is below ground (wind turbine) or below seabed (MHK turbine). Ignoring this point.', & ErrStat, ErrMsg, RoutineName) InputFileData%WindVziList(I) = 0.0_ReKi ENDIF @@ -570,7 +714,6 @@ SUBROUTINE InflowWind_ValidateInput( InitInp, InputFileData, ErrStat, ErrMsg ) CALL Steady_ValidateInput() CASE ( Uniform_WindNumber ) - IF ( InitInp%WindType2UseInputFile ) CALL Uniform_ValidateInput() CASE ( TSFF_WindNumber ) @@ -814,7 +957,7 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM ! Passed variables TYPE(InflowWind_InitInputType), INTENT(IN ) :: InitInp !< Input data for initialization - TYPE(InflowWind_InputFile), INTENT(INOUT) :: InputFileData !< The data for initialization + TYPE(InflowWind_InputFile), INTENT(IN ) :: InputFileData !< The data for initialization TYPE(InflowWind_ParameterType), INTENT(INOUT) :: p !< The parameters for InflowWind TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< The misc/optimization variables for InflowWind INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status from this subroutine @@ -827,6 +970,8 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM ! Local variables INTEGER(IntKi) :: I !< Generic counter + REAL(ReKi) :: theta + REAL(ReKi) :: R ! radius ! Initialize ErrStat @@ -838,24 +983,19 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM !----------------------------------------------------------------- ! Copy over the general information that applies to everything !----------------------------------------------------------------- - p%CTTS_Flag = .FALSE. ! Copy the WindType over. - p%WindType = InputFileData%WindType - ! Convert the PropagationDir to radians and store this. For simplicity, we will shift it to be between -pi and pi + p%FlowField%PropagationDir = D2R * InputFileData%PropagationDir + CALL MPi2Pi( p%FlowField%PropagationDir ) ! Shift if necessary so that the value is between -pi and pi - p%PropagationDir = D2R * InputFileData%PropagationDir - CALL MPi2Pi( p%PropagationDir ) ! Shift if necessary so that the value is between -pi and pi - - p%VFlowAngle = D2R * InputFileData%VFlowAngle + p%FlowField%VFlowAngle = D2R * InputFileData%VFlowAngle ! Copy over the list of wind coordinates. Move the arrays to the new one. p%NWindVel = InputFileData%NWindVel - CALL AllocAry( p%WindViXYZ, 3, p%NWindVel, & - "XYZ coordinates of the requested wind points.", TmpErrStat, TmpErrMsg ) + CALL AllocAry( p%WindViXYZ, 3, p%NWindVel, "XYZ coordinates of the requested wind points.", TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -871,12 +1011,48 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM ! Allocate array used for calculating the AllOuts values. This has a total of nine 3d velocity vectors ! in it (one for each of the possible WindViXYZ points). This gets passed into CalcOutput at each timestep, ! although only the first NWindVel velocity vectors gets calculated. - CALL AllocAry( m%WindViUVW, 3, p%NWindVel, & - "Array of wind velocities corresponding to the WindViLists", TmpErrStat, TmpErrMsg ) + CALL AllocAry( m%WindViUVW, 3, p%NWindVel, "Array of wind velocities corresponding to the WindViLists", TmpErrStat, TmpErrMsg ) CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) IF ( ErrStat>= AbortErrLev ) RETURN m%WindViUVW = 0.0_ReKi + ! If output acceleration flag is set, allocate array to hold wind point accelerations. + IF (InitInp%OutputAccel) THEN + CALL AllocAry( m%WindAiUVW, 3, p%NWindVel, "Array of wind accelerations corresponding to the WindViLists", TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat>= AbortErrLev ) RETURN + m%WindAiUVW = 0.0_ReKi + END IF + + CALL AllocAry( m%u_Hub%PositionXYZ, 3, 1, "Array of positions for hub values", TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + CALL AllocAry( m%y_Hub%VelocityUVW, 3, 1, "Array of velocities for hub values", TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + + CALL AllocAry( m%u_Avg%PositionXYZ, 3, IfW_NumPtsAvg, "Array of positions for rotor-averaged values", TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + CALL AllocAry( m%y_Avg%VelocityUVW, 3, IfW_NumPtsAvg, "Array of velocities for rotor-averaged values", TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + CALL AllocAry( p%PositionAvg, 3, IfW_NumPtsAvg, "Array of positions for computing average wind speed", TmpErrStat, TmpErrMsg ) + CALL SetErrStat(TmpErrStat,TmpErrMsg,ErrStat,ErrMsg,RoutineName) + IF ( ErrStat>= AbortErrLev ) RETURN + + + if (InitInp%RadAvg < 0.0_ReKi) then + R = max(1.0_ReKi, InputFileData%Uniform_RefLength)/2.0_ReKi ! We'll use this as a guess for the rotor radius + else + R = InitInp%RadAvg + end if + R = R * 0.7_ReKi !70% radius + + do i=1,IfW_NumPtsAvg + theta = pi +(i-1)*TwoPi/IfW_NumPtsAvg + p%PositionAvg(1,i) = R*cos(theta) + p%PositionAvg(2,i) = R*sin(theta) + p%PositionAvg(3,i) = 0.0_ReKi + end do + + p%OutputAccel = InitInp%OutputAccel ! Set the OutList CALL SetOutParam( InputFileData%OutList, p, TmpErrStat, TmpErrmsg ) @@ -952,9 +1128,15 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM ! Create the rotation matrices -- rotate from XYZ to X'Y'Z' (wind aligned along X) coordinates ! Included in this rotation is the wind upflow (inclination) angle (rotation about Y axis) - p%RotToWind(1,:) = (/ COS(-p%VFlowAngle) * COS(-p%PropagationDir), COS(-p%VFlowAngle) * SIN(-p%PropagationDir), -SIN(-p%VFlowAngle) /) - p%RotToWind(2,:) = (/ -SIN(-p%PropagationDir), COS(-p%PropagationDir), 0.0_ReKi /) - p%RotToWind(3,:) = (/ SIN(-p%VFlowAngle) * COS(-p%PropagationDir), SIN(-p%VFlowAngle) * SIN(-p%PropagationDir), COS(-p%VFlowAngle) /) + p%FlowField%RotToWind(1,:) = [ COS(-p%FlowField%VFlowAngle) * COS(-p%FlowField%PropagationDir), & + COS(-p%FlowField%VFlowAngle) * SIN(-p%FlowField%PropagationDir), & + -SIN(-p%FlowField%VFlowAngle) ] + p%FlowField%RotToWind(2,:) = [ -SIN(-p%FlowField%PropagationDir), & + COS(-p%FlowField%PropagationDir), & + 0.0_ReKi ] + p%FlowField%RotToWind(3,:) = [ SIN(-p%FlowField%VFlowAngle) * COS(-p%FlowField%PropagationDir), & + SIN(-p%FlowField%VFlowAngle) * SIN(-p%FlowField%PropagationDir), & + COS(-p%FlowField%VFlowAngle) ] ! Create the rotation matrices -- rotate from X'Y'Z' (wind aligned along X) to global XYZ coordinates: this is the same as a ! rotation about the (positive) upflow angle multiplied by a rotation about the (positive) wind direction: @@ -962,23 +1144,21 @@ SUBROUTINE InflowWind_SetParameters( InitInp, InputFileData, p, m, ErrStat, ErrM ! loal wind = R( -p%VFlowAngle) * R (-p%PropagationDir) [global wind] ! = R^T(p%VFlowAngle) * R^T(p%PropagationDir) [global wind] ! = (R(p%PropagationDir) * R(p%VFlowAngle))^T [global wind] - p%RotFromWind = TRANSPOSE(p%RotToWind) + p%FlowField%RotFromWind = TRANSPOSE(p%FlowField%RotToWind) ! Create the array used for holding the rotated list of WindViXYZ coordinates in the wind reference frame, and populate it CALL AllocAry( p%WindViXYZprime, 3, p%NWindVel, 'Array for WindViXYZ coordinates in the wind reference frame', & TmpErrStat, TmpErrMsg ) CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) IF ( ErrStat>= AbortErrLev ) RETURN - - p%RefPosition = (/ 0.0_ReKi, 0.0_ReKi, p%ReferenceHeight /) - + p%WindViXYZprime = 0.0_ReKi ! set the output points. Note rotation is about the hub height at [0 0 H]. See InflowWind_SetParameters for details. DO I = 1,p%NWindVel - p%WindViXYZprime(:,I) = MATMUL( p%RotToWind, (p%WindViXYZ(:,I) - p%RefPosition )) + p%RefPosition + p%WindViXYZprime(:,I) = MATMUL( p%FlowField%RotToWind, (p%WindViXYZ(:,I) - p%FlowField%RefPosition )) + p%FlowField%RefPosition ENDDO - p%RotateWindBox = .not. (EqualRealNos (p%PropagationDir, 0.0_ReKi) .AND. EqualRealNos (p%VFlowAngle, 0.0_ReKi)) + p%FlowField%RotateWindBox = .not. (EqualRealNos (p%FlowField%PropagationDir, 0.0_ReKi) .AND. EqualRealNos (p%FlowField%VFlowAngle, 0.0_ReKi)) END SUBROUTINE InflowWind_SetParameters @@ -999,15 +1179,15 @@ END SUBROUTINE InflowWind_SetParameters !! the sign is set to 0 if the channel is invalid. !! It sets assumes the value p%NumOuts has been set before this routine has been called, and it sets the values of p%OutParam here. !! -!! This routine was generated by Write_ChckOutLst.m using the parameters listed in OutListParameters.xlsx at 26-Oct-2020 15:42:27. +!! This routine was generated by Write_ChckOutLst.m using the parameters listed in OutListParameters.xlsx at 29-Jul-2022 19:48:39. SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) !.................................................................................................................................. - IMPLICIT NONE + IMPLICIT NONE ! Passed variables - CHARACTER(ChanLen), INTENT(IN) :: OutList(:) !< The list out user-requested outputs + CHARACTER(ChanLen), INTENT(IN) :: OutList(:) !< The list of user-requested outputs TYPE(InflowWind_ParameterType), INTENT(INOUT) :: p !< The module parameters INTEGER(IntKi), INTENT(OUT) :: ErrStat !< The error status code CHARACTER(*), INTENT(OUT) :: ErrMsg !< The error message, if an error occurred @@ -1016,7 +1196,6 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) INTEGER :: ErrStat2 ! temporary (local) error status INTEGER :: I ! Generic loop-counting index - INTEGER :: J ! Generic loop-counting index INTEGER :: INDX ! Index for valid arrays LOGICAL :: CheckOutListAgain ! Flag used to determine if output parameter starting with "M" is valid (or the negative of another parameter) @@ -1024,38 +1203,72 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I) CHARACTER(*), PARAMETER :: RoutineName = "SetOutParam" - CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(59) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically - "WIND1ANGXY ","WIND1VELMAG","WIND1VELX ","WIND1VELXY ","WIND1VELY ","WIND1VELZ ","WIND2ANGXY ", & - "WIND2VELMAG","WIND2VELX ","WIND2VELXY ","WIND2VELY ","WIND2VELZ ","WIND3ANGXY ","WIND3VELMAG", & - "WIND3VELX ","WIND3VELXY ","WIND3VELY ","WIND3VELZ ","WIND4ANGXY ","WIND4VELMAG","WIND4VELX ", & - "WIND4VELXY ","WIND4VELY ","WIND4VELZ ","WIND5ANGXY ","WIND5VELMAG","WIND5VELX ","WIND5VELXY ", & - "WIND5VELY ","WIND5VELZ ","WIND6ANGXY ","WIND6VELMAG","WIND6VELX ","WIND6VELXY ","WIND6VELY ", & - "WIND6VELZ ","WIND7ANGXY ","WIND7VELMAG","WIND7VELX ","WIND7VELXY ","WIND7VELY ","WIND7VELZ ", & - "WIND8ANGXY ","WIND8VELMAG","WIND8VELX ","WIND8VELXY ","WIND8VELY ","WIND8VELZ ","WIND9ANGXY ", & - "WIND9VELMAG","WIND9VELX ","WIND9VELXY ","WIND9VELY ","WIND9VELZ ","WINDMEAS1 ","WINDMEAS2 ", & - "WINDMEAS3 ","WINDMEAS4 ","WINDMEAS5 "/) - INTEGER(IntKi), PARAMETER :: ParamIndxAry(59) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) - Wind1AngXY , Wind1VelMag , Wind1VelX , Wind1VelXY , Wind1VelY , Wind1VelZ , Wind2AngXY , & - Wind2VelMag , Wind2VelX , Wind2VelXY , Wind2VelY , Wind2VelZ , Wind3AngXY , Wind3VelMag , & - Wind3VelX , Wind3VelXY , Wind3VelY , Wind3VelZ , Wind4AngXY , Wind4VelMag , Wind4VelX , & - Wind4VelXY , Wind4VelY , Wind4VelZ , Wind5AngXY , Wind5VelMag , Wind5VelX , Wind5VelXY , & - Wind5VelY , Wind5VelZ , Wind6AngXY , Wind6VelMag , Wind6VelX , Wind6VelXY , Wind6VelY , & - Wind6VelZ , Wind7AngXY , Wind7VelMag , Wind7VelX , Wind7VelXY , Wind7VelY , Wind7VelZ , & - Wind8AngXY , Wind8VelMag , Wind8VelX , Wind8VelXY , Wind8VelY , Wind8VelZ , Wind9AngXY , & - Wind9VelMag , Wind9VelX , Wind9VelXY , Wind9VelY , Wind9VelZ , WindMeas1 , WindMeas2 , & - WindMeas3 , WindMeas4 , WindMeas5 /) - CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(59) = (/ & ! This lists the units corresponding to the allowed parameters - "(deg)","(m/s)","(m/s)","(m/s)","(m/s)","(m/s)","(deg)", & - "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)","(deg)","(m/s)", & - "(m/s)","(m/s)","(m/s)","(m/s)","(deg)","(m/s)","(m/s)", & - "(m/s)","(m/s)","(m/s)","(deg)","(m/s)","(m/s)","(m/s)", & - "(m/s)","(m/s)","(deg)","(m/s)","(m/s)","(m/s)","(m/s)", & - "(m/s)","(deg)","(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & - "(deg)","(m/s)","(m/s)","(m/s)","(m/s)","(m/s)","(deg)", & - "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(98) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + "WIND1ACCX ","WIND1ACCY ","WIND1ACCZ ","WIND1ANGXY ","WIND1VELMAG ", & + "WIND1VELX ","WIND1VELXY ","WIND1VELY ","WIND1VELZ ","WIND2ACCX ", & + "WIND2ACCY ","WIND2ACCZ ","WIND2ANGXY ","WIND2VELMAG ","WIND2VELX ", & + "WIND2VELXY ","WIND2VELY ","WIND2VELZ ","WIND3ACCX ","WIND3ACCY ", & + "WIND3ACCZ ","WIND3ANGXY ","WIND3VELMAG ","WIND3VELX ","WIND3VELXY ", & + "WIND3VELY ","WIND3VELZ ","WIND4ACCX ","WIND4ACCY ","WIND4ACCZ ", & + "WIND4ANGXY ","WIND4VELMAG ","WIND4VELX ","WIND4VELXY ","WIND4VELY ", & + "WIND4VELZ ","WIND5ACCX ","WIND5ACCY ","WIND5ACCZ ","WIND5ANGXY ", & + "WIND5VELMAG ","WIND5VELX ","WIND5VELXY ","WIND5VELY ","WIND5VELZ ", & + "WIND6ACCX ","WIND6ACCY ","WIND6ACCZ ","WIND6ANGXY ","WIND6VELMAG ", & + "WIND6VELX ","WIND6VELXY ","WIND6VELY ","WIND6VELZ ","WIND7ACCX ", & + "WIND7ACCY ","WIND7ACCZ ","WIND7ANGXY ","WIND7VELMAG ","WIND7VELX ", & + "WIND7VELXY ","WIND7VELY ","WIND7VELZ ","WIND8ACCX ","WIND8ACCY ", & + "WIND8ACCZ ","WIND8ANGXY ","WIND8VELMAG ","WIND8VELX ","WIND8VELXY ", & + "WIND8VELY ","WIND8VELZ ","WIND9ACCX ","WIND9ACCY ","WIND9ACCZ ", & + "WIND9ANGXY ","WIND9VELMAG ","WIND9VELX ","WIND9VELXY ","WIND9VELY ", & + "WIND9VELZ ","WINDDISKANGXY ","WINDDISKVELMAG","WINDDISKVELX ","WINDDISKVELXY ", & + "WINDDISKVELY ","WINDDISKVELZ ","WINDHUBANGXY ","WINDHUBVELMAG ","WINDHUBVELX ", & + "WINDHUBVELXY ","WINDHUBVELY ","WINDHUBVELZ ","WINDMEAS1 ","WINDMEAS2 ", & + "WINDMEAS3 ","WINDMEAS4 ","WINDMEAS5 "/) + + INTEGER(IntKi), PARAMETER :: ParamIndxAry(98) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + Wind1AccX , Wind1AccY , Wind1AccZ , Wind1AngXY , Wind1VelMag , & + Wind1VelX , Wind1VelXY , Wind1VelY , Wind1VelZ , Wind2AccX , & + Wind2AccY , Wind2AccZ , Wind2AngXY , Wind2VelMag , Wind2VelX , & + Wind2VelXY , Wind2VelY , Wind2VelZ , Wind3AccX , Wind3AccY , & + Wind3AccZ , Wind3AngXY , Wind3VelMag , Wind3VelX , Wind3VelXY , & + Wind3VelY , Wind3VelZ , Wind4AccX , Wind4AccY , Wind4AccZ , & + Wind4AngXY , Wind4VelMag , Wind4VelX , Wind4VelXY , Wind4VelY , & + Wind4VelZ , Wind5AccX , Wind5AccY , Wind5AccZ , Wind5AngXY , & + Wind5VelMag , Wind5VelX , Wind5VelXY , Wind5VelY , Wind5VelZ , & + Wind6AccX , Wind6AccY , Wind6AccZ , Wind6AngXY , Wind6VelMag , & + Wind6VelX , Wind6VelXY , Wind6VelY , Wind6VelZ , Wind7AccX , & + Wind7AccY , Wind7AccZ , Wind7AngXY , Wind7VelMag , Wind7VelX , & + Wind7VelXY , Wind7VelY , Wind7VelZ , Wind8AccX , Wind8AccY , & + Wind8AccZ , Wind8AngXY , Wind8VelMag , Wind8VelX , Wind8VelXY , & + Wind8VelY , Wind8VelZ , Wind9AccX , Wind9AccY , Wind9AccZ , & + Wind9AngXY , Wind9VelMag , Wind9VelX , Wind9VelXY , Wind9VelY , & + Wind9VelZ , WindDiskAngXY , WindDiskVelMag , WindDiskVelX , WindDiskVelXY , & + WindDiskVelY , WindDiskVelZ , WindHubAngXY , WindHubVelMag , WindHubVelX , & + WindHubVelXY , WindHubVelY , WindHubVelZ , WindMeas1 , WindMeas2 , & + WindMeas3 , WindMeas4 , WindMeas5 /) + + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(98) = (/ character(ChanLen) :: & ! This lists the units corresponding to the allowed parameters + "(m/s)","(m/s)","(m/s)","(deg)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(deg)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(deg)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(deg)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(deg)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(deg)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(deg)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(deg)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(deg)","(m/s)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(deg)","(m/s)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(deg)","(m/s)","(m/s)", & + "(m/s)","(m/s)","(m/s)","(m/s)","(m/s)", & "(m/s)","(m/s)","(m/s)"/) - ! Initialize values ErrStat = ErrID_None ErrMsg = "" @@ -1071,14 +1284,30 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) InvalidOutput( WindVelX( I) ) = .TRUE. InvalidOutput( WindVelY( I) ) = .TRUE. InvalidOutput( WindVelZ( I) ) = .TRUE. + InvalidOutput( WindAccX( I) ) = .TRUE. + InvalidOutput( WindAccY( I) ) = .TRUE. + InvalidOutput( WindAccZ( I) ) = .TRUE. InvalidOutput( WindVelXY( I) ) = .TRUE. InvalidOutput( WindVelMag(I) ) = .TRUE. InvalidOutput( WindAngXY( I) ) = .TRUE. END DO - - DO I=p%lidar%NumPulseGate+1,5 - InvalidOutput( WindMeas(I) ) = .TRUE. - END DO + + ! Set all accelerations invalid if not requested + if (.not. p%OutputAccel) then + InvalidOutput(WindAccX) = .TRUE. + InvalidOutput(WindAccY) = .TRUE. + InvalidOutput(WindAccZ) = .TRUE. + end if + + IF (p%lidar%SensorType == SensorType_SinglePoint) THEN + DO I=p%lidar%NumBeam+1,5 + InvalidOutput( WindMeas(I) ) = .TRUE. + END DO + ELSE + DO I=p%lidar%NumPulseGate+1,5 + InvalidOutput( WindMeas(I) ) = .TRUE. + END DO + END IF ! ................. End of validity checking ................. @@ -1212,10 +1441,13 @@ SUBROUTINE SetOutParamLin( p, ErrStat, ErrMsg ) p%OutParamLinIndx(1,i) = j p%OutParamLinIndx(2,i) = 3 exit !exit j loop; move to next parameter + else !bjj: initialize this in case we have the new outputs that aren't just X-Y-Z velocities. CHECK THIS!!! + p%OutParamLinIndx(1,i) = 0 + p%OutParamLinIndx(2,i) = 0 end if end do - end if + end if end do @@ -1243,6 +1475,8 @@ SUBROUTINE SetAllOuts( p, y, m, ErrStat, ErrMsg ) ! Initialization ErrStat = ErrID_None ErrMsg = '' + + if (p%NumOuts < 1) return ! We set the unused values to 0 at init, so we don't need to set them again here: DO I = 1,p%NWindVel @@ -1258,15 +1492,54 @@ SUBROUTINE SetAllOuts( p, y, m, ErrStat, ErrMsg ) else m%AllOuts( WindAngXY(I) ) = ATAN2( m%WindViUVW(2,I), m%WindViUVW(1,I) )*R2D ! in degrees end if -! m%AllOuts( WindAngVer(I) ) = ATAN2( m%WindViUVW(3,I), m%AllOuts( WindVelXY(I) ) )*R2D ! in degrees END DO + + ! Set accelerations + if (allocated(m%WindAiUVW)) then + DO I = 1,p%NWindVel + m%AllOuts( WindAccX(I) ) = m%WindAiUVW(1,I) + m%AllOuts( WindAccY(I) ) = m%WindAiUVW(2,I) + m%AllOuts( WindAccZ(I) ) = m%WindAiUVW(3,I) + END DO + end if + + ! DiskVel outputs: + m%AllOuts( WindDiskVelX ) = y%DiskVel(1) + m%AllOuts( WindDiskVelY ) = y%DiskVel(2) + m%AllOuts( WindDiskVelZ ) = y%DiskVel(3) + m%AllOuts( WindDiskVelXY ) = SQRT( y%DiskVel(1)**2 + y%DiskVel(2)**2 ) + m%AllOuts( WindDiskVelMag ) = TwoNorm(y%DiskVel) + if ( m%AllOuts( WindDiskVelXY ) == 0.0_ReKi) then + m%AllOuts( WindDiskAngXY ) = 0.0_ReKi + else + m%AllOuts( WindDiskAngXY ) = ATAN2( y%DiskVel(2), y%DiskVel(1) )*R2D ! in degrees + end if + + ! DiskVel outputs: + m%AllOuts( WindHubVelX ) = y%HubVel(1) + m%AllOuts( WindHubVelY ) = y%HubVel(2) + m%AllOuts( WindHubVelZ ) = y%HubVel(3) + m%AllOuts( WindHubVelXY ) = SQRT( y%HubVel(1)**2 + y%HubVel(2)**2 ) + m%AllOuts( WindHubVelMag ) = TwoNorm(y%HubVel) + if ( m%AllOuts( WindHubVelXY ) == 0.0_ReKi) then + m%AllOuts( WindHubAngXY ) = 0.0_ReKi + else + m%AllOuts( WindHubAngXY ) = ATAN2( y%HubVel(2), y%HubVel(1) )*R2D ! in degrees + end if + !FIXME: Add in Wind1Dir etc. -- although those can be derived outside of FAST. - DO I = 1,MIN(5, p%lidar%NumPulseGate ) - m%AllOuts( WindMeas(I) ) = y%lidar%lidSpeed(I) - END DO +IF ( p%lidar%SensorType == SensorType_SinglePoint) THEN + DO I = 1,MIN(5, p%lidar%NumBeam ) + m%AllOuts( WindMeas(I) ) = y%lidar%LidSpeed(I) + END DO + ELSE + DO I = 1,MIN(5, p%lidar%NumPulseGate ) + m%AllOuts( WindMeas(I) ) = y%lidar%LidSpeed(I) + END DO + END IF END SUBROUTINE SetAllOuts @@ -1351,300 +1624,166 @@ END SUBROUTINE InflowWind_CloseSumFile SUBROUTINE CalculateOutput( Time, InputData, p, x, xd, z, OtherStates, y, m, FillWrOut, ErrStat, ErrMsg ) + REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds + TYPE(InflowWind_InputType), INTENT(IN ) :: InputData !< Inputs at Time + TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(InflowWind_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time + TYPE(InflowWind_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at Time + TYPE(InflowWind_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at Time + TYPE(InflowWind_OtherStateType), INTENT(IN ) :: OtherStates !< Other states at Time + TYPE(InflowWind_OutputType), INTENT(INOUT) :: y !< Outputs computed at Time (IN for mesh reasons and data allocation) + TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< misc/optimization variables + LOGICAL, INTENT(IN ) :: FillWrOut !< Flag to determine if we need to fill WriteOutput values + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + CHARACTER(*), PARAMETER :: RoutineName="CalculateOutput" + + ! Temporary variables for error handling + INTEGER(IntKi) :: TmpErrStat + CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message + + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + + ! Get velocities and accelerations for the given positions + CALL IfW_FlowField_GetVelAcc(p%FlowField, 0, Time, InputData%PositionXYZ, & + y%VelocityUVW, y%AccelUVW, TmpErrStat, TmpErrMsg) + CALL SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) + IF ( ErrStat >= AbortErrLev) RETURN + + ! Get velocities and accelerations for OutList variables, no error check + IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN + CALL IfW_FlowField_GetVelAcc(p%FlowField, 0, Time, p%WindViXYZ, & + m%WindViUVW, m%WindAiUVW, TmpErrStat, TmpErrMsg) + ENDIF - IMPLICIT NONE - - CHARACTER(*), PARAMETER :: RoutineName="CalcOutput" - - - ! Inputs / Outputs - - REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds - TYPE(InflowWind_InputType), INTENT(IN ) :: InputData !< Inputs at Time - TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters - TYPE(InflowWind_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time - TYPE(InflowWind_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at Time - TYPE(InflowWind_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at Time - TYPE(InflowWind_OtherStateType), INTENT(IN ) :: OtherStates !< Other states at Time - TYPE(InflowWind_OutputType), INTENT(INOUT) :: y !< Outputs computed at Time (IN for mesh reasons and data allocation) - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< misc/optimization variables - LOGICAL, INTENT(IN ) :: FillWrOut !< Flag to determine if we need to fill WriteOutput values - - INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - - - ! Local variables - REAL(ReKi), ALLOCATABLE :: PositionXYZprime(:,:) !< PositionXYZ array in the prime (wind) coordinates - REAL(ReKi) :: DiskVel(3) !< HACK for AD14: disk velocity output at Time - - INTEGER(IntKi) :: I !< Generic counters - - - ! Temporary variables for error handling - INTEGER(IntKi) :: TmpErrStat - CHARACTER(ErrMsgLen) :: TmpErrMsg ! temporary error message - - - - ! Initialize ErrStat - ErrStat = ErrID_None - ErrMsg = "" +END SUBROUTINE CalculateOutput + +!==================================================================================================== +!> this routine calculates a rotor-averaged mean velocity, DiskVel +SUBROUTINE InflowWind_GetSpatialAverage( Time, InputData, p, x, xd, z, OtherStates, m, MeanVelocity, ErrStat, ErrMsg ) - !----------------------------------------------------------------------- - ! Points coordinate transforms from to global to wind file coordinates - !----------------------------------------------------------------------- + IMPLICIT NONE + CHARACTER(*), PARAMETER :: RoutineName="InflowWind_GetSpatialAverage" - !> Make a copy of the InputData%PositionXYZ coordinates with the applied rotation matrix... - !! This copy is made because if we translate it to the prime coordinates, then back again, we - !! may shift the points by some small amount of machine error, and we don't want to do that. - !! - !! Note that we allocate this at every call to CalcOutput. The reason is that we may call CalcOutput - !! multiple times in each timestep with different sized InputData%PositionXYZ arrays (if calling for LIDAR - !! data etc). We don't really want to have extra copies of OtherStates lying around in order to be able to - !! do this. - CALL AllocAry( PositionXYZprime, 3, SIZE(InputData%PositionXYZ,DIM=2), & - "Array for holding the XYZprime position data", TmpErrStat, TmpErrMsg ) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN + ! Inputs / Outputs - ! Apply the coordinate transformation to the PositionXYZ coordinates to get the PositionXYZprime coordinate list - ! If the PropagationDir is zero, we don't need to apply this and will simply copy the data. Repeat for the WindViXYZ. - IF ( .not. p%RotateWindBox ) THEN - PositionXYZprime = InputData%PositionXYZ - ELSE - ! NOTE: rotations are about the hub at [ 0 0 H ]. See InflowWind_SetParameters for details. - DO I = 1,SIZE(InputData%PositionXYZ,DIM=2) - PositionXYZprime(:,I) = MATMUL( p%RotToWind, (InputData%PositionXYZ(:,I) - p%RefPosition) ) + p%RefPosition - ENDDO - ENDIF - + REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds + TYPE(InflowWind_InputType), INTENT(IN ) :: InputData !< Inputs at Time + TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(InflowWind_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time + TYPE(InflowWind_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at Time + TYPE(InflowWind_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at Time + TYPE(InflowWind_OtherStateType), INTENT(IN ) :: OtherStates !< Other states at Time + TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< misc/optimization variables + REAL(ReKi), INTENT( OUT) :: MeanVelocity(3) !< at InputPosition - !--------------------------------- - ! - - ! Compute the wind velocities by stepping through all the data points and calling the appropriate GetWindSpeed routine - SELECT CASE ( p%WindType ) - - CASE (Steady_WindNumber, Uniform_WindNumber) - - ! InputData only contains the Position array, so we can pass that directly. - CALL IfW_UniformWind_CalcOutput( Time, PositionXYZprime, p%UniformWind, y%VelocityUVW, & - DiskVel, m%UniformWind, TmpErrStat, TmpErrMsg) - - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - ! Call IfW_UniformWind_CalcOutput again in order to get the values needed for the OutList -- note that we do not report errors from this - IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN - ! Move the arrays for the Velocity information - CALL IfW_UniformWind_CalcOutput( Time, p%WindViXYZprime, p%UniformWind, m%WindViUVW, & - DiskVel, m%UniformWind, TmpErrStat, TmpErrMsg) - ENDIF - - CASE (TSFF_WindNumber) - - ! InputData only contains the Position array, so we can pass that directly. - CALL IfW_TSFFWind_CalcOutput( Time, PositionXYZprime, p%TSFFWind, & - y%VelocityUVW, DiskVel, m%TSFFWind, TmpErrStat, TmpErrMsg) - - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! Call IfW_TSFFWind_CalcOutput again in order to get the values needed for the OutList - IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN - ! Move the arrays for the Velocity information - CALL IfW_TSFFWind_CalcOutput( Time, p%WindViXYZprime, p%TSFFWind, & - m%WindViUVW, DiskVel, m%TSFFWind, TmpErrStat, TmpErrMsg) - - ! Out of bounds errors will be ErrID_Severe, not ErrID_Fatal - IF ( TmpErrStat >= ErrID_Fatal ) THEN - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ENDIF - - - - CASE (BladedFF_WindNumber) !also includes BladedFF_Shr_WindNumber + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - ! InputData only contains the Position array, so we can pass that directly. - CALL IfW_BladedFFWind_CalcOutput( Time, PositionXYZprime, p%BladedFFWind, & - y%VelocityUVW, DiskVel, m%BladedFFWind, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! Call IfW_BladedFFWind_CalcOutput again in order to get the values needed for the OutList - IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN - ! Move the arrays for the Velocity information - CALL IfW_BladedFFWind_CalcOutput( Time, p%WindViXYZprime, p%BladedFFWind, & - m%WindViUVW, DiskVel, m%BladedFFWind, TmpErrStat, TmpErrMsg) - - ! Out of bounds errors will be ErrID_Severe, not ErrID_Fatal - IF ( TmpErrStat >= ErrID_Fatal ) THEN - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ENDIF - - - CASE (User_WindNumber) - - ! InputData only contains the Position array, so we can pass that directly. - CALL IfW_UserWind_CalcOutput( Time, PositionXYZprime, p%UserWind, & - y%VelocityUVW, DiskVel, m%UserWind, TmpErrStat, TmpErrMsg) - - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - ! Call IfW_UserWind_CalcOutput again in order to get the values needed for the OutList - IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN - ! Move the arrays for the Velocity information - CALL IfW_UserWind_CalcOutput( Time, p%WindViXYZprime, p%UserWind, & - m%WindViUVW, DiskVel, m%UserWind, TmpErrStat, TmpErrMsg) + ! Local variables + INTEGER(IntKi) :: I !< Generic counters - ! Out of bounds errors will be ErrID_Severe, not ErrID_Fatal - IF ( TmpErrStat >= ErrID_Fatal ) THEN - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ENDIF + ! Temporary variables for error handling + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary error message + LOGICAL, PARAMETER :: FillWrOut = .false. - CASE ( HAWC_WindNumber ) - - ! InputData only contains the Position array, so we can pass that directly. - CALL IfW_HAWCWind_CalcOutput( Time, PositionXYZprime, p%HAWCWind, & - y%VelocityUVW, DiskVel, m%HAWCWind, TmpErrStat, TmpErrMsg) - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + MeanVelocity = 0.0_ReKi + + !----------------------------------------------------------------------- + ! Points coordinate transforms from to global to aligned with hub orientation + !----------------------------------------------------------------------- + m%u_Avg%HubPosition = InputData%HubPosition + m%u_Avg%HubOrientation = InputData%HubOrientation + + do i=1,IfW_NumPtsAvg + m%u_Avg%PositionXYZ(:,i) = matmul(InputData%HubOrientation,p%PositionAvg(:,i)) + InputData%HubPosition + end do - ! Call IfW_TSFFWind_CalcOutput again in order to get the values needed for the OutList - IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN - CALL IfW_HAWCWind_CalcOutput( Time, p%WindViXYZprime, p%HAWCWind, & - m%WindViUVW, DiskVel, m%HAWCWind, TmpErrStat, TmpErrMsg) + CALL CalculateOutput( Time, m%u_Avg, p, x, xd, z, OtherStates, m%y_Avg, m, FillWrOut, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! Out of bounds errors will be ErrID_Severe, not ErrID_Fatal - IF ( TmpErrStat >= ErrID_Fatal ) THEN - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - ENDIF - + do i=1,IfW_NumPtsAvg + MeanVelocity = MeanVelocity + m%y_Avg%VelocityUVW(:,i) + end do + MeanVelocity = MeanVelocity / REAL(IfW_NumPtsAvg,ReKi) + + + RETURN - CASE ( FDext_WindNumber ) - - CALL IfW_4Dext_CalcOutput(Time, PositionXYZprime, p%FDext, y%VelocityUVW, m%FDext, TmpErrStat, TmpErrMsg) - DiskVel = 0.0_ReKi ! this is only for AD14, which we frankly don't care about in 4Dext wind - - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN +!............................ +END SUBROUTINE InflowWind_GetSpatialAverage +!==================================================================================================== +!> this routine calculates a rotor-averaged mean velocity, DiskVel +SUBROUTINE InflowWind_GetHubValues( Time, InputData, p, x, xd, z, OtherStates, m, Velocity, ErrStat, ErrMsg ) - ! Call IfW_4Dext_CalcOutput again in order to get the values needed for the OutList - IF ( p%NWindVel >= 1_IntKi .AND. FillWrOut ) THEN - ! Move the arrays for the Velocity information - CALL IfW_4Dext_CalcOutput(Time, p%WindViXYZprime, p%FDext, m%WindViUVW, m%FDext, TmpErrStat, TmpErrMsg) - - ! Out of bounds errors will be ErrID_Severe, not ErrID_Fatal - IF ( TmpErrStat >= ErrID_Fatal ) THEN - CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF - - ENDIF - - - ! If it isn't one of the above cases, we have a problem and won't be able to continue + IMPLICIT NONE - CASE DEFAULT - - CALL SetErrStat( ErrID_Fatal, ' Error: Undefined wind type '//TRIM(Num2LStr(p%WindType))//'. '// & - 'Call WindInflow_Init() before calling this function.', ErrStat, ErrMsg, RoutineName ) - - y%VelocityUVW(:,:) = 0.0 - RETURN - - END SELECT - - - ! Add coherent turbulence to background wind - -!!! IF (p%CTTS_Flag) THEN -!!! -!!! DO PointCounter = 1, SIZE(InputData%Position, 2) -!!! -!!! TempWindSpeed = CTTS_GetWindSpeed( Time, InputData%Position(:,PointCounter), ErrStat, ErrMsg ) -!!! -!!! ! Error Handling -- move ErrMsg inside CTTS_GetWindSPeed and simplify -!!! IF (ErrStat >= ErrID_Severe) THEN -!!! ErrMsg = 'IfW_CalcOutput: Error in CTTS_GetWindSpeed for point number '//TRIM(Num2LStr(PointCounter)) -!!! EXIT ! Exit the loop -!!! ENDIF -!!! -!!! y%Velocity(:,PointCounter) = y%Velocity(:,PointCounter) + TempWindSpeed -!!! -!!! ENDDO -!!! -!!! ! If something went badly wrong, Return -!!! IF (ErrStat >= ErrID_Severe ) RETURN -!!! -!!! ENDIF -!!! - !ENDIF + CHARACTER(*), PARAMETER :: RoutineName="InflowWind_GetSpatialAverage" + ! Inputs / Outputs + REAL(DbKi), INTENT(IN ) :: Time !< Current simulation time in seconds + TYPE(InflowWind_InputType), INTENT(IN ) :: InputData !< Inputs at Time + TYPE(InflowWind_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(InflowWind_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time + TYPE(InflowWind_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at Time + TYPE(InflowWind_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at Time + TYPE(InflowWind_OtherStateType), INTENT(IN ) :: OtherStates !< Other states at Time + TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: m !< misc/optimization variables + REAL(ReKi), INTENT( OUT) :: Velocity(3) !< at InputPosition + + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - !----------------------------------------------------------------------- - ! Windspeed coordinate transforms from Wind file coordinates to global - !----------------------------------------------------------------------- + ! Local variables + INTEGER(IntKi) :: I !< Generic counters - ! The VelocityUVW array data that has been returned from the sub-modules is in the wind file (X'Y'Z') coordinates at - ! this point. These must be rotated to the global XYZ coordinates. So now we apply the coordinate transformation - ! to the VelocityUVW(prime) coordinates (in wind X'Y'Z' coordinate frame) returned from the submodules to the XYZ - ! coordinate frame, but only if PropagationDir is not zero. This is only a rotation of the returned wind field, so - ! UVW contains the direction components of the wind at XYZ after translation from the U'V'W' wind velocity components - ! in the X'Y'Z' (wind file) coordinate frame. - ! NOTE: rotations are about the hub at [ 0 0 H ]. See InflowWind_SetParameters for details. - IF ( p%RotateWindBox ) THEN - DO I = 1,SIZE(y%VelocityUVW,DIM=2) - y%VelocityUVW(:,I) = MATMUL( p%RotFromWind, y%VelocityUVW(:,I) ) - ENDDO - ENDIF - ! We also need to rotate the reference frame for the WindViUVW array - ! NOTE: rotations are about the hub at [ 0 0 H ]. See InflowWind_SetParameters for details. - IF ( p%RotateWindBox .AND. FillWrOut ) THEN - DO I = 1,SIZE(m%WindViUVW,DIM=2) - m%WindViUVW(:,I) = MATMUL( p%RotFromWind, m%WindViUVW(:,I) ) - ENDDO - ENDIF + ! Temporary variables for error handling + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary error message + LOGICAL, PARAMETER :: FillWrOut = .false. - ! DiskVel values over to the output and apply the coordinate transformation - y%DiskVel = MATMUL( p%RotFromWind, DiskVel ) + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" + + !----------------------------------------------------------------------- + ! Calculate values at the hub: + !----------------------------------------------------------------------- + m%u_Hub%HubPosition = InputData%HubPosition + m%u_Hub%HubOrientation = InputData%HubOrientation + + m%u_Hub%PositionXYZ(:,1) = InputData%HubPosition - ! Done with the prime coordinates for the XYZ position information that was passed in. - IF (ALLOCATED(PositionXYZprime)) DEALLOCATE(PositionXYZprime) - - + CALL CalculateOutput( Time, m%u_Hub, p, x, xd, z, OtherStates, m%y_Hub, m, FillWrOut, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + Velocity = m%y_Hub%VelocityUVW(:,1) + + RETURN -END SUBROUTINE CalculateOutput - +!............................ +END SUBROUTINE InflowWind_GetHubValues !==================================================================================================== !> this routine calculates the mean wind speed SUBROUTINE InflowWind_GetMean( StartTime, EndTime, delta_time, InputPosition, MeanVelocity, & diff --git a/modules/inflowwind/src/InflowWind_Types.f90 b/modules/inflowwind/src/InflowWind_Types.f90 index 8575aab02..605bfe222 100644 --- a/modules/inflowwind/src/InflowWind_Types.f90 +++ b/modules/inflowwind/src/InflowWind_Types.f90 @@ -31,12 +31,7 @@ !! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry. MODULE InflowWind_Types !--------------------------------------------------------------------------------------------------------------------------------- -USE IfW_UniformWind_Types -USE IfW_TSFFWind_Types -USE IfW_BladedFFWind_Types -USE IfW_HAWCWind_Types -USE IfW_UserWind_Types -USE IfW_4Dext_Types +USE InflowWind_IO_Types USE Lidar_Types USE NWTC_Library IMPLICIT NONE @@ -49,35 +44,16 @@ MODULE InflowWind_Types INTEGER(IntKi), PUBLIC, PARAMETER :: User_WindNumber = 6 ! User defined wind. [-] INTEGER(IntKi), PUBLIC, PARAMETER :: BladedFF_Shr_WindNumber = 7 ! Native Bladed binary full-field file. [-] INTEGER(IntKi), PUBLIC, PARAMETER :: FDext_WindNumber = 8 ! 4D wind from external souce (i.e., FAST.Farm). [-] - INTEGER(IntKi), PUBLIC, PARAMETER :: Highest_WindNumber = 8 ! Highest wind number supported. [-] -! ========= WindFileMetaData ======= - TYPE, PUBLIC :: WindFileMetaData - CHARACTER(1024) :: FileName !< Name of the windfile retrieved [-] - INTEGER(IntKi) :: WindType = 0 !< Type of the windfile [-] - REAL(ReKi) :: RefHt !< Reference height given in file [meters] - LOGICAL :: RefHt_Set !< Reference height was given in file [-] - REAL(DbKi) :: DT !< TimeStep of the wind file -- zero value for none [seconds] - INTEGER(IntKi) :: NumTSteps !< Number of timesteps in the time range of wind file [-] - LOGICAL :: ConstantDT !< Timesteps are the same throughout file [-] - REAL(ReKi) , DIMENSION(1:2) :: TRange !< Time range of the wind file [seconds] - LOGICAL :: TRange_Limited !< TRange limits strictly enforced [-] - REAL(ReKi) , DIMENSION(1:2) :: YRange !< Range in y direction [meters] - LOGICAL :: YRange_Limited !< YRange limits strictly enforced [-] - REAL(ReKi) , DIMENSION(1:2) :: ZRange !< Range in z direction [meters] - LOGICAL :: ZRange_Limited !< ZRange limits strictly enforced [-] - INTEGER(IntKi) :: BinaryFormat !< Binary format identifier [-] - LOGICAL :: IsBinary !< Windfile is a binary file [-] - REAL(ReKi) , DIMENSION(1:3) :: TI !< Turbulence intensity (U,V,W) [-] - LOGICAL :: TI_listed !< Turbulence intesity given in file [-] - REAL(ReKi) :: MWS !< Approximate mean wind speed [-] - END TYPE WindFileMetaData -! ======================= + INTEGER(IntKi), PUBLIC, PARAMETER :: Point_WindNumber = 9 ! 1D wind components from ExtInflow [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Highest_WindNumber = 9 ! Highest wind number supported. [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: IfW_NumPtsAvg = 144 ! Number of points averaged for rotor-average wind speed [-] ! ========= InflowWind_InputFile ======= TYPE, PUBLIC :: InflowWind_InputFile LOGICAL :: EchoFlag !< Echo the input file [-] INTEGER(IntKi) :: WindType = 0 !< Type of windfile [-] REAL(ReKi) :: PropagationDir !< Direction of wind propagation (meteorological direction) [(degrees)] REAL(ReKi) :: VFlowAngle !< Vertical (upflow) angle [degrees] + LOGICAL :: VelInterpCubic = .FALSE. !< Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7] [-] INTEGER(IntKi) :: NWindVel !< Number of points to output the wind velocity (0 to 9) [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WindVxiList !< List of X coordinates for wind velocity measurements [meters] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WindVyiList !< List of Y coordinates for wind velocity measurements [meters] @@ -106,11 +82,19 @@ MODULE InflowWind_Types LOGICAL :: SumPrint !< Write summary info to a file .IfW.Sum [-] INTEGER(IntKi) :: NumOuts !< Number of parameters in the output list (number of outputs requested) [-] CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: OutList !< List of user-requested output channels [-] - INTEGER(IntKi) :: SensorType = SensorType_None !< Sensor type (for lidar/sensor module) [-] - INTEGER(IntKi) :: NumPulseGate !< the number of range gates to return wind speeds at [-] - REAL(ReKi) , DIMENSION(1:3) :: RotorApexOffsetPos !< position of the lidar unit relative to the rotor apex of rotation [m] + INTEGER(IntKi) :: SensorType !< Sensor type (for lidar/sensor module) [-] + INTEGER(IntKi) :: NumBeam !< Number of lidar beams [-] + INTEGER(IntKi) :: NumPulseGate !< The number of range gates to return wind speeds at [-] + REAL(ReKi) , DIMENSION(1:3) :: RotorApexOffsetPos !< Position of the lidar unit relative to the rotor apex of rotation [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FocalDistanceX !< LIDAR LOS focal distance co-ordinates in the x direction [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FocalDistanceY !< LIDAR LOS focal distance co-ordinates in the y direction [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FocalDistanceZ !< LIDAR LOS focal distance co-ordinates in the z direction [m] + REAL(ReKi) :: PulseSpacing !< Distance between range gates [m] + REAL(ReKi) :: MeasurementInterval !< Time between each measurement [s] + REAL(ReKi) :: URefLid !< Reference average wind speed for the lidar [m/s] LOGICAL :: LidRadialVel !< TRUE => return radial component, FALSE => return 'x' direction estimate [-] - TYPE(IfW_FFWind_InitInputType) :: FF !< scaling data [-] + INTEGER(IntKi) :: ConsiderHubMotion !< Flag whether or not the hub motion's impact on the Lidar measurement will be considered [0 for no, 1 for yes] [-] + TYPE(Grid3D_InitInputType) :: FF !< scaling data [-] END TYPE InflowWind_InputFile ! ======================= ! ========= InflowWind_InitInputType ======= @@ -126,8 +110,15 @@ MODULE InflowWind_Types TYPE(FileInfoType) :: PassedFileData !< If we don't use the input file, pass everything through this [-] LOGICAL :: WindType2UseInputFile = .TRUE. !< Flag for toggling file based IO in wind type 2. [-] TYPE(FileInfoType) :: WindType2Data !< Optional slot for wind type 2 data if file IO is not used. [-] + LOGICAL :: OutputAccel = .FALSE. !< Flag to output wind acceleration [-] TYPE(Lidar_InitInputType) :: lidar !< InitInput for lidar data [-] - TYPE(IfW_4Dext_InitInputType) :: FDext !< InitInput for lidar data [-] + TYPE(Grid4D_InitInputType) :: FDext !< InitInput for 4D external wind data [-] + REAL(ReKi) :: RadAvg !< Radius (from hub) used for averaging wind speed [-] + INTEGER(IntKi) :: MHK !< MHK turbine type switch [-] + REAL(ReKi) :: WtrDpth !< Water depth [m] + REAL(ReKi) :: MSL2SWL !< Mean sea level to still water level [m] + INTEGER(IntKi) :: BoxExceedAllowIdx = -1 !< Extrapolate winds outside box starting at this index (for OLAF wakes and LidarSim) [-] + LOGICAL :: BoxExceedAllowF = .FALSE. !< Flag to allow Extrapolation winds outside box starting at this index (for OLAF wakes and LidarSim) [-] END TYPE InflowWind_InitInputType ! ======================= ! ========= InflowWind_InitOutputType ======= @@ -135,7 +126,7 @@ MODULE InflowWind_Types CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputHdr !< Names of output-to-file channels [-] CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: WriteOutputUnt !< Units of output-to-file channels [-] TYPE(ProgDesc) :: Ver !< Version information of InflowWind module [-] - TYPE(WindFileMetaData) :: WindFileInfo !< Meta data from the wind file [-] + TYPE(WindFileDat) :: WindFileInfo !< Meta data from the wind file [-] CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_y !< Names of the outputs used in linearization [-] CHARACTER(LinChanLen) , DIMENSION(:), ALLOCATABLE :: LinNames_u !< Names of the inputs used in linearization [-] LOGICAL , DIMENSION(:), ALLOCATABLE :: RotFrame_y !< Flag that tells FAST/MBC3 if the outputs used in linearization are in the rotating frame [-] @@ -143,58 +134,38 @@ MODULE InflowWind_Types LOGICAL , DIMENSION(:), ALLOCATABLE :: IsLoad_u !< Flag that tells FAST if the inputs used in linearization are loads (for preconditioning matrix) [-] END TYPE InflowWind_InitOutputType ! ======================= -! ========= InflowWind_MiscVarType ======= - TYPE, PUBLIC :: InflowWind_MiscVarType - INTEGER(IntKi) :: TimeIndex = 0 !< An Index into the TData array [-] - TYPE(IfW_UniformWind_MiscVarType) :: UniformWind !< MiscVars from UniformWind [-] - TYPE(IfW_TSFFWind_MiscVarType) :: TSFFWind !< MiscVars from TSFFWind [-] - TYPE(IfW_HAWCWind_MiscVarType) :: HAWCWind !< MiscVars from HAWCWind [-] - TYPE(IfW_BladedFFWind_MiscVarType) :: BladedFFWind !< MiscVars from BladedFFWind [-] - TYPE(IfW_UserWind_MiscVarType) :: UserWind !< MiscVars from UserWind [-] - TYPE(IfW_4Dext_MiscVarType) :: FDext !< MiscVars from FDext [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AllOuts !< An array holding the value of all of the calculated (not only selected) output channels [see OutListParameters.xlsx spreadsheet] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WindViUVW !< List of UVW velocities for wind velocity measurements, 3xNWindVel. corresponds to ParamData%WindViXYZ [meters/second] - END TYPE InflowWind_MiscVarType -! ======================= ! ========= InflowWind_ParameterType ======= TYPE, PUBLIC :: InflowWind_ParameterType CHARACTER(1024) :: RootFileName !< Root of the InflowWind input filename [-] - LOGICAL :: CTTS_Flag = .FALSE. !< determines if coherent turbulence is used [-] - LOGICAL :: RotateWindBox = .FALSE. !< determines if wind will be rotated [-] + INTEGER(IntKi) :: WindType = 0 !< Type of wind -- set to Undef_Wind initially [-] REAL(DbKi) :: DT !< Time step for cont. state integration & disc. state update [seconds] - REAL(ReKi) :: PropagationDir !< Direction of wind propagation [radians] - REAL(ReKi) :: VFlowAngle !< Vertical (upflow) angle [radians] - REAL(ReKi) , DIMENSION(1:3,1:3) :: RotToWind !< Rotation matrix for rotating from the global XYZ coordinate system to the wind coordinate system (wind along X') [-] - REAL(ReKi) , DIMENSION(1:3,1:3) :: RotFromWind !< Rotation matrix for rotating from the wind coordinate system (wind along X') back to the global XYZ coordinate system. Equal to TRANSPOSE(RotToWind) [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WindViXYZprime !< List of XYZ coordinates for velocity measurements, translated to the wind coordinate system (prime coordinates). This equals MATMUL( RotToWind, ParamData%WindViXYZ ) [meters] - INTEGER(IntKi) :: WindType = 0 !< Type of wind -- set to Undef_Wind initially [-] - REAL(ReKi) :: ReferenceHeight !< Height of the wind turbine [meters] - REAL(ReKi) , DIMENSION(1:3) :: RefPosition !< Reference position (point where box is rotated) [meters] - INTEGER(IntKi) :: NWindVel !< Number of points in the wind velocity list [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WindViXYZ !< List of XYZ coordinates for wind velocity measurements, 3xNWindVel [meters] - TYPE(IfW_UniformWind_ParameterType) :: UniformWind !< Parameters from UniformWind [-] - TYPE(IfW_TSFFWind_ParameterType) :: TSFFWind !< Parameters from TSFFWind -- TurbSim full-field format [-] - TYPE(IfW_BladedFFWind_ParameterType) :: BladedFFWind !< Parameters from BladedFFWind -- Bladed-style full-field format [-] - TYPE(IfW_HAWCWind_ParameterType) :: HAWCWind !< Parameters from HAWCWind [-] - TYPE(IfW_UserWind_ParameterType) :: UserWind !< Parameters from UserWind [-] - TYPE(IfW_4Dext_ParameterType) :: FDext !< Parameters from FDext [-] + TYPE(FlowFieldType) :: FlowField !< Parameters from Full-Field [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PositionAvg !< (non-rotated) positions of points used for averaging wind speed [meters] + INTEGER(IntKi) :: NWindVel !< Number of points in the wind velocity list [-] INTEGER(IntKi) :: NumOuts = 0 !< Number of parameters in the output list (number of outputs requested) [-] TYPE(OutParmType) , DIMENSION(:), ALLOCATABLE :: OutParam !< Names and units (and other characteristics) of all requested output parameters [-] INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: OutParamLinIndx !< Index into WriteOutput for WindViXYZ in linearization analysis [-] TYPE(Lidar_ParameterType) :: lidar !< Lidar parameter data [-] + LOGICAL :: OutputAccel = .FALSE. !< Flag to output wind acceleration [-] END TYPE InflowWind_ParameterType ! ======================= ! ========= InflowWind_InputType ======= TYPE, PUBLIC :: InflowWind_InputType REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PositionXYZ !< Array holding the input positions at a given timestep [meters] TYPE(Lidar_InputType) :: lidar !< Lidar data [-] + REAL(ReKi) , DIMENSION(1:3) :: HubPosition !< position of the hub (inertial frame) [m] + REAL(ReKi) , DIMENSION(1:3,1:3) :: HubOrientation !< orientation of the hub (direction cosine matrix) [-] END TYPE InflowWind_InputType ! ======================= ! ========= InflowWind_OutputType ======= TYPE, PUBLIC :: InflowWind_OutputType REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: VelocityUVW !< Array holding the U,V,W velocity for a given timestep [meters/sec] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: AccelUVW !< Array holding the U,V,W acceleration for a given timestep [meters/sec] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< Array with values to output to file [-] REAL(ReKi) , DIMENSION(1:3) :: DiskVel !< Vector holding the U,V,W average velocity of the disk [meters/sec] + REAL(ReKi) , DIMENSION(1:3) :: HubVel !< Vector holding the U,V,W velocity at the hub [meters/sec] TYPE(Lidar_OutputType) :: lidar !< Lidar data [-] END TYPE InflowWind_OutputType ! ======================= @@ -218,266 +189,18 @@ MODULE InflowWind_Types REAL(ReKi) :: DummyOtherState !< Remove this variable if you have other states [-] END TYPE InflowWind_OtherStateType ! ======================= +! ========= InflowWind_MiscVarType ======= + TYPE, PUBLIC :: InflowWind_MiscVarType + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: AllOuts !< An array holding the value of all of the calculated (not only selected) output channels [see OutListParameters.xlsx spreadsheet] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WindViUVW !< List of UVW velocities for wind velocity measurements, 3xNWindVel. corresponds to ParamData%WindViXYZ [meters/second] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WindAiUVW !< List of UVW accelerations for wind acceleration measurements, 3xNWindVel. corresponds to ParamData%WindViXYZ [m/s^2] + TYPE(InflowWind_InputType) :: u_Avg !< inputs for computing rotor-averaged values [-] + TYPE(InflowWind_OutputType) :: y_Avg !< outputs for computing rotor-averaged values [-] + TYPE(InflowWind_InputType) :: u_Hub !< inputs for computing hub values [-] + TYPE(InflowWind_OutputType) :: y_Hub !< outputs for computing hub values [-] + END TYPE InflowWind_MiscVarType +! ======================= CONTAINS - SUBROUTINE InflowWind_CopyWindFileMetaData( SrcWindFileMetaDataData, DstWindFileMetaDataData, CtrlCode, ErrStat, ErrMsg ) - TYPE(WindFileMetaData), INTENT(IN) :: SrcWindFileMetaDataData - TYPE(WindFileMetaData), INTENT(INOUT) :: DstWindFileMetaDataData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_CopyWindFileMetaData' -! - ErrStat = ErrID_None - ErrMsg = "" - DstWindFileMetaDataData%FileName = SrcWindFileMetaDataData%FileName - DstWindFileMetaDataData%WindType = SrcWindFileMetaDataData%WindType - DstWindFileMetaDataData%RefHt = SrcWindFileMetaDataData%RefHt - DstWindFileMetaDataData%RefHt_Set = SrcWindFileMetaDataData%RefHt_Set - DstWindFileMetaDataData%DT = SrcWindFileMetaDataData%DT - DstWindFileMetaDataData%NumTSteps = SrcWindFileMetaDataData%NumTSteps - DstWindFileMetaDataData%ConstantDT = SrcWindFileMetaDataData%ConstantDT - DstWindFileMetaDataData%TRange = SrcWindFileMetaDataData%TRange - DstWindFileMetaDataData%TRange_Limited = SrcWindFileMetaDataData%TRange_Limited - DstWindFileMetaDataData%YRange = SrcWindFileMetaDataData%YRange - DstWindFileMetaDataData%YRange_Limited = SrcWindFileMetaDataData%YRange_Limited - DstWindFileMetaDataData%ZRange = SrcWindFileMetaDataData%ZRange - DstWindFileMetaDataData%ZRange_Limited = SrcWindFileMetaDataData%ZRange_Limited - DstWindFileMetaDataData%BinaryFormat = SrcWindFileMetaDataData%BinaryFormat - DstWindFileMetaDataData%IsBinary = SrcWindFileMetaDataData%IsBinary - DstWindFileMetaDataData%TI = SrcWindFileMetaDataData%TI - DstWindFileMetaDataData%TI_listed = SrcWindFileMetaDataData%TI_listed - DstWindFileMetaDataData%MWS = SrcWindFileMetaDataData%MWS - END SUBROUTINE InflowWind_CopyWindFileMetaData - - SUBROUTINE InflowWind_DestroyWindFileMetaData( WindFileMetaDataData, ErrStat, ErrMsg ) - TYPE(WindFileMetaData), INTENT(INOUT) :: WindFileMetaDataData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyWindFileMetaData' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE InflowWind_DestroyWindFileMetaData - - SUBROUTINE InflowWind_PackWindFileMetaData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(WindFileMetaData), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_PackWindFileMetaData' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1*LEN(InData%FileName) ! FileName - Int_BufSz = Int_BufSz + 1 ! WindType - Re_BufSz = Re_BufSz + 1 ! RefHt - Int_BufSz = Int_BufSz + 1 ! RefHt_Set - Db_BufSz = Db_BufSz + 1 ! DT - Int_BufSz = Int_BufSz + 1 ! NumTSteps - Int_BufSz = Int_BufSz + 1 ! ConstantDT - Re_BufSz = Re_BufSz + SIZE(InData%TRange) ! TRange - Int_BufSz = Int_BufSz + 1 ! TRange_Limited - Re_BufSz = Re_BufSz + SIZE(InData%YRange) ! YRange - Int_BufSz = Int_BufSz + 1 ! YRange_Limited - Re_BufSz = Re_BufSz + SIZE(InData%ZRange) ! ZRange - Int_BufSz = Int_BufSz + 1 ! ZRange_Limited - Int_BufSz = Int_BufSz + 1 ! BinaryFormat - Int_BufSz = Int_BufSz + 1 ! IsBinary - Re_BufSz = Re_BufSz + SIZE(InData%TI) ! TI - Int_BufSz = Int_BufSz + 1 ! TI_listed - Re_BufSz = Re_BufSz + 1 ! MWS - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO I = 1, LEN(InData%FileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%FileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = InData%WindType - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%RefHt - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%RefHt_Set, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%DT - Db_Xferred = Db_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NumTSteps - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%ConstantDT, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%TRange,1), UBOUND(InData%TRange,1) - ReKiBuf(Re_Xferred) = InData%TRange(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = TRANSFER(InData%TRange_Limited, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%YRange,1), UBOUND(InData%YRange,1) - ReKiBuf(Re_Xferred) = InData%YRange(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = TRANSFER(InData%YRange_Limited, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%ZRange,1), UBOUND(InData%ZRange,1) - ReKiBuf(Re_Xferred) = InData%ZRange(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = TRANSFER(InData%ZRange_Limited, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%BinaryFormat - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%IsBinary, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - DO i1 = LBOUND(InData%TI,1), UBOUND(InData%TI,1) - ReKiBuf(Re_Xferred) = InData%TI(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = TRANSFER(InData%TI_listed, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%MWS - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE InflowWind_PackWindFileMetaData - - SUBROUTINE InflowWind_UnPackWindFileMetaData( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(WindFileMetaData), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_UnPackWindFileMetaData' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - DO I = 1, LEN(OutData%FileName) - OutData%FileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%WindType = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%RefHt = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%RefHt_Set = TRANSFER(IntKiBuf(Int_Xferred), OutData%RefHt_Set) - Int_Xferred = Int_Xferred + 1 - OutData%DT = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 - OutData%NumTSteps = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%ConstantDT = TRANSFER(IntKiBuf(Int_Xferred), OutData%ConstantDT) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%TRange,1) - i1_u = UBOUND(OutData%TRange,1) - DO i1 = LBOUND(OutData%TRange,1), UBOUND(OutData%TRange,1) - OutData%TRange(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%TRange_Limited = TRANSFER(IntKiBuf(Int_Xferred), OutData%TRange_Limited) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%YRange,1) - i1_u = UBOUND(OutData%YRange,1) - DO i1 = LBOUND(OutData%YRange,1), UBOUND(OutData%YRange,1) - OutData%YRange(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%YRange_Limited = TRANSFER(IntKiBuf(Int_Xferred), OutData%YRange_Limited) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%ZRange,1) - i1_u = UBOUND(OutData%ZRange,1) - DO i1 = LBOUND(OutData%ZRange,1), UBOUND(OutData%ZRange,1) - OutData%ZRange(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%ZRange_Limited = TRANSFER(IntKiBuf(Int_Xferred), OutData%ZRange_Limited) - Int_Xferred = Int_Xferred + 1 - OutData%BinaryFormat = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%IsBinary = TRANSFER(IntKiBuf(Int_Xferred), OutData%IsBinary) - Int_Xferred = Int_Xferred + 1 - i1_l = LBOUND(OutData%TI,1) - i1_u = UBOUND(OutData%TI,1) - DO i1 = LBOUND(OutData%TI,1), UBOUND(OutData%TI,1) - OutData%TI(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%TI_listed = TRANSFER(IntKiBuf(Int_Xferred), OutData%TI_listed) - Int_Xferred = Int_Xferred + 1 - OutData%MWS = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE InflowWind_UnPackWindFileMetaData - SUBROUTINE InflowWind_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrStat, ErrMsg ) TYPE(InflowWind_InputFile), INTENT(IN) :: SrcInputFileData TYPE(InflowWind_InputFile), INTENT(INOUT) :: DstInputFileData @@ -487,6 +210,7 @@ SUBROUTINE InflowWind_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCod ! Local INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_CopyInputFile' @@ -497,6 +221,7 @@ SUBROUTINE InflowWind_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCod DstInputFileData%WindType = SrcInputFileData%WindType DstInputFileData%PropagationDir = SrcInputFileData%PropagationDir DstInputFileData%VFlowAngle = SrcInputFileData%VFlowAngle + DstInputFileData%VelInterpCubic = SrcInputFileData%VelInterpCubic DstInputFileData%NWindVel = SrcInputFileData%NWindVel IF (ALLOCATED(SrcInputFileData%WindVxiList)) THEN i1_l = LBOUND(SrcInputFileData%WindVxiList,1) @@ -570,23 +295,76 @@ SUBROUTINE InflowWind_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCod DstInputFileData%OutList = SrcInputFileData%OutList ENDIF DstInputFileData%SensorType = SrcInputFileData%SensorType + DstInputFileData%NumBeam = SrcInputFileData%NumBeam DstInputFileData%NumPulseGate = SrcInputFileData%NumPulseGate DstInputFileData%RotorApexOffsetPos = SrcInputFileData%RotorApexOffsetPos +IF (ALLOCATED(SrcInputFileData%FocalDistanceX)) THEN + i1_l = LBOUND(SrcInputFileData%FocalDistanceX,1) + i1_u = UBOUND(SrcInputFileData%FocalDistanceX,1) + IF (.NOT. ALLOCATED(DstInputFileData%FocalDistanceX)) THEN + ALLOCATE(DstInputFileData%FocalDistanceX(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%FocalDistanceX.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputFileData%FocalDistanceX = SrcInputFileData%FocalDistanceX +ENDIF +IF (ALLOCATED(SrcInputFileData%FocalDistanceY)) THEN + i1_l = LBOUND(SrcInputFileData%FocalDistanceY,1) + i1_u = UBOUND(SrcInputFileData%FocalDistanceY,1) + IF (.NOT. ALLOCATED(DstInputFileData%FocalDistanceY)) THEN + ALLOCATE(DstInputFileData%FocalDistanceY(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%FocalDistanceY.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputFileData%FocalDistanceY = SrcInputFileData%FocalDistanceY +ENDIF +IF (ALLOCATED(SrcInputFileData%FocalDistanceZ)) THEN + i1_l = LBOUND(SrcInputFileData%FocalDistanceZ,1) + i1_u = UBOUND(SrcInputFileData%FocalDistanceZ,1) + IF (.NOT. ALLOCATED(DstInputFileData%FocalDistanceZ)) THEN + ALLOCATE(DstInputFileData%FocalDistanceZ(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputFileData%FocalDistanceZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputFileData%FocalDistanceZ = SrcInputFileData%FocalDistanceZ +ENDIF + DstInputFileData%PulseSpacing = SrcInputFileData%PulseSpacing + DstInputFileData%MeasurementInterval = SrcInputFileData%MeasurementInterval + DstInputFileData%URefLid = SrcInputFileData%URefLid DstInputFileData%LidRadialVel = SrcInputFileData%LidRadialVel - CALL IfW_FFWind_CopyInitInput( SrcInputFileData%FF, DstInputFileData%FF, CtrlCode, ErrStat2, ErrMsg2 ) + DstInputFileData%ConsiderHubMotion = SrcInputFileData%ConsiderHubMotion + CALL InflowWind_IO_Copygrid3d_initinputtype( SrcInputFileData%FF, DstInputFileData%FF, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE InflowWind_CopyInputFile - SUBROUTINE InflowWind_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) + SUBROUTINE InflowWind_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(InflowWind_InputFile), INTENT(INOUT) :: InputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyInputFile' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyInputFile' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputFileData%WindVxiList)) THEN DEALLOCATE(InputFileData%WindVxiList) ENDIF @@ -599,7 +377,17 @@ SUBROUTINE InflowWind_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) IF (ALLOCATED(InputFileData%OutList)) THEN DEALLOCATE(InputFileData%OutList) ENDIF - CALL IfW_FFWind_DestroyInitInput( InputFileData%FF, ErrStat, ErrMsg ) +IF (ALLOCATED(InputFileData%FocalDistanceX)) THEN + DEALLOCATE(InputFileData%FocalDistanceX) +ENDIF +IF (ALLOCATED(InputFileData%FocalDistanceY)) THEN + DEALLOCATE(InputFileData%FocalDistanceY) +ENDIF +IF (ALLOCATED(InputFileData%FocalDistanceZ)) THEN + DEALLOCATE(InputFileData%FocalDistanceZ) +ENDIF + CALL InflowWind_IO_Destroygrid3d_initinputtype( InputFileData%FF, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE InflowWind_DestroyInputFile SUBROUTINE InflowWind_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -641,6 +429,7 @@ SUBROUTINE InflowWind_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_BufSz = Int_BufSz + 1 ! WindType Re_BufSz = Re_BufSz + 1 ! PropagationDir Re_BufSz = Re_BufSz + 1 ! VFlowAngle + Int_BufSz = Int_BufSz + 1 ! VelInterpCubic Int_BufSz = Int_BufSz + 1 ! NWindVel Int_BufSz = Int_BufSz + 1 ! WindVxiList allocated yes/no IF ( ALLOCATED(InData%WindVxiList) ) THEN @@ -686,12 +475,32 @@ SUBROUTINE InflowWind_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_BufSz = Int_BufSz + SIZE(InData%OutList)*LEN(InData%OutList) ! OutList END IF Int_BufSz = Int_BufSz + 1 ! SensorType + Int_BufSz = Int_BufSz + 1 ! NumBeam Int_BufSz = Int_BufSz + 1 ! NumPulseGate Re_BufSz = Re_BufSz + SIZE(InData%RotorApexOffsetPos) ! RotorApexOffsetPos + Int_BufSz = Int_BufSz + 1 ! FocalDistanceX allocated yes/no + IF ( ALLOCATED(InData%FocalDistanceX) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FocalDistanceX upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%FocalDistanceX) ! FocalDistanceX + END IF + Int_BufSz = Int_BufSz + 1 ! FocalDistanceY allocated yes/no + IF ( ALLOCATED(InData%FocalDistanceY) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FocalDistanceY upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%FocalDistanceY) ! FocalDistanceY + END IF + Int_BufSz = Int_BufSz + 1 ! FocalDistanceZ allocated yes/no + IF ( ALLOCATED(InData%FocalDistanceZ) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FocalDistanceZ upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%FocalDistanceZ) ! FocalDistanceZ + END IF + Re_BufSz = Re_BufSz + 1 ! PulseSpacing + Re_BufSz = Re_BufSz + 1 ! MeasurementInterval + Re_BufSz = Re_BufSz + 1 ! URefLid Int_BufSz = Int_BufSz + 1 ! LidRadialVel + Int_BufSz = Int_BufSz + 1 ! ConsiderHubMotion ! Allocate buffers for subtypes, if any (we'll get sizes from these) Int_BufSz = Int_BufSz + 3 ! FF: size of buffers for each call to pack subtype - CALL IfW_FFWind_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, .TRUE. ) ! FF + CALL InflowWind_IO_Packgrid3d_initinputtype( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, .TRUE. ) ! FF CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -742,6 +551,8 @@ SUBROUTINE InflowWind_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%VFlowAngle Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%VelInterpCubic, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NWindVel Int_Xferred = Int_Xferred + 1 IF ( .NOT. ALLOCATED(InData%WindVxiList) ) THEN @@ -870,15 +681,70 @@ SUBROUTINE InflowWind_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat END IF IntKiBuf(Int_Xferred) = InData%SensorType Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumBeam + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NumPulseGate Int_Xferred = Int_Xferred + 1 DO i1 = LBOUND(InData%RotorApexOffsetPos,1), UBOUND(InData%RotorApexOffsetPos,1) ReKiBuf(Re_Xferred) = InData%RotorApexOffsetPos(i1) Re_Xferred = Re_Xferred + 1 END DO + IF ( .NOT. ALLOCATED(InData%FocalDistanceX) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FocalDistanceX,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FocalDistanceX,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%FocalDistanceX,1), UBOUND(InData%FocalDistanceX,1) + ReKiBuf(Re_Xferred) = InData%FocalDistanceX(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%FocalDistanceY) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FocalDistanceY,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FocalDistanceY,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%FocalDistanceY,1), UBOUND(InData%FocalDistanceY,1) + ReKiBuf(Re_Xferred) = InData%FocalDistanceY(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%FocalDistanceZ) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FocalDistanceZ,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FocalDistanceZ,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%FocalDistanceZ,1), UBOUND(InData%FocalDistanceZ,1) + ReKiBuf(Re_Xferred) = InData%FocalDistanceZ(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + ReKiBuf(Re_Xferred) = InData%PulseSpacing + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MeasurementInterval + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%URefLid + Re_Xferred = Re_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%LidRadialVel, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - CALL IfW_FFWind_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, OnlySize ) ! FF + IntKiBuf(Int_Xferred) = InData%ConsiderHubMotion + Int_Xferred = Int_Xferred + 1 + CALL InflowWind_IO_Packgrid3d_initinputtype( Re_Buf, Db_Buf, Int_Buf, InData%FF, ErrStat2, ErrMsg2, OnlySize ) ! FF CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -922,6 +788,7 @@ SUBROUTINE InflowWind_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS INTEGER(IntKi) :: Int_Xferred INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_UnPackInputFile' @@ -943,6 +810,8 @@ SUBROUTINE InflowWind_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Re_Xferred = Re_Xferred + 1 OutData%VFlowAngle = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%VelInterpCubic = TRANSFER(IntKiBuf(Int_Xferred), OutData%VelInterpCubic) + Int_Xferred = Int_Xferred + 1 OutData%NWindVel = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WindVxiList not allocated @@ -1083,6 +952,8 @@ SUBROUTINE InflowWind_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS END IF OutData%SensorType = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + OutData%NumBeam = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%NumPulseGate = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 i1_l = LBOUND(OutData%RotorApexOffsetPos,1) @@ -1091,19 +962,81 @@ SUBROUTINE InflowWind_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS OutData%RotorApexOffsetPos(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO - OutData%LidRadialVel = TRANSFER(IntKiBuf(Int_Xferred), OutData%LidRadialVel) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FocalDistanceX not allocated 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 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FocalDistanceX)) DEALLOCATE(OutData%FocalDistanceX) + ALLOCATE(OutData%FocalDistanceX(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FocalDistanceX.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%FocalDistanceX,1), UBOUND(OutData%FocalDistanceX,1) + OutData%FocalDistanceX(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FocalDistanceY not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FocalDistanceY)) DEALLOCATE(OutData%FocalDistanceY) + ALLOCATE(OutData%FocalDistanceY(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FocalDistanceY.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%FocalDistanceY,1), UBOUND(OutData%FocalDistanceY,1) + OutData%FocalDistanceY(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FocalDistanceZ not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FocalDistanceZ)) DEALLOCATE(OutData%FocalDistanceZ) + ALLOCATE(OutData%FocalDistanceZ(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FocalDistanceZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%FocalDistanceZ,1), UBOUND(OutData%FocalDistanceZ,1) + OutData%FocalDistanceZ(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + OutData%PulseSpacing = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MeasurementInterval = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%URefLid = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%LidRadialVel = TRANSFER(IntKiBuf(Int_Xferred), OutData%LidRadialVel) + Int_Xferred = Int_Xferred + 1 + OutData%ConsiderHubMotion = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -1126,7 +1059,7 @@ SUBROUTINE InflowWind_UnPackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL IfW_FFWind_UnpackInitInput( Re_Buf, Db_Buf, Int_Buf, OutData%FF, ErrStat2, ErrMsg2 ) ! FF + CALL InflowWind_IO_Unpackgrid3d_initinputtype( Re_Buf, Db_Buf, Int_Buf, OutData%FF, ErrStat2, ErrMsg2 ) ! FF CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1164,27 +1097,50 @@ SUBROUTINE InflowWind_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCod CALL NWTC_Library_Copyfileinfotype( SrcInitInputData%WindType2Data, DstInitInputData%WindType2Data, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + DstInitInputData%OutputAccel = SrcInitInputData%OutputAccel CALL Lidar_CopyInitInput( SrcInitInputData%lidar, DstInitInputData%lidar, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_4Dext_CopyInitInput( SrcInitInputData%FDext, DstInitInputData%FDext, CtrlCode, ErrStat2, ErrMsg2 ) + CALL InflowWind_IO_Copygrid4d_initinputtype( SrcInitInputData%FDext, DstInitInputData%FDext, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + DstInitInputData%RadAvg = SrcInitInputData%RadAvg + DstInitInputData%MHK = SrcInitInputData%MHK + DstInitInputData%WtrDpth = SrcInitInputData%WtrDpth + DstInitInputData%MSL2SWL = SrcInitInputData%MSL2SWL + DstInitInputData%BoxExceedAllowIdx = SrcInitInputData%BoxExceedAllowIdx + DstInitInputData%BoxExceedAllowF = SrcInitInputData%BoxExceedAllowF END SUBROUTINE InflowWind_CopyInitInput - SUBROUTINE InflowWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE InflowWind_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(InflowWind_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedFileData, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroyfileinfotype( InitInputData%WindType2Data, ErrStat, ErrMsg ) - CALL Lidar_DestroyInitInput( InitInputData%lidar, ErrStat, ErrMsg ) - CALL IfW_4Dext_DestroyInitInput( InitInputData%FDext, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedFileData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroyfileinfotype( InitInputData%WindType2Data, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Lidar_DestroyInitInput( InitInputData%lidar, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_IO_Destroygrid4d_initinputtype( InitInputData%FDext, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE InflowWind_DestroyInitInput SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1266,6 +1222,7 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 1 ! OutputAccel Int_BufSz = Int_BufSz + 3 ! lidar: size of buffers for each call to pack subtype CALL Lidar_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, .TRUE. ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -1284,7 +1241,7 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! FDext: size of buffers for each call to pack subtype - CALL IfW_4Dext_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, .TRUE. ) ! FDext + CALL InflowWind_IO_Packgrid4d_initinputtype( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, .TRUE. ) ! FDext CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1300,6 +1257,12 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Re_BufSz = Re_BufSz + 1 ! RadAvg + Int_BufSz = Int_BufSz + 1 ! MHK + Re_BufSz = Re_BufSz + 1 ! WtrDpth + Re_BufSz = Re_BufSz + 1 ! MSL2SWL + Int_BufSz = Int_BufSz + 1 ! BoxExceedAllowIdx + Int_BufSz = Int_BufSz + 1 ! BoxExceedAllowF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1405,6 +1368,8 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + IntKiBuf(Int_Xferred) = TRANSFER(InData%OutputAccel, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 CALL Lidar_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, OnlySize ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1433,7 +1398,7 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL IfW_4Dext_PackInitInput( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, OnlySize ) ! FDext + CALL InflowWind_IO_Packgrid4d_initinputtype( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, OnlySize ) ! FDext CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -1461,6 +1426,18 @@ SUBROUTINE InflowWind_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + ReKiBuf(Re_Xferred) = InData%RadAvg + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%MHK + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WtrDpth + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MSL2SWL + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%BoxExceedAllowIdx + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%BoxExceedAllowF, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE InflowWind_PackInitInput SUBROUTINE InflowWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1591,6 +1568,8 @@ SUBROUTINE InflowWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + OutData%OutputAccel = TRANSFER(IntKiBuf(Int_Xferred), OutData%OutputAccel) + Int_Xferred = Int_Xferred + 1 Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -1664,13 +1643,25 @@ SUBROUTINE InflowWind_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrS Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL IfW_4Dext_UnpackInitInput( Re_Buf, Db_Buf, Int_Buf, OutData%FDext, ErrStat2, ErrMsg2 ) ! FDext + CALL InflowWind_IO_Unpackgrid4d_initinputtype( Re_Buf, Db_Buf, Int_Buf, OutData%FDext, ErrStat2, ErrMsg2 ) ! FDext CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + OutData%RadAvg = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MHK = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WtrDpth = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%MSL2SWL = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%BoxExceedAllowIdx = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%BoxExceedAllowF = TRANSFER(IntKiBuf(Int_Xferred), OutData%BoxExceedAllowF) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE InflowWind_UnPackInitInput SUBROUTINE InflowWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -1715,7 +1706,7 @@ SUBROUTINE InflowWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, Ctrl CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - CALL InflowWind_Copywindfilemetadata( SrcInitOutputData%WindFileInfo, DstInitOutputData%WindFileInfo, CtrlCode, ErrStat2, ErrMsg2 ) + CALL InflowWind_IO_Copywindfiledat( SrcInitOutputData%WindFileInfo, DstInitOutputData%WindFileInfo, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN IF (ALLOCATED(SrcInitOutputData%LinNames_y)) THEN @@ -1780,23 +1771,37 @@ SUBROUTINE InflowWind_CopyInitOutput( SrcInitOutputData, DstInitOutputData, Ctrl ENDIF END SUBROUTINE InflowWind_CopyInitOutput - SUBROUTINE InflowWind_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE InflowWind_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(InflowWind_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN DEALLOCATE(InitOutputData%WriteOutputUnt) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) - CALL InflowWind_Destroywindfilemetadata( InitOutputData%WindFileInfo, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_IO_Destroywindfiledat( InitOutputData%WindFileInfo, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitOutputData%LinNames_y)) THEN DEALLOCATE(InitOutputData%LinNames_y) ENDIF @@ -1878,7 +1883,7 @@ SUBROUTINE InflowWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSta DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 3 ! WindFileInfo: size of buffers for each call to pack subtype - CALL InflowWind_Packwindfilemetadata( Re_Buf, Db_Buf, Int_Buf, InData%WindFileInfo, ErrStat2, ErrMsg2, .TRUE. ) ! WindFileInfo + CALL InflowWind_IO_Packwindfiledat( Re_Buf, Db_Buf, Int_Buf, InData%WindFileInfo, ErrStat2, ErrMsg2, .TRUE. ) ! WindFileInfo CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2008,7 +2013,7 @@ SUBROUTINE InflowWind_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSta ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL InflowWind_Packwindfilemetadata( Re_Buf, Db_Buf, Int_Buf, InData%WindFileInfo, ErrStat2, ErrMsg2, OnlySize ) ! WindFileInfo + CALL InflowWind_IO_Packwindfiledat( Re_Buf, Db_Buf, Int_Buf, InData%WindFileInfo, ErrStat2, ErrMsg2, OnlySize ) ! WindFileInfo CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2257,7 +2262,7 @@ SUBROUTINE InflowWind_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Err Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL InflowWind_Unpackwindfilemetadata( Re_Buf, Db_Buf, Int_Buf, OutData%WindFileInfo, ErrStat2, ErrMsg2 ) ! WindFileInfo + CALL InflowWind_IO_Unpackwindfiledat( Re_Buf, Db_Buf, Int_Buf, OutData%WindFileInfo, ErrStat2, ErrMsg2 ) ! WindFileInfo CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2360,9 +2365,9 @@ SUBROUTINE InflowWind_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Err END IF END SUBROUTINE InflowWind_UnPackInitOutput - SUBROUTINE InflowWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(InflowWind_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: DstMiscData + SUBROUTINE InflowWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) + TYPE(InflowWind_ParameterType), INTENT(IN) :: SrcParamData + TYPE(InflowWind_ParameterType), INTENT(INOUT) :: DstParamData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -2372,85 +2377,147 @@ SUBROUTINE InflowWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, Err INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_CopyMisc' + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_CopyParam' ! ErrStat = ErrID_None ErrMsg = "" - DstMiscData%TimeIndex = SrcMiscData%TimeIndex - CALL IfW_UniformWind_CopyMisc( SrcMiscData%UniformWind, DstMiscData%UniformWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_TSFFWind_CopyMisc( SrcMiscData%TSFFWind, DstMiscData%TSFFWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_HAWCWind_CopyMisc( SrcMiscData%HAWCWind, DstMiscData%HAWCWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_BladedFFWind_CopyMisc( SrcMiscData%BladedFFWind, DstMiscData%BladedFFWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_UserWind_CopyMisc( SrcMiscData%UserWind, DstMiscData%UserWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_4Dext_CopyMisc( SrcMiscData%FDext, DstMiscData%FDext, CtrlCode, ErrStat2, ErrMsg2 ) + DstParamData%RootFileName = SrcParamData%RootFileName + DstParamData%WindType = SrcParamData%WindType + DstParamData%DT = SrcParamData%DT +IF (ALLOCATED(SrcParamData%WindViXYZprime)) THEN + i1_l = LBOUND(SrcParamData%WindViXYZprime,1) + i1_u = UBOUND(SrcParamData%WindViXYZprime,1) + i2_l = LBOUND(SrcParamData%WindViXYZprime,2) + i2_u = UBOUND(SrcParamData%WindViXYZprime,2) + IF (.NOT. ALLOCATED(DstParamData%WindViXYZprime)) THEN + ALLOCATE(DstParamData%WindViXYZprime(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%WindViXYZprime.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%WindViXYZprime = SrcParamData%WindViXYZprime +ENDIF +IF (ALLOCATED(SrcParamData%WindViXYZ)) THEN + i1_l = LBOUND(SrcParamData%WindViXYZ,1) + i1_u = UBOUND(SrcParamData%WindViXYZ,1) + i2_l = LBOUND(SrcParamData%WindViXYZ,2) + i2_u = UBOUND(SrcParamData%WindViXYZ,2) + IF (.NOT. ALLOCATED(DstParamData%WindViXYZ)) THEN + ALLOCATE(DstParamData%WindViXYZ(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%WindViXYZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%WindViXYZ = SrcParamData%WindViXYZ +ENDIF + CALL IfW_FlowField_Copyflowfieldtype( SrcParamData%FlowField, DstParamData%FlowField, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN -IF (ALLOCATED(SrcMiscData%AllOuts)) THEN - i1_l = LBOUND(SrcMiscData%AllOuts,1) - i1_u = UBOUND(SrcMiscData%AllOuts,1) - IF (.NOT. ALLOCATED(DstMiscData%AllOuts)) THEN - ALLOCATE(DstMiscData%AllOuts(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%PositionAvg)) THEN + i1_l = LBOUND(SrcParamData%PositionAvg,1) + i1_u = UBOUND(SrcParamData%PositionAvg,1) + i2_l = LBOUND(SrcParamData%PositionAvg,2) + i2_u = UBOUND(SrcParamData%PositionAvg,2) + IF (.NOT. ALLOCATED(DstParamData%PositionAvg)) THEN + ALLOCATE(DstParamData%PositionAvg(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%AllOuts.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%PositionAvg.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%AllOuts = SrcMiscData%AllOuts + DstParamData%PositionAvg = SrcParamData%PositionAvg ENDIF -IF (ALLOCATED(SrcMiscData%WindViUVW)) THEN - i1_l = LBOUND(SrcMiscData%WindViUVW,1) - i1_u = UBOUND(SrcMiscData%WindViUVW,1) - i2_l = LBOUND(SrcMiscData%WindViUVW,2) - i2_u = UBOUND(SrcMiscData%WindViUVW,2) - IF (.NOT. ALLOCATED(DstMiscData%WindViUVW)) THEN - ALLOCATE(DstMiscData%WindViUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + DstParamData%NWindVel = SrcParamData%NWindVel + DstParamData%NumOuts = SrcParamData%NumOuts +IF (ALLOCATED(SrcParamData%OutParam)) THEN + i1_l = LBOUND(SrcParamData%OutParam,1) + i1_u = UBOUND(SrcParamData%OutParam,1) + IF (.NOT. ALLOCATED(DstParamData%OutParam)) THEN + ALLOCATE(DstParamData%OutParam(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%WindViUVW.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%OutParam.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%WindViUVW = SrcMiscData%WindViUVW + DO i1 = LBOUND(SrcParamData%OutParam,1), UBOUND(SrcParamData%OutParam,1) + CALL NWTC_Library_Copyoutparmtype( SrcParamData%OutParam(i1), DstParamData%OutParam(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO ENDIF - END SUBROUTINE InflowWind_CopyMisc +IF (ALLOCATED(SrcParamData%OutParamLinIndx)) THEN + i1_l = LBOUND(SrcParamData%OutParamLinIndx,1) + i1_u = UBOUND(SrcParamData%OutParamLinIndx,1) + i2_l = LBOUND(SrcParamData%OutParamLinIndx,2) + i2_u = UBOUND(SrcParamData%OutParamLinIndx,2) + IF (.NOT. ALLOCATED(DstParamData%OutParamLinIndx)) THEN + ALLOCATE(DstParamData%OutParamLinIndx(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%OutParamLinIndx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%OutParamLinIndx = SrcParamData%OutParamLinIndx +ENDIF + CALL Lidar_CopyParam( SrcParamData%lidar, DstParamData%lidar, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstParamData%OutputAccel = SrcParamData%OutputAccel + END SUBROUTINE InflowWind_CopyParam - SUBROUTINE InflowWind_DestroyMisc( MiscData, ErrStat, ErrMsg ) - TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: MiscData + SUBROUTINE InflowWind_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(InflowWind_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" - CALL IfW_UniformWind_DestroyMisc( MiscData%UniformWind, ErrStat, ErrMsg ) - CALL IfW_TSFFWind_DestroyMisc( MiscData%TSFFWind, ErrStat, ErrMsg ) - CALL IfW_HAWCWind_DestroyMisc( MiscData%HAWCWind, ErrStat, ErrMsg ) - CALL IfW_BladedFFWind_DestroyMisc( MiscData%BladedFFWind, ErrStat, ErrMsg ) - CALL IfW_UserWind_DestroyMisc( MiscData%UserWind, ErrStat, ErrMsg ) - CALL IfW_4Dext_DestroyMisc( MiscData%FDext, ErrStat, ErrMsg ) -IF (ALLOCATED(MiscData%AllOuts)) THEN - DEALLOCATE(MiscData%AllOuts) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(ParamData%WindViXYZprime)) THEN + DEALLOCATE(ParamData%WindViXYZprime) ENDIF -IF (ALLOCATED(MiscData%WindViUVW)) THEN - DEALLOCATE(MiscData%WindViUVW) +IF (ALLOCATED(ParamData%WindViXYZ)) THEN + DEALLOCATE(ParamData%WindViXYZ) ENDIF - END SUBROUTINE InflowWind_DestroyMisc + CALL IfW_FlowField_Destroyflowfieldtype( ParamData%FlowField, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(ParamData%PositionAvg)) THEN + DEALLOCATE(ParamData%PositionAvg) +ENDIF +IF (ALLOCATED(ParamData%OutParam)) THEN +DO i1 = LBOUND(ParamData%OutParam,1), UBOUND(ParamData%OutParam,1) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(ParamData%OutParam) +ENDIF +IF (ALLOCATED(ParamData%OutParamLinIndx)) THEN + DEALLOCATE(ParamData%OutParamLinIndx) +ENDIF + CALL Lidar_DestroyParam( ParamData%lidar, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE InflowWind_DestroyParam - SUBROUTINE InflowWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE InflowWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(InflowWind_MiscVarType), INTENT(IN) :: InData + TYPE(InflowWind_ParameterType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -2465,7 +2532,7 @@ SUBROUTINE InflowWind_PackMisc( 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 = 'InflowWind_PackMisc' + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_PackParam' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -2481,120 +2548,90 @@ SUBROUTINE InflowWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! TimeIndex + Int_BufSz = Int_BufSz + 1*LEN(InData%RootFileName) ! RootFileName + Int_BufSz = Int_BufSz + 1 ! WindType + Db_BufSz = Db_BufSz + 1 ! DT + Int_BufSz = Int_BufSz + 1 ! WindViXYZprime allocated yes/no + IF ( ALLOCATED(InData%WindViXYZprime) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! WindViXYZprime upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WindViXYZprime) ! WindViXYZprime + END IF + Int_BufSz = Int_BufSz + 1 ! WindViXYZ allocated yes/no + IF ( ALLOCATED(InData%WindViXYZ) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! WindViXYZ upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WindViXYZ) ! WindViXYZ + END IF ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! UniformWind: size of buffers for each call to pack subtype - CALL IfW_UniformWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%UniformWind, ErrStat2, ErrMsg2, .TRUE. ) ! UniformWind + Int_BufSz = Int_BufSz + 3 ! FlowField: size of buffers for each call to pack subtype + CALL IfW_FlowField_Packflowfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%FlowField, ErrStat2, ErrMsg2, .TRUE. ) ! FlowField CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! UniformWind + IF(ALLOCATED(Re_Buf)) THEN ! FlowField Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! UniformWind + IF(ALLOCATED(Db_Buf)) THEN ! FlowField Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! UniformWind + IF(ALLOCATED(Int_Buf)) THEN ! FlowField Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! TSFFWind: size of buffers for each call to pack subtype - CALL IfW_TSFFWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%TSFFWind, ErrStat2, ErrMsg2, .TRUE. ) ! TSFFWind + Int_BufSz = Int_BufSz + 1 ! PositionAvg allocated yes/no + IF ( ALLOCATED(InData%PositionAvg) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! PositionAvg upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PositionAvg) ! PositionAvg + END IF + Int_BufSz = Int_BufSz + 1 ! NWindVel + Int_BufSz = Int_BufSz + 1 ! NumOuts + 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 ! TSFFWind + IF(ALLOCATED(Re_Buf)) THEN ! OutParam Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! TSFFWind + IF(ALLOCATED(Db_Buf)) THEN ! OutParam Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! TSFFWind + IF(ALLOCATED(Int_Buf)) THEN ! OutParam Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! HAWCWind: size of buffers for each call to pack subtype - CALL IfW_HAWCWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%HAWCWind, ErrStat2, ErrMsg2, .TRUE. ) ! HAWCWind + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! OutParamLinIndx allocated yes/no + IF ( ALLOCATED(InData%OutParamLinIndx) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! OutParamLinIndx upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%OutParamLinIndx) ! OutParamLinIndx + END IF + Int_BufSz = Int_BufSz + 3 ! lidar: size of buffers for each call to pack subtype + CALL Lidar_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, .TRUE. ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! HAWCWind + IF(ALLOCATED(Re_Buf)) THEN ! lidar Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! HAWCWind + IF(ALLOCATED(Db_Buf)) THEN ! lidar Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! HAWCWind + IF(ALLOCATED(Int_Buf)) THEN ! lidar Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Int_BufSz = Int_BufSz + 3 ! BladedFFWind: size of buffers for each call to pack subtype - CALL IfW_BladedFFWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%BladedFFWind, ErrStat2, ErrMsg2, .TRUE. ) ! BladedFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! BladedFFWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! BladedFFWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! BladedFFWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! UserWind: size of buffers for each call to pack subtype - CALL IfW_UserWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%UserWind, ErrStat2, ErrMsg2, .TRUE. ) ! UserWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! UserWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! UserWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! UserWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! FDext: size of buffers for each call to pack subtype - CALL IfW_4Dext_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, .TRUE. ) ! FDext - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! FDext - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! FDext - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! FDext - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 1 ! AllOuts allocated yes/no - IF ( ALLOCATED(InData%AllOuts) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! AllOuts upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%AllOuts) ! AllOuts - END IF - Int_BufSz = Int_BufSz + 1 ! WindViUVW allocated yes/no - IF ( ALLOCATED(InData%WindViUVW) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! WindViUVW upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%WindViUVW) ! WindViUVW - END IF + Int_BufSz = Int_BufSz + 1 ! OutputAccel IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -2622,65 +2659,55 @@ SUBROUTINE InflowWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Db_Xferred = 1 Int_Xferred = 1 - IntKiBuf(Int_Xferred) = InData%TimeIndex + DO I = 1, LEN(InData%RootFileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%RootFileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IntKiBuf(Int_Xferred) = InData%WindType Int_Xferred = Int_Xferred + 1 - CALL IfW_UniformWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%UniformWind, ErrStat2, ErrMsg2, OnlySize ) ! UniformWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + DbKiBuf(Db_Xferred) = InData%DT + Db_Xferred = Db_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%WindViXYZprime) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WindViXYZprime,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindViXYZprime,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WindViXYZprime,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindViXYZprime,2) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_TSFFWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%TSFFWind, ErrStat2, ErrMsg2, OnlySize ) ! TSFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + DO i2 = LBOUND(InData%WindViXYZprime,2), UBOUND(InData%WindViXYZprime,2) + DO i1 = LBOUND(InData%WindViXYZprime,1), UBOUND(InData%WindViXYZprime,1) + ReKiBuf(Re_Xferred) = InData%WindViXYZprime(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WindViXYZ) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WindViXYZ,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindViXYZ,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WindViXYZ,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindViXYZ,2) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_HAWCWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%HAWCWind, ErrStat2, ErrMsg2, OnlySize ) ! HAWCWind + DO i2 = LBOUND(InData%WindViXYZ,2), UBOUND(InData%WindViXYZ,2) + DO i1 = LBOUND(InData%WindViXYZ,1), UBOUND(InData%WindViXYZ,1) + ReKiBuf(Re_Xferred) = InData%WindViXYZ(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + CALL IfW_FlowField_Packflowfieldtype( Re_Buf, Db_Buf, Int_Buf, InData%FlowField, ErrStat2, ErrMsg2, OnlySize ) ! FlowField CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2708,35 +2735,42 @@ SUBROUTINE InflowWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL IfW_BladedFFWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%BladedFFWind, ErrStat2, ErrMsg2, OnlySize ) ! BladedFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + IF ( .NOT. ALLOCATED(InData%PositionAvg) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PositionAvg,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PositionAvg,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PositionAvg,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PositionAvg,2) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_UserWind_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%UserWind, ErrStat2, ErrMsg2, OnlySize ) ! UserWind + DO i2 = LBOUND(InData%PositionAvg,2), UBOUND(InData%PositionAvg,2) + DO i1 = LBOUND(InData%PositionAvg,1), UBOUND(InData%PositionAvg,1) + ReKiBuf(Re_Xferred) = InData%PositionAvg(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IntKiBuf(Int_Xferred) = InData%NWindVel + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumOuts + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%OutParam) ) THEN + IntKiBuf( Int_Xferred ) = 0 + 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) + 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 @@ -2764,7 +2798,29 @@ SUBROUTINE InflowWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - CALL IfW_4Dext_PackMisc( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, OnlySize ) ! FDext + END DO + END IF + IF ( .NOT. ALLOCATED(InData%OutParamLinIndx) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%OutParamLinIndx,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%OutParamLinIndx,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%OutParamLinIndx,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%OutParamLinIndx,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%OutParamLinIndx,2), UBOUND(InData%OutParamLinIndx,2) + DO i1 = LBOUND(InData%OutParamLinIndx,1), UBOUND(InData%OutParamLinIndx,1) + IntKiBuf(Int_Xferred) = InData%OutParamLinIndx(i1,i2) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + CALL Lidar_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, OnlySize ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -2792,48 +2848,15 @@ SUBROUTINE InflowWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - IF ( .NOT. ALLOCATED(InData%AllOuts) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AllOuts,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AllOuts,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%AllOuts,1), UBOUND(InData%AllOuts,1) - ReKiBuf(Re_Xferred) = InData%AllOuts(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%WindViUVW) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%OutputAccel, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WindViUVW,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindViUVW,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WindViUVW,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindViUVW,2) - Int_Xferred = Int_Xferred + 2 + END SUBROUTINE InflowWind_PackParam - DO i2 = LBOUND(InData%WindViUVW,2), UBOUND(InData%WindViUVW,2) - DO i1 = LBOUND(InData%WindViUVW,1), UBOUND(InData%WindViUVW,1) - ReKiBuf(Re_Xferred) = InData%WindViUVW(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - END SUBROUTINE InflowWind_PackMisc - - SUBROUTINE InflowWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE InflowWind_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(InflowWind_MiscVarType), INTENT(INOUT) :: OutData + TYPE(InflowWind_ParameterType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -2846,7 +2869,7 @@ SUBROUTINE InflowWind_UnPackMisc( 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 = 'InflowWind_UnPackMisc' + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_UnPackParam' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -2857,8 +2880,60 @@ SUBROUTINE InflowWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%TimeIndex = IntKiBuf(Int_Xferred) + DO I = 1, LEN(OutData%RootFileName) + OutData%RootFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%WindType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%DT = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WindViXYZprime not allocated + Int_Xferred = Int_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%WindViXYZprime)) DEALLOCATE(OutData%WindViXYZprime) + ALLOCATE(OutData%WindViXYZprime(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WindViXYZprime.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%WindViXYZprime,2), UBOUND(OutData%WindViXYZprime,2) + DO i1 = LBOUND(OutData%WindViXYZprime,1), UBOUND(OutData%WindViXYZprime,1) + OutData%WindViXYZprime(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WindViXYZ not allocated + Int_Xferred = Int_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%WindViXYZ)) DEALLOCATE(OutData%WindViXYZ) + ALLOCATE(OutData%WindViXYZ(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WindViXYZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%WindViXYZ,2), UBOUND(OutData%WindViXYZ,2) + DO i1 = LBOUND(OutData%WindViXYZ,1), UBOUND(OutData%WindViXYZ,1) + OutData%WindViXYZ(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -2892,13 +2967,54 @@ SUBROUTINE InflowWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL IfW_UniformWind_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%UniformWind, ErrStat2, ErrMsg2 ) ! UniformWind + CALL IfW_FlowField_Unpackflowfieldtype( Re_Buf, Db_Buf, Int_Buf, OutData%FlowField, ErrStat2, ErrMsg2 ) ! FlowField CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PositionAvg not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PositionAvg)) DEALLOCATE(OutData%PositionAvg) + ALLOCATE(OutData%PositionAvg(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PositionAvg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%PositionAvg,2), UBOUND(OutData%PositionAvg,2) + DO i1 = LBOUND(OutData%PositionAvg,1), UBOUND(OutData%PositionAvg,1) + OutData%PositionAvg(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + OutData%NWindVel = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NumOuts = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutParam not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%OutParam)) DEALLOCATE(OutData%OutParam) + ALLOCATE(OutData%OutParam(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutParam.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%OutParam,1), UBOUND(OutData%OutParam,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -2932,13 +3048,38 @@ SUBROUTINE InflowWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL IfW_TSFFWind_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%TSFFWind, ErrStat2, ErrMsg2 ) ! TSFFWind + CALL NWTC_Library_Unpackoutparmtype( Re_Buf, Db_Buf, Int_Buf, OutData%OutParam(i1), ErrStat2, ErrMsg2 ) ! OutParam CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutParamLinIndx not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%OutParamLinIndx)) DEALLOCATE(OutData%OutParamLinIndx) + ALLOCATE(OutData%OutParamLinIndx(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutParamLinIndx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%OutParamLinIndx,2), UBOUND(OutData%OutParamLinIndx,2) + DO i1 = LBOUND(OutData%OutParamLinIndx,1), UBOUND(OutData%OutParamLinIndx,1) + OutData%OutParamLinIndx(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -2972,93 +3113,280 @@ SUBROUTINE InflowWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL IfW_HAWCWind_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%HAWCWind, ErrStat2, ErrMsg2 ) ! HAWCWind + CALL Lidar_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%lidar, ErrStat2, ErrMsg2 ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_BladedFFWind_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%BladedFFWind, ErrStat2, ErrMsg2 ) ! BladedFFWind + OutData%OutputAccel = TRANSFER(IntKiBuf(Int_Xferred), OutData%OutputAccel) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE InflowWind_UnPackParam + + SUBROUTINE InflowWind_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(InflowWind_InputType), INTENT(IN) :: SrcInputData + TYPE(InflowWind_InputType), INTENT(INOUT) :: DstInputData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_CopyInput' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcInputData%PositionXYZ)) THEN + i1_l = LBOUND(SrcInputData%PositionXYZ,1) + i1_u = UBOUND(SrcInputData%PositionXYZ,1) + i2_l = LBOUND(SrcInputData%PositionXYZ,2) + i2_u = UBOUND(SrcInputData%PositionXYZ,2) + IF (.NOT. ALLOCATED(DstInputData%PositionXYZ)) THEN + ALLOCATE(DstInputData%PositionXYZ(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%PositionXYZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%PositionXYZ = SrcInputData%PositionXYZ +ENDIF + CALL Lidar_CopyInput( SrcInputData%lidar, DstInputData%lidar, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstInputData%HubPosition = SrcInputData%HubPosition + DstInputData%HubOrientation = SrcInputData%HubOrientation + END SUBROUTINE InflowWind_CopyInput + + SUBROUTINE InflowWind_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(InflowWind_InputType), INTENT(INOUT) :: InputData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyInput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(InputData%PositionXYZ)) THEN + DEALLOCATE(InputData%PositionXYZ) +ENDIF + CALL Lidar_DestroyInput( InputData%lidar, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE InflowWind_DestroyInput + + SUBROUTINE InflowWind_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(InflowWind_InputType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_PackInput' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! PositionXYZ allocated yes/no + IF ( ALLOCATED(InData%PositionXYZ) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! PositionXYZ upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PositionXYZ) ! PositionXYZ + END IF + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! lidar: size of buffers for each call to pack subtype + CALL Lidar_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, .TRUE. ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size + IF(ALLOCATED(Re_Buf)) THEN ! lidar + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) 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 + IF(ALLOCATED(Db_Buf)) THEN ! lidar + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) 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 + IF(ALLOCATED(Int_Buf)) THEN ! lidar + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) END IF - CALL IfW_UserWind_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%UserWind, ErrStat2, ErrMsg2 ) ! UserWind + Re_BufSz = Re_BufSz + SIZE(InData%HubPosition) ! HubPosition + Re_BufSz = Re_BufSz + SIZE(InData%HubOrientation) ! HubOrientation + 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%PositionXYZ) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PositionXYZ,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PositionXYZ,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PositionXYZ,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PositionXYZ,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%PositionXYZ,2), UBOUND(InData%PositionXYZ,2) + DO i1 = LBOUND(InData%PositionXYZ,1), UBOUND(InData%PositionXYZ,1) + ReKiBuf(Re_Xferred) = InData%PositionXYZ(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + CALL Lidar_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, OnlySize ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + DO i1 = LBOUND(InData%HubPosition,1), UBOUND(InData%HubPosition,1) + ReKiBuf(Re_Xferred) = InData%HubPosition(i1) + Re_Xferred = Re_Xferred + 1 + END DO + DO i2 = LBOUND(InData%HubOrientation,2), UBOUND(InData%HubOrientation,2) + DO i1 = LBOUND(InData%HubOrientation,1), UBOUND(InData%HubOrientation,1) + ReKiBuf(Re_Xferred) = InData%HubOrientation(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END SUBROUTINE InflowWind_PackInput + + SUBROUTINE InflowWind_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(InflowWind_InputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_UnPackInput' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PositionXYZ not allocated + Int_Xferred = Int_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%PositionXYZ)) DEALLOCATE(OutData%PositionXYZ) + ALLOCATE(OutData%PositionXYZ(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PositionXYZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%PositionXYZ,2), UBOUND(OutData%PositionXYZ,2) + DO i1 = LBOUND(OutData%PositionXYZ,1), UBOUND(OutData%PositionXYZ,1) + OutData%PositionXYZ(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -3092,59 +3420,34 @@ SUBROUTINE InflowWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL IfW_4Dext_UnpackMisc( Re_Buf, Db_Buf, Int_Buf, OutData%FDext, ErrStat2, ErrMsg2 ) ! FDext + CALL Lidar_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%lidar, ErrStat2, ErrMsg2 ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AllOuts not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%AllOuts)) DEALLOCATE(OutData%AllOuts) - ALLOCATE(OutData%AllOuts(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AllOuts.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%AllOuts,1), UBOUND(OutData%AllOuts,1) - OutData%AllOuts(i1) = ReKiBuf(Re_Xferred) + i1_l = LBOUND(OutData%HubPosition,1) + i1_u = UBOUND(OutData%HubPosition,1) + DO i1 = LBOUND(OutData%HubPosition,1), UBOUND(OutData%HubPosition,1) + OutData%HubPosition(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%HubOrientation,1) + i1_u = UBOUND(OutData%HubOrientation,1) + i2_l = LBOUND(OutData%HubOrientation,2) + i2_u = UBOUND(OutData%HubOrientation,2) + DO i2 = LBOUND(OutData%HubOrientation,2), UBOUND(OutData%HubOrientation,2) + DO i1 = LBOUND(OutData%HubOrientation,1), UBOUND(OutData%HubOrientation,1) + OutData%HubOrientation(i1,i2) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WindViUVW not allocated - Int_Xferred = Int_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%WindViUVW)) DEALLOCATE(OutData%WindViUVW) - ALLOCATE(OutData%WindViUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WindViUVW.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%WindViUVW,2), UBOUND(OutData%WindViUVW,2) - DO i1 = LBOUND(OutData%WindViUVW,1), UBOUND(OutData%WindViUVW,1) - OutData%WindViUVW(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - END SUBROUTINE InflowWind_UnPackMisc + END DO + END SUBROUTINE InflowWind_UnPackInput - SUBROUTINE InflowWind_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(InflowWind_ParameterType), INTENT(IN) :: SrcParamData - TYPE(InflowWind_ParameterType), INTENT(INOUT) :: DstParamData + SUBROUTINE InflowWind_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(InflowWind_OutputType), INTENT(IN) :: SrcOutputData + TYPE(InflowWind_OutputType), INTENT(INOUT) :: DstOutputData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -3154,142 +3457,96 @@ SUBROUTINE InflowWind_CopyParam( SrcParamData, DstParamData, CtrlCode, 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 = 'InflowWind_CopyParam' + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_CopyOutput' ! ErrStat = ErrID_None ErrMsg = "" - DstParamData%RootFileName = SrcParamData%RootFileName - DstParamData%CTTS_Flag = SrcParamData%CTTS_Flag - DstParamData%RotateWindBox = SrcParamData%RotateWindBox - DstParamData%DT = SrcParamData%DT - DstParamData%PropagationDir = SrcParamData%PropagationDir - DstParamData%VFlowAngle = SrcParamData%VFlowAngle - DstParamData%RotToWind = SrcParamData%RotToWind - DstParamData%RotFromWind = SrcParamData%RotFromWind -IF (ALLOCATED(SrcParamData%WindViXYZprime)) THEN - i1_l = LBOUND(SrcParamData%WindViXYZprime,1) - i1_u = UBOUND(SrcParamData%WindViXYZprime,1) - i2_l = LBOUND(SrcParamData%WindViXYZprime,2) - i2_u = UBOUND(SrcParamData%WindViXYZprime,2) - IF (.NOT. ALLOCATED(DstParamData%WindViXYZprime)) THEN - ALLOCATE(DstParamData%WindViXYZprime(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcOutputData%VelocityUVW)) THEN + i1_l = LBOUND(SrcOutputData%VelocityUVW,1) + i1_u = UBOUND(SrcOutputData%VelocityUVW,1) + i2_l = LBOUND(SrcOutputData%VelocityUVW,2) + i2_u = UBOUND(SrcOutputData%VelocityUVW,2) + IF (.NOT. ALLOCATED(DstOutputData%VelocityUVW)) THEN + ALLOCATE(DstOutputData%VelocityUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%WindViXYZprime.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%VelocityUVW.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%WindViXYZprime = SrcParamData%WindViXYZprime + DstOutputData%VelocityUVW = SrcOutputData%VelocityUVW ENDIF - DstParamData%WindType = SrcParamData%WindType - DstParamData%ReferenceHeight = SrcParamData%ReferenceHeight - DstParamData%RefPosition = SrcParamData%RefPosition - DstParamData%NWindVel = SrcParamData%NWindVel -IF (ALLOCATED(SrcParamData%WindViXYZ)) THEN - i1_l = LBOUND(SrcParamData%WindViXYZ,1) - i1_u = UBOUND(SrcParamData%WindViXYZ,1) - i2_l = LBOUND(SrcParamData%WindViXYZ,2) - i2_u = UBOUND(SrcParamData%WindViXYZ,2) - IF (.NOT. ALLOCATED(DstParamData%WindViXYZ)) THEN - ALLOCATE(DstParamData%WindViXYZ(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcOutputData%AccelUVW)) THEN + i1_l = LBOUND(SrcOutputData%AccelUVW,1) + i1_u = UBOUND(SrcOutputData%AccelUVW,1) + i2_l = LBOUND(SrcOutputData%AccelUVW,2) + i2_u = UBOUND(SrcOutputData%AccelUVW,2) + IF (.NOT. ALLOCATED(DstOutputData%AccelUVW)) THEN + ALLOCATE(DstOutputData%AccelUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%WindViXYZ.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%AccelUVW.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%WindViXYZ = SrcParamData%WindViXYZ + DstOutputData%AccelUVW = SrcOutputData%AccelUVW ENDIF - CALL IfW_UniformWind_CopyParam( SrcParamData%UniformWind, DstParamData%UniformWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_TSFFWind_CopyParam( SrcParamData%TSFFWind, DstParamData%TSFFWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_BladedFFWind_CopyParam( SrcParamData%BladedFFWind, DstParamData%BladedFFWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_HAWCWind_CopyParam( SrcParamData%HAWCWind, DstParamData%HAWCWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_UserWind_CopyParam( SrcParamData%UserWind, DstParamData%UserWind, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - CALL IfW_4Dext_CopyParam( SrcParamData%FDext, DstParamData%FDext, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - DstParamData%NumOuts = SrcParamData%NumOuts -IF (ALLOCATED(SrcParamData%OutParam)) THEN - i1_l = LBOUND(SrcParamData%OutParam,1) - i1_u = UBOUND(SrcParamData%OutParam,1) - IF (.NOT. ALLOCATED(DstParamData%OutParam)) THEN - ALLOCATE(DstParamData%OutParam(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%OutParam.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcParamData%OutParam,1), UBOUND(SrcParamData%OutParam,1) - CALL NWTC_Library_Copyoutparmtype( SrcParamData%OutParam(i1), DstParamData%OutParam(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF -IF (ALLOCATED(SrcParamData%OutParamLinIndx)) THEN - i1_l = LBOUND(SrcParamData%OutParamLinIndx,1) - i1_u = UBOUND(SrcParamData%OutParamLinIndx,1) - i2_l = LBOUND(SrcParamData%OutParamLinIndx,2) - i2_u = UBOUND(SrcParamData%OutParamLinIndx,2) - IF (.NOT. ALLOCATED(DstParamData%OutParamLinIndx)) THEN - ALLOCATE(DstParamData%OutParamLinIndx(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +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 DstParamData%OutParamLinIndx.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%WriteOutput.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%OutParamLinIndx = SrcParamData%OutParamLinIndx + DstOutputData%WriteOutput = SrcOutputData%WriteOutput ENDIF - CALL Lidar_CopyParam( SrcParamData%lidar, DstParamData%lidar, CtrlCode, ErrStat2, ErrMsg2 ) + DstOutputData%DiskVel = SrcOutputData%DiskVel + DstOutputData%HubVel = SrcOutputData%HubVel + CALL Lidar_CopyOutput( SrcOutputData%lidar, DstOutputData%lidar, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE InflowWind_CopyParam + END SUBROUTINE InflowWind_CopyOutput - SUBROUTINE InflowWind_DestroyParam( ParamData, ErrStat, ErrMsg ) - TYPE(InflowWind_ParameterType), INTENT(INOUT) :: ParamData + SUBROUTINE InflowWind_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(InflowWind_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(ParamData%WindViXYZprime)) THEN - DEALLOCATE(ParamData%WindViXYZprime) -ENDIF -IF (ALLOCATED(ParamData%WindViXYZ)) THEN - DEALLOCATE(ParamData%WindViXYZ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(OutputData%VelocityUVW)) THEN + DEALLOCATE(OutputData%VelocityUVW) ENDIF - CALL IfW_UniformWind_DestroyParam( ParamData%UniformWind, ErrStat, ErrMsg ) - CALL IfW_TSFFWind_DestroyParam( ParamData%TSFFWind, ErrStat, ErrMsg ) - CALL IfW_BladedFFWind_DestroyParam( ParamData%BladedFFWind, ErrStat, ErrMsg ) - CALL IfW_HAWCWind_DestroyParam( ParamData%HAWCWind, ErrStat, ErrMsg ) - CALL IfW_UserWind_DestroyParam( ParamData%UserWind, ErrStat, ErrMsg ) - CALL IfW_4Dext_DestroyParam( ParamData%FDext, ErrStat, ErrMsg ) -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) +IF (ALLOCATED(OutputData%AccelUVW)) THEN + DEALLOCATE(OutputData%AccelUVW) ENDIF -IF (ALLOCATED(ParamData%OutParamLinIndx)) THEN - DEALLOCATE(ParamData%OutParamLinIndx) +IF (ALLOCATED(OutputData%WriteOutput)) THEN + DEALLOCATE(OutputData%WriteOutput) ENDIF - CALL Lidar_DestroyParam( ParamData%lidar, ErrStat, ErrMsg ) - END SUBROUTINE InflowWind_DestroyParam + CALL Lidar_DestroyOutput( OutputData%lidar, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE InflowWind_DestroyOutput - SUBROUTINE InflowWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE InflowWind_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(InflowWind_ParameterType), INTENT(IN) :: InData + TYPE(InflowWind_OutputType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -3304,7 +3561,7 @@ SUBROUTINE InflowWind_PackParam( 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 = 'InflowWind_PackParam' + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_PackOutput' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -3320,162 +3577,26 @@ SUBROUTINE InflowWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1*LEN(InData%RootFileName) ! RootFileName - Int_BufSz = Int_BufSz + 1 ! CTTS_Flag - Int_BufSz = Int_BufSz + 1 ! RotateWindBox - Db_BufSz = Db_BufSz + 1 ! DT - Re_BufSz = Re_BufSz + 1 ! PropagationDir - Re_BufSz = Re_BufSz + 1 ! VFlowAngle - Re_BufSz = Re_BufSz + SIZE(InData%RotToWind) ! RotToWind - Re_BufSz = Re_BufSz + SIZE(InData%RotFromWind) ! RotFromWind - Int_BufSz = Int_BufSz + 1 ! WindViXYZprime allocated yes/no - IF ( ALLOCATED(InData%WindViXYZprime) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! WindViXYZprime upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%WindViXYZprime) ! WindViXYZprime - END IF - Int_BufSz = Int_BufSz + 1 ! WindType - Re_BufSz = Re_BufSz + 1 ! ReferenceHeight - Re_BufSz = Re_BufSz + SIZE(InData%RefPosition) ! RefPosition - Int_BufSz = Int_BufSz + 1 ! NWindVel - Int_BufSz = Int_BufSz + 1 ! WindViXYZ allocated yes/no - IF ( ALLOCATED(InData%WindViXYZ) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! WindViXYZ upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%WindViXYZ) ! WindViXYZ + Int_BufSz = Int_BufSz + 1 ! VelocityUVW allocated yes/no + IF ( ALLOCATED(InData%VelocityUVW) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! VelocityUVW upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%VelocityUVW) ! VelocityUVW END IF - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! UniformWind: size of buffers for each call to pack subtype - CALL IfW_UniformWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%UniformWind, ErrStat2, ErrMsg2, .TRUE. ) ! UniformWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! UniformWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! UniformWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! UniformWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! TSFFWind: size of buffers for each call to pack subtype - CALL IfW_TSFFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%TSFFWind, ErrStat2, ErrMsg2, .TRUE. ) ! TSFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! TSFFWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! TSFFWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! TSFFWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! BladedFFWind: size of buffers for each call to pack subtype - CALL IfW_BladedFFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%BladedFFWind, ErrStat2, ErrMsg2, .TRUE. ) ! BladedFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! BladedFFWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! BladedFFWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! BladedFFWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! HAWCWind: size of buffers for each call to pack subtype - CALL IfW_HAWCWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%HAWCWind, ErrStat2, ErrMsg2, .TRUE. ) ! HAWCWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! HAWCWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! HAWCWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! HAWCWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! UserWind: size of buffers for each call to pack subtype - CALL IfW_UserWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%UserWind, ErrStat2, ErrMsg2, .TRUE. ) ! UserWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! UserWind - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! UserWind - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! UserWind - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 3 ! FDext: size of buffers for each call to pack subtype - CALL IfW_4Dext_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, .TRUE. ) ! FDext - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! FDext - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! FDext - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! FDext - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 1 ! NumOuts - 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 + Int_BufSz = Int_BufSz + 1 ! AccelUVW allocated yes/no + IF ( ALLOCATED(InData%AccelUVW) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! AccelUVW upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AccelUVW) ! AccelUVW END IF - Int_BufSz = Int_BufSz + 1 ! OutParamLinIndx allocated yes/no - IF ( ALLOCATED(InData%OutParamLinIndx) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! OutParamLinIndx upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%OutParamLinIndx) ! OutParamLinIndx + 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 + Re_BufSz = Re_BufSz + SIZE(InData%DiskVel) ! DiskVel + Re_BufSz = Re_BufSz + SIZE(InData%HubVel) ! HubVel + ! Allocate buffers for subtypes, if any (we'll get sizes from these) Int_BufSz = Int_BufSz + 3 ! lidar: size of buffers for each call to pack subtype - CALL Lidar_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, .TRUE. ) ! lidar + CALL Lidar_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, .TRUE. ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3518,1277 +3639,42 @@ SUBROUTINE InflowWind_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Db_Xferred = 1 Int_Xferred = 1 - DO I = 1, LEN(InData%RootFileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%RootFileName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = TRANSFER(InData%CTTS_Flag, IntKiBuf(1)) + IF ( .NOT. ALLOCATED(InData%VelocityUVW) ) THEN + IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = TRANSFER(InData%RotateWindBox, IntKiBuf(1)) + ELSE + IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%DT - Db_Xferred = Db_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%PropagationDir - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%VFlowAngle - Re_Xferred = Re_Xferred + 1 - DO i2 = LBOUND(InData%RotToWind,2), UBOUND(InData%RotToWind,2) - DO i1 = LBOUND(InData%RotToWind,1), UBOUND(InData%RotToWind,1) - ReKiBuf(Re_Xferred) = InData%RotToWind(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - DO i2 = LBOUND(InData%RotFromWind,2), UBOUND(InData%RotFromWind,2) - DO i1 = LBOUND(InData%RotFromWind,1), UBOUND(InData%RotFromWind,1) - ReKiBuf(Re_Xferred) = InData%RotFromWind(i1,i2) - Re_Xferred = Re_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelocityUVW,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelocityUVW,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%VelocityUVW,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelocityUVW,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%VelocityUVW,2), UBOUND(InData%VelocityUVW,2) + DO i1 = LBOUND(InData%VelocityUVW,1), UBOUND(InData%VelocityUVW,1) + ReKiBuf(Re_Xferred) = InData%VelocityUVW(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO END DO - END DO - IF ( .NOT. ALLOCATED(InData%WindViXYZprime) ) THEN + END IF + IF ( .NOT. ALLOCATED(InData%AccelUVW) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WindViXYZprime,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindViXYZprime,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccelUVW,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccelUVW,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WindViXYZprime,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindViXYZprime,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%AccelUVW,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AccelUVW,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%WindViXYZprime,2), UBOUND(InData%WindViXYZprime,2) - DO i1 = LBOUND(InData%WindViXYZprime,1), UBOUND(InData%WindViXYZprime,1) - ReKiBuf(Re_Xferred) = InData%WindViXYZprime(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - IntKiBuf(Int_Xferred) = InData%WindType - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%ReferenceHeight - Re_Xferred = Re_Xferred + 1 - DO i1 = LBOUND(InData%RefPosition,1), UBOUND(InData%RefPosition,1) - ReKiBuf(Re_Xferred) = InData%RefPosition(i1) - Re_Xferred = Re_Xferred + 1 - END DO - IntKiBuf(Int_Xferred) = InData%NWindVel - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%WindViXYZ) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WindViXYZ,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindViXYZ,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%WindViXYZ,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindViXYZ,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%WindViXYZ,2), UBOUND(InData%WindViXYZ,2) - DO i1 = LBOUND(InData%WindViXYZ,1), UBOUND(InData%WindViXYZ,1) - ReKiBuf(Re_Xferred) = InData%WindViXYZ(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - CALL IfW_UniformWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%UniformWind, ErrStat2, ErrMsg2, OnlySize ) ! UniformWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_TSFFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%TSFFWind, ErrStat2, ErrMsg2, OnlySize ) ! TSFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_BladedFFWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%BladedFFWind, ErrStat2, ErrMsg2, OnlySize ) ! BladedFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_HAWCWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%HAWCWind, ErrStat2, ErrMsg2, OnlySize ) ! HAWCWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_UserWind_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%UserWind, ErrStat2, ErrMsg2, OnlySize ) ! UserWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - CALL IfW_4Dext_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%FDext, ErrStat2, ErrMsg2, OnlySize ) ! FDext - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IntKiBuf(Int_Xferred) = InData%NumOuts - Int_Xferred = Int_Xferred + 1 - 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%OutParam,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%OutParam,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 - END IF - IF ( .NOT. ALLOCATED(InData%OutParamLinIndx) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%OutParamLinIndx,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%OutParamLinIndx,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%OutParamLinIndx,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%OutParamLinIndx,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%OutParamLinIndx,2), UBOUND(InData%OutParamLinIndx,2) - DO i1 = LBOUND(InData%OutParamLinIndx,1), UBOUND(InData%OutParamLinIndx,1) - IntKiBuf(Int_Xferred) = InData%OutParamLinIndx(i1,i2) - Int_Xferred = Int_Xferred + 1 - END DO - END DO - END IF - CALL Lidar_PackParam( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, OnlySize ) ! lidar - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE InflowWind_PackParam - - SUBROUTINE InflowWind_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(InflowWind_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 = 'InflowWind_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 - DO I = 1, LEN(OutData%RootFileName) - OutData%RootFileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%CTTS_Flag = TRANSFER(IntKiBuf(Int_Xferred), OutData%CTTS_Flag) - Int_Xferred = Int_Xferred + 1 - OutData%RotateWindBox = TRANSFER(IntKiBuf(Int_Xferred), OutData%RotateWindBox) - Int_Xferred = Int_Xferred + 1 - OutData%DT = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 - OutData%PropagationDir = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%VFlowAngle = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - i1_l = LBOUND(OutData%RotToWind,1) - i1_u = UBOUND(OutData%RotToWind,1) - i2_l = LBOUND(OutData%RotToWind,2) - i2_u = UBOUND(OutData%RotToWind,2) - DO i2 = LBOUND(OutData%RotToWind,2), UBOUND(OutData%RotToWind,2) - DO i1 = LBOUND(OutData%RotToWind,1), UBOUND(OutData%RotToWind,1) - OutData%RotToWind(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - i1_l = LBOUND(OutData%RotFromWind,1) - i1_u = UBOUND(OutData%RotFromWind,1) - i2_l = LBOUND(OutData%RotFromWind,2) - i2_u = UBOUND(OutData%RotFromWind,2) - DO i2 = LBOUND(OutData%RotFromWind,2), UBOUND(OutData%RotFromWind,2) - DO i1 = LBOUND(OutData%RotFromWind,1), UBOUND(OutData%RotFromWind,1) - OutData%RotFromWind(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WindViXYZprime not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - 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%WindViXYZprime)) DEALLOCATE(OutData%WindViXYZprime) - ALLOCATE(OutData%WindViXYZprime(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WindViXYZprime.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%WindViXYZprime,2), UBOUND(OutData%WindViXYZprime,2) - DO i1 = LBOUND(OutData%WindViXYZprime,1), UBOUND(OutData%WindViXYZprime,1) - OutData%WindViXYZprime(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - OutData%WindType = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%ReferenceHeight = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - i1_l = LBOUND(OutData%RefPosition,1) - i1_u = UBOUND(OutData%RefPosition,1) - DO i1 = LBOUND(OutData%RefPosition,1), UBOUND(OutData%RefPosition,1) - OutData%RefPosition(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - OutData%NWindVel = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WindViXYZ not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - 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%WindViXYZ)) DEALLOCATE(OutData%WindViXYZ) - ALLOCATE(OutData%WindViXYZ(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WindViXYZ.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%WindViXYZ,2), UBOUND(OutData%WindViXYZ,2) - DO i1 = LBOUND(OutData%WindViXYZ,1), UBOUND(OutData%WindViXYZ,1) - OutData%WindViXYZ(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_UniformWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%UniformWind, ErrStat2, ErrMsg2 ) ! UniformWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_TSFFWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%TSFFWind, ErrStat2, ErrMsg2 ) ! TSFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_BladedFFWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%BladedFFWind, ErrStat2, ErrMsg2 ) ! BladedFFWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_HAWCWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%HAWCWind, ErrStat2, ErrMsg2 ) ! HAWCWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_UserWind_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%UserWind, ErrStat2, ErrMsg2 ) ! UserWind - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL IfW_4Dext_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%FDext, ErrStat2, ErrMsg2 ) ! FDext - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - OutData%NumOuts = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutParam not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%OutParam)) DEALLOCATE(OutData%OutParam) - ALLOCATE(OutData%OutParam(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutParam.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%OutParam,1), UBOUND(OutData%OutParam,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackoutparmtype( Re_Buf, Db_Buf, Int_Buf, OutData%OutParam(i1), ErrStat2, ErrMsg2 ) ! OutParam - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutParamLinIndx not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - i2_l = IntKiBuf( Int_Xferred ) - i2_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%OutParamLinIndx)) DEALLOCATE(OutData%OutParamLinIndx) - ALLOCATE(OutData%OutParamLinIndx(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutParamLinIndx.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%OutParamLinIndx,2), UBOUND(OutData%OutParamLinIndx,2) - DO i1 = LBOUND(OutData%OutParamLinIndx,1), UBOUND(OutData%OutParamLinIndx,1) - OutData%OutParamLinIndx(i1,i2) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END DO - END DO - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL Lidar_UnpackParam( Re_Buf, Db_Buf, Int_Buf, OutData%lidar, ErrStat2, ErrMsg2 ) ! lidar - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE InflowWind_UnPackParam - - SUBROUTINE InflowWind_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(InflowWind_InputType), INTENT(IN) :: SrcInputData - TYPE(InflowWind_InputType), INTENT(INOUT) :: DstInputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_CopyInput' -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(SrcInputData%PositionXYZ)) THEN - i1_l = LBOUND(SrcInputData%PositionXYZ,1) - i1_u = UBOUND(SrcInputData%PositionXYZ,1) - i2_l = LBOUND(SrcInputData%PositionXYZ,2) - i2_u = UBOUND(SrcInputData%PositionXYZ,2) - IF (.NOT. ALLOCATED(DstInputData%PositionXYZ)) THEN - ALLOCATE(DstInputData%PositionXYZ(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%PositionXYZ.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstInputData%PositionXYZ = SrcInputData%PositionXYZ -ENDIF - CALL Lidar_CopyInput( SrcInputData%lidar, DstInputData%lidar, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE InflowWind_CopyInput - - SUBROUTINE InflowWind_DestroyInput( InputData, ErrStat, ErrMsg ) - TYPE(InflowWind_InputType), INTENT(INOUT) :: InputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyInput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(InputData%PositionXYZ)) THEN - DEALLOCATE(InputData%PositionXYZ) -ENDIF - CALL Lidar_DestroyInput( InputData%lidar, ErrStat, ErrMsg ) - END SUBROUTINE InflowWind_DestroyInput - - SUBROUTINE InflowWind_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(InflowWind_InputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_PackInput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! PositionXYZ allocated yes/no - IF ( ALLOCATED(InData%PositionXYZ) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! PositionXYZ upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%PositionXYZ) ! PositionXYZ - END IF - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! lidar: size of buffers for each call to pack subtype - CALL Lidar_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, .TRUE. ) ! lidar - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! lidar - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! lidar - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! lidar - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IF ( .NOT. ALLOCATED(InData%PositionXYZ) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PositionXYZ,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PositionXYZ,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%PositionXYZ,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PositionXYZ,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%PositionXYZ,2), UBOUND(InData%PositionXYZ,2) - DO i1 = LBOUND(InData%PositionXYZ,1), UBOUND(InData%PositionXYZ,1) - ReKiBuf(Re_Xferred) = InData%PositionXYZ(i1,i2) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - CALL Lidar_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, OnlySize ) ! lidar - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END SUBROUTINE InflowWind_PackInput - - SUBROUTINE InflowWind_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(InflowWind_InputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_UnPackInput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PositionXYZ not allocated - Int_Xferred = Int_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%PositionXYZ)) DEALLOCATE(OutData%PositionXYZ) - ALLOCATE(OutData%PositionXYZ(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PositionXYZ.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i2 = LBOUND(OutData%PositionXYZ,2), UBOUND(OutData%PositionXYZ,2) - DO i1 = LBOUND(OutData%PositionXYZ,1), UBOUND(OutData%PositionXYZ,1) - OutData%PositionXYZ(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END DO - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL Lidar_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%lidar, ErrStat2, ErrMsg2 ) ! lidar - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END SUBROUTINE InflowWind_UnPackInput - - SUBROUTINE InflowWind_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(InflowWind_OutputType), INTENT(IN) :: SrcOutputData - TYPE(InflowWind_OutputType), INTENT(INOUT) :: DstOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_CopyOutput' -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(SrcOutputData%VelocityUVW)) THEN - i1_l = LBOUND(SrcOutputData%VelocityUVW,1) - i1_u = UBOUND(SrcOutputData%VelocityUVW,1) - i2_l = LBOUND(SrcOutputData%VelocityUVW,2) - i2_u = UBOUND(SrcOutputData%VelocityUVW,2) - IF (.NOT. ALLOCATED(DstOutputData%VelocityUVW)) THEN - ALLOCATE(DstOutputData%VelocityUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%VelocityUVW.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstOutputData%VelocityUVW = SrcOutputData%VelocityUVW -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 - DstOutputData%DiskVel = SrcOutputData%DiskVel - CALL Lidar_CopyOutput( SrcOutputData%lidar, DstOutputData%lidar, CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - END SUBROUTINE InflowWind_CopyOutput - - SUBROUTINE InflowWind_DestroyOutput( OutputData, ErrStat, ErrMsg ) - TYPE(InflowWind_OutputType), INTENT(INOUT) :: OutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyOutput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(OutputData%VelocityUVW)) THEN - DEALLOCATE(OutputData%VelocityUVW) -ENDIF -IF (ALLOCATED(OutputData%WriteOutput)) THEN - DEALLOCATE(OutputData%WriteOutput) -ENDIF - CALL Lidar_DestroyOutput( OutputData%lidar, ErrStat, ErrMsg ) - END SUBROUTINE InflowWind_DestroyOutput - - SUBROUTINE InflowWind_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(InflowWind_OutputType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_PackOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! VelocityUVW allocated yes/no - IF ( ALLOCATED(InData%VelocityUVW) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! VelocityUVW upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%VelocityUVW) ! VelocityUVW - END IF - Int_BufSz = Int_BufSz + 1 ! 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 - Re_BufSz = Re_BufSz + SIZE(InData%DiskVel) ! DiskVel - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! lidar: size of buffers for each call to pack subtype - CALL Lidar_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, .TRUE. ) ! lidar - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! lidar - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! lidar - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! lidar - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IF ( .NOT. ALLOCATED(InData%VelocityUVW) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%VelocityUVW,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelocityUVW,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%VelocityUVW,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%VelocityUVW,2) - Int_Xferred = Int_Xferred + 2 - - DO i2 = LBOUND(InData%VelocityUVW,2), UBOUND(InData%VelocityUVW,2) - DO i1 = LBOUND(InData%VelocityUVW,1), UBOUND(InData%VelocityUVW,1) - ReKiBuf(Re_Xferred) = InData%VelocityUVW(i1,i2) + DO i2 = LBOUND(InData%AccelUVW,2), UBOUND(InData%AccelUVW,2) + DO i1 = LBOUND(InData%AccelUVW,1), UBOUND(InData%AccelUVW,1) + ReKiBuf(Re_Xferred) = InData%AccelUVW(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO @@ -4811,6 +3697,10 @@ SUBROUTINE InflowWind_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E DO i1 = LBOUND(InData%DiskVel,1), UBOUND(InData%DiskVel,1) ReKiBuf(Re_Xferred) = InData%DiskVel(i1) Re_Xferred = Re_Xferred + 1 + END DO + DO i1 = LBOUND(InData%HubVel,1), UBOUND(InData%HubVel,1) + ReKiBuf(Re_Xferred) = InData%HubVel(i1) + Re_Xferred = Re_Xferred + 1 END DO CALL Lidar_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%lidar, ErrStat2, ErrMsg2, OnlySize ) ! lidar CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -4893,6 +3783,29 @@ SUBROUTINE InflowWind_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AccelUVW not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AccelUVW)) DEALLOCATE(OutData%AccelUVW) + ALLOCATE(OutData%AccelUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AccelUVW.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%AccelUVW,2), UBOUND(OutData%AccelUVW,2) + DO i1 = LBOUND(OutData%AccelUVW,1), UBOUND(OutData%AccelUVW,1) + OutData%AccelUVW(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WriteOutput not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -4916,6 +3829,12 @@ SUBROUTINE InflowWind_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat DO i1 = LBOUND(OutData%DiskVel,1), UBOUND(OutData%DiskVel,1) OutData%DiskVel(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + END DO + i1_l = LBOUND(OutData%HubVel,1) + i1_u = UBOUND(OutData%HubVel,1) + DO i1 = LBOUND(OutData%HubVel,1), UBOUND(OutData%HubVel,1) + OutData%HubVel(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END DO Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 @@ -4976,15 +3895,27 @@ SUBROUTINE InflowWind_CopyContState( SrcContStateData, DstContStateData, CtrlCod DstContStateData%DummyContState = SrcContStateData%DummyContState END SUBROUTINE InflowWind_CopyContState - SUBROUTINE InflowWind_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE InflowWind_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(InflowWind_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE InflowWind_DestroyContState SUBROUTINE InflowWind_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -5101,15 +4032,27 @@ SUBROUTINE InflowWind_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCod DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE InflowWind_CopyDiscState - SUBROUTINE InflowWind_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE InflowWind_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(InflowWind_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE InflowWind_DestroyDiscState SUBROUTINE InflowWind_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -5226,15 +4169,27 @@ SUBROUTINE InflowWind_CopyConstrState( SrcConstrStateData, DstConstrStateData, C DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE InflowWind_CopyConstrState - SUBROUTINE InflowWind_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE InflowWind_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(InflowWind_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE InflowWind_DestroyConstrState SUBROUTINE InflowWind_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -5351,22 +4306,241 @@ SUBROUTINE InflowWind_CopyOtherState( SrcOtherStateData, DstOtherStateData, Ctrl DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState END SUBROUTINE InflowWind_CopyOtherState - SUBROUTINE InflowWind_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) - TYPE(InflowWind_OtherStateType), INTENT(INOUT) :: OtherStateData + SUBROUTINE InflowWind_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(InflowWind_OtherStateType), INTENT(INOUT) :: OtherStateData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyOtherState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE InflowWind_DestroyOtherState + + SUBROUTINE InflowWind_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(InflowWind_OtherStateType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_PackOtherState' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! DummyOtherState + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%DummyOtherState + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_PackOtherState + + SUBROUTINE InflowWind_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(InflowWind_OtherStateType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_UnPackOtherState' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%DummyOtherState = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE InflowWind_UnPackOtherState + + SUBROUTINE InflowWind_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) + TYPE(InflowWind_MiscVarType), INTENT(IN) :: SrcMiscData + TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: DstMiscData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_CopyMisc' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcMiscData%AllOuts)) THEN + i1_l = LBOUND(SrcMiscData%AllOuts,1) + i1_u = UBOUND(SrcMiscData%AllOuts,1) + IF (.NOT. ALLOCATED(DstMiscData%AllOuts)) THEN + ALLOCATE(DstMiscData%AllOuts(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%AllOuts.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%AllOuts = SrcMiscData%AllOuts +ENDIF +IF (ALLOCATED(SrcMiscData%WindViUVW)) THEN + i1_l = LBOUND(SrcMiscData%WindViUVW,1) + i1_u = UBOUND(SrcMiscData%WindViUVW,1) + i2_l = LBOUND(SrcMiscData%WindViUVW,2) + i2_u = UBOUND(SrcMiscData%WindViUVW,2) + IF (.NOT. ALLOCATED(DstMiscData%WindViUVW)) THEN + ALLOCATE(DstMiscData%WindViUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%WindViUVW.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%WindViUVW = SrcMiscData%WindViUVW +ENDIF +IF (ALLOCATED(SrcMiscData%WindAiUVW)) THEN + i1_l = LBOUND(SrcMiscData%WindAiUVW,1) + i1_u = UBOUND(SrcMiscData%WindAiUVW,1) + i2_l = LBOUND(SrcMiscData%WindAiUVW,2) + i2_u = UBOUND(SrcMiscData%WindAiUVW,2) + IF (.NOT. ALLOCATED(DstMiscData%WindAiUVW)) THEN + ALLOCATE(DstMiscData%WindAiUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%WindAiUVW.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%WindAiUVW = SrcMiscData%WindAiUVW +ENDIF + CALL InflowWind_CopyInput( SrcMiscData%u_Avg, DstMiscData%u_Avg, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL InflowWind_CopyOutput( SrcMiscData%y_Avg, DstMiscData%y_Avg, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL InflowWind_CopyInput( SrcMiscData%u_Hub, DstMiscData%u_Hub, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL InflowWind_CopyOutput( SrcMiscData%y_Hub, DstMiscData%y_Hub, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + END SUBROUTINE InflowWind_CopyMisc + + SUBROUTINE InflowWind_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" - END SUBROUTINE InflowWind_DestroyOtherState - SUBROUTINE InflowWind_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(MiscData%AllOuts)) THEN + DEALLOCATE(MiscData%AllOuts) +ENDIF +IF (ALLOCATED(MiscData%WindViUVW)) THEN + DEALLOCATE(MiscData%WindViUVW) +ENDIF +IF (ALLOCATED(MiscData%WindAiUVW)) THEN + DEALLOCATE(MiscData%WindAiUVW) +ENDIF + CALL InflowWind_DestroyInput( MiscData%u_Avg, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyOutput( MiscData%y_Avg, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyInput( MiscData%u_Hub, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyOutput( MiscData%y_Hub, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END SUBROUTINE InflowWind_DestroyMisc + + SUBROUTINE InflowWind_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(InflowWind_OtherStateType), INTENT(IN) :: InData + TYPE(InflowWind_MiscVarType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -5381,7 +4555,7 @@ SUBROUTINE InflowWind_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSta LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_PackOtherState' + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_PackMisc' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -5397,7 +4571,90 @@ SUBROUTINE InflowWind_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSta Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! DummyOtherState + Int_BufSz = Int_BufSz + 1 ! AllOuts allocated yes/no + IF ( ALLOCATED(InData%AllOuts) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AllOuts upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AllOuts) ! AllOuts + END IF + Int_BufSz = Int_BufSz + 1 ! WindViUVW allocated yes/no + IF ( ALLOCATED(InData%WindViUVW) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! WindViUVW upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WindViUVW) ! WindViUVW + END IF + Int_BufSz = Int_BufSz + 1 ! WindAiUVW allocated yes/no + IF ( ALLOCATED(InData%WindAiUVW) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! WindAiUVW upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WindAiUVW) ! WindAiUVW + END IF + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! u_Avg: size of buffers for each call to pack subtype + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_Avg, ErrStat2, ErrMsg2, .TRUE. ) ! u_Avg + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! u_Avg + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! u_Avg + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! u_Avg + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! y_Avg: size of buffers for each call to pack subtype + CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_Avg, ErrStat2, ErrMsg2, .TRUE. ) ! y_Avg + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! y_Avg + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! y_Avg + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! y_Avg + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! u_Hub: size of buffers for each call to pack subtype + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_Hub, ErrStat2, ErrMsg2, .TRUE. ) ! u_Hub + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! u_Hub + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! u_Hub + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! u_Hub + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! y_Hub: size of buffers for each call to pack subtype + CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_Hub, ErrStat2, ErrMsg2, .TRUE. ) ! y_Hub + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! y_Hub + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! y_Hub + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! y_Hub + 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 @@ -5425,15 +4682,180 @@ SUBROUTINE InflowWind_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrSta Db_Xferred = 1 Int_Xferred = 1 - ReKiBuf(Re_Xferred) = InData%DummyOtherState - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE InflowWind_PackOtherState + IF ( .NOT. ALLOCATED(InData%AllOuts) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AllOuts,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AllOuts,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AllOuts,1), UBOUND(InData%AllOuts,1) + ReKiBuf(Re_Xferred) = InData%AllOuts(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WindViUVW) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WindViUVW,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindViUVW,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WindViUVW,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindViUVW,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%WindViUVW,2), UBOUND(InData%WindViUVW,2) + DO i1 = LBOUND(InData%WindViUVW,1), UBOUND(InData%WindViUVW,1) + ReKiBuf(Re_Xferred) = InData%WindViUVW(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WindAiUVW) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WindAiUVW,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindAiUVW,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WindAiUVW,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WindAiUVW,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%WindAiUVW,2), UBOUND(InData%WindAiUVW,2) + DO i1 = LBOUND(InData%WindAiUVW,1), UBOUND(InData%WindAiUVW,1) + ReKiBuf(Re_Xferred) = InData%WindAiUVW(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_Avg, ErrStat2, ErrMsg2, OnlySize ) ! u_Avg + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_Avg, ErrStat2, ErrMsg2, OnlySize ) ! y_Avg + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL InflowWind_PackInput( Re_Buf, Db_Buf, Int_Buf, InData%u_Hub, ErrStat2, ErrMsg2, OnlySize ) ! u_Hub + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL InflowWind_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_Hub, ErrStat2, ErrMsg2, OnlySize ) ! y_Hub + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + END SUBROUTINE InflowWind_PackMisc - SUBROUTINE InflowWind_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE InflowWind_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(InflowWind_OtherStateType), INTENT(INOUT) :: OutData + TYPE(InflowWind_MiscVarType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -5442,9 +4864,11 @@ SUBROUTINE InflowWind_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, 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) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_UnPackOtherState' + CHARACTER(*), PARAMETER :: RoutineName = 'InflowWind_UnPackMisc' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -5455,9 +4879,231 @@ SUBROUTINE InflowWind_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, Err Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - OutData%DummyOtherState = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE InflowWind_UnPackOtherState + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AllOuts not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AllOuts)) DEALLOCATE(OutData%AllOuts) + ALLOCATE(OutData%AllOuts(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AllOuts.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AllOuts,1), UBOUND(OutData%AllOuts,1) + OutData%AllOuts(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WindViUVW not allocated + Int_Xferred = Int_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%WindViUVW)) DEALLOCATE(OutData%WindViUVW) + ALLOCATE(OutData%WindViUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WindViUVW.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%WindViUVW,2), UBOUND(OutData%WindViUVW,2) + DO i1 = LBOUND(OutData%WindViUVW,1), UBOUND(OutData%WindViUVW,1) + OutData%WindViUVW(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WindAiUVW not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%WindAiUVW)) DEALLOCATE(OutData%WindAiUVW) + ALLOCATE(OutData%WindAiUVW(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WindAiUVW.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%WindAiUVW,2), UBOUND(OutData%WindAiUVW,2) + DO i1 = LBOUND(OutData%WindAiUVW,1), UBOUND(OutData%WindAiUVW,1) + OutData%WindAiUVW(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u_Avg, ErrStat2, ErrMsg2 ) ! u_Avg + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y_Avg, ErrStat2, ErrMsg2 ) ! y_Avg + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_UnpackInput( Re_Buf, Db_Buf, Int_Buf, OutData%u_Hub, ErrStat2, ErrMsg2 ) ! u_Hub + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL InflowWind_UnpackOutput( Re_Buf, Db_Buf, Int_Buf, OutData%y_Hub, ErrStat2, ErrMsg2 ) ! y_Hub + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END SUBROUTINE InflowWind_UnPackMisc SUBROUTINE InflowWind_Input_ExtrapInterp(u, t, u_out, t_out, ErrStat, ErrMsg ) @@ -5566,6 +5212,16 @@ SUBROUTINE InflowWind_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, END IF ! check if allocated CALL Lidar_Input_ExtrapInterp1( u1%lidar, u2%lidar, tin, u_out%lidar, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + DO i1 = LBOUND(u_out%HubPosition,1),UBOUND(u_out%HubPosition,1) + b = -(u1%HubPosition(i1) - u2%HubPosition(i1)) + u_out%HubPosition(i1) = u1%HubPosition(i1) + b * ScaleFactor + END DO + DO i2 = LBOUND(u_out%HubOrientation,2),UBOUND(u_out%HubOrientation,2) + DO i1 = LBOUND(u_out%HubOrientation,1),UBOUND(u_out%HubOrientation,1) + b = -(u1%HubOrientation(i1,i2) - u2%HubOrientation(i1,i2)) + u_out%HubOrientation(i1,i2) = u1%HubOrientation(i1,i2) + b * ScaleFactor + END DO + END DO END SUBROUTINE InflowWind_Input_ExtrapInterp1 @@ -5636,6 +5292,18 @@ SUBROUTINE InflowWind_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrSt END IF ! check if allocated CALL Lidar_Input_ExtrapInterp2( u1%lidar, u2%lidar, u3%lidar, tin, u_out%lidar, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + DO i1 = LBOUND(u_out%HubPosition,1),UBOUND(u_out%HubPosition,1) + b = (t(3)**2*(u1%HubPosition(i1) - u2%HubPosition(i1)) + t(2)**2*(-u1%HubPosition(i1) + u3%HubPosition(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%HubPosition(i1) + t(3)*u2%HubPosition(i1) - t(2)*u3%HubPosition(i1) ) * scaleFactor + u_out%HubPosition(i1) = u1%HubPosition(i1) + b + c * t_out + END DO + DO i2 = LBOUND(u_out%HubOrientation,2),UBOUND(u_out%HubOrientation,2) + DO i1 = LBOUND(u_out%HubOrientation,1),UBOUND(u_out%HubOrientation,1) + b = (t(3)**2*(u1%HubOrientation(i1,i2) - u2%HubOrientation(i1,i2)) + t(2)**2*(-u1%HubOrientation(i1,i2) + u3%HubOrientation(i1,i2)))* scaleFactor + c = ( (t(2)-t(3))*u1%HubOrientation(i1,i2) + t(3)*u2%HubOrientation(i1,i2) - t(2)*u3%HubOrientation(i1,i2) ) * scaleFactor + u_out%HubOrientation(i1,i2) = u1%HubOrientation(i1,i2) + b + c * t_out + END DO + END DO END SUBROUTINE InflowWind_Input_ExtrapInterp2 @@ -5743,6 +5411,14 @@ SUBROUTINE InflowWind_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, END DO END DO END IF ! check if allocated +IF (ALLOCATED(y_out%AccelUVW) .AND. ALLOCATED(y1%AccelUVW)) THEN + DO i2 = LBOUND(y_out%AccelUVW,2),UBOUND(y_out%AccelUVW,2) + DO i1 = LBOUND(y_out%AccelUVW,1),UBOUND(y_out%AccelUVW,1) + b = -(y1%AccelUVW(i1,i2) - y2%AccelUVW(i1,i2)) + y_out%AccelUVW(i1,i2) = y1%AccelUVW(i1,i2) + b * ScaleFactor + END DO + END DO +END IF ! check if allocated IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) b = -(y1%WriteOutput(i1) - y2%WriteOutput(i1)) @@ -5752,6 +5428,10 @@ SUBROUTINE InflowWind_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, DO i1 = LBOUND(y_out%DiskVel,1),UBOUND(y_out%DiskVel,1) b = -(y1%DiskVel(i1) - y2%DiskVel(i1)) y_out%DiskVel(i1) = y1%DiskVel(i1) + b * ScaleFactor + END DO + DO i1 = LBOUND(y_out%HubVel,1),UBOUND(y_out%HubVel,1) + b = -(y1%HubVel(i1) - y2%HubVel(i1)) + y_out%HubVel(i1) = y1%HubVel(i1) + b * ScaleFactor END DO CALL Lidar_Output_ExtrapInterp1( y1%lidar, y2%lidar, tin, y_out%lidar, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) @@ -5823,6 +5503,15 @@ SUBROUTINE InflowWind_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrS END DO END DO END IF ! check if allocated +IF (ALLOCATED(y_out%AccelUVW) .AND. ALLOCATED(y1%AccelUVW)) THEN + DO i2 = LBOUND(y_out%AccelUVW,2),UBOUND(y_out%AccelUVW,2) + DO i1 = LBOUND(y_out%AccelUVW,1),UBOUND(y_out%AccelUVW,1) + b = (t(3)**2*(y1%AccelUVW(i1,i2) - y2%AccelUVW(i1,i2)) + t(2)**2*(-y1%AccelUVW(i1,i2) + y3%AccelUVW(i1,i2)))* scaleFactor + c = ( (t(2)-t(3))*y1%AccelUVW(i1,i2) + t(3)*y2%AccelUVW(i1,i2) - t(2)*y3%AccelUVW(i1,i2) ) * scaleFactor + y_out%AccelUVW(i1,i2) = y1%AccelUVW(i1,i2) + b + c * t_out + END DO + END DO +END IF ! check if allocated IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) b = (t(3)**2*(y1%WriteOutput(i1) - y2%WriteOutput(i1)) + t(2)**2*(-y1%WriteOutput(i1) + y3%WriteOutput(i1)))* scaleFactor @@ -5834,6 +5523,11 @@ SUBROUTINE InflowWind_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrS b = (t(3)**2*(y1%DiskVel(i1) - y2%DiskVel(i1)) + t(2)**2*(-y1%DiskVel(i1) + y3%DiskVel(i1)))* scaleFactor c = ( (t(2)-t(3))*y1%DiskVel(i1) + t(3)*y2%DiskVel(i1) - t(2)*y3%DiskVel(i1) ) * scaleFactor y_out%DiskVel(i1) = y1%DiskVel(i1) + b + c * t_out + END DO + DO i1 = LBOUND(y_out%HubVel,1),UBOUND(y_out%HubVel,1) + b = (t(3)**2*(y1%HubVel(i1) - y2%HubVel(i1)) + t(2)**2*(-y1%HubVel(i1) + y3%HubVel(i1)))* scaleFactor + c = ( (t(2)-t(3))*y1%HubVel(i1) + t(3)*y2%HubVel(i1) - t(2)*y3%HubVel(i1) ) * scaleFactor + y_out%HubVel(i1) = y1%HubVel(i1) + b + c * t_out END DO CALL Lidar_Output_ExtrapInterp2( y1%lidar, y2%lidar, y3%lidar, tin, y_out%lidar, tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) diff --git a/modules/inflowwind/src/Lidar.f90 b/modules/inflowwind/src/Lidar.f90 index 10d835849..ec35b2a3f 100644 --- a/modules/inflowwind/src/Lidar.f90 +++ b/modules/inflowwind/src/Lidar.f90 @@ -84,8 +84,12 @@ SUBROUTINE Lidar_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None - ! local variables + ! Temporary variables for error handling + INTEGER(IntKi) :: TmpErrStat !< temporary error message + CHARACTER(ErrMsgLen) :: TmpErrMsg + ! local variables + INTEGER(IntKi) :: IBeam INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None @@ -97,16 +101,28 @@ SUBROUTINE Lidar_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init ErrStat = ErrID_None ErrMsg = "" - - - - !............................................................................................ - ! Define parameters here: - !............................................................................................ + + ! Check for errors in the InflowWind Input File - p%lidar%RotorApexOffsetPos = InitInp%lidar%RotorApexOffsetPos + ! Make sure that NumPulseGate makes sense + IF ( (p%lidar%SensorType == 3) .and. (p%lidar%NumPulseGate < 0 .OR. p%lidar%NumPulseGate > 5) ) THEN + CALL SetErrStat( ErrID_Fatal, 'NumPulseGate must be greater than or equal to zero and less than 5.', & + ErrStat, ErrMsg, RoutineName ) + RETURN + ENDIF + + ! Make sure that multiple beams are only used when using single point beams + IF ( p%lidar%NumBeam > 1 .AND. p%lidar%SensorType > 1) THEN + CALL SetErrStat( ErrID_Fatal, 'Multiple beams can only be used with single point lidar', & + ErrStat, ErrMsg, RoutineName ) + RETURN + ENDIF + + CALL AllocAry(p%lidar%MsrPosition , 3, p%lidar%NumBeam, 'Array for measurement coordinates', TmpErrStat, TmpErrMsg ) + CALL SetErrStat( TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName) + IF ( ErrStat>= AbortErrLev ) RETURN - p%lidar%SensorType = InitInp%lidar%SensorType + IF (p%lidar%SensorType == SensorType_None) THEN p%lidar%NumPulseGate = 0 ELSEIF (p%lidar%SensorType == SensorType_SinglePoint) THEN @@ -115,13 +131,13 @@ SUBROUTINE Lidar_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init ! variables for both pulsed and continuous-wave lidars - CALL InflowWind_GetMean(0.0_DbKi, InitInp%lidar%TMax, Interval, InitInp%lidar%HubPosition, TempWindSpeed, & - p, x, xd, z, OtherState, m, ErrStat2, ErrMsg2 ) + + - p%lidar%SpatialRes = 0.5_ReKi*TempWindSpeed(1)*Interval + p%lidar%SpatialRes = 0.5_ReKi*p%lidar%URefLid*Interval p%lidar%RayRangeSq = (Pi*(BeamRad**2)/LsrWavLen)**2 - p%lidar%LidRadialVel = InitInp%lidar%LidRadialVel !.FALSE. + IF (p%lidar%SensorType == SensorType_ContinuousLidar) THEN @@ -132,12 +148,12 @@ SUBROUTINE Lidar_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init ELSEIF (p%lidar%SensorType == SensorType_PulsedLidar) THEN p%lidar%WtFnTrunc = 0.01_ReKi - p%lidar%NumPulseGate = InitInp%lidar%NumPulseGate + ! values for the WindCube - p%lidar%DeltaP = 30.0_ReKi + ! p%lidar%DeltaP = 30.0_ReKi !Replaced by pulse spacing p%lidar%DeltaR = 30.0_ReKi - p%lidar%PulseRangeOne = 35.0_ReKi + ! p%lidar%PulseRangeOne = 50.0 ReKi ! Replaced by the focal distance p%lidar%r_p = p%lidar%DeltaR/(2.0_ReKi*SQRT(LOG(2.0_ReKi))) @@ -165,8 +181,10 @@ SUBROUTINE Lidar_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init ! Define initial guess for the system inputs here: !............................................................................................ - u%lidar%LidPosition = InitInp%lidar%HubPosition - u%lidar%MsrPosition = InitInp%lidar%HubPosition + (/ 50.0, 0.0, 0.0 /) !bjj: todo FIXME with initial guess of lidar focus. + p%lidar%LidPosition = InitInp%lidar%HubPosition + DO IBeam = 1,p%lidar%NumBeam + p%lidar%MsrPosition(:,IBeam) = (/ p%lidar%FocalDistanceX(IBeam), p%lidar%FocalDistanceY(IBeam), p%lidar%FocalDistanceZ(IBeam) /) !bjj: todo FIXME with initial guess of lidar focus. + END DO u%lidar%PulseLidEl = 0.0_ReKi u%lidar%PulseLidAz = 0.0_ReKi @@ -179,20 +197,48 @@ SUBROUTINE Lidar_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, Init ! IF (ErrStat >= AbortErrLev) RETURN !y%WriteOutput = 0 - - CALL AllocAry( y%lidar%LidSpeed, p%lidar%NumPulseGate, 'y%lidar%LidSpeed', ErrStat2, ErrMsg2 ) + IF (p%lidar%SensorType == SensorType_SinglePoint) THEN + CALL AllocAry( y%lidar%LidSpeed, p%lidar%NumBeam, 'y%lidar%LidSpeed', ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - !CALL AllocAry( y%LidErr, p%NumPulseGate, 'y%LidErr', ErrStat2, ErrMsg2 ) - ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + !CALL AllocAry( y%LidErr, p%NumPulseGate, 'y%LidErr', ErrStat2, ErrMsg2 ) + ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + + CALL AllocAry( y%lidar%WtTrunc, p%lidar%NumBeam, 'y%lidar%WtTrunc', ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + + CALL AllocAry( y%lidar%MsrPositionsX, p%lidar%NumBeam, 'y%lidar%MsrPositionsX', ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + + CALL AllocAry( y%lidar%MsrPositionsY, p%lidar%NumBeam, 'y%lidar%MsrPositionsY', ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + + CALL AllocAry( y%lidar%MsrPositionsZ, p%lidar%NumBeam, 'y%lidar%MsrPositionsZ', ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + ELSEIF (p%lidar%NumPulseGate > 0) then ! the Cray Fortran compiler doesn't like allocating size zero + CALL AllocAry( y%lidar%LidSpeed, p%lidar%NumPulseGate, 'y%lidar%LidSpeed', ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + + !CALL AllocAry( y%LidErr, p%NumPulseGate, 'y%LidErr', ErrStat2, ErrMsg2 ) + !CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + + CALL AllocAry( y%lidar%WtTrunc, p%lidar%NumPulseGate, 'y%lidar%WtTrunc', ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); - CALL AllocAry( y%lidar%WtTrunc, p%lidar%NumPulseGate, 'y%lidar%WtTrunc', ErrStat2, ErrMsg2 ) + CALL AllocAry( y%lidar%MsrPositionsX, p%lidar%NumPulseGate, 'y%lidar%MsrPositionsX', ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + + CALL AllocAry( y%lidar%MsrPositionsY, p%lidar%NumPulseGate, 'y%lidar%MsrPositionsY', ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + + CALL AllocAry( y%lidar%MsrPositionsZ, p%lidar%NumPulseGate, 'y%lidar%MsrPositionsZ', ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ); + ENDIF IF (ErrStat >= AbortErrLev) RETURN - y%lidar%LidSpeed = 0.0 - y%lidar%WtTrunc = 0.0 + if (allocated(y%lidar%LidSpeed)) y%lidar%LidSpeed = 0.0 + if (allocated(y%lidar%WtTrunc )) y%lidar%WtTrunc = 0.0 !............................................................................................ ! Define initialization-routine output here: @@ -292,10 +338,15 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs TYPE(InflowWind_InputType) :: Input ! position where wind speed should be returned TYPE(InflowWind_OutputType) :: Output ! velocity at Input%Position + REAL(ReKi) :: LidPosition(3) ! Lidar Position + REAL(ReKi) :: LidPosition_N(3) !Transformed Lidar Position + REAL(ReKi) :: LidarMsrPosition(3) !Transformed Lidar Position + REAL(ReKi) :: MeasurementCurrentStep + REAL(ReKi) :: OutputVelocity(3) - + INTEGER(IntKi) :: IBeam INTEGER(IntKi) :: IRangeGt INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 @@ -307,11 +358,26 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs ErrStat = ErrID_None ErrMsg = "" + + MeasurementCurrentStep = INT(t / p%lidar%MeasurementInterval) + + IF ( (p%lidar%MeasurementInterval * MeasurementCurrentStep) /= t ) THEN + Output%VelocityUVW(:,1) = 0 + RETURN + ENDIF + + IF (p%lidar%ConsiderHubMotion == 1) THEN + LidPosition_N = (/ u%lidar%HubDisplacementX, u%lidar%HubDisplacementY, u%lidar%HubDisplacementZ /) & ! rotor apex position (absolute) + + p%lidar%RotorApexOffsetPos ! lidar offset-from-rotor-apex position + LidPosition = p%lidar%LidPosition + LidPosition_N + ELSE + LidPosition_N = p%lidar%RotorApexOffsetPos + LidPosition = p%lidar%LidPosition + LidPosition_N + END IF IF (p%lidar%SensorType == SensorType_None) RETURN - - ! allocate arrays to compute outputs + ! allocate arrays to compute outputs CALL AllocAry(Input%PositionXYZ, 3,1, 'Input%PositionXYZ',ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -329,20 +395,26 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs IF (p%lidar%SensorType == SensorType_SinglePoint) THEN - - !get lidar speed at the focal point to see if it is out of bounds - Input%PositionXYZ(:,1) = u%lidar%MsrPosition + DO IBeam = 1,p%lidar%NumBeam + !get lidar speed at the focal point to see if it is out of bounds + Input%PositionXYZ(:,1) = LidPosition + p%lidar%MsrPosition(:,IBeam) CALL CalculateOutput( t, Input, p, x, xd, z, OtherState, Output, m, .FALSE., ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - y%lidar%LidSpeed = Output%VelocityUVW(:,1) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + y%lidar%LidSpeed(IBeam) = SQRT( DOT_PRODUCT(Output%VelocityUVW(:,1), Output%VelocityUVW(:,1)) ) y%lidar%WtTrunc = 1.0_ReKi + + y%lidar%MsrPositionsX(IBeam) = Input%PositionXYZ(1,1) + y%lidar%MsrPositionsY(IBeam) = Input%PositionXYZ(2,1) + y%lidar%MsrPositionsZ(IBeam) = Input%PositionXYZ(3,1) + + END DO ELSEIF (p%lidar%SensorType == SensorType_ContinuousLidar) THEN !calculate the focal distance of the lidar as well as the modified focal distance so that the peak of the weighting func !is at the intended focal distance - Distance = u%lidar%MsrPosition - u%lidar%LidPosition + Distance = p%lidar%MsrPosition(:,1) - LidPosition FocDist = SQRT( DOT_PRODUCT( Distance, Distance ) ) !TwoNorm IF(EqualRealNos(FocDist,0.0_ReKi)) THEN ! Avoid division-by-zero @@ -369,7 +441,12 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs LidWtRatio = 1.0_ReKi !LidWt/LidWtMax !get lidar speed at the focal point to see if it is out of bounds - Input%PositionXYZ(:,1) = u%lidar%MsrPosition + Input%PositionXYZ(:,1) = LidPosition + p%lidar%MsrPosition(:,1) + + y%lidar%MsrPositionsX(1) = LidPosition(1) + p%lidar%MsrPosition(1,1) + y%lidar%MsrPositionsY(1) = LidPosition(2) + p%lidar%MsrPosition(2,1) + y%lidar%MsrPositionsZ(1) = LidPosition(3) + p%lidar%MsrPosition(3,1) + CALL CalculateOutput( t, Input, p, x, xd, z, OtherState, Output, m, .FALSE., ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -418,9 +495,9 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs !calculate points to scan for current beam point - Input%PositionXYZ(3,1) = u%lidar%LidPosition(3) + SIN(LidPhi)*(LidRange + FocDist) - Input%PositionXYZ(1,1) = u%lidar%LidPosition(1) - COS(LidTheta)*COS(LidPhi)*(LidRange + FocDist) - Input%PositionXYZ(2,1) = u%lidar%LidPosition(2) + SIN(LidTheta)*COS(LidPhi)*(LidRange + FocDist) + Input%PositionXYZ(3,1) = LidPosition(3) + SIN(LidPhi)*(LidRange + FocDist) + Input%PositionXYZ(1,1) = LidPosition(1) - COS(LidTheta)*COS(LidPhi)*(LidRange + FocDist) + Input%PositionXYZ(2,1) = LidPosition(2) + SIN(LidTheta)*COS(LidPhi)*(LidRange + FocDist) CALL CalculateOutput( t, Input, p, x, xd, z, OtherState, Output, m, .FALSE., ErrStat2, ErrMsg2 ) IF (ErrStat2 >= AbortErrLev ) THEN !out of bounds @@ -435,9 +512,9 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs !calculate points to scan for current beam point - Input%PositionXYZ(3,1) = u%lidar%LidPosition(3) + SIN(LidPhi)*(FocDist - LidRange) - Input%PositionXYZ(1,1) = u%lidar%LidPosition(1) - COS(LidTheta)*COS(LidPhi)*(FocDist - LidRange) - Input%PositionXYZ(2,1) = u%lidar%LidPosition(2) + SIN(LidTheta)*COS(LidPhi)*(FocDist - LidRange) + Input%PositionXYZ(3,1) = LidPosition(3) + SIN(LidPhi)*(FocDist - LidRange) + Input%PositionXYZ(1,1) = LidPosition(1) - COS(LidTheta)*COS(LidPhi)*(FocDist - LidRange) + Input%PositionXYZ(2,1) = LidPosition(2) + SIN(LidTheta)*COS(LidPhi)*(FocDist - LidRange) CALL CalculateOutput( t, Input, p, x, xd, z, OtherState, Output, m, .FALSE., ErrStat2, ErrMsg2 ) IF (ErrStat2 >= AbortErrLev) THEN !out of bounds @@ -477,19 +554,27 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs DO IRangeGt = 1,p%lidar%NumPulseGate !y%lidar%LidErr(IRangeGt) = 0 + + LidPosition(2) = LidPosition(2) + p%lidar%MsrPosition(2,1) + LidPosition(3) = LidPosition(3) + p%lidar%MsrPosition(3,1) !get lidar speed at the focal point to see if it is out of bounds - Input%PositionXYZ(:,1) = u%lidar%LidPosition + LidDirUnVec*(p%lidar%PulseRangeOne + (IRangeGt-1)*p%lidar%DeltaP) + Input%PositionXYZ(:,1) = LidPosition + LidDirUnVec*(-p%lidar%MsrPosition(1,1) - (IRangeGt-1)*p%lidar%PulseSpacing) + + y%lidar%MsrPositionsX(IRangeGt) = LidPosition(1) + LidDirUnVec(1)*(-p%lidar%MsrPosition(1,1) - (IRangeGt-1)*p%lidar%PulseSpacing) + y%lidar%MsrPositionsY(IRangeGt) = LidPosition(2) + p%lidar%MsrPosition(2,1) + y%lidar%MsrPositionsZ(IRangeGt) = LidPosition(3) + p%lidar%MsrPosition(3,1) + CALL CalculateOutput( t, Input, p, x, xd, z, OtherState, Output, m, .FALSE., ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - LidWt = NWTC_ERF((p%lidar%DeltaP/2)/p%lidar%r_p)/p%lidar%DeltaP + LidWt = NWTC_ERF((p%lidar%PulseSpacing/2)/p%lidar%r_p)/p%lidar%PulseSpacing LidWtMax = LidWt LidWtRatio = 1.0_ReKi !LidWt/LidWtMax !if out of bounds - IF (AbortErrLev >= AbortErrLev) THEN + IF (ErrStat2 >= AbortErrLev) THEN !y%LidErr(IRangeGt) = 1 y%lidar%LidSpeed(IRangeGt) = -99 CALL Cleanup() @@ -513,12 +598,12 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs !calculate range of current beam point LidRange = LidRange + p%lidar%SpatialRes - LidWt = (NWTC_ERF((LidRange + p%lidar%DeltaP/2.)/p%lidar%r_p) - NWTC_ERF((LidRange - p%lidar%DeltaP/2.)/p%lidar%r_p))/(2.*p%lidar%DeltaP) + LidWt = (NWTC_ERF((LidRange + p%lidar%PulseSpacing/2.)/p%lidar%r_p) - NWTC_ERF((LidRange - p%lidar%PulseSpacing/2.)/p%lidar%r_p))/(2.*p%lidar%PulseSpacing) LidWtRatio = LidWt/LidWtMax !trunc point is behind lidar - IF (LidRange > (p%lidar%PulseRangeOne + (IRangeGt-1)*p%lidar%DeltaP)) THEN + IF (LidRange > (p%lidar%PulseRangeOne + (IRangeGt-1)*p%lidar%PulseSpacing)) THEN IF (NWTC_VerboseLevel == NWTC_Verbose) & CALL SetErrStat( ErrID_Info, "Lidar truncation point at gate "//trim(num2lstr(IRangeGt))//" is behind the lidar. Truncation ratio is "& //trim(num2lstr(LidWtRatio))//'.', ErrStat, ErrMsg, RoutineName) ! set informational message about point being behind lidar @@ -529,7 +614,7 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs !calculate points to scan for current beam point - Input%PositionXYZ(:,1) = u%lidar%LidPosition + LidDirUnVec*(p%lidar%PulseRangeOne + (IRangeGt-1)*p%lidar%DeltaP + LidRange) + Input%PositionXYZ(:,1) = LidPosition + LidDirUnVec*(-p%lidar%MsrPosition(1,1) - (IRangeGt-1)*p%lidar%PulseSpacing + LidRange) CALL CalculateOutput( t, Input, p, x, xd, z, OtherState, Output, m, .FALSE., ErrStat2, ErrMsg2 ) IF (ErrStat2 >= AbortErrLev) THEN !out of bounds IF (NWTC_VerboseLevel == NWTC_Verbose) & @@ -541,7 +626,7 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs OutputVelocity = Output%VelocityUVW(:,1) !calculate points to scan for current beam point - Input%PositionXYZ(:,1) = u%lidar%LidPosition + LidDirUnVec*(p%lidar%PulseRangeOne + (IRangeGt-1)*p%lidar%DeltaP - LidRange) + Input%PositionXYZ(:,1) = LidPosition + LidDirUnVec*(-p%lidar%MsrPosition(1,1) - (IRangeGt-1)*p%lidar%PulseSpacing - LidRange) CALL CalculateOutput( t, Input, p, x, xd, z, OtherState, Output, m, .FALSE., ErrStat2, ErrMsg2 ) IF (ErrStat2 >= AbortErrLev) THEN !out of bounds IF (NWTC_VerboseLevel == NWTC_Verbose) & @@ -552,7 +637,7 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs ENDIF - y%lidar%LidSpeed(IRangeGt) = y%lidar%LidSpeed(IRangeGt) + LidWt*DOT_PRODUCT(-1*LidDirUnVec,Output%VelocityUVW(:,1) + OutputVelocity) + y%lidar%LidSpeed(IRangeGt) = y%lidar%LidSpeed(IRangeGt) + LidWt*DOT_PRODUCT(-1*LidDirUnVec,Output%VelocityUVW(:,1) + OutputVelocity) WtFuncSum = WtFuncSum + 2*LidWt END DO @@ -568,10 +653,8 @@ SUBROUTINE Lidar_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMs END DO - - END IF !type of lidar measurements - - + END IF + CALL Cleanup() RETURN diff --git a/modules/inflowwind/src/Lidar.txt b/modules/inflowwind/src/Lidar.txt index fd54f5575..8f2defd9d 100644 --- a/modules/inflowwind/src/Lidar.txt +++ b/modules/inflowwind/src/Lidar.txt @@ -9,60 +9,76 @@ #include Registry_NWTC_Library.txt # LIDAR Constants -param Lidar - IntKi SensorType_None - -1 - - -param Lidar - IntKi SensorType_SinglePoint - 0 - - -param ^ - IntKi SensorType_ContinuousLidar - 1 - - -param ^ - IntKi SensorType_PulsedLidar - 2 - - +param Lidar - IntKi SensorType_None - 0 - - +param Lidar - IntKi SensorType_SinglePoint - 1 - - +param ^ - IntKi SensorType_ContinuousLidar - 2 - - +param ^ - IntKi SensorType_PulsedLidar - 3 - - # ..... LIDAR_InitInputType data ....................................................................................................... -typedef ^ Lidar_InitInputType IntKi SensorType - SensorType_None - "SensorType_* parameter" - -typedef ^ Lidar_InitInputType DbKi Tmax - - - "the length of the simulation" "s" -typedef ^ Lidar_InitInputType ReKi RotorApexOffsetPos {3} - - "position of the lidar unit relative to the rotor apex of rotation" m -typedef ^ Lidar_InitInputType ReKi HubPosition {3} - - "initial position of the hub (lidar mounted on hub) [0,0,HubHeight]" "m" -typedef ^ Lidar_InitInputType IntKi NumPulseGate - - - "the number of range gates to return wind speeds at" - -typedef ^ Lidar_InitInputType LOGICAL LidRadialVel - - - "TRUE => return radial component, FALSE => return 'x' direction estimate" - +typedef ^ Lidar_InitInputType IntKi SensorType - SensorType_None - "SensorType_* parameter" - +typedef ^ Lidar_InitInputType DbKi Tmax - - - "the length of the simulation" "s" +typedef ^ Lidar_InitInputType ReKi RotorApexOffsetPos {3} - - "position of the lidar unit relative to the rotor apex of rotation" "m" +typedef ^ Lidar_InitInputType ReKi HubPosition {3} - - "initial position of the hub (lidar mounted on hub) [0,0,HubHeight]" "m" +typedef ^ Lidar_InitInputType IntKi NumPulseGate - - - "the number of range gates to return wind speeds at" - +typedef ^ Lidar_InitInputType LOGICAL LidRadialVel - - - "TRUE => return radial component, FALSE => return 'x' direction estimate" - # ..... LIDAR_InitInputType data ....................................................................................................... -typedef ^ Lidar_InitOutputType ReKi DummyInitOut - +typedef ^ Lidar_InitOutputType ReKi DummyInitOut - # ..... LIDAR_ParameterType data ....................................................................................................... -typedef ^ Lidar_ParameterType IntKi NumPulseGate - - - "the number of range gates to return wind speeds at; pulsed lidar only" - -typedef ^ Lidar_ParameterType ReKi RotorApexOffsetPos {3} - - "position of the lidar unit relative to the rotor apex of rotation" m -typedef ^ Lidar_ParameterType ReKi RayRangeSq - - - "Rayleigh Range Squared" -typedef ^ Lidar_ParameterType ReKi SpatialRes - - - "spatial sampling distance of weighting function (1/2)*(avg ws)*dt" -typedef ^ Lidar_ParameterType IntKi SensorType - - - "SensorType_* parameter" - -typedef ^ Lidar_ParameterType ReKi WtFnTrunc - - - "Percentage of the peak value at which to truncate weighting function" -typedef ^ Lidar_ParameterType ReKi PulseRangeOne - - - "the range to the closest range gate" -typedef ^ Lidar_ParameterType ReKi DeltaP - - - "the distance between range gates" -typedef ^ Lidar_ParameterType ReKi DeltaR - - - "the FWHM width of the pulse" -typedef ^ Lidar_ParameterType ReKi r_p - - - -typedef ^ Lidar_ParameterType LOGICAL LidRadialVel - - - "TRUE => return radial component, FALSE => return 'x' direction estimate" - +typedef ^ Lidar_ParameterType IntKi NumPulseGate - - - "the number of range gates to return wind speeds at; pulsed lidar only" - +typedef ^ Lidar_ParameterType ReKi RotorApexOffsetPos {3} - - "position of the lidar unit relative to the rotor apex of rotation" "m" +typedef ^ Lidar_ParameterType ReKi RayRangeSq - - - "Rayleigh Range Squared" +typedef ^ Lidar_ParameterType ReKi SpatialRes - - - "spatial sampling distance of weighting function (1/2)*(avg ws)*dt" +typedef ^ Lidar_ParameterType IntKi SensorType - - - "SensorType_* parameter" - +typedef ^ Lidar_ParameterType ReKi WtFnTrunc - - - "Percentage of the peak value at which to truncate weighting function" +typedef ^ Lidar_ParameterType ReKi PulseRangeOne - - - "the range to the closest range gate" "m" +typedef ^ Lidar_ParameterType ReKi DeltaP - - - "the distance between range gates" "m" +typedef ^ Lidar_ParameterType ReKi DeltaR - - - "the FWHM width of the pulse" +typedef ^ Lidar_ParameterType ReKi r_p - - - +typedef ^ Lidar_ParameterType LOGICAL LidRadialVel - - - "TRUE => return radial component, FALSE => return 'x' direction estimate" - +typedef ^ Lidar_ParameterType ReKi DisplacementLidarX - - - "Displacement of the lidar system from the focal measurement point" "m" +typedef ^ Lidar_ParameterType ReKi DisplacementLidarY - - - "Displacement of the lidar system from the focal measurement point" "m" +typedef ^ Lidar_ParameterType ReKi DisplacementLidarZ - - - "Displacement of the lidar system from the focal measurement point" "m" +typedef ^ Lidar_ParameterType IntKi NumBeam - - - "Number of lidar beams" - +typedef ^ Lidar_ParameterType ReKi FocalDistanceX : - - "LIDAR LOS focal distance co-ordinates in the x direction" "m" +typedef ^ Lidar_ParameterType ReKi FocalDistanceY : - - "LIDAR LOS focal distance co-ordinates in the y direction" "m" +typedef ^ Lidar_ParameterType ReKi FocalDistanceZ : - - "LIDAR LOS focal distance co-ordinates in the z direction" "m" +typedef ^ Lidar_ParameterType ReKi MsrPosition {:}{:} - - "Position of the desired wind measurement (was XMsrPt, YMsrPt, ZMsrPt)" "m" +typedef ^ Lidar_ParameterType ReKi PulseSpacing - - - "Distance between range gates" "m" +typedef ^ Lidar_ParameterType ReKi URefLid - - - "Reference average wind speed for the lidar" "m/s" +typedef ^ Lidar_ParameterType IntKi ConsiderHubMotion - - - "Flag whether to consider the hub motion's impact on the Lidar measurement" - +typedef ^ Lidar_ParameterType ReKi MeasurementInterval - - - "Time steps between lidar measurements" "s" +typedef ^ Lidar_ParameterType ReKi LidPosition {3} - - "Position of the Lidar unit (was XLidPt, YLidPt, ZLidPt)" "m" + # ..... States .................................................................................................................... # Define continuous (differentiable) states here: -typedef ^ ContinuousStateType ReKi DummyContState - - - "Remove this variable if you have continuous states" - +typedef ^ ContinuousStateType ReKi DummyContState - - - "Remove this variable if you have continuous states" - # Define discrete (nondifferentiable) states here: -typedef ^ DiscreteStateType ReKi DummyDiscState - - - "Remove this variable if you have discrete states" - -# Define constraint states here: -typedef ^ ConstraintStateType ReKi DummyConstrState - - - "Remove this variable if you have constraint states" - +typedef ^ DiscreteStateType ReKi DummyDiscState - - - "Remove this variable if you have discrete states" - +# Define constraint states here: +typedef ^ ConstraintStateType ReKi DummyConstrState - - - "Remove this variable if you have constraint states" - # Define "other" states (any data that are not considered actual states) here: -typedef ^ OtherStateType ReKi DummyOtherState - - - +typedef ^ OtherStateType ReKi DummyOtherState - - - # ..... Misc/Optimization variables................................................................................................. # Define any data that are used only for efficiency purposes (these variables are not associated with time): # e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. -typedef ^ MiscVarType ReKi DummyMiscVar - - - "Remove this variable if you have misc variables" - +typedef ^ MiscVarType ReKi DummyMiscVar - - - "Remove this variable if you have misc variables" - # ..... LIDAR_InputType data ....................................................................................................... -typedef ^ Lidar_InputType ReKi LidPosition {3} - - "Position of the Lidar unit (was XLidPt, YLidPt, ZLidPt)" m -typedef ^ Lidar_InputType ReKi MsrPosition {3} - - "Position of the desired wind measurement (was XMsrPt, YMsrPt, ZMsrPt)" m -typedef ^ Lidar_InputType ReKi PulseLidEl - - - "the angle off of the x axis that the lidar is aimed (0 would be staring directly upwind, pi/2 would be staring perpendicular to the x axis)" -typedef ^ Lidar_InputType ReKi PulseLidAz - - - "the angle in the YZ plane that the lidar is staring (if PulseLidEl is set to pi/2, then 0 would be aligned with the positive z axis, pi/2 would be aligned with the positive y axis)" - +typedef ^ Lidar_InputType ReKi PulseLidEl - - - "the angle off of the x axis that the lidar is aimed (0 would be staring directly upwind, pi/2 would be staring perpendicular to the x axis)" +typedef ^ Lidar_InputType ReKi PulseLidAz - - - "the angle in the YZ plane that the lidar is staring (if PulseLidEl is set to pi/2, then 0 would be aligned with the positive z axis, pi/2 would be aligned with the positive y axis)" +typedef ^ Lidar_InputType ReKi HubDisplacementX - - - "X direction hub displacement of the lidar (from ElastoDyn)" "m" +typedef ^ Lidar_InputType ReKi HubDisplacementY - - - "Y direction hub displacement of the lidar (from ElastoDyn)" "m" +typedef ^ Lidar_InputType ReKi HubDisplacementZ - - - "Z direction hub displacement of the lidar (from ElastoDyn)" "m" # ..... LIDAR_OutputType data ....................................................................................................... -typedef ^ Lidar_OutputType ReKi LidSpeed {:} - - "Speed detected by Lidar at measurement point (range gates for pulsed lidar)" "m/s" -typedef ^ Lidar_OutputType ReKi WtTrunc {:} - - "Contains the fraction of the peak that the weighting function was truncated at (for when truncated early)." -#typedef ^ Lidar_OutputType IntKi LidErr {:} - - "Error code; THIS NEEDS TO GET FIXED (no integer outputs)" - +typedef ^ Lidar_OutputType ReKi LidSpeed {:} - - "Speed detected by Lidar at measurement point (range gates for pulsed lidar)" "m/s" +typedef ^ Lidar_OutputType ReKi WtTrunc {:} - - "Contains the fraction of the peak that the weighting function was truncated at (for when truncated early)." +typedef ^ Lidar_OutputType ReKi MsrPositionsX {:} - - "Lidar X direction measurement points" "m" +typedef ^ Lidar_OutputType ReKi MsrPositionsY {:} - - "Lidar Y direction measurement points" "m" +typedef ^ Lidar_OutputType ReKi MsrPositionsZ {:} - - "Lidar Z direction measurement points" "m" +#typedef ^ Lidar_OutputType IntKi LidErr {:} - - "Error code; THIS NEEDS TO GET FIXED (no integer outputs)" diff --git a/modules/inflowwind/src/Lidar_Types.f90 b/modules/inflowwind/src/Lidar_Types.f90 index 4ec86f6a3..f95da8671 100644 --- a/modules/inflowwind/src/Lidar_Types.f90 +++ b/modules/inflowwind/src/Lidar_Types.f90 @@ -33,10 +33,10 @@ MODULE Lidar_Types !--------------------------------------------------------------------------------------------------------------------------------- USE NWTC_Library IMPLICIT NONE - INTEGER(IntKi), PUBLIC, PARAMETER :: SensorType_None = -1 - INTEGER(IntKi), PUBLIC, PARAMETER :: SensorType_SinglePoint = 0 - INTEGER(IntKi), PUBLIC, PARAMETER :: SensorType_ContinuousLidar = 1 - INTEGER(IntKi), PUBLIC, PARAMETER :: SensorType_PulsedLidar = 2 + INTEGER(IntKi), PUBLIC, PARAMETER :: SensorType_None = 0 + INTEGER(IntKi), PUBLIC, PARAMETER :: SensorType_SinglePoint = 1 + INTEGER(IntKi), PUBLIC, PARAMETER :: SensorType_ContinuousLidar = 2 + INTEGER(IntKi), PUBLIC, PARAMETER :: SensorType_PulsedLidar = 3 ! ========= Lidar_InitInputType ======= TYPE, PUBLIC :: Lidar_InitInputType INTEGER(IntKi) :: SensorType = SensorType_None !< SensorType_* parameter [-] @@ -60,11 +60,24 @@ MODULE Lidar_Types REAL(ReKi) :: SpatialRes !< spatial sampling distance of weighting function (1/2)*(avg ws)*dt [-] INTEGER(IntKi) :: SensorType !< SensorType_* parameter [-] REAL(ReKi) :: WtFnTrunc !< Percentage of the peak value at which to truncate weighting function [-] - REAL(ReKi) :: PulseRangeOne !< the range to the closest range gate [-] - REAL(ReKi) :: DeltaP !< the distance between range gates [-] + REAL(ReKi) :: PulseRangeOne !< the range to the closest range gate [m] + REAL(ReKi) :: DeltaP !< the distance between range gates [m] REAL(ReKi) :: DeltaR !< the FWHM width of the pulse [-] REAL(ReKi) :: r_p LOGICAL :: LidRadialVel !< TRUE => return radial component, FALSE => return 'x' direction estimate [-] + REAL(ReKi) :: DisplacementLidarX !< Displacement of the lidar system from the focal measurement point [m] + REAL(ReKi) :: DisplacementLidarY !< Displacement of the lidar system from the focal measurement point [m] + REAL(ReKi) :: DisplacementLidarZ !< Displacement of the lidar system from the focal measurement point [m] + INTEGER(IntKi) :: NumBeam !< Number of lidar beams [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FocalDistanceX !< LIDAR LOS focal distance co-ordinates in the x direction [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FocalDistanceY !< LIDAR LOS focal distance co-ordinates in the y direction [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: FocalDistanceZ !< LIDAR LOS focal distance co-ordinates in the z direction [m] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: MsrPosition !< Position of the desired wind measurement (was XMsrPt, YMsrPt, ZMsrPt) [m] + REAL(ReKi) :: PulseSpacing !< Distance between range gates [m] + REAL(ReKi) :: URefLid !< Reference average wind speed for the lidar [m/s] + INTEGER(IntKi) :: ConsiderHubMotion !< Flag whether to consider the hub motion's impact on the Lidar measurement [-] + REAL(ReKi) :: MeasurementInterval !< Time steps between lidar measurements [s] + REAL(ReKi) , DIMENSION(1:3) :: LidPosition !< Position of the Lidar unit (was XLidPt, YLidPt, ZLidPt) [m] END TYPE Lidar_ParameterType ! ======================= ! ========= Lidar_ContinuousStateType ======= @@ -94,16 +107,20 @@ MODULE Lidar_Types ! ======================= ! ========= Lidar_InputType ======= TYPE, PUBLIC :: Lidar_InputType - REAL(ReKi) , DIMENSION(1:3) :: LidPosition !< Position of the Lidar unit (was XLidPt, YLidPt, ZLidPt) [m] - REAL(ReKi) , DIMENSION(1:3) :: MsrPosition !< Position of the desired wind measurement (was XMsrPt, YMsrPt, ZMsrPt) [m] REAL(ReKi) :: PulseLidEl !< the angle off of the x axis that the lidar is aimed (0 would be staring directly upwind, pi/2 would be staring perpendicular to the x axis) [-] REAL(ReKi) :: PulseLidAz !< the angle in the YZ plane that the lidar is staring (if PulseLidEl is set to pi/2, then 0 would be aligned with the positive z axis, pi/2 would be aligned with the positive y axis) [-] + REAL(ReKi) :: HubDisplacementX !< X direction hub displacement of the lidar (from ElastoDyn) [m] + REAL(ReKi) :: HubDisplacementY !< Y direction hub displacement of the lidar (from ElastoDyn) [m] + REAL(ReKi) :: HubDisplacementZ !< Z direction hub displacement of the lidar (from ElastoDyn) [m] END TYPE Lidar_InputType ! ======================= ! ========= Lidar_OutputType ======= TYPE, PUBLIC :: Lidar_OutputType REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: LidSpeed !< Speed detected by Lidar at measurement point (range gates for pulsed lidar) [m/s] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WtTrunc !< Contains the fraction of the peak that the weighting function was truncated at (for when truncated early). [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsX !< Lidar X direction measurement points [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsY !< Lidar Y direction measurement points [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsZ !< Lidar Z direction measurement points [m] END TYPE Lidar_OutputType ! ======================= CONTAINS @@ -116,6 +133,7 @@ SUBROUTINE Lidar_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Er ! Local INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_CopyInitInput' @@ -130,15 +148,27 @@ SUBROUTINE Lidar_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Er DstInitInputData%LidRadialVel = SrcInitInputData%LidRadialVel END SUBROUTINE Lidar_CopyInitInput - SUBROUTINE Lidar_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE Lidar_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Lidar_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Lidar_DestroyInitInput SUBROUTINE Lidar_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -241,6 +271,7 @@ SUBROUTINE Lidar_UnPackInitInput( 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 = 'Lidar_UnPackInitInput' @@ -293,15 +324,27 @@ SUBROUTINE Lidar_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, DstInitOutputData%DummyInitOut = SrcInitOutputData%DummyInitOut END SUBROUTINE Lidar_CopyInitOutput - SUBROUTINE Lidar_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE Lidar_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Lidar_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Lidar_DestroyInitOutput SUBROUTINE Lidar_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -410,6 +453,7 @@ SUBROUTINE Lidar_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMs ! 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 = 'Lidar_CopyParam' @@ -427,17 +471,100 @@ SUBROUTINE Lidar_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMs DstParamData%DeltaR = SrcParamData%DeltaR DstParamData%r_p = SrcParamData%r_p DstParamData%LidRadialVel = SrcParamData%LidRadialVel + DstParamData%DisplacementLidarX = SrcParamData%DisplacementLidarX + DstParamData%DisplacementLidarY = SrcParamData%DisplacementLidarY + DstParamData%DisplacementLidarZ = SrcParamData%DisplacementLidarZ + DstParamData%NumBeam = SrcParamData%NumBeam +IF (ALLOCATED(SrcParamData%FocalDistanceX)) THEN + i1_l = LBOUND(SrcParamData%FocalDistanceX,1) + i1_u = UBOUND(SrcParamData%FocalDistanceX,1) + IF (.NOT. ALLOCATED(DstParamData%FocalDistanceX)) THEN + ALLOCATE(DstParamData%FocalDistanceX(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%FocalDistanceX.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%FocalDistanceX = SrcParamData%FocalDistanceX +ENDIF +IF (ALLOCATED(SrcParamData%FocalDistanceY)) THEN + i1_l = LBOUND(SrcParamData%FocalDistanceY,1) + i1_u = UBOUND(SrcParamData%FocalDistanceY,1) + IF (.NOT. ALLOCATED(DstParamData%FocalDistanceY)) THEN + ALLOCATE(DstParamData%FocalDistanceY(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%FocalDistanceY.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%FocalDistanceY = SrcParamData%FocalDistanceY +ENDIF +IF (ALLOCATED(SrcParamData%FocalDistanceZ)) THEN + i1_l = LBOUND(SrcParamData%FocalDistanceZ,1) + i1_u = UBOUND(SrcParamData%FocalDistanceZ,1) + IF (.NOT. ALLOCATED(DstParamData%FocalDistanceZ)) THEN + ALLOCATE(DstParamData%FocalDistanceZ(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%FocalDistanceZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%FocalDistanceZ = SrcParamData%FocalDistanceZ +ENDIF +IF (ALLOCATED(SrcParamData%MsrPosition)) THEN + i1_l = LBOUND(SrcParamData%MsrPosition,1) + i1_u = UBOUND(SrcParamData%MsrPosition,1) + i2_l = LBOUND(SrcParamData%MsrPosition,2) + i2_u = UBOUND(SrcParamData%MsrPosition,2) + IF (.NOT. ALLOCATED(DstParamData%MsrPosition)) THEN + ALLOCATE(DstParamData%MsrPosition(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%MsrPosition.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%MsrPosition = SrcParamData%MsrPosition +ENDIF + DstParamData%PulseSpacing = SrcParamData%PulseSpacing + DstParamData%URefLid = SrcParamData%URefLid + DstParamData%ConsiderHubMotion = SrcParamData%ConsiderHubMotion + DstParamData%MeasurementInterval = SrcParamData%MeasurementInterval + DstParamData%LidPosition = SrcParamData%LidPosition END SUBROUTINE Lidar_CopyParam - SUBROUTINE Lidar_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE Lidar_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Lidar_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(ParamData%FocalDistanceX)) THEN + DEALLOCATE(ParamData%FocalDistanceX) +ENDIF +IF (ALLOCATED(ParamData%FocalDistanceY)) THEN + DEALLOCATE(ParamData%FocalDistanceY) +ENDIF +IF (ALLOCATED(ParamData%FocalDistanceZ)) THEN + DEALLOCATE(ParamData%FocalDistanceZ) +ENDIF +IF (ALLOCATED(ParamData%MsrPosition)) THEN + DEALLOCATE(ParamData%MsrPosition) +ENDIF END SUBROUTINE Lidar_DestroyParam SUBROUTINE Lidar_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -486,6 +613,35 @@ SUBROUTINE Lidar_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Re_BufSz = Re_BufSz + 1 ! DeltaR Re_BufSz = Re_BufSz + 1 ! r_p Int_BufSz = Int_BufSz + 1 ! LidRadialVel + Re_BufSz = Re_BufSz + 1 ! DisplacementLidarX + Re_BufSz = Re_BufSz + 1 ! DisplacementLidarY + Re_BufSz = Re_BufSz + 1 ! DisplacementLidarZ + Int_BufSz = Int_BufSz + 1 ! NumBeam + Int_BufSz = Int_BufSz + 1 ! FocalDistanceX allocated yes/no + IF ( ALLOCATED(InData%FocalDistanceX) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FocalDistanceX upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%FocalDistanceX) ! FocalDistanceX + END IF + Int_BufSz = Int_BufSz + 1 ! FocalDistanceY allocated yes/no + IF ( ALLOCATED(InData%FocalDistanceY) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FocalDistanceY upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%FocalDistanceY) ! FocalDistanceY + END IF + Int_BufSz = Int_BufSz + 1 ! FocalDistanceZ allocated yes/no + IF ( ALLOCATED(InData%FocalDistanceZ) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FocalDistanceZ upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%FocalDistanceZ) ! FocalDistanceZ + END IF + Int_BufSz = Int_BufSz + 1 ! MsrPosition allocated yes/no + IF ( ALLOCATED(InData%MsrPosition) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! MsrPosition upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MsrPosition) ! MsrPosition + END IF + Re_BufSz = Re_BufSz + 1 ! PulseSpacing + Re_BufSz = Re_BufSz + 1 ! URefLid + Int_BufSz = Int_BufSz + 1 ! ConsiderHubMotion + Re_BufSz = Re_BufSz + 1 ! MeasurementInterval + Re_BufSz = Re_BufSz + SIZE(InData%LidPosition) ! LidPosition IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -537,6 +693,91 @@ SUBROUTINE Lidar_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Re_Xferred = Re_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%LidRadialVel, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%DisplacementLidarX + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%DisplacementLidarY + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%DisplacementLidarZ + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumBeam + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%FocalDistanceX) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FocalDistanceX,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FocalDistanceX,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%FocalDistanceX,1), UBOUND(InData%FocalDistanceX,1) + ReKiBuf(Re_Xferred) = InData%FocalDistanceX(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%FocalDistanceY) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FocalDistanceY,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FocalDistanceY,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%FocalDistanceY,1), UBOUND(InData%FocalDistanceY,1) + ReKiBuf(Re_Xferred) = InData%FocalDistanceY(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%FocalDistanceZ) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FocalDistanceZ,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FocalDistanceZ,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%FocalDistanceZ,1), UBOUND(InData%FocalDistanceZ,1) + ReKiBuf(Re_Xferred) = InData%FocalDistanceZ(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MsrPosition) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPosition,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPosition,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPosition,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPosition,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%MsrPosition,2), UBOUND(InData%MsrPosition,2) + DO i1 = LBOUND(InData%MsrPosition,1), UBOUND(InData%MsrPosition,1) + ReKiBuf(Re_Xferred) = InData%MsrPosition(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + ReKiBuf(Re_Xferred) = InData%PulseSpacing + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%URefLid + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%ConsiderHubMotion + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%MeasurementInterval + Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%LidPosition,1), UBOUND(InData%LidPosition,1) + ReKiBuf(Re_Xferred) = InData%LidPosition(i1) + Re_Xferred = Re_Xferred + 1 + END DO END SUBROUTINE Lidar_PackParam SUBROUTINE Lidar_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -553,6 +794,7 @@ SUBROUTINE Lidar_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM 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 = 'Lidar_UnPackParam' @@ -592,6 +834,105 @@ SUBROUTINE Lidar_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM Re_Xferred = Re_Xferred + 1 OutData%LidRadialVel = TRANSFER(IntKiBuf(Int_Xferred), OutData%LidRadialVel) Int_Xferred = Int_Xferred + 1 + OutData%DisplacementLidarX = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%DisplacementLidarY = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%DisplacementLidarZ = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%NumBeam = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FocalDistanceX not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FocalDistanceX)) DEALLOCATE(OutData%FocalDistanceX) + ALLOCATE(OutData%FocalDistanceX(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FocalDistanceX.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%FocalDistanceX,1), UBOUND(OutData%FocalDistanceX,1) + OutData%FocalDistanceX(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FocalDistanceY not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FocalDistanceY)) DEALLOCATE(OutData%FocalDistanceY) + ALLOCATE(OutData%FocalDistanceY(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FocalDistanceY.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%FocalDistanceY,1), UBOUND(OutData%FocalDistanceY,1) + OutData%FocalDistanceY(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FocalDistanceZ not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FocalDistanceZ)) DEALLOCATE(OutData%FocalDistanceZ) + ALLOCATE(OutData%FocalDistanceZ(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FocalDistanceZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%FocalDistanceZ,1), UBOUND(OutData%FocalDistanceZ,1) + OutData%FocalDistanceZ(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MsrPosition not allocated + Int_Xferred = Int_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%MsrPosition)) DEALLOCATE(OutData%MsrPosition) + ALLOCATE(OutData%MsrPosition(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MsrPosition.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%MsrPosition,2), UBOUND(OutData%MsrPosition,2) + DO i1 = LBOUND(OutData%MsrPosition,1), UBOUND(OutData%MsrPosition,1) + OutData%MsrPosition(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + OutData%PulseSpacing = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%URefLid = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%ConsiderHubMotion = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%MeasurementInterval = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + i1_l = LBOUND(OutData%LidPosition,1) + i1_u = UBOUND(OutData%LidPosition,1) + DO i1 = LBOUND(OutData%LidPosition,1), UBOUND(OutData%LidPosition,1) + OutData%LidPosition(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END SUBROUTINE Lidar_UnPackParam SUBROUTINE Lidar_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) @@ -611,15 +952,27 @@ SUBROUTINE Lidar_CopyContState( SrcContStateData, DstContStateData, CtrlCode, Er DstContStateData%DummyContState = SrcContStateData%DummyContState END SUBROUTINE Lidar_CopyContState - SUBROUTINE Lidar_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE Lidar_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Lidar_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Lidar_DestroyContState SUBROUTINE Lidar_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -736,15 +1089,27 @@ SUBROUTINE Lidar_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, Er DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE Lidar_CopyDiscState - SUBROUTINE Lidar_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE Lidar_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Lidar_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Lidar_DestroyDiscState SUBROUTINE Lidar_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -861,15 +1226,27 @@ SUBROUTINE Lidar_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCo DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE Lidar_CopyConstrState - SUBROUTINE Lidar_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE Lidar_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Lidar_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Lidar_DestroyConstrState SUBROUTINE Lidar_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -986,15 +1363,27 @@ SUBROUTINE Lidar_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState END SUBROUTINE Lidar_CopyOtherState - SUBROUTINE Lidar_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE Lidar_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Lidar_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Lidar_DestroyOtherState SUBROUTINE Lidar_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1111,15 +1500,27 @@ SUBROUTINE Lidar_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%DummyMiscVar = SrcMiscData%DummyMiscVar END SUBROUTINE Lidar_CopyMisc - SUBROUTINE Lidar_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE Lidar_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Lidar_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Lidar_DestroyMisc SUBROUTINE Lidar_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1227,28 +1628,40 @@ SUBROUTINE Lidar_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMs 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 = 'Lidar_CopyInput' ! ErrStat = ErrID_None ErrMsg = "" - DstInputData%LidPosition = SrcInputData%LidPosition - DstInputData%MsrPosition = SrcInputData%MsrPosition DstInputData%PulseLidEl = SrcInputData%PulseLidEl DstInputData%PulseLidAz = SrcInputData%PulseLidAz + DstInputData%HubDisplacementX = SrcInputData%HubDisplacementX + DstInputData%HubDisplacementY = SrcInputData%HubDisplacementY + DstInputData%HubDisplacementZ = SrcInputData%HubDisplacementZ END SUBROUTINE Lidar_CopyInput - SUBROUTINE Lidar_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE Lidar_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Lidar_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Lidar_DestroyInput SUBROUTINE Lidar_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1286,10 +1699,11 @@ SUBROUTINE Lidar_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Re_BufSz = Re_BufSz + SIZE(InData%LidPosition) ! LidPosition - Re_BufSz = Re_BufSz + SIZE(InData%MsrPosition) ! MsrPosition Re_BufSz = Re_BufSz + 1 ! PulseLidEl Re_BufSz = Re_BufSz + 1 ! PulseLidAz + Re_BufSz = Re_BufSz + 1 ! HubDisplacementX + Re_BufSz = Re_BufSz + 1 ! HubDisplacementY + Re_BufSz = Re_BufSz + 1 ! HubDisplacementZ IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1317,18 +1731,16 @@ SUBROUTINE Lidar_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Db_Xferred = 1 Int_Xferred = 1 - DO i1 = LBOUND(InData%LidPosition,1), UBOUND(InData%LidPosition,1) - ReKiBuf(Re_Xferred) = InData%LidPosition(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO i1 = LBOUND(InData%MsrPosition,1), UBOUND(InData%MsrPosition,1) - ReKiBuf(Re_Xferred) = InData%MsrPosition(i1) - Re_Xferred = Re_Xferred + 1 - END DO ReKiBuf(Re_Xferred) = InData%PulseLidEl Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%PulseLidAz Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%HubDisplacementX + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%HubDisplacementY + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%HubDisplacementZ + Re_Xferred = Re_Xferred + 1 END SUBROUTINE Lidar_PackInput SUBROUTINE Lidar_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1344,7 +1756,6 @@ SUBROUTINE Lidar_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM 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 = 'Lidar_UnPackInput' @@ -1358,22 +1769,16 @@ SUBROUTINE Lidar_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - i1_l = LBOUND(OutData%LidPosition,1) - i1_u = UBOUND(OutData%LidPosition,1) - DO i1 = LBOUND(OutData%LidPosition,1), UBOUND(OutData%LidPosition,1) - OutData%LidPosition(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - i1_l = LBOUND(OutData%MsrPosition,1) - i1_u = UBOUND(OutData%MsrPosition,1) - DO i1 = LBOUND(OutData%MsrPosition,1), UBOUND(OutData%MsrPosition,1) - OutData%MsrPosition(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO OutData%PulseLidEl = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%PulseLidAz = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%HubDisplacementX = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%HubDisplacementY = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%HubDisplacementZ = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE Lidar_UnPackInput SUBROUTINE Lidar_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -1414,23 +1819,80 @@ SUBROUTINE Lidar_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Er END IF END IF DstOutputData%WtTrunc = SrcOutputData%WtTrunc +ENDIF +IF (ALLOCATED(SrcOutputData%MsrPositionsX)) THEN + i1_l = LBOUND(SrcOutputData%MsrPositionsX,1) + i1_u = UBOUND(SrcOutputData%MsrPositionsX,1) + IF (.NOT. ALLOCATED(DstOutputData%MsrPositionsX)) THEN + ALLOCATE(DstOutputData%MsrPositionsX(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%MsrPositionsX.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%MsrPositionsX = SrcOutputData%MsrPositionsX +ENDIF +IF (ALLOCATED(SrcOutputData%MsrPositionsY)) THEN + i1_l = LBOUND(SrcOutputData%MsrPositionsY,1) + i1_u = UBOUND(SrcOutputData%MsrPositionsY,1) + IF (.NOT. ALLOCATED(DstOutputData%MsrPositionsY)) THEN + ALLOCATE(DstOutputData%MsrPositionsY(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%MsrPositionsY.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%MsrPositionsY = SrcOutputData%MsrPositionsY +ENDIF +IF (ALLOCATED(SrcOutputData%MsrPositionsZ)) THEN + i1_l = LBOUND(SrcOutputData%MsrPositionsZ,1) + i1_u = UBOUND(SrcOutputData%MsrPositionsZ,1) + IF (.NOT. ALLOCATED(DstOutputData%MsrPositionsZ)) THEN + ALLOCATE(DstOutputData%MsrPositionsZ(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%MsrPositionsZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%MsrPositionsZ = SrcOutputData%MsrPositionsZ ENDIF END SUBROUTINE Lidar_CopyOutput - SUBROUTINE Lidar_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE Lidar_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Lidar_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%LidSpeed)) THEN DEALLOCATE(OutputData%LidSpeed) ENDIF IF (ALLOCATED(OutputData%WtTrunc)) THEN DEALLOCATE(OutputData%WtTrunc) +ENDIF +IF (ALLOCATED(OutputData%MsrPositionsX)) THEN + DEALLOCATE(OutputData%MsrPositionsX) +ENDIF +IF (ALLOCATED(OutputData%MsrPositionsY)) THEN + DEALLOCATE(OutputData%MsrPositionsY) +ENDIF +IF (ALLOCATED(OutputData%MsrPositionsZ)) THEN + DEALLOCATE(OutputData%MsrPositionsZ) ENDIF END SUBROUTINE Lidar_DestroyOutput @@ -1479,6 +1941,21 @@ SUBROUTINE Lidar_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 2*1 ! WtTrunc upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%WtTrunc) ! WtTrunc END IF + Int_BufSz = Int_BufSz + 1 ! MsrPositionsX allocated yes/no + IF ( ALLOCATED(InData%MsrPositionsX) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MsrPositionsX upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MsrPositionsX) ! MsrPositionsX + END IF + Int_BufSz = Int_BufSz + 1 ! MsrPositionsY allocated yes/no + IF ( ALLOCATED(InData%MsrPositionsY) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MsrPositionsY upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MsrPositionsY) ! MsrPositionsY + END IF + Int_BufSz = Int_BufSz + 1 ! MsrPositionsZ allocated yes/no + IF ( ALLOCATED(InData%MsrPositionsZ) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MsrPositionsZ upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MsrPositionsZ) ! MsrPositionsZ + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1536,6 +2013,51 @@ SUBROUTINE Lidar_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%MsrPositionsX) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPositionsX,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPositionsX,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MsrPositionsX,1), UBOUND(InData%MsrPositionsX,1) + ReKiBuf(Re_Xferred) = InData%MsrPositionsX(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MsrPositionsY) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPositionsY,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPositionsY,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MsrPositionsY,1), UBOUND(InData%MsrPositionsY,1) + ReKiBuf(Re_Xferred) = InData%MsrPositionsY(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MsrPositionsZ) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPositionsZ,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPositionsZ,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MsrPositionsZ,1), UBOUND(InData%MsrPositionsZ,1) + ReKiBuf(Re_Xferred) = InData%MsrPositionsZ(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE Lidar_PackOutput SUBROUTINE Lidar_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1601,6 +2123,60 @@ SUBROUTINE Lidar_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MsrPositionsX not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MsrPositionsX)) DEALLOCATE(OutData%MsrPositionsX) + ALLOCATE(OutData%MsrPositionsX(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MsrPositionsX.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MsrPositionsX,1), UBOUND(OutData%MsrPositionsX,1) + OutData%MsrPositionsX(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MsrPositionsY not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MsrPositionsY)) DEALLOCATE(OutData%MsrPositionsY) + ALLOCATE(OutData%MsrPositionsY(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MsrPositionsY.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MsrPositionsY,1), UBOUND(OutData%MsrPositionsY,1) + OutData%MsrPositionsY(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MsrPositionsZ not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MsrPositionsZ)) DEALLOCATE(OutData%MsrPositionsZ) + ALLOCATE(OutData%MsrPositionsZ(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MsrPositionsZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MsrPositionsZ,1), UBOUND(OutData%MsrPositionsZ,1) + OutData%MsrPositionsZ(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE Lidar_UnPackOutput @@ -1682,8 +2258,6 @@ SUBROUTINE Lidar_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMs 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 = "" @@ -1698,18 +2272,16 @@ SUBROUTINE Lidar_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMs END IF ScaleFactor = t_out / t(2) - DO i1 = LBOUND(u_out%LidPosition,1),UBOUND(u_out%LidPosition,1) - b = -(u1%LidPosition(i1) - u2%LidPosition(i1)) - u_out%LidPosition(i1) = u1%LidPosition(i1) + b * ScaleFactor - END DO - DO i1 = LBOUND(u_out%MsrPosition,1),UBOUND(u_out%MsrPosition,1) - b = -(u1%MsrPosition(i1) - u2%MsrPosition(i1)) - u_out%MsrPosition(i1) = u1%MsrPosition(i1) + b * ScaleFactor - END DO b = -(u1%PulseLidEl - u2%PulseLidEl) u_out%PulseLidEl = u1%PulseLidEl + b * ScaleFactor b = -(u1%PulseLidAz - u2%PulseLidAz) u_out%PulseLidAz = u1%PulseLidAz + b * ScaleFactor + b = -(u1%HubDisplacementX - u2%HubDisplacementX) + u_out%HubDisplacementX = u1%HubDisplacementX + b * ScaleFactor + b = -(u1%HubDisplacementY - u2%HubDisplacementY) + u_out%HubDisplacementY = u1%HubDisplacementY + b * ScaleFactor + b = -(u1%HubDisplacementZ - u2%HubDisplacementZ) + u_out%HubDisplacementZ = u1%HubDisplacementZ + b * ScaleFactor END SUBROUTINE Lidar_Input_ExtrapInterp1 @@ -1745,8 +2317,6 @@ SUBROUTINE Lidar_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, E INTEGER(IntKi) :: ErrStat2 ! local errors CHARACTER(ErrMsgLen) :: ErrMsg2 ! local errors CHARACTER(*), PARAMETER :: RoutineName = 'Lidar_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 = "" @@ -1767,22 +2337,21 @@ SUBROUTINE Lidar_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, E END IF ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) - DO i1 = LBOUND(u_out%LidPosition,1),UBOUND(u_out%LidPosition,1) - b = (t(3)**2*(u1%LidPosition(i1) - u2%LidPosition(i1)) + t(2)**2*(-u1%LidPosition(i1) + u3%LidPosition(i1)))* scaleFactor - c = ( (t(2)-t(3))*u1%LidPosition(i1) + t(3)*u2%LidPosition(i1) - t(2)*u3%LidPosition(i1) ) * scaleFactor - u_out%LidPosition(i1) = u1%LidPosition(i1) + b + c * t_out - END DO - DO i1 = LBOUND(u_out%MsrPosition,1),UBOUND(u_out%MsrPosition,1) - b = (t(3)**2*(u1%MsrPosition(i1) - u2%MsrPosition(i1)) + t(2)**2*(-u1%MsrPosition(i1) + u3%MsrPosition(i1)))* scaleFactor - c = ( (t(2)-t(3))*u1%MsrPosition(i1) + t(3)*u2%MsrPosition(i1) - t(2)*u3%MsrPosition(i1) ) * scaleFactor - u_out%MsrPosition(i1) = u1%MsrPosition(i1) + b + c * t_out - END DO b = (t(3)**2*(u1%PulseLidEl - u2%PulseLidEl) + t(2)**2*(-u1%PulseLidEl + u3%PulseLidEl))* scaleFactor c = ( (t(2)-t(3))*u1%PulseLidEl + t(3)*u2%PulseLidEl - t(2)*u3%PulseLidEl ) * scaleFactor u_out%PulseLidEl = u1%PulseLidEl + b + c * t_out b = (t(3)**2*(u1%PulseLidAz - u2%PulseLidAz) + t(2)**2*(-u1%PulseLidAz + u3%PulseLidAz))* scaleFactor c = ( (t(2)-t(3))*u1%PulseLidAz + t(3)*u2%PulseLidAz - t(2)*u3%PulseLidAz ) * scaleFactor u_out%PulseLidAz = u1%PulseLidAz + b + c * t_out + b = (t(3)**2*(u1%HubDisplacementX - u2%HubDisplacementX) + t(2)**2*(-u1%HubDisplacementX + u3%HubDisplacementX))* scaleFactor + c = ( (t(2)-t(3))*u1%HubDisplacementX + t(3)*u2%HubDisplacementX - t(2)*u3%HubDisplacementX ) * scaleFactor + u_out%HubDisplacementX = u1%HubDisplacementX + b + c * t_out + b = (t(3)**2*(u1%HubDisplacementY - u2%HubDisplacementY) + t(2)**2*(-u1%HubDisplacementY + u3%HubDisplacementY))* scaleFactor + c = ( (t(2)-t(3))*u1%HubDisplacementY + t(3)*u2%HubDisplacementY - t(2)*u3%HubDisplacementY ) * scaleFactor + u_out%HubDisplacementY = u1%HubDisplacementY + b + c * t_out + b = (t(3)**2*(u1%HubDisplacementZ - u2%HubDisplacementZ) + t(2)**2*(-u1%HubDisplacementZ + u3%HubDisplacementZ))* scaleFactor + c = ( (t(2)-t(3))*u1%HubDisplacementZ + t(3)*u2%HubDisplacementZ - t(2)*u3%HubDisplacementZ ) * scaleFactor + u_out%HubDisplacementZ = u1%HubDisplacementZ + b + c * t_out END SUBROUTINE Lidar_Input_ExtrapInterp2 @@ -1891,6 +2460,24 @@ SUBROUTINE Lidar_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, ErrM b = -(y1%WtTrunc(i1) - y2%WtTrunc(i1)) y_out%WtTrunc(i1) = y1%WtTrunc(i1) + b * ScaleFactor END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%MsrPositionsX) .AND. ALLOCATED(y1%MsrPositionsX)) THEN + DO i1 = LBOUND(y_out%MsrPositionsX,1),UBOUND(y_out%MsrPositionsX,1) + b = -(y1%MsrPositionsX(i1) - y2%MsrPositionsX(i1)) + y_out%MsrPositionsX(i1) = y1%MsrPositionsX(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%MsrPositionsY) .AND. ALLOCATED(y1%MsrPositionsY)) THEN + DO i1 = LBOUND(y_out%MsrPositionsY,1),UBOUND(y_out%MsrPositionsY,1) + b = -(y1%MsrPositionsY(i1) - y2%MsrPositionsY(i1)) + y_out%MsrPositionsY(i1) = y1%MsrPositionsY(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%MsrPositionsZ) .AND. ALLOCATED(y1%MsrPositionsZ)) THEN + DO i1 = LBOUND(y_out%MsrPositionsZ,1),UBOUND(y_out%MsrPositionsZ,1) + b = -(y1%MsrPositionsZ(i1) - y2%MsrPositionsZ(i1)) + y_out%MsrPositionsZ(i1) = y1%MsrPositionsZ(i1) + b * ScaleFactor + END DO END IF ! check if allocated END SUBROUTINE Lidar_Output_ExtrapInterp1 @@ -1962,6 +2549,27 @@ SUBROUTINE Lidar_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, c = ( (t(2)-t(3))*y1%WtTrunc(i1) + t(3)*y2%WtTrunc(i1) - t(2)*y3%WtTrunc(i1) ) * scaleFactor y_out%WtTrunc(i1) = y1%WtTrunc(i1) + b + c * t_out END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%MsrPositionsX) .AND. ALLOCATED(y1%MsrPositionsX)) THEN + DO i1 = LBOUND(y_out%MsrPositionsX,1),UBOUND(y_out%MsrPositionsX,1) + b = (t(3)**2*(y1%MsrPositionsX(i1) - y2%MsrPositionsX(i1)) + t(2)**2*(-y1%MsrPositionsX(i1) + y3%MsrPositionsX(i1)))* scaleFactor + c = ( (t(2)-t(3))*y1%MsrPositionsX(i1) + t(3)*y2%MsrPositionsX(i1) - t(2)*y3%MsrPositionsX(i1) ) * scaleFactor + y_out%MsrPositionsX(i1) = y1%MsrPositionsX(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%MsrPositionsY) .AND. ALLOCATED(y1%MsrPositionsY)) THEN + DO i1 = LBOUND(y_out%MsrPositionsY,1),UBOUND(y_out%MsrPositionsY,1) + b = (t(3)**2*(y1%MsrPositionsY(i1) - y2%MsrPositionsY(i1)) + t(2)**2*(-y1%MsrPositionsY(i1) + y3%MsrPositionsY(i1)))* scaleFactor + c = ( (t(2)-t(3))*y1%MsrPositionsY(i1) + t(3)*y2%MsrPositionsY(i1) - t(2)*y3%MsrPositionsY(i1) ) * scaleFactor + y_out%MsrPositionsY(i1) = y1%MsrPositionsY(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ALLOCATED(y_out%MsrPositionsZ) .AND. ALLOCATED(y1%MsrPositionsZ)) THEN + DO i1 = LBOUND(y_out%MsrPositionsZ,1),UBOUND(y_out%MsrPositionsZ,1) + b = (t(3)**2*(y1%MsrPositionsZ(i1) - y2%MsrPositionsZ(i1)) + t(2)**2*(-y1%MsrPositionsZ(i1) + y3%MsrPositionsZ(i1)))* scaleFactor + c = ( (t(2)-t(3))*y1%MsrPositionsZ(i1) + t(3)*y2%MsrPositionsZ(i1) - t(2)*y3%MsrPositionsZ(i1) ) * scaleFactor + y_out%MsrPositionsZ(i1) = y1%MsrPositionsZ(i1) + b + c * t_out + END DO END IF ! check if allocated END SUBROUTINE Lidar_Output_ExtrapInterp2 diff --git a/modules/inflowwind/tests/ifw_test_tools.F90 b/modules/inflowwind/tests/ifw_test_tools.F90 index bbbabbbdf..109fd36f7 100644 --- a/modules/inflowwind/tests/ifw_test_tools.F90 +++ b/modules/inflowwind/tests/ifw_test_tools.F90 @@ -13,7 +13,7 @@ function getInputFileData() INTEGER :: ErrStat CHARACTER(ErrMsgLen) :: ErrMsg TYPE(FileInfoType) :: getInputFileData - CHARACTER(1024), DIMENSION(55) :: data = (/ & + CHARACTER(1024), DIMENSION(69) :: data = (/ & '------- InflowWind v3.01.* INPUT FILE ------------------------------------------------------------------------- ', & 'Steady 8 m/s winds with no shear for FAST CertTests #20 and #25 ', & '--------------------------------------------------------------------------------------------------------------- ', & @@ -21,6 +21,7 @@ function getInputFileData() ' 1 WindType - switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined; 7=native Bladed FF) ', & ' 0 PropagationDir - Direction of wind propagation (meteoroligical rotation from aligned with X (positive rotates towards -Y) -- degrees) ', & ' 0 VFlowAng - Upflow angle (degrees) (not used for native Bladed format WindType=7) ', & + ' false VelInterpCubic - Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7] ', & ' 1 NWindVel - Number of points to output the wind velocity (0 to 9) ', & ' 0 WindVxiList - List of coordinates in the inertial X direction (m) ', & ' 0 WindVyiList - List of coordinates in the inertial Y direction (m) ', & @@ -63,6 +64,19 @@ function getInputFileData() ' 0 PLExp_HAWC - Power law exponent (-) (used for PL wind profile type only) ', & ' 0.03 Z0 - Surface roughness length (m) (used for LG wind profile type only) ', & ' 0 XOffset - Initial offset in +x direction (shift of wind box) ', & + ' ---------------- LIDAR Parameters --------------------------------------------------------------------------- ', & + ' 0 SensorType - Switch for lidar configuration (0 = None, 1 = Single Point Beam(s), 2 = Continuous, 3 = Pulsed) ', & + ' 0 NumPulseGate - Number of lidar measurement gates (used when SensorType = 3) ', & + ' 30 PulseSpacing - Distance between range gates (m) (used when SensorType = 3) ', & + ' 0 NumBeam - Number of lidar measurement beams (0-5)(used when SensorType = 1) ', & + ' -200 FocalDistanceX - Focal distance co-ordinates of the lidar beam in the x direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m)', & + ' 0 FocalDistanceY - Focal distance co-ordinates of the lidar beam in the y direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m)', & + ' 0 FocalDistanceZ - Focal distance co-ordinates of the lidar beam in the z direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m)', & + '0.0 0.0 0.0 RotorApexOffsetPos - Offset of the lidar from hub height (m) ', & + ' 17 URefLid - Reference average wind speed for the lidar[m/s] ', & + ' 0.25 MeasurementInterval - Time between each measurement [s] ', & + ' False LidRadialVel - TRUE => return radial component, FALSE => return "x" direction estimate ', & + ' 1 ConsiderHubMotion - Flag whether to consider the hub motion impact on Lidar measurements ', & '====================== OUTPUT ================================================== ', & 'False SumPrint - Print summary data to .IfW.sum (flag) ', & ' OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) ', & @@ -80,7 +94,7 @@ function getInputFileDataWindType2() INTEGER :: ErrStat CHARACTER(ErrMsgLen) :: ErrMsg TYPE(FileInfoType) :: getInputFileDataWindType2 - CHARACTER(1024), DIMENSION(55) :: data = (/ & + CHARACTER(1024), DIMENSION(69) :: data = (/ & '------- InflowWind v3.01.* INPUT FILE ------------------------------------------------------------------------- ', & 'Steady 8 m/s winds with no shear for FAST CertTests #20 and #25 ', & '--------------------------------------------------------------------------------------------------------------- ', & @@ -88,6 +102,7 @@ function getInputFileDataWindType2() ' 2 WindType - switch for wind file type (1=steady; 2=uniform; 3=binary TurbSim FF; 4=binary Bladed-style FF; 5=HAWC format; 6=User defined; 7=native Bladed FF) ', & ' 0 PropagationDir - Direction of wind propagation (meteoroligical rotation from aligned with X (positive rotates towards -Y) -- degrees) ', & ' 0 VFlowAng - Upflow angle (degrees) (not used for native Bladed format WindType=7) ', & + ' false VelInterpCubic - Use cubic interpolation for velocity in time (false=linear, true=cubic) [Used with WindType=2,3,4,5,7] ', & ' 1 NWindVel - Number of points to output the wind velocity (0 to 9) ', & ' 0 WindVxiList - List of coordinates in the inertial X direction (m) ', & ' 0 WindVyiList - List of coordinates in the inertial Y direction (m) ', & @@ -130,6 +145,19 @@ function getInputFileDataWindType2() ' 0 PLExp_HAWC - Power law exponent (-) (used for PL wind profile type only) ', & ' 0.03 Z0 - Surface roughness length (m) (used for LG wind profile type only) ', & ' 0 XOffset - Initial offset in +x direction (shift of wind box) ', & + ' ---------------- LIDAR Parameters --------------------------------------------------------------------------- ', & + ' 0 SensorType - Switch for lidar configuration (0 = None, 1 = Single Point Beam(s), 2 = Continuous, 3 = Pulsed) ', & + ' 0 NumPulseGate - Number of lidar measurement gates (used when SensorType = 3) ', & + ' 30 PulseSpacing - Distance between range gates (m) (used when SensorType = 3) ', & + ' 0 NumBeam - Number of lidar measurement beams (0-5)(used when SensorType = 1) ', & + ' -200 FocalDistanceX - Focal distance co-ordinates of the lidar beam in the x direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m)', & + ' 0 FocalDistanceY - Focal distance co-ordinates of the lidar beam in the y direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m)', & + ' 0 FocalDistanceZ - Focal distance co-ordinates of the lidar beam in the z direction (relative to hub height) (only first coordinate used for SensorType 2 and 3) (m)', & + '0.0 0.0 0.0 RotorApexOffsetPos - Offset of the lidar from hub height (m) ', & + ' 17 URefLid - Reference average wind speed for the lidar[m/s] ', & + ' 0.25 MeasurementInterval - Time between each measurement [s] ', & + ' False LidRadialVel - TRUE => return radial component, FALSE => return "x" direction estimate ', & + ' 1 ConsiderHubMotion - Flag whether to consider the hub motion impact on Lidar measurements ', & '====================== OUTPUT ================================================== ', & 'False SumPrint - Print summary data to .IfW.sum (flag) ', & ' OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-) ', & diff --git a/modules/inflowwind/tests/test_outputs.F90 b/modules/inflowwind/tests/test_outputs.F90 index 3a89f5759..a5acd741c 100644 --- a/modules/inflowwind/tests/test_outputs.F90 +++ b/modules/inflowwind/tests/test_outputs.F90 @@ -44,7 +44,7 @@ subroutine test_outputs_parsing_alternate() PriPath = "" InFileInfo = getInputFileData() - InFileInfo%Lines(51:53) = (/ & + InFileInfo%Lines(65:67) = (/ & 'True SumPrint - Print summary data to .IfW.sum (flag) ', & ' OutList - The next line(s) contains a list of output parameters. See OutListParameters.xlsx for a listing of available output channels, (-)', & '"Wind1VelX,Wind1VelY" - Wind velocity at point WindVxiList(1),WindVyiList(1),WindVziList(1). X, Y, and Z direction components. ' & diff --git a/modules/inflowwind/tests/test_steady_wind.F90 b/modules/inflowwind/tests/test_steady_wind.F90 index 3f6def1a5..6b0578402 100644 --- a/modules/inflowwind/tests/test_steady_wind.F90 +++ b/modules/inflowwind/tests/test_steady_wind.F90 @@ -43,7 +43,7 @@ subroutine test_steady_wind_input_mult_heights() PriPath = "" InFileInfo = getInputFileData() - InFileInfo%Lines(8:11) = (/ & + InFileInfo%Lines(9:12) = (/ & ' 2 NWindVel - Number of points to output the wind velocity (0 to 9) ', & ' 0,0 WindVxiList - List of coordinates in the inertial X direction (m) ', & ' 0,0 WindVyiList - List of coordinates in the inertial Y direction (m) ', & diff --git a/modules/inflowwind/tests/test_uniform_wind.F90 b/modules/inflowwind/tests/test_uniform_wind.F90 index f5525cfb7..13421e5da 100644 --- a/modules/inflowwind/tests/test_uniform_wind.F90 +++ b/modules/inflowwind/tests/test_uniform_wind.F90 @@ -90,13 +90,13 @@ subroutine test_uniform_wind_direct_data() ! Results @assertEqual(0, TmpErrStat, message='Error message: '//trim(TmpErrMsg)//NewLine//'ErrStat: ') - @assertEqual(0.0, p%UniformWind%TData(1)) - @assertEqual(0.1, p%UniformWind%TData(2)) - @assertEqual(999.9, p%UniformWind%TData(3)) + @assertEqual(0.0, p%FlowField%Uniform%Time(1)) + @assertEqual(0.1, p%FlowField%Uniform%Time(2)) + @assertEqual(999.9, p%FlowField%Uniform%Time(3)) - @assertEqual(12.0, p%UniformWind%V(1)) - @assertEqual(12.0, p%UniformWind%V(2)) - @assertEqual(12.0, p%UniformWind%V(3)) + @assertEqual(12.0, p%FlowField%Uniform%VelH(1)) + @assertEqual(12.0, p%FlowField%Uniform%VelH(2)) + @assertEqual(12.0, p%FlowField%Uniform%VelH(3)) end subroutine diff --git a/modules/map/CMakeLists.txt b/modules/map/CMakeLists.txt index 2bf1de3f4..b69312b4d 100644 --- a/modules/map/CMakeLists.txt +++ b/modules/map/CMakeLists.txt @@ -19,6 +19,11 @@ if(WIN32 OR CYGWIN OR MINGW) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMAP_DLL_EXPORTS -DCMINPACK_NO_DLL -DNDEBUG -D_WINDOWS -D_USRDLL") endif() +if (NOT WIN32) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") +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) @@ -28,29 +33,26 @@ endif() file(GLOB MAP_CLIB_SOURCES src/*.c src/*.cc src/*/*.c src/*/*.cc) file(GLOB MAP_C_HEADERS src/*.h src/*/*.h) -add_library(mapcpplib ${MAP_CLIB_SOURCES} src/MAP_Types.f90 src/MAP_Fortran_Types.f90) - -target_include_directories(mapcpplib PUBLIC +add_library(maplib + src/map.f90 + src/MAP_Types.f90 + src/MAP_Fortran_Types.f90 + ${MAP_CLIB_SOURCES} +) +target_link_libraries(maplib nwtclibs) +target_include_directories(maplib PUBLIC $ $ $ $ - $) -target_link_libraries(mapcpplib nwtclibs) - -add_library(maplib - src/map.f90 - src/MAP_Types.f90 - src/MAP_Fortran_Types.f90 + $ ) -target_link_libraries(maplib mapcpplib) +set_target_properties(maplib PROPERTIES PUBLIC_HEADER src/MAP_Types.h) -install(TARGETS maplib mapcpplib +install(TARGETS maplib EXPORT "${CMAKE_PROJECT_NAME}Libraries" - RUNTIME DESTINATION lib + RUNTIME DESTINATION bin ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) - -install(FILES - src/MAP_Types.h - DESTINATION include) + LIBRARY DESTINATION lib + PUBLIC_HEADER DESTINATION include +) diff --git a/modules/map/src/MAP_Fortran_Types.f90 b/modules/map/src/MAP_Fortran_Types.f90 index 47c34ab7c..4bed537cd 100644 --- a/modules/map/src/MAP_Fortran_Types.f90 +++ b/modules/map/src/MAP_Fortran_Types.f90 @@ -72,15 +72,27 @@ SUBROUTINE MAP_Fortran_CopyLin_InitInputType( SrcLin_InitInputTypeData, DstLin_I DstLin_InitInputTypeData%linearize = SrcLin_InitInputTypeData%linearize END SUBROUTINE MAP_Fortran_CopyLin_InitInputType - SUBROUTINE MAP_Fortran_DestroyLin_InitInputType( Lin_InitInputTypeData, ErrStat, ErrMsg ) + SUBROUTINE MAP_Fortran_DestroyLin_InitInputType( Lin_InitInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Lin_InitInputType), INTENT(INOUT) :: Lin_InitInputTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MAP_Fortran_DestroyLin_InitInputType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MAP_Fortran_DestroyLin_InitInputType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE MAP_Fortran_DestroyLin_InitInputType SUBROUTINE MAP_Fortran_PackLin_InitInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -235,15 +247,27 @@ SUBROUTINE MAP_Fortran_CopyLin_InitOutputType( SrcLin_InitOutputTypeData, DstLin ENDIF END SUBROUTINE MAP_Fortran_CopyLin_InitOutputType - SUBROUTINE MAP_Fortran_DestroyLin_InitOutputType( Lin_InitOutputTypeData, ErrStat, ErrMsg ) + SUBROUTINE MAP_Fortran_DestroyLin_InitOutputType( Lin_InitOutputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Lin_InitOutputType), INTENT(INOUT) :: Lin_InitOutputTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MAP_Fortran_DestroyLin_InitOutputType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MAP_Fortran_DestroyLin_InitOutputType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(Lin_InitOutputTypeData%LinNames_y)) THEN DEALLOCATE(Lin_InitOutputTypeData%LinNames_y) ENDIF @@ -504,15 +528,27 @@ SUBROUTINE MAP_Fortran_CopyLin_ParamType( SrcLin_ParamTypeData, DstLin_ParamType DstLin_ParamTypeData%Jac_ny = SrcLin_ParamTypeData%Jac_ny END SUBROUTINE MAP_Fortran_CopyLin_ParamType - SUBROUTINE MAP_Fortran_DestroyLin_ParamType( Lin_ParamTypeData, ErrStat, ErrMsg ) + SUBROUTINE MAP_Fortran_DestroyLin_ParamType( Lin_ParamTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Lin_ParamType), INTENT(INOUT) :: Lin_ParamTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MAP_Fortran_DestroyLin_ParamType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MAP_Fortran_DestroyLin_ParamType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(Lin_ParamTypeData%Jac_u_indx)) THEN DEALLOCATE(Lin_ParamTypeData%Jac_u_indx) ENDIF diff --git a/modules/map/src/MAP_Types.f90 b/modules/map/src/MAP_Types.f90 index af274d629..d179fa96e 100644 --- a/modules/map/src/MAP_Types.f90 +++ b/modules/map/src/MAP_Types.f90 @@ -285,16 +285,29 @@ SUBROUTINE MAP_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrS IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE MAP_CopyInitInput - SUBROUTINE MAP_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE MAP_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MAP_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" - CALL MAP_Fortran_Destroylin_initinputtype( InitInputData%LinInitInp, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MAP_Fortran_Destroylin_initinputtype( InitInputData%LinInitInp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE MAP_DestroyInitInput SUBROUTINE MAP_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -661,23 +674,37 @@ SUBROUTINE MAP_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, E IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE MAP_CopyInitOutput - SUBROUTINE MAP_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE MAP_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MAP_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%writeOutputHdr)) THEN DEALLOCATE(InitOutputData%writeOutputHdr) ENDIF IF (ALLOCATED(InitOutputData%writeOutputUnt)) THEN DEALLOCATE(InitOutputData%writeOutputUnt) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) - CALL MAP_Fortran_Destroylin_initoutputtype( InitOutputData%LinInitOut, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MAP_Fortran_Destroylin_initoutputtype( InitOutputData%LinInitOut, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE MAP_DestroyInitOutput SUBROUTINE MAP_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1118,15 +1145,27 @@ SUBROUTINE MAP_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrS DstContStateData%C_obj%dummy = SrcContStateData%C_obj%dummy END SUBROUTINE MAP_CopyContState - SUBROUTINE MAP_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE MAP_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MAP_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE MAP_DestroyContState SUBROUTINE MAP_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1283,15 +1322,27 @@ SUBROUTINE MAP_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrS DstDiscStateData%C_obj%dummy = SrcDiscStateData%C_obj%dummy END SUBROUTINE MAP_CopyDiscState - SUBROUTINE MAP_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE MAP_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MAP_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE MAP_DestroyDiscState SUBROUTINE MAP_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1456,7 +1507,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%H_Len = SIZE(DstOtherStateData%H) IF (DstOtherStateData%c_obj%H_Len > 0) & - DstOtherStateData%c_obj%H = C_LOC( DstOtherStateData%H(i1_l) ) + DstOtherStateData%c_obj%H = C_LOC( DstOtherStateData%H( i1_l ) ) END IF DstOtherStateData%H = SrcOtherStateData%H ENDIF @@ -1471,7 +1522,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%V_Len = SIZE(DstOtherStateData%V) IF (DstOtherStateData%c_obj%V_Len > 0) & - DstOtherStateData%c_obj%V = C_LOC( DstOtherStateData%V(i1_l) ) + DstOtherStateData%c_obj%V = C_LOC( DstOtherStateData%V( i1_l ) ) END IF DstOtherStateData%V = SrcOtherStateData%V ENDIF @@ -1486,7 +1537,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%Ha_Len = SIZE(DstOtherStateData%Ha) IF (DstOtherStateData%c_obj%Ha_Len > 0) & - DstOtherStateData%c_obj%Ha = C_LOC( DstOtherStateData%Ha(i1_l) ) + DstOtherStateData%c_obj%Ha = C_LOC( DstOtherStateData%Ha( i1_l ) ) END IF DstOtherStateData%Ha = SrcOtherStateData%Ha ENDIF @@ -1501,7 +1552,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%Va_Len = SIZE(DstOtherStateData%Va) IF (DstOtherStateData%c_obj%Va_Len > 0) & - DstOtherStateData%c_obj%Va = C_LOC( DstOtherStateData%Va(i1_l) ) + DstOtherStateData%c_obj%Va = C_LOC( DstOtherStateData%Va( i1_l ) ) END IF DstOtherStateData%Va = SrcOtherStateData%Va ENDIF @@ -1516,7 +1567,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%x_Len = SIZE(DstOtherStateData%x) IF (DstOtherStateData%c_obj%x_Len > 0) & - DstOtherStateData%c_obj%x = C_LOC( DstOtherStateData%x(i1_l) ) + DstOtherStateData%c_obj%x = C_LOC( DstOtherStateData%x( i1_l ) ) END IF DstOtherStateData%x = SrcOtherStateData%x ENDIF @@ -1531,7 +1582,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%y_Len = SIZE(DstOtherStateData%y) IF (DstOtherStateData%c_obj%y_Len > 0) & - DstOtherStateData%c_obj%y = C_LOC( DstOtherStateData%y(i1_l) ) + DstOtherStateData%c_obj%y = C_LOC( DstOtherStateData%y( i1_l ) ) END IF DstOtherStateData%y = SrcOtherStateData%y ENDIF @@ -1546,7 +1597,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%z_Len = SIZE(DstOtherStateData%z) IF (DstOtherStateData%c_obj%z_Len > 0) & - DstOtherStateData%c_obj%z = C_LOC( DstOtherStateData%z(i1_l) ) + DstOtherStateData%c_obj%z = C_LOC( DstOtherStateData%z( i1_l ) ) END IF DstOtherStateData%z = SrcOtherStateData%z ENDIF @@ -1561,7 +1612,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%xa_Len = SIZE(DstOtherStateData%xa) IF (DstOtherStateData%c_obj%xa_Len > 0) & - DstOtherStateData%c_obj%xa = C_LOC( DstOtherStateData%xa(i1_l) ) + DstOtherStateData%c_obj%xa = C_LOC( DstOtherStateData%xa( i1_l ) ) END IF DstOtherStateData%xa = SrcOtherStateData%xa ENDIF @@ -1576,7 +1627,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%ya_Len = SIZE(DstOtherStateData%ya) IF (DstOtherStateData%c_obj%ya_Len > 0) & - DstOtherStateData%c_obj%ya = C_LOC( DstOtherStateData%ya(i1_l) ) + DstOtherStateData%c_obj%ya = C_LOC( DstOtherStateData%ya( i1_l ) ) END IF DstOtherStateData%ya = SrcOtherStateData%ya ENDIF @@ -1591,7 +1642,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%za_Len = SIZE(DstOtherStateData%za) IF (DstOtherStateData%c_obj%za_Len > 0) & - DstOtherStateData%c_obj%za = C_LOC( DstOtherStateData%za(i1_l) ) + DstOtherStateData%c_obj%za = C_LOC( DstOtherStateData%za( i1_l ) ) END IF DstOtherStateData%za = SrcOtherStateData%za ENDIF @@ -1606,7 +1657,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%Fx_connect_Len = SIZE(DstOtherStateData%Fx_connect) IF (DstOtherStateData%c_obj%Fx_connect_Len > 0) & - DstOtherStateData%c_obj%Fx_connect = C_LOC( DstOtherStateData%Fx_connect(i1_l) ) + DstOtherStateData%c_obj%Fx_connect = C_LOC( DstOtherStateData%Fx_connect( i1_l ) ) END IF DstOtherStateData%Fx_connect = SrcOtherStateData%Fx_connect ENDIF @@ -1621,7 +1672,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%Fy_connect_Len = SIZE(DstOtherStateData%Fy_connect) IF (DstOtherStateData%c_obj%Fy_connect_Len > 0) & - DstOtherStateData%c_obj%Fy_connect = C_LOC( DstOtherStateData%Fy_connect(i1_l) ) + DstOtherStateData%c_obj%Fy_connect = C_LOC( DstOtherStateData%Fy_connect( i1_l ) ) END IF DstOtherStateData%Fy_connect = SrcOtherStateData%Fy_connect ENDIF @@ -1636,7 +1687,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%Fz_connect_Len = SIZE(DstOtherStateData%Fz_connect) IF (DstOtherStateData%c_obj%Fz_connect_Len > 0) & - DstOtherStateData%c_obj%Fz_connect = C_LOC( DstOtherStateData%Fz_connect(i1_l) ) + DstOtherStateData%c_obj%Fz_connect = C_LOC( DstOtherStateData%Fz_connect( i1_l ) ) END IF DstOtherStateData%Fz_connect = SrcOtherStateData%Fz_connect ENDIF @@ -1651,7 +1702,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%Fx_anchor_Len = SIZE(DstOtherStateData%Fx_anchor) IF (DstOtherStateData%c_obj%Fx_anchor_Len > 0) & - DstOtherStateData%c_obj%Fx_anchor = C_LOC( DstOtherStateData%Fx_anchor(i1_l) ) + DstOtherStateData%c_obj%Fx_anchor = C_LOC( DstOtherStateData%Fx_anchor( i1_l ) ) END IF DstOtherStateData%Fx_anchor = SrcOtherStateData%Fx_anchor ENDIF @@ -1666,7 +1717,7 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%Fy_anchor_Len = SIZE(DstOtherStateData%Fy_anchor) IF (DstOtherStateData%c_obj%Fy_anchor_Len > 0) & - DstOtherStateData%c_obj%Fy_anchor = C_LOC( DstOtherStateData%Fy_anchor(i1_l) ) + DstOtherStateData%c_obj%Fy_anchor = C_LOC( DstOtherStateData%Fy_anchor( i1_l ) ) END IF DstOtherStateData%Fy_anchor = SrcOtherStateData%Fy_anchor ENDIF @@ -1681,112 +1732,140 @@ SUBROUTINE MAP_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E END IF DstOtherStateData%c_obj%Fz_anchor_Len = SIZE(DstOtherStateData%Fz_anchor) IF (DstOtherStateData%c_obj%Fz_anchor_Len > 0) & - DstOtherStateData%c_obj%Fz_anchor = C_LOC( DstOtherStateData%Fz_anchor(i1_l) ) + DstOtherStateData%c_obj%Fz_anchor = C_LOC( DstOtherStateData%Fz_anchor( i1_l ) ) END IF DstOtherStateData%Fz_anchor = SrcOtherStateData%Fz_anchor ENDIF END SUBROUTINE MAP_CopyOtherState - SUBROUTINE MAP_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE MAP_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MAP_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(OtherStateData%H)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%H) OtherStateData%H => NULL() OtherStateData%C_obj%H = C_NULL_PTR OtherStateData%C_obj%H_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%V)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%V) OtherStateData%V => NULL() OtherStateData%C_obj%V = C_NULL_PTR OtherStateData%C_obj%V_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%Ha)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%Ha) OtherStateData%Ha => NULL() OtherStateData%C_obj%Ha = C_NULL_PTR OtherStateData%C_obj%Ha_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%Va)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%Va) OtherStateData%Va => NULL() OtherStateData%C_obj%Va = C_NULL_PTR OtherStateData%C_obj%Va_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%x)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%x) OtherStateData%x => NULL() OtherStateData%C_obj%x = C_NULL_PTR OtherStateData%C_obj%x_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%y)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%y) OtherStateData%y => NULL() OtherStateData%C_obj%y = C_NULL_PTR OtherStateData%C_obj%y_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%z)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%z) OtherStateData%z => NULL() OtherStateData%C_obj%z = C_NULL_PTR OtherStateData%C_obj%z_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%xa)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%xa) OtherStateData%xa => NULL() OtherStateData%C_obj%xa = C_NULL_PTR OtherStateData%C_obj%xa_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%ya)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%ya) OtherStateData%ya => NULL() OtherStateData%C_obj%ya = C_NULL_PTR OtherStateData%C_obj%ya_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%za)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%za) OtherStateData%za => NULL() OtherStateData%C_obj%za = C_NULL_PTR OtherStateData%C_obj%za_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%Fx_connect)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%Fx_connect) OtherStateData%Fx_connect => NULL() OtherStateData%C_obj%Fx_connect = C_NULL_PTR OtherStateData%C_obj%Fx_connect_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%Fy_connect)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%Fy_connect) OtherStateData%Fy_connect => NULL() OtherStateData%C_obj%Fy_connect = C_NULL_PTR OtherStateData%C_obj%Fy_connect_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%Fz_connect)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%Fz_connect) OtherStateData%Fz_connect => NULL() OtherStateData%C_obj%Fz_connect = C_NULL_PTR OtherStateData%C_obj%Fz_connect_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%Fx_anchor)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%Fx_anchor) OtherStateData%Fx_anchor => NULL() OtherStateData%C_obj%Fx_anchor = C_NULL_PTR OtherStateData%C_obj%Fx_anchor_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%Fy_anchor)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%Fy_anchor) OtherStateData%Fy_anchor => NULL() OtherStateData%C_obj%Fy_anchor = C_NULL_PTR OtherStateData%C_obj%Fy_anchor_Len = 0 ENDIF IF (ASSOCIATED(OtherStateData%Fz_anchor)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OtherStateData%Fz_anchor) OtherStateData%Fz_anchor => NULL() OtherStateData%C_obj%Fz_anchor = C_NULL_PTR @@ -2222,7 +2301,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%H_Len = SIZE(OutData%H) IF (OutData%c_obj%H_Len > 0) & - OutData%c_obj%H = C_LOC( OutData%H(i1_l) ) + OutData%c_obj%H = C_LOC( OutData%H( i1_l ) ) DO i1 = LBOUND(OutData%H,1), UBOUND(OutData%H,1) OutData%H(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2243,7 +2322,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%V_Len = SIZE(OutData%V) IF (OutData%c_obj%V_Len > 0) & - OutData%c_obj%V = C_LOC( OutData%V(i1_l) ) + OutData%c_obj%V = C_LOC( OutData%V( i1_l ) ) DO i1 = LBOUND(OutData%V,1), UBOUND(OutData%V,1) OutData%V(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2264,7 +2343,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%Ha_Len = SIZE(OutData%Ha) IF (OutData%c_obj%Ha_Len > 0) & - OutData%c_obj%Ha = C_LOC( OutData%Ha(i1_l) ) + OutData%c_obj%Ha = C_LOC( OutData%Ha( i1_l ) ) DO i1 = LBOUND(OutData%Ha,1), UBOUND(OutData%Ha,1) OutData%Ha(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2285,7 +2364,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%Va_Len = SIZE(OutData%Va) IF (OutData%c_obj%Va_Len > 0) & - OutData%c_obj%Va = C_LOC( OutData%Va(i1_l) ) + OutData%c_obj%Va = C_LOC( OutData%Va( i1_l ) ) DO i1 = LBOUND(OutData%Va,1), UBOUND(OutData%Va,1) OutData%Va(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2306,7 +2385,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%x_Len = SIZE(OutData%x) IF (OutData%c_obj%x_Len > 0) & - OutData%c_obj%x = C_LOC( OutData%x(i1_l) ) + OutData%c_obj%x = C_LOC( OutData%x( i1_l ) ) DO i1 = LBOUND(OutData%x,1), UBOUND(OutData%x,1) OutData%x(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2327,7 +2406,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%y_Len = SIZE(OutData%y) IF (OutData%c_obj%y_Len > 0) & - OutData%c_obj%y = C_LOC( OutData%y(i1_l) ) + OutData%c_obj%y = C_LOC( OutData%y( i1_l ) ) DO i1 = LBOUND(OutData%y,1), UBOUND(OutData%y,1) OutData%y(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2348,7 +2427,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%z_Len = SIZE(OutData%z) IF (OutData%c_obj%z_Len > 0) & - OutData%c_obj%z = C_LOC( OutData%z(i1_l) ) + OutData%c_obj%z = C_LOC( OutData%z( i1_l ) ) DO i1 = LBOUND(OutData%z,1), UBOUND(OutData%z,1) OutData%z(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2369,7 +2448,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%xa_Len = SIZE(OutData%xa) IF (OutData%c_obj%xa_Len > 0) & - OutData%c_obj%xa = C_LOC( OutData%xa(i1_l) ) + OutData%c_obj%xa = C_LOC( OutData%xa( i1_l ) ) DO i1 = LBOUND(OutData%xa,1), UBOUND(OutData%xa,1) OutData%xa(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2390,7 +2469,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%ya_Len = SIZE(OutData%ya) IF (OutData%c_obj%ya_Len > 0) & - OutData%c_obj%ya = C_LOC( OutData%ya(i1_l) ) + OutData%c_obj%ya = C_LOC( OutData%ya( i1_l ) ) DO i1 = LBOUND(OutData%ya,1), UBOUND(OutData%ya,1) OutData%ya(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2411,7 +2490,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%za_Len = SIZE(OutData%za) IF (OutData%c_obj%za_Len > 0) & - OutData%c_obj%za = C_LOC( OutData%za(i1_l) ) + OutData%c_obj%za = C_LOC( OutData%za( i1_l ) ) DO i1 = LBOUND(OutData%za,1), UBOUND(OutData%za,1) OutData%za(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2432,7 +2511,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%Fx_connect_Len = SIZE(OutData%Fx_connect) IF (OutData%c_obj%Fx_connect_Len > 0) & - OutData%c_obj%Fx_connect = C_LOC( OutData%Fx_connect(i1_l) ) + OutData%c_obj%Fx_connect = C_LOC( OutData%Fx_connect( i1_l ) ) DO i1 = LBOUND(OutData%Fx_connect,1), UBOUND(OutData%Fx_connect,1) OutData%Fx_connect(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2453,7 +2532,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%Fy_connect_Len = SIZE(OutData%Fy_connect) IF (OutData%c_obj%Fy_connect_Len > 0) & - OutData%c_obj%Fy_connect = C_LOC( OutData%Fy_connect(i1_l) ) + OutData%c_obj%Fy_connect = C_LOC( OutData%Fy_connect( i1_l ) ) DO i1 = LBOUND(OutData%Fy_connect,1), UBOUND(OutData%Fy_connect,1) OutData%Fy_connect(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2474,7 +2553,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%Fz_connect_Len = SIZE(OutData%Fz_connect) IF (OutData%c_obj%Fz_connect_Len > 0) & - OutData%c_obj%Fz_connect = C_LOC( OutData%Fz_connect(i1_l) ) + OutData%c_obj%Fz_connect = C_LOC( OutData%Fz_connect( i1_l ) ) DO i1 = LBOUND(OutData%Fz_connect,1), UBOUND(OutData%Fz_connect,1) OutData%Fz_connect(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2495,7 +2574,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%Fx_anchor_Len = SIZE(OutData%Fx_anchor) IF (OutData%c_obj%Fx_anchor_Len > 0) & - OutData%c_obj%Fx_anchor = C_LOC( OutData%Fx_anchor(i1_l) ) + OutData%c_obj%Fx_anchor = C_LOC( OutData%Fx_anchor( i1_l ) ) DO i1 = LBOUND(OutData%Fx_anchor,1), UBOUND(OutData%Fx_anchor,1) OutData%Fx_anchor(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2516,7 +2595,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%Fy_anchor_Len = SIZE(OutData%Fy_anchor) IF (OutData%c_obj%Fy_anchor_Len > 0) & - OutData%c_obj%Fy_anchor = C_LOC( OutData%Fy_anchor(i1_l) ) + OutData%c_obj%Fy_anchor = C_LOC( OutData%Fy_anchor( i1_l ) ) DO i1 = LBOUND(OutData%Fy_anchor,1), UBOUND(OutData%Fy_anchor,1) OutData%Fy_anchor(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2537,7 +2616,7 @@ SUBROUTINE MAP_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%Fz_anchor_Len = SIZE(OutData%Fz_anchor) IF (OutData%c_obj%Fz_anchor_Len > 0) & - OutData%c_obj%Fz_anchor = C_LOC( OutData%Fz_anchor(i1_l) ) + OutData%c_obj%Fz_anchor = C_LOC( OutData%Fz_anchor( i1_l ) ) DO i1 = LBOUND(OutData%Fz_anchor,1), UBOUND(OutData%Fz_anchor,1) OutData%Fz_anchor(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -2730,7 +2809,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%H_Len = SIZE(OtherStateData%H) IF (OtherStateData%c_obj%H_Len > 0) & - OtherStateData%c_obj%H = C_LOC( OtherStateData%H( LBOUND(OtherStateData%H,1) ) ) + OtherStateData%c_obj%H = C_LOC( OtherStateData%H( LBOUND(OtherStateData%H,1) ) ) END IF END IF @@ -2742,7 +2821,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%V_Len = SIZE(OtherStateData%V) IF (OtherStateData%c_obj%V_Len > 0) & - OtherStateData%c_obj%V = C_LOC( OtherStateData%V( LBOUND(OtherStateData%V,1) ) ) + OtherStateData%c_obj%V = C_LOC( OtherStateData%V( LBOUND(OtherStateData%V,1) ) ) END IF END IF @@ -2754,7 +2833,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%Ha_Len = SIZE(OtherStateData%Ha) IF (OtherStateData%c_obj%Ha_Len > 0) & - OtherStateData%c_obj%Ha = C_LOC( OtherStateData%Ha( LBOUND(OtherStateData%Ha,1) ) ) + OtherStateData%c_obj%Ha = C_LOC( OtherStateData%Ha( LBOUND(OtherStateData%Ha,1) ) ) END IF END IF @@ -2766,7 +2845,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%Va_Len = SIZE(OtherStateData%Va) IF (OtherStateData%c_obj%Va_Len > 0) & - OtherStateData%c_obj%Va = C_LOC( OtherStateData%Va( LBOUND(OtherStateData%Va,1) ) ) + OtherStateData%c_obj%Va = C_LOC( OtherStateData%Va( LBOUND(OtherStateData%Va,1) ) ) END IF END IF @@ -2778,7 +2857,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%x_Len = SIZE(OtherStateData%x) IF (OtherStateData%c_obj%x_Len > 0) & - OtherStateData%c_obj%x = C_LOC( OtherStateData%x( LBOUND(OtherStateData%x,1) ) ) + OtherStateData%c_obj%x = C_LOC( OtherStateData%x( LBOUND(OtherStateData%x,1) ) ) END IF END IF @@ -2790,7 +2869,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%y_Len = SIZE(OtherStateData%y) IF (OtherStateData%c_obj%y_Len > 0) & - OtherStateData%c_obj%y = C_LOC( OtherStateData%y( LBOUND(OtherStateData%y,1) ) ) + OtherStateData%c_obj%y = C_LOC( OtherStateData%y( LBOUND(OtherStateData%y,1) ) ) END IF END IF @@ -2802,7 +2881,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%z_Len = SIZE(OtherStateData%z) IF (OtherStateData%c_obj%z_Len > 0) & - OtherStateData%c_obj%z = C_LOC( OtherStateData%z( LBOUND(OtherStateData%z,1) ) ) + OtherStateData%c_obj%z = C_LOC( OtherStateData%z( LBOUND(OtherStateData%z,1) ) ) END IF END IF @@ -2814,7 +2893,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%xa_Len = SIZE(OtherStateData%xa) IF (OtherStateData%c_obj%xa_Len > 0) & - OtherStateData%c_obj%xa = C_LOC( OtherStateData%xa( LBOUND(OtherStateData%xa,1) ) ) + OtherStateData%c_obj%xa = C_LOC( OtherStateData%xa( LBOUND(OtherStateData%xa,1) ) ) END IF END IF @@ -2826,7 +2905,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%ya_Len = SIZE(OtherStateData%ya) IF (OtherStateData%c_obj%ya_Len > 0) & - OtherStateData%c_obj%ya = C_LOC( OtherStateData%ya( LBOUND(OtherStateData%ya,1) ) ) + OtherStateData%c_obj%ya = C_LOC( OtherStateData%ya( LBOUND(OtherStateData%ya,1) ) ) END IF END IF @@ -2838,7 +2917,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%za_Len = SIZE(OtherStateData%za) IF (OtherStateData%c_obj%za_Len > 0) & - OtherStateData%c_obj%za = C_LOC( OtherStateData%za( LBOUND(OtherStateData%za,1) ) ) + OtherStateData%c_obj%za = C_LOC( OtherStateData%za( LBOUND(OtherStateData%za,1) ) ) END IF END IF @@ -2850,7 +2929,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%Fx_connect_Len = SIZE(OtherStateData%Fx_connect) IF (OtherStateData%c_obj%Fx_connect_Len > 0) & - OtherStateData%c_obj%Fx_connect = C_LOC( OtherStateData%Fx_connect( LBOUND(OtherStateData%Fx_connect,1) ) ) + OtherStateData%c_obj%Fx_connect = C_LOC( OtherStateData%Fx_connect( LBOUND(OtherStateData%Fx_connect,1) ) ) END IF END IF @@ -2862,7 +2941,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%Fy_connect_Len = SIZE(OtherStateData%Fy_connect) IF (OtherStateData%c_obj%Fy_connect_Len > 0) & - OtherStateData%c_obj%Fy_connect = C_LOC( OtherStateData%Fy_connect( LBOUND(OtherStateData%Fy_connect,1) ) ) + OtherStateData%c_obj%Fy_connect = C_LOC( OtherStateData%Fy_connect( LBOUND(OtherStateData%Fy_connect,1) ) ) END IF END IF @@ -2874,7 +2953,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%Fz_connect_Len = SIZE(OtherStateData%Fz_connect) IF (OtherStateData%c_obj%Fz_connect_Len > 0) & - OtherStateData%c_obj%Fz_connect = C_LOC( OtherStateData%Fz_connect( LBOUND(OtherStateData%Fz_connect,1) ) ) + OtherStateData%c_obj%Fz_connect = C_LOC( OtherStateData%Fz_connect( LBOUND(OtherStateData%Fz_connect,1) ) ) END IF END IF @@ -2886,7 +2965,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%Fx_anchor_Len = SIZE(OtherStateData%Fx_anchor) IF (OtherStateData%c_obj%Fx_anchor_Len > 0) & - OtherStateData%c_obj%Fx_anchor = C_LOC( OtherStateData%Fx_anchor( LBOUND(OtherStateData%Fx_anchor,1) ) ) + OtherStateData%c_obj%Fx_anchor = C_LOC( OtherStateData%Fx_anchor( LBOUND(OtherStateData%Fx_anchor,1) ) ) END IF END IF @@ -2898,7 +2977,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%Fy_anchor_Len = SIZE(OtherStateData%Fy_anchor) IF (OtherStateData%c_obj%Fy_anchor_Len > 0) & - OtherStateData%c_obj%Fy_anchor = C_LOC( OtherStateData%Fy_anchor( LBOUND(OtherStateData%Fy_anchor,1) ) ) + OtherStateData%c_obj%Fy_anchor = C_LOC( OtherStateData%Fy_anchor( LBOUND(OtherStateData%Fy_anchor,1) ) ) END IF END IF @@ -2910,7 +2989,7 @@ SUBROUTINE MAP_F2C_CopyOtherState( OtherStateData, ErrStat, ErrMsg, SkipPointers ELSE OtherStateData%c_obj%Fz_anchor_Len = SIZE(OtherStateData%Fz_anchor) IF (OtherStateData%c_obj%Fz_anchor_Len > 0) & - OtherStateData%c_obj%Fz_anchor = C_LOC( OtherStateData%Fz_anchor( LBOUND(OtherStateData%Fz_anchor,1) ) ) + OtherStateData%c_obj%Fz_anchor = C_LOC( OtherStateData%Fz_anchor( LBOUND(OtherStateData%Fz_anchor,1) ) ) END IF END IF END SUBROUTINE MAP_F2C_CopyOtherState @@ -2941,7 +3020,7 @@ SUBROUTINE MAP_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode END IF DstConstrStateData%c_obj%H_Len = SIZE(DstConstrStateData%H) IF (DstConstrStateData%c_obj%H_Len > 0) & - DstConstrStateData%c_obj%H = C_LOC( DstConstrStateData%H(i1_l) ) + DstConstrStateData%c_obj%H = C_LOC( DstConstrStateData%H( i1_l ) ) END IF DstConstrStateData%H = SrcConstrStateData%H ENDIF @@ -2956,7 +3035,7 @@ SUBROUTINE MAP_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode END IF DstConstrStateData%c_obj%V_Len = SIZE(DstConstrStateData%V) IF (DstConstrStateData%c_obj%V_Len > 0) & - DstConstrStateData%c_obj%V = C_LOC( DstConstrStateData%V(i1_l) ) + DstConstrStateData%c_obj%V = C_LOC( DstConstrStateData%V( i1_l ) ) END IF DstConstrStateData%V = SrcConstrStateData%V ENDIF @@ -2971,7 +3050,7 @@ SUBROUTINE MAP_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode END IF DstConstrStateData%c_obj%x_Len = SIZE(DstConstrStateData%x) IF (DstConstrStateData%c_obj%x_Len > 0) & - DstConstrStateData%c_obj%x = C_LOC( DstConstrStateData%x(i1_l) ) + DstConstrStateData%c_obj%x = C_LOC( DstConstrStateData%x( i1_l ) ) END IF DstConstrStateData%x = SrcConstrStateData%x ENDIF @@ -2986,7 +3065,7 @@ SUBROUTINE MAP_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode END IF DstConstrStateData%c_obj%y_Len = SIZE(DstConstrStateData%y) IF (DstConstrStateData%c_obj%y_Len > 0) & - DstConstrStateData%c_obj%y = C_LOC( DstConstrStateData%y(i1_l) ) + DstConstrStateData%c_obj%y = C_LOC( DstConstrStateData%y( i1_l ) ) END IF DstConstrStateData%y = SrcConstrStateData%y ENDIF @@ -3001,46 +3080,63 @@ SUBROUTINE MAP_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode END IF DstConstrStateData%c_obj%z_Len = SIZE(DstConstrStateData%z) IF (DstConstrStateData%c_obj%z_Len > 0) & - DstConstrStateData%c_obj%z = C_LOC( DstConstrStateData%z(i1_l) ) + DstConstrStateData%c_obj%z = C_LOC( DstConstrStateData%z( i1_l ) ) END IF DstConstrStateData%z = SrcConstrStateData%z ENDIF END SUBROUTINE MAP_CopyConstrState - SUBROUTINE MAP_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE MAP_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MAP_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(ConstrStateData%H)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(ConstrStateData%H) ConstrStateData%H => NULL() ConstrStateData%C_obj%H = C_NULL_PTR ConstrStateData%C_obj%H_Len = 0 ENDIF IF (ASSOCIATED(ConstrStateData%V)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(ConstrStateData%V) ConstrStateData%V => NULL() ConstrStateData%C_obj%V = C_NULL_PTR ConstrStateData%C_obj%V_Len = 0 ENDIF IF (ASSOCIATED(ConstrStateData%x)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(ConstrStateData%x) ConstrStateData%x => NULL() ConstrStateData%C_obj%x = C_NULL_PTR ConstrStateData%C_obj%x_Len = 0 ENDIF IF (ASSOCIATED(ConstrStateData%y)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(ConstrStateData%y) ConstrStateData%y => NULL() ConstrStateData%C_obj%y = C_NULL_PTR ConstrStateData%C_obj%y_Len = 0 ENDIF IF (ASSOCIATED(ConstrStateData%z)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(ConstrStateData%z) ConstrStateData%z => NULL() ConstrStateData%C_obj%z = C_NULL_PTR @@ -3256,7 +3352,7 @@ SUBROUTINE MAP_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END IF OutData%c_obj%H_Len = SIZE(OutData%H) IF (OutData%c_obj%H_Len > 0) & - OutData%c_obj%H = C_LOC( OutData%H(i1_l) ) + OutData%c_obj%H = C_LOC( OutData%H( i1_l ) ) DO i1 = LBOUND(OutData%H,1), UBOUND(OutData%H,1) OutData%H(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -3277,7 +3373,7 @@ SUBROUTINE MAP_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END IF OutData%c_obj%V_Len = SIZE(OutData%V) IF (OutData%c_obj%V_Len > 0) & - OutData%c_obj%V = C_LOC( OutData%V(i1_l) ) + OutData%c_obj%V = C_LOC( OutData%V( i1_l ) ) DO i1 = LBOUND(OutData%V,1), UBOUND(OutData%V,1) OutData%V(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -3298,7 +3394,7 @@ SUBROUTINE MAP_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END IF OutData%c_obj%x_Len = SIZE(OutData%x) IF (OutData%c_obj%x_Len > 0) & - OutData%c_obj%x = C_LOC( OutData%x(i1_l) ) + OutData%c_obj%x = C_LOC( OutData%x( i1_l ) ) DO i1 = LBOUND(OutData%x,1), UBOUND(OutData%x,1) OutData%x(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -3319,7 +3415,7 @@ SUBROUTINE MAP_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END IF OutData%c_obj%y_Len = SIZE(OutData%y) IF (OutData%c_obj%y_Len > 0) & - OutData%c_obj%y = C_LOC( OutData%y(i1_l) ) + OutData%c_obj%y = C_LOC( OutData%y( i1_l ) ) DO i1 = LBOUND(OutData%y,1), UBOUND(OutData%y,1) OutData%y(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -3340,7 +3436,7 @@ SUBROUTINE MAP_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, END IF OutData%c_obj%z_Len = SIZE(OutData%z) IF (OutData%c_obj%z_Len > 0) & - OutData%c_obj%z = C_LOC( OutData%z(i1_l) ) + OutData%c_obj%z = C_LOC( OutData%z( i1_l ) ) DO i1 = LBOUND(OutData%z,1), UBOUND(OutData%z,1) OutData%z(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -3434,7 +3530,7 @@ SUBROUTINE MAP_F2C_CopyConstrState( ConstrStateData, ErrStat, ErrMsg, SkipPointe ELSE ConstrStateData%c_obj%H_Len = SIZE(ConstrStateData%H) IF (ConstrStateData%c_obj%H_Len > 0) & - ConstrStateData%c_obj%H = C_LOC( ConstrStateData%H( LBOUND(ConstrStateData%H,1) ) ) + ConstrStateData%c_obj%H = C_LOC( ConstrStateData%H( LBOUND(ConstrStateData%H,1) ) ) END IF END IF @@ -3446,7 +3542,7 @@ SUBROUTINE MAP_F2C_CopyConstrState( ConstrStateData, ErrStat, ErrMsg, SkipPointe ELSE ConstrStateData%c_obj%V_Len = SIZE(ConstrStateData%V) IF (ConstrStateData%c_obj%V_Len > 0) & - ConstrStateData%c_obj%V = C_LOC( ConstrStateData%V( LBOUND(ConstrStateData%V,1) ) ) + ConstrStateData%c_obj%V = C_LOC( ConstrStateData%V( LBOUND(ConstrStateData%V,1) ) ) END IF END IF @@ -3458,7 +3554,7 @@ SUBROUTINE MAP_F2C_CopyConstrState( ConstrStateData, ErrStat, ErrMsg, SkipPointe ELSE ConstrStateData%c_obj%x_Len = SIZE(ConstrStateData%x) IF (ConstrStateData%c_obj%x_Len > 0) & - ConstrStateData%c_obj%x = C_LOC( ConstrStateData%x( LBOUND(ConstrStateData%x,1) ) ) + ConstrStateData%c_obj%x = C_LOC( ConstrStateData%x( LBOUND(ConstrStateData%x,1) ) ) END IF END IF @@ -3470,7 +3566,7 @@ SUBROUTINE MAP_F2C_CopyConstrState( ConstrStateData, ErrStat, ErrMsg, SkipPointe ELSE ConstrStateData%c_obj%y_Len = SIZE(ConstrStateData%y) IF (ConstrStateData%c_obj%y_Len > 0) & - ConstrStateData%c_obj%y = C_LOC( ConstrStateData%y( LBOUND(ConstrStateData%y,1) ) ) + ConstrStateData%c_obj%y = C_LOC( ConstrStateData%y( LBOUND(ConstrStateData%y,1) ) ) END IF END IF @@ -3482,7 +3578,7 @@ SUBROUTINE MAP_F2C_CopyConstrState( ConstrStateData, ErrStat, ErrMsg, SkipPointe ELSE ConstrStateData%c_obj%z_Len = SIZE(ConstrStateData%z) IF (ConstrStateData%c_obj%z_Len > 0) & - ConstrStateData%c_obj%z = C_LOC( ConstrStateData%z( LBOUND(ConstrStateData%z,1) ) ) + ConstrStateData%c_obj%z = C_LOC( ConstrStateData%z( LBOUND(ConstrStateData%z,1) ) ) END IF END IF END SUBROUTINE MAP_F2C_CopyConstrState @@ -3519,16 +3615,29 @@ SUBROUTINE MAP_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE MAP_CopyParam - SUBROUTINE MAP_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE MAP_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MAP_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" - CALL MAP_Fortran_Destroylin_paramtype( ParamData%LinParams, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MAP_Fortran_Destroylin_paramtype( ParamData%LinParams, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE MAP_DestroyParam SUBROUTINE MAP_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -3842,7 +3951,7 @@ SUBROUTINE MAP_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%x_Len = SIZE(DstInputData%x) IF (DstInputData%c_obj%x_Len > 0) & - DstInputData%c_obj%x = C_LOC( DstInputData%x(i1_l) ) + DstInputData%c_obj%x = C_LOC( DstInputData%x( i1_l ) ) END IF DstInputData%x = SrcInputData%x ENDIF @@ -3857,7 +3966,7 @@ SUBROUTINE MAP_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%y_Len = SIZE(DstInputData%y) IF (DstInputData%c_obj%y_Len > 0) & - DstInputData%c_obj%y = C_LOC( DstInputData%y(i1_l) ) + DstInputData%c_obj%y = C_LOC( DstInputData%y( i1_l ) ) END IF DstInputData%y = SrcInputData%y ENDIF @@ -3872,7 +3981,7 @@ SUBROUTINE MAP_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%z_Len = SIZE(DstInputData%z) IF (DstInputData%c_obj%z_Len > 0) & - DstInputData%c_obj%z = C_LOC( DstInputData%z(i1_l) ) + DstInputData%c_obj%z = C_LOC( DstInputData%z( i1_l ) ) END IF DstInputData%z = SrcInputData%z ENDIF @@ -3881,34 +3990,50 @@ SUBROUTINE MAP_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE MAP_CopyInput - SUBROUTINE MAP_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE MAP_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MAP_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(InputData%x)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%x) InputData%x => NULL() InputData%C_obj%x = C_NULL_PTR InputData%C_obj%x_Len = 0 ENDIF IF (ASSOCIATED(InputData%y)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%y) InputData%y => NULL() InputData%C_obj%y = C_NULL_PTR InputData%C_obj%y_Len = 0 ENDIF IF (ASSOCIATED(InputData%z)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%z) InputData%z => NULL() InputData%C_obj%z = C_NULL_PTR InputData%C_obj%z_Len = 0 ENDIF - CALL MeshDestroy( InputData%PtFairDisplacement, ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%PtFairDisplacement, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE MAP_DestroyInput SUBROUTINE MAP_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -4125,7 +4250,7 @@ SUBROUTINE MAP_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END IF OutData%c_obj%x_Len = SIZE(OutData%x) IF (OutData%c_obj%x_Len > 0) & - OutData%c_obj%x = C_LOC( OutData%x(i1_l) ) + OutData%c_obj%x = C_LOC( OutData%x( i1_l ) ) DO i1 = LBOUND(OutData%x,1), UBOUND(OutData%x,1) OutData%x(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -4146,7 +4271,7 @@ SUBROUTINE MAP_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END IF OutData%c_obj%y_Len = SIZE(OutData%y) IF (OutData%c_obj%y_Len > 0) & - OutData%c_obj%y = C_LOC( OutData%y(i1_l) ) + OutData%c_obj%y = C_LOC( OutData%y( i1_l ) ) DO i1 = LBOUND(OutData%y,1), UBOUND(OutData%y,1) OutData%y(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -4167,7 +4292,7 @@ SUBROUTINE MAP_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END IF OutData%c_obj%z_Len = SIZE(OutData%z) IF (OutData%c_obj%z_Len > 0) & - OutData%c_obj%z = C_LOC( OutData%z(i1_l) ) + OutData%c_obj%z = C_LOC( OutData%z( i1_l ) ) DO i1 = LBOUND(OutData%z,1), UBOUND(OutData%z,1) OutData%z(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -4283,7 +4408,7 @@ SUBROUTINE MAP_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%x_Len = SIZE(InputData%x) IF (InputData%c_obj%x_Len > 0) & - InputData%c_obj%x = C_LOC( InputData%x( LBOUND(InputData%x,1) ) ) + InputData%c_obj%x = C_LOC( InputData%x( LBOUND(InputData%x,1) ) ) END IF END IF @@ -4295,7 +4420,7 @@ SUBROUTINE MAP_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%y_Len = SIZE(InputData%y) IF (InputData%c_obj%y_Len > 0) & - InputData%c_obj%y = C_LOC( InputData%y( LBOUND(InputData%y,1) ) ) + InputData%c_obj%y = C_LOC( InputData%y( LBOUND(InputData%y,1) ) ) END IF END IF @@ -4307,7 +4432,7 @@ SUBROUTINE MAP_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%z_Len = SIZE(InputData%z) IF (InputData%c_obj%z_Len > 0) & - InputData%c_obj%z = C_LOC( InputData%z( LBOUND(InputData%z,1) ) ) + InputData%c_obj%z = C_LOC( InputData%z( LBOUND(InputData%z,1) ) ) END IF END IF END SUBROUTINE MAP_F2C_CopyInput @@ -4338,7 +4463,7 @@ SUBROUTINE MAP_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrM END IF DstOutputData%c_obj%Fx_Len = SIZE(DstOutputData%Fx) IF (DstOutputData%c_obj%Fx_Len > 0) & - DstOutputData%c_obj%Fx = C_LOC( DstOutputData%Fx(i1_l) ) + DstOutputData%c_obj%Fx = C_LOC( DstOutputData%Fx( i1_l ) ) END IF DstOutputData%Fx = SrcOutputData%Fx ENDIF @@ -4353,7 +4478,7 @@ SUBROUTINE MAP_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrM END IF DstOutputData%c_obj%Fy_Len = SIZE(DstOutputData%Fy) IF (DstOutputData%c_obj%Fy_Len > 0) & - DstOutputData%c_obj%Fy = C_LOC( DstOutputData%Fy(i1_l) ) + DstOutputData%c_obj%Fy = C_LOC( DstOutputData%Fy( i1_l ) ) END IF DstOutputData%Fy = SrcOutputData%Fy ENDIF @@ -4368,7 +4493,7 @@ SUBROUTINE MAP_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrM END IF DstOutputData%c_obj%Fz_Len = SIZE(DstOutputData%Fz) IF (DstOutputData%c_obj%Fz_Len > 0) & - DstOutputData%c_obj%Fz = C_LOC( DstOutputData%Fz(i1_l) ) + DstOutputData%c_obj%Fz = C_LOC( DstOutputData%Fz( i1_l ) ) END IF DstOutputData%Fz = SrcOutputData%Fz ENDIF @@ -4395,7 +4520,7 @@ SUBROUTINE MAP_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrM END IF DstOutputData%c_obj%wrtOutput_Len = SIZE(DstOutputData%wrtOutput) IF (DstOutputData%c_obj%wrtOutput_Len > 0) & - DstOutputData%c_obj%wrtOutput = C_LOC( DstOutputData%wrtOutput(i1_l) ) + DstOutputData%c_obj%wrtOutput = C_LOC( DstOutputData%wrtOutput( i1_l ) ) END IF DstOutputData%wrtOutput = SrcOutputData%wrtOutput ENDIF @@ -4404,28 +4529,43 @@ SUBROUTINE MAP_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrM IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE MAP_CopyOutput - SUBROUTINE MAP_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE MAP_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MAP_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MAP_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(OutputData%Fx)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OutputData%Fx) OutputData%Fx => NULL() OutputData%C_obj%Fx = C_NULL_PTR OutputData%C_obj%Fx_Len = 0 ENDIF IF (ASSOCIATED(OutputData%Fy)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OutputData%Fy) OutputData%Fy => NULL() OutputData%C_obj%Fy = C_NULL_PTR OutputData%C_obj%Fy_Len = 0 ENDIF IF (ASSOCIATED(OutputData%Fz)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OutputData%Fz) OutputData%Fz => NULL() OutputData%C_obj%Fz = C_NULL_PTR @@ -4435,12 +4575,14 @@ SUBROUTINE MAP_DestroyOutput( OutputData, ErrStat, ErrMsg ) DEALLOCATE(OutputData%WriteOutput) ENDIF IF (ASSOCIATED(OutputData%wrtOutput)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OutputData%wrtOutput) OutputData%wrtOutput => NULL() OutputData%C_obj%wrtOutput = C_NULL_PTR OutputData%C_obj%wrtOutput_Len = 0 ENDIF - CALL MeshDestroy( OutputData%ptFairleadLoad, ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%ptFairleadLoad, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE MAP_DestroyOutput SUBROUTINE MAP_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -4697,7 +4839,7 @@ SUBROUTINE MAP_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%Fx_Len = SIZE(OutData%Fx) IF (OutData%c_obj%Fx_Len > 0) & - OutData%c_obj%Fx = C_LOC( OutData%Fx(i1_l) ) + OutData%c_obj%Fx = C_LOC( OutData%Fx( i1_l ) ) DO i1 = LBOUND(OutData%Fx,1), UBOUND(OutData%Fx,1) OutData%Fx(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -4718,7 +4860,7 @@ SUBROUTINE MAP_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%Fy_Len = SIZE(OutData%Fy) IF (OutData%c_obj%Fy_Len > 0) & - OutData%c_obj%Fy = C_LOC( OutData%Fy(i1_l) ) + OutData%c_obj%Fy = C_LOC( OutData%Fy( i1_l ) ) DO i1 = LBOUND(OutData%Fy,1), UBOUND(OutData%Fy,1) OutData%Fy(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -4739,7 +4881,7 @@ SUBROUTINE MAP_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%Fz_Len = SIZE(OutData%Fz) IF (OutData%c_obj%Fz_Len > 0) & - OutData%c_obj%Fz = C_LOC( OutData%Fz(i1_l) ) + OutData%c_obj%Fz = C_LOC( OutData%Fz( i1_l ) ) DO i1 = LBOUND(OutData%Fz,1), UBOUND(OutData%Fz,1) OutData%Fz(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -4778,7 +4920,7 @@ SUBROUTINE MAP_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%wrtOutput_Len = SIZE(OutData%wrtOutput) IF (OutData%c_obj%wrtOutput_Len > 0) & - OutData%c_obj%wrtOutput = C_LOC( OutData%wrtOutput(i1_l) ) + OutData%c_obj%wrtOutput = C_LOC( OutData%wrtOutput( i1_l ) ) DO i1 = LBOUND(OutData%wrtOutput,1), UBOUND(OutData%wrtOutput,1) OutData%wrtOutput(i1) = REAL(DbKiBuf(Db_Xferred), C_DOUBLE) Db_Xferred = Db_Xferred + 1 @@ -4903,7 +5045,7 @@ SUBROUTINE MAP_F2C_CopyOutput( OutputData, ErrStat, ErrMsg, SkipPointers ) ELSE OutputData%c_obj%Fx_Len = SIZE(OutputData%Fx) IF (OutputData%c_obj%Fx_Len > 0) & - OutputData%c_obj%Fx = C_LOC( OutputData%Fx( LBOUND(OutputData%Fx,1) ) ) + OutputData%c_obj%Fx = C_LOC( OutputData%Fx( LBOUND(OutputData%Fx,1) ) ) END IF END IF @@ -4915,7 +5057,7 @@ SUBROUTINE MAP_F2C_CopyOutput( OutputData, ErrStat, ErrMsg, SkipPointers ) ELSE OutputData%c_obj%Fy_Len = SIZE(OutputData%Fy) IF (OutputData%c_obj%Fy_Len > 0) & - OutputData%c_obj%Fy = C_LOC( OutputData%Fy( LBOUND(OutputData%Fy,1) ) ) + OutputData%c_obj%Fy = C_LOC( OutputData%Fy( LBOUND(OutputData%Fy,1) ) ) END IF END IF @@ -4927,7 +5069,7 @@ SUBROUTINE MAP_F2C_CopyOutput( OutputData, ErrStat, ErrMsg, SkipPointers ) ELSE OutputData%c_obj%Fz_Len = SIZE(OutputData%Fz) IF (OutputData%c_obj%Fz_Len > 0) & - OutputData%c_obj%Fz = C_LOC( OutputData%Fz( LBOUND(OutputData%Fz,1) ) ) + OutputData%c_obj%Fz = C_LOC( OutputData%Fz( LBOUND(OutputData%Fz,1) ) ) END IF END IF @@ -4939,7 +5081,7 @@ SUBROUTINE MAP_F2C_CopyOutput( OutputData, ErrStat, ErrMsg, SkipPointers ) ELSE OutputData%c_obj%wrtOutput_Len = SIZE(OutputData%wrtOutput) IF (OutputData%c_obj%wrtOutput_Len > 0) & - OutputData%c_obj%wrtOutput = C_LOC( OutputData%wrtOutput( LBOUND(OutputData%wrtOutput,1) ) ) + OutputData%c_obj%wrtOutput = C_LOC( OutputData%wrtOutput( LBOUND(OutputData%wrtOutput,1) ) ) END IF END IF END SUBROUTINE MAP_F2C_CopyOutput diff --git a/modules/map/src/lineroutines.h b/modules/map/src/lineroutines.h index d34e9ae4c..26b28835c 100644 --- a/modules/map/src/lineroutines.h +++ b/modules/map/src/lineroutines.h @@ -96,7 +96,7 @@ MAP_ERROR_CODE increment_the_dof_by_delta(MAP_InputType_t* u_type, const Vessel* MAP_ERROR_CODE increment_psi_dof_by_delta(MAP_InputType_t* u_type, const Vessel* vessel, const double delta, const int size); -MAP_ERROR_CODE f_op_sequence(MAP_OtherStateType_t* other_type, MAP_ParameterType_t* p_type, MAP_InputType_t* u_type, MAP_OutputType_t* y_type, MAP_ConstraintStateType_t* z_type, Fd* force, int size, char* map_msg, MAP_ERROR_CODE* ierr); +MAP_ERROR_CODE f_op_sequence(MAP_OtherStateType_t* other_type, MAP_ParameterType_t* p_type, MAP_InputType_t* u_type, MAP_OutputType_t* y_type, MAP_ConstraintStateType_t* z_type, Fd* force, const int size, char* map_msg, MAP_ERROR_CODE* ierr); MAP_ERROR_CODE fd_x_sequence(MAP_OtherStateType_t* other_type, MAP_ParameterType_t* p_type, MAP_InputType_t* u_type, MAP_OutputType_t* y_type, MAP_ConstraintStateType_t* z_type, Fd* force, const double epsilon, const int size, const double* original_pos, char* map_msg, MAP_ERROR_CODE* ierr); MAP_ERROR_CODE fd_y_sequence(MAP_OtherStateType_t* other_type, MAP_ParameterType_t* p_type, MAP_InputType_t* u_type, MAP_OutputType_t* y_type, MAP_ConstraintStateType_t* z_type, Fd* force, const double epsilon, const int size, const double* original_pos, char* map_msg, MAP_ERROR_CODE* ierr); MAP_ERROR_CODE fd_z_sequence(MAP_OtherStateType_t* other_type, MAP_ParameterType_t* p_type, MAP_InputType_t* u_type, MAP_OutputType_t* y_type, MAP_ConstraintStateType_t* z_type, Fd* force, const double epsilon, const int size, const double* original_pos, char* map_msg, MAP_ERROR_CODE* ierr); diff --git a/modules/map/src/mapinit.c b/modules/map/src/mapinit.c index 4def89c44..3afe39f3a 100644 --- a/modules/map/src/mapinit.c +++ b/modules/map/src/mapinit.c @@ -1777,7 +1777,7 @@ MAP_ERROR_CODE allocate_types_for_nodes(MAP_InputType_t* u_type, MAP_ConstraintS while (i_parsedqty-1) { /* iterating through all strings */ if (parsed->entry[i_parsed]->slen) { /* if the string length is not 0 */ if (next==1) { - if (biseqcstrcaseless(parsed->entry[i_parsed],"FIX")) { + if (biseqcstrcaseless(parsed->entry[i_parsed],"FIX") || biseqcstrcaseless(parsed->entry[i_parsed],"FIXED")) { fix_num++; break; /* break the while-loop because the agenda is reached */ } else if (biseqcstrcaseless(parsed->entry[i_parsed],"CONNECT")) { @@ -1898,7 +1898,7 @@ MAP_ERROR_CODE set_node_list(const MAP_ParameterType_t* p_type, MAP_InputType_t if (next==0) { next++; } else if (next==1) { - if (biseqcstrcaseless(parsed->entry[i_parsed],"FIX")) { + if (biseqcstrcaseless(parsed->entry[i_parsed],"FIX") || biseqcstrcaseless(parsed->entry[i_parsed],"FIXED")) { node_iter->type = FIX; fix_num++; /* VarTypePtr FAST derived array index */ success = associate_vartype_ptr(&node_iter->position_ptr.x, other_type->x, fix_num); diff --git a/modules/moordyn/CMakeLists.txt b/modules/moordyn/CMakeLists.txt index 18f66807b..ec15a3f32 100644 --- a/modules/moordyn/CMakeLists.txt +++ b/modules/moordyn/CMakeLists.txt @@ -18,26 +18,37 @@ if (GENERATE_TYPES) generate_f90_types(src/MoorDyn_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/MoorDyn_Types.f90) endif() -set(MOORDYN_LIBS_SOURCES +add_library(moordynlib src/MoorDyn.f90 + src/MoorDyn_Body.f90 src/MoorDyn_IO.f90 + src/MoorDyn_Line.f90 + src/MoorDyn_Misc.f90 + src/MoorDyn_Point.f90 + src/MoorDyn_Rod.f90 src/MoorDyn_Types.f90 ) +target_link_libraries(moordynlib nwtclibs) -add_library(moordynlib ${MOORDYN_LIBS_SOURCES}) -target_link_libraries(moordynlib nwtclibs versioninfolib) - -install(TARGETS moordynlib - EXPORT "${CMAKE_PROJECT_NAME}Libraries" - RUNTIME DESTINATION lib - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) +# Driver +add_executable(moordyn_driver + src/MoorDyn_Driver.f90 +) +target_link_libraries(moordyn_driver moordynlib versioninfolib) -set(MD_DRIVER_SOURCES src/MoorDyn_Driver.f90) -add_executable(moordyn_driver ${MD_DRIVER_SOURCES}) -target_link_libraries(moordyn_driver moordynlib nwtclibs ${CMAKE_DL_LIBS}) +# C-bindings interface library +add_library(moordyn_c_binding SHARED + src/MoorDyn_C_Binding.f90 +) +target_link_libraries(moordyn_c_binding moordynlib versioninfolib) +if(APPLE OR UNIX) + target_compile_definitions(moordyn_c_binding PRIVATE IMPLICIT_DLLEXPORT) +endif() -install(TARGETS moordyn_driver +install(TARGETS moordynlib moordyn_driver moordyn_c_binding + EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) +) + diff --git a/modules/moordyn/README.md b/modules/moordyn/README.md index af24791e5..8a7aaeff0 100644 --- a/modules/moordyn/README.md +++ b/modules/moordyn/README.md @@ -3,9 +3,6 @@ This is an externally developed module with further information available on the developer's documentation site: [Matt Hall](http://www.matt-hall.ca/moordyn.html). -The legacy version of FAST's information regarding this module -are available at the [NWTC Software Portal](https://nwtc.nrel.gov/MoorDyn/). - ## Overview MoorDyn is a lumped-mass mooring line model for simulating the dynamics of moorings connected to floating offshore structures. It accounts for internal diff --git a/modules/moordyn/python-lib/moordyn_library.py b/modules/moordyn/python-lib/moordyn_library.py new file mode 100644 index 000000000..7078afa4f --- /dev/null +++ b/modules/moordyn/python-lib/moordyn_library.py @@ -0,0 +1,412 @@ +#********************************************************************************************************************************** +# LICENSING +# Copyright (C) 2021 National Renewable Energy Laboratory +# Author: Nicole Mendoza +# +# This file is part of MoorDyn. +# +# 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 is the Python-C interface library for MoorDyn +# Usage: THIS LIBRARY IS NOT TO BE CHANGED OR EDITED BY THE USER +from ctypes import ( + CDLL, + POINTER, + create_string_buffer, + byref, + c_byte, + c_int, + c_double, + c_float, + c_char, + c_char_p, + c_bool +) +import numpy as np +import datetime + +class MoorDynLib(CDLL): + + # Human readable error levels + error_levels = { + 0: "None", + 1: "Info", + 2: "Warning", + 3: "Severe Error", + 4: "Fatal Error" + } + + # NOTE: the error message length in Fortran is controlled by the + # ErrMsgLen variable in the NWTC_Base.f90 file. If that ever + # changes, it may be necessary to update the corresponding size + # here. + error_msg_c_len = 1025 + + # NOTE: the length of the name used for any output file written by the + # HD Fortran code is 1025. + default_str_c_len = 1025 + + def __init__(self, library_path): + super().__init__(library_path) + self.library_path = library_path + + self._initialize_routines() + + # Create buffers for class data + self.abort_error_level = 4 + self.error_status_c = c_int(0) + self.error_message_c = create_string_buffer(self.error_msg_c_len) + self.error_message = create_string_buffer(1025) + self.ended = False # For error handling at end + + self._channel_names = create_string_buffer(256*1000) + self._channel_units = create_string_buffer(256*1000) + + self.dt = c_double(0) + self.total_time = c_double(0) + self.numTimeSteps = c_int(0) + + # Initialize routines ------------------------------------------------------------------------------------------------------------ + def _initialize_routines(self): + self.MD_C_Init.argtypes = [ + POINTER(c_char_p), # IN: input file string + POINTER(c_int), # IN: input file string length + POINTER(c_double), # IN: dt + POINTER(c_float), # IN: g + POINTER(c_float), # IN: rho_water + POINTER(c_float), # IN: depth_water + POINTER(c_float), # IN: platform initial position + POINTER(c_int), # IN: interpolation order + POINTER(c_int), # OUT: number of channels + POINTER(c_char), # OUT: output channel names + POINTER(c_char), # OUT: output channel units + POINTER(c_int), # OUT: ErrStat_C + POINTER(c_char) # OUT: ErrMsg_C + ] + self.MD_C_Init.restype = c_int + + self.MD_C_CalcOutput.argtypes = [ + POINTER(c_double), # IN: Time @ n + POINTER(c_float), # IN: Positions -- node positions (1 x 6 array) + POINTER(c_float), # IN: Velocities -- node velocities (1 x 6 array) + POINTER(c_float), # IN: Accelerations -- node accelerations (1 x 6 array) + POINTER(c_float), # OUT: Forces (3 forces and 3 moments) + POINTER(c_float), # OUT: Output Channel Values + POINTER(c_int), # OUT: ErrStat_C + POINTER(c_char) # OUT: ErrMsg_C + ] + self.MD_C_CalcOutput.restype = c_int + + self.MD_C_UpdateStates.argtypes = [ + POINTER(c_double), # IN: time @ n + POINTER(c_double), # IN: time @ n+1 + POINTER(c_float), # IN: Positions -- node positions (1 x 6 array) + POINTER(c_float), # IN: Velocities -- node velocities (1 x 6 array) + POINTER(c_float), # IN: Accelerations -- node accelerations (1 x 6 array) + POINTER(c_int), # OUT: ErrStat_C + POINTER(c_char) # OUT: ErrMsg_C + ] + self.MD_C_UpdateStates.restype = c_int + + self.MD_C_End.argtypes = [ + POINTER(c_int), # OUT: ErrStat_C + POINTER(c_char) # OUT: ErrMsg_C + ] + self.MD_C_End.restype = c_int + + # md_init ------------------------------------------------------------------------------------------------------------ + def md_init(self, input_string_array, g, rho_water, depth_water, platform_init_pos, interpOrder): + + # Convert the string into a c_char byte array + input_string = '\x00'.join(input_string_array) + input_string = input_string.encode('utf-8') + input_string_length = len(input_string) + + # Convert the initial positions array into c_float array + init_positions_c = (c_float * 6)(0.0, ) + for i, p in enumerate(platform_init_pos): + init_positions_c[i] = c_float(p) + + self._numChannels = c_int(0) + + self.MD_C_Init( + c_char_p(input_string), # IN: input file string + byref(c_int(input_string_length)), # IN: input file string length + byref(c_double(self.dt)), # IN: time step (dt) + byref(c_float(g)), # IN: g + byref(c_float(rho_water)), # IN: rho_water + byref(c_float(depth_water)), # IN: depth_water + init_positions_c, # IN: platform initial position + byref(c_int(interpOrder)), # IN: interpolation order + byref(self._numChannels), # OUT: number of channels + self._channel_names, # OUT: output channel names + self._channel_units, # OUT: output channel units + byref(self.error_status_c), # OUT: ErrStat_C + self.error_message_c # OUT: ErrMsg_C + ) + + self.check_error() + + # md_calcOutput ------------------------------------------------------------------------------------------------------------ + def md_calcOutput(self, t, positions, velocities, accelerations, forces, output_channel_values): + + positions_c = (c_float * 6)(0.0,) + for i, p in enumerate(positions): + positions_c[i] = c_float(p) + + velocities_c = (c_float * 6)(0.0,) + for i, p in enumerate(velocities): + velocities_c[i] = c_float(p) + + accelerations_c = (c_float * 6)(0.0,) + for i, p in enumerate(accelerations): + accelerations_c[i] = c_float(p) + + forces_c = (c_float * 6)(0.0,) + for i, p in enumerate(forces): + forces_c[i] = c_float(p) + + outputs_c = (c_float * self._numChannels.value)(0.0,) + for i, p in enumerate(output_channel_values): + outputs_c[i] = c_float(p) + + self.MD_C_CalcOutput( + byref(c_double(t)), # IN: time + positions_c, # IN: positions + velocities_c, # IN: velocities + accelerations_c, # IN: accelerations + forces_c, # OUT: forces + outputs_c, # OUT: output channel values + byref(self.error_status_c), # OUT: ErrStat_C + self.error_message_c # OUT: ErrMsg_C + ) + + for i in range(0,len(forces_c)): + forces[i] = c_float(forces_c[i]).value + + for i in range(0,len(outputs_c)): + output_channel_values[i] = c_float(outputs_c[i]).value + + self.check_error() + + # md_updateStates ------------------------------------------------------------------------------------------------------------ + def md_updateStates(self, t1, t2, positions, velocities, accelerations): + + positions_c = (c_float * 6)(0.0,) + for i, p in enumerate(positions): + positions_c[i] = c_float(p) + + velocities_c = (c_float * 6)(0.0,) + for i, p in enumerate(velocities): + velocities_c[i] = c_float(p) + + accelerations_c = (c_float * 6)(0.0,) + for i, p in enumerate(accelerations): + accelerations_c[i] = c_float(p) + + self.MD_C_UpdateStates( + byref(c_double(t1)), # IN: current time (t) + byref(c_double(t2)), # IN: next time step (t+1) + positions_c, # IN: positions + velocities_c, # IN: velocities + accelerations_c, # IN: accelerations + byref(self.error_status_c), # OUT: ErrStat_C + self.error_message_c # OUT: ErrMsg_C + ) + + self.check_error() + + # md_end ------------------------------------------------------------------------------------------------------------ + def md_end(self): + + if not self.ended: + self.ended = True + self.MD_C_End( + byref(self.error_status_c), # OUT: ErrStat_C + self.error_message_c # OUT: ErrMsg_C + ) + self.check_error() + + #=============================================================================== + # OTHER FUNCTIONS -------------------------------------------------------------------------------------------------- + + # Error Handling Functions + def check_error(self): + if self.error_status_c.value == 0: + return + elif self.error_status_c.value < self.abort_error_level: + print(f"MoorDyn error status: {self.error_levels[self.error_status_c.value]}: {self.error_message_c.value.decode('ascii')}") + else: + print(f"MoorDyn error status: {self.error_levels[self.error_status_c.value]}: {self.error_message_c.value.decode('ascii')}") + self.md_end() + raise Exception("\nMoorDyn terminated prematurely.") + + # Output Channel Functions + @property + def output_channel_names(self): + if len(self._channel_names.value.split()) == 0: + return [] + output_channel_names = self._channel_names.value.split() + output_channel_names = [n.decode('UTF-8') for n in output_channel_names] + return output_channel_names + + @property + def output_channel_units(self): + if len(self._channel_units.value.split()) == 0: + return [] + output_channel_units = self._channel_units.value.split() + output_channel_units = [n.decode('UTF-8') for n in output_channel_units] + return output_channel_units + +#=============================================================================== +# Helper class for writing output channels to file. +# For the regression testing to mirror the output from the InfowWind Fortran +# driver. This may also have value for debugging the interfacing to MD. + +class WriteOutChans(): + """ + This is only for testing purposes. Since we are not returning the + output channels to anything, we will write them to file. When coupled to + another code, this data would be passed back for inclusion the any output + file there. + """ + def __init__(self,filename,chan_names,chan_units): + chan_names.insert(0,'Time') # add time index header + chan_units.insert(0,'(s)') # add time index unit + self.OutFile=open(filename,'wt') # open output file and write header info + # write file header + t_string=datetime.datetime.now() + dt_string=datetime.date.today() + self.OutFile.write(f"## This file was generated by MoorDyn c-bindings library on {dt_string.strftime('%b-%d-%Y')} at {t_string.strftime('%H:%M:%S')}\n") + self.OutFile.write(f"## This file contains output channels requested from the OutList section of the input file") + self.OutFile.write(f"{filename}\n") + self.OutFile.write("#\n") + self.OutFile.write("#\n") + self.OutFile.write("#\n") + self.OutFile.write("#\n") + l = len(chan_names) + f_string = "{:^15s}"+" {:^20s} "*(l-1) + self.OutFile.write(f_string.format(*chan_names) + '\n') + self.OutFile.write(f_string.format(*chan_units) + '\n') + self.opened = True + + def write(self,chan_data): + l = chan_data.shape[1] + f_string = "{:10.4f}"+"{:25.7f}"*(l-1) + for i in range(0,chan_data.shape[0]): + self.OutFile.write(f_string.format(*chan_data[i,:]) + '\n') + #if i==0: + # print(f"{chan_data[i,:]}") + + def end(self): + if self.opened: + self.OutFile.close() + self.opened = False + +#=============================================================================== +# Helper class for debugging the interface. This will write out all the +# input position/orientation, velocities, accelerations, and the resulting +# forces and moments at each input node. If all is functioning correctly, +# this will be identical to the corresponding values in the MoorDyn output +# channels. + +class DriverDbg(): + """ + This is only for debugging purposes only. The input motions and resulting + forces can be written to file with this class to verify the data I/O to the + Fortran library. When coupled to another code, the force/moment array would + be passed back to the calling code for use in the structural solver. + """ + def __init__(self,filename): + self.DbgFile=open(filename,'wt') # open output file and write header info + self.numNodePts=1 + # write file header + t_string=datetime.datetime.now() + dt_string=datetime.date.today() + self.DbgFile.write(f"## This file was generated by moordyn_c_lib on {dt_string.strftime('%b-%d-%Y')} at {t_string.strftime('%H:%M:%S')}\n") + self.DbgFile.write(f"## This file contains the resulting forces/moments on the substructure passed into the moordyn_c_lib\n") + self.DbgFile.write("#\n") + f_string = "{:^25s}" + self.DbgFile.write("# T ") + for i in range(1,2): + f_num = "N{0:04d}_".format(i) + self.DbgFile.write(f_string.format(f_num+"x" )) + self.DbgFile.write(f_string.format(f_num+"y" )) + self.DbgFile.write(f_string.format(f_num+"z" )) + self.DbgFile.write(f_string.format(f_num+"Rx" )) + self.DbgFile.write(f_string.format(f_num+"Ry" )) + self.DbgFile.write(f_string.format(f_num+"Rz" )) + self.DbgFile.write(f_string.format(f_num+"Vx" )) + self.DbgFile.write(f_string.format(f_num+"Vy" )) + self.DbgFile.write(f_string.format(f_num+"Vz" )) + self.DbgFile.write(f_string.format(f_num+"RVx")) + self.DbgFile.write(f_string.format(f_num+"RVy")) + self.DbgFile.write(f_string.format(f_num+"RVz")) + self.DbgFile.write(f_string.format(f_num+"Ax" )) + self.DbgFile.write(f_string.format(f_num+"Ay" )) + self.DbgFile.write(f_string.format(f_num+"Az" )) + self.DbgFile.write(f_string.format(f_num+"RAx")) + self.DbgFile.write(f_string.format(f_num+"RAy")) + self.DbgFile.write(f_string.format(f_num+"RAz")) + self.DbgFile.write(f_string.format(f_num+"Fx" )) + self.DbgFile.write(f_string.format(f_num+"Fy" )) + self.DbgFile.write(f_string.format(f_num+"Fz" )) + self.DbgFile.write(f_string.format(f_num+"Mx" )) + self.DbgFile.write(f_string.format(f_num+"My" )) + self.DbgFile.write(f_string.format(f_num+"Mz" )) + self.DbgFile.write("\n") + self.DbgFile.write("# (s) ") + for i in range(1,2): + self.DbgFile.write(f_string.format("(m)" )) + self.DbgFile.write(f_string.format("(m)" )) + self.DbgFile.write(f_string.format("(m)" )) + self.DbgFile.write(f_string.format("(rad)" )) + self.DbgFile.write(f_string.format("(rad)" )) + self.DbgFile.write(f_string.format("(rad)" )) + self.DbgFile.write(f_string.format("(m/s)" )) + self.DbgFile.write(f_string.format("(m/s)" )) + self.DbgFile.write(f_string.format("(m/s)" )) + self.DbgFile.write(f_string.format("(rad/s)" )) + self.DbgFile.write(f_string.format("(rad/s)" )) + self.DbgFile.write(f_string.format("(rad/s)" )) + self.DbgFile.write(f_string.format("(m/s^2)" )) + self.DbgFile.write(f_string.format("(m/s^2)" )) + self.DbgFile.write(f_string.format("(m/s^2)" )) + self.DbgFile.write(f_string.format("(rad/s^2)")) + self.DbgFile.write(f_string.format("(rad/s^2)")) + self.DbgFile.write(f_string.format("(rad/s^2)")) + self.DbgFile.write(f_string.format("(N)" )) + self.DbgFile.write(f_string.format("(N)" )) + self.DbgFile.write(f_string.format("(N)" )) + self.DbgFile.write(f_string.format("(N-m)" )) + self.DbgFile.write(f_string.format("(N-m)" )) + self.DbgFile.write(f_string.format("(N-m)" )) + self.DbgFile.write("\n") + self.opened = True + + def write(self,t,Positions,Velocities,Accelerations,Forces): + t_string = "{:10.4f}" + f_string = "{:25.7f}"*6 + self.DbgFile.write(t_string.format(t)) + self.DbgFile.write(f_string.format(*Positions[:])) + self.DbgFile.write(f_string.format(*Velocities[:])) + self.DbgFile.write(f_string.format(*Accelerations[:])) + self.DbgFile.write(f_string.format(*Forces[:])) + self.DbgFile.write("\n") + + def end(self): + if self.opened: + self.DbgFile.close() + self.opened = False diff --git a/modules/moordyn/src/MoorDyn.f90 b/modules/moordyn/src/MoorDyn.f90 index 23d8854ef..bbd5fc932 100644 --- a/modules/moordyn/src/MoorDyn.f90 +++ b/modules/moordyn/src/MoorDyn.f90 @@ -1,6 +1,7 @@ !********************************************************************************************************************************** ! LICENSING -! Copyright (C) 2015 Matthew Hall +! Copyright (C) 2020-2021 Alliance for Sustainable Energy, LLC +! Copyright (C) 2015-2019 Matthew Hall ! ! This file is part of MoorDyn. ! @@ -22,19 +23,32 @@ MODULE MoorDyn USE MoorDyn_Types USE MoorDyn_IO USE NWTC_Library + USE MoorDyn_Line + USE MoorDyn_Point + USE MoorDyn_Rod + USE MoorDyn_Body + USE MoorDyn_Misc + + !USE WAVES, only: WaveGrid_n, WaveGrid_x0, WaveGrid_dx, WaveGrid_nx, WaveGrid_y0, WaveGrid_dy, WaveGrid_ny, WaveGrid_nz ! seeing if I can get waves data here directly... IMPLICIT NONE PRIVATE - TYPE(ProgDesc), PARAMETER :: MD_ProgDesc = ProgDesc( 'MoorDyn', '', '' ) + TYPE(ProgDesc), PARAMETER :: MD_ProgDesc = ProgDesc( 'MoorDyn', 'v2.0.0', '2022-12-08' ) + INTEGER(IntKi), PARAMETER :: wordy = 0 ! verbosity level. >1 = more console output PUBLIC :: MD_Init PUBLIC :: MD_UpdateStates PUBLIC :: MD_CalcOutput PUBLIC :: MD_CalcContStateDeriv PUBLIC :: MD_End + PUBLIC :: MD_JacobianPContState + PUBLIC :: MD_JacobianPInput + PUBLIC :: MD_JacobianPDiscState + PUBLIC :: MD_JacobianPConstrState + PUBLIC :: MD_GetOP CONTAINS @@ -43,7 +57,7 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er IMPLICIT NONE - TYPE(MD_InitInputType), INTENT(INOUT) :: InitInp ! INTENT(INOUT) : Input data for initialization routine + TYPE(MD_InitInputType), INTENT(IN ) :: InitInp ! INTENT(INOUT) : Input data for initialization routine TYPE(MD_InputType), INTENT( OUT) :: u ! INTENT( OUT) : An initial guess for the input; input mesh must be defined TYPE(MD_ParameterType), INTENT( OUT) :: p ! INTENT( OUT) : Parameters TYPE(MD_ContinuousStateType), INTENT( OUT) :: x ! INTENT( OUT) : Initial continuous states @@ -53,32 +67,94 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er TYPE(MD_OutputType), INTENT( OUT) :: y ! INTENT( OUT) : Initial system outputs (outputs are not calculated; only the output mesh is initialized) TYPE(MD_MiscVarType), INTENT( OUT) :: m ! INTENT( OUT) : Initial misc/optimization variables REAL(DbKi), INTENT(INOUT) :: DTcoupling ! Coupling interval in seconds: the rate that Output is the actual coupling interval - TYPE(MD_InitOutputType), INTENT(INOUT) :: InitOut ! Output for initialization routine + TYPE(MD_InitOutputType), INTENT( OUT) :: InitOut ! Output for initialization routine INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! local variables + TYPE(MD_InputFileType) :: InputFileDat ! Data read from input file for setup, but not stored after Init + type(FileInfoType) :: FileInfo_In !< The derived type for holding the full input file for parsing -- we may pass this in the future + ! CHARACTER(1024) :: priPath ! The path to the primary MoorDyn input file REAL(DbKi) :: t ! instantaneous time, to be used during IC generation - INTEGER(IntKi) :: I ! index + INTEGER(IntKi) :: l ! index + INTEGER(IntKi) :: I ! Current line number of input file INTEGER(IntKi) :: J ! index INTEGER(IntKi) :: K ! index + INTEGER(IntKi) :: Itemp ! index + INTEGER(IntKi) :: iTurb ! index for turbine in FAST.Farm applications 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(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 + REAL(ReKi) :: rPos(3) ! array for setting fairlead reference positions in mesh + REAL(ReKi) :: OrMat(3,3) ! rotation matrix for setting fairlead positions correctly if there is initial platform rotation + REAL(ReKi) :: OrMat2(3,3) + REAL(R8Ki) :: OrMatRef(3,3) + REAL(DbKi), ALLOCATABLE :: FairTensIC(:,:)! array of size nCpldCons, 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 - TYPE(MD_InputType) :: uArray(1) ! a size-one array for u to make call to TimeStep happy - REAL(DbKi) :: utimes(1) ! a size-one array saying time is 0 to make call to TimeStep happy + REAL(DbKi) :: dtM ! actual mooring dynamics time step + INTEGER(IntKi) :: NdtM ! number of time steps to integrate through with RK2 + INTEGER(IntKi) :: ntWave ! number of time steps of wave data + + TYPE(MD_InputType) :: u_array(1) ! a size-one array for u to make call to TimeStep happy + REAL(DbKi) :: t_array(1) ! a size-one array saying time is 0 to make call to TimeStep happy + TYPE(MD_InputType) :: u_interp ! interpolated instantaneous input values to be calculated for each mooring time step + + CHARACTER(MaxWrScrLen) :: Message + + ! Local variables for reading file input (Previously in MDIO_ReadInput) + INTEGER(IntKi) :: UnEc ! The local unit number for this module's echo file + INTEGER(IntKi) :: UnOut ! for outputing wave kinematics data + CHARACTER(200) :: Frmt ! a string to hold a format statement + + CHARACTER(1024) :: EchoFile ! Name of MoorDyn echo file + CHARACTER(1024) :: Line ! String to temporarially hold value of read line + CHARACTER(20) :: LineOutString ! String to temporarially hold characters specifying line output options + CHARACTER(20) :: OptString ! String to temporarially hold name of option variable + CHARACTER(40) :: OptValue ! String to temporarially hold value of options variable input + CHARACTER(40) :: DepthValue ! Temporarily stores the optional WtrDpth setting for MD, which could be a number or a filename + CHARACTER(40) :: WaterKinValue ! Temporarily stores the optional WaterKin setting for MD, which is typically a filename + INTEGER(IntKi) :: nOpts ! number of options lines in input file + CHARACTER(40) :: TempString1 ! + CHARACTER(40) :: TempString2 ! + CHARACTER(40) :: TempString3 ! + CHARACTER(40) :: TempString4 ! + CHARACTER(40) :: TempString5 ! + CHARACTER(40) :: TempStrings(6) ! Array of 6 strings used when parsing comma-separated items + CHARACTER(1024) :: FileName ! + + REAL(DbKi) :: depth ! local water depth interpolated from bathymetry grid [m] + Real(DbKi) :: nvec(3) ! local seabed surface normal vector (positive out) + + + CHARACTER(25) :: let1 ! strings used for splitting and parsing identifiers + CHARACTER(25) :: num1 + CHARACTER(25) :: let2 + CHARACTER(25) :: num2 + CHARACTER(25) :: let3 + + REAL(DbKi) :: tempArray(6) + REAL(ReKi) :: rRef(6) ! used to pass positions to mesh (real type precision) + REAL(DbKi) :: rRefDub(3) + + INTEGER(IntKi) :: TempIDnums(100) ! array to hold IdNums of controlled lines for each CtrlChan + + ! for reading output channels + CHARACTER(ChanLen),ALLOCATABLE :: OutList(:) ! array of output channel request (moved here from InitInput) + INTEGER :: MaxAryLen = 1000 ! Maximum length of the array being read + INTEGER :: NumWords ! Number of words contained on a line + INTEGER :: Nx + INTEGER :: QuoteCh ! Character position. + CHARACTER(*), PARAMETER :: RoutineName = 'MD_Init' + ErrStat = ErrID_None ErrMsg = "" + m%zeros6 = 0.0_DbKi ! Initialize the NWTC Subroutine Library CALL NWTC_Init( ) @@ -87,422 +163,2080 @@ SUBROUTINE MD_Init(InitInp, u, p, x, xd, z, other, y, m, DTcoupling, InitOut, Er CALL DispNVD( MD_ProgDesc ) InitOut%Ver = MD_ProgDesc + CALL WrScr(' This is MoorDyn v2, with significant input file changes from v1.') + CALL WrScr(' Copyright: (C) 2022 National Renewable Energy Laboratory, (C) 2019 Matt Hall') + !--------------------------------------------------------------------------------------------- ! Get all the inputs taken care of !--------------------------------------------------------------------------------------------- - - ! set environmental parameters from input data and error check - ! (should remove these values as options from MoorDyn input file for consistency?) - - p%g = InitInp%g - p%WtrDpth = InitInp%WtrDepth - p%rhoW = InitInp%rhoW - p%RootName = TRIM(InitInp%RootName)//'.MD' ! all files written from this module will have this root name + ! set default values for the simulation settings + ! these defaults are based on the glue code + p%dtM0 = DTcoupling ! default to the coupling interval (but will likely need to be smaller) + p%Tmax = InitInp%Tmax + p%g = InitInp%g + p%rhoW = InitInp%rhoW + ! TODO: add MSL2SWL from OpenFAST <<<< + ! set the following to some defaults + p%kBot = 3.0E6 + p%cBot = 3.0E5 + InputFileDat%dtIC = 2.0_DbKi + InputFileDat%TMaxIC = 60.0_DbKi + InputFileDat%CdScaleIC = 4.0_ReKi + InputFileDat%threshIC = 0.01_ReKi + p%WaveKin = 0_IntKi + p%Current = 0_IntKi + p%dtOut = 0.0_DbKi + p%mu_kT = 0.0_DbKi + p%mu_kA = 0.0_DbKi + p%mc = 1.0_DbKi + p%cv = 200.0_DbKi + DepthValue = "" ! Start off as empty string, to only be filled if MD setting is specified (otherwise InitInp%WtrDepth is used) + ! DepthValue and InitInp%WtrDepth are processed later by setupBathymetry. + WaterKinValue = "" + + m%PtfmInit = InitInp%PtfmInit(:,1) ! is this copying necssary in case this is an individual instance in FAST.Farm? - ! call function that reads input file and creates cross-referenced Connect and Line objects - CALL MDIO_ReadInput(InitInp, p, m, ErrStat2, ErrMsg2) - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN - - ! process the OutList array and set up the index arrays for the requested output quantities - CALL MDIO_ProcessOutList(InitInp%OutList, p, m, y, InitOut, ErrStat2, ErrMsg2 ) - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN - !------------------------------------------------------------------------------------------------- - ! Connect mooring system together and make necessary allocations - !------------------------------------------------------------------------------------------------- + ! Check if this MoorDyn instance is being run from FAST.Farm (indicated by FarmSize > 0) + if (InitInp%FarmSize > 0) then + CALL WrScr(' >>> MoorDyn is running in array mode <<< ') + ! could make sure the size of this is right: SIZE(InitInp%FarmCoupledKinematics) + p%nTurbines = InitInp%FarmSize + else ! FarmSize==0 indicates normal, FAST module mode + p%nTurbines = 1 ! if a regular FAST module mode, we treat it like a nTurbine=1 farm case + END IF - CALL WrNR( ' Creating mooring system. ' ) + ! allocate some parameter arrays that are for each turbine (size 1 if regular OpenFAST use) + allocate( p%nCpldBodies( p%nTurbines)) + allocate( p%nCpldRods ( p%nTurbines)) + allocate( p%nCpldCons ( p%nTurbines)) + allocate( p%TurbineRefPos(3, p%nTurbines)) + + ! initialize the arrays (to zero, except for passed in farm turbine reference positions) + p%nCpldBodies = 0 + p%nCpldRods = 0 + p%nCpldCons = 0 + + if (InitInp%FarmSize > 0) then + p%TurbineRefPos = InitInp%TurbineRefPos ! copy over turbine reference positions for later use + else + p%TurbineRefPos = 0.0_DbKi ! for now assuming this is zero for FAST use + end if - p%NFairs = 0 ! this is the number of "vessel" type Connections. being consistent with MAP terminology - p%NConns = 0 ! this is the number of "connect" type Connections. not to be confused with NConnects, the number of Connections - p%NAnchs = 0 ! this is the number of "fixed" type Connections. + + !--------------------------------------------------------------------------------------------- + ! read input file and create cross-referenced mooring system objects + !--------------------------------------------------------------------------------------------- + + + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = "" - ! cycle through Connects and identify Connect types - DO I = 1, p%NConnects - - TempString = m%ConnectList(I)%type - CALL Conv2UC(TempString) - if (TempString == 'FIXED') then - m%ConnectList(I)%TypeNum = 0 - p%NAnchs = p%NAnchs + 1 - else if (TempString == 'VESSEL') then - m%ConnectList(I)%TypeNum = 1 - p%NFairs = p%NFairs + 1 ! if a vessel connection, increment fairlead counter - else if (TempString == 'CONNECT') then - m%ConnectList(I)%TypeNum = 2 - p%NConns = p%NConns + 1 - else - CALL CheckError( ErrID_Fatal, 'Error in provided Connect type. Must be fixed, vessel, or connect.' ) - RETURN - END IF - END DO - CALL WrScr(trim(Num2LStr(p%NFairs))//' fairleads, '//trim(Num2LStr(p%NAnchs))//' anchors, '//trim(Num2LStr(p%NConns))//' connects.') + CALL WrScr( ' Parsing MoorDyn input file: '//trim(InitInp%FileName) ) - ! allocate fairleads list - ALLOCATE ( m%FairIdList(p%NFairs), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - CALL CheckError( ErrID_Fatal, 'Error allocating space for FairIdList array.') - RETURN - END IF + ! ----------------------------------------------------------------- + ! Read the primary MoorDyn input file, or copy from passed input + if (InitInp%UsePrimaryInputFile) then + ! Read the entire input file, minus any comment lines, into the FileInfo_In + ! data structure in memory for further processing. + call ProcessComFile( InitInp%FileName, FileInfo_In, ErrStat2, ErrMsg2 ) + CALL GetPath( InitInp%FileName, p%PriPath ) ! Input files will be relative to the path where the primary input file is located. + else + call NWTC_Library_CopyFileInfoType( InitInp%PassedPrimaryInputData, FileInfo_In, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) + p%PriPath = "" + endif + if (Failed()) return; - ! allocate connect list - ALLOCATE ( m%ConnIdList(p%NConns), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - CALL CheckError( ErrID_Fatal, 'Error allocating space for ConnIdList array.') - RETURN - END IF + ! For diagnostic purposes, the following can be used to display the contents + ! of the FileInfo_In data structure. + !call Print_FileInfo_Struct( CU, FileInfo_In ) ! CU is the screen -- different number on different systems. + ! Parse the FileInfo_In structure of data from the inputfile into the InitInp%InputFile structure +! CALL ParsePrimaryFileInfo_BuildModel( PriPath, InitInp, FileInfo_In, InputFileDat, p, m, UnEc, ErrStat2, ErrMsg2 ) +! if (Failed()) return; - ! now go back through and record the fairlead Id numbers (this is all the "connecting" that's required) - J = 1 ! counter for fairlead number - K = 1 ! counter for connect number - DO I = 1,p%NConnects - IF (m%ConnectList(I)%TypeNum == 1) THEN - m%FairIdList(J) = I ! if a vessel connection, add ID to list - J = J + 1 - ELSE IF (m%ConnectList(I)%TypeNum == 2) THEN - m%ConnIdList(K) = I ! if a connect connection, add ID to list - K = K + 1 - END IF - END DO - ! go through lines and allocate variables - DO I = 1, p%NLines - CALL SetupLine( m%LineList(I), m%LineTypeList(m%LineList(I)%PropsIdNum), p%rhoW , ErrStat2, ErrMsg2) - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN - END DO +!NOTE: This could be split into a separate routine for easier to read code + !------------------------------------------------------------------------------------------------- + ! Parsing of input file from the FileInfo_In data structure + ! - FileInfo_Type is essentially a string array with some metadata. + !------------------------------------------------------------------------------------------------- - !------------------------------------------------------------------------------------ - ! prepare state vector - !------------------------------------------------------------------------------------ + UnEc = -1 + nOpts = 0 ! Setting here rather than implied save - ! allocate list of starting state vector indices for each line - does this belong elsewhere? - ALLOCATE ( m%LineStateIndList(p%NLines), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - CALL CheckError(ErrID_Fatal, ' Error allocating LineStateIndList array.') - RETURN - END IF + ! ----------------- go through file contents a first time, counting each entry ----------------------- - ! figure out required size of state vector and how it will be apportioned to Connect and Lines (J is keeping track of the growing size of the state vector) - J = p%NConns*6 ! start index of first line's states (added six state variables for each "connect"-type connection) + i = 0 ! set line number counter to before first line + Line = NextLine(i); ! Get the line and increment counter. See description of routine. + + do while ( i <= FileInfo_In%NumLines ) - DO I = 1, p%NLines - m%LineStateIndList(I) = J+1 ! assign start index of each line - J = J + 6*(m%LineList(I)%N - 1) !add 6 state variables for each internal node - END DO + if (INDEX(Line, "---") > 0) then ! look for a header line + if ( ( INDEX(Line, "LINE DICTIONARY") > 0) .or. ( INDEX(Line, "LINE TYPES") > 0) ) then ! if line dictionary header - ! allocate state vector for RK2 based on size just calculated - ALLOCATE ( x%states(J), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating state vector.' - !CALL CleanUp() - RETURN - END IF + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! find how many elements of this type there are + Line = NextLine(i) + DO while (INDEX(Line, "---") == 0) ! while we DON'T find another header line + p%nLineTypes = p%nLineTypes + 1 + Line = NextLine(i) + END DO + else if ( (INDEX(Line, "ROD DICTIONARY") > 0) .or. ( INDEX(Line, "ROD TYPES") > 0) ) then ! if rod dictionary header - ! get header information for the FAST output file <<< what does this mean? + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! find how many elements of this type there are + Line = NextLine(i) + DO while (INDEX(Line, "---") == 0) ! while we DON'T find another header line + p%nRodTypes = p%nRodTypes + 1 + Line = NextLine(i) + END DO + else if ((INDEX(Line, "BODIES") > 0 ) .or. (INDEX(Line, "BODY LIST") > 0 ) .or. (INDEX(Line, "BODY PROPERTIES") > 0 )) then - !-------------------------------------------------------------------------- - ! create i/o meshes for fairlead positions and forces - !-------------------------------------------------------------------------- + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! find how many elements of this type there are + Line = NextLine(i) + DO while (INDEX(Line, "---") == 0) ! while we DON'T find another header line + p%nBodies = p%nBodies + 1 + Line = NextLine(i) + END DO - ! create input mesh for fairlead kinematics - CALL MeshCreate(BlankMesh=u%PtFairleadDisplacement , & - IOS= COMPONENT_INPUT , & - Nnodes=p%NFairs , & - TranslationDisp=.TRUE. , & - TranslationVel=.TRUE. , & - ErrStat=ErrStat2 , & - ErrMess=ErrMsg2) + else if ((INDEX(Line, "RODS") > 0 ) .or. (INDEX(Line, "ROD LIST") > 0) .or. (INDEX(Line, "ROD PROPERTIES") > 0)) then ! if rod properties header - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! find how many elements of this type there are + Line = NextLine(i) + DO while (INDEX(Line, "---") == 0) ! while we DON'T find another header line + p%nRods = p%nRods + 1 + Line = NextLine(i) + END DO + else if ((INDEX(Line, "POINTS") > 0 ) .or. (INDEX(Line, "CONNECTION PROPERTIES") > 0) .or. (INDEX(Line, "NODE PROPERTIES") > 0) .or. (INDEX(Line, "POINT PROPERTIES") > 0) .or. (INDEX(Line, "POINT LIST") > 0) ) then ! if node properties header - ! --------------------------- set up initial condition of each fairlead ------------------------------- - DO i = 1,p%NFairs + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! find how many elements of this type there are + Line = NextLine(i) + DO while (INDEX(Line, "---") == 0) ! while we DON'T find another header line + p%nConnects = p%nConnects + 1 + Line = NextLine(i) + END DO - Pos(1) = m%ConnectList(m%FairIdList(i))%conX ! set relative position of each fairlead i (I'm pretty sure this is just relative to ptfm origin) - Pos(2) = m%ConnectList(m%FairIdList(i))%conY - Pos(3) = m%ConnectList(m%FairIdList(i))%conZ + else if ((INDEX(Line, "LINES") > 0 ) .or. (INDEX(Line, "LINE PROPERTIES") > 0) .or. (INDEX(Line, "LINE LIST") > 0) ) then ! if line properties header - CALL MeshPositionNode(u%PtFairleadDisplacement,i,Pos,ErrStat2,ErrMsg2)! "assign the coordinates of each node in the global coordinate space" + ! skip following two lines (label line and unit line) + i=i+2 + + ! find how many elements of this type there are + Line = NextLine(i) + DO while (INDEX(Line, "---") == 0) ! while we DON'T find another header line + p%nLines = p%nLines + 1 + Line = NextLine(i) + END DO - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN + else if (INDEX(Line, "CONTROL") > 0) then ! if failure conditions header + IF (wordy > 1) print *, " Reading control channels: "; + + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! find how many elements of this type there are + Line = NextLine(i) + DO while (INDEX(Line, "---") == 0) ! while we DON'T find another header line + p%nCtrlChans = p%nCtrlChans + 1 + Line = NextLine(i) + END DO + + else if (INDEX(Line, "FAILURE") > 0) then ! if failure conditions header - ! set offset position of each node to according to initial platform position - CALL SmllRotTrans('initial fairlead positions due to platform rotation', InitInp%PtfmInit(4),InitInp%PtfmInit(5),InitInp%PtfmInit(6), TransMat, '', ErrStat2, ErrMsg2) ! account for possible platform rotation + IF (wordy > 1) print *, " Reading failure conditions: "; + + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! find how many elements of this type there are + Line = NextLine(i) + DO while (INDEX(Line, "---") == 0) ! while we DON'T find another header line + p%nFails = p%nFails + 1 + Line = NextLine(i) + END DO + + + else if (INDEX(Line, "OPTIONS") > 0) then ! if options header - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN + IF (wordy > 0) print *, "Reading Options" + + ! don't skip any lines (no column headers for the options section) + ! process each line in this section + Line = NextLine(i) + DO while (INDEX(Line, "---") == 0) ! while we DON'T find another header line + + ! parse out entries: value, option keyword + READ(Line,*,IOSTAT=ErrStat2) OptValue, OptString ! look at first two entries, ignore remaining words in line, which should be comments + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Failed to read options.', ErrStat, ErrMsg, RoutineName ) ! would be nice to specify which line had the error + CALL CleanUp() + RETURN + END IF + + CALL Conv2UC(OptString) + + ! check all possible options types and see if OptString is one of them, in which case set the variable. + if ( OptString == 'WRITELOG') THEN + read (OptValue,*) p%writeLog + if (p%writeLog > 0) then ! if not zero, open a log file for output + CALL GetNewUnit( p%UnLog ) + CALL OpenFOutFile ( p%UnLog, TRIM(p%RootName)//'.log', ErrStat, ErrMsg ) + IF ( ErrStat > AbortErrLev ) THEN + ErrMsg = ' Failed to open MoorDyn log file: '//TRIM(ErrMsg) + RETURN + END IF + write(p%UnLog,'(A)', IOSTAT=ErrStat2) "MoorDyn v2 log file with output level "//TRIM(Num2LStr(p%writeLog)) + write(p%UnLog,'(A)', IOSTAT=ErrStat2) "Note: options above the writeLog line in the input file will not be recorded." + end if + else if ( OptString == 'DTM') THEN + read (OptValue,*) p%dtM0 + else if ( OptString == 'G') then + read (OptValue,*) p%g + else if (( OptString == 'RHOW') .or. ( OptString == 'RHO')) then + read (OptValue,*) p%rhoW + else if (( OptString == 'WTRDPTH') .or. ( OptString == 'DEPTH') .or. ( OptString == 'WATERDEPTH')) then + read (OptValue,*) DepthValue ! water depth input read in as a string to be processed by setupBathymetry + else if (( OptString == 'KBOT') .or. ( OptString == 'KB')) then + read (OptValue,*) p%kBot + else if (( OptString == 'CBOT') .or. ( OptString == 'CB')) then + read (OptValue,*) p%cBot + else if ( OptString == 'DTIC') then + read (OptValue,*) InputFileDat%dtIC + else if ( OptString == 'TMAXIC') then + read (OptValue,*) InputFileDat%TMaxIC + else if ( OptString == 'CDSCALEIC') then + read (OptValue,*) InputFileDat%CdScaleIC + else if ( OptString == 'THRESHIC') then + read (OptValue,*) InputFileDat%threshIC + else if ( OptString == 'WATERKIN') then + read (OptValue,*) WaterKinValue + else if ( OptString == 'DTOUT') then + read (OptValue,*) p%dtOut + else if ( OptString == 'MU_KT') then + read (OptValue,*) p%mu_kT + else if ( OptString == 'MU_KA') then + read (OptValue,*) p%mu_kA + else if ( OptString == 'MC') then + read (OptValue,*) p%mc + else if ( OptString == 'CV') then + read (OptValue,*) p%cv + else + CALL SetErrStat( ErrID_Warn, 'Unable to interpret input '//trim(OptString)//' in OPTIONS section.', ErrStat, ErrMsg, RoutineName ) + end if + + nOpts = nOpts + 1 + Line = NextLine(i) + END DO + - ! Apply initial platform rotations and translations (fixed Jun 19, 2015) - u%PtFairleadDisplacement%TranslationDisp(1,i) = InitInp%PtfmInit(1) + Transmat(1,1)*Pos(1) + Transmat(2,1)*Pos(2) + TransMat(3,1)*Pos(3) - Pos(1) - u%PtFairleadDisplacement%TranslationDisp(2,i) = InitInp%PtfmInit(2) + Transmat(1,2)*Pos(1) + Transmat(2,2)*Pos(2) + TransMat(3,2)*Pos(3) - Pos(2) - 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) + else if (INDEX(Line, "OUTPUT") > 0) then ! if output header - ! set velocity of each node to zero - 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) + ! we don't need to count this section... + Line = NextLine(i) - ! set each node as a point element - CALL MeshConstructElement(u%PtFairleadDisplacement, ELEMENT_POINT, ErrStat2, ErrMsg2, i) - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN + else ! otherwise ignore this line that isn't a recognized header line and read the next line + Line = NextLine(i) + end if - END DO ! I + else ! otherwise ignore this line, which doesn't have the "---" or header line and read the next line + Line = NextLine(i) + end if + + end do + p%nConnectsExtra = p%nConnects + 2*p%nLines ! set maximum number of connections, accounting for possible detachment of each line end and a connection for that - CALL MeshCommit ( u%PtFairleadDisplacement, ErrStat, ErrMsg ) + IF (wordy > 0) print *, " Identified ", p%nLineTypes , "LineTypes in input file." + IF (wordy > 0) print *, " Identified ", p%nRodTypes , "RodTypes in input file." + IF (wordy > 0) print *, " Identified ", p%nBodies , "Bodies in input file." + IF (wordy > 0) print *, " Identified ", p%nRods , "Rods in input file." + IF (wordy > 0) print *, " Identified ", p%nConnects , "Connections in input file." + IF (wordy > 0) print *, " Identified ", p%nLines , "Lines in input file." + IF (wordy > 0) print *, " Identified ", nOpts , "Options in input file." - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN + ! set up seabed bathymetry + CALL setupBathymetry(DepthValue, InitInp%WtrDepth, m%BathymetryGrid, m%BathGrid_Xs, m%BathGrid_Ys, ErrStat2, ErrMsg2) + CALL getDepthFromBathymetry(m%BathymetryGrid, m%BathGrid_Xs, m%BathGrid_Ys, 0.0_DbKi, 0.0_DbKi, p%WtrDpth, nvec) ! set depth at 0,0 as nominal for waves etc + + + ! set up wave and current kinematics + CALL setupWaterKin(WaterKinValue, p, InitInp%Tmax, ErrStat2, ErrMsg2); if(Failed()) return - ! copy the input fairlead kinematics mesh to make the output mesh for fairlead loads, PtFairleadLoad - CALL MeshCopy ( SrcMesh = u%PtFairleadDisplacement, DestMesh = y%PtFairleadLoad, & - CtrlCode = MESH_SIBLING, IOS = COMPONENT_OUTPUT, & - Force = .TRUE., ErrStat = ErrStat2, ErrMess=ErrMsg2 ) - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN + ! ----------------------------- misc checks to be sorted ----------------------------- - ! -------------------------------------------------------------------- - ! go through all Connects and set position based on input file - ! -------------------------------------------------------------------- - ! first do it for all connections (connect and anchor types will be saved) - DO I = 1, p%NConnects - 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_DbKi - m%ConnectList(I)%rd(2) = 0.0_DbKi - m%ConnectList(I)%rd(3) = 0.0_DbKi - END DO + ! make sure nLineTypes isn't zero + IF ( p%nLineTypes < 1 ) THEN + CALL SetErrStat( ErrID_Fatal, 'nLineTypes parameter must be greater than zero.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + ! make sure NLines is at least one + IF ( p%NLines < 1 ) THEN + CALL SetErrStat( ErrID_Fatal, 'NLines parameter must be at least 1.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF - ! 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_DbKi - END DO - END DO - ! for connect types, write the coordinates to the state vector - DO I = 1,p%NConns - x%states(6*I-2:6*I) = m%ConnectList(m%ConnIdList(I))%r ! double check order of r vs rd - x%states(6*I-5:6*I-3) = m%ConnectList(m%ConnIdList(I))%rd - END DO + + - ! -------------------------------------------------------------------- - ! open output file(s) and write header lines - CALL MDIO_OpenOutput( InitInp%FileName, p, m, InitOut, ErrStat2, ErrMsg2 ) - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN - ! -------------------------------------------------------------------- + ! ----------------------------- allocate necessary arrays ---------------------------- + ! Allocate object arrays - ! -------------------------------------------------------------------- - ! size active tensioning inputs arrays based on highest channel number read from input file for now <<<<<<< - ! -------------------------------------------------------------------- + ALLOCATE(m%LineTypeList(p%nLineTypes), STAT = ErrStat2 ); if(AllocateFailed("LineTypeList")) return + ALLOCATE(m%RodTypeList( p%nRodTypes ), STAT = ErrStat2 ); if(AllocateFailed("LineTypeList")) return + + ALLOCATE(m%BodyList( p%nBodies ), STAT = ErrStat2 ); if(AllocateFailed("BodyList" )) return + ALLOCATE(m%RodList( p%nRods ), STAT = ErrStat2 ); if(AllocateFailed("RodList" )) return + ALLOCATE(m%ConnectList( p%nConnects ), STAT = ErrStat2 ); if(AllocateFailed("ConnectList" )) return + ALLOCATE(m%LineList( p%nLines ), STAT = ErrStat2 ); if(AllocateFailed("LineList" )) return - ! find the highest channel number - N = 0 - DO I = 1, p%NLines - IF ( m%LineList(I)%CtrlChan > N ) then - N = m%LineList(I)%CtrlChan - END IF - END DO + ALLOCATE(m%FailList( p%nFails ), STAT = ErrStat2 ); if(AllocateFailed("FailList" )) return + - ! allocate the input arrays (if any requested) - if (N > 0) then - call AllocAry( u%DeltaL, N, 'u%DeltaL', ErrStat2, ErrMsg2 ) - call CheckError( ErrStat2, ErrMsg2 ) - if (ErrStat >= AbortErrLev) return - u%DeltaL = 0.0_ReKi - call AllocAry( u%DeltaLdot, N, 'u%DeltaLdot', ErrStat2, ErrMsg2 ) - call CheckError( ErrStat2, ErrMsg2 ) - if (ErrStat >= AbortErrLev) return - u%DeltaLdot = 0.0_ReKi - call AllocAry( InitOut%CableCChanRqst, N, 'CableCChanRqst', ErrStat2, ErrMsg2 ) - call CheckError( ErrStat2, ErrMsg2 ) - if (ErrStat >= AbortErrLev) return - InitOut%CableCChanRqst = .FALSE. ! Initialize to false - do J=1,p%NLines - if (m%LineList(J)%CtrlChan > 0) InitOut%CableCChanRqst(m%LineList(J)%CtrlChan) = .TRUE. - enddo - endif + ! Allocate associated index arrays (note: some are allocated larger than will be used, for simplicity) + ALLOCATE(m%BodyStateIs1(p%nBodies ), m%BodyStateIsN(p%nBodies ), STAT=ErrStat2); if(AllocateFailed("BodyStateIs1/N")) return + ALLOCATE(m%RodStateIs1(p%nRods ), m%RodStateIsN(p%nRods ), STAT=ErrStat2); if(AllocateFailed("RodStateIs1/N" )) return + ALLOCATE(m%ConStateIs1(p%nConnects), m%ConStateIsN(p%nConnects), STAT=ErrStat2); if(AllocateFailed("ConStateIs1/N" )) return + ALLOCATE(m%LineStateIs1(p%nLines) , m%LineStateIsN(p%nLines) , STAT=ErrStat2); if(AllocateFailed("LineStateIs1/N")) return + ALLOCATE(m%FreeBodyIs( p%nBodies ), STAT=ErrStat2); if(AllocateFailed("FreeBodyIs")) return + ALLOCATE(m%FreeRodIs( p%nRods ), STAT=ErrStat2); if(AllocateFailed("FreeRodIs")) return + ALLOCATE(m%FreeConIs( p%nConnects), STAT=ErrStat2); if(AllocateFailed("FreeConnectIs")) return - ! -------------------------------------------------------------------- - ! go through lines and initialize internal node positions using Catenary() - ! -------------------------------------------------------------------- - DO I = 1, p%NLines - - N = m%LineList(I)%N ! for convenience - - !TODO: apply any initial adjustment of line length from active tensioning <<<<<<<<<<<< - ! >>> maybe this should be skipped <<<< - - ! set end node positions and velocities from connect objects - m%LineList(I)%r(:,N) = m%ConnectList(m%LineList(I)%FairConnect)%r - m%LineList(I)%r(:,0) = m%ConnectList(m%LineList(I)%AnchConnect)%r - m%LineList(I)%rd(:,N) = (/ 0.0, 0.0, 0.0 /) ! set anchor end velocities to zero - m%LineList(I)%rd(:,0) = (/ 0.0, 0.0, 0.0 /) ! set fairlead end velocities to zero + ALLOCATE(m%CpldBodyIs(p%nBodies , p%nTurbines), STAT=ErrStat2); if(AllocateFailed("CpldBodyIs")) return + ALLOCATE(m%CpldRodIs( p%nRods , p%nTurbines), STAT=ErrStat2); if(AllocateFailed("CpldRodIs")) return + ALLOCATE(m%CpldConIs(p%nConnects, p%nTurbines), STAT=ErrStat2); if(AllocateFailed("CpldConnectIs")) return - ! set initial line internal node positions using quasi-static model or straight-line interpolation from anchor to fairlead - CALL InitializeLine( m%LineList(I), m%LineTypeList(m%LineList(I)%PropsIdNum), p%rhoW , ErrStat2, ErrMsg2) - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN - IF (ErrStat >= ErrId_Warn) CALL WrScr(" Catenary solver failed for one or more lines. Using linear node spacing.") ! make this statement more accurate - ! assign the resulting internal node positions to the integrator initial state vector! (velocities leave at 0) - 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_DbKi ! assign velocities (of zero) - END DO - END DO + ! ---------------------- now go through again and process file contents -------------------- - END DO !I = 1, p%NLines + call Body_Setup( m%GroundBody, m%zeros6, p, ErrStat2, ErrMsg2) + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + ! note: no longer worrying about "Echo" option + + Nx = 0 ! set state counter to zero + i = 0 ! set line number counter to before first line + Line = NextLine(i) + + do while ( i <= FileInfo_In%NumLines ) + + if (INDEX(Line, "---") > 0) then ! look for a header line + + CALL Conv2UC(Line) ! allow lowercase section header names as well -! ! try writing output for troubleshooting purposes (TEMPORARY) -! CALL MDIO_WriteOutputs(-1.0_DbKi, p, m, y, ErrStat, ErrMsg) -! IF ( ErrStat >= AbortErrLev ) THEN -! ErrMsg = ' Error in MDIO_WriteOutputs: '//TRIM(ErrMsg) -! RETURN -! END IF + !------------------------------------------------------------------------------------------- + if ( ( INDEX(Line, "LINE DICTIONARY") > 0) .or. ( INDEX(Line, "LINE TYPES") > 0) ) then ! if line dictionary header + + IF (wordy > 0) print *, "Reading line types" + + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! process each line + DO l = 1,p%nLineTypes + + !read into a line + Line = NextLine(i) + + ! check for correct number of columns in current line + IF ( CountWords( Line ) /= 10 ) THEN + CALL SetErrStat( ErrID_Fatal, ' Unable to parse Line type '//trim(Num2LStr(l))//' on row '//trim(Num2LStr(i))//' in input file. Row has wrong number of columns. Must be 10 columns.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + ! parse out entries: Name Diam MassDenInAir EA cIntDamp EI Cd Ca CdAx CaAx + READ(Line,*,IOSTAT=ErrStat2) m%LineTypeList(l)%name, m%LineTypeList(l)%d, & + m%LineTypeList(l)%w, tempString1, tempString2, tempString3, & + m%LineTypeList(l)%Cdn, m%LineTypeList(l)%Can, m%LineTypeList(l)%Cdt, m%LineTypeList(l)%Cat + + IF ( ErrStat2 /= ErrID_None ) THEN + CALL SetErrStat( ErrID_Fatal, 'Failed to process line type inputs of entry '//trim(Num2LStr(l))//'. Check formatting and correct number of columns.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + !TODO: add check if %name is maximum length, which might indicate the full name was too long <<< + + ! process stiffness coefficients + CALL SplitByBars(tempString1, N, tempStrings) + if (N > 2) then + CALL SetErrStat( ErrID_Fatal, 'A line type EA entry can have at most 2 (comma-separated) values.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + else if (N==2) then ! visco-elastic case! + m%LineTypeList(l)%ElasticMod = 2 + read(tempStrings(2), *) m%LineTypeList(l)%EA_D + else + m%LineTypeList(l)%ElasticMod = 1 ! normal case + end if + ! get the regular/static coefficient or relation in all cases (can be from a lookup table) + CALL getCoefficientOrCurve(tempStrings(1), m%LineTypeList(l)%EA, & + m%LineTypeList(l)%nEApoints, & + m%LineTypeList(l)%stiffXs, & + m%LineTypeList(l)%stiffYs, ErrStat2, ErrMsg2) + + + ! process damping coefficients + CALL SplitByBars(tempString2, N, tempStrings) + if (N > m%LineTypeList(l)%ElasticMod) then + CALL SetErrStat( ErrID_Fatal, 'A line type BA entry cannot have more (comma-separated) values its EA entry.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + else if (N==2) then ! visco-elastic case when two BA values provided + read(tempStrings(2), *) m%LineTypeList(l)%BA_D + else if (m%LineTypeList(l)%ElasticMod == 2) then ! case where there is no dynamic damping for viscoelastic model (will it work)? + CALL WrScr("Warning, viscoelastic model being used with zero damping on the dynamic stiffness.") + end if + ! get the regular/static coefficient or relation in all cases (can be from a lookup table?) + CALL getCoefficientOrCurve(tempStrings(1), m%LineTypeList(l)%BA, & + m%LineTypeList(l)%nBApoints, & + m%LineTypeList(l)%dampXs, & + m%LineTypeList(l)%dampYs, ErrStat2, ErrMsg2) + + ! process bending stiffness coefficients (which might use lookup tables) + CALL getCoefficientOrCurve(tempString3, m%LineTypeList(l)%EI, & + m%LineTypeList(l)%nEIpoints, & + m%LineTypeList(l)%bstiffXs, & + m%LineTypeList(l)%bstiffYs, ErrStat2, ErrMsg2) + + ! specify IdNum of line type for error checking + m%LineTypeList(l)%IdNum = l + + ! write lineType information to log file + if (p%writeLog > 1) then + write(p%UnLog, '(A12,A20)' ) " LineType"//trim(num2lstr(l))//":" + write(p%UnLog, '(A12,A20)' ) " name: ", m%LineTypeList(l)%name + write(p%UnLog, '(A12,f12.4)') " d : ", m%LineTypeList(l)%d + write(p%UnLog, '(A12,f12.4)') " w : ", m%LineTypeList(l)%w + write(p%UnLog, '(A12,f12.4)') " Cdn : ", m%LineTypeList(l)%Cdn + write(p%UnLog, '(A12,f12.4)') " Can : ", m%LineTypeList(l)%Can + write(p%UnLog, '(A12,f12.4)') " Cdt : ", m%LineTypeList(l)%Cdt + write(p%UnLog, '(A12,f12.4)') " Cat : ", m%LineTypeList(l)%Cat + end if + + IF ( ErrStat2 /= ErrID_None ) THEN + CALL SetErrStat( ErrID_Fatal, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + END DO - ! -------------------------------------------------------------------- - ! do dynamic relaxation to get ICs - ! -------------------------------------------------------------------- - CALL WrScr(" Finalizing ICs using dynamic relaxation."//NewLine) ! newline because next line writes over itself + !------------------------------------------------------------------------------------------- + else if ( (INDEX(Line, "ROD DICTIONARY") > 0) .or. ( INDEX(Line, "ROD TYPES") > 0) ) then ! if rod dictionary header + + IF (wordy > 0) print *, "Reading rod types" + + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! process each line + DO l = 1,p%nRodTypes + + !read into a line + Line = NextLine(i) + + ! check for correct number of columns in current line + IF ( CountWords( Line ) /= 7 ) THEN + CALL SetErrStat( ErrID_Fatal, ' Unable to parse Rod Type '//trim(Num2LStr(l))//' on row '//trim(Num2LStr(i))//' in input file. Row has wrong number of columns. Must be 7 columns.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + ! parse out entries: Name Diam MassDen Cd Ca CdEnd CaEnd + IF (ErrStat2 == 0) THEN + READ(Line,*,IOSTAT=ErrStat2) m%RodTypeList(l)%name, m%RodTypeList(l)%d, m%RodTypeList(l)%w, & + m%RodTypeList(l)%Cdn, m%RodTypeList(l)%Can, m%RodTypeList(l)%CdEnd, m%RodTypeList(l)%CaEnd + + m%RodTypeList(l)%Cdt = 0.0_DbKi ! not used + m%RodTypeList(l)%Cat = 0.0_DbKi ! not used + END IF + + ! specify IdNum of rod type for error checking + m%RodTypeList(l)%IdNum = l + + ! write lineType information to log file + if (p%writeLog > 1) then + write(p%UnLog, '(A12,A20)' ) " RodType"//trim(num2lstr(l))//":" + write(p%UnLog, '(A12,A20)' ) " name: ", m%RodTypeList(l)%name + write(p%UnLog, '(A12,f12.4)') " d : ", m%RodTypeList(l)%d + write(p%UnLog, '(A12,f12.4)') " w : ", m%RodTypeList(l)%w + write(p%UnLog, '(A12,f12.4)') " Cdn : ", m%RodTypeList(l)%Cdn + write(p%UnLog, '(A12,f12.4)') " Can : ", m%RodTypeList(l)%Can + write(p%UnLog, '(A12,f12.4)') " Cdt : ", m%RodTypeList(l)%CdEnd + write(p%UnLog, '(A12,f12.4)') " Cat : ", m%RodTypeList(l)%CaEnd + end if + + IF ( ErrStat2 /= ErrID_None ) THEN + CALL SetErrStat( ErrID_Fatal, 'Failed to process rod type properties for rod '//trim(Num2LStr(l))//'. Check formatting and correct number of columns.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + END DO + + + !------------------------------------------------------------------------------------------- + else if ((INDEX(Line, "BODIES") > 0 ) .or. (INDEX(Line, "BODY LIST") > 0 ) .or. (INDEX(Line, "BODY PROPERTIES") > 0 )) then + + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! process each body + DO l = 1,p%nBodies + + !read into a line + Line = NextLine(i) + + ! check for correct number of columns in current line + IF ( CountWords( Line ) /= 14 ) THEN + CALL SetErrStat( ErrID_Fatal, ' Unable to parse Body '//trim(Num2LStr(l))//' on row '//trim(Num2LStr(i))//' in input file. Row has wrong number of columns. Must be 14 columns.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF - ! boost drag coefficient of each line type - DO I = 1, p%NTypes - m%LineTypeList(I)%Cdn = m%LineTypeList(I)%Cdn * InitInp%CdScaleIC - m%LineTypeList(I)%Cdt = m%LineTypeList(I)%Cdt * InitInp%CdScaleIC - END DO + ! parse out entries: ID Attachment X0 Y0 Z0 r0 p0 y0 M CG* I* V CdA* Ca* + IF (ErrStat2 == 0) THEN + READ(Line,*,IOSTAT=ErrStat2) m%BodyList(l)%IdNum, tempString1, & + tempArray(1), tempArray(2), tempArray(3), tempArray(4), tempArray(5), tempArray(6), & + m%BodyList(l)%bodyM, tempString2, tempString3, m%BodyList(l)%bodyV, tempString4, tempString5 + END IF + + ! process CG + CALL SplitByBars(tempString2, N, tempStrings) + if (N == 1) then ! if only one entry, it is the z coordinate + m%BodyList(l)%rCG(1) = 0.0_DbKi + m%BodyList(l)%rCG(2) = 0.0_DbKi + READ(tempString2, *) m%BodyList(l)%rCG(3) + else if (N==3) then ! all three coordinates provided + READ(tempStrings(1), *) m%BodyList(l)%rCG(1) + READ(tempStrings(2), *) m%BodyList(l)%rCG(2) + READ(tempStrings(3), *) m%BodyList(l)%rCG(3) + else + CALL SetErrStat( ErrID_Fatal, 'Body '//trim(Num2LStr(l))//' CG entry (col 10) must have 1 or 3 numbers.' , ErrStat, ErrMsg, RoutineName ) + end if + ! process mements of inertia + CALL SplitByBars(tempString3, N, tempStrings) + if (N == 1) then ! if only one entry, use it for all directions + READ(tempString3, *) m%BodyList(l)%BodyI(1) + m%BodyList(l)%BodyI(2) = m%BodyList(l)%BodyI(1) + m%BodyList(l)%BodyI(3) = m%BodyList(l)%BodyI(1) + else if (N==3) then ! all three directions provided separately + READ(tempStrings(1), *) m%BodyList(l)%BodyI(1) + READ(tempStrings(2), *) m%BodyList(l)%BodyI(2) + READ(tempStrings(3), *) m%BodyList(l)%BodyI(3) + else + CALL SetErrStat( ErrID_Fatal, 'Body '//trim(Num2LStr(l))//' inertia entry (col 11) must have 1 or 3 numbers.' , ErrStat, ErrMsg, RoutineName ) + end if + ! process drag ceofficient by area product + CALL SplitByBars(tempString4, N, tempStrings) + if (N == 1) then ! if only one entry, use it for all directions + READ(tempString4, *) m%BodyList(l)%BodyCdA(1) + m%BodyList(l)%BodyCdA(2) = m%BodyList(l)%BodyCdA(1) + m%BodyList(l)%BodyCdA(3) = m%BodyList(l)%BodyCdA(1) + else if (N==3) then ! all three coordinates provided + READ(tempStrings(1), *) m%BodyList(l)%BodyCdA(1) + READ(tempStrings(2), *) m%BodyList(l)%BodyCdA(2) + READ(tempStrings(3), *) m%BodyList(l)%BodyCdA(3) + else + CALL SetErrStat( ErrID_Fatal, 'Body '//trim(Num2LStr(l))//' CdA entry (col 13) must have 1 or 3 numbers.' , ErrStat, ErrMsg, RoutineName ) + end if + ! process added mass coefficient + CALL SplitByBars(tempString5, N, tempStrings) + if (N == 1) then ! if only one entry, use it for all directions + READ(tempString5, *) m%BodyList(l)%BodyCa(1) + m%BodyList(l)%BodyCa(2) = m%BodyList(l)%BodyCa(1) + m%BodyList(l)%BodyCa(3) = m%BodyList(l)%BodyCa(1) + else if (N==3) then ! all three coordinates provided + READ(tempStrings(1), *) m%BodyList(l)%BodyCa(1) + READ(tempStrings(2), *) m%BodyList(l)%BodyCa(2) + READ(tempStrings(3), *) m%BodyList(l)%BodyCa(3) + else + CALL SetErrStat( ErrID_Fatal, 'Body '//trim(Num2LStr(l))//' Ca entry (col 14) must have 1 or 3 numbers.' , ErrStat, ErrMsg, RoutineName ) + end if + + + IF ( ErrStat2 /= 0 ) THEN + CALL WrScr(' Unable to parse Body '//trim(Num2LStr(l))//' on row '//trim(Num2LStr(i))//' in input file.') ! Specific screen output because errors likely + CALL WrScr(' Ensure row has all 13 columns needed in MDv2 input file (13th Dec 2021).') + CALL SetErrStat( ErrID_Fatal, 'Failed to read bodies.' , ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + - ! allocate array holding three latest fairlead tensions - ALLOCATE ( FairTensIC(p%NFairs,3), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - CALL CheckError( ErrID_Fatal, ErrMsg2 ) - RETURN - END IF + !----------- process body type ----------------- - ! initialize fairlead tension memory at zero - DO J = 1,p%NFairs - DO I = 1, 3 - FairTensIC(J,I) = 0.0_DbKi - END DO - END DO + call DecomposeString(tempString1, let1, num1, let2, num2, let3) ! note: this call is overkill (it's just a string) but leaving it here for potential future expansions + + if ((let1 == "ANCHOR") .or. (let1 == "FIXED") .or. (let1 == "FIX")) then ! if a fixed body (this would just be used if someone wanted to temporarly fix a body that things were attached to) + + m%BodyList(l)%typeNum = 1 + + else if ((let1 == "COUPLED") .or. (let1 == "VESSEL") .or. (let1 == "CPLD") .or. (let1 == "VES")) then ! if a coupled body + + m%BodyList(l)%typeNum = -1 + p%nCpldBodies(1)=p%nCpldBodies(1)+1 ! add this body to coupled list + m%CpldBodyIs(p%nCpldBodies(1),1) = l - t = 0.0_DbKi ! start time at zero + ! body initial position due to coupling will be adjusted later + + ! TODO: add option for body coupling to different turbines in FAST.Farm <<< + + else if (let1 == "FREE") then ! if a free body + m%BodyList(l)%typeNum = 0 + + p%nFreeBodies=p%nFreeBodies+1 + + m%BodyStateIs1(p%nFreeBodies) = Nx+1 + m%BodyStateIsN(p%nFreeBodies) = Nx+12 + Nx = Nx + 12 ! add 12 state variables for free Body + + m%FreeBodyIs(p%nFreeBodies) = l + + m%BodyList(l)%r6 = tempArray ! set initial body position and orientation + + else + CALL SetErrStat( ErrID_Fatal, "Unidentified Body type string for Body "//trim(Num2LStr(l))//": "//trim(tempString1), ErrStat, ErrMsg, RoutineName ) + return + end if + + + ! check for sequential IdNums + IF ( m%BodyList(l)%IdNum .NE. l ) THEN + CALL SetErrStat( ErrID_Fatal, 'Body numbers must be sequential starting from 1.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + + ! set up body + CALL Body_Setup( m%BodyList(l), tempArray, p, ErrStat2, ErrMsg2) + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Failed to read data for body '//trim(Num2LStr(l)), ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + IF (wordy > 1) print *, "Set up body ", l, " of type ", m%BodyList(l)%typeNum - ! because TimeStep wants an array... - call MD_CopyInput( u, uArray(1), MESH_NEWCOPY, ErrStat2, ErrMsg2 ) + END DO + + + !------------------------------------------------------------------------------------------- + else if ((INDEX(Line, "RODS") > 0 ) .or. (INDEX(Line, "ROD LIST") > 0) .or. (INDEX(Line, "ROD PROPERTIES") > 0)) then ! if rod properties header + IF (wordy > 0) print *, "Reading Rods" + + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! process each rod + DO l = 1,p%nRods + + !read into a line + Line = NextLine(i) + + ! check for correct number of columns in current line + IF ( CountWords( Line ) /= 11 ) THEN + CALL SetErrStat( ErrID_Fatal, ' Unable to parse Rod '//trim(Num2LStr(l))//' on row '//trim(Num2LStr(i))//' in input file. Row has wrong number of columns. Must be 11 columns.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + ! parse out entries: RodID RodType Attachment Xa Ya Za Xb Yb Zb NumSegs Flags/Outputs + IF (ErrStat2 == 0) THEN + READ(Line,*,IOSTAT=ErrStat2) m%RodList(l)%IdNum, tempString1, tempString2, & + tempArray(1), tempArray(2), tempArray(3), tempArray(4), tempArray(5), tempArray(6), & + m%RodList(l)%N, LineOutString + END IF - DO I = 1, ceiling(InitInp%TMaxIC/InitInp%DTIC) ! loop through IC gen time steps, up to maximum + ! find Rod properties index + DO J = 1,p%nRodTypes + IF (trim(tempString1) == trim(m%RodTypeList(J)%name)) THEN + m%RodList(l)%PropsIdNum = J + EXIT + END IF + IF (J == p%nRodTypes) THEN ! call an error if there is no match + CALL SetErrStat( ErrID_Fatal, 'Unable to find matching rod type name for Rod '//trim(Num2LStr(l))//": "//trim(tempString1), ErrStat, ErrMsg, RoutineName ) + RETURN + END IF + END DO - ! integrate the EOMs one DTIC s time step - CALL TimeStep ( t, InitInp%DTIC, uArray, utimes, p, x, xd, z, other, m, ErrStat, ErrMsg ) - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN - ! store new fairlead tension (and previous fairlead tensions for comparison) - DO J = 1, p%NFairs - FairTensIC(J,3) = FairTensIC(J,2) - FairTensIC(J,2) = FairTensIC(J,1) - FairTensIC(J,1) = TwoNorm(m%ConnectList(m%FairIdList(J))%Ftot(:)) - END DO + !----------- process rod type ----------------- - ! provide status message - ! bjj: putting this in a string so we get blanks to cover up previous values (if current string is shorter than previous one) - Message = ' t='//trim(Num2LStr(t))//' FairTen 1: '//trim(Num2LStr(FairTensIC(1,1)))// & - ', '//trim(Num2LStr(FairTensIC(1,2)))//', '//trim(Num2LStr(FairTensIC(1,3))) - CALL WrOver( Message ) - - ! check for convergence (compare current tension at each fairlead with previous two values) - IF (I > 2) THEN - Converged = 1 - DO J = 1, p%NFairs ! check for non-convergence - IF (( abs( FairTensIC(J,1)/FairTensIC(J,2) - 1.0 ) > InitInp%threshIC ) .OR. ( abs( FairTensIC(J,1)/FairTensIC(J,3) - 1.0 ) > InitInp%threshIC ) ) THEN - Converged = 0 - EXIT - END IF - END DO + call DecomposeString(tempString2, let1, num1, let2, num2, let3) + + if ((let1 == "ANCHOR") .or. (let1 == "FIXED") .or. (let1 == "FIX")) then + + m%RodList(l)%typeNum = 2 + CALL Body_AddRod(m%GroundBody, l, tempArray) ! add rod l to Ground body + - IF (Converged == 1) THEN ! (J == p%NFairs) THEN ! if we made it with all cases satisfying the threshold - CALL WrScr(' Fairlead tensions converged to '//trim(Num2LStr(100.0*InitInp%threshIC))//'% after '//trim(Num2LStr(t))//' seconds.') - EXIT ! break out of the time stepping loop - END IF - END IF + else if ((let1 == "PINNED") .or. (let1 == "PIN")) then + m%RodList(l)%typeNum = 1 + CALL Body_AddRod(m%GroundBody, l, tempArray) ! add rod l to Ground body + + p%nFreeRods=p%nFreeRods+1 ! add this pinned rod to the free list because it is half free + + m%RodStateIs1(p%nFreeRods) = Nx+1 + m%RodStateIsN(p%nFreeRods) = Nx+6 + Nx = Nx + 6 ! add 6 state variables for each pinned rod + + m%FreeRodIs(p%nFreeRods) = l + + else if (let1 == "BODY") then ! attached to a body (either rididly or pinned) + + if (len_trim(num1) > 0) then + + READ(num1,*) J ! convert to int, representing parent body index + + if ((J <= p%nBodies) .and. (J > 0)) then + + CALL Body_AddRod(m%BodyList(J), l, tempArray) ! add rod l to the body + + if ( (let2 == "PINNED") .or. (let2 == "PIN") ) then + m%RodList(l)%typeNum = 1 + + p%nFreeRods=p%nFreeRods+1 ! add this pinned rod to the free list because it is half free + + m%RodStateIs1(p%nFreeRods) = Nx+1 + m%RodStateIsN(p%nFreeRods) = Nx+6 + Nx = Nx + 6 ! add 6 state variables for each pinned rod + + m%FreeRodIs(p%nFreeRods) = l + + else if (let2 == " ") then ! rod is not requested to be pinned, so add this rod as a fixed one + m%RodList(l)%typeNum = 2 + + else + CALL SetErrStat( ErrID_Fatal, "Unidentified Type/BodyID for Rod "//trim(Num2LStr(l))//": "//trim(tempString2), ErrStat, ErrMsg, RoutineName ) + return + end if + + else + CALL SetErrStat( ErrID_Fatal, "Body ID out of bounds for Rod "//trim(Num2LStr(l))//".", ErrStat, ErrMsg, RoutineName ) + return + end if + + else + CALL SetErrStat( ErrID_Fatal, "No number provided for Rod "//trim(Num2LStr(l))//" Body attachment.", ErrStat, ErrMsg, RoutineName ) + return + end if + + else if ((let1 == "VESSEL") .or. (let1 == "VES") .or. (let1 == "COUPLED") .or. (let1 == "CPLD")) then ! if a rigidly coupled rod, add to list and add + m%RodList(l)%typeNum = -2 + + p%nCpldRods(1)=p%nCpldRods(1)+1 ! add this rod to coupled list + + m%CpldRodIs(p%nCpldRods(1),1) = l + + else if ((let1 == "VESSELPINNED") .or. (let1 == "VESPIN") .or. (let1 == "COUPLEDPINNED") .or. (let1 == "CPLDPIN")) then ! if a pinned coupled rod, add to list and add + m%RodList(l)%typeNum = -1 + + p%nCpldRods(1)=p%nCpldRods(1)+1 ! add + p%nFreeRods =p%nFreeRods+1 ! add this pinned rod to the free list because it is half free + + m%RodStateIs1(p%nFreeRods) = Nx+1 + m%RodStateIsN(p%nFreeRods) = Nx+6 + Nx = Nx + 6 ! add 6 state variables for each pinned rod + + m%CpldRodIs(p%nCpldRods(1),1) = l + m%FreeRodIs(p%nFreeRods) = l + + ! TODO: add option for body coupling to different turbines in FAST.Farm <<< + + else if ((let1 == "CONNECT") .or. (let1 == "CON") .or. (let1 == "FREE")) then + m%RodList(l)%typeNum = 0 + + p%nFreeRods=p%nFreeRods+1 ! add this pinned rod to the free list because it is half free + + m%RodStateIs1(p%nFreeRods) = Nx+1 + m%RodStateIsN(p%nFreeRods) = Nx+12 + Nx = Nx + 12 ! add 12 state variables for free Rod + + m%FreeRodIs(p%nFreeRods) = l + + else + + CALL SetErrStat( ErrID_Fatal, "Unidentified Type/BodyID for Rod "//trim(Num2LStr(l))//": "//trim(tempString2), ErrStat, ErrMsg, RoutineName ) + return + end if + + + ! process output flag characters (LineOutString) and set line output flag array (OutFlagList) + m%RodList(l)%OutFlagList = 0 ! first set array all to zero + ! per node, 3 component + IF ( scan( LineOutString, 'p') > 0 ) m%RodList(l)%OutFlagList(2 ) = 1 ! node position + IF ( scan( LineOutString, 'v') > 0 ) m%RodList(l)%OutFlagList(3 ) = 1 ! node velocity + IF ( scan( LineOutString, 'U') > 0 ) m%RodList(l)%OutFlagList(4 ) = 1 ! water velocity + IF ( scan( LineOutString, 'B') > 0 ) m%RodList(l)%OutFlagList(5 ) = 1 ! node buoyancy force + IF ( scan( LineOutString, 'D') > 0 ) m%RodList(l)%OutFlagList(6 ) = 1 ! drag force + IF ( scan( LineOutString, 'I') > 0 ) m%RodList(l)%OutFlagList(7 ) = 1 ! inertia force + IF ( scan( LineOutString, 'P') > 0 ) m%RodList(l)%OutFlagList(8 ) = 1 ! dynamic pressure force + IF ( scan( LineOutString, 'b') > 0 ) m%RodList(l)%OutFlagList(9 ) = 1 ! seabed contact forces + ! per node, 1 component + IF ( scan( LineOutString, 'W') > 0 ) m%RodList(l)%OutFlagList(10) = 1 ! node weight/buoyancy (positive up) + IF ( scan( LineOutString, 'K') > 0 ) m%RodList(l)%OutFlagList(11) = 1 ! curvature at node + ! per element, 1 component >>> these don't apply to a rod!! <<< + IF ( scan( LineOutString, 't') > 0 ) m%RodList(l)%OutFlagList(12) = 1 ! segment tension force (just EA) + IF ( scan( LineOutString, 'c') > 0 ) m%RodList(l)%OutFlagList(13) = 1 ! segment internal damping force + IF ( scan( LineOutString, 's') > 0 ) m%RodList(l)%OutFlagList(14) = 1 ! Segment strain + IF ( scan( LineOutString, 'd') > 0 ) m%RodList(l)%OutFlagList(15) = 1 ! Segment strain rate + + IF (SUM(m%RodList(l)%OutFlagList) > 0) m%RodList(l)%OutFlagList(1) = 1 ! this first entry signals whether to create any output file at all + ! the above letter-index combinations define which OutFlagList entry corresponds to which output type + + + ! specify IdNum of line for error checking + m%RodList(l)%IdNum = l + + ! check for sequential IdNums + IF ( m%RodList(l)%IdNum .NE. l ) THEN + CALL SetErrStat( ErrID_Fatal, 'Line numbers must be sequential starting from 1.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + ! set up rod + CALL Rod_Setup( m%RodList(l), m%RodTypeList(m%RodList(l)%PropsIdNum), tempArray, p, ErrStat2, ErrMsg2) + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + + ! note: Rod was already added to its respective parent body if type > 0 + + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Failed to read rod data for Rod '//trim(Num2LStr(l)), ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF - IF (I == ceiling(InitInp%TMaxIC/InitInp%DTIC) ) THEN - CALL WrScr(' Fairlead tensions did not converge within TMaxIC='//trim(Num2LStr(InitInp%TMaxIC))//' seconds.') - !ErrStat = ErrID_Warn - !ErrMsg = ' MD_Init: ran dynamic convergence to TMaxIC without convergence' - END IF + END DO ! l = 1,p%nRods - END DO ! I ... looping through time steps - CALL MD_DestroyInput( uArray(1), ErrStat2, ErrMsg2 ) + !------------------------------------------------------------------------------------------- + else if ((INDEX(Line, "POINTS") > 0 ) .or. (INDEX(Line, "CONNECTION PROPERTIES") > 0) .or. (INDEX(Line, "NODE PROPERTIES") > 0) .or. (INDEX(Line, "POINT PROPERTIES") > 0) .or. (INDEX(Line, "POINT LIST") > 0) ) then ! if node properties header + + IF (wordy > 0) print *, "Reading Points" + + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! process each point + DO l = 1,p%nConnects + + !read into a line + Line = NextLine(i) + + ! check for correct number of columns in current line + IF ( CountWords( Line ) /= 9 ) THEN + CALL SetErrStat( ErrID_Fatal, ' Unable to parse Point '//trim(Num2LStr(l))//' on row '//trim(Num2LStr(i))//' in input file. Row has wrong number of columns. Must be 9 columns.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + ! parse out entries: PointID Attachment X Y Z M V CdA Ca + IF (ErrStat2 == 0) THEN + READ(Line,*,IOSTAT=ErrStat2) m%ConnectList(l)%IdNum, tempString1, tempArray(1), & + tempArray(2), tempString4, m%ConnectList(l)%conM, & + m%ConnectList(l)%conV, m%ConnectList(l)%conCdA, m%ConnectList(l)%conCa + + CALL Conv2UC(tempString4) ! convert to uppercase so that matching is not case-sensitive + + if ((INDEX(tempString4, "SEABED") > 0 ) .or. (INDEX(tempString4, "GROUND") > 0 ) .or. (INDEX(tempString4, "FLOOR") > 0 )) then ! if keyword used + CALL WrScr('Point '//trim(Num2LStr(l))//' depth set to be on the seabed; finding z location based on depth/bathymetry') ! interpret the anchor depth value as a 'seabed' input + CALL getDepthFromBathymetry(m%BathymetryGrid, m%BathGrid_Xs, m%BathGrid_Ys, tempArray(1), tempArray(2), depth, nvec) ! meaning the anchor should be at the depth of the local bathymetry + tempArray(3) = -depth + else ! if the anchor depth input isn't one of the supported keywords, + READ(tempString4, *, IOSTAT=ErrStat2) tempArray(3) ! assume it's a scalar depth value + !TODO: add error check for if the above read fails + end if + + ! not used + m%ConnectList(l)%conFX = 0.0_DbKi + m%ConnectList(l)%conFY = 0.0_DbKi + m%ConnectList(l)%conFZ = 0.0_DbKi + + END IF + + + IF ( ErrStat2 /= 0 ) THEN + CALL WrScr(' Unable to parse Point '//trim(Num2LStr(l))//' row in input file.') ! Specific screen output because errors likely + CALL WrScr(' Ensure row has all 9 columns, including CdA and Ca.') ! to be caused by non-updated input file formats. + CALL SetErrStat( ErrID_Fatal, 'Failed to read connects.' , ErrStat, ErrMsg, RoutineName ) ! would be nice to specify which line <<<<<<<<< + CALL CleanUp() + RETURN + END IF + + m%ConnectList(l)%r = tempArray(1:3) ! set initial, or reference, node position (for coupled or child objects, this will be the local reference location about the parent) - ! UNboost drag coefficient of each line type - DO I = 1, p%NTypes - m%LineTypeList(I)%Cdn = m%LineTypeList(I)%Cdn / InitInp%CdScaleIC - m%LineTypeList(I)%Cdt = m%LineTypeList(I)%Cdt / InitInp%CdScaleIC - END DO + !----------- process connection type ----------------- + call DecomposeString(tempString1, let1, num1, let2, num2, let3) + + if ((let1 == "ANCHOR") .or. (let1 == "FIXED") .or. (let1 == "FIX")) then + m%ConnectList(l)%typeNum = 1 + + !m%ConnectList(l)%r = tempArray(1:3) ! set initial node position + + CALL Body_AddConnect(m%GroundBody, l, tempArray(1:3)) ! add connection l to Ground body + + else if (let1 == "BODY") then ! attached to a body + if (len_trim(num1) > 0) then + READ(num1, *) J ! convert to int, representing parent body index + + if ((J <= p%nBodies) .and. (J > 0)) then + m%ConnectList(l)%typeNum = 1 + + CALL Body_AddConnect(m%BodyList(J), l, tempArray(1:3)) ! add connection l to Ground body + + else + CALL SetErrStat( ErrID_Fatal, "Body ID out of bounds for Connection "//trim(Num2LStr(l))//".", ErrStat, ErrMsg, RoutineName ) + return + end if + else + CALL SetErrStat( ErrID_Fatal, "No number provided for Connection "//trim(Num2LStr(l))//" Body attachment.", ErrStat, ErrMsg, RoutineName ) + return + end if + + else if ((let1 == "VESSEL") .or. (let1 == "VES") .or. (let1 == "COUPLED") .or. (let1 == "CPLD")) then ! if a fairlead, add to list and add + m%ConnectList(l)%typeNum = -1 + p%nCpldCons(1)=p%nCpldCons(1)+1 + m%CpldConIs(p%nCpldCons(1),1) = l + + else if ((let1 == "CONNECT") .or. (let1 == "CON") .or. (let1 == "FREE")) then + m%ConnectList(l)%typeNum = 0 + + p%nFreeCons=p%nFreeCons+1 ! add this pinned rod to the free list because it is half free + + m%ConStateIs1(p%nFreeCons) = Nx+1 + m%ConStateIsN(p%nFreeCons) = Nx+6 + Nx = Nx + 6 ! add 12 state variables for free Connection + + m%FreeConIs(p%nFreeCons) = l + + !m%ConnectList(l)%r = tempArray(1:3) ! set initial node position + + else if ((let1 == "TURBINE") .or. (let1 == "T")) then ! turbine-coupled in FAST.Farm case + + if (len_trim(num1) > 0) then + READ(num1, *) J ! convert to int, representing turbine index + + if ((J <= p%nTurbines) .and. (J > 0)) then + + m%ConnectList(l)%TypeNum = -1 ! set as coupled type + p%nCpldCons(J) = p%nCpldCons(J) + 1 ! increment counter for the appropriate turbine + m%CpldConIs(p%nCpldCons(J),J) = l + CALL WrScr(' added connection '//TRIM(int2lstr(l))//' as fairlead for turbine '//trim(int2lstr(J))) + + + else + CALL SetErrStat( ErrID_Fatal, "Turbine ID out of bounds for Connection "//trim(Num2LStr(l))//".", ErrStat, ErrMsg, RoutineName ) + return + end if + else + CALL SetErrStat( ErrID_Fatal, "No number provided for Connection "//trim(Num2LStr(l))//" Turbine attachment.", ErrStat, ErrMsg, RoutineName ) + return + end if + + else + CALL SetErrStat( ErrID_Fatal, "Unidentified Type/BodyID for Connection "//trim(Num2LStr(l))//": "//trim(tempString1), ErrStat, ErrMsg, RoutineName ) + return + end if + + ! set initial velocity to zero + m%ConnectList(l)%rd(1) = 0.0_DbKi + m%ConnectList(l)%rd(2) = 0.0_DbKi + m%ConnectList(l)%rd(3) = 0.0_DbKi + + !also set number of attached lines to zero initially + m%ConnectList(l)%nAttached = 0 + + + ! check for sequential IdNums + IF ( m%ConnectList(l)%IdNum .NE. l ) THEN + CALL SetErrStat( ErrID_Fatal, 'Connection numbers must be sequential starting from 1.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + - p%dtCoupling = DTcoupling ! store coupling time step for use in updatestates + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Failed to read data for Connection '//trim(Num2LStr(l)), ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + IF (wordy > 0) print *, "Set up Point ", l, " of type ", m%ConnectList(l)%typeNum - other%dummy = 0 - xd%dummy = 0 - z%dummy = 0 + END DO ! l = 1,p%nRods - CONTAINS + !------------------------------------------------------------------------------------------- + else if ((INDEX(Line, "LINES") > 0 ) .or. (INDEX(Line, "LINE PROPERTIES") > 0) .or. (INDEX(Line, "LINE LIST") > 0) ) then ! if line properties header - SUBROUTINE CheckError(ErrID,Msg) - ! This subroutine sets the error message and level and cleans up if the error is >= AbortErrLev + IF (wordy > 0) print *, "Reading Lines" + + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! process each line + DO l = 1,p%nLines + + !read into a line + Line = NextLine(i) + + ! check for correct number of columns in current line + IF ( CountWords( Line ) /= 7 ) THEN + CALL SetErrStat( ErrID_Fatal, ' Unable to parse Line '//trim(Num2LStr(l))//' on row '//trim(Num2LStr(i))//' in input file. Row has wrong number of columns. Must be 7 columns.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + ! parse out entries: ID LineType AttachA AttachB UnstrLen NumSegs Outputs (note: order changed Dec 13, 2021 before MDv2 release) + IF (ErrStat2 == 0) THEN + READ(Line,*,IOSTAT=ErrStat2) m%LineList(l)%IdNum, tempString1, tempString2, tempString3, & + m%LineList(l)%UnstrLen, m%LineList(l)%N, LineOutString + END IF + + ! identify index of line type + DO J = 1,p%nLineTypes + IF (trim(tempString1) == trim(m%LineTypeList(J)%name)) THEN + m%LineList(l)%PropsIdNum = J + EXIT + END IF + IF (J == p%nLineTypes) THEN ! call an error if there is no match + CALL SetErrStat( ErrID_Fatal, 'Unable to find matching line type name for Line '//trim(Num2LStr(l)), ErrStat, ErrMsg, RoutineName ) + RETURN + END IF + END DO + + ! account for states of line + m%LineStateIs1(l) = Nx + 1 + if (m%LineTypeList(m%LineList(l)%PropsIdNum)%ElasticMod == 2) then + Nx = Nx + 7*m%LineList(l)%N - 6 ! if using viscoelastic model, need one more state per segment + m%LineStateIsN(l) = Nx + else + Nx = Nx + 6*m%LineList(l)%N - 6 ! normal case, just 6 states per internal node + m%LineStateIsN(l) = Nx + end if + + ! Process attachment identfiers and attach line ends + + ! First for the anchor (or end A)... + + call DecomposeString(tempString2, let1, num1, let2, num2, let3) + + if (len_trim(num1)<1) then + CALL SetErrStat( ErrID_Fatal, "Error: no number provided for line "//trim(Num2LStr(l))//" end A attachment.", ErrStat, ErrMsg, RoutineName ) + return + end if + + READ(num1, *) J ! convert to int + + ! if id starts with an "R" or "Rod" + if ((let1 == "R") .or. (let1 == "ROD")) then + + if ((J <= p%nRods) .and. (J > 0)) then + if (let2 == "A") then + CALL Rod_AddLine(m%RodList(J), l, 0, 0) ! add line l (end A, denoted by 0) to rod J (end A, denoted by 0) + else if (let2 == "B") then + CALL Rod_AddLine(m%RodList(J), l, 0, 1) ! add line l (end A, denoted by 0) to rod J (end B, denoted by 1) + else + CALL SetErrStat( ErrID_Fatal, "Error: rod end (A or B) must be specified for line "//trim(Num2LStr(l))//" end A attachment. Instead seeing "//let2, ErrStat, ErrMsg, RoutineName ) + return + end if + else + CALL SetErrStat( ErrID_Fatal, "Error: rod connection ID out of bounds for line "//trim(Num2LStr(l))//" end A attachment.", ErrStat, ErrMsg, RoutineName ) + return + end if + + ! if J starts with a "C" or "Con" or goes straight ot the number then it's attached to a Connection + else if ((len_trim(let1)==0) .or. (let1 == "C") .or. (let1 == "CON")) then + + if ((J <= p%nConnects) .and. (J > 0)) then + CALL Connect_AddLine(m%ConnectList(J), l, 0) ! add line l (end A, denoted by 0) to connection J + else + CALL SetErrStat( ErrID_Fatal, "Error: connection out of bounds for line "//trim(Num2LStr(l))//" end A attachment.", ErrStat, ErrMsg, RoutineName ) + return + end if + + end if + + + ! Then again for the fairlead (or end B)... + + call DecomposeString(tempString3, let1, num1, let2, num2, let3) + + if (len_trim(num1)<1) then + CALL SetErrStat( ErrID_Fatal, "Error: no number provided for line "//trim(Num2LStr(l))//" end B attachment.", ErrStat, ErrMsg, RoutineName ) + return + end if + + READ(num1, *) J ! convert to int + + ! if id starts with an "R" or "Rod" + if ((let1 == "R") .or. (let1 == "ROD")) then + + if ((J <= p%nRods) .and. (J > 0)) then + if (let2 == "A") then + CALL Rod_AddLine(m%RodList(J), l, 1, 0) ! add line l (end B, denoted by 1) to rod J (end A, denoted by 0) + else if (let2 == "B") then + CALL Rod_AddLine(m%RodList(J), l, 1, 1) ! add line l (end B, denoted by 1) to rod J (end B, denoted by 1) + else + CALL SetErrStat( ErrID_Fatal, "Error: rod end (A or B) must be specified for line "//trim(Num2LStr(l))//" end B attachment. Instead seeing "//let2, ErrStat, ErrMsg, RoutineName ) + return + end if + else + CALL SetErrStat( ErrID_Fatal, "Error: rod connection ID out of bounds for line "//trim(Num2LStr(l))//" end B attachment.", ErrStat, ErrMsg, RoutineName ) + return + end if + + ! if J starts with a "C" or "Con" or goes straight ot the number then it's attached to a Connection + else if ((len_trim(let1)==0) .or. (let1 == "C") .or. (let1 == "CON")) then + + if ((J <= p%nConnects) .and. (J > 0)) then + CALL Connect_AddLine(m%ConnectList(J), l, 1) ! add line l (end B, denoted by 1) to connection J + else + CALL SetErrStat( ErrID_Fatal, "Error: connection out of bounds for line "//trim(Num2LStr(l))//" end B attachment.", ErrStat, ErrMsg, RoutineName ) + return + end if + + end if + + + ! process output flag characters (LineOutString) and set line output flag array (OutFlagList) + m%LineList(l)%OutFlagList = 0 ! first set array all to zero + ! per node 3 component + IF ( scan( LineOutString, 'p') > 0 ) m%LineList(l)%OutFlagList(2) = 1 + IF ( scan( LineOutString, 'v') > 0 ) m%LineList(l)%OutFlagList(3) = 1 + IF ( scan( LineOutString, 'U') > 0 ) m%LineList(l)%OutFlagList(4) = 1 + IF ( scan( LineOutString, 'D') > 0 ) m%LineList(l)%OutFlagList(5) = 1 + IF ( scan( LineOutString, 'b') > 0 ) m%LineList(l)%OutFlagList(6) = 1 ! seabed contact forces + ! per node 1 component + IF ( scan( LineOutString, 'W') > 0 ) m%LineList(l)%OutFlagList(7) = 1 ! node weight/buoyancy (positive up) + IF ( scan( LineOutString, 'K') > 0 ) m%LineList(l)%OutFlagList(8) = 1 ! curvature at node + ! per element 1 component + IF ( scan( LineOutString, 't') > 0 ) m%LineList(l)%OutFlagList(10) = 1 ! segment tension force (just EA) + IF ( scan( LineOutString, 'c') > 0 ) m%LineList(l)%OutFlagList(11) = 1 ! segment internal damping force + IF ( scan( LineOutString, 's') > 0 ) m%LineList(l)%OutFlagList(12) = 1 ! Segment strain + IF ( scan( LineOutString, 'd') > 0 ) m%LineList(l)%OutFlagList(13) = 1 ! Segment strain rate + IF ( scan( LineOutString, 'l') > 0 ) m%LineList(l)%OutFlagList(14) = 1 ! Segment stretched length + + IF (SUM(m%LineList(l)%OutFlagList) > 0) m%LineList(l)%OutFlagList(1) = 1 ! this first entry signals whether to create any output file at all + ! the above letter-index combinations define which OutFlagList entry corresponds to which output type + + + ! specify IdNum of line for error checking + m%LineList(l)%IdNum = l + + + ! check for sequential IdNums + IF ( m%LineList(l)%IdNum .NE. l ) THEN + CALL SetErrStat( ErrID_Fatal, 'Line numbers must be sequential starting from 1.', ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + + ! setup line + CALL SetupLine( m%LineList(l), m%LineTypeList(m%LineList(l)%PropsIdNum), p, ErrStat2, ErrMsg2) + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + + + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Failed to read line data for Line '//trim(Num2LStr(l)), ErrStat, ErrMsg, RoutineName ) + CALL CleanUp() + RETURN + END IF + + END DO ! l = 1,p%nLines + + + + !------------------------------------------------------------------------------------------- + else if (INDEX(Line, "CONTROL") > 0) then ! if control inputs header + + IF (wordy > 0) print *, " Reading control inputs"; + + ! TODO: add stuff <<<<<<<< + + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! process each line + DO l = 1,p%nCtrlChans + + !read into a line + Line = NextLine(i) + + ! count commas to determine how many line IDs specified for this channel + N = count(transfer(Line, 'a', len(Line)) == ",") + 1 ! number of line IDs given + + ! parse out entries: CtrlChan, LineIdNums + read(Line, *) Itemp, TempIDnums(1:N) ! parse out each line ID + + DO J = 1,N + if (TempIDnums(J) <= p%nLines) then ! ensure line ID is in range + if (m%LineList( TempIDnums(J) )%CtrlChan == 0) then ! ensure line doesn't already have a CtrlChan assigned + m%LineList( TempIDnums(J) )%CtrlChan = Itemp + CALL WrScr('Assigned Line '//TRIM(Int2LStr(TempIDnums(J)))//' to control channel '//TRIM(Int2LStr(Itemp))) + else + CALL WrScr('Error: Line '//TRIM(Int2LStr(TempIDnums(J)))//' already is assigned to control channel '//TRIM(Int2LStr(m%LineList( TempIDnums(J) )%CtrlChan))//' so cannot also be assigned to channel '//TRIM(Int2LStr(Itemp))) + end if + else + CALL WrScr('Error: Line ID '//TRIM(Int2LStr(TempIDnums(J)))//' of CtrlChan '//TRIM(Int2LStr(Itemp))//' is out of range') + end if + + END DO + + END DO + + + !------------------------------------------------------------------------------------------- + else if (INDEX(Line, "FAILURE") > 0) then ! if failure conditions header + + CALL WrScr(" Warning: Failure capabilities are not yet implemented in MoorDyn.") + + ! skip following two lines (label line and unit line) + Line = NextLine(i) + Line = NextLine(i) + + ! process each line + DO l = 1,p%nFails + + !read into a line + Line = NextLine(i) + + ! TODO: Failure capabilities still need to be completed + READ(Line,*,IOSTAT=ErrStat2) m%LineList(l)%IdNum, tempString1, m%LineList(l)%UnstrLen, & + m%LineList(l)%N, tempString2, tempString3, LineOutString + + END DO + + + !------------------------------------------------------------------------------------------- + else if (INDEX(Line, "OUTPUT") > 0) then ! if output header + + IF (wordy > 0) print *, "Reading Outputs" + + ! (don't skip any lines) + + ! allocate InitInp%Outliest (to a really big number for now...) + CALL AllocAry( OutList, MaxAryLen, "MoorDyn Input File's Outlist", ErrStat2, ErrMsg2 ); if(Failed()) return + + + ! Initialize some values + p%NumOuts = 0 ! start counter at zero + OutList = '' + + + ! Read in all of the lines containing output parameters and store them in OutList(:) + ! customm implementation to avoid need for "END" keyword line + DO + ! read a line + Line = NextLine(i) + Line = adjustl(trim(Line)) ! remove leading whitespace + + CALL Conv2UC(Line) ! convert to uppercase for easy string matching + + if ((INDEX(Line, "---") > 0) .or. (INDEX(Line, "END") > 0)) EXIT ! stop if we hit a header line or the keyword "END" + + ! Check if we have a quoted string at the beginning. Ignore anything outside the quotes if so (this is the ReadVar behaviour for quoted strings). + IF (SCAN(Line(1:1), '''"' ) == 1_IntKi ) THEN + QuoteCh = SCAN( Line(2:), '''"' ) ! last quote + IF (QuoteCh < 1) QuoteCh = LEN_TRIM(Line) ! in case no end quote + Line(QuoteCh+2:) = ' ' ! blank out everything after last quote + END IF + + NumWords = CountWords( Line ) ! The number of words in Line. + + p%NumOuts = p%NumOuts + NumWords ! The total number of output channels read in so far. + + + IF ( p%NumOuts > MaxAryLen ) THEN ! Check to see if the maximum # allowable in the array has been reached. + + ErrStat = ErrID_Fatal + ErrMsg = 'Error while reading output channels: The maximum number of output channels allowed is '//TRIM( Int2LStr(MaxAryLen) )//'.' + EXIT + + ELSE + CALL GetWords ( Line, OutList((p%NumOuts - NumWords + 1):p%NumOuts), NumWords ) + + END IF + + END DO + + ! process the OutList array and set up the index arrays for the requested output quantities + CALL MDIO_ProcessOutList(OutList, p, m, y, InitOut, ErrStat2, ErrMsg2 ) + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + + + !------------------------------------------------------------------------------------------- + else ! otherwise ignore this line that isn't a recognized header line and read the next line + Line = NextLine(i) + end if + + !------------------------------------------------------------------------------------------- + + else ! otherwise ignore this line, which doesn't have the "---" or header line and read the next line + Line = NextLine(i) + end if + + end do + + + ! this is the end of parsing the input file, so cleanup anything we don't need anymore + CALL CleanUp() + + ! End of input file parsing from the FileInfo_In data structure + !------------------------------------------------------------------------------------------------- + + + + + + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + + + + !------------------------------------------------------------------------------------------------- + ! Connect mooring system together and make necessary allocations + !------------------------------------------------------------------------------------------------- + + CALL WrNr(' Created mooring system: ' ) + +! p%NAnchs = 0 ! this is the number of "fixed" type Connections. <<<<<<<<<<<<<< + + CALL WrScr(trim(Num2LStr(p%nLines))//' lines, '//trim(Num2LStr(p%NConnects))//' points, '//trim(Num2LStr(p%nRods))//' rods, '//trim(Num2LStr(p%nBodies))//' bodies.') + + + + + ! ! now go back through and record the fairlead Id numbers (this >>>WAS<<< all the "connecting" that's required) <<<< + ! J = 1 ! counter for fairlead number + ! K = 1 ! counter for connect number + ! DO I = 1,p%NConnects + ! IF (m%ConnectList(I)%typeNum == 1) THEN + ! m%CpldConIs(J) = I ! if a vessel connection, add ID to list + ! J = J + 1 + ! ELSE IF (m%ConnectList(I)%typeNum == 2) THEN + ! m%FreeConIs(K) = I ! if a connect connection, add ID to list + ! K = K + 1 + ! END IF + ! END DO + + IF (wordy > 1) print *, "nLineTypes = ",p%nLineTypes + IF (wordy > 1) print *, "nRodTypes = ",p%nRodTypes + IF (wordy > 1) print *, "nConnects = ",p%nConnects + IF (wordy > 1) print *, "nConnectsExtra = ",p%nConnectsExtra + IF (wordy > 1) print *, "nBodies = ",p%nBodies + IF (wordy > 1) print *, "nRods = ",p%nRods + IF (wordy > 1) print *, "nLines = ",p%nLines + IF (wordy > 1) print *, "nCtrlChans = ",p%nCtrlChans + IF (wordy > 1) print *, "nFails = ",p%nFails + IF (wordy > 1) print *, "nFreeBodies = ",p%nFreeBodies + IF (wordy > 1) print *, "nFreeRods = ",p%nFreeRods + IF (wordy > 1) print *, "nFreeCons = ",p%nFreeCons + IF (wordy > 1) print *, "nCpldBodies = ",p%nCpldBodies + IF (wordy > 1) print *, "nCpldRods = ",p%nCpldRods + IF (wordy > 1) print *, "nCpldCons = ",p%nCpldCons + IF (wordy > 1) print *, "NConns = ",p%NConns + IF (wordy > 1) print *, "NAnchs = ",p%NAnchs + + IF (wordy > 2) print *, "FreeConIs are ", m%FreeConIs + IF (wordy > 2) print *, "CpldConIs are ", m%CpldConIs + + + ! write system description to log file + if (p%writeLog > 1) then + write(p%UnLog, '(A)') "----- MoorDyn Model Summary (to be written) -----" + end if + + + + !------------------------------------------------------------------------------------ + ! fill in state vector index record holders + !------------------------------------------------------------------------------------ + + ! allocate state vector index record holders... + + + + ! ! allocate list of starting and ending state vector indices for each free connection + ! ALLOCATE ( m%ConStateIs1(p%nFreeCons), m%ConStateIsN(p%nFreeCons), STAT = ErrStat ) + ! IF ( ErrStat /= ErrID_None ) THEN + ! CALL CheckError(ErrID_Fatal, ' Error allocating ConStateIs array.') + ! RETURN + ! END IF + ! + ! ! allocate list of starting and ending state vector indices for each line - does this belong elsewhere? + ! ALLOCATE ( m%LineStateIs1(p%nLines), m%LineStateIsN(p%nLines), STAT = ErrStat ) + ! IF ( ErrStat /= ErrID_None ) THEN + ! CALL CheckError(ErrID_Fatal, ' Error allocating LineStateIs arrays.') + ! RETURN + ! END IF + ! + ! + ! ! fill in values for state vector index record holders... + ! + ! J=0 ! start off index counter at zero + ! + ! ! Free Bodies... + ! ! Free Rods... + ! + ! ! Free Connections... + ! DO l = 1, p%nFreeCons + ! J = J + 1 ! assign start index + ! m%ConStateIs1(l) = J + ! + ! J = J + 5 ! assign end index (5 entries further, since nodes have 2*3 states) + ! m%ConStateIsN(l) = J + ! END DO + ! + ! ! Lines + ! DO l = 1, p%nLines + ! J = J + 1 ! assign start index + ! m%LineStateIs1(l) = J + ! + ! J = J + 6*(m%LineList(l)%N - 1) - 1 ! !add 6 state variables for each internal node + ! m%LineStateIsN(l) = J + ! END DO + ! + ! + ! ! record number of states + ! m%Nx = J + + + !------------------------------------------------------------------------------------ + ! prepare state vector etc. + !------------------------------------------------------------------------------------ + + ! the number of states is Nx + m%Nx = Nx + + IF (wordy > 0) print *, "allocating state vectors to size ", Nx + + ! allocate state vector and temporary state vectors based on size just calculated + ALLOCATE ( x%states(m%Nx), m%xTemp%states(m%Nx), m%xdTemp%states(m%Nx), STAT = ErrStat2 ) + IF ( ErrStat2 /= ErrID_None ) THEN + ErrMsg = ' Error allocating state vectors.' + !CALL CleanUp() + RETURN + END IF + x%states = 0.0_DbKi + m%xTemp%states = 0.0_DbKi + m%xdTemp%states = 0.0_DbKi + + + + ! ================================ initialize system ================================ + ! This will also set the initial positions of any dependent (child) objects + + ! call ground body to update all the fixed things... + m%GroundBody%r6(4:6) = 0.0_DbKi + CALL Body_SetDependentKin(m%GroundBody, 0.0_DbKi, m) + + ! m%GroundBody%OrMat = EulerConstruct( m%GroundBody%r6(4:6) ) ! make sure it's OrMat is set up <<< need to check this approach + + ! ! first set/update the kinematics of all the fixed things (>>>> eventually do this by using a ground body <<<<) + ! ! only doing connections so far + ! DO J = 1,p%nConnects + ! if (m%ConnectList(J)%typeNum == 1) then + ! ! set the attached line endpoint positions: + ! CALL Connect_SetKinematics(m%ConnectList(J), m%ConnectList(J)%r, (/0.0_DbKi,0.0_DbKi,0.0_DbKi/), 0.0_DbKi, m%LineList) + ! end if + ! END DO + + + ! Initialize coupled objects based on passed kinematics + ! (set up initial condition of each coupled object based on values specified by glue code) + ! Also create i/o meshes + + ALLOCATE ( u%CoupledKinematics(p%nTurbines), STAT = ErrStat2 ) + IF ( ErrStat2 /= ErrID_None ) THEN + CALL CheckError(ErrID_Fatal, ' Error allocating CoupledKinematics input array.') + RETURN + END IF + ALLOCATE ( y%CoupledLoads(p%nTurbines), STAT = ErrStat2 ) + IF ( ErrStat2 /= ErrID_None ) THEN + CALL CheckError(ErrID_Fatal, ' Error allocating CoupledLoads output array.') + RETURN + END IF + + ! Go through each turbine and set up its mesh and initial positions of coupled objects + DO iTurb = 1,p%nTurbines + + ! calculate rotation matrix OrMat for the initial orientation provided for this turbine + CALL SmllRotTrans('PtfmInit', InitInp%PtfmInit(4,iTurb),InitInp%PtfmInit(5,iTurb),InitInp%PtfmInit(6,iTurb), OrMat, '', ErrStat2, ErrMsg2) + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + + ! count number of coupling nodes needed for the mesh of this turbine + K = p%nCpldBodies(iTurb) + p%nCpldRods(iTurb) + p%nCpldCons(iTurb) + if (K == 0) K = 1 ! Always have at least one node (it will be a dummy node if no fairleads are attached) + + ! create input mesh for fairlead kinematics + CALL MeshCreate(BlankMesh=u%CoupledKinematics(iTurb) , & + IOS= COMPONENT_INPUT, Nnodes = K, & + TranslationDisp=.TRUE., TranslationVel=.TRUE., & + Orientation=.TRUE., RotationVel=.TRUE., & + TranslationAcc=.TRUE., RotationAcc= .TRUE., & + ErrStat=ErrStat2, ErrMess=ErrMsg2) + + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + + ! note: in MoorDyn-F v2, the points in the mesh correspond in order to all the coupled bodies, then rods, then connections + ! >>> make sure all coupled objects have been offset correctly by the PtfmInit values, including if it's a farm situation -- below or where the objects are first created <<<< + + + J = 0 ! this is the counter through the mesh points for each turbine + + DO l = 1,p%nCpldBodies(iTurb) + J = J + 1 + + rRef = m%BodyList(m%CpldBodyIs(l,iTurb))%r6 ! for now set reference position as per input file <<< + !OrMatRef = + + CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2) ! defaults to identity orientation matrix + !TODO: >>> should also maybe set reference orientation (which might make part of a couple lines down redundant) <<< + + ! calculate initial point relative position, adjusted due to initial platform translations + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) = InitInp%PtfmInit(1:3,iTurb) - rRef(1:3) + + OrMat2 = MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6)))) ! combine the Body's relative orientation with the turbine's initial orientation + u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the body <<< + + ! set absolute initial positions in MoorDyn + m%BodyList(m%CpldBodyIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + m%BodyList(m%CpldBodyIs(l,iTurb))%r6(4:6) = EulerExtract(MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6))))) ! apply rotation from PtfmInit onto input file's body orientation to get its true initial orientation + + CALL MeshConstructElement(u%CoupledKinematics(iTurb), ELEMENT_POINT, ErrStat2, ErrMsg2, J) ! set node as point element + + ! lastly, do this to initialize any attached Rods or Points and set their positions + CALL Body_InitializeUnfree( m%BodyList(m%CpldBodyIs(l,iTurb)), m ) + + END DO + + DO l = 1,p%nCpldRods(iTurb) ! keeping this one simple for now, positioning at whatever is specified in input file <<<<< should change to glue code! + J = J + 1 + + rRef = m%RodList(m%CpldRodIs(l,iTurb))%r6 ! for now set reference position as per input file <<< + OrMatRef = TRANSPOSE( m%RodList(m%CpldRodIs(l,iTurb))%OrMat ) ! for now set reference orientation as per input file <<< + CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2, OrMatRef) ! assign the reference position and orientation + + ! calculate initial point relative position, adjusted due to initial platform rotations and translations <<< could convert to array math + u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) + u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) + u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) + + OrMat2 = MATMUL(OrMat, TRANSPOSE( EulerConstruct( rRef(4:6)))) ! combine the Rod's relative orientation with the turbine's initial orientation + u%CoupledKinematics(iTurb)%Orientation(:,:,J) = OrMat2 ! set the result as the current orientation of the rod <<< + + ! set absolute initial positions in MoorDyn + m%RodList(m%CpldRodIs(l,iTurb))%r6(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + m%RodList(m%CpldRodIs(l,iTurb))%r6(4:6) = EulerExtract(MATMUL(OrMat, OrMatRef)) ! apply rotation from PtfmInit onto input file's rod orientation to get its true initial orientation + + ! >>> still need to set Rod initial orientations accounting for PtfmInit rotation <<< + + CALL MeshConstructElement(u%CoupledKinematics(iTurb), ELEMENT_POINT, ErrStat2, ErrMsg2, J) + + ! lastly, do this to set the attached line endpoint positions: + CALL Rod_SetKinematics(m%RodList(m%CpldRodIs(l,iTurb)), REAL(rRef,R8Ki), m%zeros6, m%zeros6, 0.0_DbKi, m) + END DO + + DO l = 1,p%nCpldCons(iTurb) ! keeping this one simple for now, positioning at whatever is specified by glue code <<< + J = J + 1 + + ! set reference position as per input file <<< what about turbine positions in array? + rRef(1:3) = m%ConnectList(m%CpldConIs(l,iTurb))%r + CALL MeshPositionNode(u%CoupledKinematics(iTurb), J, rRef(1:3), ErrStat2, ErrMsg2) + + ! calculate initial point relative position, adjusted due to initial platform rotations and translations <<< could convert to array math + u%CoupledKinematics(iTurb)%TranslationDisp(1,J) = InitInp%PtfmInit(1,iTurb) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) + u%CoupledKinematics(iTurb)%TranslationDisp(2,J) = InitInp%PtfmInit(2,iTurb) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) + u%CoupledKinematics(iTurb)%TranslationDisp(3,J) = InitInp%PtfmInit(3,iTurb) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) + + ! set absolute initial positions in MoorDyn + m%ConnectList(m%CpldConIs(l,iTurb))%r = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + + CALL MeshConstructElement(u%CoupledKinematics(iTurb), ELEMENT_POINT, ErrStat2, ErrMsg2, J) + + ! lastly, do this to set the attached line endpoint positions: + rRefDub = rRef(1:3) + CALL Connect_SetKinematics(m%ConnectList(m%CpldConIs(l,iTurb)), rRefDub, m%zeros6(1:3), m%zeros6(1:3), 0.0_DbKi, m) + END DO + + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + + ! if no coupled objects exist for this turbine, add a single dummy element to keep I/O interp/extrap routines happy + if (J == 0) then + rRef = 0.0_DbKi ! position at PRP + CALL MeshPositionNode(u%CoupledKinematics(iTurb), 1, rRef, ErrStat2, ErrMsg2) + CALL MeshConstructElement(u%CoupledKinematics(iTurb), ELEMENT_POINT, ErrStat2, ErrMsg2, 1) + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + end if + + ! set velocities/accelerations of all mesh nodes to zero + u%CoupledKinematics(iTurb)%TranslationVel = 0.0_ReKi + u%CoupledKinematics(iTurb)%TranslationAcc = 0.0_ReKi + u%CoupledKinematics(iTurb)%RotationVel = 0.0_ReKi + u%CoupledKinematics(iTurb)%RotationAcc = 0.0_ReKi + + CALL MeshCommit ( u%CoupledKinematics(iTurb), ErrStat2, ErrMsg ) + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + + ! copy the input fairlead kinematics mesh to make the output mesh for fairlead loads, PtFairleadLoad + CALL MeshCopy ( SrcMesh = u%CoupledKinematics(iTurb), DestMesh = y%CoupledLoads(iTurb), & + CtrlCode = MESH_SIBLING, IOS = COMPONENT_OUTPUT, & + Force = .TRUE., Moment = .TRUE., ErrStat = ErrStat2, ErrMess=ErrMsg2 ) + + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + + end do ! iTurb + + ! >>>>>> ensure the output mesh includes all elements from u%(Farm)CoupledKinematics, OR make a seperate array of output meshes for each turbine <<<<<<<<< + + + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + + + ! ----------------------------- Arrays for active tensioning --------------------------- + + ! size active tensioning inputs arrays based on highest channel number read from input file for now <<<<<<< + + ! find the highest channel number + N = 0 + DO I = 1, p%NLines + IF ( m%LineList(I)%CtrlChan > N ) then + N = m%LineList(I)%CtrlChan + END IF + END DO + + ! note: it would be nice to just have input arrays of the number of control channels used, rather than from 1 up to N (the highest CtrlChan) + + ! allocate the input arrays (if any requested) + if (N > 0) then + call AllocAry( u%DeltaL, N, 'u%DeltaL', ErrStat2, ErrMsg2 ) + call CheckError( ErrStat2, ErrMsg2 ) + if (ErrStat >= AbortErrLev) return + u%DeltaL = 0.0_ReKi + call AllocAry( u%DeltaLdot, N, 'u%DeltaLdot', ErrStat2, ErrMsg2 ) + call CheckError( ErrStat2, ErrMsg2 ) + if (ErrStat >= AbortErrLev) return + u%DeltaLdot = 0.0_ReKi + call AllocAry( InitOut%CableCChanRqst, N, 'CableCChanRqst', ErrStat2, ErrMsg2 ) + call CheckError( ErrStat2, ErrMsg2 ) + if (ErrStat >= AbortErrLev) return + InitOut%CableCChanRqst = .FALSE. ! Initialize to false + do J=1,p%NLines + if (m%LineList(J)%CtrlChan > 0) InitOut%CableCChanRqst(m%LineList(J)%CtrlChan) = .TRUE. ! set the flag of the corresponding channel to true + enddo + endif + + + ! >>> set up wave stuff here??? <<< + + + m%WaveTi = 1 ! set initial wave grid time interpolation index to 1 to start with + + + ! Frmt = '(A10,'//TRIM(Int2LStr(p%NumOuts))//'(A1,A12))' + ! + ! WRITE(p%MDUnOut,Frmt, IOSTAT=ErrStat2) TRIM( 'Time' ), ( p%Delim, TRIM( p%OutParam(I)%Name), I=1,p%NumOuts ) + ! + ! WRITE(p%MDUnOut,Frmt) TRIM( '(s)' ), ( p%Delim, TRIM( p%OutParam(I)%Units ), I=1,p%NumOuts ) + ! + ! + ! + ! ! Write the output parameters to the file + ! + ! Frmt = '(F10.4,'//TRIM(Int2LStr(p%NumOuts))//'(A1,e10.4))' + ! + ! WRITE(p%MDUnOut,Frmt) Time, ( p%Delim, y%WriteOutput(I), I=1,p%NumOuts ) + + + + ! ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + + ! if any of the coupled objects need initialization steps, that should have been taken care of already <<<< + + + ! initialize objects with states, writing their initial states to the master state vector (x%states) + + + !TODO: apply any initial adjustment of line length from active tensioning <<<<<<<<<<<< + ! >>> maybe this should be skipped <<<< + + + ! Go through Bodys and write the coordinates to the state vector + DO l = 1,p%nFreeBodies + CALL Body_Initialize(m%BodyList(m%FreeBodyIs(l)), x%states(m%BodyStateIs1(l) : m%BodyStateIsN(l)), m) + END DO + + ! Go through independent (including pinned) Rods and write the coordinates to the state vector + DO l = 1,p%nFreeRods + CALL Rod_Initialize(m%RodList(m%FreeRodIs(l)), x%states(m%RodStateIs1(l):m%RodStateIsN(l)), m) + END DO + + ! Go through independent connections (Connects) and write the coordinates to the state vector and set positions of attached line ends + DO l = 1, p%nFreeCons + CALL Connect_Initialize(m%ConnectList(m%FreeConIs(l)), x%states(m%ConStateIs1(l) : m%conStateIsN(l)), m) + END DO + + + ! Lastly, go through lines and initialize internal node positions using quasi-static model + DO l = 1, p%NLines + + N = m%LineList(l)%N ! for convenience + + ! ! set end node positions and velocities from connect objects + ! m%LineList(l)%r(:,N) = m%ConnectList(m%LineList(l)%FairConnect)%r + ! m%LineList(l)%r(:,0) = m%ConnectList(m%LineList(l)%AnchConnect)%r + ! m%LineList(l)%rd(:,N) = (/ 0.0, 0.0, 0.0 /) ! set anchor end velocities to zero + ! m%LineList(l)%rd(:,0) = (/ 0.0, 0.0, 0.0 /) ! set fairlead end velocities to zero + + ! set initial line internal node positions using quasi-static model or straight-line interpolation from anchor to fairlead + CALL Line_Initialize( m%LineList(l), m%LineTypeList(m%LineList(l)%PropsIdNum), p%rhoW , ErrStat2, ErrMsg2) + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + !IF (ErrStat >= ErrId_Warn) CALL WrScr(" Note: Catenary pre-solver was unsuccessful for one or more lines so started with linear node spacing instead.") ! make this statement more accurate + + IF (wordy > 2) print *, "Line ", l, " with NumSegs =", N + IF (wordy > 2) print *, "its states range from index ", m%LineStateIs1(l), " to ", m%LineStateIsN(l) + + ! assign the resulting internal node positions to the integrator initial state vector! (velocities leave at 0) + DO I = 1, N-1 +! print *, "I=", I + DO J = 1, 3 +! print*, J, " ... writing position state to index ", 1*(m%LineStateIs1(l) + 3*N-3 + 3*I-3 + J-1) + x%states(m%LineStateIs1(l) + 3*N-3 + 3*I-3 + J-1 ) = m%LineList(l)%r(J,I) ! assign position + x%states(m%LineStateIs1(l) + 3*I-3 + J-1 ) = 0.0_DbKi ! assign velocities (of zero) + END DO +! print *, m%LineList(l)%r(:,I) + END DO + + ! if using viscoelastic model, initialize the internal states + if (m%LineList(l)%ElasticMod == 2) then + do I = 1,N + x%states(m%LineStateIs1(l) + 6*N-6 + I-1) = m%LineList(l)%dl_1(I) ! should be zero + end do + end if + + + END DO !l = 1, p%NLines + + + + ! -------------------------------------------------------------------- + ! open output file(s) and write header lines + CALL MDIO_OpenOutput( MD_ProgDesc, p, m, InitOut, ErrStat2, ErrMsg2 ) + CALL CheckError( ErrStat2, ErrMsg2 ) + IF (ErrStat >= AbortErrLev) RETURN + ! -------------------------------------------------------------------- + + + IF (wordy > 2) THEN + print *,"Done setup of the system (before any dynamic relaxation. State vector is as follows:" + + DO I = 1, m%Nx + print *, x%states(I) + END DO + END IF + +! ! try writing output for troubleshooting purposes (TEMPORARY) +! CALL MDIO_WriteOutputs(-1.0_DbKi, p, m, y, ErrStat, ErrMsg) +! IF ( ErrStat >= AbortErrLev ) THEN +! ErrMsg = ' Error in MDIO_WriteOutputs: '//TRIM(ErrMsg) +! RETURN +! END IF +! END DO + + ! ------------------------------------------------------------------- + ! if log file, compute and write some object properties + ! ------------------------------------------------------------------- + if (p%writeLog > 1) then + + write(p%UnLog, '(A)' ) " Bodies:" + DO l = 1,p%nBodies + write(p%UnLog, '(A)' ) " Body"//trim(num2lstr(l))//":" + write(p%UnLog, '(A12, f12.4)') " mass: ", m%BodyList(l)%M(1,1) + END DO + + write(p%UnLog, '(A)' ) " Rods:" + DO l = 1,p%nRods + write(p%UnLog, '(A)' ) " Rod"//trim(num2lstr(l))//":" + ! m%RodList(l) + END DO + + write(p%UnLog, '(A)' ) " Points:" + DO l = 1,p%nFreeCons + write(p%UnLog, '(A)' ) " Point"//trim(num2lstr(l))//":" + ! m%ConnectList(l) + END DO + + write(p%UnLog, '(A)' ) " Lines:" + DO l = 1,p%nLines + write(p%UnLog, '(A)' ) " Line"//trim(num2lstr(l))//":" + ! m%LineList(l) + END DO + + end if + + + ! -------------------------------------------------------------------- + ! do dynamic relaxation to get ICs + ! -------------------------------------------------------------------- + + ! only do this if TMaxIC > 0 + if (InputFileDat%TMaxIC > 0.0_DbKi) then + + CALL WrScr(" Finalizing initial conditions using dynamic relaxation."//NewLine) ! newline because next line writes over itself + + ! boost drag coefficient of each line type <<<<<<<< does this actually do anything or do lines hold these coefficients??? + DO I = 1, p%nLineTypes + m%LineTypeList(I)%Cdn = m%LineTypeList(I)%Cdn * InputFileDat%CdScaleIC + m%LineTypeList(I)%Cdt = m%LineTypeList(I)%Cdt * InputFileDat%CdScaleIC ! <<<<< need to update this to apply to all objects' drag + END DO + + ! allocate array holding 10 latest fairlead tensions + ALLOCATE ( FairTensIC(p%nLines, 10), STAT = ErrStat2 ) + IF ( ErrStat2 /= ErrID_None ) THEN + CALL CheckError( ErrID_Fatal, ErrMsg2 ) + RETURN + END IF + + ! initialize fairlead tension memory at changing values so things start unconverged + DO J = 1,p%nLines + DO I = 1, 10 + FairTensIC(J,I) = I + END DO + END DO + + + ! round dt to integer number of time steps + NdtM = ceiling(InputFileDat%dtIC/p%dtM0) ! get number of mooring time steps to do based on desired time step size + dtM = InputFileDat%dtIC/real(NdtM, DbKi) ! adjust desired time step to satisfy dt with an integer number of time steps + + t = 0.0_DbKi ! start time at zero + + ! because TimeStep wants an array... + call MD_CopyInput( u, u_array(1), MESH_NEWCOPY, ErrStat2, ErrMsg2 ) ! make a size=1 array of inputs (since MD_RK2 expects an array to InterpExtrap) + call MD_CopyInput( u, u_interp, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) ! also make an inputs object to interpExtrap to + t_array(1) = t ! fill in the times "array" for u_array + + DO I = 1, ceiling(InputFileDat%TMaxIC/InputFileDat%dtIC) ! loop through IC gen time steps, up to maximum + + + !loop through line integration time steps + DO J = 1, NdtM ! for (double ts=t; ts<=t+ICdt-dts; ts+=dts) + + CALL MD_RK2(t, dtM, u_interp, u_array, t_array, p, x, xd, z, other, m, ErrStat2, ErrMsg2) + + ! check for NaNs - is this a good place/way to do it? + DO K = 1, m%Nx + IF (Is_NaN(x%states(K))) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' NaN state detected.' + EXIT + END IF + END DO + + IF (ErrStat == ErrID_Fatal) THEN + CALL WrScr("NaN detected at time "//TRIM(Num2LStr(t))//" during MoorDyn's dynamic relaxation process.") + IF (wordy > 1) THEN + print *, "Here is the state vector: " + print *, x%states + END IF + EXIT + END IF + + END DO ! J time steps + + ! ! integrate the EOMs one DTIC s time step + ! CALL TimeStep ( t, InputFileDat%dtIC, u_array, t_array, p, x, xd, z, other, m, ErrStat, ErrMsg ) + ! CALL CheckError( ErrStat2, ErrMsg2 ) + ! IF (ErrStat >= AbortErrLev) RETURN + + ! store new fairlead tension (and previous fairlead tensions for comparison) + DO l = 1, p%nLines + + DO K=0,8 ! we want to count down from 10 to 2 . + FairTensIC(l, 10-K) = FairTensIC(l, 9-K) ! this pushes stored values up in the array + END DO + + ! now store latest value of each line's fairlead (end B) tension + FairTensIC(l,1) = TwoNorm(m%LineList(l)%Fnet(:, m%LineList(l)%N)) + END DO + + + ! provide status message + ! bjj: putting this in a string so we get blanks to cover up previous values (if current string is shorter than previous one) + Message = ' t='//trim(Num2LStr(t))//' FairTen 1: '//trim(Num2LStr(FairTensIC(1,1)))// & + ', '//trim(Num2LStr(FairTensIC(1,2)))//', '//trim(Num2LStr(FairTensIC(1,3))) + CALL WrOver( Message ) + + ! check for convergence (compare current tension at each fairlead with previous 9 values) + IF (I > 9) THEN + + Converged = 1 + + ! check for non-convergence + + DO l = 1, p%nLines + DO K = 1,9 + IF ( abs( FairTensIC(l,K)/FairTensIC(l,K+1) - 1.0 ) > InputFileDat%threshIC ) THEN + Converged = 0 + EXIT + END IF + END DO + + IF (Converged == 0) EXIT ! make sure we exit this loop too + END DO + + IF (Converged == 1) THEN ! if we made it with all cases satisfying the threshold + CALL WrScr(' Fairlead tensions converged to '//trim(Num2LStr(100.0*InputFileDat%threshIC))//'% after '//trim(Num2LStr(t))//' seconds.') + EXIT ! break out of the time stepping loop + END IF + END IF + + IF (I == ceiling(InputFileDat%TMaxIC/InputFileDat%dtIC) ) THEN + CALL WrScr(' Fairlead tensions did not converge within TMaxIC='//trim(Num2LStr(InputFileDat%TMaxIC))//' seconds.') + !ErrStat = ErrID_Warn + !ErrMsg = ' MD_Init: ran dynamic convergence to TMaxIC without convergence' + END IF + + END DO ! I ... looping through time steps + + + + CALL MD_DestroyInput( u_array(1), ErrStat2, ErrMsg2 ) + + ! UNboost drag coefficient of each line type <<< + DO I = 1, p%nLineTypes + m%LineTypeList(I)%Cdn = m%LineTypeList(I)%Cdn / InputFileDat%CdScaleIC + m%LineTypeList(I)%Cdt = m%LineTypeList(I)%Cdt / InputFileDat%CdScaleIC + END DO + + end if ! InputFileDat%TMaxIC > 0 + + + p%dtCoupling = DTcoupling ! store coupling time step for use in updatestates + + other%dummy = 0 + xd%dummy = 0 + z%dummy = 0 + + if (InitInp%Linearize) then + call MD_Init_Jacobian(InitInp, p, u, y, m, InitOut, ErrStat2, ErrMsg2); if(Failed()) return + endif + + CALL WrScr(' MoorDyn initialization completed.') + + m%LastOutTime = -1.0_DbKi ! set to nonzero to ensure that output happens at the start of simulation at t=0 + + ! TODO: add feature for automatic water depth increase based on max anchor depth! + + CONTAINS + + + LOGICAL FUNCTION AllocateFailed(arrayName) + + CHARACTER(*), INTENT(IN ) :: arrayName ! The array name + + call SetErrStat(ErrStat2, "Error allocating space for "//trim(arrayName)//" array.", ErrStat, ErrMsg, 'MD_Init') + AllocateFailed = ErrStat2 >= AbortErrLev + if (AllocateFailed) call CleanUp() !<<<<<<<<<< need to fix this up + END FUNCTION AllocateFailed + + + LOGICAL FUNCTION Failed() + + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'MD_Init') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp() + END FUNCTION Failed + + + 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) + CHARACTER(1024) :: ErrMsg3 ! The error message (ErrMsg) ! Set error status/message; IF ( ErrID /= ErrID_None ) THEN @@ -516,29 +2250,54 @@ SUBROUTINE CheckError(ErrID,Msg) IF ( ErrStat >= AbortErrLev ) THEN - IF (ALLOCATED(m%FairIdList )) DEALLOCATE(m%FairIdList ) - IF (ALLOCATED(m%ConnIdList )) DEALLOCATE(m%ConnIdList ) - IF (ALLOCATED(m%LineStateIndList )) DEALLOCATE(m%LineStateIndList ) + IF (ALLOCATED(m%CpldConIs )) DEALLOCATE(m%CpldConIs ) + IF (ALLOCATED(m%FreeConIs )) DEALLOCATE(m%FreeConIs ) + IF (ALLOCATED(m%LineStateIs1 )) DEALLOCATE(m%LineStateIs1 ) + IF (ALLOCATED(m%LineStateIsN )) DEALLOCATE(m%LineStateIsN ) + IF (ALLOCATED(m%ConStateIs1 )) DEALLOCATE(m%ConStateIs1 ) + IF (ALLOCATED(m%ConStateIsN )) DEALLOCATE(m%ConStateIsN ) IF (ALLOCATED(x%states )) DEALLOCATE(x%states ) - IF (ALLOCATED(FairTensIC )) DEALLOCATE(FairTensIC ) + IF (ALLOCATED(FairTensIC )) DEALLOCATE(FairTensIC ) + + call CleanUp() ! make sure to close files END IF END IF END SUBROUTINE CheckError + SUBROUTINE CleanUp() + ! ErrStat = ErrID_Fatal + call MD_DestroyInputFileType( InputFileDat, ErrStat2, ErrMsg2 ) ! Ignore any error messages from this + IF (p%UnLog > 0_IntKi) CLOSE( p%UnLog ) ! Remove this when the log file is kept open during the full simulation + END SUBROUTINE + + !> If for some reason the file is truncated, it is possible to get into an infinite loop + !! in a while looking for the next section and accidentally overstep the end of the array + !! resulting in a segfault. This function will trap that issue and return a section break + CHARACTER(1024) function NextLine(i) + integer, intent(inout) :: i ! Current line number corresponding to contents of NextLine + i=i+1 ! Increment to line next line. + if (i>FileInfo_In%NumLines) then + NextLine="---" ! Set as a separator so we can escape some of the while loops + else + NextLine=trim(FileInfo_In%Lines(i)) + !TODO: add comment character recognition here? (discard any characters past a #) + endif + end function NextLine + END SUBROUTINE MD_Init - !============================================================================================== + !----------------------------------------------------------------------------------------====== - !============================================================================================== - SUBROUTINE MD_UpdateStates( t, n, u, utimes, p, x, xd, z, other, m, ErrStat, ErrMsg) + !----------------------------------------------------------------------------------------====== + SUBROUTINE MD_UpdateStates( t, n, u, t_array, p, x, xd, z, other, m, ErrStat, ErrMsg) REAL(DbKi) , INTENT(IN ) :: t INTEGER(IntKi) , INTENT(IN ) :: n TYPE(MD_InputType) , INTENT(INOUT) :: u(:) ! INTENT(INOUT) ! had to change this to INOUT - REAL(DbKi) , INTENT(IN ) :: utimes(:) + REAL(DbKi) , INTENT(IN ) :: t_array(:) TYPE(MD_ParameterType) , INTENT(IN ) :: p ! INTENT(IN ) TYPE(MD_ContinuousStateType) , INTENT(INOUT) :: x ! INTENT(INOUT) TYPE(MD_DiscreteStateType) , INTENT(INOUT) :: xd ! INTENT(INOUT) @@ -553,11 +2312,16 @@ SUBROUTINE MD_UpdateStates( t, n, u, utimes, p, x, xd, z, other, m, ErrStat, Err ! moved to TimeStep TYPE(MD_InputType) :: u_interp ! INTEGER(IntKi) :: nTime + + TYPE(MD_InputType) :: u_interp ! interpolated instantaneous input values to be calculated for each mooring time step - REAL(DbKi) :: t2 ! copy of time passed to TimeStep - + REAL(DbKi) :: t2 ! copy of time variable that will get advanced by the integrator (not sure this is necessary<<<) + REAL(DbKi) :: dtM ! actual mooring dynamics time step + INTEGER(IntKi) :: NdtM ! number of time steps to integrate through with RK2 + INTEGER(IntKi) :: I + INTEGER(IntKi) :: J - nTime = size(u) ! the number of times of input data provided? + nTime = size(u) ! the number of times of input data provided? <<<<<<< not used t2 = t @@ -568,29 +2332,90 @@ SUBROUTINE MD_UpdateStates( t, n, u, utimes, p, x, xd, z, other, m, ErrStat, Err ! IF (ErrStat >= AbortErrLev) RETURN ! ! ! interpolate input mesh to correct time -! CALL MD_Input_ExtrapInterp(u, utimes, u_interp, t, ErrStat2, ErrMsg2) +! CALL MD_Input_ExtrapInterp(u, t_array, u_interp, t, ErrStat2, ErrMsg2) ! CALL CheckError( ErrStat2, ErrMsg2 ) ! IF (ErrStat >= AbortErrLev) RETURN ! ! ! ! go through fairleads and apply motions from driver -! DO I = 1, p%NFairs +! DO I = 1, p%nCpldCons ! DO J = 1,3 -! m%ConnectList(m%FairIdList(I))%r(J) = u_interp%PtFairleadDisplacement%Position(J,I) + u_interp%PtFairleadDisplacement%TranslationDisp(J,I) -! m%ConnectList(m%FairIdList(I))%rd(J) = u_interp%PtFairleadDisplacement%TranslationVel(J,I) ! is this right? <<< +! m%ConnectList(m%CpldConIs(I))%r(J) = u_interp%PtFairleadDisplacement%Position(J,I) + u_interp%PtFairleadDisplacement%TranslationDisp(J,I) +! m%ConnectList(m%CpldConIs(I))%rd(J) = u_interp%PtFairleadDisplacement%TranslationVel(J,I) ! is this right? <<< ! END DO ! END DO ! - ! call function that loops through mooring model time steps - CALL TimeStep ( t2, p%dtCoupling, u, utimes, p, x, xd, z, other, m, ErrStat2, ErrMsg2 ) - CALL CheckError( ErrStat2, ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN - ! clean up input interpolation stuff - ! moved to TimeStep CALL MD_DestroyInput(u_interp, ErrStat, ErrMsg) +! ! call function that loops through mooring model time steps +! CALL TimeStep ( t2, p%dtCoupling, u, t_array, p, x, xd, z, other, m, ErrStat2, ErrMsg2 ) +! CALL CheckError( ErrStat2, ErrMsg2 ) +! IF (ErrStat >= AbortErrLev) RETURN + + + ! create space for arrays/meshes in u_interp ... is it efficient to do this every time step??? + CALL MD_CopyInput(u(1), u_interp, MESH_NEWCOPY, ErrStat, ErrMsg) + + + ! round dt to integer number of time steps <<<< should this be calculated only once, up front? + NdtM = ceiling(p%dtCoupling/p%dtM0) ! get number of mooring time steps to do based on desired time step size + dtM = p%dtCoupling/REAL(NdtM,DbKi) ! adjust desired time step to satisfy dt with an integer number of time steps + + + !loop through line integration time steps + DO I = 1, NdtM ! for (double ts=t; ts<=t+ICdt-dts; ts+=dts) + + CALL MD_RK2(t2, dtM, u_interp, u, t_array, p, x, xd, z, other, m, ErrStat2, ErrMsg2) + + + ! check for NaNs - is this a good place/way to do it? + DO J = 1, m%Nx + IF (Is_NaN(x%states(J))) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' NaN state detected.' + EXIT + END IF + END DO + + IF (ErrStat == ErrID_Fatal) THEN + CALL WrScr("NaN detected at time "//TRIM(Num2LStr(t2))//" in MoorDyn.") + IF (wordy > 1) THEN + print *, ". Here is the state vector: " + print *, x%states + END IF + EXIT + END IF + + END DO ! I time steps + + + ! destroy dxdt and x2, and u_interp + !CALL MD_DestroyContState( dxdt, ErrStat, ErrMsg) + !CALL MD_DestroyContState( x2, ErrStat, ErrMsg) + CALL MD_DestroyInput(u_interp, ErrStat, ErrMsg) + IF ( ErrStat /= ErrID_None ) THEN + ErrMsg = ' Error destroying dxdt or x2.' + END IF + ! CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'MD_UpdateStates') + + ! check for NaNs - is this a good place/way to do it? + DO J = 1, m%Nx + IF (Is_NaN(x%states(J))) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' NaN state detected.' + EXIT + END IF + END DO + + IF (ErrStat == ErrID_Fatal) THEN + CALL WrScr("NaN detected at time "//TRIM(Num2LStr(t2))//" in MoorDyn.") + IF (wordy > 1) THEN + print *, ". Here is the state vector: " + print *, x%states + END IF + END IF CONTAINS @@ -618,11 +2443,11 @@ SUBROUTINE CheckError(ErrId, Msg) END SUBROUTINE CheckError END SUBROUTINE MD_UpdateStates - !======================================================================================== + !---------------------------------------------------------------------------------------- - !======================================================================================== + !---------------------------------------------------------------------------------------- SUBROUTINE MD_CalcOutput( t, u, p, x, xd, z, other, y, m, ErrStat, ErrMsg ) REAL(DbKi) , INTENT(IN ) :: t @@ -637,46 +2462,148 @@ SUBROUTINE MD_CalcOutput( t, u, p, x, xd, z, other, y, m, ErrStat, ErrMsg ) INTEGER(IntKi) , INTENT(INOUT) :: ErrStat CHARACTER(*) , INTENT(INOUT) :: ErrMsg - TYPE(MD_ContinuousStateType) :: dxdt ! time derivatives of continuous states (initialized in CalcContStateDeriv) - INTEGER(IntKi) :: I ! counter - INTEGER(IntKi) :: J ! counter - - INTEGER(IntKi) :: ErrStat2 ! Error status of the operation - CHARACTER(ErrMsgLen) :: ErrMsg2 ! Error message if ErrStat2 /= ErrID_None + ! TYPE(MD_ContinuousStateType) :: dxdt ! time derivatives of continuous states (initialized in CalcContStateDeriv) + INTEGER(IntKi) :: I ! counter + INTEGER(IntKi) :: J ! counter + INTEGER(IntKi) :: K ! counter + INTEGER(IntKi) :: l ! index used for objects + INTEGER(IntKi) :: iTurb ! counter + + Real(DbKi) :: F6net(6) ! net force and moment calculated on coupled objects + + INTEGER(IntKi) :: ErrStat2 ! Error status of the operation + CHARACTER(ErrMsgLen) :: ErrMsg2 ! Error message if ErrStat2 /= ErrID_None ! below updated to make sure outputs are current (based on provided x and u) - similar to what's in UpdateStates - ! go through fairleads and apply motions from driver - 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) = u%PtFairleadDisplacement%TranslationVel(J,I) ! is this right? <<< - END DO - END DO + ! ! go through fairleads and apply motions from driver + ! DO I = 1, p%nCpldCons + ! DO J = 1,3 + ! m%ConnectList(m%CpldConIs(I))%r(J) = u%CoupledKinematics%Position(J,I) + u%CoupledKinematics%TranslationDisp(J,I) + ! m%ConnectList(m%CpldConIs(I))%rd(J) = u%CoupledKinematics%TranslationVel(J,I) ! is this right? <<< + ! END DO + ! END DO + + + ! ! go through nodes and apply wave kinematics from driver (if water kinematics were passed in at each node in future) + ! IF (p%WaterKin > 0) THEN + ! + ! J=0 + ! ! Body reference point coordinates + ! DO I = 1, p%nBodies + ! J = J + 1 + ! m%BodyList(I)%U = u%U(:,J) + ! m%BodyList(I)%Ud = u%Ud(:,J) + ! m%BodyList(I)%zeta = u%zeta(J) + ! END DO + ! ! Rod node coordinates + ! DO I = 1, p%nRods + ! DO K = 0,m%RodList(I)%N + ! J = J + 1 + ! m%RodList(I)%U (:,K) = u%U(:,J) + ! m%RodList(I)%Ud(:,K) = u%Ud(:,J) + ! m%RodList(I)%zeta(K) = u%zeta(J) + ! m%RodList(I)%PDyn(K) = u%PDyn(J) + ! END DO + ! END DO + ! ! Point reference point coordinates + ! DO I = 1, p%nConnects + ! J = J + 1 + ! m%ConnectList(I)%U = u%U(:,J) + ! m%ConnectList(I)%Ud = u%Ud(:,J) + ! m%ConnectList(I)%zeta = u%zeta(J) + ! END DO + ! ! Line internal node coordinates + ! DO I = 1, p%nLines + ! DO K = 1, m%LineList(I)%N-1 + ! J = J + 1 + ! m%LineList(I)%U (:,K) = u%U(:,J) + ! m%LineList(I)%Ud(:,K) = u%Ud(:,J) + ! m%LineList(I)%zeta(K) = u%zeta(J) + ! END DO + ! END DO + ! + ! END IF + + ! call CalcContStateDeriv in order to run model and calculate dynamics with provided x and u - CALL MD_CalcContStateDeriv( t, u, p, x, xd, z, other, m, dxdt, ErrStat, ErrMsg ) - - - ! assign net force on fairlead Connects to the output mesh - DO i = 1, p%NFairs - DO J=1,3 - y%PtFairleadLoad%Force(J,I) = m%ConnectList(m%FairIdList(I))%Ftot(J) + CALL MD_CalcContStateDeriv( t, u, p, x, xd, z, other, m, m%xdTemp, ErrStat, ErrMsg ) + + ! ! assign net force on fairlead Connects to the fairlead force output mesh + ! DO i = 1, p%nCpldCons + ! DO J=1,3 + ! y%PtFairleadLoad%Force(J,I) = m%ConnectList(m%CpldConIs(I))%Fnet(J) + ! END DO + ! END DO + + ! now that forces have been updated, write them to the output mesh + + do iTurb = 1,p%nTurbines + + J = 0 ! mesh index + DO l = 1,p%nCpldBodies(iTurb) + J = J + 1 + CALL Body_GetCoupledForce(m%BodyList(m%CpldBodyIs(l,iTurb)), F6net, m, p) + y%CoupledLoads(iTurb)%Force( :,J) = F6net(1:3) + y%CoupledLoads(iTurb)%Moment(:,J) = F6net(4:6) END DO - END DO - + + DO l = 1,p%nCpldRods(iTurb) + J = J + 1 + CALL Rod_GetCoupledForce(m%RodList(m%CpldRodIs(l,iTurb)), F6net, m, p) + y%CoupledLoads(iTurb)%Force( :,J) = F6net(1:3) + y%CoupledLoads(iTurb)%Moment(:,J) = F6net(4:6) + END DO + + DO l = 1,p%nCpldCons(iTurb) + J = J + 1 + CALL Connect_GetCoupledForce(m%ConnectList(m%CpldConIs(l,iTurb)), F6net(1:3), m, p) + y%CoupledLoads(iTurb)%Force(:,J) = F6net(1:3) + END DO + + end do + + ! ! write all node positions to the node positons output array (if water kinematics were passed in at each node in future) + ! ! go through the nodes and fill in the data (this should maybe be turned into a global function) + ! J=0 + ! ! Body reference point coordinates + ! DO I = 1, p%nBodies + ! J = J + 1 + ! y%rAll(:,J) = m%BodyList(I)%r6(1:3) + ! END DO + ! ! Rod node coordinates + ! DO I = 1, p%nRods + ! DO K = 0,m%RodList(I)%N + ! J = J + 1 + ! y%rAll(:,J) = m%RodList(I)%r(:,K) + ! END DO + ! END DO + ! ! Point reference point coordinates + ! DO I = 1, p%nConnects + ! J = J + 1 + ! y%rAll(:,J) = m%ConnectList(I)%r + ! END DO + ! ! Line internal node coordinates + ! DO I = 1, p%nLines + ! DO K = 1, m%LineList(I)%N-1 + ! J = J + 1 + ! y%rAll(:,J) = m%LineList(I)%r(:,K) + ! END DO + ! END DO + ! calculate outputs (y%WriteOutput) for glue code and write any m outputs to MoorDyn output files - CALL MDIO_WriteOutputs(t, p, m, y, ErrStat2, ErrMsg2) + CALL MDIO_WriteOutputs(REAL(t,DbKi) , p, m, y, ErrStat2, ErrMsg2) CALL CheckError(ErrStat2, 'In MDIO_WriteOutputs: '//trim(ErrMsg2)) IF ( ErrStat >= AbortErrLev ) RETURN - ! destroy dxdt - CALL MD_DestroyContState( dxdt, ErrStat2, ErrMsg2) - CALL CheckError(ErrStat2, 'When destroying dxdt: '//trim(ErrMsg2)) - IF ( ErrStat >= AbortErrLev ) RETURN + ! ! destroy dxdt + ! CALL MD_DestroyContState( dxdt, ErrStat2, ErrMsg2) + ! CALL CheckError(ErrStat2, 'When destroying dxdt: '//trim(ErrMsg2)) + ! IF ( ErrStat >= AbortErrLev ) RETURN @@ -697,18 +2624,18 @@ SUBROUTINE CheckError(ErrId, Msg) CALL WrScr( ErrMsg ) ! do this always or only if warning level? <<<<<<<<<<<<<<<<<<<<<< probably should remove all instances - IF( ErrStat > ErrID_Warn ) THEN - CALL MD_DestroyContState( dxdt, ErrStat2, ErrMsg2) - END IF + ! IF( ErrStat > ErrID_Warn ) THEN + ! CALL MD_DestroyContState( dxdt, ErrStat2, ErrMsg2) + ! END IF END IF END SUBROUTINE CheckError END SUBROUTINE MD_CalcOutput - !============================================================================================= + !---------------------------------------------------------------------------------------- - !============================================================================================= + !---------------------------------------------------------------------------------------- SUBROUTINE MD_CalcContStateDeriv( t, u, p, x, xd, z, other, m, dxdt, ErrStat, ErrMsg ) ! Tight coupling routine for computing derivatives of continuous states ! this is modelled off what used to be subroutine DoRHSmaster @@ -721,430 +2648,279 @@ SUBROUTINE MD_CalcContStateDeriv( t, u, p, x, xd, z, other, m, dxdt, ErrStat, Er TYPE(MD_ConstraintStateType), INTENT(IN ) :: z ! Constraint states at t TYPE(MD_OtherStateType), INTENT(IN ) :: other ! Other states at t TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! misc/optimization variables - TYPE(MD_ContinuousStateType), INTENT( OUT) :: dxdt ! Continuous state derivatives at t + TYPE(MD_ContinuousStateType), INTENT(INOUT) :: 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 INTEGER(IntKi) :: L ! index + INTEGER(IntKi) :: I ! index INTEGER(IntKi) :: J ! index INTEGER(IntKi) :: K ! index + INTEGER(IntKi) :: iTurb ! index INTEGER(IntKi) :: Istart ! start index of line/connect in state vector INTEGER(IntKi) :: Iend ! end index of line/connect in state vector - + REAL(DbKi) :: temp(3) ! temporary for passing kinematics + + REAL(DbKi) :: r6_in(6) ! temporary for passing kinematics + REAL(DbKi) :: v6_in(6) ! temporary for passing kinematics + REAL(DbKi) :: a6_in(6) ! temporary for passing kinematics + REAL(DbKi) :: r_in(3) ! temporary for passing kinematics + REAL(DbKi) :: rd_in(3) ! temporary for passing kinematics + REAL(DbKi) :: a_in(3) ! temporary for passing kinematics + + INTEGER(IntKi) :: ErrStat2 ! Error status of the operation + CHARACTER(ErrMsgLen) :: ErrMsg2 ! Error message if ErrStat2 /= ErrID_None + character(*), parameter :: RoutineName = 'MD_CalcContStateDeriv' + ! Initialize ErrStat ErrStat = ErrID_None ErrMsg = "" - ! allocations of dxdt (as in SubDyn. "INTENT(OUT) automatically deallocates the arrays on entry, we have to allocate them here" is this right/efficient?) - ALLOCATE ( dxdt%states(size(x%states)), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating dxdt%states array.' - RETURN + ! allocate dxdt if not already allocated (e.g. if called for linearization) + IF (.NOT. ALLOCATED(dxdt%states) ) THEN + CALL AllocAry( dxdt%states, SIZE(x%states), 'dxdt%states', ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF ( ErrStat >= AbortErrLev ) RETURN END IF - - ! clear connection force and mass values + ! clear connection force and mass values updateFairlead( t ); <<<< manually set anchored connection stuff for now here + r6_in = 0.0_DbKi + v6_in = 0.0_DbKi + CALL Body_SetKinematics(m%GroundBody, r6_in, v6_in, m%zeros6, t, m) + + ! ---------------------------------- coupled things --------------------------------- + ! Apply displacement and velocity terms here. Accelerations will be considered to calculate inertial loads at the end. + ! Note: TurbineRefPos is to offset into farm's true global reference based on turbine X and Y reference positions (these should be 0 for regular FAST use) + - ! update fairlead positions for instantaneous values (fixed 2015-06-22) - DO K = 1, p%NFairs - DO J = 1,3 - m%ConnectList(m%FairIdList(K))%r(J) = u%PtFairleadDisplacement%Position(J,K) + u%PtFairleadDisplacement%TranslationDisp(J,K) - m%ConnectList(m%FairIdList(K))%rd(J) = u%PtFairleadDisplacement%TranslationVel(J,K) ! is this right? <<< + DO iTurb = 1, p%nTurbines + + J = 0 ! J is the index of the coupling points in the input mesh CoupledKinematics + ! any coupled bodies (type -1) + DO l = 1,p%nCpldBodies(iTurb) + J = J + 1 + r6_in(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + !r6_in(4:6) = EulerExtract( TRANSPOSE( u%CoupledKinematics(iTurb)%Orientation(:,:,J) ) ) + r6_in(4:6) = EulerExtract( u%CoupledKinematics(iTurb)%Orientation(:,:,J) ) ! <<< changing back + v6_in(1:3) = u%CoupledKinematics(iTurb)%TranslationVel(:,J) + v6_in(4:6) = u%CoupledKinematics(iTurb)%RotationVel(:,J) + a6_in(1:3) = u%CoupledKinematics(iTurb)%TranslationAcc(:,J) + a6_in(4:6) = u%CoupledKinematics(iTurb)%RotationAcc(:,J) + + CALL Body_SetKinematics(m%BodyList(m%CpldBodyIs(l,iTurb)), r6_in, v6_in, a6_in, t, m) END DO - END DO - + + ! any coupled rods (type -1 or -2) note, rotations ignored if it's a pinned rod + DO l = 1,p%nCpldRods(iTurb) + J = J + 1 + + r6_in(1:3) = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + r6_in(4:6) = MATMUL( u%CoupledKinematics(iTurb)%Orientation(:,:,J) , (/0.0, 0.0, 1.0/) ) ! <<<< CHECK ! adjustment because rod's rotational entries are a unit vector, q + v6_in(1:3) = u%CoupledKinematics(iTurb)%TranslationVel(:,J) + v6_in(4:6) = u%CoupledKinematics(iTurb)%RotationVel(:,J) + a6_in(1:3) = u%CoupledKinematics(iTurb)%TranslationAcc(:,J) + a6_in(4:6) = u%CoupledKinematics(iTurb)%RotationAcc(:,J) + + CALL Rod_SetKinematics(m%RodList(m%CpldRodIs(l,iTurb)), r6_in, v6_in, a6_in, t, m) + + END DO + + ! any coupled points (type -1) + DO l = 1, p%nCpldCons(iTurb) + J = J + 1 + + r_in = u%CoupledKinematics(iTurb)%Position(:,J) + u%CoupledKinematics(iTurb)%TranslationDisp(:,J) + p%TurbineRefPos(:,iTurb) + rd_in = u%CoupledKinematics(iTurb)%TranslationVel(:,J) + a_in(1:3) = u%CoupledKinematics(iTurb)%TranslationAcc(:,J) + CALL Connect_SetKinematics(m%ConnectList(m%CpldConIs(l,iTurb)), r_in, rd_in, a_in, t, m) + + !print "(f8.5, f12.6, f12.6, f8.4, f8.4, f8.4, f8.4)", t, r_in(1), r_in(3), rd_in(1), rd_in(3), a_in(1), a_in(3) + + END DO + + end do ! iTurb + + + ! >>>>> in theory I would repeat the above but for each turbine in the case of array use here <<<<< + ! DO I = 1,p%nTurbines + ! J = 0? + ! other logic? + ! nvm: need to get kinematics from entries in u%FarmCoupledKinematics(I)%Position etc. + ! nvm: using knowledge of p%meshIndex or something + ! in theory might also support individual line tensioning control commands from turbines this way too, or maybe it's supercontroller level (not a short term problem though) + + ! apply line length changes from active tensioning if applicable DO L = 1, p%NLines IF (m%LineList(L)%CtrlChan > 0) then - + ! do a bounds check to prohibit excessive segment length changes (until a method to add/remove segments is created) IF ( u%DeltaL(m%LineList(L)%CtrlChan) > m%LineList(L)%UnstrLen / m%LineList(L)%N ) then ErrStat = ErrID_Fatal ErrMsg = ' Active tension command will make a segment longer than the limit of twice its original length.' - print *, u%DeltaL(m%LineList(L)%CtrlChan), " is an increase of more than ", (m%LineList(L)%UnstrLen / m%LineList(L)%N) - print *, u%DeltaL - print*, m%LineList(L)%CtrlChan + call WrScr(trim(Num2LStr(u%DeltaL(m%LineList(L)%CtrlChan)))//" is an increase of more than "//trim(Num2LStr(m%LineList(L)%UnstrLen / m%LineList(L)%N))) + IF (wordy > 0) print *, u%DeltaL + IF (wordy > 0) print*, m%LineList(L)%CtrlChan RETURN END IF IF ( u%DeltaL(m%LineList(L)%CtrlChan) < -0.5 * m%LineList(L)%UnstrLen / m%LineList(L)%N ) then ErrStat = ErrID_Fatal ErrMsg = ' Active tension command will make a segment shorter than the limit of half its original length.' - print *, u%DeltaL(m%LineList(L)%CtrlChan), " is a reduction of more than half of ", (m%LineList(L)%UnstrLen / m%LineList(L)%N) - print *, u%DeltaL - print*, m%LineList(L)%CtrlChan + call WrScr(trim(Num2LStr(u%DeltaL(m%LineList(L)%CtrlChan)))//" is a reduction of more than half of "//trim(Num2LStr(m%LineList(L)%UnstrLen / m%LineList(L)%N))) + IF (wordy > 0) print *, u%DeltaL + IF (wordy > 0) print*, m%LineList(L)%CtrlChan RETURN END IF - + ! for now this approach only acts on the fairlead end segment, and assumes all segment lengths are otherwise equal size m%LineList(L)%l( m%LineList(L)%N) = m%LineList(L)%UnstrLen/m%LineList(L)%N + u%DeltaL(m%LineList(L)%CtrlChan) m%LineList(L)%ld(m%LineList(L)%N) = u%DeltaLdot(m%LineList(L)%CtrlChan) END IF END DO - - ! do Line force and acceleration calculations, also add end masses/forces to respective Connects - DO L = 1, p%NLines - Istart = m%LineStateIndList(L) - Iend = Istart + 6*(m%LineList(L)%N - 1) - 1 - CALL DoLineRHS(x%states(Istart:Iend), dxdt%states(Istart:Iend), t, m%LineList(L), & - m%LineTypeList(m%LineList(L)%PropsIdNum), & - m%ConnectList(m%LineList(L)%FairConnect)%Ftot, m%ConnectList(m%LineList(L)%FairConnect)%Mtot, & - m%ConnectList(m%LineList(L)%AnchConnect)%Ftot, m%ConnectList(m%LineList(L)%AnchConnect)%Mtot ) + + + ! ! go through nodes and apply wave kinematics from driver (if water kinematics were passed in at each node in future) + ! IF (p%WaterKin > 0) THEN + ! + ! J=0 + ! ! Body reference point coordinates + ! DO I = 1, p%nBodies + ! J = J + 1 + ! m%BodyList(I)%U = u%U(:,J) + ! m%BodyList(I)%Ud = u%Ud(:,J) + ! m%BodyList(I)%zeta = u%zeta(J) + ! END DO + ! ! Rod node coordinates + ! DO I = 1, p%nRods + ! DO K = 0,m%RodList(I)%N + ! J = J + 1 + ! m%RodList(I)%U (:,K) = u%U(:,J) + ! m%RodList(I)%Ud(:,K) = u%Ud(:,J) + ! m%RodList(I)%zeta(K) = u%zeta(J) + ! m%RodList(I)%PDyn(K) = u%PDyn(J) + ! END DO + ! END DO + ! ! Point reference point coordinates + ! DO I = 1, p%nConnects + ! J = J + 1 + ! m%ConnectList(I)%U = u%U(:,J) + ! m%ConnectList(I)%Ud = u%Ud(:,J) + ! m%ConnectList(I)%zeta = u%zeta(J) + ! END DO + ! ! Line internal node coordinates + ! DO I = 1, p%nLines + ! DO K = 1, m%LineList(I)%N-1 + ! J = J + 1 + ! m%LineList(I)%U (:,K) = u%U(:,J) + ! m%LineList(I)%Ud(:,K) = u%Ud(:,J) + ! m%LineList(I)%zeta(K) = u%zeta(J) + ! END DO + ! END DO + ! + ! END IF + + + ! independent or semi-independent things with their own states... + + ! give Bodies latest state variables (kinematics will also be assigned to dependent connections and rods, and thus line ends) + DO l = 1,p%nFreeBodies + CALL Body_SetState(m%BodyList(m%FreeBodyIs(l)), x%states(m%BodyStateIs1(l):m%BodyStateIsN(l)), t, m) END DO - - - ! perform connection force and mass calculations (done to all connects for sake of calculating fairlead/anchor loads) - DO L = 1, p%NConnects - ! add Connect's own forces including buoyancy and weight - m%ConnectList(L)%Ftot(1) =m%ConnectList(L)%Ftot(1) + m%ConnectList(L)%conFX - m%ConnectList(L)%Ftot(2) =m%ConnectList(L)%Ftot(2) + m%ConnectList(L)%conFY - m%ConnectList(L)%Ftot(3) =m%ConnectList(L)%Ftot(3) + m%ConnectList(L)%conFZ + m%ConnectList(L)%conV*p%rhoW*p%g - m%ConnectList(L)%conM*p%g - - ! add Connect's own mass - DO J = 1,3 - m%ConnectList(L)%Mtot(J,J) = m%ConnectList(L)%Mtot(J,J) + m%ConnectList(L)%conM - END DO - END DO ! L - - - ! do Connect acceleration calculations - changed to do only connect types - DO L = 1, p%NConns - Istart = L*6-5 - Iend = L*6 - CALL DoConnectRHS(x%states(Istart:Iend), dxdt%states(Istart:Iend), t, m%ConnectList(m%ConnIDList(L))) + + ! give independent or pinned rods' latest state variables (kinematics will also be assigned to attached line ends) + DO l = 1,p%nFreeRods + CALL Rod_SetState(m%RodList(m%FreeRodIs(l)), x%states(m%RodStateIs1(l):m%RodStateIsN(l)), t, m) END DO - - - CONTAINS - - - !====================================================================== - SUBROUTINE DoLineRHS (X, Xd, t, Line, LineProp, FairFtot, FairMtot, AnchFtot, AnchMtot) - - 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(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(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 - d = LineProp%d ! for convenience - rho = LineProp%w/(Pi/4.0*d*d) - - - - ! set end node positions and velocities from connect objects' states - DO J = 1, 3 - Line%r( J,N) = m%ConnectList(Line%FairConnect)%r(J) - Line%r( J,0) = m%ConnectList(Line%AnchConnect)%r(J) - Line%rd(J,N) = m%ConnectList(Line%FairConnect)%rd(J) - Line%rd(J,0) = m%ConnectList(Line%AnchConnect)%rd(J) - END DO - - ! set interior node positions and velocities - DO I = 1, N-1 - DO J = 1, 3 - Line%r( J,I) = X( 3*N-3 + 3*I-3 + J) ! r(J,I) = X[3*N-3 + 3*i-3 + J]; // get positions .. used to start from m%LineStateIndList(Line%IdNum) in whole state vector - Line%rd(J,I) = X( 3*I-3 + J) ! rd(J,I) = X[ 3*i-3 + J]; // get velocities - END DO - END DO - - ! calculate instantaneous (stretched) segment lengths and rates << should add catch here for if lstr is ever zero - DO I = 1, N - 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_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 - Line%lstrd(I) = Sum1/Line%lstr(I) ! segment stretched length rate of change - - ! Line%V(I) = Pi/4.0 * d*d*Line%l(I) !volume attributed to segment - END DO - - !calculate unit tangent vectors (q) for each node (including ends) note: I think these are pointing toward 0 rather than N! - CALL UnitVector(Line%q(:,0), Line%r(:,1), Line%r(:,0)) ! compute unit vector q - DO I = 1, N-1 - CALL UnitVector(Line%q(:,I), Line%r(:,I+1), Line%r(:,I-1)) ! compute unit vector q ... using adjacent two nodes! - END DO - CALL UnitVector(Line%q(:,N), Line%r(:,N), Line%r(:,N-1)) ! compute unit vector q - - - ! wave kinematics not implemented yet - - - !calculate mass (including added mass) matrix for each node - DO I = 0, N - IF (I==0) THEN - m_i = Pi/8.0 *d*d*Line%l(1)*rho - v_i = 0.5 *Line%V(1) - ELSE IF (I==N) THEN - m_i = pi/8.0 *d*d*Line%l(N)*rho; - v_i = 0.5*Line%V(N) - ELSE - m_i = pi/8.0 * d*d*rho*(Line%l(I) + Line%l(I+1)) - v_i = 0.5 *(Line%V(I) + Line%V(I+1)) - END IF - - DO J=1,3 - DO K=1,3 - IF (J==K) THEN - Line%M(K,J,I) = m_i + p%rhoW*v_i*( LineProp%Can*(1 - Line%q(J,I)*Line%q(K,I)) + LineProp%Cat*Line%q(J,I)*Line%q(K,I) ) - ELSE - Line%M(K,J,I) = p%rhoW*v_i*( LineProp%Can*(-Line%q(J,I)*Line%q(K,I)) + LineProp%Cat*Line%q(J,I)*Line%q(K,I) ) - END IF - END DO - END DO - - CALL Inverse3by3(Line%S(:,:,I), Line%M(:,:,I)) ! invert mass matrix - END DO - - - ! ------------------ CALCULATE FORCES ON EACH NODE ---------------------------- - - ! loop through the segments - DO I = 1, N - - ! line tension, inherently including possibility of dynamic length changes in l term - IF (Line%lstr(I)/Line%l(I) > 1.0) THEN - DO J = 1, 3 - Line%T(J,I) = LineProp%EA *( 1.0/Line%l(I) - 1.0/Line%lstr(I) ) * (Line%r(J,I)-Line%r(J,I-1)) - END DO - ELSE - DO J = 1, 3 - Line%T(J,I) = 0.0_DbKi ! cable can't "push" - END DO - END if - - ! line internal damping force based on line-specific BA value, including possibility of dynamic length changes in l and ld terms - DO J = 1, 3 - Line%Td(J,I) = Line%BA* ( Line%lstrd(I) - Line%lstr(I)*Line%ld(I)/Line%l(I) )/Line%l(I) * (Line%r(J,I)-Line%r(J,I-1)) / Line%lstr(I) - END DO - END DO - - - - ! loop through the nodes - DO I = 0, N - - !submerged weight (including buoyancy) - IF (I==0) THEN - Line%W(3,I) = Pi/8.0*d*d* Line%l(1)*(rho - p%rhoW) *(-p%g) ! assuming g is positive - ELSE IF (i==N) THEN - Line%W(3,I) = pi/8.0*d*d* Line%l(N)*(rho - p%rhoW) *(-p%g) - ELSE - Line%W(3,I) = pi/8.0*d*d* (Line%l(I)*(rho - p%rhoW) + Line%l(I+1)*(rho - p%rhoW) )*(-p%g) ! left in this form for future free surface handling - END IF - - !relative flow velocities - DO J = 1, 3 - Vi(J) = 0.0 - Line%rd(J,I) ! relative flow velocity over node -- this is where wave velicites would be added - END DO - - ! decomponse relative flow into components - 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 - SumSqVq = SumSqVq + Vq(J)*Vq(J) - SumSqVp = SumSqVp + Vp(J)*Vp(J) - END DO - MagVp = sqrt(SumSqVp) ! get magnitudes of flow components - MagVq = sqrt(SumSqVq) - - ! transverse and tangenential drag - IF (I==0) THEN - DO J = 1, 3 - Line%Dp(J,I) = 0.25*p%rhoW*LineProp%Cdn* d*Line%l(1) * MagVp * Vp(J) - Line%Dq(J,I) = 0.25*p%rhoW*LineProp%Cdt* Pi*d*Line%l(1) * MagVq * Vq(J) - END DO - ELSE IF (I==N) THEN - DO J = 1, 3 - Line%Dp(J,I) = 0.25*p%rhoW*LineProp%Cdn* d*Line%l(N) * MagVp * Vp(J); - Line%Dq(J,I) = 0.25*p%rhoW*LineProp%Cdt* Pi*d*Line%l(N) * MagVq * Vq(J) - END DO - ELSE - DO J = 1, 3 - Line%Dp(J,I) = 0.25*p%rhoW*LineProp%Cdn* d*(Line%l(I) + Line%l(I+1)) * MagVp * vp(J); - Line%Dq(J,I) = 0.25*p%rhoW*LineProp%Cdt* Pi*d*(Line%l(I) + Line%l(I+1)) * MagVq * vq(J); - END DO - END IF - - ! F-K force from fluid acceleration not implemented yet - - ! bottom contact (stiffness and damping, vertical-only for now) - updated Nov 24 for general case where anchor and fairlead ends may deal with bottom contact forces - - IF (Line%r(3,I) < -p%WtrDpth) THEN - IF (I==0) THEN - Line%B(3,I) = ( (-p%WtrDpth - Line%r(3,I))*p%kBot - Line%rd(3,I)*p%cBot) * 0.5*d*( Line%l(I+1) ) - ELSE IF (I==N) THEN - Line%B(3,I) = ( (-p%WtrDpth - Line%r(3,I))*p%kBot - Line%rd(3,I)*p%cBot) * 0.5*d*(Line%l(I) ) - ELSE - Line%B(3,I) = ( (-p%WtrDpth - Line%r(3,I))*p%kBot - Line%rd(3,I)*p%cBot) * 0.5*d*(Line%l(I) + Line%l(I+1) ) - - - - END IF - ELSE - Line%B(3,I) = 0.0_DbKi - END IF - - ! total forces - IF (I==0) THEN - DO J = 1, 3 - Line%F(J,I) = Line%T(J,1) + Line%Td(J,1) + Line%W(J,I) + Line%Dp(J,I) + Line%Dq(J,I) + Line%B(J,I) - END DO - ELSE IF (I==N) THEN - DO J = 1, 3 - Line%F(J,I) = -Line%T(J,N) - Line%Td(J,N) + Line%W(J,I) + Line%Dp(J,I) + Line%Dq(J,I) + Line%B(J,I) - END DO - ELSE - DO J = 1, 3 - Line%F(J,I) = Line%T(J,I+1) - Line%T(J,I) + Line%Td(J,I+1) - Line%Td(J,I) + Line%W(J,I) + Line%Dp(J,I) + Line%Dq(J,I) + Line%B(J,I) - END DO - END IF - - END DO ! I - done looping through nodes - - - ! loop through internal nodes and update their states - DO I=1, N-1 - DO J=1,3 - - ! calculate RHS constant (premultiplying force vector by inverse of mass matrix ... i.e. rhs = S*Forces) - 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 - - ! update states - Xd(3*N-3 + 3*I-3 + J) = X(3*I-3 + J); ! dxdt = V (velocities) - Xd( 3*I-3 + J) = Sum1 ! dVdt = RHS * A (accelerations) - - END DO ! J - END DO ! I - - - ! add force and mass of end nodes to the Connects they correspond to - DO J = 1,3 - FairFtot(J) = FairFtot(J) + Line%F(J,N) - AnchFtot(J) = AnchFtot(J) + Line%F(J,0) - DO K = 1,3 - FairMtot(K,J) = FairMtot(K,J) + Line%M(K,J,N) - AnchMtot(K,J) = AnchMtot(K,J) + Line%M(K,J,0) - END DO - END DO - - END SUBROUTINE DoLineRHS - !===================================================================== - - - !====================================================================== - 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(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 - - - !INTEGER(IntKi) :: I ! index of segments or nodes along line - INTEGER(IntKi) :: J ! index - INTEGER(IntKi) :: K ! index - 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 - ! added by the calling subroutine. The only thing left is any added mass or drag forces from the connection (e.g. float) - ! itself, which will be added below. - - - IF (EqualRealNos(t, 0.0_DbKi)) THEN ! this is old: with current IC gen approach, we skip the first call to the line objects, because they're set AFTER the call to the connects + ! give Connects (independent connections) latest state variable values (kinematics will also be assigned to attached line ends) + DO l = 1,p%nFreeCons + ! Print *, "calling SetState for free connection, con#", m%FreeConIs(l), " with state range: ", m%ConStateIs1(l), "-", m%ConStateIsN(l) + !K=K+1 + CALL Connect_SetState(m%ConnectList(m%FreeConIs(l)), x%states(m%ConStateIs1(l):m%ConStateIsN(l)), t, m) + END DO + + ! give Lines latest state variable values for internal nodes + DO l = 1,p%nLines + CALL Line_SetState(m%LineList(l), x%states(m%LineStateIs1(l):m%LineStateIsN(l)), t) + END DO - DO J = 1,3 - Xd(3+J) = X(J) ! velocities - 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 - DO J = 1,3 - Connect%r(J) = X(3 + J) ! get positions - Connect%rd(J) = X(J) ! get velocities - END DO - END IF + ! calculate dynamics of free objects (will also calculate forces (doRHS()) from any child/dependent objects)... - - ! add any added mass and drag forces from the Connect body itself - DO J = 1,3 - Connect%Ftot(J) = Connect%Ftot(J) - 0.5 * p%rhoW * Connect%rd(J) * abs(Connect%rd(J)) * Connect%conCdA; ! add drag forces - corrected Nov 24 - Connect%Mtot(J,J) = Connect%Mtot(J,J) + Connect%conV*p%rhoW*Connect%conCa; ! add added mass + ! calculate line dynamics (and calculate line forces and masses attributed to connections) + DO l = 1,p%nLines + CALL Line_GetStateDeriv(m%LineList(l), dxdt%states(m%LineStateIs1(l):m%LineStateIsN(l)), m, p) !dt might also be passed for fancy friction models + END DO + + ! calculate connect dynamics (including contributions from attached lines + ! as well as hydrodynamic forces etc. on connect object itself if applicable) + DO l = 1,p%nFreeCons + CALL Connect_GetStateDeriv(m%ConnectList(m%FreeConIs(l)), dxdt%states(m%ConStateIs1(l):m%ConStateIsN(l)), m, p) + END DO + + ! calculate dynamics of independent Rods + DO l = 1,p%nFreeRods + CALL Rod_GetStateDeriv(m%RodList(m%FreeRodIs(l)), dxdt%states(m%RodStateIs1(l):m%RodStateIsN(l)), m, p) + END DO + + ! calculate dynamics of Bodies + DO l = 1,p%nFreeBodies + CALL Body_GetStateDeriv(m%BodyList(m%FreeBodyIs(l)), dxdt%states(m%BodyStateIs1(l):m%BodyStateIsN(l)), m, p) + END DO + + + + ! get dynamics/forces (doRHS()) of coupled objects, which weren't addressed in above calls (this includes inertial loads) + ! note: can do this in any order since there are no dependencies among coupled objects + + DO iTurb = 1,p%nTurbines + DO l = 1,p%nCpldCons(iTurb) + + ! >>>>>>>> here we should pass along accelerations and include inertial loads in the calculation!!! << 0_IntKi) CLOSE( p%UnLog ) ! close log file if it's open + !TODO: any need to specifically deallocate things like m%xTemp%states in the above? <<<< ! IF ( ErrStat==ErrID_None) THEN ! CALL WrScr('MoorDyn closed without errors') @@ -1219,30 +2998,83 @@ SUBROUTINE CheckError(ErrId, Msg) END SUBROUTINE CheckError - END SUBROUTINE MD_End ! -------+ - !========================================================================================================== + END SUBROUTINE MD_End ! -------+ + !----------------------------------------------------------------------------------------================== + + +!!========== MD_CheckError ======= <---------------------------------------------------------------+ +! SUBROUTINE MD_CheckError(InMsg,OutMsg) +! ! Passed arguments +!! CHARACTER(*), INTENT(IN ) :: InMsg ! The input string +! CHARACTER(*), INTENT(INOUT) :: OutMsg ! The error message (ErrMsg)! +! + ! OutMsg = InMsg + ! RETURN + !END SUBROUTINE MD_CheckError ! -------+ + !----------------------------------------------------------------------------------------================== + + + ! RK2 integrater (part of what was in TimeStep) + !-------------------------------------------------------------- + SUBROUTINE MD_RK2 ( t, dtM, u_interp, u, t_array, p, x, xd, z, other, m, ErrStat, ErrMsg ) + + REAL(DbKi) , INTENT(INOUT) :: t ! intial time (s) for this integration step + REAL(DbKi) , INTENT(IN ) :: dtM ! single time step size (s) for this integration step + TYPE( MD_InputType ) , INTENT(INOUT) :: u_interp ! interpolated instantaneous input values to be calculated for each mooring time step + TYPE( MD_InputType ) , INTENT(INOUT) :: u(:) ! INTENT(IN ) + REAL(DbKi) , INTENT(IN ) :: t_array(:) ! times corresponding to elements of u(:)? + TYPE( MD_ParameterType ) , INTENT(IN ) :: p ! INTENT(IN ) + TYPE( MD_ContinuousStateType ) , INTENT(INOUT) :: x + TYPE( MD_DiscreteStateType ) , INTENT(IN ) :: xd ! INTENT(IN ) + TYPE( MD_ConstraintStateType ) , INTENT(IN ) :: z ! INTENT(IN ) + TYPE( MD_OtherStateType ) , INTENT(IN ) :: other ! INTENT(INOUT) + TYPE(MD_MiscVarType) , INTENT(INOUT) :: m ! INTENT(INOUT) + INTEGER(IntKi) , INTENT( OUT) :: ErrStat + CHARACTER(*) , INTENT( OUT) :: ErrMsg + + + INTEGER(IntKi) :: I ! counter + INTEGER(IntKi) :: J ! counter + + + ! ------------------------------------------------------------------------------- + ! RK2 integrator written here, now calling CalcContStateDeriv + !-------------------------------------------------------------------------------- + + ! step 1 + + CALL MD_Input_ExtrapInterp(u, t_array, u_interp, t , ErrStat, ErrMsg) ! interpolate input mesh to correct time (t) + + CALL MD_CalcContStateDeriv( t, u_interp, p, x, xd, z, other, m, m%xdTemp, ErrStat, ErrMsg ) + DO J = 1, m%Nx + m%xTemp%states(J) = x%states(J) + 0.5*dtM*m%xdTemp%states(J) !x1 = x0 + dt*f0/2.0; + END DO + ! step 2 -!!========== MD_CheckError ======= <---------------------------------------------------------------+ -! SUBROUTINE MD_CheckError(InMsg,OutMsg) -! ! Passed arguments -!! CHARACTER(*), INTENT(IN ) :: InMsg ! The input string -! CHARACTER(*), INTENT(INOUT) :: OutMsg ! The error message (ErrMsg)! -! - ! OutMsg = InMsg - ! RETURN - !END SUBROUTINE MD_CheckError ! -------+ - !========================================================================================================== + CALL MD_Input_ExtrapInterp(u, t_array, 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_DbKi*dtM), u_interp, p, m%xTemp, xd, z, other, m, m%xdTemp, ErrStat, ErrMsg ) !called with updated states x2 and time = t + dt/2.0 + DO J = 1, m%Nx + x%states(J) = x%states(J) + dtM*m%xdTemp%states(J) + END DO + t = t + dtM ! update time + + !TODO error check? <<<< + END SUBROUTINE MD_RK2 + !-------------------------------------------------------------- - !======================================================================================================== - SUBROUTINE TimeStep ( t, dtStep, u, utimes, p, x, xd, z, other, m, ErrStat, ErrMsg ) + !----------------------------------------------------------------------------------------================ + ! this would do a full (coupling) time step and is no longer used + SUBROUTINE TimeStep ( t, dtStep, u, t_array, p, x, xd, z, other, m, ErrStat, ErrMsg ) + REAL(DbKi) , INTENT(INOUT) :: t - REAL(ReKi) , INTENT(IN ) :: dtStep ! how long to advance the time for + REAL(DbKi) , INTENT(IN ) :: dtStep ! how long to advance the time for TYPE( MD_InputType ) , INTENT(INOUT) :: u(:) ! INTENT(IN ) - REAL(DbKi) , INTENT(IN ) :: utimes(:) ! times corresponding to elements of u(:)? + REAL(DbKi) , INTENT(IN ) :: t_array(:) ! times corresponding to elements of u(:)? TYPE( MD_ParameterType ) , INTENT(IN ) :: p ! INTENT(IN ) TYPE( MD_ContinuousStateType ) , INTENT(INOUT) :: x TYPE( MD_DiscreteStateType ) , INTENT(IN ) :: xd ! INTENT(IN ) @@ -1262,7 +3094,7 @@ SUBROUTINE TimeStep ( t, dtStep, u, utimes, p, x, xd, z, other, m, ErrStat, ErrM INTEGER(IntKi) :: J ! counter TYPE(MD_InputType) :: u_interp ! interpolated instantaneous input values to be calculated for each mooring time step - Real(DbKi) :: tDbKi ! double version because that's what MD_Input_ExtrapInterp needs. + ! Real(DbKi) :: tDbKi ! double version because that's what MD_Input_ExtrapInterp needs. ! allocate space for x2 @@ -1272,19 +3104,19 @@ SUBROUTINE TimeStep ( t, dtStep, u, utimes, p, x, xd, z, other, m, ErrStat, ErrM CALL MD_CopyInput(u(1), u_interp, MESH_NEWCOPY, ErrStat, ErrMsg) - Nx = size(x%states) + Nx = size(x%states) ! <<<< should this be the m%Nx parameter instead? ! round dt to integer number of time steps NdtM = ceiling(dtStep/p%dtM0) ! get number of mooring time steps to do based on desired time step size - dtM = dtStep/float(NdtM) ! adjust desired time step to satisfy dt with an integer number of time steps + dtM = dtStep/REAL(NdtM,DbKi) ! adjust desired time step to satisfy dt with an integer number of time steps !loop through line integration time steps DO I = 1, NdtM ! for (double ts=t; ts<=t+ICdt-dts; ts+=dts) - !tDbKi = t ! get DbKi version of current time (why does ExtrapInterp except different time type than UpdateStates?) + ! tDbKi = t ! get DbKi version of current time (why does ExtrapInterp except different time type than UpdateStates?) ! ------------------------------------------------------------------------------- @@ -1293,7 +3125,7 @@ SUBROUTINE TimeStep ( t, dtStep, u, utimes, p, x, xd, z, other, m, ErrStat, ErrM ! step 1 - CALL MD_Input_ExtrapInterp(u, utimes, u_interp, t , ErrStat, ErrMsg) ! interpolate input mesh to correct time (t) + CALL MD_Input_ExtrapInterp(u, t_array, u_interp, t , ErrStat, ErrMsg) ! interpolate input mesh to correct time (t) CALL MD_CalcContStateDeriv( t, u_interp, p, x, xd, z, other, m, dxdt, ErrStat, ErrMsg ) DO J = 1, Nx @@ -1302,7 +3134,7 @@ SUBROUTINE TimeStep ( t, dtStep, u, utimes, p, x, xd, z, other, m, ErrStat, ErrM ! step 2 - 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_Input_ExtrapInterp(u, t_array, 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_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 @@ -1310,16 +3142,14 @@ SUBROUTINE TimeStep ( t, dtStep, u, utimes, p, x, xd, z, other, m, ErrStat, ErrM END DO t = t + dtM ! update time - - !print *, " In TimeStep t=", t, ", L1N8Pz=", M%LineList(1)%r(3,8), ", dL1=", u_interp%DeltaL(1) !---------------------------------------------------------------------------------- ! >>> below should no longer be necessary thanks to using ExtrapInterp of u(:) within the mooring time stepping loop.. <<< ! ! update Fairlead positions by integrating velocity and last position (do this AFTER the processing of the time step rather than before) - ! DO J = 1, p%NFairs + ! DO J = 1, p%nCpldCons ! DO K = 1, 3 - ! m%ConnectList(m%FairIdList(J))%r(K) = m%ConnectList(m%FairIdList(J))%r(K) + m%ConnectList(m%FairIdList(J))%rd(K)*dtM + ! m%ConnectList(m%CpldConIs(J))%r(K) = m%ConnectList(m%CpldConIs(J))%r(K) + m%ConnectList(m%CpldConIs(J))%rd(K)*dtM ! END DO ! END DO @@ -1339,7 +3169,7 @@ SUBROUTINE TimeStep ( t, dtStep, u, utimes, p, x, xd, z, other, m, ErrStat, ErrM ! check for NaNs - is this a good place/way to do it? DO J = 1, Nx - IF (Is_NaN(REAL(x%states(J),DbKi))) THEN + IF (Is_NaN(x%states(J))) THEN ErrStat = ErrID_Fatal ErrMsg = ' NaN state detected.' END IF @@ -1347,880 +3177,904 @@ SUBROUTINE TimeStep ( t, dtStep, u, utimes, p, x, xd, z, other, m, ErrStat, ErrM END SUBROUTINE TimeStep - !====================================================================== - - - - !======================================================================= - SUBROUTINE SetupLine (Line, LineProp, rhoW, ErrStat, ErrMsg) - ! allocate arrays in line object - - TYPE(MD_Line), INTENT(INOUT) :: Line ! the single line object of interest - TYPE(MD_LineProp), INTENT(INOUT) :: LineProp ! the single line property set for the line of interest - REAL(ReKi), INTENT(IN) :: rhoW - INTEGER, INTENT( INOUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT( INOUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - INTEGER(4) :: J ! Generic index - INTEGER(4) :: K ! Generic index - INTEGER(IntKi) :: N - - N = Line%N ! number of segments in this line (for code readability) - - ! allocate node positions and velocities (NOTE: these arrays start at ZERO) - ALLOCATE ( Line%r(3, 0:N), Line%rd(3, 0:N), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating r and rd arrays.' - !CALL CleanUp() - RETURN - END IF - - ! allocate node tangent vectors - ALLOCATE ( Line%q(3, 0:N), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating q array.' - !CALL CleanUp() - RETURN - END IF - - ! allocate segment scalar quantities - ALLOCATE ( Line%l(N), Line%ld(N), Line%lstr(N), Line%lstrd(N), Line%V(N), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating segment scalar quantity arrays.' - !CALL CleanUp() - RETURN - END IF - - ! assign values for l and V - DO J=1,N - Line%l(J) = Line%UnstrLen/REAL(N, DbKi) - Line%ld(J)= 0.0_DbKi - Line%V(J) = Line%l(J)*0.25*Pi*LineProp%d*LineProp%d - END DO - - ! allocate segment tension and internal damping force vectors - ALLOCATE ( Line%T(3, N), Line%Td(3, N), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating T and Td arrays.' - !CALL CleanUp() - RETURN - END IF - - ! allocate node force vectors - ALLOCATE ( Line%W(3, 0:N), Line%Dp(3, 0:N), Line%Dq(3, 0:N), Line%Ap(3, 0:N), & - Line%Aq(3, 0:N), Line%B(3, 0:N), Line%F(3, 0:N), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating node force arrays.' - !CALL CleanUp() - RETURN - END IF - - ! 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_DbKi - Line%B(K,J) = 0.0_DbKi - END DO - END DO - - ! allocate mass and inverse mass matrices for each node (including ends) - ALLOCATE ( Line%S(3, 3, 0:N), Line%M(3, 3, 0:N), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating T and Td arrays.' - !CALL CleanUp() - RETURN - END IF - - ! Specify specific internal damping coefficient (BA) for this line. - ! Will be equal to inputted BA of LineType if input value is positive. - ! If input value is negative, it is considered to be desired damping ratio (zeta) - ! from which the line's BA can be calculated based on the segment natural frequency. - IF (LineProp%BA < 0) THEN - ! - we assume desired damping coefficient is zeta = -LineProp%BA - ! - highest axial vibration mode of a segment is wn = sqrt(k/m) = 2N/UnstrLen*sqrt(EA/w) - Line%BA = -LineProp%BA * Line%UnstrLen / Line%N * SQRT(LineProp%EA * LineProp%w) - ! print *, 'Based on zeta, BA set to ', Line%BA - - ! print *, 'Negative BA input detected, treating as -zeta. For zeta = ', -LineProp%BA, ', setting BA to ', Line%BA - - ELSE - Line%BA = LineProp%BA - ! temp = Line%N * Line%BA / Line%UnstrLen * SQRT(1.0/(LineProp%EA * LineProp%w)) - ! print *, 'BA set as input to ', Line%BA, '. Corresponding zeta is ', temp - END IF - - !temp = 2*Line%N / Line%UnstrLen * sqrt( LineProp%EA / LineProp%w) / TwoPi - !print *, 'Segment natural frequency is ', temp, ' Hz' - - - ! need to add cleanup sub <<< - - - END SUBROUTINE SetupLine - !====================================================================== - - - - - !=============================================================================================== - SUBROUTINE InitializeLine (Line, LineProp, rhoW, ErrStat, ErrMsg) - ! calculate initial profile of the line using quasi-static model - - TYPE(MD_Line), INTENT(INOUT) :: Line ! the single line object of interest - TYPE(MD_LineProp), INTENT(INOUT) :: LineProp ! the single line property set for the line of interest - REAL(ReKi), INTENT(IN) :: rhoW - INTEGER, INTENT( INOUT ) :: ErrStat ! returns a non-zero value when an error occurs - CHARACTER(*), INTENT( INOUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - 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(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 + !-------------------------------------------------------------- - N = Line%N ! for convenience - ! try to calculate initial line profile using catenary routine (from FAST v.7) - ! note: much of this function is adapted from the FAST source code +!-------------------------------------------------------------- +! Connection-Specific Subroutines +!-------------------------------------------------------------- - ! Transform the fairlead location from the inertial frame coordinate system - ! to the local coordinate system of the current line (this coordinate - ! system lies at the current anchor, Z being vertical, and X directed from - ! current anchor to the current fairlead). Also, compute the orientation - ! of this local coordinate system: - XF = SQRT( ( Line%r(1,N) - Line%r(1,0) )**2.0 + ( Line%r(2,N) - Line%r(2,0) )**2.0 ) - 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_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 - ENDIF - WetWeight = LineProp%w - 0.25*Pi*LineProp%d*LineProp%d*rhoW +!-------------------------------------------------------------- +! Rod-Specific Subroutines +!-------------------------------------------------------------- - !LineNodes = Line%N + 1 ! number of nodes in line for catenary model to worry about - ! allocate temporary arrays for catenary routine - ALLOCATE ( LSNodes(N+1), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating LSNodes array.' - CALL CleanUp() - RETURN - END IF - ALLOCATE ( LNodesX(N+1), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating LNodesX array.' - CALL CleanUp() - RETURN - END IF - ALLOCATE ( LNodesZ(N+1), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating LNodesZ array.' - CALL CleanUp() - RETURN - END IF - ! Assign node arc length locations - 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 - LSNodes(N+1) = Line%UnstrLen ! ensure the last node length isn't longer than the line due to numerical error - - ! Solve the analytical, static equilibrium equations for a catenary (or - ! taut) mooring line with seabed interaction in order to find the - ! horizontal and vertical tensions at the fairlead in the local coordinate - ! system of the current line: - ! NOTE: The values for the horizontal and vertical tensions at the fairlead - ! from the previous time step are used as the initial guess values at - ! at this time step (because the LAnchHTe(:) and LAnchVTe(:) arrays - ! are stored in a module and thus their values are saved from CALL to - ! CALL). - - - CALL Catenary ( XF , ZF , Line%UnstrLen, LineProp%EA , & - WetWeight , SeabedCD, TenTol, (N+1) , & - LSNodes, LNodesX, LNodesZ , ErrStat2, ErrMsg2) - IF (ErrStat2 == ErrID_None) THEN ! if it worked, use it - ! Transform the positions of each node on the current line from the local - ! coordinate system of the current line to the inertial frame coordinate - ! system: - 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) + LNodesX(J+1)*COSPhi - Line%r(2,J) = Line%r(2,0) + LNodesX(J+1)*SINPhi - Line%r(3,J) = Line%r(3,0) + LNodesZ(J+1) - ENDDO ! J - All nodes per line where the line position and tension can be output +!-------------------------------------------------------------- +! Body-Specific Subroutines +!-------------------------------------------------------------- - ELSE ! if there is a problem with the catenary approach, just stretch the nodes linearly between fairlead and anchor - 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, 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 +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +! ###### 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 MD_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(MD_InputType), INTENT(INOUT) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) + TYPE(MD_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(MD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point + TYPE(MD_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point + TYPE(MD_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point + TYPE(MD_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point + TYPE(MD_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(MD_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(MD_OutputType) :: y_m, y_p + TYPE(MD_ContinuousStateType) :: x_m, x_p + TYPE(MD_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 = 'MD_JacobianPInput' + + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = '' + + ! get OP values here: + call MD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat2, ErrMsg2 ); if(Failed()) return + + ! make a copy of the inputs to perturb + call MD_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 MD_CopyOutput( y, y_p, MESH_NEWCOPY, ErrStat2, ErrMsg2); if(Failed()) return + call MD_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 MD_CopyInput( u, u_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call MD_Perturb_u( p, i, 1, u_perturb, delta_p ) + ! compute y at u_op + delta_p u + call MD_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 MD_CopyInput( u, u_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call MD_Perturb_u( p, i, -1, u_perturb, delta_m ) + ! compute y at u_op - delta_m u + call MD_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 MD_Compute_dY( p, y_p, y_m, delta_p, dYdu(:,i) ) + end do + if(Failed()) return + END IF + IF ( PRESENT( dXdu ) ) THEN + if (.not. allocated(dXdu)) then + call AllocAry(dXdu, p%Jac_nx, 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 MD_CopyInput( u, u_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call MD_Perturb_u( p, i, 1, u_perturb, delta_p ) + ! compute x at u_op + delta u + call MD_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 MD_CopyInput( u, u_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call MD_Perturb_u( p, i, -1, u_perturb, delta_m ) + ! compute x at u_op - delta u + call MD_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 (state entries are mapped the the dXdu column in routine): + call MD_Compute_dX( p, x_p, x_m, delta_p, dXdu(:,i) ) + end do + 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 MD_DestroyContState( x_p, ErrStat2, ErrMsg2 ) ! we don't need this any more + call MD_DestroyContState( x_m, ErrStat2, ErrMsg2 ) ! we don't need this any more + call MD_DestroyOutput( y_p, ErrStat2, ErrMsg2 ) + call MD_DestroyOutput( y_m, ErrStat2, ErrMsg2 ) + call MD_DestroyInput(u_perturb, ErrStat2, ErrMsg2 ) + end subroutine cleanup + +END SUBROUTINE MD_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 MD_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(MD_InputType), INTENT(INOUT) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) + TYPE(MD_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(MD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point + TYPE(MD_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point + TYPE(MD_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point + TYPE(MD_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point + TYPE(MD_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(MD_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(MD_OutputType) :: y_p, y_m + TYPE(MD_ContinuousStateType) :: x_p, x_m + TYPE(MD_ContinuousStateType) :: x_perturb + REAL(R8Ki) :: delta ! delta change in input or state + INTEGER(IntKi) :: i, k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_JacobianPContState' + + ! Initialize ErrStat + ErrStat = ErrID_None + ErrMsg = '' + + ! make a copy of the continuous states to perturb NOTE: MESH_NEWCOPY + call MD_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, '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 MD_CopyOutput( y, y_p, MESH_NEWCOPY, ErrStat2, ErrMsg2); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call MD_CopyOutput( y, y_m, MESH_NEWCOPY, ErrStat2, ErrMsg2); if(Failed()) return + ! Loop over the dx dimension of the dYdx array. Perturb the corresponding state (note difference in ordering of dYdx and x%states). + ! The p%dxIdx_map2_xStateIdx(i) is the index to the state array for the given dx index + do i=1,p%Jac_nx ! index into dx dimension + ! get x_op + delta x + call MD_CopyContState( x, x_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call MD_perturb_x(p, p%dxIdx_map2_xStateIdx(i), 1, x_perturb, delta ) + ! compute y at x_op + delta x + call MD_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 MD_CopyContState( x, x_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call MD_perturb_x(p, p%dxIdx_map2_xStateIdx(i), -1, x_perturb, delta ) + ! compute y at x_op - delta x + call MD_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 MD_Compute_dY( p, y_p, y_m, delta, dYdx(:,i) ) + 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: + if (.not. allocated(dXdx)) then + call AllocAry(dXdx, p%Jac_nx, p%Jac_nx, 'dXdx', ErrStat2, ErrMsg2); if(Failed()) return + end if + ! Loop over the dx dimension of the array. Perturb the corresponding state (note difference in ordering of dXdx and x%states). + ! The resulting x_p and x_m are used to calculate the column for dXdx (mapping of state entry to dXdx row entry occurs in MD_Compute_dX) + ! The p%dxIdx_map2_xStateIdx(i) is the index to the state array for the given dx index + do i=1,p%Jac_nx ! index into dx dimension + ! get x_op + delta x + call MD_CopyContState( x, x_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call MD_perturb_x(p, p%dxIdx_map2_xStateIdx(i), 1, x_perturb, delta ) + ! compute x at x_op + delta x + call MD_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 MD_CopyContState( x, x_perturb, MESH_UPDATECOPY, ErrStat2, ErrMsg2 ); call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call MD_perturb_x(p, p%dxIdx_map2_xStateIdx(i), -1, x_perturb, delta ) + ! compute x at x_op - delta x + call MD_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 MD_Compute_dX( p, x_p, x_m, delta, dXdx(:,i) ) + end do + 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, 'MD_JacobianPContState') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp() + end function Failed + + subroutine CleanUp() + call MD_DestroyOutput( y_p, ErrStat2, ErrMsg2 ) + call MD_DestroyOutput( y_m, ErrStat2, ErrMsg2 ) + call MD_DestroyContState( x_p, ErrStat2, ErrMsg2 ) + call MD_DestroyContState( x_m, ErrStat2, ErrMsg2 ) + call MD_DestroyContState(x_perturb, ErrStat2, ErrMsg2 ) + end subroutine cleanup + +END SUBROUTINE MD_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 MD_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(MD_InputType), INTENT(INOUT) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) + TYPE(MD_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(MD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point + TYPE(MD_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point + TYPE(MD_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point + TYPE(MD_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point + TYPE(MD_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(MD_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 MD_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 MD_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(MD_InputType), INTENT(INOUT) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) + TYPE(MD_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(MD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point + TYPE(MD_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point + TYPE(MD_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point + TYPE(MD_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point + TYPE(MD_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(MD_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 = 'MD_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 MD_JacobianPConstrState +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +!> Routine to pack the data structures representing the operating points into arrays for linearization. +SUBROUTINE MD_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(MD_InputType), INTENT(INOUT) :: u !< Inputs at operating point (may change to inout if a mesh copy is required) + TYPE(MD_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(MD_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at operating point + TYPE(MD_DiscreteStateType), INTENT(IN ) :: xd !< Discrete states at operating point + TYPE(MD_ConstraintStateType), INTENT(IN ) :: z !< Constraint states at operating point + TYPE(MD_OtherStateType), INTENT(IN ) :: OtherState !< Other states at operating point + TYPE(MD_OutputType), INTENT(IN ) :: y !< Output at operating point + TYPE(MD_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 = 'MD_GetOP' + LOGICAL :: FieldMask(FIELDMASK_SIZE) + TYPE(MD_ContinuousStateType) :: dx ! derivative of continuous states at operating point + ErrStat = ErrID_None + ErrMsg = '' + ! inputs + IF ( PRESENT( u_op ) ) THEN + nu = size(p%Jac_u_indx,1) + u%CoupledKinematics(1)%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. + ! fill in the u_op values from the input mesh + call PackMotionMesh(u%CoupledKinematics(1), u_op, idx, FieldMask=FieldMask) + + ! now do the active tensioning commands if there are any + if (allocated(u%DeltaL)) then + do i=1,size(u%DeltaL) + u_op(idx) = u%DeltaL(i) + idx = idx + 1 + u_op(idx) = u%DeltaLdot(i) + idx = idx + 1 + end do + endif + END IF + ! outputs + IF ( PRESENT( y_op ) ) THEN + ny = p%Jac_ny + y%CoupledLoads(1)%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%CoupledLoads(1), y_op, idx) + do i=1,p%NumOuts + y_op(idx) = y%WriteOutput(i) + idx = idx + 1 + end do + END IF + ! states + IF ( PRESENT( x_op ) ) THEN + if (.not. allocated(x_op)) then + call AllocAry(x_op, p%Jac_nx,'x_op',ErrStat2,ErrMsg2); if (Failed()) return + end if + do i=1, p%Jac_nx + x_op(i) = x%states(p%dxIdx_map2_xStateIdx(i)) ! x for lin is different order, so use mapping + end do + END IF + ! state derivatives? + IF ( PRESENT( dx_op ) ) THEN + if (.not. allocated(dx_op)) then + call AllocAry(dx_op, p%Jac_nx,'dx_op',ErrStat2,ErrMsg2); if(failed()) return + end if + call MD_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dx, ErrStat2, ErrMsg2 ) ; if(Failed()) return + do i=1, p%Jac_nx + dx_op(i) = dx%states(p%dxIdx_map2_xStateIdx(i)) ! x for lin is different order, so use mapping + 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, 'MD_GetOP') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp() + end function Failed + + subroutine CleanUp() + call MD_DestroyContState(dx, ErrStat2, ErrMsg2); + end subroutine +END SUBROUTINE MD_GetOP + + + +!==================================================================================================== +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +!> 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 subroutines calculating dXdx etc (MD_Compute_dX) +SUBROUTINE MD_Init_Jacobian(Init, p, u, y, m, InitOut, ErrStat, ErrMsg) + TYPE(MD_InitInputType) , INTENT(IN ) :: Init !< Init + TYPE(MD_ParameterType) , INTENT(INOUT) :: p !< parameters + TYPE(MD_InputType) , INTENT(IN ) :: u !< inputs + TYPE(MD_OutputType) , INTENT(IN ) :: y !< outputs + TYPE(MD_MiscVarType) , INTENT(INOUT) :: m !< misc variables <<<<<<<< + TYPE(MD_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 + + INTEGER(IntKi) :: l, I + real(ReKi) :: dl_slack ! how much a given line segment is stretched [m] + real(ReKi) :: dl_slack_min ! minimum change in a node position for the least-strained segment in the simulation to go slack [m] + + + ! 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) + + + ! Figure out appropriate transverse perturbation size to avoid slack segments + dl_slack_min = 0.1_ReKi ! start at 0.1 m + + do l = 1,p%nLines + do I = 1, m%LineList(l)%N + dl_slack = m%LineList(l)%lstr(I) - m%LineList(l)%l(I) + + ! store the smallest positive length margin to a segment going slack + if (( dl_slack > 0.0_ReKi) .and. (dl_slack < dl_slack_min)) then + dl_slack_min = dl_slack + end if + end do + end do + + dl_slack_min = 0.5*dl_slack_min ! apply 0.5 safety factor + + !TODO: consider attachment radii to also produce a rotational perturbation size from the above + + + ! --- 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%CoupledLoads(1)%nNodes * 6 & ! 3 forces + 3 moments at each node (moments may be zero) + + 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%CoupledLoads(1), 'LinNames_y', InitOut%LinNames_y, index_next) ! <<< should a specific name be provided here? + do i=1,p%NumOuts + InitOut%LinNames_y(i+index_next-1) = trim(InitOut%WriteOutputHdr(i))//', '//trim(InitOut%WriteOutputUnt(i)) + end do + + 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) :: idx ! index into the LinNames_x array + INTEGER(IntKi) :: i + INTEGER(IntKi) :: l + INTEGER(IntKi) :: N + + p%Jac_nx = m%Nx ! size of (continuous) state vector (includes the first derivatives) + + ! allocate space for the row/column names and for perturbation sizes + CALL AllocAry(InitOut%LinNames_x , p%Jac_nx, 'LinNames_x' , ErrStat2, ErrMsg2); if(ErrStat/=ErrID_None) return + CALL AllocAry(InitOut%RotFrame_x , p%Jac_nx, 'RotFrame_x' , ErrStat2, ErrMsg2); if(ErrStat/=ErrID_None) return + CALL AllocAry(InitOut%DerivOrder_x , p%Jac_nx, 'DerivOrder_x' , ErrStat2, ErrMsg2); if(ErrStat/=ErrID_None) return + CALL AllocAry(p%dx , p%Jac_nx, 'p%dx' , ErrStat2, ErrMsg2); if(ErrStat/=ErrID_None) return + CALL AllocAry(p%dxIdx_map2_xStateIdx, p%Jac_nx, 'p%dxIdx_map2_xStateIdx', ErrStat2, ErrMsg2); if(ErrStat/=ErrID_None) return + + p%dxIdx_map2_xStateIdx = 0_IntKi ! all values should be overwritten by logic below + + ! set linearization output names and default perturbations, p%dx: + ! NOTE: the order is different than the order of the internal states. This is to + ! match what the OpenFAST framework is expecting: all positions first, then all + ! derviatives of positions (velocity terms) second. This adds slight complexity + ! here, but considerably simplifies post processing of the full OpenFAST results + ! for linearization. + ! The p%dxIdx_map2_xStateIdx array holds the index for the x%states array + ! corresponding to the current jacobian index. + + !----------------- + ! position states + !----------------- + idx = 0 + ! Free bodies + DO l = 1,p%nFreeBodies ! Body m%BodyList(m%FreeBodyIs(l)) + p%dx(idx+1:idx+3) = dl_slack_min ! body displacement [m] + p%dx(idx+4:idx+6) = 0.02 ! body rotation [rad] + ! corresponds to state indices: (m%BodyStateIs1(l)+6:m%BodyStateIs1(l)+11) + InitOut%LinNames_x(idx+1) = 'Body '//trim(num2lstr(m%FreeBodyIs(l)))//' Px, m' + InitOut%LinNames_x(idx+2) = 'Body '//trim(num2lstr(m%FreeBodyIs(l)))//' Py, m' + InitOut%LinNames_x(idx+3) = 'Body '//trim(num2lstr(m%FreeBodyIs(l)))//' Pz, m' + InitOut%LinNames_x(idx+4) = 'Body '//trim(num2lstr(m%FreeBodyIs(l)))//' rot_x, rad' + InitOut%LinNames_x(idx+5) = 'Body '//trim(num2lstr(m%FreeBodyIs(l)))//' rot_y, rad' + InitOut%LinNames_x(idx+6) = 'Body '//trim(num2lstr(m%FreeBodyIs(l)))//' rot_z, rad' + p%dxIdx_map2_xStateIdx(idx+1) = m%BodyStateIs1(l)+6 ! x%state index for Px + p%dxIdx_map2_xStateIdx(idx+2) = m%BodyStateIs1(l)+7 ! x%state index for Py + p%dxIdx_map2_xStateIdx(idx+3) = m%BodyStateIs1(l)+8 ! x%state index for Pz + p%dxIdx_map2_xStateIdx(idx+4) = m%BodyStateIs1(l)+9 ! x%state index for rot_x + p%dxIdx_map2_xStateIdx(idx+5) = m%BodyStateIs1(l)+10 ! x%state index for rot_y + p%dxIdx_map2_xStateIdx(idx+6) = m%BodyStateIs1(l)+11 ! x%state index for rot_z + idx = idx + 6 + END DO - CALL CleanUp() ! deallocate temporary arrays + ! Rods + DO l = 1,p%nFreeRods ! Rod m%RodList(m%FreeRodIs(l)) + if (m%RodList(m%FreeRodIs(l))%typeNum == 1) then ! pinned rod + p%dx(idx+1:idx+3) = 0.02 ! rod rotation [rad] + ! corresponds to state indices: (m%RodStateIs1(l)+3:m%RodStateIs1(l)+5) + InitOut%LinNames_x(idx+1) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' rot_x, rad' + InitOut%LinNames_x(idx+2) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' rot_y, rad' + InitOut%LinNames_x(idx+3) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' rot_z, rad' + p%dxIdx_map2_xStateIdx(idx+4) = m%RodStateIs1(l)+3 ! x%state index for rot_x + p%dxIdx_map2_xStateIdx(idx+5) = m%RodStateIs1(l)+4 ! x%state index for rot_y + p%dxIdx_map2_xStateIdx(idx+6) = m%RodStateIs1(l)+5 ! x%state index for rot_z + idx = idx + 3 + else ! free rod + p%dx(idx+1:idx+3) = dl_slack_min ! rod displacement [m] + p%dx(idx+4:idx+6) = 0.02 ! rod rotation [rad] + ! corresponds to state indices: (m%RodStateIs1(l)+6:m%RodStateIs1(l)+11) + InitOut%LinNames_x(idx+1) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' Px, m' + InitOut%LinNames_x(idx+2) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' Py, m' + InitOut%LinNames_x(idx+3) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' Pz, m' + InitOut%LinNames_x(idx+4) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' rot_x, rad' + InitOut%LinNames_x(idx+5) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' rot_y, rad' + InitOut%LinNames_x(idx+6) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' rot_z, rad' + p%dxIdx_map2_xStateIdx(idx+1) = m%RodStateIs1(l)+6 ! x%state index for Px + p%dxIdx_map2_xStateIdx(idx+2) = m%RodStateIs1(l)+7 ! x%state index for Py + p%dxIdx_map2_xStateIdx(idx+3) = m%RodStateIs1(l)+8 ! x%state index for Pz + p%dxIdx_map2_xStateIdx(idx+4) = m%RodStateIs1(l)+9 ! x%state index for rot_x + p%dxIdx_map2_xStateIdx(idx+5) = m%RodStateIs1(l)+10 ! x%state index for rot_y + p%dxIdx_map2_xStateIdx(idx+6) = m%RodStateIs1(l)+11 ! x%state index for rot_z + idx = idx + 6 + end if + END DO + ! Free Connnections + DO l = 1,p%nFreeCons ! Point m%ConnectList(m%FreeConIs(l)) + ! corresponds to state indices: (m%ConStateIs1(l)+3:m%ConStateIs1(l)+5) + p%dx(idx+1:idx+3) = dl_slack_min ! point displacement [m] + InitOut%LinNames_x(idx+1) = 'Point '//trim(num2lstr(m%FreeConIs(l)))//' Px, m' + InitOut%LinNames_x(idx+2) = 'Point '//trim(num2lstr(m%FreeConIs(l)))//' Py, m' + InitOut%LinNames_x(idx+3) = 'Point '//trim(num2lstr(m%FreeConIs(l)))//' Pz, m' + p%dxIdx_map2_xStateIdx(idx+1) = m%ConStateIs1(l)+3 ! x%state index for Px + p%dxIdx_map2_xStateIdx(idx+2) = m%ConStateIs1(l)+4 ! x%state index for Py + p%dxIdx_map2_xStateIdx(idx+3) = m%ConStateIs1(l)+5 ! x%state index for Pz + idx = idx + 3 + END DO + ! Lines + DO l = 1,p%nLines ! Line m%LineList(l) + ! corresponds to state indices: (m%LineStateIs1(l)+3*N-3:m%LineStateIs1(l)+6*N-7) -- NOTE: end nodes not included + N = m%LineList(l)%N ! number of segments in the line + DO i = 0,N-2 + p%dx(idx+1:idx+3) = dl_slack_min ! line internal node displacement [m] + InitOut%LinNames_x(idx+1) = 'Line '//trim(num2lstr(l))//' node '//trim(num2lstr(i+1))//' Px, m' + InitOut%LinNames_x(idx+2) = 'Line '//trim(num2lstr(l))//' node '//trim(num2lstr(i+1))//' Py, m' + InitOut%LinNames_x(idx+3) = 'Line '//trim(num2lstr(l))//' node '//trim(num2lstr(i+1))//' Pz, m' + p%dxIdx_map2_xStateIdx(idx+1) = m%LineStateIs1(l)+3*N+3*i-3 ! x%state index for Px + p%dxIdx_map2_xStateIdx(idx+2) = m%LineStateIs1(l)+3*N+3*i-2 ! x%state index for Py + p%dxIdx_map2_xStateIdx(idx+3) = m%LineStateIs1(l)+3*N+3*i-1 ! x%state index for Pz + idx = idx + 3 + END DO + END DO - CONTAINS + !----------------- + ! velocity states + !----------------- + ! Free bodies + DO l = 1,p%nFreeBodies ! Body m%BodyList(m%FreeBodyIs(l)) + ! corresponds to state indices: (m%BodyStateIs1(l):m%BodyStateIs1(l)+5) + p%dx(idx+1:idx+3) = 0.1 ! body translational velocity [m/s] + p%dx(idx+4:idx+6) = 0.1 ! body rotational velocity [rad/s] + InitOut%LinNames_x(idx+1) = 'Body '//trim(num2lstr(m%FreeBodyIs(l)))//' Vx, m/s' + InitOut%LinNames_x(idx+2) = 'Body '//trim(num2lstr(m%FreeBodyIs(l)))//' Vy, m/s' + InitOut%LinNames_x(idx+3) = 'Body '//trim(num2lstr(m%FreeBodyIs(l)))//' Vz, m/s' + InitOut%LinNames_x(idx+4) = 'Body '//trim(num2lstr(m%FreeBodyIs(l)))//' omega_x, rad/s' + InitOut%LinNames_x(idx+5) = 'Body '//trim(num2lstr(m%FreeBodyIs(l)))//' omega_y, rad/s' + InitOut%LinNames_x(idx+6) = 'Body '//trim(num2lstr(m%FreeBodyIs(l)))//' omega_z, rad/s' + p%dxIdx_map2_xStateIdx(idx+1) = m%BodyStateIs1(l)+0 ! x%state index for Rx + p%dxIdx_map2_xStateIdx(idx+2) = m%BodyStateIs1(l)+1 ! x%state index for Ry + p%dxIdx_map2_xStateIdx(idx+3) = m%BodyStateIs1(l)+2 ! x%state index for Rz + p%dxIdx_map2_xStateIdx(idx+4) = m%BodyStateIs1(l)+3 ! x%state index for omega_x + p%dxIdx_map2_xStateIdx(idx+5) = m%BodyStateIs1(l)+4 ! x%state index for omega_y + p%dxIdx_map2_xStateIdx(idx+6) = m%BodyStateIs1(l)+5 ! x%state index for omega_z + idx = idx + 6 + END DO + ! Rods + DO l = 1,p%nFreeRods ! Rod m%RodList(m%FreeRodIs(l)) + if (m%RodList(m%FreeRodIs(l))%typeNum == 1) then ! pinned rod + ! corresponds to state indices: (m%RodStateIs1(l):m%RodStateIs1(l)+2) + p%dx(idx+1:idx+3) = 0.1 ! body rotational velocity [rad/s] + InitOut%LinNames_x(idx+1) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' omega_x, rad/s' + InitOut%LinNames_x(idx+2) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' omega_y, rad/s' + InitOut%LinNames_x(idx+3) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' omega_z, rad/s' + p%dxIdx_map2_xStateIdx(idx+1) = m%RodStateIs1(l)+0 ! x%state index for Vx + p%dxIdx_map2_xStateIdx(idx+2) = m%RodStateIs1(l)+1 ! x%state index for Vy + p%dxIdx_map2_xStateIdx(idx+3) = m%RodStateIs1(l)+2 ! x%state index for Vz + idx = idx + 3 + else ! free rod + ! corresponds to state indices: (m%RodStateIs1(l):m%RodStateIs1(l)+5) + p%dx(idx+1:idx+3) = 0.1 ! body translational velocity [m/s] + p%dx(idx+4:idx+6) = 0.02 ! body rotational velocity [rad/s] + InitOut%LinNames_x(idx+1) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' Vx, m/s' + InitOut%LinNames_x(idx+2) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' Vy, m/s' + InitOut%LinNames_x(idx+3) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' Vz, m/s' + InitOut%LinNames_x(idx+4) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' omega_x, rad/s' + InitOut%LinNames_x(idx+5) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' omega_y, rad/s' + InitOut%LinNames_x(idx+6) = 'Rod '//trim(num2lstr(m%FreeRodIs(l)))//' omega_z, rad/s' + p%dxIdx_map2_xStateIdx(idx+1) = m%RodStateIs1(l)+0 ! x%state index for Vx + p%dxIdx_map2_xStateIdx(idx+2) = m%RodStateIs1(l)+1 ! x%state index for Vy + p%dxIdx_map2_xStateIdx(idx+3) = m%RodStateIs1(l)+2 ! x%state index for Vz + p%dxIdx_map2_xStateIdx(idx+4) = m%RodStateIs1(l)+3 ! x%state index for omega_x + p%dxIdx_map2_xStateIdx(idx+5) = m%RodStateIs1(l)+4 ! x%state index for omega_y + p%dxIdx_map2_xStateIdx(idx+6) = m%RodStateIs1(l)+5 ! x%state index for omega_z + idx = idx + 6 + end if + END DO - !======================================================================= - SUBROUTINE CleanUp() - ! deallocate temporary arrays - - IF (ALLOCATED(LSNodes)) DEALLOCATE(LSNodes) - IF (ALLOCATED(LNodesX)) DEALLOCATE(LNodesX) - IF (ALLOCATED(LNodesZ)) DEALLOCATE(LNodesZ) - - END SUBROUTINE CleanUp - !======================================================================= - - - !======================================================================= - SUBROUTINE Catenary ( XF_In, ZF_In, L_In , EA_In, & - W_In , CB_In, Tol_In, N , & - s_In , X_In , Z_In , ErrStat, ErrMsg ) - - ! This subroutine is copied from FAST v7 with minor modifications - - ! This routine solves the analytical, static equilibrium equations - ! for a catenary (or taut) mooring line with seabed interaction. - ! Stretching of the line is accounted for, but bending stiffness - ! is not. Given the mooring line properties and the fairlead - ! position relative to the anchor, this routine finds the line - ! configuration and tensions. Since the analytical solution - ! involves two nonlinear equations (XF and ZF) in two unknowns - ! (HF and VF), a Newton-Raphson iteration scheme is implemented in - ! order to solve for the solution. The values of HF and VF that - ! are passed into this routine are used as the initial guess in - ! the iteration. The Newton-Raphson iteration is only accurate in - ! double precision, so all of the input/output arguments are - ! converteds to/from double precision from/to default precision. - - - ! USE Precision - - - IMPLICIT NONE - - - ! Passed Variables: - - INTEGER(4), INTENT(IN ) :: N ! Number of nodes where the line position and tension can be output (-) - - 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 - - - ! Local Variables: - - REAL(DbKi) :: CB ! Coefficient of seabed static friction (a negative value indicates no seabed) (-) - REAL(DbKi) :: CBOvrEA ! = CB/EA - REAL(DbKi) :: DET ! Determinant of the Jacobian matrix (m^2/N^2) - REAL(DbKi) :: dHF ! Increment in HF predicted by Newton-Raphson (N) - REAL(DbKi) :: dVF ! Increment in VF predicted by Newton-Raphson (N) - REAL(DbKi) :: dXFdHF ! Partial derivative of the calculated horizontal distance with respect to the horizontal fairlead tension (m/N): dXF(HF,VF)/dHF - REAL(DbKi) :: dXFdVF ! Partial derivative of the calculated horizontal distance with respect to the vertical fairlead tension (m/N): dXF(HF,VF)/dVF - REAL(DbKi) :: dZFdHF ! Partial derivative of the calculated vertical distance with respect to the horizontal fairlead tension (m/N): dZF(HF,VF)/dHF - REAL(DbKi) :: dZFdVF ! Partial derivative of the calculated vertical distance with respect to the vertical fairlead tension (m/N): dZF(HF,VF)/dVF - REAL(DbKi) :: EA ! Extensional stiffness of line (N) - REAL(DbKi) :: EXF ! Error function between calculated and known horizontal distance (meters): XF(HF,VF) - XF - REAL(DbKi) :: EZF ! Error function between calculated and known vertical distance (meters): ZF(HF,VF) - ZF - REAL(DbKi) :: HA ! Effective horizontal tension in line at the anchor (N) - REAL(DbKi) :: HF ! Effective horizontal tension in line at the fairlead (N) - REAL(DbKi) :: HFOvrW ! = HF/W - REAL(DbKi) :: HFOvrWEA ! = HF/WEA - REAL(DbKi) :: L ! Unstretched length of line (meters) - REAL(DbKi) :: Lamda0 ! Catenary parameter used to generate the initial guesses of the horizontal and vertical tensions at the fairlead for the Newton-Raphson iteration (-) - REAL(DbKi) :: LMax ! Maximum stretched length of the line with seabed interaction beyond which the line would have to double-back on itself; here the line forms an "L" between the anchor and fairlead (i.e. it is horizontal along the seabed from the anchor, then vertical to the fairlead) (meters) - REAL(DbKi) :: LMinVFOvrW ! = L - VF/W - REAL(DbKi) :: LOvrEA ! = L/EA - REAL(DbKi) :: s (N) ! Unstretched arc distance along line from anchor to each node where the line position and tension can be output (meters) - REAL(DbKi) :: sOvrEA ! = s(I)/EA - REAL(DbKi) :: SQRT1VFOvrHF2 ! = SQRT( 1.0_DbKi + VFOvrHF2 ) - REAL(DbKi) :: SQRT1VFMinWLOvrHF2 ! = SQRT( 1.0_DbKi + VFMinWLOvrHF2 ) - REAL(DbKi) :: SQRT1VFMinWLsOvrHF2 ! = SQRT( 1.0_DbKi + VFMinWLsOvrHF*VFMinWLsOvrHF ) - REAL(DbKi) :: Te (N) ! Effective line tensions at each node (N) - REAL(DbKi) :: Tol ! Convergence tolerance within Newton-Raphson iteration specified as a fraction of tension (-) - REAL(DbKi) :: VA ! Effective vertical tension in line at the anchor (N) - REAL(DbKi) :: VF ! Effective vertical tension in line at the fairlead (N) - REAL(DbKi) :: VFMinWL ! = VF - WL - REAL(DbKi) :: VFMinWLOvrHF ! = VFMinWL/HF - REAL(DbKi) :: VFMinWLOvrHF2 ! = VFMinWLOvrHF*VFMinWLOvrHF - REAL(DbKi) :: VFMinWLs ! = VFMinWL + Ws - REAL(DbKi) :: VFMinWLsOvrHF ! = VFMinWLs/HF - REAL(DbKi) :: VFOvrHF ! = VF/HF - REAL(DbKi) :: VFOvrHF2 ! = VFOvrHF*VFOvrHF - REAL(DbKi) :: VFOvrWEA ! = VF/WEA - REAL(DbKi) :: W ! Weight of line in fluid per unit length (N/m) - REAL(DbKi) :: WEA ! = W*EA - REAL(DbKi) :: WL ! Total weight of line in fluid (N): W*L - REAL(DbKi) :: Ws ! = W*s(I) - REAL(DbKi) :: X (N) ! Horizontal locations of each line node relative to the anchor (meters) - REAL(DbKi) :: XF ! Horizontal distance between anchor and fairlead (meters) - REAL(DbKi) :: XF2 ! = XF*XF - REAL(DbKi) :: Z (N) ! Vertical locations of each line node relative to the anchor (meters) - REAL(DbKi) :: ZF ! Vertical distance between anchor and fairlead (meters) - REAL(DbKi) :: ZF2 ! = ZF*ZF - - INTEGER(4) :: I ! Index for counting iterations or looping through line nodes (-) - INTEGER(4) :: MaxIter ! Maximum number of Newton-Raphson iterations possible before giving up (-) - - LOGICAL :: FirstIter ! Flag to determine whether or not this is the first time through the Newton-Raphson interation (flag) - - - ErrStat = ERrId_None - - - ! The Newton-Raphson iteration is only accurate in double precision, so - ! convert the input arguments into double precision: - - CB = REAL( CB_In , DbKi ) - EA = REAL( EA_In , DbKi ) - HF = 0.0_DbKi ! = REAL( HF_In , DbKi ) - L = REAL( L_In , DbKi ) - s (:) = REAL( s_In (:), DbKi ) - Tol = REAL( Tol_In , DbKi ) - VF = 0.0_DbKi ! keeping this for some error catching functionality? (at first glance) ! VF = REAL( VF_In , DbKi ) - W = REAL( W_In , DbKi ) - XF = REAL( XF_In , DbKi ) - ZF = REAL( ZF_In , DbKi ) + ! Free Connnections + DO l = 1,p%nFreeCons ! Point m%ConnectList(m%FreeConIs(l)) + ! corresponds to state indices: (m%ConStateIs1(l):m%ConStateIs1(l)+2) + p%dx(idx+1:idx+3) = 0.1 ! point translational velocity [m/s] + InitOut%LinNames_x(idx+1) = 'Point '//trim(num2lstr(m%FreeConIs(l)))//' Vx, m/s' + InitOut%LinNames_x(idx+2) = 'Point '//trim(num2lstr(m%FreeConIs(l)))//' Vy, m/s' + InitOut%LinNames_x(idx+3) = 'Point '//trim(num2lstr(m%FreeConIs(l)))//' Vz, m/s' + p%dxIdx_map2_xStateIdx(idx+1) = m%ConStateIs1(l)+0 ! x%state index for Vx + p%dxIdx_map2_xStateIdx(idx+2) = m%ConStateIs1(l)+1 ! x%state index for Vy + p%dxIdx_map2_xStateIdx(idx+3) = m%ConStateIs1(l)+2 ! x%state index for Vz + idx = idx + 3 + END DO + ! Lines + DO l = 1,p%nLines ! Line m%LineList(l) + ! corresponds to state indices: (m%LineStateIs1(l):m%LineStateIs1(l)+3*N-4) -- NOTE: end nodes not included + N = m%LineList(l)%N ! number of segments in the line + DO i = 0,N-2 + p%dx(idx+1:idx+3) = 0.1 ! line internal node translational velocity [m/s] + InitOut%LinNames_x(idx+1) = 'Line '//trim(num2lstr(l))//' node '//trim(num2lstr(i+1))//' Vx, m/s' + InitOut%LinNames_x(idx+2) = 'Line '//trim(num2lstr(l))//' node '//trim(num2lstr(i+1))//' Vy, m/s' + InitOut%LinNames_x(idx+3) = 'Line '//trim(num2lstr(l))//' node '//trim(num2lstr(i+1))//' Vz, m/s' + p%dxIdx_map2_xStateIdx(idx+1) = m%LineStateIs1(l)+3*i+0 ! x%state index for Vx + p%dxIdx_map2_xStateIdx(idx+2) = m%LineStateIs1(l)+3*i+1 ! x%state index for Vy + p%dxIdx_map2_xStateIdx(idx+3) = m%LineStateIs1(l)+3*i+2 ! x%state index for Vz + idx = idx + 3 + END DO + END DO + ! If a summary file is ever made... + ! !Formatting may be needed to make it pretty + ! if(UnSum > 0) then + ! write(UnSum,*) ' Lin_Jac_x idx x%state idx' + ! do i=1,p%Jac_nx + ! write(UnSum,*) InitOut%LinNames_x(i),' ',i,' ',p%dxIdx_map2_xStateIdx(i) + ! enddo + ! endif + + InitOut%RotFrame_x = .false. + InitOut%DerivOrder_x = 2 + END SUBROUTINE Init_Jacobian_x + + SUBROUTINE Init_Jacobian_u() + INTEGER(IntKi) :: i, j, idx, nu, i_meshField + character(10) :: LinStr ! for noting which line a DeltaL control is attached to + logical :: LinCtrl ! Is the current DeltaL channel associated with a line? + ! Number of inputs + i = 0 + if (allocated(u%DeltaL)) i=size(u%DeltaL) + nu = u%CoupledKinematics(1)%nNodes * 18 & ! 3 Translation Displacements + 3 orientations + 6 velocities + 6 accelerations at each node <<<<<<< + + i*2 ! a deltaL and rate of change for each active tension control channel + + ! --- 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%IsLoad_u = .false. ! None of MoorDyn's inputs are loads + 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%CoupledKinematics(1), 'CoupledKinematics', InitOut%LinNames_u, idx) ! all 6 motion fields + + ! --- 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 + p%Jac_u_indx = 0 ! initialize to zero + idx = 1 + !Module/Mesh/Field: u%CoupledKinematics(1)%TranslationDisp = 1; + !Module/Mesh/Field: u%CoupledKinematics(1)%Orientation = 2; + !Module/Mesh/Field: u%CoupledKinematics(1)%TranslationVel = 3; + !Module/Mesh/Field: u%CoupledKinematics(1)%RotationVel = 4; + !Module/Mesh/Field: u%CoupledKinematics(1)%TranslationAcc = 5; + !Module/Mesh/Field: u%CoupledKinematics(1)%RotationAcc = 6; + do i_meshField = 1,6 + do i=1,u%CoupledKinematics(1)%nNodes + do j=1,3 + p%Jac_u_indx(idx,1) = i_meshField ! mesh field type (indicated by 1-6) + p%Jac_u_indx(idx,2) = j ! x, y, or z + p%Jac_u_indx(idx,3) = i ! node + idx = idx + 1 + end do !j + end do !i + end do + ! now do the active tensioning commands if there are any + if (allocated(u%DeltaL)) then + do i=1,size(u%DeltaL) ! Signals may be passed in without being requested for control + ! Figure out if this DeltaL control channel is associated with a line or multiple or none and label + LinCtrl = .FALSE. + LinStr = '(lines: ' + do J=1,p%NLines + if (m%LineList(J)%CtrlChan == i) then + LinCtrl = .TRUE. + LinStr = LinStr//trim(num2lstr(i))//' ' + endif + enddo + if ( LinCtrl) LinStr = LinStr//' )' + if (.not. LinCtrl) LinStr = '(lines: none)' + + p%Jac_u_indx(idx,1) = 10 ! 10-11 mean active tension changes (10: deltaL; 11: deltaLdot) + p%Jac_u_indx(idx,2) = 0 ! not used + p%Jac_u_indx(idx,3) = i ! indicates DeltaL entry number + InitOut%LinNames_u(idx) = 'CtrlChan DeltaL '//trim(num2lstr(i))//', m '//trim(LinStr) + idx = idx + 1 - ! HF and VF cannot be initialized to zero when a portion of the line rests on the seabed and the anchor tension is nonzero - - ! Generate the initial guess values for the horizontal and vertical tensions - ! at the fairlead in the Newton-Raphson iteration for the catenary mooring - ! line solution. Use starting values documented in: Peyrot, Alain H. and - ! Goulois, A. M., "Analysis Of Cable Structures," Computers & Structures, - ! Vol. 10, 1979, pp. 805-813: - XF2 = XF*XF - ZF2 = ZF*ZF - - IF ( XF == 0.0_DbKi ) THEN ! .TRUE. if the current mooring line is exactly vertical - Lamda0 = 1.0D+06 - ELSEIF ( L <= SQRT( XF2 + ZF2 ) ) THEN ! .TRUE. if the current mooring line is taut - Lamda0 = 0.2_DbKi - ELSE ! The current mooring line must be slack and not vertical - Lamda0 = SQRT( 3.0_DbKi*( ( L**2 - ZF2 )/XF2 - 1.0_DbKi ) ) - ENDIF - - HF = ABS( 0.5_DbKi*W* XF/ Lamda0 ) - VF = 0.5_DbKi*W*( ZF/TANH(Lamda0) + L ) - - - ! Abort when there is no solution or when the only possible solution is - ! illogical: - - IF ( Tol <= EPSILON(TOL) ) THEN ! .TRUE. when the convergence tolerance is specified incorrectly - ErrStat = ErrID_Warn - ErrMsg = ' Convergence tolerance must be greater than zero in routine Catenary().' - return - ELSEIF ( XF < 0.0_DbKi ) THEN ! .TRUE. only when the local coordinate system is not computed correctly - ErrStat = ErrID_Warn - ErrMsg = ' The horizontal distance between an anchor and its'// & - ' fairlead must not be less than zero in routine Catenary().' - return - - ELSEIF ( ZF < 0.0_DbKi ) THEN ! .TRUE. if the fairlead has passed below its anchor - ErrStat = ErrID_Warn - ErrMsg = ' A fairlead has passed below its anchor.' - return - - ELSEIF ( L <= 0.0_DbKi ) THEN ! .TRUE. when the unstretched line length is specified incorrectly - ErrStat = ErrID_Warn - ErrMsg = ' Unstretched length of line must be greater than zero in routine Catenary().' - return - - ELSEIF ( EA <= 0.0_DbKi ) THEN ! .TRUE. when the unstretched line length is specified incorrectly - ErrStat = ErrID_Warn - ErrMsg = ' Extensional stiffness of line must be greater than zero in routine Catenary().' - return - - ELSEIF ( W == 0.0_DbKi ) THEN ! .TRUE. when the weight of the line in fluid is zero so that catenary solution is ill-conditioned - ErrStat = ErrID_Warn - ErrMsg = ' The weight of the line in fluid must not be zero. '// & - ' Routine Catenary() cannot solve quasi-static mooring line solution.' - return - - - ELSEIF ( W > 0.0_DbKi ) THEN ! .TRUE. when the line will sink in fluid - - LMax = XF - EA/W + SQRT( (EA/W)*(EA/W) + 2.0_DbKi*ZF*EA/W ) ! Compute the maximum stretched length of the line with seabed interaction beyond which the line would have to double-back on itself; here the line forms an "L" between the anchor and fairlead (i.e. it is horizontal along the seabed from the anchor, then vertical to the fairlead) - - IF ( ( L >= LMax ) .AND. ( CB >= 0.0_DbKi ) ) then ! .TRUE. if the line is as long or longer than its maximum possible value with seabed interaction - ErrStat = ErrID_Warn - ErrMsg = ' Unstretched mooring line length too large. '// & - ' Routine Catenary() cannot solve quasi-static mooring line solution.' - return - END IF - - ENDIF - - - ! Initialize some commonly used terms that don't depend on the iteration: - - WL = W *L - WEA = W *EA - LOvrEA = L /EA - CBOvrEA = CB /EA - MaxIter = INT(1.0_DbKi/Tol) ! Smaller tolerances may take more iterations, so choose a maximum inversely proportional to the tolerance - - - - ! To avoid an ill-conditioned situation, ensure that the initial guess for - ! HF is not less than or equal to zero. Similarly, avoid the problems - ! associated with having exactly vertical (so that HF is zero) or exactly - ! horizontal (so that VF is zero) lines by setting the minimum values - ! equal to the tolerance. This prevents us from needing to implement - ! the known limiting solutions for vertical or horizontal lines (and thus - ! complicating this routine): - - HF = MAX( HF, Tol ) - XF = MAX( XF, Tol ) - ZF = MAX( ZF, TOl ) - - - - ! Solve the analytical, static equilibrium equations for a catenary (or - ! taut) mooring line with seabed interaction: - - ! Begin Newton-Raphson iteration: - - I = 1 ! Initialize iteration counter - FirstIter = .TRUE. ! Initialize iteration flag - - DO - - - ! Initialize some commonly used terms that depend on HF and VF: - - VFMinWL = VF - WL - LMinVFOvrW = L - VF/W - HFOvrW = HF/W - HFOvrWEA = HF/WEA - VFOvrWEA = VF/WEA - VFOvrHF = VF/HF - VFMinWLOvrHF = VFMinWL/HF - VFOvrHF2 = VFOvrHF *VFOvrHF - VFMinWLOvrHF2 = VFMinWLOvrHF*VFMinWLOvrHF - SQRT1VFOvrHF2 = SQRT( 1.0_DbKi + VFOvrHF2 ) - SQRT1VFMinWLOvrHF2 = SQRT( 1.0_DbKi + VFMinWLOvrHF2 ) - - - ! Compute the error functions (to be zeroed) and the Jacobian matrix - ! (these depend on the anticipated configuration of the mooring line): - - IF ( ( CB < 0.0_DbKi ) .OR. ( W < 0.0_DbKi ) .OR. ( VFMinWL > 0.0_DbKi ) ) THEN ! .TRUE. when no portion of the line rests on the seabed - - EXF = ( LOG( VFOvrHF + SQRT1VFOvrHF2 ) & - - LOG( VFMinWLOvrHF + SQRT1VFMinWLOvrHF2 ) )*HFOvrW & - + LOvrEA* HF - XF - EZF = ( SQRT1VFOvrHF2 & - - SQRT1VFMinWLOvrHF2 )*HFOvrW & - + LOvrEA*( VF - 0.5_DbKi*WL ) - ZF - - dXFdHF = ( LOG( VFOvrHF + SQRT1VFOvrHF2 ) & - - LOG( VFMinWLOvrHF + SQRT1VFMinWLOvrHF2 ) )/ W & - - ( ( VFOvrHF + VFOvrHF2 /SQRT1VFOvrHF2 )/( VFOvrHF + SQRT1VFOvrHF2 ) & - - ( VFMinWLOvrHF + VFMinWLOvrHF2/SQRT1VFMinWLOvrHF2 )/( VFMinWLOvrHF + SQRT1VFMinWLOvrHF2 ) )/ W & - + LOvrEA - dXFdVF = ( ( 1.0_DbKi + VFOvrHF /SQRT1VFOvrHF2 )/( VFOvrHF + SQRT1VFOvrHF2 ) & - - ( 1.0_DbKi + VFMinWLOvrHF /SQRT1VFMinWLOvrHF2 )/( VFMinWLOvrHF + SQRT1VFMinWLOvrHF2 ) )/ W - dZFdHF = ( SQRT1VFOvrHF2 & - - SQRT1VFMinWLOvrHF2 )/ W & - - ( VFOvrHF2 /SQRT1VFOvrHF2 & - - VFMinWLOvrHF2/SQRT1VFMinWLOvrHF2 )/ W - dZFdVF = ( VFOvrHF /SQRT1VFOvrHF2 & - - VFMinWLOvrHF /SQRT1VFMinWLOvrHF2 )/ W & - + LOvrEA - - - ELSEIF ( -CB*VFMinWL < HF ) THEN ! .TRUE. when a portion of the line rests on the seabed and the anchor tension is nonzero - - EXF = LOG( VFOvrHF + SQRT1VFOvrHF2 ) *HFOvrW & - - 0.5_DbKi*CBOvrEA*W* LMinVFOvrW*LMinVFOvrW & - + LOvrEA* HF + LMinVFOvrW - XF - EZF = ( SQRT1VFOvrHF2 - 1.0_DbKi )*HFOvrW & - + 0.5_DbKi*VF*VFOvrWEA - ZF - - dXFdHF = LOG( VFOvrHF + SQRT1VFOvrHF2 ) / W & - - ( ( VFOvrHF + VFOvrHF2 /SQRT1VFOvrHF2 )/( VFOvrHF + SQRT1VFOvrHF2 ) )/ W & - + LOvrEA - dXFdVF = ( ( 1.0_DbKi + VFOvrHF /SQRT1VFOvrHF2 )/( VFOvrHF + SQRT1VFOvrHF2 ) )/ W & - + CBOvrEA*LMinVFOvrW - 1.0_DbKi/W - dZFdHF = ( SQRT1VFOvrHF2 - 1.0_DbKi & - - VFOvrHF2 /SQRT1VFOvrHF2 )/ W - dZFdVF = ( VFOvrHF /SQRT1VFOvrHF2 )/ W & - + VFOvrWEA - - - ELSE ! 0.0_DbKi < HF <= -CB*VFMinWL ! A portion of the line must rest on the seabed and the anchor tension is zero - - EXF = LOG( VFOvrHF + SQRT1VFOvrHF2 ) *HFOvrW & - - 0.5_DbKi*CBOvrEA*W*( LMinVFOvrW*LMinVFOvrW - ( LMinVFOvrW - HFOvrW/CB )*( LMinVFOvrW - HFOvrW/CB ) ) & - + LOvrEA* HF + LMinVFOvrW - XF - EZF = ( SQRT1VFOvrHF2 - 1.0_DbKi )*HFOvrW & - + 0.5_DbKi*VF*VFOvrWEA - ZF - - dXFdHF = LOG( VFOvrHF + SQRT1VFOvrHF2 ) / W & - - ( ( VFOvrHF + VFOvrHF2 /SQRT1VFOvrHF2 )/( VFOvrHF + SQRT1VFOvrHF2 ) )/ W & - + LOvrEA - ( LMinVFOvrW - HFOvrW/CB )/EA - dXFdVF = ( ( 1.0_DbKi + VFOvrHF /SQRT1VFOvrHF2 )/( VFOvrHF + SQRT1VFOvrHF2 ) )/ W & - + HFOvrWEA - 1.0_DbKi/W - dZFdHF = ( SQRT1VFOvrHF2 - 1.0_DbKi & - - VFOvrHF2 /SQRT1VFOvrHF2 )/ W - dZFdVF = ( VFOvrHF /SQRT1VFOvrHF2 )/ W & - + VFOvrWEA - - - ENDIF - - - ! Compute the determinant of the Jacobian matrix and the incremental - ! tensions predicted by Newton-Raphson: - - - DET = dXFdHF*dZFdVF - dXFdVF*dZFdHF - - if ( EqualRealNos( DET, 0.0_DbKi ) ) then -!bjj: there is a serious problem with the debugger here when DET = 0 - ErrStat = ErrID_Warn - ErrMsg = ' Iteration not convergent (DET is 0). '// & - ' Routine Catenary() cannot solve quasi-static mooring line solution.' - return - endif - - - dHF = ( -dZFdVF*EXF + dXFdVF*EZF )/DET ! This is the incremental change in horizontal tension at the fairlead as predicted by Newton-Raphson - dVF = ( dZFdHF*EXF - dXFdHF*EZF )/DET ! This is the incremental change in vertical tension at the fairlead as predicted by Newton-Raphson - - dHF = dHF*( 1.0_DbKi - Tol*I ) ! Reduce dHF by factor (between 1 at I = 1 and 0 at I = MaxIter) that reduces linearly with iteration count to ensure that we converge on a solution even in the case were we obtain a nonconvergent cycle about the correct solution (this happens, for example, if we jump to quickly between a taut and slack catenary) - dVF = dVF*( 1.0_DbKi - Tol*I ) ! Reduce dHF by factor (between 1 at I = 1 and 0 at I = MaxIter) that reduces linearly with iteration count to ensure that we converge on a solution even in the case were we obtain a nonconvergent cycle about the correct solution (this happens, for example, if we jump to quickly between a taut and slack catenary) - - dHF = MAX( dHF, ( Tol - 1.0_DbKi )*HF ) ! To avoid an ill-conditioned situation, make sure HF does not go less than or equal to zero by having a lower limit of Tol*HF [NOTE: the value of dHF = ( Tol - 1.0_DbKi )*HF comes from: HF = HF + dHF = Tol*HF when dHF = ( Tol - 1.0_DbKi )*HF] - - ! Check if we have converged on a solution, or restart the iteration, or - ! Abort if we cannot find a solution: - - IF ( ( ABS(dHF) <= ABS(Tol*HF) ) .AND. ( ABS(dVF) <= ABS(Tol*VF) ) ) THEN ! .TRUE. if we have converged; stop iterating! [The converge tolerance, Tol, is a fraction of tension] - - EXIT - - - ELSEIF ( ( I == MaxIter ) .AND. ( FirstIter ) ) THEN ! .TRUE. if we've iterated MaxIter-times for the first time; - - ! Perhaps we failed to converge because our initial guess was too far off. - ! (This could happen, for example, while linearizing a model via large - ! pertubations in the DOFs.) Instead, use starting values documented in: - ! Peyrot, Alain H. and Goulois, A. M., "Analysis Of Cable Structures," - ! Computers & Structures, Vol. 10, 1979, pp. 805-813: - ! NOTE: We don't need to check if the current mooring line is exactly - ! vertical (i.e., we don't need to check if XF == 0.0), because XF is - ! limited by the tolerance above. - - XF2 = XF*XF - ZF2 = ZF*ZF - - IF ( L <= SQRT( XF2 + ZF2 ) ) THEN ! .TRUE. if the current mooring line is taut - Lamda0 = 0.2_DbKi - ELSE ! The current mooring line must be slack and not vertical - Lamda0 = SQRT( 3.0_DbKi*( ( L*L - ZF2 )/XF2 - 1.0_DbKi ) ) - ENDIF - - HF = MAX( ABS( 0.5_DbKi*W* XF/ Lamda0 ), Tol ) ! As above, set the lower limit of the guess value of HF to the tolerance - VF = 0.5_DbKi*W*( ZF/TANH(Lamda0) + L ) - - - ! Restart Newton-Raphson iteration: - - I = 0 - FirstIter = .FALSE. - dHF = 0.0_DbKi - dVF = 0.0_DbKi - - - ELSEIF ( ( I == MaxIter ) .AND. ( .NOT. FirstIter ) ) THEN ! .TRUE. if we've iterated as much as we can take without finding a solution; Abort - ErrStat = ErrID_Warn - ErrMsg = ' Iteration not convergent. '// & - ' Routine Catenary() cannot solve quasi-static mooring line solution.' - RETURN - - - ENDIF - - - ! Increment fairlead tensions and iteration counter so we can try again: - - HF = HF + dHF - VF = VF + dVF - - I = I + 1 - - - ENDDO - - - - ! We have found a solution for the tensions at the fairlead! - - ! Now compute the tensions at the anchor and the line position and tension - ! at each node (again, these depend on the configuration of the mooring - ! line): - - IF ( ( CB < 0.0_DbKi ) .OR. ( W < 0.0_DbKi ) .OR. ( VFMinWL > 0.0_DbKi ) ) THEN ! .TRUE. when no portion of the line rests on the seabed - - ! Anchor tensions: - - HA = HF - VA = VFMinWL - - - ! Line position and tension at each node: - - DO I = 1,N ! Loop through all nodes where the line position and tension are to be computed - - IF ( ( s(I) < 0.0_DbKi ) .OR. ( s(I) > L ) ) THEN - ErrStat = ErrID_Warn - ErrMsg = ' All line nodes must be located between the anchor ' & - //'and fairlead (inclusive) in routine Catenary().' - RETURN - END IF - - Ws = W *s(I) ! Initialize - VFMinWLs = VFMinWL + Ws ! some commonly - VFMinWLsOvrHF = VFMinWLs/HF ! used terms - sOvrEA = s(I) /EA ! that depend - SQRT1VFMinWLsOvrHF2 = SQRT( 1.0_DbKi + VFMinWLsOvrHF*VFMinWLsOvrHF ) ! on s(I) - - X (I) = ( LOG( VFMinWLsOvrHF + SQRT1VFMinWLsOvrHF2 ) & - - LOG( VFMinWLOvrHF + SQRT1VFMinWLOvrHF2 ) )*HFOvrW & - + sOvrEA* HF - Z (I) = ( SQRT1VFMinWLsOvrHF2 & - - SQRT1VFMinWLOvrHF2 )*HFOvrW & - + sOvrEA*( VFMinWL + 0.5_DbKi*Ws ) - Te(I) = SQRT( HF*HF + VFMinWLs*VFMinWLs ) - - ENDDO ! I - All nodes where the line position and tension are to be computed - - - ELSEIF ( -CB*VFMinWL < HF ) THEN ! .TRUE. when a portion of the line rests on the seabed and the anchor tension is nonzero - - ! Anchor tensions: - - HA = HF + CB*VFMinWL - VA = 0.0_DbKi - - - ! Line position and tension at each node: - - DO I = 1,N ! Loop through all nodes where the line position and tension are to be computed - - IF ( ( s(I) < 0.0_DbKi ) .OR. ( s(I) > L ) ) THEN - ErrStat = ErrID_Warn - ErrMsg = ' All line nodes must be located between the anchor ' & - //'and fairlead (inclusive) in routine Catenary().' - RETURN - END IF - - Ws = W *s(I) ! Initialize - VFMinWLs = VFMinWL + Ws ! some commonly - VFMinWLsOvrHF = VFMinWLs/HF ! used terms - sOvrEA = s(I) /EA ! that depend - SQRT1VFMinWLsOvrHF2 = SQRT( 1.0_DbKi + VFMinWLsOvrHF*VFMinWLsOvrHF ) ! on s(I) - - IF ( s(I) <= LMinVFOvrW ) THEN ! .TRUE. if this node rests on the seabed and the tension is nonzero - - X (I) = s(I) & - + sOvrEA*( HF + CB*VFMinWL + 0.5_DbKi*Ws*CB ) - Z (I) = 0.0_DbKi - Te(I) = HF + CB*VFMinWLs - - ELSE ! LMinVFOvrW < s <= L ! This node must be above the seabed - - X (I) = LOG( VFMinWLsOvrHF + SQRT1VFMinWLsOvrHF2 ) *HFOvrW & - + sOvrEA* HF + LMinVFOvrW - 0.5_DbKi*CB*VFMinWL*VFMinWL/WEA - Z (I) = ( - 1.0_DbKi + SQRT1VFMinWLsOvrHF2 )*HFOvrW & - + sOvrEA*( VFMinWL + 0.5_DbKi*Ws ) + 0.5_DbKi* VFMinWL*VFMinWL/WEA - Te(I) = SQRT( HF*HF + VFMinWLs*VFMinWLs ) - - ENDIF - - ENDDO ! I - All nodes where the line position and tension are to be computed - - - ELSE ! 0.0_DbKi < HF <= -CB*VFMinWL ! A portion of the line must rest on the seabed and the anchor tension is zero - - ! Anchor tensions: - - HA = 0.0_DbKi - VA = 0.0_DbKi - - - ! Line position and tension at each node: - - DO I = 1,N ! Loop through all nodes where the line position and tension are to be computed - - IF ( ( s(I) < 0.0_DbKi ) .OR. ( s(I) > L ) ) THEN - ErrStat = ErrID_Warn - ErrMsg = ' All line nodes must be located between the anchor ' & - //'and fairlead (inclusive) in routine Catenary().' - RETURN - END IF - - Ws = W *s(I) ! Initialize - VFMinWLs = VFMinWL + Ws ! some commonly - VFMinWLsOvrHF = VFMinWLs/HF ! used terms - sOvrEA = s(I) /EA ! that depend - SQRT1VFMinWLsOvrHF2 = SQRT( 1.0_DbKi + VFMinWLsOvrHF*VFMinWLsOvrHF ) ! on s(I) - - IF ( s(I) <= LMinVFOvrW - HFOvrW/CB ) THEN ! .TRUE. if this node rests on the seabed and the tension is zero - - X (I) = s(I) - Z (I) = 0.0_DbKi - Te(I) = 0.0_DbKi - - ELSEIF ( s(I) <= LMinVFOvrW ) THEN ! .TRUE. if this node rests on the seabed and the tension is nonzero - - X (I) = s(I) - ( LMinVFOvrW - 0.5_DbKi*HFOvrW/CB )*HF/EA & - + sOvrEA*( HF + CB*VFMinWL + 0.5_DbKi*Ws*CB ) + 0.5_DbKi*CB*VFMinWL*VFMinWL/WEA - Z (I) = 0.0_DbKi - Te(I) = HF + CB*VFMinWLs - - ELSE ! LMinVFOvrW < s <= L ! This node must be above the seabed - - X (I) = LOG( VFMinWLsOvrHF + SQRT1VFMinWLsOvrHF2 ) *HFOvrW & - + sOvrEA* HF + LMinVFOvrW - ( LMinVFOvrW - 0.5_DbKi*HFOvrW/CB )*HF/EA - Z (I) = ( - 1.0_DbKi + SQRT1VFMinWLsOvrHF2 )*HFOvrW & - + sOvrEA*( VFMinWL + 0.5_DbKi*Ws ) + 0.5_DbKi* VFMinWL*VFMinWL/WEA - Te(I) = SQRT( HF*HF + VFMinWLs*VFMinWLs ) - - ENDIF - - ENDDO ! I - All nodes where the line position and tension are to be computed - - - ENDIF - - - - ! The Newton-Raphson iteration is only accurate in double precision, so - ! convert the output arguments back into the default precision for real - ! numbers: - - !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 - !======================================================================= - - - END SUBROUTINE InitializeLine - !====================================================================== - - - - ! ============ below are some math convenience functions =============== - ! should add error checking if I keep these, but hopefully there are existing NWTCLib functions to replace them - - - ! return unit vector (u) in direction from r1 to r2 - !======================================================================= - SUBROUTINE UnitVector( u, r1, r2 ) - REAL(DbKi), INTENT(OUT) :: u(:) - REAL(DbKi), INTENT(IN) :: r1(:) - REAL(DbKi), INTENT(IN) :: r2(:) - - REAL(DbKi) :: Length - - u = r2 - r1 - Length = TwoNorm(u) - - if ( .NOT. EqualRealNos(length, 0.0_DbKi ) ) THEN - u = u / Length - END IF - - END SUBROUTINE UnitVector - !======================================================================= - - - !compute the inverse of a 3-by-3 matrix m - !======================================================================= - SUBROUTINE Inverse3by3( Minv, M ) - Real(DbKi), INTENT(OUT) :: Minv(:,:) ! returned inverse matrix - Real(DbKi), INTENT(IN) :: M(:,:) ! inputted matrix - - 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)) + & - M(1, 3) * (M(2, 1) * M(3, 2) - M(2, 2) * M(3, 1)); - - invdet = 1.0 / det ! because multiplying is faster than dividing + p%Jac_u_indx(idx,1) = 11 + p%Jac_u_indx(idx,2) = 0 + p%Jac_u_indx(idx,3) = i + InitOut%LinNames_u(idx) = 'CtrlChan DeltaLdot '//trim(num2lstr(i))//', m/s'//trim(LinStr) + idx = idx + 1 + end do + endif - Minv(1, 1) = (M(2, 2) * M(3, 3) - M(3, 2) * M(2, 3)) * invdet - Minv(1, 2) = (M(1, 3) * M(3, 2) - M(1, 2) * M(3, 3)) * invdet - Minv(1, 3) = (M(1, 2) * M(2, 3) - M(1, 3) * M(2, 2)) * invdet - Minv(2, 1) = (M(2, 3) * M(3, 1) - M(2, 1) * M(3, 3)) * invdet - Minv(2, 2) = (M(1, 1) * M(3, 3) - M(1, 3) * M(3, 1)) * invdet - Minv(2, 3) = (M(2, 1) * M(1, 3) - M(1, 1) * M(2, 3)) * invdet - Minv(3, 1) = (M(2, 1) * M(3, 2) - M(3, 1) * M(2, 2)) * invdet - Minv(3, 2) = (M(3, 1) * M(1, 2) - M(1, 1) * M(3, 2)) * invdet - Minv(3, 3) = (M(1, 1) * M(2, 2) - M(2, 1) * M(1, 2)) * invdet + ! --- Default perturbations, p%du: + call allocAry( p%du, 11, 'p%du', ErrStat2, ErrMsg2); if(ErrStat2/=ErrID_None) return + p%du( 1) = dl_slack_min ! u%CoupledKinematics(1)%TranslationDisp = 1; + p%du( 2) = 0.1_ReKi ! u%CoupledKinematics(1)%Orientation = 2; + p%du( 3) = 0.1_ReKi ! u%CoupledKinematics(1)%TranslationVel = 3; + p%du( 4) = 0.1_ReKi ! u%CoupledKinematics(1)%RotationVel = 4; + p%du( 5) = 0.1_ReKi ! u%CoupledKinematics(1)%TranslationAcc = 5; + p%du( 6) = 0.1_ReKi ! u%CoupledKinematics(1)%RotationAcc = 6; + p%du(10) = dl_slack_min ! deltaL [m] + p%du(11) = 0.2_ReKi ! deltaLdot [m/s] + END SUBROUTINE Init_Jacobian_u + +END SUBROUTINE MD_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 MD_init_jacobian is consistant with this routine! +SUBROUTINE MD_Perturb_u( p, n, perturb_sign, u, du ) + TYPE(MD_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(MD_InputType) , INTENT(INOUT) :: u !< perturbed MD 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) + u%CoupledKinematics(1)%TranslationDisp( fieldIndx,node) = u%CoupledKinematics(1)%TranslationDisp( fieldIndx,node) + du * perturb_sign + CASE ( 2) + CALL PerturbOrientationMatrix( u%CoupledKinematics(1)%Orientation(:,:,node), du * perturb_sign, fieldIndx, UseSmlAngle=.true. ) + CASE ( 3) + u%CoupledKinematics(1)%TranslationVel( fieldIndx,node) = u%CoupledKinematics(1)%TranslationVel( fieldIndx,node) + du * perturb_sign + CASE ( 4) + u%CoupledKinematics(1)%RotationVel(fieldIndx,node) = u%CoupledKinematics(1)%RotationVel(fieldIndx,node) + du * perturb_sign + CASE ( 5) + u%CoupledKinematics(1)%TranslationAcc( fieldIndx,node) = u%CoupledKinematics(1)%TranslationAcc( fieldIndx,node) + du * perturb_sign + CASE ( 6) + u%CoupledKinematics(1)%RotationAcc(fieldIndx,node) = u%CoupledKinematics(1)%RotationAcc(fieldIndx,node) + du * perturb_sign + CASE (10) + u%deltaL(node) = u%deltaL(node) + du * perturb_sign + CASE (11) + u%deltaLdot(node) = u%deltaLdot(node) + du * perturb_sign + END SELECT +END SUBROUTINE MD_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 MD_init_jacobian is consistant with this routine! +SUBROUTINE MD_Compute_dY(p, y_p, y_m, delta, dY) + TYPE(MD_ParameterType) , INTENT(IN ) :: p !< parameters + TYPE(MD_OutputType) , INTENT(IN ) :: y_p !< MD outputs at \f$ u + \Delta_p u \f$ or \f$ z + \Delta_p z \f$ (p=plus) + TYPE(MD_OutputType) , INTENT(IN ) :: y_m !< MD 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%CoupledLoads(1), y_m%CoupledLoads(1), 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 MD_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 MD_init_jacobian is consistant with this routine! +SUBROUTINE MD_Perturb_x( p, i, perturb_sign, x, dx ) + TYPE(MD_ParameterType) , INTENT(IN ) :: p !< parameters + INTEGER( IntKi ) , INTENT(IN ) :: i !< state array index number + INTEGER( IntKi ) , INTENT(IN ) :: perturb_sign !< +1 or -1 (value to multiply perturbation by; positive or negative difference) + TYPE(MD_ContinuousStateType), INTENT(INOUT) :: x !< perturbed MD states + REAL( R8Ki ) , INTENT( OUT) :: dx !< amount that specific state was perturbed + + dx=p%dx(i) + x%states(i) = x%states(i) + dx * perturb_sign +END SUBROUTINE MD_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 MD_init_jacobian is consistant with this routine! +SUBROUTINE MD_Compute_dX(p, x_p, x_m, delta, dX) + TYPE(MD_ParameterType) , INTENT(IN ) :: p !< parameters + TYPE(MD_ContinuousStateType), INTENT(IN ) :: x_p !< 1 = more console output + + PUBLIC :: Body_Setup + PUBLIC :: Body_Initialize + PUBLIC :: Body_InitializeUnfree + PUBLIC :: Body_SetKinematics + PUBLIC :: Body_SetState + PUBLIC :: Body_SetDependentKin + PUBLIC :: Body_GetStateDeriv + PUBLIC :: Body_DoRHS + PUBLIC :: Body_GetCoupledForce + PUBLIC :: Body_AddConnect + PUBLIC :: Body_AddRod + + + +CONTAINS + + + SUBROUTINE Body_Setup( Body, tempArray, p, ErrStat, ErrMsg) + + TYPE(MD_Body), INTENT(INOUT) :: Body ! the single body object of interest + REAL(DbKi), INTENT(IN) :: tempArray(6) ! initial pose of body + TYPE(MD_ParameterType), INTENT(IN ) :: p ! Parameters + INTEGER, INTENT(INOUT ) :: ErrStat ! returns a non-zero value when an error occurs + CHARACTER(*), INTENT(INOUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + INTEGER(4) :: J ! Generic index + INTEGER(4) :: K ! Generic index + INTEGER(IntKi) :: N + + REAL(DbKi) :: Mtemp(6,6) + + ! set initial velocity to zero + Body%v6 = 0.0_DbKi + + !also set number of attached rods and points to zero initially + Body%nAttachedC = 0 + Body%nAttachedR = 0 + + ! set up body initial mass matrix (excluding any rods or attachements) + DO J=1,3 + Mtemp(J,J) = Body%BodyM ! fill in mass + Mtemp(3+J,3+J) = Body%BodyI(J) ! fill in inertia + END DO + + CALL TranslateMass6to6DOF(Body%rCG, Mtemp, Body%M0) ! account for potential CG offset <<< is the direction right? <<< + + DO J=1,3 + Body%M0(J,J) = Body%M0(J,J) + Body%BodyV*Body%BodyCa(J) ! add added mass in each direction about ref point (so only diagonals) <<< eventually expand to multi D + END DO + + ! --------------- if this is an independent body (not coupled) ---------- + ! set initial position and orientation of body from input file + Body%r6 = tempArray + + ! calculate orientation matrix based on latest angles + !RotMat(r6[3], r6[4], r6[5], OrMat); + Body%OrMat = TRANSPOSE( EulerConstruct( Body%r6(4:6) ) ) ! full Euler angle approach <<<< need to check order + + IF (wordy > 0) print *, "Set up Body ",Body%IdNum, ", type ", Body%typeNum + + ! need to add cleanup sub <<< + + END SUBROUTINE Body_Setup + +! ! used to initialize bodies that aren't free i.e. don't have states +! !-------------------------------------------------------------- +! SUBROUTINE Body_InitializeUnfree(Body, r6_in, mesh, mesh_index, m) +! +! Type(MD_Body), INTENT(INOUT) :: Body ! the Body object +! Real(DbKi), INTENT(IN ) :: r6_in(6) ! state vector section for this line +! TYPE(MeshType), INTENT(INOUT) :: mesh ! +! Integer(IntKi), INTENT(IN ) :: mesh_index ! index of the node in the mesh for the current object being initialized +! TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects +! +! INTEGER(IntKi) :: l ! index of segments or nodes along line +! REAL(DbKi) :: rRef(3) ! reference position of mesh node +! REAL(DbKi) :: OrMat(3,3) ! DCM for body orientation based on r6_in +! REAL(DbKi) :: dummyStates(12) +! +! +! rRef = 0.0_DbKi ! <<< maybe this should be the offsets of the local platform origins from the global origins in future? And that's what's specificed by the Body input coordinates? +! +! CALL MeshPositionNode(mesh, mesh+index, rRef,ErrStat2,ErrMsg2)! "assign the coordinates (u%PtFairleadDisplacement%Position) of each node in the global coordinate space" +! +! CALL CheckError( ErrStat2, ErrMsg2 ) +! IF (ErrStat >= AbortErrLev) RETURN +! +! ! Apply offsets due to initial platform rotations and translations (fixed Jun 19, 2015) +! CALL SmllRotTrans('body rotation matrix', r6_in(4),r6_in(5),r6_in(6), OrMat, '', ErrStat2, ErrMsg2) +! mesh%TranslationDisp(1, mesh_index) = r6_in(1) + OrMat(1,1)*rRef(1) + OrMat(2,1)*rRef(2) + OrMat(3,1)*rRef(3) - rRef(1) +! mesh%TranslationDisp(2, mesh_index) = r6_in(2) + OrMat(1,2)*rRef(1) + OrMat(2,2)*rRef(2) + OrMat(3,2)*rRef(3) - rRef(2) +! mesh%TranslationDisp(3, mesh_index) = r6_in(3) + OrMat(1,3)*rRef(1) + OrMat(2,3)*rRef(2) + OrMat(3,3)*rRef(3) - rRef(3) +! +! ! what about node point orientation ??? +! +! ! If any Rod is fixed to the body (not pinned), initialize it now because otherwise it won't be initialized +! DO l=1, Body%nAttachedR +! if (m%RodList(Body%attachedR(l))%typeNum == 2) CALL Rod_Initialize(m%RodList(Body%attachedR(l)), dummyStates, m%LineList) +! END DO +! +! ! Note: Connections don't need any initialization +! +! END SUBROUTINE Body_InitializeUnfree +! !-------------------------------------------------------------- + + + ! used to initialize bodies that are free + !-------------------------------------------------------------- + SUBROUTINE Body_Initialize(Body, states, m) + + Type(MD_Body), INTENT(INOUT) :: Body ! the Body object + Real(DbKi), INTENT(INOUT) :: states(:) ! state vector section for this Body + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + + INTEGER(IntKi) :: l ! index of segments or nodes along line + REAL(DbKi) :: dummyStates(12) ! dummy vector to mimic states when initializing a rigidly attached rod + + + ! assign initial body kinematics to state vector + states(7:12) = Body%r6 + states(1:6 ) = Body%v6 + + + ! set positions of any dependent connections and rods now (before they are initialized) + CALL Body_SetDependentKin(Body, 0.0_DbKi, m) + + ! If any Rod is fixed to the body (not pinned), initialize it now because otherwise it won't be initialized + DO l=1, Body%nAttachedR + if (m%RodList(Body%attachedR(l))%typeNum == 2) CALL Rod_Initialize(m%RodList(Body%attachedR(l)), dummyStates, m) + END DO + + ! Note: Connections don't need any initialization + + END SUBROUTINE Body_Initialize + !-------------------------------------------------------------- + + ! used to initialize bodies that are coupled or fixed + !-------------------------------------------------------------- + SUBROUTINE Body_InitializeUnfree(Body, m) + + Type(MD_Body), INTENT(INOUT) :: Body ! the Body object + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + + INTEGER(IntKi) :: l ! index of segments or nodes along line + REAL(DbKi) :: dummyStates(12) ! dummy vector to mimic states when initializing a rigidly attached rod + + + ! set positions of any dependent connections and rods now (before they are initialized) + CALL Body_SetDependentKin(Body, 0.0_DbKi, m) + + ! If any Rod is fixed to the body (not pinned), initialize it now because otherwise it won't be initialized + DO l=1, Body%nAttachedR + if (m%RodList(Body%attachedR(l))%typeNum == 2) CALL Rod_Initialize(m%RodList(Body%attachedR(l)), dummyStates, m) + END DO + + ! Note: Connections don't need any initialization + + END SUBROUTINE Body_InitializeUnfree + !-------------------------------------------------------------- + + + + + ! set kinematics for Bodies if they are coupled (or ground) + !-------------------------------------------------------------- + SUBROUTINE Body_SetKinematics(Body, r_in, v_in, a_in, t, m) + + Type(MD_Body), INTENT(INOUT) :: Body ! the Body object + Real(DbKi), INTENT(IN ) :: r_in(6) ! 6-DOF position + Real(DbKi), INTENT(IN ) :: v_in(6) ! 6-DOF velocity + Real(DbKi), INTENT(IN ) :: a_in(6) ! 6-DOF acceleration (only used for coupled rods) + Real(DbKi), INTENT(IN ) :: t ! instantaneous time + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects (for simplicity, since Bodies deal with Rods and Connections) + + + INTEGER(IntKi) :: l + + ! store current time + Body%time = t + + ! if (abs(Body%typeNum) == 2) then ! body coupled in 6 DOF, or ground + Body%r6 = r_in + Body%v6 = v_in + Body%a6 = a_in + + ! since this body has no states and all DOFs have been set, pass its kinematics to dependent attachments + CALL Body_SetDependentKin(Body, t, m) + + ! else if (abs(Body%typeNum) == 1) then ! body pinned at reference point + ! + ! ! set Body *end A only* kinematics based on BCs (linear model for now) + ! Body%r6(1:3) = r_in(1:3) + ! Body%v6(1:3) = v_in(1:3) + ! + ! ! Body is pinned so only ref point posiiton is specified, rotations are left alone and will be + ! ! handled, along with passing kinematics to attached objects, by separate call to setState + ! + ! else + ! print *, "Error: Body_SetKinematics called for a free Body." ! <<< + ! end if + + END SUBROUTINE Body_SetKinematics + !-------------------------------------------------------------- + + + !-------------------------------------------------------------- + SUBROUTINE Body_SetState(Body, X, t, m) + + Type(MD_Body), INTENT(INOUT) :: Body ! the Body object + Real(DbKi), INTENT(IN ) :: X(:) ! state vector section for this line + Real(DbKi), INTENT(IN ) :: t ! instantaneous time + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + + INTEGER(IntKi) :: l ! index of segments or nodes along line + INTEGER(IntKi) :: J ! index + + ! store current time + Body%time = t + + + + Body%r6 = X(7:12) ! get positions + Body%v6 = X(1:6) ! get velocities + + + ! set positions of any dependent connections and rods + CALL Body_SetDependentKin(Body, t, m) + + END SUBROUTINE Body_SetState + !-------------------------------------------------------------- + + + ! set the states (positions and velocities) of any connects or rods that are part of this body + ! also computes the orientation matrix (never skip this sub!) + !-------------------------------------------------------------- + SUBROUTINE Body_SetDependentKin(Body, t, m) + + Type(MD_Body), INTENT(INOUT) :: Body ! the Bodyion object + REAL(DbKi), INTENT(IN ) :: t + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects (for simplicity, since Bodies deal with Rods and Connections) + + INTEGER(IntKi) :: l ! index of attached objects + + Real(DbKi) :: rConnect(3) + Real(DbKi) :: rdConnect(3) + Real(DbKi) :: rRod(6) + Real(DbKi) :: vRod(6) + Real(DbKi) :: aRod(6) + + + + ! calculate orientation matrix based on latest angles + !CALL SmllRotTrans('', Body%r6(4), Body%r6(5), Body%r6(6), Body%TransMat, '', ErrStat2, ErrMsg2) + Body%OrMat = TRANSPOSE( EulerConstruct( Body%r6(4:6) ) ) ! full Euler angle approach <<<< need to check order + + ! set kinematics of any dependent connections + do l = 1,Body%nAttachedC + + CALL transformKinematics(Body%rConnectRel(:,l), Body%r6, Body%OrMat, Body%v6, rConnect, rdConnect) !<<< should double check this function + + ! >>> need to add acceleration terms here too? <<< + + ! pass above to the connection and get it to calculate the forces + CALL Connect_SetKinematics( m%ConnectList(Body%attachedC(l)), rConnect, rdConnect, m%zeros6(1:3), t, m) + end do + + ! set kinematics of any dependent Rods + do l=1,Body%nAttachedR + + ! calculate displaced coordinates/orientation and velocities of each rod <<<<<<<<<<<<< + ! do 3d details of Rod ref point + CALL TransformKinematicsA( Body%r6RodRel(1:3,l), Body%r6(1:3), Body%OrMat, Body%v6, Body%a6, rRod(1:3), vRod(1:3), aRod(1:3)) ! set first three entires (end A translation) of rRod and rdRod + ! does the above function need to take in all 6 elements of r6RodRel?? + + ! do rotational stuff + rRod(4:6) = MATMUL(Body%OrMat, Body%r6RodRel(4:6,l)) !<<<<<< correct? <<<<< rotateVector3(r6RodRel[i]+3, OrMat, rRod+3); ! rotate rod relative unit vector by OrMat to get unit vec in reference coords + vRod(4:6) = Body%v6(4:6) ! transformed rotational velocity. <<< is this okay as is? <<<< + aRod(4:6) = Body%a6(4:6) + + ! pass above to the rod and get it to calculate the forces + CALL Rod_SetKinematics(m%RodList(Body%attachedR(l)), rRod, vRod, aRod, t, m) + end do + + END SUBROUTINE Body_SetDependentKin + !-------------------------------------------------------------- + + + !-------------------------------------------------------------- + SUBROUTINE Body_GetStateDeriv(Body, Xd, m, p) + + Type(MD_Body), INTENT(INOUT) :: Body ! the Bodyion object + Real(DbKi), INTENT(INOUT) :: Xd(:) ! state derivative vector section for this line + + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + TYPE(MD_ParameterType),INTENT(IN ) :: p ! Parameters + + INTEGER(IntKi) :: J ! index + + Real(DbKi) :: acc(6) ! 6DOF acceleration vector + + Real(DbKi) :: y_temp (6) ! temporary vector for LU decomposition + Real(DbKi) :: LU_temp(6,6) ! temporary matrix for LU decomposition + + + ! Initialize temp variables + y_temp = 0.0_DbKi +! FIXME: should LU_temp be set to M_out before calling LUsolve????? + LU_temp = 0.0_DbKi + + CALL Body_DoRHS(Body, m, p) + + ! solve for accelerations in [M]{a}={f} using LU decomposition + CALL LUsolve(6, Body%M, LU_temp, Body%F6net, y_temp, acc) + + ! fill in state derivatives + Xd(7:12) = Body%v6 ! dxdt = V (velocities) + Xd(1:6) = acc ! dVdt = a (accelerations) + + ! store accelerations in case they're useful as output + Body%a6 = acc + + ! check for NaNs (should check all state derivatives, not just first 6) + DO J = 1, 6 + IF (Is_NaN(Xd(J))) THEN + CALL WrScr("NaN detected at time "//trim(Num2LStr(Body%time))//" in Body "//trim(Int2LStr(Body%IdNum))//"in MoorDyn,") + IF (wordy > 0) print *, "state derivatives:" + IF (wordy > 0) print *, Xd + EXIT + END IF + END DO + + + END SUBROUTINE Body_GetStateDeriv + !-------------------------------------------------------------- + + !-------------------------------------------------------------- + SUBROUTINE Body_DoRHS(Body, m, p) + + Type(MD_Body), INTENT(INOUT) :: Body ! the Bodyion object + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + TYPE(MD_ParameterType),INTENT(IN ) :: p ! Parameters + + !TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! misc/optimization variables + + INTEGER(IntKi) :: l ! index of attached lines + INTEGER(IntKi) :: I ! index + INTEGER(IntKi) :: J ! index + INTEGER(IntKi) :: K ! index + + Real(DbKi) :: Fgrav(3) ! body weight force + Real(DbKi) :: body_rCGrotated(3) ! instantaneous vector from body ref point to CG + Real(DbKi) :: U(3) ! water velocity - zero for now + Real(DbKi) :: Ud(3) ! water acceleration- zero for now + Real(DbKi) :: vi(6) ! relative water velocity (last 3 terms are rotatonal and will be set to zero + Real(DbKi) :: F6_i(6) ! net force and moments from an attached object + Real(DbKi) :: M6_i(6,6) ! mass and inertia from an attached object + + ! Initialize variables + U = 0.0_DbKi ! Set to zero for now + Body%F6net = 0.0_DbKi + + ! First, the body's own mass matrix must be adjusted based on its orientation so that + ! we have a mass matrix in the global orientation frame + Body%M = RotateM6(Body%M0, Body%OrMat) + + !gravity on core body + Fgrav(1) = 0.0_DbKi + Fgrav(2) = 0.0_DbKi + Fgrav(3) = Body%bodyV * p%rhow * p%g - Body%bodyM * p%g ! weight+buoyancy vector + + body_rCGrotated = MATMUL(Body%OrMat, Body%rCG) ! rotateVector3(body_rCG, OrMat, body_rCGrotated); ! relative vector to body CG in inertial orientation + CALL translateForce3to6DOF(body_rCGrotated, Fgrav, Body%F6net) ! gravity forces and moments about body ref point given CG location + + + ! --------------------------------- apply wave kinematics ------------------------------------ + !env->waves->getU(r6, t, U); ! call generic function to get water velocities <<<<<<<<< all needs updating + + ! for (int J=0; J<3; J++) + ! Ud[J] = 0.0; ! set water accelerations as zero for now + ! ------------------------------------------------------------------------------------------ + + ! viscous drag calculation (on core body) + vi(1:3) = U - Body%v6(1:3) ! relative flow velocity over body ref point + vi(4:6) = - Body%v6(4:6) ! for rotation, this is just the negative of the body's rotation for now (not allowing flow rotation) + + Body%F6net = Body%F6net + 0.5*p%rhoW * vi * abs(vi) * Body%bodyCdA + ! <<< NOTE, for body this should be fixed to account for orientation!! <<< what about drag in rotational DOFs??? <<<<<<<<<<<<<< + + + + ! Get contributions from any dependent connections + do l = 1,Body%nAttachedC + + ! get net force and mass from Connection on body ref point (global orientation) + CALL Connect_GetNetForceAndMass( m%ConnectList(Body%attachedC(l)), Body%r6(1:3), F6_i, M6_i, m, p) + + if (ABS(F6_i(5)) > 1.0E12) then + print *, "Warning: extreme pitch moment from body-attached Point ", l + end if + + ! sum quantitites + Body%F6net = Body%F6net + F6_i + Body%M = Body%M + M6_i + end do + + ! Get contributions from any dependent Rods + do l=1,Body%nAttachedR + + ! get net force and mass from Rod on body ref point (global orientation) + CALL Rod_GetNetForceAndMass(m%RodList(Body%attachedR(l)), Body%r6(1:3), F6_i, M6_i, m, p) + + if (ABS(F6_i(5)) > 1.0E12) then + print *, "Warning: extreme pitch moment from body-attached Rod ", l + end if + + ! sum quantitites + Body%F6net = Body%F6net + F6_i + Body%M = Body%M + M6_i + end do + + + END SUBROUTINE Body_DoRHS + !===================================================================== + + + ! calculate the aggregate 3/6DOF rigid-body loads of a coupled rod including inertial loads + !-------------------------------------------------------------- + SUBROUTINE Body_GetCoupledForce(Body, Fnet_out, m, p) + + Type(MD_Body), INTENT(INOUT) :: Body ! the Body object + Real(DbKi), INTENT( OUT) :: Fnet_out(6) ! force and moment vector + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + TYPE(MD_ParameterType),INTENT(IN ) :: p ! Parameters + + Real(DbKi) :: F6_iner(6) ! inertial reaction force + + ! do calculations of forces and masses on the body + CALL Body_DoRHS(Body, m, p) + + ! add inertial loads as appropriate + if (Body%typeNum == -1) then + + F6_iner = 0.0_DbKi !-MATMUL(Body%M, Body%a6) <<<<<<<< why does including F6_iner cause instability??? + Fnet_out = Body%F6net + F6_iner ! add inertial loads + + else + print *, "ERROR, Body_GetCoupledForce called for wrong (non-coupled) body type in MoorDyn!" + end if + + END SUBROUTINE Body_GetCoupledForce + !-------------------------------------------------------------- + + + + ! this function handles assigning a connection to a body + !-------------------------------------------------------------- + SUBROUTINE Body_AddConnect(Body, connectID, coords) + + Type(MD_Body), INTENT(INOUT) :: Body ! the Connection object + Integer(IntKi), INTENT(IN ) :: connectID + REAL(DbKi), INTENT(IN ) :: coords(3) + + + IF (wordy > 0) Print*, "C", connectID, "->B", Body%IdNum + + IF(Body%nAttachedC < 30) THEN ! this is currently just a maximum imposed by a fixed array size. could be improved. + Body%nAttachedC = Body%nAttachedC + 1 ! increment the number connected + Body%AttachedC(Body%nAttachedC) = connectID + Body%rConnectRel(:,Body%nAttachedC) = coords ! store relative position of connect on body + ELSE + Print*, "too many Points attached to Body ", Body%IdNum, " in MoorDyn!" + END IF + + END SUBROUTINE Body_AddConnect + + + ! this function handles assigning a rod to a body + !-------------------------------------------------------------- + SUBROUTINE Body_AddRod(Body, rodID, coords) + + Type(MD_Body), INTENT(INOUT) :: Body ! the Connection object + Integer(IntKi), INTENT(IN ) :: rodID + REAL(DbKi), INTENT(IN ) :: coords(6) ! positions of rod ends A and B relative to body + + REAL(DbKi) :: tempUnitVec(3) + REAL(DbKi) :: dummyLength + + IF (wordy > 0) Print*, "R", rodID, "->B", Body%IdNum + + IF(Body%nAttachedR < 30) THEN ! this is currently just a maximum imposed by a fixed array size. could be improved. + Body%nAttachedR = Body%nAttachedR + 1 ! increment the number connected + + ! store rod ID + Body%AttachedR(Body%nAttachedR) = rodID + + ! store Rod end A relative position and unit vector from end A to B + CALL UnitVector(coords(1:3), coords(4:6), tempUnitVec, dummyLength) + Body%r6RodRel(1:3, Body%nAttachedR) = coords(1:3) + Body%r6RodRel(4:6, Body%nAttachedR) = tempUnitVec + + ELSE + Print*, "too many rods attached to Body ", Body%IdNum, " in MoorDyn" + END IF + + END SUBROUTINE Body_AddRod + + + +END MODULE MoorDyn_Body diff --git a/modules/moordyn/src/MoorDyn_C_Binding.f90 b/modules/moordyn/src/MoorDyn_C_Binding.f90 new file mode 100644 index 000000000..28c8e0bca --- /dev/null +++ b/modules/moordyn/src/MoorDyn_C_Binding.f90 @@ -0,0 +1,745 @@ +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2021 National Renewable Energy Laboratory +! Author: Nicole Mendoza +! +! This file is part of MoorDyn. +! +! 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 MoorDyn_C + + USE ISO_C_BINDING + USE MoorDyn + USE MoorDyn_Types + USE NWTC_Library + USE VersionInfo + +IMPLICIT NONE + +PUBLIC :: MD_C_Init +PUBLIC :: MD_C_UpdateStates +PUBLIC :: MD_C_CalcOutput +PUBLIC :: MD_C_End + +!------------------------------------------------------------------------------------ +! Error handling +! This must exactly match the value in the python-lib. If ErrMsgLen changes at +! some point in the nwtc-library, this should be updated, but the logic exists +! to correctly handle different lengths of the strings +integer(IntKi), parameter :: ErrMsgLen_C = 1025 +integer(IntKi), parameter :: IntfStrLen = 1025 ! length of other strings through the C interface + + +!------------------------------------------------------------------------------------ +! Version info for display +TYPE(ProgDesc), PARAMETER :: version = ProgDesc( 'MoorDyn library', '', '' ) + + +!-------------------------------------------------------------------------------------------------------------------------------------------------------- +! Data storage +! All MoorDyn data is stored within the following data structures inside this +! module. No data is stored within MoorDyn itself, but is instead passed in +! from this module. This data is not available to the calling code unless +! explicitly passed through the interface (derived types such as these are +! non-trivial to pass through the c-bindings). +TYPE(MD_InitInputType) :: InitInp !< Input data for initialization routine +TYPE(MD_InputType), ALLOCATABLE :: u(:) !< An initial guess for the input; input mesh must be defined +TYPE(MD_ParameterType) :: p !< Parameters +TYPE(MD_ContinuousStateType) :: x(0:2) !< Initial continuous states +TYPE(MD_DiscreteStateType) :: xd(0:2) !< Initial discrete states +TYPE(MD_ConstraintStateType) :: z(0:2) !< Initial constraint states +TYPE(MD_OtherStateType) :: other(0:2) !< Initial other states +TYPE(MD_OutputType) :: y !< Initial system outputs (outputs are not calculated; only the output mesh is initialized) +TYPE(MD_MiscVarType) :: m !< Initial misc/optimization variables +TYPE(MD_InitOutputType) :: InitOutData !< Output for initialization routine + +!-------------------------------------------------------------------------------------------------------------------------------------------------------- +! Time tracking +! For the solver in MD, previous timesteps input must be stored for extrapolation +! to the t+dt timestep. This can be either linear (1) quadratic (2). The +! InterpOrder variable tracks what this is and sets the size of the inputs `u` +! passed into MD. Inputs `u` will be sized as follows: +! linear interp u(2) with inputs at T,T-dt +! quadratic interp u(3) with inputs at T,T-dt,T-2*dt +! Time tracking +! When we are performing a correction step, time information of previous +! calls is needed to decide how to apply correction logic or cycle the inputs +! and resave the previous timestep states. +! Correction steps +! OpenFAST has the ability to perform correction steps. During a correction +! step, new input values are passed in but the timestep remains the same. +! When this occurs the new input data at time t is used with the state +! information from the previous timestep (t) to calculate new state values +! time t+dt in the UpdateStates routine. In OpenFAST this is all handled by +! the glue code. However, here we do not pass state information through the +! interface and therefore must store it here analogously to how it is handled +! in the OpenFAST glue code. +INTEGER(IntKi) :: InterpOrder !< Interpolation order: must be 1 (linear) or 2 (quadratic) +REAL(DbKi), DIMENSION(:), ALLOCATABLE :: InputTimes(:) !< InputTimes array +REAL(DbKi) :: InputTimePrev !< input time of last UpdateStates call +real(DbKi) :: dT_Global !< dT of the code calling this module +integer(IntKi) :: N_Global !< global timestep +real(DbKi) :: T_Initial !< initial Time of simulation + +! We are including the previous state info here (not done in OpenFAST this way) +INTEGER(IntKi), PARAMETER :: STATE_LAST = 0 !< Index for previous state (not needed in OF, but necessary here) +INTEGER(IntKi), PARAMETER :: STATE_CURR = 1 !< Index for current state +INTEGER(IntKi), PARAMETER :: STATE_PRED = 2 !< Index for predicted state + +! Note the indexing is different on inputs (no clue why, but thats how OF handles it) +INTEGER(IntKi), PARAMETER :: INPUT_LAST = 3 !< Index for previous input at t-dt +INTEGER(IntKi), PARAMETER :: INPUT_CURR = 2 !< Index for current input at t +INTEGER(IntKi), PARAMETER :: INPUT_PRED = 1 !< Index for predicted input at t+dt + +!-------------------------------------------------------------------------------------------------------------------------------------------------------- +! Meshes for motions and loads +! Meshes are used within MD to handle all motions and loads. Rather than directly +! map to those nodes, we will create a mapping to go between the array of node +! positions passed into this module and what is used inside MD. This is done +! through a pair of meshes for the motion and loads corresponding to the node +! positions passed in. +!------------------------------ +! Meshes for external nodes +! These point meshes are merely used to simplify the mapping of motions/loads +! to/from MD using the library mesh mapping routines. These meshes may contain +! one or multiple points. +! - 1 point -- rigid floating body assumption +! - N points -- flexible structure (either floating or fixed bottom) +TYPE(MeshType) :: MD_MotionMesh !< mesh for motions of external nodes +TYPE(MeshType) :: MD_LoadMesh !< mesh for loads for external nodes +TYPE(MeshMapType) :: Map_Motion_2_MD !< Mesh mapping between input motion mesh and MD +TYPE(MeshMapType) :: Map_MD_2_Load !< Mesh mapping between MD output loads mesh and external nodes mesh + +! Motions input (so that we don't have to reallocate all the time) +REAL(ReKi) :: tmpPositions(6,1) !< temp array. Probably don't need this, but makes conversion from C clearer. +REAL(ReKi) :: tmpVelocities(6,1) !< temp array. Probably don't need this, but makes conversion from C clearer. +REAL(ReKi) :: tmpAccelerations(6,1) !< temp array. Probably don't need this, but makes conversion from C clearer. +REAL(ReKi) :: tmpForces(6,1) !< temp array. Probably don't need this, but makes conversion to C clearer. + +CONTAINS + +!> This routine sets the error status in C_CHAR for export to calling code. +!! Make absolutely certain that we do not overrun the end of ErrMsg_C. That is hard coded to 1025, +!! but ErrMsgLen is set in the nwtc_library, and could change without updates here. We don't want an +!! inadvertant buffer overrun -- that can lead to bad things. +subroutine SetErr(ErrStat, ErrMsg, ErrStat_C, ErrMsg_C) + integer, intent(in ) :: ErrStat !< aggregated error message (fortran type) + character(ErrMsgLen), intent(in ) :: ErrMsg !< aggregated error message (fortran type) + integer(c_int), intent( out) :: ErrStat_C + character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) + integer :: i + ErrStat_C = ErrStat ! We will send back the same error status that is used in OpenFAST + if (ErrMsgLen > ErrMsgLen_C-1) then ! If ErrMsgLen is > the space in ErrMsg_C, do not copy everything over + ErrMsg_C = TRANSFER( trim(ErrMsg(1:ErrMsgLen_C-1))//C_NULL_CHAR, ErrMsg_C ) + else + ErrMsg_C = TRANSFER( trim(ErrMsg)//C_NULL_CHAR, ErrMsg_C ) + endif +end subroutine SetErr + +!=============================================================================================================== +!---------------------------------------------- MD INIT -------------------------------------------------------- +!=============================================================================================================== +SUBROUTINE MD_C_Init(InputFileString_C, InputFileStringLength_C, DT_C, G_C, RHO_C, DEPTH_C, PtfmInit_C, InterpOrder_C, NumChannels_C, OutputChannelNames_C, OutputChannelUnits_C, ErrStat_C, ErrMsg_C) BIND (C, NAME='MD_C_Init') +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: MD_C_Init +!GCC$ ATTRIBUTES DLLEXPORT :: MD_C_Init +#endif + TYPE(C_PTR) , INTENT(IN ) :: InputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR + INTEGER(C_INT) , INTENT(IN ) :: InputFileStringLength_C !< length of the input file string + REAL(C_DOUBLE) , INTENT(IN ) :: DT_C + REAL(C_FLOAT) , INTENT(IN ) :: G_C + REAL(C_FLOAT) , INTENT(IN ) :: RHO_C + REAL(C_FLOAT) , INTENT(IN ) :: DEPTH_C + REAL(C_FLOAT) , INTENT(IN ) :: PtfmInit_C(6) + INTEGER(C_INT) , INTENT(IN ) :: InterpOrder_C + INTEGER(C_INT) , INTENT( OUT) :: NumChannels_C + CHARACTER(KIND=C_CHAR) , INTENT( OUT) :: OutputChannelNames_C(100000) + CHARACTER(KIND=C_CHAR) , INTENT( OUT) :: OutputChannelUnits_C(100000) + INTEGER(C_INT) , INTENT( OUT) :: ErrStat_C + CHARACTER(KIND=C_CHAR) , INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) + + ! Local Variables + CHARACTER(KIND=C_char, LEN=InputFileStringLength_C), POINTER :: InputFileString !< Input file as a single string with NULL chracter separating lines + INTEGER(IntKi) :: ErrStat, ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg, ErrMsg2 + INTEGER :: I, J, K + character(*), parameter :: RoutineName = 'MD_C_Init' + + + ! Initialize library and display info on this compile + ErrStat = ErrID_None + ErrMsg = '' + + CALL NWTC_Init( ProgNameIn=version%Name ) + CALL DispCopyrightLicense( version%Name ) + CALL DispCompileRuntimeInfo( version%Name ) + + + + ! Convert the MD input file to FileInfoType + !---------------------------------------------------------------------------------------------------------------------------------------------- + + ! Get fortran pointer to C_NULL_CHAR deliniated input file as a string + CALL C_F_pointer(InputFileString_C, InputFileString) + + ! Convert string inputs to FileInfoType + CALL InitFileInfo(InputFileString, InitInp%PassedPrimaryInputData, ErrStat2, ErrMsg2); if (Failed()) return + + ! Set other inputs for calling MD_Init + !---------------------------------------------------------------------------------------------------------------------------------------------- + + ! Check the interpolation order + IF (InterpOrder_C .EQ. 1 .OR. InterpOrder_C .EQ. 2) THEN + InterpOrder = INT(InterpOrder_C, IntKi) + call AllocAry( InputTimes, InterpOrder+1, 'InputTimes', ErrStat2, ErrMsg2); if (Failed()) return + ELSE + ErrStat2 = ErrID_Fatal + ErrMsg2 = 'InterpOrder must be 1 (linear) or 2 (quadratic)' + if (Failed()) return + END IF + + dT_Global = REAL(DT_C, DbKi) + N_Global = 0_IntKi ! Assume we are on timestep 0 at start + InitInp%FileName = 'notUsed' + InitInp%RootName = 'MDroot' + InitInp%UsePrimaryInputFile = .FALSE. + + ! Environment variables -- These should be passed in from C. + InitInp%g = REAL(G_C, ReKi) + InitInp%rhoW = REAL(RHO_C, ReKi) + InitInp%WtrDepth = REAL(DEPTH_C, ReKi) + + ! Platform position (x,y,z,Rx,Ry,Rz) -- where rotations are small angle assumption in radians. + ! This data is used to set the CoupledKinematics mesh that will be used at each timestep call + CALL AllocAry (InitInp%PtfmInit, 6, 1, 'InitInp%PtfmInit', ErrStat2, ErrMsg2 ); if (Failed()) return + DO I = 1,6 + InitInp%PtfmInit(I,1) = REAL(PtfmInit_C(I),ReKi) + END DO + + ALLOCATE(u(InterpOrder+1), STAT=ErrStat2) + if (ErrStat2 /= 0) then + ErrStat2 = ErrID_Fatal + ErrMsg2 = 'Failed to allocate Inputs type for MD' + if (Failed()) return + endif + + !------------------------------------------------- + ! Call the main subroutine MD_Init + !------------------------------------------------- + CALL MD_Init(InitInp, u(1), p, x(STATE_CURR), xd(STATE_CURR), z(STATE_CURR), other(STATE_CURR), y, m, dT_Global, InitOutData, ErrStat2, ErrMsg2); if (Failed()) return + + !------------------------------------------------- + ! Set output channel information for driver code + !------------------------------------------------- + + ! Number of channels + NumChannels_C = size(InitOutData%WriteOutputHdr) + + ! Transfer the output channel names and units to c_char arrays for returning + k=1 + DO i=1,NumChannels_C + DO j=1,ChanLen ! max length of channel name. Same for units + OutputChannelNames_C(k)=InitOutData%WriteOutputHdr(i)(j:j) + OutputChannelUnits_C(k)=InitOutData%WriteOutputUnt(i)(j:j) + k=k+1 + END DO + END DO + + ! Null terminate the string + OutputChannelNames_C(k) = C_NULL_CHAR + OutputChannelUnits_C(k) = C_NULL_CHAR + + !------------------------------------------------------------- + ! Set the interface meshes for motion inputs and loads output + !------------------------------------------------------------- + DO i = 1,6 + tmpPositions(i,1) = REAL(PtfmInit_C(i),ReKi) + END DO + tmpVelocities = 0_ReKi + tmpAccelerations = 0_ReKi + CALL SetMotionLoadsInterfaceMeshes(ErrStat2,ErrMsg2); if (Failed()) return + + DO i=2,InterpOrder+1 + CALL MD_CopyInput (u(1), u(i), MESH_NEWCOPY, Errstat2, ErrMsg2); if (Failed()) return + END DO + InputTimePrev = -dT_Global ! Initialize for MD_C_UpdateStates + + !------------------------------------------------------------- + ! Initial setup of other pieces of x,xd,z,other + !------------------------------------------------------------- + CALL MD_CopyContState ( x( STATE_CURR), x( STATE_PRED), MESH_NEWCOPY, ErrStat2, ErrMsg2); if (Failed()) return + CALL MD_CopyDiscState ( xd( STATE_CURR), xd( STATE_PRED), MESH_NEWCOPY, ErrStat2, ErrMsg2); if (Failed()) return + CALL MD_CopyConstrState( z( STATE_CURR), z( STATE_PRED), MESH_NEWCOPY, ErrStat2, ErrMsg2); if (Failed()) return + CALL MD_CopyOtherState ( other(STATE_CURR), other(STATE_PRED), MESH_NEWCOPY, ErrStat2, ErrMsg2); if (Failed()) return + + !------------------------------------------------------------- + ! Setup the previous timestep copies of states + !------------------------------------------------------------- + CALL MD_CopyContState ( x( STATE_CURR), x( STATE_LAST), MESH_NEWCOPY, ErrStat2, ErrMsg2); if (Failed()) return + CALL MD_CopyDiscState ( xd( STATE_CURR), xd( STATE_LAST), MESH_NEWCOPY, ErrStat2, ErrMsg2); if (Failed()) return + CALL MD_CopyConstrState( z( STATE_CURR), z( STATE_LAST), MESH_NEWCOPY, ErrStat2, ErrMsg2); if (Failed()) return + CALL MD_CopyOtherState ( other(STATE_CURR), other(STATE_LAST), MESH_NEWCOPY, ErrStat2, ErrMsg2); if (Failed()) return + + !------------------------------------------------- + ! Clean up variables and set up for MD_C_CalcOutput + !------------------------------------------------- + CALL MD_DestroyInitInput( InitInp, ErrStat2, ErrMsg2 ); if (Failed()) return + CALL MD_DestroyInitOutput( InitOutData, ErrStat2, ErrMsg2 ); if (Failed()) return + + call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) + + +CONTAINS + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + if (Failed) then + call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) + endif + end function Failed +END SUBROUTINE MD_C_Init + +!=============================================================================================================== +!---------------------------------------------- MD UPDATE STATES ----------------------------------------------- +!=============================================================================================================== +SUBROUTINE MD_C_UpdateStates(Time_C, TimeNext_C, POSITIONS_C, VELOCITIES_C, ACCELERATIONS_C, ErrStat_C, ErrMsg_C) BIND (C, NAME='MD_C_UpdateStates') +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: MD_C_UpdateStates +!GCC$ ATTRIBUTES DLLEXPORT :: MD_C_UpdateStates +#endif + real(c_double), intent(in ) :: Time_C + real(c_double), intent(in ) :: TimeNext_C + REAL(C_FLOAT) , INTENT(IN ) :: POSITIONS_C(1,6) + REAL(C_FLOAT) , INTENT(IN ) :: VELOCITIES_C(1,6) + REAL(C_FLOAT) , INTENT(IN ) :: ACCELERATIONS_C(1,6) + INTEGER(C_INT) , INTENT( OUT) :: ErrStat_C + CHARACTER(KIND=C_CHAR) , INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) + + ! Local Variables + INTEGER(IntKi) :: ErrStat, ErrStat2, J + CHARACTER(ErrMsgLen) :: ErrMsg, ErrMsg2 + LOGICAL :: CorrectionStep + character(*), parameter :: RoutineName = 'MD_C_UpdateStates' + + ! Set up error handling for MD_C_CalcOutput + ErrStat = ErrID_None + ErrMsg = '' + CorrectionStep = .FALSE. + + !------------------------------------------------------- + ! Check the time for current timestep and next timestep + !------------------------------------------------------- + ! These inputs are used in the time stepping algorithm within MD_UpdateStates + ! For quadratic interpolation (InterpOrder==2), 3 timesteps are used. For + ! linear (InterOrder==1), 2 timesteps (the MD code can handle either). + ! u(1) inputs at t + dt ! Next timestep + ! u(2) inputs at t ! This timestep + ! u(3) inputs at t - dt ! previous timestep (quadratic only) + ! + ! NOTE: Within MD, the Radiation calculations can be done at an integer multiple of the + ! timestep. This is checked at each UpdateStates call. However, if we compile + ! in double precision, the values of Time_C and TimeNext_C are in double precison, + ! but InputTimes is in DbKi (which is promoted quad precision when compiling in + ! double precision) and the check may fail. So we are going to set the times we + ! we pass over to UpdateStates using the global timestep and the stored DbKi value + ! for the timestep rather than the lower precision (when compiled double) time + ! values passed in. It is a bit of a clumsy workaround for this precision loss, + ! but should not affect any results. + + ! Check if we are repeating an UpdateStates call (for example in a predictor/corrector loop) + if ( EqualRealNos( real(Time_C,DbKi), InputTimePrev ) ) then + CorrectionStep = .true. + else ! Setup time input times array + InputTimePrev = real(Time_C,DbKi) ! Store for check next time + if (InterpOrder>1) then ! quadratic, so keep the old time + InputTimes(INPUT_LAST) = ( N_Global - 1 ) * dT_Global ! u(3) at T-dT + endif + InputTimes(INPUT_CURR) = N_Global * dT_Global ! u(2) at T + InputTimes(INPUT_PRED) = ( N_Global + 1 ) * dT_Global ! u(1) at T+dT + N_Global = N_Global + 1_IntKi ! increment counter to T+dT + endif + + + IF (CorrectionStep) THEN + ! Step back to previous state because we are doing a correction step + ! -- repeating the T -> T+dt update with new inputs at T+dt + ! -- the STATE_CURR contains states at T+dt from the previous call, so revert those + CALL MD_CopyContState (x( STATE_LAST), x( STATE_CURR), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + CALL MD_CopyDiscState (xd( STATE_LAST), xd( STATE_CURR), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + CALL MD_CopyConstrState (z( STATE_LAST), z( STATE_CURR), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + CALL MD_CopyOtherState (other(STATE_LAST), other(STATE_CURR), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + ELSE + ! Cycle inputs back one timestep since we are moving forward in time. + IF (InterpOrder>1) THEN ! quadratic, so keep the old time + CALL MD_CopyInput( u(INPUT_CURR), u(INPUT_LAST), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + END IF + ! Move inputs from previous t+dt (now t) to t + CALL MD_CopyInput( u(INPUT_PRED), u(INPUT_CURR), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + END IF + + ! Reshape position and velocity (transposing from a row vector to a column vector) + DO J = 1,6 + tmpPositions(J,1) = REAL(POSITIONS_C(1,J),ReKi) + tmpVelocities(J,1) = REAL(VELOCITIES_C(1,J),ReKi) + tmpAccelerations(J,1) = REAL(ACCELERATIONS_C(1,J),ReKi) + END DO + + ! Transfer motions to input meshes + CALL Set_MotionMesh( ErrStat2, ErrMsg2 ); IF (Failed()) RETURN + CALL MD_SetInputMotion( u(INPUT_PRED), ErrStat2, ErrMsg2 ); IF (Failed()) RETURN + + ! Set copy the current state over to the predicted state for sending to UpdateStates + ! -- The STATE_PREDicted will get updated in the call. + ! -- The UpdateStates routine expects this to contain states at T at the start of the call (history not passed in) + CALL MD_CopyContState (x( STATE_CURR), x( STATE_PRED), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + CALL MD_CopyDiscState (xd( STATE_CURR), xd( STATE_PRED), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + CALL MD_CopyConstrState (z( STATE_CURR), z( STATE_PRED), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + CALL MD_CopyOtherState (other(STATE_CURR), other(STATE_PRED), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + + !------------------------------------------------- + ! Call the main subroutine MD_UpdateStates + !------------------------------------------------- + CALL MD_UpdateStates( InputTimes(INPUT_CURR), N_Global, u, InputTimes, p, x(STATE_PRED), xd(STATE_PRED), z(STATE_PRED), other(STATE_PRED), m, ErrStat2, ErrMsg2); IF (Failed()) RETURN + + !------------------------------------------------------- + ! Cycle the states + !------------------------------------------------------- + ! Move current state at T to previous state at T-dt + ! -- STATE_LAST now contains info at time T + ! -- this allows repeating the T --> T+dt update + CALL MD_CopyContState (x( STATE_CURR), x( STATE_LAST), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + CALL MD_CopyDiscState (xd( STATE_CURR), xd( STATE_LAST), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + CALL MD_CopyConstrState (z( STATE_CURR), z( STATE_LAST), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + CALL MD_CopyOtherState (other(STATE_CURR), other(STATE_LAST), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + ! Update the predicted state as the new current state + ! -- we have now advanced from T to T+dt. This allows calling with CalcOuput to get the outputs at T+dt + CALL MD_CopyContState (x( STATE_PRED), x( STATE_CURR), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + CALL MD_CopyDiscState (xd( STATE_PRED), xd( STATE_CURR), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + CALL MD_CopyConstrState (z( STATE_PRED), z( STATE_CURR), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + CALL MD_CopyOtherState (other(STATE_PRED), other(STATE_CURR), MESH_UPDATECOPY, ErrStat2, ErrMsg2); IF (Failed()) RETURN + + + + call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) + +CONTAINS + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + if (Failed) call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) + end function Failed +END SUBROUTINE MD_C_UpdateStates + +!=============================================================================================================== +!---------------------------------------------- MD CALC OUTPUT ------------------------------------------------- +!=============================================================================================================== +!> Calculate the moordyn results iven the current set of states and inputs +SUBROUTINE MD_C_CalcOutput(Time_C, POSITIONS_C, VELOCITIES_C, ACCELERATIONS_C, FORCES_C, OUTPUTS_C, ErrStat_C, ErrMsg_C) BIND (C, NAME='MD_C_CalcOutput') +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: MD_C_CalcOutput +!GCC$ ATTRIBUTES DLLEXPORT :: MD_C_CalcOutput +#endif + REAL(C_DOUBLE) , INTENT(IN ) :: Time_C + REAL(C_FLOAT) , INTENT(IN ) :: POSITIONS_C(1,6) + REAL(C_FLOAT) , INTENT(IN ) :: VELOCITIES_C(1,6) + REAL(C_FLOAT) , INTENT(IN ) :: ACCELERATIONS_C(1,6) + REAL(C_FLOAT) , INTENT( OUT) :: FORCES_C(1,6) + REAL(C_FLOAT) , INTENT( OUT) :: OUTPUTS_C(p%NumOuts) + INTEGER(C_INT) , INTENT( OUT) :: ErrStat_C + CHARACTER(KIND=C_CHAR) , INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) + + ! Local Variables + REAL(DbKi) :: t + INTEGER(IntKi) :: ErrStat, ErrStat2, J + CHARACTER(ErrMsgLen) :: ErrMsg, ErrMsg2 + character(*), parameter :: RoutineName = 'MD_C_CalcOutput' + + ! Set up error handling for MD_C_CalcOutput + ErrStat = ErrID_None + ErrMsg = '' + + ! Set up inputs to MD_CalcOutput + !----------------------------------------------------------------------------------------------------------- + + ! Time + t = REAL(Time_C, DbKi) + + ! Reshape position and velocity (from row vector to a column vector) + DO J = 1,6 + tmpPositions(J,1) = REAL(POSITIONS_C(1,J),ReKi) + tmpVelocities(J,1) = REAL(VELOCITIES_C(1,J),ReKi) + tmpAccelerations(J,1) = REAL(ACCELERATIONS_C(1,J),ReKi) + END DO + + ! Transfer motions to input meshes + CALL Set_MotionMesh(ErrStat2, ErrMsg2 ); if (Failed()) return; + + ! transfer input motion mesh to u(1) meshes + CALL MD_SetInputMotion( u(1), ErrStat2, ErrMsg2 ); if (Failed()) return; + + !------------------------------------------------- + ! Call the main subroutine MD_CalcOutput + !------------------------------------------------- + CALL MD_CalcOutput( t, u(1), p, x(STATE_CURR), xd(STATE_CURR), z(STATE_CURR), other(STATE_CURR), y, m, ErrStat2, ErrMsg2 ); if (Failed()) return; + + !------------------------------------------------- + ! Convert the outputs of MD_calcOutput back to C + !------------------------------------------------- + ! Transfer resulting load meshes to intermediate mesh + CALL MD_TransferLoads( u(1), y, ErrStat2, ErrMsg2 ); if (Failed()) return; + + ! Set output force/moment array + CALL Set_OutputLoadArray( ) + + ! Reshape for return + DO J = 1,6 + FORCES_C(1,J) = REAL(tmpForces(J,1), c_float) + END DO + + OUTPUTS_C = REAL(y%WriteOutput, C_FLOAT) + +CONTAINS + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + if (Failed) then + call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) + endif + end function Failed +END SUBROUTINE MD_C_CalcOutput + +!=============================================================================================================== +!----------------------------------------------- MD END -------------------------------------------------------- +!=============================================================================================================== +!> Cleanup memory +!! NOTE: the error handling here is slightly different than in other routines +SUBROUTINE MD_C_End(ErrStat_C,ErrMsg_C) BIND (C, NAME='MD_C_End') +#ifndef IMPLICIT_DLLEXPORT +!DEC$ ATTRIBUTES DLLEXPORT :: MD_C_End +!GCC$ ATTRIBUTES DLLEXPORT :: MD_C_End +#endif + INTEGER(C_INT) , INTENT( OUT) :: ErrStat_C + CHARACTER(KIND=C_CHAR) , INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) + + ! Local variables + INTEGER(IntKi) :: ErrStat, ErrStat2, i + CHARACTER(ErrMsgLen) :: ErrMsg, ErrMsg2 + character(*), parameter :: RoutineName = 'MD_C_End' + + ! Set up error handling for MD_C_End + ErrStat = ErrID_None + ErrMsg = '' + + ! Call the main subroutine MD_End + CALL MD_End(u(1), p, x(1), xd(1), z(1), other(1), y, m, ErrStat2, ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! NOTE: MoorDyn_End only takes 1 instance of u, not the array. So extra + ! logic is required here (this isn't necessary in the fortran driver + ! or in openfast, but may be when this code is called from C, Python, + ! or some other code using the c-bindings) + IF (allocated(u)) THEN + DO i=2,size(u) + CALL MD_DestroyInput( u(i), ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + END DO + IF (allocated(u)) deallocate(u) + END IF + + ! Destroy any other copies of states (rerun on (STATE_CURR) is ok) + call MD_DestroyContState( x( STATE_LAST), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MD_DestroyContState( x( STATE_CURR), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MD_DestroyContState( x( STATE_PRED), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MD_DestroyDiscState( xd( STATE_LAST), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MD_DestroyDiscState( xd( STATE_CURR), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MD_DestroyDiscState( xd( STATE_PRED), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MD_DestroyConstrState( z( STATE_LAST), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MD_DestroyConstrState( z( STATE_CURR), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MD_DestroyConstrState( z( STATE_PRED), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MD_DestroyOtherState( other(STATE_LAST), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MD_DestroyOtherState( other(STATE_CURR), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MD_DestroyOtherState( other(STATE_PRED), ErrStat2, ErrMsg2 ); call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! if deallocate other items now + if (allocated(InputTimes)) deallocate(InputTimes) + + ! Clear out mesh related data storage + call ClearMesh() + + call SetErr(ErrStat,ErrMsg,ErrStat_C,ErrMsg_C) +CONTAINS + !> Don't leave junk in memory. So destroy meshes and mappings. + subroutine ClearMesh() + call MeshDestroy( MD_MotionMesh, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MeshDestroy( MD_LoadMesh, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! Destroy mesh mappings + call NWTC_Library_Destroymeshmaptype( Map_Motion_2_MD, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call NWTC_Library_Destroymeshmaptype( Map_MD_2_Load, ErrStat2, ErrMsg2 ) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + end subroutine ClearMesh +END SUBROUTINE MD_C_End + +!=============================================================================================================== +!----------------------------------------- ADDITIONAL SUBROUTINES ---------------------------------------------- +!=============================================================================================================== +!! This subroutine sets the interface meshes to map to the input motions to the MD +!! meshes. This subroutine also sets the meshes for the output loads. +SUBROUTINE SetMotionLoadsInterfaceMeshes(ErrStat,ErrMsg) + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< temporary error status + CHARACTER(ErrMsgLen), INTENT( OUT) :: ErrMsg !< temporary error message + REAL(ReKi) :: InitPos(3) + REAL(R8Ki) :: theta(3) + REAL(R8Ki) :: Orient(3,3) + !------------------------------------------------------------- + ! Set the interface meshes for motion inputs and loads output + !------------------------------------------------------------- + ! Motion mesh + ! This point mesh may contain more than one point. Mapping will be used to map + ! this to the input mesh. + CALL MeshCreate( MD_MotionMesh , & + IOS = COMPONENT_INPUT , & + Nnodes = 1 , & + ErrStat = ErrStat , & + ErrMess = ErrMsg , & + TranslationDisp = .TRUE., Orientation = .TRUE., & + TranslationVel = .TRUE., RotationVel = .TRUE., & + TranslationAcc = .TRUE., RotationAcc = .TRUE. ) + IF (ErrStat >= AbortErrLev) RETURN + + ! initial position and orientation of node + InitPos = tmpPositions(1:3,1) + theta = REAL(tmpPositions(4:6,1),DbKi) ! convert ReKi to DbKi to avoid roundoff + CALL SmllRotTrans( 'InputRotation', theta(1), theta(2), theta(3), Orient, 'Orient', ErrStat, ErrMsg ) + CALL MeshPositionNode( MD_MotionMesh , & + 1 , & + InitPos , & ! position + ErrStat, ErrMsg , & + Orient ) ! orientation + IF (ErrStat >= AbortErrLev) RETURN + + CALL MeshConstructElement ( MD_MotionMesh, ELEMENT_POINT, ErrStat, ErrMsg, 1 ) + IF (ErrStat >= AbortErrLev) RETURN + + CALL MeshCommit ( MD_MotionMesh, ErrStat, ErrMsg ) + IF (ErrStat >= AbortErrLev) RETURN + + MD_MotionMesh%RemapFlag = .TRUE. + + ! For checking the mesh, uncomment this. + ! note: CU is is output unit (platform dependent). + !call MeshPrintInfo( CU, MD_MotionMesh ) + + !------------------------------------------------------------- + ! Loads mesh + ! This point mesh may contain more than one point. Mapping will be used to map + ! the loads from output mesh + CALL MeshCopy( SrcMesh = MD_MotionMesh ,& + DestMesh = MD_LoadMesh ,& + CtrlCode = MESH_SIBLING ,& + IOS = COMPONENT_OUTPUT ,& + ErrStat = ErrStat ,& + ErrMess = ErrMsg ,& + Force = .TRUE. ,& + Moment = .TRUE. ) + IF (ErrStat >= AbortErrLev) RETURN + + MD_LoadMesh%RemapFlag = .TRUE. + + ! For checking the mesh, uncomment this. + ! note: CU is is output unit (platform dependent). + !call MeshPrintInfo( CU, MD_LoadMesh ) + + !------------------------------------------------------------- + ! Set the mapping meshes + IF ( allocated(u(1)%CoupledKinematics) ) THEN ! input motions + CALL MeshMapCreate( MD_MotionMesh, u(1)%CoupledKinematics(1), Map_Motion_2_MD, ErrStat, ErrMsg ) + IF (ErrStat >= AbortErrLev) RETURN + END IF + IF ( allocated(y%CoupledLoads) ) THEN ! output loads + CALL MeshMapCreate( y%CoupledLoads(1), MD_LoadMesh, Map_MD_2_Load, ErrStat, ErrMsg ) + IF (ErrStat >= AbortErrLev) RETURN + END IF +END SUBROUTINE SetMotionLoadsInterfaceMeshes + +!--------------------------------------------------------------------------------------------------------------- +!> This routine is operating on module level data, hence few inputs +SUBROUTINE Set_MotionMesh(ErrStat, ErrMsg) + REAL(R8Ki) :: theta(3) + REAL(R8Ki) :: Orient(3,3) + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(ErrMsgLen), INTENT( OUT) :: ErrMsg + ! Set mesh corresponding to input motions + theta = REAL(tmpPositions(4:6,1),DbKi) ! convert ReKi to DbKi to avoid roundoff + CALL SmllRotTrans( 'InputRotation', theta(1), theta(2), theta(3), Orient, 'Orient', ErrStat, ErrMsg ) + MD_MotionMesh%TranslationDisp(1:3,1) = tmpPositions(1:3,1) - MD_MotionMesh%Position(1:3,1) ! relative displacement only + MD_MotionMesh%Orientation(1:3,1:3,1) = Orient + MD_MotionMesh%TranslationVel( 1:3,1) = tmpVelocities(1:3,1) + MD_MotionMesh%RotationVel( 1:3,1) = tmpVelocities(4:6,1) + MD_MotionMesh%TranslationAcc( 1:3,1) = tmpAccelerations(1:3,1) + MD_MotionMesh%RotationAcc( 1:3,1) = tmpAccelerations(4:6,1) +END SUBROUTINE Set_MotionMesh + +!--------------------------------------------------------------------------------------------------------------- +!> Map the motion of the intermediate input mesh over to the input meshes +!! This routine is operating on module level data, hence few inputs +SUBROUTINE MD_SetInputMotion( u_local, ErrStat, ErrMsg ) + TYPE(MD_InputType), INTENT(INOUT) :: u_local + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(ErrMsgLen), INTENT( OUT) :: ErrMsg + + ErrStat = ErrID_None + ErrMsg = '' + + IF ( allocated(u_local%CoupledKinematics) ) THEN + CALL Transfer_Point_to_Point( MD_MotionMesh, u_local%CoupledKinematics(1), Map_Motion_2_MD, ErrStat, ErrMsg ) + END IF +END SUBROUTINE MD_SetInputMotion + +!--------------------------------------------------------------------------------------------------------------- +!> Map the loads of the output meshes to the intermediate output mesh. Since +!! we are mapping two meshes over to a single one, we use an intermediate +!! temporary mesh -- This step is not currently necessary in MD since only one set +!! of load points is used with MD. +SUBROUTINE MD_TransferLoads( u_local, y_local, ErrStat, ErrMsg ) + TYPE(MD_InputType), INTENT(IN ) :: u_local ! Only one input (probably at T) + TYPE(MD_OutputType), INTENT(IN ) :: y_local ! Only one input (probably at T) + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(ErrMsgLen), INTENT( OUT) :: ErrMsg + + ErrStat = ErrID_None + ErrMsg = '' + MD_LoadMesh%Force = 0.0_ReKi + MD_LoadMesh%Moment = 0.0_ReKi + + ! mesh + IF ( allocated(y_local%CoupledLoads) ) THEN + CALL Transfer_Point_to_Point( y_local%CoupledLoads(1), MD_LoadMesh, Map_MD_2_Load, ErrStat, ErrMsg, u_local%CoupledKinematics(1), MD_MotionMesh ) + IF (ErrStat >= AbortErrLev) RETURN + END IF +END SUBROUTINE MD_TransferLoads + +!--------------------------------------------------------------------------------------------------------------- +!> Transfer the loads from the load mesh to the temporary array for output +!! This routine is operating on module level data, hence few inputs +SUBROUTINE Set_OutputLoadArray() + ! Set mesh corresponding to input motions + tmpForces(1:3,1) = MD_LoadMesh%Force (1:3,1) + tmpForces(4:6,1) = MD_LoadMesh%Moment(1:3,1) +END SUBROUTINE Set_OutputLoadArray + +END MODULE diff --git a/modules/moordyn/src/MoorDyn_Driver.f90 b/modules/moordyn/src/MoorDyn_Driver.f90 index 0b501336e..9b370d8eb 100644 --- a/modules/moordyn/src/MoorDyn_Driver.f90 +++ b/modules/moordyn/src/MoorDyn_Driver.f90 @@ -1,7 +1,7 @@ !********************************************************************************************************************************** ! LICENSING -! Copyright (C) 2020 National Renewable Energy Laboratory -! Copyright (C) 2020 Matthew Hall +! Copyright (C) 2020-2021 Alliance for Sustainable Energy, LLC +! Copyright (C) 2015-2019 Matthew Hall ! ! This file is part of MoorDyn. ! @@ -27,27 +27,65 @@ PROGRAM MoorDyn_Driver IMPLICIT NONE + TYPE MD_Drvr_InitInput + LOGICAL :: Echo + REAL(DbKi) :: Gravity + REAL(DbKi) :: rhoW + REAL(DbKi) :: WtrDepth + + CHARACTER(1024) :: MDInputFile + CHARACTER(1024) :: OutRootName + REAL(DbKi) :: TMax + REAL(DbKi) :: dtC + + INTEGER :: FarmSize + REAL(DbKi) :: FarmPositions(8,40) + + INTEGER :: InputsMod + CHARACTER(1024) :: InputsFile + INTEGER :: nTurb + END TYPE MD_Drvr_InitInput + + INTEGER(IntKi) :: ErrStat ! Status of error message CHARACTER(1024) :: ErrMsg ! Error message if ErrStat /= ErrID_None - TYPE (MD_InitInputType) :: MD_InitInput - TYPE (MD_ParameterType) :: MD_Parameter - TYPE (MD_ContinuousStateType) :: MD_ContinuousState - TYPE (MD_InitOutputType) :: MD_InitOutput - TYPE (MD_DiscreteStateType) :: MD_DiscreteState - TYPE (MD_ConstraintStateType) :: MD_ConstraintState - TYPE (MD_OtherStateType) :: MD_OtherState - TYPE (MD_MiscVarType) :: MD_MiscVar + INTEGER(IntKi) :: ErrStat2 ! Status of error message + CHARACTER(1024) :: ErrMsg2 ! Error message if ErrStat /= ErrID_None - TYPE (MD_InputType), ALLOCATABLE :: MD_Input(:) - REAL(DbKi), DIMENSION(:), ALLOCATABLE :: MD_InputTimes + 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(MD_Drvr_InitInput) :: drvrInitInp ! Initialization data for the driver program + INTEGER :: UnIn ! Unit number for the input file + INTEGER :: UnEcho ! The local unit number for this module's echo file + + + TYPE (MD_InitInputType) :: MD_InitInp + TYPE (MD_ParameterType) :: MD_p + TYPE (MD_ContinuousStateType) :: MD_x ! continuous states + TYPE (MD_InitOutputType) :: MD_InitOut + TYPE (MD_DiscreteStateType) :: MD_xd ! discrete states + TYPE (MD_ConstraintStateType) :: MD_xc ! constraint states + TYPE (MD_OtherStateType) :: MD_xo ! other states + TYPE (MD_MiscVarType) :: MD_m + + TYPE (MD_InputType), ALLOCATABLE :: MD_u(:) + REAL(DbKi), DIMENSION(:), ALLOCATABLE :: MD_uTimes - TYPE (MD_OutputType) :: MD_Output ! Output file identifier + TYPE (MD_OutputType) :: MD_y ! Output file identifier + + ! Motion file parsing + type(FileInfoType) :: FileInfo_PrescribeMtn !< The derived type for holding the prescribed forces input file for parsing -- we may pass this in the future + integer(IntKi) :: CurLine !< current entry in FileInfo_In%Lines array + real(ReKi), ALLOCATABLE :: TmpRe(:) !< temporary number array for reading values in - INTEGER(IntKi) :: UnPtfmMotIn ! platform motion input file identifier CHARACTER(100) :: Line ! String to temporarially hold value of read line REAL(ReKi), ALLOCATABLE :: PtfmMotIn(:,:) ! Variable for storing time, and DOF time series from driver input file - REAL(ReKi), ALLOCATABLE :: PtfmMot(:,:) ! Variable for storing interpolated DOF time series from driver input file + REAL(ReKi), ALLOCATABLE :: r_in(:,:) ! Variable for storing interpolated DOF time series from driver input file + REAL(ReKi), ALLOCATABLE :: r_in2(:,:) ! used for filtering + REAL(ReKi), ALLOCATABLE :: rd_in(:,:) ! Variable for storing 1st derivative of interpolate DOF time series + REAL(ReKi), ALLOCATABLE :: rd_in2(:,:) ! used for filtering + REAL(ReKi), ALLOCATABLE :: rdd_in(:,:) ! Variable for storing 2nd derivative of interpolate DOF time series + REAL(ReKi), ALLOCATABLE :: rdd_in2(:,:) ! used for filtering INTEGER(IntKi) :: ntIn ! number of time steps read from driver input file INTEGER(IntKi) :: ncIn ! number of channels read from driver input file INTEGER(IntKi) :: nt ! number of coupling time steps to use in simulation @@ -60,244 +98,463 @@ PROGRAM MoorDyn_Driver INTEGER(IntKi) :: MD_interp_order ! order of interpolation/extrapolation ! Local variables - Integer(IntKi) :: i ! counter for various loops - Integer(IntKi) :: j ! counter for various loops - Integer(IntKi) :: k ! counter for various loops + Integer(IntKi) :: i,j,k,l ! counter for various loops + Integer(IntKi) :: iTurb + Integer(IntKi) :: nTurbines Integer(IntKi) :: iIn integer(intKi) :: Un - + + ! data for SimStatus/RunTimes: + REAL(DbKi) :: PrevSimTime !< Previous time message was written to screen (s > 0) + REAL(ReKi) :: PrevClockTime !< Previous clock time in seconds past midnight + INTEGER :: SimStrtTime (8) !< An array containing the elements of the start time (after initialization). + INTEGER :: ProgStrtTime (8) !< An array containing the elements of the program start time (before initialization). + REAL(ReKi) :: SimStrtCPU !< User CPU time for simulation (without intialization) + REAL(ReKi) :: ProgStrtCPU !< User CPU time for program (with intialization) + + CHARACTER(20) :: FlagArg ! flag argument from command line - CHARACTER(1024) :: PlatformInitInputFile CHARACTER(200) :: git_commit ! String containing the current git commit hash TYPE(ProgDesc), PARAMETER :: version = ProgDesc( 'MoorDyn Driver', '', '' ) + + + + ErrMsg = "" + ErrStat = ErrID_None + UnEcho=-1 + UnIn =-1 + + ! TODO: Sort out error handling (two sets of flags currently used) CALL NWTC_Init( ProgNameIn=version%Name ) - MD_InitInput%FileName = "MoorDyn.dat" ! initialize to empty string to make sure it's input from the command line - CALL CheckArgs( MD_InitInput%FileName, Arg2=PlatformInitInputFile, Flag=FlagArg ) + MD_InitInp%FileName = "MoorDyn.dat" ! initialize to empty string to make sure it's input from the command line + CALL CheckArgs( MD_InitInp%FileName, Arg2=drvrInitInp%InputsFile, Flag=FlagArg ) IF ( LEN( TRIM(FlagArg) ) > 0 ) CALL NormStop() ! Display the copyright notice - CALL DispCopyrightLicense( version%Name, 'Copyright (C) 2020 Matthew Hall' ) + CALL DispCopyrightLicense( version%Name, 'Copyright (C) 2021 NREL, 2019 Matt Hall' ) ! Obtain OpenFAST git commit hash git_commit = QueryGitVersion() ! 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 ) - ! ------------------------------------------------------------------------- - ! Initialize MoorDyn - ! ------------------------------------------------------------------------- + + + CALL DATE_AND_TIME ( Values=ProgStrtTime ) ! Let's time the whole simulation + CALL CPU_TIME ( ProgStrtCPU ) ! Initial time (this zeros the start time when used as a MATLAB function) + + + CALL WrScr( ' MD Driver updated 2022-01-12') + + ! Parse the driver input file and run the simulation based on that file + CALL get_command_argument(1, drvrFilename) + CALL ReadDriverInputFile( drvrFilename, drvrInitInp); + + ! do any initializing and allocating needed in prep for calling MD_Init + + ! set the input file name and other environment terms + !MD_InitInp%NStepWave = 1 ! an arbitrary number > 0 (to set the size of the wave data, which currently contains all zero values) + MD_InitInp%Tmax = drvrInitInp%TMax + MD_InitInp%g = drvrInitInp%Gravity + MD_InitInp%rhoW = drvrInitInp%rhoW + MD_InitInp%WtrDepth = drvrInitInp%WtrDepth + MD_InitInp%FileName = drvrInitInp%MDInputFile + MD_InitInp%RootName = drvrInitInp%OutRootName + MD_InitInp%UsePrimaryInputFile = .TRUE. + !MD_InitInp%PassedPrimaryInputData = + MD_InitInp%Echo = drvrInitInp%Echo + !MD_InitInp%OutList = <<<< never used? + MD_InitInp%Linearize = .FALSE. + + TMax = drvrInitInp%TMax + dtC = drvrInitInp%dtC ! desired coupling time step size for communicating with MoorDyn - dtC = 0.01 ! desired coupling time step size for communicating with MoorDyn + ! do OpenFAST vs FAST.Farm related setup + + MD_InitInp%FarmSize = drvrInitInp%FarmSize + + if (drvrInitInp%FarmSize > 0) then ! Check if this MoorDyn instance is being run from FAST.Farm (indicated by FarmSize > 0) + nTurbines = drvrInitInp%FarmSize + else ! FarmSize==0 indicates normal, FAST module mode + nTurbines = 1 ! if a regular FAST module mode, we treat it like a nTurbine=1 farm case + end if + + CALL AllocAry(MD_InitInp%PtfmInit, 6, nTurbines, 'PtfmInit array' , ErrStat2, ErrMsg2); call AbortIfFailed() + CALL AllocAry(MD_InitInp%TurbineRefPos, 3, nTurbines, 'TurbineRefPos array', ErrStat2, ErrMsg2); call AbortIfFailed() - MD_interp_order = 0 + do J=1,nTurbines + MD_InitInp%TurbineRefPos(1,J) = drvrInitInp%FarmPositions(1,J) + MD_InitInp%TurbineRefPos(2,J) = drvrInitInp%FarmPositions(2,J) + MD_InitInp%TurbineRefPos(3,J) = 0.0_DbKi + MD_InitInp%PtfmInit(1,J) = drvrInitInp%FarmPositions(3,J) + MD_InitInp%PtfmInit(2,J) = drvrInitInp%FarmPositions(4,J) + MD_InitInp%PtfmInit(3,J) = drvrInitInp%FarmPositions(5,J) + MD_InitInp%PtfmInit(4,J) = drvrInitInp%FarmPositions(6,J)*D2R !3.14159265/180.0 + MD_InitInp%PtfmInit(5,J) = drvrInitInp%FarmPositions(7,J)*D2R !3.14159265/180.0 + MD_InitInp%PtfmInit(6,J) = drvrInitInp%FarmPositions(8,J)*D2R !3.14159265/180.0 + end do + + MD_interp_order = 1 - ! MAP: allocate Input and Output arrays; used for interpolation and extrapolation - Allocate(MD_InputTimes(MD_interp_order + 1)) + ! allocate Input and Output arrays; used for interpolation and extrapolation + Allocate(MD_uTimes(MD_interp_order + 1)) ! @bonnie : This is in the FAST developers glue code example, but it's probably not needed here. - Allocate(MD_Input(MD_interp_order + 1)) + Allocate(MD_u(MD_interp_order + 1)) - ! set the input file name and other environment terms. - !MD_InitInput%NStepWave = 1 ! an arbitrary number > 0 (to set the size of the wave data, which currently contains all zero values) - MD_InitInput%g = 9.81 ! This need to be according to g used in ElastoDyn - MD_InitInput%rhoW = 1025 ! This needs to be set according to seawater density in HydroDyn - MD_InitInput%PtfmInit = 0.0 - MD_InitInput%RootName = "MoorDyn.MD" - - CALL GetNewUnit( Un ) - OPEN(Unit=Un,FILE='MD.out',STATUS='UNKNOWN') + + if (drvrInitInp%InputsMod > 1) then + ErrStat2 = ErrID_Fatal + ErrMsg2 = ' ERROR: MoorDyn Driver InputsMod must be 0 or 1.' + CALL AbortIfFailed() + end if + + + ! -------------------------------- ----------------------------------- + + ! fill in the hydrodynamics data + ALLOCATE( MD_InitInp%WaveVel (2,200,3)) + ALLOCATE( MD_InitInp%WaveAcc (2,200,3)) + ALLOCATE( MD_InitInp%WavePDyn(2,200) ) + ALLOCATE( MD_InitInp%WaveElev(2,200) ) + ALLOCATE( MD_InitInp%WaveTime(2) ) + MD_InitInp%WaveVel = 0.0_ReKi + MD_InitInp%WaveAcc = 0.0_ReKi + MD_InitInp%WavePDyn = 0.0_ReKi + MD_InitInp%WaveElev = 0.0_ReKi + MD_InitInp%WaveTime = 0.0_ReKi + DO I = 1,SIZE(MD_InitInp%WaveTime) + MD_InitInp%WaveTime(I) = 600.0*I + END DO + + ! open driver output file >>> not yet used <<< + !CALL GetNewUnit( Un ) + !OPEN(Unit=Un,FILE='MD.out',STATUS='UNKNOWN') ! call the initialization routine - CALL MD_Init( MD_InitInput , & - MD_Input(1) , & - MD_Parameter , & - MD_ContinuousState , & - MD_DiscreteState , & - MD_ConstraintState , & - MD_OtherState , & - MD_Output , & - MD_MiscVar , & - dtC , & - MD_InitOutput , & - ErrStat , & - ErrMsg ) - IF ( ErrStat .NE. ErrID_None ) THEN - IF (ErrStat >=AbortErrLev) CALL ProgAbort(ErrMsg) - CALL WrScr( ErrMsg ) - END IF + CALL MD_Init( MD_InitInp, MD_u(1), MD_p, MD_x , MD_xd, MD_xc, MD_xo, MD_y, MD_m, dtC, MD_InitOut, ErrStat, ErrMsg2 ); call AbortIfFailed() - CALL MD_DestroyInitInput ( MD_InitInput , ErrStat, ErrMsg ) - CALL MD_DestroyInitOutput ( MD_InitOutput , ErrStat, ErrMsg ) + CALL MD_DestroyInitInput ( MD_InitInp , ErrStat, ErrMsg ); call AbortIfFailed() + CALL MD_DestroyInitOutput ( MD_InitOut , ErrStat, ErrMsg ); call AbortIfFailed() - CALL DispNVD( MD_InitOutput%Ver ) + CALL DispNVD( MD_InitOut%Ver ) - ncIn = 6 + size(MD_Input(1)%DeltaL) ! determine number of input channels expected from driver input file time series (DOFs including active tensioning channels) + ! determine number of input channels expected from driver input file time series (DOFs including active tensioning channels) + if (allocated(MD_u(1)%DeltaL)) then + ncIn = size(MD_u(1)%DeltaL) ! if unallocated, size will return garbage for some compilers + else + ncIn = 0 + endif - ! ------------------------------------------------------------------------- - ! Read in prescribed motions from text file if available - ! (single 6DOF platform for now, plus one active tensioning command) - ! (to be updated for versatile coupling in future) - ! ------------------------------------------------------------------------- - IF( LEN( TRIM(PlatformInitInputFile) ) < 1 ) THEN - ntIn = 0 ! flag to indicate no motion input file - print *, "No MoorDyn Driver input file provided, so using zero values." + do iTurb = 1, MD_p%nTurbines + ncIn = ncIn + MD_p%nCpldBodies(iTurb)*6 + MD_p%nCpldRods(iTurb)*6 + MD_p%nCpldCons(iTurb)*3 + end do + + call WrScr('MoorDyn has '//trim(num2lstr(ncIn))//' coupled DOFs and/or active-tensioned inputs.') - ELSE - CALL GetNewUnit( UnPtfmMotIn ) - CALL OpenFInpFile ( UnPtfmMotIn, PlatformInitInputFile, ErrStat, ErrMsg ) - IF (ErrStat /= 0 ) THEN - print *, ErrStat, ErrMsg - STOP - ENDIF - print *, "Reading platform motion input data from ", PlatformInitInputFile - - ! Read through length of file to find its length - i = 1 ! start counter - DO - READ(UnPtfmMotIn,'(A)',IOSTAT=ErrStat) Line !read into a line - - - IF (ErrStat /= 0) EXIT - - print *, TRIM(Line) - - i = i+1 - END DO + if (drvrInitInp%InputsMod == 1 ) then - ! rewind to start of input file to re-read things now that we know how long it is - REWIND(UnPtfmMotIn) - - ntIn = i-1 ! save number of lines of file - - - ! allocate space for input motion array (including time column) - ALLOCATE ( PtfmMotIn(ntIn, ncIn+1), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for PtfmMotIn array.' - CALL WrScr( ErrMsg ) - END IF - - ! read the data in from the file - DO i = 1, ntIn - READ (UnPtfmMotIn,*,IOSTAT=ErrStat) (PtfmMotIn (i,J), J=1,ncIn+1) - - IF ( ErrStat /= 0 ) THEN - ErrMsg = ' Error reading the input time-series file. Expecting '//TRIM(Int2LStr(ncIn))//' channels plus time.' - CALL WrScr( ErrMsg ) - END IF - END DO - - ! Close the inputs file - CLOSE ( UnPtfmMotIn ) + if ( LEN( TRIM(drvrInitInp%InputsFile) ) < 1 ) then + ErrStat = ErrID_Fatal + ErrMsg = ' ERROR: MoorDyn Driver InputFile cannot be empty if InputsMode is 1.' + CALL AbortIfFailed() + end if + + call WrScr('Reading platform motion input data from '//trim(drvrInitInp%InputsFile)) + call WrScr(' MD driver is expecting '//trim(num2lstr(ncIn))//' columns of input data, plus time, in motion input file.') + + ! Parse the motion file and store in the FileInfoType structure. This will strip out the header + ! and leave just the table. PrescribeMtn%NumLines is the number of timesteps. + call ProcessComFile( drvrInitInp%InputsFile, FileInfo_PrescribeMtn, ErrStat2, ErrMsg2 ) + call AbortIfFailed() + + ! number of lines in table (number of timesteps) + ntIn = FileInfo_PrescribeMtn%NumLines + + ! Allocate the array (include time column) + call AllocAry( PtfmMotIn, ntIn, ncIn+1, "Array of motion data", ErrStat2, ErrMsg2 ); call AbortIfFailed() + call AllocAry( TmpRe, ncIn+1, "TempRe", ErrStat2, ErrMsg2 ); call AbortIfFailed() + + ! Loop over all table lines. Expecting ncIn+1 colunns + CurLine=1 + do i=1,ntIn + call ParseAry ( FileInfo_PrescribeMtn, CurLine, 'motions', TmpRe, ncIn+1, ErrStat2, ErrMsg2, UnEcho ) + ErrMsg2='Error reading the input time-series file. Expecting '//TRIM(Int2LStr(ncIn))//' channels plus time.'//NewLine//trim(ErrMsg2) + call AbortIfFailed() + PtfmMotIn(i,1:ncIn+1) = TmpRe + enddo + + deallocate(TmpRe) + + call WrScr("Read "//trim(Num2LStr(ntIn))//" time steps from input file.") + !print *, PtfmMotIn + + ! trim simulation duration to length of input file if needed + if (PtfmMotIn(ntIn, 1) < TMax) then + TMax = PtfmMotIn(ntIn, 1) + end if - print *, "Read ", ntIn, " time steps from input file." - print *, PtfmMotIn - - END IF - ! ----------------------- specify stepping details ----------------------- + ! specify stepping details + nt = tMax/dtC - 1 ! number of coupling time steps - IF (ntIn > 0) THEN - tMax = PtfmMotIn(ntIn, 1) ! save last time step as total sim time - ELSE - tMax = 60 - END IF - + + ! allocate space for processed motion array + ALLOCATE ( r_in(nt, ncIn), r_in2(nt, ncIn), rd_in(nt, ncIn), rd_in2(nt, ncIn), rdd_in(nt, ncIn), rdd_in2(nt, ncIn), STAT=ErrStat2) + IF ( ErrStat2 /= ErrID_None ) THEN + ErrStat2 = ErrID_Fatal + ErrMsg = ' Error allocating space for r_in or rd_in array.' + call AbortIfFailed() + END IF - nt = tMax/dtC - 1 ! number of coupling time steps - CALL WrScr(" ") - print *, "Tmax - ", tMax, " and nt=", nt - CALL WrScr(" ") + ! go through and interpolate inputs to new regular time steps (if nt=0 this array should be left as zeros) - ! allocate space for processed motion array - ALLOCATE ( PtfmMot(nt, ncIn), STAT = ErrStat ) - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Error allocating space for PtfmMot array.' - CALL WrScr( ErrMsg ) - END IF - - - ! go through and interpolate inputs to new regular time steps (if nt=0 this array should be left as zeros) - IF (ntIn > 0) THEN - DO i = 1,nt - + DO i = 1,nt t = dtC*(i-1) - ! interpolation routine + ! interpolation routine DO iIn = 1,ntIn-1 - IF (PtfmMotIn(iIn+1, 1) > t) THEN - frac = (t - PtfmMotIn(iIn, 1) )/( PtfmMotIn(iIn+1, 1) - PtfmMotIn(iIn, 1) ) - - ! print *, "t=", t, ", iIn=", iIn, ", frac=", frac - + IF (PtfmMotIn(iIn+1, 1) > t) THEN ! find the right two points to interpolate between (remember that the first column of PtfmMotIn is time) + frac = (t - PtfmMotIn(iIn, 1) )/( PtfmMotIn(iIn+1, 1) - PtfmMotIn(iIn, 1) ) ! interpolation fraction (0-1) between two interpolation points + DO J=1,ncIn - PtfmMot(i, J) = PtfmMotIn(iIn, J+1) + frac*(PtfmMotIn(iIn+1, J+1) - PtfmMotIn(iIn, J+1)) + ! get interpolated position of coupling point + r_in(i, J) = PtfmMotIn(iIn, J+1) + frac*(PtfmMotIn(iIn+1, J+1) - PtfmMotIn(iIn, J+1)) + + if (iIn==1) then + ! use forward different to estimate velocity of coupling point + rd_in(i, J) = (PtfmMotIn(iIn+1, J+1) - PtfmMotIn(iIn, J+1)) / (PtfmMotIn(iIn+1, 1) - PtfmMotIn(iIn, 1)) + else + ! use central different to estimate velocity of coupling point + rd_in(i, J) = (PtfmMotIn(iIn+1, J+1) - PtfmMotIn(iIn-1, J+1)) / (PtfmMotIn(iIn+1, 1) - PtfmMotIn(iIn-1, 1)) + + end if END DO - EXIT + EXIT ! break out of the loop for this time step once we've done its interpolation END IF END DO - ! print *, t, "s", PtfmMot(i,:) + END DO + ! ----- filter position ----- + ! now filter forward + DO i = 1,nt + DO J=1,ncIn + if (i==1) then + r_in2(i, J) = r_in(i, J) + else + r_in2(i, J) = 0.1*r_in(i, J) + 0.9*r_in2(i-1, J) + end if + END DO + END DO + ! now filter backward and save back to original variable + DO i = nt,1,-1 + DO J=1,ncIn + if (i==nt) then + r_in(i, J) = r_in2(i, J) + else + r_in(i, J) = 0.1*r_in2(i, J) + 0.9*r_in(i+1, J) + end if + END DO END DO - ELSE - PtfmMot = 0.0_Reki - END IF - + ! now get derivative after filtering has been applied (derivative no longer needs to be calculated earlier) + DO i = 1,nt + DO J=1,ncIn + if (i==1) then + ! use forward different to estimate velocity of coupling point + rd_in(i, J) = (r_in(i+1, J) - r_in(i, J)) / dtC + else if (i==nt) then + ! use forward different to estimate velocity of coupling point + rd_in(i, J) = (r_in(i, J) - r_in(i-1, J)) / dtC + else + ! use central different to estimate velocity of coupling point + rd_in(i, J) = (r_in(i+1, J) - r_in(i-1, J)) / (2.0*dtC) + end if + END DO + END DO + + + + ! ----- filter velocity ----- + ! now filter forward + DO i = 1,nt + DO J=1,ncIn + if (i==1) then + rd_in2(i, J) = rd_in(i, J) + else + rd_in2(i, J) = 0.1*rd_in(i, J) + 0.9*rd_in2(i-1, J) + end if + END DO + END DO + ! now filter backward and save back to original variable + DO i = nt,1,-1 + DO J=1,ncIn + if (i==nt) then + rd_in(i, J) = rd_in2(i, J) + else + rd_in(i, J) = 0.1*rd_in2(i, J) + 0.9*rd_in(i+1, J) + end if + END DO + END DO + + + ! now get derivative after filtering has been applied (derivative no longer needs to be calculated earlier) + DO i = 1,nt + DO J=1,ncIn + if (i==1) then + ! use forward different to estimate velocity of coupling point + rdd_in(i, J) = (rd_in(i+1, J) - rd_in(i, J)) / dtC + else if (i==nt) then + ! use forward different to estimate velocity of coupling point + rdd_in(i, J) = (rd_in(i, J) - rd_in(i-1, J)) / dtC + else + ! use central different to estimate velocity of coupling point + rdd_in(i, J) = (rd_in(i+1, J) - rd_in(i-1, J)) / (2.0*dtC) + end if + END DO + END DO + + + ! ----- filter acceleration ----- + ! now filter forward + DO i = 1,nt + DO J=1,ncIn + if (i==1) then + rdd_in2(i, J) = rdd_in(i, J) + else + rdd_in2(i, J) = 0.2*rdd_in(i, J) + 0.8*rdd_in2(i-1, J) + end if + END DO + END DO + ! now filter backward and save back to original variable + DO i = nt,1,-1 + DO J=1,ncIn + if (i==nt) then + rdd_in(i, J) = rdd_in2(i, J) + else + rdd_in(i, J) = 0.2*rdd_in2(i, J) + 0.8*rdd_in(i+1, J) + end if + END DO + END DO + + + else + nt = tMax/dtC - 1 ! number of coupling time steps + end if + CALL WrScr(" ") + call WrScr("Tmax - "//trim(Num2LStr(tMax))//" and nt="//trim(Num2LStr(nt))) + CALL WrScr(" ") ! --------------------------------------------------------------- ! Set the initial input values ! --------------------------------------------------------------- - - ! start with zeros >>> or should this be the initial row of DOFs? <<< - MD_Input(1)%PtFairleadDisplacement%TranslationDisp = 0.0_ReKi - MD_Input(1)%DeltaL = 0.0_ReKi - MD_Input(1)%DeltaLdot = 0.0_ReKi + ! zero the tension commands + if (allocated(MD_u(1)%DeltaL)) then + MD_u(1)%DeltaL = 0.0_ReKi + MD_u(1)%DeltaLdot = 0.0_ReKi + endif + +! ! zero water inputs (if passing wave info in from glue code) +! MD_u(1)%U = 0.0 +! MD_u(1)%Ud = 0.0 +! MD_u(1)%zeta = 0.0 +! MD_u(1)%PDyn = 0.0 +! ! now add some current in x for testing +! MD_u(1)%U(1,:) = 1.0 + + ! copy inputs to initialize input arrays for higher interp orders if applicable DO i = 2, MD_interp_order + 1 - CALL MD_CopyInput( MD_Input(1), MD_Input(i), MESH_NEWCOPY, ErrStat, ErrMsg ) - END DO - + CALL MD_CopyInput( MD_u(1), MD_u(i), MESH_NEWCOPY, ErrStat2, ErrMsg2 ); call AbortIfFailed() + END DO DO i = 1, MD_interp_order + 1 - MD_InputTimes(i) = -(i - 1) * dtC - ENDDO - + MD_uTimes(i) = -(i - 1) * dtC + END DO + ! get output at initialization (before time stepping) t = 0 + ! First, set correct inputs for initialization (errors occur otherwise) + if (drvrInitInp%InputsMod == 1 ) then + + DO iTurb = 1, MD_p%nTurbines + i = 1 ! read first timestep data + K = 1 ! the index of the coupling points in the input mesh CoupledKinematics + J = 1 ! the starting index of the relevant DOFs in the input array + ! any coupled bodies (type -1) + DO l = 1,MD_p%nCpldBodies(iTurb) + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + MD_u(1)%CoupledKinematics(iTurb)%Orientation( :,:,K) = EulerConstruct( r_in(i, J+3:J+5) ) ! full Euler angle approach + MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) + MD_u(1)%CoupledKinematics(iTurb)%RotationVel( :,K) = rd_in(i, J+3:J+5) + MD_u(1)%CoupledKinematics(iTurb)%TranslationAcc( :,K) = rdd_in(i, J:J+2) + MD_u(1)%CoupledKinematics(iTurb)%RotationAcc( :,K) = rdd_in(i, J+3:J+5) + + K = K + 1 + J = J + 6 + END DO + + ! any coupled rods (type -1 or -2) >>> need to make rotations ignored if it's a pinned rod <<< + DO l = 1,MD_p%nCpldRods(iTurb) + + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + MD_u(1)%CoupledKinematics(iTurb)%Orientation( :,:,K) = EulerConstruct( r_in(i, J+3:J+5) ) + MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) + MD_u(1)%CoupledKinematics(iTurb)%RotationVel( :,K) = rd_in(i, J+3:J+5) + MD_u(1)%CoupledKinematics(iTurb)%TranslationAcc( :,K) = rdd_in(i, J:J+2) + MD_u(1)%CoupledKinematics(iTurb)%RotationAcc( :,K) = rdd_in(i, J+3:J+5) + + K = K + 1 + J = J + 6 + END DO + + ! any coupled points (type -1) + DO l = 1, MD_p%nCpldCons(iTurb) + + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) + MD_u(1)%CoupledKinematics(iTurb)%TranslationAcc( :,K) = 0.0_DbKi !rdd_in(i, J:J+2) + + !print *, u%PtFairleadDisplacement%Position(:,l) + u%PtFairleadDisplacement%TranslationDisp(:,l) + !print *, u%PtFairleadDisplacement%TranslationVel(:,l) + + K = K + 1 + J = J + 3 + END DO + + end do ! iTurb + + ! also provide any active tensioning commands + if (allocated(MD_u(1)%DeltaL)) then + do l = 1, size(MD_u(1)%DeltaL) + MD_u(1)%DeltaL( l) = 0.0_DbKi ! r_in(i, J) + MD_u(1)%DeltaLdot(l) = 0.0_DbKi !rd_in(i, J) + J = J + 1 + end do + endif + + end if ! InputsMod == 1 + CALL MD_CalcOutput( t, MD_u(1), MD_p, MD_x, MD_xd, MD_xc , MD_xo, MD_y, MD_m, ErrStat2, ErrMsg2 ); call AbortIfFailed() - CALL MD_CalcOutput( t , & - MD_Input(1) , & - MD_Parameter , & - MD_ContinuousState , & - MD_DiscreteState , & - MD_ConstraintState , & - MD_OtherState , & - MD_Output , & - MD_MiscVar , & - ErrStat , & - ErrMsg ) - IF ( ErrStat .NE. ErrID_None ) THEN - IF (ErrStat >=AbortErrLev) CALL ProgAbort(ErrMsg) - CALL WrScr( ErrMsg ) - END IF ! ------------------------------------------------------------------------- - ! BEGIN time marching >>> note that 3 rotational platform DOFs are currently neglected <<< + ! BEGIN time marching ! ------------------------------------------------------------------------- - - print *,"Doing time marching now..." + + call WrScr("Doing time marching now...") + + CALL SimStatus_FirstTime( PrevSimTime, PrevClockTime, SimStrtTime, SimStrtCPU, t, tMax ) DO i = 1,nt @@ -305,77 +562,98 @@ PROGRAM MoorDyn_Driver t = dtC*(i-1) - MD_InputTimes(1) = t + dtC - !MD_InputTimes(2) = MD_InputTimes(1) - dtC - !MD_InputTimes(3) = MD_InputTimes(2) - dtC - ! apply platform translations (neglecting rotations for now) - MD_Input(1)%PtFairleadDisplacement%TranslationDisp(1,1) = PtfmMot(i, 1) - MD_Input(1)%PtFairleadDisplacement%TranslationDisp(1,2) = PtfmMot(i, 2) - MD_Input(1)%PtFairleadDisplacement%TranslationDisp(1,3) = PtfmMot(i, 3) - - !MD_Input(2)%PtFairleadDisplacement%TranslationDisp(1,1) = .001*n_t_global - !MD_Input(3)%PtFairleadDisplacement%TranslationDisp(1,1) = .001*n_t_global - - ! what about velocities?? + if ( MOD( i, 20 ) == 0 ) THEN + CALL SimStatus( PrevSimTime, PrevClockTime, t, tMax ) + end if - ! also provide any active tensioning commands (just using delta L, and finite differencing to get derivative) - DO j = 1,ncIn-6 - - MD_Input(1)%DeltaL(j) = PtfmMot(i, 6+j) + ! shift older inputs back in the buffer + CALL MD_CopyInput( MD_u(1), MD_u(2), MESH_NEWCOPY, ErrStat2, ErrMsg2 ); call AbortIfFailed() ! copy from 1 to 2 before 1 is updated with latest. + MD_uTimes(1) = t + dtC + MD_uTimes(2) = MD_uTimes(1) - dtC + !MD_uTimes(3) = MD_uTimes(2) - dtC + + ! update coupled object kinematics iff we're reading input time series + if (drvrInitInp%InputsMod == 1 ) then - IF (i>1) then - MD_Input(1)%DeltaLdot(j) = (PtfmMot(i, 6+j) - PtfmMot(i-1, 6+j))/dtC - ELSE - MD_Input(1)%DeltaLdot(j) = 0.0_ReKi - END IF + DO iTurb = 1, MD_p%nTurbines + + K = 1 ! the index of the coupling points in the input mesh CoupledKinematics + J = 1 ! the starting index of the relevant DOFs in the input array + ! any coupled bodies (type -1) + DO l = 1,MD_p%nCpldBodies(iTurb) + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + MD_u(1)%CoupledKinematics(iTurb)%Orientation( :,:,K) = EulerConstruct( r_in(i, J+3:J+5) ) ! full Euler angle approach + MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) + MD_u(1)%CoupledKinematics(iTurb)%RotationVel( :,K) = rd_in(i, J+3:J+5) + MD_u(1)%CoupledKinematics(iTurb)%TranslationAcc( :,K) = rdd_in(i, J:J+2) + MD_u(1)%CoupledKinematics(iTurb)%RotationAcc( :,K) = rdd_in(i, J+3:J+5) + + K = K + 1 + J = J + 6 + END DO + + ! any coupled rods (type -1 or -2) >>> need to make rotations ignored if it's a pinned rod <<< + DO l = 1,MD_p%nCpldRods(iTurb) + + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + MD_u(1)%CoupledKinematics(iTurb)%Orientation( :,:,K) = EulerConstruct( r_in(i, J+3:J+5) ) + MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) + MD_u(1)%CoupledKinematics(iTurb)%RotationVel( :,K) = rd_in(i, J+3:J+5) + MD_u(1)%CoupledKinematics(iTurb)%TranslationAcc( :,K) = rdd_in(i, J:J+2) + MD_u(1)%CoupledKinematics(iTurb)%RotationAcc( :,K) = rdd_in(i, J+3:J+5) + + K = K + 1 + J = J + 6 + END DO + + ! any coupled points (type -1) + DO l = 1, MD_p%nCpldCons(iTurb) + + MD_u(1)%CoupledKinematics(iTurb)%TranslationDisp(:,K) = r_in(i, J:J+2) - MD_u(1)%CoupledKinematics(iTurb)%Position(:,K) - MD_p%TurbineRefPos(:,iTurb) + MD_u(1)%CoupledKinematics(iTurb)%TranslationVel( :,K) = rd_in(i, J:J+2) + MD_u(1)%CoupledKinematics(iTurb)%TranslationAcc( :,K) = 0.0_DbKi !rdd_in(i, J:J+2) + + !print *, u%PtFairleadDisplacement%Position(:,l) + u%PtFairleadDisplacement%TranslationDisp(:,l) + !print *, u%PtFairleadDisplacement%TranslationVel(:,l) + + K = K + 1 + J = J + 3 + END DO + + end do ! iTurb - END DO + ! also provide any active tensioning commands + if (allocated(MD_u(1)%DeltaL)) then + do l = 1, size(MD_u(1)%DeltaL) + MD_u(1)%DeltaL( l) = 0.0_DbKi ! r_in(i, J) + MD_u(1)%DeltaLdot(l) = 0.0_DbKi !rd_in(i, J) + J = J + 1 + end do + endif + + end if ! InputsMod == 1 + + ! >>> otherwise, mesh kinematics should all still be zero ... maybe worth checking <<< + ! --------------------------------- update states --------------------------------- - CALL MD_UpdateStates( t , & - nt , & - MD_Input , & - MD_InputTimes , & - MD_Parameter , & - MD_ContinuousState , & - MD_DiscreteState , & - MD_ConstraintState , & - MD_OtherState , & - MD_MiscVar , & - ErrStat , & - ErrMsg ) - IF ( ErrStat .NE. ErrID_None ) THEN - IF (ErrStat >=AbortErrLev) CALL ProgAbort(ErrMsg) - CALL WrScr( ErrMsg ) - EXIT - END IF + CALL MD_UpdateStates( t, nt, MD_u, MD_uTimes, MD_p, MD_x, MD_xd, MD_xc, MD_xo, MD_m, ErrStat2, ErrMsg2 ); call AbortIfFailed() + - ! update the global time step by one delta t <<<< ??? why? + ! update the global time step by one delta t <<<< ??? why? ADP: UpdateStates updtes from t -> t+dt. Need to calculate outputs at this final time. t = t + dtC ! --------------------------------- calculate outputs --------------------------------- - CALL MD_CalcOutput( t , & - MD_Input(1) , & - MD_Parameter , & - MD_ContinuousState , & - MD_DiscreteState , & - MD_ConstraintState , & - MD_OtherState , & - MD_Output , & - MD_MiscVar , & - ErrStat , & - ErrMsg ) - IF ( ErrStat .NE. ErrID_None ) THEN - IF (ErrStat >=AbortErrLev) CALL ProgAbort(ErrMsg) - CALL WrScr( ErrMsg ) - END IF - - - WRITE(Un,100) t, MD_Input(1)%PtFairleadDisplacement%TranslationDisp(1,1), & - ((MD_Output%PtFairleadLoad%Force(k,j), k=1,3),j=1,3) + CALL MD_CalcOutput( t, MD_u(1), MD_p, MD_x, MD_xd, MD_xc, MD_xo, MD_y, MD_m, ErrStat2, ErrMsg2 ); call AbortIfFailed() + + + ! >>> should make output vector to hold and print outputs <<< + !WRITE(Un, *) t, MD_u(1)%CoupledKinematics(1)%TranslationDisp(1,1), ((MD_y%CoupledLoads(1)%Force(k,j), k=1,3),j=1,3) !WRITE(*,*) t_global + ! FORMAT(2(1X,F8.3),9(1X,E12.5)) + END DO @@ -383,35 +661,139 @@ PROGRAM MoorDyn_Driver ! END time marching ! ------------------------------------------------------------------------- + CALL RunTimes( ProgStrtTime, ProgStrtCPU, SimStrtTime, SimStrtCPU, t ) + ! Destroy all objects - CALL MD_End( MD_Input(1) , & - MD_Parameter , & - MD_ContinuousState , & - MD_DiscreteState , & - MD_ConstraintState , & - MD_OtherState , & - MD_Output , & - MD_MiscVar , & - ErrStat , & - ErrMsg ) - IF ( ErrStat .NE. ErrID_None ) THEN - IF (ErrStat >=AbortErrLev) CALL ProgAbort(ErrMsg) - CALL WrScr( ErrMsg ) - END IF + CALL MD_End( MD_u(1), MD_p, MD_x, MD_xd, MD_xc , MD_xo, MD_y, MD_m, ErrStat2, ErrMsg2 ); call AbortIfFailed() do j = 2,MD_interp_order+1 - call MD_DestroyInput( MD_Input(j), ErrStat, ErrMsg) + call MD_DestroyInput( MD_u(j), ErrStat, ErrMsg) end do - DEALLOCATE(MD_Input) - DEALLOCATE(MD_InputTimes) + DEALLOCATE(MD_u) + DEALLOCATE(MD_uTimes) - IF (ALLOCATED(PtfmMot) ) DEALLOCATE(PtfmMot ) + IF (ALLOCATED(r_in) ) DEALLOCATE(r_in ) IF (ALLOCATED(PtfmMotIn)) DEALLOCATE(PtfmMotIn) CALL WrScr( "Program has ended" ) close (un) -100 FORMAT(2(1X,F8.3),9(1X,E12.5)) - - END PROGRAM \ No newline at end of file + +CONTAINS + + SUBROUTINE AbortIfFailed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'MoorDyn_Driver') + IF ( ErrStat /= ErrID_None ) THEN + CALL WrScr( "Local error: "//ErrMsg2 ) + CALL WrScr( "Full error messages: "//ErrMsg ) + END IF + if (ErrStat >= AbortErrLev) then + call CleanUp() + STOP + endif + END SUBROUTINE AbortIfFailed + + LOGICAL FUNCTION Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'OutSummary') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp() + END FUNCTION Failed + + SUBROUTINE CleanUp() + if(UnEcho>0) CLOSE(UnEcho) + if(UnEcho>0) CLOSE( UnIn) + if(allocated(MD_u)) deallocate(MD_u) + END SUBROUTINE CleanUp + + !------------------------------------------------------------------------------------------------------------------------------- + SUBROUTINE ReadDriverInputFile( inputFile, InitInp) + CHARACTER(*), INTENT( IN ) :: inputFile + TYPE(MD_Drvr_InitInput), INTENT( OUT ) :: InitInp + ! Local variables + INTEGER :: I ! generic integer for counting + INTEGER :: J ! generic integer for counting + CHARACTER( 2) :: strI ! string version of the loop counter + + CHARACTER(1024) :: EchoFile ! Name of MoorDyn 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 MoorDyn input file + CHARACTER(1024) :: FilePath ! Path Name of MoorDyn input file + + UnEcho=-1 + UnIn =-1 + + FileName = TRIM(inputFile) + + CALL GetNewUnit( UnIn ) + CALL OpenFInpFile( UnIn, FileName, ErrStat2, ErrMsg2); + call AbortIfFailed() + + CALL WrScr( 'Opening MoorDyn Driver input file: '//FileName ) + + ! Read until "echo" + CALL ReadCom( UnIn, FileName, 'MoorDyn Driver input file header line 1', ErrStat2, ErrMsg2); call AbortIfFailed() + CALL ReadCom( UnIn, FileName, 'MoorDyn Driver input file header line 2', ErrStat2, ErrMsg2); call AbortIfFailed() + CALL ReadVar ( UnIn, FileName, InitInp%Echo, 'Echo', 'Echo Input', ErrStat2, ErrMsg2); call AbortIfFailed() + ! If we echo, we rewind + IF ( InitInp%Echo ) THEN + EchoFile = TRIM(FileName)//'.echo' + CALL GetNewUnit( UnEcho ) + CALL OpenEcho ( UnEcho, EchoFile, ErrStat, ErrMsg ); call AbortIfFailed() + REWIND(UnIn) + CALL ReadCom( UnIn, FileName, 'MoorDyn Driver input file header line 1', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadCom( UnIn, FileName, 'MoorDyn Driver input file header line 2', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar ( UnIn, FileName, InitInp%Echo, 'Echo', 'Echo the input file data', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + END IF + !---------------------- ENVIRONMENTAL CONDITIONS ------------------------------------------------- + CALL ReadCom( UnIn, FileName, 'Environmental conditions header', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%Gravity, 'Gravity', 'Gravity', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%rhoW , 'rhoW', 'water density', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%WtrDepth, 'WtrDepth', 'water depth', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + !---------------------- MoorDyn ------------------------------------------------------------------- + CALL ReadCom( UnIn, FileName, 'MoorDyn header', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%MDInputFile, 'MDInputFile', 'MoorDyn input filename', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%OutRootName, 'OutRootName', 'MoorDyn output root filename', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%TMax , 'Tmax', 'Simulation time duration', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%dtC , 'dtC', 'Time step size for calling MoorDyn', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%InputsMod , 'InputsMode', 'Mode for the inputs - zero/steady/time-series', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%InputsFile , 'InputsFile', 'Filename for the MoorDyn inputs', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadVar( UnIn, FileName, InitInp%FarmSize , 'NumTurbines', 'number of turbines in FAST.Farm', ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + CALL ReadCom( UnIn, FileName, 'Initial positions header', ErrStat2, ErrMsg2); call AbortIfFailed() + CALL ReadCom( UnIn, FileName, 'Initial positions table header line 1', ErrStat2, ErrMsg2); call AbortIfFailed() + CALL ReadCom( UnIn, FileName, 'Initial positions table header line 2', ErrStat2, ErrMsg2); call AbortIfFailed() + do J=1,MAX(1,InitInp%FarmSize) + CALL ReadAry( UnIn, FileName, InitInp%FarmPositions(:,J), 8, "FarmPositions", "FAST.Farm position inputs", ErrStat2, ErrMsg2, UnEcho); call AbortIfFailed() + end do + + ! done reading + if(UnEcho>0) CLOSE( UnEcho ) + if(UnIn>0) CLOSE( UnIn ) + + ! Perform input checks and triggers + !CALL GetPath( FileName, FilePath ) + !IF ( PathIsRelative( InitInp%MDInputFile ) ) then + ! InitInp%MDInputFile = TRIM(FilePath)//TRIM(InitInp%MDInputFile) + !END IF + !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 + + END SUBROUTINE ReadDriverInputFile + + subroutine print_help() + print '(a)', 'usage: ' + print '(a)', '' + print '(a)', 'MoorDynDriver.exe driverfilename' + print '(a)', '' + print '(a)', 'Where driverfilename is the name of the MoorDyn driver input file.' + print '(a)', '' + end subroutine print_help +!---------------------------------------------------------------------------------------------------------------------------------- + +END PROGRAM diff --git a/modules/moordyn/src/MoorDyn_IO.f90 b/modules/moordyn/src/MoorDyn_IO.f90 index 2eb3c9a67..14d93ff6b 100644 --- a/modules/moordyn/src/MoorDyn_IO.f90 +++ b/modules/moordyn/src/MoorDyn_IO.f90 @@ -1,6 +1,7 @@ !********************************************************************************************************************************** ! LICENSING -! Copyright (C) 2015 Matthew Hall +! Copyright (C) 2020-2021 Alliance for Sustainable Energy, LLC +! Copyright (C) 2015-2019 Matthew Hall ! ! This file is part of MoorDyn. ! @@ -28,6 +29,11 @@ MODULE MoorDyn_IO PRIVATE + INTEGER(IntKi), PARAMETER :: wordy = 0 ! verbosity level. >1 = more console output + + INTEGER, PARAMETER :: nCoef = 30 ! maximum number of entries to allow in nonlinear coefficient lookup tables + ! it would be nice if the above worked for everything, but I think it needs to also be matched in the Registry + ! --------------------------- Output definitions ----------------------------------------- ! The following are some definitions for use with the output options in MoorDyn. @@ -41,8 +47,7 @@ MODULE MoorDyn_IO ! QType - (int) the type of quantity to output. 0=tension, 1=x pos, etc. see the parameters below ! NodeID - (int) the ID number of the node of the output quantity - ! These are the "OTypes": 0=Connect object, 1=Line Object - ! (will just use 0 and 1 rather than parameter names) + ! These are the "OTypes": 1=Line, 2=Connect, 3=Rod, 4=Body ! Indices for computing output channels: - customized for the MD_OutParmType approach ! these are the "QTypes" @@ -56,17 +61,26 @@ MODULE MoorDyn_IO INTEGER, PARAMETER :: AccX = 7 INTEGER, PARAMETER :: AccY = 8 INTEGER, PARAMETER :: AccZ = 9 - INTEGER, PARAMETER :: Ten = 10 - INTEGER, PARAMETER :: FX = 11 - INTEGER, PARAMETER :: FY = 12 - INTEGER, PARAMETER :: FZ = 13 + INTEGER, PARAMETER :: Ten = 10 + INTEGER, PARAMETER :: FX = 11 + INTEGER, PARAMETER :: FY = 12 + INTEGER, PARAMETER :: FZ = 13 + INTEGER, PARAMETER :: MX = 14 + INTEGER, PARAMETER :: MY = 15 + INTEGER, PARAMETER :: MZ = 16 + INTEGER, PARAMETER :: Pitch = 17 + INTEGER, PARAMETER :: Roll = 18 + INTEGER, PARAMETER :: Yaw = 19 + INTEGER, PARAMETER :: Sub = 20 ! List of units corresponding to the quantities parameters for QTypes - CHARACTER(ChanLen), PARAMETER :: UnitList(0:13) = (/ & + CHARACTER(ChanLen), PARAMETER :: UnitList(0:20) = (/ & "(s) ","(m) ","(m) ","(m) ", & "(m/s) ","(m/s) ","(m/s) ", & "(m/s2) ","(m/s2) ","(m/s2) ", & - "(N) ","(N) ","(N) ","(N) " /) + "(N) ","(N) ","(N) ","(N) ", & + "(Nm) ","(Nm) ","(Nm) ", & + "(deg) ","(deg) ","(deg) ","(frac) "/) CHARACTER(28), PARAMETER :: OutPFmt = "( I4, 3X,A 10,1 X, A10 )" ! Output format parameter output list. CHARACTER(28), PARAMETER :: OutSFmt = "ES10.3E2" @@ -84,7 +98,11 @@ MODULE MoorDyn_IO - PUBLIC :: MDIO_ReadInput + ! PUBLIC :: MDIO_ReadInput + PUBLIC :: setupBathymetry + PUBLIC :: getCoefficientOrCurve + PUBLIC :: SplitByBars + PUBLIC :: DecomposeString PUBLIC :: MDIO_OpenOutput PUBLIC :: MDIO_CloseOutput PUBLIC :: MDIO_ProcessOutList @@ -94,525 +112,280 @@ MODULE MoorDyn_IO CONTAINS + SUBROUTINE setupBathymetry(inputString, defaultDepth, BathGrid, BathGrid_Xs, BathGrid_Ys, ErrStat3, ErrMsg3) + ! SUBROUTINE getBathymetry(inputString, BathGrid, BathGrid_Xs, BathGrid_Ys, BathGrid_npoints, ErrStat3, ErrMsg3) + CHARACTER(40), INTENT(IN ) :: inputString ! string describing water depth or bathymetry filename + REAL(ReKi), INTENT(IN ) :: defaultDepth ! depth to use if inputString is empty + REAL(DbKi), ALLOCATABLE, INTENT(INOUT) :: BathGrid (:,:) + REAL(DbKi), ALLOCATABLE, INTENT(INOUT) :: BathGrid_Xs (:) + REAL(DbKi), ALLOCATABLE, INTENT(INOUT) :: BathGrid_Ys (:) + INTEGER(IntKi), INTENT( OUT) :: ErrStat3 ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg3 ! Error message if ErrStat /= ErrID_None - !==================================================================================================== - SUBROUTINE MDIO_ReadInput( InitInp, p, m, ErrStat, ErrMsg ) - - ! This subroutine reads the input required for MoorDyn from the file whose name is an - ! input parameter. It sets the size of p%NTypes, NConnects, and NLines, - ! allocates LineTypeList, ConnectList, and LineList, and puts all the read contents of - ! the input file into the respective slots in those lists of types. - - - ! Passed variables - - TYPE(MD_InitInputType), INTENT( INOUT ) :: InitInp ! the MoorDyn data - TYPE(MD_ParameterType), INTENT(INOUT) :: p ! Parameters - TYPE(MD_MiscVarType), INTENT( OUT) :: m ! INTENT( OUT) : Initial misc/optimization vars - 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 - - INTEGER :: I ! generic integer for counting - INTEGER :: J ! generic integer for counting - INTEGER :: UnIn ! Unit number for the input file - INTEGER :: UnEc ! The local unit number for this module's echo file - CHARACTER(1024) :: EchoFile ! Name of MoorDyn echo file - CHARACTER(1024) :: Line ! String to temporarially hold value of read line - CHARACTER(20) :: LineOutString ! String to temporarially hold characters specifying line output options - CHARACTER(20) :: OptString ! String to temporarially hold name of option variable - CHARACTER(20) :: OptValue ! String to temporarially hold value of options variable input - CHARACTER(1024) :: FileName ! - - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MDIO_ReadInput' - - - ! - UnEc = -1 - - ! Initialize ErrStat - ErrStat = ErrID_None - ErrMsg = "" - - !------------------------------------------------------------------------------------------------- - ! Open the file - !------------------------------------------------------------------------------------------------- - FileName = TRIM(InitInp%FileName) - - CALL GetNewUnit( UnIn ) - CALL OpenFInpFile( UnIn, FileName, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - - CALL WrScr( ' MD_Init: Opening MoorDyn input file: '//FileName ) - - - !------------------------------------------------------------------------------------------------- - ! File header - !------------------------------------------------------------------------------------------------- - - CALL ReadCom( UnIn, FileName, 'MoorDyn input file header line 1', ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - - CALL ReadCom( UnIn, FileName, 'MoorDyn input file header line 2', ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - - ! Echo Input Files. - CALL ReadVar ( UnIn, FileName, InitInp%Echo, 'Echo', 'Echo Input', ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - 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. - - IF ( InitInp%Echo ) THEN - - !print *, 'gonna try to open echo file' - - EchoFile = TRIM(p%RootName)//'.ech' ! open an echo file for writing - - !print *, 'name is ', EchoFile - - CALL GetNewUnit( UnEc ) - CALL OpenEcho ( UnEc, EchoFile, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - REWIND(UnIn) ! rewind to start of input file to re-read the first few lines - - - - - CALL ReadCom( UnIn, FileName, 'MoorDyn input file header line 1', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - CALL ReadCom( UnIn, FileName, 'MoorDyn input file header line 2', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - 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', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - !print *, 'at end of echo if statement' - - END IF - - - !------------------------------------------------------------------------------------------------- - ! Line Types Properties Section - !------------------------------------------------------------------------------------------------- - - CALL ReadCom( UnIn, FileName, 'Line types header', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - - CALL ReadVar ( UnIn, FileName, p%NTypes, 'NTypes', 'Number of line types', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - - ! Table header - DO I = 1, 2 - CALL ReadCom( UnIn, FileName, 'Line types table header', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - END DO - - ! make sure NTypes isn't zero - IF ( p%NTypes < 1 ) THEN - CALL SetErrStat( ErrID_Fatal, 'NTypes parameter must be greater than zero.', ErrStat, ErrMsg, RoutineName ) - CALL CleanUp() - RETURN - END IF - - ! Allocate memory for LineTypeList array to hold line type properties - ALLOCATE ( m%LineTypeList(p%NTypes), STAT = ErrStat2 ) - IF ( ErrStat2 /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, 'Error allocating space for LineTypeList array.', ErrStat, ErrMsg, RoutineName ) - CALL CleanUp() - RETURN - END IF - - ! read each line - DO I = 1,p%NTypes - ! read the table entries Name Diam MassDenInAir EA cIntDamp Can Cat Cdn Cdt in the MoorDyn input file - READ(UnIn,'(A)',IOSTAT=ErrStat2) Line !read into a line - - IF (ErrStat2 == 0) THEN - READ(Line,*,IOSTAT=ErrStat2) m%LineTypeList(I)%name, m%LineTypeList(I)%d, & - m%LineTypeList(I)%w, m%LineTypeList(I)%EA, m%LineTypeList(I)%BA, & - m%LineTypeList(I)%Can, m%LineTypeList(I)%Cat, m%LineTypeList(I)%Cdn, m%LineTypeList(I)%Cdt - END IF - - m%LineTypeList(I)%IdNum = I ! specify IdNum of line type for error checking - - - IF ( ErrStat2 /= ErrID_None ) THEN - CALL SetErrStat( ErrID_Fatal, 'Failed to read line type properties for line '//trim(Num2LStr(I)), ErrStat, ErrMsg, RoutineName ) - CALL CleanUp() - RETURN - END IF - - IF ( InitInp%Echo ) THEN - WRITE( UnEc, '(A)' ) TRIM(Line) - END IF - - END DO - - - - !------------------------------------------------------------------------------------------------- - ! Connections Section - !------------------------------------------------------------------------------------------------- - - CALL ReadCom( UnIn, FileName, 'Connections header', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - - CALL ReadVar ( UnIn, FileName, p%NConnects, 'NConnects', 'Number of Connects', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - - ! Table header - DO I = 1, 2 - CALL ReadCom( UnIn, FileName, 'Connects header', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - END DO - - ! make sure NConnects is at least two - IF ( p%NConnects < 2 ) THEN - ErrMsg = ' NConnects parameter must be at least 2.' - CALL CleanUp() - RETURN - END IF - - ! allocate ConnectList - ALLOCATE ( m%ConnectList(p%NConnects), STAT = ErrStat2 ) - IF ( ErrStat2 /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, 'Error allocating space for ConnectList array.', ErrStat, ErrMsg, RoutineName ) - CALL CleanUp() - RETURN - END IF - - - ! read each line - DO I = 1,p%NConnects - ! read the table entries Node Type X Y Z M V FX FY FZ Cda Ca - READ(UnIn,'(A)',IOSTAT=ErrStat2) Line !read into a line - - IF (ErrStat2 == 0) THEN - READ(Line,*,IOSTAT=ErrStat2) m%ConnectList(I)%IdNum, m%ConnectList(I)%type, m%ConnectList(I)%conX, & - m%ConnectList(I)%conY, m%ConnectList(I)%conZ, m%ConnectList(I)%conM, & - m%ConnectList(I)%conV, m%ConnectList(I)%conFX, m%ConnectList(I)%conFY, & - m%ConnectList(I)%conFZ, m%ConnectList(I)%conCdA, m%ConnectList(I)%conCa - END IF - - IF ( ErrStat2 /= 0 ) THEN - CALL WrScr(' Unable to parse Connection '//trim(Num2LStr(I))//' row in input file.') ! Specific screen output because errors likely - CALL WrScr(' Ensure row has all 12 columns, including CdA and Ca.') ! to be caused by non-updated input file formats. - CALL SetErrStat( ErrID_Fatal, 'Failed to read connects.' , ErrStat, ErrMsg, RoutineName ) ! would be nice to specify which line <<<<<<<<< - CALL CleanUp() - RETURN - END IF - - ! check for sequential IdNums - IF ( m%ConnectList(I)%IdNum .NE. I ) THEN - CALL SetErrStat( ErrID_Fatal, 'Node numbers must be sequential starting from 1.', ErrStat, ErrMsg, RoutineName ) - CALL CleanUp() - RETURN - END IF - - - - - IF ( InitInp%Echo ) THEN - WRITE( UnEc, '(A)' ) TRIM(Line) - END IF - - END DO - - - !------------------------------------------------------------------------------------------------- - ! Lines Section - !------------------------------------------------------------------------------------------------- + INTEGER(IntKi) :: I + INTEGER(IntKi) :: UnCoef ! unit number for coefficient input file + + INTEGER(IntKi) :: ErrStat4 + CHARACTER(120) :: ErrMsg4 + CHARACTER(120) :: Line2 - CALL ReadCom( UnIn, FileName, 'Lines header', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF + CHARACTER(20) :: nGridX_string ! string to temporarily hold the nGridX string from Line2 + CHARACTER(20) :: nGridY_string ! string to temporarily hold the nGridY string from Line3 + INTEGER(IntKi) :: nGridX ! integer of the size of BathGrid_Xs + INTEGER(IntKi) :: nGridY ! integer of the size of BathGrid_Ys - CALL ReadVar ( UnIn, FileName, p%NLines, 'NLines', 'Number of Lines', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF + IF (LEN_TRIM(inputString) == 0) THEN + ! If the input is empty (not provided), make the 1x1 bathymetry grid using the default depth + ALLOCATE(BathGrid(1,1), STAT=ErrStat4) + BathGrid(1,1) = REAL(defaultDepth,R8Ki) + + ALLOCATE(BathGrid_Xs(1), STAT=ErrStat4) + BathGrid_Xs(1) = 0.0_DbKi + + ALLOCATE(BathGrid_Ys(1), STAT=ErrStat4) + BathGrid_Ys(1) = 0.0_DbKi + + ELSE IF (SCAN(inputString, "abcdfghijklmnopqrstuvwxyzABCDFGHIJKLMNOPQRSTUVWXYZ") == 0) THEN + ! If the input does not have any of these string values, let's treat it as a number but store in a matrix + ALLOCATE(BathGrid(1,1), STAT=ErrStat4) + READ(inputString, *, IOSTAT=ErrStat4) BathGrid(1,1) + + ALLOCATE(BathGrid_Xs(1), STAT=ErrStat4) + BathGrid_Xs(1) = 0.0_DbKi + + ALLOCATE(BathGrid_Ys(1), STAT=ErrStat4) + BathGrid_Ys(1) = 0.0_DbKi + ELSE ! otherwise interpret the input as a file name to load the bathymetry lookup data from + CALL WrScr(" The depth input contains letters so will load a bathymetry file.") + + ! load lookup table data from file + CALL GetNewUnit( UnCoef ) ! unit number for coefficient input file + CALL OpenFInpFile( UnCoef, TRIM(inputString), ErrStat4, ErrMsg4 ) + cALL SetErrStat(ErrStat4, ErrMsg4, ErrStat3, ErrMsg3, 'MDIO_getBathymetry') + + READ(UnCoef,'(A)',IOSTAT=ErrStat4) Line2 ! skip the first title line + READ(UnCoef,*,IOSTAT=ErrStat4) nGridX_string, nGridX ! read in the second line as the number of x values in the BathGrid + READ(UnCoef,*,IOSTAT=ErrStat4) nGridY_string, nGridY ! read in the third line as the number of y values in the BathGrid + + ! Allocate the bathymetry matrix and associated grid x and y values + ALLOCATE(BathGrid(nGridX, nGridY), STAT=ErrStat4) + ALLOCATE(BathGrid_Xs(nGridX), STAT=ErrStat4) + ALLOCATE(BathGrid_Ys(nGridY), STAT=ErrStat4) + + DO I = 1, nGridY+1 ! loop through each line in the rest of the bathymetry file + + READ(UnCoef,'(A)',IOSTAT=ErrStat4) Line2 ! read into a line and call it Line2 + IF (ErrStat4 > 0) EXIT + + IF (I==1) THEN ! if it's the first line in the Bathymetry Grid, then it's a list of all the x values + READ(Line2, *,IOSTAT=ErrStat4) BathGrid_Xs + ELSE ! if it's not the first line, then the first value is a y value and the rest are the depth values + READ(Line2, *,IOSTAT=ErrStat4) BathGrid_Ys(I-1), BathGrid(I-1,:) + ENDIF + + END DO - ! Table header - DO I = 1, 2 - CALL ReadCom( UnIn, FileName, 'Lines header', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - END DO - - ! make sure NLines is at least one - IF ( p%NLines < 1 ) THEN - CALL SetErrStat( ErrID_Fatal, 'NLines parameter must be at least 1.', ErrStat, ErrMsg, RoutineName ) - CALL CleanUp() - RETURN - END IF - - ! allocate LineList - ALLOCATE ( m%LineList(p%NLines), STAT = ErrStat2 ) - IF ( ErrStat2 /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, 'Error allocating space for LineList array.', ErrStat, ErrMsg, RoutineName ) - CALL CleanUp() - RETURN - END IF - - ! read each line - DO I = 1,p%NLines - ! read the table entries Line LineType UnstrLen NumSegs NodeAnch NodeFair Flags/Outputs - READ(UnIn,'(A)',IOSTAT=ErrStat2) Line !read into a line - - - IF (ErrStat2 == 0) THEN - READ(Line,*,IOSTAT=ErrStat2) m%LineList(I)%IdNum, m%LineList(I)%type, m%LineList(I)%UnstrLen, & - m%LineList(I)%N, m%LineList(I)%AnchConnect, m%LineList(I)%FairConnect, LineOutString, m%LineList(I)%CtrlChan - END IF - - IF ( ErrStat2 /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, 'Failed to read line data for Line '//trim(Num2LStr(I)), ErrStat, ErrMsg, RoutineName ) - CALL CleanUp() - RETURN - END IF - - - ! check for sequential IdNums - IF ( m%LineList(I)%IdNum .NE. I ) THEN - CALL SetErrStat( ErrID_Fatal, 'Line numbers must be sequential starting from 1.', ErrStat, ErrMsg, RoutineName ) - CALL CleanUp() - RETURN - END IF - - ! identify index of line type - DO J = 1,p%NTypes - IF (trim(m%LineList(I)%type) == trim(m%LineTypeList(J)%name)) THEN - m%LineList(I)%PropsIdNum = J - EXIT - IF (J == p%NTypes) THEN ! call an error if there is no match - CALL SetErrStat( ErrID_Severe, 'Unable to find matching line type name for Line '//trim(Num2LStr(I)), ErrStat, ErrMsg, RoutineName ) - END IF + IF (I < 2) THEN + ErrStat3 = ErrID_Fatal + ErrMsg3 = "Less than the minimum of 2 data lines found in file "//TRIM(inputString) + CLOSE (UnCoef) + RETURN + ELSE + ! BathGrid_npoints = nGridX*nGridY ! save the number of points in the grid + CLOSE (UnCoef) END IF - END DO - - ! process output flag characters (LineOutString) and set line output flag array (OutFlagList) - m%LineList(I)%OutFlagList = 0 ! first set array all to zero - IF ( scan( LineOutString, 'p') > 0 ) m%LineList(I)%OutFlagList(2) = 1 - IF ( scan( LineOutString, 'v') > 0 ) m%LineList(I)%OutFlagList(3) = 1 - IF ( scan( LineOutString, 'U') > 0 ) m%LineList(I)%OutFlagList(4) = 1 - IF ( scan( LineOutString, 'D') > 0 ) m%LineList(I)%OutFlagList(5) = 1 - IF ( scan( LineOutString, 't') > 0 ) m%LineList(I)%OutFlagList(6) = 1 - IF ( scan( LineOutString, 'c') > 0 ) m%LineList(I)%OutFlagList(7) = 1 - IF ( scan( LineOutString, 's') > 0 ) m%LineList(I)%OutFlagList(8) = 1 - IF ( scan( LineOutString, 'd') > 0 ) m%LineList(I)%OutFlagList(9) = 1 - IF ( scan( LineOutString, 'l') > 0 ) m%LineList(I)%OutFlagList(10)= 1 - IF (SUM(m%LineList(I)%OutFlagList) > 0) m%LineList(I)%OutFlagList(1) = 1 ! this first entry signals whether to create any output file at all - ! the above letter-index combinations define which OutFlagList entry corresponds to which output type - - - ! check errors - IF ( ErrStat /= ErrID_None ) THEN - ErrMsg = ' Failed to read line data for Line '//trim(Num2LStr(I)) - CALL CleanUp() - RETURN - END IF - - - IF ( InitInp%Echo ) THEN - WRITE( UnEc, '(A)' ) TRIM(Line) - END IF - - END DO ! I - + + END IF - !------------------------------------------------------------------------------------------------- - ! Read any options lines - !------------------------------------------------------------------------------------------------- + END SUBROUTINE setupBathymetry + - CALL ReadCom( UnIn, FileName, 'Options header', ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF + ! read in stiffness/damping coefficient or load nonlinear data file if applicable + SUBROUTINE getCoefficientOrCurve(inputString, LineProp_c, LineProp_npoints, LineProp_Xs, LineProp_Ys, ErrStat3, ErrMsg3) + + CHARACTER(40), INTENT(IN ) :: inputString + REAL(DbKi), INTENT(INOUT) :: LineProp_c + INTEGER(IntKi), INTENT( OUT) :: LineProp_nPoints + REAL(DbKi), INTENT( OUT) :: LineProp_Xs (nCoef) + REAL(DbKi), INTENT( OUT) :: LineProp_Ys (nCoef) + + INTEGER(IntKi), INTENT( OUT) :: ErrStat3 ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg3 ! Error message if ErrStat /= ErrID_None - ! loop through any remaining input lines, and use them to set options (overwriting default values in many cases). - ! doing this manually since I'm not sure that there is a built in subroutine for reading any input value on any line number. - DO - - READ(UnIn,'(A)',IOSTAT=ErrStat2) Line !read into a line - - IF (ErrStat2 == 0) THEN - IF (( Line(1:3) == '---' ) .OR. ( Line(1:3) == 'END' ) .OR. ( Line(1:3) == 'end' )) EXIT ! check if it's the end line - - READ(Line,*,IOSTAT=ErrStat2) OptValue, OptString ! look at first two entries, ignore remaining words in line, which should be comments - END IF - - IF ( ErrStat2 /= 0 ) THEN - CALL SetErrStat( ErrID_Fatal, 'Failed to read options.', ErrStat, ErrMsg, RoutineName ) ! would be nice to specify which line had the error - CALL CleanUp() - RETURN - END IF - - CALL Conv2UC(OptString) - - ! check all possible options types and see if OptString is one of them, in which case set the variable. - if ( OptString == 'DTM') THEN - read (OptValue,*) p%dtM0 ! InitInp%DTmooring - else if ( OptString == 'G') then - read (OptValue,*) p%G - else if ( OptString == 'RHOW') then - read (OptValue,*) p%rhoW - else if ( OptString == 'WTRDPTH') then - read (OptValue,*) p%WtrDpth - else if ( OptString == 'KBOT') then - read (OptValue,*) p%kBot - else if ( OptString == 'CBOT') then - read (OptValue,*) p%cBot - else if ( OptString == 'DTIC') then - read (OptValue,*) InitInp%dtIC - else if ( OptString == 'TMAXIC') then - read (OptValue,*) InitInp%TMaxIC - else if ( OptString == 'CDSCALEIC') then - read (OptValue,*) InitInp%CdScaleIC - else if ( OptString == 'THRESHIC') then - read (OptValue,*) InitInp%threshIC - else - CALL SetErrStat( ErrID_Warn, 'unable to interpret input '//trim(OptString), ErrStat, ErrMsg, RoutineName ) - end if - - IF ( InitInp%Echo ) THEN - WRITE( UnEc, '(A)' ) TRIM(Line) - END IF - - END DO - - - !------------------------------------------------------------------------------------------------- - ! Read the FAST-style outputs list in the final section, if there is one - !------------------------------------------------------------------------------------------------- - ! we don't read in the outputs header line because it's already been read in for detecting the end of the variable-length options section - ! CALL ReadCom( UnIn, FileName, 'Outputs header', ErrStat, ErrMsg, UnEc ) - - ! allocate InitInp%Outliest (to a really big number for now...) - CALL AllocAry( InitInp%OutList, 1000, "MoorDyn Input File's Outlist", ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() + INTEGER(IntKi) :: nC, I + INTEGER(IntKi) :: UnCoef ! unit number for coefficient input file + + + INTEGER(IntKi) :: ErrStat4 + CHARACTER(120) :: ErrMsg4 + CHARACTER(120) :: Line2 + + + if (SCAN(inputString, "abcdfghijklmnopqrstuvwxyzABCDFGHIJKLMNOPQRSTUVWXYZ") == 0) then ! "eE" are exluded as they're used for scientific notation! + + ! "found NO letter in the line coefficient value so treating it as a number." + READ(inputString, *, IOSTAT=ErrStat4) LineProp_c ! convert the entry string into a real number + LineProp_npoints = 0; + + else ! otherwise interpet the input as a file name to load stress-strain lookup data from + + CALL WrScr("found A letter in the line coefficient value so will try to load the filename.") + + LineProp_c = 0.0 + + ! load lookup table data from file + + CALL GetNewUnit( UnCoef ) + CALL OpenFInpFile( UnCoef, TRIM(inputString), ErrStat4, ErrMsg4 ) ! add error handling? + + READ(UnCoef,'(A)',IOSTAT=ErrStat4) Line2 ! skip the first two lines (title, names, and units) then parse + READ(UnCoef,'(A)',IOSTAT=ErrStat4) Line2 + READ(UnCoef,'(A)',IOSTAT=ErrStat4) Line2 + + DO I = 1, nCoef + + READ(UnCoef,'(A)',IOSTAT=ErrStat4) Line2 !read into a line + + IF (ErrStat4 > 0) then + CALL WrScr("Error while reading lookup table file") + EXIT + ELSE IF (ErrStat4 < 0) then + CALL WrScr("Read "//trim(Int2LStr(I-1))//" data lines from lookup table file") + EXIT + ELSE + READ(Line2,*,IOSTAT=ErrStat4) LineProp_Xs(I), LineProp_Ys(I) + END IF + END DO + + if (I < 2) then + ErrStat3 = ErrID_Fatal + ErrMsg3 = "Less than the minimum of 2 data lines found in file "//TRIM(inputString)//" (first 3 lines are headers)." + LineProp_npoints = 0 + Close (UnCoef) RETURN + else + LineProp_npoints = I-1 + Close (UnCoef) + end if + + END IF + + END SUBROUTINE getCoefficientOrCurve + + + ! Split a string into separate strings by the bar (|) symbol + SUBROUTINE SplitByBars(instring, n, outstrings) + + CHARACTER(*), INTENT(INOUT) :: instring + INTEGER(IntKi), INTENT( OUT) :: n + CHARACTER(40), INTENT(INOUT) :: outstrings(6) ! array of output strings. Up to 6 strings can be read + + INTEGER :: pos1, pos2, i + + n = 0 + pos1=1 + + DO + pos2 = INDEX(instring(pos1:), "|") ! find index of next comma + IF (pos2 == 0) THEN ! if there isn't another comma, read the last entry and call it done (this could be the only entry if no commas) + n = n + 1 + outstrings(n) = instring(pos1:) + EXIT END IF + n = n + 1 + if (n > 6) then + CALL WrScr("ERROR - SplitByBars cannot do more than 6 entries") + end if + outstrings(n) = instring(pos1:pos1+pos2-2) + pos1 = pos2+pos1 + END DO + + END SUBROUTINE SplitByBars - ! OutList - List of user-requested output channels (-): - CALL ReadOutputList ( UnIn, FileName, InitInp%OutList, p%NumOuts, 'OutList', "List of user-requested output channels", ErrStat2, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) THEN - CALL CleanUp() - RETURN - END IF - - !print *, 'NumOuts is ', p%NumOuts - !print *, ' OutList is ', InitInp%OutList(1:p%NumOuts) - - - !------------------------------------------------------------------------------------------------- - ! This is the end of the input file - !------------------------------------------------------------------------------------------------- - - CALL CleanUp() - CONTAINS - ! subroutine to set ErrState and close the files if an error occurs - SUBROUTINE CleanUp() - - ! ErrStat = ErrID_Fatal - CLOSE( UnIn ) - IF (InitInp%Echo) CLOSE( UnEc ) + ! Split a string into separate letter strings and integers. Letters are converted to uppercase. + SUBROUTINE DecomposeString(outWord, let1, num1, let2, num2, let3) + + CHARACTER(*), INTENT(INOUT) :: outWord + CHARACTER(25), INTENT( OUT) :: let1 + ! INTEGER(IntKi), INTENT( OUT) :: num1 + CHARACTER(25), INTENT( OUT) :: num1 + CHARACTER(25), INTENT( OUT) :: let2 + CHARACTER(25), INTENT( OUT) :: num2 +! INTEGER(IntKi), INTENT( OUT) :: num2 + CHARACTER(25), INTENT( OUT) :: let3 + + INTEGER(IntKi) :: I ! Generic loop-counting index + + CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I), the name of each output channel + CHARACTER(ChanLen) :: qVal ! quantity type string to match to list of valid options + + INTEGER :: oID ! ID number of connect or line object + INTEGER :: nID ! ID number of node object + INTEGER :: i1 = 0 ! indices of start of numbers or letters in OutListTmp string, for parsing + INTEGER :: i2 = 0 + INTEGER :: i3 = 0 + INTEGER :: i4 = 0 - END SUBROUTINE + + CALL Conv2UC(outWord) ! convert to all uppercase for string matching purposes - END SUBROUTINE MDIO_ReadInput - ! ==================================================================================================== + ! start these strings as empty, and fill in only if used + let1 = '' + num1 = '' + let2 = '' + num2 = '' + let3 = '' + ! find indicies of changes in number-vs-letter in characters of outWord and split into segments accordingly + + i1 = scan( outWord , '1234567890' ) ! find index of first number in the string + if (i1 > 0) then ! if there is a number + let1 = TRIM(outWord( 1:i1-1)) + i2 = i1+verify( outWord(i1+1:) , '1234567890' ) ! find starting index of second set of letters (if first character is a letter, i.e. i1>1), otherwise index of first letter + if (i2 > i1) then ! if there is a second letter/word + num1 = TRIM(outWord(i1:i2-1)) + i3 = i2+scan( outWord(i2+1:) , '1234567890' ) ! find starting index of second set of numbers <<<< + if (i3 > i2) then ! if there is a second number + let2 = TRIM(outWord(i2:i3-1)) + i4 = i3+verify( outWord(i3+1:) , '1234567890' ) ! third letter start + if (i4 > i3) then ! if there is a third letter/word + num2 = TRIM(outWord(i3:i4-1)) + let3 = TRIM(outWord(i4: )) + else + num2 = TRIM(outWord(i3:)) + end if + else + let2 = TRIM(outWord(i2:)) + end if + else + num1 = TRIM(outWord(i1:)) + end if + else + let1 = TRIM(outWord) + end if + + + !READ(outWord(i1:i2-1)) num1 + !READ(outWord(i3:i4-1)) num2 + + ! print *, "Decomposed string ", outWord, " into:" + ! print *, let1 + ! print *, num1 + ! print *, let2 + ! print *, num2 + ! print *, let3 + ! print *, "based on indices (i1-i4):" + ! print *, i1 + ! print *, i2 + ! print *, i3 + ! print *, i4 + + END SUBROUTINE DecomposeString + ! ==================================================================================================== @@ -645,7 +418,16 @@ SUBROUTINE MDIO_ProcessOutList(OutList, p, m, y, InitOut, ErrStat, ErrMsg ) INTEGER :: oID ! ID number of connect or line object INTEGER :: nID ! ID number of node object INTEGER :: i1,i2,i3,i4 ! indices of start of numbers or letters in OutListTmp string, for parsing - + + CHARACTER(25) :: let1 ! strings used for splitting and parsing identifiers + CHARACTER(25) :: num1 + CHARACTER(25) :: let2 + CHARACTER(25) :: num2 + CHARACTER(25) :: let3 + + INTEGER(IntKi) :: LineNumOuts ! number of entries in LineWrOutput for each line + INTEGER(IntKi) :: RodNumOuts ! same for Rods + ! see the top of the module for info on the output labelling types @@ -680,74 +462,114 @@ SUBROUTINE MDIO_ProcessOutList(OutList, p, m, y, InitOut, ErrStat, ErrMsg ) DO I = 1,p%NumOuts OutListTmp = OutList(I) ! current requested output name + + call DecomposeString(OutListTmp, let1, num1, let2, num2, let3) + + + !p%OutParam(I)%Name = OutListTmp CALL Conv2UC(OutListTmp) ! convert to all uppercase for string matching purposes - ! find indicies of changes in number-vs-letter in characters of OutListTmp - i1 = scan( OutListTmp , '1234567890' ) ! first number in the string - i2 = i1+verify( OutListTmp(i1+1:) , '1234567890' ) ! second letter start (assuming first character is a letter, i.e. i1>1) - i3 = i2+scan( OutListTmp(i2+1:) , '1234567890' ) ! second number start - i4 = i3+verify( OutListTmp(i3+1:) , '1234567890' ) ! third letter start - !i5 = scan( OutListTmp(i1:) , '1234567890' ) ! find first letter after first number - + ! ! find indicies of changes in number-vs-letter in characters of OutListTmp + ! i1 = scan( OutListTmp , '1234567890' ) ! first number in the string + ! i2 = i1+verify( OutListTmp(i1+1:) , '1234567890' ) ! second letter start (assuming first character is a letter, i.e. i1>1) + ! i3 = i2+scan( OutListTmp(i2+1:) , '1234567890' ) ! second number start + ! i4 = i3+verify( OutListTmp(i3+1:) , '1234567890' ) ! third letter start + ! error check - IF (i1 <= 1) THEN - CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid - CALL WrScr('Warning: invalid output specifier '//trim(OutListTmp)//'. Starting character must be C or L.') - CYCLE ! <<<<<<<<<<< check correct usage - END IF + ! IF (i1 <= 1) THEN + ! CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid + ! CALL WrScr('Warning: invalid output specifier '//trim(OutListTmp)//'. Starting character must be C or L.') + ! CYCLE ! <<<<<<<<<<< check correct usage + ! END IF p%OutParam(I)%Name = OutListTmp ! label channel with whatever name was inputted, for now ! figure out what type of output it is and process accordingly - ! fairlead tension case (updated) - IF (OutListTmp(1:i1-1) == 'FAIRTEN') THEN - p%OutParam(I)%OType = 2 ! connection object type + ! fairlead tension case (updated) <<<<<<<<<<<<<<<<<<<<<<<<<<< these are not currently working - need new way to find ObjID + IF (let1 == 'FAIRTEN') THEN + p%OutParam(I)%OType = 1 ! line object type p%OutParam(I)%QType = Ten ! tension quantity type p%OutParam(I)%Units = UnitList(Ten) ! set units according to QType - READ (OutListTmp(i1:),*) oID ! this is the line number - p%OutParam(I)%ObjID = m%LineList(oID)%FairConnect ! get the connection ID of the fairlead - p%OutParam(I)%NodeID = -1 ! not used. m%LineList(oID)%N ! specify node N (fairlead) - + READ (num1,*) oID ! this is the line number + p%OutParam(I)%ObjID = oID ! record the ID of the line + p%OutParam(I)%NodeID = m%LineList(oID)%N ! specify node N (end B, fairlead) + ! >>> should check validity of ObjID and NodeID <<< + ! achor tension case - ELSE IF (OutListTmp(1:i1-1) == 'ANCHTEN') THEN - p%OutParam(I)%OType = 2 ! connectoin object type + ELSE IF (let1 == 'ANCHTEN') THEN + p%OutParam(I)%OType = 1 ! line object type p%OutParam(I)%QType = Ten ! tension quantity type p%OutParam(I)%Units = UnitList(Ten) ! set units according to QType - READ (OutListTmp(i1:),*) oID ! this is the line number - p%OutParam(I)%ObjID = m%LineList(oID)%AnchConnect ! get the connection ID of the fairlead - p%OutParam(I)%NodeID = -1 ! not used. m%LineList(oID)%0 ! specify node 0 (anchor) + READ (num1,*) oID ! this is the line number + p%OutParam(I)%ObjID = oID ! record the ID of the line + p%OutParam(I)%NodeID = 0 ! specify node 0 (end A, anchor) ! more general case ELSE ! what object type? - ! Line case ... L?N?xxxx - IF (OutListTmp(1:i1-1) == 'L') THEN + + ! Line case + IF (let1(1:1) == 'L') THEN ! Look for L?N?xxxx p%OutParam(I)%OType = 1 ! Line object type - ! for now we'll just assume the next character(s) are "n" to represent node number: - READ (OutListTmp(i3:i4-1),*) nID - p%OutParam(I)%NodeID = nID - qVal = OutListTmp(i4:) ! isolate quantity type string - ! Connect case ... C?xxx or Con?xxx - ELSE IF (OutListTmp(1:1) == 'C') THEN + ! for now we'll just assume the next character(s) are "n" to represent node number or "s" to represent segment number + IF (num2/=" ") THEN + READ (num2,*) nID ! node or segment ID + p%OutParam(I)%NodeID = nID + ELSE + CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid + CALL WrScr('Warning: invalid output specifier '//trim(OutListTmp)//'. Line ID or Node ID missing.') + CYCLE + END IF + qVal = let3 ! quantity type string + + ! Connect case + ELSE IF (let1(1:1) == 'C') THEN ! Look for C?xxx or Con?xxx p%OutParam(I)%OType = 2 ! Connect object type - qVal = OutListTmp(i2:) ! isolate quantity type string + qVal = let2 ! quantity type string + + ! Rod case + ELSE IF (let1(1:1) == 'R') THEN ! Look for R?xxx or Rod?xxx + p%OutParam(I)%OType = 3 ! Rod object type + IF (LEN_TRIM(let3)== 0) THEN ! No third character cluster indicates this is a whole-rod channel + p%OutParam(I)%NodeID = 0 + qVal = let2 ! quantity type string + ELSE IF (num2/=" ") THEN + READ (num2,*) nID ! rod node ID + p%OutParam(I)%NodeID = nID + qVal = let3 ! quantity type string + ELSE + CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid + CALL WrScr('Warning: invalid output specifier '//trim(OutListTmp)//'. Rod ID or Node ID missing.') + CYCLE + END IF + + ! Body case + ELSE IF (Let1(1:1) == 'B') THEN ! Look for B?xxx or Body?xxx + p%OutParam(I)%OType = 4 ! Body object type + qVal = let2 ! quantity type string ! should do fairlead option also! ! error ELSE CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid - CALL WrScr('Warning: invalid output specifier '//trim(OutListTmp)//'. Type must be L or C.') + CALL WrScr('Warning: invalid output specifier '//trim(OutListTmp)//'. Must start with L, C, R, or B') CYCLE END IF ! object number - READ (OutListTmp(i1:i2-1),*) oID - p%OutParam(I)%ObjID = oID ! line or connect ID number + IF (num1/=" ") THEN + READ (num1,*) oID + p%OutParam(I)%ObjID = oID ! line or connect ID number + ELSE + CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid + CALL WrScr('Warning: invalid output specifier '//trim(OutListTmp)//'. Object ID missing.') + CYCLE + END IF ! which kind of quantity? IF (qVal == 'PX') THEN @@ -777,7 +599,7 @@ SUBROUTINE MDIO_ProcessOutList(OutList, p, m, y, InitOut, ErrStat, ErrMsg ) ELSE IF (qVal == 'AZ') THEN p%OutParam(I)%QType = AccZ p%OutParam(I)%Units = UnitList(AccZ) - ELSE IF ((qVal == 'T') .or. (qval == 'Ten')) THEN + ELSE IF ((qVal == 'T') .or. (qVal == 'TEN')) THEN p%OutParam(I)%QType = Ten p%OutParam(I)%Units = UnitList(Ten) ELSE IF (qVal == 'FX') THEN @@ -788,7 +610,19 @@ SUBROUTINE MDIO_ProcessOutList(OutList, p, m, y, InitOut, ErrStat, ErrMsg ) p%OutParam(I)%Units = UnitList(FY) ELSE IF (qVal == 'FZ') THEN p%OutParam(I)%QType = FZ - p%OutParam(I)%Units = UnitList(FZ) + p%OutParam(I)%Units = UnitList(FZ) ! <<<< should add moments as well <<<< + ELSE IF (qVal == 'ROLL') THEN + p%OutParam(I)%QType = Roll + p%OutParam(I)%Units = UnitList(Roll) + ELSE IF (qVal == 'PITCH') THEN + p%OutParam(I)%QType = Pitch + p%OutParam(I)%Units = UnitList(Pitch) + ELSE IF (qVal == 'YAW') THEN + p%OutParam(I)%QType = Yaw + p%OutParam(I)%Units = UnitList(Yaw) + ELSE IF (qVal == 'SUB') THEN + p%OutParam(I)%QType = Sub + p%OutParam(I)%Units = UnitList(Sub) ELSE CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid CALL WrScr('Warning: invalid output specifier '//trim(OutListTmp)//'. Quantity type not recognized.') @@ -798,23 +632,44 @@ SUBROUTINE MDIO_ProcessOutList(OutList, p, m, y, InitOut, ErrStat, ErrMsg ) END IF ! also check whether each object index and node index (if applicable) is in range - IF (p%OutParam(I)%OType==2) THEN + + IF (p%OutParam(I)%OType==1) THEN ! Line + IF (p%OutParam(I)%ObjID > p%NLines) THEN + CALL WrScr('Warning: output Line index excedes number of Lines in requested output '//trim(OutListTmp)//'.') + CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid + END IF + IF (p%OutParam(I)%NodeID > m%LineList(p%OutParam(I)%ObjID)%N) THEN + CALL WrScr('Warning: output node index excedes number of nodes in requested output '//trim(OutListTmp)//'.') + CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid + ELSE IF (p%OutParam(I)%NodeID < 0) THEN + CALL WrScr('Warning: output node index is less than zero in requested output '//trim(OutListTmp)//'.') + CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid + END IF + + ELSE IF (p%OutParam(I)%OType==2) THEN ! Connect IF (p%OutParam(I)%ObjID > p%NConnects) THEN CALL WrScr('Warning: output Connect index excedes number of Connects in requested output '//trim(OutListTmp)//'.') CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid END IF - ELSE IF (p%OutParam(I)%OType==1) THEN - IF (p%OutParam(I)%ObjID > p%NLines) THEN - CALL WrScr('Warning: output Line index excedes number of Lines in requested output '//trim(OutListTmp)//'.') + + ELSE IF (p%OutParam(I)%OType==3) THEN ! Rod + IF (p%OutParam(I)%ObjID > p%NRods) THEN + CALL WrScr('Warning: output Rod index excedes number of Rods in requested output '//trim(OutListTmp)//'.') CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid END IF - IF (p%OutParam(I)%NodeID > m%LineList(p%OutParam(I)%ObjID)%N) THEN + IF (p%OutParam(I)%NodeID > m%RodList(p%OutParam(I)%ObjID)%N) THEN CALL WrScr('Warning: output node index excedes number of nodes in requested output '//trim(OutListTmp)//'.') CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid ELSE IF (p%OutParam(I)%NodeID < 0) THEN CALL WrScr('Warning: output node index is less than zero in requested output '//trim(OutListTmp)//'.') CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid END IF + + ELSE IF (p%OutParam(I)%OType==4) THEN ! Body + IF (p%OutParam(I)%ObjID > p%NBodies) THEN + CALL WrScr('Warning: output Body index excedes number of Bodies in requested output '//trim(OutListTmp)//'.') + CALL DenoteInvalidOutput(p%OutParam(I)) ! flag as invalid + END IF END IF @@ -855,13 +710,36 @@ SUBROUTINE MDIO_ProcessOutList(OutList, p, m, y, InitOut, ErrStat, ErrMsg ) ! allocate output array in each Line DO I=1,p%NLines - ALLOCATE(m%LineList(I)%LineWrOutput( 1 + 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:5)) + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(6:10)) ), STAT = ErrStat) + + + ! calculate number of output entries (excluding time) to write for this line + LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:6)) & + + (m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(7:9)) & + + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(10:18)) + + ALLOCATE(m%LineList(I)%LineWrOutput( 1 + LineNumOuts), STAT = ErrStat) IF ( ErrStat /= ErrID_None ) THEN ErrMsg = ' Error allocating space for a LineWrOutput array' ErrStat = ErrID_Fatal RETURN END IF END DO ! I + + ! allocate output array in each Rod + DO I=1,p%NRods + + ! calculate number of output entries (excluding time) to write for this Rod + RodNumOuts = 3*(m%RodList(I)%N + 1)*SUM(m%RodList(I)%OutFlagList(2:9)) & + + (m%RodList(I)%N + 1)*SUM(m%RodList(I)%OutFlagList(10:11)) & + + m%RodList(I)%N*SUM(m%RodList(I)%OutFlagList(12:18)) + + ALLOCATE(m%RodList(I)%RodWrOutput( 1 + RodNumOuts), STAT = ErrStat) + IF ( ErrStat /= ErrID_None ) THEN + ErrMsg = ' Error allocating space for a RodWrOutput array' + ErrStat = ErrID_Fatal + RETURN + END IF + END DO ! I !print *, "y%WriteOutput allocated to size ", size(y%WriteOutput) @@ -888,17 +766,16 @@ SUBROUTINE DenoteInvalidOutput( OutParm ) END SUBROUTINE DenoteInvalidOutput END SUBROUTINE MDIO_ProcessOutList - !==================================================================================================== + !----------------------------------------------------------------------------------------============ - !==================================================================================================== - SUBROUTINE MDIO_OpenOutput( OutRootName, p, m, InitOut, ErrStat, ErrMsg ) + !----------------------------------------------------------------------------------------============ + SUBROUTINE MDIO_OpenOutput( MD_ProgDesc, p, m, InitOut, ErrStat, ErrMsg ) !---------------------------------------------------------------------------------------------------- - - CHARACTER(*), INTENT( IN ) :: OutRootName ! Root name for the output file + TYPE(ProgDesc), INTENT( IN ) :: MD_ProgDesc TYPE(MD_ParameterType), INTENT( INOUT ) :: p TYPE(MD_MiscVarType), INTENT( INOUT ) :: m TYPE(MD_InitOutPutType ), INTENT( IN ) :: InitOut ! @@ -908,8 +785,9 @@ SUBROUTINE MDIO_OpenOutput( OutRootName, p, m, InitOut, ErrStat, ErrMsg ) INTEGER :: I ! Generic loop counter INTEGER :: J ! Generic loop counter CHARACTER(1024) :: OutFileName ! The name of the output file including the full path. -! INTEGER :: L ! counter for index in LineWrOutput - INTEGER :: LineNumOuts ! number of entries in LineWrOutput for each line + INTEGER :: L ! counter for index in LineWrOutput + INTEGER :: LineNumOuts ! number of entries in LineWrOutput for each line + INTEGER :: RodNumOuts ! for Rods ... redundant <<< CHARACTER(200) :: Frmt ! a string to hold a format statement INTEGER :: ErrStat2 @@ -917,7 +795,7 @@ SUBROUTINE MDIO_OpenOutput( OutRootName, p, m, InitOut, ErrStat, ErrMsg ) ErrStat = ErrID_None ErrMsg = "" - p%Delim = ' ' ! for now + p%Delim = ' ' ! for now !------------------------------------------------------------------------------------------------- ! Open the output file, if necessary, and write the header @@ -937,9 +815,17 @@ SUBROUTINE MDIO_OpenOutput( OutRootName, p, m, InitOut, ErrStat, ErrMsg ) END IF + ! Write empty header lines (to match standard OF out file formats used by all other modules) + write (p%MDUnOut,'(/,A/)', IOSTAT=ErrStat) 'These predictions were generated by '//& + TRIM(MD_ProgDesc%Name)//' ('//TRIM(MD_ProgDesc%Ver)//TRIM(MD_ProgDesc%Date)//& + ') on '//CurDate()//' at '//CurTime()//'.' + write(p%MDUnOut,*) '' + write(p%MDUnOut,*) '' + write(p%MDUnOut,*) '' + !Write the names of the output parameters: - Frmt = '(A10,'//TRIM(Int2LStr(p%NumOuts))//'(A1,A10))' + Frmt = '(A10,'//TRIM(Int2LStr(p%NumOuts))//'(A1,A15))' WRITE(p%MDUnOut,Frmt, IOSTAT=ErrStat2) TRIM( 'Time' ), ( p%Delim, TRIM( p%OutParam(I)%Name), I=1,p%NumOuts ) @@ -975,90 +861,123 @@ SUBROUTINE MDIO_OpenOutput( OutRootName, p, m, InitOut, ErrStat, ErrMsg ) END IF - ! calculate number of output entries (including time) to write for this line - LineNumOuts = 1 + 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 = '(A10,'//TRIM(Int2LStr(LineNumOuts))//'(A1,A10))' ! should evenutally use user specified format? - !Frmt = '(A10,'//TRIM(Int2LStr(3+3*m%LineList(I)%N))//'(A1,A10))' + ! calculate number of output entries (excluding time) to write for this line + LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:6)) & + + (m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(7:9)) & + + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(10:18)) + + if (wordy > 2) PRINT *, LineNumOuts, " output channels" + + Frmt = '(A10,'//TRIM(Int2LStr(1 + LineNumOuts))//'(A1,A15))' ! should evenutally use user specified format? + !Frmt = '(A10,'//TRIM(Int2LStr(3+3*m%LineList(I)%N))//'(A1,A15))' ! Write the names of the output parameters: (these use "implied DO" loops) WRITE(m%LineList(I)%LineUnOut,'(A10)', advance='no', IOSTAT=ErrStat2) TRIM( 'Time' ) IF (m%LineList(I)%OutFlagList(2) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'px', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'py', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'pz', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(3) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'vx', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'vy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'vz', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(4) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Ux', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Uy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Uz', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(5) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Dx', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Dy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Dz', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(6) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & - ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'Ten', J=1,(m%LineList(I)%N) ) + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'bx', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'by', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'bz', J=0,(m%LineList(I)%N) ) END IF + IF (m%LineList(I)%OutFlagList(7) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & - ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'Dmp', J=1,(m%LineList(I)%N) ) + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Wz', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(8) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Kurv', J=0,(m%LineList(I)%N) ) + END IF + + IF (m%LineList(I)%OutFlagList(10) == 1) THEN + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'Ten', J=1,(m%LineList(I)%N) ) + END IF + IF (m%LineList(I)%OutFlagList(11) == 1) THEN + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'Dmp', J=1,(m%LineList(I)%N) ) + END IF + IF (m%LineList(I)%OutFlagList(12) == 1) THEN + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'Str', J=1,(m%LineList(I)%N) ) END IF - IF (m%LineList(I)%OutFlagList(9) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & + IF (m%LineList(I)%OutFlagList(13) == 1) THEN + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'SRt', J=1,(m%LineList(I)%N) ) END IF - IF (m%LineList(I)%OutFlagList(10)== 1) THEN + IF (m%LineList(I)%OutFlagList(14)== 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'Lst', J=1,(m%LineList(I)%N) ) END IF WRITE(m%LineList(I)%LineUnOut,'(A1)', IOSTAT=ErrStat2) ' ' ! make line break at the end + ! Now write the units line WRITE(m%LineList(I)%LineUnOut,'(A10)', advance='no', IOSTAT=ErrStat2) TRIM( '(s)' ) IF (m%LineList(I)%OutFlagList(2) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, '(m)', p%Delim, '(m)', p%Delim, '(m)', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(3) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, '(m/s)', p%Delim, '(m/s)', p%Delim, '(m/s)', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(4) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, '(m/s)', p%Delim, '(m/s)', p%Delim, '(m/s)', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(5) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, '(N)', p%Delim, '(N)', p%Delim, '(N)', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(6) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & - ( p%Delim, '(N)', J=1,(m%LineList(I)%N) ) + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((3+3*m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(N)', p%Delim, '(N)', p%Delim, '(N)', J=0,(m%LineList(I)%N) ) END IF + IF (m%LineList(I)%OutFlagList(7) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & - ( p%Delim, '(N)', J=1,(m%LineList(I)%N) ) + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(Nup)', J=0,(m%LineList(I)%N) ) END IF IF (m%LineList(I)%OutFlagList(8) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(1/m)', J=0,(m%LineList(I)%N) ) + END IF + + IF (m%LineList(I)%OutFlagList(10) == 1) THEN + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(N)', J=1,(m%LineList(I)%N) ) + END IF + IF (m%LineList(I)%OutFlagList(11) == 1) THEN + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(N)', J=1,(m%LineList(I)%N) ) + END IF + IF (m%LineList(I)%OutFlagList(12) == 1) THEN + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, '(-)', J=1,(m%LineList(I)%N) ) END IF - IF (m%LineList(I)%OutFlagList(9) == 1) THEN - WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & + IF (m%LineList(I)%OutFlagList(13) == 1) THEN + WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, '(1/s)', J=1,(m%LineList(I)%N) ) END IF - IF (m%LineList(I)%OutFlagList(10)== 1) THEN + IF (m%LineList(I)%OutFlagList(14)== 1) THEN WRITE(m%LineList(I)%LineUnOut,'('//TRIM(Int2LStr((m%LineList(I)%N)))//'(A1,A10))', advance='no', IOSTAT=ErrStat2) & ( p%Delim, '(m)', J=1,(m%LineList(I)%N) ) END IF @@ -1070,13 +989,185 @@ SUBROUTINE MDIO_OpenOutput( OutRootName, p, m, InitOut, ErrStat, ErrMsg ) END DO ! I - line number + + + !-------------------------------------------------------------------------- + ! now do the same for rod output files + !-------------------------------------------------------------------------- + + !! allocate UnLineOuts + !ALLOCATE(UnLineOuts(p%NLines)) ! should add error checking + + DO I = 1,p%NRods + + + IF (m%RodList(I)%OutFlagList(1) == 1) THEN ! only proceed if the Rod is flagged to output a file + + ! Open the file for output + OutFileName = TRIM(p%RootName)//'.Rod'//TRIM(Int2LStr(I))//'.out' + CALL GetNewUnit( m%RodList(I)%RodUnOut ) + + CALL OpenFOutFile ( m%RodList(I)%RodUnOut, OutFileName, ErrStat, ErrMsg ) + IF ( ErrStat > ErrID_None ) THEN + ErrMsg = ' Error opening Rod output file '//TRIM(ErrMsg) + ErrStat = ErrID_Fatal + RETURN + END IF + + + ! calculate number of output entries (excluding time) to write for this Rod + RodNumOuts = 3*(m%RodList(I)%N + 1)*SUM(m%RodList(I)%OutFlagList(2:9)) & + + (m%RodList(I)%N + 1)*SUM(m%RodList(I)%OutFlagList(10:11)) & + + m%RodList(I)%N*SUM(m%RodList(I)%OutFlagList(12:18)) + + if (wordy > 2) PRINT *, RodNumOuts, " output channels" + + Frmt = '(A10,'//TRIM(Int2LStr(1 + RodNumOuts))//'(A1,A15))' ! should evenutally use user specified format? + !Frmt = '(A10,'//TRIM(Int2LStr(3+3*m%RodList(I)%N))//'(A1,A15))' + + ! >>> should functionalize the below <<< + + + ! Write the names of the output parameters: (these use "implied DO" loops) + + WRITE(m%RodList(I)%RodUnOut,'(A10)', advance='no', IOSTAT=ErrStat2) TRIM( 'Time' ) + IF (m%RodList(I)%OutFlagList(2) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'px', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'py', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'pz', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(3) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'vx', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'vy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'vz', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(4) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Ux', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Uy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Uz', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(5) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Box', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Boy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Boz', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(6) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Dx', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Dy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Dz', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(7) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Fix', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Fiy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Fiz', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(8) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Pdx', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Pdy', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Pdz', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(9) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'bx', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'by', p%Delim, 'Node'//TRIM(Int2Lstr(J))//'bz', J=0,(m%RodList(I)%N) ) + END IF + + IF (m%RodList(I)%OutFlagList(10) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Wz', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(11) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Node'//TRIM(Int2Lstr(J))//'Kurv', J=0,(m%RodList(I)%N) ) + END IF + + IF (m%RodList(I)%OutFlagList(12) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'Ten', J=1,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(13) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'Dmp', J=1,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(14) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'Str', J=1,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(15) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, 'Seg'//TRIM(Int2Lstr(J))//'SRt', J=1,(m%RodList(I)%N) ) + END IF + + WRITE(m%RodList(I)%RodUnOut,'(A1)', IOSTAT=ErrStat2) ' ' ! make line break at the end + + + ! Now write the units line + + WRITE(m%RodList(I)%RodUnOut,'(A10)', advance='no', IOSTAT=ErrStat2) TRIM( '(s)' ) + IF (m%RodList(I)%OutFlagList(2) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(m)', p%Delim, '(m)', p%Delim, '(m)', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(3) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(m/s)', p%Delim, '(m/s)', p%Delim, '(m/s)', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(4) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(m/s)', p%Delim, '(m/s)', p%Delim, '(m/s)', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(5) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(N)', p%Delim, '(N)', p%Delim, '(N)', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(6) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(N)', p%Delim, '(N)', p%Delim, '(N)', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(7) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(N)', p%Delim, '(N)', p%Delim, '(N)', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(8) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(N)', p%Delim, '(N)', p%Delim, '(N)', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(9) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((3+3*m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(N)', p%Delim, '(N)', p%Delim, '(N)', J=0,(m%RodList(I)%N) ) + END IF + + IF (m%RodList(I)%OutFlagList(10) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(Nup)', J=0,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(11) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(1/m)', J=0,(m%RodList(I)%N) ) + END IF + + IF (m%RodList(I)%OutFlagList(12) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(N)', J=1,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(13) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(N)', J=1,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(14) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(-)', J=1,(m%RodList(I)%N) ) + END IF + IF (m%RodList(I)%OutFlagList(15) == 1) THEN + WRITE(m%RodList(I)%RodUnOut,'('//TRIM(Int2LStr((m%RodList(I)%N)))//'(A1,A15))', advance='no', IOSTAT=ErrStat2) & + ( p%Delim, '(1/s)', J=1,(m%RodList(I)%N) ) + END IF + + WRITE(m%RodList(I)%RodUnOut,'(A1)', IOSTAT=ErrStat2) ' ' ! make Rod break at the end + + END IF ! if rod is flagged for output file + + END DO ! I - rod number + ! need to fix error handling in this sub END SUBROUTINE MDIO_OpenOutput - !==================================================================================================== + !----------------------------------------------------------------------------------------============ - !==================================================================================================== + !----------------------------------------------------------------------------------------============ SUBROUTINE MDIO_CloseOutput ( p, m, ErrStat, ErrMsg ) ! This function cleans up after running the MoorDyn output module. ! It closes the output files and releases memory. @@ -1093,26 +1184,41 @@ SUBROUTINE MDIO_CloseOutput ( p, m, ErrStat, ErrMsg ) ErrMsg = "" +!FIXME: make sure thes are actually open before trying to close them. Segfault will occur otherwise!!!! +! This bug can be triggered by an early failure of the parsing routines, before these files were ever opened +! which returns MD to OpenFAST as ErrID_Fatal, then OpenFAST calls MD_End, which calls this. + ! close main MoorDyn output file if (p%MDUnOut > 0) then CLOSE( p%MDUnOut, IOSTAT = ErrStat ) - IF ( ErrStat /= 0 ) THEN - ErrMsg = 'Error closing output file' - END IF - endif - + IF ( ErrStat /= 0 ) THEN + ErrMsg = 'Error closing output file' + END IF + end if + + ! close individual rod output files + DO I=1,p%NRods + if (allocated(m%RodList)) then + if (m%RodList(I)%RodUnOut > 0) then + CLOSE( m%RodList(I)%RodUnOut, IOSTAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrMsg = 'Error closing rod output file' + END IF + end if + end if + END DO + ! close individual line output files - if (allocated(m%LineList)) then - DO I=1,p%NLines + DO I=1,p%NLines + if (allocated(m%LineList)) then if (m%LineList(I)%LineUnOut > 0) then CLOSE( m%LineList(I)%LineUnOut, IOSTAT = ErrStat ) - IF ( ErrStat /= 0 ) THEN - ErrMsg = 'Error closing line output file' - exit ! exit this loop - END IF - endif - END DO - endif + IF ( ErrStat /= 0 ) THEN + ErrMsg = 'Error closing line output file' + END IF + end if + end if + END DO ! deallocate output arrays IF (ALLOCATED(m%MDWrOutput)) THEN @@ -1125,10 +1231,10 @@ SUBROUTINE MDIO_CloseOutput ( p, m, ErrStat, ErrMsg ) END DO END SUBROUTINE MDIO_CloseOutput - !==================================================================================================== + !----------------------------------------------------------------------------------------============ - !==================================================================================================== + !----------------------------------------------------------------------------------------============ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) ! This subroutine gathers the output data defined by the OutParams list and ! writes it to the output file opened in MDIO_OutInit() @@ -1145,6 +1251,7 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) INTEGER :: K ! Generic loop counter INTEGER :: L ! counter for index in LineWrOutput INTEGER :: LineNumOuts ! number of entries in LineWrOutput for each line + INTEGER :: RodNumOuts ! same for Rods CHARACTER(200) :: Frmt ! a string to hold a format statement @@ -1156,80 +1263,177 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) ErrStat = ErrID_None ErrMsg = '' END IF + + ! -------------------------------- main output file -------------------------------- + + if ( p%NumOuts > 0_IntKi ) then + + ! gather the required output quantities (INCOMPLETE!) + DO I = 1,p%NumOuts + + + IF (p%OutParam(I)%OType == 1) THEN ! if dealing with a Line output + + SELECT CASE (p%OutParam(I)%QType) + CASE (PosX) + y%WriteOutput(I) = m%LineList(p%OutParam(I)%ObjID)%r(1,p%OutParam(I)%NodeID) ! x position + CASE (PosY) + y%WriteOutput(I) = m%LineList(p%OutParam(I)%ObjID)%r(2,p%OutParam(I)%NodeID) ! y position + CASE (PosZ) + y%WriteOutput(I) = m%LineList(p%OutParam(I)%ObjID)%r(3,p%OutParam(I)%NodeID) ! z position + CASE (VelX) + y%WriteOutput(I) = m%LineList(p%OutParam(I)%ObjID)%rd(1,p%OutParam(I)%NodeID) ! x velocity + CASE (VelY) + y%WriteOutput(I) = m%LineList(p%OutParam(I)%ObjID)%rd(2,p%OutParam(I)%NodeID) ! y velocity + CASE (VelZ) + y%WriteOutput(I) = m%LineList(p%OutParam(I)%ObjID)%rd(3,p%OutParam(I)%NodeID) ! z velocity + CASE (Ten) + y%WriteOutput(I) = Line_GetNodeTen(m%LineList(p%OutParam(I)%ObjID), p%OutParam(I)%NodeID, p) ! this is actually the segment tension ( 1 < NodeID < N ) Should deal with properly! + + CASE DEFAULT + y%WriteOutput(I) = 0.0_ReKi + ErrStat = ErrID_Warn + ErrMsg = ' Unsupported output quantity '//TRIM(p%OutParam(I)%Name)//' requested from Line '//TRIM(Num2Lstr(p%OutParam(I)%ObjID))//'.' + END SELECT + + ELSE IF (p%OutParam(I)%OType == 2) THEN ! if dealing with a Connect output + SELECT CASE (p%OutParam(I)%QType) + CASE (PosX) + y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%r(1) ! x position + CASE (PosY) + y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%r(2) ! y position + CASE (PosZ) + y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%r(3) ! z position + CASE (VelX) + y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%rd(1) ! x velocity + CASE (VelY) + y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%rd(2) ! y velocity + CASE (VelZ) + y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%rd(3) ! z velocity + CASE (AccX) + y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%a(1) ! x acceleration + CASE (AccY) + y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%a(2) ! y acceleration + CASE (AccZ) + y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%a(3) ! z acceleration + CASE (Ten) + y%WriteOutput(I) = TwoNorm(m%ConnectList(p%OutParam(I)%ObjID)%Fnet) ! total force magnitude on a connect (used eg. for fairlead and anchor tensions) + CASE (FX) + y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%Fnet(1) ! total force in x - added Nov 24 + CASE (FY) + y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%Fnet(2) ! total force in y + CASE (FZ) + y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%Fnet(3) ! total force in z + CASE DEFAULT + y%WriteOutput(I) = 0.0_ReKi + ErrStat = ErrID_Warn + ErrMsg = ' Unsupported output quantity '//TRIM(p%OutParam(I)%Name)//' requested from Connection '//TRIM(Num2Lstr(p%OutParam(I)%ObjID))//'.' + END SELECT + + ELSE IF (p%OutParam(I)%OType == 3) THEN ! if dealing with a Rod output + + SELECT CASE (p%OutParam(I)%QType) + CASE (PosX) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%r(1,p%OutParam(I)%NodeID) ! x position + CASE (PosY) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%r(2,p%OutParam(I)%NodeID) ! y position + CASE (PosZ) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%r(3,p%OutParam(I)%NodeID) ! z position + CASE (VelX) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%rd(1,p%OutParam(I)%NodeID) ! x velocity + CASE (VelY) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%rd(2,p%OutParam(I)%NodeID) ! y velocity + CASE (VelZ) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%rd(3,p%OutParam(I)%NodeID) ! z velocity + CASE (AccX) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%a6(1) ! x acceleration <<< should this become distributed for each node? + CASE (AccY) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%a6(2) ! y acceleration + CASE (AccZ) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%a6(3) ! z acceleration + CASE (FX) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%F6net(1) ! total force in x - added Nov 24 + CASE (FY) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%F6net(2) ! total force in y + CASE (FZ) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%F6net(3) ! total force in z + CASE (Roll) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%roll*180.0/pi ! rod roll + CASE (Pitch) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%pitch*180.0/pi ! rod pitch + CASE (Sub) + y%WriteOutput(I) = m%RodList(p%OutParam(I)%ObjID)%h0 / m%RodList(p%OutParam(I)%ObjID)%UnstrLen ! rod submergence + CASE DEFAULT + y%WriteOutput(I) = 0.0_ReKi + ErrStat = ErrID_Warn + ErrMsg = ' Unsupported output quantity '//TRIM(p%OutParam(I)%Name)//' requested from Rod '//TRIM(Num2Lstr(p%OutParam(I)%ObjID))//'.' + END SELECT + + ELSE IF (p%OutParam(I)%OType == 4) THEN ! if dealing with a Body output + SELECT CASE (p%OutParam(I)%QType) + CASE (PosX) + y%WriteOutput(I) = m%BodyList(p%OutParam(I)%ObjID)%r6(1) ! x position + CASE (PosY) + y%WriteOutput(I) = m%BodyList(p%OutParam(I)%ObjID)%r6(2) ! y position + CASE (PosZ) + y%WriteOutput(I) = m%BodyList(p%OutParam(I)%ObjID)%r6(3) ! z position + CASE (VelX) + y%WriteOutput(I) = m%BodyList(p%OutParam(I)%ObjID)%v6(1) ! x velocity + CASE (VelY) + y%WriteOutput(I) = m%BodyList(p%OutParam(I)%ObjID)%v6(2) ! y velocity + CASE (VelZ) + y%WriteOutput(I) = m%BodyList(p%OutParam(I)%ObjID)%v6(3) ! z velocity + CASE (FX) + y%WriteOutput(I) = m%BodyList(p%OutParam(I)%ObjID)%F6net(1) ! total force in x - added Nov 24 + CASE (FY) + y%WriteOutput(I) = m%BodyList(p%OutParam(I)%ObjID)%F6net(2) ! total force in y + CASE (FZ) + y%WriteOutput(I) = m%BodyList(p%OutParam(I)%ObjID)%F6net(3) ! total force in z + CASE (Roll) + y%WriteOutput(I) = m%BodyList(p%OutParam(I)%ObjID)%r6(4)*180.0/pi ! roll + CASE (Pitch) + y%WriteOutput(I) = m%BodyList(p%OutParam(I)%ObjID)%r6(5)*180.0/pi ! pitch + CASE (Yaw) + y%WriteOutput(I) = m%BodyList(p%OutParam(I)%ObjID)%r6(6)*180.0/pi ! yaw + CASE DEFAULT + y%WriteOutput(I) = 0.0_ReKi + ErrStat = ErrID_Warn + ErrMsg = ' Unsupported output quantity '//TRIM(p%OutParam(I)%Name)//' requested from Body '//TRIM(Num2Lstr(p%OutParam(I)%ObjID))//'.' + END SELECT + + + ELSE ! it must be an invalid output, so write zero + y%WriteOutput(I) = 0.0_ReKi - ! Return if there are no outputs - if ( p%NumOuts < 1_IntKi ) return - - - ! gather the required output quantities (INCOMPLETE!) - DO I = 1,p%NumOuts - - IF (p%OutParam(I)%OType == 2) THEN ! if dealing with a Connect output - SELECT CASE (p%OutParam(I)%QType) - CASE (PosX) - y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%r(1) ! x position - CASE (PosY) - y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%r(2) ! y position - CASE (PosZ) - y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%r(3) ! z position - CASE (VelX) - y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%rd(1) ! x velocity - CASE (VelY) - y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%rd(2) ! y velocity - CASE (VelZ) - y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%rd(3) ! z velocity - CASE (Ten) - y%WriteOutput(I) = TwoNorm(m%ConnectList(p%OutParam(I)%ObjID)%Ftot) ! total force magnitude on a connect (used eg. for fairlead and anchor tensions) - CASE (FX) - y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%Ftot(1) ! total force in x - added Nov 24 - CASE (FY) - y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%Ftot(2) ! total force in y - CASE (FZ) - y%WriteOutput(I) = m%ConnectList(p%OutParam(I)%ObjID)%Ftot(3) ! total force in z - CASE DEFAULT - 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 - - ELSE IF (p%OutParam(I)%OType == 1) THEN ! if dealing with a Line output - - SELECT CASE (p%OutParam(I)%QType) - CASE (PosX) - y%WriteOutput(I) = m%LineList(p%OutParam(I)%ObjID)%r(1,p%OutParam(I)%NodeID) ! x position - CASE (PosY) - y%WriteOutput(I) = m%LineList(p%OutParam(I)%ObjID)%r(2,p%OutParam(I)%NodeID) ! y position - CASE (PosZ) - y%WriteOutput(I) = m%LineList(p%OutParam(I)%ObjID)%r(3,p%OutParam(I)%NodeID) ! z position - CASE (VelX) - y%WriteOutput(I) = m%LineList(p%OutParam(I)%ObjID)%rd(1,p%OutParam(I)%NodeID) ! x velocity - CASE (VelY) - y%WriteOutput(I) = m%LineList(p%OutParam(I)%ObjID)%rd(2,p%OutParam(I)%NodeID) ! y velocity - CASE (VelZ) - y%WriteOutput(I) = m%LineList(p%OutParam(I)%ObjID)%rd(3,p%OutParam(I)%NodeID) ! z velocity - 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_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_DbKi - - END IF - - END DO ! I, loop through OutParam - - - ! Write the output parameters to the file - - Frmt = '(F10.4,'//TRIM(Int2LStr(p%NumOuts))//'(A1,e12.6))' ! should evenutally use user specified format? + END IF - WRITE(p%MDUnOut,Frmt) Time, ( p%Delim, y%WriteOutput(I), I=1,p%NumOuts ) + END DO ! I, loop through OutParam + END IF + ! check if this is a repeated time step, in which case exit instead of writing a duplicate line to the output files + if (Time <= m%LastOutTime) then + return + else + m%LastOutTime = Time + end if + + ! if using a certain output time step, check whether we should output, and exit the subroutine if not + if (p%dtOut > 0) then + !if (Time < (floor((Time-p%dtCoupling)/p%dtOut) + 1.0)*p%dtOut) then + if ( abs(MOD( Time - 0.5*p%dtOut, p%dtOut) - 0.5*p%dtOut) >= 0.5*p%dtCoupling) then + return + end if + end if + ! What the above does is say if ((dtOut==0) || (t >= (floor((t-dtC)/dtOut) + 1.0)*dtOut)), continue to writing files + + if ( p%NumOuts > 0_IntKi ) then + + ! Write the output parameters to the file + Frmt = '(F10.4,'//TRIM(Int2LStr(p%NumOuts))//'(A1,ES15.7E2))' ! should evenutally use user specified format? + + WRITE(p%MDUnOut,Frmt) Time, ( p%Delim, y%WriteOutput(I), I=1,p%NumOuts ) + END IF @@ -1241,12 +1445,19 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) IF (m%LineList(I)%OutFlagList(1) == 1) THEN ! only proceed if the line is flagged to output a file ! calculate number of output entries to write for this line - 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)) + !LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:5)) + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(6:9)) + LineNumOuts = 3*(m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(2:6)) & + + (m%LineList(I)%N + 1)*SUM(m%LineList(I)%OutFlagList(7:9)) & + + m%LineList(I)%N*SUM(m%LineList(I)%OutFlagList(10:18)) - 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 + if (m%LineList(I)%OutFlagList(2) == 1) THEN ! if node positions are included, make them using a float format for higher precision + Frmt = '(F10.4,'//TRIM(Int2LStr(3*(m%LineList(I)%N + 1)))//'(A1,ES15.7E2),'//TRIM(Int2LStr(LineNumOuts - 3*(m%LineList(I)%N - 1)))//'(A1,ES15.7E2))' + else + Frmt = '(F10.4,'//TRIM(Int2LStr(LineNumOuts))//'(A1,ES15.7E2))' ! should evenutally use user specified format? + end if + + L = 1 ! start of index of line output file at first entry 12345.7890 ! Time ! m%LineList(I)%LineWrOutput(L) = Time @@ -1277,7 +1488,7 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) IF (m%LineList(I)%OutFlagList(4) == 1) THEN DO J = 0,m%LineList(I)%N ! note index starts at zero because these are nodes DO K = 1,3 - m%LineList(I)%LineWrOutput(L) = 0.0 + m%LineList(I)%LineWrOutput(L) = m%LineList(I)%U(K,J) L = L+1 END DO END DO @@ -1295,8 +1506,36 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) END IF - ! Segment tension force (excludes damping term, just EA) + ! Node seabed contact force IF (m%LineList(I)%OutFlagList(6) == 1) THEN + DO J = 0,m%LineList(I)%N + DO K = 1,3 + m%LineList(I)%LineWrOutput(L) = m%LineList(I)%B(K,J) + L = L+1 + END DO + END DO + END IF + + + ! Node weights + IF (m%LineList(I)%OutFlagList(7) == 1) THEN + DO J = 0,m%LineList(I)%N + m%LineList(I)%LineWrOutput(L) = m%LineList(I)%W(3,J) + L = L+1 + END DO + END IF + + ! ! Node curvatures + ! IF (m%LineList(I)%OutFlagList(8) == 1) THEN + ! DO J = 0,m%LineList(I)%N + ! m%LineList(I)%LineWrOutput(L) = m%LineList(I)%W(3,J) + ! L = L+1 + ! END DO + ! END IF + + + ! Segment tension force (excludes damping term, just EA) + IF (m%LineList(I)%OutFlagList(10) == 1) THEN DO J = 1,m%LineList(I)%N m%LineList(I)%LineWrOutput(L) = TwoNorm(m%LineList(I)%T(:,J) ) L = L+1 @@ -1304,7 +1543,7 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) END IF ! Segment internal damping force - IF (m%LineList(I)%OutFlagList(7) == 1) THEN + IF (m%LineList(I)%OutFlagList(11) == 1) THEN DO J = 1,m%LineList(I)%N IF (( m%LineList(I)%Td(3,J)*m%LineList(I)%T(3,J) ) > 0) THEN ! if statement for handling sign (positive = tension) m%LineList(I)%LineWrOutput(L) = TwoNorm(m%LineList(I)%Td(:,J) ) @@ -1316,7 +1555,7 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) END IF ! Segment strain - IF (m%LineList(I)%OutFlagList(8) == 1) THEN + IF (m%LineList(I)%OutFlagList(12) == 1) THEN DO J = 1,m%LineList(I)%N m%LineList(I)%LineWrOutput(L) = m%LineList(I)%lstr(J)/m%LineList(I)%l(J) - 1.0 L = L+1 @@ -1324,7 +1563,7 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) END IF ! Segment strain rate - IF (m%LineList(I)%OutFlagList(9) == 1) THEN + IF (m%LineList(I)%OutFlagList(13) == 1) THEN DO J = 1,m%LineList(I)%N m%LineList(I)%LineWrOutput(L) = m%LineList(I)%lstrd(J)/m%LineList(I)%l(J) L = L+1 @@ -1332,13 +1571,14 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) END IF ! Segment length - IF (m%LineList(I)%OutFlagList(10) == 1) THEN + IF (m%LineList(I)%OutFlagList(14) == 1) THEN DO J = 1,m%LineList(I)%N m%LineList(I)%LineWrOutput(L) = m%LineList(I)%lstr(J) L = L+1 END DO END IF + WRITE(m%LineList(I)%LineUnOut,Frmt) Time, ( p%Delim, m%LineList(I)%LineWrOutput(J), J=1,(LineNumOuts) ) !WRITE(m%LineList(I)%LineUnOut,Frmt) Time, ( p%Delim, m%LineList(I)%LineWrOutput(J), J=1,(3+3*m%LineList(I)%N) ) @@ -1346,9 +1586,178 @@ SUBROUTINE MDIO_WriteOutputs( Time, p, m, y, ErrStat, ErrMsg ) END IF ! if line output file flag is on END DO ! I + + + + !------------------------------------------------------------------------ + ! now do the outputs for each Rod! + + DO I=1,p%NRods + + IF (m%RodList(I)%OutFlagList(1) == 1) THEN ! only proceed if the line is flagged to output a file + + ! calculate number of output entries to write for this Rod + RodNumOuts = 3*(m%RodList(I)%N + 1)*SUM(m%RodList(I)%OutFlagList(2:9)) & + + (m%RodList(I)%N + 1)*SUM(m%RodList(I)%OutFlagList(10:11)) & + + m%RodList(I)%N*SUM(m%RodList(I)%OutFlagList(12:18)) + + + Frmt = '(F10.4,'//TRIM(Int2LStr(RodNumOuts))//'(A1,ES15.7E2))' ! should evenutally use user specified format? + + L = 1 ! start of index of line output file at first entry + + ! Time + ! m%RodList(I)%RodWrOutput(L) = Time + ! L = L+1 + + ! Node positions + IF (m%RodList(I)%OutFlagList(2) == 1) THEN + DO J = 0,m%RodList(I)%N ! note index starts at zero because these are nodes + DO K = 1,3 + m%RodList(I)%RodWrOutput(L) = m%RodList(I)%r(K,J) + L = L+1 + END DO + END DO + END IF + + ! Node velocities + IF (m%RodList(I)%OutFlagList(3) == 1) THEN + DO J = 0,m%RodList(I)%N ! note index starts at zero because these are nodes + DO K = 1,3 + m%RodList(I)%RodWrOutput(L) = m%RodList(I)%rd(K,J) + L = L+1 + END DO + END DO + END IF + + + ! Node wave velocities (not implemented yet) + IF (m%RodList(I)%OutFlagList(4) == 1) THEN + DO J = 0,m%RodList(I)%N ! note index starts at zero because these are nodes + DO K = 1,3 + m%RodList(I)%RodWrOutput(L) = m%RodList(I)%U(K,J) + L = L+1 + END DO + END DO + END IF + + ! Node buoyancy forces + IF (m%RodList(I)%OutFlagList(5) == 1) THEN + DO J = 0,m%RodList(I)%N ! note index starts at zero because these are nodes + DO K = 1,3 + m%RodList(I)%RodWrOutput(L) = m%RodList(I)%Bo(K,J) + L = L+1 + END DO + END DO + END IF + + ! Node drag forces + IF (m%RodList(I)%OutFlagList(6) == 1) THEN + DO J = 0,m%RodList(I)%N ! note index starts at zero because these are nodes + DO K = 1,3 + m%RodList(I)%RodWrOutput(L) = m%RodList(I)%Dp(K,J) + m%RodList(I)%Dq(K,J) + L = L+1 + END DO + END DO + END IF + + ! Node inertia forces + IF (m%RodList(I)%OutFlagList(7) == 1) THEN + DO J = 0,m%RodList(I)%N ! note index starts at zero because these are nodes + DO K = 1,3 + m%RodList(I)%RodWrOutput(L) = m%RodList(I)%Ap(K,J) + m%RodList(I)%Aq(K,J) + L = L+1 + END DO + END DO + END IF + + ! Node dynamic pressure forces + IF (m%RodList(I)%OutFlagList(8) == 1) THEN + DO J = 0,m%RodList(I)%N ! note index starts at zero because these are nodes + DO K = 1,3 + m%RodList(I)%RodWrOutput(L) = m%RodList(I)%Pd(K,J) + L = L+1 + END DO + END DO + END IF + + ! Node seabed contact force + IF (m%RodList(I)%OutFlagList(9) == 1) THEN + DO J = 0,m%RodList(I)%N + DO K = 1,3 + m%RodList(I)%RodWrOutput(L) = m%RodList(I)%B(K,J) + L = L+1 + END DO + END DO + END IF + + + ! Node weights + IF (m%RodList(I)%OutFlagList(10) == 1) THEN + DO J = 0,m%RodList(I)%N + m%RodList(I)%RodWrOutput(L) = m%RodList(I)%W(3,J) + L = L+1 + END DO + END IF + + ! ! Node curvatures + ! IF (m%RodList(I)%OutFlagList(8) == 1) THEN + ! DO J = 0,m%RodList(I)%N + ! m%RodList(I)%RodWrOutput(L) = m%RodList(I)%W(3,J) + ! L = L+1 + ! END DO + ! END IF + + + ! Segment tension force (excludes damping term, just EA) + ! N/A + + ! Segment internal damping force + ! N/A + + ! Segment strain + ! N/A + + ! Segment strain rate + ! N/A + + + WRITE(m%RodList(I)%RodUnOut,Frmt) Time, ( p%Delim, m%RodList(I)%RodWrOutput(J), J=1,(RodNumOuts) ) + + END IF ! if line output file flag is on + + END DO ! I END SUBROUTINE MDIO_WriteOutputs - !==================================================================================================== + !----------------------------------------------------------------------------------------============ + + + ! get tension at any node including fairlead or anchor (accounting for weight in these latter cases) + !-------------------------------------------------------------- + FUNCTION Line_GetNodeTen(Line, i, p) result(NodeTen) + + TYPE(MD_Line), INTENT(IN ) :: Line ! label for the current line, for convenience + INTEGER(IntKi), INTENT(IN ) :: i ! node index to get tension at + TYPE(MD_ParameterType), INTENT(IN ) :: p ! Parameters + REAL(DbKi) :: NodeTen ! returned calculation of tension at node + + INTEGER(IntKi) :: J + REAL(DbKi) :: Tmag_squared + + if (i==0) then + NodeTen = sqrt( Line%Fnet(1,i)**2 + Line%Fnet(2,i)**2 + Line%Fnet(3,i)**2 ) ! if an end node, use Fnet which already includes weight + else if (i==Line%N) then + NodeTen = sqrt( Line%Fnet(1,i)**2 + Line%Fnet(2,i)**2 + Line%Fnet(3,i)**2 ) + else + Tmag_squared = 0.0_DbKi + DO J=1,3 + Tmag_squared = Tmag_squared + 0.25*(Line%T(J,i) + Line%Td(J,i) + Line%T(J,i+1) + Line%Td(J,i+1))**2 ! take average of tension in adjacent segments + END DO + NodeTen = sqrt(Tmag_squared) + end if + + END FUNCTION Line_GetNodeTen + !-------------------------------------------------------------- END MODULE MoorDyn_IO diff --git a/modules/moordyn/src/MoorDyn_Line.f90 b/modules/moordyn/src/MoorDyn_Line.f90 new file mode 100644 index 000000000..1d6b21642 --- /dev/null +++ b/modules/moordyn/src/MoorDyn_Line.f90 @@ -0,0 +1,1635 @@ +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2020-2021 Alliance for Sustainable Energy, LLC +! Copyright (C) 2015-2019 Matthew Hall +! +! This file is part of MoorDyn. +! +! 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 MoorDyn_Line + + USE MoorDyn_Types + USE MoorDyn_IO + USE NWTC_Library + USE MoorDyn_Misc + + IMPLICIT NONE + + PRIVATE + + INTEGER(IntKi), PARAMETER :: wordy = 0 ! verbosity level. >1 = more console output + + PUBLIC :: SetupLine + PUBLIC :: Line_Initialize + PUBLIC :: Line_SetState + PUBLIC :: Line_GetStateDeriv + PUBLIC :: Line_SetEndKinematics + PUBLIC :: Line_GetEndStuff + PUBLIC :: Line_GetEndSegmentInfo + PUBLIC :: Line_SetEndOrientation + + + +CONTAINS + + + !----------------------------------------------------------------------- + ! >>>>>>>>>>>>>> rename/reorganize this subroutine >>>>>>>>>>>>> + SUBROUTINE SetupLine (Line, LineProp, p, ErrStat, ErrMsg) + ! allocate arrays in line object + + TYPE(MD_Line), INTENT(INOUT) :: Line ! the single line object of interest + TYPE(MD_LineProp), INTENT(INOUT) :: LineProp ! the single line property set for the line of interest + TYPE(MD_ParameterType), INTENT(IN ) :: p ! Parameters + INTEGER, INTENT( INOUT ) :: ErrStat ! returns a non-zero value when an error occurs + CHARACTER(*), INTENT( INOUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + INTEGER(4) :: I, J, K ! Generic index + INTEGER(IntKi) :: N + REAL(DbKi) :: temp + + + N = Line%N ! number of segments in this line (for code readability) + + ! -------------- save some section properties to the line object itself ----------------- + + Line%d = LineProp%d + Line%rho = LineProp%w/(Pi/4.0 * Line%d * Line%d) + + Line%EA = LineProp%EA + ! note: Line%BA is set later + Line%EA_D = LineProp%EA_D + Line%BA_D = LineProp%BA_D + Line%EI = LineProp%EI !<<< for bending stiffness + + Line%Can = LineProp%Can + Line%Cat = LineProp%Cat + Line%Cdn = LineProp%Cdn + Line%Cdt = LineProp%Cdt + + ! copy over elasticity data + Line%ElasticMod = LineProp%ElasticMod + + Line%nEApoints = LineProp%nEApoints + DO I = 1,Line%nEApoints + Line%stiffXs(I) = LineProp%stiffXs(I) + Line%stiffYs(I) = LineProp%stiffYs(I) ! note: this does not convert to E (not EA) like done in C version + END DO + + Line%nBApoints = LineProp%nBApoints + DO I = 1,Line%nBApoints + Line%dampXs(I) = LineProp%dampXs(I) + Line%dampYs(I) = LineProp%dampYs(I) + END DO + + Line%nEIpoints = LineProp%nEIpoints + DO I = 1,Line%nEIpoints + Line%bstiffXs(I) = LineProp%bstiffXs(I) + Line%bstiffYs(I) = LineProp%bstiffYs(I) ! copy over + END DO + + + + ! Specify specific internal damping coefficient (BA) for this line. + ! Will be equal to inputted BA of LineType if input value is positive. + ! If input value is negative, it is considered to be desired damping ratio (zeta) + ! from which the line's BA can be calculated based on the segment natural frequency. + IF (LineProp%BA < 0) THEN + ! - we assume desired damping coefficient is zeta = -LineProp%BA + ! - highest axial vibration mode of a segment is wn = sqrt(k/m) = 2N/UnstrLen*sqrt(EA/w) + Line%BA = -LineProp%BA * Line%UnstrLen / Line%N * SQRT(LineProp%EA * LineProp%w) + IF (wordy > 1) print *, 'Based on zeta, BA set to ', Line%BA + + IF (wordy > 1) print *, 'Negative BA input detected, treating as -zeta. For zeta = ', -LineProp%BA, ', setting BA to ', Line%BA + + ELSE + Line%BA = LineProp%BA + IF (wordy > 1) temp = Line%N * Line%BA / Line%UnstrLen * SQRT(1.0/(LineProp%EA * LineProp%w)) + IF (wordy > 1) print *, 'BA set as input to ', Line%BA, '. Corresponding zeta is ', temp + END IF + + !temp = 2*Line%N / Line%UnstrLen * sqrt( LineProp%EA / LineProp%w) / TwoPi + !print *, 'Segment natural frequency is ', temp, ' Hz' + + + !print *, "Line ElasticMod is ", Line%ElasticMod + !print *, "EA (static value) is", Line%EA + !print *, "EA_D is", Line%EA_D + !print *, "BA is", Line%BA + !print *, "BA_D is", Line%BA_D + + + ! allocate node positions and velocities (NOTE: these arrays start at ZERO) + ALLOCATE ( Line%r(3, 0:N), Line%rd(3, 0:N), STAT = ErrStat ) + IF ( ErrStat /= ErrID_None ) THEN + ErrMsg = ' Error allocating r and rd arrays.' + !CALL CleanUp() + RETURN + END IF + + ! if using viscoelastic model, allocate additional state quantities + if (Line%ElasticMod == 2) then + ALLOCATE ( Line%dl_1(N), STAT = ErrStat ) + IF ( ErrStat /= ErrID_None ) THEN + ErrMsg = ' Error allocating dl_1 array.' + !CALL CleanUp() + RETURN + END IF + ! initialize to zero + Line%dl_1 = 0.0_DbKi + end if + + ! allocate node and segment tangent vectors + ALLOCATE ( Line%q(3, 0:N), Line%qs(3, N), STAT = ErrStat ) + IF ( ErrStat /= ErrID_None ) THEN + ErrMsg = ' Error allocating q or qs array.' + !CALL CleanUp() + RETURN + END IF + + ! allocate segment scalar quantities + ALLOCATE ( Line%l(N), Line%ld(N), Line%lstr(N), Line%lstrd(N), Line%Kurv(0:N), Line%V(N), STAT = ErrStat ) + IF ( ErrStat /= ErrID_None ) THEN + ErrMsg = ' Error allocating segment scalar quantity arrays.' + !CALL CleanUp() + RETURN + END IF + Line%Kurv = 0.0_DbKi + + ! assign values for l, ld, and V + DO J=1,N + Line%l(J) = Line%UnstrLen/REAL(N, DbKi) + Line%ld(J)= 0.0_DbKi + Line%V(J) = Line%l(J)*0.25*Pi*LineProp%d*LineProp%d + END DO + + ! allocate water related vectors + ALLOCATE ( Line%U(3, 0:N), Line%Ud(3, 0:N), Line%zeta(0:N), Line%PDyn(0:N), STAT = ErrStat ) + ! set to zero initially (important of wave kinematics are not being used) + Line%U = 0.0_DbKi + Line%Ud = 0.0_DbKi + Line%zeta = 0.0_DbKi + Line%PDyn = 0.0_DbKi + + ! allocate segment tension and internal damping force vectors + ALLOCATE ( Line%T(3, N), Line%Td(3, N), STAT = ErrStat ) + IF ( ErrStat /= ErrID_None ) THEN + ErrMsg = ' Error allocating T and Td arrays.' + !CALL CleanUp() + RETURN + END IF + + ! allocate node force vectors + ALLOCATE ( Line%W(3, 0:N), Line%Dp(3, 0:N), Line%Dq(3, 0:N), Line%Ap(3, 0:N), & + Line%Aq(3, 0:N), Line%B(3, 0:N), Line%Bs(3, 0:N), Line%Fnet(3, 0:N), STAT = ErrStat ) + IF ( ErrStat /= ErrID_None ) THEN + ErrMsg = ' Error allocating node force arrays.' + !CALL CleanUp() + RETURN + END IF + + ! set gravity and bottom contact forces to zero initially (because the horizontal components should remain at zero) + Line%W = 0.0_DbKi + Line%B = 0.0_DbKi + + ! allocate mass and inverse mass matrices for each node (including ends) + ALLOCATE ( Line%S(3, 3, 0:N), Line%M(3, 3, 0:N), STAT = ErrStat ) + IF ( ErrStat /= ErrID_None ) THEN + ErrMsg = ' Error allocating T and Td arrays.' + !CALL CleanUp() + RETURN + END IF + + + if (p%writeLog > 1) then + write(p%UnLog, '(A)') " - Line"//trim(num2lstr(Line%IdNum)) + write(p%UnLog, '(A)') " ID: "//trim(num2lstr(Line%IdNum)) + write(p%UnLog, '(A)') " UnstrLen: "//trim(num2lstr(Line%UnstrLen)) + write(p%UnLog, '(A)') " N : "//trim(num2lstr(Line%N )) + write(p%UnLog, '(A)') " d : "//trim(num2lstr(Line%d )) + write(p%UnLog, '(A)') " rho : "//trim(num2lstr(Line%rho )) + write(p%UnLog, '(A)') " E : "//trim(num2lstr(Line%EA )) + write(p%UnLog, '(A)') " EI : "//trim(num2lstr(Line%EI )) + !write(p%UnLog, '(A)') " BAin: "//trim(num2lstr(Line%BAin)) + write(p%UnLog, '(A)') " Can : "//trim(num2lstr(Line%Can )) + write(p%UnLog, '(A)') " Cat : "//trim(num2lstr(Line%Cat )) + write(p%UnLog, '(A)') " Cdn : "//trim(num2lstr(Line%Cdn )) + write(p%UnLog, '(A)') " Cdt : "//trim(num2lstr(Line%Cdt )) + !write(p%UnLog, '(A)') " ww_l: " << ( (rho - env->rho_w)*(pi/4.*d*d) )*9.81 << endl; + end if + + + ! need to add cleanup sub <<< + + + END SUBROUTINE SetupLine + !-------------------------------------------------------------- + + + + + + !----------------------------------------------------------------------------------------======= + SUBROUTINE Line_Initialize (Line, LineProp, rhoW, ErrStat, ErrMsg) + ! calculate initial profile of the line using quasi-static model + + TYPE(MD_Line), INTENT(INOUT) :: Line ! the single line object of interest + TYPE(MD_LineProp), INTENT(INOUT) :: LineProp ! the single line property set for the line of interest + REAL(DbKi), INTENT(IN) :: rhoW + INTEGER, INTENT( INOUT ) :: ErrStat ! returns a non-zero value when an error occurs + CHARACTER(*), INTENT( INOUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + 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(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 + + + N = Line%N ! for convenience + + ! try to calculate initial line profile using catenary routine (from FAST v.7) + ! note: much of this function is adapted from the FAST source code + + ! Transform the fairlead location from the inertial frame coordinate system + ! to the local coordinate system of the current line (this coordinate + ! system lies at the current anchor, Z being vertical, and X directed from + ! current anchor to the current fairlead). Also, compute the orientation + ! of this local coordinate system: + + XF = SQRT( ( Line%r(1,N) - Line%r(1,0) )**2.0 + ( Line%r(2,N) - Line%r(2,0) )**2.0 ) + 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_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 + ENDIF + + WetWeight = LineProp%w - 0.25*Pi*LineProp%d*LineProp%d*rhoW + + !LineNodes = Line%N + 1 ! number of nodes in line for catenary model to worry about + + ! allocate temporary arrays for catenary routine + ALLOCATE ( LSNodes(N+1), STAT = ErrStat ) + IF ( ErrStat /= ErrID_None ) THEN + ErrMsg = ' Error allocating LSNodes array.' + CALL CleanUp() + RETURN + END IF + + ALLOCATE ( LNodesX(N+1), STAT = ErrStat ) + IF ( ErrStat /= ErrID_None ) THEN + ErrMsg = ' Error allocating LNodesX array.' + CALL CleanUp() + RETURN + END IF + + ALLOCATE ( LNodesZ(N+1), STAT = ErrStat ) + IF ( ErrStat /= ErrID_None ) THEN + ErrMsg = ' Error allocating LNodesZ array.' + CALL CleanUp() + RETURN + END IF + + ! Assign node arc length locations + 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 + LSNodes(N+1) = Line%UnstrLen ! ensure the last node length isn't longer than the line due to numerical error + + ! Solve the analytical, static equilibrium equations for a catenary (or + ! taut) mooring line with seabed interaction in order to find the + ! horizontal and vertical tensions at the fairlead in the local coordinate + ! system of the current line: + ! NOTE: The values for the horizontal and vertical tensions at the fairlead + ! from the previous time step are used as the initial guess values at + ! at this time step (because the LAnchHTe(:) and LAnchVTe(:) arrays + ! are stored in a module and thus their values are saved from CALL to + ! CALL). + + + CALL Catenary ( XF , ZF , Line%UnstrLen, LineProp%EA , & + WetWeight , SeabedCD, TenTol, (N+1) , & + LSNodes, LNodesX, LNodesZ , ErrStat2, ErrMsg2) + + IF (ErrStat2 == ErrID_None) THEN ! if it worked, use it + ! Transform the positions of each node on the current line from the local + ! coordinate system of the current line to the inertial frame coordinate + ! system: + + DO J = 0,N ! Loop through all nodes per line where the line position and tension can be output + Line%r(1,J) = Line%r(1,0) + LNodesX(J+1)*COSPhi + Line%r(2,J) = Line%r(2,0) + LNodesX(J+1)*SINPhi + Line%r(3,J) = Line%r(3,0) + LNodesZ(J+1) + ENDDO ! J - All nodes per line where the line position and tension can be output + + + ELSE ! if there is a problem with the catenary approach, just stretch the nodes linearly between fairlead and anchor + + !CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Line_Initialize') + call WrScr(" Catenary solve of Line "//trim(Num2LStr(Line%IdNum))//" unsuccessful. Initializing as linear.") + +! print *, "Node positions: " + + DO J = 0,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, 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) + +! print*, Line%r(:,J) + ENDDO + +! print*,"FYI line end A and B node coords are" +! print*, Line%r(:,0) +! print*, Line%r(:,N) + ENDIF + + + + CALL CleanUp() ! deallocate temporary arrays + + + + CONTAINS + + + !----------------------------------------------------------------------- + SUBROUTINE CleanUp() + ! deallocate temporary arrays + + IF (ALLOCATED(LSNodes)) DEALLOCATE(LSNodes) + IF (ALLOCATED(LNodesX)) DEALLOCATE(LNodesX) + IF (ALLOCATED(LNodesZ)) DEALLOCATE(LNodesZ) + + END SUBROUTINE CleanUp + !----------------------------------------------------------------------- + + + !----------------------------------------------------------------------- + SUBROUTINE Catenary ( XF_In, ZF_In, L_In , EA_In, & + W_In , CB_In, Tol_In, N , & + s_In , X_In , Z_In , ErrStat, ErrMsg ) + + ! This subroutine is copied from FAST v7 with minor modifications + + ! This routine solves the analytical, static equilibrium equations + ! for a catenary (or taut) mooring line with seabed interaction. + ! Stretching of the line is accounted for, but bending stiffness + ! is not. Given the mooring line properties and the fairlead + ! position relative to the anchor, this routine finds the line + ! configuration and tensions. Since the analytical solution + ! involves two nonlinear equations (XF and ZF) in two unknowns + ! (HF and VF), a Newton-Raphson iteration scheme is implemented in + ! order to solve for the solution. The values of HF and VF that + ! are passed into this routine are used as the initial guess in + ! the iteration. The Newton-Raphson iteration is only accurate in + ! double precision, so all of the input/output arguments are + ! converteds to/from double precision from/to default precision. + + ! >>>> TO DO: streamline this function, if it's still to be used at all <<<< + + ! USE Precision + + + IMPLICIT NONE + + + ! Passed Variables: + + INTEGER(4), INTENT(IN ) :: N ! Number of nodes where the line position and tension can be output (-) + + 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 + + + ! Local Variables: + + REAL(DbKi) :: CB ! Coefficient of seabed static friction (a negative value indicates no seabed) (-) + REAL(DbKi) :: CBOvrEA ! = CB/EA + REAL(DbKi) :: DET ! Determinant of the Jacobian matrix (m^2/N^2) + REAL(DbKi) :: dHF ! Increment in HF predicted by Newton-Raphson (N) + REAL(DbKi) :: dVF ! Increment in VF predicted by Newton-Raphson (N) + REAL(DbKi) :: dXFdHF ! Partial derivative of the calculated horizontal distance with respect to the horizontal fairlead tension (m/N): dXF(HF,VF)/dHF + REAL(DbKi) :: dXFdVF ! Partial derivative of the calculated horizontal distance with respect to the vertical fairlead tension (m/N): dXF(HF,VF)/dVF + REAL(DbKi) :: dZFdHF ! Partial derivative of the calculated vertical distance with respect to the horizontal fairlead tension (m/N): dZF(HF,VF)/dHF + REAL(DbKi) :: dZFdVF ! Partial derivative of the calculated vertical distance with respect to the vertical fairlead tension (m/N): dZF(HF,VF)/dVF + REAL(DbKi) :: EA ! Extensional stiffness of line (N) + REAL(DbKi) :: EXF ! Error function between calculated and known horizontal distance (meters): XF(HF,VF) - XF + REAL(DbKi) :: EZF ! Error function between calculated and known vertical distance (meters): ZF(HF,VF) - ZF + REAL(DbKi) :: HA ! Effective horizontal tension in line at the anchor (N) + REAL(DbKi) :: HF ! Effective horizontal tension in line at the fairlead (N) + REAL(DbKi) :: HFOvrW ! = HF/W + REAL(DbKi) :: HFOvrWEA ! = HF/WEA + REAL(DbKi) :: L ! Unstretched length of line (meters) + REAL(DbKi) :: Lamda0 ! Catenary parameter used to generate the initial guesses of the horizontal and vertical tensions at the fairlead for the Newton-Raphson iteration (-) + REAL(DbKi) :: LMax ! Maximum stretched length of the line with seabed interaction beyond which the line would have to double-back on itself; here the line forms an "L" between the anchor and fairlead (i.e. it is horizontal along the seabed from the anchor, then vertical to the fairlead) (meters) + REAL(DbKi) :: LMinVFOvrW ! = L - VF/W + REAL(DbKi) :: LOvrEA ! = L/EA + REAL(DbKi) :: s (N) ! Unstretched arc distance along line from anchor to each node where the line position and tension can be output (meters) + REAL(DbKi) :: sOvrEA ! = s(I)/EA + REAL(DbKi) :: SQRT1VFOvrHF2 ! = SQRT( 1.0_DbKi + VFOvrHF2 ) + REAL(DbKi) :: SQRT1VFMinWLOvrHF2 ! = SQRT( 1.0_DbKi + VFMinWLOvrHF2 ) + REAL(DbKi) :: SQRT1VFMinWLsOvrHF2 ! = SQRT( 1.0_DbKi + VFMinWLsOvrHF*VFMinWLsOvrHF ) + REAL(DbKi) :: Te (N) ! Effective line tensions at each node (N) + REAL(DbKi) :: Tol ! Convergence tolerance within Newton-Raphson iteration specified as a fraction of tension (-) + REAL(DbKi) :: VA ! Effective vertical tension in line at the anchor (N) + REAL(DbKi) :: VF ! Effective vertical tension in line at the fairlead (N) + REAL(DbKi) :: VFMinWL ! = VF - WL + REAL(DbKi) :: VFMinWLOvrHF ! = VFMinWL/HF + REAL(DbKi) :: VFMinWLOvrHF2 ! = VFMinWLOvrHF*VFMinWLOvrHF + REAL(DbKi) :: VFMinWLs ! = VFMinWL + Ws + REAL(DbKi) :: VFMinWLsOvrHF ! = VFMinWLs/HF + REAL(DbKi) :: VFOvrHF ! = VF/HF + REAL(DbKi) :: VFOvrHF2 ! = VFOvrHF*VFOvrHF + REAL(DbKi) :: VFOvrWEA ! = VF/WEA + REAL(DbKi) :: W ! Weight of line in fluid per unit length (N/m) + REAL(DbKi) :: WEA ! = W*EA + REAL(DbKi) :: WL ! Total weight of line in fluid (N): W*L + REAL(DbKi) :: Ws ! = W*s(I) + REAL(DbKi) :: X (N) ! Horizontal locations of each line node relative to the anchor (meters) + REAL(DbKi) :: XF ! Horizontal distance between anchor and fairlead (meters) + REAL(DbKi) :: XF2 ! = XF*XF + REAL(DbKi) :: Z (N) ! Vertical locations of each line node relative to the anchor (meters) + REAL(DbKi) :: ZF ! Vertical distance between anchor and fairlead (meters) + REAL(DbKi) :: ZF2 ! = ZF*ZF + + INTEGER(4) :: I ! Index for counting iterations or looping through line nodes (-) + INTEGER(4) :: MaxIter ! Maximum number of Newton-Raphson iterations possible before giving up (-) + + LOGICAL :: FirstIter ! Flag to determine whether or not this is the first time through the Newton-Raphson interation (flag) + + + ErrStat = ERrId_None + + + ! The Newton-Raphson iteration is only accurate in double precision, so + ! convert the input arguments into double precision: + + CB = REAL( CB_In , DbKi ) + EA = REAL( EA_In , DbKi ) + HF = 0.0_DbKi ! = REAL( HF_In , DbKi ) + L = REAL( L_In , DbKi ) + s (:) = REAL( s_In (:), DbKi ) + Tol = REAL( Tol_In , DbKi ) + VF = 0.0_DbKi ! keeping this for some error catching functionality? (at first glance) ! VF = REAL( VF_In , DbKi ) + W = REAL( W_In , DbKi ) + XF = REAL( XF_In , DbKi ) + ZF = REAL( ZF_In , DbKi ) + + + + ! HF and VF cannot be initialized to zero when a portion of the line rests on the seabed and the anchor tension is nonzero + + ! Generate the initial guess values for the horizontal and vertical tensions + ! at the fairlead in the Newton-Raphson iteration for the catenary mooring + ! line solution. Use starting values documented in: Peyrot, Alain H. and + ! Goulois, A. M., "Analysis Of Cable Structures," Computers & Structures, + ! Vol. 10, 1979, pp. 805-813: + XF2 = XF*XF + ZF2 = ZF*ZF + + IF ( XF == 0.0_DbKi ) THEN ! .TRUE. if the current mooring line is exactly vertical + Lamda0 = 1.0D+06 + ELSEIF ( L <= SQRT( XF2 + ZF2 ) ) THEN ! .TRUE. if the current mooring line is taut + Lamda0 = 0.2_DbKi + ELSE ! The current mooring line must be slack and not vertical + Lamda0 = SQRT( 3.0_DbKi*( ( L**2 - ZF2 )/XF2 - 1.0_DbKi ) ) + ENDIF + + HF = ABS( 0.5_DbKi*W* XF/ Lamda0 ) + VF = 0.5_DbKi*W*( ZF/TANH(Lamda0) + L ) + + + ! Abort when there is no solution or when the only possible solution is + ! illogical: + + IF ( Tol <= EPSILON(TOL) ) THEN ! .TRUE. when the convergence tolerance is specified incorrectly + ErrStat = ErrID_Warn + ErrMsg = ' Convergence tolerance must be greater than zero in routine Catenary().' + return + ELSEIF ( XF < 0.0_DbKi ) THEN ! .TRUE. only when the local coordinate system is not computed correctly + ErrStat = ErrID_Warn + ErrMsg = ' The horizontal distance between an anchor and its'// & + ' fairlead must not be less than zero in routine Catenary().' + return + + ELSEIF ( ZF < 0.0_DbKi ) THEN ! .TRUE. if the fairlead has passed below its anchor + ErrStat = ErrID_Warn + ErrMsg = " A line's fairlead is defined as below its anchor. You may need to swap a line's fairlead and anchor end nodes." + return + + ELSEIF ( L <= 0.0_DbKi ) THEN ! .TRUE. when the unstretched line length is specified incorrectly + ErrStat = ErrID_Warn + ErrMsg = ' Unstretched length of line must be greater than zero in routine Catenary().' + return + + ELSEIF ( EA <= 0.0_DbKi ) THEN ! .TRUE. when the unstretched line length is specified incorrectly + ErrStat = ErrID_Warn + ErrMsg = ' Extensional stiffness of line must be greater than zero in routine Catenary().' + return + + ELSEIF ( W == 0.0_DbKi ) THEN ! .TRUE. when the weight of the line in fluid is zero so that catenary solution is ill-conditioned + ErrStat = ErrID_Warn + ErrMsg = ' The weight of the line in fluid must not be zero. '// & + ' Routine Catenary() cannot solve quasi-static mooring line solution.' + return + + + ELSEIF ( W > 0.0_DbKi ) THEN ! .TRUE. when the line will sink in fluid + + LMax = XF - EA/W + SQRT( (EA/W)*(EA/W) + 2.0_DbKi*ZF*EA/W ) ! Compute the maximum stretched length of the line with seabed interaction beyond which the line would have to double-back on itself; here the line forms an "L" between the anchor and fairlead (i.e. it is horizontal along the seabed from the anchor, then vertical to the fairlead) + + IF ( ( L >= LMax ) .AND. ( CB >= 0.0_DbKi ) ) then ! .TRUE. if the line is as long or longer than its maximum possible value with seabed interaction + ErrStat = ErrID_Warn + !ErrMsg = ' Unstretched mooring line length too large. '// & + ! ' Routine Catenary() cannot solve quasi-static mooring line solution.' + return + END IF + + ENDIF + + + ! Initialize some commonly used terms that don't depend on the iteration: + + WL = W *L + WEA = W *EA + LOvrEA = L /EA + CBOvrEA = CB /EA + MaxIter = INT(1.0_DbKi/Tol) ! Smaller tolerances may take more iterations, so choose a maximum inversely proportional to the tolerance + + + + ! To avoid an ill-conditioned situation, ensure that the initial guess for + ! HF is not less than or equal to zero. Similarly, avoid the problems + ! associated with having exactly vertical (so that HF is zero) or exactly + ! horizontal (so that VF is zero) lines by setting the minimum values + ! equal to the tolerance. This prevents us from needing to implement + ! the known limiting solutions for vertical or horizontal lines (and thus + ! complicating this routine): + + HF = MAX( HF, Tol ) + XF = MAX( XF, Tol ) + ZF = MAX( ZF, TOl ) + + + + ! Solve the analytical, static equilibrium equations for a catenary (or + ! taut) mooring line with seabed interaction: + + ! Begin Newton-Raphson iteration: + + I = 1 ! Initialize iteration counter + FirstIter = .TRUE. ! Initialize iteration flag + + DO + + + ! Initialize some commonly used terms that depend on HF and VF: + + VFMinWL = VF - WL + LMinVFOvrW = L - VF/W + HFOvrW = HF/W + HFOvrWEA = HF/WEA + VFOvrWEA = VF/WEA + VFOvrHF = VF/HF + VFMinWLOvrHF = VFMinWL/HF + VFOvrHF2 = VFOvrHF *VFOvrHF + VFMinWLOvrHF2 = VFMinWLOvrHF*VFMinWLOvrHF + SQRT1VFOvrHF2 = SQRT( 1.0_DbKi + VFOvrHF2 ) + SQRT1VFMinWLOvrHF2 = SQRT( 1.0_DbKi + VFMinWLOvrHF2 ) + + + ! Compute the error functions (to be zeroed) and the Jacobian matrix + ! (these depend on the anticipated configuration of the mooring line): + + IF ( ( CB < 0.0_DbKi ) .OR. ( W < 0.0_DbKi ) .OR. ( VFMinWL > 0.0_DbKi ) ) THEN ! .TRUE. when no portion of the line rests on the seabed + + EXF = ( LOG( VFOvrHF + SQRT1VFOvrHF2 ) & + - LOG( VFMinWLOvrHF + SQRT1VFMinWLOvrHF2 ) )*HFOvrW & + + LOvrEA* HF - XF + EZF = ( SQRT1VFOvrHF2 & + - SQRT1VFMinWLOvrHF2 )*HFOvrW & + + LOvrEA*( VF - 0.5_DbKi*WL ) - ZF + + dXFdHF = ( LOG( VFOvrHF + SQRT1VFOvrHF2 ) & + - LOG( VFMinWLOvrHF + SQRT1VFMinWLOvrHF2 ) )/ W & + - ( ( VFOvrHF + VFOvrHF2 /SQRT1VFOvrHF2 )/( VFOvrHF + SQRT1VFOvrHF2 ) & + - ( VFMinWLOvrHF + VFMinWLOvrHF2/SQRT1VFMinWLOvrHF2 )/( VFMinWLOvrHF + SQRT1VFMinWLOvrHF2 ) )/ W & + + LOvrEA + dXFdVF = ( ( 1.0_DbKi + VFOvrHF /SQRT1VFOvrHF2 )/( VFOvrHF + SQRT1VFOvrHF2 ) & + - ( 1.0_DbKi + VFMinWLOvrHF /SQRT1VFMinWLOvrHF2 )/( VFMinWLOvrHF + SQRT1VFMinWLOvrHF2 ) )/ W + dZFdHF = ( SQRT1VFOvrHF2 & + - SQRT1VFMinWLOvrHF2 )/ W & + - ( VFOvrHF2 /SQRT1VFOvrHF2 & + - VFMinWLOvrHF2/SQRT1VFMinWLOvrHF2 )/ W + dZFdVF = ( VFOvrHF /SQRT1VFOvrHF2 & + - VFMinWLOvrHF /SQRT1VFMinWLOvrHF2 )/ W & + + LOvrEA + + + ELSEIF ( -CB*VFMinWL < HF ) THEN ! .TRUE. when a portion of the line rests on the seabed and the anchor tension is nonzero + + EXF = LOG( VFOvrHF + SQRT1VFOvrHF2 ) *HFOvrW & + - 0.5_DbKi*CBOvrEA*W* LMinVFOvrW*LMinVFOvrW & + + LOvrEA* HF + LMinVFOvrW - XF + EZF = ( SQRT1VFOvrHF2 - 1.0_DbKi )*HFOvrW & + + 0.5_DbKi*VF*VFOvrWEA - ZF + + dXFdHF = LOG( VFOvrHF + SQRT1VFOvrHF2 ) / W & + - ( ( VFOvrHF + VFOvrHF2 /SQRT1VFOvrHF2 )/( VFOvrHF + SQRT1VFOvrHF2 ) )/ W & + + LOvrEA + dXFdVF = ( ( 1.0_DbKi + VFOvrHF /SQRT1VFOvrHF2 )/( VFOvrHF + SQRT1VFOvrHF2 ) )/ W & + + CBOvrEA*LMinVFOvrW - 1.0_DbKi/W + dZFdHF = ( SQRT1VFOvrHF2 - 1.0_DbKi & + - VFOvrHF2 /SQRT1VFOvrHF2 )/ W + dZFdVF = ( VFOvrHF /SQRT1VFOvrHF2 )/ W & + + VFOvrWEA + + + ELSE ! 0.0_DbKi < HF <= -CB*VFMinWL ! A portion of the line must rest on the seabed and the anchor tension is zero + + EXF = LOG( VFOvrHF + SQRT1VFOvrHF2 ) *HFOvrW & + - 0.5_DbKi*CBOvrEA*W*( LMinVFOvrW*LMinVFOvrW - ( LMinVFOvrW - HFOvrW/CB )*( LMinVFOvrW - HFOvrW/CB ) ) & + + LOvrEA* HF + LMinVFOvrW - XF + EZF = ( SQRT1VFOvrHF2 - 1.0_DbKi )*HFOvrW & + + 0.5_DbKi*VF*VFOvrWEA - ZF + + dXFdHF = LOG( VFOvrHF + SQRT1VFOvrHF2 ) / W & + - ( ( VFOvrHF + VFOvrHF2 /SQRT1VFOvrHF2 )/( VFOvrHF + SQRT1VFOvrHF2 ) )/ W & + + LOvrEA - ( LMinVFOvrW - HFOvrW/CB )/EA + dXFdVF = ( ( 1.0_DbKi + VFOvrHF /SQRT1VFOvrHF2 )/( VFOvrHF + SQRT1VFOvrHF2 ) )/ W & + + HFOvrWEA - 1.0_DbKi/W + dZFdHF = ( SQRT1VFOvrHF2 - 1.0_DbKi & + - VFOvrHF2 /SQRT1VFOvrHF2 )/ W + dZFdVF = ( VFOvrHF /SQRT1VFOvrHF2 )/ W & + + VFOvrWEA + + + ENDIF + + + ! Compute the determinant of the Jacobian matrix and the incremental + ! tensions predicted by Newton-Raphson: + + + DET = dXFdHF*dZFdVF - dXFdVF*dZFdHF + + if ( EqualRealNos( DET, 0.0_DbKi ) ) then +!bjj: there is a serious problem with the debugger here when DET = 0 + ErrStat = ErrID_Warn + ErrMsg = ' Iteration not convergent (DET is 0). '// & + ' Routine Catenary() cannot solve quasi-static mooring line solution.' + return + endif + + + dHF = ( -dZFdVF*EXF + dXFdVF*EZF )/DET ! This is the incremental change in horizontal tension at the fairlead as predicted by Newton-Raphson + dVF = ( dZFdHF*EXF - dXFdHF*EZF )/DET ! This is the incremental change in vertical tension at the fairlead as predicted by Newton-Raphson + + dHF = dHF*( 1.0_DbKi - Tol*I ) ! Reduce dHF by factor (between 1 at I = 1 and 0 at I = MaxIter) that reduces linearly with iteration count to ensure that we converge on a solution even in the case were we obtain a nonconvergent cycle about the correct solution (this happens, for example, if we jump to quickly between a taut and slack catenary) + dVF = dVF*( 1.0_DbKi - Tol*I ) ! Reduce dHF by factor (between 1 at I = 1 and 0 at I = MaxIter) that reduces linearly with iteration count to ensure that we converge on a solution even in the case were we obtain a nonconvergent cycle about the correct solution (this happens, for example, if we jump to quickly between a taut and slack catenary) + + dHF = MAX( dHF, ( Tol - 1.0_DbKi )*HF ) ! To avoid an ill-conditioned situation, make sure HF does not go less than or equal to zero by having a lower limit of Tol*HF [NOTE: the value of dHF = ( Tol - 1.0_DbKi )*HF comes from: HF = HF + dHF = Tol*HF when dHF = ( Tol - 1.0_DbKi )*HF] + + ! Check if we have converged on a solution, or restart the iteration, or + ! Abort if we cannot find a solution: + + IF ( ( ABS(dHF) <= ABS(Tol*HF) ) .AND. ( ABS(dVF) <= ABS(Tol*VF) ) ) THEN ! .TRUE. if we have converged; stop iterating! [The converge tolerance, Tol, is a fraction of tension] + + EXIT + + + ELSEIF ( ( I == MaxIter ) .AND. ( FirstIter ) ) THEN ! .TRUE. if we've iterated MaxIter-times for the first time; + + ! Perhaps we failed to converge because our initial guess was too far off. + ! (This could happen, for example, while linearizing a model via large + ! pertubations in the DOFs.) Instead, use starting values documented in: + ! Peyrot, Alain H. and Goulois, A. M., "Analysis Of Cable Structures," + ! Computers & Structures, Vol. 10, 1979, pp. 805-813: + ! NOTE: We don't need to check if the current mooring line is exactly + ! vertical (i.e., we don't need to check if XF == 0.0), because XF is + ! limited by the tolerance above. + + XF2 = XF*XF + ZF2 = ZF*ZF + + IF ( L <= SQRT( XF2 + ZF2 ) ) THEN ! .TRUE. if the current mooring line is taut + Lamda0 = 0.2_DbKi + ELSE ! The current mooring line must be slack and not vertical + Lamda0 = SQRT( 3.0_DbKi*( ( L*L - ZF2 )/XF2 - 1.0_DbKi ) ) + ENDIF + + HF = MAX( ABS( 0.5_DbKi*W* XF/ Lamda0 ), Tol ) ! As above, set the lower limit of the guess value of HF to the tolerance + VF = 0.5_DbKi*W*( ZF/TANH(Lamda0) + L ) + + + ! Restart Newton-Raphson iteration: + + I = 0 + FirstIter = .FALSE. + dHF = 0.0_DbKi + dVF = 0.0_DbKi + + + ELSEIF ( ( I == MaxIter ) .AND. ( .NOT. FirstIter ) ) THEN ! .TRUE. if we've iterated as much as we can take without finding a solution; Abort + ErrStat = ErrID_Warn + ErrMsg = ' Iteration not convergent. '// & + ' Routine Catenary() cannot solve quasi-static mooring line solution.' + RETURN + + + ENDIF + + + ! Increment fairlead tensions and iteration counter so we can try again: + + HF = HF + dHF + VF = VF + dVF + + I = I + 1 + + + ENDDO + + + + ! We have found a solution for the tensions at the fairlead! + + ! Now compute the tensions at the anchor and the line position and tension + ! at each node (again, these depend on the configuration of the mooring + ! line): + + IF ( ( CB < 0.0_DbKi ) .OR. ( W < 0.0_DbKi ) .OR. ( VFMinWL > 0.0_DbKi ) ) THEN ! .TRUE. when no portion of the line rests on the seabed + + ! Anchor tensions: + + HA = HF + VA = VFMinWL + + + ! Line position and tension at each node: + + DO I = 1,N ! Loop through all nodes where the line position and tension are to be computed + + IF ( ( s(I) < 0.0_DbKi ) .OR. ( s(I) > L ) ) THEN + ErrStat = ErrID_Warn + ErrMsg = ' All line nodes must be located between the anchor ' & + //'and fairlead (inclusive) in routine Catenary().' + RETURN + END IF + + Ws = W *s(I) ! Initialize + VFMinWLs = VFMinWL + Ws ! some commonly + VFMinWLsOvrHF = VFMinWLs/HF ! used terms + sOvrEA = s(I) /EA ! that depend + SQRT1VFMinWLsOvrHF2 = SQRT( 1.0_DbKi + VFMinWLsOvrHF*VFMinWLsOvrHF ) ! on s(I) + + X (I) = ( LOG( VFMinWLsOvrHF + SQRT1VFMinWLsOvrHF2 ) & + - LOG( VFMinWLOvrHF + SQRT1VFMinWLOvrHF2 ) )*HFOvrW & + + sOvrEA* HF + Z (I) = ( SQRT1VFMinWLsOvrHF2 & + - SQRT1VFMinWLOvrHF2 )*HFOvrW & + + sOvrEA*( VFMinWL + 0.5_DbKi*Ws ) + Te(I) = SQRT( HF*HF + VFMinWLs*VFMinWLs ) + + ENDDO ! I - All nodes where the line position and tension are to be computed + + + ELSEIF ( -CB*VFMinWL < HF ) THEN ! .TRUE. when a portion of the line rests on the seabed and the anchor tension is nonzero + + ! Anchor tensions: + + HA = HF + CB*VFMinWL + VA = 0.0_DbKi + + + ! Line position and tension at each node: + + DO I = 1,N ! Loop through all nodes where the line position and tension are to be computed + + IF ( ( s(I) < 0.0_DbKi ) .OR. ( s(I) > L ) ) THEN + ErrStat = ErrID_Warn + ErrMsg = ' All line nodes must be located between the anchor ' & + //'and fairlead (inclusive) in routine Catenary().' + RETURN + END IF + + Ws = W *s(I) ! Initialize + VFMinWLs = VFMinWL + Ws ! some commonly + VFMinWLsOvrHF = VFMinWLs/HF ! used terms + sOvrEA = s(I) /EA ! that depend + SQRT1VFMinWLsOvrHF2 = SQRT( 1.0_DbKi + VFMinWLsOvrHF*VFMinWLsOvrHF ) ! on s(I) + + IF ( s(I) <= LMinVFOvrW ) THEN ! .TRUE. if this node rests on the seabed and the tension is nonzero + + X (I) = s(I) & + + sOvrEA*( HF + CB*VFMinWL + 0.5_DbKi*Ws*CB ) + Z (I) = 0.0_DbKi + Te(I) = HF + CB*VFMinWLs + + ELSE ! LMinVFOvrW < s <= L ! This node must be above the seabed + + X (I) = LOG( VFMinWLsOvrHF + SQRT1VFMinWLsOvrHF2 ) *HFOvrW & + + sOvrEA* HF + LMinVFOvrW - 0.5_DbKi*CB*VFMinWL*VFMinWL/WEA + Z (I) = ( - 1.0_DbKi + SQRT1VFMinWLsOvrHF2 )*HFOvrW & + + sOvrEA*( VFMinWL + 0.5_DbKi*Ws ) + 0.5_DbKi* VFMinWL*VFMinWL/WEA + Te(I) = SQRT( HF*HF + VFMinWLs*VFMinWLs ) + + ENDIF + + ENDDO ! I - All nodes where the line position and tension are to be computed + + + ELSE ! 0.0_DbKi < HF <= -CB*VFMinWL ! A portion of the line must rest on the seabed and the anchor tension is zero + + ! Anchor tensions: + + HA = 0.0_DbKi + VA = 0.0_DbKi + + + ! Line position and tension at each node: + + DO I = 1,N ! Loop through all nodes where the line position and tension are to be computed + + IF ( ( s(I) < 0.0_DbKi ) .OR. ( s(I) > L ) ) THEN + ErrStat = ErrID_Warn + ErrMsg = ' All line nodes must be located between the anchor ' & + //'and fairlead (inclusive) in routine Catenary().' + RETURN + END IF + + Ws = W *s(I) ! Initialize + VFMinWLs = VFMinWL + Ws ! some commonly + VFMinWLsOvrHF = VFMinWLs/HF ! used terms + sOvrEA = s(I) /EA ! that depend + SQRT1VFMinWLsOvrHF2 = SQRT( 1.0_DbKi + VFMinWLsOvrHF*VFMinWLsOvrHF ) ! on s(I) + + IF ( s(I) <= LMinVFOvrW - HFOvrW/CB ) THEN ! .TRUE. if this node rests on the seabed and the tension is zero + + X (I) = s(I) + Z (I) = 0.0_DbKi + Te(I) = 0.0_DbKi + + ELSEIF ( s(I) <= LMinVFOvrW ) THEN ! .TRUE. if this node rests on the seabed and the tension is nonzero + + X (I) = s(I) - ( LMinVFOvrW - 0.5_DbKi*HFOvrW/CB )*HF/EA & + + sOvrEA*( HF + CB*VFMinWL + 0.5_DbKi*Ws*CB ) + 0.5_DbKi*CB*VFMinWL*VFMinWL/WEA + Z (I) = 0.0_DbKi + Te(I) = HF + CB*VFMinWLs + + ELSE ! LMinVFOvrW < s <= L ! This node must be above the seabed + + X (I) = LOG( VFMinWLsOvrHF + SQRT1VFMinWLsOvrHF2 ) *HFOvrW & + + sOvrEA* HF + LMinVFOvrW - ( LMinVFOvrW - 0.5_DbKi*HFOvrW/CB )*HF/EA + Z (I) = ( - 1.0_DbKi + SQRT1VFMinWLsOvrHF2 )*HFOvrW & + + sOvrEA*( VFMinWL + 0.5_DbKi*Ws ) + 0.5_DbKi* VFMinWL*VFMinWL/WEA + Te(I) = SQRT( HF*HF + VFMinWLs*VFMinWLs ) + + ENDIF + + ENDDO ! I - All nodes where the line position and tension are to be computed + + + ENDIF + + + + ! The Newton-Raphson iteration is only accurate in double precision, so + ! convert the output arguments back into the default precision for real + ! numbers: + + !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 + !----------------------------------------------------------------------- + + + END SUBROUTINE Line_Initialize + !-------------------------------------------------------------- + + + !-------------------------------------------------------------- + SUBROUTINE Line_SetState(Line, X, t) + + TYPE(MD_Line), INTENT(INOUT) :: Line ! the current Line object + Real(DbKi), INTENT(IN ) :: X(:) ! state vector section for this line + Real(DbKi), INTENT(IN ) :: t ! instantaneous time + + INTEGER(IntKi) :: i ! index of segments or nodes along line + INTEGER(IntKi) :: J ! index + + + ! store current time + Line%time = t + + ! set interior node positions and velocities based on state vector + DO I=1,Line%N-1 + DO J=1,3 + + Line%r( J,I) = X( 3*Line%N-3 + 3*I-3 + J) ! get positions + Line%rd(J,I) = X( 3*I-3 + J) ! get velocities + + END DO + END DO + + ! if using viscoelastic model, also set the static stiffness stretch + if (Line%ElasticMod == 2) then + do I=1,Line%N + Line%dl_1(I) = X( 6*Line%N-6 + I) ! these will be the last N entries in the state vector + end do + end if + + END SUBROUTINE Line_SetState + !-------------------------------------------------------------- + + !-------------------------------------------------------------- + SUBROUTINE Line_GetStateDeriv(Line, Xd, m, p) !, FairFtot, FairMtot, AnchFtot, AnchMtot) + + TYPE(MD_Line), INTENT(INOUT) :: Line ! the current Line object + Real(DbKi), INTENT(INOUT) :: Xd(:) ! state derivative vector section for this line + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + TYPE(MD_ParameterType), INTENT(IN ) :: p ! Parameters + + ! 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(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(DbKi) :: d ! line diameter + Real(DbKi) :: rho ! line material density [kg/m^3] + Real(DbKi) :: Sum1 ! for summing squares + Real(DbKi) :: dummyLength ! + 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 ! + Real(DbKi) :: MagT ! tension stiffness force magnitude + Real(DbKi) :: MagTd ! tension damping force magnitude + Real(DbKi) :: Xi ! used in interpolating from lookup table + Real(DbKi) :: Yi ! used in interpolating from lookup table + Real(DbKi) :: dl ! stretch of a segment [m] + Real(DbKi) :: ld_1 ! rate of change of static stiffness portion of segment [m/s] + Real(DbKi) :: EA_1 ! stiffness of 'static stiffness' portion of segment, combines with dynamic stiffness to give static stiffnes [m/s] + + Real(DbKi) :: Kurvi ! temporary curvature value [1/m] + Real(DbKi) :: pvec(3) ! the p vector used in bending stiffness calcs + Real(DbKi) :: Mforce_im1(3) ! force vector for a contributor to the effect of a bending moment [N] + Real(DbKi) :: Mforce_ip1(3) ! force vector for a contributor to the effect of a bending moment [N] + Real(DbKi) :: Mforce_i( 3) ! force vector for a contributor to the effect of a bending moment [N] + + Real(DbKi) :: depth ! local water depth interpolated from bathymetry grid [m] + Real(DbKi) :: nvec(3) ! local seabed surface normal vector (positive out) + Real(DbKi) :: Fn(3) ! seabed contact normal force vector + Real(DbKi) :: Vn(3) ! normal velocity of a line node relative to the seabed slope [m/s] + Real(DbKi) :: Vsb(3) ! tangent velocity of a line node relative to the seabed slope [m/s] + Real(DbKi) :: Va(3) ! velocity of a line node in the axial or "in-line" direction [m/s] + Real(DbKi) :: Vt(3) ! velocity of a line node in the transverse direction [m/s] + Real(DbKi) :: VtMag ! magnitude of the transverse velocity of a line node [m/s] + Real(DbKi) :: VaMag ! magnitude of the axial velocity of a line node [m/s] + Real(DbKi) :: FkTmax ! maximum kinetic friction force in the transverse direction (scalar) + Real(DbKi) :: FkAmax ! maximum kinetic friction force in the axial direction (scalar) + Real(DbKi) :: FkT(3) ! kinetic friction force in the transverse direction (vector) + Real(DbKi) :: FkA(3) ! kinetic friction force in the axial direction (vector) + !Real(DbKi) :: mc_T ! ratio of the transverse static friction coefficient to the transverse kinetic friction coefficient + !Real(DbKi) :: mc_A ! ratio of the axial static friction coefficient to the axial kinetic friction coefficient + Real(DbKi) :: FfT(3) ! total friction force in the transverse direction + Real(DbKi) :: FfA(3) ! total friction force in the axial direction + Real(DbKi) :: Ff(3) ! total friction force on the line node + + + N = Line%N ! for convenience + d = Line%d + rho = Line%rho + + ! note that end node kinematics should have already been set by attached objects + + ! ! set end node positions and velocities from connect objects' states + ! DO J = 1, 3 + ! Line%r( J,N) = m%ConnectList(Line%FairConnect)%r(J) + ! Line%r( J,0) = m%ConnectList(Line%AnchConnect)%r(J) + ! Line%rd(J,N) = m%ConnectList(Line%FairConnect)%rd(J) + ! Line%rd(J,0) = m%ConnectList(Line%AnchConnect)%rd(J) + ! END DO + + + + ! -------------------- calculate various kinematic quantities --------------------------- + DO I = 1, N + + + ! calculate current (Stretched) segment lengths and unit tangent vectors (qs) for each segment (this is used for bending calculations) + CALL UnitVector(Line%r(:,I-1), Line%r(:,I), Line%qs(:,I), Line%lstr(I)) + + ! should add catch here for if lstr is ever zero + + 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 + Line%lstrd(I) = Sum1/Line%lstr(I) ! segment stretched length rate of change + + ! Line%V(I) = Pi/4.0 * d*d*Line%l(I) !volume attributed to segment + END DO + + !calculate unit tangent vectors (q) for each internal node based on adjacent node positions + DO I = 1, N-1 + CALL UnitVector(Line%r(:,I-1), Line%r(:,I+1), Line%q(:,I), dummyLength) + END DO + + ! calculate unit tangent vectors for either end node if the line has no bending stiffness of if either end is pinned (otherwise it's already been set via setEndStateFromRod) + if ((Line%endTypeA==0) .or. (Line%EI==0.0)) then + CALL UnitVector(Line%r(:,0), Line%r(:,1), Line%q(:,0), dummyLength) + end if + if ((Line%endTypeB==0) .or. (Line%EI==0.0)) then + CALL UnitVector(Line%r(:,N-1), Line%r(:,N), Line%q(:,N), dummyLength) + end if + + ! apply wave kinematics (if there are any) + DO i=0,N + CALL getWaterKin(p, Line%r(1,i), Line%r(2,i), Line%r(3,i), Line%time, m%WaveTi, Line%U(:,i), Line%Ud(:,i), Line%zeta(i), Line%PDyn(i)) + END DO + + + ! --------------- calculate mass (including added mass) matrix for each node ----------------- + DO I = 0, N + IF (I==0) THEN + m_i = Pi/8.0 *d*d*Line%l(1)*rho + v_i = 0.5 *Line%V(1) + ELSE IF (I==N) THEN + m_i = pi/8.0 *d*d*Line%l(N)*rho; + v_i = 0.5*Line%V(N) + ELSE + m_i = pi/8.0 * d*d*rho*(Line%l(I) + Line%l(I+1)) + v_i = 0.5 *(Line%V(I) + Line%V(I+1)) + END IF + + DO J=1,3 + DO K=1,3 + IF (J==K) THEN + Line%M(K,J,I) = m_i + p%rhoW*v_i*( Line%Can*(1 - Line%q(J,I)*Line%q(K,I)) + Line%Cat*Line%q(J,I)*Line%q(K,I) ) + ELSE + Line%M(K,J,I) = p%rhoW*v_i*( Line%Can*(-Line%q(J,I)*Line%q(K,I)) + Line%Cat*Line%q(J,I)*Line%q(K,I) ) + END IF + END DO + END DO + + CALL Inverse3by3(Line%S(:,:,I), Line%M(:,:,I)) ! invert mass matrix + END DO + + + ! ------------------ CALCULATE FORCES ON EACH NODE ---------------------------- + + ! loop through the segments + DO I = 1, N + + ! handle nonlinear stiffness if needed + if (Line%nEApoints > 0) then + + Xi = Line%lstr(I)/Line%l(I) - 1.0 ! strain rate based on inputs + Yi = 0.0_DbKi + + ! find stress based on strain + if (Xi < 0.0) then ! if negative strain (compression), zero stress + Yi = 0.0_DbKi + else if (Xi < Line%stiffXs(1)) then ! if strain below first data point, interpolate from zero + Yi = Xi * Line%stiffYs(1)/Line%stiffXs(1) + else if (Xi >= Line%stiffXs(Line%nEApoints)) then ! if strain exceeds last data point, use last data point + Yi = Line%stiffYs(Line%nEApoints) + else ! otherwise we're in range of the table so interpolate! + do J=1, Line%nEApoints-1 ! go through lookup table until next entry exceeds inputted strain rate + if (Line%stiffXs(J+1) > Xi) then + Yi = Line%stiffYs(J) + (Xi-Line%stiffXs(J)) * (Line%stiffYs(J+1)-Line%stiffYs(J))/(Line%stiffXs(J+1)-Line%stiffXs(J)) + exit + end if + end do + end if + + ! calculate a young's modulus equivalent value based on stress/strain + Line%EA = Yi/Xi + end if + + + ! >>>> could do similar as above for nonlinear damping or bending stiffness <<<< + if (Line%nBApoints > 0) print *, 'Nonlinear elastic damping not yet implemented' + if (Line%nEIpoints > 0) print *, 'Nonlinear bending stiffness not yet implemented' + + + ! basic elasticity model + if (Line%ElasticMod == 1) then + ! line tension, inherently including possibility of dynamic length changes in l term + if (Line%lstr(I)/Line%l(I) > 1.0) then + MagT = Line%EA *( Line%lstr(I)/Line%l(I) - 1.0 ) + else + MagT = 0.0_DbKi ! cable can't "push" + end if + ! line internal damping force based on line-specific BA value, including possibility of dynamic length changes in l and ld terms + MagTd = Line%BA* ( Line%lstrd(I) - Line%lstr(I)*Line%ld(I)/Line%l(I) )/Line%l(I) + + ! viscoelastic model + else if (Line%ElasticMod == 2) then + + EA_1 = Line%EA_D*Line%EA/(Line%EA_D - Line%EA)! calculated EA_1 which is the stiffness in series with EA_D that will result in the desired static stiffness of EA_S + + dl = Line%lstr(I) - Line%l(I) ! delta l of this segment + + ld_1 = (Line%EA_D*dl - (Line%EA_D + EA_1)*Line%dl_1(I) + Line%BA_D*Line%lstrd(I)) /( Line%BA_D + Line%BA) ! rate of change of static stiffness portion [m/s] + + !MagT = (Line%EA*Line%dl_S(I) + Line%BA*ld_S)/ Line%l(I) ! compute tension based on static portion (dynamic portion would give same) + MagT = EA_1*Line%dl_1(I)/ Line%l(I) + MagTd = Line%BA*ld_1 / Line%l(I) + + ! update state derivative for static stiffness stretch (last N entries in the state vector) + Xd( 6*N-6 + I) = ld_1 + + end if + + + do J = 1, 3 + !Line%T(J,I) = Line%EA *( 1.0/Line%l(I) - 1.0/Line%lstr(I) ) * (Line%r(J,I)-Line%r(J,I-1)) + Line%T(J,I) = MagT * Line%qs(J,I) + !Line%Td(J,I) = Line%BA* ( Line%lstrd(I) / Line%l(I) ) * (Line%r(J,I)-Line%r(J,I-1)) / Line%lstr(I) ! note new form of damping coefficient, BA rather than Cint + Line%Td(J,I) = MagTd * Line%qs(J,I) + end do + end do + + + ! Bending loads + Line%Bs = 0.0_DbKi ! zero bending forces + + if (Line%EI > 0) then + ! loop through all nodes to calculate bending forces due to bending stiffness + do i=0,N + + ! end node A case (only if attached to a Rod, i.e. a cantilever rather than pinned connection) + if (i==0) then + + if (Line%endTypeA > 0) then ! if attached to Rod i.e. cantilever connection + + Kurvi = GetCurvature(Line%lstr(1), Line%q(:,0), Line%qs(:,1)) ! curvature (assuming rod angle is node angle which is middle of if there was a segment -1/2) + + pvec = cross_product(Line%q(:,0), Line%qs(:,1)) ! get direction of bending radius axis + + Mforce_ip1 = cross_product(Line%qs(:,1), pvec) ! get direction of resulting force from bending to apply on node i+1 + + call scalevector(pvec, Kurvi*Line%EI, Line%endMomentA) ! record bending moment at end for potential application to attached object + + call scalevector(Mforce_ip1, Kurvi*Line%EI/Line%lstr(1), Mforce_ip1) ! scale force direction vectors by desired moment force magnitudes to get resulting forces on adjacent nodes + + Mforce_i = -Mforce_ip1 ! set force on node i to cancel out forces on adjacent nodes + + ! apply these forces to the node forces + Line%Bs(:,i ) = Line%Bs(:,i ) + Mforce_i + Line%Bs(:,i+1) = Line%Bs(:,i+1) + Mforce_ip1 + + end if + + ! end node A case (only if attached to a Rod, i.e. a cantilever rather than pinned connection) + else if (i==N) then + + if (Line%endTypeB > 0) then ! if attached to Rod i.e. cantilever connection + + Kurvi = GetCurvature(Line%lstr(N), Line%qs(:,N), Line%q(:,N)) ! curvature (assuming rod angle is node angle which is middle of if there was a segment -1/2 + + pvec = cross_product(Line%qs(:,N), Line%q(:,N)) ! get direction of bending radius axis + + Mforce_im1 = cross_product(Line%qs(:,N), pvec) ! get direction of resulting force from bending to apply on node i-1 + + call scalevector(pvec, -Kurvi*Line%EI, Line%endMomentB ) ! record bending moment at end (note end B is oposite sign as end A) + + call scalevector(Mforce_im1, Kurvi*Line%EI/Line%lstr(N), Mforce_im1) ! scale force direction vectors by desired moment force magnitudes to get resulting forces on adjacent nodes + + Mforce_i = -Mforce_im1 ! set force on node i to cancel out forces on adjacent nodes + + ! apply these forces to the node forces + Line%Bs(:,i-1) = Line%Bs(:,i-1) + Mforce_im1 + Line%Bs(:,i ) = Line%Bs(:,i ) + Mforce_i + + end if + + else ! internal node + + Kurvi = GetCurvature(Line%lstr(i)+Line%lstr(i+1), Line%qs(:,i), Line%qs(:,i+1)) ! curvature + + pvec = cross_product(Line%qs(:,i), Line%qs(:,i+1)) ! get direction of bending radius axis + + Mforce_im1 = cross_product(Line%qs(:,i ), pvec) ! get direction of resulting force from bending to apply on node i-1 + Mforce_ip1 = cross_product(Line%qs(:,i+1), pvec) ! get direction of resulting force from bending to apply on node i+1 + + ! scale force direction vectors by desired moment force magnitudes to get resulting forces on adjacent nodes + call scalevector(Mforce_im1, Kurvi*Line%EI/Line%lstr(i ), Mforce_im1) + call scalevector(Mforce_ip1, Kurvi*Line%EI/Line%lstr(i+1), Mforce_ip1) + + Mforce_i = -Mforce_im1 - Mforce_ip1 ! set force on node i to cancel out forces on adjacent nodes + + ! apply these forces to the node forces + Line%Bs(:,i-1) = Line%Bs(:,i-1) + Mforce_im1 + Line%Bs(:,i ) = Line%Bs(:,i ) + Mforce_i + Line%Bs(:,i+1) = Line%Bs(:,i+1) + Mforce_ip1 + + end if + + ! record curvature at node + Line%Kurv(i) = Kurvi + + end do ! for i=0,N (looping through nodes) + end if ! if EI > 0 + + + + + ! loop through the nodes + DO I = 0, N + + !submerged weight (including buoyancy) + IF (I==0) THEN + Line%W(3,I) = Pi/8.0*d*d* Line%l(1)*(rho - p%rhoW) *(-p%g) ! assuming g is positive + ELSE IF (i==N) THEN + Line%W(3,I) = pi/8.0*d*d* Line%l(N)*(rho - p%rhoW) *(-p%g) + ELSE + Line%W(3,I) = pi/8.0*d*d* (Line%l(I)*(rho - p%rhoW) + Line%l(I+1)*(rho - p%rhoW) )*(-p%g) ! left in this form for future free surface handling + END IF + + ! relative flow velocities + DO J = 1, 3 + Vi(J) = Line%U(J,I) - Line%rd(J,I) ! relative flow velocity over node -- this is where wave velicites would be added + END DO + + ! decomponse relative flow into components + 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 + SumSqVq = SumSqVq + Vq(J)*Vq(J) + SumSqVp = SumSqVp + Vp(J)*Vp(J) + END DO + MagVp = sqrt(SumSqVp) ! get magnitudes of flow components + MagVq = sqrt(SumSqVq) + + ! transverse and tangenential drag + IF (I==0) THEN + Line%Dp(:,I) = 0.25*p%rhoW*Line%Cdn* d*Line%l(1) * MagVp * Vp + Line%Dq(:,I) = 0.25*p%rhoW*Line%Cdt* Pi*d*Line%l(1) * MagVq * Vq + ELSE IF (I==N) THEN + Line%Dp(:,I) = 0.25*p%rhoW*Line%Cdn* d*Line%l(N) * MagVp * Vp + Line%Dq(:,I) = 0.25*p%rhoW*Line%Cdt* Pi*d*Line%l(N) * MagVq * Vq + ELSE + Line%Dp(:,I) = 0.25*p%rhoW*Line%Cdn* d*(Line%l(I) + Line%l(I+1)) * MagVp * vp + Line%Dq(:,I) = 0.25*p%rhoW*Line%Cdt* Pi*d*(Line%l(I) + Line%l(I+1)) * MagVq * vq + END IF + + ! F-K force from fluid acceleration not implemented yet + + ! bottom contact (stiffness and damping, vertical-only for now) - updated Nov 24 for general case where anchor and fairlead ends may deal with bottom contact forces + ! bottom contact - updated throughout October 2021 for seabed bathymetry and friction models + + ! interpolate the local depth from the bathymetry grid and return the vector normal to the seabed slope + CALL getDepthFromBathymetry(m%BathymetryGrid, m%BathGrid_Xs, m%BathGrid_Ys, Line%r(1,I), Line%r(2,I), depth, nvec) + + IF (Line%r(3,I) < -depth) THEN ! for every line node at or below the seabed + + ! calculate the velocity components of the node relative to the seabed + Vn = DOT_PRODUCT( Line%rd(:,I), nvec) * nvec ! velocity component normal to the local seabed slope + Vsb = Line%rd(:,I) - Vn ! velocity component along (tangent to) the seabed + + ! calculate the normal contact force on the line node + IF (I==0) THEN + Fn = ( (-depth - Line%r(3,I))*nvec(3)*nvec*p%kBot - Vn*p%cBot) * 0.5*d*( Line%l(I+1) ) + ELSE IF (I==N) THEN + Fn = ( (-depth - Line%r(3,I))*nvec(3)*nvec*p%kBot - Vn*p%cBot) * 0.5*d*(Line%l(I) ) + ELSE + Fn = ( (-depth - Line%r(3,I))*nvec(3)*nvec*p%kBot - Vn*p%cBot) * 0.5*d*(Line%l(I) + Line%l(I+1) ) + END IF + + ! calculate the axial and transverse components of the node velocity vector along the seabed + Va = DOT_PRODUCT( Vsb , Line%q(:,I) ) * Line%q(:,I) + Vt = Vsb - Va + + ! calculate the magnitudes of each velocity + VaMag = SQRT(Va(1)**2+Va(2)**2+Va(3)**2) + VtMag = SQRT(Vt(1)**2+Vt(2)**2+Vt(3)**2) + + ! find the maximum possible kinetic friction force using transverse and axial kinetic friction coefficients + FkTmax = p%mu_kT*SQRT(Fn(1)**2+Fn(2)**2+Fn(3)**2) + FkAmax = p%mu_kA*SQRT(Fn(1)**2+Fn(2)**2+Fn(3)**2) + ! turn the maximum kinetic friction forces into vectors in the direction of their velocities + DO J = 1, 3 + IF (VtMag==0) THEN + FkT(J) = 0.0_DbKi + ELSE + FkT(J) = FkTmax*Vt(J)/VtMag + END IF + IF (VaMag==0) THEN + FkA(J) = 0.0_DbKi + ELSE + FkA(J) = FkAmax*Va(J)/VaMag + END IF + END DO + ! calculate the ratio between the static and kinetic coefficients of friction + !mc_T = p%mu_sT/p%mu_kT + !mc_A = p%mu_sA/p%mu_kA + + ! calculate the transverse friction force + IF (p%mu_kT*p%cv*VtMag > p%mc*FkTmax) THEN ! if the friction force of the linear curve is greater than the maximum friction force allowed adjusted for static friction, + FfT = -FkT ! then the friction force is the maximum kinetic friction force vector (constant part of the curve) + ELSE ! if the friction force of the linear curve is less than the maximum friction force allowed adjusted for static friction, + FfT = -p%mu_kT*p%cv*Vt ! then the friction force is the calculated value of the linear line + END IF + ! calculate the axial friction force + IF (p%mu_kA*p%cv*VaMag > p%mc*FkAmax) THEN ! if the friction force of the linear curve is greater than the maximum friction force allowed adjusted for static friction, + FfA = -FkA ! then the friction force is the maximum kinetic friction force vector (constant part of the curve) + ELSE ! if the friction force of the linear curve is less than the maximum friction force allowed adjusted for static friction, + FfA = -p%mu_kA*p%cv*Va ! then the friction force is the calculated value of the linear line + END IF + ! NOTE: these friction forces have a negative sign here to indicate a force in the opposite direction of motion + + ! the total friction force is along the plane of the seabed slope, which is just the vector sum of the transverse and axial components + Ff = FfT + FfA + + ELSE + Fn = 0.0_DbKi + Ff = 0.0_DbKi + END IF + + + ! the total force from bottom contact on the line node is the sum of the normal contact force and the friction force + Line%B(:,I) = Fn + Ff + + ! total forces + IF (I==0) THEN + Line%Fnet(:,I) = Line%T(:,1) + Line%Td(:,1) + Line%W(:,I) + Line%Dp(:,I) + Line%Dq(:,I) + Line%B(:,I) + Line%Bs(:,I) + ELSE IF (I==N) THEN + Line%Fnet(:,I) = -Line%T(:,N) - Line%Td(:,N) + Line%W(:,I) + Line%Dp(:,I) + Line%Dq(:,I) + Line%B(:,I) + Line%Bs(:,I) + ELSE + Line%Fnet(:,I) = Line%T(:,I+1) - Line%T(:,I) + Line%Td(:,I+1) - Line%Td(:,I) + Line%W(:,I) + Line%Dp(:,I) + Line%Dq(:,I) + Line%B(:,I) + Line%Bs(:,I) + END IF + + END DO ! I - done looping through nodes + + ! loop through internal nodes and update their states <<< should/could convert to matrix operations instead of all these loops + DO I=1, N-1 + DO J=1,3 + + ! calculate RHS constant (premultiplying force vector by inverse of mass matrix ... i.e. rhs = S*Forces) + Sum1 = 0.0_DbKi ! reset temporary accumulator <<< could turn this into a Line%a array to save and output node accelerations + DO K = 1, 3 + Sum1 = Sum1 + Line%S(K,J,I) * Line%Fnet(K,I) ! matrix-vector multiplication [S i]{Forces i} << double check indices + END DO ! K + + ! update states + Xd(3*N-3 + 3*I-3 + J) = Line%rd(J,I); ! dxdt = V (velocities) + Xd( 3*I-3 + J) = Sum1 ! dVdt = RHS * A (accelerations) + + END DO ! J + END DO ! I + + + ! check for NaNs + DO J = 1, 6*(N-1) + IF (Is_NaN(Xd(J))) THEN + print *, "NaN detected at time ", Line%time, " in Line ", Line%IdNum, " in MoorDyn." + IF (wordy > 1) THEN + print *, "state derivatives:" + print *, Xd + + + + print *, "m_i p%rhoW v_i Line%Can Line%Cat" + print *, m_i + print *, p%rhoW + print *, v_i + print *, Line%Can + print *, Line%Cat + + print *, "Line%q" + print *, Line%q + + print *, "Line%r" + print *, Line%r + + + print *, "Here is the mass matrix set" + print *, Line%M + + print *, "Here is the inverted mass matrix set" + print *, Line%S + + print *, "Here is the net force set" + print *, Line%Fnet + END IF + + EXIT + END IF + END DO + + + ! ! add force and mass of end nodes to the Connects they correspond to <<<<<<<<<<<< do this from Connection instead now! + ! DO J = 1,3 + ! FairFtot(J) = FairFtot(J) + Line%F(J,N) + ! AnchFtot(J) = AnchFtot(J) + Line%F(J,0) + ! DO K = 1,3 + ! FairMtot(K,J) = FairMtot(K,J) + Line%M(K,J,N) + ! AnchMtot(K,J) = AnchMtot(K,J) + Line%M(K,J,0) + ! END DO + ! END DO + + END SUBROUTINE Line_GetStateDeriv + !===================================================================== + + + !-------------------------------------------------------------- + SUBROUTINE Line_SetEndKinematics(Line, r_in, rd_in, t, topOfLine) + + TYPE(MD_Line), INTENT(INOUT) :: Line ! the current Line object + Real(DbKi), INTENT(IN ) :: r_in( 3) ! state vector section for this line + Real(DbKi), INTENT(IN ) :: rd_in(3) ! state vector section for this line + Real(DbKi), INTENT(IN ) :: t ! instantaneous time + INTEGER(IntKi), INTENT(IN ) :: topOfLine ! 0 for end A (Node 0), 1 for end B (node N) + + Integer(IntKi) :: I,J + INTEGER(IntKi) :: inode + + IF (topOfLine==1) THEN + inode = Line%N + Line%endTypeB = 0 ! set as ball rather than rigid connection (unless changed later by SetEndOrientation) + ELSE + inode = 0 + Line%endTypeA = 0 ! set as ball rather than rigid connection (unless changed later by SetEndOrientation) + END IF + + !Line%r( :,inode) = r_in + !Line%rd(:,inode) = rd_in + + DO J = 1,3 + Line%r( :,inode) = r_in + Line%rd(:,inode) = rd_in + END DO + + ! print *, "SetEndKinematics of line ", Line%idNum, " top?:", topOfLine + ! print *, r_in + ! print *, Line%r( :,inode), " - confirming, node ", inode + ! print *, rd_in + + Line%time = t + + END SUBROUTINE Line_SetEndKinematics + !-------------------------------------------------------------- + + + ! get force, moment, and mass of line at line end node + !-------------------------------------------------------------- + SUBROUTINE Line_GetEndStuff(Line, Fnet_out, Moment_out, M_out, topOfLine) + + TYPE(MD_Line), INTENT(INOUT) :: Line ! label for the current line, for convenience + REAL(DbKi), INTENT( OUT) :: Fnet_out(3) ! net force on end node + REAL(DbKi), INTENT( OUT) :: Moment_out(3) ! moment on end node (future capability) + REAL(DbKi), INTENT( OUT) :: M_out(3,3) ! mass matrix of end node + INTEGER(IntKi), INTENT(IN ) :: topOfLine ! 0 for end A (Node 0), 1 for end B (node N) + + Integer(IntKi) :: I,J + INTEGER(IntKi) :: inode + + IF (topOfLine==1) THEN ! end B of line + Fnet_out = Line%Fnet(:, Line%N) + Moment_out = Line%endMomentB + M_out = Line%M(:,:, Line%N) + ELSE ! end A of line + Fnet_out = Line%Fnet(:, 0) + Moment_out = Line%endMomentA + M_out = Line%M(:,:, 0) + END IF + + END SUBROUTINE Line_GetEndStuff + !-------------------------------------------------------------- + + ! Get bending stiffness vector from line end for use in computing orientation of zero-length rods + !-------------------------------------------------------------- + SUBROUTINE Line_GetEndSegmentInfo(Line, q_EI_dl, topOfLine, rodEndB) + + TYPE(MD_Line), INTENT(INOUT) :: Line ! label for the current line, for convenience + REAL(DbKi), INTENT( OUT) :: q_EI_dl(3) ! EI/dl of the line end segment multiplied by the axis unit vector with the correct sign + INTEGER(IntKi), INTENT(IN ) :: topOfLine ! 0 for end A (Node 0), 1 for end B (node N) + INTEGER(IntKi), INTENT(IN ) :: rodEndB ! rodEndB=0 means the line is attached to Rod end A, =1 means attached to Rod end B (implication for unit vector sign) + + REAL(DbKi) :: qEnd(3) + REAL(DbKi) :: dlEnd + + if (topOfLine==1) then + CALL UnitVector(Line%r(:,Line%N-1), Line%r(:,Line%N), qEnd, dlEnd) ! unit vector of last line segment + if (rodEndB == 0) then + q_EI_dl = qEnd*Line%EI/dlEnd ! -----line----->[A==ROD==>B] + else + q_EI_dl = -qEnd*Line%EI/dlEnd ! -----line----->[B==ROD==>A] + end if + else + CALL UnitVector(Line%r(:,0 ), Line%r(:,1 ), qEnd, dlEnd) ! unit vector of first line segment + if (rodEndB == 0) then + q_EI_dl = -qEnd*Line%EI/dlEnd ! <----line-----[A==ROD==>B] + else + q_EI_dl = qEnd*Line%EI/dlEnd ! <----line-----[B==ROD==>A] + end if + end if + + END SUBROUTINE Line_GetEndSegmentInfo + !-------------------------------------------------------------- + + + ! set end node unit vector of a line (this is called when attached to a Rod, only applicable for bending stiffness) + !-------------------------------------------------------------- + SUBROUTINE Line_SetEndOrientation(Line, qin, topOfLine, rodEndB) + + TYPE(MD_Line), INTENT(INOUT) :: Line ! label for the current line, for convenience + REAL(DbKi), INTENT(IN ) :: qin(3) ! the rod's axis unit vector + INTEGER(IntKi), INTENT(IN ) :: topOfLine ! 0 for end A (Node 0), 1 for end B (node N) + INTEGER(IntKi), INTENT(IN ) :: rodEndB ! =0 means the line is attached to Rod end A, =1 means attached to Rod end B (implication for unit vector sign) + + if (topOfLine==1) then + + Line%endTypeB = 1 ! indicate attached to Rod (at every time step, just in case line gets detached) + + if (rodEndB==1) then + Line%q(:,Line%N) = -qin ! -----line----->[B<==ROD==A] + else + Line%q(:,Line%N) = qin ! -----line----->[A==ROD==>B] + end if + else + + Line%endTypeA = 1 ! indicate attached to Rod (at every time step, just in case line gets detached) ! indicate attached to Rod + + if (rodEndB==1) then + Line%q(:,0 ) = qin ! [A==ROD==>B]-----line-----> + else + Line%q(:,0 ) = -qin ! [B<==ROD==A]-----line-----> + end if + end if + + END SUBROUTINE Line_SetEndOrientation + !-------------------------------------------------------------- + + +END MODULE MoorDyn_Line diff --git a/modules/moordyn/src/MoorDyn_Misc.f90 b/modules/moordyn/src/MoorDyn_Misc.f90 new file mode 100644 index 000000000..90cb049d1 --- /dev/null +++ b/modules/moordyn/src/MoorDyn_Misc.f90 @@ -0,0 +1,2110 @@ +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2020-2021 Alliance for Sustainable Energy, LLC +! Copyright (C) 2015-2019 Matthew Hall +! +! This file is part of MoorDyn. +! +! 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 MoorDyn_Misc + + USE MoorDyn_Types + USE NWTC_Library + USE NWTC_FFTPACK + + IMPLICIT NONE + + PRIVATE + + INTEGER(IntKi), PARAMETER :: wordy = 0 ! verbosity level. >1 = more console output + + PUBLIC :: UnitVector + PUBLIC :: ScaleVector + PUBLIC :: GetCurvature + PUBLIC :: GetOrientationAngles + PUBLIC :: TransformKinematics + PUBLIC :: TransformKinematicsA + PUBLIC :: TransformKinematicsAtoB + PUBLIC :: TranslateForce3to6DOF + PUBLIC :: TranslateMass3to6DOF + PUBLIC :: TranslateMass6to6DOF + PUBLIC :: GetH + PUBLIC :: RotateM6 + PUBLIC :: RotateM3 + PUBLIC :: CalcOrientation + PUBLIC :: Inverse3by3 + PUBLIC :: LUsolve + + PUBLIC :: getInterpNums + PUBLIC :: calculate4Dinterpolation + PUBLIC :: calculate3Dinterpolation + PUBLIC :: calculate2Dinterpolation + + PUBLIC :: getDepthFromBathymetry + + PUBLIC :: getWaterKin + PUBLIC :: setupWaterKin + +CONTAINS + + + ! ::::::::::::::::::::::::::::::::: math convenience functions :::::::::::::::::::::::::::::::::: + ! should add error checking if I keep these, but hopefully there are existing NWTCLib functions to replace them + + ! return unit vector (u) and in direction from r1 to r2 and distance between points + !----------------------------------------------------------------------- + SUBROUTINE UnitVector( r1, r2, u, Length ) ! note: order of parameters chagned in this function + + REAL(DbKi), INTENT(IN ) :: r1(:) + REAL(DbKi), INTENT(IN ) :: r2(:) + REAL(DbKi), INTENT( OUT) :: u(:) + REAL(DbKi), INTENT( OUT) :: length + + u = r2 - r1 + length = TwoNorm(u) + + if ( .NOT. EqualRealNos(length, 0.0_DbKi ) ) THEN + u = u / Length + END IF + + END SUBROUTINE UnitVector + !----------------------------------------------------------------------- + + ! scale vector to desired length + !----------------------------------------------------------------------- + SUBROUTINE ScaleVector( u_in, newlength, u_out ) + REAL(DbKi), INTENT(IN ) :: u_in(3) ! input vector + REAL(DbKi), INTENT(IN ) :: newlength ! desired length of output vector + REAL(DbKi), INTENT(INOUT) :: u_out(3) ! output vector (hopefully can be the same as u_in without issue) + + REAL(DbKi) :: length_squared + REAL(DbKi) :: scaler + INTEGER(IntKi) :: J + + length_squared = 0.0; + DO J=1,3 + length_squared = length_squared + u_in(J)*u_in(J) + END DO + + if (length_squared > 0) then + scaler = newlength/sqrt(length_squared) + else ! if original vector is zero, return zero + scaler = 0.0_DbKi + end if + + DO J=1,3 + u_out(J) = u_in(J) * scaler + END DO + + END SUBROUTINE ScaleVector + !----------------------------------------------------------------------- + + + ! convenience function to calculate curvature based on adjacent segments' direction vectors and their combined length + function GetCurvature(length, q1, q2) + + real(DbKi), intent(in ) :: length + real(DbKi), intent(in ) :: q1(3) + real(DbKi), intent(in ) :: q2(3) + real(DbKi) :: GetCurvature + + + real(DbKi) :: q1_dot_q2 + + ! note "length" here is combined from both segments + + q1_dot_q2 = dot_product( q1, q2 ) + + if (q1_dot_q2 > 1.0) then ! this is just a small numerical error, so set q1_dot_q2 to 1 + GetCurvature = 0.0_DbKi ! this occurs when there's no curvature, so return zero curvature + + !else if (q1_dot_q2 < 0) ! this is a bend of more than 90 degrees, too much, call an error! + + else ! normal case + GetCurvature = 4.0/length * sqrt(0.5*(1.0 - q1_dot_q2)) ! this is the normal curvature calculation + end if + + return + end function GetCurvature + + + ! calculate orientation angles of a direction vector + !----------------------------------------------------------------------- + subroutine GetOrientationAngles(vec, phi, sinPhi, cosPhi, tanPhi, beta, sinBeta, cosBeta, k_hat) + real(DbKi), intent(in ) :: vec(3) !p1(3),p2(3) + real(DbKi), intent( out) :: phi, sinPhi, cosPhi, tanPhi, beta, sinBeta, cosBeta, k_hat(3) + + real(DbKi) :: vecLen, vecLen2D + + vecLen = SQRT(Dot_Product(vec,vec)) + vecLen2D = SQRT(vec(1)**2+vec(2)**2) + if ( vecLen < 0.000001 ) then + print *, "ERROR in GetOrientationAngles in MoorDyn. Supplied vector is near zero" + print *, vec + k_hat = NaN ! 1.0/0.0 + else + k_hat = vec / vecLen + phi = atan2(vecLen2D, vec(3)) ! incline angle + end if + if ( phi < 0.000001) 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 + !----------------------------------------------------------------------- + + + ! calculate position and velocity of point based on its position relative to moving 6DOF body + !----------------------------------------------------------------------- + SUBROUTINE TransformKinematics(rRelBody, r_in, TransMat, rd_in, r_out, rd_out) + REAL(DbKi), INTENT(IN ) :: rRelBody(:) ! coordinate of end A + REAL(DbKi), INTENT(IN ) :: r_in(3) ! Rod unit vector + REAL(DbKi), INTENT(IN ) :: TransMat(3,3)! + REAL(DbKi), INTENT(IN ) :: rd_in(6) ! 6DOF velecity vector about Rod end A, in global orientation frame + REAL(DbKi), INTENT( OUT) :: r_out(3) ! coordinates of end B + REAL(DbKi), INTENT( OUT) :: rd_out(3) ! velocity of end B + + REAL(DbKi) :: rRel(3) + + ! rd_in should be in global orientation frame + ! note: it's okay if r_out and rd_out are 6-size. Only the first 3 will be written, and 4-6 will + ! already be correct or can be assigned seperately from r_in and rd_in (assuming orientation frames are identical) + + + ! locations (unrotated reference frame) about platform reference point (2021-01-05: just transposed TransMat, it was incorrect before) + rRel(1) = TransMat(1,1)*rRelBody(1) + TransMat(1,2)*rRelBody(2) + TransMat(1,3)*rRelBody(3) ! x + rRel(2) = TransMat(2,1)*rRelBody(1) + TransMat(2,2)*rRelBody(2) + TransMat(2,3)*rRelBody(3) ! y + rRel(3) = TransMat(3,1)*rRelBody(1) + TransMat(3,2)*rRelBody(2) + TransMat(3,3)*rRelBody(3) ! z + + ! absolute locations + r_out = rRel + r_in + + ! absolute velocities + rd_out(1) = - rd_in(6)*rRel(2) + rd_in(5)*rRel(3) + rd_in(1) ! x + rd_out(2) = rd_in(6)*rRel(1) - rd_in(4)*rRel(3) + rd_in(2) ! y + rd_out(3) = -rd_in(5)*rRel(1) + rd_in(4)*rRel(2) + rd_in(3) ! z + + ! absolute accelerations + rd_out(1) = - rd_in(6)*rRel(2) + rd_in(5)*rRel(3) + rd_in(1) ! x + rd_out(2) = rd_in(6)*rRel(1) - rd_in(4)*rRel(3) + rd_in(2) ! y + rd_out(3) = -rd_in(5)*rRel(1) + rd_in(4)*rRel(2) + rd_in(3) ! z + + + + !rRel = MATMUL(TransMat, rRelBody) + !H = getH(rRel) + !! absolute locations + !r_out = rRel + r_in + !! absolute velocities + !rd_out = MATMUL( H, rd_in(4:6)) + rd_in(1:3) + + + END SUBROUTINE TransformKinematics + !----------------------------------------------------------------------- + + + + ! calculate position, velocity, and acceleration of point based on its position relative to moving 6DOF body + !----------------------------------------------------------------------- + SUBROUTINE TransformKinematicsA(rRelBody, r_in, TransMat, v_in, a_in, r_out, v_out, a_out) + REAL(DbKi), INTENT(IN ) :: rRelBody(:) ! relative location of point about reference point, in local/reference coordinate system + REAL(DbKi), INTENT(IN ) :: r_in(3) ! translation applied to reference point + REAL(DbKi), INTENT(IN ) :: TransMat(3,3)! rotation matrix describing rotation about reference point + REAL(DbKi), INTENT(IN ) :: v_in(6) ! 6DOF velecity vector about ref point in global orientation frame + REAL(DbKi), INTENT(IN ) :: a_in(6) ! 6DOF acceleration vector + REAL(DbKi), INTENT( OUT) :: r_out(3) ! coordinates of point of interest + REAL(DbKi), INTENT( OUT) :: v_out(3) ! velocity of point + REAL(DbKi), INTENT( OUT) :: a_out(3) ! acceleration of point + + REAL(DbKi) :: rRel(3) + REAL(DbKi) :: rRel2(3) + + REAL(DbKi) :: r_out2(3) + REAL(DbKi) :: rd_out2(3) + REAL(DbKi) :: H(3,3) + + ! rd_in should be in global orientation frame + ! note: it's okay if r_out and rd_out are 6-size. Only the first 3 will be written, and 4-6 will + ! already be correct or can be assigned seperately from r_in and rd_in (assuming orientation frames are identical) + + + ! locations about ref point in *unrotated* reference frame + !rRel2(1) = TransMat(1,1)*rRelBody(1) + TransMat(2,1)*rRelBody(2) + TransMat(3,1)*rRelBody(3) ! x + !rRel2(2) = TransMat(1,2)*rRelBody(1) + TransMat(2,2)*rRelBody(2) + TransMat(3,2)*rRelBody(3) ! y + !rRel2(3) = TransMat(1,3)*rRelBody(1) + TransMat(2,3)*rRelBody(2) + TransMat(3,3)*rRelBody(3) ! z + + rRel = MATMUL(TransMat, rRelBody) + + H = getH(rRel) + + ! absolute locations + r_out = rRel + r_in + + ! absolute velocities + !rd_out2(1) = - v_in(6)*rRel(2) + v_in(5)*rRel(3) + v_in(1) ! x + !rd_out2(2) = v_in(6)*rRel(1) - v_in(4)*rRel(3) + v_in(2) ! y + !rd_out2(3) = -v_in(5)*rRel(1) + v_in(4)*rRel(2) + v_in(3) ! z + + v_out = MATMUL( H, v_in(4:6)) + v_in(1:3) + + ! absolute accelerations + a_out = MATMUL( H, a_in(4:6)) + a_in(1:3) ! << should add second order terms! + + + END SUBROUTINE TransformKinematicsA + !----------------------------------------------------------------------- + + ! calculate position and velocity of point along rod (distance L along direction u) + !----------------------------------------------------------------------- + SUBROUTINE TransformKinematicsAtoB(rA, u, L, rd_in, r_out, rd_out) + REAL(DbKi), INTENT(IN ) :: rA(3) ! coordinate of end A + REAL(DbKi), INTENT(IN ) :: u(3) ! Rod unit vector + REAL(DbKi), INTENT(IN ) :: L ! Rod length from end A to B + REAL(DbKi), INTENT(IN ) :: rd_in(6) ! 6DOF velecity vector about Rod end A, in global orientation frame + REAL(DbKi), INTENT( OUT) :: r_out(3) ! coordinates of end B + REAL(DbKi), INTENT( OUT) :: rd_out(3) ! velocity of end B + + REAL(DbKi) :: rRel(3) + + + ! locations (unrotated reference frame) + rRel = L*u ! relative location of point B from point A + r_out = rRel + rA ! absolute location of point B + + ! absolute velocities + rd_out(1) = - rd_in(6)*rRel(2) + rd_in(5)*rRel(3) + rd_in(1) ! x + rd_out(2) = rd_in(6)*rRel(1) - rd_in(4)*rRel(3) + rd_in(2) ! y + rd_out(3) = -rd_in(5)*rRel(1) + rd_in(4)*rRel(2) + rd_in(3) ! z + + + END SUBROUTINE TransformKinematicsAtoB + !----------------------------------------------------------------------- + + ! + !----------------------------------------------------------------------- + SUBROUTINE TranslateForce3to6DOF(dx, F, Fout) + REAL(DbKi), INTENT(IN ) :: dx(3) ! displacement vector from ref point to point of force (F) application + REAL(DbKi), INTENT(IN ) :: F(3) ! applied force + REAL(DbKi), INTENT( OUT) :: Fout(6) ! resultant applied force and moment about ref point + + Fout(1:3) = F + + Fout(4:6) = CROSS_PRODUCT(dx, F) + + END SUBROUTINE TranslateForce3to6DOF + !----------------------------------------------------------------------- + + + ! + !----------------------------------------------------------------------- + SUBROUTINE TranslateMass3to6DOF(dx, Min, Mout) + REAL(DbKi), INTENT(IN ) :: dx(3) ! displacement vector from ref point to point of mass matrix (Min) + REAL(DbKi), INTENT(IN ) :: Min( 3,3) ! original mass matrix (assumed at center of mass, or a point mass) + REAL(DbKi), INTENT( OUT) :: Mout(6,6) ! resultant mass and inertia matrix about ref point + + REAL(DbKi) :: H( 3,3) ! "anti-symmetric tensor components" from Sadeghi and Incecik + REAL(DbKi) :: tempM( 3,3) + REAL(DbKi) :: tempM2(3,3) + REAL(DbKi) :: Htrans(3,3) + Integer(IntKi) :: I,J + + ! sub-matrix definitions are accordint to | m J | + ! | J^T I | + + H = getH(dx); + + ! mass matrix [m'] = [m] + Mout(1:3,1:3) = Min + + ! product of inertia matrix [J'] = [m][H] + [J] + Mout(1:3,4:6) = MATMUL(Min, H) + Mout(4:6,1:3) = TRANSPOSE(Mout(1:3,4:6)) + + !moment of inertia matrix [I'] = [H][m][H]^T + [J]^T [H] + [H]^T [J] + [I] + Mout(4:6,4:6) = MATMUL(MATMUL(H, Min), TRANSPOSE(H)) + + END SUBROUTINE TranslateMass3to6DOF + !----------------------------------------------------------------------- + + ! + !----------------------------------------------------------------------- + SUBROUTINE TranslateMass6to6DOF(dx, Min, Mout) + REAL(DbKi), INTENT(IN ) :: dx(3) ! displacement vector from ref point to point of mass matrix (Min) + REAL(DbKi), INTENT(IN ) :: Min( 6,6) ! original mass matrix + REAL(DbKi), INTENT( OUT) :: Mout(6,6) ! resultant mass and inertia matrix about ref point + + REAL(DbKi) :: H( 3,3) ! "anti-symmetric tensor components" from Sadeghi and Incecik + + H = getH(dx); + + ! mass matrix [m'] = [m] + Mout(1:3,1:3) = Min(1:3,1:3) + + ! product of inertia matrix [J'] = [m][H] + [J] + Mout(1:3,4:6) = MATMUL(Min(1:3,1:3), H) + Min(1:3,4:6) + Mout(4:6,1:3) = TRANSPOSE(Mout(1:3,4:6)) + + !moment of inertia matrix [I'] = [H][m][H]^T + [J]^T [H] + [H]^T [J] + [I] + Mout(4:6,4:6) = MATMUL(MATMUL(H, Min(1:3,1:3)), TRANSPOSE(H)) + MATMUL(Min(4:6,1:3),H) + MATMUL(TRANSPOSE(H),Min(1:3,4:6)) + Min(4:6,4:6) + + END SUBROUTINE TranslateMass6to6DOF + !----------------------------------------------------------------------- + + ! produce alternator matrix + !----------------------------------------------------------------------- + FUNCTION GetH(r) + Real(DbKi), INTENT(IN) :: r(3) ! inputted vector + Real(DbKi) :: GetH(3,3) ! outputted matrix + + GetH(2,1) = -r(3) + GetH(1,2) = r(3) + GetH(3,1) = r(2) + GetH(1,3) = -r(2) + GetH(3,2) = -r(1) + GetH(2,3) = r(1) + + GetH(1,1) = 0.0_DbKi + GetH(2,2) = 0.0_DbKi + GetH(3,3) = 0.0_DbKi + + END FUNCTION GetH + !----------------------------------------------------------------------- + + + + ! apply a rotation to a 6-by-6 mass/inertia tensor (see Sadeghi and Incecik 2005 for theory) + !----------------------------------------------------------------------- + FUNCTION RotateM6(Min, rotMat) result(outMat) + + Real(DbKi), INTENT(IN) :: Min(6,6) ! inputted matrix to be rotated + Real(DbKi), INTENT(IN) :: rotMat(3,3) ! rotation matrix (DCM) + Real(DbKi) :: outMat(6,6) ! rotated matrix + + ! the process for each of the following is to + ! 1. copy out the relevant 3x3 matrix section, + ! 2. rotate it, and + ! 3. paste it into the output 6x6 matrix + + ! mass matrix + outMat(1:3,1:3) = rotateM3(Min(1:3,1:3), rotMat) + + ! product of inertia matrix + outMat(1:3,4:6) = rotateM3(Min(1:3,4:6), rotMat) + outMat(4:6,1:3) = TRANSPOSE(outMat(1:3,4:6)) + + ! moment of inertia matrix + outMat(4:6,4:6) = rotateM3(Min(4:6,4:6), rotMat) + + END FUNCTION RotateM6 + + + ! apply a rotation to a 3-by-3 mass matrix or any other second order tensor + !----------------------------------------------------------------------- + FUNCTION RotateM3(Min, rotMat) result(outMat) + + Real(DbKi), INTENT(IN) :: Min(3,3) ! inputted matrix to be rotated + Real(DbKi), INTENT(IN) :: rotMat(3,3) ! rotation matrix (DCM) + Real(DbKi) :: outMat(3,3) ! rotated matrix + + ! overall operation is [m'] = [a]*[m]*[a]^T + + outMat = MATMUL( MATMUL(rotMat, Min), TRANSPOSE(rotMat) ) + + END FUNCTION RotateM3 + + + + + + ! calculates rotation matrix R to rotate from global axes to a member's local axes + !----------------------------------------------------------------------- + FUNCTION CalcOrientation(phi, beta, gamma) result(R) + + REAL(DbKi), INTENT ( IN ) :: phi ! member incline angle + REAL(DbKi), INTENT ( IN ) :: beta ! member incline heading + REAL(DbKi), INTENT ( IN ) :: gamma ! member twist angle + REAL(DbKi) :: R(3,3) ! rotation matrix + + INTEGER(IntKi) :: errStat + CHARACTER(100) :: errMsg + + REAL(DbKi) :: s1, c1, s2, c2, s3, c3 + + + ! trig terms for Euler angles rotation based on beta, phi, and gamma + s1 = sin(beta) + c1 = cos(beta) + s2 = sin(phi) + c2 = cos(phi) + s3 = sin(gamma) + c3 = cos(gamma) + + ! calculate rotation matrix based on Z1Y2Z3 Euler rotation sequence from https:!en.wikipedia.org/wiki/Euler_angles#Rotation_matrix + + R(1,1) = c1*c2*c3-s1*s3 + R(1,2) = -c3*s1-c1*c2*s3 + R(1,3) = c1*s2 + R(2,1) = c1*s3+c2*c3*s1 + R(2,2) = c1*c3-c2*s1*s3 + R(2,3) = s1*s2 + R(3,1) = -c3*s2 + R(3,2) = s2*s3 + R(3,3) = c2 + + ! could also calculate unit normals p1 and p2 for rectangular cross sections + !p1 = matmul( R, [1,0,0] ) ! unit vector that is perpendicular to the 'beta' plane if gamma is zero + !p2 = cross( q, p1 ) ! unit vector orthogonal to both p1 and q + + END FUNCTION CalcOrientation + + + !compute the inverse of a 3-by-3 matrix m + !----------------------------------------------------------------------- + SUBROUTINE Inverse3by3( Minv, M ) + Real(DbKi), INTENT(OUT) :: Minv(3,3) ! returned inverse matrix + Real(DbKi), INTENT(IN) :: M(3,3) ! inputted matrix + + 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)) + & + M(1, 3) * (M(2, 1) * M(3, 2) - M(2, 2) * M(3, 1)); + + invdet = 1.0 / det ! because multiplying is faster than dividing + + Minv(1, 1) = (M(2, 2) * M(3, 3) - M(3, 2) * M(2, 3)) * invdet + Minv(1, 2) = (M(1, 3) * M(3, 2) - M(1, 2) * M(3, 3)) * invdet + Minv(1, 3) = (M(1, 2) * M(2, 3) - M(1, 3) * M(2, 2)) * invdet + Minv(2, 1) = (M(2, 3) * M(3, 1) - M(2, 1) * M(3, 3)) * invdet + Minv(2, 2) = (M(1, 1) * M(3, 3) - M(1, 3) * M(3, 1)) * invdet + Minv(2, 3) = (M(2, 1) * M(1, 3) - M(1, 1) * M(2, 3)) * invdet + Minv(3, 1) = (M(2, 1) * M(3, 2) - M(3, 1) * M(2, 2)) * invdet + Minv(3, 2) = (M(3, 1) * M(1, 2) - M(1, 1) * M(3, 2)) * invdet + Minv(3, 3) = (M(1, 1) * M(2, 2) - M(2, 1) * M(1, 2)) * invdet + + END SUBROUTINE Inverse3by3 + !----------------------------------------------------------------------- + + + ! One-function implementation of Crout LU Decomposition. Solves Ax=b for x + SUBROUTINE LUsolve(n, A, LU, b, y, x) + + INTEGER(intKi), INTENT(IN ) :: n ! size of matrices and vectors + Real(DbKi), INTENT(IN ) :: A( n,n) ! LHS matrix (e.g. mass matrix) + Real(DbKi), INTENT(INOUT) :: LU(n,n) ! stores LU matrix data + Real(DbKi), INTENT(IN ) :: b(n) ! RHS vector + Real(DbKi), INTENT(INOUT) :: y(n) ! temporary vector + Real(DbKi), INTENT( OUT) :: x(n) ! LHS vector to solve for + + INTEGER(intKi) :: i,j,k,p + Real(DbKi) :: sum + + DO k = 1,n + DO i = k,n + + sum = 0.0_DbKi + + DO p=1,k-1 !for(int p=0; p=0; --i) + + sum = 0.0_DbKi + + DO k=i+1, n + sum = sum + LU(i,k)*x(k) + END DO + + x(i) = (y(i)-sum) + + END DO !j (actually decrementing i) + + END SUBROUTINE LUsolve + + + + ! :::::::::::::::::::::::::: interpolation subroutines ::::::::::::::::::::::::::::::: + + + SUBROUTINE getInterpNums(xlist, xin, istart, i, fout) + + Real(DbKi), INTENT (IN ) :: xlist(:) ! list of x values + Real(DbKi), INTENT (IN ) :: xin ! x value to be interpolated + Integer(IntKi),INTENT (IN ) :: istart ! first lower index to try + Integer(IntKi),INTENT ( OUT) :: i ! lower index to interpolate from + Real(DbKi), INTENT ( OUT) :: fout ! fraction to return such that y* = y[i] + fout*(y[i+1]-y[i]) + + Integer(IntKi) :: i1 + Integer(IntKi) :: nx + + i1 = 1 ! Setting in declaration causes an implied save, which would never allow this routine to find anything at the start of the array. + + nx = SIZE(xlist) + + if (xin <= xlist(1)) THEN ! below lowest data point + i = 1_IntKi + fout = 0.0_DbKi + + else if (xlist(nx) <= xin) THEN ! above highest data point + i = nx + fout = 0.0_DbKi + + else ! within the data range + + IF (xlist(min(istart,nx)) < xin) i1 = istart ! if istart is below the actual value, start with it instead of starting at 1 to save time, but make sure it doesn't overstep the array + + DO i = i1, nx-1 + IF (xlist(i+1) > xin) THEN + fout = (xin - xlist(i) )/( xlist(i+1) - xlist(i) ) + exit + END IF + END DO + END IF + + END SUBROUTINE getInterpNums + + + SUBROUTINE getInterpNumsSiKi(xlist, xin, istart, i, fout) + + Real(SiKi), INTENT (IN ) :: xlist(:) ! list of x values + Real(SiKi), INTENT (IN ) :: xin ! x value to be interpolated + Integer(IntKi),INTENT (IN ) :: istart ! first lower index to try + Integer(IntKi),INTENT ( OUT) :: i ! lower index to interpolate from + Real(SiKi), INTENT ( OUT) :: fout ! fraction to return such that y* = y[i] + fout*(y[i+1]-y[i]) + + Integer(IntKi) :: i1 + Integer(IntKi) :: nx + + i1 = 1 ! Setting in declaration causes an implied save, which would never allow this routine to find anything at the start of the array. + + nx = SIZE(xlist) + + if (xin <= xlist(1)) THEN ! below lowest data point + i = 1_IntKi + fout = 0.0_SiKi + + else if (xlist(nx) <= xin) THEN ! above highest data point + i = nx + fout = 0.0_SiKi + + else ! within the data range + + IF (xlist(min(istart,nx)) < xin) i1 = istart ! if istart is below the actual value, start with it instead of starting at 1 to save time, but make sure it doesn't overstep the array + + DO i = i1, nx-1 + IF (xlist(i+1) > xin) THEN + fout = (xin - xlist(i) )/( xlist(i+1) - xlist(i) ) + exit + END IF + END DO + END IF + + END SUBROUTINE getInterpNumsSiKi + + SUBROUTINE calculate4Dinterpolation(f, ix0, iy0, iz0, it0, fx, fy, fz, ft, c) + + Real(SiKi), INTENT (IN ) :: f(:,:,:,:) ! data array + INTEGER(IntKi), INTENT (IN ) :: ix0, iy0, iz0, it0 ! indices for interpolation + Real(SiKi), INTENT (IN ) :: fx, fy, fz, ft ! interpolation fractions + Real(DbKi), INTENT ( OUT) :: c ! the output value + + INTEGER(IntKi) :: ix1, iy1, iz1, it1 ! second indices + REAL(SiKi) :: c000, c001, c010, c011, c100, c101, c110, c111 + REAL(SiKi) :: c00, c01, c10, c11, c0, c1 + + ! handle end case conditions + if (fx == 0) then + ix1 = ix0 + else + ix1 = min(ix0+1,size(f,4)) ! don't overstep bounds + end if + + if (fy == 0) then + iy1 = iy0 + else + iy1 = min(iy0+1,size(f,3)) ! don't overstep bounds + end if + + if (fz == 0) then + iz1 = iz0 + else + iz1 = min(iz0+1,size(f,2)) ! don't overstep bounds + end if + + if (ft == 0) then + it1 = it0 + else + it1 = min(it0+1,size(f,1)) ! don't overstep bounds + end if + + c000 = f(it0,iz0,iy0,ix0)*(1.0-ft) + f(it1,iz0,iy0,ix0)*ft + c001 = f(it0,iz1,iy0,ix0)*(1.0-ft) + f(it1,iz1,iy0,ix0)*ft + c010 = f(it0,iz0,iy1,ix0)*(1.0-ft) + f(it1,iz0,iy1,ix0)*ft + c011 = f(it0,iz1,iy1,ix0)*(1.0-ft) + f(it1,iz1,iy1,ix0)*ft + c100 = f(it0,iz0,iy0,ix1)*(1.0-ft) + f(it1,iz0,iy0,ix1)*ft + c101 = f(it0,iz1,iy0,ix1)*(1.0-ft) + f(it1,iz1,iy0,ix1)*ft + c110 = f(it0,iz0,iy1,ix1)*(1.0-ft) + f(it1,iz0,iy1,ix1)*ft + c111 = f(it0,iz1,iy1,ix1)*(1.0-ft) + f(it1,iz1,iy1,ix1)*ft + + c00 = c000*(1.0-fx) + c100*fx + c01 = c001*(1.0-fx) + c101*fx + c10 = c010*(1.0-fx) + c110*fx + c11 = c011*(1.0-fx) + c111*fx + + c0 = c00 *(1.0-fy) + c10 *fy + c1 = c01 *(1.0-fy) + c11 *fy + + c = c0 *(1.0-fz) + c1 *fz + + END SUBROUTINE + + + SUBROUTINE calculate3Dinterpolation(f, ix0, iy0, iz0, fx, fy, fz, c) + + Real(SiKi), INTENT (IN ) :: f(:,:,:) ! data array + INTEGER(IntKi), INTENT (IN ) :: ix0, iy0, iz0 ! indices for interpolation + Real(SiKi), INTENT (IN ) :: fx, fy, fz ! interpolation fractions + Real(DbKi), INTENT ( OUT) :: c ! the output value + + INTEGER(IntKi) :: ix1, iy1, iz1 ! second indices + REAL(SiKi) :: c000, c001, c010, c011, c100, c101, c110, c111 + REAL(SiKi) :: c00, c01, c10, c11, c0, c1 + + ! note that "z" could also be "t" - dimension names are arbitrary + + ! handle end case conditions + if (fx == 0) then + ix1 = ix0 + else + ix1 = min(ix0+1,size(f,3)) ! don't overstep bounds + end if + + if (fy == 0) then + iy1 = iy0 + else + iy1 = min(iy0+1,size(f,2)) ! don't overstep bounds + end if + + if (fz == 0) then + iz1 = iz0 + else + iz1 = min(iz0+1,size(f,1)) ! don't overstep bounds + end if + + c000 = f(iz0,iy0,ix0) + c001 = f(iz1,iy0,ix0) + c010 = f(iz0,iy1,ix0) + c011 = f(iz1,iy1,ix0) + c100 = f(iz0,iy0,ix1) + c101 = f(iz1,iy0,ix1) + c110 = f(iz0,iy1,ix1) + c111 = f(iz1,iy1,ix1) + + c00 = c000*(1.0-fx) + c100*fx + c01 = c001*(1.0-fx) + c101*fx + c10 = c010*(1.0-fx) + c110*fx + c11 = c011*(1.0-fx) + c111*fx + + c0 = c00 *(1.0-fy) + c10 *fy + c1 = c01 *(1.0-fy) + c11 *fy + + c = c0 *(1.0-fz) + c1 *fz + + END SUBROUTINE + + SUBROUTINE calculate2Dinterpolation(f, ix0, iy0, fx, fy, c) + REAL(DbKi), INTENT (IN ) :: f(:,:) ! data array + INTEGER(IntKi), INTENT (IN ) :: ix0, iy0 ! indices for interpolation + REAL(DbKi), INTENT (IN ) :: fx, fy ! interpolation fractions + REAL(DbKi), INTENT ( OUT) :: c ! the output value + + INTEGER(IntKi) :: ix1, iy1 ! second indices + REAL(DbKi) :: c00, c01, c10, c11, c0, c1 + + ! handle end case conditions + IF (fx == 0) THEN + ix1 = ix0 + ELSE + ix1 = min(ix0+1,size(f,2)) ! don't overstep bounds + END IF + IF (fy == 0) THEN + iy1 = iy0 + ELSE + iy1 = min(iy0+1,size(f,1)) ! don't overstep bounds + END IF + c00 = f(iy0, ix0) + c01 = f(iy1, ix0) + c10 = f(iy0, ix1) + c11 = f(iy1, ix1) + c0 = c00 *(1.0-fx) + c10 *fx + c1 = c01 *(1.0-fx) + c11 *fx + c = c0 *(1.0-fy) + c1 *fy + END SUBROUTINE calculate2Dinterpolation + + + SUBROUTINE calculate1Dinterpolation(f, ix0, fx, c) + REAL(DbKi), INTENT (IN ) :: f(:) ! data array + INTEGER(IntKi), INTENT (IN ) :: ix0 ! indices for interpolation + REAL(DbKi), INTENT (IN ) :: fx ! interpolation fractions + REAL(DbKi), INTENT ( OUT) :: c ! the output value + + INTEGER(IntKi) :: ix1 ! second index + REAL(DbKi) :: c0, c1 + + ! handle end case conditions + IF (fx == 0) THEN + ix1 = ix0 + ELSE + ix1 = min(ix0+1,size(f,1)) ! don't overstep bounds + END IF + + c0 = f(ix0) + c1 = f(ix1) + c = c0*(1.0-fx) + c1*fx + END SUBROUTINE calculate1Dinterpolation + + + + + ! :::::::::::::::::::::::::: bathymetry subroutines ::::::::::::::::::::::::::::::: + + ! interpolates local seabed depth and normal vector + SUBROUTINE getDepthFromBathymetry(BathymetryGrid, BathGrid_Xs, BathGrid_Ys, LineX, LineY, depth, nvec) + + REAL(DbKi), INTENT(IN ) :: BathymetryGrid(:,:) ! need colons or some sort of dimension setting + REAL(DbKi), INTENT(IN ) :: BathGrid_Xs(:) + REAL(DbKi), INTENT(IN ) :: BathGrid_Ys(:) + REAL(DbKi), INTENT(IN ) :: LineX + REAL(DbKi), INTENT(IN ) :: LineY + REAL(DbKi), INTENT( OUT) :: depth ! local seabed depth (positive down) [m] + REAL(DbKi), INTENT( OUT) :: nvec(3) ! local seabed surface normal vector (positive out) + + INTEGER(IntKi) :: ix0, iy0 ! indeces for interpolation + INTEGER(IntKi) :: ix1, iy1 ! second indices + Real(DbKi) :: fx, fy ! interpolation fractions + REAL(DbKi) :: c00, c01, c10, c11, cx0, cx1, c0y, c1y ! temporary depth values + Real(DbKi) :: dx, dy ! x and y spacing of local grid panel [m] + Real(DbKi) :: dc_dx, dc_dy ! local slope + Real(DbKi) :: tempVector(3) ! normal vector before scaling to unit + + ! get interpolation indices and fractions for the relevant grid panel + CALL getInterpNums(BathGrid_Xs, LineX, 1, ix0, fx) + CALL getInterpNums(BathGrid_Ys, LineY, 1, iy0, fy) + + !CALL calculate2Dinterpolation(BathymetryGrid, ix, iy, fx, fy, depth) + + ! handle end case conditions + IF (fx == 0) THEN + ix1 = ix0 + ELSE + ix1 = min(ix0+1,size(BathymetryGrid,2)) ! don't overstep bounds + END IF + IF (fy == 0) THEN + iy1 = iy0 + ELSE + iy1 = min(iy0+1,size(BathymetryGrid,1)) ! don't overstep bounds + END IF + + ! get corner points of the panel + c00 = BathymetryGrid(iy0, ix0) + c01 = BathymetryGrid(iy1, ix0) + c10 = BathymetryGrid(iy0, ix1) + c11 = BathymetryGrid(iy1, ix1) + + ! get interpolated points and local value + cx0 = c00 *(1.0-fx) + c10 *fx + cx1 = c01 *(1.0-fx) + c11 *fx + c0y = c00 *(1.0-fy) + c01 *fy + c1y = c10 *(1.0-fy) + c11 *fy + depth = cx0 *(1.0-fy) + cx1 *fy + + ! get local slope + dx = BathGrid_Xs(ix1) - BathGrid_Xs(ix0) + dy = BathGrid_Ys(iy1) - BathGrid_Ys(iy0) + if ( dx > 0.0 ) then + dc_dx = (c1y-c0y)/dx + else + dc_dx = 0.0_DbKi ! maybe this should raise an error + end if + if ( dx > 0.0 ) then + dc_dy = (cx1-cx0)/dy + else + dc_dy = 0.0_DbKi ! maybe this should raise an error + end if + + tempVector(1) = dc_dx + tempVector(2) = dc_dy + tempVector(3) = 1.0_DbKi + CALL ScaleVector( tempVector, 1.0_DbKi, nvec ) ! compute unit vector + + END SUBROUTINE getDepthFromBathymetry + + + ! :::::::::::::::::::::::::: wave and current subroutines ::::::::::::::::::::::::::::::: + + + ! master function to get wave/water kinematics at a given point -- called by each object from grid-based data + SUBROUTINE getWaterKin(p, x, y, z, t, tindex, U, Ud, zeta, PDyn) + + ! This whole approach assuems that px, py, and pz are in increasing order. + ! Wheeler stretching is now built in. + + TYPE(MD_ParameterType),INTENT (IN ) :: p ! MoorDyn parameters (contains the wave info for now) + Real(DbKi), INTENT (IN ) :: x + Real(DbKi), INTENT (IN ) :: y + Real(DbKi), INTENT (IN ) :: z + Real(DbKi), INTENT (IN ) :: t + INTEGER(IntKi), INTENT (INOUT) :: tindex ! pass time index to try starting from, returns identified time index + Real(DbKi), INTENT (INOUT) :: U(3) + Real(DbKi), INTENT (INOUT) :: Ud(3) + Real(DbKi), INTENT (INOUT) :: zeta + Real(DbKi), INTENT (INOUT) :: PDyn + + + INTEGER(IntKi) :: ix, iy, iz, it ! indices for interpolation + INTEGER(IntKi) :: iz0, iz1 ! special indices for currrent interpolation + INTEGER(IntKi) :: N ! number of rod elements for convenience + Real(SiKi) :: fx, fy, fz, ft ! interpolation fractions + Real(DbKi) :: zp ! zprime coordinate used for Wheeler stretching + + + ! if wave kinematics enabled, get interpolated values from grid + if (p%WaveKin > 0) then + + ! find time interpolation indices and coefficients + !CALL getInterpNums(p%tWave, t, tindex, it, ft) + it = floor(t/ p%dtWave) + 1 ! add 1 because Fortran indexing starts at 1 + ft = (t - (it-1)*p%dtWave)/p%dtWave + tindex = it + + ! find x-y interpolation indices and coefficients + CALL getInterpNumsSiKi(p%pxWave , REAL(x,SiKi), 1, ix, fx) + CALL getInterpNumsSiKi(p%pyWave , REAL(y,SiKi), 1, iy, fy) + + ! interpolate wave elevation + CALL calculate3Dinterpolation(p%zeta, ix, iy, it, fx, fy, ft, zeta) + + ! compute modified z coordinate to be used for interpolating velocities and accelerations with Wheeler stretching + zp = ( z - zeta ) * p%WtrDpth/( p%WtrDpth + zeta ) + + CALL getInterpNumsSiKi(p%pzWave , REAL(zp,SiKi), 1, iz, fz) + + ! interpolate everything else + CALL calculate4Dinterpolation(p%PDyn , ix, iy, iz, it, fx, fy, fz, ft, PDyn) + CALL calculate4Dinterpolation(p%uxWave, ix, iy, iz, it, fx, fy, fz, ft, U(1) ) + CALL calculate4Dinterpolation(p%uyWave, ix, iy, iz, it, fx, fy, fz, ft, U(2) ) + CALL calculate4Dinterpolation(p%uzWave, ix, iy, iz, it, fx, fy, fz, ft, U(3) ) + CALL calculate4Dinterpolation(p%axWave, ix, iy, iz, it, fx, fy, fz, ft, Ud(1) ) + CALL calculate4Dinterpolation(p%ayWave, ix, iy, iz, it, fx, fy, fz, ft, Ud(2) ) + CALL calculate4Dinterpolation(p%azWave, ix, iy, iz, it, fx, fy, fz, ft, Ud(3) ) + else + U = 0.0_DbKi + Ud = 0.0_DbKi + zeta = 0.0_DbKi + PDyn = 0.0_DbKi + end if + + + ! if current kinematics enabled, add interpolated current values from profile + if (p%Current > 0) then + + CALL getInterpNumsSiKi(p%pzCurrent, REAL(z,SiKi), 1, iz0, fz) + + IF (fz == 0) THEN ! handle end case conditions + iz1 = iz0 + ELSE + iz1 = min(iz0+1,size(p%pzCurrent)) ! don't overstep bounds + END IF + + U(1) = U(1) + (1.0-fz)*p%uxCurrent(iz0) + fz*p%uxCurrent(iz1) + U(2) = U(2) + (1.0-fz)*p%uyCurrent(iz0) + fz*p%uyCurrent(iz1) + end if + + END SUBROUTINE getWaterKin + + + ! unused routine with old code for taking wave kinematic grid inputs from HydroDyn + SUBROUTINE CopyWaterKinFromHydroDyn(p, InitInp) + + TYPE(MD_InitInputType), INTENT(IN ) :: InitInp ! INTENT(INOUT) : Input data for initialization routine + TYPE(MD_ParameterType), INTENT( OUT) :: p ! INTENT( OUT) : Parameters + + INTEGER(IntKi) :: I, J, K, Itemp + + + ! ----------------------------- Arrays for wave kinematics ----------------------------- + + + ! :::::::::::::: BELOW WILL BE USED EVENTUALLY WHEN WAVE INFO IS AN INPUT :::::::::::::::::: + ! ! The rAll array contains all nodes or reference points in the system + ! ! (x,y,z global coordinates for each) in the order of bodies, rods, points, internal line nodes. + ! + ! ! count the number of nodes to use for passing wave kinematics + ! J=0 + ! ! Body reference point coordinates + ! J = J + p%nBodies + ! ! Rod node coordinates (including ends) + ! DO l = 1, p%nRods + ! J = J + (m%RodList(l)%N + 1) + ! END DO + ! ! Point reference point coordinates + ! J = J + p%nConnects + ! ! Line internal node coordinates + ! DO l = 1, p%nLines + ! J = J + (m%LineList(l)%N - 1) + ! END DO + ! + ! ! allocate all relevant arrays + ! ! allocate state vector and temporary state vectors based on size just calculated + ! ALLOCATE ( y%rAll(3,J), u%U(3,J), u%Ud(3,J), u%zeta(J), u%PDyn(J), STAT = ErrStat ) + ! IF ( ErrStat /= ErrID_None ) THEN + ! ErrMsg = ' Error allocating wave kinematics vectors.' + ! RETURN + ! END IF + ! + ! + ! ! go through the nodes and fill in the data (this should maybe be turned into a global function) + ! J=0 + ! ! Body reference point coordinates + ! DO I = 1, p%nBodies + ! J = J + 1 + ! y%rAll(:,J) = m%BodyList(I)%r6(1:3) + ! END DO + ! ! Rod node coordinates + ! DO I = 1, p%nRods + ! DO K = 0,m%RodList(I)%N + ! J = J + 1 + ! y%rAll(:,J) = m%RodList(I)%r(:,K) + ! END DO + ! END DO + ! ! Point reference point coordinates + ! DO I = 1, p%nConnects + ! J = J + 1 + ! y%rAll(:,J) = m%ConnectList(I)%r + ! END DO + ! ! Line internal node coordinates + ! DO I = 1, p%nLines + ! DO K = 1,m%LineList(I)%N-1 + ! J = J + 1 + ! y%rAll(:,J) = m%LineList(I)%r(:,K) + ! END DO + ! END DO + ! :::::::::::::::: the above might be used eventually. For now, let's store wave info grids within this module ::::::::::::::::: + + + ! ----- copy wave grid data over from HydroDyn (as was done in USFLOWT branch) ----- + + ! get grid and time info (currently this is hard-coded to match what's in HydroDyn_Input + ! DO I=1,p%nzWave + ! p%pz(I) = 1.0 - 2.0**(p%nzWave-I) ! -127, -63, -31, -15, -7, -3, -1, 0 + ! END DO + ! DO J = 1,p%nyWave + ! p%py(J) = WaveGrid_y0 + WaveGrid_dy*(J-1) + ! END DO + ! DO K = 1,p%nxWave + ! p%px(K) = WaveGrid_x0 + WaveGrid_dx*(K-1) + ! END DO + ! + ! p%tWave = InitInp%WaveTime + + DO I=1,p%nzWave + DO J = 1,p%nyWave + DO K = 1,p%nxWave + Itemp = (I-1)*p%nxWave*p%nyWave + (J-1)*p%nxWave + K ! index of actual node on 3D grid + + p%uxWave (:,I,J,K) = InitInp%WaveVel( :,Itemp,1) ! note: indices are t, z, y, x + p%uyWave (:,I,J,K) = InitInp%WaveVel( :,Itemp,2) + p%uzWave (:,I,J,K) = InitInp%WaveVel( :,Itemp,3) + p%axWave (:,I,J,K) = InitInp%WaveAcc( :,Itemp,1) + p%ayWave (:,I,J,K) = InitInp%WaveAcc( :,Itemp,2) + p%azWave (:,I,J,K) = InitInp%WaveAcc( :,Itemp,3) + p%PDyn( :,I,J,K) = InitInp%WavePDyn(:,Itemp) + END DO + END DO + END DO + + DO J = 1,p%nyWave + DO K = 1,p%nxWave + Itemp = (J-1)*p%nxWave + K ! index of actual node on surface 2D grid + p%zeta(:,J,K) = InitInp%WaveElev(:,Itemp) + END DO + END DO + + END SUBROUTINE CopyWaterKinFromHydroDyn + + + ! ----- write wave grid spacing to output file ----- + SUBROUTINE WriteWaveGrid(p, ErrStat, ErrMsg) + + TYPE(MD_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 + + INTEGER(IntKi) :: ErrStat2 + CHARACTER(120) :: ErrMsg2 + + CHARACTER(120) :: Frmt + INTEGER(IntKi) :: UnOut ! for outputing wave kinematics data + INTEGER(IntKi) :: I + + + CALL GetNewUnit( UnOut) + + CALL OpenFOutFile ( UnOut, "waves.txt", ErrStat, ErrMsg ) + IF ( ErrStat > ErrID_None ) THEN + ErrMsg = ' Error opening wave grid file: '//TRIM(ErrMsg) + ErrStat = ErrID_Fatal + RETURN + END IF + + WRITE(UnOut, *, IOSTAT=ErrStat2) TRIM( 'MoorDyn v2 wave/current kinematics grid file' ) + WRITE(UnOut, *, IOSTAT=ErrStat2) TRIM( '---------------------------------------------' ) + WRITE(UnOut, *, IOSTAT=ErrStat2) TRIM( 'The following 6 lines (4-9) specify the input type then the inputs for x, then, y, then z coordinates.' ) + + WRITE(UnOut,*, IOSTAT=ErrStat2) TRIM( '1 - X input type (0: not used; 1: list values in ascending order; 2: uniform specified by -xlim, xlim, num)' ) + Frmt = '('//TRIM(Int2LStr(5))//'(A1,e10.4))' + WRITE(UnOut,*, IOSTAT=ErrStat2) ( " ", TRIM(Num2LStr(p%pxWave(I))), I=1,p%nxWave ) + + WRITE(UnOut,*, IOSTAT=ErrStat2) TRIM( '1 - Y input type (0: not used; 1: list values in ascending order; 2: uniform specified by -xlim, xlim, num)' ) + Frmt = '('//TRIM(Int2LStr(5))//'(A1,e10.4))' + WRITE(UnOut,*, IOSTAT=ErrStat2) ( " ", TRIM(Num2LStr(p%pyWave(I))), I=1,p%nyWave ) + + WRITE(UnOut,*, IOSTAT=ErrStat2) TRIM( '1 - Z input type (0: not used; 1: list values in ascending order; 2: uniform specified by -xlim, xlim, num)' ) + Frmt = '('//TRIM(Int2LStr(8))//'(A1,e10.4))' + WRITE(UnOut,*, IOSTAT=ErrStat2) ( " ", TRIM(Num2LStr(p%pzWave(I))), I=1,p%nzWave ) + + CLOSE(UnOut, IOSTAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrMsg = 'Error closing wave grid file' + END IF + + END SUBROUTINE WriteWaveGrid + + + ! ----- write wave kinematics grid data to output file ----- + SUBROUTINE WriteWaveData(p, ErrStat, ErrMsg) + + TYPE(MD_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 + + INTEGER(IntKi) :: ErrStat2 + CHARACTER(120) :: ErrMsg2 + + INTEGER(IntKi) :: UnOut ! for outputing wave kinematics data + INTEGER(IntKi) :: I,J,K, l, Itemp + + CALL GetNewUnit( UnOut) + + CALL OpenFOutFile ( UnOut, "wave data.txt", ErrStat, ErrMsg ) + IF ( ErrStat > ErrID_None ) THEN + ErrMsg = ' Error opening wave grid file: '//TRIM(ErrMsg) + ErrStat = ErrID_Fatal + RETURN + END IF + + ! write channel labels + + + ! time + WRITE(UnOut,"(A10)", IOSTAT=ErrStat2, advance="no") "Time" + + DO J = 1,p%nyWave !y + DO K = 1,p%nxWave !x + WRITE(UnOut,"(A3,A8)", IOSTAT=ErrStat2, advance="no") " ze0", Num2Lstr(J+10*K) + END DO + END DO + DO I=1,p%nzWave !z + DO J = 1,p%nyWave !y + DO K = 1,p%nxWave !x + WRITE(UnOut,"(A3,A8)", IOSTAT=ErrStat2, advance="no") " ux", Num2Lstr(I+10*J+100*K) + WRITE(UnOut,"(A3,A8)", IOSTAT=ErrStat2, advance="no") " uy", Num2Lstr(I+10*J+100*K) + WRITE(UnOut,"(A3,A8)", IOSTAT=ErrStat2, advance="no") " uz", Num2Lstr(I+10*J+100*K) + END DO + END DO + END DO + DO I=1,p%nzWave !z + DO J = 1,p%nyWave !y + DO K = 1,p%nxWave !x + WRITE(UnOut,"(A3,A8)", IOSTAT=ErrStat2, advance="no") " ax", Num2Lstr(I+10*J+100*K) + WRITE(UnOut,"(A3,A8)", IOSTAT=ErrStat2, advance="no") " ay", Num2Lstr(I+10*J+100*K) + WRITE(UnOut,"(A3,A8)", IOSTAT=ErrStat2, advance="no") " az", Num2Lstr(I+10*J+100*K) + END DO + END DO + END DO + DO I=1,p%nzWave !z + DO J = 1,p%nyWave !y + DO K = 1,p%nxWave !x + WRITE(UnOut,"(A3,A8)", IOSTAT=ErrStat2, advance="no") " pd", Num2Lstr(I+10*J+100*K) + END DO + END DO + END DO + + ! end the line + WRITE(UnOut, "(A1)", IOSTAT=ErrStat2) " " + + + + DO l=1, p%ntWave ! loop through all time steps + + ! time + WRITE(UnOut,"(F10.4)", IOSTAT=ErrStat2, advance="no") p%dtWave*(l-1) + !WRITE(UnOut,"(F10.4)", IOSTAT=ErrStat2, advance="no") InitInp%WaveTime(l) + + ! wave elevation (all slices for now, to check) + DO J = 1,p%nyWave !y + DO K = 1,p%nxWave !x + Itemp = (J-1)*p%nxWave + K ! index of actual node + + WRITE(UnOut,"(A1,e10.3)", IOSTAT=ErrStat2, advance="no") " ", p%zeta(l,J,K) + END DO + END DO + + ! wave velocities + DO I=1,p%nzWave !z + DO J = 1,p%nyWave !y + DO K = 1,p%nxWave !x + Itemp = (I-1)*p%nxWave*p%nyWave + (J-1)*p%nxWave + K ! index of actual node + + WRITE(UnOut,"(A1,e10.3)", IOSTAT=ErrStat2, advance="no") " ", p%uxWave(l,I,J,K) + WRITE(UnOut,"(A1,e10.3)", IOSTAT=ErrStat2, advance="no") " ", p%uyWave(l,I,J,K) + WRITE(UnOut,"(A1,e10.3)", IOSTAT=ErrStat2, advance="no") " ", p%uzWave(l,I,J,K) + END DO + END DO + END DO + + ! wave accelerations + DO I=1,p%nzWave !z + DO J = 1,p%nyWave !y + DO K = 1,p%nxWave !x + Itemp = (I-1)*p%nxWave*p%nyWave + (J-1)*p%nxWave + K ! index of actual node + + WRITE(UnOut,"(A1,e10.3)", IOSTAT=ErrStat2, advance="no") " ", p%axWave(l,I,J,K) + WRITE(UnOut,"(A1,e10.3)", IOSTAT=ErrStat2, advance="no") " ", p%ayWave(l,I,J,K) + WRITE(UnOut,"(A1,e10.3)", IOSTAT=ErrStat2, advance="no") " ", p%azWave(l,I,J,K) + END DO + END DO + END DO + + ! dynamic pressure + DO I=1,p%nzWave !z + DO J = 1,p%nyWave !y + DO K = 1,p%nxWave !x + Itemp = (I-1)*p%nxWave*p%nyWave + (J-1)*p%nxWave + K ! index of actual node + + WRITE(UnOut,"(A1,e10.3)", IOSTAT=ErrStat2, advance="no") " ", p%PDyn(l,I,J,K) + END DO + END DO + END DO + + ! end the line + WRITE(UnOut, "(A1)", IOSTAT=ErrStat2) " " + + + END DO + + + CLOSE(UnOut, IOSTAT = ErrStat ) + IF ( ErrStat /= 0 ) THEN + ErrMsg = 'Error closing wave grid file' + END IF + + END SUBROUTINE WriteWaveData + + + ! ----- process WaterKin input value, potentially reading wave inputs and generating wave field ----- + SUBROUTINE setupWaterKin(WaterKinString, p, Tmax, ErrStat, ErrMsg) + + CHARACTER(40), INTENT(IN ) :: WaterKinString ! string describing water kinematics filename + TYPE(MD_ParameterType), INTENT(INOUT) :: p ! Parameters + REAL(ReKi), INTENT(IN ) :: Tmax + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + INTEGER(IntKi) :: I, iIn, ix, iy, iz + INTEGER(IntKi) :: ntIn ! number of time series inputs from file + INTEGER(IntKi) :: UnIn ! unit number for coefficient input file + INTEGER(IntKi) :: UnEcho + REAL(SiKi) :: pzCurrentTemp(100) ! current depth increments read in from input file (positive-down at this stage) + REAL(SiKi) :: uxCurrentTemp(100) + REAL(SiKi) :: uyCurrentTemp(100) + + CHARACTER(120) :: WaveKinFile + INTEGER(IntKi) :: UnElev ! unit number for coefficient input file + REAL(SiKi), ALLOCATABLE :: WaveTimeIn(:) ! temporarily holds wave input time series + REAL(SiKi), ALLOCATABLE :: WaveElevIn(:) + REAL(SiKi), ALLOCATABLE :: WaveElev0(:) ! interpolated reference wave elevation time series + REAL(SiKi) :: WaveDir + REAL(SiKi) :: t, Frac + CHARACTER(1024) :: FileName ! Name of MoorDyn input file + CHARACTER(120) :: Line + CHARACTER(120) :: Line2 + CHARACTER(120) :: entries2 + INTEGER(IntKi) :: coordtype + + INTEGER(IntKi) :: NStepWave ! + INTEGER(IntKi) :: NStepWave2 ! + REAL(SiKi) :: WaveTMax ! max wave elevation time series duration after optimizing lenght for FFT + REAL(SiKi) :: WaveDOmega + REAL(SiKi) :: SinWaveDir ! SIN( WaveDirArr(I) ) -- Each wave frequency has a unique wave direction. + REAL(SiKi) :: CosWaveDir ! COS( WaveDirArr(I) ) -- Each wave frequency has a unique wave direction. + + REAL(SiKi), ALLOCATABLE :: TmpFFTWaveElev(:) ! Data for the FFT calculation + TYPE(FFT_DataType) :: FFT_Data ! the instance of the FFT module we're using + + + COMPLEX(SiKi),ALLOCATABLE :: tmpComplex(:) ! A temporary array (0:NStepWave2-1) for FFT use. + + REAL(SiKi) :: Omega ! Wave frequency (rad/s) + COMPLEX(SiKi), PARAMETER :: ImagNmbr = (0.0,1.0) ! The imaginary number, SQRT(-1.0) + COMPLEX(SiKi) :: ImagOmega ! = ImagNmbr*Omega (rad/s) + REAL(DbKi), ALLOCATABLE :: WaveNmbr(:) ! wave number for frequency array + REAL(SiKi), ALLOCATABLE :: WaveElevC0(:,:) ! Discrete Fourier transform of the instantaneous elevation of incident waves at the ref point (meters) + COMPLEX(SiKi), ALLOCATABLE :: WaveElevC( :) ! Discrete Fourier transform of the instantaneous elevation of incident waves at the ref point (meters) + COMPLEX(SiKi), ALLOCATABLE :: WaveAccCHx(:) ! Discrete Fourier transform of the instantaneous horizontal acceleration in x-direction of incident waves before applying stretching at the zi-coordinates for points (m/s^2) + COMPLEX(SiKi), ALLOCATABLE :: WaveAccCHy(:) ! Discrete Fourier transform of the instantaneous horizontal acceleration in y-direction of incident waves before applying stretching at the zi-coordinates for points (m/s^2) + COMPLEX(SiKi), ALLOCATABLE :: WaveAccCV( :) ! Discrete Fourier transform of the instantaneous vertical acceleration of incident waves before applying stretching at the zi-coordinates for points (m/s^2) + COMPLEX(SiKi), ALLOCATABLE :: WaveDynPC( :) ! Discrete Fourier transform of the instantaneous dynamic pressure of incident waves before applying stretching at the zi-coordinates for points (N/m^2) + COMPLEX(SiKi), ALLOCATABLE :: WaveVelCHx(:) ! Discrete Fourier transform of the instantaneous horizontal velocity of incident waves before applying stretching at the zi-coordinates for points (m/s) + COMPLEX(SiKi), ALLOCATABLE :: WaveVelCHy(:) ! Discrete Fourier transform of the instantaneous horizontal velocity in x-direction of incident waves before applying stretching at the zi-coordinates for points (m/s) + COMPLEX(SiKi), ALLOCATABLE :: WaveVelCV( :) ! Discrete Fourier transform of the instantaneous vertical velocity in y-direction of incident waves before applying stretching at the zi-coordinates for points (m/s) + COMPLEX(SiKi) :: WGNC ! Discrete Fourier transform of the realization of a White Gaussian Noise (WGN) time series process with unit variance for the current frequency component (-) + + INTEGER(IntKi) :: ErrStatTmp + INTEGER(IntKi) :: ErrStat2 + CHARACTER(120) :: ErrMsg2 + CHARACTER(120) :: RoutineName = 'SetupWaveKin' + + + ErrStatTmp = ErrID_None ! TODO: get rid of redundancy <<< + ErrStat2 = ErrID_None + ErrMsg2 = "" + + IF (LEN_TRIM(WaterKinString) == 0) THEN + ! If the input is empty (not provided), there are no water kinematics to be included + p%WaveKin = 0 + p%Current = 0 + return + + ELSE IF (SCAN(WaterKinString, "abcdfghijklmnopqrstuvwxyzABCDFGHIJKLMNOPQRSTUVWXYZ") == 0) THEN + ! If the input has no letters, let's assume it's a number + print *, "ERROR WaveKin option does not currently support numeric entries. It must be a filename." + p%WaveKin = 0 + p%Current = 0 + return + END IF + + + ! otherwise interpret the input as a file name to load the bathymetry lookup data from + print *, " The waterKin input contains letters so will load a water kinematics input file" + + + ! -------- load water kinematics input file ------------- + + IF ( PathIsRelative( WaterKinString ) ) THEN ! properly handle relative path <<< + !CALL GetPath( TRIM(InitInp%InputFile), TmpPath ) + FileName = TRIM(p%PriPath)//TRIM(WaterKinString) + ELSE + FileName = trim(WaterKinString) + END IF + + + + UnEcho=-1 + CALL GetNewUnit( UnIn ) + CALL OpenFInpFile( UnIn, FileName, ErrStat2, ErrMsg2); if(Failed()) return + + + CALL ReadCom( UnIn, FileName, 'MoorDyn water kinematics input file header', ErrStat2, ErrMsg2, UnEcho); if(Failed()) return + CALL ReadCom( UnIn, FileName, 'MoorDyn water kinematics input file header', ErrStat2, ErrMsg2, UnEcho); if(Failed()) return + ! ----- waves ----- + CALL ReadCom( UnIn, FileName, 'waves header', ErrStat2, ErrMsg2, UnEcho); if(Failed()) return + CALL ReadVar( UnIn, FileName, p%WaveKin , 'WaveKinMod' , 'WaveKinMod' , ErrStat2, ErrMsg2, UnEcho); if(Failed()) return + CALL ReadVar( UnIn, FileName, WaveKinFile, 'WaveKinFile', 'WaveKinFile' , ErrStat2, ErrMsg2, UnEcho); if(Failed()) return + CALL ReadVar( UnIn, FileName, p%dtWave , 'dtWave', 'time step for waves', ErrStat2, ErrMsg2, UnEcho); if(Failed()) return + CALL ReadVar( UnIn, FileName, WaveDir , 'WaveDir' , 'wave direction', ErrStat2, ErrMsg2, UnEcho); if(Failed()) return + ! X grid points + READ(UnIn,*, IOSTAT=ErrStat2) coordtype ! get the entry type + READ(UnIn,'(A)', IOSTAT=ErrStat2) entries2 ! get entries as string to be processed + CALL gridAxisCoords(coordtype, entries2, p%pxWave, p%nxWave, ErrStat2, ErrMsg2) + ! Y grid points + READ(UnIn,*, IOSTAT=ErrStat2) coordtype ! get the entry type + READ(UnIn,'(A)', IOSTAT=ErrStat2) entries2 ! get entries as string to be processed + CALL gridAxisCoords(coordtype, entries2, p%pyWave, p%nyWave, ErrStat2, ErrMsg2) + ! Z grid points + READ(UnIn,*, IOSTAT=ErrStat2) coordtype ! get the entry type + READ(UnIn,'(A)', IOSTAT=ErrStat2) entries2 ! get entries as string to be processed + CALL gridAxisCoords(coordtype, entries2, p%pzWave, p%nzWave, ErrStat2, ErrMsg2) + ! ----- current ----- + CALL ReadCom( UnIn, FileName, 'current header', ErrStat2, ErrMsg2, UnEcho); if(Failed()) return + CALL ReadVar( UnIn, FileName, p%Current, 'CurrentMod', 'CurrentMod', ErrStat2, ErrMsg2, UnEcho); if(Failed()) return + CALL ReadCom( UnIn, FileName, 'current profile header', ErrStat2, ErrMsg2, UnEcho); if(Failed()) return + CALL ReadCom( UnIn, FileName, 'current profile header', ErrStat2, ErrMsg2, UnEcho); if(Failed()) return + ! current profile table... (read through to end of file or ---) + DO I=1,100 + READ(UnIn, *, IOSTAT=ErrStat2) pzCurrentTemp(i), uxCurrentTemp(i), uyCurrentTemp(i) ! read into a line + if (ErrStat2 /= 0) then + p%nzCurrent = i-1 ! save number of valid current depth points in profile + EXIT ! break out of the loop if it couldn't read the line (i.e. if at end of file) + end if + if (i == 100) then + print*,"WARNING: MD can handle a maximum of 100 current profile points" + exit + end if + END DO + + + CLOSE(UnIn) + + + ! ------------------- start with wave kinematics ----------------------- + + ! WaveKin options: 0 - none or set externally during the sim (Waves object not needed unless there's current) [default] + ! 1 - set externally for each node in each object (Waves object not needed unless there's current) (TBD) + ! 2 - set from inputted wave elevation FFT, grid approach* (TBD) + ! 3 - set from inputted wave elevation time series, grid approach* [supported] + ! 4 - set from inputted wave elevation FFT, node approach (TBD) + ! 5 - set from inputted wave elevation time series, node approach (TBD) + ! 6 - set from inputted velocity, acceleration, and wave elevation grid data (TBD)** + + ! Current options: 0 - no currents or set externally (as part of WaveKin =0 or 1 approach) [default] + ! 1 - read in steady current profile, grid approach (current_profile.txt)** [supported] + ! 2 - read in dynamic current profile, grid approach (current_profile_dynamic.txt)** (TBD) + ! 3 - read in steady current profile, node approach (current_profile.txt) (TBD) + ! 4 - read in dynamic current profile, node approach (current_profile_dynamic.txt) (TBD) + + ! * the first call to any of these will attempt to load water_grid.txt to define the grid to put things on + ! ** if a grid has already been set, these will interpolate onto it, otherwise they'll make a new grid based on their provided coordinates + + ! NOTE: lots of partial code is available from MD-C for supporting various wave kinematics input options + + ! WaveKin and Current compatibility check could go here in future + + + ! --------------------- set from inputted wave elevation time series, grid approach ------------------- + if (p%WaveKin == 3) then + + print *, 'Setting up WaveKin 3 option: read wave elevation time series from file' + + IF ( LEN_TRIM( WaveKinFile ) == 0 ) THEN + CALL SetErrStat( ErrID_Fatal,'WaveKinFile must not be an empty string.',ErrStat, ErrMsg, RoutineName); return + RETURN + END IF + + IF ( PathIsRelative( WaveKinFile ) ) THEN ! properly handle relative path <<< + !CALL GetPath( TRIM(InitInp%InputFile), TmpPath ) + WaveKinFile = TRIM(p%PriPath)//TRIM(WaveKinFile) + END IF + + ! note: following is adapted from MoorDyn_Driver + + CALL GetNewUnit( UnElev ) + + CALL OpenFInpFile ( UnElev, WaveKinFile, ErrStat2, ErrMsg2 ); if(Failed()) return + + print *, 'Reading wave elevation data from ', trim(WaveKinFile) + + ! Read through length of file to find its length + i = 1 ! start counter + DO + READ(UnElev,'(A)',IOSTAT=ErrStat2) Line !read into a line + IF (ErrStat2 /= 0) EXIT ! break out of the loop if it couldn't read the line (i.e. if at end of file) + i = i+1 + END DO + + ! rewind to start of input file to re-read things now that we know how long it is + REWIND(UnElev) + + ntIn = i-3 ! save number of lines of file + + + ! allocate space for input wave elevation array (including time column) + CALL AllocAry(WaveTimeIn, ntIn, 'WaveTimeIn', ErrStat2, ErrMsg2 ); if(Failed()) return + CALL AllocAry(WaveElevIn, ntIn, 'WaveElevIn', ErrStat2, ErrMsg2 ); if(Failed()) return + + ! read the data in from the file + READ(UnElev,'(A)',IOSTAT=ErrStat2) Line ! skip the first two lines as headers + READ(UnElev,'(A)',IOSTAT=ErrStat2) Line ! + + DO i = 1, ntIn + READ (UnElev, *, IOSTAT=ErrStat2) WaveTimeIn(i), WaveElevIn(i) + + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal,'Error reading WaveElev input file.',ErrStat, ErrMsg, RoutineName); return + END IF + END DO + + ! Close the inputs file + CLOSE ( UnElev ) + + print *, "Read ", ntIn, " time steps from input file." + + ! if (WaveTimeIn(ntIn) < TMax) then <<<< need to handle if time series is too short? + + ! specify stepping details + p%ntWave = CEILING(Tmax/p%dtWave) ! number of wave time steps + + + ! allocate space for processed reference wave elevation time series + ALLOCATE ( WaveElev0( 0:p%ntWave ), STAT=ErrStatTmp ) ! this has an extra entry of zero in case it needs to be padded to be even + IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,'Cannot allocate array WaveElev0.',ErrStat,ErrMsg,RoutineName) + WaveElev0 = 0.0_SiKi + + ! go through and interpolate (should replace with standard function) + DO i = 1, p%ntWave + t = p%dtWave*(i-1) + + ! interpolation routine + DO iIn = 1,ntIn-1 + IF (WaveTimeIn(iIn+1) > t) THEN ! find the right two points to interpolate between (remember that the first column of PtfmMotIn is time) + frac = (t - WaveTimeIn(iIn) )/( WaveTimeIn(iIn+1) - WaveTimeIn(iIn) ) ! interpolation fraction (0-1) between two interpolation points + WaveElev0(i-1) = WaveElevIn(iIn) + frac*(WaveElevIn(iIn+1) - WaveElevIn(iIn)) ! get interpolated wave elevation + EXIT ! break out of the loop for this time step once we've done its interpolation + END IF + END DO + END DO + + ! note: following is adapted from UserWaves.v90 UserWaveElevations_Init + + + + ! Set new value for NStepWave so that the FFT algorithms are efficient. We will use the values passed in rather than what is read from the file + + IF ( MOD(p%ntWave,2) == 1 ) p%ntWave = p%ntWave + 1 ! Set NStepWave to an even integer + NStepWave2 = MAX( p%ntWave/2, 1 ) ! Make sure that NStepWave is an even product of small factors (PSF) that is + NStepWave = 2*PSF ( NStepWave2, 9 ) ! greater or equal to WaveTMax/WaveDT to ensure that the FFT is efficient. + NStepWave2 = NStepWave/2 ! Update the value of NStepWave2 based on the value needed for NStepWave. + WaveTMax = NStepWave*p%dtWave ! Update the value of WaveTMax based on the value needed for NStepWave. + WaveDOmega = TwoPi/TMax ! Compute the frequency step for incident wave calculations. + p%ntWave = NStepWave + + + + + ! Allocate array to hold the wave elevations for calculation of FFT. + ALLOCATE ( TmpFFTWaveElev( 0:NStepWave-1 ), STAT=ErrStatTmp ) + IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,'Cannot allocate array TmpFFTWaveElev.',ErrStat,ErrMsg,RoutineName) + + ! Allocate frequency array for the wave elevation information in frequency space + ALLOCATE ( WaveElevC0(2, 0:NStepWave2 ), STAT=ErrStatTmp ) + IF (ErrStatTmp /= 0) CALL SetErrStat(ErrID_Fatal,'Cannot allocate array WaveElevC0.',ErrStat,ErrMsg,RoutineName) + + + ! Now check if all the allocations worked properly + IF ( ErrStat >= AbortErrLev ) THEN + CALL CleanUp() + RETURN + END IF + + ! Set the values + TmpFFTWaveElev = 0.0_DbKi + WaveElevC0(:,:) = 0.0_DbKi + + + ! Copy values over + DO I=0, MIN(SIZE(WaveElev0), NStepWave)-1 + TmpFFTWaveElev(I) = WaveElev0(I) + ENDDO + + ! Initialize the FFT + CALL InitFFT ( NStepWave, FFT_Data, .FALSE., ErrStatTmp ) + CALL SetErrStat(ErrStatTmp,'Error occured while initializing the FFT.',ErrStat,ErrMsg,RoutineName); if(Failed()) return + + ! Apply the forward FFT to get the real and imaginary parts of the frequency information. + CALL ApplyFFT_f ( TmpFFTWaveElev(:), FFT_Data, ErrStatTmp ) ! Note that the TmpFFTWaveElev now contains the real and imaginary bits. + CALL SetErrStat(ErrStatTmp,'Error occured while applying the forwards FFT to TmpFFTWaveElev array.',ErrStat,ErrMsg,RoutineName); if(Failed()) return + + ! Copy the resulting TmpFFTWaveElev(:) data over to the WaveElevC0 array + DO I=1,NStepWave2-1 + WaveElevC0 (1,I) = TmpFFTWaveElev(2*I-1) + WaveElevC0 (2,I) = TmpFFTWaveElev(2*I) + ENDDO + WaveElevC0(:,NStepWave2) = 0.0_SiKi + + CALL ExitFFT(FFT_Data, ErrStatTmp) + CALL SetErrStat(ErrStatTmp,'Error occured while cleaning up after the FFTs.', ErrStat,ErrMsg,RoutineName); if(Failed()) return + + + IF (ALLOCATED( WaveElev0 )) DEALLOCATE( WaveElev0 , STAT=ErrStatTmp) + IF (ALLOCATED( TmpFFTWaveElev )) DEALLOCATE( TmpFFTWaveElev, STAT=ErrStatTmp) + + + + ! note: following is a very streamlined adaptation from from Waves.v90 VariousWaves_Init + + ! allocate all the wave kinematics FFT arrays + ALLOCATE( WaveNmbr (0:NStepWave2), STAT=ErrStatTmp); CALL SetErrStat(ErrStatTmp,'Cannot allocate WaveNmbr. ',ErrStat,ErrMsg,RoutineName) + ALLOCATE( tmpComplex(0:NStepWave2), STAT=ErrStatTmp); CALL SetErrStat(ErrStatTmp,'Cannot allocate tmpComplex.',ErrStat,ErrMsg,RoutineName) + ALLOCATE( WaveElevC (0:NStepWave2), STAT=ErrStatTmp); CALL SetErrStat(ErrStatTmp,'Cannot allocate WaveElevC .',ErrStat,ErrMsg,RoutineName) + ALLOCATE( WaveDynPC (0:NStepWave2), STAT=ErrStatTmp); CALL SetErrStat(ErrStatTmp,'Cannot allocate WaveDynPC .',ErrStat,ErrMsg,RoutineName) + ALLOCATE( WaveVelCHx(0:NStepWave2), STAT=ErrStatTmp); CALL SetErrStat(ErrStatTmp,'Cannot allocate WaveVelCHx.',ErrStat,ErrMsg,RoutineName) + ALLOCATE( WaveVelCHy(0:NStepWave2), STAT=ErrStatTmp); CALL SetErrStat(ErrStatTmp,'Cannot allocate WaveVelCHy.',ErrStat,ErrMsg,RoutineName) + ALLOCATE( WaveVelCV (0:NStepWave2), STAT=ErrStatTmp); CALL SetErrStat(ErrStatTmp,'Cannot allocate WaveVelCV .',ErrStat,ErrMsg,RoutineName) + ALLOCATE( WaveAccCHx(0:NStepWave2), STAT=ErrStatTmp); CALL SetErrStat(ErrStatTmp,'Cannot allocate WaveAccCHx.',ErrStat,ErrMsg,RoutineName) + ALLOCATE( WaveAccCHy(0:NStepWave2), STAT=ErrStatTmp); CALL SetErrStat(ErrStatTmp,'Cannot allocate WaveAccCHy.',ErrStat,ErrMsg,RoutineName) + ALLOCATE( WaveAccCV (0:NStepWave2), STAT=ErrStatTmp); CALL SetErrStat(ErrStatTmp,'Cannot allocate WaveAccCV .',ErrStat,ErrMsg,RoutineName) + + ! allocate time series grid data arrays (now that we know the number of time steps coming from the IFFTs) + CALL allocateKinematicsArrays() + + + ! Set the CosWaveDir and SinWaveDir values + CosWaveDir=COS(D2R*WaveDir) + SinWaveDir=SIN(D2R*WaveDir) + + ! get wave number array once + DO I = 0, NStepWave2 + WaveNmbr(i) = WaveNumber ( REAL(I*WaveDOmega, R8Ki), p%g, p%WtrDpth ) + tmpComplex(I) = CMPLX(WaveElevC0(1,I), WaveElevC0(2,I)) + END DO + + ! set up FFTer for doing IFFTs + CALL InitFFT ( NStepWave, FFT_Data, .TRUE., ErrStatTmp ) + CALL SetErrStat(ErrStatTmp,'Error occured while initializing the FFT.', ErrStat, ErrMsg, routineName); if(Failed()) return + + ! Loop through all points where the incident wave kinematics will be computed + do ix = 1,p%nxWave + do iy = 1,p%nyWave + do iz = 1,p%nzWave + + ! Compute the discrete Fourier transform of the incident wave kinematics + do i = 0, NStepWave2 ! Loop through the positive frequency components (including zero) of the discrete Fourier transforms + + Omega = i*WaveDOmega + ImagOmega = ImagNmbr*Omega + + WaveElevC (i) = tmpComplex(i) * EXP( -ImagNmbr*WaveNmbr(i)*( p%pxWave(ix)*CosWaveDir + p%pyWave(iy)*SinWaveDir )) + WaveDynPC (i) = p%rhoW*p%g* WaveElevC(i) * COSHNumOvrCOSHDen( WaveNmbr(i), p%WtrDpth, REAL(p%pzWave(iz), R8Ki) ) + WaveVelCHx(i) = Omega*WaveElevC(i) * COSHNumOvrSINHDen( WaveNmbr(i), p%WtrDpth, REAL(p%pzWave(iz), R8Ki) ) *CosWaveDir + WaveVelCHy(i) = Omega*WaveElevC(i) * COSHNumOvrSINHDen( WaveNmbr(i), p%WtrDpth, REAL(p%pzWave(iz), R8Ki) ) *SinWaveDir + WaveVelCV (i) = ImagOmega*WaveElevC(i) * SINHNumOvrSINHDen( WaveNmbr(i), p%WtrDpth, REAL(p%pzWave(iz), R8Ki) ) + WaveAccCHx(i) = ImagOmega*WaveVelCHx(i) + WaveAccCHy(i) = ImagOmega*WaveVelCHy(i) + WaveAccCV (i) = ImagOmega*WaveVelCV (i) + end do ! I, frequencies + + ! now IFFT all the wave kinematics except surface elevation and save it into the grid of data + CALL ApplyFFT_cx( p%PDyn (:,iz,iy,ix), WaveDynPC , FFT_Data, ErrStatTmp ); CALL SetErrStat(ErrStatTmp,'Error IFFTing WaveDynP.', ErrStat,ErrMsg,RoutineName) + CALL ApplyFFT_cx( p%uxWave(:,iz,iy,ix), WaveVelCHx, FFT_Data, ErrStatTmp ); CALL SetErrStat(ErrStatTmp,'Error IFFTing WaveVelHx.',ErrStat,ErrMsg,RoutineName) + CALL ApplyFFT_cx( p%uyWave(:,iz,iy,ix), WaveVelCHy, FFT_Data, ErrStatTmp ); CALL SetErrStat(ErrStatTmp,'Error IFFTing WaveVelHy.',ErrStat,ErrMsg,RoutineName) + CALL ApplyFFT_cx( p%uzWave(:,iz,iy,ix), WaveVelCV , FFT_Data, ErrStatTmp ); CALL SetErrStat(ErrStatTmp,'Error IFFTing WaveVelV.', ErrStat,ErrMsg,RoutineName) + CALL ApplyFFT_cx( p%axWave(:,iz,iy,ix), WaveAccCHx, FFT_Data, ErrStatTmp ); CALL SetErrStat(ErrStatTmp,'Error IFFTing WaveAccHx.',ErrStat,ErrMsg,RoutineName) + CALL ApplyFFT_cx( p%ayWave(:,iz,iy,ix), WaveAccCHy, FFT_Data, ErrStatTmp ); CALL SetErrStat(ErrStatTmp,'Error IFFTing WaveAccHy.',ErrStat,ErrMsg,RoutineName) + CALL ApplyFFT_cx( p%azWave(:,iz,iy,ix), WaveAccCV , FFT_Data, ErrStatTmp ); CALL SetErrStat(ErrStatTmp,'Error IFFTing WaveAccV.', ErrStat,ErrMsg,RoutineName) + + end do ! iz + + ! IFFT wave elevation here because it's only at the surface + CALL ApplyFFT_cx( p%zeta(:,iy,ix) , WaveElevC , FFT_Data, ErrStatTmp ); CALL SetErrStat(ErrStatTmp,'Error IFFTing WaveElev.', ErrStat,ErrMsg,RoutineName) + end do ! iy + end do ! ix + + ! could also reproduce the wave elevation at 0,0,0 on a separate channel for verification... + + CALL ExitFFT(FFT_Data, ErrStatTmp) + CALL SetErrStat(ErrStatTmp,'Error occured while cleaning up after the IFFTs.', ErrStat,ErrMsg,RoutineName); if(Failed()) return + + end if ! p%WaveKin == 3 + + + ! --------------------------------- now do currents -------------------------------- + if (p%Current == 1) then + + ! allocate current profile arrays to correct size + CALL AllocAry( p%pzCurrent, p%nzCurrent, 'pzCurrent', ErrStat2, ErrMsg2 ); if(Failed()) return + CALL AllocAry( p%uxCurrent, p%nzCurrent, 'uxCurrent', ErrStat2, ErrMsg2 ); if(Failed()) return + CALL AllocAry( p%uyCurrent, p%nzCurrent, 'uyCurrent', ErrStat2, ErrMsg2 ); if(Failed()) return + + ! copy over data, flipping sign of depth values (to be positive-up) and reversing order + do i = 1,p%nzCurrent + p%pzCurrent(i) = -pzCurrentTemp(p%nzCurrent + 1 - i) ! flip sign so depth is positive-up + p%uxCurrent(i) = uxCurrentTemp(p%nzCurrent + 1 - i) + p%uyCurrent(i) = uyCurrentTemp(p%nzCurrent + 1 - i) + end do + + end if ! p%Current == 1 + + + ! ------------------------------ clean up and finished --------------------------- + CALL cleanup() + + + CONTAINS + + + ! get grid axis coordinates, initialize/record in array, and return size + SUBROUTINE gridAxisCoords(coordtype, entries, coordarray, n, ErrStat, ErrMsg) + + INTEGER(IntKi), INTENT(IN ) :: coordtype + CHARACTER(*), INTENT(INOUT) :: entries + REAL(SiKi), ALLOCATABLE, INTENT(INOUT) :: coordarray(:) + INTEGER(IntKi), INTENT( OUT) :: n + + + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + REAL(ReKi) :: tempArray (100) + REAL(ReKi) :: dx + INTEGER(IntKi) :: nEntries, I + + ! get array of coordinate entries + CALL stringToArray(entries, nEntries, tempArray) + + ! set number of coordinates + if ( coordtype==0) then ! 0: not used - make one grid point at zero + n = 1; + else if (coordtype==1) then ! 1: list values in ascending order + n = nEntries + else if (coordtype==2) then ! 2: uniform specified by -xlim, xlim, num + n = int(tempArray(3)) + else + print *, "Error: invalid coordinate type specified to gridAxisCoords" + end if + + ! allocate coordinate array + CALL AllocAry(coordarray, n, 'x,y, or z grid points' , ErrStat, ErrMsg) + !ALLOCATE ( coordarray(n), STAT=ErrStat) + + ! fill in coordinates + if ( coordtype==0) then + coordarray(1) = 0.0_ReKi + + else if (coordtype==1) then + coordarray(1:n) = tempArray(1:n) + + else if (coordtype==2) then + coordarray(1) = tempArray(1) + coordarray(n) = tempArray(2) + dx = (coordarray(n)-coordarray(0))/REAL(n-1) + do i=2,n-1 + coordarray(i) = coordarray(1) + REAL(i)*dx + end do + + else + print *, "Error: invalid coordinate type specified to gridAxisCoords" + end if + + print *, "Set water grid coordinates to :" + DO i=1,n + print *, " ", coordarray(i) + end do + + END SUBROUTINE gridAxisCoords + + + ! Extract an array of numbers out of a string with comma-separated numbers (this could go in a more general location) + SUBROUTINE stringToArray(instring, n, outarray) + + CHARACTER(*), INTENT(INOUT) :: instring + INTEGER(IntKi), INTENT( OUT) :: n + REAL(ReKi), INTENT( OUT) :: outarray(100) ! array of output numbers (100 maximum) + + CHARACTER(40) :: tempstring + INTEGER :: pos1, pos2, i + + outarray = 0.0_ReKi + + n = 0 + pos1=1 + + DO + pos2 = INDEX(instring(pos1:), ",") ! find index of next comma + IF (pos2 == 0) THEN ! if there isn't another comma, read the last entry and call it done (this could be the only entry if no commas) + n = n + 1 + READ(instring(pos1:), *) outarray(n) + EXIT + END IF + n = n + 1 + if (n > 100) then + print *, "ERROR - stringToArray cannot do more than 100 entries" + end if + READ(instring(pos1:pos1+pos2-2), *) outarray(n) + + pos1 = pos2+pos1 + END DO + + END SUBROUTINE stringToArray + + + ! allocate water kinematics arrays + SUBROUTINE allocateKinematicsArrays() + ! error check print *, "Error in Waves::makeGrid, a time or space array is size zero." << endl; + + ALLOCATE ( p%uxWave( p%ntWave,p%nzWave,p%nyWave,p%nxWave), STAT=ErrStatTmp) + ALLOCATE ( p%uyWave( p%ntWave,p%nzWave,p%nyWave,p%nxWave), STAT=ErrStatTmp) + ALLOCATE ( p%uzWave( p%ntWave,p%nzWave,p%nyWave,p%nxWave), STAT=ErrStatTmp) + ALLOCATE ( p%axWave( p%ntWave,p%nzWave,p%nyWave,p%nxWave), STAT=ErrStatTmp) + ALLOCATE ( p%ayWave( p%ntWave,p%nzWave,p%nyWave,p%nxWave), STAT=ErrStatTmp) + ALLOCATE ( p%azWave( p%ntWave,p%nzWave,p%nyWave,p%nxWave), STAT=ErrStatTmp) + ALLOCATE ( p%PDyn ( p%ntWave,p%nzWave,p%nyWave,p%nxWave), STAT=ErrStatTmp) + ALLOCATE ( p%zeta ( p%ntWave,p%nyWave,p%nxWave), STAT = ErrStatTmp ) ! 2D grid over x and y only + + END SUBROUTINE allocateKinematicsArrays + + + ! compact way to set the right error status and check if an abort is needed (and do cleanup if so) + LOGICAL FUNCTION Failed() + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SetupWaterKin') + Failed = ErrStat >= AbortErrLev + if (Failed) call CleanUp() + END FUNCTION Failed + + + SUBROUTINE CleanUp + + !IF (ALLOCATED( WaveElev )) DEALLOCATE( WaveElev, STAT=ErrStatTmp) + !IF (ALLOCATED( WaveTime )) DEALLOCATE( WaveTime, STAT=ErrStatTmp) + IF (ALLOCATED( TmpFFTWaveElev )) DEALLOCATE( TmpFFTWaveElev, STAT=ErrStatTmp) + IF (ALLOCATED( WaveElevC0 )) DEALLOCATE( WaveElevC0, STAT=ErrStatTmp) + + ! >>> missing some things <<< + + IF (ALLOCATED( WaveNmbr )) DEALLOCATE( WaveNmbr , STAT=ErrStatTmp) + IF (ALLOCATED( tmpComplex )) DEALLOCATE( tmpComplex , STAT=ErrStatTmp) + IF (ALLOCATED( WaveElevC )) DEALLOCATE( WaveElevC , STAT=ErrStatTmp) + IF (ALLOCATED( WaveDynPC )) DEALLOCATE( WaveDynPC , STAT=ErrStatTmp) + IF (ALLOCATED( WaveVelCHx )) DEALLOCATE( WaveVelCHx , STAT=ErrStatTmp) + IF (ALLOCATED( WaveVelCHy )) DEALLOCATE( WaveVelCHy , STAT=ErrStatTmp) + IF (ALLOCATED( WaveVelCV )) DEALLOCATE( WaveVelCV , STAT=ErrStatTmp) + IF (ALLOCATED( WaveAccCHx )) DEALLOCATE( WaveAccCHx , STAT=ErrStatTmp) + IF (ALLOCATED( WaveAccCHy )) DEALLOCATE( WaveAccCHy , STAT=ErrStatTmp) + IF (ALLOCATED( WaveAccCV )) DEALLOCATE( WaveAccCV , STAT=ErrStatTmp) + + END SUBROUTINE CleanUp + + + !======================================================================= + FUNCTION WaveNumber ( Omega, g, h ) + + + ! This FUNCTION solves the finite depth dispersion relationship: + ! + ! k*tanh(k*h)=(Omega^2)/g + ! + ! for k, the wavenumber (WaveNumber) given the frequency, Omega, + ! gravitational constant, g, and water depth, h, as inputs. A + ! high order initial guess is used in conjunction with a quadratic + ! Newton's method for the solution with seven significant digits + ! accuracy using only one iteration pass. The method is due to + ! Professor J.N. Newman of M.I.T. as found in routine EIGVAL of + ! the SWIM-MOTION-LINES (SML) software package in source file + ! Solve.f of the SWIM module. + + + + IMPLICIT NONE + + + ! Passed Variables: + + REAL(DbKi), INTENT(IN ) :: g ! Gravitational acceleration (m/s^2) + REAL(DbKi), INTENT(IN ) :: h ! Water depth (meters) + REAL(DbKi), INTENT(IN ) :: Omega ! Wave frequency (rad/s) + REAL(DbKi) :: WaveNumber ! This function = wavenumber, k (1/m) + + + ! Local Variables: + + REAL(DbKi) :: A ! A temporary variable used in the solution. + REAL(DbKi) :: B ! A temporary variable used in the solution. + REAL(DbKi) :: C ! A temporary variable used in the solution. + REAL(DbKi) :: C2 ! A temporary variable used in the solution. + REAL(DbKi) :: CC ! A temporary variable used in the solution. + REAL(DbKi) :: E2 ! A temporary variable used in the solution. + REAL(DbKi) :: X0 ! A temporary variable used in the solution. + + + + ! Compute the wavenumber, unless Omega is zero, in which case, return + ! zero: + + IF ( Omega == 0.0 ) THEN ! When .TRUE., the formulation below is ill-conditioned; thus, the known value of zero is returned. + + + WaveNumber = 0.0 + + + ELSE ! Omega > 0.0; solve for the wavenumber as usual. + + + C = Omega*Omega*h/REAL(g,DbKi) + CC = C*C + + + ! Find X0: + + IF ( C <= 2.0 ) THEN + + X0 = SQRT(C)*( 1.0 + C*( 0.169 + (0.031*C) ) ) + + ELSE + + E2 = EXP(-2.0*C) + + X0 = C*( 1.0 + ( E2*( 2.0 - (12.0*E2) ) ) ) + + END IF + + + ! Find the WaveNumber: + + IF ( C <= 4.8 ) THEN + + C2 = CC - X0*X0 + A = 1.0/( C - C2 ) + B = A*( ( 0.5*LOG( ( X0 + C )/( X0 - C ) ) ) - X0 ) + + WaveNumber = ( X0 - ( B*C2*( 1.0 + (A*B*C*X0) ) ) )/h + + ELSE + + WaveNumber = X0/h + + END IF + + + END IF + + + + RETURN + END FUNCTION WaveNumber + + !======================================================================= + FUNCTION COSHNumOvrCOSHDen ( k, h, z ) + + + ! This FUNCTION computes the shallow water hyperbolic numerator + ! over denominator term in the wave kinematics expressions: + ! + ! COSH( k*( z + h ) )/COSH( k*h ) + ! + ! given the wave number, k, water depth, h, and elevation z, as + ! inputs. + + IMPLICIT NONE + + + ! Passed Variables: + + REAL(SiKi) :: COSHNumOvrCOSHDen ! This function = COSH( k*( z + h ) )/COSH( k*h ) (-) + REAL(DbKi), INTENT(IN ) :: h ! Water depth ( h > 0 ) (meters) + REAL(DbKi), INTENT(IN ) :: k ! Wave number ( k >= 0 ) (1/m) + REAL(DbKi), INTENT(IN ) :: z ! Elevation (-h <= z <= 0 ) (meters) + + + + ! Compute the hyperbolic numerator over denominator: + + IF ( k*h > 89.4_DbKi ) THEN ! When .TRUE., the shallow water formulation will trigger a floating point overflow error; however, COSH( k*( z + h ) )/COSH( k*h ) = EXP( k*z ) + EXP( -k*( z + 2*h ) ) for large k*h. This equals the deep water formulation, EXP( k*z ), except near z = -h, because h > 14.23*wavelength (since k = 2*Pi/wavelength) in this case. + + COSHNumOvrCOSHDen = REAL(EXP( k*z ) + EXP( -k*( z + 2.0_DbKi*h ) )) + + ELSE ! 0 < k*h <= 89.4; use the shallow water formulation. + + COSHNumOvrCOSHDen =REAL( COSH( k*( z + h ) ),R8Ki)/COSH( k*h ) + + END IF + + + + RETURN + END FUNCTION COSHNumOvrCOSHDen +!======================================================================= + FUNCTION COSHNumOvrSINHDen ( k, h, z ) + + + ! This FUNCTION computes the shallow water hyperbolic numerator + ! over denominator term in the wave kinematics expressions: + ! + ! COSH( k*( z + h ) )/SINH( k*h ) + ! + ! given the wave number, k, water depth, h, and elevation z, as + ! inputs. + + + + IMPLICIT NONE + + + ! Passed Variables: + + REAL(SiKi) :: COSHNumOvrSINHDen ! This function = COSH( k*( z + h ) )/SINH( k*h ) (-) + REAL(DbKi), INTENT(IN ) :: h ! Water depth ( h > 0 ) (meters) + REAL(DbKi), INTENT(IN ) :: k ! Wave number ( k >= 0 ) (1/m) + REAL(DbKi), INTENT(IN ) :: z ! Elevation (-h <= z <= 0 ) (meters) + + + + ! Compute the hyperbolic numerator over denominator: + + + IF ( k < EPSILON(0.0_DbKi) ) THEN ! When .TRUE., the shallow water formulation is ill-conditioned; thus, HUGE(k) is returned to approximate the known value of infinity. + + COSHNumOvrSINHDen = 1.0E20 ! HUGE( k ) + + ELSEIF ( k*h > 89.4_DbKi ) THEN ! When .TRUE., the shallow water formulation will trigger a floating point overflow error; however, COSH( k*( z + h ) )/SINH( k*h ) = EXP( k*z ) + EXP( -k*( z + 2*h ) ) for large k*h. This equals the deep water formulation, EXP( k*z ), except near z = -h, because h > 14.23*wavelength (since k = 2*Pi/wavelength) in this case. + + COSHNumOvrSINHDen = EXP( k*z ) + EXP( -k*( z + 2*h ) ) + + ELSE ! 0 < k*h <= 89.4; use the shallow water formulation. + + COSHNumOvrSINHDen = COSH( k*( z + h ) )/SINH( k*h ) + + END IF + + + + RETURN + END FUNCTION COSHNumOvrSINHDen +!======================================================================= + FUNCTION COTH ( X ) + + + ! This FUNCTION computes the hyperbolic cotangent, + ! COSH(X)/SINH(X). + + + USE Precision + + + IMPLICIT NONE + + + ! Passed Variables: + + REAL(DbKi) :: COTH ! This function = COSH( X )/SINH( X ) (-) + REAL(DbKi), INTENT(IN ) :: X ! The argument (-) + + + + ! Compute the hyperbolic cotangent: + + IF ( X == 0.0_DbKi ) THEN ! When .TRUE., the formulation below is ill-conditioned; thus, HUGE(X) is returned to approximate the known value of infinity. + + COTH = HUGE( X ) + + ELSE ! X /= 0.0; use the numerically-stable computation of COTH(X) by means of TANH(X). + + COTH = 1.0_DbKi/TANH( X ) ! = COSH( X )/SINH( X ) + + END IF + + + + RETURN + END FUNCTION COTH + + !======================================================================= + FUNCTION SINHNumOvrSINHDen ( k, h, z ) + + + ! This FUNCTION computes the shallow water hyperbolic numerator + ! over denominator term in the wave kinematics expressions: + ! + ! SINH( k*( z + h ) )/SINH( k*h ) + ! + ! given the wave number, k, water depth, h, and elevation z, as + ! inputs. + + + IMPLICIT NONE + + + ! Passed Variables: + + REAL(SiKi) :: SINHNumOvrSINHDen ! This function = SINH( k*( z + h ) )/SINH( k*h ) (-) + REAL(DbKi), INTENT(IN ) :: h ! Water depth ( h > 0 ) (meters) + REAL(DbKi), INTENT(IN ) :: k ! Wave number ( k >= 0 ) (1/m) + REAL(DbKi), INTENT(IN ) :: z ! Elevation (-h <= z <= 0 ) (meters) + + + + ! Compute the hyperbolic numerator over denominator: + + IF ( k == 0.0_DbKi ) THEN ! When .TRUE., the shallow water formulation is ill-conditioned; thus, the known value of unity is returned. + + SINHNumOvrSINHDen = 1.0 + + ELSEIF ( k*h > 89.4_DbKi ) THEN ! When .TRUE., the shallow water formulation will trigger a floating point overflow error; however, SINH( k*( z + h ) )/SINH( k*h ) = EXP( k*z ) - EXP( -k*( z + 2*h ) ) for large k*h. This equals the deep water formulation, EXP( k*z ), except near z = -h, because h > 14.23*wavelength (since k = 2*Pi/wavelength) in this case. + + SINHNumOvrSINHDen = EXP( k*z ) - EXP( -k*( z + 2.0_DbKi*h ) ) + + ELSE ! 0 < k*h <= 89.4; use the shallow water formulation. + + SINHNumOvrSINHDen = SINH( k*( z + h ) )/SINH( k*h ) + + END IF + + + + RETURN + END FUNCTION SINHNumOvrSINHDen + + END SUBROUTINE setupWaterKin + + + + + +END MODULE MoorDyn_Misc diff --git a/modules/moordyn/src/MoorDyn_Point.f90 b/modules/moordyn/src/MoorDyn_Point.f90 new file mode 100644 index 000000000..fce8aab12 --- /dev/null +++ b/modules/moordyn/src/MoorDyn_Point.f90 @@ -0,0 +1,419 @@ +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2020-2021 Alliance for Sustainable Energy, LLC +! Copyright (C) 2015-2019 Matthew Hall +! +! This file is part of MoorDyn. +! +! 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 MoorDyn_Point + + USE MoorDyn_Types + USE MoorDyn_IO + USE NWTC_Library + USE MoorDyn_Misc + USE MoorDyn_Line, only : Line_SetEndKinematics, Line_GetEndStuff + + IMPLICIT NONE + + PRIVATE + + INTEGER(IntKi), PARAMETER :: wordy = 0 ! verbosity level. >1 = more console output + + PUBLIC :: Connect_Initialize + PUBLIC :: Connect_SetKinematics + PUBLIC :: Connect_SetState + PUBLIC :: Connect_GetStateDeriv + PUBLIC :: Connect_DoRHS + PUBLIC :: Connect_GetCoupledForce + PUBLIC :: Connect_GetNetForceAndMass + PUBLIC :: Connect_AddLine + PUBLIC :: Connect_RemoveLine + + +CONTAINS + + + !-------------------------------------------------------------- + SUBROUTINE Connect_Initialize(Connect, states, m) + + Type(MD_Connect), INTENT(INOUT) :: Connect ! the Connection object + Real(DbKi), INTENT(INOUT) :: states(6) ! state vector section for this Connection + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + + INTEGER(IntKi) :: l + + + if (Connect%typeNum == 0) then ! error check + + ! pass kinematics to any attached lines so they have initial positions at this initialization stage + DO l=1,Connect%nAttached + IF (wordy > 1) print *, "Connect ", Connect%IdNum, " setting end kinematics of line ", Connect%attached(l), " to ", Connect%r + CALL Line_SetEndKinematics(m%LineList(Connect%attached(l)), Connect%r, Connect%rd, 0.0_DbKi, Connect%Top(l)) + END DO + + + ! assign initial node kinematics to state vector + states(4:6) = Connect%r + states(1:3) = Connect%rd + + + IF (wordy > 0) print *, "Initialized Connection ", Connect%IdNum + + else + CALL WrScr(" Error: wrong Point type given to Connect_Initialize for number "//trim(Int2Lstr(Connect%idNum))) + end if + + END SUBROUTINE Connect_Initialize + !-------------------------------------------------------------- + + + !-------------------------------------------------------------- + SUBROUTINE Connect_SetKinematics(Connect, r_in, rd_in, a_in, t, m) + + Type(MD_Connect), INTENT(INOUT) :: Connect ! the Connection object + Real(DbKi), INTENT(IN ) :: r_in( 3) ! position + Real(DbKi), INTENT(IN ) :: rd_in(3) ! velocity + Real(DbKi), INTENT(IN ) :: a_in(3) ! acceleration (only used for coupled connects) + Real(DbKi), INTENT(IN ) :: t ! instantaneous time + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + + + INTEGER(IntKi) :: l + + ! store current time + Connect%time = t + + + ! if (Connect%typeNum==0) THEN ! anchor ( <<< to be changed/expanded) ... in MoorDyn F also used for coupled connections + + ! set position and velocity + Connect%r = r_in + Connect%rd = rd_in + Connect%a = a_in + + ! pass latest kinematics to any attached lines + DO l=1,Connect%nAttached + CALL Line_SetEndKinematics(m%LineList(Connect%attached(l)), Connect%r, Connect%rd, t, Connect%Top(l)) + END DO + + ! else + ! + ! PRINT*,"Error: setKinematics called for wrong Connection type. Connection ", Connect%IdNum, " type ", Connect%typeNum + + ! END IF + + + END SUBROUTINE Connect_SetKinematics + !-------------------------------------------------------------- + + !-------------------------------------------------------------- + SUBROUTINE Connect_SetState(Connect, X, t, m) + + Type(MD_Connect), INTENT(INOUT) :: Connect ! the Connection object + Real(DbKi), INTENT(IN ) :: X(:) ! state vector section for this line + Real(DbKi), INTENT(IN ) :: t ! instantaneous time + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + + INTEGER(IntKi) :: l ! index of segments or nodes along line + INTEGER(IntKi) :: J ! index + + + ! store current time + Connect%time = t + + ! from state values, get r and rdot values + DO J=1,3 + Connect%r( J) = X(3 + J) ! get positions + Connect%rd(J) = X( J) ! get velocities + END DO + + ! pass latest kinematics to any attached lines + DO l=1,Connect%nAttached + CALL Line_SetEndKinematics(m%LineList(Connect%attached(l)), Connect%r, Connect%rd, t, Connect%Top(l)) + END DO + + END SUBROUTINE Connect_SetState + !-------------------------------------------------------------- + + !-------------------------------------------------------------- + SUBROUTINE Connect_GetStateDeriv(Connect, Xd, m, p) + + Type(MD_Connect), INTENT(INOUT) :: Connect ! the Connection object + Real(DbKi), INTENT(INOUT) :: Xd(:) ! state derivative vector section for this line + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + + TYPE(MD_ParameterType),INTENT(IN ) :: p ! Parameters + + !TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! misc/optimization variables + + !INTEGER(IntKi) :: l ! index of attached lines + INTEGER(IntKi) :: J ! index + INTEGER(IntKi) :: K ! index + Real(DbKi) :: Sum1 ! for adding things + + Real(DbKi) :: S(3,3) ! inverse mass matrix + + + CALL Connect_DoRHS(Connect, m, p) + +! // solve for accelerations in [M]{a}={f} using LU decomposition +! double M_tot[9]; // serialize total mass matrix for easy processing +! for (int I=0; I<3; I++) for (int J=0; J<3; J++) M_tot[3*I+J]=M[I][J]; +! double LU[9]; // serialized matrix that will hold LU matrices combined +! Crout(3, M_tot, LU); // perform LU decomposition on mass matrix +! double acc[3]; // acceleration vector to solve for +! solveCrout(3, LU, Fnet, acc); // solve for acceleration vector + + ! solve for accelerations in [M]{a}={f} using LU decomposition +! CALL LUsolve(6, M_out, LU_temp, Fnet_out, y_temp, acc) + + + ! invert node mass matrix + CALL Inverse3by3(S, Connect%M) + + ! accelerations + Connect%a = MATMUL(S, Connect%Fnet) + + ! fill in state derivatives + Xd(4:6) = Connect%rd ! dxdt = V (velocities) + Xd(1:3) = Connect%a ! dVdt = RHS * A (accelerations) + + + ! check for NaNs + DO J = 1, 6 + IF (Is_NaN(Xd(J))) THEN + CALL WrScr("NaN detected at time "//trim(Num2LStr(Connect%time))//" in Point "//trim(Int2LStr(Connect%IdNum))//" in MoorDyn.") + IF (wordy > 1) print *, "state derivatives:" + IF (wordy > 1) print *, Xd + EXIT + END IF + END DO + + END SUBROUTINE Connect_GetStateDeriv + !-------------------------------------------------------------- + + !-------------------------------------------------------------- + SUBROUTINE Connect_DoRHS(Connect, m, p) + + Type(MD_Connect), INTENT(INOUT) :: Connect ! the Connection object + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + TYPE(MD_ParameterType),INTENT(IN ) :: p ! Parameters + + !TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! misc/optimization variables + + INTEGER(IntKi) :: l ! index of attached lines + INTEGER(IntKi) :: I ! index + INTEGER(IntKi) :: J ! index + INTEGER(IntKi) :: K ! index + + Real(DbKi) :: Fnet_i(3) ! force from an attached line + Real(DbKi) :: Moment_dummy(3) ! dummy vector to hold unused line end moments + Real(DbKi) :: M_i(3,3) ! mass from an attached line + + + ! start with the Connection's own forces including buoyancy and weight, and its own mass + Connect%Fnet(1) = Connect%conFX + Connect%Fnet(2) = Connect%conFY + Connect%Fnet(3) = Connect%conFZ + Connect%conV*p%rhoW*p%g - Connect%conM*p%g + + Connect%M = 0.0_DbKi ! clear (zero) the connect mass matrix + + DO J = 1,3 + Connect%M (J,J) = Connect%conM ! set the diagonals to the self-mass (to start with) + END DO + + + ! print *, "connection number", Connect%IdNum + ! print *, "attached lines: ", Connect%attached + ! print *, "size of line list" , size(m%LineList) + + ! loop through attached lines, adding force and mass contributions + DO l=1,Connect%nAttached + + ! print *, " l", l + ! print *, Connect%attached(l) + ! print *, m%LineList(Connect%attached(l))%Fnet + ! + ! + ! print *, " attached line ID", m%LineList(Connect%attached(l))%IdNum + + CALL Line_GetEndStuff(m%LineList(Connect%attached(l)), Fnet_i, Moment_dummy, M_i, Connect%Top(l)) + + ! sum quantitites + Connect%Fnet = Connect%Fnet + Fnet_i + Connect%M = Connect%M + M_i + + END DO + + + ! XXXWhen this sub is called, any self weight, buoyancy, or external forcing should have already been + ! added by the calling subroutine. The only thing left is any added mass or drag forces from the connection (e.g. float) + ! itself, which will be added below.XXX + + + ! IF (EqualRealNos(t, 0.0_DbKi)) THEN ! this is old: with current IC gen approach, we skip the first call to the line objects, because they're set AFTER the call to the connects + ! + ! DO J = 1,3 + ! Xd(3+J) = X(J) ! velocities - 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 + ! DO J = 1,3 + ! Connect%r(J) = X(3 + J) ! get positions + ! Connect%rd(J) = X(J) ! get velocities + ! END DO + ! END IF + + + ! add any added mass and drag forces from the Connect body itself + DO J = 1,3 + Connect%Fnet(J) = Connect%Fnet(J) - 0.5 * p%rhoW * Connect%rd(J) * abs(Connect%rd(J)) * Connect%conCdA; ! add drag forces - corrected Nov 24 + Connect%M (J,J) = Connect%M (J,J) + Connect%conV*p%rhoW*Connect%conCa; ! add added mass + + END DO + + ! would this sub ever need to include the m*a inertial term? Is it ever called for coupled connects? <<< + + END SUBROUTINE Connect_DoRHS + !===================================================================== + + + ! calculate the force including inertial loads on connect that is coupled + !-------------------------------------------------------------- + SUBROUTINE Connect_GetCoupledForce(Connect, Fnet_out, m, p) + + Type(MD_Connect), INTENT(INOUT) :: Connect ! the Connect object + Real(DbKi), INTENT( OUT) :: Fnet_out(3) ! force and moment vector about rRef + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + TYPE(MD_ParameterType),INTENT(IN ) :: p ! Parameters + + Real(DbKi) :: F_iner(3) ! inertial force + + IF (Connect%typeNum == -1) then + ! calculate forces and masses of connect + CALL Connect_DoRHS(Connect, m, p) + + ! add inertial loads as appropriate + F_iner = -MATMUL(Connect%M, Connect%a) ! inertial loads + Fnet_out = Connect%Fnet + F_iner ! add inertial loads + + ELSE + CALL WrScr("Connect_GetCoupledForce called for wrong (uncoupled) Point type in MoorDyn!") + END IF + + END SUBROUTINE Connect_GetCoupledForce + + + ! calculate the force and mass contributions of the connect on the parent body (only for type 3 connects?) + !-------------------------------------------------------------- + SUBROUTINE Connect_GetNetForceAndMass(Connect, rRef, Fnet_out, M_out, m, p) + + Type(MD_Connect), INTENT(INOUT) :: Connect ! the Connect object + Real(DbKi), INTENT(IN ) :: rRef(3) ! global coordinates of reference point (i.e. the parent body) + Real(DbKi), INTENT( OUT) :: Fnet_out(6) ! force and moment vector about rRef + Real(DbKi), INTENT( OUT) :: M_out(6,6) ! mass and inertia matrix about rRef + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + TYPE(MD_ParameterType),INTENT(IN ) :: p ! Parameters + + Real(DbKi) :: rRel( 3) ! position of connection relative to the body reference point (global orientation frame) + + + CALL Connect_DoRHS(Connect, m, p) + + rRel = Connect%r - rRef ! vector from body reference point to node + + ! convert net force into 6dof force about body ref point + CALL translateForce3to6DOF(rRel, Connect%Fnet, Fnet_out) + + ! convert mass matrix to 6by6 mass matrix about body ref point + CALL translateMass3to6DOF(rRel, Connect%M, M_out) + + END SUBROUTINE Connect_GetNetForceAndMass + + + + + ! this function handles assigning a line to a connection node + !-------------------------------------------------------------- + SUBROUTINE Connect_AddLine(Connect, lineID, TopOfLine) + + Type(MD_Connect), INTENT (INOUT) :: Connect ! the Connection object + Integer(IntKi), INTENT( IN ) :: lineID + Integer(IntKi), INTENT( IN ) :: TopOfLine + + IF (wordy > 0) Print*, "L", lineID, "->C", Connect%IdNum + + IF (Connect%nAttached <10) THEN ! this is currently just a maximum imposed by a fixed array size. could be improved. + Connect%nAttached = Connect%nAttached + 1 ! add the line to the number connected + Connect%Attached(Connect%nAttached) = lineID + Connect%Top(Connect%nAttached) = TopOfLine ! attached to line ... 1 = top/fairlead(end B), 0 = bottom/anchor(end A) + ELSE + Print*, "Too many lines connected to Point ", Connect%IdNum, " in MoorDyn!" + END IF + + END SUBROUTINE Connect_AddLine + + + ! this function handles removing a line from a connection node + !-------------------------------------------------------------- + SUBROUTINE Connect_RemoveLine(Connect, lineID, TopOfLine, rEnd, rdEnd) + + Type(MD_Connect), INTENT (INOUT) :: Connect ! the Connection object + Integer(IntKi), INTENT( IN ) :: lineID + Integer(IntKi), INTENT( OUT) :: TopOfLine + REAL(DbKi), INTENT(INOUT) :: rEnd(3) + REAL(DbKi), INTENT(INOUT) :: rdEnd(3) + + Integer(IntKi) :: l,m,J + + DO l = 1,Connect%nAttached ! look through attached lines + + IF (Connect%Attached(l) == lineID) THEN ! if this is the line's entry in the attachment list + + TopOfLine = Connect%Top(l); ! record which end of the line was attached + + DO m = l,Connect%nAttached-1 + + Connect%Attached(m) = Connect%Attached(m+1) ! move subsequent line links forward one spot in the list to eliminate this line link + Connect%Top( m) = Connect%Top(m+1) + + Connect%nAttached = Connect%nAttached - 1 ! reduce attached line counter by 1 + + ! also pass back the kinematics at the end + DO J = 1,3 + rEnd( J) = Connect%r( J) + rdEnd(J) = Connect%rd(J) + END DO + + print*, "Detached line ", lineID, " from Connection ", Connect%IdNum + + EXIT + END DO + + IF (l == Connect%nAttached) THEN ! detect if line not found + print *, "Error: failed to find line to remove during removeLineFromConnect call to connection ", Connect%IdNum, ". Line ", lineID + END IF + + END IF + + END DO + + END SUBROUTINE Connect_RemoveLine + + + +END MODULE MoorDyn_Point diff --git a/modules/moordyn/src/MoorDyn_Registry.txt b/modules/moordyn/src/MoorDyn_Registry.txt index 636bfc9db..a3ed6ef2b 100644 --- a/modules/moordyn/src/MoorDyn_Registry.txt +++ b/modules/moordyn/src/MoorDyn_Registry.txt @@ -13,44 +13,118 @@ include Registry_NWTC_Library.txt +## ====== some data read from the input file, but not needed after init ====== +typedef MoorDyn/MD MD_InputFileType DbKi DTIC - 0.5 - "convergence check time step for IC generation" "[s]" +typedef ^ ^ DbKi TMaxIC - 120 - "maximum time to allow for getting converged ICs" "[s]" +typedef ^ ^ ReKi CdScaleIC - 1 - "factor to scale drag coefficients by during dynamic relaxation" "[]" +typedef ^ ^ ReKi threshIC - 0.01 - "convergence tolerance for ICs (0.01 means 1%)" "[]" -## ============================== Define input types here: ============================================================================================================================================ +## ============================== Define initialization input types here: ============================================================================================================================= typedef MoorDyn/MD InitInputType ReKi g - -999.9 - "gravity constant" "[m/s^2]" typedef ^ ^ ReKi rhoW - -999.9 - "sea density" "[kg/m^3]" typedef ^ ^ ReKi WtrDepth - -999.9 - "depth of water" "[m]" -typedef ^ ^ ReKi PtfmInit {6} - - "initial position of platform" - +typedef ^ ^ ReKi PtfmInit {:}{:} - - "initial position of platform(s) shape: 6, nTurbines" - +typedef ^ ^ IntKi FarmSize - 0 - "Indicates normal FAST module mode if 0, FAST.Farm coupled mode and =nTurbines if >0" - +typedef ^ ^ ReKi TurbineRefPos {:}{:} - - "reference position of turbines in farm, shape: 3, nTurbines" - +typedef ^ ^ ReKi Tmax - - - "simulation duration" "[s]" typedef ^ ^ CHARACTER(1024) FileName - "" - "MoorDyn input file" typedef ^ ^ CHARACTER(1024) RootName - - - "RootName for writing output files" - +typedef ^ ^ LOGICAL UsePrimaryInputFile - .TRUE. - "Read input file instead of passed data" - +typedef ^ ^ FileInfoType PassedPrimaryInputData - - - "Primary input file as FileInfoType (set by driver/glue code) -- String array with metadata" - typedef ^ ^ LOGICAL Echo - "" - "echo parameter - do we want to echo the header line describing the input file?" -typedef ^ ^ ReKi DTIC - - - "convergence check time step for IC generation" "[s]" -typedef ^ ^ ReKi TMaxIC - 120 - "maximum time to allow for getting converged ICs" "[s]" -typedef ^ ^ ReKi CdScaleIC - 1 - "factor to scale drag coefficients by during dynamic relaxation" "[]" -typedef ^ ^ ReKi threshIC - 0.01 - "convergence tolerance for ICs (0.01 means 1%)" "[]" -typedef ^ ^ CHARACTER(ChanLen) OutList {:} "" - "string containing list of output channels requested in input file" +typedef ^ ^ CHARACTER(ChanLen) OutList {:} "" - "string containing list of output channels requested in input file" +typedef ^ ^ Logical Linearize - .FALSE. - "Flag that tells this module if the glue code wants to linearize." - + +#typedef ^ ^ DbKi UGrid {:}{:}{:} - - "water velocities time series at each grid point" - +#typedef ^ ^ DbKi UdGrid {:}{:}{:} - - "water accelerations time series at each grid point" - +#typedef ^ ^ DbKi zetaGrid {:}{:} - - "water surface elevations time series at each grid point" - +#typedef ^ ^ DbKi PDynGrid {:}{:} - - "water dynamic pressure time series at each grid point" - +typedef ^ ^ ReKi WaveVel {:}{:}{:} - - "" - +typedef ^ ^ ReKi WaveAcc {:}{:}{:} - - "" - +typedef ^ ^ ReKi WavePDyn {:}{:} - - "" - +typedef ^ ^ ReKi WaveElev {:}{:} - - "" - +typedef ^ ^ DbKi WaveTime {:} - - "Should this be double precision?" - + +# nvm # Farm-level simulation inputs - these are passed by FAST.Farm - the arrays are populated from the individual turbine-level MoorDyn instances +# nvm typedef ^ ^ MeshType FarmCoupledKinematics {:} - - "array of input kinematics meshes from each of the turbine-level MoorDyn instances" "[m, m/s]" +# nvm typedef ^ ^ IntKi FarmNCpldBodies {:} - - "" "" +# nvm typedef ^ ^ IntKi FarmNCpldRods {:} - - "" "" +# nvm typedef ^ ^ IntKi FarmNCpldCons {:} - - "number of Fairlead Connections" "" # ====================================== Internal data types ======================================================================== # 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 ^ ^ CHARACTER(20) name - - - "name/identifier of this set of line properties" typedef ^ ^ DbKi d - - - "volume-equivalent diameter" "[m]" typedef ^ ^ DbKi w - - - "per-length weight in air" "[kg/m]" -typedef ^ ^ DbKi EA - - - "stiffness" "[N]" +typedef ^ ^ DbKi EA - - - "axial stiffness" "[N]" +typedef ^ ^ DbKi EA_D - - - "axial stiffness" "[N]" typedef ^ ^ DbKi BA - - - "internal damping coefficient times area" "[N-s]" +typedef ^ ^ DbKi BA_D - - - "internal damping coefficient times area" "[N-s]" +typedef ^ ^ DbKi EI - - - "bending stiffness" "[N-m]" 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" +typedef ^ ^ IntKi ElasticMod - - - "Which elasticity model to use: {0 basic, 1 viscoelastic, 2 future SYCOM} " - +typedef ^ ^ IntKi nEApoints - 0 - "number of values in stress-strain lookup table (0 means using constant E)" +typedef ^ ^ DbKi stiffXs {30} - - "x array for stress-strain lookup table (up to nCoef)" +typedef ^ ^ DbKi stiffYs {30} - - "y array for stress-strain lookup table" +typedef ^ ^ IntKi nBApoints - 0 - "number of values in stress-strainrate lookup table (0 means using constant c)" +typedef ^ ^ DbKi dampXs {30} - - "x array for stress-strainrate lookup table (up to nCoef)" +typedef ^ ^ DbKi dampYs {30} - - "y array for stress-strainrate lookup table " +typedef ^ ^ IntKi nEIpoints - 0 - "number of values in bending stress-strain lookup table (0 means using constant E)" +typedef ^ ^ DbKi bstiffXs {30} - - "x array for stress-strain lookup table (up to nCoef)" +typedef ^ ^ DbKi bstiffYs {30} - - "y array for stress-strain lookup table" + +# rod properties from rod dictionary input +typedef ^ MD_RodProp IntKi IdNum - - - "integer identifier of this set of rod properties" +typedef ^ ^ CHARACTER(10) name - - - "name/identifier of this set of rod properties" +typedef ^ ^ DbKi d - - - "volume-equivalent diameter" "[m]" +typedef ^ ^ DbKi w - - - "per-length weight in air" "[kg/m]" +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" +typedef ^ ^ DbKi CdEnd - - - "drag coefficient for rod end" "[-]" +typedef ^ ^ DbKi CaEnd - - - "added mass coefficient for rod end" "[-]" + +# this is the Body type, which holds data for each body object +typedef ^ MD_Body IntKi IdNum - - - "integer identifier of this Connection" +typedef ^ ^ IntKi typeNum - - - "integer identifying the type. 0=fixed, 1=vessel, 2=connect" +typedef ^ ^ IntKi AttachedC {30} - - "list of IdNums of connections attached to this body" +typedef ^ ^ IntKi AttachedR {30} - - "list of IdNums of rods attached to this body" +typedef ^ ^ IntKi nAttachedC - 0 - "number of attached connections" +typedef ^ ^ IntKi nAttachedR - 0 - "number of attached rods" +typedef ^ ^ DbKi rConnectRel {3}{30} - - "relative position of connection on body" +typedef ^ ^ DbKi r6RodRel {6}{30} - - "relative position and orientation of rod on body" +typedef ^ ^ DbKi bodyM - - - "" +typedef ^ ^ DbKi bodyV - - - "" +typedef ^ ^ DbKi bodyI {3} - - "" +typedef ^ ^ DbKi bodyCdA {6} - - "product of drag force and frontal area of connection point" "[m^2]" +typedef ^ ^ DbKi bodyCa {6} - - "added mass coefficient of connection point" "-" +typedef ^ ^ DbKi time - - - "current time" "[s]" +typedef ^ ^ DbKi r6 {6} - - "position" +typedef ^ ^ DbKi v6 {6} - - "velocity" +typedef ^ ^ DbKi a6 {6} - - "acceleration (only used for coupled bodies)" +typedef ^ ^ DbKi U {3} - - "water velocity at ref point" "[m/s]" +typedef ^ ^ DbKi Ud {3} - - "water acceleration at ref point" "[m/s^2]" +typedef ^ ^ DbKi zeta - - - "water surface elevation above ref point" "[m]" +typedef ^ ^ DbKi F6net {6} - - "total force and moment on body (excluding inertial loads)" +typedef ^ ^ DbKi M6net {6}{6} - - "total mass matrix of Body and any attached objects" +typedef ^ ^ DbKi M {6}{6} - - "rotated body 6-dof mass and inertia matrix in global orientation" +typedef ^ ^ DbKi M0 {6}{6} - - "body 6-dof mass and inertia matrix in its own frame" +typedef ^ ^ DbKi OrMat {3}{3} - - "DCM for body orientation" +typedef ^ ^ DbKi rCG {3} - - "vector in body frame from ref point to CG (before rods etc..)" # this is the Connection type, which holds data for each connection object typedef ^ MD_Connect IntKi IdNum - - - "integer identifier of this Connection" typedef ^ ^ CHARACTER(10) type - - - "type of Connect: fix, vessel, connect" -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 ^ ^ DbKi conX - - - "" -typedef ^ ^ DbKi conY - - - "" -typedef ^ ^ DbKi conZ - - - "" +typedef ^ ^ IntKi typeNum - - - "integer identifying the type. 0=fixed, 1=vessel, 2=connect" +typedef ^ ^ IntKi Attached {10} - - "list of IdNums of lines attached to this connection node" +typedef ^ ^ IntKi Top {10} - - "list of ints specifying whether each line is attached at 1 = top/fairlead(end B), 0 = bottom/anchor(end A)" +typedef ^ ^ IntKi nAttached - 0 - "number of attached lines" typedef ^ ^ DbKi conM - - - "" typedef ^ ^ DbKi conV - - - "" typedef ^ ^ DbKi conFX - - - "" @@ -58,31 +132,127 @@ 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 time - - - "current time" "[s]" typedef ^ ^ DbKi r {3} - - "position" typedef ^ ^ DbKi rd {3} - - "velocity" +typedef ^ ^ DbKi a {3} - - "acceleration (only used for coupled points)" +typedef ^ ^ DbKi U {3} - - "water velocity at node" "[m/s]" +typedef ^ ^ DbKi Ud {3} - - "water acceleration at node" "[m/s^2]" +typedef ^ ^ DbKi zeta - - - "water surface elevation above node" "[m]" +typedef ^ ^ DbKi PDyn {:} - - "water dynamic pressure at node" "[Pa]" +typedef ^ ^ DbKi Fnet {3} - - "total force on node (excluding inertial loads)" +typedef ^ ^ DbKi M {3}{3} - - "node mass matrix, from attached lines" + +# this is the Rod type, which holds data for each Rod object +typedef ^ MD_Rod IntKi IdNum - - - "integer identifier of this Line" +typedef ^ ^ CHARACTER(10) type - - - "type of Rod. should match one of RodProp names" +typedef ^ ^ IntKi PropsIdNum - - - "the IdNum of the associated rod properties" - +typedef ^ ^ IntKi typeNum - - - "integer identifying the type. 0=fixed, 1=vessel, 2=connect" +typedef ^ ^ IntKi AttachedA {10} - - "list of IdNums of lines attached to end A" +typedef ^ ^ IntKi AttachedB {10} - - "list of IdNums of lines attached to end B" +typedef ^ ^ IntKi TopA {10} - - "list of ints specifying whether each line is attached at 1 = top/fairlead(end B), 0 = bottom/anchor(end A)" +typedef ^ ^ IntKi TopB {10} - - "list of ints specifying whether each line is attached at 1 = top/fairlead(end B), 0 = bottom/anchor(end A)" +typedef ^ ^ IntKi nAttachedA - 0 - "number of attached lines to Rod end A" +typedef ^ ^ IntKi nAttachedB - 0 - "number of attached lines to Rod end B" +typedef ^ ^ IntKi OutFlagList {20} - - "array specifying what line quantities should be output (1 vs 0)" - +typedef ^ ^ IntKi N - - - "The number of elements in the line" - +typedef ^ ^ IntKi endTypeA - - - "type of connection at end A: 0=pinned to Connection, 1=cantilevered to Rod." - +typedef ^ ^ IntKi endTypeB - - - "type of connection at end B: 0=pinned to Connection, 1=cantilevered to Rod." - +typedef ^ ^ DbKi UnstrLen - - - "length of the rod" "[m]" +typedef ^ ^ DbKi mass - - - "mass of the rod" "[kg]" +typedef ^ ^ DbKi rho - - - "density" "[kg/m3]" +typedef ^ ^ DbKi d - - - "volume-equivalent diameter" "[m]" +typedef ^ ^ DbKi Can - - - "" "[-]" +typedef ^ ^ DbKi Cat - - - "" "[-]" +typedef ^ ^ DbKi Cdn - - - "" "[-]" +typedef ^ ^ DbKi Cdt - - - "" "[-]" +typedef ^ ^ DbKi CdEnd - - - "drag coefficient for rod end" "[-]" +typedef ^ ^ DbKi CaEnd - - - "added mass coefficient for rod end" "[-]" +typedef ^ ^ DbKi time - - - "current time" "[s]" +typedef ^ ^ DbKi roll - - - "roll relative to vertical" "deg" +typedef ^ ^ DbKi pitch - - - "pitch relative to vertical" "deg" +typedef ^ ^ DbKi h0 - - - "submerged length of rod axis, distance along rod centerline from end A to the waterplane (0 <= h0 <= L)" "m" +typedef ^ ^ DbKi r {:}{:} - - "node positions" - +typedef ^ ^ DbKi rd {:}{:} - - "node velocities" - +typedef ^ ^ DbKi q {3} - - "tangent vector for rod as a whole" - +typedef ^ ^ DbKi l {:} - - "segment unstretched length" "[m]" +typedef ^ ^ DbKi V {:} - - "segment volume" "[m^3]" +typedef ^ ^ DbKi U {:}{:} - - "water velocity at node" "[m/s]" +typedef ^ ^ DbKi Ud {:}{:} - - "water acceleration at node" "[m/s^2]" +typedef ^ ^ DbKi zeta {:} - - "water surface elevation above node" "[m]" +typedef ^ ^ DbKi PDyn {:} - - "water dynamic pressure at node" "[Pa]" +typedef ^ ^ DbKi W {:}{:} - - "weight vectors" "[N]" +typedef ^ ^ DbKi Bo {:}{:} - - "buoyancy force vectors" "[N]" +typedef ^ ^ DbKi Pd {:}{:} - - "dynamic pressure force 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 Fnet {:}{:} - - "total force on node" "[N]" +typedef ^ ^ DbKi M {:}{:}{:} - - "node mass matrix" "[kg]" +typedef ^ ^ DbKi FextA {3} - - "external forces from attached lines on/about end A " - +typedef ^ ^ DbKi FextB {3} - - "external forces from attached lines on/about end A " - +typedef ^ ^ DbKi Mext {3} - - "external moment vector holding sum of any externally applied moments i.e. bending lines" - +typedef ^ ^ DbKi r6 {6} - - "6 DOF position vector" - +typedef ^ ^ DbKi v6 {6} - - "6 DOF velocity vector" - +typedef ^ ^ DbKi a6 {6} - - "6 DOF acceleration vector (only used for coupled Rods)" - +typedef ^ ^ DbKi F6net {6} - - "total force and moment about end A (excluding inertial loads) that Rod may exert on whatever it's attached to" +typedef ^ ^ DbKi M6net {6}{6} - - "total mass matrix about end A of Rod and any attached Points" +typedef ^ ^ DbKi OrMat {3}{3} - - "DCM for body orientation" +typedef ^ ^ IntKi RodUnOut - - - "unit number of rod output file" +typedef ^ ^ DbKi RodWrOutput {:} - - "one row of output data for this rod" + # this is the Line type, which holds data for each line object typedef ^ MD_Line IntKi IdNum - - - "integer identifier of this Line" -typedef ^ ^ CHARACTER(10) type - - - "type of line. should match one of LineProp names" +#typedef ^ ^ CHARACTER(10) type - - - "type of line. should match one of LineProp names" +typedef ^ ^ IntKi PropsIdNum - - - "the IdNum of the associated line properties" - +typedef ^ ^ IntKi ElasticMod - - - "Which elasticity model to use: {0 basic, 1 viscoelastic, 2 future SYCOM} " - typedef ^ ^ IntKi OutFlagList {20} - - "array specifying what line quantities should be output (1 vs 0)" - -typedef ^ ^ IntKi CtrlChan - - - "index of control channel that will drive line active tensioning (0 for none)" - +typedef ^ ^ IntKi CtrlChan - 0 - "index of control channel that will drive line active tensioning (0 for none)" - typedef ^ ^ IntKi FairConnect - - - "IdNum of Connection at fairlead" 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 ^ ^ IntKi endTypeA - - - "type of connection at end A: 0=pinned to Connection, 1=cantilevered to Rod." - +typedef ^ ^ IntKi endTypeB - - - "type of connection at end B: 0=pinned to Connection, 1=cantilevered to Rod." - typedef ^ ^ DbKi UnstrLen - - - "unstretched length of the line" - -typedef ^ ^ DbKi BA - - - "internal damping coefficient times area for this line only" "[N-s]" +typedef ^ ^ DbKi rho - - - "density" "[kg/m3]" +typedef ^ ^ DbKi d - - - "volume-equivalent diameter" "[m]" +typedef ^ ^ DbKi EA - 0 - "stiffness" "[N]" +typedef ^ ^ DbKi EA_D - 0 - "dynamic stiffness when using viscoelastic model" "[N]" +typedef ^ ^ DbKi BA - 0 - "internal damping coefficient times area for this line only" "[N-s]" +typedef ^ ^ DbKi BA_D - 0 - "dynamic internal damping coefficient times area when using viscoelastic model" "[N-s]" +typedef ^ ^ DbKi EI - 0 - "bending stiffness" "[N-m]" +typedef ^ ^ DbKi Can - - - "" "[-]" +typedef ^ ^ DbKi Cat - - - "" "[-]" +typedef ^ ^ DbKi Cdn - - - "" "[-]" +typedef ^ ^ DbKi Cdt - - - "" "[-]" +typedef ^ ^ IntKi nEApoints - 0 - "number of values in stress-strain lookup table (0 means using constant E)" +typedef ^ ^ DbKi stiffXs {30} - - "x array for stress-strain lookup table (up to nCoef)" +typedef ^ ^ DbKi stiffYs {30} - - "y array for stress-strain lookup table" +typedef ^ ^ IntKi nBApoints - 0 - "number of values in stress-strainrate lookup table (0 means using constant c)" +typedef ^ ^ DbKi dampXs {30} - - "x array for stress-strainrate lookup table (up to nCoef)" +typedef ^ ^ DbKi dampYs {30} - - "y array for stress-strainrate lookup table " +typedef ^ ^ IntKi nEIpoints - 0 - "number of values in bending stress-strain lookup table (0 means using constant E)" +typedef ^ ^ DbKi bstiffXs {30} - - "x array for stress-strain lookup table (up to nCoef)" +typedef ^ ^ DbKi bstiffYs {30} - - "y array for stress-strain lookup table" +typedef ^ ^ DbKi time - - - "current time" "[s]" typedef ^ ^ DbKi r {:}{:} - - "node positions" - typedef ^ ^ DbKi rd {:}{:} - - "node velocities" - typedef ^ ^ DbKi q {:}{:} - - "node tangent vectors" - +typedef ^ ^ DbKi qs {:}{:} - - "segment 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 Kurv {:} - - "curvature at each node point" "[1/m]" +typedef ^ ^ DbKi dl_1 {:} - - "segment stretch attributed to static stiffness portion" "[m]" typedef ^ ^ DbKi V {:} - - "segment volume" "[m^3]" +typedef ^ ^ DbKi U {:}{:} - - "water velocity at node" "[m/s]" +typedef ^ ^ DbKi Ud {:}{:} - - "water acceleration at node" "[m/s^2]" +typedef ^ ^ DbKi zeta {:} - - "water surface elevation above node" "[m]" +typedef ^ ^ DbKi PDyn {:} - - "water dynamic pressure at node" "[Pa]" typedef ^ ^ DbKi T {:}{:} - - "segment tension vectors" "[N]" typedef ^ ^ DbKi Td {:}{:} - - "segment internal damping force vectors" "[N]" typedef ^ ^ DbKi W {:}{:} - - "weight/buoyancy vectors" "[N]" @@ -91,17 +261,22 @@ typedef ^ ^ DbKi Dq {:}{:} 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 Bs {:}{:} - - "node force due to bending moments" "[N]" +typedef ^ ^ DbKi Fnet {:}{:} - - "total force on node" "[N]" typedef ^ ^ DbKi S {:}{:}{:} - - "node inverse mass matrix" "[kg]" typedef ^ ^ DbKi M {:}{:}{:} - - "node mass matrix" "[kg]" +typedef ^ ^ DbKi EndMomentA {3} - - "vector of end moments due to bending at line end A" "[N-m]" +typedef ^ ^ DbKi EndMomentB {3} - - "vector of end moments due to bending at line end B" "[N-m]" typedef ^ ^ IntKi LineUnOut - - - "unit number of line output file" -typedef ^ ^ ReKi LineWrOutput {:} - - "one row of output data for this line" +typedef ^ ^ DbKi LineWrOutput {:} - - "one row of output data for this line" +# this is the Fail type, which holds data for possible line failure descriptors TO BE FILLED IN LATER +typedef ^ MD_Fail IntKi IdNum - - - "integer identifier of this failure" # this is the MDOutParmType - a less literal alternative of the NWTC OutParmType for MoorDyn (to avoid huge lists of possible output channel permutations) -typedef ^ MD_OutParmType CHARACTER(ChanLen) Name - - - "name of output channel" -typedef ^ ^ CHARACTER(ChanLen) Units - - - "units string" +typedef ^ MD_OutParmType CHARACTER(10) Name - - - "name of output channel" +typedef ^ ^ CHARACTER(10) Units - - - "units string" typedef ^ ^ IntKi QType - - - "type of quantity - 0=tension, 1=x, 2=y, 3=z..." typedef ^ ^ IntKi OType - - - "type of object - 0=line, 1=connect" typedef ^ ^ IntKi NodeID - - - "node number if OType=0. 0=anchor, -1=N=Fairlead" @@ -113,63 +288,154 @@ typedef ^ InitOutputType CHARACTER(ChanLen) writeOutputHdr {:} " typedef ^ ^ CHARACTER(ChanLen) writeOutputUnt {:} "" - "second line of output file contents: units" typedef ^ ^ ProgDesc Ver - "" - "this module's name, version, and date" typedef ^ ^ LOGICAL CableCChanRqst {:} .FALSE. - "flag indicating control channel for drive line active tensioning is requested" - +# --- InitOutputs for linearization --- +typedef ^ ^ CHARACTER(LinChanLen) LinNames_y {:} - - "Names of the outputs used in linearization" - +typedef ^ ^ CHARACTER(LinChanLen) LinNames_x {:} - - "Names of the continuous states used in linearization" - +typedef ^ ^ CHARACTER(LinChanLen) LinNames_u {:} - - "Names of the inputs used in linearization" - +typedef ^ ^ LOGICAL RotFrame_y {:} - - "Flag that tells FAST/MBC3 if the outputs used in linearization are in the rotating frame" - +typedef ^ ^ 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 ^ ^ 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" - ## ============================== Define Continuous states here: ===================================================================================================================================== -typedef ^ ContinuousStateType DbKi states {:} "" - "full list of node coordinates and velocities" "[m] or [m/s]" - +typedef ^ ContinuousStateType DbKi states {:} "" - "state vector of mooring system, e.g. node coordinates and velocities" "" ## ============================== Define Discrete states here: ===================================================================================================================================== typedef ^ DiscreteStateType SiKi dummy - - - "Remove this variable if you have discrete states" - - ## ============================== Define constraint states here: ===================================================================================================================================== typedef ^ ConstraintStateType SiKi dummy - - - "Remove this variable if you have constraint states" - - ## ============================== Define Other states here: ===================================================================================================================================== typedef ^ OtherStateType SiKi dummy - - - "Remove this variable if you have other states" - ## ============================== Define Misc variables here: ===================================================================================================================================== typedef ^ MiscVarType MD_LineProp LineTypeList {:} - - "array of properties for each line type" - -typedef ^ ^ MD_Connect ConnectList {:} - - "array of connection properties" - -typedef ^ ^ MD_Line LineList {:} - - "array of line properties" - -typedef ^ ^ IntKi FairIdList {:} - - "array of size NFairs listing the ID of each fairlead (index of ConnectList)" "" -typedef ^ ^ IntKi ConnIdList {:} - - "array of size NConnss listing the ID of each connect type connection (index of ConnectList)" "" -typedef ^ ^ IntKi LineStateIndList {:} - - "starting index of each line's states in state vector" "" -typedef ^ ^ ReKi MDWrOutput {:} - - "Data from time step to be written to a MoorDyn output file" +typedef ^ ^ MD_RodProp RodTypeList {:} - - "array of properties for each rod type" - +typedef ^ ^ MD_Body GroundBody - - - "the single ground body which is the parent of all stationary connections" - +typedef ^ ^ MD_Body BodyList {:} - - "array of body objects" - +typedef ^ ^ MD_Rod RodList {:} - - "array of rod objects" - +typedef ^ ^ MD_Connect ConnectList {:} - - "array of connection objects" - +typedef ^ ^ MD_Line LineList {:} - - "array of line objects" - +typedef ^ ^ MD_Fail FailList {:} - - "array of line objects" - +typedef ^ ^ IntKi FreeConIs {:} - - "array of free connection indices in ConnectList vector" "" +typedef ^ ^ IntKi CpldConIs {:}{:} - - "array of coupled/fairlead connection indices in ConnectList vector" "" +typedef ^ ^ IntKi FreeRodIs {:} - - "array of free rod indices in RodList vector" "" +typedef ^ ^ IntKi CpldRodIs {:}{:} - - "array of coupled/fairlead rod indices in RodList vector" "" +typedef ^ ^ IntKi FreeBodyIs {:} - - "array of free body indices in BodyList vector" "" +typedef ^ ^ IntKi CpldBodyIs {:}{:} - - "array of coupled body indices in BodyList vector" "" +typedef ^ ^ IntKi LineStateIs1 {:} - - "starting index of each line's states in state vector" "" +typedef ^ ^ IntKi LineStateIsN {:} - - "ending index of each line's states in state vector" "" +typedef ^ ^ IntKi ConStateIs1 {:} - - "starting index of each line's states in state vector" "" +typedef ^ ^ IntKi ConStateIsN {:} - - "ending index of each line's states in state vector" "" +typedef ^ ^ IntKi RodStateIs1 {:} - - "starting index of each rod's states in state vector" "" +typedef ^ ^ IntKi RodStateIsN {:} - - "ending index of each rod's states in state vector" "" +typedef ^ ^ IntKi BodyStateIs1 {:} - - "starting index of each body's states in state vector" "" +typedef ^ ^ IntKi BodyStateIsN {:} - - "ending index of each body's states in state vector" "" +typedef ^ ^ IntKi Nx - - - "number of states and size of state vector" "" +typedef ^ ^ IntKi WaveTi - - - "current interpolation index for wave time series data" "" +typedef ^ ^ MD_ContinuousStateType xTemp - - - "contains temporary state vector used in integration (put here so it's only allocated once)" +typedef ^ ^ MD_ContinuousStateType xdTemp - - - "contains temporary state derivative vector used in integration (put here so it's only allocated once)" +typedef ^ ^ DbKi zeros6 {6} - - "array of zeros for convenience" +typedef ^ ^ DbKi MDWrOutput {:} - - "Data from time step to be written to a MoorDyn output file" +typedef ^ ^ DbKi LastOutTime - - - "Time of last writing to MD output files" +typedef ^ ^ ReKi PtfmInit {6} - - "initial position of platform for an individual (non-farm) MD instance" - +typedef ^ ^ DbKi BathymetryGrid {:}{:} - - "matrix describing the bathymetry in a grid of x's and y's" +typedef ^ ^ DbKi BathGrid_Xs {:} - - "array of x-coordinates in the bathymetry grid" +typedef ^ ^ DbKi BathGrid_Ys {:} - - "array of y-coordinates in the bathymetry grid" +typedef ^ ^ IntKi BathGrid_npoints {:} - - "number of grid points to describe the bathymetry grid" ## ============================== Parameters ============================================================================================================================================ -typedef ^ ParameterType IntKi NTypes - - - "number of line types" "" -typedef ^ ^ IntKi NConnects - - - "number of Connection objects" "" -typedef ^ ^ IntKi NFairs - - - "number of Fairlead Connections" "" -typedef ^ ^ IntKi NConns - - - "number of Connect type Connections - not to be confused with NConnects" "" -typedef ^ ^ IntKi NAnchs - - - "number of Anchor type Connections" "" -typedef ^ ^ IntKi NLines - - - "number of Line objects" "" -typedef ^ ^ ReKi g - 9.81 - "gravitational constant" "[kg/m^2]" -typedef ^ ^ ReKi rhoW - - - "density of seawater" "[m]" -typedef ^ ^ ReKi WtrDpth - - - "water depth" "[m]" -typedef ^ ^ ReKi kBot - - - "bottom stiffness" "[Pa/m]" -typedef ^ ^ ReKi cBot - - - "bottom damping" "[Pa-s/m]" -typedef ^ ^ ReKi dtM0 - - - "desired mooring model time step" "[s]" -typedef ^ ^ ReKi dtCoupling - - - "coupling time step that MoorDyn should expect" "[s]" +typedef ^ ParameterType IntKi nLineTypes - 0 - "number of line types" "" +typedef ^ ^ IntKi nRodTypes - 0 - "number of rod types" "" +typedef ^ ^ IntKi nConnects - 0 - "number of Connection objects" "" +typedef ^ ^ IntKi nConnectsExtra - 0 - "number of Connection objects including space for extra ones that could arise from line failures" "" +typedef ^ ^ IntKi nBodies - 0 - "number of Body objects" "" +typedef ^ ^ IntKi nRods - 0 - "number of Rod objects" "" +typedef ^ ^ IntKi nLines - 0 - "number of Line objects" "" +typedef ^ ^ IntKi nCtrlChans - 0 - "number of distinct control channels specified for use as inputs" "" +typedef ^ ^ IntKi nFails - 0 - "number of failure conditions" "" +typedef ^ ^ IntKi nFreeBodies - 0 - "" "" +typedef ^ ^ IntKi nFreeRods - 0 - "" "" +typedef ^ ^ IntKi nFreeCons - 0 - "" "" +typedef ^ ^ IntKi nCpldBodies {:} - - "number of coupled bodies (for FAST.Farm, size>1 with an entry for each turbine)" "" +typedef ^ ^ IntKi nCpldRods {:} - - "number of coupled rods (for FAST.Farm, size>1 with an entry for each turbine)" "" +typedef ^ ^ IntKi nCpldCons {:} - - "number of coupled points (for FAST.Farm, size>1 with an entry for each turbine)" "" +typedef ^ ^ IntKi NConns - 0 - "number of Connect type Connections - not to be confused with NConnects" "" +typedef ^ ^ IntKi NAnchs - 0 - "number of Anchor type Connections" "" +typedef ^ ^ DbKi Tmax - - - "simulation duration" "[s]" +typedef ^ ^ DbKi g - 9.81 - "gravitational constant (positive)" "[m/s^2]" +typedef ^ ^ DbKi rhoW - 1025 - "density of seawater" "[kg/m^3]" +typedef ^ ^ DbKi WtrDpth - - - "water depth" "[m]" +typedef ^ ^ DbKi kBot - - - "bottom stiffness" "[Pa/m]" +typedef ^ ^ DbKi cBot - - - "bottom damping" "[Pa-s/m]" +typedef ^ ^ DbKi dtM0 - - - "desired mooring model time step" "[s]" +typedef ^ ^ DbKi dtCoupling - - - "coupling time step that MoorDyn should expect" "[s]" typedef ^ ^ IntKi NumOuts - - - "Number of parameters in the output list (number of outputs requested)" - +typedef ^ ^ DbKi dtOut - - - "interval for writing output file lines" "[s]" typedef ^ ^ CHARACTER(1024) RootName - - - "RootName for writing output files" - typedef ^ ^ MD_OutParmType OutParam {:} - - "Names and units (and other characteristics) of all requested output parameters" - typedef ^ ^ CHARACTER(1) Delim - - - "Column delimiter for output text files" - typedef ^ ^ IntKi MDUnOut - - - "Unit number of main output file" +typedef ^ ^ CHARACTER(1024) PriPath - - - "The path to the primary MoorDyn input file, used if looking for additional input files" +typedef ^ ^ IntKi writeLog - -1 - "Switch for level of log file output" +#NOTE: there may be an issue with start/restart with the UnLog stored in parameters. We'll ignore this for now -- ADP +typedef ^ ^ IntKi UnLog - -1 - "Unit number of log file" +typedef ^ ^ IntKi WaveKin - - - "Flag for whether or how to consider water kinematics" +typedef ^ ^ IntKi Current - - - "Flag for whether or how to consider water kinematics" +typedef ^ ^ IntKi nTurbines - - - "Number of turbines if MoorDyn is performing an array-level simulation with FAST.Farm, otherwise 0" +typedef ^ ^ ReKi TurbineRefPos {:}{:} - - "reference position of turbines in farm, shape: 3, nTurbines" - +typedef ^ ^ DbKi mu_kT - - - "transverse kinetic friction coefficient" "(-)" +typedef ^ ^ DbKi mu_kA - - - "axial kinetic friction coefficient" "(-)" +typedef ^ ^ DbKi mc - - - "ratio of the static friction coefficient to the kinetic friction coefficient" "(-)" +typedef ^ ^ DbKi cv - - - "saturated damping coefficient" "(-)" +# --- parameters for wave and current --- +typedef ^ ^ IntKi nxWave - - - "number of x wave grid points" - +typedef ^ ^ IntKi nyWave - - - "number of y wave grid points" - +typedef ^ ^ IntKi nzWave - - - "number of z wave grid points" - +typedef ^ ^ IntKi ntWave - - - "number of wave time steps" - +typedef ^ ^ SiKi pxWave {:} - - "x location of wave grid points" - +typedef ^ ^ SiKi pyWave {:} - - "y location of wave grid points" - +typedef ^ ^ SiKi pzWave {:} - - "z location of wave grid points" - +typedef ^ ^ SiKi dtWave - - - "wave data time step" - +typedef ^ ^ SiKi uxWave {:}{:}{:}{:} - - "wave velocities time series at each grid point" - +typedef ^ ^ SiKi uyWave {:}{:}{:}{:} - - "wave velocities time series at each grid point" - +typedef ^ ^ SiKi uzWave {:}{:}{:}{:} - - "wave velocities time series at each grid point" - +typedef ^ ^ SiKi axWave {:}{:}{:}{:} - - "wave accelerations time series at each grid point" - +typedef ^ ^ SiKi ayWave {:}{:}{:}{:} - - "wave accelerations time series at each grid point" - +typedef ^ ^ SiKi azWave {:}{:}{:}{:} - - "wave accelerations time series at each grid point" - +typedef ^ ^ SiKi PDyn {:}{:}{:}{:} - - "wave dynamic pressure time series at each grid point" - +typedef ^ ^ SiKi zeta {:}{:}{:} - - "wave surface elevations time series at each surface grid point" - +typedef ^ ^ IntKi nzCurrent - - - "number of z current grid points" - +typedef ^ ^ SiKi pzCurrent {:} - - "z location of current grid points" - +typedef ^ ^ SiKi uxCurrent {:} - - "current velocities time series at each grid point" - +typedef ^ ^ SiKi uyCurrent {:} - - "current velocities time series at each grid point" - +# --- Parameters for linearization --- +typedef ^ ^ Integer Nx0 - - - "copy of initial size of system state vector, for linearization routines" - +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_nx - - - "number of continuous states in jacobian matrix" - +typedef ^ ^ Integer dxIdx_map2_xStateIdx {:} - - "Mapping array from index of dX array to corresponding state index" - # ============================== Inputs ============================================================================================================================================ -typedef ^ InputType MeshType PtFairleadDisplacement - - - "mesh for position AND VELOCITY of each fairlead in X,Y,Z" "[m, m/s]" -# typedef ^ ^ MeshType HydroForceLineMesh - - - "Meshed input data" - -typedef ^ ^ ReKi DeltaL {:} - - "change in line length command for each channel" "[m]" -typedef ^ ^ ReKi DeltaLdot {:} - - "rate of change of line length command for each channel" "[m]" +typedef ^ InputType MeshType CoupledKinematics {:} - - "array of meshes for each coupling point (6 DOF info used for rods and bodies)" "[m, m/s]" <<<< will use this eventually! +typedef ^ ^ ReKi DeltaL {:} - - "change in line length command for each channel" "[m]" +typedef ^ ^ ReKi DeltaLdot {:} - - "rate of change of line length command for each channel" "[m]" +#typedef ^ ^ DbKi U {:}{:} - - "water velocities at each node" - +#typedef ^ ^ DbKi Ud {:}{:} - - "water accelerations at each node" - +#typedef ^ ^ DbKi zeta {:} - - "water surface elevations above each node" - +#typedef ^ ^ DbKi PDyn {:} - - "water dynamic pressure at each node" - ## ============================== Outputs ============================================================================================================================================ -typedef ^ OutputType MeshType PtFairleadLoad - - - "point mesh for fairlead forces in X,Y,Z" "[N]" +typedef ^ OutputType MeshType CoupledLoads {:} - - "array of point meshes for mooring reaction forces (and moments) at coupling points" "[N]" typedef ^ ^ ReKi WriteOutput {:} - - "output vector returned to glue code" "" -# typedef ^ ^ MeshType LineMeshPosition - - - "Meshed output data" - +# should CoupledLoads be an array? +#typedef ^ ^ DbKi rAll {:}{:} - - "Mesh of all point positions: bodies, rods, points, line internal nodes" - diff --git a/modules/moordyn/src/MoorDyn_Rod.f90 b/modules/moordyn/src/MoorDyn_Rod.f90 new file mode 100644 index 000000000..26bd00c96 --- /dev/null +++ b/modules/moordyn/src/MoorDyn_Rod.f90 @@ -0,0 +1,1194 @@ +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2020-2021 Alliance for Sustainable Energy, LLC +! Copyright (C) 2015-2019 Matthew Hall +! +! This file is part of MoorDyn. +! +! 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 MoorDyn_Rod + + USE MoorDyn_Types + USE MoorDyn_IO + USE NWTC_Library + USE MoorDyn_Misc + USE MoorDyn_Line, only : Line_SetEndKinematics, Line_GetEndStuff, Line_SetEndOrientation, Line_GetEndSegmentInfo + + IMPLICIT NONE + + PRIVATE + + INTEGER(IntKi), PARAMETER :: wordy = 0 ! verbosity level. >1 = more console output + + PUBLIC :: Rod_Setup + PUBLIC :: Rod_Initialize + PUBLIC :: Rod_SetKinematics + PUBLIC :: Rod_SetState + PUBLIC :: Rod_GetStateDeriv + PUBLIC :: Rod_DoRHS + PUBLIC :: Rod_GetCoupledForce + PUBLIC :: Rod_GetNetForceAndMass + PUBLIC :: Rod_AddLine + PUBLIC :: Rod_RemoveLine + + + +CONTAINS + + + !----------------------------------------------------------------------- + SUBROUTINE Rod_Setup(Rod, RodProp, endCoords, p, ErrStat, ErrMsg) + + TYPE(MD_Rod), INTENT(INOUT) :: Rod ! the single rod object of interest + TYPE(MD_RodProp), INTENT(INOUT) :: RodProp ! the single rod property set for the line of interest + REAL(DbKi), INTENT(IN) :: endCoords(6) + TYPE(MD_ParameterType), INTENT(IN ) :: p ! Parameters + INTEGER, INTENT( INOUT ) :: ErrStat ! returns a non-zero value when an error occurs + CHARACTER(*), INTENT( INOUT ) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + INTEGER(4) :: i ! Generic index + INTEGER(4) :: K ! Generic index + INTEGER(IntKi) :: N + + Real(DbKi) :: phi, beta, sinPhi, cosPhi, tanPhi, sinBeta, cosBeta ! various orientation things + Real(DbKi) :: k_hat(3) ! unit vector (redundant, not used) <<<< + + INTEGER :: ErrStat2 + + N = Rod%N ! number of segments in this line (for code readability) + + ! -------------- save some section properties to the line object itself ----------------- + + Rod%d = RodProp%d + Rod%rho = RodProp%w/(Pi/4.0 * Rod%d * Rod%d) + + Rod%Can = RodProp%Can + Rod%Cat = RodProp%Cat + Rod%Cdn = RodProp%Cdn + Rod%Cdt = RodProp%Cdt + Rod%CaEnd = RodProp%CaEnd + Rod%CdEnd = RodProp%CdEnd + + + ! allocate node positions and velocities (NOTE: these arrays start at ZERO) + ALLOCATE(Rod%r(3, 0:N), Rod%rd(3, 0:N), STAT=ErrStat2); if(AllocateFailed("")) return + + ! allocate segment scalar quantities + if (Rod%N == 0) then ! special case of zero-length Rod + ALLOCATE(Rod%l(1), Rod%V(N), STAT=ErrStat2); if(AllocateFailed("Rod: l and V")) return + else ! normal case + ALLOCATE(Rod%l(N), Rod%V(N), STAT=ErrStat2); if(AllocateFailed("Rod: l and V")) return + end if + + ! allocate water related vectors + ALLOCATE(Rod%U(3, 0:N), Rod%Ud(3, 0:N), Rod%zeta(0:N), Rod%PDyn(0:N), STAT=ErrStat2) + if(AllocateFailed("Rod: U Ud zeta PDyn")) return + + ! allocate node force vectors + ALLOCATE(Rod%W(3, 0:N), Rod%Bo(3, 0:N), Rod%Dp(3, 0:N), Rod%Dq(3, 0:N), Rod%Ap(3, 0:N), & + Rod%Aq(3, 0:N), Rod%Pd(3, 0:N), Rod%B(3, 0:N), Rod%Fnet(3, 0:N), STAT=ErrStat2) + if(AllocateFailed("Rod: force arrays")) return + + ! allocate mass and inverse mass matrices for each node (including ends) + ALLOCATE(Rod%M(3, 3, 0:N), STAT=ErrStat2); if(AllocateFailed("Rod: M")) return + + + ! set to zero initially (important of wave kinematics are not being used) + Rod%U = 0.0_DbKi + Rod%Ud = 0.0_DbKi + Rod%zeta = 0.0_DbKi + Rod%PDyn = 0.0_DbKi + + ! ------------------------- set some geometric properties and the starting kinematics ------------------------- + + CALL UnitVector(endCoords(1:3), endCoords(4:6), Rod%q, Rod%UnstrLen) ! get Rod axis direction vector and Rod length + + ! set Rod positions (some or all may be overwritten depending on if the Rod is coupled or attached to a Body) + Rod%r6(1:3) = endCoords(1:3) ! (end A coordinates) + Rod%v6(1:3) = 0.0_DbKi ! (end A velocity, unrotated axes) + + Rod%r6(4:6) = Rod%q ! (Rod direction unit vector) + Rod%v6(4:6) = 0.0_DbKi ! (rotational velocities about unrotated axes) + + ! save mass for future calculations >>>> should calculate I_l and I_r here in future <<<< + Rod%mass = Rod%UnstrLen*RodProp%w + + + ! assign values for l and V + if (Rod%N == 0) then + Rod%l(1) = 0.0_DbKi + Rod%V(1) = 0.0_DbKi + else + DO i=1,N + Rod%l(i) = Rod%UnstrLen/REAL(N, DbKi) + Rod%V(i) = Rod%l(i)*0.25*Pi*RodProp%d*RodProp%d + END DO + end if + + + ! set gravity and bottom contact forces to zero initially (because the horizontal components should remain at zero) + Rod%W = 0.0_DbKi + Rod%B = 0.0_DbKi + + ! calculate some orientation items to be used for mesh setup + call GetOrientationAngles(Rod%q, phi, sinPhi, cosPhi, tanPhi, beta, sinBeta, cosBeta, k_hat) ! calculate some orientation information for the Rod as a whole + Rod%OrMat = CalcOrientation(phi, beta, 0.0_DbKi) ! get rotation matrix to put things in global rather than rod-axis orientations + + + IF (wordy > 0) print *, "Set up Rod ",Rod%IdNum, ", type ", Rod%typeNum + + + if (p%writeLog > 1) then + write(p%UnLog, '(A)') " - Rod "//trim(num2lstr(Rod%IdNum)) + write(p%UnLog, '(A)') " ID: "//trim(num2lstr(Rod%IdNum)) + write(p%UnLog, '(A)') " UnstrLen: "//trim(num2lstr(Rod%UnstrLen)) + write(p%UnLog, '(A)') " N : "//trim(num2lstr(Rod%N )) + write(p%UnLog, '(A)') " d : "//trim(num2lstr(Rod%d )) + write(p%UnLog, '(A)') " rho : "//trim(num2lstr(Rod%rho )) + write(p%UnLog, '(A)') " Can : "//trim(num2lstr(Rod%Can )) + write(p%UnLog, '(A)') " Cat : "//trim(num2lstr(Rod%Cat )) + write(p%UnLog, '(A)') " CaEnd: "//trim(num2lstr(Rod%CaEnd )) + write(p%UnLog, '(A)') " Cdn : "//trim(num2lstr(Rod%Cdn )) + write(p%UnLog, '(A)') " Cdt : "//trim(num2lstr(Rod%Cdt )) + write(p%UnLog, '(A)') " CdEnd: "//trim(num2lstr(Rod%CdEnd )) + !write(p%UnLog, '(A)') " ww_l: " << ( (rho - env->rho_w)*(pi/4.*d*d) )*9.81 << endl; + end if + + + ! need to add cleanup sub <<< + + + CONTAINS + + LOGICAL FUNCTION AllocateFailed(arrayName) + CHARACTER(*), INTENT(IN ) :: arrayName ! The array name + call SetErrStat(ErrStat2, "Error allocating space for "//trim(arrayName)//" array.", ErrStat, ErrMsg, 'Rod_Setup') + AllocateFailed = ErrStat2 >= AbortErrLev + !if (AllocateFailed) call CleanUp() + END FUNCTION AllocateFailed + + END SUBROUTINE Rod_Setup + !-------------------------------------------------------------- + + + + + ! Make output file for Rod and set end kinematics of any attached lines. + ! For free Rods, fill in the initial states into the state vector. + ! Notes: r6 and v6 must already be set. + ! ground- or body-pinned rods have already had setKinematics called to set first 3 elements of r6, v6. + !-------------------------------------------------------------- + SUBROUTINE Rod_Initialize(Rod, states, m) + + TYPE(MD_Rod), INTENT(INOUT) :: Rod ! the rod object + Real(DbKi), INTENT(INOUT) :: states(:) ! state vector section for this line + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + + + INTEGER(IntKi) :: l ! index of segments or nodes along line + REAL(DbKi) :: rRef(3) ! reference position of mesh node + REAL(DbKi) :: OrMat(3,3) ! DCM for body orientation based on r6_in + + IF (wordy > 0) print *, "initializing Rod ", Rod%idNum + + ! the r6 and v6 vectors should have already been set + ! r and rd of ends have already been set by setup function or by parent object <<<<< right? <<<<< + + + ! Pass kinematics to any attached lines (this is just like what a Connection does, except for both ends) + ! so that they have the correct initial positions at this initialization stage. + + if (Rod%typeNum >- 2) CALL Rod_SetDependentKin(Rod, 0.0_DbKi, m, .TRUE.) ! don't call this for type -2 coupled Rods as it's already been called + + + ! assign the resulting kinematics to its part of the state vector (only matters if it's an independent Rod) + + if (Rod%typeNum == 0) then ! free Rod type + + states(1:6) = 0.0_DbKi ! zero velocities for initialization + states(7:9) = Rod%r(:,0) ! end A position + states(10:12) = Rod%q ! rod direction unit vector + + else if (abs(Rod%typeNum) ==1 ) then ! pinned rod type (coupled or attached to something previously via setPinKin) + + states(1:3) = 0.0_DbKi ! zero velocities for initialization + states(4:6) = Rod%q ! rod direction unit vector + + end if + + ! note: this may also be called by a coupled rod (type = -1) in which case states will be empty + + + END SUBROUTINE Rod_Initialize + !-------------------------------------------------------------- + + + + + ! set kinematics for Rods ONLY if they are attached to a body (including a coupled body) or coupled (otherwise shouldn't be called) + !-------------------------------------------------------------- + SUBROUTINE Rod_SetKinematics(Rod, r6_in, v6_in, a6_in, t, m) + + Type(MD_Rod), INTENT(INOUT) :: Rod ! the Rod object + Real(DbKi), INTENT(IN ) :: r6_in(6) ! 6-DOF position + Real(DbKi), INTENT(IN ) :: v6_in(6) ! 6-DOF velocity + Real(DbKi), INTENT(IN ) :: a6_in(6) ! 6-DOF acceleration (only used for coupled rods) + Real(DbKi), INTENT(IN ) :: t ! instantaneous time + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + + INTEGER(IntKi) :: l + + Rod%time = t ! store current time + + + if (abs(Rod%typeNum) == 2) then ! rod rigidly coupled to a body, or ground, or coupling point + Rod%r6 = r6_in + Rod%v6 = v6_in + Rod%a6 = a6_in + + call ScaleVector(Rod%r6(4:6), 1.0_DbKi, Rod%r6(4:6)); ! enforce direction vector to be a unit vector + + ! since this rod has no states and all DOFs have been set, pass its kinematics to dependent Lines + CALL Rod_SetDependentKin(Rod, t, m, .FALSE.) + + else if (abs(Rod%typeNum) == 1) then ! rod end A pinned to a body, or ground, or coupling point + + ! set Rod *end A only* kinematics based on BCs (linear model for now) + Rod%r6(1:3) = r6_in(1:3) + Rod%v6(1:3) = v6_in(1:3) + Rod%a6(1:3) = a6_in(1:3) + + + ! Rod is pinned so only end A is specified, rotations are left alone and will be + ! handled, along with passing kinematics to dependent lines, by separate call to setState + + else + print *, "Error: Rod_SetKinematics called for a free Rod in MoorDyn." ! <<< + end if + + + ! update Rod direction unit vector (simply equal to last three entries of r6, presumably these were set elsewhere for pinned Rods) + Rod%q = Rod%r6(4:6) + + + + END SUBROUTINE Rod_SetKinematics + !-------------------------------------------------------------- + + ! pass the latest states to the rod if it has any DOFs/states (then update rod end kinematics including attached lines) + !-------------------------------------------------------------- + SUBROUTINE Rod_SetState(Rod, X, t, m) + + Type(MD_Rod), INTENT(INOUT) :: Rod ! the Rod object + Real(DbKi), INTENT(IN ) :: X(:) ! state vector section for this line + Real(DbKi), INTENT(IN ) :: t ! instantaneous time + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + + INTEGER(IntKi) :: J ! index + + + ! for a free Rod, there are 12 states: + ! [ x, y, z velocity of end A, then rate of change of u/v/w coordinates of unit vector pointing toward end B, + ! then x, y, z coordinate of end A, u/v/w coordinates of unit vector pointing toward end B] + + ! for a pinned Rod, there are 6 states (rotational only): + ! [ rate of change of u/v/w coordinates of unit vector pointing toward end B, + ! then u/v/w coordinates of unit vector pointing toward end B] + + + ! store current time + Rod%time = t + + + ! copy over state values for potential use during derivative calculations + if (Rod%typeNum == 0) then ! free Rod type + + ! CALL ScaleVector(X(10:12), 1.0, X(10:12)) ! enforce direction vector to be a unit vector <<<< can't do this with FAST frameowrk, could be a problem!! + + ! TODO: add "controller" adjusting state derivatives of X(10:12) to artificially force X(10:12) to remain a unit vector <<<<<<<<<<< + + + Rod%r6(1:3) = X(7:9) ! (end A coordinates) + Rod%v6(1:3) = X(1:3) ! (end A velocity, unrotated axes) + CALL ScaleVector(X(10:12), 1.0_DbKi, Rod%r6(4:6)) !Rod%r6(4:6) = X(10:12) ! (Rod direction unit vector) + Rod%v6(4:6) = X(4:6) ! (rotational velocities about unrotated axes) + + + CALL Rod_SetDependentKin(Rod, t, m, .FALSE.) + + else if (abs(Rod%typeNum) == 1) then ! pinned rod type (coupled or attached to something)t previously via setPinKin) + + !CALL ScaleVector(X(4:6), 1.0, X(4:6)) ! enforce direction vector to be a unit vector + + + CALL ScaleVector(X(4:6), 1.0_DbKi, Rod%r6(4:6)) !Rod%r6(3+J) = X(3+J) ! (Rod direction unit vector) + Rod%v6(4:6) = X(1:3) ! (rotational velocities about unrotated axes) + + + CALL Rod_SetDependentKin(Rod, t, m, .FALSE.) + + else + print *, "Error: Rod::setState called for a non-free rod type in MoorDyn" ! <<< + end if + + ! update Rod direction unit vector (simply equal to last three entries of r6) + Rod%q = Rod%r6(4:6) + + END SUBROUTINE Rod_SetState + !-------------------------------------------------------------- + + + ! Set the Rod end kinematics then set the kinematics of dependent objects (any attached lines). + ! This also determines the orientation of zero-length rods. + !-------------------------------------------------------------- + SUBROUTINE Rod_SetDependentKin(Rod, t, m, initial) + + Type(MD_Rod), INTENT(INOUT) :: Rod ! the Rod object + Real(DbKi), INTENT(IN ) :: t ! instantaneous time + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects (for simplicity, since Bodies deal with Rods and Connections) + LOGICAL, INTENT(IN ) :: initial ! true if this is the call during initialization (in which case avoid calling any Lines yet) + + INTEGER(IntKi) :: l ! index of segments or nodes along line + INTEGER(IntKi) :: J ! index + INTEGER(IntKi) :: N ! number of segments + + REAL(DbKi) :: qEnd(3) ! unit vector of attached line end segment, following same direction convention as Rod's q vector + REAL(DbKi) :: q_EI_dl(3) ! <<<< add description + REAL(DbKi) :: EIend ! bending stiffness of attached line end segment + REAL(DbKi) :: dlEnd ! stretched length of attached line end segment + REAL(DbKi) :: qMomentSum(3) ! summation of qEnd*EI/dl_stretched (with correct sign) for each attached line + + + ! Initialize variables + qMomentSum = 0.0_DbKi + + ! in future pass accelerations here too? <<<< + + N = Rod%N + + ! from state values, set positions of end nodes + ! end A + Rod%r(:,0) = Rod%r6(1:3) ! positions + Rod%rd(:,0) = Rod%v6(1:3) ! velocities + + !print *, Rod%r6(1:3) + !print *, Rod%r(:,0) + + if (Rod%N > 0) then ! set end B nodes only if the rod isn't zero length + CALL transformKinematicsAtoB(Rod%r6(1:3), Rod%r6(4:6), Rod%UnstrLen, Rod%v6, Rod%r(:,N), Rod%rd(:,N)) ! end B + end if + + ! pass end node kinematics to any attached lines (this is just like what a Connection does, except for both ends) + DO l=1,Rod%nAttachedA + CALL Line_SetEndKinematics(m%LineList(Rod%attachedA(l)), Rod%r(:,0), Rod%rd(:,0), t, Rod%TopA(l)) + END DO + DO l=1,Rod%nAttachedB + CALL Line_SetEndKinematics(m%LineList(Rod%attachedB(l)), Rod%r(:,N), Rod%rd(:,N), t, Rod%TopB(l)) + END DO + + + ! if this is a zero-length Rod and we're passed initialization, get bending moment-related information from attached lines and compute Rod's equilibrium orientation + if ((N==0) .and. (.not. initial)) then + + DO l=1,Rod%nAttachedA + + CALL Line_GetEndSegmentInfo(m%LineList(Rod%attachedA(l)), q_EI_dl, Rod%TopA(l), 0) + + qMomentSum = qMomentSum + q_EI_dl ! add each component to the summation vector + + END DO + + DO l=1,Rod%nAttachedB + + CALL Line_GetEndSegmentInfo(m%LineList(Rod%attachedB(l)), q_EI_dl, Rod%TopB(l), 1) + + qMomentSum = qMomentSum + q_EI_dl ! add each component to the summation vector + + END DO + + ! solve for line unit vector that balances all moments (unit vector of summation of qEnd*EI/dl_stretched over each line) + CALL ScaleVector(qMomentSum, 1.0_DbKi, Rod%q) + + Rod%r6(4:6) = Rod%q ! set orientation angles + END IF + + ! pass Rod orientation to any attached lines (this is just like what a Connection does, except for both ends) + DO l=1,Rod%nAttachedA + CALL Line_SetEndOrientation(m%LineList(Rod%attachedA(l)), Rod%q, Rod%TopA(l), 0) + END DO + DO l=1,Rod%nAttachedB + CALL Line_SetEndOrientation(m%LineList(Rod%attachedB(l)), Rod%q, Rod%TopB(l), 1) + END DO + + END SUBROUTINE Rod_SetDependentKin + !-------------------------------------------------------------- + + !-------------------------------------------------------------- + SUBROUTINE Rod_GetStateDeriv(Rod, Xd, m, p) + + Type(MD_Rod), INTENT(INOUT) :: Rod ! the Rod object + Real(DbKi), INTENT(INOUT) :: Xd(:) ! state derivative vector section for this line + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects (for simplicity, since Bodies deal with Rods and Connections) + TYPE(MD_ParameterType),INTENT(IN ) :: p ! Parameters + + !TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! misc/optimization variables + + INTEGER(IntKi) :: J ! index + + Real(DbKi) :: Fnet (6) ! net force and moment about reference point + Real(DbKi) :: M_out (6,6) ! mass matrix about reference point + + Real(DbKi) :: acc(6) ! 6DOF acceleration vector about reference point + + Real(DbKi) :: Mcpl(3) ! moment in response to end A acceleration due to inertial coupling + + Real(DbKi) :: y_temp (6) ! temporary vector for LU decomposition + Real(DbKi) :: LU_temp(6,6) ! temporary matrix for LU decomposition + + ! Initialize some things to zero + y_temp = 0.0_DbKi +! FIXME: should LU_temp be set to M_out before calling LUsolve????? + LU_temp = 0.0_DbKi + + CALL Rod_GetNetForceAndMass(Rod, Rod%r(:,0), Fnet, M_out, m, p) + + + + ! TODO: add "controller" adjusting state derivatives of X(10:12) to artificially force X(10:12) to remain a unit vector <<<<<<<<<<< + + ! fill in state derivatives + IF (Rod%typeNum == 0) THEN ! free Rod type, 12 states + + ! solve for accelerations in [M]{a}={f} using LU decomposition + CALL LUsolve(6, M_out, LU_temp, Fnet, y_temp, acc) + + Xd(7:9) = Rod%v6(1:3) !Xd[6 + I] = v6[ I]; ! dxdt = V (velocities) + Xd(1:6) = acc !Xd[ I] = acc[ I]; ! dVdt = a (accelerations) + !Xd[3 + I] = acc[3+I]; ! rotational accelerations + + ! rate of change of unit vector components!! CHECK! <<<<< + Xd(10) = - Rod%v6(6)*Rod%r6(5) + Rod%v6(5)*Rod%r6(6) ! i.e. u_dot_x = -omega_z*u_y + omega_y*u_z + Xd(11) = Rod%v6(6)*Rod%r6(4) - Rod%v6(4)*Rod%r6(6) ! i.e. u_dot_y = omega_z*u_x - omega_x*u_z + Xd(12) = -Rod%v6(5)*Rod%r6(4) + Rod%v6(4)*Rod%r6(5) ! i.e. u_dot_z = -omega_y*u_x - omega_x*u_y + + ! store accelerations in case they're useful as output + Rod%a6 = acc + + ELSE ! pinned rod, 6 states (rotational only) + + ! account for moment in response to end A acceleration due to inertial coupling (off-diagonal sub-matrix terms) + !Fnet(4:6) = Fnet(4:6) - MATMUL(M_out(4:6,1:3), Rod%a6(1:3)) ! << 1) THEN + print *, " state derivatives:" + print *, Xd + + print *, "r0" + print *, Rod%r(:,0) + print *, "F" + print *, Fnet + print *, "M" + print *, M_out + print *, "acc" + print *, acc + END IF + + EXIT + END IF + END DO + + END SUBROUTINE Rod_GetStateDeriv + !-------------------------------------------------------------- + + + ! calculate the forces on the rod, including from attached lines + !-------------------------------------------------------------- + SUBROUTINE Rod_DoRHS(Rod, m, p) + + Type(MD_Rod), INTENT(INOUT) :: Rod ! the Rodion object + TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! passing along all mooring objects + TYPE(MD_ParameterType),INTENT(IN ) :: p ! Parameters + + !TYPE(MD_MiscVarType), INTENT(INOUT) :: m ! misc/optimization variables + + INTEGER(IntKi) :: l ! index of attached lines + INTEGER(IntKi) :: I,J,K ! index + + + INTEGER(IntKi) :: N ! number of rod elements for convenience + + Real(DbKi) :: phi, beta, sinPhi, cosPhi, tanPhi, sinBeta, cosBeta ! various orientation things + Real(DbKi) :: k_hat(3) ! unit vector (redundant, not used) <<<< + Real(DbKi) :: Ftemp ! temporary force component + Real(DbKi) :: Mtemp ! temporary moment component + + Real(DbKi) :: m_i, v_i ! + Real(DbKi) :: zeta ! wave elevation above/below a given node + !Real(DbKi) :: h0 ! distance along rod centerline from end A to the waterplane + Real(DbKi) :: deltaL ! submerged length of a given segment + Real(DbKi) :: Lsum ! cumulative length along rod axis from bottom + Real(DbKi) :: dL ! length attributed to node + Real(DbKi) :: VOF ! fraction of volume associated with node that is submerged + + Real(DbKi) :: VOF0 ! original VOF based only on axis before refinement + Real(DbKi) :: z1hi ! highest elevation of cross section at node [m] + Real(DbKi) :: z1lo ! lowest elevation of cross section at node [m] + Real(DbKi) :: G ! distance normal to axis from bottom edge of cross section to waterplane [m] + Real(DbKi) :: al ! angle involved in circular segment buoyancy calc [rad] + Real(DbKi) :: A ! area of cross section at node that is below the waterline [m2] + Real(DbKi) :: zA ! crude approximation to z value of centroid of submerged cross section at node [m] + + + Real(DbKi) :: Vi(3) ! relative flow velocity over a node + Real(DbKi) :: SumSqVp, SumSqVq, MagVp, MagVq + Real(DbKi) :: Vp(3), Vq(3) ! transverse and axial components of water velocity at a given node + Real(DbKi) :: ap(3), aq(3) ! transverse and axial components of water acceleration at a given node + Real(DbKi) :: Fnet_i(3) ! force from an attached line + Real(DbKi) :: Mnet_i(3) ! moment from an attached line + Real(DbKi) :: Mass_i(3,3) ! mass from an attached line + + ! used in lumped 6DOF calculations: + Real(DbKi) :: rRel( 3) ! relative position of each node i from rRef + !Real(DbKi) :: OrMat(3,3) ! rotation matrix to rotate global z to rod's axis + Real(DbKi) :: F6_i(6) ! a node's contribution to the total force vector + Real(DbKi) :: M6_i(6,6) ! a node's contribution to the total mass matrix + Real(DbKi) :: I_l ! axial inertia of rod + Real(DbKi) :: I_r ! radial inertia of rod about CG + Real(DbKi) :: Imat_l(3,3) ! inertia about CG aligned with Rod axis + Real(DbKi) :: Imat(3,3) ! inertia about CG in global frame + Real(DbKi) :: h_c ! location of CG along axis + Real(DbKi) :: r_c(3) ! 3d location of CG relative to node A + Real(DbKi) :: Fcentripetal(3) ! centripetal force + Real(DbKi) :: Mcentripetal(3) ! centripetal moment + + Real(DbKi) :: depth ! local interpolated depth from bathymetry grid [m] + Real(DbKi) :: nvec(3) ! local seabed surface normal vector (positive out) + + + N = Rod%N + + ! ------------------------------ zero some things -------------------------- + + Rod%Mext = 0.0_DbKi ! zero the external moment sum + + Lsum = 0.0_DbKi + + + ! ---------------------------- initial rod and node calculations ------------------------ + + ! calculate some orientation information for the Rod as a whole + !call GetOrientationAngles(Rod%r( :,0), Rod%r( :,N), phi, sinPhi, cosPhi, tanPhi, beta, sinBeta, cosBeta, k_hat) + call GetOrientationAngles(Rod%q, phi, sinPhi, cosPhi, tanPhi, beta, sinBeta, cosBeta, k_hat) + + ! save to internal roll and pitch variables for use in output <<< should check these, make Euler angles isntead of independent <<< + Rod%roll = -phi*sinBeta + Rod%pitch = phi*cosBeta + + ! set interior node positions and velocities (stretch the nodes between the endpoints linearly) (skipped for zero-length Rods) + DO i=1,N-1 + Rod%r( :,i) = Rod%r( :,0) + (Rod%r( :,N) - Rod%r( :,0)) * (REAL(i)/REAL(N)) + Rod%rd(:,i) = Rod%rd(:,0) + (Rod%rd(:,N) - Rod%rd(:,0)) * (REAL(i)/REAL(N)) + + Rod%V(i) = 0.25*pi * Rod%d*Rod%d * Rod%l(i) ! volume attributed to segment + END DO + + + ! apply wave kinematics (if there are any) + + DO i=0,N + CALL getWaterKin(p, Rod%r(1,i), Rod%r(2,i), Rod%r(3,i), Rod%time, m%WaveTi, Rod%U(:,i), Rod%Ud(:,i), Rod%zeta(i), Rod%PDyn(i)) + !F(i) = 1.0 ! set VOF value to one for now (everything submerged - eventually this should be element-based!!!) <<<< + ! <<<< currently F is not being used and instead a VOF variable is used within the node loop + END DO + + ! Calculated h0 (note this should be deprecated/replced) + zeta = Rod%zeta(N) ! temporary + ! get approximate location of waterline crossing along Rod axis (note: negative h0 indicates end A is above end B, and measures -distance from end A to waterline crossing) + if ((Rod%r(3,0) < zeta) .and. (Rod%r(3,N) < zeta)) then ! fully submerged case + Rod%h0 = Rod%UnstrLen + else if ((Rod%r(3,0) < zeta) .and. (Rod%r(3,N) > zeta)) then ! check if it's crossing the water plane (should also add some limits to avoid near-horizontals at some point) + Rod%h0 = (zeta - Rod%r(3,0))/Rod%q(3) ! distance along rod centerline from end A to the waterplane + else if ((Rod%r(3,N) < zeta) .and. (Rod%r(3,0) > zeta)) then ! check if it's crossing the water plane but upside down + Rod%h0 = -(zeta - Rod%r(3,0))/Rod%q(3) ! negative distance along rod centerline from end A to the waterplane + else + Rod%h0 = 0.0_DbKi ! fully unsubmerged case (ever applicable?) + end if + + + ! -------------------------- loop through all the nodes ----------------------------------- + DO I = 0, N + + + ! ------------------ calculate added mass matrix for each node ------------------------- + + ! get mass and volume considering adjacent segment lengths + IF (I==0) THEN + dL = 0.5*Rod%l(1) + m_i = 0.25*Pi * Rod%d*Rod%d * dL *Rod%rho ! (will be zero for zero-length Rods) + v_i = 0.5 *Rod%V(1) + ELSE IF (I==N) THEN + dL = 0.5*Rod%l(N) + m_i = 0.25*pi * Rod%d*Rod%d * dL *Rod%rho + v_i = 0.5*Rod%V(N) + ELSE + dL = 0.5*(Rod%l(I) + Rod%l(I+1)) + m_i = 0.25*pi * Rod%d*Rod%d * dL *Rod%rho + v_i = 0.5 *(Rod%V(I) + Rod%V(I+1)) + END IF + + ! get scalar for submerged portion + if (Rod%h0 < 0.0_DbKi) then ! upside down partially-submerged Rod case + IF (Lsum >= -Rod%h0) THEN ! if fully submerged + VOF0 = 1.0_DbKi + ELSE IF (Lsum + dL > -Rod%h0) THEN ! if partially below waterline + VOF0 = (Lsum+dL + Rod%h0)/dL + ELSE ! must be out of water + VOF0 = 0.0_DbKi + END IF + else + IF (Lsum + dL <= Rod%h0) THEN ! if fully submerged + VOF0 = 1.0_DbKi + ELSE IF (Lsum < Rod%h0) THEN ! if partially below waterline + VOF0 = (Rod%h0 - Lsum)/dL + ELSE ! must be out of water + VOF0 = 0.0_DbKi + END IF + end if + + Lsum = Lsum + dL ! add length attributed to this node to the total + + ! get submerged cross sectional area and centroid for each node + z1hi = Rod%r(3,I) + 0.5*Rod%d*abs(sinPhi) ! highest elevation of cross section at node + z1lo = Rod%r(3,I) - 0.5*Rod%d*abs(sinPhi) ! lowest elevation of cross section at node + + if (z1lo > Rod%zeta(I)) then ! fully out of water + A = 0.0 ! area + zA = 0 ! centroid depth + else if (z1hi < Rod%zeta(I)) then ! fully submerged + A = Pi*0.25*Rod%d**2 + zA = Rod%r(3,I) + else ! if z1hi*z1lo < 0.0: # if cross section crosses waterplane + if (abs(sinPhi) < 0.001) then ! if cylinder is near vertical, i.e. end is horizontal + A = 0.5_DbKi ! <<< shouldn't this just be zero? <<< + zA = 0.0_DbKi + else + G = (Rod%r(3,I)-Rod%zeta(I))/abs(sinPhi) !(-z1lo+Rod%zeta(I))/abs(sinPhi) ! distance from node to waterline cross at same axial location [m] + !A = 0.25*Rod%d**2*acos((Rod%d - 2.0*G)/Rod%d) - (0.5*Rod%d-G)*sqrt(Rod%d*G-G**2) ! area of circular cross section that is below waterline [m^2] + !zA = (z1lo-Rod%zeta(I))/2 ! very crude approximation of centroid for now... <<< need to double check zeta bit <<< + al = acos(2.0*G/Rod%d) + A = Rod%d*Rod%d/8.0 * (2.0*al - sin(2.0*al)) + zA = Rod%r(3,I) - 0.6666666666 * Rod%d* (sin(al))**3 / (2.0*al - sin(2.0*al)) + end if + end if + + VOF = VOF0*cosPhi**2 + A/(0.25*Pi*Rod%d**2)*sinPhi**2 ! this is a more refined VOF-type measure that can work for any incline + + + ! build mass and added mass matrix + DO J=1,3 + DO K=1,3 + IF (J==K) THEN + Rod%M(K,J,I) = m_i + VOF*p%rhoW*v_i*( Rod%Can*(1 - Rod%q(J)*Rod%q(K)) + Rod%Cat*Rod%q(J)*Rod%q(K) ) + ELSE + Rod%M(K,J,I) = VOF*p%rhoW*v_i*( Rod%Can*(-Rod%q(J)*Rod%q(K)) + Rod%Cat*Rod%q(J)*Rod%q(K) ) + END IF + END DO + END DO + + ! <<<< what about accounting for offset of half segment from node location for end nodes? <<<< + + +! CALL Inverse3by3(Rod%S(:,:,I), Rod%M(:,:,I)) ! invert mass matrix + + + ! ------------------ CALCULATE FORCES ON EACH NODE ---------------------------- + + if (N > 0) then ! the following force calculations are only nonzero for finite-length rods (skipping for zero-length Rods) + + ! >>> no nodal axial elasticity loads calculated since it's assumed rigid, but should I calculate tension/compression due to other loads? <<< + + ! weight (now only the dry weight) + Rod%W(:,I) = (/ 0.0_DbKi, 0.0_DbKi, -m_i * p%g /) ! assuming g is positive + + ! radial buoyancy force from sides (now calculated based on outside pressure, for submerged portion only) + Ftemp = -VOF * v_i * p%rhoW*p%g * sinPhi ! magnitude of radial buoyancy force at this node + Rod%Bo(:,I) = (/ Ftemp*cosBeta*cosPhi, Ftemp*sinBeta*cosPhi, -Ftemp*sinPhi /) + + !relative flow velocities + DO J = 1, 3 + Vi(J) = Rod%U(J,I) - Rod%rd(J,I) ! relative flow velocity over node -- this is where wave velicites would be added + END DO + + ! decomponse relative flow into components + SumSqVp = 0.0_DbKi ! start sums of squares at zero + SumSqVq = 0.0_DbKi + DO J = 1, 3 + Vq(J) = DOT_PRODUCT( Vi , Rod%q ) * Rod%q(J); ! tangential relative flow component + Vp(J) = Vi(J) - Vq(J) ! transverse relative flow component + SumSqVq = SumSqVq + Vq(J)*Vq(J) + SumSqVp = SumSqVp + Vp(J)*Vp(J) + END DO + MagVp = sqrt(SumSqVp) ! get magnitudes of flow components + MagVq = sqrt(SumSqVq) + + ! transverse and tangenential drag + Rod%Dp(:,I) = VOF * 0.5*p%rhoW*Rod%Cdn* Rod%d* dL * MagVp * Vp + Rod%Dq(:,I) = 0.0_DbKi ! 0.25*p%rhoW*Rod%Cdt* Pi*Rod%d* dL * MagVq * Vq <<< should these axial side loads be included? + + ! fluid acceleration components for current node + aq = DOT_PRODUCT(Rod%Ud(:,I), Rod%q) * Rod%q ! tangential component of fluid acceleration + ap = Rod%Ud(:,I) - aq ! normal component of fluid acceleration + ! transverse and axial Froude-Krylov force + Rod%Ap(:,I) = VOF * p%rhoW*(1.0+Rod%Can)* v_i * ap ! + Rod%Aq(:,I) = 0.0_DbKi ! p%rhoW*(1.0+Rod%Cat)* v_i * aq ! <<< just put a taper-based term here eventually? + + ! dynamic pressure + Rod%Pd(:,I) = 0.0_DbKi ! assuming zero for sides for now, until taper comes into play + + ! seabed contact (stiffness and damping, vertical-only for now) + ! interpolate the local depth from the bathymetry grid + CALL getDepthFromBathymetry(m%BathymetryGrid, m%BathGrid_Xs, m%BathGrid_Ys, Rod%r(1,I), Rod%r(2,I), depth, nvec) + + IF (Rod%r(3,I) < -depth) THEN + Rod%B(3,I) = ( (-depth - Rod%r(3,I))*p%kBot - Rod%rd(3,I)*p%cBot) * Rod%d*dL + ELSE + Rod%B(1,I) = 0.0_DbKi + Rod%B(2,I) = 0.0_DbKi + Rod%B(3,I) = 0.0_DbKi + END IF + + ELSE ! zero-length (N=0) Rod case + + ! >>>>>>>>>>>>>> still need to check handling of zero length rods <<<<<<<<<<<<<<<<<<< + + ! for zero-length rods, make sure various forces are zero + Rod%W = 0.0_DbKi + Rod%Bo = 0.0_DbKi + Rod%Dp = 0.0_DbKi + Rod%Dq = 0.0_DbKi + Rod%Ap = 0.0_DbKi + Rod%Aq = 0.0_DbKi + Rod%Pd = 0.0_DbKi + Rod%B = 0.0_DbKi + + END IF + + + ! ------ now add forces, moments, and added mass from Rod end effects (these can exist even if N==0) ------- + + IF ((I==0) .and. (z1lo < Rod%zeta(I))) THEN ! if this is end A and it is at least partially submerged + + ! >>> eventually should consider a VOF approach for the ends hTilt = 0.5*Rod%d/cosPhi <<< + + ! buoyancy force + Ftemp = -VOF * 0.25*Pi*Rod%d*Rod%d * p%rhoW*p%g* zA + Rod%Bo(:,I) = Rod%Bo(:,I) + (/ Ftemp*cosBeta*sinPhi, Ftemp*sinBeta*sinPhi, Ftemp*cosPhi /) + + ! buoyancy moment + Mtemp = -VOF * 1.0/64.0*Pi*Rod%d**4 * p%rhoW*p%g * sinPhi + Rod%Mext = Rod%Mext + (/ Mtemp*sinBeta, -Mtemp*cosBeta, 0.0_DbKi /) + + ! axial drag + Rod%Dq(:,I) = Rod%Dq(:,I) + VOF * 0.25* Pi*Rod%d*Rod%d * p%rhoW*Rod%CdEnd * MagVq * Vq + + ! >>> what about rotational drag?? <<< eqn will be Pi* Rod%d**4/16.0 omega_rel?^2... *0.5 * Cd... + + ! Froud-Krylov force + Rod%Aq(:,I) = Rod%Aq(:,I) + VOF * p%rhoW*(1.0+Rod%CaEnd)* (2.0/3.0*Pi*Rod%d**3 /8.0) * aq + + ! dynamic pressure force + Rod%Pd(:,I) = Rod%Pd(:,I) + VOF * 0.25* Pi*Rod%d*Rod%d * Rod%PDyn(I) * Rod%q + + ! added mass + DO J=1,3 + DO K=1,3 + Rod%M(K,J,I) = Rod%M(K,J,I) + VOF*p%rhoW* Rod%CaEnd* (2.0/3.0*Pi*Rod%d**3 /8.0) *Rod%q(J)*Rod%q(K) + END DO + END DO + + END IF + + IF ((I==N) .and. (z1lo < Rod%zeta(I))) THEN ! if this end B and it is at least partially submerged (note, if N=0, both this and previous if statement are true) + + ! buoyancy force + Ftemp = VOF * 0.25*Pi*Rod%d*Rod%d * p%rhoW*p%g* zA + Rod%Bo(:,I) = Rod%Bo(:,I) + (/ Ftemp*cosBeta*sinPhi, Ftemp*sinBeta*sinPhi, Ftemp*cosPhi /) + + ! buoyancy moment + Mtemp = VOF * 1.0/64.0*Pi*Rod%d**4 * p%rhoW*p%g * sinPhi + Rod%Mext = Rod%Mext + (/ Mtemp*sinBeta, -Mtemp*cosBeta, 0.0_DbKi /) + + ! axial drag + Rod%Dq(:,I) = Rod%Dq(:,I) + VOF * 0.25* Pi*Rod%d*Rod%d * p%rhoW*Rod%CdEnd * MagVq * Vq + + ! Froud-Krylov force + Rod%Aq(:,I) = Rod%Aq(:,I) + VOF * p%rhoW*(1.0+Rod%CaEnd)* (2.0/3.0*Pi*Rod%d**3 /8.0) * aq + + ! dynamic pressure force + Rod%Pd(:,I) = Rod%Pd(:,I) - VOF * 0.25* Pi*Rod%d*Rod%d * Rod%PDyn(I) * Rod%q + + ! added mass + DO J=1,3 + DO K=1,3 + Rod%M(K,J,I) = Rod%M(K,J,I) + VOF*p%rhoW* Rod%CaEnd* (2.0/3.0*Pi*Rod%d**3 /8.0) *Rod%q(J)*Rod%q(K) + END DO + END DO + + END IF + + + ! ---------------------------- total forces for this node ----------------------------- + + Rod%Fnet(:,I) = Rod%W(:,I) + Rod%Bo(:,I) + Rod%Dp(:,I) + Rod%Dq(:,I) & + + Rod%Ap(:,I) + Rod%Aq(:,I) + Rod%Pd(:,I) + Rod%B(:,I) + + + END DO ! I - done looping through nodes + + + ! ----- add waterplane moment of inertia moment if applicable ----- + IF ((Rod%r(3,0) < zeta) .and. (Rod%r(3,N) > zeta)) then ! check if it's crossing the water plane <<< may need updating + ! >>> could scale the below based on whether part of the end cap is crossing the water plane... + !Mtemp = 1.0/16.0 *Pi*Rod%d**4 * p%rhoW*p%g * sinPhi * (1.0 + 0.5* tanPhi**2) ! original (goes to infinity at 90 deg) + Mtemp = 1.0/16.0 *Pi*Rod%d**4 * p%rhoW*p%g * sinPhi * cosPhi ! simple alternative that goes to 0 at 90 deg then reverses sign beyond that + Rod%Mext = Rod%Mext + (/ Mtemp*sinBeta, -Mtemp*cosBeta, 0.0_DbKi /) + END IF + + + ! ---------------- now add in forces on end nodes from attached lines ------------------ + + ! zero the external force/moment sums (important!) + + ! loop through lines attached to end A + Rod%FextA = 0.0_DbKi + DO l=1,Rod%nAttachedA + + CALL Line_GetEndStuff(m%LineList(Rod%attachedA(l)), Fnet_i, Mnet_i, Mass_i, Rod%TopA(l)) + + ! sum quantitites + Rod%Fnet(:,0)= Rod%Fnet(:,0) + Fnet_i ! total force + Rod%FextA = Rod%FextA + Fnet_i ! a copy for outputting totalled line loads + Rod%Mext = Rod%Mext + Mnet_i ! externally applied moment + Rod%M(:,:,0) = Rod%M(:,:,0) + Mass_i ! mass at end node + + END DO + + ! loop through lines attached to end B + Rod%FextB = 0.0_DbKi + DO l=1,Rod%nAttachedB + + CALL Line_GetEndStuff(m%LineList(Rod%attachedB(l)), Fnet_i, Mnet_i, Mass_i, Rod%TopB(l)) + + ! sum quantitites + Rod%Fnet(:,N)= Rod%Fnet(:,N) + Fnet_i ! total force + Rod%FextB = Rod%FextB + Fnet_i ! a copy for outputting totalled line loads + Rod%Mext = Rod%Mext + Mnet_i ! externally applied moment + Rod%M(:,:,N) = Rod%M(:,:,N) + Mass_i ! mass at end node + + END DO + + ! ---------------- now lump everything in 6DOF about end A ----------------------------- + + ! question: do I really want to neglect the rotational inertia/drag/etc across the length of each segment? + + ! make sure 6DOF quantiaties are zeroed before adding them up + Rod%F6net = 0.0_DbKi + Rod%M6net = 0.0_DbKi + + ! now go through each node's contributions, put them about end A, and sum them + DO i = 0,Rod%N + + rRel = Rod%r(:,i) - Rod%r(:,0) ! vector from reference point to node + + ! convert segment net force into 6dof force about body ref point (if the Rod itself, end A) + CALL translateForce3to6DOF(rRel, Rod%Fnet(:,i), F6_i) + + ! convert segment mass matrix to 6by6 mass matrix about body ref point (if the Rod itself, end A) + CALL translateMass3to6DOF(rRel, Rod%M(:,:,i), M6_i) + + ! sum contributions + Rod%F6net = Rod%F6net + F6_i + Rod%M6net = Rod%M6net + M6_i + + END DO + + ! ------------- Calculate some items for the Rod as a whole here ----------------- + + ! >>> could some of these be precalculated just once? <<< + + ! add inertia terms for the Rod assuming it is uniform density (radial terms add to existing matrix which contains parallel-axis-theorem components only) + Imat_l = 0.0_DbKi + if (Rod%N > 0) then + I_l = 0.125*Rod%mass * Rod%d*Rod%d ! axial moment of inertia + I_r = Rod%mass/12 * (0.75*Rod%d*Rod%d + (Rod%UnstrLen/Rod%N)**2 ) * Rod%N ! summed radial moment of inertia for each segment individually + + Imat_l(1,1) = I_r ! inertia about CG in local orientations (as if Rod is vertical) + Imat_l(2,2) = I_r + Imat_l(3,3) = I_l + end if + + ! >>> some of the kinematics parts of this could potentially be moved to a different routine <<< + Rod%OrMat = CalcOrientation(phi, beta, 0.0_DbKi) ! get rotation matrix to put things in global rather than rod-axis orientations + + Imat = RotateM3(Imat_l, Rod%OrMat) ! rotate to give inertia matrix about CG in global frame + + ! these supplementary inertias can then be added the matrix (these are the terms ASIDE from the parallel axis terms) + Rod%M6net(4:6,4:6) = Rod%M6net(4:6,4:6) + Imat + + + ! now add centripetal and gyroscopic forces/moments, and that should be everything + h_c = 0.5*Rod%UnstrLen ! distance to center of mass + r_c = h_c*Rod%q ! vector to center of mass + + ! note that Rod%v6(4:6) is the rotational velocity vector, omega + Fcentripetal = 0.0_DbKi !<<>> do we need to ensure zero moment is passed if it's pinned? <<< + !if (abs(Rod%typeNum)==1) then + ! Fnet_out(4:6) = 0.0_DbKi + !end if + + + END SUBROUTINE Rod_GetNetForceAndMass + !-------------------------------------------------------------- + + + ! this function handles assigning a line to a connection node + SUBROUTINE Rod_AddLine(Rod, lineID, TopOfLine, endB) + + Type(MD_Rod), INTENT (INOUT) :: Rod ! the Connection object + + Integer(IntKi), INTENT( IN ) :: lineID + Integer(IntKi), INTENT( IN ) :: TopOfLine + Integer(IntKi), INTENT( IN ) :: endB ! add line to end B if 1, end A if 0 + + if (endB==1) then ! attaching to end B + + IF (wordy > 0) Print*, "L", lineID, "->R", Rod%IdNum , "b" + + IF (Rod%nAttachedB <10) THEN ! this is currently just a maximum imposed by a fixed array size. could be improved. + Rod%nAttachedB = Rod%nAttachedB + 1 ! add the line to the number connected + Rod%AttachedB(Rod%nAttachedB) = lineID + Rod%TopB(Rod%nAttachedB) = TopOfLine ! attached to line ... 1 = top/fairlead(end B), 0 = bottom/anchor(end A) + ELSE + Print*, "too many lines connected to Rod ", Rod%IdNum, " in MoorDyn!" + END IF + + else ! attaching to end A + + IF (wordy > 0) Print*, "L", lineID, "->R", Rod%IdNum , "a" + + IF (Rod%nAttachedA <10) THEN ! this is currently just a maximum imposed by a fixed array size. could be improved. + Rod%nAttachedA = Rod%nAttachedA + 1 ! add the line to the number connected + Rod%AttachedA(Rod%nAttachedA) = lineID + Rod%TopA(Rod%nAttachedA) = TopOfLine ! attached to line ... 1 = top/fairlead(end B), 0 = bottom/anchor(end A) + ELSE + Print*, "too many lines connected to Rod ", Rod%IdNum, " in MoorDyn!" + END IF + + end if + + END SUBROUTINE Rod_AddLine + + + ! this function handles removing a line from a connection node + SUBROUTINE Rod_RemoveLine(Rod, lineID, TopOfLine, endB, rEnd, rdEnd) + + Type(MD_Rod), INTENT (INOUT) :: Rod ! the Connection object + + Integer(IntKi), INTENT( IN ) :: lineID + Integer(IntKi), INTENT( OUT) :: TopOfLine + Integer(IntKi), INTENT( IN ) :: endB ! end B if 1, end A if 0 + REAL(DbKi), INTENT(INOUT) :: rEnd(3) + REAL(DbKi), INTENT(INOUT) :: rdEnd(3) + + Integer(IntKi) :: l,m,J + + if (endB==1) then ! attaching to end B + + DO l = 1,Rod%nAttachedB ! look through attached lines + + IF (Rod%AttachedB(l) == lineID) THEN ! if this is the line's entry in the attachment list + + TopOfLine = Rod%TopB(l); ! record which end of the line was attached + + DO m = l,Rod%nAttachedB-1 + + Rod%AttachedB(m) = Rod%AttachedB(m+1) ! move subsequent line links forward one spot in the list to eliminate this line link + Rod%TopB( m) = Rod%TopB(m+1) + + Rod%nAttachedB = Rod%nAttachedB - 1 ! reduce attached line counter by 1 + + ! also pass back the kinematics at the end + DO J = 1,3 + rEnd( J) = Rod%r( J,Rod%N) + rdEnd(J) = Rod%rd(J,Rod%N) + END DO + + print*, "Detached line ", lineID, " from Rod ", Rod%IdNum, " end B" + + EXIT + END DO + + IF (l == Rod%nAttachedB) THEN ! detect if line not found + print *, "Error: failed to find line to remove during RemoveLine call to Rod ", Rod%IdNum, ". Line ", lineID + END IF + END IF + END DO + + else ! attaching to end A + + DO l = 1,Rod%nAttachedA ! look through attached lines + + IF (Rod%AttachedA(l) == lineID) THEN ! if this is the line's entry in the attachment list + + TopOfLine = Rod%TopA(l); ! record which end of the line was attached + + DO m = l,Rod%nAttachedA-1 + + Rod%AttachedA(m) = Rod%AttachedA(m+1) ! move subsequent line links forward one spot in the list to eliminate this line link + Rod%TopA( m) = Rod%TopA(m+1) + + Rod%nAttachedA = Rod%nAttachedA - 1 ! reduce attached line counter by 1 + + ! also pass back the kinematics at the end + DO J = 1,3 + rEnd( J) = Rod%r( J,0) + rdEnd(J) = Rod%rd(J,0) + END DO + + print*, "Detached line ", lineID, " from Rod ", Rod%IdNum, " end A" + + EXIT + END DO + + IF (l == Rod%nAttachedA) THEN ! detect if line not found + print *, "Error: failed to find line to remove during RemoveLine call to Rod ", Rod%IdNum, ". Line ", lineID + END IF + END IF + END DO + + end if + + END SUBROUTINE Rod_RemoveLine + + + + +END MODULE MoorDyn_Rod diff --git a/modules/moordyn/src/MoorDyn_Types.f90 b/modules/moordyn/src/MoorDyn_Types.f90 index 242c7fee1..b35edada0 100644 --- a/modules/moordyn/src/MoorDyn_Types.f90 +++ b/modules/moordyn/src/MoorDyn_Types.f90 @@ -33,46 +33,116 @@ MODULE MoorDyn_Types !--------------------------------------------------------------------------------------------------------------------------------- USE NWTC_Library IMPLICIT NONE +! ========= MD_InputFileType ======= + TYPE, PUBLIC :: MD_InputFileType + REAL(DbKi) :: DTIC = 0.5 !< convergence check time step for IC generation [[s]] + REAL(DbKi) :: TMaxIC = 120 !< maximum time to allow for getting converged ICs [[s]] + REAL(ReKi) :: CdScaleIC = 1 !< factor to scale drag coefficients by during dynamic relaxation [[]] + REAL(ReKi) :: threshIC = 0.01 !< convergence tolerance for ICs (0.01 means 1%) [[]] + END TYPE MD_InputFileType +! ======================= ! ========= MD_InitInputType ======= TYPE, PUBLIC :: MD_InitInputType REAL(ReKi) :: g = -999.9 !< gravity constant [[m/s^2]] REAL(ReKi) :: rhoW = -999.9 !< sea density [[kg/m^3]] REAL(ReKi) :: WtrDepth = -999.9 !< depth of water [[m]] - REAL(ReKi) , DIMENSION(1:6) :: PtfmInit !< initial position of platform [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: PtfmInit !< initial position of platform(s) shape: 6, nTurbines [-] + INTEGER(IntKi) :: FarmSize = 0 !< Indicates normal FAST module mode if 0, FAST.Farm coupled mode and =nTurbines if >0 [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: TurbineRefPos !< reference position of turbines in farm, shape: 3, nTurbines [-] + REAL(ReKi) :: Tmax !< simulation duration [[s]] CHARACTER(1024) :: FileName !< MoorDyn input file [-] CHARACTER(1024) :: RootName !< RootName for writing output files [-] + LOGICAL :: UsePrimaryInputFile = .TRUE. !< Read input file instead of passed data [-] + TYPE(FileInfoType) :: PassedPrimaryInputData !< Primary input file as FileInfoType (set by driver/glue code) -- String array with metadata [-] LOGICAL :: Echo !< echo parameter - do we want to echo the header line describing the input file? [-] - REAL(ReKi) :: DTIC !< convergence check time step for IC generation [[s]] - REAL(ReKi) :: TMaxIC = 120 !< maximum time to allow for getting converged ICs [[s]] - REAL(ReKi) :: CdScaleIC = 1 !< factor to scale drag coefficients by during dynamic relaxation [[]] - REAL(ReKi) :: threshIC = 0.01 !< convergence tolerance for ICs (0.01 means 1%) [[]] CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: OutList !< string containing list of output channels requested in input file [-] + LOGICAL :: Linearize = .FALSE. !< Flag that tells this module if the glue code wants to linearize. [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: WaveVel !< [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: WaveAcc !< [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WavePDyn !< [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: WaveElev !< [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: WaveTime !< Should this be double precision? [-] END TYPE MD_InitInputType ! ======================= ! ========= MD_LineProp ======= 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 [-] + CHARACTER(20) :: name !< name/identifier of this set of line properties [-] REAL(DbKi) :: d !< volume-equivalent diameter [[m]] REAL(DbKi) :: w !< per-length weight in air [[kg/m]] - REAL(DbKi) :: EA !< stiffness [[N]] + REAL(DbKi) :: EA !< axial stiffness [[N]] + REAL(DbKi) :: EA_D !< axial stiffness [[N]] REAL(DbKi) :: BA !< internal damping coefficient times area [[N-s]] + REAL(DbKi) :: BA_D !< internal damping coefficient times area [[N-s]] + REAL(DbKi) :: EI !< bending stiffness [[N-m]] 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 [-] + INTEGER(IntKi) :: ElasticMod !< Which elasticity model to use: {0 basic, 1 viscoelastic, 2 future SYCOM} [-] + INTEGER(IntKi) :: nEApoints = 0 !< number of values in stress-strain lookup table (0 means using constant E) [-] + REAL(DbKi) , DIMENSION(1:30) :: stiffXs !< x array for stress-strain lookup table (up to nCoef) [-] + REAL(DbKi) , DIMENSION(1:30) :: stiffYs !< y array for stress-strain lookup table [-] + INTEGER(IntKi) :: nBApoints = 0 !< number of values in stress-strainrate lookup table (0 means using constant c) [-] + REAL(DbKi) , DIMENSION(1:30) :: dampXs !< x array for stress-strainrate lookup table (up to nCoef) [-] + REAL(DbKi) , DIMENSION(1:30) :: dampYs !< y array for stress-strainrate lookup table [-] + INTEGER(IntKi) :: nEIpoints = 0 !< number of values in bending stress-strain lookup table (0 means using constant E) [-] + REAL(DbKi) , DIMENSION(1:30) :: bstiffXs !< x array for stress-strain lookup table (up to nCoef) [-] + REAL(DbKi) , DIMENSION(1:30) :: bstiffYs !< y array for stress-strain lookup table [-] END TYPE MD_LineProp ! ======================= +! ========= MD_RodProp ======= + TYPE, PUBLIC :: MD_RodProp + INTEGER(IntKi) :: IdNum !< integer identifier of this set of rod properties [-] + CHARACTER(10) :: name !< name/identifier of this set of rod properties [-] + REAL(DbKi) :: d !< volume-equivalent diameter [[m]] + REAL(DbKi) :: w !< per-length weight in air [[kg/m]] + 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 [-] + REAL(DbKi) :: CdEnd !< drag coefficient for rod end [[-]] + REAL(DbKi) :: CaEnd !< added mass coefficient for rod end [[-]] + END TYPE MD_RodProp +! ======================= +! ========= MD_Body ======= + TYPE, PUBLIC :: MD_Body + INTEGER(IntKi) :: IdNum !< integer identifier of this Connection [-] + INTEGER(IntKi) :: typeNum !< integer identifying the type. 0=fixed, 1=vessel, 2=connect [-] + INTEGER(IntKi) , DIMENSION(1:30) :: AttachedC !< list of IdNums of connections attached to this body [-] + INTEGER(IntKi) , DIMENSION(1:30) :: AttachedR !< list of IdNums of rods attached to this body [-] + INTEGER(IntKi) :: nAttachedC = 0 !< number of attached connections [-] + INTEGER(IntKi) :: nAttachedR = 0 !< number of attached rods [-] + REAL(DbKi) , DIMENSION(1:3,1:30) :: rConnectRel !< relative position of connection on body [-] + REAL(DbKi) , DIMENSION(1:6,1:30) :: r6RodRel !< relative position and orientation of rod on body [-] + REAL(DbKi) :: bodyM !< [-] + REAL(DbKi) :: bodyV !< [-] + REAL(DbKi) , DIMENSION(1:3) :: bodyI !< [-] + REAL(DbKi) , DIMENSION(1:6) :: bodyCdA !< product of drag force and frontal area of connection point [[m^2]] + REAL(DbKi) , DIMENSION(1:6) :: bodyCa !< added mass coefficient of connection point [-] + REAL(DbKi) :: time !< current time [[s]] + REAL(DbKi) , DIMENSION(1:6) :: r6 !< position [-] + REAL(DbKi) , DIMENSION(1:6) :: v6 !< velocity [-] + REAL(DbKi) , DIMENSION(1:6) :: a6 !< acceleration (only used for coupled bodies) [-] + REAL(DbKi) , DIMENSION(1:3) :: U !< water velocity at ref point [[m/s]] + REAL(DbKi) , DIMENSION(1:3) :: Ud !< water acceleration at ref point [[m/s^2]] + REAL(DbKi) :: zeta !< water surface elevation above ref point [[m]] + REAL(DbKi) , DIMENSION(1:6) :: F6net !< total force and moment on body (excluding inertial loads) [-] + REAL(DbKi) , DIMENSION(1:6,1:6) :: M6net !< total mass matrix of Body and any attached objects [-] + REAL(DbKi) , DIMENSION(1:6,1:6) :: M !< rotated body 6-dof mass and inertia matrix in global orientation [-] + REAL(DbKi) , DIMENSION(1:6,1:6) :: M0 !< body 6-dof mass and inertia matrix in its own frame [-] + REAL(DbKi) , DIMENSION(1:3,1:3) :: OrMat !< DCM for body orientation [-] + REAL(DbKi) , DIMENSION(1:3) :: rCG !< vector in body frame from ref point to CG (before rods etc..) [-] + END TYPE MD_Body +! ======================= ! ========= MD_Connect ======= TYPE, PUBLIC :: MD_Connect INTEGER(IntKi) :: IdNum !< integer identifier of this Connection [-] CHARACTER(10) :: type !< type of Connect: fix, vessel, connect [-] - 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(DbKi) :: conX !< [-] - REAL(DbKi) :: conY !< [-] - REAL(DbKi) :: conZ !< [-] + INTEGER(IntKi) :: typeNum !< integer identifying the type. 0=fixed, 1=vessel, 2=connect [-] + INTEGER(IntKi) , DIMENSION(1:10) :: Attached !< list of IdNums of lines attached to this connection node [-] + INTEGER(IntKi) , DIMENSION(1:10) :: Top !< list of ints specifying whether each line is attached at 1 = top/fairlead(end B), 0 = bottom/anchor(end A) [-] + INTEGER(IntKi) :: nAttached = 0 !< number of attached lines [-] REAL(DbKi) :: conM !< [-] REAL(DbKi) :: conV !< [-] REAL(DbKi) :: conFX !< [-] @@ -80,33 +150,129 @@ MODULE MoorDyn_Types 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) :: time !< current time [[s]] REAL(DbKi) , DIMENSION(1:3) :: r !< position [-] REAL(DbKi) , DIMENSION(1:3) :: rd !< velocity [-] + REAL(DbKi) , DIMENSION(1:3) :: a !< acceleration (only used for coupled points) [-] + REAL(DbKi) , DIMENSION(1:3) :: U !< water velocity at node [[m/s]] + REAL(DbKi) , DIMENSION(1:3) :: Ud !< water acceleration at node [[m/s^2]] + REAL(DbKi) :: zeta !< water surface elevation above node [[m]] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: PDyn !< water dynamic pressure at node [[Pa]] + REAL(DbKi) , DIMENSION(1:3) :: Fnet !< total force on node (excluding inertial loads) [-] + REAL(DbKi) , DIMENSION(1:3,1:3) :: M !< node mass matrix, from attached lines [-] END TYPE MD_Connect ! ======================= +! ========= MD_Rod ======= + TYPE, PUBLIC :: MD_Rod + INTEGER(IntKi) :: IdNum !< integer identifier of this Line [-] + CHARACTER(10) :: type !< type of Rod. should match one of RodProp names [-] + INTEGER(IntKi) :: PropsIdNum !< the IdNum of the associated rod properties [-] + INTEGER(IntKi) :: typeNum !< integer identifying the type. 0=fixed, 1=vessel, 2=connect [-] + INTEGER(IntKi) , DIMENSION(1:10) :: AttachedA !< list of IdNums of lines attached to end A [-] + INTEGER(IntKi) , DIMENSION(1:10) :: AttachedB !< list of IdNums of lines attached to end B [-] + INTEGER(IntKi) , DIMENSION(1:10) :: TopA !< list of ints specifying whether each line is attached at 1 = top/fairlead(end B), 0 = bottom/anchor(end A) [-] + INTEGER(IntKi) , DIMENSION(1:10) :: TopB !< list of ints specifying whether each line is attached at 1 = top/fairlead(end B), 0 = bottom/anchor(end A) [-] + INTEGER(IntKi) :: nAttachedA = 0 !< number of attached lines to Rod end A [-] + INTEGER(IntKi) :: nAttachedB = 0 !< number of attached lines to Rod end B [-] + INTEGER(IntKi) , DIMENSION(1:20) :: OutFlagList !< array specifying what line quantities should be output (1 vs 0) [-] + INTEGER(IntKi) :: N !< The number of elements in the line [-] + INTEGER(IntKi) :: endTypeA !< type of connection at end A: 0=pinned to Connection, 1=cantilevered to Rod. [-] + INTEGER(IntKi) :: endTypeB !< type of connection at end B: 0=pinned to Connection, 1=cantilevered to Rod. [-] + REAL(DbKi) :: UnstrLen !< length of the rod [[m]] + REAL(DbKi) :: mass !< mass of the rod [[kg]] + REAL(DbKi) :: rho !< density [[kg/m3]] + REAL(DbKi) :: d !< volume-equivalent diameter [[m]] + REAL(DbKi) :: Can !< [[-]] + REAL(DbKi) :: Cat !< [[-]] + REAL(DbKi) :: Cdn !< [[-]] + REAL(DbKi) :: Cdt !< [[-]] + REAL(DbKi) :: CdEnd !< drag coefficient for rod end [[-]] + REAL(DbKi) :: CaEnd !< added mass coefficient for rod end [[-]] + REAL(DbKi) :: time !< current time [[s]] + REAL(DbKi) :: roll !< roll relative to vertical [deg] + REAL(DbKi) :: pitch !< pitch relative to vertical [deg] + REAL(DbKi) :: h0 !< submerged length of rod axis, distance along rod centerline from end A to the waterplane (0 <= h0 <= L) [m] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: r !< node positions [-] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: rd !< node velocities [-] + REAL(DbKi) , DIMENSION(1:3) :: q !< tangent vector for rod as a whole [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: l !< segment unstretched length [[m]] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: V !< segment volume [[m^3]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: U !< water velocity at node [[m/s]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: Ud !< water acceleration at node [[m/s^2]] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: zeta !< water surface elevation above node [[m]] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: PDyn !< water dynamic pressure at node [[Pa]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: W !< weight vectors [[N]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: Bo !< buoyancy force vectors [[N]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: Pd !< dynamic pressure force 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 :: Fnet !< total force on node [[N]] + REAL(DbKi) , DIMENSION(:,:,:), ALLOCATABLE :: M !< node mass matrix [[kg]] + REAL(DbKi) , DIMENSION(1:3) :: FextA !< external forces from attached lines on/about end A [-] + REAL(DbKi) , DIMENSION(1:3) :: FextB !< external forces from attached lines on/about end A [-] + REAL(DbKi) , DIMENSION(1:3) :: Mext !< external moment vector holding sum of any externally applied moments i.e. bending lines [-] + REAL(DbKi) , DIMENSION(1:6) :: r6 !< 6 DOF position vector [-] + REAL(DbKi) , DIMENSION(1:6) :: v6 !< 6 DOF velocity vector [-] + REAL(DbKi) , DIMENSION(1:6) :: a6 !< 6 DOF acceleration vector (only used for coupled Rods) [-] + REAL(DbKi) , DIMENSION(1:6) :: F6net !< total force and moment about end A (excluding inertial loads) that Rod may exert on whatever it's attached to [-] + REAL(DbKi) , DIMENSION(1:6,1:6) :: M6net !< total mass matrix about end A of Rod and any attached Points [-] + REAL(DbKi) , DIMENSION(1:3,1:3) :: OrMat !< DCM for body orientation [-] + INTEGER(IntKi) :: RodUnOut !< unit number of rod output file [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: RodWrOutput !< one row of output data for this rod [-] + END TYPE MD_Rod +! ======================= ! ========= MD_Line ======= TYPE, PUBLIC :: MD_Line INTEGER(IntKi) :: IdNum !< integer identifier of this Line [-] - CHARACTER(10) :: type !< type of line. should match one of LineProp names [-] + INTEGER(IntKi) :: PropsIdNum !< the IdNum of the associated line properties [-] + INTEGER(IntKi) :: ElasticMod !< Which elasticity model to use: {0 basic, 1 viscoelastic, 2 future SYCOM} [-] INTEGER(IntKi) , DIMENSION(1:20) :: OutFlagList !< array specifying what line quantities should be output (1 vs 0) [-] - INTEGER(IntKi) :: CtrlChan !< index of control channel that will drive line active tensioning (0 for none) [-] + INTEGER(IntKi) :: CtrlChan = 0 !< index of control channel that will drive line active tensioning (0 for none) [-] INTEGER(IntKi) :: FairConnect !< IdNum of Connection at fairlead [-] 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 [-] + INTEGER(IntKi) :: endTypeA !< type of connection at end A: 0=pinned to Connection, 1=cantilevered to Rod. [-] + INTEGER(IntKi) :: endTypeB !< type of connection at end B: 0=pinned to Connection, 1=cantilevered to Rod. [-] REAL(DbKi) :: UnstrLen !< unstretched length of the line [-] - REAL(DbKi) :: BA !< internal damping coefficient times area for this line only [[N-s]] + REAL(DbKi) :: rho !< density [[kg/m3]] + REAL(DbKi) :: d !< volume-equivalent diameter [[m]] + REAL(DbKi) :: EA = 0 !< stiffness [[N]] + REAL(DbKi) :: EA_D = 0 !< dynamic stiffness when using viscoelastic model [[N]] + REAL(DbKi) :: BA = 0 !< internal damping coefficient times area for this line only [[N-s]] + REAL(DbKi) :: BA_D = 0 !< dynamic internal damping coefficient times area when using viscoelastic model [[N-s]] + REAL(DbKi) :: EI = 0 !< bending stiffness [[N-m]] + REAL(DbKi) :: Can !< [[-]] + REAL(DbKi) :: Cat !< [[-]] + REAL(DbKi) :: Cdn !< [[-]] + REAL(DbKi) :: Cdt !< [[-]] + INTEGER(IntKi) :: nEApoints = 0 !< number of values in stress-strain lookup table (0 means using constant E) [-] + REAL(DbKi) , DIMENSION(1:30) :: stiffXs !< x array for stress-strain lookup table (up to nCoef) [-] + REAL(DbKi) , DIMENSION(1:30) :: stiffYs !< y array for stress-strain lookup table [-] + INTEGER(IntKi) :: nBApoints = 0 !< number of values in stress-strainrate lookup table (0 means using constant c) [-] + REAL(DbKi) , DIMENSION(1:30) :: dampXs !< x array for stress-strainrate lookup table (up to nCoef) [-] + REAL(DbKi) , DIMENSION(1:30) :: dampYs !< y array for stress-strainrate lookup table [-] + INTEGER(IntKi) :: nEIpoints = 0 !< number of values in bending stress-strain lookup table (0 means using constant E) [-] + REAL(DbKi) , DIMENSION(1:30) :: bstiffXs !< x array for stress-strain lookup table (up to nCoef) [-] + REAL(DbKi) , DIMENSION(1:30) :: bstiffYs !< y array for stress-strain lookup table [-] + REAL(DbKi) :: time !< current time [[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 :: qs !< segment 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 :: Kurv !< curvature at each node point [[1/m]] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: dl_1 !< segment stretch attributed to static stiffness portion [[m]] REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: V !< segment volume [[m^3]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: U !< water velocity at node [[m/s]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: Ud !< water acceleration at node [[m/s^2]] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: zeta !< water surface elevation above node [[m]] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: PDyn !< water dynamic pressure at node [[Pa]] 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]] @@ -115,17 +281,25 @@ MODULE MoorDyn_Types 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 :: Bs !< node force due to bending moments [[N]] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: Fnet !< total force on node [[N]] REAL(DbKi) , DIMENSION(:,:,:), ALLOCATABLE :: S !< node inverse mass matrix [[kg]] REAL(DbKi) , DIMENSION(:,:,:), ALLOCATABLE :: M !< node mass matrix [[kg]] + REAL(DbKi) , DIMENSION(1:3) :: EndMomentA !< vector of end moments due to bending at line end A [[N-m]] + REAL(DbKi) , DIMENSION(1:3) :: EndMomentB !< vector of end moments due to bending at line end B [[N-m]] INTEGER(IntKi) :: LineUnOut !< unit number of line output file [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: LineWrOutput !< one row of output data for this line [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: LineWrOutput !< one row of output data for this line [-] END TYPE MD_Line ! ======================= +! ========= MD_Fail ======= + TYPE, PUBLIC :: MD_Fail + INTEGER(IntKi) :: IdNum !< integer identifier of this failure [-] + END TYPE MD_Fail +! ======================= ! ========= MD_OutParmType ======= TYPE, PUBLIC :: MD_OutParmType - CHARACTER(ChanLen) :: Name !< name of output channel [-] - CHARACTER(ChanLen) :: Units !< units string [-] + CHARACTER(10) :: Name !< name of output channel [-] + CHARACTER(10) :: Units !< units string [-] INTEGER(IntKi) :: QType !< type of quantity - 0=tension, 1=x, 2=y, 3=z... [-] INTEGER(IntKi) :: OType !< type of object - 0=line, 1=connect [-] INTEGER(IntKi) :: NodeID !< node number if OType=0. 0=anchor, -1=N=Fairlead [-] @@ -138,11 +312,19 @@ MODULE MoorDyn_Types CHARACTER(ChanLen) , DIMENSION(:), ALLOCATABLE :: writeOutputUnt !< second line of output file contents: units [-] TYPE(ProgDesc) :: Ver !< this module's name, version, and date [-] LOGICAL , DIMENSION(:), ALLOCATABLE :: CableCChanRqst !< flag indicating control channel for drive line active tensioning is requested [-] + 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 MD_InitOutputType ! ======================= ! ========= MD_ContinuousStateType ======= TYPE, PUBLIC :: MD_ContinuousStateType - REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: states !< full list of node coordinates and velocities [[m] or [m/s]] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: states !< state vector of mooring system, e.g. node coordinates and velocities [] END TYPE MD_ContinuousStateType ! ======================= ! ========= MD_DiscreteStateType ======= @@ -163,50 +345,291 @@ MODULE MoorDyn_Types ! ========= MD_MiscVarType ======= TYPE, PUBLIC :: MD_MiscVarType TYPE(MD_LineProp) , DIMENSION(:), ALLOCATABLE :: LineTypeList !< array of properties for each line type [-] - TYPE(MD_Connect) , DIMENSION(:), ALLOCATABLE :: ConnectList !< array of connection properties [-] - TYPE(MD_Line) , DIMENSION(:), ALLOCATABLE :: LineList !< array of line properties [-] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: FairIdList !< array of size NFairs listing the ID of each fairlead (index of ConnectList) [] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: ConnIdList !< array of size NConnss listing the ID of each connect type connection (index of ConnectList) [] - INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: LineStateIndList !< starting index of each line's states in state vector [] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MDWrOutput !< Data from time step to be written to a MoorDyn output file [-] + TYPE(MD_RodProp) , DIMENSION(:), ALLOCATABLE :: RodTypeList !< array of properties for each rod type [-] + TYPE(MD_Body) :: GroundBody !< the single ground body which is the parent of all stationary connections [-] + TYPE(MD_Body) , DIMENSION(:), ALLOCATABLE :: BodyList !< array of body objects [-] + TYPE(MD_Rod) , DIMENSION(:), ALLOCATABLE :: RodList !< array of rod objects [-] + TYPE(MD_Connect) , DIMENSION(:), ALLOCATABLE :: ConnectList !< array of connection objects [-] + TYPE(MD_Line) , DIMENSION(:), ALLOCATABLE :: LineList !< array of line objects [-] + TYPE(MD_Fail) , DIMENSION(:), ALLOCATABLE :: FailList !< array of line objects [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: FreeConIs !< array of free connection indices in ConnectList vector [] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: CpldConIs !< array of coupled/fairlead connection indices in ConnectList vector [] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: FreeRodIs !< array of free rod indices in RodList vector [] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: CpldRodIs !< array of coupled/fairlead rod indices in RodList vector [] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: FreeBodyIs !< array of free body indices in BodyList vector [] + INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: CpldBodyIs !< array of coupled body indices in BodyList vector [] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: LineStateIs1 !< starting index of each line's states in state vector [] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: LineStateIsN !< ending index of each line's states in state vector [] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: ConStateIs1 !< starting index of each line's states in state vector [] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: ConStateIsN !< ending index of each line's states in state vector [] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: RodStateIs1 !< starting index of each rod's states in state vector [] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: RodStateIsN !< ending index of each rod's states in state vector [] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: BodyStateIs1 !< starting index of each body's states in state vector [] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: BodyStateIsN !< ending index of each body's states in state vector [] + INTEGER(IntKi) :: Nx !< number of states and size of state vector [] + INTEGER(IntKi) :: WaveTi !< current interpolation index for wave time series data [] + TYPE(MD_ContinuousStateType) :: xTemp !< contains temporary state vector used in integration (put here so it's only allocated once) [-] + TYPE(MD_ContinuousStateType) :: xdTemp !< contains temporary state derivative vector used in integration (put here so it's only allocated once) [-] + REAL(DbKi) , DIMENSION(1:6) :: zeros6 !< array of zeros for convenience [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: MDWrOutput !< Data from time step to be written to a MoorDyn output file [-] + REAL(DbKi) :: LastOutTime !< Time of last writing to MD output files [-] + REAL(ReKi) , DIMENSION(1:6) :: PtfmInit !< initial position of platform for an individual (non-farm) MD instance [-] + REAL(DbKi) , DIMENSION(:,:), ALLOCATABLE :: BathymetryGrid !< matrix describing the bathymetry in a grid of x's and y's [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: BathGrid_Xs !< array of x-coordinates in the bathymetry grid [-] + REAL(DbKi) , DIMENSION(:), ALLOCATABLE :: BathGrid_Ys !< array of y-coordinates in the bathymetry grid [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: BathGrid_npoints !< number of grid points to describe the bathymetry grid [-] END TYPE MD_MiscVarType ! ======================= ! ========= MD_ParameterType ======= TYPE, PUBLIC :: MD_ParameterType - INTEGER(IntKi) :: NTypes !< number of line types [] - INTEGER(IntKi) :: NConnects !< number of Connection objects [] - INTEGER(IntKi) :: NFairs !< number of Fairlead Connections [] - INTEGER(IntKi) :: NConns !< number of Connect type Connections - not to be confused with NConnects [] - INTEGER(IntKi) :: NAnchs !< number of Anchor type Connections [] - INTEGER(IntKi) :: NLines !< number of Line objects [] - REAL(ReKi) :: g = 9.81 !< gravitational constant [[kg/m^2]] - REAL(ReKi) :: rhoW !< density of seawater [[m]] - REAL(ReKi) :: WtrDpth !< water depth [[m]] - REAL(ReKi) :: kBot !< bottom stiffness [[Pa/m]] - REAL(ReKi) :: cBot !< bottom damping [[Pa-s/m]] - REAL(ReKi) :: dtM0 !< desired mooring model time step [[s]] - REAL(ReKi) :: dtCoupling !< coupling time step that MoorDyn should expect [[s]] + INTEGER(IntKi) :: nLineTypes = 0 !< number of line types [] + INTEGER(IntKi) :: nRodTypes = 0 !< number of rod types [] + INTEGER(IntKi) :: nConnects = 0 !< number of Connection objects [] + INTEGER(IntKi) :: nConnectsExtra = 0 !< number of Connection objects including space for extra ones that could arise from line failures [] + INTEGER(IntKi) :: nBodies = 0 !< number of Body objects [] + INTEGER(IntKi) :: nRods = 0 !< number of Rod objects [] + INTEGER(IntKi) :: nLines = 0 !< number of Line objects [] + INTEGER(IntKi) :: nCtrlChans = 0 !< number of distinct control channels specified for use as inputs [] + INTEGER(IntKi) :: nFails = 0 !< number of failure conditions [] + INTEGER(IntKi) :: nFreeBodies = 0 !< [] + INTEGER(IntKi) :: nFreeRods = 0 !< [] + INTEGER(IntKi) :: nFreeCons = 0 !< [] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: nCpldBodies !< number of coupled bodies (for FAST.Farm, size>1 with an entry for each turbine) [] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: nCpldRods !< number of coupled rods (for FAST.Farm, size>1 with an entry for each turbine) [] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: nCpldCons !< number of coupled points (for FAST.Farm, size>1 with an entry for each turbine) [] + INTEGER(IntKi) :: NConns = 0 !< number of Connect type Connections - not to be confused with NConnects [] + INTEGER(IntKi) :: NAnchs = 0 !< number of Anchor type Connections [] + REAL(DbKi) :: Tmax !< simulation duration [[s]] + REAL(DbKi) :: g = 9.81 !< gravitational constant (positive) [[m/s^2]] + REAL(DbKi) :: rhoW = 1025 !< density of seawater [[kg/m^3]] + REAL(DbKi) :: WtrDpth !< water depth [[m]] + REAL(DbKi) :: kBot !< bottom stiffness [[Pa/m]] + REAL(DbKi) :: cBot !< bottom damping [[Pa-s/m]] + REAL(DbKi) :: dtM0 !< desired mooring model time step [[s]] + REAL(DbKi) :: dtCoupling !< coupling time step that MoorDyn should expect [[s]] INTEGER(IntKi) :: NumOuts !< Number of parameters in the output list (number of outputs requested) [-] + REAL(DbKi) :: dtOut !< interval for writing output file lines [[s]] CHARACTER(1024) :: RootName !< RootName for writing output files [-] TYPE(MD_OutParmType) , DIMENSION(:), ALLOCATABLE :: OutParam !< Names and units (and other characteristics) of all requested output parameters [-] CHARACTER(1) :: Delim !< Column delimiter for output text files [-] INTEGER(IntKi) :: MDUnOut !< Unit number of main output file [-] + CHARACTER(1024) :: PriPath !< The path to the primary MoorDyn input file, used if looking for additional input files [-] + INTEGER(IntKi) :: writeLog = -1 !< Switch for level of log file output [-] + INTEGER(IntKi) :: UnLog = -1 !< Unit number of log file [-] + INTEGER(IntKi) :: WaveKin !< Flag for whether or how to consider water kinematics [-] + INTEGER(IntKi) :: Current !< Flag for whether or how to consider water kinematics [-] + INTEGER(IntKi) :: nTurbines !< Number of turbines if MoorDyn is performing an array-level simulation with FAST.Farm, otherwise 0 [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: TurbineRefPos !< reference position of turbines in farm, shape: 3, nTurbines [-] + REAL(DbKi) :: mu_kT !< transverse kinetic friction coefficient [(-)] + REAL(DbKi) :: mu_kA !< axial kinetic friction coefficient [(-)] + REAL(DbKi) :: mc !< ratio of the static friction coefficient to the kinetic friction coefficient [(-)] + REAL(DbKi) :: cv !< saturated damping coefficient [(-)] + INTEGER(IntKi) :: nxWave !< number of x wave grid points [-] + INTEGER(IntKi) :: nyWave !< number of y wave grid points [-] + INTEGER(IntKi) :: nzWave !< number of z wave grid points [-] + INTEGER(IntKi) :: ntWave !< number of wave time steps [-] + REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: pxWave !< x location of wave grid points [-] + REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: pyWave !< y location of wave grid points [-] + REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: pzWave !< z location of wave grid points [-] + REAL(SiKi) :: dtWave !< wave data time step [-] + REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: uxWave !< wave velocities time series at each grid point [-] + REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: uyWave !< wave velocities time series at each grid point [-] + REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: uzWave !< wave velocities time series at each grid point [-] + REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: axWave !< wave accelerations time series at each grid point [-] + REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: ayWave !< wave accelerations time series at each grid point [-] + REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: azWave !< wave accelerations time series at each grid point [-] + REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: PDyn !< wave dynamic pressure time series at each grid point [-] + REAL(SiKi) , DIMENSION(:,:,:), ALLOCATABLE :: zeta !< wave surface elevations time series at each surface grid point [-] + INTEGER(IntKi) :: nzCurrent !< number of z current grid points [-] + REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: pzCurrent !< z location of current grid points [-] + REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: uxCurrent !< current velocities time series at each grid point [-] + REAL(SiKi) , DIMENSION(:), ALLOCATABLE :: uyCurrent !< current velocities time series at each grid point [-] + INTEGER(IntKi) :: Nx0 !< copy of initial size of system state vector, for linearization routines [-] + 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(:), ALLOCATABLE :: 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 !< number of continuous states in jacobian matrix [-] + INTEGER(IntKi) , DIMENSION(:), ALLOCATABLE :: dxIdx_map2_xStateIdx !< Mapping array from index of dX array to corresponding state index [-] END TYPE MD_ParameterType ! ======================= ! ========= MD_InputType ======= TYPE, PUBLIC :: MD_InputType - TYPE(MeshType) :: PtFairleadDisplacement !< mesh for position AND VELOCITY of each fairlead in X,Y,Z [[m, m/s]] + TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: CoupledKinematics !< array of meshes for each coupling point (6 DOF info used for rods and bodies) [[m, m/s]] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: DeltaL !< change in line length command for each channel [[m]] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: DeltaLdot !< rate of change of line length command for each channel [[m]] END TYPE MD_InputType ! ======================= ! ========= MD_OutputType ======= TYPE, PUBLIC :: MD_OutputType - TYPE(MeshType) :: PtFairleadLoad !< point mesh for fairlead forces in X,Y,Z [[N]] + TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: CoupledLoads !< array of point meshes for mooring reaction forces (and moments) at coupling points [[N]] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: WriteOutput !< output vector returned to glue code [] END TYPE MD_OutputType ! ======================= CONTAINS + SUBROUTINE MD_CopyInputFileType( SrcInputFileTypeData, DstInputFileTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_InputFileType), INTENT(IN) :: SrcInputFileTypeData + TYPE(MD_InputFileType), INTENT(INOUT) :: DstInputFileTypeData + 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 = 'MD_CopyInputFileType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstInputFileTypeData%DTIC = SrcInputFileTypeData%DTIC + DstInputFileTypeData%TMaxIC = SrcInputFileTypeData%TMaxIC + DstInputFileTypeData%CdScaleIC = SrcInputFileTypeData%CdScaleIC + DstInputFileTypeData%threshIC = SrcInputFileTypeData%threshIC + END SUBROUTINE MD_CopyInputFileType + + SUBROUTINE MD_DestroyInputFileType( InputFileTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_InputFileType), INTENT(INOUT) :: InputFileTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyInputFileType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE MD_DestroyInputFileType + + SUBROUTINE MD_PackInputFileType( 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(MD_InputFileType), 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 = 'MD_PackInputFileType' + ! 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 + Db_BufSz = Db_BufSz + 1 ! DTIC + Db_BufSz = Db_BufSz + 1 ! TMaxIC + Re_BufSz = Re_BufSz + 1 ! CdScaleIC + Re_BufSz = Re_BufSz + 1 ! threshIC + 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%DTIC + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%TMaxIC + Db_Xferred = Db_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%CdScaleIC + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%threshIC + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE MD_PackInputFileType + + SUBROUTINE MD_UnPackInputFileType( 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(MD_InputFileType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackInputFileType' + ! 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%DTIC = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%TMaxIC = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%CdScaleIC = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%threshIC = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE MD_UnPackInputFileType + SUBROUTINE MD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) TYPE(MD_InitInputType), INTENT(IN) :: SrcInitInputData TYPE(MD_InitInputType), INTENT(INOUT) :: DstInitInputData @@ -227,14 +650,43 @@ SUBROUTINE MD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrSt DstInitInputData%g = SrcInitInputData%g DstInitInputData%rhoW = SrcInitInputData%rhoW DstInitInputData%WtrDepth = SrcInitInputData%WtrDepth +IF (ALLOCATED(SrcInitInputData%PtfmInit)) THEN + i1_l = LBOUND(SrcInitInputData%PtfmInit,1) + i1_u = UBOUND(SrcInitInputData%PtfmInit,1) + i2_l = LBOUND(SrcInitInputData%PtfmInit,2) + i2_u = UBOUND(SrcInitInputData%PtfmInit,2) + IF (.NOT. ALLOCATED(DstInitInputData%PtfmInit)) THEN + ALLOCATE(DstInitInputData%PtfmInit(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%PtfmInit.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF DstInitInputData%PtfmInit = SrcInitInputData%PtfmInit +ENDIF + DstInitInputData%FarmSize = SrcInitInputData%FarmSize +IF (ALLOCATED(SrcInitInputData%TurbineRefPos)) THEN + i1_l = LBOUND(SrcInitInputData%TurbineRefPos,1) + i1_u = UBOUND(SrcInitInputData%TurbineRefPos,1) + i2_l = LBOUND(SrcInitInputData%TurbineRefPos,2) + i2_u = UBOUND(SrcInitInputData%TurbineRefPos,2) + IF (.NOT. ALLOCATED(DstInitInputData%TurbineRefPos)) THEN + ALLOCATE(DstInitInputData%TurbineRefPos(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%TurbineRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%TurbineRefPos = SrcInitInputData%TurbineRefPos +ENDIF + DstInitInputData%Tmax = SrcInitInputData%Tmax DstInitInputData%FileName = SrcInitInputData%FileName DstInitInputData%RootName = SrcInitInputData%RootName + 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 DstInitInputData%Echo = SrcInitInputData%Echo - DstInitInputData%DTIC = SrcInitInputData%DTIC - DstInitInputData%TMaxIC = SrcInitInputData%TMaxIC - DstInitInputData%CdScaleIC = SrcInitInputData%CdScaleIC - DstInitInputData%threshIC = SrcInitInputData%threshIC IF (ALLOCATED(SrcInitInputData%OutList)) THEN i1_l = LBOUND(SrcInitInputData%OutList,1) i1_u = UBOUND(SrcInitInputData%OutList,1) @@ -246,20 +698,128 @@ SUBROUTINE MD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrSt END IF END IF DstInitInputData%OutList = SrcInitInputData%OutList +ENDIF + DstInitInputData%Linearize = SrcInitInputData%Linearize +IF (ALLOCATED(SrcInitInputData%WaveVel)) THEN + i1_l = LBOUND(SrcInitInputData%WaveVel,1) + i1_u = UBOUND(SrcInitInputData%WaveVel,1) + i2_l = LBOUND(SrcInitInputData%WaveVel,2) + i2_u = UBOUND(SrcInitInputData%WaveVel,2) + i3_l = LBOUND(SrcInitInputData%WaveVel,3) + i3_u = UBOUND(SrcInitInputData%WaveVel,3) + IF (.NOT. ALLOCATED(DstInitInputData%WaveVel)) THEN + ALLOCATE(DstInitInputData%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 DstInitInputData%WaveVel.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%WaveVel = SrcInitInputData%WaveVel +ENDIF +IF (ALLOCATED(SrcInitInputData%WaveAcc)) THEN + i1_l = LBOUND(SrcInitInputData%WaveAcc,1) + i1_u = UBOUND(SrcInitInputData%WaveAcc,1) + i2_l = LBOUND(SrcInitInputData%WaveAcc,2) + i2_u = UBOUND(SrcInitInputData%WaveAcc,2) + i3_l = LBOUND(SrcInitInputData%WaveAcc,3) + i3_u = UBOUND(SrcInitInputData%WaveAcc,3) + IF (.NOT. ALLOCATED(DstInitInputData%WaveAcc)) THEN + ALLOCATE(DstInitInputData%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 DstInitInputData%WaveAcc.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%WaveAcc = SrcInitInputData%WaveAcc +ENDIF +IF (ALLOCATED(SrcInitInputData%WavePDyn)) THEN + i1_l = LBOUND(SrcInitInputData%WavePDyn,1) + i1_u = UBOUND(SrcInitInputData%WavePDyn,1) + i2_l = LBOUND(SrcInitInputData%WavePDyn,2) + i2_u = UBOUND(SrcInitInputData%WavePDyn,2) + IF (.NOT. ALLOCATED(DstInitInputData%WavePDyn)) THEN + ALLOCATE(DstInitInputData%WavePDyn(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%WavePDyn.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%WavePDyn = SrcInitInputData%WavePDyn +ENDIF +IF (ALLOCATED(SrcInitInputData%WaveElev)) THEN + i1_l = LBOUND(SrcInitInputData%WaveElev,1) + i1_u = UBOUND(SrcInitInputData%WaveElev,1) + i2_l = LBOUND(SrcInitInputData%WaveElev,2) + i2_u = UBOUND(SrcInitInputData%WaveElev,2) + IF (.NOT. ALLOCATED(DstInitInputData%WaveElev)) THEN + ALLOCATE(DstInitInputData%WaveElev(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%WaveElev.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%WaveElev = SrcInitInputData%WaveElev +ENDIF +IF (ALLOCATED(SrcInitInputData%WaveTime)) THEN + i1_l = LBOUND(SrcInitInputData%WaveTime,1) + i1_u = UBOUND(SrcInitInputData%WaveTime,1) + IF (.NOT. ALLOCATED(DstInitInputData%WaveTime)) THEN + ALLOCATE(DstInitInputData%WaveTime(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%WaveTime.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%WaveTime = SrcInitInputData%WaveTime ENDIF END SUBROUTINE MD_CopyInitInput - SUBROUTINE MD_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE MD_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MD_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(InitInputData%PtfmInit)) THEN + DEALLOCATE(InitInputData%PtfmInit) +ENDIF +IF (ALLOCATED(InitInputData%TurbineRefPos)) THEN + DEALLOCATE(InitInputData%TurbineRefPos) +ENDIF + CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedPrimaryInputData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitInputData%OutList)) THEN DEALLOCATE(InitInputData%OutList) +ENDIF +IF (ALLOCATED(InitInputData%WaveVel)) THEN + DEALLOCATE(InitInputData%WaveVel) +ENDIF +IF (ALLOCATED(InitInputData%WaveAcc)) THEN + DEALLOCATE(InitInputData%WaveAcc) +ENDIF +IF (ALLOCATED(InitInputData%WavePDyn)) THEN + DEALLOCATE(InitInputData%WavePDyn) +ENDIF +IF (ALLOCATED(InitInputData%WaveElev)) THEN + DEALLOCATE(InitInputData%WaveElev) +ENDIF +IF (ALLOCATED(InitInputData%WaveTime)) THEN + DEALLOCATE(InitInputData%WaveTime) ENDIF END SUBROUTINE MD_DestroyInitInput @@ -301,18 +861,70 @@ SUBROUTINE MD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_BufSz = Re_BufSz + 1 ! g Re_BufSz = Re_BufSz + 1 ! rhoW Re_BufSz = Re_BufSz + 1 ! WtrDepth + Int_BufSz = Int_BufSz + 1 ! PtfmInit allocated yes/no + IF ( ALLOCATED(InData%PtfmInit) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! PtfmInit upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%PtfmInit) ! PtfmInit + END IF + Int_BufSz = Int_BufSz + 1 ! FarmSize + Int_BufSz = Int_BufSz + 1 ! TurbineRefPos allocated yes/no + IF ( ALLOCATED(InData%TurbineRefPos) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! TurbineRefPos upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TurbineRefPos) ! TurbineRefPos + END IF + Re_BufSz = Re_BufSz + 1 ! Tmax Int_BufSz = Int_BufSz + 1*LEN(InData%FileName) ! FileName Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName + 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 Int_BufSz = Int_BufSz + 1 ! Echo - Re_BufSz = Re_BufSz + 1 ! DTIC - Re_BufSz = Re_BufSz + 1 ! TMaxIC - Re_BufSz = Re_BufSz + 1 ! CdScaleIC - Re_BufSz = Re_BufSz + 1 ! threshIC 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 ! Linearize + Int_BufSz = Int_BufSz + 1 ! WaveVel allocated yes/no + IF ( ALLOCATED(InData%WaveVel) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! WaveVel upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WaveVel) ! WaveVel + END IF + Int_BufSz = Int_BufSz + 1 ! WaveAcc allocated yes/no + IF ( ALLOCATED(InData%WaveAcc) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! WaveAcc upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WaveAcc) ! WaveAcc + END IF + Int_BufSz = Int_BufSz + 1 ! WavePDyn allocated yes/no + IF ( ALLOCATED(InData%WavePDyn) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! WavePDyn upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WavePDyn) ! WavePDyn + END IF + Int_BufSz = Int_BufSz + 1 ! WaveElev allocated yes/no + IF ( ALLOCATED(InData%WaveElev) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! WaveElev upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WaveElev) ! WaveElev + END IF + 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 + Db_BufSz = Db_BufSz + SIZE(InData%WaveTime) ! WaveTime END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -347,35 +959,97 @@ SUBROUTINE MD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%WtrDepth Re_Xferred = Re_Xferred + 1 - DO i1 = LBOUND(InData%PtfmInit,1), UBOUND(InData%PtfmInit,1) - ReKiBuf(Re_Xferred) = InData%PtfmInit(i1) - Re_Xferred = Re_Xferred + 1 - END DO - DO I = 1, LEN(InData%FileName) - IntKiBuf(Int_Xferred) = ICHAR(InData%FileName(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 - IntKiBuf(Int_Xferred) = TRANSFER(InData%Echo, IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%DTIC - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%TMaxIC - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%CdScaleIC - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%threshIC - Re_Xferred = Re_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%OutList) ) THEN + IF ( .NOT. ALLOCATED(InData%PtfmInit) ) THEN 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 ) = LBOUND(InData%PtfmInit,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmInit,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PtfmInit,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PtfmInit,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%PtfmInit,2), UBOUND(InData%PtfmInit,2) + DO i1 = LBOUND(InData%PtfmInit,1), UBOUND(InData%PtfmInit,1) + ReKiBuf(Re_Xferred) = InData%PtfmInit(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IntKiBuf(Int_Xferred) = InData%FarmSize + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%TurbineRefPos) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TurbineRefPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TurbineRefPos,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TurbineRefPos,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TurbineRefPos,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%TurbineRefPos,2), UBOUND(InData%TurbineRefPos,2) + DO i1 = LBOUND(InData%TurbineRefPos,1), UBOUND(InData%TurbineRefPos,1) + ReKiBuf(Re_Xferred) = InData%TurbineRefPos(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + ReKiBuf(Re_Xferred) = InData%Tmax + Re_Xferred = Re_Xferred + 1 + DO I = 1, LEN(InData%FileName) + IntKiBuf(Int_Xferred) = ICHAR(InData%FileName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(InData%RootName) + IntKiBuf(Int_Xferred) = ICHAR(InData%RootName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + 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 + IntKiBuf(Int_Xferred) = TRANSFER(InData%Echo, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + 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 @@ -385,6 +1059,113 @@ SUBROUTINE MD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 1 END DO ! I END DO + END IF + IntKiBuf(Int_Xferred) = TRANSFER(InData%Linearize, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%WaveVel) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveVel,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveVel,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveVel,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveVel,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveVel,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveVel,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%WaveVel,3), UBOUND(InData%WaveVel,3) + DO i2 = LBOUND(InData%WaveVel,2), UBOUND(InData%WaveVel,2) + DO i1 = LBOUND(InData%WaveVel,1), UBOUND(InData%WaveVel,1) + ReKiBuf(Re_Xferred) = InData%WaveVel(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WaveAcc) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveAcc,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveAcc,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveAcc,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveAcc,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveAcc,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveAcc,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%WaveAcc,3), UBOUND(InData%WaveAcc,3) + DO i2 = LBOUND(InData%WaveAcc,2), UBOUND(InData%WaveAcc,2) + DO i1 = LBOUND(InData%WaveAcc,1), UBOUND(InData%WaveAcc,1) + ReKiBuf(Re_Xferred) = InData%WaveAcc(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WavePDyn) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WavePDyn,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WavePDyn,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WavePDyn,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WavePDyn,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%WavePDyn,2), UBOUND(InData%WavePDyn,2) + DO i1 = LBOUND(InData%WavePDyn,1), UBOUND(InData%WavePDyn,1) + ReKiBuf(Re_Xferred) = InData%WavePDyn(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%WaveElev) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveElev,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveElev,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WaveElev,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveElev,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%WaveElev,2), UBOUND(InData%WaveElev,2) + DO i1 = LBOUND(InData%WaveElev,1), UBOUND(InData%WaveElev,1) + ReKiBuf(Re_Xferred) = InData%WaveElev(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + 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) + DbKiBuf(Db_Xferred) = InData%WaveTime(i1) + Db_Xferred = Db_Xferred + 1 + END DO END IF END SUBROUTINE MD_PackInitInput @@ -423,12 +1204,56 @@ SUBROUTINE MD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = Re_Xferred + 1 OutData%WtrDepth = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 - i1_l = LBOUND(OutData%PtfmInit,1) - i1_u = UBOUND(OutData%PtfmInit,1) - DO i1 = LBOUND(OutData%PtfmInit,1), UBOUND(OutData%PtfmInit,1) - OutData%PtfmInit(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PtfmInit not allocated + Int_Xferred = Int_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%PtfmInit)) DEALLOCATE(OutData%PtfmInit) + ALLOCATE(OutData%PtfmInit(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PtfmInit.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%PtfmInit,2), UBOUND(OutData%PtfmInit,2) + DO i1 = LBOUND(OutData%PtfmInit,1), UBOUND(OutData%PtfmInit,1) + OutData%PtfmInit(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + OutData%FarmSize = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TurbineRefPos not allocated + Int_Xferred = Int_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%TurbineRefPos)) DEALLOCATE(OutData%TurbineRefPos) + ALLOCATE(OutData%TurbineRefPos(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TurbineRefPos.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%TurbineRefPos,2), UBOUND(OutData%TurbineRefPos,2) + DO i1 = LBOUND(OutData%TurbineRefPos,1), UBOUND(OutData%TurbineRefPos,1) + OutData%TurbineRefPos(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + OutData%Tmax = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 DO I = 1, LEN(OutData%FileName) OutData%FileName(I:I) = CHAR(IntKiBuf(Int_Xferred)) Int_Xferred = Int_Xferred + 1 @@ -437,16 +1262,50 @@ SUBROUTINE MD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err OutData%RootName(I:I) = CHAR(IntKiBuf(Int_Xferred)) Int_Xferred = Int_Xferred + 1 END DO ! I + 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) OutData%Echo = TRANSFER(IntKiBuf(Int_Xferred), OutData%Echo) Int_Xferred = Int_Xferred + 1 - OutData%DTIC = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%TMaxIC = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%CdScaleIC = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%threshIC = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutList not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -467,56 +1326,204 @@ SUBROUTINE MD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END DO ! I END DO END IF - END SUBROUTINE MD_UnPackInitInput - - SUBROUTINE MD_CopyLineProp( SrcLinePropData, DstLinePropData, CtrlCode, ErrStat, ErrMsg ) - TYPE(MD_LineProp), INTENT(IN) :: SrcLinePropData - TYPE(MD_LineProp), INTENT(INOUT) :: DstLinePropData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyLineProp' -! - ErrStat = ErrID_None - ErrMsg = "" - DstLinePropData%IdNum = SrcLinePropData%IdNum - DstLinePropData%name = SrcLinePropData%name - DstLinePropData%d = SrcLinePropData%d - DstLinePropData%w = SrcLinePropData%w - DstLinePropData%EA = SrcLinePropData%EA - DstLinePropData%BA = SrcLinePropData%BA - DstLinePropData%Can = SrcLinePropData%Can - DstLinePropData%Cat = SrcLinePropData%Cat - DstLinePropData%Cdn = SrcLinePropData%Cdn - DstLinePropData%Cdt = SrcLinePropData%Cdt - END SUBROUTINE MD_CopyLineProp - - SUBROUTINE MD_DestroyLineProp( LinePropData, ErrStat, ErrMsg ) - TYPE(MD_LineProp), INTENT(INOUT) :: LinePropData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyLineProp' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE MD_DestroyLineProp - - SUBROUTINE MD_PackLineProp( 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(MD_LineProp), 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 + OutData%Linearize = TRANSFER(IntKiBuf(Int_Xferred), OutData%Linearize) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveVel not allocated + Int_Xferred = Int_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%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) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveAcc not allocated + Int_Xferred = Int_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%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%WaveAcc.', 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) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WavePDyn not allocated + Int_Xferred = Int_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%WavePDyn)) DEALLOCATE(OutData%WavePDyn) + ALLOCATE(OutData%WavePDyn(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WavePDyn.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%WavePDyn,2), UBOUND(OutData%WavePDyn,2) + DO i1 = LBOUND(OutData%WavePDyn,1), UBOUND(OutData%WavePDyn,1) + OutData%WavePDyn(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WaveElev not allocated + Int_Xferred = Int_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%WaveElev)) DEALLOCATE(OutData%WaveElev) + ALLOCATE(OutData%WaveElev(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveElev.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%WaveElev,2), UBOUND(OutData%WaveElev,2) + DO i1 = LBOUND(OutData%WaveElev,1), UBOUND(OutData%WaveElev,1) + OutData%WaveElev(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 + Int_Xferred = Int_Xferred + 1 + ELSE + 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 (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveTime.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%WaveTime,1), UBOUND(OutData%WaveTime,1) + OutData%WaveTime(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE MD_UnPackInitInput + + SUBROUTINE MD_CopyLineProp( SrcLinePropData, DstLinePropData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_LineProp), INTENT(IN) :: SrcLinePropData + TYPE(MD_LineProp), INTENT(INOUT) :: DstLinePropData + 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 = 'MD_CopyLineProp' +! + ErrStat = ErrID_None + ErrMsg = "" + DstLinePropData%IdNum = SrcLinePropData%IdNum + DstLinePropData%name = SrcLinePropData%name + DstLinePropData%d = SrcLinePropData%d + DstLinePropData%w = SrcLinePropData%w + DstLinePropData%EA = SrcLinePropData%EA + DstLinePropData%EA_D = SrcLinePropData%EA_D + DstLinePropData%BA = SrcLinePropData%BA + DstLinePropData%BA_D = SrcLinePropData%BA_D + DstLinePropData%EI = SrcLinePropData%EI + DstLinePropData%Can = SrcLinePropData%Can + DstLinePropData%Cat = SrcLinePropData%Cat + DstLinePropData%Cdn = SrcLinePropData%Cdn + DstLinePropData%Cdt = SrcLinePropData%Cdt + DstLinePropData%ElasticMod = SrcLinePropData%ElasticMod + DstLinePropData%nEApoints = SrcLinePropData%nEApoints + DstLinePropData%stiffXs = SrcLinePropData%stiffXs + DstLinePropData%stiffYs = SrcLinePropData%stiffYs + DstLinePropData%nBApoints = SrcLinePropData%nBApoints + DstLinePropData%dampXs = SrcLinePropData%dampXs + DstLinePropData%dampYs = SrcLinePropData%dampYs + DstLinePropData%nEIpoints = SrcLinePropData%nEIpoints + DstLinePropData%bstiffXs = SrcLinePropData%bstiffXs + DstLinePropData%bstiffYs = SrcLinePropData%bstiffYs + END SUBROUTINE MD_CopyLineProp + + SUBROUTINE MD_DestroyLineProp( LinePropData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_LineProp), INTENT(INOUT) :: LinePropData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyLineProp' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE MD_DestroyLineProp + + SUBROUTINE MD_PackLineProp( 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(MD_LineProp), 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 @@ -546,11 +1553,24 @@ SUBROUTINE MD_PackLineProp( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Db_BufSz = Db_BufSz + 1 ! d Db_BufSz = Db_BufSz + 1 ! w Db_BufSz = Db_BufSz + 1 ! EA + Db_BufSz = Db_BufSz + 1 ! EA_D Db_BufSz = Db_BufSz + 1 ! BA + Db_BufSz = Db_BufSz + 1 ! BA_D + Db_BufSz = Db_BufSz + 1 ! EI Db_BufSz = Db_BufSz + 1 ! Can Db_BufSz = Db_BufSz + 1 ! Cat Db_BufSz = Db_BufSz + 1 ! Cdn Db_BufSz = Db_BufSz + 1 ! Cdt + Int_BufSz = Int_BufSz + 1 ! ElasticMod + Int_BufSz = Int_BufSz + 1 ! nEApoints + Db_BufSz = Db_BufSz + SIZE(InData%stiffXs) ! stiffXs + Db_BufSz = Db_BufSz + SIZE(InData%stiffYs) ! stiffYs + Int_BufSz = Int_BufSz + 1 ! nBApoints + Db_BufSz = Db_BufSz + SIZE(InData%dampXs) ! dampXs + Db_BufSz = Db_BufSz + SIZE(InData%dampYs) ! dampYs + Int_BufSz = Int_BufSz + 1 ! nEIpoints + Db_BufSz = Db_BufSz + SIZE(InData%bstiffXs) ! bstiffXs + Db_BufSz = Db_BufSz + SIZE(InData%bstiffYs) ! bstiffYs IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -590,8 +1610,14 @@ SUBROUTINE MD_PackLineProp( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%EA Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%EA_D + Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%BA Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%BA_D + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%EI + Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%Can Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%Cat @@ -600,6 +1626,38 @@ SUBROUTINE MD_PackLineProp( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Db_Xferred = Db_Xferred + 1 DbKiBuf(Db_Xferred) = InData%Cdt Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%ElasticMod + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nEApoints + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%stiffXs,1), UBOUND(InData%stiffXs,1) + DbKiBuf(Db_Xferred) = InData%stiffXs(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%stiffYs,1), UBOUND(InData%stiffYs,1) + DbKiBuf(Db_Xferred) = InData%stiffYs(i1) + Db_Xferred = Db_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%nBApoints + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%dampXs,1), UBOUND(InData%dampXs,1) + DbKiBuf(Db_Xferred) = InData%dampXs(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%dampYs,1), UBOUND(InData%dampYs,1) + DbKiBuf(Db_Xferred) = InData%dampYs(i1) + Db_Xferred = Db_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%nEIpoints + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%bstiffXs,1), UBOUND(InData%bstiffXs,1) + DbKiBuf(Db_Xferred) = InData%bstiffXs(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%bstiffYs,1), UBOUND(InData%bstiffYs,1) + DbKiBuf(Db_Xferred) = InData%bstiffYs(i1) + Db_Xferred = Db_Xferred + 1 + END DO END SUBROUTINE MD_PackLineProp SUBROUTINE MD_UnPackLineProp( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -615,6 +1673,7 @@ SUBROUTINE MD_UnPackLineProp( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM 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 = 'MD_UnPackLineProp' @@ -640,8 +1699,14 @@ SUBROUTINE MD_UnPackLineProp( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM Db_Xferred = Db_Xferred + 1 OutData%EA = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 + OutData%EA_D = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 OutData%BA = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 + OutData%BA_D = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%EI = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 OutData%Can = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 OutData%Cat = DbKiBuf(Db_Xferred) @@ -650,90 +1715,106 @@ SUBROUTINE MD_UnPackLineProp( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM Db_Xferred = Db_Xferred + 1 OutData%Cdt = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 + OutData%ElasticMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nEApoints = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%stiffXs,1) + i1_u = UBOUND(OutData%stiffXs,1) + DO i1 = LBOUND(OutData%stiffXs,1), UBOUND(OutData%stiffXs,1) + OutData%stiffXs(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%stiffYs,1) + i1_u = UBOUND(OutData%stiffYs,1) + DO i1 = LBOUND(OutData%stiffYs,1), UBOUND(OutData%stiffYs,1) + OutData%stiffYs(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + OutData%nBApoints = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%dampXs,1) + i1_u = UBOUND(OutData%dampXs,1) + DO i1 = LBOUND(OutData%dampXs,1), UBOUND(OutData%dampXs,1) + OutData%dampXs(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%dampYs,1) + i1_u = UBOUND(OutData%dampYs,1) + DO i1 = LBOUND(OutData%dampYs,1), UBOUND(OutData%dampYs,1) + OutData%dampYs(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + OutData%nEIpoints = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%bstiffXs,1) + i1_u = UBOUND(OutData%bstiffXs,1) + DO i1 = LBOUND(OutData%bstiffXs,1), UBOUND(OutData%bstiffXs,1) + OutData%bstiffXs(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%bstiffYs,1) + i1_u = UBOUND(OutData%bstiffYs,1) + DO i1 = LBOUND(OutData%bstiffYs,1), UBOUND(OutData%bstiffYs,1) + OutData%bstiffYs(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO END SUBROUTINE MD_UnPackLineProp - SUBROUTINE MD_CopyConnect( SrcConnectData, DstConnectData, CtrlCode, ErrStat, ErrMsg ) - TYPE(MD_Connect), INTENT(IN) :: SrcConnectData - TYPE(MD_Connect), INTENT(INOUT) :: DstConnectData + SUBROUTINE MD_CopyRodProp( SrcRodPropData, DstRodPropData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_RodProp), INTENT(IN) :: SrcRodPropData + TYPE(MD_RodProp), INTENT(INOUT) :: DstRodPropData 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 = 'MD_CopyConnect' + CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyRodProp' ! ErrStat = ErrID_None ErrMsg = "" - DstConnectData%IdNum = SrcConnectData%IdNum - DstConnectData%type = SrcConnectData%type - DstConnectData%TypeNum = SrcConnectData%TypeNum -IF (ALLOCATED(SrcConnectData%AttachedFairs)) THEN - i1_l = LBOUND(SrcConnectData%AttachedFairs,1) - i1_u = UBOUND(SrcConnectData%AttachedFairs,1) - IF (.NOT. ALLOCATED(DstConnectData%AttachedFairs)) THEN - ALLOCATE(DstConnectData%AttachedFairs(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstConnectData%AttachedFairs.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstConnectData%AttachedFairs = SrcConnectData%AttachedFairs -ENDIF -IF (ALLOCATED(SrcConnectData%AttachedAnchs)) THEN - i1_l = LBOUND(SrcConnectData%AttachedAnchs,1) - i1_u = UBOUND(SrcConnectData%AttachedAnchs,1) - IF (.NOT. ALLOCATED(DstConnectData%AttachedAnchs)) THEN - ALLOCATE(DstConnectData%AttachedAnchs(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstConnectData%AttachedAnchs.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstConnectData%AttachedAnchs = SrcConnectData%AttachedAnchs -ENDIF - DstConnectData%conX = SrcConnectData%conX - DstConnectData%conY = SrcConnectData%conY - DstConnectData%conZ = SrcConnectData%conZ - DstConnectData%conM = SrcConnectData%conM - DstConnectData%conV = SrcConnectData%conV - DstConnectData%conFX = SrcConnectData%conFX - DstConnectData%conFY = SrcConnectData%conFY - DstConnectData%conFZ = SrcConnectData%conFZ - DstConnectData%conCa = SrcConnectData%conCa - DstConnectData%conCdA = SrcConnectData%conCdA - DstConnectData%Ftot = SrcConnectData%Ftot - DstConnectData%Mtot = SrcConnectData%Mtot - DstConnectData%S = SrcConnectData%S - DstConnectData%r = SrcConnectData%r - DstConnectData%rd = SrcConnectData%rd - END SUBROUTINE MD_CopyConnect - - SUBROUTINE MD_DestroyConnect( ConnectData, ErrStat, ErrMsg ) - TYPE(MD_Connect), INTENT(INOUT) :: ConnectData + DstRodPropData%IdNum = SrcRodPropData%IdNum + DstRodPropData%name = SrcRodPropData%name + DstRodPropData%d = SrcRodPropData%d + DstRodPropData%w = SrcRodPropData%w + DstRodPropData%Can = SrcRodPropData%Can + DstRodPropData%Cat = SrcRodPropData%Cat + DstRodPropData%Cdn = SrcRodPropData%Cdn + DstRodPropData%Cdt = SrcRodPropData%Cdt + DstRodPropData%CdEnd = SrcRodPropData%CdEnd + DstRodPropData%CaEnd = SrcRodPropData%CaEnd + END SUBROUTINE MD_CopyRodProp + + SUBROUTINE MD_DestroyRodProp( RodPropData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_RodProp), INTENT(INOUT) :: RodPropData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyConnect' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyRodProp' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(ConnectData%AttachedFairs)) THEN - DEALLOCATE(ConnectData%AttachedFairs) -ENDIF -IF (ALLOCATED(ConnectData%AttachedAnchs)) THEN - DEALLOCATE(ConnectData%AttachedAnchs) -ENDIF - END SUBROUTINE MD_DestroyConnect - SUBROUTINE MD_PackConnect( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE MD_DestroyRodProp + + SUBROUTINE MD_PackRodProp( 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(MD_Connect), INTENT(IN) :: InData + TYPE(MD_RodProp), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -748,7 +1829,7 @@ SUBROUTINE MD_PackConnect( 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 = 'MD_PackConnect' + CHARACTER(*), PARAMETER :: RoutineName = 'MD_PackRodProp' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -765,33 +1846,15 @@ SUBROUTINE MD_PackConnect( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Db_BufSz = 0 Int_BufSz = 0 Int_BufSz = Int_BufSz + 1 ! IdNum - Int_BufSz = Int_BufSz + 1*LEN(InData%type) ! type - Int_BufSz = Int_BufSz + 1 ! TypeNum - Int_BufSz = Int_BufSz + 1 ! AttachedFairs allocated yes/no - IF ( ALLOCATED(InData%AttachedFairs) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! AttachedFairs upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%AttachedFairs) ! AttachedFairs - END IF - Int_BufSz = Int_BufSz + 1 ! AttachedAnchs allocated yes/no - IF ( ALLOCATED(InData%AttachedAnchs) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! AttachedAnchs upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%AttachedAnchs) ! AttachedAnchs - END IF - 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 + Int_BufSz = Int_BufSz + 1*LEN(InData%name) ! name + Db_BufSz = Db_BufSz + 1 ! d + Db_BufSz = Db_BufSz + 1 ! w + Db_BufSz = Db_BufSz + 1 ! Can + Db_BufSz = Db_BufSz + 1 ! Cat + Db_BufSz = Db_BufSz + 1 ! Cdn + Db_BufSz = Db_BufSz + 1 ! Cdt + Db_BufSz = Db_BufSz + 1 ! CdEnd + Db_BufSz = Db_BufSz + 1 ! CaEnd IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -821,93 +1884,340 @@ SUBROUTINE MD_PackConnect( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, IntKiBuf(Int_Xferred) = InData%IdNum Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(InData%type) - IntKiBuf(Int_Xferred) = ICHAR(InData%type(I:I), IntKi) + DO I = 1, LEN(InData%name) + IntKiBuf(Int_Xferred) = ICHAR(InData%name(I:I), IntKi) Int_Xferred = Int_Xferred + 1 END DO ! I - IntKiBuf(Int_Xferred) = InData%TypeNum - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%AttachedFairs) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AttachedFairs,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AttachedFairs,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%AttachedFairs,1), UBOUND(InData%AttachedFairs,1) - IntKiBuf(Int_Xferred) = InData%AttachedFairs(i1) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - IF ( .NOT. ALLOCATED(InData%AttachedAnchs) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%AttachedAnchs,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AttachedAnchs,1) - Int_Xferred = Int_Xferred + 2 + DbKiBuf(Db_Xferred) = InData%d + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%w + 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 + DbKiBuf(Db_Xferred) = InData%CdEnd + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%CaEnd + Db_Xferred = Db_Xferred + 1 + END SUBROUTINE MD_PackRodProp - DO i1 = LBOUND(InData%AttachedAnchs,1), UBOUND(InData%AttachedAnchs,1) - IntKiBuf(Int_Xferred) = InData%AttachedAnchs(i1) - Int_Xferred = Int_Xferred + 1 - END DO - END IF - DbKiBuf(Db_Xferred) = InData%conX + SUBROUTINE MD_UnPackRodProp( 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(MD_RodProp), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackRodProp' + ! 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%IdNum = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(OutData%name) + OutData%name(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%d = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%conY + OutData%w = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%conZ + OutData%Can = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%conM + OutData%Cat = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%conV + OutData%Cdn = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%conFX + OutData%Cdt = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%conFY + OutData%CdEnd = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%conFZ + OutData%CaEnd = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%conCa + END SUBROUTINE MD_UnPackRodProp + + SUBROUTINE MD_CopyBody( SrcBodyData, DstBodyData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_Body), INTENT(IN) :: SrcBodyData + TYPE(MD_Body), INTENT(INOUT) :: DstBodyData + 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 = 'MD_CopyBody' +! + ErrStat = ErrID_None + ErrMsg = "" + DstBodyData%IdNum = SrcBodyData%IdNum + DstBodyData%typeNum = SrcBodyData%typeNum + DstBodyData%AttachedC = SrcBodyData%AttachedC + DstBodyData%AttachedR = SrcBodyData%AttachedR + DstBodyData%nAttachedC = SrcBodyData%nAttachedC + DstBodyData%nAttachedR = SrcBodyData%nAttachedR + DstBodyData%rConnectRel = SrcBodyData%rConnectRel + DstBodyData%r6RodRel = SrcBodyData%r6RodRel + DstBodyData%bodyM = SrcBodyData%bodyM + DstBodyData%bodyV = SrcBodyData%bodyV + DstBodyData%bodyI = SrcBodyData%bodyI + DstBodyData%bodyCdA = SrcBodyData%bodyCdA + DstBodyData%bodyCa = SrcBodyData%bodyCa + DstBodyData%time = SrcBodyData%time + DstBodyData%r6 = SrcBodyData%r6 + DstBodyData%v6 = SrcBodyData%v6 + DstBodyData%a6 = SrcBodyData%a6 + DstBodyData%U = SrcBodyData%U + DstBodyData%Ud = SrcBodyData%Ud + DstBodyData%zeta = SrcBodyData%zeta + DstBodyData%F6net = SrcBodyData%F6net + DstBodyData%M6net = SrcBodyData%M6net + DstBodyData%M = SrcBodyData%M + DstBodyData%M0 = SrcBodyData%M0 + DstBodyData%OrMat = SrcBodyData%OrMat + DstBodyData%rCG = SrcBodyData%rCG + END SUBROUTINE MD_CopyBody + + SUBROUTINE MD_DestroyBody( BodyData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_Body), INTENT(INOUT) :: BodyData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyBody' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE MD_DestroyBody + + SUBROUTINE MD_PackBody( 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(MD_Body), 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 = 'MD_PackBody' + ! 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 ! IdNum + Int_BufSz = Int_BufSz + 1 ! typeNum + Int_BufSz = Int_BufSz + SIZE(InData%AttachedC) ! AttachedC + Int_BufSz = Int_BufSz + SIZE(InData%AttachedR) ! AttachedR + Int_BufSz = Int_BufSz + 1 ! nAttachedC + Int_BufSz = Int_BufSz + 1 ! nAttachedR + Db_BufSz = Db_BufSz + SIZE(InData%rConnectRel) ! rConnectRel + Db_BufSz = Db_BufSz + SIZE(InData%r6RodRel) ! r6RodRel + Db_BufSz = Db_BufSz + 1 ! bodyM + Db_BufSz = Db_BufSz + 1 ! bodyV + Db_BufSz = Db_BufSz + SIZE(InData%bodyI) ! bodyI + Db_BufSz = Db_BufSz + SIZE(InData%bodyCdA) ! bodyCdA + Db_BufSz = Db_BufSz + SIZE(InData%bodyCa) ! bodyCa + Db_BufSz = Db_BufSz + 1 ! time + Db_BufSz = Db_BufSz + SIZE(InData%r6) ! r6 + Db_BufSz = Db_BufSz + SIZE(InData%v6) ! v6 + Db_BufSz = Db_BufSz + SIZE(InData%a6) ! a6 + Db_BufSz = Db_BufSz + SIZE(InData%U) ! U + Db_BufSz = Db_BufSz + SIZE(InData%Ud) ! Ud + Db_BufSz = Db_BufSz + 1 ! zeta + Db_BufSz = Db_BufSz + SIZE(InData%F6net) ! F6net + Db_BufSz = Db_BufSz + SIZE(InData%M6net) ! M6net + Db_BufSz = Db_BufSz + SIZE(InData%M) ! M + Db_BufSz = Db_BufSz + SIZE(InData%M0) ! M0 + Db_BufSz = Db_BufSz + SIZE(InData%OrMat) ! OrMat + Db_BufSz = Db_BufSz + SIZE(InData%rCG) ! rCG + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IntKiBuf(Int_Xferred) = InData%IdNum + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%typeNum + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%AttachedC,1), UBOUND(InData%AttachedC,1) + IntKiBuf(Int_Xferred) = InData%AttachedC(i1) + Int_Xferred = Int_Xferred + 1 + END DO + DO i1 = LBOUND(InData%AttachedR,1), UBOUND(InData%AttachedR,1) + IntKiBuf(Int_Xferred) = InData%AttachedR(i1) + Int_Xferred = Int_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%nAttachedC + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nAttachedR + Int_Xferred = Int_Xferred + 1 + DO i2 = LBOUND(InData%rConnectRel,2), UBOUND(InData%rConnectRel,2) + DO i1 = LBOUND(InData%rConnectRel,1), UBOUND(InData%rConnectRel,1) + DbKiBuf(Db_Xferred) = InData%rConnectRel(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + DO i2 = LBOUND(InData%r6RodRel,2), UBOUND(InData%r6RodRel,2) + DO i1 = LBOUND(InData%r6RodRel,1), UBOUND(InData%r6RodRel,1) + DbKiBuf(Db_Xferred) = InData%r6RodRel(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + DbKiBuf(Db_Xferred) = InData%bodyM Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%conCdA + DbKiBuf(Db_Xferred) = InData%bodyV + Db_Xferred = Db_Xferred + 1 + DO i1 = LBOUND(InData%bodyI,1), UBOUND(InData%bodyI,1) + DbKiBuf(Db_Xferred) = InData%bodyI(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%bodyCdA,1), UBOUND(InData%bodyCdA,1) + DbKiBuf(Db_Xferred) = InData%bodyCdA(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%bodyCa,1), UBOUND(InData%bodyCa,1) + DbKiBuf(Db_Xferred) = InData%bodyCa(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DbKiBuf(Db_Xferred) = InData%time + Db_Xferred = Db_Xferred + 1 + DO i1 = LBOUND(InData%r6,1), UBOUND(InData%r6,1) + DbKiBuf(Db_Xferred) = InData%r6(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%v6,1), UBOUND(InData%v6,1) + DbKiBuf(Db_Xferred) = InData%v6(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%a6,1), UBOUND(InData%a6,1) + DbKiBuf(Db_Xferred) = InData%a6(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%U,1), UBOUND(InData%U,1) + DbKiBuf(Db_Xferred) = InData%U(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%Ud,1), UBOUND(InData%Ud,1) + DbKiBuf(Db_Xferred) = InData%Ud(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DbKiBuf(Db_Xferred) = InData%zeta Db_Xferred = Db_Xferred + 1 - DO i1 = LBOUND(InData%Ftot,1), UBOUND(InData%Ftot,1) - DbKiBuf(Db_Xferred) = InData%Ftot(i1) + DO i1 = LBOUND(InData%F6net,1), UBOUND(InData%F6net,1) + DbKiBuf(Db_Xferred) = InData%F6net(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) - DbKiBuf(Db_Xferred) = InData%Mtot(i1,i2) + DO i2 = LBOUND(InData%M6net,2), UBOUND(InData%M6net,2) + DO i1 = LBOUND(InData%M6net,1), UBOUND(InData%M6net,1) + DbKiBuf(Db_Xferred) = InData%M6net(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) - DbKiBuf(Db_Xferred) = InData%S(i1,i2) + 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 - DO i1 = LBOUND(InData%r,1), UBOUND(InData%r,1) - DbKiBuf(Db_Xferred) = InData%r(i1) - Db_Xferred = Db_Xferred + 1 + DO i2 = LBOUND(InData%M0,2), UBOUND(InData%M0,2) + DO i1 = LBOUND(InData%M0,1), UBOUND(InData%M0,1) + DbKiBuf(Db_Xferred) = InData%M0(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO END DO - DO i1 = LBOUND(InData%rd,1), UBOUND(InData%rd,1) - DbKiBuf(Db_Xferred) = InData%rd(i1) + DO i2 = LBOUND(InData%OrMat,2), UBOUND(InData%OrMat,2) + DO i1 = LBOUND(InData%OrMat,1), UBOUND(InData%OrMat,1) + DbKiBuf(Db_Xferred) = InData%OrMat(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + DO i1 = LBOUND(InData%rCG,1), UBOUND(InData%rCG,1) + DbKiBuf(Db_Xferred) = InData%rCG(i1) Db_Xferred = Db_Xferred + 1 END DO - END SUBROUTINE MD_PackConnect + END SUBROUTINE MD_PackBody - SUBROUTINE MD_UnPackConnect( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE MD_UnPackBody( 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(MD_Connect), INTENT(INOUT) :: OutData + TYPE(MD_Body), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -920,7 +2230,7 @@ SUBROUTINE MD_UnPackConnect( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackConnect' + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackBody' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -933,111 +2243,157 @@ SUBROUTINE MD_UnPackConnect( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs Int_Xferred = 1 OutData%IdNum = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(OutData%type) - OutData%type(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%TypeNum = IntKiBuf(Int_Xferred) + OutData%typeNum = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AttachedFairs not allocated + i1_l = LBOUND(OutData%AttachedC,1) + i1_u = UBOUND(OutData%AttachedC,1) + DO i1 = LBOUND(OutData%AttachedC,1), UBOUND(OutData%AttachedC,1) + OutData%AttachedC(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + i1_l = LBOUND(OutData%AttachedR,1) + i1_u = UBOUND(OutData%AttachedR,1) + DO i1 = LBOUND(OutData%AttachedR,1), UBOUND(OutData%AttachedR,1) + OutData%AttachedR(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + OutData%nAttachedC = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - ELSE + OutData%nAttachedR = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%AttachedFairs)) DEALLOCATE(OutData%AttachedFairs) - ALLOCATE(OutData%AttachedFairs(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AttachedFairs.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%AttachedFairs,1), UBOUND(OutData%AttachedFairs,1) - OutData%AttachedFairs(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%rConnectRel,1) + i1_u = UBOUND(OutData%rConnectRel,1) + i2_l = LBOUND(OutData%rConnectRel,2) + i2_u = UBOUND(OutData%rConnectRel,2) + DO i2 = LBOUND(OutData%rConnectRel,2), UBOUND(OutData%rConnectRel,2) + DO i1 = LBOUND(OutData%rConnectRel,1), UBOUND(OutData%rConnectRel,1) + OutData%rConnectRel(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AttachedAnchs not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%AttachedAnchs)) DEALLOCATE(OutData%AttachedAnchs) - ALLOCATE(OutData%AttachedAnchs(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AttachedAnchs.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%AttachedAnchs,1), UBOUND(OutData%AttachedAnchs,1) - OutData%AttachedAnchs(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + END DO + i1_l = LBOUND(OutData%r6RodRel,1) + i1_u = UBOUND(OutData%r6RodRel,1) + i2_l = LBOUND(OutData%r6RodRel,2) + i2_u = UBOUND(OutData%r6RodRel,2) + DO i2 = LBOUND(OutData%r6RodRel,2), UBOUND(OutData%r6RodRel,2) + DO i1 = LBOUND(OutData%r6RodRel,1), UBOUND(OutData%r6RodRel,1) + OutData%r6RodRel(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO - END IF - 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) + END DO + OutData%bodyM = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - OutData%conFZ = DbKiBuf(Db_Xferred) + OutData%bodyV = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - OutData%conCa = DbKiBuf(Db_Xferred) + i1_l = LBOUND(OutData%bodyI,1) + i1_u = UBOUND(OutData%bodyI,1) + DO i1 = LBOUND(OutData%bodyI,1), UBOUND(OutData%bodyI,1) + OutData%bodyI(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%bodyCdA,1) + i1_u = UBOUND(OutData%bodyCdA,1) + DO i1 = LBOUND(OutData%bodyCdA,1), UBOUND(OutData%bodyCdA,1) + OutData%bodyCdA(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%bodyCa,1) + i1_u = UBOUND(OutData%bodyCa,1) + DO i1 = LBOUND(OutData%bodyCa,1), UBOUND(OutData%bodyCa,1) + OutData%bodyCa(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + OutData%time = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - OutData%conCdA = DbKiBuf(Db_Xferred) + i1_l = LBOUND(OutData%r6,1) + i1_u = UBOUND(OutData%r6,1) + DO i1 = LBOUND(OutData%r6,1), UBOUND(OutData%r6,1) + OutData%r6(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%v6,1) + i1_u = UBOUND(OutData%v6,1) + DO i1 = LBOUND(OutData%v6,1), UBOUND(OutData%v6,1) + OutData%v6(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%a6,1) + i1_u = UBOUND(OutData%a6,1) + DO i1 = LBOUND(OutData%a6,1), UBOUND(OutData%a6,1) + OutData%a6(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%U,1) + i1_u = UBOUND(OutData%U,1) + DO i1 = LBOUND(OutData%U,1), UBOUND(OutData%U,1) + OutData%U(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%Ud,1) + i1_u = UBOUND(OutData%Ud,1) + DO i1 = LBOUND(OutData%Ud,1), UBOUND(OutData%Ud,1) + OutData%Ud(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + OutData%zeta = 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) = DbKiBuf(Db_Xferred) + i1_l = LBOUND(OutData%F6net,1) + i1_u = UBOUND(OutData%F6net,1) + DO i1 = LBOUND(OutData%F6net,1), UBOUND(OutData%F6net,1) + OutData%F6net(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO - i1_l = LBOUND(OutData%Mtot,1) - i1_u = UBOUND(OutData%Mtot,1) - i2_l = LBOUND(OutData%Mtot,2) - 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) = DbKiBuf(Db_Xferred) + i1_l = LBOUND(OutData%M6net,1) + i1_u = UBOUND(OutData%M6net,1) + i2_l = LBOUND(OutData%M6net,2) + i2_u = UBOUND(OutData%M6net,2) + DO i2 = LBOUND(OutData%M6net,2), UBOUND(OutData%M6net,2) + DO i1 = LBOUND(OutData%M6net,1), UBOUND(OutData%M6net,1) + OutData%M6net(i1,i2) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END DO - i1_l = LBOUND(OutData%S,1) - i1_u = UBOUND(OutData%S,1) - i2_l = LBOUND(OutData%S,2) - 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) = DbKiBuf(Db_Xferred) + i1_l = LBOUND(OutData%M,1) + i1_u = UBOUND(OutData%M,1) + i2_l = LBOUND(OutData%M,2) + i2_u = UBOUND(OutData%M,2) + DO i2 = LBOUND(OutData%M,2), UBOUND(OutData%M,2) + DO i1 = LBOUND(OutData%M,1), UBOUND(OutData%M,1) + OutData%M(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) = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 + i1_l = LBOUND(OutData%M0,1) + i1_u = UBOUND(OutData%M0,1) + i2_l = LBOUND(OutData%M0,2) + i2_u = UBOUND(OutData%M0,2) + DO i2 = LBOUND(OutData%M0,2), UBOUND(OutData%M0,2) + DO i1 = LBOUND(OutData%M0,1), UBOUND(OutData%M0,1) + OutData%M0(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO 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) = DbKiBuf(Db_Xferred) + i1_l = LBOUND(OutData%OrMat,1) + i1_u = UBOUND(OutData%OrMat,1) + i2_l = LBOUND(OutData%OrMat,2) + i2_u = UBOUND(OutData%OrMat,2) + DO i2 = LBOUND(OutData%OrMat,2), UBOUND(OutData%OrMat,2) + DO i1 = LBOUND(OutData%OrMat,1), UBOUND(OutData%OrMat,1) + OutData%OrMat(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + i1_l = LBOUND(OutData%rCG,1) + i1_u = UBOUND(OutData%rCG,1) + DO i1 = LBOUND(OutData%rCG,1), UBOUND(OutData%rCG,1) + OutData%rCG(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO - END SUBROUTINE MD_UnPackConnect + END SUBROUTINE MD_UnPackBody - SUBROUTINE MD_CopyLine( SrcLineData, DstLineData, CtrlCode, ErrStat, ErrMsg ) - TYPE(MD_Line), INTENT(IN) :: SrcLineData - TYPE(MD_Line), INTENT(INOUT) :: DstLineData + SUBROUTINE MD_CopyConnect( SrcConnectData, DstConnectData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_Connect), INTENT(IN) :: SrcConnectData + TYPE(MD_Connect), INTENT(INOUT) :: DstConnectData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg @@ -1045,374 +2401,781 @@ SUBROUTINE MD_CopyLine( SrcLineData, DstLineData, CtrlCode, ErrStat, ErrMsg ) 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 = 'MD_CopyLine' + CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyConnect' ! ErrStat = ErrID_None ErrMsg = "" - DstLineData%IdNum = SrcLineData%IdNum - DstLineData%type = SrcLineData%type - DstLineData%OutFlagList = SrcLineData%OutFlagList - DstLineData%CtrlChan = SrcLineData%CtrlChan - DstLineData%FairConnect = SrcLineData%FairConnect - DstLineData%AnchConnect = SrcLineData%AnchConnect - DstLineData%PropsIdNum = SrcLineData%PropsIdNum - DstLineData%N = SrcLineData%N - DstLineData%UnstrLen = SrcLineData%UnstrLen - DstLineData%BA = SrcLineData%BA -IF (ALLOCATED(SrcLineData%r)) THEN - i1_l = LBOUND(SrcLineData%r,1) - i1_u = UBOUND(SrcLineData%r,1) - i2_l = LBOUND(SrcLineData%r,2) - i2_u = UBOUND(SrcLineData%r,2) - IF (.NOT. ALLOCATED(DstLineData%r)) THEN - ALLOCATE(DstLineData%r(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + DstConnectData%IdNum = SrcConnectData%IdNum + DstConnectData%type = SrcConnectData%type + DstConnectData%typeNum = SrcConnectData%typeNum + DstConnectData%Attached = SrcConnectData%Attached + DstConnectData%Top = SrcConnectData%Top + DstConnectData%nAttached = SrcConnectData%nAttached + DstConnectData%conM = SrcConnectData%conM + DstConnectData%conV = SrcConnectData%conV + DstConnectData%conFX = SrcConnectData%conFX + DstConnectData%conFY = SrcConnectData%conFY + DstConnectData%conFZ = SrcConnectData%conFZ + DstConnectData%conCa = SrcConnectData%conCa + DstConnectData%conCdA = SrcConnectData%conCdA + DstConnectData%time = SrcConnectData%time + DstConnectData%r = SrcConnectData%r + DstConnectData%rd = SrcConnectData%rd + DstConnectData%a = SrcConnectData%a + DstConnectData%U = SrcConnectData%U + DstConnectData%Ud = SrcConnectData%Ud + DstConnectData%zeta = SrcConnectData%zeta +IF (ALLOCATED(SrcConnectData%PDyn)) THEN + i1_l = LBOUND(SrcConnectData%PDyn,1) + i1_u = UBOUND(SrcConnectData%PDyn,1) + IF (.NOT. ALLOCATED(DstConnectData%PDyn)) THEN + ALLOCATE(DstConnectData%PDyn(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%r.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstConnectData%PDyn.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%r = SrcLineData%r + DstConnectData%PDyn = SrcConnectData%PDyn ENDIF -IF (ALLOCATED(SrcLineData%rd)) THEN - i1_l = LBOUND(SrcLineData%rd,1) - i1_u = UBOUND(SrcLineData%rd,1) - i2_l = LBOUND(SrcLineData%rd,2) - i2_u = UBOUND(SrcLineData%rd,2) - IF (.NOT. ALLOCATED(DstLineData%rd)) THEN - ALLOCATE(DstLineData%rd(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%rd.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + DstConnectData%Fnet = SrcConnectData%Fnet + DstConnectData%M = SrcConnectData%M + END SUBROUTINE MD_CopyConnect + + SUBROUTINE MD_DestroyConnect( ConnectData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_Connect), INTENT(INOUT) :: ConnectData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyConnect' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. END IF - DstLineData%rd = SrcLineData%rd + +IF (ALLOCATED(ConnectData%PDyn)) THEN + DEALLOCATE(ConnectData%PDyn) ENDIF -IF (ALLOCATED(SrcLineData%q)) THEN - i1_l = LBOUND(SrcLineData%q,1) - i1_u = UBOUND(SrcLineData%q,1) - i2_l = LBOUND(SrcLineData%q,2) - i2_u = UBOUND(SrcLineData%q,2) - IF (.NOT. ALLOCATED(DstLineData%q)) THEN - ALLOCATE(DstLineData%q(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%q.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + END SUBROUTINE MD_DestroyConnect + + SUBROUTINE MD_PackConnect( 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(MD_Connect), 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 = 'MD_PackConnect' + ! 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 ! IdNum + Int_BufSz = Int_BufSz + 1*LEN(InData%type) ! type + Int_BufSz = Int_BufSz + 1 ! typeNum + Int_BufSz = Int_BufSz + SIZE(InData%Attached) ! Attached + Int_BufSz = Int_BufSz + SIZE(InData%Top) ! Top + Int_BufSz = Int_BufSz + 1 ! nAttached + 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 + 1 ! time + Db_BufSz = Db_BufSz + SIZE(InData%r) ! r + Db_BufSz = Db_BufSz + SIZE(InData%rd) ! rd + Db_BufSz = Db_BufSz + SIZE(InData%a) ! a + Db_BufSz = Db_BufSz + SIZE(InData%U) ! U + Db_BufSz = Db_BufSz + SIZE(InData%Ud) ! Ud + Db_BufSz = Db_BufSz + 1 ! zeta + Int_BufSz = Int_BufSz + 1 ! PDyn allocated yes/no + IF ( ALLOCATED(InData%PDyn) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PDyn upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%PDyn) ! PDyn + END IF + Db_BufSz = Db_BufSz + SIZE(InData%Fnet) ! Fnet + Db_BufSz = Db_BufSz + SIZE(InData%M) ! M + 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 - DstLineData%q = SrcLineData%q -ENDIF -IF (ALLOCATED(SrcLineData%l)) THEN - i1_l = LBOUND(SrcLineData%l,1) - i1_u = UBOUND(SrcLineData%l,1) - IF (.NOT. ALLOCATED(DstLineData%l)) THEN - ALLOCATE(DstLineData%l(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%l.', ErrStat, ErrMsg,RoutineName) - RETURN - 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 - DstLineData%l = SrcLineData%l -ENDIF -IF (ALLOCATED(SrcLineData%ld)) THEN - i1_l = LBOUND(SrcLineData%ld,1) - i1_u = UBOUND(SrcLineData%ld,1) - IF (.NOT. ALLOCATED(DstLineData%ld)) THEN - ALLOCATE(DstLineData%ld(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%ld.', ErrStat, ErrMsg,RoutineName) - RETURN - 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 - DstLineData%ld = SrcLineData%ld -ENDIF -IF (ALLOCATED(SrcLineData%lstr)) THEN - i1_l = LBOUND(SrcLineData%lstr,1) - i1_u = UBOUND(SrcLineData%lstr,1) - IF (.NOT. ALLOCATED(DstLineData%lstr)) THEN - ALLOCATE(DstLineData%lstr(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%lstr.', ErrStat, ErrMsg,RoutineName) - RETURN - 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%IdNum + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(InData%type) + IntKiBuf(Int_Xferred) = ICHAR(InData%type(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IntKiBuf(Int_Xferred) = InData%typeNum + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%Attached,1), UBOUND(InData%Attached,1) + IntKiBuf(Int_Xferred) = InData%Attached(i1) + Int_Xferred = Int_Xferred + 1 + END DO + DO i1 = LBOUND(InData%Top,1), UBOUND(InData%Top,1) + IntKiBuf(Int_Xferred) = InData%Top(i1) + Int_Xferred = Int_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%nAttached + Int_Xferred = Int_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 + DbKiBuf(Db_Xferred) = InData%time + Db_Xferred = Db_Xferred + 1 + DO i1 = LBOUND(InData%r,1), UBOUND(InData%r,1) + DbKiBuf(Db_Xferred) = InData%r(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%rd,1), UBOUND(InData%rd,1) + DbKiBuf(Db_Xferred) = InData%rd(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%a,1), UBOUND(InData%a,1) + DbKiBuf(Db_Xferred) = InData%a(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%U,1), UBOUND(InData%U,1) + DbKiBuf(Db_Xferred) = InData%U(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%Ud,1), UBOUND(InData%Ud,1) + DbKiBuf(Db_Xferred) = InData%Ud(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DbKiBuf(Db_Xferred) = InData%zeta + Db_Xferred = Db_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%PDyn) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PDyn,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PDyn,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PDyn,1), UBOUND(InData%PDyn,1) + DbKiBuf(Db_Xferred) = InData%PDyn(i1) + Db_Xferred = Db_Xferred + 1 + END DO END IF - DstLineData%lstr = SrcLineData%lstr -ENDIF -IF (ALLOCATED(SrcLineData%lstrd)) THEN - i1_l = LBOUND(SrcLineData%lstrd,1) - i1_u = UBOUND(SrcLineData%lstrd,1) - IF (.NOT. ALLOCATED(DstLineData%lstrd)) THEN - ALLOCATE(DstLineData%lstrd(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%lstrd.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + DO i1 = LBOUND(InData%Fnet,1), UBOUND(InData%Fnet,1) + DbKiBuf(Db_Xferred) = InData%Fnet(i1) + Db_Xferred = Db_Xferred + 1 + END DO + 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 SUBROUTINE MD_PackConnect + + SUBROUTINE MD_UnPackConnect( 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(MD_Connect), 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 = 'MD_UnPackConnect' + ! 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%IdNum = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(OutData%type) + OutData%type(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%typeNum = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%Attached,1) + i1_u = UBOUND(OutData%Attached,1) + DO i1 = LBOUND(OutData%Attached,1), UBOUND(OutData%Attached,1) + OutData%Attached(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + i1_l = LBOUND(OutData%Top,1) + i1_u = UBOUND(OutData%Top,1) + DO i1 = LBOUND(OutData%Top,1), UBOUND(OutData%Top,1) + OutData%Top(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + OutData%nAttached = IntKiBuf(Int_Xferred) + Int_Xferred = Int_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 + OutData%time = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + 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) = 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%a,1) + i1_u = UBOUND(OutData%a,1) + DO i1 = LBOUND(OutData%a,1), UBOUND(OutData%a,1) + OutData%a(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%U,1) + i1_u = UBOUND(OutData%U,1) + DO i1 = LBOUND(OutData%U,1), UBOUND(OutData%U,1) + OutData%U(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%Ud,1) + i1_u = UBOUND(OutData%Ud,1) + DO i1 = LBOUND(OutData%Ud,1), UBOUND(OutData%Ud,1) + OutData%Ud(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + OutData%zeta = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PDyn not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PDyn)) DEALLOCATE(OutData%PDyn) + ALLOCATE(OutData%PDyn(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PDyn.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PDyn,1), UBOUND(OutData%PDyn,1) + OutData%PDyn(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO END IF - DstLineData%lstrd = SrcLineData%lstrd + i1_l = LBOUND(OutData%Fnet,1) + i1_u = UBOUND(OutData%Fnet,1) + DO i1 = LBOUND(OutData%Fnet,1), UBOUND(OutData%Fnet,1) + OutData%Fnet(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%M,1) + i1_u = UBOUND(OutData%M,1) + i2_l = LBOUND(OutData%M,2) + i2_u = UBOUND(OutData%M,2) + DO i2 = LBOUND(OutData%M,2), UBOUND(OutData%M,2) + DO i1 = LBOUND(OutData%M,1), UBOUND(OutData%M,1) + OutData%M(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END SUBROUTINE MD_UnPackConnect + + SUBROUTINE MD_CopyRod( SrcRodData, DstRodData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_Rod), INTENT(IN) :: SrcRodData + TYPE(MD_Rod), INTENT(INOUT) :: DstRodData + 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 = 'MD_CopyRod' +! + ErrStat = ErrID_None + ErrMsg = "" + DstRodData%IdNum = SrcRodData%IdNum + DstRodData%type = SrcRodData%type + DstRodData%PropsIdNum = SrcRodData%PropsIdNum + DstRodData%typeNum = SrcRodData%typeNum + DstRodData%AttachedA = SrcRodData%AttachedA + DstRodData%AttachedB = SrcRodData%AttachedB + DstRodData%TopA = SrcRodData%TopA + DstRodData%TopB = SrcRodData%TopB + DstRodData%nAttachedA = SrcRodData%nAttachedA + DstRodData%nAttachedB = SrcRodData%nAttachedB + DstRodData%OutFlagList = SrcRodData%OutFlagList + DstRodData%N = SrcRodData%N + DstRodData%endTypeA = SrcRodData%endTypeA + DstRodData%endTypeB = SrcRodData%endTypeB + DstRodData%UnstrLen = SrcRodData%UnstrLen + DstRodData%mass = SrcRodData%mass + DstRodData%rho = SrcRodData%rho + DstRodData%d = SrcRodData%d + DstRodData%Can = SrcRodData%Can + DstRodData%Cat = SrcRodData%Cat + DstRodData%Cdn = SrcRodData%Cdn + DstRodData%Cdt = SrcRodData%Cdt + DstRodData%CdEnd = SrcRodData%CdEnd + DstRodData%CaEnd = SrcRodData%CaEnd + DstRodData%time = SrcRodData%time + DstRodData%roll = SrcRodData%roll + DstRodData%pitch = SrcRodData%pitch + DstRodData%h0 = SrcRodData%h0 +IF (ALLOCATED(SrcRodData%r)) THEN + i1_l = LBOUND(SrcRodData%r,1) + i1_u = UBOUND(SrcRodData%r,1) + i2_l = LBOUND(SrcRodData%r,2) + i2_u = UBOUND(SrcRodData%r,2) + IF (.NOT. ALLOCATED(DstRodData%r)) THEN + ALLOCATE(DstRodData%r(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%r.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRodData%r = SrcRodData%r ENDIF -IF (ALLOCATED(SrcLineData%V)) THEN - i1_l = LBOUND(SrcLineData%V,1) - i1_u = UBOUND(SrcLineData%V,1) - IF (.NOT. ALLOCATED(DstLineData%V)) THEN - ALLOCATE(DstLineData%V(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRodData%rd)) THEN + i1_l = LBOUND(SrcRodData%rd,1) + i1_u = UBOUND(SrcRodData%rd,1) + i2_l = LBOUND(SrcRodData%rd,2) + i2_u = UBOUND(SrcRodData%rd,2) + IF (.NOT. ALLOCATED(DstRodData%rd)) THEN + ALLOCATE(DstRodData%rd(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%V.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%rd.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%V = SrcLineData%V + DstRodData%rd = SrcRodData%rd ENDIF -IF (ALLOCATED(SrcLineData%T)) THEN - i1_l = LBOUND(SrcLineData%T,1) - i1_u = UBOUND(SrcLineData%T,1) - i2_l = LBOUND(SrcLineData%T,2) - i2_u = UBOUND(SrcLineData%T,2) - IF (.NOT. ALLOCATED(DstLineData%T)) THEN - ALLOCATE(DstLineData%T(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + DstRodData%q = SrcRodData%q +IF (ALLOCATED(SrcRodData%l)) THEN + i1_l = LBOUND(SrcRodData%l,1) + i1_u = UBOUND(SrcRodData%l,1) + IF (.NOT. ALLOCATED(DstRodData%l)) THEN + ALLOCATE(DstRodData%l(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%T.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%l.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%T = SrcLineData%T + DstRodData%l = SrcRodData%l ENDIF -IF (ALLOCATED(SrcLineData%Td)) THEN - i1_l = LBOUND(SrcLineData%Td,1) - i1_u = UBOUND(SrcLineData%Td,1) - i2_l = LBOUND(SrcLineData%Td,2) - i2_u = UBOUND(SrcLineData%Td,2) - IF (.NOT. ALLOCATED(DstLineData%Td)) THEN - ALLOCATE(DstLineData%Td(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRodData%V)) THEN + i1_l = LBOUND(SrcRodData%V,1) + i1_u = UBOUND(SrcRodData%V,1) + IF (.NOT. ALLOCATED(DstRodData%V)) THEN + ALLOCATE(DstRodData%V(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Td.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%V.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%Td = SrcLineData%Td + DstRodData%V = SrcRodData%V ENDIF -IF (ALLOCATED(SrcLineData%W)) THEN - i1_l = LBOUND(SrcLineData%W,1) - i1_u = UBOUND(SrcLineData%W,1) - i2_l = LBOUND(SrcLineData%W,2) - i2_u = UBOUND(SrcLineData%W,2) - IF (.NOT. ALLOCATED(DstLineData%W)) THEN - ALLOCATE(DstLineData%W(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRodData%U)) THEN + i1_l = LBOUND(SrcRodData%U,1) + i1_u = UBOUND(SrcRodData%U,1) + i2_l = LBOUND(SrcRodData%U,2) + i2_u = UBOUND(SrcRodData%U,2) + IF (.NOT. ALLOCATED(DstRodData%U)) THEN + ALLOCATE(DstRodData%U(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%W.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%U.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%W = SrcLineData%W + DstRodData%U = SrcRodData%U ENDIF -IF (ALLOCATED(SrcLineData%Dp)) THEN - i1_l = LBOUND(SrcLineData%Dp,1) - i1_u = UBOUND(SrcLineData%Dp,1) - i2_l = LBOUND(SrcLineData%Dp,2) - i2_u = UBOUND(SrcLineData%Dp,2) - IF (.NOT. ALLOCATED(DstLineData%Dp)) THEN - ALLOCATE(DstLineData%Dp(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRodData%Ud)) THEN + i1_l = LBOUND(SrcRodData%Ud,1) + i1_u = UBOUND(SrcRodData%Ud,1) + i2_l = LBOUND(SrcRodData%Ud,2) + i2_u = UBOUND(SrcRodData%Ud,2) + IF (.NOT. ALLOCATED(DstRodData%Ud)) THEN + ALLOCATE(DstRodData%Ud(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Dp.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%Ud.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%Dp = SrcLineData%Dp + DstRodData%Ud = SrcRodData%Ud ENDIF -IF (ALLOCATED(SrcLineData%Dq)) THEN - i1_l = LBOUND(SrcLineData%Dq,1) - i1_u = UBOUND(SrcLineData%Dq,1) - i2_l = LBOUND(SrcLineData%Dq,2) - i2_u = UBOUND(SrcLineData%Dq,2) - IF (.NOT. ALLOCATED(DstLineData%Dq)) THEN - ALLOCATE(DstLineData%Dq(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRodData%zeta)) THEN + i1_l = LBOUND(SrcRodData%zeta,1) + i1_u = UBOUND(SrcRodData%zeta,1) + IF (.NOT. ALLOCATED(DstRodData%zeta)) THEN + ALLOCATE(DstRodData%zeta(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Dq.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%zeta.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%Dq = SrcLineData%Dq + DstRodData%zeta = SrcRodData%zeta ENDIF -IF (ALLOCATED(SrcLineData%Ap)) THEN - i1_l = LBOUND(SrcLineData%Ap,1) - i1_u = UBOUND(SrcLineData%Ap,1) - i2_l = LBOUND(SrcLineData%Ap,2) - i2_u = UBOUND(SrcLineData%Ap,2) - IF (.NOT. ALLOCATED(DstLineData%Ap)) THEN - ALLOCATE(DstLineData%Ap(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRodData%PDyn)) THEN + i1_l = LBOUND(SrcRodData%PDyn,1) + i1_u = UBOUND(SrcRodData%PDyn,1) + IF (.NOT. ALLOCATED(DstRodData%PDyn)) THEN + ALLOCATE(DstRodData%PDyn(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Ap.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%PDyn.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%Ap = SrcLineData%Ap + DstRodData%PDyn = SrcRodData%PDyn ENDIF -IF (ALLOCATED(SrcLineData%Aq)) THEN - i1_l = LBOUND(SrcLineData%Aq,1) - i1_u = UBOUND(SrcLineData%Aq,1) - i2_l = LBOUND(SrcLineData%Aq,2) - i2_u = UBOUND(SrcLineData%Aq,2) - IF (.NOT. ALLOCATED(DstLineData%Aq)) THEN - ALLOCATE(DstLineData%Aq(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRodData%W)) THEN + i1_l = LBOUND(SrcRodData%W,1) + i1_u = UBOUND(SrcRodData%W,1) + i2_l = LBOUND(SrcRodData%W,2) + i2_u = UBOUND(SrcRodData%W,2) + IF (.NOT. ALLOCATED(DstRodData%W)) THEN + ALLOCATE(DstRodData%W(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Aq.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%W.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%Aq = SrcLineData%Aq + DstRodData%W = SrcRodData%W ENDIF -IF (ALLOCATED(SrcLineData%B)) THEN - i1_l = LBOUND(SrcLineData%B,1) - i1_u = UBOUND(SrcLineData%B,1) - i2_l = LBOUND(SrcLineData%B,2) - i2_u = UBOUND(SrcLineData%B,2) - IF (.NOT. ALLOCATED(DstLineData%B)) THEN - ALLOCATE(DstLineData%B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRodData%Bo)) THEN + i1_l = LBOUND(SrcRodData%Bo,1) + i1_u = UBOUND(SrcRodData%Bo,1) + i2_l = LBOUND(SrcRodData%Bo,2) + i2_u = UBOUND(SrcRodData%Bo,2) + IF (.NOT. ALLOCATED(DstRodData%Bo)) THEN + ALLOCATE(DstRodData%Bo(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%B.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%Bo.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%B = SrcLineData%B + DstRodData%Bo = SrcRodData%Bo ENDIF -IF (ALLOCATED(SrcLineData%F)) THEN - i1_l = LBOUND(SrcLineData%F,1) - i1_u = UBOUND(SrcLineData%F,1) - i2_l = LBOUND(SrcLineData%F,2) - i2_u = UBOUND(SrcLineData%F,2) - IF (.NOT. ALLOCATED(DstLineData%F)) THEN - ALLOCATE(DstLineData%F(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRodData%Pd)) THEN + i1_l = LBOUND(SrcRodData%Pd,1) + i1_u = UBOUND(SrcRodData%Pd,1) + i2_l = LBOUND(SrcRodData%Pd,2) + i2_u = UBOUND(SrcRodData%Pd,2) + IF (.NOT. ALLOCATED(DstRodData%Pd)) THEN + ALLOCATE(DstRodData%Pd(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%F.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%Pd.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%F = SrcLineData%F + DstRodData%Pd = SrcRodData%Pd ENDIF -IF (ALLOCATED(SrcLineData%S)) THEN - i1_l = LBOUND(SrcLineData%S,1) - i1_u = UBOUND(SrcLineData%S,1) - i2_l = LBOUND(SrcLineData%S,2) - i2_u = UBOUND(SrcLineData%S,2) - i3_l = LBOUND(SrcLineData%S,3) - i3_u = UBOUND(SrcLineData%S,3) - IF (.NOT. ALLOCATED(DstLineData%S)) THEN - ALLOCATE(DstLineData%S(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRodData%Dp)) THEN + i1_l = LBOUND(SrcRodData%Dp,1) + i1_u = UBOUND(SrcRodData%Dp,1) + i2_l = LBOUND(SrcRodData%Dp,2) + i2_u = UBOUND(SrcRodData%Dp,2) + IF (.NOT. ALLOCATED(DstRodData%Dp)) THEN + ALLOCATE(DstRodData%Dp(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%S.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%Dp.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%S = SrcLineData%S + DstRodData%Dp = SrcRodData%Dp ENDIF -IF (ALLOCATED(SrcLineData%M)) THEN - i1_l = LBOUND(SrcLineData%M,1) - i1_u = UBOUND(SrcLineData%M,1) - i2_l = LBOUND(SrcLineData%M,2) - i2_u = UBOUND(SrcLineData%M,2) - i3_l = LBOUND(SrcLineData%M,3) - i3_u = UBOUND(SrcLineData%M,3) - IF (.NOT. ALLOCATED(DstLineData%M)) THEN - ALLOCATE(DstLineData%M(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRodData%Dq)) THEN + i1_l = LBOUND(SrcRodData%Dq,1) + i1_u = UBOUND(SrcRodData%Dq,1) + i2_l = LBOUND(SrcRodData%Dq,2) + i2_u = UBOUND(SrcRodData%Dq,2) + IF (.NOT. ALLOCATED(DstRodData%Dq)) THEN + ALLOCATE(DstRodData%Dq(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%M.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%Dq.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%M = SrcLineData%M + DstRodData%Dq = SrcRodData%Dq ENDIF - DstLineData%LineUnOut = SrcLineData%LineUnOut -IF (ALLOCATED(SrcLineData%LineWrOutput)) THEN - i1_l = LBOUND(SrcLineData%LineWrOutput,1) - i1_u = UBOUND(SrcLineData%LineWrOutput,1) - IF (.NOT. ALLOCATED(DstLineData%LineWrOutput)) THEN - ALLOCATE(DstLineData%LineWrOutput(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcRodData%Ap)) THEN + i1_l = LBOUND(SrcRodData%Ap,1) + i1_u = UBOUND(SrcRodData%Ap,1) + i2_l = LBOUND(SrcRodData%Ap,2) + i2_u = UBOUND(SrcRodData%Ap,2) + IF (.NOT. ALLOCATED(DstRodData%Ap)) THEN + ALLOCATE(DstRodData%Ap(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%LineWrOutput.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%Ap.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstLineData%LineWrOutput = SrcLineData%LineWrOutput + DstRodData%Ap = SrcRodData%Ap ENDIF - END SUBROUTINE MD_CopyLine +IF (ALLOCATED(SrcRodData%Aq)) THEN + i1_l = LBOUND(SrcRodData%Aq,1) + i1_u = UBOUND(SrcRodData%Aq,1) + i2_l = LBOUND(SrcRodData%Aq,2) + i2_u = UBOUND(SrcRodData%Aq,2) + IF (.NOT. ALLOCATED(DstRodData%Aq)) THEN + ALLOCATE(DstRodData%Aq(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%Aq.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRodData%Aq = SrcRodData%Aq +ENDIF +IF (ALLOCATED(SrcRodData%B)) THEN + i1_l = LBOUND(SrcRodData%B,1) + i1_u = UBOUND(SrcRodData%B,1) + i2_l = LBOUND(SrcRodData%B,2) + i2_u = UBOUND(SrcRodData%B,2) + IF (.NOT. ALLOCATED(DstRodData%B)) THEN + ALLOCATE(DstRodData%B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRodData%B = SrcRodData%B +ENDIF +IF (ALLOCATED(SrcRodData%Fnet)) THEN + i1_l = LBOUND(SrcRodData%Fnet,1) + i1_u = UBOUND(SrcRodData%Fnet,1) + i2_l = LBOUND(SrcRodData%Fnet,2) + i2_u = UBOUND(SrcRodData%Fnet,2) + IF (.NOT. ALLOCATED(DstRodData%Fnet)) THEN + ALLOCATE(DstRodData%Fnet(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%Fnet.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRodData%Fnet = SrcRodData%Fnet +ENDIF +IF (ALLOCATED(SrcRodData%M)) THEN + i1_l = LBOUND(SrcRodData%M,1) + i1_u = UBOUND(SrcRodData%M,1) + i2_l = LBOUND(SrcRodData%M,2) + i2_u = UBOUND(SrcRodData%M,2) + i3_l = LBOUND(SrcRodData%M,3) + i3_u = UBOUND(SrcRodData%M,3) + IF (.NOT. ALLOCATED(DstRodData%M)) THEN + ALLOCATE(DstRodData%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 DstRodData%M.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRodData%M = SrcRodData%M +ENDIF + DstRodData%FextA = SrcRodData%FextA + DstRodData%FextB = SrcRodData%FextB + DstRodData%Mext = SrcRodData%Mext + DstRodData%r6 = SrcRodData%r6 + DstRodData%v6 = SrcRodData%v6 + DstRodData%a6 = SrcRodData%a6 + DstRodData%F6net = SrcRodData%F6net + DstRodData%M6net = SrcRodData%M6net + DstRodData%OrMat = SrcRodData%OrMat + DstRodData%RodUnOut = SrcRodData%RodUnOut +IF (ALLOCATED(SrcRodData%RodWrOutput)) THEN + i1_l = LBOUND(SrcRodData%RodWrOutput,1) + i1_u = UBOUND(SrcRodData%RodWrOutput,1) + IF (.NOT. ALLOCATED(DstRodData%RodWrOutput)) THEN + ALLOCATE(DstRodData%RodWrOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstRodData%RodWrOutput.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstRodData%RodWrOutput = SrcRodData%RodWrOutput +ENDIF + END SUBROUTINE MD_CopyRod - SUBROUTINE MD_DestroyLine( LineData, ErrStat, ErrMsg ) - TYPE(MD_Line), INTENT(INOUT) :: LineData + SUBROUTINE MD_DestroyRod( RodData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_Rod), INTENT(INOUT) :: RodData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyLine' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyRod' + + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(LineData%r)) THEN - DEALLOCATE(LineData%r) -ENDIF -IF (ALLOCATED(LineData%rd)) THEN - DEALLOCATE(LineData%rd) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(RodData%r)) THEN + DEALLOCATE(RodData%r) ENDIF -IF (ALLOCATED(LineData%q)) THEN - DEALLOCATE(LineData%q) +IF (ALLOCATED(RodData%rd)) THEN + DEALLOCATE(RodData%rd) ENDIF -IF (ALLOCATED(LineData%l)) THEN - DEALLOCATE(LineData%l) +IF (ALLOCATED(RodData%l)) THEN + DEALLOCATE(RodData%l) ENDIF -IF (ALLOCATED(LineData%ld)) THEN - DEALLOCATE(LineData%ld) +IF (ALLOCATED(RodData%V)) THEN + DEALLOCATE(RodData%V) ENDIF -IF (ALLOCATED(LineData%lstr)) THEN - DEALLOCATE(LineData%lstr) +IF (ALLOCATED(RodData%U)) THEN + DEALLOCATE(RodData%U) ENDIF -IF (ALLOCATED(LineData%lstrd)) THEN - DEALLOCATE(LineData%lstrd) +IF (ALLOCATED(RodData%Ud)) THEN + DEALLOCATE(RodData%Ud) ENDIF -IF (ALLOCATED(LineData%V)) THEN - DEALLOCATE(LineData%V) +IF (ALLOCATED(RodData%zeta)) THEN + DEALLOCATE(RodData%zeta) ENDIF -IF (ALLOCATED(LineData%T)) THEN - DEALLOCATE(LineData%T) +IF (ALLOCATED(RodData%PDyn)) THEN + DEALLOCATE(RodData%PDyn) ENDIF -IF (ALLOCATED(LineData%Td)) THEN - DEALLOCATE(LineData%Td) +IF (ALLOCATED(RodData%W)) THEN + DEALLOCATE(RodData%W) ENDIF -IF (ALLOCATED(LineData%W)) THEN - DEALLOCATE(LineData%W) +IF (ALLOCATED(RodData%Bo)) THEN + DEALLOCATE(RodData%Bo) ENDIF -IF (ALLOCATED(LineData%Dp)) THEN - DEALLOCATE(LineData%Dp) +IF (ALLOCATED(RodData%Pd)) THEN + DEALLOCATE(RodData%Pd) ENDIF -IF (ALLOCATED(LineData%Dq)) THEN - DEALLOCATE(LineData%Dq) +IF (ALLOCATED(RodData%Dp)) THEN + DEALLOCATE(RodData%Dp) ENDIF -IF (ALLOCATED(LineData%Ap)) THEN - DEALLOCATE(LineData%Ap) +IF (ALLOCATED(RodData%Dq)) THEN + DEALLOCATE(RodData%Dq) ENDIF -IF (ALLOCATED(LineData%Aq)) THEN - DEALLOCATE(LineData%Aq) +IF (ALLOCATED(RodData%Ap)) THEN + DEALLOCATE(RodData%Ap) ENDIF -IF (ALLOCATED(LineData%B)) THEN - DEALLOCATE(LineData%B) +IF (ALLOCATED(RodData%Aq)) THEN + DEALLOCATE(RodData%Aq) ENDIF -IF (ALLOCATED(LineData%F)) THEN - DEALLOCATE(LineData%F) +IF (ALLOCATED(RodData%B)) THEN + DEALLOCATE(RodData%B) ENDIF -IF (ALLOCATED(LineData%S)) THEN - DEALLOCATE(LineData%S) +IF (ALLOCATED(RodData%Fnet)) THEN + DEALLOCATE(RodData%Fnet) ENDIF -IF (ALLOCATED(LineData%M)) THEN - DEALLOCATE(LineData%M) +IF (ALLOCATED(RodData%M)) THEN + DEALLOCATE(RodData%M) ENDIF -IF (ALLOCATED(LineData%LineWrOutput)) THEN - DEALLOCATE(LineData%LineWrOutput) +IF (ALLOCATED(RodData%RodWrOutput)) THEN + DEALLOCATE(RodData%RodWrOutput) ENDIF - END SUBROUTINE MD_DestroyLine + END SUBROUTINE MD_DestroyRod - SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE MD_PackRod( 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(MD_Line), INTENT(IN) :: InData + TYPE(MD_Rod), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -1427,7 +3190,7 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_PackLine' + CHARACTER(*), PARAMETER :: RoutineName = 'MD_PackRod' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -1445,14 +3208,32 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_BufSz = 0 Int_BufSz = Int_BufSz + 1 ! IdNum Int_BufSz = Int_BufSz + 1*LEN(InData%type) ! type - Int_BufSz = Int_BufSz + SIZE(InData%OutFlagList) ! OutFlagList - Int_BufSz = Int_BufSz + 1 ! CtrlChan - Int_BufSz = Int_BufSz + 1 ! FairConnect - Int_BufSz = Int_BufSz + 1 ! AnchConnect Int_BufSz = Int_BufSz + 1 ! PropsIdNum + Int_BufSz = Int_BufSz + 1 ! typeNum + Int_BufSz = Int_BufSz + SIZE(InData%AttachedA) ! AttachedA + Int_BufSz = Int_BufSz + SIZE(InData%AttachedB) ! AttachedB + Int_BufSz = Int_BufSz + SIZE(InData%TopA) ! TopA + Int_BufSz = Int_BufSz + SIZE(InData%TopB) ! TopB + Int_BufSz = Int_BufSz + 1 ! nAttachedA + Int_BufSz = Int_BufSz + 1 ! nAttachedB + Int_BufSz = Int_BufSz + SIZE(InData%OutFlagList) ! OutFlagList Int_BufSz = Int_BufSz + 1 ! N + Int_BufSz = Int_BufSz + 1 ! endTypeA + Int_BufSz = Int_BufSz + 1 ! endTypeB Db_BufSz = Db_BufSz + 1 ! UnstrLen - Db_BufSz = Db_BufSz + 1 ! BA + Db_BufSz = Db_BufSz + 1 ! mass + Db_BufSz = Db_BufSz + 1 ! rho + Db_BufSz = Db_BufSz + 1 ! d + Db_BufSz = Db_BufSz + 1 ! Can + Db_BufSz = Db_BufSz + 1 ! Cat + Db_BufSz = Db_BufSz + 1 ! Cdn + Db_BufSz = Db_BufSz + 1 ! Cdt + Db_BufSz = Db_BufSz + 1 ! CdEnd + Db_BufSz = Db_BufSz + 1 ! CaEnd + Db_BufSz = Db_BufSz + 1 ! time + Db_BufSz = Db_BufSz + 1 ! roll + Db_BufSz = Db_BufSz + 1 ! pitch + Db_BufSz = Db_BufSz + 1 ! h0 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 @@ -1463,51 +3244,52 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_BufSz = Int_BufSz + 2*2 ! rd upper/lower bounds for each dimension 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 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 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 - 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 - 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 - 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 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 - Db_BufSz = Db_BufSz + SIZE(InData%T) ! T + Int_BufSz = Int_BufSz + 1 ! U allocated yes/no + IF ( ALLOCATED(InData%U) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! U upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%U) ! U 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 - Db_BufSz = Db_BufSz + SIZE(InData%Td) ! Td + Int_BufSz = Int_BufSz + 1 ! Ud allocated yes/no + IF ( ALLOCATED(InData%Ud) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Ud upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%Ud) ! Ud + END IF + Int_BufSz = Int_BufSz + 1 ! zeta allocated yes/no + IF ( ALLOCATED(InData%zeta) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! zeta upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%zeta) ! zeta + END IF + Int_BufSz = Int_BufSz + 1 ! PDyn allocated yes/no + IF ( ALLOCATED(InData%PDyn) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PDyn upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%PDyn) ! PDyn 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 Db_BufSz = Db_BufSz + SIZE(InData%W) ! W END IF + Int_BufSz = Int_BufSz + 1 ! Bo allocated yes/no + IF ( ALLOCATED(InData%Bo) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Bo upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%Bo) ! Bo + END IF + Int_BufSz = Int_BufSz + 1 ! Pd allocated yes/no + IF ( ALLOCATED(InData%Pd) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Pd upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%Pd) ! Pd + 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 @@ -1533,26 +3315,30 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_BufSz = Int_BufSz + 2*2 ! B upper/lower bounds for each dimension 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 - 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 - Db_BufSz = Db_BufSz + SIZE(InData%S) ! S + Int_BufSz = Int_BufSz + 1 ! Fnet allocated yes/no + IF ( ALLOCATED(InData%Fnet) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Fnet upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%Fnet) ! Fnet 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 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 - IF ( ALLOCATED(InData%LineWrOutput) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! LineWrOutput upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%LineWrOutput) ! LineWrOutput + Db_BufSz = Db_BufSz + SIZE(InData%FextA) ! FextA + Db_BufSz = Db_BufSz + SIZE(InData%FextB) ! FextB + Db_BufSz = Db_BufSz + SIZE(InData%Mext) ! Mext + Db_BufSz = Db_BufSz + SIZE(InData%r6) ! r6 + Db_BufSz = Db_BufSz + SIZE(InData%v6) ! v6 + Db_BufSz = Db_BufSz + SIZE(InData%a6) ! a6 + Db_BufSz = Db_BufSz + SIZE(InData%F6net) ! F6net + Db_BufSz = Db_BufSz + SIZE(InData%M6net) ! M6net + Db_BufSz = Db_BufSz + SIZE(InData%OrMat) ! OrMat + Int_BufSz = Int_BufSz + 1 ! RodUnOut + Int_BufSz = Int_BufSz + 1 ! RodWrOutput allocated yes/no + IF ( ALLOCATED(InData%RodWrOutput) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! RodWrOutput upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%RodWrOutput) ! RodWrOutput END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -1587,23 +3373,67 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz IntKiBuf(Int_Xferred) = ICHAR(InData%type(I:I), IntKi) Int_Xferred = Int_Xferred + 1 END DO ! I - DO i1 = LBOUND(InData%OutFlagList,1), UBOUND(InData%OutFlagList,1) - IntKiBuf(Int_Xferred) = InData%OutFlagList(i1) + IntKiBuf(Int_Xferred) = InData%PropsIdNum + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%typeNum + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%AttachedA,1), UBOUND(InData%AttachedA,1) + IntKiBuf(Int_Xferred) = InData%AttachedA(i1) Int_Xferred = Int_Xferred + 1 END DO - IntKiBuf(Int_Xferred) = InData%CtrlChan + DO i1 = LBOUND(InData%AttachedB,1), UBOUND(InData%AttachedB,1) + IntKiBuf(Int_Xferred) = InData%AttachedB(i1) + Int_Xferred = Int_Xferred + 1 + END DO + DO i1 = LBOUND(InData%TopA,1), UBOUND(InData%TopA,1) + IntKiBuf(Int_Xferred) = InData%TopA(i1) + Int_Xferred = Int_Xferred + 1 + END DO + DO i1 = LBOUND(InData%TopB,1), UBOUND(InData%TopB,1) + IntKiBuf(Int_Xferred) = InData%TopB(i1) + Int_Xferred = Int_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%nAttachedA Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%FairConnect + IntKiBuf(Int_Xferred) = InData%nAttachedB Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%AnchConnect + DO i1 = LBOUND(InData%OutFlagList,1), UBOUND(InData%OutFlagList,1) + IntKiBuf(Int_Xferred) = InData%OutFlagList(i1) + Int_Xferred = Int_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%N Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%PropsIdNum + IntKiBuf(Int_Xferred) = InData%endTypeA Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%N + IntKiBuf(Int_Xferred) = InData%endTypeB Int_Xferred = Int_Xferred + 1 DbKiBuf(Db_Xferred) = InData%UnstrLen Db_Xferred = Db_Xferred + 1 - DbKiBuf(Db_Xferred) = InData%BA + DbKiBuf(Db_Xferred) = InData%mass + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%rho + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%d + 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 + DbKiBuf(Db_Xferred) = InData%CdEnd + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%CaEnd + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%time + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%roll + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%pitch + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%h0 Db_Xferred = Db_Xferred + 1 IF ( .NOT. ALLOCATED(InData%r) ) THEN IntKiBuf( Int_Xferred ) = 0 @@ -1645,157 +3475,166 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%q) ) THEN + DO i1 = LBOUND(InData%q,1), UBOUND(InData%q,1) + DbKiBuf(Db_Xferred) = InData%q(i1) + Db_Xferred = Db_Xferred + 1 + END DO + IF ( .NOT. ALLOCATED(InData%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%q,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%q,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%q,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%q,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%l,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%l,1) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%q,2), UBOUND(InData%q,2) - DO i1 = LBOUND(InData%q,1), UBOUND(InData%q,1) - DbKiBuf(Db_Xferred) = InData%q(i1,i2) - Db_Xferred = Db_Xferred + 1 - END DO + DO i1 = LBOUND(InData%l,1), UBOUND(InData%l,1) + DbKiBuf(Db_Xferred) = InData%l(i1) + Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%l) ) THEN + IF ( .NOT. ALLOCATED(InData%V) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%l,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%l,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%V,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%l,1), UBOUND(InData%l,1) - DbKiBuf(Db_Xferred) = InData%l(i1) + DO i1 = LBOUND(InData%V,1), UBOUND(InData%V,1) + DbKiBuf(Db_Xferred) = InData%V(i1) Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%ld) ) THEN + IF ( .NOT. ALLOCATED(InData%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%ld,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ld,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%U,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%U,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%U,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%U,2) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%ld,1), UBOUND(InData%ld,1) - DbKiBuf(Db_Xferred) = InData%ld(i1) - Db_Xferred = Db_Xferred + 1 + DO i2 = LBOUND(InData%U,2), UBOUND(InData%U,2) + DO i1 = LBOUND(InData%U,1), UBOUND(InData%U,1) + DbKiBuf(Db_Xferred) = InData%U(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%lstr) ) THEN + IF ( .NOT. ALLOCATED(InData%Ud) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%lstr,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%lstr,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Ud,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ud,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Ud,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ud,2) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%lstr,1), UBOUND(InData%lstr,1) - DbKiBuf(Db_Xferred) = InData%lstr(i1) - Db_Xferred = Db_Xferred + 1 + DO i2 = LBOUND(InData%Ud,2), UBOUND(InData%Ud,2) + DO i1 = LBOUND(InData%Ud,1), UBOUND(InData%Ud,1) + DbKiBuf(Db_Xferred) = InData%Ud(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%lstrd) ) THEN + IF ( .NOT. ALLOCATED(InData%zeta) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%lstrd,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%lstrd,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%zeta,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%zeta,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%lstrd,1), UBOUND(InData%lstrd,1) - DbKiBuf(Db_Xferred) = InData%lstrd(i1) + DO i1 = LBOUND(InData%zeta,1), UBOUND(InData%zeta,1) + DbKiBuf(Db_Xferred) = InData%zeta(i1) Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%V) ) THEN + IF ( .NOT. ALLOCATED(InData%PDyn) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%PDyn,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PDyn,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%V,1), UBOUND(InData%V,1) - DbKiBuf(Db_Xferred) = InData%V(i1) + DO i1 = LBOUND(InData%PDyn,1), UBOUND(InData%PDyn,1) + DbKiBuf(Db_Xferred) = InData%PDyn(i1) Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%T) ) THEN + IF ( .NOT. ALLOCATED(InData%W) ) THEN 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,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%T,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%W,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%W,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%T,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%T,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%W,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%W,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%T,2), UBOUND(InData%T,2) - DO i1 = LBOUND(InData%T,1), UBOUND(InData%T,1) - DbKiBuf(Db_Xferred) = InData%T(i1,i2) + DO i2 = LBOUND(InData%W,2), UBOUND(InData%W,2) + DO i1 = LBOUND(InData%W,1), UBOUND(InData%W,1) + DbKiBuf(Db_Xferred) = InData%W(i1,i2) Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Td) ) THEN + IF ( .NOT. ALLOCATED(InData%Bo) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Td,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Td,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Bo,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Bo,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Td,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Td,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Bo,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Bo,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%Td,2), UBOUND(InData%Td,2) - DO i1 = LBOUND(InData%Td,1), UBOUND(InData%Td,1) - DbKiBuf(Db_Xferred) = InData%Td(i1,i2) + DO i2 = LBOUND(InData%Bo,2), UBOUND(InData%Bo,2) + DO i1 = LBOUND(InData%Bo,1), UBOUND(InData%Bo,1) + DbKiBuf(Db_Xferred) = InData%Bo(i1,i2) Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%W) ) THEN + IF ( .NOT. ALLOCATED(InData%Pd) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%W,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%W,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Pd,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Pd,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%W,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%W,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Pd,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Pd,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%W,2), UBOUND(InData%W,2) - DO i1 = LBOUND(InData%W,1), UBOUND(InData%W,1) - DbKiBuf(Db_Xferred) = InData%W(i1,i2) + DO i2 = LBOUND(InData%Pd,2), UBOUND(InData%Pd,2) + DO i1 = LBOUND(InData%Pd,1), UBOUND(InData%Pd,1) + DbKiBuf(Db_Xferred) = InData%Pd(i1,i2) Db_Xferred = Db_Xferred + 1 END DO END DO @@ -1900,51 +3739,26 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%F) ) THEN + IF ( .NOT. ALLOCATED(InData%Fnet) ) THEN 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%Fnet,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Fnet,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%F,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Fnet,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Fnet,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%F,2), UBOUND(InData%F,2) - DO i1 = LBOUND(InData%F,1), UBOUND(InData%F,1) - DbKiBuf(Db_Xferred) = InData%F(i1,i2) + DO i2 = LBOUND(InData%Fnet,2), UBOUND(InData%Fnet,2) + DO i1 = LBOUND(InData%Fnet,1), UBOUND(InData%Fnet,1) + DbKiBuf(Db_Xferred) = InData%Fnet(i1,i2) Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%S) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%S,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%S,1) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%S,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%S,2) - Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%S,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%S,3) - Int_Xferred = Int_Xferred + 2 - - 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) - DbKiBuf(Db_Xferred) = InData%S(i1,i2,i3) - Db_Xferred = Db_Xferred + 1 - END DO - END DO - END DO - END IF IF ( .NOT. ALLOCATED(InData%M) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -1970,30 +3784,70 @@ SUBROUTINE MD_PackLine( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz END DO END DO END IF - IntKiBuf(Int_Xferred) = InData%LineUnOut - Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%LineWrOutput) ) THEN + DO i1 = LBOUND(InData%FextA,1), UBOUND(InData%FextA,1) + DbKiBuf(Db_Xferred) = InData%FextA(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%FextB,1), UBOUND(InData%FextB,1) + DbKiBuf(Db_Xferred) = InData%FextB(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%Mext,1), UBOUND(InData%Mext,1) + DbKiBuf(Db_Xferred) = InData%Mext(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%r6,1), UBOUND(InData%r6,1) + DbKiBuf(Db_Xferred) = InData%r6(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%v6,1), UBOUND(InData%v6,1) + DbKiBuf(Db_Xferred) = InData%v6(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%a6,1), UBOUND(InData%a6,1) + DbKiBuf(Db_Xferred) = InData%a6(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%F6net,1), UBOUND(InData%F6net,1) + DbKiBuf(Db_Xferred) = InData%F6net(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i2 = LBOUND(InData%M6net,2), UBOUND(InData%M6net,2) + DO i1 = LBOUND(InData%M6net,1), UBOUND(InData%M6net,1) + DbKiBuf(Db_Xferred) = InData%M6net(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + DO i2 = LBOUND(InData%OrMat,2), UBOUND(InData%OrMat,2) + DO i1 = LBOUND(InData%OrMat,1), UBOUND(InData%OrMat,1) + DbKiBuf(Db_Xferred) = InData%OrMat(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + IntKiBuf(Int_Xferred) = InData%RodUnOut + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%RodWrOutput) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%LineWrOutput,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LineWrOutput,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%RodWrOutput,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RodWrOutput,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%LineWrOutput,1), UBOUND(InData%LineWrOutput,1) - ReKiBuf(Re_Xferred) = InData%LineWrOutput(i1) - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%RodWrOutput,1), UBOUND(InData%RodWrOutput,1) + DbKiBuf(Db_Xferred) = InData%RodWrOutput(i1) + Db_Xferred = Db_Xferred + 1 END DO END IF - END SUBROUTINE MD_PackLine + END SUBROUTINE MD_PackRod - SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE MD_UnPackRod( 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(MD_Line), INTENT(INOUT) :: OutData + TYPE(MD_Rod), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -2007,7 +3861,7 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackLine' + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackRod' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -2024,25 +3878,77 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) OutData%type(I:I) = CHAR(IntKiBuf(Int_Xferred)) Int_Xferred = Int_Xferred + 1 END DO ! I + OutData%PropsIdNum = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%typeNum = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%AttachedA,1) + i1_u = UBOUND(OutData%AttachedA,1) + DO i1 = LBOUND(OutData%AttachedA,1), UBOUND(OutData%AttachedA,1) + OutData%AttachedA(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + i1_l = LBOUND(OutData%AttachedB,1) + i1_u = UBOUND(OutData%AttachedB,1) + DO i1 = LBOUND(OutData%AttachedB,1), UBOUND(OutData%AttachedB,1) + OutData%AttachedB(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + i1_l = LBOUND(OutData%TopA,1) + i1_u = UBOUND(OutData%TopA,1) + DO i1 = LBOUND(OutData%TopA,1), UBOUND(OutData%TopA,1) + OutData%TopA(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + i1_l = LBOUND(OutData%TopB,1) + i1_u = UBOUND(OutData%TopB,1) + DO i1 = LBOUND(OutData%TopB,1), UBOUND(OutData%TopB,1) + OutData%TopB(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + OutData%nAttachedA = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nAttachedB = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 i1_l = LBOUND(OutData%OutFlagList,1) i1_u = UBOUND(OutData%OutFlagList,1) DO i1 = LBOUND(OutData%OutFlagList,1), UBOUND(OutData%OutFlagList,1) OutData%OutFlagList(i1) = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 END DO - OutData%CtrlChan = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%FairConnect = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%AnchConnect = IntKiBuf(Int_Xferred) + OutData%N = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%PropsIdNum = IntKiBuf(Int_Xferred) + OutData%endTypeA = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%N = IntKiBuf(Int_Xferred) + OutData%endTypeB = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%UnstrLen = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 - OutData%BA = DbKiBuf(Db_Xferred) + OutData%mass = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%rho = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%d = 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 + OutData%CdEnd = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%CaEnd = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%time = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%roll = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%pitch = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%h0 = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! r not allocated Int_Xferred = Int_Xferred + 1 @@ -2090,120 +3996,131 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! q not allocated + i1_l = LBOUND(OutData%q,1) + i1_u = UBOUND(OutData%q,1) + DO i1 = LBOUND(OutData%q,1), UBOUND(OutData%q,1) + OutData%q(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! 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%q)) DEALLOCATE(OutData%q) - ALLOCATE(OutData%q(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%l)) DEALLOCATE(OutData%l) + ALLOCATE(OutData%l(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%q.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%l.', ErrStat, ErrMsg,RoutineName) RETURN 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) = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 - END DO + DO i1 = LBOUND(OutData%l,1), UBOUND(OutData%l,1) + OutData%l(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! l not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! V not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%l)) DEALLOCATE(OutData%l) - ALLOCATE(OutData%l(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%V)) DEALLOCATE(OutData%V) + ALLOCATE(OutData%V(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%l.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%V.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%l,1), UBOUND(OutData%l,1) - OutData%l(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%V,1), UBOUND(OutData%V,1) + OutData%V(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ld not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! 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%ld)) DEALLOCATE(OutData%ld) - ALLOCATE(OutData%ld(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%U)) DEALLOCATE(OutData%U) + ALLOCATE(OutData%U(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ld.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%U.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%ld,1), UBOUND(OutData%ld,1) - OutData%ld(i1) = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 + DO i2 = LBOUND(OutData%U,2), UBOUND(OutData%U,2) + DO i1 = LBOUND(OutData%U,1), UBOUND(OutData%U,1) + OutData%U(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! lstr not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Ud not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%lstr)) DEALLOCATE(OutData%lstr) - ALLOCATE(OutData%lstr(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%Ud)) DEALLOCATE(OutData%Ud) + ALLOCATE(OutData%Ud(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%lstr.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Ud.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%lstr,1), UBOUND(OutData%lstr,1) - OutData%lstr(i1) = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 + DO i2 = LBOUND(OutData%Ud,2), UBOUND(OutData%Ud,2) + DO i1 = LBOUND(OutData%Ud,1), UBOUND(OutData%Ud,1) + OutData%Ud(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! lstrd not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! zeta not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%lstrd)) DEALLOCATE(OutData%lstrd) - ALLOCATE(OutData%lstrd(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%zeta)) DEALLOCATE(OutData%zeta) + ALLOCATE(OutData%zeta(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%lstrd.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%zeta.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%lstrd,1), UBOUND(OutData%lstrd,1) - OutData%lstrd(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%zeta,1), UBOUND(OutData%zeta,1) + OutData%zeta(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! V not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PDyn not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%V)) DEALLOCATE(OutData%V) - ALLOCATE(OutData%V(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%PDyn)) DEALLOCATE(OutData%PDyn) + ALLOCATE(OutData%PDyn(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%V.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PDyn.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%V,1), UBOUND(OutData%V,1) - OutData%V(i1) = DbKiBuf(Db_Xferred) + DO i1 = LBOUND(OutData%PDyn,1), UBOUND(OutData%PDyn,1) + OutData%PDyn(i1) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! T not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! W not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -2213,20 +4130,20 @@ SUBROUTINE MD_UnPackLine( 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%T)) DEALLOCATE(OutData%T) - ALLOCATE(OutData%T(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%W)) DEALLOCATE(OutData%W) + ALLOCATE(OutData%W(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%T.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%W.', ErrStat, ErrMsg,RoutineName) RETURN 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) = DbKiBuf(Db_Xferred) + DO i2 = LBOUND(OutData%W,2), UBOUND(OutData%W,2) + DO i1 = LBOUND(OutData%W,1), UBOUND(OutData%W,1) + OutData%W(i1,i2) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Td not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Bo not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -2236,20 +4153,20 @@ SUBROUTINE MD_UnPackLine( 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%Td)) DEALLOCATE(OutData%Td) - ALLOCATE(OutData%Td(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Bo)) DEALLOCATE(OutData%Bo) + ALLOCATE(OutData%Bo(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Td.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Bo.', ErrStat, ErrMsg,RoutineName) RETURN 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) = DbKiBuf(Db_Xferred) + DO i2 = LBOUND(OutData%Bo,2), UBOUND(OutData%Bo,2) + DO i1 = LBOUND(OutData%Bo,1), UBOUND(OutData%Bo,1) + OutData%Bo(i1,i2) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! W not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Pd not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -2259,15 +4176,15 @@ SUBROUTINE MD_UnPackLine( 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%W)) DEALLOCATE(OutData%W) - ALLOCATE(OutData%W(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Pd)) DEALLOCATE(OutData%Pd) + ALLOCATE(OutData%Pd(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%W.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Pd.', ErrStat, ErrMsg,RoutineName) RETURN 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) = DbKiBuf(Db_Xferred) + DO i2 = LBOUND(OutData%Pd,2), UBOUND(OutData%Pd,2) + DO i1 = LBOUND(OutData%Pd,1), UBOUND(OutData%Pd,1) + OutData%Pd(i1,i2) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END DO @@ -2387,7 +4304,7 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Fnet not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -2397,47 +4314,19 @@ SUBROUTINE MD_UnPackLine( 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%F)) DEALLOCATE(OutData%F) - ALLOCATE(OutData%F(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Fnet)) DEALLOCATE(OutData%Fnet) + ALLOCATE(OutData%Fnet(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%Fnet.', ErrStat, ErrMsg,RoutineName) RETURN 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) = DbKiBuf(Db_Xferred) + DO i2 = LBOUND(OutData%Fnet,2), UBOUND(OutData%Fnet,2) + DO i1 = LBOUND(OutData%Fnet,1), UBOUND(OutData%Fnet,1) + OutData%Fnet(i1,i2) = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! S not allocated - Int_Xferred = Int_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%S)) DEALLOCATE(OutData%S) - ALLOCATE(OutData%S(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%S.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - 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) = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 - END DO - END DO - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! M not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -2466,776 +4355,632 @@ SUBROUTINE MD_UnPackLine( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END DO END DO END IF - OutData%LineUnOut = IntKiBuf(Int_Xferred) + i1_l = LBOUND(OutData%FextA,1) + i1_u = UBOUND(OutData%FextA,1) + DO i1 = LBOUND(OutData%FextA,1), UBOUND(OutData%FextA,1) + OutData%FextA(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%FextB,1) + i1_u = UBOUND(OutData%FextB,1) + DO i1 = LBOUND(OutData%FextB,1), UBOUND(OutData%FextB,1) + OutData%FextB(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%Mext,1) + i1_u = UBOUND(OutData%Mext,1) + DO i1 = LBOUND(OutData%Mext,1), UBOUND(OutData%Mext,1) + OutData%Mext(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%r6,1) + i1_u = UBOUND(OutData%r6,1) + DO i1 = LBOUND(OutData%r6,1), UBOUND(OutData%r6,1) + OutData%r6(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%v6,1) + i1_u = UBOUND(OutData%v6,1) + DO i1 = LBOUND(OutData%v6,1), UBOUND(OutData%v6,1) + OutData%v6(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%a6,1) + i1_u = UBOUND(OutData%a6,1) + DO i1 = LBOUND(OutData%a6,1), UBOUND(OutData%a6,1) + OutData%a6(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%F6net,1) + i1_u = UBOUND(OutData%F6net,1) + DO i1 = LBOUND(OutData%F6net,1), UBOUND(OutData%F6net,1) + OutData%F6net(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%M6net,1) + i1_u = UBOUND(OutData%M6net,1) + i2_l = LBOUND(OutData%M6net,2) + i2_u = UBOUND(OutData%M6net,2) + DO i2 = LBOUND(OutData%M6net,2), UBOUND(OutData%M6net,2) + DO i1 = LBOUND(OutData%M6net,1), UBOUND(OutData%M6net,1) + OutData%M6net(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + i1_l = LBOUND(OutData%OrMat,1) + i1_u = UBOUND(OutData%OrMat,1) + i2_l = LBOUND(OutData%OrMat,2) + i2_u = UBOUND(OutData%OrMat,2) + DO i2 = LBOUND(OutData%OrMat,2), UBOUND(OutData%OrMat,2) + DO i1 = LBOUND(OutData%OrMat,1), UBOUND(OutData%OrMat,1) + OutData%OrMat(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + OutData%RodUnOut = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LineWrOutput not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RodWrOutput not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%LineWrOutput)) DEALLOCATE(OutData%LineWrOutput) - ALLOCATE(OutData%LineWrOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%RodWrOutput)) DEALLOCATE(OutData%RodWrOutput) + ALLOCATE(OutData%RodWrOutput(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LineWrOutput.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RodWrOutput.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%LineWrOutput,1), UBOUND(OutData%LineWrOutput,1) - OutData%LineWrOutput(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(OutData%RodWrOutput,1), UBOUND(OutData%RodWrOutput,1) + OutData%RodWrOutput(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 END DO END IF - END SUBROUTINE MD_UnPackLine + END SUBROUTINE MD_UnPackRod - SUBROUTINE MD_CopyOutParmType( SrcOutParmTypeData, DstOutParmTypeData, CtrlCode, ErrStat, ErrMsg ) - TYPE(MD_OutParmType), INTENT(IN) :: SrcOutParmTypeData - TYPE(MD_OutParmType), INTENT(INOUT) :: DstOutParmTypeData + SUBROUTINE MD_CopyLine( SrcLineData, DstLineData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_Line), INTENT(IN) :: SrcLineData + TYPE(MD_Line), INTENT(INOUT) :: DstLineData 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 = 'MD_CopyOutParmType' + CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyLine' ! ErrStat = ErrID_None ErrMsg = "" - DstOutParmTypeData%Name = SrcOutParmTypeData%Name - DstOutParmTypeData%Units = SrcOutParmTypeData%Units - DstOutParmTypeData%QType = SrcOutParmTypeData%QType - DstOutParmTypeData%OType = SrcOutParmTypeData%OType - DstOutParmTypeData%NodeID = SrcOutParmTypeData%NodeID - DstOutParmTypeData%ObjID = SrcOutParmTypeData%ObjID - END SUBROUTINE MD_CopyOutParmType - - SUBROUTINE MD_DestroyOutParmType( OutParmTypeData, ErrStat, ErrMsg ) - TYPE(MD_OutParmType), INTENT(INOUT) :: OutParmTypeData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyOutParmType' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE MD_DestroyOutParmType - - SUBROUTINE MD_PackOutParmType( 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(MD_OutParmType), 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 = 'MD_PackOutParmType' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1*LEN(InData%Name) ! Name - Int_BufSz = Int_BufSz + 1*LEN(InData%Units) ! Units - Int_BufSz = Int_BufSz + 1 ! QType - Int_BufSz = Int_BufSz + 1 ! OType - Int_BufSz = Int_BufSz + 1 ! NodeID - Int_BufSz = Int_BufSz + 1 ! ObjID - 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 + DstLineData%IdNum = SrcLineData%IdNum + DstLineData%PropsIdNum = SrcLineData%PropsIdNum + DstLineData%ElasticMod = SrcLineData%ElasticMod + DstLineData%OutFlagList = SrcLineData%OutFlagList + DstLineData%CtrlChan = SrcLineData%CtrlChan + DstLineData%FairConnect = SrcLineData%FairConnect + DstLineData%AnchConnect = SrcLineData%AnchConnect + DstLineData%N = SrcLineData%N + DstLineData%endTypeA = SrcLineData%endTypeA + DstLineData%endTypeB = SrcLineData%endTypeB + DstLineData%UnstrLen = SrcLineData%UnstrLen + DstLineData%rho = SrcLineData%rho + DstLineData%d = SrcLineData%d + DstLineData%EA = SrcLineData%EA + DstLineData%EA_D = SrcLineData%EA_D + DstLineData%BA = SrcLineData%BA + DstLineData%BA_D = SrcLineData%BA_D + DstLineData%EI = SrcLineData%EI + DstLineData%Can = SrcLineData%Can + DstLineData%Cat = SrcLineData%Cat + DstLineData%Cdn = SrcLineData%Cdn + DstLineData%Cdt = SrcLineData%Cdt + DstLineData%nEApoints = SrcLineData%nEApoints + DstLineData%stiffXs = SrcLineData%stiffXs + DstLineData%stiffYs = SrcLineData%stiffYs + DstLineData%nBApoints = SrcLineData%nBApoints + DstLineData%dampXs = SrcLineData%dampXs + DstLineData%dampYs = SrcLineData%dampYs + DstLineData%nEIpoints = SrcLineData%nEIpoints + DstLineData%bstiffXs = SrcLineData%bstiffXs + DstLineData%bstiffYs = SrcLineData%bstiffYs + DstLineData%time = SrcLineData%time +IF (ALLOCATED(SrcLineData%r)) THEN + i1_l = LBOUND(SrcLineData%r,1) + i1_u = UBOUND(SrcLineData%r,1) + i2_l = LBOUND(SrcLineData%r,2) + i2_u = UBOUND(SrcLineData%r,2) + IF (.NOT. ALLOCATED(DstLineData%r)) THEN + ALLOCATE(DstLineData%r(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%r.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - DO I = 1, LEN(InData%Name) - IntKiBuf(Int_Xferred) = ICHAR(InData%Name(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - DO I = 1, LEN(InData%Units) - IntKiBuf(Int_Xferred) = ICHAR(InData%Units(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = InData%QType - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%OType - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NodeID - Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%ObjID - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE MD_PackOutParmType - - SUBROUTINE MD_UnPackOutParmType( 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(MD_OutParmType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackOutParmType' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - DO I = 1, LEN(OutData%Name) - OutData%Name(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - DO I = 1, LEN(OutData%Units) - OutData%Units(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%QType = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%OType = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NodeID = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%ObjID = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE MD_UnPackOutParmType - - SUBROUTINE MD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) - TYPE(MD_InitOutputType), INTENT(IN) :: SrcInitOutputData - TYPE(MD_InitOutputType), INTENT(INOUT) :: DstInitOutputData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_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) + DstLineData%r = SrcLineData%r +ENDIF +IF (ALLOCATED(SrcLineData%rd)) THEN + i1_l = LBOUND(SrcLineData%rd,1) + i1_u = UBOUND(SrcLineData%rd,1) + i2_l = LBOUND(SrcLineData%rd,2) + i2_u = UBOUND(SrcLineData%rd,2) + IF (.NOT. ALLOCATED(DstLineData%rd)) THEN + ALLOCATE(DstLineData%rd(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%writeOutputHdr.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%rd.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitOutputData%writeOutputHdr = SrcInitOutputData%writeOutputHdr + DstLineData%rd = SrcLineData%rd 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(SrcLineData%q)) THEN + i1_l = LBOUND(SrcLineData%q,1) + i1_u = UBOUND(SrcLineData%q,1) + i2_l = LBOUND(SrcLineData%q,2) + i2_u = UBOUND(SrcLineData%q,2) + IF (.NOT. ALLOCATED(DstLineData%q)) THEN + ALLOCATE(DstLineData%q(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%writeOutputUnt.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%q.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitOutputData%writeOutputUnt = SrcInitOutputData%writeOutputUnt + DstLineData%q = SrcLineData%q 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%CableCChanRqst)) THEN - i1_l = LBOUND(SrcInitOutputData%CableCChanRqst,1) - i1_u = UBOUND(SrcInitOutputData%CableCChanRqst,1) - IF (.NOT. ALLOCATED(DstInitOutputData%CableCChanRqst)) THEN - ALLOCATE(DstInitOutputData%CableCChanRqst(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcLineData%qs)) THEN + i1_l = LBOUND(SrcLineData%qs,1) + i1_u = UBOUND(SrcLineData%qs,1) + i2_l = LBOUND(SrcLineData%qs,2) + i2_u = UBOUND(SrcLineData%qs,2) + IF (.NOT. ALLOCATED(DstLineData%qs)) THEN + ALLOCATE(DstLineData%qs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%CableCChanRqst.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%qs.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInitOutputData%CableCChanRqst = SrcInitOutputData%CableCChanRqst + DstLineData%qs = SrcLineData%qs ENDIF - END SUBROUTINE MD_CopyInitOutput - - SUBROUTINE MD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) - TYPE(MD_InitOutputType), INTENT(INOUT) :: InitOutputData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyInitOutput' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(InitOutputData%writeOutputHdr)) THEN - DEALLOCATE(InitOutputData%writeOutputHdr) +IF (ALLOCATED(SrcLineData%l)) THEN + i1_l = LBOUND(SrcLineData%l,1) + i1_u = UBOUND(SrcLineData%l,1) + IF (.NOT. ALLOCATED(DstLineData%l)) THEN + ALLOCATE(DstLineData%l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstLineData%l = SrcLineData%l ENDIF -IF (ALLOCATED(InitOutputData%writeOutputUnt)) THEN - DEALLOCATE(InitOutputData%writeOutputUnt) +IF (ALLOCATED(SrcLineData%ld)) THEN + i1_l = LBOUND(SrcLineData%ld,1) + i1_u = UBOUND(SrcLineData%ld,1) + IF (.NOT. ALLOCATED(DstLineData%ld)) THEN + ALLOCATE(DstLineData%ld(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%ld.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstLineData%ld = SrcLineData%ld ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) -IF (ALLOCATED(InitOutputData%CableCChanRqst)) THEN - DEALLOCATE(InitOutputData%CableCChanRqst) +IF (ALLOCATED(SrcLineData%lstr)) THEN + i1_l = LBOUND(SrcLineData%lstr,1) + i1_u = UBOUND(SrcLineData%lstr,1) + IF (.NOT. ALLOCATED(DstLineData%lstr)) THEN + ALLOCATE(DstLineData%lstr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%lstr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstLineData%lstr = SrcLineData%lstr ENDIF - END SUBROUTINE MD_DestroyInitOutput - - SUBROUTINE MD_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(MD_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 = 'MD_PackInitOutput' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! writeOutputHdr allocated yes/no - IF ( ALLOCATED(InData%writeOutputHdr) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! writeOutputHdr upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%writeOutputHdr)*LEN(InData%writeOutputHdr) ! writeOutputHdr - END IF - Int_BufSz = Int_BufSz + 1 ! writeOutputUnt allocated yes/no - IF ( ALLOCATED(InData%writeOutputUnt) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! writeOutputUnt upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%writeOutputUnt)*LEN(InData%writeOutputUnt) ! writeOutputUnt - END IF - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype - CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Ver - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Ver - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Ver - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - Int_BufSz = Int_BufSz + 1 ! CableCChanRqst allocated yes/no - IF ( ALLOCATED(InData%CableCChanRqst) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! CableCChanRqst upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%CableCChanRqst) ! CableCChanRqst +IF (ALLOCATED(SrcLineData%lstrd)) THEN + i1_l = LBOUND(SrcLineData%lstrd,1) + i1_u = UBOUND(SrcLineData%lstrd,1) + IF (.NOT. ALLOCATED(DstLineData%lstrd)) THEN + ALLOCATE(DstLineData%lstrd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%lstrd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF 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 + DstLineData%lstrd = SrcLineData%lstrd +ENDIF +IF (ALLOCATED(SrcLineData%Kurv)) THEN + i1_l = LBOUND(SrcLineData%Kurv,1) + i1_u = UBOUND(SrcLineData%Kurv,1) + IF (.NOT. ALLOCATED(DstLineData%Kurv)) THEN + ALLOCATE(DstLineData%Kurv(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Kurv.', 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 + DstLineData%Kurv = SrcLineData%Kurv +ENDIF +IF (ALLOCATED(SrcLineData%dl_1)) THEN + i1_l = LBOUND(SrcLineData%dl_1,1) + i1_u = UBOUND(SrcLineData%dl_1,1) + IF (.NOT. ALLOCATED(DstLineData%dl_1)) THEN + ALLOCATE(DstLineData%dl_1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%dl_1.', 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 + DstLineData%dl_1 = SrcLineData%dl_1 +ENDIF +IF (ALLOCATED(SrcLineData%V)) THEN + i1_l = LBOUND(SrcLineData%V,1) + i1_u = UBOUND(SrcLineData%V,1) + IF (.NOT. ALLOCATED(DstLineData%V)) THEN + ALLOCATE(DstLineData%V(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%V.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IF ( .NOT. ALLOCATED(InData%writeOutputHdr) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%writeOutputHdr,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%writeOutputHdr,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%writeOutputHdr,1), UBOUND(InData%writeOutputHdr,1) - DO I = 1, LEN(InData%writeOutputHdr) - IntKiBuf(Int_Xferred) = ICHAR(InData%writeOutputHdr(i1)(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO + DstLineData%V = SrcLineData%V +ENDIF +IF (ALLOCATED(SrcLineData%U)) THEN + i1_l = LBOUND(SrcLineData%U,1) + i1_u = UBOUND(SrcLineData%U,1) + i2_l = LBOUND(SrcLineData%U,2) + i2_u = UBOUND(SrcLineData%U,2) + IF (.NOT. ALLOCATED(DstLineData%U)) THEN + ALLOCATE(DstLineData%U(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%U.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF 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 + DstLineData%U = SrcLineData%U +ENDIF +IF (ALLOCATED(SrcLineData%Ud)) THEN + i1_l = LBOUND(SrcLineData%Ud,1) + i1_u = UBOUND(SrcLineData%Ud,1) + i2_l = LBOUND(SrcLineData%Ud,2) + i2_u = UBOUND(SrcLineData%Ud,2) + IF (.NOT. ALLOCATED(DstLineData%Ud)) THEN + ALLOCATE(DstLineData%Ud(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Ud.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF 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%CableCChanRqst) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%CableCChanRqst,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CableCChanRqst,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%CableCChanRqst,1), UBOUND(InData%CableCChanRqst,1) - IntKiBuf(Int_Xferred) = TRANSFER(InData%CableCChanRqst(i1), IntKiBuf(1)) - Int_Xferred = Int_Xferred + 1 - END DO + DstLineData%Ud = SrcLineData%Ud +ENDIF +IF (ALLOCATED(SrcLineData%zeta)) THEN + i1_l = LBOUND(SrcLineData%zeta,1) + i1_u = UBOUND(SrcLineData%zeta,1) + IF (.NOT. ALLOCATED(DstLineData%zeta)) THEN + ALLOCATE(DstLineData%zeta(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%zeta.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF END IF - END SUBROUTINE MD_PackInitOutput - - SUBROUTINE MD_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(MD_InitOutputType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackInitOutput' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! writeOutputHdr not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%writeOutputHdr)) DEALLOCATE(OutData%writeOutputHdr) - ALLOCATE(OutData%writeOutputHdr(i1_l:i1_u),STAT=ErrStat2) + DstLineData%zeta = SrcLineData%zeta +ENDIF +IF (ALLOCATED(SrcLineData%PDyn)) THEN + i1_l = LBOUND(SrcLineData%PDyn,1) + i1_u = UBOUND(SrcLineData%PDyn,1) + IF (.NOT. ALLOCATED(DstLineData%PDyn)) THEN + ALLOCATE(DstLineData%PDyn(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%writeOutputHdr.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%PDyn.', 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) + DstLineData%PDyn = SrcLineData%PDyn +ENDIF +IF (ALLOCATED(SrcLineData%T)) THEN + i1_l = LBOUND(SrcLineData%T,1) + i1_u = UBOUND(SrcLineData%T,1) + i2_l = LBOUND(SrcLineData%T,2) + i2_u = UBOUND(SrcLineData%T,2) + IF (.NOT. ALLOCATED(DstLineData%T)) THEN + ALLOCATE(DstLineData%T(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%writeOutputUnt.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%T.', ErrStat, ErrMsg,RoutineName) + RETURN END IF - DO i1 = LBOUND(OutData%writeOutputUnt,1), UBOUND(OutData%writeOutputUnt,1) - DO I = 1, LEN(OutData%writeOutputUnt) - OutData%writeOutputUnt(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - END DO END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CableCChanRqst not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%CableCChanRqst)) DEALLOCATE(OutData%CableCChanRqst) - ALLOCATE(OutData%CableCChanRqst(i1_l:i1_u),STAT=ErrStat2) + DstLineData%T = SrcLineData%T +ENDIF +IF (ALLOCATED(SrcLineData%Td)) THEN + i1_l = LBOUND(SrcLineData%Td,1) + i1_u = UBOUND(SrcLineData%Td,1) + i2_l = LBOUND(SrcLineData%Td,2) + i2_u = UBOUND(SrcLineData%Td,2) + IF (.NOT. ALLOCATED(DstLineData%Td)) THEN + ALLOCATE(DstLineData%Td(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CableCChanRqst.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Td.', ErrStat, ErrMsg,RoutineName) + RETURN END IF - DO i1 = LBOUND(OutData%CableCChanRqst,1), UBOUND(OutData%CableCChanRqst,1) - OutData%CableCChanRqst(i1) = TRANSFER(IntKiBuf(Int_Xferred), OutData%CableCChanRqst(i1)) - Int_Xferred = Int_Xferred + 1 - END DO END IF - END SUBROUTINE MD_UnPackInitOutput - - SUBROUTINE MD_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(MD_ContinuousStateType), INTENT(IN) :: SrcContStateData - TYPE(MD_ContinuousStateType), INTENT(INOUT) :: DstContStateData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyContState' -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(SrcContStateData%states)) THEN - i1_l = LBOUND(SrcContStateData%states,1) - i1_u = UBOUND(SrcContStateData%states,1) - IF (.NOT. ALLOCATED(DstContStateData%states)) THEN - ALLOCATE(DstContStateData%states(i1_l:i1_u),STAT=ErrStat2) + DstLineData%Td = SrcLineData%Td +ENDIF +IF (ALLOCATED(SrcLineData%W)) THEN + i1_l = LBOUND(SrcLineData%W,1) + i1_u = UBOUND(SrcLineData%W,1) + i2_l = LBOUND(SrcLineData%W,2) + i2_u = UBOUND(SrcLineData%W,2) + IF (.NOT. ALLOCATED(DstLineData%W)) THEN + ALLOCATE(DstLineData%W(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstContStateData%states.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%W.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstContStateData%states = SrcContStateData%states -ENDIF - END SUBROUTINE MD_CopyContState - - SUBROUTINE MD_DestroyContState( ContStateData, ErrStat, ErrMsg ) - TYPE(MD_ContinuousStateType), INTENT(INOUT) :: ContStateData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyContState' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(ContStateData%states)) THEN - DEALLOCATE(ContStateData%states) + DstLineData%W = SrcLineData%W ENDIF - END SUBROUTINE MD_DestroyContState - - SUBROUTINE MD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(MD_ContinuousStateType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_PackContState' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - 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 - Db_BufSz = Db_BufSz + SIZE(InData%states) ! states +IF (ALLOCATED(SrcLineData%Dp)) THEN + i1_l = LBOUND(SrcLineData%Dp,1) + i1_u = UBOUND(SrcLineData%Dp,1) + i2_l = LBOUND(SrcLineData%Dp,2) + i2_u = UBOUND(SrcLineData%Dp,2) + IF (.NOT. ALLOCATED(DstLineData%Dp)) THEN + ALLOCATE(DstLineData%Dp(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Dp.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF 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 + DstLineData%Dp = SrcLineData%Dp +ENDIF +IF (ALLOCATED(SrcLineData%Dq)) THEN + i1_l = LBOUND(SrcLineData%Dq,1) + i1_u = UBOUND(SrcLineData%Dq,1) + i2_l = LBOUND(SrcLineData%Dq,2) + i2_u = UBOUND(SrcLineData%Dq,2) + IF (.NOT. ALLOCATED(DstLineData%Dq)) THEN + ALLOCATE(DstLineData%Dq(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Dq.', 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 + DstLineData%Dq = SrcLineData%Dq +ENDIF +IF (ALLOCATED(SrcLineData%Ap)) THEN + i1_l = LBOUND(SrcLineData%Ap,1) + i1_u = UBOUND(SrcLineData%Ap,1) + i2_l = LBOUND(SrcLineData%Ap,2) + i2_u = UBOUND(SrcLineData%Ap,2) + IF (.NOT. ALLOCATED(DstLineData%Ap)) THEN + ALLOCATE(DstLineData%Ap(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Ap.', 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 + DstLineData%Ap = SrcLineData%Ap +ENDIF +IF (ALLOCATED(SrcLineData%Aq)) THEN + i1_l = LBOUND(SrcLineData%Aq,1) + i1_u = UBOUND(SrcLineData%Aq,1) + i2_l = LBOUND(SrcLineData%Aq,2) + i2_u = UBOUND(SrcLineData%Aq,2) + IF (.NOT. ALLOCATED(DstLineData%Aq)) THEN + ALLOCATE(DstLineData%Aq(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Aq.', 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%states) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%states,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%states,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%states,1), UBOUND(InData%states,1) - DbKiBuf(Db_Xferred) = InData%states(i1) - Db_Xferred = Db_Xferred + 1 - END DO + DstLineData%Aq = SrcLineData%Aq +ENDIF +IF (ALLOCATED(SrcLineData%B)) THEN + i1_l = LBOUND(SrcLineData%B,1) + i1_u = UBOUND(SrcLineData%B,1) + i2_l = LBOUND(SrcLineData%B,2) + i2_u = UBOUND(SrcLineData%B,2) + IF (.NOT. ALLOCATED(DstLineData%B)) THEN + ALLOCATE(DstLineData%B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF END IF - END SUBROUTINE MD_PackContState - - SUBROUTINE MD_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(MD_ContinuousStateType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackContState' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! states not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%states)) DEALLOCATE(OutData%states) - ALLOCATE(OutData%states(i1_l:i1_u),STAT=ErrStat2) + DstLineData%B = SrcLineData%B +ENDIF +IF (ALLOCATED(SrcLineData%Bs)) THEN + i1_l = LBOUND(SrcLineData%Bs,1) + i1_u = UBOUND(SrcLineData%Bs,1) + i2_l = LBOUND(SrcLineData%Bs,2) + i2_u = UBOUND(SrcLineData%Bs,2) + IF (.NOT. ALLOCATED(DstLineData%Bs)) THEN + ALLOCATE(DstLineData%Bs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%states.', ErrStat, ErrMsg,RoutineName) - RETURN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Bs.', ErrStat, ErrMsg,RoutineName) + RETURN END IF - DO i1 = LBOUND(OutData%states,1), UBOUND(OutData%states,1) - OutData%states(i1) = DbKiBuf(Db_Xferred) - Db_Xferred = Db_Xferred + 1 - END DO END IF - END SUBROUTINE MD_UnPackContState - - SUBROUTINE MD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(MD_DiscreteStateType), INTENT(IN) :: SrcDiscStateData - TYPE(MD_DiscreteStateType), INTENT(INOUT) :: DstDiscStateData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyDiscState' -! - ErrStat = ErrID_None - ErrMsg = "" - DstDiscStateData%dummy = SrcDiscStateData%dummy - END SUBROUTINE MD_CopyDiscState + DstLineData%Bs = SrcLineData%Bs +ENDIF +IF (ALLOCATED(SrcLineData%Fnet)) THEN + i1_l = LBOUND(SrcLineData%Fnet,1) + i1_u = UBOUND(SrcLineData%Fnet,1) + i2_l = LBOUND(SrcLineData%Fnet,2) + i2_u = UBOUND(SrcLineData%Fnet,2) + IF (.NOT. ALLOCATED(DstLineData%Fnet)) THEN + ALLOCATE(DstLineData%Fnet(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%Fnet.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstLineData%Fnet = SrcLineData%Fnet +ENDIF +IF (ALLOCATED(SrcLineData%S)) THEN + i1_l = LBOUND(SrcLineData%S,1) + i1_u = UBOUND(SrcLineData%S,1) + i2_l = LBOUND(SrcLineData%S,2) + i2_u = UBOUND(SrcLineData%S,2) + i3_l = LBOUND(SrcLineData%S,3) + i3_u = UBOUND(SrcLineData%S,3) + IF (.NOT. ALLOCATED(DstLineData%S)) THEN + ALLOCATE(DstLineData%S(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%S.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstLineData%S = SrcLineData%S +ENDIF +IF (ALLOCATED(SrcLineData%M)) THEN + i1_l = LBOUND(SrcLineData%M,1) + i1_u = UBOUND(SrcLineData%M,1) + i2_l = LBOUND(SrcLineData%M,2) + i2_u = UBOUND(SrcLineData%M,2) + i3_l = LBOUND(SrcLineData%M,3) + i3_u = UBOUND(SrcLineData%M,3) + IF (.NOT. ALLOCATED(DstLineData%M)) THEN + ALLOCATE(DstLineData%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 DstLineData%M.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstLineData%M = SrcLineData%M +ENDIF + DstLineData%EndMomentA = SrcLineData%EndMomentA + DstLineData%EndMomentB = SrcLineData%EndMomentB + DstLineData%LineUnOut = SrcLineData%LineUnOut +IF (ALLOCATED(SrcLineData%LineWrOutput)) THEN + i1_l = LBOUND(SrcLineData%LineWrOutput,1) + i1_u = UBOUND(SrcLineData%LineWrOutput,1) + IF (.NOT. ALLOCATED(DstLineData%LineWrOutput)) THEN + ALLOCATE(DstLineData%LineWrOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstLineData%LineWrOutput.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstLineData%LineWrOutput = SrcLineData%LineWrOutput +ENDIF + END SUBROUTINE MD_CopyLine - SUBROUTINE MD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) - TYPE(MD_DiscreteStateType), INTENT(INOUT) :: DiscStateData + SUBROUTINE MD_DestroyLine( LineData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_Line), INTENT(INOUT) :: LineData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyLine' + ErrStat = ErrID_None ErrMsg = "" - END SUBROUTINE MD_DestroyDiscState - SUBROUTINE MD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(LineData%r)) THEN + DEALLOCATE(LineData%r) +ENDIF +IF (ALLOCATED(LineData%rd)) THEN + DEALLOCATE(LineData%rd) +ENDIF +IF (ALLOCATED(LineData%q)) THEN + DEALLOCATE(LineData%q) +ENDIF +IF (ALLOCATED(LineData%qs)) THEN + DEALLOCATE(LineData%qs) +ENDIF +IF (ALLOCATED(LineData%l)) THEN + DEALLOCATE(LineData%l) +ENDIF +IF (ALLOCATED(LineData%ld)) THEN + DEALLOCATE(LineData%ld) +ENDIF +IF (ALLOCATED(LineData%lstr)) THEN + DEALLOCATE(LineData%lstr) +ENDIF +IF (ALLOCATED(LineData%lstrd)) THEN + DEALLOCATE(LineData%lstrd) +ENDIF +IF (ALLOCATED(LineData%Kurv)) THEN + DEALLOCATE(LineData%Kurv) +ENDIF +IF (ALLOCATED(LineData%dl_1)) THEN + DEALLOCATE(LineData%dl_1) +ENDIF +IF (ALLOCATED(LineData%V)) THEN + DEALLOCATE(LineData%V) +ENDIF +IF (ALLOCATED(LineData%U)) THEN + DEALLOCATE(LineData%U) +ENDIF +IF (ALLOCATED(LineData%Ud)) THEN + DEALLOCATE(LineData%Ud) +ENDIF +IF (ALLOCATED(LineData%zeta)) THEN + DEALLOCATE(LineData%zeta) +ENDIF +IF (ALLOCATED(LineData%PDyn)) THEN + DEALLOCATE(LineData%PDyn) +ENDIF +IF (ALLOCATED(LineData%T)) THEN + DEALLOCATE(LineData%T) +ENDIF +IF (ALLOCATED(LineData%Td)) THEN + DEALLOCATE(LineData%Td) +ENDIF +IF (ALLOCATED(LineData%W)) THEN + DEALLOCATE(LineData%W) +ENDIF +IF (ALLOCATED(LineData%Dp)) THEN + DEALLOCATE(LineData%Dp) +ENDIF +IF (ALLOCATED(LineData%Dq)) THEN + DEALLOCATE(LineData%Dq) +ENDIF +IF (ALLOCATED(LineData%Ap)) THEN + DEALLOCATE(LineData%Ap) +ENDIF +IF (ALLOCATED(LineData%Aq)) THEN + DEALLOCATE(LineData%Aq) +ENDIF +IF (ALLOCATED(LineData%B)) THEN + DEALLOCATE(LineData%B) +ENDIF +IF (ALLOCATED(LineData%Bs)) THEN + DEALLOCATE(LineData%Bs) +ENDIF +IF (ALLOCATED(LineData%Fnet)) THEN + DEALLOCATE(LineData%Fnet) +ENDIF +IF (ALLOCATED(LineData%S)) THEN + DEALLOCATE(LineData%S) +ENDIF +IF (ALLOCATED(LineData%M)) THEN + DEALLOCATE(LineData%M) +ENDIF +IF (ALLOCATED(LineData%LineWrOutput)) THEN + DEALLOCATE(LineData%LineWrOutput) +ENDIF + END SUBROUTINE MD_DestroyLine + + SUBROUTINE MD_PackLine( 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(MD_DiscreteStateType), INTENT(IN) :: InData + TYPE(MD_Line), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -3250,7 +4995,7 @@ SUBROUTINE MD_PackDiscState( 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 = 'MD_PackDiscState' + CHARACTER(*), PARAMETER :: RoutineName = 'MD_PackLine' ! buffers to store subtypes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -3266,17 +5011,191 @@ SUBROUTINE MD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! dummy - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF + Int_BufSz = Int_BufSz + 1 ! IdNum + Int_BufSz = Int_BufSz + 1 ! PropsIdNum + Int_BufSz = Int_BufSz + 1 ! ElasticMod + Int_BufSz = Int_BufSz + SIZE(InData%OutFlagList) ! OutFlagList + Int_BufSz = Int_BufSz + 1 ! CtrlChan + Int_BufSz = Int_BufSz + 1 ! FairConnect + Int_BufSz = Int_BufSz + 1 ! AnchConnect + Int_BufSz = Int_BufSz + 1 ! N + Int_BufSz = Int_BufSz + 1 ! endTypeA + Int_BufSz = Int_BufSz + 1 ! endTypeB + Db_BufSz = Db_BufSz + 1 ! UnstrLen + Db_BufSz = Db_BufSz + 1 ! rho + Db_BufSz = Db_BufSz + 1 ! d + Db_BufSz = Db_BufSz + 1 ! EA + Db_BufSz = Db_BufSz + 1 ! EA_D + Db_BufSz = Db_BufSz + 1 ! BA + Db_BufSz = Db_BufSz + 1 ! BA_D + Db_BufSz = Db_BufSz + 1 ! EI + Db_BufSz = Db_BufSz + 1 ! Can + Db_BufSz = Db_BufSz + 1 ! Cat + Db_BufSz = Db_BufSz + 1 ! Cdn + Db_BufSz = Db_BufSz + 1 ! Cdt + Int_BufSz = Int_BufSz + 1 ! nEApoints + Db_BufSz = Db_BufSz + SIZE(InData%stiffXs) ! stiffXs + Db_BufSz = Db_BufSz + SIZE(InData%stiffYs) ! stiffYs + Int_BufSz = Int_BufSz + 1 ! nBApoints + Db_BufSz = Db_BufSz + SIZE(InData%dampXs) ! dampXs + Db_BufSz = Db_BufSz + SIZE(InData%dampYs) ! dampYs + Int_BufSz = Int_BufSz + 1 ! nEIpoints + Db_BufSz = Db_BufSz + SIZE(InData%bstiffXs) ! bstiffXs + Db_BufSz = Db_BufSz + SIZE(InData%bstiffYs) ! bstiffYs + Db_BufSz = Db_BufSz + 1 ! time + 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 + Db_BufSz = Db_BufSz + SIZE(InData%r) ! r END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN + 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 + 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 + Db_BufSz = Db_BufSz + SIZE(InData%q) ! q + END IF + Int_BufSz = Int_BufSz + 1 ! qs allocated yes/no + IF ( ALLOCATED(InData%qs) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! qs upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%qs) ! qs + 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 + 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 + 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 + 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 + Db_BufSz = Db_BufSz + SIZE(InData%lstrd) ! lstrd + END IF + Int_BufSz = Int_BufSz + 1 ! Kurv allocated yes/no + IF ( ALLOCATED(InData%Kurv) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Kurv upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%Kurv) ! Kurv + END IF + Int_BufSz = Int_BufSz + 1 ! dl_1 allocated yes/no + IF ( ALLOCATED(InData%dl_1) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! dl_1 upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%dl_1) ! dl_1 + 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 + Db_BufSz = Db_BufSz + SIZE(InData%V) ! V + END IF + Int_BufSz = Int_BufSz + 1 ! U allocated yes/no + IF ( ALLOCATED(InData%U) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! U upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%U) ! U + END IF + Int_BufSz = Int_BufSz + 1 ! Ud allocated yes/no + IF ( ALLOCATED(InData%Ud) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Ud upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%Ud) ! Ud + END IF + Int_BufSz = Int_BufSz + 1 ! zeta allocated yes/no + IF ( ALLOCATED(InData%zeta) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! zeta upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%zeta) ! zeta + END IF + Int_BufSz = Int_BufSz + 1 ! PDyn allocated yes/no + IF ( ALLOCATED(InData%PDyn) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! PDyn upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%PDyn) ! PDyn + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + Db_BufSz = Db_BufSz + SIZE(InData%B) ! B + END IF + Int_BufSz = Int_BufSz + 1 ! Bs allocated yes/no + IF ( ALLOCATED(InData%Bs) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Bs upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%Bs) ! Bs + END IF + Int_BufSz = Int_BufSz + 1 ! Fnet allocated yes/no + IF ( ALLOCATED(InData%Fnet) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! Fnet upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%Fnet) ! Fnet + 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 + 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 + Db_BufSz = Db_BufSz + SIZE(InData%M) ! M + END IF + Db_BufSz = Db_BufSz + SIZE(InData%EndMomentA) ! EndMomentA + Db_BufSz = Db_BufSz + SIZE(InData%EndMomentB) ! EndMomentB + Int_BufSz = Int_BufSz + 1 ! LineUnOut + Int_BufSz = Int_BufSz + 1 ! LineWrOutput allocated yes/no + IF ( ALLOCATED(InData%LineWrOutput) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LineWrOutput upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%LineWrOutput) ! LineWrOutput + 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 @@ -3294,449 +5213,6094 @@ SUBROUTINE MD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Db_Xferred = 1 Int_Xferred = 1 - ReKiBuf(Re_Xferred) = InData%dummy - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE MD_PackDiscState - - SUBROUTINE MD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(MD_DiscreteStateType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackDiscState' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%dummy = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE MD_UnPackDiscState - - SUBROUTINE MD_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(MD_ConstraintStateType), INTENT(IN) :: SrcConstrStateData - TYPE(MD_ConstraintStateType), INTENT(INOUT) :: DstConstrStateData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyConstrState' -! - ErrStat = ErrID_None - ErrMsg = "" - DstConstrStateData%dummy = SrcConstrStateData%dummy - END SUBROUTINE MD_CopyConstrState + IntKiBuf(Int_Xferred) = InData%IdNum + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%PropsIdNum + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%ElasticMod + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%OutFlagList,1), UBOUND(InData%OutFlagList,1) + IntKiBuf(Int_Xferred) = InData%OutFlagList(i1) + Int_Xferred = Int_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%CtrlChan + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%FairConnect + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%AnchConnect + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%N + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%endTypeA + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%endTypeB + Int_Xferred = Int_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%UnstrLen + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%rho + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%d + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%EA + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%EA_D + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%BA + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%BA_D + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%EI + 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 + IntKiBuf(Int_Xferred) = InData%nEApoints + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%stiffXs,1), UBOUND(InData%stiffXs,1) + DbKiBuf(Db_Xferred) = InData%stiffXs(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%stiffYs,1), UBOUND(InData%stiffYs,1) + DbKiBuf(Db_Xferred) = InData%stiffYs(i1) + Db_Xferred = Db_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%nBApoints + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%dampXs,1), UBOUND(InData%dampXs,1) + DbKiBuf(Db_Xferred) = InData%dampXs(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%dampYs,1), UBOUND(InData%dampYs,1) + DbKiBuf(Db_Xferred) = InData%dampYs(i1) + Db_Xferred = Db_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%nEIpoints + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%bstiffXs,1), UBOUND(InData%bstiffXs,1) + DbKiBuf(Db_Xferred) = InData%bstiffXs(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%bstiffYs,1), UBOUND(InData%bstiffYs,1) + DbKiBuf(Db_Xferred) = InData%bstiffYs(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DbKiBuf(Db_Xferred) = InData%time + Db_Xferred = Db_Xferred + 1 + 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 + IntKiBuf( Int_Xferred ) = LBOUND(InData%r,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%r,2) + Int_Xferred = Int_Xferred + 2 - SUBROUTINE MD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) - TYPE(MD_ConstraintStateType), INTENT(INOUT) :: ConstrStateData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyConstrState' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE MD_DestroyConstrState + DO i2 = LBOUND(InData%r,2), UBOUND(InData%r,2) + DO i1 = LBOUND(InData%r,1), UBOUND(InData%r,1) + DbKiBuf(Db_Xferred) = InData%r(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%rd) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%rd,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%rd,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%rd,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%rd,2) + Int_Xferred = Int_Xferred + 2 - SUBROUTINE MD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + DO i2 = LBOUND(InData%rd,2), UBOUND(InData%rd,2) + DO i1 = LBOUND(InData%rd,1), UBOUND(InData%rd,1) + DbKiBuf(Db_Xferred) = InData%rd(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%q) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%q,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%q,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%q,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%q,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%q,2), UBOUND(InData%q,2) + DO i1 = LBOUND(InData%q,1), UBOUND(InData%q,1) + DbKiBuf(Db_Xferred) = InData%q(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%qs) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%qs,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%qs,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%qs,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%qs,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%qs,2), UBOUND(InData%qs,2) + DO i1 = LBOUND(InData%qs,1), UBOUND(InData%qs,1) + DbKiBuf(Db_Xferred) = InData%qs(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%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%l,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%l,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%l,1), UBOUND(InData%l,1) + DbKiBuf(Db_Xferred) = InData%l(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ld) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ld,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ld,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ld,1), UBOUND(InData%ld,1) + DbKiBuf(Db_Xferred) = InData%ld(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%lstr) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%lstr,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%lstr,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%lstr,1), UBOUND(InData%lstr,1) + DbKiBuf(Db_Xferred) = InData%lstr(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%lstrd) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%lstrd,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%lstrd,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%lstrd,1), UBOUND(InData%lstrd,1) + DbKiBuf(Db_Xferred) = InData%lstrd(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Kurv) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Kurv,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Kurv,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Kurv,1), UBOUND(InData%Kurv,1) + DbKiBuf(Db_Xferred) = InData%Kurv(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%dl_1) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dl_1,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dl_1,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%dl_1,1), UBOUND(InData%dl_1,1) + DbKiBuf(Db_Xferred) = InData%dl_1(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%V) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%V,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%V,1), UBOUND(InData%V,1) + DbKiBuf(Db_Xferred) = InData%V(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%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%U,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%U,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%U,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%U,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%U,2), UBOUND(InData%U,2) + DO i1 = LBOUND(InData%U,1), UBOUND(InData%U,1) + DbKiBuf(Db_Xferred) = InData%U(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Ud) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Ud,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ud,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Ud,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ud,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Ud,2), UBOUND(InData%Ud,2) + DO i1 = LBOUND(InData%Ud,1), UBOUND(InData%Ud,1) + DbKiBuf(Db_Xferred) = InData%Ud(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%zeta) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%zeta,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%zeta,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%zeta,1), UBOUND(InData%zeta,1) + DbKiBuf(Db_Xferred) = InData%zeta(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PDyn) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PDyn,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PDyn,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%PDyn,1), UBOUND(InData%PDyn,1) + DbKiBuf(Db_Xferred) = InData%PDyn(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%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,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%T,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%T,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%T,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%T,2), UBOUND(InData%T,2) + DO i1 = LBOUND(InData%T,1), UBOUND(InData%T,1) + DbKiBuf(Db_Xferred) = InData%T(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Td) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Td,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Td,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Td,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Td,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Td,2), UBOUND(InData%Td,2) + DO i1 = LBOUND(InData%Td,1), UBOUND(InData%Td,1) + DbKiBuf(Db_Xferred) = InData%Td(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%W) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%W,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%W,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%W,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%W,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%W,2), UBOUND(InData%W,2) + DO i1 = LBOUND(InData%W,1), UBOUND(InData%W,1) + DbKiBuf(Db_Xferred) = InData%W(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%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%Dp,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Dp,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Dp,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Dp,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Dp,2), UBOUND(InData%Dp,2) + DO i1 = LBOUND(InData%Dp,1), UBOUND(InData%Dp,1) + DbKiBuf(Db_Xferred) = InData%Dp(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + 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 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Dq,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Dq,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Dq,2), UBOUND(InData%Dq,2) + DO i1 = LBOUND(InData%Dq,1), UBOUND(InData%Dq,1) + DbKiBuf(Db_Xferred) = InData%Dq(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Ap) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Ap,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ap,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Ap,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Ap,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Ap,2), UBOUND(InData%Ap,2) + DO i1 = LBOUND(InData%Ap,1), UBOUND(InData%Ap,1) + DbKiBuf(Db_Xferred) = InData%Ap(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Aq) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Aq,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Aq,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Aq,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Aq,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Aq,2), UBOUND(InData%Aq,2) + DO i1 = LBOUND(InData%Aq,1), UBOUND(InData%Aq,1) + DbKiBuf(Db_Xferred) = InData%Aq(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%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%B,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%B,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%B,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%B,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%B,2), UBOUND(InData%B,2) + DO i1 = LBOUND(InData%B,1), UBOUND(InData%B,1) + DbKiBuf(Db_Xferred) = InData%B(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Bs) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Bs,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Bs,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Bs,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Bs,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Bs,2), UBOUND(InData%Bs,2) + DO i1 = LBOUND(InData%Bs,1), UBOUND(InData%Bs,1) + DbKiBuf(Db_Xferred) = InData%Bs(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Fnet) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Fnet,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Fnet,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Fnet,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Fnet,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%Fnet,2), UBOUND(InData%Fnet,2) + DO i1 = LBOUND(InData%Fnet,1), UBOUND(InData%Fnet,1) + DbKiBuf(Db_Xferred) = InData%Fnet(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%S) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%S,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%S,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%S,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%S,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%S,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%S,3) + Int_Xferred = Int_Xferred + 2 + + 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) + DbKiBuf(Db_Xferred) = InData%S(i1,i2,i3) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END IF + 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%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 + IntKiBuf( Int_Xferred ) = LBOUND(InData%M,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%M,3) + Int_Xferred = Int_Xferred + 2 + + 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) + DbKiBuf(Db_Xferred) = InData%M(i1,i2,i3) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END IF + DO i1 = LBOUND(InData%EndMomentA,1), UBOUND(InData%EndMomentA,1) + DbKiBuf(Db_Xferred) = InData%EndMomentA(i1) + Db_Xferred = Db_Xferred + 1 + END DO + DO i1 = LBOUND(InData%EndMomentB,1), UBOUND(InData%EndMomentB,1) + DbKiBuf(Db_Xferred) = InData%EndMomentB(i1) + Db_Xferred = Db_Xferred + 1 + END DO + IntKiBuf(Int_Xferred) = InData%LineUnOut + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%LineWrOutput) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LineWrOutput,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LineWrOutput,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LineWrOutput,1), UBOUND(InData%LineWrOutput,1) + DbKiBuf(Db_Xferred) = InData%LineWrOutput(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE MD_PackLine + + SUBROUTINE MD_UnPackLine( 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(MD_Line), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackLine' + ! 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%IdNum = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%PropsIdNum = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%ElasticMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%OutFlagList,1) + i1_u = UBOUND(OutData%OutFlagList,1) + DO i1 = LBOUND(OutData%OutFlagList,1), UBOUND(OutData%OutFlagList,1) + OutData%OutFlagList(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + OutData%CtrlChan = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%FairConnect = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%AnchConnect = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%N = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%endTypeA = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%endTypeB = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%UnstrLen = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%rho = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%d = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%EA = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%EA_D = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%BA = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%BA_D = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%EI = 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 + OutData%nEApoints = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%stiffXs,1) + i1_u = UBOUND(OutData%stiffXs,1) + DO i1 = LBOUND(OutData%stiffXs,1), UBOUND(OutData%stiffXs,1) + OutData%stiffXs(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%stiffYs,1) + i1_u = UBOUND(OutData%stiffYs,1) + DO i1 = LBOUND(OutData%stiffYs,1), UBOUND(OutData%stiffYs,1) + OutData%stiffYs(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + OutData%nBApoints = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%dampXs,1) + i1_u = UBOUND(OutData%dampXs,1) + DO i1 = LBOUND(OutData%dampXs,1), UBOUND(OutData%dampXs,1) + OutData%dampXs(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%dampYs,1) + i1_u = UBOUND(OutData%dampYs,1) + DO i1 = LBOUND(OutData%dampYs,1), UBOUND(OutData%dampYs,1) + OutData%dampYs(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + OutData%nEIpoints = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%bstiffXs,1) + i1_u = UBOUND(OutData%bstiffXs,1) + DO i1 = LBOUND(OutData%bstiffXs,1), UBOUND(OutData%bstiffXs,1) + OutData%bstiffXs(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%bstiffYs,1) + i1_u = UBOUND(OutData%bstiffYs,1) + DO i1 = LBOUND(OutData%bstiffYs,1), UBOUND(OutData%bstiffYs,1) + OutData%bstiffYs(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + OutData%time = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + 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 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%r)) DEALLOCATE(OutData%r) + ALLOCATE(OutData%r(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%r.', ErrStat, ErrMsg,RoutineName) + RETURN + 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! rd not allocated + Int_Xferred = Int_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%rd)) DEALLOCATE(OutData%rd) + ALLOCATE(OutData%rd(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%rd.', ErrStat, ErrMsg,RoutineName) + RETURN + 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! q not allocated + Int_Xferred = Int_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%q)) DEALLOCATE(OutData%q) + ALLOCATE(OutData%q(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%q.', ErrStat, ErrMsg,RoutineName) + RETURN + 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! qs not allocated + Int_Xferred = Int_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%qs)) DEALLOCATE(OutData%qs) + ALLOCATE(OutData%qs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%qs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%qs,2), UBOUND(OutData%qs,2) + DO i1 = LBOUND(OutData%qs,1), UBOUND(OutData%qs,1) + OutData%qs(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! 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%l)) DEALLOCATE(OutData%l) + ALLOCATE(OutData%l(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%l.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%l,1), UBOUND(OutData%l,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 + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ld)) DEALLOCATE(OutData%ld) + ALLOCATE(OutData%ld(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ld.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ld,1), UBOUND(OutData%ld,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 + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%lstr)) DEALLOCATE(OutData%lstr) + ALLOCATE(OutData%lstr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%lstr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%lstr,1), UBOUND(OutData%lstr,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 + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%lstrd)) DEALLOCATE(OutData%lstrd) + ALLOCATE(OutData%lstrd(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%lstrd.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%lstrd,1), UBOUND(OutData%lstrd,1) + OutData%lstrd(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Kurv not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Kurv)) DEALLOCATE(OutData%Kurv) + ALLOCATE(OutData%Kurv(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Kurv.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Kurv,1), UBOUND(OutData%Kurv,1) + OutData%Kurv(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dl_1 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%dl_1)) DEALLOCATE(OutData%dl_1) + ALLOCATE(OutData%dl_1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%dl_1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%dl_1,1), UBOUND(OutData%dl_1,1) + OutData%dl_1(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! V not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%V)) DEALLOCATE(OutData%V) + ALLOCATE(OutData%V(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%V.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%V,1), UBOUND(OutData%V,1) + OutData%V(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! 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 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%U)) DEALLOCATE(OutData%U) + ALLOCATE(OutData%U(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%U.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%U,2), UBOUND(OutData%U,2) + DO i1 = LBOUND(OutData%U,1), UBOUND(OutData%U,1) + OutData%U(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Ud not allocated + Int_Xferred = Int_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%Ud)) DEALLOCATE(OutData%Ud) + ALLOCATE(OutData%Ud(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Ud.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Ud,2), UBOUND(OutData%Ud,2) + DO i1 = LBOUND(OutData%Ud,1), UBOUND(OutData%Ud,1) + OutData%Ud(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! zeta not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%zeta)) DEALLOCATE(OutData%zeta) + ALLOCATE(OutData%zeta(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%zeta.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%zeta,1), UBOUND(OutData%zeta,1) + OutData%zeta(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PDyn not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%PDyn)) DEALLOCATE(OutData%PDyn) + ALLOCATE(OutData%PDyn(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PDyn.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%PDyn,1), UBOUND(OutData%PDyn,1) + OutData%PDyn(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! T not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%T)) DEALLOCATE(OutData%T) + ALLOCATE(OutData%T(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%T.', ErrStat, ErrMsg,RoutineName) + RETURN + 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Td not allocated + Int_Xferred = Int_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%Td)) DEALLOCATE(OutData%Td) + ALLOCATE(OutData%Td(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Td.', ErrStat, ErrMsg,RoutineName) + RETURN + 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! W not allocated + Int_Xferred = Int_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%W)) DEALLOCATE(OutData%W) + ALLOCATE(OutData%W(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%W.', ErrStat, ErrMsg,RoutineName) + RETURN + 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! 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 + IF (ALLOCATED(OutData%Dp)) DEALLOCATE(OutData%Dp) + ALLOCATE(OutData%Dp(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Dp.', ErrStat, ErrMsg,RoutineName) + RETURN + 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + 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 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Dq)) DEALLOCATE(OutData%Dq) + ALLOCATE(OutData%Dq(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Dq.', ErrStat, ErrMsg,RoutineName) + RETURN + 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Ap not allocated + Int_Xferred = Int_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%Ap)) DEALLOCATE(OutData%Ap) + ALLOCATE(OutData%Ap(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Ap.', ErrStat, ErrMsg,RoutineName) + RETURN + 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Aq not allocated + Int_Xferred = Int_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%Aq)) DEALLOCATE(OutData%Aq) + ALLOCATE(OutData%Aq(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Aq.', ErrStat, ErrMsg,RoutineName) + RETURN + 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! 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%B)) DEALLOCATE(OutData%B) + ALLOCATE(OutData%B(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%B.', ErrStat, ErrMsg,RoutineName) + RETURN + 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Bs not allocated + Int_Xferred = Int_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%Bs)) DEALLOCATE(OutData%Bs) + ALLOCATE(OutData%Bs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Bs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Bs,2), UBOUND(OutData%Bs,2) + DO i1 = LBOUND(OutData%Bs,1), UBOUND(OutData%Bs,1) + OutData%Bs(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Fnet not allocated + Int_Xferred = Int_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%Fnet)) DEALLOCATE(OutData%Fnet) + ALLOCATE(OutData%Fnet(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Fnet.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%Fnet,2), UBOUND(OutData%Fnet,2) + DO i1 = LBOUND(OutData%Fnet,1), UBOUND(OutData%Fnet,1) + OutData%Fnet(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! S not allocated + Int_Xferred = Int_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%S)) DEALLOCATE(OutData%S) + ALLOCATE(OutData%S(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%S.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! 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%M)) DEALLOCATE(OutData%M) + ALLOCATE(OutData%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%M.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + 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) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END DO + END IF + i1_l = LBOUND(OutData%EndMomentA,1) + i1_u = UBOUND(OutData%EndMomentA,1) + DO i1 = LBOUND(OutData%EndMomentA,1), UBOUND(OutData%EndMomentA,1) + OutData%EndMomentA(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + i1_l = LBOUND(OutData%EndMomentB,1) + i1_u = UBOUND(OutData%EndMomentB,1) + DO i1 = LBOUND(OutData%EndMomentB,1), UBOUND(OutData%EndMomentB,1) + OutData%EndMomentB(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + OutData%LineUnOut = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LineWrOutput not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LineWrOutput)) DEALLOCATE(OutData%LineWrOutput) + ALLOCATE(OutData%LineWrOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LineWrOutput.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LineWrOutput,1), UBOUND(OutData%LineWrOutput,1) + OutData%LineWrOutput(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE MD_UnPackLine + + SUBROUTINE MD_CopyFail( SrcFailData, DstFailData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_Fail), INTENT(IN) :: SrcFailData + TYPE(MD_Fail), INTENT(INOUT) :: DstFailData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyFail' +! + ErrStat = ErrID_None + ErrMsg = "" + DstFailData%IdNum = SrcFailData%IdNum + END SUBROUTINE MD_CopyFail + + SUBROUTINE MD_DestroyFail( FailData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_Fail), INTENT(INOUT) :: FailData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyFail' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE MD_DestroyFail + + SUBROUTINE MD_PackFail( 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(MD_Fail), 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 = 'MD_PackFail' + ! 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 ! IdNum + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IntKiBuf(Int_Xferred) = InData%IdNum + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE MD_PackFail + + SUBROUTINE MD_UnPackFail( 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(MD_Fail), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackFail' + ! 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%IdNum = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE MD_UnPackFail + + SUBROUTINE MD_CopyOutParmType( SrcOutParmTypeData, DstOutParmTypeData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_OutParmType), INTENT(IN) :: SrcOutParmTypeData + TYPE(MD_OutParmType), INTENT(INOUT) :: DstOutParmTypeData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyOutParmType' +! + ErrStat = ErrID_None + ErrMsg = "" + DstOutParmTypeData%Name = SrcOutParmTypeData%Name + DstOutParmTypeData%Units = SrcOutParmTypeData%Units + DstOutParmTypeData%QType = SrcOutParmTypeData%QType + DstOutParmTypeData%OType = SrcOutParmTypeData%OType + DstOutParmTypeData%NodeID = SrcOutParmTypeData%NodeID + DstOutParmTypeData%ObjID = SrcOutParmTypeData%ObjID + END SUBROUTINE MD_CopyOutParmType + + SUBROUTINE MD_DestroyOutParmType( OutParmTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_OutParmType), INTENT(INOUT) :: OutParmTypeData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyOutParmType' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE MD_DestroyOutParmType + + SUBROUTINE MD_PackOutParmType( 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(MD_OutParmType), 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 = 'MD_PackOutParmType' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1*LEN(InData%Name) ! Name + Int_BufSz = Int_BufSz + 1*LEN(InData%Units) ! Units + Int_BufSz = Int_BufSz + 1 ! QType + Int_BufSz = Int_BufSz + 1 ! OType + Int_BufSz = Int_BufSz + 1 ! NodeID + Int_BufSz = Int_BufSz + 1 ! ObjID + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + DO I = 1, LEN(InData%Name) + IntKiBuf(Int_Xferred) = ICHAR(InData%Name(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(InData%Units) + IntKiBuf(Int_Xferred) = ICHAR(InData%Units(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IntKiBuf(Int_Xferred) = InData%QType + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%OType + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NodeID + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%ObjID + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE MD_PackOutParmType + + SUBROUTINE MD_UnPackOutParmType( 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(MD_OutParmType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackOutParmType' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + DO I = 1, LEN(OutData%Name) + OutData%Name(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(OutData%Units) + OutData%Units(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%QType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%OType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NodeID = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%ObjID = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END SUBROUTINE MD_UnPackOutParmType + + SUBROUTINE MD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_InitOutputType), INTENT(IN) :: SrcInitOutputData + TYPE(MD_InitOutputType), INTENT(INOUT) :: DstInitOutputData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyInitOutput' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcInitOutputData%writeOutputHdr)) THEN + i1_l = LBOUND(SrcInitOutputData%writeOutputHdr,1) + i1_u = UBOUND(SrcInitOutputData%writeOutputHdr,1) + IF (.NOT. ALLOCATED(DstInitOutputData%writeOutputHdr)) THEN + ALLOCATE(DstInitOutputData%writeOutputHdr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%writeOutputHdr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%writeOutputHdr = SrcInitOutputData%writeOutputHdr +ENDIF +IF (ALLOCATED(SrcInitOutputData%writeOutputUnt)) THEN + i1_l = LBOUND(SrcInitOutputData%writeOutputUnt,1) + i1_u = UBOUND(SrcInitOutputData%writeOutputUnt,1) + IF (.NOT. ALLOCATED(DstInitOutputData%writeOutputUnt)) THEN + ALLOCATE(DstInitOutputData%writeOutputUnt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%writeOutputUnt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%writeOutputUnt = SrcInitOutputData%writeOutputUnt +ENDIF + CALL NWTC_Library_Copyprogdesc( SrcInitOutputData%Ver, DstInitOutputData%Ver, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcInitOutputData%CableCChanRqst)) THEN + i1_l = LBOUND(SrcInitOutputData%CableCChanRqst,1) + i1_u = UBOUND(SrcInitOutputData%CableCChanRqst,1) + IF (.NOT. ALLOCATED(DstInitOutputData%CableCChanRqst)) THEN + ALLOCATE(DstInitOutputData%CableCChanRqst(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%CableCChanRqst.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitOutputData%CableCChanRqst = SrcInitOutputData%CableCChanRqst +ENDIF +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 MD_CopyInitOutput + + SUBROUTINE MD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_InitOutputType), INTENT(INOUT) :: InitOutputData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyInitOutput' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(InitOutputData%writeOutputHdr)) THEN + DEALLOCATE(InitOutputData%writeOutputHdr) +ENDIF +IF (ALLOCATED(InitOutputData%writeOutputUnt)) THEN + DEALLOCATE(InitOutputData%writeOutputUnt) +ENDIF + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(InitOutputData%CableCChanRqst)) THEN + DEALLOCATE(InitOutputData%CableCChanRqst) +ENDIF +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 MD_DestroyInitOutput + + SUBROUTINE MD_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(MD_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 = 'MD_PackInitOutput' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! writeOutputHdr allocated yes/no + IF ( ALLOCATED(InData%writeOutputHdr) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! writeOutputHdr upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%writeOutputHdr)*LEN(InData%writeOutputHdr) ! writeOutputHdr + END IF + Int_BufSz = Int_BufSz + 1 ! writeOutputUnt allocated yes/no + IF ( ALLOCATED(InData%writeOutputUnt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! writeOutputUnt upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%writeOutputUnt)*LEN(InData%writeOutputUnt) ! writeOutputUnt + END IF + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + Int_BufSz = Int_BufSz + 3 ! Ver: size of buffers for each call to pack subtype + CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, .TRUE. ) ! Ver + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! Ver + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! Ver + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! Ver + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! CableCChanRqst allocated yes/no + IF ( ALLOCATED(InData%CableCChanRqst) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! CableCChanRqst upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%CableCChanRqst) ! CableCChanRqst + 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 + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IF ( .NOT. ALLOCATED(InData%writeOutputHdr) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%writeOutputHdr,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%writeOutputHdr,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%writeOutputHdr,1), UBOUND(InData%writeOutputHdr,1) + DO I = 1, LEN(InData%writeOutputHdr) + IntKiBuf(Int_Xferred) = ICHAR(InData%writeOutputHdr(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( .NOT. ALLOCATED(InData%writeOutputUnt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%writeOutputUnt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%writeOutputUnt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%writeOutputUnt,1), UBOUND(InData%writeOutputUnt,1) + DO I = 1, LEN(InData%writeOutputUnt) + IntKiBuf(Int_Xferred) = ICHAR(InData%writeOutputUnt(i1)(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + CALL NWTC_Library_Packprogdesc( Re_Buf, Db_Buf, Int_Buf, InData%Ver, ErrStat2, ErrMsg2, OnlySize ) ! Ver + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF ( .NOT. ALLOCATED(InData%CableCChanRqst) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CableCChanRqst,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CableCChanRqst,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%CableCChanRqst,1), UBOUND(InData%CableCChanRqst,1) + IntKiBuf(Int_Xferred) = TRANSFER(InData%CableCChanRqst(i1), IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + 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 MD_PackInitOutput + + SUBROUTINE MD_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(MD_InitOutputType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackInitOutput' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! writeOutputHdr not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%writeOutputHdr)) DEALLOCATE(OutData%writeOutputHdr) + ALLOCATE(OutData%writeOutputHdr(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%writeOutputHdr.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%writeOutputHdr,1), UBOUND(OutData%writeOutputHdr,1) + DO I = 1, LEN(OutData%writeOutputHdr) + OutData%writeOutputHdr(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! writeOutputUnt not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%writeOutputUnt)) DEALLOCATE(OutData%writeOutputUnt) + ALLOCATE(OutData%writeOutputUnt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%writeOutputUnt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%writeOutputUnt,1), UBOUND(OutData%writeOutputUnt,1) + DO I = 1, LEN(OutData%writeOutputUnt) + OutData%writeOutputUnt(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + END DO + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackprogdesc( Re_Buf, Db_Buf, Int_Buf, OutData%Ver, ErrStat2, ErrMsg2 ) ! Ver + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CableCChanRqst not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%CableCChanRqst)) DEALLOCATE(OutData%CableCChanRqst) + ALLOCATE(OutData%CableCChanRqst(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CableCChanRqst.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%CableCChanRqst,1), UBOUND(OutData%CableCChanRqst,1) + OutData%CableCChanRqst(i1) = TRANSFER(IntKiBuf(Int_Xferred), OutData%CableCChanRqst(i1)) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + 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 MD_UnPackInitOutput + + SUBROUTINE MD_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_ContinuousStateType), INTENT(IN) :: SrcContStateData + TYPE(MD_ContinuousStateType), INTENT(INOUT) :: DstContStateData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyContState' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcContStateData%states)) THEN + i1_l = LBOUND(SrcContStateData%states,1) + i1_u = UBOUND(SrcContStateData%states,1) + IF (.NOT. ALLOCATED(DstContStateData%states)) THEN + ALLOCATE(DstContStateData%states(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstContStateData%states.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstContStateData%states = SrcContStateData%states +ENDIF + END SUBROUTINE MD_CopyContState + + SUBROUTINE MD_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_ContinuousStateType), INTENT(INOUT) :: ContStateData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyContState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(ContStateData%states)) THEN + DEALLOCATE(ContStateData%states) +ENDIF + END SUBROUTINE MD_DestroyContState + + SUBROUTINE MD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(MD_ContinuousStateType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_PackContState' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + 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 + Db_BufSz = Db_BufSz + SIZE(InData%states) ! states + 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%states) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%states,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%states,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%states,1), UBOUND(InData%states,1) + DbKiBuf(Db_Xferred) = InData%states(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE MD_PackContState + + SUBROUTINE MD_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(MD_ContinuousStateType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackContState' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! states not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%states)) DEALLOCATE(OutData%states) + ALLOCATE(OutData%states(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%states.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%states,1), UBOUND(OutData%states,1) + OutData%states(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + END SUBROUTINE MD_UnPackContState + + SUBROUTINE MD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_DiscreteStateType), INTENT(IN) :: SrcDiscStateData + TYPE(MD_DiscreteStateType), INTENT(INOUT) :: DstDiscStateData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyDiscState' +! + ErrStat = ErrID_None + ErrMsg = "" + DstDiscStateData%dummy = SrcDiscStateData%dummy + END SUBROUTINE MD_CopyDiscState + + SUBROUTINE MD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_DiscreteStateType), INTENT(INOUT) :: DiscStateData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyDiscState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE MD_DestroyDiscState + + SUBROUTINE MD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(MD_DiscreteStateType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_PackDiscState' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! dummy + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%dummy + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE MD_PackDiscState + + SUBROUTINE MD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(MD_DiscreteStateType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackDiscState' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%dummy = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE MD_UnPackDiscState + + SUBROUTINE MD_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_ConstraintStateType), INTENT(IN) :: SrcConstrStateData + TYPE(MD_ConstraintStateType), INTENT(INOUT) :: DstConstrStateData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyConstrState' +! + ErrStat = ErrID_None + ErrMsg = "" + DstConstrStateData%dummy = SrcConstrStateData%dummy + END SUBROUTINE MD_CopyConstrState + + SUBROUTINE MD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_ConstraintStateType), INTENT(INOUT) :: ConstrStateData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyConstrState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE MD_DestroyConstrState + + SUBROUTINE MD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(MD_ConstraintStateType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_PackConstrState' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! dummy + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%dummy + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE MD_PackConstrState + + SUBROUTINE MD_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(MD_ConstraintStateType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackConstrState' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%dummy = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE MD_UnPackConstrState + + SUBROUTINE MD_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_OtherStateType), INTENT(IN) :: SrcOtherStateData + TYPE(MD_OtherStateType), INTENT(INOUT) :: DstOtherStateData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyOtherState' +! + ErrStat = ErrID_None + ErrMsg = "" + DstOtherStateData%dummy = SrcOtherStateData%dummy + END SUBROUTINE MD_CopyOtherState + + SUBROUTINE MD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_OtherStateType), INTENT(INOUT) :: OtherStateData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyOtherState' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + END SUBROUTINE MD_DestroyOtherState + + SUBROUTINE MD_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) + TYPE(MD_OtherStateType), INTENT(IN) :: InData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly + ! Local variables + INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_BufSz + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_BufSz + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_PackOtherState' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Re_BufSz = Re_BufSz + 1 ! dummy + IF ( Re_BufSz .GT. 0 ) THEN + ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Db_BufSz .GT. 0 ) THEN + ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + ReKiBuf(Re_Xferred) = InData%dummy + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE MD_PackOtherState + + SUBROUTINE MD_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(MD_OtherStateType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size + INTEGER(IntKi) :: Re_Xferred + INTEGER(IntKi) :: Db_Xferred + INTEGER(IntKi) :: Int_Xferred + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackOtherState' + ! buffers to store meshes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + OutData%dummy = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END SUBROUTINE MD_UnPackOtherState + + SUBROUTINE MD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_MiscVarType), INTENT(IN) :: SrcMiscData + TYPE(MD_MiscVarType), INTENT(INOUT) :: DstMiscData + INTEGER(IntKi), INTENT(IN ) :: CtrlCode + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg +! Local + INTEGER(IntKi) :: i,j,k + INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyMisc' +! + ErrStat = ErrID_None + ErrMsg = "" +IF (ALLOCATED(SrcMiscData%LineTypeList)) THEN + i1_l = LBOUND(SrcMiscData%LineTypeList,1) + i1_u = UBOUND(SrcMiscData%LineTypeList,1) + IF (.NOT. ALLOCATED(DstMiscData%LineTypeList)) THEN + ALLOCATE(DstMiscData%LineTypeList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%LineTypeList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%LineTypeList,1), UBOUND(SrcMiscData%LineTypeList,1) + CALL MD_Copylineprop( SrcMiscData%LineTypeList(i1), DstMiscData%LineTypeList(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcMiscData%RodTypeList)) THEN + i1_l = LBOUND(SrcMiscData%RodTypeList,1) + i1_u = UBOUND(SrcMiscData%RodTypeList,1) + IF (.NOT. ALLOCATED(DstMiscData%RodTypeList)) THEN + ALLOCATE(DstMiscData%RodTypeList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%RodTypeList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%RodTypeList,1), UBOUND(SrcMiscData%RodTypeList,1) + CALL MD_Copyrodprop( SrcMiscData%RodTypeList(i1), DstMiscData%RodTypeList(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL MD_Copybody( SrcMiscData%GroundBody, DstMiscData%GroundBody, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcMiscData%BodyList)) THEN + i1_l = LBOUND(SrcMiscData%BodyList,1) + i1_u = UBOUND(SrcMiscData%BodyList,1) + IF (.NOT. ALLOCATED(DstMiscData%BodyList)) THEN + ALLOCATE(DstMiscData%BodyList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%BodyList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%BodyList,1), UBOUND(SrcMiscData%BodyList,1) + CALL MD_Copybody( SrcMiscData%BodyList(i1), DstMiscData%BodyList(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcMiscData%RodList)) THEN + i1_l = LBOUND(SrcMiscData%RodList,1) + i1_u = UBOUND(SrcMiscData%RodList,1) + IF (.NOT. ALLOCATED(DstMiscData%RodList)) THEN + ALLOCATE(DstMiscData%RodList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%RodList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%RodList,1), UBOUND(SrcMiscData%RodList,1) + CALL MD_Copyrod( SrcMiscData%RodList(i1), DstMiscData%RodList(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcMiscData%ConnectList)) THEN + i1_l = LBOUND(SrcMiscData%ConnectList,1) + i1_u = UBOUND(SrcMiscData%ConnectList,1) + IF (.NOT. ALLOCATED(DstMiscData%ConnectList)) THEN + ALLOCATE(DstMiscData%ConnectList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%ConnectList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%ConnectList,1), UBOUND(SrcMiscData%ConnectList,1) + CALL MD_Copyconnect( SrcMiscData%ConnectList(i1), DstMiscData%ConnectList(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcMiscData%LineList)) THEN + i1_l = LBOUND(SrcMiscData%LineList,1) + i1_u = UBOUND(SrcMiscData%LineList,1) + IF (.NOT. ALLOCATED(DstMiscData%LineList)) THEN + ALLOCATE(DstMiscData%LineList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%LineList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%LineList,1), UBOUND(SrcMiscData%LineList,1) + CALL MD_Copyline( SrcMiscData%LineList(i1), DstMiscData%LineList(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcMiscData%FailList)) THEN + i1_l = LBOUND(SrcMiscData%FailList,1) + i1_u = UBOUND(SrcMiscData%FailList,1) + IF (.NOT. ALLOCATED(DstMiscData%FailList)) THEN + ALLOCATE(DstMiscData%FailList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%FailList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMiscData%FailList,1), UBOUND(SrcMiscData%FailList,1) + CALL MD_Copyfail( SrcMiscData%FailList(i1), DstMiscData%FailList(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF +IF (ALLOCATED(SrcMiscData%FreeConIs)) THEN + i1_l = LBOUND(SrcMiscData%FreeConIs,1) + i1_u = UBOUND(SrcMiscData%FreeConIs,1) + IF (.NOT. ALLOCATED(DstMiscData%FreeConIs)) THEN + ALLOCATE(DstMiscData%FreeConIs(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%FreeConIs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%FreeConIs = SrcMiscData%FreeConIs +ENDIF +IF (ALLOCATED(SrcMiscData%CpldConIs)) THEN + i1_l = LBOUND(SrcMiscData%CpldConIs,1) + i1_u = UBOUND(SrcMiscData%CpldConIs,1) + i2_l = LBOUND(SrcMiscData%CpldConIs,2) + i2_u = UBOUND(SrcMiscData%CpldConIs,2) + IF (.NOT. ALLOCATED(DstMiscData%CpldConIs)) THEN + ALLOCATE(DstMiscData%CpldConIs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%CpldConIs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%CpldConIs = SrcMiscData%CpldConIs +ENDIF +IF (ALLOCATED(SrcMiscData%FreeRodIs)) THEN + i1_l = LBOUND(SrcMiscData%FreeRodIs,1) + i1_u = UBOUND(SrcMiscData%FreeRodIs,1) + IF (.NOT. ALLOCATED(DstMiscData%FreeRodIs)) THEN + ALLOCATE(DstMiscData%FreeRodIs(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%FreeRodIs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%FreeRodIs = SrcMiscData%FreeRodIs +ENDIF +IF (ALLOCATED(SrcMiscData%CpldRodIs)) THEN + i1_l = LBOUND(SrcMiscData%CpldRodIs,1) + i1_u = UBOUND(SrcMiscData%CpldRodIs,1) + i2_l = LBOUND(SrcMiscData%CpldRodIs,2) + i2_u = UBOUND(SrcMiscData%CpldRodIs,2) + IF (.NOT. ALLOCATED(DstMiscData%CpldRodIs)) THEN + ALLOCATE(DstMiscData%CpldRodIs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%CpldRodIs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%CpldRodIs = SrcMiscData%CpldRodIs +ENDIF +IF (ALLOCATED(SrcMiscData%FreeBodyIs)) THEN + i1_l = LBOUND(SrcMiscData%FreeBodyIs,1) + i1_u = UBOUND(SrcMiscData%FreeBodyIs,1) + IF (.NOT. ALLOCATED(DstMiscData%FreeBodyIs)) THEN + ALLOCATE(DstMiscData%FreeBodyIs(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%FreeBodyIs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%FreeBodyIs = SrcMiscData%FreeBodyIs +ENDIF +IF (ALLOCATED(SrcMiscData%CpldBodyIs)) THEN + i1_l = LBOUND(SrcMiscData%CpldBodyIs,1) + i1_u = UBOUND(SrcMiscData%CpldBodyIs,1) + i2_l = LBOUND(SrcMiscData%CpldBodyIs,2) + i2_u = UBOUND(SrcMiscData%CpldBodyIs,2) + IF (.NOT. ALLOCATED(DstMiscData%CpldBodyIs)) THEN + ALLOCATE(DstMiscData%CpldBodyIs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%CpldBodyIs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%CpldBodyIs = SrcMiscData%CpldBodyIs +ENDIF +IF (ALLOCATED(SrcMiscData%LineStateIs1)) THEN + i1_l = LBOUND(SrcMiscData%LineStateIs1,1) + i1_u = UBOUND(SrcMiscData%LineStateIs1,1) + IF (.NOT. ALLOCATED(DstMiscData%LineStateIs1)) THEN + ALLOCATE(DstMiscData%LineStateIs1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%LineStateIs1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%LineStateIs1 = SrcMiscData%LineStateIs1 +ENDIF +IF (ALLOCATED(SrcMiscData%LineStateIsN)) THEN + i1_l = LBOUND(SrcMiscData%LineStateIsN,1) + i1_u = UBOUND(SrcMiscData%LineStateIsN,1) + IF (.NOT. ALLOCATED(DstMiscData%LineStateIsN)) THEN + ALLOCATE(DstMiscData%LineStateIsN(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%LineStateIsN.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%LineStateIsN = SrcMiscData%LineStateIsN +ENDIF +IF (ALLOCATED(SrcMiscData%ConStateIs1)) THEN + i1_l = LBOUND(SrcMiscData%ConStateIs1,1) + i1_u = UBOUND(SrcMiscData%ConStateIs1,1) + IF (.NOT. ALLOCATED(DstMiscData%ConStateIs1)) THEN + ALLOCATE(DstMiscData%ConStateIs1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%ConStateIs1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%ConStateIs1 = SrcMiscData%ConStateIs1 +ENDIF +IF (ALLOCATED(SrcMiscData%ConStateIsN)) THEN + i1_l = LBOUND(SrcMiscData%ConStateIsN,1) + i1_u = UBOUND(SrcMiscData%ConStateIsN,1) + IF (.NOT. ALLOCATED(DstMiscData%ConStateIsN)) THEN + ALLOCATE(DstMiscData%ConStateIsN(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%ConStateIsN.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%ConStateIsN = SrcMiscData%ConStateIsN +ENDIF +IF (ALLOCATED(SrcMiscData%RodStateIs1)) THEN + i1_l = LBOUND(SrcMiscData%RodStateIs1,1) + i1_u = UBOUND(SrcMiscData%RodStateIs1,1) + IF (.NOT. ALLOCATED(DstMiscData%RodStateIs1)) THEN + ALLOCATE(DstMiscData%RodStateIs1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%RodStateIs1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%RodStateIs1 = SrcMiscData%RodStateIs1 +ENDIF +IF (ALLOCATED(SrcMiscData%RodStateIsN)) THEN + i1_l = LBOUND(SrcMiscData%RodStateIsN,1) + i1_u = UBOUND(SrcMiscData%RodStateIsN,1) + IF (.NOT. ALLOCATED(DstMiscData%RodStateIsN)) THEN + ALLOCATE(DstMiscData%RodStateIsN(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%RodStateIsN.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%RodStateIsN = SrcMiscData%RodStateIsN +ENDIF +IF (ALLOCATED(SrcMiscData%BodyStateIs1)) THEN + i1_l = LBOUND(SrcMiscData%BodyStateIs1,1) + i1_u = UBOUND(SrcMiscData%BodyStateIs1,1) + IF (.NOT. ALLOCATED(DstMiscData%BodyStateIs1)) THEN + ALLOCATE(DstMiscData%BodyStateIs1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%BodyStateIs1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%BodyStateIs1 = SrcMiscData%BodyStateIs1 +ENDIF +IF (ALLOCATED(SrcMiscData%BodyStateIsN)) THEN + i1_l = LBOUND(SrcMiscData%BodyStateIsN,1) + i1_u = UBOUND(SrcMiscData%BodyStateIsN,1) + IF (.NOT. ALLOCATED(DstMiscData%BodyStateIsN)) THEN + ALLOCATE(DstMiscData%BodyStateIsN(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%BodyStateIsN.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%BodyStateIsN = SrcMiscData%BodyStateIsN +ENDIF + DstMiscData%Nx = SrcMiscData%Nx + DstMiscData%WaveTi = SrcMiscData%WaveTi + CALL MD_CopyContState( SrcMiscData%xTemp, DstMiscData%xTemp, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL MD_CopyContState( SrcMiscData%xdTemp, DstMiscData%xdTemp, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + DstMiscData%zeros6 = SrcMiscData%zeros6 +IF (ALLOCATED(SrcMiscData%MDWrOutput)) THEN + i1_l = LBOUND(SrcMiscData%MDWrOutput,1) + i1_u = UBOUND(SrcMiscData%MDWrOutput,1) + IF (.NOT. ALLOCATED(DstMiscData%MDWrOutput)) THEN + ALLOCATE(DstMiscData%MDWrOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%MDWrOutput.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%MDWrOutput = SrcMiscData%MDWrOutput +ENDIF + DstMiscData%LastOutTime = SrcMiscData%LastOutTime + DstMiscData%PtfmInit = SrcMiscData%PtfmInit +IF (ALLOCATED(SrcMiscData%BathymetryGrid)) THEN + i1_l = LBOUND(SrcMiscData%BathymetryGrid,1) + i1_u = UBOUND(SrcMiscData%BathymetryGrid,1) + i2_l = LBOUND(SrcMiscData%BathymetryGrid,2) + i2_u = UBOUND(SrcMiscData%BathymetryGrid,2) + IF (.NOT. ALLOCATED(DstMiscData%BathymetryGrid)) THEN + ALLOCATE(DstMiscData%BathymetryGrid(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%BathymetryGrid.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%BathymetryGrid = SrcMiscData%BathymetryGrid +ENDIF +IF (ALLOCATED(SrcMiscData%BathGrid_Xs)) THEN + i1_l = LBOUND(SrcMiscData%BathGrid_Xs,1) + i1_u = UBOUND(SrcMiscData%BathGrid_Xs,1) + IF (.NOT. ALLOCATED(DstMiscData%BathGrid_Xs)) THEN + ALLOCATE(DstMiscData%BathGrid_Xs(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%BathGrid_Xs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%BathGrid_Xs = SrcMiscData%BathGrid_Xs +ENDIF +IF (ALLOCATED(SrcMiscData%BathGrid_Ys)) THEN + i1_l = LBOUND(SrcMiscData%BathGrid_Ys,1) + i1_u = UBOUND(SrcMiscData%BathGrid_Ys,1) + IF (.NOT. ALLOCATED(DstMiscData%BathGrid_Ys)) THEN + ALLOCATE(DstMiscData%BathGrid_Ys(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%BathGrid_Ys.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%BathGrid_Ys = SrcMiscData%BathGrid_Ys +ENDIF +IF (ALLOCATED(SrcMiscData%BathGrid_npoints)) THEN + i1_l = LBOUND(SrcMiscData%BathGrid_npoints,1) + i1_u = UBOUND(SrcMiscData%BathGrid_npoints,1) + IF (.NOT. ALLOCATED(DstMiscData%BathGrid_npoints)) THEN + ALLOCATE(DstMiscData%BathGrid_npoints(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%BathGrid_npoints.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%BathGrid_npoints = SrcMiscData%BathGrid_npoints +ENDIF + END SUBROUTINE MD_CopyMisc + + SUBROUTINE MD_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_MiscVarType), INTENT(INOUT) :: MiscData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyMisc' + + ErrStat = ErrID_None + ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(MiscData%LineTypeList)) THEN +DO i1 = LBOUND(MiscData%LineTypeList,1), UBOUND(MiscData%LineTypeList,1) + CALL MD_Destroylineprop( MiscData%LineTypeList(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MiscData%LineTypeList) +ENDIF +IF (ALLOCATED(MiscData%RodTypeList)) THEN +DO i1 = LBOUND(MiscData%RodTypeList,1), UBOUND(MiscData%RodTypeList,1) + CALL MD_Destroyrodprop( MiscData%RodTypeList(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MiscData%RodTypeList) +ENDIF + CALL MD_Destroybody( MiscData%GroundBody, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(MiscData%BodyList)) THEN +DO i1 = LBOUND(MiscData%BodyList,1), UBOUND(MiscData%BodyList,1) + CALL MD_Destroybody( MiscData%BodyList(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MiscData%BodyList) +ENDIF +IF (ALLOCATED(MiscData%RodList)) THEN +DO i1 = LBOUND(MiscData%RodList,1), UBOUND(MiscData%RodList,1) + CALL MD_Destroyrod( MiscData%RodList(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MiscData%RodList) +ENDIF +IF (ALLOCATED(MiscData%ConnectList)) THEN +DO i1 = LBOUND(MiscData%ConnectList,1), UBOUND(MiscData%ConnectList,1) + CALL MD_Destroyconnect( MiscData%ConnectList(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MiscData%ConnectList) +ENDIF +IF (ALLOCATED(MiscData%LineList)) THEN +DO i1 = LBOUND(MiscData%LineList,1), UBOUND(MiscData%LineList,1) + CALL MD_Destroyline( MiscData%LineList(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MiscData%LineList) +ENDIF +IF (ALLOCATED(MiscData%FailList)) THEN +DO i1 = LBOUND(MiscData%FailList,1), UBOUND(MiscData%FailList,1) + CALL MD_Destroyfail( MiscData%FailList(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MiscData%FailList) +ENDIF +IF (ALLOCATED(MiscData%FreeConIs)) THEN + DEALLOCATE(MiscData%FreeConIs) +ENDIF +IF (ALLOCATED(MiscData%CpldConIs)) THEN + DEALLOCATE(MiscData%CpldConIs) +ENDIF +IF (ALLOCATED(MiscData%FreeRodIs)) THEN + DEALLOCATE(MiscData%FreeRodIs) +ENDIF +IF (ALLOCATED(MiscData%CpldRodIs)) THEN + DEALLOCATE(MiscData%CpldRodIs) +ENDIF +IF (ALLOCATED(MiscData%FreeBodyIs)) THEN + DEALLOCATE(MiscData%FreeBodyIs) +ENDIF +IF (ALLOCATED(MiscData%CpldBodyIs)) THEN + DEALLOCATE(MiscData%CpldBodyIs) +ENDIF +IF (ALLOCATED(MiscData%LineStateIs1)) THEN + DEALLOCATE(MiscData%LineStateIs1) +ENDIF +IF (ALLOCATED(MiscData%LineStateIsN)) THEN + DEALLOCATE(MiscData%LineStateIsN) +ENDIF +IF (ALLOCATED(MiscData%ConStateIs1)) THEN + DEALLOCATE(MiscData%ConStateIs1) +ENDIF +IF (ALLOCATED(MiscData%ConStateIsN)) THEN + DEALLOCATE(MiscData%ConStateIsN) +ENDIF +IF (ALLOCATED(MiscData%RodStateIs1)) THEN + DEALLOCATE(MiscData%RodStateIs1) +ENDIF +IF (ALLOCATED(MiscData%RodStateIsN)) THEN + DEALLOCATE(MiscData%RodStateIsN) +ENDIF +IF (ALLOCATED(MiscData%BodyStateIs1)) THEN + DEALLOCATE(MiscData%BodyStateIs1) +ENDIF +IF (ALLOCATED(MiscData%BodyStateIsN)) THEN + DEALLOCATE(MiscData%BodyStateIsN) +ENDIF + CALL MD_DestroyContState( MiscData%xTemp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MD_DestroyContState( MiscData%xdTemp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(MiscData%MDWrOutput)) THEN + DEALLOCATE(MiscData%MDWrOutput) +ENDIF +IF (ALLOCATED(MiscData%BathymetryGrid)) THEN + DEALLOCATE(MiscData%BathymetryGrid) +ENDIF +IF (ALLOCATED(MiscData%BathGrid_Xs)) THEN + DEALLOCATE(MiscData%BathGrid_Xs) +ENDIF +IF (ALLOCATED(MiscData%BathGrid_Ys)) THEN + DEALLOCATE(MiscData%BathGrid_Ys) +ENDIF +IF (ALLOCATED(MiscData%BathGrid_npoints)) THEN + DEALLOCATE(MiscData%BathGrid_npoints) +ENDIF + END SUBROUTINE MD_DestroyMisc + + SUBROUTINE MD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(MD_ConstraintStateType), INTENT(IN) :: InData + TYPE(MD_MiscVarType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly ! Local variables - INTEGER(IntKi) :: Re_BufSz + INTEGER(IntKi) :: Re_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 = 'MD_PackMisc' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! LineTypeList allocated yes/no + IF ( ALLOCATED(InData%LineTypeList) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LineTypeList upper/lower bounds for each dimension + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + DO i1 = LBOUND(InData%LineTypeList,1), UBOUND(InData%LineTypeList,1) + Int_BufSz = Int_BufSz + 3 ! LineTypeList: size of buffers for each call to pack subtype + CALL MD_Packlineprop( Re_Buf, Db_Buf, Int_Buf, InData%LineTypeList(i1), ErrStat2, ErrMsg2, .TRUE. ) ! LineTypeList + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! LineTypeList + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! LineTypeList + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! LineTypeList + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! RodTypeList allocated yes/no + IF ( ALLOCATED(InData%RodTypeList) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! RodTypeList upper/lower bounds for each dimension + DO i1 = LBOUND(InData%RodTypeList,1), UBOUND(InData%RodTypeList,1) + Int_BufSz = Int_BufSz + 3 ! RodTypeList: size of buffers for each call to pack subtype + CALL MD_Packrodprop( Re_Buf, Db_Buf, Int_Buf, InData%RodTypeList(i1), ErrStat2, ErrMsg2, .TRUE. ) ! RodTypeList + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! RodTypeList + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! RodTypeList + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! RodTypeList + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 3 ! GroundBody: size of buffers for each call to pack subtype + CALL MD_Packbody( Re_Buf, Db_Buf, Int_Buf, InData%GroundBody, ErrStat2, ErrMsg2, .TRUE. ) ! GroundBody + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! GroundBody + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! GroundBody + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! GroundBody + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 1 ! BodyList allocated yes/no + IF ( ALLOCATED(InData%BodyList) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BodyList upper/lower bounds for each dimension + DO i1 = LBOUND(InData%BodyList,1), UBOUND(InData%BodyList,1) + Int_BufSz = Int_BufSz + 3 ! BodyList: size of buffers for each call to pack subtype + CALL MD_Packbody( Re_Buf, Db_Buf, Int_Buf, InData%BodyList(i1), ErrStat2, ErrMsg2, .TRUE. ) ! BodyList + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! BodyList + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! BodyList + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! BodyList + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! RodList allocated yes/no + IF ( ALLOCATED(InData%RodList) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! RodList upper/lower bounds for each dimension + DO i1 = LBOUND(InData%RodList,1), UBOUND(InData%RodList,1) + Int_BufSz = Int_BufSz + 3 ! RodList: size of buffers for each call to pack subtype + CALL MD_Packrod( Re_Buf, Db_Buf, Int_Buf, InData%RodList(i1), ErrStat2, ErrMsg2, .TRUE. ) ! RodList + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! RodList + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! RodList + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! RodList + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! ConnectList allocated yes/no + IF ( ALLOCATED(InData%ConnectList) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ConnectList upper/lower bounds for each dimension + DO i1 = LBOUND(InData%ConnectList,1), UBOUND(InData%ConnectList,1) + Int_BufSz = Int_BufSz + 3 ! ConnectList: size of buffers for each call to pack subtype + CALL MD_Packconnect( Re_Buf, Db_Buf, Int_Buf, InData%ConnectList(i1), ErrStat2, ErrMsg2, .TRUE. ) ! ConnectList + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ConnectList + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ConnectList + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ConnectList + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! LineList allocated yes/no + IF ( ALLOCATED(InData%LineList) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LineList upper/lower bounds for each dimension + DO i1 = LBOUND(InData%LineList,1), UBOUND(InData%LineList,1) + Int_BufSz = Int_BufSz + 3 ! LineList: size of buffers for each call to pack subtype + CALL MD_Packline( Re_Buf, Db_Buf, Int_Buf, InData%LineList(i1), ErrStat2, ErrMsg2, .TRUE. ) ! LineList + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! LineList + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! LineList + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! LineList + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! FailList allocated yes/no + IF ( ALLOCATED(InData%FailList) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FailList upper/lower bounds for each dimension + DO i1 = LBOUND(InData%FailList,1), UBOUND(InData%FailList,1) + Int_BufSz = Int_BufSz + 3 ! FailList: size of buffers for each call to pack subtype + CALL MD_Packfail( Re_Buf, Db_Buf, Int_Buf, InData%FailList(i1), ErrStat2, ErrMsg2, .TRUE. ) ! FailList + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! FailList + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! FailList + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! FailList + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + END DO + END IF + Int_BufSz = Int_BufSz + 1 ! FreeConIs allocated yes/no + IF ( ALLOCATED(InData%FreeConIs) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FreeConIs upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%FreeConIs) ! FreeConIs + END IF + Int_BufSz = Int_BufSz + 1 ! CpldConIs allocated yes/no + IF ( ALLOCATED(InData%CpldConIs) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! CpldConIs upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%CpldConIs) ! CpldConIs + END IF + Int_BufSz = Int_BufSz + 1 ! FreeRodIs allocated yes/no + IF ( ALLOCATED(InData%FreeRodIs) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FreeRodIs upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%FreeRodIs) ! FreeRodIs + END IF + Int_BufSz = Int_BufSz + 1 ! CpldRodIs allocated yes/no + IF ( ALLOCATED(InData%CpldRodIs) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! CpldRodIs upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%CpldRodIs) ! CpldRodIs + END IF + Int_BufSz = Int_BufSz + 1 ! FreeBodyIs allocated yes/no + IF ( ALLOCATED(InData%FreeBodyIs) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! FreeBodyIs upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%FreeBodyIs) ! FreeBodyIs + END IF + Int_BufSz = Int_BufSz + 1 ! CpldBodyIs allocated yes/no + IF ( ALLOCATED(InData%CpldBodyIs) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! CpldBodyIs upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%CpldBodyIs) ! CpldBodyIs + END IF + Int_BufSz = Int_BufSz + 1 ! LineStateIs1 allocated yes/no + IF ( ALLOCATED(InData%LineStateIs1) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LineStateIs1 upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%LineStateIs1) ! LineStateIs1 + END IF + Int_BufSz = Int_BufSz + 1 ! LineStateIsN allocated yes/no + IF ( ALLOCATED(InData%LineStateIsN) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LineStateIsN upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%LineStateIsN) ! LineStateIsN + END IF + Int_BufSz = Int_BufSz + 1 ! ConStateIs1 allocated yes/no + IF ( ALLOCATED(InData%ConStateIs1) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ConStateIs1 upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%ConStateIs1) ! ConStateIs1 + END IF + Int_BufSz = Int_BufSz + 1 ! ConStateIsN allocated yes/no + IF ( ALLOCATED(InData%ConStateIsN) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! ConStateIsN upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%ConStateIsN) ! ConStateIsN + END IF + Int_BufSz = Int_BufSz + 1 ! RodStateIs1 allocated yes/no + IF ( ALLOCATED(InData%RodStateIs1) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! RodStateIs1 upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%RodStateIs1) ! RodStateIs1 + END IF + Int_BufSz = Int_BufSz + 1 ! RodStateIsN allocated yes/no + IF ( ALLOCATED(InData%RodStateIsN) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! RodStateIsN upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%RodStateIsN) ! RodStateIsN + END IF + Int_BufSz = Int_BufSz + 1 ! BodyStateIs1 allocated yes/no + IF ( ALLOCATED(InData%BodyStateIs1) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BodyStateIs1 upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%BodyStateIs1) ! BodyStateIs1 + END IF + Int_BufSz = Int_BufSz + 1 ! BodyStateIsN allocated yes/no + IF ( ALLOCATED(InData%BodyStateIsN) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BodyStateIsN upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%BodyStateIsN) ! BodyStateIsN + END IF + Int_BufSz = Int_BufSz + 1 ! Nx + Int_BufSz = Int_BufSz + 1 ! WaveTi + Int_BufSz = Int_BufSz + 3 ! xTemp: size of buffers for each call to pack subtype + CALL MD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%xTemp, ErrStat2, ErrMsg2, .TRUE. ) ! xTemp + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! xTemp + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! xTemp + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! xTemp + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! xdTemp: size of buffers for each call to pack subtype + CALL MD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%xdTemp, ErrStat2, ErrMsg2, .TRUE. ) ! xdTemp + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! xdTemp + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! xdTemp + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! xdTemp + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Db_BufSz = Db_BufSz + SIZE(InData%zeros6) ! zeros6 + Int_BufSz = Int_BufSz + 1 ! MDWrOutput allocated yes/no + IF ( ALLOCATED(InData%MDWrOutput) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MDWrOutput upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%MDWrOutput) ! MDWrOutput + END IF + Db_BufSz = Db_BufSz + 1 ! LastOutTime + Re_BufSz = Re_BufSz + SIZE(InData%PtfmInit) ! PtfmInit + Int_BufSz = Int_BufSz + 1 ! BathymetryGrid allocated yes/no + IF ( ALLOCATED(InData%BathymetryGrid) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! BathymetryGrid upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%BathymetryGrid) ! BathymetryGrid + END IF + Int_BufSz = Int_BufSz + 1 ! BathGrid_Xs allocated yes/no + IF ( ALLOCATED(InData%BathGrid_Xs) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BathGrid_Xs upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%BathGrid_Xs) ! BathGrid_Xs + END IF + Int_BufSz = Int_BufSz + 1 ! BathGrid_Ys allocated yes/no + IF ( ALLOCATED(InData%BathGrid_Ys) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BathGrid_Ys upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%BathGrid_Ys) ! BathGrid_Ys + END IF + Int_BufSz = Int_BufSz + 1 ! BathGrid_npoints allocated yes/no + IF ( ALLOCATED(InData%BathGrid_npoints) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! BathGrid_npoints upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%BathGrid_npoints) ! BathGrid_npoints + 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%LineTypeList) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LineTypeList,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LineTypeList,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LineTypeList,1), UBOUND(InData%LineTypeList,1) + CALL MD_Packlineprop( Re_Buf, Db_Buf, Int_Buf, InData%LineTypeList(i1), ErrStat2, ErrMsg2, OnlySize ) ! LineTypeList + 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%RodTypeList) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%RodTypeList,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RodTypeList,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%RodTypeList,1), UBOUND(InData%RodTypeList,1) + CALL MD_Packrodprop( Re_Buf, Db_Buf, Int_Buf, InData%RodTypeList(i1), ErrStat2, ErrMsg2, OnlySize ) ! RodTypeList + 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 MD_Packbody( Re_Buf, Db_Buf, Int_Buf, InData%GroundBody, ErrStat2, ErrMsg2, OnlySize ) ! GroundBody + 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%BodyList) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BodyList,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BodyList,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BodyList,1), UBOUND(InData%BodyList,1) + CALL MD_Packbody( Re_Buf, Db_Buf, Int_Buf, InData%BodyList(i1), ErrStat2, ErrMsg2, OnlySize ) ! BodyList + 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%RodList) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%RodList,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RodList,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%RodList,1), UBOUND(InData%RodList,1) + CALL MD_Packrod( Re_Buf, Db_Buf, Int_Buf, InData%RodList(i1), ErrStat2, ErrMsg2, OnlySize ) ! RodList + 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%ConnectList) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ConnectList,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ConnectList,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ConnectList,1), UBOUND(InData%ConnectList,1) + CALL MD_Packconnect( Re_Buf, Db_Buf, Int_Buf, InData%ConnectList(i1), ErrStat2, ErrMsg2, OnlySize ) ! ConnectList + 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%LineList) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LineList,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LineList,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LineList,1), UBOUND(InData%LineList,1) + CALL MD_Packline( Re_Buf, Db_Buf, Int_Buf, InData%LineList(i1), ErrStat2, ErrMsg2, OnlySize ) ! LineList + 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%FailList) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FailList,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FailList,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%FailList,1), UBOUND(InData%FailList,1) + CALL MD_Packfail( Re_Buf, Db_Buf, Int_Buf, InData%FailList(i1), ErrStat2, ErrMsg2, OnlySize ) ! FailList + 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%FreeConIs) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FreeConIs,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FreeConIs,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%FreeConIs,1), UBOUND(InData%FreeConIs,1) + IntKiBuf(Int_Xferred) = InData%FreeConIs(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%CpldConIs) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CpldConIs,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CpldConIs,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CpldConIs,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CpldConIs,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%CpldConIs,2), UBOUND(InData%CpldConIs,2) + DO i1 = LBOUND(InData%CpldConIs,1), UBOUND(InData%CpldConIs,1) + IntKiBuf(Int_Xferred) = InData%CpldConIs(i1,i2) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%FreeRodIs) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FreeRodIs,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FreeRodIs,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%FreeRodIs,1), UBOUND(InData%FreeRodIs,1) + IntKiBuf(Int_Xferred) = InData%FreeRodIs(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%CpldRodIs) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CpldRodIs,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CpldRodIs,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CpldRodIs,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CpldRodIs,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%CpldRodIs,2), UBOUND(InData%CpldRodIs,2) + DO i1 = LBOUND(InData%CpldRodIs,1), UBOUND(InData%CpldRodIs,1) + IntKiBuf(Int_Xferred) = InData%CpldRodIs(i1,i2) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%FreeBodyIs) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%FreeBodyIs,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FreeBodyIs,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%FreeBodyIs,1), UBOUND(InData%FreeBodyIs,1) + IntKiBuf(Int_Xferred) = InData%FreeBodyIs(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%CpldBodyIs) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CpldBodyIs,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CpldBodyIs,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CpldBodyIs,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CpldBodyIs,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%CpldBodyIs,2), UBOUND(InData%CpldBodyIs,2) + DO i1 = LBOUND(InData%CpldBodyIs,1), UBOUND(InData%CpldBodyIs,1) + IntKiBuf(Int_Xferred) = InData%CpldBodyIs(i1,i2) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%LineStateIs1) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LineStateIs1,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LineStateIs1,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LineStateIs1,1), UBOUND(InData%LineStateIs1,1) + IntKiBuf(Int_Xferred) = InData%LineStateIs1(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%LineStateIsN) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LineStateIsN,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LineStateIsN,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LineStateIsN,1), UBOUND(InData%LineStateIsN,1) + IntKiBuf(Int_Xferred) = InData%LineStateIsN(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ConStateIs1) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ConStateIs1,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ConStateIs1,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ConStateIs1,1), UBOUND(InData%ConStateIs1,1) + IntKiBuf(Int_Xferred) = InData%ConStateIs1(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ConStateIsN) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ConStateIsN,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ConStateIsN,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%ConStateIsN,1), UBOUND(InData%ConStateIsN,1) + IntKiBuf(Int_Xferred) = InData%ConStateIsN(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%RodStateIs1) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%RodStateIs1,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RodStateIs1,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%RodStateIs1,1), UBOUND(InData%RodStateIs1,1) + IntKiBuf(Int_Xferred) = InData%RodStateIs1(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%RodStateIsN) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%RodStateIsN,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%RodStateIsN,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%RodStateIsN,1), UBOUND(InData%RodStateIsN,1) + IntKiBuf(Int_Xferred) = InData%RodStateIsN(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BodyStateIs1) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BodyStateIs1,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BodyStateIs1,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BodyStateIs1,1), UBOUND(InData%BodyStateIs1,1) + IntKiBuf(Int_Xferred) = InData%BodyStateIs1(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BodyStateIsN) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BodyStateIsN,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BodyStateIsN,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BodyStateIsN,1), UBOUND(InData%BodyStateIsN,1) + IntKiBuf(Int_Xferred) = InData%BodyStateIsN(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IntKiBuf(Int_Xferred) = InData%Nx + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%WaveTi + Int_Xferred = Int_Xferred + 1 + CALL MD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%xTemp, ErrStat2, ErrMsg2, OnlySize ) ! xTemp + 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 MD_PackContState( Re_Buf, Db_Buf, Int_Buf, InData%xdTemp, ErrStat2, ErrMsg2, OnlySize ) ! xdTemp + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + DO i1 = LBOUND(InData%zeros6,1), UBOUND(InData%zeros6,1) + DbKiBuf(Db_Xferred) = InData%zeros6(i1) + Db_Xferred = Db_Xferred + 1 + END DO + IF ( .NOT. ALLOCATED(InData%MDWrOutput) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MDWrOutput,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MDWrOutput,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MDWrOutput,1), UBOUND(InData%MDWrOutput,1) + DbKiBuf(Db_Xferred) = InData%MDWrOutput(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + DbKiBuf(Db_Xferred) = InData%LastOutTime + Db_Xferred = Db_Xferred + 1 + DO i1 = LBOUND(InData%PtfmInit,1), UBOUND(InData%PtfmInit,1) + ReKiBuf(Re_Xferred) = InData%PtfmInit(i1) + Re_Xferred = Re_Xferred + 1 + END DO + IF ( .NOT. ALLOCATED(InData%BathymetryGrid) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BathymetryGrid,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BathymetryGrid,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BathymetryGrid,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BathymetryGrid,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%BathymetryGrid,2), UBOUND(InData%BathymetryGrid,2) + DO i1 = LBOUND(InData%BathymetryGrid,1), UBOUND(InData%BathymetryGrid,1) + DbKiBuf(Db_Xferred) = InData%BathymetryGrid(i1,i2) + Db_Xferred = Db_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BathGrid_Xs) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BathGrid_Xs,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BathGrid_Xs,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BathGrid_Xs,1), UBOUND(InData%BathGrid_Xs,1) + DbKiBuf(Db_Xferred) = InData%BathGrid_Xs(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BathGrid_Ys) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BathGrid_Ys,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BathGrid_Ys,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BathGrid_Ys,1), UBOUND(InData%BathGrid_Ys,1) + DbKiBuf(Db_Xferred) = InData%BathGrid_Ys(i1) + Db_Xferred = Db_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%BathGrid_npoints) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%BathGrid_npoints,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%BathGrid_npoints,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%BathGrid_npoints,1), UBOUND(InData%BathGrid_npoints,1) + IntKiBuf(Int_Xferred) = InData%BathGrid_npoints(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + END SUBROUTINE MD_PackMisc + + SUBROUTINE MD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) + REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) + INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) + TYPE(MD_MiscVarType), INTENT(INOUT) :: OutData + INTEGER(IntKi), INTENT( OUT) :: ErrStat + CHARACTER(*), INTENT( OUT) :: ErrMsg + ! Local variables + INTEGER(IntKi) :: Buf_size INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_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) :: 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 = 'MD_PackConstrState' - ! buffers to store subtypes, if any + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackMisc' + ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LineTypeList not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LineTypeList)) DEALLOCATE(OutData%LineTypeList) + ALLOCATE(OutData%LineTypeList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LineTypeList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LineTypeList,1), UBOUND(OutData%LineTypeList,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MD_Unpacklineprop( Re_Buf, Db_Buf, Int_Buf, OutData%LineTypeList(i1), ErrStat2, ErrMsg2 ) ! LineTypeList + 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 ! RodTypeList not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%RodTypeList)) DEALLOCATE(OutData%RodTypeList) + ALLOCATE(OutData%RodTypeList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RodTypeList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%RodTypeList,1), UBOUND(OutData%RodTypeList,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MD_Unpackrodprop( Re_Buf, Db_Buf, Int_Buf, OutData%RodTypeList(i1), ErrStat2, ErrMsg2 ) ! RodTypeList + 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 MD_Unpackbody( Re_Buf, Db_Buf, Int_Buf, OutData%GroundBody, ErrStat2, ErrMsg2 ) ! GroundBody + 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 ! BodyList not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BodyList)) DEALLOCATE(OutData%BodyList) + ALLOCATE(OutData%BodyList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BodyList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BodyList,1), UBOUND(OutData%BodyList,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MD_Unpackbody( Re_Buf, Db_Buf, Int_Buf, OutData%BodyList(i1), ErrStat2, ErrMsg2 ) ! BodyList + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! dummy - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + 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 ! RodList not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%RodList)) DEALLOCATE(OutData%RodList) + ALLOCATE(OutData%RodList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RodList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%RodList,1), UBOUND(OutData%RodList,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MD_Unpackrod( Re_Buf, Db_Buf, Int_Buf, OutData%RodList(i1), ErrStat2, ErrMsg2 ) ! RodList + 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 ! ConnectList not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ConnectList)) DEALLOCATE(OutData%ConnectList) + ALLOCATE(OutData%ConnectList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ConnectList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ConnectList,1), UBOUND(OutData%ConnectList,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MD_Unpackconnect( Re_Buf, Db_Buf, Int_Buf, OutData%ConnectList(i1), ErrStat2, ErrMsg2 ) ! ConnectList + 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 ! LineList not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LineList)) DEALLOCATE(OutData%LineList) + ALLOCATE(OutData%LineList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LineList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LineList,1), UBOUND(OutData%LineList,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MD_Unpackline( Re_Buf, Db_Buf, Int_Buf, OutData%LineList(i1), ErrStat2, ErrMsg2 ) ! LineList + 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 ! FailList not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FailList)) DEALLOCATE(OutData%FailList) + ALLOCATE(OutData%FailList(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FailList.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%FailList,1), UBOUND(OutData%FailList,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MD_Unpackfail( Re_Buf, Db_Buf, Int_Buf, OutData%FailList(i1), ErrStat2, ErrMsg2 ) ! FailList + 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 ! FreeConIs not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FreeConIs)) DEALLOCATE(OutData%FreeConIs) + ALLOCATE(OutData%FreeConIs(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FreeConIs.', ErrStat, ErrMsg,RoutineName) RETURN - END IF + END IF + DO i1 = LBOUND(OutData%FreeConIs,1), UBOUND(OutData%FreeConIs,1) + OutData%FreeConIs(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + 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) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CpldConIs not allocated + Int_Xferred = Int_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%CpldConIs)) DEALLOCATE(OutData%CpldConIs) + ALLOCATE(OutData%CpldConIs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CpldConIs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%CpldConIs,2), UBOUND(OutData%CpldConIs,2) + DO i1 = LBOUND(OutData%CpldConIs,1), UBOUND(OutData%CpldConIs,1) + OutData%CpldConIs(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FreeRodIs not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FreeRodIs)) DEALLOCATE(OutData%FreeRodIs) + ALLOCATE(OutData%FreeRodIs(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FreeRodIs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%FreeRodIs,1), UBOUND(OutData%FreeRodIs,1) + OutData%FreeRodIs(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CpldRodIs not allocated + Int_Xferred = Int_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%CpldRodIs)) DEALLOCATE(OutData%CpldRodIs) + ALLOCATE(OutData%CpldRodIs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CpldRodIs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%CpldRodIs,2), UBOUND(OutData%CpldRodIs,2) + DO i1 = LBOUND(OutData%CpldRodIs,1), UBOUND(OutData%CpldRodIs,1) + OutData%CpldRodIs(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FreeBodyIs not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%FreeBodyIs)) DEALLOCATE(OutData%FreeBodyIs) + ALLOCATE(OutData%FreeBodyIs(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%FreeBodyIs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%FreeBodyIs,1), UBOUND(OutData%FreeBodyIs,1) + OutData%FreeBodyIs(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CpldBodyIs not allocated + Int_Xferred = Int_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%CpldBodyIs)) DEALLOCATE(OutData%CpldBodyIs) + ALLOCATE(OutData%CpldBodyIs(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CpldBodyIs.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%CpldBodyIs,2), UBOUND(OutData%CpldBodyIs,2) + DO i1 = LBOUND(OutData%CpldBodyIs,1), UBOUND(OutData%CpldBodyIs,1) + OutData%CpldBodyIs(i1,i2) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LineStateIs1 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LineStateIs1)) DEALLOCATE(OutData%LineStateIs1) + ALLOCATE(OutData%LineStateIs1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LineStateIs1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LineStateIs1,1), UBOUND(OutData%LineStateIs1,1) + OutData%LineStateIs1(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LineStateIsN not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LineStateIsN)) DEALLOCATE(OutData%LineStateIsN) + ALLOCATE(OutData%LineStateIsN(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LineStateIsN.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LineStateIsN,1), UBOUND(OutData%LineStateIsN,1) + OutData%LineStateIsN(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ConStateIs1 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ConStateIs1)) DEALLOCATE(OutData%ConStateIs1) + ALLOCATE(OutData%ConStateIs1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ConStateIs1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ConStateIs1,1), UBOUND(OutData%ConStateIs1,1) + OutData%ConStateIs1(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ConStateIsN not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ConStateIsN)) DEALLOCATE(OutData%ConStateIsN) + ALLOCATE(OutData%ConStateIsN(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ConStateIsN.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ConStateIsN,1), UBOUND(OutData%ConStateIsN,1) + OutData%ConStateIsN(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RodStateIs1 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%RodStateIs1)) DEALLOCATE(OutData%RodStateIs1) + ALLOCATE(OutData%RodStateIs1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RodStateIs1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%RodStateIs1,1), UBOUND(OutData%RodStateIs1,1) + OutData%RodStateIs1(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! RodStateIsN not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%RodStateIsN)) DEALLOCATE(OutData%RodStateIsN) + ALLOCATE(OutData%RodStateIsN(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%RodStateIsN.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%RodStateIsN,1), UBOUND(OutData%RodStateIsN,1) + OutData%RodStateIsN(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BodyStateIs1 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BodyStateIs1)) DEALLOCATE(OutData%BodyStateIs1) + ALLOCATE(OutData%BodyStateIs1(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BodyStateIs1.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BodyStateIs1,1), UBOUND(OutData%BodyStateIs1,1) + OutData%BodyStateIs1(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BodyStateIsN not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BodyStateIsN)) DEALLOCATE(OutData%BodyStateIsN) + ALLOCATE(OutData%BodyStateIsN(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BodyStateIsN.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BodyStateIsN,1), UBOUND(OutData%BodyStateIsN,1) + OutData%BodyStateIsN(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + OutData%Nx = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WaveTi = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL MD_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%xTemp, ErrStat2, ErrMsg2 ) ! xTemp + 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 MD_UnpackContState( Re_Buf, Db_Buf, Int_Buf, OutData%xdTemp, ErrStat2, ErrMsg2 ) ! xdTemp + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + i1_l = LBOUND(OutData%zeros6,1) + i1_u = UBOUND(OutData%zeros6,1) + DO i1 = LBOUND(OutData%zeros6,1), UBOUND(OutData%zeros6,1) + OutData%zeros6(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MDWrOutput not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MDWrOutput)) DEALLOCATE(OutData%MDWrOutput) + ALLOCATE(OutData%MDWrOutput(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MDWrOutput.', ErrStat, ErrMsg,RoutineName) RETURN - END IF + END IF + DO i1 = LBOUND(OutData%MDWrOutput,1), UBOUND(OutData%MDWrOutput,1) + OutData%MDWrOutput(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + 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) + OutData%LastOutTime = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + i1_l = LBOUND(OutData%PtfmInit,1) + i1_u = UBOUND(OutData%PtfmInit,1) + DO i1 = LBOUND(OutData%PtfmInit,1), UBOUND(OutData%PtfmInit,1) + OutData%PtfmInit(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BathymetryGrid not allocated + Int_Xferred = Int_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%BathymetryGrid)) DEALLOCATE(OutData%BathymetryGrid) + ALLOCATE(OutData%BathymetryGrid(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BathymetryGrid.', ErrStat, ErrMsg,RoutineName) RETURN - END IF + END IF + DO i2 = LBOUND(OutData%BathymetryGrid,2), UBOUND(OutData%BathymetryGrid,2) + DO i1 = LBOUND(OutData%BathymetryGrid,1), UBOUND(OutData%BathymetryGrid,1) + OutData%BathymetryGrid(i1,i2) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + END DO + END DO END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%dummy - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE MD_PackConstrState - - SUBROUTINE MD_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(MD_ConstraintStateType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackConstrState' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%dummy = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE MD_UnPackConstrState - - SUBROUTINE MD_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ErrStat, ErrMsg ) - TYPE(MD_OtherStateType), INTENT(IN) :: SrcOtherStateData - TYPE(MD_OtherStateType), INTENT(INOUT) :: DstOtherStateData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyOtherState' -! - ErrStat = ErrID_None - ErrMsg = "" - DstOtherStateData%dummy = SrcOtherStateData%dummy - END SUBROUTINE MD_CopyOtherState - - SUBROUTINE MD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) - TYPE(MD_OtherStateType), INTENT(INOUT) :: OtherStateData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyOtherState' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" - END SUBROUTINE MD_DestroyOtherState - - SUBROUTINE MD_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(MD_OtherStateType), INTENT(IN) :: InData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly - ! Local variables - INTEGER(IntKi) :: Re_BufSz - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_BufSz - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_BufSz - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i,i1,i2,i3,i4,i5 - LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_PackOtherState' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Re_BufSz = Re_BufSz + 1 ! dummy - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BathGrid_Xs not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BathGrid_Xs)) DEALLOCATE(OutData%BathGrid_Xs) + ALLOCATE(OutData%BathGrid_Xs(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BathGrid_Xs.', ErrStat, ErrMsg,RoutineName) RETURN - END IF + END IF + DO i1 = LBOUND(OutData%BathGrid_Xs,1), UBOUND(OutData%BathGrid_Xs,1) + OutData%BathGrid_Xs(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + 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) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BathGrid_Ys not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BathGrid_Ys)) DEALLOCATE(OutData%BathGrid_Ys) + ALLOCATE(OutData%BathGrid_Ys(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BathGrid_Ys.', ErrStat, ErrMsg,RoutineName) RETURN - END IF + END IF + DO i1 = LBOUND(OutData%BathGrid_Ys,1), UBOUND(OutData%BathGrid_Ys,1) + OutData%BathGrid_Ys(i1) = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + 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) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BathGrid_npoints not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BathGrid_npoints)) DEALLOCATE(OutData%BathGrid_npoints) + ALLOCATE(OutData%BathGrid_npoints(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BathGrid_npoints.', ErrStat, ErrMsg,RoutineName) RETURN - END IF + END IF + DO i1 = LBOUND(OutData%BathGrid_npoints,1), UBOUND(OutData%BathGrid_npoints,1) + OutData%BathGrid_npoints(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - ReKiBuf(Re_Xferred) = InData%dummy - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE MD_PackOtherState - - SUBROUTINE MD_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) - REAL(ReKi), ALLOCATABLE, INTENT(IN ) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT(IN ) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT(IN ) :: IntKiBuf(:) - TYPE(MD_OtherStateType), INTENT(INOUT) :: OutData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - ! Local variables - INTEGER(IntKi) :: Buf_size - INTEGER(IntKi) :: Re_Xferred - INTEGER(IntKi) :: Db_Xferred - INTEGER(IntKi) :: Int_Xferred - INTEGER(IntKi) :: i - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackOtherState' - ! buffers to store meshes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - OutData%dummy = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END SUBROUTINE MD_UnPackOtherState + END SUBROUTINE MD_UnPackMisc - SUBROUTINE MD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) - TYPE(MD_MiscVarType), INTENT(IN) :: SrcMiscData - TYPE(MD_MiscVarType), INTENT(INOUT) :: DstMiscData + SUBROUTINE MD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) + TYPE(MD_ParameterType), INTENT(IN) :: SrcParamData + TYPE(MD_ParameterType), INTENT(INOUT) :: DstParamData INTEGER(IntKi), INTENT(IN ) :: CtrlCode INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 + INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyMisc' + CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyParam' ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcMiscData%LineTypeList)) THEN - i1_l = LBOUND(SrcMiscData%LineTypeList,1) - i1_u = UBOUND(SrcMiscData%LineTypeList,1) - IF (.NOT. ALLOCATED(DstMiscData%LineTypeList)) THEN - ALLOCATE(DstMiscData%LineTypeList(i1_l:i1_u),STAT=ErrStat2) + DstParamData%nLineTypes = SrcParamData%nLineTypes + DstParamData%nRodTypes = SrcParamData%nRodTypes + DstParamData%nConnects = SrcParamData%nConnects + DstParamData%nConnectsExtra = SrcParamData%nConnectsExtra + DstParamData%nBodies = SrcParamData%nBodies + DstParamData%nRods = SrcParamData%nRods + DstParamData%nLines = SrcParamData%nLines + DstParamData%nCtrlChans = SrcParamData%nCtrlChans + DstParamData%nFails = SrcParamData%nFails + DstParamData%nFreeBodies = SrcParamData%nFreeBodies + DstParamData%nFreeRods = SrcParamData%nFreeRods + DstParamData%nFreeCons = SrcParamData%nFreeCons +IF (ALLOCATED(SrcParamData%nCpldBodies)) THEN + i1_l = LBOUND(SrcParamData%nCpldBodies,1) + i1_u = UBOUND(SrcParamData%nCpldBodies,1) + IF (.NOT. ALLOCATED(DstParamData%nCpldBodies)) THEN + ALLOCATE(DstParamData%nCpldBodies(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%LineTypeList.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%nCpldBodies.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcMiscData%LineTypeList,1), UBOUND(SrcMiscData%LineTypeList,1) - CALL MD_Copylineprop( SrcMiscData%LineTypeList(i1), DstMiscData%LineTypeList(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO + DstParamData%nCpldBodies = SrcParamData%nCpldBodies ENDIF -IF (ALLOCATED(SrcMiscData%ConnectList)) THEN - i1_l = LBOUND(SrcMiscData%ConnectList,1) - i1_u = UBOUND(SrcMiscData%ConnectList,1) - IF (.NOT. ALLOCATED(DstMiscData%ConnectList)) THEN - ALLOCATE(DstMiscData%ConnectList(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%nCpldRods)) THEN + i1_l = LBOUND(SrcParamData%nCpldRods,1) + i1_u = UBOUND(SrcParamData%nCpldRods,1) + IF (.NOT. ALLOCATED(DstParamData%nCpldRods)) THEN + ALLOCATE(DstParamData%nCpldRods(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%ConnectList.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%nCpldRods.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcMiscData%ConnectList,1), UBOUND(SrcMiscData%ConnectList,1) - CALL MD_Copyconnect( SrcMiscData%ConnectList(i1), DstMiscData%ConnectList(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO + DstParamData%nCpldRods = SrcParamData%nCpldRods ENDIF -IF (ALLOCATED(SrcMiscData%LineList)) THEN - i1_l = LBOUND(SrcMiscData%LineList,1) - i1_u = UBOUND(SrcMiscData%LineList,1) - IF (.NOT. ALLOCATED(DstMiscData%LineList)) THEN - ALLOCATE(DstMiscData%LineList(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%nCpldCons)) THEN + i1_l = LBOUND(SrcParamData%nCpldCons,1) + i1_u = UBOUND(SrcParamData%nCpldCons,1) + IF (.NOT. ALLOCATED(DstParamData%nCpldCons)) THEN + ALLOCATE(DstParamData%nCpldCons(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%LineList.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%nCpldCons.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DO i1 = LBOUND(SrcMiscData%LineList,1), UBOUND(SrcMiscData%LineList,1) - CALL MD_Copyline( SrcMiscData%LineList(i1), DstMiscData%LineList(i1), CtrlCode, ErrStat2, ErrMsg2 ) + DstParamData%nCpldCons = SrcParamData%nCpldCons +ENDIF + DstParamData%NConns = SrcParamData%NConns + DstParamData%NAnchs = SrcParamData%NAnchs + DstParamData%Tmax = SrcParamData%Tmax + DstParamData%g = SrcParamData%g + DstParamData%rhoW = SrcParamData%rhoW + DstParamData%WtrDpth = SrcParamData%WtrDpth + DstParamData%kBot = SrcParamData%kBot + DstParamData%cBot = SrcParamData%cBot + DstParamData%dtM0 = SrcParamData%dtM0 + DstParamData%dtCoupling = SrcParamData%dtCoupling + DstParamData%NumOuts = SrcParamData%NumOuts + DstParamData%dtOut = SrcParamData%dtOut + DstParamData%RootName = SrcParamData%RootName +IF (ALLOCATED(SrcParamData%OutParam)) THEN + i1_l = LBOUND(SrcParamData%OutParam,1) + i1_u = UBOUND(SrcParamData%OutParam,1) + IF (.NOT. ALLOCATED(DstParamData%OutParam)) THEN + ALLOCATE(DstParamData%OutParam(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%OutParam.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcParamData%OutParam,1), UBOUND(SrcParamData%OutParam,1) + CALL MD_Copyoutparmtype( SrcParamData%OutParam(i1), DstParamData%OutParam(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcMiscData%FairIdList)) THEN - i1_l = LBOUND(SrcMiscData%FairIdList,1) - i1_u = UBOUND(SrcMiscData%FairIdList,1) - IF (.NOT. ALLOCATED(DstMiscData%FairIdList)) THEN - ALLOCATE(DstMiscData%FairIdList(i1_l:i1_u),STAT=ErrStat2) + DstParamData%Delim = SrcParamData%Delim + DstParamData%MDUnOut = SrcParamData%MDUnOut + DstParamData%PriPath = SrcParamData%PriPath + DstParamData%writeLog = SrcParamData%writeLog + DstParamData%UnLog = SrcParamData%UnLog + DstParamData%WaveKin = SrcParamData%WaveKin + DstParamData%Current = SrcParamData%Current + DstParamData%nTurbines = SrcParamData%nTurbines +IF (ALLOCATED(SrcParamData%TurbineRefPos)) THEN + i1_l = LBOUND(SrcParamData%TurbineRefPos,1) + i1_u = UBOUND(SrcParamData%TurbineRefPos,1) + i2_l = LBOUND(SrcParamData%TurbineRefPos,2) + i2_u = UBOUND(SrcParamData%TurbineRefPos,2) + IF (.NOT. ALLOCATED(DstParamData%TurbineRefPos)) THEN + ALLOCATE(DstParamData%TurbineRefPos(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%FairIdList.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%TurbineRefPos.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%FairIdList = SrcMiscData%FairIdList + DstParamData%TurbineRefPos = SrcParamData%TurbineRefPos ENDIF -IF (ALLOCATED(SrcMiscData%ConnIdList)) THEN - i1_l = LBOUND(SrcMiscData%ConnIdList,1) - i1_u = UBOUND(SrcMiscData%ConnIdList,1) - IF (.NOT. ALLOCATED(DstMiscData%ConnIdList)) THEN - ALLOCATE(DstMiscData%ConnIdList(i1_l:i1_u),STAT=ErrStat2) + DstParamData%mu_kT = SrcParamData%mu_kT + DstParamData%mu_kA = SrcParamData%mu_kA + DstParamData%mc = SrcParamData%mc + DstParamData%cv = SrcParamData%cv + DstParamData%nxWave = SrcParamData%nxWave + DstParamData%nyWave = SrcParamData%nyWave + DstParamData%nzWave = SrcParamData%nzWave + DstParamData%ntWave = SrcParamData%ntWave +IF (ALLOCATED(SrcParamData%pxWave)) THEN + i1_l = LBOUND(SrcParamData%pxWave,1) + i1_u = UBOUND(SrcParamData%pxWave,1) + IF (.NOT. ALLOCATED(DstParamData%pxWave)) THEN + ALLOCATE(DstParamData%pxWave(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%ConnIdList.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%pxWave.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%ConnIdList = SrcMiscData%ConnIdList + DstParamData%pxWave = SrcParamData%pxWave ENDIF -IF (ALLOCATED(SrcMiscData%LineStateIndList)) THEN - i1_l = LBOUND(SrcMiscData%LineStateIndList,1) - i1_u = UBOUND(SrcMiscData%LineStateIndList,1) - IF (.NOT. ALLOCATED(DstMiscData%LineStateIndList)) THEN - ALLOCATE(DstMiscData%LineStateIndList(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%pyWave)) THEN + i1_l = LBOUND(SrcParamData%pyWave,1) + i1_u = UBOUND(SrcParamData%pyWave,1) + IF (.NOT. ALLOCATED(DstParamData%pyWave)) THEN + ALLOCATE(DstParamData%pyWave(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%LineStateIndList.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%pyWave.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%LineStateIndList = SrcMiscData%LineStateIndList + DstParamData%pyWave = SrcParamData%pyWave ENDIF -IF (ALLOCATED(SrcMiscData%MDWrOutput)) THEN - i1_l = LBOUND(SrcMiscData%MDWrOutput,1) - i1_u = UBOUND(SrcMiscData%MDWrOutput,1) - IF (.NOT. ALLOCATED(DstMiscData%MDWrOutput)) THEN - ALLOCATE(DstMiscData%MDWrOutput(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%pzWave)) THEN + i1_l = LBOUND(SrcParamData%pzWave,1) + i1_u = UBOUND(SrcParamData%pzWave,1) + IF (.NOT. ALLOCATED(DstParamData%pzWave)) THEN + ALLOCATE(DstParamData%pzWave(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%MDWrOutput.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%pzWave.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%MDWrOutput = SrcMiscData%MDWrOutput + DstParamData%pzWave = SrcParamData%pzWave ENDIF - END SUBROUTINE MD_CopyMisc + DstParamData%dtWave = SrcParamData%dtWave +IF (ALLOCATED(SrcParamData%uxWave)) THEN + i1_l = LBOUND(SrcParamData%uxWave,1) + i1_u = UBOUND(SrcParamData%uxWave,1) + i2_l = LBOUND(SrcParamData%uxWave,2) + i2_u = UBOUND(SrcParamData%uxWave,2) + i3_l = LBOUND(SrcParamData%uxWave,3) + i3_u = UBOUND(SrcParamData%uxWave,3) + i4_l = LBOUND(SrcParamData%uxWave,4) + i4_u = UBOUND(SrcParamData%uxWave,4) + IF (.NOT. ALLOCATED(DstParamData%uxWave)) THEN + ALLOCATE(DstParamData%uxWave(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%uxWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%uxWave = SrcParamData%uxWave +ENDIF +IF (ALLOCATED(SrcParamData%uyWave)) THEN + i1_l = LBOUND(SrcParamData%uyWave,1) + i1_u = UBOUND(SrcParamData%uyWave,1) + i2_l = LBOUND(SrcParamData%uyWave,2) + i2_u = UBOUND(SrcParamData%uyWave,2) + i3_l = LBOUND(SrcParamData%uyWave,3) + i3_u = UBOUND(SrcParamData%uyWave,3) + i4_l = LBOUND(SrcParamData%uyWave,4) + i4_u = UBOUND(SrcParamData%uyWave,4) + IF (.NOT. ALLOCATED(DstParamData%uyWave)) THEN + ALLOCATE(DstParamData%uyWave(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%uyWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%uyWave = SrcParamData%uyWave +ENDIF +IF (ALLOCATED(SrcParamData%uzWave)) THEN + i1_l = LBOUND(SrcParamData%uzWave,1) + i1_u = UBOUND(SrcParamData%uzWave,1) + i2_l = LBOUND(SrcParamData%uzWave,2) + i2_u = UBOUND(SrcParamData%uzWave,2) + i3_l = LBOUND(SrcParamData%uzWave,3) + i3_u = UBOUND(SrcParamData%uzWave,3) + i4_l = LBOUND(SrcParamData%uzWave,4) + i4_u = UBOUND(SrcParamData%uzWave,4) + IF (.NOT. ALLOCATED(DstParamData%uzWave)) THEN + ALLOCATE(DstParamData%uzWave(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%uzWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%uzWave = SrcParamData%uzWave +ENDIF +IF (ALLOCATED(SrcParamData%axWave)) THEN + i1_l = LBOUND(SrcParamData%axWave,1) + i1_u = UBOUND(SrcParamData%axWave,1) + i2_l = LBOUND(SrcParamData%axWave,2) + i2_u = UBOUND(SrcParamData%axWave,2) + i3_l = LBOUND(SrcParamData%axWave,3) + i3_u = UBOUND(SrcParamData%axWave,3) + i4_l = LBOUND(SrcParamData%axWave,4) + i4_u = UBOUND(SrcParamData%axWave,4) + IF (.NOT. ALLOCATED(DstParamData%axWave)) THEN + ALLOCATE(DstParamData%axWave(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%axWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%axWave = SrcParamData%axWave +ENDIF +IF (ALLOCATED(SrcParamData%ayWave)) THEN + i1_l = LBOUND(SrcParamData%ayWave,1) + i1_u = UBOUND(SrcParamData%ayWave,1) + i2_l = LBOUND(SrcParamData%ayWave,2) + i2_u = UBOUND(SrcParamData%ayWave,2) + i3_l = LBOUND(SrcParamData%ayWave,3) + i3_u = UBOUND(SrcParamData%ayWave,3) + i4_l = LBOUND(SrcParamData%ayWave,4) + i4_u = UBOUND(SrcParamData%ayWave,4) + IF (.NOT. ALLOCATED(DstParamData%ayWave)) THEN + ALLOCATE(DstParamData%ayWave(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%ayWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%ayWave = SrcParamData%ayWave +ENDIF +IF (ALLOCATED(SrcParamData%azWave)) THEN + i1_l = LBOUND(SrcParamData%azWave,1) + i1_u = UBOUND(SrcParamData%azWave,1) + i2_l = LBOUND(SrcParamData%azWave,2) + i2_u = UBOUND(SrcParamData%azWave,2) + i3_l = LBOUND(SrcParamData%azWave,3) + i3_u = UBOUND(SrcParamData%azWave,3) + i4_l = LBOUND(SrcParamData%azWave,4) + i4_u = UBOUND(SrcParamData%azWave,4) + IF (.NOT. ALLOCATED(DstParamData%azWave)) THEN + ALLOCATE(DstParamData%azWave(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%azWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%azWave = SrcParamData%azWave +ENDIF +IF (ALLOCATED(SrcParamData%PDyn)) THEN + i1_l = LBOUND(SrcParamData%PDyn,1) + i1_u = UBOUND(SrcParamData%PDyn,1) + i2_l = LBOUND(SrcParamData%PDyn,2) + i2_u = UBOUND(SrcParamData%PDyn,2) + i3_l = LBOUND(SrcParamData%PDyn,3) + i3_u = UBOUND(SrcParamData%PDyn,3) + i4_l = LBOUND(SrcParamData%PDyn,4) + i4_u = UBOUND(SrcParamData%PDyn,4) + IF (.NOT. ALLOCATED(DstParamData%PDyn)) THEN + ALLOCATE(DstParamData%PDyn(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%PDyn.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%PDyn = SrcParamData%PDyn +ENDIF +IF (ALLOCATED(SrcParamData%zeta)) THEN + i1_l = LBOUND(SrcParamData%zeta,1) + i1_u = UBOUND(SrcParamData%zeta,1) + i2_l = LBOUND(SrcParamData%zeta,2) + i2_u = UBOUND(SrcParamData%zeta,2) + i3_l = LBOUND(SrcParamData%zeta,3) + i3_u = UBOUND(SrcParamData%zeta,3) + IF (.NOT. ALLOCATED(DstParamData%zeta)) THEN + ALLOCATE(DstParamData%zeta(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%zeta.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%zeta = SrcParamData%zeta +ENDIF + DstParamData%nzCurrent = SrcParamData%nzCurrent +IF (ALLOCATED(SrcParamData%pzCurrent)) THEN + i1_l = LBOUND(SrcParamData%pzCurrent,1) + i1_u = UBOUND(SrcParamData%pzCurrent,1) + IF (.NOT. ALLOCATED(DstParamData%pzCurrent)) THEN + ALLOCATE(DstParamData%pzCurrent(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%pzCurrent.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%pzCurrent = SrcParamData%pzCurrent +ENDIF +IF (ALLOCATED(SrcParamData%uxCurrent)) THEN + i1_l = LBOUND(SrcParamData%uxCurrent,1) + i1_u = UBOUND(SrcParamData%uxCurrent,1) + IF (.NOT. ALLOCATED(DstParamData%uxCurrent)) THEN + ALLOCATE(DstParamData%uxCurrent(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%uxCurrent.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%uxCurrent = SrcParamData%uxCurrent +ENDIF +IF (ALLOCATED(SrcParamData%uyCurrent)) THEN + i1_l = LBOUND(SrcParamData%uyCurrent,1) + i1_u = UBOUND(SrcParamData%uyCurrent,1) + IF (.NOT. ALLOCATED(DstParamData%uyCurrent)) THEN + ALLOCATE(DstParamData%uyCurrent(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%uyCurrent.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%uyCurrent = SrcParamData%uyCurrent +ENDIF + DstParamData%Nx0 = SrcParamData%Nx0 +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 +IF (ALLOCATED(SrcParamData%dx)) THEN + i1_l = LBOUND(SrcParamData%dx,1) + i1_u = UBOUND(SrcParamData%dx,1) + IF (.NOT. ALLOCATED(DstParamData%dx)) THEN + ALLOCATE(DstParamData%dx(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%dx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%dx = SrcParamData%dx +ENDIF + DstParamData%Jac_ny = SrcParamData%Jac_ny + DstParamData%Jac_nx = SrcParamData%Jac_nx +IF (ALLOCATED(SrcParamData%dxIdx_map2_xStateIdx)) THEN + i1_l = LBOUND(SrcParamData%dxIdx_map2_xStateIdx,1) + i1_u = UBOUND(SrcParamData%dxIdx_map2_xStateIdx,1) + IF (.NOT. ALLOCATED(DstParamData%dxIdx_map2_xStateIdx)) THEN + ALLOCATE(DstParamData%dxIdx_map2_xStateIdx(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%dxIdx_map2_xStateIdx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%dxIdx_map2_xStateIdx = SrcParamData%dxIdx_map2_xStateIdx +ENDIF + END SUBROUTINE MD_CopyParam - SUBROUTINE MD_DestroyMisc( MiscData, ErrStat, ErrMsg ) - TYPE(MD_MiscVarType), INTENT(INOUT) :: MiscData + SUBROUTINE MD_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) + TYPE(MD_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(MiscData%LineTypeList)) THEN -DO i1 = LBOUND(MiscData%LineTypeList,1), UBOUND(MiscData%LineTypeList,1) - CALL MD_Destroylineprop( MiscData%LineTypeList(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(MiscData%LineTypeList) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(ParamData%nCpldBodies)) THEN + DEALLOCATE(ParamData%nCpldBodies) ENDIF -IF (ALLOCATED(MiscData%ConnectList)) THEN -DO i1 = LBOUND(MiscData%ConnectList,1), UBOUND(MiscData%ConnectList,1) - CALL MD_Destroyconnect( MiscData%ConnectList(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(MiscData%ConnectList) +IF (ALLOCATED(ParamData%nCpldRods)) THEN + DEALLOCATE(ParamData%nCpldRods) ENDIF -IF (ALLOCATED(MiscData%LineList)) THEN -DO i1 = LBOUND(MiscData%LineList,1), UBOUND(MiscData%LineList,1) - CALL MD_Destroyline( MiscData%LineList(i1), ErrStat, ErrMsg ) +IF (ALLOCATED(ParamData%nCpldCons)) THEN + DEALLOCATE(ParamData%nCpldCons) +ENDIF +IF (ALLOCATED(ParamData%OutParam)) THEN +DO i1 = LBOUND(ParamData%OutParam,1), UBOUND(ParamData%OutParam,1) + CALL MD_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - DEALLOCATE(MiscData%LineList) + DEALLOCATE(ParamData%OutParam) ENDIF -IF (ALLOCATED(MiscData%FairIdList)) THEN - DEALLOCATE(MiscData%FairIdList) +IF (ALLOCATED(ParamData%TurbineRefPos)) THEN + DEALLOCATE(ParamData%TurbineRefPos) ENDIF -IF (ALLOCATED(MiscData%ConnIdList)) THEN - DEALLOCATE(MiscData%ConnIdList) +IF (ALLOCATED(ParamData%pxWave)) THEN + DEALLOCATE(ParamData%pxWave) ENDIF -IF (ALLOCATED(MiscData%LineStateIndList)) THEN - DEALLOCATE(MiscData%LineStateIndList) +IF (ALLOCATED(ParamData%pyWave)) THEN + DEALLOCATE(ParamData%pyWave) ENDIF -IF (ALLOCATED(MiscData%MDWrOutput)) THEN - DEALLOCATE(MiscData%MDWrOutput) +IF (ALLOCATED(ParamData%pzWave)) THEN + DEALLOCATE(ParamData%pzWave) ENDIF - END SUBROUTINE MD_DestroyMisc +IF (ALLOCATED(ParamData%uxWave)) THEN + DEALLOCATE(ParamData%uxWave) +ENDIF +IF (ALLOCATED(ParamData%uyWave)) THEN + DEALLOCATE(ParamData%uyWave) +ENDIF +IF (ALLOCATED(ParamData%uzWave)) THEN + DEALLOCATE(ParamData%uzWave) +ENDIF +IF (ALLOCATED(ParamData%axWave)) THEN + DEALLOCATE(ParamData%axWave) +ENDIF +IF (ALLOCATED(ParamData%ayWave)) THEN + DEALLOCATE(ParamData%ayWave) +ENDIF +IF (ALLOCATED(ParamData%azWave)) THEN + DEALLOCATE(ParamData%azWave) +ENDIF +IF (ALLOCATED(ParamData%PDyn)) THEN + DEALLOCATE(ParamData%PDyn) +ENDIF +IF (ALLOCATED(ParamData%zeta)) THEN + DEALLOCATE(ParamData%zeta) +ENDIF +IF (ALLOCATED(ParamData%pzCurrent)) THEN + DEALLOCATE(ParamData%pzCurrent) +ENDIF +IF (ALLOCATED(ParamData%uxCurrent)) THEN + DEALLOCATE(ParamData%uxCurrent) +ENDIF +IF (ALLOCATED(ParamData%uyCurrent)) THEN + DEALLOCATE(ParamData%uyCurrent) +ENDIF +IF (ALLOCATED(ParamData%Jac_u_indx)) THEN + DEALLOCATE(ParamData%Jac_u_indx) +ENDIF +IF (ALLOCATED(ParamData%du)) THEN + DEALLOCATE(ParamData%du) +ENDIF +IF (ALLOCATED(ParamData%dx)) THEN + DEALLOCATE(ParamData%dx) +ENDIF +IF (ALLOCATED(ParamData%dxIdx_map2_xStateIdx)) THEN + DEALLOCATE(ParamData%dxIdx_map2_xStateIdx) +ENDIF + END SUBROUTINE MD_DestroyParam - SUBROUTINE MD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) + SUBROUTINE MD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(MD_MiscVarType), INTENT(IN) :: InData + TYPE(MD_ParameterType), INTENT(IN) :: InData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg LOGICAL,OPTIONAL, INTENT(IN ) :: SizeOnly @@ -3748,114 +11312,204 @@ SUBROUTINE MD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz 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 = 'MD_PackMisc' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! LineTypeList allocated yes/no - IF ( ALLOCATED(InData%LineTypeList) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! LineTypeList upper/lower bounds for each dimension - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - DO i1 = LBOUND(InData%LineTypeList,1), UBOUND(InData%LineTypeList,1) - Int_BufSz = Int_BufSz + 3 ! LineTypeList: size of buffers for each call to pack subtype - CALL MD_Packlineprop( Re_Buf, Db_Buf, Int_Buf, InData%LineTypeList(i1), ErrStat2, ErrMsg2, .TRUE. ) ! LineTypeList - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! LineTypeList - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! LineTypeList - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! LineTypeList - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - END IF - Int_BufSz = Int_BufSz + 1 ! ConnectList allocated yes/no - IF ( ALLOCATED(InData%ConnectList) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! ConnectList upper/lower bounds for each dimension - DO i1 = LBOUND(InData%ConnectList,1), UBOUND(InData%ConnectList,1) - Int_BufSz = Int_BufSz + 3 ! ConnectList: size of buffers for each call to pack subtype - CALL MD_Packconnect( Re_Buf, Db_Buf, Int_Buf, InData%ConnectList(i1), ErrStat2, ErrMsg2, .TRUE. ) ! ConnectList - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! ConnectList - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! ConnectList - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! ConnectList - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO + LOGICAL :: OnlySize ! if present and true, do not pack, just allocate buffers + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_PackParam' + ! buffers to store subtypes, if any + REAL(ReKi), ALLOCATABLE :: Re_Buf(:) + REAL(DbKi), ALLOCATABLE :: Db_Buf(:) + INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) + + OnlySize = .FALSE. + IF ( PRESENT(SizeOnly) ) THEN + OnlySize = SizeOnly + ENDIF + ! + ErrStat = ErrID_None + ErrMsg = "" + Re_BufSz = 0 + Db_BufSz = 0 + Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! nLineTypes + Int_BufSz = Int_BufSz + 1 ! nRodTypes + Int_BufSz = Int_BufSz + 1 ! nConnects + Int_BufSz = Int_BufSz + 1 ! nConnectsExtra + Int_BufSz = Int_BufSz + 1 ! nBodies + Int_BufSz = Int_BufSz + 1 ! nRods + Int_BufSz = Int_BufSz + 1 ! nLines + Int_BufSz = Int_BufSz + 1 ! nCtrlChans + Int_BufSz = Int_BufSz + 1 ! nFails + Int_BufSz = Int_BufSz + 1 ! nFreeBodies + Int_BufSz = Int_BufSz + 1 ! nFreeRods + Int_BufSz = Int_BufSz + 1 ! nFreeCons + Int_BufSz = Int_BufSz + 1 ! nCpldBodies allocated yes/no + IF ( ALLOCATED(InData%nCpldBodies) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! nCpldBodies upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%nCpldBodies) ! nCpldBodies + END IF + Int_BufSz = Int_BufSz + 1 ! nCpldRods allocated yes/no + IF ( ALLOCATED(InData%nCpldRods) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! nCpldRods upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%nCpldRods) ! nCpldRods + END IF + Int_BufSz = Int_BufSz + 1 ! nCpldCons allocated yes/no + IF ( ALLOCATED(InData%nCpldCons) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! nCpldCons upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%nCpldCons) ! nCpldCons END IF - Int_BufSz = Int_BufSz + 1 ! LineList allocated yes/no - IF ( ALLOCATED(InData%LineList) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! LineList upper/lower bounds for each dimension - DO i1 = LBOUND(InData%LineList,1), UBOUND(InData%LineList,1) - Int_BufSz = Int_BufSz + 3 ! LineList: size of buffers for each call to pack subtype - CALL MD_Packline( Re_Buf, Db_Buf, Int_Buf, InData%LineList(i1), ErrStat2, ErrMsg2, .TRUE. ) ! LineList + Int_BufSz = Int_BufSz + 1 ! NConns + Int_BufSz = Int_BufSz + 1 ! NAnchs + Db_BufSz = Db_BufSz + 1 ! Tmax + Db_BufSz = Db_BufSz + 1 ! g + Db_BufSz = Db_BufSz + 1 ! rhoW + Db_BufSz = Db_BufSz + 1 ! WtrDpth + Db_BufSz = Db_BufSz + 1 ! kBot + Db_BufSz = Db_BufSz + 1 ! cBot + Db_BufSz = Db_BufSz + 1 ! dtM0 + Db_BufSz = Db_BufSz + 1 ! dtCoupling + Int_BufSz = Int_BufSz + 1 ! NumOuts + Db_BufSz = Db_BufSz + 1 ! dtOut + Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName + 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 + ! Allocate buffers for subtypes, if any (we'll get sizes from these) + 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 MD_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 ! LineList + IF(ALLOCATED(Re_Buf)) THEN ! OutParam Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! LineList + IF(ALLOCATED(Db_Buf)) THEN ! OutParam Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! LineList + 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 ! FairIdList allocated yes/no - IF ( ALLOCATED(InData%FairIdList) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! FairIdList upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%FairIdList) ! FairIdList - END IF - Int_BufSz = Int_BufSz + 1 ! ConnIdList allocated yes/no - IF ( ALLOCATED(InData%ConnIdList) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! ConnIdList upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%ConnIdList) ! ConnIdList - END IF - Int_BufSz = Int_BufSz + 1 ! LineStateIndList allocated yes/no - IF ( ALLOCATED(InData%LineStateIndList) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! LineStateIndList upper/lower bounds for each dimension - Int_BufSz = Int_BufSz + SIZE(InData%LineStateIndList) ! LineStateIndList - END IF - Int_BufSz = Int_BufSz + 1 ! MDWrOutput allocated yes/no - IF ( ALLOCATED(InData%MDWrOutput) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! MDWrOutput upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%MDWrOutput) ! MDWrOutput + Int_BufSz = Int_BufSz + 1*LEN(InData%Delim) ! Delim + Int_BufSz = Int_BufSz + 1 ! MDUnOut + Int_BufSz = Int_BufSz + 1*LEN(InData%PriPath) ! PriPath + Int_BufSz = Int_BufSz + 1 ! writeLog + Int_BufSz = Int_BufSz + 1 ! UnLog + Int_BufSz = Int_BufSz + 1 ! WaveKin + Int_BufSz = Int_BufSz + 1 ! Current + Int_BufSz = Int_BufSz + 1 ! nTurbines + Int_BufSz = Int_BufSz + 1 ! TurbineRefPos allocated yes/no + IF ( ALLOCATED(InData%TurbineRefPos) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! TurbineRefPos upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%TurbineRefPos) ! TurbineRefPos + END IF + Db_BufSz = Db_BufSz + 1 ! mu_kT + Db_BufSz = Db_BufSz + 1 ! mu_kA + Db_BufSz = Db_BufSz + 1 ! mc + Db_BufSz = Db_BufSz + 1 ! cv + Int_BufSz = Int_BufSz + 1 ! nxWave + Int_BufSz = Int_BufSz + 1 ! nyWave + Int_BufSz = Int_BufSz + 1 ! nzWave + Int_BufSz = Int_BufSz + 1 ! ntWave + Int_BufSz = Int_BufSz + 1 ! pxWave allocated yes/no + IF ( ALLOCATED(InData%pxWave) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! pxWave upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%pxWave) ! pxWave + END IF + Int_BufSz = Int_BufSz + 1 ! pyWave allocated yes/no + IF ( ALLOCATED(InData%pyWave) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! pyWave upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%pyWave) ! pyWave + END IF + Int_BufSz = Int_BufSz + 1 ! pzWave allocated yes/no + IF ( ALLOCATED(InData%pzWave) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! pzWave upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%pzWave) ! pzWave + END IF + Re_BufSz = Re_BufSz + 1 ! dtWave + Int_BufSz = Int_BufSz + 1 ! uxWave allocated yes/no + IF ( ALLOCATED(InData%uxWave) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! uxWave upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%uxWave) ! uxWave + END IF + Int_BufSz = Int_BufSz + 1 ! uyWave allocated yes/no + IF ( ALLOCATED(InData%uyWave) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! uyWave upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%uyWave) ! uyWave + END IF + Int_BufSz = Int_BufSz + 1 ! uzWave allocated yes/no + IF ( ALLOCATED(InData%uzWave) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! uzWave upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%uzWave) ! uzWave + END IF + Int_BufSz = Int_BufSz + 1 ! axWave allocated yes/no + IF ( ALLOCATED(InData%axWave) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! axWave upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%axWave) ! axWave + END IF + Int_BufSz = Int_BufSz + 1 ! ayWave allocated yes/no + IF ( ALLOCATED(InData%ayWave) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! ayWave upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%ayWave) ! ayWave + END IF + Int_BufSz = Int_BufSz + 1 ! azWave allocated yes/no + IF ( ALLOCATED(InData%azWave) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! azWave upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%azWave) ! azWave + END IF + Int_BufSz = Int_BufSz + 1 ! PDyn allocated yes/no + IF ( ALLOCATED(InData%PDyn) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! PDyn upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%PDyn) ! PDyn + END IF + Int_BufSz = Int_BufSz + 1 ! zeta allocated yes/no + IF ( ALLOCATED(InData%zeta) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! zeta upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%zeta) ! zeta + END IF + Int_BufSz = Int_BufSz + 1 ! nzCurrent + Int_BufSz = Int_BufSz + 1 ! pzCurrent allocated yes/no + IF ( ALLOCATED(InData%pzCurrent) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! pzCurrent upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%pzCurrent) ! pzCurrent + END IF + Int_BufSz = Int_BufSz + 1 ! uxCurrent allocated yes/no + IF ( ALLOCATED(InData%uxCurrent) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! uxCurrent upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%uxCurrent) ! uxCurrent + END IF + Int_BufSz = Int_BufSz + 1 ! uyCurrent allocated yes/no + IF ( ALLOCATED(InData%uyCurrent) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! uyCurrent upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%uyCurrent) ! uyCurrent + END IF + Int_BufSz = Int_BufSz + 1 ! Nx0 + 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 + Int_BufSz = Int_BufSz + 1 ! dx allocated yes/no + IF ( ALLOCATED(InData%dx) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! dx upper/lower bounds for each dimension + Db_BufSz = Db_BufSz + SIZE(InData%dx) ! dx + END IF + Int_BufSz = Int_BufSz + 1 ! Jac_ny + Int_BufSz = Int_BufSz + 1 ! Jac_nx + Int_BufSz = Int_BufSz + 1 ! dxIdx_map2_xStateIdx allocated yes/no + IF ( ALLOCATED(InData%dxIdx_map2_xStateIdx) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! dxIdx_map2_xStateIdx upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + SIZE(InData%dxIdx_map2_xStateIdx) ! dxIdx_map2_xStateIdx END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -3871,209 +11525,620 @@ SUBROUTINE MD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz 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 + IF ( Int_BufSz .GT. 0 ) THEN + ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + + Re_Xferred = 1 + Db_Xferred = 1 + Int_Xferred = 1 + + IntKiBuf(Int_Xferred) = InData%nLineTypes + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nRodTypes + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nConnects + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nConnectsExtra + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nBodies + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nRods + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nLines + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nCtrlChans + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nFails + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nFreeBodies + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nFreeRods + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nFreeCons + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%nCpldBodies) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%nCpldBodies,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nCpldBodies,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%nCpldBodies,1), UBOUND(InData%nCpldBodies,1) + IntKiBuf(Int_Xferred) = InData%nCpldBodies(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%nCpldRods) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%nCpldRods,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nCpldRods,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%nCpldRods,1), UBOUND(InData%nCpldRods,1) + IntKiBuf(Int_Xferred) = InData%nCpldRods(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%nCpldCons) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%nCpldCons,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nCpldCons,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%nCpldCons,1), UBOUND(InData%nCpldCons,1) + IntKiBuf(Int_Xferred) = InData%nCpldCons(i1) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IntKiBuf(Int_Xferred) = InData%NConns + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NAnchs + Int_Xferred = Int_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%Tmax + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%g + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%rhoW + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%WtrDpth + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%kBot + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%cBot + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%dtM0 + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%dtCoupling + Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumOuts + Int_Xferred = Int_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%dtOut + Db_Xferred = Db_Xferred + 1 + DO I = 1, LEN(InData%RootName) + IntKiBuf(Int_Xferred) = ICHAR(InData%RootName(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + 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%OutParam,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%OutParam,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%OutParam,1), UBOUND(InData%OutParam,1) + CALL MD_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 + DO I = 1, LEN(InData%Delim) + IntKiBuf(Int_Xferred) = ICHAR(InData%Delim(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IntKiBuf(Int_Xferred) = InData%MDUnOut + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(InData%PriPath) + IntKiBuf(Int_Xferred) = ICHAR(InData%PriPath(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IntKiBuf(Int_Xferred) = InData%writeLog + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%UnLog + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%WaveKin + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%Current + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nTurbines + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%TurbineRefPos) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TurbineRefPos,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TurbineRefPos,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%TurbineRefPos,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%TurbineRefPos,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%TurbineRefPos,2), UBOUND(InData%TurbineRefPos,2) + DO i1 = LBOUND(InData%TurbineRefPos,1), UBOUND(InData%TurbineRefPos,1) + ReKiBuf(Re_Xferred) = InData%TurbineRefPos(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + DbKiBuf(Db_Xferred) = InData%mu_kT + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%mu_kA + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%mc + Db_Xferred = Db_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%cv + Db_Xferred = Db_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nxWave + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nyWave + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%nzWave + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%ntWave + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%pxWave) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%pxWave,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%pxWave,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%pxWave,1), UBOUND(InData%pxWave,1) + ReKiBuf(Re_Xferred) = InData%pxWave(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%pyWave) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%pyWave,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%pyWave,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%pyWave,1), UBOUND(InData%pyWave,1) + ReKiBuf(Re_Xferred) = InData%pyWave(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%pzWave) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%pzWave,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%pzWave,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%pzWave,1), UBOUND(InData%pzWave,1) + ReKiBuf(Re_Xferred) = InData%pzWave(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + ReKiBuf(Re_Xferred) = InData%dtWave + Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%uxWave) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%uxWave,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uxWave,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%uxWave,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uxWave,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%uxWave,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uxWave,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%uxWave,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uxWave,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%uxWave,4), UBOUND(InData%uxWave,4) + DO i3 = LBOUND(InData%uxWave,3), UBOUND(InData%uxWave,3) + DO i2 = LBOUND(InData%uxWave,2), UBOUND(InData%uxWave,2) + DO i1 = LBOUND(InData%uxWave,1), UBOUND(InData%uxWave,1) + ReKiBuf(Re_Xferred) = InData%uxWave(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%uyWave) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%uyWave,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uyWave,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%uyWave,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uyWave,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%uyWave,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uyWave,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%uyWave,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uyWave,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%uyWave,4), UBOUND(InData%uyWave,4) + DO i3 = LBOUND(InData%uyWave,3), UBOUND(InData%uyWave,3) + DO i2 = LBOUND(InData%uyWave,2), UBOUND(InData%uyWave,2) + DO i1 = LBOUND(InData%uyWave,1), UBOUND(InData%uyWave,1) + ReKiBuf(Re_Xferred) = InData%uyWave(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%uzWave) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%uzWave,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uzWave,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%uzWave,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uzWave,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%uzWave,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uzWave,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%uzWave,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uzWave,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%uzWave,4), UBOUND(InData%uzWave,4) + DO i3 = LBOUND(InData%uzWave,3), UBOUND(InData%uzWave,3) + DO i2 = LBOUND(InData%uzWave,2), UBOUND(InData%uzWave,2) + DO i1 = LBOUND(InData%uzWave,1), UBOUND(InData%uzWave,1) + ReKiBuf(Re_Xferred) = InData%uzWave(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) + IF ( .NOT. ALLOCATED(InData%axWave) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%axWave,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%axWave,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%axWave,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%axWave,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%axWave,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%axWave,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%axWave,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%axWave,4) + Int_Xferred = Int_Xferred + 2 - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 + DO i4 = LBOUND(InData%axWave,4), UBOUND(InData%axWave,4) + DO i3 = LBOUND(InData%axWave,3), UBOUND(InData%axWave,3) + DO i2 = LBOUND(InData%axWave,2), UBOUND(InData%axWave,2) + DO i1 = LBOUND(InData%axWave,1), UBOUND(InData%axWave,1) + ReKiBuf(Re_Xferred) = InData%axWave(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%ayWave) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ayWave,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ayWave,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ayWave,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ayWave,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ayWave,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ayWave,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%ayWave,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ayWave,4) + Int_Xferred = Int_Xferred + 2 - IF ( .NOT. ALLOCATED(InData%LineTypeList) ) THEN + DO i4 = LBOUND(InData%ayWave,4), UBOUND(InData%ayWave,4) + DO i3 = LBOUND(InData%ayWave,3), UBOUND(InData%ayWave,3) + DO i2 = LBOUND(InData%ayWave,2), UBOUND(InData%ayWave,2) + DO i1 = LBOUND(InData%ayWave,1), UBOUND(InData%ayWave,1) + ReKiBuf(Re_Xferred) = InData%ayWave(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%azWave) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%LineTypeList,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LineTypeList,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%azWave,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%azWave,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%azWave,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%azWave,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%azWave,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%azWave,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%azWave,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%azWave,4) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%LineTypeList,1), UBOUND(InData%LineTypeList,1) - CALL MD_Packlineprop( Re_Buf, Db_Buf, Int_Buf, InData%LineTypeList(i1), ErrStat2, ErrMsg2, OnlySize ) ! LineTypeList - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + DO i4 = LBOUND(InData%azWave,4), UBOUND(InData%azWave,4) + DO i3 = LBOUND(InData%azWave,3), UBOUND(InData%azWave,3) + DO i2 = LBOUND(InData%azWave,2), UBOUND(InData%azWave,2) + DO i1 = LBOUND(InData%azWave,1), UBOUND(InData%azWave,1) + ReKiBuf(Re_Xferred) = InData%azWave(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%PDyn) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PDyn,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PDyn,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PDyn,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PDyn,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PDyn,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PDyn,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%PDyn,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%PDyn,4) + 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 DO + DO i4 = LBOUND(InData%PDyn,4), UBOUND(InData%PDyn,4) + DO i3 = LBOUND(InData%PDyn,3), UBOUND(InData%PDyn,3) + DO i2 = LBOUND(InData%PDyn,2), UBOUND(InData%PDyn,2) + DO i1 = LBOUND(InData%PDyn,1), UBOUND(InData%PDyn,1) + ReKiBuf(Re_Xferred) = InData%PDyn(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO END IF - IF ( .NOT. ALLOCATED(InData%ConnectList) ) THEN + IF ( .NOT. ALLOCATED(InData%zeta) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%ConnectList,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ConnectList,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%zeta,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%zeta,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%zeta,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%zeta,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%zeta,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%zeta,3) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%ConnectList,1), UBOUND(InData%ConnectList,1) - CALL MD_Packconnect( Re_Buf, Db_Buf, Int_Buf, InData%ConnectList(i1), ErrStat2, ErrMsg2, OnlySize ) ! ConnectList - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + DO i3 = LBOUND(InData%zeta,3), UBOUND(InData%zeta,3) + DO i2 = LBOUND(InData%zeta,2), UBOUND(InData%zeta,2) + DO i1 = LBOUND(InData%zeta,1), UBOUND(InData%zeta,1) + ReKiBuf(Re_Xferred) = InData%zeta(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IntKiBuf(Int_Xferred) = InData%nzCurrent + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%pzCurrent) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%pzCurrent,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%pzCurrent,1) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END DO + DO i1 = LBOUND(InData%pzCurrent,1), UBOUND(InData%pzCurrent,1) + ReKiBuf(Re_Xferred) = InData%pzCurrent(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF - IF ( .NOT. ALLOCATED(InData%LineList) ) THEN + IF ( .NOT. ALLOCATED(InData%uxCurrent) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%LineList,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LineList,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%uxCurrent,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uxCurrent,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%LineList,1), UBOUND(InData%LineList,1) - CALL MD_Packline( Re_Buf, Db_Buf, Int_Buf, InData%LineList(i1), ErrStat2, ErrMsg2, OnlySize ) ! LineList - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + DO i1 = LBOUND(InData%uxCurrent,1), UBOUND(InData%uxCurrent,1) + ReKiBuf(Re_Xferred) = InData%uxCurrent(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%uyCurrent) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%uyCurrent,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%uyCurrent,1) + Int_Xferred = Int_Xferred + 2 - IF(ALLOCATED(Re_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf - Re_Xferred = Re_Xferred + SIZE(Re_Buf) - DEALLOCATE(Re_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Db_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf - Db_Xferred = Db_Xferred + SIZE(Db_Buf) - DEALLOCATE(Db_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - IF(ALLOCATED(Int_Buf)) THEN - IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 - IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf - Int_Xferred = Int_Xferred + SIZE(Int_Buf) - DEALLOCATE(Int_Buf) - ELSE - IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 - ENDIF - END DO + DO i1 = LBOUND(InData%uyCurrent,1), UBOUND(InData%uyCurrent,1) + ReKiBuf(Re_Xferred) = InData%uyCurrent(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF - IF ( .NOT. ALLOCATED(InData%FairIdList) ) THEN + IntKiBuf(Int_Xferred) = InData%Nx0 + 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%FairIdList,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%FairIdList,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%Jac_u_indx,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Jac_u_indx,2) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%FairIdList,1), UBOUND(InData%FairIdList,1) - IntKiBuf(Int_Xferred) = InData%FairIdList(i1) - Int_Xferred = Int_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 - IF ( .NOT. ALLOCATED(InData%ConnIdList) ) 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%ConnIdList,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ConnIdList,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%du,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%du,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%ConnIdList,1), UBOUND(InData%ConnIdList,1) - IntKiBuf(Int_Xferred) = InData%ConnIdList(i1) - Int_Xferred = Int_Xferred + 1 + 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 - IF ( .NOT. ALLOCATED(InData%LineStateIndList) ) THEN + IF ( .NOT. ALLOCATED(InData%dx) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%LineStateIndList,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LineStateIndList,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%dx,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dx,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%LineStateIndList,1), UBOUND(InData%LineStateIndList,1) - IntKiBuf(Int_Xferred) = InData%LineStateIndList(i1) - Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%dx,1), UBOUND(InData%dx,1) + DbKiBuf(Db_Xferred) = InData%dx(i1) + Db_Xferred = Db_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%MDWrOutput) ) THEN + IntKiBuf(Int_Xferred) = InData%Jac_ny + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%Jac_nx + Int_Xferred = Int_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%dxIdx_map2_xStateIdx) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%MDWrOutput,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MDWrOutput,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%dxIdx_map2_xStateIdx,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dxIdx_map2_xStateIdx,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%MDWrOutput,1), UBOUND(InData%MDWrOutput,1) - ReKiBuf(Re_Xferred) = InData%MDWrOutput(i1) - Re_Xferred = Re_Xferred + 1 + DO i1 = LBOUND(InData%dxIdx_map2_xStateIdx,1), UBOUND(InData%dxIdx_map2_xStateIdx,1) + IntKiBuf(Int_Xferred) = InData%dxIdx_map2_xStateIdx(i1) + Int_Xferred = Int_Xferred + 1 END DO END IF - END SUBROUTINE MD_PackMisc + END SUBROUTINE MD_PackParam - SUBROUTINE MD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) + SUBROUTINE MD_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(MD_MiscVarType), INTENT(INOUT) :: OutData + TYPE(MD_ParameterType), INTENT(INOUT) :: OutData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg ! Local variables @@ -4083,9 +12148,12 @@ SUBROUTINE MD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) 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 = 'MD_UnPackMisc' + CHARACTER(*), PARAMETER :: RoutineName = 'MD_UnPackParam' ! buffers to store meshes, if any REAL(ReKi), ALLOCATABLE :: Re_Buf(:) REAL(DbKi), ALLOCATABLE :: Db_Buf(:) @@ -4096,20 +12164,126 @@ SUBROUTINE MD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LineTypeList not allocated + OutData%nLineTypes = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nRodTypes = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nConnects = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nConnectsExtra = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nBodies = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nRods = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nLines = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nCtrlChans = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nFails = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nFreeBodies = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nFreeRods = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nFreeCons = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nCpldBodies not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%nCpldBodies)) DEALLOCATE(OutData%nCpldBodies) + ALLOCATE(OutData%nCpldBodies(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nCpldBodies.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%nCpldBodies,1), UBOUND(OutData%nCpldBodies,1) + OutData%nCpldBodies(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nCpldRods not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%nCpldRods)) DEALLOCATE(OutData%nCpldRods) + ALLOCATE(OutData%nCpldRods(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nCpldRods.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%nCpldRods,1), UBOUND(OutData%nCpldRods,1) + OutData%nCpldRods(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nCpldCons not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%nCpldCons)) DEALLOCATE(OutData%nCpldCons) + ALLOCATE(OutData%nCpldCons(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nCpldCons.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%nCpldCons,1), UBOUND(OutData%nCpldCons,1) + OutData%nCpldCons(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO + END IF + OutData%NConns = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NAnchs = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%Tmax = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%g = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%rhoW = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%WtrDpth = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%kBot = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%cBot = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%dtM0 = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%dtCoupling = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%NumOuts = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%dtOut = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + DO I = 1, LEN(OutData%RootName) + OutData%RootName(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutParam not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%LineTypeList)) DEALLOCATE(OutData%LineTypeList) - ALLOCATE(OutData%LineTypeList(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%OutParam)) DEALLOCATE(OutData%OutParam) + ALLOCATE(OutData%OutParam(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LineTypeList.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutParam.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%LineTypeList,1), UBOUND(OutData%LineTypeList,1) + DO i1 = LBOUND(OutData%OutParam,1), UBOUND(OutData%OutParam,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -4143,7 +12317,7 @@ SUBROUTINE MD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL MD_Unpacklineprop( Re_Buf, Db_Buf, Int_Buf, OutData%LineTypeList(i1), ErrStat2, ErrMsg2 ) ! LineTypeList + CALL MD_Unpackoutparmtype( Re_Buf, Db_Buf, Int_Buf, OutData%OutParam(i1), ErrStat2, ErrMsg2 ) ! OutParam CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4152,564 +12326,519 @@ SUBROUTINE MD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ConnectList not allocated + DO I = 1, LEN(OutData%Delim) + OutData%Delim(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%MDUnOut = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(OutData%PriPath) + OutData%PriPath(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%writeLog = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%UnLog = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WaveKin = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%Current = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nTurbines = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! TurbineRefPos not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%ConnectList)) DEALLOCATE(OutData%ConnectList) - ALLOCATE(OutData%ConnectList(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%TurbineRefPos)) DEALLOCATE(OutData%TurbineRefPos) + ALLOCATE(OutData%TurbineRefPos(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ConnectList.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%TurbineRefPos.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%ConnectList,1), UBOUND(OutData%ConnectList,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL MD_Unpackconnect( Re_Buf, Db_Buf, Int_Buf, OutData%ConnectList(i1), ErrStat2, ErrMsg2 ) ! ConnectList - 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 + DO i2 = LBOUND(OutData%TurbineRefPos,2), UBOUND(OutData%TurbineRefPos,2) + DO i1 = LBOUND(OutData%TurbineRefPos,1), UBOUND(OutData%TurbineRefPos,1) + OutData%TurbineRefPos(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LineList not allocated + OutData%mu_kT = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%mu_kA = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%mc = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%cv = DbKiBuf(Db_Xferred) + Db_Xferred = Db_Xferred + 1 + OutData%nxWave = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nyWave = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%nzWave = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%ntWave = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! pxWave not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%LineList)) DEALLOCATE(OutData%LineList) - ALLOCATE(OutData%LineList(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%pxWave)) DEALLOCATE(OutData%pxWave) + ALLOCATE(OutData%pxWave(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LineList.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%pxWave.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%LineList,1), UBOUND(OutData%LineList,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL MD_Unpackline( Re_Buf, Db_Buf, Int_Buf, OutData%LineList(i1), ErrStat2, ErrMsg2 ) ! LineList - 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 + DO i1 = LBOUND(OutData%pxWave,1), UBOUND(OutData%pxWave,1) + OutData%pxWave(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! pyWave not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%pyWave)) DEALLOCATE(OutData%pyWave) + ALLOCATE(OutData%pyWave(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%pyWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%pyWave,1), UBOUND(OutData%pyWave,1) + OutData%pyWave(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! pzWave not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%pzWave)) DEALLOCATE(OutData%pzWave) + ALLOCATE(OutData%pzWave(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%pzWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%pzWave,1), UBOUND(OutData%pzWave,1) + OutData%pzWave(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + OutData%dtWave = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! uxWave not allocated + Int_Xferred = Int_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%uxWave)) DEALLOCATE(OutData%uxWave) + ALLOCATE(OutData%uxWave(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%uxWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%uxWave,4), UBOUND(OutData%uxWave,4) + DO i3 = LBOUND(OutData%uxWave,3), UBOUND(OutData%uxWave,3) + DO i2 = LBOUND(OutData%uxWave,2), UBOUND(OutData%uxWave,2) + DO i1 = LBOUND(OutData%uxWave,1), UBOUND(OutData%uxWave,1) + OutData%uxWave(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! uyWave not allocated + Int_Xferred = Int_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%uyWave)) DEALLOCATE(OutData%uyWave) + ALLOCATE(OutData%uyWave(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%uyWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%uyWave,4), UBOUND(OutData%uyWave,4) + DO i3 = LBOUND(OutData%uyWave,3), UBOUND(OutData%uyWave,3) + DO i2 = LBOUND(OutData%uyWave,2), UBOUND(OutData%uyWave,2) + DO i1 = LBOUND(OutData%uyWave,1), UBOUND(OutData%uyWave,1) + OutData%uyWave(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! uzWave not allocated + Int_Xferred = Int_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%uzWave)) DEALLOCATE(OutData%uzWave) + ALLOCATE(OutData%uzWave(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%uzWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%uzWave,4), UBOUND(OutData%uzWave,4) + DO i3 = LBOUND(OutData%uzWave,3), UBOUND(OutData%uzWave,3) + DO i2 = LBOUND(OutData%uzWave,2), UBOUND(OutData%uzWave,2) + DO i1 = LBOUND(OutData%uzWave,1), UBOUND(OutData%uzWave,1) + OutData%uzWave(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! axWave not allocated + Int_Xferred = Int_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%axWave)) DEALLOCATE(OutData%axWave) + ALLOCATE(OutData%axWave(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%axWave.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%axWave,4), UBOUND(OutData%axWave,4) + DO i3 = LBOUND(OutData%axWave,3), UBOUND(OutData%axWave,3) + DO i2 = LBOUND(OutData%axWave,2), UBOUND(OutData%axWave,2) + DO i1 = LBOUND(OutData%axWave,1), UBOUND(OutData%axWave,1) + OutData%axWave(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! FairIdList not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ayWave not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%FairIdList)) DEALLOCATE(OutData%FairIdList) - ALLOCATE(OutData%FairIdList(i1_l:i1_u),STAT=ErrStat2) + 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%ayWave)) DEALLOCATE(OutData%ayWave) + ALLOCATE(OutData%ayWave(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%FairIdList.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ayWave.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%FairIdList,1), UBOUND(OutData%FairIdList,1) - OutData%FairIdList(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + DO i4 = LBOUND(OutData%ayWave,4), UBOUND(OutData%ayWave,4) + DO i3 = LBOUND(OutData%ayWave,3), UBOUND(OutData%ayWave,3) + DO i2 = LBOUND(OutData%ayWave,2), UBOUND(OutData%ayWave,2) + DO i1 = LBOUND(OutData%ayWave,1), UBOUND(OutData%ayWave,1) + OutData%ayWave(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ConnIdList not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! azWave not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%ConnIdList)) DEALLOCATE(OutData%ConnIdList) - ALLOCATE(OutData%ConnIdList(i1_l:i1_u),STAT=ErrStat2) + 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%azWave)) DEALLOCATE(OutData%azWave) + ALLOCATE(OutData%azWave(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%ConnIdList.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%azWave.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%ConnIdList,1), UBOUND(OutData%ConnIdList,1) - OutData%ConnIdList(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + DO i4 = LBOUND(OutData%azWave,4), UBOUND(OutData%azWave,4) + DO i3 = LBOUND(OutData%azWave,3), UBOUND(OutData%azWave,3) + DO i2 = LBOUND(OutData%azWave,2), UBOUND(OutData%azWave,2) + DO i1 = LBOUND(OutData%azWave,1), UBOUND(OutData%azWave,1) + OutData%azWave(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LineStateIndList not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! PDyn not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%LineStateIndList)) DEALLOCATE(OutData%LineStateIndList) - ALLOCATE(OutData%LineStateIndList(i1_l:i1_u),STAT=ErrStat2) + 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%PDyn)) DEALLOCATE(OutData%PDyn) + ALLOCATE(OutData%PDyn(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%LineStateIndList.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%PDyn.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%LineStateIndList,1), UBOUND(OutData%LineStateIndList,1) - OutData%LineStateIndList(i1) = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 + DO i4 = LBOUND(OutData%PDyn,4), UBOUND(OutData%PDyn,4) + DO i3 = LBOUND(OutData%PDyn,3), UBOUND(OutData%PDyn,3) + DO i2 = LBOUND(OutData%PDyn,2), UBOUND(OutData%PDyn,2) + DO i1 = LBOUND(OutData%PDyn,1), UBOUND(OutData%PDyn,1) + OutData%PDyn(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MDWrOutput not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! zeta not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%MDWrOutput)) DEALLOCATE(OutData%MDWrOutput) - ALLOCATE(OutData%MDWrOutput(i1_l:i1_u),STAT=ErrStat2) + 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%zeta)) DEALLOCATE(OutData%zeta) + ALLOCATE(OutData%zeta(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%MDWrOutput.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%zeta.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%MDWrOutput,1), UBOUND(OutData%MDWrOutput,1) - OutData%MDWrOutput(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(OutData%zeta,3), UBOUND(OutData%zeta,3) + DO i2 = LBOUND(OutData%zeta,2), UBOUND(OutData%zeta,2) + DO i1 = LBOUND(OutData%zeta,1), UBOUND(OutData%zeta,1) + OutData%zeta(i1,i2,i3) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO END IF - END SUBROUTINE MD_UnPackMisc - - SUBROUTINE MD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) - TYPE(MD_ParameterType), INTENT(IN) :: SrcParamData - TYPE(MD_ParameterType), INTENT(INOUT) :: DstParamData - INTEGER(IntKi), INTENT(IN ) :: CtrlCode - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg -! Local - INTEGER(IntKi) :: i,j,k - INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 - INTEGER(IntKi) :: ErrStat2 - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'MD_CopyParam' -! - ErrStat = ErrID_None - ErrMsg = "" - DstParamData%NTypes = SrcParamData%NTypes - DstParamData%NConnects = SrcParamData%NConnects - DstParamData%NFairs = SrcParamData%NFairs - DstParamData%NConns = SrcParamData%NConns - DstParamData%NAnchs = SrcParamData%NAnchs - DstParamData%NLines = SrcParamData%NLines - DstParamData%g = SrcParamData%g - DstParamData%rhoW = SrcParamData%rhoW - DstParamData%WtrDpth = SrcParamData%WtrDpth - DstParamData%kBot = SrcParamData%kBot - DstParamData%cBot = SrcParamData%cBot - DstParamData%dtM0 = SrcParamData%dtM0 - DstParamData%dtCoupling = SrcParamData%dtCoupling - DstParamData%NumOuts = SrcParamData%NumOuts - DstParamData%RootName = SrcParamData%RootName -IF (ALLOCATED(SrcParamData%OutParam)) THEN - i1_l = LBOUND(SrcParamData%OutParam,1) - i1_u = UBOUND(SrcParamData%OutParam,1) - IF (.NOT. ALLOCATED(DstParamData%OutParam)) THEN - ALLOCATE(DstParamData%OutParam(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%OutParam.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcParamData%OutParam,1), UBOUND(SrcParamData%OutParam,1) - CALL MD_Copyoutparmtype( SrcParamData%OutParam(i1), DstParamData%OutParam(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF - DstParamData%Delim = SrcParamData%Delim - DstParamData%MDUnOut = SrcParamData%MDUnOut - END SUBROUTINE MD_CopyParam - - SUBROUTINE MD_DestroyParam( ParamData, ErrStat, ErrMsg ) - TYPE(MD_ParameterType), INTENT(INOUT) :: ParamData - INTEGER(IntKi), INTENT( OUT) :: ErrStat - CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyParam' - INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! - ErrStat = ErrID_None - ErrMsg = "" -IF (ALLOCATED(ParamData%OutParam)) THEN -DO i1 = LBOUND(ParamData%OutParam,1), UBOUND(ParamData%OutParam,1) - CALL MD_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(ParamData%OutParam) -ENDIF - END SUBROUTINE MD_DestroyParam - - SUBROUTINE MD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) - REAL(ReKi), ALLOCATABLE, INTENT( OUT) :: ReKiBuf(:) - REAL(DbKi), ALLOCATABLE, INTENT( OUT) :: DbKiBuf(:) - INTEGER(IntKi), ALLOCATABLE, INTENT( OUT) :: IntKiBuf(:) - TYPE(MD_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 = 'MD_PackParam' - ! buffers to store subtypes, if any - REAL(ReKi), ALLOCATABLE :: Re_Buf(:) - REAL(DbKi), ALLOCATABLE :: Db_Buf(:) - INTEGER(IntKi), ALLOCATABLE :: Int_Buf(:) - - OnlySize = .FALSE. - IF ( PRESENT(SizeOnly) ) THEN - OnlySize = SizeOnly - ENDIF - ! - ErrStat = ErrID_None - ErrMsg = "" - Re_BufSz = 0 - Db_BufSz = 0 - Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! NTypes - Int_BufSz = Int_BufSz + 1 ! NConnects - Int_BufSz = Int_BufSz + 1 ! NFairs - Int_BufSz = Int_BufSz + 1 ! NConns - Int_BufSz = Int_BufSz + 1 ! NAnchs - Int_BufSz = Int_BufSz + 1 ! NLines - Re_BufSz = Re_BufSz + 1 ! g - Re_BufSz = Re_BufSz + 1 ! rhoW - Re_BufSz = Re_BufSz + 1 ! WtrDpth - Re_BufSz = Re_BufSz + 1 ! kBot - Re_BufSz = Re_BufSz + 1 ! cBot - Re_BufSz = Re_BufSz + 1 ! dtM0 - Re_BufSz = Re_BufSz + 1 ! dtCoupling - Int_BufSz = Int_BufSz + 1 ! NumOuts - Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName - 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 - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - 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 MD_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*LEN(InData%Delim) ! Delim - Int_BufSz = Int_BufSz + 1 ! MDUnOut - IF ( Re_BufSz .GT. 0 ) THEN - ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Db_BufSz .GT. 0 ) THEN - ALLOCATE( DbKiBuf( Db_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF ( Int_BufSz .GT. 0 ) THEN - ALLOCATE( IntKiBuf( Int_BufSz ), STAT=ErrStat2 ) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them) - - Re_Xferred = 1 - Db_Xferred = 1 - Int_Xferred = 1 - - IntKiBuf(Int_Xferred) = InData%NTypes + OutData%nzCurrent = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NConnects + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! pzCurrent not allocated Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NFairs + ELSE Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NConns + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%pzCurrent)) DEALLOCATE(OutData%pzCurrent) + ALLOCATE(OutData%pzCurrent(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%pzCurrent.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%pzCurrent,1), UBOUND(OutData%pzCurrent,1) + OutData%pzCurrent(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! uxCurrent not allocated Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NAnchs + ELSE Int_Xferred = Int_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NLines + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%uxCurrent)) DEALLOCATE(OutData%uxCurrent) + ALLOCATE(OutData%uxCurrent(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%uxCurrent.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%uxCurrent,1), UBOUND(OutData%uxCurrent,1) + OutData%uxCurrent(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! uyCurrent not allocated Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%g - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%rhoW - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%WtrDpth - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%kBot - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%cBot - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%dtM0 - Re_Xferred = Re_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%dtCoupling - Re_Xferred = Re_Xferred + 1 - IntKiBuf(Int_Xferred) = InData%NumOuts + ELSE Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(InData%RootName) - IntKiBuf(Int_Xferred) = ICHAR(InData%RootName(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IF ( .NOT. ALLOCATED(InData%OutParam) ) THEN - IntKiBuf( Int_Xferred ) = 0 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%uyCurrent)) DEALLOCATE(OutData%uyCurrent) + ALLOCATE(OutData%uyCurrent(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%uyCurrent.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%uyCurrent,1), UBOUND(OutData%uyCurrent,1) + OutData%uyCurrent(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + OutData%Nx0 = 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 - 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 MD_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%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 - DO I = 1, LEN(InData%Delim) - IntKiBuf(Int_Xferred) = ICHAR(InData%Delim(I:I), IntKi) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IntKiBuf(Int_Xferred) = InData%MDUnOut - Int_Xferred = Int_Xferred + 1 - END SUBROUTINE MD_PackParam - - SUBROUTINE MD_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(MD_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 = 'MD_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%NTypes = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 - OutData%NConnects = IntKiBuf(Int_Xferred) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! du not allocated Int_Xferred = Int_Xferred + 1 - OutData%NFairs = IntKiBuf(Int_Xferred) + ELSE Int_Xferred = Int_Xferred + 1 - OutData%NConns = IntKiBuf(Int_Xferred) + 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 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dx not allocated Int_Xferred = Int_Xferred + 1 - OutData%NAnchs = IntKiBuf(Int_Xferred) + ELSE Int_Xferred = Int_Xferred + 1 - OutData%NLines = IntKiBuf(Int_Xferred) + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%dx)) DEALLOCATE(OutData%dx) + ALLOCATE(OutData%dx(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%dx.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + 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 + END IF + OutData%Jac_ny = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - OutData%g = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%rhoW = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%WtrDpth = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%kBot = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%cBot = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%dtM0 = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%dtCoupling = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - OutData%NumOuts = IntKiBuf(Int_Xferred) + OutData%Jac_nx = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - DO I = 1, LEN(OutData%RootName) - OutData%RootName(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! OutParam not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dxIdx_map2_xStateIdx not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%OutParam)) DEALLOCATE(OutData%OutParam) - ALLOCATE(OutData%OutParam(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%dxIdx_map2_xStateIdx)) DEALLOCATE(OutData%dxIdx_map2_xStateIdx) + ALLOCATE(OutData%dxIdx_map2_xStateIdx(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutParam.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%dxIdx_map2_xStateIdx.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%OutParam,1), UBOUND(OutData%OutParam,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL MD_Unpackoutparmtype( Re_Buf, Db_Buf, Int_Buf, OutData%OutParam(i1), ErrStat2, ErrMsg2 ) ! OutParam - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) - IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) - IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END DO + DO i1 = LBOUND(OutData%dxIdx_map2_xStateIdx,1), UBOUND(OutData%dxIdx_map2_xStateIdx,1) + OutData%dxIdx_map2_xStateIdx(i1) = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + END DO END IF - DO I = 1, LEN(OutData%Delim) - OutData%Delim(I:I) = CHAR(IntKiBuf(Int_Xferred)) - Int_Xferred = Int_Xferred + 1 - END DO ! I - OutData%MDUnOut = IntKiBuf(Int_Xferred) - Int_Xferred = Int_Xferred + 1 END SUBROUTINE MD_UnPackParam SUBROUTINE MD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) @@ -4727,9 +12856,22 @@ SUBROUTINE MD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" - CALL MeshCopy( SrcInputData%PtFairleadDisplacement, DstInputData%PtFairleadDisplacement, CtrlCode, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(SrcInputData%CoupledKinematics)) THEN + i1_l = LBOUND(SrcInputData%CoupledKinematics,1) + i1_u = UBOUND(SrcInputData%CoupledKinematics,1) + IF (.NOT. ALLOCATED(DstInputData%CoupledKinematics)) THEN + ALLOCATE(DstInputData%CoupledKinematics(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%CoupledKinematics.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcInputData%CoupledKinematics,1), UBOUND(SrcInputData%CoupledKinematics,1) + CALL MeshCopy( SrcInputData%CoupledKinematics(i1), DstInputData%CoupledKinematics(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcInputData%DeltaL)) THEN i1_l = LBOUND(SrcInputData%DeltaL,1) i1_u = UBOUND(SrcInputData%DeltaL,1) @@ -4756,16 +12898,34 @@ SUBROUTINE MD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) ENDIF END SUBROUTINE MD_CopyInput - SUBROUTINE MD_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE MD_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MD_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( InputData%PtFairleadDisplacement, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(InputData%CoupledKinematics)) THEN +DO i1 = LBOUND(InputData%CoupledKinematics,1), UBOUND(InputData%CoupledKinematics,1) + CALL MeshDestroy( InputData%CoupledKinematics(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(InputData%CoupledKinematics) +ENDIF IF (ALLOCATED(InputData%DeltaL)) THEN DEALLOCATE(InputData%DeltaL) ENDIF @@ -4809,24 +12969,30 @@ SUBROUTINE MD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! CoupledKinematics allocated yes/no + IF ( ALLOCATED(InData%CoupledKinematics) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! CoupledKinematics upper/lower bounds for each dimension ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! PtFairleadDisplacement: size of buffers for each call to pack subtype - CALL MeshPack( InData%PtFairleadDisplacement, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! PtFairleadDisplacement + DO i1 = LBOUND(InData%CoupledKinematics,1), UBOUND(InData%CoupledKinematics,1) + Int_BufSz = Int_BufSz + 3 ! CoupledKinematics: size of buffers for each call to pack subtype + CALL MeshPack( InData%CoupledKinematics(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! CoupledKinematics CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! PtFairleadDisplacement + IF(ALLOCATED(Re_Buf)) THEN ! CoupledKinematics Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! PtFairleadDisplacement + IF(ALLOCATED(Db_Buf)) THEN ! CoupledKinematics Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! PtFairleadDisplacement + IF(ALLOCATED(Int_Buf)) THEN ! CoupledKinematics Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + END IF Int_BufSz = Int_BufSz + 1 ! DeltaL allocated yes/no IF ( ALLOCATED(InData%DeltaL) ) THEN Int_BufSz = Int_BufSz + 2*1 ! DeltaL upper/lower bounds for each dimension @@ -4864,7 +13030,18 @@ SUBROUTINE MD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Db_Xferred = 1 Int_Xferred = 1 - CALL MeshPack( InData%PtFairleadDisplacement, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! PtFairleadDisplacement + IF ( .NOT. ALLOCATED(InData%CoupledKinematics) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CoupledKinematics,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CoupledKinematics,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%CoupledKinematics,1), UBOUND(InData%CoupledKinematics,1) + CALL MeshPack( InData%CoupledKinematics(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! CoupledKinematics CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -4892,6 +13069,8 @@ SUBROUTINE MD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + END DO + END IF IF ( .NOT. ALLOCATED(InData%DeltaL) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -4951,6 +13130,20 @@ SUBROUTINE MD_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CoupledKinematics not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%CoupledKinematics)) DEALLOCATE(OutData%CoupledKinematics) + ALLOCATE(OutData%CoupledKinematics(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CoupledKinematics.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%CoupledKinematics,1), UBOUND(OutData%CoupledKinematics,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -4984,13 +13177,15 @@ SUBROUTINE MD_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL MeshUnpack( OutData%PtFairleadDisplacement, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! PtFairleadDisplacement + CALL MeshUnpack( OutData%CoupledKinematics(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! CoupledKinematics 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 ! DeltaL not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -5044,9 +13239,22 @@ SUBROUTINE MD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs ! ErrStat = ErrID_None ErrMsg = "" - CALL MeshCopy( SrcOutputData%PtFairleadLoad, DstOutputData%PtFairleadLoad, CtrlCode, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(SrcOutputData%CoupledLoads)) THEN + i1_l = LBOUND(SrcOutputData%CoupledLoads,1) + i1_u = UBOUND(SrcOutputData%CoupledLoads,1) + IF (.NOT. ALLOCATED(DstOutputData%CoupledLoads)) THEN + ALLOCATE(DstOutputData%CoupledLoads(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%CoupledLoads.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcOutputData%CoupledLoads,1), UBOUND(SrcOutputData%CoupledLoads,1) + CALL MeshCopy( SrcOutputData%CoupledLoads(i1), DstOutputData%CoupledLoads(i1), CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF IF (ALLOCATED(SrcOutputData%WriteOutput)) THEN i1_l = LBOUND(SrcOutputData%WriteOutput,1) i1_u = UBOUND(SrcOutputData%WriteOutput,1) @@ -5061,16 +13269,34 @@ SUBROUTINE MD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs ENDIF END SUBROUTINE MD_CopyOutput - SUBROUTINE MD_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE MD_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MD_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MD_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( OutputData%PtFairleadLoad, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + +IF (ALLOCATED(OutputData%CoupledLoads)) THEN +DO i1 = LBOUND(OutputData%CoupledLoads,1), UBOUND(OutputData%CoupledLoads,1) + CALL MeshDestroy( OutputData%CoupledLoads(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(OutputData%CoupledLoads) +ENDIF IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF @@ -5111,24 +13337,30 @@ SUBROUTINE MD_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 + Int_BufSz = Int_BufSz + 1 ! CoupledLoads allocated yes/no + IF ( ALLOCATED(InData%CoupledLoads) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! CoupledLoads upper/lower bounds for each dimension ! Allocate buffers for subtypes, if any (we'll get sizes from these) - Int_BufSz = Int_BufSz + 3 ! PtFairleadLoad: size of buffers for each call to pack subtype - CALL MeshPack( InData%PtFairleadLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! PtFairleadLoad + DO i1 = LBOUND(InData%CoupledLoads,1), UBOUND(InData%CoupledLoads,1) + Int_BufSz = Int_BufSz + 3 ! CoupledLoads: size of buffers for each call to pack subtype + CALL MeshPack( InData%CoupledLoads(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! CoupledLoads CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN - IF(ALLOCATED(Re_Buf)) THEN ! PtFairleadLoad + IF(ALLOCATED(Re_Buf)) THEN ! CoupledLoads Re_BufSz = Re_BufSz + SIZE( Re_Buf ) DEALLOCATE(Re_Buf) END IF - IF(ALLOCATED(Db_Buf)) THEN ! PtFairleadLoad + IF(ALLOCATED(Db_Buf)) THEN ! CoupledLoads Db_BufSz = Db_BufSz + SIZE( Db_Buf ) DEALLOCATE(Db_Buf) END IF - IF(ALLOCATED(Int_Buf)) THEN ! PtFairleadLoad + IF(ALLOCATED(Int_Buf)) THEN ! CoupledLoads Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + END DO + 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 @@ -5161,7 +13393,18 @@ SUBROUTINE MD_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Db_Xferred = 1 Int_Xferred = 1 - CALL MeshPack( InData%PtFairleadLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! PtFairleadLoad + IF ( .NOT. ALLOCATED(InData%CoupledLoads) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%CoupledLoads,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%CoupledLoads,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%CoupledLoads,1), UBOUND(InData%CoupledLoads,1) + CALL MeshPack( InData%CoupledLoads(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! CoupledLoads CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -5189,6 +13432,8 @@ SUBROUTINE MD_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF + END DO + END IF IF ( .NOT. ALLOCATED(InData%WriteOutput) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -5233,6 +13478,20 @@ SUBROUTINE MD_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! CoupledLoads not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%CoupledLoads)) DEALLOCATE(OutData%CoupledLoads) + ALLOCATE(OutData%CoupledLoads(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%CoupledLoads.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%CoupledLoads,1), UBOUND(OutData%CoupledLoads,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -5266,13 +13525,15 @@ SUBROUTINE MD_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL MeshUnpack( OutData%PtFairleadLoad, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! PtFairleadLoad + CALL MeshUnpack( OutData%CoupledLoads(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! CoupledLoads 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 ! WriteOutput not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -5388,8 +13649,12 @@ SUBROUTINE MD_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg ) END IF ScaleFactor = t_out / t(2) - CALL MeshExtrapInterp1(u1%PtFairleadDisplacement, u2%PtFairleadDisplacement, tin, u_out%PtFairleadDisplacement, tin_out, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(u_out%CoupledKinematics) .AND. ALLOCATED(u1%CoupledKinematics)) THEN + DO i1 = LBOUND(u_out%CoupledKinematics,1),UBOUND(u_out%CoupledKinematics,1) + CALL MeshExtrapInterp1(u1%CoupledKinematics(i1), u2%CoupledKinematics(i1), tin, u_out%CoupledKinematics(i1), tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +END IF ! check if allocated IF (ALLOCATED(u_out%DeltaL) .AND. ALLOCATED(u1%DeltaL)) THEN DO i1 = LBOUND(u_out%DeltaL,1),UBOUND(u_out%DeltaL,1) b = -(u1%DeltaL(i1) - u2%DeltaL(i1)) @@ -5459,8 +13724,12 @@ SUBROUTINE MD_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, ErrM END IF ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) - CALL MeshExtrapInterp2(u1%PtFairleadDisplacement, u2%PtFairleadDisplacement, u3%PtFairleadDisplacement, tin, u_out%PtFairleadDisplacement, tin_out, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(u_out%CoupledKinematics) .AND. ALLOCATED(u1%CoupledKinematics)) THEN + DO i1 = LBOUND(u_out%CoupledKinematics,1),UBOUND(u_out%CoupledKinematics,1) + CALL MeshExtrapInterp2(u1%CoupledKinematics(i1), u2%CoupledKinematics(i1), u3%CoupledKinematics(i1), tin, u_out%CoupledKinematics(i1), tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +END IF ! check if allocated IF (ALLOCATED(u_out%DeltaL) .AND. ALLOCATED(u1%DeltaL)) THEN DO i1 = LBOUND(u_out%DeltaL,1),UBOUND(u_out%DeltaL,1) b = (t(3)**2*(u1%DeltaL(i1) - u2%DeltaL(i1)) + t(2)**2*(-u1%DeltaL(i1) + u3%DeltaL(i1)))* scaleFactor @@ -5572,8 +13841,12 @@ SUBROUTINE MD_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, ErrMsg END IF ScaleFactor = t_out / t(2) - CALL MeshExtrapInterp1(y1%PtFairleadLoad, y2%PtFairleadLoad, tin, y_out%PtFairleadLoad, tin_out, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(y_out%CoupledLoads) .AND. ALLOCATED(y1%CoupledLoads)) THEN + DO i1 = LBOUND(y_out%CoupledLoads,1),UBOUND(y_out%CoupledLoads,1) + CALL MeshExtrapInterp1(y1%CoupledLoads(i1), y2%CoupledLoads(i1), tin, y_out%CoupledLoads(i1), tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +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)) @@ -5637,8 +13910,12 @@ SUBROUTINE MD_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, Err END IF ScaleFactor = t_out / (t(2) * t(3) * (t(2) - t(3))) - CALL MeshExtrapInterp2(y1%PtFairleadLoad, y2%PtFairleadLoad, y3%PtFairleadLoad, tin, y_out%PtFairleadLoad, tin_out, ErrStat2, ErrMsg2 ) +IF (ALLOCATED(y_out%CoupledLoads) .AND. ALLOCATED(y1%CoupledLoads)) THEN + DO i1 = LBOUND(y_out%CoupledLoads,1),UBOUND(y_out%CoupledLoads,1) + CALL MeshExtrapInterp2(y1%CoupledLoads(i1), y2%CoupledLoads(i1), y3%CoupledLoads(i1), tin, y_out%CoupledLoads(i1), tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + ENDDO +END IF ! check if allocated IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN DO i1 = LBOUND(y_out%WriteOutput,1),UBOUND(y_out%WriteOutput,1) b = (t(3)**2*(y1%WriteOutput(i1) - y2%WriteOutput(i1)) + t(2)**2*(-y1%WriteOutput(i1) + y3%WriteOutput(i1)))* scaleFactor diff --git a/modules/moordyn/src/MoorDyn_bathymetry.txt b/modules/moordyn/src/MoorDyn_bathymetry.txt new file mode 100644 index 000000000..bfe4ffbbb --- /dev/null +++ b/modules/moordyn/src/MoorDyn_bathymetry.txt @@ -0,0 +1,8 @@ +--- MoorDyn Bathymetry Input File --- +nGridX 4 +nGridY 4 + -800 -10 10 800 +-800 400 400 500 500 + -10 400 400 500 500 + 10 600 600 600 600 + 800 600 600 600 600 \ No newline at end of file diff --git a/modules/nwtc-library/CMakeLists.txt b/modules/nwtc-library/CMakeLists.txt index 6883581a0..8074c3d7d 100644 --- a/modules/nwtc-library/CMakeLists.txt +++ b/modules/nwtc-library/CMakeLists.txt @@ -14,20 +14,67 @@ # limitations under the License. # +#------------------------------------------------------------------------------- +# NWTC System File +#------------------------------------------------------------------------------- + +if (${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU") + if (WIN32) + set(NWTC_SYS_FILE src/SysGnuWin.f90) + set(NWTC_SYS_FILE_MATLAB ${CMAKE_CURRENT_SOURCE_DIR}/src/SysMatlabWindows.f90) + elseif (APPLE OR UNIX OR CYGWIN) + set(NWTC_SYS_FILE src/SysGnuLinux.f90) + set(NWTC_SYS_FILE_MATLAB ${CMAKE_CURRENT_SOURCE_DIR}/src/SysMatlabLinuxGnu.f90) + endif () +elseif (${CMAKE_Fortran_COMPILER_ID} MATCHES "^Intel") + if (APPLE OR UNIX) + set(NWTC_SYS_FILE src/SysIFL.f90) + set(NWTC_SYS_FILE_MATLAB ${CMAKE_CURRENT_SOURCE_DIR}/src/SysMatlabLinuxIntel.f90) + elseif (WIN32) + set(NWTC_SYS_FILE src/SysIVF.f90) + set(NWTC_SYS_FILE_MATLAB ${CMAKE_CURRENT_SOURCE_DIR}/src/SysMatlabWindows.f90) + endif (APPLE OR UNIX) +elseif (${CMAKE_Fortran_COMPILER_ID} STREQUAL "Flang") + if(APPLE OR UNIX) + set(NWTC_SYS_FILE src/SysFlangLinux.f90) + endif() +endif () + +# System file +if (NWTC_SYS_FILE) + message("-- Setting system file as: ${NWTC_SYS_FILE}") +else () + message(FATAL_ERROR "Cannot determine system file used with NWTC_Library") +endif () + +#------------------------------------------------------------------------------- +# NWTC Library +#------------------------------------------------------------------------------- + set(NWTCLIBS_SOURCES + + src/NWTC_Base.f90 + src/SingPrec.f90 + src/ModMesh.f90 src/ModMesh_Mapping.f90 src/ModMesh_Types.f90 - src/NWTC_Base.f90 + src/NWTC_IO.f90 src/NWTC_Library.f90 src/NWTC_Num.f90 src/NWTC_RandomNumber.f90 - src/SingPrec.f90 + src/NWTC_Library_Types.f90 + src/VTK.f90 + src/YAML.f90 + src/JSON.f90 # RanLux sources src/ranlux/RANLUX.f90 + + # Public Domain Aeronautical Software (PDAS) Polynomial Root Finder + src/Polynomial/quartic.f90 # NetLib sources src/NetLib/fftpack/fftpack4.1.f @@ -51,7 +98,8 @@ set(NWTCLIBS_SOURCES src/NetLib/slatec/i1mach.f src/NetLib/slatec/j4save.f src/NetLib/slatec/xgetua.f - src/NetLib/slatec/xermsg.f ) + src/NetLib/slatec/xermsg.f +) get_filename_component(FCNAME ${CMAKE_Fortran_COMPILER} NAME) @@ -85,52 +133,66 @@ if (CMAKE_BUILD_TYPE MATCHES Debug) endif() endif() endif() -endif() +endif() +# Create NWTC Library +add_library(nwtclibs ${NWTC_SYS_FILE} ${NWTCLIBS_SOURCES}) +target_link_libraries(nwtclibs PUBLIC + ${LAPACK_LIBRARIES} + ${CMAKE_DL_LIBS} + ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES} +) +if (USE_DLL_INTERFACE) + target_compile_definitions(nwtclibs PRIVATE USE_DLL_INTERFACE) +endif (USE_DLL_INTERFACE) +if (USE_LOCAL_STATIC_LAPACK) + add_dependencies(nwtclibs lapack) +endif() -if(BUILD_OPENFAST_SIMULINK_API) +# Install libraries +install(TARGETS nwtclibs + EXPORT "${CMAKE_PROJECT_NAME}Libraries" + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) - if (APPLE OR UNIX) - if (${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU") - set(NWTC_SYS_FILE src/SysMatlabLinuxGnu.f90) - elseif (${CMAKE_Fortran_COMPILER_ID} MATCHES "^Intel") - set(NWTC_SYS_FILE src/SysMatlabLinuxIntel.f90) - endif() - elseif (WIN32) - set(NWTC_SYS_FILE src/SysMatlabWindows.f90) - endif() +#------------------------------------------------------------------------------- +# NWTC Library for MATLAB +#------------------------------------------------------------------------------- -elseif (${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU") - if (WIN32) - set(NWTC_SYS_FILE src/SysGnuWin.f90) - elseif (APPLE OR UNIX OR CYGWIN) - set(NWTC_SYS_FILE src/SysGnuLinux.f90) +if (BUILD_OPENFAST_SIMULINK_API) + + # Check that matlab system file was found + if (NWTC_SYS_FILE_MATLAB) + message("-- Setting Matlab system file as: ${NWTC_SYS_FILE_MATLAB}") + message(STATUS "In NWTC Matlab_MEX_LIBRARY: ${Matlab_MEX_LIBRARY}") + else () + message(FATAL_ERROR "Cannot determine Matlab system file used with NWTC_Library") endif () -elseif (${CMAKE_Fortran_COMPILER_ID} MATCHES "^Intel") - if (APPLE OR UNIX) - set(NWTC_SYS_FILE src/SysIFL.f90) - elseif (WIN32) - set(NWTC_SYS_FILE src/SysIVF.f90) - endif (APPLE OR UNIX) -endif () -if (NWTC_SYS_FILE) - message("-- Setting system file as: ${NWTC_SYS_FILE}") - list(APPEND NWTCLIBS_SOURCES ${NWTC_SYS_FILE}) -else (NWTC_SYS_FILE) - message(FATAL_ERROR "Cannot determine system file used with NWTC_Library") -endif (NWTC_SYS_FILE) - -add_library(nwtclibs ${NWTCLIBS_SOURCES}) + # NWTC Library with MATLAB system file + add_library(nwtclibs-matlab ${NWTC_SYS_FILE_MATLAB} ${NWTCLIBS_SOURCES}) + set_target_properties(nwtclibs-matlab PROPERTIES + Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/matlab) + if (USE_DLL_INTERFACE) + target_compile_definitions(nwtclibs-matlab PRIVATE USE_DLL_INTERFACE) + endif (USE_DLL_INTERFACE) + target_link_libraries(nwtclibs-matlab PUBLIC + ${LAPACK_LIBRARIES} + ${CMAKE_DL_LIBS} + ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES} + ) + if (USE_LOCAL_STATIC_LAPACK) + add_dependencies(nwtclibs lapack) + endif() -if(BUILD_OPENFAST_SIMULINK_API) - find_package(Matlab REQUIRED) - target_link_libraries(nwtclibs ${LAPACK_LIBRARIES} ${CMAKE_DL_LIBS} ${Matlab_MEX_LIBRARY}) -else() - target_link_libraries(nwtclibs ${LAPACK_LIBRARIES} ${CMAKE_DL_LIBS}) -endif() + # Install matlab nwtc libraries + install(TARGETS nwtclibs-matlab + EXPORT "${CMAKE_PROJECT_NAME}Libraries" + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + ) +endif () -install(TARGETS nwtclibs - EXPORT "${CMAKE_PROJECT_NAME}Libraries" - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) diff --git a/modules/nwtc-library/src/JSON.f90 b/modules/nwtc-library/src/JSON.f90 new file mode 100644 index 000000000..f672c1a05 --- /dev/null +++ b/modules/nwtc-library/src/JSON.f90 @@ -0,0 +1,170 @@ +!.................................................................................................................................. +! LICENSING +! Copyright (C) 2013-2016 National Renewable Energy Laboratory +! +! This file is part of NWTC_Library. +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +! +!********************************************************************************************************************************** +module JSON + use Precision, only: IntKi, SiKi, R8Ki + use NWTC_Base, only: ErrID_None, ErrID_Fatal + use NWTC_IO, only: num2lstr + + implicit none + + !> Write 2D array to file in JSON format + interface json_write_array + module procedure json_write_array2R4 ! Two dimension array of SiKi + module procedure json_write_array2I ! Two dimension array of IntKi + module procedure json_write_array2R8 ! Two dimension array of R8Ki + end interface + + private + + public :: json_write_array + +contains + + +! --------------------------------------------------------------------------------} +! --- Write Array 2D +! --------------------------------------------------------------------------------{ +subroutine json_write_array2I(fid, key, A, VarFmt, ErrStat, ErrMsg) + 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 :: nr, nc, i ! size (rows and columns) of A + character(256) :: Fmt + ErrStat = ErrID_None + ErrMsg = "" + nr = size(A,1) + nc = size(A,2) + + ! Key + write(fid, '(A,": [")', iostat=ErrStat, advance='no') trim(key) + if (nr==0) then + write(fid, '("[]]")', iostat=ErrStat) + else + ! JSON Line format + if (nc==1) then + Fmt = '("[",'//VarFmt//',"],")' + else + Fmt = '("[",'//trim(Num2LStr(nc-1))//'('//VarFmt//',","),'//VarFmt//',"]")' + endif + ! Write line by line + do i=1,nr + write(fid, Fmt, iostat=ErrStat, advance='no') A(i,:) + if (i This routine writes mesh information in text form. It is used for debugging. - SUBROUTINE MeshPrintInfo ( U, M, N) + SUBROUTINE MeshPrintInfo ( U, M, N, MeshName) INTEGER, INTENT(IN ) :: U !< fortran output unit TYPE(MeshType),INTENT(IN ) :: M !< mesh to be reported on INTEGER, OPTIONAL,INTENT(IN ) :: N !< Number to print, default is all nodes + character(*), optional, intent(in ) :: MeshName !< name of the mesh ! Local INTEGER isz,i,j,nn,Ielement,Xelement nn = M%Nnodes !5 IF (PRESENT(N)) nn = min(nn,N) - write(U,*)'----------- MeshPrintInfo: -------------' + if (present(MeshName)) then + write(U,*)'----------- MeshPrintInfo: '//trim(MeshName)//' -------------' + else + write(U,*)'----------- MeshPrintInfo: -------------' + endif write(U,*) 'Initialized: ', M%initialized write(U,*) 'Committed: ', M%Committed @@ -3072,24 +3078,24 @@ SUBROUTINE PackMotionMesh_Names(M, MeshName, Names, indx_first, FieldMask) END SUBROUTINE PackMotionMesh_Names +!............................................................................................................................... !> This subroutine returns the operating point values of the mesh fields. It assumes all fields marked !! by FieldMask are allocated; Some fields may be allocated by the ModMesh module and not used in !! the linearization procedure, thus I am not using the check if they are allocated to determine if they should be included. - SUBROUTINE PackMotionMesh(M, Ary, indx_first, FieldMask, UseSmlAngle) + SUBROUTINE PackMotionMesh(M, Ary, indx_first, FieldMask, TrimOP) TYPE(MeshType) , INTENT(IN ) :: M !< Motion mesh REAL(ReKi) , INTENT(INOUT) :: Ary(:) !< array to pack this mesh into INTEGER(IntKi) , INTENT(INOUT) :: indx_first !< index into Ary; gives location of next array position to fill LOGICAL, OPTIONAL , INTENT(IN ) :: FieldMask(FIELDMASK_SIZE) !< flags to determine if this field is part of the packing - LOGICAL, OPTIONAL , INTENT(IN ) :: UseSmlAngle !< flag to determine if the orientation should be packed as a DCM or a log map + LOGICAL, OPTIONAL , INTENT(IN ) :: TrimOP !< flag to determine if the orientation should be packed as a DCM or a log map ! local variables: INTEGER(IntKi) :: i, j, k LOGICAL :: Mask(FIELDMASK_SIZE) !< flags to determine if this field is part of the packing - LOGICAL :: OutputSmlAngle - !REAL(R8Ki) :: logmap(3) !< array to pack logmaps into - REAL(R8Ki) :: angles(3) !< array to pack logmaps into + LOGICAL :: PackForTrimSolution + REAL(R8Ki) :: logmap(3) !< array to pack dcm vector representation (logmaps) into INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 @@ -3100,6 +3106,12 @@ SUBROUTINE PackMotionMesh(M, Ary, indx_first, FieldMask, UseSmlAngle) Mask = .true. end if + if (present(TrimOP)) then + PackForTrimSolution = TrimOP + else + PackForTrimSolution = .false. + end if + if (Mask(MASKID_TRANSLATIONDISP)) then do i=1,M%NNodes @@ -3111,19 +3123,12 @@ SUBROUTINE PackMotionMesh(M, Ary, indx_first, FieldMask, UseSmlAngle) end if if (Mask(MASKID_ORIENTATION)) then - if (present(UseSmlAngle)) then - OutputSmlAngle = UseSmlAngle - else - OutputSmlAngle = .false. - end if - if (OutputSmlAngle) then + if (PackForTrimSolution) then do i=1,M%NNodes - !call DCM_logMap(M%Orientation(:,:,i), logmap, ErrStat2, ErrMsg2) - angles = GetSmllRotAngs ( M%Orientation(:,:,i), ErrStat2, ErrMsg2 ) + call DCM_logMap(M%Orientation(:,:,i), logmap, ErrStat2, ErrMsg2) !NOTE: we cannot use GetSmllRotAngs because we CANNOT assume that all DCMs in the code are small. do k=1,3 - !Ary(indx_first) = logmap(k) - Ary(indx_first) = angles(k) + Ary(indx_first) = logmap(k) indx_first = indx_first + 1 end do end do @@ -3149,6 +3154,7 @@ SUBROUTINE PackMotionMesh(M, Ary, indx_first, FieldMask, UseSmlAngle) end if if (Mask(MASKID_ROTATIONVEL)) then + do i=1,M%NNodes do j=1,3 Ary(indx_first) = M%RotationVel(j,i) @@ -3162,17 +3168,27 @@ SUBROUTINE PackMotionMesh(M, Ary, indx_first, FieldMask, UseSmlAngle) do j=1,3 Ary(indx_first) = M%TranslationAcc(j,i) indx_first = indx_first + 1 - end do + end do end do end if if (Mask(MASKID_ROTATIONACC)) then - do i=1,M%NNodes - do j=1,3 - Ary(indx_first) = M%RotationAcc(j,i) - indx_first = indx_first + 1 - end do - end do + if (PackForTrimSolution) then ! these are difficult to converge in a trim solution + do i=1,M%NNodes + do j=1,3 + Ary(indx_first) = 0.0_ReKi + indx_first = indx_first + 1 + end do + end do + else + do i=1,M%NNodes + do j=1,3 + Ary(indx_first) = M%RotationAcc(j,i) + indx_first = indx_first + 1 + end do + end do + end if + end if @@ -3577,6 +3593,58 @@ SUBROUTINE MeshExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, ErrMsg ) END SUBROUTINE MeshExtrapInterp2 +!............................................................................................................................... +!> High level function to easily create a point mesh with one node and one element + SUBROUTINE CreatePointMesh(mesh, posInit, orientInit, errStat, errMsg, hasMotion, hasLoads, hasAcc) + type(MeshType), intent(inout) :: mesh !< Mesh to be created + real(ReKi), intent(in ) :: PosInit(3) !< Xi,Yi,Zi, coordinates of node + real(R8Ki), intent(in ) :: orientInit(3,3) !< Orientation (direction cosine matrix) of node; identity by default + logical, intent(in ) :: hasMotion !< include displacements in mesh + logical, intent(in ) :: hasLoads !< include loads in mesh + logical, optional, intent(in ) :: hasAcc !< include acceleration (default is true) + integer(IntKi) , intent(out) :: errStat ! Status of error message + character(*) , intent(out) :: errMsg ! Error message if ErrStat /= ErrID_None + logical :: hasAcc_loc !< include acceleration + integer(IntKi) :: errStat2 ! local status of error message + character(ErrMsgLen) :: errMsg2 ! local error message if ErrStat /= ErrID_None + errStat = ErrID_None + errMsg = '' + hasAcc_loc = .true. + if (present(hasAcc)) hasAcc_loc=hasAcc + + call MeshCreate(mesh, COMPONENT_INPUT, 1, errStat2, errMsg2, & + Orientation=hasMotion, TranslationDisp=hasMotion, TranslationVel=hasMotion, RotationVel=hasMotion, & + TranslationAcc=hasAcc_loc, RotationAcc=hasAcc_loc, & + Force = hasLoads, Moment = hasLoads) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'CreatePointMesh') + if (ErrStat >= AbortErrLev) return + + call MeshPositionNode(mesh, 1, posInit, errStat2, errMsg2, orientInit); + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'CreatePointMesh') + + call MeshConstructElement(mesh, ELEMENT_POINT, errStat2, errMsg2, p1=1); + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'CreatePointMesh') + + call MeshCommit(mesh, errStat2, errMsg2); + call SetErrStat(errStat2, errMsg2, errStat, errMsg, 'CreatePointMesh') + + ! Initialize fields + if (hasLoads) then + mesh%Force = 0.0_ReKi + mesh%Moment = 0.0_ReKi + endif + if (hasMotion) then + mesh%Orientation = mesh%RefOrientation + mesh%TranslationDisp = 0.0_ReKi + mesh%TranslationVel = 0.0_ReKi + mesh%RotationVel = 0.0_ReKi + endif + if (hasAcc_loc) then + mesh%TranslationAcc = 0.0_ReKi + mesh%RotationAcc = 0.0_ReKi + endif + + END SUBROUTINE CreatePointMesh !---------------------------------------------------------------------------------------------------------------------------------- END MODULE ModMesh diff --git a/modules/nwtc-library/src/ModMesh_Mapping.f90 b/modules/nwtc-library/src/ModMesh_Mapping.f90 index 6a56316bc..df2723a60 100644 --- a/modules/nwtc-library/src/ModMesh_Mapping.f90 +++ b/modules/nwtc-library/src/ModMesh_Mapping.f90 @@ -36,15 +36,15 @@ MODULE ModMesh_Mapping !bjj: these types require the use of ModMesh.f90, thus they cannot be part of NWTC_Library_Types.f90 (though they are auto_generated with that code): - !> Type that describes characteristics of the mapping between two meshes + !> Type that describes characteristics of the mapping between two meshes TYPE, PUBLIC :: MapType - INTEGER(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 - REAL(R8Ki) :: distance !< magnitude of couple_arm - REAL(R8Ki) :: couple_arm(3) !< Vector between a point and node 1 of an element (p_ODR - p_OSR) - REAL(R8Ki) :: shape_fn(2) !< shape functions: 1-D element-level location [0,1] based on closest-line projection of point + INTEGER(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 [-] + REAL(R8Ki) :: distance !< magnitude of couple_arm [m] + REAL(R8Ki) :: couple_arm(3) !< Vector between a point and node 1 of an element (p_ODR - p_OSR) [m] + REAL(R8Ki) :: shape_fn(2) !< shape functions: 1-D element-level location [0,1] based on closest-line projection of point [-] END TYPE MapType - !> data structures (for linearization) containing jacobians of mapping between fields on different meshes + !> data structures (for linearization) containing jacobians of mapping between fields on different meshes TYPE, PUBLIC :: MeshMapLinearizationType ! values for motions: REAL(R8Ki), ALLOCATABLE :: mi(:,:) !< block matrix of motions that reflects identity (i.e., solely the mapping of one quantity to itself on another mesh) [-] @@ -62,21 +62,21 @@ MODULE ModMesh_Mapping END TYPE MeshMapLinearizationType - !> data structures to determine full mapping between fields on different meshes + !> data structures to determine full mapping between fields on different meshes TYPE, PUBLIC :: MeshMapType - TYPE(MapType), ALLOCATABLE :: MapLoads(:) !< mapping data structure for loads on the mesh + TYPE(MapType), ALLOCATABLE :: MapLoads(:) !< mapping data structure for loads on the mesh [-] TYPE(MapType), ALLOCATABLE :: MapMotions(:) !< mapping data structure for motions and/or scalars on the mesh [-] - TYPE(MapType), ALLOCATABLE :: MapSrcToAugmt(:) !< for source line2 loads, we map between source and an augmented source mesh, then between augmented source and destination - TYPE(MeshType) :: Augmented_Ln2_Src !< the augmented source mesh needed for some mapping types - TYPE(MeshType) :: Lumped_Points_Src !< a lumped mesh needed for some mapping types, stored here for efficiency + TYPE(MapType), ALLOCATABLE :: MapSrcToAugmt(:) !< for source line2 loads, we map between source and an augmented source mesh, then between augmented source and destination [-] + TYPE(MeshType) :: Augmented_Ln2_Src !< the augmented source mesh needed for some mapping types [-] + TYPE(MeshType) :: Lumped_Points_Src !< a lumped mesh needed for some mapping types, stored here for efficiency [-] #ifdef MESH_DEBUG TYPE(MeshType) :: Lumped_Points_Dest #endif - INTEGER, ALLOCATABLE :: LoadLn2_A_Mat_Piv(:) !< The pivot values for the factorization of LoadLn2_A_Mat - REAL(R8Ki), ALLOCATABLE :: DisplacedPosition(:,:,:) !< couple_arm +Scr%Disp - Dest%Disp for each mapped node (stored here for efficiency) - REAL(R8Ki), ALLOCATABLE :: LoadLn2_A_Mat(:,:) !< The n-by-n (n=3xNNodes) matrix that makes up the diagonal of the [A 0; B A] matrix in the point-to-line load mapping - REAL(R8Ki), ALLOCATABLE :: LoadLn2_F(:,:) !< The 3-components of the forces for each node of an element in the point-to-line load mapping (for each element) - REAL(R8Ki), ALLOCATABLE :: LoadLn2_M(:,:) !< The 3-components of the moments for each node of an element in the point-to-line load mapping (for each element) + INTEGER, ALLOCATABLE :: LoadLn2_A_Mat_Piv(:) !< The pivot values for the factorization of LoadLn2_A_Mat [-] + REAL(R8Ki), ALLOCATABLE :: DisplacedPosition(:,:,:) !< couple_arm +Scr%Disp - Dest%Disp for each mapped node (stored here for efficiency) [m] + REAL(R8Ki), ALLOCATABLE :: LoadLn2_A_Mat(:,:) !< The n-by-n (n=3xNNodes) matrix that makes up the diagonal of the [A 0; B A] matrix in the point-to-line load mapping [-] + REAL(R8Ki), ALLOCATABLE :: LoadLn2_F(:,:) !< The 3-components of the forces for each node of an element in the point-to-line load mapping (for each element) [-] + REAL(R8Ki), ALLOCATABLE :: LoadLn2_M(:,:) !< The 3-components of the moments for each node of an element in the point-to-line load mapping (for each element) [-] TYPE(MeshMapLinearizationType) :: dM !< type that contains information for linearization matrices, partial M partial u (or y) END TYPE MeshMapType @@ -2482,7 +2482,7 @@ SUBROUTINE Transfer_Point_to_Point( Src, Dest, MeshMap, ErrStat, ErrMsg, SrcDisp !! IF Src is forces and/or moments, loop over Src Mesh; !! each load in the source mesh needs to be placed somewhere in the destination mesh. - if ( HasLoadFields(Src) ) then + if ( HasLoadFields(Src) .AND. HasLoadFields(Dest) ) then !........................ ! Create mapping @@ -5763,10 +5763,10 @@ END SUBROUTINE WriteMappingTransferToFile !bjj: these routines require the use of ModMesh.f90, thus they cannot be part of NWTC_Library_Types.f90: !STARTOFREGISTRYGENERATEDFILE 'NWTC_Library_Types.f90' ! -! WARNING This file is generated automatically by the FAST registry +! WARNING This file is generated automatically by the FAST registry. ! Do not edit. Your changes to this file will be lost. ! -! FAST Registry (v3.02.00, 23-Jul-2016) +! FAST Registry !********************************************************************************************************************************* SUBROUTINE NWTC_Library_CopyMapType( SrcMapTypeData, DstMapTypeData, CtrlCode, ErrStat, ErrMsg ) TYPE(MapType), INTENT(IN) :: SrcMapTypeData @@ -5791,15 +5791,27 @@ SUBROUTINE NWTC_Library_CopyMapType( SrcMapTypeData, DstMapTypeData, CtrlCode, E DstMapTypeData%shape_fn = SrcMapTypeData%shape_fn END SUBROUTINE NWTC_Library_CopyMapType - SUBROUTINE NWTC_Library_DestroyMapType( MapTypeData, ErrStat, ErrMsg ) + SUBROUTINE NWTC_Library_DestroyMapType( MapTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MapType), INTENT(INOUT) :: MapTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyMapType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyMapType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE NWTC_Library_DestroyMapType SUBROUTINE NWTC_Library_PackMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -6101,15 +6113,27 @@ SUBROUTINE NWTC_Library_CopyMeshMapLinearizationType( SrcMeshMapLinearizationTyp ENDIF END SUBROUTINE NWTC_Library_CopyMeshMapLinearizationType - SUBROUTINE NWTC_Library_DestroyMeshMapLinearizationType( MeshMapLinearizationTypeData, ErrStat, ErrMsg ) + SUBROUTINE NWTC_Library_DestroyMeshMapLinearizationType( MeshMapLinearizationTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MeshMapLinearizationType), INTENT(INOUT) :: MeshMapLinearizationTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyMeshMapLinearizationType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyMeshMapLinearizationType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MeshMapLinearizationTypeData%mi)) THEN DEALLOCATE(MeshMapLinearizationTypeData%mi) ENDIF @@ -6913,35 +6937,52 @@ SUBROUTINE NWTC_Library_CopyMeshMapType( SrcMeshMapTypeData, DstMeshMapTypeData, IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE NWTC_Library_CopyMeshMapType - SUBROUTINE NWTC_Library_DestroyMeshMapType( MeshMapTypeData, ErrStat, ErrMsg ) + SUBROUTINE NWTC_Library_DestroyMeshMapType( MeshMapTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MeshMapType), INTENT(INOUT) :: MeshMapTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyMeshMapType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyMeshMapType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MeshMapTypeData%MapLoads)) THEN DO i1 = LBOUND(MeshMapTypeData%MapLoads,1), UBOUND(MeshMapTypeData%MapLoads,1) - CALL NWTC_Library_Destroymaptype( MeshMapTypeData%MapLoads(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymaptype( MeshMapTypeData%MapLoads(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MeshMapTypeData%MapLoads) ENDIF IF (ALLOCATED(MeshMapTypeData%MapMotions)) THEN DO i1 = LBOUND(MeshMapTypeData%MapMotions,1), UBOUND(MeshMapTypeData%MapMotions,1) - CALL NWTC_Library_Destroymaptype( MeshMapTypeData%MapMotions(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymaptype( MeshMapTypeData%MapMotions(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MeshMapTypeData%MapMotions) ENDIF IF (ALLOCATED(MeshMapTypeData%MapSrcToAugmt)) THEN DO i1 = LBOUND(MeshMapTypeData%MapSrcToAugmt,1), UBOUND(MeshMapTypeData%MapSrcToAugmt,1) - CALL NWTC_Library_Destroymaptype( MeshMapTypeData%MapSrcToAugmt(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymaptype( MeshMapTypeData%MapSrcToAugmt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MeshMapTypeData%MapSrcToAugmt) ENDIF - CALL MeshDestroy( MeshMapTypeData%Augmented_Ln2_Src, ErrStat, ErrMsg ) - CALL MeshDestroy( MeshMapTypeData%Lumped_Points_Src, ErrStat, ErrMsg ) + CALL MeshDestroy( MeshMapTypeData%Augmented_Ln2_Src, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( MeshMapTypeData%Lumped_Points_Src, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MeshMapTypeData%LoadLn2_A_Mat_Piv)) THEN DEALLOCATE(MeshMapTypeData%LoadLn2_A_Mat_Piv) ENDIF @@ -6957,7 +6998,8 @@ SUBROUTINE NWTC_Library_DestroyMeshMapType( MeshMapTypeData, ErrStat, ErrMsg ) IF (ALLOCATED(MeshMapTypeData%LoadLn2_M)) THEN DEALLOCATE(MeshMapTypeData%LoadLn2_M) ENDIF - CALL NWTC_Library_Destroymeshmaplinearizationtype( MeshMapTypeData%dM, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaplinearizationtype( MeshMapTypeData%dM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE NWTC_Library_DestroyMeshMapType SUBROUTINE NWTC_Library_PackMeshMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) diff --git a/modules/nwtc-library/src/NWTC_Base.f90 b/modules/nwtc-library/src/NWTC_Base.f90 index 6690f0842..2ccec45fb 100644 --- a/modules/nwtc-library/src/NWTC_Base.f90 +++ b/modules/nwtc-library/src/NWTC_Base.f90 @@ -36,6 +36,8 @@ MODULE NWTC_Base INTEGER, PARAMETER :: ErrMsgLen = 1024 !< The maximum number of characters in an error message in the FAST framework INTEGER(IntKi), PARAMETER :: ChanLen = 20 !< The maximum allowable length of channel names (i.e., width of output columns) in the FAST framework + INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 !< The maximum allowable length of channel names without optional "-" or "M" at the beginning to indicate the negative of the channel + INTEGER(IntKi), PARAMETER :: MinChanLen = 10 !< The min allowable length of channel names (i.e., width of output columns), used because some modules (like Bladed DLL outputs) have excessively long names INTEGER(IntKi), PARAMETER :: LinChanLen = 200 !< The allowable length of row/column names in linearization files INTEGER(IntKi), PARAMETER :: MaxFileInfoLineLen = 1024 !< The allowable length of an input line stored in FileInfoType%Lines @@ -56,16 +58,23 @@ MODULE NWTC_Base INTEGER(IntKi), PARAMETER :: NWTC_MAX_DLL_PROC = 5 !< maximum number of procedures that can be dynamically loaded from a DLL (see DLL_Type nwtc_base::dll_type) +#ifdef FLANG_COMPILER + TYPE(C_FUNPTR), PARAMETER :: NULL_PROC_ADDR(NWTC_MAX_DLL_PROC) = C_NULL_FUNPTR !< this is a hack so the Flang compiler will initialize ProcAddr to C_NULL_FUNPTR in DLL_Type (remove if no longer needed) +#endif !> Type definition for dynamically loaded libraries: !! Note that changes here may need to be reflected in DLLTypePack() (nwtc_io::dlltypepack) DLLTypeUnPack() (nwtc_io::dlltypeunpack), !! and the FAST Registry executable. - + TYPE DLL_Type - INTEGER(C_INTPTR_T) :: FileAddr !< The address of file FileName. (RETURN value from LoadLibrary ) [Windows] + INTEGER(C_INTPTR_T) :: FileAddr = INT(0,C_INTPTR_T) !< The address of file FileName. (RETURN value from LoadLibrary ) [Windows] TYPE(C_PTR) :: FileAddrX = C_NULL_PTR !< The address of file FileName. (RETURN value from dlopen ) [Linux] - TYPE(C_FUNPTR) :: ProcAddr(NWTC_MAX_DLL_PROC) = C_NULL_FUNPTR !< The address of procedure ProcName. (RETURN value from GetProcAddress or dlsym) [initialized to Null for pack/unpack] +#ifdef FLANG_COMPILER + TYPE(C_FUNPTR) :: ProcAddr(NWTC_MAX_DLL_PROC) = NULL_PROC_ADDR !< The address of procedure ProcName. (RETURN value from GetProcAddress or dlsym) [initialized to Null for pack/unpack] +#else + TYPE(C_FUNPTR) :: ProcAddr(NWTC_MAX_DLL_PROC) = C_NULL_FUNPTR !< The address of procedure ProcName. (RETURN value from GetProcAddress or dlsym) [initialized to Null for pack/unpack] +#endif CHARACTER(1024) :: FileName !< The name of the DLL file including the full path to the current working directory. CHARACTER(1024) :: ProcName(NWTC_MAX_DLL_PROC) = "" !< The name of the procedure in the DLL that will be called. diff --git a/modules/nwtc-library/src/NWTC_IO.f90 b/modules/nwtc-library/src/NWTC_IO.f90 index 7be142eec..231b7e4a3 100644 --- a/modules/nwtc-library/src/NWTC_IO.f90 +++ b/modules/nwtc-library/src/NWTC_IO.f90 @@ -103,23 +103,16 @@ MODULE NWTC_IO MODULE PROCEDURE AllLAry2 MODULE PROCEDURE AllLAry3 ! MODULE PROCEDURE AllLAry4 Not yet coded. - MODULE PROCEDURE AllR4Ary1 ! 1-dimensional array of SiKi reals - MODULE PROCEDURE AllR8Ary1 ! 1-dimensional array of R8Ki reals - MODULE PROCEDURE AllR16Ary1 ! 1-dimensional array of QuKi reals MODULE PROCEDURE AllR4Ary2 ! 2-dimensional array of SiKi reals - MODULE PROCEDURE AllR8Ary2 ! 2-dimensional array of R8Ki reals - MODULE PROCEDURE AllR16Ary2 ! 2-dimensional array of QuKi reals - MODULE PROCEDURE AllR4Ary3 ! 3-dimensional array of SiKi reals - MODULE PROCEDURE AllR8Ary3 ! 3-dimensional array of R8Ki reals - MODULE PROCEDURE AllR16Ary3 ! 3-dimensional array of QuKi reals MODULE PROCEDURE AllR4Ary4 ! 4-dimensional array of SiKi reals - MODULE PROCEDURE AllR8Ary4 ! 4-dimensional array of R8Ki reals - MODULE PROCEDURE AllR16Ary4 ! 4-dimensional array of QuKi reals MODULE PROCEDURE AllR4Ary5 ! 5-dimensional array of SiKi reals + MODULE PROCEDURE AllR8Ary1 ! 1-dimensional array of R8Ki reals + MODULE PROCEDURE AllR8Ary2 ! 2-dimensional array of R8Ki reals + MODULE PROCEDURE AllR8Ary3 ! 3-dimensional array of R8Ki reals + MODULE PROCEDURE AllR8Ary4 ! 4-dimensional array of R8Ki reals MODULE PROCEDURE AllR8Ary5 ! 5-dimensional array of R8Ki reals - MODULE PROCEDURE AllR16Ary5 ! 5-dimensional array of QuKi reals END INTERFACE !> \copydoc nwtc_io::allipary1 @@ -130,7 +123,6 @@ MODULE NWTC_IO MODULE PROCEDURE AllRPAry2 MODULE PROCEDURE AllR4PAry3 MODULE PROCEDURE AllR8PAry3 - MODULE PROCEDURE AllR16PAry3 ! MODULE PROCEDURE AllRPAry4 !not yet coded END INTERFACE @@ -141,7 +133,6 @@ MODULE NWTC_IO MODULE PROCEDURE ParseLoVar ! Parses an LOGICAL from a string. MODULE PROCEDURE ParseSiVar ! Parses a single-precision REAL from a string. MODULE PROCEDURE ParseR8Var ! Parses a double-precision REAL from a string. - MODULE PROCEDURE ParseQuVar ! Parses a quad-precision REAL from a string. END INTERFACE !> \copydoc nwtc_io::parsechvarwdefault @@ -151,7 +142,6 @@ MODULE NWTC_IO MODULE PROCEDURE ParseLoVarWDefault ! Parses an LOGICAL from a string, potentially sets to a default value if "Default" is parsed. MODULE PROCEDURE ParseSiVarWDefault ! Parses a single-precision REAL from a string, potentially sets to a default value if "Default" is parsed. MODULE PROCEDURE ParseR8VarWDefault ! Parses a double-precision REAL from a string, potentially sets to a default value if "Default" is parsed. - MODULE PROCEDURE ParseQuVarWDefault ! Parses a quad-precision REAL from a string, potentially sets to a default value if "Default" is parsed. END INTERFACE !> \copydoc nwtc_io::parsedbary @@ -160,7 +150,6 @@ MODULE NWTC_IO MODULE PROCEDURE ParseLoAry ! Parse an array of LOGICAL values. MODULE PROCEDURE ParseSiAry ! Parse an array of single-precision REAL values. MODULE PROCEDURE ParseR8Ary ! Parse an array of double-precision REAL values. - MODULE PROCEDURE ParseQuAry ! Parse an array of quad-precision REAL values. MODULE PROCEDURE ParseChAry END INTERFACE @@ -168,7 +157,6 @@ MODULE NWTC_IO INTERFACE CheckRealVar MODULE PROCEDURE CheckR4Var ! 4-byte real MODULE PROCEDURE CheckR8Var ! 8-byte real - MODULE PROCEDURE CheckR16Var ! 16-byte real END INTERFACE !> \copydoc nwtc_io::readcvar @@ -178,7 +166,6 @@ MODULE NWTC_IO MODULE PROCEDURE ReadLVar MODULE PROCEDURE ReadR4Var ! 4-byte real MODULE PROCEDURE ReadR8Var ! 8-byte real - MODULE PROCEDURE ReadR16Var ! 16-byte real END INTERFACE !> \copydoc nwtc_io::readivarwdefault @@ -188,7 +175,7 @@ MODULE NWTC_IO MODULE PROCEDURE ReadLVarWDefault ! Logical MODULE PROCEDURE ReadR4VarWDefault ! 4-byte real MODULE PROCEDURE ReadR8VarWDefault ! 8-byte real - MODULE PROCEDURE ReadR16VarWDefault ! 16-byte real + MODULE PROCEDURE ReadIAryWDefault END INTERFACE !> \copydoc nwtc_io::readcary @@ -196,13 +183,12 @@ MODULE NWTC_IO MODULE PROCEDURE ReadCAry MODULE PROCEDURE ReadCAryFromStr MODULE PROCEDURE ReadIAry + MODULE PROCEDURE ReadIAryFromStr MODULE PROCEDURE ReadLAry MODULE PROCEDURE ReadR4Ary ! read array of 4-byte reals MODULE PROCEDURE ReadR4AryFromStr MODULE PROCEDURE ReadR8Ary ! read array of 8-byte reals MODULE PROCEDURE ReadR8AryFromStr - MODULE PROCEDURE ReadR16Ary ! read array of 16-byte reals - MODULE PROCEDURE ReadR16AryFromStr END INTERFACE !> \copydoc nwtc_io::readcarylines @@ -210,7 +196,6 @@ MODULE NWTC_IO MODULE PROCEDURE ReadCAryLines MODULE PROCEDURE ReadR4AryLines MODULE PROCEDURE ReadR8AryLines - MODULE PROCEDURE ReadR16AryLines ! MODULE PROCEDURE ReadIAryLines ! Not coded yet ! MODULE PROCEDURE ReadLAryLines ! Not coded yet END INTERFACE @@ -218,9 +203,9 @@ MODULE NWTC_IO !> \copydoc nwtc_io::int2lstr INTERFACE Num2LStr MODULE PROCEDURE Int2LStr ! default integers + MODULE PROCEDURE B8Ki2LStr ! 8 byte integers MODULE PROCEDURE R2LStr4 ! 4-byte reals MODULE PROCEDURE R2LStr8 ! 8-byte reals - MODULE PROCEDURE R2LStr16 ! 16-byte reals END INTERFACE !> \copydoc nwtc_io::dispnvd0 @@ -236,8 +221,6 @@ MODULE NWTC_IO MODULE PROCEDURE WrMatrix2R4 ! Two dimension matrix of SiKi MODULE PROCEDURE WrMatrix1R8 ! Single dimension matrix (Ary) of R8Ki MODULE PROCEDURE WrMatrix2R8 ! Two dimension matrix of R8Ki - MODULE PROCEDURE WrMatrix1R16 ! Single dimension matrix (Ary) of QuKi - MODULE PROCEDURE WrMatrix2R16 ! Two dimension matrix of QuKi END INTERFACE !> \copydoc nwtc_io::wrpartialmatrix1r8 @@ -251,7 +234,6 @@ MODULE NWTC_IO MODULE PROCEDURE WrIAryFileNR MODULE PROCEDURE WrR4AryFileNR MODULE PROCEDURE WrR8AryFileNR - MODULE PROCEDURE WrR16AryFileNR END INTERFACE CONTAINS @@ -792,43 +774,6 @@ SUBROUTINE AllR8PAry3 ( Ary, AryDim1, AryDim2, AryDim3, Descr, ErrStat, ErrMsg RETURN END SUBROUTINE AllR8PAry3 !======================================================================= -!> \copydoc nwtc_io::allipary1 - SUBROUTINE AllR16PAry3 ( Ary, AryDim1, AryDim2, AryDim3, Descr, ErrStat, ErrMsg ) - - - ! This routine allocates a 3-D REAL array. - - ! Argument declarations. - - REAL(QuKi), POINTER :: Ary (:,:,:) ! Array to be allocated - INTEGER, INTENT(IN) :: AryDim1 ! The size of the first dimension of the array. - INTEGER, INTENT(IN) :: AryDim2 !< The size of the second dimension of the array. - INTEGER, INTENT(IN) :: AryDim3 !< The size of the third dimension of the array. - INTEGER, INTENT(OUT) :: ErrStat ! Error status - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message corresponding to ErrStat - CHARACTER(*), INTENT(IN) :: Descr ! Brief array description. - - - IF ( ASSOCIATED(Ary) ) THEN - DEALLOCATE(Ary) - !ErrStat = ErrID_Warn - !ErrMsg = " AllRPAry3: Ary already allocated." - END IF - - ALLOCATE ( Ary(AryDim1,AryDim2,AryDim3) , STAT=ErrStat ) - IF ( ErrStat /= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'Error allocating '//TRIM(Num2LStr(AryDim1*AryDim2*AryDim3*BYTES_IN_REAL))//& - ' bytes of memory for the '//TRIM( Descr )//' array.' - ELSE - ErrStat = ErrID_None - ErrMsg = '' - END IF - - Ary = 0 - RETURN - END SUBROUTINE AllR16PAry3 -!======================================================================= !> \copydoc nwtc_io::allcary1 SUBROUTINE AllLAry1 ( Ary, AryDim1, Descr, ErrStat, ErrMsg ) @@ -1000,41 +945,6 @@ SUBROUTINE AllR8Ary1 ( Ary, AryDim1, Descr, ErrStat, ErrMsg ) RETURN END SUBROUTINE AllR8Ary1 !======================================================================= -!> \copydoc nwtc_io::allcary1 - SUBROUTINE AllR16Ary1 ( Ary, AryDim1, Descr, ErrStat, ErrMsg ) - - - ! This routine allocates a 1-D 16-byte REAL array. - - - ! Argument declarations. - - REAL(QuKi), ALLOCATABLE :: Ary (:) ! Array to be allocated - INTEGER, INTENT(IN) :: AryDim1 ! The size of the array. - - CHARACTER(*), INTENT(IN) :: Descr ! Brief array description. - INTEGER, INTENT(OUT) :: ErrStat ! Error status - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message corresponding to ErrStat - - - ALLOCATE ( Ary(AryDim1) , STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - ErrStat = ErrID_Fatal - IF ( ALLOCATED(Ary) ) THEN ! or Sttus=151 on IVF - ErrMsg = 'Error allocating memory for the '//TRIM( Descr )//' array; array was already allocated.' - ELSE - ErrMsg = 'Error allocating '//TRIM(Num2LStr(AryDim1*BYTES_IN_QuKi))//' bytes of memory for the '//TRIM( Descr )//' array.' - END IF - ELSE - ErrStat = ErrID_None - ErrMsg = '' - END IF - - - RETURN - END SUBROUTINE AllR16Ary1 -!======================================================================= !> \copydoc nwtc_io::allcary1 SUBROUTINE AllR4Ary2 ( Ary, AryDim1, AryDim2, Descr, ErrStat, ErrMsg ) @@ -1111,43 +1021,6 @@ SUBROUTINE AllR8Ary2 ( Ary, AryDim1, AryDim2, Descr, ErrStat, ErrMsg ) RETURN END SUBROUTINE AllR8Ary2 !======================================================================= -!> \copydoc nwtc_io::allcary1 - SUBROUTINE AllR16Ary2 ( Ary, AryDim1, AryDim2, Descr, ErrStat, ErrMsg ) - - - ! This routine allocates a 2-D 4-Byte REAL array. - - - ! Argument declarations. - - REAL(QuKi), ALLOCATABLE :: Ary (:,:) ! Array to be allocated - - INTEGER, INTENT(IN) :: AryDim1 ! The size of the first dimension of the array. - INTEGER, INTENT(IN) :: AryDim2 !< The size of the second dimension of the array. - CHARACTER(*), INTENT(IN) :: Descr ! Brief array description. - INTEGER, INTENT(OUT) :: ErrStat ! Error status - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message corresponding to ErrStat - - - - ALLOCATE ( Ary(AryDim1,AryDim2) , STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - ErrStat = ErrID_Fatal - IF ( ALLOCATED(Ary) ) THEN ! or Sttus=151 on IVF - ErrMsg = 'Error allocating memory for the '//TRIM( Descr )//' array; array was already allocated.' - ELSE - ErrMsg = 'Error allocating '//TRIM(Num2LStr(AryDim1*AryDim2*BYTES_IN_QuKi))//& - ' bytes of memory for the '//TRIM( Descr )//' array.' - END IF - ELSE - ErrStat = ErrID_None - ErrMsg = '' - END IF - - RETURN - END SUBROUTINE AllR16Ary2 -!======================================================================= !> \copydoc nwtc_io::allcary1 SUBROUTINE AllR4Ary3 ( Ary, AryDim1, AryDim2, AryDim3, Descr, ErrStat, ErrMsg ) @@ -1222,43 +1095,6 @@ SUBROUTINE AllR8Ary3 ( Ary, AryDim1, AryDim2, AryDim3, Descr, ErrStat, ErrMsg ) RETURN END SUBROUTINE AllR8Ary3 !======================================================================= -!> \copydoc nwtc_io::allcary1 - SUBROUTINE AllR16Ary3 ( Ary, AryDim1, AryDim2, AryDim3, Descr, ErrStat, ErrMsg ) - - - ! This routine allocates a 3-D 16-byte REAL array. - - - ! Argument declarations. - - REAL(QuKi), ALLOCATABLE :: Ary (:,:,:) ! Array to be allocated - - INTEGER, INTENT(IN) :: AryDim1 ! The size of the first dimension of the array. - INTEGER, INTENT(IN) :: AryDim2 !< The size of the second dimension of the array. - INTEGER, INTENT(IN) :: AryDim3 !< The size of the third dimension of the array. - CHARACTER(*), INTENT(IN) :: Descr ! Brief array description. - INTEGER, INTENT(OUT) :: ErrStat ! Error status; if present, program does not abort on error - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message corresponding to ErrStat - - - ALLOCATE ( Ary(AryDim1,AryDim2,AryDim3) , STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - ErrStat = ErrID_Fatal - IF ( ALLOCATED(Ary) ) THEN ! or Sttus=151 on IVF - ErrMsg = 'Error allocating memory for the '//TRIM( Descr )//' array; array was already allocated.' - ELSE - ErrMsg = 'Error allocating '//TRIM(Num2LStr(AryDim1*AryDim2*AryDim3*BYTES_IN_REAL))//& - ' bytes of memory for the '//TRIM( Descr )//' array.' - END IF - ELSE - ErrStat = ErrID_None - ErrMsg = '' - END IF - - RETURN - END SUBROUTINE AllR16Ary3 -!======================================================================= !> \copydoc nwtc_io::allcary1 SUBROUTINE AllR4Ary4 ( Ary, AryDim1, AryDim2, AryDim3, AryDim4, Descr, ErrStat, ErrMsg ) @@ -1335,44 +1171,6 @@ SUBROUTINE AllR8Ary4 ( Ary, AryDim1, AryDim2, AryDim3, AryDim4, Descr, ErrStat, RETURN END SUBROUTINE AllR8Ary4 !======================================================================= -!> \copydoc nwtc_io::allcary1 - SUBROUTINE AllR16Ary4 ( Ary, AryDim1, AryDim2, AryDim3, AryDim4, Descr, ErrStat, ErrMsg ) - - - ! This routine allocates a 4-D 16-byte REAL array. - - - ! Argument declarations. - - REAL(QuKi), ALLOCATABLE :: Ary (:,:,:,:) ! Array to be allocated - - INTEGER, INTENT(IN) :: AryDim1 ! The size of the first dimension of the array. - INTEGER, INTENT(IN) :: AryDim2 !< The size of the second dimension of the array. - INTEGER, INTENT(IN) :: AryDim3 !< The size of the third dimension of the array. - INTEGER, INTENT(IN) :: AryDim4 !< The size of the fourth dimension of the array. - CHARACTER(*), INTENT(IN) :: Descr ! Brief array description. - INTEGER, INTENT(OUT) :: ErrStat ! Error status; if present, program does not abort on error - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message corresponding to ErrStat - - - ALLOCATE ( Ary(AryDim1,AryDim2,AryDim3,AryDim4) , STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - ErrStat = ErrID_Fatal - IF ( ALLOCATED(Ary) ) THEN ! or Sttus=151 on IVF - ErrMsg = 'Error allocating memory for the '//TRIM( Descr )//' array; array was already allocated.' - ELSE - ErrMsg = 'Error allocating '//TRIM(Num2LStr(AryDim1*AryDim2*AryDim3*AryDim4*BYTES_IN_REAL))//& - ' bytes of memory for the '//TRIM( Descr )//' array.' - END IF - ELSE - ErrStat = ErrID_None - ErrMsg = '' - END IF - - RETURN - END SUBROUTINE AllR16Ary4 -!======================================================================= !> \copydoc nwtc_io::allcary1 SUBROUTINE AllR4Ary5 ( Ary, AryDim1, AryDim2, AryDim3, AryDim4, AryDim5, Descr, ErrStat, ErrMsg ) @@ -1455,48 +1253,6 @@ SUBROUTINE AllR8Ary5 ( Ary, AryDim1, AryDim2, AryDim3, AryDim4, AryDim5, Descr, RETURN END SUBROUTINE AllR8Ary5 !======================================================================= -!> \copydoc nwtc_io::allcary1 - SUBROUTINE AllR16Ary5 ( Ary, AryDim1, AryDim2, AryDim3, AryDim4, AryDim5, Descr, ErrStat, ErrMsg ) - - - ! This routine allocates a 5-D 16-byte REAL array. - - - ! Argument declarations. - - REAL(QuKi), ALLOCATABLE :: Ary (:,:,:,:,:) ! Array to be allocated - - INTEGER, INTENT(IN) :: AryDim1 ! The size of the first dimension of the array. - INTEGER, INTENT(IN) :: AryDim2 !< The size of the second dimension of the array. - INTEGER, INTENT(IN) :: AryDim3 !< The size of the third dimension of the array. - INTEGER, INTENT(IN) :: AryDim4 !< The size of the fourth dimension of the array. - INTEGER, INTENT(IN) :: AryDim5 !< The size of the fourth dimension of the array. - CHARACTER(*), INTENT(IN) :: Descr ! Brief array description. - INTEGER, INTENT(OUT) :: ErrStat ! Error status; if present, program does not abort on error - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message corresponding to ErrStat - - - ALLOCATE ( Ary(AryDim1,AryDim2,AryDim3,AryDim4,AryDim5) , STAT=ErrStat ) - - IF ( ErrStat /= 0 ) THEN - ErrStat = ErrID_Fatal - IF ( ALLOCATED(Ary) ) THEN ! or Sttus=151 on IVF - ErrMsg = 'Error allocating memory for the '//TRIM( Descr )//' array; array was already allocated.' - ELSE - ErrMsg = 'Error allocating '//TRIM(Num2LStr(AryDim1*AryDim2*AryDim3*AryDim4*AryDim5*BYTES_IN_REAL))//& - ' bytes of memory for the '//TRIM( Descr )//' array.' - END IF - ELSE - ErrStat = ErrID_None - ErrMsg = '' - END IF - - - - RETURN - END SUBROUTINE AllR16Ary5 - -!======================================================================= !> This subroutine checks the data to be parsed to make sure it finds !! the expected variable name and an associated value. SUBROUTINE ChkParseData ( Words, ExpVarName, FileName, FileLineNum, NameIndx, ErrStat, ErrMsg ) @@ -1765,24 +1521,6 @@ SUBROUTINE CheckR8Var( RealVar, RealDesc, ErrStat, ErrMsg ) END SUBROUTINE CheckR8Var !======================================================================= -!> \copydoc nwtc_io::checkr4var -SUBROUTINE CheckR16Var( RealVar, RealDesc, ErrStat, ErrMsg ) - - REAL(QuKi), INTENT(IN) :: RealVar !< Real value to check - CHARACTER(*),INTENT(IN) :: RealDesc !< description of RealVar - INTEGER, INTENT(OUT) :: ErrStat !< Error status - CHARACTER(*),INTENT(OUT) :: ErrMsg !< Error message - - IF (IEEE_IS_NAN(RealVar) .or. .not. IEEE_IS_FINITE( RealVar) ) THEN - ErrStat = ErrID_Fatal - ErrMsg = trim(RealDesc)//': value is not a finite real number.' - ELSE - ErrStat = ErrID_None - ErrMsg = "" - END IF - -END SUBROUTINE CheckR16Var -!======================================================================= !> This routine converts all the text in a string to upper case. SUBROUTINE Conv2UC ( Str ) @@ -2080,6 +1818,11 @@ SUBROUTINE DLLTypeUnPack( OutData, ReKiBuf, DbKiBuf, IntKiBuf, ErrStat, ErrMsg ) IF ( IntKiBuf(1) == 1 .AND. LEN_TRIM(OutData%FileName) > 0 .AND. LEN_TRIM(OutData%ProcName(1)) > 0 ) THEN CALL LoadDynamicLib( OutData, ErrStat, ErrMsg ) + else + ! Nullifying + OutData%FileAddr = INT(0,C_INTPTR_T) + OutData%FileAddrX = C_NULL_PTR + OutData%ProcAddr = C_NULL_FUNPTR END IF END SUBROUTINE DLLTypeUnPack @@ -2199,7 +1942,11 @@ SUBROUTINE GetNewUnit ( UnIn, ErrStat, ErrMsg ) INTEGER :: Un ! Unit number LOGICAL :: Opened ! Flag indicating whether or not a file is opened. INTEGER(IntKi), PARAMETER :: StartUnit = 10 ! Starting unit number to check (numbers less than 10 reserved) - INTEGER(IntKi), PARAMETER :: MaxUnit = 99 ! The maximum unit number available (or 10 less than the number of files you want to have open at a time) + ! NOTE: maximum unit numbers in fortran 90 and later is 2**31-1. However, there are limits within the OS. + ! macos -- 256 (change with ulimit -n) + ! linux -- 1024 (change with ulimit -n) + ! windows -- 512 (not sure how to change -- ADP) + INTEGER(IntKi), PARAMETER :: MaxUnit = 1024 ! The maximum unit number available (or 10 less than the number of files you want to have open at a time) CHARACTER(ErrMsgLen) :: Msg ! Temporary error message @@ -2440,21 +2187,21 @@ END SUBROUTINE GetTokens !! It uses spaces, tabs, commas, semicolons, single quotes, and double quotes ("whitespace") !! as word separators. If there aren't NumWords in the line, the remaining array elements will remain empty. !! Use CountWords (nwtc_io::countwords) to count the number of words in a line. - SUBROUTINE GetWords ( Line, Words, NumWords ) + SUBROUTINE GetWords ( Line, Words, NumWords, NumFound ) ! Argument declarations. - INTEGER, INTENT(IN) :: NumWords !< The number of words to look for. - - CHARACTER(*), INTENT(IN) :: Line !< The string to search. - CHARACTER(*), INTENT(OUT) :: Words(NumWords) !< The array of found words. + INTEGER, INTENT(IN) :: NumWords !< The maximum number of words to look for (and size of Words) + CHARACTER(*), INTENT(IN) :: Line !< The string to search. + CHARACTER(*), INTENT(OUT) :: Words(NumWords) !< The array of found words. + INTEGER, OPTIONAL, INTENT(OUT) :: NumFound !< The number of words found ! Local declarations. - INTEGER :: Ch ! Character position within the string. - INTEGER :: IW ! Word index. - INTEGER :: NextWhite ! The location of the next whitespace in the string. + INTEGER :: Ch ! Character position within the string. + INTEGER :: IW ! Word index. + INTEGER :: NextWhite ! The location of the next whitespace in the string. @@ -2464,48 +2211,51 @@ SUBROUTINE GetWords ( Line, Words, NumWords ) Words(IW) = ' ' END DO ! IW + IW = 0 + ! Let's make sure we have text on this line. - IF ( LEN_TRIM( Line ) == 0 ) RETURN - - - ! Parse words separated by any combination of spaces, tabs, commas, - ! semicolons, single quotes, and double quotes ("whitespace"). + IF ( LEN_TRIM( Line ) > 0 ) THEN - Ch = 0 - IW = 0 + ! Parse words separated by any combination of spaces, tabs, commas, + ! semicolons, single quotes, and double quotes ("whitespace"). - DO + Ch = 0 - NextWhite = SCAN( Line(Ch+1:) , ' ,;''"'//Tab ) + DO - IF ( NextWhite > 1 ) THEN + NextWhite = SCAN( Line(Ch+1:) , ' ,;''"'//Tab ) - IW = IW + 1 - Words(IW) = Line(Ch+1:Ch+NextWhite-1) - if (NextWhite > len(words(iw)) ) then - call ProgWarn('Error reading field from file. There are too many characters in the input file to store in the field. Value may be truncated.') - end if + IF ( NextWhite > 1 ) THEN - IF ( IW == NumWords ) EXIT + IW = IW + 1 + Words(IW) = Line(Ch+1:Ch+NextWhite-1) + if (NextWhite > len(words(iw)) ) then + call ProgWarn('Error reading field from file. There are too many characters in the input file to store in the field. Value may be truncated.') + end if - Ch = Ch + NextWhite + IF ( IW == NumWords ) EXIT - ELSE IF ( NextWhite == 1 ) THEN + Ch = Ch + NextWhite - Ch = Ch + 1 + ELSE IF ( NextWhite == 1 ) THEN - CYCLE + Ch = Ch + 1 - ELSE + CYCLE - EXIT + ELSE - END IF + EXIT - END DO + END IF + END DO + + END IF + + IF (PRESENT(NumFound)) NumFound = IW RETURN END SUBROUTINE GetWords @@ -2556,24 +2306,26 @@ END SUBROUTINE IntAry2Str !! It eliminates trailing zeroes and even the decimal point if it is not a fraction. \n !! Use Num2LStr (nwtc_io::num2lstr) instead of directly calling a specific routine in the generic interface. FUNCTION Int2LStr ( Num ) - - CHARACTER(11) :: Int2LStr !< string representing input number. - - + CHARACTER(11) :: Int2LStr !< string representing input number. ! Argument declarations. - - INTEGER, INTENT(IN) :: Num !< The number to convert to a left-justified string. - - - - WRITE (Int2LStr,'(I11)') Num - - Int2Lstr = ADJUSTL( Int2LStr ) - - - RETURN + INTEGER(IntKi), INTENT(IN) :: Num !< The number to convert to a left-justified string. + WRITE (Int2LStr,'(I11)') Num + Int2Lstr = ADJUSTL( Int2LStr ) + RETURN END FUNCTION Int2LStr !======================================================================= +!> This function returns a left-adjusted string representing the passed numeric value. +!! It eliminates trailing zeroes and even the decimal point if it is not a fraction. \n +!! Use Num2LStr (nwtc_io::num2lstr) instead of directly calling a specific routine in the generic interface. + FUNCTION B8Ki2LStr ( Num ) + CHARACTER(20) :: B8Ki2LStr !< string representing input number. + ! Argument declarations. + INTEGER(B8Ki), INTENT(IN) :: Num !< The number to convert to a left-justified string. + WRITE (B8Ki2LStr,'(I20)') Num + B8Ki2Lstr = ADJUSTL( B8Ki2LStr ) + RETURN + END FUNCTION B8Ki2LStr +!======================================================================= !> This function returns true if and only if the first character of the input StringToCheck matches on the of comment characters !! nwtc_io::commchars. FUNCTION IsComment(StringToCheck) @@ -3178,7 +2930,6 @@ SUBROUTINE ParseChAry ( FileInfo, LineNum, AryName, Ary, AryLen, ErrStat, ErrMsg ! Local declarations. INTEGER(IntKi) :: ErrStatLcl ! Error status local to this routine. - INTEGER(IntKi) :: i ! Error status local to this routine. CHARACTER(*), PARAMETER :: RoutineName = 'ParseChAry' @@ -3187,7 +2938,8 @@ SUBROUTINE ParseChAry ( FileInfo, LineNum, AryName, Ary, AryLen, ErrStat, ErrMsg IF (LineNum > size(FileInfo%Lines) ) THEN CALL SetErrStat ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data.'//NewLine// & - ' >> The "'//TRIM( AryName )//'" array was not assigned because the file is too short.' & + ' >> The "'//TRIM( AryName )//'" array was not assigned because the file is too short. LineNum='// & + trim(num2lstr(LineNum))//'; NumLines='//trim(num2lstr(size(FileInfo%Lines))) & , ErrStat, ErrMsg, RoutineName ) RETURN END IF @@ -3196,7 +2948,7 @@ SUBROUTINE ParseChAry ( FileInfo, LineNum, AryName, Ary, AryLen, ErrStat, ErrMsg IF ( ErrStatLcl /= 0 ) THEN CALL SetErrStat ( ErrID_Fatal, 'A fatal error occurred when parsing data from "' & //TRIM( FileInfo%FileList(FileInfo%FileIndx(LineNum)) )//'".'//NewLine// & - ' >> The "'//TRIM( AryName )//'" array was not assigned valid REAL values on line #' & + ' >> The "'//TRIM( AryName )//'" array was not assigned valid CHARACTER values on line #' & //TRIM( Num2LStr( FileInfo%FileLine(LineNum) ) )//'.'//NewLine//' >> The text being parsed was :'//NewLine & //' "'//TRIM( FileInfo%Lines(LineNum) )//'"',ErrStat,ErrMsg,RoutineName ) RETURN @@ -3229,7 +2981,8 @@ SUBROUTINE ParseCom ( FileInfo, LineNum, Var, ErrStat, ErrMsg, UnEc ) IF (LineNum > size(FileInfo%Lines) ) THEN CALL SetErrStat ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data.'//NewLine// & - ' >> The comment line was not assigned because the file is too short.' & + ' >> The comment line was not assigned because the file is too short. LineNum='// & + trim(num2lstr(LineNum))//'; NumLines='//trim(num2lstr(size(FileInfo%Lines))) & , ErrStat, ErrMsg, RoutineName ) RETURN END IF @@ -3279,7 +3032,7 @@ SUBROUTINE ParseChVar ( 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 = 'ParseChVar' @@ -3291,7 +3044,8 @@ SUBROUTINE ParseChVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE IF (LineNum > size(FileInfo%Lines) ) THEN CALL SetErrStat ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data.'//NewLine// & - ' >> The "'//TRIM( ExpVarName )//'" variable was not assigned because the file is too short.' & + ' >> The "'//TRIM( ExpVarName )//'" variable was not assigned because the file is too short. LineNum='// & + trim(num2lstr(LineNum))//'; NumLines='//trim(num2lstr(size(FileInfo%Lines))) & , ErrStat, ErrMsg, RoutineName ) RETURN END IF @@ -3408,7 +3162,8 @@ SUBROUTINE ParseR8Ary ( FileInfo, LineNum, AryName, Ary, AryLen, ErrStat, ErrMsg IF (LineNum > size(FileInfo%Lines) ) THEN CALL SetErrStat ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data.'//NewLine// & - ' >> The "'//TRIM( AryName )//'" array was not assigned because the file is too short.' & + ' >> The "'//TRIM( AryName )//'" array was not assigned because the file is too short. LineNum='// & + trim(num2lstr(LineNum))//'; NumLines='//trim(num2lstr(size(FileInfo%Lines))) & , ErrStat, ErrMsg, RoutineName ) RETURN END IF @@ -3473,7 +3228,8 @@ SUBROUTINE ParseR8Var ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE IF (LineNum > size(FileInfo%Lines) ) THEN CALL SetErrStat ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data.'//NewLine// & - ' >> The "'//TRIM( ExpVarName )//'" variable was not assigned because the file is too short.' & + ' >> The "'//TRIM( ExpVarName )//'" variable was not assigned because the file is too short. LineNum='// & + trim(num2lstr(LineNum))//'; NumLines='//trim(num2lstr(size(FileInfo%Lines))) & , ErrStat, ErrMsg, RoutineName ) RETURN END IF @@ -3553,186 +3309,6 @@ SUBROUTINE ParseR8VarWDefault ( FileInfo, LineNum, ExpVarName, Var, VarDefault, RETURN END SUBROUTINE ParseR8VarWDefault !======================================================================= -!> This subroutine parses the specified line of text for AryLen REAL values. -!! Generate an error message if the value is the wrong type. -!! Use ParseAry (nwtc_io::parseary) instead of directly calling a specific routine in the generic interface. - SUBROUTINE ParseQuAry ( FileInfo, LineNum, AryName, Ary, AryLen, ErrStat, ErrMsg, UnEc ) - - ! Arguments declarations. - - INTEGER, INTENT(IN) :: AryLen !< The length of the array to parse. - - REAL(QuKi), INTENT(OUT) :: Ary (AryLen) !< The array to receive the input values. - - INTEGER(IntKi), INTENT(OUT) :: ErrStat !< The error status. - INTEGER(IntKi), INTENT(INOUT) :: LineNum !< The number of the line to parse. - - INTEGER, INTENT(IN), OPTIONAL :: UnEc !< I/O unit for echo file. If present and > 0, write to UnEc. - - CHARACTER(*), INTENT(In) :: AryName !< The array name we are trying to fill. - CHARACTER(*), INTENT(OUT) :: ErrMsg !< The error message, if ErrStat /= 0. - - TYPE (FileInfoType), INTENT(IN) :: FileInfo !< The derived type for holding the file information. - - - ! Local declarations. - - INTEGER(IntKi) :: ErrStatLcl ! Error status local to this routine. - INTEGER(IntKi) :: i ! Error status local to this routine. - - CHARACTER(*), PARAMETER :: RoutineName = 'ParseQuAry' - - - ErrStat = ErrID_None - ErrMsg = "" - - IF (LineNum > size(FileInfo%Lines) ) THEN - CALL SetErrStat ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data.'//NewLine// & - ' >> The "'//TRIM( AryName )//'" array was not assigned because the file is too short.' & - , ErrStat, ErrMsg, RoutineName ) - RETURN - END IF - - - READ (FileInfo%Lines(LineNum),*,IOSTAT=ErrStatLcl) Ary - IF ( ErrStatLcl /= 0 ) THEN - CALL SetErrStat ( ErrID_Fatal, 'A fatal error occurred when parsing data from "' & - //TRIM( FileInfo%FileList(FileInfo%FileIndx(LineNum)) )//'".'//NewLine// & - ' >> The "'//TRIM( AryName )//'" array was not assigned valid REAL values on line #' & - //TRIM( Num2LStr( FileInfo%FileLine(LineNum) ) )//'.'//NewLine//' >> The text being parsed was :'//NewLine & - //' "'//TRIM( FileInfo%Lines(LineNum) )//'"',ErrStat,ErrMsg,RoutineName ) - RETURN - ENDIF - - DO i=1,AryLen - call CheckRealVar( Ary(i), AryName, ErrStat, ErrMsg ) - if (ErrStat>= AbortErrLev) return - END DO - - - IF ( PRESENT(UnEc) ) THEN - IF ( UnEc > 0 ) WRITE (UnEc,'(A)') TRIM( FileInfo%Lines(LineNum) ) - END IF - - LineNum = LineNum + 1 - - RETURN - - END SUBROUTINE ParseQuAry -!======================================================================= -!> \copydoc nwtc_io::parsechvar - SUBROUTINE ParseQuVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnEc ) - - ! Arguments declarations. - - REAL(QuKi), INTENT(OUT) :: Var ! The double-precision REAL variable to receive the input value. - - INTEGER(IntKi), INTENT(OUT) :: ErrStat ! The error status. - INTEGER(IntKi), INTENT(INOUT) :: LineNum ! The number of the line to parse. - - INTEGER, INTENT(IN), OPTIONAL :: UnEc ! I/O unit for echo file. If present and > 0, write to UnEc. - - CHARACTER(*), INTENT(OUT) :: ErrMsg ! The error message, if ErrStat /= 0. - CHARACTER(*), INTENT(IN) :: ExpVarName ! The expected variable name. - - TYPE (FileInfoType), INTENT(IN) :: FileInfo ! The derived type for holding the file information. - - - ! Local declarations. - - 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(NWTC_SizeOfNumWord) :: Words (2) ! The two "words" parsed from the line. - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'ParseQuVar' - - - ErrStat = ErrID_None - ErrMsg = "" - - IF (LineNum > size(FileInfo%Lines) ) THEN - CALL SetErrStat ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data.'//NewLine// & - ' >> The "'//TRIM( ExpVarName )//'" variable was not assigned because the file is too short.' & - , ErrStat, ErrMsg, RoutineName ) - RETURN - END IF - - CALL GetWords ( FileInfo%Lines(LineNum), Words, 2 ) ! Read the first two words in Line. - - CALL ChkParseData ( Words, ExpVarName, FileInfo%FileList(FileInfo%FileIndx(LineNum)) & - , FileInfo%FileLine(LineNum), NameIndx, ErrStatLcl, ErrMsg2 ) - CALL SetErrStat(ErrStatLcl, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF ( ErrStat >= AbortErrLev ) RETURN - - - READ (Words(3-NameIndx),*,IOSTAT=ErrStatLcl) Var - IF ( ErrStatLcl /= 0 ) THEN - CALL SetErrStat ( ErrID_Fatal, NewLine//'A fatal error occurred when parsing data from "' & - //TRIM( FileInfo%FileList(FileInfo%FileIndx(LineNum)) )//'".'//NewLine// & - ' >> The variable "'//TRIM( Words(NameIndx) )//'" was not assigned valid REAL value on line #' & - //TRIM( Num2LStr( LineNum ) )//'.'//NewLine//' >> The text being parsed was :'//& - NewLine//' "'//TRIM( FileInfo%Lines(LineNum) )//'"', ErrStat, ErrMsg, RoutineName) - RETURN - ENDIF - CALL CheckRealVar( Var, ExpVarName, ErrStatLcl, ErrMsg2) - CALL SetErrStat(ErrStatLcl, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - IF ( PRESENT(UnEc) ) THEN - IF ( UnEc > 0 ) WRITE (UnEc,'(1X,A15," = ",A20)') Words - END IF - - LineNum = LineNum + 1 - - RETURN - END SUBROUTINE ParseQuVar -!======================================================================= -!> \copydoc nwtc_io::parsechvarwdefault - SUBROUTINE ParseQuVarWDefault ( FileInfo, LineNum, ExpVarName, Var, VarDefault, ErrStat, ErrMsg, UnEc ) - - ! Arguments declarations. - - - INTEGER(IntKi), INTENT(OUT) :: ErrStat ! The error status. - INTEGER(IntKi), INTENT(INOUT) :: LineNum ! The number of the line to parse. - - INTEGER, INTENT(IN), OPTIONAL :: UnEc ! I/O unit for echo file. If present and > 0, write to UnEc. - - REAL(QuKi), INTENT(OUT) :: Var ! The double-precision REAL variable to receive the input value. - REAL(QuKi), INTENT(IN) :: VarDefault ! The double-precision REAL used as the default. - CHARACTER(*), INTENT(OUT) :: ErrMsg ! The error message, if ErrStat /= 0. - CHARACTER(*), INTENT(IN) :: ExpVarName ! The expected variable name. - - TYPE (FileInfoType), INTENT(IN) :: FileInfo ! The derived type for holding the file information. - - - ! Local declarations. - - INTEGER(IntKi) :: ErrStatLcl ! Error status local to this routine. - - CHARACTER(ErrMsgLen) :: ErrMsg2 - CHARACTER(*), PARAMETER :: RoutineName = 'ParseQuVarDefault' - CHARACTER(20) :: defaultStr - - ErrStat=ErrID_None - ErrMsg = "" - - ! First parse this as a string - CALL ParseVar ( FileInfo, LineNum, ExpVarName, defaultStr, ErrStatLcl, ErrMsg2, UnEc ) - CALL SetErrStat(ErrStatLcl, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN - CALL Conv2UC( defaultStr ) - IF ( INDEX(defaultStr, "DEFAULT" ) /= 1 ) THEN ! If it's not "default", read this variable - LineNum = LineNum - 1 ! back up a line - CALL ParseVar ( FileInfo, LineNum, ExpVarName, Var, ErrStatLcl, ErrMsg2, UnEc ) - CALL SetErrStat( ErrStatLcl, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ELSE - Var = VarDefault ! "DEFAULT" value - END IF - - RETURN - END SUBROUTINE ParseQuVarWDefault -!======================================================================= !> \copydoc nwtc_io::parsedbary SUBROUTINE ParseInAry ( FileInfo, LineNum, AryName, Ary, AryLen, ErrStat, ErrMsg, UnEc ) @@ -3764,7 +3340,8 @@ SUBROUTINE ParseInAry ( FileInfo, LineNum, AryName, Ary, AryLen, ErrStat, ErrMsg IF (LineNum > size(FileInfo%Lines) ) THEN CALL SetErrStat ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data.'//NewLine// & - ' >> The "'//TRIM( AryName )//'" array was not assigned because the file is too short.' & + ' >> The "'//TRIM( AryName )//'" array was not assigned because the file is too short. LineNum='// & + trim(num2lstr(LineNum))//'; NumLines='//trim(num2lstr(size(FileInfo%Lines))) & , ErrStat, ErrMsg, RoutineName ) RETURN END IF @@ -3949,7 +3526,8 @@ SUBROUTINE ParseInVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE IF (LineNum > size(FileInfo%Lines) ) THEN CALL SetErrStat ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data.'//NewLine// & - ' >> The "'//TRIM( ExpVarName )//'" variable was not assigned because the file is too short.' & + ' >> The "'//TRIM( ExpVarName )//'" variable was not assigned because the file is too short. LineNum='// & + trim(num2lstr(LineNum))//'; NumLines='//trim(num2lstr(size(FileInfo%Lines))) & , ErrStat, ErrMsg, RoutineName ) RETURN END IF @@ -4070,7 +3648,8 @@ SUBROUTINE ParseLoAry ( FileInfo, LineNum, AryName, Ary, AryLen, ErrStat, ErrMsg IF (LineNum > size(FileInfo%Lines) ) THEN CALL SetErrStat ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data.'//NewLine// & - ' >> The "'//TRIM( AryName )//'" array was not assigned because the file is too short.' & + ' >> The "'//TRIM( AryName )//'" array was not assigned because the file is too short. LineNum='// & + trim(num2lstr(LineNum))//'; NumLines='//trim(num2lstr(size(FileInfo%Lines))) & , ErrStat, ErrMsg, RoutineName ) RETURN END IF @@ -4133,7 +3712,8 @@ SUBROUTINE ParseLoVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE IF (LineNum > size(FileInfo%Lines) ) THEN CALL SetErrStat ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data.'//NewLine// & - ' >> The "'//TRIM( ExpVarName )//'" variable was not assigned because the file is too short.' & + ' >> The "'//TRIM( ExpVarName )//'" variable was not assigned because the file is too short. LineNum='// & + trim(num2lstr(LineNum))//'; NumLines='//trim(num2lstr(size(FileInfo%Lines))) & , ErrStat, ErrMsg, RoutineName ) RETURN END IF @@ -4143,10 +3723,8 @@ SUBROUTINE ParseLoVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE CALL ChkParseData ( Words, ExpVarName, FileInfo%FileList(FileInfo%FileIndx(LineNum)) & , FileInfo%FileLine(LineNum), NameIndx, ErrStatLcl, ErrMsg2 ) - IF ( ErrStatLcl /= 0 ) THEN CALL SetErrStat ( ErrStatLcl, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - RETURN - ENDIF + IF (ErrStat >= AbortErrLev) RETURN READ (Words(3-NameIndx),*,IOSTAT=ErrStatLcl) Var @@ -4247,7 +3825,8 @@ SUBROUTINE ParseSiAry ( FileInfo, LineNum, AryName, Ary, AryLen, ErrStat, ErrMsg IF (LineNum > size(FileInfo%Lines) ) THEN CALL SetErrStat ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data.'//NewLine// & - ' >> The "'//TRIM( AryName )//'" array was not assigned because the file is too short.' & + ' >> The "'//TRIM( AryName )//'" array was not assigned because the file is too short. LineNum='// & + trim(num2lstr(LineNum))//'; NumLines='//trim(num2lstr(size(FileInfo%Lines))) & , ErrStat, ErrMsg, RoutineName ) RETURN END IF @@ -4309,7 +3888,8 @@ SUBROUTINE ParseSiVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE IF (LineNum > size(FileInfo%Lines) ) THEN CALL SetErrStat ( ErrID_Fatal, NewLine//' >> A fatal error occurred when parsing data.'//NewLine// & - ' >> The "'//TRIM( ExpVarName )//'" variable was not assigned because the file is too short.' & + ' >> The "'//TRIM( ExpVarName )//'" variable was not assigned because the file is too short. LineNum='// & + trim(num2lstr(LineNum))//'; NumLines='//trim(num2lstr(size(FileInfo%Lines))) & , ErrStat, ErrMsg, RoutineName ) RETURN END IF @@ -4332,7 +3912,9 @@ SUBROUTINE ParseSiVar ( FileInfo, LineNum, ExpVarName, Var, ErrStat, ErrMsg, UnE RETURN ENDIF - CALL CheckRealVar( Var, ExpVarName, ErrStat, ErrMsg) + CALL CheckRealVar( Var, ExpVarName, ErrStatLcl, ErrMsg2 ) + CALL SetErrStat( ErrStatLcl, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + IF ( ErrStat >= AbortErrLev ) RETURN IF ( PRESENT(UnEc) ) THEN 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) @@ -4489,6 +4071,10 @@ subroutine InitFileInfo_FromNullCString(FileString, FileInfo, ErrStat, ErrMsg) NullLoc = idx endif enddo + ! If the last line is not NULL terminated, might miss the line containing END + if (NullLoc < len_trim(FileString)) then + NumLines = NumLines + 1 + endif if (NumLines == 0) then ErrStat2 = ErrID_Fatal @@ -4515,9 +4101,13 @@ subroutine InitFileInfo_FromNullCString(FileString, FileInfo, ErrStat, ErrMsg) NullLoc = index(FileString(idx:len(FileString)),C_NULL_CHAR) ! started indexing at idx, so add that back in for location in FileString NullLoc = NullLoc + idx - 1 - if (NullLoc > 0) then + if (NullLoc > idx) then FileStringArray(Line) = trim(FileString(idx:NullLoc-1)) else + ! If not NULL terminated + if (len_trim(FileString(NullLoc:len_trim(FileString))) > 0) then + FileStringArray(Line) = trim(FileString(NullLoc+1:len_trim(FileString))) + endif exit ! exit loop as we didn't find any more endif idx = min(NullLoc + 1,len(FileString)) ! Start next segment of file, but overstep end @@ -4742,7 +4332,8 @@ SUBROUTINE ProcessComFile ( TopFileName, FileInfo, ErrStat, ErrMsg ) ENDIF IF ( AryInd /= FileInfo%NumLines ) THEN ! This would happen if there is a mis-match between ScanComFile and ReadComFile - CALL SetErrStat( ErrID_Fatal, "Error processing files: number of lines read does not match array size.", ErrStat, ErrMsg, RoutineName ) + CALL SetErrStat( ErrID_Fatal, "Error processing files: number of lines read ("//trim(num2lstr(AryInd))// & + ") does not match array size ("//trim(num2lstr(fileInfo%NumLines))//").", ErrStat, ErrMsg, RoutineName ) CALL Cleanup() RETURN END IF @@ -4939,49 +4530,6 @@ FUNCTION R2LStr8 ( Num, Fmt_in ) RETURN END FUNCTION R2LStr8 -!======================================================================= -!> \copydoc nwtc_io::int2lstr - FUNCTION R2LStr16 ( Num, Fmt_in ) - - ! This function converts a 16-byte floating point number to - ! a left-aligned string. It eliminates trailing zeroes - ! and even the decimal point if it is not a fraction. - - - ! Function declaration. - - CHARACTER(15) :: R2LStr16 ! This function. - CHARACTER(*), OPTIONAL :: Fmt_in - - - ! Argument declarations. - - REAL(QuKi), INTENT(IN) :: Num ! The floating-point number to convert. - CHARACTER(15) :: Fmt ! format for output - - - ! Return a 0 if that's what we have. - - IF ( Num == 0.0_QuKi ) THEN - R2LStr16 = '0' - RETURN - END IF - - - ! Write the number into the string using G format and left justify it. - if ( present( Fmt_in ) ) then - Fmt = '('//Fmt_in//')' - else - Fmt = '(1PG15.5)' - end if - - WRITE (R2LStr16,Fmt) Num - - CALL AdjRealStr( R2LStr16 ) - - - RETURN - END FUNCTION R2LStr16 !====================================================================== !> This routine reads a AryLen values separated by whitespace (or other Fortran record delimiters such as commas) !! into an array (either on same line or multiple lines). @@ -5831,26 +5379,68 @@ SUBROUTINE ReadIAry ( UnIn, Fil, Ary, AryLen, AryName, AryDescr, ErrStat, ErrMsg RETURN END SUBROUTINE ReadIAry -!======================================================================= -!> \copydoc nwtc_io::readcvar -!! WARNING: this routine limits the size of the number being read to 30 characters - SUBROUTINE ReadIVar ( UnIn, Fil, Var, VarName, VarDescr, ErrStat, ErrMsg, UnEc ) - - - ! This routine reads a single integer variable from the next line of the input file. - +!> This routine reads a AryLen values separated by whitespace (or other Fortran record delimiters such as commas) +!! into an array (either on same line or multiple lines) from an input string +!! Use ReadAry (nwtc_io::readary) instead of directly calling a specific routine in the generic interface. + SUBROUTINE ReadIAryFromStr ( Str, Ary, AryLen, AryName, AryDescr, ErrStat, ErrMsg, UnEc ) - ! Argument declarations: + ! Argument declarations: + CHARACTER(*), INTENT(IN) :: Str !< String to read from + INTEGER, INTENT(IN) :: AryLen !< Length of the array. + INTEGER, INTENT(IN), OPTIONAL:: UnEc !< I/O unit for echo file. If present and > 0, write to UnEc + INTEGER, INTENT(OUT) :: ErrStat !< Error status + CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message describing ErrStat + INTEGER, INTENT(INOUT) :: Ary(AryLen) !< Integer array being read. + CHARACTER(*), INTENT(IN) :: AryDescr !< Text string describing the variable. + CHARACTER(*), INTENT(IN) :: AryName !< Text string containing the variable name. + ! Local declarations: + INTEGER :: Ind ! Index into the string array. Assumed to be one digit. + INTEGER :: IOS ! I/O status returned from the read statement. - INTEGER, INTENT(OUT) :: Var ! Integer variable being read. - INTEGER, INTENT(IN) :: UnIn ! I/O unit for input file. - 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 + ! Init of output + do Ind=1,AryLen + Ary(Ind)=0.0 + end do + ! Reading fields from string + READ (Str,*,IOSTAT=IOS) ( Ary(Ind), Ind=1,AryLen ) - CHARACTER(*), INTENT(IN) :: Fil ! Name of the input file. - CHARACTER(*), INTENT(IN) :: VarDescr ! Text string describing the variable. - CHARACTER(*), INTENT(IN) :: VarName ! Text string containing the variable name. + ! Dedicated "CheckIOS" + IF ( IOS < 0 ) THEN + write(ErrMsg,'(A,I0,A)') 'End of line reached while trying to read ',AryLen,' value from string:`'//trim(Str)//'`' + ErrStat = ErrID_Fatal + ELSE IF ( IOS > 0 ) THEN + write(ErrMsg,'(A,I0,A)') 'Unexpected error while trying to read ',AryLen,' value from string:`'//trim(Str)//'`' + ELSE + ErrMsg='' + ErrStat = ErrID_None + END IF + IF (ErrStat >= AbortErrLev) RETURN + IF ( PRESENT(UnEc) ) THEN + IF ( UnEc > 0 ) & + WRITE (UnEc,Ec_ReAryFrmt) TRIM( AryName ), AryDescr, ( Ary(Ind), Ind=1,MIN(AryLen,NWTC_MaxAryLen) ) + END IF + RETURN + END SUBROUTINE ReadIAryFromStr +!======================================================================= +!> \copydoc nwtc_io::readcvar +!! WARNING: this routine limits the size of the number being read to 30 characters + SUBROUTINE ReadIVar ( UnIn, Fil, Var, VarName, VarDescr, ErrStat, ErrMsg, UnEc ) + + + ! This routine reads a single integer variable from the next line of the input file. + + + ! Argument declarations: + + INTEGER, INTENT(OUT) :: Var ! Integer variable being read. + INTEGER, INTENT(IN) :: UnIn ! I/O unit for input file. + 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 + + CHARACTER(*), INTENT(IN) :: Fil ! Name of the input file. + CHARACTER(*), INTENT(IN) :: VarDescr ! Text string describing the variable. + CHARACTER(*), INTENT(IN) :: VarName ! Text string containing the variable name. ! Local declarations: @@ -5971,7 +5561,7 @@ SUBROUTINE ReadLVarWDefault ( UnIn, Fil, Var, VarName, VarDescr, VarDefault, Err IF ( PRESENT(UnEc) ) THEN IF ( UnEc > 0 ) & - WRITE (UnEc,Ec_IntFrmt) Var, VarName, VarDescr + WRITE (UnEc,Ec_LgFrmt) Var, VarName, VarDescr END IF @@ -6243,7 +5833,7 @@ END SUBROUTINE ReadOutputList !! These values represent the names of output channels, and they are specified in the format !! required for OutList(:) in FAST input files. !! The end of this list is specified with the line beginning with the 3 characters "END". - SUBROUTINE ReadOutputListFromFileInfo ( FileInfo, LineNum, CharAry, AryLenRead, AryName, AryDescr, ErrStat, ErrMsg, UnEc ) + SUBROUTINE ReadOutputListFromFileInfo ( FileInfo, LineNum, CharAry, AryLenRead, ErrStat, ErrMsg, UnEc ) ! Argument declarations: @@ -6256,9 +5846,6 @@ SUBROUTINE ReadOutputListFromFileInfo ( FileInfo, LineNum, CharAry, AryLenRead, CHARACTER(*), INTENT(OUT) :: CharAry(:) !< Character array being read (calling routine dimensions it to max allowable size). - CHARACTER(*), INTENT(IN) :: AryDescr !< Text string describing the variable. - CHARACTER(*), INTENT(IN) :: AryName !< Text string containing the variable name. - ! Local declarations: @@ -6325,6 +5912,8 @@ SUBROUTINE ReadOutputListFromFileInfo ( FileInfo, LineNum, CharAry, AryLenRead, LineNum = LineNum+1 + if (LineNum > FileInfo%NumLines) exit ! Don't overrun end of file in case no END found + END DO @@ -6520,101 +6109,6 @@ SUBROUTINE ReadR8AryFromStr ( Str, Ary, AryLen, AryName, AryDescr, ErrStat, ErrM RETURN END SUBROUTINE ReadR8AryFromStr !======================================================================= -!> \copydoc nwtc_io::readcary - SUBROUTINE ReadR16Ary ( UnIn, Fil, Ary, AryLen, AryName, AryDescr, ErrStat, ErrMsg, UnEc ) - - - ! This routine reads a AryLen values into a 16-byte real array separated by white space - ! (possibly on the same line of the input file). - - - ! Argument declarations: - - INTEGER, INTENT(IN) :: AryLen ! Length of the array. - INTEGER, INTENT(IN) :: UnIn ! I/O unit for input file. - INTEGER, INTENT(IN),OPTIONAL :: UnEc ! I/O unit for echo file. If present and > 0, write to UnEc - INTEGER, INTENT(OUT) :: ErrStat ! Error status - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message - - - REAL(QuKi), INTENT(INOUT) :: Ary(AryLen) ! Real array being read. - - 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 :: Ind ! Index into the real array. Assumed to be one digit. - INTEGER :: IOS ! I/O status returned from the read statement. - - - - READ (UnIn,*,IOSTAT=IOS) ( Ary(Ind), Ind=1,AryLen ) - - CALL CheckIOS ( IOS, Fil, TRIM( AryName ), NumType, ErrStat, ErrMsg ) - - IF (ErrStat >= AbortErrLev) RETURN - - DO Ind=1,AryLen - CALL CheckRealVar( Ary(Ind), AryName, ErrStat, ErrMsg) - IF (ErrStat >= AbortErrLev) RETURN - END DO - - IF ( PRESENT(UnEc) ) THEN - IF ( UnEc > 0 ) THEN - WRITE( UnEc, Ec_ReAryFrmt ) TRIM( AryName ), AryDescr, Ary(1:MIN(AryLen,NWTC_MaxAryLen)) - END IF - END IF - - - RETURN - END SUBROUTINE ReadR16Ary -!====================================================================== -!> This routine reads a AryLen values separated by whitespace (or other Fortran record delimiters such as commas) -!! into an array (either on same line or multiple lines) from an input string -!! Use ReadAry (nwtc_io::readary) instead of directly calling a specific routine in the generic interface. - SUBROUTINE ReadR16AryFromStr ( Str, Ary, AryLen, AryName, AryDescr, ErrStat, ErrMsg, UnEc ) - - ! Argument declarations: - CHARACTER(*), INTENT(IN) :: Str !< String to read from - INTEGER, INTENT(IN) :: AryLen !< Length of the array. - INTEGER, INTENT(IN), OPTIONAL:: UnEc !< I/O unit for echo file. If present and > 0, write to UnEc - INTEGER, INTENT(OUT) :: ErrStat !< Error status - CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message describing ErrStat - REAL(QuKi), INTENT(INOUT) :: Ary(AryLen) ! Real array being read. - CHARACTER(*), INTENT(IN) :: AryDescr !< Text string describing the variable. - CHARACTER(*), INTENT(IN) :: AryName !< Text string containing the variable name. - ! Local declarations: - INTEGER :: Ind ! Index into the string array. Assumed to be one digit. - INTEGER :: IOS ! I/O status returned from the read statement. - - ! Init of output - do Ind=1,AryLen - Ary(Ind)=0.0 - end do - ! Reading fields from string - READ (Str,*,IOSTAT=IOS) ( Ary(Ind), Ind=1,AryLen ) - - ! Dedicated "CheckIOS" - IF ( IOS < 0 ) THEN - write(ErrMsg,'(A,I0,A)') 'End of line reached while trying to read ',AryLen,' value from string:`'//trim(Str)//'`' - ErrStat = ErrID_Fatal - ELSE IF ( IOS > 0 ) THEN - write(ErrMsg,'(A,I0,A)') 'Unexpected error while trying to read ',AryLen,' value from string:`'//trim(Str)//'`' - ELSE - ErrMsg='' - ErrStat = ErrID_None - END IF - IF (ErrStat >= AbortErrLev) RETURN - IF ( PRESENT(UnEc) ) THEN - IF ( UnEc > 0 ) & - WRITE (UnEc,Ec_ReAryFrmt) TRIM( AryName ), AryDescr, ( Ary(Ind), Ind=1,MIN(AryLen,NWTC_MaxAryLen) ) - END IF - RETURN - END SUBROUTINE ReadR16AryFromStr -!======================================================================= !> \copydoc nwtc_io::readcarylines SUBROUTINE ReadR4AryLines ( UnIn, Fil, Ary, AryLen, AryName, AryDescr, ErrStat, ErrMsg, UnEc ) @@ -6709,55 +6203,6 @@ SUBROUTINE ReadR8AryLines ( UnIn, Fil, Ary, AryLen, AryName, AryDescr, ErrStat, RETURN END SUBROUTINE ReadR8AryLines !======================================================================= -!> \copydoc nwtc_io::readcarylines - SUBROUTINE ReadR16AryLines ( UnIn, Fil, Ary, AryLen, AryName, AryDescr, ErrStat, ErrMsg, UnEc ) - - - ! This routine reads a AryLen values into a real array from the next AryLen lines of the input file. - - - ! Argument declarations: - - INTEGER, INTENT(IN) :: AryLen ! Length of the array. - INTEGER, INTENT(IN) :: UnIn ! I/O unit for input file. - INTEGER, INTENT(IN), OPTIONAL:: UnEc ! I/O unit for echo file. If present and > 0, write to UnEc - INTEGER, INTENT(OUT) :: ErrStat ! Error status - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message associated with ErrStat - - REAL(QuKi), INTENT(OUT) :: Ary(AryLen) ! Real (16-byte) array being read. - - 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 :: Ind ! Index into the real array. Assumed to be one digit. - INTEGER :: IOS ! I/O status returned from the read statement. - - - - ErrStat = ErrID_None - ErrMsg = "" - - DO Ind=1,AryLen - READ (UnIn,*,IOSTAT=IOS) Ary(Ind) - - CALL CheckIOS ( IOS, Fil, TRIM( AryName )//'('//TRIM( Num2LStr( Ind ) )//')', NumType, ErrStat, ErrMsg ) - IF (ErrStat >= AbortErrLev) RETURN - CALL CheckRealVar( Ary(Ind), AryName, ErrStat, ErrMsg) - IF (ErrStat >= AbortErrLev) RETURN - - IF ( PRESENT(UnEc) ) THEN - IF ( UnEc > 0 ) & - WRITE (UnEc,Ec_ReFrmt) Ary(Ind), TRIM( AryName )//'('//TRIM( Int2LStr( Ind ) )//')', AryDescr - END IF - END DO - - RETURN - END SUBROUTINE ReadR16AryLines -!======================================================================= !> \copydoc nwtc_io::readcvar !! WARNING: this routine limits the size of the number being read to 30 characters SUBROUTINE ReadR4Var ( UnIn, Fil, Var, VarName, VarDescr, ErrStat, ErrMsg, UnEc ) @@ -6813,8 +6258,8 @@ SUBROUTINE ReadR4VarWDefault ( UnIn, Fil, Var, VarName, VarDescr, VarDefault, Er ! Argument declarations: - REAL(SiKi), INTENT(OUT) :: Var ! Variable being read - REAL(SiKi), INTENT(IN ) :: VarDefault ! Default value for variable being read + REAL(R4Ki), INTENT(OUT) :: Var ! Variable being read + REAL(R4Ki), INTENT(IN ) :: VarDefault ! Default value for variable being read INTEGER(IntKi),INTENT(OUT) :: ErrStat ! Error status; if present, program does not abort on error CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message @@ -6952,106 +6397,32 @@ SUBROUTINE ReadR8VarWDefault ( UnIn, Fil, Var, VarName, VarDescr, VarDefault, Er RETURN END SUBROUTINE ReadR8VarWDefault !======================================================================= -!> \copydoc nwtc_io::readcvar -!! WARNING: this routine limits the size of the number being read to 30 characters - SUBROUTINE ReadR16Var ( UnIn, Fil, Var, VarName, VarDescr, ErrStat, ErrMsg, UnEc ) - - - ! This routine reads a single double (real) variable from the next line of the input file. - ! New code should call ReadVar instead of directly calling this routine. - - - ! Argument declarations: - - REAL(QuKi), INTENT(OUT) :: Var ! Real (16-byte) variable being read. - INTEGER(IntKi),INTENT(OUT),OPTIONAL:: ErrStat ! Error status; if present, program does not abort on error - CHARACTER(*), INTENT(OUT),OPTIONAL:: ErrMsg ! Error message - - INTEGER, INTENT(IN) :: UnIn ! I/O unit for input file. - INTEGER, INTENT(IN), OPTIONAL:: UnEc ! I/O unit for echo file. If present and > 0, write to UnEc - - CHARACTER( *), INTENT(IN) :: Fil ! Name of the input file. - CHARACTER( *), INTENT(IN) :: VarDescr ! Text string describing the variable. - CHARACTER( *), INTENT(IN) :: VarName ! Text string containing the variable name. - - - ! Local declarations: - - INTEGER :: IOS ! I/O status returned from the read statement. - - CHARACTER(30) :: Word ! String to hold the first word on the line. - - - - - CALL ReadNum ( UnIn, Fil, Word, VarName, ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev) RETURN ! If we're about to read a T/F and treat it as a number, we have a less severe ErrStat - - - READ (Word,*,IOSTAT=IOS) Var - - CALL CheckIOS ( IOS, Fil, VarName, NumType, ErrStat, ErrMsg ) - IF (ErrStat >= AbortErrLev) RETURN - CALL CheckRealVar( Var, VarName, ErrStat, ErrMsg) - IF (ErrStat >= AbortErrLev) RETURN - - IF ( PRESENT(UnEc) ) THEN - IF ( UnEc > 0 ) & - WRITE (UnEc,Ec_ReFrmt) Var, VarName, VarDescr - END IF - - - RETURN - END SUBROUTINE ReadR16Var -!======================================================================= !> \copydoc nwtc_io::readr4varwdefault - SUBROUTINE ReadR16VarWDefault ( UnIn, Fil, Var, VarName, VarDescr, VarDefault, ErrStat, ErrMsg, UnEc ) - + SUBROUTINE ReadIAryWDefault ( UnIn, Fil, Var, AryLen, VarName, VarDescr, VarDefault, ErrStat, ErrMsg, UnEc ) ! Argument declarations: - - REAL(QuKi), INTENT(OUT) :: Var !< Variable being read - REAL(QuKi), INTENT(IN ) :: VarDefault !< Default value for variable being read - + INTEGER, INTENT(IN ) :: AryLen !< Length of the array. + INTEGER(IntKi), dimension(AryLen), INTENT(OUT) :: Var !< Variable being read + INTEGER(IntKi), dimension(AryLen), INTENT(IN ) :: VarDefault !< Default value for variable being read INTEGER(IntKi),INTENT(OUT) :: ErrStat !< Error status; if present, program does not abort on error CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message - INTEGER, INTENT(IN) :: UnIn !< I/O unit for input file. INTEGER, INTENT(IN), OPTIONAL:: UnEc !< I/O unit for echo file. If present and > 0, write to UnEc - CHARACTER( *), INTENT(IN) :: Fil !< Name of the input file. CHARACTER( *), INTENT(IN) :: VarDescr !< Text string describing the variable. CHARACTER( *), INTENT(IN) :: VarName !< Text string containing the variable name. - - ! Local declarations: - INTEGER :: IOS ! I/O status returned from the read statement. - CHARACTER(30) :: Word ! String to hold the first word on the line. - - - CALL ReadNum ( UnIn, Fil, Word, VarName, ErrStat, ErrMsg ) - IF ( ErrStat >= AbortErrLev) RETURN ! If we're about to read a T/F and treat it as a number, we have a less severe ErrStat - - - CALL Conv2UC( Word ) - IF ( INDEX(Word, "DEFAULT" ) /= 1 ) THEN ! If it's not "default", read this variable; otherwise use the DEFAULT value - READ (Word,*,IOSTAT=IOS) Var - - CALL CheckIOS ( IOS, Fil, VarName, NumType, ErrStat, ErrMsg ) - IF (ErrStat >= AbortErrLev) RETURN - CALL CheckRealVar( Var, VarName, ErrStat, ErrMsg) - IF (ErrStat >= AbortErrLev) RETURN + CHARACTER(1024) :: sVar ! String to hold the value of the variable + ! Read full content of variable as one string, should it be "default", or an array + CALL ReadVar (UnIn, Fil, sVar, VarName, VarDescr, ErrStat, ErrMsg, UnEc) + IF ( ErrStat >= AbortErrLev) RETURN + CALL Conv2UC( sVar ) + IF ( INDEX(sVar, "DEFAULT" ) /= 1 ) THEN ! If it's not "default", read this variable; otherwise use the DEFAULT value + call ReadIAryFromStr (sVar, Var, AryLen, VarName, VarDescr, ErrStat, ErrMsg) ELSE Var = VarDefault END IF - - IF ( PRESENT(UnEc) ) THEN - IF ( UnEc > 0 ) & - WRITE (UnEc,Ec_ReFrmt) Var, VarName, VarDescr - END IF - - RETURN - END SUBROUTINE ReadR16VarWDefault + END SUBROUTINE ReadIAryWDefault !======================================================================= !> This routine reads a string from the next line of the input file. SUBROUTINE ReadStr ( UnIn, Fil, CharVar, VarName, VarDescr, ErrStat, ErrMsg, UnEc ) @@ -7156,13 +6527,11 @@ RECURSIVE SUBROUTINE ScanComFile ( FirstFile, ThisFile, LastFile, StartLine, Las ErrMsg = "" ! Is this file already open from earlier in the recursion. That would be bad. - + ! But if it's being read by another thread, we allow it. FileName = ThisFile%Filename INQUIRE ( FILE=Filename, OPENED=IsOpen ) IF ( IsOpen ) THEN - CALL SetErrStat( ErrID_Fatal, 'Fatal error scanning "'//TRIM( Filename ) & - //'". A file cannot directly or indirectly include itself.', ErrStat, ErrMsg, RoutineName ) - RETURN + CALL SetErrStat( ErrID_Warn, 'The file being read is already opened (maybe by another thread?): "'//TRIM( Filename ), ErrStat, ErrMsg, RoutineName ) ENDIF @@ -7914,36 +7283,6 @@ SUBROUTINE WrMatrix1R8( A, Un, ReFmt, MatName ) RETURN END SUBROUTINE WrMatrix1R8 !======================================================================= -!> \copydoc nwtc_io::wrmatrix1r4 - SUBROUTINE WrMatrix1R16( A, Un, ReFmt, MatName ) - - REAL(QuKi), INTENT(IN) :: A(:) - INTEGER, INTENT(IN) :: Un - CHARACTER(*), INTENT(IN) :: ReFmt ! Format for printing ReKi numbers - CHARACTER(*), OPTIONAL, INTENT(IN) :: MatName - - INTEGER :: ErrStat - INTEGER :: nr ! size (rows and columns) of A - CHARACTER(256) :: Fmt - - - nr = SIZE(A,1) - - IF ( PRESENT(MatName) ) THEN - WRITE( Un, '(A,": ",A," x ",A)', IOSTAT=ErrStat ) TRIM(MatName), TRIM(Num2LStr(nr)), "1" - END IF - - Fmt = "(2x, "//TRIM(Num2LStr(nr))//"(1x,"//ReFmt//"))" - - WRITE( Un, Fmt, IOSTAT=ErrStat ) A(:) - IF (ErrStat /= 0) THEN - CALL WrScr('Error '//TRIM(Num2LStr(ErrStat))//' writing matrix in WrMatrix1R16().') - RETURN - END IF - - RETURN - END SUBROUTINE WrMatrix1R16 -!======================================================================= !> \copydoc nwtc_io::wrmatrix1r4 SUBROUTINE WrMatrix2R4( A, Un, ReFmt, MatName ) @@ -8016,42 +7355,6 @@ SUBROUTINE WrMatrix2R8( A, Un, ReFmt, MatName ) RETURN END SUBROUTINE WrMatrix2R8 !======================================================================= -!> \copydoc nwtc_io::wrmatrix1r4 - SUBROUTINE WrMatrix2R16( A, Un, ReFmt, MatName ) - - REAL(QuKi), INTENT(IN) :: A(:,:) - INTEGER, INTENT(IN) :: Un - CHARACTER(*), INTENT(IN) :: ReFmt ! Format for printing ReKi numbers - CHARACTER(*), OPTIONAL, INTENT(IN) :: MatName - - INTEGER :: ErrStat - INTEGER :: nr, nc ! size (rows and columns) of A - INTEGER :: i ! indices into A - CHARACTER(256) :: Fmt - - - nr = SIZE(A,1) - nc = SIZE(A,2) - - IF ( PRESENT(MatName) ) THEN - WRITE( Un, '(A,": ",A," x ",A)', IOSTAT=ErrStat ) TRIM(MatName), TRIM(Num2LStr(nr)), TRIM(Num2LStr(nc)) - END IF - - Fmt = "(2x, "//TRIM(Num2LStr(nc))//"(1x,"//ReFmt//"))" - - DO i=1,nr - WRITE( Un, Fmt, IOSTAT=ErrStat ) A(i,:) - IF (ErrStat /= 0) THEN - CALL WrScr('Error '//TRIM(Num2LStr(ErrStat))//' writing matrix in WrMatrix2R16().') - RETURN - END IF - - - END DO - - RETURN - END SUBROUTINE WrMatrix2R16 -!======================================================================= !> Based on nwtc_io::wrmatrix, this routine writes a matrix to an already-open text file. It allows !! the user to omit rows and columns of A in the the file. !! Use WrPartialMatrix (nwtc_io::wrpartialmatrix) instead of directly calling a specific routine in the generic interface. @@ -8384,46 +7687,6 @@ SUBROUTINE WrR8AryFileNR ( Unit, Ary, Fmt, ErrStat, ErrMsg ) RETURN END SUBROUTINE WrR8AryFileNR !======================================================================= -!> \copydoc nwtc_io::wrr4aryfilenr - SUBROUTINE WrR16AryFileNR ( Unit, Ary, Fmt, ErrStat, ErrMsg ) - - ! Argument declarations. - - INTEGER, INTENT(IN) :: Unit ! I/O unit for input file. - REAL(QuKi), INTENT(IN) :: Ary (:) ! Array to be written without a newline at the end. - CHARACTER(*), INTENT(IN) :: Fmt ! Fmt of one element to be written. - - INTEGER(IntKi), INTENT(OUT) :: ErrStat ! Error status - CHARACTER(*), INTENT(OUT) :: ErrMsg ! Error message associated with ErrStat - - ! Local variables: - CHARACTER(50) :: Fmt2 ! Fmt of entire array to be written (will be copied). - - - - IF ( SIZE(Ary) == 0 ) THEN - ErrStat = ErrID_None - ErrMsg = '' - RETURN - END IF - - - WRITE(Fmt2,*) SIZE(Ary) - Fmt2 = '('//TRIM(Fmt2)//'('//TRIM(Fmt)//'))' - - WRITE (Unit,Fmt2,ADVANCE='NO',IOSTAT=ErrStat) Ary - IF ( ErrStat /= 0 ) THEN - ErrStat = ErrID_Fatal - ErrMsg = 'WrR16AryFileNR:Error '//TRIM(Num2LStr(ErrStat))//' occurred while writing to file using this format: '//TRIM(Fmt2) - ELSE - ErrStat = ErrID_None - ErrMsg = '' - END IF - - - RETURN - END SUBROUTINE WrR16AryFileNR -!======================================================================= !> This routine writes out a string to the screen. RECURSIVE SUBROUTINE WrScr ( InStr ) @@ -8525,330 +7788,6 @@ SUBROUTINE WrScr1 ( Str ) RETURN END SUBROUTINE WrScr1 -!======================================================================= -!> This routine writes out the heading for an vtk xml file (associated footer generated in -!! nwtc_io::wrvtk_footer). It tries to open a text file for writing and returns the Unit number of the opened file. - SUBROUTINE WrVTK_header( FileName, NumberOfPoints, NumberOfLines, NumberOfPolys, Un, ErrStat, ErrMsg ) - - CHARACTER(*) , INTENT(IN ) :: FileName !< Name of output file - INTEGER(IntKi) , INTENT(IN ) :: NumberOfPoints !< Number of points in this VTK file - INTEGER(IntKi) , INTENT(IN ) :: NumberOfLines !< Number of lines in this VTK file - INTEGER(IntKi) , INTENT(IN ) :: NumberOfPolys !< Number of polygons in this VTK file - INTEGER(IntKi) , INTENT( OUT) :: Un !< unit number of opened file - INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< error level/status of OpenFOutFile operation - CHARACTER(*) , INTENT( OUT) :: ErrMsg !< message when error occurs - - CALL GetNewUnit( Un, ErrStat, ErrMsg ) - CALL OpenFOutFile ( Un, TRIM(FileName), ErrStat, ErrMsg ) - if (ErrStat >= AbortErrLev) return - - ! Write a VTP mesh file (Polygonal VTK file) with positions and polygons (surfaces) - ! (note alignment of WRITE statements to make sure spaces are lined up in XML file) - WRITE(Un,'(A)') '' - WRITE(Un,'(A)') '' ! bjj note: we don't have binary data in this file, so byte_order shouldn't matter, right? - WRITE(Un,'(A)') ' ' - WRITE(Un,'(2(A,i7),A)') ' ' - - RETURN - END SUBROUTINE WrVTK_header -!======================================================================= -!> This routine writes out the footer for an vtk xml file (associated header generated -!! in nwtc_io::wrvtk_header). It closes the file Un. - SUBROUTINE WrVTK_footer( Un ) - - INTEGER(IntKi) , INTENT(IN ) :: Un !< unit number of opened file - - WRITE(Un,'(A)') ' ' - WRITE(Un,'(A)') ' ' - WRITE(Un,'(A)') '' - CLOSE(Un) - - RETURN - END SUBROUTINE WrVTK_footer - -!======================================================================= -!> This routine reads the header for a vtk, ascii, structured_points dataset file, -!! including all the information about the structured points. It tries to open a -!! text file for reading and returns the Unit number of the opened file. -!! The caller is responsible for closing the file unit unless caller set Un = -1! - SUBROUTINE ReadVTK_SP_info( FileName, descr, dims, origin, gridSpacing, vecLabel, Un, ErrStat, ErrMsg ) - - CHARACTER(*) , INTENT(IN ) :: FileName !< Name of output file - CHARACTER(1024) , INTENT( OUT) :: descr !< Line describing the contents of the file - INTEGER(IntKi) , INTENT( OUT) :: dims(3) !< dimension of the 3D grid (nX,nY,nZ) - REAL(ReKi) , INTENT( OUT) :: origin(3) !< the lower-left corner of the 3D grid (X0,Y0,Z0) - REAL(ReKi) , INTENT( OUT) :: gridSpacing(3) !< spacing between grid points in each of the 3 directions (dX,dY,dZ) - CHARACTER(1024) , INTENT( OUT) :: vecLabel - INTEGER(IntKi) , INTENT(INOUT) :: Un !< unit number of opened file - INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< error level/status of OpenFOutFile operation - CHARACTER(*) , INTENT( OUT) :: ErrMsg !< message when error occurs - - INTEGER(IntKi) :: ErrStat2 ! local error level/status of OpenFOutFile operation - CHARACTER(ErrMsgLen) :: ErrMsg2 ! local message when error occurs - CHARACTER(1024) :: Dummy1, Dummy2 - CHARACTER(1024) :: Line ! one line of the file - CHARACTER(1024) :: formatLbl - CHARACTER(*), PARAMETER :: RoutineName = 'ReadVTK_SP_info' - INTEGER(IntKi) :: sz, nPts, nArr, nums(2) - LOGICAL :: closeOnReturn - - ErrStat = ErrID_None - ErrMsg = '' - - IF (Un == -1 ) THEN - closeOnReturn = .TRUE. - ELSE - closeOnReturn = .FALSE. - END IF - - CALL GetNewUnit( Un, ErrStat, ErrMsg ) - CALL OpenFInpFile ( Un, TRIM(FileName), ErrStat, ErrMsg ) - if (ErrStat >= AbortErrLev) return - - CALL ReadCom( Un, FileName, 'File header: Module Version (line 1)', ErrStat2, ErrMsg2, 0 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL ReadStr( Un, FileName, descr, 'descr', 'File Description line', ErrStat2, ErrMsg2, 0 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - formatLbl = "" - CALL ReadStr( Un, FileName, formatLbl, 'formatLbl', 'ASCII label', ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - call Conv2UC(formatLbl) - if (INDEX(formatLbl, "ASCII" ) /= 1 ) THEN ! If this line doesn't contain the word ASCII, we have a bad file header - CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find ASCII label', ErrStat, ErrMsg, RoutineName ) - end if - Line = "" - CALL ReadStr( Un, FileName, Line, "dataset", "DATASET STRUCTURED_POINTS", ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - CALL Conv2UC( Line ) - IF ( INDEX(Line, "DATASET" ) /= 1 ) THEN ! If this line doesn't contain the word dataset, we have a bad file header - CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find DATASET label', ErrStat, ErrMsg, RoutineName ) - END IF - IF ( INDEX(Line, "STRUCTURED_POINTS" ) == 0 ) THEN ! If this line doesn't also contain the word structured_points, we have a bad file header - CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find STRUCTURED_POINTS label', ErrStat, ErrMsg, RoutineName ) - end if - - ! Dimensions - Line = "" - CALL ReadStr( Un, FileName, Line, "Dimensions", "DIMENSIONS data", ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - Line = trim(Line) - CALL Conv2UC( Line ) - IF ( INDEX(Line, "DIMENSIONS" ) /= 1 ) THEN ! If this line doesn't contain the word dataset, we have a bad file header - CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find DIMENSIONS label', ErrStat, ErrMsg, RoutineName ) - ELSE - sz = len(Line) - Line = Line(12:sz) - READ(Line,*, IOSTAT=ErrStat2) dims - if (ErrStat2 /= 0) then - CALL SetErrStat( ErrID_Fatal, 'Error reading "dims".', ErrStat, ErrMsg, RoutineName ) - end if - END IF - - ! Origin - Line = "" - CALL ReadStr( Un, FileName, Line, "Origin", "ORIGIN data", ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - Line = trim(Line) - CALL Conv2UC( Line ) - IF ( INDEX(Line, "ORIGIN" ) /= 1 ) THEN ! If this line doesn't contain the word dataset, we have a bad file header - CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find ORIGIN label', ErrStat, ErrMsg, RoutineName ) - ELSE - sz = len(Line) - Line = Line(8:sz) - READ(Line,*, IOSTAT=ErrStat2) origin - if (ErrStat2 /= 0) then - CALL SetErrStat( ErrID_Fatal, 'Error reading "origin".', ErrStat, ErrMsg, RoutineName ) - end if - - END IF - - ! Spacing - Line = "" - CALL ReadStr( Un, FileName, Line, "gridSpacing", "SPACING data", ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - Line = trim(Line) - CALL Conv2UC( Line ) - IF ( INDEX(Line, "SPACING" ) /= 1 ) THEN ! If this line doesn't contain the word dataset, we have a bad file header - CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find SPACING label', ErrStat, ErrMsg, RoutineName ) - ELSE - sz = len(Line) - Line = Line(9:sz) - READ(Line,*,IOSTAT=ErrStat2) gridSpacing - if (ErrStat2 /= 0) then - CALL SetErrStat( ErrID_Fatal, 'Error reading "gridSpacing".', ErrStat, ErrMsg, RoutineName ) - end if - - END IF - - ! Point Data - Line = "" - CALL ReadStr( Un, FileName, Line, "Point_Data", "POINT_DATA", ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - Line = trim(Line) - CALL Conv2UC( Line ) - IF ( INDEX(Line, "POINT_DATA" ) /= 1 ) THEN ! If this line doesn't contain the word dataset, we have a bad file header - CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find POINT_DATA label', ErrStat, ErrMsg, RoutineName ) - ELSE - sz = len(Line) - Line = Line(12:sz) - READ(Line,*,IOSTAT=ErrStat2) nPts - if (ErrStat2 /= 0) then - CALL SetErrStat( ErrID_Fatal, 'Error reading "nPts".', ErrStat, ErrMsg, RoutineName ) - end if - IF ( nPts /= ( dims(1)*dims(2)*dims(3) ) ) THEN ! Abort if DIMENSIONS AND POINT_DATA don't agree - CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: POINT_DATA does not match DIMENSIONS', ErrStat, ErrMsg, RoutineName ) - END IF - END IF - - ! VECTOR or FIELD Label - Line = "" - CALL ReadStr( Un, FileName, Line, "VECTORS or FIELD", "VECTORS or FIELD label", ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - Line = trim(Line) - CALL Conv2UC( Line ) - IF ( ( INDEX(Line, "VECTORS" ) /= 1 ) .AND. ( INDEX(Line, "FIELD" ) /= 1 ) ) THEN - CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find VECTORS or FIELD label', ErrStat, ErrMsg, RoutineName ) - ELSE - IF ( INDEX(Line, "FIELD" ) == 1 ) THEN ! Must be FIELD - READ(Line,*,IOSTAT=ErrStat2) Dummy1, Dummy2, nArr - if (ErrStat2 /= 0) then - CALL SetErrStat( ErrID_Fatal, 'Error reading "nArr".', ErrStat, ErrMsg, RoutineName ) - ELSE IF ( nArr /= 1_IntKi ) THEN - CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: FIELD label must have only 1 array', ErrStat, ErrMsg, RoutineName ) - END IF - - Line = "" - CALL ReadStr( Un, FileName, Line, "Array", "Array definition", ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - Line = trim(Line) - Call Conv2UC( Line ) - sz = INDEX(Line, "FLOAT" ) - IF ( sz == 0 ) THEN - CALL SetErrStat( ErrID_Fatal, 'Invalid FIELD datatype. Must be set to float.', ErrStat, ErrMsg, RoutineName ) - ELSE - READ(Line,*,IOSTAT=ErrStat2) Dummy1, nums - if (ErrStat2 /= 0) then - CALL SetErrStat( ErrID_Fatal, 'Error reading "nums".', ErrStat, ErrMsg, RoutineName ) - ELSEIF ( nums(1) /= 3_IntKi ) THEN ! Abort if we don't have 3-element vectors - CALL SetErrStat( ErrID_Fatal, 'Invalid FIELD datatype. FIELD array must have 3 elements.', ErrStat, ErrMsg, RoutineName ) - ELSEIF ( nums(2) /= ( dims(1)*dims(2)*dims(3) ) ) THEN ! Abort if DIMENSIONS AND FIELD data don't agree - CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: FIELD array does not match DIMENSIONS', ErrStat, ErrMsg, RoutineName ) - END IF - END IF - ELSE ! Must be VECTORS - sz = INDEX(Line, "FLOAT" ) - IF ( sz == 0 ) THEN - CALL SetErrStat( ErrID_Fatal, 'Invalid VECTORS datatype. Must be set to float.', ErrStat, ErrMsg, RoutineName ) - ELSE - vecLabel = Line(9:sz-2) - END IF - END IF - END IF - - IF ( (ErrStat >= AbortErrLev) .or. closeOnReturn ) THEN - close(Un) - Un = -1 - RETURN - END IF - - RETURN - END SUBROUTINE ReadVTK_SP_info - -!======================================================================= -!> This routine reads the vector data for a vtk, ascii, structured_points dataset file, -!! The Unit number of the file is already assumed to be valid via a previous call to -!! ReadVTK_SP_info. - SUBROUTINE ReadVTK_SP_vectors( FileName, Un, dims, gridVals, ErrStat, ErrMsg ) - - CHARACTER(*) , INTENT(IN ) :: FileName !< Name of output file - INTEGER(IntKi) , INTENT(IN ) :: Un !< unit number of opened file - INTEGER(IntKi) , INTENT(IN ) :: dims(3) !< dimension of the 3D grid (nX,nY,nZ) - REAL(SiKi) , INTENT( OUT) :: gridVals(:,:,:,:) !< 4D array of data, size (3,nX,nY,nZ), must be pre-allocated - INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< error level/status of OpenFOutFile operation - CHARACTER(*) , INTENT( OUT) :: ErrMsg !< message when error occurs - - INTEGER :: ErrStat2 - - ErrStat = ErrID_None - ErrMsg = '' - - READ(Un,*, IOSTAT=ErrStat2) gridVals(1:3,1:dims(1),1:dims(2),1:dims(3)) - - close(Un) - if (ErrStat2 /= 0) then - CALL SetErrStat( ErrID_Fatal, 'Invalid vtk file: '//trim(FileName)//'.', ErrStat, ErrMsg, 'ReadVTK_SP_vectors' ) - end if - - END SUBROUTINE ReadVTK_SP_vectors - -!======================================================================= -!> This routine writes out the heading for an vtk, ascii, structured_points dataset file . -!! It tries to open a text file for writing and returns the Unit number of the opened file. - SUBROUTINE WrVTK_SP_header( FileName, descr, Un, ErrStat, ErrMsg ) - - CHARACTER(*) , INTENT(IN ) :: FileName !< Name of output file - CHARACTER(*) , INTENT(IN ) :: descr !< Line describing the contents of the file - INTEGER(IntKi) , INTENT( OUT) :: Un !< unit number of opened file - INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< error level/status of OpenFOutFile operation - CHARACTER(*) , INTENT( OUT) :: ErrMsg !< message when error occurs - - CALL GetNewUnit( Un, ErrStat, ErrMsg ) - CALL OpenFOutFile ( Un, TRIM(FileName), ErrStat, ErrMsg ) - if (ErrStat >= AbortErrLev) return - - WRITE(Un,'(A)') '# vtk DataFile Version 3.0' - WRITE(Un,'(A)') trim(descr) - WRITE(Un,'(A)') 'ASCII' - WRITE(Un,'(A)') 'DATASET STRUCTURED_POINTS' - - RETURN - END SUBROUTINE WrVTK_SP_header - - - SUBROUTINE WrVTK_SP_vectors3D( Un, dataDescr, dims, origin, gridSpacing, gridVals, ErrStat, ErrMsg ) - - INTEGER(IntKi) , INTENT(IN ) :: Un !< unit number of previously opened file (via call to WrVTK_SP_header) - CHARACTER(*) , INTENT(IN ) :: dataDescr !< Short label describing the vector data - INTEGER(IntKi) , INTENT(IN ) :: dims(3) !< dimension of the 3D grid (nX,nY,nZ) - REAL(ReKi) , INTENT(IN ) :: origin(3) !< the lower-left corner of the 3D grid (X0,Y0,Z0) - REAL(ReKi) , INTENT(IN ) :: gridSpacing(3) !< spacing between grid points in each of the 3 directions (dX,dY,dZ) - REAL(SiKi) , INTENT(IN ) :: gridVals(:,:,:,:) !< 3D array of data, size (nX,nY,nZ) - INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< error level/status of OpenFOutFile operation - CHARACTER(*) , INTENT( OUT) :: ErrMsg !< message when error occurs - - INTEGER(IntKi) :: nPts ! Total number of grid points - - if ( .not. (Un > 0) ) then - ErrStat = ErrID_Fatal - ErrMsg = 'WrVTK_SP_points: Invalid file unit, be sure to call WrVTK_SP_header prior to calling WrVTK_SP_points.' - return - end if - - ErrStat = ErrID_None - ErrMsg = '' - nPts = dims(1)*dims(2)*dims(3) - - ! Note: gridVals must be stored such that the left-most dimension is X and the right-most dimension is Z - WRITE(Un,'(A,3(i5,1X))') 'DIMENSIONS ', dims - WRITE(Un,'(A,3(f10.2,1X))') 'ORIGIN ' , origin - WRITE(Un,'(A,3(f10.2,1X))') 'SPACING ' , gridSpacing - WRITE(Un,'(A,i15)') 'POINT_DATA ', nPts - WRITE(Un,'(A)') 'VECTORS '//trim(dataDescr)//' float' - WRITE(Un,'(3(f10.2,1X))') gridVals - close(Un) - RETURN - - END SUBROUTINE WrVTK_SP_vectors3D END MODULE NWTC_IO diff --git a/modules/nwtc-library/src/NWTC_Library.f90 b/modules/nwtc-library/src/NWTC_Library.f90 index 232c9c971..77d1388f8 100644 --- a/modules/nwtc-library/src/NWTC_Library.f90 +++ b/modules/nwtc-library/src/NWTC_Library.f90 @@ -71,6 +71,7 @@ MODULE NWTC_Library !! (without this, it is possible [depending on the Sys*.f90 file used] that the screen output will be written to a !! file called "fort.7") + USE NWTC_Library_Types USE NWTC_Num ! technically we don't need to specify this if we have ModMesh (because ModMesh USEs NWTC_Num) USE ModMesh diff --git a/modules/nwtc-library/src/NWTC_Library_Types.f90 b/modules/nwtc-library/src/NWTC_Library_Types.f90 index 47550fd32..ebe2e74a6 100644 --- a/modules/nwtc-library/src/NWTC_Library_Types.f90 +++ b/modules/nwtc-library/src/NWTC_Library_Types.f90 @@ -137,15 +137,27 @@ SUBROUTINE NWTC_Library_CopyProgDesc( SrcProgDescData, DstProgDescData, CtrlCode DstProgDescData%Date = SrcProgDescData%Date END SUBROUTINE NWTC_Library_CopyProgDesc - SUBROUTINE NWTC_Library_DestroyProgDesc( ProgDescData, ErrStat, ErrMsg ) + SUBROUTINE NWTC_Library_DestroyProgDesc( ProgDescData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ProgDesc), INTENT(INOUT) :: ProgDescData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyProgDesc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyProgDesc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE NWTC_Library_DestroyProgDesc SUBROUTINE NWTC_Library_PackProgDesc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -330,15 +342,27 @@ SUBROUTINE NWTC_Library_CopyFASTdataType( SrcFASTdataTypeData, DstFASTdataTypeDa ENDIF END SUBROUTINE NWTC_Library_CopyFASTdataType - SUBROUTINE NWTC_Library_DestroyFASTdataType( FASTdataTypeData, ErrStat, ErrMsg ) + SUBROUTINE NWTC_Library_DestroyFASTdataType( FASTdataTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FASTdataType), INTENT(INOUT) :: FASTdataTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyFASTdataType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyFASTdataType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(FASTdataTypeData%ChanNames)) THEN DEALLOCATE(FASTdataTypeData%ChanNames) ENDIF @@ -629,15 +653,27 @@ SUBROUTINE NWTC_Library_CopyOutParmType( SrcOutParmTypeData, DstOutParmTypeData, DstOutParmTypeData%SignM = SrcOutParmTypeData%SignM END SUBROUTINE NWTC_Library_CopyOutParmType - SUBROUTINE NWTC_Library_DestroyOutParmType( OutParmTypeData, ErrStat, ErrMsg ) + SUBROUTINE NWTC_Library_DestroyOutParmType( OutParmTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(OutParmType), INTENT(INOUT) :: OutParmTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyOutParmType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyOutParmType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE NWTC_Library_DestroyOutParmType SUBROUTINE NWTC_Library_PackOutParmType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -827,15 +863,27 @@ SUBROUTINE NWTC_Library_CopyFileInfoType( SrcFileInfoTypeData, DstFileInfoTypeDa ENDIF END SUBROUTINE NWTC_Library_CopyFileInfoType - SUBROUTINE NWTC_Library_DestroyFileInfoType( FileInfoTypeData, ErrStat, ErrMsg ) + SUBROUTINE NWTC_Library_DestroyFileInfoType( FileInfoTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FileInfoType), INTENT(INOUT) :: FileInfoTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyFileInfoType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyFileInfoType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(FileInfoTypeData%FileLine)) THEN DEALLOCATE(FileInfoTypeData%FileLine) ENDIF @@ -1132,15 +1180,27 @@ SUBROUTINE NWTC_Library_CopyQuaternion( SrcQuaternionData, DstQuaternionData, Ct DstQuaternionData%v = SrcQuaternionData%v END SUBROUTINE NWTC_Library_CopyQuaternion - SUBROUTINE NWTC_Library_DestroyQuaternion( QuaternionData, ErrStat, ErrMsg ) + SUBROUTINE NWTC_Library_DestroyQuaternion( QuaternionData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Quaternion), INTENT(INOUT) :: QuaternionData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyQuaternion' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyQuaternion' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE NWTC_Library_DestroyQuaternion SUBROUTINE NWTC_Library_PackQuaternion( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1284,15 +1344,27 @@ SUBROUTINE NWTC_Library_CopyNWTC_RandomNumber_ParameterType( SrcNWTC_RandomNumbe 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 ) + SUBROUTINE NWTC_Library_DestroyNWTC_RandomNumber_ParameterType( NWTC_RandomNumber_ParameterTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) 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' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'NWTC_Library_DestroyNWTC_RandomNumber_ParameterType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(NWTC_RandomNumber_ParameterTypeData%RandSeedAry)) THEN DEALLOCATE(NWTC_RandomNumber_ParameterTypeData%RandSeedAry) ENDIF diff --git a/modules/nwtc-library/src/NWTC_Num.f90 b/modules/nwtc-library/src/NWTC_Num.f90 index 815410987..de4fcd8de 100644 --- a/modules/nwtc-library/src/NWTC_Num.f90 +++ b/modules/nwtc-library/src/NWTC_Num.f90 @@ -69,11 +69,9 @@ MODULE NWTC_Num 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 REAL(SiKi) :: TwoPi_R4 !< 2*pi in 4-byte precision REAL(R8Ki) :: TwoPi_R8 !< 2*pi in 8-byte precision - REAL(QuKi) :: TwoPi_R16 !< 2*pi in 16-byte precision ! constants for kernel smoothing INTEGER, PARAMETER :: kernelType_EPANECHINIKOV = 1 @@ -96,21 +94,22 @@ MODULE NWTC_Num INTERFACE EqualRealNos MODULE PROCEDURE EqualRealNos4 MODULE PROCEDURE EqualRealNos8 - MODULE PROCEDURE EqualRealNos16 END INTERFACE !> \copydoc nwtc_num::eulerconstructr4() INTERFACE EulerConstruct MODULE PROCEDURE EulerConstructR4 MODULE PROCEDURE EulerConstructR8 - MODULE PROCEDURE EulerConstructR16 + END INTERFACE + + INTERFACE EulerConstructZYX + MODULE PROCEDURE EulerConstructZYXR8 END INTERFACE !> \copydoc nwtc_num::eulerextractr4() INTERFACE EulerExtract MODULE PROCEDURE EulerExtractR4 MODULE PROCEDURE EulerExtractR8 - MODULE PROCEDURE EulerExtractR16 END INTERFACE !> \copydoc nwtc_num::taitbryanyxzextractr4() @@ -118,20 +117,17 @@ MODULE NWTC_Num INTERFACE TaitBryanYXZExtract MODULE PROCEDURE TaitBryanYXZExtractR4 MODULE PROCEDURE TaitBryanYXZExtractR8 - MODULE PROCEDURE TaitBryanYXZExtractR16 END INTERFACE INTERFACE TaitBryanYXZConstruct MODULE PROCEDURE TaitBryanYXZConstructR4 MODULE PROCEDURE TaitBryanYXZConstructR8 - MODULE PROCEDURE TaitBryanYXZConstructR16 END INTERFACE !> \copydoc nwtc_num::outerproductr4 INTERFACE OuterProduct MODULE PROCEDURE OuterProductR4 MODULE PROCEDURE OuterProductR8 - MODULE PROCEDURE OuterProductR16 END INTERFACE !> \copydoc nwtc_num::cross_productr4() @@ -140,12 +136,10 @@ MODULE NWTC_Num MODULE PROCEDURE Cross_ProductR4R8 MODULE PROCEDURE Cross_ProductR8 MODULE PROCEDURE Cross_ProductR8R4 - MODULE PROCEDURE Cross_ProductR16 END INTERFACE !> \copydoc nwtc_num::smllrottransd() INTERFACE SmllRotTrans - MODULE PROCEDURE SmllRotTransDD MODULE PROCEDURE SmllRotTransD MODULE PROCEDURE SmllRotTransR END INTERFACE @@ -160,21 +154,18 @@ MODULE NWTC_Num INTERFACE Zero2TwoPi MODULE PROCEDURE Zero2TwoPiR4 MODULE PROCEDURE Zero2TwoPiR8 - MODULE PROCEDURE Zero2TwoPiR16 END INTERFACE !> \copydoc nwtc_num::twonormr4 INTERFACE TwoNorm MODULE PROCEDURE TwoNormR4 MODULE PROCEDURE TwoNormR8 - MODULE PROCEDURE TwoNormR16 END INTERFACE !> \copydoc nwtc_num::tracer4 INTERFACE trace MODULE PROCEDURE traceR4 MODULE PROCEDURE traceR8 - MODULE PROCEDURE traceR16 END INTERFACE !> \copydoc nwtc_num::dcm_expd @@ -213,18 +204,15 @@ MODULE NWTC_Num INTERFACE InterpStp MODULE PROCEDURE InterpStpComp4 MODULE PROCEDURE InterpStpComp8 - MODULE PROCEDURE InterpStpComp16 MODULE PROCEDURE InterpStpReal4 MODULE PROCEDURE InterpStpReal4_8 MODULE PROCEDURE InterpStpReal8 - MODULE PROCEDURE InterpStpReal16 END INTERFACE !> \copydoc nwtc_num::interparrayr4 INTERFACE InterpArray MODULE PROCEDURE InterpArrayR4 MODULE PROCEDURE InterpArrayR8 - MODULE PROCEDURE InterpArrayR16 END INTERFACE !> \copydoc nwtc_num::interpwrappedstpreal4 @@ -232,51 +220,42 @@ MODULE NWTC_Num MODULE PROCEDURE InterpWrappedStpReal4 MODULE PROCEDURE InterpWrappedStpReal4_8 MODULE PROCEDURE InterpWrappedStpReal8 - MODULE PROCEDURE InterpWrappedStpReal16 END INTERFACE !> \copydoc nwtc_num::locatestpr4 INTERFACE LocateStp MODULE PROCEDURE LocateStpR4 MODULE PROCEDURE LocateStpR8 - MODULE PROCEDURE LocateStpR16 END INTERFACE !> \copydoc nwtc_num::skewsymmatr4 INTERFACE SkewSymMat MODULE PROCEDURE SkewSymMatR4 MODULE PROCEDURE SkewSymMatR8 - MODULE PROCEDURE SkewSymMatR16 END INTERFACE !> \copydoc nwtc_num::angle_extrapinterp2_r4 INTERFACE Angles_ExtrapInterp MODULE PROCEDURE Angles_ExtrapInterp1_R4 MODULE PROCEDURE Angles_ExtrapInterp1_R8 - MODULE PROCEDURE Angles_ExtrapInterp1_R16 MODULE PROCEDURE Angles_ExtrapInterp1_R4R MODULE PROCEDURE Angles_ExtrapInterp1_R8R - MODULE PROCEDURE Angles_ExtrapInterp1_R16R MODULE PROCEDURE Angles_ExtrapInterp2_R4 MODULE PROCEDURE Angles_ExtrapInterp2_R8 - MODULE PROCEDURE Angles_ExtrapInterp2_R16 MODULE PROCEDURE Angles_ExtrapInterp2_R4R MODULE PROCEDURE Angles_ExtrapInterp2_R8R - MODULE PROCEDURE Angles_ExtrapInterp2_R16R END INTERFACE !> \copydoc nwtc_num::addorsub2pi_r4 INTERFACE AddOrSub2Pi MODULE PROCEDURE AddOrSub2Pi_R4 MODULE PROCEDURE AddOrSub2Pi_R8 - MODULE PROCEDURE AddOrSub2Pi_R16 END INTERFACE !> \copydoc nwtc_num::mpi2pi_r4 INTERFACE MPi2Pi MODULE PROCEDURE MPi2Pi_R4 MODULE PROCEDURE MPi2Pi_R8 - MODULE PROCEDURE MPi2Pi_R16 END INTERFACE CONTAINS @@ -350,36 +329,6 @@ SUBROUTINE AddOrSub2Pi_R8 ( OldAngle, NewAngle ) RETURN END SUBROUTINE AddOrSub2Pi_R8 -!======================================================================= -!> \copydoc nwtc_num::addorsub2pi_r4 - SUBROUTINE AddOrSub2Pi_R16 ( OldAngle, NewAngle ) - - ! Argument declarations: - - REAL(QuKi), INTENT(IN ) :: OldAngle ! Angle from which NewAngle will be converted to within 2*Pi of, rad. - REAL(QuKi), INTENT(INOUT) :: NewAngle ! Angle to be converted to within 2*Pi of OldAngle, rad. - - - ! Local declarations: - - REAL(QuKi) :: DelAngle ! The difference between OldAngle and NewAngle, rad. - - - - ! Add or subtract 2*Pi in order to convert NewAngle two within Pi of OldAngle: - - - DelAngle = OldAngle - NewAngle - - DO WHILE ( ABS( DelAngle ) > Pi_R16 ) - - NewAngle = NewAngle + SIGN( TwoPi_R16, DelAngle ) - DelAngle = OldAngle - NewAngle - - END DO - - RETURN - END SUBROUTINE AddOrSub2Pi_R16 !======================================================================= FUNCTION BlendCosine( x, LowerBound, UpperBound ) RESULT(S) @@ -615,26 +564,6 @@ FUNCTION Cross_ProductR8R4(Vector1, Vector2) result(CProd) RETURN END FUNCTION Cross_ProductR8R4 !======================================================================= -!> \copydoc nwtc_num::cross_productr4 - FUNCTION Cross_ProductR16(Vector1, Vector2) result(CProd) - - ! Argument declarations. - - REAL(QuKi), INTENT(IN ) :: Vector1 (3) - REAL(QuKi), INTENT(IN ) :: Vector2 (3) - - ! Function definition - REAL(QuKi) :: CProd (3) ! = Vector1 X Vector2 (resulting in a vector) - - - CProd(1) = Vector1(2)*Vector2(3) - Vector1(3)*Vector2(2) - CProd(2) = Vector1(3)*Vector2(1) - Vector1(1)*Vector2(3) - CProd(3) = Vector1(1)*Vector2(2) - Vector1(2)*Vector2(1) - - - RETURN - END FUNCTION Cross_ProductR16 -!======================================================================= !> This routine calculates the parameters needed to compute a irregularly-spaced natural cubic spline. !! Natural cubic splines are used in that the curvature at the end points is zero. !! This routine does not require that the XAry be regularly spaced. @@ -1221,14 +1150,14 @@ FUNCTION DCM_expR(lambda) ! ! "'Interpolation' of DCMs", M.A. Sprague, 11 March 2014, Eq. 31-33 - REAL(ReKi), INTENT(IN) :: lambda(3) !< vector containing unique components of skew-symmetric matrix: \f$\lambda_1\f$, \f$\lambda_2\f$, and \f$\lambda_3\f$ - REAL(ReKi) :: DCM_expR(3,3) !< the computed matrix exponential, \f$\Lambda\f$ + REAL(SiKi), INTENT(IN) :: lambda(3) !< vector containing unique components of skew-symmetric matrix: \f$\lambda_1\f$, \f$\lambda_2\f$, and \f$\lambda_3\f$ + REAL(SiKi) :: DCM_expR(3,3) !< the computed matrix exponential, \f$\Lambda\f$ ! local variables - REAL(ReKi) :: stheta ! sine of angle of rotation - REAL(ReKi) :: theta ! angle of rotation - REAL(ReKi) :: theta2 ! angle of rotation squared - REAL(ReKi) :: tmp_Mat(3,3) + REAL(SiKi) :: stheta ! sine of angle of rotation + REAL(SiKi) :: theta ! angle of rotation + REAL(SiKi) :: theta2 ! angle of rotation squared + REAL(SiKi) :: tmp_Mat(3,3) INTEGER(IntKi) :: ErrStat CHARACTER(30) :: ErrMsg @@ -1237,8 +1166,8 @@ FUNCTION DCM_expR(lambda) theta = TwoNorm(lambda) ! Eq. 32 theta2 = theta**2 - IF ( EqualRealNos(theta, 0.0_ReKi) .or. & - EqualRealNos(theta2, 0.0_ReKi) ) THEN ! + IF ( EqualRealNos(theta, 0.0_SiKi) .or. & + EqualRealNos(theta2, 0.0_SiKi) ) THEN ! CALL eye(DCM_expR, ErrStat, ErrMsg) ! Eq. 33a @@ -1246,15 +1175,15 @@ FUNCTION DCM_expR(lambda) ! convert lambda to skew-symmetric matrix: !tmp_mat = -SkewSymMat(lambda) - tmp_mat(1,1) = 0.0_ReKi + tmp_mat(1,1) = 0.0_SiKi tmp_mat(2,1) = -lambda(3) tmp_mat(3,1) = lambda(2) tmp_mat(1,2) = lambda(3) - tmp_mat(2,2) = 0.0_ReKi + tmp_mat(2,2) = 0.0_SiKi tmp_mat(3,2) = -lambda(1) tmp_mat(1,3) = -lambda(2) tmp_mat(2,3) = lambda(1) - tmp_mat(3,3) = 0.0_ReKi + tmp_mat(3,3) = 0.0_SiKi ! Eq. 33b @@ -1433,18 +1362,18 @@ SUBROUTINE DCM_logMapR(DCM, logMap, ErrStat, ErrMsg, thetaOut) ! This function computes the logarithmic map for a direction cosine matrix. - REAL(ReKi), INTENT(IN) :: DCM(3,3) - REAL(ReKi), INTENT( OUT) :: logMap(3) - REAL(ReKi),OPTIONAL,INTENT( OUT) :: thetaOut + REAL(SiKi), INTENT(IN) :: DCM(3,3) + REAL(SiKi), INTENT( OUT) :: logMap(3) + REAL(SiKi),OPTIONAL,INTENT( OUT) :: thetaOut INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! local variables - REAL(ReKi) :: cosTheta - REAL(ReKi) :: theta - REAL(ReKi) :: TwoSinTheta - REAL(ReKi) :: v(3) - REAL(ReKi) :: divisor + REAL(SiKi) :: cosTheta + REAL(SiKi) :: theta + REAL(SiKi) :: TwoSinTheta + REAL(SiKi) :: v(3) + REAL(SiKi) :: divisor INTEGER(IntKi) :: indx_max ! initialization @@ -1452,13 +1381,13 @@ SUBROUTINE DCM_logMapR(DCM, logMap, ErrStat, ErrMsg, thetaOut) ErrMsg = "" - cosTheta = 0.5_ReKi*( trace(DCM) - 1.0_ReKi ) - cosTheta = min( max(cosTheta,-1.0_ReKi), 1.0_ReKi ) !make sure it's in a valid range (to avoid cases where this is slightly outside the +/-1 range) + cosTheta = 0.5_SiKi*( trace(DCM) - 1.0_SiKi ) + cosTheta = min( max(cosTheta,-1.0_SiKi), 1.0_SiKi ) !make sure it's in a valid range (to avoid cases where this is slightly outside the +/-1 range) theta = ACOS( cosTheta ) ! Eq. 25 ( 0<=theta<=pi ) !IF ( EqualRealNos( pi, theta ) ) THEN - IF ( theta > 3.1_ReKi ) THEN ! theta/(2*sin(theta)) blows up quickly as theta approaches pi, + IF ( theta > 3.1_SiKi ) THEN ! theta/(2*sin(theta)) blows up quickly as theta approaches pi, ! so I'm putting a pretty large tolerance on pi here, and using a different equation to find the solution near pi logMap(1) = 1.0_ReKi + DCM(1,1) - DCM(2,2) - DCM(3,3); @@ -1467,7 +1396,7 @@ SUBROUTINE DCM_logMapR(DCM, logMap, ErrStat, ErrMsg, thetaOut) indx_max = maxloc( abs(logMap), 1 ) - divisor = sqrt(abs( logMap(indx_max) * 2.0_ReKi*(1.0_ReKi - cosTheta) )) / theta ! 2*(1-cosTheta)/theta^2 * abs(lambda(indx_max)) + divisor = sqrt(abs( logMap(indx_max) * 2.0_SiKi*(1.0_SiKi - cosTheta) )) / theta ! 2*(1-cosTheta)/theta^2 * abs(lambda(indx_max)) if (indx_max == 1) then !logMap(1) = 1.0 + DCM(1,1) - DCM(2,2) - DCM(3,3) ! 2*(1-cosTheta)/theta^2 * lambda(1) * lambda(1) logMap(2) = DCM(1,2) + DCM(2,1) ! 2*(1-cosTheta)/theta^2 * lambda(1) * lambda(2) @@ -1486,20 +1415,20 @@ SUBROUTINE DCM_logMapR(DCM, logMap, ErrStat, ErrMsg, thetaOut) ! at this point we may have the wrong sign for logMap (though if theta==pi, it doesn't matter because we can change it in the DCM_setLogMapforInterp() routines) ! we'll do a little checking to see if we should change the sign: - IF ( EqualRealNos( pi, theta ) ) RETURN + IF ( EqualRealNos( Pi_S, theta ) ) RETURN v(1) = -DCM(3,2) + DCM(2,3) !-skewSym(3,2) v(2) = DCM(3,1) - DCM(1,3) ! skewSym(3,1) v(3) = -DCM(2,1) + DCM(1,2) !-skewSym(2,1) indx_max = maxloc( abs(v), 1 ) ! find component with largest magnitude - if ( .not. EqualRealNos( sign(1.0_ReKi,v(indx_max)), sign(1.0_ReKi,logMap(indx_max)) )) logMap = -logMap + if ( .not. EqualRealNos( sign(1.0_SiKi,v(indx_max)), sign(1.0_SiKi,logMap(indx_max)) )) logMap = -logMap ELSE - TwoSinTheta = 2.0_ReKi*sin(theta) + TwoSinTheta = 2.0_SiKi*sin(theta) - IF ( EqualRealNos(0.0_ReKi, theta) .or. EqualRealNos( 0.0_ReKi, TwoSinTheta ) ) THEN + IF ( EqualRealNos(0.0_SiKi, theta) .or. EqualRealNos( 0.0_SiKi, TwoSinTheta ) ) THEN !skewSym = DCM - TRANSPOSE(DCM) ! @@ -1510,7 +1439,7 @@ SUBROUTINE DCM_logMapR(DCM, logMap, ErrStat, ErrMsg, thetaOut) !logMap = 0.5_ReKi * logMap ! Eq. 26b with limit as x approaches 0 of (x/sin(x)) = 1 - logMap = 0.0_ReKi ! Eq. 26a + logMap = 0.0_SiKi ! Eq. 26a ELSE ! 0 < theta < pi @@ -1618,11 +1547,11 @@ SUBROUTINE DCM_SetLogMapForInterpR( tensor ) ! tensor*( 1 + TwoPi*k/TwoNorm(tensor) ) for any integer k - REAL(ReKi), INTENT(INOUT) :: tensor(:,:) + REAL(SiKi), INTENT(INOUT) :: tensor(:,:) - REAL(ReKi) :: diff1, diff2 ! magnitude-squared of difference between two adjacent values - REAL(ReKi) :: temp(3), temp1(3) ! difference between two tensors - REAL(ReKi) :: period(3) ! the period to add to the rotational parameters + REAL(SiKi) :: diff1, diff2 ! magnitude-squared of difference between two adjacent values + REAL(SiKi) :: temp(3), temp1(3) ! difference between two tensors + REAL(SiKi) :: period(3) ! the period to add to the rotational parameters INTEGER(IntKi) :: nc ! size of the tensors matrix INTEGER(IntKi) :: ic ! loop counters for each array dimension @@ -1633,7 +1562,7 @@ SUBROUTINE DCM_SetLogMapForInterpR( tensor ) diff1 = TwoNorm( tensor(:,ic) ) - if ( .NOT. EqualRealNos( diff1, 0.0_ReKi) ) then + if ( .NOT. EqualRealNos( diff1, 0.0_SiKi) ) then ! check if we're going around a 2pi boundary: period = tensor(:,ic) * ( Twopi/diff1 ) @@ -1751,40 +1680,6 @@ FUNCTION EqualRealNos8 ( ReNum1, ReNum2 ) END FUNCTION EqualRealNos8 !======================================================================= -!> \copydoc nwtc_num::equalrealnos4 - FUNCTION EqualRealNos16 ( ReNum1, ReNum2 ) - - ! passed variables - - REAL(QuKi), INTENT(IN ) :: ReNum1 ! the first real number to compare - REAL(QuKi), INTENT(IN ) :: ReNum2 ! the second real number to compare - - LOGICAL :: EqualRealNos16 !< .true. if and only if the numbers are almost equal - - ! local variables - REAL(QuKi), PARAMETER :: Eps = EPSILON(ReNum1) ! machine precision - REAL(QuKi), PARAMETER :: Tol = 100.0_QuKi*Eps / 2.0_QuKi ! absolute tolerance (ignore the last 2 significant digits) - - REAL(QuKi) :: Fraction - - - ! make sure we're never trying to get more precision than Tol - - Fraction = MAX( ABS(ReNum1+ReNum2), 1.0_QuKi ) - - - - ! determine if ReNum1 and ReNum2 are approximately equal - - IF ( ABS(ReNum1 - ReNum2) <= Fraction*Tol ) THEN ! the relative error - EqualRealNos16 = .TRUE. - ELSE - EqualRealNos16 = .FALSE. - ENDIF - - - END FUNCTION EqualRealNos16 -!======================================================================= !> This function creates a rotation matrix, M, from a 1-2-3 rotation !! sequence of the 3 Euler angles, \f$\theta_x\f$, \f$\theta_y\f$, and \f$\theta_z\f$, in radians. !! M represents a change of basis (from global to local coordinates; @@ -1898,57 +1793,6 @@ FUNCTION EulerConstructR8(theta) result(M) END FUNCTION EulerConstructR8 !======================================================================= -!> \copydoc nwtc_num::eulerconstructr4 - FUNCTION EulerConstructR16(theta) result(M) - - ! this function creates a rotation matrix, M, from a 1-2-3 rotation - ! sequence of the 3 Euler angles, theta_x, theta_y, and theta_z, in radians. - ! M represents a change of basis (from global to local coordinates; - ! not a physical rotation of the body). it is the inverse of EulerExtract(). - ! - ! M = R(theta_z) * R(theta_y) * R(theta_x) - ! = [ cz sz 0 | [ cy 0 -sy | [ 1 0 0 | - ! |-sz cz 0 | * | 0 1 0 | * | 0 cx sx | - ! | 0 0 1 ] | sy 0 cy ] | 0 -sx cx ] - ! = [ cy*cz cx*sz+sx*sy*cz sx*sz-cx*sy*cz | - ! |-cy*sz cx*cz-sx*sy*sz sx*cz+cx*sy*sz | - ! | sy -sx*cy cx*cy ] - ! where cz = cos(theta_z), sz = sin(theta_z), cy = cos(theta_y), etc. - - REAL(QuKi) :: M(3,3) ! rotation matrix M - REAL(QuKi), INTENT(IN) :: theta(3) ! the 3 rotation angles: theta_x, theta_y, theta_z - - REAL(QuKi) :: cx ! cos(theta_x) - REAL(QuKi) :: sx ! sin(theta_x) - REAL(QuKi) :: cy ! cos(theta_y) - REAL(QuKi) :: sy ! sin(theta_y) - REAL(QuKi) :: cz ! cos(theta_z) - REAL(QuKi) :: sz ! sin(theta_z) - - - cx = cos( theta(1) ) - sx = sin( theta(1) ) - - cy = cos( theta(2) ) - sy = sin( theta(2) ) - - cz = cos( theta(3) ) - sz = sin( theta(3) ) - - M(1,1) = cy*cz - M(2,1) = -cy*sz - M(3,1) = sy - - M(1,2) = cx*sz+sx*sy*cz - M(2,2) = cx*cz-sx*sy*sz - M(3,2) = -sx*cy - - M(1,3) = sx*sz-cx*sy*cz - M(2,3) = sx*cz+cx*sy*sz - M(3,3) = cx*cy - - END FUNCTION EulerConstructR16 -!======================================================================= !> if M is a rotation matrix from a 1-2-3 rotation sequence, this function returns !! the 3 Euler angles, \f$\theta_x\f$, \f$\theta_y\f$, and \f$\theta_z\f$ (in radians), that formed !! the matrix. M represents a change of basis (from global to local coordinates; @@ -2150,102 +1994,49 @@ FUNCTION EulerExtractR8(M) result(theta) END FUNCTION EulerExtractR8 + !======================================================================= -!> \copydoc nwtc_num::eulerextractr4 - FUNCTION EulerExtractR16(M) result(theta) +!> + FUNCTION EulerConstructZYXR8(theta) result(M) - ! if M is a rotation matrix from a 1-2-3 rotation sequence, this function returns - ! the 3 Euler angles, theta_x, theta_y, and theta_z (in radians), that formed - ! the matrix. M represents a change of basis (from global to local coordinates; - ! not a physical rotation of the body). M is the inverse of EulerConstruct(). + ! this function creates a rotation matrix, M, from a 3-2-1 rotation + ! sequence of the 3 Euler angles, theta_z, theta_y, and theta_x, in radians. + ! M represents a change of basis (from global to local coordinates; + ! not a physical rotation of the body). ! - ! M = R(theta_z) * R(theta_y) * R(theta_x) - ! = [ cz sz 0 | [ cy 0 -sy | [ 1 0 0 | - ! |-sz cz 0 | * | 0 1 0 | * | 0 cx sx | - ! | 0 0 1 ] | sy 0 cy ] | 0 -sx cx ] - ! = [ cy*cz cx*sz+sx*sy*cz sx*sz-cx*sy*cz | - ! |-cy*sz cx*cz-sx*sy*sz sx*cz+cx*sy*sz | - ! | sy -sx*cy cx*cy ] - ! where cz = cos(theta_z), sz = sin(theta_z), cy = cos(theta_y), etc. - ! - ! returned angles are in the range [-pi, pi] - - REAL(QuKi), INTENT(IN) :: M(3,3) ! rotation matrix M - REAL(QuKi) :: theta(3) ! the 3 rotation angles: theta_x, theta_y, theta_z + REAL(R8Ki) :: M(3,3) ! rotation matrix M + REAL(R8Ki), INTENT(IN) :: theta(3) ! the 3 rotation angles: theta_x, theta_y, theta_z - REAL(QuKi) :: cx ! cos(theta_x) - REAL(QuKi) :: sx ! sin(theta_x) - REAL(QuKi) :: cy ! cos(theta_y) -! REAL(QuKi) :: sy ! sin(theta_y) - REAL(QuKi) :: cz ! cos(theta_z) - REAL(QuKi) :: sz ! sin(theta_z) + REAL(R8Ki) :: cx ! cos(theta_x) + REAL(R8Ki) :: sx ! sin(theta_x) + REAL(R8Ki) :: cy ! cos(theta_y) + REAL(R8Ki) :: sy ! sin(theta_y) + REAL(R8Ki) :: cz ! cos(theta_z) + REAL(R8Ki) :: sz ! sin(theta_z) - ! use trig identity sz**2 + cz**2 = 1 to get abs(cy): - cy = sqrt( m(1,1)**2 + m(2,1)**2 ) -! cy = sqrt( m(3,3)**2 + m(3,2)**2 ) - - if ( EqualRealNos(cy,0.0_QuKi) ) then - !if ( cy < 16*epsilon(0.0_ReKi) ) then - - theta(2) = atan2( m(3,1), cy ) ! theta_y - - ! cy = 0 -> sy = +/- 1 - ! M = [ 0 cx*sz+/-sx*cz sx*sz-/+cx*cz | - ! | 0 cx*cz-/+sx*sz sx*cz+/-cx*sz | - ! |+/-1 0 0 ] - - ! gimbal lock allows us to choose theta_z = 0 - theta(3) = 0.0_QuKi ! theta_z - - ! which reduces the matrix to - ! M = [ 0 +/-sx -/+cx | - ! | 0 cx sx | - ! |+/-1 0 0 ] - - theta(1) = atan2( m(2,3), m(2,2) ) ! theta_x - - else - ! atan2( cy*sz, cy*cz ) - theta(3) = atan2( -m(2,1), m(1,1) ) ! theta_z - cz = cos( theta(3) ) - sz = sin( theta(3) ) - - ! get the appropriate sign for cy: - if ( EqualRealNos(cz, 0.0_QuKi) ) then - cy = sign( cy, -m(2,1)/sz ) - !cy = -m(2,1)/sz - else - cy = sign( cy, m(1,1)/cz ) - !cy = -m(1,1)/cz - end if - theta(2) = atan2( m(3,1), cy ) ! theta_y - - !theta(1) = atan2( -m(3,2), m(3,3) ) ! theta_x - - ! for numerical reasons, we're going to get theta_x using - ! M' = (R(theta_z) * R(theta_y))^T * M = R(theta_x) - ! = [ cy 0 sy | [ cz -sz 0 | [ 1 0 0 | - ! | 0 1 0 | * | sz cz 0 | * M = | 0 cx sx | - ! |-sy 0 cy ] | 0 0 1 ] | 0 -sx cx ] - ! = [ cy*cz -cy*sz sy | [ 1 0 0 | - ! | sz cz 0 | * M = | 0 cx sx | - ! |-sy*cz sy*sz cy ] | 0 -sx cx ] - ! taking M'(2,2) and M'(2,3) , we get cx and sx: - ! sz*m(1,2) + cz*m(2,2) = cx - ! sz*m(1,3) + cz*m(2,3) = sx - cz = cos( theta(3) ) - sz = sin( theta(3) ) - - cx = sz*m(1,2) + cz*m(2,2) - sx = sz*m(1,3) + cz*m(2,3) - - theta(1) = atan2( sx, cx ) + cx = cos( theta(1) ) + sx = sin( theta(1) ) + + cy = cos( theta(2) ) + sy = sin( theta(2) ) + + cz = cos( theta(3) ) + sz = sin( theta(3) ) - end if - + M(1,1) = cy*cz + M(2,1) = sx*sy*cz - sz*cx + M(3,1) = sx*sz + sy*cx*cz + + M(1,2) = sz*cy + M(2,2) = sx*sy*sz + cx*cz + M(3,2) = -sx*cz + sy*sz*cx - END FUNCTION EulerExtractR16 + M(1,3) = -sy + M(2,3) = sx*cy + M(3,3) = cx*cy + + END FUNCTION EulerConstructZYXR8 !======================================================================= !> This routine sets the matrices in the first two dimensions of A equal !! to the identity matrix (all zeros, with ones on the diagonal). @@ -2256,7 +2047,7 @@ END FUNCTION EulerExtractR16 SUBROUTINE Eye2( A, ErrStat, ErrMsg ) - REAL(ReKi), INTENT(INOUT) :: A (:,:) !< Array to set to the identity matrix (nr,nc,n) + REAL(SiKi), INTENT(INOUT) :: A (:,:) !< Array to set to the identity matrix (nr,nc,n) INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error level CHARACTER(*), INTENT(OUT) :: ErrMsg !< ErrMsg corresponding to ErrStat @@ -2278,11 +2069,11 @@ SUBROUTINE Eye2( A, ErrStat, ErrMsg ) END IF ! initialize to zero: - A = 0._ReKi + A = 0.0_SiKi ! set the diagonals to one: DO j = 1, MIN(nr,nc) ! the diagonal of the matrix - A(j,j) = 1._ReKi + A(j,j) = 1.0_SiKi END DO END SUBROUTINE Eye2 @@ -2329,7 +2120,7 @@ SUBROUTINE Eye3( A, ErrStat, ErrMsg ) ! Note that this also returns the "pseudo-identity" when A(:,:) ! is not square (i.e., nr/=nc). - REAL(ReKi), INTENT(INOUT) :: A (:,:,:) ! Array to set to the identity matrix (nr,nc,n) + REAL(SiKi), INTENT(INOUT) :: A (:,:,:) ! Array to set to the identity matrix (nr,nc,n) INTEGER(IntKi), INTENT(OUT) :: ErrStat ! Error level CHARACTER(*), INTENT(OUT) :: ErrMsg ! ErrMsg corresponding to ErrStat @@ -2353,12 +2144,12 @@ SUBROUTINE Eye3( A, ErrStat, ErrMsg ) END IF ! initialize to zero: - A = 0._ReKi + A = 0.0_SiKi ! set the diagonals to one: DO i = 1, n ! loop through the matrices DO j = 1, MIN(nr,nc) ! the diagonal of the matrix - A(j,j,i) = 1._ReKi + A(j,j,i) = 1.0_SiKi END DO END DO @@ -2406,6 +2197,51 @@ SUBROUTINE Eye3D( A, ErrStat, ErrMsg ) END DO END SUBROUTINE Eye3D +!==================================================================================================== +INTEGER FUNCTION FindValidChannelIndx(OutListVal, ValidParamAry, SignM_out) RESULT( Indx ) + + CHARACTER(*), INTENT(IN) :: OutListVal + CHARACTER(OutStrLenM1), INTENT(IN) :: ValidParamAry(:) + INTEGER, OPTIONAL, INTENT(OUT) :: SignM_out + + CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I) + INTEGER :: SignM + LOGICAL :: CheckOutListAgain ! Flag used to determine if output parameter starting with "M" is valid (or the negative of another parameter) + + OutListTmp = OutListVal + + ! 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 + 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. + SignM = 1 + ELSE + SignM = 1 + END IF + + CALL Conv2UC( OutListTmp ) ! Convert OutListTmp to upper case + + + Indx = IndexCharAry( OutListTmp(1:OutStrLenM1), ValidParamAry ) + + + ! If it started with an "M" (CheckOutListAgain) we didn't find the value in our list (Indx < 1) + + IF ( CheckOutListAgain .AND. Indx < 1 ) THEN ! Let's assume that "M" really meant "minus" and then test again + SignM = -1 ! ex, "MTipDxc1" causes the sign of TipDxc1 to be switched. + OutListTmp = OutListTmp(2:) + + Indx = IndexCharAry( OutListTmp(1:OutStrLenM1), ValidParamAry ) + END IF + + IF (PRESENT(SignM_out)) SignM_out = SignM + +END FUNCTION FindValidChannelIndx !======================================================================= !> This routine uses the Gauss-Jordan elimination method for the !! solution of a given set of simultaneous linear equations. @@ -2665,21 +2501,21 @@ FUNCTION GetSmllRotAngsR ( DCMat, ErrStat, ErrMsg ) ! passed variables - REAL(ReKi), INTENT(IN ) :: DCMat (3,3) + REAL(SiKi), INTENT(IN ) :: DCMat (3,3) INTEGER, INTENT(OUT ) :: ErrStat ! a non-zero value indicates an error in the permutation matrix algorithm CHARACTER(*),INTENT(OUT ),OPTIONAL :: ErrMsg ! a non-zero value indicates an error in the permutation matrix algorithm - REAL(ReKi) :: GetSmllRotAngsR ( 3 ) + REAL(SiKi) :: GetSmllRotAngsR ( 3 ) ! local variables - REAL(ReKi) :: denom ! the denominator of the resulting matrix - REAL(ReKi), PARAMETER :: LrgAngle = 0.4_ReKi ! Threshold for when a small angle becomes large (about 23deg). This comes from: COS(SmllAngle) ~ 1/SQRT( 1 + SmllAngle^2 ) and SIN(SmllAngle) ~ SmllAngle/SQRT( 1 + SmllAngle^2 ) results in ~5% error when SmllAngle = 0.4rad. + REAL(SiKi) :: denom ! the denominator of the resulting matrix + REAL(SiKi), PARAMETER :: LrgAngle = 0.4_SiKi ! Threshold for when a small angle becomes large (about 23deg). This comes from: COS(SmllAngle) ~ 1/SQRT( 1 + SmllAngle^2 ) and SIN(SmllAngle) ~ SmllAngle/SQRT( 1 + SmllAngle^2 ) results in ~5% error when SmllAngle = 0.4rad. ! initialize output angles (just in case there is an error that prevents them from getting set) - GetSmllRotAngsR = 0.0_ReKi + GetSmllRotAngsR = 0.0_SiKi ErrStat = ErrID_None ErrMsg = "" @@ -2688,9 +2524,9 @@ FUNCTION GetSmllRotAngsR ( DCMat, ErrStat, ErrMsg ) GetSmllRotAngsR(2) = DCMat(3,1) - DCMat(1,3) GetSmllRotAngsR(3) = DCMat(1,2) - DCMat(2,1) - denom = DCMat(1,1) + DCMat(2,2) + DCMat(3,3) - 1.0_ReKi + denom = DCMat(1,1) + DCMat(2,2) + DCMat(3,3) - 1.0_SiKi - IF ( .NOT. EqualRealNos( denom, 0.0_ReKi ) ) THEN + IF ( .NOT. EqualRealNos( denom, 0.0_SiKi ) ) THEN GetSmllRotAngsR = GetSmllRotAngsR / denom ! check that the angles are, in fact, small @@ -3163,36 +2999,36 @@ FUNCTION InterpStpComp8( XVal, XAry, YAry, Ind, AryLen ) RETURN END FUNCTION InterpStpComp8 + !======================================================================= !> \copydoc nwtc_num::interpstpcomp4 - FUNCTION InterpStpComp16( XVal, XAry, YAry, Ind, AryLen ) + FUNCTION InterpStpReal4( XVal, XAry, YAry, Ind, AryLen ) ! Function declaration. - COMPLEX(QuKi) :: InterpStpComp16 !< The interpolated value of Y at XVal + REAL(SiKi) :: InterpStpReal4 !< The interpolated value of Y at XVal ! Argument declarations. - INTEGER, INTENT(IN) :: AryLen !< Length of the arrays. - INTEGER, INTENT(INOUT) :: Ind !< Initial and final index into the arrays. - - REAL(QuKi), INTENT(IN) :: XAry (AryLen) !< Array of X values to be interpolated. - REAL(QuKi), INTENT(IN) :: XVal !< X value to be interpolated. + INTEGER, INTENT(IN) :: AryLen ! Length of the arrays. + INTEGER, INTENT(INOUT) :: Ind ! Initial and final index into the arrays. - COMPLEX(QuKi), INTENT(IN) :: YAry (AryLen) !< Array of Y values to be interpolated. + REAL(SiKi), INTENT(IN) :: XAry (AryLen) ! Array of X values to be interpolated. + REAL(SiKi), INTENT(IN) :: XVal ! X value to be interpolated. + REAL(SiKi), INTENT(IN) :: YAry (AryLen) ! Array of Y values to be interpolated. ! Let's check the limits first. IF ( XVal <= XAry(1) ) THEN - InterpStpComp16 = YAry(1) - Ind = 1 + InterpStpReal4 = YAry(1) + Ind = 1 RETURN ELSE IF ( XVal >= XAry(AryLen) ) THEN - InterpStpComp16 = YAry(AryLen) - Ind = MAX(AryLen - 1, 1) + InterpStpReal4 = YAry(AryLen) + Ind = MAX(AryLen - 1, 1) RETURN END IF @@ -3213,7 +3049,7 @@ FUNCTION InterpStpComp16( XVal, XAry, YAry, Ind, AryLen ) ELSE - InterpStpComp16 = ( YAry(Ind+1) - YAry(Ind) )*( XVal - XAry(Ind) )/( XAry(Ind+1) - XAry(Ind) ) + YAry(Ind) + InterpStpReal4 = ( YAry(Ind+1) - YAry(Ind) )*( XVal - XAry(Ind) )/( XAry(Ind+1) - XAry(Ind) ) + YAry(Ind) RETURN END IF @@ -3222,14 +3058,14 @@ FUNCTION InterpStpComp16( XVal, XAry, YAry, Ind, AryLen ) RETURN - END FUNCTION InterpStpComp16 + END FUNCTION InterpStpReal4 !======================================================================= !> \copydoc nwtc_num::interpstpcomp4 - FUNCTION InterpStpReal4( XVal, XAry, YAry, Ind, AryLen ) + FUNCTION InterpStpReal4_8( XVal, XAry, YAry, Ind, AryLen ) ! Function declaration. - REAL(SiKi) :: InterpStpReal4 !< The interpolated value of Y at XVal + REAL(R8Ki) :: InterpStpReal4_8 !< The interpolated value of Y at XVal ! Argument declarations. @@ -3239,18 +3075,18 @@ FUNCTION InterpStpReal4( XVal, XAry, YAry, Ind, AryLen ) REAL(SiKi), INTENT(IN) :: XAry (AryLen) ! Array of X values to be interpolated. REAL(SiKi), INTENT(IN) :: XVal ! X value to be interpolated. - REAL(SiKi), INTENT(IN) :: YAry (AryLen) ! Array of Y values to be interpolated. + REAL(R8Ki), INTENT(IN) :: YAry (AryLen) ! Array of Y values to be interpolated. ! Let's check the limits first. IF ( XVal <= XAry(1) ) THEN - InterpStpReal4 = YAry(1) + InterpStpReal4_8 = YAry(1) Ind = 1 RETURN ELSE IF ( XVal >= XAry(AryLen) ) THEN - InterpStpReal4 = YAry(AryLen) + InterpStpReal4_8 = YAry(AryLen) Ind = MAX(AryLen - 1, 1) RETURN END IF @@ -3272,7 +3108,7 @@ FUNCTION InterpStpReal4( XVal, XAry, YAry, Ind, AryLen ) ELSE - InterpStpReal4 = ( YAry(Ind+1) - YAry(Ind) )*( XVal - XAry(Ind) )/( XAry(Ind+1) - XAry(Ind) ) + YAry(Ind) + InterpStpReal4_8 = ( YAry(Ind+1) - YAry(Ind) )*( XVal - XAry(Ind) )/( XAry(Ind+1) - XAry(Ind) ) + YAry(Ind) RETURN END IF @@ -3281,73 +3117,14 @@ FUNCTION InterpStpReal4( XVal, XAry, YAry, Ind, AryLen ) RETURN - END FUNCTION InterpStpReal4 + END FUNCTION InterpStpReal4_8 !======================================================================= !> \copydoc nwtc_num::interpstpcomp4 - FUNCTION InterpStpReal4_8( XVal, XAry, YAry, Ind, AryLen ) + FUNCTION InterpStpReal8( XVal, XAry, YAry, Ind, AryLen ) ! Function declaration. - REAL(R8Ki) :: InterpStpReal4_8 !< The interpolated value of Y at XVal - - - ! Argument declarations. - - INTEGER, INTENT(IN) :: AryLen ! Length of the arrays. - INTEGER, INTENT(INOUT) :: Ind ! Initial and final index into the arrays. - - REAL(SiKi), INTENT(IN) :: XAry (AryLen) ! Array of X values to be interpolated. - REAL(SiKi), INTENT(IN) :: XVal ! X value to be interpolated. - REAL(R8Ki), INTENT(IN) :: YAry (AryLen) ! Array of Y values to be interpolated. - - - - ! Let's check the limits first. - - IF ( XVal <= XAry(1) ) THEN - InterpStpReal4_8 = YAry(1) - Ind = 1 - RETURN - ELSE IF ( XVal >= XAry(AryLen) ) THEN - InterpStpReal4_8 = YAry(AryLen) - Ind = MAX(AryLen - 1, 1) - RETURN - END IF - - - ! Let's interpolate! - - Ind = MAX( MIN( Ind, AryLen-1 ), 1 ) - - DO - - IF ( XVal < XAry(Ind) ) THEN - - Ind = Ind - 1 - - ELSE IF ( XVal >= XAry(Ind+1) ) THEN - - Ind = Ind + 1 - - ELSE - - InterpStpReal4_8 = ( YAry(Ind+1) - YAry(Ind) )*( XVal - XAry(Ind) )/( XAry(Ind+1) - XAry(Ind) ) + YAry(Ind) - RETURN - - END IF - - END DO - - - RETURN - END FUNCTION InterpStpReal4_8 -!======================================================================= -!> \copydoc nwtc_num::interpstpcomp4 - FUNCTION InterpStpReal8( XVal, XAry, YAry, Ind, AryLen ) - - ! Function declaration. - - REAL(R8Ki) :: InterpStpReal8 !< The interpolated value of Y at XVal + REAL(R8Ki) :: InterpStpReal8 !< The interpolated value of Y at XVal ! Argument declarations. @@ -3400,64 +3177,7 @@ FUNCTION InterpStpReal8( XVal, XAry, YAry, Ind, AryLen ) RETURN END FUNCTION InterpStpReal8 -!======================================================================= -!> \copydoc nwtc_num::interpstpcomp4 - FUNCTION InterpStpReal16( XVal, XAry, YAry, Ind, AryLen ) - - ! Function declaration. - - REAL(QuKi) :: InterpStpReal16 !< The interpolated value of Y at XVal - - ! Argument declarations. - - INTEGER, INTENT(IN) :: AryLen ! Length of the arrays. - INTEGER, INTENT(INOUT) :: Ind ! Initial and final index into the arrays. - - REAL(QuKi), INTENT(IN) :: XAry (AryLen) ! Array of X values to be interpolated. - REAL(QuKi), INTENT(IN) :: XVal ! X value to be interpolated. - REAL(QuKi), INTENT(IN) :: YAry (AryLen) ! Array of Y values to be interpolated. - - - - ! Let's check the limits first. - - IF ( XVal <= XAry(1) ) THEN - InterpStpReal16 = YAry(1) - Ind = 1 - RETURN - ELSE IF ( XVal >= XAry(AryLen) ) THEN - InterpStpReal16 = YAry(AryLen) - Ind = MAX(AryLen - 1, 1) - RETURN - END IF - - - ! Let's interpolate! - - Ind = MAX( MIN( Ind, AryLen-1 ), 1 ) - - DO - - IF ( XVal < XAry(Ind) ) THEN - - Ind = Ind - 1 - - ELSE IF ( XVal >= XAry(Ind+1) ) THEN - - Ind = Ind + 1 - - ELSE - - InterpStpReal16 = ( YAry(Ind+1) - YAry(Ind) )*( XVal - XAry(Ind) )/( XAry(Ind+1) - XAry(Ind) ) + YAry(Ind) - RETURN - END IF - - END DO - - - RETURN - END FUNCTION InterpStpReal16 !======================================================================= !> This funtion returns a y-value array that corresponds to an input x-value by interpolating into the arrays. !! It uses the passed index as the starting point and does a stepwise interpolation from there. This is @@ -3833,40 +3553,6 @@ FUNCTION InterpWrappedStpReal8( XValIn, XAry, YAry, Ind, AryLen ) END FUNCTION InterpWrappedStpReal8 !======================================================================= -!> \copydoc nwtc_num::interpwrappedstpreal4 - FUNCTION InterpWrappedStpReal16( XValIn, XAry, YAry, Ind, AryLen ) - - ! Function declaration. - - REAL(QuKi) :: InterpWrappedStpReal16 !< The interpolated value of Y at XVal - - - ! Argument declarations. - - INTEGER, INTENT(IN) :: AryLen !< Length of the arrays. - INTEGER, INTENT(INOUT) :: Ind ! Initial and final index into the arrays. - - REAL(QuKi), INTENT(IN) :: XAry (AryLen) ! Array of X values to be interpolated. - REAL(QuKi), INTENT(IN) :: XValIn ! X value to be interpolated. - REAL(QuKi), INTENT(IN) :: YAry (AryLen) ! Array of Y values to be interpolated. - - REAL(QuKi) :: XVal ! X value to be interpolated. - - - - ! Wrap XValIn into the range XAry(1) to XAry(AryLen) - XVal = MOD(XValIn, XAry(AryLen)) - - ! Set the Ind to the first index if we are at the beginning of XAry - IF ( XVal <= XAry(2) ) THEN - Ind = 1 - END IF - - InterpWrappedStpReal16 = InterpStp( XVal, XAry, YAry, Ind, AryLen ) - - - END FUNCTION InterpWrappedStpReal16 -!======================================================================= !> This subroutine calculates interpolated values for an array of input values. !! The size of the xknown and yknown arrays must match, and the size of the !! xnew and ynew arrays must match. Xknown must be in ascending order. @@ -3952,47 +3638,6 @@ function interp_lin0(x,x0,x1,f0,f1) ! Linear interpolation function end function interp_lin0 END SUBROUTINE InterpArrayR8 !======================================================================= -!> \copydoc nwtc_num::interparrayr4 - SUBROUTINE InterpArrayR16( xknown, yknown, xnew, ynew ) - REAL(QuKi), INTENT(IN ) :: xknown(:) - REAL(QuKi), INTENT(IN ) :: yknown(:) - REAL(QuKi), INTENT(IN ) :: xnew(:) - REAL(QuKi), INTENT( OUT) :: ynew(:) - integer(IntKi) i,itmp,nknown - nknown=size(xknown) - do i=1,size(xnew) - itmp=minloc(abs(xnew(i)-xknown),dim=1) - if (itmp==nknown) then - if (xknown(itmp)>xnew(i)) then - ynew(i)=interp_lin0(xnew(i),xknown(itmp-1),xknown(itmp),yknown(itmp-1),yknown(itmp)) - else - ! The current x is above the max of xknown - ! extrapolation required, here fixed to upper bound - ynew(i)=yknown(nknown) - endif - elseif (xknown(itmp) This subroutine calculates the iosparametric coordinates, isopc, which is a value between -1 and 1 !! (for each dimension of a dataset), indicating where InCoord falls between posLo and posHi. !! It is used in InterpStpReal2D (nwtcnum::interpstpreal2d) and InterpStpReal3D (nwtcnum::interpstpreal3d). @@ -4328,54 +3973,6 @@ SUBROUTINE LocateStpR8( XVal, XAry, Ind, AryLen ) END SUBROUTINE LocateStpR8 !======================================================================= -!> \copydoc nwtc_num::locatestpr4 - SUBROUTINE LocateStpR16( XVal, XAry, Ind, AryLen ) - - ! Argument declarations. - - INTEGER, INTENT(IN) :: AryLen ! Length of the array. - INTEGER, INTENT(INOUT) :: Ind ! Initial and final index into the array. - - REAL(QuKi), INTENT(IN) :: XAry (AryLen) ! Array of X values to be interpolated. - REAL(QuKi), INTENT(IN) :: XVal ! X value to be interpolated. - - - - ! Let's check the limits first. - - IF ( XVal < XAry(1) ) THEN - Ind = 0 - ELSE IF ( XVal >= XAry(AryLen) ) THEN - Ind = AryLen - ELSE - - Ind = MAX( MIN( Ind, AryLen-1 ), 1 ) - - DO - - IF ( XVal < XAry(Ind) ) THEN - - Ind = Ind - 1 - - ELSE IF ( XVal >= XAry(Ind+1) ) THEN - - Ind = Ind + 1 - - ELSE - - RETURN - - END IF - - END DO - - - END IF - - RETURN - - END SUBROUTINE LocateStpR16 -!======================================================================= !> This routine calculates the mean value of an array. FUNCTION Mean ( Ary, AryLen ) @@ -4464,30 +4061,6 @@ SUBROUTINE MPi2Pi_R8 ( Angle ) RETURN END SUBROUTINE MPi2Pi_R8 !======================================================================= -!> \copydoc nwtc_num::mpi2pi_r4 - SUBROUTINE MPi2Pi_R16 ( Angle ) - - - ! Argument declarations: - - REAL(QuKi), INTENT(INOUT) :: Angle - - - ! Get the angle between 0 and 2Pi. - - Angle = MODULO( Angle, TwoPi_R16 ) - - - ! Get the angle between -Pi and Pi. - - IF ( Angle > Pi_R16 ) THEN - Angle = Angle - TwoPi_R16 - END IF - - - RETURN - END SUBROUTINE MPi2Pi_R16 -!======================================================================= !> This function takes an angle in radians and converts it to !! an angle in degrees in the range [-180,180] real(reKi) function Rad2M180to180Deg(Angle) result(Alpha) @@ -4557,27 +4130,6 @@ FUNCTION OuterProductR8(u,v) END FUNCTION OuterProductR8 !======================================================================= -!> \copydoc nwtc_num::outerproductr4 - FUNCTION OuterProductR16(u,v) - - ! this routine calculates the outer product of two vectors - - REAL(QuKi),INTENT(IN):: u(:),v(:) - REAL(QuKi)::OuterProductR16(SIZE(u),SIZE(v)) - - INTEGER(IntKi)::i,j,n1,n2 - - n1=SIZE(u) - n2=SIZE(v) - - DO i=1,n1 - DO j=1,n2 - OuterProductR16(i,j) = u(i) * v(j) - ENDDO - ENDDO - - END FUNCTION OuterProductR16 -!======================================================================= !> This subroutine perturbs an orientation matrix by a small angle. Two methods !! are used: !! small angle DCM: perturb small angles extracted from DCM @@ -5632,11 +5184,9 @@ SUBROUTINE SetConstants( ) 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 ) TwoPi_R4 = Pi_R4 *2.0_SiKi TwoPi_R8 = Pi_R8 *2.0_R8Ki - TwoPi_R16 = Pi_R16*2.0_QuKi ! IEEE constants: CALL Set_IEEE_Constants( NaN_D, Inf_D, NaN, Inf, NaN_S, Inf_S ) @@ -5829,10 +5379,10 @@ SUBROUTINE SmllRotTransD( RotationType, Theta1, Theta2, Theta3, TransMat, ErrTxt ! Passed Variables: - REAL(ReKi), INTENT(IN ) :: Theta1 !< \f$\theta_1\f$: the small rotation about \f$X_1\f$, (rad). - REAL(ReKi), INTENT(IN ) :: Theta2 !< \f$\theta_2\f$: the small rotation about \f$X_2\f$, (rad). - REAL(ReKi), INTENT(IN ) :: Theta3 !< \f$\theta_3\f$: the small rotation about \f$X_3\f$, (rad). - REAL(DbKi), INTENT(OUT) :: TransMat (3,3) !< The resulting transformation matrix from \f$X\f$ to \f$x\f$, (-). + REAL(R8Ki), INTENT(IN ) :: Theta1 !< \f$\theta_1\f$: the small rotation about \f$X_1\f$, (rad). + REAL(R8Ki), INTENT(IN ) :: Theta2 !< \f$\theta_2\f$: the small rotation about \f$X_2\f$, (rad). + REAL(R8Ki), INTENT(IN ) :: Theta3 !< \f$\theta_3\f$: the small rotation about \f$X_3\f$, (rad). + REAL(R8Ki), INTENT(OUT) :: TransMat (3,3) !< The resulting transformation matrix from \f$X\f$ to \f$x\f$, (-). INTEGER(IntKi),INTENT(OUT) :: ErrStat !< Error status CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message corresponding to ErrStat @@ -5920,102 +5470,7 @@ SUBROUTINE SmllRotTransD( RotationType, Theta1, Theta2, Theta3, TransMat, ErrTxt END SUBROUTINE SmllRotTransD !======================================================================= !> \copydoc nwtc_num::smllrottransd - SUBROUTINE SmllRotTransDD( RotationType, Theta1, Theta2, Theta3, TransMat, ErrTxt, ErrStat, ErrMsg ) - - ! Passed Variables: - - REAL(DbKi), INTENT(IN ) :: Theta1 !< The small rotation about X1, (rad). - REAL(DbKi), INTENT(IN ) :: Theta2 !< The small rotation about X2, (rad). - REAL(DbKi), INTENT(IN ) :: Theta3 !< The small rotation about X3, (rad). - REAL(DbKi), INTENT(OUT) :: TransMat (3,3) !< The resulting transformation matrix from X to x, (-). - - INTEGER(IntKi),INTENT(OUT) :: ErrStat !< Error status - CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message corresponding to ErrStat - - CHARACTER(*), INTENT(IN) :: RotationType !< The type of rotation; used to inform the user where a large rotation is occuring upon such an event. - CHARACTER(*), INTENT(IN ), OPTIONAL :: ErrTxt !< an additional message to be displayed as a warning (typically the simulation time) - - ! Local Variables: - - REAL(DbKi) :: ComDenom ! = ( Theta1^2 + Theta2^2 + Theta3^2 )*SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) - REAL(DbKi), PARAMETER :: LrgAngle = 0.4 ! Threshold for when a small angle becomes large (about 23deg). This comes from: COS(SmllAngle) ~ 1/SQRT( 1 + SmllAngle^2 ) and SIN(SmllAngle) ~ SmllAngle/SQRT( 1 + SmllAngle^2 ) results in ~5% error when SmllAngle = 0.4rad. - REAL(DbKi) :: Theta11 ! = Theta1^2 - REAL(DbKi) :: Theta12S ! = Theta1*Theta2*[ SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) - 1.0 ] - REAL(DbKi) :: Theta13S ! = Theta1*Theta3*[ SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) - 1.0 ] - REAL(DbKi) :: Theta22 ! = Theta2^2 - REAL(DbKi) :: Theta23S ! = Theta2*Theta3*[ SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) - 1.0 ] - REAL(DbKi) :: Theta33 ! = Theta3^2 - REAL(DbKi) :: SqrdSum ! = Theta1^2 + Theta2^2 + Theta3^2 - REAL(DbKi) :: SQRT1SqrdSum ! = SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) - - LOGICAL, SAVE :: FrstWarn = .TRUE. ! When .TRUE., indicates that we're on the first warning. - - - ErrStat = ErrID_None - ErrMsg = '' - - ! Display a warning message if at least one angle gets too large in magnitude: - - IF ( ( ( ABS(Theta1) > LrgAngle ) .OR. ( ABS(Theta2) > LrgAngle ) .OR. ( ABS(Theta3) > LrgAngle ) ) .AND. FrstWarn ) THEN - - ErrStat= ErrID_Severe - ErrMsg = 'Small angle assumption violated in SUBROUTINE SmllRotTrans() due to a large '//TRIM(RotationType)//'. '// & - 'The solution may be inaccurate. Simulation continuing, but future warnings from SmllRotTrans() will be suppressed.' - - IF ( PRESENT(ErrTxt) ) THEN - ErrMsg = TRIM(ErrMsg)//NewLine//' Additional debugging message from SUBROUTINE SmllRotTrans(): '//TRIM(ErrTxt) - END IF - - !CALL ProgWarn( TRIM(ErrMsg) ) - - FrstWarn = .FALSE. ! Don't enter here again! - - ENDIF - - - ! Compute some intermediate results: - - Theta11 = Theta1*Theta1 - Theta22 = Theta2*Theta2 - Theta33 = Theta3*Theta3 - - SqrdSum = Theta11 + Theta22 + Theta33 - SQRT1SqrdSum = SQRT( 1.0_DbKi + SqrdSum ) - ComDenom = SqrdSum*SQRT1SqrdSum - - Theta12S = Theta1*Theta2*( SQRT1SqrdSum - 1.0_DbKi ) - Theta13S = Theta1*Theta3*( SQRT1SqrdSum - 1.0_DbKi ) - Theta23S = Theta2*Theta3*( SQRT1SqrdSum - 1.0_DbKi ) - - - ! Define the transformation matrix: - - IF ( ComDenom == 0.0_DbKi ) THEN ! All angles are zero and matrix is ill-conditioned (the matrix is derived assuming that the angles are not zero); return identity - - TransMat(1,:) = (/ 1.0_DbKi, 0.0_DbKi, 0.0_DbKi /) - TransMat(2,:) = (/ 0.0_DbKi, 1.0_DbKi, 0.0_DbKi /) - TransMat(3,:) = (/ 0.0_DbKi, 0.0_DbKi, 1.0_DbKi /) - - ELSE ! At least one angle is nonzero - - TransMat(1,1) = ( Theta11*SQRT1SqrdSum + Theta22 + Theta33 )/ComDenom - TransMat(2,2) = ( Theta11 + Theta22*SQRT1SqrdSum + Theta33 )/ComDenom - TransMat(3,3) = ( Theta11 + Theta22 + Theta33*SQRT1SqrdSum )/ComDenom - TransMat(1,2) = ( Theta3*SqrdSum + Theta12S )/ComDenom - TransMat(2,1) = ( -Theta3*SqrdSum + Theta12S )/ComDenom - TransMat(1,3) = ( -Theta2*SqrdSum + Theta13S )/ComDenom - TransMat(3,1) = ( Theta2*SqrdSum + Theta13S )/ComDenom - TransMat(2,3) = ( Theta1*SqrdSum + Theta23S )/ComDenom - TransMat(3,2) = ( -Theta1*SqrdSum + Theta23S )/ComDenom - - ENDIF - - - RETURN - END SUBROUTINE SmllRotTransDD -!======================================================================= -!> \copydoc nwtc_num::smllrottransd - SUBROUTINE SmllRotTransR( RotationType, Theta1, Theta2, Theta3, TransMat, ErrTxt, ErrStat, ErrMsg ) + SUBROUTINE SmllRotTransR( RotationType, Theta1, Theta2, Theta3, TransMat, ErrTxt, ErrStat, ErrMsg ) ! This routine computes the 3x3 transformation matrix, TransMat, @@ -6056,10 +5511,10 @@ SUBROUTINE SmllRotTransR( RotationType, Theta1, Theta2, Theta3, TransMat, ErrTxt ! Passed Variables: - REAL(ReKi), INTENT(IN ) :: Theta1 ! The small rotation about X1, (rad). - REAL(ReKi), INTENT(IN ) :: Theta2 ! The small rotation about X2, (rad). - REAL(ReKi), INTENT(IN ) :: Theta3 ! The small rotation about X3, (rad). - REAL(ReKi), INTENT(OUT) :: TransMat (3,3) ! The resulting transformation matrix from X to x, (-). + REAL(SiKi), INTENT(IN ) :: Theta1 ! The small rotation about X1, (rad). + REAL(SiKi), INTENT(IN ) :: Theta2 ! The small rotation about X2, (rad). + REAL(SiKi), INTENT(IN ) :: Theta3 ! The small rotation about X3, (rad). + REAL(SiKi), INTENT(OUT) :: TransMat (3,3) ! The resulting transformation matrix from X to x, (-). INTEGER(IntKi),INTENT(OUT) :: ErrStat CHARACTER(*), INTENT(OUT) :: ErrMsg @@ -6069,16 +5524,16 @@ SUBROUTINE SmllRotTransR( RotationType, Theta1, Theta2, Theta3, TransMat, ErrTxt ! Local Variables: - REAL(ReKi) :: ComDenom ! = ( Theta1^2 + Theta2^2 + Theta3^2 )*SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) - REAL(ReKi), PARAMETER :: LrgAngle = 0.4 ! Threshold for when a small angle becomes large (about 23deg). This comes from: COS(SmllAngle) ~ 1/SQRT( 1 + SmllAngle^2 ) and SIN(SmllAngle) ~ SmllAngle/SQRT( 1 + SmllAngle^2 ) results in ~5% error when SmllAngle = 0.4rad. - REAL(ReKi) :: Theta11 ! = Theta1^2 - REAL(ReKi) :: Theta12S ! = Theta1*Theta2*[ SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) - 1.0 ] - REAL(ReKi) :: Theta13S ! = Theta1*Theta3*[ SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) - 1.0 ] - REAL(ReKi) :: Theta22 ! = Theta2^2 - REAL(ReKi) :: Theta23S ! = Theta2*Theta3*[ SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) - 1.0 ] - REAL(ReKi) :: Theta33 ! = Theta3^2 - REAL(ReKi) :: SqrdSum ! = Theta1^2 + Theta2^2 + Theta3^2 - REAL(ReKi) :: SQRT1SqrdSum ! = SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) + REAL(SiKi) :: ComDenom ! = ( Theta1^2 + Theta2^2 + Theta3^2 )*SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) + REAL(SiKi), PARAMETER :: LrgAngle = 0.4 ! Threshold for when a small angle becomes large (about 23deg). This comes from: COS(SmllAngle) ~ 1/SQRT( 1 + SmllAngle^2 ) and SIN(SmllAngle) ~ SmllAngle/SQRT( 1 + SmllAngle^2 ) results in ~5% error when SmllAngle = 0.4rad. + REAL(SiKi) :: Theta11 ! = Theta1^2 + REAL(SiKi) :: Theta12S ! = Theta1*Theta2*[ SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) - 1.0 ] + REAL(SiKi) :: Theta13S ! = Theta1*Theta3*[ SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) - 1.0 ] + REAL(SiKi) :: Theta22 ! = Theta2^2 + REAL(SiKi) :: Theta23S ! = Theta2*Theta3*[ SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) - 1.0 ] + REAL(SiKi) :: Theta33 ! = Theta3^2 + REAL(SiKi) :: SqrdSum ! = Theta1^2 + Theta2^2 + Theta3^2 + REAL(SiKi) :: SQRT1SqrdSum ! = SQRT( 1.0 + Theta1^2 + Theta2^2 + Theta3^2 ) LOGICAL, SAVE :: FrstWarn = .TRUE. ! When .TRUE., indicates that we're on the first warning. @@ -6115,18 +5570,18 @@ SUBROUTINE SmllRotTransR( RotationType, Theta1, Theta2, Theta3, TransMat, ErrTxt SQRT1SqrdSum = SQRT( 1.0_ReKi + SqrdSum ) ComDenom = SqrdSum*SQRT1SqrdSum - Theta12S = Theta1*Theta2*( SQRT1SqrdSum - 1.0_Reki ) - Theta13S = Theta1*Theta3*( SQRT1SqrdSum - 1.0_Reki ) - Theta23S = Theta2*Theta3*( SQRT1SqrdSum - 1.0_Reki ) + Theta12S = Theta1*Theta2*( SQRT1SqrdSum - 1.0_Siki ) + Theta13S = Theta1*Theta3*( SQRT1SqrdSum - 1.0_Siki ) + Theta23S = Theta2*Theta3*( SQRT1SqrdSum - 1.0_Siki ) ! Define the transformation matrix: IF ( ComDenom == 0.0_ReKi ) THEN ! All angles are zero and matrix is ill-conditioned (the matrix is derived assuming that the angles are not zero); return identity - TransMat(1,:) = (/ 1.0_ReKi, 0.0_ReKi, 0.0_ReKi /) - TransMat(2,:) = (/ 0.0_ReKi, 1.0_ReKi, 0.0_ReKi /) - TransMat(3,:) = (/ 0.0_ReKi, 0.0_ReKi, 1.0_ReKi /) + TransMat(1,:) = (/ 1.0_SiKi, 0.0_SiKi, 0.0_SiKi /) + TransMat(2,:) = (/ 0.0_SiKi, 1.0_SiKi, 0.0_SiKi /) + TransMat(3,:) = (/ 0.0_SiKi, 0.0_SiKi, 1.0_SiKi /) ELSE ! At least one angle is nonzero @@ -6318,30 +5773,6 @@ FUNCTION SkewSymMatR8 ( x ) RESULT(M) RETURN END FUNCTION SkewSymMatR8 !======================================================================= -!> \copydoc nwtc_num::skewsymmatr4 - FUNCTION SkewSymMatR16 ( x ) RESULT(M) - - ! Function arguments - - REAL(QuKi) :: M(3,3) ! skew-symmetric matrix formed from input vector \f$x\f$ - REAL(QuKi), INTENT(IN) :: x(3) ! input vector \f$x\f$ - - M(1,1) = 0.0_QuKi - M(2,1) = x(3) - M(3,1) = -x(2) - - M(1,2) = -x(3) - M(2,2) = 0.0_QuKi - M(3,2) = x(1) - - M(1,3) = x(2) - M(2,3) = -x(1) - M(3,3) = 0.0_QuKi - - RETURN - END FUNCTION SkewSymMatR16 - -!======================================================================= !> If M is a rotation matrix from a 1-2-3 rotation sequence about Y-X-Z, this function returns !! the 3 sequential angles, \f$\theta_y\f$, \f$\theta_x\f$, and \f$\theta_z\f$ (in radians), that formed !! the matrix. M represents a change of basis (from global to local coordinates; @@ -6625,85 +6056,7 @@ FUNCTION TaitBryanYXZExtractR8(M) result(theta) END FUNCTION TaitBryanYXZExtractR8 -!> See nwtc_num::taitbryanyxzextractr4 for detailed explanation of algorithm - FUNCTION TaitBryanYXZExtractR16(M) result(theta) - - - REAL(QuKi), INTENT(IN) :: M(3,3) !< rotation matrix, M - REAL(QuKi) :: theta(3) !< the 3 rotation angles, \f$(\theta_y, \theta_x, \theta_z)\f$, corresponding to the Tait-Bryan rotation angle corresponding to cant-toe-twist - - REAL(QuKi) :: C_1 ! C_1 > cos(theta_y) - REAL(QuKi) :: S_1 ! S_1 > sin(theta_y) - REAL(QuKi) :: C_2 ! C_2 > cos(theta_x) - REAL(QuKi) :: C_3 ! C_3 > cos(theta_z) - REAL(QuKi) :: S_3 ! S_3 > sin(theta_z) - - !> See nwtc_num::taitbryanyxzextractr4 for detailed description of how this works. - - ! use trig identity S_3**2 + C_3**2 = 1 to get abs( C_2 ) - C_2 = sqrt( m(1,2)**2 + m(2,2)**2 ) - - ! If C_2 is zero, we can simplifiy some things since theta(2) is +/- pi/2 - if ( EqualRealNos( C_2, 0.0_QuKi ) ) then - - ! find sign of theta(2) based on sin(theta_2) - theta(2) = atan2( -m(3,2), C_2 ) ! theta_2 -> theta_x - - ! Considering C_2 = 0 and S_2 = \pm 1, the matrix M reduces to - ! M = [ C_1 C_3 \pm S_1 S_3 0 \pm C_1 S_3 - S_1 C_3 | - ! | \pm S_1 C_3 - C_1 S_3 0 \pm C_1 C_3 + S_1 S_3 | - ! | 0 0 \mp 1 0 ] - ! - ! At this point we can choose \theta_3 = 0 due to gimbal lock giving sin(theta(3)) = 0, cos(theta(3)) = 1. - - theta(3) = 0.0_QuKi ! theta_z = theta_3 - - ! This further reduces M to - ! M = [ C_1 0 - S_1 | - ! | \pm S_1 0 \pm C_1 | - ! | 0 \mp 1 0 ] - ! - ! - ! allowing us to solve for theta_1 by theta_1 = atan2( -M(1,3), M(1,1) ) = atan2( S_1, C_1). - theta(1) = atan2( -m(1,3), m(1,1) ) - - else - ! First, start by finding \f$ \theta(1) \f$ from \f$ M(3,1) \f$ and \f$ M(3,3) \f$ using - ! - ! theta(1) = atan2( M(3,1), M(3,3) ) = atan2( S_1 * C_2, C_1 * C_2 ). - ! With this we calculate values for S_1 and C_1. - - theta(1) = atan2( m(3,1), m(3,3) ) ! theta_1 -> theta_y - C_1 = cos( theta(1) ) - S_1 = sin( theta(1) ) - - ! We already know abs( C_2 ), but need the sign of it. This can be found by comparing the - ! S_1 * C_2 and C_1 * C_2 terms with the C_1 and S_1 terms we just found. - - if ( EqualRealNos( C_1, 0.0_QuKi ) ) then - C_2 = sign( C_2, m(3,1) / S_1 ) - else - C_2 = sign( C_2, m(3,3) / C_1 ) - endif - - ! Now can calculate theta(2) - theta(2) = atan2( -m(3,2), C_2 ) - - - ! For numerical reasons, we're going to get theta(3) using some matrix math and identities about M. - ! See nwtc_num::taitbryanyxzextractr4 for complete documentation on the matrix math used here - - S_3 = -( m(2,1) * C_1 + m(2,3) * (- S_1) ) - C_3 = m(1,1) * C_1 + m(1,3) * (- S_1) - - theta(3) = atan2( S_3, C_3) - - endif - - - END FUNCTION TaitBryanYXZExtractR16 - FUNCTION TaitBryanYXZConstructR4(theta) result(M) ! this function creates a rotation matrix, M, from a 1-2-3 rotation ! sequence of the 3 TaitBryan angles, theta_x, theta_y, and theta_z, in radians. @@ -6754,7 +6107,7 @@ END FUNCTION TaitBryanYXZConstructR4 FUNCTION TaitBryanYXZConstructR8(theta) result(M) - ! this function creates a rotation matrix, M, from a 1-2-3 rotation + ! this function creates a rotation matrix, M, from a 1-2-3 rotation ! sequence of the 3 TaitBryan angles, theta_x, theta_y, and theta_z, in radians. ! M represents a change of basis (from global to local coordinates; ! not a physical rotation of the body). it is the inverse of TaitBryanYXZExtract(). @@ -6801,55 +6154,6 @@ FUNCTION TaitBryanYXZConstructR8(theta) result(M) END FUNCTION TaitBryanYXZConstructR8 - FUNCTION TaitBryanYXZConstructR16(theta) result(M) - - ! this function creates a rotation matrix, M, from a 1-2-3 rotation - ! sequence of the 3 TaitBryan angles, theta_x, theta_y, and theta_z, in radians. - ! M represents a change of basis (from global to local coordinates; - ! not a physical rotation of the body). it is the inverse of TaitBryanYXZExtract(). - ! - ! M = R(theta_z) * R(theta_x) * R(theta_y) - ! = [ cz sz 0 | [ 1 0 0 | [ cy 0 -sy | - ! |-sz cz 0 |* | 0 cx sx | * | 0 1 0 | - ! | 0 0 1 ] | 0 -sx cx ] | sy 0 cy ] - ! = [ cy*cz+sy*sx*sz cx*sz cy*sx*sz-cz*sy | - ! |cz*sy*sx-cy*sz cx*cz cy*cz*sx+sy*sz | - ! |cx*sy -sx cx*cy ] - ! where cz = cos(theta_z), sz = sin(theta_z), cy = cos(theta_y), etc. - - REAL(QuKi) :: M(3,3) ! rotation matrix M - REAL(QuKi), INTENT(IN) :: theta(3) ! the 3 rotation angles: theta_x, theta_y, theta_z - - REAL(QuKi) :: cx ! cos(theta_x) - REAL(QuKi) :: sx ! sin(theta_x) - REAL(QuKi) :: cy ! cos(theta_y) - REAL(QuKi) :: sy ! sin(theta_y) - REAL(QuKi) :: cz ! cos(theta_z) - REAL(QuKi) :: sz ! sin(theta_z) - - cx = cos( theta(1) ) - sx = sin( theta(1) ) - - cy = cos( theta(2) ) - sy = sin( theta(2) ) - - cz = cos( theta(3) ) - sz = sin( theta(3) ) - - M(1,1) = cy*cz+sy*sx*sz - M(1,2) = cx*sz - M(1,3) = cy*sx*sz-cz*sy - - M(2,1) = cz*sy*sx-cy*sz - M(2,2) = cx*cz - M(2,3) = cy*cz*sx+sy*sz - - M(3,1) = cx*sy - M(3,2) = -sx - M(3,3) = cy*cx - - END FUNCTION TaitBryanYXZConstructR16 - !======================================================================= !> This routine takes an array of time values such as that returned from @@ -6907,24 +6211,7 @@ FUNCTION traceR8(A) end do END FUNCTION traceR8 -!======================================================================= -!> \copydoc nwtc_num::tracer4 - FUNCTION traceR16(A) - - REAL(QuKi), INTENT(IN) :: A(:,:) - REAL(QuKi) :: traceR16 - - INTEGER(IntKi) :: n ! rows/cols in A - INTEGER(IntKi) :: i ! loop counter - - n = min( SIZE(A,1), SIZE(A,2) ) - traceR16 = 0.0_ReKi - do i=1,n - traceR16 = traceR16 + A(i,i) - end do - - END FUNCTION traceR16 !======================================================================= !> This function returns the \f$l_2\f$ (Euclidian) norm of a vector, !! \f$v = \left(v_1, v_2, \ldots ,v_n\right)\f$. The \f$l_2\f$-norm is defined as @@ -6957,20 +6244,7 @@ FUNCTION TwoNormR8(v) END FUNCTION -!======================================================================= -!> \copydoc nwtc_num::twonormr4 - FUNCTION TwoNormR16(v) - - ! this function returns the 2-norm of a vector v - ! fortran 2008 has Norm2() built in - - REAL(QuKi), INTENT(IN) :: v(:) - REAL(QuKi) :: TwoNormR16 - - TwoNormR16 = SQRT( DOT_PRODUCT(v, v) ) - - - END FUNCTION + !======================================================================= !> This routine is used to convert Angle to an equivalent value !! in the range \f$[0, 2\pi)\f$. \n @@ -7024,47 +6298,19 @@ SUBROUTINE Zero2TwoPiR8 ( Angle ) RETURN END SUBROUTINE Zero2TwoPiR8 -!======================================================================= -!> \copydoc nwtc_num::zero2twopir4 - SUBROUTINE Zero2TwoPiR16 ( Angle ) - - ! This routine is used to convert Angle to an equivalent value - ! in the range [0, 2*pi). - - - ! Argument declarations: - - REAL(QuKi), INTENT(INOUT) :: Angle - - - - ! Get the angle between 0 and 2Pi. - - Angle = MODULO( Angle, TwoPi_R16 ) - - - ! Check numerical case where Angle == 2Pi. - - IF ( Angle == TwoPi_R16 ) THEN - Angle = 0.0_DbKi - END IF - - - RETURN - END SUBROUTINE Zero2TwoPiR16 !======================================================================= !< This routine extrapolates or interpolates between angles SUBROUTINE Angles_ExtrapInterp1_R4(Angle1, Angle2, tin, Angle_out, tin_out ) REAL(SiKi), INTENT(IN ) :: Angle1 !< Angle at t1 > t2 REAL(SiKi), INTENT(IN ) :: Angle2 !< Angle at t2 - REAL(DbKi), INTENT(IN ) :: tin(:) !< Times associated with the inputs + REAL(R8Ki), INTENT(IN ) :: tin(:) !< Times associated with the inputs REAL(SiKi), INTENT(INOUT) :: Angle_out !< Input at tin_out - REAL(DbKi), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to + REAL(R8Ki), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to ! local variables INTEGER(IntKi), parameter :: order = 1 ! order of polynomial fit (max 2) - REAL(DbKi) :: t(SIZE(tin)) ! Times associated with the inputs - REAL(DbKi) :: t_out ! Time to which to be extrap/interpd + REAL(R8Ki) :: t(SIZE(tin)) ! Times associated with the inputs + REAL(R8Ki) :: t_out ! Time to which to be extrap/interpd REAL(SiKi) :: Angle2_mod @@ -7101,14 +6347,14 @@ END SUBROUTINE Angles_ExtrapInterp1_R4 SUBROUTINE Angles_ExtrapInterp1_R8(Angle1, Angle2, tin, Angle_out, tin_out) REAL(R8Ki), INTENT(IN ) :: Angle1 !< Angle at t1 > t2 REAL(R8Ki), INTENT(IN ) :: Angle2 !< Angle at t2 - REAL(DbKi), INTENT(IN ) :: tin(:) !< Times associated with the inputs + REAL(R8Ki), INTENT(IN ) :: tin(:) !< Times associated with the inputs REAL(R8Ki), INTENT(INOUT) :: Angle_out !< Input at tin_out - REAL(DbKi), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to + REAL(R8Ki), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to ! local variables INTEGER(IntKi), parameter :: order = 1 ! order of polynomial fit (max 2) - REAL(DbKi) :: t(SIZE(tin)) ! Times associated with the inputs - REAL(DbKi) :: t_out ! Time to which to be extrap/interpd + REAL(R8Ki) :: t(SIZE(tin)) ! Times associated with the inputs + REAL(R8Ki) :: t_out ! Time to which to be extrap/interpd REAL(R8Ki) :: Angle2_mod @@ -7139,62 +6385,19 @@ SUBROUTINE Angles_ExtrapInterp1_R8(Angle1, Angle2, tin, Angle_out, tin_out) ! call MPi2Pi(Angle_out) END SUBROUTINE Angles_ExtrapInterp1_R8 -!======================================================================= - !< This routine extrapolates or interpolates between angles - SUBROUTINE Angles_ExtrapInterp1_R16(Angle1, Angle2, tin, Angle_out, tin_out) - REAL(QuKi), INTENT(IN ) :: Angle1 !< Angle at t1 > t2 - REAL(QuKi), INTENT(IN ) :: Angle2 !< Angle at t2 - REAL(DbKi), INTENT(IN ) :: tin(:) !< Times associated with the inputs - REAL(QuKi), INTENT(INOUT) :: Angle_out !< Input at tin_out - REAL(DbKi), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to - - ! local variables - INTEGER(IntKi), parameter :: order = 1 ! order of polynomial fit (max 2) - REAL(DbKi) :: t(SIZE(tin)) ! Times associated with the inputs - REAL(DbKi) :: t_out ! Time to which to be extrap/interpd - - REAL(QuKi) :: Angle2_mod - - ! we'll subtract a constant from the times to resolve some - ! numerical issues when t gets large (and to simplify the equations) - t = tin - tin(1) - t_out = tin_out - tin(1) - - ! ! some error checking: - ! - ! if ( size(t) .ne. order+1) then - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Angles_ExtrapInterp1: size(t) must equal 2.' - ! RETURN - ! end if - ! - !IF ( EqualRealNos( t(1), t(2) ) ) THEN - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Angles_ExtrapInterp1: t(1) must not equal t(2) to avoid a division-by-zero error.' - ! RETURN - !END IF - - Angle2_mod = Angle2 - call AddOrSub2Pi( Angle1, Angle2_mod ) - - Angle_out = Angle1 + (Angle2_mod - Angle1) * t_out / t(2) -! call Zero2TwoPi(Angle_out) -! call MPi2Pi(Angle_out) - - END SUBROUTINE Angles_ExtrapInterp1_R16 !======================================================================= !< This routine extrapolates or interpolates between angles SUBROUTINE Angles_ExtrapInterp1_R4R(Angle1, Angle2, tin, Angle_out, tin_out ) REAL(SiKi), INTENT(IN ) :: Angle1 !< Angle at t1 > t2 REAL(SiKi), INTENT(IN ) :: Angle2 !< Angle at t2 - REAL(ReKi), INTENT(IN ) :: tin(:) !< Times associated with the inputs + REAL(R4Ki), INTENT(IN ) :: tin(:) !< Times associated with the inputs REAL(SiKi), INTENT(INOUT) :: Angle_out !< Input at tin_out - REAL(ReKi), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to + REAL(R4Ki), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to ! local variables INTEGER(IntKi), parameter :: order = 1 ! order of polynomial fit (max 2) - REAL(ReKi) :: t(SIZE(tin)) ! Times associated with the inputs - REAL(ReKi) :: t_out ! Time to which to be extrap/interpd + REAL(SiKi) :: t(SIZE(tin)) ! Times associated with the inputs + REAL(SiKi) :: t_out ! Time to which to be extrap/interpd REAL(SiKi) :: Angle2_mod @@ -7231,14 +6434,14 @@ END SUBROUTINE Angles_ExtrapInterp1_R4R SUBROUTINE Angles_ExtrapInterp1_R8R(Angle1, Angle2, tin, Angle_out, tin_out) REAL(R8Ki), INTENT(IN ) :: Angle1 !< Angle at t1 > t2 REAL(R8Ki), INTENT(IN ) :: Angle2 !< Angle at t2 - REAL(ReKi), INTENT(IN ) :: tin(:) !< Times associated with the inputs + REAL(SiKi), INTENT(IN ) :: tin(:) !< Times associated with the inputs REAL(R8Ki), INTENT(INOUT) :: Angle_out !< Input at tin_out - REAL(ReKi), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to + REAL(SiKi), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to ! local variables INTEGER(IntKi), parameter :: order = 1 ! order of polynomial fit (max 2) - REAL(ReKi) :: t(SIZE(tin)) ! Times associated with the inputs - REAL(ReKi) :: t_out ! Time to which to be extrap/interpd + REAL(SiKi) :: t(SIZE(tin)) ! Times associated with the inputs + REAL(SiKi) :: t_out ! Time to which to be extrap/interpd REAL(R8Ki) :: Angle2_mod @@ -7269,49 +6472,6 @@ SUBROUTINE Angles_ExtrapInterp1_R8R(Angle1, Angle2, tin, Angle_out, tin_out) ! call MPi2Pi(Angle_out) END SUBROUTINE Angles_ExtrapInterp1_R8R -!======================================================================= - !< This routine extrapolates or interpolates between angles - SUBROUTINE Angles_ExtrapInterp1_R16R(Angle1, Angle2, tin, Angle_out, tin_out) - REAL(QuKi), INTENT(IN ) :: Angle1 !< Angle at t1 > t2 - REAL(QuKi), INTENT(IN ) :: Angle2 !< Angle at t2 - REAL(ReKi), INTENT(IN ) :: tin(:) !< Times associated with the inputs - REAL(QuKi), INTENT(INOUT) :: Angle_out !< Input at tin_out - REAL(ReKi), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to - - ! local variables - INTEGER(IntKi), parameter :: order = 1 ! order of polynomial fit (max 2) - REAL(ReKi) :: t(SIZE(tin)) ! Times associated with the inputs - REAL(ReKi) :: t_out ! Time to which to be extrap/interpd - - REAL(QuKi) :: Angle2_mod - - ! we'll subtract a constant from the times to resolve some - ! numerical issues when t gets large (and to simplify the equations) - t = tin - tin(1) - t_out = tin_out - tin(1) - - ! ! some error checking: - ! - ! if ( size(t) .ne. order+1) then - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Angles_ExtrapInterp1: size(t) must equal 2.' - ! RETURN - ! end if - ! - !IF ( EqualRealNos( t(1), t(2) ) ) THEN - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Angles_ExtrapInterp1: t(1) must not equal t(2) to avoid a division-by-zero error.' - ! RETURN - !END IF - - Angle2_mod = Angle2 - call AddOrSub2Pi( Angle1, Angle2_mod ) - - Angle_out = Angle1 + (Angle2_mod - Angle1) * t_out / t(2) -! call Zero2TwoPi(Angle_out) -! call MPi2Pi(Angle_out) - - END SUBROUTINE Angles_ExtrapInterp1_R16R !======================================================================= !< This routine extrapolates or interpolates between angles SUBROUTINE Angles_ExtrapInterp2_R4(Angle1, Angle2, Angle3, tin, Angle_out, tin_out ) @@ -7437,84 +6597,23 @@ SUBROUTINE Angles_ExtrapInterp2_R8(Angle1, Angle2, Angle3, tin, Angle_out, tin_o ! call MPi2Pi(Angle_out) END SUBROUTINE Angles_ExtrapInterp2_R8 -!======================================================================= - !< This routine extrapolates or interpolates between angles - SUBROUTINE Angles_ExtrapInterp2_R16(Angle1, Angle2, Angle3, tin, Angle_out, tin_out ) - REAL(QuKi), INTENT(IN ) :: Angle1 !< Angle at t1 > t2 > t3 - REAL(QuKi), INTENT(IN ) :: Angle2 !< Angle at t2 > t3 - REAL(QuKi), INTENT(IN ) :: Angle3 !< Angle at t3 - REAL(DbKi), INTENT(IN ) :: tin(:) !< Times associated with the inputs - REAL(QuKi), INTENT(INOUT) :: Angle_out !< Input at tin_out - REAL(DbKi), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to - - ! local variables - INTEGER(IntKi), parameter :: order = 2 ! order of polynomial fit (max 2) - REAL(DbKi) :: t(SIZE(tin)) ! Times associated with the inputs - REAL(DbKi) :: t_out ! Time to which to be extrap/interpd - - REAL(DbKi) :: scaleFactor ! temporary for extrapolation/interpolation - REAL(QuKi) :: Angle2_mod - REAL(QuKi) :: Angle3_mod - - ! we'll subtract a constant from the times to resolve some - ! numerical issues when t gets large (and to simplify the equations) - t = tin - tin(1) - t_out = tin_out - tin(1) - - ! some error checking: - - !if ( size(t) .ne. order+1) then - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Angles_ExtrapInterp2: size(t) must equal 3.' - ! RETURN - !end if - ! - !IF ( EqualRealNos( t(1), t(2) ) ) THEN - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Angles_ExtrapInterp2: t(1) must not equal t(2) to avoid a division-by-zero error.' - ! RETURN - !END IF - !IF ( EqualRealNos( t(2), t(3) ) ) THEN - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Angles_ExtrapInterp2: t(2) must not equal t(3) to avoid a division-by-zero error.' - ! RETURN - !END IF - !IF ( EqualRealNos( t(1), t(3) ) ) THEN - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Angles_ExtrapInterp2: t(1) must not equal t(3) to avoid a division-by-zero error.' - ! RETURN - !END IF - Angle2_mod = Angle2 - Angle3_mod = Angle3 - call AddOrSub2Pi( Angle1, Angle2_mod ) - call AddOrSub2Pi( Angle2_mod, Angle3_mod ) - - scaleFactor = t_out / ( t(2) * t(3) * (t(2) - t(3)) ) - - Angle_out = Angle1 & - + ( t(3)**2 * (Angle1 - Angle2_mod) + t(2)**2*(-Angle1 + Angle3_mod) ) * scaleFactor & - + ( (t(2)-t(3))*Angle1 + t(3)*Angle2_mod - t(2)*Angle3_mod ) *scaleFactor * t_out -! call Zero2TwoPi(Angle_out) -! call MPi2Pi(Angle_out) - - END SUBROUTINE Angles_ExtrapInterp2_R16 !======================================================================= !< This routine extrapolates or interpolates between angles SUBROUTINE Angles_ExtrapInterp2_R4R(Angle1, Angle2, Angle3, tin, Angle_out, tin_out ) REAL(SiKi), INTENT(IN ) :: Angle1 !< Angle at t1 > t2 > t3 REAL(SiKi), INTENT(IN ) :: Angle2 !< Angle at t2 > t3 REAL(SiKi), INTENT(IN ) :: Angle3 !< Angle at t3 - REAL(ReKi), INTENT(IN ) :: tin(:) !< Times associated with the inputs + REAL(R4Ki), INTENT(IN ) :: tin(:) !< Times associated with the inputs REAL(SiKi), INTENT(INOUT) :: Angle_out !< Input at tin_out - REAL(ReKi), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to + REAL(R4Ki), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to ! local variables INTEGER(IntKi), parameter :: order = 2 ! order of polynomial fit (max 2) - REAL(ReKi) :: t(SIZE(tin)) ! Times associated with the inputs - REAL(ReKi) :: t_out ! Time to which to be extrap/interpd + REAL(R4Ki) :: t(SIZE(tin)) ! Times associated with the inputs + REAL(R4Ki) :: t_out ! Time to which to be extrap/interpd - REAL(DbKi) :: scaleFactor ! temporary for extrapolation/interpolation + REAL(R8Ki) :: scaleFactor ! temporary for extrapolation/interpolation REAL(SiKi) :: Angle2_mod REAL(SiKi) :: Angle3_mod @@ -7568,16 +6667,16 @@ SUBROUTINE Angles_ExtrapInterp2_R8R(Angle1, Angle2, Angle3, tin, Angle_out, tin_ REAL(R8Ki), INTENT(IN ) :: Angle1 !< Angle at t1 > t2 > t3 REAL(R8Ki), INTENT(IN ) :: Angle2 !< Angle at t2 > t3 REAL(R8Ki), INTENT(IN ) :: Angle3 !< Angle at t3 - REAL(ReKi), INTENT(IN ) :: tin(:) !< Times associated with the inputs + REAL(R4Ki), INTENT(IN ) :: tin(:) !< Times associated with the inputs REAL(R8Ki), INTENT(INOUT) :: Angle_out !< Input at tin_out - REAL(ReKi), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to + REAL(R4Ki), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to ! local variables INTEGER(IntKi), parameter :: order = 2 ! order of polynomial fit (max 2) - REAL(ReKi) :: t(SIZE(tin)) ! Times associated with the inputs - REAL(ReKi) :: t_out ! Time to which to be extrap/interpd + REAL(R4Ki) :: t(SIZE(tin)) ! Times associated with the inputs + REAL(R4Ki) :: t_out ! Time to which to be extrap/interpd - REAL(DbKi) :: scaleFactor ! temporary for extrapolation/interpolation + REAL(R8Ki) :: scaleFactor ! temporary for extrapolation/interpolation REAL(R8Ki) :: Angle2_mod REAL(R8Ki) :: Angle3_mod @@ -7624,67 +6723,5 @@ SUBROUTINE Angles_ExtrapInterp2_R8R(Angle1, Angle2, Angle3, tin, Angle_out, tin_ ! call MPi2Pi(Angle_out) END SUBROUTINE Angles_ExtrapInterp2_R8R -!======================================================================= - !< This routine extrapolates or interpolates between angles - SUBROUTINE Angles_ExtrapInterp2_R16R(Angle1, Angle2, Angle3, tin, Angle_out, tin_out ) - REAL(QuKi), INTENT(IN ) :: Angle1 !< Angle at t1 > t2 > t3 - REAL(QuKi), INTENT(IN ) :: Angle2 !< Angle at t2 > t3 - REAL(QuKi), INTENT(IN ) :: Angle3 !< Angle at t3 - REAL(ReKi), INTENT(IN ) :: tin(:) !< Times associated with the inputs - REAL(QuKi), INTENT(INOUT) :: Angle_out !< Input at tin_out - REAL(ReKi), INTENT(IN ) :: tin_out !< time to be extrap/interp'd to - - ! local variables - INTEGER(IntKi), parameter :: order = 2 ! order of polynomial fit (max 2) - REAL(ReKi) :: t(SIZE(tin)) ! Times associated with the inputs - REAL(ReKi) :: t_out ! Time to which to be extrap/interpd - - REAL(DbKi) :: scaleFactor ! temporary for extrapolation/interpolation - REAL(QuKi) :: Angle2_mod - REAL(QuKi) :: Angle3_mod - - ! we'll subtract a constant from the times to resolve some - ! numerical issues when t gets large (and to simplify the equations) - t = tin - tin(1) - t_out = tin_out - tin(1) - - ! some error checking: - - !if ( size(t) .ne. order+1) then - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Angles_ExtrapInterp2: size(t) must equal 3.' - ! RETURN - !end if - ! - !IF ( EqualRealNos( t(1), t(2) ) ) THEN - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Angles_ExtrapInterp2: t(1) must not equal t(2) to avoid a division-by-zero error.' - ! RETURN - !END IF - !IF ( EqualRealNos( t(2), t(3) ) ) THEN - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Angles_ExtrapInterp2: t(2) must not equal t(3) to avoid a division-by-zero error.' - ! RETURN - !END IF - !IF ( EqualRealNos( t(1), t(3) ) ) THEN - ! ErrStat = ErrID_Fatal - ! ErrMsg = 'Angles_ExtrapInterp2: t(1) must not equal t(3) to avoid a division-by-zero error.' - ! RETURN - !END IF - - Angle2_mod = Angle2 - Angle3_mod = Angle3 - call AddOrSub2Pi( Angle1, Angle2_mod ) - call AddOrSub2Pi( Angle2_mod, Angle3_mod ) - - scaleFactor = t_out / ( t(2) * t(3) * (t(2) - t(3)) ) - - Angle_out = Angle1 & - + ( t(3)**2 * (Angle1 - Angle2_mod) + t(2)**2*(-Angle1 + Angle3_mod) ) * scaleFactor & - + ( (t(2)-t(3))*Angle1 + t(3)*Angle2_mod - t(2)*Angle3_mod ) *scaleFactor * t_out -! call Zero2TwoPi(Angle_out) -! call MPi2Pi(Angle_out) - - END SUBROUTINE Angles_ExtrapInterp2_R16R !======================================================================= END MODULE NWTC_Num diff --git a/modules/nwtc-library/src/NWTC_RandomNumber.f90 b/modules/nwtc-library/src/NWTC_RandomNumber.f90 index ed8b6648f..f12b9a852 100644 --- a/modules/nwtc-library/src/NWTC_RandomNumber.f90 +++ b/modules/nwtc-library/src/NWTC_RandomNumber.f90 @@ -35,7 +35,6 @@ MODULE NWTC_RandomNumber INTERFACE UniformRandomNumbers MODULE PROCEDURE UniformRandomNumbersR4 ! 4-byte reals MODULE PROCEDURE UniformRandomNumbersR8 ! 8-byte reals -MODULE PROCEDURE UniformRandomNumbersR16 ! 16-byte reals END INTERFACE CONTAINS @@ -159,32 +158,5 @@ SUBROUTINE UniformRandomNumbersR8( pRNG_Type, RandomNumbers ) END IF END SUBROUTINE UniformRandomNumbersR8 -!======================================================================= -!> \copydoc nwtc_randomnumber::uniformrandomnumbersr4 -SUBROUTINE UniformRandomNumbersR16( pRNG_Type, RandomNumbers ) - - IMPLICIT NONE - - INTEGER, INTENT(IN ) :: pRNG_Type - REAL(QuKi), INTENT( OUT), DIMENSION(:) :: RandomNumbers - - REAL(ReKi), ALLOCATABLE :: RN(:) - - IF ( pRNG_Type == pRNG_INTRINSIC ) THEN - - ! The Fortran intrinsic has an interface for various floating - ! point types, so pass the variable directly - CALL RANDOM_NUMBER( RandomNumbers ) - - ELSEIF ( pRNG_Type == pRNG_RANLUX ) THEN - - ! RanLux, as implemented, uses ReKi, so cast the return value as needed - ALLOCATE( RN( SIZE(RandomNumbers) ) ) - CALL RanLux ( RN ) - RandomNumbers = REAL(RN, KIND=QuKi) - - END IF - -END SUBROUTINE UniformRandomNumbersR16 END MODULE diff --git a/modules/nwtc-library/src/NetLib/scalapack/NWTC_ScaLAPACK.f90 b/modules/nwtc-library/src/NetLib/scalapack/NWTC_ScaLAPACK.f90 index 556220d10..c458f774b 100644 --- a/modules/nwtc-library/src/NetLib/scalapack/NWTC_ScaLAPACK.f90 +++ b/modules/nwtc-library/src/NetLib/scalapack/NWTC_ScaLAPACK.f90 @@ -43,7 +43,7 @@ SUBROUTINE ScaLAPACK_DLASRT2( ID, N, D, KEY, ErrStat, ErrMsg ) ! .. Array Arguments .. INTEGER, intent(inout) :: KEY( : ) - DOUBLE PRECISION,intent(inout) :: D( : ) ! On entry, the array to be sorted. On exit, D has been sorted into increasing/decreasing order, depending on ID + REAL(R8Ki) ,intent(inout) :: D( : ) ! On entry, the array to be sorted. On exit, D has been sorted into increasing/decreasing order, depending on ID ! Local variable INTEGER :: INFO ! = 0: successful exit; < 0: if INFO = -i, the i-th argument had an illegal value @@ -79,7 +79,7 @@ SUBROUTINE ScaLAPACK_SLASRT2( ID, N, D, KEY, ErrStat, ErrMsg ) ! .. Array Arguments .. INTEGER, intent(inout) :: KEY( : ) - REAL, intent(inout) :: D( : ) ! On entry, the array to be sorted. On exit, D has been sorted into increasing/decreasing order, depending on ID + REAL(R4Ki), intent(inout) :: D( : ) ! On entry, the array to be sorted. On exit, D has been sorted into increasing/decreasing order, depending on ID ! Local variable INTEGER :: INFO ! = 0: successful exit; < 0: if INFO = -i, the i-th argument had an illegal value diff --git a/modules/nwtc-library/src/NetLib/slatec/NWTC_SLATEC.f90 b/modules/nwtc-library/src/NetLib/slatec/NWTC_SLATEC.f90 index 68fe20777..bd9576038 100644 --- a/modules/nwtc-library/src/NetLib/slatec/NWTC_SLATEC.f90 +++ b/modules/nwtc-library/src/NetLib/slatec/NWTC_SLATEC.f90 @@ -47,20 +47,20 @@ MODULE NWTC_SLATEC !> Single precision wrapper for the qk61 integration routine from the slatec library !! Note that the qk61 routine follows -fdefault-real-8 setting, so it is of type ReKi subroutine wrap_qk61(func,low,hi,answer,abserr,resabs,resasc) - real(ReKi), intent(in ) :: low,hi ! integration limits - real(ReKi), intent( out) :: answer - real(ReKi), intent(in ) :: abserr,resabs,resasc - real(ReKi), external :: func ! function + real(R4Ki), intent(in ) :: low,hi ! integration limits + real(R4Ki), intent( out) :: answer + real(R4Ki), intent(in ) :: abserr,resabs,resasc + real(R4Ki), external :: func ! function call qk61(func,low,hi,answer,abserr,resabs,resasc) end subroutine wrap_qk61 !> Double precision wrapper for the dqk61 integration routine from the slatec library !! Note that the qk61 routine follows -fdefault-real-8 setting, so it is of type DbKi subroutine wrap_dqk61(func,low,hi,answer,abserr,resabs,resasc) - real(DbKi), intent(in ) :: low,hi ! integration limits - real(DbKi), intent( out) :: answer - real(DbKi), intent(in ) :: abserr,resabs,resasc - real(DbKi), external :: func ! function + real(R8Ki), intent(in ) :: low,hi ! integration limits + real(R8Ki), intent( out) :: answer + real(R8Ki), intent(in ) :: abserr,resabs,resasc + real(R8Ki), external :: func ! function call dqk61(func,low,hi,answer,abserr,resabs,resasc) end subroutine wrap_dqk61 diff --git a/modules/nwtc-library/src/Polynomial/quartic.f90 b/modules/nwtc-library/src/Polynomial/quartic.f90 new file mode 100644 index 000000000..ee88e26ed --- /dev/null +++ b/modules/nwtc-library/src/Polynomial/quartic.f90 @@ -0,0 +1,591 @@ +!+ +MODULE PolynomialRoots +! --------------------------------------------------------------------------- +! PURPOSE - Solve for the roots of a polynomial equation with real +! coefficients, up to quartic order. Retrun a code indicating the nature +! of the roots found. + +! AUTHORS - Alfred H. Morris, Naval Surface Weapons Center, Dahlgren,VA +! William L. Davis, Naval Surface Weapons Center, Dahlgren,VA +! Alan Miller, CSIRO Mathematical & Information Sciences +! CLAYTON, VICTORIA, AUSTRALIA 3169 +! http://www.mel.dms.csiro.au/~alan +! Ralph L. Carmichael, Public Domain Aeronautical Software +! http://www.pdas.com +! REVISION HISTORY +! DATE VERS PERSON STATEMENT OF CHANGES +! ?? 1.0 AHM&WLD Original coding +! 27Feb97 1.1 AM Converted to be compatible with ELF90 +! 12Jul98 1.2 RLC Module format; numerous style changes +! 4Jan99 1.3 RLC Made the tests for zero constant term exactly zero + + + IMPLICIT NONE + + INTEGER,PARAMETER,PRIVATE:: SP=KIND(1.0_4), DP=KIND(1.0_8) + REAL(DP),PARAMETER,PRIVATE:: ZERO=0.0D0, FOURTH=0.25D0, HALF=0.5D0 + REAL(DP),PARAMETER,PRIVATE:: ONE=1.0D0, TWO=2.0D0, THREE=3.0D0, FOUR=4.0D0 + COMPLEX(DP),PARAMETER,PRIVATE:: CZERO=(0.D0,0.D0) + + REAL(DP),PARAMETER,PRIVATE:: EPS=EPSILON(ONE) + + CHARACTER(LEN=*),PARAMETER,PUBLIC:: POLYROOTS_VERSION= "1.3 (4 Jan 1999)" + INTEGER,PRIVATE:: outputCode +! =0 degenerate equation +! =1 one real root +! =21 two identical real roots +! =22 two distinct real roots +! =23 two complex roots +! =31 multiple real roots +! =32 one real and two complex roots +! =33 three distinct real roots +! =41 +! =42 two real and two complex roots +! =43 +! =44 four complex roots + + PRIVATE:: CubeRoot + PUBLIC:: LinearRoot + PRIVATE:: OneLargeTwoSmall + PUBLIC:: QuadraticRoots + PUBLIC:: CubicRoots + PUBLIC:: QuarticRoots + PUBLIC:: SolvePolynomial +!---------------------------------------------------------------------------- + + INTERFACE Swap + MODULE PROCEDURE SwapDouble + MODULE PROCEDURE SwapSingle + END INTERFACE + +CONTAINS + +!+ +FUNCTION CubeRoot(x) RESULT(f) +! --------------------------------------------------------------------------- +! PURPOSE - Compute the Cube Root of a REAL(DP) number. If the argument is +! negative, then the cube root is also negative. + + REAL(DP),INTENT(IN) :: x + REAL(DP):: f +!---------------------------------------------------------------------------- + IF (x < ZERO) THEN + f=-EXP(LOG(-x)/THREE) + ELSE IF (x > ZERO) THEN + f=EXP(LOG(x)/THREE) + ELSE + f=ZERO + END IF + RETURN +END Function CubeRoot ! --------------------------------------------------- + +!+ +SUBROUTINE LinearRoot(a, z) +! --------------------------------------------------------------------------- +! PURPOSE - COMPUTES THE ROOTS OF THE REAL POLYNOMIAL +! A(1) + A(2)*Z +! AND STORES THE RESULTS IN Z. It is assumed that a(2) is non-zero. + REAL(DP),INTENT(IN),DIMENSION(:):: a + REAL(DP),INTENT(OUT):: z +!---------------------------------------------------------------------------- + IF (a(2)==0.0) THEN + z=ZERO + ELSE + z=-a(1)/a(2) + END IF + RETURN +END Subroutine LinearRoot ! ----------------------------------------------- + +!+ +SUBROUTINE OneLargeTwoSmall(a1,a2,a4,w, z) +! --------------------------------------------------------------------------- +! PURPOSE - Compute the roots of a cubic when one root, w, is known to be +! much larger in magnitude than the other two + + REAL(DP),INTENT(IN):: a1,a2,a4 + REAL(DP),INTENT(IN):: w + COMPLEX(DP),INTENT(OUT),DIMENSION(:):: z + + + REAL(DP),DIMENSION(3):: aq +!---------------------------------------------------------------------------- + aq(1)=a1 + aq(2)=a2+a1/w + aq(3)=-a4*w + CALL QuadraticRoots(aq, z) + z(3)=CMPLX(w,ZERO,DP) + + IF (AIMAG(z(1)) == ZERO) RETURN + z(3)=z(2) + z(2)=z(1) + z(1)=CMPLX(w,ZERO,DP) + RETURN +END Subroutine OneLargeTwoSmall ! ----------------------------------------- + +!+ +SUBROUTINE QuadraticRoots(a, z) +! --------------------------------------------------------------------------- +! PURPOSE - COMPUTES THE ROOTS OF THE REAL POLYNOMIAL +! A(1) + A(2)*Z + A(3)*Z**2 +! AND STORES THE RESULTS IN Z. IT IS ASSUMED THAT A(3) IS NONZERO. + + REAL(DP),INTENT(IN),DIMENSION(:):: a + COMPLEX(DP),INTENT(OUT),DIMENSION(:):: z + + + REAL(DP):: d, r, w, x, y +!---------------------------------------------------------------------------- + IF(a(1)==0.0) THEN ! EPS is a global module constant (private) + z(1) = CZERO ! one root is obviously zero + z(2) = CMPLX(-a(2)/a(3), ZERO,DP) ! remainder is a linear eq. + outputCode=21 ! two identical real roots + RETURN + END IF + + d = a(2)*a(2) - FOUR*a(1)*a(3) ! the discriminant + IF (ABS(d) <= TWO*eps*a(2)*a(2)) THEN + z(1) = CMPLX(-HALF*a(2)/a(3), ZERO, DP) ! discriminant is tiny + z(2) = z(1) + outputCode=22 ! two distinct real roots + RETURN + END IF + + r = SQRT(ABS(d)) + IF (d < ZERO) THEN + x = -HALF*a(2)/a(3) ! negative discriminant => roots are complex + y = ABS(HALF*r/a(3)) + z(1) = CMPLX(x, y, DP) + z(2) = CMPLX(x,-y, DP) ! its conjugate + outputCode=23 ! COMPLEX ROOTS + RETURN + END IF + + IF (a(2) /= ZERO) THEN ! see Numerical Recipes, sec. 5.5 + w = -(a(2) + SIGN(r,a(2))) + z(1) = CMPLX(TWO*a(1)/w, ZERO, DP) + z(2) = CMPLX(HALF*w/a(3), ZERO, DP) + outputCode=22 ! two real roots + RETURN + END IF + + x = ABS(HALF*r/a(3)) ! a(2)=0 if you get here + z(1) = CMPLX( x, ZERO, DP) + z(2) = CMPLX(-x, ZERO, DP) + outputCode=22 + RETURN +END Subroutine QuadraticRoots ! ------------------------------------------- + +!+ +SUBROUTINE CubicRoots(a, z) +!---------------------------------------------------------------------------- +! PURPOSE - Compute the roots of the real polynomial +! A(1) + A(2)*Z + A(3)*Z**2 + A(4)*Z**3 + REAL(DP),INTENT(IN),DIMENSION(:):: a + COMPLEX(DP),INTENT(OUT),DIMENSION(:):: z + + REAL(DP),PARAMETER:: RT3=1.7320508075689D0 ! (Sqrt(3) + REAL (DP) :: aq(3), arg, c, cf, d, p, p1, q, q1 + REAL(DP):: r, ra, rb, rq, rt + REAL(DP):: r1, s, sf, sq, sum, t, tol, t1, w + REAL(DP):: w1, w2, x, x1, x2, x3, y, y1, y2, y3 + +! NOTE - It is assumed that a(4) is non-zero. No test is made here. +!---------------------------------------------------------------------------- + IF (a(1)==0.0) THEN + z(1) = CZERO ! one root is obviously zero + CALL QuadraticRoots(a(2:4), z(2:3)) ! remaining 2 roots here + RETURN + END IF + + p = a(3)/(THREE*a(4)) + q = a(2)/a(4) + r = a(1)/a(4) + tol = FOUR*EPS + + c = ZERO + t = a(2) - p*a(3) + IF (ABS(t) > tol*ABS(a(2))) c = t/a(4) + + t = TWO*p*p - q + IF (ABS(t) <= tol*ABS(q)) t = ZERO + d = r + p*t + IF (ABS(d) <= tol*ABS(r)) GO TO 110 + +! SET SQ = (A(4)/S)**2 * (C**3/27 + D**2/4) + + s = MAX(ABS(a(1)), ABS(a(2)), ABS(a(3))) + p1 = a(3)/(THREE*s) + q1 = a(2)/s + r1 = a(1)/s + + t1 = q - 2.25D0*p*p + IF (ABS(t1) <= tol*ABS(q)) t1 = ZERO + w = FOURTH*r1*r1 + w1 = HALF*p1*r1*t + w2 = q1*q1*t1/27.0D0 + + IF (w1 >= ZERO) THEN + w = w + w1 + sq = w + w2 + ELSE IF (w2 < ZERO) THEN + sq = w + (w1 + w2) + ELSE + w = w + w2 + sq = w + w1 + END IF + + IF (ABS(sq) <= tol*w) sq = ZERO + rq = ABS(s/a(4))*SQRT(ABS(sq)) + IF (sq >= ZERO) GO TO 40 + +! ALL ROOTS ARE REAL + + arg = ATAN2(rq, -HALF*d) + cf = COS(arg/THREE) + sf = SIN(arg/THREE) + rt = SQRT(-c/THREE) + y1 = TWO*rt*cf + y2 = -rt*(cf + rt3*sf) + y3 = -(d/y1)/y2 + + x1 = y1 - p + x2 = y2 - p + x3 = y3 - p + + IF (ABS(x1) > ABS(x2)) CALL Swap(x1,x2) + IF (ABS(x2) > ABS(x3)) CALL Swap(x2,x3) + IF (ABS(x1) > ABS(x2)) CALL Swap(x1,x2) + + w = x3 + + IF (ABS(x2) < 0.1D0*ABS(x3)) GO TO 70 + IF (ABS(x1) < 0.1D0*ABS(x2)) x1 = - (r/x3)/x2 + z(1) = CMPLX(x1, ZERO,DP) + z(2) = CMPLX(x2, ZERO,DP) + z(3) = CMPLX(x3, ZERO,DP) + RETURN + +! REAL AND COMPLEX ROOTS + +40 ra =CubeRoot(-HALF*d - SIGN(rq,d)) + rb = -c/(THREE*ra) + t = ra + rb + w = -p + x = -p + IF (ABS(t) <= tol*ABS(ra)) GO TO 41 + w = t - p + x = -HALF*t - p + IF (ABS(x) <= tol*ABS(p)) x = ZERO + 41 t = ABS(ra - rb) + y = HALF*rt3*t + + IF (t <= tol*ABS(ra)) GO TO 60 + IF (ABS(x) < ABS(y)) GO TO 50 + s = ABS(x) + t = y/x + GO TO 51 +50 s = ABS(y) + t = x/y +51 IF (s < 0.1D0*ABS(w)) GO TO 70 + w1 = w/s + sum = ONE + t*t + IF (w1*w1 < 0.01D0*sum) w = - ((r/sum)/s)/s + z(1) = CMPLX(w, ZERO,DP) + z(2) = CMPLX(x, y,DP) + z(3) = CMPLX(x,-y,DP) + RETURN + +! AT LEAST TWO ROOTS ARE EQUAL + +60 IF (ABS(x) < ABS(w)) GO TO 61 + IF (ABS(w) < 0.1D0*ABS(x)) w = - (r/x)/x + z(1) = CMPLX(w, ZERO,DP) + z(2) = CMPLX(x, ZERO,DP) + z(3) = z(2) + RETURN + 61 IF (ABS(x) < 0.1D0*ABS(w)) GO TO 70 + z(1) = CMPLX(x, ZERO,DP) + z(2) = z(1) + z(3) = CMPLX(w, ZERO,DP) + RETURN + +! HERE W IS MUCH LARGER IN MAGNITUDE THAN THE OTHER ROOTS. +! AS A RESULT, THE OTHER ROOTS MAY BE EXCEEDINGLY INACCURATE +! BECAUSE OF ROUNDOFF ERROR. TO DEAL WITH THIS, A QUADRATIC +! IS FORMED WHOSE ROOTS ARE THE SAME AS THE SMALLER ROOTS OF +! THE CUBIC. THIS QUADRATIC IS THEN SOLVED. + +! THIS CODE WAS WRITTEN BY WILLIAM L. DAVIS (NSWC). + +70 aq(1) = a(1) + aq(2) = a(2) + a(1)/w + aq(3) = -a(4)*w + CALL QuadraticRoots(aq, z) + z(3) = CMPLX(w, ZERO,DP) + + IF (AIMAG(z(1)) == ZERO) RETURN + z(3) = z(2) + z(2) = z(1) + z(1) = CMPLX(w, ZERO,DP) + RETURN +!----------------------------------------------------------------------- + + +! CASE WHEN D = 0 + +110 z(1) = CMPLX(-p, ZERO,DP) + w = SQRT(ABS(c)) + IF (c < ZERO) GO TO 120 + z(2) = CMPLX(-p, w,DP) + z(3) = CMPLX(-p,-w,DP) + RETURN + +120 IF (p /= ZERO) GO TO 130 + z(2) = CMPLX(w, ZERO,DP) + z(3) = CMPLX(-w, ZERO,DP) + RETURN + +130 x = -(p + SIGN(w,p)) + z(3) = CMPLX(x, ZERO,DP) + t = THREE*a(1)/(a(3)*x) + IF (ABS(p) > ABS(t)) GO TO 131 + z(2) = CMPLX(t, ZERO,DP) + RETURN +131 z(2) = z(1) + z(1) = CMPLX(t, ZERO,DP) + RETURN +END Subroutine CubicRoots ! ----------------------------------------------- + + +!+ +SUBROUTINE QuarticRoots(a,z) +!---------------------------------------------------------------------------- +! PURPOSE - Compute the roots of the real polynomial +! A(1) + A(2)*Z + ... + A(5)*Z**4 + + REAL(DP), INTENT(IN) :: a(:) + COMPLEX(DP), INTENT(OUT) :: z(:) + + COMPLEX(DP) :: w + REAL(DP):: b,b2, c, d, e, h, p, q, r, t + REAL(DP),DIMENSION(4):: temp + REAL(DP):: u, v, v1, v2, x, x1, x2, x3, y + + +! NOTE - It is assumed that a(5) is non-zero. No test is made here + +!---------------------------------------------------------------------------- + + IF (a(1)==0.0) THEN + z(1) = CZERO ! one root is obviously zero + CALL CubicRoots(a(2:), z(2:)) + RETURN + END IF + + + b = a(4)/(FOUR*a(5)) + c = a(3)/a(5) + d = a(2)/a(5) + e = a(1)/a(5) + b2 = b*b + + p = HALF*(c - 6.0D0*b2) + q = d - TWO*b*(c - FOUR*b2) + r = b2*(c - THREE*b2) - b*d + e + +! SOLVE THE RESOLVENT CUBIC EQUATION. THE CUBIC HAS AT LEAST ONE +! NONNEGATIVE REAL ROOT. IF W1, W2, W3 ARE THE ROOTS OF THE CUBIC +! THEN THE ROOTS OF THE ORIGINIAL EQUATION ARE +! Z = -B + CSQRT(W1) + CSQRT(W2) + CSQRT(W3) +! WHERE THE SIGNS OF THE SQUARE ROOTS ARE CHOSEN SO +! THAT CSQRT(W1) * CSQRT(W2) * CSQRT(W3) = -Q/8. + + temp(1) = -q*q/64.0D0 + temp(2) = 0.25D0*(p*p - r) + temp(3) = p + temp(4) = ONE + CALL CubicRoots(temp,z) + IF (AIMAG(z(2)) /= ZERO) GO TO 60 + +! THE RESOLVENT CUBIC HAS ONLY REAL ROOTS +! REORDER THE ROOTS IN INCREASING ORDER + + x1 = REAL(z(1),8) + x2 = REAL(z(2),8) + x3 = REAL(z(3),8) + IF (x1 > x2) CALL Swap(x1,x2) + IF (x2 > x3) CALL Swap(x2,x3) + IF (x1 > x2) CALL Swap(x1,x2) + + u = ZERO + IF (x3 > ZERO) u = SQRT(x3) + IF (x2 <= ZERO) GO TO 41 + IF (x1 >= ZERO) GO TO 30 + IF (ABS(x1) > x2) GO TO 40 + x1 = ZERO + +30 x1 = SQRT(x1) + x2 = SQRT(x2) + IF (q > ZERO) x1 = -x1 + temp(1) = (( x1 + x2) + u) - b + temp(2) = ((-x1 - x2) + u) - b + temp(3) = (( x1 - x2) - u) - b + temp(4) = ((-x1 + x2) - u) - b + CALL SelectSort(temp) + IF (ABS(temp(1)) >= 0.1D0*ABS(temp(4))) GO TO 31 + t = temp(2)*temp(3)*temp(4) + IF (t /= ZERO) temp(1) = e/t +31 z(1) = CMPLX(temp(1), ZERO,DP) + z(2) = CMPLX(temp(2), ZERO,DP) + z(3) = CMPLX(temp(3), ZERO,DP) + z(4) = CMPLX(temp(4), ZERO,DP) + RETURN + +40 v1 = SQRT(ABS(x1)) +v2 = ZERO +GO TO 50 +41 v1 = SQRT(ABS(x1)) +v2 = SQRT(ABS(x2)) +IF (q < ZERO) u = -u + +50 x = -u - b +y = v1 - v2 +z(1) = CMPLX(x, y,DP) +z(2) = CMPLX(x,-y,DP) +x = u - b +y = v1 + v2 +z(3) = CMPLX(x, y,DP) +z(4) = CMPLX(x,-y,DP) +RETURN + +! THE RESOLVENT CUBIC HAS COMPLEX ROOTS + +60 t = REAL(z(1),8) +x = ZERO +IF (t < ZERO) THEN + GO TO 61 +ELSE IF (t == ZERO) THEN + GO TO 70 +ELSE + GO TO 62 +END IF +61 h = ABS(REAL(z(2),8)) + ABS(AIMAG(z(2))) +IF (ABS(t) <= h) GO TO 70 +GO TO 80 +62 x = SQRT(t) +IF (q > ZERO) x = -x + +70 w = SQRT(z(2)) + u = TWO*REAL(w,8) + v = TWO*ABS(AIMAG(w)) + t = x - b + x1 = t + u + x2 = t - u + IF (ABS(x1) <= ABS(x2)) GO TO 71 + t = x1 + x1 = x2 + x2 = t +71 u = -x - b + h = u*u + v*v + IF (x1*x1 < 0.01D0*MIN(x2*x2,h)) x1 = e/(x2*h) + z(1) = CMPLX(x1, ZERO,DP) + z(2) = CMPLX(x2, ZERO,DP) + z(3) = CMPLX(u, v,DP) + z(4) = CMPLX(u,-v,DP) + RETURN + +80 v = SQRT(ABS(t)) + z(1) = CMPLX(-b, v,DP) + z(2) = CMPLX(-b,-v,DP) + z(3) = z(1) + z(4) = z(2) + RETURN + +END Subroutine QuarticRoots + +!+ +SUBROUTINE SelectSort(a) +! --------------------------------------------------------------------------- +! PURPOSE - Reorder the elements of in increasing order. + REAL(DP),INTENT(IN OUT),DIMENSION(:):: a + + INTEGER:: j + INTEGER,DIMENSION(1):: k +! NOTE - This is a n**2 method. It should only be used for small arrays. <25 +!---------------------------------------------------------------------------- + DO j=1,SIZE(a)-1 + k=MINLOC(a(j:)) + IF (j /= k(1)) CALL Swap(a(k(1)),a(j)) + END DO + RETURN +END Subroutine SelectSort ! ----------------------------------------------- + +!+ +SUBROUTINE SolvePolynomial(quarticCoeff, cubicCoeff, quadraticCoeff, & + linearCoeff, constantCoeff, code, root1,root2,root3,root4) +! --------------------------------------------------------------------------- + REAL(DP),INTENT(IN):: quarticCoeff + REAL(DP),INTENT(IN):: cubicCoeff, quadraticCoeff + REAL(DP),INTENT(IN):: linearCoeff, constantCoeff + INTEGER,INTENT(OUT):: code + COMPLEX(DP),INTENT(OUT):: root1,root2,root3,root4 + REAL(DP),DIMENSION(5):: a + COMPLEX(DP),DIMENSION(5):: z +!---------------------------------------------------------------------------- + a(1)=constantCoeff + a(2)=linearCoeff + a(3)=quadraticCoeff + a(4)=cubicCoeff + a(5)=quarticCoeff + + IF (quarticCoeff /= ZERO) THEN + CALL QuarticRoots(a,z) + ELSE IF (cubicCoeff /= ZERO) THEN + CALL CubicRoots(a,z) + ELSE IF (quadraticCoeff /= ZERO) THEN + CALL QuadraticRoots(a,z) + ELSE IF (linearCoeff /= ZERO) THEN + z(1)=CMPLX(-constantCoeff/linearCoeff, 0, DP) + outputCode=1 + ELSE + outputCode=0 ! { no roots } + END IF + + code=outputCode + IF (outputCode > 0) root1=z(1) + IF (outputCode > 1) root2=z(2) + IF (outputCode > 23) root3=z(3) + IF (outputCode > 99) root4=z(4) + RETURN +END Subroutine SolvePolynomial ! ------------------------------------------ + +!+ +SUBROUTINE SwapDouble(a,b) +! --------------------------------------------------------------------------- +! PURPOSE - Interchange the contents of a and b + REAL(DP),INTENT(IN OUT):: a,b + REAL(DP):: t +!---------------------------------------------------------------------------- + t=b + b=a + a=t + RETURN +END Subroutine SwapDouble ! ----------------------------------------------- + +!+ +SUBROUTINE SwapSingle(a,b) +! --------------------------------------------------------------------------- +! PURPOSE - Interchange the contents of a and b + REAL(SP),INTENT(IN OUT):: a,b + REAL(SP):: t +!---------------------------------------------------------------------------- + t=b + b=a + a=t + RETURN +END Subroutine SwapSingle ! ----------------------------------------------- + + +END Module PolynomialRoots ! ============================================== + + diff --git a/modules/nwtc-library/src/Polynomial/readme.txt b/modules/nwtc-library/src/Polynomial/readme.txt new file mode 100644 index 000000000..8798b4c11 --- /dev/null +++ b/modules/nwtc-library/src/Polynomial/readme.txt @@ -0,0 +1,63 @@ + + +ROOTS OF QUARTIC/CUBIC/QUADRATIC POLYNOMIALS /quartic/readme.txt + WITH REAL COEFFICIENTS + + +The files for this program are in the directory \quartic on the CD-ROM and in the +archive file quartic.zip that may be downloaded from the PDAS web site. + readme.txt this file of general description + quartic.f90 the complete source codetosh (Intel) + + +The reference documents for this program may be accessed +from the web page http://www.pdas.com/quarticrefs.html. + +2020-03-05 bjj: see http://www.pdas.com/quartic.html and http://www.pdas.com/quarticdownload.html + +To compile this program for your computer, use the command + gfortran quartic.f90 -o quartic.exe +Linux and Macintosh users may prefer to omit the .exe on the file name. + + +Many problems in science and engineering lead to polynomial equations +and the desired physical quantities must be found by solving for the +zeroes of the equation. Most books on Numerical Computing or Engineering +Mathematics show examples of code for making these calculations. +One must be careful with roundoff and overflow when making these +calculations and the textbook examples frequently do not incorporate +these "robustness" features. + +There is a collection of software from the U.S. Naval Surface Weapons +Center that has been widely distributed and checked for accuracy. +Among this collection is a very nice coding of the solution of zeroes +of polynomial equations with real coefficients up to quartic order. +I noted that Alan Miller of CSIRO had updated the code to comply with +modern Fortran, using the Essential Lahey Fortran 90 compiler, which +enforces very strict standards of program structure and syntax. +I have added a simple front-end that allows you to solve quartics as +a stand-alone program. Of course, you may want to extract the subroutine +for inclusion in your own code. + +This program computes the solution to the polynomial equation + a*x**4 + b*x**3 + c*x**2 + d*x + e = 0 +with real coefficients. + +The program asks for the coefficients of each term of the polynomial +to be solved. If you are solving a cubic, answer zero to the question +"What is the coefficient of the quartic term?" + +If you want to take the program apart to use in your own programs, you +can pick up each of the individual subroutines or go for the general +subroutine SolvePolynomial. It should be pretty obvious. If not, send +me mail and I will try to clear it up. + +The routine quartic.f90 has been checked and will compile properly with +either of the free Fortran compilers, gfortran or g95. + +There is a treasure house of wonderful Fortran code at Alan Miller's web site + at http://users.bigpond.net.au/amiller/ +There seems to be a problem with this web site, but there is a mirror site at + http://jblevins.org/mirror/amiller/ +that should work for now. + 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 3207dde39..40cdaee1b 100644 --- a/modules/nwtc-library/src/Registry_NWTC_Library_typedef_nomesh.txt +++ b/modules/nwtc-library/src/Registry_NWTC_Library_typedef_nomesh.txt @@ -28,8 +28,8 @@ typedef NWTC_Library FileInfoType IntKi NumLines typedef ^ ^ IntKi NumFiles typedef ^ ^ IntKi FileLine {:} typedef ^ ^ IntKi FileIndx {:} -typedef ^ ^ CHARACTER(1024) FileList {:} -typedef ^ ^ CHARACTER(1024) Lines {:} +typedef ^ ^ CHARACTER(MaxFileInfoLineLen) FileList {:} +typedef ^ ^ CHARACTER(MaxFileInfoLineLen) Lines {:} typedef NWTC_Library Quaternion ReKi q0 typedef ^ ^ ReKi v {3} diff --git a/modules/nwtc-library/src/SingPrec.f90 b/modules/nwtc-library/src/SingPrec.f90 index 3f98240cd..edcfcf174 100644 --- a/modules/nwtc-library/src/SingPrec.f90 +++ b/modules/nwtc-library/src/SingPrec.f90 @@ -21,10 +21,10 @@ !.................................................................................................................................. !> This module stores constants to specify the KIND of variables. !! -!! NOTE: When using preprocessor definition DOUBLE_PRECISION (which sets ReKi=R8Ki and DbKi=QuKi), you +!! NOTE: When using preprocessor definition DOUBLE_PRECISION (which sets ReKi=R8Ki), you !! may need to use a compile option to convert default reals to 8 bytes: \n -!! - Intel: /real_size:64 /double_size:128 -!! - Gnu: -fdefault-real-8 +!! - Intel: /real_size:64 +!! - Gnu: -fdefault-real-8 MODULE Precision !.................................................................................................................................. @@ -40,18 +40,15 @@ MODULE Precision INTEGER, PARAMETER :: B8Ki = SELECTED_INT_KIND( 18 ) !< Kind for eight-byte whole numbers #ifdef HAS_FORTRAN2008_FEATURES -INTEGER, PARAMETER :: QuKi = real128 !< Kind for 16-byte, floating-point numbers +INTEGER, PARAMETER :: R4Ki = real32 !< Kind for four-byte, floating-point numbers INTEGER, PARAMETER :: R8Ki = real64 !< Kind for eight-byte floating-point numbers -INTEGER, PARAMETER :: SiKi = real32 !< Kind for four-byte, floating-point numbers #else -INTEGER, PARAMETER :: QuKi = SELECTED_REAL_KIND( 20, 500 ) !< Kind for 16-byte, floating-point numbers +INTEGER, PARAMETER :: R4Ki = SELECTED_REAL_KIND( 6, 30 ) !< Kind for four-byte, floating-point numbers INTEGER, PARAMETER :: R8Ki = SELECTED_REAL_KIND( 14, 300 ) !< Kind for eight-byte floating-point numbers -INTEGER, PARAMETER :: SiKi = SELECTED_REAL_KIND( 6, 30 ) !< Kind for four-byte, floating-point numbers #endif -INTEGER, PARAMETER :: BYTES_IN_SiKi = 4 !< Number of bytes per SiKi number +INTEGER, PARAMETER :: BYTES_IN_R4Ki = 4 !< Number of bytes per R4Ki number INTEGER, PARAMETER :: BYTES_IN_R8Ki = 8 !< Number of bytes per R8Ki number -INTEGER, PARAMETER :: BYTES_IN_QuKi = 16 !< Number of bytes per QuKi number @@ -60,18 +57,18 @@ MODULE Precision INTEGER, PARAMETER :: IntKi = B4Ki !< Default kind for integers INTEGER, PARAMETER :: BYTES_IN_INT = 4 !< Number of bytes per IntKi number - use SIZEOF() -#if !defined (DOUBLE_PRECISION) && !defined (OPENFAST_DOUBLE_PRECISION) -INTEGER, PARAMETER :: ReKi = SiKi !< Default kind for floating-point numbers +INTEGER, PARAMETER :: SiKi = R4Ki !< Default kind for single floating-point numbers +INTEGER, PARAMETER :: BYTES_IN_SiKi = BYTES_IN_R4Ki !< Number of bytes per R4Ki number - use SIZEOF() + INTEGER, PARAMETER :: DbKi = R8Ki !< Default kind for double floating-point numbers - -INTEGER, PARAMETER :: BYTES_IN_REAL = BYTES_IN_SiKi !< Number of bytes per ReKi number - use SIZEOF() -INTEGER, PARAMETER :: BYTES_IN_DBL = BYTES_IN_R8Ki !< Number of bytes per DbKi number - use SIZEOF() -#else -INTEGER, PARAMETER :: ReKi = R8Ki !< Default kind for floating-point numbers -INTEGER, PARAMETER :: DbKi = QuKi !< Default kind for double floating-point numbers +INTEGER, PARAMETER :: BYTES_IN_DBL = BYTES_IN_R8Ki !< Number of bytes per R8Ki number - use SIZEOF() +#ifdef OPENFAST_DOUBLE_PRECISION +INTEGER, PARAMETER :: ReKi = R8Ki !< Default kind for floating-point numbers INTEGER, PARAMETER :: BYTES_IN_REAL = BYTES_IN_R8Ki !< Number of bytes per ReKi number - use SIZEOF() -INTEGER, PARAMETER :: BYTES_IN_DBL = BYTES_IN_QuKi !< Number of bytes per DbKi number - use SIZEOF() +#else +INTEGER, PARAMETER :: ReKi = R4Ki !< Default kind for floating-point numbers +INTEGER, PARAMETER :: BYTES_IN_REAL = BYTES_IN_R4Ki !< Number of bytes per ReKi number - use SIZEOF() #endif diff --git a/modules/nwtc-library/src/SysFlangLinux.f90 b/modules/nwtc-library/src/SysFlangLinux.f90 new file mode 100644 index 000000000..42f04c2d6 --- /dev/null +++ b/modules/nwtc-library/src/SysFlangLinux.f90 @@ -0,0 +1,461 @@ +!********************************************************************************************************************************** +! LICENSING +! Copyright (C) 2013 National Renewable Energy Laboratory +! +! This file is part of the NWTC Subroutine Library. +! +! Licensed under the Apache License, Version 2.0 (the "License"); +! you may not use this file except in compliance with the License. +! You may obtain a copy of the License at +! +! http://www.apache.org/licenses/LICENSE-2.0 +! +! Unless required by applicable law or agreed to in writing, software +! distributed under the License is distributed on an "AS IS" BASIS, +! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +! See the License for the specific language governing permissions and +! limitations under the License. +!********************************************************************************************************************************** +MODULE SysSubs + + ! This module contains routines with system-specific logic and references, including all references to the console unit, CU. + ! It also contains standard (but not system-specific) routines it uses. + ! SysGnuLinux.f90 is specifically for the GNU Fortran (gfortran) compiler on Linux and macOS. + ! It contains the following routines: + ! FUNCTION FileSize( Unit ) ! Returns the size (in bytes) of an open file. + ! FUNCTION Is_NaN( DblNum ) ! Please use IEEE_IS_NAN() instead + ! FUNCTION NWTC_ERF( x ) + ! FUNCTION NWTC_gamma( x ) ! Returns the gamma value of its argument. + ! SUBROUTINE FlushOut ( Unit ) + ! SUBROUTINE GET_CWD( DirName, Status ) + ! SUBROUTINE MKDIR( new_directory_path ) + ! SUBROUTINE OpenCon + ! SUBROUTINE OpenUnfInpBEFile ( Un, InFile, RecLen, Error ) + ! SUBROUTINE ProgExit ( StatCode ) + ! 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 ) + + USE NWTC_Base + + IMPLICIT NONE + + INTERFACE NWTC_ERF ! Returns the ERF value of its argument + MODULE PROCEDURE NWTC_ERFR4 + MODULE PROCEDURE NWTC_ERFR8 + END INTERFACE + + INTERFACE NWTC_gamma ! Returns the gamma value of its argument + MODULE PROCEDURE NWTC_gammaR4 + MODULE PROCEDURE NWTC_gammaR8 + END INTERFACE + + INTEGER, PARAMETER :: ConRecL = 120 ! The record length for console output. + INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. Unit 6 causes ADAMS to crash. + INTEGER, PARAMETER :: MaxWrScrLen = 98 ! The maximum number of characters allowed to be written to a line in WrScr + LOGICAL, PARAMETER :: KBInputOK = .TRUE. ! A flag to tell the program that keyboard input is allowed in the environment. + CHARACTER(*), PARAMETER :: NewLine = ACHAR(10) ! The delimiter for New Lines [ Windows is CHAR(13)//CHAR(10); MAC is CHAR(13); Unix is CHAR(10) {CHAR(13)=\r is a line feed, CHAR(10)=\n is a new line}] + CHARACTER(*), PARAMETER :: OS_Desc = 'GNU Fortran for Linux' ! Description of the language/OS + CHARACTER( 1), PARAMETER :: PathSep = '/' ! The path separator. + CHARACTER( 1), PARAMETER :: SwChar = '-' ! The switch character for command-line options. + CHARACTER(11), PARAMETER :: UnfForm = 'UNFORMATTED' ! The string to specify unformatted I/O files. + + #ifdef USE_DLL_INTERFACE + + INTEGER(C_INT), PARAMETER :: RTLD_LAZY=1 ! "Perform lazy binding. Only resolve symbols as the code that references them is executed. If the symbol is never referenced, then it is never resolved. (Lazy binding is only performed for function references; references to variables are always immediately bound when the library is loaded.) " + INTEGER(C_INT), PARAMETER :: RTLD_NOW=2 ! "If this value is specified, or the environment variable LD_BIND_NOW is set to a nonempty string, all undefined symbols in the library are resolved before dlopen() returns. If this cannot be done, an error is returned." + INTEGER(C_INT), PARAMETER :: RTLD_GLOBAL=256 ! "The symbols defined by this library will be made available for symbol resolution of subsequently loaded libraries" + INTEGER(C_INT), PARAMETER :: RTLD_LOCAL=0 ! "This is the converse of RTLD_GLOBAL, and the default if neither flag is specified. Symbols defined in this library are not made available to resolve references in subsequently loaded libraries." + + INTERFACE !linux API routines + !bjj see http://linux.die.net/man/3/dlopen + ! and https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/dlopen.3.html + + FUNCTION dlOpen(filename,mode) BIND(C,NAME="dlopen") + ! void *dlopen(const char *filename, int mode); + USE ISO_C_BINDING + IMPLICIT NONE + TYPE(C_PTR) :: dlOpen + CHARACTER(C_CHAR), INTENT(IN) :: filename(*) + INTEGER(C_INT), VALUE :: mode + END FUNCTION + + FUNCTION dlSym(handle,name) BIND(C,NAME="dlsym") + ! void *dlsym(void *handle, const char *name); + USE ISO_C_BINDING + IMPLICIT NONE + TYPE(C_FUNPTR) :: dlSym ! A function pointer + TYPE(C_PTR), VALUE :: handle + CHARACTER(C_CHAR), INTENT(IN) :: name(*) + END FUNCTION + + FUNCTION dlClose(handle) BIND(C,NAME="dlclose") + ! int dlclose(void *handle); + USE ISO_C_BINDING + IMPLICIT NONE + INTEGER(C_INT) :: dlClose + TYPE(C_PTR), VALUE :: handle + END FUNCTION + + END INTERFACE + + #endif + + CONTAINS + + + FUNCTION Is_NaN( DblNum ) + + ! This routine determines if a REAL(DbKi) variable holds a proper number. + ! BJJ: this routine is used in CRUNCH. + ! Note that IsNaN does not exist in earlier versions of gfortran (e.g., 4.2.1), + ! but does exist in version 4.4. It should be replaced with the standard + ! IEEE_IS_NAN when gfortran implements it. + + REAL(DbKi), INTENT(IN) :: DblNum + LOGICAL :: Is_Nan + + Is_NaN = IsNaN( DblNum ) + + END FUNCTION + !======================================================================= + FUNCTION NWTC_ERFR4( x ) + + ! Returns the ERF value of its argument. The result has a value equal + ! to the error function: 2/pi * integral_from_0_to_x of e^(-t^2) dt. + + REAL(SiKi), INTENT(IN) :: x ! input + REAL(SiKi) :: NWTC_ERFR4 ! result + + NWTC_ERFR4 = ERF( x ) + + END FUNCTION NWTC_ERFR4 + !======================================================================= + FUNCTION NWTC_ERFR8( x ) + + ! Returns the ERF value of its argument. The result has a value equal + ! to the error function: 2/pi * integral_from_0_to_x of e^(-t^2) dt. + + REAL(R8Ki), INTENT(IN) :: x ! input + REAL(R8Ki) :: NWTC_ERFR8 ! result + + NWTC_ERFR8 = ERF( x ) + + END FUNCTION NWTC_ERFR8 + !======================================================================= + FUNCTION NWTC_GammaR4( x ) + + ! Returns the gamma value of its argument. The result has a value equal + ! to a processor-dependent approximation to the gamma function of x. + + REAL(SiKi), INTENT(IN) :: x ! input + REAL(SiKi) :: NWTC_GammaR4 ! result + + NWTC_GammaR4 = gamma( x ) + + END FUNCTION NWTC_GammaR4 + !======================================================================= + FUNCTION NWTC_GammaR8( x ) + + ! Returns the gamma value of its argument. The result has a value equal + ! to a processor-dependent approximation to the gamma function of x. + + REAL(R8Ki), INTENT(IN) :: x ! input + REAL(R8Ki) :: NWTC_GammaR8 ! result + + NWTC_GammaR8 = gamma( x ) + + END FUNCTION NWTC_GammaR8 + + !======================================================================= + !bjj note: this subroutine is not tested for this compiler + SUBROUTINE Get_CWD ( DirName, Status ) + CHARACTER(1024) :: pwd + INTEGER :: length + CHARACTER(*), INTENT(OUT) :: DirName ! A CHARACTER string containing the path of the current working directory. + INTEGER, INTENT(OUT) :: Status ! Status returned by the call to a portability routine. + call get_environment_variable('PWD', DirName, length, Status) + END SUBROUTINE Get_CWD + !======================================================================= + SUBROUTINE MKDIR ( new_directory_path ) + + ! This routine creates a given directory if it does not exist. + + implicit none + + character(*), intent(in) :: new_directory_path + character(1024) :: make_command + logical :: directory_exists + + ! Check if the directory exists first + inquire( file=trim(new_directory_path), exist=directory_exists ) + + if ( .NOT. directory_exists ) then + make_command = 'mkdir -p '//trim(new_directory_path) + call system( make_command ) + endif + + END SUBROUTINE MKDIR + !======================================================================= + SUBROUTINE OpenCon + END SUBROUTINE OpenCon + !======================================================================= + SUBROUTINE OpenUnfInpBEFile ( Un, InFile, RecLen, Error ) + + ! This routine opens a binary input file. Data is stored in RecLen-byte records. + + IMPLICIT NONE + + INTEGER, INTENT(IN) :: Un ! Logical unit for the input file. + CHARACTER(*), INTENT(IN) :: InFile ! Name of the input file. + INTEGER, INTENT(IN) :: RecLen ! Size of records in the input file, in bytes. + LOGICAL, INTENT(OUT) :: Error ! Flag to indicate the open failed. + INTEGER :: IOS ! I/O status of OPEN. + + ! Open input file. Make sure it worked. + OPEN ( Un, FILE=TRIM( InFile ), STATUS='OLD', FORM='UNFORMATTED', & + ACCESS='DIRECT', RECL=RecLen, IOSTAT=IOS, ACTION='READ' ) + + IF ( IOS /= 0 ) THEN + Error = .TRUE. + ELSE + Error = .FALSE. + END IF + + END SUBROUTINE OpenUnfInpBEFile + !======================================================================= + SUBROUTINE ProgExit ( StatCode ) + + ! This routine stops the program. If the compiler supports the EXIT routine, + ! pass the program status to it. Otherwise, do a STOP. + + INTEGER, INTENT(IN) :: StatCode ! The status code to pass to the OS. + + CALL EXIT ( StatCode ) + + END SUBROUTINE + !======================================================================= + 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) F03 has standard intrinsic routines to do this, + ! but Gnu has not yet implemented it. This code will fail if + ! the compiler checks for floating-point-error, hence the + ! compiler directive FPE_TRAP_ENABLED. + + 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 + + ! 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. + ! note that anything that refers to NaN or Inf will be incorrect in that case. + + #ifndef FPE_TRAP_ENABLED + ! 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 + !======================================================================= + SUBROUTINE UsrAlarm + + ! This routine generates an alarm to warn the user that something went wrong. + CALL WrNR ( CHAR( 7 ) ) + + END SUBROUTINE UsrAlarm + !======================================================================= + SUBROUTINE WrNR ( Str ) + + ! This routine writes out a string to the screen without following it with a new line. + + CHARACTER(*), INTENT(IN) :: Str ! The string to write to the screen. + + WRITE (CU,'(A)',ADVANCE='NO') Str + + END SUBROUTINE WrNR ! ( Str ) + !======================================================================= + SUBROUTINE WrOver ( Str ) + + ! This routine writes out a string that overwrites the previous line. + + CHARACTER(*), INTENT(IN) :: Str ! The string to write to the screen. + INTEGER(IntKi) :: NChars ! Number of characters to write + CHARACTER(1), PARAMETER :: CR = ACHAR( 13 ) ! The carriage return character. + CHARACTER(25) :: Fmt = '(2A, (" "))' ! The format specifier for the output. + + NChars = MaxWrScrLen - LEN( Str ) + + IF ( NChars > 0 ) THEN + ! bjj: note that this will produce an error if NChars > 999 + WRITE (Fmt(5:7),'(I3)') NChars + WRITE (CU,Fmt,ADVANCE='NO') CR, Str + ELSE + ! bjj: note that this will almost certainly write more than MaxWrScrLen characters on a line + WRITE (CU,'(2A)',ADVANCE='NO') CR, Str + END IF + + END SUBROUTINE WrOver ! ( Str ) + !======================================================================= + SUBROUTINE WriteScr ( Str, Frm ) + + ! This routine writes out a string to the screen. + + IMPLICIT NONE + + CHARACTER(*), INTENT(IN) :: Str ! The input string to write to the screen. + CHARACTER(*), INTENT(IN) :: Frm ! Format specifier for the output. + INTEGER :: ErrStat ! Error status of write operation (so code doesn't crash) + + IF ( LEN_TRIM(Str) < 1 ) THEN + WRITE ( CU, '()', IOSTAT=ErrStat ) + ELSE + WRITE ( CU, Frm, IOSTAT=ErrStat ) TRIM(Str) + END IF + + IF ( ErrStat /= 0 ) THEN + print *, ' WriteScr produced an error. Please inform the programmer.' + ENDIF + + END SUBROUTINE WriteScr ! ( Str ) + !======================================================================= + SUBROUTINE LoadDynamicLib ( DLL, ErrStat, ErrMsg ) + + ! This SUBROUTINE is used to dynamically load a DLL. + + TYPE (DLL_Type), INTENT(INOUT) :: DLL ! The DLL to be loaded. + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + #ifdef USE_DLL_INTERFACE + + ErrStat = ErrID_None + ErrMsg = '' + + ! Load the DLL and get the file address: + + DLL%FileAddrX = dlOpen( TRIM(DLL%FileName)//C_NULL_CHAR, RTLD_LAZY ) !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%FileAddrX) ) THEN + ErrStat = ErrID_Fatal + WRITE(ErrMsg,'(I2)') BITS_IN_ADDR + ErrMsg = 'The dynamic library '//TRIM(DLL%FileName)//' could not be loaded. Check that the file '// & + 'exists in the specified location and that it is compiled for '//TRIM(ErrMsg)//'-bit applications.' + RETURN + END IF + + ! Get the procedure address: + + CALL LoadDynamicLibProc ( DLL, ErrStat, ErrMsg ) + #else + + ErrStat = ErrID_Fatal + ErrMsg = ' LoadDynamicLib: Not compiled with -DUSE_DLL_INTERFACE for '//TRIM(OS_Desc) + + #endif + + END SUBROUTINE LoadDynamicLib + !======================================================================= + SUBROUTINE LoadDynamicLibProc ( DLL, ErrStat, ErrMsg ) + + ! This SUBROUTINE is used to dynamically load a procedure from a DLL. + + TYPE (DLL_Type), INTENT(INOUT) :: DLL ! The DLL to be loaded. + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + INTEGER(IntKi) :: i + + #ifdef USE_DLL_INTERFACE + + ErrStat = ErrID_None + ErrMsg = '' + + do i=1,NWTC_MAX_DLL_PROC + if ( len_trim( DLL%ProcName(i) ) > 0 ) then + + 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 + i - 1 + ErrMsg = 'The procedure '//TRIM(DLL%ProcName(i))//' in file '//TRIM(DLL%FileName)//' could not be loaded.' + RETURN + END IF + + end if + end do + + #else + + ErrStat = ErrID_Fatal + ErrMsg = ' LoadDynamicLibProc: Not compiled with -DUSE_DLL_INTERFACE for '//TRIM(OS_Desc) + + #endif + + END SUBROUTINE LoadDynamicLibProc + !======================================================================= + SUBROUTINE FreeDynamicLib ( DLL, ErrStat, ErrMsg ) + + ! This SUBROUTINE is used to free a dynamically loaded DLL (loaded in LoadDynamicLib). + + TYPE (DLL_Type), INTENT(INOUT) :: DLL ! The DLL to be freed. + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + INTEGER(C_INT) :: Success ! Whether or not the call to dlClose was successful + INTEGER(C_INT), PARAMETER :: TRUE = 0 + + #ifdef USE_DLL_INTERFACE + + ! Close the library: + + IF( .NOT. C_ASSOCIATED(DLL%FileAddrX) ) RETURN + Success = dlClose( DLL%FileAddrX ) !The function dlclose() returns 0 on success, and nonzero on error. + + IF ( Success /= TRUE ) THEN !bjj: note that this is not the same as LOGICAL .TRUE. + ErrStat = ErrID_Fatal + ErrMsg = 'The dynamic library could not be freed.' + RETURN + ELSE + ErrStat = ErrID_None + ErrMsg = '' + DLL%FileAddrX = C_NULL_PTR + END IF + + #else + + ErrStat = ErrID_Fatal + ErrMsg = ' FreeDynamicLib: Not compiled with -DUSE_DLL_INTERFACE for '//TRIM(OS_Desc) + + #endif + + END SUBROUTINE FreeDynamicLib + !======================================================================= + END MODULE SysSubs + \ No newline at end of file diff --git a/modules/nwtc-library/src/SysGnuLinux.f90 b/modules/nwtc-library/src/SysGnuLinux.f90 index 8f3eeb9bc..d45d88b3c 100644 --- a/modules/nwtc-library/src/SysGnuLinux.f90 +++ b/modules/nwtc-library/src/SysGnuLinux.f90 @@ -47,18 +47,16 @@ MODULE SysSubs INTERFACE NWTC_ERF ! Returns the ERF value of its argument MODULE PROCEDURE NWTC_ERFR4 MODULE PROCEDURE NWTC_ERFR8 - MODULE PROCEDURE NWTC_ERFR16 END INTERFACE INTERFACE NWTC_gamma ! Returns the gamma value of its argument ! note: gamma is part of the F08 standard, but may not be implemented everywhere... MODULE PROCEDURE NWTC_gammaR4 MODULE PROCEDURE NWTC_gammaR8 - MODULE PROCEDURE NWTC_gammaR16 END INTERFACE INTEGER, PARAMETER :: ConRecL = 120 ! The record length for console output. - INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. Unit 6 causes ADAMS to crash. + INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. INTEGER, PARAMETER :: MaxWrScrLen = 98 ! The maximum number of characters allowed to be written to a line in WrScr LOGICAL, PARAMETER :: KBInputOK = .TRUE. ! A flag to tell the program that keyboard input is allowed in the environment. CHARACTER(*), PARAMETER :: NewLine = ACHAR(10) ! The delimiter for New Lines [ Windows is CHAR(13)//CHAR(10); MAC is CHAR(13); Unix is CHAR(10) {CHAR(13)=\r is a line feed, CHAR(10)=\n is a new line}] @@ -131,18 +129,6 @@ FUNCTION NWTC_ERFR8( x ) END FUNCTION NWTC_ERFR8 !======================================================================= -FUNCTION NWTC_ERFR16( x ) - - ! Returns the ERF value of its argument. The result has a value equal - ! to the error function: 2/pi * integral_from_0_to_x of e^(-t^2) dt. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_ERFR16 ! result - - NWTC_ERFR16 = ERF( x ) - -END FUNCTION NWTC_ERFR16 -!======================================================================= FUNCTION NWTC_GammaR4( x ) ! Returns the gamma value of its argument. The result has a value equal @@ -167,18 +153,6 @@ FUNCTION NWTC_GammaR8( x ) END FUNCTION NWTC_GammaR8 !======================================================================= -FUNCTION NWTC_GammaR16( x ) - - ! Returns the gamma value of its argument. The result has a value equal - ! to a processor-dependent approximation to the gamma function of x. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_GammaR16 ! result - - NWTC_GammaR16 = gamma( x ) - -END FUNCTION NWTC_GammaR16 -!======================================================================= SUBROUTINE FlushOut ( Unit ) ! This subroutine flushes the buffer on the specified Unit. @@ -541,6 +515,9 @@ FUNCTION dlClose(handle) BIND(C,NAME="dlclose") END INTERFACE + ErrStat = ErrID_None + ErrMsg = '' + ! Close the library: IF( .NOT. C_ASSOCIATED(DLL%FileAddrX) ) RETURN diff --git a/modules/nwtc-library/src/SysGnuWin.f90 b/modules/nwtc-library/src/SysGnuWin.f90 index f761a2e72..0905792bb 100644 --- a/modules/nwtc-library/src/SysGnuWin.f90 +++ b/modules/nwtc-library/src/SysGnuWin.f90 @@ -47,18 +47,16 @@ MODULE SysSubs INTERFACE NWTC_ERF ! Returns the ERF value of its argument MODULE PROCEDURE NWTC_ERFR4 MODULE PROCEDURE NWTC_ERFR8 - MODULE PROCEDURE NWTC_ERFR16 END INTERFACE INTERFACE NWTC_gamma ! Returns the gamma value of its argument ! note: gamma is part of the F08 standard, but may not be implemented everywhere... MODULE PROCEDURE NWTC_gammaR4 MODULE PROCEDURE NWTC_gammaR8 - MODULE PROCEDURE NWTC_gammaR16 END INTERFACE INTEGER, PARAMETER :: ConRecL = 120 ! The record length for console output. - INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. Unit 6 causes ADAMS to crash. + INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. INTEGER, PARAMETER :: MaxWrScrLen = 98 ! The maximum number of characters allowed to be written to a line in WrScr LOGICAL, PARAMETER :: KBInputOK = .TRUE. ! A flag to tell the program that keyboard input is allowed in the environment. CHARACTER(*), PARAMETER :: NewLine = ACHAR(10) ! The delimiter for New Lines [ Windows is CHAR(13)//CHAR(10); MAC is CHAR(13); Unix is CHAR(10) {CHAR(13)=\r is a line feed, CHAR(10)=\n is a new line}] @@ -131,18 +129,6 @@ FUNCTION NWTC_ERFR8( x ) END FUNCTION NWTC_ERFR8 !======================================================================= -FUNCTION NWTC_ERFR16( x ) - - ! Returns the ERF value of its argument. The result has a value equal - ! to the error function: 2/pi * integral_from_0_to_x of e^(-t^2) dt. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_ERFR16 ! result - - NWTC_ERFR16 = ERF( x ) - -END FUNCTION NWTC_ERFR16 -!======================================================================= FUNCTION NWTC_GammaR4( x ) ! Returns the gamma value of its argument. The result has a value equal @@ -167,18 +153,6 @@ FUNCTION NWTC_GammaR8( x ) END FUNCTION NWTC_GammaR8 !======================================================================= -FUNCTION NWTC_GammaR16( x ) - - ! Returns the gamma value of its argument. The result has a value equal - ! to a processor-dependent approximation to the gamma function of x. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_GammaR16 ! result - - NWTC_GammaR16 = gamma( x ) - -END FUNCTION NWTC_GammaR16 -!======================================================================= SUBROUTINE FlushOut ( Unit ) ! This subroutine flushes the buffer on the specified Unit. @@ -517,6 +491,9 @@ FUNCTION FreeLibrary(hLibModule) BIND(C, NAME='FreeLibrary') END INTERFACE + ErrStat = ErrID_None + ErrMsg = '' + ! Free the DLL: IF ( DLL%FileAddr == INT(0,C_INTPTR_T) ) RETURN diff --git a/modules/nwtc-library/src/SysIFL.f90 b/modules/nwtc-library/src/SysIFL.f90 index a3746afde..c6c439e89 100644 --- a/modules/nwtc-library/src/SysIFL.f90 +++ b/modules/nwtc-library/src/SysIFL.f90 @@ -47,18 +47,16 @@ MODULE SysSubs INTERFACE NWTC_ERF ! Returns the ERF value of its argument MODULE PROCEDURE NWTC_ERFR4 MODULE PROCEDURE NWTC_ERFR8 - MODULE PROCEDURE NWTC_ERFR16 END INTERFACE INTERFACE NWTC_gamma ! Returns the gamma value of its argument ! note: gamma is part of the F08 standard, but may not be implemented everywhere... MODULE PROCEDURE NWTC_gammaR4 MODULE PROCEDURE NWTC_gammaR8 - MODULE PROCEDURE NWTC_gammaR16 END INTERFACE INTEGER, PARAMETER :: ConRecL = 120 ! The record length for console output. - INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. Unit 6 causes ADAMS to crash. + INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. INTEGER, PARAMETER :: MaxWrScrLen = 98 ! The maximum number of characters allowed to be written to a line in WrScr LOGICAL, PARAMETER :: KBInputOK = .TRUE. ! A flag to tell the program that keyboard input is allowed in the environment. CHARACTER(*), PARAMETER :: NewLine = ACHAR(10) ! The delimiter for New Lines [ Windows is CHAR(13)//CHAR(10); MAC is CHAR(13); Unix is CHAR(10) {CHAR(13)=\r is a line feed, CHAR(10)=\n is a new line}] @@ -134,18 +132,6 @@ FUNCTION NWTC_ERFR8( x ) END FUNCTION NWTC_ERFR8 !======================================================================= -FUNCTION NWTC_ERFR16( x ) - - ! Returns the ERF value of its argument. The result has a value equal - ! to the error function: 2/pi * integral_from_0_to_x of e^(-t^2) dt. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_ERFR16 ! result - - NWTC_ERFR16 = ERF( x ) - -END FUNCTION NWTC_ERFR16 -!======================================================================= FUNCTION NWTC_GammaR4( x ) ! Returns the gamma value of its argument. The result has a value equal @@ -170,18 +156,6 @@ FUNCTION NWTC_GammaR8( x ) END FUNCTION NWTC_GammaR8 !======================================================================= -FUNCTION NWTC_GammaR16( x ) - - ! Returns the gamma value of its argument. The result has a value equal - ! to a processor-dependent approximation to the gamma function of x. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_GammaR16 ! result - - NWTC_GammaR16 = gamma( x ) - -END FUNCTION NWTC_GammaR16 -!======================================================================= SUBROUTINE FlushOut ( Unit ) ! This subroutine flushes the buffer on the specified Unit. @@ -518,6 +492,9 @@ FUNCTION dlClose(handle) BIND(C,NAME="dlclose") END FUNCTION END INTERFACE + + ErrStat = ErrID_None + ErrMsg = '' ! Close the library: diff --git a/modules/nwtc-library/src/SysIVF.f90 b/modules/nwtc-library/src/SysIVF.f90 index 0e99442cd..603ad6da7 100644 --- a/modules/nwtc-library/src/SysIVF.f90 +++ b/modules/nwtc-library/src/SysIVF.f90 @@ -47,21 +47,19 @@ MODULE SysSubs INTERFACE NWTC_ERF ! Returns the ERF value of its argument MODULE PROCEDURE NWTC_ERFR4 MODULE PROCEDURE NWTC_ERFR8 - MODULE PROCEDURE NWTC_ERFR16 END INTERFACE INTERFACE NWTC_gamma ! Returns the gamma value of its argument ! note: gamma is part of the F08 standard, but may not be implemented everywhere... MODULE PROCEDURE NWTC_gammaR4 MODULE PROCEDURE NWTC_gammaR8 - MODULE PROCEDURE NWTC_gammaR16 END INTERFACE INTEGER, PARAMETER :: ConRecL = 120 ! The record length for console output. - INTEGER, PARAMETER :: CU = 7 ! The I/O unit for the console. Unit 6 causes ADAMS to crash. + INTEGER, PARAMETER :: CU = 7 ! The I/O unit for the console. INTEGER, PARAMETER :: MaxWrScrLen = 98 ! The maximum number of characters allowed to be written to a line in WrScr LOGICAL, PARAMETER :: KBInputOK = .TRUE. ! A flag to tell the program that keyboard input is allowed in the environment. - CHARACTER(*), PARAMETER :: NewLine = ACHAR(10) ! The delimiter for New Lines [ Windows is CHAR(13)//CHAR(10); MAC is CHAR(13); Unix is CHAR(10) {CHAR(13)=\r is a line feed, CHAR(10)=\n is a new line}] + CHARACTER(*), PARAMETER :: NewLine = ACHAR(10) ! The delimiter for New Lines [ Windows is CHAR(13)//CHAR(10); MAC is CHAR(13); Unix is CHAR(10) {CHAR(13)=\r is a line feed, CHAR(10)=\n is a new line}]; Note: NewLine change to ACHAR(10) here on Windows to fix issues with C/Fortran interoperability using WrScr CHARACTER(*), PARAMETER :: OS_Desc = 'Intel Visual Fortran for Windows'! Description of the language/OS CHARACTER( 1), PARAMETER :: PathSep = '\' ! The path separator. CHARACTER( 1), PARAMETER :: SwChar = '/' ! The switch character for command-line options. @@ -137,19 +135,6 @@ FUNCTION NWTC_ERFR8( x ) END FUNCTION NWTC_ERFR8 !======================================================================= -!> \copydoc syssubs::nwtc_erfr4 -FUNCTION NWTC_ERFR16( x ) - - ! Returns the ERF value of its argument. The result has a value equal - ! to the error function: 2/pi * integral_from_0_to_x of e^(-t^2) dt. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_ERFR16 ! result - - NWTC_ERFR16 = ERF( x ) - -END FUNCTION NWTC_ERFR16 -!======================================================================= !> Returns the gamma value of its argument. The result has a value equal !! to a processor-dependent approximation to the gamma function of x: !! \f{equation}{ @@ -177,16 +162,6 @@ FUNCTION NWTC_GammaR8( x ) END FUNCTION NWTC_GammaR8 !======================================================================= -!> \copydoc syssubs::nwtc_gammar4 -FUNCTION NWTC_GammaR16( x ) - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_GammaR16 ! result - - NWTC_GammaR16 = gamma( x ) - -END FUNCTION NWTC_GammaR16 -!======================================================================= !> This subroutine flushes the buffer on the specified Unit. !! It is especially useful when printing "running..." type messages. SUBROUTINE FlushOut ( Unit ) @@ -452,7 +427,10 @@ SUBROUTINE FreeDynamicLib ( DLL, ErrStat, ErrMsg ) CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None INTEGER(HANDLE) :: FileAddr ! The address of file FileName. (RETURN value from LoadLibrary in kernel32.f90) INTEGER(BOOL) :: Success ! Whether or not the call to FreeLibrary was successful - + + ErrStat = ErrID_None + ErrMsg = '' + IF ( DLL%FileAddr == INT(0,C_INTPTR_T) ) RETURN FileAddr = TRANSFER(DLL%FileAddr, FileAddr) !convert INTEGER(C_INTPTR_T) to INTEGER(HANDLE) [used only for compatibility with gfortran] diff --git a/modules/nwtc-library/src/SysIVF_Labview.f90 b/modules/nwtc-library/src/SysIVF_Labview.f90 index 40b1600e9..529ed52f3 100644 --- a/modules/nwtc-library/src/SysIVF_Labview.f90 +++ b/modules/nwtc-library/src/SysIVF_Labview.f90 @@ -60,13 +60,11 @@ MODULE SysSubs INTERFACE NWTC_gamma ! Returns the gamma value of its argument MODULE PROCEDURE NWTC_gammaR4 MODULE PROCEDURE NWTC_gammaR8 - MODULE PROCEDURE NWTC_gammaR16 END INTERFACE INTERFACE NWTC_ERF ! Returns the ERF value of its argument MODULE PROCEDURE NWTC_ERFR4 MODULE PROCEDURE NWTC_ERFR8 - MODULE PROCEDURE NWTC_ERFR16 END INTERFACE @@ -75,7 +73,7 @@ MODULE SysSubs INTEGER, PARAMETER :: ConRecL = 120 ! The record length for console output. - INTEGER, PARAMETER :: CU = 7 ! The I/O unit for the console. Unit 6 causes ADAMS to crash. + INTEGER, PARAMETER :: CU = 7 ! The I/O unit for the console. INTEGER, PARAMETER :: MaxWrScrLen = 98 ! The maximum number of characters allowed to be written to a line in WrScr LOGICAL, PARAMETER :: KBInputOK = .FALSE. ! A flag to tell the program that keyboard input is allowed in the environment. @@ -217,19 +215,6 @@ FUNCTION NWTC_ERFR8( x ) NWTC_ERFR8 = ERF( x ) END FUNCTION NWTC_ERFR8 -!======================================================================= - FUNCTION NWTC_ERFR16( x ) - - ! Returns the ERF value of its argument. The result has a value equal - ! to the error function: 2/pi * integral_from_0_to_x of e^(-t^2) dt. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_ERFR16 ! result - - - NWTC_ERFR16 = ERF( x ) - - END FUNCTION NWTC_ERFR16 !======================================================================= FUNCTION NWTC_GammaR4( x ) @@ -256,19 +241,6 @@ FUNCTION NWTC_GammaR8( x ) NWTC_GammaR8 = gamma( x ) END FUNCTION NWTC_GammaR8 -!======================================================================= - FUNCTION NWTC_GammaR16( x ) - - ! Returns the gamma value of its argument. The result has a value equal - ! to a processor-dependent approximation to the gamma function of x. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_GammaR16 ! result - - - NWTC_GammaR16 = gamma( x ) - - END FUNCTION NWTC_GammaR16 !======================================================================= SUBROUTINE OpenCon diff --git a/modules/nwtc-library/src/SysMatlabLinuxGnu.f90 b/modules/nwtc-library/src/SysMatlabLinuxGnu.f90 index f948f6cd3..d69f22743 100644 --- a/modules/nwtc-library/src/SysMatlabLinuxGnu.f90 +++ b/modules/nwtc-library/src/SysMatlabLinuxGnu.f90 @@ -50,18 +50,16 @@ MODULE SysSubs INTERFACE NWTC_ERF ! Returns the ERF value of its argument MODULE PROCEDURE NWTC_ERFR4 MODULE PROCEDURE NWTC_ERFR8 - MODULE PROCEDURE NWTC_ERFR16 END INTERFACE INTERFACE NWTC_gamma ! Returns the gamma value of its argument ! note: gamma is part of the F08 standard, but may not be implemented everywhere... MODULE PROCEDURE NWTC_gammaR4 MODULE PROCEDURE NWTC_gammaR8 - MODULE PROCEDURE NWTC_gammaR16 END INTERFACE INTEGER, PARAMETER :: ConRecL = 120 ! The record length for console output. - INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. Unit 6 causes ADAMS to crash. + INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. INTEGER, PARAMETER :: MaxWrScrLen = 98 ! The maximum number of characters allowed to be written to a line in WrScr LOGICAL, PARAMETER :: KBInputOK = .FALSE. ! A flag to tell the program that keyboard input is allowed in the environment. CHARACTER(*), PARAMETER :: NewLine = ACHAR(10) ! The delimiter for New Lines [ Windows is CHAR(13)//CHAR(10); MAC is CHAR(13); Unix is CHAR(10) {CHAR(13)=\r is a line feed, CHAR(10)=\n is a new line}] @@ -134,18 +132,6 @@ FUNCTION NWTC_ERFR8( x ) END FUNCTION NWTC_ERFR8 !======================================================================= -FUNCTION NWTC_ERFR16( x ) - - ! Returns the ERF value of its argument. The result has a value equal - ! to the error function: 2/pi * integral_from_0_to_x of e^(-t^2) dt. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_ERFR16 ! result - - NWTC_ERFR16 = ERF( x ) - -END FUNCTION NWTC_ERFR16 -!======================================================================= FUNCTION NWTC_GammaR4( x ) ! Returns the gamma value of its argument. The result has a value equal @@ -170,18 +156,6 @@ FUNCTION NWTC_GammaR8( x ) END FUNCTION NWTC_GammaR8 !======================================================================= -FUNCTION NWTC_GammaR16( x ) - - ! Returns the gamma value of its argument. The result has a value equal - ! to a processor-dependent approximation to the gamma function of x. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_GammaR16 ! result - - NWTC_GammaR16 = gamma( x ) - -END FUNCTION NWTC_GammaR16 -!======================================================================= SUBROUTINE FlushOut ( Unit ) ! This subroutine flushes the buffer on the specified Unit. @@ -538,6 +512,9 @@ FUNCTION dlClose(handle) BIND(C,NAME="dlclose") END INTERFACE + ErrStat = ErrID_None + ErrMsg = '' + ! Close the library: IF( .NOT. C_ASSOCIATED(DLL%FileAddrX) ) RETURN diff --git a/modules/nwtc-library/src/SysMatlabLinuxIntel.f90 b/modules/nwtc-library/src/SysMatlabLinuxIntel.f90 index 6935a9ffa..c521e449f 100644 --- a/modules/nwtc-library/src/SysMatlabLinuxIntel.f90 +++ b/modules/nwtc-library/src/SysMatlabLinuxIntel.f90 @@ -50,18 +50,16 @@ MODULE SysSubs INTERFACE NWTC_ERF ! Returns the ERF value of its argument MODULE PROCEDURE NWTC_ERFR4 MODULE PROCEDURE NWTC_ERFR8 - MODULE PROCEDURE NWTC_ERFR16 END INTERFACE INTERFACE NWTC_gamma ! Returns the gamma value of its argument ! note: gamma is part of the F08 standard, but may not be implemented everywhere... MODULE PROCEDURE NWTC_gammaR4 MODULE PROCEDURE NWTC_gammaR8 - MODULE PROCEDURE NWTC_gammaR16 END INTERFACE INTEGER, PARAMETER :: ConRecL = 120 ! The record length for console output. - INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. Unit 6 causes ADAMS to crash. + INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. INTEGER, PARAMETER :: MaxWrScrLen = 98 ! The maximum number of characters allowed to be written to a line in WrScr LOGICAL, PARAMETER :: KBInputOK = .FALSE. ! A flag to tell the program that keyboard input is allowed in the environment. CHARACTER(*), PARAMETER :: NewLine = ACHAR(10) ! The delimiter for New Lines [ Windows is CHAR(13)//CHAR(10); MAC is CHAR(13); Unix is CHAR(10) {CHAR(13)=\r is a line feed, CHAR(10)=\n is a new line}] @@ -137,18 +135,6 @@ FUNCTION NWTC_ERFR8( x ) END FUNCTION NWTC_ERFR8 !======================================================================= -FUNCTION NWTC_ERFR16( x ) - - ! Returns the ERF value of its argument. The result has a value equal - ! to the error function: 2/pi * integral_from_0_to_x of e^(-t^2) dt. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_ERFR16 ! result - - NWTC_ERFR16 = ERF( x ) - -END FUNCTION NWTC_ERFR16 -!======================================================================= FUNCTION NWTC_GammaR4( x ) ! Returns the gamma value of its argument. The result has a value equal @@ -173,18 +159,6 @@ FUNCTION NWTC_GammaR8( x ) END FUNCTION NWTC_GammaR8 !======================================================================= -FUNCTION NWTC_GammaR16( x ) - - ! Returns the gamma value of its argument. The result has a value equal - ! to a processor-dependent approximation to the gamma function of x. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_GammaR16 ! result - - NWTC_GammaR16 = gamma( x ) - -END FUNCTION NWTC_GammaR16 -!======================================================================= SUBROUTINE FlushOut ( Unit ) ! This subroutine flushes the buffer on the specified Unit. @@ -529,6 +503,9 @@ FUNCTION dlClose(handle) BIND(C,NAME="dlclose") END INTERFACE + ErrStat = ErrID_None + ErrMsg = '' + ! Close the library: IF( .NOT. C_ASSOCIATED(DLL%FileAddrX) ) RETURN diff --git a/modules/nwtc-library/src/SysMatlabWindows.f90 b/modules/nwtc-library/src/SysMatlabWindows.f90 index 004a72ef3..ff266e9b1 100644 --- a/modules/nwtc-library/src/SysMatlabWindows.f90 +++ b/modules/nwtc-library/src/SysMatlabWindows.f90 @@ -36,26 +36,24 @@ MODULE SysSubs INTERFACE NWTC_ERF ! Returns the ERF value of its argument MODULE PROCEDURE NWTC_ERFR4 MODULE PROCEDURE NWTC_ERFR8 - MODULE PROCEDURE NWTC_ERFR16 END INTERFACE INTERFACE NWTC_gamma ! Returns the gamma value of its argument ! note: gamma is part of the F08 standard, but may not be implemented everywhere... MODULE PROCEDURE NWTC_gammaR4 MODULE PROCEDURE NWTC_gammaR8 - MODULE PROCEDURE NWTC_gammaR16 END INTERFACE !======================================================================= INTEGER, PARAMETER :: ConRecL = 120 ! The record length for console output. - INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. Unit 6 causes ADAMS to crash. + INTEGER, PARAMETER :: CU = 6 ! The I/O unit for the console. INTEGER, PARAMETER :: MaxWrScrLen = 98 ! The maximum number of characters allowed to be written to a line in WrScr LOGICAL, PARAMETER :: KBInputOK = .FALSE. ! A flag to tell the program that keyboard input is allowed in the environment. - CHARACTER(*), PARAMETER :: NewLine = ACHAR(10) ! The delimiter for New Lines [ Windows is CHAR(13)//CHAR(10); MAC is CHAR(13); Unix is CHAR(10) {CHAR(13)=\r is a line feed, CHAR(10)=\n is a new line}] + CHARACTER(*), PARAMETER :: NewLine = ACHAR(10) ! The delimiter for New Lines [ Windows is CHAR(13)//CHAR(10); MAC is CHAR(13); Unix is CHAR(10) {CHAR(13)=\r is a line feed, CHAR(10)=\n is a new line}]; Note: NewLine change to ACHAR(10) here on Windows to fix issues with C/Fortran interoperability using WrScr CHARACTER(*), PARAMETER :: OS_Desc = 'Intel Visual Fortran for Windows/Matlab' ! Description of the language/OS CHARACTER( 1), PARAMETER :: PathSep = '\' ! The path separator. CHARACTER( 1), PARAMETER :: SwChar = '/' ! The switch character for command-line options. @@ -175,19 +173,6 @@ FUNCTION NWTC_ERFR8( x ) END FUNCTION NWTC_ERFR8 !======================================================================= -!> \copydoc syssubs::nwtc_erfr4 -FUNCTION NWTC_ERFR16( x ) - - ! Returns the ERF value of its argument. The result has a value equal - ! to the error function: 2/pi * integral_from_0_to_x of e^(-t^2) dt. - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_ERFR16 ! result - - NWTC_ERFR16 = ERF( x ) - -END FUNCTION NWTC_ERFR16 -!======================================================================= !> Returns the gamma value of its argument. The result has a value equal !! to a processor-dependent approximation to the gamma function of x: !! \f{equation}{ @@ -215,16 +200,6 @@ FUNCTION NWTC_GammaR8( x ) END FUNCTION NWTC_GammaR8 !======================================================================= -!> \copydoc syssubs::nwtc_gammar4 -FUNCTION NWTC_GammaR16( x ) - - REAL(QuKi), INTENT(IN) :: x ! input - REAL(QuKi) :: NWTC_GammaR16 ! result - - NWTC_GammaR16 = gamma( x ) - -END FUNCTION NWTC_GammaR16 -!======================================================================= !> This routine creates a given directory if it does not already exist. SUBROUTINE MKDIR ( new_directory_path ) @@ -504,6 +479,9 @@ SUBROUTINE FreeDynamicLib ( DLL, ErrStat, ErrMsg ) INTEGER(HANDLE) :: FileAddr ! The address of file FileName. (RETURN value from LoadLibrary in kernel32.f90) INTEGER(BOOL) :: Success ! Whether or not the call to FreeLibrary was successful + ErrStat = ErrID_None + ErrMsg = '' + IF ( DLL%FileAddr == INT(0,C_INTPTR_T) ) RETURN FileAddr = TRANSFER(DLL%FileAddr, FileAddr) !convert INTEGER(C_INTPTR_T) to INTEGER(HANDLE) [used only for compatibility with gfortran] diff --git a/modules/nwtc-library/src/VTK.f90 b/modules/nwtc-library/src/VTK.f90 new file mode 100644 index 000000000..d70345dec --- /dev/null +++ b/modules/nwtc-library/src/VTK.f90 @@ -0,0 +1,972 @@ +!> Tools to read/write VTK files, for both +! - VTK ASCII format (vtk_* routines, and the vtk_misc type) +! - VTK ASCII format for structure points (SP) +! - VTK XML format (header and footer, the rest is found in ModMesh for now) +module VTK + + use Precision, only: IntKi, SiKi, ReKi + use NWTC_Base, only: ErrID_None, ErrID_Fatal, AbortErrLev, ErrMsgLen + use NWTC_IO, only: GetNewUnit, NewLine, WrScr, ReadStr, OpenFOutFile + use NWTC_IO, only: OpenFinpFile, ReadCom, Conv2UC + use NWTC_IO, only: SetErrStat + + implicit none + + character(8), parameter :: RFMT='E17.8E3' + character(8), parameter :: IFMT='I7' + + ! Internal type to ensure the same options are used in between calls for the functions vtk_* + TYPE, PUBLIC :: VTK_Misc + integer :: vtk_unit + logical :: bFileOpen=.false. + + integer :: nData=0; + integer :: nPoints=0; + + logical :: bBinary = .false. + character(len=255) :: buffer + + ! Reference Frame + real(ReKi),dimension(3,3) :: T_g2b + real(ReKi),dimension(3) :: PO_g + END TYPE VTK_Misc + + interface vtk_dataset_structured_grid; module procedure & + vtk_dataset_structured_grid_flat, & + vtk_dataset_structured_grid_grid + end interface + + interface vtk_point_data_vector; module procedure & + vtk_point_data_vector_flat, & + vtk_point_data_vector_grid2D,& + vtk_point_data_vector_grid + end interface + interface vtk_point_data_scalar; module procedure & + vtk_point_data_scalar_flat, & + vtk_point_data_scalar_2D, & + vtk_point_data_scalar_grid2D, & + vtk_point_data_scalar_grid + end interface + interface vtk_cell_data_scalar; module procedure & + vtk_cell_data_scalar_1d,& + vtk_cell_data_scalar_2d + end interface + + private + + ! --- VTK ASCII routines + public :: vtk_misc_init + public :: set_vtk_binary_format + public :: set_vtk_coordinate_transform + public :: vtk_new_ascii_file + public :: vtk_close_file + public :: vtk_dataset_polydata + public :: vtk_lines + public :: vtk_quad + public :: vtk_dataset_rectilinear + public :: vtk_dataset_structured_points + public :: vtk_dataset_structured_grid + public :: vtk_point_data_init + public :: vtk_point_data_scalar + public :: vtk_point_data_vector + public :: vtk_cell_data_init + public :: vtk_cell_data_scalar + public :: vtk_cell_data_vector + public :: WrVTK_SP_header + public :: WrVTK_SP_vectors3D + public :: ReadVTK_SP_info + public :: ReadVTK_SP_vectors + ! --- VTK XML routines + public :: WrVTK_header + public :: WrVTK_footer +contains + +!======================================================================= +!> This routine writes out the heading for an vtk xml file (associated footer generated in +!! nwtc_io::wrvtk_footer). It tries to open a text file for writing and returns the Unit number of the opened file. + SUBROUTINE WrVTK_header( FileName, NumberOfPoints, NumberOfLines, NumberOfPolys, Un, ErrStat, ErrMsg ) + + CHARACTER(*) , INTENT(IN ) :: FileName !< Name of output file + INTEGER(IntKi) , INTENT(IN ) :: NumberOfPoints !< Number of points in this VTK file + INTEGER(IntKi) , INTENT(IN ) :: NumberOfLines !< Number of lines in this VTK file + INTEGER(IntKi) , INTENT(IN ) :: NumberOfPolys !< Number of polygons in this VTK file + INTEGER(IntKi) , INTENT( OUT) :: Un !< unit number of opened file + INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< error level/status of OpenFOutFile operation + CHARACTER(*) , INTENT( OUT) :: ErrMsg !< message when error occurs + + CALL GetNewUnit( Un, ErrStat, ErrMsg ) + CALL OpenFOutFile ( Un, TRIM(FileName), ErrStat, ErrMsg ) + if (ErrStat >= AbortErrLev) return + + ! Write a VTP mesh file (Polygonal VTK file) with positions and polygons (surfaces) + ! (note alignment of WRITE statements to make sure spaces are lined up in XML file) + WRITE(Un,'(A)') '' + WRITE(Un,'(A)') '' ! bjj note: we don't have binary data in this file, so byte_order shouldn't matter, right? + WRITE(Un,'(A)') ' ' + WRITE(Un,'(2(A,i7),A)') ' ' + + RETURN + END SUBROUTINE WrVTK_header +!======================================================================= +!> This routine writes out the footer for an vtk xml file (associated header generated +!! in nwtc_io::wrvtk_header). It closes the file Un. + SUBROUTINE WrVTK_footer( Un ) + + INTEGER(IntKi) , INTENT(IN ) :: Un !< unit number of opened file + + WRITE(Un,'(A)') ' ' + WRITE(Un,'(A)') ' ' + WRITE(Un,'(A)') '' + CLOSE(Un) + + RETURN + END SUBROUTINE WrVTK_footer + +!======================================================================= +!> This routine reads the header for a vtk, ascii, structured_points dataset file, +!! including all the information about the structured points. It tries to open a +!! text file for reading and returns the Unit number of the opened file. +!! The caller is responsible for closing the file unit unless caller set Un = -1! + SUBROUTINE ReadVTK_SP_info( FileName, descr, dims, origin, gridSpacing, vecLabel, Un, ErrStat, ErrMsg ) + + CHARACTER(*) , INTENT(IN ) :: FileName !< Name of output file + CHARACTER(1024) , INTENT( OUT) :: descr !< Line describing the contents of the file + INTEGER(IntKi) , INTENT( OUT) :: dims(3) !< dimension of the 3D grid (nX,nY,nZ) + REAL(ReKi) , INTENT( OUT) :: origin(3) !< the lower-left corner of the 3D grid (X0,Y0,Z0) + REAL(ReKi) , INTENT( OUT) :: gridSpacing(3) !< spacing between grid points in each of the 3 directions (dX,dY,dZ) + CHARACTER(1024) , INTENT( OUT) :: vecLabel + INTEGER(IntKi) , INTENT(INOUT) :: Un !< unit number of opened file + INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< error level/status of OpenFOutFile operation + CHARACTER(*) , INTENT( OUT) :: ErrMsg !< message when error occurs + + INTEGER(IntKi) :: ErrStat2 ! local error level/status of OpenFOutFile operation + CHARACTER(ErrMsgLen) :: ErrMsg2 ! local message when error occurs + CHARACTER(1024) :: Dummy1, Dummy2 + CHARACTER(1024) :: Line ! one line of the file + CHARACTER(1024) :: formatLbl + CHARACTER(*), PARAMETER :: RoutineName = 'ReadVTK_SP_info' + INTEGER(IntKi) :: sz, nPts, nArr, nums(2) + LOGICAL :: closeOnReturn + + ErrStat = ErrID_None + ErrMsg = '' + + IF (Un == -1 ) THEN + closeOnReturn = .TRUE. + ELSE + closeOnReturn = .FALSE. + END IF + + CALL GetNewUnit( Un, ErrStat, ErrMsg ) + CALL OpenFInpFile ( Un, TRIM(FileName), ErrStat, ErrMsg ) + if (ErrStat >= AbortErrLev) return + + CALL ReadCom( Un, FileName, 'File header: Module Version (line 1)', ErrStat2, ErrMsg2, 0 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL ReadStr( Un, FileName, descr, 'descr', 'File Description line', ErrStat2, ErrMsg2, 0 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + formatLbl = "" + CALL ReadStr( Un, FileName, formatLbl, 'formatLbl', 'ASCII label', ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call Conv2UC(formatLbl) + if (INDEX(formatLbl, "ASCII" ) /= 1 ) THEN ! If this line doesn't contain the word ASCII, we have a bad file header + CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find ASCII label', ErrStat, ErrMsg, RoutineName ) + end if + Line = "" + CALL ReadStr( Un, FileName, Line, "dataset", "DATASET STRUCTURED_POINTS", ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + CALL Conv2UC( Line ) + IF ( INDEX(Line, "DATASET" ) /= 1 ) THEN ! If this line doesn't contain the word dataset, we have a bad file header + CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find DATASET label', ErrStat, ErrMsg, RoutineName ) + END IF + IF ( INDEX(Line, "STRUCTURED_POINTS" ) == 0 ) THEN ! If this line doesn't also contain the word structured_points, we have a bad file header + CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find STRUCTURED_POINTS label', ErrStat, ErrMsg, RoutineName ) + end if + + ! Dimensions + Line = "" + CALL ReadStr( Un, FileName, Line, "Dimensions", "DIMENSIONS data", ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + Line = trim(Line) + CALL Conv2UC( Line ) + IF ( INDEX(Line, "DIMENSIONS" ) /= 1 ) THEN ! If this line doesn't contain the word dataset, we have a bad file header + CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find DIMENSIONS label', ErrStat, ErrMsg, RoutineName ) + ELSE + sz = len(Line) + Line = Line(12:sz) + READ(Line,*, IOSTAT=ErrStat2) dims + if (ErrStat2 /= 0) then + CALL SetErrStat( ErrID_Fatal, 'Error reading "dims".', ErrStat, ErrMsg, RoutineName ) + end if + END IF + + ! Origin + Line = "" + CALL ReadStr( Un, FileName, Line, "Origin", "ORIGIN data", ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + Line = trim(Line) + CALL Conv2UC( Line ) + IF ( INDEX(Line, "ORIGIN" ) /= 1 ) THEN ! If this line doesn't contain the word dataset, we have a bad file header + CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find ORIGIN label', ErrStat, ErrMsg, RoutineName ) + ELSE + sz = len(Line) + Line = Line(8:sz) + READ(Line,*, IOSTAT=ErrStat2) origin + if (ErrStat2 /= 0) then + CALL SetErrStat( ErrID_Fatal, 'Error reading "origin".', ErrStat, ErrMsg, RoutineName ) + end if + + END IF + + ! Spacing + Line = "" + CALL ReadStr( Un, FileName, Line, "gridSpacing", "SPACING data", ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + Line = trim(Line) + CALL Conv2UC( Line ) + IF ( INDEX(Line, "SPACING" ) /= 1 ) THEN ! If this line doesn't contain the word dataset, we have a bad file header + CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find SPACING label', ErrStat, ErrMsg, RoutineName ) + ELSE + sz = len(Line) + Line = Line(9:sz) + READ(Line,*,IOSTAT=ErrStat2) gridSpacing + if (ErrStat2 /= 0) then + CALL SetErrStat( ErrID_Fatal, 'Error reading "gridSpacing".', ErrStat, ErrMsg, RoutineName ) + end if + + END IF + + ! Point Data + Line = "" + CALL ReadStr( Un, FileName, Line, "Point_Data", "POINT_DATA", ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + Line = trim(Line) + CALL Conv2UC( Line ) + IF ( INDEX(Line, "POINT_DATA" ) /= 1 ) THEN ! If this line doesn't contain the word dataset, we have a bad file header + CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find POINT_DATA label', ErrStat, ErrMsg, RoutineName ) + ELSE + sz = len(Line) + Line = Line(12:sz) + READ(Line,*,IOSTAT=ErrStat2) nPts + if (ErrStat2 /= 0) then + CALL SetErrStat( ErrID_Fatal, 'Error reading "nPts".', ErrStat, ErrMsg, RoutineName ) + end if + IF ( nPts /= ( dims(1)*dims(2)*dims(3) ) ) THEN ! Abort if DIMENSIONS AND POINT_DATA don't agree + CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: POINT_DATA does not match DIMENSIONS', ErrStat, ErrMsg, RoutineName ) + END IF + END IF + + ! VECTOR or FIELD Label + Line = "" + CALL ReadStr( Un, FileName, Line, "VECTORS or FIELD", "VECTORS or FIELD label", ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + Line = trim(Line) + CALL Conv2UC( Line ) + IF ( ( INDEX(Line, "VECTORS" ) /= 1 ) .AND. ( INDEX(Line, "FIELD" ) /= 1 ) ) THEN + CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: did not find VECTORS or FIELD label', ErrStat, ErrMsg, RoutineName ) + ELSE + IF ( INDEX(Line, "FIELD" ) == 1 ) THEN ! Must be FIELD + READ(Line,*,IOSTAT=ErrStat2) Dummy1, Dummy2, nArr + if (ErrStat2 /= 0) then + CALL SetErrStat( ErrID_Fatal, 'Error reading "nArr".', ErrStat, ErrMsg, RoutineName ) + ELSE IF ( nArr /= 1_IntKi ) THEN + CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: FIELD label must have only 1 array', ErrStat, ErrMsg, RoutineName ) + END IF + + Line = "" + CALL ReadStr( Un, FileName, Line, "Array", "Array definition", ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + Line = trim(Line) + Call Conv2UC( Line ) + sz = INDEX(Line, "FLOAT" ) + IF ( sz == 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Invalid FIELD datatype. Must be set to float.', ErrStat, ErrMsg, RoutineName ) + ELSE + READ(Line,*,IOSTAT=ErrStat2) Dummy1, nums + if (ErrStat2 /= 0) then + CALL SetErrStat( ErrID_Fatal, 'Error reading "nums".', ErrStat, ErrMsg, RoutineName ) + ELSEIF ( nums(1) /= 3_IntKi ) THEN ! Abort if we don't have 3-element vectors + CALL SetErrStat( ErrID_Fatal, 'Invalid FIELD datatype. FIELD array must have 3 elements.', ErrStat, ErrMsg, RoutineName ) + ELSEIF ( nums(2) /= ( dims(1)*dims(2)*dims(3) ) ) THEN ! Abort if DIMENSIONS AND FIELD data don't agree + CALL SetErrStat( ErrID_Fatal, 'Invalid vtk structured_points file: FIELD array does not match DIMENSIONS', ErrStat, ErrMsg, RoutineName ) + END IF + END IF + ELSE ! Must be VECTORS + sz = INDEX(Line, "FLOAT" ) + IF ( sz == 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Invalid VECTORS datatype. Must be set to float.', ErrStat, ErrMsg, RoutineName ) + ELSE + vecLabel = Line(9:sz-2) + END IF + END IF + END IF + + IF ( (ErrStat >= AbortErrLev) .or. closeOnReturn ) THEN + close(Un) + Un = -1 + RETURN + END IF + + RETURN + END SUBROUTINE ReadVTK_SP_info + +!======================================================================= +!> This routine reads the vector data for a vtk, ascii, structured_points dataset file, +!! The Unit number of the file is already assumed to be valid via a previous call to +!! ReadVTK_SP_info. + SUBROUTINE ReadVTK_SP_vectors( FileName, Un, dims, gridVals, ErrStat, ErrMsg ) + + CHARACTER(*) , INTENT(IN ) :: FileName !< Name of output file + INTEGER(IntKi) , INTENT(IN ) :: Un !< unit number of opened file + INTEGER(IntKi) , INTENT(IN ) :: dims(3) !< dimension of the 3D grid (nX,nY,nZ) + REAL(SiKi) , INTENT( OUT) :: gridVals(:,:,:,:) !< 4D array of data, size (3,nX,nY,nZ), must be pre-allocated + INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< error level/status of OpenFOutFile operation + CHARACTER(*) , INTENT( OUT) :: ErrMsg !< message when error occurs + + INTEGER :: ErrStat2 + + ErrStat = ErrID_None + ErrMsg = '' + + READ(Un,*, IOSTAT=ErrStat2) gridVals(1:3,1:dims(1),1:dims(2),1:dims(3)) + + close(Un) + if (ErrStat2 /= 0) then + CALL SetErrStat( ErrID_Fatal, 'Invalid vtk file: '//trim(FileName)//'.', ErrStat, ErrMsg, 'ReadVTK_SP_vectors' ) + end if + + END SUBROUTINE ReadVTK_SP_vectors + +!======================================================================= +!> This routine writes out the heading for an vtk, ascii, structured_points dataset file . +!! It tries to open a text file for writing and returns the Unit number of the opened file. + SUBROUTINE WrVTK_SP_header( FileName, descr, Un, ErrStat, ErrMsg ) + + CHARACTER(*) , INTENT(IN ) :: FileName !< Name of output file + CHARACTER(*) , INTENT(IN ) :: descr !< Line describing the contents of the file + INTEGER(IntKi) , INTENT( OUT) :: Un !< unit number of opened file + INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< error level/status of OpenFOutFile operation + CHARACTER(*) , INTENT( OUT) :: ErrMsg !< message when error occurs + + CALL GetNewUnit( Un, ErrStat, ErrMsg ) + CALL OpenFOutFile ( Un, TRIM(FileName), ErrStat, ErrMsg ) + if (ErrStat >= AbortErrLev) return + + WRITE(Un,'(A)') '# vtk DataFile Version 3.0' + WRITE(Un,'(A)') trim(descr) + WRITE(Un,'(A)') 'ASCII' + WRITE(Un,'(A)') 'DATASET STRUCTURED_POINTS' + + RETURN + END SUBROUTINE WrVTK_SP_header + + + SUBROUTINE WrVTK_SP_vectors3D( Un, dataDescr, dims, origin, gridSpacing, gridVals, ErrStat, ErrMsg ) + + INTEGER(IntKi) , INTENT(IN ) :: Un !< unit number of previously opened file (via call to WrVTK_SP_header) + CHARACTER(*) , INTENT(IN ) :: dataDescr !< Short label describing the vector data + INTEGER(IntKi) , INTENT(IN ) :: dims(3) !< dimension of the 3D grid (nX,nY,nZ) + REAL(ReKi) , INTENT(IN ) :: origin(3) !< the lower-left corner of the 3D grid (X0,Y0,Z0) + REAL(ReKi) , INTENT(IN ) :: gridSpacing(3) !< spacing between grid points in each of the 3 directions (dX,dY,dZ) + REAL(SiKi) , INTENT(IN ) :: gridVals(:,:,:,:) !< 3D array of data, size (nX,nY,nZ) + INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< error level/status of OpenFOutFile operation + CHARACTER(*) , INTENT( OUT) :: ErrMsg !< message when error occurs + + INTEGER(IntKi) :: nPts ! Total number of grid points + + if ( .not. (Un > 0) ) then + ErrStat = ErrID_Fatal + ErrMsg = 'WrVTK_SP_points: Invalid file unit, be sure to call WrVTK_SP_header prior to calling WrVTK_SP_points.' + return + end if + + ErrStat = ErrID_None + ErrMsg = '' + nPts = dims(1)*dims(2)*dims(3) + + ! Note: gridVals must be stored such that the left-most dimension is X and the right-most dimension is Z + WRITE(Un,'(A,3(i5,1X))') 'DIMENSIONS ', dims + WRITE(Un,'(A,3(f10.2,1X))') 'ORIGIN ' , origin + WRITE(Un,'(A,3(f10.2,1X))') 'SPACING ' , gridSpacing + WRITE(Un,'(A,i15)') 'POINT_DATA ', nPts + WRITE(Un,'(A)') 'VECTORS '//trim(dataDescr)//' float' + WRITE(Un,'(3(f10.2,1X))') gridVals + close(Un) + RETURN + + END SUBROUTINE WrVTK_SP_vectors3D + + subroutine vtk_misc_init(mvtk) + type(VTK_Misc),intent(inout) :: mvtk + mvtk%vtk_unit = -1 !< VTK output unit [-] + mvtk%bFileOpen = .false. !< binary file is open [-] + mvtk%bBinary = .false. !< write binary files [-] + mvtk%nData = 0 !< number of data lines [-] + mvtk%nPoints = 0 !< number of points [-] + end subroutine + + !> + subroutine set_vtk_binary_format(bBin,mvtk) + logical, intent(in)::bBin + type(VTK_Misc),intent(inout) :: mvtk + mvtk%bBinary=bBin + end subroutine + + + !> Save a coordinate transform + ! ALL VTK Will be exported in this coordinate system! + subroutine set_vtk_coordinate_transform(T_g2b_in,PO_g_in,mvtk) + real(ReKi),dimension(3,3), intent(in) :: T_g2b_in + real(ReKi),dimension(3) , intent(in) :: PO_g_in + type(VTK_Misc),intent(inout) :: mvtk + mvtk%T_g2b=T_g2b_in + mvtk%PO_g=PO_g_in + end subroutine + + logical function vtk_new_ascii_file(filename,label,mvtk) + !use MainIO, only: get_free_unit ,check_io + !use MainIOData, only: bSTOP_ALLOWED + !use FileSystem, only: file_exists + !use Logging, only: log_warning,log_error,log_info + ! + character(len=*),intent(in) :: filename + character(len=*),intent(in) :: label + type(VTK_Misc),intent(inout) :: mvtk + ! + integer :: iostatvar + logical :: b + + if (.not. mvtk%bFileOpen) then + CALL GetNewUnit( mvtk%vtk_unit ) + if (mvtk%bBinary) then + ! Fortran 2003 stream, otherwise intel fortran ! + !form='UNFORMATTED',access='SEQUENTIAL',action='WRITE',convert='BIG_ENDIAN',recordtype='STREAM',buffered='YES', + !print*,'Not available for this compiler' !COMPAQ-COMPILER + !STOP !COMPAQ-COMPILER +!bjj: CONVERT is non-standard, so maybe this should be part of Sys*.f90? Like OpenUnfInpBEFile()? +!eb : Commented out for now since it doesnt work anymore anyway (worked 5 years ago..). Adding binary would be great though! + !open(unit = mvtk%vtk_unit,file= trim(adjustl(filename)),form='UNFORMATTED',access = 'stream',& !OTHER-COMPILER + ! action = 'WRITE',convert= 'BIG_ENDIAN',iostat=iostatvar,status='replace') !OTHER-COMPILER + call WrScr('Binary VTK output not available at the moment') + STOP ! Temporary, but easiest for now. + else + open(mvtk%vtk_unit,file=trim(adjustl(filename)),iostat=iostatvar,action="write",status='replace') + endif + if (iostatvar == 0) then + if (mvtk%bBinary) then + write(mvtk%vtk_unit)'# vtk DataFile Version 3.0'//NewLine + write(mvtk%vtk_unit)trim(label)//NewLine + write(mvtk%vtk_unit)'BINARY'//NewLine + else + write(mvtk%vtk_unit,'(a)') '# vtk DataFile Version 2.0' + write(mvtk%vtk_unit,'(a)') trim(label) + write(mvtk%vtk_unit,'(a)') 'ASCII' + write(mvtk%vtk_unit,'(a)') ' ' + endif + + mvtk%bFileOpen=.true. + mvtk%nData=-1; + endif + else + b=.false. + !call log_error('VTK: Cannot open two vtk files at the same time, call vtk_close first') + endif + if (iostatvar ==0) then + vtk_new_ascii_file=.true. + else + vtk_new_ascii_file=.false. + endif + end function + + subroutine vtk_close_file(mvtk) + type(VTK_Misc),intent(inout) :: mvtk + if ( mvtk%bFileOpen ) then + close(mvtk%vtk_unit) + mvtk%bFileOpen=.false. + endif + endsubroutine + + + ! ------------------------------------------------------------------------- + ! --- POLYDATA STUFF + ! ------------------------------------------------------------------------- + subroutine vtk_dataset_polydata(Points,mvtk,bladeFrame) + real(ReKi), dimension(:,:),intent(in) :: Points !< 3 x n + type(VTK_Misc),intent(inout) :: mvtk + logical, intent(in) :: bladeFrame + integer :: i + if ( mvtk%bFileOpen ) then + mvtk%nPoints=size(Points,2) + if (mvtk%bBinary) then + write(mvtk%vtk_unit)'DATASET POLYDATA'//NewLine + write(mvtk%buffer,'(A,I0,A)') 'POINTS ', mvtk%nPoints ,' double' + write(mvtk%vtk_unit)trim(mvtk%buffer)//NewLine + if (bladeFrame) then + do i=1,mvtk%nPoints + write(mvtk%vtk_unit)matmul(mvtk%T_g2b,Points(1:3,i)-mvtk%PO_g) + enddo + else + do i=1,mvtk%nPoints + write(mvtk%vtk_unit)Points(1:3,i) + enddo + endif + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A)') 'DATASET POLYDATA' + write(mvtk%vtk_unit,'(A,I0,A)') 'POINTS ', mvtk%nPoints ,' double' + if (bladeFrame) then + do i=1,mvtk%nPoints + write(mvtk%vtk_unit,'(3'//RFMT//')') matmul(mvtk%T_g2b,Points(1:3,i)-mvtk%PO_g) + enddo + else + do i=1,mvtk%nPoints + write(mvtk%vtk_unit,'(3'//RFMT//')') Points(1:3,i) + enddo + endif + write(mvtk%vtk_unit,*) ' ' + endif + endif + end subroutine + + + subroutine vtk_lines(L,mvtk) + integer, dimension(:,:),intent(in) :: L !< 2 x n + type(VTK_Misc),intent(inout) :: mvtk + + integer :: i + + if ( mvtk%bFileOpen ) then + mvtk%nData=size(L,2) + if (mvtk%bBinary) then + write(mvtk%buffer,'(A,I0,A,I0)')'LINES ',mvtk%nData,' ',3*mvtk%nData + write(mvtk%vtk_unit)trim(mvtk%buffer)//NewLine + do i=1,mvtk%nData + write(mvtk%vtk_unit)2,L(1:2,i) + enddo + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A,I0,A,I0)')'LINES ',mvtk%nData,' ',3*mvtk%nData + do i=1,mvtk%nData + write(mvtk%vtk_unit,'(3'//IFMT//')') 2, L(1:2,i) + enddo + write(mvtk%vtk_unit,*) ' ' + endif + endif + end subroutine + + subroutine vtk_quad(Q,mvtk) + integer, dimension(:,:),intent(in) :: Q !< 4 x n + type(VTK_Misc),intent(inout) :: mvtk + integer :: i + if ( mvtk%bFileOpen ) then + mvtk%nData=size(Q,2) + if (mvtk%bBinary) then + write(mvtk%buffer,'(A,I0,A,I0)')'POLYGONS ',mvtk%nData,' ',5*mvtk%nData + write(mvtk%vtk_unit)trim(mvtk%buffer)//NewLine + do i=1,mvtk%nData + write(mvtk%vtk_unit)4,Q(1:4,i) + enddo + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A,I0,A,I0)') 'POLYGONS ', mvtk%nData,' ',5*mvtk%nData + do i=1,mvtk%nData + write(mvtk%vtk_unit,'(5'//IFMT//')') 4, Q(1:4,i) + enddo + write(mvtk%vtk_unit,*) ' ' + endif + endif + end subroutine + + ! ------------------------------------------------------------------------- + ! --- RECTILINEAR + ! ------------------------------------------------------------------------- + subroutine vtk_dataset_rectilinear(v1,v2,v3,mvtk) + real(ReKi), dimension(:),intent(in) :: v1,v2,v3 !< n + type(VTK_Misc),intent(inout) :: mvtk + + if ( mvtk%bFileOpen ) then + mvtk%nPoints=size(v1)*size(v2)*size(v3) + if (mvtk%bBinary) then + write(mvtk%vtk_unit) 'DATASET RECTILINEAR_GRID'//NewLine + write(mvtk%buffer,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', size(v1),' ',size(v2),' ',size(v3) + write(mvtk%vtk_unit) trim(mvtk%buffer)//NewLine + write(mvtk%buffer,'(A,I0,A)') 'X_COORDINATES ', size(v1), ' double' + write(mvtk%vtk_unit) trim(mvtk%buffer)//NewLine + write(mvtk%vtk_unit)v1 + write(mvtk%vtk_unit)NewLine + write(mvtk%buffer,'(A,I0,A)') 'Y_COORDINATES ', size(v2), ' double' + write(mvtk%vtk_unit) trim(mvtk%buffer)//NewLine + write(mvtk%vtk_unit)v2 + write(mvtk%vtk_unit)NewLine + write(mvtk%buffer,'(A,I0,A)') 'Z_COORDINATES ', size(v3), ' double' + write(mvtk%vtk_unit) trim(mvtk%buffer)//NewLine + write(mvtk%vtk_unit)v3 + !write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A)') 'DATASET RECTILINEAR_GRID' + write(mvtk%vtk_unit,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', size(v1),' ',size(v2),' ',size(v3) + write(mvtk%vtk_unit,'(A,I0,A)') 'X_COORDINATES ', size(v1), ' double' + write(mvtk%vtk_unit,'('//RFMT//')') v1 + write(mvtk%vtk_unit,'(A,I0,A)') 'Y_COORDINATES ', size(v2), ' double' + write(mvtk%vtk_unit,'('//RFMT//')') v2 + write(mvtk%vtk_unit,'(A,I0,A)') 'Z_COORDINATES ', size(v3), ' double' + write(mvtk%vtk_unit,'('//RFMT//')') v3 + write(mvtk%vtk_unit,*) ' ' + endif + endif + end subroutine + + subroutine vtk_dataset_structured_points(x0,dx,n,mvtk) + real(ReKi), dimension(3), intent(in) :: x0 !< origin + real(ReKi), dimension(3), intent(in) :: dx !< spacing + integer, dimension(3), intent(in) :: n !< length + type(VTK_Misc),intent(inout) :: mvtk + + if ( mvtk%bFileOpen ) then + mvtk%nPoints=n(1)*n(2)*n(3) + if (mvtk%bBinary) then + write(mvtk%vtk_unit) 'DATASET STRUCTURED_POINTS'//NewLine + write(mvtk%buffer,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ',n(1),' ',n(2),' ',n(3) + write(mvtk%vtk_unit) trim(mvtk%buffer)//NewLine + write(mvtk%buffer,'(A,3F16.8)') 'ORIGIN ', x0 + write(mvtk%vtk_unit) trim(mvtk%buffer)//NewLine + write(mvtk%buffer,'(A,3F16.8)') 'SPACING ', dx + write(mvtk%vtk_unit) trim(mvtk%buffer)//NewLine + else + write(mvtk%vtk_unit,'(A)') 'DATASET STRUCTURED_POINTS' + write(mvtk%vtk_unit,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', n(1),' ',n(2),' ',n(3) + write(mvtk%vtk_unit,'(A,3F16.8,A)') 'ORIGIN ',x0 + write(mvtk%vtk_unit,'(A,3F16.8,A)') 'SPACING ',dx + endif + endif + end subroutine + + + ! ------------------------------------------------------------------------- + ! --- STRUCTURED GRID (Points dumped without for loop since memory is in proper order) + ! ------------------------------------------------------------------------- + !> Subroutine using flat data as input (not in natural order) + subroutine vtk_dataset_structured_grid_flat(D,n1,n2,n3,mvtk) + integer , intent(in) :: n1,n2,n3 + real(ReKi), dimension(:,:),intent(in)::D + type(VTK_Misc),intent(inout) :: mvtk + if ( mvtk%bFileOpen ) then + mvtk%nPoints=n1*n2*n3 + if (mvtk%bBinary) then + write(mvtk%vtk_unit) 'DATASET STRUCTURED_GRID'//NewLine + write(mvtk%buffer,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', n1,' ',n2,' ',n3 + write(mvtk%vtk_unit) trim(mvtk%buffer)//NewLine + write(mvtk%buffer,'(A,I0,A)') 'POINTS ', mvtk%nPoints, ' double' + write(mvtk%vtk_unit) trim(mvtk%buffer)//NewLine + write(mvtk%vtk_unit)D + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A)') 'DATASET STRUCTURED_GRID' + write(mvtk%vtk_unit,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', n1,' ',n2,' ',n3 + write(mvtk%vtk_unit,'(A,I0,A)') 'POINTS ', mvtk%nPoints, ' double' + write(mvtk%vtk_unit,'(3'//RFMT//')')D + write(mvtk%vtk_unit,*) ' ' + endif + endif + end subroutine + + !> Using Grid data 4d as input + subroutine vtk_dataset_structured_grid_grid(D,n1,n2,n3,mvtk) + integer , intent(in) :: n1,n2,n3 + real(ReKi), dimension(:,:,:,:),intent(in)::D + type(VTK_Misc),intent(inout) :: mvtk + + if ( mvtk%bFileOpen ) then + mvtk%nPoints=n1*n2*n3 + if (mvtk%bBinary) then + write(mvtk%vtk_unit) 'DATASET STRUCTURED_GRID'//NewLine + write(mvtk%buffer,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', n1,' ',n2,' ',n3 + write(mvtk%vtk_unit) trim(mvtk%buffer)//NewLine + write(mvtk%buffer,'(A,I0,A)') 'POINTS ', mvtk%nPoints, ' double' + write(mvtk%vtk_unit) trim(mvtk%buffer)//NewLine + write(mvtk%vtk_unit)D + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A)') 'DATASET STRUCTURED_GRID' + write(mvtk%vtk_unit,'(A,I0,A,I0,A,I0)') 'DIMENSIONS ', n1,' ',n2,' ',n3 + write(mvtk%vtk_unit,'(A,I0,A)') 'POINTS ', mvtk%nPoints, ' double' + write(mvtk%vtk_unit,'(3'//RFMT//')')D + write(mvtk%vtk_unit,*) ' ' + endif + endif + end subroutine + + + + ! ------------------------------------------------------------------------- + ! --- POINT DATA + ! ------------------------------------------------------------------------- + subroutine vtk_point_data_init(mvtk) + type(VTK_Misc),intent(inout) :: mvtk + if ( mvtk%bFileOpen ) then + if(mvtk%bBinary) then + write(mvtk%buffer,'(A,I0)')'POINT_DATA ',mvtk%nPoints + write(mvtk%vtk_unit)trim(mvtk%buffer)//NewLine + else + write(mvtk%vtk_unit,'(A,I0)') 'POINT_DATA ', mvtk%nPoints + endif + endif + end subroutine + + subroutine vtk_point_data_scalar_flat(D,sname,mvtk) + real(ReKi), dimension(:),intent(in)::D + character(len=*),intent(in) ::sname + type(VTK_Misc),intent(inout) :: mvtk + + if ( mvtk%bFileOpen ) then + if (mvtk%bBinary) then + write(mvtk%vtk_unit)'SCALARS '//trim(sname)//' double'//NewLine + write(mvtk%vtk_unit)'LOOKUP_TABLE default'//NewLine + write(mvtk%vtk_unit)D + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A,A,A)') 'SCALARS ', sname, ' double' + write(mvtk%vtk_unit,'(A)') 'LOOKUP_TABLE default' + write(mvtk%vtk_unit,'(1'//RFMT//')')D + endif + endif + end subroutine + + subroutine vtk_point_data_scalar_2D(D,sname,mvtk) + real(ReKi), dimension(:,:),intent(in)::D + character(len=*),intent(in) ::sname + type(VTK_Misc),intent(inout) :: mvtk + + if ( mvtk%bFileOpen ) then + if (mvtk%bBinary) then + write(mvtk%vtk_unit)'SCALARS '//trim(sname)//' double'//NewLine + write(mvtk%vtk_unit)'LOOKUP_TABLE default'//NewLine + write(mvtk%vtk_unit)D + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A,A,A)') 'SCALARS ', sname, ' double' + write(mvtk%vtk_unit,'(A)') 'LOOKUP_TABLE default' + write(mvtk%vtk_unit,'(1'//RFMT//')')D + endif + endif + end subroutine + + subroutine vtk_point_data_scalar_grid(D,sname,mvtk) + real(ReKi), dimension(:,:,:,:),intent(in)::D + character(len=*),intent(in) ::sname + type(VTK_Misc),intent(inout) :: mvtk + + if ( mvtk%bFileOpen ) then + if (mvtk%bBinary) then + write(mvtk%vtk_unit)'SCALARS '//trim(sname)//' double'//NewLine + write(mvtk%vtk_unit)'LOOKUP_TABLE default'//NewLine + write(mvtk%vtk_unit)D + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A,A,A)') 'SCALARS ', sname, ' double' + write(mvtk%vtk_unit,'(A)') 'LOOKUP_TABLE default' + write(mvtk%vtk_unit,'(1'//RFMT//')')D + endif + endif + end subroutine + + subroutine vtk_point_data_scalar_grid2D(D,sname,mvtk) + real(ReKi), dimension(:,:,:),intent(in)::D + character(len=*),intent(in) ::sname + type(VTK_Misc),intent(inout) :: mvtk + + if ( mvtk%bFileOpen ) then + if (mvtk%bBinary) then + write(mvtk%vtk_unit)'SCALARS '//trim(sname)//' double'//NewLine + write(mvtk%vtk_unit)'LOOKUP_TABLE default'//NewLine + write(mvtk%vtk_unit)D + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A,A,A)') 'SCALARS ', sname, ' double' + write(mvtk%vtk_unit,'(A)') 'LOOKUP_TABLE default' + write(mvtk%vtk_unit,'(1'//RFMT//')')D + endif + endif + end subroutine + + !> + subroutine vtk_point_data_vector_flat(D,sname,mvtk) + real(ReKi), dimension(:,:),intent(in) :: D !< 3 x n + character(len=*),intent(in) ::sname + type(VTK_Misc),intent(inout) :: mvtk + if ( mvtk%bFileOpen ) then + if (mvtk%bBinary) then + write(mvtk%vtk_unit)'VECTORS '//trim(sname)//' double'//NewLine + write(mvtk%vtk_unit)D + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A,A,A)') 'VECTORS ', sname, ' double' + write(mvtk%vtk_unit,'(3'//RFMT//')')D + endif + endif + end subroutine + !> + subroutine vtk_point_data_vector_grid(D,sname,mvtk) + real(ReKi), dimension(:,:,:,:),intent(in) :: D !< 3 x n + character(len=*),intent(in) ::sname + type(VTK_Misc),intent(inout) :: mvtk + if ( mvtk%bFileOpen ) then + if (mvtk%bBinary) then + write(mvtk%vtk_unit)'VECTORS '//trim(sname)//' double'//NewLine + write(mvtk%vtk_unit)D + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A,A,A)') 'VECTORS ', sname, ' double' + write(mvtk%vtk_unit,'(3'//RFMT//')')D + endif + endif + end subroutine + !> + subroutine vtk_point_data_vector_grid2D(D,sname,mvtk) + real(ReKi), dimension(:,:,:),intent(in) :: D !< + character(len=*),intent(in) ::sname + type(VTK_Misc),intent(inout) :: mvtk + if ( mvtk%bFileOpen ) then + if (mvtk%bBinary) then + write(mvtk%vtk_unit)'VECTORS '//trim(sname)//' double'//NewLine + write(mvtk%vtk_unit)D + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A,A,A)') 'VECTORS ', sname, ' double' + write(mvtk%vtk_unit,'(3'//RFMT//')')D + endif + endif + end subroutine + + + ! ------------------------------------------------------------------------- + ! --- CELL DATA + ! ------------------------------------------------------------------------- + subroutine vtk_cell_data_init(mvtk) + type(VTK_Misc),intent(inout) :: mvtk + if ( mvtk%bFileOpen ) then + if (mvtk%bBinary) then + write(mvtk%buffer,'(A,I0)')'CELL_DATA ',mvtk%nData + write(mvtk%vtk_unit)trim(mvtk%buffer)//NewLine + else + write(mvtk%vtk_unit,'(A,I0)') 'CELL_DATA ', mvtk%nData + endif + endif + end subroutine + + subroutine vtk_cell_data_scalar_1d(D,sname,mvtk) + real(ReKi), dimension(:),intent(in)::D + character(len=*),intent(in) ::sname + type(VTK_Misc),intent(inout) :: mvtk + + if ( mvtk%bFileOpen ) then + if (mvtk%bBinary) then + write(mvtk%vtk_unit)'SCALARS '//trim(sname)//' double 1'//NewLine + write(mvtk%vtk_unit)'LOOKUP_TABLE default'//NewLine + write(mvtk%vtk_unit)D + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,fmt='(A,A,A)') 'SCALARS ', sname, ' double' + write(mvtk%vtk_unit,'(A)') 'LOOKUP_TABLE default' + write(mvtk%vtk_unit,'(1'//RFMT//')')D + endif + endif + end subroutine + + subroutine vtk_cell_data_scalar_2d(D,sname,mvtk) + real(ReKi), dimension(:,:),intent(in)::D + character(len=*),intent(in) ::sname + type(VTK_Misc),intent(inout) :: mvtk + + if ( mvtk%bFileOpen ) then + if (mvtk%bBinary) then + write(mvtk%vtk_unit)'SCALARS '//trim(sname)//' double 1'//NewLine + write(mvtk%vtk_unit)'LOOKUP_TABLE default'//NewLine + write(mvtk%vtk_unit)D + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,fmt='(A,A,A)') 'SCALARS ', sname, ' double' + write(mvtk%vtk_unit,'(A)') 'LOOKUP_TABLE default' + write(mvtk%vtk_unit,'(1'//RFMT//')')D + endif + endif + end subroutine + + + subroutine vtk_cell_data_vector(D,sname,mvtk) + real(ReKi), dimension(:,:),intent(in) :: D !< 3 x n + character(len=*),intent(in) ::sname + type(VTK_Misc),intent(inout) :: mvtk + if ( mvtk%bFileOpen ) then + if (mvtk%bBinary) then + write(mvtk%vtk_unit)'VECTORS '//trim(sname)//' double'//NewLine + write(mvtk%vtk_unit)D + write(mvtk%vtk_unit)NewLine + else + write(mvtk%vtk_unit,'(A,A,A)') 'VECTORS ', sname, ' double' + write(mvtk%vtk_unit,'(3'//RFMT//')')D + endif + endif + end subroutine + + ! --------------------------------------------------------------------------------} + ! --- VTK Tools + ! --------------------------------------------------------------------------------{ + !> Exports a Plane From a mesh + subroutine export_plane_grid3d(fname,v1,v2,v3,Values,mvtk) + character(len=*),intent(in) :: fname + real(ReKi),dimension(:), intent(in) :: v1,v2,v3 + real(ReKi),dimension(:,:,:,:), intent(in) :: Values + type(VTK_Misc),intent(inout) :: mvtk + ! Variables + integer :: nD + + ! Writting + if ( vtk_new_ascii_file(trim(fname),'grid',mvtk)) then + nD=size(Values,1) + call vtk_dataset_rectilinear(v1,v2,v3,mvtk) + ! Output as a structured grid, No need to reorder + call vtk_point_data_init(mvtk) + ! Could be a function of nDim, be careful + if(nD==3) then + call vtk_point_data_vector(Values(1:3,:,:,:),'Velocity',mvtk) ! Label... + endif + + call vtk_close_file(mvtk) + endif ! file opening + end subroutine + + !> Exports a Plane From a mesh + subroutine export_plane_grid2d(fname,v1,v2,v3,Values,mvtk) + character(len=*),intent(in) :: fname + real(ReKi),dimension(:), intent(in) :: v1,v2,v3 + real(ReKi),dimension(:,:,:), intent(in) :: Values + type(VTK_Misc),intent(inout) :: mvtk + ! Variables + integer :: nD + + ! Writting + if ( vtk_new_ascii_file(trim(fname),'plane',mvtk) ) then + nD=size(Values,1) + call vtk_dataset_rectilinear(v1,v2,v3,mvtk) + ! Output as a structured grid, No need to reorder + call vtk_point_data_init(mvtk) + ! Could be a function of nDim, be careful + if(nD==3) then + call vtk_point_data_vector(Values(1:3,:,:),'Velocity',mvtk) ! Label... + endif + + call vtk_close_file(mvtk) + endif ! file opening + end subroutine +end module VTK diff --git a/modules/subdyn/src/Yaml.f90 b/modules/nwtc-library/src/YAML.f90 similarity index 56% rename from modules/subdyn/src/Yaml.f90 rename to modules/nwtc-library/src/YAML.f90 index 316707fdd..5af02a209 100644 --- a/modules/subdyn/src/Yaml.f90 +++ b/modules/nwtc-library/src/YAML.f90 @@ -2,7 +2,7 @@ ! LICENSING ! Copyright (C) 2013-2016 National Renewable Energy Laboratory ! -! This file is part of SubDyn. +! This file is part of NWTC_Library. ! ! Licensed under the Apache License, Version 2.0 (the "License"); ! you may not use this file except in compliance with the License. @@ -18,7 +18,9 @@ ! !********************************************************************************************************************************** module YAML - use NWTC_Library + use Precision, only: IntKi, SiKi, R8Ki + use NWTC_Base, only: ErrID_None, ErrID_Fatal + use NWTC_IO, only: num2lstr implicit none @@ -32,8 +34,6 @@ module YAML 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 list to file @@ -41,7 +41,6 @@ module YAML module procedure yaml_write_listI ! Single dimension array (Ary) of IntKi module procedure yaml_write_listR4 ! Single dimension array (Ary) of SiKi module procedure yaml_write_listR8 ! Single dimension array (Ary) of R8Ki - module procedure yaml_write_listR16 ! Single dimension array (Ary) of QuKi end interface !> Write variable to file @@ -50,16 +49,30 @@ module YAML 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_comm public :: yaml_write_var public :: yaml_write_list public :: yaml_write_array contains +!> Write comment to yaml file +subroutine yaml_write_comm(fid, comment, ErrStat, ErrMsg) + integer(IntKi), intent(in ) :: fid !< File Unit + character(len=*), intent(in ) :: comment !< Comment + integer, intent( out) :: ErrStat !< A non-zero value indicates an error occurred + character(len=*), intent( out) :: ErrMsg !< Error message if errstat /= errid_none + ErrStat = ErrID_None + ErrMsg = "" + write(fid, '("#",A)', iostat=ErrStat) comment + if (ErrStat /= 0) then + ErrStat = ErrID_Fatal + ErrMsg = 'Error writing comment `'//trim(comment)//'` to YAML file' + endif +end subroutine yaml_write_comm ! -------------------------------------------------------------------------------- ! --- Write variable ! -------------------------------------------------------------------------------- @@ -86,8 +99,8 @@ subroutine yaml_write_varC(fid, key, val, VarFmt, ErrStat, ErrMsg, level, commen write(fid, Fmt, iostat=ErrStat) key, val endif if (ErrStat /= 0) then - ErrMsg='Error writting variable '//trim(key)//' to YAML file' - return + ErrStat = ErrID_Fatal + ErrMsg = 'Error writing variable '//trim(key)//' to YAML file' endif end subroutine yaml_write_varC @@ -113,8 +126,8 @@ subroutine yaml_write_varI(fid, key, val, VarFmt, ErrStat, ErrMsg, level, commen write(fid, Fmt, iostat=ErrStat) key, val endif if (ErrStat /= 0) then - ErrMsg='Error writting variable '//trim(key)//' to YAML file' - return + ErrStat = ErrID_Fatal + ErrMsg = 'Error writing variable '//trim(key)//' to YAML file' endif end subroutine yaml_write_varI @@ -140,8 +153,8 @@ subroutine yaml_write_varR4(fid, key, val, VarFmt, ErrStat, ErrMsg, level, comme write(fid, Fmt, iostat=ErrStat) key, val endif if (ErrStat /= 0) then - ErrMsg='Error writting variable '//trim(key)//' to YAML file' - return + ErrStat = ErrID_Fatal + ErrMsg = 'Error writing variable '//trim(key)//' to YAML file' endif end subroutine yaml_write_varR4 @@ -167,39 +180,11 @@ subroutine yaml_write_varR8(fid, key, val, VarFmt, ErrStat, ErrMsg, level, comme write(fid, Fmt, iostat=ErrStat) key, val endif if (ErrStat /= 0) then - ErrMsg='Error writting variable '//trim(key)//' to YAML file' - return + ErrStat = ErrID_Fatal + ErrMsg = 'Error writing variable '//trim(key)//' to YAML file' 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 List @@ -214,65 +199,12 @@ subroutine yaml_write_listI(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment 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 list '//trim(key)//' to YAML file' - return - end if - endif -end subroutine yaml_write_listI - -subroutine yaml_write_listR4(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment) - integer(IntKi), intent(in ) :: fid !< File Unit - character(len=*), intent(in ) :: key !< list name - real(SiKi), dimension(:), intent(in ) :: A !< list - 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 - + Fmt = '' + if (present(level)) Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' if (nc==0) then if (present(comment)) then write(fid, '('//trim(Fmt)//'A,": []",1X,"#",1X,A)', iostat=ErrStat) trim(key), trim(comment) @@ -280,42 +212,41 @@ subroutine yaml_write_listR4(fid, key, A, VarFmt, ErrStat, ErrMsg, level, commen write(fid, '('//trim(Fmt)//'A,": []")', iostat=ErrStat) trim(key) endif else + if (nc==1) then + Fmt = '('//trim(Fmt)//'A,": [",'//VarFmt//',"]"' + else + Fmt = '('//trim(Fmt)//'A,": [",'//trim(Num2LStr(nc-1))//'('//VarFmt//',","), '//VarFmt//'"]"' + endif if (present(comment)) then - Fmt = '('//trim(Fmt)//'A,": [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]",1X,"#",1X,A)' + Fmt = trim(Fmt)//',1X,"#",1X,A)' write(fid, Fmt, iostat=ErrStat)trim(key), A(:), trim(comment) else - Fmt = '('//trim(Fmt)//'A,": [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]",1X,"#",1X,A)' + Fmt = trim(Fmt)//')' write(fid, Fmt, iostat=ErrStat)trim(key), A(:) endif - if (ErrStat /= 0) then - ErrMsg='Error writting list '//trim(key)//' to YAML file' - return - end if endif -end subroutine yaml_write_listR4 + if (ErrStat /= 0) then + ErrStat = ErrID_Fatal + ErrMsg = 'Error writing list '//trim(key)//' to YAML file' + end if +end subroutine yaml_write_listI -subroutine yaml_write_listR8(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment) +subroutine yaml_write_listR4(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment) integer(IntKi), intent(in ) :: fid !< File Unit character(len=*), intent(in ) :: key !< list name - real(R8Ki), dimension(:), intent(in ) :: A !< list + real(SiKi), dimension(:), intent(in ) :: A !< list 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 - + Fmt = '' + if (present(level)) Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' if (nc==0) then if (present(comment)) then write(fid, '('//trim(Fmt)//'A,": []",1X,"#",1X,A)', iostat=ErrStat) trim(key), trim(comment) @@ -323,42 +254,41 @@ subroutine yaml_write_listR8(fid, key, A, VarFmt, ErrStat, ErrMsg, level, commen write(fid, '('//trim(Fmt)//'A,": []")', iostat=ErrStat) trim(key) endif else + if (nc==1) then + Fmt = '('//trim(Fmt)//'A,": [",'//VarFmt//',"]"' + else + Fmt = '('//trim(Fmt)//'A,": [",'//trim(Num2LStr(nc-1))//'('//VarFmt//',","), '//VarFmt//'"]"' + endif if (present(comment)) then - Fmt = '('//trim(Fmt)//'A,": [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]",1X,"#",1X,A)' + Fmt = trim(Fmt)//',1X,"#",1X,A)' write(fid, Fmt, iostat=ErrStat)trim(key), A(:), trim(comment) else - Fmt = '('//trim(Fmt)//'A,": [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]",1X,"#",1X,A)' + Fmt = trim(Fmt)//')' write(fid, Fmt, iostat=ErrStat)trim(key), A(:) endif - if (ErrStat /= 0) then - ErrMsg='Error writting list '//trim(key)//' to YAML file' - return - end if endif -end subroutine yaml_write_listR8 + if (ErrStat /= 0) then + ErrStat = ErrID_Fatal + ErrMsg = 'Error writing list '//trim(key)//' to YAML file' + end if +end subroutine yaml_write_listR4 -subroutine yaml_write_listR16(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment) +subroutine yaml_write_listR8(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment) integer(IntKi), intent(in ) :: fid !< File Unit character(len=*), intent(in ) :: key !< list name - real(QuKi), dimension(:), intent(in ) :: A !< list + real(R8Ki), dimension(:), intent(in ) :: A !< list 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 - + Fmt = '' + if (present(level)) Fmt = trim(Num2LStr(level*INDENT_SPACES))//'X,' if (nc==0) then if (present(comment)) then write(fid, '('//trim(Fmt)//'A,": []",1X,"#",1X,A)', iostat=ErrStat) trim(key), trim(comment) @@ -366,19 +296,25 @@ subroutine yaml_write_listR16(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comme write(fid, '('//trim(Fmt)//'A,": []")', iostat=ErrStat) trim(key) endif else + if (nc==1) then + Fmt = '('//trim(Fmt)//'A,": [",'//VarFmt//',"]"' + else + Fmt = '('//trim(Fmt)//'A,": [",'//trim(Num2LStr(nc-1))//'('//VarFmt//',","), '//VarFmt//'"]"' + endif if (present(comment)) then - Fmt = '('//trim(Fmt)//'A,": [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]",1X,"#",1X,A)' + Fmt = trim(Fmt)//',1X,"#",1X,A)' write(fid, Fmt, iostat=ErrStat)trim(key), A(:), trim(comment) else - Fmt = '('//trim(Fmt)//'A,": [",'//trim(Num2LStr(nc))//'('//VarFmt//',","),"]",1X,"#",1X,A)' + Fmt = trim(Fmt)//')' write(fid, Fmt, iostat=ErrStat)trim(key), A(:) endif - if (ErrStat /= 0) then - ErrMsg='Error writting list '//trim(key)//' to YAML file' - return - end if endif -end subroutine yaml_write_listR16 + if (ErrStat /= 0) then + ErrStat = ErrID_Fatal + ErrMsg = 'Error writing list '//trim(key)//' to YAML file' + end if +end subroutine yaml_write_listR8 + ! -------------------------------------------------------------------------------- ! --- Write 1D array @@ -393,41 +329,32 @@ subroutine yaml_write_array1I(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comme 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 - + 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), 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 + if (ErrStat /= 0) then + ErrStat = ErrID_Fatal + ErrMsg = 'Error writing array '//trim(key)//' to YAML file' + end if end subroutine yaml_write_array1I subroutine yaml_write_array1R4(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment) @@ -440,41 +367,32 @@ subroutine yaml_write_array1R4(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comm 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 - + 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), 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 + if (ErrStat /= 0) then + ErrStat = ErrID_Fatal + ErrMsg = 'Error writing array '//trim(key)//' to YAML file' + end if end subroutine yaml_write_array1R4 subroutine yaml_write_array1R8(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment) @@ -487,95 +405,39 @@ subroutine yaml_write_array1R8(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comm 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 - + 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), 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 + if (ErrStat /= 0) then + ErrStat = ErrID_Fatal + ErrMsg = 'Error writing array '//trim(key)//' to YAML file' 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 - +end subroutine yaml_write_array1R8 ! --------------------------------------------------------------------------------} ! --- Write Array 2D ! --------------------------------------------------------------------------------{ -subroutine yaml_write_array2I(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comment, label, json) +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 @@ -585,93 +447,60 @@ subroutine yaml_write_array2I(fid, key, A, VarFmt, ErrStat, ErrMsg, level, comme 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 - logical, optional, intent(in ) :: json !< If present, write to JSON format integer :: nr, nc, i ! size (rows and columns) of A - integer :: nSpaces ! number of indentation spaces character(256) :: Fmt - logical :: bjson ErrStat = ErrID_None ErrMsg = "" nr = size(A,1) nc = size(A,2) + Fmt='' - Fmt = '' - if (present(json)) then - bjson=json + ! Indent and Key + 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 - bjson=.false. + Fmt = trim(Num2LStr(INDENT_SPACES))//'X,' endif - - if (.not.bjson) then - ! Indent and Key - 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 - ! Data - if (nr==0) then - write(fid, '('//trim(Fmt)//'"- [ ]")', iostat=ErrStat) - else - ! YAML Line format - if (present(label)) then - if (nc==1) then - Fmt = '('//trim(Fmt)//'"- [", '//VarFmt//', "] # ",I0)' - else - Fmt = '('//trim(Fmt)//'"- [", '//trim(Num2LStr(nc-1))//'('//VarFmt//', ","), '//VarFmt//', "] # ",I0)' - endif + ! Data + if (nr==0) then + write(fid, '('//trim(Fmt)//'"- [ ]")', iostat=ErrStat) + else + ! YAML Line format + if (present(label)) then + if (nc==1) then + Fmt = '('//trim(Fmt)//'"- [", '//VarFmt//', "] # ",I0)' else - if (nc==1) then - Fmt = '('//trim(Fmt)//'"- [", '//trim(Num2LStr(nc))//'('//VarFmt//'), "]")' - else - Fmt = '('//trim(Fmt)//'"- [", '//trim(Num2LStr(nc-1))//'('//VarFmt//', ","), '//VarFmt//', "]")' - endif + Fmt = '('//trim(Fmt)//'"- [", '//trim(Num2LStr(nc-1))//'('//VarFmt//', ","), '//VarFmt//', "] # ",I0)' endif - ! Write line by line - 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 - end do - endif - else - ! Key - write(fid, '(A,": [")', iostat=ErrStat, advance='no') trim(key) - if (nr==0) then - write(fid, '("[]]")', iostat=ErrStat) else - ! JSON Line format if (nc==1) then - Fmt = '("[",'//VarFmt//',"],")' + Fmt = '('//trim(Fmt)//'"- [", '//trim(Num2LStr(nc))//'('//VarFmt//'), "]")' else - Fmt = '("[",'//trim(Num2LStr(nc-1))//'('//VarFmt//',","),'//VarFmt//',"]")' + Fmt = '('//trim(Fmt)//'"- [", '//trim(Num2LStr(nc-1))//'('//VarFmt//', ","), '//VarFmt//', "]")' endif - ! Write line by line - do i=1,nr - write(fid, Fmt, iostat=ErrStat, advance='no') A(i,:) - if (i +) +set_target_properties(openfast_postlib PROPERTIES PUBLIC_HEADER src/FAST_Library.h) -add_library(openfastlib src/FAST_Library.f90) -target_link_libraries(openfastlib openfast_postlib openfast_prelib scdataexlib foamfastlib) +# OpenFAST Library static (openfast, FAST.Farm, Simulink) +add_library(openfastlib_static INTERFACE) +target_link_libraries(openfastlib_static INTERFACE openfast_postlib) -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. - # https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html - set_source_files_properties( - src/FAST_Subs.f90 src/FAST_Types.f90 src/FAST_Library.f90 - PROPERTIES - COMPILE_FLAGS "-fno-var-tracking -fno-var-tracking-assignments" - ) -endif() -if (${_compiler_id} MATCHES "^INTEL" AND ${_build_type} STREQUAL "RELEASE" AND NOT WIN32) - # Compilation hangs on FAST_Farm_Types.f90 with -O3 on linux (on some hardware) - set_source_files_properties(src/FAST_Types.f90 PROPERTIES COMPILE_FLAGS "-O2") +# OpenFAST Library shared (Python, openfast_cpp, openfastcpplib) +add_library(openfastlib SHARED src/FAST_Library.f90) +target_link_libraries(openfastlib openfast_postlib) +if(APPLE OR UNIX) + target_compile_definitions(openfastlib PRIVATE IMPLICIT_DLLEXPORT) endif() -install(TARGETS openfastlib openfast_prelib openfast_postlib +# Install +install(TARGETS openfast_postlib openfast_prelib openfastlib openfastlib_static EXPORT ${CMAKE_PROJECT_NAME}Libraries - RUNTIME DESTINATION lib + RUNTIME DESTINATION bin ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) - -install(FILES - src/FAST_Library.h - DESTINATION include) + LIBRARY DESTINATION lib + PUBLIC_HEADER DESTINATION include +) diff --git a/modules/openfast-library/src/FAST_Library.f90 b/modules/openfast-library/src/FAST_Library.f90 index f57e97b05..e962337d3 100644 --- a/modules/openfast-library/src/FAST_Library.f90 +++ b/modules/openfast-library/src/FAST_Library.f90 @@ -83,7 +83,7 @@ subroutine FAST_DeallocateTurbines(ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_Deal ErrMsg_c = C_NULL_CHAR end subroutine !================================================================================================================================== -subroutine FAST_Sizes(iTurb, InputFileName_c, AbortErrLev_c, NumOuts_c, dt_c, tmax_c, ErrStat_c, ErrMsg_c, ChannelNames_c, TMax, InitInpAry) BIND (C, NAME='FAST_Sizes') +subroutine FAST_Sizes(iTurb, InputFileName_c, AbortErrLev_c, NumOuts_c, dt_c, dt_out_c, tmax_c, ErrStat_c, ErrMsg_c, ChannelNames_c, TMax, InitInpAry) BIND (C, NAME='FAST_Sizes') IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT !DEC$ ATTRIBUTES DLLEXPORT :: FAST_Sizes @@ -94,6 +94,7 @@ subroutine FAST_Sizes(iTurb, InputFileName_c, AbortErrLev_c, NumOuts_c, dt_c, tm INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c INTEGER(C_INT), INTENT( OUT) :: NumOuts_c REAL(C_DOUBLE), INTENT( OUT) :: dt_c + REAL(C_DOUBLE), INTENT( OUT) :: dt_out_c REAL(C_DOUBLE), INTENT( OUT) :: tmax_c INTEGER(C_INT), INTENT( OUT) :: ErrStat_c CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_c(IntfStrLen) @@ -151,6 +152,7 @@ subroutine FAST_Sizes(iTurb, InputFileName_c, AbortErrLev_c, NumOuts_c, dt_c, tm AbortErrLev_c = AbortErrLev NumOuts_c = min(MAXOUTPUTS, SUM( Turbine(iTurb)%y_FAST%numOuts )) dt_c = Turbine(iTurb)%p_FAST%dt + dt_out_c = Turbine(iTurb)%p_FAST%DT_Out tmax_c = Turbine(iTurb)%p_FAST%TMax ErrStat_c = ErrStat @@ -504,7 +506,7 @@ subroutine FAST_Restart(iTurb, CheckpointRootName_c, AbortErrLev_c, NumOuts_c, d end subroutine FAST_Restart !================================================================================================================================== -subroutine FAST_OpFM_Init(iTurb, TMax, InputFileName_c, TurbID, NumSC2CtrlGlob, NumSC2Ctrl, NumCtrl2SC, InitSCOutputsGlob, InitSCOutputsTurbine, NumActForcePtsBlade, NumActForcePtsTower, TurbPosn, AbortErrLev_c, dt_c, NumBl_c, NumBlElem_c, & +subroutine FAST_OpFM_Init(iTurb, TMax, InputFileName_c, TurbID, NumSC2CtrlGlob, NumSC2Ctrl, NumCtrl2SC, InitSCOutputsGlob, InitSCOutputsTurbine, NumActForcePtsBlade, NumActForcePtsTower, TurbPosn, AbortErrLev_c, dt_c, NumBl_c, NumBlElem_c, NodeClusterType_c, & OpFM_Input_from_FAST, OpFM_Output_to_FAST, SC_DX_Input_from_FAST, SC_DX_Output_to_FAST, ErrStat_c, ErrMsg_c) BIND (C, NAME='FAST_OpFM_Init') IMPLICIT NONE #ifndef IMPLICIT_DLLEXPORT @@ -522,6 +524,7 @@ subroutine FAST_OpFM_Init(iTurb, TMax, InputFileName_c, TurbID, NumSC2CtrlGlob, REAL(C_FLOAT), INTENT(IN ) :: InitScOutputsTurbine (*) ! Initial Supercontroller turbine specific outputs = controller inputs INTEGER(C_INT), INTENT(IN ) :: NumActForcePtsBlade ! number of actuator line force points in blade INTEGER(C_INT), INTENT(IN ) :: NumActForcePtsTower ! number of actuator line force points in tower + INTEGER(C_INT), INTENT(IN ):: NodeClusterType_c REAL(C_FLOAT), INTENT(IN ) :: TurbPosn(3) INTEGER(C_INT), INTENT( OUT) :: AbortErrLev_c REAL(C_DOUBLE), INTENT( OUT) :: dt_c @@ -581,6 +584,8 @@ subroutine FAST_OpFM_Init(iTurb, TMax, InputFileName_c, TurbID, NumSC2CtrlGlob, ExternInitData%NumActForcePtsBlade = NumActForcePtsBlade ExternInitData%NumActForcePtsTower = NumActForcePtsTower + ExternInitData%NodeClusterType = NodeClusterType_c + CALL FAST_InitializeAll_T( t_initial, iTurb, Turbine(iTurb), ErrStat, ErrMsg, InputFileName, ExternInitData ) ! set values for return to OpenFOAM diff --git a/modules/openfast-library/src/FAST_Library.h b/modules/openfast-library/src/FAST_Library.h index 3c5f4cd65..0fcb764f6 100644 --- a/modules/openfast-library/src/FAST_Library.h +++ b/modules/openfast-library/src/FAST_Library.h @@ -18,7 +18,7 @@ EXTERNAL_ROUTINE void FAST_DeallocateTurbines(int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_OpFM_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, double * dt, int * NumBl, int * NumBlElem, int * n_t_global, OpFM_InputType_t* OpFM_Input, OpFM_OutputType_t* OpFM_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_OpFM_Init(int * iTurb, double *TMax, const char *InputFileName, int * TurbineID, int * NumSC2CtrlGlob, int * NumSC2Ctrl, int * NumCtrl2SC, float * initSCInputsGlob, float * initSCInputsTurbine, int * NumActForcePtsBlade, int * NumActForcePtsTower, float * TurbinePosition, - int *AbortErrLev, double * dt, int * NumBl, int * NumBlElem, OpFM_InputType_t* OpFM_Input, OpFM_OutputType_t* OpFM_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, + int *AbortErrLev, double * dt, int * NumBl, int * NumBlElem, int * NodeClusterType, OpFM_InputType_t* OpFM_Input, OpFM_OutputType_t* OpFM_Output, SC_DX_InputType_t* SC_DX_Input, SC_DX_OutputType_t* SC_DX_Output, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_OpFM_Solution0(int * iTurb, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_OpFM_Step(int * iTurb, int *ErrStat, char *ErrMsg); @@ -27,9 +27,9 @@ EXTERNAL_ROUTINE void FAST_HubPosition(int * iTurb, float * absolute_position, f EXTERNAL_ROUTINE void FAST_Restart(int * iTurb, const char *CheckpointRootName, int *AbortErrLev, int * NumOuts, double * dt, int * n_t_global, int *ErrStat, char *ErrMsg); #ifdef __cplusplus -EXTERNAL_ROUTINE void FAST_Sizes(int * iTurb, const char *InputFileName, int *AbortErrLev, int * NumOuts, double * dt, double * tmax, int *ErrStat, char *ErrMsg, char *ChannelNames, double *TMax = NULL, double *InitInputAry = NULL); +EXTERNAL_ROUTINE void FAST_Sizes(int * iTurb, const char *InputFileName, int *AbortErrLev, int * NumOuts, double * dt, double * dt_out, double * tmax, int *ErrStat, char *ErrMsg, char *ChannelNames, double *TMax = NULL, double *InitInputAry = NULL); #else -EXTERNAL_ROUTINE void FAST_Sizes(int * iTurb, const char *InputFileName, int *AbortErrLev, int * NumOuts, double * dt, double * tmax, int *ErrStat, char *ErrMsg, char *ChannelNames, double *TMax, double *InitInputAry); +EXTERNAL_ROUTINE void FAST_Sizes(int * iTurb, const char *InputFileName, int *AbortErrLev, int * NumOuts, double * dt, double * dt_out, double * tmax, int *ErrStat, char *ErrMsg, char *ChannelNames, double *TMax, double *InitInputAry); #endif EXTERNAL_ROUTINE void FAST_Start(int * iTurb, int *NumInputs_c, int *NumOutputs_c, double *InputAry, double *OutputAry, int *ErrStat, char *ErrMsg); EXTERNAL_ROUTINE void FAST_Update(int * iTurb, int *NumInputs_c, int *NumOutputs_c, double *InputAry, double *OutputAry, bool *EndSimulationEarly, int *ErrStat, char *ErrMsg); @@ -58,6 +58,16 @@ EXTERNAL_ROUTINE void FAST_CreateCheckpoint(int * iTurb, const char *CheckpointR #define MAXInitINPUTS 53 #define NumFixedInputs 2 + 2 + MAXIMUM_BLADES + 1 + MAXIMUM_AFCTRL + MAXIMUM_CABLE_DELTAL + MAXIMUM_CABLE_DELTALDOT - +/* Fixed inputs list: + 1 Generator Torque (N-m) + 2 Electrical Power (W) + 3 Yaw pos (rad) + 4 Yaw rate (rad/s) + 5-7 Blade 1-3 pitch angle (rad) + 8 High speed shaft brake fraction (-) + 9-11 Blade 1-3 Airfoil control (-) + 12-31 Cable control channel 1-20 DeltaL (m) + 32-51 Cable control channel 1-20 DeltaLDot (m/s) +*/ #endif diff --git a/modules/openfast-library/src/FAST_Lin.f90 b/modules/openfast-library/src/FAST_Lin.f90 index 63b06f234..c412b5f1f 100644 --- a/modules/openfast-library/src/FAST_Lin.f90 +++ b/modules/openfast-library/src/FAST_Lin.f90 @@ -118,6 +118,9 @@ SUBROUTINE Init_Lin(p_FAST, y_FAST, m_FAST, AD, ED, NumBl, NumBlNodes, ErrStat, 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 + else if ( p_FAST%CompMooring == Module_MD ) then + p_FAST%Lin_NumMods = p_FAST%Lin_NumMods + 1 + p_FAST%Lin_ModOrder( p_FAST%Lin_NumMods ) = Module_MD end if @@ -1107,6 +1110,63 @@ SUBROUTINE FAST_Linearize_OP(t_global, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, end if ! if ( p_FAST%LinOutMod ) end if ! if ( p_FAST%CompMooring == Module_MAP ) + + !..................... + ! MoorDyn + !..................... + if ( p_FAST%CompMooring == Module_MD ) then + + call MD_JacobianPInput( t_global, MD%Input(1), MD%p, MD%x(STATE_CURR), MD%xd(STATE_CURR), MD%z(STATE_CURR), & + MD%OtherSt(STATE_CURR), MD%y, MD%m, ErrStat2, ErrMsg2, & + dXdu=y_FAST%Lin%Modules(Module_MD)%Instance(1)%B, & + dYdu=y_FAST%Lin%Modules(Module_MD)%Instance(1)%D ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + call MD_JacobianPContState( t_global, MD%Input(1), MD%p, MD%x(STATE_CURR), MD%xd(STATE_CURR), MD%z(STATE_CURR), MD%OtherSt(STATE_CURR), & + MD%y, MD%m, ErrStat2, ErrMsg2, dYdx=y_FAST%Lin%Modules(Module_MD)%Instance(1)%C, & + dXdx=y_FAST%Lin%Modules(Module_MD)%Instance(1)%A ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + ! get the operating point + call MD_GetOP( t_global, MD%Input(1), MD%p, MD%x(STATE_CURR), MD%xd(STATE_CURR), MD%z(STATE_CURR), & + MD%OtherSt(STATE_CURR), MD%y, MD%m, ErrStat2, ErrMsg2, & + u_op=y_FAST%Lin%Modules(Module_MD)%Instance(1)%op_u, & + y_op=y_FAST%Lin%Modules(Module_MD)%Instance(1)%op_y, & + x_op=y_FAST%Lin%Modules(Module_MD)%Instance(1)%op_x, & + dx_op=y_FAST%Lin%Modules(Module_MD)%Instance(1)%op_dx ) + 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_MD)) + call WrLinFile_txt_Head(t_global, p_FAST, y_FAST, y_FAST%Lin%Modules(Module_MD)%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 + ! dXdx, dXdu, dYdx, dYdu: + call WrPartialMatrix( y_FAST%Lin%Modules(Module_MD)%Instance(1)%A, Un, p_FAST%OutFmt, 'dXdx' ) + call WrPartialMatrix( y_FAST%Lin%Modules(Module_MD)%Instance(1)%B, Un, p_FAST%OutFmt, 'dXdu', UseCol=y_FAST%Lin%Modules(Module_MD)%Instance(1)%use_u ) + call WrPartialMatrix( y_FAST%Lin%Modules(Module_MD)%Instance(1)%C, Un, p_FAST%OutFmt, 'dYdx', UseRow=y_FAST%Lin%Modules(Module_MD)%Instance(1)%use_y ) + call WrPartialMatrix( y_FAST%Lin%Modules(Module_MD)%Instance(1)%D, Un, p_FAST%OutFmt, 'dYdu', UseRow=y_FAST%Lin%Modules(Module_MD)%Instance(1)%use_y, & + UseCol=y_FAST%Lin%Modules(Module_MD)%Instance(1)%use_u ) + end if + + ! finish writing the file + call WrLinFile_txt_End(Un, p_FAST, y_FAST%Lin%Modules(Module_MD)%Instance(1) ) + + end if ! if ( p_FAST%LinOutMod ) + end if ! if ( p_FAST%CompMooring == Module_MD ) + !..................... ! Linearization of glue code Input/Output solve: !..................... @@ -1667,7 +1727,7 @@ SUBROUTINE Glue_Jacobians( p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, IfW, OpFM, !............ ! we need to do this for CompElast=ED and CompElast=BD - call Linear_ED_InputSolve_du( p_FAST, y_FAST, SrvD, ED%Input(1), ED%y, AD%y, AD%Input(1), BD, HD, SD, MAPp, MeshMapData, dUdu, ErrStat2, ErrMsg2 ) + call Linear_ED_InputSolve_du( p_FAST, y_FAST, SrvD, ED%Input(1), ED%y, AD%y, AD%Input(1), BD, HD, SD, MAPp, MD, MeshMapData, dUdu, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) !............ @@ -1703,12 +1763,20 @@ SUBROUTINE Glue_Jacobians( p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, IfW, OpFM, ! \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, SrvD, SD%Input(1), SD%y, ED%y, HD, MAPp, MeshMapData, dUdu, ErrStat2, ErrMsg2 ) + call Linear_SD_InputSolve_du( p_FAST, y_FAST, SrvD, SD%Input(1), SD%y, ED%y, HD, MAPp, MD, 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 + !............ + ! \f$ \frac{\partial U_\Lambda^{MD}}{\partial u^{MD}} \end{bmatrix} = \f$ (dUdu block row 9=MD) <<<< + !............ + if (p_FAST%CompMooring == MODULE_MD) then + call Linear_MD_InputSolve_du( p_FAST, y_FAST, MD%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 SrvD, HD, SD, and MAP !..................................... ! dUdy @@ -1758,7 +1826,7 @@ SUBROUTINE Glue_Jacobians( p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, IfW, OpFM, ! \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, SrvD, ED%Input(1), ED%y, AD%y, AD%Input(1), BD, HD, SD, MAPp, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) + call Linear_ED_InputSolve_dy( p_FAST, y_FAST, SrvD, ED%Input(1), ED%y, AD%y, AD%Input(1), BD, HD, SD, MAPp, MD, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) !............ @@ -1801,7 +1869,7 @@ SUBROUTINE Glue_Jacobians( p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, IfW, OpFM, !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, SrvD, SD%Input(1), SD%y, ED%y, HD, MAPp, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) + call Linear_SD_InputSolve_dy( p_FAST, y_FAST, SrvD, SD%Input(1), SD%y, ED%y, HD, MAPp, MD, 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' @@ -1815,6 +1883,14 @@ SUBROUTINE Glue_Jacobians( p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD, IfW, OpFM, 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 + !............ + ! \f$ \frac{\partial U_\Lambda^{MD}}{\partial y^{ED}} \end{bmatrix} = \f$ + ! \f$ \frac{\partial U_\Lambda^{MD}}{\partial y^{SD}} \end{bmatrix} = \f$ (dUdy block row 9=MD) <<<< + !............ + if (p_FAST%CompMooring == MODULE_MD) then + call Linear_MD_InputSolve_dy( p_FAST, y_FAST, MD%Input(1), ED%y, SD%y, MeshMapData, dUdy, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + end if END SUBROUTINE Glue_Jacobians @@ -1876,13 +1952,14 @@ SUBROUTINE Linear_IfW_InputSolve_du_AD( p_FAST, y_FAST, u_AD, dUdu ) end do END DO + ! HubPosition and HubOrientation from ElastoDyn are missing from this END IF 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, SrvD, u_ED, y_ED, y_AD, u_AD, BD, HD, SD, MAPp, MeshMapData, dUdu, ErrStat, ErrMsg ) +SUBROUTINE Linear_ED_InputSolve_du( p_FAST, y_FAST, SrvD, u_ED, y_ED, y_AD, u_AD, BD, HD, SD, MAPp, MD, 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) @@ -1895,6 +1972,7 @@ SUBROUTINE Linear_ED_InputSolve_du( p_FAST, y_FAST, SrvD, u_ED, y_ED, y_AD, u_AD 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(MoorDyn_Data), INTENT(INOUT) :: MD !< MD 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 INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status @@ -1910,6 +1988,7 @@ SUBROUTINE Linear_ED_InputSolve_du( p_FAST, y_FAST, SrvD, u_ED, y_ED, y_AD, u_AD 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) :: MD_Start ! starting index of dUdu (column) where MD fairlead motion inputs are located INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None @@ -2164,6 +2243,29 @@ SUBROUTINE Linear_ED_InputSolve_du( p_FAST, y_FAST, SrvD, u_ED, y_ED, y_AD, u_AD call SetBlockMatrix( dUdu, MeshMapData%Mooring_P_2_ED_P%dM%m_us, ED_Start_mt, MAP_Start ) end if + !.......... + ! dU^{ED}/du^{MD} + !.......... + else if ( p_FAST%CompMooring == Module_MD ) 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 MD loads to ED PlatformPtmesh input: + ! we're mapping loads, so we also need the sibling meshes' displacements: + + MD_Start = y_FAST%Lin%Modules(Module_MD)%Instance(1)%LinStartIndx(LIN_INPUT_COL) + + ! NOTE: Assumes at least one coupled MD object + + CALL Linearize_Point_to_Point( MD%y%CoupledLoads(1), u_ED%PlatformPtMesh, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, MD%Input(1)%CoupledKinematics(1), y_ED%PlatformPtMesh) + 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, MD_Start ) + end if + end if end if @@ -2172,7 +2274,7 @@ END SUBROUTINE Linear_ED_InputSolve_du !---------------------------------------------------------------------------------------------------------------------------------- !> This routine forms the dU^{SD}/du^{SrvD}, dU^{SD}/du^{HD}, dU^{SD}/du^{SD}, and dU^{SD}/du^{MAP} blocks (SD row) of dUdu. (i.e., how do changes in SrvD, HD, SD, and MAP inputs affect the SD inputs?) -SUBROUTINE Linear_SD_InputSolve_du( p_FAST, y_FAST, SrvD, u_SD, y_SD, y_ED, HD, MAPp, MeshMapData, dUdu, ErrStat, ErrMsg ) +SUBROUTINE Linear_SD_InputSolve_du( p_FAST, y_FAST, SrvD, u_SD, y_SD, y_ED, HD, MAPp, MD, 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) @@ -2182,6 +2284,7 @@ SUBROUTINE Linear_SD_InputSolve_du( p_FAST, y_FAST, SrvD, u_SD, y_SD, y_ED, HD, 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(MoorDyn_Data), INTENT(INOUT) :: MD !< MD 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 @@ -2190,7 +2293,7 @@ SUBROUTINE Linear_SD_InputSolve_du( p_FAST, y_FAST, SrvD, u_SD, y_SD, y_ED, HD, ! local variables INTEGER(IntKi) :: j, SrvD_Start INTEGER(IntKi) :: HD_Start - INTEGER(IntKi) :: MAP_Start + INTEGER(IntKi) :: MAP_Start, MD_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 @@ -2309,31 +2412,52 @@ SUBROUTINE Linear_SD_InputSolve_du( p_FAST, y_FAST, SrvD, u_SD, y_SD, y_ED, HD, ! dU^{SD}/du^{MAP} !.......... - if ( p_FAST%CompMooring == Module_MAP ) then + 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: + ! 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) - 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%Y3Mesh) !MAPp%Input(1)%ptFairleadLoad and y_SD%Y3Mesh 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 + ! 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%Y3Mesh) !MAPp%Input(1)%ptFairleadLoad and y_SD%Y3Mesh 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 + + !.......... + ! dU^{SD}/du^{MD} + !.......... + else if ( p_FAST%CompMooring == Module_MD ) then + + ! Transfer MD loads to ED PlatformPtmesh input: + ! we're mapping loads, so we also need the sibling meshes' displacements: + + MD_Start = y_FAST%Lin%Modules(Module_MD)%Instance(1)%LinStartIndx(LIN_INPUT_COL) + ! NOTE: Assumes at least one coupled MD object + + CALL Linearize_Point_to_Point( MD%y%CoupledLoads(1), u_SD%LMesh, MeshMapData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2, MD%Input(1)%CoupledKinematics(1), y_SD%Y3Mesh) + 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, MD_Start ) end if + + end if + END IF END SUBROUTINE Linear_SD_InputSolve_du !---------------------------------------------------------------------------------------------------------------------------------- !> This routine forms the dU^{SD}/dy^{SrvD}, dU^{SD}/dy^{HD} and dU^{SD}/dy^{SD} blocks (SD row) of dUdu. (i.e., how do changes in SrvD, HD, and SD inputs affect the SD inputs?) -SUBROUTINE Linear_SD_InputSolve_dy( p_FAST, y_FAST, SrvD, u_SD, y_SD, y_ED, HD, MAPp, MeshMapData, dUdy, ErrStat, ErrMsg ) +SUBROUTINE Linear_SD_InputSolve_dy( p_FAST, y_FAST, SrvD, u_SD, y_SD, y_ED, HD, MAPp, MD, 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) @@ -2343,14 +2467,15 @@ SUBROUTINE Linear_SD_InputSolve_dy( p_FAST, y_FAST, SrvD, u_SD, y_SD, y_ED, HD, 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(MoorDyn_Data), INTENT(INOUT) :: MD !< MD 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) :: j, SrvD_Out_Start, SD_Start, SD_Out_Start, HD_Start, HD_Out_Start, ED_Out_Start, MAP_Out_Start - INTEGER(IntKi) :: MAP_Start + INTEGER(IntKi) :: j, SrvD_Out_Start, SD_Start, SD_Out_Start, HD_Start, HD_Out_Start, ED_Out_Start, MAP_Out_Start, MD_Out_Start + INTEGER(IntKi) :: MAP_Start, MD_Start ! INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation ! CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None @@ -2440,6 +2565,23 @@ SUBROUTINE Linear_SD_InputSolve_dy( p_FAST, y_FAST, SrvD, u_SD, y_SD, y_ED, HD, 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_Y3Mesh_Start(y_SD, y_FAST) ! start of y_SD%Y3Mesh%TranslationDisp field + call SumBlockMatrix( dUdy, MeshMapData%Mooring_P_2_SD_P%dM%m_uD, SD_Start, SD_Out_Start ) + end if + + !.......... + ! dU^{SD}/dy^{MD} + !.......... + else if ( p_FAST%CompMooring == Module_MD ) then + if ( MD%y%CoupledLoads(1)%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. + MD_Out_Start = y_FAST%Lin%Modules(Module_MD)%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(MD%y%CoupledLoads(1), u_SD%LMesh, MeshMapData%Mooring_P_2_SD_P, SD_Start, MD_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_Y3Mesh_Start(y_SD, y_FAST) ! start of y_SD%Y3Mesh%TranslationDisp field @@ -3001,7 +3143,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, SrvD, u_ED, y_ED, y_AD, u_AD, BD, HD, SD, MAPp, MeshMapData, dUdy, ErrStat, ErrMsg ) +SUBROUTINE Linear_ED_InputSolve_dy( p_FAST, y_FAST, SrvD, u_ED, y_ED, y_AD, u_AD, BD, HD, SD, MAPp, MD, 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) @@ -3014,6 +3156,7 @@ SUBROUTINE Linear_ED_InputSolve_dy( p_FAST, y_FAST, SrvD, u_ED, y_ED, y_AD, u_AD 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(MoorDyn_Data), INTENT(INOUT) :: MD !< MD 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^(ED)/du^(AD) block @@ -3032,6 +3175,7 @@ SUBROUTINE Linear_ED_InputSolve_dy( p_FAST, y_FAST, SrvD, u_ED, y_ED, y_AD, u_AD 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 + INTEGER(IntKi) :: MD_Out_Start ! starting index of dUdy (column) where MoorDyn output fields are located CHARACTER(*), PARAMETER :: RoutineName = 'Linear_ED_InputSolve_dy' @@ -3246,7 +3390,21 @@ SUBROUTINE Linear_ED_InputSolve_dy( p_FAST, y_FAST, SrvD, u_ED, y_ED, y_AD, u_AD 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 - + ! MoorDyn + ! parts of dU^{ED}/dy^{MD} and dU^{ED}/dy^{ED}: + else if ( p_FAST%CompMooring == Module_MD ) then + if ( MD%y%CoupledLoads(1)%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. + MD_Out_Start = y_FAST%Lin%Modules(Module_MD)%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(MD%y%CoupledLoads(1), u_ED%PlatformPtMesh, MeshMapData%Mooring_P_2_ED_P, ED_Start, MD_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 @@ -3446,7 +3604,13 @@ SUBROUTINE Linear_AD_InputSolve_IfW_dy( p_FAST, y_FAST, u_AD, dUdy ) AD_Start = AD_Start + 3 end do end if - + + do i=1,3 !rotor-disk velocity component (DiskVel) + dUdy( AD_Start + i - 1, y_FAST%Lin%Modules(MODULE_IfW)%Instance(1)%LinStartIndx(LIN_OUTPUT_COL) + (node-1)*3 + i - 1 ) = -1.0_R8Ki + end do + node = node + 1 + AD_Start = AD_Start + 3 + !END IF @@ -3905,6 +4069,141 @@ SUBROUTINE Linear_MAP_InputSolve_dy( p_FAST, y_FAST, u_MAP, y_ED, y_SD, MeshMapD END IF END SUBROUTINE Linear_MAP_InputSolve_dy +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine forms the dU^{MD}/du^{MD} block of dUdu. (i.e., how do changes in the MD outputs affect +!! the MD inputs?) +SUBROUTINE Linear_MD_InputSolve_du( p_FAST, y_FAST, u_MD, 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(MD_InputType), INTENT(INOUT) :: u_MD !< The inputs to MoorDyn + 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^{MD}/dy^{ED} block + + INTEGER(IntKi) :: ErrStat !< Error status of the operation + CHARACTER(*) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! Local variables: + + INTEGER(IntKi) :: MD_Start_td ! starting index of dUdu (column) where particular MD fields are located + INTEGER(IntKi) :: MD_Start_tr ! starting index of dUdu (row) where particular MD fields are located + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Linear_MD_InputSolve_du' + + + ErrStat = ErrID_None + ErrMsg = "" + IF (u_MD%CoupledKinematics(1)%Committed) THEN + !................................... + ! FairLead Mesh + !................................... + + if ( p_FAST%CompSub == Module_SD ) THEN + ! dU^{MD}/du^{MD} + call Linearize_Point_to_Point( y_SD%Y3Mesh, u_MD%CoupledKinematics(1), MeshMapData%SDy3_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + + ! MD is destination in the mapping, so we want M_{tv_uD} and M_{ta_uD} + MD_Start_td = y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%LinStartIndx(LIN_INPUT_COL) + MD_Start_tr = MD_Start_td + u_MD%CoupledKinematics(1)%NNodes * 6 ! skip 2 fields (TranslationDisp and Orientation) with 3 components before translational velocity field + + ! translational velocity: + if (allocated(MeshMapData%SDy3_P_2_Mooring_P%dM%tv_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%SDy3_P_2_Mooring_P%dM%tv_ud, MD_Start_tr, MD_Start_td ) + end if + + ! translational acceleration: + MD_Start_tr = MD_Start_tr + u_MD%CoupledKinematics(1)%NNodes * 6 ! skip 2 fields ( TranslationVel and RotationVel) + if (allocated(MeshMapData%SDy3_P_2_Mooring_P%dM%ta_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%SDy3_P_2_Mooring_P%dM%ta_ud, MD_Start_tr, MD_Start_td ) + end if + + else if ( p_FAST%CompSub == Module_None ) THEN + ! dU^{MD}/du^{MD} + call Linearize_Point_to_Point( y_ED%PlatformPtMesh, u_MD%CoupledKinematics(1), MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + + ! MD is destination in the mapping, so we want M_{tv_uD} and M_{ta_uD} + MD_Start_td = y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%LinStartIndx(LIN_INPUT_COL) + MD_Start_tr = MD_Start_td + u_MD%CoupledKinematics(1)%NNodes * 6 ! skip 2 fields (TranslationDisp and Orientation) with 3 components before translational velocity field + + ! translational velocity: + if (allocated(MeshMapData%ED_P_2_Mooring_P%dM%tv_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_Mooring_P%dM%tv_ud, MD_Start_tr, MD_Start_td ) + end if + + ! translational acceleration: + MD_Start_tr = MD_Start_tr + u_MD%CoupledKinematics(1)%NNodes * 6 ! skip 2 fields (TranslationDisp and Orientation) with 3 components before translational velocity field + if (allocated(MeshMapData%ED_P_2_Mooring_P%dM%ta_uD )) then + call SetBlockMatrix( dUdu, MeshMapData%ED_P_2_Mooring_P%dM%ta_ud, MD_Start_tr, MD_Start_td ) + end if + + end if + + + END IF +END SUBROUTINE Linear_MD_InputSolve_du + +!---------------------------------------------------------------------------------------------------------------------------------- +!> This routine forms the dU^{MD}/dy^{ED} block of dUdy. (i.e., how do changes in the ED outputs affect +!! the MD inputs?) +SUBROUTINE Linear_MD_InputSolve_dy( p_FAST, y_FAST, u_MD, 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(MD_InputType), INTENT(INOUT) :: u_MD !< The inputs to MoorDyn + 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^{MD}/dy^{ED} block + + INTEGER(IntKi) :: ErrStat !< Error status of the operation + CHARACTER(*) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! Local variables: + + INTEGER(IntKi) :: MD_Start ! starting index of dUdy (column) where particular MD 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_MD_InputSolve_dy' + + + ErrStat = ErrID_None + ErrMsg = "" + IF (u_MD%CoupledKinematics(1)%Committed) THEN + !................................... + ! FairLead Mesh + !................................... + + MD_Start = y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%LinStartIndx(LIN_INPUT_COL) + + if ( p_FAST%CompSub == Module_SD ) THEN + ! dU^{MD}/dy^{SD} + + !!! ! This linearization was done in forming dUdu (see Linear_MD_InputSolve_du()), so we don't need to re-calculate these matrices + !!! ! while forming dUdy, too. + !!!call Linearize_Point_to_Point( y_SD%Y3Mesh, u_MD%CoupledKinematics(1), MeshMapData%SD_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + + SD_Out_Start = Indx_y_SD_Y3Mesh_Start(y_SD, y_FAST) ! start of y_SD%Y3Mesh%TranslationDisp field + call Assemble_dUdy_Motions( y_SD%Y3Mesh, u_MD%CoupledKinematics(1), MeshMapData%SDy3_P_2_Mooring_P, MD_Start, SD_Out_Start, dUdy, OnlyTranslationDisp=.false.) + + else if ( p_FAST%CompSub == Module_None ) THEN + ! dU^{MD}/dy^{ED} + !!! ! This linearization was done in forming dUdu (see Linear_MD_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_MD%CoupledKinematics, MeshMapData%ED_P_2_Mooring_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_MD%CoupledKinematics(1), MeshMapData%ED_P_2_Mooring_P, MD_Start, ED_Out_Start, dUdy, OnlyTranslationDisp=.false.) + + end if + + END IF +END SUBROUTINE Linear_MD_InputSolve_dy + !---------------------------------------------------------------------------------------------------------------------------------- !> This routine allocates the state matrices for the glue code and concatenates the module-level state matrices into @@ -4876,7 +5175,7 @@ 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(SD_OutputType), INTENT(IN ) :: y_SD !< SD outputs at t - INTEGER :: SD_Out_Start !< starting index of this mesh in ElastoDyn outputs + INTEGER :: SD_Out_Start !< starting index of this mesh in SubDyn outputs SD_Out_Start = y_FAST%Lin%Modules(MODULE_SD)%Instance(1)%LinStartIndx(LIN_OUTPUT_COL) END FUNCTION Indx_y_SD_Y1Mesh_Start @@ -4886,7 +5185,7 @@ 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 - INTEGER :: SD_Out_Start !< starting index of this mesh in ElastoDyn outputs + INTEGER :: SD_Out_Start !< starting index of this mesh in SubDyn 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 @@ -4895,9 +5194,9 @@ FUNCTION Indx_y_SD_Y3Mesh_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 - INTEGER :: SD_Out_Start !< starting index of this mesh in ElastoDyn outputs + INTEGER :: SD_Out_Start !< starting index of this mesh in SubDyn outputs - SD_Out_Start = Indx_y_SD_Y2Mesh_Start(y_SD, y_FAST) + y_SD%Y2Mesh%NNodes * 6 ! 3 forces + 3 moments at each node! skip all of the Y1Mesh data and get to the beginning of + SD_Out_Start = Indx_y_SD_Y2Mesh_Start(y_SD, y_FAST) + y_SD%Y2Mesh%NNodes * 6 ! 3 forces + 3 moments at each node! skip all of the Y2Mesh data and get to the beginning of Y3Mesh END FUNCTION Indx_y_SD_Y3Mesh_Start !---------------------------------------------------------------------------------------------------------------------------------- @@ -5283,6 +5582,7 @@ SUBROUTINE SaveOP(i, p_FAST, y_FAST, ED, BD, SrvD, AD, IfW, OpFM, HD, SD, ExtPtf CALL MAP_CopyInput (MAPp%Input(1), y_FAST%op%u_MAP(i), CtrlCode, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ELSEIF (p_FAST%CompMooring == Module_MD) THEN CALL MD_CopyContState (MD%x( STATE_CURR), y_FAST%op%x_MD(i), CtrlCode, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -5295,6 +5595,7 @@ SUBROUTINE SaveOP(i, p_FAST, y_FAST, ED, BD, SrvD, AD, IfW, OpFM, HD, SD, ExtPtf CALL MD_CopyInput (MD%Input(1), y_FAST%op%u_MD(i), CtrlCode, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ELSEIF (p_FAST%CompMooring == Module_FEAM) THEN CALL FEAM_CopyContState (FEAM%x( STATE_CURR), y_FAST%op%x_FEAM(i), CtrlCode, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -5474,8 +5775,8 @@ SUBROUTINE PerturbOP(t, iLinTime, iMode, p_FAST, y_FAST, ED, BD, SrvD, AD, IfW, do j=1,size(AD%x(STATE_CURR)%rotors(1)%BEMT%DBEMT%element,2) do i=1,size(AD%x(STATE_CURR)%rotors(1)%BEMT%DBEMT%element,1) - indx_last = indx + size(AD%x(STATE_CURR)%rotors(1)%BEMT%DBEMT%element(i,j)%vind_dot) - 1 - call GetStateAry(p_FAST, iMode, t, AD%x(STATE_CURR)%rotors(1)%BEMT%DBEMT%element(i,j)%vind_dot, y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_mag( indx : indx_last), & + indx_last = indx + size(AD%x(STATE_CURR)%rotors(1)%BEMT%DBEMT%element(i,j)%vind_1) - 1 + call GetStateAry(p_FAST, iMode, t, AD%x(STATE_CURR)%rotors(1)%BEMT%DBEMT%element(i,j)%vind_1, y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_mag( indx : indx_last), & y_FAST%Lin%Modules(ThisModule)%Instance(1)%op_x_eig_phase(indx : indx_last) ) indx = indx_last + 1 end do @@ -6155,8 +6456,25 @@ SUBROUTINE FAST_InitSteadyOutputs( psi, p_FAST, m_FAST, ED, BD, SrvD, AD, IfW, H call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) end if - !! MoorDyn - !ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN + ! MoorDyn + ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN + + allocate( MD%Output( p_FAST%LinInterpOrder+1 ), STAT = ErrStat2 ) + if (ErrStat2 /= 0) then + call SetErrStat(ErrID_Fatal, "Error allocating MD%Output.", ErrStat, ErrMsg, RoutineName ) + else + do j = 1, p_FAST%LinInterpOrder + 1 + call MD_CopyOutput(MD%y, MD%Output(j), MESH_NEWCOPY, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + end do + + call MD_CopyOutput(MD%y, MD%y_interp, MESH_NEWCOPY, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + end if + + + + !! FEAM !ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN !! OrcaFlex @@ -6332,8 +6650,17 @@ SUBROUTINE FAST_SaveOutputs( psi, p_FAST, m_FAST, ED, BD, SrvD, AD, IfW, HD, SD, CALL MAP_CopyOutput (MAPp%y, MAPp%Output(1), MESH_UPDATECOPY, Errstat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) - !! MoorDyn - !ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN + ! MoorDyn + ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN + + DO j = p_FAST%LinInterpOrder, 1, -1 + CALL MD_CopyOutput (MD%Output(j), MD%Output(j+1), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + END DO + + CALL MD_CopyOutput (MD%y, MD%Output(1), MESH_UPDATECOPY, Errstat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + !! FEAM !ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN !! OrcaFlex @@ -6405,7 +6732,7 @@ SUBROUTINE FAST_DiffInterpOutputs( psi_target, p_FAST, y_FAST, m_FAST, ED, BD, S CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) call ED_GetOP( t_global, ED%Input(1), ED%p, ED%x(STATE_CURR), ED%xd(STATE_CURR), ED%z(STATE_CURR), ED%OtherSt(STATE_CURR), & - ED%y_interp, ED%m, ErrStat2, ErrMsg2, y_op=y_FAST%Lin%Modules(Module_ED)%Instance(1)%op_y, NeedPackedOrient=.true.) + ED%y_interp, ED%m, ErrStat2, ErrMsg2, y_op=y_FAST%Lin%Modules(Module_ED)%Instance(1)%op_y, NeedTrimOP=.true.) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ! BeamDyn @@ -6417,7 +6744,7 @@ SUBROUTINE FAST_DiffInterpOutputs( psi_target, p_FAST, y_FAST, m_FAST, ED, BD, S CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) call BD_GetOP( t_global, BD%Input(1,k), BD%p(k), BD%x(k,STATE_CURR), BD%xd(k,STATE_CURR), BD%z(k,STATE_CURR), BD%OtherSt(k,STATE_CURR), & - BD%y_interp(k), BD%m(k), ErrStat2, ErrMsg2, y_op=y_FAST%Lin%Modules(Module_BD)%Instance(k)%op_y, NeedPackedOrient=.true.) + BD%y_interp(k), BD%m(k), ErrStat2, ErrMsg2, y_op=y_FAST%Lin%Modules(Module_BD)%Instance(k)%op_y, NeedTrimOP=.true.) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) END DO ! k=p_FAST%nBeams @@ -6478,7 +6805,7 @@ SUBROUTINE FAST_DiffInterpOutputs( psi_target, p_FAST, y_FAST, m_FAST, ED, BD, S 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, NeedPackedOrient=.true.) + SD%y_interp, SD%m, ErrStat2, ErrMsg2, y_op=y_FAST%Lin%Modules(Module_SD)%Instance(1)%op_y, NeedTrimOP=.true.) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) ELSE IF ( p_FAST%CompSub == Module_ExtPtfm ) THEN END IF ! SubDyn/ExtPtfm_MCKF @@ -6494,8 +6821,16 @@ SUBROUTINE FAST_DiffInterpOutputs( psi_target, p_FAST, y_FAST, m_FAST, ED, BD, S 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_interp, ErrStat2, ErrMsg2, y_op=y_FAST%Lin%Modules(Module_MAP)%Instance(1)%op_y) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - !! MoorDyn - !ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN + ! MoorDyn + ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN + + CALL MD_Output_ExtrapInterp (MD%Output, m_FAST%Lin%Psi, MD%y_interp, psi_target, ErrStat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName ) + + call MD_GetOP( t_global, MD%Input(1), MD%p, MD%x(STATE_CURR), MD%xd(STATE_CURR), MD%z(STATE_CURR), MD%OtherSt(STATE_CURR), & + MD%y_interp, MD%m, ErrStat2, ErrMsg2, y_op=y_FAST%Lin%Modules(Module_MD)%Instance(1)%op_y) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + !! FEAM !ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN !! OrcaFlex diff --git a/modules/openfast-library/src/FAST_Mods.f90 b/modules/openfast-library/src/FAST_Mods.f90 index c0215f53a..a98e8d15b 100644 --- a/modules/openfast-library/src/FAST_Mods.f90 +++ b/modules/openfast-library/src/FAST_Mods.f90 @@ -64,8 +64,6 @@ MODULE FAST_ModTypes INTEGER(IntKi), PARAMETER :: SizeJac_ED_HD = 12 - LOGICAL, PARAMETER :: GenerateAdamsModel = .FALSE. - LOGICAL, PARAMETER :: BD_Solve_Option1 = .TRUE. diff --git a/modules/openfast-library/src/FAST_Registry.txt b/modules/openfast-library/src/FAST_Registry.txt index c806cef96..f1b4e5504 100644 --- a/modules/openfast-library/src/FAST_Registry.txt +++ b/modules/openfast-library/src/FAST_Registry.txt @@ -118,6 +118,9 @@ typedef ^ FAST_ParameterType IntKi CompIce - - - "Compute ice loading (switch) { typedef ^ FAST_ParameterType IntKi MHK - - - "MHK turbine type (switch) {0=Not an MHK turbine; 1=Fixed MHK turbine; 2=Floating MHK turbine}" - typedef ^ FAST_ParameterType LOGICAL UseDWM - - - "Use the DWM module in AeroDyn" - typedef ^ FAST_ParameterType LOGICAL Linearize - - - "Linearization analysis (flag)" - +typedef ^ FAST_ParameterType IntKi WaveFieldMod - - - "Wave field handling (-) (switch) 0: use individual HydroDyn inputs without adjustment, 1: adjust wave phases based on turbine offsets from farm origin" - +typedef ^ FAST_ParameterType logical FarmIntegration - .false. - "whether this is called from FAST.Farm (or another program that doesn't want FAST to call all of the init stuff first)" - +typedef ^ FAST_ParameterType SiKi TurbinePos {3} - - "Initial position of turbine base (origin used for graphics)" m # Environmental conditions: typedef ^ FAST_ParameterType ReKi Gravity - - - "Gravitational acceleration" m/s^2 typedef ^ FAST_ParameterType ReKi AirDens - - - "Air density" kg/m^3 @@ -166,7 +169,6 @@ typedef ^ FAST_ParameterType CHARACTER(1024) VTK_OutFileRoot - "''" - "The rootn typedef ^ FAST_ParameterType INTEGER VTK_tWidth - - - "Width of number of files for leading zeros in file name format" - typedef ^ FAST_ParameterType DbKi VTK_fps - - - "number of frames per second to output VTK data" - typedef ^ FAST_ParameterType FAST_VTK_SurfaceType VTK_surface - - - "Data for VTK surface visualization" -typedef ^ FAST_ParameterType SiKi TurbinePos {3} - - "Initial position of turbine base (origin used for graphics)" m typedef ^ FAST_ParameterType CHARACTER(4) Tdesc - - - "description of turbine ID (for FAST.Farm) screen printing" # Parameters for linearization @@ -185,7 +187,7 @@ typedef ^ FAST_ParameterType LOGICAL LinOutJac - - - "Include full Jacabians in typedef ^ FAST_ParameterType LOGICAL LinOutMod - - - "Write module-level linearization output files in addition to output for full system? (flag) [unused if Linearize=False]" - typedef ^ FAST_ParameterType FAST_VTK_ModeShapeType VTK_modes - - - "Data for VTK mode-shape visualization" - -typedef ^ FAST_ParameterType LOGICAL UseSC - - - "Use Supercontroller" - +typedef ^ FAST_ParameterType LOGICAL UseSC - - - "Use Supercontroller" - typedef ^ FAST_ParameterType IntKi Lin_NumMods - - - "number of modules in the linearization" typedef ^ FAST_ParameterType IntKi Lin_ModOrder {NumModules} - - "indices that determine which order the modules are in the glue-code linearization matrix" typedef ^ FAST_ParameterType IntKi LinInterpOrder - - - "Interpolation order for CalcSteady solution" - @@ -558,6 +560,8 @@ typedef ^ ^ MD_ParameterType p - - - "Parameters" typedef ^ ^ MD_InputType u - - - "System inputs" typedef ^ ^ MD_OutputType y - - - "System outputs" typedef ^ ^ MD_MiscVarType m - - - "Misc/optimization variables" +typedef ^ ^ MD_OutputType Output {:} - - "Array of outputs associated with CalcSteady Azimuths" +typedef ^ ^ MD_OutputType y_interp - - - "interpolated system outputs for CalcSteady" typedef ^ ^ MD_InputType Input {:} - - "Array of inputs associated with InputTimes" typedef ^ ^ DbKi InputTimes {:} - - "Array of times associated with Input Array" @@ -619,13 +623,16 @@ typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_SrvD_P_P - - - "Map ElastoDyn typedef ^ FAST_ModuleMapType MeshMapType BDED_L_2_AD_L_B {:} - - "Map ElastoDyn BladeLn2Mesh point meshes OR BeamDyn BldMotion line2 meshes to AeroDyn14 InputMarkers OR AeroDyn BladeMotion line2 meshes" typedef ^ FAST_ModuleMapType MeshMapType AD_L_2_BDED_B {:} - - "Map AeroDyn14 InputMarkers or AeroDyn BladeLoad line2 meshes to ElastoDyn BladePtLoad point meshes or BeamDyn BldMotion line2 meshes" typedef ^ FAST_ModuleMapType MeshMapType BD_L_2_BD_L {:} - - "Map BeamDyn BldMotion output meshes to locations on the BD input DistrLoad mesh stored in MeshMapType%y_BD_BldMotion_4Loads (BD input and output meshes are not siblings and in fact have nodes at different locations" -# ED <-> AD (nacelle, tower, hub, blade root) +# ED <-> AD (nacelle, tower, hub, blade root, tailfin) typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_AD_P_N - - - "Map ElastoDyn Nacelle point motion mesh to AeroDyn Nacelle point motion mesh" typedef ^ FAST_ModuleMapType MeshMapType AD_P_2_ED_P_N - - - "Map AeroDyn Nacelle point load mesh to ElastoDyn nacelle point load mesh" +typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_AD_P_TF - - - "Map ElastoDyn TailFin CM point motion mesh to AeroDyn TailFin ref point motion mesh" +typedef ^ FAST_ModuleMapType MeshMapType AD_P_2_ED_P_TF - - - "Map AeroDyn TailFin ref point load mesh to ElastoDyn TailFin CM point load mesh" typedef ^ FAST_ModuleMapType MeshMapType ED_L_2_AD_L_T - - - "Map ElastoDyn TowerLn2Mesh line2 mesh to AeroDyn14 Twr_InputMarkers or AeroDyn TowerMotion line2 mesh" typedef ^ FAST_ModuleMapType MeshMapType AD_L_2_ED_P_T - - - "Map AeroDyn14 Twr_InputMarkers or AeroDyn TowerLoad line2 mesh to ElastoDyn TowerPtLoads point mesh" typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_AD_P_R {:} - - "Map ElastoDyn BladeRootMotion point meshes to AeroDyn BladeRootMotion point meshes" typedef ^ FAST_ModuleMapType MeshMapType ED_P_2_AD_P_H - - - "Map ElastoDyn HubPtMotion point mesh to AeroDyn HubMotion point mesh" +typedef ^ FAST_ModuleMapType MeshMapType AD_P_2_ED_P_H - - - "Map AeroDyn HubLoad point mesh to ElastoDyn HubPtLoad point mesh" # IceF <-> SD typedef ^ FAST_ModuleMapType MeshMapType IceF_P_2_SD_P - - - "Map IceFloe point mesh to SubDyn LMesh point mesh" typedef ^ FAST_ModuleMapType MeshMapType SDy3_P_2_IceF_P - - - "Map SubDyn y3Mesh point mesh to IceFloe point mesh" @@ -640,6 +647,8 @@ typedef ^ FAST_ModuleMapType Integer Jac_u_indx {:}{:} - - "matrix to help fill/ typedef ^ FAST_ModuleMapType MeshType u_ED_NacelleLoads - - - "copy of ED input mesh" typedef ^ FAST_ModuleMapType MeshType u_ED_PlatformPtMesh - - - "copy of ED input mesh" typedef ^ FAST_ModuleMapType MeshType u_ED_PlatformPtMesh_2 - - - "copy of ED input mesh (used only for temporary storage)" +typedef ^ FAST_ModuleMapType MeshType u_ED_PlatformPtMesh_3 - - - "copy of ED input mesh (used only for temporary storage)" +typedef ^ FAST_ModuleMapType MeshType u_ED_PlatformPtMesh_MDf - - - "copy of ED input mesh used to store loads from farm-level MD" typedef ^ FAST_ModuleMapType MeshType u_ED_TowerPtloads - - - "copy of ED input mesh" typedef ^ FAST_ModuleMapType MeshType u_ED_BladePtLoads {:} - - "copy of ED input mesh" typedef ^ FAST_ModuleMapType MeshType u_SD_TPMesh - - - "copy of SD input mesh" @@ -656,6 +665,7 @@ typedef ^ FAST_ModuleMapType MeshType y_BD_BldMotion_4Loads {:} - - "BD blade mo typedef ^ FAST_ModuleMapType MeshType u_BD_Distrload {:} - - "copy of BD DistrLoad input meshes" typedef ^ FAST_ModuleMapType MeshType u_Orca_PtfmMesh - - - "copy of Orca PtfmMesh input mesh" typedef ^ FAST_ModuleMapType MeshType u_ExtPtfm_PtfmMesh - - - "copy of ExtPtfm_MCKF PtfmMesh input mesh" +#typedef ^ FAST_ModuleMapType MeshType u_FarmMD_CoupledLoads - - - "FAST-internal copy of MoorDyn's CoupledLoads output mesh for use with shared moorings in FAST.Farm" # ..... FAST_ExternalInput data ....................................................................................................... typedef FAST FAST_ExternInputType ReKi GenTrq - - - "generator torque input from Simulink/Labview" typedef ^ FAST_ExternInputType ReKi ElecPwr - - - "electric power input from Simulink/Labview" @@ -723,7 +733,8 @@ typedef ^ FAST_ExternInitType DbKi Tmax - -1 - "External code specified Tmax" s typedef ^ FAST_ExternInitType IntKi SensorType - SensorType_None - "lidar sensor type, which should not be pulsed at the moment; this input should be replaced with a section in the InflowWind input file" - typedef ^ FAST_ExternInitType LOGICAL LidRadialVel - - - "TRUE => return radial component, FALSE => return 'x' direction estimate" - typedef ^ FAST_ExternInitType IntKi TurbineID - 0 - "ID number for turbine (used to create output file naming convention)" - -typedef ^ FAST_ExternInitType ReKi TurbinePos {3} - - "Initial position of turbine base (origin used in future for graphics)" m +typedef ^ FAST_ExternInitType ReKi TurbinePos {3} - - "Initial position of turbine base (origin used for graphics or in FAST.Farm)" m +typedef ^ FAST_ExternInitType IntKi WaveFieldMod - - - "Wave field handling (-) (switch) 0: use individual HydroDyn inputs without adjustment, 1: adjust wave phases based on turbine offsets from farm origin" - typedef ^ FAST_ExternInitType IntKi NumSC2CtrlGlob - - - "number of global controller inputs [from supercontroller]" - typedef ^ FAST_ExternInitType IntKi NumSC2Ctrl - - - "number of turbine specific controller inputs [from supercontroller]" - typedef ^ FAST_ExternInitType IntKi NumCtrl2SC - - - "number of controller outputs [to supercontroller]" - @@ -736,7 +747,7 @@ typedef ^ FAST_ExternInitType ReKi windGrid_pZero 3 - - "fixed position of the X typedef ^ FAST_ExternInitType CHARACTER(1024) RootName - - - "Root name of FAST output files (overrides normal operation)" - typedef ^ FAST_ExternInitType IntKi NumActForcePtsBlade - - - "number of actuator line force points in blade" - typedef ^ FAST_ExternInitType IntKi NumActForcePtsTower - - - "number of actuator line force points in tower" - - +typedef ^ FAST_ExternInitType logical NodeClusterType - - - "Node clustering for actuator line (0 - Uniform, 1 - Non-uniform clustered towards tip)" - # ..... FAST Turbine Data (one realization) ....................................................................................................... typedef ^ FAST_TurbineType IntKi TurbID - 1 - "Turbine ID Number" - diff --git a/modules/openfast-library/src/FAST_Solver.f90 b/modules/openfast-library/src/FAST_Solver.f90 index 364d0b78c..1f6653285 100644 --- a/modules/openfast-library/src/FAST_Solver.f90 +++ b/modules/openfast-library/src/FAST_Solver.f90 @@ -175,8 +175,8 @@ SUBROUTINE BD_InputSolve( p_FAST, BD, y_AD, u_AD, y_ED, y_SrvD, u_SrvD, MeshMapD END SUBROUTINE BD_InputSolve !---------------------------------------------------------------------------------------------------------------------------------- -!> This routine sets the inputs required for ED--using the Option 2 solve method; currently the only input not solved in this routine -!! are the fields on PlatformPtMesh and HubPtLoad, which are solved in option 1. +!> This routine sets the inputs required for ED--using the Option 2 solve method. Currently the only inputs not solved in this routine +!! are the fields on PlatformPtMesh, which are solved in Option 1. The fields on HubPtLoad are solved in both Option 2 and Option 1. SUBROUTINE ED_InputSolve( p_FAST, u_ED, y_ED, p_AD14, y_AD14, y_AD, y_SrvD, u_AD, u_SrvD, MeshMapData, ErrStat, ErrMsg ) !.................................................................................................................................. @@ -359,6 +359,7 @@ SUBROUTINE ED_InputSolve( p_FAST, u_ED, y_ED, p_AD14, y_AD14, y_AD, y_SrvD, u_AD u_ED%PtfmAddedMass = 0.0_ReKi IF ( p_FAST%CompAero == Module_AD ) THEN ! we have to do this after the nacelle loads from StrucCtrl NStC + ! Transfer AeroDyn nacelle loads to ElastoDyn. Store on intermediate mesh from MeshMapData IF ( u_AD%rotors(1)%NacelleMotion%Committed ) THEN CALL Transfer_Point_to_Point( y_AD%rotors(1)%NacelleLoad, MeshMapData%u_ED_NacelleLoads, MeshMapData%AD_P_2_ED_P_N, ErrStat2, ErrMsg2, u_AD%rotors(1)%NacelleMotion, y_ED%NacelleMotion ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -366,6 +367,23 @@ SUBROUTINE ED_InputSolve( p_FAST, u_ED, y_ED, p_AD14, y_AD14, y_AD, y_SrvD, u_AD u_ED%NacelleLoads%Force = u_ED%NacelleLoads%Force + MeshMapData%u_ED_NacelleLoads%Force u_ED%NacelleLoads%Moment = u_ED%NacelleLoads%Moment + MeshMapData%u_ED_NacelleLoads%Moment END IF + ! Transfer AeroDyn TailFin loads to ElastoDyn + IF ( u_AD%rotors(1)%TFinMotion%Committed ) THEN + CALL Transfer_Point_to_Point( y_AD%rotors(1)%TFinLoad, u_ED%TFinCMLoads, MeshMapData%AD_P_2_ED_P_TF, ErrStat2, ErrMsg2, u_AD%rotors(1)%TFinMotion, y_ED%TFinCMMotion ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END IF + END IF + + IF ( p_FAST%CompAero == Module_AD .and. p_FAST%MHK > 0 .and. .not. (p_FAST%CompElast == Module_BD .and. BD_Solve_Option1)) THEN + u_ED%HubPtLoad%Force = 0.0_ReKi + u_ED%HubPtLoad%Moment = 0.0_ReKi + IF ( u_AD%rotors(1)%HubMotion%Committed ) THEN + CALL Transfer_Point_to_Point( y_AD%rotors(1)%HubLoad, MeshMapData%u_ED_HubPtLoad, MeshMapData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2, u_AD%rotors(1)%HubMotion, y_ED%HubPtMotion ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + + u_ED%HubPtLoad%Force = u_ED%HubPtLoad%Force + MeshMapData%u_ED_HubPtLoad%Force + u_ED%HubPtLoad%Moment = u_ED%HubPtLoad%Moment + MeshMapData%u_ED_HubPtLoad%Moment + END IF END IF ! add damping in blades and tower for linearization convergence @@ -443,66 +461,24 @@ SUBROUTINE IfW_InputSolve( p_FAST, m_FAST, u_IfW, p_IfW, u_AD14, u_AD, OtherSt_A ELSEIF (p_FAST%CompAero == MODULE_AD) THEN - DO K = 1,SIZE(u_AD%rotors(1)%BladeMotion) - DO J = 1,u_AD%rotors(1)%BladeMotion(k)%Nnodes - - Node = Node + 1 - u_IfW%PositionXYZ(:,Node) = u_AD%rotors(1)%BladeMotion(k)%TranslationDisp(:,j) + u_AD%rotors(1)%BladeMotion(k)%Position(:,j) - - END DO !J = 1,p%BldNodes ! Loop through the blade nodes / elements - END DO !K = 1,p%NumBl - - DO J=1,u_AD%rotors(1)%TowerMotion%nnodes - Node = Node + 1 - u_IfW%PositionXYZ(:,Node) = u_AD%rotors(1)%TowerMotion%TranslationDisp(:,J) + u_AD%rotors(1)%TowerMotion%Position(:,J) - END DO - - if (u_AD%rotors(1)%NacelleMotion%Committed) then - Node = Node + 1 - u_IfW%PositionXYZ(:,Node) = u_AD%rotors(1)%NacelleMotion%TranslationDisp(:,1) + u_AD%rotors(1)%NacelleMotion%Position(:,1) - end if - -! if (u_AD%HubMotion%Committed) then -! Node = Node + 1 -! u_IfW%PositionXYZ(:,Node) = u_AD%HubMotion%TranslationDisp(:,1) + u_AD%HubMotion%Position(:,1) -! end if - - ! vortex points from FVW in AD15 (should be at then end, since not "rotor dependent" - if (allocated(OtherSt_AD%WakeLocationPoints)) then - do J=1,size(OtherSt_AD%WakeLocationPoints,DIM=2) - Node = Node + 1 - u_IfW%PositionXYZ(:,Node) = OtherSt_AD%WakeLocationPoints(:,J) - enddo - end if + ! Set u_IfW%PositionXYZ needed by AeroDyn (node counter will be incremented) + call AD_SetExternalWindPositions(u_AD, OtherSt_AD, u_IfW%PositionXYZ, node, errStat, errMsg) END IF + + u_IfW%HubPosition = y_ED%HubPtMotion%Position(:,1) + y_ED%HubPtMotion%TranslationDisp(:,1) + u_IfW%HubOrientation = y_ED%HubPtMotion%Orientation(:,:,1) + - CALL IfW_SetExternalInputs( p_IfW, m_FAST, y_ED, u_IfW ) - - -END SUBROUTINE IfW_InputSolve -!---------------------------------------------------------------------------------------------------------------------------------- -!> This routine sets the inputs required for InflowWind from an external source (Simulink) -SUBROUTINE IfW_SetExternalInputs( p_IfW, m_FAST, y_ED, u_IfW ) -!.................................................................................................................................. - TYPE(InflowWind_ParameterType), INTENT(IN) :: p_IfW !< InflowWind parameters - TYPE(FAST_MiscVarType), INTENT(IN) :: m_FAST !< Glue-code misc variables (including inputs from external sources like Simulink) - TYPE(ED_OutputType), INTENT(IN) :: y_ED !< The outputs of the structural dynamics module - TYPE(InflowWind_InputType), INTENT(INOUT) :: u_IfW !< InflowWind Inputs at t - - ! bjj: this is a total hack to get the lidar inputs into InflowWind. We should use a mesh to take care of this messiness (and, really this Lidar Focus should come - ! from Fortran (a scanning pattern or file-lookup inside InflowWind), not MATLAB. - - u_IfW%lidar%LidPosition = y_ED%HubPtMotion%Position(:,1) + y_ED%HubPtMotion%TranslationDisp(:,1) & ! rotor apex position (absolute) - + p_IfW%lidar%RotorApexOffsetPos ! lidar offset-from-rotor-apex position - - u_IfW%lidar%MsrPosition = m_FAST%ExternInput%LidarFocus + u_IfW%lidar%LidPosition + IF ( p_FAST%MHK==1 .or. p_FAST%MHK==2 ) THEN + u_IfW%PositionXYZ(3,:) = u_IfW%PositionXYZ(3,:) + p_FAST%WtrDpth + ENDIF +END SUBROUTINE IfW_InputSolve -END SUBROUTINE IfW_SetExternalInputs !---------------------------------------------------------------------------------------------------------------------------------- !> This routine sets the AeroDyn wind inflow inputs. SUBROUTINE AD_InputSolve_IfW( p_FAST, u_AD, y_IfW, y_OpFM, ErrStat, ErrMsg ) @@ -538,55 +514,25 @@ SUBROUTINE AD_InputSolve_IfW( p_FAST, u_AD, y_IfW, y_OpFM, ErrStat, ErrMsg ) else node = 1 end if - - - NumBl = size(u_AD%rotors(1)%InflowOnBlade,3) - Nnodes = size(u_AD%rotors(1)%InflowOnBlade,2) - - do k=1,NumBl - do j=1,Nnodes - u_AD%rotors(1)%InflowOnBlade(:,j,k) = y_IfW%VelocityUVW(:,node) - node = node + 1 - end do - end do - - if ( allocated(u_AD%rotors(1)%InflowOnTower) ) then - Nnodes = size(u_AD%rotors(1)%InflowOnTower,2) - do j=1,Nnodes - u_AD%rotors(1)%InflowOnTower(:,j) = y_IfW%VelocityUVW(:,node) - node = node + 1 - end do - end if - if (u_AD%rotors(1)%NacelleMotion%NNodes > 0) then - u_AD%rotors(1)%InflowOnNacelle(:) = y_IfW%VelocityUVW(:,node) - node = node + 1 - else - u_AD%rotors(1)%InflowOnNacelle = 0.0_ReKi - end if - -! if (u_AD%HubMotion%NNodes > 0) then -! u_AD%InflowOnHub(:) = y_IfW%VelocityUVW(:,node) -! node = node + 1 -! else -! u_AD%InflowOnHub = 0.0_ReKi -! end if - - ! vortex points from FVW in AD15 (should be at then end, since not "rotor dependent" - if ( allocated(u_AD%InflowWakeVel) ) then - Nnodes = size(u_AD%InflowWakeVel,DIM=2) - do j=1,Nnodes - u_AD%InflowWakeVel(:,j) = y_IfW%VelocityUVW(:,node) - node = node + 1 - end do - end if + ! Set the external wind from inflowwin into the AeroDyn inputs. Node counter is incremented + call AD_GetExternalWind(u_AD, y_IfW%VelocityUVW, node, errStat, errMsg) ELSEIF ( p_FAST%CompInflow == MODULE_OpFM ) THEN node = 2 !start of inputs to AD15 NumBl = size(u_AD%rotors(1)%InflowOnBlade,3) Nnodes = size(u_AD%rotors(1)%InflowOnBlade,2) - + + ! Hub -- first point + if (u_AD%rotors(1)%HubMotion%NNodes > 0) then + u_AD%rotors(1)%InflowOnHub(1) = y_OpFM%u(1) + u_AD%rotors(1)%InflowOnHub(2) = y_OpFM%v(1) + u_AD%rotors(1)%InflowOnHub(3) = y_OpFM%w(1) + else + u_AD%rotors(1)%InflowOnHub = 0.0_ReKi + end if + do k=1,NumBl do j=1,Nnodes u_AD%rotors(1)%InflowOnBlade(1,j,k) = y_OpFM%u(node) @@ -606,6 +552,7 @@ SUBROUTINE AD_InputSolve_IfW( p_FAST, u_AD, y_IfW, y_OpFM, ErrStat, ErrMsg ) end do end if + ! Nacelle if (u_AD%rotors(1)%NacelleMotion%NNodes > 0) then u_AD%rotors(1)%InflowOnNacelle(1) = y_OpFM%u(node) u_AD%rotors(1)%InflowOnNacelle(2) = y_OpFM%v(node) @@ -615,14 +562,15 @@ SUBROUTINE AD_InputSolve_IfW( p_FAST, u_AD, y_IfW, y_OpFM, ErrStat, ErrMsg ) u_AD%rotors(1)%InflowOnNacelle = 0.0_ReKi end if -! if (u_AD%HubMotion%NNodes > 0) then -! u_AD%InflowOnHub(1) = y_OpFM%u(node) -! u_AD%InflowOnHub(2) = y_OpFM%v(node) -! u_AD%InflowOnHub(3) = y_OpFM%w(node) -! node = node + 1 -! else -! u_AD%InflowOnHub = 0.0_ReKi -! end if + ! TailFin + if (u_AD%rotors(1)%TFinMotion%NNodes > 0) then + u_AD%rotors(1)%InflowOnTailFin(1) = y_OpFM%u(node) + u_AD%rotors(1)%InflowOnTailFin(2) = y_OpFM%v(node) + u_AD%rotors(1)%InflowOnTailFin(3) = y_OpFM%w(node) + node = node + 1 + else + u_AD%rotors(1)%InflowOnTailFin = 0.0_ReKi + end if ELSE @@ -711,6 +659,12 @@ SUBROUTINE AD_InputSolve_NoIfW( p_FAST, u_AD, y_SrvD, y_ED, BD, MeshMapData, Err call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) END IF + + ! Tailfin - Transfer ElastoDyn CM motion to AeroDyn ref point motion + IF (u_AD%rotors(1)%TFinMotion%Committed) THEN + CALL Transfer_Point_to_Point( y_ED%TFinCMMotion, u_AD%rotors(1)%TFinMotion, MeshMapData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + END IF @@ -733,14 +687,13 @@ SUBROUTINE AD_InputSolve_NoIfW( p_FAST, u_AD, y_SrvD, y_ED, BD, MeshMapData, Err END SUBROUTINE AD_InputSolve_NoIfW !---------------------------------------------------------------------------------------------------------------------------------- !> This routine sets the AeroDyn14 wind inflow inputs. -SUBROUTINE AD14_InputSolve_IfW( p_FAST, u_AD14, y_IfW, y_OpFM, ErrStat, ErrMsg ) +SUBROUTINE AD14_InputSolve_IfW( p_FAST, u_AD14, y_IfW, ErrStat, ErrMsg ) !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ! Passed variables TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST !< parameter FAST data TYPE(AD14_InputType), INTENT(INOUT) :: u_AD14 !< The inputs to AeroDyn14 TYPE(InflowWind_OutputType), INTENT(IN) :: y_IfW !< The outputs from InflowWind - TYPE(OpFM_OutputType), INTENT(IN) :: y_OpFM !< outputs from the OpenFOAM integration module INTEGER(IntKi) :: ErrStat !< Error status of the operation CHARACTER(*) :: ErrMsg !< Error message if ErrStat /= ErrID_None @@ -766,10 +719,6 @@ SUBROUTINE AD14_InputSolve_IfW( p_FAST, u_AD14, y_IfW, y_OpFM, ErrStat, ErrMsg ) ELSE u_AD14%InflowVelocity = y_IfW%VelocityUVW(:,:) END IF - ELSEIF ( p_FAST%CompInflow == MODULE_OpFM ) THEN - u_AD14%InflowVelocity(1,:) = y_OpFM%u(2:) - u_AD14%InflowVelocity(2,:) = y_OpFM%v(2:) - u_AD14%InflowVelocity(3,:) = y_OpFM%w(2:) ELSE u_AD14%InflowVelocity = 0.0_ReKi ! whole array END IF @@ -955,17 +904,28 @@ SUBROUTINE SrvD_InputSolve( p_FAST, m_FAST, u_SrvD, y_ED, y_IfW, y_OpFM, y_BD, y u_SrvD%WindDir = ATAN2( y_IfW%VelocityUVW(2,1), y_IfW%VelocityUVW(1,1) ) u_SrvD%HorWindV = SQRT( y_IfW%VelocityUVW(1,1)**2 + y_IfW%VelocityUVW(2,1)**2 ) + if (allocated(y_IfW%lidar%LidSpeed )) u_SrvD%LidSpeed = y_IfW%lidar%LidSpeed + if (allocated(y_IfW%lidar%MsrPositionsX)) u_SrvD%MsrPositionsX = y_IfW%lidar%MsrPositionsX + if (allocated(y_IfW%lidar%MsrPositionsY)) u_SrvD%MsrPositionsY = y_IfW%lidar%MsrPositionsY + if (allocated(y_IfW%lidar%MsrPositionsZ)) u_SrvD%MsrPositionsZ = y_IfW%lidar%MsrPositionsZ ELSEIF ( p_FAST%CompInflow == Module_OpFM ) THEN u_SrvD%WindDir = ATAN2( y_OpFM%v(1), y_OpFM%u(1) ) u_SrvD%HorWindV = SQRT( y_OpFM%u(1)**2 + y_OpFM%v(1)**2 ) + if (allocated(u_SrvD%LidSpeed )) u_SrvD%LidSpeed = 0.0 + if (allocated(u_SrvD%MsrPositionsX)) u_SrvD%MsrPositionsX = 0.0 + if (allocated(u_SrvD%MsrPositionsY)) u_SrvD%MsrPositionsY = 0.0 + if (allocated(u_SrvD%MsrPositionsz)) u_SrvD%MsrPositionsz = 0.0 ELSE ! No wind inflow u_SrvD%WindDir = 0.0 u_SrvD%HorWindV = 0.0 - + if (allocated(u_SrvD%LidSpeed )) u_SrvD%LidSpeed = 0.0 + if (allocated(u_SrvD%MsrPositionsX)) u_SrvD%MsrPositionsX = 0.0 + if (allocated(u_SrvD%MsrPositionsY)) u_SrvD%MsrPositionsY = 0.0 + if (allocated(u_SrvD%MsrPositionsz)) u_SrvD%MsrPositionsz = 0.0 ENDIF @@ -1393,8 +1353,8 @@ SUBROUTINE Transfer_ED_to_HD_SD_BD_Mooring( p_FAST, y_ED, u_HD, u_SD, u_ExtPtfm, 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' ) + CALL Transfer_Point_to_Point( y_ED%PlatformPtMesh, u_MD%CoupledKinematics(1), MeshMapData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName//'u_MD%CoupledKinematics' ) ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN ! motions: @@ -2030,6 +1990,7 @@ SUBROUTINE U_ED_HD_Residual( y_ED2, y_HD2, u_IN, U_Resid) !.................. ! Set mooring line inputs (which don't have acceleration fields) !.................. + !TODO: MoorDyn input mesh now has acceleration fields, and they are used in some uncommon cases. Is this an issue? <<< IF ( p_FAST%CompMooring == Module_MAP ) THEN @@ -2043,10 +2004,10 @@ SUBROUTINE U_ED_HD_Residual( y_ED2, y_HD2, u_IN, U_Resid) 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 Transfer_Point_to_Point( y_ED2%PlatformPtMesh, u_MD%PtFairleadDisplacement, MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL Transfer_Point_to_Point( y_ED2%PlatformPtMesh, u_MD%CoupledKinematics(1), 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, 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%CoupledLoads(1), MeshMapData%u_ED_PlatformPtMesh, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_MD%CoupledKinematics(1), 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 @@ -2064,7 +2025,14 @@ SUBROUTINE U_ED_HD_Residual( y_ED2, y_HD2, u_IN, U_Resid) MeshMapData%u_ED_PlatformPtMesh%Moment = 0.0_ReKi END IF - + + + ! add farm-level mooring loads if applicable >>> note: not yet set up for SubDyn <<< + IF (p_FAST%FarmIntegration) THEN + MeshMapData%u_ED_PlatformPtMesh%Force = MeshMapData%u_ED_PlatformPtMesh%Force + MeshMapData%u_ED_PlatformPtMesh_MDf%Force + MeshMapData%u_ED_PlatformPtMesh%Moment = MeshMapData%u_ED_PlatformPtMesh%Moment + MeshMapData%u_ED_PlatformPtMesh_MDf%Moment + END IF + ! Map motions for ServodDyn Structural control (TMD) if used and forces from the TMD to the platform IF ( p_FAST%CompServo == Module_SrvD .and. p_FAST%CompSub /= Module_SD ) THEN @@ -2161,6 +2129,7 @@ SUBROUTINE FullOpt1_InputOutputSolve( this_time, p_FAST, calcJacobian & , u_IceF, y_IceF & , u_IceD, y_IceD & , u_SrvD, y_SrvD & + , u_AD, y_AD & ! for buoyancy loads , MeshMapData , ErrStat, ErrMsg, WriteThisStep ) !.................................................................................................................................. @@ -2250,6 +2219,10 @@ SUBROUTINE FullOpt1_InputOutputSolve( this_time, p_FAST, calcJacobian & TYPE(IceD_InputType), INTENT(INOUT) :: u_IceD(:) !< IceDyn inputs (INOUT just because I don't want to use another tempoarary mesh and we'll overwrite this later) TYPE(SrvD_OutputType), INTENT(IN ) :: y_SrvD !< SrvD outputs TYPE(SrvD_InputType), INTENT(INOUT) :: u_SrvD !< SrvD inputs (INOUT just because I don't want to use another tempoarary mesh and we'll overwrite this later) + + ! AeroDyn -- for buoyancy loads on hub + TYPE(AD_OutputType), INTENT(IN ) :: y_AD !< The outputs to AeroDyn14 + TYPE(AD_InputType), INTENT(INOUT) :: u_AD !< The inputs to AeroDyn15 TYPE(FAST_ModuleMapType) , INTENT(INOUT) :: MeshMapData !< data for mapping meshes between modules INTEGER(IntKi) , INTENT( OUT) :: ErrStat !< Error status of the operation @@ -2974,10 +2947,10 @@ SUBROUTINE U_FullOpt1_Residual( y_ED2, y_SD2, y_HD2, y_BD2, y_Orca2, y_ExtPtfm2, ! 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%y3Mesh, u_MD%PtFairleadDisplacement, MeshMapData%SDy3_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL Transfer_Point_to_Point( y_SD2%y3Mesh, u_MD%CoupledKinematics(1), MeshMapData%SDy3_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 Transfer_Point_to_Point( y_ED2%PlatformPtMesh, u_MD%CoupledKinematics(1), MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) end if @@ -3031,7 +3004,7 @@ SUBROUTINE U_FullOpt1_Residual( y_ED2, y_SD2, y_HD2, y_BD2, y_Orca2, y_ExtPtfm2, IF ( p_FAST%CompElast == Module_BD .and. BD_Solve_Option1) THEN - + ! Transfer ED motions to BD inputs: call Transfer_ED_to_BD_tmp( y_ED2, MeshMapData, ErrStat2, ErrMsg2 ) ! sets MeshMapData%u_BD_RootMotion(:) CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -3047,6 +3020,14 @@ SUBROUTINE U_FullOpt1_Residual( y_ED2, y_SD2, y_HD2, y_BD2, y_Orca2, y_ExtPtfm2, MeshMapData%u_ED_HubPtLoad%Force = MeshMapData%u_ED_HubPtLoad%Force + MeshMapData%u_ED_HubPtLoad_2%Force MeshMapData%u_ED_HubPtLoad%Moment = MeshMapData%u_ED_HubPtLoad%Moment + MeshMapData%u_ED_HubPtLoad_2%Moment end do + IF ( p_FAST%CompAero == Module_AD .and. p_FAST%MHK > 0) THEN + IF ( u_AD%rotors(1)%HubMotion%Committed ) THEN + CALL Transfer_Point_to_Point( y_AD%rotors(1)%HubLoad, MeshMapData%u_ED_HubPtLoad_2, MeshMapData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2, u_AD%rotors(1)%HubMotion, y_ED2%HubPtMotion ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + MeshMapData%u_ED_HubPtLoad%Force = MeshMapData%u_ED_HubPtLoad%Force + MeshMapData%u_ED_HubPtLoad_2%Force + MeshMapData%u_ED_HubPtLoad%Moment = MeshMapData%u_ED_HubPtLoad%Moment + MeshMapData%u_ED_HubPtLoad_2%Moment + END IF + END IF END IF @@ -3261,13 +3242,13 @@ SUBROUTINE U_FullOpt1_Residual( y_ED2, y_SD2, y_HD2, y_BD2, y_Orca2, y_ExtPtfm2, ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN 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%Y3Mesh ) !u_MD and y_SD contain the displacements needed for moment calculations + CALL Transfer_Point_to_Point( y_MD%CoupledLoads(1), MeshMapData%u_SD_LMesh_2, MeshMapData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2, u_MD%CoupledKinematics(1), y_SD2%Y3Mesh ) !u_MD and y_SD contain the displacements needed for moment calculations CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName) 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 Transfer_Point_to_Point( y_MD%CoupledLoads(1), MeshMapData%u_ED_PlatformPtMesh_2, MeshMapData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, u_MD%CoupledKinematics(1), 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 @@ -3296,7 +3277,14 @@ SUBROUTINE U_FullOpt1_Residual( y_ED2, y_SD2, y_HD2, y_BD2, y_Orca2, y_ExtPtfm2, 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 - + + + ! add farm-level mooring loads if applicable + IF (p_FAST%FarmIntegration) THEN + MeshMapData%u_ED_PlatformPtMesh%Force = MeshMapData%u_ED_PlatformPtMesh%Force + MeshMapData%u_ED_PlatformPtMesh_MDf%Force + MeshMapData%u_ED_PlatformPtMesh%Moment = MeshMapData%u_ED_PlatformPtMesh%Moment + MeshMapData%u_ED_PlatformPtMesh_MDf%Moment + END IF + ! Map the forces from the platform mounted TMD (from ServoDyn) to the platform reference point IF ( p_FAST%CompServo == Module_SrvD .and. p_FAST%CompSub /= Module_SD .and. allocated(y_SrvD%SStCLoadMesh)) THEN @@ -3327,6 +3315,7 @@ END SUBROUTINE U_FullOpt1_Residual !............................................................................................................................... SUBROUTINE CleanUp() INTEGER(IntKi) :: ErrStat3 ! The error identifier (ErrStat) + INTEGER(IntKi) :: nb CHARACTER(ErrMsgLen) :: ErrMsg3 ! The error message (ErrMsg) INTEGER(IntKi) :: nb_local @@ -4095,6 +4084,8 @@ SUBROUTINE ResetRemapFlags(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp ED%Input( 1)%NacelleLoads%RemapFlag = .FALSE. ED%y%NacelleMotion%RemapFlag = .FALSE. + ED%Input( 1)%TFinCMLoads%RemapFlag = .FALSE. + ED%y%TFinCMMotion%RemapFlag = .FALSE. ED%Input( 1)%HubPtLoad%RemapFlag = .FALSE. ED%y%HubPtMotion%RemapFlag = .FALSE. @@ -4124,8 +4115,11 @@ SUBROUTINE ResetRemapFlags(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp AD14%y%Twr_OutputLoads%RemapFlag = .FALSE. END IF ELSEIF ( p_FAST%CompAero == Module_AD ) THEN - - AD%Input(1)%rotors(1)%HubMotion%RemapFlag = .FALSE. + + IF (AD%Input(1)%rotors(1)%HubMotion%Committed) THEN + AD%Input(1)%rotors(1)%HubMotion%RemapFlag = .FALSE. + AD%y%rotors(1)%HubLoad%RemapFlag = .FALSE. + END IF IF (AD%Input(1)%rotors(1)%TowerMotion%Committed) THEN AD%Input(1)%rotors(1)%TowerMotion%RemapFlag = .FALSE. @@ -4139,6 +4133,11 @@ SUBROUTINE ResetRemapFlags(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp AD%Input(1)%rotors(1)%NacelleMotion%RemapFlag = .FALSE. AD%y%rotors(1)%NacelleLoad%RemapFlag = .FALSE. END IF + + IF (AD%Input(1)%rotors(1)%TFinMotion%Committed) THEN + AD%Input(1)%rotors(1)%TFinMotion%RemapFlag = .FALSE. + AD%y%rotors(1)%TFinLoad%RemapFlag = .FALSE. + END IF DO k=1,SIZE(AD%Input(1)%rotors(1)%BladeMotion) AD%Input(1)%rotors(1)%BladeRootMotion(k)%RemapFlag = .FALSE. @@ -4229,8 +4228,8 @@ SUBROUTINE ResetRemapFlags(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, MAPp MAPp%Input(1)%PtFairDisplacement%RemapFlag = .FALSE. MAPp%y%PtFairleadLoad%RemapFlag = .FALSE. ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN - MD%Input(1)%PtFairleadDisplacement%RemapFlag = .FALSE. - MD%y%PtFairleadLoad%RemapFlag = .FALSE. + MD%Input(1)%CoupledKinematics(1)%RemapFlag = .FALSE. + MD%y%CoupledLoads(1)%RemapFlag = .FALSE. ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN FEAM%Input(1)%PtFairleadDisplacement%RemapFlag = .FALSE. FEAM%y%PtFairleadLoad%RemapFlag = .FALSE. @@ -4551,9 +4550,16 @@ SUBROUTINE InitModuleMappings(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, M END DO - ! Hub point mesh - CALL MeshMapCreate( ED%y%HubPtMotion, AD%Input(1)%rotors(1)%HubMotion, MeshMapData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ED_2_AD_HubMotion' ) + ! Hub point mesh: + IF ( AD%Input(1)%rotors(1)%HubMotion%Committed ) THEN + CALL MeshMapCreate( ED%y%HubPtMotion, AD%Input(1)%rotors(1)%HubMotion, MeshMapData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ED_2_AD_HubMotion' ) + CALL MeshMapCreate( AD%y%rotors(1)%HubLoad, ED%Input(1)%HubPtLoad, MeshMapData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':AD_2_ED_HubLoad' ) + + CALL MeshCopy( ED%Input(1)%HubPtLoad, MeshMapData%u_ED_HubPtLoad, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_ED_HubPtLoad' ) + END IF ! Tower mesh: @@ -4578,6 +4584,14 @@ SUBROUTINE InitModuleMappings(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, M CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_ED_NacelleLoads' ) endif endif + + ! Tailfin mesh: + if ( AD%Input(1)%rotors(1)%TFinMotion%Committed ) then + CALL MeshMapCreate( ED%y%TFinCMMotion, AD%Input(1)%rotors(1)%TFinMotion, MeshMapData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ED_2_AD_TailFinMotion' ) + CALL MeshMapCreate( AD%y%rotors(1)%TFinLoad, ED%Input(1)%TFinCMLoads, MeshMapData%AD_P_2_ED_P_TF, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':AD_2_ED_TailFinLoads' ) + endif IF ( p_FAST%CompElast == Module_ED ) then @@ -4765,18 +4779,18 @@ SUBROUTINE InitModuleMappings(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, M ! 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 MeshMapCreate( MD%y%CoupledLoads(1), 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%y3Mesh, MD%Input(1)%PtFairleadDisplacement, MeshMapData%SDy3_P_2_Mooring_P, ErrStat2, ErrMsg2 ) + CALL MeshMapCreate( SD%y%y3Mesh, MD%Input(1)%CoupledKinematics(1), MeshMapData%SDy3_P_2_Mooring_P, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':SDy3_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 MeshMapCreate( MD%y%CoupledLoads(1), 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 MeshMapCreate( PlatformMotion, MD%Input(1)%CoupledKinematics(1), 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 @@ -4891,15 +4905,28 @@ SUBROUTINE InitModuleMappings(p_FAST, ED, BD, AD14, AD, HD, SD, ExtPtfm, SrvD, M .or. p_FAST%CompMooring == Module_Orca) THEN ! Temporary meshes for transfering inputs to ED, HD, BD, Orca, and SD - CALL MeshCopy ( ED%Input(1)%HubPtLoad, MeshMapData%u_ED_HubPtLoad, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_ED_HubPtLoad' ) - + CALL MeshCopy( ED%Input(1)%HubPtLoad, MeshMapData%u_ED_HubPtLoad, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_ED_HubPtLoad' ) + CALL MeshCopy ( ED%Input(1)%PlatformPtMesh, MeshMapData%u_ED_PlatformPtMesh, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_ED_PlatformPtMesh' ) CALL MeshCopy ( ED%Input(1)%PlatformPtMesh, MeshMapData%u_ED_PlatformPtMesh_2, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_ED_PlatformPtMesh_2' ) + CALL MeshCopy ( ED%Input(1)%PlatformPtMesh, MeshMapData%u_ED_PlatformPtMesh_3, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_ED_PlatformPtMesh_3' ) + + ! for now, setting up this additional load mesh for farm-level MD loads if in FAST.Farm (@mhall TODO: add more checks/handling) <<< + if (p_FAST%FarmIntegration) then + CALL MeshCopy ( ED%Input(1)%PlatformPtMesh, MeshMapData%u_ED_PlatformPtMesh_MDf, MESH_NEWCOPY, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_ED_PlatformPtMesh_MDf' ) + + ! need to initialize to zero? + MeshMapData%u_ED_PlatformPtMesh_MDf%Force = 0.0_ReKi + MeshMapData%u_ED_PlatformPtMesh_MDf%Moment = 0.0_ReKi + end if + IF ( p_FAST%CompElast == Module_BD ) THEN @@ -5096,7 +5123,7 @@ SUBROUTINE CalcOutputs_And_SolveForInputs( n_t_global, this_time, this_state, ca CALL Transfer_Point_to_Point( SD%y%y3Mesh, MAPp%Input(1)%PtFairDisplacement, MeshMapData%SDy3_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%y3Mesh, MD%Input(1)%PtFairleadDisplacement, MeshMapData%SDy3_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL Transfer_Point_to_Point( SD%y%y3Mesh, MD%Input(1)%CoupledKinematics(1), MeshMapData%SDy3_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%y3Mesh, FEAM%Input(1)%PtFairleadDisplacement, MeshMapData%SDy3_P_2_Mooring_P, ErrStat, ErrMsg ) @@ -5105,7 +5132,7 @@ SUBROUTINE CalcOutputs_And_SolveForInputs( n_t_global, this_time, this_state, ca 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, SrvD, MeshMapData, ErrStat2, ErrMsg2, WriteThisStep) + CALL SolveOption1(this_time, this_state, calcJacobian, p_FAST, ED, BD, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, SrvD, AD, MeshMapData, ErrStat2, ErrMsg2, WriteThisStep) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -5118,7 +5145,7 @@ SUBROUTINE CalcOutputs_And_SolveForInputs( n_t_global, this_time, this_state, ca ! because we're not calling InflowWind_CalcOutput or getting new values from OpenFOAM, ! this probably can be skipped - CALL AD14_InputSolve_IfW( p_FAST, AD14%Input(1), IfW%y, OpFM%y, ErrStat2, ErrMsg2 ) + CALL AD14_InputSolve_IfW( p_FAST, AD14%Input(1), IfW%y, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSEIF ( p_FAST%CompAero == Module_AD ) THEN @@ -5141,7 +5168,7 @@ SUBROUTINE CalcOutputs_And_SolveForInputs( n_t_global, this_time, this_state, ca ! OpenFOAM is the driver and it sets these inputs outside of this solve; the OpenFOAM inputs and outputs thus don't change ! in this scenario until OpenFOAM takes another step **this is a source of error, but it is the way the OpenFOAM-FAST7 coupling ! works, so I'm not going to spend time that I don't have now to fix it** - CALL OpFM_SetInputs( p_FAST, AD14%p, AD14%Input(1), AD14%y, AD%Input(1), AD%y, ED%y, SrvD%y, OpFM, ErrStat2, ErrMsg2 ) + CALL OpFM_SetInputs( p_FAST, AD%Input(1), AD%y, SrvD%y, OpFM, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) END IF @@ -5168,7 +5195,7 @@ END SUBROUTINE CalcOutputs_And_SolveForInputs !---------------------------------------------------------------------------------------------------------------------------------- !> This routine implements the "option 1" solve for all inputs with direct links to HD, SD, ExtPtfm, MAP, OrcaFlex interface, and the ED !! platform reference point. Also in solve option 1 are the BD-ED blade root coupling. -SUBROUTINE SolveOption1(this_time, this_state, calcJacobian, p_FAST, ED, BD, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, SrvD, MeshMapData, ErrStat, ErrMsg, WriteThisStep ) +SUBROUTINE SolveOption1(this_time, this_state, calcJacobian, p_FAST, ED, BD, HD, SD, ExtPtfm, MAPp, FEAM, MD, Orca, IceF, IceD, SrvD, AD, MeshMapData, ErrStat, ErrMsg, WriteThisStep ) !............................................................................................................................... REAL(DbKi) , intent(in ) :: this_time !< The current simulation time (actual or time of prediction) INTEGER(IntKi) , intent(in ) :: this_state !< Index into the state array (current or predicted states) @@ -5189,6 +5216,7 @@ SUBROUTINE SolveOption1(this_time, this_state, calcJacobian, p_FAST, ED, BD, HD, TYPE(OrcaFlex_Data), INTENT(INOUT) :: Orca !< OrcaFlex interface data TYPE(IceFloe_Data), INTENT(INOUT) :: IceF !< IceFloe data TYPE(IceDyn_Data), INTENT(INOUT) :: IceD !< All the IceDyn data used in time-step loop + TYPE(AeroDyn_Data), INTENT(INOUT) :: AD !< AeroDyn data TYPE(FAST_ModuleMapType), INTENT(INOUT) :: MeshMapData !< Data for mapping between modules @@ -5278,6 +5306,7 @@ SUBROUTINE SolveOption1(this_time, this_state, calcJacobian, p_FAST, ED, BD, HD, , IceF%Input(1), IceF%y & , IceD%Input(1,:), IceD%y & ! bjj: I don't really want to make temp copies of input types. perhaps we should pass the whole Input() structure? (likewise for BD)... , SrvD%Input(1), SrvD%y & + , AD%Input(1), AD%y & , MeshMapData , ErrStat2, ErrMsg2, WriteThisStep ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -5313,10 +5342,10 @@ SUBROUTINE SolveOption1(this_time, this_state, calcJacobian, p_FAST, ED, BD, HD, ! 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%y3Mesh, MD%Input(1)%PtFairleadDisplacement, MeshMapData%SDy3_P_2_Mooring_P, ErrStat, ErrMsg ) + CALL Transfer_Point_to_Point( SD%y%y3Mesh, MD%Input(1)%CoupledKinematics(1), MeshMapData%SDy3_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 Transfer_Point_to_Point( ED%y%PlatformPtMesh, MD%Input(1)%CoupledKinematics(1), MeshMapData%ED_P_2_Mooring_P, ErrStat, ErrMsg ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) endif @@ -5543,6 +5572,10 @@ SUBROUTINE SolveOption2c_Inp2AD_SrvD(this_time, this_state, p_FAST, m_FAST, ED, IF (p_FAST%CompInflow == Module_IfW) THEN + ! get Lidar position directly from hub mesh (may map meshes later) + IfW%Input%lidar%HubDisplacementX = ED%y%HubPtMotion%TranslationDisp(1,1) + IfW%Input%lidar%HubDisplacementY = ED%y%HubPtMotion%TranslationDisp(2,1) + IfW%Input%lidar%HubDisplacementZ = ED%y%HubPtMotion%TranslationDisp(3,1) CALL InflowWind_CalcOutput( this_time, IfW%Input(1), IfW%p, IfW%x(this_state), IfW%xd(this_state), IfW%z(this_state), & IfW%OtherSt(this_state), IfW%y, IfW%m, ErrStat2, ErrMsg2 ) @@ -5551,7 +5584,7 @@ SUBROUTINE SolveOption2c_Inp2AD_SrvD(this_time, this_state, p_FAST, m_FAST, ED, ! ! OpenFOAM is the driver and it computes outputs outside of this solve; the OpenFOAM inputs and outputs thus don't change ! ! in this scenario until OpenFOAM takes another step **this is a source of error, but it is the way the OpenFOAM-FAST7 coupling ! ! works, so I'm not going to spend time that I don't have now to fix it** - ! CALL OpFM_SetInputs( p_FAST, AD14%p, AD14%Input(1), AD14%y, AD%Input(1), AD%y, ED%y, SrvD%y, OpFM, ErrStat2, ErrMsg2 ) + ! CALL OpFM_SetInputs( p_FAST, AD%Input(1), AD%y, ED%y, SrvD%y, OpFM, ErrStat2, ErrMsg2 ) ! CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! CALL OpFM_SetWriteOutput(OpFM) @@ -5559,7 +5592,7 @@ SUBROUTINE SolveOption2c_Inp2AD_SrvD(this_time, this_state, p_FAST, m_FAST, ED, IF ( p_FAST%CompAero == Module_AD14 ) THEN - CALL AD14_InputSolve_IfW( p_FAST, AD14%Input(1), IfW%y, OpFM%y, ErrStat2, ErrMsg2 ) + CALL AD14_InputSolve_IfW( p_FAST, AD14%Input(1), IfW%y, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ELSE IF ( p_FAST%CompAero == Module_AD ) THEN @@ -5662,7 +5695,7 @@ SUBROUTINE SolveOption2(this_time, this_state, p_FAST, m_FAST, ED, BD, AD14, AD, ! in this scenario until OpenFOAM takes another step **this is a source of error, but it is the way the OpenFOAM-FAST7 coupling ! works, so I'm not going to spend time that I don't have now to fix it** ! note that I'm setting these inputs AFTER the call to ServoDyn so OpenFOAM gets all the inputs updated at the same step - CALL OpFM_SetInputs( p_FAST, AD14%p, AD14%Input(1), AD14%y, AD%Input(1), AD%y, ED%y, SrvD%y, OpFM, ErrStat2, ErrMsg2 ) + CALL OpFM_SetInputs( p_FAST, AD%Input(1), AD%y, SrvD%y, OpFM, ErrStat2, ErrMsg2 ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) CALL OpFM_SetWriteOutput(OpFM) diff --git a/modules/openfast-library/src/FAST_Subs.f90 b/modules/openfast-library/src/FAST_Subs.f90 index 3a6fb654d..2f99a720c 100644 --- a/modules/openfast-library/src/FAST_Subs.f90 +++ b/modules/openfast-library/src/FAST_Subs.f90 @@ -23,6 +23,7 @@ MODULE FAST_Subs USE FAST_Solver USE FAST_Linear + USE Waves, ONLY : WaveGrid_n USE SC_DataEx USE VersionInfo @@ -32,7 +33,7 @@ MODULE FAST_Subs !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! INITIALIZATION ROUTINES !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -!> a wrapper routine to call FAST_Initialize a the full-turbine simulation level (makes easier to write top-level driver) +!> a wrapper routine to call FAST_Initialize at the full-turbine simulation level (makes easier to write top-level driver) SUBROUTINE FAST_InitializeAll_T( t_initial, TurbID, Turbine, ErrStat, ErrMsg, InFile, ExternInitData ) REAL(DbKi), INTENT(IN ) :: t_initial !< initial time @@ -118,6 +119,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, INTEGER(IntKi) :: IceDim ! dimension we're pre-allocating for number of IceDyn legs/instances INTEGER(IntKi) :: I ! generic loop counter INTEGER(IntKi) :: k ! blade loop counter + INTEGER(IntKi) :: nNodes ! temp var for OpFM coupling logical :: CallStart @@ -190,10 +192,12 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, END IF ! ... Open and read input files ... - ! also, set turbine reference position for graphics output + ! also, set applicable farm paramters and turbine reference position also for graphics output p_FAST%UseSC = .FALSE. if (PRESENT(ExternInitData)) then + p_FAST%FarmIntegration = ExternInitData%FarmIntegration p_FAST%TurbinePos = ExternInitData%TurbinePos + p_FAST%WaveFieldMod = ExternInitData%WaveFieldMod if( (ExternInitData%NumSC2CtrlGlob .gt. 0) .or. (ExternInitData%NumSC2Ctrl .gt. 0) .or. (ExternInitData%NumCtrl2SC .gt. 0)) then p_FAST%UseSC = .TRUE. end if @@ -206,6 +210,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, else p_FAST%TurbinePos = 0.0_ReKi + p_FAST%WaveFieldMod = 0 CALL FAST_Init( p_FAST, m_FAST, y_FAST, t_initial, InputFile, ErrStat2, ErrMsg2 ) ! We have the name of the input file from somewhere else (e.g. Simulink) end if @@ -244,6 +249,9 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_ED%Gravity = p_FAST%Gravity + Init%InData_ED%MHK = p_FAST%MHK + Init%InData_ED%WtrDpth = p_FAST%WtrDpth + CALL ED_Init( Init%InData_ED, ED%Input(1), ED%p, ED%x(STATE_CURR), ED%xd(STATE_CURR), ED%z(STATE_CURR), ED%OtherSt(STATE_CURR), & ED%y, ED%m, p_FAST%dt_module( MODULE_ED ), Init%OutData_ED, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) @@ -479,7 +487,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_AD%MHK = p_FAST%MHK if ( p_FAST%MHK == 0 ) then Init%InData_AD%defFldDens = p_FAST%AirDens - elseif ( p_FAST%MHK == 1 ) then + elseif ( p_FAST%MHK == 1 .or. p_FAST%MHK == 2 ) then Init%InData_AD%defFldDens = p_FAST%WtrDens end if Init%InData_AD%defKinVisc = p_FAST%KinVisc @@ -494,6 +502,8 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_AD%rotors(1)%HubOrientation = ED%y%HubPtMotion%RefOrientation(:,:,1) Init%InData_AD%rotors(1)%NacellePosition = ED%y%NacelleMotion%Position(:,1) Init%InData_AD%rotors(1)%NacelleOrientation = ED%y%NacelleMotion%RefOrientation(:,:,1) + ! Note: not passing tailfin position and orientation at init + Init%InData_AD%rotors(1)%AeroProjMod = APM_BEM_NoSweepPitchTwist do k=1,NumBl Init%InData_AD%rotors(1)%BladeRootPosition(:,k) = ED%y%BladeRootMotion(k)%Position(:,1) @@ -553,33 +563,36 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_IfW%RootName = TRIM(p_FAST%OutFileRoot)//'.'//TRIM(y_FAST%Module_Abrev(Module_IfW)) Init%InData_IfW%UseInputFile = .TRUE. Init%InData_IfW%FixedWindFileRootName = .FALSE. + Init%InData_IfW%OutputAccel = p_FAST%MHK > 0 + + Init%InData_IfW%MHK = p_FAST%MHK + Init%InData_IfW%WtrDpth = p_FAST%WtrDpth Init%InData_IfW%NumWindPoints = 0 IF ( p_FAST%CompServo == Module_SrvD ) Init%InData_IfW%NumWindPoints = Init%InData_IfW%NumWindPoints + 1 IF ( p_FAST%CompAero == Module_AD14 ) THEN Init%InData_IfW%NumWindPoints = Init%InData_IfW%NumWindPoints + NumBl * AD14%Input(1)%InputMarkers(1)%NNodes + AD14%Input(1)%Twr_InputMarkers%NNodes ELSEIF ( p_FAST%CompAero == Module_AD ) THEN - ! Blade - DO k=1,NumBl - Init%InData_IfW%NumWindPoints = Init%InData_IfW%NumWindPoints + AD%Input(1)%rotors(1)%BladeMotion(k)%NNodes - END DO - ! Tower - Init%InData_IfW%NumWindPoints = Init%InData_IfW%NumWindPoints + AD%Input(1)%rotors(1)%TowerMotion%NNodes - ! Nacelle - if (AD%Input(1)%rotors(1)%NacelleMotion%Committed) then - Init%InData_IfW%NumWindPoints = Init%InData_IfW%NumWindPoints + AD%Input(1)%rotors(1)%NacelleMotion%NNodes ! 1 point - endif - ! Wake + ! Number of Wind points from AeroDyn, see AeroDyn.f90 + Init%InData_IfW%NumWindPoints = Init%InData_IfW%NumWindPoints + AD_NumWindPoints(AD%Input(1), AD%OtherSt(STATE_CURR)) + ! Wake -- we allow the wake positions to exceed the wind box if (allocated(AD%OtherSt(STATE_CURR)%WakeLocationPoints)) then - Init%InData_IfW%NumWindPoints = Init%InData_IfW%NumWindPoints + size(AD%OtherSt(STATE_CURR)%WakeLocationPoints,DIM=2) - end if - + Init%InData_IfW%BoxExceedAllowF = .true. + Init%InData_IfW%BoxExceedAllowIdx = min(Init%InData_IfW%BoxExceedAllowIdx, AD_BoxExceedPointsIdx(AD%Input(1), AD%OtherSt(STATE_CURR))) + endif END IF ! lidar Init%InData_IfW%lidar%Tmax = p_FAST%TMax Init%InData_IfW%lidar%HubPosition = ED%y%HubPtMotion%Position(:,1) + Init%InData_IfW%lidar%HubPosition = ED%y%HubPtMotion%Position(:,1) + if ( p_FAST%CompElast == Module_BD ) then + Init%InData_IfW%RadAvg = TwoNorm(BD%y(1)%BldMotion%Position(:,1) - BD%y(1)%BldMotion%Position(:,BD%y(1)%BldMotion%Nnodes)) + else + Init%InData_IfW%RadAvg = Init%OutData_ED%BladeLength + end if + IF ( PRESENT(ExternInitData) ) THEN Init%InData_IfW%Use4Dext = ExternInitData%FarmIntegration @@ -588,14 +601,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_IfW%FDext%delta = ExternInitData%windGrid_delta Init%InData_IfW%FDext%pZero = ExternInitData%windGrid_pZero end if - - ! bjj: these lidar inputs should come from an InflowWind input file; I'm hard coding them here for now - Init%InData_IfW%lidar%SensorType = ExternInitData%SensorType - Init%InData_IfW%lidar%LidRadialVel = ExternInitData%LidRadialVel - Init%InData_IfW%lidar%RotorApexOffsetPos = 0.0 - Init%InData_IfW%lidar%NumPulseGate = 0 ELSE - Init%InData_IfW%lidar%SensorType = SensorType_None Init%InData_IfW%Use4Dext = .false. END IF @@ -625,6 +631,34 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL Cleanup() RETURN END IF + + IF ( p_FAST%CompServo == Module_SrvD ) THEN !assign the number of gates to ServD + if (allocated(IfW%y%lidar%LidSpeed)) then ! make sure we have the array allocated before setting it + CALL AllocAry(Init%InData_SrvD%LidSpeed, size(IfW%y%lidar%LidSpeed), 'Init%InData_SrvD%LidSpeed', errStat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + Init%InData_SrvD%LidSpeed = IfW%y%lidar%LidSpeed + endif + if (allocated(IfW%y%lidar%MsrPositionsX)) then ! make sure we have the array allocated before setting it + CALL AllocAry(Init%InData_SrvD%MsrPositionsX, size(IfW%y%lidar%MsrPositionsX), 'Init%InData_SrvD%MsrPositionsX', errStat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + Init%InData_SrvD%MsrPositionsX = IfW%y%lidar%MsrPositionsX + endif + if (allocated(IfW%y%lidar%MsrPositionsY)) then ! make sure we have the array allocated before setting it + CALL AllocAry(Init%InData_SrvD%MsrPositionsY, size(IfW%y%lidar%MsrPositionsY), 'Init%InData_SrvD%MsrPositionsY', errStat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + Init%InData_SrvD%MsrPositionsY = IfW%y%lidar%MsrPositionsY + endif + if (allocated(IfW%y%lidar%MsrPositionsZ)) then ! make sure we have the array allocated before setting it + CALL AllocAry(Init%InData_SrvD%MsrPositionsZ, size(IfW%y%lidar%MsrPositionsZ), 'Init%InData_SrvD%MsrPositionsZ', errStat2, ErrMsg2) + CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + Init%InData_SrvD%MsrPositionsZ = IfW%y%lidar%MsrPositionsZ + endif + Init%InData_SrvD%SensorType = IfW%p%lidar%SensorType + Init%InData_SrvD%NumBeam = IfW%p%lidar%NumBeam + Init%InData_SrvD%NumPulseGate = IfW%p%lidar%NumPulseGate + Init%InData_SrvD%PulseSpacing = IfW%p%lidar%PulseSpacing + END IF + ELSEIF ( p_FAST%CompInflow == Module_OpFM ) THEN @@ -636,20 +670,29 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, CALL Cleanup() RETURN END IF - Init%InData_OpFM%BladeLength = Init%OutData_ED%BladeLength - Init%InData_OpFM%TowerHeight = Init%OutData_ED%TowerHeight - Init%InData_OpFM%TowerBaseHeight = Init%OutData_ED%TowerBaseHeight - ALLOCATE(Init%InData_OpFM%StructBldRNodes( SIZE(Init%OutData_ED%BldRNodes)), STAT=ErrStat2) - Init%InData_OpFM%StructBldRNodes(:) = Init%OutData_ED%BldRNodes(:) - ALLOCATE(Init%InData_OpFM%StructTwrHNodes( SIZE(Init%OutData_ED%TwrHNodes)), STAT=ErrStat2) - Init%InData_OpFM%StructTwrHNodes(:) = Init%OutData_ED%TwrHNodes(:) + ! get blade and tower info from AD. Assumption made that all blades have same spanwise characteristics + Init%InData_OpFM%BladeLength = Init%OutData_AD%rotors(1)%BladeProps(1)%BlSpn(Init%OutData_AD%rotors(1)%BladeProps(1)%NumBlNds) + if (allocated(Init%OutData_AD%rotors(1)%TwrElev)) then + Init%InData_OpFM%TowerHeight = Init%OutData_AD%rotors(1)%TwrElev(SIZE(Init%OutData_AD%rotors(1)%TwrElev)) - Init%OutData_AD%rotors(1)%TwrElev(1) ! TwrElev is based on ground or MSL. Need flexible tower length and first node + Init%InData_OpFM%TowerBaseHeight = Init%OutData_AD%rotors(1)%TwrElev(1) + ALLOCATE(Init%InData_OpFM%StructTwrHNodes( SIZE(Init%OutData_AD%rotors(1)%TwrElev)), STAT=ErrStat2) + Init%InData_OpFM%StructTwrHNodes(:) = Init%OutData_AD%rotors(1)%TwrElev(:) + else + Init%InData_OpFM%TowerHeight = 0.0_ReKi + Init%InData_OpFM%TowerBaseHeight = 0.0_ReKi + endif + ALLOCATE(Init%InData_OpFM%StructBldRNodes(Init%OutData_AD%rotors(1)%BladeProps(1)%NumBlNds), STAT=ErrStat2) + Init%InData_OpFM%StructBldRNodes(:) = Init%OutData_AD%rotors(1)%BladeProps(1)%BlSpn(:) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal,"Error allocating OpFM%InitInput.",ErrStat,ErrMsg,RoutineName) CALL Cleanup() RETURN END IF + + !Set node clustering type + Init%InData_OpFM%NodeClusterType = ExternInitData%NodeClusterType ! set up the data structures for integration with OpenFOAM - CALL Init_OpFM( Init%InData_OpFM, p_FAST, AirDens, AD14%Input(1), AD%Input(1), Init%OutData_AD, AD%y, ED%y, OpFM, Init%OutData_OpFM, ErrStat2, ErrMsg2 ) + CALL Init_OpFM( Init%InData_OpFM, p_FAST, AirDens, AD%Input(1), Init%OutData_AD, AD%y, OpFM, Init%OutData_OpFM, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF (ErrStat >= AbortErrLev) THEN @@ -741,7 +784,8 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, Init%InData_HD%hasIce = p_FAST%CompIce /= Module_None Init%InData_HD%Linearize = p_FAST%Linearize - ! if wave field needs an offset, modify these values (added at request of SOWFA developers): + ! these values support wave field handling + Init%InData_HD%WaveFieldMod = p_FAST%WaveFieldMod Init%InData_HD%PtfmLocationX = p_FAST%TurbinePos(1) Init%InData_HD%PtfmLocationY = p_FAST%TurbinePos(2) @@ -946,14 +990,28 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, ! initialize MoorDyn ! ........................ ELSEIF (p_FAST%CompMooring == Module_MD) THEN + + ! some new allocations needed with version that's compatible with farm-level use + ALLOCATE( Init%InData_MD%PtfmInit(6,1), Init%InData_MD%TurbineRefPos(3,1), STAT = ErrStat2 ) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal,"Error allocating MoorDyn PtfmInit and TurbineRefPos initialization inputs.",ErrStat,ErrMsg,RoutineName) + CALL Cleanup() + RETURN + END IF Init%InData_MD%FileName = p_FAST%MooringFile ! This needs to be set according to what is in the FAST input file. Init%InData_MD%RootName = p_FAST%OutFileRoot - Init%InData_MD%PtfmInit = Init%OutData_ED%PlatformPos !ED%x(STATE_CURR)%QT(1:6) ! initial position of the platform !bjj: this should come from Init%OutData_ED, not x_ED - Init%InData_MD%g = p_FAST%Gravity ! This need to be according to g from driver - Init%InData_MD%rhoW = Init%OutData_HD%WtrDens ! This needs to be set according to seawater density in HydroDyn + Init%InData_MD%PtfmInit(:,1) = Init%OutData_ED%PlatformPos ! initial position of the platform (when a FAST module, MoorDyn just takes one row in this matrix) + Init%InData_MD%FarmSize = 0 ! 0 here indicates normal FAST module use of MoorDyn, for a single turbine + Init%InData_MD%TurbineRefPos(:,1) = 0.0_DbKi ! for normal FAST use, the global reference frame is at 0,0,0 + Init%InData_MD%g = p_FAST%Gravity ! This need to be according to g used in ElastoDyn + Init%InData_MD%rhoW = Init%OutData_HD%WtrDens ! This needs to be set according to seawater density in HydroDyn Init%InData_MD%WtrDepth = Init%OutData_HD%WtrDpth ! This need to be set according to the water depth in HydroDyn + Init%InData_MD%Tmax = p_FAST%TMax ! expected simulation duration (used by MoorDyn for wave kinematics preprocesing) + + Init%InData_MD%Linearize = p_FAST%Linearize + CALL MD_Init( Init%InData_MD, MD%Input(1), MD%p, MD%x(STATE_CURR), MD%xd(STATE_CURR), MD%z(STATE_CURR), & MD%OtherSt(STATE_CURR), MD%y, MD%m, p_FAST%dt_module( MODULE_MD ), Init%OutData_MD, ErrStat2, ErrMsg2 ) @@ -962,7 +1020,22 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, p_FAST%ModuleInitialized(Module_MD) = .TRUE. CALL SetModuleSubstepTime(Module_MD, p_FAST, y_FAST, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - + + allocate( y_FAST%Lin%Modules(MODULE_MD)%Instance(1), stat=ErrStat2) + if (ErrStat2 /= 0 ) then + call SetErrStat(ErrID_Fatal, "Error allocating Lin%Modules(MD).", ErrStat, ErrMsg, RoutineName ) + else + if (allocated(Init%OutData_MD%LinNames_y)) call move_alloc(Init%OutData_MD%LinNames_y,y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%Names_y) + if (allocated(Init%OutData_MD%LinNames_x)) call move_alloc(Init%OutData_MD%LinNames_x,y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%Names_x) + if (allocated(Init%OutData_MD%LinNames_u)) call move_alloc(Init%OutData_MD%LinNames_u,y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%Names_u) + if (allocated(Init%OutData_MD%RotFrame_y)) call move_alloc(Init%OutData_MD%RotFrame_y,y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%RotFrame_y) + if (allocated(Init%OutData_MD%RotFrame_x)) call move_alloc(Init%OutData_MD%RotFrame_x,y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%RotFrame_x) + if (allocated(Init%OutData_MD%RotFrame_u)) call move_alloc(Init%OutData_MD%RotFrame_u,y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%RotFrame_u) + if (allocated(Init%OutData_MD%IsLoad_u )) call move_alloc(Init%OutData_MD%IsLoad_u ,y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%IsLoad_u ) + if (allocated(Init%OutData_MD%WriteOutputHdr)) y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%NumOutputs = size(Init%OutData_MD%WriteOutputHdr) + if (allocated(Init%OutData_MD%DerivOrder_x)) call move_alloc(Init%OutData_MD%DerivOrder_x,y_FAST%Lin%Modules(MODULE_MD)%Instance(1)%DerivOrder_x) + end if + IF (ErrStat >= AbortErrLev) THEN CALL Cleanup() RETURN @@ -1398,7 +1471,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, BD, SrvD, endif end if - m_FAST%ExternInput%LidarFocus = 1.0_ReKi ! make this non-zero (until we add the initial position in the InflowWind input file) + !............................................................................................................................... @@ -1714,9 +1787,9 @@ SUBROUTINE FAST_Init( p, m_FAST, y_FAST, t_initial, InputFile, ErrStat, ErrMsg, ELSEIF ( p%CompSub == Module_ExtPtfm .and. p%MHK == 0) THEN p%TurbineType = Type_Offshore_Fixed ELSEIF ( p%MHK == 1 ) THEN - p%TurbineType = Type_MHK_Fixed + p%TurbineType = Type_MHK_Fixed ELSEIF ( p%MHK == 2 ) THEN - p%TurbineType = Type_MHK_Floating + p%TurbineType = Type_MHK_Floating ELSE p%TurbineType = Type_LandBased END IF @@ -1767,7 +1840,7 @@ SUBROUTINE ValidateInputData(p, m_FAST, ErrStat, ErrMsg) IF ( p%TMax < 0.0_DbKi ) THEN CALL SetErrStat( ErrID_Fatal, 'TMax must not be a negative number.', ErrStat, ErrMsg, RoutineName ) ELSE IF ( p%TMax < p%TStart ) THEN - CALL SetErrStat( ErrID_Fatal, 'TMax must not be less than TStart.', ErrStat, ErrMsg, RoutineName ) + CALL SetErrStat( ErrID_Fatal, 'TStart ('//trim(num2lstr(p%TStart))//') should be greater than TMax ('//trim(num2lstr(p%TMax))//') in OpenFAST input file.', ErrStat, ErrMsg, RoutineName ) END IF IF ( p%n_ChkptTime < p%n_TMax_m1 ) THEN @@ -1833,15 +1906,14 @@ SUBROUTINE ValidateInputData(p, m_FAST, ErrStat, ErrMsg) END IF IF (p%CompElast == Module_BD .and. p%CompAero == Module_AD14 ) CALL SetErrStat( ErrID_Fatal, 'AeroDyn14 cannot be used when BeamDyn is used. Change CompAero or CompElast in the FAST input file.', ErrStat, ErrMsg, RoutineName ) + if (p%CompInflow == MODULE_OpFM .and. p%CompAero == Module_AD14 ) CALL SetErrStat( ErrID_Fatal, 'AeroDyn14 cannot be used when OpenFOAM is used. Change CompAero or CompInflow in the FAST input file.', ErrStat, ErrMsg, RoutineName ) - IF (p%MHK /= 0) CALL SetErrStat( ErrID_Fatal, 'MHK switch must be 0 in the FAST input file. Functionality to model an MHK turbine has not yet been implemented.', ErrStat, ErrMsg, RoutineName ) ! hkr (4/6/21) Remove after MHK functionality is implemented - IF (p%MHK /= 0 .and. p%MHK /= 1 .and. p%MHK /= 2) CALL SetErrStat( ErrID_Fatal, 'MHK switch is invalid. Set MHK to 0, 1, or 2 in the FAST input file.', ErrStat, ErrMsg, RoutineName ) - IF (p%MHK == 2) CALL SetErrStat( ErrID_Fatal, 'Functionality to model a floating MHK turbine has not yet been implemented.', ErrStat, ErrMsg, RoutineName ) - IF (p%MHK == 1 .and. p%CompAero == Module_AD14 .or. p%MHK == 2 .and. p%CompAero == Module_AD14) CALL SetErrStat( ErrID_Fatal, 'AeroDyn14 cannot be used with an MHK turbine. Change CompAero or MHK in the FAST input file.', ErrStat, ErrMsg, RoutineName ) + IF (p%MHK == 1 .and. p%Linearize .or. p%MHK == 2 .and. p%Linearize) CALL SetErrStat( ErrID_Fatal, 'Linearization has not yet been implemented for an MHK turbine. Change MHK or Linearize in the FAST input file.', ErrStat, ErrMsg, RoutineName ) + IF (p%Gravity < 0.0_ReKi) CALL SetErrStat( ErrID_Fatal, 'Gravity must not be negative.', ErrStat, ErrMsg, RoutineName ) IF (p%WtrDpth < 0.0_ReKi) CALL SetErrStat( ErrID_Fatal, 'WtrDpth must not be negative.', ErrStat, ErrMsg, RoutineName ) @@ -1913,7 +1985,7 @@ SUBROUTINE ValidateInputData(p, m_FAST, ErrStat, ErrMsg) 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 .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%CompMooring /= MODULE_None .and. p%CompMooring == MODULE_FEAM) call SetErrStat(ErrID_Fatal,'Linearization is not implemented for the FEAMooring mooring module.',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) end if @@ -2920,6 +2992,7 @@ SUBROUTINE FAST_ReadPrimaryFile( InputFile, p, m_FAST, OverrideAbortErrLev, ErrS p%n_DT_Out = NINT( p%DT_Out / p%DT ) + ! TStart - Time to begin tabular output (s): CALL ReadVar( UnIn, InputFile, p%TStart, "TStart", "Time to begin tabular output (s)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -3308,6 +3381,7 @@ SUBROUTINE SetVTKParameters(p_FAST, InitOutData_ED, InitOutData_AD, InitInData_H INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'SetVTKParameters' + INTEGER(IntKi) :: rootNode, cylNode, tipNode ErrStat = ErrID_None @@ -3417,16 +3491,8 @@ SUBROUTINE SetVTKParameters(p_FAST, InitOutData_ED, InitOutData_AD, InitInData_H call move_alloc( InitOutData_AD%rotors(1)%BladeShape(k)%AirfoilCoords, p_FAST%VTK_Surface%BladeShape(k)%AirfoilCoords ) end do ELSE -#ifndef USE_DEFAULT_BLADE_SURFACE - call setErrStat(ErrID_Fatal,'Cannot do surface visualization without airfoil coordinates defined in AeroDyn.',ErrStat,ErrMsg,RoutineName) - return - END IF - ELSE - call setErrStat(ErrID_Fatal,'Cannot do surface visualization without using AeroDyn.',ErrStat,ErrMsg,RoutineName) - return - END IF -#else ! AD used without airfoil coordinates specified + call WrScr('Using generic blade surfaces for AeroDyn (S809 airfoil, assumed chord, twist, AC). ') rootNode = 1 @@ -3434,34 +3500,35 @@ SUBROUTINE SetVTKParameters(p_FAST, InitOutData_ED, InitOutData_AD, InitInData_H tipNode = AD%Input(1)%rotors(1)%BladeMotion(K)%NNodes cylNode = min(3,AD%Input(1)%rotors(1)%BladeMotion(K)%Nnodes) - call SetVTKDefaultBladeParams(AD%Input(1)%rotors(1)%BladeMotion(K), p_FAST%VTK_Surface%BladeShape(K), tipNode, rootNode, cylNode, ErrStat2, ErrMsg2) + call SetVTKDefaultBladeParams(AD%Input(1)%rotors(1)%BladeMotion(K), p_FAST%VTK_Surface%BladeShape(K), tipNode, rootNode, cylNode, 1, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF (ErrStat >= AbortErrLev) RETURN END DO END IF ELSE IF ( p_FAST%CompElast == Module_BD ) THEN + call WrScr('Using generic blade surfaces for BeamDyn (rectangular airfoil, constant chord). ') ! TODO make this an option rootNode = 1 DO K=1,NumBl tipNode = BD%y(k)%BldMotion%NNodes cylNode = min(3,BD%y(k)%BldMotion%NNodes) - call SetVTKDefaultBladeParams(BD%y(k)%BldMotion, p_FAST%VTK_Surface%BladeShape(K), tipNode, rootNode, cylNode, ErrStat2, ErrMsg2) + call SetVTKDefaultBladeParams(BD%y(k)%BldMotion, p_FAST%VTK_Surface%BladeShape(K), tipNode, rootNode, cylNode, 4, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF (ErrStat >= AbortErrLev) RETURN END DO ELSE + call WrScr('Using generic blade surfaces for ElastoDyn (rectangular airfoil, constant chord). ') ! TODO make this an option DO K=1,NumBl rootNode = ED%y%BladeLn2Mesh(K)%NNodes tipNode = ED%y%BladeLn2Mesh(K)%NNodes-1 cylNode = min(2,ED%y%BladeLn2Mesh(K)%NNodes) - call SetVTKDefaultBladeParams(ED%y%BladeLn2Mesh(K), p_FAST%VTK_Surface%BladeShape(K), tipNode, rootNode, cylNode, ErrStat2, ErrMsg2) + call SetVTKDefaultBladeParams(ED%y%BladeLn2Mesh(K), p_FAST%VTK_Surface%BladeShape(K), tipNode, rootNode, cylNode, 4, ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF (ErrStat >= AbortErrLev) RETURN END DO END IF -#endif !....................... @@ -3498,13 +3565,14 @@ SUBROUTINE SetVTKParameters(p_FAST, InitOutData_ED, InitOutData_AD, InitInData_H END SUBROUTINE SetVTKParameters !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine comes up with some default airfoils for blade surfaces for a given blade mesh, M. -SUBROUTINE SetVTKDefaultBladeParams(M, BladeShape, tipNode, rootNode, cylNode, ErrStat, ErrMsg) +SUBROUTINE SetVTKDefaultBladeParams(M, BladeShape, tipNode, rootNode, cylNode, iShape, ErrStat, ErrMsg) TYPE(MeshType), INTENT(IN ) :: M !< The Mesh the defaults should be calculated for TYPE(FAST_VTK_BLSurfaceType), INTENT(INOUT) :: BladeShape !< BladeShape to set to default values INTEGER(IntKi), INTENT(IN ) :: rootNode !< Index of root node (innermost node) for this mesh INTEGER(IntKi), INTENT(IN ) :: tipNode !< Index of tip node (outermost node) for this mesh INTEGER(IntKi), INTENT(IN ) :: cylNode !< Index of last node to have a cylinder shape + INTEGER(IntKi), INTENT(IN ) :: iShape !< 1: S809, 2: circle, 3: square, 4: rectangle INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None @@ -3516,15 +3584,53 @@ SUBROUTINE SetVTKDefaultBladeParams(M, BladeShape, tipNode, rootNode, cylNode, E INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'SetVTKDefaultBladeParams' + integer :: N ! Number of points for airfoil + real, allocatable, dimension(:) :: xc, yc ! Coordinate of airfoil - !Note: jmj does not like this default option + ErrStat = ErrID_None + ErrMsg = '' - integer, parameter :: N = 66 + select case (iShape) + case (1) + N=66 + call AllocAry(xc, N, 'xc', Errstat2, ErrMsg2) + call AllocAry(yc, N, 'yc', Errstat2, ErrMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName); if (ErrStat >= AbortErrLev) return + xc=(/ 1.0,0.996203,0.98519,0.967844,0.945073,0.917488,0.885293,0.848455,0.80747,0.763042,0.715952,0.667064,0.617331,0.56783,0.519832,0.474243,0.428461,0.382612,0.33726,0.29297,0.250247,0.209576,0.171409,0.136174,0.104263,0.076035,0.051823,0.03191,0.01659,0.006026,0.000658,0.000204,0.0,0.000213,0.001045,0.001208,0.002398,0.009313,0.02323,0.04232,0.065877,0.093426,0.124111,0.157653,0.193738,0.231914,0.271438,0.311968,0.35337,0.395329,0.438273,0.48192,0.527928,0.576211,0.626092,0.676744,0.727211,0.776432,0.823285,0.86663,0.905365,0.938474,0.965086,0.984478,0.996141,1.0 /) + yc=(/ 0.0,0.000487,0.002373,0.00596,0.011024,0.017033,0.023458,0.03028,0.037766,0.045974,0.054872,0.064353,0.074214,0.084095,0.093268,0.099392,0.10176,0.10184,0.10007,0.096703,0.091908,0.085851,0.078687,0.07058,0.061697,0.052224,0.042352,0.032299,0.02229,0.012615,0.003723,0.001942,-0.00002,-0.001794,-0.003477,-0.003724,-0.005266,-0.011499,-0.020399,-0.030269,-0.040821,-0.051923,-0.063082,-0.07373,-0.083567,-0.092442,-0.099905,-0.105281,-0.108181,-0.108011,-0.104552,-0.097347,-0.086571,-0.073979,-0.060644,-0.047441,-0.0351,-0.024204,-0.015163,-0.008204,-0.003363,-0.000487,0.000743,0.000775,0.00029,0.0 /) + case (2) + ! Circle + N=21 + call AllocAry(xc, N, 'xc', Errstat2, ErrMsg2) + call AllocAry(yc, N, 'yc', Errstat2, ErrMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName); if (ErrStat >= AbortErrLev) return + do i=1,N + angle = (i-1)*TwoPi/(N-1) + xc(i) = (cos(angle)+1)/2 ! between 0 and 1, 0.5 substracted later + yc(i) = (sin(angle)+1)/2-0.5 ! between -0.5 and 0.5 + enddo + case (3) + ! Square + N=5 + call AllocAry(xc, N, 'xc', Errstat2, ErrMsg2) + call AllocAry(yc, N, 'yc', Errstat2, ErrMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName); if (ErrStat >= AbortErrLev) return + xc = (/1.0 , 0.0 , 0.0 , 1.0 , 1.0/) ! between 0 and 1, 0.5 substracted later + yc = (/-0.5 , -0.5 , 0.5 , 0.5 , -0.5/) ! between -0.5 and 0.5 + case (4) + ! Rectangle + N=5 + call AllocAry(xc, N, 'xc', Errstat2, ErrMsg2) + call AllocAry(yc, N, 'yc', Errstat2, ErrMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName); if (ErrStat >= AbortErrLev) return + xc = (/1.0 , 0.0 , 0.0 , 1.0 , 1.0/) ! between 0 and 1, 0.5 substracted later + yc = (/-0.25 , -0.25 , 0.25 , 0.25 , 0.0/) ! between 0.25 and 0.25 + case default + call SetErrStat(ErrID_Fatal, 'Unknown iShape specfied for VTK default shapes',ErrStat,ErrMsg,RoutineName) + return + end select ! default airfoil shape coordinates; uses S809 values from http://wind.nrel.gov/airfoils/Shapes/S809_Shape.html: - real, parameter, dimension(N) :: xc=(/ 1.0,0.996203,0.98519,0.967844,0.945073,0.917488,0.885293,0.848455,0.80747,0.763042,0.715952,0.667064,0.617331,0.56783,0.519832,0.474243,0.428461,0.382612,0.33726,0.29297,0.250247,0.209576,0.171409,0.136174,0.104263,0.076035,0.051823,0.03191,0.01659,0.006026,0.000658,0.000204,0.0,0.000213,0.001045,0.001208,0.002398,0.009313,0.02323,0.04232,0.065877,0.093426,0.124111,0.157653,0.193738,0.231914,0.271438,0.311968,0.35337,0.395329,0.438273,0.48192,0.527928,0.576211,0.626092,0.676744,0.727211,0.776432,0.823285,0.86663,0.905365,0.938474,0.965086,0.984478,0.996141,1.0 /) - real, parameter, dimension(N) :: yc=(/ 0.0,0.000487,0.002373,0.00596,0.011024,0.017033,0.023458,0.03028,0.037766,0.045974,0.054872,0.064353,0.074214,0.084095,0.093268,0.099392,0.10176,0.10184,0.10007,0.096703,0.091908,0.085851,0.078687,0.07058,0.061697,0.052224,0.042352,0.032299,0.02229,0.012615,0.003723,0.001942,-0.00002,-0.001794,-0.003477,-0.003724,-0.005266,-0.011499,-0.020399,-0.030269,-0.040821,-0.051923,-0.063082,-0.07373,-0.083567,-0.092442,-0.099905,-0.105281,-0.108181,-0.108011,-0.104552,-0.097347,-0.086571,-0.073979,-0.060644,-0.047441,-0.0351,-0.024204,-0.015163,-0.008204,-0.003363,-0.000487,0.000743,0.000775,0.00029,0.0 /) - call AllocAry(BladeShape%AirfoilCoords, 2, N, M%NNodes, 'BladeShape%AirfoilCoords', ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -3535,6 +3641,25 @@ SUBROUTINE SetVTKDefaultBladeParams(M, BladeShape, tipNode, rootNode, cylNode, E bladeLengthFract = 0.22*bladeLength bladeLengthFract2 = bladeLength-bladeLengthFract != 0.78*bladeLength + + ! Circle, square or rectangle, constant chord + if (iShape>1) then + chord = bladeLength*0.04 ! chord set to 4% of blade length + DO i=1,M%Nnodes + posLength = TwoNorm( M%Position(:,i) - M%Position(:,rootNode) ) + DO j=1,N + ! normalized x,y coordinates for airfoil + x = yc(j) + y = xc(j) - 0.5 + ! x,y coordinates for cylinder + BladeShape%AirfoilCoords(1,j,i) = chord*x + BladeShape%AirfoilCoords(2,j,i) = chord*y + END DO + enddo + return ! We exit this routine + endif + + ! Assumed chord/twist/AC distribution for a blade DO i=1,M%Nnodes posLength = TwoNorm( M%Position(:,i) - M%Position(:,rootNode) ) @@ -4092,8 +4217,8 @@ SUBROUTINE FAST_Solution0(p_FAST, y_FAST, m_FAST, ED, BD, SrvD, AD14, AD, IfW, O ! the initial ServoDyn and IfW/Lidar inputs from Simulink: IF ( p_FAST%CompServo == Module_SrvD ) CALL SrvD_SetExternalInputs( p_FAST, m_FAST, SrvD%Input(1) ) - IF ( p_FAST%CompInflow == Module_IfW ) CALL IfW_SetExternalInputs( IfW%p, m_FAST, ED%y, IfW%Input(1) ) - + + CALL CalcOutputs_And_SolveForInputs( n_t_global, t_initial, STATE_CURR, m_FAST%calcJacobian, m_FAST%NextJacCalcTime, & p_FAST, m_FAST, y_FAST%WriteThisStep, ED, BD, SrvD, AD14, AD, IfW, OpFM, HD, SD, ExtPtfm, & MAPp, FEAM, MD, Orca, IceF, IceD, MeshMapData, ErrStat2, ErrMsg2 ) @@ -5407,6 +5532,7 @@ SUBROUTINE WrVTK_AllMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, H call MeshWrVTK(p_FAST%TurbinePos, ED%Input(1)%TowerPtLoads, trim(p_FAST%VTK_OutFileRoot)//'.ED_TowerPtLoads', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, ED%y%TowerLn2Mesh ) call MeshWrVTK(p_FAST%TurbinePos, ED%Input(1)%HubPtLoad, trim(p_FAST%VTK_OutFileRoot)//'.ED_Hub', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, ED%y%HubPtMotion ) call MeshWrVTK(p_FAST%TurbinePos, ED%Input(1)%NacelleLoads, trim(p_FAST%VTK_OutFileRoot)//'.ED_Nacelle' ,y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, ED%y%NacelleMotion ) + call MeshWrVTK(p_FAST%TurbinePos, ED%Input(1)%TFinCMLoads, trim(p_FAST%VTK_OutFileRoot)//'.ED_TailFin' ,y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, ED%y%TFinCMMotion ) call MeshWrVTK(p_FAST%TurbinePos, ED%Input(1)%PlatformPtMesh, trim(p_FAST%VTK_OutFileRoot)//'.ED_PlatformPtMesh', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, ED%y%PlatformPtMesh ) end if @@ -5487,22 +5613,23 @@ SUBROUTINE WrVTK_AllMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, H ! AeroDyn IF ( p_FAST%CompAero == Module_AD .and. allocated(AD%Input)) THEN - - if (allocated(AD%Input(1)%rotors(1)%BladeRootMotion)) then + if (allocated(AD%Input(1)%rotors) .and. allocated(AD%y%rotors) ) then + if (allocated(AD%Input(1)%rotors(1)%BladeRootMotion)) then - DO K=1,NumBl - call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%rotors(1)%BladeRootMotion(K), trim(p_FAST%VTK_OutFileRoot)//'.AD_BladeRootMotion'//trim(num2lstr(k)), y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) - !call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%BladeMotion(K), trim(p_FAST%VTK_OutFileRoot)//'.AD_BladeMotion'//trim(num2lstr(k)), y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) - END DO + DO K=1,NumBl + call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%rotors(1)%BladeRootMotion(K), trim(p_FAST%VTK_OutFileRoot)//'.AD_BladeRootMotion'//trim(num2lstr(k)), y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) + !call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%BladeMotion(K), trim(p_FAST%VTK_OutFileRoot)//'.AD_BladeMotion'//trim(num2lstr(k)), y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) + END DO - call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%rotors(1)%HubMotion, trim(p_FAST%VTK_OutFileRoot)//'.AD_HubMotion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) - !call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%TowerMotion, trim(p_FAST%VTK_OutFileRoot)//'.AD_TowerMotion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) + call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%rotors(1)%HubMotion, trim(p_FAST%VTK_OutFileRoot)//'.AD_HubMotion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) + !call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%TowerMotion, trim(p_FAST%VTK_OutFileRoot)//'.AD_TowerMotion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) - DO K=1,NumBl - call MeshWrVTK(p_FAST%TurbinePos, AD%y%rotors(1)%BladeLoad(K), trim(p_FAST%VTK_OutFileRoot)//'.AD_Blade'//trim(num2lstr(k)), y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, AD%Input(1)%rotors(1)%BladeMotion(k) ) - END DO - call MeshWrVTK(p_FAST%TurbinePos, AD%y%rotors(1)%TowerLoad, trim(p_FAST%VTK_OutFileRoot)//'.AD_Tower', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, AD%Input(1)%rotors(1)%TowerMotion ) + DO K=1,NumBl + call MeshWrVTK(p_FAST%TurbinePos, AD%y%rotors(1)%BladeLoad(K), trim(p_FAST%VTK_OutFileRoot)//'.AD_Blade'//trim(num2lstr(k)), y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, AD%Input(1)%rotors(1)%BladeMotion(k) ) + END DO + call MeshWrVTK(p_FAST%TurbinePos, AD%y%rotors(1)%TowerLoad, trim(p_FAST%VTK_OutFileRoot)//'.AD_Tower', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, AD%Input(1)%rotors(1)%TowerMotion ) + end if end if ! FVW submodule of AD15 @@ -5520,31 +5647,18 @@ SUBROUTINE WrVTK_AllMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, H ! HydroDyn 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%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 + call MeshWrVTK(p_FAST%TurbinePos, HD%Input(1)%PRPMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_PRP', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) + call MeshWrVTK(p_FAST%TurbinePos, HD%y%WamitMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_WAMIT', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%Input(1)%WAMITMesh ) + call MeshWrVTK(p_FAST%TurbinePos, HD%y%Morison%Mesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_Morison', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%Input(1)%Morison%Mesh ) END IF ! SubDyn IF ( p_FAST%CompSub == Module_SD .and. allocated(SD%Input)) THEN !call MeshWrVTK(p_FAST%TurbinePos, SD%Input(1)%TPMesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_TPMesh_motion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) call MeshWrVTK(p_FAST%TurbinePos, SD%Input(1)%LMesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_LMesh_y2Mesh', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, SD%y%y2Mesh ) + call MeshWrVTK(p_FAST%TurbinePos, SD%Input(1)%LMesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_LMesh_y3Mesh', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, SD%y%y3Mesh ) call MeshWrVTK(p_FAST%TurbinePos, SD%y%y1Mesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_y1Mesh_TPMesh', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, SD%Input(1)%TPMesh ) - !call MeshWrVTK(p_FAST%TurbinePos, SD%y%y2Mesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_y2Mesh_motion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) !call MeshWrVTK(p_FAST%TurbinePos, SD%y%y3Mesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_y3Mesh_motion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) ELSE IF ( p_FAST%CompSub == Module_ExtPtfm .and. allocated(ExtPtfm%Input)) THEN call MeshWrVTK(p_FAST%TurbinePos, ExtPtfm%y%PtfmMesh, trim(p_FAST%VTK_OutFileRoot)//'.ExtPtfm', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, ExtPtfm%Input(1)%PtfmMesh ) @@ -5559,9 +5673,9 @@ SUBROUTINE WrVTK_AllMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, H ! MoorDyn ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN - if (allocated(MD%Input)) then - call MeshWrVTK(p_FAST%TurbinePos, MD%y%PtFairleadLoad, trim(p_FAST%VTK_OutFileRoot)//'.MD_PtFairlead', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, MD%Input(1)%PtFairleadDisplacement ) - !call MeshWrVTK(p_FAST%TurbinePos, MD%Input(1)%PtFairleadDisplacement, trim(p_FAST%VTK_OutFileRoot)//'.MD_PtFair_motion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) + if (allocated(MD%Input) .and. allocated(MD%y%CoupledLoads)) then + call MeshWrVTK(p_FAST%TurbinePos, MD%y%CoupledLoads(1), trim(p_FAST%VTK_OutFileRoot)//'.MD_PtFairlead', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, MD%Input(1)%CoupledKinematics(1) ) + !call MeshWrVTK(p_FAST%TurbinePos, MD%Input(1)%CoupledKinematics, trim(p_FAST%VTK_OutFileRoot)//'.MD_PtFair_motion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) end if ! FEAMooring @@ -5589,7 +5703,7 @@ SUBROUTINE WrVTK_AllMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, H ! IceDyn ELSEIF ( p_FAST%CompIce == Module_IceD ) THEN - if (allocated(IceD%Input)) then + if (allocated(IceD%Input) .and. allocated(IceD%y)) then DO k = 1,p_FAST%numIceLegs call MeshWrVTK(p_FAST%TurbinePos, IceD%y(k)%PointMesh, trim(p_FAST%VTK_OutFileRoot)//'.IceD_PointMesh'//trim(num2lstr(k)), y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, IceD%Input(1,k)%PointMesh ) @@ -5625,7 +5739,6 @@ SUBROUTINE WrVTK_BasicMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, TYPE(IceFloe_Data), INTENT(IN ) :: IceF !< IceFloe data TYPE(IceDyn_Data), INTENT(IN ) :: IceD !< All the IceDyn data used in time-step loop - logical :: OutputFields INTEGER(IntKi) :: NumBl, k INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMSg2 @@ -5639,12 +5752,14 @@ SUBROUTINE WrVTK_BasicMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, ! Blades - IF ( p_FAST%CompAero == Module_AD ) THEN ! These meshes may have airfoil data associated with nodes... - DO K=1,NumBl - call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%rotors(1)%BladeMotion(K), trim(p_FAST%VTK_OutFileRoot)//'.AD_Blade'//trim(num2lstr(k)), & - y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, Sib=AD%y%rotors(1)%BladeLoad(K) ) - END DO - ELSE IF ( p_FAST%CompElast == Module_BD ) THEN + IF ( p_FAST%CompAero == Module_AD .and. ALLOCATED(AD%Input) ) THEN ! These meshes may have airfoil data associated with nodes... + if (allocated(AD%Input(1)%rotors) .and. allocated(AD%y%rotors)) then + DO K=1,NumBl + call MeshWrVTK(p_FAST%TurbinePos, AD%Input(1)%rotors(1)%BladeMotion(K), trim(p_FAST%VTK_OutFileRoot)//'.AD_Blade'//trim(num2lstr(k)), & + y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, Sib=AD%y%rotors(1)%BladeLoad(K) ) + END DO + end if + ELSE IF ( p_FAST%CompElast == Module_BD .and. ALLOCATED(BD%y)) THEN DO K=1,NumBl call MeshWrVTK(p_FAST%TurbinePos, BD%y(k)%BldMotion, trim(p_FAST%VTK_OutFileRoot)//'.BD_BldMotion'//trim(num2lstr(k)), & y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) @@ -5656,16 +5771,20 @@ SUBROUTINE WrVTK_BasicMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, END DO END IF -! Nacelle - call MeshWrVTK(p_FAST%TurbinePos, ED%y%NacelleMotion, trim(p_FAST%VTK_OutFileRoot)//'.ED_Nacelle', y_FAST%VTK_count, & - p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, Sib=ED%Input(1)%NacelleLoads ) - -! Hub - call MeshWrVTK(p_FAST%TurbinePos, ED%y%HubPtMotion, trim(p_FAST%VTK_OutFileRoot)//'.ED_Hub', y_FAST%VTK_count, & - p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, Sib=ED%Input(1)%HubPtLoad ) -! Tower motions - call MeshWrVTK(p_FAST%TurbinePos, ED%y%TowerLn2Mesh, trim(p_FAST%VTK_OutFileRoot)//'.ED_TowerLn2Mesh_motion', & - y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) + if (allocated(ED%Input)) then + ! Nacelle + call MeshWrVTK(p_FAST%TurbinePos, ED%y%NacelleMotion, trim(p_FAST%VTK_OutFileRoot)//'.ED_Nacelle', y_FAST%VTK_count, & + p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, Sib=ED%Input(1)%NacelleLoads ) + ! TailFin + call MeshWrVTK(p_FAST%TurbinePos, ED%y%TFinCMMotion, trim(p_FAST%VTK_OutFileRoot)//'.ED_TailFin', y_FAST%VTK_count, & + p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, Sib=ED%Input(1)%TFinCMLoads ) + ! Hub + call MeshWrVTK(p_FAST%TurbinePos, ED%y%HubPtMotion, trim(p_FAST%VTK_OutFileRoot)//'.ED_Hub', y_FAST%VTK_count, & + p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, Sib=ED%Input(1)%HubPtLoad ) + ! Tower motions + call MeshWrVTK(p_FAST%TurbinePos, ED%y%TowerLn2Mesh, trim(p_FAST%VTK_OutFileRoot)//'.ED_TowerLn2Mesh_motion', & + y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) + end if @@ -5677,17 +5796,11 @@ SUBROUTINE WrVTK_BasicMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, ! call MeshWrVTK(p_FAST%TurbinePos, SD%y%y3Mesh, trim(p_FAST%VTK_OutFileRoot)//'.SD_y3Mesh_motion', y_FAST%VTK_count, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) ! END IF - IF ( p_FAST%CompHydro == Module_HD ) THEN - - if (p_FAST%CompSub == Module_NONE) then - 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 - !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 ) + IF ( p_FAST%CompHydro == Module_HD .and. ALLOCATED(HD%Input)) THEN + call MeshWrVTK(p_FAST%TurbinePos, HD%Input(1)%WAMITMesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_WAMIT', y_FAST%VTK_count, & + p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%y%WAMITMesh ) + call MeshWrVTK(p_FAST%TurbinePos, HD%Input(1)%Morison%Mesh, trim(p_FAST%VTK_OutFileRoot)//'.HD_Morison', y_FAST%VTK_count, & + p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, HD%y%Morison%Mesh ) END IF @@ -5695,7 +5808,7 @@ SUBROUTINE WrVTK_BasicMeshes(p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, ! IF ( p_FAST%CompMooring == Module_MAP ) THEN ! call MeshWrVTK(p_FAST%TurbinePos, MAPp%Input(1)%PtFairDisplacement, trim(p_FAST%VTK_OutFileRoot)//'.MAP_PtFair_motion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) ! ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN -! call MeshWrVTK(p_FAST%TurbinePos, MD%Input(1)%PtFairleadDisplacement, trim(p_FAST%VTK_OutFileRoot)//'.MD_PtFair_motion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) +! call MeshWrVTK(p_FAST%TurbinePos, MD%Input(1)%CoupledKinematics, trim(p_FAST%VTK_OutFileRoot)//'.MD_PtFair_motion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) ! ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN ! call MeshWrVTK(p_FAST%TurbinePos, FEAM%Input(1)%PtFairleadDisplacement, trim(p_FAST%VTK_OutFileRoot)//'FEAM_PtFair_motion', y_FAST%VTK_count, p_FAST%VTK_fields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth ) ! END IF @@ -5745,28 +5858,34 @@ SUBROUTINE WrVTK_Surfaces(t_global, p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW ! Wave elevation if ( allocated( p_FAST%VTK_Surface%WaveElev ) ) call WrVTK_WaveElev( t_global, p_FAST, y_FAST, HD) -! Nacelle - call MeshWrVTK_PointSurface (p_FAST%TurbinePos, ED%y%NacelleMotion, trim(p_FAST%VTK_OutFileRoot)//'.NacelleSurface', & - y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , verts = p_FAST%VTK_Surface%NacelleBox, Sib=ED%Input(1)%NacelleLoads ) - - -! Hub - call MeshWrVTK_PointSurface (p_FAST%TurbinePos, ED%y%HubPtMotion, trim(p_FAST%VTK_OutFileRoot)//'.HubSurface', & - y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , & - NumSegments=p_FAST%VTK_Surface%NumSectors, radius=p_FAST%VTK_Surface%HubRad, Sib=ED%Input(1)%HubPtLoad ) - -! Tower motions - call MeshWrVTK_Ln2Surface (p_FAST%TurbinePos, ED%y%TowerLn2Mesh, trim(p_FAST%VTK_OutFileRoot)//'.TowerSurface', & - y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, p_FAST%VTK_Surface%NumSectors, p_FAST%VTK_Surface%TowerRad ) - + if (allocated(ED%Input)) then + ! Nacelle + call MeshWrVTK_PointSurface (p_FAST%TurbinePos, ED%y%NacelleMotion, trim(p_FAST%VTK_OutFileRoot)//'.NacelleSurface', & + y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , verts = p_FAST%VTK_Surface%NacelleBox, Sib=ED%Input(1)%NacelleLoads ) + ! TailFin TODO TailFin + !call MeshWrVTK_PointSurface (p_FAST%TurbinePos, ED%y%TFinCMMotion, trim(p_FAST%VTK_OutFileRoot)//'.TailFinSurface', & + ! y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , verts = p_FAST%VTK_Surface%TFinBox, Sib=ED%Input(1)%TFinCMLoads ) + + ! Hub + call MeshWrVTK_PointSurface (p_FAST%TurbinePos, ED%y%HubPtMotion, trim(p_FAST%VTK_OutFileRoot)//'.HubSurface', & + y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , & + NumSegments=p_FAST%VTK_Surface%NumSectors, radius=p_FAST%VTK_Surface%HubRad, Sib=ED%Input(1)%HubPtLoad ) + + ! Tower motions + call MeshWrVTK_Ln2Surface (p_FAST%TurbinePos, ED%y%TowerLn2Mesh, trim(p_FAST%VTK_OutFileRoot)//'.TowerSurface', & + y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth, p_FAST%VTK_Surface%NumSectors, p_FAST%VTK_Surface%TowerRad ) + end if + ! Blades - IF ( p_FAST%CompAero == Module_AD ) THEN ! These meshes may have airfoil data associated with nodes... - DO K=1,NumBl - call MeshWrVTK_Ln2Surface (p_FAST%TurbinePos, AD%Input(1)%rotors(1)%BladeMotion(K), trim(p_FAST%VTK_OutFileRoot)//'.Blade'//trim(num2lstr(k))//'Surface', & - y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , verts=p_FAST%VTK_Surface%BladeShape(K)%AirfoilCoords & - ,Sib=AD%y%rotors(1)%BladeLoad(k) ) - END DO - ELSE IF ( p_FAST%CompElast == Module_BD ) THEN + IF ( p_FAST%CompAero == Module_AD .and. allocated(AD%Input)) THEN ! These meshes may have airfoil data associated with nodes... + if (allocated(AD%Input(1)%rotors) .and. allocated(AD%y%rotors)) then + DO K=1,NumBl + call MeshWrVTK_Ln2Surface (p_FAST%TurbinePos, AD%Input(1)%rotors(1)%BladeMotion(K), trim(p_FAST%VTK_OutFileRoot)//'.Blade'//trim(num2lstr(k))//'Surface', & + y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , verts=p_FAST%VTK_Surface%BladeShape(K)%AirfoilCoords & + ,Sib=AD%y%rotors(1)%BladeLoad(k) ) + END DO + end if + ELSE IF ( p_FAST%CompElast == Module_BD .and. allocated(BD%y)) THEN DO K=1,NumBl call MeshWrVTK_Ln2Surface (p_FAST%TurbinePos, BD%y(k)%BldMotion, trim(p_FAST%VTK_OutFileRoot)//'.Blade'//trim(num2lstr(k))//'Surface', & y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2, p_FAST%VTK_tWidth , verts=p_FAST%VTK_Surface%BladeShape(K)%AirfoilCoords ) @@ -5816,7 +5935,7 @@ SUBROUTINE WrVTK_Surfaces(t_global, p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW ! IF ( p_FAST%CompMooring == Module_MAP ) THEN ! call MeshWrVTK(p_FAST%TurbinePos, MAPp%Input(1)%PtFairDisplacement, trim(p_FAST%VTK_OutFileRoot)//'.MAP_PtFair_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) ! ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN -! call MeshWrVTK(p_FAST%TurbinePos, MD%Input(1)%PtFairleadDisplacement, trim(p_FAST%VTK_OutFileRoot)//'.MD_PtFair_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) +! call MeshWrVTK(p_FAST%TurbinePos, MD%Input(1)%CoupledKinematics, trim(p_FAST%VTK_OutFileRoot)//'.MD_PtFair_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) ! ELSEIF ( p_FAST%CompMooring == Module_FEAM ) THEN ! call MeshWrVTK(p_FAST%TurbinePos, FEAM%Input(1)%PtFairleadDisplacement, trim(p_FAST%VTK_OutFileRoot)//'FEAM_PtFair_motion', y_FAST%VTK_count, OutputFields, ErrStat2, ErrMsg2 ) ! END IF @@ -7255,7 +7374,8 @@ SUBROUTINE FAST_RestoreForVTKModeShape_T(t_initial, p_FAST, y_FAST, m_FAST, ED, INTEGER(IntKi) :: iLinTime ! generic loop counters INTEGER(IntKi) :: it ! generic loop counters - INTEGER(IntKi) :: iMode ! generic loop counters + INTEGER(IntKi) :: iMode ! loop counter on modes + INTEGER(IntKi) :: iModeMax ! maximum mode number (based on what is present in the binary file) INTEGER(IntKi) :: ModeNo ! mode number INTEGER(IntKi) :: NLinTimes @@ -7263,6 +7383,9 @@ SUBROUTINE FAST_RestoreForVTKModeShape_T(t_initial, p_FAST, y_FAST, m_FAST, ED, CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'FAST_RestoreForVTKModeShape_T' CHARACTER(1024) :: VTK_RootName + CHARACTER(1024) :: VTK_RootDir + CHARACTER(1024) :: vtkroot + CHARACTER(1024) :: sInfo !< String used for formatted screen output ErrStat = ErrID_None @@ -7283,15 +7406,31 @@ SUBROUTINE FAST_RestoreForVTKModeShape_T(t_initial, p_FAST, y_FAST, m_FAST, ED, VTK_RootName = p_FAST%VTK_OutFileRoot - select case (p_FAST%VTK_modes%VTKLinTim) - case (1) + ! Creating VTK folder in case user deleted it. + ! We have to extract the vtk root dir again because p_FAST%VTK_OutFileRoot contains the full basename + call GetPath ( p_FAST%OutFileRoot, VTK_RootDir, vtkroot ) + VTK_RootDir = trim(VTK_RootDir) // 'vtk' + call MKDIR( trim(VTK_RootDir) ) - do iMode = 1,p_FAST%VTK_modes%VTKLinModes - ModeNo = p_FAST%VTK_modes%VTKModes(iMode) - call GetTimeConstants(p_FAST%VTK_modes%DampedFreq_Hz(ModeNo), p_FAST%VTK_fps, nt, dt, p_FAST%VTK_tWidth ) - if (nt > 500) cycle + iModeMax = size(p_FAST%VTK_Modes%x_eig_magnitude, 3) + do iMode = 1,p_FAST%VTK_modes%VTKLinModes + ModeNo = p_FAST%VTK_modes%VTKModes(iMode) + if (ModeNo>iModeMax) then + call WrScr(' Skipping mode '//trim(num2lstr(ModeNo))//', maximum number of modes reached ('//trim(num2lstr(iModeMax))//'). Exiting.') + exit; + endif + call GetTimeConstants(p_FAST%VTK_modes%DampedFreq_Hz(ModeNo), p_FAST%VTK_fps, p_FAST%VTK_modes%VTKLinTim, nt, dt, p_FAST%VTK_tWidth ) + write(sInfo, '(A,I4,A,F12.4,A,I4,A,I0)') 'Mode',ModeNo,', Freq=', p_FAST%VTK_modes%DampedFreq_Hz(ModeNo),'Hz, NLinTimes=',NLinTimes,', nt=',nt + call WrScr(trim(sInfo)) + if (nt > 500) then + call WrScr(' Skipping mode '//trim(num2lstr(ModeNo))//' due to low frequency.') + cycle + endif + + select case (p_FAST%VTK_modes%VTKLinTim) + case (1) p_FAST%VTK_OutFileRoot = trim(VTK_RootName)//'.Mode'//trim(num2lstr(ModeNo)) y_FAST%VTK_count = 1 ! we are skipping the reference meshes by starting at 1 do iLinTime = 1,NLinTimes @@ -7320,15 +7459,7 @@ SUBROUTINE FAST_RestoreForVTKModeShape_T(t_initial, p_FAST, y_FAST, m_FAST, ED, call WriteVTK(m_FAST%Lin%LinTimes(iLinTime), p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, HD, SD, ExtPtfm, SrvD, MAPp, FEAM, MD, Orca, IceF, IceD) end do ! iLinTime - end do ! iMode - - case (2) - - do iMode = 1,p_FAST%VTK_modes%VTKLinModes - ModeNo = p_FAST%VTK_modes%VTKModes(iMode) - - call GetTimeConstants(p_FAST%VTK_modes%DampedFreq_Hz(ModeNo), p_FAST%VTK_fps, nt, dt, p_FAST%VTK_tWidth ) - if (nt > 500) cycle + case (2) do iLinTime = 1,NLinTimes p_FAST%VTK_OutFileRoot = trim(VTK_RootName)//'.Mode'//trim(num2lstr(ModeNo))//'.LinTime'//trim(num2lstr(iLinTime)) @@ -7359,19 +7490,22 @@ SUBROUTINE FAST_RestoreForVTKModeShape_T(t_initial, p_FAST, y_FAST, m_FAST, ED, call WriteVTK(m_FAST%Lin%LinTimes(iLinTime)+tprime, p_FAST, y_FAST, MeshMapData, ED, BD, AD, IfW, OpFM, HD, SD, ExtPtfm, SrvD, MAPp, FEAM, MD, Orca, IceF, IceD) - end do + end do ! it + end do ! iLinTime + + end select ! VTKLinTim=1 or 2 + + end do ! iMode - end do ! iLinTime - end do ! iMode - end select END SUBROUTINE FAST_RestoreForVTKModeShape_T !---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE GetTimeConstants(DampedFreq_Hz, VTK_fps, nt, dt, VTK_tWidth ) +SUBROUTINE GetTimeConstants(DampedFreq_Hz, VTK_fps, VTKLinTim, nt, dt, VTK_tWidth) REAL(R8Ki), INTENT(IN ) :: DampedFreq_Hz REAL(DbKi), INTENT(IN ) :: VTK_fps + INTEGER(IntKi), INTENT(IN ) :: VTKLinTim INTEGER(IntKi), INTENT( OUT) :: nt !< number of steps REAL(DbKi), INTENT( OUT) :: dt !< time step INTEGER(IntKi), INTENT( OUT) :: VTK_tWidth @@ -7380,21 +7514,27 @@ SUBROUTINE GetTimeConstants(DampedFreq_Hz, VTK_fps, nt, dt, VTK_tWidth ) INTEGER(IntKi) :: NCycles INTEGER(IntKi), PARAMETER :: MinFrames = 5 - if (DampedFreq_Hz <= 0.0_DbKi) then + if (DampedFreq_Hz <= 1e-4_DbKi) then nt = huge(nt) dt = epsilon(dt) VTK_tWidth = 1 return end if - nt = 1 - NCycles = 0 - do while (nt return radial component, FALSE => return 'x' direction estimate [-] INTEGER(IntKi) :: TurbineID = 0 !< ID number for turbine (used to create output file naming convention) [-] - REAL(ReKi) , DIMENSION(1:3) :: TurbinePos !< Initial position of turbine base (origin used in future for graphics) [m] + REAL(ReKi) , DIMENSION(1:3) :: TurbinePos !< Initial position of turbine base (origin used for graphics or in FAST.Farm) [m] + INTEGER(IntKi) :: WaveFieldMod !< Wave field handling (-) (switch) 0: use individual HydroDyn inputs without adjustment, 1: adjust wave phases based on turbine offsets from farm origin [-] INTEGER(IntKi) :: NumSC2CtrlGlob !< number of global controller inputs [from supercontroller] [-] INTEGER(IntKi) :: NumSC2Ctrl !< number of turbine specific controller inputs [from supercontroller] [-] INTEGER(IntKi) :: NumCtrl2SC !< number of controller outputs [to supercontroller] [-] @@ -753,6 +763,7 @@ MODULE FAST_Types CHARACTER(1024) :: RootName !< Root name of FAST output files (overrides normal operation) [-] INTEGER(IntKi) :: NumActForcePtsBlade !< number of actuator line force points in blade [-] INTEGER(IntKi) :: NumActForcePtsTower !< number of actuator line force points in tower [-] + INTEGER(IntKi) :: NodeClusterType !< Node clustering for actuator line (0 - Uniform, 1 - Non-uniform clustered towards tip) [-] END TYPE FAST_ExternInitType ! ======================= ! ========= FAST_TurbineType ======= @@ -817,15 +828,27 @@ SUBROUTINE FAST_CopyVTK_BLSurfaceType( SrcVTK_BLSurfaceTypeData, DstVTK_BLSurfac ENDIF END SUBROUTINE FAST_CopyVTK_BLSurfaceType - SUBROUTINE FAST_DestroyVTK_BLSurfaceType( VTK_BLSurfaceTypeData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyVTK_BLSurfaceType( VTK_BLSurfaceTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_VTK_BLSurfaceType), INTENT(INOUT) :: VTK_BLSurfaceTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyVTK_BLSurfaceType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyVTK_BLSurfaceType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(VTK_BLSurfaceTypeData%AirfoilCoords)) THEN DEALLOCATE(VTK_BLSurfaceTypeData%AirfoilCoords) ENDIF @@ -1075,15 +1098,27 @@ SUBROUTINE FAST_CopyVTK_SurfaceType( SrcVTK_SurfaceTypeData, DstVTK_SurfaceTypeD ENDIF END SUBROUTINE FAST_CopyVTK_SurfaceType - SUBROUTINE FAST_DestroyVTK_SurfaceType( VTK_SurfaceTypeData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyVTK_SurfaceType( VTK_SurfaceTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_VTK_SurfaceType), INTENT(INOUT) :: VTK_SurfaceTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyVTK_SurfaceType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyVTK_SurfaceType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(VTK_SurfaceTypeData%TowerRad)) THEN DEALLOCATE(VTK_SurfaceTypeData%TowerRad) ENDIF @@ -1095,7 +1130,8 @@ SUBROUTINE FAST_DestroyVTK_SurfaceType( VTK_SurfaceTypeData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(VTK_SurfaceTypeData%BladeShape)) THEN DO i1 = LBOUND(VTK_SurfaceTypeData%BladeShape,1), UBOUND(VTK_SurfaceTypeData%BladeShape,1) - CALL FAST_Destroyvtk_blsurfacetype( VTK_SurfaceTypeData%BladeShape(i1), ErrStat, ErrMsg ) + CALL FAST_Destroyvtk_blsurfacetype( VTK_SurfaceTypeData%BladeShape(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(VTK_SurfaceTypeData%BladeShape) ENDIF @@ -1640,15 +1676,27 @@ SUBROUTINE FAST_CopyVTK_ModeShapeType( SrcVTK_ModeShapeTypeData, DstVTK_ModeShap ENDIF END SUBROUTINE FAST_CopyVTK_ModeShapeType - SUBROUTINE FAST_DestroyVTK_ModeShapeType( VTK_ModeShapeTypeData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyVTK_ModeShapeType( VTK_ModeShapeTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_VTK_ModeShapeType), INTENT(INOUT) :: VTK_ModeShapeTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyVTK_ModeShapeType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyVTK_ModeShapeType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(VTK_ModeShapeTypeData%VTKModes)) THEN DEALLOCATE(VTK_ModeShapeTypeData%VTKModes) ENDIF @@ -2116,6 +2164,9 @@ SUBROUTINE FAST_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%MHK = SrcParamData%MHK DstParamData%UseDWM = SrcParamData%UseDWM DstParamData%Linearize = SrcParamData%Linearize + DstParamData%WaveFieldMod = SrcParamData%WaveFieldMod + DstParamData%FarmIntegration = SrcParamData%FarmIntegration + DstParamData%TurbinePos = SrcParamData%TurbinePos DstParamData%Gravity = SrcParamData%Gravity DstParamData%AirDens = SrcParamData%AirDens DstParamData%WtrDens = SrcParamData%WtrDens @@ -2162,7 +2213,6 @@ SUBROUTINE FAST_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg CALL FAST_Copyvtk_surfacetype( SrcParamData%VTK_surface, DstParamData%VTK_surface, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN - DstParamData%TurbinePos = SrcParamData%TurbinePos DstParamData%Tdesc = SrcParamData%Tdesc DstParamData%CalcSteady = SrcParamData%CalcSteady DstParamData%TrimCase = SrcParamData%TrimCase @@ -2185,17 +2235,31 @@ SUBROUTINE FAST_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%LinInterpOrder = SrcParamData%LinInterpOrder END SUBROUTINE FAST_CopyParam - SUBROUTINE FAST_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" - CALL FAST_Destroyvtk_surfacetype( ParamData%VTK_surface, ErrStat, ErrMsg ) - CALL FAST_Destroyvtk_modeshapetype( ParamData%VTK_modes, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL FAST_Destroyvtk_surfacetype( ParamData%VTK_surface, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyvtk_modeshapetype( ParamData%VTK_modes, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE FAST_DestroyParam SUBROUTINE FAST_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2259,6 +2323,9 @@ SUBROUTINE FAST_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 1 ! MHK Int_BufSz = Int_BufSz + 1 ! UseDWM Int_BufSz = Int_BufSz + 1 ! Linearize + Int_BufSz = Int_BufSz + 1 ! WaveFieldMod + Int_BufSz = Int_BufSz + 1 ! FarmIntegration + Re_BufSz = Re_BufSz + SIZE(InData%TurbinePos) ! TurbinePos Re_BufSz = Re_BufSz + 1 ! Gravity Re_BufSz = Re_BufSz + 1 ! AirDens Re_BufSz = Re_BufSz + 1 ! WtrDens @@ -2320,7 +2387,6 @@ SUBROUTINE FAST_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF - Re_BufSz = Re_BufSz + SIZE(InData%TurbinePos) ! TurbinePos Int_BufSz = Int_BufSz + 1*LEN(InData%Tdesc) ! Tdesc Int_BufSz = Int_BufSz + 1 ! CalcSteady Int_BufSz = Int_BufSz + 1 ! TrimCase @@ -2442,6 +2508,14 @@ SUBROUTINE FAST_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%Linearize, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%WaveFieldMod + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%FarmIntegration, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO i1 = LBOUND(InData%TurbinePos,1), UBOUND(InData%TurbinePos,1) + ReKiBuf(Re_Xferred) = InData%TurbinePos(i1) + Re_Xferred = Re_Xferred + 1 + END DO ReKiBuf(Re_Xferred) = InData%Gravity Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%AirDens @@ -2588,10 +2662,6 @@ SUBROUTINE FAST_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, ELSE IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 ENDIF - DO i1 = LBOUND(InData%TurbinePos,1), UBOUND(InData%TurbinePos,1) - ReKiBuf(Re_Xferred) = InData%TurbinePos(i1) - Re_Xferred = Re_Xferred + 1 - END DO DO I = 1, LEN(InData%Tdesc) IntKiBuf(Int_Xferred) = ICHAR(InData%Tdesc(I:I), IntKi) Int_Xferred = Int_Xferred + 1 @@ -2755,6 +2825,16 @@ SUBROUTINE FAST_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs Int_Xferred = Int_Xferred + 1 OutData%Linearize = TRANSFER(IntKiBuf(Int_Xferred), OutData%Linearize) Int_Xferred = Int_Xferred + 1 + OutData%WaveFieldMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%FarmIntegration = TRANSFER(IntKiBuf(Int_Xferred), OutData%FarmIntegration) + Int_Xferred = Int_Xferred + 1 + i1_l = LBOUND(OutData%TurbinePos,1) + i1_u = UBOUND(OutData%TurbinePos,1) + DO i1 = LBOUND(OutData%TurbinePos,1), UBOUND(OutData%TurbinePos,1) + OutData%TurbinePos(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO OutData%Gravity = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%AirDens = ReKiBuf(Re_Xferred) @@ -2915,12 +2995,6 @@ SUBROUTINE FAST_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - i1_l = LBOUND(OutData%TurbinePos,1) - i1_u = UBOUND(OutData%TurbinePos,1) - DO i1 = LBOUND(OutData%TurbinePos,1), UBOUND(OutData%TurbinePos,1) - OutData%TurbinePos(i1) = REAL(ReKiBuf(Re_Xferred), SiKi) - Re_Xferred = Re_Xferred + 1 - END DO DO I = 1, LEN(OutData%Tdesc) OutData%Tdesc(I:I) = CHAR(IntKiBuf(Int_Xferred)) Int_Xferred = Int_Xferred + 1 @@ -4085,19 +4159,32 @@ SUBROUTINE FAST_CopyLinStateSave( SrcLinStateSaveData, DstLinStateSaveData, Ctrl ENDIF END SUBROUTINE FAST_CopyLinStateSave - SUBROUTINE FAST_DestroyLinStateSave( LinStateSaveData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyLinStateSave( LinStateSaveData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_LinStateSave), INTENT(INOUT) :: LinStateSaveData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyLinStateSave' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyLinStateSave' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(LinStateSaveData%x_IceD)) THEN DO i2 = LBOUND(LinStateSaveData%x_IceD,2), UBOUND(LinStateSaveData%x_IceD,2) DO i1 = LBOUND(LinStateSaveData%x_IceD,1), UBOUND(LinStateSaveData%x_IceD,1) - CALL IceD_DestroyContState( LinStateSaveData%x_IceD(i1,i2), ErrStat, ErrMsg ) + CALL IceD_DestroyContState( LinStateSaveData%x_IceD(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(LinStateSaveData%x_IceD) @@ -4105,7 +4192,8 @@ SUBROUTINE FAST_DestroyLinStateSave( LinStateSaveData, ErrStat, ErrMsg ) IF (ALLOCATED(LinStateSaveData%xd_IceD)) THEN DO i2 = LBOUND(LinStateSaveData%xd_IceD,2), UBOUND(LinStateSaveData%xd_IceD,2) DO i1 = LBOUND(LinStateSaveData%xd_IceD,1), UBOUND(LinStateSaveData%xd_IceD,1) - CALL IceD_DestroyDiscState( LinStateSaveData%xd_IceD(i1,i2), ErrStat, ErrMsg ) + CALL IceD_DestroyDiscState( LinStateSaveData%xd_IceD(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(LinStateSaveData%xd_IceD) @@ -4113,7 +4201,8 @@ SUBROUTINE FAST_DestroyLinStateSave( LinStateSaveData, ErrStat, ErrMsg ) IF (ALLOCATED(LinStateSaveData%z_IceD)) THEN DO i2 = LBOUND(LinStateSaveData%z_IceD,2), UBOUND(LinStateSaveData%z_IceD,2) DO i1 = LBOUND(LinStateSaveData%z_IceD,1), UBOUND(LinStateSaveData%z_IceD,1) - CALL IceD_DestroyConstrState( LinStateSaveData%z_IceD(i1,i2), ErrStat, ErrMsg ) + CALL IceD_DestroyConstrState( LinStateSaveData%z_IceD(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(LinStateSaveData%z_IceD) @@ -4121,7 +4210,8 @@ SUBROUTINE FAST_DestroyLinStateSave( LinStateSaveData, ErrStat, ErrMsg ) IF (ALLOCATED(LinStateSaveData%OtherSt_IceD)) THEN DO i2 = LBOUND(LinStateSaveData%OtherSt_IceD,2), UBOUND(LinStateSaveData%OtherSt_IceD,2) DO i1 = LBOUND(LinStateSaveData%OtherSt_IceD,1), UBOUND(LinStateSaveData%OtherSt_IceD,1) - CALL IceD_DestroyOtherState( LinStateSaveData%OtherSt_IceD(i1,i2), ErrStat, ErrMsg ) + CALL IceD_DestroyOtherState( LinStateSaveData%OtherSt_IceD(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(LinStateSaveData%OtherSt_IceD) @@ -4129,7 +4219,8 @@ SUBROUTINE FAST_DestroyLinStateSave( LinStateSaveData, ErrStat, ErrMsg ) IF (ALLOCATED(LinStateSaveData%u_IceD)) THEN DO i2 = LBOUND(LinStateSaveData%u_IceD,2), UBOUND(LinStateSaveData%u_IceD,2) DO i1 = LBOUND(LinStateSaveData%u_IceD,1), UBOUND(LinStateSaveData%u_IceD,1) - CALL IceD_DestroyInput( LinStateSaveData%u_IceD(i1,i2), ErrStat, ErrMsg ) + CALL IceD_DestroyInput( LinStateSaveData%u_IceD(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(LinStateSaveData%u_IceD) @@ -4137,7 +4228,8 @@ SUBROUTINE FAST_DestroyLinStateSave( LinStateSaveData, ErrStat, ErrMsg ) IF (ALLOCATED(LinStateSaveData%x_BD)) THEN DO i2 = LBOUND(LinStateSaveData%x_BD,2), UBOUND(LinStateSaveData%x_BD,2) DO i1 = LBOUND(LinStateSaveData%x_BD,1), UBOUND(LinStateSaveData%x_BD,1) - CALL BD_DestroyContState( LinStateSaveData%x_BD(i1,i2), ErrStat, ErrMsg ) + CALL BD_DestroyContState( LinStateSaveData%x_BD(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(LinStateSaveData%x_BD) @@ -4145,7 +4237,8 @@ SUBROUTINE FAST_DestroyLinStateSave( LinStateSaveData, ErrStat, ErrMsg ) IF (ALLOCATED(LinStateSaveData%xd_BD)) THEN DO i2 = LBOUND(LinStateSaveData%xd_BD,2), UBOUND(LinStateSaveData%xd_BD,2) DO i1 = LBOUND(LinStateSaveData%xd_BD,1), UBOUND(LinStateSaveData%xd_BD,1) - CALL BD_DestroyDiscState( LinStateSaveData%xd_BD(i1,i2), ErrStat, ErrMsg ) + CALL BD_DestroyDiscState( LinStateSaveData%xd_BD(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(LinStateSaveData%xd_BD) @@ -4153,7 +4246,8 @@ SUBROUTINE FAST_DestroyLinStateSave( LinStateSaveData, ErrStat, ErrMsg ) IF (ALLOCATED(LinStateSaveData%z_BD)) THEN DO i2 = LBOUND(LinStateSaveData%z_BD,2), UBOUND(LinStateSaveData%z_BD,2) DO i1 = LBOUND(LinStateSaveData%z_BD,1), UBOUND(LinStateSaveData%z_BD,1) - CALL BD_DestroyConstrState( LinStateSaveData%z_BD(i1,i2), ErrStat, ErrMsg ) + CALL BD_DestroyConstrState( LinStateSaveData%z_BD(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(LinStateSaveData%z_BD) @@ -4161,7 +4255,8 @@ SUBROUTINE FAST_DestroyLinStateSave( LinStateSaveData, ErrStat, ErrMsg ) IF (ALLOCATED(LinStateSaveData%OtherSt_BD)) THEN DO i2 = LBOUND(LinStateSaveData%OtherSt_BD,2), UBOUND(LinStateSaveData%OtherSt_BD,2) DO i1 = LBOUND(LinStateSaveData%OtherSt_BD,1), UBOUND(LinStateSaveData%OtherSt_BD,1) - CALL BD_DestroyOtherState( LinStateSaveData%OtherSt_BD(i1,i2), ErrStat, ErrMsg ) + CALL BD_DestroyOtherState( LinStateSaveData%OtherSt_BD(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(LinStateSaveData%OtherSt_BD) @@ -4169,332 +4264,387 @@ SUBROUTINE FAST_DestroyLinStateSave( LinStateSaveData, ErrStat, ErrMsg ) IF (ALLOCATED(LinStateSaveData%u_BD)) THEN DO i2 = LBOUND(LinStateSaveData%u_BD,2), UBOUND(LinStateSaveData%u_BD,2) DO i1 = LBOUND(LinStateSaveData%u_BD,1), UBOUND(LinStateSaveData%u_BD,1) - CALL BD_DestroyInput( LinStateSaveData%u_BD(i1,i2), ErrStat, ErrMsg ) + CALL BD_DestroyInput( LinStateSaveData%u_BD(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(LinStateSaveData%u_BD) ENDIF IF (ALLOCATED(LinStateSaveData%x_ED)) THEN DO i1 = LBOUND(LinStateSaveData%x_ED,1), UBOUND(LinStateSaveData%x_ED,1) - CALL ED_DestroyContState( LinStateSaveData%x_ED(i1), ErrStat, ErrMsg ) + CALL ED_DestroyContState( LinStateSaveData%x_ED(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%x_ED) ENDIF IF (ALLOCATED(LinStateSaveData%xd_ED)) THEN DO i1 = LBOUND(LinStateSaveData%xd_ED,1), UBOUND(LinStateSaveData%xd_ED,1) - CALL ED_DestroyDiscState( LinStateSaveData%xd_ED(i1), ErrStat, ErrMsg ) + CALL ED_DestroyDiscState( LinStateSaveData%xd_ED(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%xd_ED) ENDIF IF (ALLOCATED(LinStateSaveData%z_ED)) THEN DO i1 = LBOUND(LinStateSaveData%z_ED,1), UBOUND(LinStateSaveData%z_ED,1) - CALL ED_DestroyConstrState( LinStateSaveData%z_ED(i1), ErrStat, ErrMsg ) + CALL ED_DestroyConstrState( LinStateSaveData%z_ED(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%z_ED) ENDIF IF (ALLOCATED(LinStateSaveData%OtherSt_ED)) THEN DO i1 = LBOUND(LinStateSaveData%OtherSt_ED,1), UBOUND(LinStateSaveData%OtherSt_ED,1) - CALL ED_DestroyOtherState( LinStateSaveData%OtherSt_ED(i1), ErrStat, ErrMsg ) + CALL ED_DestroyOtherState( LinStateSaveData%OtherSt_ED(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%OtherSt_ED) ENDIF IF (ALLOCATED(LinStateSaveData%u_ED)) THEN DO i1 = LBOUND(LinStateSaveData%u_ED,1), UBOUND(LinStateSaveData%u_ED,1) - CALL ED_DestroyInput( LinStateSaveData%u_ED(i1), ErrStat, ErrMsg ) + CALL ED_DestroyInput( LinStateSaveData%u_ED(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%u_ED) ENDIF IF (ALLOCATED(LinStateSaveData%x_SrvD)) THEN DO i1 = LBOUND(LinStateSaveData%x_SrvD,1), UBOUND(LinStateSaveData%x_SrvD,1) - CALL SrvD_DestroyContState( LinStateSaveData%x_SrvD(i1), ErrStat, ErrMsg ) + CALL SrvD_DestroyContState( LinStateSaveData%x_SrvD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%x_SrvD) ENDIF IF (ALLOCATED(LinStateSaveData%xd_SrvD)) THEN DO i1 = LBOUND(LinStateSaveData%xd_SrvD,1), UBOUND(LinStateSaveData%xd_SrvD,1) - CALL SrvD_DestroyDiscState( LinStateSaveData%xd_SrvD(i1), ErrStat, ErrMsg ) + CALL SrvD_DestroyDiscState( LinStateSaveData%xd_SrvD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%xd_SrvD) ENDIF IF (ALLOCATED(LinStateSaveData%z_SrvD)) THEN DO i1 = LBOUND(LinStateSaveData%z_SrvD,1), UBOUND(LinStateSaveData%z_SrvD,1) - CALL SrvD_DestroyConstrState( LinStateSaveData%z_SrvD(i1), ErrStat, ErrMsg ) + CALL SrvD_DestroyConstrState( LinStateSaveData%z_SrvD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%z_SrvD) ENDIF IF (ALLOCATED(LinStateSaveData%OtherSt_SrvD)) THEN DO i1 = LBOUND(LinStateSaveData%OtherSt_SrvD,1), UBOUND(LinStateSaveData%OtherSt_SrvD,1) - CALL SrvD_DestroyOtherState( LinStateSaveData%OtherSt_SrvD(i1), ErrStat, ErrMsg ) + CALL SrvD_DestroyOtherState( LinStateSaveData%OtherSt_SrvD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%OtherSt_SrvD) ENDIF IF (ALLOCATED(LinStateSaveData%u_SrvD)) THEN DO i1 = LBOUND(LinStateSaveData%u_SrvD,1), UBOUND(LinStateSaveData%u_SrvD,1) - CALL SrvD_DestroyInput( LinStateSaveData%u_SrvD(i1), ErrStat, ErrMsg ) + CALL SrvD_DestroyInput( LinStateSaveData%u_SrvD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%u_SrvD) ENDIF IF (ALLOCATED(LinStateSaveData%x_AD)) THEN DO i1 = LBOUND(LinStateSaveData%x_AD,1), UBOUND(LinStateSaveData%x_AD,1) - CALL AD_DestroyContState( LinStateSaveData%x_AD(i1), ErrStat, ErrMsg ) + CALL AD_DestroyContState( LinStateSaveData%x_AD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%x_AD) ENDIF IF (ALLOCATED(LinStateSaveData%xd_AD)) THEN DO i1 = LBOUND(LinStateSaveData%xd_AD,1), UBOUND(LinStateSaveData%xd_AD,1) - CALL AD_DestroyDiscState( LinStateSaveData%xd_AD(i1), ErrStat, ErrMsg ) + CALL AD_DestroyDiscState( LinStateSaveData%xd_AD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%xd_AD) ENDIF IF (ALLOCATED(LinStateSaveData%z_AD)) THEN DO i1 = LBOUND(LinStateSaveData%z_AD,1), UBOUND(LinStateSaveData%z_AD,1) - CALL AD_DestroyConstrState( LinStateSaveData%z_AD(i1), ErrStat, ErrMsg ) + CALL AD_DestroyConstrState( LinStateSaveData%z_AD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%z_AD) ENDIF IF (ALLOCATED(LinStateSaveData%OtherSt_AD)) THEN DO i1 = LBOUND(LinStateSaveData%OtherSt_AD,1), UBOUND(LinStateSaveData%OtherSt_AD,1) - CALL AD_DestroyOtherState( LinStateSaveData%OtherSt_AD(i1), ErrStat, ErrMsg ) + CALL AD_DestroyOtherState( LinStateSaveData%OtherSt_AD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%OtherSt_AD) ENDIF IF (ALLOCATED(LinStateSaveData%u_AD)) THEN DO i1 = LBOUND(LinStateSaveData%u_AD,1), UBOUND(LinStateSaveData%u_AD,1) - CALL AD_DestroyInput( LinStateSaveData%u_AD(i1), ErrStat, ErrMsg ) + CALL AD_DestroyInput( LinStateSaveData%u_AD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%u_AD) ENDIF IF (ALLOCATED(LinStateSaveData%x_IfW)) THEN DO i1 = LBOUND(LinStateSaveData%x_IfW,1), UBOUND(LinStateSaveData%x_IfW,1) - CALL InflowWind_DestroyContState( LinStateSaveData%x_IfW(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyContState( LinStateSaveData%x_IfW(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%x_IfW) ENDIF IF (ALLOCATED(LinStateSaveData%xd_IfW)) THEN DO i1 = LBOUND(LinStateSaveData%xd_IfW,1), UBOUND(LinStateSaveData%xd_IfW,1) - CALL InflowWind_DestroyDiscState( LinStateSaveData%xd_IfW(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyDiscState( LinStateSaveData%xd_IfW(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%xd_IfW) ENDIF IF (ALLOCATED(LinStateSaveData%z_IfW)) THEN DO i1 = LBOUND(LinStateSaveData%z_IfW,1), UBOUND(LinStateSaveData%z_IfW,1) - CALL InflowWind_DestroyConstrState( LinStateSaveData%z_IfW(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyConstrState( LinStateSaveData%z_IfW(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%z_IfW) ENDIF IF (ALLOCATED(LinStateSaveData%OtherSt_IfW)) THEN DO i1 = LBOUND(LinStateSaveData%OtherSt_IfW,1), UBOUND(LinStateSaveData%OtherSt_IfW,1) - CALL InflowWind_DestroyOtherState( LinStateSaveData%OtherSt_IfW(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyOtherState( LinStateSaveData%OtherSt_IfW(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%OtherSt_IfW) ENDIF IF (ALLOCATED(LinStateSaveData%u_IfW)) THEN DO i1 = LBOUND(LinStateSaveData%u_IfW,1), UBOUND(LinStateSaveData%u_IfW,1) - CALL InflowWind_DestroyInput( LinStateSaveData%u_IfW(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyInput( LinStateSaveData%u_IfW(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%u_IfW) ENDIF IF (ALLOCATED(LinStateSaveData%x_SD)) THEN DO i1 = LBOUND(LinStateSaveData%x_SD,1), UBOUND(LinStateSaveData%x_SD,1) - CALL SD_DestroyContState( LinStateSaveData%x_SD(i1), ErrStat, ErrMsg ) + CALL SD_DestroyContState( LinStateSaveData%x_SD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%x_SD) ENDIF IF (ALLOCATED(LinStateSaveData%xd_SD)) THEN DO i1 = LBOUND(LinStateSaveData%xd_SD,1), UBOUND(LinStateSaveData%xd_SD,1) - CALL SD_DestroyDiscState( LinStateSaveData%xd_SD(i1), ErrStat, ErrMsg ) + CALL SD_DestroyDiscState( LinStateSaveData%xd_SD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%xd_SD) ENDIF IF (ALLOCATED(LinStateSaveData%z_SD)) THEN DO i1 = LBOUND(LinStateSaveData%z_SD,1), UBOUND(LinStateSaveData%z_SD,1) - CALL SD_DestroyConstrState( LinStateSaveData%z_SD(i1), ErrStat, ErrMsg ) + CALL SD_DestroyConstrState( LinStateSaveData%z_SD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%z_SD) ENDIF IF (ALLOCATED(LinStateSaveData%OtherSt_SD)) THEN DO i1 = LBOUND(LinStateSaveData%OtherSt_SD,1), UBOUND(LinStateSaveData%OtherSt_SD,1) - CALL SD_DestroyOtherState( LinStateSaveData%OtherSt_SD(i1), ErrStat, ErrMsg ) + CALL SD_DestroyOtherState( LinStateSaveData%OtherSt_SD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%OtherSt_SD) ENDIF IF (ALLOCATED(LinStateSaveData%u_SD)) THEN DO i1 = LBOUND(LinStateSaveData%u_SD,1), UBOUND(LinStateSaveData%u_SD,1) - CALL SD_DestroyInput( LinStateSaveData%u_SD(i1), ErrStat, ErrMsg ) + CALL SD_DestroyInput( LinStateSaveData%u_SD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%u_SD) ENDIF IF (ALLOCATED(LinStateSaveData%x_ExtPtfm)) THEN DO i1 = LBOUND(LinStateSaveData%x_ExtPtfm,1), UBOUND(LinStateSaveData%x_ExtPtfm,1) - CALL ExtPtfm_DestroyContState( LinStateSaveData%x_ExtPtfm(i1), ErrStat, ErrMsg ) + CALL ExtPtfm_DestroyContState( LinStateSaveData%x_ExtPtfm(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%x_ExtPtfm) ENDIF IF (ALLOCATED(LinStateSaveData%xd_ExtPtfm)) THEN DO i1 = LBOUND(LinStateSaveData%xd_ExtPtfm,1), UBOUND(LinStateSaveData%xd_ExtPtfm,1) - CALL ExtPtfm_DestroyDiscState( LinStateSaveData%xd_ExtPtfm(i1), ErrStat, ErrMsg ) + CALL ExtPtfm_DestroyDiscState( LinStateSaveData%xd_ExtPtfm(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%xd_ExtPtfm) ENDIF IF (ALLOCATED(LinStateSaveData%z_ExtPtfm)) THEN DO i1 = LBOUND(LinStateSaveData%z_ExtPtfm,1), UBOUND(LinStateSaveData%z_ExtPtfm,1) - CALL ExtPtfm_DestroyConstrState( LinStateSaveData%z_ExtPtfm(i1), ErrStat, ErrMsg ) + CALL ExtPtfm_DestroyConstrState( LinStateSaveData%z_ExtPtfm(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%z_ExtPtfm) ENDIF IF (ALLOCATED(LinStateSaveData%OtherSt_ExtPtfm)) THEN DO i1 = LBOUND(LinStateSaveData%OtherSt_ExtPtfm,1), UBOUND(LinStateSaveData%OtherSt_ExtPtfm,1) - CALL ExtPtfm_DestroyOtherState( LinStateSaveData%OtherSt_ExtPtfm(i1), ErrStat, ErrMsg ) + CALL ExtPtfm_DestroyOtherState( LinStateSaveData%OtherSt_ExtPtfm(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%OtherSt_ExtPtfm) ENDIF IF (ALLOCATED(LinStateSaveData%u_ExtPtfm)) THEN DO i1 = LBOUND(LinStateSaveData%u_ExtPtfm,1), UBOUND(LinStateSaveData%u_ExtPtfm,1) - CALL ExtPtfm_DestroyInput( LinStateSaveData%u_ExtPtfm(i1), ErrStat, ErrMsg ) + CALL ExtPtfm_DestroyInput( LinStateSaveData%u_ExtPtfm(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%u_ExtPtfm) ENDIF IF (ALLOCATED(LinStateSaveData%x_HD)) THEN DO i1 = LBOUND(LinStateSaveData%x_HD,1), UBOUND(LinStateSaveData%x_HD,1) - CALL HydroDyn_DestroyContState( LinStateSaveData%x_HD(i1), ErrStat, ErrMsg ) + CALL HydroDyn_DestroyContState( LinStateSaveData%x_HD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%x_HD) ENDIF IF (ALLOCATED(LinStateSaveData%xd_HD)) THEN DO i1 = LBOUND(LinStateSaveData%xd_HD,1), UBOUND(LinStateSaveData%xd_HD,1) - CALL HydroDyn_DestroyDiscState( LinStateSaveData%xd_HD(i1), ErrStat, ErrMsg ) + CALL HydroDyn_DestroyDiscState( LinStateSaveData%xd_HD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%xd_HD) ENDIF IF (ALLOCATED(LinStateSaveData%z_HD)) THEN DO i1 = LBOUND(LinStateSaveData%z_HD,1), UBOUND(LinStateSaveData%z_HD,1) - CALL HydroDyn_DestroyConstrState( LinStateSaveData%z_HD(i1), ErrStat, ErrMsg ) + CALL HydroDyn_DestroyConstrState( LinStateSaveData%z_HD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%z_HD) ENDIF IF (ALLOCATED(LinStateSaveData%OtherSt_HD)) THEN DO i1 = LBOUND(LinStateSaveData%OtherSt_HD,1), UBOUND(LinStateSaveData%OtherSt_HD,1) - CALL HydroDyn_DestroyOtherState( LinStateSaveData%OtherSt_HD(i1), ErrStat, ErrMsg ) + CALL HydroDyn_DestroyOtherState( LinStateSaveData%OtherSt_HD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%OtherSt_HD) ENDIF IF (ALLOCATED(LinStateSaveData%u_HD)) THEN DO i1 = LBOUND(LinStateSaveData%u_HD,1), UBOUND(LinStateSaveData%u_HD,1) - CALL HydroDyn_DestroyInput( LinStateSaveData%u_HD(i1), ErrStat, ErrMsg ) + CALL HydroDyn_DestroyInput( LinStateSaveData%u_HD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%u_HD) ENDIF IF (ALLOCATED(LinStateSaveData%x_IceF)) THEN DO i1 = LBOUND(LinStateSaveData%x_IceF,1), UBOUND(LinStateSaveData%x_IceF,1) - CALL IceFloe_DestroyContState( LinStateSaveData%x_IceF(i1), ErrStat, ErrMsg ) + CALL IceFloe_DestroyContState( LinStateSaveData%x_IceF(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%x_IceF) ENDIF IF (ALLOCATED(LinStateSaveData%xd_IceF)) THEN DO i1 = LBOUND(LinStateSaveData%xd_IceF,1), UBOUND(LinStateSaveData%xd_IceF,1) - CALL IceFloe_DestroyDiscState( LinStateSaveData%xd_IceF(i1), ErrStat, ErrMsg ) + CALL IceFloe_DestroyDiscState( LinStateSaveData%xd_IceF(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%xd_IceF) ENDIF IF (ALLOCATED(LinStateSaveData%z_IceF)) THEN DO i1 = LBOUND(LinStateSaveData%z_IceF,1), UBOUND(LinStateSaveData%z_IceF,1) - CALL IceFloe_DestroyConstrState( LinStateSaveData%z_IceF(i1), ErrStat, ErrMsg ) + CALL IceFloe_DestroyConstrState( LinStateSaveData%z_IceF(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%z_IceF) ENDIF IF (ALLOCATED(LinStateSaveData%OtherSt_IceF)) THEN DO i1 = LBOUND(LinStateSaveData%OtherSt_IceF,1), UBOUND(LinStateSaveData%OtherSt_IceF,1) - CALL IceFloe_DestroyOtherState( LinStateSaveData%OtherSt_IceF(i1), ErrStat, ErrMsg ) + CALL IceFloe_DestroyOtherState( LinStateSaveData%OtherSt_IceF(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%OtherSt_IceF) ENDIF IF (ALLOCATED(LinStateSaveData%u_IceF)) THEN DO i1 = LBOUND(LinStateSaveData%u_IceF,1), UBOUND(LinStateSaveData%u_IceF,1) - CALL IceFloe_DestroyInput( LinStateSaveData%u_IceF(i1), ErrStat, ErrMsg ) + CALL IceFloe_DestroyInput( LinStateSaveData%u_IceF(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%u_IceF) ENDIF IF (ALLOCATED(LinStateSaveData%x_MAP)) THEN DO i1 = LBOUND(LinStateSaveData%x_MAP,1), UBOUND(LinStateSaveData%x_MAP,1) - CALL MAP_DestroyContState( LinStateSaveData%x_MAP(i1), ErrStat, ErrMsg ) + CALL MAP_DestroyContState( LinStateSaveData%x_MAP(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%x_MAP) ENDIF IF (ALLOCATED(LinStateSaveData%xd_MAP)) THEN DO i1 = LBOUND(LinStateSaveData%xd_MAP,1), UBOUND(LinStateSaveData%xd_MAP,1) - CALL MAP_DestroyDiscState( LinStateSaveData%xd_MAP(i1), ErrStat, ErrMsg ) + CALL MAP_DestroyDiscState( LinStateSaveData%xd_MAP(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%xd_MAP) ENDIF IF (ALLOCATED(LinStateSaveData%z_MAP)) THEN DO i1 = LBOUND(LinStateSaveData%z_MAP,1), UBOUND(LinStateSaveData%z_MAP,1) - CALL MAP_DestroyConstrState( LinStateSaveData%z_MAP(i1), ErrStat, ErrMsg ) + CALL MAP_DestroyConstrState( LinStateSaveData%z_MAP(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%z_MAP) ENDIF IF (ALLOCATED(LinStateSaveData%u_MAP)) THEN DO i1 = LBOUND(LinStateSaveData%u_MAP,1), UBOUND(LinStateSaveData%u_MAP,1) - CALL MAP_DestroyInput( LinStateSaveData%u_MAP(i1), ErrStat, ErrMsg ) + CALL MAP_DestroyInput( LinStateSaveData%u_MAP(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%u_MAP) ENDIF IF (ALLOCATED(LinStateSaveData%x_FEAM)) THEN DO i1 = LBOUND(LinStateSaveData%x_FEAM,1), UBOUND(LinStateSaveData%x_FEAM,1) - CALL FEAM_DestroyContState( LinStateSaveData%x_FEAM(i1), ErrStat, ErrMsg ) + CALL FEAM_DestroyContState( LinStateSaveData%x_FEAM(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%x_FEAM) ENDIF IF (ALLOCATED(LinStateSaveData%xd_FEAM)) THEN DO i1 = LBOUND(LinStateSaveData%xd_FEAM,1), UBOUND(LinStateSaveData%xd_FEAM,1) - CALL FEAM_DestroyDiscState( LinStateSaveData%xd_FEAM(i1), ErrStat, ErrMsg ) + CALL FEAM_DestroyDiscState( LinStateSaveData%xd_FEAM(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%xd_FEAM) ENDIF IF (ALLOCATED(LinStateSaveData%z_FEAM)) THEN DO i1 = LBOUND(LinStateSaveData%z_FEAM,1), UBOUND(LinStateSaveData%z_FEAM,1) - CALL FEAM_DestroyConstrState( LinStateSaveData%z_FEAM(i1), ErrStat, ErrMsg ) + CALL FEAM_DestroyConstrState( LinStateSaveData%z_FEAM(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%z_FEAM) ENDIF IF (ALLOCATED(LinStateSaveData%OtherSt_FEAM)) THEN DO i1 = LBOUND(LinStateSaveData%OtherSt_FEAM,1), UBOUND(LinStateSaveData%OtherSt_FEAM,1) - CALL FEAM_DestroyOtherState( LinStateSaveData%OtherSt_FEAM(i1), ErrStat, ErrMsg ) + CALL FEAM_DestroyOtherState( LinStateSaveData%OtherSt_FEAM(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%OtherSt_FEAM) ENDIF IF (ALLOCATED(LinStateSaveData%u_FEAM)) THEN DO i1 = LBOUND(LinStateSaveData%u_FEAM,1), UBOUND(LinStateSaveData%u_FEAM,1) - CALL FEAM_DestroyInput( LinStateSaveData%u_FEAM(i1), ErrStat, ErrMsg ) + CALL FEAM_DestroyInput( LinStateSaveData%u_FEAM(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%u_FEAM) ENDIF IF (ALLOCATED(LinStateSaveData%x_MD)) THEN DO i1 = LBOUND(LinStateSaveData%x_MD,1), UBOUND(LinStateSaveData%x_MD,1) - CALL MD_DestroyContState( LinStateSaveData%x_MD(i1), ErrStat, ErrMsg ) + CALL MD_DestroyContState( LinStateSaveData%x_MD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%x_MD) ENDIF IF (ALLOCATED(LinStateSaveData%xd_MD)) THEN DO i1 = LBOUND(LinStateSaveData%xd_MD,1), UBOUND(LinStateSaveData%xd_MD,1) - CALL MD_DestroyDiscState( LinStateSaveData%xd_MD(i1), ErrStat, ErrMsg ) + CALL MD_DestroyDiscState( LinStateSaveData%xd_MD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%xd_MD) ENDIF IF (ALLOCATED(LinStateSaveData%z_MD)) THEN DO i1 = LBOUND(LinStateSaveData%z_MD,1), UBOUND(LinStateSaveData%z_MD,1) - CALL MD_DestroyConstrState( LinStateSaveData%z_MD(i1), ErrStat, ErrMsg ) + CALL MD_DestroyConstrState( LinStateSaveData%z_MD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%z_MD) ENDIF IF (ALLOCATED(LinStateSaveData%OtherSt_MD)) THEN DO i1 = LBOUND(LinStateSaveData%OtherSt_MD,1), UBOUND(LinStateSaveData%OtherSt_MD,1) - CALL MD_DestroyOtherState( LinStateSaveData%OtherSt_MD(i1), ErrStat, ErrMsg ) + CALL MD_DestroyOtherState( LinStateSaveData%OtherSt_MD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%OtherSt_MD) ENDIF IF (ALLOCATED(LinStateSaveData%u_MD)) THEN DO i1 = LBOUND(LinStateSaveData%u_MD,1), UBOUND(LinStateSaveData%u_MD,1) - CALL MD_DestroyInput( LinStateSaveData%u_MD(i1), ErrStat, ErrMsg ) + CALL MD_DestroyInput( LinStateSaveData%u_MD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(LinStateSaveData%u_MD) ENDIF @@ -12766,15 +12916,27 @@ SUBROUTINE FAST_CopyLinType( SrcLinTypeData, DstLinTypeData, CtrlCode, ErrStat, DstLinTypeData%NumOutputs = SrcLinTypeData%NumOutputs END SUBROUTINE FAST_CopyLinType - SUBROUTINE FAST_DestroyLinType( LinTypeData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyLinType( LinTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_LinType), INTENT(INOUT) :: LinTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyLinType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyLinType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(LinTypeData%Names_u)) THEN DEALLOCATE(LinTypeData%Names_u) ENDIF @@ -14169,18 +14331,31 @@ SUBROUTINE FAST_CopyModLinType( SrcModLinTypeData, DstModLinTypeData, CtrlCode, ENDIF END SUBROUTINE FAST_CopyModLinType - SUBROUTINE FAST_DestroyModLinType( ModLinTypeData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyModLinType( ModLinTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_ModLinType), INTENT(INOUT) :: ModLinTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyModLinType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyModLinType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ModLinTypeData%Instance)) THEN DO i1 = LBOUND(ModLinTypeData%Instance,1), UBOUND(ModLinTypeData%Instance,1) - CALL FAST_Destroylintype( ModLinTypeData%Instance(i1), ErrStat, ErrMsg ) + CALL FAST_Destroylintype( ModLinTypeData%Instance(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModLinTypeData%Instance) ENDIF @@ -14428,19 +14603,33 @@ SUBROUTINE FAST_CopyLinFileType( SrcLinFileTypeData, DstLinFileTypeData, CtrlCod DstLinFileTypeData%WindSpeed = SrcLinFileTypeData%WindSpeed END SUBROUTINE FAST_CopyLinFileType - SUBROUTINE FAST_DestroyLinFileType( LinFileTypeData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyLinFileType( LinFileTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_LinFileType), INTENT(INOUT) :: LinFileTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyLinFileType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyLinFileType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(LinFileTypeData%Modules,1), UBOUND(LinFileTypeData%Modules,1) - CALL FAST_Destroymodlintype( LinFileTypeData%Modules(i1), ErrStat, ErrMsg ) + CALL FAST_Destroymodlintype( LinFileTypeData%Modules(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL FAST_Destroylintype( LinFileTypeData%Glue, ErrStat, ErrMsg ) + CALL FAST_Destroylintype( LinFileTypeData%Glue, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE FAST_DestroyLinFileType SUBROUTINE FAST_PackLinFileType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -14829,15 +15018,27 @@ SUBROUTINE FAST_CopyMiscLinType( SrcMiscLinTypeData, DstMiscLinTypeData, CtrlCod ENDIF END SUBROUTINE FAST_CopyMiscLinType - SUBROUTINE FAST_DestroyMiscLinType( MiscLinTypeData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyMiscLinType( MiscLinTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_MiscLinType), INTENT(INOUT) :: MiscLinTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyMiscLinType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyMiscLinType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscLinTypeData%LinTimes)) THEN DEALLOCATE(MiscLinTypeData%LinTimes) ENDIF @@ -15318,15 +15519,27 @@ SUBROUTINE FAST_CopyOutputFileType( SrcOutputFileTypeData, DstOutputFileTypeData DstOutputFileTypeData%DriverWriteOutput = SrcOutputFileTypeData%DriverWriteOutput END SUBROUTINE FAST_CopyOutputFileType - SUBROUTINE FAST_DestroyOutputFileType( OutputFileTypeData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyOutputFileType( OutputFileTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_OutputFileType), INTENT(INOUT) :: OutputFileTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyOutputFileType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyOutputFileType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputFileTypeData%TimeData)) THEN DEALLOCATE(OutputFileTypeData%TimeData) ENDIF @@ -15340,10 +15553,13 @@ SUBROUTINE FAST_DestroyOutputFileType( OutputFileTypeData, ErrStat, ErrMsg ) DEALLOCATE(OutputFileTypeData%ChannelUnits) ENDIF DO i1 = LBOUND(OutputFileTypeData%Module_Ver,1), UBOUND(OutputFileTypeData%Module_Ver,1) - CALL NWTC_Library_Destroyprogdesc( OutputFileTypeData%Module_Ver(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( OutputFileTypeData%Module_Ver(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL FAST_Destroylinfiletype( OutputFileTypeData%Lin, ErrStat, ErrMsg ) - CALL FAST_Destroylinstatesave( OutputFileTypeData%op, ErrStat, ErrMsg ) + CALL FAST_Destroylinfiletype( OutputFileTypeData%Lin, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroylinstatesave( OutputFileTypeData%op, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE FAST_DestroyOutputFileType SUBROUTINE FAST_PackOutputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -16176,19 +16392,32 @@ SUBROUTINE FAST_CopyIceDyn_Data( SrcIceDyn_DataData, DstIceDyn_DataData, CtrlCod ENDIF END SUBROUTINE FAST_CopyIceDyn_Data - SUBROUTINE FAST_DestroyIceDyn_Data( IceDyn_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyIceDyn_Data( IceDyn_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceDyn_Data), INTENT(INOUT) :: IceDyn_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyIceDyn_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyIceDyn_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(IceDyn_DataData%x)) THEN DO i2 = LBOUND(IceDyn_DataData%x,2), UBOUND(IceDyn_DataData%x,2) DO i1 = LBOUND(IceDyn_DataData%x,1), UBOUND(IceDyn_DataData%x,1) - CALL IceD_DestroyContState( IceDyn_DataData%x(i1,i2), ErrStat, ErrMsg ) + CALL IceD_DestroyContState( IceDyn_DataData%x(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(IceDyn_DataData%x) @@ -16196,7 +16425,8 @@ SUBROUTINE FAST_DestroyIceDyn_Data( IceDyn_DataData, ErrStat, ErrMsg ) IF (ALLOCATED(IceDyn_DataData%xd)) THEN DO i2 = LBOUND(IceDyn_DataData%xd,2), UBOUND(IceDyn_DataData%xd,2) DO i1 = LBOUND(IceDyn_DataData%xd,1), UBOUND(IceDyn_DataData%xd,1) - CALL IceD_DestroyDiscState( IceDyn_DataData%xd(i1,i2), ErrStat, ErrMsg ) + CALL IceD_DestroyDiscState( IceDyn_DataData%xd(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(IceDyn_DataData%xd) @@ -16204,7 +16434,8 @@ SUBROUTINE FAST_DestroyIceDyn_Data( IceDyn_DataData, ErrStat, ErrMsg ) IF (ALLOCATED(IceDyn_DataData%z)) THEN DO i2 = LBOUND(IceDyn_DataData%z,2), UBOUND(IceDyn_DataData%z,2) DO i1 = LBOUND(IceDyn_DataData%z,1), UBOUND(IceDyn_DataData%z,1) - CALL IceD_DestroyConstrState( IceDyn_DataData%z(i1,i2), ErrStat, ErrMsg ) + CALL IceD_DestroyConstrState( IceDyn_DataData%z(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(IceDyn_DataData%z) @@ -16212,39 +16443,45 @@ SUBROUTINE FAST_DestroyIceDyn_Data( IceDyn_DataData, ErrStat, ErrMsg ) IF (ALLOCATED(IceDyn_DataData%OtherSt)) THEN DO i2 = LBOUND(IceDyn_DataData%OtherSt,2), UBOUND(IceDyn_DataData%OtherSt,2) DO i1 = LBOUND(IceDyn_DataData%OtherSt,1), UBOUND(IceDyn_DataData%OtherSt,1) - CALL IceD_DestroyOtherState( IceDyn_DataData%OtherSt(i1,i2), ErrStat, ErrMsg ) + CALL IceD_DestroyOtherState( IceDyn_DataData%OtherSt(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(IceDyn_DataData%OtherSt) ENDIF IF (ALLOCATED(IceDyn_DataData%p)) THEN DO i1 = LBOUND(IceDyn_DataData%p,1), UBOUND(IceDyn_DataData%p,1) - CALL IceD_DestroyParam( IceDyn_DataData%p(i1), ErrStat, ErrMsg ) + CALL IceD_DestroyParam( IceDyn_DataData%p(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(IceDyn_DataData%p) ENDIF IF (ALLOCATED(IceDyn_DataData%u)) THEN DO i1 = LBOUND(IceDyn_DataData%u,1), UBOUND(IceDyn_DataData%u,1) - CALL IceD_DestroyInput( IceDyn_DataData%u(i1), ErrStat, ErrMsg ) + CALL IceD_DestroyInput( IceDyn_DataData%u(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(IceDyn_DataData%u) ENDIF IF (ALLOCATED(IceDyn_DataData%y)) THEN DO i1 = LBOUND(IceDyn_DataData%y,1), UBOUND(IceDyn_DataData%y,1) - CALL IceD_DestroyOutput( IceDyn_DataData%y(i1), ErrStat, ErrMsg ) + CALL IceD_DestroyOutput( IceDyn_DataData%y(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(IceDyn_DataData%y) ENDIF IF (ALLOCATED(IceDyn_DataData%m)) THEN DO i1 = LBOUND(IceDyn_DataData%m,1), UBOUND(IceDyn_DataData%m,1) - CALL IceD_DestroyMisc( IceDyn_DataData%m(i1), ErrStat, ErrMsg ) + CALL IceD_DestroyMisc( IceDyn_DataData%m(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(IceDyn_DataData%m) ENDIF IF (ALLOCATED(IceDyn_DataData%Input)) THEN DO i2 = LBOUND(IceDyn_DataData%Input,2), UBOUND(IceDyn_DataData%Input,2) DO i1 = LBOUND(IceDyn_DataData%Input,1), UBOUND(IceDyn_DataData%Input,1) - CALL IceD_DestroyInput( IceDyn_DataData%Input(i1,i2), ErrStat, ErrMsg ) + CALL IceD_DestroyInput( IceDyn_DataData%Input(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(IceDyn_DataData%Input) @@ -17769,19 +18006,32 @@ SUBROUTINE FAST_CopyBeamDyn_Data( SrcBeamDyn_DataData, DstBeamDyn_DataData, Ctrl ENDIF END SUBROUTINE FAST_CopyBeamDyn_Data - SUBROUTINE FAST_DestroyBeamDyn_Data( BeamDyn_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyBeamDyn_Data( BeamDyn_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BeamDyn_Data), INTENT(INOUT) :: BeamDyn_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyBeamDyn_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyBeamDyn_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(BeamDyn_DataData%x)) THEN DO i2 = LBOUND(BeamDyn_DataData%x,2), UBOUND(BeamDyn_DataData%x,2) DO i1 = LBOUND(BeamDyn_DataData%x,1), UBOUND(BeamDyn_DataData%x,1) - CALL BD_DestroyContState( BeamDyn_DataData%x(i1,i2), ErrStat, ErrMsg ) + CALL BD_DestroyContState( BeamDyn_DataData%x(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(BeamDyn_DataData%x) @@ -17789,7 +18039,8 @@ SUBROUTINE FAST_DestroyBeamDyn_Data( BeamDyn_DataData, ErrStat, ErrMsg ) IF (ALLOCATED(BeamDyn_DataData%xd)) THEN DO i2 = LBOUND(BeamDyn_DataData%xd,2), UBOUND(BeamDyn_DataData%xd,2) DO i1 = LBOUND(BeamDyn_DataData%xd,1), UBOUND(BeamDyn_DataData%xd,1) - CALL BD_DestroyDiscState( BeamDyn_DataData%xd(i1,i2), ErrStat, ErrMsg ) + CALL BD_DestroyDiscState( BeamDyn_DataData%xd(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(BeamDyn_DataData%xd) @@ -17797,7 +18048,8 @@ SUBROUTINE FAST_DestroyBeamDyn_Data( BeamDyn_DataData, ErrStat, ErrMsg ) IF (ALLOCATED(BeamDyn_DataData%z)) THEN DO i2 = LBOUND(BeamDyn_DataData%z,2), UBOUND(BeamDyn_DataData%z,2) DO i1 = LBOUND(BeamDyn_DataData%z,1), UBOUND(BeamDyn_DataData%z,1) - CALL BD_DestroyConstrState( BeamDyn_DataData%z(i1,i2), ErrStat, ErrMsg ) + CALL BD_DestroyConstrState( BeamDyn_DataData%z(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(BeamDyn_DataData%z) @@ -17805,53 +18057,61 @@ SUBROUTINE FAST_DestroyBeamDyn_Data( BeamDyn_DataData, ErrStat, ErrMsg ) IF (ALLOCATED(BeamDyn_DataData%OtherSt)) THEN DO i2 = LBOUND(BeamDyn_DataData%OtherSt,2), UBOUND(BeamDyn_DataData%OtherSt,2) DO i1 = LBOUND(BeamDyn_DataData%OtherSt,1), UBOUND(BeamDyn_DataData%OtherSt,1) - CALL BD_DestroyOtherState( BeamDyn_DataData%OtherSt(i1,i2), ErrStat, ErrMsg ) + CALL BD_DestroyOtherState( BeamDyn_DataData%OtherSt(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(BeamDyn_DataData%OtherSt) ENDIF IF (ALLOCATED(BeamDyn_DataData%p)) THEN DO i1 = LBOUND(BeamDyn_DataData%p,1), UBOUND(BeamDyn_DataData%p,1) - CALL BD_DestroyParam( BeamDyn_DataData%p(i1), ErrStat, ErrMsg ) + CALL BD_DestroyParam( BeamDyn_DataData%p(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(BeamDyn_DataData%p) ENDIF IF (ALLOCATED(BeamDyn_DataData%u)) THEN DO i1 = LBOUND(BeamDyn_DataData%u,1), UBOUND(BeamDyn_DataData%u,1) - CALL BD_DestroyInput( BeamDyn_DataData%u(i1), ErrStat, ErrMsg ) + CALL BD_DestroyInput( BeamDyn_DataData%u(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(BeamDyn_DataData%u) ENDIF IF (ALLOCATED(BeamDyn_DataData%y)) THEN DO i1 = LBOUND(BeamDyn_DataData%y,1), UBOUND(BeamDyn_DataData%y,1) - CALL BD_DestroyOutput( BeamDyn_DataData%y(i1), ErrStat, ErrMsg ) + CALL BD_DestroyOutput( BeamDyn_DataData%y(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(BeamDyn_DataData%y) ENDIF IF (ALLOCATED(BeamDyn_DataData%m)) THEN DO i1 = LBOUND(BeamDyn_DataData%m,1), UBOUND(BeamDyn_DataData%m,1) - CALL BD_DestroyMisc( BeamDyn_DataData%m(i1), ErrStat, ErrMsg ) + CALL BD_DestroyMisc( BeamDyn_DataData%m(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(BeamDyn_DataData%m) ENDIF IF (ALLOCATED(BeamDyn_DataData%Output)) THEN DO i2 = LBOUND(BeamDyn_DataData%Output,2), UBOUND(BeamDyn_DataData%Output,2) DO i1 = LBOUND(BeamDyn_DataData%Output,1), UBOUND(BeamDyn_DataData%Output,1) - CALL BD_DestroyOutput( BeamDyn_DataData%Output(i1,i2), ErrStat, ErrMsg ) + CALL BD_DestroyOutput( BeamDyn_DataData%Output(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(BeamDyn_DataData%Output) ENDIF IF (ALLOCATED(BeamDyn_DataData%y_interp)) THEN DO i1 = LBOUND(BeamDyn_DataData%y_interp,1), UBOUND(BeamDyn_DataData%y_interp,1) - CALL BD_DestroyOutput( BeamDyn_DataData%y_interp(i1), ErrStat, ErrMsg ) + CALL BD_DestroyOutput( BeamDyn_DataData%y_interp(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(BeamDyn_DataData%y_interp) ENDIF IF (ALLOCATED(BeamDyn_DataData%Input)) THEN DO i2 = LBOUND(BeamDyn_DataData%Input,2), UBOUND(BeamDyn_DataData%Input,2) DO i1 = LBOUND(BeamDyn_DataData%Input,1), UBOUND(BeamDyn_DataData%Input,1) - CALL BD_DestroyInput( BeamDyn_DataData%Input(i1,i2), ErrStat, ErrMsg ) + CALL BD_DestroyInput( BeamDyn_DataData%Input(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(BeamDyn_DataData%Input) @@ -19492,41 +19752,64 @@ SUBROUTINE FAST_CopyElastoDyn_Data( SrcElastoDyn_DataData, DstElastoDyn_DataData ENDIF END SUBROUTINE FAST_CopyElastoDyn_Data - SUBROUTINE FAST_DestroyElastoDyn_Data( ElastoDyn_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyElastoDyn_Data( ElastoDyn_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ElastoDyn_Data), INTENT(INOUT) :: ElastoDyn_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyElastoDyn_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyElastoDyn_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(ElastoDyn_DataData%x,1), UBOUND(ElastoDyn_DataData%x,1) - CALL ED_DestroyContState( ElastoDyn_DataData%x(i1), ErrStat, ErrMsg ) + CALL ED_DestroyContState( ElastoDyn_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(ElastoDyn_DataData%xd,1), UBOUND(ElastoDyn_DataData%xd,1) - CALL ED_DestroyDiscState( ElastoDyn_DataData%xd(i1), ErrStat, ErrMsg ) + CALL ED_DestroyDiscState( ElastoDyn_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(ElastoDyn_DataData%z,1), UBOUND(ElastoDyn_DataData%z,1) - CALL ED_DestroyConstrState( ElastoDyn_DataData%z(i1), ErrStat, ErrMsg ) + CALL ED_DestroyConstrState( ElastoDyn_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(ElastoDyn_DataData%OtherSt,1), UBOUND(ElastoDyn_DataData%OtherSt,1) - CALL ED_DestroyOtherState( ElastoDyn_DataData%OtherSt(i1), ErrStat, ErrMsg ) + CALL ED_DestroyOtherState( ElastoDyn_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL ED_DestroyParam( ElastoDyn_DataData%p, ErrStat, ErrMsg ) - CALL ED_DestroyInput( ElastoDyn_DataData%u, ErrStat, ErrMsg ) - CALL ED_DestroyOutput( ElastoDyn_DataData%y, ErrStat, ErrMsg ) - CALL ED_DestroyMisc( ElastoDyn_DataData%m, ErrStat, ErrMsg ) + CALL ED_DestroyParam( ElastoDyn_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ED_DestroyInput( ElastoDyn_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ED_DestroyOutput( ElastoDyn_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ED_DestroyMisc( ElastoDyn_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ElastoDyn_DataData%Output)) THEN DO i1 = LBOUND(ElastoDyn_DataData%Output,1), UBOUND(ElastoDyn_DataData%Output,1) - CALL ED_DestroyOutput( ElastoDyn_DataData%Output(i1), ErrStat, ErrMsg ) + CALL ED_DestroyOutput( ElastoDyn_DataData%Output(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ElastoDyn_DataData%Output) ENDIF - CALL ED_DestroyOutput( ElastoDyn_DataData%y_interp, ErrStat, ErrMsg ) + CALL ED_DestroyOutput( ElastoDyn_DataData%y_interp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ElastoDyn_DataData%Input)) THEN DO i1 = LBOUND(ElastoDyn_DataData%Input,1), UBOUND(ElastoDyn_DataData%Input,1) - CALL ED_DestroyInput( ElastoDyn_DataData%Input(i1), ErrStat, ErrMsg ) + CALL ED_DestroyInput( ElastoDyn_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ElastoDyn_DataData%Input) ENDIF @@ -20800,41 +21083,64 @@ SUBROUTINE FAST_CopyServoDyn_Data( SrcServoDyn_DataData, DstServoDyn_DataData, C ENDIF END SUBROUTINE FAST_CopyServoDyn_Data - SUBROUTINE FAST_DestroyServoDyn_Data( ServoDyn_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyServoDyn_Data( ServoDyn_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ServoDyn_Data), INTENT(INOUT) :: ServoDyn_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyServoDyn_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyServoDyn_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(ServoDyn_DataData%x,1), UBOUND(ServoDyn_DataData%x,1) - CALL SrvD_DestroyContState( ServoDyn_DataData%x(i1), ErrStat, ErrMsg ) + CALL SrvD_DestroyContState( ServoDyn_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(ServoDyn_DataData%xd,1), UBOUND(ServoDyn_DataData%xd,1) - CALL SrvD_DestroyDiscState( ServoDyn_DataData%xd(i1), ErrStat, ErrMsg ) + CALL SrvD_DestroyDiscState( ServoDyn_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(ServoDyn_DataData%z,1), UBOUND(ServoDyn_DataData%z,1) - CALL SrvD_DestroyConstrState( ServoDyn_DataData%z(i1), ErrStat, ErrMsg ) + CALL SrvD_DestroyConstrState( ServoDyn_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(ServoDyn_DataData%OtherSt,1), UBOUND(ServoDyn_DataData%OtherSt,1) - CALL SrvD_DestroyOtherState( ServoDyn_DataData%OtherSt(i1), ErrStat, ErrMsg ) + CALL SrvD_DestroyOtherState( ServoDyn_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL SrvD_DestroyParam( ServoDyn_DataData%p, ErrStat, ErrMsg ) - CALL SrvD_DestroyInput( ServoDyn_DataData%u, ErrStat, ErrMsg ) - CALL SrvD_DestroyOutput( ServoDyn_DataData%y, ErrStat, ErrMsg ) - CALL SrvD_DestroyMisc( ServoDyn_DataData%m, ErrStat, ErrMsg ) + CALL SrvD_DestroyParam( ServoDyn_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SrvD_DestroyInput( ServoDyn_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SrvD_DestroyOutput( ServoDyn_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SrvD_DestroyMisc( ServoDyn_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ServoDyn_DataData%Output)) THEN DO i1 = LBOUND(ServoDyn_DataData%Output,1), UBOUND(ServoDyn_DataData%Output,1) - CALL SrvD_DestroyOutput( ServoDyn_DataData%Output(i1), ErrStat, ErrMsg ) + CALL SrvD_DestroyOutput( ServoDyn_DataData%Output(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ServoDyn_DataData%Output) ENDIF - CALL SrvD_DestroyOutput( ServoDyn_DataData%y_interp, ErrStat, ErrMsg ) + CALL SrvD_DestroyOutput( ServoDyn_DataData%y_interp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ServoDyn_DataData%Input)) THEN DO i1 = LBOUND(ServoDyn_DataData%Input,1), UBOUND(ServoDyn_DataData%Input,1) - CALL SrvD_DestroyInput( ServoDyn_DataData%Input(i1), ErrStat, ErrMsg ) + CALL SrvD_DestroyInput( ServoDyn_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ServoDyn_DataData%Input) ENDIF @@ -22089,34 +22395,55 @@ SUBROUTINE FAST_CopyAeroDyn14_Data( SrcAeroDyn14_DataData, DstAeroDyn14_DataData ENDIF END SUBROUTINE FAST_CopyAeroDyn14_Data - SUBROUTINE FAST_DestroyAeroDyn14_Data( AeroDyn14_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyAeroDyn14_Data( AeroDyn14_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AeroDyn14_Data), INTENT(INOUT) :: AeroDyn14_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyAeroDyn14_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyAeroDyn14_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(AeroDyn14_DataData%x,1), UBOUND(AeroDyn14_DataData%x,1) - CALL AD14_DestroyContState( AeroDyn14_DataData%x(i1), ErrStat, ErrMsg ) + CALL AD14_DestroyContState( AeroDyn14_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(AeroDyn14_DataData%xd,1), UBOUND(AeroDyn14_DataData%xd,1) - CALL AD14_DestroyDiscState( AeroDyn14_DataData%xd(i1), ErrStat, ErrMsg ) + CALL AD14_DestroyDiscState( AeroDyn14_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(AeroDyn14_DataData%z,1), UBOUND(AeroDyn14_DataData%z,1) - CALL AD14_DestroyConstrState( AeroDyn14_DataData%z(i1), ErrStat, ErrMsg ) + CALL AD14_DestroyConstrState( AeroDyn14_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(AeroDyn14_DataData%OtherSt,1), UBOUND(AeroDyn14_DataData%OtherSt,1) - CALL AD14_DestroyOtherState( AeroDyn14_DataData%OtherSt(i1), ErrStat, ErrMsg ) + CALL AD14_DestroyOtherState( AeroDyn14_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL AD14_DestroyParam( AeroDyn14_DataData%p, ErrStat, ErrMsg ) - CALL AD14_DestroyInput( AeroDyn14_DataData%u, ErrStat, ErrMsg ) - CALL AD14_DestroyOutput( AeroDyn14_DataData%y, ErrStat, ErrMsg ) - CALL AD14_DestroyMisc( AeroDyn14_DataData%m, ErrStat, ErrMsg ) + CALL AD14_DestroyParam( AeroDyn14_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_DestroyInput( AeroDyn14_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_DestroyOutput( AeroDyn14_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_DestroyMisc( AeroDyn14_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(AeroDyn14_DataData%Input)) THEN DO i1 = LBOUND(AeroDyn14_DataData%Input,1), UBOUND(AeroDyn14_DataData%Input,1) - CALL AD14_DestroyInput( AeroDyn14_DataData%Input(i1), ErrStat, ErrMsg ) + CALL AD14_DestroyInput( AeroDyn14_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(AeroDyn14_DataData%Input) ENDIF @@ -23185,41 +23512,64 @@ SUBROUTINE FAST_CopyAeroDyn_Data( SrcAeroDyn_DataData, DstAeroDyn_DataData, Ctrl ENDIF END SUBROUTINE FAST_CopyAeroDyn_Data - SUBROUTINE FAST_DestroyAeroDyn_Data( AeroDyn_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyAeroDyn_Data( AeroDyn_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(AeroDyn_Data), INTENT(INOUT) :: AeroDyn_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyAeroDyn_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyAeroDyn_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(AeroDyn_DataData%x,1), UBOUND(AeroDyn_DataData%x,1) - CALL AD_DestroyContState( AeroDyn_DataData%x(i1), ErrStat, ErrMsg ) + CALL AD_DestroyContState( AeroDyn_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(AeroDyn_DataData%xd,1), UBOUND(AeroDyn_DataData%xd,1) - CALL AD_DestroyDiscState( AeroDyn_DataData%xd(i1), ErrStat, ErrMsg ) + CALL AD_DestroyDiscState( AeroDyn_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(AeroDyn_DataData%z,1), UBOUND(AeroDyn_DataData%z,1) - CALL AD_DestroyConstrState( AeroDyn_DataData%z(i1), ErrStat, ErrMsg ) + CALL AD_DestroyConstrState( AeroDyn_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(AeroDyn_DataData%OtherSt,1), UBOUND(AeroDyn_DataData%OtherSt,1) - CALL AD_DestroyOtherState( AeroDyn_DataData%OtherSt(i1), ErrStat, ErrMsg ) + CALL AD_DestroyOtherState( AeroDyn_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL AD_DestroyParam( AeroDyn_DataData%p, ErrStat, ErrMsg ) - CALL AD_DestroyInput( AeroDyn_DataData%u, ErrStat, ErrMsg ) - CALL AD_DestroyOutput( AeroDyn_DataData%y, ErrStat, ErrMsg ) - CALL AD_DestroyMisc( AeroDyn_DataData%m, ErrStat, ErrMsg ) + CALL AD_DestroyParam( AeroDyn_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD_DestroyInput( AeroDyn_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD_DestroyOutput( AeroDyn_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD_DestroyMisc( AeroDyn_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(AeroDyn_DataData%Output)) THEN DO i1 = LBOUND(AeroDyn_DataData%Output,1), UBOUND(AeroDyn_DataData%Output,1) - CALL AD_DestroyOutput( AeroDyn_DataData%Output(i1), ErrStat, ErrMsg ) + CALL AD_DestroyOutput( AeroDyn_DataData%Output(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(AeroDyn_DataData%Output) ENDIF - CALL AD_DestroyOutput( AeroDyn_DataData%y_interp, ErrStat, ErrMsg ) + CALL AD_DestroyOutput( AeroDyn_DataData%y_interp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(AeroDyn_DataData%Input)) THEN DO i1 = LBOUND(AeroDyn_DataData%Input,1), UBOUND(AeroDyn_DataData%Input,1) - CALL AD_DestroyInput( AeroDyn_DataData%Input(i1), ErrStat, ErrMsg ) + CALL AD_DestroyInput( AeroDyn_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(AeroDyn_DataData%Input) ENDIF @@ -24493,41 +24843,64 @@ SUBROUTINE FAST_CopyInflowWind_Data( SrcInflowWind_DataData, DstInflowWind_DataD ENDIF END SUBROUTINE FAST_CopyInflowWind_Data - SUBROUTINE FAST_DestroyInflowWind_Data( InflowWind_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyInflowWind_Data( InflowWind_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(InflowWind_Data), INTENT(INOUT) :: InflowWind_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyInflowWind_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyInflowWind_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(InflowWind_DataData%x,1), UBOUND(InflowWind_DataData%x,1) - CALL InflowWind_DestroyContState( InflowWind_DataData%x(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyContState( InflowWind_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(InflowWind_DataData%xd,1), UBOUND(InflowWind_DataData%xd,1) - CALL InflowWind_DestroyDiscState( InflowWind_DataData%xd(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyDiscState( InflowWind_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(InflowWind_DataData%z,1), UBOUND(InflowWind_DataData%z,1) - CALL InflowWind_DestroyConstrState( InflowWind_DataData%z(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyConstrState( InflowWind_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(InflowWind_DataData%OtherSt,1), UBOUND(InflowWind_DataData%OtherSt,1) - CALL InflowWind_DestroyOtherState( InflowWind_DataData%OtherSt(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyOtherState( InflowWind_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL InflowWind_DestroyParam( InflowWind_DataData%p, ErrStat, ErrMsg ) - CALL InflowWind_DestroyInput( InflowWind_DataData%u, ErrStat, ErrMsg ) - CALL InflowWind_DestroyOutput( InflowWind_DataData%y, ErrStat, ErrMsg ) - CALL InflowWind_DestroyMisc( InflowWind_DataData%m, ErrStat, ErrMsg ) + CALL InflowWind_DestroyParam( InflowWind_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyInput( InflowWind_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyOutput( InflowWind_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyMisc( InflowWind_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InflowWind_DataData%Output)) THEN DO i1 = LBOUND(InflowWind_DataData%Output,1), UBOUND(InflowWind_DataData%Output,1) - CALL InflowWind_DestroyOutput( InflowWind_DataData%Output(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyOutput( InflowWind_DataData%Output(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InflowWind_DataData%Output) ENDIF - CALL InflowWind_DestroyOutput( InflowWind_DataData%y_interp, ErrStat, ErrMsg ) + CALL InflowWind_DestroyOutput( InflowWind_DataData%y_interp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InflowWind_DataData%Input)) THEN DO i1 = LBOUND(InflowWind_DataData%Input,1), UBOUND(InflowWind_DataData%Input,1) - CALL InflowWind_DestroyInput( InflowWind_DataData%Input(i1), ErrStat, ErrMsg ) + CALL InflowWind_DestroyInput( InflowWind_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InflowWind_DataData%Input) ENDIF @@ -25733,19 +26106,35 @@ SUBROUTINE FAST_CopyOpenFOAM_Data( SrcOpenFOAM_DataData, DstOpenFOAM_DataData, C IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE FAST_CopyOpenFOAM_Data - SUBROUTINE FAST_DestroyOpenFOAM_Data( OpenFOAM_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyOpenFOAM_Data( OpenFOAM_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(OpenFOAM_Data), INTENT(INOUT) :: OpenFOAM_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyOpenFOAM_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyOpenFOAM_Data' + ErrStat = ErrID_None ErrMsg = "" - CALL OpFM_DestroyInput( OpenFOAM_DataData%u, ErrStat, ErrMsg ) - CALL OpFM_DestroyOutput( OpenFOAM_DataData%y, ErrStat, ErrMsg ) - CALL OpFM_DestroyParam( OpenFOAM_DataData%p, ErrStat, ErrMsg ) - CALL OpFM_DestroyMisc( OpenFOAM_DataData%m, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL OpFM_DestroyInput( OpenFOAM_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL OpFM_DestroyOutput( OpenFOAM_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL OpFM_DestroyParam( OpenFOAM_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL OpFM_DestroyMisc( OpenFOAM_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE FAST_DestroyOpenFOAM_Data SUBROUTINE FAST_PackOpenFOAM_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -26206,18 +26595,33 @@ SUBROUTINE FAST_CopySCDataEx_Data( SrcSCDataEx_DataData, DstSCDataEx_DataData, C IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE FAST_CopySCDataEx_Data - SUBROUTINE FAST_DestroySCDataEx_Data( SCDataEx_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroySCDataEx_Data( SCDataEx_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SCDataEx_Data), INTENT(INOUT) :: SCDataEx_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroySCDataEx_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroySCDataEx_Data' + ErrStat = ErrID_None ErrMsg = "" - CALL SC_DX_DestroyInput( SCDataEx_DataData%u, ErrStat, ErrMsg ) - CALL SC_DX_DestroyOutput( SCDataEx_DataData%y, ErrStat, ErrMsg ) - CALL SC_DX_DestroyParam( SCDataEx_DataData%p, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL SC_DX_DestroyInput( SCDataEx_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SC_DX_DestroyOutput( SCDataEx_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SC_DX_DestroyParam( SCDataEx_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE FAST_DestroySCDataEx_Data SUBROUTINE FAST_PackSCDataEx_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -26664,44 +27068,67 @@ SUBROUTINE FAST_CopySubDyn_Data( SrcSubDyn_DataData, DstSubDyn_DataData, CtrlCod ENDIF END SUBROUTINE FAST_CopySubDyn_Data - SUBROUTINE FAST_DestroySubDyn_Data( SubDyn_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroySubDyn_Data( SubDyn_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SubDyn_Data), INTENT(INOUT) :: SubDyn_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroySubDyn_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroySubDyn_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(SubDyn_DataData%x,1), UBOUND(SubDyn_DataData%x,1) - CALL SD_DestroyContState( SubDyn_DataData%x(i1), ErrStat, ErrMsg ) + CALL SD_DestroyContState( SubDyn_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(SubDyn_DataData%xd,1), UBOUND(SubDyn_DataData%xd,1) - CALL SD_DestroyDiscState( SubDyn_DataData%xd(i1), ErrStat, ErrMsg ) + CALL SD_DestroyDiscState( SubDyn_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(SubDyn_DataData%z,1), UBOUND(SubDyn_DataData%z,1) - CALL SD_DestroyConstrState( SubDyn_DataData%z(i1), ErrStat, ErrMsg ) + CALL SD_DestroyConstrState( SubDyn_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(SubDyn_DataData%OtherSt,1), UBOUND(SubDyn_DataData%OtherSt,1) - CALL SD_DestroyOtherState( SubDyn_DataData%OtherSt(i1), ErrStat, ErrMsg ) + CALL SD_DestroyOtherState( SubDyn_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL SD_DestroyParam( SubDyn_DataData%p, ErrStat, ErrMsg ) - CALL SD_DestroyInput( SubDyn_DataData%u, ErrStat, ErrMsg ) - CALL SD_DestroyOutput( SubDyn_DataData%y, ErrStat, ErrMsg ) - CALL SD_DestroyMisc( SubDyn_DataData%m, ErrStat, ErrMsg ) + CALL SD_DestroyParam( SubDyn_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SD_DestroyInput( SubDyn_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SD_DestroyOutput( SubDyn_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SD_DestroyMisc( SubDyn_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(SubDyn_DataData%Input)) THEN DO i1 = LBOUND(SubDyn_DataData%Input,1), UBOUND(SubDyn_DataData%Input,1) - CALL SD_DestroyInput( SubDyn_DataData%Input(i1), ErrStat, ErrMsg ) + CALL SD_DestroyInput( SubDyn_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) 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 ) + CALL SD_DestroyOutput( SubDyn_DataData%Output(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(SubDyn_DataData%Output) ENDIF - CALL SD_DestroyOutput( SubDyn_DataData%y_interp, ErrStat, ErrMsg ) + CALL SD_DestroyOutput( SubDyn_DataData%y_interp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(SubDyn_DataData%InputTimes)) THEN DEALLOCATE(SubDyn_DataData%InputTimes) ENDIF @@ -27953,34 +28380,55 @@ SUBROUTINE FAST_CopyExtPtfm_Data( SrcExtPtfm_DataData, DstExtPtfm_DataData, Ctrl ENDIF END SUBROUTINE FAST_CopyExtPtfm_Data - SUBROUTINE FAST_DestroyExtPtfm_Data( ExtPtfm_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyExtPtfm_Data( ExtPtfm_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ExtPtfm_Data), INTENT(INOUT) :: ExtPtfm_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyExtPtfm_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyExtPtfm_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(ExtPtfm_DataData%x,1), UBOUND(ExtPtfm_DataData%x,1) - CALL ExtPtfm_DestroyContState( ExtPtfm_DataData%x(i1), ErrStat, ErrMsg ) + CALL ExtPtfm_DestroyContState( ExtPtfm_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(ExtPtfm_DataData%xd,1), UBOUND(ExtPtfm_DataData%xd,1) - CALL ExtPtfm_DestroyDiscState( ExtPtfm_DataData%xd(i1), ErrStat, ErrMsg ) + CALL ExtPtfm_DestroyDiscState( ExtPtfm_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(ExtPtfm_DataData%z,1), UBOUND(ExtPtfm_DataData%z,1) - CALL ExtPtfm_DestroyConstrState( ExtPtfm_DataData%z(i1), ErrStat, ErrMsg ) + CALL ExtPtfm_DestroyConstrState( ExtPtfm_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(ExtPtfm_DataData%OtherSt,1), UBOUND(ExtPtfm_DataData%OtherSt,1) - CALL ExtPtfm_DestroyOtherState( ExtPtfm_DataData%OtherSt(i1), ErrStat, ErrMsg ) + CALL ExtPtfm_DestroyOtherState( ExtPtfm_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL ExtPtfm_DestroyParam( ExtPtfm_DataData%p, ErrStat, ErrMsg ) - CALL ExtPtfm_DestroyInput( ExtPtfm_DataData%u, ErrStat, ErrMsg ) - CALL ExtPtfm_DestroyOutput( ExtPtfm_DataData%y, ErrStat, ErrMsg ) - CALL ExtPtfm_DestroyMisc( ExtPtfm_DataData%m, ErrStat, ErrMsg ) + CALL ExtPtfm_DestroyParam( ExtPtfm_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ExtPtfm_DestroyInput( ExtPtfm_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ExtPtfm_DestroyOutput( ExtPtfm_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ExtPtfm_DestroyMisc( ExtPtfm_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ExtPtfm_DataData%Input)) THEN DO i1 = LBOUND(ExtPtfm_DataData%Input,1), UBOUND(ExtPtfm_DataData%Input,1) - CALL ExtPtfm_DestroyInput( ExtPtfm_DataData%Input(i1), ErrStat, ErrMsg ) + CALL ExtPtfm_DestroyInput( ExtPtfm_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ExtPtfm_DataData%Input) ENDIF @@ -29049,41 +29497,64 @@ SUBROUTINE FAST_CopyHydroDyn_Data( SrcHydroDyn_DataData, DstHydroDyn_DataData, C ENDIF END SUBROUTINE FAST_CopyHydroDyn_Data - SUBROUTINE FAST_DestroyHydroDyn_Data( HydroDyn_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyHydroDyn_Data( HydroDyn_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(HydroDyn_Data), INTENT(INOUT) :: HydroDyn_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyHydroDyn_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyHydroDyn_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(HydroDyn_DataData%x,1), UBOUND(HydroDyn_DataData%x,1) - CALL HydroDyn_DestroyContState( HydroDyn_DataData%x(i1), ErrStat, ErrMsg ) + CALL HydroDyn_DestroyContState( HydroDyn_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(HydroDyn_DataData%xd,1), UBOUND(HydroDyn_DataData%xd,1) - CALL HydroDyn_DestroyDiscState( HydroDyn_DataData%xd(i1), ErrStat, ErrMsg ) + CALL HydroDyn_DestroyDiscState( HydroDyn_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(HydroDyn_DataData%z,1), UBOUND(HydroDyn_DataData%z,1) - CALL HydroDyn_DestroyConstrState( HydroDyn_DataData%z(i1), ErrStat, ErrMsg ) + CALL HydroDyn_DestroyConstrState( HydroDyn_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(HydroDyn_DataData%OtherSt,1), UBOUND(HydroDyn_DataData%OtherSt,1) - CALL HydroDyn_DestroyOtherState( HydroDyn_DataData%OtherSt(i1), ErrStat, ErrMsg ) + CALL HydroDyn_DestroyOtherState( HydroDyn_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL HydroDyn_DestroyParam( HydroDyn_DataData%p, ErrStat, ErrMsg ) - CALL HydroDyn_DestroyInput( HydroDyn_DataData%u, ErrStat, ErrMsg ) - CALL HydroDyn_DestroyOutput( HydroDyn_DataData%y, ErrStat, ErrMsg ) - CALL HydroDyn_DestroyMisc( HydroDyn_DataData%m, ErrStat, ErrMsg ) + CALL HydroDyn_DestroyParam( HydroDyn_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL HydroDyn_DestroyInput( HydroDyn_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL HydroDyn_DestroyOutput( HydroDyn_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL HydroDyn_DestroyMisc( HydroDyn_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(HydroDyn_DataData%Output)) THEN DO i1 = LBOUND(HydroDyn_DataData%Output,1), UBOUND(HydroDyn_DataData%Output,1) - CALL HydroDyn_DestroyOutput( HydroDyn_DataData%Output(i1), ErrStat, ErrMsg ) + CALL HydroDyn_DestroyOutput( HydroDyn_DataData%Output(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(HydroDyn_DataData%Output) ENDIF - CALL HydroDyn_DestroyOutput( HydroDyn_DataData%y_interp, ErrStat, ErrMsg ) + CALL HydroDyn_DestroyOutput( HydroDyn_DataData%y_interp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(HydroDyn_DataData%Input)) THEN DO i1 = LBOUND(HydroDyn_DataData%Input,1), UBOUND(HydroDyn_DataData%Input,1) - CALL HydroDyn_DestroyInput( HydroDyn_DataData%Input(i1), ErrStat, ErrMsg ) + CALL HydroDyn_DestroyInput( HydroDyn_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(HydroDyn_DataData%Input) ENDIF @@ -30338,34 +30809,55 @@ SUBROUTINE FAST_CopyIceFloe_Data( SrcIceFloe_DataData, DstIceFloe_DataData, Ctrl ENDIF END SUBROUTINE FAST_CopyIceFloe_Data - SUBROUTINE FAST_DestroyIceFloe_Data( IceFloe_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyIceFloe_Data( IceFloe_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IceFloe_Data), INTENT(INOUT) :: IceFloe_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyIceFloe_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyIceFloe_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(IceFloe_DataData%x,1), UBOUND(IceFloe_DataData%x,1) - CALL IceFloe_DestroyContState( IceFloe_DataData%x(i1), ErrStat, ErrMsg ) + CALL IceFloe_DestroyContState( IceFloe_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(IceFloe_DataData%xd,1), UBOUND(IceFloe_DataData%xd,1) - CALL IceFloe_DestroyDiscState( IceFloe_DataData%xd(i1), ErrStat, ErrMsg ) + CALL IceFloe_DestroyDiscState( IceFloe_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(IceFloe_DataData%z,1), UBOUND(IceFloe_DataData%z,1) - CALL IceFloe_DestroyConstrState( IceFloe_DataData%z(i1), ErrStat, ErrMsg ) + CALL IceFloe_DestroyConstrState( IceFloe_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(IceFloe_DataData%OtherSt,1), UBOUND(IceFloe_DataData%OtherSt,1) - CALL IceFloe_DestroyOtherState( IceFloe_DataData%OtherSt(i1), ErrStat, ErrMsg ) + CALL IceFloe_DestroyOtherState( IceFloe_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL IceFloe_DestroyParam( IceFloe_DataData%p, ErrStat, ErrMsg ) - CALL IceFloe_DestroyInput( IceFloe_DataData%u, ErrStat, ErrMsg ) - CALL IceFloe_DestroyOutput( IceFloe_DataData%y, ErrStat, ErrMsg ) - CALL IceFloe_DestroyMisc( IceFloe_DataData%m, ErrStat, ErrMsg ) + CALL IceFloe_DestroyParam( IceFloe_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IceFloe_DestroyInput( IceFloe_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IceFloe_DestroyOutput( IceFloe_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IceFloe_DestroyMisc( IceFloe_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(IceFloe_DataData%Input)) THEN DO i1 = LBOUND(IceFloe_DataData%Input,1), UBOUND(IceFloe_DataData%Input,1) - CALL IceFloe_DestroyInput( IceFloe_DataData%Input(i1), ErrStat, ErrMsg ) + CALL IceFloe_DestroyInput( IceFloe_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(IceFloe_DataData%Input) ENDIF @@ -31432,39 +31924,62 @@ SUBROUTINE FAST_CopyMAP_Data( SrcMAP_DataData, DstMAP_DataData, CtrlCode, ErrSta ENDIF END SUBROUTINE FAST_CopyMAP_Data - SUBROUTINE FAST_DestroyMAP_Data( MAP_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyMAP_Data( MAP_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MAP_Data), INTENT(INOUT) :: MAP_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyMAP_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyMAP_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(MAP_DataData%x,1), UBOUND(MAP_DataData%x,1) - CALL MAP_DestroyContState( MAP_DataData%x(i1), ErrStat, ErrMsg ) + CALL MAP_DestroyContState( MAP_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(MAP_DataData%xd,1), UBOUND(MAP_DataData%xd,1) - CALL MAP_DestroyDiscState( MAP_DataData%xd(i1), ErrStat, ErrMsg ) + CALL MAP_DestroyDiscState( MAP_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(MAP_DataData%z,1), UBOUND(MAP_DataData%z,1) - CALL MAP_DestroyConstrState( MAP_DataData%z(i1), ErrStat, ErrMsg ) + CALL MAP_DestroyConstrState( MAP_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL MAP_DestroyOtherState( MAP_DataData%OtherSt, ErrStat, ErrMsg ) - CALL MAP_DestroyParam( MAP_DataData%p, ErrStat, ErrMsg ) - CALL MAP_DestroyInput( MAP_DataData%u, ErrStat, ErrMsg ) - CALL MAP_DestroyOutput( MAP_DataData%y, ErrStat, ErrMsg ) - CALL MAP_DestroyOtherState( MAP_DataData%OtherSt_old, ErrStat, ErrMsg ) + CALL MAP_DestroyOtherState( MAP_DataData%OtherSt, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MAP_DestroyParam( MAP_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MAP_DestroyInput( MAP_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MAP_DestroyOutput( MAP_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MAP_DestroyOtherState( MAP_DataData%OtherSt_old, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MAP_DataData%Output)) THEN DO i1 = LBOUND(MAP_DataData%Output,1), UBOUND(MAP_DataData%Output,1) - CALL MAP_DestroyOutput( MAP_DataData%Output(i1), ErrStat, ErrMsg ) + CALL MAP_DestroyOutput( MAP_DataData%Output(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MAP_DataData%Output) ENDIF - CALL MAP_DestroyOutput( MAP_DataData%y_interp, ErrStat, ErrMsg ) + CALL MAP_DestroyOutput( MAP_DataData%y_interp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MAP_DataData%Input)) THEN DO i1 = LBOUND(MAP_DataData%Input,1), UBOUND(MAP_DataData%Input,1) - CALL MAP_DestroyInput( MAP_DataData%Input(i1), ErrStat, ErrMsg ) + CALL MAP_DestroyInput( MAP_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MAP_DataData%Input) ENDIF @@ -32711,34 +33226,55 @@ SUBROUTINE FAST_CopyFEAMooring_Data( SrcFEAMooring_DataData, DstFEAMooring_DataD ENDIF END SUBROUTINE FAST_CopyFEAMooring_Data - SUBROUTINE FAST_DestroyFEAMooring_Data( FEAMooring_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyFEAMooring_Data( FEAMooring_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FEAMooring_Data), INTENT(INOUT) :: FEAMooring_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyFEAMooring_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyFEAMooring_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(FEAMooring_DataData%x,1), UBOUND(FEAMooring_DataData%x,1) - CALL FEAM_DestroyContState( FEAMooring_DataData%x(i1), ErrStat, ErrMsg ) + CALL FEAM_DestroyContState( FEAMooring_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(FEAMooring_DataData%xd,1), UBOUND(FEAMooring_DataData%xd,1) - CALL FEAM_DestroyDiscState( FEAMooring_DataData%xd(i1), ErrStat, ErrMsg ) + CALL FEAM_DestroyDiscState( FEAMooring_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(FEAMooring_DataData%z,1), UBOUND(FEAMooring_DataData%z,1) - CALL FEAM_DestroyConstrState( FEAMooring_DataData%z(i1), ErrStat, ErrMsg ) + CALL FEAM_DestroyConstrState( FEAMooring_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(FEAMooring_DataData%OtherSt,1), UBOUND(FEAMooring_DataData%OtherSt,1) - CALL FEAM_DestroyOtherState( FEAMooring_DataData%OtherSt(i1), ErrStat, ErrMsg ) + CALL FEAM_DestroyOtherState( FEAMooring_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL FEAM_DestroyParam( FEAMooring_DataData%p, ErrStat, ErrMsg ) - CALL FEAM_DestroyInput( FEAMooring_DataData%u, ErrStat, ErrMsg ) - CALL FEAM_DestroyOutput( FEAMooring_DataData%y, ErrStat, ErrMsg ) - CALL FEAM_DestroyMisc( FEAMooring_DataData%m, ErrStat, ErrMsg ) + CALL FEAM_DestroyParam( FEAMooring_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FEAM_DestroyInput( FEAMooring_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FEAM_DestroyOutput( FEAMooring_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FEAM_DestroyMisc( FEAMooring_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(FEAMooring_DataData%Input)) THEN DO i1 = LBOUND(FEAMooring_DataData%Input,1), UBOUND(FEAMooring_DataData%Input,1) - CALL FEAM_DestroyInput( FEAMooring_DataData%Input(i1), ErrStat, ErrMsg ) + CALL FEAM_DestroyInput( FEAMooring_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(FEAMooring_DataData%Input) ENDIF @@ -33758,6 +34294,25 @@ SUBROUTINE FAST_CopyMoorDyn_Data( SrcMoorDyn_DataData, DstMoorDyn_DataData, Ctrl CALL MD_CopyMisc( SrcMoorDyn_DataData%m, DstMoorDyn_DataData%m, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN +IF (ALLOCATED(SrcMoorDyn_DataData%Output)) THEN + i1_l = LBOUND(SrcMoorDyn_DataData%Output,1) + i1_u = UBOUND(SrcMoorDyn_DataData%Output,1) + IF (.NOT. ALLOCATED(DstMoorDyn_DataData%Output)) THEN + ALLOCATE(DstMoorDyn_DataData%Output(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMoorDyn_DataData%Output.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DO i1 = LBOUND(SrcMoorDyn_DataData%Output,1), UBOUND(SrcMoorDyn_DataData%Output,1) + CALL MD_CopyOutput( SrcMoorDyn_DataData%Output(i1), DstMoorDyn_DataData%Output(i1), CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + ENDDO +ENDIF + CALL MD_CopyOutput( SrcMoorDyn_DataData%y_interp, DstMoorDyn_DataData%y_interp, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN IF (ALLOCATED(SrcMoorDyn_DataData%Input)) THEN i1_l = LBOUND(SrcMoorDyn_DataData%Input,1) i1_u = UBOUND(SrcMoorDyn_DataData%Input,1) @@ -33788,34 +34343,64 @@ SUBROUTINE FAST_CopyMoorDyn_Data( SrcMoorDyn_DataData, DstMoorDyn_DataData, Ctrl ENDIF END SUBROUTINE FAST_CopyMoorDyn_Data - SUBROUTINE FAST_DestroyMoorDyn_Data( MoorDyn_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyMoorDyn_Data( MoorDyn_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MoorDyn_Data), INTENT(INOUT) :: MoorDyn_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyMoorDyn_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyMoorDyn_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(MoorDyn_DataData%x,1), UBOUND(MoorDyn_DataData%x,1) - CALL MD_DestroyContState( MoorDyn_DataData%x(i1), ErrStat, ErrMsg ) + CALL MD_DestroyContState( MoorDyn_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(MoorDyn_DataData%xd,1), UBOUND(MoorDyn_DataData%xd,1) - CALL MD_DestroyDiscState( MoorDyn_DataData%xd(i1), ErrStat, ErrMsg ) + CALL MD_DestroyDiscState( MoorDyn_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(MoorDyn_DataData%z,1), UBOUND(MoorDyn_DataData%z,1) - CALL MD_DestroyConstrState( MoorDyn_DataData%z(i1), ErrStat, ErrMsg ) + CALL MD_DestroyConstrState( MoorDyn_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(MoorDyn_DataData%OtherSt,1), UBOUND(MoorDyn_DataData%OtherSt,1) - CALL MD_DestroyOtherState( MoorDyn_DataData%OtherSt(i1), ErrStat, ErrMsg ) + CALL MD_DestroyOtherState( MoorDyn_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL MD_DestroyParam( MoorDyn_DataData%p, ErrStat, ErrMsg ) - CALL MD_DestroyInput( MoorDyn_DataData%u, ErrStat, ErrMsg ) - CALL MD_DestroyOutput( MoorDyn_DataData%y, ErrStat, ErrMsg ) - CALL MD_DestroyMisc( MoorDyn_DataData%m, ErrStat, ErrMsg ) + CALL MD_DestroyParam( MoorDyn_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MD_DestroyInput( MoorDyn_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MD_DestroyOutput( MoorDyn_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MD_DestroyMisc( MoorDyn_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +IF (ALLOCATED(MoorDyn_DataData%Output)) THEN +DO i1 = LBOUND(MoorDyn_DataData%Output,1), UBOUND(MoorDyn_DataData%Output,1) + CALL MD_DestroyOutput( MoorDyn_DataData%Output(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) +ENDDO + DEALLOCATE(MoorDyn_DataData%Output) +ENDIF + CALL MD_DestroyOutput( MoorDyn_DataData%y_interp, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MoorDyn_DataData%Input)) THEN DO i1 = LBOUND(MoorDyn_DataData%Input,1), UBOUND(MoorDyn_DataData%Input,1) - CALL MD_DestroyInput( MoorDyn_DataData%Input(i1), ErrStat, ErrMsg ) + CALL MD_DestroyInput( MoorDyn_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MoorDyn_DataData%Input) ENDIF @@ -34004,6 +34589,46 @@ SUBROUTINE FAST_PackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 1 ! Output allocated yes/no + IF ( ALLOCATED(InData%Output) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Output upper/lower bounds for each dimension + DO i1 = LBOUND(InData%Output,1), UBOUND(InData%Output,1) + Int_BufSz = Int_BufSz + 3 ! Output: size of buffers for each call to pack subtype + CALL MD_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 MD_PackOutput( Re_Buf, Db_Buf, Int_Buf, InData%y_interp, ErrStat2, ErrMsg2, .TRUE. ) ! y_interp + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! y_interp + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! y_interp + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! y_interp + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 1 ! Input allocated yes/no IF ( ALLOCATED(InData%Input) ) THEN Int_BufSz = Int_BufSz + 2*1 ! Input upper/lower bounds for each dimension @@ -34267,6 +34892,75 @@ SUBROUTINE FAST_PackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, E CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF ( .NOT. ALLOCATED(InData%Output) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + 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 MD_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 MD_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 @@ -34709,6 +35403,102 @@ SUBROUTINE FAST_UnPackMoorDyn_Data( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + 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 MD_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 MD_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) @@ -34865,34 +35655,55 @@ SUBROUTINE FAST_CopyOrcaFlex_Data( SrcOrcaFlex_DataData, DstOrcaFlex_DataData, C ENDIF END SUBROUTINE FAST_CopyOrcaFlex_Data - SUBROUTINE FAST_DestroyOrcaFlex_Data( OrcaFlex_DataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyOrcaFlex_Data( OrcaFlex_DataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(OrcaFlex_Data), INTENT(INOUT) :: OrcaFlex_DataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyOrcaFlex_Data' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyOrcaFlex_Data' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + DO i1 = LBOUND(OrcaFlex_DataData%x,1), UBOUND(OrcaFlex_DataData%x,1) - CALL Orca_DestroyContState( OrcaFlex_DataData%x(i1), ErrStat, ErrMsg ) + CALL Orca_DestroyContState( OrcaFlex_DataData%x(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(OrcaFlex_DataData%xd,1), UBOUND(OrcaFlex_DataData%xd,1) - CALL Orca_DestroyDiscState( OrcaFlex_DataData%xd(i1), ErrStat, ErrMsg ) + CALL Orca_DestroyDiscState( OrcaFlex_DataData%xd(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(OrcaFlex_DataData%z,1), UBOUND(OrcaFlex_DataData%z,1) - CALL Orca_DestroyConstrState( OrcaFlex_DataData%z(i1), ErrStat, ErrMsg ) + CALL Orca_DestroyConstrState( OrcaFlex_DataData%z(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DO i1 = LBOUND(OrcaFlex_DataData%OtherSt,1), UBOUND(OrcaFlex_DataData%OtherSt,1) - CALL Orca_DestroyOtherState( OrcaFlex_DataData%OtherSt(i1), ErrStat, ErrMsg ) + CALL Orca_DestroyOtherState( OrcaFlex_DataData%OtherSt(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO - CALL Orca_DestroyParam( OrcaFlex_DataData%p, ErrStat, ErrMsg ) - CALL Orca_DestroyInput( OrcaFlex_DataData%u, ErrStat, ErrMsg ) - CALL Orca_DestroyOutput( OrcaFlex_DataData%y, ErrStat, ErrMsg ) - CALL Orca_DestroyMisc( OrcaFlex_DataData%m, ErrStat, ErrMsg ) + CALL Orca_DestroyParam( OrcaFlex_DataData%p, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Orca_DestroyInput( OrcaFlex_DataData%u, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Orca_DestroyOutput( OrcaFlex_DataData%y, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Orca_DestroyMisc( OrcaFlex_DataData%m, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(OrcaFlex_DataData%Input)) THEN DO i1 = LBOUND(OrcaFlex_DataData%Input,1), UBOUND(OrcaFlex_DataData%Input,1) - CALL Orca_DestroyInput( OrcaFlex_DataData%Input(i1), ErrStat, ErrMsg ) + CALL Orca_DestroyInput( OrcaFlex_DataData%Input(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OrcaFlex_DataData%Input) ENDIF @@ -36239,6 +37050,12 @@ SUBROUTINE FAST_CopyModuleMapType( SrcModuleMapTypeData, DstModuleMapTypeData, C CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%AD_P_2_ED_P_N, DstModuleMapTypeData%AD_P_2_ED_P_N, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ED_P_2_AD_P_TF, DstModuleMapTypeData%ED_P_2_AD_P_TF, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%AD_P_2_ED_P_TF, DstModuleMapTypeData%AD_P_2_ED_P_TF, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ED_L_2_AD_L_T, DstModuleMapTypeData%ED_L_2_AD_L_T, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -36264,6 +37081,9 @@ SUBROUTINE FAST_CopyModuleMapType( SrcModuleMapTypeData, DstModuleMapTypeData, C CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%ED_P_2_AD_P_H, DstModuleMapTypeData%ED_P_2_AD_P_H, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN + CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%AD_P_2_ED_P_H, DstModuleMapTypeData%AD_P_2_ED_P_H, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) + IF (ErrStat>=AbortErrLev) RETURN CALL NWTC_Library_Copymeshmaptype( SrcModuleMapTypeData%IceF_P_2_SD_P, DstModuleMapTypeData%IceF_P_2_SD_P, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -36351,6 +37171,12 @@ SUBROUTINE FAST_CopyModuleMapType( SrcModuleMapTypeData, DstModuleMapTypeData, C CALL MeshCopy( SrcModuleMapTypeData%u_ED_PlatformPtMesh_2, DstModuleMapTypeData%u_ED_PlatformPtMesh_2, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcModuleMapTypeData%u_ED_PlatformPtMesh_3, DstModuleMapTypeData%u_ED_PlatformPtMesh_3, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN + CALL MeshCopy( SrcModuleMapTypeData%u_ED_PlatformPtMesh_MDf, DstModuleMapTypeData%u_ED_PlatformPtMesh_MDf, CtrlCode, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat>=AbortErrLev) RETURN CALL MeshCopy( SrcModuleMapTypeData%u_ED_TowerPtloads, DstModuleMapTypeData%u_ED_TowerPtloads, CtrlCode, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN @@ -36447,76 +37273,111 @@ SUBROUTINE FAST_CopyModuleMapType( SrcModuleMapTypeData, DstModuleMapTypeData, C IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE FAST_CopyModuleMapType - SUBROUTINE FAST_DestroyModuleMapType( ModuleMapTypeData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyModuleMapType( ModuleMapTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_ModuleMapType), INTENT(INOUT) :: ModuleMapTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyModuleMapType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyModuleMapType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ModuleMapTypeData%ED_P_2_BD_P)) THEN DO i1 = LBOUND(ModuleMapTypeData%ED_P_2_BD_P,1), UBOUND(ModuleMapTypeData%ED_P_2_BD_P,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_BD_P(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_BD_P(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%ED_P_2_BD_P) ENDIF IF (ALLOCATED(ModuleMapTypeData%BD_P_2_ED_P)) THEN DO i1 = LBOUND(ModuleMapTypeData%BD_P_2_ED_P,1), UBOUND(ModuleMapTypeData%BD_P_2_ED_P,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BD_P_2_ED_P(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BD_P_2_ED_P(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%BD_P_2_ED_P) ENDIF IF (ALLOCATED(ModuleMapTypeData%ED_P_2_BD_P_Hub)) THEN DO i1 = LBOUND(ModuleMapTypeData%ED_P_2_BD_P_Hub,1), UBOUND(ModuleMapTypeData%ED_P_2_BD_P_Hub,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_BD_P_Hub(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_BD_P_Hub(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) 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_Mooring_P, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%Mooring_P_2_ED_P, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SDy3_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_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_HD_PRP_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_HD_W_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%HD_W_P_2_ED_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_HD_M_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%HD_M_P_2_ED_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_Mooring_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%Mooring_P_2_ED_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SDy3_P_2_Mooring_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%Mooring_P_2_SD_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_SD_TP, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SD_TP_2_ED_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SD_P_2_HD_M_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%HD_M_P_2_SD_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SD_P_2_HD_W_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%HD_W_P_2_SD_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ModuleMapTypeData%ED_P_2_NStC_P_N)) THEN DO i1 = LBOUND(ModuleMapTypeData%ED_P_2_NStC_P_N,1), UBOUND(ModuleMapTypeData%ED_P_2_NStC_P_N,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_NStC_P_N(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_NStC_P_N(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%ED_P_2_NStC_P_N) ENDIF IF (ALLOCATED(ModuleMapTypeData%NStC_P_2_ED_P_N)) THEN DO i1 = LBOUND(ModuleMapTypeData%NStC_P_2_ED_P_N,1), UBOUND(ModuleMapTypeData%NStC_P_2_ED_P_N,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%NStC_P_2_ED_P_N(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%NStC_P_2_ED_P_N(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%NStC_P_2_ED_P_N) ENDIF IF (ALLOCATED(ModuleMapTypeData%ED_L_2_TStC_P_T)) THEN DO i1 = LBOUND(ModuleMapTypeData%ED_L_2_TStC_P_T,1), UBOUND(ModuleMapTypeData%ED_L_2_TStC_P_T,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_L_2_TStC_P_T(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_L_2_TStC_P_T(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%ED_L_2_TStC_P_T) ENDIF IF (ALLOCATED(ModuleMapTypeData%TStC_P_2_ED_P_T)) THEN DO i1 = LBOUND(ModuleMapTypeData%TStC_P_2_ED_P_T,1), UBOUND(ModuleMapTypeData%TStC_P_2_ED_P_T,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%TStC_P_2_ED_P_T(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%TStC_P_2_ED_P_T(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%TStC_P_2_ED_P_T) ENDIF IF (ALLOCATED(ModuleMapTypeData%ED_L_2_BStC_P_B)) THEN DO i2 = LBOUND(ModuleMapTypeData%ED_L_2_BStC_P_B,2), UBOUND(ModuleMapTypeData%ED_L_2_BStC_P_B,2) DO i1 = LBOUND(ModuleMapTypeData%ED_L_2_BStC_P_B,1), UBOUND(ModuleMapTypeData%ED_L_2_BStC_P_B,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_L_2_BStC_P_B(i1,i2), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_L_2_BStC_P_B(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(ModuleMapTypeData%ED_L_2_BStC_P_B) @@ -36524,7 +37385,8 @@ SUBROUTINE FAST_DestroyModuleMapType( ModuleMapTypeData, ErrStat, ErrMsg ) IF (ALLOCATED(ModuleMapTypeData%BStC_P_2_ED_P_B)) THEN DO i2 = LBOUND(ModuleMapTypeData%BStC_P_2_ED_P_B,2), UBOUND(ModuleMapTypeData%BStC_P_2_ED_P_B,2) DO i1 = LBOUND(ModuleMapTypeData%BStC_P_2_ED_P_B,1), UBOUND(ModuleMapTypeData%BStC_P_2_ED_P_B,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BStC_P_2_ED_P_B(i1,i2), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BStC_P_2_ED_P_B(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(ModuleMapTypeData%BStC_P_2_ED_P_B) @@ -36532,7 +37394,8 @@ SUBROUTINE FAST_DestroyModuleMapType( ModuleMapTypeData, ErrStat, ErrMsg ) IF (ALLOCATED(ModuleMapTypeData%BD_L_2_BStC_P_B)) THEN DO i2 = LBOUND(ModuleMapTypeData%BD_L_2_BStC_P_B,2), UBOUND(ModuleMapTypeData%BD_L_2_BStC_P_B,2) DO i1 = LBOUND(ModuleMapTypeData%BD_L_2_BStC_P_B,1), UBOUND(ModuleMapTypeData%BD_L_2_BStC_P_B,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BD_L_2_BStC_P_B(i1,i2), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BD_L_2_BStC_P_B(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(ModuleMapTypeData%BD_L_2_BStC_P_B) @@ -36540,76 +37403,101 @@ SUBROUTINE FAST_DestroyModuleMapType( ModuleMapTypeData, ErrStat, ErrMsg ) IF (ALLOCATED(ModuleMapTypeData%BStC_P_2_BD_P_B)) THEN DO i2 = LBOUND(ModuleMapTypeData%BStC_P_2_BD_P_B,2), UBOUND(ModuleMapTypeData%BStC_P_2_BD_P_B,2) DO i1 = LBOUND(ModuleMapTypeData%BStC_P_2_BD_P_B,1), UBOUND(ModuleMapTypeData%BStC_P_2_BD_P_B,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BStC_P_2_BD_P_B(i1,i2), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BStC_P_2_BD_P_B(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(ModuleMapTypeData%BStC_P_2_BD_P_B) ENDIF IF (ALLOCATED(ModuleMapTypeData%SStC_P_P_2_ED_P)) THEN DO i1 = LBOUND(ModuleMapTypeData%SStC_P_P_2_ED_P,1), UBOUND(ModuleMapTypeData%SStC_P_P_2_ED_P,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SStC_P_P_2_ED_P(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SStC_P_P_2_ED_P(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%SStC_P_P_2_ED_P) ENDIF IF (ALLOCATED(ModuleMapTypeData%ED_P_2_SStC_P_P)) THEN DO i1 = LBOUND(ModuleMapTypeData%ED_P_2_SStC_P_P,1), UBOUND(ModuleMapTypeData%ED_P_2_SStC_P_P,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_SStC_P_P(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_SStC_P_P(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%ED_P_2_SStC_P_P) ENDIF IF (ALLOCATED(ModuleMapTypeData%SStC_P_P_2_SD_P)) THEN DO i1 = LBOUND(ModuleMapTypeData%SStC_P_P_2_SD_P,1), UBOUND(ModuleMapTypeData%SStC_P_P_2_SD_P,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SStC_P_P_2_SD_P(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SStC_P_P_2_SD_P(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%SStC_P_P_2_SD_P) ENDIF IF (ALLOCATED(ModuleMapTypeData%SDy3_P_2_SStC_P_P)) THEN DO i1 = LBOUND(ModuleMapTypeData%SDy3_P_2_SStC_P_P,1), UBOUND(ModuleMapTypeData%SDy3_P_2_SStC_P_P,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SDy3_P_2_SStC_P_P(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SDy3_P_2_SStC_P_P(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%SDy3_P_2_SStC_P_P) ENDIF - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_SrvD_P_P, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_SrvD_P_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ModuleMapTypeData%BDED_L_2_AD_L_B)) THEN DO i1 = LBOUND(ModuleMapTypeData%BDED_L_2_AD_L_B,1), UBOUND(ModuleMapTypeData%BDED_L_2_AD_L_B,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BDED_L_2_AD_L_B(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BDED_L_2_AD_L_B(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%BDED_L_2_AD_L_B) ENDIF IF (ALLOCATED(ModuleMapTypeData%AD_L_2_BDED_B)) THEN DO i1 = LBOUND(ModuleMapTypeData%AD_L_2_BDED_B,1), UBOUND(ModuleMapTypeData%AD_L_2_BDED_B,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%AD_L_2_BDED_B(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%AD_L_2_BDED_B(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%AD_L_2_BDED_B) ENDIF IF (ALLOCATED(ModuleMapTypeData%BD_L_2_BD_L)) THEN DO i1 = LBOUND(ModuleMapTypeData%BD_L_2_BD_L,1), UBOUND(ModuleMapTypeData%BD_L_2_BD_L,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BD_L_2_BD_L(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BD_L_2_BD_L(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%BD_L_2_BD_L) ENDIF - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_AD_P_N, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%AD_P_2_ED_P_N, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_L_2_AD_L_T, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%AD_L_2_ED_P_T, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_AD_P_N, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%AD_P_2_ED_P_N, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%AD_P_2_ED_P_TF, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_L_2_AD_L_T, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%AD_L_2_ED_P_T, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ModuleMapTypeData%ED_P_2_AD_P_R)) THEN DO i1 = LBOUND(ModuleMapTypeData%ED_P_2_AD_P_R,1), UBOUND(ModuleMapTypeData%ED_P_2_AD_P_R,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_AD_P_R(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_AD_P_R(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%ED_P_2_AD_P_R) ENDIF - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_AD_P_H, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%IceF_P_2_SD_P, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SDy3_P_2_IceF_P, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%IceF_P_2_SD_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SDy3_P_2_IceF_P, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ModuleMapTypeData%IceD_P_2_SD_P)) THEN DO i1 = LBOUND(ModuleMapTypeData%IceD_P_2_SD_P,1), UBOUND(ModuleMapTypeData%IceD_P_2_SD_P,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%IceD_P_2_SD_P(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%IceD_P_2_SD_P(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%IceD_P_2_SD_P) ENDIF IF (ALLOCATED(ModuleMapTypeData%SDy3_P_2_IceD_P)) THEN DO i1 = LBOUND(ModuleMapTypeData%SDy3_P_2_IceD_P,1), UBOUND(ModuleMapTypeData%SDy3_P_2_IceD_P,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SDy3_P_2_IceD_P(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SDy3_P_2_IceD_P(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%SDy3_P_2_IceD_P) ENDIF @@ -36622,43 +37510,64 @@ SUBROUTINE FAST_DestroyModuleMapType( ModuleMapTypeData, ErrStat, ErrMsg ) IF (ALLOCATED(ModuleMapTypeData%Jac_u_indx)) THEN DEALLOCATE(ModuleMapTypeData%Jac_u_indx) ENDIF - CALL MeshDestroy( ModuleMapTypeData%u_ED_NacelleLoads, ErrStat, ErrMsg ) - CALL MeshDestroy( ModuleMapTypeData%u_ED_PlatformPtMesh, ErrStat, ErrMsg ) - CALL MeshDestroy( ModuleMapTypeData%u_ED_PlatformPtMesh_2, ErrStat, ErrMsg ) - CALL MeshDestroy( ModuleMapTypeData%u_ED_TowerPtloads, ErrStat, ErrMsg ) + CALL MeshDestroy( ModuleMapTypeData%u_ED_NacelleLoads, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( ModuleMapTypeData%u_ED_PlatformPtMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( ModuleMapTypeData%u_ED_PlatformPtMesh_2, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( ModuleMapTypeData%u_ED_PlatformPtMesh_3, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( ModuleMapTypeData%u_ED_PlatformPtMesh_MDf, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( ModuleMapTypeData%u_ED_TowerPtloads, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ModuleMapTypeData%u_ED_BladePtLoads)) THEN DO i1 = LBOUND(ModuleMapTypeData%u_ED_BladePtLoads,1), UBOUND(ModuleMapTypeData%u_ED_BladePtLoads,1) - CALL MeshDestroy( ModuleMapTypeData%u_ED_BladePtLoads(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( ModuleMapTypeData%u_ED_BladePtLoads(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%u_ED_BladePtLoads) ENDIF - 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_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 ) + CALL MeshDestroy( ModuleMapTypeData%u_SD_TPMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( ModuleMapTypeData%u_SD_LMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( ModuleMapTypeData%u_SD_LMesh_2, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( ModuleMapTypeData%u_HD_M_Mesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( ModuleMapTypeData%u_HD_W_Mesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( ModuleMapTypeData%u_ED_HubPtLoad, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( ModuleMapTypeData%u_ED_HubPtLoad_2, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ModuleMapTypeData%u_BD_RootMotion)) THEN DO i1 = LBOUND(ModuleMapTypeData%u_BD_RootMotion,1), UBOUND(ModuleMapTypeData%u_BD_RootMotion,1) - CALL MeshDestroy( ModuleMapTypeData%u_BD_RootMotion(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( ModuleMapTypeData%u_BD_RootMotion(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%u_BD_RootMotion) ENDIF IF (ALLOCATED(ModuleMapTypeData%y_BD_BldMotion_4Loads)) THEN DO i1 = LBOUND(ModuleMapTypeData%y_BD_BldMotion_4Loads,1), UBOUND(ModuleMapTypeData%y_BD_BldMotion_4Loads,1) - CALL MeshDestroy( ModuleMapTypeData%y_BD_BldMotion_4Loads(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( ModuleMapTypeData%y_BD_BldMotion_4Loads(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%y_BD_BldMotion_4Loads) ENDIF IF (ALLOCATED(ModuleMapTypeData%u_BD_Distrload)) THEN DO i1 = LBOUND(ModuleMapTypeData%u_BD_Distrload,1), UBOUND(ModuleMapTypeData%u_BD_Distrload,1) - CALL MeshDestroy( ModuleMapTypeData%u_BD_Distrload(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( ModuleMapTypeData%u_BD_Distrload(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%u_BD_Distrload) ENDIF - CALL MeshDestroy( ModuleMapTypeData%u_Orca_PtfmMesh, ErrStat, ErrMsg ) - CALL MeshDestroy( ModuleMapTypeData%u_ExtPtfm_PtfmMesh, ErrStat, ErrMsg ) + CALL MeshDestroy( ModuleMapTypeData%u_Orca_PtfmMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( ModuleMapTypeData%u_ExtPtfm_PtfmMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE FAST_DestroyModuleMapType SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -37425,6 +38334,40 @@ 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_AD_P_TF: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2, .TRUE. ) ! ED_P_2_AD_P_TF + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! ED_P_2_AD_P_TF + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! ED_P_2_AD_P_TF + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! ED_P_2_AD_P_TF + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! AD_P_2_ED_P_TF: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_TF, ErrStat2, ErrMsg2, .TRUE. ) ! AD_P_2_ED_P_TF + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD_P_2_ED_P_TF + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD_P_2_ED_P_TF + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD_P_2_ED_P_TF + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 3 ! ED_L_2_AD_L_T: size of buffers for each call to pack subtype CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%ED_L_2_AD_L_T, ErrStat2, ErrMsg2, .TRUE. ) ! ED_L_2_AD_L_T CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -37499,6 +38442,23 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + SIZE( Int_Buf ) DEALLOCATE(Int_Buf) END IF + Int_BufSz = Int_BufSz + 3 ! AD_P_2_ED_P_H: size of buffers for each call to pack subtype + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2, .TRUE. ) ! AD_P_2_ED_P_H + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! AD_P_2_ED_P_H + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! AD_P_2_ED_P_H + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! AD_P_2_ED_P_H + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 3 ! IceF_P_2_SD_P: size of buffers for each call to pack subtype CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%IceF_P_2_SD_P, ErrStat2, ErrMsg2, .TRUE. ) ! IceF_P_2_SD_P CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -37645,6 +38605,40 @@ 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_ED_PlatformPtMesh_3: size of buffers for each call to pack subtype + CALL MeshPack( InData%u_ED_PlatformPtMesh_3, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! u_ED_PlatformPtMesh_3 + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! u_ED_PlatformPtMesh_3 + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! u_ED_PlatformPtMesh_3 + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! u_ED_PlatformPtMesh_3 + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF + Int_BufSz = Int_BufSz + 3 ! u_ED_PlatformPtMesh_MDf: size of buffers for each call to pack subtype + CALL MeshPack( InData%u_ED_PlatformPtMesh_MDf, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! u_ED_PlatformPtMesh_MDf + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN ! u_ED_PlatformPtMesh_MDf + Re_BufSz = Re_BufSz + SIZE( Re_Buf ) + DEALLOCATE(Re_Buf) + END IF + IF(ALLOCATED(Db_Buf)) THEN ! u_ED_PlatformPtMesh_MDf + Db_BufSz = Db_BufSz + SIZE( Db_Buf ) + DEALLOCATE(Db_Buf) + END IF + IF(ALLOCATED(Int_Buf)) THEN ! u_ED_PlatformPtMesh_MDf + Int_BufSz = Int_BufSz + SIZE( Int_Buf ) + DEALLOCATE(Int_Buf) + END IF Int_BufSz = Int_BufSz + 3 ! u_ED_TowerPtloads: size of buffers for each call to pack subtype CALL MeshPack( InData%u_ED_TowerPtloads, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! u_ED_TowerPtloads CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -39172,6 +40166,62 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, 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_AD_P_TF, ErrStat2, ErrMsg2, OnlySize ) ! ED_P_2_AD_P_TF + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_TF, ErrStat2, ErrMsg2, OnlySize ) ! AD_P_2_ED_P_TF + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + IF(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 @@ -39297,6 +40347,34 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN + IF(ALLOCATED(Re_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf + Re_Xferred = Re_Xferred + SIZE(Re_Buf) + DEALLOCATE(Re_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Db_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf + Db_Xferred = Db_Xferred + SIZE(Db_Buf) + DEALLOCATE(Db_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + IF(ALLOCATED(Int_Buf)) THEN + IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1 + IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf + Int_Xferred = Int_Xferred + SIZE(Int_Buf) + DEALLOCATE(Int_Buf) + ELSE + IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1 + ENDIF + CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2, OnlySize ) ! AD_P_2_ED_P_H + CALL 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 @@ -39574,6 +40652,62 @@ SUBROUTINE FAST_PackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, 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_ED_PlatformPtMesh_3, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! u_ED_PlatformPtMesh_3 + 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_ED_PlatformPtMesh_MDf, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! u_ED_PlatformPtMesh_MDf + 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 @@ -41523,7 +42657,215 @@ 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%SDy3_P_2_SStC_P_P(i1), ErrStat2, ErrMsg2 ) ! SDy3_P_2_SStC_P_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%SDy3_P_2_SStC_P_P(i1), ErrStat2, ErrMsg2 ) ! SDy3_P_2_SStC_P_P + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + 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_SrvD_P_P, ErrStat2, ErrMsg2 ) ! ED_P_2_SrvD_P_P + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BDED_L_2_AD_L_B not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BDED_L_2_AD_L_B)) DEALLOCATE(OutData%BDED_L_2_AD_L_B) + ALLOCATE(OutData%BDED_L_2_AD_L_B(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BDED_L_2_AD_L_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BDED_L_2_AD_L_B,1), UBOUND(OutData%BDED_L_2_AD_L_B,1) + 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%BDED_L_2_AD_L_B(i1), ErrStat2, ErrMsg2 ) ! BDED_L_2_AD_L_B + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + 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 ! AD_L_2_BDED_B not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AD_L_2_BDED_B)) DEALLOCATE(OutData%AD_L_2_BDED_B) + ALLOCATE(OutData%AD_L_2_BDED_B(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AD_L_2_BDED_B.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AD_L_2_BDED_B,1), UBOUND(OutData%AD_L_2_BDED_B,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) + Re_Xferred = Re_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) + Db_Xferred = Db_Xferred + Buf_size + END IF + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) + Int_Xferred = Int_Xferred + Buf_size + END IF + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_L_2_BDED_B(i1), ErrStat2, ErrMsg2 ) ! AD_L_2_BDED_B + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) + IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) + IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BD_L_2_BD_L not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%BD_L_2_BD_L)) DEALLOCATE(OutData%BD_L_2_BD_L) + ALLOCATE(OutData%BD_L_2_BD_L(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BD_L_2_BD_L.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%BD_L_2_BD_L,1), UBOUND(OutData%BD_L_2_BD_L,1) + Buf_size=IntKiBuf( Int_Xferred ) + Int_Xferred = Int_Xferred + 1 + IF(Buf_size > 0) THEN + 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%BD_L_2_BD_L(i1), ErrStat2, ErrMsg2 ) ! BD_L_2_BD_L CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -41565,27 +42907,13 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_SrvD_P_P, ErrStat2, ErrMsg2 ) ! ED_P_2_SrvD_P_P + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_N, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_N CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BDED_L_2_AD_L_B not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BDED_L_2_AD_L_B)) DEALLOCATE(OutData%BDED_L_2_AD_L_B) - ALLOCATE(OutData%BDED_L_2_AD_L_B(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BDED_L_2_AD_L_B.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%BDED_L_2_AD_L_B,1), UBOUND(OutData%BDED_L_2_AD_L_B,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -41619,85 +42947,13 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%BDED_L_2_AD_L_B(i1), ErrStat2, ErrMsg2 ) ! BDED_L_2_AD_L_B - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - 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 ! AD_L_2_BDED_B not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%AD_L_2_BDED_B)) DEALLOCATE(OutData%AD_L_2_BDED_B) - ALLOCATE(OutData%AD_L_2_BDED_B(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AD_L_2_BDED_B.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%AD_L_2_BDED_B,1), UBOUND(OutData%AD_L_2_BDED_B,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_L_2_BDED_B(i1), ErrStat2, ErrMsg2 ) ! AD_L_2_BDED_B + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_P_2_ED_P_N, ErrStat2, ErrMsg2 ) ! AD_P_2_ED_P_N CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END DO - END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! BD_L_2_BD_L not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%BD_L_2_BD_L)) DEALLOCATE(OutData%BD_L_2_BD_L) - ALLOCATE(OutData%BD_L_2_BD_L(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%BD_L_2_BD_L.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%BD_L_2_BD_L,1), UBOUND(OutData%BD_L_2_BD_L,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -41731,15 +42987,13 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%BD_L_2_BD_L(i1), ErrStat2, ErrMsg2 ) ! BD_L_2_BD_L + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_TF, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_TF CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END DO - END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -41773,7 +43027,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_N, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_N + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_P_2_ED_P_TF, ErrStat2, ErrMsg2 ) ! AD_P_2_ED_P_TF CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -41813,7 +43067,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%AD_P_2_ED_P_N, ErrStat2, ErrMsg2 ) ! AD_P_2_ED_P_N + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_L_2_AD_L_T, ErrStat2, ErrMsg2 ) ! ED_L_2_AD_L_T CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -41853,13 +43107,27 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_L_2_AD_L_T, ErrStat2, ErrMsg2 ) ! ED_L_2_AD_L_T + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_L_2_ED_P_T, ErrStat2, ErrMsg2 ) ! AD_L_2_ED_P_T CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ED_P_2_AD_P_R not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%ED_P_2_AD_P_R)) DEALLOCATE(OutData%ED_P_2_AD_P_R) + ALLOCATE(OutData%ED_P_2_AD_P_R(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ED_P_2_AD_P_R.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%ED_P_2_AD_P_R,1), UBOUND(OutData%ED_P_2_AD_P_R,1) Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -41893,27 +43161,15 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_L_2_ED_P_T, ErrStat2, ErrMsg2 ) ! AD_L_2_ED_P_T + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_R(i1), ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_R CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ED_P_2_AD_P_R not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%ED_P_2_AD_P_R)) DEALLOCATE(OutData%ED_P_2_AD_P_R) - ALLOCATE(OutData%ED_P_2_AD_P_R(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ED_P_2_AD_P_R.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%ED_P_2_AD_P_R,1), UBOUND(OutData%ED_P_2_AD_P_R,1) + END DO + END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -41947,15 +43203,13 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_R(i1), ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_R + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_H CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf ) IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf ) IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) - END DO - END IF Buf_size=IntKiBuf( Int_Xferred ) Int_Xferred = Int_Xferred + 1 IF(Buf_size > 0) THEN @@ -41989,7 +43243,7 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) Int_Xferred = Int_Xferred + Buf_size END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%ED_P_2_AD_P_H, ErrStat2, ErrMsg2 ) ! ED_P_2_AD_P_H + CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%AD_P_2_ED_P_H, ErrStat2, ErrMsg2 ) ! AD_P_2_ED_P_H CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat >= AbortErrLev) RETURN @@ -42369,6 +43623,86 @@ SUBROUTINE FAST_UnPackModuleMapType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta 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_ED_PlatformPtMesh_3, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! u_ED_PlatformPtMesh_3 + 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_ED_PlatformPtMesh_MDf, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! u_ED_PlatformPtMesh_MDf + 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) @@ -43025,15 +44359,27 @@ SUBROUTINE FAST_CopyExternInputType( SrcExternInputTypeData, DstExternInputTypeD DstExternInputTypeData%CableDeltaLdot = SrcExternInputTypeData%CableDeltaLdot END SUBROUTINE FAST_CopyExternInputType - SUBROUTINE FAST_DestroyExternInputType( ExternInputTypeData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyExternInputType( ExternInputTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_ExternInputType), INTENT(INOUT) :: ExternInputTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyExternInputType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyExternInputType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE FAST_DestroyExternInputType SUBROUTINE FAST_PackExternInputType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -43241,17 +44587,31 @@ SUBROUTINE FAST_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE FAST_CopyMisc - SUBROUTINE FAST_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" - CALL FAST_Destroyexterninputtype( MiscData%ExternInput, ErrStat, ErrMsg ) - CALL FAST_Destroymisclintype( MiscData%Lin, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL FAST_Destroyexterninputtype( MiscData%ExternInput, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroymisclintype( MiscData%Lin, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE FAST_DestroyMisc SUBROUTINE FAST_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -43701,52 +45061,96 @@ SUBROUTINE FAST_CopyInitData( SrcInitDataData, DstInitDataData, CtrlCode, ErrSta IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE FAST_CopyInitData - SUBROUTINE FAST_DestroyInitData( InitDataData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyInitData( InitDataData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_InitData), INTENT(INOUT) :: InitDataData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyInitData' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyInitData' + ErrStat = ErrID_None ErrMsg = "" - CALL ED_DestroyInitInput( InitDataData%InData_ED, ErrStat, ErrMsg ) - CALL ED_DestroyInitOutput( InitDataData%OutData_ED, ErrStat, ErrMsg ) - CALL BD_DestroyInitInput( InitDataData%InData_BD, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL ED_DestroyInitInput( InitDataData%InData_ED, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ED_DestroyInitOutput( InitDataData%OutData_ED, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL BD_DestroyInitInput( InitDataData%InData_BD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitDataData%OutData_BD)) THEN DO i1 = LBOUND(InitDataData%OutData_BD,1), UBOUND(InitDataData%OutData_BD,1) - CALL BD_DestroyInitOutput( InitDataData%OutData_BD(i1), ErrStat, ErrMsg ) + CALL BD_DestroyInitOutput( InitDataData%OutData_BD(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InitDataData%OutData_BD) ENDIF - CALL SrvD_DestroyInitInput( InitDataData%InData_SrvD, ErrStat, ErrMsg ) - CALL SrvD_DestroyInitOutput( InitDataData%OutData_SrvD, ErrStat, ErrMsg ) - CALL AD14_DestroyInitInput( InitDataData%InData_AD14, ErrStat, ErrMsg ) - CALL AD14_DestroyInitOutput( InitDataData%OutData_AD14, ErrStat, ErrMsg ) - CALL AD_DestroyInitInput( InitDataData%InData_AD, ErrStat, ErrMsg ) - CALL AD_DestroyInitOutput( InitDataData%OutData_AD, ErrStat, ErrMsg ) - CALL InflowWind_DestroyInitInput( InitDataData%InData_IfW, ErrStat, ErrMsg ) - CALL InflowWind_DestroyInitOutput( InitDataData%OutData_IfW, ErrStat, ErrMsg ) - CALL OpFM_DestroyInitInput( InitDataData%InData_OpFM, ErrStat, ErrMsg ) - CALL OpFM_DestroyInitOutput( InitDataData%OutData_OpFM, ErrStat, ErrMsg ) - CALL HydroDyn_DestroyInitInput( InitDataData%InData_HD, ErrStat, ErrMsg ) - CALL HydroDyn_DestroyInitOutput( InitDataData%OutData_HD, ErrStat, ErrMsg ) - CALL SD_DestroyInitInput( InitDataData%InData_SD, ErrStat, ErrMsg ) - CALL SD_DestroyInitOutput( InitDataData%OutData_SD, ErrStat, ErrMsg ) - CALL ExtPtfm_DestroyInitInput( InitDataData%InData_ExtPtfm, ErrStat, ErrMsg ) - CALL ExtPtfm_DestroyInitOutput( InitDataData%OutData_ExtPtfm, ErrStat, ErrMsg ) - CALL MAP_DestroyInitInput( InitDataData%InData_MAP, ErrStat, ErrMsg ) - CALL MAP_DestroyInitOutput( InitDataData%OutData_MAP, ErrStat, ErrMsg ) - CALL FEAM_DestroyInitInput( InitDataData%InData_FEAM, ErrStat, ErrMsg ) - CALL FEAM_DestroyInitOutput( InitDataData%OutData_FEAM, ErrStat, ErrMsg ) - CALL MD_DestroyInitInput( InitDataData%InData_MD, ErrStat, ErrMsg ) - CALL MD_DestroyInitOutput( InitDataData%OutData_MD, ErrStat, ErrMsg ) - CALL Orca_DestroyInitInput( InitDataData%InData_Orca, ErrStat, ErrMsg ) - CALL Orca_DestroyInitOutput( InitDataData%OutData_Orca, ErrStat, ErrMsg ) - CALL IceFloe_DestroyInitInput( InitDataData%InData_IceF, ErrStat, ErrMsg ) - CALL IceFloe_DestroyInitOutput( InitDataData%OutData_IceF, ErrStat, ErrMsg ) - CALL IceD_DestroyInitInput( InitDataData%InData_IceD, ErrStat, ErrMsg ) - CALL IceD_DestroyInitOutput( InitDataData%OutData_IceD, ErrStat, ErrMsg ) + CALL SrvD_DestroyInitInput( InitDataData%InData_SrvD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SrvD_DestroyInitOutput( InitDataData%OutData_SrvD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_DestroyInitInput( InitDataData%InData_AD14, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD14_DestroyInitOutput( InitDataData%OutData_AD14, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD_DestroyInitInput( InitDataData%InData_AD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL AD_DestroyInitOutput( InitDataData%OutData_AD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyInitInput( InitDataData%InData_IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL InflowWind_DestroyInitOutput( InitDataData%OutData_IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL OpFM_DestroyInitInput( InitDataData%InData_OpFM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL OpFM_DestroyInitOutput( InitDataData%OutData_OpFM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL HydroDyn_DestroyInitInput( InitDataData%InData_HD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL HydroDyn_DestroyInitOutput( InitDataData%OutData_HD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SD_DestroyInitInput( InitDataData%InData_SD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL SD_DestroyInitOutput( InitDataData%OutData_SD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ExtPtfm_DestroyInitInput( InitDataData%InData_ExtPtfm, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL ExtPtfm_DestroyInitOutput( InitDataData%OutData_ExtPtfm, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MAP_DestroyInitInput( InitDataData%InData_MAP, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MAP_DestroyInitOutput( InitDataData%OutData_MAP, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FEAM_DestroyInitInput( InitDataData%InData_FEAM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FEAM_DestroyInitOutput( InitDataData%OutData_FEAM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MD_DestroyInitInput( InitDataData%InData_MD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MD_DestroyInitOutput( InitDataData%OutData_MD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Orca_DestroyInitInput( InitDataData%InData_Orca, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL Orca_DestroyInitOutput( InitDataData%OutData_Orca, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IceFloe_DestroyInitInput( InitDataData%InData_IceF, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IceFloe_DestroyInitOutput( InitDataData%OutData_IceF, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IceD_DestroyInitInput( InitDataData%InData_IceD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL IceD_DestroyInitOutput( InitDataData%OutData_IceD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE FAST_DestroyInitData SUBROUTINE FAST_PackInitData( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -46618,6 +48022,7 @@ SUBROUTINE FAST_CopyExternInitType( SrcExternInitTypeData, DstExternInitTypeData DstExternInitTypeData%LidRadialVel = SrcExternInitTypeData%LidRadialVel DstExternInitTypeData%TurbineID = SrcExternInitTypeData%TurbineID DstExternInitTypeData%TurbinePos = SrcExternInitTypeData%TurbinePos + DstExternInitTypeData%WaveFieldMod = SrcExternInitTypeData%WaveFieldMod DstExternInitTypeData%NumSC2CtrlGlob = SrcExternInitTypeData%NumSC2CtrlGlob DstExternInitTypeData%NumSC2Ctrl = SrcExternInitTypeData%NumSC2Ctrl DstExternInitTypeData%NumCtrl2SC = SrcExternInitTypeData%NumCtrl2SC @@ -46652,17 +48057,30 @@ SUBROUTINE FAST_CopyExternInitType( SrcExternInitTypeData, DstExternInitTypeData DstExternInitTypeData%RootName = SrcExternInitTypeData%RootName DstExternInitTypeData%NumActForcePtsBlade = SrcExternInitTypeData%NumActForcePtsBlade DstExternInitTypeData%NumActForcePtsTower = SrcExternInitTypeData%NumActForcePtsTower + DstExternInitTypeData%NodeClusterType = SrcExternInitTypeData%NodeClusterType END SUBROUTINE FAST_CopyExternInitType - SUBROUTINE FAST_DestroyExternInitType( ExternInitTypeData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyExternInitType( ExternInitTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_ExternInitType), INTENT(INOUT) :: ExternInitTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyExternInitType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyExternInitType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ExternInitTypeData%fromSCGlob)) THEN DEALLOCATE(ExternInitTypeData%fromSCGlob) ENDIF @@ -46711,6 +48129,7 @@ SUBROUTINE FAST_PackExternInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 1 ! LidRadialVel Int_BufSz = Int_BufSz + 1 ! TurbineID Re_BufSz = Re_BufSz + SIZE(InData%TurbinePos) ! TurbinePos + Int_BufSz = Int_BufSz + 1 ! WaveFieldMod Int_BufSz = Int_BufSz + 1 ! NumSC2CtrlGlob Int_BufSz = Int_BufSz + 1 ! NumSC2Ctrl Int_BufSz = Int_BufSz + 1 ! NumCtrl2SC @@ -46731,6 +48150,7 @@ SUBROUTINE FAST_PackExternInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName Int_BufSz = Int_BufSz + 1 ! NumActForcePtsBlade Int_BufSz = Int_BufSz + 1 ! NumActForcePtsTower + Int_BufSz = Int_BufSz + 1 ! NodeClusterType IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -46770,6 +48190,8 @@ SUBROUTINE FAST_PackExternInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ReKiBuf(Re_Xferred) = InData%TurbinePos(i1) Re_Xferred = Re_Xferred + 1 END DO + IntKiBuf(Int_Xferred) = InData%WaveFieldMod + Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NumSC2CtrlGlob Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NumSC2Ctrl @@ -46828,6 +48250,8 @@ SUBROUTINE FAST_PackExternInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NumActForcePtsTower Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%NodeClusterType, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE FAST_PackExternInitType SUBROUTINE FAST_UnPackExternInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -46871,6 +48295,8 @@ SUBROUTINE FAST_UnPackExternInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt OutData%TurbinePos(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO + OutData%WaveFieldMod = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%NumSC2CtrlGlob = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 OutData%NumSC2Ctrl = IntKiBuf(Int_Xferred) @@ -46941,6 +48367,8 @@ SUBROUTINE FAST_UnPackExternInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSt Int_Xferred = Int_Xferred + 1 OutData%NumActForcePtsTower = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + OutData%NodeClusterType = TRANSFER(IntKiBuf(Int_Xferred), OutData%NodeClusterType) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE FAST_UnPackExternInitType SUBROUTINE FAST_CopyTurbineType( SrcTurbineTypeData, DstTurbineTypeData, CtrlCode, ErrStat, ErrMsg ) @@ -47023,36 +48451,69 @@ SUBROUTINE FAST_CopyTurbineType( SrcTurbineTypeData, DstTurbineTypeData, CtrlCod IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE FAST_CopyTurbineType - SUBROUTINE FAST_DestroyTurbineType( TurbineTypeData, ErrStat, ErrMsg ) + SUBROUTINE FAST_DestroyTurbineType( TurbineTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(FAST_TurbineType), INTENT(INOUT) :: TurbineTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyTurbineType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'FAST_DestroyTurbineType' + ErrStat = ErrID_None ErrMsg = "" - CALL FAST_DestroyParam( TurbineTypeData%p_FAST, ErrStat, ErrMsg ) - CALL FAST_Destroyoutputfiletype( TurbineTypeData%y_FAST, ErrStat, ErrMsg ) - CALL FAST_DestroyMisc( TurbineTypeData%m_FAST, ErrStat, ErrMsg ) - CALL FAST_Destroymodulemaptype( TurbineTypeData%MeshMapData, ErrStat, ErrMsg ) - CALL FAST_Destroyelastodyn_data( TurbineTypeData%ED, ErrStat, ErrMsg ) - CALL FAST_Destroybeamdyn_data( TurbineTypeData%BD, ErrStat, ErrMsg ) - CALL FAST_Destroyservodyn_data( TurbineTypeData%SrvD, ErrStat, ErrMsg ) - CALL FAST_Destroyaerodyn_data( TurbineTypeData%AD, ErrStat, ErrMsg ) - CALL FAST_Destroyaerodyn14_data( TurbineTypeData%AD14, ErrStat, ErrMsg ) - CALL FAST_Destroyinflowwind_data( TurbineTypeData%IfW, ErrStat, ErrMsg ) - CALL FAST_Destroyopenfoam_data( TurbineTypeData%OpFM, ErrStat, ErrMsg ) - CALL FAST_Destroyscdataex_data( TurbineTypeData%SC_DX, ErrStat, ErrMsg ) - CALL FAST_Destroyhydrodyn_data( TurbineTypeData%HD, ErrStat, ErrMsg ) - CALL FAST_Destroysubdyn_data( TurbineTypeData%SD, ErrStat, ErrMsg ) - CALL FAST_Destroymap_data( TurbineTypeData%MAP, ErrStat, ErrMsg ) - CALL FAST_Destroyfeamooring_data( TurbineTypeData%FEAM, ErrStat, ErrMsg ) - CALL FAST_Destroymoordyn_data( TurbineTypeData%MD, ErrStat, ErrMsg ) - CALL FAST_Destroyorcaflex_data( TurbineTypeData%Orca, ErrStat, ErrMsg ) - CALL FAST_Destroyicefloe_data( TurbineTypeData%IceF, ErrStat, ErrMsg ) - CALL FAST_Destroyicedyn_data( TurbineTypeData%IceD, ErrStat, ErrMsg ) - CALL FAST_Destroyextptfm_data( TurbineTypeData%ExtPtfm, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL FAST_DestroyParam( TurbineTypeData%p_FAST, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyoutputfiletype( TurbineTypeData%y_FAST, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_DestroyMisc( TurbineTypeData%m_FAST, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroymodulemaptype( TurbineTypeData%MeshMapData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyelastodyn_data( TurbineTypeData%ED, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroybeamdyn_data( TurbineTypeData%BD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyservodyn_data( TurbineTypeData%SrvD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyaerodyn_data( TurbineTypeData%AD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyaerodyn14_data( TurbineTypeData%AD14, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyinflowwind_data( TurbineTypeData%IfW, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyopenfoam_data( TurbineTypeData%OpFM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyscdataex_data( TurbineTypeData%SC_DX, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyhydrodyn_data( TurbineTypeData%HD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroysubdyn_data( TurbineTypeData%SD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroymap_data( TurbineTypeData%MAP, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyfeamooring_data( TurbineTypeData%FEAM, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroymoordyn_data( TurbineTypeData%MD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyorcaflex_data( TurbineTypeData%Orca, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyicefloe_data( TurbineTypeData%IceF, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyicedyn_data( TurbineTypeData%IceD, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL FAST_Destroyextptfm_data( TurbineTypeData%ExtPtfm, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE FAST_DestroyTurbineType SUBROUTINE FAST_PackTurbineType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) diff --git a/modules/openfast-registry/src/data.h b/modules/openfast-registry/src/data.h index bc81980c7..4680d1539 100644 --- a/modules/openfast-registry/src/data.h +++ b/modules/openfast-registry/src/data.h @@ -76,6 +76,8 @@ typedef struct node_struct { int is_interface_type ; +/* array pointer instead of allocatable*/ + int is_pointer; /* 0 = allocatable, 1 = pointer */ /* marker */ int mark ; diff --git a/modules/openfast-registry/src/gen_module_files.c b/modules/openfast-registry/src/gen_module_files.c index e0438498b..1d15ebfe0 100644 --- a/modules/openfast-registry/src/gen_module_files.c +++ b/modules/openfast-registry/src/gen_module_files.c @@ -146,7 +146,14 @@ gen_copy_f2c(FILE *fp, // *.f90 file we are writting to fprintf(fp, " ELSE\n"); fprintf(fp, " %sData%%c_obj%%%s_Len = SIZE(%sData%%%s)\n", nonick, r->name, nonick, r->name); fprintf(fp, " IF (%sData%%c_obj%%%s_Len > 0) &\n", nonick, r->name); - fprintf(fp, " %sData%%c_obj%%%s = C_LOC( %sData%%%s( LBOUND(%sData%%%s,1) ) ) \n", nonick, r->name, nonick, r->name, nonick, r->name ); + + fprintf(fp, " %sData%%c_obj%%%s = C_LOC( %sData%%%s(", nonick, r->name, nonick, r->name); + for (int d = 1; d <= r->ndims; d++) { + fprintf(fp, " LBOUND(%sData%%%s,%d)", nonick, r->name, d); + if (d < r->ndims) { fprintf(fp, ","); } + } + fprintf(fp, " ) )\n"); + fprintf(fp, " END IF\n"); fprintf(fp, " END IF\n"); } @@ -241,7 +248,14 @@ gen_copy( FILE * fp, const node_t * ModName, char * inout, char * inoutlong, con if ( sw_ccode && is_pointer(r) ) { // bjj: this needs to be updated if we've got multiple dimension arrays fprintf(fp," Dst%sData%%c_obj%%%s_Len = SIZE(Dst%sData%%%s)\n",nonick,r->name,nonick,r->name) ; fprintf(fp," IF (Dst%sData%%c_obj%%%s_Len > 0) &\n",nonick,r->name) ; - fprintf(fp," Dst%sData%%c_obj%%%s = C_LOC( Dst%sData%%%s(i1_l) ) \n",nonick,r->name, nonick,r->name ) ; + + fprintf(fp, " Dst%sData%%c_obj%%%s = C_LOC( Dst%sData%%%s(", nonick, r->name, nonick, r->name); + for (d = 1; d <= r->ndims; d++) { + fprintf(fp, " i%d_l", d); + if (d < r->ndims) { fprintf(fp, ","); } + } + fprintf(fp, " ) )\n"); + } fprintf(fp," END IF\n") ; // end dest allocated/associated @@ -734,7 +748,14 @@ gen_unpack( FILE * fp, const node_t * ModName, char * inout, char * inoutlong ) if (sw_ccode && is_pointer(r)) { // bjj: this needs to be updated if we've got multiple dimension arrays fprintf(fp, " OutData%%c_obj%%%s_Len = SIZE(OutData%%%s)\n", r->name, r->name); fprintf(fp, " IF (OutData%%c_obj%%%s_Len > 0) &\n", r->name); - fprintf(fp, " OutData%%c_obj%%%s = C_LOC( OutData%%%s(i1_l) ) \n", r->name, r->name); + + fprintf(fp, " OutData%%c_obj%%%s = C_LOC( OutData%%%s(", r->name,r->name); + for (d = 1; d <= r->ndims; d++) { + fprintf(fp, " i%d_l", d); + if (d < r->ndims) { fprintf(fp, ","); } + } + fprintf(fp, " ) )\n"); + } strcpy(mainIndent, " "); } @@ -945,15 +966,26 @@ gen_destroy( FILE * fp, const node_t * ModName, char * inout, char * inoutlong ) remove_nickname(ModName->nickname,inout,nonick) ; append_nickname((is_a_fast_interface_type(inoutlong))?ModName->nickname:"",inoutlong,addnick) ; - fprintf(fp, " SUBROUTINE %s_Destroy%s( %sData, ErrStat, ErrMsg )\n",ModName->nickname,nonick,nonick ); + fprintf(fp, " SUBROUTINE %s_Destroy%s( %sData, ErrStat, ErrMsg, DEALLOCATEpointers )\n",ModName->nickname,nonick,nonick ); fprintf(fp, " TYPE(%s), INTENT(INOUT) :: %sData\n",addnick,nonick) ; fprintf(fp, " INTEGER(IntKi), INTENT( OUT) :: ErrStat\n") ; fprintf(fp, " CHARACTER(*), INTENT( OUT) :: ErrMsg\n"); - fprintf(fp, " CHARACTER(*), PARAMETER :: RoutineName = '%s_Destroy%s'\n", ModName->nickname, nonick); + fprintf(fp, " LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers\n"); + fprintf(fp, " \n"); fprintf(fp, " INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 \n"); - fprintf(fp,"! \n") ; - fprintf(fp," ErrStat = ErrID_None\n") ; - fprintf(fp, " ErrMsg = \"\"\n"); + fprintf(fp, " LOGICAL :: DEALLOCATEpointers_local\n"); + fprintf(fp, " INTEGER(IntKi) :: ErrStat2\n"); + fprintf(fp, " CHARACTER(ErrMsgLen) :: ErrMsg2\n"); + fprintf(fp, " CHARACTER(*), PARAMETER :: RoutineName = '%s_Destroy%s'\n\n", ModName->nickname, nonick); + fprintf(fp, " ErrStat = ErrID_None\n"); + fprintf(fp, " ErrMsg = \"\"\n\n"); + fprintf(fp, " IF (PRESENT(DEALLOCATEpointers)) THEN\n"); + fprintf(fp, " DEALLOCATEpointers_local = DEALLOCATEpointers\n"); + fprintf(fp, " ELSE\n"); + fprintf(fp, " DEALLOCATEpointers_local = .true.\n"); + fprintf(fp, " END IF\n"); + fprintf(fp," \n") ; + // sprintf(tmp,"%s_%s",ModName->nickname,inoutlong) ; // sprintf(tmp,"%s",inoutlong) ; @@ -979,16 +1011,20 @@ gen_destroy( FILE * fp, const node_t * ModName, char * inout, char * inoutlong ) } if (!strcmp(r->type->name, "meshtype")) { - fprintf(fp, " CALL MeshDestroy( %sData%%%s%s, ErrStat, ErrMsg )\n", nonick, r->name, dimstr(r->ndims)); + fprintf(fp, " CALL MeshDestroy( %sData%%%s%s, ErrStat2, ErrMsg2 )\n", nonick, r->name, dimstr(r->ndims)); + fprintf(fp, " CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)\n"); } else if (!strcmp(r->type->name, "dll_type")) { - fprintf(fp, " CALL FreeDynamicLib( %sData%%%s%s, ErrStat, ErrMsg )\n", nonick, r->name, dimstr(r->ndims)); + fprintf(fp, " CALL FreeDynamicLib( %sData%%%s%s, ErrStat2, ErrMsg2 )\n", nonick, r->name, dimstr(r->ndims)); + fprintf(fp, " CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)\n"); + } else { //if (r->type->type_type == DERIVED) { // && ! r->type->usefrom ) { char nonick2[NAMELEN]; remove_nickname(r->type->module->nickname, r->type->name, nonick2); - fprintf(fp, " CALL %s_Destroy%s( %sData%%%s%s, ErrStat, ErrMsg )\n", - r->type->module->nickname, fast_interface_type_shortname(nonick2), nonick, r->name, dimstr(r->ndims)); + fprintf(fp, " CALL %s_Destroy%s( %sData%%%s%s, ErrStat2, ErrMsg2, DEALLOCATEpointers_local )\n", + r->type->module->nickname, fast_interface_type_shortname(nonick2), nonick, r->name, dimstr(r->ndims)); + fprintf(fp, " CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)\n"); } for (d = r->ndims; d >= 1; d--) { @@ -996,6 +1032,9 @@ gen_destroy( FILE * fp, const node_t * ModName, char * inout, char * inoutlong ) } } if ( r->ndims > 0 && has_deferred_dim(r,0) ) { + if (is_pointer(r)) { + fprintf(fp, " IF (DEALLOCATEpointers_local) &\n"); + } fprintf(fp," DEALLOCATE(%sData%%%s)\n",nonick,r->name) ; if ( is_pointer(r) ) { fprintf(fp, " %sData%%%s => NULL()\n",nonick,r->name) ; @@ -1559,7 +1598,7 @@ fprintf(fp," END IF\n") ; #endif void -gen_ExtrapInterp1(FILE *fp, const node_t * ModName, char * typnm, char * typnmlong, char * xtypnm, char * uy, const int max_ndims, const int max_nrecurs, const int max_alloc_ndims, const node_t *q) +gen_ExtrapInterp1(FILE *fp, const node_t * ModName, char * typnm, char * typnmlong, char * xtypnm, char * uy, char * modPrefix, const int max_ndims, const int max_nrecurs, const int max_alloc_ndims, const node_t *q) { node_t *r; int i, j; @@ -1579,10 +1618,10 @@ gen_ExtrapInterp1(FILE *fp, const node_t * ModName, char * typnm, char * typnmlo fprintf(fp, "\n"); - fprintf(fp, " TYPE(%s_%s), INTENT(%s) :: %s1 ! %s at t1 > t2\n", ModName->nickname, typnmlong, (q->containsPtr == 1) ? "INOUT" : "IN", uy, typnm); - fprintf(fp, " TYPE(%s_%s), INTENT(%s) :: %s2 ! %s at t2 \n", ModName->nickname, typnmlong, (q->containsPtr == 1) ? "INOUT" : "IN", uy, typnm); + fprintf(fp, " TYPE(%s%s), INTENT(%s) :: %s1 ! %s at t1 > t2\n", modPrefix, typnmlong, (q->containsPtr == 1) ? "INOUT" : "IN", uy, typnm); + fprintf(fp, " TYPE(%s%s), INTENT(%s) :: %s2 ! %s at t2 \n", modPrefix, typnmlong, (q->containsPtr == 1) ? "INOUT" : "IN", uy, typnm); fprintf(fp, " REAL(%s), INTENT(IN ) :: tin(2) ! Times associated with the %ss\n", xtypnm, typnm); - fprintf(fp, " TYPE(%s_%s), INTENT(INOUT) :: %s_out ! %s at tin_out\n", ModName->nickname, typnmlong, uy, typnm); + fprintf(fp, " TYPE(%s%s), INTENT(INOUT) :: %s_out ! %s at tin_out\n", modPrefix, typnmlong, uy, typnm); fprintf(fp, " REAL(%s), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to\n", xtypnm); fprintf(fp, " INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation\n"); fprintf(fp, " CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None\n"); @@ -1633,7 +1672,7 @@ gen_ExtrapInterp1(FILE *fp, const node_t * ModName, char * typnm, char * typnmlo } void -gen_ExtrapInterp2(FILE *fp, const node_t * ModName, char * typnm, char * typnmlong, char * xtypnm, char * uy, const int max_ndims, const int max_nrecurs, const int max_alloc_ndims, const node_t *q) +gen_ExtrapInterp2(FILE *fp, const node_t * ModName, char * typnm, char * typnmlong, char * xtypnm, char * uy, char * modPrefix, const int max_ndims, const int max_nrecurs, const int max_alloc_ndims, const node_t *q) { node_t *r; int i, j; @@ -1654,11 +1693,11 @@ gen_ExtrapInterp2(FILE *fp, const node_t * ModName, char * typnm, char * typnmlo fprintf(fp, "!..................................................................................................................................\n"); fprintf(fp, "\n"); - fprintf(fp, " TYPE(%s_%s), INTENT(%s) :: %s1 ! %s at t1 > t2 > t3\n", ModName->nickname, typnmlong, (q->containsPtr == 1) ? "INOUT" : "IN", uy, typnm); - fprintf(fp, " TYPE(%s_%s), INTENT(%s) :: %s2 ! %s at t2 > t3\n", ModName->nickname, typnmlong, (q->containsPtr == 1) ? "INOUT" : "IN", uy, typnm); - fprintf(fp, " TYPE(%s_%s), INTENT(%s) :: %s3 ! %s at t3\n", ModName->nickname, typnmlong, (q->containsPtr == 1) ? "INOUT" : "IN", uy, typnm); + fprintf(fp, " TYPE(%s%s), INTENT(%s) :: %s1 ! %s at t1 > t2 > t3\n", modPrefix, typnmlong, (q->containsPtr == 1) ? "INOUT" : "IN", uy, typnm); + fprintf(fp, " TYPE(%s%s), INTENT(%s) :: %s2 ! %s at t2 > t3\n", modPrefix, typnmlong, (q->containsPtr == 1) ? "INOUT" : "IN", uy, typnm); + fprintf(fp, " TYPE(%s%s), INTENT(%s) :: %s3 ! %s at t3\n", modPrefix, typnmlong, (q->containsPtr == 1) ? "INOUT" : "IN", uy, typnm); fprintf(fp, " REAL(%s), INTENT(IN ) :: tin(3) ! Times associated with the %ss\n", xtypnm, typnm); - fprintf(fp, " TYPE(%s_%s), INTENT(INOUT) :: %s_out ! %s at tin_out\n", ModName->nickname, typnmlong, uy, typnm); + fprintf(fp, " TYPE(%s%s), INTENT(INOUT) :: %s_out ! %s at tin_out\n", modPrefix, typnmlong, uy, typnm); fprintf(fp, " REAL(%s), INTENT(IN ) :: tin_out ! time to be extrap/interp'd to\n", xtypnm); fprintf(fp, " INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation\n" ); @@ -1720,10 +1759,10 @@ gen_ExtrapInterp2(FILE *fp, const node_t * ModName, char * typnm, char * typnmlo void -gen_ExtrapInterp(FILE *fp, const node_t * ModName, char * typnm, char * typnmlong, char * xtypnm) +gen_ExtrapInterp(FILE *fp, const node_t * ModName, char * typnm, char * typnmlong, char * xtypnm, const int useModPrefix) { char nonick[NAMELEN]; - char *ddtname; char uy[2]; + char *ddtname; char uy[2]; char modPrefix[NAMELEN + 1]; node_t *q, *r; int max_ndims, max_nrecurs, max_alloc_ndims; @@ -1734,6 +1773,15 @@ gen_ExtrapInterp(FILE *fp, const node_t * ModName, char * typnm, char * typnmlon strcpy(uy, "u"); } + if (useModPrefix == 1) { + strcpy(modPrefix, ModName->nickname); + strcat(modPrefix, "_"); + } + else + { + strcpy(modPrefix, ""); + } + for (q = ModName->module_ddt_list; q; q = q->next) { if (q->usefrom == 0) { @@ -1760,11 +1808,11 @@ gen_ExtrapInterp(FILE *fp, const node_t * ModName, char * typnm, char * typnmlon fprintf(fp, "\n"); - fprintf(fp, " TYPE(%s_%s), INTENT(%s) :: %s(:) ! %s at t1 > t2 > t3\n", ModName->nickname, typnmlong, (q->containsPtr == 1) ? "INOUT" : "IN", uy, typnm); + fprintf(fp, " TYPE(%s%s), INTENT(%s) :: %s(:) ! %s at t1 > t2 > t3\n", modPrefix, typnmlong, (q->containsPtr == 1) ? "INOUT" : "IN", uy, typnm); fprintf(fp, " REAL(%s), INTENT(IN ) :: t(:) ! Times associated with the %ss\n", xtypnm, typnm); //jm Modified from INTENT( OUT) to INTENT(INOUT) to prevent ALLOCATABLE array arguments in the DDT //jm from being maliciously deallocated through the call.See Sec. 5.1.2.7 of bonehead Fortran 2003 standard - fprintf(fp, " TYPE(%s_%s), INTENT(INOUT) :: %s_out ! %s at tin_out\n", ModName->nickname, typnmlong, uy, typnm); + fprintf(fp, " TYPE(%s%s), INTENT(INOUT) :: %s_out ! %s at tin_out\n", modPrefix, typnmlong, uy, typnm); fprintf(fp, " REAL(%s), INTENT(IN ) :: t_out ! time to be extrap/interp'd to\n", xtypnm); fprintf(fp, " INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation\n"); fprintf(fp, " CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None\n"); @@ -1811,8 +1859,8 @@ gen_ExtrapInterp(FILE *fp, const node_t * ModName, char * typnm, char * typnmlon calc_extint_order(fp, ModName, r, 0, &max_ndims, &max_nrecurs, &max_alloc_ndims); } - gen_ExtrapInterp1(fp, ModName, typnm, typnmlong, xtypnm, uy, max_ndims, max_nrecurs, max_alloc_ndims, q); - gen_ExtrapInterp2(fp, ModName, typnm, typnmlong, xtypnm, uy, max_ndims, max_nrecurs, max_alloc_ndims, q); + gen_ExtrapInterp1(fp, ModName, typnm, typnmlong, xtypnm, uy, modPrefix, max_ndims, max_nrecurs, max_alloc_ndims, q); + gen_ExtrapInterp2(fp, ModName, typnm, typnmlong, xtypnm, uy, modPrefix, max_ndims, max_nrecurs, max_alloc_ndims, q); } } @@ -2126,7 +2174,7 @@ gen_module( FILE * fp , node_t * ModName, char * prog_ver ) } } - if ( is_pointer(r) ) { + if (sw_ccode && is_pointer(r) ) { fprintf(fp," %s ",c_types_binding(r->type->mapsto) ) ; } else { fprintf(fp," %s ",r->type->mapsto ) ; @@ -2252,16 +2300,21 @@ gen_module( FILE * fp , node_t * ModName, char * prog_ver ) // gen_rk4( fp, ModName ) ; if (strcmp(make_lower_temp(ModName->name), "airfoilinfo") == 0) { // make interpolation routines for AirfoilInfo module - gen_ExtrapInterp(fp, ModName, "Output", "OutputType","ReKi"); - gen_ExtrapInterp(fp, ModName, "UA_BL_Type", "UA_BL_Type", "ReKi"); + gen_ExtrapInterp(fp, ModName, "Output", "OutputType","ReKi",1); + gen_ExtrapInterp(fp, ModName, "UA_BL_Type", "UA_BL_Type", "ReKi",1); } else if (!sw_noextrap) { if (strcmp(make_lower_temp(ModName->name), "dbemt") == 0) { // make interpolation routines for element-level DBEMT module - - gen_ExtrapInterp(fp, ModName, "ElementInputType", "ElementInputType", "DbKi"); + gen_ExtrapInterp(fp, ModName, "ElementInputType", "ElementInputType", "DbKi",1); } - - gen_ExtrapInterp(fp, ModName, "Input", "InputType", "DbKi"); - gen_ExtrapInterp(fp, ModName, "Output", "OutputType", "DbKi"); +// else if (strcmp(make_lower_temp(ModName->name), "bemt") == 0) { +// gen_ExtrapInterp(fp, ModName, "SkewWake_InputType", "SkewWake_InputType", "DbKi",1); +// } +// else if (strcmp(make_lower_temp(ModName->name), "aerodyn") == 0) { +// gen_ExtrapInterp(fp, ModName, "RotInputType", "RotInputType", "DbKi",0); // don't append "AD_" to the type name! +// } + + gen_ExtrapInterp(fp, ModName, "Input", "InputType", "DbKi",1); + gen_ExtrapInterp(fp, ModName, "Output", "OutputType", "DbKi",1); } fprintf(fp,"END MODULE %s_Types\n",ModName->name ) ; @@ -2294,40 +2347,42 @@ gen_module_files ( char * dirname, char * prog_ver ) if ((fp = fopen( fname , "w" )) == NULL ) return(1) ; print_warning(fp,fname2, ""); - if ( sw_ccode == 1 ) { - - - if ( strlen(dirname) > 0 ) - { sprintf(fname,"%s/%s_Types.h",dirname,p->name) ; } - else - { sprintf(fname, "%s_Types.h",p->name) ;} - sprintf(fname2,"%s_Types.h",p->name) ; - if ((fph = fopen( fname , "w" )) == NULL ) return(1) ; - - - print_warning(fph,fname2, "//") ; - - fprintf(fph,"\n#ifndef _%s_TYPES_H\n",p->name); - fprintf(fph,"#define _%s_TYPES_H\n\n",p->name); - fprintf(fph,"\n#ifdef _WIN32 //define something for Windows (32-bit)\n"); - fprintf(fph,"# include \"stdbool.h\"\n"); - fprintf(fph,"# define CALL __declspec( dllexport )\n"); - fprintf(fph,"#elif _WIN64 //define something for Windows (64-bit)\n"); - fprintf(fph,"# include \"stdbool.h\"\n"); - fprintf(fph,"# define CALL __declspec( dllexport ) \n"); - fprintf(fph,"#else\n"); - fprintf(fph,"# include \n"); - fprintf(fph,"# define CALL \n"); - fprintf(fph,"#endif\n\n\n"); - } gen_module ( fp , p, prog_ver ) ; close_the_file( fp, "" ) ; - if ( sw_ccode ) { - gen_c_module ( fph , p ) ; - - fprintf(fph,"\n#endif // _%s_TYPES_H\n\n\n",p->name); - close_the_file( fph,"//") ; + // generate .h files for C/C++: + if ( sw_ccode ) { + if (strlen(dirname) > 0) + { + sprintf(fname, "%s/%s_Types.h", dirname, p->name); + } + else + { + sprintf(fname, "%s_Types.h", p->name); + } + sprintf(fname2, "%s_Types.h", p->name); + fprintf(stderr, "generating %s\n", fname); + + if ((fph = fopen(fname, "w")) == NULL) return(1); + print_warning(fph, fname2, "//"); + + fprintf(fph, "\n#ifndef _%s_TYPES_H\n", p->name); + fprintf(fph, "#define _%s_TYPES_H\n\n", p->name); + fprintf(fph, "\n#ifdef _WIN32 //define something for Windows (32-bit)\n"); + fprintf(fph, "# include \"stdbool.h\"\n"); + fprintf(fph, "# define CALL __declspec( dllexport )\n"); + fprintf(fph, "#elif _WIN64 //define something for Windows (64-bit)\n"); + fprintf(fph, "# include \"stdbool.h\"\n"); + fprintf(fph, "# define CALL __declspec( dllexport ) \n"); + fprintf(fph, "#else\n"); + fprintf(fph, "# include \n"); + fprintf(fph, "# define CALL \n"); + fprintf(fph, "#endif\n\n\n"); + + gen_c_module(fph, p); + + fprintf(fph, "\n#endif // _%s_TYPES_H\n\n\n", p->name); + close_the_file(fph, "//"); } } } diff --git a/modules/openfast-registry/src/reg_parse.c b/modules/openfast-registry/src/reg_parse.c index ab645697c..ccacae580 100644 --- a/modules/openfast-registry/src/reg_parse.c +++ b/modules/openfast-registry/src/reg_parse.c @@ -468,7 +468,45 @@ reg_parse( FILE * infile ) tokens[FIELD_SYM], tokens[FIELD_TYPE] ) ; } #endif field_struct->usefrom = type_struct->usefrom ; - + /* Error Checking for Fortran Pointers used outside of FAST Interfaces: InitInputType, InitOutputType, Parameter */ + /* Note: Skip this check if the -ccode option is being used */ + if (field_struct->ndims > 0) { + if (!sw_ccode && is_pointer(field_struct)) { + if (modname_struct->is_interface_type) { + char nonick[NAMELEN]; + sprintf(tmpstr, "%s", make_lower_temp(ddtname)); + remove_nickname(modname_struct->nickname, tmpstr, nonick); + if (!strcmp(nonick, "continuousstatetype")) { + fprintf(stderr, "REGISTRY ERROR: Fortran Pointer Arrays cannot be used in ContinuousStateType data\n"); + exit(9); + } + if (!strcmp(nonick, "discretestatetype")) { + fprintf(stderr, "REGISTRY ERROR: Fortran Pointer Arrays cannot be used in DiscreteStateType data\n"); + exit(9); + } + if (!strcmp(nonick, "constraintstatetype")) { + fprintf(stderr, "REGISTRY ERROR: Fortran Pointer Arrays cannot be used in ConstraintStateType data\n"); + exit(9); + } + if (!strcmp(nonick, "otherstatetype")) { + fprintf(stderr, "REGISTRY ERROR: Fortran Pointer Arrays cannot be used in OtherStateType data\n"); + exit(9); + } + if (!strcmp(nonick, "miscvartype")) { + fprintf(stderr, "REGISTRY ERROR: Fortran Pointer Arrays cannot be used in MiscVarType data\n"); + exit(9); + } + if (!strcmp(nonick, "inputtype")) { + fprintf(stderr, "REGISTRY ERROR: Fortran Pointer Arrays cannot be used in InputType data\n"); + exit(9); + } + if (!strcmp(nonick, "outputtype")) { + fprintf(stderr, "REGISTRY ERROR: Fortran Pointer Arrays cannot be used in OutputType data\n"); + exit(9); + } + } + } + } add_node_to_end( field_struct , &(type_struct->fields) ) ; } // not param @@ -561,12 +599,13 @@ int set_dim_len ( char * dimspec , node_t * dim_entry ) { dim_entry->deferred = 0 ; + dim_entry->is_pointer = 0; if (!strcmp( dimspec , "standard_domain" )) { dim_entry->len_defined_how = DOMAIN_STANDARD ; } - else if (!strncmp( dimspec, "constant=" , 9 ) || isNum(dimspec[0]) || dimspec[0] == ':' || dimspec[0] == '(' ) + else if (!strncmp( dimspec, "constant=" , 9 ) || isNum(dimspec[0]) || dimspec[0] == ':' || dimspec[0] == '*' || dimspec[0] == '(' ) { char *p, *colon, *paren ; - p = (isNum(dimspec[0])||dimspec[0]==':'||dimspec[0]=='(')?dimspec:&(dimspec[9]) ; + p = (isNum(dimspec[0])||dimspec[0]==':'||dimspec[0]=='*'||dimspec[0]=='(')?dimspec:&(dimspec[9]) ; /* check for colon */ if (( colon = index(p,':')) != NULL ) { @@ -584,6 +623,13 @@ set_dim_len ( char * dimspec , node_t * dim_entry ) } dim_entry->coord_end = atoi(colon+1) ; } + else if ((colon = index(p, '*')) != NULL) + { + *colon = '\0'; + dim_entry->deferred = 1; + dim_entry->coord_end = atoi(colon + 1); + dim_entry->is_pointer = 1; + } else { dim_entry->coord_start = 1 ; diff --git a/modules/openfast-registry/src/type.c b/modules/openfast-registry/src/type.c index 310d7b793..5c3f19ace 100644 --- a/modules/openfast-registry/src/type.c +++ b/modules/openfast-registry/src/type.c @@ -137,7 +137,9 @@ assoc_or_allocated( node_t * r ) int is_pointer( node_t * r ) { - + if (r->ndims > 0 && r->dims[0]->is_pointer) { + return(1); + } if ( sw_ccode && r->ndims > 0 && r->dims[0]->deferred ){ if ( !strncmp( make_lower_temp(r-> name), "writeoutput", 11) ) { // this covers WriteOutput, WriteOutputHdr, and WriteOutputUnt return( 0 ); // we're going to use these in the glue code, so these will be a special case diff --git a/modules/openfoam/CMakeLists.txt b/modules/openfoam/CMakeLists.txt index 7d895a7cf..c92947cce 100644 --- a/modules/openfoam/CMakeLists.txt +++ b/modules/openfoam/CMakeLists.txt @@ -18,24 +18,21 @@ if (GENERATE_TYPES) generate_f90_types(src/OpenFOAM_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/OpenFOAM_Types.f90 -ccode) endif() -# copy the header files to their build location -configure_file(src/OpenFOAM_Types.h ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) +add_library(foamtypeslib src/OpenFOAM_Types.f90) +target_link_libraries(foamtypeslib nwtclibs) -add_library(openfoamtypeslib src/OpenFOAM_Types.f90) -target_link_libraries(openfoamtypeslib nwtclibs) - -add_library(foamfastlib - src/OpenFOAM.f90 +add_library(foamfastlib src/OpenFOAM.f90) +target_link_libraries(foamfastlib openfast_prelib) +target_include_directories(foamfastlib PUBLIC + $ ) -target_link_libraries(foamfastlib openfoamtypeslib openfast_prelib nwtclibs) +set_target_properties(foamfastlib PROPERTIES PUBLIC_HEADER src/OpenFOAM_Types.h) -install(TARGETS openfoamtypeslib foamfastlib +install(TARGETS foamtypeslib foamfastlib EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) - -install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/OpenFOAM_Types.h - DESTINATION include + PUBLIC_HEADER DESTINATION include ) + diff --git a/modules/openfoam/src/OpenFOAM.f90 b/modules/openfoam/src/OpenFOAM.f90 index af7c853dc..dfeae3698 100644 --- a/modules/openfoam/src/OpenFOAM.f90 +++ b/modules/openfoam/src/OpenFOAM.f90 @@ -2,7 +2,7 @@ ! LICENSING ! Copyright (C) 2015 National Renewable Energy Laboratory ! -! Lidar module, a submodule of InflowWind +! OpenFOAM module ! ! Licensed under the Apache License, Version 2.0 (the "License"); ! you may not use this file except in compliance with the License. @@ -17,42 +17,28 @@ ! limitations under the License. ! !********************************************************************************************************************************** +!> This is a pseudo module used to couple OpenFAST with OpenFOAM; it is used to interface to CFD codes including SOWFA, OpenFOAM, and AMR-Wind MODULE OpenFOAM - -! This is a pseudo module used to couple FAST v8 with OpenFOAM; it is considered part of the FAST glue code USE FAST_Types -! USE OpenFOAM_IO IMPLICIT NONE - PRIVATE - TYPE(ProgDesc), PARAMETER :: OpFM_Ver = ProgDesc( 'OpenFOAM Integration', '', '' ) - -! ===================================================================================================" - - ! ..... Public Subroutines ................................................................................................... - PUBLIC :: Init_OpFM ! Initialization routine PUBLIC :: OpFM_SetInputs ! Glue-code routine to update inputs for OpenFOAM PUBLIC :: OpFM_SetWriteOutput - CONTAINS !---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE Init_OpFM( InitInp, p_FAST, AirDens, u_AD14, u_AD, initOut_AD, y_AD, y_ED, OpFM, InitOut, ErrStat, ErrMsg ) -!.................................................................................................................................. - +SUBROUTINE Init_OpFM( InitInp, p_FAST, AirDens, u_AD, initOut_AD, y_AD, OpFM, InitOut, ErrStat, ErrMsg ) TYPE(OpFM_InitInputType), INTENT(IN ) :: InitInp ! Input data for initialization routine TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST ! Parameters for the glue code REAL(ReKi), INTENT(IN ) :: AirDens ! Air Density kg/m^3 - TYPE(AD14_InputType), INTENT(IN ) :: u_AD14 ! AeroDyn14 input data TYPE(AD_InputType), INTENT(IN ) :: u_AD ! AeroDyn input data TYPE(AD_OutputType), INTENT(IN ) :: y_AD ! AeroDyn output data (for mesh mapping) TYPE(AD_InitOutputType), INTENT(IN ) :: initOut_AD ! AeroDyn InitOutput data (for BladeProps) - TYPE(ED_OutputType), INTENT(IN) :: y_ED ! The outputs of the structural dynamics module TYPE(OpenFOAM_Data), INTENT(INOUT) :: OpFM ! data for the OpenFOAM integration module TYPE(OpFM_InitOutputType), INTENT(INOUT) :: InitOut ! Output for initialization routine INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation @@ -71,111 +57,147 @@ SUBROUTINE Init_OpFM( InitInp, p_FAST, AirDens, u_AD14, u_AD, initOut_AD, y_AD, ErrStat = ErrID_None ErrMsg = "" - !............................................................................................ - ! Define parameters here: - !............................................................................................ + ! number of blades + OpFM%p%NumBl = SIZE( u_AD%rotors(1)%BladeMotion, 1 ) + + ! air density, required for normalizing values sent to OpenFOAM: + OpFM%p%AirDens = AirDens + if ( EqualRealNos( AirDens, 0.0_ReKi ) ) & + CALL SetErrStat( ErrID_Fatal, 'Air density cannot be zero for OpenFOAM integration. Check that AeroDyn is used and that air density is set properly', ErrStat,ErrMsg,RoutineName) + IF (ErrStat >= AbortErrLev) RETURN + + + ! The accuracy of the AD15 to CFD coupling is expected to diminish if an insufficient number of AD15 nodes + ! is used. Long term the AD15 nodes will be experted directly, but in the short term we will do a couple + ! quick sanity checks. + ! If the number of nodes requested from CFD (nNodesForceBlade) is more than 4x the number of AD15 blade nodes + ! we expect a lot of innacuracies. The user should increase the number of nodes in AD15 + if (Opfm%p%nNodesForceBlade > 4 * u_AD%rotors(1)%BladeMotion(1)%NNodes) then + ErrMsg2=trim(Num2LStr(Opfm%p%nNodesForceBlade))//' blade points requested from CFD. AD15 only uses ' & + //trim(Num2LStr(u_AD%rotors(1)%BladeMotion(k)%NNodes))//' mesh points. ' & + //'Increase number of AD15 mesh points to at least 50% as many points as the CFD requested.' + call WrScr('OpFM Error: '//trim(ErrMsg2)) + call SetErrStat(ErrID_Fatal, ErrMsg2, ErrStat, ErrMsg, RoutineName) + return + ! if the number of nodes requested from CFD (nNodesForceBlade) is more than double the number of nodes in AD15, issue a warning. + elseif (Opfm%p%nNodesForceBlade > 2 * u_AD%rotors(1)%BladeMotion(1)%NNodes) then + ErrMsg2=trim(Num2LStr(Opfm%p%nNodesForceBlade))//' blade points requested from CFD. AD15 only uses ' & + //trim(Num2LStr(u_AD%rotors(1)%BladeMotion(k)%NNodes))//' mesh points. This may result in inacurate loads.' + call WrScr('OpFM WARNING: '//trim(ErrMsg2)) + call SetErrStat(ErrID_Warn, ErrMsg2, ErrStat, ErrMsg, RoutineName) + endif + + !--------------------------- + ! Motion points from AD15 + !--------------------------- + + ! Hub node (always set) + OpFM%p%nNodesVel = 1 ! Hub is first point always + + ! Blade nodes (always set) + DO k=1,OpFM%p%NumBl + OpFM%p%nNodesVel = OpFM%p%nNodesVel + u_AD%rotors(1)%BladeMotion(k)%NNodes + END DO - ! number of velocity nodes in the interface: + ! Tower motion + OpFM%p%nNodesVel = OpFM%p%nNodesVel + u_AD%rotors(1)%TowerMotion%NNodes - OpFM%p%NnodesVel = 1 ! always want the hub point - IF ( p_FAST%CompAero == Module_AD14 ) THEN ! AeroDyn 14 needs these velocities - CALL SetErrStat(ErrID_Fatal, 'Error AeroDyn14 is not supported yet with different number of velocity and force actuator nodes', ErrStat, ErrMsg, RoutineName) - RETURN - ELSEIF ( p_FAST%CompAero == Module_AD ) THEN ! AeroDyn 15 needs these velocities - OpFM%p%NumBl = SIZE( u_AD%rotors(1)%BladeMotion, 1 ) + ! Nacelle motion + if (u_AD%rotors(1)%HubMotion%NNodes > 0) then + OpFM%p%nNodesVel = OpFM%p%nNodesVel + u_AD%rotors(1)%HubMotion%NNodes + endif - OpFM%p%NnodesVel = OpFM%p%NnodesVel + y_AD%rotors(1)%TowerLoad%NNodes ! tower nodes (if any) - DO k=1,OpFM%p%NumBl - OpFM%p%NnodesVel = OpFM%p%NnodesVel + u_AD%rotors(1)%BladeMotion(k)%NNodes ! blade nodes - END DO - END IF + ! Tail fin nodes + if (u_AD%rotors(1)%TFinMotion%NNodes > 0) then + OpFM%p%nNodesVel = OpFM%p%nNodesVel + u_AD%rotors(1)%TFinMotion%NNodes + endif - ! number of force nodes in the interface - Opfm%p%NnodesForceBlade = InitInp%NumActForcePtsBlade - OpFM%p%NnodesForceTower = InitInp%NumActForcePtsTower - OpFM%p%NnodesForce = 1 + OpFM%p%NumBl * InitInp%NumActForcePtsBlade + + !--------------------------- + ! number of force actuator points from CFD. + !--------------------------- + Opfm%p%nNodesForceBlade = InitInp%NumActForcePtsBlade ! from extern CFD + OpFM%p%nNodesForceTower = InitInp%NumActForcePtsTower ! from extern CFD + + ! Hub + blades + OpFM%p%nNodesForce = 1 + OpFM%p%NumBl * Opfm%p%nNodesForceBlade ! +1 for hub OpFM%p%BladeLength = InitInp%BladeLength - if ( y_AD%rotors(1)%TowerLoad%NNodes > 0 ) then + ! Tower motion + if ( (u_AD%rotors(1)%TowerMotion%NNodes > 0) .and. (OpFM%p%nNodesForceTower > 0) ) then OpFM%p%NMappings = OpFM%p%NumBl + 1 OpFM%p%TowerHeight = InitInp%TowerHeight OpFM%p%TowerBaseHeight = InitInp%TowerBaseHeight - OpFM%p%NnodesForce = OpFM%p%NnodesForce + InitInp%NumActForcePtsTower + OpFM%p%nNodesForce = OpFM%p%nNodesForce + OpFM%p%nNodesForceTower else OpFM%p%NMappings = OpFM%p%NumBl end if - ! air density, required for normalizing values sent to OpenFOAM: - OpFM%p%AirDens = AirDens - if ( EqualRealNos( AirDens, 0.0_ReKi ) ) & - CALL SetErrStat( ErrID_Fatal, 'Air density cannot be zero for OpenFOAM integration. Check that AeroDyn is used and that air density is set properly', ErrStat,ErrMsg,RoutineName) + ! FIXME: we are missing the nacelle and tail fin nodes. Add these sometime (may require changes in CFD) !............................................................................................ ! Allocate arrays and define initial guesses for the OpenFOAM inputs here: !............................................................................................ - CALL AllocPAry( OpFM%u%pxVel, OpFM%p%NnodesVel, 'pxVel', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%pyVel, OpFM%p%NnodesVel, 'pyVel', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%pzVel, OpFM%p%NnodesVel, 'pzVel', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%pxForce, OpFM%p%NnodesForce, 'pxForce', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%pyForce, OpFM%p%NnodesForce, 'pyForce', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%pzForce, OpFM%p%NnodesForce, 'pzForce', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%xdotForce, OpFM%p%NnodesForce, 'xdotForce', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%ydotForce, OpFM%p%NnodesForce, 'ydotForce', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%zdotForce, OpFM%p%NnodesForce, 'zdotForce', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%pOrientation, 3*3*OpFM%p%NnodesForce, 'pOrientation', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%fx, OpFM%p%NnodesForce, 'fx', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%fy, OpFM%p%NnodesForce, 'fy', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%fz, OpFM%p%NnodesForce, 'fz', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%momentx, OpFM%p%NnodesForce, 'momentx', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%momenty, OpFM%p%NnodesForce, 'momenty', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%momentz, OpFM%p%NnodesForce, 'momentz', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%u%forceNodesChord, OpFM%p%NnodesForce, 'forceNodesChord', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - IF (ErrStat >= AbortErrLev) RETURN - - ! make sure the C versions are synced with these arrays - OpFM%u%c_obj%pxVel_Len = OpFM%p%NnodesVel; OpFM%u%c_obj%pxVel = C_LOC( OpFM%u%pxVel(1) ) - OpFM%u%c_obj%pyVel_Len = OpFM%p%NnodesVel; OpFM%u%c_obj%pyVel = C_LOC( OpFM%u%pyVel(1) ) - OpFM%u%c_obj%pzVel_Len = OpFM%p%NnodesVel; OpFM%u%c_obj%pzVel = C_LOC( OpFM%u%pzVel(1) ) - OpFM%u%c_obj%pxForce_Len = OpFM%p%NnodesForce; OpFM%u%c_obj%pxForce = C_LOC( OpFM%u%pxForce(1) ) - OpFM%u%c_obj%pyForce_Len = OpFM%p%NnodesForce; OpFM%u%c_obj%pyForce = C_LOC( OpFM%u%pyForce(1) ) - OpFM%u%c_obj%pzForce_Len = OpFM%p%NnodesForce; OpFM%u%c_obj%pzForce = C_LOC( OpFM%u%pzForce(1) ) - OpFM%u%c_obj%xdotForce_Len = OpFM%p%NnodesForce; OpFM%u%c_obj%xdotForce = C_LOC( OpFM%u%xdotForce(1) ) - OpFM%u%c_obj%ydotForce_Len = OpFM%p%NnodesForce; OpFM%u%c_obj%ydotForce = C_LOC( OpFM%u%ydotForce(1) ) - OpFM%u%c_obj%zdotForce_Len = OpFM%p%NnodesForce; OpFM%u%c_obj%zdotForce = C_LOC( OpFM%u%zdotForce(1) ) - OpFM%u%c_obj%pOrientation_Len = OpFM%p%NnodesForce*3*3; OpFM%u%c_obj%pOrientation = C_LOC( OpFM%u%pOrientation(1) ) - OpFM%u%c_obj%fx_Len = OpFM%p%NnodesForce; OpFM%u%c_obj%fx = C_LOC( OpFM%u%fx(1) ) - OpFM%u%c_obj%fy_Len = OpFM%p%NnodesForce; OpFM%u%c_obj%fy = C_LOC( OpFM%u%fy(1) ) - OpFM%u%c_obj%fz_Len = OpFM%p%NnodesForce; OpFM%u%c_obj%fz = C_LOC( OpFM%u%fz(1) ) - OpFM%u%c_obj%momentx_Len = OpFM%p%NnodesForce; OpFM%u%c_obj%momentx = C_LOC( OpFM%u%momentx(1) ) - OpFM%u%c_obj%momenty_Len = OpFM%p%NnodesForce; OpFM%u%c_obj%momenty = C_LOC( OpFM%u%momenty(1) ) - OpFM%u%c_obj%momentz_Len = OpFM%p%NnodesForce; OpFM%u%c_obj%momentz = C_LOC( OpFM%u%momentz(1) ) - OpFM%u%c_obj%forceNodesChord_Len = OpFM%p%NnodesForce; OpFM%u%c_obj%forceNodesChord = C_LOC( OpFM%u%forceNodesChord(1) ) + ! Motion points (from AD15) + CALL AllocPAry( OpFM%u%pxVel, OpFM%p%nNodesVel, 'pxVel', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%pyVel, OpFM%p%nNodesVel, 'pyVel', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%pzVel, OpFM%p%nNodesVel, 'pzVel', ErrStat2, ErrMsg2 ); if (Failed()) return; + ! Force actuator points (large number set by CFD) + CALL AllocPAry( OpFM%u%pxForce, OpFM%p%nNodesForce, 'pxForce', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%pyForce, OpFM%p%nNodesForce, 'pyForce', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%pzForce, OpFM%p%nNodesForce, 'pzForce', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%xdotForce, OpFM%p%nNodesForce, 'xdotForce', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%ydotForce, OpFM%p%nNodesForce, 'ydotForce', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%zdotForce, OpFM%p%nNodesForce, 'zdotForce', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%pOrientation,3*3*OpFM%p%nNodesForce, 'pOrientation', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%fx, OpFM%p%nNodesForce, 'fx', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%fy, OpFM%p%nNodesForce, 'fy', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%fz, OpFM%p%nNodesForce, 'fz', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%momentx, OpFM%p%nNodesForce, 'momentx', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%momenty, OpFM%p%nNodesForce, 'momenty', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%momentz, OpFM%p%nNodesForce, 'momentz', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%u%forceNodesChord, OpFM%p%nNodesForce, 'forceNodesChord', ErrStat2, ErrMsg2 ); if (Failed()) return; + + ! make sure the C versions are synced with these arrays: + ! Motion points (from AD15) + OpFM%u%c_obj%pxVel_Len = OpFM%p%nNodesVel; OpFM%u%c_obj%pxVel = C_LOC( OpFM%u%pxVel(1) ) + OpFM%u%c_obj%pyVel_Len = OpFM%p%nNodesVel; OpFM%u%c_obj%pyVel = C_LOC( OpFM%u%pyVel(1) ) + OpFM%u%c_obj%pzVel_Len = OpFM%p%nNodesVel; OpFM%u%c_obj%pzVel = C_LOC( OpFM%u%pzVel(1) ) + ! Force actuator points (large number set by CFD) + OpFM%u%c_obj%pxForce_Len = OpFM%p%nNodesForce; OpFM%u%c_obj%pxForce = C_LOC( OpFM%u%pxForce(1) ) + OpFM%u%c_obj%pyForce_Len = OpFM%p%nNodesForce; OpFM%u%c_obj%pyForce = C_LOC( OpFM%u%pyForce(1) ) + OpFM%u%c_obj%pzForce_Len = OpFM%p%nNodesForce; OpFM%u%c_obj%pzForce = C_LOC( OpFM%u%pzForce(1) ) + OpFM%u%c_obj%xdotForce_Len = OpFM%p%nNodesForce; OpFM%u%c_obj%xdotForce = C_LOC( OpFM%u%xdotForce(1) ) + OpFM%u%c_obj%ydotForce_Len = OpFM%p%nNodesForce; OpFM%u%c_obj%ydotForce = C_LOC( OpFM%u%ydotForce(1) ) + OpFM%u%c_obj%zdotForce_Len = OpFM%p%nNodesForce; OpFM%u%c_obj%zdotForce = C_LOC( OpFM%u%zdotForce(1) ) + OpFM%u%c_obj%pOrientation_Len = OpFM%p%nNodesForce*3*3; OpFM%u%c_obj%pOrientation = C_LOC( OpFM%u%pOrientation(1) ) + OpFM%u%c_obj%fx_Len = OpFM%p%nNodesForce; OpFM%u%c_obj%fx = C_LOC( OpFM%u%fx(1) ) + OpFM%u%c_obj%fy_Len = OpFM%p%nNodesForce; OpFM%u%c_obj%fy = C_LOC( OpFM%u%fy(1) ) + OpFM%u%c_obj%fz_Len = OpFM%p%nNodesForce; OpFM%u%c_obj%fz = C_LOC( OpFM%u%fz(1) ) + OpFM%u%c_obj%momentx_Len = OpFM%p%nNodesForce; OpFM%u%c_obj%momentx = C_LOC( OpFM%u%momentx(1) ) + OpFM%u%c_obj%momenty_Len = OpFM%p%nNodesForce; OpFM%u%c_obj%momenty = C_LOC( OpFM%u%momenty(1) ) + OpFM%u%c_obj%momentz_Len = OpFM%p%nNodesForce; OpFM%u%c_obj%momentz = C_LOC( OpFM%u%momentz(1) ) + OpFM%u%c_obj%forceNodesChord_Len = OpFM%p%nNodesForce; OpFM%u%c_obj%forceNodesChord = C_LOC( OpFM%u%forceNodesChord(1) ) ! initialize the arrays: - call OpFM_CreateActForceBladeTowerNodes(OpFM%p, ErrStat2, ErrMsg2) !Creates the blade and tower nodes in radial and tower height co-ordinates - call OpFM_InterpolateForceNodesChord(initOut_AD, OpFM%p, OpFM%u, ErrStat2, ErrMsg2) !Interpolates the chord distribution to the force nodes - call OpFM_CreateActForceMotionsMesh( p_FAST, y_ED, InitInp, OpFM, ErrStat2, ErrMsg2) + !----------------------- + OpFM%p%NodeClusterType = InitInp%NodeClusterType + ! Create the blade and tower nodes in radial and tower height co-ordinates + call OpFM_CreateActForceBladeTowerNodes(initOut_AD, OpFM%p, OpFM%u, ErrStat2, ErrMsg2); if (Failed()) return; + ! Interpolates the chord distribution to the force nodes + call OpFM_InterpolateForceNodesChord(initOut_AD, OpFM%p, OpFM%u, ErrStat2, ErrMsg2); if (Failed()) return; + ! create actuator point motion mesh + call OpFM_CreateActForceMotionsMesh( p_FAST, u_AD, InitInp, OpFM, ErrStat2, ErrMsg2); if (Failed()) return; !............................................................................................ - ! Allocate arrays and set up mappings to point loads (for AD15 only): + ! Allocate arrays and set up mappings to point loads (for AD15 only): ! (bjj: note that normally I'd put these things in the FAST_ModuleMapType, but I don't want ! to add OpenFOAM integrations in the rest fo the code). !............................................................................................ ! Allocate space for mapping data structures - ALLOCATE( OpFM%m%ActForceLoads(OpFM%p%NMappings), OpFM%m%Line2_to_Line2_Loads(OpFM%p%NMappings), OpFM%m%Line2_to_Line2_Motions(OpFM%p%NMappings),STAT=ErrStat2) - ALLOCATE( OpFM%m%ActForceLoadsPoints(OpFM%p%NMappings), OpFM%m%Line2_to_Point_Loads(OpFM%p%NMappings), OpFM%m%Line2_to_Point_Motions(OpFM%p%NMappings),STAT=ErrStat2) + ALLOCATE( OpFM%m%ActForceLoadsPoints(OpFM%p%NMappings), OpFM%m%Line2_to_Point_Loads(OpFM%p%NMappings), OpFM%m%Line2_to_Point_Motions(OpFM%p%NMappings),STAT=ErrStat2); if (Failed2()) return; do k=1,OpFM%p%NMappings - call MeshCopy ( SrcMesh = OpFM%m%ActForceMotions(k) & - , DestMesh = OpFM%m%ActForceLoads(k) & - , CtrlCode = MESH_SIBLING & - , IOS = COMPONENT_OUTPUT & - , Force = .true. & - , Moment = .true. & - , ErrStat = ErrStat2 & - , ErrMess = ErrMsg2 ) - OpFM%m%ActForceLoads(k)%RemapFlag = .true. call MeshCopy ( SrcMesh = OpFM%m%ActForceMotionsPoints(k) & , DestMesh = OpFM%m%ActForceLoadsPoints(k) & , CtrlCode = MESH_SIBLING & @@ -184,66 +206,49 @@ SUBROUTINE Init_OpFM( InitInp, p_FAST, AirDens, u_AD14, u_AD, initOut_AD, y_AD, , Moment = .true. & , ErrStat = ErrStat2 & , ErrMess = ErrMsg2 ) + if (Failed()) return; OpFM%m%ActForceLoadsPoints(k)%RemapFlag = .true. end do - - ! create the mapping data structures: - DO k=1,OpFM%p%NumBl - IF (p_FAST%CompElast == Module_ED ) THEN - call MeshMapCreate( y_ED%BladeLn2Mesh(k), OpFM%m%ActForceMotions(k), OpFM%m%Line2_to_Line2_Motions(k), ErrStat2, ErrMsg2 ); - ELSEIF (p_FAST%CompElast == Module_BD ) THEN - ! call MeshMapCreate( BD%y(k)%BldMotion, OpFM%m%ActForceMotions(k), OpFM%m%Line2_to_Line2_Motions(k), ErrStat2, ErrMsg2 ); - END IF - call MeshMapCreate( y_AD%rotors(1)%BladeLoad(k), OpFM%m%ActForceLoads(k), OpFM%m%Line2_to_Line2_Loads(k), ErrStat2, ErrMsg2 ); - call MeshMapCreate( OpFM%m%ActForceMotions(k), OpFM%m%ActForceMotionsPoints(k), OpFM%m%Line2_to_Point_Motions(k), ErrStat2, ErrMsg2 ); - call MeshMapCreate( OpFM%m%ActForceLoads(k), OpFM%m%ActForceLoadsPoints(k), OpFM%m%Line2_to_Point_Loads(k), ErrStat2, ErrMsg2 ); -! OpFM%m%ActForceLoads(k)%RemapFlag = .false. + ! Mapping of meshes for blades + DO k=1,OpFM%p%NumBl + call MeshMapCreate( u_AD%rotors(1)%BladeMotion(k), OpFM%m%ActForceMotionsPoints(k), OpFM%m%Line2_to_Point_Motions(k), ErrStat2, ErrMsg2 ); if (Failed()) return; + call MeshMapCreate( y_AD%rotors(1)%BladeLoad(k), OpFM%m%ActForceLoadsPoints(k), OpFM%m%Line2_to_Point_Loads(k), ErrStat2, ErrMsg2 ); if (Failed()) return; END DO - + + ! Mapping tower do k=OpFM%p%NumBl+1,OpFM%p%NMappings - call MeshMapCreate( y_ED%TowerLn2Mesh, OpFM%m%ActForceMotions(k), OpFM%m%Line2_to_Line2_Motions(k), ErrStat2, ErrMsg2 ); - call MeshMapCreate( OpFM%m%ActForceMotions(k), OpFM%m%ActForceMotionsPoints(k), OpFM%m%Line2_to_Point_Motions(k), ErrStat2, ErrMsg2 ); - + call MeshMapCreate( u_AD%rotors(1)%TowerMotion, OpFM%m%ActForceMotionsPoints(k), OpFM%m%Line2_to_Point_Motions(k), ErrStat2, ErrMsg2 ); if (Failed()) return; + if ( y_AD%rotors(1)%TowerLoad%nnodes > 0 ) then ! we can have an input mesh on the tower without having an output mesh. - call MeshMapCreate( y_AD%rotors(1)%TowerLoad, OpFM%m%ActForceLoads(k), OpFM%m%Line2_to_Line2_Loads(k), ErrStat2, ErrMsg2 ); - call MeshMapCreate( OpFM%m%ActForceLoads(k), OpFM%m%ActForceLoadsPoints(k), OpFM%m%Line2_to_Point_Loads(k), ErrStat2, ErrMsg2 ); -! OpFM%m%ActForceLoads(k)%RemapFlag = .false. + call MeshMapCreate( y_AD%rotors(1)%TowerLoad, OpFM%m%ActForceLoadsPoints(k), OpFM%m%Line2_to_Point_Loads(k), ErrStat2, ErrMsg2 ); if (Failed()) return; end if - end do - - call SetOpFMPositions(p_FAST, u_AD14, u_AD, y_ED, OpFM) + + call SetOpFMPositions(p_FAST, u_AD, OpFM, ErrStat2, ErrMsg2); if (Failed()) return; OpFM%u%fx = 0.0_ReKi OpFM%u%fy = 0.0_ReKi OpFM%u%fz = 0.0_ReKi - + !............................................................................................ ! Define system output initializations (set up mesh) here: !............................................................................................ - CALL AllocPAry( OpFM%y%u, OpFM%p%NnodesVel, 'u', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%y%v, OpFM%p%NnodesVel, 'v', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - CALL AllocPAry( OpFM%y%w, OpFM%p%NnodesVel, 'w', ErrStat2, ErrMsg2 ); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - IF (ErrStat >= AbortErrLev) RETURN + CALL AllocPAry( OpFM%y%u, OpFM%p%nNodesVel, 'u', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%y%v, OpFM%p%nNodesVel, 'v', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocPAry( OpFM%y%w, OpFM%p%nNodesVel, 'w', ErrStat2, ErrMsg2 ); if (Failed()) return; ! make sure the C versions are synced with these arrays - OpFM%y%c_obj%u_Len = OpFM%p%NnodesVel; OpFM%y%c_obj%u = C_LOC( OpFM%y%u(1) ) - OpFM%y%c_obj%v_Len = OpFM%p%NnodesVel; OpFM%y%c_obj%v = C_LOC( OpFM%y%v(1) ) - OpFM%y%c_obj%w_Len = OpFM%p%NnodesVel; OpFM%y%c_obj%w = C_LOC( OpFM%y%w(1) ) + OpFM%y%c_obj%u_Len = OpFM%p%nNodesVel; OpFM%y%c_obj%u = C_LOC( OpFM%y%u(1) ) + OpFM%y%c_obj%v_Len = OpFM%p%nNodesVel; OpFM%y%c_obj%v = C_LOC( OpFM%y%v(1) ) + OpFM%y%c_obj%w_Len = OpFM%p%nNodesVel; OpFM%y%c_obj%w = C_LOC( OpFM%y%w(1) ) !............................................................................................ ! Define initialization-routine output (including writeOutput array) here: !............................................................................................ - - CALL AllocAry( InitOut%WriteOutputHdr, 3, 'WriteOutputHdr', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( InitOut%WriteOutputUnt, 3, 'WriteOutputUnt', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - CALL AllocAry( OpFM%y%WriteOutput, 3, 'WriteOutput', ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - IF (ErrStat >= AbortErrLev) RETURN + CALL AllocAry( InitOut%WriteOutputHdr, 3, 'WriteOutputHdr', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocAry( InitOut%WriteOutputUnt, 3, 'WriteOutputUnt', ErrStat2, ErrMsg2 ); if (Failed()) return; + CALL AllocAry( OpFM%y%WriteOutput, 3, 'WriteOutput', ErrStat2, ErrMsg2 ); if (Failed()) return; InitOut%WriteOutputHdr(1) = 'Wind1VelX'; InitOut%WriteOutputUnt(1) = '(m/s)' InitOut%WriteOutputHdr(2) = 'Wind1VelY'; InitOut%WriteOutputUnt(2) = '(m/s)' @@ -253,19 +258,26 @@ SUBROUTINE Init_OpFM( InitInp, p_FAST, AirDens, u_AD14, u_AD, initOut_AD, y_AD, InitOut%Ver = OpFM_Ver RETURN - +contains + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + end function Failed + logical function Failed2() + if (ErrStat2 /= 0_IntKi) then + CALL SetErrStat( ErrID_Fatal, 'Error allocating meshes.', ErrStat, ErrMsg, RoutineName ) + Failed2 = .true. + else + Failed2 = .false. + endif + end function Failed2 END SUBROUTINE Init_OpFM -!---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE OpFM_SetInputs( p_FAST, p_AD14, u_AD14, y_AD14, u_AD, y_AD, y_ED, y_SrvD, OpFM, ErrStat, ErrMsg ) -!.................................................................................................................................. +!---------------------------------------------------------------------------------------------------------------------------------- +SUBROUTINE OpFM_SetInputs( p_FAST, u_AD, y_AD, y_SrvD, OpFM, ErrStat, ErrMsg ) TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST ! Parameters for the glue code - TYPE(AD14_ParameterType), INTENT(IN) :: p_AD14 ! The parameters from AeroDyn14 (for mesh transfer with improperly set meshes) - TYPE(AD14_InputType), INTENT(IN) :: u_AD14 ! The input meshes (already calculated) from AeroDyn14 - TYPE(AD14_OutputType), INTENT(IN) :: y_AD14 ! The output meshes (already calculated) from AeroDyn14 TYPE(AD_InputType), INTENT(IN) :: u_AD ! The input meshes (already calculated) from AeroDyn TYPE(AD_OutputType), INTENT(IN) :: y_AD ! The output meshes (already calculated) from AeroDyn - TYPE(ED_OutputType), INTENT(IN) :: y_ED ! The outputs of the structural dynamics module TYPE(SrvD_OutputType), INTENT(IN) :: y_SrvD ! The outputs of the ServoDyn module (control) TYPE(OpenFOAM_Data), INTENT(INOUT) :: OpFM ! data for the OpenFOAM integration module INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation @@ -274,7 +286,6 @@ SUBROUTINE OpFM_SetInputs( p_FAST, p_AD14, u_AD14, y_AD14, u_AD, y_AD, y_ED, y_S ! local variables INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None - CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_SetInputs' @@ -282,50 +293,51 @@ SUBROUTINE OpFM_SetInputs( p_FAST, p_AD14, u_AD14, y_AD14, u_AD, y_AD, y_ED, y_S ErrMsg = "" ! set the positions - call SetOpFMPositions(p_FAST, u_AD14, u_AD, y_ED, OpFM) + call SetOpFMPositions(p_FAST, u_AD, OpFM, ErrStat2, ErrMsg2) + call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! set the forces - call SetOpFMForces(p_FAST, p_AD14, u_AD14, y_AD14, u_AD, y_AD, y_ED, OpFM, ErrStat2, ErrMsg2) + call SetOpFMForces(p_FAST, u_AD, y_AD, OpFM, ErrStat2, ErrMsg2) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END SUBROUTINE OpFM_SetInputs -!---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE SetOpFMPositions(p_FAST, u_AD14, u_AD, y_ED, OpFM) +!---------------------------------------------------------------------------------------------------------------------------------- +SUBROUTINE SetOpFMPositions(p_FAST, u_AD, OpFM, ErrStat, ErrMsg) TYPE(OpenFOAM_Data), INTENT(INOUT) :: OpFM ! data for the OpenFOAM integration module - TYPE(AD14_InputType), INTENT(IN) :: u_AD14 ! The input meshes (already calculated) from AeroDyn14 TYPE(AD_InputType), INTENT(IN) :: u_AD ! The input meshes (already calculated) from AeroDyn - TYPE(ED_OutputType), INTENT(IN) :: y_ED ! The outputs of the structural dynamics module TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST ! FAST parameter data - + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! Local variables: - INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None INTEGER(IntKi) :: J ! Loops through nodes / elements. INTEGER(IntKi) :: K ! Loops through blades. INTEGER(IntKi) :: Node ! Node number for blade/node on mesh + CHARACTER(*), PARAMETER :: RoutineName = 'SetOpFMPositions' + ErrStat = ErrID_None + ErrMsg = "" ! Do the Velocity (AeroDyn) nodes first !------------------------------------------------------------------------------------------------- - Node = 1 ! displaced hub position - OpFM%u%pxVel(Node) = y_ED%HubPtMotion%Position(1,1) + y_ED%HubPtMotion%TranslationDisp(1,1) - OpFM%u%pyVel(Node) = y_ED%HubPtMotion%Position(2,1) + y_ED%HubPtMotion%TranslationDisp(2,1) - OpFM%u%pzVel(Node) = y_ED%HubPtMotion%Position(3,1) + y_ED%HubPtMotion%TranslationDisp(3,1) + Node = 1 ! displaced hub position + OpFM%u%pxVel(Node) = u_AD%rotors(1)%HubMotion%Position(1,1) + u_AD%rotors(1)%HubMotion%TranslationDisp(1,1) + OpFM%u%pyVel(Node) = u_AD%rotors(1)%HubMotion%Position(2,1) + u_AD%rotors(1)%HubMotion%TranslationDisp(2,1) + OpFM%u%pzVel(Node) = u_AD%rotors(1)%HubMotion%Position(3,1) + u_AD%rotors(1)%HubMotion%TranslationDisp(3,1) + - ! blade nodes DO K = 1,SIZE(u_AD%rotors(1)%BladeMotion) - DO J = 1,u_AD%rotors(1)%BladeMotion(k)%Nnodes - + DO J = 1,u_AD%rotors(1)%BladeMotion(k)%nNodes + Node = Node + 1 OpFM%u%pxVel(Node) = u_AD%rotors(1)%BladeMotion(k)%TranslationDisp(1,j) + u_AD%rotors(1)%BladeMotion(k)%Position(1,j) OpFM%u%pyVel(Node) = u_AD%rotors(1)%BladeMotion(k)%TranslationDisp(2,j) + u_AD%rotors(1)%BladeMotion(k)%Position(2,j) OpFM%u%pzVel(Node) = u_AD%rotors(1)%BladeMotion(k)%TranslationDisp(3,j) + u_AD%rotors(1)%BladeMotion(k)%Position(3,j) - + END DO !J = 1,p%BldNodes ! Loop through the blade nodes / elements END DO !K = 1,p%NumBl @@ -340,102 +352,90 @@ SUBROUTINE SetOpFMPositions(p_FAST, u_AD14, u_AD, y_ED, OpFM) end if ! Do the Actuator Force nodes now - Node = 1 ! displaced hub position + !------------------------------------------------------------------------------------------------- + Node = 1 ! displaced hub position OpFM%u%pxForce(Node) = OpFM%u%pxVel(Node) - OpFM%u%pyForce(Node) = OpFM%u%pyVel(Node) + OpFM%u%pyForce(Node) = OpFM%u%pyVel(Node) OpFM%u%pzForce(Node) = OpFM%u%pzVel(Node) - OpFM%u%pOrientation((Node-1)*9 + 1) = y_ED%HubPtMotion%Orientation(1,1,1) - OpFM%u%pOrientation((Node-1)*9 + 2) = y_ED%HubPtMotion%Orientation(2,1,1) - OpFM%u%pOrientation((Node-1)*9 + 3) = y_ED%HubPtMotion%Orientation(3,1,1) - OpFM%u%pOrientation((Node-1)*9 + 4) = y_ED%HubPtMotion%Orientation(1,2,1) - OpFM%u%pOrientation((Node-1)*9 + 5) = y_ED%HubPtMotion%Orientation(2,2,1) - OpFM%u%pOrientation((Node-1)*9 + 6) = y_ED%HubPtMotion%Orientation(3,2,1) - OpFM%u%pOrientation((Node-1)*9 + 7) = y_ED%HubPtMotion%Orientation(1,3,1) - OpFM%u%pOrientation((Node-1)*9 + 8) = y_ED%HubPtMotion%Orientation(2,3,1) - OpFM%u%pOrientation((Node-1)*9 + 9) = y_ED%HubPtMotion%Orientation(3,3,1) - - + OpFM%u%pOrientation((Node-1)*9 + 1) = u_AD%rotors(1)%HubMotion%Orientation(1,1,1) + OpFM%u%pOrientation((Node-1)*9 + 2) = u_AD%rotors(1)%HubMotion%Orientation(2,1,1) + OpFM%u%pOrientation((Node-1)*9 + 3) = u_AD%rotors(1)%HubMotion%Orientation(3,1,1) + OpFM%u%pOrientation((Node-1)*9 + 4) = u_AD%rotors(1)%HubMotion%Orientation(1,2,1) + OpFM%u%pOrientation((Node-1)*9 + 5) = u_AD%rotors(1)%HubMotion%Orientation(2,2,1) + OpFM%u%pOrientation((Node-1)*9 + 6) = u_AD%rotors(1)%HubMotion%Orientation(3,2,1) + OpFM%u%pOrientation((Node-1)*9 + 7) = u_AD%rotors(1)%HubMotion%Orientation(1,3,1) + OpFM%u%pOrientation((Node-1)*9 + 8) = u_AD%rotors(1)%HubMotion%Orientation(2,3,1) + OpFM%u%pOrientation((Node-1)*9 + 9) = u_AD%rotors(1)%HubMotion%Orientation(3,3,1) + + DO K = 1,OpFM%p%NumBl ! mesh mapping from line2 mesh to point mesh - IF (p_FAST%CompElast == Module_ED ) THEN - call Transfer_Line2_to_Line2( y_ED%BladeLn2Mesh(k), OpFM%m%ActForceMotions(k), OpFM%m%Line2_to_Line2_Motions(k), ErrStat2, ErrMsg2 ) - ELSEIF (p_FAST%CompElast == Module_BD ) THEN - ! call Transfer_Line2_to_Point( BD%y(k)%BldMotion, OpFM%m%ActForceMotions(k), OpFM%m%Line2_to_Line2_Motions(k), ErrStat2, ErrMsg2 ) - END IF - call Transfer_Line2_to_Point( OpFM%m%ActForceMotions(k), OpFM%m%ActForceMotionsPoints(k), OpFM%m%Line2_to_Point_Motions(k), ErrStat2, ErrMsg2 ) - - - DO J = 1, OpFM%p%NnodesForceBlade + call Transfer_Line2_to_Point( u_AD%rotors(1)%BladeMotion(k), OpFM%m%ActForceMotionsPoints(k), OpFM%m%Line2_to_Point_Motions(k), ErrStat2, ErrMsg2 ); if (Failed()) return; + + + DO J = 1, OpFM%p%nNodesForceBlade Node = Node + 1 OpFM%u%pxForce(Node) = OpFM%m%ActForceMotionsPoints(k)%Position(1,J) + OpFM%m%ActForceMotionsPoints(k)%TranslationDisp(1,J) OpFM%u%pyForce(Node) = OpFM%m%ActForceMotionsPoints(k)%Position(2,J) + OpFM%m%ActForceMotionsPoints(k)%TranslationDisp(2,J) OpFM%u%pzForce(Node) = OpFM%m%ActForceMotionsPoints(k)%Position(3,J) + OpFM%m%ActForceMotionsPoints(k)%TranslationDisp(3,J) - OpFM%u%xdotForce(Node) = OpFM%m%ActForceMotionsPoints(k)%TranslationVel(1,J) - OpFM%u%ydotForce(Node) = OpFM%m%ActForceMotionsPoints(k)%TranslationVel(2,J) + OpFM%u%xdotForce(Node) = OpFM%m%ActForceMotionsPoints(k)%TranslationVel(1,J) + OpFM%u%ydotForce(Node) = OpFM%m%ActForceMotionsPoints(k)%TranslationVel(2,J) OpFM%u%zdotForce(Node) = OpFM%m%ActForceMotionsPoints(k)%TranslationVel(3,J) OpFM%u%pOrientation((Node-1)*9 + 1) = OpFM%m%ActForceMotionsPoints(k)%Orientation(1,1,J) - OpFM%u%pOrientation((Node-1)*9 + 2) = OpFM%m%ActForceMotionsPoints(k)%Orientation(2,1,J) + OpFM%u%pOrientation((Node-1)*9 + 2) = OpFM%m%ActForceMotionsPoints(k)%Orientation(2,1,J) OpFM%u%pOrientation((Node-1)*9 + 3) = OpFM%m%ActForceMotionsPoints(k)%Orientation(3,1,J) OpFM%u%pOrientation((Node-1)*9 + 4) = OpFM%m%ActForceMotionsPoints(k)%Orientation(1,2,J) - OpFM%u%pOrientation((Node-1)*9 + 5) = OpFM%m%ActForceMotionsPoints(k)%Orientation(2,2,J) + OpFM%u%pOrientation((Node-1)*9 + 5) = OpFM%m%ActForceMotionsPoints(k)%Orientation(2,2,J) OpFM%u%pOrientation((Node-1)*9 + 6) = OpFM%m%ActForceMotionsPoints(k)%Orientation(3,2,J) OpFM%u%pOrientation((Node-1)*9 + 7) = OpFM%m%ActForceMotionsPoints(k)%Orientation(1,3,J) - OpFM%u%pOrientation((Node-1)*9 + 8) = OpFM%m%ActForceMotionsPoints(k)%Orientation(2,3,J) + OpFM%u%pOrientation((Node-1)*9 + 8) = OpFM%m%ActForceMotionsPoints(k)%Orientation(2,3,J) OpFM%u%pOrientation((Node-1)*9 + 9) = OpFM%m%ActForceMotionsPoints(k)%Orientation(3,3,J) END DO - - END DO - - DO K = OpFM%p%NumBl+1,OpFM%p%NMappings - call Transfer_Line2_to_Line2( y_ED%TowerLn2Mesh, OpFM%m%ActForceMotions(k), OpFM%m%Line2_to_Line2_Motions(k), ErrStat2, ErrMsg2 ) - call Transfer_Line2_to_Point( OpFM%m%ActForceMotions(k), OpFM%m%ActForceMotionsPoints(k), OpFM%m%Line2_to_Point_Motions(k), ErrStat2, ErrMsg2 ) - - DO J=1,OpFM%p%NnodesForceTower - Node = Node + 1 - OpFM%u%pxForce(Node) = OpFM%m%ActForceMotionsPoints(k)%Position(1,J) + OpFM%m%ActForceMotionsPoints(k)%TranslationDisp(1,J) - OpFM%u%pyForce(Node) = OpFM%m%ActForceMotionsPoints(k)%Position(2,J) + OpFM%m%ActForceMotionsPoints(k)%TranslationDisp(2,J) - OpFM%u%pzForce(Node) = OpFM%m%ActForceMotionsPoints(k)%Position(3,J) + OpFM%m%ActForceMotionsPoints(k)%TranslationDisp(3,J) - OpFM%u%pOrientation((Node-1)*9 + 1) = OpFM%m%ActForceMotionsPoints(k)%Orientation(1,1,J) - OpFM%u%pOrientation((Node-1)*9 + 2) = OpFM%m%ActForceMotionsPoints(k)%Orientation(2,1,J) - OpFM%u%pOrientation((Node-1)*9 + 3) = OpFM%m%ActForceMotionsPoints(k)%Orientation(3,1,J) - OpFM%u%pOrientation((Node-1)*9 + 4) = OpFM%m%ActForceMotionsPoints(k)%Orientation(1,2,J) - OpFM%u%pOrientation((Node-1)*9 + 5) = OpFM%m%ActForceMotionsPoints(k)%Orientation(2,2,J) - OpFM%u%pOrientation((Node-1)*9 + 6) = OpFM%m%ActForceMotionsPoints(k)%Orientation(3,2,J) - OpFM%u%pOrientation((Node-1)*9 + 7) = OpFM%m%ActForceMotionsPoints(k)%Orientation(1,3,J) - OpFM%u%pOrientation((Node-1)*9 + 8) = OpFM%m%ActForceMotionsPoints(k)%Orientation(2,3,J) - OpFM%u%pOrientation((Node-1)*9 + 9) = OpFM%m%ActForceMotionsPoints(k)%Orientation(3,3,J) + END DO + if (OpFM%p%NMappings .gt. OpFM%p%NumBl) then + DO K = OpFM%p%NumBl+1,OpFM%p%NMappings + call Transfer_Line2_to_Point( u_AD%rotors(1)%TowerMotion, OpFM%m%ActForceMotionsPoints(k), OpFM%m%Line2_to_Point_Motions(k), ErrStat2, ErrMsg2 ); if (Failed()) return; + + DO J=1,OpFM%p%nNodesForceTower + Node = Node + 1 + OpFM%u%pxForce(Node) = OpFM%m%ActForceMotionsPoints(k)%Position(1,J) + OpFM%m%ActForceMotionsPoints(k)%TranslationDisp(1,J) + OpFM%u%pyForce(Node) = OpFM%m%ActForceMotionsPoints(k)%Position(2,J) + OpFM%m%ActForceMotionsPoints(k)%TranslationDisp(2,J) + OpFM%u%pzForce(Node) = OpFM%m%ActForceMotionsPoints(k)%Position(3,J) + OpFM%m%ActForceMotionsPoints(k)%TranslationDisp(3,J) + OpFM%u%pOrientation((Node-1)*9 + 1) = OpFM%m%ActForceMotionsPoints(k)%Orientation(1,1,J) + OpFM%u%pOrientation((Node-1)*9 + 2) = OpFM%m%ActForceMotionsPoints(k)%Orientation(2,1,J) + OpFM%u%pOrientation((Node-1)*9 + 3) = OpFM%m%ActForceMotionsPoints(k)%Orientation(3,1,J) + OpFM%u%pOrientation((Node-1)*9 + 4) = OpFM%m%ActForceMotionsPoints(k)%Orientation(1,2,J) + OpFM%u%pOrientation((Node-1)*9 + 5) = OpFM%m%ActForceMotionsPoints(k)%Orientation(2,2,J) + OpFM%u%pOrientation((Node-1)*9 + 6) = OpFM%m%ActForceMotionsPoints(k)%Orientation(3,2,J) + OpFM%u%pOrientation((Node-1)*9 + 7) = OpFM%m%ActForceMotionsPoints(k)%Orientation(1,3,J) + OpFM%u%pOrientation((Node-1)*9 + 8) = OpFM%m%ActForceMotionsPoints(k)%Orientation(2,3,J) + OpFM%u%pOrientation((Node-1)*9 + 9) = OpFM%m%ActForceMotionsPoints(k)%Orientation(3,3,J) + END DO END DO - - END DO - + endif +contains + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + end function Failed END SUBROUTINE SetOpFMPositions -!---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE SetOpFMForces(p_FAST, p_AD14, u_AD14, y_AD14, u_AD, y_AD, y_ED, OpFM, ErrStat, ErrMsg) +!---------------------------------------------------------------------------------------------------------------------------------- +SUBROUTINE SetOpFMForces(p_FAST, u_AD, y_AD, OpFM, ErrStat, ErrMsg) TYPE(OpenFOAM_Data), INTENT(INOUT) :: OpFM ! data for the OpenFOAM integration module - TYPE(AD14_ParameterType), INTENT(IN) :: p_AD14 ! The input meshes (already calculated) from AeroDyn14 - TYPE(AD14_InputType), INTENT(IN) :: u_AD14 ! The input meshes (already calculated) from AeroDyn14 - TYPE(AD14_OutputType), INTENT(IN) :: y_AD14 ! The output meshes (already calculated) from AeroDyn14 TYPE(AD_InputType), INTENT(IN) :: u_AD ! The input meshes (already calculated) from AeroDyn TYPE(AD_OutputType), INTENT(IN) :: y_AD ! The output meshes (already calculated) from AeroDyn - TYPE(ED_OutputType), INTENT(IN) :: y_ED ! The outputs of the structural dynamics module TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST ! FAST parameter data - !TYPE(FAST_MiscVarType), INTENT(IN ) :: m_FAST ! misc FAST data, including inputs from external codes like Simulink INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! Local variables: -! REAL(ReKi) :: dRforceNodes ! Uniform distance between two consecutive blade force nodes -! REAL(ReKi) :: dHforceNodes ! Uniform distance between two consecutive tower force nodes - INTEGER(IntKi) :: J ! Loops through nodes / elements INTEGER(IntKi) :: K ! Loops through blades. INTEGER(IntKi) :: Node ! Node number for blade/node on mesh -#ifdef DEBUG_OPENFOAM +#ifdef DEBUG_OPENFOAM INTEGER(IntKi) :: actForcesFile, aerodynForcesFile ! Unit numbers for files containing actuator forces and aerodyn forces #endif INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation @@ -456,10 +456,10 @@ SUBROUTINE SetOpFMForces(p_FAST, p_AD14, u_AD14, y_AD14, u_AD, y_AD, y_ED, OpFM, ! blade nodes !....................... -#ifdef DEBUG_OPENFOAM +#ifdef DEBUG_OPENFOAM CALL GetNewUnit( aerodynForcesFile ) open(unit=aerodynForcesFile,file='fast_aerodyn_velocity_forces.csv') - write(aerodynForcesFile,*) '#x, y, z, fx, fy, fz' + write(aerodynForcesFile,*) '#x, y, z, u, v, w, fx, fy, fz' CALL GetNewUnit( actForcesFile ) open(unit=actForcesFile,file='fast_actuator_forces.csv') @@ -467,17 +467,16 @@ SUBROUTINE SetOpFMForces(p_FAST, p_AD14, u_AD14, y_AD14, u_AD, y_AD, y_ED, OpFM, #endif DO K = 1,OpFM%p%NumBl - -#ifdef DEBUG_OPENFOAM - DO J = 1,u_AD%BladeMotion(k)%NNodes - write(aerodynForcesFile,*) u_AD%BladeMotion(k)%TranslationDisp(1,j) + u_AD%BladeMotion(k)%Position(1,j), ', ', u_AD%BladeMotion(k)%TranslationDisp(2,j) + u_AD%BladeMotion(k)%Position(2,j), ', ', u_AD%BladeMotion(k)%TranslationDisp(3,j) + u_AD%BladeMotion(k)%Position(3,j), ', ', OpFM%y%u(1 + (k-1)*u_AD%BladeMotion(k)%NNodes + j), ', ', OpFM%y%v(1 + (k-1)*u_AD%BladeMotion(k)%NNodes + j), ', ', OpFM%y%w(1 + (k-1)*u_AD%BladeMotion(k)%NNodes + j), ', ', y_AD%rotors(1)%BladeLoad(k)%Force(1,j), ', ', y_AD%rotors(1)%BladeLoad(k)%Force(2,j), ', ', y_AD%rotors(1)%BladeLoad(k)%Force(2,j) + +#ifdef DEBUG_OPENFOAM + DO J = 1,u_AD%rotors(1)%BladeMotion(k)%NNodes + write(aerodynForcesFile,*) u_AD%rotors(1)%BladeMotion(k)%TranslationDisp(1,j) + u_AD%rotors(1)%BladeMotion(k)%Position(1,j), ', ', u_AD%rotors(1)%BladeMotion(k)%TranslationDisp(2,j) + u_AD%rotors(1)%BladeMotion(k)%Position(2,j), ', ', u_AD%rotors(1)%BladeMotion(k)%TranslationDisp(3,j) + u_AD%rotors(1)%BladeMotion(k)%Position(3,j), ', ', OpFM%y%u(1 + (k-1)*u_AD%rotors(1)%BladeMotion(k)%NNodes + j), ', ', OpFM%y%v(1 + (k-1)*u_AD%rotors(1)%BladeMotion(k)%NNodes + j), ', ', OpFM%y%w(1 + (k-1)*u_AD%rotors(1)%BladeMotion(k)%NNodes + j), ', ', y_AD%rotors(1)%BladeLoad(k)%Force(1,j), ', ', y_AD%rotors(1)%BladeLoad(k)%Force(2,j), ', ', y_AD%rotors(1)%BladeLoad(k)%Force(2,j) END DO #endif - call Transfer_Line2_to_Line2( y_AD%rotors(1)%BladeLoad(k), OpFM%m%ActForceLoads(k), OpFM%m%Line2_to_Line2_Loads(k), ErrStat2, ErrMsg2, u_AD%rotors(1)%BladeMotion(k), OpFM%m%ActForceMotions(k) ) - call Transfer_Line2_to_Point( OpFM%m%ActForceLoads(k), OpFM%m%ActForceLoadsPoints(k), OpFM%m%Line2_to_Point_Loads(k), ErrStat2, ErrMsg2, OpFM%m%ActForceMotions(k), OpFM%m%ActForceMotionsPoints(k) ) + call Transfer_Line2_to_Point( y_AD%rotors(1)%BladeLoad(k), OpFM%m%ActForceLoadsPoints(k), OpFM%m%Line2_to_Point_Loads(k), ErrStat2, ErrMsg2, u_AD%rotors(1)%BladeMotion(k), OpFM%m%ActForceMotionsPoints(k) ); if (Failed()) return; - DO J = 1, OpFM%p%NnodesForceBlade + DO J = 1, OpFM%p%nNodesForceBlade Node = Node + 1 OpFM%u%fx(Node) = OpFM%m%ActForceLoadsPoints(k)%Force(1,j) OpFM%u%fy(Node) = OpFM%m%ActForceLoadsPoints(k)%Force(2,j) @@ -486,11 +485,11 @@ SUBROUTINE SetOpFMForces(p_FAST, p_AD14, u_AD14, y_AD14, u_AD, y_AD, y_ED, OpFM, OpFM%u%momenty(Node) = OpFM%m%ActForceLoadsPoints(k)%Moment(2,j) OpFM%u%momentz(Node) = OpFM%m%ActForceLoadsPoints(k)%Moment(3,j) -#ifdef DEBUG_OPENFOAM +#ifdef DEBUG_OPENFOAM write(actForcesFile,*) OpFM%u%pxForce(Node), ', ', OpFM%u%pyForce(Node), ', ', OpFM%u%pzForce(Node), ', ', OpFM%u%fx(Node), ', ', OpFM%u%fy(Node), ', ', OpFM%u%fz(Node), ', ' #endif - END DO + END DO END DO !K = 1,OpFM%p%NumBl @@ -498,44 +497,48 @@ SUBROUTINE SetOpFMForces(p_FAST, p_AD14, u_AD14, y_AD14, u_AD, y_AD, y_ED, OpFM, ! tower nodes !....................... - ! mesh mapping from line2 mesh to point mesh - DO K = OpFM%p%NumBl+1,OpFM%p%NMappings - + if (OpFM%p%NMappings .gt. OpFM%p%NumBl) then + ! mesh mapping from line2 mesh to point mesh + DO K = OpFM%p%NumBl+1,OpFM%p%NMappings #ifdef DEBUG_OPENFOAM - DO J = 1,u_AD%rotors(1)%TowerMotion%NNodes - write(aerodynForcesFile,*) u_AD%rotors(1)%TowerMotion%TranslationDisp(1,j) + u_AD%rotors(1)%TowerMotion%Position(1,j), ', ', u_AD%rotors(1)%TowerMotion%TranslationDisp(2,j) + u_AD%rotors(1)%TowerMotion%Position(2,j), ', ', u_AD%TowerMotion%TranslationDisp(3,j) + u_AD%TowerMotion%Position(3,j), ', ', OpFM%y%u(1 + OpFM%p%NumBl*u_AD%BladeMotion(k)%NNodes + j), ', ', OpFM%y%v(1 + OpFM%p%NumBl*u_AD%BladeMotion(k)%NNodes + j), ', ', OpFM%y%w(1 + OpFM%p%NumBl*u_AD%BladeMotion(k)%NNodes + j), ', ', y_AD%rotors(1)%TowerLoad%Force(1,j), ', ', y_AD%rotors(1)%TowerLoad%Force(2,j), ', ', y_AD%rotors(1)%TowerLoad%Force(2,j) - END DO + DO J = 1,u_AD%rotors(1)%TowerMotion%NNodes + write(aerodynForcesFile,*) u_AD%rotors(1)%TowerMotion%TranslationDisp(1,j) + u_AD%rotors(1)%TowerMotion%Position(1,j), ', ', u_AD%rotors(1)%TowerMotion%TranslationDisp(2,j) + u_AD%rotors(1)%TowerMotion%Position(2,j), ', ', u_AD%rotors(1)%TowerMotion%TranslationDisp(3,j) + u_AD%rotors(1)%TowerMotion%Position(3,j), ', ', OpFM%y%u(1 + OpFM%p%NumBl*u_AD%rotors(1)%BladeMotion(k)%NNodes + j), ', ', OpFM%y%v(1 + OpFM%p%NumBl*u_AD%rotors(1)%BladeMotion(k)%NNodes + j), ', ', OpFM%y%w(1 + OpFM%p%NumBl*u_AD%rotors(1)%BladeMotion(k)%NNodes + j), ', ', y_AD%rotors(1)%TowerLoad%Force(1,j), ', ', y_AD%rotors(1)%TowerLoad%Force(2,j), ', ', y_AD%rotors(1)%TowerLoad%Force(2,j) + END DO #endif - call Transfer_Line2_to_Line2( y_AD%rotors(1)%TowerLoad, OpFM%m%ActForceLoads(k), OpFM%m%Line2_to_Line2_Loads(k), ErrStat2, ErrMsg2, u_AD%rotors(1)%TowerMotion, OpFM%m%ActForceMotions(k) ) - call Transfer_Line2_to_Point( OpFM%m%ActForceLoads(k), OpFM%m%ActForceLoadsPoints(k), OpFM%m%Line2_to_Point_Loads(k), ErrStat2, ErrMsg2, OpFM%m%ActForceMotions(k), OpFM%m%ActForceMotionsPoints(k) ) - - DO J=1,OpFM%p%NnodesForceTower - Node = Node + 1 - OpFM%u%fx(Node) = OpFM%m%ActForceLoadsPoints(k)%Force(1,j) - OpFM%u%fy(Node) = OpFM%m%ActForceLoadsPoints(k)%Force(2,j) - OpFM%u%fz(Node) = OpFM%m%ActForceLoadsPoints(k)%Force(3,j) - OpFM%u%momentx(Node) = OpFM%m%ActForceLoadsPoints(k)%Moment(1,j) - OpFM%u%momenty(Node) = OpFM%m%ActForceLoadsPoints(k)%Moment(2,j) - OpFM%u%momentz(Node) = OpFM%m%ActForceLoadsPoints(k)%Moment(3,j) - -#ifdef DEBUG_OPENFOAM - write(actForcesFile,*) OpFM%u%pxForce(Node), ', ', OpFM%u%pyForce(Node), ', ', OpFM%u%pzForce(Node), ', ', OpFM%u%fx(Node), ', ', OpFM%u%fy(Node), ', ', OpFM%u%fz(Node), ', ' + call Transfer_Line2_to_Point( y_AD%rotors(1)%TowerLoad, OpFM%m%ActForceLoadsPoints(k), OpFM%m%Line2_to_Point_Loads(k), ErrStat2, ErrMsg2, u_AD%rotors(1)%TowerMotion, OpFM%m%ActForceMotionsPoints(k) ); if (Failed()) return; + + DO J=1,OpFM%p%nNodesForceTower + Node = Node + 1 + OpFM%u%fx(Node) = OpFM%m%ActForceLoadsPoints(k)%Force(1,j) + OpFM%u%fy(Node) = OpFM%m%ActForceLoadsPoints(k)%Force(2,j) + OpFM%u%fz(Node) = OpFM%m%ActForceLoadsPoints(k)%Force(3,j) + OpFM%u%momentx(Node) = OpFM%m%ActForceLoadsPoints(k)%Moment(1,j) + OpFM%u%momenty(Node) = OpFM%m%ActForceLoadsPoints(k)%Moment(2,j) + OpFM%u%momentz(Node) = OpFM%m%ActForceLoadsPoints(k)%Moment(3,j) + +#ifdef DEBUG_OPENFOAM + write(actForcesFile,*) OpFM%u%pxForce(Node), ', ', OpFM%u%pyForce(Node), ', ', OpFM%u%pzForce(Node), ', ', OpFM%u%fx(Node), ', ', OpFM%u%fy(Node), ', ', OpFM%u%fz(Node), ', ' #endif - END DO + END DO -#ifdef DEBUG_OPENFOAM - close(aerodynForcesFile) - close(actForcesFile) +#ifdef DEBUG_OPENFOAM + close(aerodynForcesFile) + close(actForcesFile) #endif - END DO + END DO + endif +contains + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + end function Failed END SUBROUTINE SetOpFMForces + !---------------------------------------------------------------------------------------------------------------------------------- SUBROUTINE OpFM_SetWriteOutput( OpFM ) -!.................................................................................................................................. - TYPE(OpenFOAM_Data), INTENT(INOUT) :: OpFM ! data for the OpenFOAM integration module ! set the hub-height wind speeds @@ -547,16 +550,14 @@ SUBROUTINE OpFM_SetWriteOutput( OpFM ) END IF END IF - - END SUBROUTINE OpFM_SetWriteOutput -!---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE OpFM_CreateActForceMotionsMesh( p_FAST, y_ED, InitIn_OpFM, OpFM, ErrStat, ErrMsg ) -!.................................................................................................................................. +!---------------------------------------------------------------------------------------------------------------------------------- +!> Create the actuator line force point mesh +SUBROUTINE OpFM_CreateActForceMotionsMesh( p_FAST, u_AD, InitIn_OpFM, OpFM, ErrStat, ErrMsg ) TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST ! Parameters for the glue code - TYPE(ED_OutputType), INTENT(IN) :: y_ED ! The outputs of the structural dynamics module - TYPE(OpFM_InitInputType), INTENT(IN ) :: InitIn_OpFM ! InitInp data for the OpenFOAM integration module + TYPE(AD_InputType), INTENT(IN) :: u_AD ! The input meshes (already calculated) from AeroDyn + TYPE(OpFM_InitInputType), INTENT(IN ) :: InitIn_OpFM ! InitInp data for the OpenFOAM integration module TYPE(OpenFOAM_Data), INTENT(INOUT) :: OpFM ! data for the OpenFOAM integration module INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None @@ -565,167 +566,107 @@ SUBROUTINE OpFM_CreateActForceMotionsMesh( p_FAST, y_ED, InitIn_OpFM, OpFM, ErrS TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: tmpActForceMotionsMesh !< temporary mesh for interpolating orientation to actuator force points [-] INTEGER(IntKi) :: k ! blade loop counter INTEGER(IntKi) :: j ! node counter - INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None - CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_CreateActForceMotionsMesh' ! Initialize variables - ErrStat = ErrID_None ErrMsg = "" - ! Allocate space for mapping data structures - ALLOCATE(tmpActForceMotionsMesh(OpFM%p%NMappings) , STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating force nodes mesh mapping types', ErrStat, ErrMsg, RoutineName) - RETURN - END IF - CALL OpFM_CreateTmpActForceMotionsMesh( p_FAST, y_ED, OpFM%p, InitIn_OpFM, tmpActForceMotionsMesh, ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - if (errStat >= AbortErrLev) return - - ALLOCATE(OpFM%m%ActForceMotions(OpFM%p%NMappings), STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating force nodes mesh', ErrStat, ErrMsg, RoutineName) - RETURN - END IF - ALLOCATE(OpFM%m%ActForceMotionsPoints(OpFM%p%NMappings), STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating force nodes mesh', ErrStat, ErrMsg, RoutineName) - RETURN - END IF - DO k=1,OpFM%p%NumBl - call MeshCreate ( BlankMesh = OpFM%m%ActForceMotions(k) & - ,IOS = COMPONENT_INPUT & - ,Nnodes = OpFM%p%NnodesForceBlade & - ,Orientation = .true. & - ,TranslationDisp = .true. & - ,TranslationVel = .true. & - ,RotationVel = .true. & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & - ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN - OpFM%m%ActForceMotions(k)%RemapFlag = .false. - - call MeshCreate ( BlankMesh = OpFM%m%ActForceMotionsPoints(k) & - ,IOS = COMPONENT_INPUT & - ,Nnodes = OpFM%p%NnodesForceBlade & - ,Orientation = .true. & - ,TranslationDisp = .true. & - ,TranslationVel = .true. & - ,RotationVel = .true. & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & - ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN - OpFM%m%ActForceMotions(k)%RemapFlag = .false. - - do j=1,OpFM%p%NnodesForceBlade - call MeshPositionNode(OpFM%m%ActForceMotions(k), j, tmpActForceMotionsMesh(k)%position(:,j), errStat2, errMsg2, & - orient=tmpActForceMotionsMesh(k)%Orientation(:,:,j) ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - call MeshPositionNode(OpFM%m%ActForceMotionsPoints(k), j, tmpActForceMotionsMesh(k)%position(:,j), errStat2, errMsg2, & - orient=tmpActForceMotionsMesh(k)%Orientation(:,:,j) ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - call MeshConstructElement(OpFM%m%ActForceMotionsPoints(k), ELEMENT_POINT, errStat2, errMsg2, p1=j ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - end do !j + ! Allocate space for mapping data structures + ALLOCATE(tmpActForceMotionsMesh(OpFM%p%NMappings) , STAT=ErrStat2); if (Failed2()) return; + ALLOCATE(OpFM%m%ActForceMotionsPoints(OpFM%p%NMappings), STAT=ErrStat2); if (Failed2()) return; + ! create a temporary mesh with the correct orientation info (stored in Orientation). This is then stored as the RefOrientation on the real mesh. + ! ADP: this is a clever method @gantech came up with to interpolate orientations from one mesh to a finer mesh. + CALL OpFM_CreateTmpActForceMotionsMesh( p_FAST, u_AD, OpFM%p, InitIn_OpFM, tmpActForceMotionsMesh, ErrStat2, ErrMsg2 ); if (Failed()) return; + + !------- + ! Blades + DO k=1,OpFM%p%NumBl + call MeshCreate ( BlankMesh = OpFM%m%ActForceMotionsPoints(k) & + ,IOS = COMPONENT_INPUT & + ,nNodes = OpFM%p%nNodesForceBlade & + ,Orientation = .true. & + ,TranslationDisp = .true. & + ,TranslationVel = .true. & + ,RotationVel = .true. & + ,ErrStat = ErrStat2 & + ,ErrMess = ErrMsg2 & + ) + if (Failed()) return; + OpFM%m%ActForceMotionsPoints(k)%RemapFlag = .false. + + do j=1,OpFM%p%nNodesForceBlade + ! Use the temp mesh Orientation info as the RefOrientation for this mesh. + call MeshPositionNode(OpFM%m%ActForceMotionsPoints(k), j, tmpActForceMotionsMesh(k)%position(:,j), errStat2, errMsg2, orient=tmpActForceMotionsMesh(k)%Orientation(:,:,j)); if (Failed()) return; + call MeshConstructElement(OpFM%m%ActForceMotionsPoints(k), ELEMENT_POINT, errStat2, errMsg2, p1=j ); if (Failed()) return; + end do !j - ! create elements: - DO J = 2,OpFM%p%NnodesForceBlade - call MeshConstructElement ( Mesh = OpFM%m%ActForceMotions(k) & - , Xelement = ELEMENT_LINE2 & - , P1 = J-1 & ! node1 number - , P2 = J & ! node2 number - , ErrStat = ErrStat2 & - , ErrMess = ErrMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - END DO ! J (blade nodes) - call MeshCommit(OpFM%m%ActForceMotions(k), errStat2, errMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) return - call MeshCommit(OpFM%m%ActForceMotionsPoints(k), errStat2, errMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) return - END DO + call MeshCommit(OpFM%m%ActForceMotionsPoints(k), errStat2, errMsg2 ); if (Failed()) return; + END DO - DO k=OpFM%p%NumBl+1,OpFM%p%NMappings !Tower if present - call MeshCreate ( BlankMesh = OpFM%m%ActForceMotions(k) & - ,IOS = COMPONENT_INPUT & - ,Nnodes = OpFM%p%NnodesForceTower & - ,Orientation = .true. & - ,TranslationDisp = .true. & - ,TranslationVel = .true. & - ,RotationVel = .true. & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & - ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN - OpFM%m%ActForceMotions(k)%RemapFlag = .false. - - call MeshCreate ( BlankMesh = OpFM%m%ActForceMotionsPoints(k) & - ,IOS = COMPONENT_INPUT & - ,Nnodes = OpFM%p%NnodesForceTower & - ,Orientation = .true. & - ,TranslationDisp = .true. & - ,TranslationVel = .true. & - ,RotationVel = .true. & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & + !------ + ! Tower + if (OpFM%p%NMappings .gt. OpFM%p%NumBl) then + DO k=OpFM%p%NumBl+1,OpFM%p%NMappings + call MeshCreate ( BlankMesh = OpFM%m%ActForceMotionsPoints(k) & + ,IOS = COMPONENT_INPUT & + ,nNodes = OpFM%p%nNodesForceTower & + ,Orientation = .true. & + ,TranslationDisp = .true. & + ,TranslationVel = .true. & + ,RotationVel = .true. & + ,ErrStat = ErrStat2 & + ,ErrMess = ErrMsg2 & ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN - OpFM%m%ActForceMotionsPoints(k)%RemapFlag = .false. - - do j=1,OpFM%p%NnodesForceTower - call MeshPositionNode(OpFM%m%ActForceMotions(k), j, tmpActForceMotionsMesh(k)%position(:,j), errStat2, errMsg2, & - orient=tmpActForceMotionsMesh(k)%Orientation(:,:,j) ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - call MeshPositionNode(OpFM%m%ActForceMotionsPoints(k), j, tmpActForceMotionsMesh(k)%position(:,j), errStat2, errMsg2, & - orient=tmpActForceMotionsMesh(k)%Orientation(:,:,j) ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - call MeshConstructElement(OpFM%m%ActForceMotionsPoints(k), ELEMENT_POINT, errStat2, errMsg2, p1=j ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + if (Failed()) return; + OpFM%m%ActForceMotionsPoints(k)%RemapFlag = .false. + + do j=1,OpFM%p%nNodesForceTower + call MeshPositionNode(OpFM%m%ActForceMotionsPoints(k), j, tmpActForceMotionsMesh(k)%position(:,j), errStat2, errMsg2, orient=tmpActForceMotionsMesh(k)%Orientation(:,:,j)); if (Failed()) return; + call MeshConstructElement(OpFM%m%ActForceMotionsPoints(k), ELEMENT_POINT, errStat2, errMsg2, p1=j); if (Failed()) return; end do !j - ! create elements: - DO J = 2,OpFM%p%NnodesForceTower - call MeshConstructElement ( Mesh = OpFM%m%ActForceMotions(k) & - , Xelement = ELEMENT_LINE2 & - , P1 = J-1 & ! node1 number - , P2 = J & ! node2 number - , ErrStat = ErrStat2 & - , ErrMess = ErrMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - END DO ! J (tower nodes) - - call MeshCommit(OpFM%m%ActForceMotions(k), errStat2, errMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) return - call MeshCommit(OpFM%m%ActForceMotionsPoints(k), errStat2, errMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) return + call MeshCommit(OpFM%m%ActForceMotionsPoints(k), errStat2, errMsg2 ); if (Failed()) return; END DO + endif - DO k=1,OpFM%p%NMappings - call MeshDestroy ( tmpActForceMotionsMesh(k), ErrStat2, ErrMsg2 ) - END DO - DEALLOCATE(tmpActForceMotionsMesh) + call Cleanup() + return +contains + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + if (Failed) call Cleanup() + end function Failed + subroutine Cleanup() + ! NOTE: don't trap errors here + if (allocated(tmpActForceMotionsMesh)) then + do k=1,OpFM%p%NMappings + call MeshDestroy ( tmpActForceMotionsMesh(k), ErrStat2, ErrMsg2 ) + end do + deallocate(tmpActForceMotionsMesh) + endif + end subroutine Cleanup + logical function Failed2() + if (ErrStat2 /= 0_IntKi) then + CALL SetErrStat( ErrID_Fatal, 'Error allocating meshes.', ErrStat, ErrMsg, RoutineName ) + Failed2 = .true. + call Cleanup() + else + Failed2 = .false. + endif + end function Failed2 END SUBROUTINE OpFM_CreateActForceMotionsMesh -!---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE OpFM_CreateTmpActForceMotionsMesh( p_FAST, y_ED, p_OpFM, InitIn_OpFM, tmpActForceMotions, ErrStat, ErrMsg ) -!.................................................................................................................................. +!---------------------------------------------------------------------------------------------------------------------------------- +!> this routine is used to create a temporary mesh with the number of points requested by CFD using the AD15 blade definition. This +!! mesh is then used as an intermediate to interpolate the AD15 orientations over using mesh mapping. This routine only exists to +!! facilitate the orientation calculations. +SUBROUTINE OpFM_CreateTmpActForceMotionsMesh( p_FAST, u_AD, p_OpFM, InitIn_OpFM, tmpActForceMotions, ErrStat, ErrMsg ) TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST ! Parameters for the glue code - TYPE(ED_OutputType), INTENT(IN ) :: y_ED ! The outputs of the structural dynamics module + TYPE(AD_InputType), INTENT(IN) :: u_AD ! The input meshes (already calculated) from AeroDyn TYPE(OpFM_ParameterType), INTENT(IN ) :: p_OpFM ! data for the OpenFOAM integration module TYPE(OpFM_InitInputType), INTENT(IN ) :: InitIn_OpFM ! InitInp data for the OpenFOAM integration module TYPE(MeshType), INTENT(INOUT) :: tmpActForceMotions(:) ! temporary mesh to create the actuator force nodes @@ -733,413 +674,507 @@ SUBROUTINE OpFM_CreateTmpActForceMotionsMesh( p_FAST, y_ED, p_OpFM, InitIn_OpFM, CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None ! local variables - TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: tmp_line2_to_point_Motions !< mapping data structure to convert orientation of structural nodes to actuator force nodes [-] - TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: tmp_StructModelMesh !< temporary mesh copying Structural model mesh - REAL(ReKi), DIMENSION(:,:), ALLOCATABLE :: forceNodePositions ! new positions for the force actuator nodes + TYPE(MeshMapType), DIMENSION(:), ALLOCATABLE :: tmp_line2_to_point_Motions !< mapping data structure to convert orientation of structural nodes to actuator force nodes [-] + TYPE(MeshType), DIMENSION(:), ALLOCATABLE :: tmp_StructModelMesh !< temporary mesh copying Structural model mesh + REAL(ReKi), DIMENSION(:,:), ALLOCATABLE :: forceNodePositions ! new positions for the force actuator nodes INTEGER(IntKi) :: NumBl ! number of blades INTEGER(IntKi) :: k ! blade loop counter INTEGER(IntKi) :: j ! node counter - INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None - CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_CreateTmpActForceMotionsMesh' ! Initialize variables - ErrStat = ErrID_None ErrMsg = "" ! Make a copy of the Structural model mesh with the reference orientation set to zero - ALLOCATE(tmp_StructModelMesh(p_OpFM%NMappings) , STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating temporary copy of ElastoDyn mesh type', ErrStat, ErrMsg, RoutineName) - RETURN - END IF - CALL CreateTmpStructModelMesh(p_FAST, y_ED, p_OpFM, tmp_StructModelMesh, ErrStat2, ErrMsg2 ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN - + ALLOCATE(tmp_StructModelMesh(p_OpFM%NMappings) , STAT=ErrStat2); if (Failed2()) return; + CALL CreateTmpStructModelMesh(p_FAST, u_AD, p_OpFM, tmp_StructModelMesh, ErrStat2, ErrMsg2 ); if (Failed()) return; + ! Allocate space for mapping data structures - ALLOCATE( tmp_line2_to_point_Motions(p_OpFM%NMappings),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating temporary actuator force mesh mapping types', ErrStat, ErrMsg, RoutineName) - RETURN - END IF + ALLOCATE( tmp_line2_to_point_Motions(p_OpFM%NMappings),STAT=ErrStat2); if (Failed2()) return; - ! create meshes to map: - ALLOCATE(forceNodePositions(3,p_OpFM%NnodesForceBlade)) ! Allocate space to create new positions + ! Blade nodes + call AllocAry(forceNodePositions, 3, p_OpFM%nNodesForceBlade, "forceNodePositions", ErrStat2, ErrMsg2); if (Failed()) return; DO k=1,p_OpFM%NumBl - call MeshCreate ( BlankMesh = tmpActForceMotions(k) & - ,IOS = COMPONENT_INPUT & - ,Nnodes = p_OpFM%NnodesForceBlade & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & - ,force = .false. & - ,moment = .false. & - ,orientation = .true. & - ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN - + call MeshCreate ( BlankMesh = tmpActForceMotions(k) & + , IOS = COMPONENT_INPUT & + , nNodes = p_OpFM%nNodesForceBlade & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 & + , force = .false. & + , moment = .false. & + , orientation = .true. & + ) + if (Failed()) return; + tmpActForceMotions(k)%RemapFlag = .false. - call CalcForceActuatorPositionsBlade(InitIn_OpFM, p_OpFM, tmp_StructModelMesh(k)%position, forceNodePositions, errStat2, errMsg2) - do j=1,p_OpFM%NnodesForceBlade - call MeshPositionNode(tmpActForceMotions(k), j, forceNodePositions(:,j), errStat2, errMsg2) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - call MeshConstructElement( tmpActForceMotions(k), ELEMENT_POINT, errStat2, errMsg2, p1=j ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + call CalcForceActuatorPositionsBlade(InitIn_OpFM, p_OpFM, tmp_StructModelMesh(k)%position, forceNodePositions, errStat2, errMsg2); if (Failed()) return; + do j=1,p_OpFM%nNodesForceBlade + call MeshPositionNode(tmpActForceMotions(k), j, forceNodePositions(:,j), errStat2, errMsg2); if (Failed()) return; + call MeshConstructElement( tmpActForceMotions(k), ELEMENT_POINT, errStat2, errMsg2, p1=j ); if (Failed()) return; end do !j - + call MeshCommit(tmpActForceMotions(k), errStat2, errMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) if (errStat >= AbortErrLev) return end do - DEALLOCATE(forceNodePositions) ! Free space - - ALLOCATE(forceNodePositions(3,p_OpFM%NnodesForceTower)) ! Allocate space to create new positions - DO k=p_OpFM%NumBl+1,p_OpFM%NMappings - call CalcForceActuatorPositionsTower(InitIn_OpFM, p_OpFM, tmp_StructModelMesh(k)%position, forceNodePositions, errStat2, errMsg2) - - call MeshCreate ( BlankMesh = tmpActForceMotions(k) & - ,IOS = COMPONENT_INPUT & - ,Nnodes = p_OpFM%NnodesForceTower & - ,ErrStat = ErrStat2 & - ,ErrMess = ErrMsg2 & - ,force = .false. & - ,moment = .false. & - ,orientation = .true. & - ) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - IF (ErrStat >= AbortErrLev) RETURN + if (allocated(forceNodePositions)) deallocate(forceNodePositions) ! Free space + + ! Tower nodes + if (p_OpFM%NMappings .gt. p_OpFM%NumBl) then + call AllocAry(forceNodePositions, 3, p_OpFM%nNodesForceTower, "forceNodePositions", ErrStat2, ErrMsg2); if (Failed()) return; + DO k=p_OpFM%NumBl+1,p_OpFM%NMappings + call CalcForceActuatorPositionsTower(InitIn_OpFM, p_OpFM, tmp_StructModelMesh(k)%position, forceNodePositions, errStat2, errMsg2); if (Failed()) return; + + call MeshCreate ( BlankMesh = tmpActForceMotions(k) & + ,IOS = COMPONENT_INPUT & + ,nNodes = p_OpFM%nNodesForceTower & + ,ErrStat = ErrStat2 & + ,ErrMess = ErrMsg2 & + ,force = .false. & + ,moment = .false. & + ,orientation = .true. & + ) + if (Failed()) return; + + tmpActForceMotions(k)%RemapFlag = .false. + do j=1,p_OpFM%nNodesForceTower + call MeshPositionNode(tmpActForceMotions(k), j, forceNodePositions(:,j), errStat2, errMsg2); if (Failed()) return; + call MeshConstructElement( tmpActForceMotions(k), ELEMENT_POINT, errStat2, errMsg2, p1=j ); if (Failed()) return; + end do !j + + call MeshCommit(tmpActForceMotions(k), errStat2, errMsg2 ); if (Failed()) return; + END DO + if (allocated(forceNodePositions)) deallocate(forceNodePositions) ! Free space + endif - tmpActForceMotions(k)%RemapFlag = .false. - do j=1,p_OpFM%NnodesForceTower - call MeshPositionNode(tmpActForceMotions(k), j, forceNodePositions(:,j), errStat2, errMsg2) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - call MeshConstructElement( tmpActForceMotions(k), ELEMENT_POINT, errStat2, errMsg2, p1=j ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - end do !j - - call MeshCommit(tmpActForceMotions(k), errStat2, errMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) return - END DO - DEALLOCATE(forceNodePositions) ! Free space - ! create the mapping data structures: DO k=1,p_OpFM%NumBl - call MeshMapCreate( tmp_StructModelMesh(k), tmpActForceMotions(k), tmp_line2_to_point_Motions(k), ErrStat2, ErrMsg2 ); - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - END DO - - DO k=p_OpFM%NumBl+1,p_OpFM%NMappings - call MeshMapCreate( tmp_StructModelMesh(k), tmpActForceMotions(k), tmp_line2_to_point_Motions(k), ErrStat2, ErrMsg2 ); - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + call MeshMapCreate( tmp_StructModelMesh(k), tmpActForceMotions(k), tmp_line2_to_point_Motions(k), ErrStat2, ErrMsg2 ); if (Failed()) return; END DO - + + if (p_OpFM%NMappings .gt. p_OpFM%NumBl) then + DO k=p_OpFM%NumBl+1,p_OpFM%NMappings + call MeshMapCreate( tmp_StructModelMesh(k), tmpActForceMotions(k), tmp_line2_to_point_Motions(k), ErrStat2, ErrMsg2 ); if (Failed()) return; + END DO + endif + ! Map the orientation DO K = 1,p_OpFM%NMappings ! mesh mapping from line2 mesh to point mesh - call Transfer_Line2_to_Point( tmp_StructModelMesh(k), tmpActForceMotions(k), tmp_line2_to_point_Motions(k), ErrStat2, ErrMsg2 ) - call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - + call Transfer_Line2_to_Point( tmp_StructModelMesh(k), tmpActForceMotions(k), tmp_line2_to_point_Motions(k), ErrStat2, ErrMsg2 ); if (Failed()) return; END DO - DO k=1,p_OpFM%NMappings - call MeshDestroy ( tmp_StructModelMesh(k), ErrStat2, ErrMsg2 ) - call MeshMapDestroy ( tmp_line2_to_point_Motions(k), ErrStat2, ErrMsg2 ) - END DO - DEALLOCATE(tmp_StructModelMesh) - DEALLOCATE(tmp_line2_to_point_Motions) + call Cleanup() RETURN +contains + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + if (Failed) call Cleanup() + end function Failed + subroutine Cleanup() + ! NOTE: don't trap errors here + if (allocated(forceNodePositions)) deallocate(forceNodePositions) + DO k=1,p_OpFM%NMappings + call MeshDestroy ( tmp_StructModelMesh(k), ErrStat2, ErrMsg2 ) + call MeshMapDestroy ( tmp_line2_to_point_Motions(k), ErrStat2, ErrMsg2 ) + end do + if (allocated(tmp_StructModelMesh)) deallocate(tmp_StructModelMesh) + if (allocated(tmp_line2_to_point_Motions)) deallocate(tmp_line2_to_point_Motions) + end subroutine Cleanup + logical function Failed2() + if (ErrStat2 /= 0_IntKi) then + CALL SetErrStat( ErrID_Fatal, 'Error allocating meshes.', ErrStat, ErrMsg, RoutineName ) + Failed2 = .true. + call Cleanup() + else + Failed2 = .false. + endif + end function Failed2 END SUBROUTINE OpFM_CreateTmpActForceMotionsMesh -!---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE CreateTmpStructModelMesh(p_FAST, y_ED, p_OpFM, tmpStructModelMesh, ErrStat, ErrMsg ) - - TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST ! Parameters for the glue code - TYPE(ED_OutputType), INTENT(IN ) :: y_ED ! The outputs of the structural dynamics module - TYPE(OpFM_ParameterType), INTENT(IN ) :: p_OpFM ! Parameters of the OpenFOAM integration module - TYPE(MeshType), INTENT(INOUT) :: tmpStructModelMesh(:) ! temporary copy of structural model mesh - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None +!---------------------------------------------------------------------------------------------------------------------------------- +!> A temporary mesh is a copy of the AD15 mesh with the RefOrientation set to identity, and Orientation set to the AD15 RefOrientation. +!! This is used to map orientations over to a more refined mesh. +SUBROUTINE CreateTmpStructModelMesh(p_FAST, u_AD, p_OpFM, tmpBladeMesh, ErrStat, ErrMsg ) + TYPE(FAST_ParameterType), INTENT(IN ) :: p_FAST ! Parameters for the glue code + TYPE(AD_InputType), INTENT(IN ) :: u_AD ! The inputs for AD15 + TYPE(OpFM_ParameterType), INTENT(IN ) :: p_OpFM ! Parameters of the OpenFOAM integration module + TYPE(MeshType), INTENT(INOUT) :: tmpBladeMesh(:) ! temporary copy of structural model mesh + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - !Local variables - INTEGER(IntKi) :: nNodesStructModel ! Number of nodes (tower/blade) in the structural model mesh - - INTEGER(IntKi) :: j ! node counter - INTEGER(IntKi) :: k ! blade counter - INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation - CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None - - CHARACTER(*), PARAMETER :: RoutineName = 'CreateTmpStructModelMesh' - - - IF (p_FAST%CompElast == Module_ED ) THEN - - - DO K = 1,p_OpFM%NumBl - - nNodesStructModel = SIZE(y_ED%BladeLn2Mesh(K)%position(1,:)) - - CALL MeshCreate( BlankMesh = tmpStructModelMesh(K) & - , NNodes = nNodesStructModel & - , IOS = COMPONENT_OUTPUT & - , Orientation = .TRUE. & - , ErrStat = ErrStat2 & - , ErrMess = ErrMsg2 ) - IF (ErrStat >= AbortErrLev) RETURN - - tmpStructModelMesh(K)%RemapFlag = .false. - !For some reason, ElastoDyn keeps the last point as the blade/tower root - CALL MeshPositionNode ( tmpStructModelMesh(K), 1, y_ED%BladeLn2Mesh(K)%Position(:,nNodesStructModel), ErrStat2, ErrMsg2 ) - DO J = 1,nNodesStructModel-1 - CALL MeshPositionNode ( tmpStructModelMesh(K), J+1, y_ED%BladeLn2Mesh(K)%Position(:,J), ErrStat2, ErrMsg2 ) - END DO - - ! create elements: - DO J = 2,nNodesStructModel - - CALL MeshConstructElement ( Mesh = tmpStructModelMesh(K) & - , Xelement = ELEMENT_LINE2 & - , P1 = J-1 & ! node1 number - , P2 = J & ! node2 number - , ErrStat = ErrStat2 & - , ErrMess = ErrMsg2 ) - END DO ! J (blade nodes) - - ! that's our entire mesh: - CALL MeshCommit ( tmpStructModelMesh(K), ErrStat2, ErrMsg2 ) - - ! Copy the orientation - tmpStructModelMesh(K)%Orientation(:,:,1) = y_ED%BladeLn2Mesh(k)%RefOrientation(:,:,nNodesStructModel) - DO J=1,nNodesStructModel-1 - tmpStructModelMesh(K)%Orientation(:,:,J+1) = y_ED%BladeLn2Mesh(K)%RefOrientation(:,:,J) - END DO - - END DO - - DO K = p_OpFM%NumBl+1, p_OpFM%NMappings - - nNodesStructModel = SIZE(y_ED%TowerLn2Mesh%position(1,:)) - - CALL MeshCreate( BlankMesh = tmpStructModelMesh(K) & - , NNodes = nNodesStructModel & - , IOS = COMPONENT_OUTPUT & - , Orientation = .TRUE. & - , ErrStat = ErrStat2 & - , ErrMess = ErrMsg2 ) - - tmpStructModelMesh(K)%RemapFlag = .false. - !For some reason, ElastoDyn keeps the last point as the blade/tower root - CALL MeshPositionNode ( tmpStructModelMesh(K), 1, y_ED%TowerLn2Mesh%Position(:,nNodesStructModel), ErrStat2, ErrMsg2 ) - DO J = 1,nNodesStructModel-1 - CALL MeshPositionNode ( tmpStructModelMesh(K), J+1, y_ED%TowerLn2Mesh%Position(:,J), ErrStat2, ErrMsg2 ) - END DO - - ! create elements: - DO J = 2,nNodesStructModel - - CALL MeshConstructElement ( Mesh = tmpStructModelMesh(K) & - , Xelement = ELEMENT_LINE2 & - , P1 = J-1 & ! node1 number - , P2 = J & ! node2 number - , ErrStat = ErrStat2 & - , ErrMess = ErrMsg2 ) - - END DO ! J (blade nodes) - - ! that's our entire mesh: - CALL MeshCommit ( tmpStructModelMesh(K), ErrStat2, ErrMsg2 ) - - ! Copy the orientation - tmpStructModelMesh(K)%Orientation(:,:,1) = y_ED%TowerLn2Mesh%RefOrientation(:,:,nNodesStructModel) - DO J=1,nNodesStructModel-1 - tmpStructModelMesh(K)%Orientation(:,:,J+1) = y_ED%TowerLn2Mesh%RefOrientation(:,:,J) - END DO + !Local variables + INTEGER(IntKi) :: nNodes ! Number of nodes (tower/blade) in the structural model mesh + INTEGER(IntKi) :: j ! node counter + INTEGER(IntKi) :: k ! blade counter + INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation + CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None + CHARACTER(*), PARAMETER :: RoutineName = 'CreateTmpStructModelMesh' + + DO K = 1,p_OpFM%NumBl + nNodes = u_AD%rotors(1)%BladeMotion(K)%nNodes + CALL MeshCreate( BlankMesh = tmpBladeMesh(K) & + , NNodes = nNodes & + , IOS = COMPONENT_OUTPUT & + , Orientation = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + if (Failed()) return; + tmpBladeMesh(K)%RemapFlag = .false. + + DO J = 1,nNodes + CALL MeshPositionNode ( tmpBladeMesh(K), J, u_AD%rotors(1)%BladeMotion(K)%Position(:,J), ErrStat2, ErrMsg2 ) + if (Failed()) return; + END DO - END DO - - - ELSEIF (p_FAST%CompElast == Module_BD ) THEN + ! create elements: + DO J = 2,nNodes + CALL MeshConstructElement( Mesh = tmpBladeMesh(K) & + , Xelement = ELEMENT_LINE2 & + , P1 = J-1 & ! node1 number + , P2 = J & ! node2 number + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + END DO ! J (blade nodes) + if (Failed()) return; + + ! that's our entire mesh: + CALL MeshCommit ( tmpBladeMesh(K), ErrStat2, ErrMsg2 ) + + ! Copy the orientation + DO J=1,nNodes + tmpBladeMesh(K)%Orientation(:,:,J) = u_AD%rotors(1)%BladeMotion(K)%RefOrientation(:,:,J) + END DO + END DO - CALL SetErrStat(ErrID_Fatal, 'Error BeamDyn is not supported yet with OpenFOAM module', ErrStat, ErrMsg, RoutineName) - RETURN - - END IF + if (p_OpFM%NMappings .gt. p_OpFM%NumBl) then + DO K = p_OpFM%NumBl+1, p_OpFM%NMappings + nNodes = u_AD%rotors(1)%TowerMotion%nNodes + CALL MeshCreate( BlankMesh = tmpBladeMesh(K) & + , NNodes = nNodes & + , IOS = COMPONENT_OUTPUT & + , Orientation = .TRUE. & + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + if (Failed()) return; + tmpBladeMesh(K)%RemapFlag = .false. + DO J = 1,nNodes + CALL MeshPositionNode ( tmpBladeMesh(K), J, u_AD%rotors(1)%TowerMotion%Position(:,J), ErrStat2, ErrMsg2 ) + if (Failed()) return; + END DO + + ! create elements: + DO J = 2,nNodes + CALL MeshConstructElement( Mesh = tmpBladeMesh(K) & + , Xelement = ELEMENT_LINE2 & + , P1 = J-1 & ! node1 number + , P2 = J & ! node2 number + , ErrStat = ErrStat2 & + , ErrMess = ErrMsg2 ) + END DO ! J (blade nodes) + if (Failed()) return; + + ! that's our entire mesh: + CALL MeshCommit ( tmpBladeMesh(K), ErrStat2, ErrMsg2 ); if (Failed()) return; + + ! Copy the orientation + DO J=1,nNodes + tmpBladeMesh(K)%Orientation(:,:,J) = u_AD%rotors(1)%TowerMotion%RefOrientation(:,:,J) + END DO + END DO + endif - RETURN + RETURN +contains + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + end function Failed END SUBROUTINE CreateTmpStructModelMesh -!---------------------------------------------------------------------------------------------------------------------------------- -SUBROUTINE CalcForceActuatorPositionsBlade(InitIn_OpFM, p_OpFM, structPositions, forceNodePositions, ErrStat2, ErrMsg2) - - TYPE(OpFM_InitInputType), INTENT(IN ) :: InitIn_OpFM ! data for the OpenFOAM integration module - TYPE(OpFM_ParameterType), INTENT(IN ) :: p_OpFM ! data for the OpenFOAM integration module - REAL(ReKi), POINTER :: structPositions(:,:) ! structural model positions - REAL(ReKi), INTENT(INOUT) :: forceNodePositions(:,:) ! Array to store the newly created positions - INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation - CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None - - !Local variables - INTEGER(IntKi) :: nStructNodes ! Number of velocity nodes - REAL(ReKi), DIMENSION(:), ALLOCATABLE :: rStructNodes ! Distance of velocity nodes from the first node - Used as a parameter for curve fitting - INTEGER(IntKI) :: i ! Loop variables - INTEGER(IntKI) :: jLower ! Index of the struct node just smaller than the force node - REAL(ReKi) :: rInterp ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes - - nStructNodes = SIZE(structPositions,2) - ALLOCATE(rStructNodes(nStructNodes), STAT=ErrStat2) +!---------------------------------------------------------------------------------------------------------------------------------- +SUBROUTINE CalcForceActuatorPositionsBlade(InitIn_OpFM, p_OpFM, structPositions, forceNodePositions, ErrStat, ErrMsg) + TYPE(OpFM_InitInputType), INTENT(IN ) :: InitIn_OpFM ! data for the OpenFOAM integration module + TYPE(OpFM_ParameterType), INTENT(IN ) :: p_OpFM ! data for the OpenFOAM integration module + REAL(ReKi), POINTER :: structPositions(:,:) ! structural model positions + REAL(ReKi), INTENT(INOUT) :: forceNodePositions(:,:) ! Array to store the newly created positions + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + !Local variables + INTEGER(IntKi) :: nStructNodes ! Number of velocity nodes + REAL(ReKi), DIMENSION(:), ALLOCATABLE :: rStructNodes ! Distance of velocity nodes from the first node - Used as a parameter for curve fitting + INTEGER(IntKI) :: i ! Loop variables + INTEGER(IntKI) :: jLower ! Index of the struct node just smaller than the force node + REAL(ReKi) :: rInterp ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes + INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation + CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None + CHARACTER(*), PARAMETER :: RoutineName = 'CalcForceActuatorPositionsBlade' - ! Store the distance of the structural model nodes from the root into an array - rStructNodes(1) = 0.0 ! First node - rStructNodes(2:nStructNodes-1) = InitIn_OpFM%StructBldRnodes(:) - rStructNodes(nStructNodes) = p_OpFM%BladeLength + ErrStat = ErrID_None + ErrMsg = "" + + nStructNodes = SIZE(structPositions,2) + call AllocAry(rStructNodes, nStructNodes, "rStructNodes", ErrStat2, ErrMsg2); if (Failed()) return; + + ! Store the distance of the structural model nodes from the root into an array (from AD15 blade defenition) + rStructNodes(:) = InitIn_OpFM%StructBldRnodes(:) + + ! Now calculate the positions of the force nodes based on interpolation + ! NOTE: the InterpArray function from the NWTC Library could be used here instead. This interpolation will eventually be removed, so we won't update it here. + forceNodePositions(:,1) = structPositions(:,1) + DO I=2,p_OpFM%nNodesForceBlade-1 ! Calculate the position of the force nodes + do jLower = 1, (nStructNodes - 1) + if ((rStructNodes(jLower) - p_OpFM%forceBldRnodes(I))*(rStructNodes(jLower+1) - p_OpFM%forceBldRnodes(I)) .le. 0) then + exit + endif + end do + rInterp = (p_OpFM%forceBldRnodes(I) - rStructNodes(jLower))/(rStructNodes(jLower+1)-rStructNodes(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes + forceNodePositions(:,I) = structPositions(:,jLower) + rInterp * (structPositions(:,jLower+1) - structPositions(:,jLower)) + END DO + forceNodePositions(:,p_OpFM%nNodesForceBlade) = structPositions(:,nStructNodes) - ! Now calculate the positions of the force nodes based on interpolation - forceNodePositions(:,1) = structPositions(:,1) - DO I=2,p_OpFM%NnodesForceBlade-1 ! Calculate the position of the force nodes - do jLower = 1, (nStructNodes - 1) - if ((rStructNodes(jLower) - p_OpFM%forceBldRnodes(I))*(rStructNodes(jLower+1) - p_OpFM%forceBldRnodes(I)) .le. 0) then - exit - endif - end do - rInterp = (p_OpFM%forceBldRnodes(I) - rStructNodes(jLower))/(rStructNodes(jLower+1)-rStructNodes(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes - forceNodePositions(:,I) = structPositions(:,jLower) + rInterp * (structPositions(:,jLower+1) - structPositions(:,jLower)) - END DO - forceNodePositions(:,p_OpFM%NnodesForceBlade) = structPositions(:,nStructNodes) - - DEALLOCATE(rStructNodes) + if (allocated(rStructNodes)) deallocate(rStructNodes) - RETURN + RETURN +contains + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + end function Failed END SUBROUTINE CalcForceActuatorPositionsBlade + !---------------------------------------------------------------------------------------------------------------------------------- SUBROUTINE CalcForceActuatorPositionsTower(InitIn_OpFM, p_OpFM, structPositions, forceNodePositions, ErrStat, ErrMsg) + TYPE(OpFM_InitInputType), INTENT(IN ) :: InitIn_OpFM ! data for the OpenFOAM integration module + TYPE(OpFM_ParameterType), INTENT(IN ) :: p_OpFM ! data for the OpenFOAM integration module + REAL(ReKi), POINTER :: structPositions(:,:) ! structural model positions + REAL(ReKi), INTENT(INOUT) :: forceNodePositions(:,:) ! Array to store the newly created positions + INTEGER(IntKi) , intent(out) :: ErrStat ! temporary Error status of the operation + CHARACTER(ErrMsgLen) , intent(out) :: ErrMsg ! temporary Error message if ErrStat /= ErrID_None + + !Local variables + INTEGER(IntKi) :: nStructNodes ! Number of velocity nodes + REAL(ReKi), DIMENSION(:), ALLOCATABLE :: hStructNodes ! Distance of velocity nodes from the first node - Used as a parameter for curve fitting + INTEGER(IntKI) :: i ! Loop variables + INTEGER(IntKI) :: jLower ! Index of the struct node just smaller than the force node + REAL(ReKi) :: hInterp ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes + INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation + CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None + CHARACTER(*), PARAMETER :: RoutineName = 'CalcForceActuatorPositionsTower' - TYPE(OpFM_InitInputType), INTENT(IN ) :: InitIn_OpFM ! data for the OpenFOAM integration module - TYPE(OpFM_ParameterType), INTENT(IN ) :: p_OpFM ! data for the OpenFOAM integration module - REAL(ReKi), POINTER :: structPositions(:,:) ! structural model positions - REAL(ReKi), INTENT(INOUT) :: forceNodePositions(:,:) ! Array to store the newly created positions - INTEGER(IntKi) , intent(out) :: ErrStat ! temporary Error status of the operation - CHARACTER(ErrMsgLen) , intent(out) :: ErrMsg ! temporary Error message if ErrStat /= ErrID_None - + ErrStat = ErrID_None + ErrMsg = "" - !Local variables - INTEGER(IntKi) :: nStructNodes ! Number of velocity nodes - REAL(ReKi), DIMENSION(:), ALLOCATABLE :: hStructNodes ! Distance of velocity nodes from the first node - Used as a parameter for curve fitting - INTEGER(IntKI) :: i ! Loop variables - INTEGER(IntKI) :: jLower ! Index of the struct node just smaller than the force node - REAL(ReKi) :: hInterp ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes - - nStructNodes = SIZE(structPositions,2) - ALLOCATE(hStructNodes(nStructNodes), STAT=ErrStat) - IF (ErrStat /= 0) then - ErrStat=ErrID_Fatal - ErrMsg = "error allocating hStructNodes" - return - ELSE - ErrStat = ErrID_None - ErrMsg = "" - END IF + nStructNodes = SIZE(structPositions,2) + call AllocAry(hStructNodes, nStructNodes, "hStructNodes", ErrStat2, ErrMsg2); if (Failed()) return; ! Store the distance of the structural model nodes from the root into an array - hStructNodes(1) = 0.0 ! First node - hStructNodes(2:nStructNodes-1) = InitIn_OpFM%StructTwrHnodes(:) - hStructNodes(nStructNodes) = p_OpFM%TowerHeight + hStructNodes(:) = InitIn_OpFM%StructTwrHnodes(:) + hStructNodes(nStructNodes) = p_OpFM%TowerHeight+p_OpFM%TowerBaseHeight ! Now calculate the positions of the force nodes based on interpolation + ! NOTE: the InterpArray function from the NWTC Library could be used here instead. This interpolation will eventually be removed, so we won't update it here. forceNodePositions(:,1) = structPositions(:,1) - DO I=2,p_OpFM%NnodesForceTower-1 ! Calculate the position of the force nodes + DO I=2,p_OpFM%nNodesForceTower-1 ! Calculate the position of the force nodes do jLower = 1, (nStructNodes - 1) - if ((hStructNodes(jLower) - p_OpFM%forceTwrHnodes(I))*(hStructNodes(jLower+1) - p_OpFM%forceTwrHnodes(I)) .le. 0) then + if ((hStructNodes(jLower) - (p_OpFM%forceTwrHnodes(I)+p_OpFM%TowerBaseHeight))*(hStructNodes(jLower+1) - (p_OpFM%forceTwrHnodes(I)+p_OpFM%TowerBaseHeight)) .le. 0) then exit endif enddo - hInterp = (p_OpFM%forceTwrHnodes(I) - hStructNodes(jLower))/(hStructNodes(jLower+1)-hStructNodes(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes + hInterp = (p_OpFM%forceTwrHnodes(I)+p_OpFM%TowerBaseHeight - hStructNodes(jLower))/(hStructNodes(jLower+1)-hStructNodes(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes forceNodePositions(:,I) = structPositions(:,jLower) + hInterp * (structPositions(:,jLower+1) - structPositions(:,jLower)) END DO - forceNodePositions(:,p_OpFM%NnodesForceTower) = structPositions(:,nStructNodes) - DEALLOCATE(hStructNodes) + forceNodePositions(:,p_OpFM%nNodesForceTower) = structPositions(:,nStructNodes) + if (allocated(hStructNodes)) deallocate(hStructNodes) RETURN +contains + logical function Failed() + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + Failed = ErrStat >= AbortErrLev + end function Failed END SUBROUTINE CalcForceActuatorPositionsTower -SUBROUTINE OpFM_CreateActForceBladeTowerNodes(p_OpFM, ErrStat, ErrMsg) -!Creates the blade and tower nodes in radial and tower height co-ordinates +!-------------------------------------------------------------------------- +!> Creates the blade and tower nodes in radial and tower height co-ordinates +SUBROUTINE OpFM_CreateActForceBladeTowerNodes(InitOut_AD, p_OpFM, u_OpFM, ErrStat, ErrMsg) + TYPE(AD_InitOutputType), INTENT(IN ) :: InitOut_AD ! InitOut data for the OpenFOAM integration module + TYPE(OpFM_ParameterType),INTENT(INOUT) :: p_OpFM ! Parameter data for the OpenFOAM integration module + TYPE(OpFM_InputType), INTENT(INOUT) :: u_OpFM ! Input data for the OpenFOAM integration module + INTEGER(IntKi) :: ErrStat ! Error status of the operation + CHARACTER(ErrMsgLen) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + !Local variables + REAL(ReKi), ALLOCATABLE :: cNonUniform(:) + REAL(ReKi), ALLOCATABLE :: sNonUniform(:) + REAL(ReKi), ALLOCATABLE :: pNonUniform(:) + REAL(ReKi), ALLOCATABLE :: pUniform(:) + REAL(ReKi), ALLOCATABLE :: cByS(:) + REAL(ReKi), ALLOCATABLE :: e(:) + REAL(ReKi) :: eSum, eTol + REAL(ReKi) :: bladeRoot, bladeTip, rInterp + INTEGER(IntKi) :: counter + REAL(ReKi) :: dRforceNodes ! Uniform distance between two consecutive force nodes + INTEGER(IntKI) :: i ! Loop variables + INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation + CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None + CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_CreateActForceBladeTowerNodes' - TYPE(OpFM_ParameterType), INTENT(INOUT) :: p_OpFM ! data for the OpenFOAM integration module - INTEGER(IntKi) :: ErrStat ! temporary Error status of the operation - CHARACTER(ErrMsgLen) :: ErrMsg ! temporary Error message if ErrStat /= ErrID_None + ErrStat = ErrID_None + ErrMsg = "" - !Local variables - REAL(ReKi) :: dRforceNodes ! Uniform distance between two consecutive force nodes - INTEGER(IntKI) :: i ! Loop variables - INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation - - ErrStat = ErrID_None - ErrMsg = "" - - ! Line2 to Line2 mapping expects the destination mesh to be smaller than the source mesh for deformation mapping and larger than the source mesh for load mapping. This forces me to create nodes at the very ends of the blade. - - !Do the blade first - allocate(p_OpFM%forceBldRnodes(p_OpFM%NnodesForceBlade), stat=errStat2) - dRforceNodes = p_OpFM%BladeLength/(p_OpFM%NnodesForceBlade-1) - do i=1,p_OpFM%NnodesForceBlade-1 - p_OpFM%forceBldRnodes(i) = (i-1)*dRforceNodes - end do - p_OpFM%forceBldRnodes(p_OpFM%NnodesForceBlade) = p_OpFM%BladeLength - if (p_OpFM%NMappings .gt. p_OpFM%NumBl) then - !Do the tower now - allocate(p_OpFM%forceTwrHnodes(p_OpFM%NnodesForceTower), stat=errStat2) - dRforceNodes = p_OpFM%TowerHeight/(p_OpFM%NnodesForceTower-1) - do i=1,p_OpFM%NnodesForceTower-1 - p_OpFM%forceTwrHnodes(i) = (i-1)*dRforceNodes - end do - p_OpFM%forceTwrHnodes(p_OpFM%NnodesForceTower) = p_OpFM%TowerHeight - end if + ! Tower + if (p_OpFM%NMappings .gt. p_OpFM%NumBl) then + allocate(p_OpFM%forceTwrHnodes(p_OpFM%nNodesForceTower), stat=errStat2); if (Failed2()) return; + ! Compute uniform spacing. + dRforceNodes = p_OpFM%TowerHeight/(p_OpFM%nNodesForceTower-1) + do i=1,p_OpFM%nNodesForceTower-1 + p_OpFM%forceTwrHnodes(i) = (i-1)*dRforceNodes + end do + p_OpFM%forceTwrHnodes(p_OpFM%nNodesForceTower) = p_OpFM%TowerHeight + end if - return -END SUBROUTINE OpFM_CreateActForceBladeTowerNodes -SUBROUTINE OpFM_InterpolateForceNodesChord(InitOut_AD, p_OpFM, u_OpFM, ErrStat, ErrMsg) + ! Blades + allocate(cNonUniform(p_OpFM%nNodesForceBlade),stat=errStat2) + allocate(sNonUniform(p_OpFM%nNodesForceBlade),stat=errStat2) + allocate(pNonUniform(p_OpFM%nNodesForceBlade),stat=errStat2) + allocate(pUniform(p_OpFM%nNodesForceBlade),stat=errStat2) + allocate(cByS(p_OpFM%nNodesForceBlade),stat=errStat2) + allocate(e(p_OpFM%nNodesForceBlade-1),stat=errStat2) + allocate(p_OpFM%forceBldRnodes(p_OpFM%nNodesForceBlade), stat=errStat2); if (Failed2()) return; + + ! Compute uniform spacing. + dRforceNodes = p_OpFM%BladeLength/(p_OpFM%nNodesForceBlade-1) + do i=1,p_OpFM%nNodesForceBlade-1 + pUniform(i) = (i-1)*dRforceNodes + end do + pUniform(p_OpFM%nNodesForceBlade) = p_OpFM%BladeLength + p_OpFM%forceBldRnodes = pUniform + + if (p_OpFM%NodeClusterType .eq. 0) then + print*, "Using uniform blade force node clustering." + !do i = 1, p_OpFM%nNodesForceBlade + ! print*, "r(",i,") = ", pUniform(i) + !end do + end if + + + ! If non-uniform spacing is called for, compute the spacing. + ! We know that if the spacing is proportional to chord, then at each + ! element, ds = a*c, where a is some constant factor across the entire + ! blade. Therefore sum(ds) = sum(a*c) = L, so a is L/sum(c). Because + ! we don't know c at every point exactly beforehand, we have to + ! iterate using c from our previous best guess. We know things have + ! converged when a = c/ds is constant along the blade, so that is our + ! convergence check. We take the difference between a = c/ds between + ! all neighboring points to see how different they are, and take the + ! rms of that error as the convergence measure (eSum). + if (p_OpFM%NodeClusterType .eq. 1) then + + ! For chord-based clustering (increase resolution in regions of decreased chord), an iterative solution to the grid spacing is used. + ! The initial guess to the spacing is uniform spacing, so start with that. + pNonUniform = pUniform + + ! Get the chord at the initial force points. + call OpFM_InterpolateForceNodesChord(initOut_AD, p_OpFM, u_OpFM, ErrStat2, ErrMsg2) + cNonUniform(1:p_OpFM%nNodesForceBlade) = u_OpFM%forceNodesChord(2:p_OpFM%nNodesForceBlade+1) + + ! Iterate on a chord-based non-uniform spacing. + counter = 0 + e = 1.0e+6 + eTol = 1.0e-6 + eSum = sqrt(sum(e*e)) + do while ((eSum .gt. eTol) .and. (counter < 50)) + + !set the non-uniform spacing to ds = (sum(ds^) / sum(c^)) * c^, where + !the ^ denotes from the last iteration. To begin the iteration, we + !use ds = uniform. + sNonUniform = (p_OpFM%BladeLength)*cNonUniform/(sum(cNonUniform(2:p_OpFM%nNodesForceBlade-1)) + 0.5*(cNonUniform(1)+cNonUniform(p_OpFM%nNodesForceBlade))) + + ! set the new blade points based on the new ds. + do i = 2, p_OpFM%nNodesForceBlade + pNonUniform(i) = pNonUniform(i-1) + 0.5*(sNonUniform(i-1) + sNonUniform(i)) + end do + pNonUniform(p_OpFM%nNodesForceBlade) = p_OpFM%BladeLength + p_OpFM%forceBldRnodes = pNonUniform + + ! interpolate chord to the new points to get the updated chord values + call OpFM_InterpolateForceNodesChord(initOut_AD, p_OpFM, u_OpFM,ErrStat2, ErrMsg2) + cNonUniform(1:p_OpFM%nNodesForceBlade) = u_OpFM%forceNodesChord(2:p_OpFM%nNodesForceBlade+1) + + ! compute a = c/ds + cByS = cNonUniform/sNonUniform + + ! check how a = c/s varies along the span and take its rms to check + ! convergence. + e = cByS(2:p_OpFM%nNodesForceBlade) - cByS(1:p_OpFM%nNodesForceBlade-1) + eSum = sqrt(sum(e*e)) + + ! increment the iteration counter + counter = counter + 1 + + end do + + CALL WrScr("Using chord-scaled blade force node clustering") + CALL WrScr(" -converged to "//trim(Num2LStr(eSum))//" in "//trim(Num2LStr(counter))//" iterations.") + end if + + + return - !Interpolates the chord distribution to the force nodes - +contains + logical function Failed2() + if (ErrStat2 /= 0_IntKi) then + CALL SetErrStat( ErrID_Fatal, 'Failed to allocate force needs pointer array', ErrStat, ErrMsg, RoutineName ) + Failed2 = .true. + else + Failed2 = .false. + endif + end function Failed2 +END SUBROUTINE OpFM_CreateActForceBladeTowerNodes + +!-------------------------------------------------------------------------- +!> Interpolates the chord distribution to the force nodes +SUBROUTINE OpFM_InterpolateForceNodesChord(InitOut_AD, p_OpFM, u_OpFM, ErrStat, ErrMsg) TYPE(AD_InitOutputType), INTENT(IN ) :: InitOut_AD ! InitOut data for the OpenFOAM integration module - TYPE(OpFM_ParameterType), INTENT(IN ) :: p_OpFM ! Input data for the OpenFOAM integration module - TYPE(OpFM_InputType), INTENT(INOUT) :: u_OpFM ! Parameter data for the OpenFOAM integration module + TYPE(OpFM_ParameterType), INTENT(IN ) :: p_OpFM ! Parameter data for the OpenFOAM integration module + TYPE(OpFM_InputType), INTENT(INOUT) :: u_OpFM ! Input data for the OpenFOAM integration module INTEGER(IntKi) :: ErrStat ! temporary Error status of the operation CHARACTER(ErrMsgLen) :: ErrMsg ! temporary Error message if ErrStat /= ErrID_None !Local variables INTEGER(IntKI) :: i,k,node ! Loop variables INTEGER(IntKI) :: nNodesBladeProps ! Number of nodes in the blade properties for a given blade - INTEGER(IntKI) :: nNodesTowerProps ! Number of nodes in the tower properties + INTEGER(IntKI) :: nNodesTowerProps ! Number of nodes in the tower properties INTEGER(IntKI) :: jLower ! Index of the blade properties node just smaller than the force node REAL(ReKi) :: rInterp ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes ErrStat = ErrID_None ErrMsg = "" - + ! Set the chord for the hub node to be zero. Ideally, I'd like this to be the hub radius. Will figure this out later. Node = 1 u_OpFM%forceNodesChord(Node) = 0.0_ReKi ! The blades first do k = 1, p_OpFM%NumBl + ! Calculate the chord at the force nodes based on interpolation + ! NOTE: the InterpArray function from the NWTC Library could be used here instead. This interpolation will eventually be removed, so we won't update it here. nNodesBladeProps = SIZE(InitOut_AD%rotors(1)%BladeProps(k)%BlChord) - DO I=1,p_OpFM%NnodesForceBlade + DO I=1,p_OpFM%nNodesForceBlade Node = Node + 1 do jLower = 1, (nNodesBladeProps - 1) if ( (InitOut_AD%rotors(1)%BladeProps(k)%BlSpn(jLower) - p_OpFM%forceBldRnodes(I))*(InitOut_AD%rotors(1)%BladeProps(k)%BlSpn(jLower+1) - p_OpFM%forceBldRnodes(I)) .le. 0 ) then @@ -1153,30 +1188,33 @@ SUBROUTINE OpFM_InterpolateForceNodesChord(InitOut_AD, p_OpFM, u_OpFM, ErrStat, u_OpFM%forceNodesChord(Node) = InitOut_AD%rotors(1)%BladeProps(k)%BlChord(nNodesBladeProps) !Work around for when the last node of the actuator mesh is slightly outside of the Aerodyn blade properties. Surprisingly this is not an issue with the tower. end if END DO - - end do - ! The tower now - do k = p_OpFM%NumBl+1,p_OpFM%NMappings - nNodesTowerProps = SIZE(InitOut_AD%rotors(1)%TwrElev) - ! Calculate the chord at the force nodes based on interpolation - DO I=1,p_OpFM%NnodesForceTower - Node = Node + 1 - do jLower = 1, (nNodesTowerProps - 1) - if ( (InitOut_AD%rotors(1)%TwrElev(jLower) - p_OpFM%forceTwrHnodes(I)-p_OpFM%TowerBaseHeight)*(InitOut_AD%rotors(1)%TwrElev(jLower+1) - p_OpFM%forceTwrHnodes(I)-p_OpFM%TowerBaseHeight) .le. 0) then - exit - endif - enddo - if (jLower .lt. nNodesTowerProps) then - rInterp = (p_OpFM%forceTwrHnodes(I)+p_OpFM%TowerBaseHeight - InitOut_AD%rotors(1)%TwrElev(jLower))/(InitOut_AD%rotors(1)%TwrElev(jLower+1)-InitOut_AD%rotors(1)%TwrElev(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes - u_OpFM%forceNodesChord(Node) = InitOut_AD%rotors(1)%TwrDiam(jLower) + rInterp * (InitOut_AD%rotors(1)%TwrDiam(jLower+1) - InitOut_AD%rotors(1)%TwrDiam(jLower)) - else - u_OpFM%forceNodesChord(Node) = InitOut_AD%rotors(1)%TwrDiam(nNodesTowerProps) !Work around for when the last node of the actuator mesh is slightly outside of the Aerodyn tower properties. - end if - END DO - end do + if (p_OpFM%NMappings .gt. p_OpFM%NumBl) then + do k = p_OpFM%NumBl+1,p_OpFM%NMappings + nNodesTowerProps = SIZE(InitOut_AD%rotors(1)%TwrElev) + + ! Calculate the chord at the force nodes based on interpolation + do I=1,p_OpFM%nNodesForceTower + Node = Node + 1 + + do jLower = 1, (nNodesTowerProps - 1) + if ( (InitOut_AD%rotors(1)%TwrElev(jLower) - p_OpFM%forceTwrHnodes(I)-p_OpFM%TowerBaseHeight)*(InitOut_AD%rotors(1)%TwrElev(jLower+1) - p_OpFM%forceTwrHnodes(I)-p_OpFM%TowerBaseHeight) .le. 0) then + exit + endif + enddo + + if (jLower .lt. nNodesTowerProps) then + rInterp = (p_OpFM%forceTwrHnodes(I)+p_OpFM%TowerBaseHeight - InitOut_AD%rotors(1)%TwrElev(jLower))/(InitOut_AD%rotors(1)%TwrElev(jLower+1)-InitOut_AD%rotors(1)%TwrElev(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes + u_OpFM%forceNodesChord(Node) = InitOut_AD%rotors(1)%TwrDiam(jLower) + rInterp * (InitOut_AD%rotors(1)%TwrDiam(jLower+1) - InitOut_AD%rotors(1)%TwrDiam(jLower)) + else + u_OpFM%forceNodesChord(Node) = InitOut_AD%rotors(1)%TwrDiam(nNodesTowerProps) !Work around for when the last node of the actuator mesh is slightly outside of the Aerodyn tower properties. + end if + + end do + end do + endif END SUBROUTINE OpFM_InterpolateForceNodesChord diff --git a/modules/openfoam/src/OpenFOAM_Registry.txt b/modules/openfoam/src/OpenFOAM_Registry.txt index bb1e5a0f0..a8bd4f5f2 100644 --- a/modules/openfoam/src/OpenFOAM_Registry.txt +++ b/modules/openfoam/src/OpenFOAM_Registry.txt @@ -11,15 +11,14 @@ include Registry_NWTC_Library.txt # ..... OpenFOAM_InitInputType data ....................................................................................................... -typedef OpenFOAM/OpFM InitInputType IntKi NumActForcePtsBlade - - - "number of actuator line force points in blade" - -typedef ^ ^ IntKi NumActForcePtsTower - - - "number of actuator line force points in tower" - +typedef OpenFOAM/OpFM InitInputType IntKi NumActForcePtsBlade - - - "number of actuator line force points in blade -- from extern (used to linearly interpolate along AD15 blades)" - +typedef ^ ^ IntKi NumActForcePtsTower - - - "number of actuator line force points in tower -- from extern (used to linearly interpolate along AD15 tower)" - typedef ^ ^ ReKi StructBldRNodes {:} - - "Radius to structural model analysis nodes relative to hub" -typedef ^ ^ ReKi StructTwrHNodes {:} - - "Location of variable-spaced structural model tower nodes (relative to the tower rigid base height)" +typedef ^ ^ ReKi StructTwrHNodes {:} - - "Location of tower nodes from AD15 (relative to the tower rigid base height)" typedef ^ ^ ReKi BladeLength - - - "Blade length" meters typedef ^ ^ ReKi TowerHeight - - - "Tower Height" meters typedef ^ ^ ReKi TowerBaseHeight - - - "Tower Base Height" meters - - +typedef ^ ^ IntKi NodeClusterType - - - "Node clustering (0 - Uniform, 1 - Non-uniform clustered towards tip)" - @@ -30,14 +29,10 @@ typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {:} - - "Units of the typedef ^ InitOutputType ProgDesc Ver - - - "This module's name, version, and date" - # ..... MiscVars ................................................................................................................ -typedef OpenFOAM/OpFM OpFM_MiscVarType MeshType ActForceLoads {:} - - "line2 mesh for transferring AeroDyn distributed loads to OpenFOAM" - -typedef ^ ^ MeshType ActForceMotions {:} - - "line2 mesh for transferring AeroDyn distributed loads to OpenFOAM (needs translationDisp)" - -typedef ^ ^ MeshType ActForceMotionsPoints {:} - - "point mesh for transferring AeroDyn distributed loads to OpenFOAM (needs translationDisp)" - -typedef ^ ^ MeshType ActForceLoadsPoints {:} - - "point mesh for transferring AeroDyn distributed loads to OpenFOAM" - -typedef ^ ^ MeshMapType Line2_to_Line2_Loads {:} - - "mapping data structure to convert line2 loads to line2 loads" - -typedef ^ ^ MeshMapType Line2_to_Line2_Motions {:} - - "mapping data structure to convert line2 loads to line2 motions" - -typedef ^ ^ MeshMapType Line2_to_Point_Loads {:} - - "mapping data structure to convert line2 loads to point loads" - -typedef ^ ^ MeshMapType Line2_to_Point_Motions {:} - - "mapping data structure to convert line2 loads to point motions" - +typedef OpenFOAM/OpFM OpFM_MiscVarType MeshType ActForceMotionsPoints {:} - - "point mesh for transferring AeroDyn motions to OpenFOAM (includes hub+blades+nacelle+tower+tailfin)" - +typedef OpenFOAM/OpFM OpFM_MiscVarType MeshType ActForceLoadsPoints {:} - - "point mesh for transferring AeroDyn distributed loads to OpenFOAM (includes hub+blades+nacelle+tower+tailfin)" - +typedef OpenFOAM/OpFM OpFM_MiscVarType MeshMapType Line2_to_Point_Loads {:} - - "mapping data structure to convert line2 loads to point loads" - +typedef OpenFOAM/OpFM OpFM_MiscVarType MeshMapType Line2_to_Point_Motions {:} - - "mapping data structure to convert line2 loads to point motions" - # ..... Parameters ................................................................................................................ @@ -48,12 +43,12 @@ typedef OpenFOAM/OpFM ParameterType IntKi NnodesVel - - - "number of velocity no typedef OpenFOAM/OpFM ParameterType IntKi NnodesForce - - - "number of force nodes on FAST v8-OpenFOAM interface" - typedef OpenFOAM/OpFM ParameterType IntKi NnodesForceBlade - - - "number of force nodes on FAST v8-OpenFOAM interface" - typedef OpenFOAM/OpFM ParameterType IntKi NnodesForceTower - - - "number of force nodes on FAST v8-OpenFOAM interface" - -typedef ^ ^ ReKi forceBldRnodes {:} "Radial location of force nodes" - -typedef ^ ^ ReKi forceTwrHnodes {:} "Radial location of force nodes" - -typedef ^ ^ ReKi BladeLength - - - "Blade length (same for all blades)" "m" -typedef ^ ^ ReKi TowerHeight - - - "Tower height" "m" -typedef ^ ^ ReKi TowerBaseHeight - - - "Tower base height" "m" - +typedef OpenFOAM/OpFM ParameterType ReKi forceBldRnodes {:} - - "Radial location of force nodes" - +typedef OpenFOAM/OpFM ParameterType ReKi forceTwrHnodes {:} - - "Vertical location of force nodes" - +typedef OpenFOAM/OpFM ParameterType ReKi BladeLength - - - "Blade length (same for all blades)" "m" +typedef OpenFOAM/OpFM ParameterType ReKi TowerHeight - - - "Tower height" "m" +typedef OpenFOAM/OpFM ParameterType ReKi TowerBaseHeight - - - "Tower base height" "m" +typedef OpenFOAM/OpFM ParameterType IntKi NodeClusterType - - - "Node clustering (0 - Uniform, 1 - Non-uniform clustered towards tip)" - # ..... OpenFOAM_InputType data ....................................................................................................... typedef ^ InputType ReKi pxVel {:} - - "x position of velocity interface (Aerodyn) nodes" "m" diff --git a/modules/openfoam/src/OpenFOAM_Types.f90 b/modules/openfoam/src/OpenFOAM_Types.f90 index cea50b0c4..a3a92c86e 100644 --- a/modules/openfoam/src/OpenFOAM_Types.f90 +++ b/modules/openfoam/src/OpenFOAM_Types.f90 @@ -46,16 +46,18 @@ MODULE OpenFOAM_Types REAL(KIND=C_FLOAT) :: BladeLength REAL(KIND=C_FLOAT) :: TowerHeight REAL(KIND=C_FLOAT) :: TowerBaseHeight + INTEGER(KIND=C_INT) :: NodeClusterType END TYPE OpFM_InitInputType_C TYPE, PUBLIC :: OpFM_InitInputType TYPE( OpFM_InitInputType_C ) :: C_obj - INTEGER(IntKi) :: NumActForcePtsBlade !< number of actuator line force points in blade [-] - INTEGER(IntKi) :: NumActForcePtsTower !< number of actuator line force points in tower [-] + INTEGER(IntKi) :: NumActForcePtsBlade !< number of actuator line force points in blade -- from extern (used to linearly interpolate along AD15 blades) [-] + INTEGER(IntKi) :: NumActForcePtsTower !< number of actuator line force points in tower -- from extern (used to linearly interpolate along AD15 tower) [-] REAL(KIND=C_FLOAT) , DIMENSION(:), POINTER :: StructBldRNodes => NULL() !< Radius to structural model analysis nodes relative to hub [-] - REAL(KIND=C_FLOAT) , DIMENSION(:), POINTER :: StructTwrHNodes => NULL() !< Location of variable-spaced structural model tower nodes (relative to the tower rigid base height) [-] + REAL(KIND=C_FLOAT) , DIMENSION(:), POINTER :: StructTwrHNodes => NULL() !< Location of tower nodes from AD15 (relative to the tower rigid base height) [-] REAL(ReKi) :: BladeLength !< Blade length [meters] REAL(ReKi) :: TowerHeight !< Tower Height [meters] REAL(ReKi) :: TowerBaseHeight !< Tower Base Height [meters] + INTEGER(IntKi) :: NodeClusterType !< Node clustering (0 - Uniform, 1 - Non-uniform clustered towards tip) [-] END TYPE OpFM_InitInputType ! ======================= ! ========= OpFM_InitOutputType_C ======= @@ -79,12 +81,8 @@ MODULE OpenFOAM_Types END TYPE OpFM_MiscVarType_C TYPE, PUBLIC :: OpFM_MiscVarType TYPE( OpFM_MiscVarType_C ) :: C_obj - TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: ActForceLoads !< line2 mesh for transferring AeroDyn distributed loads to OpenFOAM [-] - TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: ActForceMotions !< line2 mesh for transferring AeroDyn distributed loads to OpenFOAM (needs translationDisp) [-] - TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: ActForceMotionsPoints !< point mesh for transferring AeroDyn distributed loads to OpenFOAM (needs translationDisp) [-] - TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: ActForceLoadsPoints !< point mesh for transferring AeroDyn distributed loads to OpenFOAM [-] - TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: Line2_to_Line2_Loads !< mapping data structure to convert line2 loads to line2 loads [-] - TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: Line2_to_Line2_Motions !< mapping data structure to convert line2 loads to line2 motions [-] + TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: ActForceMotionsPoints !< point mesh for transferring AeroDyn motions to OpenFOAM (includes hub+blades+nacelle+tower+tailfin) [-] + TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: ActForceLoadsPoints !< point mesh for transferring AeroDyn distributed loads to OpenFOAM (includes hub+blades+nacelle+tower+tailfin) [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: Line2_to_Point_Loads !< mapping data structure to convert line2 loads to point loads [-] TYPE(MeshMapType) , DIMENSION(:), ALLOCATABLE :: Line2_to_Point_Motions !< mapping data structure to convert line2 loads to point motions [-] END TYPE OpFM_MiscVarType @@ -106,6 +104,7 @@ MODULE OpenFOAM_Types REAL(KIND=C_FLOAT) :: BladeLength REAL(KIND=C_FLOAT) :: TowerHeight REAL(KIND=C_FLOAT) :: TowerBaseHeight + LOGICAL(KIND=C_BOOL) :: NodeClusterType END TYPE OpFM_ParameterType_C TYPE, PUBLIC :: OpFM_ParameterType TYPE( OpFM_ParameterType_C ) :: C_obj @@ -116,11 +115,12 @@ MODULE OpenFOAM_Types INTEGER(IntKi) :: NnodesForce !< number of force nodes on FAST v8-OpenFOAM interface [-] INTEGER(IntKi) :: NnodesForceBlade !< number of force nodes on FAST v8-OpenFOAM interface [-] INTEGER(IntKi) :: NnodesForceTower !< number of force nodes on FAST v8-OpenFOAM interface [-] - REAL(KIND=C_FLOAT) , DIMENSION(:), POINTER :: forceBldRnodes => NULL() - REAL(KIND=C_FLOAT) , DIMENSION(:), POINTER :: forceTwrHnodes => NULL() + REAL(KIND=C_FLOAT) , DIMENSION(:), POINTER :: forceBldRnodes => NULL() !< Radial location of force nodes [-] + REAL(KIND=C_FLOAT) , DIMENSION(:), POINTER :: forceTwrHnodes => NULL() !< Vertical location of force nodes [-] REAL(ReKi) :: BladeLength !< Blade length (same for all blades) [m] REAL(ReKi) :: TowerHeight !< Tower height [m] REAL(ReKi) :: TowerBaseHeight !< Tower base height [m] + INTEGER(IntKi) :: NodeClusterType !< Node clustering (0 - Uniform, 1 - Non-uniform clustered towards tip) [-] END TYPE OpFM_ParameterType ! ======================= ! ========= OpFM_InputType_C ======= @@ -233,7 +233,7 @@ SUBROUTINE OpFM_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Err END IF DstInitInputData%c_obj%StructBldRNodes_Len = SIZE(DstInitInputData%StructBldRNodes) IF (DstInitInputData%c_obj%StructBldRNodes_Len > 0) & - DstInitInputData%c_obj%StructBldRNodes = C_LOC( DstInitInputData%StructBldRNodes(i1_l) ) + DstInitInputData%c_obj%StructBldRNodes = C_LOC( DstInitInputData%StructBldRNodes( i1_l ) ) END IF DstInitInputData%StructBldRNodes = SrcInitInputData%StructBldRNodes ENDIF @@ -248,7 +248,7 @@ SUBROUTINE OpFM_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Err END IF DstInitInputData%c_obj%StructTwrHNodes_Len = SIZE(DstInitInputData%StructTwrHNodes) IF (DstInitInputData%c_obj%StructTwrHNodes_Len > 0) & - DstInitInputData%c_obj%StructTwrHNodes = C_LOC( DstInitInputData%StructTwrHNodes(i1_l) ) + DstInitInputData%c_obj%StructTwrHNodes = C_LOC( DstInitInputData%StructTwrHNodes( i1_l ) ) END IF DstInitInputData%StructTwrHNodes = SrcInitInputData%StructTwrHNodes ENDIF @@ -258,24 +258,40 @@ SUBROUTINE OpFM_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Err DstInitInputData%C_obj%TowerHeight = SrcInitInputData%C_obj%TowerHeight DstInitInputData%TowerBaseHeight = SrcInitInputData%TowerBaseHeight DstInitInputData%C_obj%TowerBaseHeight = SrcInitInputData%C_obj%TowerBaseHeight + DstInitInputData%NodeClusterType = SrcInitInputData%NodeClusterType + DstInitInputData%C_obj%NodeClusterType = SrcInitInputData%C_obj%NodeClusterType END SUBROUTINE OpFM_CopyInitInput - SUBROUTINE OpFM_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE OpFM_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(OpFM_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(InitInputData%StructBldRNodes)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InitInputData%StructBldRNodes) InitInputData%StructBldRNodes => NULL() InitInputData%C_obj%StructBldRNodes = C_NULL_PTR InitInputData%C_obj%StructBldRNodes_Len = 0 ENDIF IF (ASSOCIATED(InitInputData%StructTwrHNodes)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InitInputData%StructTwrHNodes) InitInputData%StructTwrHNodes => NULL() InitInputData%C_obj%StructTwrHNodes = C_NULL_PTR @@ -333,6 +349,7 @@ SUBROUTINE OpFM_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Re_BufSz = Re_BufSz + 1 ! BladeLength Re_BufSz = Re_BufSz + 1 ! TowerHeight Re_BufSz = Re_BufSz + 1 ! TowerBaseHeight + Int_BufSz = Int_BufSz + 1 ! NodeClusterType IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -402,6 +419,8 @@ SUBROUTINE OpFM_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%TowerBaseHeight Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%NodeClusterType, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE OpFM_PackInitInput SUBROUTINE OpFM_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -452,7 +471,7 @@ SUBROUTINE OpFM_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%StructBldRNodes_Len = SIZE(OutData%StructBldRNodes) IF (OutData%c_obj%StructBldRNodes_Len > 0) & - OutData%c_obj%StructBldRNodes = C_LOC( OutData%StructBldRNodes(i1_l) ) + OutData%c_obj%StructBldRNodes = C_LOC( OutData%StructBldRNodes( i1_l ) ) DO i1 = LBOUND(OutData%StructBldRNodes,1), UBOUND(OutData%StructBldRNodes,1) OutData%StructBldRNodes(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -473,7 +492,7 @@ SUBROUTINE OpFM_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E END IF OutData%c_obj%StructTwrHNodes_Len = SIZE(OutData%StructTwrHNodes) IF (OutData%c_obj%StructTwrHNodes_Len > 0) & - OutData%c_obj%StructTwrHNodes = C_LOC( OutData%StructTwrHNodes(i1_l) ) + OutData%c_obj%StructTwrHNodes = C_LOC( OutData%StructTwrHNodes( i1_l ) ) DO i1 = LBOUND(OutData%StructTwrHNodes,1), UBOUND(OutData%StructTwrHNodes,1) OutData%StructTwrHNodes(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -488,6 +507,9 @@ SUBROUTINE OpFM_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E OutData%TowerBaseHeight = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%C_obj%TowerBaseHeight = OutData%TowerBaseHeight + OutData%NodeClusterType = TRANSFER(IntKiBuf(Int_Xferred), OutData%NodeClusterType) + Int_Xferred = Int_Xferred + 1 + OutData%C_obj%NodeClusterType = OutData%NodeClusterType END SUBROUTINE OpFM_UnPackInitInput SUBROUTINE OpFM_C2Fary_CopyInitInput( InitInputData, ErrStat, ErrMsg, SkipPointers ) @@ -528,6 +550,7 @@ SUBROUTINE OpFM_C2Fary_CopyInitInput( InitInputData, ErrStat, ErrMsg, SkipPointe InitInputData%BladeLength = InitInputData%C_obj%BladeLength InitInputData%TowerHeight = InitInputData%C_obj%TowerHeight InitInputData%TowerBaseHeight = InitInputData%C_obj%TowerBaseHeight + InitInputData%NodeClusterType = InitInputData%C_obj%NodeClusterType END SUBROUTINE OpFM_C2Fary_CopyInitInput SUBROUTINE OpFM_F2C_CopyInitInput( InitInputData, ErrStat, ErrMsg, SkipPointers ) @@ -556,7 +579,7 @@ SUBROUTINE OpFM_F2C_CopyInitInput( InitInputData, ErrStat, ErrMsg, SkipPointers ELSE InitInputData%c_obj%StructBldRNodes_Len = SIZE(InitInputData%StructBldRNodes) IF (InitInputData%c_obj%StructBldRNodes_Len > 0) & - InitInputData%c_obj%StructBldRNodes = C_LOC( InitInputData%StructBldRNodes( LBOUND(InitInputData%StructBldRNodes,1) ) ) + InitInputData%c_obj%StructBldRNodes = C_LOC( InitInputData%StructBldRNodes( LBOUND(InitInputData%StructBldRNodes,1) ) ) END IF END IF @@ -568,12 +591,13 @@ SUBROUTINE OpFM_F2C_CopyInitInput( InitInputData, ErrStat, ErrMsg, SkipPointers ELSE InitInputData%c_obj%StructTwrHNodes_Len = SIZE(InitInputData%StructTwrHNodes) IF (InitInputData%c_obj%StructTwrHNodes_Len > 0) & - InitInputData%c_obj%StructTwrHNodes = C_LOC( InitInputData%StructTwrHNodes( LBOUND(InitInputData%StructTwrHNodes,1) ) ) + InitInputData%c_obj%StructTwrHNodes = C_LOC( InitInputData%StructTwrHNodes( LBOUND(InitInputData%StructTwrHNodes,1) ) ) END IF END IF InitInputData%C_obj%BladeLength = InitInputData%BladeLength InitInputData%C_obj%TowerHeight = InitInputData%TowerHeight InitInputData%C_obj%TowerBaseHeight = InitInputData%TowerBaseHeight + InitInputData%C_obj%NodeClusterType = InitInputData%NodeClusterType END SUBROUTINE OpFM_F2C_CopyInitInput SUBROUTINE OpFM_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -620,22 +644,35 @@ SUBROUTINE OpFM_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE OpFM_CopyInitOutput - SUBROUTINE OpFM_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE OpFM_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(OpFM_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN DEALLOCATE(InitOutputData%WriteOutputUnt) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE OpFM_DestroyInitOutput SUBROUTINE OpFM_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -952,38 +989,6 @@ SUBROUTINE OpFM_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcMiscData%ActForceLoads)) THEN - i1_l = LBOUND(SrcMiscData%ActForceLoads,1) - i1_u = UBOUND(SrcMiscData%ActForceLoads,1) - IF (.NOT. ALLOCATED(DstMiscData%ActForceLoads)) THEN - ALLOCATE(DstMiscData%ActForceLoads(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%ActForceLoads.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcMiscData%ActForceLoads,1), UBOUND(SrcMiscData%ActForceLoads,1) - CALL MeshCopy( SrcMiscData%ActForceLoads(i1), DstMiscData%ActForceLoads(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF -IF (ALLOCATED(SrcMiscData%ActForceMotions)) THEN - i1_l = LBOUND(SrcMiscData%ActForceMotions,1) - i1_u = UBOUND(SrcMiscData%ActForceMotions,1) - IF (.NOT. ALLOCATED(DstMiscData%ActForceMotions)) THEN - ALLOCATE(DstMiscData%ActForceMotions(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%ActForceMotions.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcMiscData%ActForceMotions,1), UBOUND(SrcMiscData%ActForceMotions,1) - CALL MeshCopy( SrcMiscData%ActForceMotions(i1), DstMiscData%ActForceMotions(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF IF (ALLOCATED(SrcMiscData%ActForceMotionsPoints)) THEN i1_l = LBOUND(SrcMiscData%ActForceMotionsPoints,1) i1_u = UBOUND(SrcMiscData%ActForceMotionsPoints,1) @@ -1016,38 +1021,6 @@ SUBROUTINE OpFM_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) IF (ErrStat>=AbortErrLev) RETURN ENDDO ENDIF -IF (ALLOCATED(SrcMiscData%Line2_to_Line2_Loads)) THEN - i1_l = LBOUND(SrcMiscData%Line2_to_Line2_Loads,1) - i1_u = UBOUND(SrcMiscData%Line2_to_Line2_Loads,1) - IF (.NOT. ALLOCATED(DstMiscData%Line2_to_Line2_Loads)) THEN - ALLOCATE(DstMiscData%Line2_to_Line2_Loads(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%Line2_to_Line2_Loads.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcMiscData%Line2_to_Line2_Loads,1), UBOUND(SrcMiscData%Line2_to_Line2_Loads,1) - CALL NWTC_Library_Copymeshmaptype( SrcMiscData%Line2_to_Line2_Loads(i1), DstMiscData%Line2_to_Line2_Loads(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF -IF (ALLOCATED(SrcMiscData%Line2_to_Line2_Motions)) THEN - i1_l = LBOUND(SrcMiscData%Line2_to_Line2_Motions,1) - i1_u = UBOUND(SrcMiscData%Line2_to_Line2_Motions,1) - IF (.NOT. ALLOCATED(DstMiscData%Line2_to_Line2_Motions)) THEN - ALLOCATE(DstMiscData%Line2_to_Line2_Motions(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%Line2_to_Line2_Motions.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DO i1 = LBOUND(SrcMiscData%Line2_to_Line2_Motions,1), UBOUND(SrcMiscData%Line2_to_Line2_Motions,1) - CALL NWTC_Library_Copymeshmaptype( SrcMiscData%Line2_to_Line2_Motions(i1), DstMiscData%Line2_to_Line2_Motions(i1), CtrlCode, ErrStat2, ErrMsg2 ) - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) - IF (ErrStat>=AbortErrLev) RETURN - ENDDO -ENDIF IF (ALLOCATED(SrcMiscData%Line2_to_Point_Loads)) THEN i1_l = LBOUND(SrcMiscData%Line2_to_Point_Loads,1) i1_u = UBOUND(SrcMiscData%Line2_to_Point_Loads,1) @@ -1082,60 +1055,52 @@ SUBROUTINE OpFM_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) ENDIF END SUBROUTINE OpFM_CopyMisc - SUBROUTINE OpFM_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE OpFM_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(OpFM_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(MiscData%ActForceLoads)) THEN -DO i1 = LBOUND(MiscData%ActForceLoads,1), UBOUND(MiscData%ActForceLoads,1) - CALL MeshDestroy( MiscData%ActForceLoads(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(MiscData%ActForceLoads) -ENDIF -IF (ALLOCATED(MiscData%ActForceMotions)) THEN -DO i1 = LBOUND(MiscData%ActForceMotions,1), UBOUND(MiscData%ActForceMotions,1) - CALL MeshDestroy( MiscData%ActForceMotions(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(MiscData%ActForceMotions) -ENDIF + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%ActForceMotionsPoints)) THEN DO i1 = LBOUND(MiscData%ActForceMotionsPoints,1), UBOUND(MiscData%ActForceMotionsPoints,1) - CALL MeshDestroy( MiscData%ActForceMotionsPoints(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( MiscData%ActForceMotionsPoints(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%ActForceMotionsPoints) ENDIF IF (ALLOCATED(MiscData%ActForceLoadsPoints)) THEN DO i1 = LBOUND(MiscData%ActForceLoadsPoints,1), UBOUND(MiscData%ActForceLoadsPoints,1) - CALL MeshDestroy( MiscData%ActForceLoadsPoints(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( MiscData%ActForceLoadsPoints(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%ActForceLoadsPoints) ENDIF -IF (ALLOCATED(MiscData%Line2_to_Line2_Loads)) THEN -DO i1 = LBOUND(MiscData%Line2_to_Line2_Loads,1), UBOUND(MiscData%Line2_to_Line2_Loads,1) - CALL NWTC_Library_Destroymeshmaptype( MiscData%Line2_to_Line2_Loads(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(MiscData%Line2_to_Line2_Loads) -ENDIF -IF (ALLOCATED(MiscData%Line2_to_Line2_Motions)) THEN -DO i1 = LBOUND(MiscData%Line2_to_Line2_Motions,1), UBOUND(MiscData%Line2_to_Line2_Motions,1) - CALL NWTC_Library_Destroymeshmaptype( MiscData%Line2_to_Line2_Motions(i1), ErrStat, ErrMsg ) -ENDDO - DEALLOCATE(MiscData%Line2_to_Line2_Motions) -ENDIF IF (ALLOCATED(MiscData%Line2_to_Point_Loads)) THEN DO i1 = LBOUND(MiscData%Line2_to_Point_Loads,1), UBOUND(MiscData%Line2_to_Point_Loads,1) - CALL NWTC_Library_Destroymeshmaptype( MiscData%Line2_to_Point_Loads(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( MiscData%Line2_to_Point_Loads(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%Line2_to_Point_Loads) ENDIF IF (ALLOCATED(MiscData%Line2_to_Point_Motions)) THEN DO i1 = LBOUND(MiscData%Line2_to_Point_Motions,1), UBOUND(MiscData%Line2_to_Point_Motions,1) - CALL NWTC_Library_Destroymeshmaptype( MiscData%Line2_to_Point_Motions(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( MiscData%Line2_to_Point_Motions(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%Line2_to_Point_Motions) ENDIF @@ -1176,56 +1141,10 @@ SUBROUTINE OpFM_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! ActForceLoads allocated yes/no - IF ( ALLOCATED(InData%ActForceLoads) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! ActForceLoads upper/lower bounds for each dimension - ! Allocate buffers for subtypes, if any (we'll get sizes from these) - DO i1 = LBOUND(InData%ActForceLoads,1), UBOUND(InData%ActForceLoads,1) - Int_BufSz = Int_BufSz + 3 ! ActForceLoads: size of buffers for each call to pack subtype - CALL MeshPack( InData%ActForceLoads(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! ActForceLoads - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! ActForceLoads - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! ActForceLoads - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! ActForceLoads - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - END IF - Int_BufSz = Int_BufSz + 1 ! ActForceMotions allocated yes/no - IF ( ALLOCATED(InData%ActForceMotions) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! ActForceMotions upper/lower bounds for each dimension - DO i1 = LBOUND(InData%ActForceMotions,1), UBOUND(InData%ActForceMotions,1) - Int_BufSz = Int_BufSz + 3 ! ActForceMotions: size of buffers for each call to pack subtype - CALL MeshPack( InData%ActForceMotions(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! ActForceMotions - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! ActForceMotions - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! ActForceMotions - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! ActForceMotions - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - END IF Int_BufSz = Int_BufSz + 1 ! ActForceMotionsPoints allocated yes/no IF ( ALLOCATED(InData%ActForceMotionsPoints) ) THEN Int_BufSz = Int_BufSz + 2*1 ! ActForceMotionsPoints upper/lower bounds for each dimension + ! Allocate buffers for subtypes, if any (we'll get sizes from these) DO i1 = LBOUND(InData%ActForceMotionsPoints,1), UBOUND(InData%ActForceMotionsPoints,1) Int_BufSz = Int_BufSz + 3 ! ActForceMotionsPoints: size of buffers for each call to pack subtype CALL MeshPack( InData%ActForceMotionsPoints(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! ActForceMotionsPoints @@ -1269,52 +1188,6 @@ SUBROUTINE OpFM_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S END IF END DO END IF - Int_BufSz = Int_BufSz + 1 ! Line2_to_Line2_Loads allocated yes/no - IF ( ALLOCATED(InData%Line2_to_Line2_Loads) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Line2_to_Line2_Loads upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Line2_to_Line2_Loads,1), UBOUND(InData%Line2_to_Line2_Loads,1) - Int_BufSz = Int_BufSz + 3 ! Line2_to_Line2_Loads: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%Line2_to_Line2_Loads(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Line2_to_Line2_Loads - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Line2_to_Line2_Loads - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Line2_to_Line2_Loads - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Line2_to_Line2_Loads - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - END IF - Int_BufSz = Int_BufSz + 1 ! Line2_to_Line2_Motions allocated yes/no - IF ( ALLOCATED(InData%Line2_to_Line2_Motions) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Line2_to_Line2_Motions upper/lower bounds for each dimension - DO i1 = LBOUND(InData%Line2_to_Line2_Motions,1), UBOUND(InData%Line2_to_Line2_Motions,1) - Int_BufSz = Int_BufSz + 3 ! Line2_to_Line2_Motions: size of buffers for each call to pack subtype - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%Line2_to_Line2_Motions(i1), ErrStat2, ErrMsg2, .TRUE. ) ! Line2_to_Line2_Motions - CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) - IF (ErrStat >= AbortErrLev) RETURN - - IF(ALLOCATED(Re_Buf)) THEN ! Line2_to_Line2_Motions - Re_BufSz = Re_BufSz + SIZE( Re_Buf ) - DEALLOCATE(Re_Buf) - END IF - IF(ALLOCATED(Db_Buf)) THEN ! Line2_to_Line2_Motions - Db_BufSz = Db_BufSz + SIZE( Db_Buf ) - DEALLOCATE(Db_Buf) - END IF - IF(ALLOCATED(Int_Buf)) THEN ! Line2_to_Line2_Motions - Int_BufSz = Int_BufSz + SIZE( Int_Buf ) - DEALLOCATE(Int_Buf) - END IF - END DO - END IF Int_BufSz = Int_BufSz + 1 ! Line2_to_Point_Loads allocated yes/no IF ( ALLOCATED(InData%Line2_to_Point_Loads) ) THEN Int_BufSz = Int_BufSz + 2*1 ! Line2_to_Point_Loads upper/lower bounds for each dimension @@ -1390,88 +1263,6 @@ SUBROUTINE OpFM_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Db_Xferred = 1 Int_Xferred = 1 - IF ( .NOT. ALLOCATED(InData%ActForceLoads) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%ActForceLoads,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ActForceLoads,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%ActForceLoads,1), UBOUND(InData%ActForceLoads,1) - CALL MeshPack( InData%ActForceLoads(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! ActForceLoads - 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%ActForceMotions) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%ActForceMotions,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%ActForceMotions,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%ActForceMotions,1), UBOUND(InData%ActForceMotions,1) - CALL MeshPack( InData%ActForceMotions(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! ActForceMotions - 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%ActForceMotionsPoints) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -1554,88 +1345,6 @@ SUBROUTINE OpFM_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S ENDIF END DO END IF - IF ( .NOT. ALLOCATED(InData%Line2_to_Line2_Loads) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Line2_to_Line2_Loads,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Line2_to_Line2_Loads,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%Line2_to_Line2_Loads,1), UBOUND(InData%Line2_to_Line2_Loads,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%Line2_to_Line2_Loads(i1), ErrStat2, ErrMsg2, OnlySize ) ! Line2_to_Line2_Loads - 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%Line2_to_Line2_Motions) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Line2_to_Line2_Motions,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Line2_to_Line2_Motions,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%Line2_to_Line2_Motions,1), UBOUND(InData%Line2_to_Line2_Motions,1) - CALL NWTC_Library_Packmeshmaptype( Re_Buf, Db_Buf, Int_Buf, InData%Line2_to_Line2_Motions(i1), ErrStat2, ErrMsg2, OnlySize ) ! Line2_to_Line2_Motions - 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%Line2_to_Point_Loads) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -1747,118 +1456,6 @@ SUBROUTINE OpFM_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! ActForceLoads not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%ActForceLoads)) DEALLOCATE(OutData%ActForceLoads) - ALLOCATE(OutData%ActForceLoads(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ActForceLoads.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%ActForceLoads,1), UBOUND(OutData%ActForceLoads,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%ActForceLoads(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! ActForceLoads - 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 ! ActForceMotions not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%ActForceMotions)) DEALLOCATE(OutData%ActForceMotions) - ALLOCATE(OutData%ActForceMotions(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%ActForceMotions.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%ActForceMotions,1), UBOUND(OutData%ActForceMotions,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%ActForceMotions(i1), Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! ActForceMotions - 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 ! ActForceMotionsPoints not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -1971,118 +1568,6 @@ SUBROUTINE OpFM_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Line2_to_Line2_Loads not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Line2_to_Line2_Loads)) DEALLOCATE(OutData%Line2_to_Line2_Loads) - ALLOCATE(OutData%Line2_to_Line2_Loads(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Line2_to_Line2_Loads.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%Line2_to_Line2_Loads,1), UBOUND(OutData%Line2_to_Line2_Loads,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%Line2_to_Line2_Loads(i1), ErrStat2, ErrMsg2 ) ! Line2_to_Line2_Loads - 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 ! Line2_to_Line2_Motions not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Line2_to_Line2_Motions)) DEALLOCATE(OutData%Line2_to_Line2_Motions) - ALLOCATE(OutData%Line2_to_Line2_Motions(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Line2_to_Line2_Motions.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%Line2_to_Line2_Motions,1), UBOUND(OutData%Line2_to_Line2_Motions,1) - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 ) - Re_Xferred = Re_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 ) - Db_Xferred = Db_Xferred + Buf_size - END IF - Buf_size=IntKiBuf( Int_Xferred ) - Int_Xferred = Int_Xferred + 1 - IF(Buf_size > 0) THEN - ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 ) - Int_Xferred = Int_Xferred + Buf_size - END IF - CALL NWTC_Library_Unpackmeshmaptype( Re_Buf, Db_Buf, Int_Buf, OutData%Line2_to_Line2_Motions(i1), ErrStat2, ErrMsg2 ) ! Line2_to_Line2_Motions - 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 ! Line2_to_Point_Loads not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -2271,7 +1756,7 @@ SUBROUTINE OpFM_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg END IF DstParamData%c_obj%forceBldRnodes_Len = SIZE(DstParamData%forceBldRnodes) IF (DstParamData%c_obj%forceBldRnodes_Len > 0) & - DstParamData%c_obj%forceBldRnodes = C_LOC( DstParamData%forceBldRnodes(i1_l) ) + DstParamData%c_obj%forceBldRnodes = C_LOC( DstParamData%forceBldRnodes( i1_l ) ) END IF DstParamData%forceBldRnodes = SrcParamData%forceBldRnodes ENDIF @@ -2286,7 +1771,7 @@ SUBROUTINE OpFM_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg END IF DstParamData%c_obj%forceTwrHnodes_Len = SIZE(DstParamData%forceTwrHnodes) IF (DstParamData%c_obj%forceTwrHnodes_Len > 0) & - DstParamData%c_obj%forceTwrHnodes = C_LOC( DstParamData%forceTwrHnodes(i1_l) ) + DstParamData%c_obj%forceTwrHnodes = C_LOC( DstParamData%forceTwrHnodes( i1_l ) ) END IF DstParamData%forceTwrHnodes = SrcParamData%forceTwrHnodes ENDIF @@ -2296,24 +1781,40 @@ SUBROUTINE OpFM_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%C_obj%TowerHeight = SrcParamData%C_obj%TowerHeight DstParamData%TowerBaseHeight = SrcParamData%TowerBaseHeight DstParamData%C_obj%TowerBaseHeight = SrcParamData%C_obj%TowerBaseHeight + DstParamData%NodeClusterType = SrcParamData%NodeClusterType + DstParamData%C_obj%NodeClusterType = SrcParamData%C_obj%NodeClusterType END SUBROUTINE OpFM_CopyParam - SUBROUTINE OpFM_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE OpFM_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(OpFM_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(ParamData%forceBldRnodes)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(ParamData%forceBldRnodes) ParamData%forceBldRnodes => NULL() ParamData%C_obj%forceBldRnodes = C_NULL_PTR ParamData%C_obj%forceBldRnodes_Len = 0 ENDIF IF (ASSOCIATED(ParamData%forceTwrHnodes)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(ParamData%forceTwrHnodes) ParamData%forceTwrHnodes => NULL() ParamData%C_obj%forceTwrHnodes = C_NULL_PTR @@ -2376,6 +1877,7 @@ SUBROUTINE OpFM_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Re_BufSz = Re_BufSz + 1 ! BladeLength Re_BufSz = Re_BufSz + 1 ! TowerHeight Re_BufSz = Re_BufSz + 1 ! TowerBaseHeight + Int_BufSz = Int_BufSz + 1 ! NodeClusterType IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -2455,6 +1957,8 @@ SUBROUTINE OpFM_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%TowerBaseHeight Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%NodeClusterType, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 END SUBROUTINE OpFM_PackParam SUBROUTINE OpFM_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -2520,7 +2024,7 @@ SUBROUTINE OpFM_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%forceBldRnodes_Len = SIZE(OutData%forceBldRnodes) IF (OutData%c_obj%forceBldRnodes_Len > 0) & - OutData%c_obj%forceBldRnodes = C_LOC( OutData%forceBldRnodes(i1_l) ) + OutData%c_obj%forceBldRnodes = C_LOC( OutData%forceBldRnodes( i1_l ) ) DO i1 = LBOUND(OutData%forceBldRnodes,1), UBOUND(OutData%forceBldRnodes,1) OutData%forceBldRnodes(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -2541,7 +2045,7 @@ SUBROUTINE OpFM_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%forceTwrHnodes_Len = SIZE(OutData%forceTwrHnodes) IF (OutData%c_obj%forceTwrHnodes_Len > 0) & - OutData%c_obj%forceTwrHnodes = C_LOC( OutData%forceTwrHnodes(i1_l) ) + OutData%c_obj%forceTwrHnodes = C_LOC( OutData%forceTwrHnodes( i1_l ) ) DO i1 = LBOUND(OutData%forceTwrHnodes,1), UBOUND(OutData%forceTwrHnodes,1) OutData%forceTwrHnodes(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -2556,6 +2060,9 @@ SUBROUTINE OpFM_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs OutData%TowerBaseHeight = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%C_obj%TowerBaseHeight = OutData%TowerBaseHeight + OutData%NodeClusterType = TRANSFER(IntKiBuf(Int_Xferred), OutData%NodeClusterType) + Int_Xferred = Int_Xferred + 1 + OutData%C_obj%NodeClusterType = OutData%NodeClusterType END SUBROUTINE OpFM_UnPackParam SUBROUTINE OpFM_C2Fary_CopyParam( ParamData, ErrStat, ErrMsg, SkipPointers ) @@ -2601,6 +2108,7 @@ SUBROUTINE OpFM_C2Fary_CopyParam( ParamData, ErrStat, ErrMsg, SkipPointers ) ParamData%BladeLength = ParamData%C_obj%BladeLength ParamData%TowerHeight = ParamData%C_obj%TowerHeight ParamData%TowerBaseHeight = ParamData%C_obj%TowerBaseHeight + ParamData%NodeClusterType = ParamData%C_obj%NodeClusterType END SUBROUTINE OpFM_C2Fary_CopyParam SUBROUTINE OpFM_F2C_CopyParam( ParamData, ErrStat, ErrMsg, SkipPointers ) @@ -2634,7 +2142,7 @@ SUBROUTINE OpFM_F2C_CopyParam( ParamData, ErrStat, ErrMsg, SkipPointers ) ELSE ParamData%c_obj%forceBldRnodes_Len = SIZE(ParamData%forceBldRnodes) IF (ParamData%c_obj%forceBldRnodes_Len > 0) & - ParamData%c_obj%forceBldRnodes = C_LOC( ParamData%forceBldRnodes( LBOUND(ParamData%forceBldRnodes,1) ) ) + ParamData%c_obj%forceBldRnodes = C_LOC( ParamData%forceBldRnodes( LBOUND(ParamData%forceBldRnodes,1) ) ) END IF END IF @@ -2646,12 +2154,13 @@ SUBROUTINE OpFM_F2C_CopyParam( ParamData, ErrStat, ErrMsg, SkipPointers ) ELSE ParamData%c_obj%forceTwrHnodes_Len = SIZE(ParamData%forceTwrHnodes) IF (ParamData%c_obj%forceTwrHnodes_Len > 0) & - ParamData%c_obj%forceTwrHnodes = C_LOC( ParamData%forceTwrHnodes( LBOUND(ParamData%forceTwrHnodes,1) ) ) + ParamData%c_obj%forceTwrHnodes = C_LOC( ParamData%forceTwrHnodes( LBOUND(ParamData%forceTwrHnodes,1) ) ) END IF END IF ParamData%C_obj%BladeLength = ParamData%BladeLength ParamData%C_obj%TowerHeight = ParamData%TowerHeight ParamData%C_obj%TowerBaseHeight = ParamData%TowerBaseHeight + ParamData%C_obj%NodeClusterType = ParamData%NodeClusterType END SUBROUTINE OpFM_F2C_CopyParam SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) @@ -2680,7 +2189,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%pxVel_Len = SIZE(DstInputData%pxVel) IF (DstInputData%c_obj%pxVel_Len > 0) & - DstInputData%c_obj%pxVel = C_LOC( DstInputData%pxVel(i1_l) ) + DstInputData%c_obj%pxVel = C_LOC( DstInputData%pxVel( i1_l ) ) END IF DstInputData%pxVel = SrcInputData%pxVel ENDIF @@ -2695,7 +2204,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%pyVel_Len = SIZE(DstInputData%pyVel) IF (DstInputData%c_obj%pyVel_Len > 0) & - DstInputData%c_obj%pyVel = C_LOC( DstInputData%pyVel(i1_l) ) + DstInputData%c_obj%pyVel = C_LOC( DstInputData%pyVel( i1_l ) ) END IF DstInputData%pyVel = SrcInputData%pyVel ENDIF @@ -2710,7 +2219,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%pzVel_Len = SIZE(DstInputData%pzVel) IF (DstInputData%c_obj%pzVel_Len > 0) & - DstInputData%c_obj%pzVel = C_LOC( DstInputData%pzVel(i1_l) ) + DstInputData%c_obj%pzVel = C_LOC( DstInputData%pzVel( i1_l ) ) END IF DstInputData%pzVel = SrcInputData%pzVel ENDIF @@ -2725,7 +2234,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%pxForce_Len = SIZE(DstInputData%pxForce) IF (DstInputData%c_obj%pxForce_Len > 0) & - DstInputData%c_obj%pxForce = C_LOC( DstInputData%pxForce(i1_l) ) + DstInputData%c_obj%pxForce = C_LOC( DstInputData%pxForce( i1_l ) ) END IF DstInputData%pxForce = SrcInputData%pxForce ENDIF @@ -2740,7 +2249,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%pyForce_Len = SIZE(DstInputData%pyForce) IF (DstInputData%c_obj%pyForce_Len > 0) & - DstInputData%c_obj%pyForce = C_LOC( DstInputData%pyForce(i1_l) ) + DstInputData%c_obj%pyForce = C_LOC( DstInputData%pyForce( i1_l ) ) END IF DstInputData%pyForce = SrcInputData%pyForce ENDIF @@ -2755,7 +2264,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%pzForce_Len = SIZE(DstInputData%pzForce) IF (DstInputData%c_obj%pzForce_Len > 0) & - DstInputData%c_obj%pzForce = C_LOC( DstInputData%pzForce(i1_l) ) + DstInputData%c_obj%pzForce = C_LOC( DstInputData%pzForce( i1_l ) ) END IF DstInputData%pzForce = SrcInputData%pzForce ENDIF @@ -2770,7 +2279,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%xdotForce_Len = SIZE(DstInputData%xdotForce) IF (DstInputData%c_obj%xdotForce_Len > 0) & - DstInputData%c_obj%xdotForce = C_LOC( DstInputData%xdotForce(i1_l) ) + DstInputData%c_obj%xdotForce = C_LOC( DstInputData%xdotForce( i1_l ) ) END IF DstInputData%xdotForce = SrcInputData%xdotForce ENDIF @@ -2785,7 +2294,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%ydotForce_Len = SIZE(DstInputData%ydotForce) IF (DstInputData%c_obj%ydotForce_Len > 0) & - DstInputData%c_obj%ydotForce = C_LOC( DstInputData%ydotForce(i1_l) ) + DstInputData%c_obj%ydotForce = C_LOC( DstInputData%ydotForce( i1_l ) ) END IF DstInputData%ydotForce = SrcInputData%ydotForce ENDIF @@ -2800,7 +2309,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%zdotForce_Len = SIZE(DstInputData%zdotForce) IF (DstInputData%c_obj%zdotForce_Len > 0) & - DstInputData%c_obj%zdotForce = C_LOC( DstInputData%zdotForce(i1_l) ) + DstInputData%c_obj%zdotForce = C_LOC( DstInputData%zdotForce( i1_l ) ) END IF DstInputData%zdotForce = SrcInputData%zdotForce ENDIF @@ -2815,7 +2324,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%pOrientation_Len = SIZE(DstInputData%pOrientation) IF (DstInputData%c_obj%pOrientation_Len > 0) & - DstInputData%c_obj%pOrientation = C_LOC( DstInputData%pOrientation(i1_l) ) + DstInputData%c_obj%pOrientation = C_LOC( DstInputData%pOrientation( i1_l ) ) END IF DstInputData%pOrientation = SrcInputData%pOrientation ENDIF @@ -2830,7 +2339,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%fx_Len = SIZE(DstInputData%fx) IF (DstInputData%c_obj%fx_Len > 0) & - DstInputData%c_obj%fx = C_LOC( DstInputData%fx(i1_l) ) + DstInputData%c_obj%fx = C_LOC( DstInputData%fx( i1_l ) ) END IF DstInputData%fx = SrcInputData%fx ENDIF @@ -2845,7 +2354,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%fy_Len = SIZE(DstInputData%fy) IF (DstInputData%c_obj%fy_Len > 0) & - DstInputData%c_obj%fy = C_LOC( DstInputData%fy(i1_l) ) + DstInputData%c_obj%fy = C_LOC( DstInputData%fy( i1_l ) ) END IF DstInputData%fy = SrcInputData%fy ENDIF @@ -2860,7 +2369,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%fz_Len = SIZE(DstInputData%fz) IF (DstInputData%c_obj%fz_Len > 0) & - DstInputData%c_obj%fz = C_LOC( DstInputData%fz(i1_l) ) + DstInputData%c_obj%fz = C_LOC( DstInputData%fz( i1_l ) ) END IF DstInputData%fz = SrcInputData%fz ENDIF @@ -2875,7 +2384,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%momentx_Len = SIZE(DstInputData%momentx) IF (DstInputData%c_obj%momentx_Len > 0) & - DstInputData%c_obj%momentx = C_LOC( DstInputData%momentx(i1_l) ) + DstInputData%c_obj%momentx = C_LOC( DstInputData%momentx( i1_l ) ) END IF DstInputData%momentx = SrcInputData%momentx ENDIF @@ -2890,7 +2399,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%momenty_Len = SIZE(DstInputData%momenty) IF (DstInputData%c_obj%momenty_Len > 0) & - DstInputData%c_obj%momenty = C_LOC( DstInputData%momenty(i1_l) ) + DstInputData%c_obj%momenty = C_LOC( DstInputData%momenty( i1_l ) ) END IF DstInputData%momenty = SrcInputData%momenty ENDIF @@ -2905,7 +2414,7 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%momentz_Len = SIZE(DstInputData%momentz) IF (DstInputData%c_obj%momentz_Len > 0) & - DstInputData%c_obj%momentz = C_LOC( DstInputData%momentz(i1_l) ) + DstInputData%c_obj%momentz = C_LOC( DstInputData%momentz( i1_l ) ) END IF DstInputData%momentz = SrcInputData%momentz ENDIF @@ -2920,118 +2429,147 @@ SUBROUTINE OpFM_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%c_obj%forceNodesChord_Len = SIZE(DstInputData%forceNodesChord) IF (DstInputData%c_obj%forceNodesChord_Len > 0) & - DstInputData%c_obj%forceNodesChord = C_LOC( DstInputData%forceNodesChord(i1_l) ) + DstInputData%c_obj%forceNodesChord = C_LOC( DstInputData%forceNodesChord( i1_l ) ) END IF DstInputData%forceNodesChord = SrcInputData%forceNodesChord ENDIF END SUBROUTINE OpFM_CopyInput - SUBROUTINE OpFM_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE OpFM_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(OpFM_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(InputData%pxVel)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%pxVel) InputData%pxVel => NULL() InputData%C_obj%pxVel = C_NULL_PTR InputData%C_obj%pxVel_Len = 0 ENDIF IF (ASSOCIATED(InputData%pyVel)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%pyVel) InputData%pyVel => NULL() InputData%C_obj%pyVel = C_NULL_PTR InputData%C_obj%pyVel_Len = 0 ENDIF IF (ASSOCIATED(InputData%pzVel)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%pzVel) InputData%pzVel => NULL() InputData%C_obj%pzVel = C_NULL_PTR InputData%C_obj%pzVel_Len = 0 ENDIF IF (ASSOCIATED(InputData%pxForce)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%pxForce) InputData%pxForce => NULL() InputData%C_obj%pxForce = C_NULL_PTR InputData%C_obj%pxForce_Len = 0 ENDIF IF (ASSOCIATED(InputData%pyForce)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%pyForce) InputData%pyForce => NULL() InputData%C_obj%pyForce = C_NULL_PTR InputData%C_obj%pyForce_Len = 0 ENDIF IF (ASSOCIATED(InputData%pzForce)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%pzForce) InputData%pzForce => NULL() InputData%C_obj%pzForce = C_NULL_PTR InputData%C_obj%pzForce_Len = 0 ENDIF IF (ASSOCIATED(InputData%xdotForce)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%xdotForce) InputData%xdotForce => NULL() InputData%C_obj%xdotForce = C_NULL_PTR InputData%C_obj%xdotForce_Len = 0 ENDIF IF (ASSOCIATED(InputData%ydotForce)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%ydotForce) InputData%ydotForce => NULL() InputData%C_obj%ydotForce = C_NULL_PTR InputData%C_obj%ydotForce_Len = 0 ENDIF IF (ASSOCIATED(InputData%zdotForce)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%zdotForce) InputData%zdotForce => NULL() InputData%C_obj%zdotForce = C_NULL_PTR InputData%C_obj%zdotForce_Len = 0 ENDIF IF (ASSOCIATED(InputData%pOrientation)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%pOrientation) InputData%pOrientation => NULL() InputData%C_obj%pOrientation = C_NULL_PTR InputData%C_obj%pOrientation_Len = 0 ENDIF IF (ASSOCIATED(InputData%fx)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%fx) InputData%fx => NULL() InputData%C_obj%fx = C_NULL_PTR InputData%C_obj%fx_Len = 0 ENDIF IF (ASSOCIATED(InputData%fy)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%fy) InputData%fy => NULL() InputData%C_obj%fy = C_NULL_PTR InputData%C_obj%fy_Len = 0 ENDIF IF (ASSOCIATED(InputData%fz)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%fz) InputData%fz => NULL() InputData%C_obj%fz = C_NULL_PTR InputData%C_obj%fz_Len = 0 ENDIF IF (ASSOCIATED(InputData%momentx)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%momentx) InputData%momentx => NULL() InputData%C_obj%momentx = C_NULL_PTR InputData%C_obj%momentx_Len = 0 ENDIF IF (ASSOCIATED(InputData%momenty)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%momenty) InputData%momenty => NULL() InputData%C_obj%momenty = C_NULL_PTR InputData%C_obj%momenty_Len = 0 ENDIF IF (ASSOCIATED(InputData%momentz)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%momentz) InputData%momentz => NULL() InputData%C_obj%momentz = C_NULL_PTR InputData%C_obj%momentz_Len = 0 ENDIF IF (ASSOCIATED(InputData%forceNodesChord)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%forceNodesChord) InputData%forceNodesChord => NULL() InputData%C_obj%forceNodesChord = C_NULL_PTR @@ -3487,7 +3025,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%pxVel_Len = SIZE(OutData%pxVel) IF (OutData%c_obj%pxVel_Len > 0) & - OutData%c_obj%pxVel = C_LOC( OutData%pxVel(i1_l) ) + OutData%c_obj%pxVel = C_LOC( OutData%pxVel( i1_l ) ) DO i1 = LBOUND(OutData%pxVel,1), UBOUND(OutData%pxVel,1) OutData%pxVel(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3508,7 +3046,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%pyVel_Len = SIZE(OutData%pyVel) IF (OutData%c_obj%pyVel_Len > 0) & - OutData%c_obj%pyVel = C_LOC( OutData%pyVel(i1_l) ) + OutData%c_obj%pyVel = C_LOC( OutData%pyVel( i1_l ) ) DO i1 = LBOUND(OutData%pyVel,1), UBOUND(OutData%pyVel,1) OutData%pyVel(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3529,7 +3067,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%pzVel_Len = SIZE(OutData%pzVel) IF (OutData%c_obj%pzVel_Len > 0) & - OutData%c_obj%pzVel = C_LOC( OutData%pzVel(i1_l) ) + OutData%c_obj%pzVel = C_LOC( OutData%pzVel( i1_l ) ) DO i1 = LBOUND(OutData%pzVel,1), UBOUND(OutData%pzVel,1) OutData%pzVel(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3550,7 +3088,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%pxForce_Len = SIZE(OutData%pxForce) IF (OutData%c_obj%pxForce_Len > 0) & - OutData%c_obj%pxForce = C_LOC( OutData%pxForce(i1_l) ) + OutData%c_obj%pxForce = C_LOC( OutData%pxForce( i1_l ) ) DO i1 = LBOUND(OutData%pxForce,1), UBOUND(OutData%pxForce,1) OutData%pxForce(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3571,7 +3109,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%pyForce_Len = SIZE(OutData%pyForce) IF (OutData%c_obj%pyForce_Len > 0) & - OutData%c_obj%pyForce = C_LOC( OutData%pyForce(i1_l) ) + OutData%c_obj%pyForce = C_LOC( OutData%pyForce( i1_l ) ) DO i1 = LBOUND(OutData%pyForce,1), UBOUND(OutData%pyForce,1) OutData%pyForce(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3592,7 +3130,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%pzForce_Len = SIZE(OutData%pzForce) IF (OutData%c_obj%pzForce_Len > 0) & - OutData%c_obj%pzForce = C_LOC( OutData%pzForce(i1_l) ) + OutData%c_obj%pzForce = C_LOC( OutData%pzForce( i1_l ) ) DO i1 = LBOUND(OutData%pzForce,1), UBOUND(OutData%pzForce,1) OutData%pzForce(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3613,7 +3151,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%xdotForce_Len = SIZE(OutData%xdotForce) IF (OutData%c_obj%xdotForce_Len > 0) & - OutData%c_obj%xdotForce = C_LOC( OutData%xdotForce(i1_l) ) + OutData%c_obj%xdotForce = C_LOC( OutData%xdotForce( i1_l ) ) DO i1 = LBOUND(OutData%xdotForce,1), UBOUND(OutData%xdotForce,1) OutData%xdotForce(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3634,7 +3172,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%ydotForce_Len = SIZE(OutData%ydotForce) IF (OutData%c_obj%ydotForce_Len > 0) & - OutData%c_obj%ydotForce = C_LOC( OutData%ydotForce(i1_l) ) + OutData%c_obj%ydotForce = C_LOC( OutData%ydotForce( i1_l ) ) DO i1 = LBOUND(OutData%ydotForce,1), UBOUND(OutData%ydotForce,1) OutData%ydotForce(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3655,7 +3193,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%zdotForce_Len = SIZE(OutData%zdotForce) IF (OutData%c_obj%zdotForce_Len > 0) & - OutData%c_obj%zdotForce = C_LOC( OutData%zdotForce(i1_l) ) + OutData%c_obj%zdotForce = C_LOC( OutData%zdotForce( i1_l ) ) DO i1 = LBOUND(OutData%zdotForce,1), UBOUND(OutData%zdotForce,1) OutData%zdotForce(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3676,7 +3214,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%pOrientation_Len = SIZE(OutData%pOrientation) IF (OutData%c_obj%pOrientation_Len > 0) & - OutData%c_obj%pOrientation = C_LOC( OutData%pOrientation(i1_l) ) + OutData%c_obj%pOrientation = C_LOC( OutData%pOrientation( i1_l ) ) DO i1 = LBOUND(OutData%pOrientation,1), UBOUND(OutData%pOrientation,1) OutData%pOrientation(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3697,7 +3235,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%fx_Len = SIZE(OutData%fx) IF (OutData%c_obj%fx_Len > 0) & - OutData%c_obj%fx = C_LOC( OutData%fx(i1_l) ) + OutData%c_obj%fx = C_LOC( OutData%fx( i1_l ) ) DO i1 = LBOUND(OutData%fx,1), UBOUND(OutData%fx,1) OutData%fx(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3718,7 +3256,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%fy_Len = SIZE(OutData%fy) IF (OutData%c_obj%fy_Len > 0) & - OutData%c_obj%fy = C_LOC( OutData%fy(i1_l) ) + OutData%c_obj%fy = C_LOC( OutData%fy( i1_l ) ) DO i1 = LBOUND(OutData%fy,1), UBOUND(OutData%fy,1) OutData%fy(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3739,7 +3277,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%fz_Len = SIZE(OutData%fz) IF (OutData%c_obj%fz_Len > 0) & - OutData%c_obj%fz = C_LOC( OutData%fz(i1_l) ) + OutData%c_obj%fz = C_LOC( OutData%fz( i1_l ) ) DO i1 = LBOUND(OutData%fz,1), UBOUND(OutData%fz,1) OutData%fz(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3760,7 +3298,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%momentx_Len = SIZE(OutData%momentx) IF (OutData%c_obj%momentx_Len > 0) & - OutData%c_obj%momentx = C_LOC( OutData%momentx(i1_l) ) + OutData%c_obj%momentx = C_LOC( OutData%momentx( i1_l ) ) DO i1 = LBOUND(OutData%momentx,1), UBOUND(OutData%momentx,1) OutData%momentx(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3781,7 +3319,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%momenty_Len = SIZE(OutData%momenty) IF (OutData%c_obj%momenty_Len > 0) & - OutData%c_obj%momenty = C_LOC( OutData%momenty(i1_l) ) + OutData%c_obj%momenty = C_LOC( OutData%momenty( i1_l ) ) DO i1 = LBOUND(OutData%momenty,1), UBOUND(OutData%momenty,1) OutData%momenty(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3802,7 +3340,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%momentz_Len = SIZE(OutData%momentz) IF (OutData%c_obj%momentz_Len > 0) & - OutData%c_obj%momentz = C_LOC( OutData%momentz(i1_l) ) + OutData%c_obj%momentz = C_LOC( OutData%momentz( i1_l ) ) DO i1 = LBOUND(OutData%momentz,1), UBOUND(OutData%momentz,1) OutData%momentz(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -3823,7 +3361,7 @@ SUBROUTINE OpFM_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END IF OutData%c_obj%forceNodesChord_Len = SIZE(OutData%forceNodesChord) IF (OutData%c_obj%forceNodesChord_Len > 0) & - OutData%c_obj%forceNodesChord = C_LOC( OutData%forceNodesChord(i1_l) ) + OutData%c_obj%forceNodesChord = C_LOC( OutData%forceNodesChord( i1_l ) ) DO i1 = LBOUND(OutData%forceNodesChord,1), UBOUND(OutData%forceNodesChord,1) OutData%forceNodesChord(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -4025,7 +3563,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%pxVel_Len = SIZE(InputData%pxVel) IF (InputData%c_obj%pxVel_Len > 0) & - InputData%c_obj%pxVel = C_LOC( InputData%pxVel( LBOUND(InputData%pxVel,1) ) ) + InputData%c_obj%pxVel = C_LOC( InputData%pxVel( LBOUND(InputData%pxVel,1) ) ) END IF END IF @@ -4037,7 +3575,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%pyVel_Len = SIZE(InputData%pyVel) IF (InputData%c_obj%pyVel_Len > 0) & - InputData%c_obj%pyVel = C_LOC( InputData%pyVel( LBOUND(InputData%pyVel,1) ) ) + InputData%c_obj%pyVel = C_LOC( InputData%pyVel( LBOUND(InputData%pyVel,1) ) ) END IF END IF @@ -4049,7 +3587,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%pzVel_Len = SIZE(InputData%pzVel) IF (InputData%c_obj%pzVel_Len > 0) & - InputData%c_obj%pzVel = C_LOC( InputData%pzVel( LBOUND(InputData%pzVel,1) ) ) + InputData%c_obj%pzVel = C_LOC( InputData%pzVel( LBOUND(InputData%pzVel,1) ) ) END IF END IF @@ -4061,7 +3599,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%pxForce_Len = SIZE(InputData%pxForce) IF (InputData%c_obj%pxForce_Len > 0) & - InputData%c_obj%pxForce = C_LOC( InputData%pxForce( LBOUND(InputData%pxForce,1) ) ) + InputData%c_obj%pxForce = C_LOC( InputData%pxForce( LBOUND(InputData%pxForce,1) ) ) END IF END IF @@ -4073,7 +3611,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%pyForce_Len = SIZE(InputData%pyForce) IF (InputData%c_obj%pyForce_Len > 0) & - InputData%c_obj%pyForce = C_LOC( InputData%pyForce( LBOUND(InputData%pyForce,1) ) ) + InputData%c_obj%pyForce = C_LOC( InputData%pyForce( LBOUND(InputData%pyForce,1) ) ) END IF END IF @@ -4085,7 +3623,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%pzForce_Len = SIZE(InputData%pzForce) IF (InputData%c_obj%pzForce_Len > 0) & - InputData%c_obj%pzForce = C_LOC( InputData%pzForce( LBOUND(InputData%pzForce,1) ) ) + InputData%c_obj%pzForce = C_LOC( InputData%pzForce( LBOUND(InputData%pzForce,1) ) ) END IF END IF @@ -4097,7 +3635,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%xdotForce_Len = SIZE(InputData%xdotForce) IF (InputData%c_obj%xdotForce_Len > 0) & - InputData%c_obj%xdotForce = C_LOC( InputData%xdotForce( LBOUND(InputData%xdotForce,1) ) ) + InputData%c_obj%xdotForce = C_LOC( InputData%xdotForce( LBOUND(InputData%xdotForce,1) ) ) END IF END IF @@ -4109,7 +3647,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%ydotForce_Len = SIZE(InputData%ydotForce) IF (InputData%c_obj%ydotForce_Len > 0) & - InputData%c_obj%ydotForce = C_LOC( InputData%ydotForce( LBOUND(InputData%ydotForce,1) ) ) + InputData%c_obj%ydotForce = C_LOC( InputData%ydotForce( LBOUND(InputData%ydotForce,1) ) ) END IF END IF @@ -4121,7 +3659,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%zdotForce_Len = SIZE(InputData%zdotForce) IF (InputData%c_obj%zdotForce_Len > 0) & - InputData%c_obj%zdotForce = C_LOC( InputData%zdotForce( LBOUND(InputData%zdotForce,1) ) ) + InputData%c_obj%zdotForce = C_LOC( InputData%zdotForce( LBOUND(InputData%zdotForce,1) ) ) END IF END IF @@ -4133,7 +3671,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%pOrientation_Len = SIZE(InputData%pOrientation) IF (InputData%c_obj%pOrientation_Len > 0) & - InputData%c_obj%pOrientation = C_LOC( InputData%pOrientation( LBOUND(InputData%pOrientation,1) ) ) + InputData%c_obj%pOrientation = C_LOC( InputData%pOrientation( LBOUND(InputData%pOrientation,1) ) ) END IF END IF @@ -4145,7 +3683,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%fx_Len = SIZE(InputData%fx) IF (InputData%c_obj%fx_Len > 0) & - InputData%c_obj%fx = C_LOC( InputData%fx( LBOUND(InputData%fx,1) ) ) + InputData%c_obj%fx = C_LOC( InputData%fx( LBOUND(InputData%fx,1) ) ) END IF END IF @@ -4157,7 +3695,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%fy_Len = SIZE(InputData%fy) IF (InputData%c_obj%fy_Len > 0) & - InputData%c_obj%fy = C_LOC( InputData%fy( LBOUND(InputData%fy,1) ) ) + InputData%c_obj%fy = C_LOC( InputData%fy( LBOUND(InputData%fy,1) ) ) END IF END IF @@ -4169,7 +3707,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%fz_Len = SIZE(InputData%fz) IF (InputData%c_obj%fz_Len > 0) & - InputData%c_obj%fz = C_LOC( InputData%fz( LBOUND(InputData%fz,1) ) ) + InputData%c_obj%fz = C_LOC( InputData%fz( LBOUND(InputData%fz,1) ) ) END IF END IF @@ -4181,7 +3719,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%momentx_Len = SIZE(InputData%momentx) IF (InputData%c_obj%momentx_Len > 0) & - InputData%c_obj%momentx = C_LOC( InputData%momentx( LBOUND(InputData%momentx,1) ) ) + InputData%c_obj%momentx = C_LOC( InputData%momentx( LBOUND(InputData%momentx,1) ) ) END IF END IF @@ -4193,7 +3731,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%momenty_Len = SIZE(InputData%momenty) IF (InputData%c_obj%momenty_Len > 0) & - InputData%c_obj%momenty = C_LOC( InputData%momenty( LBOUND(InputData%momenty,1) ) ) + InputData%c_obj%momenty = C_LOC( InputData%momenty( LBOUND(InputData%momenty,1) ) ) END IF END IF @@ -4205,7 +3743,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%momentz_Len = SIZE(InputData%momentz) IF (InputData%c_obj%momentz_Len > 0) & - InputData%c_obj%momentz = C_LOC( InputData%momentz( LBOUND(InputData%momentz,1) ) ) + InputData%c_obj%momentz = C_LOC( InputData%momentz( LBOUND(InputData%momentz,1) ) ) END IF END IF @@ -4217,7 +3755,7 @@ SUBROUTINE OpFM_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%forceNodesChord_Len = SIZE(InputData%forceNodesChord) IF (InputData%c_obj%forceNodesChord_Len > 0) & - InputData%c_obj%forceNodesChord = C_LOC( InputData%forceNodesChord( LBOUND(InputData%forceNodesChord,1) ) ) + InputData%c_obj%forceNodesChord = C_LOC( InputData%forceNodesChord( LBOUND(InputData%forceNodesChord,1) ) ) END IF END IF END SUBROUTINE OpFM_F2C_CopyInput @@ -4248,7 +3786,7 @@ SUBROUTINE OpFM_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Err END IF DstOutputData%c_obj%u_Len = SIZE(DstOutputData%u) IF (DstOutputData%c_obj%u_Len > 0) & - DstOutputData%c_obj%u = C_LOC( DstOutputData%u(i1_l) ) + DstOutputData%c_obj%u = C_LOC( DstOutputData%u( i1_l ) ) END IF DstOutputData%u = SrcOutputData%u ENDIF @@ -4263,7 +3801,7 @@ SUBROUTINE OpFM_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Err END IF DstOutputData%c_obj%v_Len = SIZE(DstOutputData%v) IF (DstOutputData%c_obj%v_Len > 0) & - DstOutputData%c_obj%v = C_LOC( DstOutputData%v(i1_l) ) + DstOutputData%c_obj%v = C_LOC( DstOutputData%v( i1_l ) ) END IF DstOutputData%v = SrcOutputData%v ENDIF @@ -4278,7 +3816,7 @@ SUBROUTINE OpFM_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Err END IF DstOutputData%c_obj%w_Len = SIZE(DstOutputData%w) IF (DstOutputData%c_obj%w_Len > 0) & - DstOutputData%c_obj%w = C_LOC( DstOutputData%w(i1_l) ) + DstOutputData%c_obj%w = C_LOC( DstOutputData%w( i1_l ) ) END IF DstOutputData%w = SrcOutputData%w ENDIF @@ -4296,28 +3834,43 @@ SUBROUTINE OpFM_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Err ENDIF END SUBROUTINE OpFM_CopyOutput - SUBROUTINE OpFM_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE OpFM_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(OpFM_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'OpFM_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(OutputData%u)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OutputData%u) OutputData%u => NULL() OutputData%C_obj%u = C_NULL_PTR OutputData%C_obj%u_Len = 0 ENDIF IF (ASSOCIATED(OutputData%v)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OutputData%v) OutputData%v => NULL() OutputData%C_obj%v = C_NULL_PTR OutputData%C_obj%v_Len = 0 ENDIF IF (ASSOCIATED(OutputData%w)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OutputData%w) OutputData%w => NULL() OutputData%C_obj%w = C_NULL_PTR @@ -4516,7 +4069,7 @@ SUBROUTINE OpFM_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM END IF OutData%c_obj%u_Len = SIZE(OutData%u) IF (OutData%c_obj%u_Len > 0) & - OutData%c_obj%u = C_LOC( OutData%u(i1_l) ) + OutData%c_obj%u = C_LOC( OutData%u( i1_l ) ) DO i1 = LBOUND(OutData%u,1), UBOUND(OutData%u,1) OutData%u(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -4537,7 +4090,7 @@ SUBROUTINE OpFM_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM END IF OutData%c_obj%v_Len = SIZE(OutData%v) IF (OutData%c_obj%v_Len > 0) & - OutData%c_obj%v = C_LOC( OutData%v(i1_l) ) + OutData%c_obj%v = C_LOC( OutData%v( i1_l ) ) DO i1 = LBOUND(OutData%v,1), UBOUND(OutData%v,1) OutData%v(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -4558,7 +4111,7 @@ SUBROUTINE OpFM_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM END IF OutData%c_obj%w_Len = SIZE(OutData%w) IF (OutData%c_obj%w_Len > 0) & - OutData%c_obj%w = C_LOC( OutData%w(i1_l) ) + OutData%c_obj%w = C_LOC( OutData%w( i1_l ) ) DO i1 = LBOUND(OutData%w,1), UBOUND(OutData%w,1) OutData%w(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -4652,7 +4205,7 @@ SUBROUTINE OpFM_F2C_CopyOutput( OutputData, ErrStat, ErrMsg, SkipPointers ) ELSE OutputData%c_obj%u_Len = SIZE(OutputData%u) IF (OutputData%c_obj%u_Len > 0) & - OutputData%c_obj%u = C_LOC( OutputData%u( LBOUND(OutputData%u,1) ) ) + OutputData%c_obj%u = C_LOC( OutputData%u( LBOUND(OutputData%u,1) ) ) END IF END IF @@ -4664,7 +4217,7 @@ SUBROUTINE OpFM_F2C_CopyOutput( OutputData, ErrStat, ErrMsg, SkipPointers ) ELSE OutputData%c_obj%v_Len = SIZE(OutputData%v) IF (OutputData%c_obj%v_Len > 0) & - OutputData%c_obj%v = C_LOC( OutputData%v( LBOUND(OutputData%v,1) ) ) + OutputData%c_obj%v = C_LOC( OutputData%v( LBOUND(OutputData%v,1) ) ) END IF END IF @@ -4676,7 +4229,7 @@ SUBROUTINE OpFM_F2C_CopyOutput( OutputData, ErrStat, ErrMsg, SkipPointers ) ELSE OutputData%c_obj%w_Len = SIZE(OutputData%w) IF (OutputData%c_obj%w_Len > 0) & - OutputData%c_obj%w = C_LOC( OutputData%w( LBOUND(OutputData%w,1) ) ) + OutputData%c_obj%w = C_LOC( OutputData%w( LBOUND(OutputData%w,1) ) ) END IF END IF END SUBROUTINE OpFM_F2C_CopyOutput diff --git a/modules/openfoam/src/OpenFOAM_Types.h b/modules/openfoam/src/OpenFOAM_Types.h index a66d6e905..b26552f2a 100644 --- a/modules/openfoam/src/OpenFOAM_Types.h +++ b/modules/openfoam/src/OpenFOAM_Types.h @@ -29,6 +29,7 @@ float BladeLength ; float TowerHeight ; float TowerBaseHeight ; + int NodeClusterType ; } OpFM_InitInputType_t ; typedef struct OpFM_InitOutputType { void * object ; @@ -42,10 +43,6 @@ - - - - } OpFM_MiscVarType_t ; typedef struct OpFM_ParameterType { void * object ; @@ -61,6 +58,7 @@ float BladeLength ; float TowerHeight ; float TowerBaseHeight ; + int NodeClusterType ; } OpFM_ParameterType_t ; typedef struct OpFM_InputType { void * object ; diff --git a/modules/orcaflex-interface/CMakeLists.txt b/modules/orcaflex-interface/CMakeLists.txt index fb6da14c5..3b744c4ce 100644 --- a/modules/orcaflex-interface/CMakeLists.txt +++ b/modules/orcaflex-interface/CMakeLists.txt @@ -18,23 +18,23 @@ if (GENERATE_TYPES) generate_f90_types(src/OrcaFlexInterface.txt ${CMAKE_CURRENT_LIST_DIR}/src/OrcaFlexInterface_Types.f90) endif() -if (ORCA_DLL_LOAD) - add_definitions(-DLibLoad) -else (ORCA_DLL_LOAD) - add_definitions(-DNO_LibLoad) -endif (ORCA_DLL_LOAD) - -add_library(orcaflexlib +add_library(orcaflexlib src/OrcaFlexInterface.f90 src/OrcaFlexInterface_Types.f90 ) target_link_libraries(orcaflexlib nwtclibs) +if (ORCA_DLL_LOAD) + target_compile_definitions(orcaflexlib PUBLIC LibLoad) +else () + target_compile_definitions(orcaflexlib PUBLIC NO_LibLoad) +endif () add_executable(orca_driver src/OrcaDriver_Subs.f90 src/OrcaDriver_Types.f90 - src/OrcaDriver.f90) -target_link_libraries(orca_driver orcaflexlib) + src/OrcaDriver.f90 +) +target_link_libraries(orca_driver orcaflexlib versioninfolib) install(TARGETS orcaflexlib orca_driver EXPORT "${CMAKE_PROJECT_NAME}Libraries" diff --git a/modules/orcaflex-interface/src/OrcaFlexInterface.f90 b/modules/orcaflex-interface/src/OrcaFlexInterface.f90 index 9dcbcbaf9..04c49d6d7 100644 --- a/modules/orcaflex-interface/src/OrcaFlexInterface.f90 +++ b/modules/orcaflex-interface/src/OrcaFlexInterface.f90 @@ -40,11 +40,6 @@ MODULE OrcaFlexInterface_Parameters ! This code was generated by Write_ChckOutLst.m at 01-Sep-2015 14:29:18. - ! Parameters related to output length (number of characters allowed in the output data headers): - - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 - - ! Indices for computing output channels: ! NOTES: ! (1) These parameters are in the order stored in "OutListParameters.xlsx" diff --git a/modules/orcaflex-interface/src/OrcaFlexInterface_Types.f90 b/modules/orcaflex-interface/src/OrcaFlexInterface_Types.f90 index 51a40873d..69d3c7a6e 100644 --- a/modules/orcaflex-interface/src/OrcaFlexInterface_Types.f90 +++ b/modules/orcaflex-interface/src/OrcaFlexInterface_Types.f90 @@ -128,15 +128,27 @@ SUBROUTINE Orca_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Err DstInitInputData%TMax = SrcInitInputData%TMax END SUBROUTINE Orca_CopyInitInput - SUBROUTINE Orca_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE Orca_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Orca_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Orca_DestroyInitInput SUBROUTINE Orca_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -300,16 +312,29 @@ SUBROUTINE Orca_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ENDIF END SUBROUTINE Orca_CopyInitOutput - SUBROUTINE Orca_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE Orca_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Orca_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF @@ -602,15 +627,27 @@ SUBROUTINE Orca_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, Err DstInputFileData%DirRoot = SrcInputFileData%DirRoot END SUBROUTINE Orca_CopyInputFile - SUBROUTINE Orca_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) + SUBROUTINE Orca_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Orca_InputFile), INTENT(INOUT) :: InputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyInputFile' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyInputFile' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Orca_DestroyInputFile SUBROUTINE Orca_PackInputFile( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -767,15 +804,27 @@ SUBROUTINE Orca_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState END SUBROUTINE Orca_CopyOtherState - SUBROUTINE Orca_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE Orca_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Orca_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Orca_DestroyOtherState SUBROUTINE Orca_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -909,15 +958,27 @@ SUBROUTINE Orca_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%LastTimeStep = SrcMiscData%LastTimeStep END SUBROUTINE Orca_CopyMisc - SUBROUTINE Orca_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE Orca_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Orca_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%AllOuts)) THEN DEALLOCATE(MiscData%AllOuts) ENDIF @@ -1137,19 +1198,33 @@ SUBROUTINE Orca_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ENDIF END SUBROUTINE Orca_CopyParam - SUBROUTINE Orca_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE Orca_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Orca_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" - CALL FreeDynamicLib( ParamData%DLL_Orca, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL FreeDynamicLib( ParamData%DLL_Orca, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ParamData%OutParam)) THEN DO i1 = LBOUND(ParamData%OutParam,1), UBOUND(ParamData%OutParam,1) - CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF @@ -1497,16 +1572,29 @@ SUBROUTINE Orca_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE Orca_CopyInput - SUBROUTINE Orca_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE Orca_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Orca_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( InputData%PtfmMesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( InputData%PtfmMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE Orca_DestroyInput SUBROUTINE Orca_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1719,16 +1807,29 @@ SUBROUTINE Orca_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Err ENDIF END SUBROUTINE Orca_CopyOutput - SUBROUTINE Orca_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE Orca_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Orca_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( OutputData%PtfmMesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( OutputData%PtfmMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF @@ -1968,15 +2069,27 @@ SUBROUTINE Orca_CopyContState( SrcContStateData, DstContStateData, CtrlCode, Err DstContStateData%Dummy = SrcContStateData%Dummy END SUBROUTINE Orca_CopyContState - SUBROUTINE Orca_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE Orca_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Orca_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Orca_DestroyContState SUBROUTINE Orca_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2093,15 +2206,27 @@ SUBROUTINE Orca_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, Err DstDiscStateData%Dummy = SrcDiscStateData%Dummy END SUBROUTINE Orca_CopyDiscState - SUBROUTINE Orca_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE Orca_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Orca_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Orca_DestroyDiscState SUBROUTINE Orca_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2218,15 +2343,27 @@ SUBROUTINE Orca_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCod DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE Orca_CopyConstrState - SUBROUTINE Orca_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE Orca_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(Orca_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'Orca_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE Orca_DestroyConstrState SUBROUTINE Orca_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) diff --git a/modules/servodyn/CMakeLists.txt b/modules/servodyn/CMakeLists.txt index 0f74f8191..361e3eb71 100644 --- a/modules/servodyn/CMakeLists.txt +++ b/modules/servodyn/CMakeLists.txt @@ -19,24 +19,27 @@ if (GENERATE_TYPES) generate_f90_types(src/ServoDyn_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/ServoDyn_Types.f90) endif() -set(SrvD_SOURCES +set(SERVODYN_SRCS + src/ServoDyn.f90 src/BladedInterface.f90 src/BladedInterface_EX.f90 src/UserSubs.f90 src/PitchCntrl_ACH.f90 src/StrucCtrl.f90 src/UserVSCont_KP.f90 - src/ServoDyn.f90 src/ServoDyn_IO.f90 src/StrucCtrl_Types.f90 src/ServoDyn_Types.f90 ) -add_library(servodynlib ${SrvD_SOURCES}) +add_library(servodynlib ${SERVODYN_SRCS}) target_link_libraries(servodynlib nwtclibs) -add_executable(servodyn_driver src/ServoDyn_Driver.f90) -target_link_libraries(servodyn_driver servodynlib nwtclibs versioninfolib ${CMAKE_DL_LIBS}) +# Driver +add_executable(servodyn_driver + src/ServoDyn_Driver.f90 +) +target_link_libraries(servodyn_driver servodynlib versioninfolib) # The Structural Control driver is currently not functional, so commenting this temporarily # add_executable(strucctrl_driver src/StrucCtrl_Driver.f90) @@ -46,4 +49,26 @@ install(TARGETS servodynlib servodyn_driver # strucctrl_driver EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) + ARCHIVE DESTINATION lib +) + +#------------------------------------------------------------------------------- +# MATLAB Library +#------------------------------------------------------------------------------- + +if (BUILD_OPENFAST_SIMULINK_API) + + add_library(servodynlib-matlab ${SERVODYN_SRCS}) + target_compile_definitions(servodynlib-matlab PUBLIC COMPILE_SIMULINK) + set_target_properties(servodynlib-matlab PROPERTIES + Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/matlab) + target_link_libraries(servodynlib-matlab nwtclibs-matlab) + + install(TARGETS servodynlib-matlab + EXPORT "${CMAKE_PROJECT_NAME}Libraries" + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + ) + +endif() \ No newline at end of file diff --git a/modules/servodyn/src/BladedInterface_EX.f90 b/modules/servodyn/src/BladedInterface_EX.f90 index 19514b28b..5775ffa6a 100644 --- a/modules/servodyn/src/BladedInterface_EX.f90 +++ b/modules/servodyn/src/BladedInterface_EX.f90 @@ -127,16 +127,22 @@ SUBROUTINE EXavrSWAP_Init( InitInp, u, p, y, dll_data, StC_CtrlChanInitInfo, UnS call InitNonLidarSensors() ! 1018:2000 if (Failed()) return + ! Initialize lidar measurements (2001:2501) + if (InitInp%NumBeam > 0 .or. InitInp%NumPulseGate > 0) then + call InitLidarMeas() + if (Failed()) return + endif + ! Initialize cable controls (2601:2800) if (InitInp%NumCableControl > 0) then call InitCableCtrl() - if (Failed()) return + if (Failed()) return endif ! Initialize cable controls (2801:3000) if (p%NumStC_Control > 0) then call InitStCCtrl() - if (Failed()) return + if (Failed()) return endif ! Add additional routines here as needed. @@ -366,6 +372,62 @@ subroutine InitStCCtrl() endif end subroutine InitStCCtrl + subroutine InitLidarMeas() + integer :: I,J + if (p%NumBeam == 0) return ! Nothing to set + ! Allocate arrays for inputs + if (allocated(InitInp%LidSpeed)) then ! make sure we have the array allocated before setting it + CALL AllocAry(u%LidSpeed, size(InitInp%LidSpeed), 'u%LidSpeed', errStat2, ErrMsg2) + if (Failed()) return + u%LidSpeed = InitInp%LidSpeed + endif + if (allocated(InitInp%MsrPositionsX)) then ! make sure we have the array allocated before setting it + CALL AllocAry(u%MsrPositionsX, size(InitInp%MsrPositionsX), 'u%MsrPositionsX', errStat2, ErrMsg2) + if (Failed()) return + u%MsrPositionsX = InitInp%MsrPositionsX + endif + if (allocated(InitInp%MsrPositionsY)) then ! make sure we have the array allocated before setting it + CALL AllocAry(u%MsrPositionsY, size(InitInp%MsrPositionsY), 'u%MsrPositionsY', errStat2, ErrMsg2) + if (Failed()) return + u%MsrPositionsY = InitInp%MsrPositionsY + endif + if (allocated(InitInp%MsrPositionsZ)) then ! make sure we have the array allocated before setting it + CALL AllocAry(u%MsrPositionsZ, size(InitInp%MsrPositionsZ), 'u%MsrPositionsZ', errStat2, ErrMsg2) + if (Failed()) return + u%MsrPositionsZ = InitInp%MsrPositionsZ + endif + ! Write summary info to summary file + if (p%SensorType > 0) then ! Set these here rather than overwrite every loop step in SensorType 1 or 3 + J=LidarMsr_StartIdx + call WrSumInfoRcvd( J+0, '','Lidar input: Sensor Type') + call WrSumInfoRcvd( J+1, '','Lidar input: Number of Beams') + call WrSumInfoRcvd( J+2, '','Lidar input: Number of Pulse Gates') + call WrSumInfoRcvd( J+3, '','Lidar input: Reference average wind speed for the lidar') + endif + if (p%SensorType == 1) THEN + do I=1,min(p%NumBeam,(LidarMsr_MaxChan-4)/4) ! Don't overstep the end for the lidar measure group + J=LidarMsr_StartIdx + 4 + (I-1) + call WrSumInfoRcvd( J+0, '','Lidar input: Measured Wind Speeds ('//trim(Num2LStr(I))//')') + call WrSumInfoRcvd( J+p%NumBeam*1, '','Lidar input: Measurement Points X ('//trim(Num2LStr(I))//')') + call WrSumInfoRcvd( J+p%NumBeam*2, '','Lidar input: Measurement Points Y ('//trim(Num2LStr(I))//')') + call WrSumInfoRcvd( J+p%NumBeam*3, '','Lidar input: Measurement Points Z ('//trim(Num2LStr(I))//')') + enddo + elseif (p%SensorType == 2) THEN + J=LidarMsr_StartIdx + call WrSumInfoRcvd( J+4, '','Lidar input: Measured Wind Speeds') + call WrSumInfoRcvd( J+5, '','Lidar input: Measurement Points X') + call WrSumInfoRcvd( J+6, '','Lidar input: Measurement Points Y') + call WrSumInfoRcvd( J+7, '','Lidar input: Measurement Points Z') + elseif (p%SensorType == 3) THEN + do I=1,min(p%NumPulseGate,(LidarMsr_MaxChan-4)/4) ! Don't overstep the end for the lidar measure group + J=LidarMsr_StartIdx + 4 + (I-1) + call WrSumInfoRcvd( J+0, '','Lidar input: Measured Wind Speeds ('//trim(Num2LStr(I))//')') + call WrSumInfoRcvd( J+p%NumPulseGate*1, '','Lidar input: Measurement Points X ('//trim(Num2LStr(I))//')') + call WrSumInfoRcvd( J+p%NumPulseGate*2, '','Lidar input: Measurement Points Y ('//trim(Num2LStr(I))//')') + call WrSumInfoRcvd( J+p%NumPulseGate*3, '','Lidar input: Measurement Points Z ('//trim(Num2LStr(I))//')') + enddo + endif + end subroutine InitLidarMeas subroutine WrBladedSumInfoToFile() @@ -482,6 +544,36 @@ end subroutine SetEXavrSWAP_Sensors subroutine SetEXavrSWAP_LidarSensors() ! in case something got set wrong, don't try to write beyond array if (size(dll_data%avrswap) < (LidarMsr_StartIdx + LidarMsr_MaxChan - 1) ) return + if (p%NumBeam == 0) return ! Nothing to set + + if (p%SensorType > 0) then ! Set these here rather than overwrite every loop step in SensorType 1 or 3 + dll_data%avrswap(LidarMsr_StartIdx) = real(p%SensorType,SiKi) ! Sensor Type + dll_data%avrswap(LidarMsr_StartIdx+1) = real(p%NumBeam,SiKi) ! Number of Beams + dll_data%avrswap(LidarMsr_StartIdx+2) = real(p%NumPulseGate,SiKi) ! Number of Pulse Gates + dll_data%avrswap(LidarMsr_StartIdx+3) = p%URefLid ! Reference average wind speed for the lidar + endif + if (p%SensorType == 1) THEN + do I=1,min(p%NumBeam,(LidarMsr_MaxChan-4)/4) ! Don't overstep the end for the lidar measure group + J=LidarMsr_StartIdx + 4 + (I-1) + dll_data%avrswap(J) = u%LidSpeed(I) ! Lidar Measured Wind Speeds + dll_data%avrswap(J+p%NumBeam) = u%MsrPositionsX(I) ! Lidar Measurement Points X + dll_data%avrswap(J+(p%NumBeam*2)) = u%MsrPositionsY(I) ! Lidar Measurement Points Y + dll_data%avrswap(J+(p%NumBeam*3)) = u%MsrPositionsZ(I) ! Lidar Measurement Points Z + enddo + elseif (p%SensorType == 2) THEN + dll_data%avrswap(LidarMsr_StartIdx+4) = u%LidSpeed(1) ! Lidar Measured Wind Speeds + dll_data%avrswap(LidarMsr_StartIdx+5) = u%MsrPositionsX(1) ! Lidar Measurement Points X + dll_data%avrswap(LidarMsr_StartIdx+6) = u%MsrPositionsY(1) ! Lidar Measurement Points Y + dll_data%avrswap(LidarMsr_StartIdx+7) = u%MsrPositionsZ(1) ! Lidar Measurement Points Z + elseif (p%SensorType == 3) THEN + do I=1,min(p%NumPulseGate,(LidarMsr_MaxChan-4)/4) ! Don't overstep the end for the lidar measure group + J=LidarMsr_StartIdx + 4 + (I-1) + dll_data%avrswap(J) = u%LidSpeed(I) ! Lidar Measured Wind Speeds + dll_data%avrswap(J+p%NumPulseGate) = u%MsrPositionsX(I) ! Lidar Measurement Points X + dll_data%avrswap(J+(p%NumPulseGate*2)) = u%MsrPositionsY(I) ! Lidar Measurement Points Y + dll_data%avrswap(J+(p%NumPulseGate*3)) = u%MsrPositionsZ(I) ! Lidar Measurement Points Z + enddo + endif end subroutine SetEXavrSWAP_LidarSensors !> Set the Lidar related sensor inputs diff --git a/modules/servodyn/src/PitchCntrl_ACH.f90 b/modules/servodyn/src/PitchCntrl_ACH.f90 index 167851ce2..f1d953396 100644 --- a/modules/servodyn/src/PitchCntrl_ACH.f90 +++ b/modules/servodyn/src/PitchCntrl_ACH.f90 @@ -11,15 +11,14 @@ SUBROUTINE PitchCntrl ( BlPitch, ElecPwr, LSS_Spd, TwrAccel, NB, ZTime, DT, DirR ! This routine reads a data file containing user specified transfer - ! function information to allow the use of control systems in FAST - ! and ADAMS. The parameters read in, and array dimensions may be - ! adjusted to suit the users need. + ! function information to allow the use of control systems in FAST. + ! The parameters read in, and array dimensions may be adjusted to + ! suit the users need. ! The transfer function coefficients are read in, then converted to ! state space form for integration using a fourth order Runge-Kutta ! integration scheme. ! This routine was originally written by C. Hansen in Fortran 77 for - ! use with FAST and ADAMS. It was converted to Modern Fortran by - ! J. Jonkman. + ! use with FAST. It was converted to Modern Fortran by J. Jonkman. USE NWTC_Library @@ -429,8 +428,7 @@ SUBROUTINE CTRL4 ( CNST, AC, BC, NORDER, MSZ, NSZ, & ! Now apply fourth transfer function to represent the actuator - ! (Do not use this actuator in ADAMS. If order of 4th - ! transfer function is zero, this transfer function is not applied) + ! (If order of 4th transfer function is zero, this transfer function is not applied) IF ( NORDER(4) == 0 ) THEN DO K=1,NB diff --git a/modules/servodyn/src/ServoDyn.f90 b/modules/servodyn/src/ServoDyn.f90 index fd544611c..a5e683526 100644 --- a/modules/servodyn/src/ServoDyn.f90 +++ b/modules/servodyn/src/ServoDyn.f90 @@ -385,6 +385,22 @@ SUBROUTINE SrvD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO u%RotPwr = 0. u%HorWindV = 0. u%YawAngle = 0. + if (allocated(InitInp%LidSpeed)) then ! Must allocate + allocate(u%LidSpeed(size(InitInp%LidSpeed))) + u%LidSpeed = 0. + endif + if (allocated(InitInp%MsrPositionsX)) then + allocate(u%MsrPositionsX(size(InitInp%MsrPositionsX))) + u%MsrPositionsX = 0. + endif + if (allocated(InitInp%MsrPositionsY)) then + allocate(u%MsrPositionsY(size(InitInp%MsrPositionsY))) + u%MsrPositionsY = 0. + endif + if (allocated(InitInp%MsrPositionsZ)) then + allocate(u%MsrPositionsZ(size(InitInp%MsrPositionsZ))) + u%MsrPositionsZ = 0. + endif m%dll_data%ElecPwr_prev = 0. m%dll_data%GenTrq_prev = 0. @@ -483,6 +499,12 @@ SUBROUTINE SrvD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO p%AirDens = InitInp%AirDens p%AvgWindSpeed = InitInp%AvgWindSpeed + p%SensorType = InitInp%SensorType + p%NumBeam = InitInp%NumBeam + p%NumPulseGate = InitInp%NumPulseGate + p%PulseSpacing = InitInp%PulseSpacing + p%URefLid = InitInp%URefLid + CALL BladedInterface_Init(u, p, m, xd, y, InputFileData, InitInp, StC_CtrlChanInitInfo, UnSum, ErrStat2, ErrMsg2 ) if (Failed()) return; diff --git a/modules/servodyn/src/ServoDyn_IO.f90 b/modules/servodyn/src/ServoDyn_IO.f90 index 805b2be99..cb900579e 100644 --- a/modules/servodyn/src/ServoDyn_IO.f90 +++ b/modules/servodyn/src/ServoDyn_IO.f90 @@ -39,11 +39,6 @@ MODULE ServoDyn_IO ! This code was generated by Write_ChckOutLst.m at 04-Feb-2021 08:42:27. - ! Parameters related to output length (number of characters allowed in the output data headers): - - INTEGER(IntKi), PARAMETER :: OutStrLenM1 = ChanLen - 1 - - ! Indices for computing output channels: ! NOTES: ! (1) These parameters are in the order stored in "OutListParameters.xlsx" @@ -1461,8 +1456,7 @@ subroutine ParseInputFileInfo( PriPath, InputFile, OutFileRoot, FileInfo_In, Inp !---------------------- OUTLIST -------------------------------------------- if ( InputFileData%Echo ) WRITE(UnEcho, '(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, UnEcho ) + call ReadOutputListFromFileInfo( FileInfo_In, CurLine, InputFileData%OutList, InputFileData%NumOuts, ErrStat2, ErrMsg2, UnEcho ) if (Failed()) return; diff --git a/modules/servodyn/src/ServoDyn_Registry.txt b/modules/servodyn/src/ServoDyn_Registry.txt index 7cc14b7d4..4f3ab877c 100644 --- a/modules/servodyn/src/ServoDyn_Registry.txt +++ b/modules/servodyn/src/ServoDyn_Registry.txt @@ -56,7 +56,16 @@ typedef ^ InitInputType IntKi InterpOrder - - - "Interpolation order from glue c #ADD in the TMD submodule input file passing here typedef ^ InitInputType ReKi fromSCGlob {:} - - "Initial global inputs to the controller [from the supercontroller]" - typedef ^ InitInputType ReKi fromSC {:} - - "Initial turbine specific inputs to the controller [from the supercontroller]" - - +#initial inputs of lidar parameters +typedef ^ InitInputType ReKi LidSpeed {:} - - "Number of Lidar measurement distances" - +typedef ^ InitInputType ReKi MsrPositionsX {:} - - "Lidar X direction measurement points" m +typedef ^ InitInputType ReKi MsrPositionsY {:} - - "Lidar Y direction measurement points" m +typedef ^ InitInputType ReKi MsrPositionsZ {:} - - "Lidar Z direction measurement points" m +typedef ^ InitInputType IntKi SensorType - - - "Lidar sensor type" - +typedef ^ InitInputType IntKi NumBeam - - - "Number of beams" - +typedef ^ InitInputType IntKi NumPulseGate - - - "Number of pulse gates" - +typedef ^ InitInputType ReKi PulseSpacing - - - "Distance between range gates" - +typedef ^ InitInputType ReKi URefLid - - - "Reference average wind speed for the lidar" m/s # Define outputs from the initialization routine here: typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "Names of the output-to-file channels" - @@ -226,6 +235,15 @@ typedef ^ BladedDLLType ReKi RootMxc 3 - - "In-plane moment (i.e., the moment ca typedef ^ BladedDLLType ReKi LSShftFxa - - - "Rotating low-speed shaft force x" N typedef ^ BladedDLLType ReKi LSShftFys - - - "Nonrotating low-speed shaft force y" N typedef ^ BladedDLLType ReKi LSShftFzs - - - "Nonrotating low-speed shaft force z" N +typedef ^ BladedDLLType ReKi LidSpeed {:} - - "Lidar measured wind speed" m/s +typedef ^ BladedDLLType ReKi MsrPositionsX {:} - - "Lidar X direction measurement points" m +typedef ^ BladedDLLType ReKi MsrPositionsY {:} - - "Lidar Y direction measurement points" m +typedef ^ BladedDLLType ReKi MsrPositionsZ {:} - - "Lidar Z direction measurement points" m +typedef ^ BladedDLLType IntKi SensorType - - - "Lidar sensor type" - +typedef ^ BladedDLLType IntKi NumBeam - - - "Number of beams" - +typedef ^ BladedDLLType IntKi NumPulseGate - - - "Number of pulse gates" - +typedef ^ BladedDLLType IntKi PulseSpacing - - - "Distance between range gates" - +typedef ^ BladedDLLType IntKi URefLid - - - "Reference average wind speed for the lidar" m/s ## these are PARAMETERS sent to the DLL (THEIR VALUES SHOULD NOT CHANGE DURING SIMULATION): typedef ^ BladedDLLType DbKi DLL_DT - - - "interval for calling DLL (integer multiple number of DT)" s typedef ^ BladedDLLType CHARACTER(1024) DLL_InFile - - - "Name of input file used in DLL" - @@ -469,6 +487,12 @@ typedef ^ ParameterType Integer Jac_Idx_BStC_y {:}{:}{:} - - "the start and typedef ^ ParameterType Integer Jac_Idx_NStC_y {:}{:} - - "the start and end indices of nacelle StC y jacobian [ start/end, instance ]" - typedef ^ ParameterType Integer Jac_Idx_TStC_y {:}{:} - - "the start and end indices of tower StC y jacobian [ start/end, instance ]" - typedef ^ ParameterType Integer Jac_Idx_SStC_y {:}{:} - - "the start and end indices of substructure StC y jacobian [ start/end, instance ]" - +# parameters for lidar assisted control +typedef ^ ParameterType IntKi SensorType - - - "Lidar sensor type" - +typedef ^ ParameterType IntKi NumBeam - - - "Number of beams" - +typedef ^ ParameterType IntKi NumPulseGate - - - "Number of pulse gates" - +typedef ^ ParameterType ReKi PulseSpacing - - - "Distance between range gates" m +typedef ^ ParameterType ReKi URefLid - - - "Reference average wind speed for the lidar" m/s @@ -521,6 +545,10 @@ typedef ^ InputType MeshType BStCMotionMesh {:}{:} - - "StC module blade typedef ^ InputType MeshType NStCMotionMesh {:} - - "StC module nacelle input motion mesh" - typedef ^ InputType MeshType TStCMotionMesh {:} - - "StC module tower input motion mesh" - typedef ^ InputType MeshType SStCMotionMesh {:} - - "StC module substructure input motion mesh" - +typedef ^ InputType ReKi LidSpeed {:} - - "Lidar measured wind speeds" m/s +typedef ^ InputType ReKi MsrPositionsX {:} - - "Lidar X direction measurement points" m +typedef ^ InputType ReKi MsrPositionsY {:} - - "Lidar Y direction measurement points" m +typedef ^ InputType ReKi MsrPositionsZ {:} - - "Lidar Z direction measurement points" m # ..... Outputs ................................................................................................................... diff --git a/modules/servodyn/src/ServoDyn_Types.f90 b/modules/servodyn/src/ServoDyn_Types.f90 index 801601b2e..71219287f 100644 --- a/modules/servodyn/src/ServoDyn_Types.f90 +++ b/modules/servodyn/src/ServoDyn_Types.f90 @@ -74,6 +74,15 @@ MODULE ServoDyn_Types INTEGER(IntKi) :: InterpOrder !< Interpolation order from glue code -- required to set m%u_xStC sizes [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: fromSCGlob !< Initial global inputs to the controller [from the supercontroller] [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: fromSC !< Initial turbine specific inputs to the controller [from the supercontroller] [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: LidSpeed !< Number of Lidar measurement distances [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsX !< Lidar X direction measurement points [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsY !< Lidar Y direction measurement points [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsZ !< Lidar Z direction measurement points [m] + INTEGER(IntKi) :: SensorType !< Lidar sensor type [-] + INTEGER(IntKi) :: NumBeam !< Number of beams [-] + INTEGER(IntKi) :: NumPulseGate !< Number of pulse gates [-] + REAL(ReKi) :: PulseSpacing !< Distance between range gates [-] + REAL(ReKi) :: URefLid !< Reference average wind speed for the lidar [m/s] END TYPE SrvD_InitInputType ! ======================= ! ========= SrvD_InitOutputType ======= @@ -239,6 +248,15 @@ MODULE ServoDyn_Types REAL(ReKi) :: LSShftFxa !< Rotating low-speed shaft force x [N] REAL(ReKi) :: LSShftFys !< Nonrotating low-speed shaft force y [N] REAL(ReKi) :: LSShftFzs !< Nonrotating low-speed shaft force z [N] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: LidSpeed !< Lidar measured wind speed [m/s] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsX !< Lidar X direction measurement points [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsY !< Lidar Y direction measurement points [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsZ !< Lidar Z direction measurement points [m] + INTEGER(IntKi) :: SensorType !< Lidar sensor type [-] + INTEGER(IntKi) :: NumBeam !< Number of beams [-] + INTEGER(IntKi) :: NumPulseGate !< Number of pulse gates [-] + INTEGER(IntKi) :: PulseSpacing !< Distance between range gates [-] + INTEGER(IntKi) :: URefLid !< Reference average wind speed for the lidar [m/s] REAL(DbKi) :: DLL_DT !< interval for calling DLL (integer multiple number of DT) [s] CHARACTER(1024) :: DLL_InFile !< Name of input file used in DLL [-] CHARACTER(1024) :: RootName !< RootName for writing output files [-] @@ -476,6 +494,11 @@ MODULE ServoDyn_Types INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Jac_Idx_NStC_y !< the start and end indices of nacelle StC y jacobian [ start/end, instance ] [-] INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Jac_Idx_TStC_y !< the start and end indices of tower StC y jacobian [ start/end, instance ] [-] INTEGER(IntKi) , DIMENSION(:,:), ALLOCATABLE :: Jac_Idx_SStC_y !< the start and end indices of substructure StC y jacobian [ start/end, instance ] [-] + INTEGER(IntKi) :: SensorType !< Lidar sensor type [-] + INTEGER(IntKi) :: NumBeam !< Number of beams [-] + INTEGER(IntKi) :: NumPulseGate !< Number of pulse gates [-] + REAL(ReKi) :: PulseSpacing !< Distance between range gates [m] + REAL(ReKi) :: URefLid !< Reference average wind speed for the lidar [m/s] END TYPE SrvD_ParameterType ! ======================= ! ========= SrvD_InputType ======= @@ -527,6 +550,10 @@ MODULE ServoDyn_Types TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: NStCMotionMesh !< StC module nacelle input motion mesh [-] TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: TStCMotionMesh !< StC module tower input motion mesh [-] TYPE(MeshType) , DIMENSION(:), ALLOCATABLE :: SStCMotionMesh !< StC module substructure input motion mesh [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: LidSpeed !< Lidar measured wind speeds [m/s] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsX !< Lidar X direction measurement points [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsY !< Lidar Y direction measurement points [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: MsrPositionsZ !< Lidar Z direction measurement points [m] END TYPE SrvD_InputType ! ======================= ! ========= SrvD_OutputType ======= @@ -707,17 +734,82 @@ SUBROUTINE SrvD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Err END IF DstInitInputData%fromSC = SrcInitInputData%fromSC ENDIF +IF (ALLOCATED(SrcInitInputData%LidSpeed)) THEN + i1_l = LBOUND(SrcInitInputData%LidSpeed,1) + i1_u = UBOUND(SrcInitInputData%LidSpeed,1) + IF (.NOT. ALLOCATED(DstInitInputData%LidSpeed)) THEN + ALLOCATE(DstInitInputData%LidSpeed(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%LidSpeed.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%LidSpeed = SrcInitInputData%LidSpeed +ENDIF +IF (ALLOCATED(SrcInitInputData%MsrPositionsX)) THEN + i1_l = LBOUND(SrcInitInputData%MsrPositionsX,1) + i1_u = UBOUND(SrcInitInputData%MsrPositionsX,1) + IF (.NOT. ALLOCATED(DstInitInputData%MsrPositionsX)) THEN + ALLOCATE(DstInitInputData%MsrPositionsX(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%MsrPositionsX.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%MsrPositionsX = SrcInitInputData%MsrPositionsX +ENDIF +IF (ALLOCATED(SrcInitInputData%MsrPositionsY)) THEN + i1_l = LBOUND(SrcInitInputData%MsrPositionsY,1) + i1_u = UBOUND(SrcInitInputData%MsrPositionsY,1) + IF (.NOT. ALLOCATED(DstInitInputData%MsrPositionsY)) THEN + ALLOCATE(DstInitInputData%MsrPositionsY(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%MsrPositionsY.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%MsrPositionsY = SrcInitInputData%MsrPositionsY +ENDIF +IF (ALLOCATED(SrcInitInputData%MsrPositionsZ)) THEN + i1_l = LBOUND(SrcInitInputData%MsrPositionsZ,1) + i1_u = UBOUND(SrcInitInputData%MsrPositionsZ,1) + IF (.NOT. ALLOCATED(DstInitInputData%MsrPositionsZ)) THEN + ALLOCATE(DstInitInputData%MsrPositionsZ(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%MsrPositionsZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInitInputData%MsrPositionsZ = SrcInitInputData%MsrPositionsZ +ENDIF + DstInitInputData%SensorType = SrcInitInputData%SensorType + DstInitInputData%NumBeam = SrcInitInputData%NumBeam + DstInitInputData%NumPulseGate = SrcInitInputData%NumPulseGate + DstInitInputData%PulseSpacing = SrcInitInputData%PulseSpacing + DstInitInputData%URefLid = SrcInitInputData%URefLid END SUBROUTINE SrvD_CopyInitInput - SUBROUTINE SrvD_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE SrvD_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SrvD_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%BlPitchInit)) THEN DEALLOCATE(InitInputData%BlPitchInit) ENDIF @@ -733,7 +825,8 @@ SUBROUTINE SrvD_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) IF (ALLOCATED(InitInputData%BladeRootRefOrient)) THEN DEALLOCATE(InitInputData%BladeRootRefOrient) ENDIF - CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedPrimaryInputData, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedPrimaryInputData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitInputData%CableControlRequestor)) THEN DEALLOCATE(InitInputData%CableControlRequestor) ENDIF @@ -742,6 +835,18 @@ SUBROUTINE SrvD_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(InitInputData%fromSC)) THEN DEALLOCATE(InitInputData%fromSC) +ENDIF +IF (ALLOCATED(InitInputData%LidSpeed)) THEN + DEALLOCATE(InitInputData%LidSpeed) +ENDIF +IF (ALLOCATED(InitInputData%MsrPositionsX)) THEN + DEALLOCATE(InitInputData%MsrPositionsX) +ENDIF +IF (ALLOCATED(InitInputData%MsrPositionsY)) THEN + DEALLOCATE(InitInputData%MsrPositionsY) +ENDIF +IF (ALLOCATED(InitInputData%MsrPositionsZ)) THEN + DEALLOCATE(InitInputData%MsrPositionsZ) ENDIF END SUBROUTINE SrvD_DestroyInitInput @@ -867,6 +972,31 @@ SUBROUTINE SrvD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Int_BufSz = Int_BufSz + 2*1 ! fromSC upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%fromSC) ! fromSC END IF + Int_BufSz = Int_BufSz + 1 ! LidSpeed allocated yes/no + IF ( ALLOCATED(InData%LidSpeed) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LidSpeed upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%LidSpeed) ! LidSpeed + END IF + Int_BufSz = Int_BufSz + 1 ! MsrPositionsX allocated yes/no + IF ( ALLOCATED(InData%MsrPositionsX) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MsrPositionsX upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MsrPositionsX) ! MsrPositionsX + END IF + Int_BufSz = Int_BufSz + 1 ! MsrPositionsY allocated yes/no + IF ( ALLOCATED(InData%MsrPositionsY) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MsrPositionsY upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MsrPositionsY) ! MsrPositionsY + END IF + Int_BufSz = Int_BufSz + 1 ! MsrPositionsZ allocated yes/no + IF ( ALLOCATED(InData%MsrPositionsZ) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MsrPositionsZ upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MsrPositionsZ) ! MsrPositionsZ + END IF + Int_BufSz = Int_BufSz + 1 ! SensorType + Int_BufSz = Int_BufSz + 1 ! NumBeam + Int_BufSz = Int_BufSz + 1 ! NumPulseGate + Re_BufSz = Re_BufSz + 1 ! PulseSpacing + Re_BufSz = Re_BufSz + 1 ! URefLid IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -1174,6 +1304,76 @@ SUBROUTINE SrvD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrM Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%LidSpeed) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LidSpeed,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LidSpeed,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LidSpeed,1), UBOUND(InData%LidSpeed,1) + ReKiBuf(Re_Xferred) = InData%LidSpeed(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MsrPositionsX) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPositionsX,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPositionsX,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MsrPositionsX,1), UBOUND(InData%MsrPositionsX,1) + ReKiBuf(Re_Xferred) = InData%MsrPositionsX(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MsrPositionsY) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPositionsY,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPositionsY,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MsrPositionsY,1), UBOUND(InData%MsrPositionsY,1) + ReKiBuf(Re_Xferred) = InData%MsrPositionsY(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MsrPositionsZ) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPositionsZ,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPositionsZ,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MsrPositionsZ,1), UBOUND(InData%MsrPositionsZ,1) + ReKiBuf(Re_Xferred) = InData%MsrPositionsZ(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IntKiBuf(Int_Xferred) = InData%SensorType + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumBeam + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumPulseGate + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%PulseSpacing + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%URefLid + Re_Xferred = Re_Xferred + 1 END SUBROUTINE SrvD_PackInitInput SUBROUTINE SrvD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -1559,6 +1759,88 @@ SUBROUTINE SrvD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, E Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LidSpeed not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LidSpeed)) DEALLOCATE(OutData%LidSpeed) + ALLOCATE(OutData%LidSpeed(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LidSpeed.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LidSpeed,1), UBOUND(OutData%LidSpeed,1) + OutData%LidSpeed(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MsrPositionsX not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MsrPositionsX)) DEALLOCATE(OutData%MsrPositionsX) + ALLOCATE(OutData%MsrPositionsX(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MsrPositionsX.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MsrPositionsX,1), UBOUND(OutData%MsrPositionsX,1) + OutData%MsrPositionsX(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MsrPositionsY not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MsrPositionsY)) DEALLOCATE(OutData%MsrPositionsY) + ALLOCATE(OutData%MsrPositionsY(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MsrPositionsY.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MsrPositionsY,1), UBOUND(OutData%MsrPositionsY,1) + OutData%MsrPositionsY(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MsrPositionsZ not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MsrPositionsZ)) DEALLOCATE(OutData%MsrPositionsZ) + ALLOCATE(OutData%MsrPositionsZ(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MsrPositionsZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MsrPositionsZ,1), UBOUND(OutData%MsrPositionsZ,1) + OutData%MsrPositionsZ(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + OutData%SensorType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NumBeam = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NumPulseGate = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%PulseSpacing = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%URefLid = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE SrvD_UnPackInitInput SUBROUTINE SrvD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -1703,22 +1985,35 @@ SUBROUTINE SrvD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ENDIF END SUBROUTINE SrvD_CopyInitOutput - SUBROUTINE SrvD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE SrvD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SrvD_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN DEALLOCATE(InitOutputData%WriteOutputUnt) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitOutputData%LinNames_y)) THEN DEALLOCATE(InitOutputData%LinNames_y) ENDIF @@ -2515,15 +2810,27 @@ SUBROUTINE SrvD_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, Err DstInputFileData%EXavrSWAP = SrcInputFileData%EXavrSWAP END SUBROUTINE SrvD_CopyInputFile - SUBROUTINE SrvD_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) + SUBROUTINE SrvD_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SrvD_InputFile), INTENT(INOUT) :: InputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyInputFile' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyInputFile' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputFileData%OutList)) THEN DEALLOCATE(InputFileData%OutList) ENDIF @@ -3488,6 +3795,59 @@ SUBROUTINE SrvD_CopyBladedDLLType( SrcBladedDLLTypeData, DstBladedDLLTypeData, C DstBladedDLLTypeData%LSShftFxa = SrcBladedDLLTypeData%LSShftFxa DstBladedDLLTypeData%LSShftFys = SrcBladedDLLTypeData%LSShftFys DstBladedDLLTypeData%LSShftFzs = SrcBladedDLLTypeData%LSShftFzs +IF (ALLOCATED(SrcBladedDLLTypeData%LidSpeed)) THEN + i1_l = LBOUND(SrcBladedDLLTypeData%LidSpeed,1) + i1_u = UBOUND(SrcBladedDLLTypeData%LidSpeed,1) + IF (.NOT. ALLOCATED(DstBladedDLLTypeData%LidSpeed)) THEN + ALLOCATE(DstBladedDLLTypeData%LidSpeed(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladedDLLTypeData%LidSpeed.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBladedDLLTypeData%LidSpeed = SrcBladedDLLTypeData%LidSpeed +ENDIF +IF (ALLOCATED(SrcBladedDLLTypeData%MsrPositionsX)) THEN + i1_l = LBOUND(SrcBladedDLLTypeData%MsrPositionsX,1) + i1_u = UBOUND(SrcBladedDLLTypeData%MsrPositionsX,1) + IF (.NOT. ALLOCATED(DstBladedDLLTypeData%MsrPositionsX)) THEN + ALLOCATE(DstBladedDLLTypeData%MsrPositionsX(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladedDLLTypeData%MsrPositionsX.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBladedDLLTypeData%MsrPositionsX = SrcBladedDLLTypeData%MsrPositionsX +ENDIF +IF (ALLOCATED(SrcBladedDLLTypeData%MsrPositionsY)) THEN + i1_l = LBOUND(SrcBladedDLLTypeData%MsrPositionsY,1) + i1_u = UBOUND(SrcBladedDLLTypeData%MsrPositionsY,1) + IF (.NOT. ALLOCATED(DstBladedDLLTypeData%MsrPositionsY)) THEN + ALLOCATE(DstBladedDLLTypeData%MsrPositionsY(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladedDLLTypeData%MsrPositionsY.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBladedDLLTypeData%MsrPositionsY = SrcBladedDLLTypeData%MsrPositionsY +ENDIF +IF (ALLOCATED(SrcBladedDLLTypeData%MsrPositionsZ)) THEN + i1_l = LBOUND(SrcBladedDLLTypeData%MsrPositionsZ,1) + i1_u = UBOUND(SrcBladedDLLTypeData%MsrPositionsZ,1) + IF (.NOT. ALLOCATED(DstBladedDLLTypeData%MsrPositionsZ)) THEN + ALLOCATE(DstBladedDLLTypeData%MsrPositionsZ(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstBladedDLLTypeData%MsrPositionsZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstBladedDLLTypeData%MsrPositionsZ = SrcBladedDLLTypeData%MsrPositionsZ +ENDIF + DstBladedDLLTypeData%SensorType = SrcBladedDLLTypeData%SensorType + DstBladedDLLTypeData%NumBeam = SrcBladedDLLTypeData%NumBeam + DstBladedDLLTypeData%NumPulseGate = SrcBladedDLLTypeData%NumPulseGate + DstBladedDLLTypeData%PulseSpacing = SrcBladedDLLTypeData%PulseSpacing + DstBladedDLLTypeData%URefLid = SrcBladedDLLTypeData%URefLid DstBladedDLLTypeData%DLL_DT = SrcBladedDLLTypeData%DLL_DT DstBladedDLLTypeData%DLL_InFile = SrcBladedDLLTypeData%DLL_InFile DstBladedDLLTypeData%RootName = SrcBladedDLLTypeData%RootName @@ -3719,15 +4079,27 @@ SUBROUTINE SrvD_CopyBladedDLLType( SrcBladedDLLTypeData, DstBladedDLLTypeData, C ENDIF END SUBROUTINE SrvD_CopyBladedDLLType - SUBROUTINE SrvD_DestroyBladedDLLType( BladedDLLTypeData, ErrStat, ErrMsg ) + SUBROUTINE SrvD_DestroyBladedDLLType( BladedDLLTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(BladedDLLType), INTENT(INOUT) :: BladedDLLTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyBladedDLLType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyBladedDLLType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(BladedDLLTypeData%avrSWAP)) THEN DEALLOCATE(BladedDLLTypeData%avrSWAP) ENDIF @@ -3736,7 +4108,8 @@ SUBROUTINE SrvD_DestroyBladedDLLType( BladedDLLTypeData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(BladedDLLTypeData%LogChannels_OutParam)) THEN DO i1 = LBOUND(BladedDLLTypeData%LogChannels_OutParam,1), UBOUND(BladedDLLTypeData%LogChannels_OutParam,1) - CALL NWTC_Library_Destroyoutparmtype( BladedDLLTypeData%LogChannels_OutParam(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyoutparmtype( BladedDLLTypeData%LogChannels_OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(BladedDLLTypeData%LogChannels_OutParam) ENDIF @@ -3746,6 +4119,18 @@ SUBROUTINE SrvD_DestroyBladedDLLType( BladedDLLTypeData, ErrStat, ErrMsg ) IF (ALLOCATED(BladedDLLTypeData%BlPitchInput)) THEN DEALLOCATE(BladedDLLTypeData%BlPitchInput) ENDIF +IF (ALLOCATED(BladedDLLTypeData%LidSpeed)) THEN + DEALLOCATE(BladedDLLTypeData%LidSpeed) +ENDIF +IF (ALLOCATED(BladedDLLTypeData%MsrPositionsX)) THEN + DEALLOCATE(BladedDLLTypeData%MsrPositionsX) +ENDIF +IF (ALLOCATED(BladedDLLTypeData%MsrPositionsY)) THEN + DEALLOCATE(BladedDLLTypeData%MsrPositionsY) +ENDIF +IF (ALLOCATED(BladedDLLTypeData%MsrPositionsZ)) THEN + DEALLOCATE(BladedDLLTypeData%MsrPositionsZ) +ENDIF IF (ALLOCATED(BladedDLLTypeData%GenSpd_TLU)) THEN DEALLOCATE(BladedDLLTypeData%GenSpd_TLU) ENDIF @@ -3923,6 +4308,31 @@ SUBROUTINE SrvD_PackBladedDLLType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_BufSz = Re_BufSz + 1 ! LSShftFxa Re_BufSz = Re_BufSz + 1 ! LSShftFys Re_BufSz = Re_BufSz + 1 ! LSShftFzs + Int_BufSz = Int_BufSz + 1 ! LidSpeed allocated yes/no + IF ( ALLOCATED(InData%LidSpeed) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LidSpeed upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%LidSpeed) ! LidSpeed + END IF + Int_BufSz = Int_BufSz + 1 ! MsrPositionsX allocated yes/no + IF ( ALLOCATED(InData%MsrPositionsX) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MsrPositionsX upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MsrPositionsX) ! MsrPositionsX + END IF + Int_BufSz = Int_BufSz + 1 ! MsrPositionsY allocated yes/no + IF ( ALLOCATED(InData%MsrPositionsY) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MsrPositionsY upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MsrPositionsY) ! MsrPositionsY + END IF + Int_BufSz = Int_BufSz + 1 ! MsrPositionsZ allocated yes/no + IF ( ALLOCATED(InData%MsrPositionsZ) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MsrPositionsZ upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MsrPositionsZ) ! MsrPositionsZ + END IF + Int_BufSz = Int_BufSz + 1 ! SensorType + Int_BufSz = Int_BufSz + 1 ! NumBeam + Int_BufSz = Int_BufSz + 1 ! NumPulseGate + Int_BufSz = Int_BufSz + 1 ! PulseSpacing + Int_BufSz = Int_BufSz + 1 ! URefLid Db_BufSz = Db_BufSz + 1 ! DLL_DT Int_BufSz = Int_BufSz + 1*LEN(InData%DLL_InFile) ! DLL_InFile Int_BufSz = Int_BufSz + 1*LEN(InData%RootName) ! RootName @@ -4258,6 +4668,76 @@ SUBROUTINE SrvD_PackBladedDLLType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%LSShftFzs Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%LidSpeed) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LidSpeed,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LidSpeed,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LidSpeed,1), UBOUND(InData%LidSpeed,1) + ReKiBuf(Re_Xferred) = InData%LidSpeed(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MsrPositionsX) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPositionsX,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPositionsX,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MsrPositionsX,1), UBOUND(InData%MsrPositionsX,1) + ReKiBuf(Re_Xferred) = InData%MsrPositionsX(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MsrPositionsY) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPositionsY,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPositionsY,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MsrPositionsY,1), UBOUND(InData%MsrPositionsY,1) + ReKiBuf(Re_Xferred) = InData%MsrPositionsY(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MsrPositionsZ) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPositionsZ,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPositionsZ,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MsrPositionsZ,1), UBOUND(InData%MsrPositionsZ,1) + ReKiBuf(Re_Xferred) = InData%MsrPositionsZ(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IntKiBuf(Int_Xferred) = InData%SensorType + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumBeam + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumPulseGate + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%PulseSpacing + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%URefLid + Int_Xferred = Int_Xferred + 1 DbKiBuf(Db_Xferred) = InData%DLL_DT Db_Xferred = Db_Xferred + 1 DO I = 1, LEN(InData%DLL_InFile) @@ -4866,6 +5346,88 @@ SUBROUTINE SrvD_UnPackBladedDLLType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrSta Re_Xferred = Re_Xferred + 1 OutData%LSShftFzs = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LidSpeed not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LidSpeed)) DEALLOCATE(OutData%LidSpeed) + ALLOCATE(OutData%LidSpeed(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LidSpeed.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LidSpeed,1), UBOUND(OutData%LidSpeed,1) + OutData%LidSpeed(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MsrPositionsX not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MsrPositionsX)) DEALLOCATE(OutData%MsrPositionsX) + ALLOCATE(OutData%MsrPositionsX(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MsrPositionsX.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MsrPositionsX,1), UBOUND(OutData%MsrPositionsX,1) + OutData%MsrPositionsX(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MsrPositionsY not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MsrPositionsY)) DEALLOCATE(OutData%MsrPositionsY) + ALLOCATE(OutData%MsrPositionsY(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MsrPositionsY.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MsrPositionsY,1), UBOUND(OutData%MsrPositionsY,1) + OutData%MsrPositionsY(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MsrPositionsZ not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MsrPositionsZ)) DEALLOCATE(OutData%MsrPositionsZ) + ALLOCATE(OutData%MsrPositionsZ(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MsrPositionsZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MsrPositionsZ,1), UBOUND(OutData%MsrPositionsZ,1) + OutData%MsrPositionsZ(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + OutData%SensorType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NumBeam = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NumPulseGate = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%PulseSpacing = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%URefLid = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%DLL_DT = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 DO I = 1, LEN(OutData%DLL_InFile) @@ -5326,36 +5888,52 @@ SUBROUTINE SrvD_CopyContState( SrcContStateData, DstContStateData, CtrlCode, Err ENDIF END SUBROUTINE SrvD_CopyContState - SUBROUTINE SrvD_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE SrvD_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SrvD_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%BStC)) THEN DO i1 = LBOUND(ContStateData%BStC,1), UBOUND(ContStateData%BStC,1) - CALL StC_DestroyContState( ContStateData%BStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyContState( ContStateData%BStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ContStateData%BStC) ENDIF IF (ALLOCATED(ContStateData%NStC)) THEN DO i1 = LBOUND(ContStateData%NStC,1), UBOUND(ContStateData%NStC,1) - CALL StC_DestroyContState( ContStateData%NStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyContState( ContStateData%NStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ContStateData%NStC) ENDIF IF (ALLOCATED(ContStateData%TStC)) THEN DO i1 = LBOUND(ContStateData%TStC,1), UBOUND(ContStateData%TStC,1) - CALL StC_DestroyContState( ContStateData%TStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyContState( ContStateData%TStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ContStateData%TStC) ENDIF IF (ALLOCATED(ContStateData%SStC)) THEN DO i1 = LBOUND(ContStateData%SStC,1), UBOUND(ContStateData%SStC,1) - CALL StC_DestroyContState( ContStateData%SStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyContState( ContStateData%SStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ContStateData%SStC) ENDIF @@ -6022,36 +6600,52 @@ SUBROUTINE SrvD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, Err ENDIF END SUBROUTINE SrvD_CopyDiscState - SUBROUTINE SrvD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE SrvD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SrvD_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(DiscStateData%BStC)) THEN DO i1 = LBOUND(DiscStateData%BStC,1), UBOUND(DiscStateData%BStC,1) - CALL StC_DestroyDiscState( DiscStateData%BStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyDiscState( DiscStateData%BStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(DiscStateData%BStC) ENDIF IF (ALLOCATED(DiscStateData%NStC)) THEN DO i1 = LBOUND(DiscStateData%NStC,1), UBOUND(DiscStateData%NStC,1) - CALL StC_DestroyDiscState( DiscStateData%NStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyDiscState( DiscStateData%NStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(DiscStateData%NStC) ENDIF IF (ALLOCATED(DiscStateData%TStC)) THEN DO i1 = LBOUND(DiscStateData%TStC,1), UBOUND(DiscStateData%TStC,1) - CALL StC_DestroyDiscState( DiscStateData%TStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyDiscState( DiscStateData%TStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(DiscStateData%TStC) ENDIF IF (ALLOCATED(DiscStateData%SStC)) THEN DO i1 = LBOUND(DiscStateData%SStC,1), UBOUND(DiscStateData%SStC,1) - CALL StC_DestroyDiscState( DiscStateData%SStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyDiscState( DiscStateData%SStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(DiscStateData%SStC) ENDIF @@ -6718,36 +7312,52 @@ SUBROUTINE SrvD_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCod ENDIF END SUBROUTINE SrvD_CopyConstrState - SUBROUTINE SrvD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE SrvD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SrvD_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ConstrStateData%BStC)) THEN DO i1 = LBOUND(ConstrStateData%BStC,1), UBOUND(ConstrStateData%BStC,1) - CALL StC_DestroyConstrState( ConstrStateData%BStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyConstrState( ConstrStateData%BStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ConstrStateData%BStC) ENDIF IF (ALLOCATED(ConstrStateData%NStC)) THEN DO i1 = LBOUND(ConstrStateData%NStC,1), UBOUND(ConstrStateData%NStC,1) - CALL StC_DestroyConstrState( ConstrStateData%NStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyConstrState( ConstrStateData%NStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ConstrStateData%NStC) ENDIF IF (ALLOCATED(ConstrStateData%TStC)) THEN DO i1 = LBOUND(ConstrStateData%TStC,1), UBOUND(ConstrStateData%TStC,1) - CALL StC_DestroyConstrState( ConstrStateData%TStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyConstrState( ConstrStateData%TStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ConstrStateData%TStC) ENDIF IF (ALLOCATED(ConstrStateData%SStC)) THEN DO i1 = LBOUND(ConstrStateData%SStC,1), UBOUND(ConstrStateData%SStC,1) - CALL StC_DestroyConstrState( ConstrStateData%SStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyConstrState( ConstrStateData%SStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ConstrStateData%SStC) ENDIF @@ -7491,15 +8101,27 @@ SUBROUTINE SrvD_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ENDIF END SUBROUTINE SrvD_CopyOtherState - SUBROUTINE SrvD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE SrvD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SrvD_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OtherStateData%BegPitMan)) THEN DEALLOCATE(OtherStateData%BegPitMan) ENDIF @@ -7520,25 +8142,29 @@ SUBROUTINE SrvD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(OtherStateData%BStC)) THEN DO i1 = LBOUND(OtherStateData%BStC,1), UBOUND(OtherStateData%BStC,1) - CALL StC_DestroyOtherState( OtherStateData%BStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyOtherState( OtherStateData%BStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OtherStateData%BStC) ENDIF IF (ALLOCATED(OtherStateData%NStC)) THEN DO i1 = LBOUND(OtherStateData%NStC,1), UBOUND(OtherStateData%NStC,1) - CALL StC_DestroyOtherState( OtherStateData%NStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyOtherState( OtherStateData%NStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OtherStateData%NStC) ENDIF IF (ALLOCATED(OtherStateData%TStC)) THEN DO i1 = LBOUND(OtherStateData%TStC,1), UBOUND(OtherStateData%TStC,1) - CALL StC_DestroyOtherState( OtherStateData%TStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyOtherState( OtherStateData%TStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OtherStateData%TStC) ENDIF IF (ALLOCATED(OtherStateData%SStC)) THEN DO i1 = LBOUND(OtherStateData%SStC,1), UBOUND(OtherStateData%SStC,1) - CALL StC_DestroyOtherState( OtherStateData%SStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyOtherState( OtherStateData%SStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OtherStateData%SStC) ENDIF @@ -8530,64 +9156,84 @@ SUBROUTINE SrvD_CopyModuleMapType( SrcModuleMapTypeData, DstModuleMapTypeData, C ENDIF END SUBROUTINE SrvD_CopyModuleMapType - SUBROUTINE SrvD_DestroyModuleMapType( ModuleMapTypeData, ErrStat, ErrMsg ) + SUBROUTINE SrvD_DestroyModuleMapType( ModuleMapTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SrvD_ModuleMapType), INTENT(INOUT) :: ModuleMapTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyModuleMapType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyModuleMapType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ModuleMapTypeData%u_BStC_Mot2_BStC)) THEN DO i2 = LBOUND(ModuleMapTypeData%u_BStC_Mot2_BStC,2), UBOUND(ModuleMapTypeData%u_BStC_Mot2_BStC,2) DO i1 = LBOUND(ModuleMapTypeData%u_BStC_Mot2_BStC,1), UBOUND(ModuleMapTypeData%u_BStC_Mot2_BStC,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%u_BStC_Mot2_BStC(i1,i2), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%u_BStC_Mot2_BStC(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(ModuleMapTypeData%u_BStC_Mot2_BStC) ENDIF IF (ALLOCATED(ModuleMapTypeData%u_NStC_Mot2_NStC)) THEN DO i1 = LBOUND(ModuleMapTypeData%u_NStC_Mot2_NStC,1), UBOUND(ModuleMapTypeData%u_NStC_Mot2_NStC,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%u_NStC_Mot2_NStC(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%u_NStC_Mot2_NStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%u_NStC_Mot2_NStC) ENDIF IF (ALLOCATED(ModuleMapTypeData%u_TStC_Mot2_TStC)) THEN DO i1 = LBOUND(ModuleMapTypeData%u_TStC_Mot2_TStC,1), UBOUND(ModuleMapTypeData%u_TStC_Mot2_TStC,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%u_TStC_Mot2_TStC(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%u_TStC_Mot2_TStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%u_TStC_Mot2_TStC) ENDIF IF (ALLOCATED(ModuleMapTypeData%u_SStC_Mot2_SStC)) THEN DO i1 = LBOUND(ModuleMapTypeData%u_SStC_Mot2_SStC,1), UBOUND(ModuleMapTypeData%u_SStC_Mot2_SStC,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%u_SStC_Mot2_SStC(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%u_SStC_Mot2_SStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%u_SStC_Mot2_SStC) ENDIF IF (ALLOCATED(ModuleMapTypeData%BStC_Frc2_y_BStC)) THEN DO i2 = LBOUND(ModuleMapTypeData%BStC_Frc2_y_BStC,2), UBOUND(ModuleMapTypeData%BStC_Frc2_y_BStC,2) DO i1 = LBOUND(ModuleMapTypeData%BStC_Frc2_y_BStC,1), UBOUND(ModuleMapTypeData%BStC_Frc2_y_BStC,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BStC_Frc2_y_BStC(i1,i2), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%BStC_Frc2_y_BStC(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(ModuleMapTypeData%BStC_Frc2_y_BStC) ENDIF IF (ALLOCATED(ModuleMapTypeData%NStC_Frc2_y_NStC)) THEN DO i1 = LBOUND(ModuleMapTypeData%NStC_Frc2_y_NStC,1), UBOUND(ModuleMapTypeData%NStC_Frc2_y_NStC,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%NStC_Frc2_y_NStC(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%NStC_Frc2_y_NStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%NStC_Frc2_y_NStC) ENDIF IF (ALLOCATED(ModuleMapTypeData%TStC_Frc2_y_TStC)) THEN DO i1 = LBOUND(ModuleMapTypeData%TStC_Frc2_y_TStC,1), UBOUND(ModuleMapTypeData%TStC_Frc2_y_TStC,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%TStC_Frc2_y_TStC(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%TStC_Frc2_y_TStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%TStC_Frc2_y_TStC) ENDIF IF (ALLOCATED(ModuleMapTypeData%SStC_Frc2_y_SStC)) THEN DO i1 = LBOUND(ModuleMapTypeData%SStC_Frc2_y_SStC,1), UBOUND(ModuleMapTypeData%SStC_Frc2_y_SStC,1) - CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SStC_Frc2_y_SStC(i1), ErrStat, ErrMsg ) + CALL NWTC_Library_Destroymeshmaptype( ModuleMapTypeData%SStC_Frc2_y_SStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ModuleMapTypeData%SStC_Frc2_y_SStC) ENDIF @@ -9920,47 +10566,65 @@ SUBROUTINE SrvD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%PrevTstepNcall = SrcMiscData%PrevTstepNcall END SUBROUTINE SrvD_CopyMisc - SUBROUTINE SrvD_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE SrvD_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SrvD_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" - CALL SrvD_Destroybladeddlltype( MiscData%dll_data, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL SrvD_Destroybladeddlltype( MiscData%dll_data, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(MiscData%xd_BlPitchFilter)) THEN DEALLOCATE(MiscData%xd_BlPitchFilter) ENDIF IF (ALLOCATED(MiscData%BStC)) THEN DO i1 = LBOUND(MiscData%BStC,1), UBOUND(MiscData%BStC,1) - CALL StC_DestroyMisc( MiscData%BStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyMisc( MiscData%BStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%BStC) ENDIF IF (ALLOCATED(MiscData%NStC)) THEN DO i1 = LBOUND(MiscData%NStC,1), UBOUND(MiscData%NStC,1) - CALL StC_DestroyMisc( MiscData%NStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyMisc( MiscData%NStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%NStC) ENDIF IF (ALLOCATED(MiscData%TStC)) THEN DO i1 = LBOUND(MiscData%TStC,1), UBOUND(MiscData%TStC,1) - CALL StC_DestroyMisc( MiscData%TStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyMisc( MiscData%TStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%TStC) ENDIF IF (ALLOCATED(MiscData%SStC)) THEN DO i1 = LBOUND(MiscData%SStC,1), UBOUND(MiscData%SStC,1) - CALL StC_DestroyMisc( MiscData%SStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyMisc( MiscData%SStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%SStC) ENDIF IF (ALLOCATED(MiscData%u_BStC)) THEN DO i2 = LBOUND(MiscData%u_BStC,2), UBOUND(MiscData%u_BStC,2) DO i1 = LBOUND(MiscData%u_BStC,1), UBOUND(MiscData%u_BStC,1) - CALL StC_DestroyInput( MiscData%u_BStC(i1,i2), ErrStat, ErrMsg ) + CALL StC_DestroyInput( MiscData%u_BStC(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(MiscData%u_BStC) @@ -9968,7 +10632,8 @@ SUBROUTINE SrvD_DestroyMisc( MiscData, ErrStat, ErrMsg ) IF (ALLOCATED(MiscData%u_NStC)) THEN DO i2 = LBOUND(MiscData%u_NStC,2), UBOUND(MiscData%u_NStC,2) DO i1 = LBOUND(MiscData%u_NStC,1), UBOUND(MiscData%u_NStC,1) - CALL StC_DestroyInput( MiscData%u_NStC(i1,i2), ErrStat, ErrMsg ) + CALL StC_DestroyInput( MiscData%u_NStC(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(MiscData%u_NStC) @@ -9976,7 +10641,8 @@ SUBROUTINE SrvD_DestroyMisc( MiscData, ErrStat, ErrMsg ) IF (ALLOCATED(MiscData%u_TStC)) THEN DO i2 = LBOUND(MiscData%u_TStC,2), UBOUND(MiscData%u_TStC,2) DO i1 = LBOUND(MiscData%u_TStC,1), UBOUND(MiscData%u_TStC,1) - CALL StC_DestroyInput( MiscData%u_TStC(i1,i2), ErrStat, ErrMsg ) + CALL StC_DestroyInput( MiscData%u_TStC(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(MiscData%u_TStC) @@ -9984,36 +10650,42 @@ SUBROUTINE SrvD_DestroyMisc( MiscData, ErrStat, ErrMsg ) IF (ALLOCATED(MiscData%u_SStC)) THEN DO i2 = LBOUND(MiscData%u_SStC,2), UBOUND(MiscData%u_SStC,2) DO i1 = LBOUND(MiscData%u_SStC,1), UBOUND(MiscData%u_SStC,1) - CALL StC_DestroyInput( MiscData%u_SStC(i1,i2), ErrStat, ErrMsg ) + CALL StC_DestroyInput( MiscData%u_SStC(i1,i2), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(MiscData%u_SStC) ENDIF IF (ALLOCATED(MiscData%y_BStC)) THEN DO i1 = LBOUND(MiscData%y_BStC,1), UBOUND(MiscData%y_BStC,1) - CALL StC_DestroyOutput( MiscData%y_BStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyOutput( MiscData%y_BStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%y_BStC) ENDIF IF (ALLOCATED(MiscData%y_NStC)) THEN DO i1 = LBOUND(MiscData%y_NStC,1), UBOUND(MiscData%y_NStC,1) - CALL StC_DestroyOutput( MiscData%y_NStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyOutput( MiscData%y_NStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%y_NStC) ENDIF IF (ALLOCATED(MiscData%y_TStC)) THEN DO i1 = LBOUND(MiscData%y_TStC,1), UBOUND(MiscData%y_TStC,1) - CALL StC_DestroyOutput( MiscData%y_TStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyOutput( MiscData%y_TStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%y_TStC) ENDIF IF (ALLOCATED(MiscData%y_SStC)) THEN DO i1 = LBOUND(MiscData%y_SStC,1), UBOUND(MiscData%y_SStC,1) - CALL StC_DestroyOutput( MiscData%y_SStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyOutput( MiscData%y_SStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(MiscData%y_SStC) ENDIF - CALL SrvD_Destroymodulemaptype( MiscData%SrvD_MeshMap, ErrStat, ErrMsg ) + CALL SrvD_Destroymodulemaptype( MiscData%SrvD_MeshMap, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE SrvD_DestroyMisc SUBROUTINE SrvD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -12313,17 +12985,34 @@ SUBROUTINE SrvD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg END IF DstParamData%Jac_Idx_SStC_y = SrcParamData%Jac_Idx_SStC_y ENDIF + DstParamData%SensorType = SrcParamData%SensorType + DstParamData%NumBeam = SrcParamData%NumBeam + DstParamData%NumPulseGate = SrcParamData%NumPulseGate + DstParamData%PulseSpacing = SrcParamData%PulseSpacing + DstParamData%URefLid = SrcParamData%URefLid END SUBROUTINE SrvD_CopyParam - SUBROUTINE SrvD_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE SrvD_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SrvD_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%BlPitchInit)) THEN DEALLOCATE(ParamData%BlPitchInit) ENDIF @@ -12341,32 +13030,38 @@ SUBROUTINE SrvD_DestroyParam( ParamData, ErrStat, ErrMsg ) 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 ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF - CALL FreeDynamicLib( ParamData%DLL_Trgt, ErrStat, ErrMsg ) + CALL FreeDynamicLib( ParamData%DLL_Trgt, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(ParamData%BStC)) THEN DO i1 = LBOUND(ParamData%BStC,1), UBOUND(ParamData%BStC,1) - CALL StC_DestroyParam( ParamData%BStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyParam( ParamData%BStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%BStC) ENDIF IF (ALLOCATED(ParamData%NStC)) THEN DO i1 = LBOUND(ParamData%NStC,1), UBOUND(ParamData%NStC,1) - CALL StC_DestroyParam( ParamData%NStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyParam( ParamData%NStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%NStC) ENDIF IF (ALLOCATED(ParamData%TStC)) THEN DO i1 = LBOUND(ParamData%TStC,1), UBOUND(ParamData%TStC,1) - CALL StC_DestroyParam( ParamData%TStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyParam( ParamData%TStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%TStC) ENDIF IF (ALLOCATED(ParamData%SStC)) THEN DO i1 = LBOUND(ParamData%SStC,1), UBOUND(ParamData%SStC,1) - CALL StC_DestroyParam( ParamData%SStC(i1), ErrStat, ErrMsg ) + CALL StC_DestroyParam( ParamData%SStC(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%SStC) ENDIF @@ -12791,6 +13486,11 @@ SUBROUTINE SrvD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 2*2 ! Jac_Idx_SStC_y upper/lower bounds for each dimension Int_BufSz = Int_BufSz + SIZE(InData%Jac_Idx_SStC_y) ! Jac_Idx_SStC_y END IF + Int_BufSz = Int_BufSz + 1 ! SensorType + Int_BufSz = Int_BufSz + 1 ! NumBeam + Int_BufSz = Int_BufSz + 1 ! NumPulseGate + Re_BufSz = Re_BufSz + 1 ! PulseSpacing + Re_BufSz = Re_BufSz + 1 ! URefLid IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -13650,6 +14350,16 @@ SUBROUTINE SrvD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END DO END DO END IF + IntKiBuf(Int_Xferred) = InData%SensorType + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumBeam + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumPulseGate + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%PulseSpacing + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%URefLid + Re_Xferred = Re_Xferred + 1 END SUBROUTINE SrvD_PackParam SUBROUTINE SrvD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -14666,6 +15376,16 @@ SUBROUTINE SrvD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs END DO END DO END IF + OutData%SensorType = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NumBeam = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%NumPulseGate = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%PulseSpacing = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%URefLid = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE SrvD_UnPackParam SUBROUTINE SrvD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) @@ -14884,18 +15604,78 @@ SUBROUTINE SrvD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ErrStat>=AbortErrLev) RETURN ENDDO +ENDIF +IF (ALLOCATED(SrcInputData%LidSpeed)) THEN + i1_l = LBOUND(SrcInputData%LidSpeed,1) + i1_u = UBOUND(SrcInputData%LidSpeed,1) + IF (.NOT. ALLOCATED(DstInputData%LidSpeed)) THEN + ALLOCATE(DstInputData%LidSpeed(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%LidSpeed.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%LidSpeed = SrcInputData%LidSpeed +ENDIF +IF (ALLOCATED(SrcInputData%MsrPositionsX)) THEN + i1_l = LBOUND(SrcInputData%MsrPositionsX,1) + i1_u = UBOUND(SrcInputData%MsrPositionsX,1) + IF (.NOT. ALLOCATED(DstInputData%MsrPositionsX)) THEN + ALLOCATE(DstInputData%MsrPositionsX(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%MsrPositionsX.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%MsrPositionsX = SrcInputData%MsrPositionsX +ENDIF +IF (ALLOCATED(SrcInputData%MsrPositionsY)) THEN + i1_l = LBOUND(SrcInputData%MsrPositionsY,1) + i1_u = UBOUND(SrcInputData%MsrPositionsY,1) + IF (.NOT. ALLOCATED(DstInputData%MsrPositionsY)) THEN + ALLOCATE(DstInputData%MsrPositionsY(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%MsrPositionsY.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%MsrPositionsY = SrcInputData%MsrPositionsY +ENDIF +IF (ALLOCATED(SrcInputData%MsrPositionsZ)) THEN + i1_l = LBOUND(SrcInputData%MsrPositionsZ,1) + i1_u = UBOUND(SrcInputData%MsrPositionsZ,1) + IF (.NOT. ALLOCATED(DstInputData%MsrPositionsZ)) THEN + ALLOCATE(DstInputData%MsrPositionsZ(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%MsrPositionsZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%MsrPositionsZ = SrcInputData%MsrPositionsZ ENDIF END SUBROUTINE SrvD_CopyInput - SUBROUTINE SrvD_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE SrvD_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SrvD_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%BlPitch)) THEN DEALLOCATE(InputData%BlPitch) ENDIF @@ -14920,32 +15700,49 @@ SUBROUTINE SrvD_DestroyInput( InputData, ErrStat, ErrMsg ) IF (ALLOCATED(InputData%Lidar)) THEN DEALLOCATE(InputData%Lidar) ENDIF - CALL MeshDestroy( InputData%PtfmMotionMesh, ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%PtfmMotionMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InputData%BStCMotionMesh)) THEN DO i2 = LBOUND(InputData%BStCMotionMesh,2), UBOUND(InputData%BStCMotionMesh,2) DO i1 = LBOUND(InputData%BStCMotionMesh,1), UBOUND(InputData%BStCMotionMesh,1) - CALL MeshDestroy( InputData%BStCMotionMesh(i1,i2), ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%BStCMotionMesh(i1,i2), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(InputData%BStCMotionMesh) ENDIF IF (ALLOCATED(InputData%NStCMotionMesh)) THEN DO i1 = LBOUND(InputData%NStCMotionMesh,1), UBOUND(InputData%NStCMotionMesh,1) - CALL MeshDestroy( InputData%NStCMotionMesh(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%NStCMotionMesh(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InputData%NStCMotionMesh) ENDIF IF (ALLOCATED(InputData%TStCMotionMesh)) THEN DO i1 = LBOUND(InputData%TStCMotionMesh,1), UBOUND(InputData%TStCMotionMesh,1) - CALL MeshDestroy( InputData%TStCMotionMesh(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%TStCMotionMesh(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InputData%TStCMotionMesh) ENDIF IF (ALLOCATED(InputData%SStCMotionMesh)) THEN DO i1 = LBOUND(InputData%SStCMotionMesh,1), UBOUND(InputData%SStCMotionMesh,1) - CALL MeshDestroy( InputData%SStCMotionMesh(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%SStCMotionMesh(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InputData%SStCMotionMesh) +ENDIF +IF (ALLOCATED(InputData%LidSpeed)) THEN + DEALLOCATE(InputData%LidSpeed) +ENDIF +IF (ALLOCATED(InputData%MsrPositionsX)) THEN + DEALLOCATE(InputData%MsrPositionsX) +ENDIF +IF (ALLOCATED(InputData%MsrPositionsY)) THEN + DEALLOCATE(InputData%MsrPositionsY) +ENDIF +IF (ALLOCATED(InputData%MsrPositionsZ)) THEN + DEALLOCATE(InputData%MsrPositionsZ) ENDIF END SUBROUTINE SrvD_DestroyInput @@ -15170,6 +15967,26 @@ SUBROUTINE SrvD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END IF END DO END IF + Int_BufSz = Int_BufSz + 1 ! LidSpeed allocated yes/no + IF ( ALLOCATED(InData%LidSpeed) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! LidSpeed upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%LidSpeed) ! LidSpeed + END IF + Int_BufSz = Int_BufSz + 1 ! MsrPositionsX allocated yes/no + IF ( ALLOCATED(InData%MsrPositionsX) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MsrPositionsX upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MsrPositionsX) ! MsrPositionsX + END IF + Int_BufSz = Int_BufSz + 1 ! MsrPositionsY allocated yes/no + IF ( ALLOCATED(InData%MsrPositionsY) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MsrPositionsY upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MsrPositionsY) ! MsrPositionsY + END IF + Int_BufSz = Int_BufSz + 1 ! MsrPositionsZ allocated yes/no + IF ( ALLOCATED(InData%MsrPositionsZ) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! MsrPositionsZ upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%MsrPositionsZ) ! MsrPositionsZ + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -15586,6 +16403,66 @@ SUBROUTINE SrvD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, ENDIF END DO END IF + IF ( .NOT. ALLOCATED(InData%LidSpeed) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%LidSpeed,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%LidSpeed,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%LidSpeed,1), UBOUND(InData%LidSpeed,1) + ReKiBuf(Re_Xferred) = InData%LidSpeed(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MsrPositionsX) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPositionsX,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPositionsX,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MsrPositionsX,1), UBOUND(InData%MsrPositionsX,1) + ReKiBuf(Re_Xferred) = InData%MsrPositionsX(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MsrPositionsY) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPositionsY,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPositionsY,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MsrPositionsY,1), UBOUND(InData%MsrPositionsY,1) + ReKiBuf(Re_Xferred) = InData%MsrPositionsY(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%MsrPositionsZ) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%MsrPositionsZ,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%MsrPositionsZ,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%MsrPositionsZ,1), UBOUND(InData%MsrPositionsZ,1) + ReKiBuf(Re_Xferred) = InData%MsrPositionsZ(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE SrvD_PackInput SUBROUTINE SrvD_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -16105,6 +16982,78 @@ SUBROUTINE SrvD_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! LidSpeed not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%LidSpeed)) DEALLOCATE(OutData%LidSpeed) + ALLOCATE(OutData%LidSpeed(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%LidSpeed.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%LidSpeed,1), UBOUND(OutData%LidSpeed,1) + OutData%LidSpeed(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MsrPositionsX not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MsrPositionsX)) DEALLOCATE(OutData%MsrPositionsX) + ALLOCATE(OutData%MsrPositionsX(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MsrPositionsX.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MsrPositionsX,1), UBOUND(OutData%MsrPositionsX,1) + OutData%MsrPositionsX(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MsrPositionsY not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MsrPositionsY)) DEALLOCATE(OutData%MsrPositionsY) + ALLOCATE(OutData%MsrPositionsY(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MsrPositionsY.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MsrPositionsY,1), UBOUND(OutData%MsrPositionsY,1) + OutData%MsrPositionsY(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! MsrPositionsZ not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%MsrPositionsZ)) DEALLOCATE(OutData%MsrPositionsZ) + ALLOCATE(OutData%MsrPositionsZ(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%MsrPositionsZ.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%MsrPositionsZ,1), UBOUND(OutData%MsrPositionsZ,1) + OutData%MsrPositionsZ(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE SrvD_UnPackInput SUBROUTINE SrvD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -16293,15 +17242,27 @@ SUBROUTINE SrvD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Err ENDIF END SUBROUTINE SrvD_CopyOutput - SUBROUTINE SrvD_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE SrvD_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SrvD_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SrvD_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF @@ -16326,26 +17287,30 @@ SUBROUTINE SrvD_DestroyOutput( OutputData, ErrStat, ErrMsg ) IF (ALLOCATED(OutputData%BStCLoadMesh)) THEN DO i2 = LBOUND(OutputData%BStCLoadMesh,2), UBOUND(OutputData%BStCLoadMesh,2) DO i1 = LBOUND(OutputData%BStCLoadMesh,1), UBOUND(OutputData%BStCLoadMesh,1) - CALL MeshDestroy( OutputData%BStCLoadMesh(i1,i2), ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%BStCLoadMesh(i1,i2), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO ENDDO DEALLOCATE(OutputData%BStCLoadMesh) ENDIF IF (ALLOCATED(OutputData%NStCLoadMesh)) THEN DO i1 = LBOUND(OutputData%NStCLoadMesh,1), UBOUND(OutputData%NStCLoadMesh,1) - CALL MeshDestroy( OutputData%NStCLoadMesh(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%NStCLoadMesh(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OutputData%NStCLoadMesh) ENDIF IF (ALLOCATED(OutputData%TStCLoadMesh)) THEN DO i1 = LBOUND(OutputData%TStCLoadMesh,1), UBOUND(OutputData%TStCLoadMesh,1) - CALL MeshDestroy( OutputData%TStCLoadMesh(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%TStCLoadMesh(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OutputData%TStCLoadMesh) ENDIF IF (ALLOCATED(OutputData%SStCLoadMesh)) THEN DO i1 = LBOUND(OutputData%SStCLoadMesh,1), UBOUND(OutputData%SStCLoadMesh,1) - CALL MeshDestroy( OutputData%SStCLoadMesh(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%SStCLoadMesh(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OutputData%SStCLoadMesh) ENDIF @@ -17456,7 +18421,7 @@ SUBROUTINE SrvD_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg b = -(u1%LSShftFys - u2%LSShftFys) u_out%LSShftFys = u1%LSShftFys + b * ScaleFactor b = -(u1%LSShftFzs - u2%LSShftFzs) - u_out%LSShftFzs = u1%LSShftFzs + b * ScaleFactor + u_out%LSShftFzs = u1%LSShftFzs + b * ScaleFactor IF (ALLOCATED(u_out%fromSC) .AND. ALLOCATED(u1%fromSC)) THEN DO i1 = LBOUND(u_out%fromSC,1),UBOUND(u_out%fromSC,1) b = -(u1%fromSC(i1) - u2%fromSC(i1)) @@ -17502,6 +18467,30 @@ SUBROUTINE SrvD_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg CALL MeshExtrapInterp1(u1%SStCMotionMesh(i1), u2%SStCMotionMesh(i1), tin, u_out%SStCMotionMesh(i1), tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) ENDDO +END IF ! check if allocated +IF (ALLOCATED(u_out%LidSpeed) .AND. ALLOCATED(u1%LidSpeed)) THEN + DO i1 = LBOUND(u_out%LidSpeed,1),UBOUND(u_out%LidSpeed,1) + b = -(u1%LidSpeed(i1) - u2%LidSpeed(i1)) + u_out%LidSpeed(i1) = u1%LidSpeed(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ALLOCATED(u_out%MsrPositionsX) .AND. ALLOCATED(u1%MsrPositionsX)) THEN + DO i1 = LBOUND(u_out%MsrPositionsX,1),UBOUND(u_out%MsrPositionsX,1) + b = -(u1%MsrPositionsX(i1) - u2%MsrPositionsX(i1)) + u_out%MsrPositionsX(i1) = u1%MsrPositionsX(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ALLOCATED(u_out%MsrPositionsY) .AND. ALLOCATED(u1%MsrPositionsY)) THEN + DO i1 = LBOUND(u_out%MsrPositionsY,1),UBOUND(u_out%MsrPositionsY,1) + b = -(u1%MsrPositionsY(i1) - u2%MsrPositionsY(i1)) + u_out%MsrPositionsY(i1) = u1%MsrPositionsY(i1) + b * ScaleFactor + END DO +END IF ! check if allocated +IF (ALLOCATED(u_out%MsrPositionsZ) .AND. ALLOCATED(u1%MsrPositionsZ)) THEN + DO i1 = LBOUND(u_out%MsrPositionsZ,1),UBOUND(u_out%MsrPositionsZ,1) + b = -(u1%MsrPositionsZ(i1) - u2%MsrPositionsZ(i1)) + u_out%MsrPositionsZ(i1) = u1%MsrPositionsZ(i1) + b * ScaleFactor + END DO END IF ! check if allocated END SUBROUTINE SrvD_Input_ExtrapInterp1 @@ -17688,7 +18677,7 @@ SUBROUTINE SrvD_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, Er u_out%LSShftFys = u1%LSShftFys + b + c * t_out b = (t(3)**2*(u1%LSShftFzs - u2%LSShftFzs) + t(2)**2*(-u1%LSShftFzs + u3%LSShftFzs))* scaleFactor c = ( (t(2)-t(3))*u1%LSShftFzs + t(3)*u2%LSShftFzs - t(2)*u3%LSShftFzs ) * scaleFactor - u_out%LSShftFzs = u1%LSShftFzs + b + c * t_out + u_out%LSShftFzs = u1%LSShftFzs + b + c * t_out IF (ALLOCATED(u_out%fromSC) .AND. ALLOCATED(u1%fromSC)) THEN DO i1 = LBOUND(u_out%fromSC,1),UBOUND(u_out%fromSC,1) b = (t(3)**2*(u1%fromSC(i1) - u2%fromSC(i1)) + t(2)**2*(-u1%fromSC(i1) + u3%fromSC(i1)))* scaleFactor @@ -17737,6 +18726,34 @@ SUBROUTINE SrvD_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, Er CALL MeshExtrapInterp2(u1%SStCMotionMesh(i1), u2%SStCMotionMesh(i1), u3%SStCMotionMesh(i1), tin, u_out%SStCMotionMesh(i1), tin_out, ErrStat2, ErrMsg2 ) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) ENDDO +END IF ! check if allocated +IF (ALLOCATED(u_out%LidSpeed) .AND. ALLOCATED(u1%LidSpeed)) THEN + DO i1 = LBOUND(u_out%LidSpeed,1),UBOUND(u_out%LidSpeed,1) + b = (t(3)**2*(u1%LidSpeed(i1) - u2%LidSpeed(i1)) + t(2)**2*(-u1%LidSpeed(i1) + u3%LidSpeed(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%LidSpeed(i1) + t(3)*u2%LidSpeed(i1) - t(2)*u3%LidSpeed(i1) ) * scaleFactor + u_out%LidSpeed(i1) = u1%LidSpeed(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ALLOCATED(u_out%MsrPositionsX) .AND. ALLOCATED(u1%MsrPositionsX)) THEN + DO i1 = LBOUND(u_out%MsrPositionsX,1),UBOUND(u_out%MsrPositionsX,1) + b = (t(3)**2*(u1%MsrPositionsX(i1) - u2%MsrPositionsX(i1)) + t(2)**2*(-u1%MsrPositionsX(i1) + u3%MsrPositionsX(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%MsrPositionsX(i1) + t(3)*u2%MsrPositionsX(i1) - t(2)*u3%MsrPositionsX(i1) ) * scaleFactor + u_out%MsrPositionsX(i1) = u1%MsrPositionsX(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ALLOCATED(u_out%MsrPositionsY) .AND. ALLOCATED(u1%MsrPositionsY)) THEN + DO i1 = LBOUND(u_out%MsrPositionsY,1),UBOUND(u_out%MsrPositionsY,1) + b = (t(3)**2*(u1%MsrPositionsY(i1) - u2%MsrPositionsY(i1)) + t(2)**2*(-u1%MsrPositionsY(i1) + u3%MsrPositionsY(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%MsrPositionsY(i1) + t(3)*u2%MsrPositionsY(i1) - t(2)*u3%MsrPositionsY(i1) ) * scaleFactor + u_out%MsrPositionsY(i1) = u1%MsrPositionsY(i1) + b + c * t_out + END DO +END IF ! check if allocated +IF (ALLOCATED(u_out%MsrPositionsZ) .AND. ALLOCATED(u1%MsrPositionsZ)) THEN + DO i1 = LBOUND(u_out%MsrPositionsZ,1),UBOUND(u_out%MsrPositionsZ,1) + b = (t(3)**2*(u1%MsrPositionsZ(i1) - u2%MsrPositionsZ(i1)) + t(2)**2*(-u1%MsrPositionsZ(i1) + u3%MsrPositionsZ(i1)))* scaleFactor + c = ( (t(2)-t(3))*u1%MsrPositionsZ(i1) + t(3)*u2%MsrPositionsZ(i1) - t(2)*u3%MsrPositionsZ(i1) ) * scaleFactor + u_out%MsrPositionsZ(i1) = u1%MsrPositionsZ(i1) + b + c * t_out + END DO END IF ! check if allocated END SUBROUTINE SrvD_Input_ExtrapInterp2 diff --git a/modules/servodyn/src/StrucCtrl.f90 b/modules/servodyn/src/StrucCtrl.f90 index 04598a739..60c9efd53 100644 --- a/modules/servodyn/src/StrucCtrl.f90 +++ b/modules/servodyn/src/StrucCtrl.f90 @@ -50,6 +50,7 @@ MODULE StrucCtrl INTEGER(IntKi), PRIVATE, PARAMETER :: DOFMode_Omni = 2 !< omni-directional INTEGER(IntKi), PRIVATE, PARAMETER :: DOFMode_TLCD = 3 !< tuned liquid column dampers !MEG & SP INTEGER(IntKi), PRIVATE, PARAMETER :: DOFMode_Prescribed = 4 !< prescribed force series + INTEGER(IntKi), PRIVATE, PARAMETER :: DOFMode_ForceDLL = 5 !< prescribed force series INTEGER(IntKi), PRIVATE, PARAMETER :: CMODE_Semi = 1 !< semi-active control INTEGER(IntKi), PRIVATE, PARAMETER :: CMODE_ActiveEXTERN = 4 !< active control @@ -971,6 +972,23 @@ SUBROUTINE StC_CalcOutput( Time, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrM y%Mesh(i_pt)%Moment(1:3,1) = matmul(transpose(u%Mesh(i_pt)%Orientation(:,:,1)), m%M_P(1:3,i_pt)) enddo endif + ELSEIF ( p%StC_DOF_MODE == DOFMode_ForceDLL ) THEN + ! Note that the prescribed force is applied the same to all Mesh pts + ! that are passed into this instance of the StC + if (p%PrescribedForcesCoordSys == PRESCRIBED_FORCE_GLOBAL) then + ! Global coords + do i_pt=1,p%NumMeshPts + y%Mesh(i_pt)%Force(1:3,1) = m%F_ext(1:3,i_pt) + y%Mesh(i_pt)%Moment(1:3,1) = 0 + enddo + ! Leave in for now just in case we decide there is a use case for a follower force from the DLL + ! elseif (p%PrescribedForcesCoordSys == PRESCRIBED_FORCE_LOCAL) then + ! ! local coords + ! do i_pt=1,p%NumMeshPts + ! y%Mesh(i_pt)%Force(1:3,1) = matmul(transpose(u%Mesh(i_pt)%Orientation(:,:,1)), m%F_P(1:3,i_pt)) + ! y%Mesh(i_pt)%Moment(1:3,1) = matmul(transpose(u%Mesh(i_pt)%Orientation(:,:,1)), m%M_P(1:3,i_pt)) + ! enddo + endif END IF ! Set output values for the measured displacements for @@ -1256,7 +1274,7 @@ SUBROUTINE StC_CalcContStateDeriv( Time, u, p, x, xd, z, OtherState, m, dxdt, Er dxdt%StC_x(6,i_pt) = 0.0_ReKi ! Z is off enddo - ELSE IF ( p%StC_DOF_MODE == DOFMode_Prescribed ) THEN + ELSE IF ( p%StC_DOF_MODE == DOFMode_Prescribed .or. p%StC_DOF_MODE == DOFMode_ForceDLL) THEN ! if prescribed forces, there are no states to advance, so return do i_pt=1,p%NumMeshPts dxdt%StC_x(1,i_pt) = 0 @@ -2139,9 +2157,10 @@ subroutine StC_ValidatePrimaryData( InputFileData, InitInp, ErrStat, ErrMsg ) InputFileData%StC_DOF_MODE /= DOFMode_Indept .and. & InputFileData%StC_DOF_MODE /= DOFMode_Omni .and. & InputFileData%StC_DOF_MODE /= DOFMode_TLCD .and. & - InputFileData%StC_DOF_MODE /= DOFMode_Prescribed) & + InputFileData%StC_DOF_MODE /= DOFMode_Prescribed .and. & + InputFileData%StC_DOF_MODE /= DOFMode_ForceDLL) & CALL SetErrStat( ErrID_Fatal, 'DOF mode (StC_DOF_MODE) must be 0 (no DOF), 1 (two independent DOFs), '// & - 'or 2 (omni-directional), or 3 (TLCD), or 4 (prescribed force time-series).', ErrStat, ErrMsg, RoutineName ) + 'or 2 (omni-directional), or 3 (TLCD), 4 (prescribed force time-series), or 5 (force from external DLL).', ErrStat, ErrMsg, RoutineName ) ! Check control modes IF ( InputFileData%StC_CMODE /= ControlMode_None .and. & @@ -2153,9 +2172,12 @@ subroutine StC_ValidatePrimaryData( InputFileData, InitInp, ErrStat, ErrMsg ) ! Check control channel if ( InputFileData%StC_CMode == CMODE_ActiveDLL ) then - if ( InputFileData%StC_DOF_MODE /= DOFMode_Indept .and. InputFileData%StC_DOF_MODE /= DOFMode_Omni ) then + if ( InputFileData%StC_DOF_MODE /= DOFMode_Indept .and. & + InputFileData%StC_DOF_MODE /= DOFMode_Omni .and. & + InputFileData%StC_DOF_MODE /= DOFMode_ForceDLL) then call SetErrStat( ErrID_Fatal, 'Control mode 4 (active with Simulink control), or 5 (active with DLL control) '// & - 'can only be used with independent or omni DOF (StC_DOF_Mode=1 or 2) in this version of StrucCtrl.', ErrStat, ErrMsg, RoutineName ) + 'can only be used with independent or omni DOF (StC_DOF_Mode=1 or 2) or force from external DLL '// & + '(StC_DOF_Mode = 5) in this version of StrucCtrl.', ErrStat, ErrMsg, RoutineName ) endif if (InitInp%NumMeshPts > 1) then do i=2,InitInp%NumMeshPts ! Warn if controlling multiple mesh points with single instance (blade TMD) @@ -2191,6 +2213,21 @@ subroutine StC_ValidatePrimaryData( InputFileData, InitInp, ErrStat, ErrMsg ) endif endif + ! DLL Force - not sure if necessary, but nothing happens if these inputs are incorrect + if (InputFileData%StC_DOF_MODE == DOFMode_ForceDLL) then + + ! Need global force coord + if (InputFileData%PrescribedForcesCoordSys /= PRESCRIBED_FORCE_GLOBAL) THEN + call SetErrStat( ErrID_Fatal, 'PrescribedForcesCoordSys must be global ('//trim(Num2LStr(PRESCRIBED_FORCE_GLOBAL))// & + ') when StC_DOF_MODE is '//trim(Num2LStr(DOFMode_ForceDLL)) , ErrStat, ErrMsg, RoutineName ) + endif + + ! Need active DLL control + if (InputFileData%StC_CMODE /= CMODE_ActiveDLL) THEN + call SetErrStat( ErrID_Fatal, 'StC_CMODE must be '//trim(Num2LStr(CMODE_ActiveDLL))// & + ' when StC_DOF_MODE is '//trim(Num2LStr(DOFMode_ForceDLL)) , ErrStat, ErrMsg, RoutineName ) + endif + endif ! Check masses make some kind of sense if (InputFileData%StC_DOF_MODE == DOFMode_Indept .and. InputFileData%StC_X_DOF .and. (InputFileData%StC_X_M <= 0.0_ReKi) ) & diff --git a/modules/servodyn/src/StrucCtrl_Types.f90 b/modules/servodyn/src/StrucCtrl_Types.f90 index d8bc847c5..3f5dd2582 100644 --- a/modules/servodyn/src/StrucCtrl_Types.f90 +++ b/modules/servodyn/src/StrucCtrl_Types.f90 @@ -371,15 +371,27 @@ SUBROUTINE StC_CopyInputFile( SrcInputFileData, DstInputFileData, CtrlCode, ErrS ENDIF END SUBROUTINE StC_CopyInputFile - SUBROUTINE StC_DestroyInputFile( InputFileData, ErrStat, ErrMsg ) + SUBROUTINE StC_DestroyInputFile( InputFileData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(StC_InputFile), INTENT(INOUT) :: InputFileData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyInputFile' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyInputFile' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputFileData%F_TBL)) THEN DEALLOCATE(InputFileData%F_TBL) ENDIF @@ -1042,15 +1054,27 @@ SUBROUTINE StC_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrS IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE StC_CopyInitInput - SUBROUTINE StC_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE StC_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(StC_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%InitRefPos)) THEN DEALLOCATE(InitInputData%InitRefPos) ENDIF @@ -1063,8 +1087,10 @@ SUBROUTINE StC_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) IF (ALLOCATED(InitInputData%InitRefOrient)) THEN DEALLOCATE(InitInputData%InitRefOrient) ENDIF - CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedPrimaryInputData, ErrStat, ErrMsg ) - CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedPrescribeFrcData, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedPrimaryInputData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL NWTC_Library_Destroyfileinfotype( InitInputData%PassedPrescribeFrcData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE StC_DestroyInitInput SUBROUTINE StC_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1703,15 +1729,27 @@ SUBROUTINE StC_CopyCtrlChanInitInfoType( SrcCtrlChanInitInfoTypeData, DstCtrlCha ENDIF END SUBROUTINE StC_CopyCtrlChanInitInfoType - SUBROUTINE StC_DestroyCtrlChanInitInfoType( CtrlChanInitInfoTypeData, ErrStat, ErrMsg ) + SUBROUTINE StC_DestroyCtrlChanInitInfoType( CtrlChanInitInfoTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(StC_CtrlChanInitInfoType), INTENT(INOUT) :: CtrlChanInitInfoTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyCtrlChanInitInfoType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyCtrlChanInitInfoType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(CtrlChanInitInfoTypeData%Requestor)) THEN DEALLOCATE(CtrlChanInitInfoTypeData%Requestor) ENDIF @@ -2191,15 +2229,27 @@ SUBROUTINE StC_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, E ENDIF END SUBROUTINE StC_CopyInitOutput - SUBROUTINE StC_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE StC_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(StC_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%RelPosition)) THEN DEALLOCATE(InitOutputData%RelPosition) ENDIF @@ -2379,15 +2429,27 @@ SUBROUTINE StC_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrS ENDIF END SUBROUTINE StC_CopyContState - SUBROUTINE StC_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE StC_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(StC_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%StC_x)) THEN DEALLOCATE(ContStateData%StC_x) ENDIF @@ -2552,15 +2614,27 @@ SUBROUTINE StC_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrS DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE StC_CopyDiscState - SUBROUTINE StC_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE StC_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(StC_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE StC_DestroyDiscState SUBROUTINE StC_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2677,15 +2751,27 @@ SUBROUTINE StC_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE StC_CopyConstrState - SUBROUTINE StC_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE StC_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(StC_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE StC_DestroyConstrState SUBROUTINE StC_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2802,15 +2888,27 @@ SUBROUTINE StC_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, E DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState END SUBROUTINE StC_CopyOtherState - SUBROUTINE StC_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE StC_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(StC_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE StC_DestroyOtherState SUBROUTINE StC_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -3167,15 +3265,27 @@ SUBROUTINE StC_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%PrescribedInterpIdx = SrcMiscData%PrescribedInterpIdx END SUBROUTINE StC_CopyMisc - SUBROUTINE StC_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE StC_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(StC_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%F_stop)) THEN DEALLOCATE(MiscData%F_stop) ENDIF @@ -4250,15 +4360,27 @@ SUBROUTINE StC_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ENDIF END SUBROUTINE StC_CopyParam - SUBROUTINE StC_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE StC_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(StC_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%F_TBL)) THEN DEALLOCATE(ParamData%F_TBL) ENDIF @@ -4862,18 +4984,31 @@ SUBROUTINE StC_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ENDIF END SUBROUTINE StC_CopyInput - SUBROUTINE StC_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE StC_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(StC_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%Mesh)) THEN DO i1 = LBOUND(InputData%Mesh,1), UBOUND(InputData%Mesh,1) - CALL MeshDestroy( InputData%Mesh(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( InputData%Mesh(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(InputData%Mesh) ENDIF @@ -5360,18 +5495,31 @@ SUBROUTINE StC_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrM ENDIF END SUBROUTINE StC_CopyOutput - SUBROUTINE StC_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE StC_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(StC_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'StC_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%Mesh)) THEN DO i1 = LBOUND(OutputData%Mesh,1), UBOUND(OutputData%Mesh,1) - CALL MeshDestroy( OutputData%Mesh(i1), ErrStat, ErrMsg ) + CALL MeshDestroy( OutputData%Mesh(i1), ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OutputData%Mesh) ENDIF diff --git a/modules/servodyn/src/UserSubs.f90 b/modules/servodyn/src/UserSubs.f90 index 64c3501f6..7ac97a52f 100644 --- a/modules/servodyn/src/UserSubs.f90 +++ b/modules/servodyn/src/UserSubs.f90 @@ -85,9 +85,6 @@ module UserSubs ! ! the DOF, respectively. Turning off the DOF forces the ! ! current RATE to remain fixed. If the rate is currently zero, ! ! the current POSITION will remain fixed as well. -! ! Note that this technique WILL NOT work for user-defined routines -! ! written for ADAMS datasets extracted using the FAST-to-ADAMS -! ! preprocessor. ! ! !USE Precision @@ -148,9 +145,6 @@ SUBROUTINE UserHSSBr ( GenTrq, ElecPwr, HSS_Spd, NumBl, ZTime, DT, DirRoot, HSSB ! the DOF, respectively. Turning off the DOF forces the ! current RATE to remain fixed. If the rate is currently zero, ! the current POSITION will remain fixed as well. - ! Note that this technique WILL NOT work for user-defined routines - ! written for ADAMS datasets extracted using the FAST-to-ADAMS - ! preprocessor. USE Precision @@ -174,7 +168,7 @@ SUBROUTINE UserHSSBr ( GenTrq, ElecPwr, HSS_Spd, NumBl, ZTime, DT, DirRoot, HSSB -HSSBrFrac = 0.0 ! NOTE: This must be specified as a real number between 0.0 (off - no brake torque) and 1.0 (full - max brake torque = HSSBrTqF); FAST/ADAMS will Abort otherwise. +HSSBrFrac = 0.0 ! NOTE: This must be specified as a real number between 0.0 (off - no brake torque) and 1.0 (full - max brake torque = HSSBrTqF); FAST will Abort otherwise. @@ -256,9 +250,6 @@ END SUBROUTINE UserTFin ! ! the DOF, respectively. Turning off the DOF forces the ! ! current RATE to remain fixed. If the rate is currently zero, ! ! the current POSITION will remain fixed as well. -! ! Note that this technique WILL NOT work for user-defined routines -! ! written for ADAMS datasets extracted using the FAST-to-ADAMS -! ! preprocessor. ! ! !USE Precision @@ -419,10 +410,7 @@ SUBROUTINE UserYawCont ( YawPos, YawRate, WindDir, YawError, NumBl, ZTime, DT, D ! setting YawDOF to False. ! This technique is useful, for example, if the yaw bearing has ! an electromagnetic latch that will unlock and relock the hinge under - ! certain specified conditions. - ! Note that this technique WILL NOT work for user-defined routines - ! written for ADAMS datasets extracted using the FAST-to-ADAMS - ! preprocessor. + ! certain specified conditions.. USE Precision diff --git a/modules/subdyn/CMakeLists.txt b/modules/subdyn/CMakeLists.txt index 8d56cc80f..fd81ca64a 100644 --- a/modules/subdyn/CMakeLists.txt +++ b/modules/subdyn/CMakeLists.txt @@ -18,7 +18,7 @@ if (GENERATE_TYPES) generate_f90_types(src/SubDyn_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/SubDyn_Types.f90) endif() -set(SUBDYN_SOURCES +add_library(subdynlib src/SubDyn.f90 src/FEM.f90 src/SD_FEM.f90 @@ -26,18 +26,14 @@ set(SUBDYN_SOURCES src/SubDyn_Output_Params.f90 src/SubDyn_Tests.f90 src/IntegerList.f90 - src/Yaml.f90 src/SubDyn_Types.f90 ) - -add_library(subdynlib ${SUBDYN_SOURCES}) target_link_libraries(subdynlib nwtclibs) -set(SUBDYN_DRIVER_SOURCES - src/SubDyn_Driver.f90) - -add_executable(subdyn_driver ${SUBDYN_DRIVER_SOURCES}) -target_link_libraries(subdyn_driver subdynlib nwtclibs versioninfolib) +add_executable(subdyn_driver + src/SubDyn_Driver.f90 +) +target_link_libraries(subdyn_driver subdynlib versioninfolib) install(TARGETS subdynlib subdyn_driver EXPORT "${CMAKE_PROJECT_NAME}Libraries" diff --git a/modules/subdyn/src/FEM.f90 b/modules/subdyn/src/FEM.f90 index ba74d2bf5..0fe0376f2 100644 --- a/modules/subdyn/src/FEM.f90 +++ b/modules/subdyn/src/FEM.f90 @@ -26,8 +26,9 @@ MODULE FEM INTEGER, PARAMETER :: LaKi = R8Ki ! Define the kind to be used for LaPack INTERFACE FINDLOCI ! In the future, use FINDLOC from intrinsic - MODULE PROCEDURE FINDLOCI_ReKi + MODULE PROCEDURE FINDLOCI_R8Ki MODULE PROCEDURE FINDLOCI_IntKi + MODULE PROCEDURE FINDLOCI_SiKi END INTERFACE @@ -84,7 +85,7 @@ SUBROUTINE EigenSolve(K, M, N, bCheckSingularity, EigVect, Omega, ErrStat, ErrMs Omega2(:) =0.0_LaKi DO I=1,N !Initialize the key and calculate Omega KEY(I)=I - Omega2(I) = AlphaR(I)/Beta(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') @@ -836,8 +837,8 @@ 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 +FUNCTION FINDLOCI_R8Ki(Array, Val) result(i) + real(R8Ki) , 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 @@ -866,6 +867,21 @@ FUNCTION FINDLOCI_IntKi(Array, Val) result(i) enddo i=-1 END FUNCTION + +FUNCTION FINDLOCI_SiKi(Array, Val) result(i) + real(SiKi), 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 @@ -1022,8 +1038,8 @@ 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 +SUBROUTINE ElemK_Beam(A, L, Ixx, Iyy, Jzz, Shear, kappa_x, kappa_y, E, G, DirCos, K) + REAL(ReKi), INTENT( IN) :: A, L, Ixx, Iyy, Jzz, E, G, kappa_x, kappa_y 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) @@ -1031,8 +1047,8 @@ SUBROUTINE ElemK_Beam(A, L, Ixx, Iyy, Jzz, Shear, kappa, E, G, DirCos, K) REAL(FEKi) :: Ax, Ay, Kx, Ky REAL(FEKi) :: DC(12, 12) - Ax = kappa*A - Ay = kappa*A + Ax = kappa_x*A + Ay = kappa_y*A K(1:12,1:12) = 0.0_FEKi diff --git a/modules/subdyn/src/SD_FEM.f90 b/modules/subdyn/src/SD_FEM.f90 index bee8e4a9e..7d300e83b 100644 --- a/modules/subdyn/src/SD_FEM.f90 +++ b/modules/subdyn/src/SD_FEM.f90 @@ -32,7 +32,7 @@ MODULE SD_FEM 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+1 ! Number of columns in Members (MemberID,MJointID1,MJointID2,MPropSetID1,MPropSetID2,COSMID) + INTEGER(IntKi), PARAMETER :: MembersCol = MaxNodesPerElem + 3+1+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) @@ -41,6 +41,7 @@ MODULE SD_FEM 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 :: iMDirCosID = 7 ! 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 ! Indices in Joints table @@ -55,9 +56,10 @@ MODULE SD_FEM INTEGER(IntKi), PARAMETER :: idJointBall = 4 ! ID for member types - INTEGER(IntKi), PARAMETER :: idMemberBeam = 1 + INTEGER(IntKi), PARAMETER :: idMemberBeamCirc = 1 INTEGER(IntKi), PARAMETER :: idMemberCable = 2 INTEGER(IntKi), PARAMETER :: idMemberRigid = 3 + INTEGER(IntKi), PARAMETER :: idMemberBeamArb = 4 ! Types of Boundary Conditions INTEGER(IntKi), PARAMETER :: idBC_Fixed = 11 ! Fixed BC @@ -380,8 +382,8 @@ SUBROUTINE SD_ReIndex_CreateNodesAndElems(Init,p, ErrStat, ErrMsg) ! NOTE: this index has different meaning depending on the member type ! DO n=iMProp,iMProp+1 - if (mType==idMemberBeam) then - sType='Member x-section property' + if (mType==idMemberBeamCirc) then + sType='Member circular cross-section property' p%Elems(iMem,n) = FINDLOCI(Init%PropSetsB(:,1), Init%Members(iMem, n) ) else if (mType==idMemberCable) then sType='Cable property' @@ -389,15 +391,19 @@ SUBROUTINE SD_ReIndex_CreateNodesAndElems(Init,p, ErrStat, ErrMsg) else if (mType==idMemberRigid) then sType='Rigid property' p%Elems(iMem,n) = FINDLOCI(Init%PropSetsR(:,1), Init%Members(iMem, n) ) + else if (mType==idMemberBeamArb) then + sType='Member arbitrary cross-section property' + p%Elems(iMem,n) = FINDLOCI(Init%PropSetsX(:,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 (mType/=idMemberBeamCirc) 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)))) + ! NOTE: for non circular beams, we could just check that E, rho, G are the same for both properties + call Fatal('Property IDs should be the same at both joints for arbitrary beams, rigid links, and cables. Check member with ID: '//TRIM(Num2LStr(Init%Members(iMem,1)))) return endif endif @@ -408,6 +414,12 @@ SUBROUTINE SD_ReIndex_CreateNodesAndElems(Init,p, ErrStat, ErrMsg) END DO !n, loop through property ids ! Column 6: member type p%Elems(iMem, iMType) = Init%Members(iMem, iMType) ! + ! Column 7: member type + + if (p%Elems(iMem, iMDirCosID)/=-1) then + p%Elems(iMem, iMDirCosID) = FINDLOCI(Init%COSMs(:,1), Init%Members(iMem, iMDirCosID) ) + endif + END DO !iMem, loop through members ! TODO in theory, we shouldn't need these anymore @@ -436,11 +448,13 @@ SUBROUTINE SD_Discrt(Init,p, ErrStat, ErrMsg) INTEGER :: NNE ! number of nodes per element INTEGER :: MaxNProp REAL(ReKi), ALLOCATABLE :: TempProps(:, :) + REAL(ReKi), ALLOCATABLE :: TempPropsX(:, :) INTEGER, ALLOCATABLE :: TempMembers(:, :) INTEGER :: knode, kelem, kprop, nprop + INTEGER :: iDirCos REAL(ReKi) :: x1, y1, z1, x2, y2, z2, dx, dy, dz, dd, dt, d1, d2, t1, t2 LOGICAL :: CreateNewProp - INTEGER(IntKi) :: nMemberCable, nMemberRigid, nMemberBeam !< Number of memebers per type + INTEGER(IntKi) :: nMemberCable, nMemberRigid, nMemberBeamCirc, nMemberBeamArb !< Number of memebers per type INTEGER(IntKi) :: eType !< Element Type INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 @@ -455,16 +469,17 @@ SUBROUTINE SD_Discrt(Init,p, ErrStat, ErrMsg) ENDIF ! --- 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 + nMemberBeamCirc = count(Init%Members(:,iMType) == idMemberBeamCirc) + nMemberCable = count(Init%Members(:,iMType) == idMemberCable) + nMemberRigid = count(Init%Members(:,iMType) == idMemberRigid) + nMemberBeamArb = count(Init%Members(:,iMType) == idMemberBeamArb) + Init%NElem = (nMemberBeamCirc + nMemberBeamArb)*Init%NDiv + nMemberCable + nMemberRigid ! NOTE: only Beams are divided + IF ( (nMemberBeamCirc+nMemberRigid+nMemberCable+nMemberBeamArb) /= 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 - p%nNodes = Init%NJoints + ( Init%NDiv - 1 )*nMemberBeam + p%nNodes = Init%NJoints + ( Init%NDiv - 1 )*(nMemberBeamCirc) ! TODO add nMemberBeamArb when support for division provided ! check the number of interior modes IF ( p%nDOFM > 6*(p%nNodes - p%nNodes_I - p%nNodes_C) ) THEN @@ -492,13 +507,24 @@ SUBROUTINE SD_Discrt(Init,p, ErrStat, ErrMsg) return endif - if (eType==idMemberBeam) then + if (eType==idMemberBeamCirc) then if ( ( .not. EqualRealNos(Init%PropSetsB(Prop1, 2),Init%PropSetsB(Prop2, 2) ) ) & .or. ( .not. EqualRealNos(Init%PropSetsB(Prop1, 3),Init%PropSetsB(Prop2, 3) ) ) & .or. ( .not. EqualRealNos(Init%PropSetsB(Prop1, 4),Init%PropSetsB(Prop2, 4) ) ) ) then call Fatal(' Material E, G and rho in a member must be the same (See member at position '//trim(num2lstr(I))//' in member list)') return endif + else if (eType==idMemberBeamArb) then + if (Prop1 /= Prop2 ) then + call Fatal(' Members using arbitrary cross section properties must have the same properties on both ends. See member at position '//trim(num2lstr(I))//' in member list)') + return + endif + !if ( ( .not. EqualRealNos(Init%PropSetsX(Prop1, 2),Init%PropSetsX(Prop2, 2) ) ) & + ! .or. ( .not. EqualRealNos(Init%PropSetsX(Prop1, 3),Init%PropSetsX(Prop2, 3) ) ) & + ! .or. ( .not. EqualRealNos(Init%PropSetsX(Prop1, 4),Init%PropSetsX(Prop2, 4) ) ) ) then + ! call Fatal(' Material E, G and rho in a member must be the same (See member at position '//trim(num2lstr(I))//' in member list)') + ! return + !endif endif ! is beam enddo @@ -519,17 +545,21 @@ 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%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) + ! TODO add Init%NPropSetsX and use PropSetXCol in the future or allocate a new TempProps + 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, PropSetsBCol,'TempProps', ErrStat2, ErrMsg2); if(Failed()) return TempProps = -9999. + TempProps(1:Init%NPropSetsB, :) = Init%PropSetsB 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%NPropSetsB + DO I = 1, p%NMembers !the first p%NMembers rows of p%Elems contain the element information ! Member data Node1 = TempMembers(I, 2) @@ -537,14 +567,15 @@ SUBROUTINE SD_Discrt(Init,p, ErrStat, ErrMsg) Prop1 = TempMembers(I, iMProp ) Prop2 = TempMembers(I, iMProp+1) eType = TempMembers(I, iMType ) + iDirCos = TempMembers(I, iMDirCosID) - if (eType/=idMemberBeam) then + if (eType==idMemberRigid .OR. eType==idMemberCable) 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) + CALL SetNewElem(kelem, Node1, Node2, eType, Prop1, Prop1, p, iDirCos) cycle endif @@ -563,19 +594,29 @@ SUBROUTINE SD_Discrt(Init,p, ErrStat, ErrMsg) dx = ( x2 - x1 )/Init%NDiv dy = ( y2 - y1 )/Init%NDiv dz = ( z2 - z1 )/Init%NDiv - - d1 = TempProps(Prop1, 5) - t1 = TempProps(Prop1, 6) - d2 = TempProps(Prop2, 5) - t2 = TempProps(Prop2, 6) - - dd = ( d2 - d1 )/Init%NDiv - dt = ( t2 - t1 )/Init%NDiv - + if (eType == idMemberBeamCirc) then + + d1 = TempProps(Prop1, 5) + t1 = TempProps(Prop1, 6) + + d2 = TempProps(Prop2, 5) + t2 = TempProps(Prop2, 6) + + dd = ( d2 - d1 )/Init%NDiv + dt = ( t2 - t1 )/Init%NDiv + ! If both dd and dt are 0, no interpolation is needed, and we can use the same property set for new nodes/elements. otherwise we'll have to create new properties for each new node - CreateNewProp = .NOT. ( EqualRealNos( dd , 0.0_ReKi ) .AND. EqualRealNos( dt , 0.0_ReKi ) ) - + + CreateNewProp = .NOT. ( EqualRealNos( dd , 0.0_ReKi ) .AND. EqualRealNos( dt , 0.0_ReKi ) ) + + elseif (eType == idMemberBeamArb) then + + CreateNewProp = .FALSE. + CALL WrScr('[WARNING] Members with non-circular cross-sections are currently not divided (member at position '//TRIM(Num2LStr(I))//' ).') + + endif + ! node connect to Node1 knode = knode + 1 Init%MemberNodes(I, 2) = knode @@ -587,11 +628,11 @@ SUBROUTINE SD_Discrt(Init,p, ErrStat, ErrMsg) ! k, E1, G1, rho1, d, t, 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, eType, Prop1, kprop, p); if (ErrStat>ErrID_None) return; + CALL SetNewElem(kelem, Node1, knode, eType, Prop1, kprop, p, iDirCos); if (ErrStat>ErrID_None) return; nprop = kprop ELSE kelem = kelem + 1 - CALL SetNewElem(kelem, Node1, knode, eType, Prop1, Prop1, p); if (ErrStat>ErrID_None) return; + CALL SetNewElem(kelem, Node1, knode, eType, Prop1, Prop1, p, iDirCos); if (ErrStat>ErrID_None) return; nprop = Prop1 ENDIF @@ -608,17 +649,17 @@ SUBROUTINE SD_Discrt(Init,p, ErrStat, ErrMsg) ! k, E1, G1, rho1, d, t 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, eType, nprop, kprop, p); if (ErrStat>ErrID_None) return; + CALL SetNewElem(kelem, knode-1, knode, eType, nprop, kprop, p, iDirCos); if (ErrStat>ErrID_None) return; nprop = kprop ELSE kelem = kelem + 1 - CALL SetNewElem(kelem, knode-1, knode, eType, nprop, nprop, p); if (ErrStat>ErrID_None) return; + CALL SetNewElem(kelem, knode-1, knode, eType, nprop, nprop, p, iDirCos); if (ErrStat>ErrID_None) return; ENDIF ENDDO ! the element connect to Node2 kelem = kelem + 1 - CALL SetNewElem(kelem, knode, Node2, eType, nprop, Prop2, p); if (ErrStat>ErrID_None) return; + CALL SetNewElem(kelem, knode, Node2, eType, nprop, Prop2, p, iDirCos); if (ErrStat>ErrID_None) return; ENDDO ! loop over all members ! Init%NPropB = kprop @@ -689,13 +730,14 @@ SUBROUTINE SetNewNode(k, x, y, z, Init) END SUBROUTINE SetNewNode !> Set properties of element k - SUBROUTINE SetNewElem(k, n1, n2, etype, p1, p2, p) + SUBROUTINE SetNewElem(k, n1, n2, etype, p1, p2, p, iDirCos) INTEGER, INTENT(IN ) :: k INTEGER, INTENT(IN ) :: n1 INTEGER, INTENT(IN ) :: n2 INTEGER, INTENT(IN ) :: eType INTEGER, INTENT(IN ) :: p1 INTEGER, INTENT(IN ) :: p2 + INTEGER, INTENT(IN ) :: iDirCos 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.'); @@ -707,6 +749,7 @@ SUBROUTINE SetNewElem(k, n1, n2, etype, p1, p2, p) p%Elems(k, iMProp ) = p1 p%Elems(k, iMProp+1) = p2 p%Elems(k, iMType) = eType + p%Elems(k, iMDirCosID) = iDirCos END SUBROUTINE SetNewElem !> Set material properties of element k, NOTE: this is only for a beam @@ -770,10 +813,11 @@ SUBROUTINE SetElementProperties(Init, p, ErrStat, ErrMsg) INTEGER :: I INTEGER :: N1, N2 ! starting node and ending node in the element INTEGER :: P1, P2 ! property set numbers for starting and ending nodes + INTEGER :: iDirCos REAL(ReKi) :: D1, D2, t1, t2, E, G, rho ! properties of a section 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 + REAL(ReKi) :: r1, r2, t, Iyy, Jzz, Ixx, A, kappa, kappa_x, kappa_y, nu, ratioSq, D_inner, D_outer LOGICAL :: shear INTEGER(IntKi) :: eType !< Member type REAL(ReKi) :: Point1(3), Point2(3) ! (x,y,z) positions of two nodes making up an element @@ -793,11 +837,32 @@ SUBROUTINE SetElementProperties(Init, p, ErrStat, ErrMsg) P1 = p%Elems(I, iMProp ) P2 = p%Elems(I, iMProp+1) eType = p%Elems(I, iMType) + iDirCos = p%Elems(I, iMDirCosID) ! --- 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 + + if (iDirCos/=-1) then + CALL GetDirCos(Point1, Point2, DirCos, L, ErrStat2, ErrMsg2); if(Failed()) return ! sets L + + ! overwrites direction cosines + DirCos(1, 1) = Init%COSMs(iDirCos, 2) + DirCos(2, 1) = Init%COSMs(iDirCos, 3) + DirCos(3, 1) = Init%COSMs(iDirCos, 4) + DirCos(1, 2) = Init%COSMs(iDirCos, 5) + DirCos(2, 2) = Init%COSMs(iDirCos, 6) + DirCos(3, 2) = Init%COSMs(iDirCos, 7) + DirCos(1, 3) = Init%COSMs(iDirCos, 8) + DirCos(2, 3) = Init%COSMs(iDirCos, 9) + DirCos(3, 3) = Init%COSMs(iDirCos, 10) + + else + CALL GetDirCos(Point1, Point2, DirCos, L, ErrStat2, ErrMsg2); if(Failed()) return ! L and DirCos + endif + + + p%ElemProps(i)%eType = eType p%ElemProps(i)%Length = L p%ElemProps(i)%DirCos = DirCos @@ -806,7 +871,8 @@ SUBROUTINE SetElementProperties(Init, p, ErrStat, ErrMsg) 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)%Kappa_x = -9.99e+36 + p%ElemProps(i)%Kappa_y = -9.99e+36 p%ElemProps(i)%YoungE = -9.99e+36 p%ElemProps(i)%ShearG = -9.99e+36 p%ElemProps(i)%Area = -9.99e+36 @@ -814,7 +880,7 @@ SUBROUTINE SetElementProperties(Init, p, ErrStat, ErrMsg) p%ElemProps(i)%T0 = -9.99e+36 ! --- Properties that are specific to some elements - if (eType==idMemberBeam) then + if (eType==idMemberBeamCirc) then E = Init%PropsB(P1, 2) ! TODO E2 G = Init%PropsB(P1, 3) ! TODO G2 rho = Init%PropsB(P1, 4) ! TODO rho2 @@ -853,7 +919,45 @@ SUBROUTINE SetElementProperties(Init, p, ErrStat, ErrMsg) p%ElemProps(i)%Iyy = Iyy p%ElemProps(i)%Jzz = Jzz p%ElemProps(i)%Shear = Shear - p%ElemProps(i)%kappa = kappa + p%ElemProps(i)%Kappa_x = kappa + p%ElemProps(i)%Kappa_y = kappa + p%ElemProps(i)%YoungE = E + p%ElemProps(i)%ShearG = G + p%ElemProps(i)%Area = A + p%ElemProps(i)%Rho = rho + p%ElemProps(i)%D = (/D1, D2/) + + else if (eType==idMemberBeamArb) then + + p%ElemProps(i)%eType = 1 + if( Init%FEMMod == 1 ) then ! uniform Euler-Bernoulli + Shear = .false. + elseif( Init%FEMMod == 3 ) then ! uniform Timoshenko + Shear = .true. + endif + ! Storing Beam specific properties + ! Here we are averaging the values at both extremities which is different from what is done for regular beams. + ! The averaging should have no effect for the material properties because the beam is assumed to be isotropic (E, G, rho constant). + E = (Init%PropSetsX(P1, 2) + Init%PropSetsX(P2, 2)) / 2 + G = (Init%PropSetsX(P1, 3) + Init%PropSetsX(P2, 3)) / 2 + rho = (Init%PropSetsX(P1, 4) + Init%PropSetsX(P2, 4)) / 2 + ! Averaging will have an impact on geometry, shear and inertia + ! but we are currently forcing the property ID to be the same, so no effect. + A = (Init%PropSetsX(P1, 5) + Init%PropSetsX(P2, 5)) / 2 + Kappa_x = (Init%PropSetsX(P1, 6) + Init%PropSetsX(P2, 6)) / 2 / A + Kappa_y = (Init%PropSetsX(P1, 7) + Init%PropSetsX(P2, 7)) / 2 / A + Ixx = (Init%PropSetsX(P1, 8) + Init%PropSetsX(P2, 8)) / 2 + Iyy = (Init%PropSetsX(P1, 9) + Init%PropSetsX(P2, 9)) / 2 + Jzz = (Init%PropSetsX(P1, 10) + Init%PropSetsX(P2, 10)) / 2 + D1 = 2._ReKi*(A/PI)**0.5 !Approximation, this value should not be used + D2 = D1 + + p%ElemProps(i)%Ixx = Ixx + p%ElemProps(i)%Iyy = Iyy + p%ElemProps(i)%Jzz = Jzz + p%ElemProps(i)%Shear = Shear + p%ElemProps(i)%Kappa_x = kappa_x + p%ElemProps(i)%Kappa_y = kappa_y p%ElemProps(i)%YoungE = E p%ElemProps(i)%ShearG = G p%ElemProps(i)%Area = A @@ -1686,9 +1790,12 @@ SUBROUTINE DirectElimination(Init, p, ErrStat, ErrMsg) ! --- 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) + ! Temporary backup of M and K of full system (Flang compiler failed when move_alloc was used here, so arrays are allocated, moved, and deallocated manually) + CALL AllocAry(KK, size(Init%K,1), size(Init%K,2), 'KK', ErrStat2, ErrMsg2); if(Failed()) return; ! system stiffness matrix + CALL AllocAry(MM, size(Init%M,1), size(Init%M,2), 'MM', ErrStat2, ErrMsg2); if(Failed()) return; ! system mass matrix + KK = Init%K + MM = Init%M + deallocate(Init%K, Init%M) ! 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 @@ -2160,7 +2267,7 @@ 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 + if (ep%eType==idMemberBeamCirc) 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) @@ -2183,8 +2290,8 @@ 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) + if (ep%eType==idMemberBeamCirc) then + CALL ElemK_Beam( eP%Area, eP%Length, eP%Ixx, eP%Iyy, eP%Jzz, eP%Shear, eP%Kappa_x, eP%Kappa_y, 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) @@ -2199,7 +2306,7 @@ SUBROUTINE ElemF(ep, gravity, Fg, Fo) 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 + if (ep%eType==idMemberBeamCirc) then Fo(1:12)=0.0_FEKi else if (ep%eType==idMemberCable) then CALL ElemF_Cable(ep%T0, ep%DirCos, Fo) diff --git a/modules/subdyn/src/SubDyn.f90 b/modules/subdyn/src/SubDyn.f90 index 248e3e747..91651ff8f 100644 --- a/modules/subdyn/src/SubDyn.f90 +++ b/modules/subdyn/src/SubDyn.f90 @@ -470,9 +470,7 @@ SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) !locals INTEGER(IntKi) :: I ! Counters INTEGER(IntKi) :: iSDNode - REAL(ReKi) :: AllOuts(0:MaxOutPts+p%OutAllInt*p%OutAllDims) REAL(ReKi) :: rotations(3) - REAL(ReKi) :: ULS(p%nDOF__L), UL0m(p%nDOF__L), FLt(p%nDOF__L) ! Temporary values in static improvement method REAL(ReKi) :: Y1(6) REAL(ReKi) :: Y1_CB(6) REAL(ReKi) :: Y1_CB_L(6) @@ -485,7 +483,7 @@ SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) 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 + ! Variables for Guyan 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) @@ -515,18 +513,15 @@ SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) RRb2g(4:6,4:6) = Rb2g ! -------------------------------------------------------------------------------- - ! --- Output 2&3 + ! --- Output Meshes 2&3 ! -------------------------------------------------------------------------------- - ! Y2Mesh: rigidbody displacements, elastic velocities and accelerations on all FEM nodes - ! Y3Mesh: elastic displacements, elastic velocities and accelerations on all FEM nodes - ! External force on internal nodes (F_L) + ! Y2Mesh: rigidbody displacements , elastic velocities and accelerations on all FEM nodes + ! Y3Mesh: elastic displacements without SIM, elastic velocities and accelerations on all FEM nodes + + ! External force on internal nodes (m%F_L) based on LMesh + FG (grav+cable) + controllable cables + ! - We only apply the lever arm for (fixed-bottom case + GuyanLoadCorrection) + ! - We only rotate the external loads for (floating case + GuyanLoadCorrection) 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 @@ -539,17 +534,11 @@ SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) 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 ) + else + m%UL = 0.0_ReKi + m%UL_dot = 0.0_ReKi + m%UL_dotdot = 0.0_ReKi 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 - endif ! --- Adding Guyan contribution to R and L DOFs if (.not.p%Floating) then ! Then we add the Guyan motion here @@ -562,32 +551,30 @@ SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) else ! We know that the Guyan modes are rigid body modes. ! We will add them in the "Full system" later + m%UR_bar = 0.0_ReKi + m%UR_bar_dot = 0.0_ReKi + m%UR_bar_dotdot = 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 - 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 + m%UL_NS = m%UL ! Storing displacements without SIM + ! Static improvement (modify UL) + if (p%SttcSolve/=idSIM_None) then + m%F_L2 = MATMUL(p%PhiL_T , m%F_L) ! NOTE: Gravity in F_L + m%UL_SIM = MATMUL(p%PhiLInvOmgL2, m%F_L2) + if ( p%nDOFM > 0) then + m%UL_0m = MATMUL(p%PhiLInvOmgL2(:,1:p%nDOFM), m%F_L2(1:p%nDOFM) ) + m%UL_SIM = m%UL_SIM - m%UL_0m + end if + m%UL = m%UL + m%UL_SIM + endif - ! Storing elastic motion (full motion for fixed bottom, CB motion only for floating) + ! --- Build original DOF vectors ("full", prior to constraints and CB) + call ReducedToFull(p, m, m%UR_bar , m%UL , m%U_full ) + call ReducedToFull(p, m, m%UR_bar_dot , m%UL_dot , m%U_full_dot ) + call ReducedToFull(p, m, m%UR_bar_dotdot, m%UL_dotdot, m%U_full_dotdot) + ! Do the same for the displacements without SIM. We'll use those for Y3 mesh + call ReducedToFull(p, m, m%UR_bar , m%UL_NS , m%U_full_NS ) + + ! Storing elastic motion (full motion for fixed bottom, CB motion+SIM for floating) m%U_full_elast = m%U_full ! --- Place displacement/velocity/acceleration into Y2 output mesh @@ -608,6 +595,8 @@ SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) ! Full displacements CB-rotated + Guyan (KEEP ME) >>> Rotate All if (p%GuyanLoadCorrection) then + m%U_full_NS (DOFList(1:3)) = matmul(Rb2g, m%U_full_NS (DOFList(1:3))) + duP(1:3) + m%U_full_NS (DOFList(4:6)) = matmul(Rb2g, m%U_full_NS (DOFList(4:6))) + rotations(1:3) 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) @@ -615,6 +604,8 @@ SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) 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_NS (DOFList(1:3)) = m%U_full_NS (DOFList(1:3)) + duP(1:3) + m%U_full_NS (DOFList(4:6)) = m%U_full_NS (DOFList(4:6)) + rotations(1:3) 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) @@ -628,12 +619,12 @@ SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) call SmllRotTrans( 'UR_bar input angles Guyan', 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) = duP(1:3) ! NOTE: using only the Guyan Displacements + y%Y2mesh%TranslationDisp (:,iSDNode) = duP(1:3) ! Y2: NOTE: only the Guyan displacements for floating ! --- Full elastic displacements for others (moordyn) - 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( 'Nodal rotation', m%U_full_NS(DOFList(4)), m%U_full_NS(DOFList(5)), m%U_full_NS(DOFList(6)), DCM, '', ErrStat2, ErrMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SD_CalcOutput') y%Y3mesh%Orientation (:,:,iSDNode) = DCM - y%Y3mesh%TranslationDisp (:,iSDNode) = m%U_full (DOFList(1:3)) + y%Y3mesh%TranslationDisp (:,iSDNode) = m%U_full_NS (DOFList(1:3)) ! Y3: Guyan+CB (but no SIM) displacements ! --- Elastic velocities and accelerations y%Y2mesh%TranslationVel (:,iSDNode) = m%U_full_dot (DOFList(1:3)) y%Y2mesh%TranslationAcc (:,iSDNode) = m%U_full_dotdot (DOFList(1:3)) @@ -641,45 +632,46 @@ SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) y%Y2mesh%RotationAcc (:,iSDNode) = m%U_full_dotdot (DOFList(4:6)) enddo else - ! --- Fixed bottom + ! --- Fixed bottom - Y3 and Y2 meshes are identical in this case 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 SmllRotTrans( 'UR_bar input angles', m%U_full_NS(DOFList(4)), m%U_full_NS(DOFList(5)), m%U_full_NS(DOFList(6)), DCM, '', ErrStat2, ErrMsg2) CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'SD_CalcOutput') - y%Y3mesh%Orientation (:,:,iSDNode) = DCM - y%Y3mesh%TranslationDisp (:,iSDNode) = m%U_full (DOFList(1:3)) y%Y2mesh%Orientation (:,:,iSDNode) = DCM - y%Y2mesh%TranslationDisp (:,iSDNode) = m%U_full (DOFList(1:3)) + y%Y2mesh%TranslationDisp (:,iSDNode) = m%U_full_NS (DOFList(1:3)) !Y2: Guyan+CB (but no SIM) 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)) + y%Y3mesh%TranslationDisp (:,iSDNode) = y%Y2mesh%TranslationDisp (:,iSDNode) + y%Y3mesh%Orientation (:,:,iSDNode) = y%Y2mesh%Orientation (:,:,iSDNode) enddo endif - ! --- Y3 mesh and Y2 mesh both have elastic velocities and accelerations + ! --- Y3 mesh and Y2 mesh both have elastic (Guyan+CB) velocities and accelerations do iSDNode = 1,p%nNodes y%Y3mesh%TranslationVel (:,iSDNode) = y%Y2mesh%TranslationVel (:,iSDNode) y%Y3mesh%TranslationAcc (:,iSDNode) = y%Y2mesh%TranslationAcc (:,iSDNode) y%Y3mesh%RotationVel (:,iSDNode) = y%Y2mesh%RotationVel (:,iSDNode) y%Y3mesh%RotationAcc (:,iSDNode) = y%Y2mesh%RotationAcc (:,iSDNode) enddo - + ! -------------------------------------------------------------------------------- ! --- 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 + ! Contribution from Craig-Bampton modes qm and qdot_m + if ( p%nDOFM > 0) then + Y1_CB = -( matmul(p%C1_11, x%qm) + matmul(p%C1_12, x%qmdot) ) ! - ( [-M_Bm K_mm]q_m + [-M_Bm C_mm] qdot_m ) + if (p%GuyanLoadCorrection.and.p%Floating) then + Y1_CB = matmul(RRb2g, Y1_CB) !>>> Rotate All + endif + else + Y1_CB = 0.0_ReKi 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 + ! Contribution from U_TP, Udot_TP, Uddot_TP, 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 @@ -692,23 +684,26 @@ SUBROUTINE SD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) 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 + + ! --- Special case for floating with extramoment, we use "rotated loads" m%F_L previously computed + if (p%GuyanLoadCorrection.and.p%Floating) then + Y1_CB_L = - (matmul(p%D1_141, m%F_L)) ! = - (M_Bm . Phi_m^T) "F_L", where "F_L"=Rg2b F_L are rotated loads + Y1_CB_L = matmul(RRb2g, Y1_CB_L) ! = - Rb2g (M_Bm . Phi_m^T) Rg2b F_L endif - Y1_Guy_R = matmul( F_I, p%TI ) - Y1_Guy_L = - matmul(p%D1_142, m%F_L) ! non rotated loads + + ! Compute "non-rotated" 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) + + ! Contributions from external forces + Y1_Guy_R = matmul( F_I, p%TI ) ! = - [-T_I.^T] F_R = [T_I.^T] F_R =~ F_R T_I (~: FORTRAN convention) + Y1_Guy_L = - matmul(p%D1_142, m%F_L) ! = - (- T_I^T . Phi_Rb^T) 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 + Y1_CB_L = - (matmul(p%D1_141, m%F_L)) ! = - (M_Bm . Phi_m^T) F_L, non-rotated loads endif + ! Total contribution Y1 = Y1_CB + Y1_Utp + Y1_CB_L+ Y1_Guy_L + Y1_Guy_R ! KEEP ME !if ( p%nDOFM > 0) then @@ -768,11 +763,11 @@ 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(u, p, x, y, m, AllOuts, ErrStat2, ErrMsg2); if(Failed()) return + CALL SDOut_MapOutputs(u, p, x, y, m, m%AllOuts, ErrStat2, ErrMsg2); if(Failed()) return ! Put the output data in the WriteOutput array DO I = 1,p%NumOuts+p%OutAllInt*p%OutAllDims - y%WriteOutput(I) = p%OutParam(I)%SignM * AllOuts( p%OutParam(I)%Indx ) + y%WriteOutput(I) = p%OutParam(I)%SignM * m%AllOuts( p%OutParam(I)%Indx ) IF ( p%OutSwtch == 1 .OR. p%OutSwtch == 3 ) THEN m%SDWrOutput(I) = y%WriteOutput(I) END IF @@ -851,7 +846,7 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) CHARACTER(64), ALLOCATABLE :: StrArray(:) ! Array of strings, for better control of table inputs LOGICAL :: Echo LOGICAL :: LegacyFormat -LOGICAL :: bNumeric +LOGICAL :: bNumeric, bInteger INTEGER(IntKi) :: UnIn INTEGER(IntKi) :: nColumns, nColValid, nColNumeric INTEGER(IntKi) :: IOS @@ -1090,7 +1085,12 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) ! 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)); + j = index(line, achar(13)) ! Remove any carriage returns in this line (required by the Flang compiler) + do while (j > 0) + line(j:j) = " " + j = index(line, achar(13)) + end do + call ReadIAryFromStrSD(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') @@ -1128,7 +1128,12 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) ! 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); + j = index(line, achar(13)) ! Remove any carriage returns in this line (required by the Flang compiler) + do while (j > 0) + line(j:j) = " " + j = index(line, achar(13)) + end do + call ReadIAryFromStrSD(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 @@ -1149,20 +1154,50 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) 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 + +nColumns=MembersCol + +if (p%NMembers == 0) then + CALL Fatal(' Error in file "'//TRIM(SDInputFile)//'": There should be at least one SubDyn member: "'//trim(Line)//'"') + return +endif + +CALL AllocAry(StrArray, nColumns, 'StrArray',ErrStat2,ErrMsg2); if (Failed()) return +READ(UnIn, FMT='(A)', IOSTAT=ErrStat2) Line ; ErrMsg2='First line of members array'; if (Failed()) return +CALL ReadCAryFromStr ( Line, StrArray, nColumns, 'Members', 'First line of members array', ErrStat2, ErrMsg2 ) +if (ErrStat2/=0) then + ! We try with one column less (legacy format) + nColumns = MembersCol-1 + deallocate(StrArray) + CALL AllocAry(StrArray, nColumns, 'StrArray',ErrStat2,ErrMsg2); if (Failed()) return + CALL ReadCAryFromStr ( Line, StrArray, nColumns, 'Members', 'First line of members array', ErrStat2, ErrMsg2 ); if(Failed()) return + call LegacyWarning('Member table contains 6 columns instead of 7, using default member directional cosines ID (-1) for all members. & + &The directional cosines will be computed based on the member nodes for all members.') + Init%Members(:,7) = -1 +endif +! Extract fields from first line +DO I = 1, nColumns + bInteger = is_integer(StrArray(I), Init%Members(1,I)) ! Convert from string to float + if (.not.bInteger) then + CALL Fatal(' Error in file "'//TRIM(SDInputFile)//'": Non integer character found in Member line. Problematic line: "'//trim(Line)//'"') + return + endif +ENDDO + +if (allocated(StrArray)) then + deallocate(StrArray) endif -DO I = 1, p%NMembers + +! ! Read remaining lines +DO I = 2, p%NMembers 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 +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 +!------------------ MEMBER CROSS-SECTION PROPERTY data 1/2 [isotropic material for now: use this table if circular-tubular elements ------------------------ +CALL ReadCom ( UnIn, SDInputFile, ' Member CROSS-Section Property Data 1/2 ',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 @@ -1173,8 +1208,8 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) ENDDO 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 +!------------------ MEMBER CROSS-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 CROSS-Section Property Data 2/2 ' ,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 @@ -1260,7 +1295,7 @@ SUBROUTINE SD_Input(SDInputFile, Init, p, ErrStat,ErrMsg) !---------------------------- OUTPUT: SUMMARY & OUTFILE ------------------------------ CALL ReadCom (UnIn, SDInputFile, 'OUTPUT' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return -CALL ReadLVar(UnIn, SDInputFile, Init%SSSum , 'SSSum' , 'Summary File Logic Variable' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return +CALL ReadLVar(UnIn, SDInputFile, Init%SSSum , 'SumPrint' , 'Summary File Logic Variable' ,ErrStat2, ErrMsg2, UnEc ); if(Failed()) return ! --- Reading OutCBModes and OutFEM Modes (temporary backward compatibility if missing) !CALL ReadIVar( UnIn, SDInputFile, p%OutCBModes , 'OutCBModes' , 'Output of CB Modes' , ErrStat2 , ErrMsg2 , UnEc ); if(Failed()) return read(UnIn,'(A)',iostat=ErrStat2) Line @@ -1421,7 +1456,7 @@ END SUBROUTINE SD_Input !! 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) +SUBROUTINE ReadIAryFromStrSD(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 @@ -1462,7 +1497,7 @@ SUBROUTINE ReadIAryFromStr(Str, IntArray, nColMax, nColValid, nColNumeric, StrAr endif enddo if(allocated(StrArray)) deallocate(StrArray) -END SUBROUTINE ReadIAryFromStr +END SUBROUTINE ReadIAryFromStrSD !> See ReadIAryFromStr, same but for floats SUBROUTINE ReadFAryFromStr(Str, FloatArray, nColMax, nColValid, nColNumeric, StrArrayOut) @@ -1831,7 +1866,6 @@ SUBROUTINE SD_AM2( t, n, u, utimes, p, x, xd, z, OtherState, m, ErrStat, ErrMsg TYPE(SD_InputType) :: u_interp ! interpolated value of inputs REAL(ReKi) :: xq(2*p%nDOFM) !temporary states (qm and qmdot only) REAL(ReKi) :: udotdot_TP2(6) ! temporary copy of udotdot_TP - REAL(ReKi) :: F_L2(p%nDOF__L) ! temporary copy of F_L INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 @@ -1854,7 +1888,7 @@ SUBROUTINE SD_AM2( t, n, u, utimes, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ! 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)) + CALL GetExtForceOnInternalDOF(u_interp, p, x, m, 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)/) if (p%GuyanLoadCorrection.and.p%Floating) then ! >>> Rotate All - udotdot_TP to body coordinates @@ -1864,11 +1898,11 @@ SUBROUTINE SD_AM2( t, n, u, utimes, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ! calculate (u_n + u_n+1)/2 udotdot_TP2 = 0.5_ReKi * ( udotdot_TP2 + m%udotdot_TP ) - F_L2 = 0.5_ReKi * ( F_L2 + m%F_L ) + m%F_L2 = 0.5_ReKi * ( m%F_L2 + m%F_L ) ! 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 + xq(1+p%nDOFM:2*p%nDOFM)=p%SDDeltaT * (-p%KMMDiag*x%qm - p%CMMDiag*x%qmdot - matmul(p%MMB, udotdot_TP2) + matmul(m%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 !.................................................... @@ -2187,7 +2221,7 @@ SUBROUTINE SD_JacobianPConstrState( t, u, p, x, xd, z, OtherState, y, m, ErrStat 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, NeedPackedOrient ) +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, NeedTrimOP ) 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 @@ -2205,11 +2239,11 @@ SUBROUTINE SD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, 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 - LOGICAL, OPTIONAL, INTENT(IN ) :: NeedPackedOrient !< whether a y_op values should contain 3-value representation instead of full orientation matrices + LOGICAL, OPTIONAL, INTENT(IN ) :: NeedTrimOP !< whether a y_op values should contain values for trim solution (3-value representation instead of full orientation matrices, no rotation acc) ! Local INTEGER(IntKi) :: idx, i - LOGICAL :: ReturnPackedOrientation + LOGICAL :: ReturnTrimOP INTEGER(IntKi) :: nu INTEGER(IntKi) :: ny INTEGER(IntKi) :: ErrStat2 @@ -2232,7 +2266,7 @@ SUBROUTINE SD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, FieldMask(MASKID_RotationVel) = .true. FieldMask(MASKID_TranslationAcc) = .true. FieldMask(MASKID_RotationAcc) = .true. - call PackMotionMesh(u%TPMesh, u_op, idx, FieldMask=FieldMask, UseSmlAngle=.true.) + call PackMotionMesh(u%TPMesh, u_op, idx, FieldMask=FieldMask) call PackLoadMesh(u%LMesh, u_op, idx) END IF @@ -2242,13 +2276,13 @@ SUBROUTINE SD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, call AllocAry(y_op, ny, 'y_op', ErrStat2, ErrMsg2); if(Failed()) return end if - if (present(NeedPackedOrient)) then - ReturnPackedOrientation = NeedPackedOrient + if (present(NeedTrimOP)) then + ReturnTrimOP = NeedTrimOP else - ReturnPackedOrientation = .false. + ReturnTrimOP = .false. end if - if (ReturnPackedOrientation) y_op = 0.0_ReKi ! initialize in case we are returning packed orientations and don't fill the entire array + if (ReturnTrimOP) y_op = 0.0_ReKi ! initialize in case we are returning packed orientations and don't fill the entire array idx = 1 call PackLoadMesh(y%Y1Mesh, y_op, idx) @@ -2259,8 +2293,8 @@ SUBROUTINE SD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, FieldMask(MASKID_RotationVel) = .true. FieldMask(MASKID_TranslationAcc) = .true. FieldMask(MASKID_RotationAcc) = .true. - call PackMotionMesh(y%Y2Mesh, y_op, idx, FieldMask=FieldMask, UseSmlAngle=ReturnPackedOrientation) - call PackMotionMesh(y%Y3Mesh, y_op, idx, FieldMask=FieldMask, UseSmlAngle=ReturnPackedOrientation) + call PackMotionMesh(y%Y2Mesh, y_op, idx, FieldMask=FieldMask, TrimOP=ReturnTrimOP) + call PackMotionMesh(y%Y3Mesh, y_op, idx, FieldMask=FieldMask, TrimOP=ReturnTrimOP) idx = idx - 1 do i=1,p%NumOuts y_op(i+idx) = y%WriteOutput(i) @@ -2300,7 +2334,7 @@ SUBROUTINE SD_GetOP( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg, u_op, call CleanUp() contains logical function Failed() - call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'Craig_Bampton') + call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) Failed = ErrStat >= AbortErrLev if (Failed) call CleanUp() end function Failed @@ -2738,20 +2772,23 @@ SUBROUTINE AllocMiscVars(p, Misc, ErrStat, 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%F_L, p%nDOF__L, 'F_L', ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%F_L2, p%nDOF__L, 'F_L2', 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_NS, p%nDOF__L, 'UL_NS', 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%UL_SIM, p%nDOF__L, 'UL_SIM' , ErrStat2, ErrMsg2); CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'AllocMiscVars') + CALL AllocAry( Misc%UL_0m, p%nDOF__L, 'UL_0m', 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_NS, p%nDOF, 'U_full_NS', 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') @@ -3012,9 +3049,37 @@ END SUBROUTINE CleanUp END SUBROUTINE PartitionDOFNodes + +!> Setup the vector of reduced DOFs based on R and L values, and transfer to full vector of DOFs +!! Reminder "reduced" here means the reduction due to constraints (rigid links and rotational joints) +!! This is a generic function, "x" can be used for displacements, velocities, accelerations +!! m%U_red is only used as a intermediate storage +SUBROUTINE ReducedToFull(p, m, xR_bar, xL, x_full) + TYPE(SD_ParameterType),target,INTENT(IN ) :: p !< Parameters + TYPE(SD_MiscVarType), INTENT(INOUT) :: m !< Misc/optimization variables + REAL(ReKi), DIMENSION(:), INTENT(IN ) :: xR_bar !< Values of "x" interface nodes (6xnI) + REAL(ReKi), DIMENSION(:), INTENT(IN ) :: xL !< Values of "x" internal nodes + REAL(ReKi), DIMENSION(:), INTENT( OUT) :: x_full !< Values of "x" transferred to full vector of DOF + if (p%reduced) then + ! Filling up full vector of reduced DOF + m%U_red(p%IDI__) = xR_bar + m%U_red(p%ID__L) = xL + 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 + ! Transfer to full + x_full = matmul(p%T_red, m%U_red) ! TODO use LAPACK, but T_red and U_red have different types... + else + ! We use U_full directly + x_full(p%IDI__) = xR_bar + x_full(p%ID__L) = xL + x_full(p%IDC_Rb)= 0 ! NOTE: for now we don't have leader DOF at "C" (bottom) + x_full(p%ID__F) = 0 + endif +END SUBROUTINE ReducedToFull + !> Compute displacements of all nodes in global system (Guyan + Rotated CB) !! -SUBROUTINE LeverArm(u, p, x, m, DU_full, bGuyan, bElastic, U_full) +SUBROUTINE LeverArm(u, p, x, m, DU_full, bGuyan, bElastic) 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 @@ -3022,7 +3087,6 @@ SUBROUTINE LeverArm(u, p, x, m, DU_full, bGuyan, bElastic, U_full) 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) @@ -3039,77 +3103,56 @@ SUBROUTINE LeverArm(u, p, x, m, DU_full, bGuyan, bElastic, U_full) 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 + ! --- 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 - ! --- 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 + 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) + call ReducedToFull(p, m, m%UR_bar, m%UL, DU_full) + ! --- 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 END SUBROUTINE LeverArm !------------------------------------------------------------------------------------------------------ !> 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 +!! First, the full vector of external forces/moments is built on the non-reduced DOF !! Then, the vector is reduced using the T_red matrix -SUBROUTINE GetExtForceOnInternalDOF(u, p, x, m, F_L, ErrStat, ErrMsg, GuyanLoadCorrection, RotateLoads, U_full) +SUBROUTINE GetExtForceOnInternalDOF(u, p, x, m, F_L, ErrStat, ErrMsg, GuyanLoadCorrection, RotateLoads) 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 @@ -3132,7 +3175,7 @@ SUBROUTINE GetExtForceOnInternalDOF(u, p, x, m, F_L, ErrStat, ErrMsg, GuyanLoadC 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) + call LeverArm(u, p, x, m, m%DU_full, bGuyan=.True., bElastic=.False.) endif ! TODO @@ -3215,7 +3258,7 @@ SUBROUTINE GetExtForceOnInternalDOF(u, p, x, m, F_L, ErrStat, ErrMsg, GuyanLoadC ! --- Reduced vector of external force if (p%reduced) then - m%Fext_red = matmul(p%T_red_T, m%Fext) + m%Fext_red = matmul(p%T_red_T, m%Fext) ! TODO use LAPACK F_L= m%Fext_red(p%ID__L) else F_L= m%Fext(p%ID__L) @@ -3247,7 +3290,7 @@ END SUBROUTINE GetExtForceOnInterfaceDOF !------------------------------------------------------------------------------------------------------ !> Output the modes to file file SUBROUTINE OutModes(Init, p, m, InitInput, CBparams, Modes, Omega, Omega_Gy, ErrStat,ErrMsg) - use YAML + use JSON, only: json_write_array 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 @@ -3310,7 +3353,7 @@ SUBROUTINE OutModes(Init, p, m, InitInput, CBparams, Modes, Omega, Omega_Gy, Err FileName = TRIM(Init%RootName)//'.CBmodes.json' ! Write Nodes/Connectivity/ElementProperties call WriteJSONCommon(FileName, Init, p, m, InitInput, 'Modes', UnSum, ErrStat2, ErrMsg2); if(Failed()) return - write(UnSum, '(A)', advance='no') ','//char(13)//achar(10) + write(UnSum, '(A)', advance='no') ','//NewLine write(UnSum, '(A)') '"Modes": [' ! --- Guyan Modes @@ -3331,7 +3374,7 @@ SUBROUTINE OutModes(Init, p, m, InitInput, CBparams, Modes, Omega, Omega_Gy, Err enddo ! --- CB Modes - if (p%nDOFM>0) write(UnSum, '(A)', advance='no')','//achar(13)//achar(10) + if (p%nDOFM>0) write(UnSum, '(A)', advance='no')','//NewLine do i = 1, p%nDOFM U_red = 0.0_ReKi U_red(p%ID__L) = CBparams%PhiL(:,i) @@ -3358,7 +3401,7 @@ SUBROUTINE OutModes(Init, p, m, InitInput, CBparams, Modes, Omega, Omega_Gy, Err CALL WrScr(' Exporting FEM modes to JSON') FileName = TRIM(Init%RootName)//'.FEMmodes.json' call WriteJSONCommon(FileName, Init, p, m, InitInput, 'Modes', UnSum, ErrStat2, ErrMsg2); if(Failed()) return - write(UnSum, '(A)', advance='no') ','//char(13)//achar(10) + write(UnSum, '(A)', advance='no') ','//NewLine write(UnSum, '(A)') '"Modes": [' nModes = min(size(Modes,2), 30) ! TODO potentially a parameter do i = 1, nModes @@ -3401,9 +3444,9 @@ SUBROUTINE WriteOneMode(U_red, omegaMode, Prefix, iMode, nModes, reduced) if (maxAmplitude>1e-5) then NodesDisp(:,:) = NodesDisp(:,:)*maxDisp/maxAmplitude endif - call yaml_write_array(UnSum, '"Displ"', NodesDisp, ReFmt, ErrStat2, ErrMsg2, json=.true.); + call json_write_array(UnSum, '"Displ"', NodesDisp, ReFmt, ErrStat2, ErrMsg2); write(UnSum, '(A)', advance='no')'}' - if (iMode Write the common part of the JSON file (Nodes, Connectivity, Element prop) SUBROUTINE WriteJSONCommon(FileName, Init, p, m, InitInput, FileKind, UnSum, ErrStat, ErrMsg) - use YAML + use JSON, only: json_write_array 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 @@ -3463,17 +3506,17 @@ SUBROUTINE WriteJSONCommon(FileName, Init, p, m, InitInput, FileKind, UnSum, Err Connectivity(i,1) = p%Elems(i,2)-1 ! Node 1 Connectivity(i,2) = p%Elems(i,3)-1 ! Node 2 enddo - call yaml_write_array(UnSum, '"Connectivity"', Connectivity, 'I0', ErrStat2, ErrMsg2, json=.true.); write(UnSum, '(A)', advance='no')','//achar(13)//achar(10) + call json_write_array(UnSum, '"Connectivity"', Connectivity, 'I0', ErrStat2, ErrMsg2); write(UnSum, '(A)', advance='no')','//NewLine if(allocated(Connectivity)) deallocate(Connectivity) ! --- Nodes - call yaml_write_array(UnSum, '"Nodes"', Init%Nodes(:,2:4), ReFmt, ErrStat2, ErrMsg2, json=.true.); write(UnSum, '(A)', advance='no')','//achar(13)//achar(10) + call json_write_array(UnSum, '"Nodes"', Init%Nodes(:,2:4), ReFmt, ErrStat2, ErrMsg2); write(UnSum, '(A)', advance='no')','//NewLine ! --- Elem props write(UnSum, '(A)') '"ElemProps": [' do i = 1, size(p%ElemProps) write(UnSum, '(A,I0,A,F8.4,A)', advance='no') ' {"shape": "cylinder", "type": ',p%ElemProps(i)%eType, ', "Diam":',p%ElemProps(i)%D(1),'}' - if (i Output the summary file SUBROUTINE OutSummary(Init, p, m, InitInput, CBparams, Modes, Omega, Omega_Gy, ErrStat,ErrMsg) - use Yaml + use YAML, only: yaml_write_var, yaml_write_list, yaml_write_array 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 @@ -3662,7 +3705,7 @@ SUBROUTINE OutSummary(Init, p, m, InitInput, CBparams, Modes, Omega, Omega_Gy, E 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,12) = p%ElemProps(i)%Kappa_x ! 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 @@ -3728,7 +3771,7 @@ SUBROUTINE OutSummary(Init, p, m, InitInput, CBparams, Modes, Omega, Omega_Gy, E mLength=MemberLength(Init%Members(i,1),Init,ErrStat,ErrMsg) ! TODO double check mass and length IF (ErrStat .EQ. ErrID_None) THEN mType = Init%Members(I, iMType) ! - if (mType==idMemberBeam) then + if (mType==idMemberBeamCirc) 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), & @@ -3746,6 +3789,12 @@ SUBROUTINE OutSummary(Init, p, m, InitInput, CBparams, Modes, Omega, Omega_Gy, E 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 if (mType==idMemberBeamArb) then + iProp(1) = FINDLOCI(Init%PropSetsX(:,1), propIDs(1)) + iProp(2) = FINDLOCI(Init%PropSetsX(:,1), propIDs(2)) + mMass= -1 ! TODO compute mass for arbitrary beams + 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 WRITE(UnSum, '(A)') '#TODO, member unknown' endif @@ -3766,7 +3815,7 @@ SUBROUTINE OutSummary(Init, p, m, InitInput, CBparams, Modes, Omega, Omega_Gy, E 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) + WRITE(UnSum, '("#",I9,9(ES28.18E2))') Init%Members(i,1), ((DirCos(k,j),j=1,3),k=1,3) ENDDO @@ -4134,6 +4183,19 @@ FUNCTION is_numeric(string, x) READ(string,fmt,IOSTAT=e) x is_numeric = e == 0 END FUNCTION is_numeric + +FUNCTION is_integer(string, x) + IMPLICIT NONE + CHARACTER(len=*), INTENT(IN) :: string + INTEGER(IntKi), INTENT(OUT) :: x + LOGICAL :: is_integer + INTEGER :: e, n + x = 0 + n=LEN_TRIM(string) + READ(string,*,IOSTAT=e) x + is_integer = e == 0 +END FUNCTION is_integer + FUNCTION is_logical(string, b) IMPLICIT NONE CHARACTER(len=*), INTENT(IN) :: string diff --git a/modules/subdyn/src/SubDyn_Output.f90 b/modules/subdyn/src/SubDyn_Output.f90 index b731e628f..7f40b0c9d 100644 --- a/modules/subdyn/src/SubDyn_Output.f90 +++ b/modules/subdyn/src/SubDyn_Output.f90 @@ -85,6 +85,7 @@ SUBROUTINE SDOut_Init( Init, y, p, misc, InitOut, WtrDpth, ErrStat, ErrMsg ) 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 + allocate(misc%AllOuts(0:MaxOutPts + p%OutAllInt*p%OutAllDims)) ! Need to start at 0... ! 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 diff --git a/modules/subdyn/src/SubDyn_Registry.txt b/modules/subdyn/src/SubDyn_Registry.txt index 9bcd06aff..0287f2ab9 100644 --- a/modules/subdyn/src/SubDyn_Registry.txt +++ b/modules/subdyn/src/SubDyn_Registry.txt @@ -33,7 +33,8 @@ typedef ^ ElemPropType ReKi Ixx - - - "Moment of inertia of an el 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 Kappa_x - - - "Shear coefficient" +typedef ^ ElemPropType ReKi Kappa_y - - - "Shear coefficient" typedef ^ ElemPropType ReKi YoungE - - - "Young's modulus" typedef ^ ElemPropType ReKi ShearG - - - "Shear modulus" N/m^2 # Properties common to all element types: @@ -90,7 +91,7 @@ typedef ^ SD_InitType ReKi PropSetsB {:}{:} - - "Property 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 R8Ki 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]" @@ -140,27 +141,32 @@ typedef ^ MiscVarType ReKi qmdotdot {:} - - "2nd Deriva 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 F_L {:} - - "Loads on internal DOF, size nL" +typedef ^ MiscVarType ReKi F_L2 {:} - - "Loads on internal DOF, size nL, used for SIM and ADM4" 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 {:} - - "Internal DOFs (L) displacements " +typedef ^ MiscVarType ReKi UL_NS {:} - - "Internal DOFs (L) displacements, No SIM (NS)" 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 DU_full {:} - - "Delta U used for extra moment, size nDOF" +typedef ^ MiscVarType ReKi U_full {:} - - "Displacement of all DOFs (full system) with SIM" +typedef ^ MiscVarType ReKi U_full_NS {:} - - "Displacement of all DOFs (full system), No SIM (NS)" 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_full_elast {:} - - "Elastic displacements for computation of K ue (without rigid body mode for floating), includes SIM" 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 ReKi AllOuts {:} - - "Data for 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" "-" +# SIM +typedef ^ MiscVarType ReKi UL_SIM {:} - - "UL for SIM = PhiL qL0- PhiM qm0, size nL" +typedef ^ MiscVarType ReKi UL_0m {:} - - "Intermediate UL term for SIM = PhiM qm0, size nL" ### 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) ### # ============================== Parameters ============================================================================================================================================ diff --git a/modules/subdyn/src/SubDyn_Types.f90 b/modules/subdyn/src/SubDyn_Types.f90 index d35659a9d..b6dfcc095 100644 --- a/modules/subdyn/src/SubDyn_Types.f90 +++ b/modules/subdyn/src/SubDyn_Types.f90 @@ -69,7 +69,8 @@ MODULE SubDyn_Types REAL(ReKi) :: Iyy !< Moment of inertia of an element [-] REAL(ReKi) :: Jzz !< Moment of inertia of an element [-] LOGICAL :: Shear !< Use timoshenko (true) E-B (false) [-] - REAL(ReKi) :: Kappa !< Shear coefficient [-] + REAL(ReKi) :: Kappa_x !< Shear coefficient [-] + REAL(ReKi) :: Kappa_y !< Shear coefficient [-] REAL(ReKi) :: YoungE !< Young's modulus [-] REAL(ReKi) :: ShearG !< Shear modulus [N/m^2] REAL(ReKi) , DIMENSION(1:2) :: D !< Diameter at node 1 and 2, for visualization only [m] @@ -130,7 +131,7 @@ MODULE SubDyn_Types 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(R8Ki) , 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) :: GuyanDampMod !< Guyan damping [0=none, 1=Rayleigh Damping, 2= user specified 6x6 matrix] [-] @@ -191,27 +192,31 @@ 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 :: F_L + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: F_L !< Loads on internal DOF, size nL [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: F_L2 !< Loads on internal DOF, size nL, used for SIM and ADM4 [-] 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 !< Internal DOFs (L) displacements [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: UL_NS !< Internal DOFs (L) displacements, No SIM (NS) [-] 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 :: DU_full !< Delta U used for extra moment, size nDOF [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: U_full !< Displacement of all DOFs (full system) with SIM [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: U_full_NS !< Displacement of all DOFs (full system), No SIM (NS) [-] 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_full_elast !< Elastic displacements for computation of K ue (without rigid body mode for floating), includes SIM [-] 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(ReKi) , DIMENSION(:), ALLOCATABLE :: AllOuts !< Data for 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 [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: UL_SIM !< UL for SIM = PhiL qL0- PhiM qm0, size nL [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: UL_0m !< Intermediate UL term for SIM = PhiM qm0, size nL [-] END TYPE SD_MiscVarType ! ======================= ! ========= SD_ParameterType ======= @@ -369,15 +374,27 @@ SUBROUTINE SD_CopyIList( SrcIListData, DstIListData, CtrlCode, ErrStat, ErrMsg ) ENDIF END SUBROUTINE SD_CopyIList - SUBROUTINE SD_DestroyIList( IListData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyIList( IListData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(IList), INTENT(INOUT) :: IListData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyIList' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyIList' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(IListData%List)) THEN DEALLOCATE(IListData%List) ENDIF @@ -643,15 +660,27 @@ SUBROUTINE SD_CopyMeshAuxDataType( SrcMeshAuxDataTypeData, DstMeshAuxDataTypeDat ENDIF END SUBROUTINE SD_CopyMeshAuxDataType - SUBROUTINE SD_DestroyMeshAuxDataType( MeshAuxDataTypeData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyMeshAuxDataType( MeshAuxDataTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(MeshAuxDataType), INTENT(INOUT) :: MeshAuxDataTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyMeshAuxDataType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyMeshAuxDataType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MeshAuxDataTypeData%NodeCnt)) THEN DEALLOCATE(MeshAuxDataTypeData%NodeCnt) ENDIF @@ -1247,15 +1276,27 @@ SUBROUTINE SD_CopyCB_MatArrays( SrcCB_MatArraysData, DstCB_MatArraysData, CtrlCo ENDIF END SUBROUTINE SD_CopyCB_MatArrays - SUBROUTINE SD_DestroyCB_MatArrays( CB_MatArraysData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyCB_MatArrays( CB_MatArraysData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(CB_MatArrays), INTENT(INOUT) :: CB_MatArraysData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyCB_MatArrays' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyCB_MatArrays' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(CB_MatArraysData%MBB)) THEN DEALLOCATE(CB_MatArraysData%MBB) ENDIF @@ -1670,7 +1711,8 @@ SUBROUTINE SD_CopyElemPropType( SrcElemPropTypeData, DstElemPropTypeData, CtrlCo DstElemPropTypeData%Iyy = SrcElemPropTypeData%Iyy DstElemPropTypeData%Jzz = SrcElemPropTypeData%Jzz DstElemPropTypeData%Shear = SrcElemPropTypeData%Shear - DstElemPropTypeData%Kappa = SrcElemPropTypeData%Kappa + DstElemPropTypeData%Kappa_x = SrcElemPropTypeData%Kappa_x + DstElemPropTypeData%Kappa_y = SrcElemPropTypeData%Kappa_y DstElemPropTypeData%YoungE = SrcElemPropTypeData%YoungE DstElemPropTypeData%ShearG = SrcElemPropTypeData%ShearG DstElemPropTypeData%D = SrcElemPropTypeData%D @@ -1680,15 +1722,27 @@ SUBROUTINE SD_CopyElemPropType( SrcElemPropTypeData, DstElemPropTypeData, CtrlCo DstElemPropTypeData%DirCos = SrcElemPropTypeData%DirCos END SUBROUTINE SD_CopyElemPropType - SUBROUTINE SD_DestroyElemPropType( ElemPropTypeData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyElemPropType( ElemPropTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(ElemPropType), INTENT(INOUT) :: ElemPropTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyElemPropType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyElemPropType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SD_DestroyElemPropType SUBROUTINE SD_PackElemPropType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1732,7 +1786,8 @@ SUBROUTINE SD_PackElemPropType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err 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 ! Kappa_x + Re_BufSz = Re_BufSz + 1 ! Kappa_y Re_BufSz = Re_BufSz + 1 ! YoungE Re_BufSz = Re_BufSz + 1 ! ShearG Re_BufSz = Re_BufSz + SIZE(InData%D) ! D @@ -1779,7 +1834,9 @@ SUBROUTINE SD_PackElemPropType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Err Re_Xferred = Re_Xferred + 1 IntKiBuf(Int_Xferred) = TRANSFER(InData%Shear, IntKiBuf(1)) Int_Xferred = Int_Xferred + 1 - ReKiBuf(Re_Xferred) = InData%Kappa + ReKiBuf(Re_Xferred) = InData%Kappa_x + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Kappa_y Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%YoungE Re_Xferred = Re_Xferred + 1 @@ -1843,7 +1900,9 @@ SUBROUTINE SD_UnPackElemPropType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Re_Xferred = Re_Xferred + 1 OutData%Shear = TRANSFER(IntKiBuf(Int_Xferred), OutData%Shear) Int_Xferred = Int_Xferred + 1 - OutData%Kappa = ReKiBuf(Re_Xferred) + OutData%Kappa_x = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Kappa_y = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%YoungE = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 @@ -1918,19 +1977,32 @@ SUBROUTINE SD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrSt DstInitInputData%Linearize = SrcInitInputData%Linearize END SUBROUTINE SD_CopyInitInput - SUBROUTINE SD_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SD_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitInputData%SoilStiffness)) THEN DEALLOCATE(InitInputData%SoilStiffness) ENDIF - CALL MeshDestroy( InitInputData%SoilMesh, ErrStat, ErrMsg ) + CALL MeshDestroy( InitInputData%SoilMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE SD_DestroyInitInput SUBROUTINE SD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2373,22 +2445,35 @@ SUBROUTINE SD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, Er ENDIF END SUBROUTINE SD_CopyInitOutput - SUBROUTINE SD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SD_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN DEALLOCATE(InitOutputData%WriteOutputUnt) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InitOutputData%LinNames_y)) THEN DEALLOCATE(InitOutputData%LinNames_y) ENDIF @@ -3437,15 +3522,27 @@ SUBROUTINE SD_CopyInitType( SrcInitTypeData, DstInitTypeData, CtrlCode, ErrStat, DstInitTypeData%SSSum = SrcInitTypeData%SSSum END SUBROUTINE SD_CopyInitType - SUBROUTINE SD_DestroyInitType( InitTypeData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyInitType( InitTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SD_InitType), INTENT(INOUT) :: InitTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyInitType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyInitType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitTypeData%Joints)) THEN DEALLOCATE(InitTypeData%Joints) ENDIF @@ -3604,7 +3701,7 @@ SUBROUTINE SD_PackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 1 ! COSMs allocated yes/no IF ( ALLOCATED(InData%COSMs) ) THEN Int_BufSz = Int_BufSz + 2*2 ! COSMs upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%COSMs) ! COSMs + Db_BufSz = Db_BufSz + SIZE(InData%COSMs) ! COSMs END IF Int_BufSz = Int_BufSz + 1 ! CMass allocated yes/no IF ( ALLOCATED(InData%CMass) ) THEN @@ -3892,8 +3989,8 @@ SUBROUTINE SD_PackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, DO i2 = LBOUND(InData%COSMs,2), UBOUND(InData%COSMs,2) DO i1 = LBOUND(InData%COSMs,1), UBOUND(InData%COSMs,1) - ReKiBuf(Re_Xferred) = InData%COSMs(i1,i2) - Re_Xferred = Re_Xferred + 1 + DbKiBuf(Db_Xferred) = InData%COSMs(i1,i2) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -4512,8 +4609,8 @@ SUBROUTINE SD_UnPackInitType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM END IF DO i2 = LBOUND(OutData%COSMs,2), UBOUND(OutData%COSMs,2) DO i1 = LBOUND(OutData%COSMs,1), UBOUND(OutData%COSMs,1) - OutData%COSMs(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + OutData%COSMs(i1,i2) = REAL(DbKiBuf(Db_Xferred), R8Ki) + Db_Xferred = Db_Xferred + 1 END DO END DO END IF @@ -5041,15 +5138,27 @@ SUBROUTINE SD_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrSt ENDIF END SUBROUTINE SD_CopyContState - SUBROUTINE SD_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SD_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ContStateData%qm)) THEN DEALLOCATE(ContStateData%qm) ENDIF @@ -5244,15 +5353,27 @@ SUBROUTINE SD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState END SUBROUTINE SD_CopyDiscState - SUBROUTINE SD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SD_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SD_DestroyDiscState SUBROUTINE SD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -5369,15 +5490,27 @@ SUBROUTINE SD_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE SD_CopyConstrState - SUBROUTINE SD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SD_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SD_DestroyConstrState SUBROUTINE SD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -5511,18 +5644,31 @@ SUBROUTINE SD_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, Er DstOtherStateData%n = SrcOtherStateData%n END SUBROUTINE SD_CopyOtherState - SUBROUTINE SD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SD_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OtherStateData%xdot)) THEN DO i1 = LBOUND(OtherStateData%xdot,1), UBOUND(OtherStateData%xdot,1) - CALL SD_DestroyContState( OtherStateData%xdot(i1), ErrStat, ErrMsg ) + CALL SD_DestroyContState( OtherStateData%xdot(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(OtherStateData%xdot) ENDIF @@ -5789,6 +5935,18 @@ SUBROUTINE SD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF DstMiscData%F_L = SrcMiscData%F_L ENDIF +IF (ALLOCATED(SrcMiscData%F_L2)) THEN + i1_l = LBOUND(SrcMiscData%F_L2,1) + i1_u = UBOUND(SrcMiscData%F_L2,1) + IF (.NOT. ALLOCATED(DstMiscData%F_L2)) THEN + ALLOCATE(DstMiscData%F_L2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%F_L2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%F_L2 = SrcMiscData%F_L2 +ENDIF IF (ALLOCATED(SrcMiscData%UR_bar)) THEN i1_l = LBOUND(SrcMiscData%UR_bar,1) i1_u = UBOUND(SrcMiscData%UR_bar,1) @@ -5837,6 +5995,18 @@ SUBROUTINE SD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF DstMiscData%UL = SrcMiscData%UL ENDIF +IF (ALLOCATED(SrcMiscData%UL_NS)) THEN + i1_l = LBOUND(SrcMiscData%UL_NS,1) + i1_u = UBOUND(SrcMiscData%UL_NS,1) + IF (.NOT. ALLOCATED(DstMiscData%UL_NS)) THEN + ALLOCATE(DstMiscData%UL_NS(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%UL_NS.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%UL_NS = SrcMiscData%UL_NS +ENDIF IF (ALLOCATED(SrcMiscData%UL_dot)) THEN i1_l = LBOUND(SrcMiscData%UL_dot,1) i1_u = UBOUND(SrcMiscData%UL_dot,1) @@ -5885,6 +6055,18 @@ SUBROUTINE SD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF DstMiscData%U_full = SrcMiscData%U_full ENDIF +IF (ALLOCATED(SrcMiscData%U_full_NS)) THEN + i1_l = LBOUND(SrcMiscData%U_full_NS,1) + i1_u = UBOUND(SrcMiscData%U_full_NS,1) + IF (.NOT. ALLOCATED(DstMiscData%U_full_NS)) THEN + ALLOCATE(DstMiscData%U_full_NS(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%U_full_NS.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%U_full_NS = SrcMiscData%U_full_NS +ENDIF IF (ALLOCATED(SrcMiscData%U_full_dot)) THEN i1_l = LBOUND(SrcMiscData%U_full_dot,1) i1_u = UBOUND(SrcMiscData%U_full_dot,1) @@ -5933,30 +6115,6 @@ SUBROUTINE SD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) 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) @@ -5980,6 +6138,18 @@ SUBROUTINE SD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF END IF DstMiscData%SDWrOutput = SrcMiscData%SDWrOutput +ENDIF +IF (ALLOCATED(SrcMiscData%AllOuts)) THEN + i1_l = LBOUND(SrcMiscData%AllOuts,1) + i1_u = UBOUND(SrcMiscData%AllOuts,1) + IF (.NOT. ALLOCATED(DstMiscData%AllOuts)) THEN + ALLOCATE(DstMiscData%AllOuts(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%AllOuts.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%AllOuts = SrcMiscData%AllOuts ENDIF DstMiscData%LastOutTime = SrcMiscData%LastOutTime DstMiscData%Decimat = SrcMiscData%Decimat @@ -6006,24 +6176,63 @@ SUBROUTINE SD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF END IF DstMiscData%Fext_red = SrcMiscData%Fext_red +ENDIF +IF (ALLOCATED(SrcMiscData%UL_SIM)) THEN + i1_l = LBOUND(SrcMiscData%UL_SIM,1) + i1_u = UBOUND(SrcMiscData%UL_SIM,1) + IF (.NOT. ALLOCATED(DstMiscData%UL_SIM)) THEN + ALLOCATE(DstMiscData%UL_SIM(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%UL_SIM.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%UL_SIM = SrcMiscData%UL_SIM +ENDIF +IF (ALLOCATED(SrcMiscData%UL_0m)) THEN + i1_l = LBOUND(SrcMiscData%UL_0m,1) + i1_u = UBOUND(SrcMiscData%UL_0m,1) + IF (.NOT. ALLOCATED(DstMiscData%UL_0m)) THEN + ALLOCATE(DstMiscData%UL_0m(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%UL_0m.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%UL_0m = SrcMiscData%UL_0m ENDIF END SUBROUTINE SD_CopyMisc - SUBROUTINE SD_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SD_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%qmdotdot)) THEN DEALLOCATE(MiscData%qmdotdot) ENDIF IF (ALLOCATED(MiscData%F_L)) THEN DEALLOCATE(MiscData%F_L) ENDIF +IF (ALLOCATED(MiscData%F_L2)) THEN + DEALLOCATE(MiscData%F_L2) +ENDIF IF (ALLOCATED(MiscData%UR_bar)) THEN DEALLOCATE(MiscData%UR_bar) ENDIF @@ -6036,6 +6245,9 @@ SUBROUTINE SD_DestroyMisc( MiscData, ErrStat, ErrMsg ) IF (ALLOCATED(MiscData%UL)) THEN DEALLOCATE(MiscData%UL) ENDIF +IF (ALLOCATED(MiscData%UL_NS)) THEN + DEALLOCATE(MiscData%UL_NS) +ENDIF IF (ALLOCATED(MiscData%UL_dot)) THEN DEALLOCATE(MiscData%UL_dot) ENDIF @@ -6048,6 +6260,9 @@ SUBROUTINE SD_DestroyMisc( MiscData, ErrStat, ErrMsg ) IF (ALLOCATED(MiscData%U_full)) THEN DEALLOCATE(MiscData%U_full) ENDIF +IF (ALLOCATED(MiscData%U_full_NS)) THEN + DEALLOCATE(MiscData%U_full_NS) +ENDIF IF (ALLOCATED(MiscData%U_full_dot)) THEN DEALLOCATE(MiscData%U_full_dot) ENDIF @@ -6060,23 +6275,26 @@ SUBROUTINE SD_DestroyMisc( MiscData, ErrStat, ErrMsg ) 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%AllOuts)) THEN + DEALLOCATE(MiscData%AllOuts) +ENDIF IF (ALLOCATED(MiscData%Fext)) THEN DEALLOCATE(MiscData%Fext) ENDIF IF (ALLOCATED(MiscData%Fext_red)) THEN DEALLOCATE(MiscData%Fext_red) +ENDIF +IF (ALLOCATED(MiscData%UL_SIM)) THEN + DEALLOCATE(MiscData%UL_SIM) +ENDIF +IF (ALLOCATED(MiscData%UL_0m)) THEN + DEALLOCATE(MiscData%UL_0m) ENDIF END SUBROUTINE SD_DestroyMisc @@ -6128,6 +6346,11 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz 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 ! F_L2 allocated yes/no + IF ( ALLOCATED(InData%F_L2) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! F_L2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%F_L2) ! F_L2 + END IF Int_BufSz = Int_BufSz + 1 ! UR_bar allocated yes/no IF ( ALLOCATED(InData%UR_bar) ) THEN Int_BufSz = Int_BufSz + 2*1 ! UR_bar upper/lower bounds for each dimension @@ -6148,6 +6371,11 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_BufSz = Int_BufSz + 2*1 ! UL upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%UL) ! UL END IF + Int_BufSz = Int_BufSz + 1 ! UL_NS allocated yes/no + IF ( ALLOCATED(InData%UL_NS) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! UL_NS upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%UL_NS) ! UL_NS + END IF Int_BufSz = Int_BufSz + 1 ! UL_dot allocated yes/no IF ( ALLOCATED(InData%UL_dot) ) THEN Int_BufSz = Int_BufSz + 2*1 ! UL_dot upper/lower bounds for each dimension @@ -6168,6 +6396,11 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz 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_NS allocated yes/no + IF ( ALLOCATED(InData%U_full_NS) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! U_full_NS upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%U_full_NS) ! U_full_NS + 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 @@ -6188,16 +6421,6 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz 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 @@ -6207,6 +6430,11 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz IF ( ALLOCATED(InData%SDWrOutput) ) THEN Int_BufSz = Int_BufSz + 2*1 ! SDWrOutput upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%SDWrOutput) ! SDWrOutput + END IF + Int_BufSz = Int_BufSz + 1 ! AllOuts allocated yes/no + IF ( ALLOCATED(InData%AllOuts) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! AllOuts upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%AllOuts) ! AllOuts END IF Db_BufSz = Db_BufSz + 1 ! LastOutTime Int_BufSz = Int_BufSz + 1 ! Decimat @@ -6220,6 +6448,16 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz 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 + Int_BufSz = Int_BufSz + 1 ! UL_SIM allocated yes/no + IF ( ALLOCATED(InData%UL_SIM) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! UL_SIM upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%UL_SIM) ! UL_SIM + END IF + Int_BufSz = Int_BufSz + 1 ! UL_0m allocated yes/no + IF ( ALLOCATED(InData%UL_0m) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! UL_0m upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%UL_0m) ! UL_0m + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -6289,6 +6527,21 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%F_L2) ) THEN + 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_L2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%F_L2,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%F_L2,1), UBOUND(InData%F_L2,1) + ReKiBuf(Re_Xferred) = InData%F_L2(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF IF ( .NOT. ALLOCATED(InData%UR_bar) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -6349,6 +6602,21 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%UL_NS) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%UL_NS,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%UL_NS,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%UL_NS,1), UBOUND(InData%UL_NS,1) + ReKiBuf(Re_Xferred) = InData%UL_NS(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF IF ( .NOT. ALLOCATED(InData%UL_dot) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -6409,6 +6677,21 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%U_full_NS) ) THEN + 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_NS,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%U_full_NS,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%U_full_NS,1), UBOUND(InData%U_full_NS,1) + ReKiBuf(Re_Xferred) = InData%U_full_NS(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 @@ -6469,36 +6752,6 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz 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 @@ -6528,6 +6781,21 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz ReKiBuf(Re_Xferred) = InData%SDWrOutput(i1) Re_Xferred = Re_Xferred + 1 END DO + END IF + IF ( .NOT. ALLOCATED(InData%AllOuts) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%AllOuts,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%AllOuts,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%AllOuts,1), UBOUND(InData%AllOuts,1) + ReKiBuf(Re_Xferred) = InData%AllOuts(i1) + Re_Xferred = Re_Xferred + 1 + END DO END IF DbKiBuf(Db_Xferred) = InData%LastOutTime Db_Xferred = Db_Xferred + 1 @@ -6563,6 +6831,36 @@ SUBROUTINE SD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%UL_SIM) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%UL_SIM,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%UL_SIM,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%UL_SIM,1), UBOUND(InData%UL_SIM,1) + ReKiBuf(Re_Xferred) = InData%UL_SIM(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%UL_0m) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%UL_0m,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%UL_0m,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%UL_0m,1), UBOUND(InData%UL_0m,1) + ReKiBuf(Re_Xferred) = InData%UL_0m(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE SD_PackMisc SUBROUTINE SD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -6646,6 +6944,24 @@ SUBROUTINE SD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! F_L2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + 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_L2)) DEALLOCATE(OutData%F_L2) + ALLOCATE(OutData%F_L2(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%F_L2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%F_L2,1), UBOUND(OutData%F_L2,1) + OutData%F_L2(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! UR_bar not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -6718,6 +7034,24 @@ SUBROUTINE SD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! UL_NS not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%UL_NS)) DEALLOCATE(OutData%UL_NS) + ALLOCATE(OutData%UL_NS(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%UL_NS.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%UL_NS,1), UBOUND(OutData%UL_NS,1) + OutData%UL_NS(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! UL_dot not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -6790,6 +7124,24 @@ SUBROUTINE SD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! U_full_NS not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + 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_NS)) DEALLOCATE(OutData%U_full_NS) + ALLOCATE(OutData%U_full_NS(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%U_full_NS.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%U_full_NS,1), UBOUND(OutData%U_full_NS,1) + OutData%U_full_NS(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! U_full_dot not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -6862,42 +7214,6 @@ SUBROUTINE SD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) 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 @@ -6933,6 +7249,24 @@ SUBROUTINE SD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) OutData%SDWrOutput(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! AllOuts not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%AllOuts)) DEALLOCATE(OutData%AllOuts) + ALLOCATE(OutData%AllOuts(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%AllOuts.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%AllOuts,1), UBOUND(OutData%AllOuts,1) + OutData%AllOuts(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END IF OutData%LastOutTime = DbKiBuf(Db_Xferred) Db_Xferred = Db_Xferred + 1 @@ -6974,6 +7308,42 @@ SUBROUTINE SD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! UL_SIM not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%UL_SIM)) DEALLOCATE(OutData%UL_SIM) + ALLOCATE(OutData%UL_SIM(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%UL_SIM.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%UL_SIM,1), UBOUND(OutData%UL_SIM,1) + OutData%UL_SIM(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! UL_0m not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%UL_0m)) DEALLOCATE(OutData%UL_0m) + ALLOCATE(OutData%UL_0m(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%UL_0m.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%UL_0m,1), UBOUND(OutData%UL_0m,1) + OutData%UL_0m(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 ) @@ -7842,21 +8212,34 @@ SUBROUTINE SD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) DstParamData%RotStates = SrcParamData%RotStates END SUBROUTINE SD_CopyParam - SUBROUTINE SD_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SD_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + 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 ) + CALL SD_Destroyelemproptype( ParamData%ElemProps(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%ElemProps) ENDIF @@ -7877,13 +8260,15 @@ SUBROUTINE SD_DestroyParam( ParamData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(ParamData%NodesDOF)) THEN DO i1 = LBOUND(ParamData%NodesDOF,1), UBOUND(ParamData%NodesDOF,1) - CALL SD_Destroyilist( ParamData%NodesDOF(i1), ErrStat, ErrMsg ) + CALL SD_Destroyilist( ParamData%NodesDOF(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) 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 ) + CALL SD_Destroyilist( ParamData%NodesDOFred(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%NodesDOFred) ENDIF @@ -8021,25 +8406,29 @@ SUBROUTINE SD_DestroyParam( ParamData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(ParamData%MoutLst)) THEN DO i1 = LBOUND(ParamData%MoutLst,1), UBOUND(ParamData%MoutLst,1) - CALL SD_Destroymeshauxdatatype( ParamData%MoutLst(i1), ErrStat, ErrMsg ) + CALL SD_Destroymeshauxdatatype( ParamData%MoutLst(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%MoutLst) ENDIF IF (ALLOCATED(ParamData%MoutLst2)) THEN DO i1 = LBOUND(ParamData%MoutLst2,1), UBOUND(ParamData%MoutLst2,1) - CALL SD_Destroymeshauxdatatype( ParamData%MoutLst2(i1), ErrStat, ErrMsg ) + CALL SD_Destroymeshauxdatatype( ParamData%MoutLst2(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%MoutLst2) ENDIF IF (ALLOCATED(ParamData%MoutLst3)) THEN DO i1 = LBOUND(ParamData%MoutLst3,1), UBOUND(ParamData%MoutLst3,1) - CALL SD_Destroymeshauxdatatype( ParamData%MoutLst3(i1), ErrStat, ErrMsg ) + CALL SD_Destroymeshauxdatatype( ParamData%MoutLst3(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%MoutLst3) 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 ) + CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) ENDDO DEALLOCATE(ParamData%OutParam) ENDIF @@ -11575,17 +11964,31 @@ SUBROUTINE SD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) ENDIF END SUBROUTINE SD_CopyInput - SUBROUTINE SD_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SD_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( InputData%TPMesh, ErrStat, ErrMsg ) - CALL MeshDestroy( InputData%LMesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( InputData%TPMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( InputData%LMesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(InputData%CableDeltaL)) THEN DEALLOCATE(InputData%CableDeltaL) ENDIF @@ -11931,18 +12334,33 @@ SUBROUTINE SD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs ENDIF END SUBROUTINE SD_CopyOutput - SUBROUTINE SD_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE SD_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SD_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SD_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL MeshDestroy( OutputData%Y1Mesh, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%Y2Mesh, ErrStat, ErrMsg ) - CALL MeshDestroy( OutputData%Y3Mesh, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL MeshDestroy( OutputData%Y1Mesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( OutputData%Y2Mesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + CALL MeshDestroy( OutputData%Y3Mesh, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) IF (ALLOCATED(OutputData%WriteOutput)) THEN DEALLOCATE(OutputData%WriteOutput) ENDIF diff --git a/modules/supercontroller/CMakeLists.txt b/modules/supercontroller/CMakeLists.txt index 4dfde3048..6c9323af6 100644 --- a/modules/supercontroller/CMakeLists.txt +++ b/modules/supercontroller/CMakeLists.txt @@ -19,30 +19,33 @@ if (GENERATE_TYPES) generate_f90_types(src/SC_DataEx_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/SCDataEx_Types.f90 -ccode -noextrap) endif() -# copy the header files to their build location -configure_file(src/SuperController_Types.h ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) -configure_file(src/SCDataEx_Types.h ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) - -add_library(scdataextypeslib src/SCDataEx_Types.f90) -target_link_libraries(scdataextypeslib nwtclibs) - -add_library(scdataexlib src/SC_DataEx.f90) -target_link_libraries(scdataexlib scdataextypeslib openfast_prelib nwtclibs) - -add_library(sctypeslib src/SuperController_Types.f90) +add_library(sctypeslib + src/SCDataEx_Types.f90 +) target_link_libraries(sctypeslib nwtclibs) add_library(scfastlib - src/SuperController.f90) -target_link_libraries(scfastlib sctypeslib openfast_prelib nwtclibs) - -install(TARGETS sctypeslib scfastlib scdataextypeslib scdataexlib + src/SC_DataEx.f90 + src/SuperController_Types.f90 + src/SuperController.f90 +) +target_include_directories(scfastlib PUBLIC + $ +) +target_link_libraries(scfastlib openfast_prelib) +set_target_properties(scfastlib PROPERTIES PUBLIC_HEADER "src/SuperController_Types.h;src/SCDataEx_Types.h") + +add_library(sclib SHARED + src/SC_DLL.F90 +) +if(APPLE OR UNIX) + target_compile_definitions(sclib PRIVATE IMPLICIT_DLLEXPORT) +endif() + +install(TARGETS sctypeslib scfastlib sclib EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) - -install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/SuperController_Types.h - ${CMAKE_CURRENT_BINARY_DIR}/SCDataEx_Types.h - DESTINATION include) + PUBLIC_HEADER DESTINATION include +) diff --git a/modules/supercontroller/src/SCDataEx_Types.f90 b/modules/supercontroller/src/SCDataEx_Types.f90 index 87f9b8325..2a44f5948 100644 --- a/modules/supercontroller/src/SCDataEx_Types.f90 +++ b/modules/supercontroller/src/SCDataEx_Types.f90 @@ -116,15 +116,27 @@ SUBROUTINE SC_DX_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, Er DstInitInputData%C_obj%NumCtrl2SC = SrcInitInputData%C_obj%NumCtrl2SC END SUBROUTINE SC_DX_CopyInitInput - SUBROUTINE SC_DX_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE SC_DX_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_DX_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DX_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DX_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SC_DX_DestroyInitInput SUBROUTINE SC_DX_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -299,16 +311,29 @@ SUBROUTINE SC_DX_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE SC_DX_CopyInitOutput - SUBROUTINE SC_DX_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE SC_DX_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_DX_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DX_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DX_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE SC_DX_DestroyInitOutput SUBROUTINE SC_DX_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -543,15 +568,27 @@ SUBROUTINE SC_DX_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMs DstParamData%C_obj%useSC = SrcParamData%C_obj%useSC END SUBROUTINE SC_DX_CopyParam - SUBROUTINE SC_DX_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE SC_DX_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_DX_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DX_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DX_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SC_DX_DestroyParam SUBROUTINE SC_DX_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -716,22 +753,35 @@ SUBROUTINE SC_DX_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMs END IF DstInputData%c_obj%toSC_Len = SIZE(DstInputData%toSC) IF (DstInputData%c_obj%toSC_Len > 0) & - DstInputData%c_obj%toSC = C_LOC( DstInputData%toSC(i1_l) ) + DstInputData%c_obj%toSC = C_LOC( DstInputData%toSC( i1_l ) ) END IF DstInputData%toSC = SrcInputData%toSC ENDIF END SUBROUTINE SC_DX_CopyInput - SUBROUTINE SC_DX_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE SC_DX_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_DX_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DX_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DX_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(InputData%toSC)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%toSC) InputData%toSC => NULL() InputData%C_obj%toSC = C_NULL_PTR @@ -867,7 +917,7 @@ SUBROUTINE SC_DX_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrM END IF OutData%c_obj%toSC_Len = SIZE(OutData%toSC) IF (OutData%c_obj%toSC_Len > 0) & - OutData%c_obj%toSC = C_LOC( OutData%toSC(i1_l) ) + OutData%c_obj%toSC = C_LOC( OutData%toSC( i1_l ) ) DO i1 = LBOUND(OutData%toSC,1), UBOUND(OutData%toSC,1) OutData%toSC(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -925,7 +975,7 @@ SUBROUTINE SC_DX_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%toSC_Len = SIZE(InputData%toSC) IF (InputData%c_obj%toSC_Len > 0) & - InputData%c_obj%toSC = C_LOC( InputData%toSC( LBOUND(InputData%toSC,1) ) ) + InputData%c_obj%toSC = C_LOC( InputData%toSC( LBOUND(InputData%toSC,1) ) ) END IF END IF END SUBROUTINE SC_DX_F2C_CopyInput @@ -956,7 +1006,7 @@ SUBROUTINE SC_DX_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Er END IF DstOutputData%c_obj%fromSC_Len = SIZE(DstOutputData%fromSC) IF (DstOutputData%c_obj%fromSC_Len > 0) & - DstOutputData%c_obj%fromSC = C_LOC( DstOutputData%fromSC(i1_l) ) + DstOutputData%c_obj%fromSC = C_LOC( DstOutputData%fromSC( i1_l ) ) END IF DstOutputData%fromSC = SrcOutputData%fromSC ENDIF @@ -971,28 +1021,42 @@ SUBROUTINE SC_DX_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, Er END IF DstOutputData%c_obj%fromSCglob_Len = SIZE(DstOutputData%fromSCglob) IF (DstOutputData%c_obj%fromSCglob_Len > 0) & - DstOutputData%c_obj%fromSCglob = C_LOC( DstOutputData%fromSCglob(i1_l) ) + DstOutputData%c_obj%fromSCglob = C_LOC( DstOutputData%fromSCglob( i1_l ) ) END IF DstOutputData%fromSCglob = SrcOutputData%fromSCglob ENDIF END SUBROUTINE SC_DX_CopyOutput - SUBROUTINE SC_DX_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE SC_DX_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_DX_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DX_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DX_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(OutputData%fromSC)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OutputData%fromSC) OutputData%fromSC => NULL() OutputData%C_obj%fromSC = C_NULL_PTR OutputData%C_obj%fromSC_Len = 0 ENDIF IF (ASSOCIATED(OutputData%fromSCglob)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OutputData%fromSCglob) OutputData%fromSCglob => NULL() OutputData%C_obj%fromSCglob = C_NULL_PTR @@ -1148,7 +1212,7 @@ SUBROUTINE SC_DX_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END IF OutData%c_obj%fromSC_Len = SIZE(OutData%fromSC) IF (OutData%c_obj%fromSC_Len > 0) & - OutData%c_obj%fromSC = C_LOC( OutData%fromSC(i1_l) ) + OutData%c_obj%fromSC = C_LOC( OutData%fromSC( i1_l ) ) DO i1 = LBOUND(OutData%fromSC,1), UBOUND(OutData%fromSC,1) OutData%fromSC(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -1169,7 +1233,7 @@ SUBROUTINE SC_DX_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END IF OutData%c_obj%fromSCglob_Len = SIZE(OutData%fromSCglob) IF (OutData%c_obj%fromSCglob_Len > 0) & - OutData%c_obj%fromSCglob = C_LOC( OutData%fromSCglob(i1_l) ) + OutData%c_obj%fromSCglob = C_LOC( OutData%fromSCglob( i1_l ) ) DO i1 = LBOUND(OutData%fromSCglob,1), UBOUND(OutData%fromSCglob,1) OutData%fromSCglob(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -1236,7 +1300,7 @@ SUBROUTINE SC_DX_F2C_CopyOutput( OutputData, ErrStat, ErrMsg, SkipPointers ) ELSE OutputData%c_obj%fromSC_Len = SIZE(OutputData%fromSC) IF (OutputData%c_obj%fromSC_Len > 0) & - OutputData%c_obj%fromSC = C_LOC( OutputData%fromSC( LBOUND(OutputData%fromSC,1) ) ) + OutputData%c_obj%fromSC = C_LOC( OutputData%fromSC( LBOUND(OutputData%fromSC,1) ) ) END IF END IF @@ -1248,7 +1312,7 @@ SUBROUTINE SC_DX_F2C_CopyOutput( OutputData, ErrStat, ErrMsg, SkipPointers ) ELSE OutputData%c_obj%fromSCglob_Len = SIZE(OutputData%fromSCglob) IF (OutputData%c_obj%fromSCglob_Len > 0) & - OutputData%c_obj%fromSCglob = C_LOC( OutputData%fromSCglob( LBOUND(OutputData%fromSCglob,1) ) ) + OutputData%c_obj%fromSCglob = C_LOC( OutputData%fromSCglob( LBOUND(OutputData%fromSCglob,1) ) ) END IF END IF END SUBROUTINE SC_DX_F2C_CopyOutput diff --git a/modules/supercontroller/src/SC_DLL.F90 b/modules/supercontroller/src/SC_DLL.F90 index 7d138a376..c99b69c58 100644 --- a/modules/supercontroller/src/SC_DLL.F90 +++ b/modules/supercontroller/src/SC_DLL.F90 @@ -1,43 +1,29 @@ -!subroutine sc_init_obfuscator() -! -! CALL RANDOM_SEED ( SIZE = 1 ) -! CALL RANDOM_SEED ( PUT=3459872 ) -! -!end subroutine sc_init_obfuscator - - - + !======================================================================= -!SUBROUTINE sc_init ( ) BIND (C, NAME='sc_init') -!subroutine sc_init ( nTurbines, nInpGlobal, NumCtrl2SC, NumParamGlobal, ParamGlobal, NumParamTurbine, & -! ParamTurbine, NumStatesGlobal, NumStatesTurbine, NumSC2CtrlGlob, & -! NumSC2Ctrl, errStat, errMsg ) bind (C, NAME='sc_init') subroutine sc_init ( nTurbines, nInpGlobal, NumCtrl2SC, NumParamGlobal, NumParamTurbine, & - NumStatesGlobal, NumStatesTurbine, NumSC2CtrlGlob, & - NumSC2Ctrl, errStat, errMsg ) bind (C, NAME='sc_init') -!subroutine sc_init ( t, nTurbines, nInpGlobal, to_SCglob, NumCtrl2SC, to_SC, & -! nStatesGlobal, StatesGlob, nStatesTurbine, StatesTurbine, NumSC2CtrlGlob, from_SCglob, & -! NumSC2Ctrl, from_SC, errStat, errMsg ) bind (C, NAME='sc_calcOutputs') - + NumStatesGlobal, NumStatesTurbine, NumSC2CtrlGlob, & + NumSC2Ctrl, errStat, errMsg ) bind (C, NAME='sc_init') ! This DLL super controller is used to implement a ... ! Modified by B. Jonkman to conform to ISO C Bindings (standard Fortran 2003) and ! compile with either gfortran or Intel Visual Fortran (IVF) ! DO NOT REMOVE or MODIFY LINES starting with "!DEC$" or "!GCC$" - ! !DEC$ specifies attributes for IVF and !GCC$ specifies attributes for gfortran + ! !DEC$ specifies attributes for Intel Fortran and !GCC$ specifies attributes for GNU Fortran ! ! Note that gfortran v5.x on Mac produces compiler errors with the DLLEXPORT attribute, ! so I've added the compiler directive IMPLICIT_DLLEXPORT. use, intrinsic :: ISO_C_Binding - implicit none + implicit none + #ifndef IMPLICIT_DLLEXPORT !DEC$ ATTRIBUTES DLLEXPORT :: sc_init !GCC$ ATTRIBUTES DLLEXPORT :: sc_init #endif + integer(C_INT), intent(in ) :: nTurbines !< number of turbines connected to this supercontroller integer(C_INT), intent( out) :: nInpGlobal !< number of global inputs to supercontroller integer(C_INT), intent( out) :: NumCtrl2SC !< number of turbine controller outputs [inputs to supercontroller] @@ -62,22 +48,25 @@ subroutine sc_init ( nTurbines, nInpGlobal, NumCtrl2SC, NumParamGlobal, NumPara NumStatesTurbine = 2 NumSC2CtrlGlob = 2 NumSC2Ctrl = 3 - - + return - end subroutine sc_init +end subroutine sc_init + subroutine sc_getInitData(nTurbines, NumParamGlobal, NumParamTurbine, ParamGlobal, ParamTurbine, & NumSC2CtrlGlob, from_SCglob, NumSC2Ctrl, from_SC,& & nStatesGlobal, StatesGlob, nStatesTurbine, StatesTurbine,& & errStat, errMsg ) bind (C, NAME='sc_getInitData') -use, intrinsic :: ISO_C_Binding - implicit none + use, intrinsic :: ISO_C_Binding + + implicit none + #ifndef IMPLICIT_DLLEXPORT !DEC$ ATTRIBUTES DLLEXPORT :: sc_getInitData !GCC$ ATTRIBUTES DLLEXPORT :: sc_getInitData #endif + integer(C_INT), intent(in ) :: nTurbines !< number of turbines connected to this supercontroller integer(C_INT), intent(in ) :: NumParamGlobal !< number of global parameters integer(C_INT), intent(in ) :: NumParamTurbine !< number of parameters per turbine @@ -127,14 +116,14 @@ subroutine sc_getInitData(nTurbines, NumParamGlobal, NumParamTurbine, ParamGloba from_SC((j-1)*NumSC2Ctrl+i) = real((j-1)*NumSC2Ctrl+i,C_FLOAT) end do end do - - end subroutine sc_getInitData + +end subroutine sc_getInitData + !======================================================================= -!SUBROUTINE sc_calcOutputs ( ) BIND (C, NAME='sc_calcOutputs') -subroutine sc_calcOutputs ( t, nTurbines, nParamGlobal, paramGlobal, nParamTurbine, paramTurbine, nInpGlobal, to_SCglob, NumCtrl2SC, to_SC, & - nStatesGlobal, StatesGlob, nStatesTurbine, StatesTurbine, NumSC2CtrlGlob, from_SCglob, & - NumSC2Ctrl, from_SC, errStat, errMsg ) bind (C, NAME='sc_calcOutputs') - +subroutine sc_calcOutputs ( t, nTurbines, nParamGlobal, paramGlobal, nParamTurbine, paramTurbine, & + nInpGlobal, to_SCglob, NumCtrl2SC, to_SC, & + nStatesGlobal, StatesGlob, nStatesTurbine, StatesTurbine, NumSC2CtrlGlob, from_SCglob, & + NumSC2Ctrl, from_SC, errStat, errMsg ) bind (C, NAME='sc_calcOutputs') ! This DLL super controller is used to implement a ... @@ -148,7 +137,8 @@ subroutine sc_calcOutputs ( t, nTurbines, nParamGlobal, paramGlobal, nParamTurbi use, intrinsic :: ISO_C_Binding - implicit none + implicit none + #ifndef IMPLICIT_DLLEXPORT !DEC$ ATTRIBUTES DLLEXPORT :: sc_calcOutputs !GCC$ ATTRIBUTES DLLEXPORT :: sc_calcOutputs @@ -204,10 +194,10 @@ subroutine sc_calcOutputs ( t, nTurbines, nParamGlobal, paramGlobal, nParamTurbi end subroutine sc_calcOutputs !======================================================================= -!SUBROUTINE sc_updateStates ( ) BIND (C, NAME='sc_updateStates') -subroutine sc_updateStates ( t, nTurbines, nParamGlobal, paramGlobal, nParamTurbine, paramTurbine, nInpGlobal, to_SCglob, NumCtrl2SC, to_SC, & - nStatesGlobal, StatesGlob, nStatesTurbine, StatesTurbine, errStat, errMsg ) bind (C, NAME='sc_updateStates') - +subroutine sc_updateStates ( t, nTurbines, nParamGlobal, paramGlobal, nParamTurbine, paramTurbine, & + nInpGlobal, to_SCglob, NumCtrl2SC, to_SC, & + nStatesGlobal, StatesGlob, nStatesTurbine, StatesTurbine, & + errStat, errMsg ) bind (C, NAME='sc_updateStates') ! This DLL super controller is used to implement a ... @@ -221,7 +211,8 @@ subroutine sc_updateStates ( t, nTurbines, nParamGlobal, paramGlobal, nParamTurb use, intrinsic :: ISO_C_Binding - implicit none + implicit none + #ifndef IMPLICIT_DLLEXPORT !DEC$ ATTRIBUTES DLLEXPORT :: sc_updateStates !GCC$ ATTRIBUTES DLLEXPORT :: sc_updateStates @@ -289,7 +280,6 @@ subroutine sc_updateStates ( t, nTurbines, nParamGlobal, paramGlobal, nParamTurb end subroutine sc_updateStates subroutine sc_end ( errStat, errMsg ) bind (C, NAME='sc_end') - ! This DLL super controller is used to implement a ... @@ -303,7 +293,8 @@ subroutine sc_end ( errStat, errMsg ) bind (C, NAME='sc_end') use, intrinsic :: ISO_C_Binding - implicit none + implicit none + #ifndef IMPLICIT_DLLEXPORT !DEC$ ATTRIBUTES DLLEXPORT :: sc_end !GCC$ ATTRIBUTES DLLEXPORT :: sc_end @@ -311,13 +302,6 @@ subroutine sc_end ( errStat, errMsg ) bind (C, NAME='sc_end') integer(C_INT), intent(inout) :: errStat !< error status code (uses NWTC_Library error codes) character(kind=C_CHAR), intent(inout) :: errMsg (*) !< Error Message from DLL to simulation code - - return end subroutine sc_end - - - - - diff --git a/modules/supercontroller/src/SuperController_Types.f90 b/modules/supercontroller/src/SuperController_Types.f90 index 06db9d3cd..10ae1505c 100644 --- a/modules/supercontroller/src/SuperController_Types.f90 +++ b/modules/supercontroller/src/SuperController_Types.f90 @@ -202,15 +202,27 @@ SUBROUTINE SC_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrSt DstInitInputData%C_obj%DLL_FileName = SrcInitInputData%C_obj%DLL_FileName END SUBROUTINE SC_CopyInitInput - SUBROUTINE SC_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE SC_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SC_DestroyInitInput SUBROUTINE SC_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -389,16 +401,29 @@ SUBROUTINE SC_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, Er DstInitOutputData%C_obj%NumSC2CtrlGlob = SrcInitOutputData%C_obj%NumSC2CtrlGlob END SUBROUTINE SC_CopyInitOutput - SUBROUTINE SC_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE SC_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE SC_DestroyInitOutput SUBROUTINE SC_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -693,7 +718,7 @@ SUBROUTINE SC_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%c_obj%ParamGlobal_Len = SIZE(DstParamData%ParamGlobal) IF (DstParamData%c_obj%ParamGlobal_Len > 0) & - DstParamData%c_obj%ParamGlobal = C_LOC( DstParamData%ParamGlobal(i1_l) ) + DstParamData%c_obj%ParamGlobal = C_LOC( DstParamData%ParamGlobal( i1_l ) ) END IF DstParamData%ParamGlobal = SrcParamData%ParamGlobal ENDIF @@ -708,35 +733,50 @@ SUBROUTINE SC_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%c_obj%ParamTurbine_Len = SIZE(DstParamData%ParamTurbine) IF (DstParamData%c_obj%ParamTurbine_Len > 0) & - DstParamData%c_obj%ParamTurbine = C_LOC( DstParamData%ParamTurbine(i1_l) ) + DstParamData%c_obj%ParamTurbine = C_LOC( DstParamData%ParamTurbine( i1_l ) ) END IF DstParamData%ParamTurbine = SrcParamData%ParamTurbine ENDIF DstParamData%DLL_Trgt = SrcParamData%DLL_Trgt END SUBROUTINE SC_CopyParam - SUBROUTINE SC_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE SC_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(ParamData%ParamGlobal)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(ParamData%ParamGlobal) ParamData%ParamGlobal => NULL() ParamData%C_obj%ParamGlobal = C_NULL_PTR ParamData%C_obj%ParamGlobal_Len = 0 ENDIF IF (ASSOCIATED(ParamData%ParamTurbine)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(ParamData%ParamTurbine) ParamData%ParamTurbine => NULL() ParamData%C_obj%ParamTurbine = C_NULL_PTR ParamData%C_obj%ParamTurbine_Len = 0 ENDIF - CALL FreeDynamicLib( ParamData%DLL_Trgt, ErrStat, ErrMsg ) + CALL FreeDynamicLib( ParamData%DLL_Trgt, ErrStat2, ErrMsg2 ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE SC_DestroyParam SUBROUTINE SC_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -993,7 +1033,7 @@ SUBROUTINE SC_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END IF OutData%c_obj%ParamGlobal_Len = SIZE(OutData%ParamGlobal) IF (OutData%c_obj%ParamGlobal_Len > 0) & - OutData%c_obj%ParamGlobal = C_LOC( OutData%ParamGlobal(i1_l) ) + OutData%c_obj%ParamGlobal = C_LOC( OutData%ParamGlobal( i1_l ) ) DO i1 = LBOUND(OutData%ParamGlobal,1), UBOUND(OutData%ParamGlobal,1) OutData%ParamGlobal(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -1014,7 +1054,7 @@ SUBROUTINE SC_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END IF OutData%c_obj%ParamTurbine_Len = SIZE(OutData%ParamTurbine) IF (OutData%c_obj%ParamTurbine_Len > 0) & - OutData%c_obj%ParamTurbine = C_LOC( OutData%ParamTurbine(i1_l) ) + OutData%c_obj%ParamTurbine = C_LOC( OutData%ParamTurbine( i1_l ) ) DO i1 = LBOUND(OutData%ParamTurbine,1), UBOUND(OutData%ParamTurbine,1) OutData%ParamTurbine(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -1141,7 +1181,7 @@ SUBROUTINE SC_F2C_CopyParam( ParamData, ErrStat, ErrMsg, SkipPointers ) ELSE ParamData%c_obj%ParamGlobal_Len = SIZE(ParamData%ParamGlobal) IF (ParamData%c_obj%ParamGlobal_Len > 0) & - ParamData%c_obj%ParamGlobal = C_LOC( ParamData%ParamGlobal( LBOUND(ParamData%ParamGlobal,1) ) ) + ParamData%c_obj%ParamGlobal = C_LOC( ParamData%ParamGlobal( LBOUND(ParamData%ParamGlobal,1) ) ) END IF END IF @@ -1153,7 +1193,7 @@ SUBROUTINE SC_F2C_CopyParam( ParamData, ErrStat, ErrMsg, SkipPointers ) ELSE ParamData%c_obj%ParamTurbine_Len = SIZE(ParamData%ParamTurbine) IF (ParamData%c_obj%ParamTurbine_Len > 0) & - ParamData%c_obj%ParamTurbine = C_LOC( ParamData%ParamTurbine( LBOUND(ParamData%ParamTurbine,1) ) ) + ParamData%c_obj%ParamTurbine = C_LOC( ParamData%ParamTurbine( LBOUND(ParamData%ParamTurbine,1) ) ) END IF END IF END SUBROUTINE SC_F2C_CopyParam @@ -1184,7 +1224,7 @@ SUBROUTINE SC_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt END IF DstDiscStateData%c_obj%Global_Len = SIZE(DstDiscStateData%Global) IF (DstDiscStateData%c_obj%Global_Len > 0) & - DstDiscStateData%c_obj%Global = C_LOC( DstDiscStateData%Global(i1_l) ) + DstDiscStateData%c_obj%Global = C_LOC( DstDiscStateData%Global( i1_l ) ) END IF DstDiscStateData%Global = SrcDiscStateData%Global ENDIF @@ -1199,28 +1239,42 @@ SUBROUTINE SC_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt END IF DstDiscStateData%c_obj%Turbine_Len = SIZE(DstDiscStateData%Turbine) IF (DstDiscStateData%c_obj%Turbine_Len > 0) & - DstDiscStateData%c_obj%Turbine = C_LOC( DstDiscStateData%Turbine(i1_l) ) + DstDiscStateData%c_obj%Turbine = C_LOC( DstDiscStateData%Turbine( i1_l ) ) END IF DstDiscStateData%Turbine = SrcDiscStateData%Turbine ENDIF END SUBROUTINE SC_CopyDiscState - SUBROUTINE SC_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE SC_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(DiscStateData%Global)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(DiscStateData%Global) DiscStateData%Global => NULL() DiscStateData%C_obj%Global = C_NULL_PTR DiscStateData%C_obj%Global_Len = 0 ENDIF IF (ASSOCIATED(DiscStateData%Turbine)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(DiscStateData%Turbine) DiscStateData%Turbine => NULL() DiscStateData%C_obj%Turbine = C_NULL_PTR @@ -1376,7 +1430,7 @@ SUBROUTINE SC_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END IF OutData%c_obj%Global_Len = SIZE(OutData%Global) IF (OutData%c_obj%Global_Len > 0) & - OutData%c_obj%Global = C_LOC( OutData%Global(i1_l) ) + OutData%c_obj%Global = C_LOC( OutData%Global( i1_l ) ) DO i1 = LBOUND(OutData%Global,1), UBOUND(OutData%Global,1) OutData%Global(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -1397,7 +1451,7 @@ SUBROUTINE SC_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END IF OutData%c_obj%Turbine_Len = SIZE(OutData%Turbine) IF (OutData%c_obj%Turbine_Len > 0) & - OutData%c_obj%Turbine = C_LOC( OutData%Turbine(i1_l) ) + OutData%c_obj%Turbine = C_LOC( OutData%Turbine( i1_l ) ) DO i1 = LBOUND(OutData%Turbine,1), UBOUND(OutData%Turbine,1) OutData%Turbine(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -1464,7 +1518,7 @@ SUBROUTINE SC_F2C_CopyDiscState( DiscStateData, ErrStat, ErrMsg, SkipPointers ) ELSE DiscStateData%c_obj%Global_Len = SIZE(DiscStateData%Global) IF (DiscStateData%c_obj%Global_Len > 0) & - DiscStateData%c_obj%Global = C_LOC( DiscStateData%Global( LBOUND(DiscStateData%Global,1) ) ) + DiscStateData%c_obj%Global = C_LOC( DiscStateData%Global( LBOUND(DiscStateData%Global,1) ) ) END IF END IF @@ -1476,7 +1530,7 @@ SUBROUTINE SC_F2C_CopyDiscState( DiscStateData, ErrStat, ErrMsg, SkipPointers ) ELSE DiscStateData%c_obj%Turbine_Len = SIZE(DiscStateData%Turbine) IF (DiscStateData%c_obj%Turbine_Len > 0) & - DiscStateData%c_obj%Turbine = C_LOC( DiscStateData%Turbine( LBOUND(DiscStateData%Turbine,1) ) ) + DiscStateData%c_obj%Turbine = C_LOC( DiscStateData%Turbine( LBOUND(DiscStateData%Turbine,1) ) ) END IF END IF END SUBROUTINE SC_F2C_CopyDiscState @@ -1499,15 +1553,27 @@ SUBROUTINE SC_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrSt DstContStateData%C_obj%Dummy = SrcContStateData%C_obj%Dummy END SUBROUTINE SC_CopyContState - SUBROUTINE SC_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE SC_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SC_DestroyContState SUBROUTINE SC_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1664,15 +1730,27 @@ SUBROUTINE SC_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, DstConstrStateData%C_obj%Dummy = SrcConstrStateData%C_obj%Dummy END SUBROUTINE SC_CopyConstrState - SUBROUTINE SC_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE SC_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SC_DestroyConstrState SUBROUTINE SC_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1829,15 +1907,27 @@ SUBROUTINE SC_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) DstMiscData%C_obj%Dummy = SrcMiscData%C_obj%Dummy END SUBROUTINE SC_CopyMisc - SUBROUTINE SC_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE SC_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SC_DestroyMisc SUBROUTINE SC_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1994,15 +2084,27 @@ SUBROUTINE SC_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, Er DstOtherStateData%C_obj%Dummy = SrcOtherStateData%C_obj%Dummy END SUBROUTINE SC_CopyOtherState - SUBROUTINE SC_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE SC_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE SC_DestroyOtherState SUBROUTINE SC_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2167,7 +2269,7 @@ SUBROUTINE SC_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) END IF DstInputData%c_obj%toSCglob_Len = SIZE(DstInputData%toSCglob) IF (DstInputData%c_obj%toSCglob_Len > 0) & - DstInputData%c_obj%toSCglob = C_LOC( DstInputData%toSCglob(i1_l) ) + DstInputData%c_obj%toSCglob = C_LOC( DstInputData%toSCglob( i1_l ) ) END IF DstInputData%toSCglob = SrcInputData%toSCglob ENDIF @@ -2182,28 +2284,42 @@ SUBROUTINE SC_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) END IF DstInputData%c_obj%toSC_Len = SIZE(DstInputData%toSC) IF (DstInputData%c_obj%toSC_Len > 0) & - DstInputData%c_obj%toSC = C_LOC( DstInputData%toSC(i1_l) ) + DstInputData%c_obj%toSC = C_LOC( DstInputData%toSC( i1_l ) ) END IF DstInputData%toSC = SrcInputData%toSC ENDIF END SUBROUTINE SC_CopyInput - SUBROUTINE SC_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE SC_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(InputData%toSCglob)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%toSCglob) InputData%toSCglob => NULL() InputData%C_obj%toSCglob = C_NULL_PTR InputData%C_obj%toSCglob_Len = 0 ENDIF IF (ASSOCIATED(InputData%toSC)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(InputData%toSC) InputData%toSC => NULL() InputData%C_obj%toSC = C_NULL_PTR @@ -2359,7 +2475,7 @@ SUBROUTINE SC_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END IF OutData%c_obj%toSCglob_Len = SIZE(OutData%toSCglob) IF (OutData%c_obj%toSCglob_Len > 0) & - OutData%c_obj%toSCglob = C_LOC( OutData%toSCglob(i1_l) ) + OutData%c_obj%toSCglob = C_LOC( OutData%toSCglob( i1_l ) ) DO i1 = LBOUND(OutData%toSCglob,1), UBOUND(OutData%toSCglob,1) OutData%toSCglob(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -2380,7 +2496,7 @@ SUBROUTINE SC_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END IF OutData%c_obj%toSC_Len = SIZE(OutData%toSC) IF (OutData%c_obj%toSC_Len > 0) & - OutData%c_obj%toSC = C_LOC( OutData%toSC(i1_l) ) + OutData%c_obj%toSC = C_LOC( OutData%toSC( i1_l ) ) DO i1 = LBOUND(OutData%toSC,1), UBOUND(OutData%toSC,1) OutData%toSC(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -2447,7 +2563,7 @@ SUBROUTINE SC_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%toSCglob_Len = SIZE(InputData%toSCglob) IF (InputData%c_obj%toSCglob_Len > 0) & - InputData%c_obj%toSCglob = C_LOC( InputData%toSCglob( LBOUND(InputData%toSCglob,1) ) ) + InputData%c_obj%toSCglob = C_LOC( InputData%toSCglob( LBOUND(InputData%toSCglob,1) ) ) END IF END IF @@ -2459,7 +2575,7 @@ SUBROUTINE SC_F2C_CopyInput( InputData, ErrStat, ErrMsg, SkipPointers ) ELSE InputData%c_obj%toSC_Len = SIZE(InputData%toSC) IF (InputData%c_obj%toSC_Len > 0) & - InputData%c_obj%toSC = C_LOC( InputData%toSC( LBOUND(InputData%toSC,1) ) ) + InputData%c_obj%toSC = C_LOC( InputData%toSC( LBOUND(InputData%toSC,1) ) ) END IF END IF END SUBROUTINE SC_F2C_CopyInput @@ -2490,7 +2606,7 @@ SUBROUTINE SC_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs END IF DstOutputData%c_obj%fromSCglob_Len = SIZE(DstOutputData%fromSCglob) IF (DstOutputData%c_obj%fromSCglob_Len > 0) & - DstOutputData%c_obj%fromSCglob = C_LOC( DstOutputData%fromSCglob(i1_l) ) + DstOutputData%c_obj%fromSCglob = C_LOC( DstOutputData%fromSCglob( i1_l ) ) END IF DstOutputData%fromSCglob = SrcOutputData%fromSCglob ENDIF @@ -2505,28 +2621,42 @@ SUBROUTINE SC_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs END IF DstOutputData%c_obj%fromSC_Len = SIZE(DstOutputData%fromSC) IF (DstOutputData%c_obj%fromSC_Len > 0) & - DstOutputData%c_obj%fromSC = C_LOC( DstOutputData%fromSC(i1_l) ) + DstOutputData%c_obj%fromSC = C_LOC( DstOutputData%fromSC( i1_l ) ) END IF DstOutputData%fromSC = SrcOutputData%fromSC ENDIF END SUBROUTINE SC_CopyOutput - SUBROUTINE SC_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE SC_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(SC_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'SC_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ASSOCIATED(OutputData%fromSCglob)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OutputData%fromSCglob) OutputData%fromSCglob => NULL() OutputData%C_obj%fromSCglob = C_NULL_PTR OutputData%C_obj%fromSCglob_Len = 0 ENDIF IF (ASSOCIATED(OutputData%fromSC)) THEN + IF (DEALLOCATEpointers_local) & DEALLOCATE(OutputData%fromSC) OutputData%fromSC => NULL() OutputData%C_obj%fromSC = C_NULL_PTR @@ -2682,7 +2812,7 @@ SUBROUTINE SC_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END IF OutData%c_obj%fromSCglob_Len = SIZE(OutData%fromSCglob) IF (OutData%c_obj%fromSCglob_Len > 0) & - OutData%c_obj%fromSCglob = C_LOC( OutData%fromSCglob(i1_l) ) + OutData%c_obj%fromSCglob = C_LOC( OutData%fromSCglob( i1_l ) ) DO i1 = LBOUND(OutData%fromSCglob,1), UBOUND(OutData%fromSCglob,1) OutData%fromSCglob(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -2703,7 +2833,7 @@ SUBROUTINE SC_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END IF OutData%c_obj%fromSC_Len = SIZE(OutData%fromSC) IF (OutData%c_obj%fromSC_Len > 0) & - OutData%c_obj%fromSC = C_LOC( OutData%fromSC(i1_l) ) + OutData%c_obj%fromSC = C_LOC( OutData%fromSC( i1_l ) ) DO i1 = LBOUND(OutData%fromSC,1), UBOUND(OutData%fromSC,1) OutData%fromSC(i1) = REAL(ReKiBuf(Re_Xferred), C_FLOAT) Re_Xferred = Re_Xferred + 1 @@ -2770,7 +2900,7 @@ SUBROUTINE SC_F2C_CopyOutput( OutputData, ErrStat, ErrMsg, SkipPointers ) ELSE OutputData%c_obj%fromSCglob_Len = SIZE(OutputData%fromSCglob) IF (OutputData%c_obj%fromSCglob_Len > 0) & - OutputData%c_obj%fromSCglob = C_LOC( OutputData%fromSCglob( LBOUND(OutputData%fromSCglob,1) ) ) + OutputData%c_obj%fromSCglob = C_LOC( OutputData%fromSCglob( LBOUND(OutputData%fromSCglob,1) ) ) END IF END IF @@ -2782,7 +2912,7 @@ SUBROUTINE SC_F2C_CopyOutput( OutputData, ErrStat, ErrMsg, SkipPointers ) ELSE OutputData%c_obj%fromSC_Len = SIZE(OutputData%fromSC) IF (OutputData%c_obj%fromSC_Len > 0) & - OutputData%c_obj%fromSC = C_LOC( OutputData%fromSC( LBOUND(OutputData%fromSC,1) ) ) + OutputData%c_obj%fromSC = C_LOC( OutputData%fromSC( LBOUND(OutputData%fromSC,1) ) ) END IF END IF END SUBROUTINE SC_F2C_CopyOutput diff --git a/modules/turbsim/CMakeLists.txt b/modules/turbsim/CMakeLists.txt index 38a1cdb0b..eb538cb0c 100644 --- a/modules/turbsim/CMakeLists.txt +++ b/modules/turbsim/CMakeLists.txt @@ -14,7 +14,7 @@ # limitations under the License. # -set(MODULE_SOURCES +add_executable(turbsim src/BlankModVKM.f90 src/CohStructures.f90 src/Profiles.f90 @@ -25,9 +25,9 @@ set(MODULE_SOURCES src/TurbSim.f90 src/TurbSim_Types.f90 src/VelocitySpectra.f90 - ) +) +target_link_libraries(turbsim versioninfolib nwtclibs) -add_executable(turbsim ${MODULE_SOURCES}) -target_link_libraries(turbsim nwtclibs versioninfolib) - -install(TARGETS turbsim RUNTIME DESTINATION bin) +install(TARGETS turbsim + RUNTIME DESTINATION bin +) diff --git a/modules/turbsim/src/TS_FileIO.f90 b/modules/turbsim/src/TS_FileIO.f90 index 1264f591b..70b5f91a7 100644 --- a/modules/turbsim/src/TS_FileIO.f90 +++ b/modules/turbsim/src/TS_FileIO.f90 @@ -2627,7 +2627,7 @@ SUBROUTINE WrFormattedFF(RootName, p_grid, UHub, V ) WRITE (UFFF,"(I14,I6,F11.3,F11.3,F15.3,F11.2,F10.2)") p_grid%NumGrid_Y, p_grid%NumGrid_Z, p_grid%GridRes_Y, p_grid%GridRes_Z, p_grid%TimeStep, p_grid%HubHt, UHub WRITE (UFFF,"(/,' Z Coordinates (m):')") - WRITE (UFFF,FormStr5) ( p_grid%Z(p_grid%GridPtIndx(IZ))-p_grid%HubHt, IZ=1,p_grid%NPoints,p_grid%NumGrid_Y ) + WRITE (UFFF,FormStr5) ( p_grid%Z(p_grid%GridPtIndx(IZ))-p_grid%HubHt, IZ=1,p_grid%NumGrid_Y*p_grid%NumGrid_Z,p_grid%NumGrid_Y ) WRITE (UFFF,"(/,' Y Coordinates (m):')") WRITE (UFFF,FormStr5) ( p_grid%Y(p_grid%GridPtIndx(IY)), IY=1,p_grid%NumGrid_Y ) diff --git a/modules/turbsim/src/TSsubs.f90 b/modules/turbsim/src/TSsubs.f90 index 27c82ea63..173fd53f6 100644 --- a/modules/turbsim/src/TSsubs.f90 +++ b/modules/turbsim/src/TSsubs.f90 @@ -1284,15 +1284,14 @@ SUBROUTINE CreateGrid( p_grid, p_usr, UHub, AddTower, ErrStat, ErrMsg ) ! Calculate Total time and NumSteps. ! Find the product of small factors that is larger than NumSteps (prime #9 = 23). -!bjj: I have no idea why it is necessary to be a factor of 4, so I'm removing it for now: ! Make sure it is a multiple of 2 too. + ! If we are starting from user-defined points, we can subtract values to try to get it to match the values entered there. IF ( p_grid%Periodic ) THEN p_grid%NumSteps = CEILING( p_grid%AnalysisTime / p_grid%TimeStep ) ! make sure NumSteps is an even number and a product of small primes NumSteps2 = ( p_grid%NumSteps - 1 )/2 + 1 - p_grid%NumSteps = 2*PSF( NumSteps2 , 9 ) ! >= 2*NumSteps2 = NumSteps + 1 - MOD(NumSteps-1,2) >= NumSteps - !p_grid%NumSteps = PSF( p_grid%NumSteps , 9 ) + p_grid%NumSteps = 2*PSF( NumSteps2 , 9, subtract=p_usr%NPoints > 0) ! >= 2*NumSteps2 = NumSteps + 1 - MOD(NumSteps-1,2) >= NumSteps p_grid%NumOutSteps = p_grid%NumSteps ELSE @@ -1300,17 +1299,10 @@ SUBROUTINE CreateGrid( p_grid, p_usr, UHub, AddTower, ErrStat, ErrMsg ) p_grid%NumSteps = MAX( CEILING( p_grid%AnalysisTime / p_grid%TimeStep ), p_grid%NumOutSteps ) ! make sure NumSteps is an even number and a product of small primes -! p_grid%NumSteps = PSF( p_grid%NumSteps , 9 ) ! make sure it's a product of small primes NumSteps2 = ( p_grid%NumSteps - 1 )/2 + 1 - p_grid%NumSteps = 2*PSF( NumSteps2 , 9 ) ! >= 2*NumSteps2 = NumOutSteps + 1 - MOD(NumOutSteps-1,2) >= NumOutSteps + p_grid%NumSteps = 2*PSF( NumSteps2 , 9, subtract=p_usr%NPoints > 0 ) ! >= 2*NumSteps2 = NumOutSteps + 1 - MOD(NumOutSteps-1,2) >= NumOutSteps END IF - - !IF (p_grid%NumSteps < 2 ) THEN - ! CALL SetErrStat( ErrID_Fatal, 'There must be at least 2 time steps. '//& - ! 'Increase the usable length of the time series or decrease the time step.', ErrStat, ErrMsg, RoutineName ) - ! RETURN - !END IF p_grid%NumFreq = p_grid%NumSteps / 2 DelF = 1.0_DbKi/( p_grid%NumSteps*p_grid%TimeStep ) @@ -1320,7 +1312,8 @@ SUBROUTINE CreateGrid( p_grid, p_usr, UHub, AddTower, ErrStat, ErrMsg ) ! IF ( .NOT. EqualRealNos( DelF, p_usr%f(1) ) .or. .not. EqualRealNos(p_grid%AnalysisTime,p_usr%f(1)*p_usr%NFreq ) .or. p_grid%NumFreq > size(p_usr%f) ) THEN IF ( .NOT. EqualRealNos( DelF, p_usr%DelF ) ) THEN CALL SetErrStat(ErrID_Fatal, 'Delta frequency in the user-input time series must be the same as the delta frequency in the simulated series. '//& - 'Change AnalysisTime or number of rows entered in user-defined time series file.', ErrStat, ErrMsg,RoutineName) + 'Change AnalysisTime or number of rows entered in user-defined time series file.'//NewLine//'AnalysisTime uses '//trim(num2lstr(p_grid%NumSteps))//& + ' steps; user-input time series uses '//trim(num2lstr(p_usr%nFreq*2))//' steps.', ErrStat, ErrMsg,RoutineName) RETURN END IF @@ -2409,7 +2402,7 @@ SUBROUTINE TimeSeriesToSpectra( p, ErrStat, ErrMsg ) DO iVec=1,p%usr%nComp DO iPoint=1,p%usr%NPoints - work = p%usr%v(:,iPoint,iVec) + work = p%usr%v(1:NumSteps,iPoint,iVec) ! perform forward FFT diff --git a/modules/version/CMakeLists.txt b/modules/version/CMakeLists.txt index 34a7891b3..1af85e5e6 100644 --- a/modules/version/CMakeLists.txt +++ b/modules/version/CMakeLists.txt @@ -30,9 +30,8 @@ add_definitions(-DGIT_VERSION_INFO="${GIT_DESCRIBE}") add_library(versioninfolib src/VersionInfo.f90) target_link_libraries(versioninfolib nwtclibs) - install(TARGETS versioninfolib EXPORT "${CMAKE_PROJECT_NAME}Libraries" RUNTIME DESTINATION bin LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) + ARCHIVE DESTINATION lib) \ No newline at end of file diff --git a/modules/wakedynamics/CMakeLists.txt b/modules/wakedynamics/CMakeLists.txt index a298eec33..bab32ba8d 100644 --- a/modules/wakedynamics/CMakeLists.txt +++ b/modules/wakedynamics/CMakeLists.txt @@ -17,13 +17,11 @@ if (GENERATE_TYPES) generate_f90_types(src/WakeDynamics_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/WakeDynamics_Types.f90 -noextrap) endif() -set(WD_LIBS_SOURCES +add_library(wdlib src/WakeDynamics.f90 #src/WakeDynamics_IO.f90 src/WakeDynamics_Types.f90 - ) - -add_library(wdlib ${WD_LIBS_SOURCES}) +) target_link_libraries(wdlib nwtclibs) install(TARGETS wdlib diff --git a/modules/wakedynamics/src/WakeDynamics.f90 b/modules/wakedynamics/src/WakeDynamics.f90 index 289d9d124..afa31e430 100644 --- a/modules/wakedynamics/src/WakeDynamics.f90 +++ b/modules/wakedynamics/src/WakeDynamics.f90 @@ -25,6 +25,7 @@ module WakeDynamics use NWTC_Library + use VTK use WakeDynamics_Types implicit none @@ -42,7 +43,9 @@ module WakeDynamics ! continuous states, and updating discrete states public :: WD_CalcOutput ! Routine for computing outputs public :: WD_CalcConstrStateResidual ! Tight coupling routine for returning the constraint state residual - + + public :: WD_TEST_Axi2Cart + public :: WD_TEST_AddVelocityCurl contains function WD_Interp ( yVal, xArr, yArr ) @@ -196,16 +199,34 @@ real(ReKi) function WakeDiam( Mod_WakeDiam, nr, dr, rArr, Vx_wake, Vx_wind_disk, end function WakeDiam +real(ReKi) function get_Ctavg(r, Ct, D_rotor) result(Ct_avg) + real(ReKi), intent(in ) :: r(:) ! radial positions + real(ReKi), intent(in ) :: Ct(:) ! Thrust coefficient Ct(r) + real(ReKi), intent(in ) :: D_rotor + real(ReKi) :: dr + integer :: j + ! Computing average Ct = \int r Ct dr / \int r dr = 2/R^2 \int r Ct dr using trapz + ! NOTE: r goes beyond the rotor (works since Ct=0 beyond that) + ! NOTE: the formula can be improved, assumes equispacing of r + Ct_avg = 0.0_ReKi + do j=2,size(r) + dr = r(j) - r(j-1) + Ct_avg = Ct_avg + 0.5_ReKi * (r(j) * Ct(j) + r(j-1) * Ct(j-1)) * dr + enddo + Ct_avg = 8.0_ReKi*Ct_avg/(D_rotor*D_rotor) +end function get_Ctavg !---------------------------------------------------------------------------------------------------------------------------------- !> This subroutine computes the near wake correction : Vx_wake -subroutine NearWakeCorrection( Ct_azavg_filt, Vx_rel_disk_filt, p, m, Vx_wake, D_rotor, errStat, errMsg ) +subroutine NearWakeCorrection( Ct_azavg_filt, Cq_azavg_filt, Vx_rel_disk_filt, p, m, Vx_wake, Vt_wake, D_rotor, errStat, errMsg ) real(ReKi), intent(in ) :: Ct_azavg_filt(0:) !< Time-filtered azimuthally averaged thrust force coefficient (normal to disk), distributed radially + real(ReKi), intent(in ) :: Cq_azavg_filt(0:) !< Time-filtered azimuthally averaged tangential force coefficient (normal to disk), distributed radially real(ReKi), intent(in ) :: D_rotor !< Rotor diameter real(ReKi), intent(in ) :: Vx_rel_disk_filt !< Time-filtered rotor-disk-averaged relative wind speed (ambient + deficits + motion), normal to disk type(WD_ParameterType), intent(in ) :: p !< Parameters type(WD_MiscVarType), intent(inout) :: m !< Initial misc/optimization variables real(ReKi), intent(inout) :: Vx_wake(0:) !< Axial wake velocity deficit at first plane + real(ReKi), intent(inout) :: Vt_wake(0:) !< Tangential wake velocity deficit at first plane integer(IntKi), intent( out) :: errStat !< Error status of the operation character(*), intent( out) :: errMsg !< Error message if errStat /= ErrID_None real(ReKi) :: alpha @@ -219,11 +240,7 @@ subroutine NearWakeCorrection( Ct_azavg_filt, Vx_rel_disk_filt, p, m, Vx_wake, D ! Computing average Ct = \int r Ct dr / \int r dr = 2/R^2 \int r Ct dr using trapz ! NOTE: r goes beyond the rotor (works since Ct=0 beyond that) - Ct_avg = 0.0_ReKi - do j=1,p%NumRadii-1 - Ct_avg = Ct_avg + 0.5_ReKi * (p%r(j) * Ct_azavg_filt(j) + p%r(j-1) * Ct_azavg_filt(j-1)) * p%dr - enddo - Ct_avg = 8.0_ReKi*Ct_avg/(D_rotor*D_rotor) + Ct_avg = get_Ctavg(p%r, Ct_azavg_filt, D_rotor) if (Ct_avg > 2.0_ReKi ) then ! THROW ERROR because we are in the prop-brake region @@ -239,7 +256,7 @@ subroutine NearWakeCorrection( Ct_azavg_filt, Vx_rel_disk_filt, p, m, Vx_wake, D ! high Ct region call Vx_high_Ct(Vx_wake, p%r, Ct_avg) ! Compute Vx_wake at p%r ! m%r_wake = p%r ! No distinction between r_wake and r, r_wake is just a temp variable anyway - + Vt_wake = 0.0_ReKi else ! Blending Ct region between Ct_low and Ct_high call Vx_low_Ct (Vx_wake, p%r) ! Evaluate Vx_wake (Ct_low) at p%r @@ -248,6 +265,7 @@ subroutine NearWakeCorrection( Ct_azavg_filt, Vx_rel_disk_filt, p, m, Vx_wake, D alpha = 1.0_ReKi - (Ct_avg - Ct_low) / (Ct_high-Ct_low) ! linear blending coefficient do j=0,p%NumRadii-1 Vx_wake(j) = alpha*Vx_wake(j)+(1.0_ReKi-alpha)*m%Vx_high(j) ! Blended CT velocity + Vt_wake(j) = alpha*Vt_wake(j) end do end if @@ -259,6 +277,7 @@ subroutine Vx_low_Ct(Vx, r_eval) real(ReKi), dimension(0:), intent(in ) :: r_eval !< Radial position where velocity is to be evaluated integer(IntKi) :: ILo ! index for interpolation real(ReKi) :: a_interp + real(ReKi) :: Cq_interp ! compute r_wake and m%a using Ct_azavg_filt m%r_wake(0) = 0.0_ReKi @@ -271,12 +290,17 @@ subroutine Vx_low_Ct(Vx, r_eval) end do ! Use a and rw to determine Vx Vx(0) = -Vx_rel_disk_filt*p%C_Nearwake*m%a(0) + Vt_wake(0) = 0.0_ReKi ILo = 0 do j=1,p%NumRadii-1 ! given r_wake and m%a at p%dr increments, find value of m%a(r_wake) using interpolation a_interp = InterpBin( r_eval(j), m%r_wake, m%a, ILo, p%NumRadii ) !( XVal, XAry, YAry, ILo, AryLen ) + Cq_interp = InterpBin( r_eval(j), m%r_wake, Cq_azavg_filt, ILo, p%NumRadii ) !( XVal, XAry, YAry, ILo, AryLen ) Vx(j) = -Vx_rel_disk_filt*p%C_NearWake*a_interp !! Low CT velocity + Vt_wake(j) = p%C_NearWake * Cq_interp * Vx_rel_disk_filt / (4._ReKi*(1._ReKi-a_interp)) + end do + end subroutine Vx_low_Ct !> Compute the induced velocity distribution in the wake for high thrust region @@ -376,28 +400,22 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut type(WD_InitOutputType), intent( out) :: InitOut !< Output for initialization routine integer(IntKi), intent( out) :: errStat !< Error status of the operation character(*), intent( out) :: errMsg !< Error message if errStat /= ErrID_None - - ! Local variables integer(IntKi) :: i ! loop counter - + character(1024) :: rootDir + character(1024) :: basename integer(IntKi) :: errStat2 ! temporary error status of the operation character(ErrMsgLen) :: errMsg2 ! temporary error message character(*), parameter :: RoutineName = 'WD_Init' - ! Initialize variables for this routine - errStat = ErrID_None errMsg = "" ! Initialize the NWTC Subroutine Library - call NWTC_Init( EchoLibVer=.FALSE. ) - ! Display the module information - if (InitInp%TurbNum <= 1) call DispNVD( WD_Ver ) ! Validate the initialization inputs @@ -405,14 +423,14 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut call SetErrStat( ErrStat2, ErrMsg2, errStat, errMsg, RoutineName ) if (errStat >= AbortErrLev) return - !............................................................................................ - ! Define parameters - !............................................................................................ - - - - ! set the rest of the parameters - p%DT_low = interval + !............................................................................................ + ! Define parameters + !............................................................................................ + p%TurbNum = InitInp%TurbNum + p%OutFileRoot = InitInp%OutFileRoot + p%DT_low = interval + ! Parameters from input file + p%Mod_Wake = InitInp%InputFileData%Mod_Wake p%NumPlanes = InitInp%InputFileData%NumPlanes p%NumRadii = InitInp%InputFileData%NumRadii p%dr = InitInp%InputFileData%dr @@ -433,16 +451,38 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut p%k_vShr = InitInp%InputFileData%k_vShr p%Mod_WakeDiam = InitInp%InputFileData%Mod_WakeDiam p%C_WakeDiam = InitInp%InputFileData%C_WakeDiam - + ! Curl variables + p%Swirl = InitInp%InputFileData%Swirl + p%k_VortexDecay = InitInp%InputFileData%k_VortexDecay + p%NumVortices = InitInp%InputFileData%NumVortices + p%sigma_D = InitInp%InputFileData%sigma_D + p%FilterInit = InitInp%InputFileData%FilterInit + p%k_vCurl = InitInp%InputFileData%k_vCurl + p%OutAllPlanes = InitInp%InputFileData%OutAllPlanes + ! Wake-Added Turbulence (WAT) variables + p%WAT = InitInp%InputFileData%WAT + p%WAT_k_Def = InitInp%InputFileData%WAT_k_Def + p%WAT_k_Grad = InitInp%InputFileData%WAT_k_Grad + + ! Finite difference grid coordinates r, y, z allocate( p%r(0:p%NumRadii-1),stat=errStat2) - if (errStat2 /= 0) then - call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for p%r.', errStat, errMsg, RoutineName ) - return - end if - + if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for p%r.', errStat, errMsg, RoutineName ) + allocate(p%y(-p%NumRadii+1:p%NumRadii-1), stat=errStat2); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for p%y.', errStat, errMsg, RoutineName ) + allocate(p%z(-p%NumRadii+1:p%NumRadii-1), stat=errStat2); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for p%z.', errStat, errMsg, RoutineName ) + if (errStat /= ErrID_None) return do i = 0,p%NumRadii-1 p%r(i) = p%dr*i end do + do i = -p%NumRadii+1,p%NumRadii-1 + p%y(i) = p%dr*i + p%z(i) = p%dr*i + end do + + ! Path for VTK outputs + call GetPath( p%OutFileRoot, rootDir, baseName ) + p%OutFileVTKDir = trim(rootDir) // 'vtk_ff_planes' + + p%filtParam = exp(-2.0_ReKi*pi*p%dt_low*InitInp%InputFileData%f_c) p%oneMinusFiltParam = 1.0_ReKi - p%filtParam @@ -454,6 +494,8 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%V_plane.', errStat, errMsg, RoutineName ) allocate( u%Ct_azavg ( 0:p%NumRadii-1 ),stat=errStat2) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%Ct_azavg.', errStat, errMsg, RoutineName ) + allocate( u%Cq_azavg ( 0:p%NumRadii-1 ),stat=errStat2) + if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%Cq_azavg.', errStat, errMsg, RoutineName ) if (errStat /= ErrID_None) return @@ -471,6 +513,8 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut ! an firstPass flag on the miscVars and if it is false we will properly initialize these state ! in CalcOutput or UpdateStates, as necessary. !............................................................................................ + x%DummyContState = 0.0_ReKi + z%DummyConstrState = 0.0_ReKi allocate ( xd%xhat_plane (3, 0:p%NumPlanes-1) , STAT=ErrStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%xhat_plane.', errStat, errMsg, RoutineName ) @@ -490,36 +534,69 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%D_rotor_filt.', errStat, errMsg, RoutineName ) allocate ( xd%Ct_azavg_filt (0:p%NumRadii-1) , STAT=ErrStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Ct_azavg_filt.', errStat, errMsg, RoutineName ) - allocate ( xd%Vx_wake (0:p%NumRadii-1,0:p%NumPlanes-1) , STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Vx_wake.', errStat, errMsg, RoutineName ) - allocate ( xd%Vr_wake (0:p%NumRadii-1,0:p%NumPlanes-1) , STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Vr_wake.', errStat, errMsg, RoutineName ) + allocate ( xd%Cq_azavg_filt (0:p%NumRadii-1) , STAT=ErrStat2 ) + if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Cq_azavg_filt.', errStat, errMsg, RoutineName ) + allocate ( xd%Vx_wake (0:p%NumRadii-1,0:p%NumPlanes-1) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Vx_wake.', errStat, errMsg, RoutineName ) + allocate ( xd%Vr_wake (0:p%NumRadii-1,0:p%NumPlanes-1) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Vr_wake.', errStat, errMsg, RoutineName ) + allocate ( xd%Vx_wake2 (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Vx_wake.', errStat, errMsg, RoutineName ) + if (errStat /= ErrID_None) return + + ! Curl + allocate ( xd%Vy_wake2 (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Vy_wake.', errStat, errMsg, RoutineName ) + allocate ( xd%Vz_wake2 (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Vz_wake.', errStat, errMsg, RoutineName ) if (errStat /= ErrID_None) return + xd%YawErr_filt = 0.0_ReKi !NOTE: initialized in InitStatesWithInputs + xd%psi_skew_filt = 0.0_ReKi !NOTE: initialized in InitStatesWithInputs + xd%chi_skew_filt = 0.0_ReKi !NOTE: initialized in InitStatesWithInputs + xd%xhat_plane = 0.0_ReKi xd%p_plane = 0.0_ReKi xd%x_plane = 0.0_ReKi xd%Vx_wake = 0.0_ReKi xd%Vr_wake = 0.0_ReKi + xd%Vx_wake2 = 0.0_ReKi xd%V_plane_filt = 0.0_ReKi xd%Vx_wind_disk_filt = 0.0_ReKi xd%TI_amb_filt = 0.0_ReKi xd%D_rotor_filt = 0.0_ReKi xd%Vx_rel_disk_filt = 0.0_ReKi xd%Ct_azavg_filt = 0.0_ReKi + xd%Cq_azavg_filt = 0.0_ReKi OtherState%firstPass = .true. ! miscvars to avoid the allocation per timestep - allocate ( m%dvdr(0:p%NumRadii-1 ) , STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%dvdr.', errStat, errMsg, RoutineName ) - allocate ( m%dvtdr(0:p%NumRadii-1 ) , STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%dvtdr.', errStat, errMsg, RoutineName ) - allocate ( m%vt_tot(0:p%NumRadii-1,0:p%NumPlanes-1 ) , STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_tot.', errStat, errMsg, RoutineName ) - allocate ( m%vt_amb(0:p%NumRadii-1,0:p%NumPlanes-1 ) , STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_amb.', errStat, errMsg, RoutineName ) - allocate ( m%vt_shr(0:p%NumRadii-1,0:p%NumPlanes-1 ) , STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_shr.', errStat, errMsg, RoutineName ) + ! Cartesian eddy viscosity (allocated even for polar if plane outputs are requested) + allocate ( m%vt_tot2(-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_tot2.', errStat, errMsg, RoutineName ) + allocate ( m%vt_amb2(-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_amb2.', errStat, errMsg, RoutineName ) + allocate ( m%vt_shr2(-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_shr2.', errStat, errMsg, RoutineName ) + if (errStat /= ErrID_None) return + m%vt_tot2 = 0.0_ReKi + m%vt_amb2 = 0.0_ReKi + m%vt_shr2 = 0.0_ReKi + if (p%Mod_Wake == Mod_Wake_Polar) then + allocate ( m%dvtdr (0:p%NumRadii-1 ) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%dvtdr.', errStat, errMsg, RoutineName ) + allocate ( m%vt_tot (0:p%NumRadii-1,0:p%NumPlanes-1 ) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_tot.', errStat, errMsg, RoutineName ) + allocate ( m%vt_amb (0:p%NumRadii-1,0:p%NumPlanes-1 ) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_amb.', errStat, errMsg, RoutineName ) + allocate ( m%vt_shr (0:p%NumRadii-1,0:p%NumPlanes-1 ) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_shr.', errStat, errMsg, RoutineName ) + else if (p%Mod_Wake == Mod_Wake_Cartesian .or. p%Mod_Wake == Mod_Wake_Curl) then + allocate ( m%dvx_dy (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%dvx_dy.', errStat, errMsg, RoutineName ) + allocate ( m%dvx_dz (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%dvx_dz.', errStat, errMsg, RoutineName ) + allocate ( m%nu_dvx_dy(-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%nu_dvx_dy.', errStat, errMsg, RoutineName ) + allocate ( m%nu_dvx_dz(-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%nu_dvx_dz.', errStat, errMsg, RoutineName ) + allocate ( m%dnuvx_dy (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%dnuvx_dy.', errStat, errMsg, RoutineName ) + allocate ( m%dnuvx_dz (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%dnuvx_dz.', errStat, errMsg, RoutineName ) + if (errStat /= ErrID_None) return + m%dvx_dy = 0.0_ReKi + m%dvx_dz = 0.0_ReKi + m%nu_dvx_dy = 0.0_ReKi + m%nu_dvx_dz = 0.0_ReKi + m%dnuvx_dy = 0.0_ReKi + m%dnuvx_dz = 0.0_ReKi + else + STOP ! should never happen + endif + allocate ( m%a(0:p%NumRadii-1 ) , STAT=ErrStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%a.', errStat, errMsg, RoutineName ) @@ -533,8 +610,13 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%r_wake.', errStat, errMsg, RoutineName ) allocate ( m%Vx_high(0:p%NumRadii-1 ) , STAT=ErrStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vx_high.', errStat, errMsg, RoutineName ) + allocate ( m%Vt_wake(0:p%NumRadii-1 ) , STAT=ErrStat2 ) + if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vx_high.', errStat, errMsg, RoutineName ) + allocate ( m%Vx_polar(0:p%NumRadii-1 ) , STAT=ErrStat2 ) + if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vx_polar.', errStat, errMsg, RoutineName ) if (errStat /= ErrID_None) return - + m%Vx_polar = 0.0_ReKi + m%Vt_wake = 0.0_ReKi !............................................................................................ ! Define initialization output here !............................................................................................ @@ -549,19 +631,29 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%Vx_wake.', errStat, errMsg, RoutineName ) allocate ( y%Vr_wake (0:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%Vr_wake.', errStat, errMsg, RoutineName ) + + allocate ( y%Vx_wake2 (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%Vx_wake.', errStat, errMsg, RoutineName ) + allocate ( y%Vy_wake2 (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%Vy_wake.', errStat, errMsg, RoutineName ) + allocate ( y%Vz_wake2 (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%Vz_wake.', errStat, errMsg, RoutineName ) + allocate ( y%D_wake (0:p%NumPlanes-1), STAT=ErrStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%D_wake.', errStat, errMsg, RoutineName ) allocate ( y%x_plane (0:p%NumPlanes-1), STAT=ErrStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%x_plane.', errStat, errMsg, RoutineName ) + allocate ( y%WAT_k_mt (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ) + if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%WAT_k_mt.', errStat, errMsg, RoutineName ) if (errStat /= ErrID_None) return y%xhat_plane = 0.0_Reki y%p_plane = 0.0_Reki y%Vx_wake = 0.0_Reki y%Vr_wake = 0.0_Reki + y%Vx_wake2 = 0.0_Reki + y%Vy_wake2 = 0.0_Reki + y%Vz_wake2 = 0.0_Reki y%D_wake = 0.0_Reki y%x_plane = 0.0_Reki - + y%WAT_k_mt = 0.0_Reki end subroutine WD_Init @@ -650,14 +742,16 @@ subroutine WD_UpdateStates( t, n, u, p, x, xd, z, OtherState, m, errStat, errMsg integer(intKi) :: errStat2 ! temporary Error status character(ErrMsgLen) :: errMsg2 ! temporary Error message character(*), parameter :: RoutineName = 'WD_UpdateStates' - real(ReKi) :: dx, absdx, norm2_xhat_plane + real(ReKi) :: dx, norm2_xhat_plane real(ReKi) :: dy_HWkDfl(3), EddyTermA, EddyTermB, lstar, Vx_wake_min + real(ReKi) :: dvdr, r_tmp, C, S, dvdtheta_r integer(intKi) :: i,j, maxPln - + integer(intKi) :: iy, iz ! indices on y and z + real(ReKi) :: vt_min ! Minimum Eddy viscosity + errStat = ErrID_None errMsg = "" - if ( EqualRealNos(u%D_Rotor,0.0_ReKi) .or. u%D_Rotor < 0.0_ReKi ) then ! TEST: E7 call SetErrStat(ErrID_Fatal, 'Rotor diameter must be greater than zero.', errStat, errMsg, RoutineName) @@ -677,118 +771,108 @@ subroutine WD_UpdateStates( t, n, u, p, x, xd, z, OtherState, m, errStat, errMsg end if - ! Update V_plane_filt to [n+1]: - + ! -------------------------------------------------------------------------------- + ! --- Update states for all planes except disk plane + ! -------------------------------------------------------------------------------- + ! --- Update V_plane_filt to [n+1]: maxPln = min(n,p%NumPlanes-2) do i = 0,maxPln xd%V_plane_filt(:,i ) = xd%V_plane_filt(:,i)*p%filtParam + u%V_plane(:,i )*p%oneMinusFiltParam end do xd%V_plane_filt (:,maxPln+1) = u%V_plane(:,maxPln+1) - maxPln = min(n+2,p%NumPlanes-1) - ! create eddy viscosity info for most downstream plane - i = maxPln+1 - lstar = WakeDiam( p%Mod_WakeDiam, p%numRadii, p%dr, p%r, xd%Vx_wake(:,i-1), xd%Vx_wind_disk_filt(i-1), xd%D_rotor_filt(i-1), p%C_WakeDiam) / 2.0_ReKi - Vx_wake_min = huge(ReKi) - do j = 0,p%NumRadii-1 - Vx_wake_min = min(Vx_wake_min, xd%Vx_wake(j,i-1)) - end do - - EddyTermA = EddyFilter(xd%x_plane(i-1),xd%D_rotor_filt(i-1), p%C_vAmb_DMin, p%C_vAmb_DMax, p%C_vAmb_FMin, p%C_vAmb_Exp) * p%k_vAmb * xd%TI_amb_filt(i-1) * xd%Vx_wind_disk_filt(i-1) * xd%D_rotor_filt(i-1)/2.0_ReKi - EddyTermB = EddyFilter(xd%x_plane(i-1),xd%D_rotor_filt(i-1), p%C_vShr_DMin, p%C_vShr_DMax, p%C_vShr_FMin, p%C_vShr_Exp) * p%k_vShr - do j = 0,p%NumRadii-1 - if ( j == 0 ) then - m%dvdr(j) = 0.0_ReKi - elseif (j <= p%NumRadii-2) then - m%dvdr(j) = ( xd%Vx_wake(j+1,i-1) - xd%Vx_wake(j-1,i-1) ) / (2_ReKi*p%dr) - else - m%dvdr(j) = - xd%Vx_wake(j-1,i-1) / (2_ReKi*p%dr) - end if - ! All of the following states are at [n] - m%vt_amb(j,i-1) = EddyTermA - m%vt_shr(j,i-1) = EddyTermB * max( (lstar**2)*abs(m%dvdr(j)) , lstar*(xd%Vx_wind_disk_filt(i-1) + Vx_wake_min ) ) - m%vt_tot(j,i-1) = m%vt_amb(j,i-1) + m%vt_shr(j,i-1) - end do - - ! We are going to update Vx_Wake - ! The quantities in these loops are all at time [n], so we need to compute prior to updating the states to [n+1] - do i = maxPln, 1, -1 - + ! --- Compute eddy viscosity terms + ! compute eddy-viscosity terms for all planes, NOTE: starting from maxPln+1 here + do i = maxPln+1, 1, -1 lstar = WakeDiam( p%Mod_WakeDiam, p%numRadii, p%dr, p%r, xd%Vx_wake(:,i-1), xd%Vx_wind_disk_filt(i-1), xd%D_rotor_filt(i-1), p%C_WakeDiam) / 2.0_ReKi - ! The following two quantities need to be for the time increments: - ! [n+1] [n] - ! dx = xd%x_plane(i) - xd%x_plane(i-1) - ! This is equivalent to - - dx = dot_product(xd%xhat_plane(:,i-1),xd%V_plane_filt(:,i-1))*p%DT_low - absdx = abs(dx) - if ( EqualRealNos( dx, 0.0_ReKi ) ) absdx = 1.0_ReKi ! This is to avoid division by zero problems in the formation of m%b and m%d below, which are not used when dx=0; the value of unity is arbitrary - Vx_wake_min = huge(ReKi) - do j = 0,p%NumRadii-1 - Vx_wake_min = min(Vx_wake_min, xd%Vx_wake(j,i-1)) - end do - + if (p%Mod_Wake == Mod_Wake_Cartesian .or. p%Mod_Wake == Mod_Wake_Curl) then + Vx_wake_min = minval(xd%Vx_wake2(:,:,i-1)) + else + do j = 0,p%NumRadii-1 + Vx_wake_min = min(Vx_wake_min, xd%Vx_wake(j,i-1)) + end do + endif + EddyTermA = EddyFilter(xd%x_plane(i-1),xd%D_rotor_filt(i-1), p%C_vAmb_DMin, p%C_vAmb_DMax, p%C_vAmb_FMin, p%C_vAmb_Exp) * p%k_vAmb * xd%TI_amb_filt(i-1) * xd%Vx_wind_disk_filt(i-1) * xd%D_rotor_filt(i-1)/2.0_ReKi EddyTermB = EddyFilter(xd%x_plane(i-1),xd%D_rotor_filt(i-1), p%C_vShr_DMin, p%C_vShr_DMax, p%C_vShr_FMin, p%C_vShr_Exp) * p%k_vShr - do j = 0,p%NumRadii-1 - if ( j == 0 ) then - m%dvdr(j) = 0.0_ReKi - elseif (j <= p%NumRadii-2) then - m%dvdr(j) = ( xd%Vx_wake(j+1,i-1) - xd%Vx_wake(j-1,i-1) ) / (2_ReKi*p%dr) - else - m%dvdr(j) = - xd%Vx_wake(j-1,i-1) / (2_ReKi*p%dr) - end if - ! All of the following states are at [n] - m%vt_amb(j,i-1) = EddyTermA - m%vt_shr(j,i-1) = EddyTermB * max( (lstar**2)*abs(m%dvdr(j)) , lstar*(xd%Vx_wind_disk_filt(i-1) + Vx_wake_min ) ) - m%vt_tot(j,i-1) = m%vt_amb(j,i-1) + m%vt_shr(j,i-1) - end do - - ! All of the m%a,m%b,m%c,m%d vectors use states at time increment [n] - ! These need to be inside another radial loop because m%dvtdr depends on the j+1 and j-1 indices of m%vt() - - m%dvtdr(0) = 0.0_ReKi - m%a(0) = 0.0_ReKi - m%b(0) = p%dr * ( xd%Vx_wind_disk_filt(i-1) + xd%Vx_wake(0,i-1)) / absdx + m%vt_tot(0,i-1)/p%dr - m%c(0) = -m%vt_tot(0,i-1)/p%dr - m%c(p%NumRadii-1) = 0.0_ReKi - m%d(0) = (p%dr * (xd%Vx_wind_disk_filt(i-1) + xd%Vx_wake(0,i-1)) / absdx - m%vt_tot(0,i-1)/p%dr ) * xd%Vx_wake(0,i-1) + ( m%vt_tot(0,i-1)/p%dr ) * xd%Vx_wake(1,i-1) + vt_min = abs(1.e-4_ReKi * xd%D_Rotor_filt(i-1) * xd%Vx_rel_disk_filt) ! Miminum eddy viscosity + if (p%Mod_Wake == Mod_Wake_Polar) then + ! Polar grid + do j = 0,p%NumRadii-1 + if ( j == 0 ) then + dvdr = 0.0_ReKi + elseif (j <= p%NumRadii-2) then + dvdr = ( xd%Vx_wake(j+1,i-1) - xd%Vx_wake(j-1,i-1) ) / (2_ReKi*p%dr) + else + dvdr = - xd%Vx_wake(j-1,i-1) / (2_ReKi*p%dr) + end if + ! All of the following states are at [n] + m%vt_amb(j,i-1) = max(EddyTermA, vt_min) + m%vt_shr(j,i-1) = EddyTermB * max( (lstar**2)*abs(dvdr) , lstar*(xd%Vx_wind_disk_filt(i-1) + Vx_wake_min ) ) + m%vt_tot(j,i-1) = m%vt_amb(j,i-1) + m%vt_shr(j,i-1) + + end do + else if (p%Mod_Wake == Mod_Wake_Cartesian .or. p%Mod_Wake == Mod_Wake_Curl) then + ! First compute gradients of dVx/dy and dVx/dz + call gradient_y(xd%Vx_wake2(:,:,i-1), p%dr, m%dvx_dy(:,:,i-1)) + call gradient_z(xd%Vx_wake2(:,:,i-1), p%dr, m%dvx_dz(:,:,i-1)) + + ! Eddy viscosity + do iz = -p%NumRadii+1, p%NumRadii-1 + do iy = -p%NumRadii+1, p%NumRadii-1 + + r_tmp = sqrt(p%y(iy)**2 + p%z(iz)**2) + if (EqualRealNos(r_tmp,0.0_ReKi) ) then + S = 0.0_ReKi + C = 0.0_ReKi + dvdtheta_r = 0.0_ReKi + else + S=p%z(iz)/r_tmp + C=p%y(iy)/r_tmp + dvdtheta_r = (m%dvx_dy(iy,iz,i-1) * (-p%z(iz)) + m%dvx_dz(iy,iz,i-1) * p%y(iy)) / r_tmp + endif + + dvdr = m%dvx_dy(iy,iz,i-1) * C + m%dvx_dz(iy,iz,i-1) * S + m%vt_amb2(iy,iz,i-1) = max(EddyTermA, vt_min) + m%vt_shr2(iy,iz,i-1) = EddyTermB * max( (lstar**2)* (abs(dvdr) + abs(dvdtheta_r)) , lstar*(xd%Vx_wind_disk_filt(i-1) + Vx_wake_min ) ) + m%vt_tot2(iy,iz,i-1) = m%vt_amb2(iy,iz,i-1) + p%k_vCurl*m%vt_shr2(iy,iz,i-1) + + enddo + enddo + endif + end do ! loop on planes i = maxPln+1, 1, -1 + ! --- Update Vx and Vr + if (p%Mod_Wake == Mod_Wake_Polar) then + call updateVelocityPolar() + else if (p%Mod_Wake == Mod_Wake_Cartesian .or. p%Mod_Wake == Mod_Wake_Curl) then + call updateVelocityCartesian() + else + ! Should never happen + endif + if (errStat >= AbortErrLev) then + call CleanUp() + return + endif + + ! --- Update plane positions and filtered states + do i = maxPln, 1, -1 + ! dx = xd%x_plane(i) - xd%x_plane(i-1) - do j = p%NumRadii-1, 1, -1 - - if (j <= p%NumRadii-2) then - m%dvtdr(j) = ( m%vt_tot(j+1,i-1) - m%vt_tot(j-1,i-1) ) / (2_ReKi*p%dr) - m%c(j) = real(j,ReKi)*xd%Vr_wake(j,i-1)/4.0_ReKi - (1_ReKi+2_ReKi*real(j,ReKi))*m%vt_tot(j,i-1)/(4.0_ReKi*p%dr) - real(j,ReKi)*m%dvtdr(j)/4.0_ReKi - m%d(j) = ( real(j,ReKi)*xd%Vr_wake(j,i-1)/4.0_ReKi - (1_ReKi-2_ReKi*real(j,ReKi))*m%vt_tot(j,i-1)/(4.0_ReKi*p%dr) - real(j,ReKi)*m%dvtdr(j)/4.0_ReKi) * xd%Vx_wake(j-1,i-1) & - + ( p%r(j)*( xd%Vx_wind_disk_filt(i-1) + xd%Vx_wake(j,i-1) )/absdx - real(j,ReKi)*m%vt_tot(j,i-1)/p%dr ) * xd%Vx_wake(j,i-1) & - + (-real(j,ReKi)*xd%Vr_wake(j,i-1)/4.0_ReKi + (1_ReKi+2_ReKi*real(j,ReKi))*m%vt_tot(j,i-1)/(4.0_ReKi*p%dr) + real(j,ReKi)*m%dvtdr(j)/4.0_ReKi ) * xd%Vx_wake(j+1,i-1) - - else - m%dvtdr(j) = 0.0_ReKi - m%d(j) = ( real(j,ReKi)*xd%Vr_wake(j,i-1)/4.0_ReKi - (1_ReKi-2_ReKi*real(j,ReKi))*m%vt_tot(j,i-1)/(4.0_ReKi*p%dr) - real(j,ReKi)*m%dvtdr(j)/4.0_ReKi) * xd%Vx_wake(j-1,i-1) & - + ( p%r(j)*( xd%Vx_wind_disk_filt(i-1) + xd%Vx_wake(j,i-1) )/absdx - real(j,ReKi)*m%vt_tot(j,i-1)/p%dr ) * xd%Vx_wake(j,i-1) - - end if - - m%a(j) = -real(j,ReKi)*xd%Vr_wake(j,i-1)/4.0_ReKi + (1.0_ReKi-2.0_ReKi*real(j,ReKi))*m%vt_tot(j,i-1)/(4.0_ReKi*p%dr) + real(j,ReKi)*m%dvtdr(j)/4.0_ReKi - m%b(j) = p%r(j) * ( xd%Vx_wind_disk_filt(i-1) + xd%Vx_wake(j,i-1) ) / absdx + real(j,ReKi)*m%vt_tot(j,i-1)/p%dr - - - end do ! j = 1,p%NumRadii-1 - - ! Update these states to [n+1] + ! NEW which one for dx? +!~ dx = dot_product(xd%xhat_plane(:,i-1),xd%V_plane_filt(:,i-1))*p%DT_low + dx = dot_product(xd%xhat_plane(:,i-1),u%V_plane(:,i-1))*p%DT_low + ! Update these states to [n+1] xd%x_plane (i) = xd%x_plane (i-1) + abs(dx) ! dx = dot_product(xd%xhat_plane(:,i-1),xd%V_plane_filt(:,i-1))*p%DT_low ; don't use absdx here xd%YawErr_filt (i) = xd%YawErr_filt(i-1) xd%xhat_plane(:,i) = xd%xhat_plane(:,i-1) - ! The function state-related arguments must be at time [n+1], so we must update YawErr_filt and xhat_plane before computing the deflection - + ! The function state-related arguments must be at time [n+1], so we must update YawErr_filt and xhat_plane before computing the deflection dy_HWkDfl = GetYawCorrection(xd%YawErr_filt(i), xd%xhat_plane(:,i), dx, p, errStat2, errMsg2) call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) if (errStat >= AbortErrLev) then @@ -796,38 +880,22 @@ subroutine WD_UpdateStates( t, n, u, p, x, xd, z, OtherState, m, errStat, errMsg call Cleanup() return end if - xd%p_plane (:,i) = xd%p_plane(:,i-1) + xd%xhat_plane(:,i-1)*dx + dy_HWkDfl & - + ( u%V_plane(:,i-1) - xd%xhat_plane(:,i-1)*dot_product(xd%xhat_plane(:,i-1),u%V_plane(:,i-1)) )*p%DT_low - + ! Old convection + !xd%p_plane (:,i) = xd%p_plane(:,i-1) + xd%xhat_plane(:,i-1)*dx + dy_HWkDfl & + ! + ( u%V_plane(:,i-1) - xd%xhat_plane(:,i-1)*dot_product(xd%xhat_plane(:,i-1),u%V_plane(:,i-1)) )*p%DT_low + ! New convection model (dx = V * dt) + xd%p_plane (:,i) = xd%p_plane(:,i-1) + u%V_Plane(:,i-1) * p%DT_low + dy_HWkDfl + xd%Vx_wind_disk_filt(i) = xd%Vx_wind_disk_filt(i-1) xd%TI_amb_filt (i) = xd%TI_amb_filt(i-1) xd%D_rotor_filt (i) = xd%D_rotor_filt(i-1) - ! Update Vx_wake and Vr_wake to [n+1] - if ( EqualRealNos( dx, 0.0_ReKi ) ) then - xd%Vx_wake(:,i) = xd%Vx_wake(:,i-1) - xd%Vr_wake(:,i) = xd%Vr_wake(:,i-1) - else - call ThomasAlgorithm(p%NumRadii, m%a, m%b, m%c, m%d, xd%Vx_wake(:,i), errStat2, errMsg2) - call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) - if (errStat >= AbortErrLev) then - ! TEST: E16, E17, or E18 - call Cleanup() - return - end if - do j = 1,p%NumRadii-1 - ! NOTE: xd%Vr_wake(0,:) was initialized to 0 and remains 0. - xd%Vr_wake(j,i) = real( j-1,ReKi)*( xd%Vr_wake(j-1,i) )/real(j,ReKi) & - ! Vx_wake is for the [n+1] , [n+1] , [n] , and [n] increments - - real(2*j-1,ReKi)*p%dr * ( xd%Vx_wake(j,i) + xd%Vx_wake(j-1,i) - xd%Vx_wake(j,i-1) - xd%Vx_wake(j-1,i-1) ) / ( real(4*j,ReKi) * absdx ) - end do - end if - end do ! i = 1,min(n+2,p%NumPlanes-1) - - - - ! Update states at disk-plane to [n+1] + end do ! loop on planes i = maxPln+1, 1, -1 + ! -------------------------------------------------------------------------------- + ! --- Update states at disk-plane (0) to time [n+1] + ! -------------------------------------------------------------------------------- + !xd%x_plane (0) = 0.0_ReKi ! already initialized to zero xd%xhat_plane (:,0) = xd%xhat_plane(:,0)*p%filtParam + u%xhat_disk(:)*p%oneMinusFiltParam ! 2-step calculation for xhat_plane at disk norm2_xhat_plane = TwoNorm( xd%xhat_plane(:,0) ) if ( EqualRealNos(norm2_xhat_plane, 0.0_ReKi) ) then @@ -836,11 +904,12 @@ subroutine WD_UpdateStates( t, n, u, p, x, xd, z, OtherState, m, errStat, errMsg call Cleanup() return end if - xd%xhat_plane (:,0) = xd%xhat_plane(:,0) / norm2_xhat_plane - xd%YawErr_filt (0) = xd%YawErr_filt(0)*p%filtParam + u%YawErr*p%oneMinusFiltParam + call filter_angles2(xd%psi_skew_filt, xd%chi_skew_filt, u%psi_skew, u%chi_skew, p%filtParam, p%oneMinusFiltParam) + xd%YawErr_filt (0) = xd%YawErr_filt(0)*p%filtParam + u%YawErr *p%oneMinusFiltParam + if ( EqualRealNos(abs(xd%YawErr_filt(0)), pi/2) .or. abs(xd%YawErr_filt(0)) > pi/2 ) then ! TEST: E4 call SetErrStat(ErrID_FATAL, 'The time-filtered nacelle-yaw error has reached +/- pi/2.', errStat, errMsg, RoutineName) @@ -848,42 +917,561 @@ subroutine WD_UpdateStates( t, n, u, p, x, xd, z, OtherState, m, errStat, errMsg return end if - ! The function state-related arguments must be at time [n+1], so we must update YawErr_filt and xhat_plane before computing the deflection + ! The function state-related arguments must be at time [n+1], so we must update YawErr_filt and xhat_plane before computing the deflection dx = 0.0_ReKi dy_HWkDfl = GetYawCorrection(xd%YawErr_filt(0), xd%xhat_plane(:,0), dx, p, errStat2, errMsg2) - call SetErrStat(ErrStat2, ErrMsg2, errStat, errMsg, RoutineName) - if (errStat /= ErrID_None) then - ! TEST: E3 - call Cleanup() - return - end if - - ! NOTE: xd%x_plane(0) was already initialized to zero - - xd%p_plane (:,0) = xd%p_plane(:,0)*p%filtParam + ( u%p_hub(:) + dy_HWkDfl(:) )*p%oneMinusFiltParam - xd%Vx_wind_disk_filt(0) = xd%Vx_wind_disk_filt(0)*p%filtParam + u%Vx_wind_disk*p%oneMinusFiltParam - xd%TI_amb_filt (0) = xd%TI_amb_filt(0)*p%filtParam + u%TI_amb*p%oneMinusFiltParam - xd%D_rotor_filt (0) = xd%D_rotor_filt(0)*p%filtParam + u%D_rotor*p%oneMinusFiltParam - xd%Vx_rel_disk_filt = xd%Vx_rel_disk_filt*p%filtParam + u%Vx_rel_disk*p%oneMinusFiltParam - + call SetErrStat(ErrStat2, ErrMsg2, errStat, errMsg, RoutineName) + if (errStat /= ErrID_None) then + ! TEST: E3 + call Cleanup() + return + end if + + ! Disk plane states filtered based on inputs + xd%p_plane (:,0) = xd%p_plane(:,0) *p%filtParam + ( u%p_hub(:) + dy_HWkDfl(:) )*p%oneMinusFiltParam + xd%Vx_wind_disk_filt(0) = xd%Vx_wind_disk_filt(0)*p%filtParam + u%Vx_wind_disk *p%oneMinusFiltParam + xd%TI_amb_filt (0) = xd%TI_amb_filt(0) *p%filtParam + u%TI_amb *p%oneMinusFiltParam + xd%D_rotor_filt (0) = xd%D_rotor_filt(0) *p%filtParam + u%D_rotor *p%oneMinusFiltParam + xd%Vx_rel_disk_filt = xd%Vx_rel_disk_filt *p%filtParam + u%Vx_rel_disk *p%oneMinusFiltParam - ! filtered, azimuthally-averaged Ct values at each radial station + ! filtered, azimuthally-averaged Ct values at each radial station xd%Ct_azavg_filt (:) = xd%Ct_azavg_filt(:)*p%filtParam + u%Ct_azavg(:)*p%oneMinusFiltParam - - call NearWakeCorrection( xd%Ct_azavg_filt, xd%Vx_rel_disk_filt, p, m, xd%Vx_wake(:,0), xd%D_rotor_filt(0), errStat, errMsg ) - + xd%Cq_azavg_filt (:) = xd%Cq_azavg_filt(:)*p%filtParam + u%Cq_azavg(:)*p%oneMinusFiltParam + + ! --- Set velocity at disk plane + m%GammaCurl = 0.0_ReKi ! Storing for outputs + m%Ct_avg = 0.0_ReKi ! Storing for outputs + if (p%Mod_Wake == Mod_Wake_Polar) then + + ! Compute wake deficit of first plane based on rotor loading, outputs: Vx_Wake, m + call NearWakeCorrection( xd%Ct_azavg_filt, xd%Cq_azavg_filt, xd%Vx_rel_disk_filt, p, m, xd%Vx_wake(:,0), m%Vt_wake, xd%D_rotor_filt(0), errStat, errMsg ) + + else if (p%Mod_Wake == Mod_Wake_Cartesian .or. p%Mod_Wake == Mod_Wake_Curl) then + + ! Initialize the spanwise velocities to zero. + ! Thses will be changed by AddSwirl and/or AddVelocityCurl + xd%Vy_wake2(:,:,0) = 0._ReKi + xd%Vz_wake2(:,:,0) = 0._ReKi + + ! --- Compute Vx + ! Compute Vx(r) + call NearWakeCorrection( xd%Ct_azavg_filt, xd%Cq_azavg_filt, xd%Vx_rel_disk_filt, p, m, m%Vx_polar(:), m%Vt_wake, xd%D_rotor_filt(0), errStat, errMsg ) + ! Convert to Cartesian + call Axisymmetric2CartesianVx(m%Vx_polar, p%r, p%y, p%z, xd%Vx_wake2(:,:,0)) + call FilterVx(xd%Vx_wake2(:,:,0), p%FilterInit) ! don't filter if FilterInit is 0 + m%Ct_avg = get_Ctavg(p%r, xd%Ct_azavg_filt, xd%D_rotor_filt(0)) + ! --- Add V/W from vorticies + if (p%Mod_Wake == Mod_Wake_Curl) then + call AddVelocityCurl(xd%Vx_wind_disk_filt(0), xd%chi_skew_filt, p%NumVortices, xd%D_Rotor_filt(0)/2., & + xd%psi_skew_filt, p%y, p%z, m%Ct_avg, p%sigma_D, xd%Vy_wake2(:,:,0), xd%Vz_wake2(:,:,0), m%GammaCurl) + + endif + ! --- Add Swirl + if (p%Swirl) then + call AddSwirl(p%r, m%Vt_wake, p%y, p%z, xd%Vy_wake2(:,:,0), xd%Vz_wake2(:,:,0)) + endif + endif + !Used for debugging: write(51,'(I5,100(1x,ES10.2E2))') n, xd%x_plane(n), xd%x_plane(n)/xd%D_rotor_filt(n), xd%Vx_wind_disk_filt(n) + xd%Vx_wake(:,n), xd%Vr_wake(:,n) call Cleanup() contains + + subroutine updateVelocityPolar() + integer(intKi) :: i,j + real(ReKi) :: dx, absdx + ! The quantities in these loops are all at time [n], so we need to compute prior to updating the states to [n+1] (loop in reversed) + do i = maxPln, 1, -1 + ! dx is used instead of delta t since plane are updated based on their indices + ! [n+1] [n] + ! dx = xd%x_plane(i) - xd%x_plane(i-1) + dx = dot_product(xd%xhat_plane(:,i-1),xd%V_plane_filt(:,i-1))*p%DT_low + absdx = abs(dx) + if ( EqualRealNos( dx, 0.0_ReKi ) ) absdx = 1.0_ReKi ! This is to avoid division by zero problems in the formation of m%b and m%d below, which are not used when dx=0; the value of unity is arbitrary + + ! All of the m%a,m%b,m%c,m%d vectors use states at time increment [n] + ! These need to be inside another radial loop because m%dvtdr depends on the j+1 and j-1 indices of m%vt() + + m%dvtdr(0) = 0.0_ReKi + m%a(0) = 0.0_ReKi + m%b(0) = p%dr * ( xd%Vx_wind_disk_filt(i-1) + xd%Vx_wake(0,i-1)) / absdx + m%vt_tot(0,i-1)/p%dr + m%c(0) = -m%vt_tot(0,i-1)/p%dr + m%c(p%NumRadii-1) = 0.0_ReKi + m%d(0) = (p%dr * (xd%Vx_wind_disk_filt(i-1) + xd%Vx_wake(0,i-1)) / absdx - m%vt_tot(0,i-1)/p%dr ) * xd%Vx_wake(0,i-1) + ( m%vt_tot(0,i-1)/p%dr ) * xd%Vx_wake(1,i-1) + + do j = p%NumRadii-1, 1, -1 + + if (j <= p%NumRadii-2) then + m%dvtdr(j) = ( m%vt_tot(j+1,i-1) - m%vt_tot(j-1,i-1) ) / (2_ReKi*p%dr) + m%c(j) = real(j,ReKi)*xd%Vr_wake(j,i-1)/4.0_ReKi - (1_ReKi+2_ReKi*real(j,ReKi))*m%vt_tot(j,i-1)/(4.0_ReKi*p%dr) - real(j,ReKi)*m%dvtdr(j)/4.0_ReKi + m%d(j) = ( real(j,ReKi)*xd%Vr_wake(j,i-1)/4.0_ReKi - (1_ReKi-2_ReKi*real(j,ReKi))*m%vt_tot(j,i-1)/(4.0_ReKi*p%dr) - real(j,ReKi)*m%dvtdr(j)/4.0_ReKi) * xd%Vx_wake(j-1,i-1) & + + ( p%r(j)*( xd%Vx_wind_disk_filt(i-1) + xd%Vx_wake(j,i-1) )/absdx - real(j,ReKi)*m%vt_tot(j,i-1)/p%dr ) * xd%Vx_wake(j,i-1) & + + (-real(j,ReKi)*xd%Vr_wake(j,i-1)/4.0_ReKi + (1_ReKi+2_ReKi*real(j,ReKi))*m%vt_tot(j,i-1)/(4.0_ReKi*p%dr) + real(j,ReKi)*m%dvtdr(j)/4.0_ReKi ) * xd%Vx_wake(j+1,i-1) + + else + m%dvtdr(j) = 0.0_ReKi + m%d(j) = ( real(j,ReKi)*xd%Vr_wake(j,i-1)/4.0_ReKi - (1_ReKi-2_ReKi*real(j,ReKi))*m%vt_tot(j,i-1)/(4.0_ReKi*p%dr) - real(j,ReKi)*m%dvtdr(j)/4.0_ReKi) * xd%Vx_wake(j-1,i-1) & + + ( p%r(j)*( xd%Vx_wind_disk_filt(i-1) + xd%Vx_wake(j,i-1) )/absdx - real(j,ReKi)*m%vt_tot(j,i-1)/p%dr ) * xd%Vx_wake(j,i-1) + + end if + + m%a(j) = -real(j,ReKi)*xd%Vr_wake(j,i-1)/4.0_ReKi + (1.0_ReKi-2.0_ReKi*real(j,ReKi))*m%vt_tot(j,i-1)/(4.0_ReKi*p%dr) + real(j,ReKi)*m%dvtdr(j)/4.0_ReKi + m%b(j) = p%r(j) * ( xd%Vx_wind_disk_filt(i-1) + xd%Vx_wake(j,i-1) ) / absdx + real(j,ReKi)*m%vt_tot(j,i-1)/p%dr + + end do ! j = 1,p%NumRadii-1 + + ! Update Vx_wake and Vr_wake to [n+1] + if ( EqualRealNos( dx, 0.0_ReKi ) ) then + xd%Vx_wake(:,i) = xd%Vx_wake(:,i-1) + xd%Vr_wake(:,i) = xd%Vr_wake(:,i-1) + else + call ThomasAlgorithm(p%NumRadii, m%a, m%b, m%c, m%d, xd%Vx_wake(:,i), errStat2, errMsg2) + call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) + if (errStat >= AbortErrLev) then + ! TEST: E16, E17, or E18 + return + end if + do j = 1,p%NumRadii-1 + ! NOTE: xd%Vr_wake(0,:) was initialized to 0 and remains 0. + xd%Vr_wake(j,i) = real( j-1,ReKi)*( xd%Vr_wake(j-1,i) )/real(j,ReKi) & + ! Vx_wake is for the [n+1] , [n+1] , [n] , and [n] increments + - real(2*j-1,ReKi)*p%dr * ( xd%Vx_wake(j,i) + xd%Vx_wake(j-1,i) - xd%Vx_wake(j,i-1) - xd%Vx_wake(j-1,i-1) ) / ( real(4*j,ReKi) * absdx ) + end do + end if + end do ! i = 1,min(n+2,p%NumPlanes-1) + end subroutine updateVelocityPolar + + !> + subroutine updateVelocityCartesian() + integer(intKi) :: iy,iz,i + real(ReKi) :: dx + real(ReKi) :: xp !< x position of the plane + real(ReKi) :: divTau + divTau =0.0_ReKi + + ! This is the formulation of curled wake algorithm (Martinez et al WES 2019) + ! The quantities in these loops are all at time [n], so we need to compute prior to updating the states to [n+1] (loop in reversed) + do i = maxPln, 1, -1 + + ! NOTE: we cannot use data at i here since positions of planes have not been updated yet + dx = abs(dot_product(xd%xhat_plane(:,i-1),xd%V_plane_filt(:,i-1))*p%DT_low) + !xp = xd%p_plane(1,i-1)/u%D_rotor ! Current plane downstream x position in D + xp = (xd%x_plane(i-1) + abs(dx))/u%D_rotor + + ! Gradients for eddy viscosity term + ! NOTE: the gradient of Vx have been computed for the eddy viscosity already + m%nu_dvx_dy(:,:) = m%vt_tot2(:,:,i-1) * m%dvx_dy(:,:,i-1) + m%nu_dvx_dz(:,:) = m%vt_tot2(:,:,i-1) * m%dvx_dz(:,:,i-1) + call gradient_y(m%nu_dvx_dy, p%dr, m%dnuvx_dy ) + call gradient_z(m%nu_dvx_dz, p%dr, m%dnuvx_dz ) + + ! Loop through all the points on the plane (y, z) + do iz = -p%NumRadii+2, p%NumRadii-2 + do iy = -p%NumRadii+2, p%NumRadii-2 + + ! Eddy viscosity term + divTau = m%dnuvx_dy(iy,iz) + m%dnuvx_dz(iy,iz) + ! Update state of Vx + xd%Vx_wake2(iy,iz,i) = xd%Vx_wake2(iy,iz,i-1) - & + p%DT_low * ( & + ( (xd%Vy_wake2(iy,iz,i-1) ) * m%dvx_dy(iy,iz,i-1) + & + (xd%Vz_wake2(iy,iz,i-1) ) * m%dvx_dz(iy,iz,i-1) & + - divTau) & + ) + ! Update state (decay) of Vy and Vz + xd%Vy_wake2(iy,iz,i) = xd%Vy_wake2(iy,iz,i-1) * exp( - p%k_VortexDecay * dx) + xd%Vz_wake2(iy,iz,i) = xd%Vz_wake2(iy,iz,i-1) * exp( - p%k_VortexDecay * dx) + + enddo ! iy + enddo ! iz + enddo ! i, planes + + end subroutine updateVelocityCartesian + subroutine Cleanup() + end subroutine Cleanup + +end subroutine WD_UpdateStates + +! A subroutine to compute 2D gradient in y +subroutine gradient_y(field, dy, gradient) + real(ReKi), intent(in), dimension(:,:) :: field ! The field to compute the gradient + real(ReKi), intent(in) :: dy ! The finite difference + real(ReKi), intent(inout), dimension(:,:) :: gradient ! The field to compute the gradient + integer :: iy,iz + gradient=0.0_ReKi + do iz=2,size(field,2)-1 + do iy=2,size(field,1)-1 + gradient(iy,iz) = (field(iy+1,iz) - field(iy-1,iz)) / (2 * dy) + enddo + enddo +end subroutine gradient_y + +! A subroutine to compute 2D gradient in z +subroutine gradient_z(field, dz, gradient) + real(ReKi), intent(in), dimension(:,:) :: field ! The field to compute the gradient + real(ReKi), intent(in) :: dz ! The finite difference + real(ReKi), intent(inout), dimension(:,:) :: gradient ! The field to compute the gradient + integer :: iy,iz + gradient=0.0_ReKi + do iz=2,size(field,2)-1 + do iy=2,size(field,1)-1 + gradient(iy,iz) = (field(iy,iz+1) - field(iy,iz-1)) / (2 * dz) + enddo + enddo +end subroutine gradient_z + + + + +! The velocities from a lamboseen vortex +subroutine lamb_oseen_2d(y, z, Gamma, sigma, v, w) + real(ReKi), intent(in) :: y ! The spanwise coordinate [m] + real(ReKi), intent(in) :: z ! The wallnormal coordinate [m] + real(ReKi), intent(in) :: sigma ! The width of the vortex [m] + real(ReKi), intent(in) :: Gamma ! The circulation strength [kg / (m s)] + real(ReKi), intent(inout) :: v ! The spanwise velocity + real(ReKi), intent(inout) :: w ! The wall-normal velocity + + ! Compute the velocities from the lamb-oseen vortex + v = Gamma / (2. * pi) * z / (y**2 + z**2 + 1.e-5) * (1. - exp(-(y**2 + z**2)/(sigma**2) )) + w = -Gamma / (2. * pi) * y / (y**2 + z**2 + 1.e-5) * (1. - exp(-(y**2 + z**2)/(sigma**2) )) + +end subroutine lamb_oseen_2d + +! A subroutine to compute the spanwise velocities from curl +subroutine AddVelocityCurl(Vx, yaw_angle, nVortex, R, psi_skew, y, z, Ct_avg, sigma_d, Vy_curl, Vz_curl, Gamma0) + + real(ReKi), intent(in) :: Vx ! The inflow velocity + real(ReKi), intent(in) :: yaw_angle ! The yaw angle (rad) + integer(intKi), intent(in) :: nVortex ! The number of vortices (-) + real(ReKi), intent(in) :: R ! The turbine radius (m) + real(ReKi), intent(in) :: psi_skew ! The angle of tilt + yaw (rad) + real(ReKi), dimension(:), intent(in) :: y ! Spanwise Cartesian coordinate (m) + real(ReKi), dimension(:), intent(in) :: z ! Wall-normal Cartesian coordinate (m) + real(ReKi), intent(in) :: Ct_avg ! Average thrust coefficient + real(ReKi), intent(in) :: sigma_d ! The width of Gaussian kernel for the vortices divided by diameter (-) + real(ReKi), dimension(:,:), intent(inout) :: Vy_curl ! Curl velocity in the y direction (m/s) + real(ReKi), dimension(:,:), intent(inout) :: Vz_curl ! Curl velocity in the z direction (m/s) + real(ReKi) , intent( out) :: Gamma0 ! Circulation used + real(ReKi) dR, G, zp, y0, z0, v, w, sigma, w_mean, v_mean + integer(intKi) ir, iy, iz, iIn + + ! The width of the Guassian vortices + sigma = sigma_d * 2 * R + + ! The separation between vortices + dR = 2 * R / nVortex + + ! Compute the Ct + ! Add another cosine term to project the vortices + Gamma0 = R * Vx * Ct_avg * sin(yaw_angle) * cos(yaw_angle) + + ! Loop through all the points + do ir = 2, nVortex-1 + + ! The vertical location of the vortices along a line in z + zp = -R + dR * ir + + ! The center location of the vortex + ! This projection is used to change from only yaw to combination of + ! yaw and tilt + y0 = -zp * sin(psi_skew) + z0 = zp * cos(psi_skew) + ! Scale the circulation based on location + G = Gamma0 * zp * dR / (R * sqrt(R**2 - zp**2)) + + ! Loop through all planes + w_mean = 0.0_ReKi + v_mean = 0.0_ReKi + iIn = 0 ! number of points inside rotor area + do iz = 1,size(z) + do iy = 1,size(y) + + call lamb_oseen_2d(y(iy) - y0, z(iz) - z0, G, sigma, v, w) + + if (sqrt(y(iy)**2 + z(iz)**2)<=R ) then + v_mean = v_mean + v + w_mean = w_mean + w + iIn = iIn +1 + endif + + Vy_curl(iy, iz) = Vy_curl(iy, iz) + v + Vz_curl(iy, iz) = Vz_curl(iy, iz) + w + + enddo + enddo + enddo + if (.false.) then + v_mean = v_mean / (iIn) + w_mean = w_mean / (iIn) + Vy_curl(:, :) = Vy_curl(:, :) - v_mean + Vz_curl(:, :) = Vz_curl(:, :) - w_mean + endif + +end subroutine AddVelocityCurl + + +!> This subroutine computes the near wake correction : Vx_wake +subroutine AddSwirl(r, Vt_wake, y, z, Vy_curl, Vz_curl) + real(ReKi), intent(in) :: r(:) !< Tangential wake velocity deficit at first plane + real(ReKi), intent(in) :: Vt_wake(:) !< Tangential wake velocity deficit at first plane + real(ReKi), dimension(:), intent(in) :: y !< Spanwise Cartesian coordinate (m) + real(ReKi), dimension(:), intent(in) :: z !< Wall-normal Cartesian coordinate (m) + real(ReKi), dimension(:,:), intent(inout) :: Vy_curl !< Curl velocity in the y direction (m/s) + real(ReKi), dimension(:,:), intent(inout) :: Vz_curl !< Curl velocity in the z direction (m/s) + + real(ReKi) :: alpha + integer(IntKi) :: iz, iy, iLow, nr + real(ReKi) :: r_tmp, r_max + real(ReKi) :: Vt, S, C ! Sine and cosine + nr = size(r) + r_max = r(nr) + iLow=0 + ! Loop through all plane points + do iz = 1,size(z) + do iy = 1,size(y) + ! Project into cartesian + r_tmp = sqrt(y(iy)**2 + z(iz)**2) + if (r_tmp<=r_max) then + if (EqualRealNos(r_tmp, 0.0_ReKi) ) then + S = 0.0_ReKi + C = 0.0_ReKi + else + S=z(iz)/r_tmp + C=y(iy)/r_tmp + endif + Vt = InterpBin(r_tmp, r, Vt_wake, iLow, nr) !( XVal, XAry, YAry, ILo, AryLen ) + Vy_curl(iy, iz) = Vy_curl(iy, iz) + Vt * S + Vz_curl(iy, iz) = Vz_curl(iy, iz) - Vt * C + endif + enddo + enddo - end subroutine Cleanup +end subroutine AddSwirl + +!> Test the curled wake velocity curl function +subroutine WD_TEST_AddVelocityCurl() + + real(ReKi) :: Vy_curl(2,2)=0.0_ReKi + real(ReKi) :: Vy_curl_ref(2,2) + real(ReKi) :: Vz_curl(2,2)=0.0_ReKi + real(ReKi) :: Vz_curl_ref(2,2) + real(ReKi) :: y(2)=(/ 0., 2./) + real(ReKi) :: z(2)=(/-1.,1./) + real(ReKi) :: Gamma0 + + call AddVelocityCurl(Vx=10., yaw_angle=0.1, nVortex=100, R=63., psi_skew=0.2, & + y=y, z=z, Ct_avg=0.7, sigma_d=0.2, Vy_curl=Vy_curl, Vz_curl=Vz_curl, Gamma0=Gamma0) + + if (abs(Vy_curl(1,1)+0.217109)>1e-4) then + print*,'Test fail for vy' + !STOP + endif + if (abs(Vz_curl(2,2)+4.459746e-2)>1e-4) then + print*,'>>> Test fail for vz' + !STOP + endif +end subroutine + + + +!> Weighted average of two angles +subroutine filter_angles2(psi_filt, chi_filt, psi, chi, alpha, alpha_bar) + real(ReKi), intent(inout) :: psi_filt !< filtered azimuth, input at n, output at n+1 + real(ReKi), intent(inout) :: chi_filt !< filtered skew angle + real(ReKi), intent(in) :: psi !< azimuth + real(ReKi), intent(in) :: chi !< skew angle + real(ReKi), intent(in) :: alpha !< filter weight + real(ReKi), intent(in) :: alpha_bar !< 1-alpha + real(ReKi) :: t_filt !< output + real(ReKi) :: x,y + real(ReKi) :: lambda(3,2) + real(ReKi) :: theta_out(3) + real(ReKi) :: lambda_interp(3) + real(ReKi) :: DCM1(3,3) + real(ReKi) :: DCM2(3,3) + real(ReKi) :: DCM_interp(3,3) + integer(intKi) :: errStat ! temporary Error status + character(ErrMsgLen) :: errMsg ! temporary Error message + errStat = ErrID_None + errMsg = "" -end subroutine WD_UpdateStates + !print*,'Input ', psi_filt, chi_filt + ! Compute the DCMs of the skew-related inputs and filtered states: + DCM1 = EulerConstruct( (/ psi_filt, 0.0_ReKi, chi_filt /) ) + DCM2 = EulerConstruct( (/ psi, 0.0_ReKi, chi /) ) + ! Compute the logarithmic map of the DCMs: + CALL DCM_logMap( DCM1, lambda(:,1), errStat, errMsg) + CALL DCM_logMap( DCM2, lambda(:,2), errStat, errMsg) + !Make sure we don't cross a 2pi boundary: + CALL DCM_SetLogMapForInterp( lambda ) + !Interpolate the logarithmic map: + lambda_interp = lambda(:,1)*alpha + lambda(:,2)*alpha_bar + !Convert back to DCM: + DCM_interp = DCM_exp( lambda_interp ) + !Convert back to angles: + theta_out = EulerExtract( DCM_interp ) + !print*,'Output Old',filter_angles(psi_filt, psi, alpha, alpha_bar),filter_angles(chi_filt, chi, alpha, alpha_bar) + psi_filt = theta_out(1) + chi_filt = theta_out(3) + !print*,'Output ', psi_filt, chi_filt, theta_out(2) +end subroutine filter_angles2 + + +!> Converts velocity vectors from an axisymmetric system in radial coordinates to a Cartesian system in Cartesian coordinates +subroutine Axisymmetric2CartesianVel(Vx_axi, Vr_axi, r, y, z, Vx, Vy, Vz) + real(ReKi), dimension(:), intent(in) :: Vx_axi !< Axial velocity, distributed radially (m/s) + real(ReKi), dimension(:), intent(in) :: Vr_axi !< Radial velocity deficit, distributed radially (m/s) + real(ReKi), dimension(:), intent(in) :: r !< Discretization of radial finite-difference grid (m + real(ReKi), dimension(:), intent(in) :: y !< Horizontal discretization of Cartesian grid (m) + real(ReKi), dimension(:), intent(in) :: z !< Nominally vertical discretization of Cartesian grid (m) + real(ReKi), dimension(:,:), intent(inout) :: Vx !< Axial velocity, distributed across the plane (m/s) + real(ReKi), dimension(:,:), intent(inout) :: Vy !< Transverse horizontal velocity, distributed across the plane (m/s) + real(ReKi), dimension(:,:), intent(inout) :: Vz !< Transverse nominally vertical velocity, distributed across the plane (m/s) + integer(IntKi) :: iz, iy, nr, iLow + real(ReKi) :: r_tmp, r_max + real(ReKi) :: Vr, S, C ! Sine and cosine + nr = size(r) + r_max = r(nr) + do iz = 1,size(z) + do iy = 1,size(y) + r_tmp = sqrt(y(iy)**2 + z(iz)**2) + if (EqualRealNos(r_tmp,0.0_ReKi) ) then + S = 0.0_ReKi + C = 0.0_ReKi + else + S=z(iz)/r_tmp + C=y(iy)/r_tmp + endif + r_tmp = min(r_tmp, r_max) ! we can't interpolate beyond r_max + iLow=0 + Vx(iy,iz) = InterpBin(r_tmp, r, Vx_axi, iLow, nr) !( XVal, XAry, YAry, ILo, AryLen ) + Vr = InterpBin(r_tmp, r, Vr_axi, iLow, nr) + Vy(iy,iz) = Vr * C + Vz(iy,iz) = Vr * S + enddo + enddo +end subroutine Axisymmetric2CartesianVel + +!> Converts scalar polar field from an axisymmetric system in radial coordinates to a Cartesian system in Cartesian coordinates +!! Values outside of the max radius are set to 0 +subroutine Axisymmetric2Cartesian(f_axi, r, y, z, f_cart) + real(ReKi), dimension(:), intent(in) :: f_axi !< Polar field, f(r), distributed radially (misc) + real(ReKi), dimension(:), intent(in) :: r !< Discretization of radial finite-difference grid (m + real(ReKi), dimension(:), intent(in) :: y !< Horizontal discretization of Cartesian grid (m) + real(ReKi), dimension(:), intent(in) :: z !< Nominally vertical discretization of Cartesian grid (m) + real(ReKi), dimension(:,:), intent(inout) :: f_cart !< Cartesian field, f(x,y) (misc) + integer(IntKi) :: iz, iy, nr, iLow + real(ReKi) :: r_tmp, r_max + nr = size(r) + r_max = r(nr) + do iz = 1,size(z) + do iy = 1,size(y) + r_tmp = sqrt(y(iy)**2 + z(iz)**2) + if (r_tmp<=r_max) then + iLow=0 + f_cart(iy,iz) = InterpBin(r_tmp, r, f_axi, iLow, nr) !( XVal, XAry, YAry, ILo, AryLen ) + else + f_cart(iy,iz) = 0.0_ReKi + endif + enddo + enddo +end subroutine Axisymmetric2Cartesian + +!> Converts velocity vector Vx from an axisymmetric system in radial coordinates to a Cartesian system in Cartesian coordinates +subroutine Axisymmetric2CartesianVx(Vx_axi, r, y, z, Vx) + real(ReKi), dimension(:), intent(in) :: Vx_axi !< Axial velocity, distributed radially (m/s) + real(ReKi), dimension(:), intent(in) :: r !< Discretization of radial finite-difference grid (m + real(ReKi), dimension(:), intent(in) :: y !< Horizontal discretization of Cartesian grid (m) + real(ReKi), dimension(:), intent(in) :: z !< Nominally vertical discretization of Cartesian grid (m) + real(ReKi), dimension(:,:), intent(inout) :: Vx !< Axial velocity, distributed across the plane (m/s) + integer(IntKi) :: iz, iy, nr, iLow + real(ReKi) :: r_tmp, r_max + real(ReKi) :: Vr, S, C ! Sine and cosine + nr = size(r) + r_max = r(nr) + do iz = 1,size(z) + do iy = 1,size(y) + r_tmp = sqrt(y(iy)**2 + z(iz)**2) + r_tmp = min(r_tmp, r_max) ! we can't interpolate beyond r_max + iLow=0 + Vx(iy,iz) = InterpBin(r_tmp, r, Vx_axi, iLow, nr) !( XVal, XAry, YAry, ILo, AryLen ) + enddo + enddo +end subroutine Axisymmetric2CartesianVx + +!> Filters the velocity using a box filter +subroutine FilterVx(Vx, nf) + real(ReKi), dimension(:,:), intent(inout) :: Vx !< Axial velocity, distributed across the plane (m/s) + integer(IntKi), intent(in) :: nf ! The filter width (number of grid points) + real(ReKi), dimension(size(Vx,1),size(Vx,2)) :: Vx_filt !< Axial velocity, distributed across the plane (m/s) + integer(IntKi) :: iz, iy, n1, n2 + + ! No filter if filter width is 0 + if(nf==0) return + + ! Initialize the filtered vars + Vx_filt = 0.0_ReKi + + do iz = 1+nf, size(Vx,2) - nf + do iy = 1+nf, size(Vx,1) - nf + + do n1=-nf,nf + + do n2=-nf,nf + + Vx_filt(iy,iz) = Vx_filt(iy,iz) + Vx(iy + n1, iz + n2) + + enddo + + enddo + enddo + enddo + + Vx = Vx_filt / ((2. * nf +1)**2 ) + +end subroutine FilterVx + + +subroutine WD_TEST_Axi2Cart() + real(ReKi) :: r(4)=(/0.,1.,2.,3./) +! real(ReKi) :: y(4)=(/-1.,0.,1.5,2./) +! real(ReKi) :: z(5)=(/-2.5,-1.5,0.,1.5,2./) + real(ReKi) :: y(4)=(/0.,1. ,1.5, 2./) + real(ReKi) :: z(5)=(/0.,0.5,1. ,1.5,2./) + real(ReKi) :: Vr_axi(4) + real(ReKi) :: Vx_axi(4) + real(ReKi) :: Vx(4,5)=0.0_ReKi + real(ReKi) :: Vy(4,5)=0.0_ReKi + real(ReKi) :: Vz(4,5)=0.0_ReKi + integer :: i,j + real(ReKi) :: Vr, r_tmp + Vr_axi=4._ReKi*r + Vx_axi=3._ReKi*r + call Axisymmetric2CartesianVel(Vx_axi, Vr_axi, r, y, z, Vx, Vy, Vz) + + do i = 1,size(y) + do j = 1,size(z) + r_tmp = sqrt(y(i)**2+z(j)**2) + Vr = sqrt(Vy(i,j)**2 + Vz(i,j)**2) + if (abs(Vr-4*r_tmp)>1e-3) then + print*,'>>Error Axi2Cart Vr',Vr,4*r_tmp + STOP + endif + if (abs(Vx(i,j)-3*r_tmp)>1e-3) then + print*,'>>Error Axi2Cart Vx',Vx(i,j),3*r_tmp + STOP + endif + enddo + enddo +end subroutine + + + !---------------------------------------------------------------------------------------------------------------------------------- !> Routine for computing outputs, used in both loose and tight coupling. !! This subroutine is used to compute the output channels (motions and loads) and place them in the WriteOutput() array. @@ -894,6 +1482,7 @@ subroutine WD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ) ! All of the calculated output channels are placed into the m%AllOuts(:), while the channels selected for outputs are ! placed in the y%WriteOutput(:) array. !.................................................................................................................................. + use VTK ! REAL(DbKi), INTENT(IN ) :: t !< Current simulation time in seconds TYPE(WD_InputType), INTENT(IN ) :: u !< Inputs at Time t @@ -910,15 +1499,20 @@ subroutine WD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ) integer, parameter :: indx = 1 - integer(intKi) :: n, i + integer(intKi) :: n, i, iy, iz, maxPln integer(intKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 character(*), parameter :: RoutineName = 'WD_CalcOutput' real(ReKi) :: correction(3) + real(ReKi) :: C, S, dvdr, dvdtheta_r, R, r_tmp + character(1024) :: Filename + type(VTK_Misc) :: mvtk + real(ReKi), dimension(3) :: dx errStat = ErrID_None errMsg = "" - + n = nint(t/p%DT_low) + maxPln = min(n+1,p%NumPlanes-1) ! Check if we are fully initialized if ( OtherState%firstPass ) then @@ -936,18 +1530,27 @@ subroutine WD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ) y%p_plane (:,i) = u%p_hub(:) + y%x_plane(i)*u%xhat_disk(:) + correction y%xhat_plane(:,i) = u%xhat_disk(:) - ! NOTE: Since we are in firstPass=T, then xd%Vx_wake is already set to zero, so just pass that into WakeDiam y%D_wake(i) = WakeDiam( p%Mod_WakeDiam, p%NumRadii, p%dr, p%r, xd%Vx_wake(:,i), u%Vx_wind_disk, u%D_rotor, p%C_WakeDiam) end do ! Initialze Vx_wake; Vr_wake is already initialized to zero, so, we don't need to do that here. - call NearWakeCorrection( u%Ct_azavg, u%Vx_rel_disk, p, m, y%Vx_wake(:,0), u%D_rotor, errStat, errMsg ) + call NearWakeCorrection( u%Ct_azavg, u%Cq_azavg, u%Vx_rel_disk, p, m, y%Vx_wake(:,0), m%Vt_wake, u%D_rotor, errStat, errMsg ) if (errStat > AbortErrLev) return y%Vx_wake(:,1) = y%Vx_wake(:,0) + + ! States approx + ! NOTE: can't modify xd + !xd%psi_skew_filt = u%psi_skew + !xd%chi_skew_filt = u%chi_skew + !xd%Vx_wind_disk_filt(0) = u%Vx_wind_disk + !xd%D_rotor_filt (0) = u%D_rotor + !xd%Ct_azavg_filt (:) = u%Ct_azavg(:) + ! Misc approx + m%Ct_avg = get_Ctavg(p%r, u%Ct_azavg, u%D_rotor) + m%GammaCurl = u%D_Rotor/2. * u%Vx_wind_disk * m%Ct_avg * sin(u%chi_skew) * cos(u%chi_skew) - return else y%x_plane = xd%x_plane @@ -961,6 +1564,109 @@ subroutine WD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ) end do end if + + if (p%Mod_Wake == Mod_Wake_Polar) then + ! Convert to Cartesian + do i = 0, maxPln + call Axisymmetric2CartesianVel(y%Vx_wake(:,i), y%Vr_wake(:,i), p%r, p%y, p%z, y%Vx_wake2(:,:,i), y%Vy_wake2(:,:,i), y%Vz_wake2(:,:,i)) + enddo + if (p%OutAllPlanes) then + do i = 0, maxPln + call Axisymmetric2Cartesian(m%vt_amb(:,i), p%r, p%y, p%z, m%vt_amb2(:,:,i)) + call Axisymmetric2Cartesian(m%vt_shr(:,i), p%r, p%y, p%z, m%vt_shr2(:,:,i)) + call Axisymmetric2Cartesian(m%vt_tot(:,i), p%r, p%y, p%z, m%vt_tot2(:,:,i)) + enddo + endif + else if (p%Mod_Wake == Mod_Wake_Cartesian .or. p%Mod_Wake == Mod_Wake_Curl) then + do i = 0, maxPln + y%Vx_wake2(:,:,i) = xd%Vx_wake2(:,:,i) + y%Vy_wake2(:,:,i) = xd%Vy_wake2(:,:,i) + y%Vz_wake2(:,:,i) = xd%Vz_wake2(:,:,i) + enddo + endif ! Curl or Polar + + ! --- WAT - Compute k_mt and add turbulence + if ( p%WAT ) then + R = u%D_Rotor /2 + do i = 1,maxPln + if ( EqualRealNos( xd%Vx_wind_disk_filt(i), 0.0_ReKi ) ) then + y%WAT_k_mt(:,:,i) = 0.0_ReKi + else + do iz = -p%NumRadii+1, p%NumRadii-1 + do iy = -p%NumRadii+1, p%NumRadii-1 + ! Polar gradients + r_tmp = sqrt(p%y(iy)**2 + p%z(iz)**2) + if (EqualRealNos(r_tmp,0.0_ReKi) ) then + S = 0.0_ReKi + C = 0.0_ReKi + dvdtheta_r = 0.0_ReKi + else + S=p%z(iz)/r_tmp ! Sine + C=p%y(iy)/r_tmp ! Cosine + dvdtheta_r = (m%dvx_dy(iy,iz,i) * (-p%z(iz)) + m%dvx_dz(iy,iz,i) * p%y(iy)) / r_tmp + endif + dvdr = m%dvx_dy(iy,iz,i) * C + m%dvx_dz(iy,iz,i) * S + ! Calculate scaling factor k_mt for wake-added Turbulence + y%WAT_k_mt(iy,iz,i) = p%WAT_k_Def * abs(1 - ((xd%Vx_wind_disk_filt(i)+y%Vx_wake2(iy,iz,i))/xd%Vx_wind_disk_filt(i)) ) & + + p%WAT_k_Grad/xd%Vx_wind_disk_filt(i) * R * ( abs(dvdr) + abs(dvdtheta_r) ) + end do ! iy + end do ! iz + endif + end do ! i, plane + + end if + + ! --- VTK outputs per plane + if (p%OutAllPlanes) then + call vtk_misc_init(mvtk) + call set_vtk_binary_format(.false., mvtk) + if ( OtherState%firstPass ) then + call MKDIR(p%OutFileVTKDir) + endif + do i = 0, min(n-1,p%NumPlanes-1), 1 +! if (EqualRealNos(t,0.0_DbKi) ) then +! write(Filename,'(A,I4.4,A)') trim(p%OutFileVTKDir)//'/PlaneOutputsAtPlane_',i,'_Init.vtk' +! else +! write(Filename,'(A,I4.4,A,I9.9,A)') trim(p%OutFileVTKDir)//'PlaneOutputsAtPlane_',i,'_Time_',int(t*10),'.vtk' +! endif +! if ( vtk_new_ascii_file(trim(filename),'vel',mvtk) ) then +! dx(1) = 0.0 +! dx(2) = p%dr +! dx(3) = p%dr +! call vtk_dataset_structured_points((/xd%p_plane(1,i),xd%p_plane(2,i)-dx*p%NumRadii, xd%p_plane(3,i)-dx*p%NumRadii /),dx,(/1,p%NumRadii*2-1,p%NumRadii*2-1/),mvtk) +! call vtk_point_data_init(mvtk) +! call vtk_point_data_scalar(xd%Vx_wake2(:,:,i),'Vx',mvtk) +! call vtk_point_data_scalar(xd%Vy_wake2(:,:,i),'Vy',mvtk) +! call vtk_point_data_scalar(xd%Vz_wake2(:,:,i),'Vz',mvtk) +! call vtk_close_file(mvtk) +! endif + + ! --- Output Plane "per time" + write(Filename,'(A,I9.9,A,I4.4,A)') trim(p%OutFileVTKDir)// PathSep //trim(p%OutFileRoot)//'.WT'//trim(num2lstr(p%TurbNum))//'.PlaneAtTime_',int(t*100),'_Plane_',i,'.vtk' + if ( vtk_new_ascii_file(trim(filename),'vel',mvtk) ) then + dx(1) = 0.0 + dx(2) = p%dr + dx(3) = p%dr + call vtk_dataset_structured_points((/xd%p_plane(1,i),-dx*p%NumRadii,-dx*p%NumRadii/),dx,(/1,p%NumRadii*2-1,p%NumRadii*2-1/),mvtk) + call vtk_point_data_init(mvtk) + call vtk_point_data_scalar(xd%Vx_wake2(:,:,i),'Vx',mvtk) + call vtk_point_data_scalar(xd%Vy_wake2(:,:,i),'Vy',mvtk) + call vtk_point_data_scalar(xd%Vz_wake2(:,:,i),'Vz',mvtk) + call vtk_point_data_scalar(m%vt_amb2(:,:,i),'vt_amb2', mvtk) + call vtk_point_data_scalar(m%vt_shr2(:,:,i),'vt_shr2', mvtk) + call vtk_point_data_scalar(m%vt_tot2(:,:,i),'vt_tot2', mvtk) + + if (p%Mod_Wake == Mod_Wake_Cartesian .or. p%Mod_Wake == Mod_Wake_Curl) then + call vtk_point_data_scalar(m%dvx_dy(:,:,i),'dvx_dy', mvtk) + call vtk_point_data_scalar(m%dvx_dz(:,:,i),'dvx_dz', mvtk) + endif + if (p%WAT) then + call vtk_point_data_scalar(y%WAT_k_mt(:,:,i),'k_mt', mvtk) + endif + call vtk_close_file(mvtk) + endif + enddo ! loop on planes + endif end subroutine WD_CalcOutput @@ -1026,6 +1732,8 @@ subroutine InitStatesWithInputs(numPlanes, numRadii, u, p, xd, m, errStat, errMs do i = 0, 1 xd%x_plane (i) = u%Vx_rel_disk*real(i,ReKi)*real(p%DT_low,ReKi) xd%YawErr_filt (i) = u%YawErr + xd%psi_skew_filt = u%psi_skew + xd%chi_skew_filt = u%chi_skew correction = correction + GetYawCorrection(u%YawErr, u%xhat_disk, xd%x_plane(i), p, errStat2, errMsg2) call SetErrStat(errStat2, errMsg2, errStat, errMsg, RoutineName) @@ -1048,10 +1756,11 @@ subroutine InitStatesWithInputs(numPlanes, numRadii, u, p, xd, m, errStat, errMs xd%Vx_rel_disk_filt = u%Vx_rel_disk - ! Initialze Ct_azavg_filt and Vx_wake; Vr_wake is already initialized to zero, so, we don't need to do that here. - xd%Ct_azavg_filt (:) = u%Ct_azavg(:) + ! Initialze Ct_azavg_filt, Cq_azavg_filt, and Vx_wake; Vr_wake is already initialized to zero, so, we don't need to do that here. + xd%Ct_azavg_filt (:) = u%Ct_azavg(:) + xd%Cq_azavg_filt (:) = u%Cq_azavg(:) - call NearWakeCorrection( xd%Ct_azavg_filt, xd%Vx_rel_disk_filt, p, m, xd%Vx_wake(:,0), xd%D_rotor_filt(0), errStat, errMsg ) + call NearWakeCorrection( xd%Ct_azavg_filt, xd%Cq_azavg_filt, xd%Vx_rel_disk_filt, p, m, xd%Vx_wake(:,0), m%Vt_wake, xd%D_rotor_filt(0), errStat, errMsg ) xd%Vx_wake(:,1) = xd%Vx_wake(:,0) end subroutine InitStatesWithInputs diff --git a/modules/wakedynamics/src/WakeDynamics_Registry.txt b/modules/wakedynamics/src/WakeDynamics_Registry.txt index e5e3b7831..c43ed6866 100644 --- a/modules/wakedynamics/src/WakeDynamics_Registry.txt +++ b/modules/wakedynamics/src/WakeDynamics_Registry.txt @@ -18,11 +18,15 @@ param WakeDynamics/WD - INTEGER WakeDiamMod_RotDiam param ^ - INTEGER WakeDiamMod_Velocity - 2 - "Wake diameter calculation model: velocity-based" - param ^ - INTEGER WakeDiamMod_MassFlux - 3 - "Wake diameter calculation model: mass-flux based" - param ^ - INTEGER WakeDiamMod_MtmFlux - 4 - "Wake diameter calculation model: momentum-flux based" - +param ^ - INTEGER Mod_Wake_Polar - 1 - "Wake model" - +param ^ - INTEGER Mod_Wake_Curl - 2 - "Wake model" - +param ^ - INTEGER Mod_Wake_Cartesian - 3 - "Wake model" - # ..... InputFile Data ....................................................................................................... typedef ^ WD_InputFileType ReKi dr - - - "Radial increment of radial finite-difference grid [>0.0]" m typedef ^ WD_InputFileType IntKi NumRadii - - - "Number of radii in the radial finite-difference grid [>=2]" - typedef ^ WD_InputFileType IntKi NumPlanes - - - "Number of wake planes [>=2]" - +typedef ^ WD_InputFileType IntKi Mod_Wake - - - "Switch between wake formulations 1=Polar, 2=Cartesian, 3=Curl" - typedef ^ WD_InputFileType ReKi f_c - - - "Cut-off frequency of the low-pass time-filter for the wake advection, deflection, and meandering model [>0.0]" Hz typedef ^ WD_InputFileType ReKi C_HWkDfl_O - - - "Calibrated parameter in the correction for wake deflection defining the horizontal offset at the rotor" m typedef ^ WD_InputFileType ReKi C_HWkDfl_OY - - - "Calibrated parameter in the correction for wake deflection defining the horizontal offset at the rotor scaled with yaw error" m/rad @@ -41,6 +45,18 @@ typedef ^ WD_InputFileType ReKi C_vShr_FMin - - typedef ^ WD_InputFileType ReKi C_vShr_Exp - - - "Calibrated parameter in the eddy viscosity filter function for the shear layer defining the exponent in the exponential region [> 0.0]" - typedef ^ WD_InputFileType IntKi Mod_WakeDiam - - - "Wake diameter calculation model {1: rotor diameter, 2: velocity-based, 3: mass-flux based, 4: momentum-flux based} [DEFAULT=1]" - typedef ^ WD_InputFileType ReKi C_WakeDiam - - - "Calibrated parameter for wake diameter calculation [>0.0 and <1.0] [unused for Mod_WakeDiam=1]" - +# curled-wake inputs +typedef ^ WD_InputFileType Logical Swirl - - - "Switch to add swirl [only used if Mod_Wake=2 or 2]" - +typedef ^ WD_InputFileType ReKi k_VortexDecay - - - "Vortex decay constant for curl" - +typedef ^ WD_InputFileType ReKi sigma_D - - - "The width of the Gaussian vortices used for the curled wake model divided by diameter" - +typedef ^ WD_InputFileType IntKi NumVortices - - - "The number of vortices used for the curled wake model" - +typedef ^ WD_InputFileType IntKi FilterInit - - - "Switch to filter the initial wake plane deficit and select the number of grid points for the filter {0: no filter, 1: filter of size 1} or DEFAULT [DEFAULT=0: if Mod_Wake is 1 or 3, or DEFAULT=2: if Mod_Wwake is 2] (switch)" +typedef ^ WD_InputFileType ReKi k_vCurl - - - "Calibrated parameter for the eddy viscosity in curled-wake model [>=0.0]" - +typedef ^ WD_InputFileType Logical OutAllPlanes - - - "Output all planes" - +# wake added turbulence (WAT) inputs +typedef ^ WD_InputFileType LOGICAL WAT - - - "Switch for turning on and off wake-added turbulence" - +typedef ^ WD_InputFileType ReKi WAT_k_Def - - - "Calibrated parameter for the influence of the wake deficit in the wake-added Turbulence (-) [>=0.0] or DEFAULT [DEFAULT=0.6]" - +typedef ^ WD_InputFileType ReKi WAT_k_Grad - - - "Calibrated parameter for the influence of the radial velocity gradient of the wake deficit in the wake-added Turbulence (-) [>=0.0] or DEFAULT [DEFAULT=0.35]" - # ..... Initialization data ....................................................................................................... @@ -48,6 +64,7 @@ typedef ^ WD_InputFileType ReKi C_WakeDiam - - # e.g., the name of the input file, the file root name, etc. typedef ^ InitInputType WD_InputFileType InputFileData - - - "FAST.Farm input-file data for wake dynamics" - typedef ^ InitInputType IntKi TurbNum - 0 - "Turbine ID number (start with 1; end with number of turbines)" - +typedef ^ InitInputType CHARACTER(1024) OutFileRoot - - - "The root name derived from the primary FAST.Farm input file" - # Define outputs from the initialization routine here: @@ -62,17 +79,23 @@ typedef ^ ContinuousStateType ReKi DummyContState - - - "Re # Define discrete (nondifferentiable) states here: typedef ^ DiscreteStateType ReKi xhat_plane {:}{:} - - "Orientations of wake planes, normal to wake planes" - +typedef ^ DiscreteStateType ReKi YawErr_filt {:} - - "Time-filtered nacelle-yaw error at the wake planes" rad +typedef ^ DiscreteStateType ReKi psi_skew_filt - - - "Time-filtered azimuth angle from skew vertical axis" rad +typedef ^ DiscreteStateType ReKi chi_skew_filt - - - "Time-filtered inflow skew angle" rad +typedef ^ DiscreteStateType ReKi V_plane_filt {:}{:} - - "Time-filtered advection, deflection, and meandering velocity of wake planes" m/s typedef ^ DiscreteStateType ReKi p_plane {:}{:} - - "Center positions of wake planes" m typedef ^ DiscreteStateType ReKi x_plane {:} - - "Downwind distance from rotor to each wake plane" m typedef ^ DiscreteStateType ReKi Vx_wake {:}{:} - - "Axial wake velocity deficit at wake planes, distributed radially" m/s typedef ^ DiscreteStateType ReKi Vr_wake {:}{:} - - "Radial wake velocity deficit at wake planes, distributed radially" m/s -typedef ^ DiscreteStateType ReKi V_plane_filt {:}{:} - - "Time-filtered advection, deflection, and meandering velocity of wake planes" m/s +typedef ^ DiscreteStateType ReKi Vx_wake2 {:}{:}{:} - - "Axial wake velocity deficit at wake planes, distributed radially" m/s +typedef ^ DiscreteStateType ReKi Vy_wake2 {:}{:}{:} - - "Longitudinal wake velocity deficit at wake planes, distributed radially" m/s +typedef ^ DiscreteStateType ReKi Vz_wake2 {:}{:}{:} - - "Vertical wake velocity deficit at wake planes, distributed radially" m/s typedef ^ DiscreteStateType ReKi Vx_wind_disk_filt {:} - - "Time-filtered rotor-disk-averaged ambient wind speed of wake planes, normal to planes" m/s typedef ^ DiscreteStateType ReKi TI_amb_filt {:} - - "Time-filtered ambient turbulence intensity of wind at wake planes" - typedef ^ DiscreteStateType ReKi D_rotor_filt {:} - - "Time-filtered rotor diameter associated with each wake plane" m typedef ^ DiscreteStateType ReKi Vx_rel_disk_filt - - - "Time-filtered rotor-disk-averaged relative wind speed (ambient + deficits + motion), normal to disk" m/s typedef ^ DiscreteStateType ReKi Ct_azavg_filt {:} - - "Time-filtered azimuthally averaged thrust force coefficient (normal to disk), distributed radially" - -typedef ^ DiscreteStateType ReKi YawErr_filt {:} - - "Time-filtered nacelle-yaw error at the wake planes" rad +typedef ^ DiscreteStateType ReKi Cq_azavg_filt {:} - - "Time-filtered azimuthally averaged torque coefficient (normal to disk), distributed radially" - # Define constraint states here: typedef ^ ConstraintStateType ReKi DummyConstrState - - - "Remove this variable if you have constraint states" - @@ -83,17 +106,29 @@ typedef ^ OtherStateType LOGICAL firstPass - # ..... 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 dvdr {:} - - "" -typedef ^ MiscVarType ReKi dvtdr {:} - - "" -typedef ^ MiscVarType ReKi vt_tot {:}{:} - - "" -typedef ^ MiscVarType ReKi vt_amb {:}{:} - - "" -typedef ^ MiscVarType ReKi vt_shr {:}{:} - - "" +typedef ^ MiscVarType ReKi dvtdr {:} - - "Radial gradient of total eddy viscosity (nr)" +typedef ^ MiscVarType ReKi vt_tot {:}{:} - - "Polar total eddy viscosity (nr,np)" +typedef ^ MiscVarType ReKi vt_amb {:}{:} - - "Polar ambient eddy viscosity (nr,np)" +typedef ^ MiscVarType ReKi vt_shr {:}{:} - - "Polar shear eddy viscosity (nr,np)" +typedef ^ MiscVarType ReKi vt_tot2 {:}{:}{:} - - "Cartesian total eddy viscosity (ny,nz,np)" +typedef ^ MiscVarType ReKi vt_amb2 {:}{:}{:} - - "Cartesian ambient eddy viscosity (ny,nz,np)" +typedef ^ MiscVarType ReKi vt_shr2 {:}{:}{:} - - "Cartesian shear eddy viscosity (ny,nz,np)" +typedef ^ MiscVarType ReKi dvx_dy {:}{:}{:} - - "Cartesian velocity gradient dVx/dy" +typedef ^ MiscVarType ReKi dvx_dz {:}{:}{:} - - "Cartesian velocity gradient dVx/dz" +typedef ^ MiscVarType ReKi nu_dvx_dy {:}{:} - - "Product of total eddy viscosity and gradient" +typedef ^ MiscVarType ReKi nu_dvx_dz {:}{:} - - "Product of total eddy viscosity and gradient" +typedef ^ MiscVarType ReKi dnuvx_dy {:}{:} - - "Gradient of nu_dvx_dy wrt y" +typedef ^ MiscVarType ReKi dnuvx_dz {:}{:} - - "Gradient of nu_dvx_dz wrt z" typedef ^ MiscVarType ReKi a {:} - - "" typedef ^ MiscVarType ReKi b {:} - - "" typedef ^ MiscVarType ReKi c {:} - - "" typedef ^ MiscVarType ReKi d {:} - - "" typedef ^ MiscVarType ReKi r_wake {:} - - "" typedef ^ MiscVarType ReKi Vx_high {:} - - "" +typedef ^ MiscVarType ReKi Vx_polar {:} - - "Vx as function of r for Cartesian implementation" +typedef ^ MiscVarType ReKi Vt_wake {:} - - "Vr as function of r for Cartesian implementation" +typedef ^ MiscVarType ReKi GammaCurl - - - "Circulation used in Curled wake model" +typedef ^ MiscVarType ReKi Ct_avg - - - "Circulation used in Curled wake model" # ..... Parameters ................................................................................................................ @@ -105,6 +140,13 @@ typedef ^ ParameterType IntKi NumPlanes - - - "Number of wak typedef ^ ParameterType IntKi NumRadii - - - "Number of radii in the radial finite-difference grid" - typedef ^ ParameterType ReKi dr - - - "Radial increment of radial finite-difference grid" m typedef ^ ParameterType ReKi r {:} - - "Discretization of radial finite-difference grid" m +typedef ^ ParameterType ReKi y {:} - - "Horizontal discretization of each wake plane (size ny=2nr-1)" m +typedef ^ ParameterType ReKi z {:} - - "Nomically-vertical discretization of each wake plane (size nz=2nr-1)" m +typedef ^ ParameterType IntKi Mod_Wake - - - "Switch between wake formulations 1=Polar, 2=Curl, 3=Cartesian" - +typedef ^ ParameterType Logical Swirl - - - "Switch to add swirl [only used if Mod_Wake=2 or 2]" - +typedef ^ ParameterType ReKi k_VortexDecay - - - "Vortex decay constant for curl" - +typedef ^ ParameterType ReKi sigma_D - - 0.2 "The width of the Gaussian vortices used for the curled wake model divided by diameter" - +typedef ^ ParameterType IntKi NumVortices - - 100 "The number of vortices used for the curled wake model" - typedef ^ ParameterType ReKi filtParam - - - "Low-pass time-filter parameter, with a value between 0 (minimum filtering) and 1 (maximum filtering) (exclusive)" - typedef ^ ParameterType ReKi oneMinusFiltParam - - - "1.0 - filtParam" - typedef ^ ParameterType ReKi C_HWkDfl_O - - - "Calibrated parameter in the correction for wake deflection defining the horizontal offset at the rotor" m @@ -124,10 +166,22 @@ typedef ^ ParameterType ReKi k_vAmb - - - "Calibrated pa typedef ^ ParameterType ReKi k_vShr - - - "Calibrated parameter for the influence of the shear layer in the eddy viscosity" - typedef ^ ParameterType IntKi Mod_WakeDiam - - - "Wake diameter calculation model" - typedef ^ ParameterType ReKi C_WakeDiam - - - "Calibrated parameter for wake diameter calculation" - - +typedef ^ ParameterType IntKi FilterInit - - - "Switch to filter the initial wake plane deficit and select the number of grid points for the filter {0: no filter, 1: filter of size 1} or DEFAULT [DEFAULT=0: if Mod_Wake is 1 or 3, or DEFAULT=2: if Mod_Wwake is 2] (switch)" +typedef ^ ParameterType ReKi k_vCurl - - - "Calibrated parameter for the eddy viscosity in curled-wake model [>=0.0]" - +typedef ^ ParameterType Logical OutAllPlanes - - - "Output all planes" - +typedef ^ ParameterType CHARACTER(1024) OutFileRoot - - - "The root name derived from the primary FAST.Farm input file" - +typedef ^ ParameterType CHARACTER(1024) OutFileVTKDir - - - "The parent directory for all VTK files written by WD" - +typedef ^ ParameterType IntKi TurbNum - 0 - "Turbine ID number (start with 1; end with number of turbines)" - +# wake added turbulence (WAT) parameters +typedef ^ ParameterType LOGICAL WAT - - - "Switch for turning on and off wake-added turbulence" - +typedef ^ ParameterType ReKi WAT_k_Def - - - "Calibrated parameter for the influence of the wake deficit in the wake-added Turbulence (-) [>=0.0] or DEFAULT [DEFAULT=0.6]" - +typedef ^ ParameterType ReKi WAT_k_Grad - - - "Calibrated parameter for the influence of the radial velocity gradient of the wake deficit in the wake-added Turbulence (-) [>=0.0] or DEFAULT [DEFAULT=0.35]" - # ..... Inputs .................................................................................................................... # Define inputs that are contained on the mesh here: typedef ^ InputType ReKi xhat_disk {3} - - "Orientation of rotor centerline, normal to disk" - +typedef ^ InputType ReKi YawErr - - - "Nacelle-yaw error at the wake planes" rad +typedef ^ InputType ReKi psi_skew - - - "Azimuth angle from the nominally vertical axis in the disk plane to the vector about which the inflow skew angle is defined" rad +typedef ^ InputType ReKi chi_skew - - - "Inflow skew angle" rad typedef ^ InputType ReKi p_hub {3} - - "Center position of hub" m typedef ^ InputType ReKi V_plane {:}{:} - - "Advection, deflection, and meandering velocity of wake planes" m/s typedef ^ InputType ReKi Vx_wind_disk - - - "Rotor-disk-averaged ambient wind speed, normal to planes" m/s @@ -135,7 +189,7 @@ typedef ^ InputType ReKi TI_amb - - typedef ^ InputType ReKi D_rotor - - - "Rotor diameter" m typedef ^ InputType ReKi Vx_rel_disk - - - "Rotor-disk-averaged relative wind speed (ambient + deficits + motion), normal to disk" m/s typedef ^ InputType ReKi Ct_azavg {:} - - "Azimuthally averaged thrust force coefficient (normal to disk), distributed radially" - -typedef ^ InputType ReKi YawErr - - - "Nacelle-yaw error at the wake planes" rad +typedef ^ InputType ReKi Cq_azavg {:} - - "Azimuthally averaged torque coefficient (normal to disk), distributed radially" - # ..... Outputs ................................................................................................................... @@ -144,6 +198,10 @@ typedef ^ OutputType ReKi xhat_plane {:}{:} - typedef ^ OutputType ReKi p_plane {:}{:} - - "Center positions of wake planes" m typedef ^ OutputType ReKi Vx_wake {:}{:} - - "Axial wake velocity deficit at wake planes, distributed radially" m/s typedef ^ OutputType ReKi Vr_wake {:}{:} - - "Radial wake velocity deficit at wake planes, distributed radially" m/s +typedef ^ OutputType ReKi Vx_wake2 {:}{:}{:} - - "Axial wake velocity deficit at wake planes, distributed across the plane" m/s +typedef ^ OutputType ReKi Vy_wake2 {:}{:}{:} - - "Transverse horizontal wake velocity deficit at wake planes, distributed across the plane" m/s +typedef ^ OutputType ReKi Vz_wake2 {:}{:}{:} - - "Transverse nominally vertical wake velocity deficit at wake planes, distributed across the plane" m/s typedef ^ OutputType ReKi D_wake {:} - - "Wake diameters at wake planes" m typedef ^ OutputType ReKi x_plane {:} - - "Downwind distance from rotor to each wake plane" m +typedef ^ OutputType ReKi WAT_k_mt {:}{:}{:} - - "Scaling factor k_mt(iP,y,z) for wake-added turbulence" - diff --git a/modules/wakedynamics/src/WakeDynamics_Types.f90 b/modules/wakedynamics/src/WakeDynamics_Types.f90 index b5a9c60fe..72d92c908 100644 --- a/modules/wakedynamics/src/WakeDynamics_Types.f90 +++ b/modules/wakedynamics/src/WakeDynamics_Types.f90 @@ -37,11 +37,15 @@ MODULE WakeDynamics_Types INTEGER(IntKi), PUBLIC, PARAMETER :: WakeDiamMod_Velocity = 2 ! Wake diameter calculation model: velocity-based [-] INTEGER(IntKi), PUBLIC, PARAMETER :: WakeDiamMod_MassFlux = 3 ! Wake diameter calculation model: mass-flux based [-] INTEGER(IntKi), PUBLIC, PARAMETER :: WakeDiamMod_MtmFlux = 4 ! Wake diameter calculation model: momentum-flux based [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Mod_Wake_Polar = 1 ! Wake model [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Mod_Wake_Curl = 2 ! Wake model [-] + INTEGER(IntKi), PUBLIC, PARAMETER :: Mod_Wake_Cartesian = 3 ! Wake model [-] ! ========= WD_InputFileType ======= TYPE, PUBLIC :: WD_InputFileType REAL(ReKi) :: dr !< Radial increment of radial finite-difference grid [>0.0] [m] INTEGER(IntKi) :: NumRadii !< Number of radii in the radial finite-difference grid [>=2] [-] INTEGER(IntKi) :: NumPlanes !< Number of wake planes [>=2] [-] + INTEGER(IntKi) :: Mod_Wake !< Switch between wake formulations 1=Polar, 2=Cartesian, 3=Curl [-] REAL(ReKi) :: f_c !< Cut-off frequency of the low-pass time-filter for the wake advection, deflection, and meandering model [>0.0] [Hz] REAL(ReKi) :: C_HWkDfl_O !< Calibrated parameter in the correction for wake deflection defining the horizontal offset at the rotor [m] REAL(ReKi) :: C_HWkDfl_OY !< Calibrated parameter in the correction for wake deflection defining the horizontal offset at the rotor scaled with yaw error [m/rad] @@ -60,12 +64,23 @@ MODULE WakeDynamics_Types REAL(ReKi) :: C_vShr_Exp !< Calibrated parameter in the eddy viscosity filter function for the shear layer defining the exponent in the exponential region [> 0.0] [-] INTEGER(IntKi) :: Mod_WakeDiam !< Wake diameter calculation model {1: rotor diameter, 2: velocity-based, 3: mass-flux based, 4: momentum-flux based} [DEFAULT=1] [-] REAL(ReKi) :: C_WakeDiam !< Calibrated parameter for wake diameter calculation [>0.0 and <1.0] [unused for Mod_WakeDiam=1] [-] + LOGICAL :: Swirl !< Switch to add swirl [only used if Mod_Wake=2 or 2] [-] + REAL(ReKi) :: k_VortexDecay !< Vortex decay constant for curl [-] + REAL(ReKi) :: sigma_D !< The width of the Gaussian vortices used for the curled wake model divided by diameter [-] + INTEGER(IntKi) :: NumVortices !< The number of vortices used for the curled wake model [-] + INTEGER(IntKi) :: FilterInit !< Switch to filter the initial wake plane deficit and select the number of grid points for the filter {0: no filter, 1: filter of size 1} or DEFAULT [DEFAULT=0: if Mod_Wake is 1 or 3, or DEFAULT=2: if Mod_Wwake is 2] (switch) [-] + REAL(ReKi) :: k_vCurl !< Calibrated parameter for the eddy viscosity in curled-wake model [>=0.0] [-] + LOGICAL :: OutAllPlanes !< Output all planes [-] + LOGICAL :: WAT !< Switch for turning on and off wake-added turbulence [-] + REAL(ReKi) :: WAT_k_Def !< Calibrated parameter for the influence of the wake deficit in the wake-added Turbulence (-) [>=0.0] or DEFAULT [DEFAULT=0.6] [-] + REAL(ReKi) :: WAT_k_Grad !< Calibrated parameter for the influence of the radial velocity gradient of the wake deficit in the wake-added Turbulence (-) [>=0.0] or DEFAULT [DEFAULT=0.35] [-] END TYPE WD_InputFileType ! ======================= ! ========= WD_InitInputType ======= TYPE, PUBLIC :: WD_InitInputType TYPE(WD_InputFileType) :: InputFileData !< FAST.Farm input-file data for wake dynamics [-] INTEGER(IntKi) :: TurbNum = 0 !< Turbine ID number (start with 1; end with number of turbines) [-] + CHARACTER(1024) :: OutFileRoot !< The root name derived from the primary FAST.Farm input file [-] END TYPE WD_InitInputType ! ======================= ! ========= WD_InitOutputType ======= @@ -83,17 +98,23 @@ MODULE WakeDynamics_Types ! ========= WD_DiscreteStateType ======= TYPE, PUBLIC :: WD_DiscreteStateType REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: xhat_plane !< Orientations of wake planes, normal to wake planes [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: YawErr_filt !< Time-filtered nacelle-yaw error at the wake planes [rad] + REAL(ReKi) :: psi_skew_filt !< Time-filtered azimuth angle from skew vertical axis [rad] + REAL(ReKi) :: chi_skew_filt !< Time-filtered inflow skew angle [rad] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: V_plane_filt !< Time-filtered advection, deflection, and meandering velocity of wake planes [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: p_plane !< Center positions of wake planes [m] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: x_plane !< Downwind distance from rotor to each wake plane [m] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vx_wake !< Axial wake velocity deficit at wake planes, distributed radially [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vr_wake !< Radial wake velocity deficit at wake planes, distributed radially [m/s] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: V_plane_filt !< Time-filtered advection, deflection, and meandering velocity of wake planes [m/s] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vx_wake2 !< Axial wake velocity deficit at wake planes, distributed radially [m/s] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vy_wake2 !< Longitudinal wake velocity deficit at wake planes, distributed radially [m/s] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vz_wake2 !< Vertical wake velocity deficit at wake planes, distributed radially [m/s] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Vx_wind_disk_filt !< Time-filtered rotor-disk-averaged ambient wind speed of wake planes, normal to planes [m/s] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TI_amb_filt !< Time-filtered ambient turbulence intensity of wind at wake planes [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: D_rotor_filt !< Time-filtered rotor diameter associated with each wake plane [m] REAL(ReKi) :: Vx_rel_disk_filt !< Time-filtered rotor-disk-averaged relative wind speed (ambient + deficits + motion), normal to disk [m/s] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Ct_azavg_filt !< Time-filtered azimuthally averaged thrust force coefficient (normal to disk), distributed radially [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: YawErr_filt !< Time-filtered nacelle-yaw error at the wake planes [rad] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Cq_azavg_filt !< Time-filtered azimuthally averaged torque coefficient (normal to disk), distributed radially [-] END TYPE WD_DiscreteStateType ! ======================= ! ========= WD_ConstraintStateType ======= @@ -108,17 +129,29 @@ MODULE WakeDynamics_Types ! ======================= ! ========= WD_MiscVarType ======= TYPE, PUBLIC :: WD_MiscVarType - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: dvdr !< [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: dvtdr !< [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: vt_tot !< [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: vt_amb !< [-] - REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: vt_shr !< [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: dvtdr !< Radial gradient of total eddy viscosity (nr) [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: vt_tot !< Polar total eddy viscosity (nr,np) [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: vt_amb !< Polar ambient eddy viscosity (nr,np) [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: vt_shr !< Polar shear eddy viscosity (nr,np) [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: vt_tot2 !< Cartesian total eddy viscosity (ny,nz,np) [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: vt_amb2 !< Cartesian ambient eddy viscosity (ny,nz,np) [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: vt_shr2 !< Cartesian shear eddy viscosity (ny,nz,np) [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: dvx_dy !< Cartesian velocity gradient dVx/dy [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: dvx_dz !< Cartesian velocity gradient dVx/dz [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: nu_dvx_dy !< Product of total eddy viscosity and gradient [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: nu_dvx_dz !< Product of total eddy viscosity and gradient [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: dnuvx_dy !< Gradient of nu_dvx_dy wrt y [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: dnuvx_dz !< Gradient of nu_dvx_dz wrt z [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: a !< [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: b !< [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: c !< [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: d !< [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: r_wake !< [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Vx_high !< [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Vx_polar !< Vx as function of r for Cartesian implementation [-] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Vt_wake !< Vr as function of r for Cartesian implementation [-] + REAL(ReKi) :: GammaCurl !< Circulation used in Curled wake model [-] + REAL(ReKi) :: Ct_avg !< Circulation used in Curled wake model [-] END TYPE WD_MiscVarType ! ======================= ! ========= WD_ParameterType ======= @@ -128,6 +161,13 @@ MODULE WakeDynamics_Types INTEGER(IntKi) :: NumRadii !< Number of radii in the radial finite-difference grid [-] REAL(ReKi) :: dr !< Radial increment of radial finite-difference grid [m] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: r !< Discretization of radial finite-difference grid [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: y !< Horizontal discretization of each wake plane (size ny=2nr-1) [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: z !< Nomically-vertical discretization of each wake plane (size nz=2nr-1) [m] + INTEGER(IntKi) :: Mod_Wake !< Switch between wake formulations 1=Polar, 2=Curl, 3=Cartesian [-] + LOGICAL :: Swirl !< Switch to add swirl [only used if Mod_Wake=2 or 2] [-] + REAL(ReKi) :: k_VortexDecay !< Vortex decay constant for curl [-] + REAL(ReKi) :: sigma_D !< The width of the Gaussian vortices used for the curled wake model divided by diameter [-] + INTEGER(IntKi) :: NumVortices !< The number of vortices used for the curled wake model [-] REAL(ReKi) :: filtParam !< Low-pass time-filter parameter, with a value between 0 (minimum filtering) and 1 (maximum filtering) (exclusive) [-] REAL(ReKi) :: oneMinusFiltParam !< 1.0 - filtParam [-] REAL(ReKi) :: C_HWkDfl_O !< Calibrated parameter in the correction for wake deflection defining the horizontal offset at the rotor [m] @@ -147,11 +187,23 @@ MODULE WakeDynamics_Types REAL(ReKi) :: k_vShr !< Calibrated parameter for the influence of the shear layer in the eddy viscosity [-] INTEGER(IntKi) :: Mod_WakeDiam !< Wake diameter calculation model [-] REAL(ReKi) :: C_WakeDiam !< Calibrated parameter for wake diameter calculation [-] + INTEGER(IntKi) :: FilterInit !< Switch to filter the initial wake plane deficit and select the number of grid points for the filter {0: no filter, 1: filter of size 1} or DEFAULT [DEFAULT=0: if Mod_Wake is 1 or 3, or DEFAULT=2: if Mod_Wwake is 2] (switch) [-] + REAL(ReKi) :: k_vCurl !< Calibrated parameter for the eddy viscosity in curled-wake model [>=0.0] [-] + LOGICAL :: OutAllPlanes !< Output all planes [-] + CHARACTER(1024) :: OutFileRoot !< The root name derived from the primary FAST.Farm input file [-] + CHARACTER(1024) :: OutFileVTKDir !< The parent directory for all VTK files written by WD [-] + INTEGER(IntKi) :: TurbNum = 0 !< Turbine ID number (start with 1; end with number of turbines) [-] + LOGICAL :: WAT !< Switch for turning on and off wake-added turbulence [-] + REAL(ReKi) :: WAT_k_Def !< Calibrated parameter for the influence of the wake deficit in the wake-added Turbulence (-) [>=0.0] or DEFAULT [DEFAULT=0.6] [-] + REAL(ReKi) :: WAT_k_Grad !< Calibrated parameter for the influence of the radial velocity gradient of the wake deficit in the wake-added Turbulence (-) [>=0.0] or DEFAULT [DEFAULT=0.35] [-] END TYPE WD_ParameterType ! ======================= ! ========= WD_InputType ======= TYPE, PUBLIC :: WD_InputType REAL(ReKi) , DIMENSION(1:3) :: xhat_disk !< Orientation of rotor centerline, normal to disk [-] + REAL(ReKi) :: YawErr !< Nacelle-yaw error at the wake planes [rad] + REAL(ReKi) :: psi_skew !< Azimuth angle from the nominally vertical axis in the disk plane to the vector about which the inflow skew angle is defined [rad] + REAL(ReKi) :: chi_skew !< Inflow skew angle [rad] REAL(ReKi) , DIMENSION(1:3) :: p_hub !< Center position of hub [m] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: V_plane !< Advection, deflection, and meandering velocity of wake planes [m/s] REAL(ReKi) :: Vx_wind_disk !< Rotor-disk-averaged ambient wind speed, normal to planes [m/s] @@ -159,7 +211,7 @@ MODULE WakeDynamics_Types REAL(ReKi) :: D_rotor !< Rotor diameter [m] REAL(ReKi) :: Vx_rel_disk !< Rotor-disk-averaged relative wind speed (ambient + deficits + motion), normal to disk [m/s] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Ct_azavg !< Azimuthally averaged thrust force coefficient (normal to disk), distributed radially [-] - REAL(ReKi) :: YawErr !< Nacelle-yaw error at the wake planes [rad] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Cq_azavg !< Azimuthally averaged torque coefficient (normal to disk), distributed radially [-] END TYPE WD_InputType ! ======================= ! ========= WD_OutputType ======= @@ -168,8 +220,12 @@ MODULE WakeDynamics_Types REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: p_plane !< Center positions of wake planes [m] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vx_wake !< Axial wake velocity deficit at wake planes, distributed radially [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vr_wake !< Radial wake velocity deficit at wake planes, distributed radially [m/s] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vx_wake2 !< Axial wake velocity deficit at wake planes, distributed across the plane [m/s] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vy_wake2 !< Transverse horizontal wake velocity deficit at wake planes, distributed across the plane [m/s] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vz_wake2 !< Transverse nominally vertical wake velocity deficit at wake planes, distributed across the plane [m/s] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: D_wake !< Wake diameters at wake planes [m] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: x_plane !< Downwind distance from rotor to each wake plane [m] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: WAT_k_mt !< Scaling factor k_mt(iP,y,z) for wake-added turbulence [-] END TYPE WD_OutputType ! ======================= CONTAINS @@ -183,6 +239,7 @@ SUBROUTINE WD_CopyInputFileType( SrcInputFileTypeData, DstInputFileTypeData, 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 = 'WD_CopyInputFileType' @@ -192,6 +249,7 @@ SUBROUTINE WD_CopyInputFileType( SrcInputFileTypeData, DstInputFileTypeData, Ctr DstInputFileTypeData%dr = SrcInputFileTypeData%dr DstInputFileTypeData%NumRadii = SrcInputFileTypeData%NumRadii DstInputFileTypeData%NumPlanes = SrcInputFileTypeData%NumPlanes + DstInputFileTypeData%Mod_Wake = SrcInputFileTypeData%Mod_Wake DstInputFileTypeData%f_c = SrcInputFileTypeData%f_c DstInputFileTypeData%C_HWkDfl_O = SrcInputFileTypeData%C_HWkDfl_O DstInputFileTypeData%C_HWkDfl_OY = SrcInputFileTypeData%C_HWkDfl_OY @@ -210,17 +268,39 @@ SUBROUTINE WD_CopyInputFileType( SrcInputFileTypeData, DstInputFileTypeData, Ctr DstInputFileTypeData%C_vShr_Exp = SrcInputFileTypeData%C_vShr_Exp DstInputFileTypeData%Mod_WakeDiam = SrcInputFileTypeData%Mod_WakeDiam DstInputFileTypeData%C_WakeDiam = SrcInputFileTypeData%C_WakeDiam + DstInputFileTypeData%Swirl = SrcInputFileTypeData%Swirl + DstInputFileTypeData%k_VortexDecay = SrcInputFileTypeData%k_VortexDecay + DstInputFileTypeData%sigma_D = SrcInputFileTypeData%sigma_D + DstInputFileTypeData%NumVortices = SrcInputFileTypeData%NumVortices + DstInputFileTypeData%FilterInit = SrcInputFileTypeData%FilterInit + DstInputFileTypeData%k_vCurl = SrcInputFileTypeData%k_vCurl + DstInputFileTypeData%OutAllPlanes = SrcInputFileTypeData%OutAllPlanes + DstInputFileTypeData%WAT = SrcInputFileTypeData%WAT + DstInputFileTypeData%WAT_k_Def = SrcInputFileTypeData%WAT_k_Def + DstInputFileTypeData%WAT_k_Grad = SrcInputFileTypeData%WAT_k_Grad END SUBROUTINE WD_CopyInputFileType - SUBROUTINE WD_DestroyInputFileType( InputFileTypeData, ErrStat, ErrMsg ) + SUBROUTINE WD_DestroyInputFileType( InputFileTypeData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WD_InputFileType), INTENT(INOUT) :: InputFileTypeData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyInputFileType' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyInputFileType' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE WD_DestroyInputFileType SUBROUTINE WD_PackInputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -261,6 +341,7 @@ SUBROUTINE WD_PackInputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Re_BufSz = Re_BufSz + 1 ! dr Int_BufSz = Int_BufSz + 1 ! NumRadii Int_BufSz = Int_BufSz + 1 ! NumPlanes + Int_BufSz = Int_BufSz + 1 ! Mod_Wake Re_BufSz = Re_BufSz + 1 ! f_c Re_BufSz = Re_BufSz + 1 ! C_HWkDfl_O Re_BufSz = Re_BufSz + 1 ! C_HWkDfl_OY @@ -279,6 +360,16 @@ SUBROUTINE WD_PackInputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Re_BufSz = Re_BufSz + 1 ! C_vShr_Exp Int_BufSz = Int_BufSz + 1 ! Mod_WakeDiam Re_BufSz = Re_BufSz + 1 ! C_WakeDiam + Int_BufSz = Int_BufSz + 1 ! Swirl + Re_BufSz = Re_BufSz + 1 ! k_VortexDecay + Re_BufSz = Re_BufSz + 1 ! sigma_D + Int_BufSz = Int_BufSz + 1 ! NumVortices + Int_BufSz = Int_BufSz + 1 ! FilterInit + Re_BufSz = Re_BufSz + 1 ! k_vCurl + Int_BufSz = Int_BufSz + 1 ! OutAllPlanes + Int_BufSz = Int_BufSz + 1 ! WAT + Re_BufSz = Re_BufSz + 1 ! WAT_k_Def + Re_BufSz = Re_BufSz + 1 ! WAT_k_Grad IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -312,6 +403,8 @@ SUBROUTINE WD_PackInputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NumPlanes Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%Mod_Wake + Int_Xferred = Int_Xferred + 1 ReKiBuf(Re_Xferred) = InData%f_c Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%C_HWkDfl_O @@ -348,6 +441,26 @@ SUBROUTINE WD_PackInputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, Er Int_Xferred = Int_Xferred + 1 ReKiBuf(Re_Xferred) = InData%C_WakeDiam Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%Swirl, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%k_VortexDecay + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%sigma_D + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumVortices + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%FilterInit + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%k_vCurl + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%OutAllPlanes, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%WAT, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WAT_k_Def + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WAT_k_Grad + Re_Xferred = Re_Xferred + 1 END SUBROUTINE WD_PackInputFileType SUBROUTINE WD_UnPackInputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -365,6 +478,7 @@ SUBROUTINE WD_UnPackInputFileType( 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 = 'WD_UnPackInputFileType' @@ -384,6 +498,8 @@ SUBROUTINE WD_UnPackInputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Xferred = Int_Xferred + 1 OutData%NumPlanes = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + OutData%Mod_Wake = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%f_c = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%C_HWkDfl_O = ReKiBuf(Re_Xferred) @@ -420,6 +536,26 @@ SUBROUTINE WD_UnPackInputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Int_Xferred = Int_Xferred + 1 OutData%C_WakeDiam = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%Swirl = TRANSFER(IntKiBuf(Int_Xferred), OutData%Swirl) + Int_Xferred = Int_Xferred + 1 + OutData%k_VortexDecay = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%sigma_D = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%NumVortices = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%FilterInit = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%k_vCurl = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%OutAllPlanes = TRANSFER(IntKiBuf(Int_Xferred), OutData%OutAllPlanes) + Int_Xferred = Int_Xferred + 1 + OutData%WAT = TRANSFER(IntKiBuf(Int_Xferred), OutData%WAT) + Int_Xferred = Int_Xferred + 1 + OutData%WAT_k_Def = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%WAT_k_Grad = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE WD_UnPackInputFileType SUBROUTINE WD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg ) @@ -440,18 +576,32 @@ SUBROUTINE WD_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrSt CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName) IF (ErrStat>=AbortErrLev) RETURN DstInitInputData%TurbNum = SrcInitInputData%TurbNum + DstInitInputData%OutFileRoot = SrcInitInputData%OutFileRoot END SUBROUTINE WD_CopyInitInput - SUBROUTINE WD_DestroyInitInput( InitInputData, ErrStat, ErrMsg ) + SUBROUTINE WD_DestroyInitInput( InitInputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WD_InitInputType), INTENT(INOUT) :: InitInputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyInitInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyInitInput' + ErrStat = ErrID_None ErrMsg = "" - CALL WD_Destroyinputfiletype( InitInputData%InputFileData, ErrStat, ErrMsg ) + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + + CALL WD_Destroyinputfiletype( InitInputData%InputFileData, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE WD_DestroyInitInput SUBROUTINE WD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -508,6 +658,7 @@ SUBROUTINE WD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg DEALLOCATE(Int_Buf) END IF Int_BufSz = Int_BufSz + 1 ! TurbNum + Int_BufSz = Int_BufSz + 1*LEN(InData%OutFileRoot) ! OutFileRoot IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -565,6 +716,10 @@ SUBROUTINE WD_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg ENDIF IntKiBuf(Int_Xferred) = InData%TurbNum Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(InData%OutFileRoot) + IntKiBuf(Int_Xferred) = ICHAR(InData%OutFileRoot(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I END SUBROUTINE WD_PackInitInput SUBROUTINE WD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -635,6 +790,10 @@ SUBROUTINE WD_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf) OutData%TurbNum = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(OutData%OutFileRoot) + OutData%OutFileRoot(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I END SUBROUTINE WD_UnPackInitInput SUBROUTINE WD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -681,22 +840,35 @@ SUBROUTINE WD_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, Er IF (ErrStat>=AbortErrLev) RETURN END SUBROUTINE WD_CopyInitOutput - SUBROUTINE WD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg ) + SUBROUTINE WD_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WD_InitOutputType), INTENT(INOUT) :: InitOutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyInitOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyInitOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN DEALLOCATE(InitOutputData%WriteOutputHdr) ENDIF IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN DEALLOCATE(InitOutputData%WriteOutputUnt) ENDIF - CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat, ErrMsg ) + CALL NWTC_Library_Destroyprogdesc( InitOutputData%Ver, ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) + CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) END SUBROUTINE WD_DestroyInitOutput SUBROUTINE WD_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -979,15 +1151,27 @@ SUBROUTINE WD_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrSt DstContStateData%DummyContState = SrcContStateData%DummyContState END SUBROUTINE WD_CopyContState - SUBROUTINE WD_DestroyContState( ContStateData, ErrStat, ErrMsg ) + SUBROUTINE WD_DestroyContState( ContStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WD_ContinuousStateType), INTENT(INOUT) :: ContStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyContState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyContState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE WD_DestroyContState SUBROUTINE WD_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -1097,6 +1281,7 @@ SUBROUTINE WD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt 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 = 'WD_CopyDiscState' @@ -1117,6 +1302,34 @@ SUBROUTINE WD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt END IF DstDiscStateData%xhat_plane = SrcDiscStateData%xhat_plane ENDIF +IF (ALLOCATED(SrcDiscStateData%YawErr_filt)) THEN + i1_l = LBOUND(SrcDiscStateData%YawErr_filt,1) + i1_u = UBOUND(SrcDiscStateData%YawErr_filt,1) + IF (.NOT. ALLOCATED(DstDiscStateData%YawErr_filt)) THEN + ALLOCATE(DstDiscStateData%YawErr_filt(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%YawErr_filt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstDiscStateData%YawErr_filt = SrcDiscStateData%YawErr_filt +ENDIF + DstDiscStateData%psi_skew_filt = SrcDiscStateData%psi_skew_filt + DstDiscStateData%chi_skew_filt = SrcDiscStateData%chi_skew_filt +IF (ALLOCATED(SrcDiscStateData%V_plane_filt)) THEN + i1_l = LBOUND(SrcDiscStateData%V_plane_filt,1) + i1_u = UBOUND(SrcDiscStateData%V_plane_filt,1) + i2_l = LBOUND(SrcDiscStateData%V_plane_filt,2) + i2_u = UBOUND(SrcDiscStateData%V_plane_filt,2) + IF (.NOT. ALLOCATED(DstDiscStateData%V_plane_filt)) THEN + ALLOCATE(DstDiscStateData%V_plane_filt(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%V_plane_filt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstDiscStateData%V_plane_filt = SrcDiscStateData%V_plane_filt +ENDIF IF (ALLOCATED(SrcDiscStateData%p_plane)) THEN i1_l = LBOUND(SrcDiscStateData%p_plane,1) i1_u = UBOUND(SrcDiscStateData%p_plane,1) @@ -1171,19 +1384,53 @@ SUBROUTINE WD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt END IF DstDiscStateData%Vr_wake = SrcDiscStateData%Vr_wake ENDIF -IF (ALLOCATED(SrcDiscStateData%V_plane_filt)) THEN - i1_l = LBOUND(SrcDiscStateData%V_plane_filt,1) - i1_u = UBOUND(SrcDiscStateData%V_plane_filt,1) - i2_l = LBOUND(SrcDiscStateData%V_plane_filt,2) - i2_u = UBOUND(SrcDiscStateData%V_plane_filt,2) - IF (.NOT. ALLOCATED(DstDiscStateData%V_plane_filt)) THEN - ALLOCATE(DstDiscStateData%V_plane_filt(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) +IF (ALLOCATED(SrcDiscStateData%Vx_wake2)) THEN + i1_l = LBOUND(SrcDiscStateData%Vx_wake2,1) + i1_u = UBOUND(SrcDiscStateData%Vx_wake2,1) + i2_l = LBOUND(SrcDiscStateData%Vx_wake2,2) + i2_u = UBOUND(SrcDiscStateData%Vx_wake2,2) + i3_l = LBOUND(SrcDiscStateData%Vx_wake2,3) + i3_u = UBOUND(SrcDiscStateData%Vx_wake2,3) + IF (.NOT. ALLOCATED(DstDiscStateData%Vx_wake2)) THEN + ALLOCATE(DstDiscStateData%Vx_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%V_plane_filt.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%Vx_wake2.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstDiscStateData%V_plane_filt = SrcDiscStateData%V_plane_filt + DstDiscStateData%Vx_wake2 = SrcDiscStateData%Vx_wake2 +ENDIF +IF (ALLOCATED(SrcDiscStateData%Vy_wake2)) THEN + i1_l = LBOUND(SrcDiscStateData%Vy_wake2,1) + i1_u = UBOUND(SrcDiscStateData%Vy_wake2,1) + i2_l = LBOUND(SrcDiscStateData%Vy_wake2,2) + i2_u = UBOUND(SrcDiscStateData%Vy_wake2,2) + i3_l = LBOUND(SrcDiscStateData%Vy_wake2,3) + i3_u = UBOUND(SrcDiscStateData%Vy_wake2,3) + IF (.NOT. ALLOCATED(DstDiscStateData%Vy_wake2)) THEN + ALLOCATE(DstDiscStateData%Vy_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%Vy_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstDiscStateData%Vy_wake2 = SrcDiscStateData%Vy_wake2 +ENDIF +IF (ALLOCATED(SrcDiscStateData%Vz_wake2)) THEN + i1_l = LBOUND(SrcDiscStateData%Vz_wake2,1) + i1_u = UBOUND(SrcDiscStateData%Vz_wake2,1) + i2_l = LBOUND(SrcDiscStateData%Vz_wake2,2) + i2_u = UBOUND(SrcDiscStateData%Vz_wake2,2) + i3_l = LBOUND(SrcDiscStateData%Vz_wake2,3) + i3_u = UBOUND(SrcDiscStateData%Vz_wake2,3) + IF (.NOT. ALLOCATED(DstDiscStateData%Vz_wake2)) THEN + ALLOCATE(DstDiscStateData%Vz_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%Vz_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstDiscStateData%Vz_wake2 = SrcDiscStateData%Vz_wake2 ENDIF IF (ALLOCATED(SrcDiscStateData%Vx_wind_disk_filt)) THEN i1_l = LBOUND(SrcDiscStateData%Vx_wind_disk_filt,1) @@ -1234,32 +1481,50 @@ SUBROUTINE WD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt END IF DstDiscStateData%Ct_azavg_filt = SrcDiscStateData%Ct_azavg_filt ENDIF -IF (ALLOCATED(SrcDiscStateData%YawErr_filt)) THEN - i1_l = LBOUND(SrcDiscStateData%YawErr_filt,1) - i1_u = UBOUND(SrcDiscStateData%YawErr_filt,1) - IF (.NOT. ALLOCATED(DstDiscStateData%YawErr_filt)) THEN - ALLOCATE(DstDiscStateData%YawErr_filt(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcDiscStateData%Cq_azavg_filt)) THEN + i1_l = LBOUND(SrcDiscStateData%Cq_azavg_filt,1) + i1_u = UBOUND(SrcDiscStateData%Cq_azavg_filt,1) + IF (.NOT. ALLOCATED(DstDiscStateData%Cq_azavg_filt)) THEN + ALLOCATE(DstDiscStateData%Cq_azavg_filt(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%YawErr_filt.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%Cq_azavg_filt.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstDiscStateData%YawErr_filt = SrcDiscStateData%YawErr_filt + DstDiscStateData%Cq_azavg_filt = SrcDiscStateData%Cq_azavg_filt ENDIF END SUBROUTINE WD_CopyDiscState - SUBROUTINE WD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) + SUBROUTINE WD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WD_DiscreteStateType), INTENT(INOUT) :: DiscStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyDiscState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyDiscState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(DiscStateData%xhat_plane)) THEN DEALLOCATE(DiscStateData%xhat_plane) ENDIF +IF (ALLOCATED(DiscStateData%YawErr_filt)) THEN + DEALLOCATE(DiscStateData%YawErr_filt) +ENDIF +IF (ALLOCATED(DiscStateData%V_plane_filt)) THEN + DEALLOCATE(DiscStateData%V_plane_filt) +ENDIF IF (ALLOCATED(DiscStateData%p_plane)) THEN DEALLOCATE(DiscStateData%p_plane) ENDIF @@ -1272,8 +1537,14 @@ SUBROUTINE WD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) IF (ALLOCATED(DiscStateData%Vr_wake)) THEN DEALLOCATE(DiscStateData%Vr_wake) ENDIF -IF (ALLOCATED(DiscStateData%V_plane_filt)) THEN - DEALLOCATE(DiscStateData%V_plane_filt) +IF (ALLOCATED(DiscStateData%Vx_wake2)) THEN + DEALLOCATE(DiscStateData%Vx_wake2) +ENDIF +IF (ALLOCATED(DiscStateData%Vy_wake2)) THEN + DEALLOCATE(DiscStateData%Vy_wake2) +ENDIF +IF (ALLOCATED(DiscStateData%Vz_wake2)) THEN + DEALLOCATE(DiscStateData%Vz_wake2) ENDIF IF (ALLOCATED(DiscStateData%Vx_wind_disk_filt)) THEN DEALLOCATE(DiscStateData%Vx_wind_disk_filt) @@ -1287,8 +1558,8 @@ SUBROUTINE WD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg ) IF (ALLOCATED(DiscStateData%Ct_azavg_filt)) THEN DEALLOCATE(DiscStateData%Ct_azavg_filt) ENDIF -IF (ALLOCATED(DiscStateData%YawErr_filt)) THEN - DEALLOCATE(DiscStateData%YawErr_filt) +IF (ALLOCATED(DiscStateData%Cq_azavg_filt)) THEN + DEALLOCATE(DiscStateData%Cq_azavg_filt) ENDIF END SUBROUTINE WD_DestroyDiscState @@ -1332,6 +1603,18 @@ SUBROUTINE WD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 2*2 ! xhat_plane upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%xhat_plane) ! xhat_plane END IF + Int_BufSz = Int_BufSz + 1 ! YawErr_filt allocated yes/no + IF ( ALLOCATED(InData%YawErr_filt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! YawErr_filt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%YawErr_filt) ! YawErr_filt + END IF + Re_BufSz = Re_BufSz + 1 ! psi_skew_filt + Re_BufSz = Re_BufSz + 1 ! chi_skew_filt + Int_BufSz = Int_BufSz + 1 ! V_plane_filt allocated yes/no + IF ( ALLOCATED(InData%V_plane_filt) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! V_plane_filt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%V_plane_filt) ! V_plane_filt + END IF Int_BufSz = Int_BufSz + 1 ! p_plane allocated yes/no IF ( ALLOCATED(InData%p_plane) ) THEN Int_BufSz = Int_BufSz + 2*2 ! p_plane upper/lower bounds for each dimension @@ -1352,10 +1635,20 @@ SUBROUTINE WD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 2*2 ! Vr_wake upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Vr_wake) ! Vr_wake END IF - Int_BufSz = Int_BufSz + 1 ! V_plane_filt allocated yes/no - IF ( ALLOCATED(InData%V_plane_filt) ) THEN - Int_BufSz = Int_BufSz + 2*2 ! V_plane_filt upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%V_plane_filt) ! V_plane_filt + Int_BufSz = Int_BufSz + 1 ! Vx_wake2 allocated yes/no + IF ( ALLOCATED(InData%Vx_wake2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Vx_wake2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vx_wake2) ! Vx_wake2 + END IF + Int_BufSz = Int_BufSz + 1 ! Vy_wake2 allocated yes/no + IF ( ALLOCATED(InData%Vy_wake2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Vy_wake2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vy_wake2) ! Vy_wake2 + END IF + Int_BufSz = Int_BufSz + 1 ! Vz_wake2 allocated yes/no + IF ( ALLOCATED(InData%Vz_wake2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Vz_wake2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vz_wake2) ! Vz_wake2 END IF Int_BufSz = Int_BufSz + 1 ! Vx_wind_disk_filt allocated yes/no IF ( ALLOCATED(InData%Vx_wind_disk_filt) ) THEN @@ -1378,10 +1671,10 @@ SUBROUTINE WD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 2*1 ! Ct_azavg_filt upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Ct_azavg_filt) ! Ct_azavg_filt END IF - Int_BufSz = Int_BufSz + 1 ! YawErr_filt allocated yes/no - IF ( ALLOCATED(InData%YawErr_filt) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! YawErr_filt upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%YawErr_filt) ! YawErr_filt + Int_BufSz = Int_BufSz + 1 ! Cq_azavg_filt allocated yes/no + IF ( ALLOCATED(InData%Cq_azavg_filt) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Cq_azavg_filt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Cq_azavg_filt) ! Cq_azavg_filt END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) @@ -1430,6 +1723,45 @@ SUBROUTINE WD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%YawErr_filt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%YawErr_filt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%YawErr_filt,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%YawErr_filt,1), UBOUND(InData%YawErr_filt,1) + ReKiBuf(Re_Xferred) = InData%YawErr_filt(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + ReKiBuf(Re_Xferred) = InData%psi_skew_filt + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%chi_skew_filt + Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%V_plane_filt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%V_plane_filt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V_plane_filt,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%V_plane_filt,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V_plane_filt,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%V_plane_filt,2), UBOUND(InData%V_plane_filt,2) + DO i1 = LBOUND(InData%V_plane_filt,1), UBOUND(InData%V_plane_filt,1) + ReKiBuf(Re_Xferred) = InData%V_plane_filt(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF IF ( .NOT. ALLOCATED(InData%p_plane) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -1505,23 +1837,78 @@ SUBROUTINE WD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%V_plane_filt) ) THEN + IF ( .NOT. ALLOCATED(InData%Vx_wake2) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V_plane_filt,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V_plane_filt,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake2,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%V_plane_filt,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%V_plane_filt,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake2,3) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%V_plane_filt,2), UBOUND(InData%V_plane_filt,2) - DO i1 = LBOUND(InData%V_plane_filt,1), UBOUND(InData%V_plane_filt,1) - ReKiBuf(Re_Xferred) = InData%V_plane_filt(i1,i2) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(InData%Vx_wake2,3), UBOUND(InData%Vx_wake2,3) + DO i2 = LBOUND(InData%Vx_wake2,2), UBOUND(InData%Vx_wake2,2) + DO i1 = LBOUND(InData%Vx_wake2,1), UBOUND(InData%Vx_wake2,1) + ReKiBuf(Re_Xferred) = InData%Vx_wake2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Vy_wake2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%Vy_wake2,3), UBOUND(InData%Vy_wake2,3) + DO i2 = LBOUND(InData%Vy_wake2,2), UBOUND(InData%Vy_wake2,2) + DO i1 = LBOUND(InData%Vy_wake2,1), UBOUND(InData%Vy_wake2,1) + ReKiBuf(Re_Xferred) = InData%Vy_wake2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Vz_wake2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%Vz_wake2,3), UBOUND(InData%Vz_wake2,3) + DO i2 = LBOUND(InData%Vz_wake2,2), UBOUND(InData%Vz_wake2,2) + DO i1 = LBOUND(InData%Vz_wake2,1), UBOUND(InData%Vz_wake2,1) + ReKiBuf(Re_Xferred) = InData%Vz_wake2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF @@ -1587,18 +1974,18 @@ SUBROUTINE WD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%YawErr_filt) ) THEN + IF ( .NOT. ALLOCATED(InData%Cq_azavg_filt) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%YawErr_filt,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%YawErr_filt,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cq_azavg_filt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cq_azavg_filt,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%YawErr_filt,1), UBOUND(InData%YawErr_filt,1) - ReKiBuf(Re_Xferred) = InData%YawErr_filt(i1) + DO i1 = LBOUND(InData%Cq_azavg_filt,1), UBOUND(InData%Cq_azavg_filt,1) + ReKiBuf(Re_Xferred) = InData%Cq_azavg_filt(i1) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -1619,6 +2006,7 @@ SUBROUTINE WD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err 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 = 'WD_UnPackDiscState' @@ -1655,30 +2043,75 @@ SUBROUTINE WD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! p_plane not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! YawErr_filt not allocated Int_Xferred = Int_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%p_plane)) DEALLOCATE(OutData%p_plane) - ALLOCATE(OutData%p_plane(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%YawErr_filt)) DEALLOCATE(OutData%YawErr_filt) + ALLOCATE(OutData%YawErr_filt(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%p_plane.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%YawErr_filt.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%p_plane,2), UBOUND(OutData%p_plane,2) - DO i1 = LBOUND(OutData%p_plane,1), UBOUND(OutData%p_plane,1) - OutData%p_plane(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO + DO i1 = LBOUND(OutData%YawErr_filt,1), UBOUND(OutData%YawErr_filt,1) + OutData%YawErr_filt(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! x_plane not allocated + OutData%psi_skew_filt = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%chi_skew_filt = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! V_plane_filt not allocated + Int_Xferred = Int_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%V_plane_filt)) DEALLOCATE(OutData%V_plane_filt) + ALLOCATE(OutData%V_plane_filt(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%V_plane_filt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%V_plane_filt,2), UBOUND(OutData%V_plane_filt,2) + DO i1 = LBOUND(OutData%V_plane_filt,1), UBOUND(OutData%V_plane_filt,1) + OutData%V_plane_filt(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! p_plane not allocated + Int_Xferred = Int_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%p_plane)) DEALLOCATE(OutData%p_plane) + ALLOCATE(OutData%p_plane(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%p_plane.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%p_plane,2), UBOUND(OutData%p_plane,2) + DO i1 = LBOUND(OutData%p_plane,1), UBOUND(OutData%p_plane,1) + OutData%p_plane(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! x_plane not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -1742,7 +2175,7 @@ SUBROUTINE WD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! V_plane_filt not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vx_wake2 not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -1752,16 +2185,77 @@ SUBROUTINE WD_UnPackDiscState( 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%V_plane_filt)) DEALLOCATE(OutData%V_plane_filt) - ALLOCATE(OutData%V_plane_filt(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%Vx_wake2)) DEALLOCATE(OutData%Vx_wake2) + ALLOCATE(OutData%Vx_wake2(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%V_plane_filt.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vx_wake2.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i2 = LBOUND(OutData%V_plane_filt,2), UBOUND(OutData%V_plane_filt,2) - DO i1 = LBOUND(OutData%V_plane_filt,1), UBOUND(OutData%V_plane_filt,1) - OutData%V_plane_filt(i1,i2) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(OutData%Vx_wake2,3), UBOUND(OutData%Vx_wake2,3) + DO i2 = LBOUND(OutData%Vx_wake2,2), UBOUND(OutData%Vx_wake2,2) + DO i1 = LBOUND(OutData%Vx_wake2,1), UBOUND(OutData%Vx_wake2,1) + OutData%Vx_wake2(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 ! Vy_wake2 not allocated + Int_Xferred = Int_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%Vy_wake2)) DEALLOCATE(OutData%Vy_wake2) + ALLOCATE(OutData%Vy_wake2(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%Vy_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%Vy_wake2,3), UBOUND(OutData%Vy_wake2,3) + DO i2 = LBOUND(OutData%Vy_wake2,2), UBOUND(OutData%Vy_wake2,2) + DO i1 = LBOUND(OutData%Vy_wake2,1), UBOUND(OutData%Vy_wake2,1) + OutData%Vy_wake2(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 ! Vz_wake2 not allocated + Int_Xferred = Int_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%Vz_wake2)) DEALLOCATE(OutData%Vz_wake2) + ALLOCATE(OutData%Vz_wake2(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%Vz_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%Vz_wake2,3), UBOUND(OutData%Vz_wake2,3) + DO i2 = LBOUND(OutData%Vz_wake2,2), UBOUND(OutData%Vz_wake2,2) + DO i1 = LBOUND(OutData%Vz_wake2,1), UBOUND(OutData%Vz_wake2,1) + OutData%Vz_wake2(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END IF @@ -1839,21 +2333,21 @@ SUBROUTINE WD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! YawErr_filt not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Cq_azavg_filt not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%YawErr_filt)) DEALLOCATE(OutData%YawErr_filt) - ALLOCATE(OutData%YawErr_filt(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Cq_azavg_filt)) DEALLOCATE(OutData%Cq_azavg_filt) + ALLOCATE(OutData%Cq_azavg_filt(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%YawErr_filt.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Cq_azavg_filt.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%YawErr_filt,1), UBOUND(OutData%YawErr_filt,1) - OutData%YawErr_filt(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%Cq_azavg_filt,1), UBOUND(OutData%Cq_azavg_filt,1) + OutData%Cq_azavg_filt(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -1876,15 +2370,27 @@ SUBROUTINE WD_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState END SUBROUTINE WD_CopyConstrState - SUBROUTINE WD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg ) + SUBROUTINE WD_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WD_ConstraintStateType), INTENT(INOUT) :: ConstrStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyConstrState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyConstrState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE WD_DestroyConstrState SUBROUTINE WD_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2001,15 +2507,27 @@ SUBROUTINE WD_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, Er DstOtherStateData%firstPass = SrcOtherStateData%firstPass END SUBROUTINE WD_CopyOtherState - SUBROUTINE WD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg ) + SUBROUTINE WD_DestroyOtherState( OtherStateData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WD_OtherStateType), INTENT(INOUT) :: OtherStateData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyOtherState' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyOtherState' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + END SUBROUTINE WD_DestroyOtherState SUBROUTINE WD_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly ) @@ -2119,24 +2637,13 @@ SUBROUTINE WD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) 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 = 'WD_CopyMisc' ! ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(SrcMiscData%dvdr)) THEN - i1_l = LBOUND(SrcMiscData%dvdr,1) - i1_u = UBOUND(SrcMiscData%dvdr,1) - IF (.NOT. ALLOCATED(DstMiscData%dvdr)) THEN - ALLOCATE(DstMiscData%dvdr(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%dvdr.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - END IF - DstMiscData%dvdr = SrcMiscData%dvdr -ENDIF IF (ALLOCATED(SrcMiscData%dvtdr)) THEN i1_l = LBOUND(SrcMiscData%dvtdr,1) i1_u = UBOUND(SrcMiscData%dvtdr,1) @@ -2191,6 +2698,142 @@ SUBROUTINE WD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF DstMiscData%vt_shr = SrcMiscData%vt_shr ENDIF +IF (ALLOCATED(SrcMiscData%vt_tot2)) THEN + i1_l = LBOUND(SrcMiscData%vt_tot2,1) + i1_u = UBOUND(SrcMiscData%vt_tot2,1) + i2_l = LBOUND(SrcMiscData%vt_tot2,2) + i2_u = UBOUND(SrcMiscData%vt_tot2,2) + i3_l = LBOUND(SrcMiscData%vt_tot2,3) + i3_u = UBOUND(SrcMiscData%vt_tot2,3) + IF (.NOT. ALLOCATED(DstMiscData%vt_tot2)) THEN + ALLOCATE(DstMiscData%vt_tot2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%vt_tot2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%vt_tot2 = SrcMiscData%vt_tot2 +ENDIF +IF (ALLOCATED(SrcMiscData%vt_amb2)) THEN + i1_l = LBOUND(SrcMiscData%vt_amb2,1) + i1_u = UBOUND(SrcMiscData%vt_amb2,1) + i2_l = LBOUND(SrcMiscData%vt_amb2,2) + i2_u = UBOUND(SrcMiscData%vt_amb2,2) + i3_l = LBOUND(SrcMiscData%vt_amb2,3) + i3_u = UBOUND(SrcMiscData%vt_amb2,3) + IF (.NOT. ALLOCATED(DstMiscData%vt_amb2)) THEN + ALLOCATE(DstMiscData%vt_amb2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%vt_amb2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%vt_amb2 = SrcMiscData%vt_amb2 +ENDIF +IF (ALLOCATED(SrcMiscData%vt_shr2)) THEN + i1_l = LBOUND(SrcMiscData%vt_shr2,1) + i1_u = UBOUND(SrcMiscData%vt_shr2,1) + i2_l = LBOUND(SrcMiscData%vt_shr2,2) + i2_u = UBOUND(SrcMiscData%vt_shr2,2) + i3_l = LBOUND(SrcMiscData%vt_shr2,3) + i3_u = UBOUND(SrcMiscData%vt_shr2,3) + IF (.NOT. ALLOCATED(DstMiscData%vt_shr2)) THEN + ALLOCATE(DstMiscData%vt_shr2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%vt_shr2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%vt_shr2 = SrcMiscData%vt_shr2 +ENDIF +IF (ALLOCATED(SrcMiscData%dvx_dy)) THEN + i1_l = LBOUND(SrcMiscData%dvx_dy,1) + i1_u = UBOUND(SrcMiscData%dvx_dy,1) + i2_l = LBOUND(SrcMiscData%dvx_dy,2) + i2_u = UBOUND(SrcMiscData%dvx_dy,2) + i3_l = LBOUND(SrcMiscData%dvx_dy,3) + i3_u = UBOUND(SrcMiscData%dvx_dy,3) + IF (.NOT. ALLOCATED(DstMiscData%dvx_dy)) THEN + ALLOCATE(DstMiscData%dvx_dy(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%dvx_dy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%dvx_dy = SrcMiscData%dvx_dy +ENDIF +IF (ALLOCATED(SrcMiscData%dvx_dz)) THEN + i1_l = LBOUND(SrcMiscData%dvx_dz,1) + i1_u = UBOUND(SrcMiscData%dvx_dz,1) + i2_l = LBOUND(SrcMiscData%dvx_dz,2) + i2_u = UBOUND(SrcMiscData%dvx_dz,2) + i3_l = LBOUND(SrcMiscData%dvx_dz,3) + i3_u = UBOUND(SrcMiscData%dvx_dz,3) + IF (.NOT. ALLOCATED(DstMiscData%dvx_dz)) THEN + ALLOCATE(DstMiscData%dvx_dz(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%dvx_dz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%dvx_dz = SrcMiscData%dvx_dz +ENDIF +IF (ALLOCATED(SrcMiscData%nu_dvx_dy)) THEN + i1_l = LBOUND(SrcMiscData%nu_dvx_dy,1) + i1_u = UBOUND(SrcMiscData%nu_dvx_dy,1) + i2_l = LBOUND(SrcMiscData%nu_dvx_dy,2) + i2_u = UBOUND(SrcMiscData%nu_dvx_dy,2) + IF (.NOT. ALLOCATED(DstMiscData%nu_dvx_dy)) THEN + ALLOCATE(DstMiscData%nu_dvx_dy(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%nu_dvx_dy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%nu_dvx_dy = SrcMiscData%nu_dvx_dy +ENDIF +IF (ALLOCATED(SrcMiscData%nu_dvx_dz)) THEN + i1_l = LBOUND(SrcMiscData%nu_dvx_dz,1) + i1_u = UBOUND(SrcMiscData%nu_dvx_dz,1) + i2_l = LBOUND(SrcMiscData%nu_dvx_dz,2) + i2_u = UBOUND(SrcMiscData%nu_dvx_dz,2) + IF (.NOT. ALLOCATED(DstMiscData%nu_dvx_dz)) THEN + ALLOCATE(DstMiscData%nu_dvx_dz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%nu_dvx_dz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%nu_dvx_dz = SrcMiscData%nu_dvx_dz +ENDIF +IF (ALLOCATED(SrcMiscData%dnuvx_dy)) THEN + i1_l = LBOUND(SrcMiscData%dnuvx_dy,1) + i1_u = UBOUND(SrcMiscData%dnuvx_dy,1) + i2_l = LBOUND(SrcMiscData%dnuvx_dy,2) + i2_u = UBOUND(SrcMiscData%dnuvx_dy,2) + IF (.NOT. ALLOCATED(DstMiscData%dnuvx_dy)) THEN + ALLOCATE(DstMiscData%dnuvx_dy(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%dnuvx_dy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%dnuvx_dy = SrcMiscData%dnuvx_dy +ENDIF +IF (ALLOCATED(SrcMiscData%dnuvx_dz)) THEN + i1_l = LBOUND(SrcMiscData%dnuvx_dz,1) + i1_u = UBOUND(SrcMiscData%dnuvx_dz,1) + i2_l = LBOUND(SrcMiscData%dnuvx_dz,2) + i2_u = UBOUND(SrcMiscData%dnuvx_dz,2) + IF (.NOT. ALLOCATED(DstMiscData%dnuvx_dz)) THEN + ALLOCATE(DstMiscData%dnuvx_dz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%dnuvx_dz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%dnuvx_dz = SrcMiscData%dnuvx_dz +ENDIF IF (ALLOCATED(SrcMiscData%a)) THEN i1_l = LBOUND(SrcMiscData%a,1) i1_u = UBOUND(SrcMiscData%a,1) @@ -2263,20 +2906,55 @@ SUBROUTINE WD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF DstMiscData%Vx_high = SrcMiscData%Vx_high ENDIF +IF (ALLOCATED(SrcMiscData%Vx_polar)) THEN + i1_l = LBOUND(SrcMiscData%Vx_polar,1) + i1_u = UBOUND(SrcMiscData%Vx_polar,1) + IF (.NOT. ALLOCATED(DstMiscData%Vx_polar)) THEN + ALLOCATE(DstMiscData%Vx_polar(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%Vx_polar.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%Vx_polar = SrcMiscData%Vx_polar +ENDIF +IF (ALLOCATED(SrcMiscData%Vt_wake)) THEN + i1_l = LBOUND(SrcMiscData%Vt_wake,1) + i1_u = UBOUND(SrcMiscData%Vt_wake,1) + IF (.NOT. ALLOCATED(DstMiscData%Vt_wake)) THEN + ALLOCATE(DstMiscData%Vt_wake(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%Vt_wake.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%Vt_wake = SrcMiscData%Vt_wake +ENDIF + DstMiscData%GammaCurl = SrcMiscData%GammaCurl + DstMiscData%Ct_avg = SrcMiscData%Ct_avg END SUBROUTINE WD_CopyMisc - SUBROUTINE WD_DestroyMisc( MiscData, ErrStat, ErrMsg ) + SUBROUTINE WD_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WD_MiscVarType), INTENT(INOUT) :: MiscData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyMisc' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyMisc' + ErrStat = ErrID_None ErrMsg = "" -IF (ALLOCATED(MiscData%dvdr)) THEN - DEALLOCATE(MiscData%dvdr) -ENDIF + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(MiscData%dvtdr)) THEN DEALLOCATE(MiscData%dvtdr) ENDIF @@ -2289,6 +2967,33 @@ SUBROUTINE WD_DestroyMisc( MiscData, ErrStat, ErrMsg ) IF (ALLOCATED(MiscData%vt_shr)) THEN DEALLOCATE(MiscData%vt_shr) ENDIF +IF (ALLOCATED(MiscData%vt_tot2)) THEN + DEALLOCATE(MiscData%vt_tot2) +ENDIF +IF (ALLOCATED(MiscData%vt_amb2)) THEN + DEALLOCATE(MiscData%vt_amb2) +ENDIF +IF (ALLOCATED(MiscData%vt_shr2)) THEN + DEALLOCATE(MiscData%vt_shr2) +ENDIF +IF (ALLOCATED(MiscData%dvx_dy)) THEN + DEALLOCATE(MiscData%dvx_dy) +ENDIF +IF (ALLOCATED(MiscData%dvx_dz)) THEN + DEALLOCATE(MiscData%dvx_dz) +ENDIF +IF (ALLOCATED(MiscData%nu_dvx_dy)) THEN + DEALLOCATE(MiscData%nu_dvx_dy) +ENDIF +IF (ALLOCATED(MiscData%nu_dvx_dz)) THEN + DEALLOCATE(MiscData%nu_dvx_dz) +ENDIF +IF (ALLOCATED(MiscData%dnuvx_dy)) THEN + DEALLOCATE(MiscData%dnuvx_dy) +ENDIF +IF (ALLOCATED(MiscData%dnuvx_dz)) THEN + DEALLOCATE(MiscData%dnuvx_dz) +ENDIF IF (ALLOCATED(MiscData%a)) THEN DEALLOCATE(MiscData%a) ENDIF @@ -2306,6 +3011,12 @@ SUBROUTINE WD_DestroyMisc( MiscData, ErrStat, ErrMsg ) ENDIF IF (ALLOCATED(MiscData%Vx_high)) THEN DEALLOCATE(MiscData%Vx_high) +ENDIF +IF (ALLOCATED(MiscData%Vx_polar)) THEN + DEALLOCATE(MiscData%Vx_polar) +ENDIF +IF (ALLOCATED(MiscData%Vt_wake)) THEN + DEALLOCATE(MiscData%Vt_wake) ENDIF END SUBROUTINE WD_DestroyMisc @@ -2344,11 +3055,6 @@ SUBROUTINE WD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Re_BufSz = 0 Db_BufSz = 0 Int_BufSz = 0 - Int_BufSz = Int_BufSz + 1 ! dvdr allocated yes/no - IF ( ALLOCATED(InData%dvdr) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! dvdr upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%dvdr) ! dvdr - END IF Int_BufSz = Int_BufSz + 1 ! dvtdr allocated yes/no IF ( ALLOCATED(InData%dvtdr) ) THEN Int_BufSz = Int_BufSz + 2*1 ! dvtdr upper/lower bounds for each dimension @@ -2369,6 +3075,51 @@ SUBROUTINE WD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_BufSz = Int_BufSz + 2*2 ! vt_shr upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%vt_shr) ! vt_shr END IF + Int_BufSz = Int_BufSz + 1 ! vt_tot2 allocated yes/no + IF ( ALLOCATED(InData%vt_tot2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! vt_tot2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%vt_tot2) ! vt_tot2 + END IF + Int_BufSz = Int_BufSz + 1 ! vt_amb2 allocated yes/no + IF ( ALLOCATED(InData%vt_amb2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! vt_amb2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%vt_amb2) ! vt_amb2 + END IF + Int_BufSz = Int_BufSz + 1 ! vt_shr2 allocated yes/no + IF ( ALLOCATED(InData%vt_shr2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! vt_shr2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%vt_shr2) ! vt_shr2 + END IF + Int_BufSz = Int_BufSz + 1 ! dvx_dy allocated yes/no + IF ( ALLOCATED(InData%dvx_dy) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! dvx_dy upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%dvx_dy) ! dvx_dy + END IF + Int_BufSz = Int_BufSz + 1 ! dvx_dz allocated yes/no + IF ( ALLOCATED(InData%dvx_dz) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! dvx_dz upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%dvx_dz) ! dvx_dz + END IF + Int_BufSz = Int_BufSz + 1 ! nu_dvx_dy allocated yes/no + IF ( ALLOCATED(InData%nu_dvx_dy) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! nu_dvx_dy upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%nu_dvx_dy) ! nu_dvx_dy + END IF + Int_BufSz = Int_BufSz + 1 ! nu_dvx_dz allocated yes/no + IF ( ALLOCATED(InData%nu_dvx_dz) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! nu_dvx_dz upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%nu_dvx_dz) ! nu_dvx_dz + END IF + Int_BufSz = Int_BufSz + 1 ! dnuvx_dy allocated yes/no + IF ( ALLOCATED(InData%dnuvx_dy) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! dnuvx_dy upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%dnuvx_dy) ! dnuvx_dy + END IF + Int_BufSz = Int_BufSz + 1 ! dnuvx_dz allocated yes/no + IF ( ALLOCATED(InData%dnuvx_dz) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! dnuvx_dz upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%dnuvx_dz) ! dnuvx_dz + END IF Int_BufSz = Int_BufSz + 1 ! a allocated yes/no IF ( ALLOCATED(InData%a) ) THEN Int_BufSz = Int_BufSz + 2*1 ! a upper/lower bounds for each dimension @@ -2399,6 +3150,18 @@ SUBROUTINE WD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_BufSz = Int_BufSz + 2*1 ! Vx_high upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Vx_high) ! Vx_high END IF + Int_BufSz = Int_BufSz + 1 ! Vx_polar allocated yes/no + IF ( ALLOCATED(InData%Vx_polar) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Vx_polar upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vx_polar) ! Vx_polar + END IF + Int_BufSz = Int_BufSz + 1 ! Vt_wake allocated yes/no + IF ( ALLOCATED(InData%Vt_wake) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Vt_wake upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vt_wake) ! Vt_wake + END IF + Re_BufSz = Re_BufSz + 1 ! GammaCurl + Re_BufSz = Re_BufSz + 1 ! Ct_avg IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -2426,21 +3189,6 @@ SUBROUTINE WD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Db_Xferred = 1 Int_Xferred = 1 - IF ( .NOT. ALLOCATED(InData%dvdr) ) THEN - IntKiBuf( Int_Xferred ) = 0 - Int_Xferred = Int_Xferred + 1 - ELSE - IntKiBuf( Int_Xferred ) = 1 - Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%dvdr,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dvdr,1) - Int_Xferred = Int_Xferred + 2 - - DO i1 = LBOUND(InData%dvdr,1), UBOUND(InData%dvdr,1) - ReKiBuf(Re_Xferred) = InData%dvdr(i1) - Re_Xferred = Re_Xferred + 1 - END DO - END IF IF ( .NOT. ALLOCATED(InData%dvtdr) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -2516,88 +3264,293 @@ SUBROUTINE WD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%a) ) THEN + IF ( .NOT. ALLOCATED(InData%vt_tot2) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%a,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%a,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_tot2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_tot2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_tot2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_tot2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_tot2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_tot2,3) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%a,1), UBOUND(InData%a,1) - ReKiBuf(Re_Xferred) = InData%a(i1) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(InData%vt_tot2,3), UBOUND(InData%vt_tot2,3) + DO i2 = LBOUND(InData%vt_tot2,2), UBOUND(InData%vt_tot2,2) + DO i1 = LBOUND(InData%vt_tot2,1), UBOUND(InData%vt_tot2,1) + ReKiBuf(Re_Xferred) = InData%vt_tot2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%b) ) THEN + IF ( .NOT. ALLOCATED(InData%vt_amb2) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%b,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%b,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_amb2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_amb2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_amb2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_amb2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_amb2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_amb2,3) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%b,1), UBOUND(InData%b,1) - ReKiBuf(Re_Xferred) = InData%b(i1) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(InData%vt_amb2,3), UBOUND(InData%vt_amb2,3) + DO i2 = LBOUND(InData%vt_amb2,2), UBOUND(InData%vt_amb2,2) + DO i1 = LBOUND(InData%vt_amb2,1), UBOUND(InData%vt_amb2,1) + ReKiBuf(Re_Xferred) = InData%vt_amb2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%c) ) THEN + IF ( .NOT. ALLOCATED(InData%vt_shr2) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%c,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%c,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_shr2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_shr2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_shr2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_shr2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_shr2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_shr2,3) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%c,1), UBOUND(InData%c,1) - ReKiBuf(Re_Xferred) = InData%c(i1) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(InData%vt_shr2,3), UBOUND(InData%vt_shr2,3) + DO i2 = LBOUND(InData%vt_shr2,2), UBOUND(InData%vt_shr2,2) + DO i1 = LBOUND(InData%vt_shr2,1), UBOUND(InData%vt_shr2,1) + ReKiBuf(Re_Xferred) = InData%vt_shr2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%d) ) THEN + IF ( .NOT. ALLOCATED(InData%dvx_dy) ) THEN 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,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%d,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%dvx_dy,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dvx_dy,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dvx_dy,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dvx_dy,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dvx_dy,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dvx_dy,3) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%d,1), UBOUND(InData%d,1) - ReKiBuf(Re_Xferred) = InData%d(i1) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(InData%dvx_dy,3), UBOUND(InData%dvx_dy,3) + DO i2 = LBOUND(InData%dvx_dy,2), UBOUND(InData%dvx_dy,2) + DO i1 = LBOUND(InData%dvx_dy,1), UBOUND(InData%dvx_dy,1) + ReKiBuf(Re_Xferred) = InData%dvx_dy(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%r_wake) ) THEN + IF ( .NOT. ALLOCATED(InData%dvx_dz) ) THEN 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_wake,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%r_wake,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%dvx_dz,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dvx_dz,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dvx_dz,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dvx_dz,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dvx_dz,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dvx_dz,3) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%r_wake,1), UBOUND(InData%r_wake,1) - ReKiBuf(Re_Xferred) = InData%r_wake(i1) - Re_Xferred = Re_Xferred + 1 + DO i3 = LBOUND(InData%dvx_dz,3), UBOUND(InData%dvx_dz,3) + DO i2 = LBOUND(InData%dvx_dz,2), UBOUND(InData%dvx_dz,2) + DO i1 = LBOUND(InData%dvx_dz,1), UBOUND(InData%dvx_dz,1) + ReKiBuf(Re_Xferred) = InData%dvx_dz(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Vx_high) ) THEN + IF ( .NOT. ALLOCATED(InData%nu_dvx_dy) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_high,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%nu_dvx_dy,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nu_dvx_dy,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%nu_dvx_dy,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nu_dvx_dy,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%nu_dvx_dy,2), UBOUND(InData%nu_dvx_dy,2) + DO i1 = LBOUND(InData%nu_dvx_dy,1), UBOUND(InData%nu_dvx_dy,1) + ReKiBuf(Re_Xferred) = InData%nu_dvx_dy(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%nu_dvx_dz) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%nu_dvx_dz,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nu_dvx_dz,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%nu_dvx_dz,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nu_dvx_dz,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%nu_dvx_dz,2), UBOUND(InData%nu_dvx_dz,2) + DO i1 = LBOUND(InData%nu_dvx_dz,1), UBOUND(InData%nu_dvx_dz,1) + ReKiBuf(Re_Xferred) = InData%nu_dvx_dz(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%dnuvx_dy) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dnuvx_dy,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dnuvx_dy,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dnuvx_dy,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dnuvx_dy,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%dnuvx_dy,2), UBOUND(InData%dnuvx_dy,2) + DO i1 = LBOUND(InData%dnuvx_dy,1), UBOUND(InData%dnuvx_dy,1) + ReKiBuf(Re_Xferred) = InData%dnuvx_dy(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%dnuvx_dz) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dnuvx_dz,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dnuvx_dz,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dnuvx_dz,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dnuvx_dz,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%dnuvx_dz,2), UBOUND(InData%dnuvx_dz,2) + DO i1 = LBOUND(InData%dnuvx_dz,1), UBOUND(InData%dnuvx_dz,1) + ReKiBuf(Re_Xferred) = InData%dnuvx_dz(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%a) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%a,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%a,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%a,1), UBOUND(InData%a,1) + ReKiBuf(Re_Xferred) = InData%a(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%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%b,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%b,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%b,1), UBOUND(InData%b,1) + ReKiBuf(Re_Xferred) = InData%b(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%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%c,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%c,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%c,1), UBOUND(InData%c,1) + ReKiBuf(Re_Xferred) = InData%c(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%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,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%d,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%d,1), UBOUND(InData%d,1) + ReKiBuf(Re_Xferred) = InData%d(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%r_wake) ) THEN + 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_wake,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%r_wake,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%r_wake,1), UBOUND(InData%r_wake,1) + ReKiBuf(Re_Xferred) = InData%r_wake(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Vx_high) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_high,1) IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_high,1) Int_Xferred = Int_Xferred + 2 @@ -2606,6 +3559,40 @@ SUBROUTINE WD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%Vx_polar) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_polar,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_polar,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Vx_polar,1), UBOUND(InData%Vx_polar,1) + ReKiBuf(Re_Xferred) = InData%Vx_polar(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Vt_wake) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vt_wake,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vt_wake,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Vt_wake,1), UBOUND(InData%Vt_wake,1) + ReKiBuf(Re_Xferred) = InData%Vt_wake(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + ReKiBuf(Re_Xferred) = InData%GammaCurl + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%Ct_avg + Re_Xferred = Re_Xferred + 1 END SUBROUTINE WD_PackMisc SUBROUTINE WD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -2623,6 +3610,7 @@ SUBROUTINE WD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) 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 = 'WD_UnPackMisc' @@ -2636,24 +3624,6 @@ SUBROUTINE WD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) Re_Xferred = 1 Db_Xferred = 1 Int_Xferred = 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dvdr not allocated - Int_Xferred = Int_Xferred + 1 - ELSE - Int_Xferred = Int_Xferred + 1 - i1_l = IntKiBuf( Int_Xferred ) - i1_u = IntKiBuf( Int_Xferred + 1) - Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%dvdr)) DEALLOCATE(OutData%dvdr) - ALLOCATE(OutData%dvdr(i1_l:i1_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%dvdr.', ErrStat, ErrMsg,RoutineName) - RETURN - END IF - DO i1 = LBOUND(OutData%dvdr,1), UBOUND(OutData%dvdr,1) - OutData%dvdr(i1) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 - END DO - END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dvtdr not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -2741,6 +3711,238 @@ SUBROUTINE WD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! vt_tot2 not allocated + Int_Xferred = Int_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%vt_tot2)) DEALLOCATE(OutData%vt_tot2) + ALLOCATE(OutData%vt_tot2(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%vt_tot2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%vt_tot2,3), UBOUND(OutData%vt_tot2,3) + DO i2 = LBOUND(OutData%vt_tot2,2), UBOUND(OutData%vt_tot2,2) + DO i1 = LBOUND(OutData%vt_tot2,1), UBOUND(OutData%vt_tot2,1) + OutData%vt_tot2(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 ! vt_amb2 not allocated + Int_Xferred = Int_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%vt_amb2)) DEALLOCATE(OutData%vt_amb2) + ALLOCATE(OutData%vt_amb2(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%vt_amb2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%vt_amb2,3), UBOUND(OutData%vt_amb2,3) + DO i2 = LBOUND(OutData%vt_amb2,2), UBOUND(OutData%vt_amb2,2) + DO i1 = LBOUND(OutData%vt_amb2,1), UBOUND(OutData%vt_amb2,1) + OutData%vt_amb2(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 ! vt_shr2 not allocated + Int_Xferred = Int_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%vt_shr2)) DEALLOCATE(OutData%vt_shr2) + ALLOCATE(OutData%vt_shr2(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%vt_shr2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%vt_shr2,3), UBOUND(OutData%vt_shr2,3) + DO i2 = LBOUND(OutData%vt_shr2,2), UBOUND(OutData%vt_shr2,2) + DO i1 = LBOUND(OutData%vt_shr2,1), UBOUND(OutData%vt_shr2,1) + OutData%vt_shr2(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 ! dvx_dy not allocated + Int_Xferred = Int_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%dvx_dy)) DEALLOCATE(OutData%dvx_dy) + ALLOCATE(OutData%dvx_dy(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%dvx_dy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%dvx_dy,3), UBOUND(OutData%dvx_dy,3) + DO i2 = LBOUND(OutData%dvx_dy,2), UBOUND(OutData%dvx_dy,2) + DO i1 = LBOUND(OutData%dvx_dy,1), UBOUND(OutData%dvx_dy,1) + OutData%dvx_dy(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 ! dvx_dz not allocated + Int_Xferred = Int_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%dvx_dz)) DEALLOCATE(OutData%dvx_dz) + ALLOCATE(OutData%dvx_dz(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%dvx_dz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%dvx_dz,3), UBOUND(OutData%dvx_dz,3) + DO i2 = LBOUND(OutData%dvx_dz,2), UBOUND(OutData%dvx_dz,2) + DO i1 = LBOUND(OutData%dvx_dz,1), UBOUND(OutData%dvx_dz,1) + OutData%dvx_dz(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 ! nu_dvx_dy not allocated + Int_Xferred = Int_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%nu_dvx_dy)) DEALLOCATE(OutData%nu_dvx_dy) + ALLOCATE(OutData%nu_dvx_dy(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nu_dvx_dy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%nu_dvx_dy,2), UBOUND(OutData%nu_dvx_dy,2) + DO i1 = LBOUND(OutData%nu_dvx_dy,1), UBOUND(OutData%nu_dvx_dy,1) + OutData%nu_dvx_dy(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nu_dvx_dz not allocated + Int_Xferred = Int_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%nu_dvx_dz)) DEALLOCATE(OutData%nu_dvx_dz) + ALLOCATE(OutData%nu_dvx_dz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nu_dvx_dz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%nu_dvx_dz,2), UBOUND(OutData%nu_dvx_dz,2) + DO i1 = LBOUND(OutData%nu_dvx_dz,1), UBOUND(OutData%nu_dvx_dz,1) + OutData%nu_dvx_dz(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dnuvx_dy not allocated + Int_Xferred = Int_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%dnuvx_dy)) DEALLOCATE(OutData%dnuvx_dy) + ALLOCATE(OutData%dnuvx_dy(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%dnuvx_dy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%dnuvx_dy,2), UBOUND(OutData%dnuvx_dy,2) + DO i1 = LBOUND(OutData%dnuvx_dy,1), UBOUND(OutData%dnuvx_dy,1) + OutData%dnuvx_dy(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dnuvx_dz not allocated + Int_Xferred = Int_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%dnuvx_dz)) DEALLOCATE(OutData%dnuvx_dz) + ALLOCATE(OutData%dnuvx_dz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%dnuvx_dz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%dnuvx_dz,2), UBOUND(OutData%dnuvx_dz,2) + DO i1 = LBOUND(OutData%dnuvx_dz,1), UBOUND(OutData%dnuvx_dz,1) + OutData%dnuvx_dz(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! a not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -2849,6 +4051,46 @@ SUBROUTINE WD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vx_polar not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vx_polar)) DEALLOCATE(OutData%Vx_polar) + ALLOCATE(OutData%Vx_polar(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vx_polar.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Vx_polar,1), UBOUND(OutData%Vx_polar,1) + OutData%Vx_polar(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vt_wake not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vt_wake)) DEALLOCATE(OutData%Vt_wake) + ALLOCATE(OutData%Vt_wake(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vt_wake.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Vt_wake,1), UBOUND(OutData%Vt_wake,1) + OutData%Vt_wake(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + OutData%GammaCurl = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%Ct_avg = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE WD_UnPackMisc SUBROUTINE WD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) @@ -2882,6 +4124,35 @@ SUBROUTINE WD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) END IF DstParamData%r = SrcParamData%r ENDIF +IF (ALLOCATED(SrcParamData%y)) THEN + i1_l = LBOUND(SrcParamData%y,1) + i1_u = UBOUND(SrcParamData%y,1) + IF (.NOT. ALLOCATED(DstParamData%y)) THEN + ALLOCATE(DstParamData%y(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%y.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%y = SrcParamData%y +ENDIF +IF (ALLOCATED(SrcParamData%z)) THEN + i1_l = LBOUND(SrcParamData%z,1) + i1_u = UBOUND(SrcParamData%z,1) + IF (.NOT. ALLOCATED(DstParamData%z)) THEN + ALLOCATE(DstParamData%z(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%z.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%z = SrcParamData%z +ENDIF + DstParamData%Mod_Wake = SrcParamData%Mod_Wake + DstParamData%Swirl = SrcParamData%Swirl + DstParamData%k_VortexDecay = SrcParamData%k_VortexDecay + DstParamData%sigma_D = SrcParamData%sigma_D + DstParamData%NumVortices = SrcParamData%NumVortices DstParamData%filtParam = SrcParamData%filtParam DstParamData%oneMinusFiltParam = SrcParamData%oneMinusFiltParam DstParamData%C_HWkDfl_O = SrcParamData%C_HWkDfl_O @@ -2901,19 +4172,46 @@ SUBROUTINE WD_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg ) DstParamData%k_vShr = SrcParamData%k_vShr DstParamData%Mod_WakeDiam = SrcParamData%Mod_WakeDiam DstParamData%C_WakeDiam = SrcParamData%C_WakeDiam + DstParamData%FilterInit = SrcParamData%FilterInit + DstParamData%k_vCurl = SrcParamData%k_vCurl + DstParamData%OutAllPlanes = SrcParamData%OutAllPlanes + DstParamData%OutFileRoot = SrcParamData%OutFileRoot + DstParamData%OutFileVTKDir = SrcParamData%OutFileVTKDir + DstParamData%TurbNum = SrcParamData%TurbNum + DstParamData%WAT = SrcParamData%WAT + DstParamData%WAT_k_Def = SrcParamData%WAT_k_Def + DstParamData%WAT_k_Grad = SrcParamData%WAT_k_Grad END SUBROUTINE WD_CopyParam - SUBROUTINE WD_DestroyParam( ParamData, ErrStat, ErrMsg ) + SUBROUTINE WD_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WD_ParameterType), INTENT(INOUT) :: ParamData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyParam' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyParam' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(ParamData%r)) THEN DEALLOCATE(ParamData%r) +ENDIF +IF (ALLOCATED(ParamData%y)) THEN + DEALLOCATE(ParamData%y) +ENDIF +IF (ALLOCATED(ParamData%z)) THEN + DEALLOCATE(ParamData%z) ENDIF END SUBROUTINE WD_DestroyParam @@ -2961,6 +4259,21 @@ SUBROUTINE WD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si 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 ! 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 ! z allocated yes/no + IF ( ALLOCATED(InData%z) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! z upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%z) ! z + END IF + Int_BufSz = Int_BufSz + 1 ! Mod_Wake + Int_BufSz = Int_BufSz + 1 ! Swirl + Re_BufSz = Re_BufSz + 1 ! k_VortexDecay + Re_BufSz = Re_BufSz + 1 ! sigma_D + Int_BufSz = Int_BufSz + 1 ! NumVortices Re_BufSz = Re_BufSz + 1 ! filtParam Re_BufSz = Re_BufSz + 1 ! oneMinusFiltParam Re_BufSz = Re_BufSz + 1 ! C_HWkDfl_O @@ -2980,6 +4293,15 @@ SUBROUTINE WD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Re_BufSz = Re_BufSz + 1 ! k_vShr Int_BufSz = Int_BufSz + 1 ! Mod_WakeDiam Re_BufSz = Re_BufSz + 1 ! C_WakeDiam + Int_BufSz = Int_BufSz + 1 ! FilterInit + Re_BufSz = Re_BufSz + 1 ! k_vCurl + Int_BufSz = Int_BufSz + 1 ! OutAllPlanes + Int_BufSz = Int_BufSz + 1*LEN(InData%OutFileRoot) ! OutFileRoot + Int_BufSz = Int_BufSz + 1*LEN(InData%OutFileVTKDir) ! OutFileVTKDir + Int_BufSz = Int_BufSz + 1 ! TurbNum + Int_BufSz = Int_BufSz + 1 ! WAT + Re_BufSz = Re_BufSz + 1 ! WAT_k_Def + Re_BufSz = Re_BufSz + 1 ! WAT_k_Grad IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -3030,6 +4352,46 @@ SUBROUTINE WD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Re_Xferred = Re_Xferred + 1 END DO END IF + 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%z) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%z,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%z,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%z,1), UBOUND(InData%z,1) + ReKiBuf(Re_Xferred) = InData%z(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IntKiBuf(Int_Xferred) = InData%Mod_Wake + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%Swirl, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%k_VortexDecay + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%sigma_D + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%NumVortices + Int_Xferred = Int_Xferred + 1 ReKiBuf(Re_Xferred) = InData%filtParam Re_Xferred = Re_Xferred + 1 ReKiBuf(Re_Xferred) = InData%oneMinusFiltParam @@ -3068,6 +4430,28 @@ SUBROUTINE WD_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_Xferred = Int_Xferred + 1 ReKiBuf(Re_Xferred) = InData%C_WakeDiam Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = InData%FilterInit + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%k_vCurl + Re_Xferred = Re_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%OutAllPlanes, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(InData%OutFileRoot) + IntKiBuf(Int_Xferred) = ICHAR(InData%OutFileRoot(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(InData%OutFileVTKDir) + IntKiBuf(Int_Xferred) = ICHAR(InData%OutFileVTKDir(I:I), IntKi) + Int_Xferred = Int_Xferred + 1 + END DO ! I + IntKiBuf(Int_Xferred) = InData%TurbNum + Int_Xferred = Int_Xferred + 1 + IntKiBuf(Int_Xferred) = TRANSFER(InData%WAT, IntKiBuf(1)) + Int_Xferred = Int_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WAT_k_Def + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%WAT_k_Grad + Re_Xferred = Re_Xferred + 1 END SUBROUTINE WD_PackParam SUBROUTINE WD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -3123,6 +4507,52 @@ SUBROUTINE WD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 END DO END IF + 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 ! z not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%z)) DEALLOCATE(OutData%z) + ALLOCATE(OutData%z(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%z.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%z,1), UBOUND(OutData%z,1) + OutData%z(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + OutData%Mod_Wake = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%Swirl = TRANSFER(IntKiBuf(Int_Xferred), OutData%Swirl) + Int_Xferred = Int_Xferred + 1 + OutData%k_VortexDecay = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%sigma_D = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%NumVortices = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 OutData%filtParam = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 OutData%oneMinusFiltParam = ReKiBuf(Re_Xferred) @@ -3161,6 +4591,28 @@ SUBROUTINE WD_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Int_Xferred = Int_Xferred + 1 OutData%C_WakeDiam = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 + OutData%FilterInit = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%k_vCurl = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%OutAllPlanes = TRANSFER(IntKiBuf(Int_Xferred), OutData%OutAllPlanes) + Int_Xferred = Int_Xferred + 1 + DO I = 1, LEN(OutData%OutFileRoot) + OutData%OutFileRoot(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + DO I = 1, LEN(OutData%OutFileVTKDir) + OutData%OutFileVTKDir(I:I) = CHAR(IntKiBuf(Int_Xferred)) + Int_Xferred = Int_Xferred + 1 + END DO ! I + OutData%TurbNum = IntKiBuf(Int_Xferred) + Int_Xferred = Int_Xferred + 1 + OutData%WAT = TRANSFER(IntKiBuf(Int_Xferred), OutData%WAT) + Int_Xferred = Int_Xferred + 1 + OutData%WAT_k_Def = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%WAT_k_Grad = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 END SUBROUTINE WD_UnPackParam SUBROUTINE WD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) @@ -3180,6 +4632,9 @@ SUBROUTINE WD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) ErrStat = ErrID_None ErrMsg = "" DstInputData%xhat_disk = SrcInputData%xhat_disk + DstInputData%YawErr = SrcInputData%YawErr + DstInputData%psi_skew = SrcInputData%psi_skew + DstInputData%chi_skew = SrcInputData%chi_skew DstInputData%p_hub = SrcInputData%p_hub IF (ALLOCATED(SrcInputData%V_plane)) THEN i1_l = LBOUND(SrcInputData%V_plane,1) @@ -3211,23 +4666,49 @@ SUBROUTINE WD_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg ) END IF DstInputData%Ct_azavg = SrcInputData%Ct_azavg ENDIF - DstInputData%YawErr = SrcInputData%YawErr +IF (ALLOCATED(SrcInputData%Cq_azavg)) THEN + i1_l = LBOUND(SrcInputData%Cq_azavg,1) + i1_u = UBOUND(SrcInputData%Cq_azavg,1) + IF (.NOT. ALLOCATED(DstInputData%Cq_azavg)) THEN + ALLOCATE(DstInputData%Cq_azavg(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%Cq_azavg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%Cq_azavg = SrcInputData%Cq_azavg +ENDIF END SUBROUTINE WD_CopyInput - SUBROUTINE WD_DestroyInput( InputData, ErrStat, ErrMsg ) + SUBROUTINE WD_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WD_InputType), INTENT(INOUT) :: InputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyInput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyInput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(InputData%V_plane)) THEN DEALLOCATE(InputData%V_plane) ENDIF IF (ALLOCATED(InputData%Ct_azavg)) THEN DEALLOCATE(InputData%Ct_azavg) +ENDIF +IF (ALLOCATED(InputData%Cq_azavg)) THEN + DEALLOCATE(InputData%Cq_azavg) ENDIF END SUBROUTINE WD_DestroyInput @@ -3267,6 +4748,9 @@ SUBROUTINE WD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Db_BufSz = 0 Int_BufSz = 0 Re_BufSz = Re_BufSz + SIZE(InData%xhat_disk) ! xhat_disk + Re_BufSz = Re_BufSz + 1 ! YawErr + Re_BufSz = Re_BufSz + 1 ! psi_skew + Re_BufSz = Re_BufSz + 1 ! chi_skew Re_BufSz = Re_BufSz + SIZE(InData%p_hub) ! p_hub Int_BufSz = Int_BufSz + 1 ! V_plane allocated yes/no IF ( ALLOCATED(InData%V_plane) ) THEN @@ -3282,7 +4766,11 @@ SUBROUTINE WD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Int_BufSz = Int_BufSz + 2*1 ! Ct_azavg upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Ct_azavg) ! Ct_azavg END IF - Re_BufSz = Re_BufSz + 1 ! YawErr + Int_BufSz = Int_BufSz + 1 ! Cq_azavg allocated yes/no + IF ( ALLOCATED(InData%Cq_azavg) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Cq_azavg upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Cq_azavg) ! Cq_azavg + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -3314,6 +4802,12 @@ SUBROUTINE WD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si ReKiBuf(Re_Xferred) = InData%xhat_disk(i1) Re_Xferred = Re_Xferred + 1 END DO + ReKiBuf(Re_Xferred) = InData%YawErr + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%psi_skew + Re_Xferred = Re_Xferred + 1 + ReKiBuf(Re_Xferred) = InData%chi_skew + Re_Xferred = Re_Xferred + 1 DO i1 = LBOUND(InData%p_hub,1), UBOUND(InData%p_hub,1) ReKiBuf(Re_Xferred) = InData%p_hub(i1) Re_Xferred = Re_Xferred + 1 @@ -3361,8 +4855,21 @@ SUBROUTINE WD_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Si Re_Xferred = Re_Xferred + 1 END DO END IF - ReKiBuf(Re_Xferred) = InData%YawErr - Re_Xferred = Re_Xferred + 1 + IF ( .NOT. ALLOCATED(InData%Cq_azavg) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Cq_azavg,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Cq_azavg,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Cq_azavg,1), UBOUND(InData%Cq_azavg,1) + ReKiBuf(Re_Xferred) = InData%Cq_azavg(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE WD_PackInput SUBROUTINE WD_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -3399,6 +4906,12 @@ SUBROUTINE WD_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg OutData%xhat_disk(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO + OutData%YawErr = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%psi_skew = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + OutData%chi_skew = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 i1_l = LBOUND(OutData%p_hub,1) i1_u = UBOUND(OutData%p_hub,1) DO i1 = LBOUND(OutData%p_hub,1), UBOUND(OutData%p_hub,1) @@ -3454,8 +4967,24 @@ SUBROUTINE WD_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 END DO END IF - OutData%YawErr = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Cq_azavg not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Cq_azavg)) DEALLOCATE(OutData%Cq_azavg) + ALLOCATE(OutData%Cq_azavg(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Cq_azavg.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Cq_azavg,1), UBOUND(OutData%Cq_azavg,1) + OutData%Cq_azavg(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF END SUBROUTINE WD_UnPackInput SUBROUTINE WD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg ) @@ -3468,6 +4997,7 @@ SUBROUTINE WD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs 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 = 'WD_CopyOutput' @@ -3530,6 +5060,54 @@ SUBROUTINE WD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs END IF DstOutputData%Vr_wake = SrcOutputData%Vr_wake ENDIF +IF (ALLOCATED(SrcOutputData%Vx_wake2)) THEN + i1_l = LBOUND(SrcOutputData%Vx_wake2,1) + i1_u = UBOUND(SrcOutputData%Vx_wake2,1) + i2_l = LBOUND(SrcOutputData%Vx_wake2,2) + i2_u = UBOUND(SrcOutputData%Vx_wake2,2) + i3_l = LBOUND(SrcOutputData%Vx_wake2,3) + i3_u = UBOUND(SrcOutputData%Vx_wake2,3) + IF (.NOT. ALLOCATED(DstOutputData%Vx_wake2)) THEN + ALLOCATE(DstOutputData%Vx_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%Vx_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%Vx_wake2 = SrcOutputData%Vx_wake2 +ENDIF +IF (ALLOCATED(SrcOutputData%Vy_wake2)) THEN + i1_l = LBOUND(SrcOutputData%Vy_wake2,1) + i1_u = UBOUND(SrcOutputData%Vy_wake2,1) + i2_l = LBOUND(SrcOutputData%Vy_wake2,2) + i2_u = UBOUND(SrcOutputData%Vy_wake2,2) + i3_l = LBOUND(SrcOutputData%Vy_wake2,3) + i3_u = UBOUND(SrcOutputData%Vy_wake2,3) + IF (.NOT. ALLOCATED(DstOutputData%Vy_wake2)) THEN + ALLOCATE(DstOutputData%Vy_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%Vy_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%Vy_wake2 = SrcOutputData%Vy_wake2 +ENDIF +IF (ALLOCATED(SrcOutputData%Vz_wake2)) THEN + i1_l = LBOUND(SrcOutputData%Vz_wake2,1) + i1_u = UBOUND(SrcOutputData%Vz_wake2,1) + i2_l = LBOUND(SrcOutputData%Vz_wake2,2) + i2_u = UBOUND(SrcOutputData%Vz_wake2,2) + i3_l = LBOUND(SrcOutputData%Vz_wake2,3) + i3_u = UBOUND(SrcOutputData%Vz_wake2,3) + IF (.NOT. ALLOCATED(DstOutputData%Vz_wake2)) THEN + ALLOCATE(DstOutputData%Vz_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%Vz_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%Vz_wake2 = SrcOutputData%Vz_wake2 +ENDIF IF (ALLOCATED(SrcOutputData%D_wake)) THEN i1_l = LBOUND(SrcOutputData%D_wake,1) i1_u = UBOUND(SrcOutputData%D_wake,1) @@ -3553,18 +5131,46 @@ SUBROUTINE WD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs END IF END IF DstOutputData%x_plane = SrcOutputData%x_plane +ENDIF +IF (ALLOCATED(SrcOutputData%WAT_k_mt)) THEN + i1_l = LBOUND(SrcOutputData%WAT_k_mt,1) + i1_u = UBOUND(SrcOutputData%WAT_k_mt,1) + i2_l = LBOUND(SrcOutputData%WAT_k_mt,2) + i2_u = UBOUND(SrcOutputData%WAT_k_mt,2) + i3_l = LBOUND(SrcOutputData%WAT_k_mt,3) + i3_u = UBOUND(SrcOutputData%WAT_k_mt,3) + IF (.NOT. ALLOCATED(DstOutputData%WAT_k_mt)) THEN + ALLOCATE(DstOutputData%WAT_k_mt(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%WAT_k_mt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%WAT_k_mt = SrcOutputData%WAT_k_mt ENDIF END SUBROUTINE WD_CopyOutput - SUBROUTINE WD_DestroyOutput( OutputData, ErrStat, ErrMsg ) + SUBROUTINE WD_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) TYPE(WD_OutputType), INTENT(INOUT) :: OutputData INTEGER(IntKi), INTENT( OUT) :: ErrStat CHARACTER(*), INTENT( OUT) :: ErrMsg - CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyOutput' + LOGICAL,OPTIONAL,INTENT(IN ) :: DEALLOCATEpointers + INTEGER(IntKi) :: i, i1, i2, i3, i4, i5 -! + LOGICAL :: DEALLOCATEpointers_local + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'WD_DestroyOutput' + ErrStat = ErrID_None ErrMsg = "" + + IF (PRESENT(DEALLOCATEpointers)) THEN + DEALLOCATEpointers_local = DEALLOCATEpointers + ELSE + DEALLOCATEpointers_local = .true. + END IF + IF (ALLOCATED(OutputData%xhat_plane)) THEN DEALLOCATE(OutputData%xhat_plane) ENDIF @@ -3577,11 +5183,23 @@ SUBROUTINE WD_DestroyOutput( OutputData, ErrStat, ErrMsg ) IF (ALLOCATED(OutputData%Vr_wake)) THEN DEALLOCATE(OutputData%Vr_wake) ENDIF +IF (ALLOCATED(OutputData%Vx_wake2)) THEN + DEALLOCATE(OutputData%Vx_wake2) +ENDIF +IF (ALLOCATED(OutputData%Vy_wake2)) THEN + DEALLOCATE(OutputData%Vy_wake2) +ENDIF +IF (ALLOCATED(OutputData%Vz_wake2)) THEN + DEALLOCATE(OutputData%Vz_wake2) +ENDIF IF (ALLOCATED(OutputData%D_wake)) THEN DEALLOCATE(OutputData%D_wake) ENDIF IF (ALLOCATED(OutputData%x_plane)) THEN DEALLOCATE(OutputData%x_plane) +ENDIF +IF (ALLOCATED(OutputData%WAT_k_mt)) THEN + DEALLOCATE(OutputData%WAT_k_mt) ENDIF END SUBROUTINE WD_DestroyOutput @@ -3640,6 +5258,21 @@ SUBROUTINE WD_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_BufSz = Int_BufSz + 2*2 ! Vr_wake upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Vr_wake) ! Vr_wake END IF + Int_BufSz = Int_BufSz + 1 ! Vx_wake2 allocated yes/no + IF ( ALLOCATED(InData%Vx_wake2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Vx_wake2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vx_wake2) ! Vx_wake2 + END IF + Int_BufSz = Int_BufSz + 1 ! Vy_wake2 allocated yes/no + IF ( ALLOCATED(InData%Vy_wake2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Vy_wake2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vy_wake2) ! Vy_wake2 + END IF + Int_BufSz = Int_BufSz + 1 ! Vz_wake2 allocated yes/no + IF ( ALLOCATED(InData%Vz_wake2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Vz_wake2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vz_wake2) ! Vz_wake2 + END IF Int_BufSz = Int_BufSz + 1 ! D_wake allocated yes/no IF ( ALLOCATED(InData%D_wake) ) THEN Int_BufSz = Int_BufSz + 2*1 ! D_wake upper/lower bounds for each dimension @@ -3650,6 +5283,11 @@ SUBROUTINE WD_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_BufSz = Int_BufSz + 2*1 ! x_plane upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%x_plane) ! x_plane END IF + Int_BufSz = Int_BufSz + 1 ! WAT_k_mt allocated yes/no + IF ( ALLOCATED(InData%WAT_k_mt) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! WAT_k_mt upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%WAT_k_mt) ! WAT_k_mt + END IF IF ( Re_BufSz .GT. 0 ) THEN ALLOCATE( ReKiBuf( Re_BufSz ), STAT=ErrStat2 ) IF (ErrStat2 /= 0) THEN @@ -3757,6 +5395,81 @@ SUBROUTINE WD_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%Vx_wake2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%Vx_wake2,3), UBOUND(InData%Vx_wake2,3) + DO i2 = LBOUND(InData%Vx_wake2,2), UBOUND(InData%Vx_wake2,2) + DO i1 = LBOUND(InData%Vx_wake2,1), UBOUND(InData%Vx_wake2,1) + ReKiBuf(Re_Xferred) = InData%Vx_wake2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Vy_wake2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%Vy_wake2,3), UBOUND(InData%Vy_wake2,3) + DO i2 = LBOUND(InData%Vy_wake2,2), UBOUND(InData%Vy_wake2,2) + DO i1 = LBOUND(InData%Vy_wake2,1), UBOUND(InData%Vy_wake2,1) + ReKiBuf(Re_Xferred) = InData%Vy_wake2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Vz_wake2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%Vz_wake2,3), UBOUND(InData%Vz_wake2,3) + DO i2 = LBOUND(InData%Vz_wake2,2), UBOUND(InData%Vz_wake2,2) + DO i1 = LBOUND(InData%Vz_wake2,1), UBOUND(InData%Vz_wake2,1) + ReKiBuf(Re_Xferred) = InData%Vz_wake2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF IF ( .NOT. ALLOCATED(InData%D_wake) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -3787,6 +5500,31 @@ SUBROUTINE WD_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( .NOT. ALLOCATED(InData%WAT_k_mt) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAT_k_mt,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAT_k_mt,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAT_k_mt,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAT_k_mt,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%WAT_k_mt,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WAT_k_mt,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%WAT_k_mt,3), UBOUND(InData%WAT_k_mt,3) + DO i2 = LBOUND(InData%WAT_k_mt,2), UBOUND(InData%WAT_k_mt,2) + DO i1 = LBOUND(InData%WAT_k_mt,1), UBOUND(InData%WAT_k_mt,1) + ReKiBuf(Re_Xferred) = InData%WAT_k_mt(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF END SUBROUTINE WD_PackOutput SUBROUTINE WD_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) @@ -3804,6 +5542,7 @@ SUBROUTINE WD_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg 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 = 'WD_UnPackOutput' @@ -3909,6 +5648,90 @@ SUBROUTINE WD_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vx_wake2 not allocated + Int_Xferred = Int_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%Vx_wake2)) DEALLOCATE(OutData%Vx_wake2) + ALLOCATE(OutData%Vx_wake2(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%Vx_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%Vx_wake2,3), UBOUND(OutData%Vx_wake2,3) + DO i2 = LBOUND(OutData%Vx_wake2,2), UBOUND(OutData%Vx_wake2,2) + DO i1 = LBOUND(OutData%Vx_wake2,1), UBOUND(OutData%Vx_wake2,1) + OutData%Vx_wake2(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 ! Vy_wake2 not allocated + Int_Xferred = Int_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%Vy_wake2)) DEALLOCATE(OutData%Vy_wake2) + ALLOCATE(OutData%Vy_wake2(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%Vy_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%Vy_wake2,3), UBOUND(OutData%Vy_wake2,3) + DO i2 = LBOUND(OutData%Vy_wake2,2), UBOUND(OutData%Vy_wake2,2) + DO i1 = LBOUND(OutData%Vy_wake2,1), UBOUND(OutData%Vy_wake2,1) + OutData%Vy_wake2(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 ! Vz_wake2 not allocated + Int_Xferred = Int_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%Vz_wake2)) DEALLOCATE(OutData%Vz_wake2) + ALLOCATE(OutData%Vz_wake2(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%Vz_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%Vz_wake2,3), UBOUND(OutData%Vz_wake2,3) + DO i2 = LBOUND(OutData%Vz_wake2,2), UBOUND(OutData%Vz_wake2,2) + DO i1 = LBOUND(OutData%Vz_wake2,1), UBOUND(OutData%Vz_wake2,1) + OutData%Vz_wake2(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_wake not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -3945,6 +5768,34 @@ SUBROUTINE WD_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! WAT_k_mt not allocated + Int_Xferred = Int_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%WAT_k_mt)) DEALLOCATE(OutData%WAT_k_mt) + ALLOCATE(OutData%WAT_k_mt(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%WAT_k_mt.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%WAT_k_mt,3), UBOUND(OutData%WAT_k_mt,3) + DO i2 = LBOUND(OutData%WAT_k_mt,2), UBOUND(OutData%WAT_k_mt,2) + DO i1 = LBOUND(OutData%WAT_k_mt,1), UBOUND(OutData%WAT_k_mt,1) + OutData%WAT_k_mt(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF END SUBROUTINE WD_UnPackOutput END MODULE WakeDynamics_Types diff --git a/reg_tests/CMakeLists.txt b/reg_tests/CMakeLists.txt index 3587cd56d..9a64d7798 100644 --- a/reg_tests/CMakeLists.txt +++ b/reg_tests/CMakeLists.txt @@ -37,54 +37,50 @@ option(CTEST_PLOT_ERRORS "Generate plots of regression test errors." OFF) # Do not display outputs when running openfast, store in log file option(CTEST_RUN_VERBOSE_FLAG "Display run outputs or store to log file." OFF) +option(CTEST_NO_RUN_FLAG "Complete the regression test comparison but do not execute the simulation. Local results must already be generated." OFF) + # Set the OpenFAST executable configuration option and default -set(CTEST_OPENFAST_EXECUTABLE "${CMAKE_BINARY_DIR}/glue-codes/openfast/openfast" CACHE FILEPATH "Specify the OpenFAST executable to use in testing.") +set(CTEST_OPENFAST_EXECUTABLE "${CMAKE_BINARY_DIR}/glue-codes/openfast/openfast${CMAKE_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Specify the OpenFAST executable to use in testing.") if(BUILD_OPENFAST_CPP_API) # Set the OpenFAST executable configuration option and default - set(CTEST_OPENFASTCPP_EXECUTABLE "${CMAKE_BINARY_DIR}/glue-codes/openfast-cpp/openfastcpp" CACHE FILEPATH "Specify the OpenFAST C++ executable to use in testing.") + set(CTEST_OPENFASTCPP_EXECUTABLE "${CMAKE_BINARY_DIR}/glue-codes/openfast-cpp/openfastcpp${CMAKE_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Specify the OpenFAST C++ executable to use in testing.") endif() # Set the FASTFarm executable configuration option and default -set(CTEST_FASTFARM_EXECUTABLE "${CMAKE_BINARY_DIR}/glue-codes/fast-farm/FAST.Farm" CACHE FILEPATH "Specify the FASTFarm executable to use in testing.") +set(CTEST_FASTFARM_EXECUTABLE "${CMAKE_BINARY_DIR}/glue-codes/fast-farm/FAST.Farm${CMAKE_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Specify the FASTFarm executable to use in testing.") # Set the AeroDyn executable configuration option and default set(CTEST_AERODYN_EXECUTABLE "${CMAKE_BINARY_DIR}/modules/aerodyn/aerodyn_driver${CMAKE_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Specify the AeroDyn driver executable to use in testing.") +# Set the UADriver executable configuration option and default +set(CTEST_UADRIVER_EXECUTABLE "${CMAKE_BINARY_DIR}/modules/aerodyn/unsteadyaero_driver${CMAKE_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Specify the UADriver executable to use in testing.") + # Set the BeamDyn executable configuration option and default -set(CTEST_BEAMDYN_EXECUTABLE "${CMAKE_BINARY_DIR}/modules/beamdyn/beamdyn_driver" CACHE FILEPATH "Specify the BeamDyn driver executable to use in testing.") +set(CTEST_BEAMDYN_EXECUTABLE "${CMAKE_BINARY_DIR}/modules/beamdyn/beamdyn_driver${CMAKE_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Specify the BeamDyn driver executable to use in testing.") # 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(CTEST_HYDRODYN_EXECUTABLE "${CMAKE_BINARY_DIR}/modules/hydrodyn/hydrodyn_driver${CMAKE_EXECUTABLE_SUFFIX}" 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(CTEST_SUBDYN_EXECUTABLE "${CMAKE_BINARY_DIR}/modules/subdyn/subdyn_driver${CMAKE_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Specify the SubDyn driver executable to use in testing.") # Set the InflowWind executable configuration option and default -set(CTEST_INFLOWWIND_EXECUTABLE "${CMAKE_BINARY_DIR}/modules/inflowwind/inflowwind_driver" CACHE FILEPATH "Specify the InflowWind 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) - if(NOT EXISTS ${PYTHON_EXECUTABLE}) - message(FATAL_ERROR "CMake cannot find a Python interpreter in your path. Python is required to run OpenFAST tests." ) - endif() -endif() +set(CTEST_INFLOWWIND_EXECUTABLE "${CMAKE_BINARY_DIR}/modules/inflowwind/inflowwind_driver${CMAKE_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Specify the InflowWind driver executable to use in testing.") + +# Set the MoorDyn executable configuration option and default +set(CTEST_MOORDYN_EXECUTABLE "${CMAKE_BINARY_DIR}/modules/moordyn/moordyn_driver${CMAKE_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Specify the MoorDyn driver executable to use in testing.") # Set the testing tolerance -set(CTEST_REGRESSION_TOL "0.00001" CACHE STRING "Set the tolerance for the regression test. Leave empty to automatically set.") -if(NOT ${CTEST_REGRESSION_TOL} STREQUAL "") - set(TOLERANCE ${CTEST_REGRESSION_TOL}) -else(NOT ${CTEST_REGRESSION_TOL} STREQUAL "") - set(TOLERANCE 0.00001) -endif() +set(CTEST_RTEST_RTOL "2" CACHE STRING "Sets the relative orders of magnitude to allow to deviate from the baseline.") +set(CTEST_RTEST_ATOL "1.9" CACHE STRING "Set the absolute orders of magnitude to consider as testable values; any deviations smaller than this always pass.") # include the r-test cmake projects (servodyn controllers) 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 glue-codes/openfast-cpp modules/aerodyn modules/beamdyn modules/hydrodyn modules/subdyn) +foreach(regTest glue-codes/openfast glue-codes/openfast-cpp modules/aerodyn modules/beamdyn modules/hydrodyn modules/inflowwind modules/moordyn modules/subdyn) file(MAKE_DIRECTORY ${CTEST_BINARY_DIR}/${regTest}) endforeach() @@ -163,9 +159,8 @@ add_custom_command( ) add_custom_target( - regression_tests + regression_test_controllers DEPENDS - openfast "${of_dest}/DISCON.dll" "${of_dest}/DISCON_ITIBarge.dll" "${of_dest}/DISCON_OC3Hywind.dll" @@ -176,3 +171,21 @@ add_custom_target( "${ff_dest}/DISCON_WT2.dll" "${ff_dest}/DISCON_WT3.dll" ) + +add_custom_target( + regression_tests ALL + DEPENDS + openfast + regression_test_controllers +) + +add_custom_target( + regression_test_module_drivers ALL + DEPENDS + aerodyn_driver + beamdyn_driver + hydrodyn_driver + inflowwind_driver + moordyn_driver + subdyn_driver +) diff --git a/reg_tests/CTestList.cmake b/reg_tests/CTestList.cmake index 754243336..0e04de8a9 100644 --- a/reg_tests/CTestList.cmake +++ b/reg_tests/CTestList.cmake @@ -19,7 +19,6 @@ #=============================================================================== function(regression TEST_SCRIPT EXECUTABLE SOURCE_DIRECTORY BUILD_DIRECTORY TESTNAME LABEL) - file(TO_NATIVE_PATH "${PYTHON_EXECUTABLE}" PYTHON_EXECUTABLE) file(TO_NATIVE_PATH "${EXECUTABLE}" EXECUTABLE) file(TO_NATIVE_PATH "${TEST_SCRIPT}" TEST_SCRIPT) @@ -49,18 +48,23 @@ function(regression TEST_SCRIPT EXECUTABLE SOURCE_DIRECTORY BUILD_DIRECTORY TEST set(TESTDIR ${extra_args}) endif() + set(NO_RUN_FLAG "") + if(CTEST_NO_RUN_FLAG) + set(NO_RUN_FLAG "-n") + endif() + add_test( - ${TESTNAME} ${PYTHON_EXECUTABLE} + ${TESTNAME} ${Python_EXECUTABLE} ${TEST_SCRIPT} ${TESTDIR} ${EXECUTABLE} ${SOURCE_DIRECTORY} # openfast source directory ${BUILD_DIRECTORY} # build directory for test - ${TOLERANCE} - ${CMAKE_SYSTEM_NAME} # [Darwin,Linux,Windows] - ${CMAKE_Fortran_COMPILER_ID} # [Intel,GNU] + ${CTEST_RTEST_RTOL} + ${CTEST_RTEST_ATOL} ${PLOT_FLAG} # empty or "-p" ${RUN_VERBOSE_FLAG} # empty or "-v" + ${NO_RUN_FLAG} # empty or "-n" ) # limit each test to 90 minutes: 5400s set_tests_properties(${TESTNAME} PROPERTIES TIMEOUT 5400 WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" LABELS "${LABEL}") @@ -79,13 +83,13 @@ function(of_regression TESTNAME LABEL) regression(${TEST_SCRIPT} ${OPENFAST_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} ${TESTNAME} "${LABEL}") endfunction(of_regression) -function(of_cpp_regression TESTNAME LABEL) +function(of_fastlib_regression TESTNAME LABEL) set(TEST_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/executeOpenfastRegressionCase.py") set(OPENFAST_EXECUTABLE "${CMAKE_BINARY_DIR}/glue-codes/openfast/openfast_cpp") set(SOURCE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/..") set(BUILD_DIRECTORY "${CTEST_BINARY_DIR}/glue-codes/openfast") - regression(${TEST_SCRIPT} ${OPENFAST_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} "${TESTNAME}_cpp" "${LABEL}" ${TESTNAME}) -endfunction(of_cpp_regression) + regression(${TEST_SCRIPT} ${OPENFAST_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} "${TESTNAME}_fastlib" "${LABEL}" ${TESTNAME}) +endfunction(of_fastlib_regression) # openfast aeroacoustic function(of_regression_aeroacoustic TESTNAME LABEL) @@ -141,6 +145,26 @@ function(ad_regression TESTNAME LABEL) regression(${TEST_SCRIPT} ${AERODYN_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} ${TESTNAME} "${LABEL}") endfunction(ad_regression) +# aerodyn-Py +function(py_ad_regression TESTNAME LABEL) + set(TEST_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/executeAerodynPyRegressionCase.py") + set(AERODYN_EXECUTABLE "${Python_EXECUTABLE}") + set(SOURCE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/..") + set(BUILD_DIRECTORY "${CTEST_BINARY_DIR}/modules/aerodyn") + regression(${TEST_SCRIPT} ${AERODYN_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} ${TESTNAME} "${LABEL}") +endfunction(py_ad_regression) + + +# UnsteadyAero driver +function(ua_regression TESTNAME LABEL) + set(TEST_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/executeUnsteadyAeroRegressionCase.py") + set(AERODYN_EXECUTABLE "${CTEST_UADRIVER_EXECUTABLE}") + set(SOURCE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/..") + set(BUILD_DIRECTORY "${CTEST_BINARY_DIR}/modules/unsteadyaero") + regression(${TEST_SCRIPT} ${AERODYN_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} ${TESTNAME} "${LABEL}") +endfunction(ua_regression) + + # beamdyn function(bd_regression TESTNAME LABEL) set(TEST_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/executeBeamdynRegressionCase.py") @@ -159,14 +183,14 @@ function(hd_regression TESTNAME LABEL) regression(${TEST_SCRIPT} ${HYDRODYN_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} ${TESTNAME} "${LABEL}") endfunction(hd_regression) -# hydrodyn-Py -function(hd_py_regression TESTNAME LABEL) +# py_hydrodyn +function(py_hd_regression TESTNAME LABEL) set(TEST_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/executeHydrodynPyRegressionCase.py") - set(HYDRODYN_EXECUTABLE "${PYTHON_EXECUTABLE}") + set(HYDRODYN_EXECUTABLE "${Python_EXECUTABLE}") set(SOURCE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/..") set(BUILD_DIRECTORY "${CTEST_BINARY_DIR}/modules/hydrodyn") regression(${TEST_SCRIPT} ${HYDRODYN_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} ${TESTNAME} "${LABEL}") -endfunction(hd_py_regression) +endfunction(py_hd_regression) # subdyn function(sd_regression TESTNAME LABEL) @@ -186,20 +210,38 @@ function(ifw_regression TESTNAME LABEL) regression(${TEST_SCRIPT} ${INFLOWWIND_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} ${TESTNAME} "${LABEL}") endfunction(ifw_regression) -# inflowwind-Py -function(ifw_py_regression TESTNAME LABEL) +# py_inflowwind +function(py_ifw_regression TESTNAME LABEL) set(TEST_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/executeInflowwindPyRegressionCase.py") - set(INFLOWWIND_EXECUTABLE "${PYTHON_EXECUTABLE}") + set(INFLOWWIND_EXECUTABLE "${Python_EXECUTABLE}") set(SOURCE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/..") set(BUILD_DIRECTORY "${CTEST_BINARY_DIR}/modules/inflowwind") regression(${TEST_SCRIPT} ${INFLOWWIND_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} ${TESTNAME} "${LABEL}") -endfunction(ifw_py_regression) +endfunction(py_ifw_regression) + +# moordyn +function(md_regression TESTNAME LABEL) + set(TEST_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/executeMoordynRegressionCase.py") + set(MOORDYN_EXECUTABLE "${CTEST_MOORDYN_EXECUTABLE}") + set(SOURCE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/..") + set(BUILD_DIRECTORY "${CTEST_BINARY_DIR}/modules/moordyn") + regression(${TEST_SCRIPT} ${MOORDYN_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} ${TESTNAME} "${LABEL}") +endfunction(md_regression) + +# py_moordyn c-bindings interface +function(py_md_regression TESTNAME LABEL) + set(TEST_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/executeMoordynPyRegressionCase.py") + set(MOORDYN_EXECUTABLE "${Python_EXECUTABLE}") + set(SOURCE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/..") + set(BUILD_DIRECTORY "${CTEST_BINARY_DIR}/modules/moordyn") + regression(${TEST_SCRIPT} ${MOORDYN_EXECUTABLE} ${SOURCE_DIRECTORY} ${BUILD_DIRECTORY} ${TESTNAME} "${LABEL}") +endfunction(py_md_regression) # # Python-based OpenFAST Library tests # function(py_openfast_library_regression TESTNAME LABEL) # set(test_module "${CMAKE_SOURCE_DIR}/modules/openfast-library/tests/test_openfast_library.py") # set(input_file "${CMAKE_SOURCE_DIR}/reg_tests/r-test/glue-codes/openfast/5MW_OC4Jckt_ExtPtfm/5MW_OC4Jckt_ExtPtfm.fst") -# add_test(${TESTNAME} ${PYTHON_EXECUTABLE} ${test_module} ${input_file} ) +# add_test(${TESTNAME} ${Python_EXECUTABLE} ${test_module} ${input_file} ) # endfunction(py_openfast_library_regression) @@ -216,51 +258,49 @@ of_regression("AWT_WSt_StartUpShutDown" "openfast;elastodyn;aerodyn15;se of_regression("AOC_WSt" "openfast;elastodyn;aerodyn14;servodyn") of_regression("AOC_YFree_WTurb" "openfast;elastodyn;aerodyn15;servodyn") of_regression("AOC_YFix_WSt" "openfast;elastodyn;aerodyn15;servodyn") -of_regression("UAE_Dnwind_YRamp_WSt" "openfast;elastodyn;aerodyn14;servodyn") +# of_regression("UAE_Dnwind_YRamp_WSt" "openfast;elastodyn;aerodyn14;servodyn") of_regression("UAE_Upwind_Rigid_WRamp_PwrCurve" "openfast;elastodyn;aerodyn15;servodyn") of_regression("WP_VSP_WTurb_PitchFail" "openfast;elastodyn;aerodyn14;servodyn") of_regression("WP_VSP_ECD" "openfast;elastodyn;aerodyn15;servodyn") of_regression("WP_VSP_WTurb" "openfast;elastodyn;aerodyn15;servodyn") of_regression("SWRT_YFree_VS_EDG01" "openfast;elastodyn;aerodyn15;servodyn") of_regression("SWRT_YFree_VS_EDC01" "openfast;elastodyn;aerodyn14;servodyn") -of_regression("SWRT_YFree_VS_WTurb" "openfast;elastodyn;aerodyn14;servodyn") +# of_regression("SWRT_YFree_VS_WTurb" "openfast;elastodyn;aerodyn14;servodyn") of_regression("5MW_Land_DLL_WTurb" "openfast;elastodyn;aerodyn15;servodyn") of_regression("5MW_OC3Mnpl_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") of_regression("5MW_OC3Trpd_DLL_WSt_WavesReg" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") -of_regression("5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") -of_regression("5MW_ITIBarge_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn14;servodyn;hydrodyn;map;offshore") +# of_regression("5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;subdyn;offshore") +# of_regression("5MW_ITIBarge_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn14;servodyn;hydrodyn;map;offshore") of_regression("5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") of_regression("5MW_OC3Spar_DLL_WTurb_WavesIrr" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") of_regression("5MW_OC4Semi_WSt_WavesWN" "openfast;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") of_regression("5MW_Land_BD_DLL_WTurb" "openfast;beamdyn;aerodyn15;servodyn") +of_regression("5MW_Land_BD_Init" "openfast;beamdyn;aerodyn15;servodyn") of_regression("5MW_OC4Jckt_ExtPtfm" "openfast;elastodyn;extptfm") of_regression("HelicalWake_OLAF" "openfast;aerodyn15;olaf") of_regression("EllipticalWing_OLAF" "openfast;aerodyn15;olaf") of_regression("StC_test_OC4Semi" "openfast;servodyn;hydrodyn;moordyn;offshore;stc") +of_regression("MHK_RM1_Fixed" "openfast;elastodyn;aerodyn15;mhk") +of_regression("MHK_RM1_Floating" "openfast;elastodyn;aerodyn15;hydrodyn;moordyn;mhk") # OpenFAST C++ API test if(BUILD_OPENFAST_CPP_API) - of_cpp_interface_regression("5MW_Land_DLL_WTurb_cpp" "openfast;openfastlib;cpp") + of_cpp_interface_regression("5MW_Land_DLL_WTurb_cpp" "openfast;fastlib;cpp") endif() -# # Python-based OpenFAST Library unit tests -# if(BUILD_SHARED_LIBS) -# py_openfast_library_regression("py_openfastlib" "python;openfastlib") -# endif() - -# OpenFAST C++ Driver test +# OpenFAST C++ Driver test for OpenFAST Library # This tests the FAST Library and FAST_Library.h -of_cpp_regression("AWT_YFree_WSt" "openfast;openfastlib;cpp;elastodyn;aerodyn15;servodyn") +of_fastlib_regression("AWT_YFree_WSt" "fastlib;elastodyn;aerodyn15;servodyn") # OpenFAST Python API test -of_regression_py("5MW_Land_DLL_WTurb_py" "openfast;openfastlib;python;elastodyn;aerodyn15;servodyn") -of_regression_py("5MW_ITIBarge_DLL_WTurb_WavesIrr_py" "openfast;openfastlib;python;elastodyn;aerodyn14;servodyn;hydrodyn;map;offshore") -of_regression_py("5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti_py" "openfast;openfastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -of_regression_py("5MW_OC3Spar_DLL_WTurb_WavesIrr_py" "openfast;openfastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") -of_regression_py("5MW_OC4Semi_WSt_WavesWN_py" "openfast;openfastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") -of_regression_py("5MW_Land_BD_DLL_WTurb_py" "openfast;openfastlib;python;beamdyn;aerodyn15;servodyn") -of_regression_py("HelicalWake_OLAF_py" "openfast;openfastlib;python;aerodyn15;olaf") -of_regression_py("EllipticalWing_OLAF_py" "openfast;openfastlib;python;aerodyn15;olaf") +of_regression_py("5MW_Land_DLL_WTurb_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn") +#of_regression_py("5MW_ITIBarge_DLL_WTurb_WavesIrr_py" "openfast;fastlib;python;elastodyn;aerodyn14;servodyn;hydrodyn;map;offshore") +of_regression_py("5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +of_regression_py("5MW_OC3Spar_DLL_WTurb_WavesIrr_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;map;offshore") +of_regression_py("5MW_OC4Semi_WSt_WavesWN_py" "openfast;fastlib;python;elastodyn;aerodyn15;servodyn;hydrodyn;moordyn;offshore") +of_regression_py("5MW_Land_BD_DLL_WTurb_py" "openfast;fastlib;python;beamdyn;aerodyn15;servodyn") +of_regression_py("HelicalWake_OLAF_py" "openfast;fastlib;python;aerodyn15;olaf") +of_regression_py("EllipticalWing_OLAF_py" "openfast;fastlib;python;aerodyn15;olaf") # AeroAcoustic regression test of_regression_aeroacoustic("IEA_LB_RWT-AeroAcoustics" "openfast;aerodyn15;aeroacoustics") @@ -278,6 +318,8 @@ of_regression_linear("StC_test_OC4Semi_Linear_Tow" "openfast;linear;servodyn;st if(BUILD_FASTFARM) ff_regression("TSinflow" "fastfarm") ff_regression("LESinflow" "fastfarm") +# ff_regression("Uninflow_curl" "fastfarm") + ff_regression("TSinflow_curl" "fastfarm") endif() # AeroDyn regression tests @@ -288,10 +330,17 @@ ad_regression("ad_Kite_OLAF" "aerodyn;bem") ad_regression("ad_MultipleHAWT" "aerodyn;bem") ad_regression("ad_QuadRotor_OLAF" "aerodyn;bem") ad_regression("ad_VerticalAxis_OLAF" "aerodyn;bem") +ad_regression("ad_MHK_RM1_Fixed" "aerodyn;bem;mhk") +ad_regression("ad_MHK_RM1_Floating" "aerodyn;bem;mhk") ad_regression("ad_BAR_CombinedCases" "aerodyn;bem") # NOTE: doing BAR at the end to avoid copy errors ad_regression("ad_BAR_OLAF" "aerodyn;bem") ad_regression("ad_BAR_SineMotion" "aerodyn;bem") +ad_regression("ad_BAR_SineMotion_UA4_DBEMT3" "aerodyn;bem") ad_regression("ad_BAR_RNAMotion" "aerodyn;bem") +py_ad_regression("py_ad_5MW_OC4Semi_WSt_WavesWN" "aerodyn;bem;python") + +# UnsteadyAero +ua_regression("ua_redfreq" "unsteadyaero") # BeamDyn regression tests bd_regression("bd_5MW_dynamic" "beamdyn;dynamic") @@ -304,14 +353,19 @@ bd_regression("bd_static_twisted_with_k1" "beamdyn;static") # HydroDyn regression tests hd_regression("hd_OC3tripod_offshore_fixedbottom_wavesirr" "hydrodyn;offshore") -hd_regression("hd_5MW_ITIBarge_DLL_WTurb_WavesIrr" "hydrodyn;offshore") +#hd_regression("hd_5MW_ITIBarge_DLL_WTurb_WavesIrr" "hydrodyn;offshore") hd_regression("hd_5MW_OC3Spar_DLL_WTurb_WavesIrr" "hydrodyn;offshore") +#hd_regression("hd_5MW_OC4Jckt_DLL_WTurb_WavesIrr_MGrowth" "hydrodyn;offshore") hd_regression("hd_5MW_OC4Semi_WSt_WavesWN" "hydrodyn;offshore") hd_regression("hd_5MW_TLP_DLL_WTurb_WavesIrr_WavesMulti" "hydrodyn;offshore") hd_regression("hd_TaperCylinderPitchMoment" "hydrodyn;offshore") +hd_regression("hd_NBodyMod1" "hydrodyn;offshore") +hd_regression("hd_NBodyMod2" "hydrodyn;offshore") +hd_regression("hd_NBodyMod3" "hydrodyn;offshore") + -# HydroDyn-Py regression tests -hd_py_regression("hd_py_5MW_OC4Semi_WSt_WavesWN" "hydrodyn;offshore;python") +# Py-HydroDyn regression tests +py_hd_regression("py_hd_5MW_OC4Semi_WSt_WavesWN" "hydrodyn;offshore;python") # SubDyn regression tests sd_regression("SD_Cable_5Joints" "subdyn;offshore") @@ -328,4 +382,18 @@ sd_regression("SD_AnsysComp3_PinBeamCable" "subdyn;offshore") # InflowWind regression tests ifw_regression("ifw_turbsimff" "inflowwind") -ifw_py_regression("ifw_py_turbsimff" "inflowwind;python") +ifw_regression("ifw_uniform" "inflowwind") +ifw_regression("ifw_nativeBladed" "inflowwind") +ifw_regression("ifw_BoxExceed" "inflowwind") +ifw_regression("ifw_BoxExceedTwr" "inflowwind") + +# Py-InflowWind regression tests +py_ifw_regression("py_ifw_turbsimff" "inflowwind;python") + +# MoorDyn regression tests +md_regression("md_5MW_OC4Semi" "moordyn") +py_md_regression("py_md_5MW_OC4Semi" "moordyn;python") +# the following tests are excessively slow in double precision, so skip these in normal testing +#md_regression("md_Node_Check_N20" "moordyn") +#md_regression("md_Node_Check_N40" "moordyn") +#md_regression("md_Single_Line_Quasi_Static_Test" "moordyn") diff --git a/reg_tests/README.md b/reg_tests/README.md index 12f84f2f0..aaa320639 100644 --- a/reg_tests/README.md +++ b/reg_tests/README.md @@ -10,7 +10,7 @@ Dependencies required to run the regression test suite are - Python 3.7+ - Numpy - CMake and CTest -- Bokeh 1.4 (optional) +- Bokeh 2.4+ (optional) ## Execution The automated regression test runs CTest and can be executed by running either of the commands `make test` or `ctest` from the build directory. If the entire OpenFAST package is to be built, CMake will configure CTest to find the new binary at `openfast/build/glue-codes/openfast/openfast`. However, if the intention is to build only the test suite, the OpenFAST binary should be specified in the CMake configuration under the `CTEST_OPENFAST_EXECUTABLE` flag. There is also a corresponding `CTEST_[MODULE]_NAME` flag for each module that is included in the regression test. diff --git a/reg_tests/executeAerodynPyRegressionCase.py b/reg_tests/executeAerodynPyRegressionCase.py new file mode 100644 index 000000000..34dd3f551 --- /dev/null +++ b/reg_tests/executeAerodynPyRegressionCase.py @@ -0,0 +1,137 @@ +# +# 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 AeroDyn 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: `executeAerodynPyRegressionCase.py -h` +""" + +import os +import sys +basepath = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, os.path.sep.join([basepath, "lib"])) +import argparse +import numpy as np +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 OpenFAST 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="AeroDyn-Inflow-Python", type=str, nargs=1, help="The path to the AeroDyn 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") +parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases") +parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases") +parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', 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] +rtol = args.rtol[0] +atol = args.atol[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", "aerodyn") +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 and initialize it with input files +rtl.copyTree(inputsDirectory, testBuildDirectory, renameDict={'py_ad_driver.out':'py_ad_driver_ref.out'}) + # , excludeExt=['.out','.outb']) + +### Run aerodyn on the test case +if not noExec: + caseInputFile = os.path.join(testBuildDirectory, "py_ad_driver.py") + returnCode = openfastDrivers.runAerodynDriverCase(caseInputFile, executable, verbose=verbose) + if returnCode != 0: + sys.exit(returnCode*10) + +###Build the filesystem navigation variables for running the regression test +# For multiple turbines, test turbine 2, for combined cases, test case 4 +localOutFile = os.path.join(testBuildDirectory, "py_ad_driver.out") +baselineOutFile = os.path.join(targetOutputDirectory, os.path.basename(localOutFile)) +rtl.validateFileOrExit(localOutFile) +rtl.validateFileOrExit(baselineOutFile) + +testData, testInfo, _ = pass_fail.readFASTOut(localOutFile) +baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile) + +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T + +norms = pass_fail.calculateNorms(testData, baselineData) + +# export all case summaries +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) + +# passing case +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeAerodynRegressionCase.py b/reg_tests/executeAerodynRegressionCase.py index 146291473..98cae5838 100644 --- a/reg_tests/executeAerodynRegressionCase.py +++ b/reg_tests/executeAerodynRegressionCase.py @@ -27,6 +27,7 @@ basepath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.sep.join([basepath, "lib"])) import argparse +import numpy as np import shutil import glob import subprocess @@ -46,9 +47,8 @@ parser.add_argument("executable", metavar="AeroDyn-Driver", type=str, nargs=1, help="The path to the AeroDyn 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases") parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases") parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', help="bool to include verbose system output") @@ -59,9 +59,8 @@ executable = args.executable[0] sourceDirectory = args.sourceDirectory[0] buildDirectory = args.buildDirectory[0] -tolerance = args.tolerance[0] - - +rtol = args.rtol[0] +atol = args.atol[0] plotError = args.plot noExec = args.noExec verbose = args.verbose @@ -110,46 +109,47 @@ caseInputFile = os.path.join(testBuildDirectory, "ad_driver.dvr") returnCode = openfastDrivers.runAerodynDriverCase(caseInputFile, executable, verbose=verbose) if returnCode != 0: - rtl.exitWithError("") + sys.exit(returnCode*10) -###Build the filesystem navigation variables for running the regression test +### Build the filesystem navigation variables for running the regression test # For multiple turbines, test turbine 2, for combined cases, test case 4 localOutFile = os.path.join(testBuildDirectory, "ad_driver.outb") localOutFileWT2 = os.path.join(testBuildDirectory, "ad_driver.T2.outb") localOutFileCase4 = os.path.join(testBuildDirectory, "ad_driver.4.outb") if os.path.exists(localOutFileWT2) : - localOutFile=localOutFileWT2 + localOutFile = localOutFileWT2 elif os.path.exists(localOutFileCase4) : - localOutFile=localOutFileCase4 + localOutFile = localOutFileCase4 baselineOutFile = os.path.join(targetOutputDirectory, os.path.basename(localOutFile)) + rtl.validateFileOrExit(localOutFile) rtl.validateFileOrExit(baselineOutFile) -testData, testInfo, testPack = pass_fail.readFASTOut(localOutFile) +testData, testInfo, _ = pass_fail.readFASTOut(localOutFile) baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile) -performance = pass_fail.calculateNorms(testData, baselineData) -normalizedNorm = performance[:, 1] + +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T + +norms = pass_fail.calculateNorms(testData, baselineData) # export all case summaries -results = list(zip(testInfo["attribute_names"], [*performance])) -results_max = performance.max(axis=0) -exportCaseSummary(testBuildDirectory, caseName, results, results_max, tolerance) +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) -# 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) +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeBeamdynRegressionCase.py b/reg_tests/executeBeamdynRegressionCase.py index 93dbc01f7..aa40c473b 100644 --- a/reg_tests/executeBeamdynRegressionCase.py +++ b/reg_tests/executeBeamdynRegressionCase.py @@ -27,6 +27,7 @@ basepath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.sep.join([basepath, "lib"])) import argparse +import numpy as np import shutil import subprocess import rtestlib as rtl @@ -45,9 +46,8 @@ parser.add_argument("executable", metavar="BeamDyn-Driver", type=str, nargs=1, help="The path to the BeamDyn 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases") parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases") parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', help="bool to include verbose system output") @@ -58,7 +58,8 @@ executable = args.executable[0] sourceDirectory = args.sourceDirectory[0] buildDirectory = args.buildDirectory[0] -tolerance = args.tolerance[0] +rtol = args.rtol[0] +atol = args.atol[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 @@ -99,7 +100,7 @@ caseInputFile = os.path.join(testBuildDirectory, "bd_driver.inp") returnCode = openfastDrivers.runBeamdynDriverCase(caseInputFile, executable) if returnCode != 0: - rtl.exitWithError("") + sys.exit(returnCode*10) ### Build the filesystem navigation variables for running the regression test localOutFile = os.path.join(testBuildDirectory, "bd_driver.out") @@ -107,31 +108,31 @@ rtl.validateFileOrExit(localOutFile) rtl.validateFileOrExit(baselineOutFile) -testData, testInfo, testPack = pass_fail.readFASTOut(localOutFile) +testData, testInfo, _ = pass_fail.readFASTOut(localOutFile) baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile) -performance = pass_fail.calculateNorms(testData, baselineData) -normalizedNorm = performance[:, 1] + +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T + +norms = pass_fail.calculateNorms(testData, baselineData) # export all case summaries -results = list(zip(testInfo["attribute_names"], [*performance])) -results_max = performance.max(axis=0) -exportCaseSummary(testBuildDirectory, caseName, results, results_max, tolerance) +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) -# 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) +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeFASTFarmRegressionCase.py b/reg_tests/executeFASTFarmRegressionCase.py index 273637bb4..9796b2e89 100644 --- a/reg_tests/executeFASTFarmRegressionCase.py +++ b/reg_tests/executeFASTFarmRegressionCase.py @@ -27,6 +27,7 @@ basepath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.sep.join([basepath, "lib"])) import argparse +import numpy as np import shutil import subprocess import rtestlib as rtl @@ -35,13 +36,7 @@ from errorPlotting import exportCaseSummary ##### Helper functions -def ignoreBaselineItems(directory, contents): - itemFilter = ['linux-intel', 'linux-gnu', 'macos-gnu', 'windows-intel'] - caught = [] - for c in contents: - if c in itemFilter: - caught.append(c) - return tuple(caught) +excludeExt=['.out','.outb','.ech','.yaml','.sum','.log'] ##### Main program @@ -54,9 +49,8 @@ def ignoreBaselineItems(directory, contents): parser.add_argument("executable", metavar="OpenFAST", type=str, nargs=1, help="The path to the OpenFAST 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases") parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases") parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', help="bool to include verbose system output") @@ -67,9 +61,8 @@ def ignoreBaselineItems(directory, contents): executable = args.executable[0] sourceDirectory = args.sourceDirectory[0] buildDirectory = args.buildDirectory[0] -tolerance = args.tolerance[0] -systemName = args.systemName[0] -compilerId = args.compilerId[0] +rtol = args.rtol[0] +atol = args.atol[0] plotError = args.plot noExec = args.noExec verbose = args.verbose @@ -80,25 +73,6 @@ def ignoreBaselineItems(directory, contents): if not os.path.isdir(buildDirectory): os.makedirs(buildDirectory) -### Map the system and compiler configurations to a solution set -# Internal names -> Human readable names -systemName_map = { - "darwin": "macos", - "linux": "linux", - "windows": "windows" -} -compilerId_map = { - "gnu": "gnu", - "intel": "intel" -} -# Build the target output directory name or choose the default -supportedBaselines = ["macos-gnu", "linux-intel", "linux-gnu", "windows-intel"] -targetSystem = systemName_map.get(systemName.lower(), "") -targetCompiler = compilerId_map.get(compilerId.lower(), "") -outputType = os.path.join(targetSystem+"-"+targetCompiler) -if outputType not in supportedBaselines: - outputType = supportedBaselines[0] -print("-- Using gold standard files with machine-compiler type {}".format(outputType)) ### Build the filesystem navigation variables for running openfast on the test case regtests = os.path.join(sourceDirectory, "reg_tests") @@ -106,7 +80,7 @@ def ignoreBaselineItems(directory, contents): rtest = os.path.join(regtests, "r-test") moduleDirectory = os.path.join(rtest, "glue-codes", "fast-farm") inputsDirectory = os.path.join(moduleDirectory, caseName) -targetOutputDirectory = os.path.join(inputsDirectory) #, outputType) +targetOutputDirectory = os.path.join(inputsDirectory) testBuildDirectory = os.path.join(buildDirectory, caseName) # verify all the required directories exist @@ -121,7 +95,7 @@ def ignoreBaselineItems(directory, contents): dst = os.path.join(buildDirectory, "5MW_Baseline") src = os.path.join(moduleDirectory, "5MW_Baseline") if not os.path.isdir(dst): - shutil.copytree(src, dst) + rtl.copyTree(src, dst, excludeExt=excludeExt) else: names = os.listdir(src) for name in names: @@ -131,19 +105,21 @@ def ignoreBaselineItems(directory, contents): dstname = os.path.join(dst, name) if os.path.isdir(srcname): if not os.path.isdir(dstname): - shutil.copytree(srcname, dstname) + rtl.copyTree(srcname, dstname, excludeExt=excludeExt) else: shutil.copy2(srcname, dstname) if not os.path.isdir(testBuildDirectory): - shutil.copytree(inputsDirectory, testBuildDirectory, ignore=ignoreBaselineItems) + rtl.copyTree(inputsDirectory, testBuildDirectory, excludeExt=excludeExt) + +caseName='FAST.Farm' # for ease of comparison ### Run openfast on the test case if not noExec: caseInputFile = os.path.join(testBuildDirectory, caseName + ".fstf") - returnCode = openfastDrivers.runOpenfastCase(caseInputFile, executable) + returnCode = openfastDrivers.runOpenfastCase(caseInputFile, executable, verbose=verbose) if returnCode != 0: - rtl.exitWithError("") + sys.exit(returnCode*10) ### Build the filesystem navigation variables for running the regression test localOutFile = os.path.join(testBuildDirectory, caseName + ".out") @@ -151,29 +127,31 @@ def ignoreBaselineItems(directory, contents): rtl.validateFileOrExit(localOutFile) rtl.validateFileOrExit(baselineOutFile) -testData, testInfo, testPack = pass_fail.readFASTOut(localOutFile) +testData, testInfo, _ = 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) +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T -# failing case -if not pass_fail.passRegressionTest(normalizedNorm, tolerance): - if plotError: - from errorPlotting import finalizePlotDirectory, plotOpenfastError - for channel in testInfo["attribute_names"]: - try: - plotOpenfastError(localOutFile, baselineOutFile, channel) - except: - error = sys.exc_info()[1] - print("Error generating plots: {}".format(error)) - finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) - - sys.exit(1) +norms = pass_fail.calculateNorms(testData, baselineData) + +# export all case summaries +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) # passing case -sys.exit(0) +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeHydrodynPyRegressionCase.py b/reg_tests/executeHydrodynPyRegressionCase.py index 6f8107cd4..77044846a 100644 --- a/reg_tests/executeHydrodynPyRegressionCase.py +++ b/reg_tests/executeHydrodynPyRegressionCase.py @@ -24,9 +24,10 @@ import os import sys -basepath = os.path.dirname(__file__) +basepath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.sep.join([basepath, "lib"])) import argparse +import numpy as np import shutil import glob import subprocess @@ -46,9 +47,8 @@ parser.add_argument("executable", metavar="HydroDyn-Python", type=str, nargs=1, help="The path to the Python 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") 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") @@ -59,7 +59,8 @@ executable = args.executable[0] sourceDirectory = args.sourceDirectory[0] buildDirectory = args.buildDirectory[0] -tolerance = args.tolerance[0] +rtol = args.rtol[0] +atol = args.atol[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 @@ -106,39 +107,39 @@ caseInputFile = os.path.join(testBuildDirectory, "hydrodyn_driver.py") returnCode = openfastDrivers.runHydrodynDriverCase(caseInputFile, executable) if returnCode != 0: - rtl.exitWithError("") + sys.exit(returnCode*10) ### Build the filesystem navigation variables for running the regression test -localOutFile = os.path.join(testBuildDirectory, "hd_py.out") -baselineOutFile = os.path.join(targetOutputDirectory, "hd_py.out") +localOutFile = os.path.join(testBuildDirectory, "py_hd.out") +baselineOutFile = os.path.join(targetOutputDirectory, "py_hd.out") rtl.validateFileOrExit(localOutFile) rtl.validateFileOrExit(baselineOutFile) -testData, testInfo, testPack = pass_fail.readFASTOut(localOutFile) +testData, testInfo, _ = pass_fail.readFASTOut(localOutFile) baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile) -performance = pass_fail.calculateNorms(testData, baselineData) -normalizedNorm = performance[:, 1] + +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T + +norms = pass_fail.calculateNorms(testData, baselineData) # export all case summaries -results = list(zip(testInfo["attribute_names"], [*performance])) -results_max = performance.max(axis=0) -exportCaseSummary(testBuildDirectory, caseName, results, results_max, tolerance) +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) -# 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) +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeHydrodynRegressionCase.py b/reg_tests/executeHydrodynRegressionCase.py index 2c442eb6b..445c21294 100644 --- a/reg_tests/executeHydrodynRegressionCase.py +++ b/reg_tests/executeHydrodynRegressionCase.py @@ -27,6 +27,7 @@ basepath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.sep.join([basepath, "lib"])) import argparse +import numpy as np import shutil import glob import subprocess @@ -36,6 +37,7 @@ from errorPlotting import exportCaseSummary ##### Main program +excludeExt=['.out','.outb','.ech','.yaml','.sum','.log','.rst'] ### Store the python executable for future python calls pythonCommand = sys.executable @@ -46,12 +48,11 @@ parser.add_argument("executable", metavar="HydroDyn-Driver", type=str, nargs=1, help="The path to the HydroDyn 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") +parser.add_argument("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") +parser.add_argument("-p", "-plot", dest="plot", default=False, const=True, 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, const=True, metavar="No-Execution", type=bool, nargs="?", help="bool to prevent execution of the test cases") +parser.add_argument("-v", "-verbose", dest="verbose", default=False, const=True, metavar="Verbose-Flag", type=bool, nargs="?", help="bool to include verbose system output") args = parser.parse_args() @@ -59,7 +60,8 @@ executable = args.executable[0] sourceDirectory = args.sourceDirectory[0] buildDirectory = args.buildDirectory[0] -tolerance = args.tolerance[0] +rtol = args.rtol[0] +atol = args.atol[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 @@ -90,20 +92,20 @@ # 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,"hd_*inp")): - 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)) + rtl.copyTree(inputsDirectory, testBuildDirectory, excludeExt=excludeExt) + +dirToCopy = os.path.join("glue-codes","openfast","5MW_Baseline","HydroData") +buildDirectoryGlue = os.path.join(buildDirectory,os.pardir,os.pardir,dirToCopy) +if not os.path.isdir(buildDirectoryGlue): + src = os.path.join(rtest,dirToCopy) + rtl.copyTree(src, buildDirectoryGlue, excludeExt=excludeExt) ### Run HydroDyn on the test case if not noExec: caseInputFile = os.path.join(testBuildDirectory, "hd_driver.inp") returnCode = openfastDrivers.runHydrodynDriverCase(caseInputFile, executable) if returnCode != 0: - rtl.exitWithError("") + sys.exit(returnCode*10) ### Build the filesystem navigation variables for running the regression test localOutFile = os.path.join(testBuildDirectory, "driver.HD.out") @@ -111,31 +113,31 @@ rtl.validateFileOrExit(localOutFile) rtl.validateFileOrExit(baselineOutFile) -testData, testInfo, testPack = pass_fail.readFASTOut(localOutFile) +testData, testInfo, _ = pass_fail.readFASTOut(localOutFile) baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile) -performance = pass_fail.calculateNorms(testData, baselineData) -normalizedNorm = performance[:, 1] + +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T + +norms = pass_fail.calculateNorms(testData, baselineData) # export all case summaries -results = list(zip(testInfo["attribute_names"], [*performance])) -results_max = performance.max(axis=0) -exportCaseSummary(testBuildDirectory, caseName, results, results_max, tolerance) +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) -# 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) +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeInflowwindPyRegressionCase.py b/reg_tests/executeInflowwindPyRegressionCase.py index 7d88591ba..3981c4f82 100644 --- a/reg_tests/executeInflowwindPyRegressionCase.py +++ b/reg_tests/executeInflowwindPyRegressionCase.py @@ -27,6 +27,7 @@ basepath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.sep.join([basepath, "lib"])) import argparse +import numpy as np import shutil import glob import subprocess @@ -46,9 +47,8 @@ parser.add_argument("executable", metavar="InflowWind-Python", type=str, nargs=1, help="The path to the InflowWind 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases") parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases") parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', help="bool to include verbose system output") @@ -59,7 +59,8 @@ executable = args.executable[0] sourceDirectory = args.sourceDirectory[0] buildDirectory = args.buildDirectory[0] -tolerance = args.tolerance[0] +rtol = args.rtol[0] +atol = args.atol[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 @@ -103,7 +104,7 @@ caseInputFile = os.path.join(testBuildDirectory, "inflowWind_testDriver.py") returnCode = openfastDrivers.runInflowwindDriverCase(caseInputFile, executable) if returnCode != 0: - rtl.exitWithError("") + sys.exit(returnCode*10) ### Build the filesystem navigation variables for running the regression test localOutFile = os.path.join(testBuildDirectory, "Points.Velocity.dat") @@ -111,31 +112,31 @@ rtl.validateFileOrExit(localOutFile) rtl.validateFileOrExit(baselineOutFile) -testData, testInfo, testPack = pass_fail.readFASTOut(localOutFile) +testData, testInfo, _ = pass_fail.readFASTOut(localOutFile) baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile) -performance = pass_fail.calculateNorms(testData, baselineData) -normalizedNorm = performance[:, 1] + +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T + +norms = pass_fail.calculateNorms(testData, baselineData) # export all case summaries -results = list(zip(testInfo["attribute_names"], [*performance])) -results_max = performance.max(axis=0) -exportCaseSummary(testBuildDirectory, caseName, results, results_max, tolerance) +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) -# 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) +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeInflowwindRegressionCase.py b/reg_tests/executeInflowwindRegressionCase.py index 42c99d628..3979d641c 100644 --- a/reg_tests/executeInflowwindRegressionCase.py +++ b/reg_tests/executeInflowwindRegressionCase.py @@ -27,6 +27,7 @@ basepath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.sep.join([basepath, "lib"])) import argparse +import numpy as np import shutil import glob import subprocess @@ -46,9 +47,8 @@ parser.add_argument("executable", metavar="InflowWind-Driver", type=str, nargs=1, help="The path to the InflowWind 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases") parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases") parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', help="bool to include verbose system output") @@ -59,7 +59,8 @@ executable = args.executable[0] sourceDirectory = args.sourceDirectory[0] buildDirectory = args.buildDirectory[0] -tolerance = args.tolerance[0] +rtol = args.rtol[0] +atol = args.atol[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 @@ -91,7 +92,11 @@ # and initialize it with input files for all test cases if not os.path.isdir(testBuildDirectory): os.makedirs(testBuildDirectory) - for file in glob.glob(os.path.join(inputsDirectory,"*inp")): + for file in (glob.glob(os.path.join(inputsDirectory,"*.inp")) + + glob.glob(os.path.join(inputsDirectory,"*.bts"))+ + glob.glob(os.path.join(inputsDirectory,"*.wnd"))+ + glob.glob(os.path.join(inputsDirectory,"*.hh"))+ + glob.glob(os.path.join(inputsDirectory,"*.sum"))): filename = file.split(os.path.sep)[-1] shutil.copy(os.path.join(inputsDirectory,filename), os.path.join(testBuildDirectory,filename)) @@ -100,7 +105,7 @@ caseInputFile = os.path.join(testBuildDirectory, "ifw_driver.inp") returnCode = openfastDrivers.runInflowwindDriverCase(caseInputFile, executable) if returnCode != 0: - rtl.exitWithError("") + sys.exit(returnCode*10) ### Build the filesystem navigation variables for running the regression test localOutFile = os.path.join(testBuildDirectory, "Points.Velocity.dat") @@ -108,31 +113,31 @@ rtl.validateFileOrExit(localOutFile) rtl.validateFileOrExit(baselineOutFile) -testData, testInfo, testPack = pass_fail.readFASTOut(localOutFile) +testData, testInfo, _ = pass_fail.readFASTOut(localOutFile) baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile) -performance = pass_fail.calculateNorms(testData, baselineData) -normalizedNorm = performance[:, 1] + +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T + +norms = pass_fail.calculateNorms(testData, baselineData) # export all case summaries -results = list(zip(testInfo["attribute_names"], [*performance])) -results_max = performance.max(axis=0) -exportCaseSummary(testBuildDirectory, caseName, results, results_max, tolerance) +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) -# 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) +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeMoordynPyRegressionCase.py b/reg_tests/executeMoordynPyRegressionCase.py new file mode 100644 index 000000000..52a1b8980 --- /dev/null +++ b/reg_tests/executeMoordynPyRegressionCase.py @@ -0,0 +1,136 @@ +# +# 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 MoorDyn 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: `executeMoordynPyRegressionCase.py -h` +""" + +import os +import sys +basepath = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, os.path.sep.join([basepath, "lib"])) +import argparse +import numpy as np +import shutil +import glob +import subprocess +import rtestlib as rtl +import openfastDrivers +import pass_fail +from errorPlotting import exportCaseSummary + +##### Main program +excludeExt=['.out','.outb','.ech','.yaml','.sum','.log'] + +### Store the python executable for future python calls +pythonCommand = sys.executable + +### Verify input arguments +parser = argparse.ArgumentParser(description="Executes MoorDyn 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="MoorDyn-Python", type=str, nargs=1, help="The path to the MoorDyn 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") +parser.add_argument("-p", "-plot", dest="plot", default=False, const=True, 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, const=True, metavar="No-Execution", type=bool, nargs="?", help="bool to prevent execution of the test cases") +parser.add_argument("-v", "-verbose", dest="verbose", default=False, const=True, 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] +rtol = args.rtol[0] +atol = args.atol[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", "moordyn") +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 and initialize it with input files +rtl.copyTree(inputsDirectory, testBuildDirectory, renameDict={'MD.out':'MD_ref.out','MDroot.MD.out':'MDroot.MD_ref.out'}) + # , excludeExt=['.out','.outb']) + +### Run MoorDyn on the test case +if not noExec: + caseInputFile = os.path.join(testBuildDirectory, "py_md_driver.py") + returnCode = openfastDrivers.runMoordynDriverCase(caseInputFile, executable) + if returnCode != 0: + sys.exit(returnCode*10) + +### Build the filesystem navigation variables for running the regression test +localOutFile = os.path.join(testBuildDirectory, "MDroot.MD.out") +baselineOutFile = os.path.join(targetOutputDirectory, "MDroot.MD.out") +rtl.validateFileOrExit(localOutFile) +rtl.validateFileOrExit(baselineOutFile) + +testData, testInfo, _ = pass_fail.readFASTOut(localOutFile) +baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile) + +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T + +norms = pass_fail.calculateNorms(testData, baselineData) + +# export all case summaries +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) + +# passing case +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeMoordynRegressionCase.py b/reg_tests/executeMoordynRegressionCase.py new file mode 100644 index 000000000..a2d209b76 --- /dev/null +++ b/reg_tests/executeMoordynRegressionCase.py @@ -0,0 +1,143 @@ +# +# 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 MoorDyn 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: `executeMoordynRegressionCase.py -h` +""" + +import os +import sys +basepath = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, os.path.sep.join([basepath, "lib"])) +import argparse +import numpy as np +import shutil +import glob +import subprocess +import rtestlib as rtl +import openfastDrivers +import pass_fail +from errorPlotting import exportCaseSummary + +##### Main program +excludeExt=['.out','.outb','.ech','.yaml','.sum','.log'] + +### Store the python executable for future python calls +pythonCommand = sys.executable + +### Verify input arguments +parser = argparse.ArgumentParser(description="Executes MoorDyn 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="MoorDyn-Driver", type=str, nargs=1, help="The path to the MoorDyn 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") +parser.add_argument("-p", "-plot", dest="plot", default=False, const=True, 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, const=True, metavar="No-Execution", type=bool, nargs="?", help="bool to prevent execution of the test cases") +parser.add_argument("-v", "-verbose", dest="verbose", default=False, const=True, 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] +rtol = args.rtol[0] +atol = args.atol[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", "moordyn") +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,"md_*inp")): + 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 MoorDyn on the test case +if not noExec: + caseInputFile = os.path.join(testBuildDirectory, "md_driver.inp") + returnCode = openfastDrivers.runMoordynDriverCase(caseInputFile, executable) + if returnCode != 0: + sys.exit(returnCode*10) + +### Build the filesystem navigation variables for running the regression test +localOutFile = os.path.join(testBuildDirectory, "driver.MD.out") +baselineOutFile = os.path.join(targetOutputDirectory, "driver.MD.out") +rtl.validateFileOrExit(localOutFile) +rtl.validateFileOrExit(baselineOutFile) + +testData, testInfo, _ = pass_fail.readFASTOut(localOutFile) +baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile) + +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T + +norms = pass_fail.calculateNorms(testData, baselineData) + +# export all case summaries +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) + +# passing case +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeOpenfastAeroAcousticRegressionCase.py b/reg_tests/executeOpenfastAeroAcousticRegressionCase.py index 381879eb2..002f21a05 100644 --- a/reg_tests/executeOpenfastAeroAcousticRegressionCase.py +++ b/reg_tests/executeOpenfastAeroAcousticRegressionCase.py @@ -28,6 +28,7 @@ basepath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.sep.join([basepath, "lib"])) import argparse +import numpy as np import shutil import subprocess import rtestlib as rtl @@ -36,13 +37,7 @@ from errorPlotting import exportCaseSummary ##### Helper functions -def ignoreBaselineItems(directory, contents): - itemFilter = ['linux-intel', 'linux-gnu', 'macos-gnu', 'windows-intel'] - caught = [] - for c in contents: - if c in itemFilter: - caught.append(c) - return tuple(caught) +excludeExt=['.out','.outb','.ech','.yaml','.sum','.log'] ##### Main program @@ -55,9 +50,8 @@ def ignoreBaselineItems(directory, contents): parser.add_argument("executable", metavar="OpenFAST", type=str, nargs=1, help="The path to the OpenFAST 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases") parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases") parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', help="bool to include verbose system output") @@ -68,9 +62,8 @@ def ignoreBaselineItems(directory, contents): executable = args.executable[0] sourceDirectory = args.sourceDirectory[0] buildDirectory = args.buildDirectory[0] -tolerance = args.tolerance[0] -systemName = args.systemName[0] -compilerId = args.compilerId[0] +rtol = args.rtol[0] +atol = args.atol[0] plotError = args.plot noExec = args.noExec verbose = args.verbose @@ -81,37 +74,17 @@ def ignoreBaselineItems(directory, contents): if not os.path.isdir(buildDirectory): os.makedirs(buildDirectory) -### Map the system and compiler configurations to a solution set -# Internal names -> Human readable names -systemName_map = { - "darwin": "macos", - "linux": "linux", - "windows": "windows" -} -compilerId_map = { - "gnu": "gnu", - "intel": "intel" -} -# Build the target output directory name or choose the default -supportedBaselines = ["macos-gnu", "linux-intel", "linux-gnu", "windows-intel"] -targetSystem = systemName_map.get(systemName.lower(), "") -targetCompiler = compilerId_map.get(compilerId.lower(), "") -outputType = os.path.join(targetSystem+"-"+targetCompiler) -if outputType not in supportedBaselines: - outputType = supportedBaselines[0] -print("-- Using gold standard files with machine-compiler type {}".format(outputType)) - ### Build the filesystem navigation variables for running openfast on 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, "glue-codes", "openfast") inputsDirectory = os.path.join(moduleDirectory, caseName) -targetOutputDirectory = os.path.join(inputsDirectory, outputType) +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)) @@ -123,14 +96,14 @@ def ignoreBaselineItems(directory, contents): # 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): - shutil.copytree(inputsDirectory, testBuildDirectory, ignore=ignoreBaselineItems) - + rtl.copyTree(inputsDirectory, testBuildDirectory, excludeExt=excludeExt) + ### Run openfast on the test case if not noExec: caseInputFile = os.path.join(testBuildDirectory, caseName + ".fst") returnCode = openfastDrivers.runOpenfastCase(caseInputFile, executable) if returnCode != 0: - rtl.exitWithError("") + sys.exit(returnCode*10) ### Build the filesystem navigation variables for running the regression test # testing on file 2. Gives each observer and sweep of frequency ranges @@ -139,31 +112,31 @@ def ignoreBaselineItems(directory, contents): rtl.validateFileOrExit(localOutFile) rtl.validateFileOrExit(baselineOutFile) -testData, testInfo, testPack = pass_fail.readFASTOut(localOutFile) +testData, testInfo, _ = pass_fail.readFASTOut(localOutFile) baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile) -performance = pass_fail.calculateNorms(testData, baselineData) -normalizedNorm = performance[:, 1] + +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T + +norms = pass_fail.calculateNorms(testData, baselineData) # export all case summaries -results = list(zip(testInfo["attribute_names"], [*performance])) -results_max = performance.max(axis=0) -exportCaseSummary(testBuildDirectory, caseName, results, results_max, tolerance) +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) -# 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) +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeOpenfastCppRegressionCase.py b/reg_tests/executeOpenfastCppRegressionCase.py index 03f9cccc2..82a7c248d 100644 --- a/reg_tests/executeOpenfastCppRegressionCase.py +++ b/reg_tests/executeOpenfastCppRegressionCase.py @@ -19,6 +19,7 @@ basepath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.sep.join([basepath, "lib"])) import argparse +import numpy as np import shutil import subprocess import rtestlib as rtl @@ -27,13 +28,7 @@ from errorPlotting import exportCaseSummary ##### Helper functions -def ignoreBaselineItems(directory, contents): - itemFilter = ['linux-intel', 'linux-gnu', 'macos-gnu', 'windows-intel'] - caught = [] - for c in contents: - if c in itemFilter: - caught.append(c) - return tuple(caught) +excludeExt=['.out','.outb','.ech','.sum','.log'] ##### Main program @@ -46,9 +41,8 @@ def ignoreBaselineItems(directory, contents): parser.add_argument("executable", metavar="OpenFAST", type=str, nargs=1, help="The path to the OpenFAST 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases") parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases") parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', help="bool to include verbose system output") @@ -59,9 +53,8 @@ def ignoreBaselineItems(directory, contents): executable = os.path.abspath(args.executable[0]) sourceDirectory = args.sourceDirectory[0] buildDirectory = args.buildDirectory[0] -tolerance = args.tolerance[0] -systemName = args.systemName[0] -compilerId = args.compilerId[0] +rtol = args.rtol[0] +atol = args.atol[0] plotError = args.plot noExec = args.noExec verbose = args.verbose @@ -72,32 +65,13 @@ def ignoreBaselineItems(directory, contents): if not os.path.isdir(buildDirectory): os.makedirs(buildDirectory) -### Map the system and compiler configurations to a solution set -# Internal names -> Human readable names -systemName_map = { - "darwin": "macos", - "linux": "linux", - "windows": "windows" -} -compilerId_map = { - "gnu": "gnu", - "intel": "intel" -} -# Build the target output directory name or choose the default -supportedBaselines = ["macos-gnu", "linux-intel", "linux-gnu", "windows-intel"] -targetSystem = systemName_map.get(systemName.lower(), "") -targetCompiler = compilerId_map.get(compilerId.lower(), "") -outputType = os.path.join(targetSystem+"-"+targetCompiler) -if outputType not in supportedBaselines: - outputType = supportedBaselines[0] -print("-- Using gold standard files with machine-compiler type {}".format(outputType)) ### Build the filesystem navigation variables for running openfast on the test case rtest = os.path.join(sourceDirectory, "reg_tests", "r-test") moduleDirectory = os.path.join(rtest, "glue-codes", "openfast-cpp") openfast_gluecode_directory = os.path.join(rtest, "glue-codes", "openfast") inputsDirectory = os.path.join(moduleDirectory, caseName) -targetOutputDirectory = os.path.join(openfast_gluecode_directory, caseName.replace('_cpp', ''), outputType) +targetOutputDirectory = os.path.join(openfast_gluecode_directory, caseName.replace('_cpp', '')) testBuildDirectory = os.path.join(buildDirectory, caseName) # verify all the required directories exist @@ -112,7 +86,7 @@ def ignoreBaselineItems(directory, contents): dst = os.path.join(buildDirectory, "5MW_Baseline") src = os.path.join(openfast_gluecode_directory, "5MW_Baseline") if not os.path.isdir(dst): - shutil.copytree(src, dst) + rtl.copyTree(src, dst, excludeExt=excludeExt) else: names = os.listdir(src) for name in names: @@ -122,12 +96,12 @@ def ignoreBaselineItems(directory, contents): dstname = os.path.join(dst, name) if os.path.isdir(srcname): if not os.path.isdir(dstname): - shutil.copytree(srcname, dstname) + rtl.copyTree(srcname, dstname, excludeExt=excludeExt) else: shutil.copy2(srcname, dstname) if not os.path.isdir(testBuildDirectory): - shutil.copytree(inputsDirectory, testBuildDirectory, ignore=ignoreBaselineItems) + rtl.copyTree(inputsDirectory, testBuildDirectory, excludeExt=excludeExt) ### Run openfast on the test case if not noExec: @@ -136,38 +110,41 @@ def ignoreBaselineItems(directory, contents): caseInputFile = os.path.abspath("cDriver.yaml") returnCode = openfastDrivers.runOpenfastCase(caseInputFile, executable) if returnCode != 0: - rtl.exitWithError("") + sys.exit(returnCode*10) os.chdir(cwd) ### Build the filesystem navigation variables for running the regression test localOutFile = os.path.join(testBuildDirectory, caseName + ".outb") baselineOutFile = os.path.join(targetOutputDirectory, caseName.replace('_cpp', '') + ".outb") + rtl.validateFileOrExit(localOutFile) rtl.validateFileOrExit(baselineOutFile) -testData, testInfo, testPack = pass_fail.readFASTOut(localOutFile) +testData, testInfo, _ = 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) +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T -# failing case -if not pass_fail.passRegressionTest(normalizedNorm, tolerance): - if plotError: - from errorPlotting import finalizePlotDirectory, plotOpenfastError - for channel in testInfo["attribute_names"]: - try: - plotOpenfastError(localOutFile, baselineOutFile, channel) - except: - error = sys.exc_info()[1] - print("Error generating plots: {}".format(error)) - finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) - - sys.exit(1) +norms = pass_fail.calculateNorms(testData, baselineData) + +# export all case summaries +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) # passing case -sys.exit(0) +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeOpenfastLinearRegressionCase.py b/reg_tests/executeOpenfastLinearRegressionCase.py index 8e8a9b701..4eed9f259 100644 --- a/reg_tests/executeOpenfastLinearRegressionCase.py +++ b/reg_tests/executeOpenfastLinearRegressionCase.py @@ -27,6 +27,7 @@ basepath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.sep.join([basepath, "lib"])) import argparse +import numpy as np import shutil import subprocess import rtestlib as rtl @@ -35,13 +36,7 @@ from errorPlotting import exportCaseSummary ##### Helper functions -def ignoreBaselineItems(directory, contents): - itemFilter = ['linux-intel', 'linux-gnu', 'macos-gnu', 'windows-intel'] - caught = [] - for c in contents: - if c in itemFilter: - caught.append(c) - return tuple(caught) +excludeExt=['.out','.outb','.ech','.yaml','.sum','.log'] def file_line_count(filename): file_handle = open(filename, 'r') @@ -64,12 +59,11 @@ def isclose(a, b, rel_tol=1e-09, abs_tol=0.0): parser.add_argument("executable", metavar="OpenFAST", type=str, nargs=1, help="The path to the OpenFAST 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 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") +parser.add_argument("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") +parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases") +parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases") +parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', help="bool to include verbose system output") args = parser.parse_args() @@ -77,12 +71,17 @@ def isclose(a, b, rel_tol=1e-09, abs_tol=0.0): executable = args.executable[0] sourceDirectory = args.sourceDirectory[0] buildDirectory = args.buildDirectory[0] -tolerance = args.tolerance[0] -systemName = args.systemName[0] -compilerId = args.compilerId[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 +rtol = args.rtol[0] +atol = args.atol[0] +plotError = args.plot +noExec = args.noExec +verbose = args.verbose + +# Tolerance have not been tuned for linearization case outputs. +# This is using 1e-5 since that seemed like a decent value prior to +# switching to relative and absolute tolerance. +rtol = 1e-5 +atol = 1e-5 # validate inputs rtl.validateExeOrExit(executable) @@ -90,33 +89,13 @@ def isclose(a, b, rel_tol=1e-09, abs_tol=0.0): if not os.path.isdir(buildDirectory): os.makedirs(buildDirectory) -### Map the system and compiler configurations to a solution set -# Internal names -> Human readable names -systemName_map = { - "darwin": "macos", - "linux": "linux", - "windows": "windows" -} -compilerId_map = { - "gnu": "gnu", - "intel": "intel" -} -# Build the target output directory name or choose the default -supportedBaselines = ["macos-gnu", "linux-intel", "linux-gnu", "windows-intel"] -targetSystem = systemName_map.get(systemName.lower(), "") -targetCompiler = compilerId_map.get(compilerId.lower(), "") -outputType = os.path.join(targetSystem+"-"+targetCompiler) -if outputType not in supportedBaselines: - outputType = supportedBaselines[0] -print("-- Using gold standard files with machine-compiler type {}".format(outputType)) - ### Build the filesystem navigation variables for running openfast on 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, "glue-codes", "openfast") inputsDirectory = os.path.join(moduleDirectory, caseName) -targetOutputDirectory = os.path.join(inputsDirectory, outputType) +targetOutputDirectory = os.path.join(inputsDirectory) testBuildDirectory = os.path.join(buildDirectory, caseName) # verify all the required directories exist @@ -132,13 +111,13 @@ def isclose(a, b, rel_tol=1e-09, abs_tol=0.0): for data in ["Ideal_Beam", "WP_Baseline"]: dataDir = os.path.join(buildDirectory, data) if not os.path.isdir(dataDir): - shutil.copytree(os.path.join(moduleDirectory, data), dataDir) + rtl.copyTree(os.path.join(moduleDirectory, data), dataDir, excludeExt=excludeExt) # Special copy for the 5MW_Baseline folder because the Windows python-only workflow may have already created data in the subfolder ServoData dst = os.path.join(buildDirectory, "5MW_Baseline") src = os.path.join(moduleDirectory, "5MW_Baseline") if not os.path.isdir(dst): - shutil.copytree(src, dst) + rtl.copyTree(src, dst, excludeExt=excludeExt) else: names = os.listdir(src) for name in names: @@ -148,25 +127,22 @@ def isclose(a, b, rel_tol=1e-09, abs_tol=0.0): dstname = os.path.join(dst, name) if os.path.isdir(srcname): if not os.path.isdir(dstname): - shutil.copytree(srcname, dstname) + rtl.copyTree(srcname, dstname, excludeExt=excludeExt) else: shutil.copy2(srcname, dstname) if not os.path.isdir(testBuildDirectory): - shutil.copytree(inputsDirectory, testBuildDirectory, ignore=ignoreBaselineItems) + rtl.copyTree(inputsDirectory, testBuildDirectory, excludeExt=excludeExt) ### Run openfast on the test case if not noExec: caseInputFile = os.path.join(testBuildDirectory, caseName + ".fst") returnCode = openfastDrivers.runOpenfastCase(caseInputFile, executable) if returnCode != 0: - rtl.exitWithError("") + sys.exit(returnCode*10) -### 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') +### Get a all the .lin files in the baseline directory +baselineOutFiles = [f for f in os.listdir(targetOutputDirectory) if '.lin' in f] # these should all exist in the local outputs directory localFiles = os.listdir(testBuildDirectory) @@ -239,8 +215,10 @@ def isclose(a, b, rel_tol=1e-09, abs_tol=0.0): for j, l_element in enumerate(l_elements): l_float = float(l_element) b_float = float(b_elements[j]) - if not isclose(l_float, b_float, tolerance, tolerance): - print(f"Failed in Jacobian matrix comparison: {l_float} and {b_float}") + if not isclose(l_float, b_float, rtol, atol): + print(f"Failed in Jacobian matrix comparison:") + print(f"{l_float} in {local_file}") + print(f"{b_float} in {baseline_file}") sys.exit(1) # skip 2 empty/header lines @@ -261,7 +239,7 @@ def isclose(a, b, rel_tol=1e-09, abs_tol=0.0): for j, l_element in enumerate(l_elements): l_float = float(l_element) b_float = float(b_elements[j]) - if not isclose(l_float, b_float, tolerance, tolerance): + if not isclose(l_float, b_float, rtol, atol): print(f"Failed in state matrix comparison: {l_float} and {b_float}") sys.exit(1) diff --git a/reg_tests/executeOpenfastRegressionCase.py b/reg_tests/executeOpenfastRegressionCase.py index 2bb1bb14c..a0cae63e6 100644 --- a/reg_tests/executeOpenfastRegressionCase.py +++ b/reg_tests/executeOpenfastRegressionCase.py @@ -27,6 +27,7 @@ basepath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.sep.join([basepath, "lib"])) import argparse +import numpy as np import shutil import subprocess import rtestlib as rtl @@ -35,13 +36,7 @@ from errorPlotting import exportCaseSummary ##### Helper functions -def ignoreBaselineItems(directory, contents): - itemFilter = ['linux-intel', 'linux-gnu', 'macos-gnu', 'windows-intel'] - caught = [] - for c in contents: - if c in itemFilter: - caught.append(c) - return tuple(caught) +excludeExt=['.out','.outb','.ech','.yaml','.sum','.log'] ##### Main program @@ -54,9 +49,8 @@ def ignoreBaselineItems(directory, contents): parser.add_argument("executable", metavar="OpenFAST", type=str, nargs=1, help="The path to the OpenFAST 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases") parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases") parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', help="bool to include verbose system output") @@ -67,9 +61,8 @@ def ignoreBaselineItems(directory, contents): executable = args.executable[0] sourceDirectory = args.sourceDirectory[0] buildDirectory = args.buildDirectory[0] -tolerance = args.tolerance[0] -systemName = args.systemName[0] -compilerId = args.compilerId[0] +rtol = args.rtol[0] +atol = args.atol[0] plotError = args.plot noExec = args.noExec verbose = args.verbose @@ -80,25 +73,6 @@ def ignoreBaselineItems(directory, contents): if not os.path.isdir(buildDirectory): os.makedirs(buildDirectory) -### Map the system and compiler configurations to a solution set -# Internal names -> Human readable names -systemName_map = { - "darwin": "macos", - "linux": "linux", - "windows": "windows" -} -compilerId_map = { - "gnu": "gnu", - "intel": "intel" -} -# Build the target output directory name or choose the default -supportedBaselines = ["macos-gnu", "linux-intel", "linux-gnu", "windows-intel"] -targetSystem = systemName_map.get(systemName.lower(), "") -targetCompiler = compilerId_map.get(compilerId.lower(), "") -outputType = os.path.join(targetSystem+"-"+targetCompiler) -if outputType not in supportedBaselines: - outputType = supportedBaselines[0] -print("-- Using gold standard files with machine-compiler type {}".format(outputType)) ### Build the filesystem navigation variables for running openfast on the test case regtests = os.path.join(sourceDirectory, "reg_tests") @@ -106,7 +80,7 @@ def ignoreBaselineItems(directory, contents): rtest = os.path.join(regtests, "r-test") moduleDirectory = os.path.join(rtest, "glue-codes", "openfast") inputsDirectory = os.path.join(moduleDirectory, caseName) -targetOutputDirectory = os.path.join(inputsDirectory, outputType) +targetOutputDirectory = os.path.join(inputsDirectory) testBuildDirectory = os.path.join(buildDirectory, caseName) # verify all the required directories exist @@ -122,13 +96,13 @@ def ignoreBaselineItems(directory, contents): for data in ["AOC", "AWT27", "SWRT", "UAE_VI", "WP_Baseline"]: dataDir = os.path.join(buildDirectory, data) if not os.path.isdir(dataDir): - shutil.copytree(os.path.join(moduleDirectory, data), dataDir) + rtl.copyTree(os.path.join(moduleDirectory, data), dataDir, excludeExt=excludeExt) # Special copy for the 5MW_Baseline folder because the Windows python-only workflow may have already created data in the subfolder ServoData dst = os.path.join(buildDirectory, "5MW_Baseline") src = os.path.join(moduleDirectory, "5MW_Baseline") if not os.path.isdir(dst): - shutil.copytree(src, dst) + rtl.copyTree(src, dst, excludeExt=excludeExt) else: names = os.listdir(src) for name in names: @@ -138,19 +112,19 @@ def ignoreBaselineItems(directory, contents): dstname = os.path.join(dst, name) if os.path.isdir(srcname): if not os.path.isdir(dstname): - shutil.copytree(srcname, dstname) + rtl.copyTree(srcname, dstname, excludeExt=excludeExt) else: shutil.copy2(srcname, dstname) if not os.path.isdir(testBuildDirectory): - shutil.copytree(inputsDirectory, testBuildDirectory, ignore=ignoreBaselineItems) + rtl.copyTree(inputsDirectory, testBuildDirectory, excludeExt=excludeExt) ### Run openfast on the test case if not noExec: caseInputFile = os.path.join(testBuildDirectory, caseName + ".fst") returnCode = openfastDrivers.runOpenfastCase(caseInputFile, executable) if returnCode != 0: - rtl.exitWithError("") + sys.exit(returnCode*10) ### Build the filesystem navigation variables for running the regression test localOutFile = os.path.join(testBuildDirectory, caseName + ".outb") @@ -158,29 +132,31 @@ def ignoreBaselineItems(directory, contents): rtl.validateFileOrExit(localOutFile) rtl.validateFileOrExit(baselineOutFile) -testData, testInfo, testPack = pass_fail.readFASTOut(localOutFile) +testData, testInfo, _ = 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) +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T -# failing case -if not pass_fail.passRegressionTest(normalizedNorm, tolerance): - if plotError: - from errorPlotting import finalizePlotDirectory, plotOpenfastError - for channel in testInfo["attribute_names"]: - try: - plotOpenfastError(localOutFile, baselineOutFile, channel) - except: - error = sys.exc_info()[1] - print("Error generating plots: {}".format(error)) - finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) - - sys.exit(1) +norms = pass_fail.calculateNorms(testData, baselineData) + +# export all case summaries +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) # passing case -sys.exit(0) +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executePythonRegressionCase.py b/reg_tests/executePythonRegressionCase.py index 58c259929..9106c588b 100644 --- a/reg_tests/executePythonRegressionCase.py +++ b/reg_tests/executePythonRegressionCase.py @@ -25,11 +25,12 @@ 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 "." +basepath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.sep.join([basepath, "lib"])) sys.path.insert(0, os.path.sep.join([basepath, "..", "glue-codes", "python"])) import platform import argparse +import numpy as np import shutil import subprocess import rtestlib as rtl @@ -39,13 +40,7 @@ import openfast_library ##### Helper functions -def ignoreBaselineItems(directory, contents): - itemFilter = ['linux-intel', 'linux-gnu', 'macos-gnu', 'windows-intel'] - caught = [] - for c in contents: - if c in itemFilter: - caught.append(c) - return tuple(caught) +excludeExt=['.out','.outb','.ech','.yaml','.sum','.log'] ##### Main program @@ -58,9 +53,8 @@ def ignoreBaselineItems(directory, contents): parser.add_argument("executable", metavar="NotUsed", type=str, nargs=1, help="Not used in this script, but kept for API compatibility.") 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases") parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases") parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', help="bool to include verbose system output") @@ -70,9 +64,8 @@ def ignoreBaselineItems(directory, contents): caseName = args.caseName[0].replace("_py", "") sourceDirectory = args.sourceDirectory[0] buildDirectory = args.buildDirectory[0] -tolerance = args.tolerance[0] -systemName = args.systemName[0] -compilerId = args.compilerId[0] +rtol = args.rtol[0] +atol = args.atol[0] plotError = args.plot noExec = args.noExec verbose = args.verbose @@ -82,25 +75,6 @@ def ignoreBaselineItems(directory, contents): if not os.path.isdir(buildDirectory): os.makedirs(buildDirectory) -### Map the system and compiler configurations to a solution set -# Internal names -> Human readable names -systemName_map = { - "darwin": "macos", - "linux": "linux", - "windows": "windows" -} -compilerId_map = { - "gnu": "gnu", - "intel": "intel" -} -# Build the target output directory name or choose the default -supportedBaselines = ["macos-gnu", "linux-intel", "linux-gnu", "windows-intel"] -targetSystem = systemName_map.get(systemName.lower(), "") -targetCompiler = compilerId_map.get(compilerId.lower(), "") -outputType = os.path.join(targetSystem+"-"+targetCompiler) -if outputType not in supportedBaselines: - outputType = supportedBaselines[0] -print("-- Using gold standard files with machine-compiler type {}".format(outputType)) ### Build the filesystem navigation variables for running openfast on the test case regtests = os.path.join(sourceDirectory, "reg_tests") @@ -108,7 +82,7 @@ def ignoreBaselineItems(directory, contents): rtest = os.path.join(regtests, "r-test") moduleDirectory = os.path.join(rtest, "glue-codes", "openfast") inputsDirectory = os.path.join(moduleDirectory, caseName) -targetOutputDirectory = os.path.join(inputsDirectory, outputType) +targetOutputDirectory = os.path.join(inputsDirectory) testBuildDirectory = os.path.join(buildDirectory, caseName) # verify all the required directories exist @@ -124,12 +98,13 @@ def ignoreBaselineItems(directory, contents): for data in ["AOC", "AWT27", "SWRT", "UAE_VI", "WP_Baseline"]: dataDir = os.path.join(buildDirectory, data) if not os.path.isdir(dataDir): - shutil.copytree(os.path.join(moduleDirectory, data), dataDir) + rtl.copyTree(os.path.join(moduleDirectory, data), dataDir, excludeExt=excludeExt) +# Special copy for the 5MW_Baseline folder because the Windows python-only workflow may have already created data in the subfolder ServoData dst = os.path.join(buildDirectory, "5MW_Baseline") src = os.path.join(moduleDirectory, "5MW_Baseline") if not os.path.isdir(dst): - shutil.copytree(src, dst) + rtl.copyTree(src, dst, excludeExt=excludeExt) else: names = os.listdir(src) for name in names: @@ -139,12 +114,12 @@ def ignoreBaselineItems(directory, contents): dstname = os.path.join(dst, name) if os.path.isdir(srcname): if not os.path.isdir(dstname): - shutil.copytree(srcname, dstname) + rtl.copyTree(srcname, dstname, excludeExt=excludeExt) else: shutil.copy2(srcname, dstname) if not os.path.isdir(testBuildDirectory): - shutil.copytree(inputsDirectory, testBuildDirectory, ignore=ignoreBaselineItems) + rtl.copyTree(inputsDirectory, testBuildDirectory, excludeExt=excludeExt) ### Run openfast on the test case if not noExec: @@ -165,6 +140,7 @@ def ignoreBaselineItems(directory, contents): output_channel_names = openfastlib.output_channel_names ### Build the filesystem navigation variables for running the regression test +localOutFile = os.path.join(testBuildDirectory, caseName + ".outb") baselineOutFile = os.path.join(targetOutputDirectory, caseName + ".outb") rtl.validateFileOrExit(baselineOutFile) @@ -173,27 +149,29 @@ def ignoreBaselineItems(directory, contents): } testData = openfastlib.output_values 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) +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T -# failing case -if not pass_fail.passRegressionTest(normalizedNorm, tolerance): - if plotError: - from errorPlotting import finalizePlotDirectory, plotOpenfastError - for channel in testInfo["attribute_names"]: - try: - plotOpenfastError(localOutFile, baselineOutFile, channel) - except: - error = sys.exc_info()[1] - print("Error generating plots: {}".format(error)) - finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) - - sys.exit(1) +norms = pass_fail.calculateNorms(testData, baselineData) + +# export all case summaries +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) # passing case -sys.exit(0) +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeSubdynRegressionCase.py b/reg_tests/executeSubdynRegressionCase.py index 94e04a710..9a71b167e 100644 --- a/reg_tests/executeSubdynRegressionCase.py +++ b/reg_tests/executeSubdynRegressionCase.py @@ -27,6 +27,7 @@ basepath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.sep.join([basepath, "lib"])) import argparse +import numpy as np import shutil import glob import subprocess @@ -46,9 +47,8 @@ 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") parser.add_argument("-p", "-plot", dest="plot", action='store_true', default=False, help="bool to include matplotlib plots in failed cases") parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', default=False, help="bool to prevent execution of the test cases") parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', default=False, help="bool to include verbose system output") @@ -59,7 +59,8 @@ executable = args.executable[0] sourceDirectory = args.sourceDirectory[0] buildDirectory = args.buildDirectory[0] -tolerance = args.tolerance[0] +rtol = args.rtol[0] +atol = args.atol[0] plotError = args.plot noExec = args.noExec verbose = args.verbose @@ -99,39 +100,40 @@ # run driver returnCode = openfastDrivers.runSubdynDriverCase(caseInputFile, executable, verbose=verbose) if returnCode != 0: - rtl.exitWithError("") + sys.exit(returnCode*10) ### 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) +testData, testInfo, _ = pass_fail.readFASTOut(localOutFile) baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile) -performance = pass_fail.calculateNorms(testData, baselineData) -normalizedNorm = performance[:, 1] + +passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) +passing_channels = passing_channels.T + +norms = pass_fail.calculateNorms(testData, baselineData) # export all case summaries -results = list(zip(testInfo["attribute_names"], [*performance])) -results_max = performance.max(axis=0) -exportCaseSummary(testBuildDirectory, caseName, results, results_max, tolerance) +channel_names = testInfo["attribute_names"] +exportCaseSummary(testBuildDirectory, caseName, channel_names, passing_channels, norms) -# 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) +if np.all(passing_channels): + sys.exit(0) + +# failing case +if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + print("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], caseName) + +sys.exit(1) diff --git a/reg_tests/executeUnsteadyAeroRegressionCase.py b/reg_tests/executeUnsteadyAeroRegressionCase.py new file mode 100644 index 000000000..b8ca22792 --- /dev/null +++ b/reg_tests/executeUnsteadyAeroRegressionCase.py @@ -0,0 +1,164 @@ +# +# 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 Unsteady Aero Driver 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: `executeUnsteadyAeroRegressionCase.py -h` +""" + +import os +import sys +basepath = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, os.path.sep.join([basepath, "lib"])) +import argparse +import numpy as np +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 OpenFAST 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="UA-Driver", type=str, nargs=1, help="The path to the UA 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("rtol", metavar="Relative-Tolerance", type=float, nargs=1, help="Relative tolerance to allow the solution to deviate; expressed as order of magnitudes less than baseline.") +parser.add_argument("atol", metavar="Absolute-Tolerance", type=float, nargs=1, help="Absolute tolerance to allow small values to pass; expressed as order of magnitudes less than baseline.") +parser.add_argument("-p", "-plot", dest="plot", action='store_true', help="bool to include plots in failed cases") +parser.add_argument("-n", "-no-exec", dest="noExec", action='store_true', help="bool to prevent execution of the test cases") +parser.add_argument("-v", "-verbose", dest="verbose", action='store_true', 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] +rtol = args.rtol[0] +atol = args.atol[0] +plotError = args.plot +noExec = args.noExec +verbose = args.verbose + +# 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", "unsteadyaero") +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 and initialize it with input files +renameDict={'UA'+str(i)+'.UA.out':'UA'+str(i)+'.UA_ref.out' for i in [2,3,4,5,6,7]} + +rtl.copyTree(inputsDirectory, testBuildDirectory, renameDict=renameDict + , excludeExt=['.sum']) + # , excludeExt=['.out','.outb','.sum']) + + +### Log errors locally +errors=[] +def Error(msg): + print(msg) + errors.append(msg) + + +### Run unsteady aero for all driver files in this folder +dvrFiles = glob.glob(os.path.join(testBuildDirectory,'*.dvr')) +if not noExec: + for caseInputFile in dvrFiles: + print('Running Case:', caseInputFile) + returnCode = openfastDrivers.runUnsteadyAeroDriverCase(caseInputFile, executable, verbose=verbose) + if returnCode != 0: + Error('Failed to run case: {}'.format(caseInputFile)) + +### Compare output with +for dvrf in dvrFiles: + simName = os.path.splitext(os.path.basename(dvrf))[0] + localOutFile = os.path.join(testBuildDirectory, simName + '.UA.out') + baselineOutFile = os.path.join(inputsDirectory, simName + '.UA.out') + + if not os.path.exists(localOutFile): + Error('File does not exist: {}'.format(localOutFile)) + continue + if not os.path.exists(baselineOutFile): + Error('File does not exist: {}'.format(baselineOutFile)) + continue + + testData, testInfo, _ = pass_fail.readFASTOut(localOutFile) + baselineData, baselineInfo, _ = pass_fail.readFASTOut(baselineOutFile) + + passing_channels = pass_fail.passing_channels(testData.T, baselineData.T, rtol, atol) + passing_channels = passing_channels.T + + norms = pass_fail.calculateNorms(testData, baselineData) + + # export all case summaries + channel_names = testInfo["attribute_names"] + exportCaseSummary(testBuildDirectory, simName, channel_names, passing_channels, norms) + + if np.all(passing_channels): + continue + + # failing case + Error('Comparison failed for case {}'.format(simName)) + if plotError: + from errorPlotting import finalizePlotDirectory, plotOpenfastError + for channel in testInfo["attribute_names"]: + try: + plotOpenfastError(localOutFile, baselineOutFile, channel, rtol, atol) + except: + error = sys.exc_info()[1] + Error("Error generating plots: {}".format(error)) + finalizePlotDirectory(localOutFile, testInfo["attribute_names"], simName) + + +if len(errors)==0: + sys.exit(0) +else: + print('---------- UNSTEADY AERODYNAMICS DRIVER TEST: {} --------'.format(caseName)) + print('The following errors occured:') + for e in errors: + print(e) + sys.exit(1) diff --git a/reg_tests/lib/errorPlotting.py b/reg_tests/lib/errorPlotting.py index 1778f3fe7..a677c8ed4 100644 --- a/reg_tests/lib/errorPlotting.py +++ b/reg_tests/lib/errorPlotting.py @@ -25,7 +25,6 @@ import os import sys import shutil - import numpy as np import rtestlib as rtl @@ -47,28 +46,43 @@ def _parseSolution(solution): except Exception as e: rtl.exitWithError("Error: {}".format(e)) -def _plotError(xseries, y1series, y2series, xlabel, title1, title2): +def _plotError(time, test, baseline, xlabel, title1, title2, RTOL_MAGNITUDE, ATOL_MAGNITUDE): from bokeh.embed import components from bokeh.layouts import gridplot from bokeh.plotting import figure - from bokeh.models.tools import HoverTool, BoxZoomTool + from bokeh.models.tools import HoverTool + # Plot the baseline and test channels p1 = figure(title=title1) p1.title.align = 'center' p1.grid.grid_line_alpha=0.3 p1.xaxis.axis_label = 'Time (s)' - p1.line(xseries, y2series, color='green', line_width=3, legend_label='Baseline') - p1.line(xseries, y1series, color='red', line_width=1, legend_label='Local') + p1.line(time, baseline, color='green', line_width=3, legend_label='Baseline') + p1.line(time, test, color='red', line_width=1, legend_label='Local') p1.add_tools(HoverTool(tooltips=[('Time','@x'), ('Value', '@y')],mode='vline')) + # Plot the error and threshold p2 = figure(title=title2, x_range=p1.x_range) p2.title.align = 'center' p2.grid.grid_line_alpha = 0 p2.xaxis.axis_label = 'Time (s)' - p2.line(xseries, abs(y2series - y1series), color='blue') + p2.line(time, abs(baseline - test), color='blue', legend_label="Error") + + # Calculate the threshold + NUMEPS = 1e-12 + ATOL_MIN = 1e-6 + baseline_offset = baseline - np.min(baseline) + b_order_of_magnitude = np.floor( np.log10( baseline_offset + NUMEPS ) ) + rtol = 10**(-1 * RTOL_MAGNITUDE) + atol = 10**(max(b_order_of_magnitude) - ATOL_MAGNITUDE) + atol = max(atol, ATOL_MIN) + passfail_line = atol + rtol * abs(baseline) + p2.line(time, passfail_line, color='red', legend_label="Threshold") + # p2.cross(xseries, passfail_line) + p2.add_tools(HoverTool(tooltips=[('Time','@x'), ('Error', '@y')], mode='vline')) - grid = gridplot([[p1, p2]], plot_width=650, plot_height=375, sizing_mode="scale_both") + grid = gridplot([[p1, p2]], width=650, height=375, sizing_mode="scale_both") script, div = components(grid) return script, div @@ -80,7 +94,7 @@ def _replace_id_div(html_string, plot): return html_string def _replace_id_script(html_string, plot): - id_start = html_string.find('var render_items') + id_start = html_string.find('const render_items') id_start += html_string[id_start:].find('roots') id_start += html_string[id_start:].find('":"') + 3 id_end = html_string[id_start:].find('"') + id_start @@ -92,7 +106,8 @@ def _save_plot(script, div, path, attribute): file_name = "_script".join((attribute, ".txt")) with open(os.path.join(path, file_name), 'w') as f: - script = _replace_id_script(script.replace('\n', '\n '), attribute) + script = script.replace('\n', '\n ') + script = _replace_id_script(script, attribute) f.write(script) file_name = "_div".join((attribute, ".txt")) @@ -104,7 +119,7 @@ def _save_plot(script, div, path, attribute): div = div.replace("' + '\n' + head += f' ' + '\n' head += ' ' + '\n' head += '

Zi$M0 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 Y*viAp*8^rpK_LddL&49lq^(TxU$eJ}8UO$Q delta 67464 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 diff --git a/docs/OtherSupporting/OpenFAST_Algorithms/OpenFAST_Algorithms.tex b/docs/OtherSupporting/OpenFAST_Algorithms/OpenFAST_Algorithms.tex index 8fbc455f9..8defae056 100644 --- a/docs/OtherSupporting/OpenFAST_Algorithms/OpenFAST_Algorithms.tex +++ b/docs/OtherSupporting/OpenFAST_Algorithms/OpenFAST_Algorithms.tex @@ -215,6 +215,7 @@ \section{Input-Output Relationships} & \mathit{y\_SD}, \mathit{u\_SD\_tmp}, \\ & \mathit{y\_MAP}, \mathit{u\_MAP\_tmp}, \\ & \mathit{y\_FEAM},\mathit{u\_FEAM\_tmp},\\ + & \mathit{y\_AD}, \mathit{u\_AD\_tmp}\footnote{Only if AD buoyancy at of hub enabled.}, \\ & \mathit{y\_SrvD},\mathit{u\_SrvD\_tmp}\footnote{Only if using ServoDyn Structural control.} ) % SrvD%PtfmStC only \end{aligned}$ diff --git a/docs/OtherSupporting/OutListParameters.xlsx b/docs/OtherSupporting/OutListParameters.xlsx index 2b3c0959652ca964471efe8c0fc8b858102ef12a..03146fa76a39a1c3b5d44021ccf8eed463d019e7 100644 GIT binary patch literal 600181 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 dr%28%t0ot%rC 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 z zjwtfrYfY`3{DF*-3dVa%SW#3YHMA?a3ev7lM++^T`BhE6sROMoin{NOo#v|dn_MrYl>1Kbw-1v zziLNod*qgUn{x}OA+nCvFeVQxW{9{3m(s6$x>_RCUDyta^bfL$kG;N+Ev63WbfI|g zqVT(#Ug)VnI+qL@8p-Kgbpzs!c!QDFQ;J8^#ePp#tg*I|s}=|93RpNTdyk*UCeNZ@ zU*=Z|e9s^~b#d||yxg$LJv88lJlkN~zl5&I1GqkFU6v^)Us^<=-3JG=A!~;Cp-tVu zXa=D0K-E`d`$F$J`$DHxP>kl7^kgC8b;T_{D4%ll$mT4zys%bGa%;FPVzAd0n;|B- zSKJqyJPw^#Tr+g@$|OI>b<$#sDZhI4`1s524egZWNM>`UNlFvmIDV`?;#BSSwYka6 zV70_-fafaT>E|j=Av-WQr7-uZu}+jIV~fAr77_J_`I)`L9O+*bz7n-5TgTeMqu%bp(m2(4-`*bMYHC_kzmXrj>i;cXCTYc~^ZY0a@ zmHg#(w*}MBrr?7I)}=vN2J~gOyf6C7)c5-3mu^@8vbWuL()DKQ18rUgA984ODI_V% zmsjA8+6}jPKe0qBXW5jBsRk1LB&}eg*w9_5Qb{vuB?aJ^EZZhwWXPOUtCAujp(Weq$)_GI*c|UuP;` ze^$4M7BkdiygIP;BnTp=eft)YeQPi+L}4XY{9wRs;zv~&bWWp_ZSQc6<)5I3`Ip%$JNbZ}K#@Sa!OYFCpaf7a42&(zI5^?t@L} z?(P2Bq(rg4KRfjHi1ddQyqI=x{&4fCJ`rZyXB;%3jjy76XYr$Nxp~7bT4Oe3-rSDn z6}4xpxr=v1!LTCN|5I9z@^hhASikMXcGy|&k+BfBtF!f=wY+mR{>N?+k=tO$-SR$H zS{9ElZnUp|GITX^eQDOryf+J@?#UWBY%y2`QjFR1os8=I;NRaonD^CWbu}&S)~bse zRbi!VXm$)*R`N`|!5BspmG+6%B-w$QmHocRf|AYKCavOMZU;K+T!&=W){J6iw>6xOp zU$=dV)lp{G?(Pz&dV0)tSuEB}9+J!Mrff`X(9QF&;=4z9)>_x;F-wzRcEOhqNjf#X zmoY4VtuW2f#;~9ZD{21ypyzr^hNq~5u%$x}`nV{5fjA}Oz7;e$(?FO24)y9eT@ z7`VMOM%AU(a(5|6&}6uLD-S95wUHm%B-vrF?45U0wkC>Pun&1BTGp_H?)e9Ye#Cq1 zy6cLbWV|4%wDInmFPi!Vgd}A!-?v89Y&>lSZOS;^9}FDG7S$!*Wm5Nl48ublyGJ~d zI%j*+e&K2_M7iUhX3DYVCWwFCBhKQ+-T5J2@bTRv7CicPsh7D4^mUNg9UKRBUYvb* z*O%AN?gdHG;as^>=h$Mdslu-Hv~sgLH@@cqg?S^%Os#^Q9)tJ)VS5J3cGg<aH|CiP(R1f~OgzoksBbJG* z76Q%bn%uAiJS4|c&fteu_|9{8DG(fuVza$Hzb{VL5!dZoGQavP=vPH5i*)!wp7F<5 zBc`a&Pn%esmyHSi=8}9>*E^WCCG#qO(d!m}r?0l6?QD7taMO?}Z>e+@6TUfg4^tk@U> zRPx%or=Cw@>RsE7|7TOq_U3wXC-57JC}i)5qa4NRMY9)6s!}9(}T9+zZ{cJH6PlW@}6KtO*|w{|O!n?q%ifJHE_; zKs`uULVy=NIgd9-#7F5`icTE;YSgR8pKd}}4Vv&_e4Ri2s}F3>O_g z^MGdh@%VM<`-M#_uO%$lGHHsMLPD?PGZhvINp@>#laJ6KamUQe^Gl~;by3EkV=leC zE^9i@GQ~N+BD`(!FI#IZ;+_zqII>PR{8ZHEk$hFsdB}bBUDYwvxNXLO#8|QX; zl|Azk@}=*7HGTHwZ!;o8j!ipkV>9}2`Pz;xzYjE-zNEZwQDB$I ziZ}9_C#BWuRi*2LgASHPlqc0xBt=$U=#YCmA~L)@yXIr>>PI(J%+6JLimX?oAB=J@?{S-}ZWrM)c@vtMLJclsqN)jiL< z+0UQL3#O$tjkwr!Ols5fcYhQg=^|>OlH*WeUr}aNxu{5ux!J=X7|h-DxNjk zzAF8`n`+dz+i4Ps+07c2#x2PUYtZP?y7wCvV6;{JE&5My)WxsSqgP+%g~ebc>@)tNo%2_~M`8~rF7kSaUf(tK|G#dEQ;mYGq0 zQuA?^=J6lCjW_-(;E0+hXzm)u+E%DLVQ!+9q>2(sgKzP4b_(b8$~p;8?qv*}9s(Kf?P%A2==ANn>(D%ThOXSiC%@N7NOv8YCzE)dI$J%@ zj$s;bv`|+s{(v|=@+689-K~BsDnKRFLT;%RH|if@DS87g>MaOPZ@{*K;2v)g*Kr{# z(ILJM6mDbZp)rl)`{-?n_~iAvOVK=8qvEubx=*H^{^-5ZhHLmDUA?!evTNA%UZ(-1 z`g&g^UlkVK77K@lzW2Uez9H(xDtBf9eYOd9p=T|Af(_OGpj3?n$8BuwDa{lN(OvpP z*S0iI?xSmmnkWCIyEoz#wNHi_4vtg=ba=~j{c)-&TarLhsjv@=M3o|GO%V5i{x&PB z(zQ5&o8lv3FaOe$c%T3HjIH8$Y%fn}_VR?@UW!jXQ16rH)H^%PlWXnepSto$63kA2 zxC_EYPGB1uus!w{H>)+Y^c>N-_0kpfL{T7mLpqD@QS&L5xO>+!lE>(cty|c>(R@KO zto!Hx>!(_M)qnDKae8`_9w6!?Nw2us^MnPSf~#IEIOT)7!hZ8i*xZR4orLB*7WHYl zM$4vo3^P|O@2gp)o>FQC)l=XP;)vV-%d-)6V0~Z3aS!}KPgjG)RqE;La#8yVv6u+w z-TwI&JoG#k_gFh~ifNi%(3^Iyxa~JIcK7MdL2(yJdnhuxOM~=gu6eeeu4$gFw-5C^ z+fo+);YyIyTreD+eJHSf^Nykwx!2`750@k#3>MZu{c%N=yL#fKcJj94=s^q51p@{6 z#(&>AF2kZo5x?aR|dRpuk$N6M7j0FA*u6+ z6Q*doFeA6|B0R3_LS9UykJNh9i7Jcb=k}z>nGDf++6I}+?uGV10&f+^w?97*Al5PA zVp6||t1Zn-;w~DEezh}wW9$H{RfMSi{TuvE{Xh91zUUWGY*te}I2$2MxxTokVWTkH zqaK_3IXZ+%UsZ(rn_!My02^e_d#@e`joQ z#p;C(8qM>UnC^-4Jy+_oNS&(;;X+&A=E9ARb^({(%dRl&qxn%lw|JBP`SZQ$bq4>R zo)dD;dC2wBj4!cDUk18*oGX>AFAm%u`$yAzt){|m^V`W8(u1R`n&~dXyUWJ${Q+86u!97-y-#; zVl|VKFjX%}--r)V|3)*yr0hYx&0}r9GB#fvAG1Cv_u|OBqO{oF5g`zGqfUx|jHV}* zuBLljlYdr*r1Xg>R#gU>eU!CrIyn9(Lx9CW=bVEc&-yQq3Q^C$th!)qeymur^Yi1L zI&0{?Z<4Lmu=MmQKZz+>&c(L!6z$jz00c9XNzQM+UHg~##et@S&pF!%T%tvU7GSbj z-t{iR>R;Au+lh(0wus{DE;;0~xa59{r@}TkJhe4zCtseNX_2b?3(Z7FeLI+BdRLY0 zS^q4B^(Oc%R+k}(!CPxupDR58LY>Qjf8M?+mb;{XznVmE1h^pya%WC|EfFLZ)A=d<&Ca1eKdZP)4pi+Ytw)>xgOaomm052? z+}#)8hY7_U&;!p5g!73}r%c zm=q%_CdW)l8I4#eVuu!*iKI~>NhhP#3^~*!RL-%H5sFfiLvjjPIdzgErB9)Qj=%SH z-}m!5#J=C}?;m^Z^Z7i_bKlqTeZ8;ieiFu*up%b~qFtoMqL3_mMdMNgKr`FV7g_WQ z9TKzaGjsRuE07ZH2V_ZKwY_O@5%sZ8hetff#?09{Heifrf;>;u5zZ-W@F z6i}H3d8Es@?()Ns6r`~8J}a+rzJ!KttMC}Imggdv)%(KNd+e5lasGM!&>8=`ovZ$S zU#Ag-eiW(>Fd)FtwkW|`kq3_zY?QCHRw=d(Hqj$dRMh1fo@`vco`tL6f*wmOel_R5 z`nc*ktmak5EQtHF4wEmG%)F27Ots{G0W_W;Tx@F3~+Ed^Ud(g}%ch0_S zwAgnfAR=ztK^qy<@cyWxm%_GHzgX4x)v2|5+a6>b-O&A%IU|=GVp+nTa3Q*vdkpfm z=MNJeg@Ii9%s**X+f4+5%Kej0W$L7YRy*Y$VFI$sMfWHtq|8U2gu zs&d}D#Vz%FyvYFDx?a85HyOH;FD2Yux}w+B6%7W#GsB)fk3;@P3l*= z3dtXJTE}tb-@L|nrJelR@)!VYEd|qWZ`TUe1Bh6X#peRQA{o^$FJR`+z? zZ7dfyQWD+K`CQnTNVD+;>+&$+8k!%an|gX}^Gkb(WlOB%3W8&>t0XJLIFAkTr_^7T zYbal!agPmOOl>zZH^XT4vygLm4!h*-N!zgQ*wmIoWvsU&7n@VKZ*b?01^zl0383TLcJw|8359Zr-)YnV!0bWhh94!!Kb=zpSmy)tIH2#lSP(zXRhf$11i8$4svIKuMTT?_!e40G@Ox1$dv^4< zTXa*uVO1F`EeBXut+r;PMr-Aw~EV#Oa)3m zh8No(XZ3&Ftj+`S=kyc-^?N#ve51-SJ^p%!dYSXu=-OxX-dZqXgmkQ%Vk)n*q17Tc zkv+aen`3&h5J2bEbB|)2nkO6SX0MH2AZf`%C-p`6(%RmH5iFPhi~*}OKG5OrmXOQ| zhnKZaI4l`K>FBGW`DnrL0uj#EuXgEHR8rsd)tZp$cznXj#&0LItQ^G4R-rXnpEt>d zBIqV8Vj0LZdd}Q+9Im|>{hTuB`1ZSCiSGV2+KdSD*nmdam|iNX_6gIZlm{EgcMcNN zNfICOv)+0Bx zG7!s8Z%20iTrIMqphx#~St(X{!Ti`~W&wZkaMRk_YuKvp8GRigf_$`aIC)0x1#T+g zFhL7)k1e&%7Mucl{pcVw!iX`wg!t0SSeoCbJ*T9!M-&Ak?uMQq&e%niBHMgZ@w7*G zY4;;D{8Ui|u2|;WH1;aq`^ymoUO2tHF}td~QF{f01>#nFegp-DH^>>)hvxU$GLAyQ zHxq0Nrd^q$ukrR^V~+Qs`gHe^UUN)CcwSn0)+wz*AABiwY_(?Ak+FrSV+@{vNs;d2o-G?3Tv1@9k z9J=Kg)1BEtrM8XlNbo-mQPfO4Z%!9|i?gRx6xs~92)e~3g5cg(o2Uc}?$WiFJlI_c zUiHbi=TjEH_M`z|>b$mD!(a-)kd*9v2h4nSEE7?JVEv97XA|U#a(hNq@-WoAgOJnq zzFJS}nh=End$@s~TI-x`M6}!Dwv@iVm#C?}Z@3Skys{JkFXDK7{kjM(QTArBpj_v> z1=skl9Heo<=%I)_5geq>rK1xHNY~l35#~b>H8AN75}K5up}v#I*aU=e{8T~J`7*P9 z2kcq0U`$|-Xh(^VLm;}9aF~O@R-X@T`_dc8yhpcm830YzmcjQ|G-msh=@G2~52(HL zELDHe6#q^{nN8pUO8#gmsJ5kPcNXmuX!Hx7cR|2mpD#xrUe@4P>oqQk!;3!l$copu z4%`6XoKCn1+3kpo((|SrWm^}q+s;(eB>wujJh2=kd=0{AGGM%P*3Nx zYoP@Z7ogVsq3c;FQQw!9WC)%$0LT^IPk4}(jL0;}TTkrqOM1%Hhr$2iP8RI}r0|WO z!--arxr4fo#zUF2$;ki>mHMFC`G^F5tC{0&AA$(8T7wg7(8+53fq4Sq$#F1?iA}Rc z_fV-5%AO7K+i;GmiX4?n!7=}bsj%cd&x}aTtUB=1K={uoK>FF`V9%*YwLE9)ko|Ds zP*K7juQ%E-5pEIF4B$B`G#W+N^QL!q5&g{S@nK47ag5!N|I7yjk_i6VP-xfn>%@|; zOp}2&QK+xjz%d5WPW~MNz0+^&AlNLugRuXH84>B;jeQvCe3LJl7@+(mfp?V}I@p^q`WRJd_U&^8cH z#9CA~Z<0?NfNnulUgrGvSyv68I-T9@G0Klus%FqiffK%&U`LQ%-SS0`C8hyo$<=q- zpEn5@=G~ZLVBv0hhZSo?BQUlbE5Jy%83SQd?&vtAwqwN?LYY0c4lHeaQa2K0>1e#R z3pQBHl5I-6;-0A#wy1JJyWm*S10NnQ7%e5s_;|)}nvr1N9OPM9)Gd8p!A_!ydgiyv z+lM~~PLe;0aSaB0=MbUs+-CzAlLl7C=TAau%Xw)jI<0lQC$aDh&Y+(aRS>;&2KapH zz9k4OPnZ{y$=8aR8XQbtb!od_{+OjRc>Chry|Y^rxfj$=f%U8>a64a1>S6sc4$?m% zzvad|Koa54Nog;^P{ZdlDtz;&A;IwN({2T#cw63e*4ePNjpcW_lzW6bHS)|L zsh)@tGQNB1L6mO-G~S~wbxVp{Jn;_V9`!MTF`wjN0C+jo3C>L;`sEKjt6)x;ZF6-0 zy^z|gHzP(U8<4;P7lf6x*q?+u0jpA92#FmjUbfHp={zECfl4K^K@|ORzdl=3`x`4W zX(Yjmauv|fZ$!1>8}q8jNx(YDN$=Bo-{Uu1o4ktJS-Oduu{5Rb%$38*1J@q`t=SE zqp2?~^?0R_^Pe9lSc45!$<=nuBwBNNzDS767}RBw+KyVQQ{E>B8BiA>yizHJ91_c7I~dB!PUvk$IX^dL^G8CW z0OODMdD>AEjPYUMfAc#NWSpgyE<1?6UxDt3Y)KLFdK;w<6~gR6Fwqp=GG!@&`Nx!8 zR*RkEYQX*wU&o%DEA%Wntda(lm_`bU048{D;WT|Th&(ntoOxerH=6@{m4sac_WEKd7h>C}y z2j6WD2`T$oznvGAO0eR!8=t`lcaM<9EMUzfMtQG^^3w1F#8@MkJs*wWk5;VcH?~A^ z5@-riD+!Gt$8|@b7-r^_LV?bbi5lT4VLG~Ak_U98j6k7;kxla2S4lCWS3L`_mH<94 z7G#51?tv31tr)ofF$1>dRBKfaeW56WqNxnyOo$4h``;E(OgzIU%8su!GWUYpbSZNO zmVRYfsVz9qHk?67MMWm-r3^kfxuZ}yG0czmNy)2uIhZxVH?5tM8Lukg&I&of;u0B) zuykl<7T)!TzD34EKIUEjyoY9(X6k$>pu~&kFd4t7ji$VQ6~hmvN1O9Hdgoe_9$iz;No1lFXZqtH0Aw^Sf<{cU(-mT;=GZ|6udo{VcYWFvdzB zJxP{2Trp6cMqv0A#MX1T8>qVr(Kbw0M1Nlu%hPR=dZeN zObw$7g$fI=>5VVPSBnV{qYc0GOxC;dYTaDsYh|C-rMu6l(&nMy_o9U8JltYtmf-`1Xxt0Eu_JjRRp{aG+Xkujw^tRYh=tzORo{mUYu;eEfAt}GNd zI_j6OacjXz#osj98MtZypl3_hA^65)1CU>thUQ>NZCNd;suHD;^0`d zkaBEUrquX$*X@?C$BUe2uqJRE$0e>LN1h&rL3c6hXbu5m*sQjbI!nMipu_7&^x?ot zf`Ua4ihEQ`rpQL=!0<4I$_9Wh`j<8d>PZxx9vde9VRoM?6MnmMlLpBrM+VnDO0e#m zdVI{GcaInRb-BLA?vZz3mQLexqs*wjzk?%$rzc4%h7#HG<&9@LTuZQq_bx?`KK$^- zw>)Mqw<{^BTf(WZ>BF0!L?Fcq?$zLs{hjk!%M)+v&#mnagSc7sXfO+l zAS`=0Z+jpCnx&!n-%fZNMYAuC#wYUp~!g$S!|VFm+##vZ%o+J;176Vx%bnapT_oEG^N|? zdzA^txBuW~_-WDF{0%pf%7WL9SUQ}RIlSb^yuyE;4(%T5c~Lg$1$NN<$Bl{(MaCa% zte+pP9eT$3#fp_F)^ng|FUx=xuHGTE%u@qj-}We}JC9vl3)(9q7nZy|f9Z9@-Pj_Jh(rFpY=6{v`Qb6F zFUe+dICxlEH!0h$(?iLz{}P)(`D|$n!5~Zgly`n>Xrx z*H_mTXA3E33yGadjaU@u6o+4*+dF)d@20FS#`NO`-}SY%#d&}my)hWjsVOP;c@vb? zv}wFn%iR9W{%7mN^1raPT&&^H*zo0&F3)QM&1Z(3dF^{-S0ESZVrdU8bNAtzdVWm> zu3;Ofl?|+b{Kb!#N%C*WJ`3%dW_|T`Smz_&+6ldvJHK6@`6@p)r_ep$d`ar@mX=1n zmOJN8-*H7Fo&S2_2Pv06Xk6B2I85ACZEnad<2xVRi17Jo zXXHn9UE5Y(@BWXD!P5Mj1v*ze4Qp9{lgYlh@Zdg{DzL7GweS3<~M)- zr>Dc}D%+ye*!5rh*vCF5B+d-LY}k+IZfKpp@Tb}R^<8xFw%f6&0&x1)=` zw){JI&Y{S+Ylc;QnEJT=jjh#l1~(WF9Vgb?uX5nTf{0Ik;p@F3);sE>oOu;CdG$JT zn)C;2|1x%l_mR&xa|5+e_uKkgg7L1nk4q3pe|3HABP3#5V7>dFmuH&$6%$$;{p;7*|1C|!pdAG^QkX3mZLSW-YY1}-Lj>tVvJEt!)0eMEB#7=v+1?&G?#N^T-|Jd2?-b`o~b$rg?KdnLYjYkyu!&Ns$E~1J@(Q+wqK$(Wx#e${W~_V zn1?-jAMvYwI$3OfRJ)vcGQWs(Be;vleZ~E2xXiW!mw(qT=a%owq**A2_)9Sij};$G(!lSSP9vCrCISnWY(0YAq~K6)W$sYcwW z!mK%ivkP)hWAC{KjhS(L)w{9uVS#Bki!Z|S)slLSWm)-g@`b259Zyzgd)rlL#LX<6 zPg>FATG?fi_%9;wx750Js#T+1`Bjv*)pc*l zdZHVfbT7sC2?A84^quog)0?gPM>SPau4dv zZ-xsp{j)1=yIwY~&;5`(u;mp@}8ooioxiTo*&)mNbsD^9=b0qez2@k z3p|HgRrzSR0)Y4i35cLKJLI41+7Fl80fZ5BkbmCTRS1(%mEswxm-HG-@d%b7*-{bv z#-(|6N`8E>CRdAPW-ePeWuL-`RYBvcPsGQ(xLcZJV0+I@=>fA1F1*%0X9XJ{E$t4$ z+$YHCiDvVP&F~4ikl39}Kbf0-JHQSz#Y|cv99SiGS{D&qd7M%w%n5hs*&iYCQb2bm}d?aTtSs%iI&8XLEIa@35-sXn0AO^Ni*sZ0&?&^_^@L|~P8Yj8NC+Jp}qUth4S zv@OavpM(|o)Q{Wk6I6Dux9g(R*utyJ0DKS=r#qh|Gl+U)vF{7X3?d&cQqz7I|Ck~k z?F-vE*P?oR< zpcyBQ3Gi!{lp*zq&xaA1He9p8l^OaDz3aioPuG*h)kja!ZVtS5%W&$qLo)U{x|V6o z`be|ak2U84{yg`Ez1j24b6XO_7LJg=+Xi1o4F{ie??NL;DCCEQKz_r`;FZ0FlN z8S-*j(EQ$u-Z*}(Q#f;MT0&8MXlMP%>1LaL(R4|xh>z`MWuo2V*xnSoHrrNf9LX}Y z`gHTmn1i{tql(nhTgD8$XFGpv+M;c4hJM=N_tcZ37GBW|b*&1YZl*Ei#pnYrcGono z6e)jR>-wd=!2y5mVznaA7eVYcfxqeb4YvAppx49~#@94g>c6$ldTBf=v@*mbEp}PZ z4E)@7zs@|DZT#-dU99S6g%1DvMbJIhaJ_Pyk@FI=ZkVL?eWDg~O>^?p$So#m!;00+ z!lv9WRtsFHQ|Q?2mpW@~n&A^9eCpV=TLZLKn%&%}r<3)h zYUy5`dDskX_I{*u+S1ra&!G7~jKf~rY%}fmlFJ~kbCOPB=0-ig>xHKHVoknjKQHB7 zrJq{$gXK%(?Rp#a?^yq#w{e>(U+4&cH8^ssX|Qjzt2=nCa06FKKoP)+8R{}qo8QVJMy-$UX0u)0 zB{LdI8DwSB?%Jbwd@kKG;AtDNcev>6f&(2+PhNwy5{6CX7(`IlQt%0 z#&}S;o=%(MT-_Lxv=fKV1-pfrSVOO$wpg5VgrPmjy!C3x>8N(y&IYGFUJlb~Eqv#R z{x#0b1_y+CSDsO48w!Lrx^IOP$f#Ls8X=Sm8?iYITMMtXe4>`BYRyc_ zQCmzmEend8sxLQ@4dczO=i5JW{Y|gYUSTD;k*PJ;_JHHU>i#loR@u1C;ixM+E@`hE zn-&9W+dh6}HIsdErw>2et$sRd&4I>G60d89R>}4^^kdt|4=qbwvtCapcE_nNu4`Vo zI3)A#;dblHEbwJ>`H%ot+U42chpro^MvHiGYSp<;VijGhqTUVBZc-Cq&=|EV7p8I(kFqu0t<_p+IV-x*t8MN{wvZALMspI6h89I zb^T{RjuZtgcwi_U@~=O$Atp+dz(CJFdD(20(_QOLLR)MXxy&Upgh!riJh*=G@I`rF z%5vL`oz~KHC)o%xjGS%)OA#)yqsL}9W)e~DY)1CWomDh8g#s~)LF2!a-5f0fE;RNj zyrSF~t6sJ}@71&XI&#a?!H2H~-F4la;dEj{wqyHM1*46gXgV-+leHzK->T z9ls^tj2ZZq#ZB7nodK7;gYtQB6yM+jXt{i|$tmBOpx11I zzh{wEE-qEpZMKbsyE5f%{rkG6g$t#;a_C|5)K<}BKxpOVn5bgyb1rs=f1A@$DXdNv zsV7G@+~9(P@6Ciw+ponNye~tByV${*RT5YXi?K+5s*zlJr0S0m$HrN|jgL=uO!N+# zq3QjJVv#Jdy|U2w`r7D^SsH;`caC3OV_c+0k3hco-g4as&0*alr^lE(gbwesFw&!@ zd_B{E-IjZ9QyLh!@Z6372%kCS)ZtCus&+@o*Uvk3&_5eoU#>o&K0lnJ4AK$A3!Pq{ zEG24zG!TRWTu-qmb4i;;Ic*6!NIAyFPzL|7WjPD$P7h+Hyj{p8{uIk1Fb>LPIfd~* zzl$}F?G?%0VKCjw!kQr~v8ofnh=9K<;`uW|Au$ccux5R~rF+6%1_^_RB=VNaC!7$7 zTm`uT(##1-V|G%b45i4E5a2VBWxm{+vo~1*vat1R#6+a*sRIauUCXyOxd9FY`9v}< z$jg7bh~^^7OP;BkvHchJlN;k2YqEpCX&Vce|L76O(nIWYR zN+hsJ@J^EM|Bvh0r5e|V{!JUptKyNBB`)9dk@SRe4 zmw@O9qvpuU*UWEnr zcO5%Ps8Io20G^@OTlO!FKN}PXjf>18E!jlE6)d9{ySql{=@jL=xC~mca|#f}XKRWE zjbY}7cq751%{-9B925w5$V-NBzY48<_8y2Eb5%1mh^J}n(Z%kHgqpO*rfn7Grq9#f z$#X@SY`Jj)-N@6FV zyyaIkQ;N5UCqy6QOW5vGTJE^?sam?jpHV>1^Pe^r{S+!3SPte=jU`yY-E>IK@INmU zxPS6gEf9dxZ!K~oN3>79IB+H10|0);gX8c%vBIMf-B)er#m_?y`$u!A_Z6v;Bi7_j z0@K7@guUa70SXL21;7xkTc#SfeQSj}WIO?4x2AFzkuh-KqYIy-gw{2u-wrJKj9EKx zEID19fP0})t|(!kW1E2GV;@U#j;feyM^luXr&fIptHb{f z&{A2fTwUXGjov&68?iqA6bG|r7R!S4;2S25_8eW`K6{;~2RZDH(sdJwCd z6ZTL2twDOsSvxI+2K7=Z?>VUR{(WdCwC$_)|*Nd{jMl_NcNU!^FdY&(`81d za2U8e2H$M%+TW@Uu@pHv3U$34627Y)0-a z&oYt9$6s{{O{}TZ;SqS%?ia@mW*u!lvjZ8A+q=R+<=H!yo5lXAyALu@B?UP<^#w8Q z23Bi}tX{@H{{-a~tE=7#@}3%u1yIciSkd>E44tY%FGTSH;k7`0`bezud^f+b;c(Um z=f|uZfgocR=h%D4Q+KccDBX;R#c6C9!tPF@Czb;C$DxT|KNcE6$;5|KL0M%|t<7T@ zmWvRJFIbhoG5v^~1u0#+7f$Xqk-`$!U3%srvMhbYd!65DhprNzL%3w4V2q@EpWKPX3Hgd!!8>7Utcu;vZj^af;+S~Vb2j+LZ9KyC zS?HA>1MA#Vdxa`wz?`p2@|ZpBKFIl%Tq6<;H)`hhEe;!QM%&zH5RW}7H}*qO3RIaC zdw~{nVg=TjFF4HNxcDsfY{B&%x|}s^6VE$!2ch||U+`efs#&fw&R~cbF4u6Ty-HQ| zj$w&CD*Wtjynzx4=tP1)2a=Jh8H%>)gS6yYq&h$Wn;4$qK}(f*ldrTWccLznF z%QKX?ylG?8B3PDr5pOWRs|yEZR%SE6ER4rR+uiDh^e!HzVK{QHhk`!pA6j`OCThXN zTB9+8B|@aw!PK|rE1g2zaK!Yy+|Cm;;mGAS%Xq2-JbB~Da1hJ4Bb2}|Bd+8oFZj7h z>_+eml@d@P6CRZm%t@30UBG>eM?P6^6eYM;o>rx0E=Y5T?H5{kNT={Ryntg=#?-kH zhT9x<80$A2bR5tpP^rWRX&Xh7W(>7ZpwD)oCC{KS#cE)Ha)?J`CBBv{5PTVN25jZ;#X8kTMl$R%tEf%+^{EV?(eC=p@Kt1_^Drzc)AdWIU&qI z(w&es6?M-~8ih`Rql7{Ep`snU3_*)XAAc%(Sq$|@*-))5Jn34}B%qpse6*uKc<1Ndog-Xf>4!nCS~( z&RJ>hc}c`kGMeW}#G&h&DGXh3*5fU8GIsbkl_j(^Hc@|3U*hA)cbltG zS9Uf|`h7u~dW^o`kt{W<9Z0~BW7PxHq7G&c(5l(t+i&-Zoqfk1?U$-&gK|DaPbdH3 z;5+o13k@Ko87NOPiLOn zHg(?yW44U9qYzxC+8bQ*-?`Z%=on<@wX@4)pB+a5LJHMdOya(GI`CTqenVfq%nI_j z>l*O%Z?t_afuyS*WLcS{(WYu#^PKcTD>v(O1-mo#TF@oUW;Lt(JHJZPw=xNew`~KO zCUurc+W62iv?g8+`PX*-kC#Y?lXVI!{a0=R4MIL(PwUr>EjOMP>hb+e=Hax4o$yw+ zYVuaSP>;I14aRAj`mFgv8yz{%Jw_i-0TE0U$J`etX$O8Q10jo*!7b27NI7M95kV6| zo(p<2P4f(680g^#UF_&q#Io@{uH30;Ul^Oo{`3UKV7@S`&FedW}ViDdeYI@IV!4+&Ix4ly@NW-`R!7G?g6_k@dcxCuD6j zNh`EwbkXA~U8^14?l7GbIAY&Kp^tJs=uFm{{#vi%4WMw98~KCAQrQ?OJB%S}WvMZA zKF&IZkxqqbjtqiB&1Q!#&u6A~E$GK>IjGB)>C7{|u{hJ0mb$uT09*k<>p>Vv^k~0E zYtf6+X%kts)pGa2P(2%v(f&10P12lMbo^4bDax==Eq(9J2IB)POYUHxmo!JVY_qL? z$U$xbs{4pS(V-4Iqj=rRGw5Q3sRpredtVyw`7IvyrZ5108)|-%T`GPLt;70-eYL*1 zvQ59R0AHbqK<@?SoDd?;%T$$OJYBqq>lg)9yX-VsY;FoG>E3V1w9f+mWrF%9#{>bK4#N_c|Q- zet4oLOVbRsd}P}Op*Y{%0a=sVMo+VwL&-1+;45s|qwc5J2fwmFto$*V_(hAGw_>6$ zdp$=u0j&^YJ~niCjk!2A=HZ{mFEy zaG*DR<*&}L#->`Iw}Y?lxa4*JsagoJPD>}~6wYDsu|$Jt?A)*-wXAvIBYdrPn4~3n z1Qp#r1HGD9oVYi7_Aa?|+;?3G;|R1S8#pS0w1uxWJfUZd`Adp0O^#nvuv7|oFm{&vmm+raeGKhjKsk*{q+LKl7k8M)gf9n_u zvOJDCyFA+C5(77+YI;zT9c+McQmyO{)Wv&(v1$$=fA@?bZyBT|f_GQ-3(j8Sby%Dc zaidmvaP5PcSZgXl3)24?berE=?-zzK8cZC_lKNCeItbN~(`(Uhjhk2dAd4bgUAZgS zlH6CRe@Zrn?8*#Qy;OIevcXEh#tv=nUs?K7^=%OM?@MJWIji!ZEfQj}d+E$p!7l)i zw49m{1BA{Sm<6K&&x0}O8kUZGjWJeweiqj8f>aQhQ0lTJ%&385=# z{O6c<&(ELG8mLp)H@!OEK!j68?qX68w7%fHVTm?c^9rcIS3PVKs$s;uT31N36No>K z>6qXfjQ3onMlCOX6sgmH`%kfBC20-#+q<&o@Jj!p2xceLB5}LQU=ic8?7HT?YQNn5 zJ7Vode>F)z+_uQ3dG-FEJaw-q+Mp5MpU6qOTGyY5wn@=TMhh|U(%w0-6Zlml=e^b~ zH1bStDy!Un(c#+b=qI=1vi9`Xx@NHnvmrPAso`opg=O)$z0{+nrV}w;tR=jiRi*A$ z%c*~Qg!M2v*M?qjVdkx68uXl_dwKJ=g7;{N>8X6VD7#Cot1a)lsoW||VyMvUT|!k? zX1+aZ6Xm#0-|BK?g|;-IlZP13_}ie*2AQGMvZI^PI8J(9?Hvbz^EqtHXvo0OO1?72 zmY{M-%waW)Tb*$Rac=Uy_ZWBptEJGvHRbdmV^w>526?lR>9@>iv0_nd$Hs>bUeJ6u z5e%9p^&+GR3dUkYZd$_usM6E(U~kkikYK@>G~O1TYCI>j@(b|mub#c;z02S7xm}zH7T+wR?#~A}o6B0G3jUQc z6tAL*GiP-=4VxshUB9DZrm+<+uC!g83?yC3;g+EA-iyU;Xv`#SVEBN?Q-U~>NdW9`zoox2LVCnsA6i5B>! zCN@vD%bPVGt-Sr1p+LPBDyWzDv>2cIn4N(FD4_ zNiv|(r=u&YK~+G`Axe}-S2wkmZ5Svb)5VRL>Cza1;OW@#0e(M*2tR%FHHq*QaL$4e z4}HfcpozwN!9nnzzBB!SmPoDbVAxLW$i8rTq?o5GDnxhl6 zKdh*3`n&E7D`LM^?NCTR=5-k{z}PlTQB@*_SSrz}>qiF#vVJS(_eGkINV6+FYxYE?Ws5KnU_@{aVMr*S9g!9*R9F2y?Ge~^*#KnCl!%LNUR zf@_{ls!Ddvdol9K(Esfwt;Jl<+EX#zT5l46v-9)Y@|jxCZYavA0m z*d!^~Z$fM^2av_)kziz54izc}-8v`aO@7}uJ+=Ugs|;?+xAs%)S*58CNj|o}MU_b7 zjA15u8N+VIPrXD959U0LClIye=tA;x?f>moH*L|4G;k?33at2v;=(r*XFYWooEeSb zxWWd^#x=~N3A9V@XW%TEp1fg_x)& z&5)H*?Jxp~V;$h~RVLkTDpn^xC+nt3J1NZzIL49}HS8pDsbVf*v7sthOms@+!^vW) znfjXNG3AVI>^rGV#!^x_f@KOxo*6lYC=$^6<~CT7HCriKMyUolF?9`hT(O-^TuyAP zD3w%&*&^9{O_{+Ooce1$wZ^A-Lm8Wg{~w#C#5MroDJIRuJh=cbVyW(>ig__9&I@S}ciLLV)Fl7jl2TCfcJzv9 z0{Y*q)4i-{e=H|b#Y^**G=JLl{-eOqRJm+V*#Sy2zti_j4&(j)Bmxte_L1{SmD*Po zJvc?*p9SAMBi>Av#zAwE>czSgU8O{%Hk$5K2~v_|6?1AVEZVB(AI0pnDQeh_tYJ7z zDlufNwYgGsQlv1d7}zRQ>LV&44GZ6o6fM#w$z(7rmCT~FN;4fN1YFUGp&r|G`$@HTnPL$HWp_leW5|H`>5D+^W4%zNi1V3ufzNY^qja>TGa_@cm-t zCb4d+aGFjzVkCt;fZ!-kvvjn;k_?$QV63*CqAeBrIn`zxG z1R`Lw?4PY^@!LPO`R;RXhMfK~7zN$J79uD!$MwSu04?DawSQ=6-Q1mx(4)kvO};Qd z>srF&TLW&{4|j+wEPtTIo}b4@;!+i}a$qU3033?&Jd!OXEOg2kiiH>O;aArfrE>-( zSq#x$p1G7m%RxvY&v(4(b%Z`g5-rFm;U2p!GJC%M||jid>9R_34OGHncq1qej{;K2Zzg;(v#XU z&7v6a{$zMYKFu(~8#!u{9?nl8G3@1n!AZFZDTcD?+>Fx4yb@E?=lr%(nfXEt`as<( zBQMI)TNW)Z+-=VbXi9@?$^(F{25M-|2lh73Hd1Vj&RM`|Xls7M*PEqKfjv8f&3pi~ zc=PY3O1az9D~tDlZl#Kn)#puUiA^}OmDtr z%V^?I!>S8)=fL~Mn%hc4C`j@i&z^10nEsbR{k(Gmv;G_W!`#&~X`gVCwR(y2b z*T3Bu0%48SlP~}D-FQ0IfZ;G0{UcAGbSrRXE_QT6A;$c&f@qsI@wxFKRUf1k z5oW*PU;@W{9I*A8{^Mi)_Z-M;5A$t& z@Sv~f^XeYgV-Eb5go;X{;p#pUkzb;vB_9Qv$tT5dqLGMm{v7$^Tg@yHeaELn24u6r zuj9&yY(7nqz+|+P(jXs#ky6JvKBcb&a#iN)8I8u~##B%b7LSouihCHvrAEmPB3KZM zH`lnXk@Xf_R)g`6+r-py=lB=mpdZR^I+e*X)T-UD5-{>=fjSlEKe&gXOGuFa6`#Lm z*1<4xR~Z7VM8k@_X+qJttTj`cF_!${RGjMNXO<37`{8oHpbrAdB+gXS zpPhjKsLAj=54kxG^brlqNQ`iqIFc%ko{E7(nm*zAlAq;J1SxjfQ-0!=101>GNb^l1 z7p!}4iuYqlnTBvw+=y05adTup%%eq2#_;8}GQ@nYxW?X23=y%i&@2oGiJ2wPJOfV# z$24qSE!~@m1aq8YEAlhKR_B8STo=qQl!W6YJ&xTZOhAVZX{=tN+(I*@kp@Nn0Ch(z z2D(|0=JMdMv_*OD|NdeE1u9AD)bPHdX@Twxn`Tx$C5lDmzYF+Ce7i7ZQFa?Q(oALG zX=|5G@vBFoknAhXW^4DiGU>|96qDHME>Xd3WIz4Ox9OW_P~V#@ngE9WFXx-w&mvYe zZGXX!R{Ct`)}66T!zG`%-(xz37is%Y@u#er%gZY|T(d@yWdN^V$Ry~)PN&taoZYhI zL$!kMQ8yDIE5&2ZEFG5@>Z~?_l>b92CFn|qrZ#sp%UjzH^M0?45|B9GpPYw$5ES{H&OT8K z4XUY}M?^dEb2j3ju^ebs^SPu|yH95E(~tM)5?Xh{JqV~j#X$MFM3{J0>W1&P*D&wF|&xWb*|Ua1UY$N(RY_+a)e8iNd@lMSEBTSLQeh+*A^ILhcvIa+MS7bjB0 zaa=L*4t|5*P0Xvpq&zluxD$VGrS|X)5e_+7hv$6QDJLlN&u#BtFt7kh4Jjnb!dhSSe%s4Rq^XO#mu##YdwgQ$fw8H!-I9P$U9U~n0P zRw^g!I5jq!FAt|uwV!y?>?1(P&!XeWkE>3b=vQ+}`H~=ZN|}&gK8*-cAB-JG$n469 zSvpxEzd}043TEg30Qy*&T!)cS7BupV*ib3&s8GVsMkftY2D3dHJ0Fk`OA!MaYZU4R>*uD)OuiUv&uMxM#De|(QiU(SQP4^x})7UogrExE-#FZP; zzv&Q@#mq?QfqS_67{YNmzoBUR@lWZh>m$ zA2T}7S#%i0n&NVw4B9)+cVeqw(|U*oh!h#8H0Y6Sm}gK7q9jgWdKtCN*a5M0ChPe+ zu~;pqMm8h%!xZ=P1hcPKrNFv#F=$$DV_JA7%UP%JA&zH;yed~8_`0JjW42T!QthzV zOv7+B4jIt-(d7v{5q8}YR_$a98)x|gWBN*aF(I-A^I7AK4=JI2#U1_2EV z>)dz)2+F7CsmF8xDwEd^=SbvrI0lO>o$Yd@p+dd8Kb;1+ zb-;ybLwxnEIhs8hnn8Yu{ywRbf3eJD<^L#wl(*AxghUZM>+%O9Vm?0>ODsI(^;JiRO=D zFb2MHs@!-`1i)yWcVoo2FA*$%cwE-BarVtoOrw+skq{%=tmh)GL`GK zj}{F_zm}jQXw^K_~5b4z-OhLib4CLKG0P{;NoCu2euKWF{b<>EapJT{Ou zQdjidwfs*%*8e!{9L_!RttOrc+)Qu<7t}3FcA`Olc_=GdRh!>8duf%&_;Cc9eZ)&s z6jlVn|7i1-1hn4XIQ%K&2Ao^fJAK!UE@n6P>J-vpynW)V;Mr+A%zZ)nf%32Ji2Of& z7P<~*VHVchQh&*7Sl;J7CY-ahYSlsFKi{=sC}n@EFh`-6x~~86V;ePn|ATiJe(Sv4 z+XziUyMl)7KPVSQYTf10^=6mmfeGrY)wXWD*7+K!LXOs+Nn8-% z*n5wmK{;>C&|Po$VPj@}`V7WXzezo!NP|oly+lDJk5#d~P&Bmr@G;*pb}rA2DuUo2 z&#u+wQT_k8WxG-0WcHtQKz3k}Oaw4`oeDSdKss}S-9$~j$-krHl_k>gEAX37wXv1QZtM>sL`w5pkzu1ZQ< z_d!K`H?y0YncrgP?P}WnwVvr?cJFIR|9O}>0=Z5WVOj%xr<>L;`A)yU`tA|R7uycVTnZY^_q9)l(i zTo*Ug4(WG{c(`T8qb_;v>`U%!n^^vz_ew_k92nw;X|?bhIpV}xln1-f&%q4#4YL|$ zIa{%r*Vo7*eW_gqXH)tDyL4g3Q+WN(4b|X}2t!7+aTJgZL>x7B;NxXMZVk1If|-bs zzcPVn##3sOtC)L9qzmuHDI=z%S$mvqG2tfUA%UE(^a_qvX>AysA4#>^eoLz_knfPa zG^X&Fv@tz0+jY8UZS6dk%^7zu58uKOM3i)>pYuhlK!$X(aLS`4UTN;FfZXhsAHOyP zdpDA}Y~_6)rfdzuvUpWKRhUXCh1n^3a?a5r2q^qhyb)kAVK~EHvK}5gl9DE|_0o~N zEh1EnyS1Ak)JhyjY9F}r+Z=Yh?j}{P2Qu$2iFMVHHJ_aX_&SOoFuSY%tKB+e5ti)% zUpY>d=4KS$6F%MK9YhLjC(fQ9$h4nVvDaDT4QxUhRWT4_KHlCNHtI2S{2-$Dz#-7Y|t>j^~%=@AbRB zXjA=`Lii>VgN*St$vqu{18M;WS>}Gnzj88oB}Z!t zz4O@1IV%bM=zcMmy+L6t^EL%48mrHEvJrr4fe7a5y^bGrM7iMKJ(thKAfKlep>JhH z3Ry_--S$(5iIlS{ix+hj=}rK@PnV$Y2O{(}pNU$v`|XfiDp+PupC-v&#_QN=6%`?< zSGqWcPY2bfz_c!<%sW0>I(_0CcFgKXF9yyW&dnjzSN+yVpP1^BUYwwmVE$%LLqOj( zB9E`y4fCK1r0n0>Umq?r{)`tU!~3`h6x z6J0GD9rG4uz}~ILw}3T8%c~wyU*u5+l-5e6CSK|%udR;Q#uuxlQVeWa&0nL}%DH>8 zaou+y4V$AJ{xtzqWD^t|L5`u7pBJe);f(^-541iAcouY(VkRD(eD~+EX$a-_9s6_<8JvKe86g4gfC1c$>Sp&o2s4G;t-`K9D5vVE=W*Bpll($UKrv} zJTs%Q$i3zD=JCxnvcSeFSxcR)r9Lz8n`6y$J8K7q>`6@84(7eJ_?X4l$nNB>Wh1h~ z(i=b_`6qP23^zSH%OtNL04;r}==9#k96PUf!{F!QFm^P}(gEko)G*9~5Zv{JDI1O( z$PD`PoAR_kRi+=CvHMReD2-nss`|~N*yXCFS?f&*DD|!l{J4y88Ic1nN0j}i>T6gT z>hwFheV?EIW-_bTytRjyCjCl*o0o;D%sPN%I`Tlnpa$b03Y8TlfQy@(AR zaW;%zU?30>I1B1e(ktE;vmC8R2Py^@b5Od?`+%IZm{yeyLa_mIitL3W?5^G$vEa&q zu1lG9vlqo3Aq>+TYA1p_96g3dY5-DB&j%M-(jqEHeoAriaa5x$|MOIp=F5K-9_9T4-Jj$k0pmi!x*O%0tsa z0r8})&_6~jyY-#q7c7f9bS4mN939!KanXGUy6PTPP+-4?nlXe4(hnyBoI)4M>qR+^ zL{D93n!JP+7?MVXPY=!t~ME1Bw^f2){aR!81$ z18au2r)2#;d~ij!HO{{i!^pp(nj8s8q9i5vHr+eCcKS%ZW$IJ$xTnF#CYyC7!p<`o z0NBYj1sqH3MXhe?I{tZSQ2v7X@9>hYoDZA^C+F`{t%y5_bO8g%h>7~Q~S<=$y^cO58rRc~UF~kb*lw%_FzU*iR(XF7866GWlkm!%O5rEMqtapCYpP;q>ORucB2s)6Q&7lUw0(xwKTn{6oBH?I47eTSXP8 z7v3}^^7>XrJoUDulE(yZRFHH|1exCl=Mz$VX%?p>h?XI@d^EKz@ZvrT>(uL4-eH5Y zXv2`n)D}UyJ#Jcpr_ge-fXvFIpXJO0hoQ7dEuc)>xp(F{AN`lS5#-0#HGqj7xd z!%3N2dUR-BFilWIXoDb#XRE(7)i5;OTaJ+el`kZIH3tMFm1&!?$Bb0=O1Y8Eoxokv z?1d=DNFlFWT+A=ZPL5Dz0)Wm}rQ;l;DV->M9zP3z2SZWXNrt^bj3O`~CtooxP(kfv zKE%PJ+4Q?DtWn}cNhH)7yz!m3vSGtVoQTdS&Q*41tWj%k@JHmMZp)B;D-^hE%@r{#Hr z7??~FsO6mFbN<5GKTwkz-qG62*?ks<#Ty3=?s+k2M+ro}VO2gErDRb@$}6fH7Izu0 zsOtkmq|p5JVM^&VFzQ4-&W$3R{{VK?5dCWDQ{^X*+qx9j<#e`4L7 z%jUvcF|FA9>9DQ0Zevn5EE>o5KLW^T%LOPn@`-ZA)Ba6d5e&P|C~88=>f^#vRne-j_;9N4{b(A`lwo^$ zRZ`#K=CTygfD^IytLtR5t-3Ms1??}m~wsuPAgo; zdx6En3}(l19*(^dmwn@6hcriQ+w9n}n4cUNl8;{E9_MD={>x=_Dg^gqFm2%!8k6=L zyR+Am24iuFDnVEI=s+Ah@Ip-7Ef#<|t%w)ZJ;*|FB*%3(`J3WE_DMu_L{tfJ#ySfP z%Zv>pU4F}qj#lN>+|Zkz%vy--*`kHW&Y>c7p(2Y92L;b}!dh~`b}WdzL&cR2`Q!bd zj4Dv>m_?q4QrFDzjL-fSB2LAjA0jQQW6D6c&G7b9!stYz84_2fS^?8bQCW~zMScc| zzDSfY2dQOSKjaULI!Y-CQ5?a?bgv@=;7pAY60I{s3LV^U$`$zzY4h~*?`?s#jJCA} zI3G_Z=;Yljtcq0#s_YN&sG!eMEq!W&wpE3uiW^-Na|8#p(7HsfSt?b8qZm@nv={9O zdBrIu!+R{838uwPL})4Ih-RwvaVye^q(M5}EoaC?@!Kab1XA*%S9DKm=~Vq73{ISp zn-8jpUQf%q5H5&^%zFgwzMm+08j~qrmD&~cKKo9NtNB2(XeqARUA6QCt7{*ivy6A7 zl;syDfHNv%rYl-!inS^C$rWl<0eC0~tGtozS_A#}-vl`zt0Tx3MX*0EFKWLwq=qS4 zOaC&?kU(lB?;kq-qbe#!CdP=gs*EgAWGmz?0SU%j(Z_&xFDS(S-mJ@s2gtRDLauV& zT7+xKhg9L|yZ2Xdxc|$Kk@3?_x0-AUS{J!6#P-5ZDV7!U# zas+P&RfcQaa*$6rWy+dQ=(sYZBlY#)F;Pim(w4w@%4s)IXk-6GlD10XWSjrPj|sKJ zNL_Hg&lkpE30iY>csFz-YxJn1d~|2UkGY-78xEbLN-#(HFJqDRNycj7i*^UhZ#)Td zoH(>7zXT*Yr!^SWg15GKaSHSO7gR!Iyul>JY8IGad(G4oQ?1XaPnb#v)fi%7UPx%1 z{=SBU#@|8Q#+LLq0{DFZaB}V-_M8PhH;Q%MM z^Lz)iaIRNQExoB3$P|FmGJj8701ZEO7WZ+k5$D<%;aTOa_Ped&4fAogRvF>c$NS_Y z$ndot?ue56jrcF-JHFAV`RW|84-8?j9x?=_+RvEqK})>ta5kub0HvZk368(vz>Spm zJ|dAn0B2b&tXbSMjHH$fAHNWi1-fENR}10jj4tUwOc%9Gm>EP-LjeVMuF;yjhMA6k zxzW3d%XYLl_9k+Tsv`^E#X9aDz;pa36hF6aR(w1Su zNMgyzF_qhw65&Rnf=II2id*@BcD8QzPhj12H*vUEbXvb)fg(lcrr>f{q=`qfmw=_* z^|NLiB`>gs=1|wx5K#?51~yI^nTeA8J)gkIMX&`L9|WZLLg;4b{7sJ5;EEp{8H0M_ zG#{YBdy5(G#!)kCwGpB8PE_G@Ys(c|ksIKDF>LR}c)V|<8d}GQIH^i^H0r-MoP)qN zwWh-ZY{*Amh2m|O!`^zcp#>#Eh4m_?=@fPb`+T#v2ys%gxN;XlIxz(FcN`9X!~Twg zf-NI^rqNnk#K0>8BnE&jh7DAA1UJK51Ds6ay!uXY1s`#1uKqaWY(v?gBDGX0p|t9j z$2GkNJ+)m>I zc)FA88AITxRSDS>>J9}yLn+qNFmt}SCZ@&HU$9F2YmFV{^z%+?=*FJ ze!jXSnpGcW7CYW_#2FkH`%yF`us?c8KXdSFD&5gIHrKdh-7R}M@rYg*|Fc>*M1=pT z*|^~)o=~L@y2qUlhqK8=DbIelletRu zvCjq`uq!PK?c7?mDb0JB2IV3YO_nnAiR?hje4N3i;F;b_3(AwRR33vDeJkeQ80j#( zv&KGpsQ{$T`(s{sCA30}mw%x@O~C8;9MXTdP(-^kPC&R5;Jx!!I^ zU|uC@2`oaY>l_jcdk z@BO@gWt?-KXAf(y^ zr&1V(ehb372}?qrlRk}`dMwo2gFoSb8v>_oXAKiotehQl-GIu@FJ$I9$MwPYeJ{#l zq2#b%JV%=qPAH}t*OyTHgPXgm3V5r3#s;qEXw4~fPKR;O#qV~5u~HZ)g?b#tq>SNd zmb_WQ#e$`iNPUe}J|($neJReW1m4T>_lk9+sbqwYzY3%11KwQ)cPaV2Z)_$afUi%Y zON)spvk0c5C}iHl+n+zJ_O?Sz1z3%${))^0rQ5|u2zj(7R2VnQt6l3^Vu3`_&$#NR z(`kSvimYCSbRyTU)E+9WWFH82GoM8baBN8 z+kg7|Idg&xc|EABuXaC`9GXm9ZkVYSNQ)Od8TU4*@RWKo$cyS{$o$6jNiyHj8*x7{ z*4%x4I0b-6X8Z0~8f$CsE~kx$b?hdpn3eFbluWAe zpsHLBxpEz^A`lZNoDHqs+>MX;WRJtQ`%eAf%Ym(bg&I~;%oNhvtk1(TYmIR=FJt8# z#!}>lA>pn@0hLbK6!C4PYe=JOxKFRCr_ z;X+@+ECftSLpnBm;}2O10Dw3F;Yl1cUzx0-RhxD}DnWSwh3UgQKFfHRoX9me*;L>Q z$v&|?Zg%#dcXl;+3o$F@u;i%eD2>U$?w714+w^?=%Gf(VJg90Y009iD8W#7ULIYr? zi5`2ht>{Eb#~(1irZK$a@&A^ksKUXxGk2s?4fitLgvcJZ61bhJ;XVkRADr^jwXl&| zxCcU30UmEtwCxJxDO6BYxA_jp4ZlL2Tyi31R~zUWk3oD&UHS$xJFe4Dr^`OWV>r7Bu4GNHvd!73C|i z(>=@QjM7%}*R&I-R$rJ?QTav-|1-`74MNvJ3(-Xd1qaIAv8Gc{_o6}-4x6b=E54r7 zvQgbEX*r};l(;EIQusyuS^{@Q2?HoU9fhQBl)l5&La3|~c~vjm{Jot=9b1g^Gc=^w z1av|+epVAQvZh}T20 zs)k>``k6av{cfCDEtr2t|?;Q4gpi zv{viYG)6O3Ww`MPB3Zhj=E2Io`l6v6sr0obk3vhr{g+5FSk@9@N9Ne>L}8k0@>EQy zWV504LDQv8T8lPd6vFQ*z-v6?AMU>)bRNwQfg!$j@bXf>;QK#wBv6eIa@a|%FXv9R zmn2wlmDq&T_WU3cXz}+^e3iF!e8c6adOzqzlFNeNd+K@8>kCBAN$O78kZCiJIz17T zuuW{Qgo+wD8R+)=&YGV(J-P9bp-52aje#cC2r63?&b9%dD}K)Ly!P!rcjkh-0aOmj zXJH*+(91XdMPfc6Mh_mgBDwM5Pb(<&NF`7t{;8FyTO}nBBC7%Q=JSe^xpGWuKBxN| zTq@1VUQVSQoPUCas;CkVthVCu$&HW6q7(aU6UIYBw1G3tpGnQCk#jJaTGOGVt4gdy zWy$Zo;ji9m;K~(H>93l13hu$}%VXy$>B0R4_^?j7i1M_Ub-7JH)QE|=7(psSP}#=L zt8@`JazIVVr(l!_qNNoanW}iqid_~Sp@e;ITzx*WmlDoY698>Z#jrrG%fqbe+aaQ6 zK7?Fa7Y6!C4hTGVMqS{eqz_hO9Vj#GA4VAl4oTA|=!7WXCf36507?%~%t?`CWkgCs zL?#Pq8{q7I_#G({DvKv9aUgc;Z{#wd;`fr7&ikw9ox3V!fxNJ;Tn$fqKlBBgr?n>( zh7U0jxuaRb*Q{w1vT2QpnTyJ-``y+E@--2^qMd`nKSOtW&zs38W8bOA<((E(`8`|} zxhMsRYPJQGbge=_Y*SS#$2AIciu~wv5ITAH3)fo&rg+w!``bg_YAAcC%={Yef27`R z05;{SnnoqZu)mZH{{wMn0nZ?;gEQdJp(EZO=-y=~v?eA{!{@R|-n2i*Gh{YdW^bQjhc5FvD0v~pLW;+nKc+(PB(4QT$g%Cd+rZJ4D!qAR1MbzOaqJ4 zyr^`Qeq-^^{uv!l6A4{tE`LPeumL)8Qv`N}V@9EeuEFadvnbf`+OP`$KXH!Lh)}sSlR_ph5{CA3G z#M1{G=ACHz NtqvBe++sxwX#c4W+DWm*@#2SfNiAQnbP&-a$Zs3rDkbuR}U)xNS zGzFw#>OO)Xhh{X-MFa0T%fgM>sa()t(W#aBizhE7f!8}HVw>o%-?RPZi*3AlPnVsz zk(@~5L(e6C4nhroXV_FfQFU&9nEUxzT_5}W%(dP6X;S<_2V^IGwgP$qu7gp(eSaZ-LeA)dZ4i+MTx_(-D&Jxz@gtPC$C-^N>o#)A zh2DU*?atSJZzw>2bJzFEJpB-&cg$4* zL06vAb144CdpRbfu5kO(J3Te(J9(ZyX+GJVBt9%ft2%R$TkyUL-D0F(19oioD4Vpf>02&kn(4v zS1_@O@d^z_Hjc^@e#&FP4qZ;2ew0bSyi}J}iS@%qJDa1*>W)SgvnxLEh#%aOWjGH` zYj{|@6G%-P>PGUaS*_R6Fu2h$g$#siM$_GH*A`ihxHt~%Mld*1t&4L-rLjU&;YK+r z@c&cASW@bbI#p<%MXtm>z<0W_>?dwi+mi$z@?ue1-Mb#wZ4vhXuGccPfQ?nY)82ezHjT`^ejQg!H@~f01^_A@K9GNB13q* zIMWLas8di5^%IeXWL+Ii2~#?fADeHr$|sH?v|f&|v&yes6vVf>ECj*PEH7qOBJK$H zQAwblq`m!nJUQsF!E8^)-#+U3m{hy*G=Px^zZg*x#p0$nWLnGEgX2~H-~^1&o*)<6 zpe?^#A)*CbXgFm({m%~&ciDOA4K$i}TGRV^;k(B?1f!{F-B$WEVlCJd(27CdPj2b6 zqe!AQU%t4~0S!qW6`jy`3Fai{uySfWvN(Dz1<;gcb3+7^(p)sbKM+1ZcLHl7+x3dy z+wR`p%&tz_kwnPwUddsR{n&?Kj zQybj|#jSZ`dC0~!PVI}cgUD5t&9Ko0w2bfa5!2$A|E@fe5?Wch+%L4cbh&rv<4t)X zk1Ml9k9SlM`St&q>h783t6iB-Mj25{DlN78L|tis?wyDm@~su|LCGMid|qE!&Lf*1 zaf>!$UZCL|?H96ie*S)Tl~9{Oh)wBSVlRncuy#^CfFilf%OJ>$u! zbr*qyx*+~&(A`YmJLjUl4_4RqS%oemnPV0CM$uLE6yh|e;`!F85sjhjGN-4AMZY(z z{2A25@0ajiIy1Gqp3;q++N3f=0l8b?P@SyylIj?>#0x7Y+%Scm00xP!=NJwD&07tU z5Lu|(FkGWrf?b!>W zBbKOZeK?!{%Z2;=rKZgAvZg%A6Qj=w6 zRhLlqVLQUI%%PdaC+ff|iU%1jtnve;1DSf5;v@@&++#4`E(qI12N0!^g7QIrA{u_` zkB1cYxCCyMgvm{&QeC6o$EFXH{>!4%u#|LVj6}%6Cz424>`)rlBeX`6j0;a%X=rb} zF`}m%`WFUpDBq}WtI0OOld0dJ+9tUCfjg;Iwb7hl$`Jj+R1#rY0;20w;7sC`|BM||hMp`Akh=n85?>-aB80rD6jtNH20Gv7#U&c9_ zgy^Eajq4Iukg1D(r5=q$Ku$$-7%lg7QXiwV)0Ri#e|qVE{<0*bpsLn_skw0j(K+OG z<}uZ`7N)kiydgDd6R5_{h|T8jE^s9`KxPI`YThe*?#kBE>Yqh&U7iEuk*E?-YKq+> z?LR*Rb*$&Pjuk9(m>yn^ew%mQA%;%5*K$45$DqYvmm^FO|V2nq@p&+^tcif@y*^3%q zBZ@6;N8eVpHAx6OmBtt9PSq^;POmL+4XMfY4z13PFUWh68ag5UdFSe9{(^n;ikIz9 zUAag`?5tTj=-9P3wTGJ)+oF*1d#n5w+z6X5lN_}~xAzBM+FT#Xh;mh*dVl!E>L-VjUE^NQ5(R~U zfV}?T%blvq79K22uMRJ6T~#{nVrr;adiAWrRYkQ`v+nk*Ez1h|XU!Ges?e5S9M!p& z#0OVys;$ylhkjjqBEMm2Xm#zKVYBjIy7Jb9HybuN)F$si-_1wwtiJV4toxm!mRsr% zz@%3;3iaK1YTBws;KrWo+8SO}k6ujz=5=cyANA;uuHXOZx_ITORZT#&cl@LN`VU*Q zuDR4b=UmIyASQgr%!xnf9WZb8*O|M5@Cn*mKeb%&%{PNTfzPmb)#*lUt!&WjF6fUn zIP@)AAG4v(hdp}r4k#H~a&vh8VX}SSj2!SQwFK?Z`^)-C^_t{1Z%fwS_{(e3`%a_hUU=;^JqOFpkqME@x18w2EE<{+(ONxz9s7yP~!AueQ;3O^!cj(_8kK}%-U8Z z1WXqv__ZdJU%v9zF7fIMVoCU{Y;!_P14 zXMPrwpeLsAE_qH1`#3?C;yEs}5_xqA5U?s!NxzayrjhxRk zYMW*;AYgQW=nvm~tpsy74|hBKWk0Mbx2gJOR@c%c)5IJ4yDhMR}CW_&qvR9r&6CN-n5v@7})Wqg^_dO-O`*9rUy!B72qL^Lf8a2>;M zfAWXB;h+lq&OCCWSua5~5s{w5e3aa5@#i1s)1FVzkQi!5)vyVnPJlWS)21V6xJ>kI zI*+EleE*Bcx_^!`liO)wmRfRi(Q8e>zvq02Cfs?)rrBck{Nrb0pUv8)bsZpV|H{FV zoj|`lhKoR7E=`#^KQjgEd9;nUW*J^-?FjwgtB}OvUKyKu77HY0@xenE^DZ5Xc6m4L zGSQ?8k%y;9hh%x5>n&KiwST9hFi9MRM0pfQxacU*mwUB8{AD`LtHabc+oqkpc{ru& zyw75iY_htVfkKGJniL{`(_g;pcji{e?EJ$&{8@=Uz_LYjKuN>tH(Tw)nVLblF3~ZV z-BUiYJWg(dEzYcVpoG}wau3=* zi^chedp-^hYuzrOWOvEUYo*nxXvmx1q=kVd;7ue)P$SC$quxn(P!Lb^wW~8nLc6l4 zIgI4mM8dr*2XkZJSa~EK4<5J2YZ~qP1NfXop$ZB~5@tA#>0p03h`aw5BJ@)Hmw!{TbR7PMv7sG2U_nq371Y?`Av7re=!9YqUsR!zOyCZ;vU zA>RDl)|as^^DiZ7==udXtDPy5z9(9%ZyHOc`aMx402h$rJ}PJXTp8 zSdW`NeTnon@?>bM3+DgDApwnmfrsJTH|dr6*V3!YkEEp6L~d>B9rcH3WvoAsPVI^2 zp?CdW`QUvepGW^jvu)Y$4vOx-&Ma@$$jQsuMCe7P2%l9Kn?;OHA|Q9V>_m0RMpyI{ z!IAwj?1!&UyhadCJ_pou?F zG)!OTGkw{n-WWuJu4}1md2;rrFy=_O_PQO%vV1>Ss>0AkHzg{2$;r^U&H$Z>&4Ghqt{n*qq266iWc? zvX4Zxt<~t;)~6;?OjtR$j9wPujhW4tY}MElhC8%2(^jSpS7rpm`;WE+Br(yg7(|C8 zDidadtp2^{d%3%fo}UjsHou*wAEm>-IDY@* z#$@O**ED%-tEOOsJ+j|8prL$w#vuC@RBRvDAhVidv%vSy;HaJ~#6@zd48Omwq95yq8qrS^XQRdDPTMpio9 z@Djml4i4ATW#_Z|d|P%r0yry^V83PX%TQ0D>a!zrHUL#))}n0LRd9X z6sw%S{nRPupciU|<{jVUJuQjZ5GdtF1;M@(yv!?PieTYWkdXzlG8fQ@KgNdLgzKkj( zz0gVDUNWR=9Zm6M{xb1-c;}JNuP2Hvm^R3bbhmm^itWPbV9wF{p-~&ePj;j6Mlae z1n2*yhR;V2qMNZ|0VN7L-W2O)I`=e91DUg>JeS2#&pKAn+-2SVfsh#cJ@)UtG+ci145G z7s}atY6&KX?`f|KRG927kvSq3uJS{;)G%3- zV0AthIBifoog5>wn8r_XDXpwOY3dR9y|LhxGKi@&Ulc9^m`KB%tovuYwZMs*qSg8O z3t5?{0f~|F<+vOWJUL@5Mxy+(5<%zR|aDuKo2<_h8D3 zE5Tefn@#unC>D=h2E&RZL=+@kp-88|CxP0F+>d_(s8}vLajkkDv?^a(0mX@>B7h8e zbSNk(-~RLd#*__E2nE>yYcfkx5vqiON^g|gi@GrOTure^^4xi`GRh41SaQ0!q}E_pj? zqC{y+CLOuroPm;+5kDd!Le-|Ivbpic*N>feI?x*Prer(hgUmbK;j+(%4B%Brw{{jH zBrOOaj%>Py8rw2Gw}i#SJxzJragYy+SE`k5@ziB|`;MVsubk*cj9QdeO=nc~Mtb1N zoL$eI(%N`Co4?&_8!>CDq*j!4U9l<2VcWID18bir)xL(ZIP;-DCO2=9K!4> zcYH#5kq@;MJ<&&D+>)8sv!g(uMf5KkU`A=*=&=1>$>Q&lSSzUSinPWF+1JsVw>bM} zVPZtu7a^&4(JD3%pD3oBxy1yB1jPg62kz4TfWM~wy0rY69CeBEf1N9>go{p$(!{}q zF2AUZGGAenCPt+cQ_*g(yXcF%5xjFJJ+ncM#+5dG{j{1?1}4Z?GlBf9#X$oeg<3F- zvA9sLQD~lX4^aw8bgyiNC{_c*FS?Z*+14gdF?F4F?qO>^qi|dW9dmJ$S6Zj?H@{CF zqhLLh>d64w&fgHs(03^HP*jt-<;^TWo9C-E99v*DDQUJK9;dO*vJta6BGiN7 z`i%xVSD384AS=tU9rR3$bUnG!n`%DZt70A^id6^-#>adYEXo%Em=~qlVh*UFlcNdy zM%!eKA)mbZ6^_vW_6&>OW~4Lbx~$A-4a%vbKx?O z;MBDa)C&^xI{DxnLJ1vqLm3#)m@jJ$V-QDfjF8yHmXx+|IrTmj!v*kpRUMNG?#LkC zjsmW#x4;a~Or?zpO1@OSi^F4TX&0FR;+iCEuSDWf{J*of>>SW}B`;tTT5|H}@s&r> z0{H>0SQGLaf=hT>?m(WREGAS6QC_g%`rT2$wzAP=Tak1U6XP1Oo>U`tw_2Fd4h#J> zGp@U?jM)`o)K*ZibWP*VJxH#R??}n{;%r1H*m3ix0#C`SwdEJZhv%-WI2{C?P=t9V zRUv*Y?{ScvYsD>*0a(1)+w_@6ZH|dUFmX9*a6~~X;-dom@Tr{F<}ZIQ&318_;#yHB zjMS7;98&5i32=>HES(Ol4=QQ&!_=QAbht4gq()y>7W03a6Y7@gypiEX1qa|n-DGB0 z9k|g;#Ma6{sBp+o2Eb98*<*171*?O=T*|kHZJ(h{yIMYqV`)cPTPZkI;XA^~aHC}H zEt`AATMYZ18~H<>iR+(B0-rgsZYGv@2y-X$SHQz9qFE46-WcV&t)yb5Q*U}B)Zf+$wplC+9E-# ziN#W!cg25QU@q?6r|tXgXldizWw^(d08gV!ZTZ>}NoWs8m2E(6eDL+hM*dxmK$eQa z=djBPJ*p~S!b|?R*D_kSydKe1Am_FF$b_0tsiCd=zHmW|dcv;r+ml1+ZbNs<(UDe5 zDey%z*iK+@*9W)gEKtRpLeQ#)+X$%X28mDC<)QP)YA< z!Ii*bxT6XkK)_B3ZOIZmLLx+@svr`9=~Rg35{M?$>iNW#1p(F<1Ja{1(h#Fz*(F93 zBhq8EB4qIDo@q2ynrlLLc7!=L84i0^=g;W1iK0er@VeJ_%4c&m)BeBSM)B8$0!H|q)08%K3DT}pQJZ$;g`As zI2FA)SGk_7=vq?%yRVoveRLS1diG(9Hu3SZ)W?YkyeYs_IV=c-vSv~D7^M~5MwFGR zQITx+tX(}{MEMu_@_ z-zN5EQlJ*1Shm_D+vuDlqaZZwvo}kit6w?TZ*fmDw2!*udIqL0?k5DDb<9Yqy5a-P zJUf>V(?qu|ryeTcvh%-|Ei^|efIVdDtI{>e&GGbuaZZ8cufEAyBy>op+9vc3XnRKn z*kFt!zIe3Odb^6W=zfN6L`p4-iNP`oT&OIT0#+mnFkW*NM5Zwjpiz(^^AA6+)tP~N z)i}}sL;kBE=y#Sxgy3rRTja_@pQCxaZE;IF@q5CNV;WW#-EjxqULuVm`R-*-`g}Vo zi+Nep;IVHmGoJrw?nyF&bQoWLpj#=dlhpUnnLV!`y5=uC7g2ug6`68V!=UBgt^||4a$5z?x(r_y6izdm zJ4LAiQf7aaS%0ZtJ7?^#qX&g@o_lQ18`xR|TmvpRdf@)s5$hQLeQ2T10xy;hvwj0hT9BMho zL@-L6W6i_$_kHkm>ff=#`4BB^Cm^#d4#mWs#tpUA>lc{6{BjJ$6B_Gs@ZbPYpvWGS zN>1aJlK^u+>;oIscGmly8xC7wPHnMe`jgrzFNbp{nb+y^tJG8Eg>DkPz}!1Erwodk zjZ;z;0<;P1tj;>!LD;TG-5*L!QDAA>=MzImZ4I@1R9sw)2bar)4?>jX3Lw2l%wM=K z2tZm1aMDljtr5;i9)lb)SEVtM%91y-E-CpjkwzuQo6Q|;Oen3Os=xGefWW-xn@q83 z1b?^@+O@abgb8Q@onRI}WBX(`S#2N|gbm6PYFB2Y-;fecHvvr9&6af^0^W{AG&1lxY7xqpzGhCeQ=>-4ZxgBU^D~I zUBKhNa$pV$RaJbV5i5?qK@J9TsHRM%Q~IdFqj%t7aM|N}ROY{)XNHC?HQ$q6MEXTu zGJ|g8_SB2eb_1mws*RPqxU<>EiB~k91GT;egv{*`H)Ff!*Ol@opDvC@$oYVE?xVYr ztz}5A(0430|9Qu@o&&G_`;?vLQfKK?zaSJd6N|VSlj977z-5btU>L==%6!zn=g^JC zd?$u4-pel=eb9azxK1ycl?F$noJGCSdS%>DZWHGmt+a?yFRkhtbVIJoL7sIrKqv0T zaxo%#=|)*o^%8^vy9>O%2&O*wK-isMY=Jurh%N0U#w<>zc_SXJ6WEf41#D~9HC-Mg zI_?dG<~y&&e_%ADRqhnDaZQC_`cuLIhtTaNf9f?( zW4yNYQ1Z$3MO4KsJT-DqAbiqQ(MlL73rSDx%;6)h!M<^4N7apCX?-CIHLccrJc=^g z!jZTlhk2V*WZaN-{!@isQ?1Mp6z0lVUm~tf2C;^%17_`{qH&USMY8$=f6n}KT1{JP zN*%7CS}2hy_vV;ru}~%%v)WMkmsyv?g?8i_;s#ral?5Rc6$wfOgq8=ZL(e5&L>$X~ z_cmZoS(nRoA^xumT_dg}=zsBfvqk3d`x4P?oH#fGVo(K<6(?fmzNU%~v4 z{ql_bBiH52zTY21^_M`#RIW*SG%085m@nN2aXg)vU;m_l1T0}HK@vI@#0Bt|dbs&m zmMbEr%vc~a{d@n0*kc_^Q=(vBxuf4ox-ciNUiRUz8pmF`=HLdZlx^1BcBtlibEAon z21W#9jmk}mSZ0m7q1?9MjaDLvlo7^Ni(;2EwIde4e`5Ev6T4zp9%**3Q^LZI@9nKj z{L#0=z<-1WR5dyAR(|J~d^#i_YI^g%IV+F4ulLnCX4vI7NPoKh=kZ4z6WhPn@rh?M zG@sm?U8H_6w0u(Eiacn^yA3)=4t0F!;2crn0U5a4AbE#Zm)PU|GfwQV@N_;CVN+#+ zBkFqc$39j6d@FbmGAvC!(GBRT&tj{oMJ>I?Mz0Nt`oOH9(qYFRx^s1YH7MiHrZeB` zxYzGMq?rXO#xB;<31EAzwlOh}vPla~E%g#A|W zcQN$UH*R&@<{G%tYHHt|VYxob+&jiBj&3u!ydxk8Mm@`?$YIC72I*J8e(|cieLjn@ z_qgipvSrMmDwQiO3p@rQ2*#=$z7luV*cxSP!`I~rsX1Z58+eVIe(>d7sBsq+ZDDlmt z_L;Ob7y)>&Y24$F@cg|qn$|cD-rO;G5X!3SY(mC9hXrBdM$X#lA3bH1Sz_$W%%;cZ zmM-Y=w9E%9KYSgwt^57Z<=LLe=zkt&Q#BteP?0?54sZ3oaQ^$Wlz_=@b%ldhINhsR z|BO#ZX`dfrHn_aNYU;+lzFoxJ^z-HyFe^6x^%*T=nEK}PYk!@W^0n2}4=;}UE4CB* zx7<%o#D2Z^Wb%_y^m12^glxybj^HxWZ+noZ+j8exwj zexaq^C8YmykI9$LIS+?$nT0Gr+jORTx;j12dl>H%Un%>S6bZL8o72Q&;}bLE7u(`Y z8P6K4y8hf+dy_4~m`H8k^JWpLK5$QId@fs^{wnN@DCau?x%-19e#= zWI&4O)S~vEZ^xw;a2%&bdtMnTV#nveLkTW8iy26Om><- zR>RZmVK9AgAiGNJ^VGy8&}N%rEXF5Jb&p?n*8!S?^p9iW;b*$kyltm_o^1cwb>6*; zJ|B%tcMFW~1lh<>?)+)(ArF)j-5We^gZ)99(_#SlB<9XR>c;5gu`Bx*NYnE+`SSfm z4mt?h`q0jF{40ny%q9jZ^A}}U^nI^C7e*U?ee|FQ4mgaD{JrF`q*}}x-H60>IE0^m z(9AXlEDzAI9TWRJ@pSt{SaVt=bq++c*}YS>tbD=~$U%`3$+xnHGDhi)U!U7CMZrQjd8IiqBpr4P#J@i>gd4 zmL|4WW__n%uNlrD%Qv_*=>+kE@~1D$Bej$ZwbZ}klm6x}hg7nFozA?UBhC@}WMSE6 zy2p=jVkNLEUtK0riLR?jC03t{ANU^B!S&(I{K@v(jkTmfdAn_aPTagUTRE;`Jw7p? zme~H)OKg%=D>)!(8x1ST(C$w#Y4@=jGt3WaW?kdYFabt#lN8mz{O{?q>oxlsv!hK4 zeVL^OEzCnb-bqDQyBaBg{Q)EDJnmWdSa~RF=gu*lJd3!W*zxO4Y_Q``orSsu_jbcf z=g=>o4SzB@DD_TVjh(Mw%D933^?Pnway8!;3oije4*&$s{z;>$9E!bWC+g+E9%;^X z?ICL?w!gF&s(q^aQYS(yb^olWje}!cPYxoT{ozHOFjHWa6!^yWNq;h1?j4^9<(^_T zHgDimI@LPHJ?(gBYv%MUY%r~|>;tg)+!H-SmA3x`0uY#Va}nD|WW3O!tOau&{Xa-(mAMN;Ky@ogU_# z@$$=6oonWk-aNg2vH6MH#p8c3XaKD<&P_bJtyg{k}EZesC+_d$FAsgzYJ;%BlT+DF6G)?Y`&&ijT|=V$da!V?ITp z8$It5p4|$(>G+59@PEC8uJMFsaKOZQ>$foMn{&?Q?pM>}hJ2BHv44horv2_Tu-WDx z%}XQSQS84TxM+*bYAN+^%g?W&XXz2EsQ?0Q!mvYR_H?VxDg14qN21kKn4nMQ(1OA) zzP!2{+JuGD+NioCPFF4fh){v=JO(ui8-m)}?00|O=5P5*)iX12q}*-rcz#8nm_s&c z2BY|EXaOz9mD|sTCO>cx@A<}Nb&tCT_VtG(R$HoD{aeFF7-3EK4MM4jC4m0O8Vm4G zXg@2CjNM;Dd$SjSRr?5_lXjrI4GA?Kr7Y(VG9eEw8xAf94i1XxD-XVZ5U-l$`X^>H z$V`FNp!a9T#yP1rz*SgPbP&^kQ%K<@pd?!Xr|qp1T|E*P3UzyG-$mYg_enlM5H`gq zH9Poba$g#=(0O#u?pI=`NhQIs5*}N|_`M?eGdfcF*yla{zxBt!1gwV5Nk>&Q7P5#)5r|31h1H-QOwf4teb*0N7>&eK zQSAr5HcRb_Te7bczW^W<&PWHqdIb$g#g`7+E7}3Dd0i-hv{!DFdjPo^_g2?WpoQs3 zUhi~$U|@$sez6G*>ptx-Q3jSR_WOBht5UudGWyCZ`!4|~rE8=OQa#Oi3OotG{Odj; z5RkRm^1vnSeq7BCK(hsj&kG4+jEz>nHR&82o^dC^X1{=}cps~?J|)flA3LYr&hvkr zc4C6thgR|4WR63tKR$M5U-RBKCS~Y$f8mQ&d|JP8u=n7a=J5Z555T*zI%KmteX74% zVX$R&m!B*`@Vwjo&)6vd@aEEV56B|$+|cqK_toK;EnjFEGb@#m0^Ejc9^}a^ik?1- zJ|LVoMAx9e{*uo>GuN$iR-RVm08ew%h&v7yBR`By$dl5K$(b#Wy#qJL`;jj7D+3KL z|Gr@8?1cnC6}Uf@ac1%ur#0j--cK=hj;BW0hZGYKBj|%Aj~TXZ9&!uMbU*d69b!+v z`l=6E@0)Y;X>C>S>v|fz^P#Pr&C$dAjL&+-Glf3+c^e_A(2df^RFTm*x2=ppb=g%5 z^j?!OuKO(1`qx{1z)r$_rz1q@_uN$y+nVmN zD)17ji2SL;J2YOII1^*|aZ*ERkcseVn+Y9=JqquL7Tq1IH@q**e5~+nLN}{Q{S)(t z6XwGG6OoYR{WGBINWJc`xLQdNUwsk~ANf=}!%)8OaWxEn`7HL!{ex)6)om;= z8LE(#S-IP~DZ{=4ay?DcYr)f~H`a30_3Brl&*cDy0Fj+0%c%mwCTyVCJnmA=O&=Wp zk6~~Sobd_9h+6oyszCGEc0Jwn_&?f_K4^9_1_6bjm>Qw|wVE`K z5rt}(Jz&VRX8Fdx&p3{-{#-5$Yaj|qND3n1SC5Xc|1H#e;G}6d8_P*oF>_%x>9Kln z^WRQ#LOMb0uf1 zwx-fR&Skg;=OXPK9%{tE#lj8p2R*Ys=8yX7rS=zwjHGke9G53uPcnUhSmQ!TrYI4*t0r~D6feAi?UbjJxgUf*newITWJ{Rrd zf$y4thd>;1=i&B;b?cg^n2j9O(*JeL?`+eWb%-}GIwC7TI0vfXX0!M|pNn;*u#`PQ zVg6xoo6({f4h>7xju|M7LV{3mVlX?{;8UvENwc8Gc5l}HiX;sB?9RN6o@Jj6l?YIi96 znld)}MvQoctL^<9LqlfGg41&59H^y+KSTa0f-3FC<8gm!okLALIE(GfC+6hE=$FH! zm}8k#KS??RpT_`C%nwFOJQ|y|LjC-G`@Qm5I`du^R+@C~+5Ke)JJu4y1CY z4GA?NY5V~9(5mY7McemBN&T)gDQK{2$2hl_9(Mi3oVro{JrqOg2W}rJw}hoxDxYP#&FOzB+?a{Ar)Z*>VDvq*c357 z=QF1qGtTd@KBRGG<(`+>NgYrd>96VeOw5N_>`AXt{qWYnra%U$wm_imrdwo(0o$ew2UWu~V0c=wA+D5C9)m4$oDx^CI{naUYB?f;%jbu^$B~wT27@`n(k;S12)Q&`Ny@PB904m<+BEWB z@@$9ojQsIKIgqXW{tVCU)-yiHuup9IUUlQAsfk!%sJLTI!;?^!1 zj#V4?rn@0=6a1_>c5!d^&yE=-8^i=lZbWu@8`WUVj6b;SGh`$z6XAx34zz+il@0c3 zHr*TAI@Fy>Ew0TNEC?+$#Bk`}nD#>Z`wqvOwshaRZWtn4S#htdZe_OIYH9f^^pFH<*OSIc(Ly1>i=$f%ZguDai-gI&pN%Vt-5XvnUBd^6hZykqJ>KOo ze6o__Df7dQ-7XI1CuJmZL^WXWN6iId^>w`6z-@nEJjMsP27N$EU*v6E65Xw)_CNj5 z5_~UEIa95sS~;Di4I|ykPCH4enDfDnaB|>J-fD1a>f9XV@X(yY`5hPqIJ?wW%)f`k z<*OE!knM}(oRqES#TfUt;o%XR_M*iw*p`5t4}`#XY93KSTBe@Z;Du;4Z_WD~n)#;q z1hRXV1&($QJL#+LS*#G;{_^C|e@TfbdjPEOfV+e(-@DP|APNe9*?j#*=~$=);8yZ_ zk9)ew)hjvn%& z5ig8B+H|7|fbg1q;q!Sa3!|sN%B{0$l+REuUK|sMv~o;lc|pbpfZ3*mABWuSMa!j$ zX3&)tMLskD*FYyY!%iL)u;v}706uFoKD<7<<$z32ClqUs5k`E;p3}gE+3y-F2mX8Y zMrT+Zeo*PapM($&^pL}PXHc&Lsn#uj@t@xV89D8^Sfb}-Od^3+{!Y0qDW4C(eBiRi zX0={VLncQ^@tRd zx7(6u;I5(t$6Y_NXUU1#tVd0~eE$WAc^3pEv*I8;!-|*s4nE8bUx2|)=pz1MaP?>48mlKQ!tcN(O>?p@RUEseWEu~q*v;Qt$zZ<=J3z!$*8oS z3K>U2C^->_5hSyz1kNxC$IoI2!4Xt1o2R7$IdC`jI^%t)mS=VYMwfB!sF;pXL#(`gQ4HrW^zslvzHC73Y?^2-a zaZYx}+751U1noAhL$YMAXXLP&SL`0APP%cubS*_>Mh_~0KjBq=W9i$7FAc@vb4=_{ z`Daf~OcPSd75>C!p9swlkn&7nU~RQHdKv{fqRu%|{Q+Q|GbcJkfUMgZ+KmTItennp zB6e%GEe>UoLnbAAeatEM9b&%3^YLPiTpjWJ@?oC82+3|LczAki3-aG64J_k!6s57t zTqogvN9EmlvvyLHF#C<0DTKBVuxk(zc{e_{CiJ|R;x&oy;`ekZn%i(?*gLi|vp7nTC8$3@4;+A4#CU;iluQLoS$p^NaC#O}7&4Lef~>l%57B2l z+liB9%S=WgHC&?}Qm+wNHop%N~oxb7iB~l(?!u{J}QBlc}Iiv)2lyak# zV7+=J@#T4TTrK1ix_tVAt@EDt=trqr5klHYAOQKq6LT`y!NwM?{rsifN|{0W5d>L2 zKloS|*I0^RAQ?)fwrF^MKtEolaw^uj*?o~dApHVC!xX34#e!)*wC4HR^yOpLGv<`dyAo z`k(|Q#CDybkeO25rAFS}W!&nox%r|FM_4#Eq*ylO3PpLrMUitO0YlIVY61pMs5M1= z;o?(Kfbw2a3gvG^lyIcZ@U>XR5US{!GpN_jylq@z6|_0E8xra2<7G&9iurwS>@LU3 z@Swri)bB2xJ5(sD^crTS?k7u(?1POGlB0}PYItgYgscz^I3E7UJKN z_5fva2%79KfU=YG`hrU7MEED8bgl*93SLY*!?lkz;T&18IC?b?NwFa^wfJAgq?e%o zuw^)THJmV25+$NaG9U8Rq^?y_ws9}ocd(*Y@vMKm*4)cXCXk#mp^%9tZ6ghZ~&cxB{*;Yn%XhMOWyoX4QrVv0)D zOV`F^mB(D|17IM|6P0|^9fQ z{I}4&j<dJrOI1$FBxXpmX=fZ9azy&rgca*}0 z>1zE7X9{nVY?90(jEU?Sy1DFW%YwO_Zlw;hBXqXIXKa1uNXI1&58 z4HKoWT}#(lPzb%Gu+=5y>{%%3O2^*RvCq zhsAS>X6~Gdku7(V`D!@PgG{T`^@&o^7?}X&&xQvQA^gYQUYzRPgCZ~r9xI_xMkSO` zO%GRBP)%>|o#kah-J4375u)4M-`x06njQ`qELo-dP-c`A-!e)Q9^kAq)nFjKtR?~| zUjY(6QwotDj>Rc1r^UHms#zSwrFSQALemnOPDqS`FqJf&TKu`S0SYK7k}VRK?+^k# z>J=ujr zIc9san@9N9M3m61;R{l|JaUN&5brug*9rGM)L&6Dx|m0Rx{j?}D;V^Cggp+ezJgm3 znybFxYjhQ^8{#RDrWLubFJ(WebJQ#^eU2!9v}rp88D+Hcw`G!aC>d$BvNenR#ZZ4) zO(a|!d8I(V%UaAs=QWS3pA=mzO{IQ_q9#cy15Q_ox@yXy%yf4?_U#d5!%^tXt`;L% zGn9CuvOrXu!T-ZqN72Iw0+=5n!+A!~3We z?&mq)UieKNPg0q-p=WDqxKiy1N5}w&UG5Q=#Aw>Y9*c_Zzx8y28XK>+-T0zKH3Ugi z&WhxrzCL+x>`YNcGx=>^YrD+Kr0FN>8Tif0Z0q>61L8Tqu3cz|=zrhjX{V;;o_^w; zWI|yZd(Bmi=Xj%D#Bh(50sXB7q62&psdCRTgxHJAYi^9D{4cIJGQYSN8~#meLd*?p z1(r1^!2~?yRAtI_y=yrqSG75n+c;iaRlK6Ph%QKw58F7y-1_$vCl87d+E4b}OMw8m z8H6CYnC8*iBbKCiJ~0O@1Dd8V+AJ>=Z@LPJeR6#eiUHQ?d;|O#vmJju>ZkP2`4CV^ z#GCe8E>bn8xWHn+aq1?x4fiP%b$pf=f`T;>^X%m%8mNR*I@I{s-cNEc_N5U_DWj@v z+sO0+*V;C@Z*JEZFIMjDTiDc#y83zg=l30D;Uh?o%XeDO__vPkNto?y)qY!OS#yow z{&?Jvlvum$bGe>bLf?y)xm(9%FtXa}d%vTs%S#FWcv;vbpY975f(I3pq(c;!f1Vy@JSLzl4kGo>&w+LOGT%NOSeLB7UUCKGJ^PcF^kx z0)FDq=%uaWwo;#ul%jZjE!_HZcc{e5pbm(_7~;i7C(rP@f?icxT&2jIx(<4bR~={a zm2oJ09{y*iR{NG9eiP`5_?a~W(zti2d{)s;A00s<=e6`CD(`^dK=$6*eCrf0i`P$A z)UJIrY#roRsZk?7^LWPfpDlf6+i3_QWtzKJzoP!6148BW3m}M2{-FaOYCu}g!z1!& ze6^xp8|SpYtnQI3N*OVX7M`WF0@^x?D!4`_tQl6czXxqDW?kNf5-^0qT`2}!V~o&( zpY1JZ;L7*2_zsn}ZWp5|?EaK5X^5IN6zvF^c#0^w>(lMsKcm{%SL4=EAXC5jbeZ5? zq{G@t5F-O<0vEPE^?sZ%G~MtexpzZcmO^6)&UeR*XY83GAejz$Yglo5DR8Lm;uozZhRH!ac~-KZMe|EUcW|4So#-I=VhzwY<) z77S+P_}Fk=5ld_Ld2P@NGwHq`2<$gsmfb#w>F5s2BCdhR>ND&cJc*=QvxghPakCc& zsot#n;(At@8y`HF>~!m2%`7TX=#Ink1Cx&2@CT%O54pJ#3K4&yHBOujzut3LscV(!e-XAG31{KRaD=R!@4YisJU zjzoOr!4M9cDN zEMnR*BKlQRd>==1)3hOozafN90W-sJmi|csq;U;0fj#v}FHBtC<%{b&zHA)os>H>X z^K&lAfZP#FW9%~*$=I3hbcfD`V<~Vvox~-&j<_xWKy$lHnF9waDX~KVAqBTce;V#C zZcWntSlzGZb%R~-ZfZr8(8Mp6h$xF;{2%VTtElWX zjuydmj&loqcC@bP5%VCI+nQn*Y_UZYDUG4N!5frhn@$*$7c;TlcMw~3WI z-9n#K!4EWLXT*AB+~{CJpidzWS;sU`#>mX{n8JSR_lm0C2%}cHo;1eRl0JucN6ypd-H!HzE26b z=kOMq&-(|RYT7Asf5C&~&S=>jnV5K82np8nWY}-n-=26tTd=;jX!x{vRc33^sdXrI zKl{HoUB}--tp^6avQ&5XI)cjmU0eePMee_F4=r8qg?=v@56+|JE0&-JX!m(R8hlY zwuRZ#VDzz17fs|~ilPNO;QcF+)IxDlMsYIr%fgy~bIKlvh#Ot2U80R8tEMq8ZNyK# z&W@l~R)&3sSbL{a`?g-Reyf!x@cejcce{C5hixHc)2TD~XWVEwC1B_eL1@z6DRRgU z54i2oTC?qzRi(Pn=hv)VL&}~noETU0_+V9GnQQH}(CSAyt|7G#^1cf`SabjJ4KLTK zn#AIX4pvcPG(bA z6hi3IU{u~-)@UbpJyS)ebnv+IX+3zzyQ!UK^nkPWA%T&txzX;&XvkEaw(PYv6W*@2 ztlbj#W}seF0un~j`Oia(U`MY$`IAQFHbL)4p~d>OpdNls_-ONYozgu168)K=4Rgic zcW0wbV$rZi-RCTh2Jm}?%cu6Z7t>{@#d`NDlzTfy<}DsGV4}~*m1X0&v*RHv>l~jE z-;A|HG{Cl5-}r&Yo`G1F+8GA*XNs-Cq9=%A=KeY$nvhXc3h zLaU0&Am}aUmTHPJvPwOc-DpNEab+4by4v8Ffo{6`=G3A^=45WaTc-sgY`Up-Y$c+P zp$U-}s=-LHqaD2oE6@#HAfc>u%gc<}AR$PR2@|;a0wp?zTvsblExUG9wL)mh564?4r^lOb=#e4za78o>9lr{l_uS zx|fSnnj^$XbPG;ZX!m+6L~G*kU|n%|`X9NQ`F{Gk4j(?%bW`Nv=15IYbZX7|in-?{ z*pb{=Ti(T;3Dyu#ihKa>1pj_lv~hcYL$0=DZPD)Vc@I5S9QU?P zPm-YQp`pnpvDxsx7}dwaMH)#{bsHEy`nW*$l*xNrapp@TD#1)!Dp6KY;KSLa|U8MQJOJD$C|Jwmjf!rc+YA8dxXvRiDX^;sep4m;b z%dNBBWM==TGea&pN0SGQ69bccY=Xkl`>eH8@c$_L|cf`sAXpBZ{7;wYdvO)BjLmgUAyPge4Nd z0-`s`bVqbak)fQIX9z@?*LK&b8V&)av_}vtVIl|pVqpJCn&d@boCP13Dh}q zGqnc2mY!vCi~Gmg4USxApd4t+U>3%2#d5gEB!K)AyL}>?*azvX`~N_si3Ne6FX9%! z75o$KQ4sa!y#M=S5u^ASqA_SWglxI1Pv3c(5BuP%A4=jtoo+ z`ey;n72W5lH0$eZ_ye8slgJ<*vNGUa&;!Q5|L3Zam$K&HOWkp(V6^n~&n${2cJA9{ zoLJvy&O3zk-0>eGKu`Z8!XP#k)dKmAm!etJ)%qpxTjj^X0d_t#De;}i9HUc^JcfJb1D_Eaec`_5jUPYB0qsnheD%rX zC^_q%6lB{ z#&f&p)e%W-*-9rALoblfDtfn~&0kJv!%nIkK|@7hy#>Ye(1Xl)oPn6rs-u6lv16g% zqFqeyUT2jIf_VRJNlky*0N(}3XRsAl54GmB8<{|5X<`j+8BV7OtU`z1P6XZ*niwV+ zc;UCR8*$u%O?0cZDp~sF9&Ih!nm`~J`!?PU1ttoL7z%eV?Z)&+6-;0vJ3uSE^k?Bz z@OG2PGB|4h#?=uVShWJnQk_FQ3ET++Pk_#1md_@eG_<(hRCURti58!!w#KVBpb2aT z1Lgsq16852*3LmyQFQ7xtO~*c)4piurnkTI!(sggY#}xW?f%MW3%!<<1!&`qW=+hg ze7H}8V5Gn1xjEv%F1W{;R2_~aSGXrq+4hPZlt)U9=)hg|= zmej$Tg2}iTuP}?Iy`0xCba};%NIDp{jMxaMU5B24B=LHv-Thk|`Im-3P5FA=StFXK zEJms0jKup3!csT~Q2Pq(&aJsq5ho)#&^uWQv3p_pbsu!p*3KJ|W&hV{Q(0&KpaW&a z0I7xhx>aqgq}7@|Q-*%^8?MZ~C%Sm6Q^#VlHcE~%R&7BbLRiw{;3i|XYQ+9$?KJ6a zNJe`_pnbvQa@sM2HJeCKFh#19@DyqHh-$%kFDcJ3UVQ*dZ!a)30OI!^aCM`H8xRWEgdLQ+7pp8tSK@O6nlc~#U=O~ z$zH%emij#zCC&oT52*MG1FUYmNZ7Qqqb4y)$dalyXAcFULHITpw-LEDjrU}CC#WQK zFA!`DbBe_$T=r?H54AphH9aXC zYvHQvvUBDTAXBF`y`QgX{CHjh$GJo}E2!!%>lX1tx&+!da-{1DsEIrp%M{TY@dJBk zk=z+Rb#{Y$yA{zefEYjJpxs7Rh!lQPhh1bCWZNy~x#gDwp3TTDU=qRqW4uOAJY>@1 zR&pZqx(gPAG@Dn-2N3>$L~JAmgzqPG{z1G|VjVS*H#5D5h)0qF(H?CfTn6^*MKFy- zGHMYqQyA!Ee;js*PE~LNBe%7;BspM4Z45n*7!63lpb?4d@-J`{tdzgaXeV@<1x(a8-s{)CenSP z&+TB#sHj*ZA^F9PNfUyP(r6uw=c}Q6hg9S?QIWXj9R)fQxdufpdLftcCJ8Cgo$8Rm z>X`10z#9pS%I!{}75Y9{m&)5PaM!34RqhmrSe_dxMn=&U{rHujW2*A>x+g|`^xqNb z|MF!M^Ymw(Z74ZJ=`N73L4p%4QP_+d1?d2%YL}W|cGJ&N>%q~p$>{sN&S4KCUsq6q zB!SnX1OhyHvu9nb4|=&Vjryj7$CU^r zOxD_#!(GuZD41gr{IIBdE7nOGtcPd2aNJ0;$`CggQ@&iT3ZrgL1XB!>hK(;fcf2^u zOMiZ4*ra~N2C6JjCJwE}oUV3JMS zw@57=Bl4ts-tg!xOCHK3!-$t|NtR8#crN-2x74S%oK-nU{%jX`ay zdRBB_#)FI8_338PIOBe#a9HSyP%E-d1ki+Yd=ad2TW9Uu4WuSKEbrQ%mw${>5Dp|m zM?&O|twd-o5~(yn?TH95lw_*n8hqIC-j|*E^Q`$nl6ljR~j2^^j2=Gi0f}+$!pfkaB@2^^AJD(v6VoeDJ(LPG;uo-FQX?3(i>6L8p zldYUAyxs&Mf);M%{35@3nju+_jXuQ>|H>cAz=(6Lh2;U6gO7DaP?0KA?l_$R2e9{o z&D(xPKqapIZVhLAW!V+3c|l&XH^Oy-+*=8jF&h?xvJVBOLB|eCOy;9mG|`nGQ-8p@ z(kqQ*>T?TnqT@vhD>>VW4NMl>Bh_ArH*Dqe<{dFJyu8RqFixNGTnKEw$!cbo2T0+n z-&ci*Jz}c;K;euakRmQ!<@?P5s>5u5O$;2A8k5&QzEW{xOf z2q?=aR5Ck_kBZEUHP)B%Y$&irs?{5}=7-nS>(cY2JpW{_qpB6<0xpt6ot66A*v6xc zjb2R}8+1t?FeW6R=pgC>h!eru?W4#JUk;g6|t zmppL7f$x+$EnFtXBr_EI#EW4}m_;vVMJ3(4(B*<~Oeq5~G`W0+NfirJ1`=sm?ez{D zEbsz;Cr%Kj_E_e0q_ZiFqWFXC#2LR<01-OXx)C{=Fv4?ZSO=o^UVj9-khxLGoG?eb z5`&^L4>DH!FU*GDrZ9fJWb2qaoiZ=dgd3h;v8AdPE)h?2^z`JdF@4Saq|7h022TTz%4T2+&ier!$tQ?GbkNJV~`Yjt&| zuBLy`!f|&qb@z7v89%f7)bR4^&|169KKIgVH>K!mN?j`x%HylYS7r4&=i0bxZS9TF zW3^YxLTg=X%Mz_`)t(HUT@_lbTXneahc&+Ur*;0S{`MVhty;7`X5$=r`bv*p{Q~B7 zYrl5bszxLJAL`ybEQ%|81I{Flfr+SyF$57qK+r@Hq*YLsD2b>nov4#&3=-nnaREg| zWa&gZ;EKB_vcyCs%osK9iqZ-y8byq4#06bI}DJD$ozAlY6z5AAFJ3QbwRYR!WURB-j!-qYjw7W{Aa@-9Et-!#p**w^MZ4d89SqK2EA+C+bV zGXMW)5|Lkv{Ab5hKr30pa zUxy+&!X!R&>G^5Gy}ZH>R(>tHqh zXYhhaaHs`mvTi~}_|z)}f=)Kplg|}btXG~}74P&OCL}$U{1Y~}^3dV8x_Hf~yzdtq zTJ(=Dyfw>h0kFrz?dXbhnsLJ}R?g0Nu;H_Dsk^zvp6>qcd7hdLgSmnyJZ}fIR5Inx z4{!E%T~gU69^aZ>3-=jw6~iU?_oeZ(cbr{5bv66kG<1%wmq|!J`f;tv9{Zac-J8|Y zbw`Web$&0Zy8oYoTxl@v)b)kp7COCcgTb%}11qB~zw0*RV(>SQnks3kr^V2&KzZxG zcf~T_>M{zI!rRah9~oitCbVZ+9(wBYk(KxVS#=SicCqH{ZzT;+#=dc}C>g+pNV^dm zTqitFa50dSviFO`i6F%)zs6TNgV-18P{l2OGq*<-ePWoTbxFagdjKn1-i@L8qY2ti4_Kw_iw$AK9q;Rr*cmxTYzN8 z{_>1T)Wzq#9Ze3mSUlgnf8V|%c-bKsr}*b3)6j_1I7khM z?^8jHFm<8#ftO{Rw?o9{_KZD?3r*dP^a<;=$-llt;i~P~d;RG@D3B1IJ}v!u$+Vf> z@C9cNx0+}g^U4YS=9B895aB}tj@irqcsM`q&?2jkY912?g;%=DhyO{Mo61K>5yqy4 z+A~KW=(q=$WB8EmrfTfZm0x3b^HXMw=aE#< zG)TiccFB5(_qowj+b!7;9)F)pN+{@6n3DAq=VJ6{TLxzJk$1@OJon{q1~0%HNBAt; zDqmr|sq(%BlyZtLGRXGq@}YE<(YJnhGmWiAXjp2!45jP!x7#~h^+a5Y$w?{vOhWsb zcyyzPk*iGAZrc51HxLa)CYIPp9chRdVlYt-KxEqZw8CeC$6mcG7F!{O(cs3CX+ojR z*6ZR!iCEknV|>moXSZjlNr--_RHrgKog%~SPhBr$Sd_NT2w`^0<4)8N{$0_bOA#fn z_e0*XiN1ROET)Hce?}qJICMC^7ZncoB%6LPZzuT)=Kslld;j{)YX^CdrEbnD->l|I z>ncoseoz|g#>2qw4YlYi6Y3>9Wn|s`vySV(7q9oC{}!6I%fF6x2n)@u@?wFJeacn8 z83%6ho4Jfrce5nIosNIZn?-omKv+^~I_!w*p- zO$rX=6Os`B5vSJ3#RX(Q{(FEKoXo0Qvk;5`+7o4#sKcgA(5 z4W$d7=5wJmHjaT))&ZX>Wk-k{VW%YTjJ{mP5Kp07_OFmUW`jY3elQ66k&lcU|Gw=` z+!k+$$m`jie~uSvgNcgO<}&tSTB^Fx%wylg#dpftc>asfx13ih4B9!;A8TX(J^^a} z9-%h!ABiU%U!%jM)nKccX&@)H9G^>eLohz;EGQ0RQrB` z30PPadpZRDLOiT0(oSCA7xmM_`yA2=*)7$l^|f0$5j!Pkd1LH&vyh-}Y-5on#RT z&wMybBO1?Dbsol_hR`e1<`2tB8hdMwz4 z3#tFMc%c#F@_~;q?J1;7z89wFu6QA#7zRP0!R&{^_6o+`m3>qdS;l*+1+s)&6^p|L zG&vxw|6u38@te3^7ZruFy_Z6FX?42JK5moJ>m1@0jb3JBF!%pl_D;fq!Iu=L11++D z=~&jF8R~BTF!aP2%<18+G8&V~sCl1BY?CWxS(j{W_v7L5z!hrGvTXCCphRn*_fu>N ztPbdmFHTr(ykQDj(#bkx_D0jF6bHqoMMK?Pi%bN;xh zHhVnI25mb?@M8Gw>kDLi85@Ujffes$Rt@}GgI5%K_@NQ{U%?Ty!5Cb3Hh(;_`)@!Jicww@5Q{c&m=9kt#vS` zw?=PbygT1MzZ5OQ8R|NW_feC4fdbB%cMhgy;09gQ>9>Edn-f4)`Wm3l&(VD zQ4npb+Yt9`TYRzN$J)nw2F%V{6AE6xKDE`wTCFyt{T&D9r1d}F)U~ZBXo0WNtnNf_yR9N>v@XC7qN;Q7;K2&?g=o*Uu1_9UPosoE1y$c>dCmS@91DZqz zYUz#7$K!*p{y_3*GtTYlm+`U5OI5| z1d(YhABt4!oiQ~XR%v^IxEHU!4jsod&nid14cF!?#%!R5)6{OJJFGQb@dcD?Q9sk$ z%6AlpQ%d2EXJj#T!#iwBMk;>8j&)VYvKQfN2AkUW!40g&&>6)&|0iqwFAb=DI}v0< zs}Z$cS%pkR-q_D#*_gsEWa#gQY_hXP!o>4D3-L>Ncyu{UMH~1)i)H1f8Vi&eTx-An zf3tg%O^YS3PI=tkj@}ubhwtRH4J3<`@I500StBd(`sUb@iRpC|VhEyDP>k7d;F5V~ ze7y$GI(#_g?jN->YhUeM7hU?Rk7rvTB)s$nlIL;dH&rw#iynC}UYLW|{3cCQ5qkyab2 z`A0$aKO2|PE_|aS*0NARPc$!~jI~k`kPv1vGX)cO6jB=V@R&eHYFM<5k5ri&g=-eP z?q!qXAj=oKVVZ5>F-sPw1efIzo8}2we5Vs0b()+0w@--1D>hLfk6W5e3(G|_6zZKn z3ki4wAgo)0bFarP(3Y_6!)1~mSKtG1M|tC*Wz&qd`@ezx%u>H>B-6V2O{tRQDGCAfp4tx zzj(!SHshJjRRwmVFdJrlXK~9t@U%E3o-cVmQe!lv8_$n3r7Yzg!iU)?jL;`9TI_1~ zUu1=LBB9rmbMzH8@&IQrt&}+J=PXe8;JF8k+K>ea-kuP1z3PuM`&*JHHz#iXjk>5{Vd2VSW;U+K#GL=Rp0T+;aa z^|VtjCtr7r#@jy^CgIg2PQwHC$!noc%@A`H%1~Sm-1JO+8jI9! z**#W^*P;EUdRTiR2_GJz)0S9kd^_jwY)tKl_k=u`xZnFzq0UJid;GcNMDxAj@T|t) z$E9c_=_5YzjDK-Yg%^+}rZ{-utuXPf-Lb}c*K_Ux&ENmw+UPWDOPG7Q={mc{i)vGX z#a^~oWiNvNZK_=TS)Z>KCsn#-ue0tpu2)9p%gltvKA#lr{@pwk?`JuvQs6~M57)1M zI=WBeKD#YQFAEfSkJRxpiH)z@vGc_hY)Yxd2@e=a-Lp51aVT7%2yeZIQhRVU{M`mq9dx^!`}r;zbV)HeA#9)g7?ls} z@It!WioiD)JwpgWdwq1dG4 zC~tT-u?ZdLDd|o9?=4W|;FWJLYIWang%V33byyU4H?VlVB7Cw(Dvh1~_4Qx4Qy;!Q zbD=0uV%)E%F*z46s#l1Y!7#`h8;1bg$uXew?6B!EYt2`>dGs_V9%S`SP}B2a-gM_W z>v`_kuuH$u;aG`xf)9IqnXKrj3Wi+RLmH8>*lPXD2&5tmbT1Nbjc`qLK+MP_&;m;a zWwxDy)g6n1ZUP2|spuaL_8dZfLxe77+K#%qz#3qAn zY3*%0FssG1w>|8#`PEkyH-n=^#mcKdB#cjB>sEV4T5H6+y6$o}i~@h@a*v4%d&yWt z{c2#BeQvm$;fp)O;H@c;>Ey>BnZ#3&si?rHb&ID9hK%KZ!IsaMI#I2V;ilpF&;43o z9>1=;xyHd-Zr91d{X9kpr=-g}i-w@xb%Fv+RGjF%t_W7lhYB3?=&_D^#mgeRP(mNy zurou~GK@XSC@b(SA}~Li zl@zT6PFOWCi~ri_;>R%Xg|-KGHVC;)f;cE-tE)1+fHr9w8w;W^GXBhz;(;LDu*j(o zO@79Q1~UsOz-7@_r&1K!sHA^eYb+UyMJE2#T}%gAq%ECwYsDK0l80<@^#Q24nQ!{* zjVhnb@f&XosfJyBK?6gsNJR>I?ex%+vpiuvZsnWYmLxREP6jJPE#a2! z|Cqc%AItuu_GR>1p>(7xdke%{4PISYm&y3l7~^;gZ{_O{FI^E>-TSrIbh_8*ADdHx z68ifsNIo|5%IoJ;L3QH;I+cv5y?XD>5mj5dNnY<$Hf3I)W&W;jDNZOmcSXWDdmbG)ubF4rY0 zo2r$K&vf;<-c9ub)$;nwX}Whyb@jU9SKiIPHmA!QEuDuxA z&0Q&P3VRSSCR(>tcX7S)f~|b?gC+P|?)2uY-uy(W8@$(T@Tt=p*Msx4{y*;Q zG$N;|t0dats9FA`oK@p>raOO}5H9Z0q~EnLFuVzZE;xK6^XZU4IP;?D6e+Exhnd>;kXMD>q$eW?WwDq z?!PJS$B<39(AsT}Ez--nNeOzkTBGvtbckerA%h{_+_+UClnZNsCFAWp|Z4AC&iBUARV;l>-Tt ztD@z&cGb+B%UI*HxNM2~swBk3YVr2RvoA<$EH3DOzOr}EW_+xInf*&&_v3zcs!zXZIK0gz&(^=Xn0tv;(`TKn zyzKnG{rTKc%^F$fkfh#%Ek9Ye;2K38xQaV=TI#e&v|C*3Pv=e<`L=x)&t7uX&~jCR z*(Dokd!b;WC5DFUE}Ao4T(8tXbvk$O|K_)Xn}lNtRlYes!ISELbvm89LEYyw>08)V zYL5-FzQ4tMd1c$E3a6+^LBl~j_7iAQRME7X9GKDSC!T!g~R?YN@nVylVMMT^j z1N{ZM1i(7(Riy4?CKi*%Bh)ch`g72p6GrAJhN5!4InEiq@|z@z7qmy0JfoO1Puz`B z7!iX@ptZ&Q<48ihz^%6TGBl-PjHO4$Sh-M9L{fEBvGPqaVef z<*nBP?Df3FTOV{|ja0u*Fo?SCE@lsIToV!*{hGq)jK}89qx32Df@gMg%A=C?PKQqW z&Gh%FDJs|x|N2+@C!fAnP^;a1rsUdohoy?hixe|17Oh5p9`Uy|NQ>p>k1sAoN`IqQ zsM@YEpk|6>;hvQ?AvVk4W%TcZK{@ZL)}KCRb<$Tme5u0yvo8nLnxxxm{Z!Mfo-A>k zjUDgruL(b%YhJkfoaE1IwX&alx5dvX2)iJeR&gE)zr)|1t-7fu_^8v_dR$Nd0!)_Xr3bT`g!PvnNv@64X%p94hjP13is1XwfWT2+mAe45*@ zJ6+6tZ?bxM3404Z-3D#QOss~~B8#?M ztgnBujfO95|8`$3K-y7h&W7neH6{f?PyH>R!0o+MS3I%@R+;p!|9zZim!EyNS$s0L z+&s|dTeD0XO~Dnr#+53F^y78TT}JrKOnPGe*!J$=WS6x|6kTGbo6fe}9@lNw6Mm(+ zP}>S$?X@qqUaK_i`79q^Noy_K9kgeAq$2o%xfjLP=q&@P$fw;48?MBJp-B%Bg3-yO5S*p=)a2jXODaTc!<+a9?VraSUS#m0|(?xv4n z2^#|O^T>|RIyk|M_Q%)jF|GFSHiKo&`?0@w{N|6i(PUjYs+p5Eik+m0%QxG+$cK~= zW;HHCR$$l2?8)&+>4$!^NB|SLU@kKg6t=m>-^Wz)GKK_pc}~xStf-}Y+1H#0nf1BG zZFbWb9T{BKJ=T&PiQFb z2U~G!(PB5NQG0fF;5rMQ5s`RRuin9HY(fHm-02$d(xiI*+??AHQp3eE=cA3Uk?|X_ zz0G>kAi)X}Zx2Z>6Sd2?K+atU|8d=8&J`Fk&1$T0_31~=X8PM1?u(fYByn|{C{-lh z?-3J(i!+O=HBrKqE&jX)TORFMB^sc&?$xgS{X@(EOo(PjS--K|?joABbM-dTF*N<-4$n%f_P2k}_B1=4- z|8F+HeD{CU?r|v${jY4tP&(R$?QWOMMCF;CwlZo@$ht6|0+s9INwqyI)6xqVZ zgBMcV@K?PuQ6i>E8>{ZAa7Kt(afB59F8Bo{FPK~F_5A;5w@YuI$?{%fqj{&#zjj6` z+#l?hFoR}UM?Pq6)ZO^OyHz-sA_lZaA=m7upHyOBzSIXTM$Cee_@-QGL*Zq zp0~1#&em#SRaolw<2uZlWdF$^8KO2%;Zh;sQUY`CF#FakA&aCDM7y5xk!IK^ji`IdiN?pc1;BtljjG|wc;Q7%h8Gp>1z!TsPG zwmUKpC&<$zjpt-$c_(r={Asn|bt0nHdlx0&0udFE(nC6>34R3jD7y0qA4UbG`5ZO# z^$%Zv`kjaj_gVm^i?K=d^M8u%3{)iWS0ex^4<9neG3_p!y&SdW+Y-`qCmg!C$O3pS zZMgd^2K6-IK&UHZoe$RjwDWZBxebeQ920&Np`JUrY;yC~B;ReI!=4v@_)As3Cic*q zW@#(StP-|8elIHYSF(33{blER#t@CEaSP+XK_U76}xEQs)g&EeYZv+*+W_H+3g$r ze5qm`!*l{{7Ed@jn`JcU(2J6(h;{_4x@Q*+Eaymy?Q}Ni&h#W)qU*ZKQbLj5@dVCk zHJ2r@OEUTN-`o&1ZEt?huZOzOi$z-_ce5RFz8C8$7a5qJNd*MW`2 zombgD?-kwoyj?Vko)rwHRWQ&kz!rFFZy+Th)7l)I>vlICu&dNYV+REBeH`ct&ukBf ziKP*}l7-TUqb}%S9Rnxz5mH!qkp!qI$nvjh@jy67b^kR8y}%Q z*wuXf8eqL32DYm+Lg{97!hAEPqCimbAcSDpjRPK4q&n4_;9|e+eBMfFO+9tYxAI$z znD#vTqJQ`a-{YM(uWNBSiW*@l^f6DRc>)UgadIf(%7#Y~XBKY17mTysoZZ((bJ;U{ z(T~wzLIm;?FprGEyF_JU6T?3B8nU@Il^21vwG!y=W@X)nTfew{qv)L)i~-FtB)7U5g00V+3HdsFW?4uCJ3)RVeSx7$|@gmSG;td z&3yKF;OdeR7U!p-SYYd>n(L!m!%z58$@#3WYU(IoflMhbA6nEPEg-J`>5_#OUc_YyXX>gB@(v2K&~B{4cSMXb$9AC+~iCb zO4fU@_dcp?(--Ia{MY6##*%yK-zP*I{A*3rS)U9a*!R2379b2@KZrx_&;^v&Mi)0( z0_Uz+vEa?WJKtpHWIbs=&t!W=>o|@MpPEv>kjP-QQvhhgr(Kdr9yUC?%YBA;KPYzh z&c;*6lA~A}dZ{+?1toObqsudG?WLglmEP7qi9j`Xci8=V@WT#PcS02^kzUIno0z`( z?`9UNu-DDzrV+Qb$M-mp->;fY_D`eUsx^^2%u{;{rxCdo&`ak9o(~~A|J=3p+aL3V z4B5U1C$Zgv4x4qcfv^4AflHD_jSYNL-WEPSGm=7ibe@(ptT_gIAB8e9IO(u7$27Wg zS*?V4GNVgP)Z3SM23V!El{;;9qmDOk*}vx@QE2|-bCvnb5w)%^l7}%#C#9zu6eQNK zvEdinx|nB?zwGb-XNfaqjwXs>6MRlyN#I73x*gZFo-}U95`~iLeae^IdaO9OJSD9z zV`Lqe(U4G`I)2fYrzD5f#{5^uVMTf$)&!qP2Fcn;`(ex&b3OvnuUe;GTqwpWVQZqM#9I$0VR~VbF zUUV};rdN>ALxuvQQx%Hr1Jiwn%484k9H zKO_2y$Nkck($<^_lZF`HZ>Yze6dB0&^1{3AXT9!oNBkV|?GP#Ch#o1UM3 zHQR#o&KyOyxGDwuzTd4T#8n2d^xqyA_q_Q!pdp!q5ED^+^P-_P(-Ap9PHgH4UoGce z1yH|_ldSqbi)O_GoF&&?HL($Kd&>$$-2q(vX5$N>3Inv!rbFg$22-(#Cx(6MHfrXxwg@is|o7 zlp^->>YC*g!5+%TfhO7|YgoTKL~2h0s+S$Tkbn$W3?w0- z2Ll%4UW|}72J`le?L;4ZXqC+d369L$kYtwJ$^miysD^4`mfjY%L|6;>f+4obbMLIH zMCNv-LR_#*(UT%FxWf}?!{&@yITH5>(I5oIhjBA4q7l2Jw49bie}Yvb(GOJX7i_08 z%Ha1eV`$K5km?k|als_U&cRHd%WR37{Bx))0XVU0&Qn%lcNi>dtm857NE|ciogO)lC-lIXAw=Sr> z{*v6}jbHDZ)l&P~L3IPf0*my`{+;M71T_6QEl^Ny*NE^a zbYayqnLWX3tzMuRWU#gtEGUNj!t{({!{0|pk&20uVF!Hm#;jf+ccYs1pD4cVXYtLe z3v(ti0pTRZ;C>tpC<+?(={C^HHb!p#$_lqA~vBzY3#14mzXiCSx(Z|9E4Qn zrqRHi5djCBkC>AklvEV;phNk%mUbqfO@6D!F9U#CNHx!>Gw3*nCd~}k7jZ>t2YwUz zNFLVFmd$##W%swE8GchT(3-Q)m$%FvSqb-ymn3jp_DDh;ALx>w^y~DE1bi-ZHzAagZq5zN)2hMzOwTb+J6gdINCJlg=34~Kyy*#RT z#3S1OYavGh`~0mJs_n*9fJ5Gxqfwx<0OW>HeVy;)ws14{0cA}C=~C>j{G_I+{z1M` z#A313^Z3oLv34?OanwW_Z$jNO+x?Mj)NHOFm-zlckSc;U_% zHR^SvYhHo0N8k(b=Ac)|)Dv;&$3-O$7h@@%#bIDp6c0MU(gz|c4}&j9ya!oQ z_RXiDqJ;*zXP2Gehz<5ZXeh-AQ7Ss+g)iVc~nB6Ze9p$~?jz>J6S+5+H$ zrN=VODkZI>!ZCEP(m!b|U)k-5VX8yCpd)ef(`YC|?Foei&!}}rMS}SbWs9{7b1`$> zqAFGb?Ea*PQVd*$=?C19F>;xQMcIs)D@eeQfy zkvZBT3xiWwDFcf@xprqD3M8;&GLz=(3k4cxyB{2TZ%ASK&X1|}ge1v5V#DcUsmvQe z*tfQRTJo}oQK3SkxXE0mf_|#x!7F5*Q9PoRk<(p2G$N1 zo7WN=4Dv!v4|vFsUw zOdBC1aoj`UCFWG7^46VI<4p$v(-X>A|0NP0=&0UJZ%t%|C3h(A<+ssf!d!q<&b@02=2ATq(Bz!-V(+_0oxbbXD3_(;iEiy>y zXsEb?26aCeYXe#bb0H#0B~6V_(^eC$7C!CI^%fIFI5#9Mr{}Pu=G0n@n&nXf_h~LK z4P$63Pi>+`?!ke-`^Ns;&#}Y?k^TZB%9K$j;U{?T;Eor@;AUT}@a)Bqh_4gw<@fF<*&vh^}3)P!hv!@_ZvG`q($P29u$1D>1lolF@adfBS8hdJT$WvR$ zSF^Iy05Hb!86=T6HvA^!xb|6 z*N_6c=zL5dYB%w=jC$O-*M8o4`f`d`P2yUwoKp8wXkq7cN2?B)$dfS9VI+QgZP0$! zAKJG6&^&!##4!tQmhZ!!Z6Na$y2{4H9AQ5qpOJBKmm??2({f(kv!IbetCLr$zse81 zlFki9@Mc9TC^!x{)ep>_4p(Ag15gKvQ@ppf$GWhX`=>E^gYhjeF3j(Kh-9Sh*Laluf6P)tusyM=T}8 zaxD`d?LjDyzaNfV`-9Nk6}H`dl3r4clkdC|yekdc?bf)j=kF2Hb{2fo>`|s8!Rh0E z%;>Oh4glhWl3WP%;Qokw+RHDa4|q^G%W-o?`#cTJpt$xe`nAlhn;X%2H%w)GZ~6;~ z*_cfc!q~uJpx!f@(u~&s*eKEBU;&!UaJTbFs&mhc*Nmu+Ug?ZQ*bmBhzF3cdQKHD3o3;bC1YvQGE`U6DyrU#xDJmr%(u zN{=UZ)L*AB=b@%UQ!^J$&AQBV+)6FtaWeBc-tmWOQ-S@^l>zpR?QCqVxY&Y3VX{Er ze|<2D5>+wABO9B~qS-_?*eL|aN^v*H^+xCtR?v?6knQB1$q%W`0Cx}c`IoI3`l-lG zXuuI8$sctf>V9j!kkCE5Tq zSE`YQ8wb-?M}AAy3-3J}5U=VeRGl`z=ZSiZN z*CGr-b7RCHhJfQ*S$r$b9X`$+#5m@Vb6Tib0^emzU38G))NTlO6X|GriiJqxkgTg4 zi6uw7@8vPD(6|`*SXY`-r+_*!2VHK(>E-D^FimknTG;xJA&jSYM9TZkt55vNjNUs}@5!n0pWaC0)42bwp`NG7Fr;jyn#bo4>I5^)* zqd7Ck{Gb4gT4pN5hIUgbk#3DeDq|&GM^hCU;bCoRpg?cY+!h5aK=HI3p^#q=DWmV zklHK4B;l*xjyxSMws8OL?(7{51&O>mRqG142g{JWrAc!&%V?fVM1?H8(x@Cb8{Vl9 z*=>0Ivezy7^b?;(0Aj+ec~e;**9`!%@YpDGSb79VPlxlz(F{NllZ9&l9wjOP?aD?7 z0c;lM=Ljv|nkcJ;{sl;coPm7h4z`wKon1pXX(PtgT258bkcL6HsCOzO9to@U6UKD( z#XRy{1?4$n%W2e;|S@uK~$kG@>P4Hz^7nZIrBkt&vDciq|%7>QezEZJ@x(@y??*z^u^*n!>^8a zS^8SJ&*y)7Why>@W3g_D^{C1FhrIX3LC>h%2eMbcu9*1E-d8`x|NF`PwL9!TTT-g54|Kg@8 z7u>V)ex1PKc?ouFR1Y3Gy$bZ%I0SEz48DpQ;Bd-}-_4tg=+&?#1GB;vldd~%KH`Yw zSgg@(wrf01U&^Y70Mq_HY7Ov)hn*Eb$;6^J!M9& zd2^41%De8_{Y%-;!|*B;RUmd-e0WKuN_%JgLz6?M%}2xNyv&7nWQ*}KMvaLw1^bHa zv|Huo>$d%dC0lA^p0%bpo-Zh{*jj_PIq>VxNO0~}?_oBE-}g#EX~lK6p7~!kmV~cR zcu9Q(5mn<&I^w;@JV}YOpF0w_f(Q#_7J=^BZp|@+r8(9iYj*DU{3M}rQJ(xp$5Vc^ z5--imC@9VnF~M?a`bz7NAsLDb=^T5b$#em#3GWavbmDC)N^=qWQQ zBVj`CeRf7zZ9I&3j5aPHCHBhc=WCg(+@I?6*rXUHVd0)#FxY!I>=qWl>{i&msma&T z7JaNWi3Ue}kB?=$x#FNb!c?hHMJByo;}kn!o86ks8^Z%0niNlPYd#;r%mc@=tLAmP z?qSxANi*5p&h)gZgT*PobnB37cOy(oqpa*-@)eW@6sI^qvJdyEx+g@q#vQI%*oZqk zIndkghVIMJFhE$83t!)RZm}?!ZFqZ8sf7C#Q_pvy_B-?OidAV}vi#_j<^WgnPUj&j z{friUN3n2wW=UAC`Gu`6Fb}%xu5QE99JbweO2J!h|EYT#0P8puJ(`_W6=bWk8Aj{KmZkUmy28OW#%_(GNcO(3<%c&mUMsizJ31S_``;iNTWI4`I6Rg@9 z*2?Ulr-DGa|D0&>>~CH1(-9Y6OQ`mSl64y+w~=Q1BGFzoO0nB8R4Nzk6ojm=thCB z@{wh?1?hDQ$N&{Nfy;~45vJs0+6A3VBU2w=W5&!m)w^n^ zMJ%>%ZY`43$va5A4&CwTW+W%mZaf4oN*v^?)oSPqfz3{REDTeNGv?P^4o70SQ<*D? zNu&`G_`iE6Kx364E3r>z5 za7xwn{;}RZw86*EUh*h^L007vXP8T24MG|jGfT~qX{)@}XJ?-3fZ+7vN?F+Z)$_Mq z0e!7CWI7i1$qN+o8yo(m>U#Pe*X*n2S=JT9&9>i1%+x0swhd;ah{tzp&uy#;8k=~c z;m9q#SX&I^R~)unyO|0B@C=`49l`_HoN=bK!4{9B@BwqjmB_u23?fRO_GB4Eyh8&7 z*2GgDmg~+eT_5QL?{FJH9!-hptR+Pn;rCEPWtGpd{!OO3`QDdDdB+(gVu)~191kYn zc0#_|_8t=Ynqu`ADRJ)EmOc#_=ss0}w^cTClNQDME&_qQ3@Pmfa-XRPR+QWA*0``3 zjV&U0i;!oB7zGhKMOQyR(7K{A%F00PV|jReI7G8g|4H;6VG}#HmjSpcu#NHI=S|)yuLu*9CTXdb$OHss0H)`D4go^QJjY+U7zF)uJh^N zrIrP$7dueW&?i52w)usQAN%1|XRzOxR3XW8nLLr)N-Z&k14SivlO2Z{o8o<$9MJ>1 zYtP)Uhz|5*efUchYt zG{4o@TZi~hU6P%D@DHvvr5)srs4%Z=j9Yf!!Ksyp=5YOMd%0)tJsxm;GF~)WiTFHJ z0KCcmPw^lel^a-GJNOu))N)KVNNNC^>Ce{&_{}PUH~gdV!EiVi#e+tM{AZGZ`oSu$ z!zuzTzCO2wLsJwqUG5#6Fx7H6;17^96(bAFWUyg=wJpwztq>;&1PcX5BhWvy;fM^w zR8qO)$>}bQ6PIu>?edcQYi4jG%A1{p%*&i4+` z*p5%m@B&Z_Coyrn4${>!tnp!P+H7ucfHNS#?% z%EDJ{JUDT?ZPvi%*B2*L4o8UojHA3Ag${-E=3)pe);GZ!FXfG3u|Qv5g+HlAvXOTg zLnlyDVG$DBOuoiSNC2)8*`;(K8V z`6cg}E^F-iZ=BKTlh5#i(T_JNS3MY_*`qpBduYu4f^4_!_e(8elP2J$ig?*E-XgE~ zrDL%=CwPGszH*F1FKQ*;YwfH9KEUg(KU&f8;FyaIshx{WbPG;B+x^ooE;j-#aA;0y z$LxUgx<2VHHzKVzyqtP*wp2K2PMIk`qBvP&4}d3^R;%2yg*)wtOhS46OUfwwn2~7o zrq5UW4Ax+gmC4X*iSl8Z=~^tC>iuF9UkK-!r0Y*sbBZK`q*JXm!3mlGyOaz1OZDxy z1BLh+yT;2d_75v$u~xorczN#aI~Ll8OnQ-Xj$5|Uy29cgc!44AV%n{sX zUOFM?Sh6!@>67LwG#^$=PEIeCzAsZtrY#GO=Jzj?e3;-IO+TE7^-hVZmsx9OG1EA2 z9=Ct5=ez9hrIHKg3BV0^WS?7yXa}WrOn3eLox>31*mReKFbVU?2PQdRJSNZcj1MUr z)BTn8Q;z_{Bcv|k1B{lGGU{0WKP_YNs!-Y|DdezfuUmHImcXAUZ~Y)dn>wmH-cr+Y z!0pHQI?2}_w|B(Zms#?CKN^ST9i67Utmt0+z$S zis_UyG+Vi^ZrzkGA~N=QuG~eW2Lv;JI&H59%0RvbMtachNk^+$I$|0@HNMKOQ*bGy zXj*aooOzE=?(IHV)19rk`>TkmcMgOpew+6&KjgUtWd>~Daz3#|Z~Izi(S`eOYcv1PZX2b;*3O%hZRwD3pf7`e^A+b&RC9Sv zwGP>Ecq%Y)8mY=M$JW;}I|y$!uiQC#>$jbz(tk#_5lZFTf7&`#Jw2>B+a!AuT;Q-!?4M%+oTC=cch8!dHi4Kmo zn?sSJR;dNf7ra%?7gWK_EVk35o*`V-DWcrnU>aLys{#)&mBCUwqAOR5o{7+oc1^3FPiY5lFN;iD880{z;(y|GGnnwta=Q zZ-|$xML9$YS58Uq2YQDbTaw`H)N8m|zslJmZTs{6Idi^}<5dPJ~X5-{3f5ei7e&l6Yf?U>Of$pFYbH1XkpanWTo04d9?-6^+A zrm#0WE;AG#XNtB$Tuo4$06DdU+yfC+vu&+4SpV^bjia^!EDJKmNdy(x0c?cuDwF*V zco$;yQ{dIkE!p9uA3$l#vgCO9;m zL9RaKH?Z!_cV8?-F>=yn8c4XnP5#aGGtTGjFreX=n~iUW|L#)GcdhXLr|gpf|)=+Kq`GsJI22dK2!Hq7k9Z#(^}vIoBUDk{6G zB2#g&W*6a!rxF16o3f2#`dIJt)M#siMox;lKEQ8_^CBx$5e=zylaTbYbOzNS(e802 zV&BJlu@!h#KgOCRP8}_>XX2fSG$WK2nH1VWXA;LjW&ELCWkkv>2E{>qg=NXTeHW0m z(!&)4a~oU`^NgB8HeX!0wk@iEY3_PudL5l3wp+AzWBT4bP&Io*tA3Gl!t?ct#Y0|4 z+osVo?^sKl3U!qq2vM*M7x5BTst;SxwY}uAO?xMVkL0vOYbs8&v+!d*jUim-x2i9? zJ&lweUzn60^7q&-RM82A+pUiF0J>K;F75<2rVM&rrkJ*1D7DCnfBt&RtOnxQ9v(?I zmQ^AnBp3l1l9jN-V6DV)^B$SL0n{4~%^EvG>&%LGu)v6mb;HucdJlcQh+Y*n1m62j zw?^(xwB(F2LVqP10f4NtK68RmKL(6MF0WXKuWiu+yHFg!@^(%EDamEfagbGQ6bPCk zcKIFaox<^nJKznb=}FfU(4RwBEZILS5j<^ff?f0_?*a&|b^DJvS~OhR>xO~tj|6eg z$Rs^)ukD&pNfnYnXI$DP#IMF3eNjYmV(#{?A}anw^Xbxt+7*zpw9M#<2S z8s=?QYFCL}hg2UOC?3Hk#Gi}wsJ@>{O#%`e@g(4`bbGe5cCB7QMjbT0=7nyjaFzHl zg|w{?h(ErAPax?%SqlQ$pvfvS=d-1tawr&3mcsXkFNoz#!qa?J!8N&X?AV{162%uwm{0915o zclRzo)p{M+)|`{|<61E3BdS^Rn)edn7S30%R}o{^wh>`Wxh&$HR;bvrHe+qbN3RuU z4#BsXhJ%(bv()=4Z`HR%G#4p;hB96wSwYTIi{-m^rzV=5=OuLf@|;nql+*0abV z$-neNb!f;H^A=ysSP(XCTYL%M+rK>G*xKnW6-xr27&?6sZ>B7N(AVhVv7C(Us2bC) zerR@!XLDB5S^Fjht&d(~-`JxTKk(V5d$r`lH9>wOb*WTmZ+u-oS?Cj9rQ)t??oVL~ z@IMziZdj)?5nHuORQ{;3Ud~Ts854=ENvn8mpUdI!6XMi_r8?`P=+4w-XS86x?Z3`G zMqvzp?Z5TBVGPEdHnD5X|1sKM%(uKH?*4Wb>*_ZXU1Bf_F>{oW2%GkwXQG8i3;do@ zgctw31G!jDox9Pa9U>}-VMDygVZO^+1LFEy{;ZFh)CNb3oVyDiT~PKAqJx;TF(LuL zw~~yL`*lRWpvN`tj6#FQM5B=e3a#Q%0*wf8sxTJR;tEDDBnlw>=QKd^ZQSR5L!`YO`2c5hru33 zFkh~!35^zdsbhJYHL>#0n6F(c z?R7jga1?byS?`p1>qAdE)<*yJY+na!9x{Mt)ZO#~IALLK zC~C{!stZ$nHXg3Hj<{P$VSVQ8aDoL2tSe?#YUOybuLAOz8g!+3ViL0`+&v!cZ+WmM zs*G4Lz+<g9aqRTI1^dfS{U~UUi51a?;c^Uad-I9b~-K1G6Y{)*03#jWm8S ztDM6C$5v>1iG=)`H;!s~OBkguaHpvA3+J}kA3oyP8l}zm8v|(DUJKW>EXrytn;#LO zDc?D7%mw&-r#6n~mHm)h=1uyS0@EFz-(MWgQBkBYR}=ItHF10U5H8Yhf^gTY*;0%S zG4l{zi6K+o##=-%jr#ic{BHmgfz$(I_0)Y0eIk+JLjfX4H70y+h6Rh3P0OmH6Ai%$ z?{gURV+orel_{%A2Swy-^tY(A#&>n#d-)h!p}DB&a_Y4oqKOE6mFfe0oVx``Ywec~ zWUWA`oaO-ZK$;c>%JUv;P+%u_#)}OKL3?8@0fRnc?Wq<#d&-aEztT@^KLrir^!*%) ztLS%J5PC2qm+I;BLr;iJx0t#wV3|04&Gtf z?fJqi1hwFV79&I?= zgDZBsP(l7{&@e+Ne__p2dIk#CW#ULEEMztTMG8Yz@z96 zRP*TC1hhtL&@xszT2Hfn&X|~?ks{IdNU+q`ZdLj4)tZ`8=NWy{wPAcPLfAVP^evUK zJ%=p51lbvY1h$nsw@vzEHUuMh25n*%KAWPb))esh(MWudvV@A(Qa)NZXPi)4J}i#{ z3c7k?C54DnWVc|T`S>fNlUQxMAd&9VDhp^Kv-WEw8z1ab+2c3W`q!!FFQyIs3ArLI zBU;d9OPU|0dLz?!G4@F1nsK`MY|!rTe} z4>Si<_lXIkC`Wkesbuu5YKZ}7gwI^~#poNIa zM(Ap-g%P?`Hen|E2MfXkCS|$nq5L<_+)Ujl&cqFl>yw^&A9*d zLbPp_*naaH)!szhsDiDEqc!IYmc#}(mOnXteAT>3^%hPkzV$ zI}{o17{51ai5mm_7A5XE;`lk<@!0~UgdJ^78ObLdZS@9vd70&?x+D|g5Cn&~5$m&OJd;68O0fnZ&zf0}JR*1&q*bs_K zQ`2pkTcDobp82i@xfS#R%QfO$hcHkcD~d!IixOfu2qhs87-2}^#;>dqTL0k@Zx9gU zg%CPCj&)p7Oa(tK4*)ggy`pHf(vVwY5RWG1Tt8zs(JnZZw(|W=R_GGEk4(`rUDoW$ z?9do#5Rri?bT$bhMm-d9zj~VbYBMHpt#ktWfO?4_`UU zELzQ+wyOD^H2=yy6a>x^kHL6#np~s7S0g;m6ouYNMF{fePt-Kk=d}^h>XX2$h7*qr z#&L27uSnd8Dx3z1TgLqLmaV@B8!h_}7S}e-lTrVLdyskw5o>H__VDz zi^`!^@S8KC-f;raDhvt2AC1;8O!)rAa==2Tv61%{EG<0H(nolB;(h>Vp{PgdX_yW0R>gG`j#_Y>D{L75SXb z!hqzTNA%SWx#^CuT2Jr+*vN(NU-TaMGsZU9(=%e7LZ%=NKU?{*fhj!QkptEY1BqRm zG_|^#T#P-2${Tak%_?Pcb;VPsrv5!?)Pfbp0zD}z)fmkKlKpq(Y;Ys6E#=e~`S5iJ zY3fBjvHbNpOQMchx*a>~il+e`z@JQD&kLO{qY{2ulCVh3sjlzg9b+*KbGdayx$^v!c;c!ceaP9HW_T z>{NWlp=U5NT+Bkqi)l`s1t}zef^UQc>nEkv;{oDEuez(qj6_FWx$ttgSYarZKTyGhj*p&+C$Ql?m4_J(;nw2GBBYrin(`>C2Msp~A>z@Pi*@UC9S1{1 zlp|n5Lut|kPTQLbi)s&o8&8FYR`mF-`2lb(y8HSDpJ9)xToO+%uY1siwNV=%K+(!7 zLf7*;P5NvqT4)ZwEFzUjtj#A=y{4r)-cuHw!d~qB=M3c zc(t@^X~^r_PTqZ*Ds1yr);zBpF@_sy zOdF}!NyCW-pm5++0NU0MuX&?vM(Y=>i8#?KK4H)Z?Cp1~|39}~4whr+_CUE)F^N9rqr$Atyg>lKIMEBXwsn)mRfHK`&uBeihSX_0tQ1y#+K=g}^3f7yY+pRGSf01TQnyTJlD2lYkOenAIX&?a zwZKpZ_*b&p;Vf~B-i+CEFCg5~qD_4^aOVKCjq>48l}>$xXU_B`xG0?#n8jGG_RWG| zmhhyP5oz^**cLt2S-e`_aNbb>9c%-2Q5+yMM&c41dS*KdL|qd{{WqZ_-p(7U0vfnwZ>KVc2?tBdNj+3vwOVU&SNaPHCUV5r_IHq$_+6=3VmSp_ zci$veq5FH*k$|UZ@?3Rtbm@gYr#3d*Ha2-%PSQ2!XT{c5=sH!;lNU7A1fn))naLihEbeSLOboD+t|@GU|==?;Gu`eyTsZ|DAC+&fMRIr! z881I{e0%#k@4&(LL!Slw{GG?p>POG-JC2BH`0o1D>gVz0CJK4;&1t#z;a zOeibhbJX!A6(M}RJGD>;R}OuL+`MeG#Zyy=4GD1x_PgLXb%O1PI_mG6O>f zd}|dUk+|~&eownkKv)zxRgk!xnjr;E-i-?|+H-A*t$rlE!^5*U%Ag5x@$|!B)Zls~ zqe74GylCM$Xp)1j`WxR^1p{Ez1av9B$Z;)zsCo13Q{^Iz;;3G(pOUv z_`?EtQ!6muzD=J1ZeG4bIZ|^8uqI;ySilYRnx=f|3(iMCzjM_EB4yyL1z7}u4*Yc8 zJ^`4K>~v37RE-H=-;-S)i}bh6-4kec2>~cx6)Oy2-x&)seBezz5F~s*0Sv(`69_TB zAMQ~rJ@;iHgQyeI=>lEyDHxat{gU|akm7x+V5ESZJlY#2X*CX(U4k>gEGU{)%A5Qs zat5OEz7O2n%O9jwfDhA&J8>o90#69QUdpl@ea0O$m9iXs#Oj*j`6;OM9x;#JOvK~F zHm_JhUYC28K$@Q+ozesH+lsS_6$ zkCFs^!v>Adete4cb@s7IiMREi6 zG1lrx^x*P6ajpEK*g$mXE%yeeSdF~j9rq>a8X~$dF@GOIfFJ?U)7z05Z}OuAna)ju0<f1{n zp+E=fBW|339dQ2B0RiYh$)N)8a642uIaVU;yl5=y-CNvRaZ0!a7DJu?M!@qE{B-VN zQv_W0f)fzNvy%^mtMa23jUgz0LbGs-UO*q!!5eEpR`jF0`pILG?oKlrjjQX(Vl%c; z@1%V*GDSJ*yo{8ZU`B=v#2$aVfoL?ww}m|`#$qpx%!Ukm7qW3w{I+_ia*zOF7~(^} z>7M7tRSC=aIJg2iUxJQ*=8Q+^CL4gdrU;U6!2zlnTLGOLiraFj0PRxZcS4))*+7rL zW?s6S$1nyr9`cnbu)H4t)1YD^}%13n}y zV_tEfM=ozYL>O0!H4kJT!A^XGp@RQA@Z6&UVKRHdUJl&7ai8Dh_Dq5Z8oZqZF-36v zzAe)PZToy}?xp={B@-@?ZqVD3@)4;!}Pci&Q)^iPaT%1x5I2f~eN46uh&>V!F#g@gYA@ z6T1uizjLgCk5fvk?Q(Qt2Faz7j+V1#w}}I%1RS1cF_{h`s;4}U`E8d3Vdcxp19>Nc zyfwfavci=bOG|e*_J==$Y~C*&a#B9jedWLoKTo@Qlz!gsh8pP{ zTJTnGw`kYnWe%$Dpo`s`H&xxQ80f*Y1YtCE#3N&V_hMON8$THpn^0bcR&kMBQqifo zq{Z0f&QL687%4sr|BohQ*fNVXszG!=l-0$%`!JA4HTXGZHYExb^Xw4B1mq-)+@c94E4l)aI# zLOb`(@Rtjny>yK<)BczQQtjO@#^L5yImOGc@y~;DRy0qtEXGvr^ zBFhR*YzHFOX$!A!uO-{Db=ceDIMRJUdPf-N^ z^yE4>%g(G6`F0+Vu`Xo>%vcOzOlVyyZg__99eIrxnsm+@@oR`FuW>}J-ThqE@wkAP zy>HA6?sTjezO)60ucsDkh&c*7YZXx%Md5v1j+PpaXM3#wesJUzpQsZLGX|%dTYGF$ z1zoV*Ji<_DnCZdP7TmaAWalUiqm$+Hg9TQhvF~uSxXb^yJVfjfOM8R(k3r z^k>DI_#Jj^ZraTKE8Mn6_lW=9y*UQo9KQLv8l#+? zoVdGHpKp}c!pBVZiJD#KrpAmV!i{>r~D7`|e#hEvh zcmp}pndY8C9lolvdYwP%`1pI8Fnf8Yx3l0=7eTSE*jI$A{GazXmZ#7SiV?YgJl-F# zyXYf$?VMGx$De018Fy>x^xJ)pojaN>u;+RY>`I5Hd@VXaZmQ;HjNC?J)<&l}8y5FQ zgY(UM%*G(}uEzx|Z;;1*%oEK+&gjAw8(nyfC#;-89GsukqCgkLvz#zo9Za5y#H^}2 zH@`Cr+YhcF>uLuai$!D67Tsk;wbHH^^15MZ|lpLOlj3pWB+X z;k{`O{`e#OKsm8b3h5Dcg9N@wVg(PULG(xUJ}W0F2Q{Qe(`m{v%)S54-ZYXJ;g=MB zqPu6uNEs?gsaEuLKJuADB3F~Ps@uhZ$K_i_WzlL1^?e z8Dl|cGSJ}w!-JUfStUIw4>Q?YMs)bu=m@1~^^_Dmyx>0mqL$FFCKW8DkA@@)G*|IM zL(AytE@b5^X?)ZK3u$~3CBRZSB%FHQyw6Po$f%GGjPfh(AU1U7ukmPVS@PtyW z>ff|rx|T7HMB$24;4pd`7`;`VwWIh_9t$Z|)0YUiUHHMmSG*edh162bl*jsMkCA~( zhaa*YPund-K7-Xi!>U!lLL3WuI4EIhdL!)=);`1PhUxzjKPi|UkUycEL&P_d@ZGkX z4RP9-L@^`$l^x|3c|KX6-8x{CkZCG;>M+e}ziWpO>O`x%TFXV2SpMD&j2muWA*{_y zT=bL+@`L3oCm&gpBrhSyYJ2#&IlhzRhNyr?L?tfEyxRa33!Xbz17A0hw!@o(`pv@X z-XI#?l9$R}m4q@OhgJ}hX;Dlob(0=BI8e8+>UuH@zf$H?W0*&}PSCOApy{szmARzt z2y5@9F9*Vyd)b!ZlGh6+GlGv_Hx1<*sGdm5+cdQj2|Yr+9;_(QR4^%>R6sQw6-~qG zxG#Qc=6FJ|v~#-*eYiYUn=MWfILB-5e}??^YyJO2Jv9EjUQqc}7T^}3Viq`-1&n+=opt#>lNK0 z=ln)UUMWxvxRhrH;`ZmB*|J>B63>j(@>IHyxcqQ`rNS0 zkon7wV?~;Til6jo%m5>6Q!|CeH;d*-D{sN1H;PAc6Y8539--t`H3oY>0Yl$}h8POY z^yP~)EwL;*Zri(tIt}ijx`p-y;@V1os(xfPy78LC4&Isrd|?EJK%p!&by|eeB3nZ_ zp2#9z_rHx5|7nztw>k7$9MZ=G7Jvq#;9W<=^|6v(4ue`wKqZp~!}F(fc>qGGT|K27 z2Cra0fAHCc0PuZ0M9xL6(1cLzV$EOp81_sQjTA$T{*fO+UP`rONE<9|mc= z4i)VGcPFO?|1Ly2-Z{rv>_5%EVJ-g#U;8>hX4=5QAcTO&So#V{(5zw%)(vy(Co_dF zQPSC`5F#$USLVv`M{$|Bz*2x2=Al729Sq?Q>r*@ma};^FHpw__#^Ye7*1+8pd9#Y2cZ#kL~bz&gR zjnoU}R&cyN5D~dGSwfn#rtp{>;o)jxc#3y%?OD`+if-Ur98F_q7&WUkAs|~=NJyn$~|-_zMC|6m;K(em?}EAI9B34#JG?Zc>UFkZ~km|z3i7~ z(PTBduc~U#=Fh;Wm!7M+I#PY7E<1U^#K#9_C$FCII)Rn;D;%%d+%bVmDt!e^JoGAh zYzO7{gic;m?u0T$MqQx^U{=-4^bb;1>0>}IbK1I6DJY&>t?WzOd|Hm{EEFeT8YIy- zccy9H)je|@w~`5dy*%oC{KVPm=Iw>Bb3X#&@vv!As9l$r`j5^6KN2(r=+EEqoAEx> zTz}s^qa{k(+8jPJVsd=rMP!waO8~`d11#O$Fx=iFa}HW@oGX7D3Mk$M(AWbsQetW) zbiD0p)N@KgjJZo8;QK7l;4}zPlfex40$HAh=6Z>r=F_XK_i=Y_7=3RG#|(!!!}1%% z3wp!0NC^MLZ9kfJtL+N}i84DfuwpYFt+o$Gyr!WKj9E012N52lqC?Pfyz5-dmLpMD zsQHL+dTHJJ5rPnC^6X<5`Eg`pufK;&(F`ls;1Uqw5gi+t4|XS+1U~HzmqKo{^yo(j zL153b?^@(vqo$@3Va1P$3_T?$fHn}e&OANJc$wNh90N=yE?M;>w$t2hsit*wT>9P? zf!9d*_XpQWR1U^^I@^r0IporGzfGKUxy*|S3gxigpGZPpt3?> zb)6rk>uS&uLbx#cXvaYrXl%KxqD$F(TaG&KecZ3zj@!#)0jzt>#qES3_R8HH#ID9$ zFvs=Y?Dl8nW2{Sz2<=#gCk(6{CM+u4Q0@JIOx8W+&YukmX5u}2{YLwL=(fq(_Sl-Z zu4(;Mc|TH$J{3iFx3Ad8uoM*j+!EujWj|=F#I1SCi*RKTBi1e*PAB@vb8ez@dOz}3 zSiQ2kbxy9zJ*uA{cEeLoKrE(mrIXxqP;eoMWZtgk`Jri-!84w{Y>0n3Nj646XylMM z)&_=3H0vK>h&=TAr2a8JE|xtka>RPPoxig^hGEsG#8{X^w+8)Ict-WH{Nm`KnE#Ea zV_Uwyv>%!xV&n+Q)aBq1?y0b87QfdS{Y|JxooVpJNW!nfL2_pL$8{9g399A4qhc5i zeTs~!+bKBO)-RMk$!AjD9k1U#J+3BFF*PM0r091txTE+lr~UuGBC`^H%FTlW0{Ihw zK*ayw6&WYT-;(TG{2QPoJ7hT{XI%~v3~OSvNTYw_d015yVLy^-f@E&@ltJtDIXN^@ zKB>y0G;w(`+v)BYV{WUsW;)NFMl;uR`HW+YSEIdxpZM<5{3k6DvEp8icGV`as7pw` zHHDZGmV%S=Si6jPg>tx}{hL(m0R^^77p(z%0jAXS`Tpu3*mE{2zuDxqX^*-x<(cjL z=u561!)vk&^~T(d77;0)`U<4`GQ2oqo8+aC6ip|uxPep$P$NNFL;0iVB#WKBGVSa- zmWu0bxzxhqaAT0FK*`P@C$49GZ@H=(*b>LS{C;_@4>b zdCG2Ja>r`PY(nC^>z$0=0Smrg$lDn!C~hsXzl7`3zP>}LPaHuEUB$QlWkHG7w1sY@ zMSO=rWO3&{?};hT#Z~_qF<{~25r5pL`J=EZ|CsOTM~xu*Eu z4tI~zVw7#EAfBC3&wkG(lOoe#s4Nwn^=cxau2MXk@sH*RI$hi;oFeSN?%o`(lm5^j z`72h-wP8+ba&@|!jm#Z-URSg9EU4Q9Z#oF4eN}fQH?^WX@K5UEs{%a64sP(*h=?ES z^lNztUp43xmPg7TBM9k68H&Yswf#E3uMcs@^#7j{EYs96hXXsTKG-kNECn+Yzh-{^ zM;_u#+6luKyDw#9zwFK5uJEs;jpj>l$BpD43mbjIsL%MYbfupVF`;0qT-Xlo3kNe0nCGn!=8%M+vGgm$jfozGkg*d9_NGf=yBlt zkQ}vw%YI0#+e0zGd*DioBR*}>9Bd5ho|`Ip@1!cO`J&)@yRL3mimj-ypOqq6%4V6V3T=^sr1- zv%vX0VGe@T(&`y(dVI=48V+VVXNQ4Qh6<5J6IN>ZZL}1$#AyN|d=J5QrZ~2$LTU!W zy$zPYsW5vJLt9yp70gwDW@`716(izH%b*l!vZuSAEh$JYTJg z;^h#OP&C8T9P%Omm5GoY(vM8J`K^|Y6PcdbCe}v#IsUrGi~iv3xqf6?dN!M9u|Z?# zByQQ{{L|4tYdDQYex{^y;<;JrCh!mheYTCtGF6uuE}$bpEG{w{;jMwHi{2j&ian@Q z4~PH%Lv55bt0hbr1X3LW|6fBb=igAPm;k6>BZp~MK&TzVZ3=`|d+NMpIaAYmofF3m zjuB9K`CEPAu-iNZLd*6g4kuyV+n+n-^3}0-GQMCSpX7pITu3BNMLV~z+{OXxh z9CJOx28D&hIc}n>wwnu67foO5cc662LO#JI{cjTk(??I_tq>N(6$O9_zP`$ z8v37(F)I}@qSN8>zQ^A5g-WHBt{l}|7)icl$Hv5O&g}UTJ?zdi76IsAov*pq6!;=_ zV-yyfBh;xcZ!9%fK7PXg^g4PZHYH{FX&=L{{)@9td3ER7Smu|38%N2%Utcym6L9@V zIoP8JjT$Ko4{^rqDoQ>t#Z&dwb`2{%47C)QxMdSrj-f8UFZx4L7`KESS2T~w|2d$; z01x5meib#zc#ePcmNETUX84CNooOeqoEtZTHt%x5TU9l!wpTb}YHK_l+ICxix=r?> zjmXR^Do;WS1$!;;xAbC#?)PZg1!YmMIa+_SZH(_-b<*2gtvu5TkTz}g4m`TSQ)_x{ zSsycJl1=}dgdyc_9n0ee&8)d)JGk0N=J(nSMtE@z=NzSrptF{#I9U|lfp-z}m$7f_ zbVfKR+ug|KI{l4|tFO${_GfLW2)!ICz2v@ijMygrsl+TXVHZJqDM#Fs%jL*q^J1LV zSBgpZtt!IHtvn<>zId+l6cp{`7VNiAHdf0t5UCis^P^H;d`qE?jIhMHy6Z;xFFB|& z{MJO)nskGYBxbU39wVh5I!1i*6i;8~V(3#i<14Rw{~$qHQXlYiX^U}?1{}%MBHcoxIG@GCzt1k4CR^gM}t+K{(0?Iwk zPQ-oZ9i1!VWkvzZuL07?JG#2PZ4X=#*2sh6a-`#)(7UqT9_fxRcZT;kf~hx(HSTBK zLEFZ`Y{wBu&l|n34m*Sb|*-f+SSJE2$YNo5$ua)Lz-MERNL_pUZQenEU1H3j`*di(l+I$O&(8rQRbn_gwWsAV^A}~FjQ-H z&u)H6{WRZR-1ZIdzt+91A2_eRysE6&lz)Mwt4kg4#9TffIoB(AeT1ZCl0!@pDJvGK2vpQhBCY*-6gTG6y#l9vmJ}KU<1lQ4RHwAk zo1F`+!Zk*7%jo$$lJ{fi3PgtXha>eB_4j@h-8ZF5tE6R0RQErN2QM}6kiI0PxAV`u zN+JKyI&yn0%s+39@}Zl(;v`%#K});$@sKKB2ub;B>c$?H+ZcaEqxL(^7q?M+tID5J zKMx4z4<6rM;CmQiIR!A)quhP?{h^#~LN4leRbXxcMjei zE(X7VGOc5F4p-ZTbiyx`IMvf_zqPha)L~v#j_+&I3Kbujf)rK0Q)WB+nGwgYXEP9e z7VdM7!Hvq{D~GTNx@1`NA4l0!$G;Iy%jfrDj(CwH-}hEfBJM?W_m>wv=74c4Qo!*< z)BndtC7GiOb^F|==I(?WvHT-Zda``IcPkfuu1g^<9eQG`ChvEZOJ0199rv_1lTN!z z3c=UeoR~u-qm>Xv?TRb)4#o9DbPMi7E{}{HO>titRAm6ssu*0-208~jnW*r~4EjYyGO-KuDHG?6Dd1-s=fuRVK-2r7P9l(6+#{xL$fvH zC*F(Y#&p%MOX%C~K9Y&sq=Dqn5dc#(U{c5Ej~@0J<{W6NawF35cr?&nVN8fvcW9Ko zhRiUFQNv_Kl0l~jx8%dEPgF8W+WJuGhWb^PvxZB{2HM6n1RYNXql?nZ6`y}!35_;O z+QN%dybW*63u=1bX(e@`@Q4Q#07!hVK{Ycw& zlO*WB`(uud(b2iTZlIsntk9(nCQxTbFziDg7IIeAD!n0%OsKa~z8Nyo4q#ylaSemu z__d`KM<(m4G1eGRc<1aP#*@kx;AX;NBK18YBO{S``L_ZpmbHV5vPJ zC3|w9toc~eURue50q@fPU@|$ZfFiJL+gN8JWJAdaTD8aal(`T3hfJ zM^22dC9i*+O*96ZJH_Fd&r#bv+C^8D8~jD&=n^d-jZZf;EEF|Ts_ou^bL5l4V6;>5 zlc|VNTN96Ts>s^_O{Sa$4EIX0ALAO*YBh@G>?da~yc{Rqwh1#Y3}mZ^VmOVBrViA%`TsM*=!1fIkZ1Ac!tg z<0oO0Dny2mHVRMv1dm`=POc&Qb;Ggao5#NC?hhF$6?MM?Zm8JQv`dDWnwrl$ngMnE z6&HZQkV@xg);%V$_Yg9eC#Jto_Df7;Bxe3v$i6LDe2vxv3xUWmez`ZtF*@=IH8odT zj=lUA4k#)`Qxv))01gyf!h^k#mbT!i`PIaQ0CZ?cKpbt+LHPc}Lql#KMxNBi5w+D~ z2+H{Y_#tAZCb)OH$XG2`@)wLVsm~e7)ffX5Metb+W5ve97xxr>_bq^&oJ`*#y@+>? zJyQIh1L3e%?tnAfZbnhx=PT-LGdX3K28A`3I(&h;X2S;ueWC(;)|gVVqTjcEGHm)6 zptZDk0Evg8Ui4E4vxWUb;@BvPq&%`x6OWxp(zg|yRP{dOlz5*c zs*LM7!Qcl6+?a8RiXwg6z|C=V5F{6`ZKb$tT+jc{Xp?K_2@7Dk#D^@g&32mHXrJ)U zx3(tt+?0B==-r*9_V}d=l1axA~VkVjXR>8H-15{+U8W8 zS04FR;JIMrOY->oiOZ;UdR0rm6ov!U`MUQHhS(cX*#BD633ydtwk~D?W*fZE|933b zCw4j1w^6v)xHR@2e+^pI0|GI0WDc6|<-OJh4+ci7)dji<;>n$Wzm7yL1W#86YO@J< zRB{$`SB!6ZkJH>P27#2ikQ<1_PZTFrB62KAIQ1<`2Lf$yB}w5Wa2H6$M~GFB6i?B& zXf!8NQ&9R|LD@TgXu)8I-S>R&l$k>ku=D|z=Sl_(s0}A?zC@8oJI@P|qsLB{5a^u~ zp?EhXFp!#yU?=^sATTF+M8&Q>n=$R4DZBU6nT)!cf}Mwz`Q!?P8iza2`Z<()iXoJv zlZkVfstNf-a-f4+ED4sBIkW!6FyZ|pWUA0F%7vVdlF||hI}Dc74a+0tC%kc(s3sP4 z(a>H{Ix)vv?4Ez*ZM?TzM8_ngRegt@G#Ztlb0?{LzeSH3-mu|qTS8qvOjRUmWYb3P zgGvF5B2(>T41NDi0n=>E#k^R7jaqsb{FD%PiV>;zBQFBcIok!A`7+Xa`;GBuWI>DY zQ+dy?tiD`V(^jC?MOg?D7CVRtmz~Io3w-m{t2$M%deP#X&*U_{9oN{F7go5D&fK2714+v2%W zHD1$F+$?4uTJL-!rNmb~FL{Fal1qnkN4~l$aZV;i&bk;`wqf4;WvOf}$G5J+sF^2j z`1SD?8Zq-FzLdQNaUkdULDy!5C%}kjTpw#n?E~LsR}*oTzUgK-hxN5)6FF&Tg+ZXY z)@2xDXdfasv#T@TQT6^pqXb}P5pSZ~%$OrTFoMiMc(IL?ZvAmS3DKa^$#V;PV?0M>9|3 zZdWLnybpVp#^zmnbmz<{sFt=sE_N*fYL$+>t|tN9!3I>wv2HDvlS@360Kib8Wz}`q zu4K5z`B&HTyO}h%H2!d4#A!(Yb&%5JU`O*fE3NGG8@IG2QyRpQaLV2d3=qAw&Ha}) zlIHTwTRA=<_qw&$JY3?;P+&NrC2St>OHTAC*y)aeRtyKcHI`4dTqT`)ZC&p@fs{HV zPDtlioP?P23=tepxQ($o#9T7YQX<(K#ZBy^kdX=27xB%-=DEf*Vim9I0#@z4fR15` zY2c@LBL)byz$I09o|YZeWl(x&G9y`6lHMf@NFVNc;;;1y6;fm zcrr=rPl3*@+1>%#a|E-L7QKR_;lr?75uI*AT*0rVW}|6P#rRj$TCP-72(o!TR?3p= zoJ9*;9nS!;{$#Tbh0}TI#93r~?6r*A<60}^DYD%j-%`%Q}r_XgEI94hFvg^p0);5xH+fAOBcz%!K4i*B&C$<>jME@0Yb_E!Wpi9coUac~&n zs>}y24e#DMkNyUE^`KdDO6s04yZcT!VOT1dHo&o{J%Bvq=sez7)&2g<1lfmju zLGv}LZf!6W)Oi%YlsuXis!H={L?DT}fCR+KvQiy=60-YdU#RJ$Cgyb`;+=g-L($nJZA|-HF^+V`ivfJm@f4_iM zJahMLmL}`dCW2v?!|YNT>k1zSJJB8QASok30g&TJMNvwB1EYWs5v2=sv%) z3}2Gl+hF58q0Ug*y2BmOv^JhTefE7|+)-uc^sv5RuV9xwfLXOFT}-6Mzd^WK-|Thp zk-P6@sq#Sywr905g;r97Pw*V#9Cq%r9{#Y_Q8$^`fRtbw%UG;*{%I*fmzQ##-X zu}nAoNlTJi=P;R;DFNXoL<;;sjGn^WteE-T6uFx9sm^68_xDz25D}zhGM;)@jvEF*4TXy1J7_NpNX>UD>!jTJ)O;^FiL=d_m~nKA(=j;B*{&w z7M-&~^^wG*k^Uu}0x%pC^H(hlV6ys69L(#qPd@P26n}72p>P?@Z^b9t%Xo|sxW2F- z(_n3zOURT|wz?QuSKQggies`q;DW=h#uBgN^fJ6waStBrKR)vktYRepuI`Ajd=Z!< zjR}g^ujfU8&EB;O!6QS$tf3!miXyvu3V$7Jr6LWMa}WVl27&{Ec5!q#m zLaA7}#i7kWr&r;~na^KH>7dQ5%rA^MT0E@UYSVL zUy6wxPxc~DThU_G$Jd;OEi3-f)d9xWY{z}dE2W{1^8*Y@Rzb)3d3Tq0xbFk>ihOn^ zgYP)0O>pnU5Qv7bV6kh~_j6{YP;1*S8a%xi^Mh>u{WSUojt*T}O~`;11xN`F!TQz& z`jrwHbGb;b$BD;aJJQs^28dm8mA#hUosdN5HPP~Yyp|~p42v#~(3X>CH~2I5Pc0Bn zKG{wmpC)QNlY=;zLF7Rh%_{s55sj4Kt{?Gb*YJ#RewxV54!5Gft?CZI#vrQX0s{YA zQIU0hXOaz=>8}mp?MPh-kN{p-`fVae0%gvfH+m19q@?3&@mIJwlwZu8V!;<570Bt_ z&zCdR0ve8f(KEW+=MvP8}>rmo!mBWcI_-$8UD48DpPqa5O!$Ne1A>b zOMegqQ5#AC<(95`v)zAg5@5X3+(Ibb2xH5PT1N)+H9n#ZWcG(ttc@JgH%F3XO%tDC z?;#^NtdTx|5#N?`T(@91No{9=U_Adj(W@QW&{(^Y0%Ef+C2ukz@|C#N z%_J?Dk55o#f->079CD--C;Q^FnRK+0NmTX$mr({)FW<2p37CvMk(svfX#FD#XOU!? zLy!Is^Y1?x09&03f`C!24DpS3ijH)k(srqDMdUpc~zF4Y9zLm7n1xBCsLDe zd#aEwH<3cas>*nf^C6Q7)F)?k>xCeYXWY4!b&46WPc?YYlB6=L8=FNe%vAs4+{8n^ zaS?-RsACwm&nwLl`XmXUZm2a5X(Vm*E;1I0Ue?L$p#42g-losEec0(_^&d3H!sekJ z)sN|27ICt?N6b4U6i#H15ql?Q7Y$mx(Xp*ReZk~SwL*p5yHw@r*d}i-$uSTzbNX~La~fOha`oha8hW=cp>`xR@MYPb zjTDfT6(*3x7xh~v;jSxiX7W5gb5%v_IF=6JXDvBfs?=eCYRhMp{rVl`)g$f_L4)=xz#yy$U(1HZ5d8dH@ z3ZT?tL?Cs7_+A~$U%fQ7@CN(08G?YFB?NevjYX9n`VQ8qq{zkdw2Gjv#l>3@%ZC^b zumODpT8na_!VKH&5Asv6U+Vm|v1F24T#+j;;(lpXe+E#0&rUM-!Ch@3(zEi-Cx8c7 zeF9ML5^V7l4ByveIN>7S$hDWI)p=!WW(xgKbJm1$AKC#LyDJIGkzk=VjGJYW?bOtu zn89A)+H=6lTGVLqmk8&93KW&qA~XM);r5sVXaH;bBsw?lZM5vBq$I>pbxtz4X0NEZ zsxpbFKY8y=dRvEQ6o5Uu{4wh`1ug<#V;ut!qOtq_g8rFwEC0&}9_N9eYysVA2CGG^ z)d8_Q2uCypH9+xVw@|*FL8z^$1cN_SqKLi2;ZCJl8&w4$;tKviT%E++3{(T_^C1*3 zqKGSDS*28eqx|qIDZ2^DPgS@i<&SR`eX&hmScqWKWafZ-H)3nGs&&jq^*tol=cQCc zse6azV8W;-uE@rwuCfPpXVrg0hq8d z8@u6{mF_3HK3%+ys()mbU7EhUe*yk(pK4VqmqU2XEUj!{v9_!;x4nx-t@>Z&HypB1 z!K4(?Nll;jB0#pwFA(hqm`E~_Vy#f;#2r~> z)k$7Qsx}#RyEGBgqF9vQYw7c;p0dxzV$H5%-YtON7D9W z#Z>Vv9<2>^KC;=jPZOCz6v0+e2wBieXEt3D5RQmk3a zmhxqrqShqAn`r}&b*ZGkz!MFz|ESXXFX-x%^6{grm|!+*OGpN{Q7({eD`7k;A{+B> z;mdNK>WU1c?+1GKHxmQ4i^eq9@Fi@)xG*60=Q={$JIe@Ldql3bMS)BW?4h|}* zCkuO_pk7ot5YIy%5AdxiB84@KHHzaR7>xU(bFCHVf7F)`D7fFDV!%~_E?x|MPHiy~ zgMj$#y97(%MS3rYcdEv+7WIj`q2<2g^C9-6S#O;{i;>yuBG`@cZ)w?2Vl&hW3&RI@ znm0J6o`7j;4#e#sgK@%l68gC6O=bL&BQ!K|X+_{G^EJQ%kt=rWQd1P@-^zQO0VzHR z`;T^KwFDaBLbunbG<{i!V~$jYrUn&f=o_FINWx`V&?g`JQF31Y%$1A$v=)cw1urj- zl&k9j+>X~kZQ{~yp{vT{LM~(qVe;IGLvcUQ^F^M$(MtZyV{!ma3H39mFD*{g zc>jm7ZT{_I9Jg=6mlRP|nE>Ad4S*Janf&q@qHS?_WcQjhUsai;Cn+^{fATsxHQ>6T zP{FK6SK6pPmDwa;enp8x6%Xo2P%kT0Hp;7>E{&;bso<7DWsjvG+|2}X3)R`H6GA`? z>7gHcuI1H}Sj_B1?V|z(#2FCa&*6YS12r^p)$U_7F3q3mu4c%tfY1J(th=ZL#F=^M zWu={Q+KpzrNLFSLK-E|PZ|~9oum_Se>)G@HS$pNUU^(CvX)r6Y9zO>>wG!L?nTUG=^OuV8_P4-9-Qs3Yb^^-(Kzraxi=riJ!u7NIGwKd; zg<0rusXzpVrt!9!pb>!>YQtDiCuBMmkS16lJe4x1BRRL)=ypxXvVn04nSMCEfY2%h z7h0tQCrk>nx48CA!Xw?|xenb^vALS*Axm~V`s{ITd@}E!kQi?}JyYbiKjsmaHXA-H z1{Bq1dbpx0zUg2~ViH~(DN%LD^24LgQJoyNLN)=VnrI_cXG(B;$AifcQXbGj@}+Md zzuscFn+kd~G0xtowNZwg)m&{GNajg{>{8@C#4>iwVhcUm5MrNDi~O`i0HfyCtt{(Q z&RdL>_af~SR)@Z7P17H;0(6^&4_rmER)8xX(17^_9dkid7q9|ud$OsY_g`N?xc3BK zl_1wWQ^SpLZ!%hqR!qiPQ&xR9$)@$d&mtF8>Bdg;qYH6SV6ktVM6{#7kG zVKA{W6D~SaSU*hmNBj_J)v3cr3VyWS^!lXp4up7E+57P zm{=~r#KHh3rU~sRdF*O+qr_L`Y9$OXc5I>k7(&Yji4X^m4#Z&sn~atLR0A*zwv^-3Hy2N92$ISC*jxTvxR{X+g>Oe zXja?86;)31L8v`Fsa7peY?syk?#J+#<936~ZxudPADz-BY|`xPXaObNR|Iy2e|Blj zCyr^5UP>f@MR1xxe5>gt8hQQq22ZeJQn%$K z!4vhD%1N7a-_iDC$l}lM-v8n8xo{r;5T3V&r=b5V62RVZb+6Td6BrDmib_6(CAr?o z@?%jZKt#7`9jA`DF(8GL@>+FOL0$kNwg8{hO%l}10mZT3rW8udpDBmJ1a75BKC1~Vn+jAX3JjYPW;x5CUFhp@3AK13O9;-!`R7yUUYh~j zOEj8)Vbq8p0wnUc{D30+5SJ~00?d?O8t$i^Q*hDz#ml9?E?@rO*%@%pKKPHUqV*T= zvMr{qVO$fq&E&1ioD#m+kE&QI?giopwDUj@IE+;PGzq70`WMJApPyyI8a`wlL!7&^ zW4Ig&^=rwg&=-g?)m8n~=!}lgCfFF@@nClhiw_R!7}lwr$mKJj!V>-RbJY9)0(Y#^ z{{c6UpPSS3X!J`u#-RxPOlCJYd8Mm1>!#^Xln-NMIm7|F3`npsnmVKs;<{FW59PKe zEhfi6OQOWNb5TT9HJpoOm!NSQ#aD`!Ng+UPl;;*IUinS~1a8EUA0pY7#d{Y$j704E zJa=r+JyFUM+a>#-@G2Kyt6A+q`zjyExP43j8~9m^bE^JdG6oQHps*_75r4GYW+`!> zIiu=f{rQ{${P&s2aD3HJH&c$Db-*l$JCT$D{c14wG_vb;5a9T5+5Mkee=W>o-Nxlk zra9R~l9|rp1sP0wdu+PK732UJy8|%p-~u($=oqld4-)B&%7X8tq#5KR;D!8fF9cxg zU9v9KbrD>5l;`~q&>$foP(Flk?PyH6yaI52c+@W^qZ9mV`3G~JbpeonnS!+|%X3({ z|3z2tAWhS#FvmJfBY=<*8v;`m0P=SZu__>)DXV7@zNpatjo+k}J41Pf*JFmT?`j5w z_xijW6GXU^-iQaxYvee=;{XR2n5^YTFvio02ci8kKbr7UY@nfvEPY@xP-r!T!J|N6 zK>$!)H-vnNeOy)cUls=FChvHF+Pd$7jNjruQCEIBh^?|mBbf=Wzmfo95)fOuZ6h96 z)d_iaQrRRk!^^LIT@n-7T8!6+2mpJ3z3(YS31`&>XEl@WO2Dr3*h$4=*6ztxUT#PDRuLj0c(N5uWl!+RY#Ns{O9uldC9kCP{7H9~hY1n_j&HuFUmu=^Du!RKX zCafuY5$|KTbY*|w+TQ%ShObVwo$PD(iUNqU#9}mX6{T+$Ci-JS2LMH4x6%%7Ac7m1 z7s65~EY|gV@T8EdxUY)ys(_m6L*FP~pIQhsp5$qT_F+?E$ga{|xvQNp*i(=f$m;s_ z6#WEM9)J!W3?yi)C-%xVNp{RY$(zMXeW7g*1oUPgpd-%nH1p{VoDtQ=5%qtpfl)o6 zDDP|hC?#O0z=@_<22jk1`nl}8SqBKJ&T;^O=i&|UI9&^j64PgNeYAU>!v^Uw?uEfWISyGFKzT;`men*U{;nn>HsGsd^;nIppSDyna zaaH$p#@W}g;5!L8%v;c8ZivmKbJrN_ET-PH>eZ9uscr2;oGM&3+N zn^}OLF1YgoA0YwOia!s~O2H7pxVAQBF;$6+C?`!S@R$UoDl$kj9u58>Nt|ZX_KW$ zGJU^8|71<13fRLFK-m5FfO|Z}VXUm8HQ$2Wy-!gkmZA4=v<86wf9U$ku&TPCZIDhu zI;5q$q)R}N?vRp{?v@Y%>23t1yFo&_8>Cy1?h=&#)&ZaAect!FzJIXyUTe*)nS17* zS^Jz5MG88dm4Vk9qatUql&eVP15qIQOuU9REI9U+;j+NIsffHQ0Erm@86=sksqIht zeri)T}3Ay#50z;!OCRHTS$sGtTpEOU-h}BRNCIFg-qT~KC#9X}7%p4phBwx^Y z2C-5iRNXrP$m*wRg+lK6ko3%0H8sGFa^qJxs#m$WeRG0{Uf^cJgbXXFBI~(^v0=Vv z`Pl7d<7dBFfjuo8PnP?VzKw zcSexvnfc5}^iBh#eBk03c2uVjQb7F)(7r9>L*v+eb`=9}&7+~ts|h+~P%{@~OEl1q zCSgz<(uOY}4ofWBG7$s!kbMK6v%!ESCz36%A(zq+q&2Fu(-$oSYTdr!m&ep5GxFax z2_XU9=2e(xFF5~W8K;skiVuKbbQAFL0Dx`FJgp|eDwpk>D^w8D4f&+VN0cddS{Y@2Db8T~O`Jv$IFE~a4;R1p>JjO;u7Tx%QB|~sL z$_%19K?|9F0td+Xt~I#EN2?_?nqMi=v_FCTOh?nrvi61kKUo?t;vss6hwAl;sG>u{ zwAxqxg+VQ12w8gNeQ)=c$d84e|K@4T|J2dn^9blLyhyE9F!&Ng{bD1*p%s5TyfxQc zdSR0%D3mB@~29>_g=XRo8A-f zZGy;q{+*#tNv4g1i8l%03QvwTE}CG}D+zg>q10RiKZud9vofn`bC) z1?FL$7?1{;SW9MUWhJ!va%HCz0U+O?C<1Z(5n$DzMMm0PMN;oB$5S6u7` z7utJWi=`FwNyC5!szJV%F(6|``Tf2^>!`Rk&b$I?fNK4xMFzSh0N{`=7;hRBcn<>e z-q;V#4|Bdxu%!G!1m>6k;SVh`zJ{*{55<)7aF|~2Loo$T&DFGrL4i2{@e$B!S)=Rc zrF^amMp58fEpRG#Mby$8_R2Ux6OB`axIKUTH@vD3w4n+wtv$r>{-k3RP*(p##*Egq zyrcaYRq!A@y3_T4GBgIv(j4@o!rLXSYnf@u4ZzR&L3PA3h=w7;= zfNK%|H$}g}1f9@EV8w!PjP@aeQ7Y9$yXV>NT)K~puB9(G|D@YpTqLwyZ{7)c-CPfp z-MwPy=~^txP0IP|(ZUc7=MR#F~bD@GBg@)UjCNaJ5V=sy1fFfR-5l}z`K#9E(o zQIwK3wyGK|{5!#^CzJ?O7M+1lgJt^Ym3C7&C zH})M(y`HznI=X{*>*?utfA$Yay{~Q#h4Z92;4E}Xy>)aIz21KcL4mQUcJ*FqzO&Eq z{&ShPzc?){_)A{?X8dK?8Pcua_+Gp2nH;)VocN}tkr!Vd3MYzY^-d-^)SzSRjcUj? zj@`G3zNglIZuh=CHL??q!)14?Hpha7GO_Q_Q`~g!i{W1w9X1^G%AQF-d3%DARGr)y zr}y(DK-i$z;oC1TawZjDB|Q+Do-WZ5Zv|c>ruND5i6m1rU#)b;!iwaHNV@Y{dooGj zA2PWG+wq{jH%PW_S)^cQvsnIxS7g20awuBaaxuiJfq|U$IU(GW?I+UOOIt4|>it!a z`9Jp~$)k`{^A=-ZZcl2`a|aP|ifMQs%jdH*$f(&Eh3(6(`{em!^fd>Ty%OOu!S_u9 z_c&0tvCg^UPE&Eks643$mzjuSI8ez4UwxiPisCV|Fah^sq;bV$>@~#(XEW@8TH>`Pkd9_Oj=?IUg|O zI8Mv*V^GdyS|zz+VkDHr5-EZZpD&8~E!eqmNjXb43E#n!PRhu-Q~TMfR?c&_;fw8; zQuR&cLz`#AuVKW%6|439nwess-A~p>&2UzaGBO>9;(7vOAKd3FR}e%a>55F$S}r_=f=YCQx(hToe!RIjJMin)sc$&XzPwK?u$t~g z-O5*uR0I)3j>pTuJh*eR?NfR7mEhj5d<^S9$>sN!qx4tV#MK%SwU{u&p1$?RK%!W% zeGzueR;U z+m#qvx|Xbg+km>fJj=wNN0ntQVF%f`_U$7!M*d5JvjO&O=@~55g+e^By4SOd=HT+T zZ*x>csqpqM+eL_r@Yv;KnaJJHW7!r2pu~WcJ*sfuC?B(7oS4XFHnQGG)hG!R5ky(@ zZ%E#j@_EDfBq1C{a>orA`RhxZyZZ?p z0ufVc(l&%LRi;;QdtWf?=2CwK*;{iGeeq%md(nbld9(_MY|C?w4_Ww zKyXN4G!CQ2DO!)@ROl#$6e7nEIqag{3DM33MY0iG%#=)+-acTDQeqnBCBN;~o=+4= zQ1u}*mn0FkP_-g5#rTy^e4(M#T*dkPI#s*MYR9VPOsr$Ed+~|nyHqN_oGG_wFTErM z?J#94O)S*)d*-F_GyJ15;&nDlh%X47oH2DOeT_lspqaqhuG+tZjurY=dR^A4G9dJg z-WI#d&xQU#sqjw{en|*qBAYfRl)>sWZQfW(jj*p336eeq~@i@#pJeGPpE4=HkVrm-%z%;cq!Jw)t8saY7p&UfVpx4 ze^5+qv$v!*^rpATNn&?$0vpc^g3;hEd}bSr_O-Bk1E!R_6}n=Tf(^$I2lkE|>s$}J zdNygnP9-<$#kDTmi3C6eZzmCP4irMd z1jwDmuyYUbmbghqHG9IUCu^?s9$6hYD?SAUW4&CDUrSb0eIzZk$D~a7^Tc95TZzir z<2Zv?O!Y-lVz{LYS9!sj(XyL_SlSq7&lIr(Yupf^vhMSI$*N$l|Odro7POecMz5glFp-P@C zE9doIuio${{y?(tWZ{R;jXvZN;}N9P2syR6kIK=X5XQvx&v9o>93fM2q?u>5vE+d7 z(R)8hWUhr)48C?TH{&oO-zbwDhJ5@ttBNKvI!c$z6GDCw&WS;To7^WQyyH|Y2sBAc z2U-aXvlIqQ=5O`fY3-;+(w>KnS?U=6=pi#%;5Ba)yOuCb@w)B4{~o=Zvq+gw$u{%y zX0HiaBCW4lP_Q~xI&>Y0TqXPu8R%Xy7at*qEFlr;=r8`rsY<1_KiPasED)9!Z}>di zlydsRZhxa&+0O{T+F2X+3VaGv1N1@9bWLk;z8d%XN-ROw%3x^y-*(#y<*AB7+p}Y06=!>WOx*lrXIwzsIw18skXq zkjn^GAtXBil&qPnJc9kA8_jNuHvK=MI+)Cl$GI0Ag{@qGGW%k{;8yzuSr@4JhEmfLgV z%aa7*+tUQ^+qd2~PF3I;#-L>8+E!V$R%Z{b)NJ!%v-dvGRUH%Ymy7|-LefMkiamztqIsx0P@Z-x% zs1m)~lVkjjL6Tq0qHQ0WrAB{>y5u4)o#`mveDxIAK!{oU#3L(7HcZy3iDUTQPl|u@ zZl4KiR*y7)Ac53*w%M?wwzw_oojm-L1i2^P;Sqo4@pjLTgQkonkV(JnOOaPrw{Nzi zyLb(;%a26t)v+7suG0(o*7>rXok924_2;n8erkYHpII3$qjNCUI-*xU#_YsFJuZ8! z&>g2Nyt>1?5L4>i0Va@5DjL|;?s|!#&J!abLZCi%^jRgeh~YiMp6%u|V}fP7JtgaK zniuu{R8bEssykfF)-(d`YCj>d`txOE{)G!JVH2OQE5Kg^*iT7)1oL^{;?;5Wbh z#NU!TIJtjj#wX;PyAAhg875A4eCCMB!nVWA{giXcvU>z`FI(dL2{dcj;v&|@fbv`# ztu5Y;IKd1i9PUp~F(?hcZ!obzkFws-^tXo7CYJr6fo+{|aq(eS)Hm4`|6r!AZ{VJe z0kz}s+h={B&iwACRc5N-(fC(i) zmO*iUaftQkUGb*Rx|&k!Lcc}?pQ1j28sRSDmx?r)e(`n5pRu%wGwT0y!Qq-t5q{Xz z-||-acKFHXJZ}LuL+-cn7vM;{e*Y@WkvUmOinDg{Nc$@$VHk z$d#`wJX5By%Ni~|>*v?4w=f&0mvoA(R(iI@;JJzeDC11XNZQ1j=b!&R$F6u$?DZO3 zW{wEW33gQBljhCE&CTxt(=+8l{jsHY4@xoGJS%k1JtHvL4-4RX^e&%YB#Az8n)H_0 z3VqUrgT$IQ^b`$yW%t@={fc1bgsJC`%^b(%2y2YZ7yCoRI$y7ar(d?90@9L%d>yVF z;Nm=JptgDzq5H+pWPU+!95duE@I%|$3_&gop4#D!Ng;C{q(Xgp>hhSj!Fz@G`-q)s z^^Tdu5rV3NYX{r9SFKJagLyVWY>>O$FEsHs0WXPNEDWEi9+-X=LDNh4LVb!6fyGZn zI2b+~J0oQ8Fn4E!NrRO`+va6tQ@Xr7hX!V?ljtK)`Nl$uU)nSiU}$;hew}dC@fFtp|1=(OKoY!b>Q$GwwUj z?WAeS8Abn7K4{=!^1U~OoQy3r=GWm@zqn=nYkI~wZeEsWJ(axXht_vpdMYwHJpYGl z&Lgz*r&TLwMnZrOfuJ`6Mz!$yiKwWwy`G1R6zryby4?p6C~Y!Vk%Iw2cv*@(x6xuj zTpC}FLwxz`AB%_QHKr3{kHMhutv7H#3=`GL`8ntrpcOO)MKJDo@@<|q_xP0Pr<*uV zA^N}%Lfb#KC*^!EuJ?Vare|29oap%7CZdn?Ff{CbRPs6W4?{F{R%hrEa_CV)KA$gw zO5<`K5kuN-RPfbFuw+(nDM-l2f73H6HJ`|NB-l0m!k)^)bmAZts14d=c{h(SLSzb zkbLHLpnd-^uexuum16EuMRdnO<(H6<1s+zGCXnnBw(%Z2vV4HbF1^5-iIATd&F^C- ztQ-F%9pMzF|C0Zp01N8(1h4~hm_^h%$*Mc_YQxVd;PktTU_-{f;+h>+l;D+@FqDFY zcGVv1KNq?k4i}C3Lo)B)$FxdZ$xt3)Mf>~P#SaEL221Pq#7h#=QMs!r!#9*Xq(_cb zzEJtaB(1*kYn&FlQ-<1dYTi_r+X4CXuqgMc=RU1 zDomforMd)GWPS(A*V#-fr22Q_6q*df;sx3LCZyax&ZE9v$|w=cb%Ggx?eYRqWDa@0 zuFfm?@fI1_8EgGF+vrHpuinV3l^#Ps?fi{DjTXwF!$l5NU~vn3zG`@f4t#DGzB`UN z8^dRU%iH%$)4*42$ljk8z}w_DV);zeG+WC~aLOM~lgxuX+;>%8PlfDjtL}S>yi|z# zaP#gG^RJ;M)E;AW4#ZiQMYo&-i#kX5!~x%X1AOm?u}+!b6fo!UI~^pSogJvX9vbs^ z6GqeW3zyq-hB}lp-@{FL5LZ#Lht20rTA@ve~K0@vJ9}}pTm$=>m z3F@rRpqy7%4=vM!JAcniG0aR6F>53Fpr`{OzzkH)_cJWnuD^!Tu6Oq#)76@$I2N2b zL!LU5+}VNV(2c79MpI5n>TONRRSWTsSrv|!l_(&w&Ql*Vd7yAiEy*fjTe$Or2?bPP z5e#_K(uyf8>E0$U`OWWD^TAUH`s~~W)=#M|aloayO?y#{r*vPjtnM&Nn0F0)lOnSdgqWM-akBHf%rvf46HogY2R` zjgtg0mgh=xzFC4tgjJK}6Ps)&EdyU+cLo_ou-n-k#)4m&k&c`;ae^EhrhiEde~Yco zd1%%fx`DP65n14DME|#tpzlOoyJ*B@>Qd|8m=n3A?GE$|NB3&MuRs!XcgwQHod6pj z58lvL@GS-THeXO}*NJ{sLbJuz;r!{T5cDn^g+{~; zE<48;M!R*CUx`1r(Ja{($siB^cxeJ3%f-wQx&GL!ygO3FNSC(g5&5eyLEqFnx~K{3 zL4)%M!7Mox1pP2PCBs+G*;%r?Niuj82A2AtZ?X48x*6pXNyNhs?e>Y8?_mai6!IWG z4R(AFQ{MBr2lh$QU?M`VQuEr#a-7U%lOaVg-77wPD33upd9uyE#%L0LKLe4H4-AI+ z1H|(B;k^9F<$z-V&#M#Y|PC4jM%vmADJx#K5%UmGx+Iq zIgenVr2Gj?vl%rGr(ym2Iny7*C|pp?Zqziw@KHRvAiT%mg*I8n!27p?!|CL>@Ie%n zCYs^6Eu0|*8gm3bgUqLJ&uwYMM(4)JVPS$Y(cv2g*{D7wvD7hfVm|uqFCfN7R$_N? zF9#lno~_M03Rr7&XfZ~VpOhM51H?eSSIiuGM@L$Aa- zWGFtm`0Ng~OC+5u{KAtj0Amo{(c8?|PmCk?dj-pK8hJciP-=lEEVHEptY!U=3_JrRilR zy~xp&(VWPDUm`*1-{BBN&h~l!Ne1o2loo#NXWgJk0&jRy9Q!8%!7nojHevD8ux%cuz1b)?Vy`=8NV zpXXr*J{ZKkv1&Nz4e>pZRrJe(G^?#Y&XHZmdwF^>fiG8DI=%O0_CO6PdZg>X4u5Up z1Vrfe`B9u(lQU?gdhrOz7Of7~xM76)r)m{U7z*tj6GEUcRo5<(z!dT-yJ9~oCSwnjB)3~xF8ec-Xj`9qBj3Ddxpji`%} z5r9fcI>4O%h|Ngrn87eL0;Ry&BFI-%ms1q{zA#{;g9u0`fhQ|I8}_V)Q`#&)Il(0I zj9$Sj3jpY=BVw127V#(GD;xOidT_7p?}0)LLLgp`F+4>57UbCNzc|sr?M2m$lRv8N zF1Wsy;*~D1i9LMhOQi{IL%0Z?!4o+EP~@7tii_SlqcoOajB$PhQw|P=5zcFB%UiSWd%|&p|*}C(EG?n3NkFqQW~}jzF>ux#~)hEjx3=^f@^r}U5)MXp*>t76SpWu32=cuqE;PdEfSh&zUH=Z zl3H+67J*)zTa*uSGZe<#RYtn%k4KM8vXX|NKqfBybE2G~2R`8V8KM zoi@n}uz!^%Oz$y+F&vFnF$}B-ybpoD0j!xmTr~LDSM$yc7g`Wv#@;fCgTX6t#FN5% zJBF83vh_w=a=nA5`kp!cX5Feqvq}GT4nG+z0{gg{Kgg-)7naNiMIQV)?{x}Rdvv}z zwFx$sAuuw$ACUc_9i!)OTu>8TP5PoFWGbB|3B#g|K}T}WFzB1-#Y!G&M8nonB1H zMJ8{&MjR7HA=_|?Lv+SOgC&hlxo(PyZ!j8S@)LwyH?xPtzvATIyr2q+__X}Uq;1zq@3D5bfq6gkEQ@A;sS$6B zUEVi$$U1l}gFk1Jp15KOd{*1(#GCV8pIZ=6ZY22LX%@N z(PD3P@4z@<()q?0Z!`4miCda%+S?f>u7JK%-eh}+H->dXr)JmfV=(O=&fTnTA|up2 zwyi-y-{$aey%fIt4znd_cHjvS^p8Dm-*xS#y$~&+o1TN(6}-w_LwG8Ckb>JZ%S$ce zkt(r`u;M9b7 zUpw^Jd_rdX@mn|v!?^1V)0kHm>LrkhRhNTP@EPg$ zJ9A_FQaWthsW4P&J)|-r!j3ft!4!cG0k)_fM@K6oe5`Iy6Pma2bW6B{UFT=5>(;PT ziEobPem*~NR6i_w$7B+FMI17w+|Cf&P2ur6@`H7oM_4z-)hiF>EVm$}<&!JfbVJ2U zN!Ok+4Wl23N)t@3r{6V<%HG+S8)I6_y$_ezMq6Q$F^p;=?|oaly!gs6>ilDPuA0u^ z&6mf!qqXZ?c@r+x?rk2)U{cY@b?dhI7|35gJ#l_;8%GV4M!Y{@crA?R&`l7shagHK zFqh1QYbLz)&ip30p7hst8SM?348191B`Ivu32vje8TgCJes$7hV&U;6XUN!HTd@O} zPdM_mO&bbW!$XL|O*gD-;q(IBTx}c31eXLNEk;z3&p+11%yy;Sd?AS0^_0WQiTF4z z6((_RM@I0&H$h;Zq0)u&=V4kaLY`68+3avX4e<9;%)ru zz=)r?sFmL@vcIxHKV%>Z*&7mN?}000h5WTI8}GNQ1-Ln5i*=hJd6L0T% z-SX2-n}uyJ&YH@ZjiH)-;r_u;6kShlwb`PpclK8iiJsr_O@7EV*8H6BS_?(%_!{-L z{-eKoPT1S?W1(b$j_Mpaoqd!L583q&W*O3pF?0ua{EL0pnmK$E`Gc%JwosSSeUvI; znkB8PcFJqcBr^LpqM2^mE3?Qn`!?xW;4Nl9J^STjjN*nAUO&0mIY=1ftY22O#)1Qn zY}&WYF9K_fcV1=FUS4y`_*~T2YhRkV(kzI#c@bt$Xdfll1^M1^Mo}mSXO75AyD^Ns zlvu^4b(uVhuMhIOsfnN#raZ##)lGTTRM5zslu?z*Y^D1qOMgOlA-Hy0mUXYmlXKly zldUB$4F7!PJol&WaC0wa`5d#zUhx2FY=qa}p-bCHKmvBbQI=pi} ze2b>XLR?m_?*U?!`>Scqz>c#W=ve;yo1*AAWc=q&@;&7H9rvrHt2!tp&MOC-)H?s! zY%W`lI+)u=IhxBjVc^=#slV~6kS%W8Lp@x7#!e1<*~)(J5tsncMww?Rx;U6t(lv!m zk(Ed}-0tt~P?(3?L1JlY2`{_AgC^LzytoEEyox@x1ikZMeq?9L^=i7Np-NiG&uV#= zeVkVIgPlM=C>tzg8t;?>U~tzIgI&pJRmDimC6hs4Mr_z8DAnOEvA#_>ga21o~L<@FOqEC)_a4WCR8DAr!k?yEs^EOxeUm?L{>4hTQjSX8EUlm z>k0=cc|KwoVT}i6#~d~NkIzzu)NI1br<1)Z!wfxO*`A|{zAXZ3`G^L>4xPM7wv^NI zn1Elb>?*{b6|2M@J#^KEiH5BCMQraYJrMO={nDv9#LI|3f_quZd3LDqPVBhz*PK#n zvlMxZ-^+%-vrqo&uOQ?f4tfM|oOL?XAJTE|6D0P>tlc=yNEJji`4Fj+S>Bbz@TZ&N z&|ZW+jtVqb67!{Bs6gQ57B1OWP%~-M<%Kuu;f*3*N=(OeMK&svZB%u$imnURmrPR| z*qdW`84mURV?+O$~ApXKLH{h0GC9>%(m^m`!#htH?mP>;socBwJ2L>p_pjcx_wWZ>Zrf~MJpi1+=jKJYa|Uq6 zujA$qXdR1fOeMB`7`dEaUyT9*LaLfH#Lp|d@nb5hd~NTCLbb$Z>Ey=*Wm?@SK!A+c zqGDpB$2NX5?FR8ez5a(qHxlk40)}$*g(!+%eS+-x`D5NWf4(HzIk}=|AWMbL2*+Nm zssA5wowb<$iaRLNVy`j?5!X{PJQyM_1Uss@67j6UII7pNwR8>(WyFG2tM-Z_zBh4M zrupNZxQEKpT=yz94kg;8Zz6}6LN)_HOB?M!Dy>-cS6?yoEIzn(g?U?T5=5>>S*fYm zsP)?0N^>X{+CXFjU0w>Brac=y2!7Wzhk74oha zm(+Pn!CwqIi{S^^&VntJ8l~uTHD; z`g^QRqaF`(fQ2Nnjsu&zSeWvK|64r`H+#Hr`;|G&)0Z&-lsa|3o!@KXRxrJi^S4-= zba(>%8D0%m(0z0ESi#3FC5z%~YnMtTdsW$w%Zp>>>J*L}N193dWo~ggi9t4-ng+SS zx+9J{e6y~M>94;Wjf?vS(jxbN=)j@dm;v!Rp`xBbVrPP#euCT`=EXbWOaz!8WKfhI`llVpq!fuPVYsNb~kh$LR zl}tfmKr0KH$9FV*9LVaQY0I(XQWpBe$V*SI~0L_^?fCOZ2S8K%pH2d6il&izHRfOMe{cp*}&F>{U zf83$_2S!}3a_YUMlm0Gq+!^cs83%DyQc>P(AS zrR*8Gg0)7x&*k#K%C596XGqJ^hSpJ;2d$@)6HY*L&1?y-X(uV2MfGg6aK6RKtNy&njEYj}@s<76w}bQ~ z8^m?j7G5egc2}d=q#Zh8D{139k;u8IbFSV3p#-^o!9`8PI&VM7D6+~gJQlu59M%tA zNt@Xj)fmV*Mj04454Lw}oLJ<4&t1=`itXHnwo<;5v7%G z3RNjZ;)lFR(J8xn1tWkKU&V?^ykMJ^QtHIq8FN`}304?GfR=6pYo@MxfEIk5H=Yo* znERT|3&(cG!Et1&$wbx|+(Xs=gGfmt%3q}NmBjx|s8i7Z4bsb6>;-h``VSucPlnOpdhaQ#BE@w9ouP7q>f*Ew}kR3%l6FnP_+P`mp-?WLNKQ^=`@gYIXX@tyy); z&HS~oi>o(!*Z=u%!wy$tQ{cPXNN-|4Dtf z8N~_?8SfHWam&1qSi8n)oQYr3J+xcUOF8mY*+PP=8{>c*{4tmk4=kumH z{F`)XLt3;Uca0%;+s3IuAQ|Ds@eg(`0A;{!2IKEaMTo+j1$0}B6I&-uA*<`0tTb@+ILK`xJ3X&t490Xa^<_M&RQxsgVIYidB6XJ5J%ArLIB%XjVwSB@wd8fbd>+eWPw#cIL(IhR)sncQ z9p??it(TGZR$|wOg9>LT!rwiRlyM`o*f2v40O~*x2G{cJy5c7aR$xUTBn6OI&3a=L z$NcuVH|>x-EB|4yre@NHcWJbk8DwGOrwL({Z|cG!a`~?O!7bgecNCnbj_FjDgb-jw z(2CJ2ynRx4IZ*YGV4)o#33fr4@$!PwybD&7!DRIvUMWsY!$uYI%Wt+N_-8^+fELn6 zM5#ostG=PM=(8l=Z?7@Bha^&bQE#>!8dmXN4qVwk*!`VZ+nBl&aEN53`eqsMLNW6C z320eReASvtpXHhJ-yQLr0p69RQ+Fb>bjW&1Uqn5cGW2A`A8MOO|F#ye)(zw#dHpe0qN7Dmu`ayhGTxesb(?1AJ5ZIWSc7I zE`nlikF@_M3lUJqI2j}5Gp*~Kk-W-eHf9mdUrZauG_EMWfkrOt|9f zXAsbu)d0}hsi3N--!GgeyJTuv#2=Hkm_bIlGYkvy?gkD7X5o?m0D{TX6*-rGwk%jB zWnC3eRoB`41DStOS${Bi{JDxN@UQbj5WSf67ag)G+AbTe;aL8OfUw5X6xjlHS=A^& zuOdF&jmfL+Lfx6GjZGZV0kD)8V5U5k3IqfR4yDnOxC&gnH;P%z?l2HPGjhqqO(pb* z+xSC5n4xpsfy})(S=j@07qrdC8mUU&^Jv#u9+OYI!+wC&fpF!KQg{%m5ia#mWcNQ} zA?n!y@!;>S*(gt@DrQFJO&Y@y06GlrzTCXOYp)3C@N}wFs=0%|@VWFoG*7CNS1s$( zz_Q^IY3Q>dDrZI@ZBp)Z!fHkuul5p@V#PG@;hH6{^0DoB#*Oc&P#RCHlrYv++8Lov ze?TIYy-gW2>YmgOFAXzIDtOY*8nAB0)ze~IlW_EXjUbmU#G;v4=M4b~AeJF{mc;Ar zTsi;|_w2WF;4k}S46C$5MNzjzs-TM$p8|nnQ8xOInY4%2x7@#yQ-lnv+{01xX1(8z zS^EYOVcH@$d$@qIfDh+Qc47Wao~01587NI#s?~$aa5`A=P&schy7&a&te8$YA~UYW z=>CcS1xFM0zil2(;|)*~{$Dt{Y3Zm%V&+YH*x?I@>4CEFe<5=%i~qR2*KCc4T^lCCsFSEk=lO1yjT<`naxd2sR$Z6cOSU3;;BN;ATU0nZP zB0w^W@BhRKWDpDtMAyumG(|yU zn1ocdJP?UKbJvgSG|6jV$f|w!Wi0R;2tfvPFXWMfD1<5>asMT|1`kyFh#ODSW#hHo zb5KA$YLqSH?|?A)ipgX~>HQ4(q6C%p^>xJzxuP=cs8iP@>7vABd$SDr zE&+AG(gwxuur{5^W^277v;$Mu9-zx`q%Tkm3n8B6Q(NELz@Z*I%WDg%kChe)9tJ;@ z81vdji%AS!d-nwhihE822OubI*4fo${qrEywVIvX&#kuE3TZt_Ihg_y>$~_0w1%xf zoL#PVk8(0C#ZGkq1xo9Db{#~pt)LQJCA0VhrjPd1rP!vYt^^wJM-&BVs4ncd7oO`` z3&!H9i9IiRpJn!fP4kw>$8yN&CAdG4sF;aY%%eMTj&jm3#U^lACN6sX5}h-#u+0`! zs5DrA#x&M*qTbdxx#avw=#joTT4bms>!=giDD5sk`gMZBeW2Di254^7+wDHZ*n!oY z)}t&2*1sgT54Jh`Crz20Or^mt$HM=UHsB>#lLUnLL&+17Wbbn62$QIprE0hTZed6-sD4VNpovb*n6r2DIq~; zR}*>T^>^m`MiWv1{RD73|0C(HYP$Qr&TU3MKGsXP_!+G_Fk6i zgK?QUxDaLxXdKHrGFOko!X(SeKOH3qxuu&k1|1O5)|ENex$N_4+)~fuz6Lz0&)PqYkK_WBn&-)8YD@ZWB@77ix495Mm#(iL* z@8;GZ#CbSZRw`bC5>Kw^=D#0o^X3BgMh4fBX-CX#5NDzEP__DZ52p48JeCa zk~Psr+t||jJb1lgRp`ea`qoLyGwV-+e^HYFIGf}&wi`;wvS8={^&Fn2z`CR&=$)XM zK%UV6<=l$~h&WtsP6p9Aiq_a2m9~J7#>&fJceJO5c5w^KMyoo@DXBuLQMn?UzxN@P z5uv&zsEocwM&Z1HoN49tjnO_2eya&7RsruV2s6+K-~4=kXwxMhAp4=8twE7-0Pxy0 zS!?ivzo55UQsOmm4BsNFM?m>NZHXklGHUm%&#u9~I0gXTh=MdxK_LohKXJux?@QV- zqo{kkaYK^n%m3-^N=^i8p4&5f#V!GEXVC@Tye(!QhaIRfnE1DLy82WZKNx1-$EYn$ z4JzeP*a1}|Af0Ua-&A+-Oy5>z)Qn3#Nz(vSX0ip^delyQ5uwVg->B5I5%U_D%iPI8 z)d``Iw}Veo03iaYFHI_Sm~s`nm>z=dO0glxU9q7@IOf*G`=Ga6pd3Ow<5?1XUl_tU zK!~?Om56^bV5g*3>b|u6LMcl01LL;Opy^TJO*_!E0MYw9V+9=^93a6s$rA;}D!t=7m2d=hT1-VF z3q14zMI($5TKzYb%A}lF8!2J~e#=)`1>ptpVSpBW4 z9r*ZJsF>qD1x^h}hOz5`gvQGusS5CNJn$v>#(_Rk?X(P~Y}dDr^rH5?gL|7u#zL0A z1Hf0-5>SYkhE-yLP@Y+iuX$L@-W0Lyh|WWd>>lLdWq3C zXZwT~`ecCVs{Xna-LU-Q_fLpZLBxvVK?|d4%J3$bS!ki`;^lH{fylk9R&^-ZPyXMCm*i)B6D5Z^V`XhYCt!NTmK^Wb!;a$r)1F+OILy^T8tVKDK%d?TlpuEmXQ;A z2I^b!@G|?%W)FyooLmttp>bcfiY-eldx%X;DW(Y}pxpfeKT<6;zv936+aDtv3tf@G zjoJT(*H|C!=(bof0C5cIQ@&z+8Obo+#|zT3DnjExvQ%4O1D&trxke)`)Jx1<{TQNi zWb8famM{7pmWoRv?QR0pg~Ei&(Og?j(=eU_k;uu=F3}F(5_;;BTNk70Fa*W&H0pSP zCG4~Bw^@=uiruC5URQds!o9AkTUvshsB`kEiAzU2Uw|Z2LEV!tUYjm5b38vKGOp6= z1G_>dFSWK+`mSie*OPBVqB@4Sv$cuEkIV|AzQE#_Qwi033bPo}H5ksz&;G2iW*=YS z>tvM;$o<(HK6mE%3a+NI!fyM$P;sQl;jt!h6Pi8w72q-*%5F-7D$2Kl0rp$%vC!{| zrUXad`@P939^n3?(kV$`@v#amK;LSs5{=Hy=IXfYvlMEeusIB+0uhOg zWnP)-vx;u*JYG-NkGbrPO_ zX!xC(st>y>KF>U!{KWd}0P2Q!BjMX0*brHYK5?zLSmvRccr_O2$C3jTdbo?}=#2S2 zSx;BbptBwWT?K)_(jVP~=7A@hUP_WuXb}CuZ??QrPv|&_6-u|WcklRk{`*&>wgoHA z`XVL$T=EGwxA$zI^PxnU*)zz-Ptfja3Kp|H&B_X8ge8APL!2o&JI*cR%_UfvR$Izu zV<1P6s>tD6ox$+?XY#tPWyWJmm{gTKpvNmBm7kqI-FB0oiG!<*u&L_c>SeE3zGVQ; zWv1TUXpnfirtwuk%k4C&_w8-O)#2S`56d~bvfrHP-EXH6!a!2em?P3U@VPawOSZ*V ztovTY3~7+}y5?JTs|0)zD$Yf}1>Rg7V;mBd;NmSm*JvgwXB21P;+QuIr8vTdZtqG`*GPu& z)tVYXW~cgK`}#9+tGyD1)Pa%x@-!Xqt4w4~+9^i5<;``n%EKh$R=3+r*MtG#lw|v+ z)|Hzu{zcGx62rA06&JJ$Abm_%pO!v&xrq>!F|u|PaN2=B(DTC5-X3b+#NJg~#{;sk z756g)$r9X>lB(!pI^(4Q`{iXFk7q+MpV3&GminOKqxx2kEol(EQlmdo6>`ewR=cwd zkh_b#W7#_R(~x)MunLVzk%P7_$4&Cb={0(E{+K{g^m-E`LipSAW06y;O=xYy7^26c zecc_av(^F+dUm;;)N6acOU15uEW&t??SEvhGd$otLw=n1hJu{W<`D7LKGcfjp~#0MA?2B_v_L4 z;$(}zyxjAq?>QB57}XkBQd_Wik5nse=~Ct^hU_kxDCRs-#;nC6okOnef>E|RVypR| z8CYyS`YOJ~K1Z0o`G;yBx8Mgh-WUv>+4GH0`~-^2tfO%?TtY0HkH(FbupTYobou`x zeLa^tmR{qH!us2>!YXXUK^siyXAz8Ib`vs}YBQC-3x{vfaQn4e=3O|-)B*K86MLa* zvF>a2savL2=W*3~E};>-wz(lSO-~fFZz1kcq!{VmDCLWeCDvhP{ls|1i?Ua&6pNZ& zJ2|2H`#&Bra_F?ZSv|F9W=+X5bBWoTlif9ICzw*I5O-)m*6ZP9w|_i)ZXzsmjp|DSule{mgDShTpXR=bw9)$9_#a#>)A#EbGl_(J2-4N>Sd!vb?@#+;0ot?Z`gO`|-8Q%QM>@ zAB(5oU%y^Y&##jrVM)DPBsgs@_0kDPx2uM1p3JXxt=e3;ggJr}C)7VADXlFH-H?6V zu*Ym`!MjKCLzzXtetsJY>^hO8{fw=KpYOff?ebQIj@^&1NwStkI%#Zi*FDdA>Bq-& zcHJD+Aw>sGb#sSaW8IOt6y`@~`L#@1d~Q6ub8G5Uh_#<_%f9c4 zq#yH0Yc0**ag(zO*5xoHS#Ep$ApQG+METqFl=~?vE#gFudqo~R=v3C36$*cBCeb=p zC0JB$$njnC^23^Y9_MPK=gB9HzFv=dH;|y|Y5wythw`gy&stnXLzUL_8qPdwI66ei znH^ev>W&Ph`$^r+{@Gn(2dTKPTkao9vf#I^sg%HLD8U~Fp1%bDTbg>sQk%QhM<%E0 zxRiRYv1J_#%JZ$C8}PULYW4KPa=XfJk}ejKV@A~9SA9ABMcbXseYI9Z@A(P~1-Du3 z_-OTd<;#RKWnlsvt<`F5Kz9wP@0@W^)Re?W>tqe_H!Qk0N3QlStc6A-75Z^sP>4Te zxjnAt;su3~Uwxi(#_X~qdVZU1U6z)+IJ*?+_my)cO zh5yi17iBx?f@g6jdh>UmvUsUBdBJ06t4>r_}t33)7unV!ZzT zJ@c59^S6bx-OiP(&y($B6Bg_1 zy!#8&Dp!WrSJ&!Q)+d@(yjC8jt)Ggjs#;4M>Tq8#orJ#){c-(wKd;y7D*TSP(fUwx zRbkqGul44$S?hC_d8;$a{az2(7p&8)E7zN=;2+|w`&hk<>yE6CWRCVf%e}Vzy$xqt zdV_T}C}S#fRK>8&i}kvZ!K?lSmM1rq)}`j+o<@1?aI|`EtE6b&>bzsyX<&y2}9>#gvXum7kvEWD(+^Ai91&t=COzskH^FKjuQ9y%_4seFlp z{ix(r_<-lShFAB}LhI6xhxb#zuO~Ve4)vdSG*mUXeQj1o;)tL5=)|GfYMU45bGB5T zsrzz)!OJL;t5)55dX9neEQ`UmYn>t0xSq|^8H;;oLf6DEhuvXty8qE2t6TKF;zN&h zij^xPsRyR75k5NhsoYfo^UF8{VzmM30d4ublS?1m6?232) z+>-lVFb} zjyWA~PnG4IbnjZl>)6x6X^HoaFm&wHi&8kW@5Fbxu}W_mv#7yu16-nwNdXrJ`ESWb z?>^q7a5zfoVLxt|d=wT~aInz&G2X(uippyx_1={$IzufKZ+x?k4_&*JNFB|}#Be$} zp~xcL#KYy*oPv{xzPf%)oSbuP!b?&kahYtF4-bRqdhjd^y;dh)zb3uorWl92ReIx4 zGIcZ~%dq{qWV6|>5uu=Q-Ne@xRU)na2ZMqyUX4A&plEH`n1dKdUN}3bAMYP8CUbJA zEXv@}k^6N!TbC7Fu#09amVwpxLa`U&ZnQKQqsiqc;$kK>%r%02S1TU6vsHhvz#Or) zTe4Qe;&m-4+cgSX@sGO?4i>PoVE=4$zZ3gs;nqDO^tm>|=w9iA$s#-~j@;Wen-sm6 zU0&1`@7R4TYWE?jJN2(g+2Zg0usk$$?%?3g;`r^b#U_f`QQ=mpaBxSh-H}}#*=`+T zF1rXH>`Uwc&e;ltgj>IHi5^V8WoH-tI^p2<9mD_EPadxajy!OQs_lX^K)SWnN1mNc z7IN7Y5^Tlg_>D7AFX44pbnWTE;%AG+E~;6*Z?g1L&N@ zY)ut9%o5rN`!|V*yM(Ne0wpPS84U)zjjIN1FlkK2?8c;55rb}X(@hrmV-UOd3LlRA zOLPiz4w!)uee9m&Lqfr&#)I46?UoOImDTew?cgA*r>xS~MFZ0@ZAQ?waTE|bb7_`? zAfyplY{gDaX%~I&OAv`ISB}s>lx}y&r=y=U4=U{>k&rzYeCg@ygUmUGgUN&&(0#^Y zE{Bm=2tpE%*?sW@iOGd0#TeN%!mZ+nZ1biRE-{eF%%|NKok&cIqF7JFolX`6rLsq# z9P-vZbWz;>o5;arKf6ILL>e;)RS9UdvuKnf$Y@8$Zf&G*5rV#JT|_tE7II0vvQu1i zGbY5IMjyg?e@VM!IM~ogYFMpnhe>ohD+^S?=WHfm?S+wE!1>#v1q6|t( zz$bO^rHW{B$BpamBz`@T?a~Ujnd{#UCjalh51-1pNgeNBt8_wtD4C#j7Q_Ja2%L(( z*`Sc$<#xBlDnmWK4Le8|X)NyIt!SZEYB`q;GTjCC986}h8;rmxBe;oZoqzIn60q?j z-@m?00J{layhm85wRj`ndS}CuvP7PMqev2DI_OQKe`FB2I7;9G+${bc650do_9oTp zmPS&k;luRDkycI}IZO}Hhnd;Y{g@Zwi$IGa84ym9TKTiWD#D@fdgY&;F*&1Rd4wdCS~)O6oF{zq0$+s)`Q=LFje4-1}hIC@KWDrXzJF7rr6{HMybxqkRd+3wpV z9(DWN6>{PEvA30fv!-fRT$1jT)5LTnkl#GK=6P#b*OvxD#w6GUQPB*Sz*}^Zd$(*+ zMrPaobt<`~Tenq+{?6y#5B&sX<6iH&bkY0INuijz#3eD;pI=2Efn`Goc`3ASXp#Yi zn0;a{KZynfe?^H0>8s#t{BB_MM_8$f{@}iUzFEC}GVtb!s0NEf%X3X6><#Zl*-QNn zH0v?%wUXAV@8Rd<%<8{%LZ4h(=HR^RBaS<#i_PXU!@}M=D9JV_rJW)?#)S|MExD;cnY zd-*wJzqQfwEyvK-Pq_X%(oimkSmR>*yb6N-w>j%B-Z`dCDy(Q?-*x%*|$ zg^J;H*B0TZNF!a5a?OgKFBB|u1^%qNzcQYbS)S*~va37KVy4@g#u~txS>|FUlpw;i zDMmm4Z1%Q$Hm}9br#1#RhfqZ+iB`;~OVpj;xhI?QOf@ta%foOHrB!%gXVT2}JC zHk;(N#vHdP@jPuAprN{M*z9W`F z_u~v>F>)z0r(@*2)9q9aMI<@t+XMH>9~z)5GT&4s$8t8*|dx+3Z<+b@<}Ck5lcKfO-NYqnEY zM1XsHId5CvQCA6g0snIIPArw%+s=0jB}s|_dtcfO|4f+~3ekG$7Z9|$ek!iAoGnG2 z$ENt=io`CCTW)hfo);QgUg83j`AqLCIqugM{86p`6|OD)x)O3&n8l8@=f^wdYKEtt z&$aDe`rzL#1Rc4M!x2j<5WjZQ;FIsr&u!z_MjT_$!JAptRNrpBlkX6I=ApVfoh=K0 zF^4mjQYcZ9&Z*{W*QpoTP5!y>t^kepMX5Om&K4%38+p<=~E0Z$$u(At?Cztyv zz)1@&8g-Mh@0qJvpL$lz=hR%!xjxdz?03CxJ4RE$@o zX>_FtuGo5gc}rRaO`tMqyBO7+7JowPvCPVcqb4|}?13UtKKO;5J~97B@lRhjHBiqh zg`Cv??w(CmRK#dI@ceqlbF|T@_!T0Kmi8{wVcUJtbY?Lj+&?KaG6nRlJq4tb%U@YL zOYRABT@bd0e+rByF8I3^`I+cZ*o}_Qob8iN#RNh%VH0>img@Ce2#MC+ za(>CL?A+4N1bfqgwb&~<(=>Y5O&WGGt8rrH#Pf37m!V)r2DhR!!7u5ol(}A9AMkjl zo%5Csqe2u(~++LeU8s0Y{h+f>qFiPt>=5nJ^*jP|P-|IGW)&Ohl z8ZO{8pJ~_BZE!&Wv23)Js&WQ>xVsQI(<}^M4MW_5^uCyA3`6|zfaJOeu9HiUW z1$HHucT{4=W70xzCCyZJH$N*uC?UIOi+M{`p*WeMl!nu8XX~bZGgq2k@4DY#Oevhr zgZeH!h|)LyMJZ)A`S>Ko1#_xr7y43pK<48K!699WiqcHAck}D7nuyU0`7vBmS7+UO zh0SL>yMPiHSRdT>C`r36g!_4j4LvPC$6*hPO^v5CT~Zsl1y0d&eLbhxdp$xQm+l1+odpr83Ws#-%+M{ zTmJD^;?92jkiS~xpWx5L+*}G5^>kpKeT56S!DlLt4pNcQ@Y?N;BC(21vEAl}0wlHS z6hU*l0%zeMWqG6GLCS|8f=JsthZftdP6Y3+^L}Ypx8+136M05{-DpLUHtxKLlv&T0 zPA)kl49@L7r=uka zY&rcnbBlu!1+6pch_*b8E=}Q|?hD|OL#`s8BS|)sWXR-gV9AA++H@k~u zVv9Wd&+hrPv?(b-QDX^>8x-aWvApGeDTd?wL!mD25PTKSy+IGeP)Z7@F^- z&z0rV(ZVt*k;h!24n!}T;+02QbU|R=U{{E`e-3<upZ@-SDujYD8Gr z5!{pN{6_;^*@7_~j5)G=o~ZtK<^g=3=ey~VS(YS97j$C&36u@QvtzHCL{X2@Ul@xd z9Uw~G&Lrw|2&qrq3od-AL$7vWD^yzrB=3g!TmuEBlLR~^nEl4JC1yv=>St6CW} zekBt4Zh;^Vhs^{t`9pA0&WD?4<16QDy$J-o&}I@FIILQL45yxr4HWf-M>F03k6j!T zN#7e`v`67PaZg?DK6%n!pDh23P{65Wm+H1t%m;2|qkdQ9-hTH(tkup`L*lm&&sPRJg2LYF8OYF< zJ&R$&*$Fqj5*DJ2Y7cq$EBe&|j7WRU;l@oijCj^v>yynzL@J}GVI?N2@%s@Vhs~UE zn35H6LFD0U5qXhDd+<)~;)3{E-G(5< zrC_FOOxypU<+jR`haP`fg5uty=>^}}TMh7V$H@1Mj+cJ)0AuSUurP9 z6Qsjm8ZbKwe(hEZKL5MNM)SUT@g>V! z-Lk7EcVcE!05WFN#Dmd>{Iw*rnAC(G+7itAhLk0+>$iJdY-If_J?IlkE?NG+I3S9b z6SRV{2wF)gj_6NdXLEw)eWg^uZjT+ zzafYEhkc^rbfFIR!5BM^1Bwdo+iMCZsA_4!1_iVsX!b(yPrAM+>PV)G;YW&JrFefr zB1DeJk5j)@BOjg8fe95dBsfRKJV|WsTVc%4&SJM={-W~;@rHf|dS1+99>;oL{3?; zh!I9`&Ks~|bk6Sx%tzi0?TbF2EtcTD$>>&-Jb2A}RO(Sd;M!KimuGZP1ci=7$CB>b zVC>}V8VUr_hs^0?mP{!XbOvgUNTxHaK()MPqeer}L=>Kk^RhA=;{Z+t$BYw%3XM+J zRy<~9!2xo>*g8M?BJm8VnE^EN7$I z^f9VUq3F2Jc72(ZMq=H!KpHD6i90S{otd`2fu3&GD%T!P-&h&wV8;s8KXue+0Vqou zw0KdW>Z&ZqhxGFAj_Yb4{;!`&C46@vIpIS%7`MITZW{WT|D~H}4J#L+dy(VY<-OO0 zST8zk&3?s9#yMoO}C-G_&J#sNi1EZ#_rMwV0TR|GpPpF)mriLYX z7gGuAXP`br<#9m;vSg@4hu`U8{eby(8IG!_F8?8l;RI4o(H5j0xO{56QC0jNU2Kpw<~=g1}KWJ`wB(L>-5$JAYq7r@Sih6imS7%|j_ zV~-Vn4LrF)+=OMUWJlbaGPH?3bI6GYBQF8}8S4Xxd2%E{A2)@h@^4z4{OODlZ-UWqht~lVaoe<9+@9pd0L9qr3 z9<0fna_V*=$N+Oflu97|(FLV&Foqu>n6umB>wIMt;R>KXLY?fV?~l0`i9v9qRYZq+ z?vw!6u2$Biqgo+;0`=WSt3wbhv6bCEecHL=<`^D)1nl<3Xa|(7bu+0LPbCnu3H>fG z_3t$y-EKXEuI#UrUMaNnXa0zvW2DrOS^mwFWjq9qjxhu&9}5NuEujnIMnUCo1V+b% zOCoaBa7^Si^d|^f{oANv4F5yD;_+9m9|<;iV*d0;Ea_k-w~-hw?v4HFQmiYnCHc|(r6m1C)ocxBYz+4;)ee@{w zr5w2m5ZynNZUi|1JunCI+G#2Gja+zywlO^+f^?woKh`W^w)Oq>HxOF(zT`%kA5PCT zS2&X-o>0~c(8jGM>L73mwtTJLX%t_;oD~QWTEgtsQ6M>haYSZSfN=a}*DeIYeDWbRItn!k0gsEi4mOjrjoWPVUR!v2;hd}N;pFNsD{e`|0 zGf+Fxbd8j5g~d~FE0PaUV#R)hAaYvd|4scO0h7W!^?17}a&EP{alz=bke7`N+&?hL z6Y^)eU1u)wzDH#!O4w~SRTz&Fw^Mz8GPjK2oFMtn4k1xM(q*VqA;0a-%`<}Tg*+oQ zE{ot2hQ)hCpncU9@!tEMurf&zvwM;{2ySEe`HraPPl}We!T7+6P^kuPk96t)I$fZ^ z6(D4cvQgttI9d4RBZCzWSXC;==Vqh2T?R`WkbBVWcAF_ty-9)Po*fBX4{Vo>C^p2F z!NVB0tWALrKk zYu`+JJLgL76?z{&UGnteqw#4pO!KhKGY9)>9T6la*tQci!??i8^MHU zwI0DI-fvB&;QeK#e50)ovStF8uqm{@!q8hToFY*9YmaD${^i{w(9~z+zTaQS;9XZn zFw4}DSOn>mWSqoBVj!ed)1EpOz+jCzqwjCMUYP+OcIzL+-Jy(+VB?Ms1|NZyX#LAQ zV%Sk4#xl#-G{+pp%k?Y>J=N_-4VxiDrL#O~ml8JcIoh5~J zxL^l-f(>G%HrzaUJ1(QU)a^z!)7+H3g~yA{yY-E5q_~W={eoatmPSNS!ANv9eS!f( z2>=nEHB|NK8ryVJ#qyj;}blkIdl0iM)uUf zr%?Z@QfjFUkCf@6z89(|BDnIcZ2XhM#c;CWfh$TIC!=0e41qM*0>tWMvlN+IW{^;H z=pc_i*j%KM;#Y*8RSkJiF!c#D1Lb0!_xoat(Pd-Q>Ol97HMwMj4v7zI-;uAPc5$`^ z{09(#Zx}gembTx)pV3THWD$-|>d2dR)ql!EDN=M|@yBPzBK zypSjV7En5;K4GjQ(`__4E)PB0-}?YQKAcZ~RvXYMA)%X)Qsqg_YuZlVL3VWVV}EPF zqJ=u(d;k|K749+RL3n-y2L@;VAqCK_HF2XXA#}(?!ehV>OqnA8GX>*@%ga{ zBiK{|*>9j;)y5r>XC{oT%QAknls(tMk<$6Xdq5Y|=l?npmWX(TAr)h*3%B z@g|2=A*{UPzoeLBn)WMG@1gCH92gcL;Z#HJ0m=@)9%*#N!4e~6^$J;$e_BW0+;pUo zPWG_dsR3!UQ&KmuWr`Y5HKVGYx5`-Pg=%%AY`n*zEF(g{dCIkJC8RZ(Yuam}ep_wZ z>CPkpIU-mITx^2G0xfAnkmcqbFA& zK9fkU`HT7Q2LuH4O+4AJ>GbRu@1L~|kyWe9GxFmU+cGD+%CF`h3>Ul@tv{BqLmA*p z>2)|j4pbb)VC+vVVYXOe@CSY$9-*mdDCQQnBfpwtXToE;OO#V^J91<|#cd-eO_&A}YA*B5Z$s#-I` z_HtETRgVzB#EoRZkFPChmPgqhn8X9TAdhQrXD<6ojS5m$I|#v`QMPe z!#=>3QtO%L??h36itig8>Fn=5ByTEp9x$j_EMrI|Ad8atEdxQqb?@o^w27;r zBsgh~wv}sYomMnJsfHM37b*_eLBa(QK$n4HDkLq2G?W&Z4*ts8dff@-8Wj7Njkmb2 zoZR|66EqP)uZo*2-X9DY>!iZIhKBU_bKLF z#&Sy=1Se#Px+3mm8L2aR-{Gl>AdtSyps)*~e7FB5vZ9QaX}Q`<(7QAQk()CvtbDw( zi-7WDitxjBK@qw#^m}z?UA(?Af>3|x)x7!|65#fAPFPB*6 z-wd!aAexZXu{RW`>S!~#HnKdCxQpSsxJManD&RxVr~uaxVb~zT*l1F7+K!ZAGJX~E zfbi-EaMuE&g_B~EuvAI2@z zwYIBz?CGti@;Ubu{jl&m5F}eZ0{l0Pv zECXy2tBf$HURX90gqn|~X^;<0)$G+@=L0O>l;Cx%t?)vRi3o`ik@#+!$QuM@EO!%N z;ZhF>hAORkP@5uL_-r;4=ggbx{LK6HdZ@kgF%mP=?!r*0%=>kyO9QcaR}9Z=zA(Uq z;p9#7(3Se4!4<*3$UAEN6`&E{4FCrMsVhhru6-CrPH(4LP(GDW z-ai45g-J^l-^3}vqNs!^YbDTl#F*kWv2U9n-bT>VJAJ5z3D`O6WwW*5RU7IrgtLB4 zgpPPScDNc&R+lcw4rXE~Yt`t2Ofe)jMjr!jH+CR2^n1cTpZtMG;fsY`?-zb5?Llb8 z<(M~!XcG5a?QJj}6#|s!ab32a;|j7}CQsvF%$Mc6jZpC4v?UmYLnGMy2*Poo_q*W; z%`|Xv5_|{8)V;{@nc1pt2SDJ6X=ZjpD^kW#eKY_9*}Mi&<{Xkw`3H6d*@_VM*tzz+ zL1EiNq(k2kdlSHN1hTW!+46+(9|JThgMlhS39U$@Sljx}DRnQY%dWgvlOw0#VHEY2 zgvSS5o9iw+e-3V}xq*Yb^&90ox`LSgUWIzw6f_J(c=;rv6Nkaf5IDi1N$C$Kqd^Xy zqb5Y#aQZPG_V+o$q=n%Gfgdn;A~J;8axiIeU#0p_M-d3K7)VbPOfr}tHVwi_1asjl zf+K@8H%$2wGJ@q0eh8W5gB0fuaGS&u-@d?7qV6*ZeuYr7;e$b>E@Y4I9yalMQP}sC z2byROMrfju2%#Z0@NhVzsnUcY7aMe8Q!Wq~Ag9m;MPr6Zkl6p+fMq#M=c3@rZ{%SB z2-6JURK&LM0YY5z`rOqSTG6)EJl?rDj zAA~H3*~v+HYHR`rHB-9@fU$=InF$553JB2TgF?t9&?6LR%8FNxZ$ndmHc-F|;40>Q zYIVQ2J;Y8$L5*O?L!Fq^VfOWeH_$e;IFl56;+qn-CpgtWC!> z#~D-wlPB(wh!E~KNO8xDz^mu4E1%K3UIolniG9Cyl;BwsjqgMDul}TvP`Pp$SvT=< zLc*-xf5Rw}u-P`AenPZFjNzG-NaawVyFv5-$lDkaNx%=0ZbU#g&?&PpLSn?Y_=LSF zLM5Ek`&+i|3c3sC1&CpVmmnZ`i6mmSz37R|g_+!r1xGZS|W|EsUQT_9iB5`!)`Tzk0@Y_3{y-vuL0rd3cU>y>vP{ZoCTI5Cn|tAh=U9gpNvaL!Q|CCgcRoUZ)d~ z*#PXV9^6>VtwXRgTD$eXOydwl888hHI|f8QOXXk$O|)Wp;|sxh6A#{S1Z>|>?jPl; zx~J=fPouZM)mDlNfoP)07%a;KR0U)&T{Q{sFa>xBQ1wx0=bML!3=U;&#Uw3=9#ROw z0Mk2~Jo)beJOFM)2h2q`j2FTO;S21AkX%mR9iGK^*{UX^_{?gP(4 z;uFmLbpw0P96SfTEW{5isX#A)dC`X5fT*UvL7ZYCMlNpqOI5^ph%tnwF9EFpJwc!% zu-p$Xw1il;7y^j|xmhQG;0UYkhOD>20?K+1{>gfAsV1Gdr?VvqDGW`pYK^_GIM85-aX>DW*XEER@{!q_Px!_6M<&Sw(DYu00VCeaZvt_SdB zxw?G{+MxaNfawmdz^sOFqbsobtoYvYeHZW=%qhMmjDgI|USkiau!0^FTrh!9Kwpl{ zHn5?m!ROjo`G7%Q$1#$z5aS!d22X`&@v6U9!+H0=Xr1w5QS4uj;ow2|ipA7-%Y{XQ zw5s)wBg;-Ejhi*J=&bo}WK@;5zN}yfh7uMgOjw{i{~5>yHT@!g`zU<}?=zUyaZ2iU zPIEwGZS(Kw7JUmOQJLJs9|cp1hMBGnJySxj#QV*ta)Q^TBS z%jIV=N3nhq`W3+ZLLOeah?<%m>RRUrZ3OBcZ+(|d(MNQrwL4>jLC}CW9kAxTtznJM zM$yD*HLtz$La$+566RafB%+1T7!U+}pBk6Un3q!cvE7I+S&_mtY|6!Rzzz zJ0F`xFhoRAH(nXqNkkvdG}eWgLE~PB%_Zh<6xyp&_Sit-CaIv4NVE+AxD!_3yF(jq z6=(|ZIM9nt0V0;rq#I(XJk7oz4fo6{(MYHe?jnu`A`M}^8(GtV^N{(GO!vszx{Gfs zM}=(!Q@1c-5D_866M)FTukd)HemXHYs&U}%1JvH4@l#R`3Jzg3e)kj`V1u?;L#rWc zv#B!ER3ecop4k>`*sBr$A6Bpq8%+dmn9U#XXDbXiVXZrwubd5!VET9Ad^Sa?JJHYx z&;oXIbA2=#hbo%@2nHKaX$Z2?q1%eap%DCl?O~97T7`gEvK`6-f=C?%CXj$iGN5a} zWVvA)1bP8-CvJh6Vkxya9suq)n6m!5olHQ`RTHj5O?!p+CYMQMKXDw-Ddc4{TS^*Z(EDX+jYs4!E!Idl&`KNQu z;vq9uigm z@28_kZk{nw_n-1j*z*e>S)C;G_X4;K;tG0j0cNy{f8Y0fQyRe}Lu^jb+2ds=*l_}# z@1UnrjpfTUUo#Po4hXvf(nei(gIKJJX`^d9_vd4KunzJEO!e(cRb?~PG{pf;AG2ar zUQB-T!S3HjYKu`6Gy)|w=mk8eiG`6JHwcz2OB_M_sB|Z~(NZ2e{uM2LJ}2i732kzF zniFAa*oHNd$u#9dv%1zjOL$BNuUnf>5AiLLNRYzU!YdEf{wl+JMyhwwKfKh<=A1z! zf#H~8mSneNd`BN{2d`OpeDL>LD`=QI^GXU~6==Gif(KFgVPx4=zV4qC^$g~W6udZt9npjZvqwu@OXF_C`a?FgtomoEw2#| zV%g}wb%zaxsi|l=XW*%kFr_Nxl_&DQL{9v~8UNfJNx(rl_wg#_*58#`CkZ09K(m@a z6r6@Hi2?w0gC>(TkW0lV{S+R%;3nn{u__>S_=P!yNnAl;3}mD5k2onyQzMv$35GX5 zk_Z4RBwsLvLm~u1pEkJ@-q~g;{Qor$VdKkc1VydQ&!$i}FymP#67np(z+S>d|J(+| zXQ&q>FPPcxz;yFmRZBT!LBDgb^_#&Ur=#eh2IQ})L);!mnYM(M;fn@S2ubIo1~4pFZGJk z1q9)KkY^*@9@;*FO(%Vj2e}^1hVM2onY{D$@X`GGydiYc!Tj4+`(`kiAR9PLbUO&1 z8XjsNP9tC4o>_j9Z`#63Vfhu$CQ}$YM61YO898UJiQj!)b4np0wIPUKVvwTZRVC`P zz-6ZOJ0B07mg74jjh=hZ5Zr=3W(HUb*vbwwEkPOFC8tToIrle3XgXD|WP$%&3m2whiv7c!(JMkqP zj8FmsvJesW8YGGtCf26!J_eQM`R=J#WLBq$Z)0o2Y#TUJo3>0^XfH3>M1 z9Xy{q`Rx%0<9l-?a3n_%ILtp{R!JoA`?197g3Vwo3dTf6^}?GHp^HH3Y-+@Bpa4M3 z{c+k7OtND{wrMjVIR5R(y*vvXB}AhiIY5~Pz)&gbuZb70{_da!oxaaBZv$sTEIzi~ zO6vvatN?k21eh_UMqU;?P9rH4RPs%faWI0>{t-bV{%_~JIwqcwSCijir+UxQ6GjUD z7o~t#xSn~whtvgWNDtwI624(}$`B5>cHVulsPP9MAS%UsZ|xT@0Fk&lk=MVI}l;vv#tx_ZeyI3x7T z<6rx0#z*1L5Dq>pGV=Zxv7yLRQT`xr8r=vTt@rs)ifFqc^-2x-V5=} zhOC7(H0Prfu#Y;4Ca4c1LdZpEGr@B|{PPVBT8IiJw2QFAr2E8OM+0zNpzj29MSd1A zQT77z4ygX+uF1s?wrK*dqwNF={~-qw3nnp_k?9*hbH8^)8s#}k7^s?Kwn=FB{u+%) zhqYH>8_)T|1aDTO{tXTNapYFok8k^~f(ftMym1U4-_N}|29Xt_I!y1O=8G6U{>MU? z851Z1&>gI;|2+oUi|xJ*p#(sN)!cVi!{AqHzy=rg|Fa9}8gpIfNf+f!)098!ikvE_ zoEb;fe`7z^#*8CQ%DKTfLANUd4}osvk>A}NZm1+V{=IR55MrQ@C5q*rSP25aVrBR0 z)!`unXY@U4{g6l3oPyHfPn%ht2HpGO!?XQY--89jEiYYR#%5>xh)zocIvT|O*8-T^ zLk|=Kv9ltl&KX|0JixWAoVWSK$*?AOFr`5XQx0j-Xk>mt)O^aH^BjF& zkJsdnz4BFkKHR2VX~<`oV;~lzX{#r9SAES<%XNLt`APis)VBw?6SMsD9`j~)s$8m( z%`Yy|CapWk_&jN~U5O*6Q`4M(U0#x|luO$7=Thfb@3~h}!lswW&B~TXbYIKn)27L; zwB)&$ZYgz@$oL!*W|mUn*=*mkfAN=L;K|s-S|;6*?RkFEp3QZW@}-7>4m01g2iasT zFSDDV%fGRYzm-bq&8I2NFm*Iqhz;#>bh}Ic#_o-AL?f?l{1EAVl?WkJ+KJ$KuX#A#IK_A4c z-3}G8?;=ae4}GNmU6>;hx(sb#%|%T0lI`PU8}@wy`i8z!i8j*LD0Xdi2wgC1ctIiP zTl+$tZ!2!vVVklZwcAyt8;50Os)GcIsWk;!&g>lMAep|BCmJ7T;~f-~<0E2DE6h~I z@n1f09@z4{ptBT#SdemmUh!4Zy^4|$I z>UUJRZ&`fRH7P%(nSa8U6ld4(FE!)zvtF6@jpmY(QngftMtnNO-ksH!SE$cD*fCD? z1TMWDl-j9aPAfOFHrD3umsceDwT~-Ij3voX1iQ7cI&bj7sZKpvfkWri6R*Ifp_h$^ zMFKY^QL%6-$s<0cQLh#z;V}I3`S=CMQj&gWlu5pQ_8cpqJ1i> zO4WJBTY;&`D3t?h4J;s#ld;SNdpzW>oBs#~O^kEVy=0EDX-LaGY+Y-x$V~T^dBrXN z{qnW6^Za7yd%C=uhY?qw1$oC&m4cAz>Q-_>yJp$i$&556%0jO^>zK%Q+`Cz>=*d$O zsjnab2LVsBk2ccVVV_=G?AfAF?)Ls!A%VJ8=8}i0Q`;M;O3kfJMdCMQA=RFM6Qwro z+RCP8?`vTba>^=N{HD)?YSqB-9hQE*x_!L)-JycEbmYrqBCa97vP=RUPH%C`7x7A5 zV4fVb*mppUip}=%94DRqW!q2lwrUc67vQ{S!`IE>|%chev`&hu)op8&$6sV-FJ!?WLuyaU&mF5t9G&pjkVAzTA8|ItqiB~ z+0_0#2dq{At3sc4xQ346I@^zJZKyf-gz{Mg+tO?=j+WYuVGa~lSWOaNJhgD}_O`Es zxRo|*uaK%Q{c9s>>#K|F%R|%azaFm7^;fO2MxUAg_RG0FlJne*%z?GGv>PkK)>U;Z zQ%vX9*Rs03mY1#@&ba?_UY}X5QtmsQRusCvO=YIdDunlWH}k^aiIN)&vuRGaH-lbP zH=<96tV^Z6yIbvX;|A03wuh7_?_F0g|JWAL(|wiVm!|9U@5;Wndu!emK7S$AniLpq!#bta&WM!g+jd%eTtmV0S`e^ZyVy~T^_t7@`gE_$K6 z)z12NJH-0z2w`lpa2Qa?W>B@8eD*`ZFz~uw(5(^@nZ$*XFurZ>-t{B$q^^^(B?Wmk zwB>!}I|a^9s(*%1!BPJ9go#Itg+u$Unoagyx0Gf(%kzdRv*ec+c03H|p(>BDujx_c zewIbf&$}QsNAFJ}Dd>>kqy@yiTP*WT`{?Vekyh>Wb^nBu(C8;=?lT37p3-F66#-KX zD+0gI_T<67t&co&76lyUJA8I;e|BN_VEMZ+yYl&ig@b;YrF~DsY_=~d`#r2Y@4#7h z^ytJPUiOF~X|HR>-2n|gdnS+hUW^gG+FlT6??3#>S&{1cPieTuG|sf5=)#0OXR(r- z?WN~1R>xVUDA7~;Yx{t2$)wq_xz6%8Qi59A9+xeDUzx@?2*|F7 z@Aj|ZQ^#iA3_6bX@A_!3G4W}f+nV+xlaqL}|3{xa-;Xtwcs4I)TmXvGxu2=-tvN5> zth!bB?(nvux=*q_HRX@28n_1@C)lUwPn&?sqy(?k@A!4wy);FXBjrND#G;gc{k$4o zxD^La?ko6ZqwsOJN2fkCw44v>BB8 z!TvH^+NNJY`!l6jYBqx*+FMw?b~M^wv#GF|Vh-$3Z=&Ss?Kbu6{b{XMW3Dap{K!I*-NKxD{jgTvnIdKPA8b9Ek4 zZPNA$7gb8SZi7&dHU3(Z3Jo7k1>Slc>aJSFzH#e05_@Oi+Klq6OL`WM8+lId>UM!o z+2`xD;zwdZm*Fd&T1yD2gB?axUXK@bG=f|p>#`m(7IUY@?dQwoT@*=+jXv9dP*+V zQAH$tJ#u!W!gOu(*o7W4(R-E6(#tPFRo;^{B#i_?hG(j~vzI#Z|!(HKxL*Dm}_ne6({X*U=Ky^=Q zI%yxHPE%dsgJ$m^)nKS_bhI|v!6y}+mpLO;KS{^lHQl=u9f(%gSgFQ7N#iZ71{6J{ zB4R?1y}{YsEIKBokzW~ih=)#Sc+jkrE}egp9SrAI|JQcaBRiZFn!PD&ocNoYwhauv zX+0LlM2|nZU1wK!1MZZ}nf7suZ}yxss&2zR`sqWJ0aB9FH$y8IKG;)Gbg@xIy>VM+ zFF9A0a_7c#(JLAe)QmhUYwx7UxqnLYtBtEyH6HN2_gkr%m0Ep|8?A-e(d9!tECd?j z`6k(E-!)l$Q&SW1^_`^I#1DZ+O7iTgNH|T@#WA2e-M0wrX8c=)d6MVVF#k#5E&`M9bM}l<^Blgk)KK~zSOa4byOxQShz$|PblfUKX2L5ezmPhvhe2&->TT%Dj3+jXZs!vmix^k z+1n1`*W?Zf4Y%=MI_B%;ludrfzt>L9a!KjOO_tM7vR(;4MyXjq}us&OjjD_kDk-y0+#T|Vz~C|IED+)x6^*GO-% zxaQVvNA3;B?k^HQf+xF2wJ6Pgud}q}SOY1AP^t~r4U~u?%$)D`r3(~RqVw1iyxD7< zZ26DIwH;E-(`lBzX0zAH{(yB`cb{$K@0tF3ch-A%N+)l!ja3L2G~6|hq;~yOUdx8@ zboAaZ`~D*Ca)F$-%1sZbp4Iu5U5xF02}DKM2l{G?@PW}lB&1!?Vn6*PKx(g(u!Z&Y z?!C1tOqTa{q$N3>ii|zhP;y{~vFn^5caU_+9gyfP>30`tE!=u&8Y-6`FZta1B5=%N zzhdtf?9lpXfm!Wq!^Yg;RWOkRsKL<^^z{Fer7TJ-)&~Pzq-l~8B#qu z+J9y1^$G54LWT`@(<9D3?kIQtQ7n~~w9indiT7;Z0X6=6uS7Y#wJC=$MQ^4-j&$fC zNeHH{eh%WDZl!}CD^OxmtXOh-8pN}jB1{&rorVSi!w|AusX0}C79Vx`O#u9NBziJvONtA7&j(ikMxLOjCP$sCu&wCHSGTRLLT+3Ic*iCX0Cy8&5S2b*%P}_^69u!az>z7k+su`7h1LAD`1;*Lk(#kaQ4*O3nK) zRi13WY=N%Zvf~w|jV$MdP!$pgnBW$_Pkj65T#(o7t#+&ofpRJuuy?}U1jU#~n6=^ts%pL;?#ogV&IxkLe9=ERh(5Aqz#;45tT=M0ScRQtX~93~Wq>=2~KOL=+3@B+vJ z8Q($0NHBVmpPv{u1z?9zx(~hK5rep*sD-4o9P2vpIMKcov&TEiT7+*Lx+cMfb~p_) zs$isg{5<&+Q)EfK4k|KFcS7(gsm@5jg;}#A+>fb^o z1)NX{Bd*wYU31Z_Eu55#f*Or~jX7nX_1Ey9PRVSRB zY!3{H5E#09j4a^&@Fk2|$a!6zlkR^_obx5m3V~}09m%#EEr`o^<%#wrthVJF;Ux2!ZCZbNCuamI($ji)pIlN*k*>N5r=T8sEbRF?(yAn z-7Os~b)i>KdT$O!U>8ErA*o)sY!Cp?O|<{_kUAvu zb3+PLu72GFu0Wh0ghCCk4m<`uS>Q!V8t&qm-VIa){H!^Dxw(2WQu7GJ5W=4S{Y?ul zTna}nCsbrixM!tcC};r* z$PML5RLPQaEIv>K7+&=w9ExRr625)SqhC%QGR@aw+;xJDIyC=cyz701` zzRg?NPUuvu&+T5Qeai_9BiF#9G#H4?5p9)bDntNQfKdd*{IiLKbs$o8qJ(&|*HcrV z@)MZRozfOe_#WbrGe+6f_#tOtVFT$Kach)l?tsz?kuxk_T|-Gk-dmaMWFhiHh_0~& za&XK$n-kL+&&bd~?10+ONBsm1O@dnebtE93%)iH=tD!*I`%5Q1BFTIB1HdC-!dG^J9H$-F?V1YLyah!Hj32~1e*f?VPK7da5RCL zC2jdI&k%%`haTAV4LuYA5j%9BL!}BT$Ie#Yb4`R#?4E{b8y3DJ(}@9I@?SMz)h)8$ zIbq=IGADGd#6$yLf+>m+ib236sy{z&dGK>7^(_S$VyGq_i+>Pk^?-+=N=SsBu^tmd zzWj*6`8mo*NHIxpd!3G0>7;Mc}=Lld6RL^U47k+&N3?DME_P!rBpS%TC;A69U7`FX@RE87I!zb-glYY6NX%Hev<2CLmp&owoYL z!_ysIjdyxanatWr%uCEsGhStQeZP8#XvW0w`#~k8F3+@++tS;=sYd)cQEQf=_rTmi zSrsxIice^TUHbCJtx5&KUIyax2s8cXM6DkZ{7}iCY@qH5X7Qr0Zd?H5eHgcYvl2X( zF}Yc4FZnmN41+3tzYo_!O?GNjTjuiQq|+;x;@MpVxE3bg)t1QYD_U5VCi@sp9gJ6w z#&(57i}AxhnTt+MU?$H!#H_EptfK$jQ`9{~RxVTd9%$QMZ9dT-3O?Kn9uzpdGy zs&IbzDUb#1HN2L(Vwl}yt6|}zSRSJ5li3In;LI5$zZ*W%VZwgrgxYu z82<4_X3frqrqYN0Fd7tl{#Wx(rM%4$cRy;V;ob?G$-){7GL!Z@?)y`>*2cM|YUwY{ zR*I0!zlt`voR`cwU4Pf?`sr_MDf)y0Nx}`MRSOgMcE|ZsIcl^~ z#JCPSXikneOc=vczXBIa>@67yp9fztSsqS>dhH+6^M;b%!GZr`BFUtNjapw}xC-h$ zR}M}9R+0HS_91Y4UvB(m<$C$4GTdes!#u-{9>5LvZS1Au$o-CAfXf6nk`nz+kRJoJ z;|9p}e$go=u=b}JUe&s0cSdj8Mh49NJ^|kq+JVC2cErHKNx{`pj4L#h`oGM%2*Jk8 ztWz!;5zAVd5j1+B~+sY*zQa>m%!#W*#r=-V0m^p+U^PHf(lE`-~> zQfT+nQTU5IOwZ*d!ezVbnG6$F{P#>~t(w$|Y5&z#_m$AuT3DHa$(reiwJE|g1_0$; zlA98{u;pFXfGA+$1;4z6eS^K!x!|wilfEN_bs+!~4~5)l^6zOOw3Rt;#XoqJtq5kp zdm==CEi&k`RDT7_Qwpa&0=U(8s>f%3mAVoc)O+`W;p2ss{3;e!j#HA*A?Kr!**7x@2|+~S^~{Lv zhshWA-WNhk=iaA1L{&E|HnXd|dJ>#1EV%ROHC| zlP5l=5Ss;{E)06^H+HBY^H>5Z2h=W=oq*s-`3H?_9~0R!t6#qf@PEmM)K{pk#di!55uge(drk;y zqn4hj1?#s@Wk% zy2H8o0tY_S?f_zZ3Mf`LpX+*~keCV3MnlK9?H(`4yk;GId8v#-(bfG=yF^4$E!?Wa zDN+w;cx+p@3r(B?Vz?Mm6}E2Td#hx>6n6&4 z&G+?TpXA>FHsP$3dHmY|hVI9Gx0cOK_ayc3a6JKo!Zg_v}i1}j; zyf|NVjpK!Q4k-uwBd%W)Qnc{Jf|ggmg~q}2AMp#BKj!&2D0<)ea}HuYLBbN|TH-s| z=6`n%I28+(6jcYB21kuKl@mv8<)o1td&5cU7er%;+(`KVfqw&(r5M+^nelES>`rBO zyMwhB{|%xfAwUqT8ez@_$DP4}39}9=@^1)m$mL~Y_^%$CxtN!2trWP{v54A@vA3AB z%D34G$j7ckYdzxR$(bRtFq|m6ApHM0iq24^kT#HtgwFdjk)3f4Yq1-mi)RiT)F!ed z-^zj-jd0||Zsv9{UCZPnu&B30rdL|oTO}y*Edob+t8=hfL5#Oj;jy9x{6KV_4Qrdc z2gc06T67;SA3Vh(crv@vIXtZJw>=>Y(k7g3YoGJhdAUab!Vb0o9PlxpMLcX~BH=jD z-@JI0dNBUiSJyL zczy{TrnRB}r9+9Ge-HFgEF_;Xo`R76kqANZsitPix7qdd z(WRz8COLslW`@i}!sie#4F8MQT$(^tVJ)P@F=LXa<2^&UM~2U;xkrZW-|KSz!*7lD z{Rb!{TtEhmIYPZ}WMDQ!bBVsG7B81LN(3stQl1=Tx-hh3g@v|8P1C2fO_L)IUU)IV z|Jjgn0AzOpwtq*p@aUu4l9tIi9d{hmXK*@>Lz~ z83RUroD>Lb+H&3BLGZ9{Q@YKUANg9ik7KTXtg2bF)9pf6JU=hIB#{y!1O`B%7RD|55Uf z4Q*{+K?Kj<32z4xwV0{+<)0pDOL7+0a@qsx&F8ETBDo_5hdTTTMn zM?PiH2%?bQXTPp8&jMX*op4-LX_cWTho$Xf8GRGj3n2=5M8nq&%p^{infcUvz6*<` zX^;{@r5w4s&cYIcLz_AZoic*~q(LDKYt~0+nA`G)c_5O+xF8wXFZJ^KO7oN28F70y z^pY4qov{xX)TR1)*w;NLPe3Bf_e2X=Wp#=n0h3rHhE&}otOv9 z>>)U|Ak9?F^cfjm-K3e>pK}PD7PF93mG7~r{s$7cXSqk9a*f)lL$S<>%O)B` zBvI|WpRxfwv%?KatOE7?n7V8agv8N>jQIC-{ORw>5e402FCgRW?(q`#3O7aj5X;sm8_kJ#!<}PMc;~Z&xxEVmvok?DLg&N~w)u2Duw~i8iS6WoL`K03k{JJ7Y#AWj@W`Nz%@*x5K9w3=XQ|qI zIUPT0P^Ku;(G-~8kzV3;w4-@b$M=T6zQ1s6t zbMPDAgQ}^PDGewY`BzoxhT+(SG5QDk${h8Sb)ij+z~Z2=V(U@6(c+6 zx_i_2LHpzLoZ7qJ-m4>K48--4pQf5dd%vBh}nhqM=B9lL6eGVG# zocgspDe>Xl8&~wWuAJ6sRXFR;#;VL%#6Q^yn?NGmUpy6aSTOv?I4=K49X)zgb_f9{ z_XbO~lpSJgJ3COCXdn`(K~G4_3{BiwuI}h}gi?47zn71>)FqdXGV>HXNamUP=Yp0# z9)tM(mU>J~1^3`nNL2)AYGnk-Z1{t|%V*qzKF@<^eAWGF>7fTTGjBvhmJI?I5$P&g zoulDo$+csSRY_Uha4tjYXzK2(P7T!tv`ojN`G%<{1oIvN6X)%N6sCAzIml~7W#v3> zwR_g<(9Vq-(nAP2nd!_OXN5dw6S|R26tHkpRWnBQr$$`O_BATm|9%$*L08I-J2Yl^%!(Sb zE~jRkGP#%ZQ4=gH-kHi{$m200hrgT@gzptB&KbX<@qiJ69Gpvd9nLg57qsm)N>frM z8W}EF6`j^FS3&c$_6a=O?t)bE-{refGo+R#2lRsBAOZ8ek@0yfgHaBYtEFG1No)SC!l{VH!?M`Ws7G7IRZDKn zoIa&R5v6$Yw`7$rtgsJM5m4gLauggl8Nu~}lb7|wDs`-`feQ_CKbtqL^Q6!*6 zCf-@k?ftP8S$HF5V!WYe6W2G{66$+(ph<0{yG8K%Bt-_A;4NP}HasZ#G_>VU6^%3x zb(ZR8YmwyfzpqX0|5z*9S@nkt%xE{7{n7BdO^BsVU^^kA?L?<)0?CU`LRW%O-zw)P zgyKzvzl11m?+>vDq}~{_m+$-^O1^Uy63BSem7b-!A+Mxt-8Y`u2`&S>TA}=BcR8d*tBFQX4^?^ zg9C&dU{~B?2JgE&eWMOs-*+wfv1P~aJ(f}^qP4}&Cw~YTY`Y1YITJ(Mb6>93BiefY z{jVd=Ej?8IKzn&o~tUf*^_$D>j26iYi)%)SAPVnQ)WAh8?(9v0A3i0Hj%{ z4Qu1(oOvjV>BNr|b;|Ja(pxws?_5Pw1V@sV>lDCn zca5&vyzEfn)71-$?Savl1uY&@MS&%FsNO$ah)=xA_jpcU6J*54yQ_SvO$ zb+`p$DPu>q^>iQU=vy*ZWuFoi$$nnahhOa+X9C7|hB`)uOO1*-==PchiBR`QnEr3G zKzS({MX|DVe&O}lrm(U}11aEG1C>46>X8N=QkccQ=cHF|&j#_T-VKxCeC-O5HCX~8 zpJMA*Hpnz~mlvkhUCIQ0KL{o`9bf{q7DbZH6RU~a@}^6ia5`5Z$fluFennQj!uzHA zsrqltt~~n`?$KY8&bl88ys9eBv`)glC}IXw+*qyohR{5*z=Fx5-bBIMh|_u_tpDmbMI+jgXN2;$0Hug zPxCatH>B@xxw{73%`g+miX7|;*X(djKIp#J0<02c{vMBjmCf7L!{W=2kf&NxVNhzm zQTVJSYf~6*o*iyw(x^wlGr=OD{%X}hy90u0h8a1%V!5p@`$yS4$01~OsJcS)s+luHgI5VxMsLTuycb2%6BqlRdP`fQ@1^FZDZi+6B$zT;L{R3R)?frN4FWh zzx`epc?G2}1kkCM6BH9QM@D#7*@*l`3`+#|uzk)p+M;to&5ez%4R`aXEZ#G&aFG^i z1{)pl7vArlz3?vl&5OzzK3~<1PFu_C3g?#mvx88*jJy&X-f=19K4R%E@?8GeK}Jn? z@LO*dlyY85?Pnf@#b`RX(@U-GSnD=>X>RGOlSRwbB2TvtII!dL=v$|kR{g#+&S^`|Tm?%? zO!uK#|69b~s6ShvM+TNOX|_Qb{=i03rm=*6<*oxF*NOoN6lm@z!Zk?XC-QZjh#&}N@QF@k&)qf<&<6G_WCV0by zM6m{66I5Buv%3D#U=~Gqh1kFn2IkAf6X1jrWIC|74$OevJM{SX%}u z;l11GZ4s}u>o)W6stVzDJL`s+y|#%gwL>^0VoyG6Mj}j83`s5whS1;EaA+~rdu#nB)VOjYN_rU$VhqZ{}krUHr!J4c#qm3Sj#!)q;(nVaUH+8eYC?go_`y}eqQoLFnn zP$;O(>X&a`)w96qbwz4XNqRv{hf>Fns%agq<%yd*+RTgIm3O45wipe3+&1cBwZ9y* z91d$DB!a#qj(>klH7o7SA{3U6%hp~jn9=%RgqewND+H(g3Ld&RwAHVU-w@Ve*4TCcl(!M0+Sz-_Bxts^&S5MY;}?F#4PiAm0F0<=B6aZ*jt zysE|nu;y90Pv&>!q36E`-aNly7y%lXZ#F|AZSQ5pzeD>r1llH4_i`V2T@iGO4C9H` zgorAWp|dG0%ko+K8R2+|me;FGtTS@S=PGpTooa#ZOQ9-~pTzx!H=zT}YwktpbWJ3m ztI;7wAvNf1UFmEd@ARPomsJz;cG0k#?>U{d6^W{KLVRm4xW}K@3H(x_#zytc)}Rpf zC&I=o1k}(rGP{AjvNSxJxTR5A)H#AZ+8RcNlI;e0SGR}w4lX(n|0u4=>d9OMkSpaZ z@dK)=dW;n(>o8_0#KLFhhZXnX2^plBkkU$C_`IZ{qkM2tUBt%B+d59s1+JrjhRgl# zSIEH)Mo+D(LO}pb#|5q`)0SU$R1JspP(B35#>~ZqQzlL`f~B`Uek@)=Nh2KPXn9^u zn2O=+c|K?Rg?|FFOIW_Vf`dn>3;z}&IhOU5%^ml6V7q$y@q+aXRZiJ7RvU=>dTQI( zWPT(JF|UQS(|anz5O)r^DwIjaM)c0kY^TE!n@g7z+=H#5wR0+yiw9(?}uiU0x?FAn($w z->*-Vu9-2R^w`Yz$6^VQ8$q;~q#q1()*Jm<_t?7b?%Xr>gO z8C^Yqc@_+h#f|Vv3W~?@=6To9A-r|4vj}#}sx$tTh?Sx>T45!Nw0ev$wbKLIs&|37 zKo!lVe9Y?Csn`SeD&QO}Ngts2R1lz&>m#`atWGbGTNc3$H^>yseCu}#3j(~((%^=V zd9aSKo#8{7Mlmt;W=l+vr#ISJ@0I4)_fFE{Rks<1PbNCeWS9?6DWxi5m@%&w=W#6i zs`4|d1!TFQ8Sp|4P511D7uKf69vEfn$9=@Foxu28o5XcWh{aFhaU#O3Jze~eW7oO;5G1z!7s%jpQUNhV4$`~b0QkG?gOuq=9KL#7a6m>`W?2DsL=Tw}2^ z=JFjcWFzeUVPQm)M=gNI(o0?{m8^y_x3aY95gn~VZ~<*VOp;o0Li*$MyKW!5{N7Ft ziT_JJEhEnM7t#r+7TLwvR6crOh}w6jmVGyWp2<$5TL@x678#~>b|zx8aR@9qX|u^B z^|s_k{y-{uO_X-dA?6_NY$|ld0!KjQ0Eo}e%He2c9WR$=&k2(mHTS!vEqDZ4Z*mcc zU?S&Q(|6q8C=R)n`d4{%#`H`OaEJ@o5W3|qh;g7ST_tk~GYyTTr}=He)DXRUSiDm0Zxy7Xn-Xo1u=KpM-r)Dg9K@i#zo9VLSr4vMz?H}2L2bvR z-OdRLP;nV*YQ46xH_9BZjmxIZWs05c8PgrL$37S#I^{{uAd|jm&sM`IByu^po#gsx z#5@4Bm>p_W^#||atanG4|29EmG;!Mnm3vkhOJshZe3G1Olc}`^0~K)7;Dv3PpEB*p9Fi>F= zo{LyEs$jN96V_7P9}yRw{?hBwf915)&`2#C;))h&(LVL5+m8NDkO7Le&Emt&?Ru~F zlnjnX0vB8f+k|v3j_EoJ90#-h#>+hgCR}q@XM0e@LW1RHT$l)!X(e;$c)yB(Qk;Wz z2qB+Yc_b2@6P?CFv2%A6_|10quv+l9ye~*M&$acBdMp@5Q2=v}(3?fe`>%K9h;qqG zoGmnpG#5O%KbIA5yK*mr4;<_&epaKlbWyJoDvrePl8URGSuV~`PjA^y_p z8IFC4o>@!Abe>Ujn-&HB|JwDu#YM*G^5vt`CwgU1Wj?8wUjd6qW zJ)*<8)}v3YDq=Es*={Rp9pS87j3BB>b+KGPua~FIX9$8N8nhU z8@i|QQdpbSmR~?5yxcgkXJYVY$4284`&AV&70cQU{?p5GmPh0EayRedw6k)~@MzDd z#@KfB`}2OBt#R@_J5j1=7{nOw9v`++P_338Sg`zjGuGW^)E#Od+*)L=?pSB`$NX>` ztl}%1JO@F>_YnVrmL?6{7m=kwy|1*7DRFW3$e}0Eac*|n(IV@>FKV)hG;n0Q?DsTU zwI7?S;6xF~n9@U=J<{Cc%gjRHtA}q6v#~lC)RfcFS|yA-Z!=6e>bJjCrR)1t?wl}Q z`N8?NtAKaxuG4{^_Z6RjIJCX1%+0k->k(l~3#9gy79j*%WR_dIZ$j_I-pv5n=W$a0%jGIZ9B`$S^sQP5yJ-A9EF^ zk!-VH+5FYozT$Tl(yTN0oHwYcv}$8=wg9vaxwM!?T|{~gtpg`fN+|Bxb= zco;;i9bqH?S=YYo_b?w8el&W{eShqwyg}96Et}{*53MjydEj;VfyN1bo^<0!!|$X; z*@8fT_>F0}GU(iGKCo<@a8yMg)pD`WUSB{Pda0bVURLk8(nIteZ!-*l#cyQGOD~j2Jj!1^6&z7nqds03pXyTL8N>L61Tz^7M9o@M zwLE*bG~<2P3A)2HCup z%c)CS&k~}XGq1N%xANM+8lGCRaid%rYNq)Nm zrztqCBb3#_Zu@Zkh;)4j_;Ypn&)PSfj!J_Qs;o!=L7mY)y#7(D$XE4XW3*F^sy|fs zfM7-Dn5#IZN0C&Q=Da~gkaOOyJcm1!mUI29{p$(|p1A_(w4Tv97Ze&aCt8|KA|Mx& zkeVWU%0{0HutaBa_o!y5Wb=VDN)m`_lNEt zy8Fe^t!y92r`Eyt$a$t?3MmVm7kUmr`V`KjNpP{rN9^jt%J9v{&5;YkU|OC#gy@|M za#?ORscaB1g9SOXd$TkYoS<53LXs z&Jtu;tO~IdRJ5G=HA($oBU^no`{kKq>TC`4d!F~W`*L$p#Aae-$|jZ_chUThO{Nr+ z611e@&8CFf=?6|kAn_79|AKi5LhR-NN#mf3Hi)*^iw$2z#G`Vw3}TG+Ij0M%WBb91 z{PHq~yXB~Qjhu_Tl*lYtTE%74g#r66&0oX}z>Y@iDlBF@l2@l<+ zt!(xo$7=~z2=@a0JZPIUL3377Y7kQ9G)K1oDkw@wu8>wj=UE=gNvlS9}ZFBs`s6+@o^6Q?Qyd1l#E)AHV<6)e)i(6}{ zeUh$)m}r{2`cGQZoFLCD!>f*xQn%05eR(lHML`-ZJg~e}Mo@jhy|$NkK;04Up^Ijc zx?~ZY0GiLYdu&$`9=j=PQ|ogxz7K~vdZU(isk8kZd@^ljsLfjP-&>yM+9-c)TQOcP zc_Jq57|uC$A}gHK^m9FP4@;!)5n$=Hr{!e-X)K{zwWl<~BY-{z;afr3R|R4Grmc03 zm+EX@97VdW$=tNkTeKl0_-TojX|}%EE2MELON;sjgj*}PaBJOOE(kUcUD@pcoQ?!} zzG)WvXK9#g%|QT!+|fxJ#J|L^W$fl@pGomf9>>#j80!-%n08gGwaQ1keic3dVV&Nw zKD13_yhhR#ch6{rwHQsOr$|9fx<7!is1XX_!xiH*tNz*AQd@AdZu?78$Ua*`Jb}tn zS}x9MsQ}}B+B`9F21kHLZtHn>C=1(44ue}?ViAl^k)dPG_3y?mXlr?wOMXjv-Z0a$ z%Y3Y{E9U8x(qp@m1I(MZ>M?`k*4H(Qn17;jEQakKFyFhWZ~+^5>UxAM#CVkluB3>C z(bqV8%&}&AlinY@D~?#;a$5w$22SHxr5(467M&-e9oLv3{6L*}-S$xPG^g!l0V*2Z zMni5XYbT8H{+|jj@m<+W0QHoFN)Yn7{huCN0k(`7NV>jkR_ej|+)8vM$FhhS*h94u zTS|HwM-}E1FE9z%$MNfYvJl%bl<~P7gC(s2EW6B>cRu9~u7EgbeHbmY5mNxsx&q4b ziC?37G>|2t6hf4VPAkacZceTEFoh@%6qbR~pdt_0zpih@OqlMZx9-*Wh|2Gk9~5iN zF(z$uQreP!H_)r`Z=a68d0LHnvo`GvOW@KC8Vt6p?u&;Hn%1Ccpdnv zlK4D1Lp?o}qPv|T3d#>ma`;L-&J$9Fj&XI=yohP`jL%5pQud7_H-V@qAvacKpB3^?EVsbMIEqrd zC<3~rzN>549B%{axSScrYL-X5o2NthXZot%ql9Wh=MMMLtOswyhE!O&RQK)CPJ$Ua zh0mxoK=rE~k`I~CDNAvHMl8w-P>US#4ftz9%-8tnp3wnaPV1bsF?lrsdrgYfb>8(>RC=cOG;~D$w-AjBS3@SsY-@tB5K|Zs>u#6 zF&S+%WcwZlk8}rRa*{6#2Yese)+>Q{2Pbs;;NEehn@0YHM<8eZ2*q`ybW} z^6-BSdlxQ7b`)T2$(LAmxO9B>EVE|Jx=PDdQqLK!A=dx>K zxzc0bB4iW2Li8+xQ+8i!pF4`t#|z-tR1da)_c|f%vesi^^T9nK4TL9DpCMyo_GRxi zC(4_8!aGnG9&`OqgBo1Rb0Ob>TB=pr-eVHa#)Yd?uBX0TRX5tfd^eyMw~(S_#SW+6 zI-0cGD>|Ax@H02s9bYzeB!*1c)L|9xmnE|6*sh*GB%l{TEKx(VQxE>O_sCTz-;SHF z6_h^}EHX0eX!a=C_;hvqeyi9upPvBX7=WTi=;(rVIqR>j_<$=0sc>T$a+@EDM^+8> z#*=D6Wy=C-ALV~aIV}x|mD?Al0^5PeUNth%~HmY}4)$lhXkD@(>kgLJ}$iRXgOa4OA;IOoYbdl-ZHnnB3% z>6X~bc6psq1l||~dvGK{;+aLr^_zO{oGqLzJVg}s-UB`MlmV8WlKtp}B_QHC0_no6 zaY~=|Qi9ggYJu;#(#KTWyp2d*+h^-b^7(;r!%y>T#2h~m05$QIc$CNG8)5}PS-bHH1KBJM??%|J|7~_0Wg27n{?IL9=+m6y@3bz2 z9Q+(RON`iBg5yy>-w}{tTr!x_G%njIbDz25ToCp5E(vu(*SU$782nQ%6H}L#*C4}l z%to05TLVY)DS_*bS)BJEO+w=irx1yVNF8#2G?2Nph~8k}j!NhL*9?aCgQl`|tb2S%Ld%gP>A7Cl z1D|Tec&*F1t@onWUWKYEqu*Lv_ISLWnu@g42jao&O+RJz+lxCqtDZZoK_+$-lB!RC z%FUihQmkI$E`^4>4oxVjU^19CGPwqz37arcg*6j zXdF{8d0?6Ya|xMnTNB9zw02&lUO8{q18HnLnjhnWvKh*SG4KA17bV6!wTqD>P6429 z_Jh3Owi-!^;r55MUd9{QChvkFrdX&-(E1_wQu^hvfL>SQkX!nXFMM>^wxV5MrP})y z>T3PAwqD<2G(=BT1M!Vm^}W{oFbaMt%XZT{JN6C;*-4-v_|oJgTV z5_e@Fs&{NeCp!_Ae4}Jlb1n?#Zua9+wGIkmh#?=Hy|BE5FquNNdmfJS{+9pu(=$HS z#fa5g?6pllF6ZK8kATkPZAQ|$4Z*2gN@PulWuup)=UJ5BygxLPg()cYFv(FP7n4d_ z>6TP#O1dcxr6>bno;aZ3y|IwBbZUxAfwS~WZ?4L)v*gH?kxselyEB`b1idNATrGH- z8d&hrL!`@r0PRcEXTmE}XXlMkjtMBM<0eR#;gVn4`3i@Bo&IC@Q5W-#&@DlzsbMhz zH~W~X?zJNPH_W`SQrDpzq;MXw@D+|9K*Kh08Ms<646Jw3IFId&x9Dn=4sdhjP=KLt z_Z;SROFW_;s9P&jD9oYtZ7pU6Tq$}+N3>dQ(uAoXRb1p1-nM~TbIcfpEuAyQi5eti z*nI4?nR0cj!~(6yMHPU&o8X#xWfq91guTnR%OY}iUI2x7%2$;}N`1RmjUXM5{8T-_ zdXT7)O&!OqTGu0_y-UR9Y%vvl{|VI&ZsUbIa39#ZvASAR+KQcctn6YI8-d|ncCcXK zhDTCnN2FaS=gknXGk z5$yXqecH*G9ku&Cro1N3-*0HOS;Hmw+EtCcZ)bSR!CcxIJ{n=>BfG}?^v-jf`(Imw zc)%}7@vt}^prozY5fv8(uVTQ*3mH+}%Xw5EjF=~8QOH+03Cewl%_dcD=b$#CvyG23 z`7x{-EJ<+yvd-PhYOLp#H$|B+wgwa%_y-jMn0Ab|vo1qV=KZm;l%?kFL)~`PFRv>g zHOz+Lh0rdF%Jfc#Ai5ij2?r-XAaphrPJ!Pbx^t)U^mM zeR}u1`QO(X#?1nCnq30*ASUcD?qDKgUo=h2lHDD9v>P1n)wXpOc|*}oatSt%$>sEn z*%V9l#2fkQ5V6wGp-q-QW=do=3ej`?k5@=7aCO0BLuWKakg-;cR6$(AYO2GqJr82% z?jEv-Tl%^L`1o7_IlTg|6)Gx(SJe5&WhWTq@A9~BSqj$1{%4(Ke)j;>oG_b_Yc`C^ zoCq|>#)u0^$lsBHzjIoHck>W8nWMB|@BE?4WvgH_+}@`CiZnbc-SC^MaF~pi5^W;L+%i=v{5%$`){&Y2oj@;i4H0=Ho_&jpEF z7V}EL0`yMRbv9?NQ>wIc761$8?I;+bAFf25`B+_F@cv=a zQ!&m}Y0IuN%7;^7f?3iAR_f9?(v+jth=YoKAT=)x`7q)&-p5ohiP7Z%IH|1r+{?0d8}3WKcG? z6y0jGs?JMmm}tH3IFpoCGpl`}_ipW&3IJ=(m$@16^#(ppQdDu)JAr~350lCttkA&w zk0o~BO}pV@YULBW^;tK+lTT+D?kh`mjx#fH#;Nk@lCv*C*K3t)+gT;&ogRkUemF8& zMbNWv6nyf5bbJ*yi>ha0VL!n0AH-oLiovppW>;GD!WzXx;BXjL_O}SGG;iD58<{?U z7NgNeAR%nRa;eZmAoKjedlkw}O!W_11drHVVBc)Dood`i0dra54-@_fGvnr>II=t( zkf1z>=J7fTaWIA*?Sw#+m7GE?Nl&?Ik`ZRUl560%aqrk>A;7^S%ofKv=xi?tMU)sxsqCCdf-xjW{(3YC< z(_25%5T-KC6qmCnC^9cP_P*4%O&rBaPa2S~tc&a^K4)X{Y(0-wz2gm%;o(uOtnO@v z!j-ZE6vmf|tG-y-x0$arO|YvrGqXQZa_qtKig7sM!2pS_7ows&R*%An5$<48EY(b# z6R9B0WiGL!bG<=8#h{!A1Eac-d}I{d6SOTq8%C-o@M>Cz8-fT|fCjbfJxXoJD4HmhPuku&6g~4e&g0;EvNt23^oK;Q`i`+vzNy%JEfB%>L;fSR*do+>!cHs>rPdfm?rzKuAmD8Ov-Es}i;FZ+Z>N z#2j1XY1;2XHZ8chVLs|2Esyu&fv~9pr-3W~t=|yh8&8EQp3@}b4Y;F0)_O*nmk+#S zr^e6$Q-ZM|d%iFlzf_3D*Y3l>O=`2!ZxV1j(P{jH3T%x#=MU#C;K+$>@Cu@=12 zvvJ};7Jiz9%Uf}KIR!N=HOn85sUnACJ!c_NW*LqetgEGCtjzjQo>}_k^!9KGCId3@ z%aGJ9fAT3uwSeM+FE(EuQTkgMyS^vm}$Q=ye_!Csjg4V zi}r@so7$U&PU-C}iBlH~R-gCPI~F{|-&)U=4%;pY^Hg|xUvZ4Y;{4Ey^U1#-pRK(_ z@L6--geHX-nrNgCG{!8Wg(+puYB>f$z zE%wgk0l5y%7M8Dqj+^(_)^q)4>%CBu?wS{=y{wtw6QC_EF%s~G%hGV?@pwAprqK63 z;Eg?i^RzJ0W;1iU#dDzAONo)WX}{#*`W33IW9{@R4Uus1tV$yscTE{-S=r zXwZFl)ggly=GP~yN&4+>R+F2=T3zFOyF@n|mn`8YDEK>;hLrCz@6(?hDAnM8%!MTD z=O7`m?FC22%0%J(0Y=i(Zw3DwA2R``zPi!5x(N<+hdlYoY7qrSYcjsK;6_)p{LQv+ zG2L}}{c`Q`>5_iyEc-$4>ApV@BQ`4&J#P&BWsOJ7Te|rPK4lO`ORnlyGaD2aWL=-U z^~jP``Ck3csOz;x+;hgFk+excaK%k|2#|TS^Yp zUf3V6JFm+8jn%nH*=#;o?WY2CS04Y8JCzJVqI_3gjT!RKE8REr(qSjILUPvot@&W` zdi4(6N$=!l9r8To37*v~L0-cFKlQT;_wv#tV`h9jgR#&I4RHMl-pRWscgB3KDnuSN zNAo@R=uGAlwd(0cG|m&)f#}aQ>sOcMkwHrrDclqFz|VEu#G^Z^_(dqUd4*s08B46{ z_f+GV)~TF4v%{2bIiTyFphP!w0)tl>${qJnT?;vr_%;GPNh^GAZF@zho>=PzODjii z!o|kc+~9HdH4+X_I+qz~J?x-b1L%fPv*&evCUp?=F_DfjnGns0GrtOdVfUI+C60Au z5H8q)9JqzWsZ=br*Qp;S>7nf0Sn+fwblmZelR$7p>0)J|eq_-9uOgy%oP6r`0+>!w z;J{x5Y{cB{{>T8t;qqV-A{}9R)d~CR^ht7ou=+A^i#f zbKanjF)a0>8-n%gK1;MgD8eRXO)z$Vf)Fizrokc*G1tat>{pn3 zCF-PJrG3p!J&j6s|T8L-XmG{odytGkQysr_cAW@+Hc&IduBDRJ141GW)}>9@bO!bpXy=dZlw$=W<=GGSr%O$b;^Oq$}_11%azx5Bw#!T!RAM z$f2X_E-W;?b^Rm1;XL2?dh`sy8HlOaUARk^S&-|!RHKl!&{6QyxKzc(4+FM&od!F^ zHfhy(7#`P&bK8Ho57+u5;-G7CtVU7jpaZ(U-;EALEAfM zVfB5vfsZ`C|0r}nsogVimEm?^`M)QUAZSz=(nY*cWMcOhZB@u_-wLF~wBiI;I9!Ml ztp`M#^z@s_OswMM2d}#3HKv!}v%TvL6VgY{Se3afGKjwUQix{QMEQ1k{fP`Zt)sA# zvyp~hV{i(KwHZrZM8I>tQ9;)3O|wZbGzAg^C*Qq}H-kQyn%$X(YfjgyHjsQRv*R|| zh+6nYu;96!axpznE0mBpVA}J5u0xlo`YckIS-e>Mw=368R-B~`U~u9p!_>&P3ro1g zb=htT&jWY;3g(cXaowEPlBy|Kl#)>9L2>ZeTf#7#sENsk9>wIIYJ2z}U)@)0y&~Ap z2UK9&kS@8o;8&Y`8i=OJ4;5i&`BK1FIpfi;H@;faK8~y0wVgZ`WFY%U3_XXR7>)ABOvf{p6&O~(zeD{$OhM-XVFwVPT zj+|d?um0OOFX(4gpe4iD#nL5CnqUIg7~_KkZo(>p)1I5UsYZp&Bb8pK#o`o?qnh7u zo!v6gO8t_{>;X11Ai^$y4Z{pMy-qvX=NMBKwgrc5iZHK>47&Nlq9da={bB9>piK?U zN#X08evB=wpZW5;b|373l@kgwhnYo9!R^NIBNn%Y4%zEfcQk&KS(LC``+#HF(=C0y z(hkN?-PkzkWU!uzqW?_#rH_h`OvU!9UEB3#ke)X$!j;81uC0)*t(%Rzg@g6N$SOE0 zw6arW2YMXI_t}r9aYVxpB)KjYNa`B{NIJT3UO)0?j5yN^9^MbEZ;S@O%={|St7Fy zcjos6l7oIB_&uG8Y^Y+?zbd|&ivDd-0YG%CSNeKfQ%pXq_aQtm8UIIh&E+8z@!8Cc zo(g}*3%W+xiS@CpY5ILT9<;<_V}PJ(R@Pj#OJ$heF?q$N0>H^})7Np`ae~^x{w)aY z@y5!je}A*S*wZnB2oC;$Bv^nPXkg(~&h)b%9iTF#WY-u6a&6QdZ8qrx*30c%`nhrs z*o_LG-d^%NlmefFXy0jwY%v^j8_ru`){+B(Q#SAe^2;ONXDk{E$0bW+`FPfmkUJhb z{N9^|xr!~8f)Jndql@0@k3m+qZw?&*8K$aXyuk= zf&*Ea^|PK|XFeZxs{mL8x(MVA^Qb)vIuUe}&9HCw1k7Xzc^6~GBlyo8*fVMzql2#Y zO}%@(rF9So@ReMo=B)CUkKy5619XCcbMzXKVLc=c73I#*2l3A72N*3Ly}7^nzJZ;* zGs#U7e-|wMHnL-u5zUG0-gW1Zxa@{ZHI#;7P)tB0arJCKZWEvUgnn>2OnCgPp7w}y z>A43rlx3vglj(tk#3G7%>^cR?NlTQ&tS5T1Wos$}RUo*d7*>U1Sik~yG7B9N#4y}s zqx>8P+u1ADu%|)s(MKsx%IqT%POEkH#KVv2=02qTQ}U9ywI4_RtSS>ii8iiLji5>rd6DaE}Z(plNmD7xKWdda~Jo0 zn~)#+e1?9v;O@b{_m;o9E~p-*gx@F>j=Gd%H|ro&VmCeP7n{z@aIfPviy9VwK@qsg zP7$ik-v)Pfe`F|X|Bl$}HzT<7e*FFseHR&Bc z3QD|MnoDyc^1cYn&R@`*t>b&QLp|yEN15X_|Cl&_8M1oDoy;WEfhtUg?3taDk=jWzm?W`m!RQKK0?2ZR-c(4%fJu9b;$x>+j$*XiDNvl^zNO z4}S}@v>&y}S~4xO0KfGsi6B z)@S7`G`(zA$C6o+#~ma_Pf1-SuZSTY2wQnOV5XqQHVkp?phFI_W9(<=8BNOke!j<0 zMJF^g9;053c5dp=-hAY4jeWFlP))ApoQ`!3gU9T1e7QsZb5PaBa_-~MjVa9;(aPmY zNh4<-Dt4Qd=QHjfw@-0r+a?r+JYSq*QJb1Io;nR9NiDRNEX?q5bG_aN5^oI(^%jJE zSv>pg0ltr|tFy2C)@P_lV!U|5%8H)X)s>Do==7PAx~Kh__Uj9~SE}6cUq9=t{U}{) z$wOjkx#hL45r&)g93!5R5L41PlG$e`7MO{_A*T6q$URTVW8zOPhk4%*+p=W#{e$A( zH)T(|UEMb3^P*xl!aM$cvr=Db1ZDPl8^{{DXsLMguDbS_H0g{x0TWP|b#~DgU99ja z`?SrW7naP{Ids>K2{d#~wpXO1a05~|2{ArQnc_s3L;hYe+vn)Z>Zx0fK<4J#y{_3@ z>vKvxzGb(Co~>yw1+RDdNbM`gTSvN7Obewf=wZyy3hlnGhI#tFagdGzzff;1zAjf= zK5M+6coweNYPYo(qqeI!b3&e>q1#f^9lth7y5#&v(K6o6=DI$oMs6N`kPy19a*g{t z)y+d6f8UI`N~4Xvo_zU^-3HPsfvFM(G9DHXt&Q}`kDw{N{% z`aa6^z$2YZzV(9vyOW>BU&)_Wy9X1WeRkz-=`q7CQb+67iLfYRr3xO-KMPH^weG9R zY0`6b7k!78__Rge3$$Bz?055(7c1{I+p0YteMWzBxkr7@6pvr&IE}xR#&42ey+*i7 zNpt*?%B`!~>4{rD6uHs<{?L5|rD>NnfIXDDtO@RH9nTkUlJt=zlLNWEq=$%X7s7K}78~ay}a*7f*JdM28 z=l-xe1Fn78zBlhmfUT^ALY@C2Ai(dTN0ibIo8G?lB>sm)z)E4UnfM@vm$_XG!#Qu`~?p1vL@S|^ND(!5W@A3hAj_j1Gz)|V6c4(Ek1z+={? zM+GygfvXSE{r=&1{M%-ynhKMYTBZETU_ir{ zAKF*$IDKl2`RuQC+tKr`q>D}LTm6m?hZh!y-&~er(V?C_!YAmh_uvDkzvI#0cvNE_ zFA;aBX6xVC?K)3?pQ!n4S+U>E^osiiH$$=O1~@jFoP4*;?fz*X?+hKlP<=9cz zt^00#ToC`EKaf|Z(81pB{z*BV2@tCaVd2h%Yv+e8cN-s!Jr?g1M2%0o?Xauw@kQ2)$Y}=`{$bep7s^ zy(N3|1kHa8!*aC@`SJEq5)ISO{Y82S0Q=YB9l@zu2ZMJfZycCns+l3T_e_tJACBj+ z9RjQkMlM~O(pPF9H%;!dQ?-kLHW|xXrC$xy7bpcpO({Ca7J;Dek6%w-*&Qgy{svZ$ ze0+i)3?a))(!4yHjiYhVNU2X7rwKI+W{g}KDm=d8)3^y`qRZ>P8gH2K(C71?Qi17=GGupMq^V=#Zv!zQjWDV;lbrTk_#KY{45yk zw{9ymC2zm{w61}`veUwk)@U~z(lwTb>>24VFXlJ$;;pZS_Fl=C8YE>KI(X%5to^}X zhlBs@m`NUN(7}1_t--2|2`ZW-VhtUa^ntsCmCXyYN~lb;qQk&*BW!_9qYc9 zo@<||-Bu!veHvd4W4NbJ?rF;=$@)xE3Ac%POv^v4siD8s-Aa1foK+STf*4X=luQl0+p0C0^_`@$+9tZ}y z1=D2VU$Dt8+%H?#HRy0`ng5TmH;ht-2e#;;4_rsm$HFM_7nRDj#n&huqoFq@%e& zh9OWiC=!-bczCp9Ox168d?q|Wwa~#j)&O}=yk`j`kM-G67QNKws;cWG-$U2J%whNBzTP4*$m1!? zx1_#ClRa9}J4kyEEzcX4CtS~2ae;!)?XbOIxZv!_FmorNf}{-(ow{Ii^x(p6pO;>D zen$+gl&{f=9hRSb(Kfd^18G8#29K(F?Kxb?1{Q}G=T>);xTm!I`kQ*OJ$MgSUo$6HmO16cYDXSgOwzCcXzBt);U<@eiAhz%|^uGuue7pvJ`N;$msKN z+;F<%6oZ{o|JUVc0xZS;?HM^FCs^wS*tXQz@h9sNwiMm#`~P_k#VptiM%m#pJ956%);4^GwfeVUth!VYFK-{i1U2TYAZa!f zCvZ`+SxYjLHEX{}Sf|tY%;-@uV*M5nQFI6g@PA~&CIRb?8wo^&Lp)P|)OW+~dAR$X z>WHBuyO1uzRR+{3CI0#))F%+(xUdfYBj~_Tuc0Vu=QaZ&zTY~U=405ihJ8MLSfi{< zusXQ#yC7ZWUSa{;7Q;>oJC?o;Aj|eVlGJ)42>nsv{}2~Psg4`4p&KOj&C{pI5Ow1J z)nA+hyrKP>&EdX76f>0(=cxj398(%cm3mK+)%js9G6YCB^GV-2U-T}M;G_rPev`ek zU|5UB>6%YQ29JJ!D*bB%+|jU2z(H`;KL-16*JwLIm_5T@4^bvQiu{$0sG!&*(jiMs z0XyCU_ARD?Ws#02#eZG*ch};bb=^z^#mH57Ux@9T>3F9yY|R2;j$KA>mBjOvVH5qX z3H!J0d90#CZG@dv(DxJ57tjmDAKl>o(dLCQwJ1{jX9dccsgEKM6O|;e(RA_j18;z5*h0P9=r7I%wW!<9kgRf)+BBWT@OqVEhSN;>(c^-ZF^RmLu~ zDTS5DUZQ%UhyHni7wYEzG%;9!T~ltZ2hvsdr(xyc%{ zUXKTPg8HRH#wKU$>WdO9vxoN1a^3wf)q2@KeiBfUZ&ab1sm$l%7?upwCL7y}B%=*yY^v|$eRd8E)JNJ#UQL5GT@u`SV zlNYMJ=2u%@##es+`NJY1sqHcVbEYx?(2UGogqHNS889`8t%vDMw{LV8>Ef31UbMi%4(|RDet+Y2!<~=e`~?-L?=GJQgWy4fSc3+!0}tXN8bob< zv-77F@a0hL+9y}ylvZkMp0r|!V27d$iGT{i*K%sbvxKv2&FzrjDh$ClIxjw00b}#$ zX*lUA@LLx0LX~(FIvQqu+F0Q)f?%O)@P!s&yXKrxO@Jig!bO15DTeQxtSg_W>OOl! zN4xm}YUlNe^#Fk!7MYLe8unW&L_VS1OxMTMU>x=4Fb=X79tRtY}*D01KH6LVmphLdvP<-iPxGeK>fX z51E=^VBKh7`;jW236hwe5Xaka%8)P zE%>8ut`gI^Q(!TApzpo2pl=_6ur5VcO~s0MSpuRPz}3a)DZ*83iVO?V$JP3vsq+m) z0DiGG(48s@JIdx`&XV>cD~Lv0x-=Kq*MN zGb(j?@t6Jvk05R&?aON*?Zu5I(#6GjO{Xo`EF*FqTrCg^P~RRTW)A*z=U^1ajy13Z z6!9@I+l%m61nWX4R#4&PAHMENlh?^Pav^zqSg(v(_JI|@|?h9>i z>`h7U!Ro+%ga~$9k6kjd&C+9B7Oyz{L(!To*`g}v0$RY9`QUndbXf}lY zgcNGjeQIbhfB-Y=ld2HO#d+X#i7MdN&ygV$lUswhZ{Zs@v}k`F&^z$FbbO_xTEM3b zA91Q}6%5^A;;^=0tudcl#P%$VCbGCc=XxK{JE{JTpbzGdxGSt!Wb~u!uNwhy<{Hn1 zVCrTZNxv-8B(o1jxdQAK$ew^>@O^)mR(|G&4V-ZjN#eu58#EB3}ki)7ycAODvyqCebeAcY)o!w~0;3-=0B5^!D5O!T9=hr8gYZ!}M+~~_0i_nm$<#hO))a=5q#VR-Eal^w z{W+79wwWJ+e?`dW3VuoYW9{06zcRzt3M?N$+CM~>m$M#4!1Tf;8R4+BTn3)Df9o_z zz=;z6Z{^3&+yd^|_%BFpx)Ji-yt-zJ);pZ|{t*k1R)pmPIXYs*q9|Uq^^PvY8AvKm zB%&#rqaaby#Q+<3coIemC$GTS8=7YCA<`ec07w5*1MoTF;6MMFesBqJ)QK~#fKm{i zmq<1YS#juhAN;rCft^2kTmkY*AZ{M04G>!!1BWOVJ2CDDtLPLa5B*~?IO_|7Q2jAP zfKYu68YgCqzEDy66(TbL@67MBkBYjA`5E7B!BE(Ib392&d1VX^uUls|sAK|4U z-d*@#Ha-T)DoP}oTo$**-yXOV@pKeGFt11YIce#W2kM^v@b=biSiS|)%_CHNwj^Lr;Z5@vm5-NzOF@8xkBAk5?*|lsg5MrBX$yG+fd7+} zd{&|{Nrg!$z@+<_G^30!5&#}3oBhGjH$aIJZrSDSfbxg=7JWq71w2}o7{1Pig$c!!l*Q^!J45%aMW02S9LR5ka*n}^ zQ_k)-#Q6j_O~?WWYcM3lwP+i)A?kny089vZCVEmd6i=cGEP${Fj1|IW@m&vpT7@U* zzTTVYyvKIpuP7we-@$PXOj-}|%(lR*L3*GSv}GQ;(` z^Xjsm?p$#*zy+lcWRKx6GRhDDfdgNG;wX8>1|fW?ItRMFRqy>j)Oqw3G5|ge|4yYh z;xvhFQbRiu&B2OBln=1xrwHsURbnfsi0r~3e`ZQQ>(4>?dY+*ucjwAlTxaSHqOi0Z zj2)b^pPizNkH=MCo|!d7O9#8*6_`yW(2Z|Pu?Wj=ISY(P(3JgW#8?C^+|Nt~Cgv94 z0mB;+3VZoZy}q)~(dwp_<4pH}LiEO$cF<|_gpbgiqJrP+Jv&q7&5Ydy<9dy{6ij3D zL9m}O8@M543TA~MnGrXA04kP9Jcc|f%8m>c;`AWmycwj?MvB0Gn9Vdi7p`dsYA9Sj z(nQ>8f+0-o6vogjGQRqcO!N?xGZ$a2zNWQXK?hqu3 z;$Imy<^@Ed5%#rR{CTEnI4R!GX1bxkZ4343zwhAO*?^SH$wFZWX$_48z7%YphD%Ez z>pgb;lD%E_u;Bv0s%;g%iDs-9xzblTkSpdaQGy^$=(D|2s3cSNYZm31-eF12JF&t#8DmDtkD7~L&FRgN#{w!I)NM)u8M|GO$o?Qg>Y#Q zS}5s6u8f+o4*&up6!T-V7NR`jombq9E#!NOyl&0`nUgze&oT5}uvhmhpUZZ10YE?f zInWE@H(ed8W?adFd98njN(}70xL#BP3>D>=0b;AHqfbSq#ji&Ljq#F`a?QgewU>Tt z_-gw0i?M`mVGcDFT4IB{PA*MS1aFt2lYTv~pv z$^Iq~mu5Ey7mG-1x@M|p0ABcqGti1y9eU>7zNavm(H1RLC8c!Z_ef3@+V1-P(mTQq zyMO@A>C!G^Hb6=`CVz3~Qk2O~OoqIHH-T%UWl6?-DQASt?tfP-0+*0OG)ac`uQ7&4;|T! zCbVHTf|Y_=b9#S@N~)PGt_E5?7#~Ox)=G54SoU4)dj#frR${mnPmqq7Po>0Pe7Gv zI_kn_07pmPTa>M$cbHc87MNqVmpT>a!(C`JrQ07jEPLD3u^OsUL(D8JzG0@Wnm^+1m zR!3MrXd{`9uY-+plnw5q1|Wn<$-ivfEZmmBy&SSj)>-T8X(Pnl09`*5%B!)emvAq2 z+OffTO8+`mM;dz}{R2z@+SdQm9pwH^fbRNlRNPFQB3|ur!9V@OwOe9dVQswgmpW;F zKn7C9Z;buc|8BPGZzA9Z?I@ zG4f_4DX9@*Rk4xZG#LwhT4)-VQ`^^2SK)mjyv@?5e$a231qUG8<7XaAKRE$FUQBad zmo(Q4sdx1OF^J~*V*t<@zNNmcYrfWB@#C54uyCJ~y`Suf#E41r2;URlf7l!Esn@4@ z-ld+XD%`Nnnk^CXX<@F+=C>j@UNvKDi&}6BfTKvY7|AL-nd?wGYO|&FRcRNV0*0{4 zpZ@bV@U_8eXq==7^qG*3A;u$)hRlNMxtaZ93sprzQ}*)3sFxZtul|}HuGfVy?PCk4AFSLVbScARLsG-; z$Ib`}4-TIFHMfh7H4nU*Y^EaHSyY7D8T&bsle=DXn=Nh$ByCQ#LIj071YPLWStJ1> zVpP&_YGF}!)+L1wPa?hx-aTPWj-iPpV?_NEQ=c6#e1WsFQI6NhS|20Wu}`ulPuzev z|I`M;!XP;}UrYc$H9dKjA|MtDT$BBoO_jX;vW0sjs5A-;92iWH*p$bP81M!F<97q3 zzYr`6aBR`=)$=r#2&M#$^(*r6*4W463TOw$_}x|}QZIS1>4A*5$mqv#X^JI4+C8!W+1f>uo z=3#hh^*-=Vy8y7Aqf}6+Tvnwf%n*SA_?P2F-4nza96bN83M?dRi^X*A*X4A=rP=cRccuK6aAkzu4@ic?-rpM_IrPk3w$wQUIqPFlWAadclGi#F_x8HFl0?4PUyc z^ZUNe*LB`ii3S)v3^jU;nn2JpNU6tKkv@k@mvS?F$lOh%+7_X zStbxyquU0v(Qk;%qKC|?^6QN#3@`nf9#h25_Pt5DXz0lQNf#f@6Y4O*S3$P6-I8a?y*=St*B7mwtKivkMwUFxN_9ewVrEjY&M ztWM_F5wQ$+ua{tgn6KcL#+hV;x=;w@`9XAFzHlpSz&9qrx90*&6Muf{SwtU2VYA6? z)7lNz(e#ByM=${)#34fDA7@V2$p7`5Gg$aVdGN+zDl7GyE}v&w6?~e9bVrD#h{lV2<$wK# z>^aDBBN8QCt3>Baf&tl}eLJjlDYSX9fukJ;X@!_&hHnR!B4HPdtxGT6axk0E6bx+W zzxxF;8?rWhlQ1GzIrL+y33xzEpxK-FN(9FTBiQ9K)}R|A+VNq>L8ut>vFMLrpZyUr z(Elw!yt{?K3Bn5!vo^88jw#kdLKn=iWEeSPEdRfMPhsK+2>x%UG5$V;aHAm z!&f4r`-z#oh>%||)laAU)4Q*hx`6KB2JMsTkGBzC6%>IeGaE@Hbb?Bc%-B$1NAj1| z%di|w8w185V*UK-7&x(*vbm6?_9K^W!}_rhc$4N(@C%|2&_r#4uw z-4*>s)BN&u?m)lW%v03TUdy!_(L^ z$4!ghlZnSVyZ3CHI?YWs#vp#!I+&*=)8@e2JhQotD?o;Or$(&o-a<7+sHTsYNY75$ z=quU^btvljU+!}&K*XbC+f(E1jPzMH&>ZTL5i{!HN6M3j$z_orgC(+E>nuvHNAyLe zIWKQf>E$2oYR&gwm!a5Q zZtib1Pt8))t4%DaY;hS3Tqu`6LDcgQZO*%8nEc4tg?WPQ8cn4(AFJGwPLweGcfl_#vMC>y`77KBMRK{OdZmfr-hjk$j}_eWy!8bvX#TTLn??%I?6%%FIFNNZ zo$XdcOPV3#uTkv2iMy6Zo-EMumS5+7 zF0DW&lE~j_nl%;^z1p3{G)l~PSmw>e5dwA^Yu{Mc4fY}-_nE)~_#C|Mpe@n2M};v+ zO=08ax!UpwTgkqxoBC4suiCD>Sb#lA^gYr@orr*gMz->OSVkc4EqgF?gIfP>)WvML zfd4cUJU3Jv7aPs@_Imo8OgnO=#h2}QXxVe{XRmq04?4?EF_X zum|G)%AeO-gj&DjvALf?82_;sXs9loi)464(%PC4lb{E+^NGBzT7$0Jp~5VfYW+nS zqDW&%rn8{1x2t&+!rrD?w8ArBvtb-DuHJy}x0bY16xF|#;)I|QVtR)1l#S&=4~cQmuZ2#5V!sFVIr zog)?g;%7-@aLbqjRg8RufD&o#^RERy*{m>Lrfe9U^jDH5bu6t8(W2G`E(nR1+~sD? z@h-9@Z7>Rv?Ai?yGS;||hbW6=pbYDh^F{4psbo7fsfK=7r!d|AXu40At&}13q>=Yp z>R|En6?p>Lor{|PK6Uf36iakIlc`9aZvsO4>t{^{$%{tk2beMz4pTPFKzHOep*;-i zZU^s@LRtNoH`&hj!P}L1^dmI}>1&eKI9{RiZLyB)BpEI@zwEiSYA8_r#`8{szV|LYv<`y7TAURlnFFUU;kb_1y zm1y6Pp-_z3L_I~rG{SUyTL8o?U!U_`H{(-x&@wBrle$%16C*-lNi$P*H=jCJwI~LX zx8$Vep{EzKalXLq<@0Dcsk|NkkY}D+|4*+Udtmv4@AF5Cm;!{EUr#E+TUUoMs|Cj8 z4YUHnzRai3OCPYndVvK>=2(VK&NGuA@&ff2t@t!GjLp$X?3n9h{pu7Dzt7Gq8-~zgfQqT%kVaEv98}XdxS_MHM_6dtT~IHaXW+9rCJD)r(Hb(9q_nLb;L zz7Kup)S`z<>pcE*uw0MSo(Lk(|J-xjJ%w^GaBmn^&bwl+4?6nFWz=c;@dw z8bqrcs7-bm*GqY~$~Pp-=QOwiNg&4^A|<^Fa<89&k%-MiCUPQzzASN9;3{PAJ^8-e z;TmC7E!m=bEy`*g7=C9H`4%lshy@T(^wfOI}VlzFG`6%A5fkP}~*XUE^+nWhf zFhD{}S?iA7g6-w{1$tmDEI@q=1|0ro%dyh>)!yl!XJ?v3uW{9185DqjTT=g^{<&qG ziW~a@AtvK{M~{M&;V%o5fth(ffX4M#=BXpUD2R*zGJ{hOvu1l6+^2vD5@-kY-UCmS ziNGDq7o!^w%;qs~SVhgr>Vf6!J|C7+4A9^Y;lJbHoqBn?L8& z<(t3be)N`{@HOd(U4@MO_GT}%IJ@j4xR=`{-k~|<+_3%~DbOSS(x%apKPg%dgfZw3 zGnW%B=$u~vv5R-@{2X`emQUbn_bj~zxuVo<^->-3Xuv|}+%TY86|=g56`_6ngb z>+)=BE4#%v*XRUQ{BB)6Wg7{412=M8F)8{^Nx!OB-L^AI#G3EZTvel^Q3AD^o7Dq< zv{3B?Z;&nfzJ9NqSn*4!AjpN;57zJf=y%%Eo~i|uMKwB))f=Q90p}@(Y%XH@aM2}o zFAn*2dEbrz>k4=1k~iBhUsv8X!x`{qA9P}y;|1;j5etP)6|48S67CPVGP(WW*SETB zOY_Y8*w1AkZ>xt){mejw`Ea4L{A~5j3h;q0^oc3Zc(HG=rG&z^sNBJ*cHnoU@0znP z>08~A7d{|AnV+O$rEDqGp})vVj1miW=`DYOe5dW3Y0nyL3>LI}w74Ia=n}rr!7UDq zV-+V!icDV!R$_K-Y%H+B1;>_+R>?ig&$g-F+HPEO~274ULclhPbO}qo=6{Eg34_@pN zg#*k|>|n*hkdv;rAcu<7aL;nmk{?H(C~u%;$w8cS*`KZG!OQ`(0fB8D>7}+tkqc6K z5c!VV+Ux>|rZGHP!*1Zu9ff!C?}z$z>aVwk;w;5D6|m+{JzUU zzkjLXgsHnaEii!D!F3JrXWv0&nyK-|3)QO;^sc^KK$;g9_Hzx?CW2AIT(EHT9n&{C zpUxJ+vxXB#i06hZZ-cM>)=j_T7lv(z;$A@kA`fUWA5H&&nL>cl%{cEE8U$kE z1u#Lt!Z9vQcZ)`$tuUg&{A$pryrkaFp(s>vq7IYrJOWMRYjFWR8pf$bS%hvRf~wC& zZEW$=#@3*FcuPs8pbQ76^Ppfyx5z7-dyIF`3*;N{6uX&NMyURoEXwD`naS!9mpG+X zr)o{+JoA(zwYn2I;jY%}`C?Uyx#uo%$QUJPvY>90?t@TPUM- zq?X};u_1knz^{42O&2K=Ds|z3{!QPz`~z5zFHesBs2qg|a=%YJ#NHfuXWqZy#i|cD zhMzq1#lfa0d}Qt{kFUCEh1TAG%lFUkep~nU5Kg2*tOc}Rwc`jk%P)Zq&4+Cf6(yS- z!J)$*_F{o?Tq)Kk+EdW?Atqe5wDH_fnI-B{gI#&4E##*<`u#W5@@|FziJElWI+isH zV)bAxb|ZLh14~+y$q}WS`f6cM>U5bL_HC%q&n>GU&E4)T#DW(2YinOTm{~!R_EZ`; zyK4@<1EsE=o9u5&Xe*qXtQ*r^b+)Wse7}QVl;JYV=nRwmqSW(BmG$Ba6SaPedK_ee zPwu@<<&Qcz&8Q@@hC{(a^cnL->iO-JH1UNII-Q?&7Qm-GvsMGav=i--^R|mR^)7>p zc=#4r#=SP-Dx`U6GOY?}_ELw2E}EIGhO&I^_RkeJo4u5o>>$;drHOLIJK<()fe3<{5e4Q{sH>U>Cvyw2Bk!P&A~;`@Ewd-WE<=S8*KE;~JRE^R#JNBa#d??b;`F9f?j;IgoO6qINm>KphZB^o)&Eg@^dUcFj-O=7^K= zBdw%gH9`IN|WuRF#9uk3|AZ(v_XyIZN@rs6vS+i;rwRTE@%?A{rwO zMtV#6@0Q4?dt;kV#MH^D-OMoA_pJ8W#>psaCcWUv&-Uo!W`Rrcfy0}B(wLRVuC5UX z;FS4j{E+9%>yEqmii2pWbqLVm_053#K8jPZrgO~EJD1%3Yu&QPqJ4bVPlKqBMHd!p z&_(Up94Y6XZCy>4$SwpCHo_f77UVne(Pu9o6mYg?(qMF2OOSu zM6MaWpOmI{D8eVvfW7cpLQ3FFQrUYD-v26?%H7oFXqyc3yn3PDA3qUZDnBtb#YVv1 zdPnDHhK`jh*1qMGr;-Hz_Ac<;gsY}>d;yy!H(jAwDeoGk*t;PQ*_0f+d*+FB(Mv6d zq$KaVRg_G?QLVszXGP;@qG-nUf_}VYgCyQcZ^V*>dKA$*ne5`9@^TYHctwq+Mev)BQsw;+q!mL=ygV<#&mf6$?<9iBt_uLoe^FT0VA6_xx<^X{S91cS;-*;gkeV4PGo z=+g_pv%4lj5$jS7KBMe1zNS(|ne^r02)@C1h9yg=a<4Cx|84@$& zksI&`)tHU+_le3+Hfm(JimUgBKN7Yxx&h1H zHGs?FB&Z}Ya3T0YB&pQRYZVH#be|bwzPL?r90X8r_x=WaPc5bxm+_y8sc_x<~(OI`*(zU8ocQ@M6^Jz0D zzfT%`^!4-o;V`tLC@ywIr|M#sQ{O})pK9Gu{&@DJU(|9{a4MWh`ioyLxNftnG_*F? z!F(Fh3OUF|7;F*|IHl3B`G<+LFR(E9wUgHbFO#U4{2Y1{{u4Z>RWCKKrd;&M#WK0< z-%o?lf~y;Pj~=X|+KN8v6S&ICc<`iACi(DaShLp=)y+2#a!m_P{0lSW$n2S?wP_PZ_kI^Atj zhs3`LXLeyJ#VjARf1=e98juNwf1byt>hW1@JI91l<86$jSnL=}6?8dY--`M;ifN06 zgO4aXe#R@xCX2J3?#}pFPJvb131n!}&4R7whf!25HBjSNFX4(&w|%;NJ#A(%))bD6 zj{>Y0^}Htso?alY-^T~((fw1JI)rC_V0vDnL924t#JDF5bQ&8?Y(R7N0An~f8ivCS zT-7U-dI#lbotIIXi<&{nB?l+x%R^385(zCII3~19=S_fiR%F9@ByNX4yV|@fHy0|w z(p6A8k58dT6|!sB?~59NlSo{t2WA9$Bm^)PpiFca9l-hr`Y<3oa!_$f-P%G1}q)DSaKJ z@pv0m{bqUOTb?;PIgBC>s z<;O*c7;JKJ}%4{bMo9ir4fa<--ja z7e6ik(Bm6q+YG=PXUIM6X4$;cyI>r!zdRRKyiEnWg1qa5p>eBgm8A~S^~0wy#Q6+l zBKjx$2V{c77=%QbunINQ?mm@ga*0#ye(gq^jIxUf+zHzc+zdiWEFFE|*oy%NS&wu| z!H>it)Q__s4JVH7Vpj0cOSsC~7`xPP8VA+YE3cG(C&4ym#!6A0>TA37!~f5);z1PMwqnG7DZ}4R?d;q0lemi zSJF8nSDS^5f*P+k4bLA@^AGc@RMUbaRcCL)KMOdpB#;OgvVGf zn})>UsBF*`j;Gz7?~#8?n)&rP`y20Z6wNp(fhZ8vGBqCF@)Y*t>#SKaF4JGA=uV!> zRKJVZLc+Y`kjFwoJ5?NBuXq3!j{U>&^ZQAR!qbVpuh9g4W^LPD2B97jnrkQe7zyCC zwAb4t2XRn`82c6UYvV(ANC5?}hN{}?nm)3h%65heSRk~dGF;-4vNN8Oz-57}R|vzz=7r7e478&dyV`@o z6enVCBc-Uly5oR6X;hEcA)z$D2L@#wye|iS;(77F2R!eMgU>d+v`1kDL6L4K2O2Xx z|2xKr7`>iqjyj1@&0sWz$-f{)#EY|dGYX&_CK7t_Kw)3`;zJxP;j$q7q5*elAO`}u z{u#msQ%}#fT5ZBtiJThtcJ=Titc$*ekS6HX2Kyq#fvx10b`iY?J|C9}BBoVH}GC4ZgLpz>`+0W0V7j zHW$;_)VLciEld?)BPpJ98Hu6{Mf~{jNz>F?ioDys}t@ep=j< zY7+OPqFZ>Sp1K?HSx=nH+9xCS%dV}(7Z^?HrothXsx`|d23Urz77m3krZI8SPoZ_5 z^ePxe^JqNZT`>1_~&5(bv@EO2gXIJ9*%+vc+3}7lL&dtj?e`h2w$~uhm14p|~rPEe^vsi%dOuYIdGT zZ^woDOp5Zik7O;*8Dn&*2p_QrB?j9&naAu#mvEu>jF&w<{H)Bpf7d{Pce)+GqHh@k zltF{nbA6&#>4(u3To-MZJBsMjbl;!QUnCCdnJs$~r7<4ZtX&yp}1B&fR&U1@P_l zHKi!L1teLz1RdZ6MBs|gy=RsPFa#)Z#3d*Gmi(~iX?Q!n)IciDVKGBsgHp&C{Lp zHK-*mWSF&n>fW|82RJ4d{9AGbmym@1mP{IJxILq=Su@~VSD214DIv*)7^oQ8j|K)= z!SchC@Trk%f6jL)&QV_W@`29W7A178(M(q}v1_N-uq9^*MU^QEgUjG?+CSvk1B zf)zji=%pSbKA40UgS&p_n`B?`_IrXXZOL(Z3l|lH0)qgcVqbB8d#&l~QLpwpo-4|V z3`U2t%?2uJTGc!=uI52>t;5V1<=08`xOVP>gW5|yy8$iKM>F-4T4J@k^JQp+mpeLW zcpf_O+$o*UakusIF}p{P=BjQo0mz18Jd>r(x`qq@D*DLLw}y<8gW|sXJnmJ7BmoW7D%4F z8(>2iBlLt)yEcV=hxP9!FV_`5TXOgnp(Rk4&&w5LolfTD*pgodF|0&4YrYwnjh^TV zPOT~=w_91>u{(GkuQR3_z)eR&+r=k)GbjS8ghV#_c^`FhJ(Y5bDJMuipd~LJLl9dA z6iYe5iVEn6q+))M+AvF&KV)_z02B13E|4F)rr2qXsR@s5DhO6wl-6|8hbK&9lWqEQ zehnm~`D^{ho8@o!19k*pW^Kt=OSDyHXL{Gi4RCJ^z7Tm*`YX2sH27TB`Fl*N^X{x7)*9iq_HH6+3h_N%{{K2nT) z#NzC7E0}(Y@F3oJtS<~1Rm$0E=&W!+B+Obi_i~?C)-jM;ccO4=CjeO(j~YJ(;3%B# zULe!v#j7#59Ou-!u;_DiTfswgn)uw%yJ2jFSW>Ha96~&m<73o*)=0c6V@hwMbI?4q zDRTt%Lh?Zd@@_8McZo{GeKi#wTanHn~5=g0VfQYHyCMZOS;7oGR86?C#ZZv3iI<^M^#%G_PnBAO^di6MPK=ucruM%{^UQxUvEq}++$um3L`SA@ ziWFEo7QWr0EiD|E_Dgc?o1POq}BkWkoZ5Ge=J5Hkw?cyzKkb-TrJND~~P8+do} zt#f%d9P{dg{F2uWF3|ZMX}Cw}wjAJq5b`q+a6v!Kx`rM?*5yuzy0+8*0&OBtJ7@qh z?FPD8fC>^u!XPx|yyhRgp9AIOeER}_M}oi~5n^Z1(C20B2OWu|=#7p=)gf1pz=0Z?Tq(bq@^ktEG@vS)N$@ zeu09dvebP@9J-M}r5c?mMZ=Eptgp6Ba zw)T?SjHCv)(;#f=4;%$#DctH|C6@eA+2vcvj2UvCdz5%zE9W#lE%UMYIVcb42L$pT z>jcn8m9{+$aLs)kyx?{He*TM*=4VpRot~;g#^ws$n1{sNUN)P&It->>St$Ira zj`X(8PR_#rcF&Df`AxSC7X6r;X;PKXbXgUh3Og5*xPcFis|679T&WeW&v+VwfUE+j z(fUD#*Y->Q7t;yzP6!HKP8WfT!0jOzDBYZ}?*tLRdEsCLfI#q_XpZp)Cz-y+5%v$+ zBt{Bj74Cz*)W2#z&P@0F*hfMG9|2M5GUyIlJi<+&Ch8$dJ}E+oDX>qZWBR^|@bdp* zLjP|X2juxGNDo~Apdx5wAA+Zj414@-1bYp-yZk}8ON9{xq(TT`hG-ZLjQkhGMg)2( zcNoc{L7Mw5IcI!zwNnHjn({vjDF0Do zr~d7Vbj>w{`}}~6#ws1+{u*{O>lgF40b^$jT_6Md?T>ladIcJ=3{6?9w!j==*h@!Z zC~HCJAfSCd0Dwt59HDPISVd!I&HPTyy-JbDZY6NNu=(_r8s1)_te5ZvW6|nd=9HG2pfgkga97S8`haI)pfS*xA$BXaJ?+%#@ke9hpOgg zAYJ0<{%3cy3uj7`vz(@*Bj<>ZI&Cf^ZQ*0vN)P|^o2`D|Haj{~7ryeh%3M>zT$7)f zYj&=iEt0Qx8*ez1)<$dG3mUb(smU1kVvwm3-uy6c6 z&p~ws<)`V59Si3bt88tNb&osdm%k>lcjR^93wDWoK3dS-ZG!%j-7)os^~FKbG`TN} z*S`MNJ-w>Sa=5OSLvM@q%WX9pP2IP)`{ix3e3{KE_oeB$|C!&u*M51{`*T=u*t|5{ zCvx1y>+AV)dCLn1`z|La1-pNcb@Ub8jDGHpRpL^3`}2xtz~S>}n2#=*+;RR5tJ%qY zrV+d>61Hz#rfGq}ydzbPOnW$Q{Ve^ue=NG;%AQpr*Fq8`zjw5;@2kGj^EiUtQp`)W zv}&0%jWzYw+I7WU!s4=m3d-cvTmI*&tG-A|bbH|+2O~HvWI3{{dqPgXVZCx;-}n`d zT=N6gk`fs_)-Mxe)$2CHBP6*94!^fz?dmhmrrX&p4je4zq6MYjO6>jp`l7B3l9}CJ zX}&Hrl2CO^w3juJb*tF}8%YUab_EIQGG1+Fxi3{vduCPkGUszm^Y4&ia+K}un#S+u zIjl6aXihAsTfe}ksn>iR6U%X0_N-iQ=t^~F^e7*7PVP(SN-S$eM0YfYMY9@`D1*BQ z{k`sC+r$p2wR1#{DRd>Pf*o)4zL`1}UXh=2Usl>yyZTIf-%31r=%lcc(Au`%kkc109+`UB8+JN|-KO zt46a`J+co}(pmoZ@1SDz_kvLO&!D&<+iXzW9-g1q(2wHh=ts#w<7@HsnGpr1Av@e$ zoUG#>tHrncmmSXjR+rwII0~w#U<1qYve`UAg zaS;UbL#EG*H9`T6E5b8H-XKKO8XkhH_nyuMrTWBwk8+@g|r)ph%f zZojY=D>7dzRI`qEcKiI?%3CkQ1flD+Hs{#I+S)K@dA_vG&^72Ex<0mZ??F5l`0r7@ zzklnYzmwFgPP!pGVkPXzOTL}++B5 z93;Qj$JGCtpJWu?Y*5)|k&xT_{6l)o!_gms`CZ}`TV-yydmrLy8w@qEcl&KK^vmhu zh(E`8{E=1e+sOHOe&(AV&Ni}YWN-b@@SYX<)Ni>xOuU&dy^4GHWbcn&`>v`&yars@ z#gTdgdpD1LrfHYf$S}2CzY;#6db!t2b@%g^FO@4-z!ZJ(sftSwHL?1#;v`JcA{RWz zFYXvg^f~_I$c+!_j`_W(LBg@rXP@4QCzI4~o;li{mX z-;vW1m00&ojFLIC>Xs2@f1ghKcomaT(*6|NZC@nqPr5;cUCQc`M16`kvYF7N_@5{D zA!%X8<_v45CwLCl2>#xDYE$s95yQ!wdgJL_%#J`#Ebs$o@w{)n zhP$V5oW&>kMIB=+vlL(-e((>R~G-fmuGU zR(Jhq{y6mF=0urO*)5Z=Shwo?Z%?1x>LkkI3t}xRh9*&@X8%uWJyO8>7If(YaqU5^ zD%JBZz+$w$^0~CEs2IrRO4^1NRz~Ne!F@nOtBAu|Bdset)`mE@0v0r5*LbOz=3fD| zhsqJs;g82Y@s$l4rY91qrMH_;J&?pYm+iawX(##E+2|=~nX@lo&N`UO_yqJ6YY^+s ze`C>ibviAjbES#g0U@5Iaa*#Yvz7XJj1yysiz6`R6t@1m@@ zu*)kk4?!X2+%JYTubDUhOqEj@x@Z9+MU0c}@GJ_Q*F`5_kkCWW9%crCyc@IfdKH>U z0ceji+Wu7>^tJA@i90gL$oFwor@*KaHP!R+&fgYzE179)SB<=S7AbZgZ`Wi|KxTN- z*WM~fa`N#m-WCKYO#-SGeDCmw4l#z>RqEXK#Bk35ViAzP)_B{m_fn{5#x<;){gs3^}>^CbuLF`V)zk zl2B*|aSAY>XHjl=Q9hz8pjY8vTdRQaE;OF|mCq?BDGIEHN3PI(?pGbBT!iSowy_nR zNj^UQfQKS`*&(n)sc`SFSSJ$gw93WI8V8G==YH)1VPb#0v!cQ$GcBxi^ybi9$6VHw zdM<&6aC{o6TLC;|NP?C^lR7?;*NybkNQtvO)4399@4sOZ>6p!XnxK}Fb6_^Mk?Sl1 z>Rmfy#FJa9*V&F+>GK+H0Ys&t#g5{OE~u5643ZLjx(`9(K!?rGy%nTSwhahoTy#XN z4kH~Ek>y_h#9EU_4?PYodd7@8BX)u2iAIW_?b#>BeIwL)y)$fKVlh66`EN~=fD|83 zg@@zq@V^wBf*pi&z-Zk3jm9}|ui``G(+cdL(3}Ug<124% ztpm??2S3wBIeAoX8rtRQW0G1*-Ze>ud>mJ``X^$!z{Wc3I!`P4@ZXFmDgp0A-j)md zh^=KAs>Fc~IEsggUxIo!Rc#T+0IkhlBbX&U?^f+VSAVUQH^2E#r5GzSm*f<0LboOV zQ;I9I%J+uN+0Eo7kT_#Z_T=7~s-%v!OiI4ZK@P-!z&uwm+q)OVz1s5TL#Op0d&!SZEK8)#;% z92-`J5}xBoU+Y3mr2JixZJYqm6%P=|q~N@BI?*(DRotXdi=^d&4Lgw{AZuWrDD85M zd@n{jbf!`Pw&7jC<(pJb*i@@hX_`=F_F9@w^zdhQFE(gj%!AB|In9f0A0+7=1SBY=}y02|~s=Sj& zzpn?y_6^vsib8t%?>7vA&6J14qniIHj@DvS1^|eE3*u%v{|yLWCP{Em2y8Bqdd8et z*8DF;Lx5ug(9!0S&RPYfZ2RrS4;w8oj-BzHfFM8&H}Uk~8wq%R<8LnFi0!zE z1!AodG^}|wE=#)FUnPI3*Z+~jYk}nh;ZR2zk^j_K8OuzJjm5^yXgO-)YWXJ#6Sp*W zi-q)+HxEmIJ;4H=5A{vKCl?swS|?QL!%~3$TqV}TP zIlzHgRZ2a~!O|D$le<6cH4Wz_KnV_GW)3 zUA8iWCUNLQzb8RDktXT77?;tUz)ISRNxJ{k$v>DiV(SAS0?#3 zc*+4xknDFE7AtY*V{dESq8QDBd@?v`&Di)Vkw$Q3xow5BA?+uZhgoVQyZLa<#TH*# zIKT@mM=@zNVsNkfN)AQghxe3tqb4=M- z0W9ie7~|+m-RLT9M~EWR%0Y3P+`<|r~!dfu_x zm`9+2n7A6%4#-350~Q$^#Wn9grtQOZFUtyO54vlz_RLiMXsk{|^O zB`|rXK>y$%b1Q*#Q($E_l+zmj@Xh^kxR6}lRvt*c@Tc%EqxHWEcKNC=8WCXUe|kfa zfYNL?KF^HT1oVORoOkB#^$Eq7ugu#*kHs@@6@L4W#$#jp$m%mrUhQ2I}Z=Ws?;NVM9)R{n&-6hWCzovH*1@1zU8 z7MOkl(3`6DHb(F$`R>F{~DtA<#jfKwyAnB9PfVE44*%5Rhy{5D;vj z#NC>~&Cb!v$=t-m*@@xr8xt$NyNz{5qD*W$BTC3+@(V%SrG6Bwl>892Oq#2m%6x2{ zk#uzcQ*EY+8KbSP=Eql79L)IgTm2Jr6v!+gs?HG_&dop5pVd_iYzwc6E`qr+I2 zANk$f3n~@!nUvG%)khxh*T2qk#wXZ?n?YbQ=@fRg_4KVhNYLxzF96Uq4eSwIPpn$j zUL@-Kfy$AIoDvM9u99pWj`tWDbP1sTT>g{Ifn(r#%@5XY@T)EDl>CH1jfg4l) z%7|0>;WHs1Gt4Y^bG*lpHc1VOhhGL4RU%bS*pDfUk~R4o$ESpTld>7r!f2|5t_j$wO0xHh3VilU{h*xt5#D3}>45+UEUsdEDwikLlG*C+7UB zq&iX{%yXXc(2xs!?G`pA*Kc`7v9qIdgRvwrjg$cmu(;@ITRLcBxTg*7$_Yo&IasjD zE0k&yV{Vu>mM;?3rHZ(#B*6k2nzize?p#VznUQ>I8_0+dtOxlFI#4Lc09G(v?}OAA_fnn?chcCD zt)xWAt^x5|c!4XFAx5J1VTCobthH?DB71X#FBGNyp}e)>$#p5f?fi-i@{%H|{N?Jp zJgw2zRvlr3n6g$=Yomc86o$8=N!N634(UEwbFh`MyF4i?rzL5Ov_6Ru%?Gq+ALLkN@og3PcKe-R zmdR#mI4Hha+Vy)yFUPQPm8f-(m=I!Aq#4F9&2xCGu&L;UyAaqpPc8j9DYzr zAjuM{^0>P|!7m|-=$x2@AyDeXikv4W2B>*_&=FrV05NolbZvm)jG_EFYR+$QqIhs+ zat$Fj8o>rJ|5_uN_Y zvBk&*#C*ASHM3Oj%kKOK^nZo^|NLk`&Mi5a1PKCihV}191Gc}TL6S`D%D+Yf+RgCY zxB?VZRTVY!M^%+KPMkp^3xyTg@Cif|63v6|E*oPz zinN`_Ep(RGuL8T8_x?*Gs;y4`h6V1|t*7+{tH9Ab={9)t{=jq4RO&sUmSy{Syvb;rkN}o$e7>;ypFOlpR&f!@Aktp+ouo#-@8PZ;gPY z?SySFuP=xBXvI^}sz9wHA_D)I51FN_`ML{>j_9(3U#fR6+x7CxEs)bK?Z9G@gDp{E5d+!fwl_9 zWzwd}sKKS#d7G~wzJir$u5B+Wzsfv#@EPXcYd0$$dpdLn&vgClNr_NPzZadG7g+uzm`OA&} zgnEusg6OFs-VdXs8ganf%ZX>qG`BX-xYtGLZ#T}Q5rRj_%M-kI!D-5Ccc7C!p6&w5_ru77 zC+a)LA2)7HSGHC7%yp*Q`!%3`^&0%fADcx#pc*V;1dlr)+z8?YK5<#Hq}vjYd_CQD zTka1g%dzxooUukeUuif*ZNmws1#+tK5>9*`jB-+GkD)n*JB9PC{iD~Xj$zUU6?Z~8 zjDYTI+4h3QL|jAgyXgP0@f%$w=`G@Zs+M5>ivSi*8B*ejL{QU8GI;a9RQc3 zEEM_?#~XZH4LgLTq|Fm^Z)!N=o+eCDEACVzjm?cx$ytQJHFPynkQ-*W5+~MQURC(b zRF6>gidFUuUb$e0nOWt^*97{;6|2sCQ+U>|E2({5D8N;Uu&%H*qFeX=0pqd?h29>0 zlu|hsZ{(+7Zuq;H05v@!!G=yH1ByAURPm>X_qY~K7$M3T?n7U_YfxH1_g(`?8dlHa z>7tg~WF?x2aR6K+`15ajpR!)awMJ(@TYZHsv4k4;Hv+mZ}EoF ztc57`B`KtA9_3)d6~=v#@T5UW>p>D9jb~Ct1D^zH z7#`-DE+0B%0tUmYszvRmxJR-H7)1In7Z6#_2)l=u#1gU%%w>&4aSlJ9`QJY48VK7J zy#6*b*g>#z-Kp~bMD3AX;O=2W_KDVqg0`z?&GmR^s2uGrJj4o=-SumI7&AwE%X{8< z>yEs^cawVDe@s-C(xrvE`aj&fvhvK;&x^}@IFfbvoqB=$p5M$wdOhh1i z+%ImEcY@v|whObb;+ro}??r)lOlK0|dhNA{8R(pppUa08mMk2xgFUhU9<}XszG{a* zqb_ma=^0N~3rngd$K;Rnrm)HBsmdTAf|%mgGQXM&I9@-j4N86g*7PN=+RX0vQQgXodw9VRht0C0BjqVV`0MG$b;8AGxrcG z9P!6zfuQh#rK`Xz$o9OQScwR7aGK8E1mxZs(1X}fV=slhBjn>O)TJS0V-elo_P4(Q zksd@jz5M0fSIlC1dDeVi-I?rO4~w_NyjYOEd2H)9o}<}@gq}29=zF<2lAH^{B~=#spHuBJVxxJ-F<(&X^GHf&i9;sX0{qX{KHap3 z)#v-4Qzjlx?iL36pA$OZiXQ(c=-l`aKw86iBKYrvRYl6VZ2%*Bh+XgfNSvfmXj4Q$(9Gd02QY=}&!1riRn_pk2i$xe}VIF!ey(3kgrpX)ecF#i0omgUnq zhtN5sHP(HdM?TEw)r%Ro|B7_NV6q{H!f}4F+jR2M$TLmo2dfd^Kz*zNShp>{&Jz6z zIr-Zv{`ov}X;nl};1e}l5~E!d5jkt_2rPhHnJ0HCs6giv@9DS-+h!CKe=4p^0`C+y zmvfb+GAdX8>cC@c6Bw=qxyk#wbujq7bvI?4V{Z3T_HBon0#|-fDqM88PHAd1Q!4Mb zVP`?@0>)HXn1q6mqv)ap2-fYk@gUyy*5bs3EE6d}E}i+3B8xu!mqtfHZRvA&t;mK? zy$g#|33T~3=3M+zK@q~J@*1VsD4>nh(0%=^@tQ%O0!T}9Lq(>@pJ-93sm*SSL#XJT z$HxGq3%cekpqMDiJVff1GgXvXbOiZCB?V?4@(M-JKl&6uonly%!*FKMHGuDc5n3$P znH#)T2PYkP*sN}rQ_g}t1duP#Eg@+5<5jx~;x$$0?{)6aiQh0&HT1A0x2f`fbso}@)72pbT*KlKgMfSj<`nP* zle4*rjmbZ+On(NQGfgQw91fID%p*U-hb;A4vO#8I=oH$1iQfU01w-+g3T^c*qmUBI z)0N^ekZ|ZSk-Bhq3ty+%1;OqT-oG?at)LI-9mQ!&NJU0e4gmCA{oM&R5e~;nq4!S5W_|io0w|t9zY{&!^x9dZ(rs|mllNA0_0#iMWBw}@8GLGXii!fL70CZ}McNzZ~5a)LItz40T$ zo|vcftb}<)_Slpa_@Xd7Ya3VDP z8v@>n1M|vKwr>t$1x#o4_ntGC(53lw1y$aK`?O=5Vp|QT;ZWU-E)|C;FFc_a*La&oSqe3MXSbh) zh(kN&N>7qT9n0FTS5U^+qe@Q?(JPMq{W$Vt=ANv<3rIFiP8UYv*>y4u-jG`~g}D4e zLab5wQVi3FrD>n7VEOm*5J3=))u+)*4Mbl!gD7ox3TP;itJ+>^J!GJViTO2stMNWTiPs32c}E#`oD+}^BmFl6TgpPBr=4lhrkvlMc&1b%iN zTtVra(GfvEyWaO683aVS_&!eVXD5HVYxI5mUKbO1dnzS>d1jmbm_MBK^|(Hp$0Yc8 z8COE~*4eT}-N=QFHxJFo@yYVH9bl~5E1)^ZKkECzjm`zX>`trUJSKi}FO{SvP~T+h#%|5dJ6V#c=~1#s$L6P**b+y2C3L!RvzU&YXjd zRh*Daa9n1i4-0wB4=;pbI5AQ(xMR29VJOJUUnTL{Y-i=|hhO3N3QE3}E|TJ{xPVy* z*Gqi58l9pbY+k7ue*mA`8Y{ks;&P3TL;2wmbcu5CVQJISi#-&8QfIU)}0qtS?c2Xs`Za%@!X^M*h7qi_OP`rv2iSlR5jDI z0l*oa2Lw^XG`<@D6T2IW$YvmcJ@@Q7GNr?sk1tWP9En(gg#Qr-`1bX_P4BulZY@7~ zCv_b?T5)yNSHwqvm=OwBZU+G77e%ueOsn4@iBOPei9?WMkCh8nW^>`15e|uW_FDNTH~wmE=DEA6O3FBk&jjsS zS9RNRcc61@cL=jiYgJl$`2qRUBnL;G<8xVIi={=C=9f*eCB2y$=~gUrd-6~CESD0d zF(J19+h$}41eYv0w`+&LS`y_ra!CZK2-epPFXA~~^| z|MXh9SP&y=Ix1wC2QY`&^{$C&URn?&M<3I(OpCdYQyIl06eBj((P zNv<~Vvt>@V&vdUlKptftTdQ0zMt40CBrjO$W^T+i(A_8MR%DT7zhO}AsrX*#U;IT! zI->A1Oh}guTy_4b=FDZH{O3#^cf*5YsJQQn{PH5WeI1|XOu%bmd)~N}g|hLJ86`MA z3vG7i#x*v2>|-4A9!H2VL78P6rSx+$G;ssOQmwa(2%}9H-BdM6@Q)6X*C{!=sLA&k zB$5rWJ|>l?Utyyfzk9BL6JYQ<1&wY`UrIy4QF)Mg;jS|@BQSeBVR7c*bU=T&x3k(d`5cw0 zwN&F$GkgEzOTvS7#L0vC9gz{P(K~v6vq zT0)%9f%AIcYT|#rxZ_{Vj*$!t0o0s=gv`#)XWVfkm)Z)3H}h%&f|{D2pE*1(#yMY$dQ;@BddT_VzBd7Hewe8t{*)i!*S;Af?<9A_X#1Sr}2vYyecOW zag@50%J`~Gu;0773|v$cnT<@4rABb<*jD*yEWv?SA;DM*Q>6b?8k}9_xv7EqQHq2i z*nAC!>z6{ZnkzLsVcuh&L z_K&+L=!zuPY8NH~5`5CoN8P!GXDI0+teNQQb_hB%7ICT1Y=c>?sJ-zf`Q=D(btinl z-*&9+bSvUj*72;)0${h14zc*C$hwq>m(&&mx1vdoE_%G=*w12c=O?&TgQb?7Wja(( zdOU1}tRc7&K1H=Y2t$mK@R&3YvtUID=%#4}R@tLGIQn3;+yvVHoKC}Pl;7d_dA?xL zTVjg14EuUU8$c|R$0|!7GHz%25qv$qAPnQ~vpRmVn}7}H1R@#OXOSZ*DEtISX!8hR zCx^CsEcOP(Asw-?xc1|rlC-j@4%e07y95YQxWg>rqaA{pGd>)VlZ5QVkoHK(fvqNv zOxIkk@nf86093iLNt}L35Fj_k$|Vv`)=|3s{5^1=o9Ior#BcwS$4gQt=LO_Q5ZvBG zLh@k(X5#<5xJ^o1w_W1|UN0j10lgG;&yh+DTV1-#D;9@1Rqi?svA*7{A;JBzV2=gtNL@UiX&&pySQTvOJpJ*3~&iQWwiJw8Bz0{Z6No{yo{5%K9N%g(PZIhEw0`1bDUg z5k!5)?wAbo#v!LmWb=N;$A%mJHYw`NkyAz|XaVe@9njRya3B5KK1#VmmVOU=V${7y z?+d!a=rg&#EUF<=jcXOPGBZnQ!!|j!EGjLqTtqGJ$Rq?wpL8&HSXvn?QV~^@>>a*v zeRv23?$e+IqPBtN150h4>s2*z@+Dj(5kQY{&Xa2(4Jtbp zD~AGLK9E#c;aSFfl0Dh8paAp}M9W^j3#X;2jUUB1!#C zS?0+}5c3QbG9+w4e@g;*V(PP`rx)I-9z?M+E34unXl21_fG=!W zGvn%wB~qQB9;0L#UeZ>-wuorv!90Kw2vO(x^+`Cv!EDKl_<|?$DlkU;Ub3qfmpL(t zClF0fWX%m@Ta5i#;o9BbcrBGX=F_0d1{}3mH&fq>g`rIX&1o(2Fpb~(v303Cvw{HJU zD^w(7CxU6^&qF>CI8xcj%J$t&7@$Jz9B4Ah-`2!gRiMBisv6LUdQi%lIrXvQqEwDR zB?xzXgE0g_J3Og7eofly493<2XhS!d?ITo#m>ZiOHn>HGLT%IOccPoaM zR7a(`4Nxh(XyWadYUN4?xG?XDtAfNSXm={?$ZqIFtCbOH;{h2D5>92_NhVWKF{N2Un8oz_{*SbCY(F3SgjJpLo>5^mTynK zdoS(8wqkU(Sy*mtn~?T)d=v+W++YRkJ7+Y|el^P$WfD_j0I^JyW9A8pWUCa4p;d?t zXZR~)FrK87rC^JJG>UWu>IOoMXEPiJsgY0Ur(?syZJ$SnyKs$+>1ATpFNW(N+HP?` zTCw6}Q4Wwgcf>H@E)W$bhf$ov34g>tlLyQ}jIY0-5NWW8yN;bj)?8niCDcISUMC_% z?OOJiy?zyT8d_9u_aYNu5K&$jSnTe#nNMt3Y*VnZ zkbRE*>=r1zmCj>dro+t9=c$u!FY}e#00~(qsGHHP!`J^^;J?p$@kR;3^)jLWelm}N zRuJwKosU$~$f3BTAuLG$@cqo&QHtXB(SiJvfoO!veXf0q_7l{GEs}HOQU2-N!0&-J=3jUjC^5=TUrK?bZeoE-o>f zKfdaLw$U)q@_cztO>`&HTBxZ>$xkMS3y5q3W&0{2!nqf;r~c*b{_)h-5&w*ueUslQ zrH5-ctpB~WtyTT4Y*6mwn(?-ugCnAY@yX-zY8lz97m<8>4&K&phpB z{vgKB+7#=Xt+_raW_%fkFH(E{zJIIlxr0raP0z3?1~IX}zb<3gi2QT((6r-(Yg$sL zyJBl}e}6M`wXQJH&O($CD-{jD1ua%NyoRIrR34%VLL-#cVBvZ`_4mb^UlhWCZ>Bf@ z>;2ACPYDSbEf<(VXh7>uP8DYf4V2|rgQfSFV00`OWtEB%@R6r-I6RI}adT4}$1itu zD0T2gcKc2Oe7wDXp3N$UKJY2xQBcN z@D3aJ>&j#73OfMMl(@~Z7wxfWJ=t%u*A+W)v*U^yGJO2&p6J%Qk5?csTMjD&HjpLP zAw}9NWs!B_CauR{rOtSzu3#lGgP!FlSct+eR(+pVi7_@1dK{X0SuES)Kc08H#} z--w%YrFhe<$6*lW@`u$mcA`#mNaN%a1YNJr;Ae#-^mBe7W%(FzQ^F#kulJyG1Vji5 zQGv}1p&TJmgMkCwP{{s%=y#68`A6#-ha;4fBPNfEMOhTM1_KsxvGo^qEs0v9`b{u4 zhnP|R4kiy`T?p`p+mXb*FFJ=f4sTBsNQJ5l0Tppf$PwV5$MY0`BLv8CFN9Gp7yO6M z6G9>2;tyULx&_s{=ik5*{xfX&-@qdNGpzsLz|#IRZ2aHALjE)C*S~?K{Abwc{{$oE z=5*!F<^>yq8Nlv-nuCvdd(L!7qk$!mB|c>LOUr@LYscBGmqMM8iza!wdj^MeM#~VZ zksyrqv%iv(G<#V?3A}6RvAfSe8NcI-{t8p%nT^$W*Yd4Sz{M`QE#eLQb~?K&b<*@8 z-)Yc2MODV-If(PH=hR)=1uIqpCC!E+s9DN7!oomUH!A8QW!D)oMzQwBd9NM*<2EFVj#HRLK0qGTOk&yTU-t#r{o>A zq*CJA)MB~?9V!!6g}y}WCa;ynlkLSskxW%4q!a(OG$4{1I)@g^(IR_9aE7f?aa^8A z&dJ?NNTVfEo520{ZAX*rdmbzLAWe%jsnpOs;U7y(5X+P4`#Z?0BK0OqG{e9KqC8JkL&YN_?#HvopPplD5E&?d;kK-iItb=?L4Zw@ zG$0j)^QOmpPZ4Oxd8HyQ0)8tESJ_1Gy;=-3JEFsfy0&TIU7XUPoPeb@c_Yp~70HRdBzM{CWKn!s~9qiM8FZO;nu zxn*+`+3s(XsE3iL_c>7yGjS6=ar0m}?HdVCtXS`a5u&RxG!HfCgA0?_<>@r@QzZ@e zBcqGcE?sgOPR&eCj~x-*fx}IvQ(`q_X87rAm47_dBb=&%fiq#O$#P@xqpdR|(&0`^ zw;9<+n=Ayl^@EG~nlLXPvr+g+qnEcH<-3-#((k6Bq9?m}nd?pB^qnpMd%s_#b;Jk8 zGWrKyEz$d7XQKEomvrBF76D@n_VYVv=Vq!Y$jj&;M2k}%8bR(_VjCZ0(wXA^2LDol zIKmp|NBa3e`&1FeO-#jrqeXq?OVJpSc=zn~)waOVmQ&eadbx$p>r7(;kmsxfs~xLt zJ&eoD9~LF;Sks$|2AS!4=o+yZq+Gen*?h6#pWY6y{bI)kn@MvvRAWmY`-^nZ<@)OM z=(ECo;?p;RG!#k$@>?NePcXa{nzlw;A@%0zo?2~tI9%X6+2CU?wVB+A&B%+J)Sq-S zwpe}*rutuv5+ikZm8UhVXMpXmR7Gv& zDmH*fM$3Uz-!`%9rWx<3>sZ`+*cQICwK4dU!pqQ)SS19r&lbfi{BfL(G1hvXw)@FStvwkrCLSP-ky#lxHiC+6j5sb8% z=HcNn32DPC;6v2D66|)nIGLav)6|Y0!@SH=(YD>mq!4E*_8J#HH~Vqx@N?TVhudXl z^>3pJsoCHp?GMICuhMeJs>1#noZwk9(b@F4*~wcv%o@Gk+fR=J94Sv%y^c)ON?|5H zVtRh746M>|9h$e*kJOgksn?Pr2r?zcYN zE6<#bz8t&c^9F@|(42s<(&oxE8YFwjJmtK@41X3vNw#3jxJoLS$=qnIRMDvVj%9g< zwtAF@PvZnaFT6<+eEIZ+Ao=Bj>taX=Af-_C{Uiff#*=#B(ZLY3W@Pn=e+C-a|Mr07 zx5Y(DHcs)=v6`7RUM(Vds~^e+?wAk7lp=dSN5rMVu=<`M9#SFAAuLzy`22*dZ)%7p zY1fWIkJ?z{5Ina9;>7FFf_ZdzqbXhbITO^NZ7T35Qp_q+?3`NJev#l#GIhk|u2PWo zYIL&x@OP8q&UrT@%FDGQG)gAv)Uj0zN**D`c4fS+=0!Jf5spTwW$n|N`=9;Qy8@;6 zB{(Z@5bBk?n8Xys9HZAVeR-&-?5rcXXYHJ=>V1v0W}|(1M()zBKNWArh?u=Zn*v;s zR#JUwsv1ANsTPf-+-s#$ug=*y`=t7^ka{U~O#@ioROQi|64oq1A2k=ntlm^X0$zXa zToTUOp~;?d9Psc-Q;3bLnvxJA!&HC3@5N|VZbsd2KOE$J!KxE3TdY-Wv%t0HI4*KP z*nk-0WVHh`#jW80WkK3Y_pfPE)7)(!u3x^X{+wG0Jpg0F$0%xk`i)6g3pomP#Zy0O zY609Rs1YBFq+ZO%@{gbhXh#40#5*0Rvce{*zwgHS{~}W{3s)p%vzR&_i%$-8-sZZR zrKaz2DVqDqdf$1IC{7LZagPfgoEMjTOqNcHdrgt0%M6V66Aj9<;a1}`v?ZvGC}|V* z`3aF{ZuqnqUQ&=+?4^hhoEGj{9BhlmsV52Sxf0*KsZr3(8^tefTu!Yt#XdP0Ymd!G z@0aGQg(5SxNX*O==O`}(lo#KKs;_Tqrsvq28+y#A`?1ww>h$2#EE#z;Ya_WjJxk=! zuxLip`_0%HuO}2W+~L5C6mrLKMD_GEun&jqZn>^spLL$eZg|qDZpn(K#SN{d-Yw8X z-6ZSn2+Q_u*bru@$Fw)T1q+Ek@aTR_dbLk8Y|&cGulsdY_hj z(xmd(ucDFcdKT|$A$n-UOlidYL4D;Qeu}RchHP7~F86H5qBtPjiqb=5LlSR5o%(uU zD0-h@;&6X5pNC9&i!%O;5V zsZxAz<9(fY`NI#3Llg_|z6uiri2IL@qQRMJfY@8R6Du`ULxS8ugy})^q9-NM;B*=* z|F^dm0PjT#*c=LzhW%BmwB;X4zx{MH=<*+^qPlzF-(TZaZk?5I0(@I6)e z*iIMfvR!0#)SHdBmty%24JB%aN`Q9FS=Cd#0wiU-WDZ2JHiEo#W}On!@K};4BzO4`pFz~%kdC=DyH4WSfL9Z(5-qVv{G z3Z)SqP*}&ZRLLW?1mC-agkkYXjdMkLUz1B;q}pd9)*z(1)u=*Q^EEVeK>@pr->Y&d zX&z6nGNz)cirQ`O?6$?>qlO8U<-uSi8NqD?62LXftdbP=HNin{IJurVBiOO34!H>I zH)jXiN*+w{dq&G9wvC?W;?^sSX=Ev?EFNer)~qsG&h$${v#Qt^So!#K2qW2~Kkp(6 z3dCpDrYTBV{!xv_V0~Gv9P@%=;}AoJmGTn)>=g)>FjMj7q=JC&v(30guHLC2pLJw0 zKa=$;n7AT0K!$O~1&h(L#_i*~^|v*Q&~)bL(i~BfmzPr&*|P1ADZ@UfoFbZKw)#9; z8l~+MZww$vIcQPP_1i=@!9-PFr|dKiaGb+JZaKbeAp! zy>S32{$fXEYt`Ow|Lb4kKMYtAOaF)qn=7x!@cc~cjIG-Le8#Bzfk8ef`7n1+F~~e$ z&&Z|9Ja6jx%a+e^;QM{VVg@b?cyd}|z5(_m>xN;rvXdk2s(Yl6()ch_dB?$?dgC<) zcv)Ja(ei+nQ8i zCOPW*R4&G(%)-F2!uU|n#&uMB+VTRoZU>01a0eP%@6x%({UHLjL3SYnchqr1(Q7=@ zNMl0ljMwVoPuUPl)9Fw>E(|G>n!C(Dy<;_HV?Rbr5Y_D^CSgK?{ zagK~>Lq7?sNOJ8gRS@HBiRqHVHzq{HRC1JND}l$K z!J*Y;H^lTVwvWGF=~xt0x)~!D8h$Y8&K`;yZvux#rE)_i8_hyu@lOf#zo^M<2m`u@ zf+m|Ow1fNQ56VR&5lH8+c=ejjG+Su<2nrAV3apJ)p=$MGt<~{kz2|jVq>ab-1_$}i z3=MM;rwdJx0yuL~!`o?tJ><{E8w7BqO^=0^83)^CjT(>1Q0xE}UJM}MXxJ&e%P@|$ zF4v@$H2sLZInr0;I|IX%a4>CPG!(Pc3I|)Z&~Q5QQOjzmPGC0H&k*^fMvG+Bu9>X- zLoZDZhbjZERFpQs;$5ZSLFqlkF4c^69ysKXCKYKB(IPF9jMf+5>VJziXA7p+LNv+g zBX-tS3@z#;kB(dfVYDEogQuCOoGK=YS&GQ(zkXF4s1c7qSbzU%l~NS?6UZ6&LHFe}niz7X`8s89o}XAmh-sh{m1LY7uTs`0Rk%hx zWyN|SaSTI*8@%NCST*E^hLK<5C%__qV*Eu_3PHncpr!SmNi;Y8zD8QX7VGoN09Mk% zexU=Q_IHV3K@%@M7)5|c)VcM#?Psv$b5$boWLs>W`POx625BMG-&~= zXzSO-{(o3|3#dARHET421P>nE-Q7Y6?oI*(clQ9ngL{DB7Tn$4gFC_9A-Fr?)ycgx zbLY*x_useHTdS+iuKn%(RaJN8bm#Or^gd$_%+x5?VS&+NQzo&-E6f7nN)nOv0oCio zo3NWus$P?LdH=xIaY4w11{R$bsHpGXks4=*-O_0(Qmr8hav8aIt3liGh2*M*XOjp` zJj>Z#_Ws0zpYK%K$5PvG&1|QbT1fuBUZysa{b5(x&TEI{S-o$`YoFwhHyT7brpa55 z0&9!G#M%8?<`b5a)VU-B19!&X5MSMeu{lnM_C9(+jeJ{GyOaMpH+A>X-?*40)4(Mr zDrB$)mc;f#jA&eqsG{g2i>y)mr{Z7}+d^d)i*jG>8_5Tm2ilER$~}VX=Okh;U2xNL zOqa@$T)ywiTnbvIcawgC3NoMzHJ_i9ERTK9yd=5V>G3+l5mOO{D~2KJ9{Q2A_UxQG zMOT1G4C!61FjQIzBij0+^VT=mb*7E8LL0+jsh?X@I`-VEch9`PIvVP3)ixs&7Qeh1 zP^(R{x|3FvA~6=AG9~MWYQalP$2pny+407sB77%8{emOkR7SgGXvy?wzyWWIFxUVO zUpr$}7Gor4UXc*>#CGW0LiW6HljASs3^q*yIvxUjh0`OB6!T-%?q6)-ChK(vTlhg? zR_+7?Ut-^khAT(Ph;J{XbSuQ>$%r^qvBg|`wVkRo*}kFg62&^@vd=^KteLv8=7(zH zIwL)m{+Vo7rp13<=u0>m`4YGm*Y10rZ=P1Y&dVl|^_h)FhEhFyB91az5qI@-g3L!2 zU5$-{bk%9|6C#x|d?Z&ymN@{rrY0~MAJ5dF;+Aiykm*A(oruf zuKZ%875k~PXsE4nS;A;Rb-J#QURymdEAE8$ysTJWaqcSiGLkmb0mAFApft8>yU>dJ}@6ofrKHF+3$ctHY(RW~~-ge#Tr zn2;{3)}VeVq)l(9br0sUJ`FTFa!y_c6xa!Sm?v1(`OU<6mM*>H43Zq#s>*=C&>cyQ zy9THGfxBGx$#1g$!cy<@LRLUU!A7#yM!W5z(KY zk!cET={Q|xYAn6zks7nbO+9GJv_7h!O*D&+NV7RxVe!lf(dA`^1}#4 za!;(Z&fPj)_&P>AVqe`f0hqhq`&a#?Xb*867N@_YhXpEWvx5WJ$AvVoU&F=btKZR+ z#GBR!d2EJFuY8vhr!NsS450lveQmwEob|SBwYt*mAz+*AjqQu%SR4ZP&upKV)5&wI zFUQ0f=2t07lowo0vq%%IG-}W}CF+-a**kHqbBYac&U6CwqlX8>9DjJzTr<9CdiMdd z*fk~BF#ryI$krOG^&m6LQdaj%w8TEog+%UvnBwf2JoJzvGu!Hb&^G4#3q5Q&W8H6? zFl*~rIAy}KKO{DC)lAx)Y^+y(avVJ93|=P|>vn%v&;RbzCAgP(e?aqHp=(GkGXq8q zE~i4n8+>xzdg?IJDKb`kE@b&^m6e;@ROGMSn4TW)$Kt@){S!qGF4Uzmx4)b)>5pu{ zHQR=gLA-+5o5@+HjHijElp$xI*pQLyWx41omSxM!r*=Cm6t*XEsG!t(f#U*b+l%2P zx4Pe{N{&7wO-dn)XoK1YsRd0gC9#x_8je=>mTx(J!w!#&(pSLZ&Y5Z?w z6O>*pM$-6~rZX_-yl#V2hWEx}%^8cThR(%U=hA~{b1@n-YTILk9w=pKpsf31gs7&m z5|n~g{Am2!krI`5Uo5;(hCfXP_IeU!_!e6YT`3Yz^xQY?MHtHFaHDy`^KT~>dFqyH z$j`1sGyjCv<=P4*+cL z&_(~xj_!7qJNHt1>Vk4TmJzYR+~awvHs#FRl54t|xCno>$-JqiSd0E%H~K=OOY81W zoM#^$x!*NBd?JV#HBI%-7m;=BH6a`R82oAP+o;&5eB|C8Q@$tl-i@j#lESXjxjy}= z{+mr%itkOP-eb^v_f@^wDl}95=}8JhtV;7RNp|>+Aztw)?G1^gMXqW?!|e`-qEd$Vq|hu5+>6LB&%Vct?x;2}}3 z8|qkbdx``_iYz+~)~A=7ND6E3&L-b6(Nyf;V9bSkV66-L>nmXIzv}0`+BT6cmi?6$ zaYMs2PZDB4QP|^n3s-vl66bJKT;w$>Nx;iajsw2&14$cMrExkv`t*gho8^sV{p3p|8W)NdTbne#Xe5+3RrrX8~rW`I8f+Sj4^TMh#0uWW`hvODu zPZau_AAY>J#tMNG%V4#R#1l3}4TW)g5k&U+qC+3qg5u|w@oP)mc7%3y-waLNT_n^2 zjp;GebS{B(_h6s*qp_hlX+C;4(a=)U)9GW2LAzTre>C^^V&Sk~{4u2HkheImGJ1T2(m4#}##q5nq>h36dAqWAkDW~>Lvlz9;TOkZDe@-L? z(JNglhR5qv)!ZmQ5t7+OK5cG^#P4mfX;>T)KF3ea}URumsF&s63ah0rxu;VZ*^SRr*eX0 zA`|P=-rg!+oT#44UZ!V>J1e{1eI5qmx{m~p#|g5^d7O6AeABaLjH8*I-f5U^ZEAn% zoOp@3!6{X2>}G|R^Way8TF}=^Gp{+@Uqv^F%nshaAF-ir)qd00ZNt02#88TIqVzgy&%mVyinxe_Kj@7NC9tC?yLqtczs>T^y3tW~zw1|C7?*|{~%HS^W=(7~X)ay4wU%RzY+Z2_p-g!P4q9E9b*!W>%i4CbE z!FLWeIv}RPr~e)~>0iBg_U<`bZ-OehLMwsBhc^f?Tt7sXHA}a`BbX3d`+t&9ZrKy! z|L}CF=k&R^c%c-zQ^EdRvJ0*=$oGYJ0N8lf)8D6OfKA(0fp`qEG4W8pHU(S0Dn7<5 zcCbxaAj3o9f^8287WxGe*e>J#=~f~&SBp0y9e7PxM&pB~7*M_mZnH^=&`?ukB6Ouq5;@}>i zjC@=q>j0`LHP5eTitI4RoyCz0L%4rSCKim=A9FEWM#1zUSOqWEE=UG1mLd9b)I1wJPYkb|JVnPdzB#NN_l_qAH$1I?q6N9wpc7_JP0{GP5&V(ko!bkDF2~K z=tEEbSROA=M*fwGEZhg2ETObLa=*-ZWey@0qcC`n!f2!rbNMMlg;pbp`|iZ(n~|D&l|ZQp(hYDgP2#De?QwV8BTnsSU9z!DI_{4Tm&XDj zI!vIndfsZK{IMsI^LjknT0OfSJndz(yF1%+cq^l$cGS>^(!vTcq9^uA#w!G^H}1Gg+RYC>etb0@P4i`1GD`^*^#Laf>Lt; zBmgh~KumgnJe*{gfz;&Wf}sty9^b8RBIp!d*1w34_9=(hsjAQxi816}9)Y1NyoS%BjRL=46fwL|&_-8yV9r!GK zL#S2V_$+SVr5}I1N#>TfX85OreOkeCUX$n%yZGiubotB@yg% zn;&0Tz@Jq9mcOXmqJ-Y7t0IeU&?2-psa`hucV7Fk?rwXfs^;rz_aB^FzS~4NwtQz& zuxR-XTTrRpAJ3p&wzd#=KQFhQ(F;kE79VM-IXyb_x2g>L<$2%5TwO8>dsV!8F*?ps~xVsM> zgXkx%h!3q>+!d+%x}}xQs{@u^TRI7MdpVNux?2%NwN$smdp9b?p-LZs&%wQ?LOi z!#9D%$a^O~+zEJFFe@eN)`7~@47xo`#PhR{qrf{;h3;L6BV&Zyfc@yu0QzKlRp5|)lEQ(Sx zwci^f>?bH5>mvBhd+1aFG+Cz&{TMB(Ch6L?4<7x3-nxXH1H9T`;A17=H10Yq=>1-} zWi9<1H{|SH?q`kp>N8xqAC?k(e1MR{Z#3dD$L6iSr+VfLUOon{Z$Z5GSm8;$`_XoH z;5p9tYS%RZ8pW z%iz+3S(+Moj{!pXWu{l-JVS3m(y-!n#WUl6M(yG@6swzAXQyzs9PanRJ9xQAu-}af zEILY8JXnedTM6pd3AgCbGTuXk6t;d{ap`1N{bcx+_AY*1sQ(ovPG{YJ-4d;t zs9kMO0E=?^-ZiS|WUJ@9Thlg{JbYat$I-0YetFJzEWgx!@gGkPuROt8m4yryyyQ}= z(>>cr1`g*-e)Yn`$f+Lfa;}dW=0_n@apru6H5H+p!=xt*UBSoQ(QZ_h*`ui<sMVep#q!sFwb2ESq zj>0D6H$NLJcxgZzVodh^UN?5Zm~1)4D=D4fEA@wCo0R(r*ZGMK{Tl)K8a~fpcGgHu z=p_0p9ACdr2rI#>13s2`_BKa1@~?}?zX!t?H6>@?*00u)vb8R`wKCxo{ZOn3W4{iH z!J+N;k*Y=|!!y8Th3X%{^7LWHZ6n=)7V7I@hR4B)G^CAWm>e-Mi+;^*Z55s4(@T(s zpQc61_9-A>G6W$pP8e&dx*(dnBJ=_|x=-|d6Mb@)j47GMi(LF&?5J^g)N@LS(Klj9 z6Zta(I;m}CEB58-JrX=_98Qk24VI^$a5)X1sq+dY&I(iYXm=Y0N5u>wQ8HGp5%=kS z{o>D-9p*qr<`@z?KF@IEW`B229&?=bt7b}W+0j%%c+9FKpQObT--yj;K&_}|{JaD% z>zj=}c2@QTx=r;}nnNY=cU1~!398tUCS&*__9xYM(U{sI)NhBtr@^0o6<{P+WKh*P zqw!{2H-4E#^WO`FxxKU|`gOcmoP9g9UOY)wC;qa|ZS!ip{gANXQGeAbV$qYwwn^N& z4Yz)YtWF1I@hED+2FCij@38J=U0p*7m(cy>Rqiy8f<;sEu>;!V=~1q-HP_q{B6t#U z!`AOYIxIojTW*%Vb)AA|sv4C`hR$rZO|*5%2i7pws#{LcOT+Dlg^SjeO*r*hu?wWbdxn;n-LDVgYQ%>}SlzE> z;+<30noL@nHxO6&Uv3ka+#Jm@A9Hs(kA}JQ;)tyi2k zl+^w~2#eIG_;%<#Y^pfmPrWucT5F9PZm=;o!*nHEy2Av_ zfR8J~N83+u5p60@ao%YAuE}z~d)Z~d{5R1TqyVnDn}=vN&Ad3bdQP-UL!O;Con-1S z3bstCV;#QvfVXxb7#>`yt(2^El@XqhuZZ^SF#|lkG3grq|A69x1t|^~&v7>Y8fXOT z;33}EahvZ83_q(7(C*+1r)MbmSYxvGjh86#?Bw%;JW8vEx*h@V>)>e!-=J=#t8~IB ziSSTw8tICt1l&`J#`p?p!-xSUMpq=pR|yVJ;-4b4hL0IgWSN>pz)^@CTkahrf-FU0 zsVl`yIv`l!hm;-konW$~PMS>S;W9`oq|;X`;o054kXRlUY;PeW^xZWV9=OZC+OxH`DqbExkObLxa;&( zFNxfy^H6!9aiDUJlo+#YHOeMzc?&v+y;bQ zc$l}62pg{etu2e`yHDqb+V7{dYIpD|r>;Q!fPpXPmNnj~D~-Xy%;Z(X42EDsHJcxW zs!xCt;~_?jJs{aZohL;d?-cM}m?qw-(C`01eg$8y{%;PY)$Dy1uyA6e`DlXiAvymZ z;*ObAaA6S^WUp|dnfEtn`!7LiwF$@d@x+g*#VTnxlwwXXFSkf=4$ayAp*0T<|AyMKuL?N)b2%;GsD9h} z$I4(l1P9!X{@5FwX5F03z-yR+3ku{s`ZtL&{@~xE|DP%TE{ubT<(EY`y=Q;dj7j`e zahI>O8&PQhP91Fg)w>4%`f8LT*<3eerX(9%Gx@SCaI~A^=gP8*ro$FeEm}KrJYa_j z0SR2-;Mtmu+PT@95ly?Vm<@B)S6>(0!o**-a;&UQyeo#l#AtHsiv#f613u3mzb{gN z;TS9c#zWt2Jk9yGHb{Lx4U*lbL)6D*|7AA?eLdbodTarU0SpV$+tVLN{f`vjsJHr| z_hL(aITq`Lv&L>k4}PSU!7pgRe+pLU8CJgTai%&$4Jt)h=Q8~MDoUmkGn6=|QJDqB zz$WL4eYeD6KV*q*>sPqWHJ>M~{+te#V(JJtxjy*j0G^B{3(}IB@$Boci7M7lE6(on zauGf>0U9VRCoiVPa~!RmhDqfNRi5%a*7%FEUgv!g+G|4BjhpKcR;-!QFQ2o(Gnb0|k9N52Pz#1og z9jf;CdVzRO8ZA`vBEq8Qd)wW+PJAGfVYATZ&Jb8M7Sw_+)#CD>?qOm zuoQRi=dOi<@KQm>k~C9gk-6#hLAjGElB2#iM}Ef9H-7F-7m?9(tOCT=D07Pgu z2Zgxv{0KQqAB0n9DIZ5wgd>(a$Ww;9+L3f`?6NFHzxToETWvl|&K$xrUC`gABd&A%IXT z2LLJ@0O%KT1mLqR2*iZI@}-utk)b8@D$!z@V_j{^aI`j_s2$C&3;Ji6+lu9~GD!1s zT@rgVEO2?&+Ies9?*_pEc-G>CxKZ-f5%o*?CHe?g?>VNE`7vjMgHQXVK?PIzYP0S- zQ|<)*;3?`Ru`SwC&Z-&84r#51(A2Vy%j;TS){5sBnyooBca*SkzLM}D> zQJV~SaFj=4rVRHLt7ziMx={%0TIC>yQKvvW%_rIvJBp~j&R>|4$^~IKpG$IB-;aq( z8?mQ{#)XW@V_UVaDe1NR{v-{plNZX$>aHRr&FsOT9P`@(1U{JSOm@RsjwMK*zM8j-N~~R_mnh)K2`B89ez@sr5~Qw?k1kc z9dSIZ4r}}h7VvcbdWnNldTNw4N^j!kN-zS9k|5MEglYv8PB}(^s3KPs3K^MDRLUpg zddf4!0)jZ6vS4==^FSk73sR!kdA-ENq}_BG*lS9IA^TP(K6+(Ebe@t)Nn(|HFpT`Y31X&qpm1ttHrr1JPRLk*HpsqnI6ekM&*|empZlif0%TztFBxBe!IRe zBH&BHt-!j3$NHaUuE3`nJP(KK<=}``bgH#}*1qdiG$w`7>vym#_$$dFD0f3T?m=(y z&)no(pL>rx*cPU@gL`+Z78@xBqtArq8joeyNBK{@t1A7awe zdDrZEf>DKihLZ7i-1`XHG^P1Rz1EWd&w-`4QP%svTl^KL@&*U5$8X9|vZ;HdFbpU{ zX6*A<%S(H>Ffl5Q`5n^uKLjfMCJVBrl^JnAa=T#*$G4+0azn5!7@*OtQtw$vp0ZKd zm-!C;W?3xt+$*u6UyB=4;EDdCOn~vvFNF;Q7unREY5#}(@W5a+$1^R>+f_O)=`bdy z-D`B4AND9j$tIerTIBIwjn|(Q#Z$|enk}1eUJB2>eqOYqffT5!WL-!4=A3BrzKyvvhf6V42W`JA|UC|gtG;^5k zZ%U?xb)%H}0Q1553VQS2%8z`kyS=2ly^Uj8PW9l)jixm|)+4X68hM1Nce9+{=*!IN z2K^U$0E&jbJGav&BoFXj8PWl9~*v7jS?=V2 zdffR9w1&cFA#S}58J1Ay;*l4Z&nv8!KD-Qkr&+j6cqfy~i|i4jND%n$dHy$Ho0OuB zvHRgY?hDQmUSyiUdMMt}L6RQ@O^psNc2z+!Ixudy45P|LK9Oi@n0^>-g~ZthAD~H~ z%V=NGIDQb6h$?~?8qoOgT4|Os>^=^`8OQGrhFvvwmBr8D<-ocL#M5j$tv3QR&CpTy zGtVM0I$*wJvvanSL03H|q{%`$k+8G+DlTRH@~u)3-fGmDd)!Ql3G%~MFIvo~u2aDsq3XgNIgQn!cq9B|8^Vy8 zr^*ZQNo4MG)S8zg?jna@*@zVRR)_v4)gzw$fOF2)ci*)kPHrW6bmn(a!I|=1PpZ@- zuu|Stpb$oPK92CiOXgOe>%ajyww32r%>~02p-DQe%;Ohl{=vpLoJo$M8V?7jRfF!M(+j|wb^g8pIzyD7u zpMXErD@SYx_ls0>R1H*gid@uQd9-xreXR(n=mvar=UyX{XPZwtiRuMOT?T)cX1;tm zXp;5%NIUx^<4k=}A?x+fHwNQKPlP2ELH71n>u;3)H$AAHsujOSQ{T+L8vSW=mxUj| z*?G*$`S|;lFkZ(`8iV*z*6gR@u3Lv+RF=OkQliTT@!6|0w$n3^IAD>i@_9^6g@*-& z@ywBN=M@~r#sZRj12`w~5w9$M{Ln_Nt?T=rvHzQ$Y^dW~qV1t+=VjBkL@cfOR}SR{ zxuWr$o%jbgzqVlJP0ao({(B_BY&<8N8J5rZ)93#TgYLgt;QiMa{%`&K>oET<9T8$)9?>bCBTOemw3AI~hu{}Ki}>iG=k z|7mai9qGTNL)}haAX+3EPM*G-s5>uO5|l=0X3{hBcBY_bIQik11HBwoUfq6=8i)0T zt8?PTv8dW71-8;)^>en7A)h2WW30(AwyJdFltgHbjUoDc91~-~VQw}A^PWU?h)(?9 z(7j?CIjq$vH+>}Z1>NaExpVbU|?!T{2kN3D=lF5-%9aiSevniDe1*Hf(Ml~3Iw4;&>INChaeIN zqA2N&iR%pTTZ!qkV9v=o!Id$iX@*h$1Ygzx`2U6accm%`ok#Y*=nt5KO&$85Rk23B zdRW(Q#CY+&CK3+_yxI~GdxIN#)BK}V<)hTIsKjshHR=bKc)WKg2G7$L#z)EH=H3e=<%=?d?&1v9=# z_zJB>!uV&BAi+Zm^W}f401Y9~5Ea73fcFDxSfEA(Y7C$z25OcuN7S;UO2GND<>+j)c_9>n;eUPn*Gdcjgj66(%^nrdFR9On(Om{cHj# z+6X|ftrMGbi1NL{czsB$z)cyTDChFxdgewJ$Q5+acXVKFN8ZqtQWEg!x80aXv7 z-T;bN82C&fJ|y64hxm9QzCgp-J6{w?DpEiRL8u_$dlLnGN4Kc5|Cz>=9L#LtSJw8AA7a2CaLqw1|G;nbwIqc0rR4{8BVDcmIsgoS zR%q~<#s>|c-2__4c%W?sT4>|11l!-5I5l_aUp6U*0-etg&=~<8J6rq5%S51?0JMf>2jzEHzE<=$BFQ`& z5E7}0^$)_OLtw#Qv$s%3(=Yh}I84CJ(;%Q?Dg#qCFo^?GFfhRZ(;rEp;t%|Qa0JAf zAxUOwzmNz=G{{1UfEp_e9I?PblZUQAQ$#0ym?QO$elONt4TIsfJYVxnPqB5gD>I-! zP?RJZCDfdf2#Z3N*RrG(5O#oory{}v4^5&sPX&&*z~KrUcfj#SGOz?w5Da*;D*f(ya6`=0*g zk`gW?-U@&g0I-ef(dFMw z#gJ2Li%I&dUq%DK4FDzt&;r2m9RPd)K13DSqrQGTHDzhO%ln0rb(2nG%LHef5jojzdTpR#900zVWFadxT0<@~3igYR@pf(&sM3}Wx0pJJ*AQ*tlKmZ&8 zs0jc-&lK)sTWRF0o+7wl-R1xQ=wJcRhA>b7a6*_D!MfBa-^#>_ik=C`F!uaHDfujD zfq?;4qNo5@EhY#zh6~-$#sUA`(*ncrewte1yhJf_B}>sfxP=3r)ztzc`)r!JZw-*m z8d<~^bz*{z*5N*HmvEuscyV*$5&=m8NJc=CFXBSa)p5X2SX*FhE`U_kz@@jcG;%cX z;hUqsZ}*{$cC$vaXPzL*Os*iw8YugqT!Qih3LN0kK_RH~E!^5Aga)nAZ@1$g`zOdp<)^7Y1|<+E07^}uoS_GVCLme>;n&|~ zNDv*^uTO~*jVVh=IhgcTW}5T5Xnxz2w<)e@_VL|NkN&5{Fxcob*^r)!4&xF7-{GWQ znBYtz*`FELA*_ymOq2nUcsZdV?dS;WP(8E3uJJIC+gVqYgL@pT`1?$M`>PM zW}3h7v}H|pBrROQI1#MM)zRm5s|c&X%uIcUdBB_=>N3S>Wkj1SD$3FO&_?0{52@BqRd5F20zbODDaa2y)@4mS=1#{#Lj zER$9pn5Pq%*P}6**9aJJ3K%dC7_b8v@NY1$nXQc(3qC+N1L71AJHRmw94%l^BtiB> z8gR6^Ke#?ZcFjNL?3ti*#Q*9*Gi>>n6s-7rm3|J9 z|1%x6E;3$QtBf)WOg*&`qOIcSo7I3WosSSW_hvP-nWbGc+~8}dQ13HraJ67vvI&SK zK&^&A`krA!M?GgOBz>tFBZgC7a|Z~~@6Q=&DF7i2Q=gv*GIHar zX1cPri^3Uw9YhekuHcd*FNL35J4cHmcvpr!x0W@+Ti&%3OU~!6{jsuZhl3ITTL7l= z+#l|8s6i_pv_xt7+$SwyZa=u~$CJD(Gn%_ZVY2+Y((69Hxk6!b*}B(h`(qS18mi}X z)65DM(V!s!#sDCg0+3`JNVFZlXsH*eQ&Xpb|F*heiByqneqJ}#)WWwWvjk~6w3bti z4G>EZBC8~v`DybCVdFs;$qZe*oB5A1=fsvmfw^t77RmRaa3$wL^vS$AcKVv+2P@?1Yp!Nv{qK-KfwHxAoG_3^Jf4=Dw=O~*WhlLwq2P$SpWpl+`AuRks?Z9PsE;_@dl=2q41WZl}>z&htV zpt-te4-K5^vNY0#qGa{E*r|TY>l$Crn63BXOVM7Dp*nNRwfSfpa=(Adb)MW&{&0>B z{`R#tIEOQ}GGM71**UsVwjol+!$nZ~imDG0ZHKbnDD*U4M{X_q9xc}qJ{e&B>BW5r z&zd5Nmp(w>q~(by-c`n#@&d`hQLy`E-hAxgAs`xe$G*HY|Qi zZcSOv@%@RH9&qF8++H6xRf1X*z=8fvEdOWnH*xsd+du5K#%~p=!=H<0)Q`Kp%9_DE zzj=$;yYqWDmpi3#oDlJ|%jZU-b=7VX&ktcYREYMK5yVvYuk7#s>ZfmQ(E}(CGDRm9lD+#1-gfIIqMm*?MqZjP<|z{Uq-T6zeTx- zauM5Vo_&)toVT&y|1hvwrJFxWlYo&wXj9mKV*i#uTAN4`gmcbq+)8JAB274_$&5}$Ol!q8PRt_(y$JYw73v-6mjVL4 z+dJ-wCpNvI9fmB}NNUeXoX$vGZ(l#U2Q9(8a<&dQ zdja31;t&d7S6~|m@1`=FC&bf>eb?Y}5|t9z$vCx`*=a?)n9)gyc~xMG4c|K&V@3>% z;4&K7e-PFG?mQtnqXSkiInXh>Co4%Zf#Vw|O2G`+(6vmH9KZ2y3I%HJQZ|mUTM#(* z`!hC_$Lkork-2qK9x=H_C~+RL9OCB>bEA zKf||>@XCLNmyb8j;Ys}dBiSQRW5U3BUIh&(wG-blt!z7`) z8GV$m`n5AT>g(f&Cv;UdEc-5%YAw57L>61=C?+-*%}xlr3rtQ(4))tOolq^13j;NdI? z#{5T6b#$Z*lLO<9qPCrh2D5^%*)3k-haI99f2@?|obyHZX#kBUWCT!|H zF5e7&`xuX%FH}N>!!Rvk>VnWtZFs6hoc?Y~y`a+2Y=bd>z{p{`1HZvek|+)@m31UF zn^UQJVupjqXX_adb_o~>#?u=;Tv`khw;z+>@w7+W;f<5E&L!iaR7*V!5*W9ub_vs1 z@2#g=o_9ZQrB6CezqPhFA9kxW)kf@CzW506eFebYw};c)$=CYh&2L_u^OX#99d~8A zut06QL14#Ucn^VXf1$HRvdyxa=(+x@AsfOjqCegJ&)`~Sr7lVJ zJB3jFwJq~pQCSQ!VuYBSlv;ukDistmuv=7^NVn-@KJ1DLOoawXB6MTARzR%9{%E1i zv)rz31fEuO{yKr(y;8KiM3h{Dc2g4HWWuFy5B9e?Z`c=V z(1-GE(&-j9*0;g0fR7E!U#+$BFXJI++~BOryerW5ceA$Rrtdw|s=I$}TeFUWa6MOg zpQ}NbCRt7-7Fv{f*Lq$0G-bR)S5Kwgx~i?&uO932yA_KF``3d1=P}LJkYsHE&O?tW z8knlegg)4Al$_c6IQhV`Ew=Wvhy9KvU3NlljkCiebm?ySoR?VGxm7FMszx-CO7fZl zOq{LUG+UvYXAhyPWq(o^+i$JkCL^i}N5c{v3aYx5=kU)?6CRkNxX$~wUg^dY^b5c1jz zDI;`5WT7%sm^PcV>zo*GH_Vx6Z)oo|Sutj^`VX63D<6^u64Q`I#Ouxq{upG9u6#tw ziw+&%DoG<+ekh2P!PL>*d$;X!Y4>DuY}A?{*Mri%x^2waLZsD%M=&z5w)zp5$9eN* zX@tiaY8PcMN zEgNDjHQA(&-Yr?O9I_c|weXk`3nH3SbK=&qs0j{ynx&a{N{vh|*_JrpVoCt6)jpG$ z&__oT0k$&eX(_05)~RQ`}i$qv0O9HnbgMTOPc%DBWK>_{SBr-w1K|= z&6?N!&t{ru>!2mS=r@$sqo{S>Rp`AKkc{tqI@Ui=)q{7!u^oYs#);0xzWt^qA_lwR ztTsjY;N$Y<&s#7NCi^Wb9wkT<-4E;&?ahG&`|R10W=Ea-f#m(K*u{UPWI6wBAUY*2 zS5f~prFRDIhh$q`7X!%;?+=$pJD8vv)4q88sZ#Q#TJhf(D3f}h=hkL>TBhQj`Q@d6 z#P_2KxTepQ*p1`@G0zCi1cK8WG49E-M>J=(N-;F|6B?)8dEgr<<-S^IDbFO?$Oz8- zgtN68oUGZlP#NQ}d!f0&=~!}WjrmzN<=KprjFv^KEwmOoReQ~k0*m3g@^p)JsQPIx zATh`KheQ@g${-Tc0SdJImZBxyWeT~-{dv3Pn(H!`GtnpBU7eZbwr!j@kLdEIFtvch z6?>{3YqN5DO4`xCkbj%eFbm>vIFAd0Pp(&gI7SC{)4m8*RknByE3@6rh(9?UK3e=p z8y7ewKWJ+iKhWpJ9TZiF?zY4Yy6Igo59v5J_iy6fb7kg1Db+5tu8X2e|1@Ni}_e zH*E`u1}7-I^S;(MtGaLNpA)MhGM92cThXMFQpCB!23qE#;HSIHO-HEssNh-ny!|5hSn8go%nO$+xbmz~pK- zx2(DK?MC9FGiYdegFUw*9(_K1y>+t#V}4J3xd`oQkGUvgosJ(b>>TC#VUMXB;l?@m zVUYF=zAcCBsWGHk$lk1vAawbaVcwplz1~nUv z<7pIiO0cArKV2Czs%{bvT(;F!?bROfbZ`I2>Z2_csQZj&b#&^}c)#VZ z`RJyd!vFT8dX4>g#K!oo?p4Hc#;?HS%A4~vq9uo?%VY7%iHwGTJwZE${HAL6&u$*> zd_Us7?BemB%1+nip*tH(-+O*MfOd3rd$oT+@{;z-r?HXW&+#hK0K-jCYe`#SYH9Hy zzTNlsE%fiLAxJ~04M`9yhwd%f&=99+GzDxZOReVRCI12V5XGG(nUT19Q za8}6`b4Qv)qh%96;^l*!Tf$eX?qqH7k_(l)LP(jg0&QH!FT>2@NmYm2-Pz|_$4LuK z>3ZW402i31`Rdnlvh7X36$!|-Mx`oQ9SB%=W8lO0JVSMLO8`Oafxp4Dvf97Fd29r- z1**N1=;PM;F264M)(~?PbYy{B!(4tD?uSjckSpf3ljy4Lzb2}R1&HR`@4w!ZHA{%} zdV!Yftb3DokZ`a}fjf#?x?`)m+mzcLPhQ&ESijWs8wC=A8TUBT=DG+y`KAcH;g$$} z_O=N9<_>882JO9CH3Cr)-bT5fLL;E8gK`B5y!=lgLQq&i5d-CuP3Y8APob?FDHfVL zDOM#YN*<(GXP|udB*kL&BE^~j#r$iUSp2b%&WIZq9)sAKf&7`TymOZSQ%hd|;br2% zAP1c{y~yNCaO(vg+*)LBkI;wj!VX^dWg3|BJf!fTz0s|Hl#8DN+KbMPtB*!Je&bFvz}o#*qliZXBMRhn2lMR zP&pU;=F`wq%qMTy@1a-Vlwxg_rv`)dBc`_w_(~54zVEr-CmTk-QT%2m=E8p7&1}bO zW1z2Zm1O7rp4hfUZiu#kHZ@Ae{yukcx`*I*pYBS0&hNn~bPCBCv(;81+2}dJF}u5Bw-YDU999Y&N?Avow1R8&1n`l` z&n7LpL#r<4?LT_dTerJS85o3Pjm5(=hE-RpD82Uu)sPvt_g3k*pgUw?K zRa|19T{;E({?JJCZ4y<5>IN6h6LV*4{)Y?8W#BV4o0vp0nt(6M1&-$F4boT^B5EWV z2Q%w0ZufZEM7Ve3**Np7ZH)TVSKIHh#xIl%^l9>JYK&c*#Jx0Nyr&r=y43Q*z;8KL zkEbQ*JKv~c%(9v9HOjF|93vva)^~acmu8Pg9`Xp{@e7ii*cK{%*V3ZCUG#9_J)6{0 zP7L=Qat~x>@L9?iOiMSeBoA&)R2N2Rz|tSrc1SGO4#bdNbP(bSxN^#(7*}5iI4rWO^!~h7n>--0wRA(yfUeX8cV=3hTP)>x+KhI?41ZfJ zCybVFXZ>*U@j5bq88#>$KyLN2#`$VFm8i9_9aYCy>sGrF=4cv}+u(x|^cp-srfs~n zdNRg8S%dEql_U(wb%WOHcA}yZ3}N`)YiG=)#O>gsU>0&`LmWxCed*kCj4LN%y^K}+ z@IjADQ$mwT<`?rt_VFhdw2zh0Zr;yDF6@_R*+QXp!#lu1#B zz9vmW;0e>$yymYVc08SV@UYN-XGejv_41i#=C!L+Rw{2q91^%1(6{i=JUE}P+7q~w ziyfEtc{a(+alZLL*Z7bp*Uf^Nf#@cY_%$JWf`B9DfG6`ApG|TpboQzHREKLSwVS32 zyT*ip(ThF@;EOD#>ncf)rP#{ulGWD&=$$LSN4xTi1Fv?Z1eFp`j8*mD&z)&vBul># zG6gqjRc0ZW#r3#K_~PPXM(s$G`SGgNR_(&Ti_)cTD^Dp)-J+V^w3^+_9KVZks=@Y) zIK5n9S75cBe0FUn7mIB#zcQ~JPCc!Y3f|_DuCAS2Z68Q=Y%j53+`>(JE8awl+KBNd zS3zBGFgLH^h5L?*_o8Rk<-`x`sL!n}Pn)sqBOi*Pmk#$b9KKA`pJl5+9EhpKn(ds= zQg`*62{+$rnM7VVz0LovqBTX2?SLF@vtxJVJ^1$q={e^9608}a(N_#n(n6f?8Aycp z9@#7%hArN@V5I9H+L`w~L@9{t0jJxRzvIRIv!&{Hlz4C%Cdo&TP9kOnmNaNu#d-Kn zfWW582EO7~gt$FlIoAlDNV?__n*HSsE6U!Q(cA0IY5Ha?Gb7@-?nz7Hl6@}rMJs50 zb~J$jt8yK$uHY-A&&`r6I&X77#EU)uq{uQGx~1FIaYcjKnfV6y(<)WQc$yMj#d!(y zrC(n!hNv=~aBLMT(sN1CSo2IT!Uju<=z{e(m$&-wS!KWR9Ta>$V`w38>gAAuy_HN5 zmyPemA`Wo{)Y_~iYxaTj1MbIoH!VqU)=yDSUy^N`GIL`5*07|f6jRG0zGb@G^pvz| z@Z|jtw*@CN=E@PDh_I^hDi)m zWiCubpzTNV+Jifvr!JdEA&d$Th{}*JZ6bn##EHi*>>)*(64%DoCp-D=ww@nQX6h*T z;X1Ko>hSvGqGff)xF!cl4;1baEZyKJTi$IZZ?Ec2-8-JHq6aPs^c!)f1|lwPU*^(t;y)ha&2F<47f5j`zO4)&f9jP~*x(wm zGX9jHZ0lKk6K)>T&b2ySHR9XHHlmKt3XyhMpZ+8yTEy@v`(%1cgb-t~zv40eByE)y zlUT_uCZ=m!w^*AK5beh{;Cy!X&|{W9L4~`#j!(pDXfA+6hWOQrh1Rc|o(f+~| zFYrc>?~j*?B%Gft!?WcvgEpbdH^GY7IiNoGk!Sj`OGEl|7nc?L>N2*LSUbg0!LR}2=WY@=Zy&letp^{LH}je2 z$>yG})D>J}N)IB!>sO49S+%O?Jh+0#_s~$oU=^>l8e58WU5#^VoI;cvp9b$wKX|`B6HJN6xZd@Ai9ha zTiG>yZK>`SJ8wsjf=bCE8kKsmt@7r*o_K1dyo6987jt-B*!p^u?X&Fr>6-5wSfg~t zg&4#=X@-_+?}?0;7&F=$h+OX9&@?!`i0y?=ei0KypqxWr-9CbEhuWH0ZPDH>R>yTC zRMG9}ez=due~BI}WbQ7ked%=PrCs5Q!o7*7W~GeX_5t+f()^276K3}&$OIOz^ACTo ziR{|WSe&vZs|t>BcG!N3fRiJQQX0sq8MY&+wZ*^gpohoEldA1j1H`JIJC%@rMb2m4 zW}7lcvHLP~@32%AglIQgFk9EHLarvuN{X(}@VntPl=Ckz&#n}wBu-D_--`!jD*5@pk<|i2% zr2SVlYaZ8X1e(jNp4j?s_g448iua`Jjn}W#oHsJqv`^AoDHd4k=&d!2H$3g;y_2qVU^`#Si%?Shz0vN-;oQliiqIDRp%0cIbN|$|?9<-sI+fKF+6Zkh^sh?Vo0UeXFo>a4 z;736^9vSZrXvh$BZphHO=UNSNy>S$J3hmLB`=9nsw1Vt1M`(i~#){0574ai0yFaW1 zA6aqzVdVoRfho*KR!TsMxm8w81$dFRM;uduBlUl3I!IUynv_^PTo)=K8>EBSpc>vpc2dw-C=-e z*6GJ3{DxdL7K8qi1xE|*~&RS3>+)OyPW!RtPph(qSdSrO*r*w;ek@- zsVd94lMm^uEK`m_bZH!-=H*HQWtopIc~5AOXI%lbCKIAA7+Y z0owVpKd|;=NR-F;67s>A8pIiN1KQ!oFfRYY9S||Y%SVuHc4(U)!!Fy){?(^~KHPy^ zJ6+xXbLiC%EP!DDxWUn0N(1feAho}2aJ1KB;nUS1&R;gb>?QdWxET2B2GCw@(@qN_ zxwaqD&Z-)JS75SUp`kUmULm91DlBZRF1g2bt`Ydgu>Kv0GNfSWBMhbc*e{u_5ja*? zbT$3uSRKa|h(=t3C?WS}?jtq5aY*enhPIDEW8b(RYRQz4C><$8{RkksbL@xOlMd^r zBr^G5i>`Q|rEk-quX?qh^@BCh?S@Jc|n$D_z9?%B_g1p&^|K2uCTDS+66Y8@JQyvXhCU;)g|wzg9HE~98^#sV2l_jhbJTivW2no zUGoiq$B~%K2MS2&pWe)$^Yc%j`~fr73Ch2C^{exhk!b*hi&lRs^1Lzi-v22GKiv8B zUw4#2Jp%Na>ME2@t{o`r;m#oI6T>%Hp|<-wOtbH^ry`F{IHQtuXLgAmFVMKXS>;Y} zR_7SG)8KT=L7QWw+Dcb5q4YzTwT5KrEtepXcz^uZ`DH??qk_UGZ>a+h3GBR+pE&JGfwD1`*rqtyv&P07Qsyij>Gx7;h&AOT%RNWen0 zfFiqxi5;70$dnrhEJFg4JCFdYiy3QbhNuz_^>B|G5Lm+qpfMH>1|_Gp!KZcXIM<-P zPhjX74CQrK_a$os7X44O0X2Ub3_XpZOrtbs2y%gsX9#n_K4*w9lo+B~r6Pb@`X3gL ztj2l$FK@Ns+DAb9=nFpVn)9eV1#=q} z?hJLso|U*b#o~AT4vxKRg`v!{Nz2E^6kJ)}OOju-tNyFlr{p}_L>U<~@3<1vje$mRe0lz?2Med1W{3(yFe{XJ6v=-uUF z1xh%nn;S(Ky!(DoTV!KbTx#<08}?034$2Qs6{@@}stx1X}@dH)#I|!OEQYP*kM-SlI6^?DpkxQB3hyDp5%e zaBv*;J@0i)gW;nTXcsl19Fg4lEuTjMKRWDZA0Bydl)pbM<|_fW$ho1S{dd0p8UX0- zikT;u5ivM!dw4U@&m@X$U$WRjcjKeSX50!&Gs5itdUvG6z9m$9K4ACO{$cH4-_`@O zb5jQ?4BI#YWSK!9>^SUtD(cEZ?XyGYdV|V_-Dt9HYQA~hI4yg6ASXs_!zwjG>VPS` zE-rLHecO@NO_Ao$m%Mb@%y#cI?SXl*AA3bxNgJE#uPt~51% zE(gDO|6uLX@U8MpKDd)+B$(Q2Lpmp&C|gTYyYx!$JL&?FDagV_h*4G|{}qTj(buRy zhpfRZsDL4@u?rCID~9(H@H8QwxfR44Mqzl(7+wtE2|>K2cuI(O<1C~Xd;_w1mb6Cw zB!*{;(ObmmjbQYu=xby&y$5zbH5v2~Mw}vm{Q{$=D(s-Dj$eMpK$;ur>d&_ULz?CM>A0iaY&*&C@&i>sBV=$3f z-u^V#xFP$vp;_Agm$bi6dOyHE45icdN2qie1R81GL0p0Ytg)Xw`HXHH@ZLM9eqfkl zo#kcn$$&(r=6+*frhlvPoBqU4qpV`UfuFO#Z1KOLFg&-4h!1Yw6s1JM=kY6D+2>^{ zUAgAjjJJw!PZSgs6A7=a7B|)EYH1;aq8%JGC+#Ou&mzXlU^(xPW(MRRp%N=5`(ZdW zdPogo;kE3MGzh8M7%F}Tg3%oBO14a!*L#OPYZCy6zTj?%Dnisj^MclP- zQtORC>{D|CAnsFOC<&mT9;Lxo{sz1N&KUeoqLA=4%eRQb@+RQ7n>G|P60YprWiSe= z_Z+j(_%5SmTG{{QP-@nudTqa zdRu;*RRB=^5TRbeasR(iAi{1#zH-|t#KF2s$coiwM&)Z8c`bJUH-6{>#ln^6#s!49 zP6SxF>W^ZFP8jtpIZ^ zzs=miQT{`O0x138D6}n|+S|9p!^-87#EKmvI^X{kr`^o!1SU*LKM;4O57xC3LQJ&p z9lWqAz#)!<1rA{XEMIbLciTynI5q_c(w?DQixrC}Is-7E^Bf0jTna1pPa5D}z>38p zhKmJ`Z6F5Cc%pwA{TC}3;EbNPA-Uy-WAC!o?{@y}Ha*tM3b$hvn=ZQI6q{1I;wLus zbj2k~IIwg_PJ#m!iR}vx)IU-ptcf%{mieYeYIpDil8AL(WQ`Y(1stCoSb+lnaSRo9 zch|<)bpiJxYOKrLlGw3Bh5)@Uj0@3Ogu09w_~9Gf>DMBJM!x|3<;xwKaBK28z`N z6YE8QWDwySfMgKzEr4W+Odp(Upt`y0h7d0Q8jb-Hhb2P^gJdY23=k)TWFmlM>_2N@ zLS_-8hL8-zekR~3NB?StU~G|$137mUgo?`M;9*Ki0b=b?6^n%J5a!Ofxh5n$Z+FtR zmwb9YQ~N=$u6SHdm8&|dj0i&o8T#aV#?2f`VcakF*W4*RbVSZn5J>PaonW~xa=wC0 zf+w0v$CG6mURK57Cxf@GG)`1gg%e1j!ox%hB;XZfmUt6>*f$6~R+_NR0vnGpHUzHu z+FQ6Y0&7<>)|h~eQ^Djsk`#gX1O$|d6q!;Kfkp(USP5#BaRVuECxmby6X&p5$M4|S zf)NikWGo6}ObKIx18k>^ap)psto0;hjExvFk%Q;y>qFcNMiY3DG3;ZIF<;0;80~)0 z*E(~O#s*^Jkgrlct?gsggp6Wo)625~WHAqH>^G!+6gdU&YQi9-<2si z;D0s+lsVv7uU2tDS{jHkvwwxc?n2NjW}fgjv~4ao9iEfH6{eR>qfF7c!?}&<@t8A+%d~Kxn`E1wwl?0GH?&2<0}q2ch;8#_$7- z;Z$H)6=OIJLam|-gxV=i$OILQr>_hbgjy*Y$k-)f$XG1KL>JgD6%X>VA7jiMG8SEk z0lo&s8Kz<#AJ9*ln0|so#y-#j6Uy4_^i1-|pr%B4EOzKFDDwNZu{D1(IC6T~LD~nQ zZL?kKadrdmYUy5l6%{_f;Vgv1WK4O=v98ZT#riP=Jz%^~9R0QH2=<_AH21A=-N2I@!g{G35h2a!p%xiXKLD7s+#+yeGMhikJ) zel!O0_)^P5Y+!-qu6C@{k?=oY?|)BWeQ!SWM>OoL@A1Ka#E zK5K}N+oXgbuEb&6i)-MFO2&UqfxE9qj>Af@`+~xExkr@Phh=)ni5f(B7%0VpE8*61 z7orq6lm{%H7C?o?6H@$z;-1-)AQ%INBnTjLztZd5FDNQ8=8rb{BlQIyc}h{N zmY$X8zRgA-dyqpJ<{1l}Z7U6*#BU$iUVbU6b>ch&y6zjrA3MN;+oNhjo7PiLQ3&(^ zpPVH-zYqkxs?kKAX7Z&x~C~6K={^4iJmj#N*=MMlz^)l06|j? zmoi=2Q%VDH0Je*1C;=q%d_j|>OH+)gT?ftfFJvT3?>_Z^CH`WY`J;4f^>~J}{pJZq zSJJkz9;{z449U`MV>i7)d}zo`NA2q%=p`tCw`#cd_S(4QZ$Ka(I*%!#gI*dsg=w&_ zKc<8ZdT6%j(<|x8Qpo&>n9^g^)tCF)M;Zwq7W>$5Ktm)fL!xy;(HqU`>m4Kto zHvcsr^Y!UvQ+KkF>2{C-Ow9D6S4HaESP2ZZq3|}LSiq11qyq|30u%r5abvww!v*)E zKW5=b5S@P=05(Ig!Jm)4PcRc!ka9O;XVqz2|~*X_+`VR z6oT~szCCd6*R=mZ!I*Mm>SSxLE^eQ$X$a$u5XSua%qoKHsw;H1rzEVd#~JxN<(;R% z{V)SP1-~N$xA~(Xktl2Y40s-HW3H*-@RMxyIibQsBzhJ+p-3wFvaipBM|3d7{ldNu zskHHd=Z+tY-)61A;13Z`U&&T*gZy2AT(cfLT!`45m%`Y>4c5TStr z_vKoj1`!jBp80z6x5FQE+`HES6=>t%4}Z-4;Yj1xyTyN_AVPHh7-kRL;BMGEFDCNy zS0bQ$i2=BgoVgwWe8X@{jA|nYBZqLgQe=Rj&7ZyO1xmMNDc0&_Uu^!P_XP&ccy1F+wM&F=^A)INPcjk zS62mtXhj=kDYF%i9N^5|_s6g@a z#Q+stg#yI$S2O@kQ19Qc0lfPmg8d3u^U&FQbw+ayO6jY32t;=;|9FNusx&`<(_d8n z={^2Ag(LWuuwx!gZpT88CXKj96L;vjWREERfBalBeB+wxYp9w2F3v}!zh&wFCujd$ zJbzb}a-WC$o4d2xi^IJG0SD{tkpmk;yPJp&nV7P|qSEri?~nHzcOP%;_rd47k=j}r z+A%}g(IaUG+cWz{ZhPyCt2yGk;#)Cgy*ufLY6Q;4ml2S!^fH6IU`d=|#+ zun!*v2cq>wSSDEMg6r&W*HG~;I`<%M!fopdWole_nL<`V0%i0?E=&;8*_F?+1&}fY zI_VFxO<>cJ*V|vO(c_H{v7Cx%$jn(=+vwi?#=AD@c&>5u6nwL;P_gD1FVpK4-@saZ z5!Q(oz6M_2#aEUwf%y6&=O!rWg6r)iYu+1$8R!q5oe-lVud|n}Im^owy5boqtX*1i z@VP`7b;EXLad&uYXLFf8Y~ZE|k2n*fhlchS z2G-C81)F3g=z*NMl9Y$~o7!F_SDDtUnIgCPoGT`!t}tiqylrNCvRNN{vd%E+Si1s# z)1O~H-_Aw8C%Z1p$n&QcJ!9`>gU=7b@I^9{IKv6940!59=;X)~gcCu-A|5`lN)nVm z7Xbe3nXOBfO=e#@Je>RrdIM!seWtQq!Kd@29H9)ld(5WVqq05SPQ|TUsHAW%WpYY; zUAj3yGj}oW8FL!GvFP>CdF>>vyS?tk_@4=u2{@`|ZLbkJnBtF}J3tw=6EgGu(F9 zyStm4z4qmhLK}P3K?^0&f0jR&lP1kOP$O%o{!%|b?Nw7gQ~i_33F~3T`gt3Bw{tn2 zV~nqx6nwU1d4(B=&&RA?xoMbGMSnixJ(>9%ecP+0s;~QImTgtvW<~C2Uo=>t8qL(( zLD)L*RfnOB5AO;sCB4mNSkUf4ai3KF7SDP%ifrjKv|=;La_~iGSoM;DQ2#~TM6Spk z;X3%X`YL>z9$baN6ww&b zhz1}tGHwTxDAY5ReV4V)DI?^1AVS>5b%6h1u5T`VW^F(YUDmaW0t}7eDfqn}^Zn3E zWp!EZ8Lo$YV|z7=D0nNpXFul7Q{0T!2QkjsSCOTnZjsHqZ}!O+2g7u$oi+1<%U`##;Mjh$|F+Rl`M z9=ol%oB+F&`D^RptF#41;?4Gj8L*{Rx6QRgW3}c>U!#1wBO?d4{o2bHt?%>VBejMP zo!2&9`LE*bParuASI{?W5{uk|0$%&UMfav?&!~&JaWk|c(FdJ}TT@1@mv#YqsYjv$bIDW_DMdqwX4VtKbzsUF|2eP}e#SOVW(`GUUtD`co?1@7BRv zqo(%qi~CQX$eUd#(_!q(y7BG1A+*u!v`9kEtKWLx&08`w>}B!yofWdrR14qLLF<`X zAzkHnFZozMadVbm3{I;Tyz#p!F#V(D;Pm?DkF?**8BO)U4#@e3XZwmHGUN4Lrqwgm z#x*gkhl;+29IwYm?0j+fw^xJvW|X01lQ)?RT=hH`DbTy zrTG@U4Q}`i#4b`cgsKkVZUhU8TzGuAp6JLW)J>}7=Ft#@yAa><_J+ADFYzbjN^<4keubY(jUf+~mnWYz$+_)KlK!_wSQjpwkk^Mra)9cUh#!LDGKp zGcIrOCiWMfn=qo^%pUtRbW2_y{AFEAB3={vj@RWN;+Wj?E(MBeVdX>h9Ez2&st5Y= zyR+>!nn|g36gYW$tPgqTel*`A=w@SFP<^UNm-l{5 z59@?#X!($wY8JUIT$V5QqKkZ+qWsAI?r*Yq5xJx$H%AsJKP#$*mTP*WO3dxvrq!*O z&EuQiAh)yG>Ym^Z;X<;FB)X_=yHnppygHuhdAp-LQik|(?$YEXzvSCUPT zjrnB_*%{5fzG5;mY}}Y5l}4 z6ZZ~VaK_!AF?FNLyt&_;p+H4FR>v3f(RP+;g+WmAuDAVxOWx9NthS`aZvkYn~|)oi8pof3|Bo^+^K#Ajy2| z?t}9kJ_9=4tu#X>X|qN0!+(>4`ha)8>f~QGpR*fT^hy?-LzkPcEuvZ8Hgww2^WH>< zCoOH>WP`G|prG)=V*yq5a3WPMcO&Yl%Lqu?MA|gkEPD5Ctc%P+zDJkBP|RHthPWH( zZ~N~(MNHmray#i8yX(FH*K@MbIr3;4u~j~vG{lAJyEGj$gDV7lb|aSflU=k zCw3`fMsIv(qMjt?ZPPj_gYxak=;)@G#75_xMIz`C-YfdYZ{IfD{;HoC?3WbG#^?Nq zw^P94_N554Bd-7~>do?szM019nov5POA%vKp%G#iqQ#<{mi_8)k5pW$*6)wLX?~@D zo?%;{h+M45XtBeIl1ay^bugiaMx7YX>xI7J=z2ayi+t|e9ZfFDg<~| zWYkbk@^+991zcE)u;Qf>xTXPJC*C@?-U~Gm_K9j*t`}8SFs%3<&B4Z}nVJ&;|lyWGcfnH;9Oa4y{NUhPV42ELB3|T0y6%HeBnBft0S)#fj7qzA?tqh zEa}kI@^+cg=la|s2?fLLBd@H0S9CmOAeP%vgM0>t#}$?$c=?_ZD}@$Wa(t1^a9hhe z$zyNO^+FM{HWBhOih7bLP?7qy7Y8=3ITNEJ72?36pIhPqR;bg3gY!GbKvK48Qnm`Q z$JLA$$>$>`L)CrW-5y~4uJ4Vpb?gEr?oKG~ucQ<`&{Z&Tn6F#Ezl9Z4^2oEJEDwV$ zUr<<#xT3q?+H8LV{|`EILv3si_}8bo_AG6r%a}8IUF8n zwrv(WADXTYY@}=~?Cv_3IX-jREZ*vvBwy)?q(z3aA`1l8Gqj@jZCo4H8~9?Cn{Kl5qH7T!{|o#Aq_jxh*s$rj&I-JIdVw~j%%w^#{osglib$$*J( ziAyQThh%yDh4d85CaZ>>Ac<@n_8L1Tcp%X%ww+Tuu=>fy|XIeK(c z6?|?$Sbd1uWw(!6ysTtzKKP(@->6$Ie?_F+Z+q3XbZoLehDT$Bjmf;Q$nW;4baTOA zfx*F-7f5>S(rf9>%uK1g=hR0hNCmcP39B~B)>phE=@&f5b`$sPtC|^|DlJ^>+<=j9 z;<|;xt?6#F0RnveN$##1BZtLW+5;;0HI5yGoLEF`bT{vy_Jz^mZF2$-9;7cV?N#Z& zd1N+|lU=C3o65BrF2)&vOlWO*WC4~0HNX-L0xZ=gwDwblYHN*TxE1Fu6=|j(EDTjI zG*_3*<@6w?Qp881`e+-T%((5fx@8`2h-Iy(xlpzsH#gl6cBIzd#Hkpm2y9jtqGNhe z_OA8K7AV48k)63E{gFK>%;xh>=H_OL0@}}VmV6FRN4A5v4^Z?n!-M6K4kSwl_<>_f z!B@SV15KZ8esH^GIrn&5Ws_-4@)LF``nwy?vzwRZ@y6wJC;S!j;)FoKCS_ZrKz`G(z>9dV)!^J*XIP1y zziWebtE2XX_ozUJjnTlvd@-~E-D`)k(J<{14b5lG+O=$)3(A%W$``-+JbfO?iNh8Y zoY3Mr*<5)_WR2Vi+2T6f?08CKsbFM7xM5^CT5|+dYsIa~eD3>v(cXgH^0$76R_>hL zfu-G-V-XH>>)t|cvP-iwX7y_sx|37%5;x1;NY}(i2>f|R%I^A1Mb_-vdJGuPi30{+xYZ;Nw0W)vxOqV<-c6w#$2X-}53+_qA>S_P&gT6*M zlCe`HNx1s8QLQU(qu#;vRU$Jc*|A_XJAYJDFQH(TqTQ{pa$CJs5haZK z|Al_VIIX zPJ~>5Js)~RnQe;n>3KfXT_>_1?wNrh%d0}r%+c;NcO1N2W1MAPpmYz0KC($Rm-w@GHc{@jL+ zz7iTqmf4sz&UWrQ&UC!1*yuDElP{bzxjh)Ems*RW=ek#m~w zI?J_+xuSPBIt*6UGY~Lh`12Q!W~_KLiy77v8YPl#Km|fz_|+Xy1&SHMWD%eO35~Wk z&uxU*U&HiX^oGMWUa*Hi_y8lRPYBpkRToDkxTYFap;qx_Bdhl|s#lXa6B;{afDbf^ z8y99eq88;Z@L}w{#X~MlvLrb~Rk@82*Bh8#5^V=6^I>t| z`)jg@suMFEqMMmEeL=7gn2&Ua!4rysjs#Z6`$Lm0Sk}VD-eWYI8MIL_*jC7$4PFV(pSc>rXyf! zgc@+ocYH+(#a!>Z-T)ugfe!&mj!?*3Pytq<0xZly8Nv8)2z*#RA;=L9W9v+4ys2Fr z6?O}e)k!>Kb(c%CMuFvH<4r%C878NP#ZP2tWf7rgW_YjoKApKM?u!FPp3uk>1RUO- z#0E;h{~Q#+`a;i5L_%osUEsqo@L}a16!HvI0OfM104`-9BO8zpGmsBjIKr(k*sivj z+Hdc%3tJtox6`B5I*#6B7eyB3Wt{cf`kDqCt|@ra0)xT!p9OA?(@E``CLd-Nmmr-t zW*uGZwtVdS)~oyG1Q46?v(3cx!shcc<(vzby?dRg^tveo?mP6cZfbpd$p2NoTg%3G z-#m1MLVNgY%BybT)P-kx_A|R@Qdl{bSGSNG_XU=>KF??2YrUm@Tr*-?RLiivg&Y(e znL#>j?4TBg_SpmqXgA+yX)nC#j7fFNfvbFPRMAEahh&&7rcOIg?079;7Z|N{=iJ|E zyr9Rv-;)UwqPC>UrIMOKzIs+4=R0toxdHsl;W}D)Y=!8VmR)%~XH9|nKI*hyO39;~ z;HRS}$_JB6JfYFMN;c}X6mn+duFgzZk)xB*$c`|wsJyP)nE9CV*KUHP>p^g3k|RT3{C>Sn6lk!5FSH*1JI zwQJ$cR%k0YKw8u6l|k3CZ19P(#Wp9)N>E#SP%7GOsd|2Me%wk!l?ItJ*xH38Q*Qal zJJi}0GtOajH`&a{c2~F@ z8!cO|hHX;5#%b>}{w8Dwl8p(v?D74(N{M+ISM?&YP_OkOJFFsfpBzJ2s5KgRXOU`j z8mPheGHRp&g?Bf&VR~$L>CK-t8q8mROq*t2 zWYc<-9tCIa815|4xN1(cn5Xf`S8>3K@VJnB+=dD9l4q?v~pBC9zSxPn%>FPu&tCX~;? zji9T!VnLXcr(t+%pn_jB5yiXqSmPt0yqXZ*1uNOhm0A$>*9LU-fzpuGOkhGTDqCg9 zica`dzx`3zCB`m|2~LUeOBN?L1)V)OK`yHL%!;1Gn|dqvSkck9*fu6u32tyBzFp5S zFUmD^1mgVN^lC8qBCYn@#>PdLQBJ6ki|R0WA#Jgb`$-^qmX8Q$1i>osXyw2g`>L#-Mgizz{^vLB1-x0?Ar?it>A0P0+&jeCXT-&quVM8>8B{P3w2y*mQ4>%8bJOD6jRuq5g|dJe6hm~Q1gwmCl|l3*63{Pc zvBjtkIysX@17tCZ*Y-@_$^(Efg^#xFpmJNcrDINV&s%Qes^miz9kS}X-b0d_R-K++u{kn2%QP#4=&}lcGRUqY_lMUpk$FCI;Euh=#E) zfMY5Qj%T1k-!q4*>L|?@7l-NyTY4k)`3aai?}U)W0IcuC>t~=&NICb1%e7-_%=@(u zfQH#R`U7el;RY)Gfz){sP!eZ=;m`moHJFdGI*e3`GW(JbFR;i%&C2D%-l+zApVicB zRi7nqf~l&UU>b_Is`q&M3@i+(y3QEKrRr-2Ajw;EA|4T=eI!vY;0E;U5Wx)}q1HKh#6dRp}x|LWRCidkG;Ep{h z0O!U3pmire>oSZSmhOV@Gn(J3l!eQYteB|7q%oDQr!X=vdJ+SW7@&Os${l=Vxd>3+ zWdLLan1XQ;130-r-`3SIGE-*^ymu{8v(?% zUIsuk5krw+g+{9vLsuX=Nc349AS5hbBk1U$`t^LiJP3N0HeciS6YKK-q=DH$0}Iia z{PncjyooURuMVsFf7xM$`uL~A>Tq(=H1eE)+2unbJ^11y>anb@rJ;hW(z5w^TGbna z>1mpcyYZhE4O{OO7Jt^fFKUiF;Em|!tNMQI#BHp41o_!!{S$D-3+~rnvGg8>%W);| zhc}Krp5&%QR)~U=I$0TsdL65PREKHKc9|Eg-%C2=M%t!=d_f3w-qd0X;qo2J4_TZV>)!>HW!#HK}0TS7I6=A4~N4Ww+b5fA0Y=* z1JKQz`CR_h<-JIbfDc0ljThgb7bfEh)rUvSX$!i$@wRXYiZ3fZQ`YpAIy2od$O#74 zU+1ib?1GuDkfR(G=U!);b~q6e~X*; zQKtv&OwU|~Tq6^qCcHzsePd5jlQ}>`QKBeZle#$C1L!yME{6aiW85_TI=Je2R#G_k!4)@9QHCuY)Vk0gENiHm(T zGLSIvX0T0}EbW5gc>SMt!3rtT>QcQtv~lDTah8b$?W?(so&vLIsc$plnZ{4 zdvWAJYlEF-r+171y85%dC30|a)2DVWI3-Cl3qAfEtJ9iDmFM zVy?QJ%a)m8ze**a2yJvV^ltA6VN6)%!NJ%^>PJ87X+nIpLdZ3u(quR(LsG5V-n*s{*(tgDV-hMu2MzNybtU#0OU| zh!3s_5FcFMfNN{O#CEB1SZ2_CMcW<03BR}x7By$3WX1xGyn`y~$VnN!_@Yl=B{CAZ zVnf|xZ#K;yH8#3ELGD(3;IPuQ4Zhb93xf}-vzF{vmOUJGUAVXP`g6*}*~#j3OZu6z zvo7|7srzz-k?2{Pt|6;}5tw=Oo@Pox< zV)4quiNyO{hf)f<%+^G64{OlfogLnk0&a-r3*j5PZ*lBzV~e;-WBu({99FavmLj`58+8R0(I_F_vL}wcB(?}xzKf;E z;hscYp-eQ&fwvrnV}A=Fr&d;QH99u>qBd+vex!mS9=zD9(jQwL|k!{+%;>we}tt%V2Hsa0ZG2`rKwypJqc z-g`KADX^qmvDqbEvDpaRfjaenv|4*AwR}-Te7M%-ZlRB~7L{<$sO1^FsO3f?HfKj{ zw!Q31!Wb=gzYwhoLURF&$|Ov{9hiV;FafXQD0!~qD1e|Hu{l7%Wtf1qpghUKv7}|; zqqx{SA8A8Cp8iAC-cgq^d5Ca(e<1UqoeWj7D66c|g|69Sh3k2?BIcFbIV!0T~ zC{X~4&*2PIpwZF%kM#c?9{5jpOJ62Jw8#?!vq|h@8Z%%~%PGWcd$W~<$YP7ipHmON z5CZ@eG0+#&joJi6II(ayR(1mS@;$Fu&>mdJMwe0Wko$GKPz&kPL9oasf!as)cr1bH z@hFT8)I#AHG&N$-WPs%lSp}W*47DNUIZ-RSWMc=kS%IQwb}F~=S&2__wG z1XY-nFjwlF(WkShj3oc>gNlV`d&!;1CaLr9{Ssnujpz|Rh@D+B9GlIT5o85ARJe}) zAtPAStc~te;7|dwf6mA?%4`xrOfvrsYJnG|rv?loUz##)?3(sOKF;f17}5?XZT-Bc zGI`pj{EcC{guNMFdF{m^ro2G%X_{!QF+!sm`^xjz?JHHUMq3b4Mq7jjv1v$pUichH zt|+KdLj_~41d+|ooJ?fFdZ3uWgNL2z=;*}`u_>@p(6`=tU_CT&{v-8`Z`fYO#m;Ql zhJ=5m6w+^2#sF&GtmuMF{YqK=FHTf}y#NIV^siKk`hJZMIJ^M`C)%IrZ_WggD+8B) zrFZVpF-HT>>6jt^f2H6lo^!vqbgXM-{WBkBXCwb;GmjfJfJ%);<p>-eFw`roJa zuHgO00*!SmQVXgy$JZNYF~RTM0c~`;itxAGFjwoG`3~|!Pl?G7=ms<b&(FldI^^YWi&h;>-*n(hM9es-}e zOg?sO%xK3InIYT`PCK1zAXR+Rfb%KJzOYz1G~MvQ(f6t88#mR1I@{$&f5921-Gm|@NxHN7d`^tMoX6RE+^@Gls&Io(`;!6n` zmU+!F)aWRNh)hROibLc*m9nQ>o%G@smZ%qBVF{j?Dwj!@4{g&Mlb5wpCFX859ekM;g zrGDxog`1BRx;)NVZP@HL^Njzz55_;eXda)oPR)DzFVjbB{nM&*#A(S*|CpkxyMp$+ zZ|4EeKNNdB0z;~Y$6TBgV+O55H$$rTQ!UGdJ3X^|y5(Ju-A3(M*OS%LZ6>dSDXGIU zKm0DdJ^h~&>uZ|N+m0TzUOzLNrT$i)dOI$FLHk|J>De$&>+fE-Z93N}^e!J()%EKL zIps}b9;9Cz=bofm0 zPu`g!cFuOu0ukxOhQl50rCs8$$gkQt+|gUwMS0vHgU&2tujjwMJsF|CdwSifLdnJF zY-fBt-}y(h^JvFeDi_csiS;5$;%;8IN5RZt9^E#Dk}c=)q;)Z4I@VEVfmn?gWI*k0 z&-9MrBZDRfT4smJTb;JZ9lWyqtcXrj?Wwtb^1qEAJmfiaYHaZj*a0@R$;TMSj45e0 zIBl`e#wBh{$s)tk7PE#%HTwsMx*fYcD%%6uRjY>VvXyLExwK2H1ZjgwVAmQsWY;ZG zH{q%6HMMFLl6Vr>6?485>?-lGWiX;*C+B&%dxc!h)A022k`Zaz*vXo*J+d z!-A<*^w5%?lx$QY{8{y2KI@Z--UJzgioz&~mV)|%Vi|5%TB_aL5H~t^uB_%5_6GRh z`hVz!uAKXuoxS(|Qqhs)3o^q+rp@t@OB+3Y!UD?^7285molcvEo*r@ToT~ZS&C5O| z>xgkXMj05Wj<&1pl#6qs`AvUTWXBeL;M8OHV%)aVT3L5T#8vmmNw2ihcn}k~b!^eF zi>VQh%j|{5KkrCn%osK@&S~!RjxMVxQT%iK9~8!jCr&+)vIaK(PTJ$`GdWsT$B!4P zsIPo5^Qmz4b6RG()wnsQKb=q=DLlcRrRnymwbD`!{|x?TX@ZU!iyb;Bs#+yFa89!i zOHpX>kOxjG(*pM{qrB|Cb8;Tn`1p34-K?_fr=E?RGX0>Y&BNh}5)&X9RXhDItP0i30?uz+46QpQeZE+FjS2|tGaGulY*b?<_Au}U0 z#=blul@(=uSWCEZRD9;`8@HTkzrLK%8S-0MxYO7k?WmbyL3(*UWwb}}3*RlcsKzwE z6(`gFb5+BLGaWP8+B(wZR%2gDy)*M<`5ag~eNoOJWyYojKOMU!Uh6n=6Eq)|nmGKn z$U{11ljxbxp_wU?KFEQSrqsnve<_~tK+ z_u~TUHmfe>wB~5|#jv}o(|noxn+Hv07mCHHeJGIoo!uR{vL}7^lMp@07RSS*E`2^B z6h@19**@u)_H?12tpCu>jj5|X&}#hP2t}lG!jr8Z-Q~38QXFgw-YA$QKMQo<8N4@V ztb@49{sN^LP`>;EQ0zMg(4!)xru6sORseQ3>pKa7VB z6H;8Uzc6uS^61f1k66BmIC0|CG_hqL%a$eW_?>+HV%F5;(3NEmiYI9`R3&V^+)%)h zQ+eIP4m&e!ZKcVf`2nf%4|UZ%e76LjooeT$J>`1JjqB;P2JYD>Ck1R=sHVR-Ab(J- z*UG>pW|Q~M4>4dU<XJfT8mMbLbd66LoH0xLBX zo-&2uJ@$`0oo!-`?aapt#ro>+FD!{$mE2f8aq1Dd@HY{$M^BzA$y~7Pqs2~HSHnjt z%Ra_bSA>*Dm{VNC=bV~hU+`9V>9I0HMOCWo;HK?e#+L@$-~Ge1X+(;_H(&z>Z!0(mh<_owAMrKB9}@PKi6kqhWE3Q;Il%8 zLUu6W@qxxGLzL87B4YRb(`&QRM~iLG_Dm3t-7%?oa!N99=%x#pLp61>mvyO(txpb_ zA;#D&u~VqLb97{x8Dpcw=+!HF7I-w94X+uT++uiW#`xiBc8^aw)|DYyiYt()(W8-) z6N8Wr+#OqTEbSNZBe5q0cN&82FCS9gxh4JAru4!wk7pGN*3PatL~(>c3&c3Av)6 zk_3-L;U^05?Ix_UQdc{npD2u|nRkCGeipNBp~2O7$y+bhq=s4PY)Wms-IB3oaEI7K1Ox=(+KXeet8Myow* zZ*-qKVt@C(uA{;E7hXz1H`yn!ikGw_tEu|(g_^Td=XZrz99*`!aaRFm+mQO_GTO~?L7 z)wFp^u?H1Tn(FtQPkNM*in?Z?E@kLaxsarjSAFg1`t(ox^?X%pgUwoBiOn7odoOdT z&E*NodWUXYdvqK37SFCqcziEYqD}Y7Q4{ft#|>dw*QPT!?k&%HWv<=!F(Jrq-MSCL z^4@1-{H+&FIn2o4v!tH(I&p8V(;lyvcUkL)UEItJRh|>jXgY0^n)Qjjs-J4#p5{cI zc)8Bv+{a;=YeM$R}n2VaOWbOEEV z=W%h#!lh$|g_j+VoRql0w07d11j?pM?nQDDGpyoQ`Cm)4wQivOk^8bDV#-<5^#)t& z%l13Y&~t#lz==9u^m=EitA5An$^ zTZiOCxyN_tXEd5M3>wmP#%SM$*B8#z*cGez=DA)qG`akm6`;~2^R)CrbmBeggZAq_ zk@S#l#S}T=tQ~HvSJIUgdzQTVMW*3u+!Ouwjiv9OR@)c7+wK9A3k$bbK2=-sw)@?C zx0|6(FLyZV(LaP9GWU$U9-8MZdjE_^s4T7EPT~9DuZ>!G1{S^_o0Ctw8}oDA`{HPc zLB2tp${d=AL^+r9IKiBD?r5}hWRG5Qc(m&8O1{-s|KRLzEz0D!b0|%sS*^?r*UweH zRj*~uJAXUa=x*okd?}^KBd6j>G`CDUr=1oXcl4f0VO^=SZTxh0*2T!ifOQQ8A#Zi0 zI#?;6RCiN%ZmpDRIUy88x0!n1uE#gX^WCR=_AN#XBTAzteZIkb#|9Ob?VQ$+A5d1H@jQoXhHtWq>O_HX=BP46;Cux38NYu6v@-qZxV^Lm@(!` z>NNj9wmi|TV(m7v5S4h}wdZJSTg-zpZnn-CF`Y^4O8h8C~I8Ju6>Gup18*r#*d|LJz+_G4_=Ke_!9ZH1`X#oHT`EiObY6Tdyn z>OisNri!=rE*GBPv9fEfIUz)Q`0Ti8vWCK2%LR6dg$faSRD$-%YR)zD)683OJ=jV? zztZ+*YMr)6&gH2=0SZCYl!#N5->QuZvwmN+dBlQ~rW;+{Hayn0k6Gh=cg=#6HDohsjraa^$$uuTnGJH5jGZ$- zdqer+@y55t!SZE9b2BvOWepuZ{&Ix2{d;n`1|hA2XqsxexCJWBn!ZUlX+!w~a=8+* zJezE)AY&dA#?)vL%YRynjWPX=XpUS9#_SnH7_)}dK7lYsjc8gyb6%D(Va!Z&xi+zU zKGCd!W}wmq!kBDwxhAo^1vg{Ff8%`qe5AEGYFli{@ND>0mnz4{CGQjlZRA1JPgp|EPBMD$4B%KOMu5F^q`h1 z&H3FgRcX#IFLGZrXYM)vlcvW(1~kiZU$BX$(Lbvf|8wuE>cuNp2BtRs)aw1m?>d!o z$B%CM?OAY(VVM&O7Tcfe(EkNyX%mM+&!!J z(iXXE9~&0iuPQlWRk_U=hJ%)e8;n;h&~L1AO^Ll#Y*BJz0wdkCF*MK0X^*)=80Dj8 zTDyl(eN@5&^=Sq0Up=qvPSreYz$m=$3I9K!c22T~bEDp;H#zqV7*`r=+De&*wi@F8 z5?A7FI9vn8G#PQfl7)8M+QN4tVcCCh<9qbjKY9DSIAwL$%EJ5n)S6R?!SE6YFJnXC zB^F-xz);k06D15Q+e%b-N|#KB+a&l6$mY3&k10|(l1tt1^ zl9p75iX1z5oN$JR-yV3_n!;m~IXq@j;K8=0Iy|gkKQ)NHFr%P7X5pL2!Cm)q9#cX! zhO{%HWq$e;5HM3gM7yGAc)Q8zDn6@S4v5=a^$SH; zK3!DL^UG#s+~(QodOmV&4V#HJR_%9pONWW;y-LXoI1?S^pu1Q^-)nw#Mg8U!0|VuI zTixBQ(If-Z(qAlcRqo!J=ri&$Sj4OBDv$Y_!*+X0Q*_;|C$@TT^O~PI?x!3)`JT6X zNDW^QEG5K7VR<)C|D(rlmVugL<*S%mpdqJH^~ ziG747RPXW$0V~z{8yv{y{EAy>Kc#oafyK38G3Zbq&<)~C8#dqRs#TUx6eWI zyx7n1#g70+MbWto>1BNmdjRqGQ`REY1EHv|@H@vwQ)M#kgq5k2g=jB2Em|#{YA1Z^ z)@%|+P+`55PEN&+V0_CD|%4&R+#qc zP&MVLqn}RQJm{*Gi;RcYsyS=3@0Mq*NGjMBGFJBV6f@adM|3NP8=W|`AveKHtlT^z z@3e!$SxM>vs?nAiRG~n%Tq_f?cWCzEyHnIVr-D?^z_dp6MK6)~-Ku$GnY{Iexhww28LvA5Gn77C@~sYNm{a(DpuZL z4Wo->Z;5OtI%|h`BdJ>?9gIzgb@$eR`Y=M+JuA{CpH5=dy_?WcA3xRE`DpA>^iO3C zJ0r(T>CxEs^X8}b?wpD^sJBtb_}#rLQz{pK*x%8www@ zBnS9nX6I|yP(p)p>P&2v1$`^yN{U?jy1y& z&h6PMX?!j8sEb(g)DiBKOv&4+1sR7WKTKYBPyNMWkd-T&H6txTE$Opis~BEXPj+Y< zoshl9P0#P#8`~KE5vJZBvYZfiGJ+7-a4Hi7<*(bSaZr4QY{JNJ(HUuAQ*oivDol`?CP=Fl|>yf zunDj^kW{kakT^E88I^_D$sd@gnXIDxZ8$Kn>3VA}VNG4aLTc8y_n~mcm z6Ty#kG<-y3>lh0{;1a9W;lbG*N6XGwz4@mDJO_EWOsoWtFGximKPw7bpDYI+Uu*%p z+g%JEPl-AP8-R81V$bA()hh!Wh&@3U+S8V^afq3% zfkf19v1LZ^6!7ME+>RW%yYH6UG2ACs5;%iH@;Vp4U>Q1IbZ)*i82l+wM@NJA2)M%> z0`A1&ndE}&5f-fo@WU|ovhtS)_^Et1+1n7jzc87aR=9wJFT`}MVi`9IhrNxAF-U)#+rNov4paUaY;{Y%Lv9# zla*D<6^8_*&84n3ZtHYuQamf}-~7qV?RryuL$bP8I4uFzH7lQoj@Ba8az&}}ij0~_ z=k``7TBi%8Vbe!ylcBll1Kezyt?`k`Vs~hDzRrD4qi0dLE=@K>7bz$62@=e3xmMW3 z>?$9h5Fqz}f#tGJjAwCF=$!EhMJpb#T9GQptDwq}o+e8Or+90Ar1~>@MlfjC3%l^t zYl>)yHJ55`zq`h;k^{XOFUDw42f{nD)imGy9Vv8P;L+TlEZtU>_t7@BEubTo~3bJuItSKWmzgG z4UNzXXq|QdUd*YoN49VdJ(JsSn#V8!Uvmzrd1)2?z$@BZ&(EYC3=>j){}*sElSX$& zqs=2&MVpAD0QtM==){tGmXj{-h(zu$ZDN8e{3Q~)yHr%E{YSe#`A5(*$wTBE0`r-T zMvKtNB+vawSxWk9;Fowi?s0Sg|DBmmG|njGS~}h_oSmsZ+8jnL@#5IT2$zAc>t4Qx zqf146S-T+$P4JO;hU{~GUn*6wuO)Ny0|R~EW``%y+wPw!$~19|G?3}o_ka~qbXAx^ zi{~~Lh1+E`CA2$tFg(POt00(IMG!k*eFeaM>2d+9$RiTyab%i$<2VWN=Q$Gxi?Oq> z8;6EM0iUvC6O%;%AL(WyM4=NWwoL>TapL5ef*qVub2?Zkfbq#9gns1(A3BchuT0>t z{X1r6g*zYX-4o#YqYl~}5r*i+v5CVfs*u=c6=|S!iDkV*kSmADB_OKQV@zbQt93-K zL}iS;xG^_l_W6yui_zoiEO>Av;jsrjUe1Jv40>Fiaekw6q~ewbF}l*(j_mncuHM^N zQm-AohC&P3YIsjNd&eu>*QOSBChz*)=V+Ru-~0#CdRJre?pV8(cI&tu4vtwvi3olk zqcbsNW7W9$*4yJ6v=0ZTp}9Mj;JLLP!k4##=(djIAO@!DN^g#j-Eez@Ggw1Pjp2@pYKTa<#7&q@+J(Fj6cdOz2t9O^LOR3jB>{f4} zdmjwCYqFYX3hUl))P~pSHCp%e&`51v2o|BdUKi^M+C6`Z-JRWsgAH!g{6g$+)311K zBL%j-`f3wH#_-W6yPlmbMb=NE4I5P_*i~`fa`x$$EGv~RR{o&(ptM*|&K*+TZPp7j zYlX&TAusEqL_+5TRa!jp@$+Q8L!I`hb8Z-PhDD>!dd>$ik)!O#Yd!DzKYg*eJ!g{q zJ=*)3>Uml_KHTj-;4Y@8dgy#Web7Q{T~6Dqi{G7t1>G?D{4F`X${ua{ny%hC$RLLs zF9)!v?;LEj%#yCYHV-fdZLDtJoZfwXWeye;pZ)>w{abUuL3Kguj1Mh2%jJD&@8_uJ zXcc|f-+jPWOhfh1MHo9|y^Ql%!!ywT=}Yi%zz=TPCs@4h7ae77UpRwIU9a3za41Xj zB%hRnj7{z94%zE+mgy+J-5ls}dpYYE= zmS}w%@J06*S3|G8bAxC%-oqAkjwoN429DZSAo&j5Ezlg%643y%?sm_M6@NJz-2D)m z;AVlQi+y4Hx+CE3OCZq|b_zBefx{ALu2TBwFiQ~*Ej>*AAv!G71g{G;XNZFh*Wu{D zw1H>R7-6tM6a4h04WvoyPvcz;Xai}|tmnyK13I%WZBPVfr#E@cN=|M9-vF$;z>m%Q zyXVnW!95zPRZPNqz>a4j=e$cpY9pHWNIdvZ3GBB-;-v-oi#!FVS;15v7q(-RcwQ?& zaU4h~i8+uj^qB=-&b}}D0Y)oc>Uuo~ZOCr`_7)fl^@SbM3rw&p8Rp~vzngNgyc`^P zG2mU+F@^+y3jX$^kAv%i*gfl(C@}zensBe+mP8sgU12yia6i(Q*7HCc%nH8l=KzrL zi}8Q|G8lmSlGpXyXoM3@j?xpsV}_%`9z{or@e5#q6YGN~bj*N2@|Xc2fJ*1S!0jQh z4J*lL0QjS569@@(yeNoZC4upA6~=hOy_oy&81uvE?i2*K8*xYkl_KBlki(P;u$^Tf zNBZaearJg3U~PouNL8Q1C*TNIDM6rsDDZc6Jo%ch(XPbzZ=WfMif7TBXT=`Y>GfTs z*R1CkgT)CGcp-%i_@5NAL|2(^L<;UPt*dhXkZd9xMGX2|+-Gl$@zB3_H{(Yk+)s0dcuP zMlKL3CR`mRV6{DFrK0>{)h8Eq!fhfh5?v0nZi=A{@7I0QY%WUBy*ut#c|e*+Y6U6* z{&Dik3#cbh_z2V(obx@ZOHHrd+h#p2JGgjWt&u~=&u8bp(blU>`Xqf<`eob4L(MuH z&PgrNfBsr-rTeSXP8J_qOTsI{{3K+9yuB{922@XAo|oqAQqgV{mko*{dRot0({lZG zt7yOW^3f?)k7+y6wJzE**RO);d8MA-wb|xO*E)GsGfgXry0^mBl2wh+!@@m_CFa$r zXU>B@_FefDr`sD|t z@mjrmj~g6{sgr+o<2D z6ctN@`uPt>#jD<^AmfBMyO@?e7Bi6JRU` zbn<1zwCP~LK?LRyK(W!`g&ab?Ag&QYGd1`TM}>&{LODO$TOrynVW>mw|GO0{s)Da# z(>}<9=U#igG%QDvB;Y{g(zpH_sJDxi8(7QivV3ximCYsQ^?%7K|14gto?h}OLCc1T zIYfXlhzP1sd3#3!Twa0+On|P)5Mn{>E&|Dzzy#=u4Bkdb!|p_61|l#)x+2Ia3Zi!y z3ZnnKa^x*rGJ@r+`uUI8XYbAlU+_W0=c%_<#mj-gd6f1}^aB#~NG^(h<{34Z(_hhK zfGiPD6B`$#t#+sXvz*5@JjG)>GHKv6;w;?)XL`R0p-$6=dEW^D(Dy~zHN(*o0kT^q z^9P{C=WCP+|L38F^7}V%&Cd<#B?8%kpLB7?=LgjQJ127BRhwiKS0X!hC|ibCk2l3YDx`1&NQykJ2@# zaGfXsI4BeyPXL?p3$g!GjK;Tm!158*a1f`T#Zdj3#%2oE#U`5a5_LvwHcQw)f!&;w z#$`7f`K$J{bOnVwvp#bQytMqC*`J-cl~=ta=rmSm2bb&RPp5UW6aTrM-evmh1-opY z+_JR|3uNuHee%lIn$MdDFZuAY5WN(@%i_9@nZ=t%?))%xlHJAQp2g2B#G;R-MBOf{ zEq=Cpm-d_UqFW6%#~gOKwm#9lSWe1f-jHc9UVQrxNx2AbzX`Tz-DQhu#`fCHGvy+p z!f?-^OGwgg7h?H#SUzt9EPqx}ihDL`k5sT8yxMg_Qp04hs@glCJRU0#Bzo9{ z@@GiZ(>&XXF@Z(dPkb~L)y;C;Y`l*L=!CfWJ)dBEd&_uv_qzPeA$89Wz@{2S(cE7H zu~%ndJAU35b2!&b!Ac6X3b*9AUA%TYz-Ey9JHiLoiN#&GwL@dB=l+qNufZwHuwCBZ zl+eKO!(>tGknHspA@f!!z=7mr548GNOaq(z3VBApArv1Z6k8CAZF!1we6iv#4eb0x zLh%$$)Iy4_u;QWeSn)4G8`b@)Cd93qt!e240=kEf%I=$K%n6lz zWsBh{2MPdzCJNY)O+g3*QFXQr!4=PYJ)~Ww2KK@2vz8wqulhJk?k0IBiD22CstP0VPEa1?# z?)1{@G{$bkbBqXJwP(P5nBMxmM2eIL>NMYK7ZODojUQ8p%tTS{%c(nJ8wDtTA@nho zprt;s_lG1?=)Xu?e-W8{PXTB3`i>vNP%;ScJ;D|05g_a$$d`dRpK38@Z`b&My#K`K z1wtpJ-=)`kxhKIGQrG_sas4G=+CsD?y639yszKXrXBf*vf`Af*k3d9=ZLX6bm1K9H z659EA=yLn)_mDIDzr@53ha3w3iGxCv(FRH?D4p)N0odWNXOM^#723?1^CDH4}guv!!T}A|U4N5Ej<7t;O=m@SdxYPIvmrNQl2%^ph z7xTbnzUzcYD0ei}eL@F;>KMk*JO;q*QT+I6Eu1@17~(|pBM2f2I}$JdJp{o`=dUP- z%SH}dHgFn2#UHQKBO@7Czx>$glNT^R@MU9DP*FCHJ|5|j+1G3))Pf3TxEQN_;gtN; zM>94%8UYZMcB(&H?2-$xVMGu$qY6<_Cm72Cy`q^CLz$9RA$5;!h#L(k5j!NtUmakh zI&Ke&5Y{QE&;JsW;rk8_Ha`4+xajOx`z>6|r$2!N+>_fk0du#_wa=akbl0HTFqpW2 za7?ckxm)tM63%phG&4Yg?L#*L_X2(~NV4Dm_NC-+Dg6-mp!CaI^BUM2-DnB0^p<{b zwIjIjY_S|!JgOcBP{#pM38pRdfbxe#XD^Ksa}$Y+ArwB6i%kSjPS&CPVYvN5_PUF& z9Ox9VI8@E^PgsDW5$+)eh+QXB9Z~acC+<Nu`wpg~C_5(rE#jz0))FyJn)=miD|ty3xVHAG&#j15EC5fkrw^U{ z7w^n}XZ?q$@LTm?$qMT)7_d(b1QUpZ&-t|UJ%94Q4?(>I{VzZleN=(_+PJxJ-L757 zx#EpcNR%$<-bSS01ASAl1^^c4V*U&FzK!EpD9ngUO26v*&sSM}a79A+ujEMdo#kII z@xGU!`F?_Gy4Q33FE9A=#jh^~Z@lC+4Ko^C&k%Ltnh%nq;3Xu|lSd#V(7uHo$j=gP zL}5rKU)n4Sl)&qjBQl74!C4n)g%k37&Y~#vjqeDNuHmlf8{ok!CxN6I)puhSKxz6f zQQUU`if*`YZ+kuhSAlf&X@^L?WGUT~lI=|8^dxIZ_^Uc~w^vFS(YlHXj1s8a_R6$y zhDrjbxh{jtxk`MX-mD29s4wNTcbO}3S_=y9I`>Rf+iO*M5&SIvU1q|4%XL0L;XG!9S0jo0$IUUjQ`x?q_(UdB9x zm&K+c8FmLox9{0{&N%_}c;jW$r=w+OIk=H`bv4KPQ>8!5WbVMKBh%0_9S1B!r|LIV zwU$n#`tSt2>>XbA8=+bXRKJu*sx2L#<7HM@#-OwU$_MxHl-F%GZ#V`4RDZ8*uZq2s zjp*!L@Wgu~d&xs$Q8Kli+UrQXFs%Z6V{?%MO& z%{k#St3Zu@A>7h=50i@ZJ;)&hKfjRd&-I{HaV9oWET!C3C8}CyoH~b$5>fLcjM#-7 zgQQIui;P&b6gz7Cs?qJPV9KxxfCO4x>#8a-+h}r2IkZn66F2RaPfJ#1bh7qoerj$P zr8`@xxrQ@dh|IO_?Dn8q^`u^-y=HVC@}`&j(-Y``Gip~&ID^tz6W;YX%ZScs&N6DP z0;tlh>{S|3casc)pf5rlTL^oj`!dzI=M>T!MYp;u(JIGoy-Y3dITdbn)ENelBdaN} z73fR7NqYq%!7`R;0&TVts6}QHjsB}&ihx2wIFivw5vxyQ3nA_OmXR`CyB9krtKyjg z%f6$!3)}IfYGN5OADmSK|Jtq^q*~I*4=k4ZoPw4S4KTk;l&`vX8GqNXJ3qSB3JJ7v zxo&s|0lc5hFmhKF&Xg@=ME~3~60qi+?C*6!1}3A(WP4zE)?hziLFHNMJa-;yTi`F8 z%n^FcSmDPdV08kV4=2L|USX!uO9W~#P*oKjaX7mNtVNy|B|-zOb;dIiNbnISi9M_$ zu^UdT2N2#WM~2dCMsrQThfzd(k#ps5yv4JPAdJAy*3HNt#MxQ}`XexS(2c6m{#sbz zNCI^NUiDzWd>}ejhN^SsRcH9u`S2kJkgSGYPET_)wHS3Xj4(SnCqpEd2M`_xg_sGM za--p&00BwBA$S5d5}1&%)e>w~h0{R{!~tV^U5p#Wj1@qg{a5ovf$;V{J*N=)@lJ+Z zhL4E@$AsMr^@XUBgz< z2@9i*i*kO!0#Fyo!6Ug6z!*fN_D7fTUpRVEPI?o82eH=#A28^BT(TU(nv4rR>j?ml z2q_G00BG{`y2ML9V@2-p691fw@5J^)MX%vCwiVNmrZxqN``U#A}TAVjO-U!EeIjEO0 zxd3ApO1LP`rPr*+k?$|O_(xeU`~zmau5$>4Y6-yXz44qX0VYG8$AR36IgUfpUpEUl z&<8Nt&J0g(wL+kDa>gYaZ;M1?;IkH8p5Q?!6;N$~w$h4j?FL|mi{ zfEqnn~;NY zvQR!tW$0U@BF5g?idV}B7JhqB?&vN2{Dt8Xf+|3P7r1tCNT~AjN*|~9f{d41zXlT$ z8GRDfzX%f^)cU8^K2ZA$2t`oySjvGz@yAKHPXyyjhCo*TGBgQlA}bO#)iam^1b&F3 z9Wj0>;49Tag~v49uKB2Z!$?GBqcf(dQnFt2C~4KhR}V#g`Nr;I)M6n-^@VCSvhw~` z=>`cHUw5D~Y=!ms=0GH1sO(Wy=~2SwrRdI9TvtI#Co&)^w|F6jt{%Ky2$p|veW~UZ z&6Q18A(0eN;^=$|B)o}3oIMZi5SMo532^^ts_73wy7ROfUM#Xk1XkGRsW4i80F#tld$7Uv6$VpVOx^TwrqNx-!3hVS~Tw-&J5F7eKUHO2Z!$M^vR4Sxu;=9=jR#)+L z3Y)V;;KtiYeSxau%GMdg_XH2R3(C+9HLHmm2>%M)-2i5&Xl|RafawoT?0_kt&Vd(N0&TbvDsyUF=q-SCcchqkztB>#CtU z^>ns0M0!zFsokI9i#L3%Y3n+nqd;rTy5xD`%w^d{cXn&ET{vg5Vb@K; zTUF<21#e|$UpmvSvr>0R!qi-o;DW*PPigN@rIfYDS%( zaD7NMnnue{nszsM+l0tT)#aNqZ$&*>w8PYFQcCDa$DP^RcKKvoI#ZFKl=%?Pun5*b zGb}3);Tc6XFhlJvo)LEk&uHu+W_VfR8H#Q&<8v;avG4_+F=scPvB=OI&+xqgGj0^% z86|HCJI)d_9v#FpSdU=FhWB`eM+u%07)fZkXpd*?cnLE)it!BPTEY%pExZ>airJ+2 z(3EXXFSl9VVq7{?nqOi2EO=Yn(@ArMG&65SK3VaEuyn*}kfB+DWxPru?2v;Q;Ez$( zNK5+~xf?li1GGN4S+Ff8#ak%V7-}k?FEwhjJW`!2<=~v1Ebo`SO)1->W>Xd{S2b6L z*9qCdbG5l9?&!Hu>#wNf`~Q*E^CbEVGgXmGPoGJOO>D)Qeeov)yr*0QaXU%I^8 zrUg{Bng*eBf-XC)+nw?G<4f!{v#xj7Nzw3RCK{2?lk2uQ_KvPI{|tjTWi(y&dP){v z_vjak(77=!ewW2cM0|M`*;a!^Y@x9iZ-9LE{gc7jgwccR(Vmf-*Ks!-X2SV*z0*Mw zGNsP=KS4%^*|pW|UJBcAxFwpkzCuUqcGQ#QV4G;g_>#_&thE$#tI-ahgD&R04bnya z4Tlq8#^-~t!2eA!ow?23rt;#Wvf@sLN}`9q_5+L1c@rBVTL8zQvUhfuY=@UD^gu1n z{fT;~YPs)byaRMJ^1wMdS(0gzs9!3M|rKY=C&Msy3> z!op$?uh&1>R0iq7s>W0T7~~Al@Rb>sUzY)zaTt78#*f?aW0uw)TKL*S>-BN87jSV6 zvI8KD>;NZ|GF}PnmbA359T*g%5>7L{MOE+ID)6WQuWoAtpoprQNym|~!SRpIPup(gq_JexLX>U=9>nRAi z9{z~$P~i2Mfp9|v9>xa_Jn$Vx50)C4Z!#&q2^^`?wFbPo0bvqc_%BnHv*m254bYoi|bWN*!ifuu#o>rf3BKnK1^Zoi^I)57@)p(PQl@xy_h+ySJH>1iS-Y zdRzX8lXon*_Y)km?tRqy+EL)DV0Qp2@W?#Zr>Y>%Q~;m;K-GP!3Nj$d(e?n5C>DNv z2A_0sj0?&jtO-5&^%*~|MKE+xN~2m&0?gj&S2JK*#&!^yvvz!9F~om-LVhEe^93^{ z=0YzOB3%onY5(r%TFzSG8bN$Qq1lU5!OE0|t4N^P+ZJS*OPqC&g9AVi4bpx2seHd0 zBAH%n@iHV59`MK>%2C1SLg?FJ-nxb?TOlB8`Vwr@jdd-KJZU-G*!Q0toteTI*A*dKJ1={8nXm@`n2*MPKHgGS+{F6yG>wXH@ z3RSb+=_pZd+T1806oH~w$m&Z}-H`V|JVNKL!l5k{qZguitnU8BtVoV?$1QAT8Warh- z`QG)~myQCf)(Lr>yRWgq;e$fhEbazX&ttM>)p8O-<_{EQ@{?BEt2qSR$@gBgcJ$pV zsvQMQ(XPQA26=A3{#rC;v&}l`(tTtzuE` z=lRx^Iw30@Lv!c9zIS~}Cubg+-Pr))%uj;Rjwm`(%f{G1s>|+QV(ANy<9s0r$-q4>iq+DmAvK(!$ zhyyZ&@70Z2ux&hq4GFs?w=>Iw5hIDsO(?ZjMh1qXPMFr8Ufda)#osk) z2eE5+OJm*8kXnxdo61NP5tmVwa?gpDj^b|Jg%2fDDW~uD3OomI zFWY>q^x2(!T|>%~?rta61s!>QcRSd3W>kRL%jlLJ(NSkeJ2yWe1%5gWhs(Dr(%Ncb zd<*OwtuS0miMt`{|9&i9JWu-Uy|qz`XshF}3|fN?aoBOIFZDgcBsg8tIo$?hdM(TK z>_ru1B+|VJQaadiS>|=oE%T(Q_wE3MqMC!R+z_Q-bY}oE!^39EsQ_#XHiTB(-wrr+ z&b~-umuU`A-h$B07!w(`3UC=(@ex41=-w58Sq1o^ck{^p+00Z*)ha-CC>o;h{6Y=| zMZvmaQTpXk;MON2Vb}3s5v)QM35cYyw@8D_a_3`#eTGO^$AhcSfme_r#edciQd=KG zkZb<5A^v9IQpM;u$PnyM@JP^he7JZBi9C#to1H%m_!efhr#9eIATeNs06@R&PNLFa za(upCTk4}}iyaUM0pYm4wD*idv9q=qw{3SJ0Hoxo;K5gt^#WF71$?*yDCjeQ3c(h} z7`Ro18W<3$Lx=bGfEbRGQdL1jCgO`2!1Ghd)SOOYOInrTx8!bE8OQN}9)dy#c&};9 z2y%9Z?Nl7vQwYknqiMgJPu&(M=vgXb3hyqnfD$ zQy+P5@5;CG%PlGLGL2SHw)y#KEhRJRfh+9RK=KL&k~llc=xQ+Le*XfpsDSjxO))6u zb~RSJsxsm^wyiy%R2x-FsLYm}%%Dg{f+MS^IysHfWYPAfv&d-bR4(_Ci;X^Y?+DWe zXQayS>z<$Om#GIW4`{LXEqdtkNMY?2%jLSPE7R@h>Q~Ax%t<=F(dR=T^MzW}?e(6= zy&|A1I$Ig{PGUMqy?EDjel`p>9wdf>h@soe;iIGvTwoP4A50$>hXqAD5ktQbLzTsn zQn1cq3nT5gUxoNKq(;0Quew--hhCE+C7mQjS?fCP9RUJGv+PG5?Zh!im8Mlo4q1-U6`Z1 z(n)lb1Jz;gh&cz|p2(4u^1i*^YZEafMQHPG14E|NVM8?4u^~yvgGCL5*LodvfnTrH zjI>n=&|Zbc0;zIQH=M=a4ZphV<;$9}lMLRj*=iY$dygbEZJQ4Mna2wpZeWeldu@vjyj=Bs1ePhW9oH53z~ugFhozq=T%) z%JUwU>o1DQiyJ4-*03(@RG9?kIJ~k)0;^!EZ3{-p>xtyX8zw7(VpF#!$4NXHV=Iu1 z@$ZHg2pJ}b`YDeBS1wJCRQ7b(Wsm(DkOY3+E=YXR|26cY#!M!Ds!$VxeE-OG1nXq&T4PpEH& zEffnScny&kReCrWJW|*k_2;W_O}# z&&q$*5S}(cLttmfeBRLa4MBU`^!B#t3Cf<8S;!-^z?)$H#btHKMm$7{6!1tNXN@;b z%!NZd(NuIA!IkhqmxZM=xNmHr#JxoXd`zXH3=k@_h9XoVw=CkE(gdA|Fu>Ial{}<9 zN@OaJvR)1cE`4C8R8+zn0MEP1T5Amun+iODP_?{M#Sj7jkF~=&s6`nN`>yhVV;W+W)@Kj##RrHV0OaJC+XVuGok3W- zMeI@-TJR__@{kL7WZUueK7h~RqXI=0z%5C~>rQz-K!hPmEmEs}SEkhp_RaRY11Pm= z{T0~u0I=;xpP3t1Y}DbmIu@>MgcB-8NiR8Is?V&uI`&> z@CkhtwdN>4{~!sv9dv0JMI_%a8C%SPRL0y@5ZF?Q?I%4W$`p{aM`_u!2jF9p) zr;X$)ltTpb+g- zN%SFYDCaOon?uonD`QaPNLFbWhNv8XF@7O}3s{_NkYLEyM1@OKBLH8bMkZX?e*$E% ze@C4GHwIMb1YX)mk`S>hU`K4$&xQYc1F5PDS$&lM)OYX`n_{x2WL#CTxp; zxG*Ja-9K5Fk{H9u0Ts{x*I|o*AmtsCI0ao%2~ZHp5-7QE%@4&dW~{o5b9Hu z-Uc@16|4!SGcfp3K~0pxK$93oP#O9&ADRNaN)zGn1!~F4%Z+y{6e8|_y>v^;!3HxQ z@J%7ZfVkQb1;?=fN{7cyp zs3v;LQeGbaepyOZ4SzDlqf;J8+g~h8LFAt_WPqXvUl`bQtA4xVn{;oh7f`KvP-#YQ0Y(-yco_w<-SRfPVq%OfWshho4~C z2p=U#JTsW&)gs{yk^Bd~Fjf5vH>w{gUYquOJ-~2aL_YWf*Gn6sb8(1!qKn^f^eF*1 ziTgwn1ujDR#J2?ghl8G*8_1g&d-Y}hM}}RDaWI$oz<@p#^d&;LAmI-of9Zx!itNM4 z{5VF*^9R0J{B4GO`SApo1PNp<*7qv{uUg;}rW(G60?*<@2*jTZ@YgW7)#0yT_@07q z{ZGdVrhdN%Ww;ku*B?0@NW*}~#2qVQ5a+$_#bglgLQGZ#uf^4IrGnUr2q~PwZcQ-{K>TH-wS-{}pJh(Pse2cnhyejd(X(!)1sL{@QgEF)hx4xc!yS zLNi6nd59IL6EIMhC-JhrIsnrgW_GW-iYp1;M=-dB_13jtsa>Jc7W_O0)K6adSnw^1 z{F03C`sPF>feHFQSl(VC%Uj};U!PPqYEn;S0fWl!p{vlMSeDMMEwR2VRYpl1r$?*F zlgp$usZbqT3u2iP^rLoMFJI@b=9Zr75?4woxARl1F!yL{WTbO6t6X1>;l#FWHIiWD zg)9(bm$>?JsoWMV3WGsyZK(`$cvr-Vm9Xfkiq(>!H_6esEfji>Ei*Zdsai^Bb(U8b zc`@it%yNBIuaVAi6P2T5CMw6npIG=qkC_-B1%Kk;PYnE_-Ja-l`0&Us`vneCC#f*` z$|{x8GvXU(NKn>#-8ttKc`Hr(McR(+J@YEOgKLpLLnypu?k@Jc$<9Ml{ZF)r>|)QJOz#wlEKrcK zDB^yyqgbRp^en%5Z;$;i^^?WT6i&HbfaWb|)=n0$mp>I`edASCZnLhYkk-IIO4l=j z%Y*%<-bf$t=jigQI>|cnvPzc+{As012Z0VV`}qU@)T9`ERWTU#IwSh4ijg(?HeXeY ztO>9As^XwiuGZ<|)T63JCuEvT9h<8-2Za;j{68gLWj<2w{7ic~%&0W0qb!5<4o!N0 z;=z5n$US;#&HIH@eLVHOI(FT!wQq-p18zvyyo7x~uXNB(<@YC|{TyJd+PXe3K-oLv zr~-Hhy#%9meP`Ur1gG~-?K7hWZLYsCVg`2G7s5z&@?TfC^Bd|423BWusnyksnRlf} zqdkJ*bv|prleVAlIwRWTymWxXqiAr;w*4Sd~+OKI&MKi+8sn)D^8^g+rMdAJpQ~ir+ z9D{<+5BUvgb0gDgVp8Wu8mSh@szh_Tqr+NWek#a1ETq*~Gq>H{jzXs|h>xdk@VZvl z`o3~?p0bM49c2~WlFDSAK1~s=x+VtAhS|d@3Fo$SP~^C+IYC|`C!O0nD6+I|om1(* zP(6$$B&5oWG^!Li8Q$WaRM5G$9K6>oOWWK@DF{z4)op$6)db9IW7itq?%J{XWq~TK zd&s+%j0gUz!zn#a&Rw;oiYM%1cx{<#he z-vEX$`V5Aj%SslZ!ruNsdlQAdy@0(Xt`%nVnB4z-B@u-Zs{k?~$g60qS z+k=@N(?3ErmJv?w21RWyRkw z4^GFckl6PbL9ILUn;&15Re}}!;vK@Qi!&VB4XUE9w%13eTgmvpcI-O%9TBGA5s~TG zMg5M5n(v6na_rju9T6hm7Gd3r`xdWjQI zF0;^)Y_eB2*?T+x>w3S>;c)Bo{oLQreSf~c|Kp+ed7tMEJ+Iewg?y;Z{e!l{ z>)(y$(Y^WegYfrdzxvU6U-qk?&i7@%`k{MY_NyQN_hrBOQF>qYtDma(Wh?(YFH7;? z=(~q+q^TUMJ#TGQP++g%`E+Wa8^cEs71i#@49_i?ofr*xN(fQ(+!DD{$a(F_fIUlN{(SZiy{?PyoMdu_z}X^dFNWmvg^5Y z?K=vvi<>K6-}JM82>&X?M4zzidP#h5{Y5ya+7++w9&YJBU`(}fL*KG%#ngszFwNj> z3?H1l5|9Lx1{6)m9zK)TxdmzA6^@&^R+>8^lCWvo=4Eq0XLT+(>tD{K@xm`=A|UWD zXF{O+#Y~L0O(1$2U-A00)M=TDpwf;DIu~c!ys_78nQeX4$`bnAoM|rqL8)Qn)6d{v zvz#*DT5&yX3!2J;PsPs|LL83q4aRFbafazgXU1xud;PLWnf_9DmjLaC%g3kP9Z&dr z*uBJnhkS3!N)5TUyt_NfNcr#}^Bg|wxx7qfX#i-LVOe>sCT!+rL6<<~^765~u$iOU zql|is?W5(&`HTe+I`xULGAL9%qLwgySJE4~MC6aP!)J!O8-) z10PzI13q53lN-xx^7@AdR*wimbt8MlWRwVoK64NU81rCXG7up#dO~@rM+?_%j@8p&aI0dZ*{Q`M{R=~`M zUTFc*fXMEOZ2qx;4uk zh3GoT>yg4M)dUv*!{a3{7=B?vEhU^w^v-%CZd5GD%ySJs&yGG2_Lv{o+qnuBu(SHi zoSRjk!1JN?<`!crIP;Pa4|68UhvRqCz?>4oTfzJ1q9=8zat&73UcB3J=bHA(HRep| z{B2C17GHgilm%TAgue>i6ZQZT0n;A3O@;)wDVN{{l)>7E(B6S0P|pVP5cX&U9l&uR z-kzHp1|jIfq2E`qf6#%E>OG>zfT4EHozNi;A4oZ^?n}u0cwJ_rt%;QQoM)inK!!D; zoM5L)m>i!lAG042VEnjfrM}O zQav1>A|LqYe4tb4$6&^dTbIYGAJH#C973moG!=`M0neMZk~{$kN}x<+VwimC)3uYL zGMRN2U_8)-pxV7nR%Lc74>%nJz6dKC09ylaJ%m^p5UQRegqcrQWnxxA2`pM5GU-Tj zNo&_4_<-=Kes>lqlqv)6}mYfqYDHQu7+m}H z5>L|8ey&-#g)sx%pAhA%b%i)?0F|8^frEyt!~jh>=E!d1yO<-;NNWMS`FbQl(|8$m zv*0Ed^p*q!P`9ze0()ekjuUpdGi+mDd`I4J(hE%M{T%3l8)?ukU_JF4OY4bvAy(oG z=U=J_-=%#c^+*10=pYhcz*sEyB0|2Ovp5H2oEIs-G&QB$+Lw2{U@FQr^ssmBa7%4% zs`@}^j?-*$8j>^jQ(n(`PGNHI21;G>wn! z)iWO7yUoYJp~gjIF9k(Bi{4uZ2(0L#&8l;81XheHgcZTBody+?gpi76w8rDYNX0Rv z;sjE0<0z~sc9T_yYZO-8S_&)Hy+C@DK`MHK9_5gVT%vHOSSvWxCZuBjEmobiW3ZyZ zcUUp-Ez;v9Sh0FvTtQi%;UkrIa;GKEXvJUh32=Cpqy2V2hT@n@;e|6=G`ci_uj^v- z$2pzw+vDxe($L_4i??T^puj$_5%+d*z*P2z%1W#;!6mmE+S^&FcF<`L`VfV`3=-6C&bZAW%?-dts*A>`H~p9y=0h9&^Z&CYsX2rsdC3wqFd?DdHW z%Su5}fT3NyZ9I~z?6a(WN;%Ngke?9#*|PT0u96EdmCM^ly0Xav-J^4Vmc#y?o&VG^ z7r8fb`hL1JKIeSCax)V~xe^LRU1YoDq$CvBXsl?wOMD(Vgh;WEva^M8QczT5XlaD; zA?)nea;w3t%y90Dw~jd;u}BgA$6oiCvHM_Y^p-Ui+bg%MG*VGnwwK;|d1<8Lf1w); zMH_BtQmHcx4DR$AA*??8{`)}~ej1;bI$ULows*NrjH=3QH9Z-u=wc!HLSre$oMQQUJ~9v(NXRi{Jn@AzMV> zlj%~7%)S_Qhm?U0OB{hO8Rd=w`>;|)&8w{y8b+SaC#HQuSZf>JkFH?(esXAFAEbG&JwQkXcs?{b6%c?9PN4?aWsA5s9AUsZIJ47h;E>pw8H9n4wb5Hc zIDy6ju*4fYff$op4Zy9Jp3-Fo@r9Y?;{+lk!bd;3zERanw1^?XMy9aL9{Lf?K_o;n zlK*BUh$UiJTbwAFZAfd;$O26x7UA{56QU)!0&UJB27L#42Qnzw1UU* z%i&+ONo<)9&jyfY9H0X)c1i&f%5JV4d1Vhj(u=A4u@_OZl z5sL$O)g&(f@k(*J#t8T5_G@bzmKbk1KSU@P3X<7O1_h%gQksi`h!~Y9j7XzKD71J= zp3x#&4YX0IvMKz7Ip?-wHE`>*zq&AxJ@VA~%pn z4s^Y^SaS4$^aO+$7;Ts!(7y*(i26PX803NjLGst($cW{aabki@1xuODf1?s$B-8X7 z?*Y^y5oU=zKqSB`%hn_Q0ItCM$!3lCePr?%7*im8EU^(1&w#8J#GlMVtcZhp0skfu z0vK8Vj2oU>j2xs|Q0Hx!@j9{~<%J*@YF@UuIRHVVAVq>02ugB${`0P;*Y^Niu}PDL zxM+*Sn8jeM5eEV=B&`&1*^M2G_lxhM$N1EP-7Q8F(h@m!+aps^SgG?Dz0 zDnVEzqS1f95|0WnUUENKjKAFM5QLZ5#XZsliInlrJj6XG>1hzao+kMTfITRqKqrV$ z2$a7X05XF@5fZ*own7YFh)uyrhfpZg5Ky}8hu9Q}yr4EmG}IdiD*}l1A9e+4hfUrz z;2Q)NI6`u_p{9tb1~dioj-|)}S35%J(&m>A1<5i>CszP*5*b;Eoc@nwP4aY)7r6)sN=<%?Dkat$CJdQ6MVP6%RM_lF zzwfP|PeU&$JG^G9pe@HO;FY6tLY^8a<8KuKd07@@voj;h$oi4i37w zA*Ow~PU|wcwldJnMvs2g#l>PIoc^)rfmR;gC7p>D9@J&l5+b>qx@lU3q-FiL7h^J_ z+`UWKx7Ygqev@WX6o%&6Ite|T!~XjvyIUm;aSp7X8TVb69qgoMm3$zcy9o?d2=CoU zPqFY#`m5Iucj_bT7FeckcW++y$*Z@(lVUKLb%r=EP`yQn zj1`uB3x%E1?j!7zCP+!x5niy2ai6B_U}_nt8;V6rg02OKoi_P8ZK0TFLP~e6FeDWC6zA%C-4vhZlf}X#| zu+LWU42aDR&$toh+wGe&C+lXK#OKGGyNl@vL-PYHg|W)+lv#P1*NWmfozNH{`i3)TJr=*}ltZU4%bU z{l8iv(`&klScCV%5(s815^s1mY^-7bCDLgK# z{;EnF*3^rqdQ8`ysIpN`mXSS%m%SP^L|*j`{>?-7Tt)16axsBjRVNx5*Fuf1hk7In+p&MM3(wk z1Ye+ph$E7KZJX;OJ&<*M&K<*#XI2GQh-3?r`72Gssm17G*+(_Jfld3%@$gGa@SK7J zS8;V8sskEb0D3cy?EvvpX*K~JU!|Z#1WYC_WC*_!&R>!{8Z?%QYm$Wa|BXADHd7vvAEr8i8n`b1R9u%$W__JPDvRvR#v6z0~H!wUe8dBJ9tUgXS30^^* zTA0-v&~_{EV$cJ$Op<3T1d1i|{3}hvsUeD+Q@Re#_C%BNT(^#_|8v903|XJSs|GlS zO2ki(NkczHLi!aL=s=vUrOUCIehQ$7E=LXEGtZ-s0EacUn*dxAz|V;;`V=x~I7ARu z6L=ndjso+t5Q09%vk}-tYx@t>Uxy4IEX6Ad+ig9qv*99W1ym z8pju$iRij`Z#0U>?F2gZe+_la{RP;=jRXAf6&++))9W!B$E&kGAgnlm$Spu{~QsPvd|E zhz%KgJ3!Pk#QB{2=iUL+GG78-jXQu;5<&)TmuWwf4I=hc3P|4mXWv~!SwkW@LO>eP zFlxbM%0=K5MM)wfTPR0t2PI^S|!d13`T(upa;qv%f<(1Gd*H1i%!SM=rF%Sj_NR z$HkVQy)iS=K%DrxZ6}DNvvB&SB5HIyZ`=w4zVD4i!qt2oj8`*#gDC*=fS=QB>Pub= zLvj-pr0mh_U>qbyrlk-Bneqy8d1aMDF24eJ0xX$ch^dRAa!H2^2=EsQL&wgD2AG9H zxAdaI1aF7Hj}3lKVB5 z1kSCCE38o6I4;zO$TUKtM$qK|%tH@?hCrgCOe!dWf^16K zV=HmNhdAiJQJNT5pr1p5Lhj{_C2=%jj3Jo@X&^(+fLAS`6kwISW%(EMaZGxNQ)kFk zn)np3XOwdx>)J(iECyA;i&o&YOI&J^q>(Uwu{s>{KdMqgKrWYtW5|N=-aKP{;vniY zAz2O7VStIDtZ2-Tf*q``5$*+JYb!)UKy~L5=GAWj+!}yOdm#8}d*R;jtte*>?GF8M z1}yK>VKxArAJGBvnMjGYYLfW>O*{BsX%^~FEC%w3Oy)%*;yunaY(TDAly#}F0e@X7 z@-ETJf}bL*CX!}}ODGc4T;i;Y>iwsz19GdT%B9WBX36uq^TA|J*2w`h25N%Fd_VzuCx`5C8*$h!g$Qgn;hW46 zcBU)sq-Jdgz+~M{h?jM!3t-5%$hLCy&fjg94EgS95}-dK)p>0;u}}10becG{aU1 z2r$_K3E48(0Pec-qHZMyxFj=!V9dY3DN={a=sgLLmQqd|tj$=vku=CAqgfVWJnR8$ zF=<&yejpNHOpg^t9kUPyXPwnihXD}=R_a|&~&Co=8@TnNc;zJJ`jvW zM0+M@b@qT~K-7Sefk$fe2x*65rCTKzs;~hA91JjWgpqAxAnZrhvChC~beKaCnoroj zgzO`&PKcxlcVG~@F=zi8Sxvx20!lQ?<2{O(nhR<SN6FcDP`!DG~ zGiG5WzQ}c}>1Fn0&~;cjZ_|{uc*`PB0X705DQ|u)Rsim8u;_XVq{o2+g5)YB_}Db1 zXX530CTU7muQHXMfvrJgpG-hnmSE^?5d(JY(1pP=Q8OTjjqIx}@rA#VF8ymwL*9$b z+WsWSDL_?&T;o2tltb3(#O=_1FwYVv1#&Jc>Xzh}E9?sVJ!$U0!#>EeEK78Yq;<$a z044oMj%C@t2a)10TMr;x!~c1j`>*K@O{D!PIS<$dz6vt@n6F^vt2f9Z3--&cPA&y_!{ zSr=&AnZHeA1468jeI9Bg{on zW^#%CtJEuCZZ=qUq)*9({A+3%S>BJCaUoI5)UC8aq6ujKOjh8+ZkM$XOuH;x7xQUL zm$kpjnUhE^8Ds+CxzAyF#wM|Vt+ zC6I^v!a@jPwjeR*1CDag0QnEt+=r|f@>vqtBh(gVE|;Zdpj!&_FKE9N>>(j645m=C z(EX%;FZ&Km09JuLA{jumbDNPH(g~?$4(fi=)4pKWFBiFjMFSuiwZ4OJGZ4*;lM<)P zb8TeI2&QzGq)$=S4Dv54r#u#HV=0$fQB^CYfDm&aHzYDkASPzXM~Cc8!|hrW#59o| zEul)7R)h(eQJ7SI1?U}X^9?z0L5)^a2L}dU4O1ypl{1H2YHXHkXAX%D z7Z!P&mR&w}*E#%~sbgoOr88@@jp59G$*hm&jUekXQ53j^qSLyL&ayw)oSvpAePr3I zMoVwEpk2Mn6P(3|QqkU_vE(nokM z_q{Q#oi@#_{z6n852{D#@&=TVG*YuZO`5E#JZks2}8s+x?Q; zR{)%KX*9C+Q4efqu7Y3uz6Flfaw~vj2AD7N!Z57s7KVEX`{ecTad33S=3VRJIFSPH zFyAg%f)&Dfv5Fzk6)G`wA{F#E-ll=A_1{8&S}X_!Euf2wyQB_IT|7}Rg+t3owj~t+ zr({$P#(*PQ-@=bWm7()S3V_XBZr`fd3i|eo%ut34f|2vzs~|al5}b))Kh=K5O64(_ zbvn2EU5dC%jk(VplmPkyMCl<*(IDsM5XdN2khC*81#AJ;3)-gmR-je5vGI$ob`enE z;}}4mg^JkEiJUKV}OAEBW#2SZuZA}U^GFR~zd<2wOsFHM)0@-?B zasLqA3kBTNI)gwtTA*Kj!9eQj-5fG_|z=`J&R!+T2{}1io21$HdqY^ z!u2|=5;_hX0$O=Et0CYK8JM#+$MB8-%wCFYwVX@noG7jb*;A5W<-j&9?@Bcxc>_cR z+4To@Jysq9JPLU6EU;(Cx)+~7RD#R(xu6ATbryn?7s1q-2u&H49;t{V^>7ngyUPfh5H%h9EEi zr)Qu+_GKqPeh!{{fz%LSK~+=y?w7C)pl|bx-k1yI`*C9gGcVw*P-ox+2|oSdV<4!{ zvz!AkG_!Ft$fFJGkU|rh)Ipl{Uvcvsj)?;yIm@@(&jWA*_OZeS{S$LF4Me@@jyqhy zBFUgXb(5KBu0|MJ`vt6C4{N?6n8DrnxnxL}AsZXe#j+>hWzl6J+3A~Fdtq+$Y$~#O zg>H!M$mvr^CXutR$UfUY@!U=caKDs= zle1vDKtM3NMT7!mIge~~6BB5}%^A|US+L8qkPrX~gz2krn-8Ht$mw3lp?+3AWWdikYyPU#KxB3GufobQU>G={ezL)6r?tgEXR_A zkiW7)lin)u=k#j~X zl>aB5-=(N)RG*(LELRY>8=1-m*Qus*1@JfZ8vGTirozNL!I`OEBnxdExp3MMDjh)5 z5IRfb)Dlcdkj}oKr`G1$!P43O4lWg9F@vJk{xA$-|fT-Z57fNLLe91=+w!7T`fQAnC6%`@&qYETHn(@&(t z`QphqnCX!P91OR37OiP2Yo)Bs$|vJM76?6sg`DnRYy>&bMnXsQI3CKU{+CT>yanNv zxQ-y(Al!5-acapi8*u26l-gNj+5d((7xzPnESeNn0E+)N4`Hoz%;uM8;z0NTryJ2& zs0_|H0tSUpJs@|O!yz&*;%?~w<(ZmAH~<@C3#YP%pypr-+5z>@Q}pmCwzS9GJMOue zT=5Vw+sUy|1s1XSp_cAew~2wqxv3Tn7BRy3(1>%mxW?>Ud9Hoh4@d2OHkUmv@>+yxq54+`T?bU$a9ZM% zVfRNx)xv+?ZcIu1==O({!+fsg{tHrF_C-c)CmkB^oPG7Egt6#Q4P(*U-`GaQi}<|R zBnT!RI}WgoI+-9PZs&ngC#k~-Mj zO1W-IZ$?X~#t8&nJP*1G(g6+4cQSE;ez$faCF;GlpFew&HcXcP6u2>{;XWZHnB)r)k2uVNsEjjmS?k4e0LGL)4Y3JG<2e`uQ z--wdl85Ck@4{&{E!h*NpcRj${eNs>AEXTJchQH{gumwFWsRm0)NPRTW^Psjvq%t2i z4hA_V*$3wP-+OhP`bQ^|!1Z0IENt8y9vQPu(Na*iOAQ~2lcj0)xPd$Hc+-KhLq|^1 zu%5g^fqapd^_G%7FLfGjf^8FDazAFqy0WbS9k8v@A$v)i=Ycs%eV-XCOMRb@?4{fF+<+I4;3yt_ zVjz2I-lc%o?|e=h$b~<**>_AW3Azo1;36*2X`P&!5E|zyk{ggE{ks3A@V@8~Fmf1jUcDn&2Lj#KVP50$5-keMA(zE=mB% zE&%%k7hC%bT$fDiuNCJ8Gex8@ZULH)Q}DuJ5E)1gH=H(I;Lf3vPdBDgeMG$^9CD_;ms&wz6pp#OWr84}+P$RNy*+;wkMd z#MAWy+rfi4gToi3z^?;DuzLP_ff>hOOwadA5YSP;VYfH)0*&N_GPh08yR|g|Fj8DY z*z^B}Z)X5ZLx9^0;yNqTJP2ZwpMYHQ0Fnb&29OP+`H@pFn#1TW|Aq|-v5V1l0hWQG ztQcaE=l`$RNb6bvTSNq3;@=R$eVWh;cLd~6U8BRu~p@>?X>yKb5l(2yW9 zjY(@rE=Wi{EJ{WxKq!XsKQakk7nuy`35nynXz(YeCx1tA2wljO+f-jc1uqyoJN2F` z_y9H`JcR8fx(2Zu;bd)@Q;z`$A`Ek&VGB$YiC`ewEe33&@`2aGz^w2Z1oFwZcY)xR z1o(*|1;$suvDN3YcyBs@hFm1>f?w-2eBTAqEPWhcYERs~0SSx4z~5>JjI6!?&jjo* zB0{U=|4!S6-T>KAkxkJa0N|f-5)d>H$)|whs!%{dM6RR%bPFQ42X;?l`E58r zwwqUPhyp%>P;}zuq*%`LW8h7g3*fi4-x?r`H8v-*{BMTPy$b4?I7^MTcTc{_#)_?u#03| z3v?e^)@juR5uPNjyMA3fB1#_z7K2aROJQaJ1Ix$4b>e|<_^-e)RVW}r`T~0aM%xbJ z49YB_2|^3|<4_F1b{18D=?GiRV1g?5e+Xv3kvb$KL#?1#G2WiL$U}#xgERl-m!A#J zr8DBUGv8Fr@os7Ab{-hdo|tZ)nHzj)H>oK;`-a7?ew)s5@$qs7XTD$~!IeLzbi{x8 zj=_nL@j>}&NM;brfSS+Px7%luvduLT{@hEG`ZjaDIOd|eDaUFuj+b{=UZ44SI$YJK zFM==l_L<6v)MGVNI>#HH>1zac-_?t=HT|PJDsQ~vY0==%fo*i0#k4vs>RL_W)>gyg zh0V^{3dQQ71v>dk@!1tW2fM<@?4#a&j)?tiW?`0~7Q(_)M5Q!R^Ci`-Vs`YQU%ZBb z!u(iEUvuef)BNzbjU7guU^(y430e~iE!1Y&Ge0%kP&3>%sbywnIc;ob*Ebli#F?)# zu0PjeV|OHBeqf{`u)U|fra3S2n{&jM;*px-xUKLqnMh zbqxL8;wygp;g%oYszJx%K^UkRN}!yL%iue+acDmNiwaeyU|?trt*Ia5F`Z<)xnT<< zG4U&h{B$%%IfweoLvvDtIfv%KC-}2VG}bo4^F6(j!*BT86lM>9kIgl2#xh$wPn!0g zpY=5DWqwxm`l#-_&4&!J!m^l$o-gbZ9uAyKrxJTNUrN;k$$Jf56M8`1AbyNbx9l;M_%l zsj*3aXYu0VZ5qWo!8FP8uFm!|{whFM z6zpWN3u>^67tu)52#KOn$e5&mK#0XYX`VOGRdKN{YX31f=In8Nvb(t_{>#r{!MbU? zQ&uxh{r$>x`GrNvV$bGyyW*zO#*H(kZ-|LUytYtg5wxpUbN8VLIQ-phtTKggR}8mLDbJLR(xvKV3+Cn zu|$Tg3ZKN?7`E!z8c0jh%&8RI6ztLC+r8(N4K3g9qUlyp^sZF=Dv8llmU(ZYoDVEo_nVTB+D+TtqCfPsiFHFal+txoYEJ?4)6==xq z8{E(kC~68GJ-ZDaHSss(8nl2%>DuMCY1cuikNpA-?ZY+p=@VzPW!y$y=8x@gKk`&> zo8?_gyCdTB#s>U4;rXpoc^1_3xy{|lV+TKMv9B5$eo=2G8c3hgpGF%)Ri@!CAS7!d zr_TH;^EX3dua0kN$7Sse8r$|3uD3Gvnx{$6JMpY%^yl6=Un`%7NBw&$PE1pd@85VU zx;EnBXjR`Csxq}SrHwVM-|9w=GaR>_D4+GOX`cDg-Tw28t&N7bU3#Kmsxq@;fHA*@ zy84z-1I8@zChHR^n}%3*=%^?SLetx(bkkjB zSl+ADb-(BGlV4jcf!|PgNM!4^Qw)qplRJ;zJEW~&Qg2nhDk&)Tgo)~zwbc(`0X|S* zHz<$|3h06YKg&KTmJL*Xwva54sO7xV5ZRILuXv?D@mODab(wKYpYA}rzn`^%rZvyk zgnB*II%}6d+SOGX8r}F0P1MehtK)Bdtn&LXk##no`7>oy{%Y%KyHdkvN{*U|>bsnd znO~+?EV`^|L5SI$ooaEJzR@ir>v`AZ`}?ak3RK@^a>vl!iko|F9Q;adB7fqzoX>#& zchd_4VW}aF`#XpM&8<_6+(3#XpujxBuk0=J6p%>C@&GBBnS&>U;&l*^~KO#s|x z$eB3xD4FYgP;t&)|NiPDUNLn#OIs611AH!}K40T#O=QZ@hrk;fTT8-)Lkqw4%rG6b z<=4}E!HrlulRj(y72LXp$;2S7iwEwqS#`PrpotS~y2!C9;?dIP5w-PyZ*jr#g` zUVu@&2sG*{zkU18i-{jn0&sqI;5sO11gcat;;t?Y#Lhd8S@FI17`) zWf}iT`r>e**-3uuoxv5_?&l-=jT@uCX*aP(CFOfQx}9H_7W4aEoy4mT3ZtdKho013 zMwZ|TvyUetI+zQ@yKJoP9uYr>;cjN(ZsWq8^TM6X!d))$uIh@dsZp%eFk#iIRRqG?Rp(BvUAJ@9hEsGCD-mz-cR`A3^pU32`rTz_*!xjemy~=gBTlu%!@|4(bpN#I(%JbVI z=a$I4no{3wjokf=GMe`7VY2sM#2dTKTRW#z5BF>937>tiX6yCQ^rmSKjjljw<@n|`-4(7=T>bYDzUG>yZ)R!*2h>y znO##*Y9GHh=w`2}__N`lqwJog-}U^NZiTHK+=(yVeh*hg{oYVplYT?d(M=CZ0tG{= zoMr=$1gv`abYNq~j+8yK$*Lnv8=?+;n$lx6ksXmVF0p*RgM)gXM#c8$cxMQ=sDHXpfGY`v1 z3#73#+t8f&)|WDUNAYO+)7?zvPF5F#t~=+YMpKCq?)O(!jqlPou<`zo!ddvksAq1A z{Q=(yi{{8LpSLO1$?IU#D-}~paCG=$UrC{duOw1ZdTrNC+N|NBs;eqvpnBUmoMC?Z zN9e9d|NX13nHKKrs*V1BvQtIphtj%Q*VVcX=UI&}IrUO*mh>;hOkZx2W>CXTKl`L? zc;KP#fH23VYaNAQZ-$;v-kZM@k+<%9Xj;FaSdy53^YgtT1O3ub&r>hv6&{zqwfnHa zhXD^m83PxqOG#9wSH(Hb_{X>R#aBdClud0PRoQz&2L}D# z&dlY~GuLK%1>MfSBmPrhn*9>Y%gr8f*!L0^W>hq#j$1Fbw%FTRT`?P$hF5faXrI%NIcV@Di7DLrb!pq& z#}^!$Pqt<37CGwoz~}kQT8_xiJ1U#kADY^@5}2I6a?mOZfQZEERjc-)U}A1)tY>ob z#*MosJQ~I~^i6n>F9Hx<4#V#bo}YEIdACaqILVx`D10yF@LO)efQK!Mh@F&upm&=mg^%&x&o(E#jlJAz+gE>iP^p?!m^e?h?hk{4 zpO!NKHUEsK*GG=B{aYg7|Fa10BO>4|x$vM}O=52qKNLYe8xTSA>#3QaBoXv=TZeq7 zqxEp%?loPzIWJu7!uvtH)L!-9V+DUUJlS+e#H;zcfj}SE*|WMXxdAGdDPtYav$LQg z2*+K@^ZM5N3Qu#|Y`%ZZGs$w1z~Q>p4Owra(;bcbCZ6B+RP!g8hig9CQ=DgCBs-kz zkjL@(nx&+-l~+Wq?>(&(J;zi#Ip?S;PFFqqGSa`I6-fF~zx=mEaO{^Nc=G>q5gZMp zc>HgP;OH+!;Q0S@5$wp}-tljV;K-jvfMS8L^Ep=z4S80G1t(D~NamQD>8f^+@PJrw z)n0{e%*_$YMj3VccUH%vQqQ<;g2j?zo-2!NwUcw8js9AaT6k*0#m)api;%Wrg@nE) zZJr_iPJq!^4UU}p{O`aahFk=$ zS-d+>POP1mw6ON6blf6&QGo5k<<7NQ)3qDw{Jkc2&RNGZ-T2hrey6ydKX69mEu%J- zH~06HHI8jqx|{C@t!ocuo&Zo#zmoz$foA#PjAv`lo|SjW^-|u2K*1b+wp~t5tOvzg zFR_jqITuUbyeT)vlE`Br7oy?qmze+xiXG&HysnA8 zkQMrRvTqndf%$ldo-Klg`6J^LD@ovzXEW9T;N(TBRjcU#6cCV5fXqF}r_Ljgce~R7 z*BCQ*(?*l8{o3chzN%Ixewub#2ez4K%J^qjDhq5$*k4i&1+%r>6Yy zmx|Z76`j)C{7eeNan0e->l)h8+=(&$6E558pQx#nQMa z2~=Tu3?nZ#6xv>AJQiJ5f2*H)OrP%&|UAxm1@| z^Pb>2k!yquKX;Z}SLz>>*Z0+G?~lB_J=R;^>EgE6Qf{-RdXcS+jx%EWO%8u8Z4Pen zalbJ=79oFSvrc-Hgu`|IQJeHRnene50%WUZGAVoto<2Si)!wG@`|X~4G-`d!KK|i!gKG}qf~9X& zJ$%2JvPCwb*Msf27t4$V{m;UEm)t5hM&wczrJT55qkexVQZ|loN?D_a1t^$+t}>on z&cFSTcl)ewPI`hfZQbgPGWT}U8SB3m6I*ru#h!PsHveWYpF!z57`>K*Nzj2=TPHW< z%q3gD8^Il>AyUqB#l73(*9Ts1nu>OPs(gTdW|y6Mq}bV8D!baFJs9l0xLsT~q-@|$ zd;4PoLovxV>><~-YjBm4Oqasmb^0=0TnA*bM8GcOBHbJagGejzdXNTeZhuF0Y+b8wgWZzxk&DqwZw%RhCvKo0%MXVt3Z?bDH-i=FaHsb1(lWxIL=G$abdob)M_2$i(^^^3oCJqV~Rev6xF!F4cKgLqrJ6*TwsLf+h-GSFNf%yzW=Xg#@l;$i>U9 zPs5>dIrU8H1)g{Bob__IeBO-zZpQEOE@Q@HtB|bsi<{IIpQ@V(+xQChOuXA4b1m|F zVNl#}Ve58>QPxCuj#d@7Upwt$ns&eKJ_ zlj~jUWRpvN1YThL!Yua8R9|&%+NQuu%;9p6b6xYD%pBf+bPmhEu-T$gE8@8kbI$LD z%+txf`hDJiDb%i`a!@?PrWohfzy0}>-!Qf+0=0ve-7N=dyeQ)YEdH>#A@h{i z{`IR@ytO~ePRe=+7gu#Fw8#~Fak(2zxJu8D+nOe?@rm!CZ72u-@z^pxZfj0%@z1lJ zN6MqPJ4Q9iSk~eSw&m^3o4aE)8}6pU8k;4?rS&|hTtR=@(Y*}gP8VMyk;&29`$g0! zWp2Z3>jx?L_FG3@Jw8FzYxq~aSXa?Go8z5K_ zdNSvyJ2mEqGzcTk;J=x-4!3S2%-Y+}72DTl&UMd&Z$mK}_G;lQ_LEKdeKGbk<(Y)0 znI^(iawZ{sZgSkP+*6z|oSc}aQOTb<&--LE-t_Nc5T~5yxXoY8^niz~erZr65p1;Xow^iq7vJ>NO{V&h1 zGM)@iwk~N-rt3N~H`%KFB{W9EZ_asQGFxW0d8CKOc5KLcWbGrvtegQm6{?Jx+Kwug zf&nWVrAaX6x02jkHS}NYkG*avMy-$kuRYU>-Lvw5^V_4l8t?TP?7LN-d++8R6wxG&>~}Q^jW_r;8shiXx5&Tw{rbZ2)f&$Rd}6%6 zHA&+Ib&J-A&%3#LGmmP2NL#Nk9(K;~y7SdYZ`La{r8I1NMYe3I{C%5D_BiF0mSJh? z9}${*E-@OPXpB_qQ<4v)=lau1NEN?#JC-1|PxuO(l!e|+8+{k0w2B;A+LEXw7r#et ztsC?X4e4$=uHM)({2`f9wdGV~7{_kVxXyzwmz#O_U;1ES>E_l}`99I%(Rv<3qo?(C z?uWc77*vrWc*>LRbv#C=bG{fqO!V81X>LDs*xx!emg7hmmP`0b%jrRjur8w+jw=ro zPrI@tI|&LOPSE;;?d#RZ=H9L^UOmswQH7;ZPgCuZb`|CO;;pLmnFhYky9x$j72DQ+ znz!4%gyvvSn%d1TuPlsv4k|xTEVv}~5zdI`kF+3)gXz>)BpiMHDWd{*D&4-i{#1$U zQ&(>DSSP=(FMj@fpI-||oO&}jY#g@BrzJls;u^&j%th*s!<8j8>GUSYcVMmdz0Vmx zrHtV*`ci+*eW2R@*1m`X(E*#kcvl>*{7MtmYjM|XKR)O;e7zloUw{_wh?IQ;%X7_AF=*3d#keT4QuN$OXgcib>XJ33$ZS z0R$eVRRB6cc)i4ug*i+ZF3KY!}a-Pzgyr4HB z$`O<7)Fm7Z% zACc$U|0RGZWmp?X8PjohKYmpDCItgl{nnRP^d>|h<4_^vgNkwj8aEwc#TIY@8DmK@ z#t`RT1-o8zNcB{PbWwyy3JB@>yjQM&CWI>Xw$2^mmUO;~g$Px1$?+gnwEzD7Wo=?&F1PwC@*nR9_ON8~XbkI_Oh@JA_v@kp-qM@U>D_cu$61O(n@e!OVRTl~ zl%bB+X~T7X)pitI9ZZYTRBLg4dyWaH)1ABY8&yUtFiBKnhk=-OC;6SjbkM*Vmbei$ zjppK`M z=84wSuJd*`GBOOe8hugwE$@QV3$5UF}7=o%ra+`#ptDp-87i&d}jXzQr&@YhIM*%-qRW7M6I6$F;WoY+Dlhzj%y1tuAE@ zt2|<6QzkDP+gf>fvNC}NZx))mNixdXsKt2y*-`1|V*oP8LX0Zvt`#OX+TT(fcll}d zrlIq2mTZsWS>+yoK1`T^MAYTeg6G|fD&JRJ$#E!W^gV1BHg1`Y41;h;r$rnLBVy9f z$}OS>DPq5)qV-&A@l}Vg%0gRVyB@ySMv2(QaY~Ot7hOYs<%q;bWBcEwhY?3IQJ(+w zLlI+hvf@O!q7{p)4>0mdw&?gZ@#mhO=@T=jcDf=k#0gr#)JtIM$4|{xCOkX8CHa`c zF`F09o-vP!#$-y->o&Mm`SA@s6UZ`*YDshvDBr|I|42DeZTTWdq>45{jI7|UtAhMUpTFJIP3K4Uc3GLBZzdFnvIUt zU30IT;W5yc9y|QK--J%{l_?izLC*~A1L%kUWvyS7W<;WE;hQAKg%M2f#Xbd+zo9Q} z$_)pwEATusW#UZzNjTTSejP17Aoa`_&v~=LKa>OHxDru~(^W)NcdkcW-%K1GAYS_- zt}qEm^dSGs>769w32Z3N(Qe$7Xm|3&kZQTEbZkxKF1+?7x44(%)%tW{rB+m@2m?_; zAD#uf6!sTde&>>}v7@+hu_14RUM3i4G=~2rQG1=*$UuSEiwgI@!_*)H>6OnB97^j0 zGks&q!=D=JQkX`qdkD+-j+6L)Hy z@mnizrW4A*P&p-_X-Hp5HqO!=7bMN~(vG-e`iY95DF>nf0#z76RlG^W6~39r>Q(DT zY4N=yJSPr6wx;#8euw)xJ%+%BN7X%CG<5@FNzo-57o&1LYUjodXF*w#wOJILIcn23`{g`(KXx8Z+%WbX^y7y&bzAWYkknL zn20i%h30~caT01fkpb0q;i8Pm26>(t4_)kwHXrpayRZzINu}yz01N^}ix7Q6A*!K5 zq~+||xFE!km4&Erf=q}a3qm{vCW#2~!lDo@7le3QizvjvMInxmgm~UP2aYc|5Zp9I zmwLwwo5x;Da<~}Tq}ps$9ZFFh^5hc`!+vXSvq=D)7vJ17pm58{1+-xE*=vD+IG!$b zYYEYLA!z9EQbO7&wzj#m^8GQ#uV(_a&U{8nQP)sh9F3L=<&;QmN;}V8657wY*IGlf z>DAkd+`A^LQ|@0=+%gk08Ohgce{p6QFKW3$CE>uEL~w{;W}3jY5n`}26JzwZwm6^W=&9hwZ0 zh$4~7OvcJk#s)(qieo5ahGfVTl0@cNBr=4KxkxCPrxS|GOr}F5ckS1qci+#wzx%lN zKdsl^d#&|cYdzQ6`(57UCh_%-j}q0+y*&}TrE_#=CpFE!Pbq?WByl$-QC#dbjvYHj zRe9dN6051H+ORveJUHZ5|A@GJ#_)lVhsHNcN4%f7RpZ{kmu;RQN8`&)f&$cz75J%4 zriFctn%a5$9X^OL@jmA*X+KU+wSL*t3Or9majosDJX`h}lZr+T1baPJ3$LtV>p%5s zvaadt?rk^D@jPHPwt`RFT;S7i)i6PQh!?RSG8IBGq)QjnmW(*)C?rehtxE zIOBx;Y_5pMI|V8GFd5zz%+Q=YD1TL|j)x;#i2HYMU-->VKZ_59KQ=PPy*qLwE7RyZ zY40+9o&T(>z{8|;(KF{I%P*}bcN?9TH*q&*RrzhtB^B@~?D&%) zvvS$r+_;@j-k$WLr>^W~ji9gJ4u(|iLvcS@HjZBMcY<$LbV1XsKiZG$@OKr}E9@Ld z^=iIp%a_#E$4EP95imalJ0BXa=v24m#EEM3XYSM#$=Rv(Bi!#$hqXfE&51wD&8J%f z9N0#mQo^~J<_7zonR6!vXg~jQb>i}?t2Ik6hL3ER|K`z>c}v9hh5-Y79iVFsI5BIn z@biVaQfeH7#-(sI-lzx)x=V)!R<)nMw5l-F;V@UoVg083r;O|F8=mhuF`Fw&H}P$U zuTGZE7w;wD6z-jR<39B)p*=%0An1ow_PtQk%5rVLBa770`+k)>YBh~&Sth=p@3dCP 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